pax_global_header00006660000000000000000000000064126154246170014522gustar00rootroot0000000000000052 comment=80cf8987cdb3c311b65584479291c2a104e9d06a praat-6.0.04/000077500000000000000000000000001261542461700127205ustar00rootroot00000000000000praat-6.0.04/.gitignore000066400000000000000000000004361261542461700147130ustar00rootroot00000000000000# Intermediate build products for Windows and Linux *.o *.a *.xcodeproj/ # Intermediate build products for MacOSX DerivedData # OSX-specific files .DS_Store # editor temporaries *.kate-swp *.orig # Praat temporary files *kanweg* makefile.defs # Executables praat Praat Praat.exe praat-6.0.04/EEG/000077500000000000000000000000001261542461700133205ustar00rootroot00000000000000praat-6.0.04/EEG/EEG.cpp000066400000000000000000000671161261542461700144370ustar00rootroot00000000000000/* EEG.cpp * * Copyright (C) 2011-2012,2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "EEG.h" #include "Sound_and_Spectrum.h" #include "oo_DESTROY.h" #include "EEG_def.h" #include "oo_COPY.h" #include "EEG_def.h" #include "oo_EQUAL.h" #include "EEG_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "EEG_def.h" #include "oo_WRITE_TEXT.h" #include "EEG_def.h" #include "oo_READ_TEXT.h" #include "EEG_def.h" #include "oo_WRITE_BINARY.h" #include "EEG_def.h" #include "oo_READ_BINARY.h" #include "EEG_def.h" #include "oo_DESCRIPTION.h" #include "EEG_def.h" Thing_implement (EEG, Function, 0); void structEEG :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Time domain:"); MelderInfo_writeLine (U" Start time: ", our xmin, U" seconds"); MelderInfo_writeLine (U" End time: ", our xmax, U" seconds"); MelderInfo_writeLine (U" Total duration: ", our xmax - our xmin, U" seconds"); if (our sound) { MelderInfo_writeLine (U"Time sampling of the signal:"); MelderInfo_writeLine (U" Number of samples: ", our sound -> nx); MelderInfo_writeLine (U" Sampling period: ", our sound -> dx, U" seconds"); MelderInfo_writeLine (U" Sampling frequency: ", Melder_single (1.0 / our sound -> dx), U" Hz"); MelderInfo_writeLine (U" First sample centred at: ", our sound -> x1, U" seconds"); } MelderInfo_writeLine (U"Number of cap electrodes: ", EEG_getNumberOfCapElectrodes (this)); MelderInfo_writeLine (U"Number of external electrodes: ", EEG_getNumberOfExternalElectrodes (this)); MelderInfo_writeLine (U"Number of extra sensors: ", EEG_getNumberOfExtraSensors (this)); } void structEEG :: v_shiftX (double xfrom, double xto) { EEG_Parent :: v_shiftX (xfrom, xto); if (our sound ) Function_shiftXTo (our sound, xfrom, xto); if (our textgrid) Function_shiftXTo (our textgrid, xfrom, xto); } void structEEG :: v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto) { EEG_Parent :: v_scaleX (xminfrom, xmaxfrom, xminto, xmaxto); if (our sound ) our sound -> v_scaleX (xminfrom, xmaxfrom, xminto, xmaxto); if (our textgrid) our textgrid -> v_scaleX (xminfrom, xmaxfrom, xminto, xmaxto); } void EEG_init (EEG me, double tmin, double tmax) { my xmin = tmin; my xmax = tmax; } EEG EEG_create (double tmin, double tmax) { try { autoEEG me = Thing_new (EEG); EEG_init (me.peek(), tmin, tmax); return me.transfer(); } catch (MelderError) { Melder_throw (U"EEG object not created."); } } long EEG_getChannelNumber (EEG me, const char32 *channelName) { for (long ichan = 1; ichan <= my numberOfChannels; ichan ++) { if (Melder_equ (my channelNames [ichan], channelName)) { return ichan; } } return 0; } EEG EEG_readFromBdfFile (MelderFile file) { try { autofile f = Melder_fopen (file, "rb"); char buffer [81]; fread (buffer, 1, 8, f); buffer [8] = '\0'; bool is24bit = buffer [0] == (char) 255; fread (buffer, 1, 80, f); buffer [80] = '\0'; trace (U"Local subject identification: \"", Melder_peek8to32 (buffer), U"\""); fread (buffer, 1, 80, f); buffer [80] = '\0'; trace (U"Local recording identification: \"", Melder_peek8to32 (buffer), U"\""); fread (buffer, 1, 8, f); buffer [8] = '\0'; trace (U"Start date of recording: \"", Melder_peek8to32 (buffer), U"\""); fread (buffer, 1, 8, f); buffer [8] = '\0'; trace (U"Start time of recording: \"", Melder_peek8to32 (buffer), U"\""); fread (buffer, 1, 8, f); buffer [8] = '\0'; long numberOfBytesInHeaderRecord = atol (buffer); trace (U"Number of bytes in header record: ", numberOfBytesInHeaderRecord); fread (buffer, 1, 44, f); buffer [44] = '\0'; trace (U"Version of data format: \"", Melder_peek8to32 (buffer), U"\""); fread (buffer, 1, 8, f); buffer [8] = '\0'; long numberOfDataRecords = strtol (buffer, nullptr, 10); trace (U"Number of data records: ", numberOfDataRecords); fread (buffer, 1, 8, f); buffer [8] = '\0'; double durationOfDataRecord = atof (buffer); trace (U"Duration of a data record: ", durationOfDataRecord); fread (buffer, 1, 4, f); buffer [4] = '\0'; long numberOfChannels = atol (buffer); trace (U"Number of channels in data record: ", numberOfChannels); if (numberOfBytesInHeaderRecord != (numberOfChannels + 1) * 256) Melder_throw (U"Number of bytes in header record (", numberOfBytesInHeaderRecord, U") doesn't match number of channels (", numberOfChannels, U")."); autostring32vector channelNames (1, numberOfChannels); for (long ichannel = 1; ichannel <= numberOfChannels; ichannel ++) { fread (buffer, 1, 16, f); buffer [16] = '\0'; // labels of the channels /* * Strip all final spaces. */ for (int i = 15; i >= 0; i --) { if (buffer [i] == ' ') { buffer [i] = '\0'; } else { break; } } channelNames [ichannel] = Melder_8to32 (buffer); trace (U"Channel <<", channelNames [ichannel], U">>"); } bool hasLetters = str32equ (channelNames [numberOfChannels], U"EDF Annotations"); double samplingFrequency = NUMundefined; for (long channel = 1; channel <= numberOfChannels; channel ++) { fread (buffer, 1, 80, f); buffer [80] = '\0'; // transducer type } for (long channel = 1; channel <= numberOfChannels; channel ++) { fread (buffer, 1, 8, f); buffer [8] = '\0'; // physical dimension of channels } autoNUMvector physicalMinimum (1, numberOfChannels); for (long ichannel = 1; ichannel <= numberOfChannels; ichannel ++) { fread (buffer, 1, 8, f); buffer [8] = '\0'; physicalMinimum [ichannel] = atof (buffer); } autoNUMvector physicalMaximum (1, numberOfChannels); for (long ichannel = 1; ichannel <= numberOfChannels; ichannel ++) { fread (buffer, 1, 8, f); buffer [8] = '\0'; physicalMaximum [ichannel] = atof (buffer); } autoNUMvector digitalMinimum (1, numberOfChannels); for (long ichannel = 1; ichannel <= numberOfChannels; ichannel ++) { fread (buffer, 1, 8, f); buffer [8] = '\0'; digitalMinimum [ichannel] = atof (buffer); } autoNUMvector digitalMaximum (1, numberOfChannels); for (long ichannel = 1; ichannel <= numberOfChannels; ichannel ++) { fread (buffer, 1, 8, f); buffer [8] = '\0'; digitalMaximum [ichannel] = atof (buffer); } for (long channel = 1; channel <= numberOfChannels; channel ++) { fread (buffer, 1, 80, f); buffer [80] = '\0'; // prefiltering } long numberOfSamplesPerDataRecord = 0; for (long channel = 1; channel <= numberOfChannels; channel ++) { fread (buffer, 1, 8, f); buffer [8] = '\0'; // number of samples in each data record long numberOfSamplesInThisDataRecord = atol (buffer); if (samplingFrequency == NUMundefined) { numberOfSamplesPerDataRecord = numberOfSamplesInThisDataRecord; samplingFrequency = numberOfSamplesInThisDataRecord / durationOfDataRecord; } if (numberOfSamplesInThisDataRecord / durationOfDataRecord != samplingFrequency) Melder_throw (U"Number of samples per data record in channel ", channel, U" (", numberOfSamplesInThisDataRecord, U") doesn't match sampling frequency of channel 1 (", samplingFrequency, U")."); } for (long channel = 1; channel <= numberOfChannels; channel ++) { fread (buffer, 1, 32, f); buffer [32] = '\0'; // reserved } double duration = numberOfDataRecords * durationOfDataRecord; autoEEG him = EEG_create (0, duration); his numberOfChannels = numberOfChannels; autoSound me = Sound_createSimple (numberOfChannels, duration, samplingFrequency); Melder_assert (my nx == numberOfSamplesPerDataRecord * numberOfDataRecords); autoNUMvector dataBuffer (0L, 3 * numberOfSamplesPerDataRecord - 1); for (long record = 1; record <= numberOfDataRecords; record ++) { for (long channel = 1; channel <= numberOfChannels; channel ++) { double factor = channel == numberOfChannels ? 1.0 : physicalMinimum [channel] / digitalMinimum [channel]; if (channel < numberOfChannels - EEG_getNumberOfExtraSensors (him.peek())) factor /= 1000000.0; if (is24bit) { fread (& dataBuffer [0], 3, numberOfSamplesPerDataRecord, f); unsigned char *p = & dataBuffer [0]; for (long i = 1; i <= numberOfSamplesPerDataRecord; i ++) { long sample = i + (record - 1) * numberOfSamplesPerDataRecord; Melder_assert (sample <= my nx); uint8_t lowByte = *p ++, midByte = *p ++, highByte = *p ++; uint32_t externalValue = ((uint32_t) highByte << 16) | ((uint32_t) midByte << 8) | (uint32_t) lowByte; if ((highByte & 128) != 0) // is the 24-bit sign bit on? externalValue |= 0xFF000000; // extend negative sign to 32 bits my z [channel] [sample] = (int32_t) externalValue * factor; } } else { fread (& dataBuffer [0], 2, numberOfSamplesPerDataRecord, f); unsigned char *p = & dataBuffer [0]; for (long i = 1; i <= numberOfSamplesPerDataRecord; i ++) { long sample = i + (record - 1) * numberOfSamplesPerDataRecord; Melder_assert (sample <= my nx); uint8 lowByte = *p ++, highByte = *p ++; uint16 externalValue = (uint16) ((uint16) highByte << 8) | (uint16) lowByte; my z [channel] [sample] = (int16) externalValue * factor; } } } } int numberOfStatusBits = 8; for (long i = 1; i <= my nx; i ++) { unsigned long value = (long) my z [numberOfChannels] [i]; if (value & 0x0000FF00) { numberOfStatusBits = 16; } } autoTextGrid thee; if (hasLetters) { thee = TextGrid_create (0, duration, U"Mark Trigger", U"Mark Trigger"); autoMelderString letters; double time = NUMundefined; for (long i = 1; i <= my nx; i ++) { unsigned long value = (long) my z [numberOfChannels] [i]; for (int byte = 1; byte <= numberOfStatusBits / 8; byte ++) { unsigned long mask = byte == 1 ? 0x000000ff : 0x0000ff00; char32 kar = byte == 1 ? (value & mask) : (value & mask) >> 8; if (kar != U'\0' && kar != 20) { MelderString_appendCharacter (& letters, kar); } else if (letters. string [0] != U'\0') { if (letters. string [0] == U'+') { if (NUMdefined (time)) { try { TextGrid_insertPoint (thee.peek(), 1, time, U""); } catch (MelderError) { Melder_throw (U"Did not insert empty mark (", letters. string, U") on Mark tier."); } time = NUMundefined; // defensive } time = Melder_atof (& letters. string [1]); MelderString_empty (& letters); } else { if (! NUMdefined (time)) { Melder_throw (U"Undefined time for label at sample ", i, U"."); } try { if (Melder_nequ (letters. string, U"Trigger-", 8)) { try { TextGrid_insertPoint (thee.peek(), 2, time, & letters. string [8]); } catch (MelderError) { Melder_clearError (); trace (U"Duplicate trigger at ", time, U" seconds: ", & letters. string [8]); } } else { TextGrid_insertPoint (thee.peek(), 1, time, & letters. string [0]); } } catch (MelderError) { Melder_throw (U"Did not insert mark (", letters. string, U") on Trigger tier."); } time = NUMundefined; // crucial MelderString_empty (& letters); } } } } if (NUMdefined (time)) { TextGrid_insertPoint (thee.peek(), 1, time, U""); time = NUMundefined; // defensive } } else { thee = TextGrid_create (0, duration, numberOfStatusBits == 8 ? U"S1 S2 S3 S4 S5 S6 S7 S8" : U"S1 S2 S3 S4 S5 S6 S7 S8 S9 S10 S11 S12 S13 S14 S15 S16", U""); for (int bit = 1; bit <= numberOfStatusBits; bit ++) { unsigned long bitValue = 1 << (bit - 1); IntervalTier tier = (IntervalTier) thy tiers -> item [bit]; for (long i = 1; i <= my nx; i ++) { unsigned long previousValue = i == 1 ? 0 : (long) my z [numberOfChannels] [i - 1]; unsigned long thisValue = (long) my z [numberOfChannels] [i]; if ((thisValue & bitValue) != (previousValue & bitValue)) { double time = i == 1 ? 0.0 : my x1 + (i - 1.5) * my dx; if (time != 0.0) TextGrid_insertBoundary (thee.peek(), bit, time); if ((thisValue & bitValue) != 0) TextGrid_setIntervalText (thee.peek(), bit, tier -> intervals -> size, U"1"); } } } } f.close (file); his channelNames = channelNames.transfer(); his sound = me.transfer(); his textgrid = thee.transfer(); if (EEG_getNumberOfCapElectrodes (him.peek()) == 32) { EEG_setChannelName (him.peek(), 1, U"Fp1"); EEG_setChannelName (him.peek(), 2, U"AF3"); EEG_setChannelName (him.peek(), 3, U"F7"); EEG_setChannelName (him.peek(), 4, U"F3"); EEG_setChannelName (him.peek(), 5, U"FC1"); EEG_setChannelName (him.peek(), 6, U"FC5"); EEG_setChannelName (him.peek(), 7, U"T7"); EEG_setChannelName (him.peek(), 8, U"C3"); EEG_setChannelName (him.peek(), 9, U"CP1"); EEG_setChannelName (him.peek(), 10, U"CP5"); EEG_setChannelName (him.peek(), 11, U"P7"); EEG_setChannelName (him.peek(), 12, U"P3"); EEG_setChannelName (him.peek(), 13, U"Pz"); EEG_setChannelName (him.peek(), 14, U"PO3"); EEG_setChannelName (him.peek(), 15, U"O1"); EEG_setChannelName (him.peek(), 16, U"Oz"); EEG_setChannelName (him.peek(), 17, U"O2"); EEG_setChannelName (him.peek(), 18, U"PO4"); EEG_setChannelName (him.peek(), 19, U"P4"); EEG_setChannelName (him.peek(), 20, U"P8"); EEG_setChannelName (him.peek(), 21, U"CP6"); EEG_setChannelName (him.peek(), 22, U"CP2"); EEG_setChannelName (him.peek(), 23, U"C4"); EEG_setChannelName (him.peek(), 24, U"T8"); EEG_setChannelName (him.peek(), 25, U"FC6"); EEG_setChannelName (him.peek(), 26, U"FC2"); EEG_setChannelName (him.peek(), 27, U"F4"); EEG_setChannelName (him.peek(), 28, U"F8"); EEG_setChannelName (him.peek(), 29, U"AF4"); EEG_setChannelName (him.peek(), 30, U"Fp2"); EEG_setChannelName (him.peek(), 31, U"Fz"); EEG_setChannelName (him.peek(), 32, U"Cz"); } else if (EEG_getNumberOfCapElectrodes (him.peek()) == 64) { EEG_setChannelName (him.peek(), 1, U"Fp1"); EEG_setChannelName (him.peek(), 2, U"AF7"); EEG_setChannelName (him.peek(), 3, U"AF3"); EEG_setChannelName (him.peek(), 4, U"F1"); EEG_setChannelName (him.peek(), 5, U"F3"); EEG_setChannelName (him.peek(), 6, U"F5"); EEG_setChannelName (him.peek(), 7, U"F7"); EEG_setChannelName (him.peek(), 8, U"FT7"); EEG_setChannelName (him.peek(), 9, U"FC5"); EEG_setChannelName (him.peek(), 10, U"FC3"); EEG_setChannelName (him.peek(), 11, U"FC1"); EEG_setChannelName (him.peek(), 12, U"C1"); EEG_setChannelName (him.peek(), 13, U"C3"); EEG_setChannelName (him.peek(), 14, U"C5"); EEG_setChannelName (him.peek(), 15, U"T7"); EEG_setChannelName (him.peek(), 16, U"TP7"); EEG_setChannelName (him.peek(), 17, U"CP5"); EEG_setChannelName (him.peek(), 18, U"CP3"); EEG_setChannelName (him.peek(), 19, U"CP1"); EEG_setChannelName (him.peek(), 20, U"P1"); EEG_setChannelName (him.peek(), 21, U"P3"); EEG_setChannelName (him.peek(), 22, U"P5"); EEG_setChannelName (him.peek(), 23, U"P7"); EEG_setChannelName (him.peek(), 24, U"P9"); EEG_setChannelName (him.peek(), 25, U"PO7"); EEG_setChannelName (him.peek(), 26, U"PO3"); EEG_setChannelName (him.peek(), 27, U"O1"); EEG_setChannelName (him.peek(), 28, U"Iz"); EEG_setChannelName (him.peek(), 29, U"Oz"); EEG_setChannelName (him.peek(), 30, U"POz"); EEG_setChannelName (him.peek(), 31, U"Pz"); EEG_setChannelName (him.peek(), 32, U"CPz"); EEG_setChannelName (him.peek(), 33, U"Fpz"); EEG_setChannelName (him.peek(), 34, U"Fp2"); EEG_setChannelName (him.peek(), 35, U"AF8"); EEG_setChannelName (him.peek(), 36, U"AF4"); EEG_setChannelName (him.peek(), 37, U"AFz"); EEG_setChannelName (him.peek(), 38, U"Fz"); EEG_setChannelName (him.peek(), 39, U"F2"); EEG_setChannelName (him.peek(), 40, U"F4"); EEG_setChannelName (him.peek(), 41, U"F6"); EEG_setChannelName (him.peek(), 42, U"F8"); EEG_setChannelName (him.peek(), 43, U"FT8"); EEG_setChannelName (him.peek(), 44, U"FC6"); EEG_setChannelName (him.peek(), 45, U"FC4"); EEG_setChannelName (him.peek(), 46, U"FC2"); EEG_setChannelName (him.peek(), 47, U"FCz"); EEG_setChannelName (him.peek(), 48, U"Cz"); EEG_setChannelName (him.peek(), 49, U"C2"); EEG_setChannelName (him.peek(), 50, U"C4"); EEG_setChannelName (him.peek(), 51, U"C6"); EEG_setChannelName (him.peek(), 52, U"T8"); EEG_setChannelName (him.peek(), 53, U"TP8"); EEG_setChannelName (him.peek(), 54, U"CP6"); EEG_setChannelName (him.peek(), 55, U"CP4"); EEG_setChannelName (him.peek(), 56, U"CP2"); EEG_setChannelName (him.peek(), 57, U"P2"); EEG_setChannelName (him.peek(), 58, U"P4"); EEG_setChannelName (him.peek(), 59, U"P6"); EEG_setChannelName (him.peek(), 60, U"P8"); EEG_setChannelName (him.peek(), 61, U"P10"); EEG_setChannelName (him.peek(), 62, U"PO8"); EEG_setChannelName (him.peek(), 63, U"PO4"); EEG_setChannelName (him.peek(), 64, U"O2"); } return him.transfer(); } catch (MelderError) { Melder_throw (U"BDF file not read."); } } static void detrend (double *a, long numberOfSamples) { double firstValue = a [1], lastValue = a [numberOfSamples]; a [1] = a [numberOfSamples] = 0.0; for (long isamp = 2; isamp < numberOfSamples; isamp ++) { a [isamp] -= ((isamp - 1.0) * lastValue + (numberOfSamples - isamp) * firstValue) / (numberOfSamples - 1); } } void EEG_detrend (EEG me) { for (long ichan = 1; ichan <= my numberOfChannels - EEG_getNumberOfExtraSensors (me); ichan ++) { detrend (my sound -> z [ichan], my sound -> nx); } } void EEG_filter (EEG me, double lowFrequency, double lowWidth, double highFrequency, double highWidth, bool doNotch50Hz) { try { /* long nsampFFT = 1; while (nsampFFT < my sound -> nx) nsampFFT *= 2; autoNUMfft_Table fftTable; NUMfft_Table_init (& fftTable, nsampFFT); */ for (long ichan = 1; ichan <= my numberOfChannels - EEG_getNumberOfExtraSensors (me); ichan ++) { autoSound channel = Sound_extractChannel (my sound, ichan); autoSpectrum spec = Sound_to_Spectrum (channel.peek(), true); Spectrum_passHannBand (spec.peek(), lowFrequency, 0.0, lowWidth); Spectrum_passHannBand (spec.peek(), 0.0, highFrequency, highWidth); if (doNotch50Hz) { Spectrum_stopHannBand (spec.peek(), 48.0, 52.0, 1.0); } autoSound him = Spectrum_to_Sound (spec.peek()); NUMvector_copyElements (his z [1], my sound -> z [ichan], 1, my sound -> nx); } } catch (MelderError) { Melder_throw (me, U": not filtered."); } } void EEG_setChannelName (EEG me, long channelNumber, const char32 *a_name) { autostring32 l_name = Melder_dup (a_name); Melder_free (my channelNames [channelNumber]); my channelNames [channelNumber] = l_name.transfer(); } void EEG_setExternalElectrodeNames (EEG me, const char32 *nameExg1, const char32 *nameExg2, const char32 *nameExg3, const char32 *nameExg4, const char32 *nameExg5, const char32 *nameExg6, const char32 *nameExg7, const char32 *nameExg8) { if (EEG_getNumberOfExternalElectrodes (me) != 8) Melder_throw (U"There aren't 8 external electrodes."); const long firstExternalElectrode = EEG_getNumberOfCapElectrodes (me) + 1; EEG_setChannelName (me, firstExternalElectrode, nameExg1); EEG_setChannelName (me, firstExternalElectrode + 1, nameExg2); EEG_setChannelName (me, firstExternalElectrode + 2, nameExg3); EEG_setChannelName (me, firstExternalElectrode + 3, nameExg4); EEG_setChannelName (me, firstExternalElectrode + 4, nameExg5); EEG_setChannelName (me, firstExternalElectrode + 5, nameExg6); EEG_setChannelName (me, firstExternalElectrode + 6, nameExg7); EEG_setChannelName (me, firstExternalElectrode + 7, nameExg8); } void EEG_subtractReference (EEG me, const char32 *channelNumber1_text, const char32 *channelNumber2_text) { long channelNumber1 = EEG_getChannelNumber (me, channelNumber1_text); if (channelNumber1 == 0) Melder_throw (me, U": no channel named \"", channelNumber1_text, U"\"."); long channelNumber2 = EEG_getChannelNumber (me, channelNumber2_text); if (channelNumber2 == 0 && channelNumber2_text [0] != '\0') Melder_throw (me, U": no channel named \"", channelNumber2_text, U"\"."); const long numberOfElectrodeChannels = my numberOfChannels - EEG_getNumberOfExtraSensors (me); for (long isamp = 1; isamp <= my sound -> nx; isamp ++) { double referenceValue = channelNumber2 == 0 ? my sound -> z [channelNumber1] [isamp] : 0.5 * (my sound -> z [channelNumber1] [isamp] + my sound -> z [channelNumber2] [isamp]); for (long ichan = 1; ichan <= numberOfElectrodeChannels; ichan ++) { my sound -> z [ichan] [isamp] -= referenceValue; } } } void EEG_subtractMeanChannel (EEG me, long fromChannel, long toChannel) { if (fromChannel < 1 || fromChannel > my numberOfChannels) Melder_throw (U"No channel ", fromChannel, U"."); if (toChannel < 1 || toChannel > my numberOfChannels) Melder_throw (U"No channel ", toChannel, U"."); if (fromChannel > toChannel) Melder_throw (U"Channel range cannot run from ", fromChannel, U" to ", toChannel, U". Please reverse."); const long numberOfElectrodeChannels = my numberOfChannels - EEG_getNumberOfExtraSensors (me); for (long isamp = 1; isamp <= my sound -> nx; isamp ++) { double referenceValue = 0.0; for (long ichan = fromChannel; ichan <= toChannel; ichan ++) { referenceValue += my sound -> z [ichan] [isamp]; } referenceValue /= (toChannel - fromChannel + 1); for (long ichan = 1; ichan <= numberOfElectrodeChannels; ichan ++) { my sound -> z [ichan] [isamp] -= referenceValue; } } } void EEG_setChannelToZero (EEG me, long channelNumber) { try { if (channelNumber < 1 || channelNumber > my numberOfChannels) Melder_throw (U"No channel ", channelNumber, U"."); long numberOfSamples = my sound -> nx; double *channel = my sound -> z [channelNumber]; for (long isample = 1; isample <= numberOfSamples; isample ++) { channel [isample] = 0.0; } } catch (MelderError) { Melder_throw (me, U": channel ", channelNumber, U" not set to zero."); } } void EEG_setChannelToZero (EEG me, const char32 *channelName) { try { long channelNumber = EEG_getChannelNumber (me, channelName); if (channelNumber == 0) Melder_throw (U"No channel named \"", channelName, U"\"."); EEG_setChannelToZero (me, channelNumber); } catch (MelderError) { Melder_throw (me, U": channel ", channelName, U" not set to zero."); } } void EEG_removeTriggers (EEG me, int which_Melder_STRING, const char32 *criterion) { try { if (my textgrid -> numberOfTiers () < 2 || ! Melder_equ (my textgrid -> tier (2) -> name, U"Trigger")) Melder_throw (me, U" does not have a Trigger channel."); TextGrid_removePoints (my textgrid, 2, which_Melder_STRING, criterion); } catch (MelderError) { Melder_throw (me, U": triggers not removed."); } } EEG EEG_extractChannel (EEG me, long channelNumber) { try { if (channelNumber < 1 || channelNumber > my numberOfChannels) Melder_throw (U"No channel ", channelNumber, U"."); autoEEG thee = EEG_create (my xmin, my xmax); thy numberOfChannels = 1; thy channelNames = NUMvector (1, 1); thy channelNames [1] = Melder_dup (my channelNames [1]); thy sound = Sound_extractChannel (my sound, channelNumber).transfer(); thy textgrid = Data_copy (my textgrid); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": channel ", channelNumber, U" not extracted."); } } EEG EEG_extractChannel (EEG me, const char32 *channelName) { try { long channelNumber = EEG_getChannelNumber (me, channelName); if (channelNumber == 0) Melder_throw (U"No channel named \"", channelName, U"\"."); return EEG_extractChannel (me, channelNumber); } catch (MelderError) { Melder_throw (me, U": channel ", channelName, U" not extracted."); } } EEG EEGs_concatenate (Collection me) { try { if (my size < 1) Melder_throw (U"Cannot concatenate zero EEG objects."); EEG first = (EEG) my item [1]; long numberOfChannels = first -> numberOfChannels; char32 **channelNames = first -> channelNames; for (long ieeg = 2; ieeg <= my size; ieeg ++) { EEG other = (EEG) my item [ieeg]; if (other -> numberOfChannels != numberOfChannels) Melder_throw (U"The number of channels of ", other, U" does not match the number of channels of ", first, U"."); for (long ichan = 1; ichan <= numberOfChannels; ichan ++) { if (! Melder_equ (other -> channelNames [ichan], channelNames [ichan])) Melder_throw (U"Channel ", ichan, U" has a different name in ", other, U" (", other -> channelNames [ichan], U") than in ", first, U" (", channelNames [ichan], U")."); } } autoOrdered soundCollection = Ordered_create (); Collection_dontOwnItems (soundCollection.peek()); autoOrdered textgridCollection = Ordered_create (); Collection_dontOwnItems (textgridCollection.peek()); for (long ieeg = 1; ieeg <= my size; ieeg ++) { EEG eeg = (EEG) my item [ieeg]; Collection_addItem (soundCollection.peek(), eeg -> sound); Collection_addItem (textgridCollection.peek(), eeg -> textgrid); } autoEEG thee = Thing_new (EEG); thy numberOfChannels = numberOfChannels; thy channelNames = NUMvector (1, numberOfChannels); for (long ichan = 1; ichan <= numberOfChannels; ichan ++) { thy channelNames [ichan] = Melder_dup (channelNames [ichan]); } thy sound = Sounds_concatenate_e (soundCollection.peek(), 0.0).transfer(); thy textgrid = TextGrids_concatenate (textgridCollection.peek()).transfer(); thy xmin = thy textgrid -> xmin; thy xmax = thy textgrid -> xmax; return thee.transfer(); } catch (MelderError) { Melder_throw (U"TextGrids not concatenated."); } } EEG EEG_extractPart (EEG me, double tmin, double tmax, bool preserveTimes) { try { autoEEG thee = Thing_new (EEG); thy numberOfChannels = my numberOfChannels; thy channelNames = NUMvector (1, my numberOfChannels); for (long ichan = 1; ichan <= my numberOfChannels; ichan ++) { thy channelNames [ichan] = Melder_dup (my channelNames [ichan]); } thy sound = Sound_extractPart (my sound, tmin, tmax, kSound_windowShape_RECTANGULAR, 1.0, preserveTimes).transfer(); thy textgrid = TextGrid_extractPart (my textgrid, tmin, tmax, preserveTimes).transfer(); thy xmin = thy textgrid -> xmin; thy xmax = thy textgrid -> xmax; return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": part not extracted."); } } void EEG_replaceTextGrid (EEG me, TextGrid textgrid) { try { autoTextGrid textgrid2 = Data_copy (textgrid); forget (my textgrid); my textgrid = textgrid2.transfer(); } catch (MelderError) { Melder_throw (me, U": TextGrid not replaced with ", textgrid, U"."); } } MixingMatrix EEG_to_MixingMatrix (EEG me, long maxNumberOfIterations, double tol, int method) { try { autoCrossCorrelationTables tables = Sound_to_CrossCorrelationTables (my sound, 0.0, 0.0, 0.002, 1); autoMixingMatrix thee = MixingMatrix_create (my sound -> ny, my sound -> ny); for (long ichan = 1; ichan <= my numberOfChannels; ichan ++) { TableOfReal_setRowLabel (thee.peek(), ichan, my channelNames [ichan]); TableOfReal_setColumnLabel (thee.peek(), ichan, Melder_cat (U"ic", ichan)); } MixingMatrix_and_CrossCorrelationTables_improveUnmixing (thee.peek(), tables.peek(), maxNumberOfIterations, tol, method); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no MixingMatrix created."); } } /* End of file EEG.cpp */ praat-6.0.04/EEG/EEG.h000066400000000000000000000056141261542461700140770ustar00rootroot00000000000000#ifndef _EEG_h_ #define _EEG_h_ /* EEG.h * * Copyright (C) 2011-2012,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Sound.h" #include "TextGrid.h" #include "../dwtools/ICA.h" #include "EEG_def.h" oo_CLASS_CREATE (EEG, Function); EEG EEG_create (double tmin, double tmax); EEG EEG_readFromBdfFile (MelderFile file); EEG EEGs_concatenate (Collection me); void EEG_init (EEG me, double tmin, double tmax); long EEG_getChannelNumber (EEG me, const char32 *channelName); void EEG_setChannelName (EEG me, long channelNumber, const char32 *a_name); static inline long EEG_getNumberOfCapElectrodes (EEG me) { return (my numberOfChannels - 1) & ~ 15L; // BUG } static inline long EEG_getNumberOfExtraSensors (EEG me) { return my numberOfChannels == 1 ? 0 : my numberOfChannels & 1 ? 1 : 8; // BUG } static inline long EEG_getNumberOfExternalElectrodes (EEG me) { return my numberOfChannels - EEG_getNumberOfCapElectrodes (me) - EEG_getNumberOfExtraSensors (me); } void EEG_setExternalElectrodeNames (EEG me, const char32 *nameExg1, const char32 *nameExg2, const char32 *nameExg3, const char32 *nameExg4, const char32 *nameExg5, const char32 *nameExg6, const char32 *nameExg7, const char32 *nameExg8); void EEG_detrend (EEG me); void EEG_filter (EEG me, double lowFrequency, double lowWidth, double highFrequency, double highWidth, bool doNotch50Hz); void EEG_subtractReference (EEG me, const char32 *channelNumber1, const char32 *channelNumber2); void EEG_subtractMeanChannel (EEG me, long fromChannel, long toChannel); void EEG_setChannelToZero (EEG me, long channelNumber); void EEG_setChannelToZero (EEG me, const char32 *channelName); void EEG_removeTriggers (EEG me, int which_Melder_STRING, const char32 *criterion); EEG EEG_extractChannel (EEG me, long channelNumber); EEG EEG_extractChannel (EEG me, const char32 *channelName); static inline Sound EEG_extractSound (EEG me) { return Data_copy (my sound); } static inline TextGrid EEG_extractTextGrid (EEG me) { return Data_copy (my textgrid); } EEG EEG_extractPart (EEG me, double tmin, double tmax, bool preserveTimes); void EEG_replaceTextGrid (EEG me, TextGrid textgrid); MixingMatrix EEG_to_MixingMatrix (EEG me, long maxNumberOfIterations, double tol, int method); /* End of file EEG.h */ #endif praat-6.0.04/EEG/EEGWindow.cpp000066400000000000000000000067151261542461700156250ustar00rootroot00000000000000/* EEGWindow.cpp * * Copyright (C) 2011-2012,2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "EEGWindow.h" #include "EditorM.h" Thing_implement (EEGWindow, TextGridEditor, 0); #include "prefs_define.h" #include "EEGWindow_prefs.h" #include "prefs_install.h" #include "EEGWindow_prefs.h" #include "prefs_copyToInstance.h" #include "EEGWindow_prefs.h" static void menu_cb_EEGWindowHelp (EDITOR_ARGS) { EDITOR_IAM (EEGWindow); Melder_help (U"EEG window"); } void structEEGWindow :: v_createMenus () { EEGWindow_Parent :: v_createMenus (); } void structEEGWindow :: v_createHelpMenuItems (EditorMenu menu) { TextGridEditor_Parent :: v_createHelpMenuItems (menu); EditorMenu_addCommand (menu, U"EEGWindow help", '?', menu_cb_EEGWindowHelp); } const char32 * structEEGWindow :: v_getChannelName (long channelNumber) { Melder_assert (our eeg != nullptr); return our eeg -> channelNames [channelNumber]; } static void menu_cb_ExtractSelectedEEG_preserveTimes (EDITOR_ARGS) { EDITOR_IAM (EEGWindow); if (my d_endSelection <= my d_startSelection) Melder_throw (U"No selection."); autoEEG extract = EEG_extractPart (my eeg, my d_startSelection, my d_endSelection, true); Editor_broadcastPublication (me, extract.transfer()); } static void menu_cb_ExtractSelectedEEG_timeFromZero (EDITOR_ARGS) { EDITOR_IAM (EEGWindow); if (my d_endSelection <= my d_startSelection) Melder_throw (U"No selection."); autoEEG extract = EEG_extractPart (my eeg, my d_startSelection, my d_endSelection, false); Editor_broadcastPublication (me, extract.transfer()); } void structEEGWindow :: v_createMenuItems_file_extract (EditorMenu menu) { EEGWindow_Parent :: v_createMenuItems_file_extract (menu); our extractSelectedEEGPreserveTimesButton = EditorMenu_addCommand (menu, U"Extract selected EEG (preserve times)", 0, menu_cb_ExtractSelectedEEG_preserveTimes); our extractSelectedEEGTimeFromZeroButton = EditorMenu_addCommand (menu, U"Extract selected EEG (time from zero)", 0, menu_cb_ExtractSelectedEEG_timeFromZero); } void structEEGWindow :: v_updateMenuItems_file () { EEGWindow_Parent :: v_updateMenuItems_file (); GuiThing_setSensitive (our extractSelectedEEGPreserveTimesButton, d_endSelection > d_startSelection); GuiThing_setSensitive (our extractSelectedEEGTimeFromZeroButton, d_endSelection > d_startSelection); } void EEGWindow_init (EEGWindow me, const char32 *title, EEG eeg) { my eeg = eeg; // before initing, because initing will already draw! TextGridEditor_init (me, title, eeg -> textgrid, eeg -> sound, false, nullptr, nullptr); } autoEEGWindow EEGWindow_create (const char32 *title, EEG eeg) { try { autoEEGWindow me = Thing_new (EEGWindow); EEGWindow_init (me.peek(), title, eeg); return me; } catch (MelderError) { Melder_throw (U"EEG window not created."); } } /* End of file EEGWindow.cpp */ praat-6.0.04/EEG/EEGWindow.h000066400000000000000000000032301261542461700152570ustar00rootroot00000000000000#ifndef _EEGWindow_h_ #define _EEGWindow_h_ /* EEGWindow.h * * Copyright (C) 2011-2012,2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "TextGridEditor.h" #include "EEG.h" Thing_define (EEGWindow, TextGridEditor) { EEG eeg; GuiMenuItem extractSelectedEEGPreserveTimesButton, extractSelectedEEGTimeFromZeroButton; bool v_hasPitch () override { return false; } bool v_hasIntensity () override { return false; } bool v_hasFormants () override { return false; } bool v_hasPulses () override { return false; } void v_createMenus () override; void v_createHelpMenuItems (EditorMenu menu) override; const char32 * v_getChannelName (long channelNumber) override; void v_createMenuItems_file_extract (EditorMenu menu) override; void v_updateMenuItems_file () override; #include "EEGWindow_prefs.h" }; void EEGWindow_init (EEGWindow me, const char32 *title, EEG eeg); autoEEGWindow EEGWindow_create (const char32 *title, EEG eeg); /* End of file EEGWindow.h */ #endif praat-6.0.04/EEG/EEGWindow_prefs.h000066400000000000000000000051601261542461700164620ustar00rootroot00000000000000/* EEGWindow_prefs.h * * Copyright (C) 2013,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ prefs_begin (EEGWindow) prefs_override_bool (EEGWindow, showSelectionViewer, 1, false) prefs_override_enum (EEGWindow, sound_scalingStrategy, 1, kTimeSoundEditor_scalingStrategy, DEFAULT) prefs_override_double (EEGWindow, sound_scaling_height, 1, U"20e-6") prefs_override_double (EEGWindow, sound_scaling_minimum, 1, U"-10e-6") prefs_override_double (EEGWindow, sound_scaling_maximum, 1, U"10e-6") prefs_override_double (EEGWindow, picture_bottom, 1, U"0.0") prefs_override_double (EEGWindow, picture_top, 1, U"0.0 (= auto)") prefs_override_bool (EEGWindow, spectrogram_show, 1, false); prefs_override_double (EEGWindow, spectrogram_viewFrom, 1, U"0.0") // Hz prefs_override_double (EEGWindow, spectrogram_viewTo, 1, U"60.0") // Hz prefs_override_double (EEGWindow, spectrogram_windowLength, 1, U"0.5") // seconds prefs_override_double (EEGWindow, spectrogram_dynamicRange, 1, U"40.0") // dB prefs_override_long (EEGWindow, spectrogram_timeSteps, 1, U"1000") prefs_override_long (EEGWindow, spectrogram_frequencySteps, 1, U"250") prefs_override_enum (EEGWindow, spectrogram_method, 1, kSound_to_Spectrogram_method, DEFAULT) prefs_override_enum (EEGWindow, spectrogram_windowShape, 1, kSound_to_Spectrogram_windowShape, DEFAULT) prefs_override_bool (EEGWindow, spectrogram_autoscaling, 1, true) prefs_override_double (EEGWindow, spectrogram_maximum, 1, U"100.0") // dB/Hz prefs_override_double (EEGWindow, spectrogram_preemphasis, 1, U"0.0") // dB/octave prefs_override_double (EEGWindow, spectrogram_dynamicCompression, 1, U"0.0") prefs_override_bool (EEGWindow, spectrogram_picture_garnish, 1, true) prefs_end (EEGWindow) /* End of file EEGWindow_prefs.h */ praat-6.0.04/EEG/EEG_def.h000066400000000000000000000024411261542461700147100ustar00rootroot00000000000000/* EEG_def.h * * Copyright (C) 2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT EEG oo_DEFINE_CLASS (EEG, Function) oo_LONG (numberOfChannels) oo_STRING_VECTOR (channelNames, numberOfChannels) oo_OBJECT (Sound, 2, sound) oo_OBJECT (TextGrid, 0, textgrid) #if oo_DECLARING void v_info () override; int v_domainQuantity () override { return MelderQuantity_TIME_SECONDS; } void v_shiftX (double xfrom, double xto) override; void v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto) override; #endif oo_END_CLASS (EEG) #undef ooSTRUCT /* End of file EEG_def.h */ praat-6.0.04/EEG/ERP.cpp000066400000000000000000000115351261542461700144570ustar00rootroot00000000000000/* ERP.cpp * * Copyright (C) 2011-2012,2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ERP.h" #include "oo_DESTROY.h" #include "ERP_def.h" #include "oo_COPY.h" #include "ERP_def.h" #include "oo_EQUAL.h" #include "ERP_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "ERP_def.h" #include "oo_WRITE_TEXT.h" #include "ERP_def.h" #include "oo_READ_TEXT.h" #include "ERP_def.h" #include "oo_WRITE_BINARY.h" #include "ERP_def.h" #include "oo_READ_BINARY.h" #include "ERP_def.h" #include "oo_DESCRIPTION.h" #include "ERP_def.h" /********** class ERPTier **********/ Thing_implement (ERP, Sound, 2); long ERP_getChannelNumber (ERP me, const char32 *channelName) { for (long ichan = 1; ichan <= my ny; ichan ++) { if (Melder_equ (my channelNames [ichan], channelName)) { return ichan; } } return 0; } void ERP_drawChannel_number (ERP me, Graphics graphics, long channelNumber, double tmin, double tmax, double vmin, double vmax, bool garnish) { if (channelNumber < 1 || channelNumber > my ny) return; /* * Automatic domain. */ if (tmin == tmax) { tmin = my xmin; tmax = my xmax; } /* * Domain expressed in sample numbers. */ long ixmin, ixmax; Matrix_getWindowSamplesX (me, tmin, tmax, & ixmin, & ixmax); /* * Automatic vertical range. */ if (vmin == vmax) { Matrix_getWindowExtrema (me, ixmin, ixmax, channelNumber, channelNumber, & vmin, & vmax); if (vmin == vmax) { vmin -= 1.0; vmax += 1.0; } } /* * Set coordinates for drawing. */ Graphics_setInner (graphics); Graphics_setWindow (graphics, tmin, tmax, vmin, vmax); Graphics_function (graphics, my z [channelNumber], ixmin, ixmax, Matrix_columnToX (me, ixmin), Matrix_columnToX (me, ixmax)); Graphics_unsetInner (graphics); if (garnish) { Graphics_drawInnerBox (graphics); Graphics_textTop (graphics, true, Melder_cat (U"Channel ", my channelNames [channelNumber])); Graphics_textBottom (graphics, true, U"Time (s)"); Graphics_marksBottom (graphics, 2, true, true, false); if (0.0 > tmin && 0.0 < tmax) Graphics_markBottom (graphics, 0.0, true, true, true, nullptr); Graphics_markLeft (graphics, vmin, true, true, false, nullptr); Graphics_markLeft (graphics, vmax, true, true, false, nullptr); Graphics_markBottom (graphics, 0.0, true, true, true, nullptr); if (vmin != 0.0 && vmax != 0.0 && (vmin > 0.0) != (vmax > 0.0)) { Graphics_markLeft (graphics, 0.0, true, true, true, nullptr); } } } void ERP_drawChannel_name (ERP me, Graphics graphics, const char32 *channelName, double tmin, double tmax, double vmin, double vmax, bool garnish) { ERP_drawChannel_number (me, graphics, ERP_getChannelNumber (me, channelName), tmin, tmax, vmin, vmax, garnish); } Table ERP_tabulate (ERP me, bool includeSampleNumbers, bool includeTime, int timeDecimals, int voltageDecimals, int units) { double voltageScaling = 1.0; const char32 *unitText = U"(V)"; if (units == 2) { voltageDecimals -= 6; voltageScaling = 1000000.0; unitText = U"(uV)"; } try { autoTable thee = Table_createWithoutColumnNames (my nx, includeSampleNumbers + includeTime + my ny); long icol = 0; if (includeSampleNumbers) Table_setColumnLabel (thee.peek(), ++ icol, U"sample"); if (includeTime) Table_setColumnLabel (thee.peek(), ++ icol, U"time(s)"); for (long ichan = 1; ichan <= my ny; ichan ++) { Table_setColumnLabel (thee.peek(), ++ icol, Melder_cat (my channelNames [ichan], unitText)); } for (long isamp = 1; isamp <= my nx; isamp ++) { icol = 0; if (includeSampleNumbers) Table_setNumericValue (thee.peek(), isamp, ++ icol, isamp); if (includeTime) Table_setStringValue (thee.peek(), isamp, ++ icol, Melder_fixed (my x1 + (isamp - 1) * my dx, timeDecimals)); for (long ichan = 1; ichan <= my ny; ichan ++) { Table_setStringValue (thee.peek(), isamp, ++ icol, Melder_fixed (voltageScaling * my z [ichan] [isamp], voltageDecimals)); } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not converted to Table."); } } Sound ERP_downto_Sound (ERP me) { try { autoSound thee = Thing_new (Sound); my structSound :: v_copy (thee.peek()); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not converted to Sound."); } } /* End of file ERP.cpp */ praat-6.0.04/EEG/ERP.h000066400000000000000000000035671261542461700141320ustar00rootroot00000000000000#ifndef _ERP_h_ #define _ERP_h_ /* ERP.h * * Copyright (C) 2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Sound.h" #include "ERP_def.h" oo_CLASS_CREATE (ERP, Sound); /** Look up the channel number from its name. */ long ERP_getChannelNumber (ERP me, const char32 *channelName); /** * Draw the scalp distribution. * @param tmin: the time window. * @param tmax: the time window. */ void ERP_drawScalp (ERP me, Graphics graphics, double tmin, double tmax, double vmin, double vmax, enum kGraphics_colourScale colourScale, bool garnish); void ERP_drawScalp_garnish (Graphics graphics, double vmin, double vmax, enum kGraphics_colourScale colourScale); void ERP_drawChannel_number (ERP me, Graphics graphics, long channelNumber, double tmin, double tmax, double vmin, double vmax, bool garnish); void ERP_drawChannel_name (ERP me, Graphics graphics, const char32 *channelName, double tmin, double tmax, double vmin, double vmax, bool garnish); Table ERP_tabulate (ERP me, bool includeSampleNumbers, bool includeTime, int timeDecimals, int voltageDecimals, int units); /** Extract the Sound part from the ERP. The channel names are lost. */ Sound ERP_downto_Sound (ERP me); /* End of file ERP.h */ #endif praat-6.0.04/EEG/ERPTier.cpp000066400000000000000000000347301261542461700153050ustar00rootroot00000000000000/* ERPTier.cpp * * Copyright (C) 2011-2012,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ERPTier.h" #include "oo_DESTROY.h" #include "ERPTier_def.h" #include "oo_COPY.h" #include "ERPTier_def.h" #include "oo_EQUAL.h" #include "ERPTier_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "ERPTier_def.h" #include "oo_WRITE_TEXT.h" #include "ERPTier_def.h" #include "oo_READ_TEXT.h" #include "ERPTier_def.h" #include "oo_WRITE_BINARY.h" #include "ERPTier_def.h" #include "oo_READ_BINARY.h" #include "ERPTier_def.h" #include "oo_DESCRIPTION.h" #include "ERPTier_def.h" /***** ERPPoint *****/ Thing_implement (ERPPoint, AnyPoint, 0); /***** ERPTier *****/ Thing_implement (ERPTier, Function, 0); void structERPTier :: v_shiftX (double xfrom, double xto) { ERPTier_Parent :: v_shiftX (xfrom, xto); //if (our sound ) Function_shiftXTo (our sound, xfrom, xto); //if (our textgrid) Function_shiftXTo (our textgrid, xfrom, xto); } void structERPTier :: v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto) { ERPTier_Parent :: v_scaleX (xminfrom, xmaxfrom, xminto, xmaxto); //if (our sound ) our sound -> v_scaleX (xminfrom, xmaxfrom, xminto, xmaxto); //if (our textgrid) our textgrid -> v_scaleX (xminfrom, xmaxfrom, xminto, xmaxto); } long ERPTier_getChannelNumber (ERPTier me, const char32 *channelName) { for (long ichan = 1; ichan <= my numberOfChannels; ichan ++) { if (Melder_equ (my channelNames [ichan], channelName)) { return ichan; } } return 0; } double ERPTier_getMean (ERPTier me, long pointNumber, long channelNumber, double tmin, double tmax) { if (pointNumber < 1 || pointNumber > my events -> size) return NUMundefined; if (channelNumber < 1 || channelNumber > my numberOfChannels) return NUMundefined; ERPPoint point = my event (pointNumber); return Vector_getMean (point -> erp.get(), tmin, tmax, channelNumber); } double ERPTier_getMean (ERPTier me, long pointNumber, const char32 *channelName, double tmin, double tmax) { return ERPTier_getMean (me, pointNumber, ERPTier_getChannelNumber (me, channelName), tmin, tmax); } static ERPTier EEG_PointProcess_to_ERPTier (EEG me, PointProcess events, double fromTime, double toTime) { try { autoERPTier thee = Thing_new (ERPTier); Function_init (thee.peek(), fromTime, toTime); thy numberOfChannels = my numberOfChannels - EEG_getNumberOfExtraSensors (me); Melder_assert (thy numberOfChannels > 0); thy channelNames = NUMvector (1, thy numberOfChannels); for (long ichan = 1; ichan <= thy numberOfChannels; ichan ++) { thy channelNames [ichan] = Melder_dup (my channelNames [ichan]); } long numberOfEvents = events -> nt; thy events = SortedSetOfDouble_create (); double soundDuration = toTime - fromTime; double samplingPeriod = my sound -> dx; long numberOfSamples = (long) floor (soundDuration / samplingPeriod) + 1; if (numberOfSamples < 1) Melder_throw (U"Time window too short."); double midTime = 0.5 * (fromTime + toTime); double soundPhysicalDuration = numberOfSamples * samplingPeriod; double firstTime = midTime - 0.5 * soundPhysicalDuration + 0.5 * samplingPeriod; // distribute the samples evenly over the time domain for (long ievent = 1; ievent <= numberOfEvents; ievent ++) { double eegEventTime = events -> t [ievent]; autoERPPoint event = Thing_new (ERPPoint); event -> number = eegEventTime; event -> erp = Sound_create (thy numberOfChannels, fromTime, toTime, numberOfSamples, samplingPeriod, firstTime); double erpEventTime = 0.0; double eegSample = 1 + (eegEventTime - my sound -> x1) / samplingPeriod; double erpSample = 1 + (erpEventTime - firstTime) / samplingPeriod; long sampleDifference = lround (eegSample - erpSample); for (long ichannel = 1; ichannel <= thy numberOfChannels; ichannel ++) { for (long isample = 1; isample <= numberOfSamples; isample ++) { long jsample = isample + sampleDifference; event -> erp -> z [ichannel] [isample] = jsample < 1 || jsample > my sound -> nx ? 0.0 : my sound -> z [ichannel] [jsample]; } } Collection_addItem (thy events, event.transfer()); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": ERP analysis not performed."); } } ERPTier EEG_to_ERPTier_bit (EEG me, double fromTime, double toTime, int markerBit) { try { autoPointProcess events = TextGrid_getStartingPoints (my textgrid, markerBit, kMelder_string_EQUAL_TO, U"1"); autoERPTier thee = EEG_PointProcess_to_ERPTier (me, events.peek(), fromTime, toTime); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": ERPTier not created."); } } static autoPointProcess TextGrid_getStartingPoints_multiNumeric (TextGrid me, uint16_t number) { try { autoPointProcess thee; int numberOfBits = my numberOfTiers(); for (int ibit = 0; ibit < numberOfBits; ibit ++) { (void) TextGrid_checkSpecifiedTierIsIntervalTier (me, ibit + 1); if (number & (1 << ibit)) { autoPointProcess bitEvents = TextGrid_getStartingPoints (me, ibit + 1, kMelder_string_EQUAL_TO, U"1"); if (thee) { thee = PointProcesses_intersection (thee.peek(), bitEvents.peek()); } else { thee = bitEvents.move(); } } } for (int ibit = 0; ibit < numberOfBits; ibit ++) { autoPointProcess bitEvents = TextGrid_getStartingPoints (me, ibit + 1, kMelder_string_EQUAL_TO, U"1"); if (! (number & (1 << ibit))) { if (thee) { thee = PointProcesses_difference (thee.peek(), bitEvents.peek()); } else { thee = PointProcess_create (my xmin, my xmax, 10); } } } return thee; } catch (MelderError) { Melder_throw (me, U": starting points not converted to PointProcess."); } } ERPTier EEG_to_ERPTier_marker (EEG me, double fromTime, double toTime, uint16_t marker) { try { autoPointProcess events = TextGrid_getStartingPoints_multiNumeric (my textgrid, marker); autoERPTier thee = EEG_PointProcess_to_ERPTier (me, events.peek(), fromTime, toTime); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": ERPTier not created."); } } ERPTier EEG_to_ERPTier_triggers (EEG me, double fromTime, double toTime, int which_Melder_STRING, const char32 *criterion) { try { autoPointProcess events = TextGrid_getPoints (my textgrid, 2, which_Melder_STRING, criterion); autoERPTier thee = EEG_PointProcess_to_ERPTier (me, events.peek(), fromTime, toTime); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": ERPTier not created."); } } ERPTier EEG_to_ERPTier_triggers_preceded (EEG me, double fromTime, double toTime, int which_Melder_STRING, const char32 *criterion, int which_Melder_STRING_precededBy, const char32 *criterion_precededBy) { try { autoPointProcess events = TextGrid_getPoints_preceded (my textgrid, 2, which_Melder_STRING, criterion, which_Melder_STRING_precededBy, criterion_precededBy); autoERPTier thee = EEG_PointProcess_to_ERPTier (me, events.peek(), fromTime, toTime); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": ERPTier not created."); } } void ERPTier_subtractBaseline (ERPTier me, double tmin, double tmax) { long numberOfEvents = my events -> size; if (numberOfEvents < 1) return; // nothing to do ERPPoint firstEvent = my event (1); long numberOfChannels = firstEvent -> erp -> ny; long numberOfSamples = firstEvent -> erp -> nx; for (long ievent = 1; ievent <= numberOfEvents; ievent ++) { ERPPoint event = my event (ievent); for (long ichannel = 1; ichannel <= numberOfChannels; ichannel ++) { double mean = Vector_getMean (event -> erp.get(), tmin, tmax, ichannel); double *channel = event -> erp -> z [ichannel]; for (long isample = 1; isample <= numberOfSamples; isample ++) { channel [isample] -= mean; } } } } void ERPTier_rejectArtefacts (ERPTier me, double threshold) { long numberOfEvents = my events -> size; if (numberOfEvents < 1) return; // nothing to do ERPPoint firstEvent = my event (1); long numberOfChannels = firstEvent -> erp -> ny; long numberOfSamples = firstEvent -> erp -> nx; if (numberOfSamples < 1) return; // nothing to do for (long ievent = numberOfEvents; ievent >= 1; ievent --) { // cycle down because of removal ERPPoint event = my event (ievent); double minimum = event -> erp -> z [1] [1]; double maximum = minimum; for (long ichannel = 1; ichannel <= (numberOfChannels & ~ 15); ichannel ++) { double *channel = event -> erp -> z [ichannel]; for (long isample = 1; isample <= numberOfSamples; isample ++) { double value = channel [isample]; if (value < minimum) minimum = value; if (value > maximum) maximum = value; } } if (minimum < - threshold || maximum > threshold) { Collection_removeItem (my events, ievent); } } } ERP ERPTier_extractERP (ERPTier me, long eventNumber) { try { long numberOfEvents = my events -> size; if (numberOfEvents < 1) Melder_throw (U"No events."); ERPTier_checkEventNumber (me, eventNumber); ERPPoint event = my event (eventNumber); long numberOfChannels = event -> erp -> ny; long numberOfSamples = event -> erp -> nx; autoERP thee = Thing_new (ERP); event -> erp -> structSound :: v_copy (thee.peek()); for (long ichannel = 1; ichannel <= numberOfChannels; ichannel ++) { double *oldChannel = event -> erp -> z [ichannel]; double *newChannel = thy z [ichannel]; for (long isample = 1; isample <= numberOfSamples; isample ++) { newChannel [isample] = oldChannel [isample]; } } thy channelNames = NUMvector (1, thy ny); for (long ichan = 1; ichan <= thy ny; ichan ++) { thy channelNames [ichan] = Melder_dup (my channelNames [ichan]); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": ERP not extracted."); } } ERP ERPTier_to_ERP_mean (ERPTier me) { try { long numberOfEvents = my events -> size; if (numberOfEvents < 1) Melder_throw (U"No events."); ERPPoint firstEvent = my event (1); long numberOfChannels = firstEvent -> erp -> ny; long numberOfSamples = firstEvent -> erp -> nx; autoERP mean = Thing_new (ERP); firstEvent -> erp -> structSound :: v_copy (mean.peek()); for (long ievent = 2; ievent <= numberOfEvents; ievent ++) { ERPPoint event = my event (ievent); for (long ichannel = 1; ichannel <= numberOfChannels; ichannel ++) { double *erpChannel = event -> erp -> z [ichannel]; double *meanChannel = mean -> z [ichannel]; for (long isample = 1; isample <= numberOfSamples; isample ++) { meanChannel [isample] += erpChannel [isample]; } } } double factor = 1.0 / numberOfEvents; for (long ichannel = 1; ichannel <= numberOfChannels; ichannel ++) { double *meanChannel = mean -> z [ichannel]; for (long isample = 1; isample <= numberOfSamples; isample ++) { meanChannel [isample] *= factor; } } mean -> channelNames = NUMvector (1, mean -> ny); for (long ichan = 1; ichan <= mean -> ny; ichan ++) { mean -> channelNames [ichan] = Melder_dup (my channelNames [ichan]); } return mean.transfer(); } catch (MelderError) { Melder_throw (me, U": mean not computed."); } } ERPTier ERPTier_extractEventsWhereColumn_number (ERPTier me, Table table, long columnNumber, int which_Melder_NUMBER, double criterion) { try { Table_checkSpecifiedColumnNumberWithinRange (table, columnNumber); Table_numericize_Assert (table, columnNumber); // extraction should work even if cells are not defined if (my events -> size != table -> rows -> size) Melder_throw (me, U" & ", table, U": the number of rows in the table (", table -> rows -> size, U") doesn't match the number of events (", my events -> size, U")."); autoERPTier thee = Thing_new (ERPTier); Function_init (thee.peek(), my xmin, my xmax); thy numberOfChannels = my numberOfChannels; thy channelNames = NUMvector (1, thy numberOfChannels); for (long ichan = 1; ichan <= thy numberOfChannels; ichan ++) { thy channelNames [ichan] = Melder_dup (my channelNames [ichan]); } thy events = SortedSetOfDouble_create (); for (long ievent = 1; ievent <= my events -> size; ievent ++) { ERPPoint oldEvent = my event (ievent); TableRow row = table -> row (ievent); if (Melder_numberMatchesCriterion (row -> cells [columnNumber]. number, which_Melder_NUMBER, criterion)) { autoERPPoint newEvent = Data_copy (oldEvent); Collection_addItem (thy events, newEvent.transfer()); } } if (thy events -> size == 0) { Melder_warning (U"No event matches criterion."); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": events not extracted."); } } ERPTier ERPTier_extractEventsWhereColumn_string (ERPTier me, Table table, long columnNumber, int which_Melder_STRING, const char32 *criterion) { try { Table_checkSpecifiedColumnNumberWithinRange (table, columnNumber); if (my events -> size != table -> rows -> size) Melder_throw (me, U" & ", table, U": the number of rows in the table (", table -> rows -> size, U") doesn't match the number of events (", my events -> size, U")."); autoERPTier thee = Thing_new (ERPTier); Function_init (thee.peek(), my xmin, my xmax); thy numberOfChannels = my numberOfChannels; thy channelNames = NUMvector (1, thy numberOfChannels); for (long ichan = 1; ichan <= thy numberOfChannels; ichan ++) { thy channelNames [ichan] = Melder_dup (my channelNames [ichan]); } thy events = SortedSetOfDouble_create (); for (long ievent = 1; ievent <= my events -> size; ievent ++) { ERPPoint oldEvent = my event (ievent); TableRow row = table -> row (ievent); if (Melder_stringMatchesCriterion (row -> cells [columnNumber]. string, which_Melder_STRING, criterion)) { autoERPPoint newEvent = Data_copy (oldEvent); Collection_addItem (thy events, newEvent.transfer()); } } if (thy events -> size == 0) { Melder_warning (U"No event matches criterion."); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": events not extracted."); } } /* End of file ERPTier.cpp */ praat-6.0.04/EEG/ERPTier.h000066400000000000000000000051111261542461700147410ustar00rootroot00000000000000#ifndef _ERPTier_h_ #define _ERPTier_h_ /* ERPTier.h * * Copyright (C) 2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "EEG.h" #include "ERP.h" #include "ERPTier_def.h" oo_CLASS_CREATE (ERPPoint, AnyPoint); oo_CLASS_CREATE (ERPTier, Function); long ERPTier_getChannelNumber (ERPTier me, const char32 *channelName); static inline void ERPTier_checkEventNumber (ERPTier me, long eventNumber) { if (eventNumber < 1) Melder_throw (U"The specified event number is ", eventNumber, U" but should have been positive."); if (eventNumber > my events -> size) Melder_throw (U"The specified event number (", eventNumber, U") exceeds the number of events (", my events -> size, U")."); } double ERPTier_getMean (ERPTier me, long pointNumber, long channelNumber, double tmin, double tmax); double ERPTier_getMean (ERPTier me, long pointNumber, const char32 *channelName, double tmin, double tmax); void ERPTier_subtractBaseline (ERPTier me, double tmin, double tmax); void ERPTier_rejectArtefacts (ERPTier me, double threshold); ERP ERPTier_extractERP (ERPTier me, long pointNumber); ERP ERPTier_to_ERP_mean (ERPTier me); ERPTier ERPTier_extractEventsWhereColumn_number (ERPTier me, Table table, long columnNumber, int which_Melder_NUMBER, double criterion); ERPTier ERPTier_extractEventsWhereColumn_string (ERPTier me, Table table, long columnNumber, int which_Melder_STRING, const char32 *criterion); ERPTier EEG_to_ERPTier_bit (EEG me, double fromTime, double toTime, int markerBit); ERPTier EEG_to_ERPTier_marker (EEG me, double fromTime, double toTime, uint16 marker); ERPTier EEG_to_ERPTier_triggers (EEG me, double fromTime, double toTime, int which_Melder_STRING, const char32 *criterion); ERPTier EEG_to_ERPTier_triggers_preceded (EEG me, double fromTime, double toTime, int which_Melder_STRING, const char32 *criterion, int which_Melder_STRING_precededBy, const char32 *criterion_precededBy); /* End of file ERPTier.h */ #endif praat-6.0.04/EEG/ERPTier_def.h000066400000000000000000000030131261542461700155560ustar00rootroot00000000000000/* ERPTier_def.h * * Copyright (C) 2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT ERPPoint oo_DEFINE_CLASS (ERPPoint, AnyPoint) oo_AUTO_OBJECT (Sound, 2, erp) oo_END_CLASS (ERPPoint) #undef ooSTRUCT #define ooSTRUCT ERPTier oo_DEFINE_CLASS (ERPTier, Function) oo_COLLECTION (SortedSetOfDouble, events, ERPPoint, 0) oo_LONG (numberOfChannels) oo_STRING_VECTOR (channelNames, numberOfChannels) #if oo_DECLARING ERPPoint event (long i) // rvalue accessor { return static_cast (our events -> item [i]); } int v_domainQuantity () override { return MelderQuantity_TIME_SECONDS; } void v_shiftX (double xfrom, double xto) override; void v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto) override; #endif oo_END_CLASS (ERPTier) #undef ooSTRUCT /* End of file ERPTier_def.h */ praat-6.0.04/EEG/ERPWindow.cpp000066400000000000000000000360171261542461700156510ustar00rootroot00000000000000/* ERPWindow.cpp * * Copyright (C) 2012,2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ERPWindow.h" #include "EditorM.h" #include "Preferences.h" Thing_implement (ERPWindow, SoundEditor, 0); #include "prefs_define.h" #include "ERPWindow_prefs.h" #include "prefs_install.h" #include "ERPWindow_prefs.h" #include "prefs_copyToInstance.h" #include "ERPWindow_prefs.h" typedef struct { int inclination, azimuth; double topX, topY; } BiosemiLocationData; static BiosemiLocationData biosemiCapCoordinates64 [1+64] = { /* * BioSemi says: * "Spherical coordinates in degrees, * by inclination (from Cz, pos is right hemisphere, neg is left hemisphere), * and azimuth (from T7 for left hemisphere, and from T8 for the right hemisphere, pos is anti-clockwise, neg is clockwise)" */ {0,0}, { -92, -72 }, // 1 Fp1 { -92, -54 }, // 2 AF7 { -74, -65 }, // 3 AF3 { -50, -68 }, // 4 F1 { -60, -51 }, // 5 F3 { -75, -41 }, // 6 F5 { -92, -36 }, // 7 F7 { -92, -18 }, // 8 FT7 { -72, -21 }, // 9 FC5 { -50, -28 }, // 10 FC3 { -32, -45 }, // 11 FC1 { -23, 0 }, // 12 C1 { -46, 0 }, // 13 C3 { -69, 0 }, // 14 C5 { -92, 0 }, // 15 T7 { -92, 18 }, // 16 TP7 { -72, 21 }, // 17 CP5 { -50, 28 }, // 18 CP3 { -32, 45 }, // 19 CP1 { -50, 68 }, // 20 P1 { -60, 51 }, // 21 P3 { -75, 41 }, // 22 P5 { -92, 36 }, // 23 P7 {-115, 40 }, // 24 P9 { -92, 54 }, // 25 PO7 { -74, 65 }, // 26 PO3 { -92, 72 }, // 27 O1 { 115, -90 }, // 28 Iz { 92, -90 }, // 29 Oz { 69, -90 }, // 30 POz { 46, -90 }, // 31 Pz { 23, -90 }, // 32 CPz { 92, 90 }, // 33 Fpz { 92, 72 }, // 34 Fp2 { 92, 54 }, // 35 AF8 { 74, 65 }, // 36 AF4 { 69, 90 }, // 37 AFz { 46, 90 }, // 38 Fz { 50, 68 }, // 39 F2 { 60, 51 }, // 40 F4 { 75, 41 }, // 41 F6 { 92, 36 }, // 42 F8 { 92, 18 }, // 43 FT8 { 72, 21 }, // 44 FC6 { 50, 28 }, // 45 FC4 { 32, 45 }, // 46 FC2 { 23, 90 }, // 47 FCz { 0, 0 }, // 48 Cz { 23, 0 }, // 49 C2 { 46, 0 }, // 50 C4 { 69, 0 }, // 51 C6 { 92, 0 }, // 52 T8 { 92, -18 }, // 53 TP8 { 72, -21 }, // 54 CP6 { 50, -28 }, // 55 CP4 { 32, -45 }, // 56 CP2 { 50, -68 }, // 57 P2 { 60, -51 }, // 58 P4 { 75, -41 }, // 59 P6 { 92, -36 }, // 60 P8 { 115, -40 }, // 61 P10 { 92, -54 }, // 62 PO8 { 74, -65 }, // 63 PO4 { 92, -72 } // 64 O2 }; static BiosemiLocationData biosemiCapCoordinates32 [1+32] = { /* * BioSemi says: * "Spherical coordinates in degrees, * by inclination (from Cz, pos is right hemisphere, neg is left hemisphere), * and azimuth (from T7 for left hemisphere, and from T8 for the right hemisphere, pos is anti-clockwise, neg is clockwise)" */ {0,0}, { -92, -72 }, // 1 Fp1 { -74, -65 }, // 2 AF3 { -92, -36 }, // 3 F7 { -60, -51 }, // 4 F3 { -32, -45 }, // 5 FC1 { -72, -21 }, // 6 FC5 { -92, 0 }, // 7 T7 { -46, 0 }, // 8 C3 { -32, 45 }, // 9 CP1 { -72, 21 }, // 10 CP5 { -92, 36 }, // 11 P7 { -60, 51 }, // 12 P3 { 46, -90 }, // 13 Pz { -74, 65 }, // 14 PO3 { -92, 72 }, // 15 O1 { 92, -90 }, // 16 Oz { 92, -72 }, // 17 O2 { 74, -65 }, // 18 PO4 { 60, -51 }, // 19 P4 { 92, -36 }, // 20 P8 { 72, -21 }, // 21 CP6 { 32, -45 }, // 22 CP2 { 46, 0 }, // 23 C4 { 92, 0 }, // 24 T8 { 72, 21 }, // 25 FC6 { 32, 45 }, // 26 FC2 { 60, 51 }, // 27 F4 { 92, 36 }, // 28 F8 { 74, 65 }, // 29 AF4 { 92, 72 }, // 30 Fp2 { 46, 90 }, // 31 Fz { 0, 0 }, // 32 Cz }; void ERP_drawScalp_garnish (Graphics graphics, double vmin, double vmax, enum kGraphics_colourScale colourScale) { long n = 201; autoNUMmatrix legend (1, n, 1, 2); for (long irow = 1; irow <= n; irow ++) { for (long icol = 1; icol <= 2; icol ++) { legend [irow] [icol] = (irow - 1) / (n - 1.0); } } Graphics_setColourScale (graphics, colourScale); Graphics_image (graphics, legend.peek(), 1, 2, 0.85, 0.98, 1, n, -0.8, +0.8, 0.0, 1.0); Graphics_setColourScale (graphics, kGraphics_colourScale_GREY); Graphics_rectangle (graphics, 0.85, 0.98, -0.8, +0.8); Graphics_setTextAlignment (graphics, Graphics_RIGHT, Graphics_TOP); Graphics_text (graphics, 1.0, -0.8, vmin * 1e6, U" μV"); Graphics_setTextAlignment (graphics, Graphics_RIGHT, Graphics_BOTTOM); Graphics_text (graphics, 1.0, +0.8, vmax * 1e6, U" μV"); } void ERP_drawScalp (ERP me, Graphics graphics, double tmin, double tmax, double vmin, double vmax, enum kGraphics_colourScale colourScale, bool garnish) { Graphics_setInner (graphics); Graphics_setWindow (graphics, -1.0, 1.0, -1.0, 1.0); //Graphics_setGrey (graphics, 1.0); //Graphics_fillRectangle (graphics, -1.1, 1.1, -1.01, 1.19); //Graphics_setColour (graphics, Graphics_BLACK); long numberOfDrawableChannels = my ny >= 64 && Melder_equ (my channelNames [64], U"O2") ? 64 : my ny >= 32 && Melder_equ (my channelNames [32], U"Cz") ? 32 : 0; BiosemiLocationData *biosemiLocationData = numberOfDrawableChannels == 64 ? biosemiCapCoordinates64 : numberOfDrawableChannels == 32 ? biosemiCapCoordinates32 : 0; for (long ichan = 1; ichan <= numberOfDrawableChannels; ichan ++) { double inclination = (double) biosemiLocationData [ichan]. inclination; double azimuth = (double) biosemiLocationData [ichan]. azimuth; bool rightHemisphere = inclination >= 0.0; double r = fabs (inclination / 115.0); double theta = rightHemisphere ? azimuth * (NUMpi / 180.0) : (azimuth + 180.0) * (NUMpi / 180.0); biosemiLocationData [ichan]. topX = r * cos (theta); biosemiLocationData [ichan]. topY = r * sin (theta); } long n = 201; double d = 2.0 / (n - 1); autoNUMvector mean (1, numberOfDrawableChannels); for (long ichan = 1; ichan <= numberOfDrawableChannels; ichan ++) { mean [ichan] = tmin == tmax ? Sampled_getValueAtX (me, tmin, ichan, 0, true) : Vector_getMean (me, tmin, tmax, ichan); } autoNUMmatrix image (1, n, 1, n); for (long irow = 1; irow <= n; irow ++) { double y = -1.0 + (irow - 1) * d; for (long icol = 1; icol <= n; icol ++) { double x = -1.0 + (icol - 1) * d; if (x * x + y * y <= 1.0) { double value = NUMundefined, sum = 0.0, weight = 0.0; for (long ichan = 1; ichan <= numberOfDrawableChannels; ichan ++) { double dx = x - biosemiLocationData [ichan]. topX; double dy = y - biosemiLocationData [ichan]. topY; double distance = sqrt (dx * dx + dy * dy); if (distance < 1e-12) { value = mean [ichan]; break; } distance = distance * distance * distance * distance * distance * distance; sum += mean [ichan] / distance; weight += 1.0 / distance; } if (value == NUMundefined) value = ( sum == 0.0 ? 0.0 : sum / weight ); image [irow] [icol] = value; } } } double whiteValue = colourScale == kGraphics_colourScale_BLUE_TO_RED ? 0.5 * (vmin + vmax) : vmin; Graphics_setColourScale (graphics, colourScale); for (long irow = 1; irow <= n; irow ++) { double y = -1.0 + (irow - 1) * d; for (long icol = 1; icol <= n; icol ++) { double x = -1.0 + (icol - 1) * d; if (x * x + y * y > 1.0) { image [irow] [icol] = whiteValue; } } } Graphics_image (graphics, image.peek(), 1, n, -1.0-0.5/n, 1.0+0.5/n, 1, n, -1.0-0.5/n, 1.0+0.5/n, vmin, vmax); Graphics_setColourScale (graphics, kGraphics_colourScale_GREY); Graphics_setLineWidth (graphics, 2.0); /* * Nose. */ Graphics_setGrey (graphics, colourScale == kGraphics_colourScale_BLUE_TO_RED ? 1.0 : 0.5); {// scope double x [3] = { -0.08, 0.0, 0.08 }, y [3] = { 0.99, 1.18, 0.99 }; Graphics_fillArea (graphics, 3, x, y); } Graphics_setColour (graphics, Graphics_BLACK); Graphics_line (graphics, -0.08, 0.99, 0.0, 1.18); Graphics_line (graphics, 0.08, 0.99, 0.0, 1.18); /* * Ears. */ Graphics_setGrey (graphics, colourScale == kGraphics_colourScale_BLUE_TO_RED ? 1.0 : 0.5); Graphics_fillRectangle (graphics, -1.09, -1.00, -0.08, 0.08); Graphics_fillRectangle (graphics, 1.09, 1.00, -0.08, 0.08); Graphics_setColour (graphics, Graphics_BLACK); Graphics_line (graphics, -0.99, 0.08, -1.09, 0.08); Graphics_line (graphics, -1.09, 0.08, -1.09, -0.08); Graphics_line (graphics, -1.09, -0.08, -0.99, -0.08); Graphics_line (graphics, 0.99, 0.08, 1.09, 0.08); Graphics_line (graphics, 1.09, 0.08, 1.09, -0.08); Graphics_line (graphics, 1.09, -0.08, 0.99, -0.08); /* * Scalp. */ Graphics_ellipse (graphics, -1.0, 1.0, -1.0, 1.0); Graphics_setLineWidth (graphics, 1.0); Graphics_unsetInner (graphics); if (garnish) { ERP_drawScalp_garnish (graphics, vmin, vmax, colourScale); } } void structERPWindow :: v_drawSelectionViewer () { ERP erp = (ERP) data; Graphics_setWindow (d_graphics, -1.1, 1.1, -1.01, 1.19); Graphics_setColour (d_graphics, Graphics_WINDOW_BACKGROUND_COLOUR); Graphics_fillRectangle (d_graphics, -1.1, 1.1, -1.01, 1.19); Graphics_setColour (d_graphics, Graphics_BLACK); long numberOfDrawableChannels = erp -> ny >= 64 && Melder_equ (erp -> channelNames [64], U"O2") ? 64 : erp -> ny >= 32 && Melder_equ (erp -> channelNames [32], U"Cz") ? 32 : 0; BiosemiLocationData *biosemiLocationData = numberOfDrawableChannels == 64 ? biosemiCapCoordinates64 : numberOfDrawableChannels == 32 ? biosemiCapCoordinates32 : 0; for (long ichan = 1; ichan <= numberOfDrawableChannels; ichan ++) { double inclination = (double) biosemiLocationData [ichan]. inclination; double azimuth = (double) biosemiLocationData [ichan]. azimuth; bool rightHemisphere = inclination >= 0.0; double r = fabs (inclination / 115.0); double theta = rightHemisphere ? azimuth * (NUMpi / 180.0) : (azimuth + 180.0) * (NUMpi / 180.0); biosemiLocationData [ichan]. topX = r * cos (theta); biosemiLocationData [ichan]. topY = r * sin (theta); } long n = 201; double d = 2.0 / (n - 1); autoNUMvector means (1, numberOfDrawableChannels); for (long ichan = 1; ichan <= numberOfDrawableChannels; ichan ++) { means [ichan] = d_startSelection == d_endSelection ? Sampled_getValueAtX (erp, d_startSelection, ichan, 0, true) : Vector_getMean (erp, d_startSelection, d_endSelection, ichan); } autoNUMmatrix image (1, n, 1, n); for (long irow = 1; irow <= n; irow ++) { double y = -1.0 + (irow - 1) * d; for (long icol = 1; icol <= n; icol ++) { double x = -1.0 + (icol - 1) * d; if (x * x + y * y <= 1.0) { double value = NUMundefined, sum = 0.0, weight = 0.0; for (long ichan = 1; ichan <= numberOfDrawableChannels; ichan ++) { double dx = x - biosemiLocationData [ichan]. topX; double dy = y - biosemiLocationData [ichan]. topY; double distance = sqrt (dx * dx + dy * dy); if (distance < 1e-12) { value = means [ichan]; break; } distance = distance * distance * distance * distance * distance * distance; sum += means [ichan] / distance; weight += 1.0 / distance; } if (value == NUMundefined) value = ( sum == 0.0 ? 0.0 : sum / weight ); image [irow] [icol] = value; } } } double minimum = 0.0, maximum = 0.0; for (long irow = 1; irow <= n; irow ++) { for (long icol = 1; icol <= n; icol ++) { double value = image [irow] [icol]; if (value < minimum) minimum = value; else if (value > maximum) maximum = value; } } double absoluteExtremum = - minimum > maximum ? - minimum : maximum; if (p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_FIXED_RANGE) { minimum = p_sound_scaling_minimum; maximum = p_sound_scaling_maximum; } else if (p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_FIXED_HEIGHT) { double mean = 0.5 * (minimum + maximum); minimum = mean - 0.5 * p_sound_scaling_height; maximum = mean + 0.5 * p_sound_scaling_height; } else { minimum = - absoluteExtremum; maximum = absoluteExtremum; } for (long irow = 1; irow <= n; irow ++) { double y = -1.0 + (irow - 1) * d; for (long icol = 1; icol <= n; icol ++) { double x = -1.0 + (icol - 1) * d; if (x * x + y * y > 1.0) { image [irow] [icol] = minimum + ( our p_scalp_colourScale == kGraphics_colourScale_BLUE_TO_RED ? 0.46 : 0.1875 ) * (maximum - minimum); // -0.625 * absoluteExtremum; } } } Graphics_setColourScale (d_graphics, our p_scalp_colourScale); Graphics_image (d_graphics, image.peek(), 1, n, -1.0-0.5/n, 1.0+0.5/n, 1, n, -1.0-0.5/n, 1.0+0.5/n, minimum, maximum); Graphics_setColourScale (d_graphics, kGraphics_colourScale_GREY); Graphics_setLineWidth (d_graphics, 2.0); /* * Nose. */ Graphics_setGrey (d_graphics, our p_scalp_colourScale == kGraphics_colourScale_BLUE_TO_RED ? 1.0 : 0.5); {// scope double x [3] = { -0.08, 0.0, 0.08 }, y [3] = { 0.99, 1.18, 0.99 }; Graphics_fillArea (d_graphics, 3, x, y); } Graphics_setColour (d_graphics, Graphics_BLACK); Graphics_line (d_graphics, -0.08, 0.99, 0.0, 1.18); Graphics_line (d_graphics, 0.08, 0.99, 0.0, 1.18); /* * Ears. */ Graphics_setGrey (d_graphics, our p_scalp_colourScale == kGraphics_colourScale_BLUE_TO_RED ? 1.0 : 0.5); Graphics_fillRectangle (d_graphics, -1.09, -1.00, -0.08, 0.08); Graphics_fillRectangle (d_graphics, 1.09, 1.00, -0.08, 0.08); Graphics_setColour (d_graphics, Graphics_BLACK); Graphics_line (d_graphics, -0.99, 0.08, -1.09, 0.08); Graphics_line (d_graphics, -1.09, 0.08, -1.09, -0.08); Graphics_line (d_graphics, -1.09, -0.08, -0.99, -0.08); Graphics_line (d_graphics, 0.99, 0.08, 1.09, 0.08); Graphics_line (d_graphics, 1.09, 0.08, 1.09, -0.08); Graphics_line (d_graphics, 1.09, -0.08, 0.99, -0.08); /* * Scalp. */ Graphics_ellipse (d_graphics, -1.0, 1.0, -1.0, 1.0); Graphics_setLineWidth (d_graphics, 1.0); } void structERPWindow :: v_prefs_addFields (EditorCommand cmd) { Any radio; OPTIONMENU_ENUM (U"Scalp colour space", kGraphics_colourScale, kGraphics_colourScale_BLUE_TO_RED) } void structERPWindow :: v_prefs_setValues (EditorCommand cmd) { SET_ENUM (U"Scalp colour space", kGraphics_colourScale, p_scalp_colourScale) } void structERPWindow :: v_prefs_getValues (EditorCommand cmd) { pref_scalp_colourScale () = p_scalp_colourScale = GET_ENUM (kGraphics_colourScale, U"Scalp colour space"); FunctionEditor_redraw (this); } autoERPWindow ERPWindow_create (const char32 *title, ERP data) { Melder_assert (data); try { autoERPWindow me = Thing_new (ERPWindow); SoundEditor_init (me.peek(), title, data); return me; } catch (MelderError) { Melder_throw (U"ERP window not created."); } } /* End of file ERPWindow.cpp */ praat-6.0.04/EEG/ERPWindow.h000066400000000000000000000031331261542461700153070ustar00rootroot00000000000000#ifndef _ERPWindow_h_ #define _ERPWindow_h_ /* ERPWindow.h * * Copyright (C) 2012,2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "SoundEditor.h" #include "ERP.h" Thing_define (ERPWindow, SoundEditor) { const char32 * v_getChannelName (long channelNumber) override { ERP erp = (ERP) our data; return erp -> channelNames [channelNumber]; } void v_drawSelectionViewer () override; bool v_hasPitch () override { return false; } bool v_hasIntensity () override { return false; } bool v_hasFormants () override { return false; } bool v_hasPulses () override { return false; } void v_prefs_addFields (EditorCommand cmd) override; void v_prefs_setValues (EditorCommand cmd) override; void v_prefs_getValues (EditorCommand cmd) override; #include "ERPWindow_prefs.h" }; /** Create an ERPWindow. */ autoERPWindow ERPWindow_create (const char32 *title, ERP data); /* End of file ERPWindow.h */ #endif praat-6.0.04/EEG/ERPWindow_prefs.h000066400000000000000000000053371261542461700165160ustar00rootroot00000000000000/* ERPWindow_prefs.h * * Copyright (C) 2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ prefs_begin (ERPWindow) prefs_override_bool (ERPWindow, showSelectionViewer, 1, true) prefs_override_enum (ERPWindow, sound_scalingStrategy, 1, kTimeSoundEditor_scalingStrategy, DEFAULT) prefs_override_double (ERPWindow, sound_scaling_height, 1, U"20e-6") prefs_override_double (ERPWindow, sound_scaling_minimum, 1, U"-10e-6") prefs_override_double (ERPWindow, sound_scaling_maximum, 1, U"10e-6") prefs_override_double (ERPWindow, picture_bottom, 1, U"0.0") prefs_override_double (ERPWindow, picture_top, 1, U"0.0 (= auto)") prefs_override_bool (ERPWindow, spectrogram_show, 1, false); prefs_override_double (ERPWindow, spectrogram_viewFrom, 1, U"0.0") // Hz prefs_override_double (ERPWindow, spectrogram_viewTo, 1, U"60.0") // Hz prefs_override_double (ERPWindow, spectrogram_windowLength, 1, U"0.5") // seconds prefs_override_double (ERPWindow, spectrogram_dynamicRange, 1, U"40.0") // dB prefs_override_long (ERPWindow, spectrogram_timeSteps, 1, U"1000") prefs_override_long (ERPWindow, spectrogram_frequencySteps, 1, U"250") prefs_override_enum (ERPWindow, spectrogram_method, 1, kSound_to_Spectrogram_method, DEFAULT) prefs_override_enum (ERPWindow, spectrogram_windowShape, 1, kSound_to_Spectrogram_windowShape, DEFAULT) prefs_override_bool (ERPWindow, spectrogram_autoscaling, 1, true) prefs_override_double (ERPWindow, spectrogram_maximum, 1, U"100.0") // dB/Hz prefs_override_double (ERPWindow, spectrogram_preemphasis, 1, U"0.0") // dB/octave prefs_override_double (ERPWindow, spectrogram_dynamicCompression, 1, U"0.0") prefs_override_bool (ERPWindow, spectrogram_picture_garnish, 1, true) prefs_add_enum_with_data (ERPWindow, scalp_colourScale, 1, kGraphics_colourScale, BLUE_TO_RED) prefs_end (ERPWindow) /* End of file ERPWindow_prefs.h */ praat-6.0.04/EEG/ERP_def.h000066400000000000000000000016351261542461700147420ustar00rootroot00000000000000/* ERP_def.h * * Copyright (C) 2011-2012,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT ERP oo_DEFINE_CLASS (ERP, Sound) oo_STRING_VECTOR (channelNames, ny) oo_END_CLASS (ERP) #undef ooSTRUCT /* End of file ERP_def.h */ praat-6.0.04/EEG/Makefile000066400000000000000000000010721261542461700147600ustar00rootroot00000000000000# Makefile of the library "EEG" # Paul Boersma, 24 August 2013 include ../makefile.defs CPPFLAGS = -I ../num -I ../kar -I ../sys -I ../dwsys -I ../stat -I ../dwtools -I ../fon OBJECTS = EEG.o EEGWindow.o ERPTier.o ERP.o ERPWindow.o \ praat_EEG.o manual_EEG.o .PHONY: all clean all: libEEG.a clean: $(RM) $(OBJECTS) $(RM) libEEG.a libEEG.a: $(OBJECTS) touch libEEG.a rm libEEG.a $(AR) cq libEEG.a $(OBJECTS) $(RANLIB) libEEG.a $(OBJECTS): *.h ../num/NUM.h ../kar/*.h ../sys/*.h ../dwsys/*.h ../stat/*.h ../dwtools/*.h ../fon/*.h praat-6.0.04/EEG/manual_EEG.cpp000066400000000000000000000161751261542461700157730ustar00rootroot00000000000000/* manual_EEG.cpp * * Copyright (C) 2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ManPagesM.h" void manual_EEG_init (ManPages me); void manual_EEG_init (ManPages me) { MAN_BEGIN (U"EEG", U"ppgb", 20120511) 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.") ENTRY (U"1. How to get an EEG object in Praat") NORMAL (U"You typically create an EEG object in Praat by opening a BDF/EDF file with @@Read from file...@. " "Praat tries to read the whole file into memory, so you may want to work with a 64-bit edition of Praat " "if you want to avoid \"out of memory\" messages.") NORMAL (U"After you do ##Read from file...#, an EEG object will appear in the list of objects.") ENTRY (U"2. How to look into an EEG object") NORMAL (U"Once you have an EEG object in the list, you can click ##View & Edit# to look into it. " "You will typically see the first 8 channels, but you scroll to the other channels by clicking on the up and down arrows. " "You can scroll and zoom in the same way as in a Sound window.") NORMAL (U"The channel names that you see are often A1, A2, ... A32, B1, B2, ... B32, C1, C2, ... C32, and so on. These represent the cap electrodes. " "If the number of cap electrodes is 32, though, the channel names are Fp1, AF3, ... Cz, " "and if it is 64, the channel names are Fp1, AF7, ... O2. You can change these names with " "##Set channel name...# from the #Modify menu.") NORMAL (U"Below the cap electrodes you may see a number of channels for the external electrodes. " "These are typically named EXG1, EXG2, ... EXG8, but you can change these names with ##Edit external electrode names...# " "from the #Modify menu.") NORMAL (U"Below the external electrodes you may see a number of special channels, " "perhaps named GSR1, GSR2, Erg1, Erg2, Resp, Plet, Temp, and Status. " "These represent recordings from other sensors than the electrodes.") NORMAL (U"The Status channel is special. It is the 8-bit digital signal that you fed to your EEG apparatus. " "When reading the BDF file, Praat extracts all 8 bits from this status signal, " "and these 8 bits are shown in the EEG window as TextGrid interval tiers named S1, S2, ... S8. " "These bits are the place to mark events. For instance, in our lab we use S8 to mark any event, " "S5 to mark a \"standard\" event, and S4 to mark a \"deviant\" event.") ENTRY (U"3. What to do to an EEG object") NORMAL (U"The raw EEG signal that you have read from a file is typically quite noisy and may have a very large " "DC (direct-current) component as compared to the small vibrations that you are interested in. " "There are several ways to clean it up.") NORMAL (U"##Subtracting a reference signal.# The voltage on the whole scalp may rise and fall in time. " "You are unlikely to be interested in these global movements; instead, you are likely to be interested only " "in the voltage movements on the brain-influenced part of the scalp (the cap electrodes) " "with respect to the voltage movements on the non-brain-influenced part of the scalp (the external electrodes). " "If you have external electrode recordings that include the left and right mastoids, you can use these channels as a %%reference signal%, i.e., " "you can use ##Subtract reference...# to subtract the average of the two mastoid channels from all electrode channels (including the external electrodes themselves). " "If you have no such recordings, you can still regard the average of a range of electrode channels as a reference signal, " "and use ##Subtract mean channel...# to subtract this from each electrode channel.") NORMAL (U"##Detrending.# With #Detrend, you subtract from each electrode channel a line in such a way that the first sample and the last sample become zero. " "Detrending and reference subtraction can be performed in either order.") NORMAL (U"##Filtering.# With ##Filter...#, you band-pass filter each electrode channel. Filtering has to be done after detrending, but " "filtering and reference subtraction can be performed in either order.") ENTRY (U"4. How to do an ERP analysis") NORMAL (U"An ERP is an Event-Related Potential. Events are marked somewhere in S1, S2, ... S8. In the above example, " "we extract all the \"deviant\" events by doing ##To ERPTier...#, setting ##From time# to -0.11 seconds, " "##To Time# to 0.39 seconds, and ##Marker bit# to 4. This way, an ERPTier object appears in the list, containing " "the parts of the EEG signal that lie in a time window of [-0.11, 0.39] seconds around each event on the S4 (deviant) tier. " "Thus, if S4 contains 150 events, the resulting ERPTier will contain 150 pieces of the original EEG signal (without the extra sensors).") NORMAL (U"You are typically interested in the part of each ERP in the ERPTier after the event. " "That is, you are probably interested in how this part compares to the part not influenced by the event, " "i.e. the part before the event. To make this comparison easier, you can do ##Subtract baseline...#: " "the waveform of the ERP will be moved up or down in such a way that the average amplitude of the part between the specified times becomes zero; " "the times you will typically fill in here are the starting time of the ERP (a negative number) and the time of the event (0.0).") NORMAL (U"After you subtract the baseline, the part after the event contains the interesting part of the ERP: " "even its sign (positive or negative) is meaningful now. Some ERPs, however, will contain very large positive or negative peaks " "because of eye movements and other disturbing signals. To remove those ERPs from the ERPTier, " "do ##Reject artefacts...#, while specifying the amount by which you allow the amplitude of an ERP to go above or below zero.") NORMAL (U"Once you have an ERPTier, you can extract each of the 150 ERPs from it with ##Extract ERP...#. " "It is perhaps more interesting to compute the average of all those 150 ERPs with ##To ERP (mean)#. " "These commands put a new ERP object in the list.") 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).") MAN_END } /* End of file manual_EEG.cpp */ praat-6.0.04/EEG/praat_EEG.cpp000066400000000000000000000757271261542461700156350ustar00rootroot00000000000000/* praat_EEG.cpp * * Copyright (C) 2011-2012,2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "praat.h" #include "EEGWindow.h" #include "ERPWindow.h" #include "ERPTier.h" #include "SpectrumEditor.h" #undef iam #define iam iam_LOOP /***** EEG *****/ DIRECT2 (EEGs_concatenate) { autoCollection eegs = praat_getSelectedObjects (); autoEEG thee = EEGs_concatenate (eegs.peek()); praat_new (thee.transfer(), U"chain"); END2 } DIRECT2 (EEG_detrend) { LOOP { iam (EEG); EEG_detrend (me); praat_dataChanged (me); } END2 } FORM (EEG_editExternalElectrodeNames, U"Edit external electrode names", 0) { WORD (U"External electrode 1", U"EXG1") WORD (U"External electrode 2", U"EXG2") WORD (U"External electrode 3", U"EXG3") WORD (U"External electrode 4", U"EXG4") WORD (U"External electrode 5", U"EXG5") WORD (U"External electrode 6", U"EXG6") WORD (U"External electrode 7", U"EXG7") WORD (U"External electrode 8", U"EXG8") OK2 int IOBJECT; LOOP { iam (EEG); if (EEG_getNumberOfExternalElectrodes (me) == 8) { const long offsetExternalElectrode = EEG_getNumberOfCapElectrodes (me); SET_STRING (U"External electrode 1", my channelNames [offsetExternalElectrode + 1]) SET_STRING (U"External electrode 2", my channelNames [offsetExternalElectrode + 2]) SET_STRING (U"External electrode 3", my channelNames [offsetExternalElectrode + 3]) SET_STRING (U"External electrode 4", my channelNames [offsetExternalElectrode + 4]) SET_STRING (U"External electrode 5", my channelNames [offsetExternalElectrode + 5]) SET_STRING (U"External electrode 6", my channelNames [offsetExternalElectrode + 6]) SET_STRING (U"External electrode 7", my channelNames [offsetExternalElectrode + 7]) SET_STRING (U"External electrode 8", my channelNames [offsetExternalElectrode + 8]) } } DO LOOP { iam (EEG); if (EEG_getNumberOfExternalElectrodes (me) != 8) Melder_throw (U"You can do this only if there are 8 external electrodes."); EEG_setExternalElectrodeNames (me, GET_STRING (U"External electrode 1"), GET_STRING (U"External electrode 2"), GET_STRING (U"External electrode 3"), GET_STRING (U"External electrode 4"), GET_STRING (U"External electrode 5"), GET_STRING (U"External electrode 6"), GET_STRING (U"External electrode 7"), GET_STRING (U"External electrode 8")); praat_dataChanged (me); } END2 } FORM (EEG_extractChannel, U"EEG: Extract channel", 0) { SENTENCE (U"Channel name", U"Cz") OK2 DO LOOP { iam (EEG); const char32 *channelName = GET_STRING (U"Channel name"); autoEEG thee = EEG_extractChannel (me, channelName); praat_new (thee.transfer(), my name, U"_", channelName); } END2 } FORM (EEG_extractPart, U"EEG: Extract part", 0) { REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"1.0") BOOLEAN (U"Preserve times", 0) OK2 DO LOOP { iam (EEG); autoEEG thee = EEG_extractPart (me, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_INTEGER (U"Preserve times")); praat_new (thee.transfer(), my name, U"_part"); } END2 } DIRECT2 (EEG_extractSound) { LOOP { iam (EEG); if (! my sound) Melder_throw (me, U": I don't contain a waveform."); autoSound thee = EEG_extractSound (me); praat_new (thee.transfer()); } END2 } DIRECT2 (EEG_extractTextGrid) { LOOP { iam (EEG); if (! my textgrid) Melder_throw (me, U": I don't contain marks."); autoTextGrid thee = EEG_extractTextGrid (me); praat_new (thee.transfer()); } END2 } FORM (EEG_filter, U"Filter", 0) { REAL (U"Low frequency (Hz)", U"1.0") REAL (U"Low width (Hz)", U"0.5") REAL (U"High frequency (Hz)", U"25.0") REAL (U"High width (Hz)", U"12.5") BOOLEAN (U"Notch at 50 Hz", true) OK2 DO LOOP { iam (EEG); EEG_filter (me, GET_REAL (U"Low frequency"), GET_REAL (U"Low width"), GET_REAL (U"High frequency"), GET_REAL (U"High width"), GET_INTEGER (U"Notch at 50 Hz")); praat_dataChanged (me); } END2 } FORM (EEG_getChannelName, U"Get channel name", 0) { NATURAL (U"Channel number", U"1") OK2 DO LOOP { iam (EEG); long channelNumber = GET_INTEGER (U"Channel number"); if (channelNumber > my numberOfChannels) Melder_throw (me, U": there are only ", my numberOfChannels, U" channels."); Melder_information (my channelNames [channelNumber]); } END2 } FORM (EEG_getChannelNumber, U"Get channel number", 0) { WORD (U"Channel name", U"Cz") OK2 DO LOOP { iam (EEG); Melder_information (EEG_getChannelNumber (me, GET_STRING (U"Channel name"))); } END2 } FORM (EEG_removeTriggers, U"Remove triggers", 0) { OPTIONMENU_ENUM (U"Remove every trigger that...", kMelder_string, DEFAULT) SENTENCE (U"...the text", U"hi") OK2 DO LOOP { iam (EEG); EEG_removeTriggers (me, GET_ENUM (kMelder_string, U"Remove every trigger that..."), GET_STRING (U"...the text")); praat_dataChanged (me); } END2 } FORM (EEG_setChannelName, U"Set channel name", 0) { NATURAL (U"Channel number", U"1") WORD (U"New name", U"BLA") OK2 DO LOOP { iam (EEG); EEG_setChannelName (me, GET_INTEGER (U"Channel number"), GET_STRING (U"New name")); praat_dataChanged (me); } END2 } FORM (EEG_setChannelToZero, U"Set channel to zero", 0) { SENTENCE (U"Channel", U"Iz") OK2 DO LOOP { iam (EEG); EEG_setChannelToZero (me, GET_STRING (U"Channel")); praat_dataChanged (me); } END2 } FORM (EEG_subtractMeanChannel, U"Subtract mean channel", 0) { LABEL (U"label", U"Range of reference channels:") NATURAL (U"From channel", U"1") NATURAL (U"To channel", U"32") OK2 DO LOOP { iam (EEG); EEG_subtractMeanChannel (me, GET_INTEGER (U"From channel"), GET_INTEGER (U"To channel")); praat_dataChanged (me); } END2 } FORM (EEG_subtractReference, U"Subtract reference", 0) { WORD (U"Reference channel 1", U"MASL") WORD (U"Reference channel 2 (optional)", U"MASR") OK2 DO LOOP { iam (EEG); EEG_subtractReference (me, GET_STRING (U"Reference channel 1"), GET_STRING (U"Reference channel 2")); praat_dataChanged (me); } END2 } FORM (EEG_to_ERPTier_bit, U"To ERPTier (bit)", 0) { REAL (U"From time (s)", U"-0.11") REAL (U"To time (s)", U"0.39") NATURAL (U"Marker bit", U"8") OK2 DO LOOP { iam (EEG); int markerBit = GET_INTEGER (U"Marker bit"); autoERPTier thee = EEG_to_ERPTier_bit (me, GET_REAL (U"From time"), GET_REAL (U"To time"), markerBit); praat_new (thee.transfer(), my name, U"_bit", markerBit); } END2 } FORM (EEG_to_ERPTier_marker, U"To ERPTier (marker)", 0) { REAL (U"From time (s)", U"-0.11") REAL (U"To time (s)", U"0.39") NATURAL (U"Marker number", U"12") OK2 DO LOOP { iam (EEG); uint16 markerNumber = GET_INTEGER (U"Marker number"); autoERPTier thee = EEG_to_ERPTier_marker (me, GET_REAL (U"From time"), GET_REAL (U"To time"), markerNumber); praat_new (thee.transfer(), my name, U"_", markerNumber); } END2 } FORM (EEG_to_ERPTier_triggers, U"To ERPTier (triggers)", 0) { REAL (U"From time (s)", U"-0.11") REAL (U"To time (s)", U"0.39") OPTIONMENU_ENUM (U"Get every event with a trigger that", kMelder_string, DEFAULT) SENTENCE (U"...the text", U"1") OK2 DO LOOP { iam (EEG); autoERPTier thee = EEG_to_ERPTier_triggers (me, GET_REAL (U"From time"), GET_REAL (U"To time"), GET_ENUM (kMelder_string, U"Get every event with a trigger that"), GET_STRING (U"...the text")); praat_new (thee.transfer(), my name, U"_trigger", GET_STRING (U"...the text")); } END2 } FORM (EEG_to_ERPTier_triggers_preceded, U"To ERPTier (triggers, preceded)", 0) { REAL (U"From time (s)", U"-0.11") REAL (U"To time (s)", U"0.39") OPTIONMENU_ENUM (U"Get every event with a trigger that", kMelder_string, DEFAULT) SENTENCE (U"...the text", U"1") OPTIONMENU_ENUM (U"and is preceded by a trigger that", kMelder_string, DEFAULT) SENTENCE (U" ...the text", U"4") OK2 DO LOOP { iam (EEG); autoERPTier thee = EEG_to_ERPTier_triggers_preceded (me, GET_REAL (U"From time"), GET_REAL (U"To time"), GET_ENUM (kMelder_string, U"Get every event with a trigger that"), GET_STRING (U"...the text"), GET_ENUM (kMelder_string, U"and is preceded by a trigger that"), GET_STRING (U" ...the text")); praat_new (thee.transfer(), my name, U"_trigger", GET_STRING (U" ...the text")); } END2 } FORM (EEG_to_MixingMatrix, U"To MixingMatrix", 0) { NATURAL (U"Maximum number of iterations", U"100") POSITIVE (U"Tolerance", U"0.001") OPTIONMENU (U"Diagonalization method", 2) OPTION (U"qdiag") OPTION (U"ffdiag") OK2 DO LOOP { iam (EEG); autoMixingMatrix thee = EEG_to_MixingMatrix (me, GET_INTEGER (U"Maximum number of iterations"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Diagonalization method")); praat_new (thee.transfer(), my name); } END2 } static void cb_EEGWindow_publication (Editor editor, void *closure, Daata publication) { (void) editor; (void) closure; /* * Keep the gate for error handling. */ try { praat_new (publication); praat_updateSelection (); if (Thing_isa (publication, classSpectrum) && str32equ (Thing_getName (publication), U"slice")) { int IOBJECT; LOOP { iam (Spectrum); autoSpectrumEditor editor2 = SpectrumEditor_create (ID_AND_FULL_NAME, me); praat_installEditor (editor2.transfer(), IOBJECT); } } } catch (MelderError) { Melder_flushError (); } } DIRECT2 (EEG_viewAndEdit) { if (theCurrentPraatApplication -> batch) Melder_throw (U"Cannot view or edit an EEG from batch."); LOOP { iam (EEG); autoEEGWindow editor = EEGWindow_create (ID_AND_FULL_NAME, me); Editor_setPublicationCallback (editor.peek(), cb_EEGWindow_publication, NULL); praat_installEditor (editor.transfer(), IOBJECT); } END2 } #pragma mark EEG & TextGrid DIRECT2 (EEG_TextGrid_replaceTextGrid) { EEG me = FIRST (EEG); EEG_replaceTextGrid (me, FIRST (TextGrid)); praat_dataChanged (me); END2 } #pragma mark ERP DIRECT2 (ERP_downto_Sound) { LOOP { iam (ERP); autoSound thee = ERP_downto_Sound (me); praat_new (thee.transfer()); } END2 } FORM (ERP_downto_Table, U"ERP: Down to Table", 0) { BOOLEAN (U"Include sample number", false) BOOLEAN (U"Include time", true) NATURAL (U"Time decimals", U"6") NATURAL (U"Voltage decimals", U"12") RADIO (U"Voltage units", 1) OPTION (U"volt") OPTION (U"microvolt") OK2 DO LOOP { iam (ERP); autoTable thee = ERP_tabulate (me, GET_INTEGER (U"Include sample number"), GET_INTEGER (U"Include time"), GET_INTEGER (U"Time decimals"), GET_INTEGER (U"Voltage decimals"), GET_INTEGER (U"Voltage units")); praat_new (thee.transfer(), my name); } END2 } FORM (ERP_draw, U"ERP: Draw", 0) { SENTENCE (U"Channel name", U"Cz") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range", U"0.0 (= all)") REAL (U"left Voltage range (V)", U"10e-6") REAL (U"right Voltage range", U"-10e-6") BOOLEAN (U"Garnish", 1) OK2 DO autoPraatPicture picture; LOOP { iam (ERP); ERP_drawChannel_name (me, GRAPHICS, GET_STRING (U"Channel name"), GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Voltage range"), GET_REAL (U"right Voltage range"), GET_INTEGER (U"Garnish")); } END2 } FORM (ERP_drawScalp, U"ERP: Draw scalp", 0) { REAL (U"left Time range (s)", U"0.1") REAL (U"right Time range", U"0.2") REAL (U"left Voltage range (V)", U"10e-6") REAL (U"right Voltage range", U"-10e-6") BOOLEAN (U"Garnish", 1) OK2 DO autoPraatPicture picture; LOOP { iam (ERP); ERP_drawScalp (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Voltage range"), GET_REAL (U"right Voltage range"), kGraphics_colourScale_GREY, GET_INTEGER (U"Garnish")); } END2 } FORM (ERP_drawScalp_colour, U"ERP: Draw scalp (colour)", 0) { REAL (U"left Time range (s)", U"0.1") REAL (U"right Time range", U"0.2") REAL (U"left Voltage range (V)", U"10e-6") REAL (U"right Voltage range", U"-10e-6") RADIO_ENUM (U"Colour scale", kGraphics_colourScale, BLUE_TO_RED) BOOLEAN (U"Garnish", 1) OK2 DO autoPraatPicture picture; LOOP { iam (ERP); ERP_drawScalp (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Voltage range"), GET_REAL (U"right Voltage range"), GET_ENUM (kGraphics_colourScale, U"Colour scale"), GET_INTEGER (U"Garnish")); } END2 } FORM (ERP_drawScalp_garnish, U"ERP: Draw scalp (garnish)", 0) { REAL (U"left Voltage range (V)", U"10e-6") REAL (U"right Voltage range", U"-10e-6") RADIO_ENUM (U"Colour scale", kGraphics_colourScale, BLUE_TO_RED) OK2 DO autoPraatPicture picture; ERP_drawScalp_garnish (GRAPHICS, GET_REAL (U"left Voltage range"), GET_REAL (U"right Voltage range"), GET_ENUM (kGraphics_colourScale, U"Colour scale")); END2 } FORM (ERP_extractOneChannelAsSound, U"ERP: Extract one channel as Sound", 0) { WORD (U"Channel name", U"Cz") OK2 DO LOOP { iam (ERP); const char32 *channelName = GET_STRING (U"Channel name"); long channelNumber = ERP_getChannelNumber (me, channelName); if (channelNumber == 0) Melder_throw (me, U": no channel named \"", channelName, U"\"."); autoSound thee = Sound_extractChannel (me, channelNumber); praat_new (thee.transfer(), my name, U"_", channelName); } END2 } FORM (ERP_formula, U"ERP: Formula", U"ERP: Formula...") { LABEL (U"label1", U"! `x' is the time in seconds, `col' is the sample number.") LABEL (U"label2", U"x = x1 ! time associated with first sample") LABEL (U"label3", U"for col from 1 to ncol") LABEL (U"label4", U" self [col] = ...") TEXTFIELD (U"formula", U"self") LABEL (U"label5", U" x = x + dx") LABEL (U"label6", U"endfor") OK2 DO LOOP { iam (ERP); try { Matrix_formula (me, GET_STRING (U"formula"), interpreter, NULL); praat_dataChanged (me); } catch (MelderError) { praat_dataChanged (me); // in case of error, the ERP may have partially changed throw; } } END2 } FORM (ERP_formula_part, U"ERP: Formula (part)", U"ERP: Formula...") { REAL (U"From time", U"0.0") REAL (U"To time", U"0.0 (= all)") NATURAL (U"From channel", U"1") NATURAL (U"To channel", U"2") TEXTFIELD (U"formula", U"2 * self") OK2 DO LOOP { iam (ERP); try { Matrix_formula_part (me, GET_REAL (U"From time"), GET_REAL (U"To time"), GET_INTEGER (U"From channel") - 0.5, GET_INTEGER (U"To channel") + 0.5, GET_STRING (U"formula"), interpreter, NULL); praat_dataChanged (me); } catch (MelderError) { praat_dataChanged (me); // in case of error, the ERP may have partially changed throw; } } END2 } FORM (ERP_getChannelName, U"Get channel name", 0) { NATURAL (U"Channel number", U"1") OK2 DO LOOP { iam (ERP); long channelNumber = GET_INTEGER (U"Channel number"); if (channelNumber > my ny) Melder_throw (me, U": there are only ", my ny, U" channels."); Melder_information (my channelNames [channelNumber]); } END2 } FORM (ERP_getChannelNumber, U"Get channel number", 0) { WORD (U"Channel name", U"Cz") OK2 DO LOOP { iam (ERP); Melder_information (ERP_getChannelNumber (me, GET_STRING (U"Channel name"))); } END2 } FORM (ERP_getMaximum, U"ERP: Get maximum", U"Sound: Get maximum...") { SENTENCE (U"Channel name", U"Cz") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0 (= all)") RADIO (U"Interpolation", 4) RADIOBUTTON (U"None") RADIOBUTTON (U"Parabolic") RADIOBUTTON (U"Cubic") RADIOBUTTON (U"Sinc70") RADIOBUTTON (U"Sinc700") OK2 DO LOOP { iam (ERP); const char32 *channelName = GET_STRING (U"Channel name"); long channelNumber = ERP_getChannelNumber (me, channelName); if (channelNumber == 0) Melder_throw (me, U": no channel named \"", channelName, U"\"."); double maximum; Vector_getMaximumAndX (me, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), channelNumber, GET_INTEGER (U"Interpolation") - 1, & maximum, NULL); Melder_informationReal (maximum, U"Volt"); } END2 } FORM (ERP_getMean, U"ERP: Get mean", U"ERP: Get mean...") { SENTENCE (U"Channel name", U"Cz") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0 (= all)") OK2 DO LOOP { iam (ERP); const char32 *channelName = GET_STRING (U"Channel name"); long channelNumber = ERP_getChannelNumber (me, channelName); if (channelNumber == 0) Melder_throw (me, U": no channel named \"", channelName, U"\"."); double mean = Vector_getMean (me, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), channelNumber); Melder_informationReal (mean, U"Volt"); } END2 } FORM (ERP_getMinimum, U"ERP: Get minimum", U"Sound: Get minimum...") { SENTENCE (U"Channel name", U"Cz") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0 (= all)") RADIO (U"Interpolation", 4) RADIOBUTTON (U"None") RADIOBUTTON (U"Parabolic") RADIOBUTTON (U"Cubic") RADIOBUTTON (U"Sinc70") RADIOBUTTON (U"Sinc700") OK2 DO LOOP { iam (ERP); const char32 *channelName = GET_STRING (U"Channel name"); long channelNumber = ERP_getChannelNumber (me, channelName); if (channelNumber == 0) Melder_throw (me, U": no channel named \"", channelName, U"\"."); double minimum; Vector_getMinimumAndX (me, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), channelNumber, GET_INTEGER (U"Interpolation") - 1, & minimum, NULL); Melder_informationReal (minimum, U"Volt"); } END2 } FORM (ERP_getTimeOfMaximum, U"ERP: Get time of maximum", U"Sound: Get time of maximum...") { SENTENCE (U"Channel name", U"Cz") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0 (= all)") RADIO (U"Interpolation", 4) RADIOBUTTON (U"None") RADIOBUTTON (U"Parabolic") RADIOBUTTON (U"Cubic") RADIOBUTTON (U"Sinc70") RADIOBUTTON (U"Sinc700") OK2 DO LOOP { iam (ERP); const char32 *channelName = GET_STRING (U"Channel name"); long channelNumber = ERP_getChannelNumber (me, channelName); if (channelNumber == 0) Melder_throw (me, U": no channel named \"", channelName, U"\"."); double timeOfMaximum; Vector_getMaximumAndX (me, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), channelNumber, GET_INTEGER (U"Interpolation") - 1, NULL, & timeOfMaximum); Melder_informationReal (timeOfMaximum, U"seconds"); } END2 } FORM (ERP_getTimeOfMinimum, U"ERP: Get time of minimum", U"Sound: Get time of minimum...") { SENTENCE (U"Channel name", U"Cz") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0 (= all)") RADIO (U"Interpolation", 4) RADIOBUTTON (U"None") RADIOBUTTON (U"Parabolic") RADIOBUTTON (U"Cubic") RADIOBUTTON (U"Sinc70") RADIOBUTTON (U"Sinc700") OK2 DO LOOP { iam (ERP); const char32 *channelName = GET_STRING (U"Channel name"); long channelNumber = ERP_getChannelNumber (me, channelName); if (channelNumber == 0) Melder_throw (me, U": no channel named \"", channelName, U"\"."); double timeOfMinimum; Vector_getMinimumAndX (me, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), channelNumber, GET_INTEGER (U"Interpolation") - 1, NULL, & timeOfMinimum); Melder_informationReal (timeOfMinimum, U"seconds"); } END2 } static void cb_ERPWindow_publication (Editor editor, void *closure, Daata publication) { (void) editor; (void) closure; /* * Keep the gate for error handling. */ try { praat_new (publication); praat_updateSelection (); if (Thing_isa (publication, classSpectrum) && str32equ (Thing_getName (publication), U"slice")) { int IOBJECT; LOOP { iam (Spectrum); autoSpectrumEditor editor2 = SpectrumEditor_create (ID_AND_FULL_NAME, me); praat_installEditor (editor2.transfer(), IOBJECT); } } } catch (MelderError) { Melder_flushError (); } } DIRECT2 (ERP_viewAndEdit) { if (theCurrentPraatApplication -> batch) Melder_throw (U"Cannot view or edit an ERP from batch."); LOOP { iam (ERP); autoERPWindow editor = ERPWindow_create (ID_AND_FULL_NAME, me); Editor_setPublicationCallback (editor.peek(), cb_ERPWindow_publication, NULL); praat_installEditor (editor.transfer(), IOBJECT); } END2 } /***** ERPTier *****/ FORM (ERPTier_getChannelName, U"Get channel name", 0) { NATURAL (U"Channel number", U"1") OK2 DO LOOP { iam (ERPTier); long channelNumber = GET_INTEGER (U"Channel number"); if (channelNumber > my numberOfChannels) Melder_throw (me, U": there are only ", my numberOfChannels, U" channels."); Melder_information (my channelNames [channelNumber]); } END2 } FORM (ERPTier_getChannelNumber, U"Get channel number", 0) { WORD (U"Channel name", U"Cz") OK2 DO LOOP { iam (ERPTier); Melder_information (ERPTier_getChannelNumber (me, GET_STRING (U"Channel name"))); } END2 } FORM (ERPTier_getMean, U"ERPTier: Get mean", U"ERPTier: Get mean...") { NATURAL (U"Point number", U"1") SENTENCE (U"Channel name", U"Cz") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0 (= all)") OK2 DO LOOP { iam (ERPTier); double mean = ERPTier_getMean (me, GET_INTEGER (U"Point number"), GET_STRING (U"Channel name"), GET_REAL (U"left Time range"), GET_REAL (U"right Time range")); Melder_informationReal (mean, U"Volt"); } END2 } FORM (ERPTier_rejectArtefacts, U"Reject artefacts", 0) { POSITIVE (U"Threshold (V)", U"75e-6") OK2 DO LOOP { iam (ERPTier); ERPTier_rejectArtefacts (me, GET_REAL (U"Threshold")); praat_dataChanged (me); } END2 } FORM (ERPTier_removeEventsBetween, U"Remove events", U"ERPTier: Remove events between...") { REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"1.0") OK2 DO LOOP { iam (ERPTier); AnyTier_removePointsBetween (me, GET_REAL (U"left Time range"), GET_REAL (U"right Time range")); praat_dataChanged (me); } END2 } FORM (ERPTier_subtractBaseline, U"Subtract baseline", 0) { REAL (U"From time (s)", U"-0.11") REAL (U"To time (s)", U"0.0") OK2 DO LOOP { iam (ERPTier); ERPTier_subtractBaseline (me, GET_REAL (U"From time"), GET_REAL (U"To time")); praat_dataChanged (me); } END2 } FORM (ERPTier_to_ERP, U"ERPTier: To ERP", 0) { NATURAL (U"Event number", U"1") OK2 DO LOOP { iam (ERPTier); autoERP thee = ERPTier_extractERP (me, GET_INTEGER (U"Event number")); praat_new (thee.transfer(), my name, U"_mean"); } END2 } DIRECT2 (ERPTier_to_ERP_mean) { LOOP { iam (ERPTier); autoERP thee = ERPTier_to_ERP_mean (me); praat_new (thee.transfer(), my name, U"_mean"); } END2 } /***** ERPTier & Table *****/ FORM (ERPTier_Table_extractEventsWhereColumn_number, U"Extract events where column (number)", 0) { WORD (U"Extract all events where column...", U"") RADIO_ENUM (U"...is...", kMelder_number, DEFAULT) REAL (U"...the number", U"0.0") OK2 DO ERPTier erpTier = FIRST (ERPTier); Table table = FIRST (Table); long columnNumber = Table_getColumnIndexFromColumnLabel (table, GET_STRING (U"Extract all events where column...")); autoERPTier thee = ERPTier_extractEventsWhereColumn_number (erpTier, table, columnNumber, GET_ENUM (kMelder_number, U"...is..."), GET_REAL (U"...the number")); praat_new (thee.transfer(), erpTier -> name); END2 } FORM (ERPTier_Table_extractEventsWhereColumn_text, U"Extract events where column (text)", 0) { WORD (U"Extract all events where column...", U"") OPTIONMENU_ENUM (U"...", kMelder_string, DEFAULT) SENTENCE (U"...the text", U"hi") OK2 DO ERPTier erpTier = FIRST (ERPTier); Table table = FIRST (Table); long columnNumber = Table_getColumnIndexFromColumnLabel (table, GET_STRING (U"Extract all events where column...")); autoERPTier thee = ERPTier_extractEventsWhereColumn_string (erpTier, table, columnNumber, GET_ENUM (kMelder_string, U"..."), GET_STRING (U"...the text")); praat_new (thee.transfer(), erpTier -> name); END2 } /***** Help menus *****/ DIRECT2 (EEG_help) { Melder_help (U"EEG"); END2 } DIRECT2 (ERPTier_help) { Melder_help (U"ERPTier"); END2 } /***** file recognizers *****/ static Any bdfFileRecognizer (int nread, const char *header, MelderFile file) { (void) header; const char32 *fileName = MelderFile_name (file); bool isBdfFile = Melder_stringMatchesCriterion (fileName, kMelder_string_ENDS_WITH, U".bdf") || Melder_stringMatchesCriterion (fileName, kMelder_string_ENDS_WITH, U".BDF"); bool isEdfFile = Melder_stringMatchesCriterion (fileName, kMelder_string_ENDS_WITH, U".edf") || Melder_stringMatchesCriterion (fileName, kMelder_string_ENDS_WITH, U".EDF"); if (nread < 512 || (! isBdfFile && ! isEdfFile)) return NULL; return EEG_readFromBdfFile (file); } /***** buttons *****/ void praat_TimeTier_query_init (ClassInfo klas); // Query buttons for time-based subclasses of AnyTier. void praat_EEG_init (); void praat_EEG_init () { Thing_recognizeClassesByName (classEEG, classERPTier, classERP, NULL); Data_recognizeFileType (bdfFileRecognizer); praat_addAction1 (classEEG, 0, U"EEG help", 0, 0, DO_EEG_help); praat_addAction1 (classEEG, 1, U"View & Edit", 0, praat_ATTRACTIVE, DO_EEG_viewAndEdit); praat_addAction1 (classEEG, 0, U"Query -", 0, 0, 0); praat_addAction1 (classEEG, 0, U"Get channel name...", 0, 1, DO_EEG_getChannelName); praat_addAction1 (classEEG, 0, U"Get channel number...", 0, 1, DO_EEG_getChannelNumber); praat_addAction1 (classEEG, 0, U"Modify -", 0, 0, 0); praat_addAction1 (classEEG, 0, U"Set channel name...", 0, 1, DO_EEG_setChannelName); praat_addAction1 (classEEG, 1, U"Edit external electrode names...", 0, 1, DO_EEG_editExternalElectrodeNames); praat_addAction1 (classEEG, 0, U"-- processing --", 0, 1, 0); praat_addAction1 (classEEG, 0, U"Subtract reference...", 0, 1, DO_EEG_subtractReference); praat_addAction1 (classEEG, 0, U"Subtract mean channel...", 0, 1, DO_EEG_subtractMeanChannel); praat_addAction1 (classEEG, 0, U"Detrend", 0, 1, DO_EEG_detrend); praat_addAction1 (classEEG, 0, U"Filter...", 0, 1, DO_EEG_filter); praat_addAction1 (classEEG, 0, U"Remove triggers...", 0, 1, DO_EEG_removeTriggers); praat_addAction1 (classEEG, 0, U"Set channel to zero...", 0, 1, DO_EEG_setChannelToZero); praat_addAction1 (classEEG, 0, U"Analyse", 0, 0, 0); praat_addAction1 (classEEG, 0, U"Extract channel...", 0, 0, DO_EEG_extractChannel); praat_addAction1 (classEEG, 1, U"Extract part...", 0, 0, DO_EEG_extractPart); praat_addAction1 (classEEG, 0, U"To ERPTier -", 0, 0, 0); praat_addAction1 (classEEG, 0, U"To ERPTier (bit)...", 0, 1, DO_EEG_to_ERPTier_bit); praat_addAction1 (classEEG, 0, U"To ERPTier (marker)...", 0, 1, DO_EEG_to_ERPTier_marker); praat_addAction1 (classEEG, 0, U"To ERPTier (triggers)...", 0, 1, DO_EEG_to_ERPTier_triggers); praat_addAction1 (classEEG, 0, U"To ERPTier (triggers, preceded)...", 0, 1, DO_EEG_to_ERPTier_triggers_preceded); praat_addAction1 (classEEG, 0, U"To ERPTier...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_EEG_to_ERPTier_bit); praat_addAction1 (classEEG, 0, U"To MixingMatrix...", 0, 0, DO_EEG_to_MixingMatrix); praat_addAction1 (classEEG, 0, U"Synthesize", 0, 0, 0); praat_addAction1 (classEEG, 0, U"Concatenate", 0, 0, DO_EEGs_concatenate); praat_addAction1 (classEEG, 0, U"Hack -", 0, 0, 0); praat_addAction1 (classEEG, 0, U"Extract waveforms as Sound", 0, 1, DO_EEG_extractSound); praat_addAction1 (classEEG, 0, U"Extract marks as TextGrid", 0, 1, DO_EEG_extractTextGrid); praat_addAction1 (classERP, 1, U"View & Edit", 0, praat_ATTRACTIVE, DO_ERP_viewAndEdit); praat_addAction1 (classERP, 0, U"Draw -", 0, 0, 0); praat_addAction1 (classERP, 0, U"Draw...", 0, 1, DO_ERP_draw); praat_addAction1 (classERP, 0, U"Draw scalp...", 0, 1, DO_ERP_drawScalp); praat_addAction1 (classERP, 0, U"Draw scalp (colour)...", 0, 1, DO_ERP_drawScalp_colour); praat_addAction1 (classERP, 0, U"Draw scalp (garnish)...", 0, 1, DO_ERP_drawScalp_garnish); praat_addAction1 (classERP, 0, U"Tabulate -", 0, 0, 0); praat_addAction1 (classERP, 0, U"Down to Table...", 0, 1, DO_ERP_downto_Table); praat_addAction1 (classERP, 0, U"Query -", 0, 0, 0); praat_addAction1 (classERP, 0, U"Get channel name...", 0, 1, DO_ERP_getChannelName); praat_addAction1 (classERP, 0, U"Get channel number...", 0, 1, DO_ERP_getChannelNumber); praat_addAction1 (classERP, 0, U"-- get shape --", 0, 1, 0); praat_addAction1 (classERP, 0, U"Get minimum...", 0, 1, DO_ERP_getMinimum); praat_addAction1 (classERP, 0, U"Get time of minimum...", 0, 1, DO_ERP_getTimeOfMinimum); praat_addAction1 (classERP, 0, U"Get maximum...", 0, 1, DO_ERP_getMaximum); praat_addAction1 (classERP, 0, U"Get time of maximum...", 0, 1, DO_ERP_getTimeOfMaximum); praat_addAction1 (classERP, 0, U"-- get statistics --", 0, 1, 0); praat_addAction1 (classERP, 0, U"Get mean...", 0, 1, DO_ERP_getMean); praat_addAction1 (classERP, 0, U"Modify -", 0, 0, 0); praat_addAction1 (classERP, 0, U"Formula...", 0, 1, DO_ERP_formula); praat_addAction1 (classERP, 0, U"Formula (part)...", 0, 1, DO_ERP_formula_part); // praat_addAction1 (classERP, 0, U"Analyse -", 0, 0, 0); // praat_addAction1 (classERP, 0, U"To ERP (difference)", 0, 1, DO_ERP_to_ERP_difference); // praat_addAction1 (classERP, 0, U"To ERP (mean)", 0, 1, DO_ERP_to_ERP_mean); praat_addAction1 (classERP, 0, U"Hack -", 0, 0, 0); praat_addAction1 (classERP, 0, U"Down to Sound", 0, 1, DO_ERP_downto_Sound); praat_addAction1 (classERP, 0, U"Extract one channel as Sound...", 0, 1, DO_ERP_extractOneChannelAsSound); praat_addAction1 (classERPTier, 0, U"ERPTier help", 0, 0, DO_ERPTier_help); // praat_addAction1 (classERPTier, 1, U"View & Edit", 0, praat_ATTRACTIVE, DO_ERPTier_viewAndEdit); praat_addAction1 (classERPTier, 0, U"Query -", 0, 0, 0); praat_TimeTier_query_init (classERPTier); praat_addAction1 (classERPTier, 0, U"-- channel names --", 0, 1, 0); praat_addAction1 (classERPTier, 0, U"Get channel name...", 0, 1, DO_ERPTier_getChannelName); praat_addAction1 (classERPTier, 0, U"Get channel number...", 0, 1, DO_ERPTier_getChannelNumber); praat_addAction1 (classERPTier, 0, U"-- erp --", 0, 1, 0); praat_addAction1 (classERPTier, 0, U"Get mean...", 0, 1, DO_ERPTier_getMean); praat_addAction1 (classERPTier, 0, U"Modify -", 0, 0, 0); praat_addAction1 (classERPTier, 0, U"Subtract baseline...", 0, 1, DO_ERPTier_subtractBaseline); praat_addAction1 (classERPTier, 0, U"Reject artefacts...", 0, 1, DO_ERPTier_rejectArtefacts); praat_addAction1 (classERPTier, 0, U"-- structure --", 0, 1, 0); praat_addAction1 (classERPTier, 0, U"Remove events between...", 0, 1, DO_ERPTier_removeEventsBetween); praat_addAction1 (classERPTier, 0, U"Analyse", 0, 0, 0); praat_addAction1 (classERPTier, 0, U"Extract ERP...", 0, 0, DO_ERPTier_to_ERP); praat_addAction1 (classERPTier, 0, U"To ERP (mean)", 0, 0, DO_ERPTier_to_ERP_mean); praat_addAction2 (classEEG, 1, classTextGrid, 1, U"Replace TextGrid", 0, 0, DO_EEG_TextGrid_replaceTextGrid); praat_addAction2 (classERPTier, 1, classTable, 1, U"Extract -", 0, 0, 0); praat_addAction2 (classERPTier, 1, classTable, 1, U"Extract events where column (number)...", 0, 1, DO_ERPTier_Table_extractEventsWhereColumn_number); praat_addAction2 (classERPTier, 1, classTable, 1, U"Extract events where column (text)...", 0, 1, DO_ERPTier_Table_extractEventsWhereColumn_text); structEEGWindow :: f_preferences (); structERPWindow :: f_preferences (); } /* End of file praat_EEG.cpp */ praat-6.0.04/FFNet/000077500000000000000000000000001261542461700136625ustar00rootroot00000000000000praat-6.0.04/FFNet/FFNet.cpp000066400000000000000000000630731261542461700153410ustar00rootroot00000000000000/* FFNet.cpp * * Copyright (C) 1997-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020712 GPL header djmw 20040420 Modified FFNet_create and FFNet_init parameters. djmw 20040422 FFNet_drawActivation: nodes with activity > 0.05 had incorrect size. djmw 20040422 FFNet_extractWeights added. djmw 20040425 FFNet_drawTopology fill input units; increase distance from arrow for output labels djmw 20040513 Info changes. djmw 20040526 Adapted FFNet_drawCostHistory. djmw 20050131 Reversed sign of derivative in minimumCrossEntropy. djmw 20060811 Changed %d to %ld in sprintf for longs. djmw 20061212 Changed info to Melder_writeLine format. djmw 20070902 FFNet_createNameFromTopology to wchar djmw 20071014 Melder_error djmw 20080121 float -> double djmw 20110304 Thing_new */ #include "FFNet_Matrix.h" #include "Matrix_extensions.h" #include "TableOfReal_extensions.h" #include "Pattern.h" #include "Collection.h" #include "Categories.h" static void bookkeeping (FFNet me); #include "oo_DESTROY.h" #include "FFNet_def.h" #include "oo_COPY.h" #include "FFNet_def.h" #include "oo_EQUAL.h" #include "FFNet_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "FFNet_def.h" #include "oo_WRITE_TEXT.h" #include "FFNet_def.h" #include "oo_WRITE_BINARY.h" #include "FFNet_def.h" #include "oo_READ_TEXT.h" #include "FFNet_def.h" #include "oo_READ_BINARY.h" #include "FFNet_def.h" #include "oo_DESCRIPTION.h" #include "FFNet_def.h" Thing_implement (FFNet, Daata, 0); static void FFNet_checkLayerNumber (FFNet me, long layer) { if (layer < 1 || layer > my nLayers) { if (layer == 0) { Melder_throw (U"A Layer number of 0 is not allowed."); } else if (layer < 0) { Melder_throw (U"A negative layer number is not allowed."); } else if (layer > my nLayers) { Melder_throw (U"A layer number of ", layer, U" is too big."); } Melder_appendError (U"This FFNet has ", layer, U" layer", (my nLayers > 1 ? U"s\n" : U"\n")); if (my nLayers == 1) { Melder_throw (U"Layer number must be equal to 1."); } else if (my nLayers == 2) { Melder_throw (U"Layer number must be equal to 1 or 2."); } else if (my nLayers == 3) { Melder_throw (U"Layer number must be equal to 1, 2 or 3."); } else { Melder_throw (U"Layer number must be in the range 1 to ", my nLayers); } } } autostring32 FFNet_createNameFromTopology (FFNet me) { autoMelderString name; MelderString_copy (&name, my nUnitsInLayer[0]); for (long i = 1; i <= my nLayers; i++) { MelderString_appendCharacter (&name, U'-'); MelderString_append (&name, my nUnitsInLayer[i]); } autostring32 naam = Melder_dup (name.string); return naam.transfer(); } /****** non-linearities ****************************************************/ static double sigmoid (FFNet /*me*/, double x, double *deriv) { double act = NUMsigmoid (x); *deriv = act * (1.0 - act); return act; } /* ******************* cost functions ****************************************/ /* For the errors calculated in the cost functions: if target > activity ==> error > 0 if target < activity ==> error < 0 */ static double minimumSquaredError (FFNet me, const double target[]) { long k = my nNodes - my nOutputs + 1; double cost = 0.0; for (long i = 1; i <= my nOutputs; i++, k++) { double e = my error[k] = target[i] - my activity[k]; cost += e * e; } return 0.5 * cost; } /* E = - sum (i=1; i=nPatterns; sum (k=1;k=nOutputs; t[k]*ln (o[k]) + (1-t[k])ln (1-o[k]))) */ /* dE/do[k] = -(1-t[k])/ (1-o[k]) + t[k]/o[k] */ /* werkt niet bij (grote?) netten */ static double minimumCrossEntropy (FFNet me, const double target[]) { long k = my nNodes - my nOutputs + 1; double cost = 0.0; for (long i = 1; i <= my nOutputs; i++, k++) { double t1 = 1.0 - target[i]; double o1 = 1.0 - my activity[k]; cost -= target[i] * log (my activity[k]) + t1 * log (o1); my error[k] = -t1 / o1 + target[i] / my activity[k]; } return cost; } /* *********************************************************************** */ void bookkeeping (FFNet me) { long nWeights = 0; my nNodes = my nUnitsInLayer[0]; for (long i = 1; i <= my nLayers; i++) { my nNodes += my nUnitsInLayer[i] + 1; nWeights += my nUnitsInLayer[i] * (my nUnitsInLayer[i - 1] + 1); } if (my nWeights > 0 && my nWeights != nWeights) { Melder_throw (U"Number of weights is incorret."); } my nWeights = nWeights; // The following test is essential because when an FFNet is read from file the w array already exists if (my w == 0) { my w = NUMvector (1, my nWeights); } my activity = NUMvector (1, my nNodes); my isbias = NUMvector (1, my nNodes); my nodeFirst = NUMvector (1, my nNodes); my nodeLast = NUMvector (1, my nNodes); my wFirst = NUMvector (1, my nNodes); my wLast = NUMvector (1, my nNodes); my wSelected = NUMvector (1, my nWeights); my error = NUMvector (1, my nNodes); my deriv = NUMvector (1, my nNodes); my dwi = NUMvector (1, my nWeights); my dw = NUMvector (1, my nWeights); my nInputs = my nUnitsInLayer[0]; my nOutputs = my nUnitsInLayer[my nLayers]; my isbias[my nInputs + 1] = 1; my activity[my nInputs + 1] = 1.0; long n = my nUnitsInLayer[0] + 2; long firstNodeInPrevious = 1, lastWeightInPrevious = 0; for (long j = 1; j <= my nLayers; j++, n++) { for (long i = 1; i <= my nUnitsInLayer[j]; i++, n++) { my isbias[n] = 0; my nodeFirst[n] = firstNodeInPrevious; my nodeLast[n] = my nodeFirst[n] + my nUnitsInLayer[j - 1]; my wFirst[n] = lastWeightInPrevious + (i - 1) * (my nUnitsInLayer[j - 1] + 1) + 1; my wLast[n] = my wFirst[n] + my nUnitsInLayer[j - 1]; } if (j != my nLayers) { my isbias[n] = 1; my activity[n] = 1.0; } lastWeightInPrevious = my wLast[n - 1]; firstNodeInPrevious += my nUnitsInLayer[j - 1] + 1; } FFNet_selectAllWeights (me); } void structFFNet :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Number of layers: ", nLayers); MelderInfo_writeLine (U"Total number of units: ", FFNet_getNumberOfUnits (this)); MelderInfo_writeLine (U" Number of units in layer ", nLayers, U" (output): ", nUnitsInLayer[nLayers]); for (long i = nLayers - 1; i >= 1; i--) { MelderInfo_writeLine (U" Number of units in layer ", i, U" (hidden): ", nUnitsInLayer[i]); } MelderInfo_writeLine (U" Number of units in layer 0 (input): ", nUnitsInLayer[0]); MelderInfo_writeLine (U"Outputs are linear: ", Melder_boolean (outputsAreLinear)); MelderInfo_writeLine (U"Number of weights: ", nWeights, U" (", FFNet_dimensionOfSearchSpace (this), U" selected)"); MelderInfo_writeLine (U"Number of nodes: ", nNodes); } void FFNet_init (FFNet me, long numberOfInputs, long nodesInLayer1, long nodesInLayer2, long numberOfOutputs, int outputsAreLinear) { long numberOfLayers = 3; if (numberOfInputs < 1) { Melder_throw (U"Number of inputs must be a natural number."); } if (numberOfOutputs < 1) { Melder_throw (U"Number of outputs must be a natural number."); } if (nodesInLayer1 < 1) { numberOfLayers--; } if (nodesInLayer2 < 1) { numberOfLayers--; } my nLayers = numberOfLayers; my nUnitsInLayer = NUMvector (0, numberOfLayers); my nUnitsInLayer[numberOfLayers--] = numberOfOutputs; if (nodesInLayer2 > 0) { my nUnitsInLayer[numberOfLayers--] = nodesInLayer2; } if (nodesInLayer1 > 0) { my nUnitsInLayer[numberOfLayers--] = nodesInLayer1; } my nUnitsInLayer[numberOfLayers] = numberOfInputs; Melder_assert (numberOfLayers == 0); my outputsAreLinear = outputsAreLinear; bookkeeping (me); FFNet_setCostFunction (me, FFNet_COST_MSE); FFNet_setNonLinearity (me, FFNet_NONLIN_SIGMOID); FFNet_reset (me, 0.1); } void FFNet_setOutputCategories (FFNet me, Categories thee) { autoCategories uniq = Categories_selectUniqueItems (thee, 1); if (uniq -> size == thy size) { my outputCategories = uniq.transfer(); } } autoFFNet FFNet_create (long numberOfInputs, long numberInLayer1, long numberInLayer2, long numberOfOutputs, int outputsAreLinear) { try { autoFFNet me = Thing_new (FFNet); FFNet_init (me.peek(), numberOfInputs, numberInLayer1, numberInLayer2, numberOfOutputs, outputsAreLinear); return me; } catch (MelderError) { Melder_throw (U"FFNet not created."); } } void FFNet_setNonLinearity (FFNet me, int nonLinearityType) { my nonLinearityType = nonLinearityType; my nonLinearity = sigmoid; my nlClosure = nullptr; } void FFNet_setCostFunction (FFNet me, int costType) { my costFunctionType = costType; if (costType == 2) { my costFunction = minimumCrossEntropy; } else { my costFunction = minimumSquaredError; } my cfClosure = nullptr; } double FFNet_getBias (FFNet me, long layer, long unit) { try { long node = FFNet_getNodeNumberFromUnitNumber (me, unit, layer); if (node < 1) { Melder_throw (U"Not a valid unit / layer combination."); } long bias_unit = my wLast[node]; return my w[bias_unit]; } catch (MelderError) { return NUMundefined; } } void FFNet_setBias (FFNet me, long layer, long unit, double value) { long node = FFNet_getNodeNumberFromUnitNumber (me, unit, layer); if (node < 1) { Melder_throw (U"Not a valid unit / layer combination."); } long bias_unit = my wLast[node]; // ??? +1 my w[bias_unit] = value; } void FFNet_setWeight (FFNet me, long layer, long unit, long unit_from, double value) { long node = FFNet_getNodeNumberFromUnitNumber (me, unit, layer); if (node < 1) { Melder_throw (U"Not a valid unit / layer combination."); } long nodef = FFNet_getNodeNumberFromUnitNumber (me, unit_from, layer - 1); if (nodef < 1) { Melder_throw (U"Not a valid unit / layer combination."); } long w_unit = my wFirst[node] + unit_from - 1; my w[w_unit] = value; } double FFNet_getWeight (FFNet me, long layer, long unit, long unit_from) { long node = FFNet_getNodeNumberFromUnitNumber (me, unit, layer); if (node < 1) { Melder_throw (U"Not a valid unit / layer combination."); } long nodef = FFNet_getNodeNumberFromUnitNumber (me, unit_from, layer - 1); if (nodef < 1) { Melder_throw (U"Not a valid unit / layer combination."); } long w_unit = my wFirst[node] + unit_from - 1; return my w[w_unit]; } void FFNet_reset (FFNet me, double wrange) { for (long i = 1; i <= my nWeights; i++) { if (my wSelected[i]) { my w[i] = NUMrandomUniform (-wrange, wrange); } } for (long i = 1; i <= my nNodes; i++) { my activity[i] = (my isbias[i] ? 1.0 : 0.0); } my accumulatedCost = 0.0; forget (my minimizer); } /***** OPERATION: ***********************************************************/ /* step 1 */ void FFNet_propagate (FFNet me, const double input[], double output[]) { // clamp input pattern on the network for (long i = 1; i <= my nUnitsInLayer[0]; i++) { my activity[i] = input[i]; } // on hidden units use activation function long k = 1, nNodes = my outputsAreLinear ? my nNodes - my nOutputs : my nNodes; for (long i = my nUnitsInLayer[0] + 2; i <= nNodes; i++) { if (my isbias[i]) { continue; } double act = 0.0; for (long j = my nodeFirst[i]; j <= my nodeLast[i]; j++, k++) { act += my w[k] * my activity[j]; } my activity[i] = my nonLinearity (me, act, & my deriv[i]); } // on output units use another activation function if (my outputsAreLinear) { for (long i = nNodes + 1; i <= my nNodes; i++) { if (my isbias[i]) { continue; } double act = 0.0; for (long j = my nodeFirst[i]; j <= my nodeLast[i]; j++, k++) { act += my w[k] * my activity[j]; } my activity[i] = act; my deriv[i] = 1.0; } } k = my nNodes - my nOutputs + 1; if (output) { for (long i = 1; i <= my nOutputs; i++, k++) { output[i] = my activity[k]; } } } double FFNet_computeError (FFNet me, const double target[]) { // compute error at output layer double cost = my costFunction (me, target); for (long i = 1; i <= my nNodes - my nOutputs; i++) { my error[i] = 0.0; } // backpropagation of errors from output to first hidden layer for (long i = my nNodes; i > my nInputs + 1; i--) { if (my isbias[i]) { continue; } my error[i] *= my deriv[i]; if (my nodeFirst[i] > my nInputs + 1) { long k = my wFirst[i]; for (long j = my nodeFirst[i]; j <= my nodeLast[i] - 1; j++, k++) { my error[j] += my error[i] * my w[k]; } } } return cost; } void FFNet_computeDerivative (FFNet me) { long k = 1; for (long i = my nInputs + 2; i <= my nNodes; i++) { if (! my isbias[i]) { for (long j = my nodeFirst[i]; j <= my nodeLast[i]; j++, k++) { my dwi[k] = - my error[i] * my activity[j]; } } } } /******* end operation ******************************************************/ long FFNet_getWinningUnit (FFNet me, int labeling) { long pos = 1, k = my nNodes - my nOutputs; if (labeling == 2) { /* stochastic */ double sum = 0.0; for (long i = 1; i <= my nOutputs; i++) { sum += my activity[k + i]; } double random = NUMrandomUniform (0.0, sum); for (pos = my nOutputs; pos >= 2; pos--) { if (random > (sum -= my activity[k + pos])) { break; } } } else { /* winner-takes-all */ double max = my activity[k + 1]; for (long i = 2; i <= my nOutputs; i++) if (my activity[k + i] > max) { max = my activity[k + i]; pos = i; } } return pos; } void FFNet_propagateToLayer (FFNet me, const double input[], double activity[], long layer) { Melder_assert (activity); long k = 0; FFNet_propagate (me, input, nullptr); for (long i = 0; i < layer; i++) { k += my nUnitsInLayer[i] + 1; } for (long i = 1; i <= my nUnitsInLayer[layer]; i++) { activity[i] = my activity[k + i]; } } void FFNet_selectAllWeights (FFNet me) { for (long i = 1; i <= my nWeights; i++) { my wSelected[i] = 1; } my dimension = my nWeights; } long FFNet_dimensionOfSearchSpace (FFNet me) { long n = 0; for (long i = 1; i <= my nWeights; i++) { if (my wSelected[i]) { n++; } } return n; } void FFNet_selectBiasesInLayer (FFNet me, long layer) { long node = my nUnitsInLayer[0] + 1; if (layer < 1 || layer > my nLayers) { return; } for (long i = 1; i <= my nWeights; i++) { my wSelected[i] = 0.0; } for (long i = 1; i < layer; i++) { node += my nUnitsInLayer[i] + 1; } for (long i = node + 1; i <= node + my nUnitsInLayer[layer]; i++) { my wSelected[my wLast[i]] = 1; } my dimension = my nUnitsInLayer[layer]; } void FFNet_weightConnectsUnits (FFNet me, long index, long *fromUnit, long *toUnit, long *layer) { Melder_assert (index > 0 && index <= my nWeights); long i = 1, np = 0, nw = my nUnitsInLayer[1] * (my nInputs + 1); while (index > nw) { i++; nw += (np = my nUnitsInLayer[i] * (my nUnitsInLayer[i - 1] + 1)); } if (i > 1) { index -= nw - np; } *fromUnit = index % (my nUnitsInLayer[i - 1] + 1); *toUnit = (index - 1) / (my nUnitsInLayer[i - 1] + 1) + 1; *layer = i; } long FFNet_getNodeNumberFromUnitNumber (FFNet me, long unit, long layer) { if (layer < 0 || layer > my nLayers || unit > my nUnitsInLayer[layer]) { return -1; } long node = unit; for (long i = 0; i < layer; i++) { node += my nUnitsInLayer[i] + 1; } return node; } void FFNet_nodeToUnitInLayer (FFNet me, long node, long *unit, long *layer) { Melder_assert (node > 0 && node <= my nNodes); long i = 0, nn = my nUnitsInLayer[0] + 1; while (node > nn) { nn += my nUnitsInLayer[++i] + 1; } if (i > 0) { node -= nn - (my nUnitsInLayer[i] + 1); } *unit = node % (my nUnitsInLayer[i] + 1); *layer = i; } long FFNet_getNumberOfWeights (FFNet me) { return my nWeights; } long FFNet_getNumberOfLayers (FFNet me) { return my nLayers; } long FFNet_getNumberOfUnits (FFNet me) { return my nNodes - my nLayers; } long FFNet_getNumberOfHiddenLayers (FFNet me) { return my nLayers - 1; } long FFNet_getNumberOfUnitsInLayer (FFNet me, int layer) { if (layer > my nLayers || layer < 0) { return 0; } return my nUnitsInLayer[layer]; } double FFNet_getMinimum (FFNet me) { return my minimizer ? Minimizer_getMinimum (my minimizer) : NUMundefined; } void FFNet_drawTopology (FFNet me, Graphics g) { long maxNumOfUnits = my nUnitsInLayer[0]; int dxIsFixed = 1; double dy = 1.0 / (my nLayers + 1); for (long i = 1; i <= my nLayers; i++) { if (my nUnitsInLayer[i] > maxNumOfUnits) { maxNumOfUnits = my nUnitsInLayer[i]; } } double dx = 1.0 / maxNumOfUnits; double radius = dx / 10.0; Graphics_setInner (g); Graphics_setWindow (g, 0.0, 1.0, 0.0, 1.0); for (long i = 0; i <= my nLayers; i++) { double dx2 = dx, x2WC, y2WC = dy / 2 + i * dy; double x2 = (maxNumOfUnits - my nUnitsInLayer[i] + 1) * dx2 / 2; /* draw the units */ if (! dxIsFixed) { dx2 = 1.0 / my nUnitsInLayer[i]; x2 = dx2 / 2.0; } if (i == 0) { Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_TOP); x2WC = x2; for (long j = 1; j <= my nInputs; j++) { Graphics_arrow (g, x2WC, y2WC - radius - dy / 4.0, x2WC, y2WC - radius); x2WC += dx2; } } Graphics_setColour (g, Graphics_RED); x2WC = x2; for (long j = 1; j <= my nUnitsInLayer[i]; j++) { Graphics_circle (g, x2WC, y2WC, radius); if (i > 0) { Graphics_fillCircle (g, x2WC, y2WC, radius); } x2WC += dx2; } Graphics_setColour (g, Graphics_BLACK); if (i > 0) { double dx1 = dx; double x1 = (maxNumOfUnits - my nUnitsInLayer[i - 1] + 1) * dx1 / 2.0; double y1WC = y2WC - dy; if (! dxIsFixed) { dx1 = 1.0 / my nUnitsInLayer[i - 1]; x1 = dx1 / 2.0; } x2WC = x2; for (long j = 1; j <= my nUnitsInLayer[i]; j++) { double x1WC = x1; for (long k = 1; k <= my nUnitsInLayer[i - 1]; k++) { double xd = x2WC - x1WC; double cosa = xd / sqrt (xd * xd + dy * dy); double sina = dy / sqrt (xd * xd + dy * dy); Graphics_line (g, x1WC + radius * cosa, y1WC + radius * sina, x2WC - radius * cosa, y2WC - radius * sina); x1WC += dx1; } x2WC += dx2; } } if (i == my nLayers) { x2WC = x2; Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_BOTTOM); for (long j = 1; j <= my nOutputs; j++) { Graphics_arrow (g, x2WC, y2WC + radius, x2WC, y2WC + radius + dy / 4.0); if (my outputCategories) { Categories_drawItem (my outputCategories.peek(), g, j, x2WC, y2WC + radius + dy / 4.0); } x2WC += dx2; } } } Graphics_unsetInner (g); } void FFNet_drawActivation (FFNet me, Graphics g) { long node = 1, maxNumOfUnits = my nUnitsInLayer[0]; int dxIsFixed = 1; Graphics_Colour colour = Graphics_inqColour (g); double dy = 1.0 / (my nLayers + 1); Graphics_setInner (g); Graphics_setWindow (g, 0.0, 1.0, 0.0, 1.0); for (long i = 1; i <= my nLayers; i++) { if (my nUnitsInLayer[i] > maxNumOfUnits) { maxNumOfUnits = my nUnitsInLayer[i]; } } double dx = 1.0 / maxNumOfUnits; double r1 = dx / 2.0; /* May touch when neighbouring activities are both 1 (very rare). */ for (long i = 0; i <= my nLayers; i++, node++) { double dx2 = dx, x2WC, y2WC = dy / 2.0 + i * dy; double x2 = (maxNumOfUnits - my nUnitsInLayer[i] + 1) * dx2 / 2.0; if (! dxIsFixed) { dx2 = 1.0 / my nUnitsInLayer[i]; x2 = dx2 / 2.0; } x2WC = x2; for (long j = 1; j <= my nUnitsInLayer[i]; j++, node++) { double activity = my activity[node]; double radius = r1 * (fabs (activity) < 0.05 ? 0.05 : fabs (activity)); /*Graphics_setColour (g, activity < 0 ? Graphics_BLACK : Graphics_RED);*/ Graphics_circle (g, x2WC, y2WC, radius); if (activity < 0) { Graphics_fillCircle (g, x2WC, y2WC, radius); } x2WC += dx2; } } Graphics_setColour (g, colour); Graphics_unsetInner (g); } /* This routine is deprecated since praat-4.2.4 20040422 and will be removed in the future. */ void FFNet_drawWeightsToLayer (FFNet me, Graphics g, int layer, int scaling, int garnish) { if (layer < 1 || layer > my nLayers) { Melder_throw (U"Layer must be in [1,", my nLayers, U"]."); } autoMatrix weights = FFNet_weightsToMatrix (me, layer, 0); Matrix_scale (weights.peek(), scaling); Matrix_drawAsSquares (weights.peek(), g, 0.0, 0.0, 0.0, 0.0, 0); if (garnish) { double x1WC, x2WC, y1WC, y2WC; Graphics_inqWindow (g, & x1WC, & x2WC, & y1WC, & y2WC); Graphics_textBottom (g, false, Melder_cat (U"Units in layer ", layer, U" ->")); if (layer == 1) { Graphics_textLeft (g, false, U"Input units ->"); } else { Graphics_textLeft (g, false, Melder_cat (U"Units in layer ", layer - 1, U" ->")); } /* how do I find out the current settings ??? */ Graphics_setTextAlignment (g, Graphics_RIGHT, Graphics_HALF); Graphics_setInner (g); Graphics_text (g, 0.5, weights->ny, U"bias"); Graphics_unsetInner (g); } } void FFNet_drawWeights (FFNet me, Graphics g, long layer, int garnish) { autoTableOfReal thee = FFNet_extractWeights (me, layer); TableOfReal_drawAsSquares (thee.peek(), g, 1, thy numberOfRows, 1, thy numberOfColumns, garnish); } void FFNet_drawCostHistory (FFNet me, Graphics g, long iFrom, long iTo, double costMin, double costMax, int garnish) { if (my minimizer) { Minimizer_drawHistory (my minimizer, g, iFrom, iTo, costMin, costMax, 0); } if (garnish) { Graphics_drawInnerBox (g); Graphics_textLeft (g, true, my costFunctionType == FFNet_COST_MSE ? U"Minimum squared error" : U"Minimum cross entropy"); Graphics_marksLeft (g, 2, true, true, false); Graphics_textBottom (g, true, U"Number of epochs"); Graphics_marksBottom (g, 2, true, true, false); } } autoCollection FFNet_createIrisExample (long numberOfHidden1, long numberOfHidden2) { try { autoCollection c = Collection_create (classDaata, 3); autoCategories uniq = Categories_sequentialNumbers (3); autoFFNet me = FFNet_create (4, numberOfHidden1, numberOfHidden2, 3, 0); FFNet_setOutputCategories (me.peek(), uniq.peek()); autostring32 name = FFNet_createNameFromTopology (me.peek()); Thing_setName (me.peek(), name.peek()); Collection_addItem (c.peek(), me.transfer()); autoTableOfReal iris = TableOfReal_createIrisDataset (); // Scale data to interval [0-1] for (long i = 1; i <= 150; i++) { for (long j = 1; j <= 4; j++) { iris -> data[i][j] /= 10.0; } } Pattern thee = nullptr; Categories him = nullptr; TableOfReal_to_Pattern_and_Categories (iris.peek(), 0, 0, 0, 0, &thee, &him); autoPattern ap = thee; autoCategories ac = him; Thing_setName (ap.peek(), U"iris"); Thing_setName (ac.peek(), U"iris"); Collection_addItem (c.peek(), ap.transfer()); Collection_addItem (c.peek(), ac.transfer()); return c; } catch (MelderError) { Melder_throw (U"Iris example not created."); } } autoTableOfReal FFNet_extractWeights (FFNet me, long layer) { try { FFNet_checkLayerNumber (me, layer); long numberOfUnitsFrom = my nUnitsInLayer[layer - 1] + 1; long numberOfUnitsTo = my nUnitsInLayer[layer]; autoTableOfReal thee = TableOfReal_create (numberOfUnitsFrom, numberOfUnitsTo); char32 label[40]; for (long i = 1; i <= numberOfUnitsFrom - 1; i++) { Melder_sprint (label,40, U"L", layer - 1, U"-", i); TableOfReal_setRowLabel (thee.peek(), i, label); } TableOfReal_setRowLabel (thee.peek(), numberOfUnitsFrom, U"Bias"); for (long i = 1; i <= numberOfUnitsTo; i++) { Melder_sprint (label,40, U"L", layer, U"-", i); TableOfReal_setColumnLabel (thee.peek(), i, label); } long node = 1; for (long i = 0; i < layer; i++) { node += my nUnitsInLayer[i] + 1; } for (long i = 1; i <= numberOfUnitsTo; i++, node++) { long k = 1; for (long j = my wFirst[node]; j <= my wLast[node]; j++) { thy data[k++][i] = my w[j]; } } return thee; } catch (MelderError) { Melder_throw (me, U": no TableOfReal created."); } } autoFFNet FFNet_and_TabelOfReal_to_FFNet (FFNet me, TableOfReal him, long layer) { try { FFNet_checkLayerNumber (me, layer); if ((my nUnitsInLayer[layer] != his numberOfColumns) || (my nUnitsInLayer[layer] == his numberOfColumns && my nUnitsInLayer[layer - 1] + 1 == his numberOfRows)) { long trys[1+3], rows[1+3], cols[1+3], ntry = my nLayers > 3 ? 3 : my nLayers, ok = 0; if (my nLayers > 3) { Melder_throw (U"Dimensions don't fit."); } for (long i = 1; i <= ntry; i++) { cols[i] = my nUnitsInLayer[i] == his numberOfColumns; rows[i] = my nUnitsInLayer[i - 1] + 1 == his numberOfRows; trys[i] = rows[i] && cols[i]; if (trys[i]) { ok ++; } } if (! rows[layer]){ Melder_throw (U"The number of rows in the TableOfReal does not equal \n" U"the number of units in the layer that connect to layer ", layer, U"."); } else { Melder_throw (U"The number of columns in the TableOfReal does not equal \n" U"the number of units in layer ", layer, U"."); } if (ok == 0) { Melder_throw (U"Please quit, there is no appropriate layer in the FFNet for this TableOfReal."); } else { if (ok == 1) { Melder_throw (U"Please try again with layer number ", trys[1] ? trys[1] : (trys[2] ? trys[2] : trys[3]), U"."); } else { Melder_throw (U"Please try again with one of the other two layer numbers."); } } } autoFFNet thee = Data_copy (me); long node = 1; for (long i = 0; i < layer; i++) { node += thy nUnitsInLayer[i] + 1; } for (long i = 1; i <= thy nUnitsInLayer[layer]; i++, node++) { long k = 1; for (long j = thy wFirst[node]; j <= thy wLast[node]; j++, k++) { thy w[j] = his data[k][i]; } } return thee; } catch (MelderError) { Melder_throw (me, U": no FFNet created."); } } /* End of file FFNet.cpp */ praat-6.0.04/FFNet/FFNet.h000066400000000000000000000222471261542461700150040ustar00rootroot00000000000000#ifndef _FFNet_h_ #define _FFNet_h_ /* FFNet.h * * Copyright (C) 1997-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19970515 djmw 20020712 GPL header. djmw 20031025 Added FFNet_getMinimum. djmw 20040420 FFNet_create and Pattern&Categories: To FFNet changes. djmw 20040422 FFNet_extractWeights added. djmw 20040505 FFNet_getNodeNumberFromUnitNumber added. djmw 20071024 Latest modification. djmw 20080121 float -> double */ #include "Data.h" #include "Categories.h" #include "Minimizers.h" #include "TableOfReal.h" #include "FFNet_def.h" oo_CLASS_CREATE (FFNet, Daata); /* Parameters: * long nLayers : the #layers in the net (exclusive the inputs) * nUnitsInLayer : array[0..nLayers] the #units in each layer * nUnitsInLayer[0] : #inputs * nUnitsInLayer[nLayers] :#outputs * nWeights : the total #weights in the net (inclusive bias) * double *w : array[1..nWeights] with the connection strengths * *activity : array[1..nNodes] with activities * outputLabels : labels belonging to the outputs * BOOKKEEPING: * long nNodes : total #nodes: bias modelled as unit with constant activity) * *isbias : array[1..nNodes] set 1 if node is bias else 0 * *nodeFirst : array[1..nNodes] first node connected to this unit * *nodeLast: : array[1..nNodes] last node connected to this unit * *wFirst : array[1..nNodes] first index in *w for this unit * *wLast : array[1..nNodes] last (inclusive the bias) * LEARNING: * int *wSelected : array[1..nWeights] weights selected for minimization * double *deriv : array[1..nNodes] derivative of nonlinearity at node * *error : array[1..nNodes] the error at node * *dw : array[1..nWeights] total derivative for weights * *dwi : array[1..nWeights] derivative per pattern * long dimension : dimension of minimizer space (<= my nWeights) * long nPatterns : the #patterns to be learned * double **inputPattern: matrix[1..nPatterns][1..nInputs] * double **targetActivation: matrix[1..nPatterns][1..nOutputs] * double accumulatedCost : accumulated costs of testing/training with patterns * * A network consists of nLayers layers. Layer numbering is from 0...nLayers. * Layer 0 is the input layer, the highest numbered layer is the output layer * (nLayers <= 4) * Each layer consists of a number of units. The biases of all the units in a layer * are modelled with connections to an extra unit in the lower layer (with constant * activity 1.0). Nodes refers to 'units' + 'bias units'. * The variable 'nNodes' is the total number of nodes (inclusive bias nodes). * E.g. the topology (2,3,4), i.e., 2 inputs, 3 units in the first layer * and 4 units in the second layer (outputs) is modelled * with (2+1)+ (3+1)+ (4) = 11 nodes. * The numbering of the weights is as follows (indices 1..nWeights): * E.g., topology (I,H,O) (I inputs, H hidden units and O output units) * There are a total of H* (I+1) + O* (H+1) weights in this net. * w[1] - w[I] : I (1)->H (1), I (2)->H (1) ... I (I)->H (1) * w[I+1] : bias->H (1) * w[ (I+1)+1] - w[2 (I+1)-1] : I (1)->H (2), I (2)->H (2) ... I (I)->H (2) * w[2 (I+1)] : bias->H (2) * ... * w[ (H-1) (I+1)+1] - w[H (I+1)-1] : I (1)->H (H), I (2)->H (H) ... I (I)->H (H) * w[H (I+1)] : bias->H (H) * M = H (I+1) * w[M+1] - w[M+H] : H (1)->O (1), H (2)->O (1) ... H (H)->O (1) * w[M+H+1] : bias->O (1) * w[M+ (H+1)+1] - w (M+2 (H+1)-1) : H (1)->O (2), H (2)->O (2) ... H (H)->O (2) * w[M+2 (H+1)] : bias->O (1) * ... * w[M+ (O-1)* (H+1)+1] - w[M+O (H+1)-1] : H (1)->O (O), H (2)->O (O) ... H (H)->O (O) * w[m+o (h+1)-1] : bias->O (O) * * Internals: * * A number of auxiliary arrays for efficient calculations have been setup. * For a node k we need to know: * 1. isbias[1..nNodes] : usage: if (isbias[k]) ... * true if node k is a bias node. There are nLayers bias nodes * 2. nodeFirst[1..nNodes] : usage is j=nodeFirst[k]; * j is the first node that is connected to k . * 3. nodeLast[1..nNodes] : usage is j=nodeLast[k] * j is the last node that is connected to k (bias included). * For the calculation of the errors, during learning, in unit k we need to * know which weights from the preceeding layer connect to it. * 4. wFirst[1..nNodes] : usage j=wFirst[k] * w[j] is first weight to node k. * 5. wLast[1..nNodes] : usage j=wLast[k] * w[j] is last weight to node k. */ /* FFNet::copy * copy everything except minimizer, patterns and inputs. */ void FFNet_init (FFNet me, long numberOfInputs, long nodesInLayer1, long nodesInLayer2, long numberOfOutputs, int outputsAreLinear); autoFFNet FFNet_create (long numberOfInputs, long numberInLayer1, long numberInLayer2, long numberOfOutputs, int outputsAreLinear ); autostring32 FFNet_createNameFromTopology (FFNet me); /* Create names as -, --, --- for 1, 2 or 3 layer networks. */ #define FFNet_COST_MSE 1 void FFNet_setCostFunction (FFNet me, int type); #define FFNet_NONLIN_SIGMOID 1 void FFNet_setNonLinearity (FFNet me, int type); void FFNet_setOutputCategories (FFNet me, Categories thee); double FFNet_getBias (FFNet me, long layer, long unit); void FFNet_setBias (FFNet me, long layer, long node, double value); void FFNet_setWeight (FFNet me, long later, long node, long node_from, double value); double FFNet_getWeight (FFNet me, long later, long node, long node_from); void FFNet_reset (FFNet me, double wrange); /* reset the neural net: * initialize all (selected) weights and biases with random numbers from the * interval (-wrange, wrange). * forget links with minimizer. */ void FFNet_propagateToLayer (FFNet me, const double input[], double activity[], long layer); /* propagate the input through the net to layer and calculate the activities */ void FFNet_propagate (FFNet me, const double input[], double output[]); /* step (1) feed forward input from "input layer" to "output layer" * if output != nullptr the output activity is copied into output. * postcondition: my activities defined */ double FFNet_computeError (FFNet me, const double target[]); /* step (2) calculate error on output nodes w.r.t. desired output */ /* step (3) backpropagate this error to previous nodes */ /* precondition: step (1) */ void FFNet_computeDerivative (FFNet me); /* step (4) compute derivative in my dwi */ /* Precondition: step (3) */ long FFNet_getWinningUnit (FFNet me, int labeling); /* labeling = 1 : winner-takes-all */ /* labeling = 2 : stochastic */ void FFNet_selectAllWeights (FFNet me); void FFNet_selectBiasesInLayer (FFNet me, long layer); long FFNet_dimensionOfSearchSpace (FFNet me); /* count the selected weights */ long FFNet_getNumberOfWeights (FFNet me); /* return my nWeights */ void FFNet_weightConnectsUnits (FFNet me, long index, long *fromUnit, long *toUnit, long *layer); /* * w[index] connects unit fromUnit in "layer-1" with unit toUnit in "layer". * fromUnit returns 0 then w[index] is bias. */ long FFNet_getNodeNumberFromUnitNumber (FFNet me, long unit, long layer); void FFNet_nodeToUnitInLayer (FFNet me, long node, long *unit, long *layer); /* translate node index to unit "unit" in layer "layer" */ long FFNet_getNumberOfLayers (FFNet me); long FFNet_getNumberOfUnits (FFNet me); long FFNet_getNumberOfHiddenLayers (FFNet me); long FFNet_getNumberOfUnitsInLayer (FFNet me, int layer); double FFNet_getMinimum (FFNet me); void FFNet_drawTopology (FFNet me, Graphics g); void FFNet_drawActivation (FFNet me, Graphics g); void FFNet_drawWeightsToLayer (FFNet me, Graphics g, int toLayer, int scaling, int garnish); /* Deprecated: the strengths of the weights that connect to the nodes in later 'layer' */ /* are drawn with boxes. The area of each box corresponds to the strength. */ /* Black boxes have negative strength? */ void FFNet_drawCostHistory (FFNet me, Graphics g, long from_iteration, long to_iteration, double from_cost, double to_cost, int garnish); /* draw cost vs epochs */ autoCollection FFNet_createIrisExample (long numberOfHidden1, long numberOfHidden2); autoTableOfReal FFNet_extractWeights (FFNet me, long layer); void FFNet_drawWeights (FFNet me, Graphics g, long layer, int garnish); autoFFNet FFNet_and_TabelOfReal_to_FFNet (FFNet me, TableOfReal him, long layer); #endif /* _FFNet_h_ */ praat-6.0.04/FFNet/FFNet_Activation_Categories.cpp000066400000000000000000000064021261542461700216600ustar00rootroot00000000000000/* FFNet_Activation_Categories.cpp * * Copyright (C) 1997-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19960322 djmw 20020712 GPL header djmw 20040416 Better error messages djmw 20071014 Melder_error */ #include "FFNet_Activation_Categories.h" static long winnerTakesAll (FFNet me, const double activation[]) { long pos = 1; double max = activation[1]; for (long i = 2; i <= my nOutputs; i++) { if (activation[i] > max) { max = activation[i]; pos = i; } } return pos; } static long stochastic (FFNet me, const double activation[]) { long i; double range = 0.0, lower = 0.0; for (i = 1; i <= my nOutputs; i++) { range += activation[i]; } double number = NUMrandomUniform (0.0, range); for (i = 1; i <= my nOutputs; i++) { lower += activation[i]; if (number < lower) { break; } } return i; } autoCategories FFNet_Activation_to_Categories (FFNet me, Activation activation, int labeling) { try { long (*labelingFunction) (FFNet me, const double act[]); if (! my outputCategories) { Melder_throw (U"No Categories (has the FFNet been trained yet?)."); } if (my nOutputs != activation -> nx) { Melder_throw (U"Number of columns and number of outputs must be equal."); } autoCategories thee = Categories_create (); labelingFunction = labeling == 2 ? stochastic : winnerTakesAll; for (long i = 1; i <= activation->ny; i++) { long index = labelingFunction (me, activation -> z[i]); autoSimpleString item = Data_copy ((SimpleString) my outputCategories -> item[index]); Collection_addItem (thee.peek(), item.transfer()); } return thee; } catch (MelderError) { Melder_throw (me, U": no Categories created."); } } autoActivation FFNet_Categories_to_Activation (FFNet me, Categories thee) { try { autoCategories uniq = Categories_selectUniqueItems (thee, 1); if (! my outputCategories) { Melder_throw (U"The FFNet does not have categories."); } long nl = OrderedOfString_isSubsetOf (uniq.peek(), my outputCategories.peek(), 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.peek(), 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."); } } /* End of file FFNet_Activation_Categories.cpp */ praat-6.0.04/FFNet/FFNet_Activation_Categories.h000066400000000000000000000025211261542461700213230ustar00rootroot00000000000000#ifndef _FFNet_Activation_Categories_h_ #define _FFNet_Activation_Categories_h_ /* FFNet_Activation_Categories.h * * Copyright (C) 1997-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19950109 djmw 20020712 GPL header djmw 20110307 Latest modification */ #include "FFNet.h" #include "Activation.h" #include "Categories.h" autoCategories FFNet_Activation_to_Categories (FFNet me, Activation activation, int labeling); /* labeling = 1 : winner-takes-all */ /* labeling = 2 : stochastic */ autoActivation FFNet_Categories_to_Activation (FFNet me, Categories labels); /* Postcondition: my outputCategories != nullptr; */ #endif /* _FFNet_Activation_Categories_h_ */ praat-6.0.04/FFNet/FFNet_Eigen.cpp000066400000000000000000000130251261542461700164400ustar00rootroot00000000000000/* FFNet_Eigen.cpp * * Copyright (C) 1994-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020712 GPL header djmw 20071202 Melder_warning */ #include "FFNet_Eigen.h" #include "Graphics.h" #include "NUM2.h" void FFNet_Eigen_drawIntersection (FFNet me, Eigen eigen, Graphics g, long pcx, long pcy, double xmin, double xmax, double ymin, double ymax) { long ix = labs (pcx), iy = labs (pcy); long numberOfEigenvalues = eigen -> numberOfEigenvalues; long dimension = eigen -> dimension; if (ix > numberOfEigenvalues || iy > numberOfEigenvalues || my nInputs != dimension) { return; } Melder_assert (ix > 0 && iy > 0); double x1, x2, y1, y2; if (xmax <= xmin || ymax <= ymin) { Graphics_inqWindow (g, & x1, & x2, & y1, & y2); } if (xmax <= xmin) { xmin = x1; xmax = x2; } if (ymax <= ymin) { ymin = y1; ymax = y2; } Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); for (long i = 1; i <= my nUnitsInLayer[1]; i++) { long unitOffset = my nInputs + 1; double c1 = 0.0, c2 = 0.0, bias = my w[ my wLast[unitOffset + i] ]; double x[6], y[6], xs[3], ys[3]; int ns = 0; for (long j = 1; j <= my nInputs; j++) { c1 += my w[ my wFirst[unitOffset + i] + j - 1 ] * eigen->eigenvectors[ix][j]; c2 += my w[ my wFirst[unitOffset + i] + j - 1 ] * eigen->eigenvectors[iy][j]; } x[1] = x[2] = x[5] = xmin; x[3] = x[4] = xmax; y[1] = y[4] = y[5] = ymin; y[2] = y[3] = ymax; for (long j = 1; j <= 4; j++) { double p1 = c1 * x[j ] + c2 * y[j ] + bias; double p2 = c1 * x[j + 1] + c2 * y[j + 1] + bias; double r = fabs (p1) / (fabs (p1) + fabs (p2)); if (p1 *p2 > 0 || r == 0.0) { continue; } if (++ns > 2) { break; } xs[ns] = x[j] + (x[j + 1] - x[j]) * r; ys[ns] = y[j] + (y[j + 1] - y[j]) * r; } if (ns < 2) { Melder_casual (U"Intersection for unit ", i, U" outside range"); } else { Graphics_line (g, xs[1], ys[1], xs[2], ys[2]); } } Graphics_unsetInner (g); } /* Draw the intersection line of the decision hyperplane 'w.e-b' of the weights of unit i from layer j with the plane spanned by eigenvectors pcx and pcy. */ void FFNet_Eigen_drawDecisionPlaneInEigenspace (FFNet me, thou, Graphics g, long unit, long layer, long pcx, long pcy, double xmin, double xmax, double ymin, double ymax) { thouart (Eigen); if (layer < 1 || layer > my nLayers) { return; } if (unit < 1 || unit > my nUnitsInLayer[layer]) { return; } if (pcx > thy numberOfEigenvalues || pcy > thy numberOfEigenvalues) { return; } if (my nUnitsInLayer[layer - 1] != thy dimension) { return; } double x1, x2, y1, y2; Graphics_inqWindow (g, & x1, & x2, & y1, & y2); if (xmax <= xmin) { xmin = x1; xmax = x2; } if (ymax <= ymin) { ymin = y1; ymax = y2; } Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); long node = FFNet_getNodeNumberFromUnitNumber (me, unit, layer); if (node < 1) { return; } /* Suppose p1 and p2 are the two points in the eigenplane, spanned by the eigenvectors e1 and e2, where the neural net decision hyperplane intersects these eigenvectors. Their coordinates in the eigenplane will be (x0*e1, 0) and (0,y0*e2). At the same time, the two points are part of the decision hyperplane of the chosen unit. The hyperplane equation is: w.e+bias = 0, where 'w' is the weight vector, 'e' is the input vector and 'b' is the bias. This results in two equations for the unknown x0 and y0: w.(x0*e1)+bias = 0 w.(y0*e2)+bias = 0 This suggests the solution for x0 and y0: x0 = -bias / (w.e1) y0 = -bias / (w.e2) If w.e1 != 0 && w.e2 != 0 p1 = (x0, 0) and p2 = (0, y0) If w.e1 == 0 && w.e2 != 0 The line is parallel to e1 and intersects e2 at y0. If w.e2 == 0 && w.e1 != 0 The line is parallel to e2 and intersects e1 at x0. If w.e1 == 0 && w.e2 == 0 Both planes are parallel, no intersection. */ long iw = my wFirst[node] - 1; double we1 = 0.0, we2 = 0.0; for (long i = 1; i <= my nUnitsInLayer[layer - 1]; i++) { we1 += my w[iw + i] * thy eigenvectors[pcx][i]; we2 += my w[iw + i] * thy eigenvectors[pcy][i]; } double bias = my w[my wLast[node]]; x1 = xmin; x2 = xmax; y1 = ymin; y2 = ymax; if (we1 != 0.0) { x1 = -bias / we1; y1 = 0.0; } if (we2 != 0.0) { x2 = 0.0; y2 = -bias / we2; } if (we1 == 0.0 && we2 == 0.0) { Melder_warning (U"We cannot draw the intersection of the neural net decision plane\n" "for unit ", unit, U" in layer ", layer, U" with the plane spanned by the eigenvectors because \nboth planes are parallel."); return; } double xi[3], yi[3]; /* Intersections */ double ni = NUMgetIntersectionsWithRectangle (x1, y1, x2, y2, xmin, ymin, xmax, ymax, xi, yi); if (ni == 2) { Graphics_line (g, xi[1], yi[1], xi[2], yi[2]); } else { Melder_warning (U"There were no intersections in the drawing area.\nPlease enlarge the drawing area."); } Graphics_unsetInner (g); } /* End of file FFNet_Eigen.cpp */ praat-6.0.04/FFNet/FFNet_Eigen.h000066400000000000000000000027331261542461700161110ustar00rootroot00000000000000#ifndef _FFNet_Eigen_h_ #define _FFNet_Eigen_h_ /* FFNet_Eigen.h * * Copyright (C) 1994-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19940726 djmw 20110307 Latest modification. */ #include "FFNet.h" #include "Eigen.h" void FFNet_Eigen_drawIntersection (FFNet me, Eigen eigen, Graphics g, long pcx, long pcy, double xmin, double xmax, double ymin, double ymax); /* Draw intersections of hyperplanes of units in layer 1 with eigenplane */ /* formed by pcx and pcy. */ /* pcx (pcy) > 0 : negative values left (bottom), positive right (top) */ /* pcx (pcy) < 0 : negative values right (top). */ void FFNet_Eigen_drawDecisionPlaneInEigenspace (FFNet me, thou, Graphics g, long unit, long layer, long pcx, long pcy, double xmin, double xmax, double ymin, double ymax); #endif /* _FFNet_Eigen_h_ */ praat-6.0.04/FFNet/FFNet_Matrix.cpp000066400000000000000000000051041261542461700166540ustar00rootroot00000000000000/* FFNet_Matrix.cpp * * Copyright (C) 1997-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19950206 djmw 20020712 GPL header */ #include "FFNet_Matrix.h" autoMatrix FFNet_weightsToMatrix (FFNet me, long layer, int deltaWeights) { try { if (layer < 1 || layer > my nLayers) { Melder_throw (U"Layer must be > 0 and < ", my nLayers, U"."); } autoMatrix thee = Matrix_create (0.5, my nUnitsInLayer[layer] + 0.5, my nUnitsInLayer[layer], 1.0, 1.0, 0.5, my nUnitsInLayer[layer - 1] + 1 + 0.5, my nUnitsInLayer[layer - 1] + 1, 1.0, 1.0); long node = 1; for (long i = 0; i < layer; i++) { node += my nUnitsInLayer[i] + 1; } for (long i = 1; i <= my nUnitsInLayer[layer]; i++, node++) { long k = 1; for (long j = my wFirst[node]; j <= my wLast[node]; j++) { thy z[k++][i] = deltaWeights ? my dwi[j] : my w[j]; } } return thee; } catch (MelderError) { Melder_throw (me, U": no Matrix created."); } } autoFFNet FFNet_weightsFromMatrix (FFNet me, Matrix him, long layer) { try { if (layer < 1 || layer > my nLayers) { Melder_throw (U"Layer must be > 0 and < ", my nLayers, U"."); } if (my nUnitsInLayer[layer] != his nx) { Melder_throw (U"The #columns (", his nx, U") must equal #units (", my nUnitsInLayer[layer], U") in layer ", layer, U"."); } long nunits = my nUnitsInLayer[layer - 1] + 1; if (nunits != his ny) { Melder_throw (U" The #rows (", his ny, U") must equal #units (", nunits , U") in layer ", layer - 1, U"."); } autoFFNet thee = Data_copy (me); long node = 1; for (long i = 0; i < layer; i++) { node += thy nUnitsInLayer[i] + 1; } for (long i = 1; i <= thy nUnitsInLayer[layer]; i++, node++) { long k = 1; for (long j = thy wFirst[node]; j <= thy wLast[node]; j++, k++) { thy w[j] = his z[k][i]; } } return thee; } catch (MelderError) { Melder_throw (me, U": no FFNet created."); } } /* End of file FFNet_Matrix.cpp */ praat-6.0.04/FFNet/FFNet_Matrix.h000066400000000000000000000031461261542461700163250ustar00rootroot00000000000000#ifndef _FFNet_Matrix_h_ #define _FFNet_Matrix_h_ /* FFNet_Matrix.h * * Copyright (C) 1997-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19950206 djmw 20020712 GPL header djmw 20110307 Latest modification */ #include "Matrix.h" #include "FFNet.h" /* The Matrix organization is as follows: */ /* */ /* nx = nUnitsInLayer[layer] */ /* ny = nUnitsInLayer[layer-1]+1 */ /* xmin = 1 xmax = nx */ /* ymin = 1 ymax = ny */ /* dx = dy = 1 */ /* x1 = y1 = 1 */ /* */ autoMatrix FFNet_weightsToMatrix (FFNet me, long layer, int deltaWeights); /* (delta) weights connected to layer into Matrix */ autoFFNet FFNet_weightsFromMatrix (FFNet me, Matrix matrix, long layer); /* creates a new FFNet in which the weights that connect to layer are */ /* replaced by the weights in the matrix */ #endif /* _FFNet_Matrix_h_ */ praat-6.0.04/FFNet/FFNet_Pattern.cpp000066400000000000000000000021251261542461700170250ustar00rootroot00000000000000/* FFNet_Pattern.cpp * * Copyright (C) 1997-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19950113 djmw 20020712 GPL header */ #include "FFNet_Pattern.h" void FFNet_Pattern_drawActivation (FFNet me, Pattern pattern, Graphics g, long index) { if (index < 1 || index > pattern->ny) { return; } FFNet_propagate (me, pattern->z[index], nullptr); FFNet_drawActivation (me, g); } /* End of file FFNet_Pattern.cpp */ praat-6.0.04/FFNet/FFNet_Pattern.h000066400000000000000000000020611261542461700164710ustar00rootroot00000000000000#ifndef _FFNet_Pattern_h_ #define _FFNet_Pattern_h_ /* FFNet_Pattern.h * * Copyright (C) 1997-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19950113 djmw 20020712 GPL header djmw 20110307 Latest modification */ #include "Pattern.h" #include "FFNet.h" void FFNet_Pattern_drawActivation( FFNet me, Pattern pattern, Graphics g, long ipattern ); #endif /* _FFNet_Pattern_h_ */ praat-6.0.04/FFNet/FFNet_Pattern_Activation.cpp000066400000000000000000000152501261542461700212110ustar00rootroot00000000000000/* FFNet_Pattern_Activation.cpp * * Copyright (C) 1994-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19960826 djmw 20020712 GPL header djmw 20030701 Removed non-GPL minimizations djmw 20040416 More precise error messages. djmw 20041118 Added FFNet_Pattern_Categories_getCosts. */ #include "Graphics.h" #include "FFNet_Pattern_Activation.h" static double func (Daata object, const double p[]) { FFNet me = (FFNet) object; Minimizer thee = my minimizer; double fp = 0.0; for (long j = 1, k = 1; k <= my nWeights; k++) { my dw[k] = 0.0; if (my wSelected[k]) { my w[k] = p[j++]; } } for (long i = 1; i <= my nPatterns; i++) { FFNet_propagate (me, my inputPattern[i], nullptr); fp += FFNet_computeError (me, my targetActivation[i]); FFNet_computeDerivative (me); /* derivative (cumulative) */ for (long k = 1; k <= my nWeights; k++) { my dw[k] += my dwi[k]; } } thy funcCalls++; return fp; } static void dfunc_optimized (Daata object, const double p[], double dp[]) { FFNet me = (FFNet) object; (void) p; long j = 1; for (long k = 1; k <= my nWeights; k++) { if (my wSelected[k]) { dp[j++] = my dw[k]; } } } static void _FFNet_Pattern_Activation_checkDimensions (FFNet me, Pattern p, Activation a) { if (my nInputs != p -> nx) { Melder_throw (U"The Pattern and the FFNet do not match.\nThe number of columns in the Pattern must equal the number of inputs in the FFNet."); } if (my nOutputs != a -> nx) { Melder_throw (U"The Activation and the FFNet do not match.\nThe number of columns in the Activation must equal the number of outputs in the FFNet."); } if (p -> ny != a -> ny) { Melder_throw (U"The Pattern and the Activation do not match.\nThe number of rows in the Pattern must equal the number of rows in the Activation."); } if (! _Pattern_checkElements (p)) { Melder_throw (U"All Pattern elements must be in the interval [0, 1].\nYou could use \"Formula...\" to scale the Pattern values first."); } if (! _Activation_checkElements (a)) { Melder_throw (U"All Activation elements must be in the interval [0, 1].\nYou could use \"Formula...\" to scale the Activation values first."); } } static void _FFNet_Pattern_Activation_learn (FFNet me, Pattern pattern, Activation activation, long maxNumOfEpochs, double tolerance, Any parameters, int costFunctionType, int reset) { try { _FFNet_Pattern_Activation_checkDimensions (me, pattern, activation); Minimizer_setParameters (my minimizer, parameters); // Link the things to be learned my nPatterns = pattern -> ny; my inputPattern = pattern -> z; my targetActivation = activation -> z; FFNet_setCostFunction (me, costFunctionType); if (reset) { autoNUMvector wbuf (1, my dimension); long k = 1; for (long i = 1; i <= my nWeights; i++) { if (my wSelected[i]) { wbuf[k++] = my w[i]; } } Minimizer_reset (my minimizer, wbuf.peek()); } Minimizer_minimize (my minimizer, maxNumOfEpochs, tolerance, 1); // Unlink my nPatterns = 0; my inputPattern = nullptr; my targetActivation = nullptr; } catch (MelderError) { my nPatterns = 0; my inputPattern = nullptr; my targetActivation = nullptr; } } void FFNet_Pattern_Activation_learnSD (FFNet me, Pattern p, Activation a, long maxNumOfEpochs, double tolerance, Any parameters, int costFunctionType) { int resetMinimizer = 0; /* Did we choose another minimizer */ if (my minimizer && ! Thing_isa (my minimizer, classSteepestDescentMinimizer)) { forget (my minimizer); resetMinimizer = 1; } /* create the minimizer if it doesn't exist */ if (! my minimizer) { resetMinimizer = 1; my minimizer = (Minimizer) SteepestDescentMinimizer_create (my dimension, me, func, dfunc_optimized); } _FFNet_Pattern_Activation_learn (me, p, a, maxNumOfEpochs,tolerance, parameters, costFunctionType, resetMinimizer); } void FFNet_Pattern_Activation_learnSM (FFNet me, Pattern p, Activation a, long maxNumOfEpochs, double tolerance, Any parameters, int costFunctionType) { int resetMinimizer = 0; // Did we choose another minimizer if (my minimizer && ! Thing_isa (my minimizer, classVDSmagtMinimizer)) { forget (my minimizer); resetMinimizer = 1; } // create the minimizer if it doesn't exist if (! my minimizer) { resetMinimizer = 1; my minimizer = (Minimizer) VDSmagtMinimizer_create (my dimension, me, func, dfunc_optimized); } _FFNet_Pattern_Activation_learn (me, p, a, maxNumOfEpochs, tolerance, parameters, costFunctionType, resetMinimizer); } double FFNet_Pattern_Activation_getCosts_total (FFNet me, Pattern p, Activation a, int costFunctionType) { try { _FFNet_Pattern_Activation_checkDimensions (me, p, a); FFNet_setCostFunction (me, costFunctionType); double cost = 0.0; for (long i = 1; i <= p -> ny; i++) { FFNet_propagate (me, p -> z[i], nullptr); cost += FFNet_computeError (me, a -> z[i]); } return cost; } catch (MelderError) { return NUMundefined; } } double FFNet_Pattern_Activation_getCosts_average (FFNet me, Pattern p, Activation a, int costFunctionType) { double costs = FFNet_Pattern_Activation_getCosts_total (me, p, a, costFunctionType); return costs == NUMundefined ? NUMundefined : costs / p -> ny; } autoActivation FFNet_Pattern_to_Activation (FFNet me, Pattern p, long layer) { try { if (layer < 1 || layer > my nLayers) { layer = my nLayers; } if (my nInputs != p -> nx) { Melder_throw (U"The Pattern and the FFNet do not match. The number of colums in the Pattern (", p -> nx, U") should equal the number of inputs in the FFNet (", my nInputs, U")."); } if (! _Pattern_checkElements (p)) { Melder_throw (U"All Pattern elements must be in the interval [0, 1].\nYou could use \"Formula...\" to scale the Pattern values first."); } long nPatterns = p -> ny; autoActivation thee = Activation_create (nPatterns, my nUnitsInLayer[layer]); for (long i = 1; i <= nPatterns; i++) { FFNet_propagateToLayer (me, p -> z[i], thy z[i], layer); } return thee; } catch (MelderError) { Melder_throw (me, U": no Activation created."); } } /* End of file FFNet_Pattern_Activation.cpp */ praat-6.0.04/FFNet/FFNet_Pattern_Activation.h000066400000000000000000000035131261542461700206550ustar00rootroot00000000000000#ifndef _FFNet_Pattern_Activation_h_ #define _FFNet_Pattern_Activation_h_ /* FFNet_Pattern_Activation.h * * Copyright (C) 1994-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 1994. djmw 20020712 GPL header. djmw 20030701 Removed non-GPL minimizations. djmw 20110714 Latest modification. */ #include "FFNet.h" #include "Pattern.h" #include "Activation.h" #include "Minimizers.h" void FFNet_Pattern_Activation_learnSD (FFNet me, Pattern p, Activation a, long maxNumOfEpochs, double tolerance, Any parameters, int costFunctionType); /* Steepest Descent minimization */ void FFNet_Pattern_Activation_learnSM (FFNet me, Pattern p, Activation a, long maxNumOfEpochs, double tolerance, Any parameters, int costFunctionType); double FFNet_Pattern_Activation_getCosts_total (FFNet me, Pattern p, Activation a, int costFunctionType); double FFNet_Pattern_Activation_getCosts_average (FFNet me, Pattern p, Activation a, int costFunctionType); autoActivation FFNet_Pattern_to_Activation (FFNet me, Pattern p, long layer); /* Calculate the activations at a layer */ /* if (layer<1 || layer > my nLayers) layer = my nLayers; */ #endif /* _FFNet_Pattern_Activation_h_ */ praat-6.0.04/FFNet/FFNet_Pattern_Categories.cpp000066400000000000000000000105331261542461700211740ustar00rootroot00000000000000/* FFNet_Pattern_Categories.cpp * * Copyright (C) 1994-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020712 GPL header. djmw 20020910 changes. djmw 20030701 Removed non-GPL minimizations. djmw 20041118 Added FFNet_Pattern_Categories_getCosts. */ #include "FFNet_Activation_Categories.h" #include "FFNet_Pattern_Categories.h" #include "FFNet_Pattern_Activation.h" static void _FFNet_Pattern_Categories_checkDimensions (FFNet me, Pattern p, Categories c) { if (my nInputs != p -> nx) { Melder_throw (U"The Pattern and the FFNet do not match.\nThe number of colums in the Pattern must equal the number of inputs in the FFNet."); } if (p -> ny != c -> size) { Melder_throw (U"The Pattern and the categories do not match.\nThe number of rows in the Pattern must equal the number of categories."); } if (! _Pattern_checkElements (p)) { Melder_throw (U"All Pattern elements must be in the interval [0, 1].\nYou could use \"Formula...\" to scale the Pattern values first."); } } static void _FFNet_Pattern_Categories_learn (FFNet me, Pattern p, Categories c, long maxNumOfEpochs, double tolerance, Any parameters, int costFunctionType, void (*learn) (FFNet, Pattern, Activation, long, double, Any, int)) { _FFNet_Pattern_Categories_checkDimensions (me, p, c); autoActivation activation = FFNet_Categories_to_Activation (me, c); double min, max; Matrix_getWindowExtrema (p, 0, 0, 0, 0, &min, &max); learn (me, p, activation.peek(), maxNumOfEpochs, tolerance, parameters, costFunctionType); } double FFNet_Pattern_Categories_getCosts_total (FFNet me, Pattern p, Categories c, int costFunctionType) { try { _FFNet_Pattern_Categories_checkDimensions (me, p, c); autoActivation activation = FFNet_Categories_to_Activation (me, c); return FFNet_Pattern_Activation_getCosts_total (me, p, activation.peek(), costFunctionType); } catch (MelderError) { return NUMundefined; } } double FFNet_Pattern_Categories_getCosts_average (FFNet me, Pattern p, Categories c, int costFunctionType) { double costs = FFNet_Pattern_Categories_getCosts_total (me, p, c, costFunctionType); return costs == NUMundefined ? NUMundefined : costs / p -> ny; } void FFNet_Pattern_Categories_learnSM (FFNet me, Pattern p, Categories c, long maxNumOfEpochs, double tolerance, Any parameters, int costFunctionType) { _FFNet_Pattern_Categories_learn (me, p, c, maxNumOfEpochs, tolerance, parameters, costFunctionType, FFNet_Pattern_Activation_learnSM); } void FFNet_Pattern_Categories_learnSD (FFNet me, Pattern p, Categories c, long maxNumOfEpochs, double tolerance, Any parameters, int costFunctionType) { _FFNet_Pattern_Categories_learn (me, p, c, maxNumOfEpochs, tolerance, parameters, costFunctionType, FFNet_Pattern_Activation_learnSD); } autoCategories FFNet_Pattern_to_Categories (FFNet me, Pattern thee, int labeling) { try { if (! my outputCategories) { Melder_throw (U"The FFNet has no output categories."); } if (my nInputs != thy nx) { Melder_throw (U"The number of colums in the Pattern (", thy nx, U") should equal the number of inputs in the FFNet (", my nInputs, U")."); } if (! _Pattern_checkElements (thee)) { Melder_throw (U"All Pattern elements must be in the interval [0, 1].\nYou could use \"Formula...\" to scale the Pattern values first."); } autoCategories him = Categories_create (); for (long k = 1; k <= thy ny; k++) { FFNet_propagate (me, thy z[k], nullptr); long index = FFNet_getWinningUnit (me, labeling); autoDaata item = Data_copy ((Daata) my outputCategories -> item[index]); Collection_addItem (him.peek(), item.transfer()); } return him; } catch (MelderError) { Melder_throw (me, U": no Categories created."); } } /* End of file FFNet_Pattern_Categories.cpp */ praat-6.0.04/FFNet/FFNet_Pattern_Categories.h000066400000000000000000000035141261542461700206420ustar00rootroot00000000000000#ifndef _FFNet_Pattern_Categories_h_ #define _FFNet_Pattern_Categories_h_ /* FFNet_Pattern_Categories.h * * Copyright (C) 1994-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19960821 djmw 20020712 GPL header djmw 20110307 Latest mofification. */ #include "FFNet.h" #include "Pattern.h" #include "Categories.h" #include "Minimizers.h" void FFNet_Pattern_Categories_learnSD (FFNet me, Pattern p, Categories c, long maxNumOfEpochs, double tolerance, Any parameters, int costFunctionType); /* Steepest descent */ void FFNet_Pattern_Categories_learnSM (FFNet me, Pattern p, Categories c, long maxNumOfEpochs, double tolerance, Any parameters, int costFunctionType); /* Conj. Gradient vdSmagt */ double FFNet_Pattern_Categories_getCosts_total (FFNet me, Pattern p, Categories c, int costFunctionType); double FFNet_Pattern_Categories_getCosts_average (FFNet me, Pattern p, Categories c, int costFunctionType); autoCategories FFNet_Pattern_to_Categories (FFNet me, Pattern p, int labeling); /* classify the Pattern */ /* labeling = 1 : winner-takes-all */ /* labeling = 2 : stochastic */ /* Preconditions: I have labels */ #endif /* _FFNet_Pattern_Categories_h_ */ praat-6.0.04/FFNet/FFNet_def.h000066400000000000000000000052421261542461700156160ustar00rootroot00000000000000/* FFNet_def.h * * Copyright (C) 1994-2008 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19961104 djmw 20020712 GPL header djmw 20060529 Added version number to oo_Collection djmw 20080122 float -> double */ #define ooSTRUCT FFNet oo_DEFINE_CLASS (FFNet, Daata) oo_LONG (nLayers) /* number of layers */ oo_LONG_VECTOR_FROM (nUnitsInLayer, 0, nLayers) oo_INT (outputsAreLinear) oo_INT (nonLinearityType) oo_INT (costFunctionType) oo_AUTO_COLLECTION (Categories, outputCategories, SimpleString, 0) oo_LONG (nWeights) /* number of weights */ oo_DOUBLE_VECTOR (w, nWeights) #if ! oo_READING && ! oo_WRITING && ! oo_COMPARING oo_LONG (nNodes) oo_LONG (nInputs) oo_LONG (nOutputs) oo_LONG (dimension) #if oo_DECLARING double (*nonLinearity) (FFNet /* me */, double /* x */, double * /* deriv */); void *nlClosure; double (*costFunction) (FFNet /* me */, const double * /* target */); void *cfClosure; #endif #if oo_DECLARING oo_DOUBLE (accumulatedCost) oo_LONG (nPatterns) oo_LONG (currentPattern) double **inputPattern, **targetActivation; #endif #if oo_DECLARING || oo_DESTROYING oo_OBJECT (Minimizer, 0, minimizer) #endif oo_DOUBLE_VECTOR (activity, nNodes) oo_LONG_VECTOR (isbias, nNodes) oo_LONG_VECTOR (nodeFirst, nNodes) oo_LONG_VECTOR (nodeLast, nNodes) oo_LONG_VECTOR (wFirst, nNodes) oo_LONG_VECTOR (wLast, nNodes) oo_DOUBLE_VECTOR (deriv, nNodes) oo_DOUBLE_VECTOR (error, nNodes) oo_LONG_VECTOR (wSelected, nWeights) oo_DOUBLE_VECTOR (dw, nWeights) oo_DOUBLE_VECTOR (dwi, nWeights) #endif #if oo_READING bookkeeping (this); FFNet_setNonLinearity (this, nonLinearityType); FFNet_setCostFunction (this, costFunctionType); #endif #if oo_COPYING thy nonLinearity = nonLinearity; thy nlClosure = nlClosure; thy costFunction = costFunction; thy cfClosure = cfClosure; #endif #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (FFNet) #undef ooSTRUCT /* End of file FFNet_def.h */ praat-6.0.04/FFNet/Makefile000066400000000000000000000012121261542461700153160ustar00rootroot00000000000000# Makefile of the library "FFNet" # David Weenink, 22 February 2010 include ../makefile.defs CPPFLAGS = -I ../num -I ../dwtools -I ../fon -I ../sys -I ../dwsys -I ../stat OBJECTS = FFNet.o \ FFNet_Eigen.o FFNet_Matrix.o FFNet_Pattern.o \ FFNet_Activation_Categories.o FFNet_Pattern_Activation.o \ FFNet_Pattern_Categories.o \ praat_FFNet_init.o manual_FFNet.o .PHONY: all clean all: libFFNet.a clean: $(RM) $(OBJECTS) $(RM) libFFNet.a libFFNet.a: $(OBJECTS) touch libFFNet.a rm libFFNet.a $(AR) cq libFFNet.a $(OBJECTS) $(RANLIB) libFFNet.a $(OBJECTS): *.h ../num/NUM.h ../sys/*.h ../dwtools/*.h ../fon/*.h ../dwsys/*.h ../stat/*.h praat-6.0.04/FFNet/manual_FFNet.cpp000066400000000000000000000630221261542461700166700ustar00rootroot00000000000000/* manual_FFNet.c * * Copyright (C) 1994-2013 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020408 GPL */ #include "ManPagesM.h" #include "FFNet.h" static void drawFFNet_345 (Graphics g) { autoFFNet me = FFNet_create (3, 4, 0, 5, 0); FFNet_drawTopology (me.peek(), g); } void manual_FFNet_init (ManPages me); void manual_FFNet_init (ManPages me) { MAN_BEGIN (U"epoch", U"djmw", 20040428) INTRO (U"A term that is often used in the context of machine learning. An epoch is one complete " "presentation of the %%data set to be learned% to a learning machine.") NORMAL (U"Learning machines like @@FFNet|feedforward neural nets@ that use iterative algorithms " "often need many epochs during their learning phase.") NORMAL (U"A @@Discriminant|discriminant classifier@ is also a learning machine. " "However, in contrast with neural nets a discriminant classifier only needs one epoch to learn.") MAN_END MAN_BEGIN (U"Feedforward neural networks", U"djmw", 20040511) INTRO (U"This tutorial describes the use of @FFNet feedforward neural networks in P\\s{RAAT}. ") NORMAL (U"@@Feedforward neural networks 1. What is a feedforward neural network?|1. What is a feedforward neural network?@") LIST_ITEM (U" @@Feedforward neural networks 1.1. The learning phase|1.1 The learning phase") LIST_ITEM (U" @@Feedforward neural networks 1.2. The classification phase|1.2 The classification phase") NORMAL (U"@@Feedforward neural networks 2. Quick start|2. Quick start@") NORMAL (U"@@Feedforward neural networks 3. FFNet versus discriminant classifier|3. FFNet versus discriminant classifier@") NORMAL (U"@@Feedforward neural networks 4. Command overview|4. Command overview@") MAN_END MAN_BEGIN (U"Feedforward neural networks 1. What is a feedforward neural network?", U"djmw", 20040426) INTRO (U"A feedforward neural network is a biologically inspired classification algorithm. " "It consist of a (possibly large) number of simple neuron-like processing %units, organized in %layers. " "Every unit in a layer is connected with all the units in the previous layer. " "These connections are not all equal: each connection may have a different strength or %weight. " "The weights on these connections encode the knowledge of a network. " "Often the units in a neural network are also called %nodes.") NORMAL (U"Data enters at the inputs and passes through the network, layer by layer, until it arrives at the outputs. " "During normal operation, that is when it acts as a classifier, there is no feedback between layers. " "This is why they are called %%feedforward% neural networks. ") NORMAL (U"In the following figure we see an example of a 2-layered network with, from top to bottom: " "an output layer with 5 units, a %hidden layer with 4 units, respectively. The network has 3 input units.") PICTURE (5, 5, drawFFNet_345) NORMAL (U"The 3 inputs are shown as circles and these do not belong to any layer of the network (although the inputs " "sometimes are considered as a virtual layer with layer number 0). Any layer that is not an output layer is a " "%hidden layer. This network therefore has 1 hidden layer and 1 output layer. The figure also shows all the " "connections between the units in different layers. A layer only connects to the previous layer. ") NORMAL (U"The operation of this network can be divided into two phases:") NORMAL (U"@@Feedforward neural networks 1.1. The learning phase|1. The learning phase") NORMAL (U"@@Feedforward neural networks 1.2. The classification phase|2. The classification phase") MAN_END MAN_BEGIN (U"Feedforward neural networks 1.1. The learning phase", U"djmw", 20040428) INTRO (U"During the learning phase the weights in the FFNet will be modified. " "All weights are modified in such a way that when a pattern is presented, " "the output unit with the correct category, hopefully, will have the largest output value.") ENTRY (U"How does learning take place?") NORMAL (U"The FFNet uses a %supervised learning algorithm: besides the input pattern, " "the neural net also needs to know to what category the pattern belongs. " "Learning proceeds as follows: a pattern is presented at the inputs. " "The pattern will be transformed in its passage through the layers of the network until it " "reaches the output layer. The units in the output layer all belong to a different category. " "The outputs of the network as they are now are compared with the outputs as they ideally would " "have been if this pattern were correctly classified: in the latter case " "the unit with the correct category would have had the largest output value and the " "output values of the other output units would have been very small. " "On the basis of this comparison all the connection weights are modified a little bit to guarantee that, the next time " "this same pattern is presented at the inputs, the value of the output unit that corresponds with the correct category " "is a little bit higher than it is now and that, at the same time, the output values of all the other incorrect outputs are a " "little bit lower than they are now. (The differences between the actual outputs and the idealized outputs " "are propagated back from the top layer to lower layers to be used at these layers to modify connection weights. " "This is why the term %%backpropagation network% is also often used to describe this type of neural network.") NORMAL (U"If you perform the procedure above once for every pattern and category pair in your data " "set you have have performed 1 @epoch of learning.") NORMAL (U"The hope is that eventually, probably after many epochs, " "the neural net will remember these pattern-category pairs. " "You even hope that the neural net when the learning phase has terminated, will be able to %generalize " "and has learned to " "@@FFNet & Pattern: To Categories...|classify@ correctly any unknown pattern presented to it. ") NORMAL (U"Because real-life data many times contains noise as well as partly contradictory information " "these hopes can only be partly fulfilled. ") NORMAL (U"For @@FFNet & Pattern & Categories: Learn...|learning@ you " "need to select 3 different objects together: a FFNet (the %classifier), " "a Pattern (the %inputs) and a Categories (the %%correct outputs%).") ENTRY (U"How long will the learning phase take?") NORMAL (U"In general this question is hard to answer. It depends on the size of the neural network, " "the number of patterns to be learned, the number of epochs, the tolerance of the minimizer " "and the speed of your computer, how much computing time the learning phase may take. ") NORMAL (U"If computing time becomes excessive in your interactive environment then consider using the " "powerful @@Scripting|scripting@ facilities in P\\s{RAAT} to process your learning job as a batch job. ") MAN_END MAN_BEGIN (U"Feedforward neural networks 1.2. The classification phase", U"djmw", 20040428) INTRO (U"In the classification phase the weights of the network are fixed. ") NORMAL (U"A pattern, presented at the inputs, will be transformed from layer to layer until it reaches the output layer. " "Now classification can occur by selecting the category associated with the output unit that has " "the largest output value. " "For classification we only need to select an FFNet and a Pattern together and " "choose @@FFNet & Pattern: To Categories...|To Categories...@. ") NORMAL (U"In contrast to the @@Feedforward neural networks 1.1. The learning phase|learning phase@ classification is very fast.") MAN_END MAN_BEGIN (U"Feedforward neural networks 2. Quick start", U"djmw", 20040426) INTRO (U"You may create the iris example set with the @@Create iris example...@ command " "that you will find under the ##Neural nets# option in the #New menu. " "Three new objects will appear in the @@List of Objects@: a @FFNet, a @Categories and " "a @Pattern.") NORMAL (U"The #Pattern contains the @@iris data set@ in a 150 rows by 4 columns matrix. " "To guarantee that every cell in the Pattern is in the [0,1] interval, all measurement " "values were divided by 10. In the #Categories the three iris species %setosa, " "%versicolor, and %virginica were categorized with the numbers #1, #2 and #3, respectively. " "Because there are 4 data columns in the Pattern and 3 different iris species in the Categories, " "the newly created #FFNet has 4 inputs and 3 outputs. " "If you have entered a positive number in one of the fields in the form, the FFNet will have " "this number of units in a %%hidden layer%. The name of the newly created FFNet " "will reflect its topology. If you did opt for the default, 0 hidden units, the FFNet will be named 4-3.") ENTRY (U"Learning the iris data") NORMAL (U"The first thing you probably might want to do is to let the #FFNet learn the association in " "each pattern-category pair. To do this select all three objects together and choose " "@@FFNet & Pattern & Categories: Learn...|Learn...@. " "A form will appear, asking you to supply some settings for " "the learning algorithm. Learning starts after you have clicked the OK-button. " "Since the example network does not have too many weights that need to be adjusted and " "the learning data set is very small and computers nowadays are very fast, this will only take a " "very short time.") ENTRY (U"Classify") NORMAL (U"Now, if you are curious how well the FFNet has learned the iris data, you may select the " "#FFNet and the #Pattern together and choose @@FFNet & Pattern: To Categories...|To Categories...@. " "A new #Categories appears in the ##List of Objects# with the name %4-3_iris (if %%4-3% was the name of the FFNet and %iris% the name of the Pattern). " "We have two different Categories in the list of objects, the topmost one has the original categories, the other " "the categories as were assigned by the FFNet classifier. The obvious thing to do now is to compare the " "original categories with the assigned categories by making a @@Confusion|confusion table@. " "Select the two #Categories and choose @@Categories: To Confusion|To Confusion@ and a newly " "created @Confusion appears. Pressing the @Info button will show you an info window with, " "among others, the fraction correct. ") NORMAL (U"You might also want to " "@@Feedforward neural networks 3. FFNet versus discriminant classifier|compare the FFNet classifier with a discriminant classifier@.") ENTRY (U"Create other neural net topologies") NORMAL (U"With a #Pattern and a #Categories selected together, you can for example create a new #FFNet of a different topology.") MAN_END MAN_BEGIN (U"Feedforward neural networks 3. FFNet versus discriminant classifier", U"djmw", 20040426) NORMAL (U"You might want to compare the FFNet classifier with a discriminant classifier. " "Unlike the FFNet, a @@Discriminant|discriminant@ classifier does not need any iterative procedure in the " "learning phase and can be used immediately after creation for classification. " "The following three simple steps will give you the confusion matrix based on discriminant analysis:") LIST_ITEM (U"1. Select the Pattern and the Categories together and choose ##To Discriminant#. " "A newly created Discriminant will appear.") LIST_ITEM (U"2. Select the Discriminant and the Pattern together and choose ##To Categories...#. A newly created @Categories will appear.") LIST_ITEM (U"3. Select the two appropriate Categories and choose @@categories: To Confusion|To Confusion@. " "A newly created @Confusion will appear. After pushing the @Info button, the info window will " "show you the fraction correct.") NORMAL (U"See also the @@Discriminant analysis@ tutorial for more information.") MAN_END MAN_BEGIN (U"Feedforward neural networks 4. Command overview", U"djmw", 20040426) INTRO (U"FFNet commands") ENTRY (U"Creation:") LIST_ITEM (U"\\bu @@Pattern & Categories: To FFNet...@") LIST_ITEM (U"\\bu @@Create FFNet...@") ENTRY (U"Learning:") LIST_ITEM (U"\\bu @@FFNet & Pattern & Categories: Learn...@") LIST_ITEM (U"\\bu @@FFNet & Pattern & Categories: Learn slow...@") ENTRY (U"Classification:") LIST_ITEM (U"\\bu @@FFNet & Pattern: To Categories...@") ENTRY (U"Drawing:") LIST_ITEM (U"\\bu @@FFNet: Draw topology@") LIST_ITEM (U"\\bu @@FFNet: Draw weights...@") LIST_ITEM (U"\\bu @@FFNet: Draw cost history...@") ENTRY (U"Queries") LIST_ITEM (U"\\bu @@FFNet & Pattern & Categories: Get total costs...@") LIST_ITEM (U"\\bu @@FFNet & Pattern & Categories: Get average costs...@") LIST_ITEM (U"\\bu @@FFNet & Pattern & Activation: Get total costs...@") LIST_ITEM (U"\\bu @@FFNet & Pattern & Activation: Get average costs...@") ENTRY (U"Analysis:") LIST_ITEM (U"\\bu ##FFNet & Pattern: To Activation...#") ENTRY (U"Modification:") LIST_ITEM (U"\\bu @@FFNet: Reset...@") LIST_ITEM (U"\\bu ##FFNet: Select biases...#") LIST_ITEM (U"\\bu ##FFNet: Select all weights#") MAN_END MAN_BEGIN (U"FFNet", U"djmw", 19961015) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"A #FFNet models a feedforward neural net. A feedforward " "neural net can %learn associations between its %input and its %output. " "The @@Feedforward neural networks@ tutorial gives you an introduction to feedforward neural nets.") MAN_END MAN_BEGIN (U"FFNet: Draw topology", U"djmw", 19970218) INTRO (U"You can choose this command after selecting 1 or more @FFNet's.") ENTRY (U"Behaviour") NORMAL (U"Draws all units and all connections of a feedforward neural net.") MAN_END MAN_BEGIN (U"FFNet: Draw weights...", U"djmw", 20040422) INTRO (U"Draws the weights in a layer of the selected @FFNet feedforward neural net.") ENTRY (U"Settings") TAG (U"##Layer number") DEFINITION (U"determines the layer.") TAG (U"##Garnish") DEFINITION (U"determines whether additional information is drawn.") ENTRY (U"Behaviour") NORMAL (U"The weights are arranged in a matrix. The columns of this matrix are indexed by the units in the layer, " "while the rows are indexed by the units in the previous layer. There is one extra row for the biases." "The values of the weights are shown as rectangles. The area of a rectangle is proportional " "to the value. Negative values are shown as filled black rectangles.") MAN_END MAN_BEGIN (U"FFNet: Draw cost history...", U"djmw", 19970218) INTRO (U"You can choose this command after selecting 1 or more @FFNet's.") ENTRY (U"Settings") TAG (U"##Iteration range") DEFINITION (U"determines the horizontal range of the plot.") TAG (U"##Cost range") DEFINITION (U"determines the vertical range of the plot.") TAG (U"##Garnish") DEFINITION (U"determines whether a box and axis labels are drawn.") ENTRY (U"Behaviour") NORMAL (U"Draws the history of the cost versus iteration number during previous learning.") MAN_END MAN_BEGIN (U"FFNet: Extract weights...", U"djmw", 20040422) INTRO (U"Extract all the weights, from all the units in the specified layer of the selected " "@FFNet, to a @TableOfReal.") ENTRY (U"Settings") TAG (U"##Layer number") DEFINITION (U"determines the layer.") ENTRY (U"Behaviour") NORMAL (U"The weights will be arranged in the TableOfReal as follows: ") NORMAL (U"The table columns will be indexed by the unit numbers in the selected layer, " "while the rows will be indexed by the unit numbers from the previous layer. " "There will be one extra row to accommodate the bias weights. " "The rows and columns are labelled with layer number and unit number as \"L%i-%j\", where %i is the layer number and " "%j the unit number from that layer. The layer number for the rows is one less than the layer number in the columns. " "The last row is labelled as \"Bias\".") MAN_END MAN_BEGIN (U"FFNet: Get number of outputs", U"djmw", 20040420) INTRO (U"Queries the selected @FFNet for the number of output units in the output layer. ") MAN_END MAN_BEGIN (U"FFNet: Get number of inputs", U"djmw", 20040420) INTRO (U"Queries the selected @FFNet for the number of inputs. ") NORMAL (U"For a network with only one layer, the inputs are connected directly to the output layer. " "In a two-layer network the inputs are connected to a hidden layer.") MAN_END MAN_BEGIN (U"FFNet: Get number of hidden units...", U"djmw", 20040420) INTRO (U"Queries the selected @FFNet for the number of units in a hidden layer.") ENTRY (U"Settings") TAG (U"##Hidden layer number") DEFINITION (U"determines the layer that is queried.") ENTRY (U"Layer numbering") NORMAL (U"The number of hidden layers is always one less than the total number of layers in a FFNet. " "A network with the output units connected to the inputs therefore has only 1 layer, the output layer and " "no hidden layers. ") MAN_END MAN_BEGIN (U"FFNet: Get number of hidden weights...", U"djmw", 20040420) INTRO (U"Queries the selected @FFNet for the number of weights in a hidden layer.") ENTRY (U"Settings") TAG (U"##Hidden layer number") DEFINITION (U"determines the layer that is queried.") MAN_END MAN_BEGIN (U"FFNet: Reset...", U"djmw", 20040420) INTRO (U"You can choose this command after selecting 1 or more @FFNet's.") ENTRY (U"WARNING") NORMAL (U"This command destroys all previous learning.") ENTRY (U"Settings") TAG (U"##Range") DEFINITION (U"determines the upper limit of the [-%range, +%range] interval from " "which new weights will be randomly selected.") ENTRY (U"Behaviour") NORMAL (U"All (selected) weights are reset to random numbers uniformly drawn from the interval [-%range, +%range]. " "This command also clears the cost history.") MAN_END MAN_BEGIN (U"FFNet: Select biases...", U"djmw", 20040422) INTRO (U"Selects only the biases in one particular layer as subject for modification during learning of the @FFNet.") ENTRY (U"Settings") TAG (U"##Layer number") DEFINITION (U"determines the layer whose biases will be modified.") ENTRY (U"Behaviour") NORMAL (U"This command induces very specific behaviour during a following learning phase. " "Instead of all the weights, only the biases in the specified layer will be changed during learning and the " "rest of the weights stay fixed. ") MAN_END #define FFNet_Create_COMMON_HELP_INOUT \ ENTRY (U"Settings")\ TAG (U"##Number of inputs")\ DEFINITION (U"the dimension of the input of the neural net.")\ TAG (U"##Number of outputs (\\>_ 1)#")\ DEFINITION (U"the number of different categories that you want the net to learn.") #define FFNet_Create_COMMON_HELP_HIDDEN \ TAG (U"##Number of units in hidden layer 1#, ##Number of units in hidden layer 2#") \ DEFINITION (U"determine the number of units in the hidden layers. " \ "If you want a neural net with no hidden layers, both numbers have to be 0. "\ "If you want a neural net with only 1 hidden layer then one of these numbers has to differ from 0. ") MAN_BEGIN (U"Create FFNet...", U"djmw", 20040420) INTRO (U"Create a new feedforward neural net of type @FFNet.") FFNet_Create_COMMON_HELP_INOUT FFNet_Create_COMMON_HELP_HIDDEN MAN_END MAN_BEGIN (U"Create FFNet (linear outputs)...", U"djmw", 20040422) INTRO (U"Create a @FFNet feedforward neural network whose output units are linear.") FFNet_Create_COMMON_HELP_INOUT FFNet_Create_COMMON_HELP_HIDDEN MAN_END MAN_BEGIN (U"Create iris example...", U"djmw", 20040423) INTRO (U"A @FFNet feedforward neural net will be created together with two other objects: " "a @Pattern and a @Categories. The Pattern will contain the observations in the @@iris data set@, " "and the Categories will contain the 3 different iris species categorized by numbers.") ENTRY (U"Settings") FFNet_Create_COMMON_HELP_HIDDEN NORMAL (U"For this simple data you can leave both hidden layers empty.") MAN_END MAN_BEGIN (U"iris data set", U"djmw", 19961015) NORMAL (U"A data set with 150 random samples of flowers from the iris species %setosa, " "%versicolor, and %virginica collected by @@Anderson (1935)@. From each species there are 50 observations for " "sepal length, sepal width, petal length, and petal width in cm. This dataset was " "used by @@Fisher (1936)@ in his initiation of the linear-discriminant-function technique.") MAN_END MAN_BEGIN (U"FFNet: Pattern", U"djmw", 19960918) INTRO (U"A @Pattern is a @Matrix in which each row forms one input pattern (vector) for the neural net.") NORMAL (U"The number of columns is the dimensionality of the input. " "The number of rows is the number of patterns.") MAN_END MAN_BEGIN (U"FFNet: Categories", U"djmw", 19960918) INTRO (U"The categories for training a neural net with a @Pattern. ") ENTRY (U"Preconditions") NORMAL (U"The number of categories in a @Categories must equal the number of rows in #Pattern.") MAN_END MAN_BEGIN (U"Activation", U"djmw", 20041118) INTRO (U"A @Matrix whose elements must be >= 0 and <= 1. " "Classification: the response of a particular layer in a neural net to a @Pattern." "Learning: the desired response of the output layer in a neural net to a @Pattern.") MAN_END MAN_BEGIN (U"FFNet: Principal components", U"djmw", 19960918) INTRO (U"When you select @FFNet and @Eigen the decision planes of layer 1 are drawn in the PC-plane.\n") MAN_END MAN_BEGIN (U"FFNet & Pattern: To Categories...", U"djmw", 19960918) INTRO (U"The @FFNet is used as a classifier. Each pattern from the @Pattern will be " "classified into one of the FFNet's categories.") MAN_END MAN_BEGIN (U"Pattern & Categories: To FFNet...", U"djmw", 20040422) INTRO (U"Create a new @FFNet feedforward neural network. " "The number of inputs of the newly created FFNet will be equal to the number of " "columns in the @Pattern and the number of outputs " "will be equal to the number of unique categories in the @Categories.") ENTRY (U"Settings") FFNet_Create_COMMON_HELP_HIDDEN MAN_END MAN_BEGIN (U"FFNet & Pattern & Categories: Learn slow...", U"djmw", 19960918) INTRO (U"To learn an association you have to select a @FFNet, a @Pattern and a @Categories object.") ENTRY (U"Preconditions") LIST_ITEM (U"The number of columns in a #Pattern must equal the number of input units of #FFNet.") ENTRY (U" Algorithm") NORMAL (U"Steepest descent") ENTRY (U"Preconditions") LIST_ITEM (U"The number of rows in a #Pattern must equal the number of categories in a #Categories.") LIST_ITEM (U"The number of unique categories in a #Categories must equal the number of output units in #FFNet.") MAN_END MAN_BEGIN (U"FFNet & Pattern & Categories: Learn...", U"djmw", 20040511) INTRO (U"You can choose this command after selecting one @Pattern, one @Categories and one @FFNet.") ENTRY (U"Settings") TAG (U"##Maximum number of epochs") DEFINITION (U"the maximum number of times that the complete #Pattern dataset will be presented to the neural net.") TAG (U"##Tolerance of minimizer") DEFINITION (U"when the difference in costs between two successive learning cycles is " "smaller than this value, the minimization process will be stopped.") NORMAL (U"##Cost function") LIST_ITEM (U"Minimum-squared-error:") LIST_ITEM (U" %costs = \\su__%allPatterns_ \\su__%allOutputs_ (%o__%k_ - d__%k_)^2, where") LIST_ITEM (U" %o__%k_ : actual output of unit %k") LIST_ITEM (U" %d__%k_ : desired output of unit %k") LIST_ITEM (U"Minimum-cross-entropy:") LIST_ITEM (U" %costs = - \\su__%allPatterns_ \\su__%allOutputs_ (%d__%k_ \\.c ln %o__%k_ + (1-%d__%k_) \\.c ln (1-%o__%k_))") ENTRY (U"Algorithm") NORMAL (U"The minimization procedure is a variant of conjugate gradient minimization, " "see for example @@Press et al. (1992)@, chapter 10, or @@Nocedal & Wright (1999)@, chapter 5.") MAN_END MAN_BEGIN (U"FFNet & Pattern & Categories: Get total costs...", U"djmw", 20041118) INTRO (U"Query the selected @FFNet, @Pattern and @Categories for the total costs.") ENTRY (U"Algorithm") NORMAL (U"All patterns are propagated and the total costs are calculated as is shown in @@FFNet & Pattern & Categories: Learn...@. ") MAN_END MAN_BEGIN (U"FFNet & Pattern & Activation: Get total costs...", U"djmw", 20041118) INTRO (U"Query the selected @FFNet, @Pattern and @Activation for the total costs.") ENTRY (U"Algorithm") NORMAL (U"All patterns are propagated and the total costs are calculated as is shown in @@FFNet & Pattern & Categories: Learn...@. ") MAN_END MAN_BEGIN (U"FFNet & Pattern & Categories: Get average costs...", U"djmw", 20041118) INTRO (U"Query the selected @FFNet, @Pattern and @Categories for the average costs.") ENTRY (U"Algorithm") NORMAL (U"All patterns are propagated and the total costs are calculated as is shown in @@FFNet & Pattern & Categories: Learn...@. " "These total costs are then divided by the number of patterns.") MAN_END MAN_BEGIN (U"FFNet & Pattern & Activation: Get average costs...", U"djmw", 20041118) INTRO (U"Query the selected @FFNet, @Pattern and @Activation for the average costs.") ENTRY (U"Algorithm") NORMAL (U"All patterns are propagated and the total costs are calculated as is shown in @@FFNet & Pattern & Categories: Learn...@. " "These total costs are then divided by the number of patterns.") MAN_END MAN_BEGIN (U"Anderson (1935)", U"djmw", 20040423) NORMAL (U"E. Anderson (1935): \"The irises of the Gasp\\e' peninsula.\" " "%%Bulletin of the American Iris Society% #59: 2\\--5.") MAN_END MAN_BEGIN (U"Fisher (1936)", U"djmw", 19980114) NORMAL (U"R.A. Fisher (1936): \"The use of multiple measurements in taxonomic " "problems.\" %%Annals of Eugenics% #7: 179\\--188.") MAN_END MAN_BEGIN (U"Nocedal & Wright (1999)", U"djmw", 20040511) NORMAL (U"J. Nocedal & S.J. Wright (1999): %%Numerical optimization.% Springer.") MAN_END } /* End of file manual_FFNet.c */ praat-6.0.04/FFNet/praat_FFNet_init.cpp000066400000000000000000000704471261542461700175560ustar00rootroot00000000000000/* praat_FFNet_init.cpp * * Copyright (C) 1994-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020408 GPL djmw 20020408 added FFNet_help djmw 20030701 Removed non-GPL minimizations djmw 20040526 Removed bug in FFNet_drawCostHistory interface. djmw 20041123 Latest modification djmw 20061218 Changed to Melder_information format. djmw 20080902 Melder_error<1...> djmw 20071011 REQUIRE requires U"". djmw 20071024 Use MelderString_append in FFNet_createNameFromTopology djmw 20100511 FFNet query outputs */ #include #include "praat.h" #include "Discriminant.h" #include "PCA.h" #include "Minimizers.h" #include "FFNet_Eigen.h" #include "FFNet_Matrix.h" #include "FFNet_Pattern.h" #include "FFNet_Activation_Categories.h" #include "FFNet_Pattern_Activation.h" #include "FFNet_Pattern_Categories.h" /* Routines to be removed sometime in the future: 20040422, 2.4.04: FFNet_drawWeightsToLayer use FFNet_drawWeights 20040422, 2.4.04: FFNet_weightsToMatrix use FFNet_extractWeights */ #undef iam #define iam iam_LOOP static char32 const *QUERY_BUTTON = U"Query -"; static char32 const *DRAW_BUTTON = U"Draw -"; static char32 const *MODIFY_BUTTON = U"Modify -"; static char32 const *EXTRACT_BUTTON = U"Extract -"; /**************** New FFNet ***************************/ static void FFNet_create_addCommonFields_inputOutput (UiForm dia) { NATURAL (U"Number of inputs", U"4") NATURAL (U"Number of outputs", U"3") } static void FFNet_create_checkCommonFields_inputOutput (UiForm dia, long *numberOfInputs, long *numberOfOutputs) { *numberOfInputs = GET_INTEGER (U"Number of inputs"); *numberOfOutputs = GET_INTEGER (U"Number of outputs"); } static void FFNet_create_addCommonFields_hidden (UiForm dia) { INTEGER (U"Number of units in hidden layer 1", U"0") INTEGER (U"Number of units in hidden layer 2", U"0") } static void FFNet_create_checkCommonFields_hidden (UiForm dia, long *numberOfHidden1, long *numberOfHidden2) { *numberOfHidden1 = GET_INTEGER (U"Number of units in hidden layer 1"); *numberOfHidden2 = GET_INTEGER (U"Number of units in hidden layer 2"); if (*numberOfHidden1 < 0 || *numberOfHidden2 < 0) { Melder_throw (U"The number of units in a hidden layer must be geater equal zero"); } } static void FFNet_create_addCommonFields (UiForm dia) { FFNet_create_addCommonFields_inputOutput (dia); FFNet_create_addCommonFields_hidden (dia); } static void FFNet_create_checkCommonFields (UiForm dia, long *numberOfInputs, long *numberOfOutputs, long *numberOfHidden1, long *numberOfHidden2) { FFNet_create_checkCommonFields_inputOutput (dia, numberOfInputs, numberOfOutputs); FFNet_create_checkCommonFields_hidden (dia, numberOfHidden1, numberOfHidden2); } FORM (FFNet_create, U"Create FFNet", U"Create FFNet...") WORD (U"Name", U"4-3") FFNet_create_addCommonFields (dia); OK DO long numberOfInputs, numberOfOutputs, numberOfHidden1, numberOfHidden2; FFNet_create_checkCommonFields (dia, &numberOfInputs, &numberOfOutputs, &numberOfHidden1, &numberOfHidden2); autoFFNet thee = FFNet_create (numberOfInputs, numberOfHidden1, numberOfHidden2, numberOfOutputs, 0); praat_new (thee.transfer(), GET_STRING (U"Name")); END FORM (FFNet_create_linearOutputs, U"Create FFNet", U"Create FFNet (linear outputs)...") WORD (U"Name", U"4-3L") FFNet_create_addCommonFields (dia); OK DO long numberOfInputs, numberOfOutputs, numberOfHidden1, numberOfHidden2; FFNet_create_checkCommonFields (dia, &numberOfInputs, &numberOfOutputs, &numberOfHidden1, &numberOfHidden2); autoFFNet thee = FFNet_create (numberOfInputs, numberOfHidden1, numberOfHidden2, numberOfOutputs, 1); praat_new (thee.transfer(), GET_STRING (U"Name")); END FORM (FFNet_createIrisExample, U"Create iris example", U"Create iris example...") LABEL (U"", U"For the feedforward neural net we need to know the:") FFNet_create_addCommonFields_hidden (dia); OK DO long numberOfHidden1, numberOfHidden2; FFNet_create_checkCommonFields_hidden (dia, &numberOfHidden1, &numberOfHidden2); autoCollection thee = FFNet_createIrisExample (numberOfHidden1, numberOfHidden2); praat_new (thee.transfer()); END DIRECT (FFNet_getNumberOfInputs) LOOP { iam (FFNet); Melder_information (my nUnitsInLayer[0], U" units"); } END DIRECT (FFNet_getNumberOfOutputs) LOOP { iam (FFNet); Melder_information (my nUnitsInLayer[my nLayers], U" units"); } END FORM (FFNet_getNumberOfHiddenUnits, U"FFNet: Get number of hidden units", U"FFNet: Get number of hidden units...") NATURAL (U"Hidden layer number", U"1") OK DO LOOP { iam (FFNet); long layerNumber = GET_INTEGER (U"Hidden layer number"); long numberOfUnits = 0; if (layerNumber > 0 && layerNumber <= my nLayers - 1) { numberOfUnits = my nUnitsInLayer[layerNumber]; } Melder_information (numberOfUnits, U" units"); } END FORM (FFNet_getCategoryOfOutputUnit, U"FFNet: Get category of output unit", U"") NATURAL (U"Output unit", U"1") OK DO LOOP { iam (FFNet); long unit = GET_INTEGER (U"Output unit"); if (unit > my outputCategories -> size) { Melder_throw (U"Output unit cannot be larger than ", my outputCategories -> size, U"."); } SimpleString ss = (SimpleString) my outputCategories -> item[unit]; Melder_information (ss -> string); } END FORM (FFNet_getOutputUnitOfCategory, U"FFNet: Get output unit of category", U"") SENTENCE (U"Category", U"u") OK DO LOOP { iam (FFNet); char32 *category = GET_STRING (U"Category"); long index = 0; for (long i = 1; i <= my outputCategories -> size; i++) { SimpleString s = (SimpleString) my outputCategories -> item[i]; if (Melder_equ (s -> string, category)) { index = i; break; } } Melder_information (index); } END FORM (FFNet_getBias, U"FFNet: Get bias", 0) NATURAL (U"Layer", U"1") NATURAL (U"Unit", U"1") OK DO LOOP { iam (FFNet); long layer = GET_INTEGER (U"Layer"); long unit = GET_INTEGER (U"Unit"); double bias = FFNet_getBias (me, layer, unit); Melder_information (bias, U"(bias for unit ", unit, U"in layer ", layer, U")."); } END FORM (FFNet_setBias, U"FFNet: Set bias", 0) NATURAL (U"Layer", U"1") NATURAL (U"Unit", U"1") REAL (U"Value", U"0.0") OK DO LOOP { iam (FFNet); FFNet_setBias (me, GET_INTEGER (U"Layer"), GET_INTEGER (U"Unit"), GET_REAL (U"Value")); } END FORM (FFNet_getWeight, U"FFNet: Get weight", 0) NATURAL (U"Layer", U"1") NATURAL (U"Unit", U"1") NATURAL (U"Unit from", U"1") OK DO LOOP { iam (FFNet); long layer = GET_INTEGER (U"Layer"); long unit = GET_INTEGER (U"Unit"); long unitf = GET_INTEGER (U"Unit from"); double w = FFNet_getWeight (me, layer, unit, unitf); Melder_information (w, U"(weight between unit ", unit, U" in layer ", layer, U", and unit ", unitf, U"in layer ", layer - 1); } END FORM (FFNet_setWeight, U"FFNet: Set weight", 0) NATURAL (U"Layer", U"1") NATURAL (U"Unit", U"1") NATURAL (U"Unit (from)", U"1") REAL (U"Value", U"0.0") OK DO LOOP { iam (FFNet); long layer = GET_INTEGER (U"Layer"); long unit = GET_INTEGER (U"Unit"); long unitf = GET_INTEGER (U"Unit (from)"); FFNet_setWeight (me, layer, unit, unitf, GET_REAL (U"Value")); } END FORM (FFNet_getNumberOfHiddenWeights, U"FFNet: Get number of hidden weights", U"FFNet: Get number of hidden weights...") NATURAL (U"Hidden layer number", U"1") OK DO LOOP { iam (FFNet); long layerNumber = GET_INTEGER (U"Hidden layer number"); long numberOfWeights = 0; if (layerNumber > 0 && layerNumber <= my nLayers - 1) { numberOfWeights = my nUnitsInLayer[layerNumber] * (my nUnitsInLayer[layerNumber - 1] + 1); } Melder_information (numberOfWeights, U" weights (including biases)"); } END DIRECT (FFNet_getNumberOfOutputWeights) LOOP { iam (FFNet); Melder_information (my nUnitsInLayer[my nLayers] * (my nUnitsInLayer[my nLayers - 1] + 1), U" weights"); } END /**************** New Pattern ***************************/ FORM (Pattern_create, U"Create Pattern", 0) WORD (U"Name", U"1x1") NATURAL (U"Dimension of a pattern", U"1") NATURAL (U"Number of patterns", U"1") OK DO praat_new (Pattern_create (GET_INTEGER (U"Number of patterns"), GET_INTEGER (U"Dimension of a pattern")), GET_STRING (U"Name")); END /**************** New Categories ***************************/ FORM (Categories_create, U"Create Categories", U"") WORD (U"Name", U"empty") OK DO autoCategories thee = Categories_create (); praat_new (thee.transfer(), GET_STRING (U"Name")); END DIRECT (FFNet_help) Melder_help (U"Feedforward neural networks"); END DIRECT (FFNet_getMinimum) LOOP { iam (FFNet); Melder_information (FFNet_getMinimum (me)); } END FORM (FFNet_reset, U"FFNet: Reset", U"FFNet: Reset...") LABEL (U"", U"Warning: this command destroys all previous learning.") LABEL (U"", U"New weights will be randomly chosen from the interval [-range, +range].") POSITIVE (U"Range", U"0.1") OK DO LOOP { iam (FFNet); FFNet_reset (me, GET_REAL (U"Range")); praat_dataChanged (OBJECT); } END FORM (FFNet_selectBiasesInLayer, U"FFNet: Select biases", U"FFNet: Select biases...") LABEL (U"", U"WARNING: This command induces very specific behaviour ") LABEL (U"", U"during a following learning phase.") NATURAL (U"Layer number", U"1") OK DO LOOP { iam (FFNet); FFNet_selectBiasesInLayer (me, GET_INTEGER (U"Layer number")); praat_dataChanged (OBJECT); } END DIRECT (FFNet_selectAllWeights) LOOP { iam (FFNet); FFNet_selectAllWeights (me); praat_dataChanged (me); } END DIRECT (FFNet_drawTopology) autoPraatPicture picture; LOOP { iam (FFNet); FFNet_drawTopology (me, GRAPHICS); } END FORM (FFNet_drawWeightsToLayer, U"FFNet: Draw weights to layer", 0) LABEL (U"", U"Warning: Disapproved. Use \"Draw weights..\" instead.") NATURAL (U"Layer number", U"1") RADIO (U"Scale", 1) RADIOBUTTON (U"by maximum of all weights to layer") RADIOBUTTON (U"by maximum weight from 'from-unit'") RADIOBUTTON (U"by maximum weight to 'to-unit'") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (FFNet); FFNet_drawWeightsToLayer (me, GRAPHICS, GET_INTEGER (U"Layer number"), GET_INTEGER (U"Scale"), GET_INTEGER (U"Garnish")); } END FORM (FFNet_drawWeights, U"FFNet: Draw weights", U"FFNet: Draw weights...") NATURAL (U"Layer number", U"1") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (FFNet); FFNet_drawWeights (me, GRAPHICS, GET_INTEGER (U"Layer number"), GET_INTEGER (U"Garnish")); } END FORM (FFNet_drawCostHistory, U"FFNet: Draw cost history", U"FFNet: Draw cost history...") INTEGER (U"left Iteration_range", U"0") INTEGER (U"right Iteration_range", U"0") REAL (U"left Cost_range", U"0.0") REAL (U"right Cost_range", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (FFNet); FFNet_drawCostHistory (me, GRAPHICS, GET_INTEGER (U"left Iteration_range"), GET_INTEGER (U"right Iteration_range"), GET_REAL (U"left Cost_range"), GET_REAL (U"right Cost_range"), GET_INTEGER (U"Garnish")); } END FORM (FFNet_extractWeights, U"FFNet: Extract weights", U"FFNet: Extract weights...") NATURAL (U"Layer number", U"1") OK DO LOOP { iam (FFNet); autoTableOfReal thee = FFNet_extractWeights (me, GET_INTEGER (U"Layer number")); praat_new (thee.transfer()); } END FORM (FFNet_weightsToMatrix, U"FFNet: Weights to Matrix ", 0) LABEL (U"", U"Warning: Use \"Extract weights..\" instead.") NATURAL (U"Layer number", U"1") OK DO LOOP { iam (FFNet); autoMatrix thee = FFNet_weightsToMatrix (me, GET_INTEGER (U"Layer number"), 0); praat_new (thee.transfer(), my name); } END /******************* FFNet && Activation *************************************/ FORM (FFNet_Activation_to_Categories, U"FFNet & Activation: To Categories", 0) RADIO (U"Kind of labeling", 1) RADIOBUTTON (U"Winner-takes-all") RADIOBUTTON (U"Stochastic") OK DO FFNet me = FIRST (FFNet); Activation thee = FIRST (Activation); autoCategories him = FFNet_Activation_to_Categories (me, thee, GET_INTEGER (U"Kind of labeling")); praat_new (him.transfer(), my name, U"_", thy name); END /******************* FFNet && Eigen ******************************************/ FORM (FFNet_Eigen_drawIntersection, U"FFnet & Eigen: Draw intersection", 0) INTEGER (U"X-component", U"1") INTEGER (U"Y-component", U"2") REAL (U"xmin", U"0.0") REAL (U"xmax", U"0.0") REAL (U"ymin", U"0.0") REAL (U"ymax", U"0.0") OK DO FFNet me = FIRST (FFNet); Eigen thee = FIRST (Eigen); autoPraatPicture picture; long pcx = GET_INTEGER (U"X-component"); long pcy = GET_INTEGER (U"Y-component"); REQUIRE (pcx != 0 && pcy != 0, U"X and Y component must differ from 0.") FFNet_Eigen_drawIntersection (me, thee, GRAPHICS, pcx, pcy, GET_REAL (U"xmin"), GET_REAL (U"xmax"), GET_REAL (U"ymin"), GET_REAL (U"ymax")); END FORM (FFNet_PCA_drawDecisionPlaneInEigenspace, U"FFNet & PCA: Draw decision plane", U"") NATURAL (U"Unit number", U"1") NATURAL (U"Layer number", U"1") NATURAL (U"Horizontal eigenvector number", U"1") NATURAL (U"Vertical eigenvector number", U"2") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") OK DO autoPraatPicture picture; FFNet me = FIRST (FFNet); PCA thee = FIRST (PCA); FFNet_Eigen_drawDecisionPlaneInEigenspace (me, thee, GRAPHICS, GET_INTEGER (U"Unit number"), GET_INTEGER (U"Layer number"), GET_INTEGER (U"Horizontal eigenvector number"), GET_INTEGER (U"Vertical eigenvector number"), GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range")); END /************************* FFNet && Categories **********************************/ DIRECT (FFNet_Categories_to_Activation) FFNet me = FIRST (FFNet); Categories thee = FIRST (Categories); autoActivation him = FFNet_Categories_to_Activation (me, thee); praat_new (him.transfer(), my name); END /************************* FFNet && Matrix **********************************/ FORM (FFNet_weightsFromMatrix, U"Replace weights by values from Matrix", 0) NATURAL (U"Layer", U"1") OK DO FFNet me = FIRST (FFNet); Matrix thee = FIRST (Matrix); autoFFNet him = FFNet_weightsFromMatrix (me, thee, GET_INTEGER (U"Layer")); praat_new (him.transfer(), my name); END /************************* FFNet && Pattern **********************************/ FORM (FFNet_Pattern_drawActivation, U"Draw an activation", 0) NATURAL (U"Pattern (row) number", U"1"); OK DO autoPraatPicture picture; FFNet me = FIRST (FFNet); Pattern thee = FIRST (Pattern); FFNet_Pattern_drawActivation (me, thee, GRAPHICS, GET_INTEGER (U"Pattern")); END FORM (FFNet_Pattern_to_Activation, U"To activations in layer", 0) NATURAL (U"Layer", U"1") OK DO FFNet me = FIRST (FFNet); Pattern thee = FIRST (Pattern); autoActivation him = FFNet_Pattern_to_Activation (me, thee, GET_INTEGER (U"Layer")); praat_new (him.transfer(), my name, U"_", thy name); END DIRECT (hint_FFNet_and_Pattern_classify) Melder_information (U"You can use the FFNet as a classifier by selecting a\n" "FFNet and a Pattern together and choosing \"To Categories...\"."); END DIRECT (hint_FFNet_and_Pattern_and_Categories_learn) Melder_information (U"You can teach a FFNet to classify by selecting a\n" "FFNet, a Pattern and a Categories together and choosing \"Learn...\"."); END FORM (FFNet_Pattern_to_Categories, U"FFNet & Pattern: To Categories", U"FFNet & Pattern: To Categories...") RADIO (U"Determine output category as", 1) RADIOBUTTON (U"Winner-takes-all") RADIOBUTTON (U"Stochastic") OK DO FFNet me = FIRST (FFNet); Pattern thee = FIRST (Pattern); autoCategories him = FFNet_Pattern_to_Categories (me, thee, GET_INTEGER (U"Determine output category as")); praat_new (him.transfer(), my name, U"_", thy name); END /*********** FFNet Pattern Activation **********************************/ FORM (FFNet_Pattern_Activation_getCosts_total, U"FFNet & Pattern & Activation: Get total costs", U"FFNet & Pattern & Activation: Get total costs...") RADIO (U"Cost function", 1) RADIOBUTTON (U"Minimum-squared-error") RADIOBUTTON (U"Minimum-cross-entropy") OK DO FFNet me = FIRST (FFNet); Pattern thee = FIRST (Pattern); Activation him = FIRST (Activation); Melder_information (FFNet_Pattern_Activation_getCosts_total (me, thee, him, GET_INTEGER (U"Cost function"))); END FORM (FFNet_Pattern_Activation_getCosts_average, U"FFNet & Pattern & Activation: Get average costs", U"FFNet & Pattern & Activation: Get average costs...") RADIO (U"Cost function", 1) RADIOBUTTON (U"Minimum-squared-error") RADIOBUTTON (U"Minimum-cross-entropy") OK DO FFNet me = FIRST (FFNet); Pattern thee = FIRST (Pattern); Activation him = FIRST (Activation); Melder_information (FFNet_Pattern_Activation_getCosts_average (me, thee, him, GET_INTEGER (U"Cost function"))); END FORM (FFNet_Pattern_Activation_learnSD, U"FFNet & Pattern & Activation: Learn slow", 0) NATURAL (U"Maximum number of epochs", U"100") POSITIVE (U"Tolerance of minimizer", U"1e-7") LABEL (U"Specifics", U"Specific for this minimization") POSITIVE (U"Learning rate", U"0.1") REAL (U"Momentum", U"0.9") RADIO (U"Cost function", 1) RADIOBUTTON (U"Minimum-squared-error") RADIOBUTTON (U"Minimum-cross-entropy") OK DO FFNet me = FIRST (FFNet); Pattern thee = FIRST (Pattern); Activation him = FIRST (Activation); struct structSteepestDescentMinimizer_parameters p; p.eta = GET_REAL (U"Learning rate"); p.momentum = GET_REAL (U"Momentum"); return FFNet_Pattern_Activation_learnSD (me, thee, him, GET_INTEGER (U"Maximum number of epochs"), GET_REAL (U"Tolerance of minimizer"), & p, GET_INTEGER (U"Cost function")); END FORM (FFNet_Pattern_Activation_learnSM, U"FFNet & Pattern & Activation: Learn", 0) NATURAL (U"Maximum number of epochs", U"100") POSITIVE (U"Tolerance of minimizer", U"1e-7") RADIO (U"Cost function", 1) RADIOBUTTON (U"Minimum-squared-error") RADIOBUTTON (U"Minimum-cross-entropy") OK DO FFNet me = FIRST (FFNet); Pattern thee = FIRST (Pattern); Activation him = FIRST (Activation); return FFNet_Pattern_Activation_learnSM (me, thee, him, GET_INTEGER (U"Maximum number of epochs"), GET_REAL (U"Tolerance of minimizer"), NULL, GET_INTEGER (U"Cost function")); END /*********** FFNet Pattern Categories **********************************/ FORM (FFNet_Pattern_Categories_getCosts_total, U"FFNet & Pattern & Categories: Get total costs", U"FFNet & Pattern & Categories: Get total costs...") RADIO (U"Cost function", 1) RADIOBUTTON (U"Minimum-squared-error") RADIOBUTTON (U"Minimum-cross-entropy") OK DO FFNet me = FIRST (FFNet); Pattern thee = FIRST (Pattern); Categories him = FIRST (Categories); Melder_information (FFNet_Pattern_Categories_getCosts_total (me, thee, him, GET_INTEGER (U"Cost function"))); END FORM (FFNet_Pattern_Categories_getCosts_average, U"FFNet & Pattern & Categories: Get average costs", U"FFNet & Pattern & Categories: Get average costs...") RADIO (U"Cost function", 1) RADIOBUTTON (U"Minimum-squared-error") RADIOBUTTON (U"Minimum-cross-entropy") OK DO FFNet me = FIRST (FFNet); Pattern thee = FIRST (Pattern); Categories him = FIRST (Categories); Melder_information (FFNet_Pattern_Categories_getCosts_average (me, thee, him, GET_INTEGER (U"Cost function"))); END FORM (Pattern_Categories_to_FFNet, U"Pattern & Categories: To FFNet", U"Pattern & Categories: To FFNet...") INTEGER (U"Number of units in hidden layer 1", U"0") INTEGER (U"Number of units in hidden layer 2", U"0") OK DO Pattern me = FIRST (Pattern); Categories thee = FIRST (Categories); long nHidden1 = GET_INTEGER (U"Number of units in hidden layer 1"); long nHidden2 = GET_INTEGER (U"Number of units in hidden layer 2"); if (nHidden1 < 1) { nHidden1 = 0; } if (nHidden2 < 1) { nHidden2 = 0; } autoCategories uniq = Categories_selectUniqueItems (thee, 1); long numberOfOutputs = uniq -> size; if (numberOfOutputs < 1) Melder_throw (U"There are not enough categories in the Categories.\n" U"Please try again with more categories in the Categories."); autoFFNet ffnet = FFNet_create (my nx, nHidden1, nHidden2, numberOfOutputs, 0); FFNet_setOutputCategories (ffnet.peek(), uniq.peek()); autostring32 ffnetName = FFNet_createNameFromTopology (ffnet.peek()); praat_new (ffnet.transfer(), ffnetName.peek()); END FORM (FFNet_Pattern_Categories_learnSM, U"FFNet & Pattern & Categories: Learn", U"FFNet & Pattern & Categories: Learn...") NATURAL (U"Maximum number of epochs", U"100") POSITIVE (U"Tolerance of minimizer", U"1e-7") RADIO (U"Cost function", 1) RADIOBUTTON (U"Minimum-squared-error") RADIOBUTTON (U"Minimum-cross-entropy") OK DO FFNet me = FIRST (FFNet); Pattern thee = FIRST (Pattern); Categories him = FIRST (Categories); FFNet_Pattern_Categories_learnSM (me, thee, him, GET_INTEGER (U"Maximum number of epochs"), GET_REAL (U"Tolerance of minimizer"), NULL, GET_INTEGER (U"Cost function")); END FORM (FFNet_Pattern_Categories_learnSD, U"FFNet & Pattern & Categories: Learn slow", U"FFNet & Pattern & Categories: Learn slow...") NATURAL (U"Maximum number of epochs", U"100") POSITIVE (U"Tolerance of minimizer", U"1e-7") LABEL (U"Specifics", U"Specific for this minimization") POSITIVE (U"Learning rate", U"0.1") REAL (U"Momentum", U"0.9") RADIO (U"Cost function", 1) RADIOBUTTON (U"Minimum-squared-error") RADIOBUTTON (U"Minimum-cross-entropy") OK DO FFNet me = FIRST (FFNet); Pattern thee = FIRST (Pattern); Categories him = FIRST (Categories); struct structSteepestDescentMinimizer_parameters p; p.eta = GET_REAL (U"Learning rate"); p.momentum = GET_REAL (U"Momentum"); FFNet_Pattern_Categories_learnSD (me, thee, him, GET_INTEGER (U"Maximum number of epochs"), GET_REAL (U"Tolerance of minimizer"), &p, GET_INTEGER (U"Cost function")); END void praat_uvafon_FFNet_init (); void praat_uvafon_FFNet_init () { Thing_recognizeClassesByName (classFFNet, NULL); praat_addMenuCommand (U"Objects", U"New", U"Neural nets", 0, 0, 0); praat_addMenuCommand (U"Objects", U"New", U"Feedforward neural networks", 0, 1, DO_FFNet_help); praat_addMenuCommand (U"Objects", U"New", U"-- FFNet --", 0, 1, 0); praat_addMenuCommand (U"Objects", U"New", U"Create iris example...", 0, 1, DO_FFNet_createIrisExample); praat_addMenuCommand (U"Objects", U"New", U"Create FFNet...", 0, 1, DO_FFNet_create); praat_addMenuCommand (U"Objects", U"New", U"Advanced", 0, 1, 0); praat_addMenuCommand (U"Objects", U"New", U"Create Pattern...", 0, 2, DO_Pattern_create); praat_addMenuCommand (U"Objects", U"New", U"Create Categories...", 0, 2, DO_Categories_create); praat_addMenuCommand (U"Objects", U"New", U"Create FFNet (linear outputs)...", 0, 2, DO_FFNet_create_linearOutputs); praat_addAction1 (classFFNet, 0, U"FFNet help", 0, 0, DO_FFNet_help); praat_addAction1 (classFFNet, 0, DRAW_BUTTON, 0, 0, 0); praat_addAction1 (classFFNet, 0, U"Draw topology", 0, 1, DO_FFNet_drawTopology); praat_addAction1 (classFFNet, 0, U"Draw weights...", 0, 1, DO_FFNet_drawWeights); praat_addAction1 (classFFNet, 0, U"Draw weights to layer...", 0, praat_DEPTH_1 | praat_HIDDEN, DO_FFNet_drawWeightsToLayer); praat_addAction1 (classFFNet, 0, U"Draw cost history...", 0, 1, DO_FFNet_drawCostHistory); praat_addAction1 (classFFNet, 0, QUERY_BUTTON, 0, 0, 0); praat_addAction1 (classFFNet, 0, U"Query structure", 0, 1, 0); praat_addAction1 (classFFNet, 1, U"Get number of outputs", 0, 2, DO_FFNet_getNumberOfOutputs); praat_addAction1 (classFFNet, 1, U"Get number of hidden units...", 0, 2, DO_FFNet_getNumberOfHiddenUnits); praat_addAction1 (classFFNet, 1, U"Get number of inputs", 0, 2, DO_FFNet_getNumberOfInputs); praat_addAction1 (classFFNet, 1, U"Get number of hidden weights...", 0, 2, DO_FFNet_getNumberOfHiddenWeights); praat_addAction1 (classFFNet, 1, U"Get number of output weights", 0, 2, DO_FFNet_getNumberOfOutputWeights); praat_addAction1 (classFFNet, 1, U"Get category of output unit...", 0, 2, DO_FFNet_getCategoryOfOutputUnit); praat_addAction1 (classFFNet, 1, U"Get output unit of category...", 0, 2, DO_FFNet_getOutputUnitOfCategory); praat_addAction1 (classFFNet, 0, U"-- FFNet weights --", 0, 1, 0); praat_addAction1 (classFFNet, 1, U"Get bias...", 0, 1, DO_FFNet_getBias); praat_addAction1 (classFFNet, 1, U"Get weight...", 0, 1, DO_FFNet_getWeight); praat_addAction1 (classFFNet, 1, U"Get minimum", 0, 1, DO_FFNet_getMinimum); praat_addAction1 (classFFNet, 0, MODIFY_BUTTON, 0, 0, 0); praat_addAction1 (classFFNet, 1, U"Set bias...", 0, 1, DO_FFNet_setBias); praat_addAction1 (classFFNet, 1, U"Set weight...", 0, 1, DO_FFNet_setWeight); praat_addAction1 (classFFNet, 1, U"Reset...", 0, 1, DO_FFNet_reset); praat_addAction1 (classFFNet, 0, U"Select biases...", 0, 1, DO_FFNet_selectBiasesInLayer); praat_addAction1 (classFFNet, 0, U"Select all weights", 0, 1, DO_FFNet_selectAllWeights); praat_addAction1 (classFFNet, 0, EXTRACT_BUTTON, 0, 0, 0); praat_addAction1 (classFFNet, 0, U"Extract weights...", 0, 1, DO_FFNet_extractWeights); praat_addAction1 (classFFNet, 0, U"Weights to Matrix...", 0, praat_DEPTH_1 | praat_HIDDEN, DO_FFNet_weightsToMatrix); praat_addAction1 (classFFNet, 0, U"& Pattern: Classify?", 0, 0, DO_hint_FFNet_and_Pattern_classify); praat_addAction1 (classFFNet, 0, U"& Pattern & Categories: Learn?", 0, 0, DO_hint_FFNet_and_Pattern_and_Categories_learn); praat_addAction2 (classFFNet, 1, classActivation, 1, U"Analyse", 0, 0, 0); praat_addAction2 (classFFNet, 1, classActivation, 1, U"To Categories...", 0, 0, DO_FFNet_Activation_to_Categories); praat_addAction2 (classFFNet, 1, classEigen, 1, U"Draw", 0, 0, 0); praat_addAction2 (classFFNet, 1, classEigen, 1, U"Draw hyperplane intersections", 0, 0, DO_FFNet_Eigen_drawIntersection); praat_addAction2 (classFFNet, 1, classCategories, 1, U"Analyse", 0, 0, 0); praat_addAction2 (classFFNet, 1, classCategories, 1, U"To Activation", 0, 0, DO_FFNet_Categories_to_Activation); praat_addAction2 (classFFNet, 1, classMatrix, 1, U"Modify", 0, 0, 0); praat_addAction2 (classFFNet, 1, classMatrix, 1, U"Weights from Matrix...", 0, 0, DO_FFNet_weightsFromMatrix); praat_addAction2 (classFFNet, 1, classPattern, 1, U"Draw", 0, 0, 0); praat_addAction2 (classFFNet, 1, classPattern, 1, U"Draw activation...", 0, 0, DO_FFNet_Pattern_drawActivation); praat_addAction2 (classFFNet, 1, classPattern, 1, U"Analyse", 0, 0, 0); praat_addAction2 (classFFNet, 1, classPattern, 1, U"To Categories...", 0, 0, DO_FFNet_Pattern_to_Categories); praat_addAction2 (classFFNet, 1, classPattern, 1, U"To Activation...", 0, 0, DO_FFNet_Pattern_to_Activation); praat_addAction2 (classFFNet, 1, classPCA, 1, U"Draw decision plane...", 0, 0, DO_FFNet_PCA_drawDecisionPlaneInEigenspace); praat_addAction2 (classPattern, 1, classCategories, 1, U"To FFNet...", 0, 0, DO_Pattern_Categories_to_FFNet); praat_addAction3 (classFFNet, 1, classPattern, 1, classActivation, 1, U"Get total costs...", 0, 0, DO_FFNet_Pattern_Activation_getCosts_total); praat_addAction3 (classFFNet, 1, classPattern, 1, classActivation, 1, U"Get average costs...", 0, 0, DO_FFNet_Pattern_Activation_getCosts_average); praat_addAction3 (classFFNet, 1, classPattern, 1, classActivation, 1, U"Learn", 0, 0, 0); praat_addAction3 (classFFNet, 1, classPattern, 1, classActivation, 1, U"Learn...", 0, 0, DO_FFNet_Pattern_Activation_learnSM); praat_addAction3 (classFFNet, 1, classPattern, 1, classActivation, 1, U"Learn slow...", 0, 0, DO_FFNet_Pattern_Activation_learnSD); praat_addAction3 (classFFNet, 1, classPattern, 1, classCategories, 1, U"Get total costs...", 0, 0, DO_FFNet_Pattern_Categories_getCosts_total); praat_addAction3 (classFFNet, 1, classPattern, 1, classCategories, 1, U"Get average costs...", 0, 0, DO_FFNet_Pattern_Categories_getCosts_average); praat_addAction3 (classFFNet, 1, classPattern, 1, classCategories, 1, U"Learn", 0, 0, 0); praat_addAction3 (classFFNet, 1, classPattern, 1, classCategories, 1, U"Learn...", 0, 0, DO_FFNet_Pattern_Categories_learnSM); praat_addAction3 (classFFNet, 1, classPattern, 1, classCategories, 1, U"Learn slow...", 0, 0, DO_FFNet_Pattern_Categories_learnSD); INCLUDE_MANPAGES (manual_FFNet_init) } /* End of file praat_FFnet_init.cpp */ praat-6.0.04/LPC/000077500000000000000000000000001261542461700133365ustar00rootroot00000000000000praat-6.0.04/LPC/Cepstrogram.cpp000066400000000000000000000444511261542461700163400ustar00rootroot00000000000000/* Cepstrogram.cpp * * Copyright (C) 2013, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20010514 djmw 20020812 GPL header djmw 20080122 Version 1: float -> double djmw 20110304 Thing_new */ #include "Cepstrogram.h" #include "Cepstrum_and_Spectrum.h" #include "NUM2.h" #include "Sound_and_Spectrum.h" #include "Sound_extensions.h" #define TOLOG(x) ((1 / NUMln10) * log ((x) + 1e-30)) #define TO10LOG(x) ((10 / NUMln10) * log ((x) + 1e-30)) #define FROMLOG(x) (exp ((x) * (NUMln10 / 10.0)) - 1e-30) Thing_implement (Cepstrogram, Matrix, 2); Thing_implement (PowerCepstrogram, Cepstrogram, 2); // derives from Matrix -> also version 2 autoCepstrogram Cepstrogram_create (double tmin, double tmax, long nt, double dt, double t1, double qmin, double qmax, long nq, double dq, double q1) { try { autoCepstrogram me = Thing_new (Cepstrogram); Matrix_init (me.peek(), tmin, tmax, nt, dt, t1, qmin, qmax, nq, dq, q1); return me; } catch (MelderError) { Melder_throw (U"Cepstrogram not created."); } } autoPowerCepstrogram PowerCepstrogram_create (double tmin, double tmax, long nt, double dt, double t1, double qmin, double qmax, long nq, double dq, double q1) { try { autoPowerCepstrogram me = Thing_new (PowerCepstrogram); Matrix_init (me.peek(), tmin, tmax, nt, dt, t1, qmin, qmax, nq, dq, q1); return me; } catch (MelderError) { Melder_throw (U"PowerCepstrogram not created."); } } void PowerCepstrogram_paint (PowerCepstrogram me, Graphics g, double tmin, double tmax, double qmin, double qmax, double dBmaximum, int autoscaling, double dynamicRangedB, double dynamicCompression, int garnish) { if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } if (qmax <= qmin) { qmin = my ymin; qmax = my ymax; } long itmin, itmax, ifmin, ifmax; if (! Matrix_getWindowSamplesX (me, tmin - 0.49999 * my dx, tmax + 0.49999 * my dx, & itmin, & itmax) || ! Matrix_getWindowSamplesY (me, qmin - 0.49999 * my dy, qmax + 0.49999 * my dy, & ifmin, & ifmax)) { return; } autoMatrix thee = (Matrix) Data_copy (me); double min = 1e308, max = -min; for (long i = 1; i <= my ny; i++) { for (long j = 1; j <= my nx; j++) { double val = TO10LOG (my z[i][j]); min = val < min ? val : min; max = val > max ? val : max; thy z[i][j] = val; } } double dBminimum = dBmaximum - dynamicRangedB; if (autoscaling) { dBminimum = min; dBmaximum = max; } for (long j = 1; j <= my nx; j++) { double lmax = thy z[1][j]; for (long i = 2; i <= my ny; i++) { if (thy z[i][j] > lmax) { lmax = thy z[i][j]; } } double factor = dynamicCompression * (max - lmax); for (long i = 1; i <= my ny; i++) { thy z[i][j] += factor; } } Graphics_setInner (g); Graphics_setWindow (g, tmin, tmax, qmin, qmax); Graphics_image (g, thy z, itmin, itmax, Matrix_columnToX (thee.peek(), itmin - 0.5), Matrix_columnToX (thee.peek(), itmax + 0.5), ifmin, ifmax, Matrix_rowToY (thee.peek(), ifmin - 0.5), Matrix_rowToY (thee.peek(), ifmax + 0.5), dBminimum, dBmaximum); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Time (s)"); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); Graphics_textLeft (g, true, U"Quefrency (s)"); } } void PowerCepstrogram_subtractTilt_inline (PowerCepstrogram me, double qstartFit, double qendFit, int lineType, int fitMethod) { try { autoPowerCepstrum thee = PowerCepstrum_create (my ymax, my ny); for (long i = 1; i <= my nx; i++) { for (long j = 1; j <= my ny; j++) { thy z[1][j] = my z[j][i]; } PowerCepstrum_subtractTilt_inline (thee.peek(), qstartFit, qendFit, lineType, fitMethod); for (long j = 1; j <= my ny; j++) { my z[j][i] = thy z[1][j]; } } } catch (MelderError) { Melder_throw (me, U": no tilt subtracted (inline)."); } } autoPowerCepstrogram PowerCepstrogram_subtractTilt (PowerCepstrogram me, double qstartFit, double qendFit, int lineType, int fitMethod) { try { autoPowerCepstrogram thee = Data_copy (me); PowerCepstrogram_subtractTilt_inline (thee.peek(), qstartFit, qendFit, lineType, fitMethod); return thee; } catch (MelderError) { Melder_throw (me, U": no tilt subtracted."); } } autoTable PowerCepstrogram_to_Table_hillenbrand (PowerCepstrogram me, double pitchFloor, double pitchCeiling) { try { autoTable thee = Table_createWithColumnNames (my nx, U"time quefrency cpp f0"); autoPowerCepstrum him = PowerCepstrum_create (my ymax, my ny); for (long i = 1; i <= my nx; i++) { for (long j = 1; j <= my ny; j++) { his z[1][j] = my z[j][i]; } double qpeak, cpp = PowerCepstrum_getPeakProminence_hillenbrand (him.peek(), pitchFloor, pitchCeiling, &qpeak); double time = Sampled_indexToX (me, i); Table_setNumericValue (thee.peek(), i, 1, time); Table_setNumericValue (thee.peek(), i, 2, qpeak); Table_setNumericValue (thee.peek(), i, 3, cpp); // Cepstrogram_getCPPS depends on this index 3!! Table_setNumericValue (thee.peek(), i, 4, 1.0 / qpeak); } return thee; } catch (MelderError) { Melder_throw (me, U": no Table with cepstral peak prominence values created."); } } autoTable PowerCepstrogram_to_Table_cpp (PowerCepstrogram me, double pitchFloor, double pitchCeiling, double deltaF0, int interpolation, double qstartFit, double qendFit, int lineType, int fitMethod) { try { autoTable thee = Table_createWithColumnNames (my nx, U"time quefrency cpp f0 rnr"); autoPowerCepstrum him = PowerCepstrum_create (my ymax, my ny); for (long i = 1; i <= my nx; i++) { for (long j = 1; j <= my ny; j++) { his z[1][j] = my z[j][i]; } double qpeak, cpp = PowerCepstrum_getPeakProminence (him.peek(), pitchFloor, pitchCeiling, interpolation, qstartFit, qendFit, lineType, fitMethod, &qpeak); double rnr = PowerCepstrum_getRNR (him.peek(), pitchFloor, pitchCeiling, deltaF0); double time = Sampled_indexToX (me, i); Table_setNumericValue (thee.peek(), i, 1, time); Table_setNumericValue (thee.peek(), i, 2, qpeak); Table_setNumericValue (thee.peek(), i, 3, cpp); // Cepstrogram_getCPPS depends on this index!! Table_setNumericValue (thee.peek(), i, 4, 1.0 / qpeak); Table_setNumericValue (thee.peek(), i, 5, rnr); } return thee; } catch (MelderError) { Melder_throw (me, U": no Table with cepstral peak prominence values created."); } } autoPowerCepstrogram PowerCepstrogram_smooth (PowerCepstrogram me, double timeAveragingWindow, double quefrencyAveragingWindow) { try { autoPowerCepstrogram thee = Data_copy (me); // 1. average across time long numberOfFrames = (long) floor (timeAveragingWindow / my dx); if (numberOfFrames > 1) { autoNUMvector qin (1, my nx); autoNUMvector qout (1, my nx); for (long iq = 1; iq <= my ny; iq++) { for (long iframe = 1; iframe <= my nx; iframe++) { //qin[iframe] = TO10LOG (my z[iq][iframe]); qin[iframe] = thy z[iq][iframe]; } NUMvector_smoothByMovingAverage (qin.peek(), my nx, numberOfFrames, qout.peek()); for (long iframe = 1; iframe <= my nx; iframe++) { //thy z[iq][iframe] = FROMLOG (qout[iframe]); // inverse thy z[iq][iframe] = qout[iframe]; // inverse } } } // 2. average across quefrencies long numberOfQuefrencyBins = (long) floor (quefrencyAveragingWindow / my dy); if (numberOfQuefrencyBins > 1) { autoNUMvector qin (1, thy ny); autoNUMvector qout (1, thy ny); for (long iframe = 1; iframe <= my nx; iframe++) { for (long iq = 1; iq <= thy ny; iq++) { //qin[iq] = TO10LOG (my z[iq][iframe]); qin[iq] = thy z[iq][iframe]; } NUMvector_smoothByMovingAverage (qin.peek(), thy ny, numberOfQuefrencyBins, qout.peek()); for (long iq = 1; iq <= thy ny; iq++) { //thy z[iq][iframe] = FROMLOG (qout[iq]); thy z[iq][iframe] = qout[iq]; } } } return thee; } catch (MelderError) { Melder_throw (me, U": not smoothed."); } } autoMatrix PowerCepstrogram_to_Matrix (PowerCepstrogram me) { try { autoMatrix thee = Thing_new (Matrix); my structMatrix :: v_copy (thee.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": no Matrix created."); } } autoPowerCepstrum PowerCepstrogram_to_PowerCepstrum_slice (PowerCepstrogram me, double time) { try { long iframe = Sampled_xToNearestIndex (me, time); iframe = iframe < 1 ? 1 : iframe > my nx ? my nx : iframe; autoPowerCepstrum thee = PowerCepstrum_create (my ymax, my ny); for (long i = 1; i <= my ny; i++) { thy z[1][i] = my z[i][iframe]; } return thee; } catch (MelderError) { Melder_throw (me, U": Cepstrum not extracted."); } } autoPowerCepstrogram Matrix_to_PowerCepstrogram (Matrix me); autoPowerCepstrogram Matrix_to_PowerCepstrogram (Matrix me) { try { autoPowerCepstrogram thee = Thing_new (PowerCepstrogram); my structMatrix :: v_copy (thee.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": no PowerCepstrogram created."); } } autoPowerCepstrogram Sound_to_PowerCepstrogram (Sound me, double pitchFloor, double dt, double maximumFrequency, double preEmphasisFrequency) { try { // minimum analysis window has 3 periods of lowest pitch double analysisWidth = 3.0 / pitchFloor; double windowDuration = 2.0 * analysisWidth; /* gaussian window */ long nFrames; // Convenience: analyse the whole sound into one Cepstrogram_frame if (windowDuration > my dx * my nx) { windowDuration = my dx * my nx; } double t1, samplingFrequency = 2 * maximumFrequency; autoSound sound = Sound_resample (me, samplingFrequency, 50); Sound_preEmphasis (sound.peek(), preEmphasisFrequency); Sampled_shortTermAnalysis (me, windowDuration, dt, & nFrames, & t1); autoSound sframe = Sound_createSimple (1, windowDuration, samplingFrequency); autoSound window = Sound_createGaussian (windowDuration, samplingFrequency); // find out the size of the FFT long nfft = 2; while (nfft < sframe -> nx) nfft *= 2; long nq = nfft / 2 + 1; double qmax = 0.5 * nfft / samplingFrequency, dq = qmax / (nq - 1); autoPowerCepstrogram thee = PowerCepstrogram_create (my xmin, my xmax, nFrames, dt, t1, 0, qmax, nq, dq, 0); autoMelderProgress progress (U"Cepstrogram analysis"); for (long iframe = 1; iframe <= nFrames; iframe++) { double t = Sampled_indexToX (thee.peek(), iframe); Sound_into_Sound (sound.peek(), sframe.peek(), t - windowDuration / 2); Vector_subtractMean (sframe.peek()); Sounds_multiply (sframe.peek(), window.peek()); autoSpectrum spec = Sound_to_Spectrum (sframe.peek(), 1); // FFT yes autoPowerCepstrum cepstrum = Spectrum_to_PowerCepstrum (spec.peek()); for (long i = 1; i <= nq; i++) { thy z[i][iframe] = cepstrum -> z[1][i]; } if ((iframe % 10) == 1) { Melder_progress ((double) iframe / nFrames, U"PowerCepstrogram analysis of frame ", iframe, U" out of ", nFrames, U"."); } } return thee; } catch (MelderError) { Melder_throw (me, U": no PowerCepstrogram created."); } } autoCepstrum Spectrum_to_Cepstrum_hillenbrand (Spectrum me); autoCepstrum Spectrum_to_Cepstrum_hillenbrand (Spectrum me) { try { autoNUMfft_Table fftTable; // originalNumberOfSamplesProbablyOdd irrelevant if (my x1 != 0.0) { Melder_throw (U"A Fourier-transformable Spectrum must have a first frequency of 0 Hz, not ", my x1, U" Hz."); } long numberOfSamples = my nx - 1; autoCepstrum thee = Cepstrum_create (0.5 / my dx, my nx); NUMfft_Table_init (&fftTable, my nx); autoNUMvector amp (1, my nx); for (long i = 1; i <= my nx; i++) { amp [i] = my v_getValueAtSample (i, 0, 2); } NUMfft_forward (&fftTable, amp.peek()); for (long i = 1; i <= my nx; i++) { double val = amp[i] / numberOfSamples;// scaling 1/n because ifft(fft(1))= n; thy z[1][i] = val * val; // power cepstrum } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Sound."); } } // 1 2 nfftdiv2 // re im re im re im // ((fft[1],0) (fft[2],fft[3]), (,), (,), (fft[nfft], 0)) nfft even // ((fft[1],0) (fft[2],fft[3]), (,), (,), (fft[nfft-1], fft[nfft])) nfft uneven static void complexfftoutput_to_power (double *fft, long nfft, double *dbs, bool to_db) { double valsq = fft[1] * fft[1]; dbs[1] = to_db ? TOLOG (valsq) : valsq; long nfftdiv2p1 = (nfft + 2) / 2; long nend = nfft % 2 == 0 ? nfftdiv2p1 : nfftdiv2p1 + 1; for (long i = 2; i < nend; i++) { double re = fft[i + i - 2], im = fft[i + i - 1]; valsq = re * re + im * im; dbs[i] = to_db ? TOLOG (valsq) : valsq; } if (nfft % 2 == 0) { valsq = fft[nfft] * fft[nfft]; dbs[nfftdiv2p1] = to_db ? TOLOG (valsq) : valsq; } } autoPowerCepstrogram Sound_to_PowerCepstrogram_hillenbrand (Sound me, double minimumPitch, double dt) { try { // minimum analysis window has 3 periods of lowest pitch double analysisWidth = 3 / minimumPitch; if (analysisWidth > my dx * my nx) { analysisWidth = my dx * my nx; } double t1, samplingFrequency = 1.0 / my dx; autoSound thee; if (samplingFrequency > 30000) { samplingFrequency = samplingFrequency / 2.0; thee = Sound_resample (me, samplingFrequency, 1); } else { thee = Data_copy (me); } // pre-emphasis with fixed coefficient 0.9 for (long i = thy nx; i > 1; i--) { thy z[1][i] -= 0.9 * thy z[1][i - 1]; } long nosInWindow = (long) floor (analysisWidth * samplingFrequency), nFrames; if (nosInWindow < 8) { Melder_throw (U"Analysis window too short."); } Sampled_shortTermAnalysis (thee.peek(), analysisWidth, dt, & nFrames, & t1); autoNUMvector hamming (1, nosInWindow); for (long i = 1; i <= nosInWindow; i++) { hamming[i] = 0.54 -0.46 * cos(2 * NUMpi * (i - 1) / (nosInWindow - 1)); } long nfft = 8; // minimum possible while (nfft < nosInWindow) { nfft *= 2; } long nfftdiv2 = nfft / 2; autoNUMvector fftbuf (1, nfft); // "complex" array autoNUMvector spectrum (1, nfftdiv2 + 1); // +1 needed autoNUMfft_Table fftTable; NUMfft_Table_init (&fftTable, nfft); // sound to spectrum double qmax = 0.5 * nfft / samplingFrequency, dq = qmax / (nfftdiv2 + 1); autoPowerCepstrogram him = PowerCepstrogram_create (my xmin, my xmax, nFrames, dt, t1, 0, qmax, nfftdiv2+1, dq, 0); autoMelderProgress progress (U"Cepstrogram analysis"); for (long iframe = 1; iframe <= nFrames; iframe++) { double tbegin = t1 + (iframe - 1) * dt - analysisWidth / 2; tbegin = tbegin < thy xmin ? thy xmin : tbegin; long istart = Sampled_xToLowIndex (thee.peek(), tbegin); // ppgb: afronding naar beneden? istart = istart < 1 ? 1 : istart; long iend = istart + nosInWindow - 1; iend = iend > thy nx ? thy nx : iend; for (long i = 1; i <= nosInWindow; i++) { fftbuf[i] = thy z[1][istart + i - 1] * hamming[i]; } for (long i = nosInWindow + 1; i <= nfft; i++) { fftbuf[i] = 0; } NUMfft_forward (&fftTable, fftbuf.peek()); complexfftoutput_to_power (fftbuf.peek(), nfft, spectrum.peek(), true); // log10(|fft|^2) // subtract average double specmean = spectrum[1]; for (long i = 2; i <= nfftdiv2 + 1; i++) { specmean += spectrum[i]; } specmean /= nfftdiv2 + 1; for (long i = 1; i <= nfftdiv2 + 1; i++) { spectrum[i] -= specmean; } /* * Here we diverge from Hillenbrand as he takes the fft of half of the spectral values. * H. forgets that the actual spectrum has nfft/2+1 values. Thefore, we take the inverse * transform because this keeps the number of samples a power of 2. * At the same time this results in twice as much numbers in the quefrency domain, i.e. we end with nfft/2+1 * numbers while H. has only nfft/4! */ fftbuf[1] = spectrum[1]; for (long i = 2; i < nfftdiv2 + 1; i++) { fftbuf[i+i-2] = spectrum[i]; fftbuf[i+i-1] = 0; } fftbuf[nfft] = spectrum[nfftdiv2 + 1]; NUMfft_backward (&fftTable, fftbuf.peek()); for (long i = 1; i <= nfftdiv2 + 1; i++) { his z[i][iframe] = fftbuf[i] * fftbuf[i]; } if ((iframe % 10) == 1) { Melder_progress ((double) iframe / nFrames, U"Cepstrogram analysis of frame ", iframe, U" out of ", nFrames, U"."); } } return him; } catch (MelderError) { Melder_throw (me, U": no Cepstrogram created."); } } double PowerCepstrogram_getCPPS (PowerCepstrogram me, bool subtractTiltBeforeSmoothing, double timeAveragingWindow, double quefrencyAveragingWindow, double pitchFloor, double pitchCeiling, double deltaF0, int interpolation, double qstartFit, double qendFit, int lineType, int fitMethod) { try { autoPowerCepstrogram him; if (subtractTiltBeforeSmoothing) { him = PowerCepstrogram_subtractTilt (me, qstartFit, qendFit, lineType, fitMethod); } autoPowerCepstrogram smooth = PowerCepstrogram_smooth (subtractTiltBeforeSmoothing ? him.peek() : me, timeAveragingWindow, quefrencyAveragingWindow); autoTable table = PowerCepstrogram_to_Table_cpp (smooth.peek(), pitchFloor, pitchCeiling, deltaF0, interpolation, qstartFit, qendFit, lineType, fitMethod); double cpps = Table_getMean (table.peek(), 3); return cpps; } catch (MelderError) { Melder_throw (me, U": no CPPS value calculated."); } } double PowerCepstrogram_getCPPS_hillenbrand (PowerCepstrogram me, bool subtractTiltBeforeSmoothing, double timeAveragingWindow, double quefrencyAveragingWindow, double pitchFloor, double pitchCeiling) { try { autoPowerCepstrogram him; if (subtractTiltBeforeSmoothing) { him = PowerCepstrogram_subtractTilt (me, 0.001, 0, 1, 1); } autoPowerCepstrogram smooth = PowerCepstrogram_smooth (subtractTiltBeforeSmoothing ? him.peek() : me, timeAveragingWindow, quefrencyAveragingWindow); autoTable table = PowerCepstrogram_to_Table_hillenbrand (smooth.peek(), pitchFloor, pitchCeiling); double cpps = Table_getMean (table.peek(), 3); return cpps; } catch (MelderError) { Melder_throw (me, U": no CPPS value calculated."); } } /* End of file Cepstrogram.cpp */ praat-6.0.04/LPC/Cepstrogram.h000066400000000000000000000070151261542461700160000ustar00rootroot00000000000000#ifndef _Cepstrogram_h_ #define _Cepstrogram_h_ /* Cepstrogram.h * * Copyright (C) 2012-2013 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20121017 djmw 20130502 Latest modification. */ /* The Cepstrogram is a matrix of REAL numbers. It is the inverse-fourier-transformed logarithm of the spectrum of a (sound) signal. */ #include "Cepstrum.h" #include "Sound.h" #include "Table.h" Thing_define (Cepstrogram, Matrix) { }; Thing_define (PowerCepstrogram, Cepstrogram) { }; /* xmin, xmax : time domain nx, dx, x1 : sampling in the time domain ymin // Lowest quefrency. ymax // Highest quefrency. ny // Number of quefrencies. dy // Quefrency step. y1 // First quefrency. */ autoCepstrogram Cepstrogram_create (double tmin, double tmax, long nt, double dt, double t1, double qmin, double qmax, long nq, double dq, double q1); autoPowerCepstrogram PowerCepstrogram_create (double tmin, double tmax, long nt, double dt, double t1, double qmin, double qmax, long nq, double dq, double q1); void PowerCepstrogram_paint (PowerCepstrogram me, Graphics g, double tmin, double tmax, double qmin, double qmax, double dBmaximum, int autoscaling, double dynamicRangedB, double dynamicCompression, int garnish); autoPowerCepstrogram PowerCepstrogram_smooth (PowerCepstrogram me, double timeAveragingWindow, double quefrencyAveragingWindow); autoPowerCepstrogram Sound_to_PowerCepstrogram (Sound me, double analysisWidth, double dt, double maximumFrequency, double preEmphasisFrequency); autoPowerCepstrogram Sound_to_PowerCepstrogram_hillenbrand (Sound me, double analysisWidth, double dt); autoTable PowerCepstrogram_to_Table_hillenbrand (PowerCepstrogram me, double pitchFloor, double pitchCeiling); autoTable PowerCepstrogram_to_Table_cpp (PowerCepstrogram me, double pitchFloor, double pitchCeiling, double deltaF0, int interpolation, double qstartFit, double qendFit, int lineType, int method); autoPowerCepstrum PowerCepstrogram_to_PowerCepstrum_slice (PowerCepstrogram me, double time); autoPowerCepstrogram PowerCepstrogram_subtractTilt (PowerCepstrogram me, double qstartFit, double qendFit, int lineType, int fitMethod); void PowerCepstrogram_subtractTilt_inline (PowerCepstrogram me, double qstartFit, double qendFit, int lineType, int fitMethod); double PowerCepstrogram_getCPPS_hillenbrand (PowerCepstrogram me, bool subtractTiltBeforeSmoothing, double timeAveragingWindow, double quefrencyAveragingWindow, double pitchFloor, double pitchCeiling); double PowerCepstrogram_getCPPS (PowerCepstrogram me, bool subtractTiltBeforeSmoothing, double timeAveragingWindow, double quefrencyAveragingWindow, double pitchFloor, double pitchCeiling, double deltaF0, int interpolation, double qstartFit, double qendFit, int lineType, int fitMethod); autoMatrix PowerCepstrogram_to_Matrix (PowerCepstrogram me); autoPowerCepstrogram Matrix_to_Cepstrogram (Matrix me); #endif /* _Cepstrogram_h_ */ praat-6.0.04/LPC/Cepstrum.cpp000066400000000000000000000454771261542461700156650ustar00rootroot00000000000000/* Cepstrum.cpp * * Copyright (C) 1994-2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20010514 djmw 20020812 GPL header djmw 20080122 Version 1: float -> double djmw 20110304 Thing_new */ #include "Cepstrum.h" #include "NUM2.h" #include "Vector.h" static void NUMvector_gaussianBlur (double sigma, long filterLength, double *filter) { if (filterLength <= 1) { filter[1] = 1; return; } double sum = 0, mid = (filterLength + 1) / 2; for (long i = 1; i <= filterLength; i++) { double val = (mid - i) / sigma; filter[i] = exp (- 0.5 * val * val); sum += filter[i]; } for (long i = 1; i <= filterLength; i++) { filter[i] /= sum; } } // filter must be normalised: sum(i=1, nfilters, filter[i]) == 1 static void NUMvector_filter (double *input, long numberOfDataPoints, double *filter, long numberOfFilterCoefficients, double *output, int edgeTreatment) { long nleft = (numberOfFilterCoefficients - 1) / 2; if (edgeTreatment == 0) { // outside values are zero for (long i = 1; i <= numberOfDataPoints; i++) { long ifrom = i - nleft, ito = i + nleft; ito = numberOfFilterCoefficients % 2 == 0 ? ito - 1 : ito; long jfrom = ifrom < 1 ? 1 : ifrom; long jto = ito > numberOfDataPoints ? numberOfDataPoints : ito; long index = ifrom < 1 ? 2 - ifrom : 1; double out = 0.0, sum = 0.0; for (long j = jfrom; j <= jto; j++, index++) { out += filter[index] * input[j]; sum += filter[index]; } output[i] = out / sum; } } else if (edgeTreatment == 1) { // wrap-around for (long i = 1; i <= numberOfDataPoints; i++) { double out = 0; for (long j = 1; j <= numberOfFilterCoefficients; j++) { long index = (i - nleft + j - 2) % numberOfDataPoints + 1; out += filter[j] * input[index]; } output[i] = out; } } } Thing_implement (Cepstrum, Matrix, 2); Thing_implement (PowerCepstrum, Cepstrum, 2); // derives from Matrix therefore also version 2 double structCepstrum :: v_getValueAtSample (long isamp, long which, int units) { (void) units; if (which == 0) { return z[1][isamp]; } else { // dB's return 20.0 * log10 (fabs(z[1][isamp]) + 1e-30); } return NUMundefined; } double structPowerCepstrum :: v_getValueAtSample (long isamp, long which, int units) { (void) units; if (which == 0) { return z[1][isamp]; } else { // dB's return 10.0 * log10 (z[1][isamp] + 1e-30); // always positive } return NUMundefined; } autoCepstrum Cepstrum_create (double qmax, long nq) { try { autoCepstrum me = Thing_new (Cepstrum); double dq = qmax / (nq - 1); Matrix_init (me.peek(), 0.0, qmax, nq, dq, 0.0, 1.0, 1.0, 1, 1, 1.0); return me; } catch (MelderError) { Melder_throw (U"Cepstrum not created."); } } autoPowerCepstrum Cepstrum_downto_PowerCepstrum (Cepstrum me ) { try { autoPowerCepstrum thee = PowerCepstrum_create (my xmax, my nx); for (long i = 1; i <= my nx; i++) { thy z[1][i] = my z[1][i] * my z[1][i]; } return thee; } catch (MelderError) { Melder_throw (me, U" not converted."); } } autoPowerCepstrum PowerCepstrum_create (double qmax, long nq) { try { autoPowerCepstrum me = Thing_new (PowerCepstrum); double dq = qmax / (nq - 1); Matrix_init (me.peek(), 0.0, qmax, nq, dq, 0.0, 1.0, 1.0, 1, 1, 1.0); return me; } catch (MelderError) { Melder_throw (U"PowerCepstrum not created."); } } static void _Cepstrum_draw (Cepstrum me, Graphics g, double qmin, double qmax, double minimum, double maximum, int power, int garnish) { int autoscaling = minimum >= maximum; Graphics_setInner (g); if (qmax <= qmin) { qmin = my xmin; qmax = my xmax; } long imin, imax; if (! Matrix_getWindowSamplesX (me, qmin, qmax, & imin, & imax)) { return; } autoNUMvector y (imin, imax); for (long i = imin; i <= imax; i++) { y[i] = my v_getValueAtSample (i, (power ? 1 : 0), 0); } if (autoscaling) { NUMvector_extrema (y.peek(), imin, imax, & minimum, & maximum); } else { for (long i = imin; i <= imax; i ++) { if (y[i] > maximum) { y[i] = maximum; } else if (y[i] < minimum) { y[i] = minimum; } } } Graphics_setWindow (g, qmin, qmax, minimum, maximum); Graphics_function (g, y.peek(), imin, imax, Matrix_columnToX (me, imin), Matrix_columnToX (me, imax)); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Quefrency (s)"); Graphics_marksBottom (g, 2, true, true, false); Graphics_textLeft (g, true, power ? U"Amplitude (dB)" : U"Amplitude"); Graphics_marksLeft (g, 2, true, true, false); } } void Cepstrum_drawLinear (Cepstrum me, Graphics g, double qmin, double qmax, double minimum, double maximum, int garnish) { _Cepstrum_draw (me, g, qmin, qmax, minimum, maximum, 0, garnish); } void PowerCepstrum_draw (PowerCepstrum me, Graphics g, double qmin, double qmax, double dBminimum, double dBmaximum, int garnish) { _Cepstrum_draw (me, g, qmin, qmax, dBminimum, dBmaximum, 1, garnish); } void PowerCepstrum_drawTiltLine (PowerCepstrum me, Graphics g, double qmin, double qmax, double dBminimum, double dBmaximum, double qstart, double qend, int lineType, int method) { Graphics_setInner (g); if (qmax <= qmin) { qmin = my xmin; qmax = my xmax; } if (dBminimum >= dBmaximum) { // autoscaling long imin, imax; if (! Matrix_getWindowSamplesX (me, qmin, qmax, & imin, & imax)) { return; } long numberOfPoints = imax - imin + 1; dBminimum = dBmaximum = my v_getValueAtSample (imin, 1, 0); for (long i = 2; i <= numberOfPoints; i++) { long isamp = imin + i - 1; double y = my v_getValueAtSample (isamp, 1, 0); dBmaximum = y > dBmaximum ? y : dBmaximum; dBminimum = y < dBminimum ? y : dBminimum; } } Graphics_setWindow (g, qmin, qmax, dBminimum, dBmaximum); qend = qend == 0 ? my xmax : qend; if (qend <= qstart) { qend = my xmax; qstart = my xmin; } qstart = qstart < my xmin ? my xmin : qstart; qend = qend > my xmax ? my xmax : qend; double a, intercept; PowerCepstrum_fitTiltLine (me, qstart, qend, &a, &intercept, lineType, method); /* * Don't draw part outside window */ double lineWidth = Graphics_inqLineWidth (g); Graphics_setLineWidth (g, 2); if (lineType == 2) { long n = 500; double dq = (qend - qstart) / (n + 1); double q1 = qstart; if (qstart <= 0) { qstart = 0.1 * dq; // some small offset to avoid log(0) n--; } autoNUMvector y (1, n); for (long i = 1; i <= n; i++) { double q = q1 + (i - 1) * dq; y[i] = a * log (q) + intercept; } Graphics_function (g, y.peek(), 1, n, qstart, qend); } else { double y1 = a * qstart + intercept, y2 = a * qend + intercept; if (y1 >= dBminimum && y2 >= dBminimum) { Graphics_line (g, qstart, y1, qend, y2); } else if (y1 < dBminimum) { qstart = (dBminimum - intercept) / a; Graphics_line (g, qstart, dBminimum, qend, y2); } else if (y2 < dBminimum) { qend = (dBminimum - intercept) / a; Graphics_line (g, qstart, y1, qend, dBminimum); } else { // don't draw anything below lower limit? } } Graphics_setLineWidth (g, lineWidth); Graphics_unsetInner (g); } /* Fit line y = ax+b (lineType ==1) or y = a log(x) + b (lineType == 2) on interval [qmin,qmax] * method == 1 : Least squares fit * method == 2 : Theil's partial robust fit */ void PowerCepstrum_fitTiltLine (PowerCepstrum me, double qmin, double qmax, double *a, double *intercept, int lineType, int method) { try { if (qmax <= qmin) { qmin = my xmin; qmax = my xmax; } long imin, imax; if (! Matrix_getWindowSamplesX (me, qmin, qmax, & imin, & imax)) { return; } imin = (lineType == 2 && imin == 1) ? 2 : imin; // log(0) is undefined! long numberOfPoints = imax - imin + 1; if (numberOfPoints < 2) { Melder_throw (U"Not enough points for fit."); } autoNUMvector y (1, numberOfPoints); autoNUMvector x (1, numberOfPoints); for (long i = 1; i <= numberOfPoints; i++) { long isamp = imin + i - 1; x[i] = my x1 + (isamp - 1) * my dx; if (lineType == 2) { x[i] = log (x[i]); } y[i] = my v_getValueAtSample (isamp, 1, 0); } if (method == 3) { // try local maxima first autoNUMvector ym (1, numberOfPoints / 2 + 1); autoNUMvector xm (1, numberOfPoints / 2 + 1); long numberOfLocalPeaks = 0; // forget y[1] if y[2] y[i + 1]) { ym[++numberOfLocalPeaks] = y[i]; xm[numberOfLocalPeaks] = x[i]; } } if (numberOfLocalPeaks > numberOfPoints / 10) { for (long i = 1; i <= numberOfLocalPeaks; i++) { x[i] = xm[i]; y[i] = ym[i]; } numberOfPoints = numberOfLocalPeaks; } method = 2; // robust fit of peaks } // fit a straight line through (x,y)'s NUMlineFit (x.peek(), y.peek(), numberOfPoints, a, intercept, method); } catch (MelderError) { Melder_throw (me, U": couldn't fit a line."); } } // Hillenbrand subtracts dB values and if the result is negative it is made zero static void PowerCepstrum_subtractTiltLine_inline2 (PowerCepstrum me, double slope, double intercept, int lineType) { for (long j = 1; j <= my nx; j++) { double q = my x1 + (j - 1) * my dx; q = j == 1 ? 0.5 * my dx : q; // approximation double xq = lineType == 2 ? log(q) : q; double db_background = slope * xq + intercept; double db_cepstrum = my v_getValueAtSample (j, 1, 0); double diff = exp ((db_cepstrum - db_background) * NUMln10 / 10) - 1e-30; my z[1][j] = diff; } } // clip with tilt line static void PowerCepstrum_subtractTiltLine_inline (PowerCepstrum me, double slope, double intercept, int lineType) { for (long j = 1; j <= my nx; j++) { double q = my x1 + (j - 1) * my dx; q = j == 1 ? 0.5 * my dx : q; // approximation double xq = lineType == 2 ? log(q) : q; double db_background = slope * xq + intercept; double db_cepstrum = my v_getValueAtSample (j, 1, 0); double diff = db_cepstrum - db_background; if (diff < 0) { diff = 0; } my z[1][j] = exp (diff * NUMln10 / 10.0) - 1e-30; } } void PowerCepstrum_subtractTilt_inline (PowerCepstrum me, double qstartFit, double qendFit, int lineType, int fitMethod) { double slope, intercept; PowerCepstrum_fitTiltLine (me, qstartFit, qendFit, &slope, &intercept, lineType, fitMethod); PowerCepstrum_subtractTiltLine_inline (me, slope, intercept, lineType); } autoPowerCepstrum PowerCepstrum_subtractTilt (PowerCepstrum me, double qstartFit, double qendFit, int lineType, int fitMethod) { try { autoPowerCepstrum thee = Data_copy (me); PowerCepstrum_subtractTilt_inline (thee.peek(), qstartFit, qendFit, lineType, fitMethod); return thee; } catch (MelderError) { Melder_throw (me, U": couldn't subtract tilt line."); } } static void PowerCepstrum_smooth_inline2 (PowerCepstrum me, double quefrencyAveragingWindow) { try { long numberOfQuefrencyBins = (long) floor (quefrencyAveragingWindow / my dx); if (numberOfQuefrencyBins > 1) { autoNUMvector qin (1, my nx); autoNUMvector qout (1, my nx); for (long iq = 1; iq <= my nx; iq++) { qin[iq] = my z[1][iq]; } NUMvector_smoothByMovingAverage (qin.peek(), my nx, numberOfQuefrencyBins, qout.peek()); for (long iq = 1; iq <= my nx; iq++) { my z[1][iq] = qout[iq]; } } } catch (MelderError) { Melder_throw (me, U": not smoothed."); } } void PowerCepstrum_smooth_inline (PowerCepstrum me, double quefrencyAveragingWindow, long numberOfIterations) { try { long numberOfQuefrencyBins = (long) floor (quefrencyAveragingWindow / my dx); if (numberOfQuefrencyBins > 1) { autoNUMvector qin (1, my nx); autoNUMvector qout (1, my nx); for (long iq = 1; iq <= my nx; iq++) { qin[iq] = my z[1][iq]; } double *xin, *xout; for (long k = 1; k <= numberOfIterations; k++) { xin = k % 2 == 1 ? qin.peek() : qout.peek (); xout = k % 2 == 1 ? qout.peek () : qin.peek(); NUMvector_smoothByMovingAverage (xin, my nx, numberOfQuefrencyBins, xout); } for (long iq = 1; iq <= my nx; iq++) { my z[1][iq] = xout[iq]; } } } catch (MelderError) { Melder_throw (me, U": not smoothed."); } } autoPowerCepstrum PowerCepstrum_smooth (PowerCepstrum me, double quefrencyAveragingWindow, long numberOfIterations) { autoPowerCepstrum thee = Data_copy (me); PowerCepstrum_smooth_inline (thee.peek(), quefrencyAveragingWindow, numberOfIterations); return thee; } void PowerCepstrum_getMaximumAndQuefrency (PowerCepstrum me, double pitchFloor, double pitchCeiling, int interpolation, double *peakdB, double *quefrency) { *peakdB = *quefrency = NUMundefined; autoPowerCepstrum thee = Data_copy (me); double lowestQuefrency = 1 / pitchCeiling, highestQuefrency = 1 / pitchFloor; for (long i = 1; i <= my nx; i++) { thy z[1][i] = my v_getValueAtSample (i, 1, 0); // 10 log val^2 } Vector_getMaximumAndX ((Vector) thee.peek(), lowestQuefrency, highestQuefrency, 1, interpolation, peakdB, quefrency); } static void Cepstrum_getZ2 (Cepstrum me, long imin, long imax, double peakdB, long margin, long keep, double *z) { *z = NUMundefined; long npeaks = 0, n = (imax - imin) / 2 + keep; autoNUMvector ymax (1, n); autoNUMvector index (1, n); for (long i = imin + 1; i < imax; i++) { if (my z[1][i] > my z[1][i-1] && my z[1][i] > my z[1][i+1]) { ymax[++npeaks] = my z[1][i]; index[npeaks] = i; } } NUMsort2 (npeaks, ymax.peek(), index.peek()); long i = npeaks - 1, ipeak = 0; while (i > 0 && ipeak < keep) { if (labs(index[i] - index[npeaks]) > margin) { ipeak++; ymax[npeaks +ipeak] = ymax[i]; } i--; } double mean, variance; NUMvector_avevar (&ymax[npeaks], ipeak, &mean, &variance); double sigma = sqrt (variance / (ipeak - 1)); double peak = exp (peakdB * NUMln10 / 10.0) - 1e-30; *z = sigma <= 0.0 ? NUMundefined : peak / sigma; } static void Cepstrum_getZ (Cepstrum me, long imin, long imax, double peakdB, double slope, double intercept, int lineType, double *z) { long ndata = imax - imin + 1; autoNUMvector dabs (1, ndata); for (long i = imin; i <= imax; i++) { double q = my x1 + (i - 1) * my dx; q = i == 1 ? 0.5 * my dx : q; // approximation double xq = lineType == 2 ? log(q) : q; double db_background = slope * xq + intercept; double db_cepstrum = my v_getValueAtSample (i, 1, 0); double diff = exp ((db_cepstrum - db_background) * NUMln10 / 10.0) - 1e-30; //double diff = fabs (db_cepstrum - db_background); dabs[i - imin + 1] = diff; } double q50 = NUMquantile (ndata, dabs.peek(), 0.5); double peak = exp (peakdB * NUMln10 / 10.0) - 1e-30; //*z = peakdB / q50; *z = peak / q50; } double PowerCepstrum_getRNR (PowerCepstrum me, double pitchFloor, double pitchCeiling, double f0fractionalWidth) { double rnr = NUMundefined; double qmin = 1 / pitchCeiling, qmax = 1 / pitchFloor, peakdB, qpeak; PowerCepstrum_getMaximumAndQuefrency (me, pitchFloor, pitchCeiling, 2, &peakdB, &qpeak); long imin, imax; if (! Matrix_getWindowSamplesX (me, qmin, qmax, & imin, & imax)) { return rnr; } long ndata = imax - imin + 1; if (ndata < 2) { return rnr; } // how many peaks in interval ? long npeaks = 2; while (qpeak > 0 && qpeak * npeaks <= qmax) { npeaks++; } npeaks--; double sum = 0, sumr = 0; for (long i = imin; i <= imax; i++) { double val = my v_getValueAtSample (i, 0, 0); double qx = my x1 + (i - 1) * my dx; sum += val; // is qx within an interval around a multiple of the peak's q ? for (long j = 1; j <= npeaks; j++) { double f0c = 1 / (j * qpeak); double f0clow = f0c * (1 - f0fractionalWidth); double f0chigh = f0c * (1 + f0fractionalWidth); double qclow = 1 / f0chigh; double qchigh = f0fractionalWidth >= 1 ? qmax : 1 / f0clow; if (qx >= qclow && qx <= qchigh) { // yes in rhamonic interval sumr += val; break; } } } rnr = sumr >= sum ? 1000000 : sumr / (sum - sumr); return rnr; } double PowerCepstrum_getPeakProminence_hillenbrand (PowerCepstrum me, double pitchFloor, double pitchCeiling, double *qpeak) { double slope, intercept, quefrency, peakdB; PowerCepstrum_fitTiltLine (me, 0.001, 0, &slope, &intercept, 1, 1); autoPowerCepstrum thee = Data_copy (me); PowerCepstrum_subtractTiltLine_inline (thee.peek(), slope, intercept, 1); PowerCepstrum_getMaximumAndQuefrency (thee.peek(), pitchFloor, pitchCeiling, 0, &peakdB, &quefrency); if (qpeak) { *qpeak = quefrency; } return peakdB; } double PowerCepstrum_getPeakProminence (PowerCepstrum me, double pitchFloor, double pitchCeiling, int interpolation, double qstartFit, double qendFit, int lineType, int fitMethod, double *qpeak) { double slope, intercept, quefrency, peakdB; PowerCepstrum_fitTiltLine (me, qstartFit, qendFit, &slope, &intercept, lineType, fitMethod); PowerCepstrum_getMaximumAndQuefrency (me, pitchFloor, pitchCeiling, interpolation, &peakdB, &quefrency); double xq = lineType == 2 ? log(quefrency) : quefrency; double db_background = slope * xq + intercept; double cpp = peakdB - db_background; if (qpeak != nullptr) { *qpeak = quefrency; } return cpp; } autoMatrix PowerCepstrum_to_Matrix (PowerCepstrum me) { try { autoMatrix thee = Thing_new (Matrix); my structMatrix :: v_copy (thee.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": no Matrix created."); } } autoPowerCepstrum Matrix_to_PowerCepstrum (Matrix me) { try { if (my ny != 1) { Melder_throw (U"Matrix should have exactly 1 row."); } autoPowerCepstrum thee = Thing_new (PowerCepstrum); my structMatrix :: v_copy (thee.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to PowerCepstrum."); } } autoPowerCepstrum Matrix_to_PowerCepstrum_row (Matrix me, long row) { try { autoPowerCepstrum thee = PowerCepstrum_create (my xmax, my nx); if (row < 1 || row > my ny) { Melder_throw (U"Row number should be between 1 and ", my ny, U" inclusive."); } NUMvector_copyElements (my z[row], thy z[1], 1, my nx); return thee; } catch (MelderError) { Melder_throw (me, U": no PowerCepstrum created."); } } autoPowerCepstrum Matrix_to_PowerCepstrum_column (Matrix me, long col) { try { autoPowerCepstrum thee = PowerCepstrum_create (my ymax, my ny); if (col < 1 || col > my nx) { Melder_throw (U"Column number should be between 1 and ", my nx, U" inclusive."); } for (long i = 1; i <= my ny; i++) { thy z[1][i] = my z[i][col]; } return thee; } catch (MelderError) { Melder_throw (me, U": no PowerCepstrum created."); } } /* End of file Cepstrum.cpp */ praat-6.0.04/LPC/Cepstrum.h000066400000000000000000000103041261542461700153070ustar00rootroot00000000000000#ifndef _Cepstrum_h_ #define _Cepstrum_h_ /* Cepstrum.h * * Copyright (C) 1994-2013, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20010111 djmw 20020812 GPL header djmw 20121117 Latest modification. */ /* The Cepstrum is a sequence of REAL numbers. It is the spectrum of the power spectrum of a (sound) signal. */ #include "Matrix.h" Thing_define (Cepstrum, Matrix) { // overridden methods: public: virtual double v_getValueAtSample (long isamp, long which, int units); }; /* The Cepstrum is a sequence of REAL numbers. It is the power spectrum of the power spectrum of a (sound) signal. */ Thing_define (PowerCepstrum, Cepstrum) { // overridden methods: public: virtual double v_getValueAtSample (long isamp, long which, int units); }; /* xmin // Lowest quefrency. xmax // Highest quefrency. nx // Number of quefrencies. dx // Quefrency step. x1 // First quefrency. ymin = ymax = dy = y1 = 1 ny = 1 */ autoCepstrum Cepstrum_create (double qmax, long nq); autoPowerCepstrum PowerCepstrum_create (double qmax, long nq); /* Preconditions: nq >= 2; Postconditions: my xmin = 0; my ymin = 1; my xmax = qmax; my ymax = 1; my nx = nq; my ny = 1; my dx = qmax / (nq -1); my dy = 1; my x1 = 0; my y1 = 1; my z [1..ny] [1..nx] = 0.0; */ void PowerCepstrum_draw (PowerCepstrum me, Graphics g, double qmin, double qmax, double dBminimum, double dBmaximum, int garnish); void Cepstrum_drawLinear (Cepstrum me, Graphics g, double qmin, double qmax, double minimum, double maximum, int garnish); void PowerCepstrum_drawTiltLine (PowerCepstrum me, Graphics g, double qmin, double qmax, double dBminimum, double dBmaximum, double qstart, double qend, int lineType, int method); /* Function: Draw a Cepstrum Preconditions: maximum > minimum; Arguments: [qmin, qmax]: quefrencies; x domain of drawing; Autowindowing: if qmax <= qmin, x domain of drawing is [my xmin, my xmax]. [minimum, maximum]: amplitude; y range of drawing. */ void PowerCepstrum_getMaximumAndQuefrency (PowerCepstrum me, double pitchFloor, double pitchCeiling, int interpolation, double *maximum, double *quefrency); // The standard of Hillenbrand with fitting options double PowerCepstrum_getPeakProminence_hillenbrand (PowerCepstrum me, double pitchFloor, double pitchCeiling, double *qpeak); double PowerCepstrum_getRNR (PowerCepstrum me, double pitchFloor, double pitchCeiling, double f0fractionalWidth); double PowerCepstrum_getPeakProminence (PowerCepstrum me, double pitchFloor, double pitchCeiling, int interpolation, double qstartFit, double qendFit, int lineType, int fitMethod, double *qpeak); void PowerCepstrum_fitTiltLine (PowerCepstrum me, double qmin, double qmax, double *slope, double *intercept, int lineType, int method); autoPowerCepstrum PowerCepstrum_subtractTilt (PowerCepstrum me, double qstartFit, double qendFit, int lineType, int fitMethod); void PowerCepstrum_subtractTilt_inline (PowerCepstrum me, double qstartFit, double qendFit, int lineType, int fitMethod); void PowerCepstrum_smooth_inline (PowerCepstrum me, double quefrencyAveragingWindow, long numberOfIterations); autoPowerCepstrum PowerCepstrum_smooth (PowerCepstrum me, double quefrencyAveragingWindow, long numberOfIterations); autoMatrix PowerCepstrum_to_Matrix (PowerCepstrum me); autoPowerCepstrum Matrix_to_PowerCepstrum (Matrix me); autoPowerCepstrum Matrix_to_PowerCepstrum_row (Matrix me, long row); autoPowerCepstrum Matrix_to_PowerCepstrum_column (Matrix me, long col); autoPowerCepstrum Cepstrum_downto_PowerCepstrum (Cepstrum me); #endif /* _Cepstrum_h_ */ praat-6.0.04/LPC/Cepstrum_and_Spectrum.cpp000066400000000000000000000132311261542461700203500ustar00rootroot00000000000000/* Cepstrum_and_Spectrum.cpp * * Copyright (C) 1994-2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020812 GPL header djmw 20041124 Changed call to Sound_to_Spectrum. djmw 20070103 Sound interface changes djmw 20080122 float -> double djmw 20121015 */ #include "Cepstrum_and_Spectrum.h" #include "NUM2.h" #include "Spectrum_extensions.h" #include "Sound_and_Spectrum.h" static autoCepstrum Spectrum_to_Cepstrum_cmplx (Spectrum me) { try { autoMatrix unwrap = Spectrum_unwrap (me); autoSpectrum sx = Data_copy (me); // Copy magnitude-squared and unwrapped phase. for (long i = 1; i <= my nx; i ++) { double xa = unwrap -> z[1][i]; sx -> z[1][i] = xa > 0.0 ? 0.5 * log (xa) : -300.0; sx -> z[2][i] = unwrap -> z[2][i]; } // Compute complex cepstrum x. autoSound x = Spectrum_to_Sound (sx.peek()); autoCepstrum thee = Cepstrum_create (x -> xmax - x -> xmin, x -> nx); NUMvector_copyElements (x -> z[1], thy z[1], 1, x -> nx); return thee; } catch (MelderError) { Melder_throw (me, U": no Cepstrum created."); } } autoPowerCepstrum Spectrum_to_PowerCepstrum (Spectrum me) { try { autoSpectrum dBspectrum = Data_copy (me); double *re = dBspectrum -> z[1], *im = dBspectrum -> z[2]; for (long i = 1; i <= dBspectrum -> nx; i ++) { re[i] = log (re[i] * re[i] + im[i] * im[i] + 1e-300); im[i] = 0.0; } autoSound cepstrum = Spectrum_to_Sound (dBspectrum.peek()); autoPowerCepstrum thee = PowerCepstrum_create (0.5 / my dx, my nx); for (long i = 1; i <= thy nx; i++) { double val = cepstrum -> z[1][i]; thy z[1][i] = val * val; } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Sound."); } } autoCepstrum Spectrum_to_Cepstrum (Spectrum me) { try { autoSpectrum dBspectrum = Data_copy (me); double *re = dBspectrum -> z[1], *im = dBspectrum -> z[2]; for (long i = 1; i <= dBspectrum -> nx; i++) { re[i] = log (re[i] * re[i] + im[i] * im[i] + 1e-300); im[i] = 0.0; } autoSound cepstrum = Spectrum_to_Sound (dBspectrum.peek()); autoCepstrum thee = Cepstrum_create (0.5 / my dx, my nx); for (long i = 1; i <= thy nx; i++) { double val = cepstrum -> z[1][i]; thy z[1][i] = val; } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Sound."); } } autoSpectrum Cepstrum_to_Spectrum (Cepstrum me) { //TODO power cepstrum try { autoCepstrum cepstrum = Data_copy (me); cepstrum -> z[1][1] = my z[1][1]; for (long i = 2; i <= cepstrum -> nx; i++) { cepstrum -> z[1][i] = 2 * my z[1][i]; } autoSpectrum thee = Sound_to_Spectrum ((Sound) cepstrum.peek(), 1); double *re = thy z[1], *im = thy z[2]; for (long i = 1; i <= thy nx; i ++) { re[i] = exp (0.5 * re[i]); // i.e., sqrt (exp(re [i])) im[i] = 0.0; } return thee; } catch (MelderError) { Melder_throw (me, U": no Spectrum created."); } } static autoCepstrum Spectrum_to_Cepstrum2 (Spectrum me) { try { autoNUMfft_Table fftTable; // originalNumberOfSamplesProbablyOdd irrelevant if (my x1 != 0.0) { Melder_throw (U"A Fourier-transformable Spectrum must have a first frequency of 0 Hz, not ", my x1, U" Hz."); } long numberOfSamples = 2 * my nx - 2; autoCepstrum thee = Cepstrum_create (0.5 / my dx, my nx); // my dx = 1 / (dT * N) = 1 / (duration of sound) thy dx = 1 / (my dx * numberOfSamples); // Cepstrum is on [-T/2, T/2] ! NUMfft_Table_init (&fftTable, numberOfSamples); autoNUMvector fftbuf (1, numberOfSamples); fftbuf[1] = my v_getValueAtSample (1, 0, 2); for (long i = 2; i < my nx; i++) { fftbuf [i + i - 2] = my v_getValueAtSample (i, 0, 2); fftbuf [i + i - 1] = 0.0; } fftbuf [numberOfSamples] = my v_getValueAtSample (my nx, 0, 2); NUMfft_backward (&fftTable, fftbuf.peek()); for (long i = 1; i <= my nx; i++) { double val = fftbuf[i] / numberOfSamples; // scaling 1/n because ifft(fft(1))= n; thy z[1][i] = val * val; // power cepstrum } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Cepstrum."); } } static autoSpectrum Cepstrum_to_Spectrum2 (Cepstrum me) { //TODO power cepstrum try { autoNUMfft_Table fftTable; long numberOfSamples = 2 * my nx - 2; autoNUMvector fftbuf (1, numberOfSamples); autoSpectrum thee = Spectrum_create (0.5 / my dx, my nx); fftbuf[1] = sqrt (my z[1][1]); for (long i = 2; i <= my nx; i++) { fftbuf[i] = 2.0 * sqrt (my z[1][i]); } // fftbuf[my nx+1 ... numberOfSamples] = 0 NUMfft_Table_init (&fftTable, numberOfSamples); NUMfft_forward (&fftTable, fftbuf.peek()); thy z[1][1] = fabs (fftbuf[1]); for (long i = 2; i < my nx; i++) { double br = fftbuf[i + i - 2], bi = fftbuf[i + i - 1]; thy z[1][i] = sqrt (br * br + bi * bi); } thy z[1][my nx] = fabs (fftbuf[numberOfSamples]); for (long i = 1; i <= my nx; i++) { thy z[1][i] = exp (NUMln10 * thy z[1][i] / 20.0) * 2e-5 / sqrt (2 * thy dx); thy z[2][i] = 0.0; } return thee; } catch (MelderError) { Melder_throw (me, U": no Spectrum created."); } } /* End of file Cepstrum_and_Spectrum.cpp */ praat-6.0.04/LPC/Cepstrum_and_Spectrum.h000066400000000000000000000021061261542461700200140ustar00rootroot00000000000000#ifndef _Cepstrum_and_Spectrum_h_ #define _Cepstrum_and_Spectrum_h_ /* Cepstrum_and_Spectrum.h * * Copyright (C) 1994-2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Spectrum.h" #include "Cepstrum.h" autoCepstrum Spectrum_to_Cepstrum (Spectrum me); autoSpectrum Cepstrum_to_Spectrum (Cepstrum me); autoPowerCepstrum Spectrum_to_PowerCepstrum (Spectrum me); #endif /* _Cepstrum_and_Spectrum_h_ */ praat-6.0.04/LPC/Cepstrumc.cpp000066400000000000000000000136261261542461700160170ustar00rootroot00000000000000/* Cepstrumc.c * * Copyright (C) 1994-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020812 GPL header djmw 20061218 Changed info to Melder_writeLine format. djmw 20071017 oo_CAN_WRITE_AS_ENCODING.h djmw 20080122 Version 1: float -> double djmw 20110304 Thing_new */ #include "Cepstrumc.h" #include "DTW.h" #include "oo_DESTROY.h" #include "Cepstrumc_def.h" #include "oo_COPY.h" #include "Cepstrumc_def.h" #include "oo_EQUAL.h" #include "Cepstrumc_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Cepstrumc_def.h" #include "oo_WRITE_TEXT.h" #include "Cepstrumc_def.h" #include "oo_WRITE_BINARY.h" #include "Cepstrumc_def.h" #include "oo_READ_TEXT.h" #include "Cepstrumc_def.h" #include "oo_READ_BINARY.h" #include "Cepstrumc_def.h" #include "oo_DESCRIPTION.h" #include "Cepstrumc_def.h" Thing_implement (Cepstrumc, Sampled, 1); void structCepstrumc :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U" Start time: ", xmin); MelderInfo_writeLine (U" End time: ", xmax); MelderInfo_writeLine (U" Number of frames: ", nx); MelderInfo_writeLine (U" Time step: ", dx); MelderInfo_writeLine (U" First frame at: ", x1); MelderInfo_writeLine (U" Number of coefficients: ", maxnCoefficients); } void Cepstrumc_Frame_init (Cepstrumc_Frame me, int nCoefficients) { my c = NUMvector (0, nCoefficients); my nCoefficients = nCoefficients; } void Cepstrumc_init (Cepstrumc me, double tmin, double tmax, long nt, double dt, double t1, int nCoefficients, double samplingFrequency) { my samplingFrequency = samplingFrequency; my maxnCoefficients = nCoefficients; Sampled_init (me, tmin, tmax, nt, dt, t1); my frame = NUMvector (1, nt); } autoCepstrumc Cepstrumc_create (double tmin, double tmax, long nt, double dt, double t1, int nCoefficients, double samplingFrequency) { try { autoCepstrumc me = Thing_new (Cepstrumc); Cepstrumc_init (me.peek(), tmin, tmax, nt, dt, t1, nCoefficients, samplingFrequency); return me; } catch (MelderError) { Melder_throw (U"Cepstrum not created."); } } static void regression (Cepstrumc me, long frame, double r[], long nr) { long nc = 1e6; double sumsq = 0; for (long i = 0; i <= my maxnCoefficients; i++) { r[i] = 0; } if (frame <= nr / 2 || frame >= my nx - nr / 2) { return; } for (long j = -nr / 2; j <= nr / 2; j++) { Cepstrumc_Frame f = & my frame[frame + j]; if (f->nCoefficients < nc) { nc = f->nCoefficients; } sumsq += j * j; } for (long i = 0; i <= nc; i++) { for (long j = -nr / 2; j <= nr / 2; j++) { Cepstrumc_Frame f = & my frame[frame + j]; r[i] += f->c[i] * j / sumsq / my dx; } } } autoDTW Cepstrumc_to_DTW (Cepstrumc me, Cepstrumc thee, double wc, double wle, double wr, double wer, double dtr, int matchStart, int matchEnd, int constraint) { try { long nr = (long) floor (dtr / my dx); if (my maxnCoefficients != thy maxnCoefficients) { Melder_throw (U"Cepstrumc orders must be equal."); } if (wr != 0 && nr < 2) { Melder_throw (U"Time window for regression coefficients too small."); } if (nr % 2 == 0) { nr++; } if (wr != 0) { Melder_casual (U"Number of frames used for regression coefficients ", nr); } autoDTW him = DTW_create (my xmin, my xmax, my nx, my dx, my x1, thy xmin, thy xmax, thy nx, thy dx, thy x1); autoNUMvector ri (0L, my maxnCoefficients); autoNUMvector rj (0L, my maxnCoefficients); // Calculate distance matrix autoMelderProgress progress (U""); for (long i = 1; i <= my nx; i++) { Cepstrumc_Frame fi = & my frame[i]; regression (me, i, ri.peek(), nr); for (long j = 1; j <= thy nx; j++) { Cepstrumc_Frame fj = & thy frame[j]; double d, dist = 0, distr = 0; if (wc != 0) { /* cepstral distance */ for (long k = 1; k <= fj -> nCoefficients; k++) { d = fi -> c[k] - fj -> c[k]; dist += d * d; } dist *= wc; } // log energy distance d = fi -> c[0] - fj -> c[0]; dist += wle * d * d; if (wr != 0) { // regression distance regression (thee, j, rj.peek(), nr); for (long k = 1; k <= fj -> nCoefficients; k++) { d = ri[k] - rj[k]; distr += d * d; } dist += wr * distr; } if (wer != 0) { // regression on c[0]: log(energy) if (wr == 0) { regression (thee, j, rj.peek(), nr); } d = ri[0] - rj[0]; dist += wer * d * d; } dist /= wc + wle + wr + wer; his z[i][j] = sqrt (dist); // prototype along y-direction } Melder_progress ( (double) i / my nx, U"Calculate distances: frame ", i, U" from ", my nx, U"."); } DTW_findPath (him.peek(), matchStart, matchEnd, constraint); return him; } catch (MelderError) { Melder_throw (U"DTW not created."); } } autoMatrix Cepstrumc_to_Matrix (Cepstrumc me) { try { autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, 0, my maxnCoefficients, my maxnCoefficients + 1, 1, 0); for (long i = 1; i <= my nx; i++) { Cepstrumc_Frame him = & my frame[i]; for (long j = 1; j <= his nCoefficients + 1; j++) { thy z[j][i] = his c[j - 1]; } } return thee; } catch (MelderError) { Melder_throw (me, U": no Matrix created."); } } /* End of file Cepstrumc.cpp */ praat-6.0.04/LPC/Cepstrumc.h000066400000000000000000000045041261542461700154570ustar00rootroot00000000000000#ifndef _Cepstrumc_h_ #define _Cepstrumc_h_ /* Cepstrumc.h * * Copyright (C) 1994-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19950822 djmw 20020812 GPL header djmw 20110306 Latest modification. */ #include "Sampled.h" #include "Matrix.h" #include "Graphics.h" #include "DTW.h" #include "Cepstrumc_def.h" oo_CLASS_CREATE (Cepstrumc, Sampled); void Cepstrumc_init (Cepstrumc me, double tmin, double tmax, long nt, double dt, double t1, int nCoefficients, double samplingFrequency); autoCepstrumc Cepstrumc_create (double tmin, double tmax, long nt, double dt, double t1, int nCoefficients, double samplingFrequency); /******************* Frames ************************************************/ void Cepstrumc_Frame_init (Cepstrumc_Frame me, int nCoefficients); autoDTW Cepstrumc_to_DTW ( Cepstrumc me, Cepstrumc thee, double wc, double wle, double wr, double wer, double dtr, int matchStart, int matchEnd, int constraint); /* 1. Calculate distances between Cepstra: Distance between frame i (from me) and j (from thee) is wc * d1 + wle * d2 + wr * d3 + wer * d4, where wc, wle, wr & wer are weights and d1 = Sum (k=1; k=nCoefficients; (c[i,k]-c[j,k])^2) d2 = (c[0,k]-c[0,k])^2 d3 = Sum (k=1; k=nCoefficients; (r[i,k]-r[j,k])^2), with r[i,k] the regression coefficient of the cepstral coefficients from the frames within a time span of 'dtr' seconds. c[i,j] is jth cepstral coefficient in frame i. d4 = regression on energy (c[0]) 2. Find optimum path through the distance matrix (see DTW). PRECONDITIONS: at least one of wc, wle, wr, wer != 0 */ autoMatrix Cepstrumc_to_Matrix (Cepstrumc me); #endif /* _Cepstrumc_h_ */ praat-6.0.04/LPC/Cepstrumc_def.h000066400000000000000000000027771261542461700163070ustar00rootroot00000000000000/* Cepstrumc_def.h * * Copyright (C) 1994-2008 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020812 GPL header djmw 20080122 Version 1: float -> double */ #define ooSTRUCT Cepstrumc_Frame oo_DEFINE_STRUCT (Cepstrumc_Frame) oo_INT (nCoefficients) #if oo_READING_BINARY if (formatVersion == 0) { oo_FLOAT_VECTOR_FROM (c, 0, nCoefficients) } else { oo_DOUBLE_VECTOR_FROM (c, 0, nCoefficients) } #else oo_DOUBLE_VECTOR_FROM (c, 0, nCoefficients) #endif oo_END_STRUCT (Cepstrumc_Frame) #undef ooSTRUCT #define ooSTRUCT Cepstrumc oo_DEFINE_CLASS (Cepstrumc, Sampled) oo_DOUBLE (samplingFrequency) /* from Sound */ oo_INT (maxnCoefficients) oo_STRUCT_VECTOR (Cepstrumc_Frame, frame, nx) #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (Cepstrumc) #undef ooSTRUCT /* End of file Cepstrumc_def.h */ praat-6.0.04/LPC/Formant_extensions.cpp000066400000000000000000000124221261542461700177300ustar00rootroot00000000000000/* Formant_extensions.c * * Copyright (C) 2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header */ #include "Formant_extensions.h" #include "NUM2.h" void Formant_formula (Formant me, double tmin, double tmax, long formantmin, long formantmax, Interpreter interpreter, char32 *expression) { try { long numberOfPossibleFormants = my maxnFormants; if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } if (formantmax >= formantmin) { formantmin = 1; formantmax = numberOfPossibleFormants; } formantmin = formantmin < 1 ? 1 : formantmin; formantmax = formantmax > numberOfPossibleFormants ? numberOfPossibleFormants : formantmax; autoMatrix fb = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, 1.0, 2 * numberOfPossibleFormants, 2 * numberOfPossibleFormants, 1.0, 1.0); for (long iframe = 1; iframe <= my nx; iframe ++) { Formant_Frame frame = & my d_frames [iframe]; int numberOfFormants = frame -> nFormants < numberOfPossibleFormants ? frame -> nFormants : numberOfPossibleFormants; for (long iformant = 1; iformant <= numberOfFormants; iformant++) { if (iformant <= frame -> nFormants) { fb -> z[2 * iformant - 1][iframe] = frame -> formant[iformant].frequency; fb -> z[2 * iformant ][iframe] = frame -> formant[iformant].bandwidth; } } } // Apply formula double ymin = 2.0 * formantmin - 1.0, ymax = 2.0 * formantmax; Matrix_formula_part (fb.peek(), tmin, tmax, ymin, ymax, expression, interpreter, nullptr); // Put results back in Formant long ixmin, ixmax, iymin, iymax; (void) Matrix_getWindowSamplesX (fb.peek(), tmin, tmax, & ixmin, & ixmax); (void) Matrix_getWindowSamplesY (fb.peek(), ymin, ymax, & iymin, & iymax); for (long iframe = ixmin; iframe <= ixmax; iframe++) { // if some of the formant frequencies are set to zero => remove the formant Formant_Frame frame = & my d_frames [iframe]; int numberOfFormants = frame -> nFormants < formantmax ? frame -> nFormants : formantmax; int iformantto = formantmin > 1 ? formantmin - 1 : 0; for (long iformant = formantmin; iformant <= numberOfFormants; iformant++) { double frequency = fb -> z[2 * iformant - 1][iframe]; double bandWidth = fb -> z[2 * iformant ][iframe]; if (frequency > 0 && bandWidth > 0) { iformantto++; frame -> formant[iformantto].frequency = frequency; frame -> formant[iformantto].bandwidth = bandWidth; } else { frame -> formant[iformant].frequency = frame -> formant[iformant].bandwidth = 0; } } // shift the (higher) formants down if necessary. for (long iformant = formantmax + 1; iformant <= frame -> nFormants; iformant++) { double frequency = fb -> z[2 * iformant - 1][iframe]; double bandWidth = fb -> z[2 * iformant ][iframe]; if (frequency > 0 && bandWidth > 0) { iformantto++; frame -> formant[iformantto].frequency = frequency; frame -> formant[iformantto].bandwidth = bandWidth; } else { frame -> formant[iformant].frequency = frame -> formant[iformant].bandwidth = 0; } } frame -> nFormants = iformantto; } } catch (MelderError) { Melder_throw (me, U": not filtered."); } } autoIntensityTier Formant_and_Spectrogram_to_IntensityTier (Formant me, Spectrogram thee, long iformant) { try { if (my xmin != thy xmin || my xmax != thy xmax) { Melder_throw (U"The start and end times of the Formant and the Spectrogram must be equal."); } if (iformant < 1 || iformant > my maxnFormants) { Melder_throw (U"Formant number not in range [1, ", my maxnFormants, U"]."); } autoIntensityTier him = IntensityTier_create (my xmin, my xmax); double previousValue = -80000.0; // can never occur double previousTime = my xmin; for (long iframe = 1; iframe <= my nx; iframe++) { Formant_Frame frame = & my d_frames [iframe]; long numberOfFormants = frame -> nFormants; double time = Sampled_indexToX (me, iframe); double value = 0; if (iformant <= numberOfFormants) { double f = frame -> formant[iformant].frequency; value = Matrix_getValueAtXY (thee, time, f); value = value == NUMundefined ? 0.0 : value; } value = 10.0 * log10 ((value + 1e-30) / 4.0e-10); /* dB / Hz */ if (value != previousValue) { if (iframe > 1 && previousTime < time - 1.5 * my dx) { // mark the end of the same interval RealTier_addPoint (him.peek(), time - my dx, previousValue); } RealTier_addPoint (him.peek(), time, value); previousTime = time; } previousValue = value; } return him; } catch (MelderError) { Melder_throw (U"IntensityTier not created from ", me, U" and ", thee, U"."); } } /* End of file Formant_extensions.cpp */ praat-6.0.04/LPC/Formant_extensions.h000066400000000000000000000023211261542461700173720ustar00rootroot00000000000000#ifndef _Formant_extensions_h_ #define _Formant_extensions_h_ /* Formant_extensions.h * * Copyright (C) 2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20121214 Initial version */ #include "Formant.h" #include "IntensityTier.h" #include "Spectrogram.h" void Formant_formula (Formant me, double tmin, double tmax, long formantmin, long formantmax, Interpreter interpreter, char32 *expression); autoIntensityTier Formant_and_Spectrogram_to_IntensityTier (Formant me, Spectrogram thee, long iformant); #endif /* _Formant_extensions_h_ */ praat-6.0.04/LPC/LPC.cpp000066400000000000000000000134551261542461700144700ustar00rootroot00000000000000/* LPC.cpp * * Copyright (C) 1994-2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020812 GPL header djmw 20030612 Removed LPC_Frame_free djmw 20060510 LPC_drawPoles error cleared if something goes wrong. djmw 20061212 Changed info to Melder_writeLine format. djmw 20071017 oo_CAN_WRITE_AS_ENCODING.h djmw 20080122 float -> double djmw 20081223 Corrected a bug in Matrix LPC_to_Matrix (last coefficient was not copied) djmw 20110304 Thing_new */ #include "LPC_and_Polynomial.h" #include "NUM2.h" #include "oo_DESTROY.h" #include "LPC_def.h" #include "oo_COPY.h" #include "LPC_def.h" #include "oo_EQUAL.h" #include "LPC_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "LPC_def.h" #include "oo_WRITE_TEXT.h" #include "LPC_def.h" #include "oo_WRITE_BINARY.h" #include "LPC_def.h" #include "oo_READ_TEXT.h" #include "LPC_def.h" #include "oo_READ_BINARY.h" #include "LPC_def.h" #include "oo_DESCRIPTION.h" #include "LPC_def.h" Thing_implement (LPC, Sampled, 1); void structLPC :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Time domain: ", xmin, U" to ", xmax, U" (s)."); MelderInfo_writeLine (U"Prediction order: ", maxnCoefficients); MelderInfo_writeLine (U"Number of frames: ", nx); MelderInfo_writeLine (U"Time step: ", dx, U" (s)."); MelderInfo_writeLine (U"First frame at: ", x1, U" (s)."); } void LPC_Frame_init (LPC_Frame me, int nCoefficients) { if (nCoefficients != 0) { my a = NUMvector (1, nCoefficients); } my nCoefficients = nCoefficients; } void LPC_init (LPC me, double tmin, double tmax, long nt, double dt, double t1, int predictionOrder, double samplingPeriod) { my samplingPeriod = samplingPeriod; my maxnCoefficients = predictionOrder; Sampled_init (me, tmin, tmax, nt, dt, t1); my d_frames = NUMvector (1, nt); } autoLPC LPC_create (double tmin, double tmax, long nt, double dt, double t1, int predictionOrder, double samplingPeriod) { try { autoLPC me = Thing_new (LPC); LPC_init (me.peek(), tmin, tmax, nt, dt, t1, predictionOrder, samplingPeriod); return me; } catch (MelderError) { Melder_throw (U"LPC not created."); } } void LPC_drawGain (LPC me, Graphics g, double tmin, double tmax, double gmin, double gmax, int garnish) { if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } long itmin, itmax; if (! Sampled_getWindowSamples (me, tmin, tmax, & itmin, & itmax)) { return; } autoNUMvector gain (itmin, itmax); for (long iframe = itmin; iframe <= itmax; iframe++) { gain[iframe] = my d_frames[iframe].gain; } if (gmax <= gmin) { NUMvector_extrema (gain.peek(), itmin, itmax, & gmin, & gmax); } if (gmax == gmin) { gmin = 0; gmax += 0.5; } Graphics_setInner (g); Graphics_setWindow (g, tmin, tmax, gmin, gmax); for (long iframe = itmin; iframe <= itmax; iframe++) { double x = Sampled_indexToX (me, iframe); Graphics_speckle (g, x, gain[iframe]); } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Time (seconds)"); Graphics_textLeft (g, true, U"Gain"); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); } } void LPC_drawPoles (LPC me, Graphics g, double time, int garnish) { autoPolynomial p = LPC_to_Polynomial (me, time); autoRoots r = Polynomial_to_Roots (p.peek()); Roots_draw (r.peek(), g, -1.0, 1.0, -1.0, 1.0, U"+", 12, garnish); } autoMatrix LPC_downto_Matrix_lpc (LPC me) { try { autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, 0.5, 0.5 + my maxnCoefficients, my maxnCoefficients, 1.0, 1.0); for (long j = 1; j <= my nx; j++) { LPC_Frame lpc = & my d_frames[j]; for (long i = 1; i <= lpc -> nCoefficients; i++) { thy z[i][j] = lpc -> a[i]; } } return thee; } catch (MelderError) { Melder_throw (me, U": no Matrix with linear prediction coefficients created."); } } autoMatrix LPC_downto_Matrix_rc (LPC me) { try { autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, 0.5, 0.5 + my maxnCoefficients, my maxnCoefficients, 1.0, 1.0); autoNUMvector rc (1, my maxnCoefficients); for (long j = 1; j <= my nx; j++) { LPC_Frame lpc = & my d_frames[j]; NUMlpc_lpc_to_rc (lpc -> a, lpc -> nCoefficients, rc.peek()); for (long i = 1; i <= lpc -> nCoefficients; i++) { thy z[i][j] = rc[i]; } } return thee; } catch (MelderError) { Melder_throw (me, U": no Matrix with relection coefficients created."); } } autoMatrix LPC_downto_Matrix_area (LPC me) { try { autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, 0.5, 0.5 + my maxnCoefficients, my maxnCoefficients, 1.0, 1.0); autoNUMvector rc (1, my maxnCoefficients); autoNUMvector area (1, my maxnCoefficients); for (long j = 1; j <= my nx; j++) { LPC_Frame lpc = & my d_frames[j]; NUMlpc_lpc_to_rc (lpc -> a, lpc -> nCoefficients, rc.peek()); NUMlpc_rc_to_area (rc.peek(), lpc -> nCoefficients, area.peek()); for (long i = 1; i <= lpc -> nCoefficients; i++) { thy z[i][j] = area[i]; } } return thee; } catch (MelderError) { Melder_throw (me, U": no Matrix with areas created."); } } /* End of file LPC.cpp */ praat-6.0.04/LPC/LPC.h000066400000000000000000000033041261542461700141250ustar00rootroot00000000000000#ifndef _LPC_h_ #define _LPC_h_ /* LPC.h * * Copyright (C) 1994-2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Matrix.h" #include "Graphics.h" #include "LPC_def.h" oo_CLASS_CREATE (LPC, Sampled); /* From Sampled: xmin, xmax : range of time (s) x1 : position of first frame (s) dx : step size (s) nx : number of frames */ void LPC_init (LPC me, double tmin, double tmax, long nt, double dt, double t1, int predictionOrder, double samplingPeriod); autoLPC LPC_create (double tmin, double tmax, long nt, double dt, double t1, int predictionOrder, double samplingPeriod); void LPC_drawGain (LPC me, Graphics g, double t1, double t2, double gmin, double gmax, int garnish); void LPC_drawPoles (LPC me, Graphics g, double time, int garnish); autoMatrix LPC_downto_Matrix_lpc (LPC me); autoMatrix LPC_downto_Matrix_rc (LPC me); autoMatrix LPC_downto_Matrix_area (LPC me); /******************* Frames ************************************************/ void LPC_Frame_init (LPC_Frame me, int nCoefficients); #endif /* _LPC_h_ */ praat-6.0.04/LPC/LPC_and_Cepstrumc.cpp000066400000000000000000000053461261542461700173370ustar00rootroot00000000000000/* LPC_and_Cepstrumc.cpp * * Copyright (C) 1994-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020812 GPL header djmw 20080122 float -> double */ /* LPC_and_Cepstrumc.c */ #include "LPC_and_Cepstrumc.h" void LPC_Frame_into_Cepstrumc_Frame (LPC_Frame me, Cepstrumc_Frame thee) { long n = my nCoefficients > thy nCoefficients ? thy nCoefficients : my nCoefficients; double *c = thy c, *a = my a; c[0] = 0.5 * log (my gain); if (n == 0) { return; } c[1] = -a[1]; for (long i = 2; i <= n; i++) { c[i] = 0; for (long k = 1; k < i; k++) { c[i] += a[i - k] * c[k] * k; } c[i] = -a[i] - c[i] / i; } } void Cepstrumc_Frame_into_LPC_Frame (Cepstrumc_Frame me, LPC_Frame thee) { double *c = my c, *a = thy a; thy gain = exp (2.0 * c[0]); if (thy nCoefficients == 0) { return; } a[1] = -c[1]; for (long i = 2; i <= thy nCoefficients; i++) { c[i] *= i; } for (long i = 2; i <= thy nCoefficients; i++) { a[i] = c[i]; for (long j = 1 ; j < i; j++) { a[i] += a[j] * c[i - j]; } a[i] /= -i; } for (long i = 2; i <= thy nCoefficients; i++) { c[i] /= i; } } autoCepstrumc LPC_to_Cepstrumc (LPC me) { try { autoCepstrumc thee = Cepstrumc_create (my xmin, my xmax, my nx, my dx, my x1, my maxnCoefficients, 1.0 / my samplingPeriod); for (long i = 1; i <= my nx; i++) { Cepstrumc_Frame_init (& thy frame[i], my d_frames[i].nCoefficients); LPC_Frame_into_Cepstrumc_Frame (& my d_frames[i], & thy frame[i]); } return thee; } catch (MelderError) { Melder_throw (me, U": no Cepstrum created."); } } autoLPC Cepstrumc_to_LPC (Cepstrumc me) { try { autoLPC thee = LPC_create (my xmin, my xmax, my nx, my dx, my x1, my maxnCoefficients, 1.0 / my samplingFrequency); for (long i = 1; i <= my nx; i++) { LPC_Frame_init (& thy d_frames[i], my frame[i].nCoefficients); Cepstrumc_Frame_into_LPC_Frame (& my frame[i], & thy d_frames[i]); } return thee; } catch (MelderError) { Melder_throw (me, U":no LPC created."); } } /* End of file LPC_and_Cepstrumc.cpp */ praat-6.0.04/LPC/LPC_and_Cepstrumc.h000066400000000000000000000023161261542461700167760ustar00rootroot00000000000000#ifndef _LPC_and_Cepstrumc_h_ #define _LPC_and_Cepstrumc_h_ /* LPC_and_Cepstrumc.h * * Copyright (C) 1994-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19950410 djmw 20020812 GPL header djmw 20110307 Latest modification */ #include "LPC.h" #include "Cepstrumc.h" autoCepstrumc LPC_to_Cepstrumc (LPC me); autoLPC Cepstrumc_to_LPC (Cepstrumc me); void LPC_Frame_into_Cepstrumc_Frame (LPC_Frame me, Cepstrumc_Frame thee); void Cepstrumc_Frame_into_LPC_Frame (Cepstrumc_Frame me, LPC_Frame thee); #endif /* _LPC_and_Cepstrumc_h_ */ praat-6.0.04/LPC/LPC_and_Formant.cpp000066400000000000000000000124301261542461700167700ustar00rootroot00000000000000/* LPC_and_Formant.cpp * * Copyright (C) 1994-2013, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20030616 Formant_Frame_into_LPC_Frame: remove formant with f >= Nyquist + change lpc indexing from -1..m djmw 20080122 float -> double */ #include "LPC_and_Formant.h" #include "LPC_and_Polynomial.h" #include "NUM2.h" void Formant_Frame_init (Formant_Frame me, long nFormants) { my nFormants = nFormants; if (nFormants > 0) { my formant = NUMvector (1, my nFormants); } } void Formant_Frame_scale (Formant_Frame me, double scale) { for (long i = 1; i <= my nFormants; i++) { my formant[i].frequency *= scale; my formant[i].bandwidth *= scale; } } void Roots_into_Formant_Frame (Roots me, Formant_Frame thee, double samplingFrequency, double margin) { long n = my max - my min + 1; autoNUMvector fc (1, n); autoNUMvector bc (1, n); // Determine the formants and bandwidths thy nFormants = 0; double fLow = margin, fHigh = samplingFrequency / 2 - margin; for (long i = my min; i <= my max; i++) { if (my v[i].im < 0) { continue; } double f = fabs (atan2 (my v[i].im, my v[i].re)) * samplingFrequency / 2.0 / NUMpi; if (f >= fLow && f <= fHigh) { /*b = - log (my v[i].re * my v[i].re + my v[i].im * my v[i].im) * samplingFrequency / 2 / NUMpi;*/ double b = - log (dcomplex_abs (my v[i])) * samplingFrequency / NUMpi; thy nFormants++; fc[thy nFormants] = f; bc[thy nFormants] = b; } } Formant_Frame_init (thee, thy nFormants); for (long i = 1; i <= thy nFormants; i++) { thy formant[i].frequency = fc[i]; thy formant[i].bandwidth = bc[i]; } } void LPC_Frame_into_Formant_Frame (LPC_Frame me, Formant_Frame thee, double samplingPeriod, double margin) { thy intensity = my gain; if (my nCoefficients == 0) { return; } autoPolynomial p = LPC_Frame_to_Polynomial (me); autoRoots r = Polynomial_to_Roots (p.peek()); Roots_fixIntoUnitCircle (r.peek()); Roots_into_Formant_Frame (r.peek(), thee, 1 / samplingPeriod, margin); } autoFormant LPC_to_Formant (LPC me, double margin) { try { double samplingFrequency = 1.0 / my samplingPeriod; long nmax = my maxnCoefficients, err = 0; long interval = nmax > 20 ? 1 : 10; if (nmax > 99) { Melder_throw (U"We cannot find the roots of a polynomial of order > 99."); } if (margin >= samplingFrequency / 4) { Melder_throw (U"Margin should be smaller than ", samplingFrequency / 4, U"."); } autoFormant thee = Formant_create (my xmin, my xmax, my nx, my dx, my x1, (nmax + 1) / 2); autoMelderProgress progress (U"LPC to Formant"); for (long i = 1; i <= my nx; i++) { Formant_Frame formant = & thy d_frames[i]; LPC_Frame lpc = & my d_frames[i]; // Initialisation of Formant_Frame is taken care of in Roots_into_Formant_Frame! try { LPC_Frame_into_Formant_Frame (lpc, formant, my samplingPeriod, margin); } catch (MelderError) { Melder_clearError(); err++; } if ( (interval == 1 || (i % interval) == 1)) { Melder_progress ( (double) i / my nx, U"LPC to Formant: frame ", i, U" out of ", my nx, U"."); } } Formant_sort (thee.peek()); if (err > 0) { Melder_warning (err, U" formant frames out of ", my nx, U" are suspect."); } return thee; } catch (MelderError) { Melder_throw (me, U": no Formant created."); } } void Formant_Frame_into_LPC_Frame (Formant_Frame me, LPC_Frame thee, double samplingPeriod) { long m = 2, n = 2 * my nFormants; if (my nFormants < 1) { return; } autoNUMvector lpc (-1, n); lpc[0] = 1; double nyquist = 2.0 / samplingPeriod; for (long i = 1; i <= my nFormants; i++) { double f = my formant[i].frequency; if (f > nyquist) { continue; } // D(z): 1 + p z^-1 + q z^-2 double r = exp (- NUMpi * my formant[i].bandwidth * samplingPeriod); double p = - 2 * r * cos (2 * NUMpi * f * samplingPeriod); double q = r * r; for (long j = m; j > 0; j--) { lpc[j] += p * lpc[j - 1] + q * lpc[j - 2]; } m += 2; } n = thy nCoefficients < n ? thy nCoefficients : n; for (long i = 1; i <= n ; i++) { thy a[i] = lpc[i]; } thy gain = my intensity; } autoLPC Formant_to_LPC (Formant me, double samplingPeriod) { try { autoLPC thee = LPC_create (my xmin, my xmax, my nx, my dx, my x1, 2 * my maxnFormants, samplingPeriod); for (long i = 1; i <= my nx; i++) { Formant_Frame f = & my d_frames[i]; LPC_Frame lpc = & thy d_frames[i]; long m = 2 * f -> nFormants; LPC_Frame_init (lpc, m); Formant_Frame_into_LPC_Frame (f, lpc, samplingPeriod); } return thee; } catch (MelderError) { Melder_throw (me, U": no LPC created."); } } /* End of file LPC_and_Formant.cpp */ praat-6.0.04/LPC/LPC_and_Formant.h000066400000000000000000000030051261542461700164330ustar00rootroot00000000000000#ifndef _LPC_and_Formant_h_ #define _LPC_and_Formant_h_ /* LPC_and_Formant.h * * Copyright (C) 1994-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20030524 GPL header djmw 20110307 Latest modification */ #include "LPC.h" #include "Polynomial.h" #include "Formant.h" autoFormant LPC_to_Formant (LPC me, double margin); autoLPC Formant_to_LPC (Formant me, double samplingPeriod); void LPC_Frame_into_Formant_Frame (LPC_Frame me, Formant_Frame thee, double samplingPeriod, double margin); void Formant_Frame_into_LPC_Frame (Formant_Frame me, LPC_Frame thee, double samplingPeriod); void Formant_Frame_scale (Formant_Frame me, double scale); void Roots_into_Formant_Frame (Roots me, Formant_Frame thee, double samplingFrequency, double margin); void Formant_Frame_init (Formant_Frame me, long nFormants); #endif /* _LPC_and_Formant_h_ */ praat-6.0.04/LPC/LPC_and_LFCC.cpp000066400000000000000000000060021261542461700160670ustar00rootroot00000000000000/* LPC_and_LFCC.cpp * * Copyright (C) 1994-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020812 GPL header djmw 20030205 Latest modifiation */ #include "LPC_and_LFCC.h" #include "NUM2.h" #define MIN(m,n) ((m) < (n) ? (m) : (n)) void LPC_Frame_into_CC_Frame (LPC_Frame me, CC_Frame thee) { double *c = thy c, *a = my a; thy c0 = 0.5 * log (my gain); if (my nCoefficients < 1) { return; } c[1] = -a[1]; for (long n = 2; n <= MIN (my nCoefficients, thy numberOfCoefficients); n++) { double s = 0; for (long k = 1; k < n; k++) { s += a[k] * c[n - k] * (n - k); } c[n] = -a[n] - s / n; } for (long n = my nCoefficients + 1; n <= thy numberOfCoefficients; n++) { double s = 0; for (long k = 1; k <= my nCoefficients; k++) { s += a[k] * c[n - k] * (n - k); } c[n] = - s / n; } } void CC_Frame_into_LPC_Frame (CC_Frame me, LPC_Frame thee) { long n = MIN (my numberOfCoefficients, thy nCoefficients); double *c = my c, *a = thy a; thy gain = exp (2.0 * my c0); if (n < 1) { return; } a[1] = -c[1]; for (long i = 2; i <= n; i++) { double ai = c[i] * i; for (long j = 1; j < i; j++) { ai += a[j] * c[i - j] * (i - j); } a[i] = -ai / i; } } autoLFCC LPC_to_LFCC (LPC me, long numberOfCoefficients) { try { if (numberOfCoefficients < 1) { numberOfCoefficients = my maxnCoefficients; } autoLFCC thee = LFCC_create (my xmin, my xmax, my nx, my dx, my x1, numberOfCoefficients, 0, 0.5 / my samplingPeriod); for (long i = 1; i <= my nx; i++) { CC_Frame_init (& thy frame[i], numberOfCoefficients); LPC_Frame_into_CC_Frame (& my d_frames[i], & thy frame[i]); } return thee; } catch (MelderError) { Melder_throw (me, U": no LFCC created."); } } autoLPC LFCC_to_LPC (LFCC me, long numberOfCoefficients) { try { if (numberOfCoefficients < 1) { numberOfCoefficients = my maximumNumberOfCoefficients; } numberOfCoefficients = MIN (numberOfCoefficients, my maximumNumberOfCoefficients); autoLPC thee = LPC_create (my xmin, my xmax, my nx, my dx, my x1, numberOfCoefficients, 0.5 / my fmax); for (long i = 1; i <= my nx; i++) { LPC_Frame_init (& thy d_frames[i], numberOfCoefficients); CC_Frame_into_LPC_Frame (& my frame[i], & thy d_frames[i]); } return thee; } catch (MelderError) { Melder_throw (me, U": no LPC created."); } } #undef MIN /* End of file LPC_and_LFCC.cpp */ praat-6.0.04/LPC/LPC_and_LFCC.h000066400000000000000000000034431261542461700155420ustar00rootroot00000000000000#ifndef _LPC_and_LFCC_h_ #define _LPC_and_LFCC_h_ /* LPC_and_LFCC.h * * Copyright (C) 1994-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20001228 djmw 20020812 GPL header djmw 20110307 Latest modification */ #include "LPC.h" #include "LFCC.h" autoLFCC LPC_to_LFCC (LPC me, long numberOfCoefficients); autoLPC LFCC_to_LPC (LFCC me, long numberOfCoefficients); void LPC_Frame_into_CC_Frame (LPC_Frame me, CC_Frame thee); /* Transformation of lp-coefficients to cepstral coefficients. The number of cepstral coefficients may be larger than the number of lp-coefficients (equation 5). Reference: Digital Signal Processing Committee (eds.), Programs for Digital Signal Processing, IEEE Press, 1979 (Formulas 4a, 4b, 4c and 5, page 4.3-2). */ void CC_Frame_into_LPC_Frame (CC_Frame me, LPC_Frame thee); /* Transformation of cepstral coefficients to lp-coefficients. The number of lp-coefficients can never exceed the number of cepstral coefficients. Reference: Digital Signal Processing Committee (eds.), Programs for Digital Signal Processing, IEEE Press, 1979 (page 4.3-6). */ #endif /* _LPC_and_LFCC_h_ */ praat-6.0.04/LPC/LPC_and_Polynomial.cpp000066400000000000000000000030101261542461700174770ustar00rootroot00000000000000/* LPC_and_Polynomial.cpp * * Copyright (C) 1994-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020812 GPL header */ #include "LPC_and_Polynomial.h" autoPolynomial LPC_Frame_to_Polynomial (LPC_Frame me) { long degree = (long) my nCoefficients; autoPolynomial thee = Polynomial_create (-1, 1, degree); for (long i = 1; i <= degree; i++) { thy coefficients[i] = my a[degree - i + 1]; } thy coefficients[degree + 1] = 1; return thee; } autoPolynomial LPC_to_Polynomial (LPC me, double time) { try { long iFrame = Sampled_xToIndex (me, time); if (iFrame < 1 || iFrame > my nx) { Melder_throw (U"invalid frame number."); } autoPolynomial thee = LPC_Frame_to_Polynomial (&my d_frames[iFrame]); return thee; } catch (MelderError) { Melder_throw (me, U":no Polynomial created."); } } /* End of file LPC_and_Polynomial.cpp */ praat-6.0.04/LPC/LPC_and_Polynomial.h000066400000000000000000000021311261542461700171470ustar00rootroot00000000000000#ifndef _LPC_and_Polynomial_h_ #define _LPC_and_Polynomial_h_ /* LPC_and_Polynomial.h * * Copyright (C) 1994-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19990607 djmw 20020812 GPL header djmw 20110307 Latest modification */ #include "LPC.h" #include "Polynomial.h" autoPolynomial LPC_to_Polynomial (LPC me, double t); autoPolynomial LPC_Frame_to_Polynomial (LPC_Frame me); #endif /* _LPC_and_Polynomial_h_ */ praat-6.0.04/LPC/LPC_and_Tube.cpp000066400000000000000000000212351261542461700162640ustar00rootroot00000000000000/* LPC_and_Tube.cpp * * Copyright (C) 1993-2012, 2014-2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020612 GPL header djmw 20041020 struct Tube_Frame -> struct structTube_Frame; struct LPC_Frame -> struct structLPC_Frame; struct Formant_Frame->struct structFormant_Frame djmw 20051005 Always make a VocalTract with length 0.01 m when wakita_length==NUMundefined. */ #include "LPC_and_Tube.h" #include "LPC_and_Formant.h" #include "LPC_to_Spectrum.h" #include "SpectrumTier.h" #include "VocalTract_to_Spectrum.h" #include "NUM2.h" // IEEE: Programs fo digital signal processing section 4.3 LPTRN void LPC_Frame_into_Tube_Frame_rc (LPC_Frame me, Tube_Frame thee) { long p = my nCoefficients; Melder_assert (p <= thy nSegments); //TODO autoNUMvector b (1, p); autoNUMvector a (1, p); for (long i = 1; i <= p; i++) { a[i] = my a[i]; } double *rc = thy c; for (long m = p; m > 0; m--) { rc[m] = a[m]; if (fabs (rc[m]) > 1) { Melder_throw (U"Relection coefficient [", m, U"] larger 1."); // TODO kan er geen Tube worden gemaakt? } for (long i = 1; i < m; i++) { b[i] = a[i]; } for (long i = 1; i < m; i++) { a[i] = (b[i] - rc[m] * b[m - i]) / (1.0 - rc[m] * rc[m]); } } } void LPC_Frame_into_Tube_Frame_area (LPC_Frame me, Tube_Frame thee) { struct structTube_Frame rc_struct = { 0 }; Tube_Frame rc = & rc_struct; Tube_Frame_init (rc, my nCoefficients, thy length); LPC_Frame_into_Tube_Frame_rc (me, rc); Tube_Frames_rc_into_area (rc, thee); rc -> destroy (); } double VocalTract_and_LPC_Frame_getMatchingLength (VocalTract me, LPC_Frame thee, double glottalDamping, bool radiationDamping, bool internalDamping) { try { // match the average distance between the first two formants in the VocaTract and the LPC spectrum long numberOfFrequencies = 1000; double maximumFrequency = 5000.0; autoSpectrum vts = VocalTract_to_Spectrum (me, numberOfFrequencies, maximumFrequency, glottalDamping, radiationDamping, internalDamping); double samplingFrequency = 1000.0 * my nx; autoSpectrum lps = Spectrum_create (0.5 * samplingFrequency, numberOfFrequencies); LPC_Frame_into_Spectrum (thee, lps.peek(), 0, 50); autoSpectrumTier vtst = Spectrum_to_SpectrumTier_peaks (vts.peek()); autoSpectrumTier lpst = Spectrum_to_SpectrumTier_peaks (lps.peek()); double vt_f1 = vtst -> point(1) -> number, vt_f2 = vtst -> point(2) -> number; double lp_f1 = lpst -> point(1) -> number, lp_f2 = lpst -> point(2) -> number; double df1 = lp_f1 - vt_f1, df2 = lp_f2 - vt_f2, df = 0.5 * (df1 + df2); double dl = - df / lp_f2; return my dx * my nx * (1 + dl); } catch (MelderError) { Melder_throw (U"Length could not be determined from VocalTract and LPC_Frame."); } } double LPC_Frame_getVTL_wakita (LPC_Frame me, double samplingPeriod, double refLength) { struct structLPC_Frame lpc_struct; LPC_Frame lpc = & lpc_struct; struct structFormant_Frame f_struct; Formant_Frame f = & f_struct; struct structTube_Frame rc_struct, af_struct; Tube_Frame rc = & rc_struct, af = & af_struct; try { long m = my nCoefficients; double length, dlength = 0.001, wakita_length = NUMundefined; double varMin = 1e308; memset (& lpc_struct, 0, sizeof (lpc_struct)); memset (& f_struct, 0, sizeof (f_struct)); memset (& rc_struct, 0, sizeof (rc_struct)); memset (& af_struct, 0, sizeof (af_struct)); LPC_Frame_init (lpc, m); Tube_Frame_init (rc, m, refLength); Tube_Frame_init (af, m, refLength); // Step 2 LPC_Frame_into_Formant_Frame (me, f, samplingPeriod, 0); // LPC_Frame_into_Formant_Frame performs the Formant_Frame_init !! if (f -> nFormants < 1) { Melder_throw (U"Not enough formants."); } double *area = af -> c; double lmin = length = 0.10; double plength = refLength; while (length <= 0.25) { // Step 3 double fscale = plength / length; for (long i = 1; i <= f -> nFormants; i++) { f -> formant[i].frequency *= fscale; f -> formant[i].bandwidth *= fscale; } /* 20000125: Bovenstaande schaling van f1/b1 kan ook gedaan worden door MGfb_to_a (f, b, nf, samplingFrequency*length/refLength, a1) De berekening is extreem gevoelig voor de samplefrequentie: een zelfde stel f,b waardes geven andere lengtes afhankelijk van Fs. Ook het weglaten van een hogere formant heeft consekwenties. De refLength zou eigenlijk vast moeten liggen op refLength=c*aantalFormanten/Fs waarbij c=340 m/s (geluidssnelheid). Bij Fs=10000 zou aantalFormanten=5 zijn en refLength -> 0.17 m */ // step 4 Formant_Frame_into_LPC_Frame (f, lpc, samplingPeriod); // step 5 rc -> length = length; LPC_Frame_into_Tube_Frame_rc (lpc, rc); // step 6.1 Tube_Frames_rc_into_area (rc, af); // step 6.2 Log(areas) double logSum = 0.0; for (long i = 1; i <= af -> nSegments; i++) { area[i] = log (area[i]); logSum += area[i]; } // step 6.3 and 7 double var = 0.0; for (long i = 1; i <= af -> nSegments; i++) { double delta = area[i] - logSum / af -> nSegments; var += delta * delta; } if (var < varMin) { lmin = length; varMin = var; } plength = length; length += dlength; } wakita_length = lmin; f -> destroy (); lpc -> destroy (); rc -> destroy (); af -> destroy (); return wakita_length; } catch (MelderError) { f -> destroy (); lpc -> destroy (); rc -> destroy (); af -> destroy (); return NUMundefined; } } int Tube_Frame_into_LPC_Frame_area (Tube_Frame me, LPC_Frame thee) { (void) me; (void) thee; return 0; } int Tube_Frame_into_LPC_Frame_rc (Tube_Frame me, LPC_Frame thee) { (void) me; (void) thee; return 0; } void VocalTract_setLength (VocalTract me, double newLength) { my xmax = newLength; my dx = newLength / my nx; my x1 = 0.5 * my dx; } autoVocalTract LPC_to_VocalTract (LPC me, double time, double glottalDamping, bool radiationDamping, bool internalDamping) { try { long iframe = Sampled_xToLowIndex (me, time); // ppgb: BUG? Is rounding down the correct thing to do? not nearestIndex? if (iframe < 1) { iframe = 1; } if (iframe > my nx) { iframe = my nx; } LPC_Frame lpc = & my d_frames[iframe]; autoVocalTract thee = LPC_Frame_to_VocalTract (lpc, 0.17); double length = VocalTract_and_LPC_Frame_getMatchingLength (thee.peek(), lpc, glottalDamping, radiationDamping, internalDamping); VocalTract_setLength (thee.peek(), length); return thee; } catch (MelderError) { Melder_throw (me, U": no VocalTract created."); } } static autoVocalTract LPC_Frame_to_VocalTract2 (LPC_Frame me, double length) { struct structTube_Frame area_struct = { 0 }; Tube_Frame area = & area_struct; try { long m = my nCoefficients; Tube_Frame_init (area, m, length); LPC_Frame_into_Tube_Frame_area (me, area); autoVocalTract thee = VocalTract_create (m, area -> length / m); // area[lips..glottis] (m^2) to VocalTract[glottis..lips] (m^2) for (long i = 1; i <= m; i++) { thy z[1][i] = area -> c[m + 1 - i]; } area -> destroy (); return thee; } catch (MelderError) { area -> destroy (); Melder_throw (U"No VocalTract created from LPC_Frame."); } } autoVocalTract LPC_Frame_to_VocalTract (LPC_Frame me, double length) { try { long m = my nCoefficients; autoNUMvector area (1, m + 1); NUMlpc_lpc_to_area (my a, m, area.peek()); autoVocalTract thee = VocalTract_create (m, length / m); // area[lips..glottis] (m^2) to VocalTract[glottis..lips] (m^2) for (long i = 1; i <= m; i++) { thy z[1][i] = area[m + 1 - i]; } return thee; } catch (MelderError) { Melder_throw (U"No VocalTract created from LPC_Frame."); } } autoVocalTract LPC_to_VocalTract (LPC me, double time, double length) { try { long iframe = Sampled_xToLowIndex (me, time); // ppgb: BUG? Is rounding down the correct thing to do? if (iframe < 1) { iframe = 1; } if (iframe > my nx) { iframe = my nx; } LPC_Frame lpc = & my d_frames[iframe]; autoVocalTract thee = LPC_Frame_to_VocalTract (lpc, length); return thee; } catch (MelderError) { Melder_throw (me, U": no VocalTract created."); } } /* End of file LPC_and_Tube.cpp */ praat-6.0.04/LPC/LPC_and_Tube.h000066400000000000000000000034371261542461700157350ustar00rootroot00000000000000#ifndef _LPC_and_Tube_h_ #define _LPC_and_Tube_h_ /* LPC_and_Tube.h * * Copyright (C) 1994-2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20030612 GPL header djmw 20110307 Latest modification */ #include "LPC.h" #include "Tube.h" #include "VocalTract.h" void LPC_Frame_into_Tube_Frame_rc (LPC_Frame me, Tube_Frame thee); void LPC_Frame_into_Tube_Frame_area (LPC_Frame me, Tube_Frame thee); autoVocalTract LPC_Frame_to_VocalTract (LPC_Frame me, double length); double LPC_Frame_getVTL_wakita (LPC_Frame me, double samplingPeriod, double refLength); double VocalTract_and_LPC_Frame_getMatchingLength (VocalTract me, LPC_Frame thee, double glottalDamping, bool radiationDamping, bool internalDamping); int Tube_Frame_into_LPC_Frame_area (Tube_Frame me, LPC_Frame thee); int Tube_Frame_into_LPC_Frame_rc (Tube_Frame me, LPC_Frame thee); autoVocalTract LPC_to_VocalTract (LPC me, double time, double length); void VocalTract_setLength (VocalTract me, double newLength); autoVocalTract LPC_to_VocalTract (LPC me, double time, double glottalDamping, bool radiationDamping, bool internalDamping); #endif /* _LPC_and_Tube_h_ */ praat-6.0.04/LPC/LPC_def.h000066400000000000000000000026671261542461700147560ustar00rootroot00000000000000/* LPC_def.h * * Copyright (C) 1994-2008 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT LPC_Frame oo_DEFINE_STRUCT (LPC_Frame) oo_INT (nCoefficients) #if oo_READING_BINARY if (formatVersion == 0) { oo_FLOAT_VECTOR (a, nCoefficients) oo_FLOAT (gain) } else { oo_DOUBLE_VECTOR (a, nCoefficients) oo_DOUBLE (gain) } #else oo_DOUBLE_VECTOR (a, nCoefficients) oo_DOUBLE (gain) #endif oo_END_STRUCT (LPC_Frame) #undef ooSTRUCT #define ooSTRUCT LPC oo_DEFINE_CLASS (LPC, Sampled) /* samplingPeriod */ oo_DOUBLE (samplingPeriod) /* from Sound */ oo_INT (maxnCoefficients) oo_STRUCT_VECTOR (LPC_Frame, d_frames, nx) #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (LPC) #undef ooSTRUCT /* End of file LPC_def.h */ praat-6.0.04/LPC/LPC_to_Spectrogram.cpp000066400000000000000000000036151261542461700175350ustar00rootroot00000000000000/* LPC_to_Spectrogram.cpp * * Copyright (C) 1994-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020812 GPL header djmw 20080122 float -> double */ #include "LPC_to_Spectrogram.h" autoSpectrogram LPC_to_Spectrogram (LPC me, double dfMin, double bandwidthReduction, double deEmphasisFrequency) { try { double samplingFrequency = 1.0 / my samplingPeriod; long nfft = 2; if (dfMin <= 0) { nfft = 512; dfMin = samplingFrequency / nfft; } while (samplingFrequency / nfft > dfMin || nfft <= my maxnCoefficients) { nfft *= 2; } double freqStep = samplingFrequency / nfft; autoSpectrogram thee = Spectrogram_create (my xmin, my xmax, my nx, my dx, my x1, 0.0, samplingFrequency / 2.0, nfft / 2 + 1, freqStep, 0.0); for (long i = 1; i <= my nx; i++) { double t = Sampled_indexToX (me, i); autoSpectrum spec = LPC_to_Spectrum (me, t, dfMin, bandwidthReduction, deEmphasisFrequency); for (long j = 1; j <= spec -> nx; j++) { double re = spec -> z[1][j], im = spec -> z[2][j]; thy z[j][i] = re * re + im * im; } } return thee; } catch (MelderError) { Melder_throw (me, U": no Spectrogram created."); } } /* End of file LPC_to_Spectrogram.cpp */ praat-6.0.04/LPC/LPC_to_Spectrogram.h000066400000000000000000000022761261542461700172040ustar00rootroot00000000000000#ifndef _LPC_to_Spectrogram_h_ #define _LPC_to_Spectrogram_h_ /* LPC_to_Spectrogram.h * * Copyright (C) 1994-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19980322 djmw 20020812 GPL header djmw 20110307 Latest modification */ #include "LPC.h" #include "Spectrogram.h" #include "LPC_to_Spectrum.h" autoSpectrogram LPC_to_Spectrogram (LPC me, double dfMin, double bandwidthReduction, double deEmphasisFrequency); /* if(dfMin >= 0) df <= dfMin else df = NyquistFrequency / 512 */ #endif /* _LPC_and_Spectrogram_h_ */ praat-6.0.04/LPC/LPC_to_Spectrum.cpp000066400000000000000000000076651261542461700170620ustar00rootroot00000000000000/* LPC_to_Spectrum.cpp * * Copyright (C) 1994-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020529 GPL header djmw 20020529 Changed NUMrealft to NUMforwardRealFastFourierTransform_f djmw 20030708 Added NUM2.h djmw 20080122 float -> double */ #include "LPC_to_Spectrum.h" #include "NUM2.h" /* PSD(f) = (sigma^2 T) /|1 + Sum (k=1..p, a[k] exp(-2 pi i f k T))|^2, where sigma^2 == gain, T is samplinginterval LPC-spectrum is approximately 20 dB too high (w.r.t. 25 ms spectrum from Sound) */ void LPC_Frame_into_Spectrum (LPC_Frame me, Spectrum thee, double bandwidthReduction, double deEmphasisFrequency) { if (my nCoefficients == 0) { for (long i = 1; i <= thy nx; i++) { thy z[1][i] = thy z[2][i] = 0.0; } return; } // When deEmphasisFrequency is effective we need 1 extra position in the fftbuffer. long nfft = 2 * (thy nx - 1), ndata = my nCoefficients + 1; double scale = 1.0 / sqrt (2.0 * thy xmax * thy dx); if (ndata >= nfft - 1 && (deEmphasisFrequency < thy xmax || ndata > nfft)) { Melder_throw (U"Spectrum size not large enough."); } autoNUMvector fftbuffer (1, nfft); // Copy 1, a[1], ... a[p] into fftbuffer fftbuffer[1] = 1; for (long i = 2; i <= ndata; i++) { fftbuffer[i] = my a[i - 1]; } if (deEmphasisFrequency < thy xmax) { // Multiply (1, a[1] z^-1, ... a[p] z^-p) by (1 - b z^-1) double b = exp (- 2.0 * NUMpi * deEmphasisFrequency / thy xmax); ndata ++; for (long i = ndata; i > 1; i--) { fftbuffer[i] -= b * fftbuffer[i - 1]; } } /* Calculate sum (k=0..ndata; a[k] (z)^-k) along a contour with radius r: sum (k=0..ndata; a[k] (rz)^-k) = sum (k=0..ndata; (a[k]r^-k) z^-k) */ double g = exp (NUMpi * bandwidthReduction / (thy dx * nfft)); /* r = 1/g */ for (long i = 2; i <= ndata; i++) { fftbuffer[i] *= pow (g, i - 1); } /* Perform the fft. The LPC spectrum is obtained by inverting this spectrum. The imaginary parts of the frequencies 0 and Nyquist are 0. */ NUMforwardRealFastFourierTransform (fftbuffer.peek(), nfft); if (my gain > 0) { scale *= sqrt (my gain); } thy z[1][1] = scale / fftbuffer[1]; thy z[2][1] = 0; for (long i = 2; i <= nfft / 2; i++) { // We use: 1 / (a + ib) = (a - ib) / (a^2 + b^2) double re = fftbuffer[i + i - 1], im = fftbuffer[i + i]; double invSquared = scale / (re * re + im * im); thy z[1][i] = re * invSquared; thy z[2][i] = -im * invSquared; } thy z[1][thy nx] = scale / fftbuffer[2]; thy z[2][thy nx] = 0; } autoSpectrum LPC_to_Spectrum (LPC me, double t, double dfMin, double bandwidthReduction, double deEmphasisFrequency) { try { double samplingFrequency = 1.0 / my samplingPeriod; long nfft = 2, index = Sampled_xToNearestIndex (me, t); if (index < 1) { index = 1; } if (index > my nx) { index = my nx; } if (dfMin <= 0) { nfft = 512; dfMin = samplingFrequency / nfft; } while (samplingFrequency / nfft > dfMin || nfft <= my d_frames[index].nCoefficients) { nfft *= 2; } autoSpectrum thee = Spectrum_create (samplingFrequency / 2.0, nfft / 2 + 1); LPC_Frame_into_Spectrum (& my d_frames[index], thee.peek(), bandwidthReduction, deEmphasisFrequency); return thee; } catch (MelderError) { Melder_throw (me, U": no Spectrum created."); } } /* End of file LPC_to_Spectrum.cpp */ praat-6.0.04/LPC/LPC_to_Spectrum.h000066400000000000000000000026731261542461700165210ustar00rootroot00000000000000#ifndef _LPC_to_Spectrum_h_ #define _LPC_to_Spectrum_h_ /* LPC_to_Spectrum.h * * Copyright (C) 1994-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19980224 djmw 20020812 GPL header djmw 20110702 Latest modification */ #include "LPC.h" #include "Spectrum.h" void LPC_Frame_into_Spectrum (LPC_Frame me, Spectrum thee, double bandwidthReduction, double deEmphasisFrequency); autoSpectrum LPC_to_Spectrum (LPC me, double t, double dfMin, double bandwidthReduction, double deEmphasisFrequency); autoSpectrum LPC_to_Spectrum2 (LPC me, double t, double dfMin, double bandwidthReduction); /* if(dfMin >= 0) df <= dfMin else df = NyquistFrequency / 512 */ /* integration radius r = exp (- pi * bandwidthReduction / samplingFrequency) */ #endif /* _LPC_and_Spectrum_h_ */ praat-6.0.04/LPC/Makefile000066400000000000000000000014471261542461700150040ustar00rootroot00000000000000# Makefile of the library "LPC" # David Weenink, 20130826 include ../makefile.defs CPPFLAGS = -I ../num -I ../dwtools -I ../fon -I ../sys -I ../dwsys -I ../stat OBJECTS = Cepstrum.o Cepstrumc.o Cepstrum_and_Spectrum.o \ Cepstrogram.o \ Formant_extensions.o \ LPC.o LPC_and_Cepstrumc.o LPC_and_Formant.o LPC_and_LFCC.o \ LPC_and_Polynomial.o \ LPC_to_Spectrum.o LPC_to_Spectrogram.o \ LPC_and_Tube.o \ Sound_and_LPC.o Sound_and_LPC_robust.o \ Sound_and_Cepstrum.o Tube.o \ VocalTractTier.o \ praat_LPC_init.o manual_LPC.o .PHONY: all clean all: libLPC.a clean: $(RM) $(OBJECTS) $(RM) libLPC.a libLPC.a: $(OBJECTS) touch libLPC.a rm libLPC.a $(AR) cq libLPC.a $(OBJECTS) $(RANLIB) libLPC.a $(OBJECTS): *.h ../num/NUM.h ../dwtools/*.h ../fon/*.h ../sys/*.h ../dwsys/*.h ../stat/*.h praat-6.0.04/LPC/Sound_and_Cepstrum.cpp000066400000000000000000000067541261542461700176520ustar00rootroot00000000000000/* Sound_and_Cepstrum.cpp * * Copyright (C) 1994-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020516 GPL header djmw 20020529 changed NUMrealft to NUM...RealFastFourierTransform_f djmw 20041124 Changed call to Sound_to_Spectrum. */ #include "Sound_and_Cepstrum.h" #include "Sound_and_Spectrum.h" #include "Cepstrum_and_Spectrum.h" #include "NUM2.h" /* Algorithm: J.B. Bednar & T.L. Watt (1985), Calculating the Complex Cepstrum without Phase Unwrapping or Integration, IEEE Trans. on ASSP 33, 1014-1017 (Does not work yet). */ autoCepstrum Sound_to_Cepstrum_bw (Sound me) { try { long nfft = 2; while (nfft < my nx) { nfft *= 2; } double qmax = (my xmax - my xmin) * nfft / my nx; autoCepstrum thee = Cepstrum_create (qmax, nfft); autoNUMvector x (1, nfft); autoNUMvector nx (1, nfft); for (long i = 1; i <= my nx; i++) { x[i] = my z[1][i]; nx[i] = (i - 1) * x[i]; } // Step 1: Fourier transform x(n) -> X(f) // and n*x(n) -> NX(f) NUMforwardRealFastFourierTransform (x.peek() , nfft); NUMforwardRealFastFourierTransform (nx.peek(), nfft); // Step 2: Multiply {X^*(f) * NX(f)} / |X(f)|^2 // Compute Avg (ln |X(f)|) as Avg (ln |X(f)|^2) / 2. // Treat i=1 separately: x[1] * nx[1] / |x[1]|^2 double lnxa = 0.0; if (x[1] != 0.0) { lnxa = 2.0 * log (fabs (x[1])); x[1] = nx[1] / x[1]; } if (x[2] != 0.0) { lnxa = 2.0 * log (fabs (x[2])); x[2] = nx[2] / x[2]; } for (long i = 3; i < nfft; i += 2) { double xr = x[i], nxr = nx[i]; double xi = x[i + 1], nxi = nx[i + 1]; double xa = xr * xr + xi * xi; if (xa > 0.0) { x[i] = (xr * nxr + xi * nxi) / xa; x[i + 1] = (xr * nxi - xi * nxr) / xa; lnxa += log (xa); } else { x[i] = x[i + 1] = 0.0; } } lnxa /= 2.0 * nfft / 2.0; // TODO // Step 4: Inverse transform of complex array x // results in: n * xhat (n) NUMreverseRealFastFourierTransform (x.peek(), nfft); // Step 5: Inverse fft-correction factor: 1/nfftd2 // Divide n * xhat (n) by n for (long i = 2; i <= my nx; i++) { thy z[1][i] = x[i] / ( (i - 1) * nfft); } // Step 6: xhat[0] = Avg (ln |X(f)|) thy z[1][1] = lnxa; return thee; } catch (MelderError) { Melder_throw (me, U": no Cepstrum created."); } } /* Zijn nog niet elkaars inverse!!!!*/ autoCepstrum Sound_to_Cepstrum (Sound me) { try { autoSpectrum spectrum = Sound_to_Spectrum (me, true); autoCepstrum thee = Spectrum_to_Cepstrum (spectrum.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": no Cepstrum calculated."); } } autoSound Cepstrum_to_Sound (Cepstrum me) { try { autoSpectrum sx = Cepstrum_to_Spectrum (me); autoSound thee = Spectrum_to_Sound (sx.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": no Sound calculated."); } } /* End of file Sound_and_Cepstrum.cpp */ praat-6.0.04/LPC/Sound_and_Cepstrum.h000066400000000000000000000021421261542461700173020ustar00rootroot00000000000000#ifndef _Sound_and_Cepstrum_h_ #define _Sound_and_Cepstrum_h_ /* Sound_and_Cepstrum.h * * Copyright (C) 1994-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020812 GPL header djmw 20110307 Latest modification */ #include "Sound.h" #include "Cepstrum.h" autoCepstrum Sound_to_Cepstrum (Sound me); autoCepstrum Sound_to_Cepstrum_bw (Sound me); autoSound Cepstrum_to_Sound (Cepstrum me); #endif /* _Sound_and_Cepstrum_h_ */ praat-6.0.04/LPC/Sound_and_LPC.cpp000066400000000000000000000440431261542461700164570ustar00rootroot00000000000000/* Sound_and_LPC.cpp * * Copyright (C) 1994-2013, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020625 GPL header djmw corrected a bug in Sound_into_LPC_Frame_marple that could crash praat when signal has only zero samples. djmw 20040303 Removed warning in Sound_to_LPC. djmw 20070103 Sound interface changes djmw 20080122 float -> double djmw 20101009 Filter and inverseFilter with one frame. */ #include "Sound_and_LPC.h" #include "Sound_extensions.h" #include "Vector.h" #include "Spectrum.h" #include "NUM2.h" #define LPC_METHOD_AUTO 1 #define LPC_METHOD_COVAR 2 #define LPC_METHOD_BURG 3 #define LPC_METHOD_MARPLE 4 /* Markel&Gray, LP of S, page 219 work[1..3*m+2] r = & work[1]; // r[1..m+1] a= & work[m+1+1]; // a[1..m+1] rc = & work[m+1+m+1+1]; // rc[1..m] for (i=1; i<= m+1+m+1+m;i++) work[i] = 0; */ #define LPC_METHOD_AUTO_WINDOW_CORRECTION 1 static void LPC_Frame_and_Sound_filter (LPC_Frame me, Sound thee, int channel) { double *y = thy z[channel], *a = my a; for (long i = 1; i <= thy nx; i++) { long m = i > my nCoefficients ? my nCoefficients : i - 1; for (long j = 1; j <= m; j++) { y[i] -= a[j] * y[i - j]; } } } void LPC_Frame_and_Sound_filterInverse (LPC_Frame me, Sound thee, int channel) { double *x = thy z[channel]; autoNUMvector y (0L, my nCoefficients); for (long i = 1; i <= thy nx; i++) { y[0] = x[i]; for (long j = 1; j <= my nCoefficients; j++) { x[i] += my a[j] * y[j]; } for (long j = my nCoefficients; j > 0; j--) { y[j] = y[j - 1]; } } } static int Sound_into_LPC_Frame_auto (Sound me, LPC_Frame thee) { long i = 1; // For error condition at end long m = thy nCoefficients; autoNUMvector r (1, m + 1); autoNUMvector a (1, m + 1); autoNUMvector rc (1, m); double *x = my z[1]; for (i = 1; i <= m + 1; i++) { for (long j = 1; j <= my nx - i + 1; j++) { r[i] += x[j] * x[j + i - 1]; } } if (r[1] == 0.0) { i = 1; /* ! */ goto end; } a[1] = 1; a[2] = rc[1] = - r[2] / r[1]; thy gain = r[1] + r[2] * rc[1]; for (i = 2; i <= m; i++) { double s = 0.0; for (long j = 1; j <= i; j++) { s += r[i - j + 2] * a[j]; } rc[i] = - s / thy gain; for (long j = 2; j <= i / 2 + 1; j++) { double at = a[j] + rc[i] * a[i - j + 2]; a[i - j + 2] += rc[i] * a[j]; a[j] = at; } a[i + 1] = rc[i]; thy gain += rc[i] * s; if (thy gain <= 0) { goto end; } } end: i--; for (long j = 1; j <= i; j++) { thy a[j] = a[j + 1]; } if (i == m) { return 1; } thy nCoefficients = i; for (long j = i + 1; j <= m; j++) { thy a[j] = 0.0; } return 0; // Melder_warning ("Less coefficienst than asked for."); } /* Markel&Gray, LP of S, page 221 work[1..m(m+1)/2+m+m+1+m+m+1] b = & work[1] grc = & work[m*(m+1)/2+1]; a = & work[m*(m+1)/2+m+1]; beta = & work [m+1)/2+m+m+1+1]; cc = & work[m+1)/2+m+m+1+m+1] for (i=1; i<=m(m+1)/2+m+m+1+m+m+1;i++) work[i] = 0; */ static int Sound_into_LPC_Frame_covar (Sound me, LPC_Frame thee) { long i = 1, n = my nx, m = thy nCoefficients; double *x = my z[1]; autoNUMvector b (1, m * (m + 1) / 2); autoNUMvector grc (1, m); autoNUMvector a (1, m + 1); autoNUMvector beta (1, m); autoNUMvector cc (1, m + 1); thy gain = 0.0; for (i = m + 1; i <= n; i++) { thy gain += x[i] * x[i]; cc[1] += x[i] * x[i - 1]; cc[2] += x[i - 1] * x[i - 1]; } if (thy gain == 0.0) { i = 1; /* ! */ goto end; } b[1] = 1.0; beta[1] = cc[2]; a[1] = 1.0; a[2] = grc[1] = -cc[1] / cc[2]; thy gain += grc[1] * cc[1]; for (i = 2; i <= m; i++) { /*130*/ double s = 0.0; /* 20 */ for (long j = 1; j <= i; j++) { cc[i - j + 2] = cc[i - j + 1] + x[m - i + 1] * x[m - i + j] - x[n - i + 1] * x[n - i + j]; } cc[1] = 0.0; for (long j = m + 1; j <= n; j++) { cc[1] += x[j - i] * x[j]; /* 30 */ } b[i * (i + 1) / 2] = 1.0; for (long j = 1; j <= i - 1; j++) { /* 70 */ double gam = 0.0; if (beta[j] < 0.0) { goto end; } else if (beta[j] == 0.0) { continue; } for (long k = 1; k <= j; k++) { gam += cc[k + 1] * b[j * (j - 1) / 2 + k]; /*50*/ } gam /= beta[j]; for (long k = 1; k <= j; k++) { b[i * (i - 1) / 2 + k] -= gam * b[j * (j - 1) / 2 + k]; /*60*/ } } beta[i] = 0.0; for (long j = 1; j <= i; j++) { beta[i] += cc[j + 1] * b[i * (i - 1) / 2 + j]; /*80*/ } if (beta[i] <= 0.0) { goto end; } for (long j = 1; j <= i; j++) { s += cc[j] * a[j]; /*100*/ } grc[i] = -s / beta[i]; for (long j = 2; j <= i; j++) { a[j] += grc[i] * b[i * (i - 1) / 2 + j - 1]; /*110*/ } a[i + 1] = grc[i]; s = grc[i] * grc[i] * beta[i]; thy gain -= s; if (thy gain <= 0.0) { goto end; } } end: i--; for (long j = 1; j <= i; j++) { thy a[j] = a[j + 1]; } if (i == m) { return 1; } thy nCoefficients = i; for (long j = i + 1; j <= m; j++) { thy a[j] = 0.0; } return 0; // Melder_warning ("Less coefficienst than asked for."); } static int Sound_into_LPC_Frame_burg (Sound me, LPC_Frame thee) { int status = NUMburg (my z[1], my nx, thy a, thy nCoefficients, &thy gain); thy gain *= my nx; for (long i = 1; i <= thy nCoefficients; i++) { thy a[i] = -thy a[i]; } return status; } static int Sound_into_LPC_Frame_marple (Sound me, LPC_Frame thee, double tol1, double tol2) { long m = 1, n = my nx, mmax = thy nCoefficients; int status = 1; double *a = thy a, *x = my z[1]; autoNUMvector c (1, mmax + 1); autoNUMvector d (1, mmax + 1); autoNUMvector r (1, mmax + 1); double e0 = 0.0; for (long k = 1; k <= n; k++) { e0 += x[k] * x[k]; } e0 *= 2.0; if (e0 == 0.0) { m = 0; thy gain *= 0.5; /* because e0 is twice the energy */ thy nCoefficients = m; return 0; // warning no signal } double q1 = 1.0 / e0; double q2 = q1 * x[1], q = q1 * x[1] * x[1], w = q1 * x[n] * x[n]; double v = q, u = w; double den = 1.0 - q - w; double q4 = 1.0 / den, q5 = 1.0 - q, q6 = 1.0 - w; double h = q2 * x[n], s = h; thy gain = e0 * den; q1 = 1.0 / thy gain; c[1] = q1 * x[1]; d[1] = q1 * x[n]; double s1 = 0.0; for (long k = 1; k <= n - 1; k++) { s1 += x[k + 1] * x[k]; } r[1] = 2.0 * s1; a[1] = - q1 * r[1]; thy gain *= (1.0 - a[1] * a[1]); while (m < mmax) { double eOld = thy gain, f = x[m + 1], b = x[n - m]; /*n-1 ->n-m*/ for (long k = 1; k <= m; k++) { /* n-1 -> n-m */ f += x[m + 1 - k] * a[k]; b += x[n - m + k] * a[k]; } q1 = 1.0 / thy gain; q2 = q1 * f; double q3 = q1 * b; for (long k = m; k >= 1; k--) { c[k + 1] = c[k] + q2 * a[k]; d[k + 1] = d[k] * q3 * a[k]; } c[1] = q2; d[1] = q3; double q7 = s * s; double y1 = f * f; double y2 = v * v; double y3 = b * b; double y4 = u * u; double y5 = 2.0 * h * s; q += y1 * q1 + q4 * (y2 * q6 + q7 * q5 + v * y5); w += y3 * q1 + q4 * (y4 * q5 + q7 * q6 + u * y5); h = s = u = v = 0.0; for (long k = 0; k <= m; k++) { h += x[n - m + k] * c[k + 1]; s += x[n - k] * c[k + 1]; u += x[n - k] * d[k + 1]; v += x[k + 1] * c[k + 1]; } q5 = 1.0 - q; q6 = 1.0 - w; den = q5 * q6 - h * h; if (den <= 0.0) { status = 2; goto end; /* 2: ill-conditioning */ } q4 = 1.0 / den; q1 *= q4; double alf = 1.0 / (1.0 + q1 * (y1 * q6 + y3 * q5 + 2.0 * h * f * b)); thy gain *= alf; y5 = h * s; double c1 = q4 * (f * q6 + b * h); double c2 = q4 * (b * q5 + h * f); double c3 = q4 * (v * q6 + y5); double c4 = q4 * (s * q5 + v * h); double c5 = q4 * (s * q6 + h * u); double c6 = q4 * (u * q5 + y5); for (long k = 1; k <= m; k++) { a[k] = alf * (a[k] + c1 * c[k + 1] + c2 * d[k + 1]); } for (long k = 1; k <= m / 2 + 1; k++) { s1 = c[k]; double s2 = d[k], s3 = c[m + 2 - k], s4 = d[m + 2 - k]; c[k] += c3 * s3 + c4 * s4; d[k] += c5 * s3 + c6 * s4; if (m + 2 - k == k) { continue; } c[m + 2 - k] += c3 * s1 + c4 * s2; d[m + 2 - k] += c5 * s1 + c6 * s2; } m++; c1 = x[n + 1 - m]; c2 = x[m]; double delta = 0; for (long k = m - 1; k >= 1; k--) { r[k + 1] = r[k] - x[n + 1 - k] * c1 - x[k] * c2; delta += r[k + 1] * a[k]; } s1 = 0.0; for (long k = 1; k <= n - m; k++) { s1 += x[k + m] * x[k]; } r[1] = 2.0 * s1; delta += r[1]; q2 = - delta / thy gain; a[m] = q2; for (long k = 1; k <= m / 2; k++) { s1 = a[k]; a[k] += q2 * a[m - k]; if (k == m - k) { continue; } a[m - k] += q2 * s1; } y1 = q2 * q2; thy gain *= 1.0 - y1; if (y1 >= 1.0) { status = 3; goto end; /* |a[m]| > 1 */ } if (thy gain < e0 * tol1) { status = 4; goto end; } if (eOld - thy gain < eOld * tol2) { status = 5; goto end; } } end: thy gain *= 0.5; /* because e0 is twice the energy */ thy nCoefficients = m; return status == 1 || status == 4 || status == 5; } static autoLPC _Sound_to_LPC (Sound me, int predictionOrder, double analysisWidth, double dt, double preEmphasisFrequency, int method, double tol1, double tol2) { double t1, samplingFrequency = 1.0 / my dx; double windowDuration = 2 * analysisWidth; /* gaussian window */ long nFrames, frameErrorCount = 0; if (floor (windowDuration / my dx) < predictionOrder + 1) Melder_throw (U"Analysis window duration too short.\n" U"For a prediction order of ", predictionOrder, U" the analysis window duration has to be greater than ", my dx * (predictionOrder + 1), U"Please increase the analysis window duration or lower the prediction order."); // Convenience: analyse the whole sound into one LPC_frame if (windowDuration > my dx * my nx) { windowDuration = my dx * my nx; } Sampled_shortTermAnalysis (me, windowDuration, dt, & nFrames, & t1); autoSound sound = Data_copy (me); autoSound sframe = Sound_createSimple (1, windowDuration, samplingFrequency); autoSound window = Sound_createGaussian (windowDuration, samplingFrequency); autoLPC thee = LPC_create (my xmin, my xmax, nFrames, dt, t1, predictionOrder, my dx); autoMelderProgress progress (U"LPC analysis"); if (preEmphasisFrequency < samplingFrequency / 2) { Sound_preEmphasis (sound.peek(), preEmphasisFrequency); } for (long i = 1; i <= nFrames; i++) { LPC_Frame lpcframe = (LPC_Frame) & thy d_frames[i]; double t = Sampled_indexToX (thee.peek(), i); LPC_Frame_init (lpcframe, predictionOrder); Sound_into_Sound (sound.peek(), sframe.peek(), t - windowDuration / 2); Vector_subtractMean (sframe.peek()); Sounds_multiply (sframe.peek(), window.peek()); if (method == LPC_METHOD_AUTO) { if (! Sound_into_LPC_Frame_auto (sframe.peek(), lpcframe)) { frameErrorCount++; } } else if (method == LPC_METHOD_COVAR) { if (! Sound_into_LPC_Frame_covar (sframe.peek(), lpcframe)) { frameErrorCount++; } } else if (method == LPC_METHOD_BURG) { if (! Sound_into_LPC_Frame_burg (sframe.peek(), lpcframe)) { frameErrorCount++; } } else if (method == LPC_METHOD_MARPLE) { if (! Sound_into_LPC_Frame_marple (sframe.peek(), lpcframe, tol1, tol2)) { frameErrorCount++; } } if ( (i % 10) == 1) { Melder_progress ( (double) i / nFrames, U"LPC analysis of frame ", i, U" out of ", nFrames, U"."); } } return thee; } autoLPC Sound_to_LPC_auto (Sound me, int predictionOrder, double analysisWidth, double dt, double preEmphasisFrequency) { try { autoLPC thee = _Sound_to_LPC (me, predictionOrder, analysisWidth, dt, preEmphasisFrequency, LPC_METHOD_AUTO, 0, 0); return thee; } catch (MelderError) { Melder_throw (me, U": no LPC (auto) created."); } } autoLPC Sound_to_LPC_covar (Sound me, int predictionOrder, double analysisWidth, double dt, double preEmphasisFrequency) { try { autoLPC thee = _Sound_to_LPC (me, predictionOrder, analysisWidth, dt, preEmphasisFrequency, LPC_METHOD_COVAR, 0, 0); return thee; } catch (MelderError) { Melder_throw (me, U": no LPC (covar) created."); } } autoLPC Sound_to_LPC_burg (Sound me, int predictionOrder, double analysisWidth, double dt, double preEmphasisFrequency) { try { autoLPC thee = _Sound_to_LPC (me, predictionOrder, analysisWidth, dt, preEmphasisFrequency, LPC_METHOD_BURG, 0, 0); return thee; } catch (MelderError) { Melder_throw (me, U": no LPC (burg) created."); } } autoLPC Sound_to_LPC_marple (Sound me, int predictionOrder, double analysisWidth, double dt, double preEmphasisFrequency, double tol1, double tol2) { try { autoLPC thee = _Sound_to_LPC (me, predictionOrder, analysisWidth, dt, preEmphasisFrequency, LPC_METHOD_MARPLE, tol1, tol2); return thee; } catch (MelderError) { Melder_throw (me, U": no LPC (marple) created."); } } autoSound LPC_and_Sound_filterInverse (LPC me, Sound thee) { try { if (my samplingPeriod != thy dx) { Melder_throw (U"Sampling frequencies are not the same."); } if (my xmin != thy xmin || thy xmax != my xmax) { Melder_throw (U"Domains of LPC and Sound are not equal."); } autoSound him = Data_copy (thee); double *e = his z[1], *x = thy z[1]; for (long i = 1; i <= his nx; i++) { double t = his x1 + (i - 1) * his dx; /* Sampled_indexToX (him, i) */ long iFrame = lround ( (t - my x1) / my dx + 1.0); /* Sampled_xToNearestIndex (me, t) */ double *a; if (iFrame < 1 || iFrame > my nx) { e[i] = 0.0; continue; } a = my d_frames[iFrame].a; long m = i > my d_frames[iFrame].nCoefficients ? my d_frames[iFrame].nCoefficients : i - 1; for (long j = 1; j <= m; j++) { e[i] += a[j] * x[i - j]; } } return him; } catch (MelderError) { Melder_throw (thee, U": not inverse filtered."); } } /* gain used as a constant amplitude multiplyer within a frame of duration my dx. future alternative: convolve gain with a smoother. */ autoSound LPC_and_Sound_filter (LPC me, Sound thee, int useGain) { try { double xmin = my xmin > thy xmin ? my xmin : thy xmin; double xmax = my xmax < thy xmax ? my xmax : thy xmax; if (xmin >= xmax) { Melder_throw (U"Domains of Sound [", thy xmin, U",", thy xmax, U"] and LPC [", my xmin, U",", my xmax, U"] do not overlap."); } // resample sound if samplings don't match autoSound source = nullptr; if (my samplingPeriod != thy dx) { source = Sound_resample (thee, 1.0 / my samplingPeriod, 50); thee = source.peek(); // reference copy; remove at end } autoSound him = Data_copy (thee); double *x = his z[1]; long ifirst = Sampled_xToHighIndex (thee, xmin); long ilast = Sampled_xToLowIndex (thee, xmax); for (long i = ifirst; i <= ilast; i++) { double t = his x1 + (i - 1) * his dx; /* Sampled_indexToX (him, i) */ long iFrame = lround ( (t - my x1) / my dx + 1.0); /* Sampled_xToNearestIndex (me, t) */ if (iFrame < 1) { continue; } if (iFrame > my nx) { break; } double *a = my d_frames[iFrame].a; long m = i > my d_frames[iFrame].nCoefficients ? my d_frames[iFrame].nCoefficients : i - 1; for (long j = 1; j <= m; j++) { x[i] -= a[j] * x[i - j]; } } // Make samples before first frame and after last frame zero. for (long i = 1; i < ifirst; i++) { x[i] = 0.0; } for (long i = ilast + 1; i <= his nx; i++) { x[i] = 0.0; } if (useGain) { for (long i = ifirst; i <= ilast; i++) { double t = his x1 + (i - 1) * his dx; /* Sampled_indexToX (him, i) */ double riFrame = (t - my x1) / my dx + 1; /* Sampled_xToIndex (me, t); */ long iFrame = (long) floor (riFrame); double phase = riFrame - iFrame; if (iFrame < 0 || iFrame > my nx) { x[i] = 0.0; } else if (iFrame == 0) { x[i] *= sqrt (my d_frames[1].gain) * phase; } else if (iFrame == my nx) { x[i] *= sqrt (my d_frames[my nx].gain) * (1.0 - phase); } else x[i] *= phase * sqrt (my d_frames[iFrame + 1].gain) + (1.0 - phase) * sqrt (my d_frames[iFrame].gain); } } return him; } catch (MelderError) { Melder_throw (thee, U": not filtered."); } } void LPC_and_Sound_filterWithFilterAtTime_inline (LPC me, Sound thee, int channel, double time) { long frameIndex = Sampled_xToNearestIndex (me, time); if (frameIndex < 1) { frameIndex = 1; } if (frameIndex > my nx) { frameIndex = my nx; } if (channel > thy ny) { channel = 1; } if (frameIndex < 1 || frameIndex > my nx) { Melder_throw (U"Frame number out of range."); } if (channel > 0) { LPC_Frame_and_Sound_filter (& (my d_frames[frameIndex]), thee, channel); } else { for (long ichan = 1; ichan <= thy ny; ichan++) { LPC_Frame_and_Sound_filter (& (my d_frames[frameIndex]), thee, ichan); } } } autoSound LPC_and_Sound_filterWithFilterAtTime (LPC me, Sound thee, int channel, double time) { try { autoSound him = Data_copy (thee); LPC_and_Sound_filterWithFilterAtTime_inline (me, him.peek(), channel, time); return him; } catch (MelderError) { Melder_throw (thee, U": not filtered."); } } void LPC_and_Sound_filterInverseWithFilterAtTime_inline (LPC me, Sound thee, int channel, double time) { try { long frameIndex = Sampled_xToNearestIndex (me, time); if (frameIndex < 1) { frameIndex = 1; } if (frameIndex > my nx) { frameIndex = my nx; } if (channel > thy ny) { channel = 1; } if (channel > 0) { LPC_Frame_and_Sound_filterInverse (& (my d_frames[frameIndex]), thee, channel); } else { for (long ichan = 1; ichan <= thy ny; ichan++) { LPC_Frame_and_Sound_filterInverse (& (my d_frames[frameIndex]), thee, ichan); } } } catch (MelderError) { Melder_throw (thee, U": not inverse filtered."); } } autoSound LPC_and_Sound_filterInverseWithFilterAtTime (LPC me, Sound thee, int channel, double time) { try { autoSound him = Data_copy (thee); LPC_and_Sound_filterInverseWithFilterAtTime_inline (me, him.peek(), channel, time); return him; } catch (MelderError) { Melder_throw (thee, U": not inverse filtered."); } } /* End of file Sound_and_LPC.cpp */ praat-6.0.04/LPC/Sound_and_LPC.h000066400000000000000000000066771261542461700161370ustar00rootroot00000000000000#ifndef _Sound_and_LPC_h_ #define _Sound_and_LPC_h_ /* Sound_and_LPC.h * * Copyright (C) 1994-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19971103 djmw 20020812 GPL header djmw 20110307 Latest modification */ #include "LPC.h" #include "Sound.h" autoLPC Sound_to_LPC_auto (Sound me, int predictionOrder, double analysisWidth, double dt, double preEmphasisFrequency); autoLPC Sound_to_LPC_covar (Sound me, int predictionOrder, double analysisWidth, double dt, double preEmphasisFrequency); autoLPC Sound_to_LPC_burg (Sound me, int predictionOrder, double analysisWidth, double dt, double preEmphasisFrequency); autoLPC Sound_to_LPC_marple (Sound me, int predictionOrder, double analysisWidth, double dt, double preEmphasisFrequency, double tol1, double tol2); /* * Function: * Calculate linear prediction coefficients according to following model: * Minimize E(m) = Sum(n=n0;n=n1; (x[n] + Sum(k=1;k=m; a[k]*x[n-k]))) * Method: * The minimization is carried out by solving the equations: * Sum(i=1;i=m; a[i]*c[i][k]) = -c[0][k] for k=1,2,...,m * where c[i][k] = Sum(n=n0;n=n1;x[n-i]*x[n-k]) * 1. Covariance: * n0=m; n1 = N-1; * c[i][k] is symmetric, positive semi-definite matrix * Markel&Gray, LP of Speech, page 221; * 2. Autocorrelation * signal is zero outside the interval; * n0=-infinity; n1=infinity * c[i][k] symmetric, positive definite Toeplitz matrix * Markel&Gray, LP of Speech, page 219; * Preconditions: * predictionOrder > 0; * preEmphasisFrequency >= 0; * * Burg method: see Numerical recipes Chapter 13. * * Marple method: see Marple, L. (1980), A new autoregressive spectrum analysis * algorithm, IEEE Trans. on ASSP 28, 441-453. * tol1 : stop iteration when E(m) / E(0) < tol1 * tol2 : stop iteration when (E(m)-E(m-1)) / E(m-1) < tol2, */ void LPC_Frame_and_Sound_filterInverse (LPC_Frame me, Sound thee, int channel); autoSound LPC_and_Sound_filter (LPC me, Sound thee, int useGain); /* E(z) = X(z)A(z), A(z) = 1 + Sum (k=1, k=m, a(k)z^-k); filter: given e & a, determine x; x(n) = e(n) - Sum (k=1, m, a(k)x(n-k)) useGain determines whether the LPC-gain is used in the synthesis. */ void LPC_and_Sound_filterWithFilterAtTime_inline (LPC me, Sound thee, int channel, double time); autoSound LPC_and_Sound_filterWithFilterAtTime (LPC me, Sound thee, int channel, double time); autoSound LPC_and_Sound_filterInverse (LPC me, Sound thee); /* E(z) = X(z)A(z), A(z) = 1 + Sum (k=1, k=m, a(k)z^-k); filter inverse: given x & a, determine e; e(n) = x(n) + Sum (k=1, m, a(k)x(n-k)) */ autoSound LPC_and_Sound_filterInverseWithFilterAtTime (LPC me, Sound thee, int channel, double time); void LPC_and_Sound_filterInverseWithFilterAtTime_inline (LPC me, Sound thee, int channel, double time); #endif /* _Sound_and_LPC_h_ */ praat-6.0.04/LPC/Sound_and_LPC_robust.cpp000066400000000000000000000205261261542461700200550ustar00rootroot00000000000000/* Sound_and_LPC_robust.cpp * * Copyright (C) 1994-2013, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20030814 First version djmw 20061218 To Melder_information format djmw 20070103 Sound interface changes djmw 20080122 float -> double djmw 20101008 New LPC_Frame_filterInverse interface. djmw 20110302 Corrected a number of pointer initialisations djmw 20111027 +Sound_to_Formant_robust */ #include "LPC_and_Formant.h" #include "Sound_and_LPC.h" #include "Sound_and_LPC_robust.h" #include "Sound_extensions.h" #include "SVD.h" #include "Vector.h" #include "NUM2.h" struct huber_struct { Sound e; double k, tol, tol_svd; long iter, itermax; int wantlocation, wantscale; double location, scale; long n, p; double *w, *work; double *a; double **covar, *c; SVD svd; }; static void huber_struct_init (struct huber_struct *hs, double windowDuration, long p, double samplingFrequency, double location, int wantlocation) { hs -> w = hs -> work = hs -> a = hs -> c = nullptr; hs -> covar = nullptr; hs -> svd = nullptr; hs -> e = Sound_createSimple (1, windowDuration, samplingFrequency).transfer(); long n = hs -> e -> nx; hs -> n = n; hs -> p = p; hs -> w = NUMvector (1, n); hs -> work = NUMvector (1, n); hs -> a = NUMvector (1, p); hs -> covar = NUMmatrix (1, p, 1, p); hs -> c = NUMvector (1, p); hs -> svd = SVD_create (p, p); hs -> wantlocation = wantlocation; if (! wantlocation) { hs -> location = location; } hs -> wantscale = 1; } static void huber_struct_destroy (struct huber_struct *hs) { forget (hs -> e); forget (hs -> svd); NUMvector_free (hs -> w, 1); NUMvector_free (hs -> work, 1); NUMvector_free (hs -> a, 1); NUMmatrix_free (hs -> covar, 1, 1); NUMvector_free (hs -> c, 1); } static void huber_struct_getWeights (struct huber_struct *hs, double *e) { double ks = hs -> k * hs -> scale; double *w = hs -> w; for (long i = 1 ; i <= hs -> n; i++) { double ei = e[i] - hs -> location; w[i] = ei > -ks && ei < ks ? 1.0 : ks / fabs (ei); } } static void huber_struct_getWeightedCovars (struct huber_struct *hs, double *s) { long p = hs -> p, n = hs -> n; double *w = hs -> w, **covar = hs -> covar, *c = hs -> c; for (long i = 1; i <= p; i++) { for (long j = i; j <= p; j++) { double tmp = 0; for (long k = p + 1; k <= n; k++) { tmp += s[k - j] * s[k - i] * w[k]; } covar[i][j] = covar[j][i] = tmp; } double tmp = 0; for (long k = p + 1; k <= n; k++) { tmp += s[k - i] * s[k] * w[k]; } c[i] = -tmp; } } static void huber_struct_solvelpc (struct huber_struct *hs) { SVD me = hs -> svd; double **covar = hs -> covar; for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= my numberOfColumns; j++) { my u[i][j] = covar[i][j]; } } SVD_setTolerance (me, hs -> tol_svd); SVD_compute (me); //long nzeros = SVD_zeroSmallSingularValues (me, 0); SVD_solve (me, hs -> c, hs -> a); } void LPC_Frames_and_Sound_huber (LPC_Frame me, Sound thee, LPC_Frame him, struct huber_struct *hs) { long p = my nCoefficients > his nCoefficients ? his nCoefficients : my nCoefficients; long n = hs -> e -> nx > thy nx ? thy nx : hs -> e -> nx; double *e = hs -> e -> z[1], *s = thy z[1]; hs -> iter = 0; hs -> scale = 1e308; hs -> p = p; double s0; do { Sound hse = hs -> e; for (long i = 1; i <= thy nx; i++) { hse -> z[1][i] = thy z[1][i]; } LPC_Frame_and_Sound_filterInverse (him, hse, 1); s0 = hs -> scale; NUMstatistics_huber (e, n, & (hs -> location), hs -> wantlocation, & (hs -> scale), hs -> wantscale, hs -> k, hs -> tol, hs -> work); huber_struct_getWeights (hs, e); huber_struct_getWeightedCovars (hs, s); // Solve C a = [-] c */ try { huber_struct_solvelpc (hs); } catch (MelderError) { // Copy the starting lpc coeffs */ for (long i = 1; i <= p; i++) { his a[i] = my a[i]; } throw MelderError(); } for (long i = 1; i <= p; i++) { his a[i] = hs -> a[i]; } (hs -> iter) ++; } while ( (hs -> iter < hs -> itermax) && (fabs (s0 - hs -> scale) > hs -> tol * s0)); } LPC LPC_and_Sound_to_LPC_robust (LPC thee, Sound me, double analysisWidth, double preEmphasisFrequency, double k, int itermax, double tol, int wantlocation) { struct huber_struct struct_huber = { 0 }; try { double t1, samplingFrequency = 1.0 / my dx, tol_svd = 0.000001; double location = 0, windowDuration = 2 * analysisWidth; /* Gaussian window */ long nFrames, frameErrorCount = 0, iter = 0; long p = thy maxnCoefficients; if (my xmin != thy xmin || my xmax != thy xmax) { Melder_throw (U"Time domains differ."); } if (my dx != thy samplingPeriod) { Melder_throw (U"Sampling intervals differ."); } if (floor (windowDuration / my dx) < p + 1) { Melder_throw (U"Analysis window too short."); } Sampled_shortTermAnalysis (me, windowDuration, thy dx, & nFrames, & t1); if (nFrames != thy nx || t1 != thy x1) { Melder_throw (U"Incorrect retrieved analysis width"); } autoSound sound = Data_copy (me); autoSound sframe = Sound_createSimple (1, windowDuration, samplingFrequency); autoSound window = Sound_createGaussian (windowDuration, samplingFrequency); autoLPC him = Data_copy (thee); huber_struct_init (&struct_huber, windowDuration, p, samplingFrequency, location, wantlocation); struct_huber.k = k; struct_huber.tol = tol; struct_huber.tol_svd = tol_svd; struct_huber.itermax = itermax; autoMelderProgress progess (U"LPC analysis"); Sound_preEmphasis (sound.peek(), preEmphasisFrequency); for (long i = 1; i <= nFrames; i++) { LPC_Frame lpc = (LPC_Frame) & thy d_frames[i]; LPC_Frame lpcto = (LPC_Frame) & his d_frames[i]; double t = Sampled_indexToX (thee, i); Sound_into_Sound (sound.peek(), sframe.peek(), t - windowDuration / 2); Vector_subtractMean (sframe.peek()); Sounds_multiply (sframe.peek(), window.peek()); try { LPC_Frames_and_Sound_huber (lpc, sframe.peek(), lpcto, & struct_huber); } catch (MelderError) { frameErrorCount++; } iter += struct_huber.iter; if ( (i % 10) == 1) { Melder_progress ( (double) i / nFrames, U"LPC analysis of frame ", i, U" out of ", nFrames, U"."); } } if (frameErrorCount) Melder_warning (U"Results of ", frameErrorCount, U" frame(s) out of ", nFrames, U" could not be optimised."); MelderInfo_writeLine (U"Number of iterations: ", iter, U"\n Average per frame: ", ((double) iter) / nFrames); huber_struct_destroy (&struct_huber); return him.transfer(); } catch (MelderError) { huber_struct_destroy (&struct_huber); Melder_throw (me, U": no robust LPC created."); } } Formant Sound_to_Formant_robust (Sound me, double dt_in, double numberOfFormants, double maximumFrequency, double halfdt_window, double preEmphasisFrequency, double safetyMargin, double k, int itermax, double tol, int wantlocation) { double dt = dt_in > 0.0 ? dt_in : halfdt_window / 4.0; double nyquist = 0.5 / my dx; int predictionOrder = (long) floor (2 * numberOfFormants); try { autoSound sound; if (maximumFrequency <= 0.0 || fabs (maximumFrequency / nyquist - 1.0) < 1.0e-12) { sound = Data_copy (me); // will be modified } else { sound = Sound_resample (me, maximumFrequency * 2.0, 50); } autoLPC lpc = Sound_to_LPC_auto (sound.peek(), predictionOrder, halfdt_window, dt, preEmphasisFrequency); autoLPC lpcr = LPC_and_Sound_to_LPC_robust (lpc.peek(), sound.peek(), halfdt_window, preEmphasisFrequency, k, itermax, tol, wantlocation); autoFormant thee = LPC_to_Formant (lpcr.peek(), safetyMargin); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no robust Formant created."); } } /* End of file Sound_and_LPC_robust.cpp */ praat-6.0.04/LPC/Sound_and_LPC_robust.h000066400000000000000000000034641261542461700175240ustar00rootroot00000000000000#ifndef _Sound_and_LPC_robust_h_ #define _Sound_and_LPC_robust_h_ /* Sound_and_LPC_robust.h * * Copyright (C) 1993-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20030815 GPL header djmw 20111027 Latest modification */ #include "LPC.h" #include "Formant.h" #include "Sound.h" void LPC_Frames_and_Sound_huber (LPC_Frame me, Sound thee, LPC_Frame him, struct huber_struct *hs); /*int LPC_Frames_and_Sound_huber (LPC_Frame me, Sound thee, LPC_Frame him, void *huber); The gnu c compiler (version 3.3.1) complaints about having two LPC_Frame types in the argument list: error: two or more data types in declaration of `LPC_Frame_and_Sound_into_LPC_Frame_huber By defining a void pointer we circumvent the complaint. */ LPC LPC_and_Sound_to_LPC_robust (LPC thee, Sound me, double analysisWidth, double preEmphasisFrequency, double k, int itermax, double tol, int wantlocation); Formant Sound_to_Formant_robust (Sound me, double dt_in, double numberOfFormants, double maximumFrequency, double halfdt_window, double preemphasisFrequency, double safetyMargin, double k, int itermax, double tol, int wantlocation); #endif /* _Sound_and_LPC_robust_h_ */ praat-6.0.04/LPC/Tube.cpp000066400000000000000000000076331261542461700147520ustar00rootroot00000000000000/* Tube.cpp * * Copyright (C) 1994-2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20030613 Creation djmw 20061212 Changed info to Melder_writeLine format. djmw 20110304 Thing_new */ #include "Tube.h" #include "NUM2.h" #include "oo_DESTROY.h" #include "Tube_def.h" #include "oo_COPY.h" #include "Tube_def.h" #include "oo_EQUAL.h" #include "Tube_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Tube_def.h" #include "oo_WRITE_TEXT.h" #include "Tube_def.h" #include "oo_WRITE_BINARY.h" #include "Tube_def.h" #include "oo_READ_TEXT.h" #include "Tube_def.h" #include "oo_READ_BINARY.h" #include "Tube_def.h" #include "oo_DESCRIPTION.h" #include "Tube_def.h" Thing_implement (Tube, Sampled, 0); void structTube :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Time domain: ", xmin, U" to ", xmax, U" seconds"); MelderInfo_writeLine (U"Maximum number of segments: ", maxnSegments); MelderInfo_writeLine (U"Number of frames: ", nx); MelderInfo_writeLine (U"Time step: ", dx, U" seconds"); MelderInfo_writeLine (U"First frame at: ", x1, U" seconds"); } void Tube_Frame_init (Tube_Frame me, long nSegments, double length) { my nSegments = nSegments; my length = length; if (nSegments <= 0) { Melder_throw (U"Number of segments must be a natural number."); } my c = NUMvector (1, nSegments); } /* Gray & Markel (1979), LPTRN */ void Tube_Frames_rc_into_area (Tube_Frame me, Tube_Frame thee) { if (my nSegments > thy nSegments) { Melder_throw (U"Number of segments to big."); } double s = 0.0001; /* 1.0 cm^2 at glottis */ double *rc = my c, *area = thy c; for (long i = my nSegments; i > 0; i--) { s *= (1.0 + rc[i]) / (1.0 - rc[i]); area[i] = s; } } static void Tube_setLengths (Tube me, double length) { for (long i = 1; i <= my nx; i++) { Tube_Frame f = & my frame[i]; if (f) { f -> length = length; } } } void Tube_init (Tube me, double tmin, double tmax, long nt, double dt, double t1, long maxnSegments, double defaultLength) { my maxnSegments = maxnSegments; Sampled_init (me, tmin, tmax, nt, dt, t1); my frame = NUMvector (1, nt); Tube_setLengths (me, defaultLength); } Thing_implement (Area, Tube, 0); void Area_init (Area me, double tmin, double tmax, long nt, double dt, double t1, long maxnSegments, double defaultLength) { Tube_init (me, tmin, tmax, nt, dt, t1, maxnSegments, defaultLength); } autoArea Area_create (double tmin, double tmax, long nt, double dt, double t1, long maxnSegments, double defaultLength) { try { autoArea me = Thing_new (Area); Area_init (me.peek(), tmin, tmax, nt, dt, t1, maxnSegments, defaultLength); return me; } catch (MelderError) { Melder_throw (U"Area not crteated."); } } Thing_implement (RC, Tube, 0); void RC_init (RC me, double tmin, double tmax, long nt, double dt, double t1, long maxnSegments, double defaultLength) { Tube_init (me, tmin, tmax, nt, dt, t1, maxnSegments, defaultLength); } autoRC RC_create (double tmin, double tmax, long nt, double dt, double t1, long maxnCoefficients, double defaultLength) { try { autoRC me = Thing_new (RC); RC_init (me.peek(), tmin, tmax, nt, dt, t1, maxnCoefficients, defaultLength); return me; } catch (MelderError) { Melder_throw (U"RC not crteated."); } } /* End of file Tube.cpp */ praat-6.0.04/LPC/Tube.h000066400000000000000000000036521261542461700144140ustar00rootroot00000000000000#ifndef _Tube_h_ #define _Tube_h_ /* Tube.h * * Copyright (C) 1994-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Sampled.h" #include "Tube_def.h" oo_CLASS_CREATE (Tube, Sampled); /* Tube's as a function of time. Tube_frame: c[1] -> mouth c[nSegments] -> glottis. */ void Tube_Frame_init (Tube_Frame me, long nSegments, double length); void Tube_Frame_free (Tube_Frame me); void Tube_Frames_rc_into_area (Tube_Frame me, Tube_Frame thee); void Tube_init (I, double tmin, double tmax, long nt, double dt, double t1, long maxnSegments, double defaultLength); Thing_define (Area, Tube) { }; /* Areas as a function of time. units in m^2. */ void Area_init (Area me, double tmin, double tmax, long nt, double dt, double t1, long maxnSegments, double defaultLength); autoArea Area_create (double tmin, double tmax, long nt, double dt, double t1, long maxnSegments, double defaultLength); Thing_define (RC, Tube) { }; /* Reflection Coefficients as a function of time. */ void RC_init (RC me, double tmin, double tmax, long nt, double dt, double t1, long maxnCoefficients, double defaultLength); autoRC RC_create (double tmin, double tmax, long nt, double dt, double t1, long maxnCoefficients, double defaultLength); #endif // _Tube_h_ praat-6.0.04/LPC/Tube_def.h000066400000000000000000000022451261542461700152270ustar00rootroot00000000000000/* Tube_def.h * * Copyright (C) 1994-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT Tube_Frame oo_DEFINE_STRUCT (Tube_Frame) oo_INT (nSegments) oo_DOUBLE (length) oo_DOUBLE_VECTOR (c, nSegments) oo_END_STRUCT (Tube_Frame) #undef ooSTRUCT #define ooSTRUCT Tube oo_DEFINE_CLASS (Tube, Sampled) oo_INT (maxnSegments) oo_STRUCT_VECTOR (Tube_Frame, frame, nx) #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (Tube) #undef ooSTRUCT /* End of file Tube_def.h */ praat-6.0.04/LPC/VocalTractTier.cpp000066400000000000000000000152551261542461700167400ustar00rootroot00000000000000/* VocalTractTier.cpp * * Copyright (C) 2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "NUM2.h" #include "RealTier.h" #include "VocalTractTier.h" #include "oo_DESTROY.h" #include "VocalTractTier_def.h" #include "oo_COPY.h" #include "VocalTractTier_def.h" #include "oo_EQUAL.h" #include "VocalTractTier_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "VocalTractTier_def.h" #include "oo_WRITE_TEXT.h" #include "VocalTractTier_def.h" #include "oo_READ_TEXT.h" #include "VocalTractTier_def.h" #include "oo_WRITE_BINARY.h" #include "VocalTractTier_def.h" #include "oo_READ_BINARY.h" #include "VocalTractTier_def.h" #include "oo_DESCRIPTION.h" #include "VocalTractTier_def.h" /***** VocalTractPoint *****/ void VocalTract_drawSegments (VocalTract me, Graphics g, double maxLength, double maxArea, bool closedAtGlottis) { Graphics_setInner (g); double maxCrossection = sqrt (maxArea); Graphics_setWindow (g, 0, maxLength, -maxCrossection, maxCrossection); for (long isection = 1; isection <= my nx; isection++) { double x1 = (isection - 1.0) * my dx, x2 = x1 + my dx; double crosssection2 = sqrt (my z[1][isection]); Graphics_line (g, x1, crosssection2, x2, crosssection2); Graphics_line (g, x1, -crosssection2, x2, -crosssection2); if (isection > 1) { double crosssection1 = sqrt (my z[1][isection - 1]); Graphics_line (g, x1, crosssection1, x1, crosssection2); Graphics_line (g, x1, -crosssection1, x1, -crosssection2); } else if (isection == 1 and closedAtGlottis) { Graphics_line (g, x1, crosssection2, x1, -crosssection2); } } Graphics_unsetInner (g); } Thing_implement (VocalTractPoint, AnyPoint, 0); autoVocalTractPoint VocalTract_to_VocalTractPoint (VocalTract me, double time) { try { autoVocalTractPoint thee = Thing_new (VocalTractPoint); thy number = time; thy d_vocalTract = (VocalTract) Data_copy (me); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to VocalTractPoint."); } } /***** VocalTractTier *****/ Thing_implement (VocalTractTier, Function, 0); autoVocalTractTier VocalTractTier_create (double fromTime, double toTime) { try { autoVocalTractTier me = Thing_new (VocalTractTier); Function_init (me.peek(), fromTime, toTime); my d_vocalTracts = SortedSetOfDouble_create (); return me; } catch (MelderError) { Melder_throw (U": VocalTractTier not created."); } } autoVocalTractTier VocalTract_to_VocalTractTier (VocalTract me, double startTime, double endTime, double time) { try { autoVocalTractTier thee = VocalTractTier_create (startTime, endTime); VocalTractTier_addVocalTract (thee.peek(), time, me); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to VocalTractTier"); } } void VocalTractTier_addVocalTract (VocalTractTier me, double time, VocalTract vocaltract) { try { autoVocalTractPoint thee = VocalTract_to_VocalTractPoint (vocaltract, time); if (my d_vocalTracts -> size > 1) { VocalTractPoint vtp = (VocalTractPoint) my d_vocalTracts -> item[1]; long numberOfSections = vtp -> d_vocalTract -> nx; if (numberOfSections != vocaltract -> nx) { forget (vocaltract); Melder_throw (U"The number of sections must be equal to ", numberOfSections, U"."); } } Collection_addItem (my d_vocalTracts, thee.transfer()); } catch (MelderError) { Melder_throw (me, U": no VocalTract added."); } } autoVocalTract VocalTractTier_to_VocalTract (VocalTractTier me, double time) { try { VocalTractPoint vtp = (VocalTractPoint) my d_vocalTracts -> item[1]; long numberOfSections = vtp -> d_vocalTract -> nx; autoVocalTract thee = VocalTract_create (numberOfSections, vtp -> d_vocalTract -> dx); for (long isection = 1; isection <= numberOfSections; isection++) { autoRealTier section = RealTier_create (my xmin, my xmax); for (long i = 1; i <= my d_vocalTracts -> size; i++) { VocalTractPoint vtpi = (VocalTractPoint) my d_vocalTracts -> item[i]; double areai = vtpi -> d_vocalTract -> z[1][isection]; RealTier_addPoint (section.peek(), vtpi -> number, areai); } thy z[1][isection] = RealTier_getValueAtTime (section.peek(), time); } return thee; } catch (MelderError) { Melder_throw (me, U": no VocalTract created."); } } autoLPC VocalTractTier_to_LPC (VocalTractTier me, double timeStep) { try { if (my d_vocalTracts -> size == 0) { Melder_throw (U"Empty VocalTractTier"); } long numberOfFrames = (long) floor ((my xmax - my xmin) / timeStep); VocalTractPoint vtp = (VocalTractPoint) my d_vocalTracts -> item[1]; long numberOfSections = vtp -> d_vocalTract -> nx; double samplingPeriod = 1.0 / (1000.0 * numberOfSections); autoNUMmatrix area (1, numberOfFrames, 1, numberOfSections + 1); autoNUMvector areavec (1, numberOfSections + 1); autoLPC thee = LPC_create (my xmin, my xmax, numberOfFrames, timeStep, timeStep / 2, numberOfSections, samplingPeriod); // interpolate each section for (long isection = 1; isection <= numberOfSections; isection++) { autoRealTier sectioni = RealTier_create (my xmin, my xmax); for (long i = 1; i <= my d_vocalTracts -> size; i++) { VocalTractPoint vtpi = (VocalTractPoint) my d_vocalTracts -> item[i]; double areai = vtpi -> d_vocalTract -> z[1][isection]; RealTier_addPoint (sectioni.peek(), vtpi -> number, areai); } for (long iframe = 1; iframe <= numberOfFrames; iframe++) { double time = thy x1 + (iframe - 1) * thy dx; area[iframe][isection] = RealTier_getValueAtTime (sectioni.peek(), time); area[iframe][numberOfSections + 1] = 0.0001; // normalisation is area[n+1] = 0.0001 } } for (long iframe = 1; iframe <= numberOfFrames; iframe++) { LPC_Frame frame = &thy d_frames[iframe]; LPC_Frame_init (frame, numberOfSections); for (long i = 1; i <= numberOfSections + 1; i++) { areavec[i] = area[iframe][numberOfSections + 1 - i]; } NUMlpc_area_to_lpc (areavec.peek(), numberOfSections + 1, frame -> a); frame -> gain = 1e-6; // something } return thee; } catch (MelderError) { Melder_throw (U": not converted to LPC."); } } /* End of file VocalTractTier.cpp */ praat-6.0.04/LPC/VocalTractTier.h000066400000000000000000000032051261542461700163750ustar00rootroot00000000000000#ifndef _VocalTractTier_h_ #define _VocalTractTier_h_ /* VocalTractTier.h * * Copyright (C) 2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "AnyTier.h" #include "LPC.h" #include "VocalTract.h" #include "VocalTractTier_def.h" oo_CLASS_CREATE (VocalTractPoint, AnyPoint); oo_CLASS_CREATE (VocalTractTier, Function); void VocalTract_drawSegments (VocalTract me, Graphics g, double maxLength, double maxArea, bool closedAtGlottis); autoVocalTractPoint VocalTract_to_VocalTractPoint (VocalTract me, double time); autoVocalTractTier VocalTractTier_create (double fromTime, double toTime); autoVocalTractTier VocalTract_to_VocalTractTier (VocalTract me, double startTime, double endTime, double time); void VocalTractTier_addVocalTract (VocalTractTier me, double time, VocalTract thee); autoLPC VocalTractTier_to_LPC (VocalTractTier me, double timeStep); autoVocalTract VocalTractTier_to_VocalTract (VocalTractTier me, double time); /* End of file VocalTractTier.h */ #endif praat-6.0.04/LPC/VocalTractTier_def.h000066400000000000000000000022161261542461700172140ustar00rootroot00000000000000/* VocalTractTier_def.h * * Copyright (C) 2012 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT VocalTractPoint oo_DEFINE_CLASS (VocalTractPoint, AnyPoint) oo_OBJECT (VocalTract, 0, d_vocalTract) oo_END_CLASS (VocalTractPoint) #undef ooSTRUCT #define ooSTRUCT VocalTractTier oo_DEFINE_CLASS (VocalTractTier, Function) oo_COLLECTION (SortedSetOfDouble, d_vocalTracts, VocalTractPoint, 0) oo_END_CLASS (VocalTractTier) #undef ooSTRUCT /* End of file VocalTract_def.h */ praat-6.0.04/LPC/manual_LPC.cpp000066400000000000000000001156501261542461700160250ustar00rootroot00000000000000/* manual_LPC.c * * Copyright (C) 1994-2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020422 GPL + removed "C syntax" part of manpage djmw 20101009 Latest modification */ #include "ManPagesM.h" #include "MFCC.h" void manual_LPC (ManPages me); void manual_LPC (ManPages me) { MAN_BEGIN (U"CC: Paint...", U"djmw", 20040407) INTRO (U"A command to paint the cepstral coefficients in shades of grey.") ENTRY (U"Settings") TAG (U"##From coefficient#, ##To coefficient#") DEFINITION (U"the range of coefficients that will be represented.") MAN_END MAN_BEGIN (U"CC: To DTW...", U"djmw", 19960918) INTRO (U"You can choose this command after selecting 2 objects with cepstral " "coefficients (two @MFCC's or @LFCC's). " "With this command you perform dynamic time warping. ") ENTRY (U"Algorithm") NORMAL (U"First we calculate distances between cepstral coefficients: ") LIST_ITEM (U"The distance between frame %i (from me) and %j (from thee) is:") LIST_ITEM (U" %wc \\.c %d1 + %wle \\.c %d2 + %wr \\.c %d3,") LIST_ITEM (U" where %wc, %wle & %wr are user-supplied weights and") LIST_ITEM (U" %d1 = \\su (%k=1..%nCoefficients; (%c__%ik_ - %c__%jk_)^2)") LIST_ITEM (U" %d2 = (c__%i0_ - c__%j0_)^2") LIST_ITEM (U" %d3 = \\su (%k=1..%nCoefficients; (%r__%ik_ - %r__%jk_)^2), with ") LIST_ITEM (U" %r__%ik_ the regression coefficient of the cepstral coefficients " "from the frames within a time span of %dtr seconds. " "c__%ij_ is %j-th cepstral coefficient in frame %i. ") NORMAL (U"Next we find the optimum path through the distance matrix with a " "Viterbi-algorithm.") MAN_END MAN_BEGIN (U"CC: To Matrix", U"djmw", 20011123) INTRO (U"Copies the cepstral coefficients of the selected @CC " "object to a newly created @Matrix object.") ENTRY (U"Behaviour") FORMULA (U"%z__%ji_ = %c__%ij_, with 1 \\<_ %i \\<_ %nx and " "1 \\<_ j \\<_ %numberOfCoefficients__%i_,") NORMAL (U"where %z__%ji_ is the matrix element in row %j and column %i and " "%c__%ij_ is the %j-th cepstral coefficient in frame %i.") MAN_END MAN_BEGIN (U"Formants: Extract smoothest part...", U"djmw", 20140313) INTRO (U"Extracts the part from one of the selected formants which shows the smoothest formant tracks in a given interval.") ENTRY (U"Settings") SCRIPT (5, Manual_SETTINGS_WINDOW_HEIGHT (5), U"" Manual_DRAW_SETTINGS_WINDOW (U"Formants: Extract smoothest part", 5) Manual_DRAW_SETTINGS_WINDOW_RANGE (U"Time range (s)", U"0.0", U"0.0") Manual_DRAW_SETTINGS_WINDOW_RANGE (U"Fitter formant range", U"1", U"3") Manual_DRAW_SETTINGS_WINDOW_FIELD (U"Order of polynomials", U"3") Manual_DRAW_SETTINGS_WINDOW_BOOLEAN (U"Use bandwidths to model formant tracks", 1) Manual_DRAW_SETTINGS_WINDOW_BOOLEAN (U"Bandwidths for smoothing test", 0) ) TAG (U"##Time range (s)#") DEFINITION (U"determines the position of the intervals that have to be compared.") TAG (U"##Fitter formant range") DEFINITION (U"determines which formant tracks will be modelled with a polynomial function. The goodness of fit of these models will be used in the comparison.") TAG (U"##Order of polynomials") DEFINITION (U"determines the maximum order of the polynomials that are used in modeling each formant track. Order 0 means a model which is a constant function; this model needs only one parameter. Order 1 means a model that is a straight line function; this order needs two parameters. Order 2 means that an additional parabolic function is used in the modeling; order 2 needs therefore 3 parameters. In general an order %p model needs %p+1 parameters.") TAG (U"##Use bandwidths to model formant tracks") DEFINITION (U"Bandwidths give an indication about the sharpness of a spectral peak. Sharp peaks have small bandwidths and, vice versa, broad peaks have large bandwidths. The width of a peak can also be interpreted as a measure of certainty for its formant frequency value. Setting this option %%on%, the default setting, means that you force the modeling function to be closer to frequencies that are well defined, i.e. that have sharp peaks, than to the frequencies of broad peaks, if choices have to be made. The consequence is that in the model sharp peaks will be better represented than broad peaks.") TAG (U"##Bandwidths for smoothing test") DEFINITION (U"determines whether for the smoothnes determination the formant frequencies are still needed. Not using them anymore probably gives a better indication of the smoothness of a track.") MAN_END MAN_BEGIN (U"PowerCepstrogram", U"djmw", 20130616) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") ENTRY (U"Description") NORMAL (U"The PowerCepstrogram shows @@PowerCepstrum|cepstral slices@ as a function of time.") MAN_END MAN_BEGIN (U"PowerCepstrogram: To Table (peak prominence)...", U"djmw", 20130616) INTRO (U"A command to create a table with @@PowerCepstrum: Get peak prominence...|cepstral peak prominence@ values.") ENTRY (U"Settings") SCRIPT (5, Manual_SETTINGS_WINDOW_HEIGHT (7), U"" Manual_DRAW_SETTINGS_WINDOW ("PowerCepstrogram: To Table (peak prominence)", 7) Manual_DRAW_SETTINGS_WINDOW_RANGE("Peak search pitch range (Hz)", U"60.0", U"300.0") Manual_DRAW_SETTINGS_WINDOW_RADIO (U"Interpolation", U"None", 0) Manual_DRAW_SETTINGS_WINDOW_RADIO (U"", U"Parabolic", 0) Manual_DRAW_SETTINGS_WINDOW_RADIO (U"", U"Cubic", 1) Manual_DRAW_SETTINGS_WINDOW_RADIO (U"", U"Sinc70", 0) Manual_DRAW_SETTINGS_WINDOW_RANGE("Tilt line quefrency range (s)", U"0.001", U"0.0 (=end)") Manual_DRAW_SETTINGS_WINDOW_OPTIONMENU(U"Fit method", U"Robust") ) NORMAL (U"The meaning of these settings is explained @@PowerCepstrum: Get peak prominence...|here@.") MAN_END MAN_BEGIN(U"PowerCepstrogram: Paint...", U"djmw", 20131001) INTRO (U"A command to draw the selected @@PowerCepstrogram@ object(s) in shades of grey.") ENTRY (U"Settings") SCRIPT (5, Manual_SETTINGS_WINDOW_HEIGHT (7), U"" Manual_DRAW_SETTINGS_WINDOW (U"PowerCepstrogram: Paint", 7) Manual_DRAW_SETTINGS_WINDOW_RANGE("Time range (s)", U"0.0", U"0.0") Manual_DRAW_SETTINGS_WINDOW_RANGE("Quefrency range (s)", U"0.0", U"0.0") Manual_DRAW_SETTINGS_WINDOW_FIELD("Maximum (dB)", U"80.0") Manual_DRAW_SETTINGS_WINDOW_BOOLEAN("Autoscaling",0) Manual_DRAW_SETTINGS_WINDOW_FIELD("Dynamic range (dB)", U"30.0") Manual_DRAW_SETTINGS_WINDOW_FIELD("Dynamic compression (0-1)", U"0.0") Manual_DRAW_SETTINGS_WINDOW_BOOLEAN("Garnish",1) ) TAG (U"##Time range (s)") DEFINITION (U"the time domain along the %%x% axis.") TAG (U"##Quefrency range (s)") DEFINITION (U"the quefency domain along the %%y% axis.") TAG (U"##Maximum (dB)") DEFINITION (U"cells that have cepstral values greater or equal than this value are drawn in black.") TAG (U"##Autoscaling") DEFINITION (U"If %%on%, overrules the effects of the previous option and the following three options. I.e. the global maximum and the " "global minimum cepstral values determine the maximum blackness and the minimal blackness. Values in-between have apropriate " "values of grey.") TAG (U"##Dynamic range (dB)") DEFINITION (U"All values more than %%Dynamic range% below the maximum will be drawn in white. Values in-between have apropriate " "values of grey.") TAG (U"##Dynamic compression (0-1)") DEFINITION (U"determines how much stronger weak frames should be made before drawing. Normally this parameter is between 0 and 1. " "If it is 0, no dynamic compression will take place. If it is 1, all time frames (vertical bands) will contain cepstral values " "that are drawn in black. If the global %%maximum% is set at 80 dB, %%autoscaling% is off, %%dynamic range% is 30 dB and " "%%dynamic compression% is 0.4 then for a frame with a local maximum of 40 dB all values will be lifted by 0.4*(80-40)=16 dB, " "so that its maximum will be seen at 56 dB (thus making the corresponding cell visible).") TAG (U"##Garnish") DEFINITION (U"Draws a box around the cepstrogram and labels the axes.") MAN_END MAN_BEGIN (U"PowerCepstrogram: Smooth...", U"djmw", 20140117) INTRO (U"Smoothes the selected @PowerCepstrogram by averaging cepstra. The smoothed PowerCepstrogram is the result of two separate steps. " "In the first step, cepsta are averaged across time. In the second step, cepstra are averaged across quefrency.") ENTRY (U"Settings") TAG (U"##Time averaging window (s)") DEFINITION (U"determines how many frames will used in the first step, averaging across time. The user-supplied value will be divided " "by the Cepstrograms's time step value (its %dx). If %%numberOfFramesToAverage%, the result of the division, turns out to be one or less, no averaging across time is performed. " "If %%numberOfFramesToAverage% is larger than one and is even, one will be added. " "Each new cepstral frame will be the average of %numberOfFramesToAverage frames of the input Cepstrogram. " "For example, if %numberOfFramesToAverage turns out to be 5, then the %j-th new cepstral frame is the result of averaging the 5 frames with indices %j\\--2 , %j\\--1, %j, %j+1 and %j+2 for all frames %j=3..%%numberOfFrames%\\--2, i.e. besides frame %j, the 2 frames on either side are used in the averaging. The %numberOfFramesToAverage has to be uneven to allow for this symmetric behaviour. ") TAG (U"##Quefrency averaging window (s)") DEFINITION (U"determines how many quefrency bins will be used for the averaging across quefrency step. The number of bins used in this step " "is the result of the division of the user-supplied value by the quefrency step value (the Cepstrogram's %dy). " "If the result turns out to be one or less, no averaging across quefrencies is performed. If the resulting value is even, one will be added. " "If, for example, the result happens to be 3 then the value in quefrency bin %k will be the average value of the values in quefrency bins " "%k\\--1, %k and %k+1. ") ENTRY (U"Note") NORMAL (U"The following commands should reproduce the smoothing described in the @@Hillenbrand & Houde (1996)@ article, where they use a 20 ms " "(10 frame) time smoothing and a 1 ms (10 bin) quefrency smoothing. ") CODE (U"selectObject (\"Sound xxx\")") CODE (U"To PowerCepstrogram: 0.041, 0.002, 5000.0") CODE (U"Smooth: 0.02, 0.001") MAN_END MAN_BEGIN (U"Cepstrum", U"djmw", 20130616) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") ENTRY (U"Description") NORMAL (U"A Cepstrum is the log spectrum of the log power spectrum.") MAN_END MAN_BEGIN (U"PowerCepstrum", U"djmw", 20130616) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") ENTRY (U"Description") NORMAL (U"A PowerCepstrum is the log power spectrum of the log power spectrum. The vertical scale will show the amplitude expressed in dB. The horizontal scale shows %%quefrency% in units of seconds.") MAN_END MAN_BEGIN (U"PowerCepstrum: Get peak prominence...", U"djmw", 20130616) INTRO (U"Calculates the cepstral peak prominence measure (CPP) as defined by @@Hillenbrand et al. (1994)@") NORMAL (U"The CPP measure is the difference in amplitude between the cepstral peak and the corresponding value on the regression " "line that is directly below the peak (i.e., the predicted magnitude for the quefrency at the cepstral peak). " "The CPP measure represents how far the cepstral peak emerges from the cepstrum background. ") ENTRY (U"Settings") SCRIPT (7, Manual_SETTINGS_WINDOW_HEIGHT (7), U"" Manual_DRAW_SETTINGS_WINDOW (U"PowerCepstrum: Get peak prominence", 7) Manual_DRAW_SETTINGS_WINDOW_RANGE("Search peak in pitch range (s)", U"60.0", U"333.3") Manual_DRAW_SETTINGS_WINDOW_RADIO (U"Interpolation", U"None", 0) Manual_DRAW_SETTINGS_WINDOW_RADIO (U"", U"Parabolic", 0) Manual_DRAW_SETTINGS_WINDOW_RADIO (U"", U"Cubic", 1) Manual_DRAW_SETTINGS_WINDOW_RADIO (U"", U"Sinc70", 0) Manual_DRAW_SETTINGS_WINDOW_RANGE (U"Tilt line quefrency range (s)", U"0.001", U"0.0 (=end)") Manual_DRAW_SETTINGS_WINDOW_OPTIONMENU (U"Fit method", U"Robust") ) TAG (U"##Search peak in pitch range") DEFINITION (U"determine the limits of the quefrency range where a peak is searched for. The lower quefrency is determined as " "1 / %%pitchCeiling% and this value is in general more critical than " "the value of the upper quefrency which equals 1 / %%pitchFloor%. A %%pitchCeiling% of 300 Hz will correspond to a lower quefrency of 1/300\\~~0.0033 seconds.") TAG (U"##Interpolation") DEFINITION (U"determines how the @@vector peak interpolation|amplitude of a peak is determined@.") TAG (U"##Tilt line quefrency range") DEFINITION (U"the quefrency range for which the amplitudes (in dB) will be modelled by a straight line. " "The lower value for this range in the Hillenbrand article was chosen as 0.001 s " "in order to reduce the effect of the low quefrency data on the straight line fit. In our analysis this value is not so critical " "as we use a more robust straight line fit.") TAG (U"##Fit method") DEFINITION (U"the default method is @@theil regression|Theil's robust line fit@. However, to be compatible with the past, a standard least squares line fit has also been implemented.") ENTRY (U"Note") NORMAL (U"The CPP value does not depend on the reference value used in the dB calculation of the power cepstrum.") MAN_END MAN_BEGIN (U"PowerCepstrum: Draw tilt line...", U"djmw", 20130616) INTRO (U"Draws the line that models the backgound of the power cepstrum.") MAN_END MAN_BEGIN (U"Formant & Spectrogram: To IntensityTier...", U"djmw", 20130109) INTRO (U"Determines the formant intensities from the selected Spectrogram.") NORMAL (U"The intensities at the frequencies of the selected formant are copied from the corresponding positions in the spectrogram. " "If the selected formant doesn't exist in a particular frame, then a large negative value (< -200 dB) is substituted instead. " "Because the values in the spectrogram are expressed in Pa^^2^/Hz, the units in the intensity tier are in dB/Hz. ") MAN_END MAN_BEGIN (U"LFCC", U"djmw", 20040421) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"An object of type LFCC represents cepstral " "coefficients on a linear frequency scale as a function of time. " "The coefficients are represented in frames with constant sampling " "period.") ENTRY (U"#LFCC commands") NORMAL (U"Creation:") LIST_ITEM (U"\\bu @@LPC: To LFCC...") MAN_END MAN_BEGIN (U"LFCC: To LPC...", U"djmw", 20040407) INTRO (U"You can choose this command after selecting 1 or more @LFCC's.") ENTRY (U"Settings") TAG (U"##Number of coefficients") DEFINITION (U"the desired number of linear predictive coefficients.") ENTRY (U"Behaviour") NORMAL (U"The transformation from cepstral coefficients to %a-coefficients " "as described in @@Markel & Gray (1976)@.") MAN_END MAN_BEGIN (U"LPC", U"djmw", 19990610) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"An object of type LPC represents filter coefficients as a function of time. " "The coefficients are represented in frames with constant sampling period.") ENTRY (U"LPC commands") NORMAL (U"Creation:") LIST_ITEM (U"\\bu @@Sound: To LPC (autocorrelation)...@") LIST_ITEM (U"\\bu @@Sound: To LPC (covariance)...@") LIST_ITEM (U"\\bu @@Sound: To LPC (burg)...@") LIST_ITEM (U"\\bu @@Sound: To LPC (marple)...@") ENTRY (U"Conversion") LIST_ITEM (U"\\bu @@LPC: To LFCC...|To LFCC...@") LIST_ITEM (U"\\bu @@LPC: To Spectrogram...|To Spectrogram...@") LIST_ITEM (U"\\bu @@LPC: To Spectrum (slice)...|To Spectrum (slice)...@") LIST_ITEM (U"\\bu @@LPC: To Polynomial (slice)...|To Polynomial (slice)...@") MAN_END MAN_BEGIN (U"LPC: Draw gain...", U"djmw", 20040407) INTRO (U"You can choose this command after selecting 1 or more @LPC objects.") ENTRY (U"Settings") TAG (U"##From time (s)#, ##To time (seconds)#") DEFINITION (U"the time domain along the %x-axis.") TAG (U"##Minimum gain#, ##Maximum gain#") DEFINITION (U"the range for the %y-axis.") TAG (U"##Garnish") DEFINITION (U"determines whether to draw a bounding box and axis labels.") ENTRY (U"Behaviour") NORMAL (U"Gain will be drawn as a function of time (gain also equals the prediction error " "energy). ") MAN_END MAN_BEGIN (U"LPC: Draw poles...", U"djmw", 20040407) INTRO (U"You can choose this command after selecting 1 or more @LPC objects.") ENTRY (U"Settings") TAG (U"##Time (s)") DEFINITION (U"the time of the nearest frame.") ENTRY (U"Behaviour") NORMAL (U"The @@Roots|roots@ of the @@LPC: To Polynomial (slice)...|linear prediction " "polynomial@, constructed from the coefficients " "of the analysis frame, will be drawn in the complex plane.") MAN_END MAN_BEGIN (U"LPC: To LFCC...", U"djmw", 20040407) INTRO (U"You can choose this command after selecting 1 or more @LPC objects.") ENTRY (U"Behaviour") NORMAL (U"The transformation from a-coefficients to cepstral coefficients " "as described in @@Markel & Gray (1976)@.") ENTRY (U"Settings") TAG (U"%%Number of coefficients%") DEFINITION (U"the desired number of cepstral coefficients.") MAN_END MAN_BEGIN (U"LPC: To Matrix", U"djmw", 20011123) INTRO (U"Copies the linear prediction coefficients of the selected @LPC " "object to a newly created @Matrix object.") ENTRY (U"Behaviour") FORMULA (U"%z__%ji_ = %a__%ij_, with 1 \\<_ %i \\<_ %nx and " "1 \\<_ j \\<_ %nCoefficients__%i_,") NORMAL (U"where %z__%ji_ is the matrix element in row %j and column %i and " "%a__%ij_ is the %j-th linear prediction coefficient in frame %i.") MAN_END MAN_BEGIN (U"LPC: To Formant", U"djmw", 19970123) INTRO (U"You can choose this command after selecting 1 or more @LPC objects.") ENTRY (U"Behaviour") NORMAL (U"For each LPC_Frame, the zeros of the linear prediction polynomial are extracted. " "Zeros that are outside the unit circle are reflected into it. " "Next, formant frequencies and bandwidths are calculated from all the roots that have the " "imaginary part positive, i.e., that lie in the upper half of the unit circle. " "Formant frequencies smaller than 50 Hz or larger than (%Nyquist_frequency - 50) are discarded. " "The remaining frequencies and bandwidths are sorted " "and copied to the Formant_Frame. Finally, the %gain field of the LPC is copied to the %intensity " "field of the Formant_Frame.") ENTRY (U"Algorithm") NORMAL (U"The root finder is Laguerre's method followed by root polishing, see @@Press " "et al. (1992)@.") ENTRY (U"Warning") LIST_ITEM (U"\\bu The formant values can be very inaccurate if you did not resample the Sound " "before the LPC-analysis (consult the @@Source-filter synthesis@ tutorial).") LIST_ITEM (U"\\bu The results of the root finder may not always be accurate when more than 30 " "roots have to be found.") MAN_END MAN_BEGIN (U"LPC: To Polynomial (slice)...", U"djmw", 20040407) INTRO (U"A command that creates a Polynomial object from each selected @LPC object.") ENTRY (U"Settings") TAG (U"##Time (s)") DEFINITION (U"defines the LPC frame whose coefficents will be selected.") ENTRY (U"Behaviour") NORMAL (U"The linear prediction coefficients %a__1..%n_ of the selected LPC " "frame will be copied to polynomial coefficients %c__1..%n+1_ as follows:") FORMULA (U"%c__%i_ = %a__%n\\--%i+1_, ") FORMULA (U"%c__%n+1_ = 1") MAN_END MAN_BEGIN (U"LPC: To Spectrum (slice)...", U"djmw", 20071120) INTRO (U"You can choose this command after selecting 1 or more @LPC objects.") ENTRY (U"Settings") TAG (U"##Time (s)") DEFINITION (U"the time at which the Spectrum must be calculated.") TAG (U"##Minimum frequency resolution (Hz)") DEFINITION (U"successive frequencies in the @Spectrum " "will be maximally this distance apart.") TAG (U"##Bandwidth reduction (Hz)") DEFINITION (U"formants with small bandwidths show up very well as peaks in the spectrum because the poles " "lie close to the contour along which the spectrum is computed (the unit circle in the z-plane). " "Peak enhancement can be realized by computing the spectrum in the z-plane along a contour of radius " "%r = exp (\\-- %\\pi \\.c %bandwidthReduction / %samplingFrequency). " "This technique is also called off-axis spectrum computation. " "Negative values evaluate the spectrum on a contour %outside the unit circle and therefore result in a " "flattened spectrum.") TAG (U"##De-emphasis frequency (Hz)") DEFINITION (U"Performs de-emphasis when frequency is in the interval (0, @@Nyquist frequency@)") ENTRY (U"Algorithm") NORMAL (U"The Spectrum at time %t will be calculated from the %nearest LPC_Frame according to:") FORMULA (U"Spectrum (%f) = \\Vr(%gain\\.c%T/%df) / (1 + \\su__%k=1..%numberOfCoefficients_ %a__%k_%z^^\\--%k^),") NORMAL (U"where %T is the sampling period and %z = exp (\\--2 %\\pi %i %f %T) and %df is the distance in Hz " "between two successive components in the Spectrum.") LIST_ITEM (U"1. Allocate a large enough buffer[1..%nfft] to perform an FFT analysis.") LIST_ITEM (U"2. Make the first value of the buffer 1 and copy the prediction coefficients #a into " "the buffer. This results in buffer values: (1, %a__1_, ..., %a__%numberOfCoefficients_, 0, ..., 0).") LIST_ITEM (U"3. If ##De-emphasis frequency# is in the interval (0, %nyquistFrequency) then \"multiply\" " "the buffer with (1 - %b %z^^\\--1^), where %b = exp (\\-- %\\pi %deEmphasisFrequency %T). " "This results in buffer values: (1, %a__1_\\--%b, %a__2_\\--%b\\.c%a__1_, ..., " "%a__%numberOfCoefficients_\\--%b\\.c%a__%numberOfCoefficients\\--1_, " "\\--%b\\.c%a__%numberOfCoefficients_, 0, ..., 0). Note that the number of values in the buffer that differ from 0 " "has increased by one.") LIST_ITEM (U"4. If ##Bandwidth reduction# is greater than 0 then multiply corresponding values in the buffer by %g^^%i\\--1^ where " "%g = exp (2%\\pi %bandwidthReduction %T / %nfft), and %i is the position index in the buffer. " "%i runs from 1 to %numberOfCoefficients+1+%t, where %t equals 1 when de-emphasis was performed, " "else 0.") LIST_ITEM (U"5. Calculate the FFT spectrum of the buffer with the coefficients. This results in complex " "amplitudes (%a__%j_,%b__%j_), %j=1..%nfft/2+1.") LIST_ITEM (U"6. Calculate the LPC Spectrum by taking the inverse of the FFT spectrum, i.e., each complex " "amplitude becomes (%a__%j_,%b__%j_)^^\\--1^ = (%a__%j_,\\--%b__%j_) / (%a__%j_^2 + %b__%j_^2)") LIST_ITEM (U"7. Multiply all values with the scale factor \\Vr(%gain\\.c%T/%df).") MAN_END MAN_BEGIN (U"LPC: To Spectrogram...", U"djmw", 20040407) INTRO (U"You can choose this command after selecting 1 or more @LPC objects.") ENTRY (U"Settings") TAG (U"##Minimum frequency resolution (Hz)") DEFINITION (U"successive frequencies in the Spectrum will be maximally this distance apart") TAG (U"##Bandwidth reduction (Hz)") DEFINITION (U"formants with small bandwidths show up very well as darker regions in the spectrogram " "because the poles lie close to the contour along which a spectrum is computed (the unit circle " "in the z-plane). " "Peak enhancement can be realized by computing a spectrum in the z-plane along a contour of radius " "%r = exp (\\-- %\\pi \\.c %bandwidthReduction / %samplingFrequency).") TAG (U"##De-emphasis frequency (Hz)") DEFINITION (U"Performs de-emphasis when value is in the interval (0, @@Nyquist frequency@)") ENTRY (U"Algorithm") NORMAL (U"For each LPC_Frame the corresponding Spectrum will be calculated according to the algorithm " "explained in @@LPC: To Spectrum (slice)...@. " "For each frequency the power, i.e., the square of the complex values, will be stored in the " "corresponding area in the Spectrogram.") MAN_END MAN_BEGIN (U"LPC: To VocalTract (slice)...", U"djmw", 20050615) INTRO (U"You can choose this command after selecting 1 or more @LPC objects.") ENTRY (U"Settings") TAG (U"##Time (s)") DEFINITION (U"the time of the nearest frame, in seconds.") TAG (U"##Length (m)") DEFINITION (U"the length of the vocal tract, in metres.") /* TAG (U"##Compute length according to Wakita") DEFINITION (U"the length of the vocal tract is calculated according " "to the algorithm as described in @@Wakita (1977)@.") ENTRY (U"Behaviour") NORMAL (U"A new @VocalTract area function is calculated from the prediction coefficients in the frame. ") ENTRY (U"Warning") NORMAL (U"If ##Compute length according to Wakita# is on, the optimal length is searched for in the range from 0.1 m to " "0.25 m. This length calculation is extremely sensitive to the number of and the positions of the formants " "with respect to the @@Nyquist frequency@. For example, there is a large difference " "between the vocal tract length estimates if the highest formant is just below or just above the " "Nyquist frequency. " "The algorithm is not very reliable in vocal tract length estimation and we do not recommend using it. " )*/ MAN_END MAN_BEGIN (U"LPC & Sound: Filter...", U"djmw", 20040407) INTRO (U"A command that creates a new Sound object from one @Sound and one @LPC " "object which have been selected together.") ENTRY (U"Settings") TAG (U"##Use LPC gain") DEFINITION (U"Determines whether the gain from the LPC is used in the synthesis.") ENTRY (U"Behaviour") NORMAL (U"Filters the selected Sound by the selected LPC-filter.") NORMAL (U"When the LPC-gain is used the samples in the new Sound will be " "multiplied with the square root of the corresponding LPC-gain value.") NORMAL (U"In #Z-domain notation: #O(%z) = #H(%z) \\.c #E(%z), where " "#E(%z) is the selected filter input Sound, #H(%z) the selected LPC filter, " "and, #O(%z) the filter output (the new Sound that will appear in the List of objects).") MAN_END MAN_BEGIN (U"LPC & Sound: Filter with filter at time...", U"djmw", 20101009) INTRO (U"Filters the selected @Sound with a static filter that is formed by the filter coefficients " "from only one @LPC frame.") ENTRY (U"Settings") TAG (U"##Channel") DEFINITION (U"determines the sound channel to be filtered.") TAG (U"##Use filter at time (s)") DEFINITION (U"determines which LPC frame will be chosen to filter the sound. ") MAN_END MAN_BEGIN (U"LPC & Sound: Filter (inverse)", U"djmw", 19970126) INTRO (U"A command that creates a new Sound object from one @Sound and one @LPC " "object which have been selected together.") ENTRY (U"Behaviour") NORMAL (U"Given a filter (the selected LPC) and its output (the selected Sound), " "its input is reconstructed (the new Sound that will appear in the List of objects).") NORMAL (U"In Z-domain notation: #E(%z) = #O(%z) / #H(%z), where " "#O(%z) is the filter output Sound, #H(%z) the LPC filter, and, #E(%z) the filter " "input Sound. (Selecting this newly generated Sound and the LPC, choosing the option " "`Filter...' generates a Sound that is identical to the Sound that originated " "the LPC.)") MAN_END MAN_BEGIN (U"LPC & Sound: Filter (inverse) with filter at time...", U"djmw", 20101009) INTRO (U"%%Inverse% filters the selected @Sound with a static inverse filter that is formed by the filter coefficients " "from only one @LPC frame.") ENTRY (U"Settings") TAG (U"##Channel") DEFINITION (U"determines the sound channel to be filtered.") TAG (U"##Use filter at time (s)") DEFINITION (U"determines which LPC frame will be chosen to inverse filter the sound. ") MAN_END MAN_BEGIN (U"MFCC", U"djmw", 20141022) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"An object of type MFCC represents mel frequency cepstral coefficients " "as a function of time. The coefficients are represented in frames " "at constant sampling period.") ENTRY (U"MFCC commands") NORMAL (U"Creation:") LIST_ITEM (U"\\bu @@Sound: To MFCC...@") LIST_ITEM (U"\\bu @@MelSpectrogram: To MFCC...@") MAN_END MAN_BEGIN (U"MFCC: To MelFilter...", U"djmw", 20141023) INTRO (U"A #deprecated command replaced by @@MFCC: To MelSpectrogram...@.") ENTRY (U"Settings") TAG (U"##From coefficient#, ##To coefficient#") DEFINITION (U"the range of coefficients that will be used in the reconstruction.") ENTRY (U"Details") NORMAL (U"The output of the triangular filters in a mel filter bank will be " "reconstructed by applying the inverse cosine transform:") FORMULA (U"%P__%j_ = 2/N (%c__0_/2 + \\Si__%k=1_^^%N-1^ %c__%k_ cos (\\pi%k(%j-0.5)/%N))),") NORMAL (U"where %N represents the number of filters, %j runs from 1 to %N, and coefficients %c__%k_ with %k less than " "%%fromCoefficient% and %k larger than %%toCoefficient% take zero values in the evaluation.") MAN_END MAN_BEGIN (U"MFCC: To MelSpectrogram...", U"djmw", 20141023) INTRO (U"A command to (re)construct a @MelSpectrogram object from the selected @MFCC object.") ENTRY (U"Settings") TAG (U"##From coefficient#, ##To coefficient#") DEFINITION (U"the range of coefficients that will be used in the reconstruction.") TAG (U"##Include constant term") DEFINITION (U"selects whether or not to include the %c__0_ coefficient in the reconstruction. As can be seen from the formula below, the contribution of the %c__0_ term is equal for each filter.") ENTRY (U"Details") NORMAL (U"The values %P__%j_ in each frame of the MelSpectrogram will be constructed by applying the inverse Discrete Cosine Transform to the corresponding frame of the MFCC object:") FORMULA (U"%P__%j_ = 2/N (%c__0_/2 + \\Si__%k=1_^^%N-1^ %c__%k_ cos (\\pi%k(%j-0.5)/%N))),") NORMAL (U"where %N represents the number of filters that were used to get the MFCC object, %j runs from 1 to %N, and coefficients %c__%k_ with %k less than " "%%fromCoefficient% and %k larger than %%toCoefficient% take zero values in the evaluation.") MAN_END MAN_BEGIN (U"Sound: To PowerCepstrogram...", U"djmw", 20130616) INTRO (U"A command that creates a @@PowerCepstrogram@ from every selected @@Sound@.") ENTRY (U"Settings") TAG (U"##Pitch floor (Hz)") DEFINITION (U"determines the effective length of the analysis window: it will be 3 longest periods long, i.e. if the pitch floor is 60 Hz, the window will be 3/60 = 0.05 seconds long.") TAG (U"##Time step (s)") TAG (U"##Maximum frequency (Hz)") TAG (U"##Pre-emphasis from (Hz)") MAN_END MAN_BEGIN (U"Sound: To Formant (robust)...", U"djmw", 20111027) INTRO (U"A command that creates a @@Formant@ object from every selected @@Sound@. ") ENTRY (U"Settings") NORMAL (U"The settings for ##Time step (s)#, ##Maximum number of formants#, ##Maximum formant (Hz), " "##Window length (s)# and ##Pre emphasis from (Hz)# are as in @@Sound: To Formant (burg)...@. " " The following settings determine aspects of the iterative formant frequency refinement.") TAG (U"%%Number of std. dev.%,") DEFINITION (U"determines the number of standard deviation from where selective weighing of samples starts. ") TAG (U"%%Maximum number of iterations%,") DEFINITION (U"determines the maximum number of iterations allowed in the refinement step.") TAG (U"%%Tolerance%,") DEFINITION (U"detemines another stop ctriterion for the refinement step. If the relative change in variance " "between successive iterations is less then this value, iteration stops. Iteration stops whenever " "one of the two defined stop criteria is reached.") ENTRY (U"Algorithm") NORMAL (U"First the sound is downsampled to twice the maximum formant frequency. Next the LPC coefficients are determined by the autocorrelation method. Finally, in an iterative procedure as described by @@Lee (1988)@ the formant frequencies and bandwidths are refined by selectively weighting of samples values.") MAN_END MAN_BEGIN (U"Sound: LPC analysis", U"djmw", 19970126) INTRO (U"You can perform this analysis by selecting one or more @Sound objects and " "choosing the appropriate command to generate an @LPC.") NORMAL (U"The acronym LPC stands for Linear Predictive Coding.") NORMAL (U"In the LPC analysis one tries to predict %x__%n_ on the basis of the %p previous samples,") FORMULA (U"%x\\'p__%n_ = \\su %a__%k_ %x__%%n-k%_") NORMAL (U"then {%a__1_, %a__2_, ..., %a__%p_} can be chosen to minimize the prediction power %%Q__p_% where") FORMULA (U"%%Q__p_% = E[ |%x__%n_ - %x\\'p__%n_|^2].") NORMAL (U"Several different algorithms exist for minimizing %%Q__p_%:") LIST_ITEM (U"\\bu @@Sound: To LPC (autocorrelation)...|To LPC (autocorrelation)...@") LIST_ITEM (U"\\bu @@Sound: To LPC (covariance)...|To LPC (covariance)...@") LIST_ITEM (U"\\bu @@Sound: To LPC (burg)...|To LPC (burg)...@") LIST_ITEM (U"\\bu @@Sound: To LPC (marple)...|To LPC (marple)...@") MAN_END #define Sound_to_LPC_COMMON_HELP(method) \ INTRO (U"With this command you create a new @LPC from every selected @Sound, " \ "using " #method " method.") \ ENTRY (U"Warning") \ NORMAL (U"You are advised not to use this command for formant analysis. " \ "For formant analysis, instead use @@Sound: To Formant (burg)...@, " \ "which also works via LPC (linear predictive coding). This is because " \ "##Sound: To Formant (burg)...# lets you specify a maximum frequency, " \ "whereas the ##To LPC# commands automatically use the @@Nyquist frequency@ " \ "as their maximum frequency. If you do use one of the ##To LPC# commands " \ "for formant analysis, you may therefore want to downsample the sound first. " \ "For instance, if you want five formants below 5500 Hz but your Sound has a sampling frequency " \ "of 44100 Hz, you have to downsample the sound to 11000 Hz with the @@Sound: Resample...@ command. " \ "After that, you can use the ##To LPC# commands, with a prediction order of 10 or 11.") \ ENTRY (U"Settings") \ TAG (U"##Prediction order#") \ DEFINITION (U"the number of linear prediction coefficients, also called the %%number of poles%. " \ "Choose this number at least twice as large as the number of spectral peaks that you want " \ "to detect.") \ TAG (U"##Analysis window duration (s)") \ DEFINITION (U"the effective duration of each analysis frame, in seconds.") \ TAG (U"##Time step (s)") \ DEFINITION (U"the time step between two consecutive analysis frames.") \ TAG (U"##Pre-emphasis frequency (Hz)") \ DEFINITION (U"a +6dB / octave filtering will be applied above this frequency. " \ "A pre-emphasis frequency of 48.47 Hz for a signal with a sampling frequency of 10 kHz " \ "approximately corresponds to a value of %a = 0.97 for the filter %y__%n_ = %x__%n_ - %a \\.c %x__%n-1_. " \ "The relation between %a and the pre-emphasis frequency is: " \ "%a = exp (\\--2\\.c%\\pi\\.c%preemphasisFrequency/%samplingFrequency). " \ "If you do not want pre-emphasis, choose a frequency greater than the @@Nyquist frequency@.") MAN_BEGIN (U"Sound: To LPC (autocorrelation)...", U"David Weenink & Paul Boersma", 20040407) Sound_to_LPC_COMMON_HELP ("the autocorrelation") ENTRY (U"Algorithm") NORMAL (U"The autocorrelation algorithm is decribed in @@Markel & Gray (1976)@.") MAN_END MAN_BEGIN (U"Sound: To LPC (covariance)...", U"David Weenink & Paul Boersma", 20040407) Sound_to_LPC_COMMON_HELP ("the covariance") ENTRY (U"Algorithm") NORMAL (U"The covariance algorithm is decribed in @@Markel & Gray (1976)@.") MAN_END MAN_BEGIN (U"Sound: To LPC (marple)...", U"djmw", 19970126) Sound_to_LPC_COMMON_HELP ("Marple's") TAG (U"##Tolerance 1") DEFINITION (U"stop the iteration when %E(%m) / %E(0) < %%Tolerance 1%, where %E(%m) is the " "prediction error for order %m.") TAG (U"##Tolerance 2") DEFINITION (U"stop the iteration when (%E(%m) - %E(%m-1)) / %E(%m-1) < %%Tolerance 2.") ENTRY (U"Algorithm") NORMAL (U"The algorithm is described in @@Marple (1980)@.") MAN_END MAN_BEGIN (U"Sound: To LPC (burg)...", U"David Weenink & Paul Boersma", 20040407) Sound_to_LPC_COMMON_HELP ("Burg's") ENTRY (U"Algorithm") NORMAL (U"Burg's algorithm is described in @@Anderson (1978)@") MAN_END MAN_BEGIN (U"Sound: To MFCC...", U"djmw", 20141022) INTRO (U"A command that creates a @MFCC object from every selected @Sound " "object.") NORMAL (U"The analysis proceeds in two steps:") LIST_ITEM (U"1. We perform a spectrum analysis on a mel frequency scale " "(see @@Sound: To MelSpectrogram...@ for details).") LIST_ITEM (U"2. We convert the melspectrogram values to mel frequency cepstral " "coefficients (see @@MelSpectrogram: To MFCC...@ for details).") MAN_END MAN_BEGIN (U"VocalTractTier", U"djmw", 20120423) INTRO (U"One of the @@types of objects@ in Praat. A VocalTractTier objects contains a number of (%time, %VocalTract) points, where a @@VocalTract@ represents the area function of the vocal tract expressed as m^^2^, running from the glottis to the lips.") MAN_END MAN_BEGIN (U"theil regression", U"djmw", 20130710) NORMAL (U"a robust linear regression method, first proposed by @@Theil (1950)@. The slope of the regression line is estimated as " "the median of all pairwise slopes between each pair of points in the data set. Because this number of pairs increases quadratically " "with the number of data points, we have implemented a somewhat less computationally intensive procedure, the %%incomplete% theil regression. In the incomplete method we first split the data set of %N data points (%x__%i_, %y__%i_), %i = 1..%N, in two equal sets " "of size %N/2 and then calculate %N/2 slopes as ") FORMULA (U"%m__%i_ = (%y__%N/2+%i_ - %y__%i_) / (%x__%N/2+%i_ - %x__%i_), for %i = 1..%N/2.") NORMAL (U"The regression slope %m is calculated as the median of these %N/2 values %m__%i_.") NORMAL (U"Given the slope %m, the offset %b is calculated as the median of the %N values %b__%i_= %y__%i_ - %m\\.c%x__%i_.") NORMAL (U"The theil regression has a breakdown point of 29.3\\% , which means that it can tolerate arbitrary corruption of up to 29.3% of the input data-points without degradation of its accuracy") MAN_END MAN_BEGIN (U"Anderson (1978)", U"djmw", 20030701) NORMAL (U"N. Anderson (1978): \"On the calculation of filter coefficients for " "maximum entropy spectral analysis.\" In Childers: %%Modern Spectrum Analysis%, " "IEEE Press: 252\\--255.") MAN_END MAN_BEGIN (U"Hillenbrand et al. (1994)", U"djmw", 20121017) NORMAL (U"J. Hillenbrand, R.A. Cleveland & R.L. Erickson (1994): \"Acoustic correlates of breathy vocal quality\", %%Journal of speech and hearing research% #37: 769\\--778.") MAN_END MAN_BEGIN (U"Hillenbrand & Houde (1996)", U"djmw", 20121203) NORMAL (U"J. Hillenbrand & R.A. Houde (1996): \"Acoustic correlates of breathy vocal quality: Dysphonic voices and continuous speech\", %%Journal of speech and hearing research% #39: 311\\--321.") MAN_END MAN_BEGIN (U"Lee (1988)", U"djmw", 20111027) NORMAL (U"C.-H. Lee (1988): \"On Robust Linear Prediction of Speech.\", %%IEEE Trans. on ASSP% #36: 642\\--649.") MAN_END MAN_BEGIN (U"Markel & Gray (1976)", U"djmw", 19980114) NORMAL (U"J.D. Markel & A.H. Gray, Jr. (1976): %%Linear Prediction of Speech.% " "Springer Verlag, Berlin.") MAN_END MAN_BEGIN (U"Marple (1980)", U"djmw", 19980114) NORMAL (U"L. Marple (1980): \"A new autoregressive spectrum analysis algorithm.\" " "%%IEEE Trans. on ASSP% #28, 441\\--454.") MAN_END MAN_BEGIN (U"Theil (1950)", U"djmw", 20121118) NORMAL (U"H. Theil (1950): \"A rank-invariant method of linear and polynomial regression analysis\", " "%%Proceedings of Koninklijke Nederlandse Akademie van Wetenschappen% ##A.53#: 1397\\--1412.") MAN_END MAN_BEGIN (U"Wakita (1977)", U"djmw", 19980114) NORMAL (U"H. Wakita (1977): \"Normalization of vowels by vocal-tract " "length and its application to vowel identification.\" %%IEEE Trans. on ASSP% " "#25: 183\\--192.") MAN_END } /* BUGS: 19980217 djmw LPC_and_Sound_filter ilast was not always defined. 19980322 djmw Sound_into_LPC_Frame_auto did not return (nCoefficients == 0) when (r[1] == 0). */ /* End of file manual_LPC.c */ praat-6.0.04/LPC/praat_LPC_init.cpp000066400000000000000000001422101261542461700166720ustar00rootroot00000000000000/* praat_LPC_init.cpp * * Copyright (C) 1994-2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20030613 Latest modification djmw 20040414 Forms texts. djmw 20060428 Latest modification djmw 20061218 Changed to Melder_information format. djmw 20070902 Melder_error<1...> djmw 20071011 REQUIRE requires L"". djmw 20080313 Cepstrum_formula djmw 20100212 Analysis window length is now "Window length" */ #include #include "Cepstrumc.h" #include "Cepstrogram.h" #include "Cepstrum_and_Spectrum.h" #include "DTW.h" #include "FilterBank.h" #include "Formant_extensions.h" #include "LPC.h" #include "MFCC.h" #include "LFCC.h" #include "LPC_and_Cepstrumc.h" #include "LPC_and_Formant.h" #include "LPC_and_LFCC.h" #include "LPC_and_Polynomial.h" #include "LPC_and_Tube.h" #include "LPC_to_Spectrogram.h" #include "LPC_to_Spectrum.h" #include "NUM2.h" #include "praatP.h" #include "Sound_and_LPC.h" #include "Sound_and_LPC_robust.h" #include "Sound_and_Cepstrum.h" #include "Sound_to_MFCC.h" #include "VocalTractTier.h" #undef iam #define iam iam_LOOP static const char32 *DRAW_BUTTON = U"Draw -"; static const char32 *QUERY_BUTTON = U"Query -"; static const char32 *MODIFY_BUTTON = U"Modify -"; void praat_CC_init (ClassInfo klas); void praat_TimeFrameSampled_query_init (ClassInfo klas); void praat_TimeFunction_modify_init (ClassInfo klas); int praat_Fon_formula (UiForm dia, Interpreter interpreter); /********************** Cepstrum ****************************************/ DIRECT (Cepstrum_downto_PowerCepstrum) LOOP { iam (Cepstrum); autoPowerCepstrum thee = Cepstrum_downto_PowerCepstrum (me); praat_new (thee.transfer(), my name); } END DIRECT (PowerCepstrum_help) Melder_help (U"PowerCepstrum"); END FORM (Cepstrum_drawLinear, U"Cepstrum: Draw linear", U"Cepstrum: Draw (linear)...") REAL (U"left Quefrency range (s)", U"0.0") REAL (U"right Quefrency range (s)", U"0.0") REAL (U"Minimum", U"0.0") REAL (U"Maximum", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (Cepstrum); Cepstrum_drawLinear (me, GRAPHICS, GET_REAL (U"left Quefrency range"), GET_REAL (U"right Quefrency range"), GET_REAL (U"Minimum"), GET_REAL (U"Maximum"), GET_INTEGER (U"Garnish")); } END FORM (PowerCepstrum_draw, U"PowerCepstrum: Draw", U"PowerCepstrum: Draw...") REAL (U"left Quefrency range (s)", U"0.0") REAL (U"right Quefrency range (s)", U"0.0") REAL (U"Minimum (dB)", U"0.0") REAL (U"Maximum (dB)", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (PowerCepstrum); PowerCepstrum_draw (me, GRAPHICS, GET_REAL (U"left Quefrency range"), GET_REAL (U"right Quefrency range"), GET_REAL (U"Minimum"), GET_REAL (U"Maximum"), GET_INTEGER (U"Garnish")); } END FORM (PowerCepstrum_drawTiltLine, U"PowerCepstrum: Draw tilt line", U"PowerCepstrum: Draw tilt line...") REAL (U"left Quefrency range (s)", U"0.0") REAL (U"right Quefrency range (s)", U"0.0") REAL (U"left Amplitude range (dB)", U"0.0") REAL (U"right Amplitude range (dB)", U"0.0") LABEL (U"", U"Parameters for the tilt line fit") REAL (U"left Tilt line quefrency range (s)", U"0.001") REAL (U"right Tilt line quefrency range (s)", U"0.0 (=end)") OPTIONMENU (U"Line type", 1) OPTION (U"Straight") OPTION (U"Exponential decay") OPTIONMENU (U"Fit method", 2) OPTION (U"Least squares") OPTION (U"Robust") OK DO autoPraatPicture picture; LOOP { iam (PowerCepstrum); PowerCepstrum_drawTiltLine (me, GRAPHICS, GET_REAL (U"left Quefrency range"), GET_REAL (U"right Quefrency range"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range"), GET_REAL (U"left Tilt line quefrency range"), GET_REAL (U"right Tilt line quefrency range"), GET_INTEGER (U"Line type"), GET_INTEGER (U"Fit method")); } END FORM (PowerCepstrum_formula, U"PowerCepstrum: Formula...", U"PowerCepstrum: Formula...") LABEL (U"label", U"y := y1; for row := 1 to nrow do { x := x1; " "for col := 1 to ncol do { self [row, col] := `formula' ; x := x + dx } y := y + dy }") TEXTFIELD (U"formula", U"self") OK DO praat_Fon_formula (dia, interpreter); END FORM (PowerCepstrum_getPeak, U"PowerCepstrum: Get peak", 0) REAL (U"left Search peak in pitch range (Hz)", U"60.0") REAL (U"right Search peak in pitch range (Hz)", U"333.3") RADIO (U"Interpolation", 2) RADIOBUTTON (U"None") RADIOBUTTON (U"Parabolic") RADIOBUTTON (U"Cubic") RADIOBUTTON (U"Sinc70") OK DO LOOP { iam (PowerCepstrum); double peakdB, quefrency; PowerCepstrum_getMaximumAndQuefrency (me, GET_REAL (U"left Search peak in pitch range"), GET_REAL (U"right Search peak in pitch range"), GET_INTEGER (U"Interpolation") - 1, &peakdB, &quefrency); Melder_informationReal (peakdB, U" dB"); } END FORM (PowerCepstrum_getQuefrencyOfPeak, U"PowerCepstrum: Get quefrency of peak", 0) REAL (U"left Search peak in pitch range (Hz)", U"60.0") REAL (U"right Search peak in pitch range (Hz)", U"333.3") RADIO (U"Interpolation", 2) RADIOBUTTON (U"None") RADIOBUTTON (U"Parabolic") RADIOBUTTON (U"Cubic") RADIOBUTTON (U"Sinc70") OK DO LOOP { iam (PowerCepstrum); double peakdB, quefrency; PowerCepstrum_getMaximumAndQuefrency (me, GET_REAL (U"left Search peak in pitch range"), GET_REAL (U"right Search peak in pitch range"), GET_INTEGER (U"Interpolation") - 1, &peakdB, &quefrency); double f = 1.0 / quefrency; Melder_information (quefrency, U" s (f =", f, U" Hz)"); } END FORM (PowerCepstrum_getRNR, U"PowerCepstrum: Get rhamonics to noise ration", 0) REAL (U"left Pitch range (Hz)", U"60.0") REAL (U"right Pitch range (Hz)", U"333.3") POSITIVE (U"Fractional width (0-1)", U"0.05") OK DO LOOP { iam (PowerCepstrum); double rnr = PowerCepstrum_getRNR (me, GET_REAL (U"left Pitch range"), GET_REAL (U"right Pitch range"), GET_REAL (U"Fractional width")); Melder_information (rnr, U" (rnr)"); } END FORM (PowerCepstrum_getPeakProminence_hillenbrand, U"PowerCepstrum: Get peak prominence (hillenbrand)", U"PowerCepstrum: Get peak prominence (hillenbrand)...") REAL (U"left Search peak in pitch range (Hz)", U"60.0") REAL (U"right Search peak in pitch range (Hz)", U"333.3") OK DO LOOP { iam (PowerCepstrum); double qpeak, cpp = PowerCepstrum_getPeakProminence_hillenbrand (me, GET_REAL (U"left Search peak in pitch range"), GET_REAL (U"right Search peak in pitch range"), &qpeak); Melder_information (cpp, U" dB; quefrency=", qpeak, U" s (f=", 1.0 / qpeak, U" Hz)."); } END FORM (PowerCepstrum_getTiltLineSlope, U"PowerCepstrum: Get tilt line slope", 0) REAL (U"left Tilt line quefrency range (s)", U"0.001") REAL (U"right Tilt line quefrency range (s)", U"0.0 (=end)") OPTIONMENU (U"Line type", 1) OPTION (U"Straight") OPTION (U"Exponential decay") OPTIONMENU (U"Fit method", 2) OPTION (U"Least squares") OPTION (U"Robust") OK DO LOOP { iam (PowerCepstrum); double a, intercept; int lineType = GET_INTEGER (U"Line type"); PowerCepstrum_fitTiltLine (me, GET_REAL (U"left Tilt line quefrency range"), GET_REAL (U"right Tilt line quefrency range"), &a, &intercept, lineType, GET_INTEGER (U"Fit method")); Melder_information (a, U" dB / ", lineType == 1 ? U"s" : U"ln (s)"); } END FORM (PowerCepstrum_getTiltLineIntercept, U"PowerCepstrum: Get tilt line intercept", 0) REAL (U"left Tilt line quefrency range (s)", U"0.001") REAL (U"right Tilt line quefrency range (s)", U"0.0 (=end)") OPTIONMENU (U"Line type", 1) OPTION (U"Straight") OPTION (U"Exponential decay") OPTIONMENU (U"Fit method", 2) OPTION (U"Least squares") OPTION (U"Robust") OK DO LOOP { iam (PowerCepstrum); double a, intercept; int lineType = GET_INTEGER (U"Line type"); PowerCepstrum_fitTiltLine (me, GET_REAL (U"left Tilt line quefrency range"), GET_REAL (U"right Tilt line quefrency range"), &a, &intercept, lineType, GET_INTEGER (U"Fit method")); Melder_information (intercept, U" dB"); } END FORM (PowerCepstrum_getPeakProminence, U"PowerCepstrum: Get peak prominence", U"PowerCepstrum: Get peak prominence...") REAL (U"left Search peak in pitch range (Hz)", U"60.0") REAL (U"right Search peak in pitch range (Hz)", U"333.3") RADIO (U"Interpolation", 2) RADIOBUTTON (U"None") RADIOBUTTON (U"Parabolic") RADIOBUTTON (U"Cubic") RADIOBUTTON (U"Sinc70") REAL (U"left Tilt line quefrency range (s)", U"0.001") REAL (U"right Tilt line quefrency range (s)", U"0.0 (=end)") OPTIONMENU (U"Line type", 1) OPTION (U"Straight") OPTION (U"Exponential decay") OPTIONMENU (U"Fit method", 2) OPTION (U"Least squares") OPTION (U"Robust") OK DO LOOP { iam (PowerCepstrum); double qpeak, cpp = PowerCepstrum_getPeakProminence (me, GET_REAL (U"left Search peak in pitch range"), GET_REAL (U"right Search peak in pitch range"), GET_INTEGER (U"Interpolation") - 1, GET_REAL (U"left Tilt line quefrency range"), GET_REAL (U"right Tilt line quefrency range"), GET_INTEGER (U"Line type"), GET_INTEGER (U"Fit method"), &qpeak); Melder_information (cpp, U" dB; quefrency=", qpeak, U" s (f=", 1.0 / qpeak, U" Hz)."); } END FORM (PowerCepstrum_subtractTilt_inline, U"PowerCepstrum: Subtract tilt (in-line)", 0) REAL (U"left Tilt line quefrency range (s)", U"0.001") REAL (U"right Tilt line quefrency range (s)", U"0.0 (=end)") OPTIONMENU (U"Line type", 1) OPTION (U"Straight") OPTION (U"Exponential decay") OPTIONMENU (U"Fit method", 2) OPTION (U"Least squares") OPTION (U"Robust") OK DO LOOP { iam (PowerCepstrum); PowerCepstrum_subtractTilt_inline (me, GET_REAL (U"left Tilt line quefrency range"), GET_REAL (U"right Tilt line quefrency range"), GET_INTEGER (U"Line type"), GET_INTEGER (U"Fit method")); } END FORM (PowerCepstrum_smooth_inline, U"PowerCepstrum: Smooth (in-line)", 0) REAL (U"Quefrency averaging window (s)", U"0.0005") NATURAL (U"Number of iterations", U"1"); OK DO LOOP { iam (PowerCepstrum); PowerCepstrum_smooth_inline (me, GET_REAL (U"Quefrency averaging window"), GET_INTEGER (U"Number of iterations")); } END FORM (PowerCepstrum_smooth, U"PowerCepstrum: Smooth", 0) REAL (U"Quefrency averaging window (s)", U"0.0005") NATURAL (U"Number of iterations", U"1"); OK DO LOOP { iam (PowerCepstrum); autoPowerCepstrum thee = PowerCepstrum_smooth (me, GET_REAL (U"Quefrency averaging window"), GET_INTEGER (U"Number of iterations")); praat_new (thee.transfer(), my name, U"_smooth"); } END FORM (PowerCepstrum_subtractTilt, U"PowerCepstrum: Subtract tilt", 0) REAL (U"left Tilt line quefrency range (s)", U"0.001") REAL (U"right Tilt line quefrency range (s)", U"0.0 (=end)") OPTIONMENU (U"Line type", 1) OPTION (U"Straight") OPTION (U"Exponential decay") OPTIONMENU (U"Fit method", 2) OPTION (U"Least squares") OPTION (U"Robust") OK DO LOOP { iam (PowerCepstrum); autoPowerCepstrum thee = PowerCepstrum_subtractTilt (me, GET_REAL (U"left Tilt line quefrency range"), GET_REAL (U"right Tilt line quefrency range"), GET_INTEGER (U"Line type"), GET_INTEGER (U"Fit method")); praat_new (thee.transfer(), my name, U"minusTilt"); } END DIRECT (Cepstrum_to_Spectrum) LOOP { iam (Cepstrum); autoSpectrum thee = Cepstrum_to_Spectrum (me); praat_new (thee.transfer(), my name); } END DIRECT (PowerCepstrum_to_Matrix) LOOP { iam (PowerCepstrum); autoMatrix thee = PowerCepstrum_to_Matrix (me); praat_new (thee.transfer(), my name); } END /********************** Cepstrogram ****************************************/ DIRECT (PowerCepstrogram_help) Melder_help (U"PowerCepstrogram"); END FORM (old_PowerCepstrogram_paint, U"PowerCepstrogram: Paint", 0) REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") REAL (U"left Quefrency range (s)", U"0.0") REAL (U"right Quefrency range (s)", U"0.0") REAL (U"Minimum (dB)", U"0.0") REAL (U"Maximum (dB)", U"0.0") BOOLEAN (U"Garnish", 1); OK DO autoPraatPicture picture; LOOP { iam (PowerCepstrogram); PowerCepstrogram_paint (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Quefrency range"), GET_REAL (U"right Quefrency range"), GET_REAL (U"Maximum"), false, GET_REAL (U"Maximum") - GET_REAL (U"Minimum"), 0.0, GET_INTEGER (U"Garnish")); } END FORM (PowerCepstrogram_paint, U"PowerCepstrogram: Paint", U"PowerCepstrogram: Paint...") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") REAL (U"left Quefrency range (s)", U"0.0") REAL (U"right Quefrency range (s)", U"0.0") REAL (U"Maximum (dB)", U"80.0") BOOLEAN (U"Autoscaling", 0); REAL (U"Dynamic range (dB)", U"30.0"); REAL (U"Dynamic compression (0-1)", U"0.0"); BOOLEAN (U"Garnish", 1); OK DO_ALTERNATIVE (old_PowerCepstrogram_paint) autoPraatPicture picture; LOOP { iam (PowerCepstrogram); PowerCepstrogram_paint (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Quefrency range"), GET_REAL (U"right Quefrency range"), GET_REAL (U"Maximum"), GET_INTEGER (U"Autoscaling"), GET_REAL (U"Dynamic range"), GET_REAL (U"Dynamic compression"), GET_INTEGER (U"Garnish")); } END FORM (PowerCepstrogram_smooth, U"PowerCepstrogram: Smooth", U"PowerCepstrogram: Smooth...") REAL (U"Time averaging window (s)", U"0.02") REAL (U"Quefrency averaging window (s)", U"0.0005") OK DO LOOP { iam (PowerCepstrogram); autoPowerCepstrogram thee = PowerCepstrogram_smooth (me, GET_REAL (U"Time averaging window"), GET_REAL (U"Quefrency averaging window")); praat_new (thee.transfer(), my name, U"_smoothed"); } END DIRECT (PowerCepstrogram_getStartQuefrency) LOOP { iam (PowerCepstrogram); Melder_informationReal (my ymin, U" (s)"); } END DIRECT (PowerCepstrogram_getEndQuefrency) LOOP { iam (PowerCepstrogram); Melder_informationReal (my ymax, U" (s)"); } END DIRECT (PowerCepstrogram_getNumberOfQuefrencyBins) LOOP { iam (PowerCepstrogram); Melder_informationReal (my ny, U" quefrency bins"); } END DIRECT (PowerCepstrogram_getQuefrencyStep) LOOP { iam (PowerCepstrogram); Melder_informationReal (my dy, U" quefrency step (s)"); } END FORM (PowerCepstrogram_subtractTilt, U"PowerCepstrogram: Subtract tilt", 0) REAL (U"left Tilt line quefrency range (s)", U"0.001") REAL (U"right Tilt line quefrency range (s)", U"0.0 (=end)") OPTIONMENU (U"Line type", 2) OPTION (U"Straight") OPTION (U"Exponential decay") OPTIONMENU (U"Fit method", 2) OPTION (U"Least squares") OPTION (U"Robust") OK DO LOOP { iam (PowerCepstrogram); autoPowerCepstrogram thee = PowerCepstrogram_subtractTilt (me, GET_REAL (U"left Tilt line quefrency range"), GET_REAL (U"right Tilt line quefrency range"), GET_INTEGER (U"Line type"), GET_INTEGER (U"Fit method")); praat_new (thee.transfer(), my name, U"_minusTilt"); } END FORM (PowerCepstrogram_subtractTilt_inline, U"PowerCepstrogram: Subtract tilt (in-line)", 0) REAL (U"left Tilt line quefrency range (s)", U"0.001") REAL (U"right Tilt line quefrency range (s)", U"0.0 (=end)") OPTIONMENU (U"Line type", 2) OPTION (U"Straight") OPTION (U"Exponential decay") OPTIONMENU (U"Fit method", 2) OPTION (U"Least squares") OPTION (U"Robust") OK DO LOOP { iam (PowerCepstrogram); PowerCepstrogram_subtractTilt_inline (me, GET_REAL (U"left Tilt line quefrency range"), GET_REAL (U"right Tilt line quefrency range"), GET_INTEGER (U"Line type"), GET_INTEGER (U"Fit method")); } END FORM (PowerCepstrogram_getCPPS_hillenbrand, U"PowerCepstrogram: Get CPPS", 0) LABEL (U"", U"Smoothing:") BOOLEAN (U"Subtract tilt before smoothing", 1) REAL (U"Time averaging window (s)", U"0.001") REAL (U"Quefrency averaging window (s)", U"0.00005") LABEL (U"", U"Peak search:") REAL (U"left Peak search pitch range (Hz)", U"60.0") REAL (U"right Peak search pitch range (Hz)", U"330.0") OK DO LOOP { iam (PowerCepstrogram); double cpps = PowerCepstrogram_getCPPS_hillenbrand (me, GET_INTEGER (U"Subtract tilt before smoothing"), GET_REAL (U"Time averaging window"), GET_REAL (U"Quefrency averaging window"), GET_REAL (U"left Peak search pitch range"), GET_REAL (U"right Peak search pitch range")); Melder_informationReal (cpps, U" dB"); } END FORM (PowerCepstrogram_getCPPS, U"PowerCepstrogram: Get CPPS", 0) LABEL (U"", U"Smoothing:") BOOLEAN (U"Subtract tilt before smoothing", 1) REAL (U"Time averaging window (s)", U"0.001") REAL (U"Quefrency averaging window (s)", U"0.00005") LABEL (U"", U"Peak search:") REAL (U"left Peak search pitch range (Hz)", U"60.0") REAL (U"right Peak search pitch range (Hz)", U"330.0") POSITIVE (U"Tolerance (0-1)", U"0.05") RADIO (U"Interpolation", 2) RADIOBUTTON (U"None") RADIOBUTTON (U"Parabolic") RADIOBUTTON (U"Cubic") RADIOBUTTON (U"Sinc70") LABEL (U"", U"Tilt line:") REAL (U"left Tilt line quefrency range (s)", U"0.001") REAL (U"right Tilt line quefrency range (s)", U"0.0 (=end)") OPTIONMENU (U"Line type", 2) OPTION (U"Straight") OPTION (U"Exponential decay") OPTIONMENU (U"Fit method", 2) OPTION (U"Least squares") OPTION (U"Robust") OK DO LOOP { iam (PowerCepstrogram); double cpps = PowerCepstrogram_getCPPS (me, GET_INTEGER (U"Subtract tilt before smoothing"), GET_REAL (U"Time averaging window"), GET_REAL (U"Quefrency averaging window"), GET_REAL (U"left Peak search pitch range"), GET_REAL (U"right Peak search pitch range"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Interpolation") - 1, GET_REAL (U"left Tilt line quefrency range"), GET_REAL (U"right Tilt line quefrency range"), GET_INTEGER (U"Line type"), GET_INTEGER (U"Fit method")); Melder_informationReal (cpps, U" dB"); } END FORM (PowerCepstrogram_formula, U"PowerCepstrogram: Formula", U"") LABEL (U"label", U"Do for all times and quefrencies:") LABEL (U"label", U" `x' is the time in seconds") LABEL (U"label", U" `y' is the quefrency in seconds") LABEL (U"label", U" `self' is the current value") LABEL (U"label", U" Replace all values with:") TEXTFIELD (U"formula", U"sqrt(self)") OK DO LOOP { iam (PowerCepstrogram); try { Matrix_formula ((Matrix) me, GET_STRING (U"formula"), interpreter, NULL); praat_dataChanged (me); } catch (MelderError) { praat_dataChanged (me); // in case of error, the PowerCepstrogram may have partially changed throw; } } END FORM (PowerCepstrogram_to_PowerCepstrum_slice, U"PowerCepstrogram: To PowerCepstrum (slice)", 0) REAL (U"Time (s)", U"0.1") OK DO LOOP { iam (PowerCepstrogram); double time = GET_REAL (U"Time"); autoPowerCepstrum thee = PowerCepstrogram_to_PowerCepstrum_slice (me, time); praat_new (thee.transfer(), my name, NUMstring_timeNoDot (time)); } END FORM (PowerCepstrogram_to_Table_cpp, U"PowerCepstrogram: To Table (peak prominence)", U"PowerCepstrogram: To Table (peak prominence)...") REAL (U"left Peak search pitch range (Hz)", U"60.0") REAL (U"right Peak search pitch range (Hz)", U"330.0") POSITIVE (U"Tolerance (0-1)", U"0.05") RADIO (U"Interpolation", 2) RADIOBUTTON (U"None") RADIOBUTTON (U"Parabolic") RADIOBUTTON (U"Cubic") RADIOBUTTON (U"Sinc70") REAL (U"left Tilt line quefrency range (s)", U"0.001") REAL (U"right Tilt line quefrency range (s)", U"0.0 (=end)") OPTIONMENU (U"Line type", 2) OPTION (U"Straight") OPTION (U"Exponential decay") OPTIONMENU (U"Fit method", 2) OPTION (U"Least squares") OPTION (U"Robust") OK DO LOOP { iam (PowerCepstrogram); autoTable thee = PowerCepstrogram_to_Table_cpp (me, GET_REAL (U"left Peak search pitch range"), GET_REAL (U"right Peak search pitch range"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Interpolation") - 1, GET_REAL (U"left Tilt line quefrency range"), GET_REAL (U"right Tilt line quefrency range"), GET_INTEGER (U"Line type"), GET_INTEGER (U"Fit method")); praat_new (thee.transfer(), my name, U"_cpp"); } END FORM (PowerCepstrogram_to_Table_hillenbrand, U"PowerCepstrogram: To Table (hillenbrand)", U"PowerCepstrogram: To Table (peak prominence...") REAL (U"left Peak search pitch range (Hz)", U"60.0") REAL (U"right Peak search pitch range (Hz)", U"330.0") OK DO LOOP { iam (PowerCepstrogram); autoTable thee = PowerCepstrogram_to_Table_hillenbrand (me, GET_REAL (U"left Peak search pitch range"), GET_REAL (U"right Peak search pitch range")); praat_new (thee.transfer(), my name, U"_cpp"); } END DIRECT (PowerCepstrogram_to_Matrix) LOOP { iam (PowerCepstrogram); autoMatrix thee = PowerCepstrogram_to_Matrix (me); praat_new (thee.transfer(), my name); } END /********************** Cepstrumc ****************************************/ DIRECT (Cepstrumc_to_LPC) LOOP { iam (Cepstrumc); autoLPC thee = Cepstrumc_to_LPC (me); praat_new (thee.transfer(), my name); } END FORM (Cepstrumc_to_DTW, U"Cepstrumc: To DTW", U"Cepstrumc: To DTW...") LABEL (U"", U"Distance calculation between Cepstra") REAL (U"Cepstral weight", U"1.0") REAL (U"Log energy weight", U"0.0") REAL (U"Regression weight", U"0.0") REAL (U"Regression weight log energy", U"0.0") REAL (U"Window for regression coefficients (seconds)", U"0.056") LABEL (U"", U"Boundary conditions for time warp") BOOLEAN (U"Match begin positions", 0) BOOLEAN (U"Match end positions", 0) RADIO (U"Slope constraints", 1) RADIOBUTTON (U"no restriction") RADIOBUTTON (U"1/3 < slope < 3") RADIOBUTTON (U"1/2 < slope < 2") RADIOBUTTON (U"2/3 < slope < 3/2") OK DO Cepstrumc c1 = nullptr, c2 = nullptr; LOOP { iam (Cepstrumc); (c1 ? c2 : c1) = me; } Melder_assert (c1 && c2); autoDTW thee = Cepstrumc_to_DTW (c1, c2, GET_REAL (U"Cepstral weight"), GET_REAL (U"Log energy weight"), GET_REAL (U"Regression weight"), GET_REAL (U"Regression weight log energy"), GET_REAL (U"Window for regression coefficients"), GET_INTEGER (U"Match begin positions"), GET_INTEGER (U"Match end positions"), GET_INTEGER (U"Slope constraints")); praat_new (thee.transfer(), c1 -> name, U"_", c2 -> name); END DIRECT (Cepstrumc_to_Matrix) LOOP { iam (Cepstrumc); autoMatrix thee = Cepstrumc_to_Matrix (me); praat_new (thee.transfer(), my name); } END /******************** Formant ********************************************/ FORM (Formant_to_LPC, U"Formant: To LPC", 0) POSITIVE (U"Sampling frequency (Hz)", U"16000.0") OK DO LOOP { iam (Formant); autoLPC thee = Formant_to_LPC (me, 1.0 / GET_REAL (U"Sampling frequency")); praat_new (thee.transfer(), my name); } END FORM (Formant_formula, U"Formant: Formula", 0) REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") NATURAL (U"left Formant range", U"1") NATURAL (U"right Formant range", U"5") LABEL (U"", U"Formant frequencies in odd numbered rows") LABEL (U"", U"Formant bandwidths in even numbered rows") SENTENCE (U"Formula", U"if row mod 2 = 1 and self[row,col]/self[row+1,col] < 5 then 0 else self fi") OK DO char32 *expression = GET_STRING (U"Formula"); LOOP { iam (Formant); Formant_formula (me, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_INTEGER (U"left Formant range"), GET_INTEGER (U"right Formant range"), interpreter, expression); } END /******************** Formant & Spectrogram ************************************/ FORM (Formant_and_Spectrogram_to_IntensityTier, U"Formant & Spectrogram: To IntensityTier", U"Formant & Spectrogram: To IntensityTier...") NATURAL (U"Formant number", U"1") OK DO Formant me = FIRST (Formant); long iformant = GET_INTEGER (U"Formant number"); Spectrogram thee = FIRST (Spectrogram); autoIntensityTier him = Formant_and_Spectrogram_to_IntensityTier (me, thee, iformant); praat_new (him.transfer(), my name, U"_", GET_INTEGER (U"Formant number")); END /********************LFCC ********************************************/ DIRECT (LFCC_help) Melder_help (U"LFCC"); END FORM (LFCC_to_LPC, U"LFCC: To LPC", U"LFCC: To LPC...") INTEGER (U"Number of coefficients", U"0") OK DO long ncof = GET_INTEGER (U"Number of coefficients"); if (ncof < 0) { Melder_throw (U"Number of coefficients must be greater or equal zero."); } LOOP { iam (LFCC); autoLPC thee = LFCC_to_LPC (me, ncof); praat_new (thee.transfer(), my name); } END /********************LPC ********************************************/ DIRECT (LPC_help) Melder_help (U"LPC"); END FORM (LPC_drawGain, U"LPC: Draw gain", U"LPC: Draw gain...") REAL (U"From time (seconds)", U"0.0") REAL (U"To time (seconds)", U"0.0 (=all)") REAL (U"Minimum gain", U"0.0") REAL (U"Maximum gain", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (LPC); LPC_drawGain (me, GRAPHICS, GET_REAL (U"From time"), GET_REAL (U"To time"), GET_REAL (U"Minimum gain"), GET_REAL (U"Maximum gain"), GET_INTEGER (U"Garnish")); } END DIRECT (LPC_getSamplingInterval) LOOP { iam (LPC); Melder_information (my samplingPeriod, U" seconds"); } END FORM (LPC_getNumberOfCoefficients, U"LPC: Get number of coefficients", U"LPC: Get number of coefficients...") NATURAL (U"Frame number", U"1") OK DO long iframe = GET_INTEGER (U"Frame number"); LOOP { iam (LPC); if (iframe > my nx) { Melder_throw (U"Frame number is too large.\n\nPlease choose a number between 1 and ", my nx); } Melder_information (my d_frames[iframe].nCoefficients, U" coefficients"); } END FORM (LPC_drawPoles, U"LPC: Draw poles", U"LPC: Draw poles...") REAL (U"Time (seconds)", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (LPC); LPC_drawPoles (me, GRAPHICS, GET_REAL (U"Time"), GET_INTEGER (U"Garnish")); } END DIRECT (LPC_to_Formant) LOOP { iam (LPC); autoFormant thee = LPC_to_Formant (me, 50); praat_new (thee.transfer(), my name); } END DIRECT (LPC_to_Formant_keep_all) LOOP { iam (LPC); autoFormant thee = LPC_to_Formant (me, 0); praat_new (thee.transfer(), my name); } END FORM (LPC_to_LFCC, U"LPC: To LFCC", U"LPC: To LFCC...") NATURAL (U"Number of coefficients", U"0") OK DO long ncof = GET_INTEGER (U"Number of coefficients"); if (ncof < 0) { Melder_throw (U"Number of coefficients must be greater or equal zero."); } LOOP { iam (LPC); autoLFCC thee = LPC_to_LFCC (me, ncof); praat_new (thee.transfer(), my name); } END FORM (LPC_to_Polynomial, U"LPC: To Polynomial", U"LPC: To Polynomial (slice)...") REAL (U"Time (seconds)", U"0.0") OK DO double time = GET_REAL (U"Time"); LOOP { iam (LPC); autoPolynomial thee = LPC_to_Polynomial (me, time); praat_new (thee.transfer(), my name, NUMstring_timeNoDot (time)); } END FORM (LPC_to_Spectrum, U"LPC: To Spectrum", U"LPC: To Spectrum (slice)...") REAL (U"Time (seconds)", U"0.0") REAL (U"Minimum frequency resolution (Hz)", U"20.0") REAL (U"Bandwidth reduction (Hz)", U"0.0") REAL (U"De-emphasis frequency (Hz)", U"50.0") OK DO LOOP { iam (LPC); double time = GET_REAL (U"Time"); autoSpectrum thee = LPC_to_Spectrum (me, time, GET_REAL (U"Minimum frequency resolution"), GET_REAL (U"Bandwidth reduction"), GET_REAL (U"De-emphasis frequency")); praat_new (thee.transfer(), my name, NUMstring_timeNoDot (time)); } END FORM (LPC_to_Spectrogram, U"LPC: To Spectrogram", U"LPC: To Spectrogram...") REAL (U"Minimum frequency resolution (Hz)", U"20.0") REAL (U"Bandwidth reduction (Hz)", U"0.0") REAL (U"De-emphasis frequency (Hz)", U"50.0") OK DO LOOP { iam (LPC); autoSpectrogram thee = LPC_to_Spectrogram (me, GET_REAL (U"Minimum frequency resolution"), GET_REAL (U"Bandwidth reduction"), GET_REAL (U"De-emphasis frequency")); praat_new (thee.transfer(), my name); } END FORM (LPC_to_VocalTract_special, U"LPC: To VocalTract", U"LPC: To VocalTract (slice, special)...") REAL (U"Time (s)", U"0.0") REAL (U"Glottal damping", U"0.1") BOOLEAN (U"Radiation damping", 1) BOOLEAN (U"Internal damping", 1) OK DO double glottalDamping = GET_REAL (U"Glottal damping"); bool radiationDamping = GET_INTEGER (U"Radiation damping"); bool internalDamping = GET_INTEGER (U"Internal damping"); LOOP { iam (LPC); double time = GET_REAL (U"Time"); autoVocalTract thee = LPC_to_VocalTract (me, time, glottalDamping, radiationDamping, internalDamping); praat_new (thee.transfer(), my name, NUMstring_timeNoDot (time)); } END FORM (LPC_to_VocalTract, U"LPC: To VocalTract", U"LPC: To VocalTract (slice)...") REAL (U"Time (s)", U"0.0") POSITIVE (U"Length (m)", U"0.17") OK DO double time = GET_REAL (U"Time"); LOOP { iam (LPC); autoVocalTract thee = LPC_to_VocalTract (me, time, GET_REAL (U"Length")); praat_new (thee.transfer(), my name, NUMstring_timeNoDot (time)); } END DIRECT (LPC_downto_Matrix_lpc) LOOP { iam (LPC); autoMatrix thee = LPC_downto_Matrix_lpc (me); praat_new (thee.transfer(), my name, U"_lpc"); } END DIRECT (LPC_downto_Matrix_rc) LOOP { iam (LPC); autoMatrix thee = LPC_downto_Matrix_rc (me); praat_new (thee.transfer(), my name, U"_rc"); } END DIRECT (LPC_downto_Matrix_area) LOOP { iam (LPC); autoMatrix thee = LPC_downto_Matrix_area (me); praat_new (thee.transfer(), my name, U"_area"); } END /********************** Sound *******************************************/ FORM (Sound_to_PowerCepstrogram, U"Sound: To PowerCepstrogram", U"Sound: To PowerCepstrogram...") POSITIVE (U"Pitch floor (Hz)", U"60.0") POSITIVE (U"Time step (s)", U"0.002") POSITIVE (U"Maximum frequency (Hz)", U"5000.0") POSITIVE (U"Pre-emphasis from (Hz)", U"50") OK DO LOOP { iam (Sound); autoPowerCepstrogram thee = Sound_to_PowerCepstrogram (me, GET_REAL (U"Pitch floor"), GET_REAL (U"Time step"), GET_REAL(U"Maximum frequency"), GET_REAL (U"Pre-emphasis from")); praat_new (thee.transfer(), my name); } END FORM (Sound_to_PowerCepstrogram_hillenbrand, U"Sound: To PowerCepstrogram (hillenbrand)", U"Sound: To PowerCepstrogram...") POSITIVE (U"Pitch floor (Hz)", U"60.0") POSITIVE (U"Time step (s)", U"0.002") OK DO LOOP { iam (Sound); autoPowerCepstrogram thee = Sound_to_PowerCepstrogram_hillenbrand (me, GET_REAL (U"Pitch floor"), GET_REAL (U"Time step")); praat_new (thee.transfer(), my name); } END FORM (Sound_to_Formant_robust, U"Sound: To Formant (robust)", U"Sound: To Formant (robust)...") REAL (U"Time step (s)", U"0.0 (= auto)") POSITIVE (U"Max. number of formants", U"5.0") REAL (U"Maximum formant (Hz)", U"5500 (= adult female)") POSITIVE (U"Window length (s)", U"0.025") POSITIVE (U"Pre-emphasis from (Hz)", U"50") POSITIVE (U"Number of std. dev.", U"1.5") NATURAL (U"Maximum number of iterations", U"5") REAL (U"Tolerance", U"0.000001") OK DO LOOP { iam (Sound); praat_new (Sound_to_Formant_robust (me, GET_REAL (U"Time step"), GET_REAL (U"Max. number of formants"), GET_REAL (U"Maximum formant"), GET_REAL (U"Window length"), GET_REAL (U"Pre-emphasis from"), 50.0, GET_REAL (U"Number of std. dev."), GET_INTEGER (U"Maximum number of iterations"), GET_REAL (U"Tolerance"), 1), my name); } END static void Sound_to_LPC_addCommonFields (UiForm dia) { LABEL (U"", U"Warning 1: for formant analysis, use \"To Formant\" instead.") LABEL (U"", U"Warning 2: if you do use \"To LPC\", you may want to resample first.") LABEL (U"", U"Click Help for more details.") LABEL (U"", U"") NATURAL (U"Prediction order", U"16") POSITIVE (U"Window length (s)", U"0.025") POSITIVE (U"Time step (s)", U"0.005") REAL (U"Pre-emphasis frequency (Hz)", U"50.0") } static void Sound_to_LPC_checkCommonFields (UiForm dia, long *predictionOrder, double *analysisWindowDuration, double *timeStep, double *preemphasisFrequency) { *predictionOrder = GET_INTEGER (U"Prediction order"); *analysisWindowDuration = GET_REAL (U"Window length"); *timeStep = GET_REAL (U"Time step"); *preemphasisFrequency = GET_REAL (U"Pre-emphasis frequency"); if (*preemphasisFrequency < 0.0) { Melder_throw (U"Pre-emphasis frequencies cannot be negative."); } } FORM (Sound_to_LPC_auto, U"Sound: To LPC (autocorrelation)", U"Sound: To LPC (autocorrelation)...") Sound_to_LPC_addCommonFields (dia); OK DO long numberOfPoles; double analysisWindowDuration, timeStep, preemphasisFrequency; Sound_to_LPC_checkCommonFields (dia, & numberOfPoles, & analysisWindowDuration, & timeStep, &preemphasisFrequency); LOOP { iam (Sound); autoLPC thee = Sound_to_LPC_auto (me, numberOfPoles, analysisWindowDuration, timeStep, preemphasisFrequency); praat_new (thee.transfer(), my name); } END FORM (Sound_to_LPC_covar, U"Sound: To LPC (covariance)", U"Sound: To LPC (covariance)...") Sound_to_LPC_addCommonFields (dia); OK DO long numberOfPoles; double analysisWindowDuration, timeStep, preemphasisFrequency; Sound_to_LPC_checkCommonFields (dia, & numberOfPoles, & analysisWindowDuration, & timeStep, & preemphasisFrequency); LOOP { iam (Sound); autoLPC thee = Sound_to_LPC_covar (me, numberOfPoles, analysisWindowDuration, timeStep, preemphasisFrequency); praat_new (thee.transfer(), my name); } END FORM (Sound_to_LPC_burg, U"Sound: To LPC (burg)", U"Sound: To LPC (burg)...") Sound_to_LPC_addCommonFields (dia); OK DO long numberOfPoles; double analysisWindowDuration, timeStep, preemphasisFrequency; Sound_to_LPC_checkCommonFields (dia, & numberOfPoles, & analysisWindowDuration, & timeStep, & preemphasisFrequency); LOOP { iam (Sound); autoLPC thee = Sound_to_LPC_burg (me, numberOfPoles, analysisWindowDuration, timeStep, preemphasisFrequency); praat_new (thee.transfer(), my name); } END FORM (Sound_to_LPC_marple, U"Sound: To LPC (marple)", U"Sound: To LPC (marple)...") Sound_to_LPC_addCommonFields (dia); POSITIVE (U"Tolerance 1", U"1e-6") POSITIVE (U"Tolerance 2", U"1e-6") OK DO long numberOfPoles; double analysisWindowDuration, timeStep, preemphasisFrequency; Sound_to_LPC_checkCommonFields (dia, & numberOfPoles, & analysisWindowDuration, &timeStep, & preemphasisFrequency); LOOP { iam (Sound); autoLPC thee = Sound_to_LPC_marple (me, numberOfPoles, analysisWindowDuration, timeStep, preemphasisFrequency, GET_REAL (U"Tolerance 1"), GET_REAL (U"Tolerance 2")); praat_new (thee.transfer(), my name); } END FORM (Sound_to_MFCC, U"Sound: To MFCC", U"Sound: To MFCC...") NATURAL (U"Number of coefficients", U"12") POSITIVE (U"Window length (s)", U"0.015") POSITIVE (U"Time step (s)", U"0.005") LABEL (U"", U"Filter bank parameters") POSITIVE (U"Position of first filter (mel)", U"100.0") POSITIVE (U"Distance between filters (mel)", U"100.0") REAL (U"Maximum frequency (mel)", U"0.0"); OK DO long p = GET_INTEGER (U"Number of coefficients"); if (p > 24) { Melder_throw (U"Number of coefficients must be < 25."); } LOOP { iam (Sound); praat_new (Sound_to_MFCC (me, p, GET_REAL (U"Window length"), GET_REAL (U"Time step"), GET_REAL (U"Position of first filter"), GET_REAL (U"Maximum frequency"), GET_REAL (U"Distance between filters")), my name); } END FORM (VocalTract_drawSegments, U"VocalTract: Draw segments", 0) POSITIVE (U"Maximum length (cm)", U"20.0") POSITIVE (U"Maximum area (cm^2)", U"90.0") BOOLEAN (U"Closed at glottis", 1) OK DO autoPraatPicture picture; double maxLength = GET_REAL (U"Maximum length") / 100.0; double maxArea = GET_REAL (U"Maximum area") / 10000.0; bool closedAtGlottis = GET_INTEGER (U"Closed at glottis"); LOOP { iam (VocalTract); VocalTract_drawSegments (me, GRAPHICS, maxLength, maxArea, closedAtGlottis); } END DIRECT (VocalTract_getLength) LOOP { iam (VocalTract); Melder_information (my xmax - my xmin, U" m"); } END FORM (VocalTract_setLength, U"", 0) POSITIVE (U"New length (m)", U"0.17") OK DO double newLength = GET_REAL (U"New length"); LOOP { iam (VocalTract); VocalTract_setLength (me, newLength); } END FORM (VocalTract_to_VocalTractTier, U"VocalTract: To VocalTractTier", 0) REAL (U"Tier start time (s)", U"0.0") REAL (U"Tier end time (s)", U"1.0") REAL (U"Insert at time (s)", U"0.5") OK DO double xmin = GET_REAL (U"Tier start time"); double xmax = GET_REAL (U"Tier end time"); double time = GET_REAL (U"Insert at time"); REQUIRE (xmin < xmax, U"The start time must be before the end time.") REQUIRE (time >= xmin and time <= xmax, U"The insert time must be between start en end time.") LOOP { iam (VocalTract); autoVocalTractTier thee = VocalTract_to_VocalTractTier (me, xmin, xmax, time); praat_new (thee.transfer(), my name); } END DIRECT (VocalTractTier_help) Melder_help (U"VocalTractTier"); END FORM (VocalTractTier_to_LPC, U"VocalTractTier: To LPC", 0) POSITIVE (U"Time step", U"0.005") OK DO LOOP { iam (VocalTractTier); autoLPC thee = VocalTractTier_to_LPC (me, GET_REAL (U"Time step")); praat_new (thee.transfer(), my name); } END FORM (VocalTractTier_to_VocalTract, U"", 0) REAL (U"Time (s)", U"0.1") OK DO double time = GET_REAL (U"Time"); LOOP { iam (VocalTractTier); autoVocalTract thee = VocalTractTier_to_VocalTract (me, time); praat_new (thee.transfer(), my name); } END FORM (VocalTractTier_addVocalTract, U"VocalTractTier: Add VocalTract", 0) REAL (U"Time", U"0.1") OK DO VocalTractTier me = FIRST (VocalTractTier); VocalTract thee = FIRST (VocalTract); VocalTractTier_addVocalTract (me, GET_REAL (U"Time"), thee); praat_dataChanged (me); END /******************* LPC & Sound *************************************/ FORM (LPC_and_Sound_filter, U"LPC & Sound: Filter", U"LPC & Sound: Filter...") BOOLEAN (U"Use LPC gain", 0) OK DO LPC me = FIRST (LPC); Sound s = FIRST (Sound); autoSound thee = LPC_and_Sound_filter (me , s, GET_INTEGER (U"Use LPC gain")); praat_new (thee.transfer(), my name); END FORM (LPC_and_Sound_filterWithFilterAtTime, U"LPC & Sound: Filter with one filter at time", U"LPC & Sound: Filter with filter at time...") OPTIONMENU (U"Channel", 2) OPTION (U"Both") OPTION (U"Left") OPTION (U"Right") REAL (U"Use filter at time (s)", U"0.0") OK DO LPC me = FIRST (LPC); Sound s = FIRST (Sound); long channel = GET_INTEGER (U"Channel") - 1; autoSound thee = LPC_and_Sound_filterWithFilterAtTime (me , s, channel, GET_REAL (U"Use filter at time")); praat_new (thee.transfer(), my name); END DIRECT (LPC_and_Sound_filterInverse) LPC me = FIRST (LPC); Sound s = FIRST (Sound); autoSound thee = LPC_and_Sound_filterInverse (me , s); praat_new (thee.transfer(), my name); END FORM (LPC_and_Sound_filterInverseWithFilterAtTime, U"LPC & Sound: Filter (inverse) with filter at time", U"LPC & Sound: Filter (inverse) with filter at time...") OPTIONMENU (U"Channel", 2) OPTION (U"Both") OPTION (U"Left") OPTION (U"Right") REAL (U"Use filter at time (s)", U"0.0") OK DO LPC me = FIRST (LPC); Sound s = FIRST (Sound); long channel = GET_INTEGER (U"Channel") - 1; autoSound thee = LPC_and_Sound_filterInverseWithFilterAtTime (me , s, channel, GET_REAL (U"Use filter at time")); praat_new (thee.transfer(), my name); END FORM (LPC_and_Sound_to_LPC_robust, U"Robust LPC analysis", U"LPC & Sound: To LPC (robust)...") POSITIVE (U"Window length (s)", U"0.025") POSITIVE (U"Pre-emphasis frequency (Hz)", U"50.0") POSITIVE (U"Number of std. dev.", U"1.5") NATURAL (U"Maximum number of iterations", U"5") REAL (U"Tolerance", U"0.000001") BOOLEAN (U"Variable location", 0) OK DO LPC me = FIRST (LPC); Sound s = FIRST (Sound); praat_new (LPC_and_Sound_to_LPC_robust (me, s, GET_REAL (U"Window length"), GET_REAL (U"Pre-emphasis frequency"), GET_REAL (U"Number of std. dev."), GET_INTEGER (U"Maximum number of iterations"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Variable location")), my name, U"_r"); END extern void praat_TimeTier_query_init (ClassInfo klas); extern void praat_TimeTier_modify_init (ClassInfo klas); void praat_uvafon_LPC_init (); void praat_uvafon_LPC_init () { Thing_recognizeClassesByName (classCepstrumc, classPowerCepstrum, classCepstrogram, classPowerCepstrogram, classLPC, classLFCC, classMFCC, classVocalTractTier, NULL); praat_addAction1 (classPowerCepstrum, 0, U"PowerCepstrum help", 0, 0, DO_PowerCepstrum_help); praat_addAction1 (classPowerCepstrum, 0, U"Draw...", 0, 0, DO_PowerCepstrum_draw); praat_addAction1 (classPowerCepstrum, 0, U"Draw tilt line...", 0, 0, DO_PowerCepstrum_drawTiltLine); praat_addAction1 (classCepstrum, 0, U"Draw (linear)...", 0, praat_HIDDEN, DO_Cepstrum_drawLinear); praat_addAction1 (classCepstrum, 0, U"Down to PowerCepstrum", 0, 0, DO_Cepstrum_downto_PowerCepstrum); praat_addAction1 (classPowerCepstrum, 1, U"Query -", 0, 0, 0); praat_addAction1 (classPowerCepstrum, 0, U"Get peak...", 0, 1, DO_PowerCepstrum_getPeak); praat_addAction1 (classPowerCepstrum, 0, U"Get quefrency of peak...", 0, 1, DO_PowerCepstrum_getQuefrencyOfPeak); praat_addAction1 (classPowerCepstrum, 0, U"Get peak prominence (hillenbrand)...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_PowerCepstrum_getPeakProminence_hillenbrand); praat_addAction1 (classPowerCepstrum, 0, U"Get peak prominence...", 0, 1, DO_PowerCepstrum_getPeakProminence); praat_addAction1 (classPowerCepstrum, 0, U"Get tilt line slope...", 0, 1, DO_PowerCepstrum_getTiltLineSlope); praat_addAction1 (classPowerCepstrum, 0, U"Get tilt line intercept...", 0, 1, DO_PowerCepstrum_getTiltLineIntercept); praat_addAction1 (classPowerCepstrum, 0, U"Get rhamonics to noise ratio...", 0, 1, DO_PowerCepstrum_getRNR); praat_addAction1 (classPowerCepstrum, 1, U"Modify -", 0, 0, 0); praat_addAction1 (classPowerCepstrum, 0, U"Formula...", 0, 1, DO_PowerCepstrum_formula); praat_addAction1 (classPowerCepstrum, 0, U"Subtract tilt (in-line)...", 0, 1, DO_PowerCepstrum_subtractTilt_inline); praat_addAction1 (classPowerCepstrum, 0, U"Smooth (in-line)...", 0, 1, DO_PowerCepstrum_smooth_inline); praat_addAction1 (classPowerCepstrum, 0, U"Subtract tilt...", 0, 0, DO_PowerCepstrum_subtractTilt); praat_addAction1 (classPowerCepstrum, 0, U"Smooth...", 0, 0, DO_PowerCepstrum_smooth); praat_addAction1 (classCepstrum, 0, U"To Spectrum", 0, praat_HIDDEN, DO_Cepstrum_to_Spectrum); praat_addAction1 (classPowerCepstrum, 0, U"To Matrix", 0, 0, DO_PowerCepstrum_to_Matrix); praat_addAction1 (classPowerCepstrogram, 0, U"PowerCepstrogram help", 0, 0, DO_PowerCepstrogram_help); praat_addAction1 (classPowerCepstrogram, 0, U"Paint...", 0, 0, DO_PowerCepstrogram_paint); praat_addAction1 (classPowerCepstrogram, 1, U"Query -", 0, 0, 0); praat_TimeFrameSampled_query_init (classPowerCepstrogram); praat_addAction1 (classPowerCepstrogram, 1, U"Query quefrency domain", 0, 1, 0); praat_addAction1 (classPowerCepstrogram, 1, U"Get start quefrency", 0, 2, DO_PowerCepstrogram_getStartQuefrency); praat_addAction1 (classPowerCepstrogram, 1, U"Get end quefrency", 0, 2, DO_PowerCepstrogram_getEndQuefrency); praat_addAction1 (classPowerCepstrogram, 1, U"Query quefrency sampling", 0, 1, 0); praat_addAction1 (classPowerCepstrogram, 1, U"Get number of quefrency bins", 0, 2, DO_PowerCepstrogram_getNumberOfQuefrencyBins); praat_addAction1 (classPowerCepstrogram, 1, U"Get quefrency step", 0, 2, DO_PowerCepstrogram_getQuefrencyStep); praat_addAction1 (classPowerCepstrogram, 0, U"Get CPPS (hillenbrand)...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_PowerCepstrogram_getCPPS_hillenbrand); praat_addAction1 (classPowerCepstrogram, 0, U"Get CPPS...", 0, 1, DO_PowerCepstrogram_getCPPS); praat_addAction1 (classPowerCepstrogram, 0, U"Modify -", 0, 0, 0); praat_TimeFunction_modify_init (classPowerCepstrogram); praat_addAction1 (classPowerCepstrogram, 0, U"Formula...", 0, 1, DO_PowerCepstrogram_formula); praat_addAction1 (classPowerCepstrogram, 0, U"Subtract tilt (in-line)...", 0, 1, DO_PowerCepstrogram_subtractTilt_inline); praat_addAction1 (classPowerCepstrogram, 0, U"To PowerCepstrum (slice)...", 0, 0, DO_PowerCepstrogram_to_PowerCepstrum_slice); praat_addAction1 (classPowerCepstrogram, 0, U"Smooth...", 0, 0, DO_PowerCepstrogram_smooth); praat_addAction1 (classPowerCepstrogram, 0, U"Subtract tilt...", 0, 0, DO_PowerCepstrogram_subtractTilt); praat_addAction1 (classPowerCepstrogram, 0, U"To Table (hillenbrand)...", 0, praat_HIDDEN, DO_PowerCepstrogram_to_Table_hillenbrand); praat_addAction1 (classPowerCepstrogram, 0, U"To Table (peak prominence)...", 0, praat_HIDDEN, DO_PowerCepstrogram_to_Table_cpp); praat_addAction1 (classPowerCepstrogram, 0, U"To Matrix", 0, 0, DO_PowerCepstrogram_to_Matrix); praat_addAction1 (classCepstrumc, 0, U"Analyse", 0, 0, 0); praat_addAction1 (classCepstrumc, 0, U"To LPC", 0, 0, DO_Cepstrumc_to_LPC); praat_addAction1 (classCepstrumc, 2, U"To DTW...", 0, 0, DO_Cepstrumc_to_DTW); praat_addAction1 (classCepstrumc, 0, U"Hack", 0, 0, 0); praat_addAction1 (classCepstrumc, 0, U"To Matrix", 0, 0, DO_Cepstrumc_to_Matrix); praat_addAction1 (classFormant, 0, U"Analyse", 0, 0, 0); praat_addAction1 (classFormant, 0, U"To LPC...", 0, 0, DO_Formant_to_LPC); praat_addAction1 (classFormant, 0, U"Formula...", U"Formula (bandwidths)...", 1, DO_Formant_formula); praat_addAction2 (classFormant, 1, classSpectrogram, 1, U"To IntensityTier...", 0, 0, DO_Formant_and_Spectrogram_to_IntensityTier); praat_addAction1 (classLFCC, 0, U"LFCC help", 0, 0, DO_LFCC_help); praat_CC_init (classLFCC); praat_addAction1 (classLFCC, 0, U"To LPC...", 0, 0, DO_LFCC_to_LPC); praat_addAction1 (classLPC, 0, U"LPC help", 0, 0, DO_LPC_help); praat_addAction1 (classLPC, 0, DRAW_BUTTON, 0, 0, 0); praat_addAction1 (classLPC, 0, U"Draw gain...", 0, 1, DO_LPC_drawGain); praat_addAction1 (classLPC, 0, U"Draw poles...", 0, 1, DO_LPC_drawPoles); praat_addAction1 (classLPC, 0, QUERY_BUTTON, 0, 0, 0); praat_TimeFrameSampled_query_init (classLPC); praat_addAction1 (classLPC, 1, U"Get sampling interval", 0, 1, DO_LPC_getSamplingInterval); praat_addAction1 (classLPC, 1, U"Get number of coefficients...", 0, 1, DO_LPC_getNumberOfCoefficients); praat_addAction1 (classLPC, 0, MODIFY_BUTTON, 0, 0, 0); praat_TimeFunction_modify_init (classLPC); praat_addAction1 (classLPC, 0, U"Extract", 0, 0, 0); praat_addAction1 (classLPC, 0, U"To Spectrum (slice)...", 0, 0, DO_LPC_to_Spectrum); praat_addAction1 (classLPC, 0, U"To VocalTract (slice)...", 0, 0, DO_LPC_to_VocalTract); praat_addAction1 (classLPC, 0, U"To VocalTract (slice, special)...", 0, 0, DO_LPC_to_VocalTract_special); praat_addAction1 (classLPC, 0, U"To Polynomial (slice)...", 0, 0, DO_LPC_to_Polynomial); praat_addAction1 (classLPC, 0, U"Down to Matrix (lpc)", 0, 0, DO_LPC_downto_Matrix_lpc); praat_addAction1 (classLPC, 0, U"Down to Matrix (rc)", 0, praat_HIDDEN, DO_LPC_downto_Matrix_rc); praat_addAction1 (classLPC, 0, U"Down to Matrix (area)", 0, praat_HIDDEN, DO_LPC_downto_Matrix_area); praat_addAction1 (classLPC, 0, U"Analyse", 0, 0, 0); praat_addAction1 (classLPC, 0, U"To Formant", 0, 0, DO_LPC_to_Formant); praat_addAction1 (classLPC, 0, U"To Formant (keep all)", 0, 0, DO_LPC_to_Formant_keep_all); praat_addAction1 (classLPC, 0, U"To LFCC...", 0, 0, DO_LPC_to_LFCC); praat_addAction1 (classLPC, 0, U"To Spectrogram...", 0, 0, DO_LPC_to_Spectrogram); praat_addAction2 (classLPC, 1, classSound, 1, U"Analyse", 0, 0, 0); praat_addAction2 (classLPC, 1, classSound, 1, U"Filter...", 0, 0, DO_LPC_and_Sound_filter); praat_addAction2 (classLPC, 1, classSound, 1, U"Filter (inverse)", 0, 0, DO_LPC_and_Sound_filterInverse); praat_addAction2 (classLPC, 1, classSound, 1, U"To LPC (robust)...", 0, praat_HIDDEN + praat_DEPTH_1, DO_LPC_and_Sound_to_LPC_robust); praat_addAction2 (classLPC, 1, classSound, 1, U"Filter with filter at time...", 0, 0, DO_LPC_and_Sound_filterWithFilterAtTime); praat_addAction2 (classLPC, 1, classSound, 1, U"Filter (inverse) with filter at time...", 0, 0, DO_LPC_and_Sound_filterInverseWithFilterAtTime); praat_addAction1 (classSound, 0, U"To LPC (autocorrelation)...", U"To Formant (sl)...", 1, DO_Sound_to_LPC_auto); praat_addAction1 (classSound, 0, U"To LPC (covariance)...", U"To LPC (autocorrelation)...", 1, DO_Sound_to_LPC_covar); praat_addAction1 (classSound, 0, U"To LPC (burg)...", U"To LPC (covariance)...", 1, DO_Sound_to_LPC_burg); praat_addAction1 (classSound, 0, U"To LPC (marple)...", U"To LPC (burg)...", 1, DO_Sound_to_LPC_marple); praat_addAction1 (classSound, 0, U"To MFCC...", U"To LPC (marple)...", 1, DO_Sound_to_MFCC); praat_addAction1 (classSound, 0, U"To Formant (robust)...", U"To Formant (sl)...", 2, DO_Sound_to_Formant_robust); praat_addAction1 (classSound, 0, U"To PowerCepstrogram...", U"To Harmonicity (gne)...", 1, DO_Sound_to_PowerCepstrogram); praat_addAction1 (classSound, 0, U"To PowerCepstrogram (hillenbrand)...", U"To Harmonicity (gne)...", praat_HIDDEN + praat_DEPTH_1, DO_Sound_to_PowerCepstrogram_hillenbrand); praat_addAction1 (classVocalTract, 0, U"Draw segments...", U"Draw", 0, DO_VocalTract_drawSegments); praat_addAction1 (classVocalTract, 1, U"Get length", U"Draw segments...", 0, DO_VocalTract_getLength); praat_addAction1 (classVocalTract, 1, U"Set length", U"Formula...", 0, DO_VocalTract_getLength); praat_addAction1 (classVocalTract, 0, U"To VocalTractTier...", U"To Spectrum...", 0, DO_VocalTract_to_VocalTractTier); praat_addAction1 (classVocalTractTier, 0, U"VocalTractTier help", 0, 0, DO_VocalTractTier_help); praat_addAction1 (classVocalTractTier, 0, U"Query -", 0, 0, 0); praat_TimeTier_query_init (classVocalTractTier); praat_addAction1 (classVocalTractTier, 0, U"Modify -", 0, 0, 0); praat_TimeTier_modify_init (classVocalTractTier); praat_addAction1 (classVocalTractTier, 0, U"To LPC...", 0, 0, DO_VocalTractTier_to_LPC); praat_addAction1 (classVocalTractTier, 0, U"To VocalTract...", 0, 0, DO_VocalTractTier_to_VocalTract); praat_addAction2 (classVocalTractTier, 1, classVocalTract, 1, U"Add VocalTract...", 0, 0, DO_VocalTractTier_addVocalTract); INCLUDE_MANPAGES (manual_LPC) INCLUDE_MANPAGES (manual_DataModeler) INCLUDE_LIBRARY (praat_DataModeler_init) } /* End of file praat_LPC_init.c */ praat-6.0.04/README.md000066400000000000000000000165371261542461700142130ustar00rootroot00000000000000# Praat: doing phonetics by computer Most information on how the program works is in its manual and on http://www.praat.org. ## 1. Compiling the source code You need the Praat source code only in the following cases: 1. you want to extend Praat’s functionality by adding C or C++ code to it; or 2. you want to understand or reuse Praat’s source code; or 3. you want to compile Praat for a computer for which we do not provide binary executables, e.g. Linux for non-Intel computers, FreeBSD, HP-UX, SGI, or SPARC Solaris. Before trying to dive into Praat’s source code, you should be familiar with the working of the Praat program and with writing Praat scripts. The Praat program can be downloaded from http://www.praat.org. ### 1.1. License All of the code is available under the [GNU General Public License](http://www.fon.hum.uva.nl/praat/GNU_General_Public_License.txt). Of course, any improvements are welcomed by the authors. ### 1.2. Downloading the archive To download the latest source code of Praat, click on one of the *zip* or *tar.gz* archives at the latest release or at any later change. ### 1.3. Unpacking the archive On most computers you can unpack the *zip* file by double-clicking. If you prefer to try the *tar.gz* file instead, drop it on *StuffIt Expander* (on Windows), double-click it (on Macintosh), or use `gunzip` and `tar xvf` (on Unix). ### 1.4. Steps to take if you want to extend Praat First make sure that the source code can be compiled as is. Then add your own buttons by editing `main/main_Praat.cpp` or `fon/praat_Fon.cpp`. Consult the manual page on [Programming](http://www.fon.hum.uva.nl/praat/manual/Programming_with_Praat.html). ### 1.5. The programming language Most of the source code is written in C++, but some parts are written in C. The code requires that your compiler supports C99 and C++11 (for e.g. `char32_t` and rvalue references). ### 1.6. Compiling for Windows Install Cygwin (on a 64-bit computer), and under Cygwin install the Devel packages i686-w64-mingw32 (for 32-bit targets) and/or x86_64-w64-mingw32 (for 64-bit targets). Move the Praat sources directory somewhere in your `/home/yourname` tree. Go to this sources directory (i.e. where `makefile` is) and type cp makefiles/makefile.defs.mingw32 ./makefile.defs if you want to build Praat's 32-bit edition, or cp makefiles/makefile.defs.mingw64 ./makefile.defs if you want to build Praat's 64-bit edition. Then type `make` to build `Praat.exe` (use `make -j4` to speed this up, i.e. to use 4 processors in parallel). Cross-compiling for Windows: use the [MinGW](http://www.mingw.org) compiler, perhaps on a Mac or Linux computer. You can find toolchains for 32 and 64 bits [here](http://sourceforge.net/projects/mingw-w64/files/) (look for Automated Builds). Install the GDI+ headers and the GDI+ library ([32-bit](http://www.fon.hum.uva.nl/praat/libgdiplus.a-32.zip); for 64-bit Windows just extract a GDI+ DLL from somewhere). Then copy the file `makefiles/makefile.defs.darmin32` or `makefiles/makefile.defs.darmin64` to the sources directory and rename it to `makefile.defs`. Then type `make`. ### 1.7. Compiling for Macintosh Extract the *xcodeproj64.zip* or *xcodeproj32.zip* file from the latest release (depending on whether you want to compile the 64-bit or the 32-bit edition) into the directory that contains `sys`, `fon`, `dwtools` and so on. Then open the project `praat32.xcodeproj` or `praat64.xcodeproj` in Xcode and choose Build or Run. The project contains the target `praat_mac` (for MacOS X, on Intel processors). If you get an error message like “Code Signing Identity xxx does not match any valid, non-expired, code-signing certificate in your keychain”, then select the target `praat_mac`, go to Info → Build, and switch “Code Signing Identity” to “Don’t Code Sign”, or sign with your own certificate if you have one as a registered Apple developer. If you get lots of errors saying “Expected unqualified-id” or “Unknown type name NSString”, then you may have to switch the Type of some .cpp file from “C++ Source” to “Objective-C++ Source” (under “Identity and Type” in the righthand sidebar). ### 1.8. Compiling on Linux and other Unixes Install `libgtk2.0-dev` (and its dependencies) and `libasound2-dev`. Then go to the sources directory and type cp makefiles/makefile.defs.linux.alsa ./makefile.defs mv external/portaudio external/portaudio2014 mv external/portaudio2007 external/portaudio Then type `make` to build the program. You may have to `kill jackd` or `artsd` to get audio to function. If your Unix isn’t Linux, you may have to edit the library names in the makefile (you may need pthread, gtk-x11-2.0, gdk-x11-2.0, atk-1.0, pangoft2-1.0, gdk_pixbuf-2.0, m, pangocairo-1.0, cairo, gio-2.0, pango-1.0, freetype, fontconfig, gobject-2.0, gmodule-2.0, gthread-2.0, rt, glib-2.0, asound). When compiling Praat on an external supercomputer or so, you will not have sound. If you do have `libgtk2.0-dev` (and its dependencies), do cp makefiles/makefile.defs.linux.silent ./makefile.defs Then type `make` to build the program. If your Unix isn’t Linux, you may have to edit the library names in the makefile (you may need pthread, gtk-x11-2.0, gdk-x11-2.0, atk-1.0, pangoft2-1.0, gdk_pixbuf-2.0, m, pangocairo-1.0, cairo, gio-2.0, pango-1.0, freetype, fontconfig, gobject-2.0, gmodule-2.0, gthread-2.0, rt, glib-2.0). ## 2. Binary executables The meaning of the names of binary files uploaded on GitHub is as follows: ### 2.1. Windows binaries - `praatXXXX_win64.zip`: zipped executable for 64-bit Windows (XP and higher) - `praatXXXX_win32.zip`: zipped executable for 32-bit Windows (XP and higher) - `praatconXXXX_win64.zip`: zipped executable for 64-bit Windows, console edition - `praatconXXXX_win32.zip`: zipped executable for 32-bit Windows, console edition - `praatconXXXX_win32sit.exe`: self-extracting StuffIt archive with executable for 32-bit Windows, console edition - `praatXXXX_win98.zip`: zipped executable for Windows 98 - `praatXXXX_win98sit.exe`: self-extracting StuffIt archive with executable for Windows 98 ### 2.2. Mac binaries - `praatXXXX_mac64.dmg`: disk image with executable for 64-bit Intel Macs (Cocoa) - `praatXXXX_mac32.dmg`: disk image with executable for 32-bit Intel Macs (Carbon) - `praatXXXX_xcodeproj64.zip`: zipped Xcode project file for the 64-bit edition (Cocoa) - `praatXXXX_xcodeproj32.zip`: zipped Xcode project file for the 32-bit edition (Carbon) - `praatXXXX_macU.dmg`: disk image with universal executable for (32-bit) PPC and Intel Macs (Carbon) - `praatXXXX_macU.sit`: StuffIt archive with universal executable for (32-bit) PPC and Intel Macs (Carbon) - `praatXXXX_macU.zip`: zipped universal executable for (32-bit) PPC and Intel Macs (Carbon) - `praatXXXX_macX.zip`: zipped executable for MacOS X (PPC) - `praatXXXX_mac9.sit`: StuffIt archive with executable for MacOS 9 - `praatXXXX_mac9.zip`: zipped executable for MacOS 9 - `praatXXXX_mac7.sit`: StuffIt archive with executable for MacOS 7 ### 2.3. Unix binaries - `praatXXXX_linux64.tar.gz`: gzipped tarred executable for 64-bit Linux (GTK) - `praatXXXX_linux32.tar.gz`: gzipped tarred executable for 32-bit Linux (GTK) - `praatXXXX_linux_motif64.tar.gz`: gzipped tarred executable for 64-bit Linux (Motif) - `praatXXXX_linux_motif32.tar.gz`: gzipped tarred executable for 32-bit Linux (Motif) - `praatXXXX_solaris.tar.gz`: gzipped tarred executable for Solaris praat-6.0.04/artsynth/000077500000000000000000000000001261542461700145745ustar00rootroot00000000000000praat-6.0.04/artsynth/Art_Speaker.cpp000066400000000000000000000362621261542461700175110ustar00rootroot00000000000000/* Art_Speaker.cpp * * Copyright (C) 1992-2012,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Art_Speaker.h" #define DLIP 5e-3 void Art_Speaker_toVocalTract (Art _art, Speaker speaker, double intX [], double intY [], double extX [], double extY [], double *bodyX, double *bodyY) { double *art = _art -> art; double f = speaker -> relativeSize * 1e-3; struct { double x, y, da; } jaw; struct { double dx, dy; } hyoid; struct { double x, y, r, radius; } body; struct { double x, y, r, a; } teeth; struct { double a; } blade; struct { double x, y, a; } tip; struct { double dx, dy; } lowerLip, upperLip; double HBody_x, HBody_y, HC, Sp, p, a, b; /* Determine the position of the hyoid bone (Mermelstein's H). */ /* The rest position is a characteristic of the speaker. */ /* The stylohyoid muscle pulls the hyoid bone up. */ /* The sternohyoid muscle pulls the hyoid bone down. */ /* The sphincter muscle pulls the hyoid bone backwards. */ hyoid.dx = -5 * f * art [kArt_muscle_SPHINCTER]; hyoid.dy = 20 * f * (art [kArt_muscle_STYLOHYOID] - art [kArt_muscle_STERNOHYOID]); /* The larynx moves up and down with the hyoid bone. */ /* Only the lowest point (Mermelstein's K) */ /* does not follow completely the horizontal movements. */ /* Anterior larynx. */ intX [1] = -14 * f + 0.5 * hyoid.dx; intY [1] = -53 * f + hyoid.dy; /* Top of larynx. */ intX [2] = -20 * f + hyoid.dx; intY [2] = -33 * f + hyoid.dy; /* Epiglottis. */ intX [3] = -20 * f + hyoid.dx; intY [3] = -26 * f + hyoid.dy; /* Hyoid bone. */ intX [4] = -16 * f + hyoid.dx; intY [4] = -26 * f + hyoid.dy; /* Posterior larynx. */ extX [1] = -22 * f + hyoid.dx; extY [1] = -53 * f + hyoid.dy; /* Esophagus. */ extX [2] = -26 * f + hyoid.dx; extY [2] = -40 * 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 [kArt_muscle_SPHINCTER] * 5 * 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 [kArt_muscle_SPHINCTER] * 5 * 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 [kArt_muscle_SPHINCTER] * 5 * f; extY [4] = 0.5 * (extY [3] + extY [5]); /* Tongue root. */ jaw.x = -75 * f, jaw.y = 53 * f; /* Position of the condyle. */ jaw.da = art [kArt_muscle_MASSETER] * 0.15 - art [kArt_muscle_MYLOHYOID] * 0.20; body.x = jaw.x + 81 * f * cos (-0.60 + jaw.da) - art [kArt_muscle_STYLOGLOSSUS] * 10 * f + art [kArt_muscle_GENIOGLOSSUS] * 10 * f; body.y = jaw.y + 81 * f * sin (-0.60 + jaw.da) - art [kArt_muscle_HYOGLOSSUS] * 10 * f + art [kArt_muscle_STYLOGLOSSUS] * 5 * 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; HBody_x = body.x - intX [4]; HBody_y = body.y - intY [4]; HC = sqrt (HBody_x * HBody_x + HBody_y * HBody_y); if (HC <= body.radius) { HC = body.radius; Sp = 0.0; // prevent rounding errors in sqrt (can occur on processors with e.g. 80-bit registers) } else { Sp = sqrt (HC * HC - body.radius * body.radius); } a = atan2 (HBody_y, HBody_x); b = asin (body.radius / HC); p = 0.57 * (34.8 * f - Sp); intX [5] = intX [4] + 0.5 * Sp * cos (a + b) - p * sin (a + b); intY [5] = intY [4] + 0.5 * Sp * sin (a + b) + p * cos (a + b); HBody_x = body.x - intX [5]; HBody_y = body.y - intY [5]; HC = sqrt (HBody_x * HBody_x + HBody_y * HBody_y); if (HC <= body.radius) { HC = body.radius; Sp = 0.0; } else Sp = sqrt (HC * HC - body.radius * body.radius); a = atan2 (HBody_y, HBody_x); b = asin (body.radius / HC); intX [6] = intX [5] + Sp * cos (a + b); intY [6] = intY [5] + Sp * sin (a + b); /* Posterior blade. */ teeth.a = speaker -> lowerTeeth.a + jaw.da; intX [7] = body.x + body.radius * cos (1.73 + teeth.a); intY [7] = body.y + body.radius * sin (1.73 + teeth.a); /* Tip. */ tip.a = (art [kArt_muscle_UPPER_TONGUE] - art [kArt_muscle_LOWER_TONGUE]) * 1.0; blade.a = teeth.a + 0.004 * (body.r - speaker -> neutralBodyDistance) + tip.a; intX [8] = intX [7] + speaker -> tip.length * cos (blade.a); intY [8] = intY [7] + speaker -> tip.length * sin (blade.a); /* Jaw. */ teeth.r = speaker -> lowerTeeth.r; teeth.x = jaw.x + teeth.r * cos (teeth.a); teeth.y = jaw.y + teeth.r * sin (teeth.a); intX [9] = teeth.x + speaker -> teethCavity.dx1; intY [9] = teeth.y + speaker -> teethCavity.dy; intX [10] = teeth.x + speaker -> teethCavity.dx2; intY [10] = intY [9]; intX [11] = teeth.x; intY [11] = teeth.y; /* Lower lip. */ lowerLip.dx = speaker -> lowerLip.dx + art [kArt_muscle_ORBICULARIS_ORIS] * 0.02 - 5e-3; lowerLip.dy = speaker -> lowerLip.dy + art [kArt_muscle_ORBICULARIS_ORIS] * 0.01; intX [12] = teeth.x; intY [12] = teeth.y + lowerLip.dy; intX [13] = teeth.x + lowerLip.dx; intY [13] = intY [12]; /* Velum. */ extX [6] = speaker -> velum.x; extY [6] = speaker -> velum.y; /* Palate. */ extX [7] = speaker -> alveoli.x; extY [7] = speaker -> alveoli.y; extX [8] = speaker -> upperTeeth.x; extY [8] = speaker -> upperTeeth.y; /* Upper lip. */ upperLip.dx = speaker -> upperLip.dx + art [kArt_muscle_ORBICULARIS_ORIS] * 0.02 - 5e-3; upperLip.dy = speaker -> upperLip.dy - art [kArt_muscle_ORBICULARIS_ORIS] * 0.01; extX [9] = extX [8]; extY [9] = extY [8] + upperLip.dy; extX [10] = extX [9] + upperLip.dx; extY [10] = extY [9]; extX [11] = extX [10] + 5e-3; extY [11] = extY [10] + DLIP; /* Chin. */ intX [14] = intX [13] + 5e-3; intY [14] = intY [13] - DLIP; intX [15] = intX [11] + 0.5e-2; intY [15] = intY [11] - 3.0e-2; intX [16] = intX [1]; intY [16] = intY [1]; } 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); previous = Graphics_insetViewport (g, 0.1, 0.9, 0.1, 0.9); Graphics_setWindow (g, -0.05, 0.05, -0.05, 0.05); /* Draw inner contour. */ for (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_line (g, intX [i], intY [i], intX [i + 1], intY [i + 1]); /* Draw outer contour. */ for (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_line (g, extX [i], extY [i], extX [i + 1], extY [i + 1]); Graphics_resetViewport (g, previous); } void Art_Speaker_fillInnerContour (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 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]; } Graphics_setGrey (g, 0.8); Graphics_fillArea (g, 16, & x [1], & y [1]); Graphics_fillCircle (g, bodyX, bodyY, 20 * 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; 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; if (i == 6) { double a7 = atan2 (intY [7] - bodyY, intX [7] - bodyX); double a6 = atan2 (intY [6] - bodyY, intX [6] - bodyX); double a = atan2 (y - bodyY, x - bodyX); double da6 = arcLength (a7, a6); double da = arcLength (a7, a); if (da <= da6) return fabs (sqrt ((bodyX - x) * (bodyX - x) + (bodyY - y) * (bodyY - y)) - bodyRadius); else nearby = arcLength (a7 + 0.5 * da6, a) < NUMpi ? 6 : 7; } else if ((x - intX [i]) * (intX [i + 1] - intX [i]) + (y - intY [i]) * (intY [i + 1] - intY [i]) < 0) { nearby = i; } else if ((x - intX [i + 1]) * (intX [i] - intX [i + 1]) + (y - intY [i + 1]) * (intY [i] - intY [i + 1]) < 0) { nearby = i + 1; } else { double boundaryDistance = sqrt ((intX [i + 1] - intX [i]) * (intX [i + 1] - intX [i]) + (intY [i + 1] - intY [i]) * (intY [i + 1] - intY [i])); double outerProduct = (intX [i] - x) * (intY [i + 1] - intY [i]) - (intY [i] - y) * (intX [i + 1] - intX [i]); return fabs (outerProduct) / boundaryDistance; } return sqrt ((intX [nearby] - x) * (intX [nearby] - x) + (intY [nearby] - y) * (intY [nearby] - y)); } static int inside (double x, double y, const double intX [], const double intY []) { int i, up = 0; for (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) up += ( y > intY [i] ? 1 : -1 ); } return up != 0 || bodyRadius * bodyRadius > (x - bodyX) * (x - bodyX) + (y - bodyY) * (y - bodyY); } void Art_Speaker_meshVocalTract (Art art, Speaker speaker, double xi [], double yi [], double xe [], double ye [], double xmm [], double ymm [], int 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; 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 */ 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]; xe [6] = 0.5 * extX [3] + 0.5 * extX [4]; ye [6] = 0.5 * extY [3] + 0.5 * extY [4]; xe [7] = 0.3 * extX [3] + 0.7 * extX [4]; ye [7] = 0.3 * extY [3] + 0.7 * extY [4]; xe [8] = 0.1 * extX [3] + 0.9 * extX [4]; ye [8] = 0.1 * extY [3] + 0.9 * extY [4]; xe [9] = 0.9 * extX [4] + 0.1 * extX [5]; ye [9] = 0.9 * extY [4] + 0.1 * extY [5]; xe [10] = 0.7 * extX [4] + 0.3 * extX [5]; ye [10] = 0.7 * extY [4] + 0.3 * extY [5]; xe [11] = 0.5 * extX [4] + 0.5 * extX [5]; ye [11] = 0.5 * extY [4] + 0.5 * extY [5]; xe [12] = 0.3 * extX [4] + 0.7 * extX [5]; 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 ++) { double a = 0.5 * NUMpi + (19 - i) * d_angle; xe [i] = speaker -> palate.radius * cos (a); ye [i] = speaker -> palate.radius * sin (a); } xe [19] = 0; ye [19] = speaker -> palate.radius; xe [20] = 0.25 * extX [7]; xe [21] = 0.50 * extX [7]; xe [22] = 0.75 * extX [7]; for (i = 20; i <= 22; i ++) { ye [i] = speaker -> palate.radius * sqrt (1.0 - xe [i] * xe [i] / (speaker -> palate.radius * speaker -> palate.radius)); } xe [23] = extX [7]; ye [23] = extY [7]; xe [24] = 0.5 * (extX [7] + extX [8]); ye [24] = 0.5 * (extY [7] + extY [8]); xe [25] = extX [8]; ye [25] = extY [8]; xe [26] = 0.25 * extX [11] + 0.75 * extX [9]; 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. */ 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) minimum = - minimum; 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. */ xi [i] = xe [i] + minimum; yi [i] = ye [i]; } 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 ++) { xm [i] = 0.5 * (xe [i] + xi [i]); ym [i] = 0.5 * (ye [i] + yi [i]); } for (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 [Art_Speaker_meshCount]; ymm [Art_Speaker_meshCount + 1] = 2 * 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; 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_setWindow (graphics, -0.05, 0.05, -0.05, 0.05); /* Mesh lines. */ for (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 ++) 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 ++) Graphics_line (graphics, xmm [i], ymm [i], xmm [i + 1], ymm [i + 1]); for (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 Graphics_resetViewport (graphics, previous); } /* End of file Art_Speaker.cpp */ praat-6.0.04/artsynth/Art_Speaker.h000066400000000000000000000035631261542461700171540ustar00rootroot00000000000000/* Art_Speaker.h * * Copyright (C) 1992-2011 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Articulation.h" #include "Speaker.h" #include "Graphics.h" void Art_Speaker_toVocalTract (Art art, Speaker speaker, double intX [], double intY [], double extX [], double extY [], double *bodyX, double *bodyY); /* Function: compute key places of the supralaryngeal vocal tract. Preconditions: index intX [1..13]; index intY [1..13]; index extX [1..9]; index extY [1..9]; Postconditions: int [1..6] is anterior larynx, hyoid, and tongue root. int [6..7] is the arc of the tongue body. int [7..13] is tongue blade, lower teeth, and lower lip. ext [1..5] is posterior larynx, back pharynx wall, and velic. ext [5..6] is the arc of the velum and palate. ext [6..9] is the gums, upper teeth and upper lip. */ void Art_Speaker_draw (Art art, Speaker speaker, Graphics g); 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 []); void Art_Speaker_drawMesh (Art art, Speaker speaker, Graphics g); /* End of file Art_Speaker.h */ praat-6.0.04/artsynth/Art_Speaker_Delta.cpp000066400000000000000000000066211261542461700206160ustar00rootroot00000000000000/* Art_Speaker_Delta.cpp * * Copyright (C) 1992-2011 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Art_Speaker_Delta.h" #include "Art_Speaker.h" 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 ++) delta -> tube [itube]. Dyeq = 120 * f * (1 + art -> art [kArt_muscle_LUNGS]); /* Glottis. */ { Delta_Tube t = delta -> tube + 36; t -> Dyeq = f * (5 - 10 * art -> art [kArt_muscle_INTERARYTENOID] + 3 * art -> art [kArt_muscle_POSTERIOR_CRICOARYTENOID] - 3 * art -> art [kArt_muscle_LATERAL_CRICOARYTENOID]); /* 4.38 */ t -> k1 = speaker -> lowerCord.k1 * (1 + art -> art [kArt_muscle_CRICOTHYROID]); t -> k3 = t -> k1 * (20 / t -> Dz) * (20 / t -> Dz); } if (speaker -> cord.numberOfMasses >= 2) { Delta_Tube t = delta -> tube + 37; t -> Dyeq = delta -> tube [36]. Dyeq; t -> k1 = speaker -> upperCord.k1 * (1 + art -> art [kArt_muscle_CRICOTHYROID]); t -> k3 = t -> k1 * (20 / t -> Dz) * (20 / t -> Dz); } if (speaker -> cord.numberOfMasses >= 10) { delta -> tube [84]. Dyeq = 0.75 * 1 * f + 0.25 * delta -> tube [36]. Dyeq; delta -> tube [85]. Dyeq = 0.50 * 1 * f + 0.50 * delta -> tube [36]. Dyeq; delta -> tube [86]. Dyeq = 0.25 * 1 * f + 0.75 * delta -> tube [36]. Dyeq; 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 ++) delta -> tube [itube]. k3 = delta -> tube [itube]. k1 * (20 / delta -> tube [itube]. Dz) * (20 / delta -> tube [itube]. Dz); } /* Vocal tract. */ Art_Speaker_meshVocalTract (art, speaker, xi, yi, xe, ye, xmm, ymm, closed); for (itube = 38; itube <= 64; itube ++) { Delta_Tube t = delta -> tube + itube; int 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; } delta -> tube [65]. Dxeq = delta -> tube [51]. Dxeq = delta -> tube [50]. Dxeq; /* Voor [r]: thy tube [60]. Brel = 0.1; thy tube [60]. k1 = 3; */ /* Nasopharyngeal port. */ delta -> tube [65]. Dyeq = f * (18 - 25 * art -> art [kArt_muscle_LEVATOR_PALATINI]); /* 4.40 */ for (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); } } /* End of file Art_Speaker_Delta.cpp */ praat-6.0.04/artsynth/Art_Speaker_Delta.h000066400000000000000000000016601261542461700202610ustar00rootroot00000000000000/* Art_Speaker_Delta.h * * Copyright (C) 1992-2011 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Articulation.h" #include "Speaker.h" #include "Delta.h" void Art_Speaker_intoDelta (Art art, Speaker speaker, Delta delta); /* End of file Art_Speaker_Delta.h */ praat-6.0.04/artsynth/Art_Speaker_to_VocalTract.cpp000066400000000000000000000033761261542461700223350ustar00rootroot00000000000000/* Art_Speaker_to_VocalTract.cpp * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Delta.h" #include "Speaker_to_Delta.h" #include "Art_Speaker_Delta.h" #include "Art_Speaker_to_VocalTract.h" autoVocalTract Art_Speaker_to_VocalTract (Art art, Speaker speaker) { autoDelta delta = Speaker_to_Delta (speaker); Art_Speaker_intoDelta (art, speaker, delta.get()); double area [300]; constexpr double sectionLength = 0.001; // one millimetre int numberOfSections = 0; for (long isection = 1; isection <= 27; isection ++) { Delta_Tube tube = delta -> tube + 37 + isection; int numberOfConstantSections = lround (tube -> Dxeq / sectionLength); double constantArea = tube -> Dyeq * tube -> Dzeq; for (int jsection = 1; jsection <= numberOfConstantSections; jsection ++) area [++ numberOfSections] = constantArea; } autoVocalTract thee = VocalTract_create (numberOfSections, sectionLength); for (long isection = 1; isection <= numberOfSections; isection ++) thy z [1] [isection] = area [isection]; return thee; } /* End of file Art_Speaker_to_VocalTract.cpp */ praat-6.0.04/artsynth/Art_Speaker_to_VocalTract.h000066400000000000000000000017131261542461700217730ustar00rootroot00000000000000/* Art_Speaker_to_VocalTract.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Articulation.h" #include "Speaker.h" #include "VocalTract.h" autoVocalTract Art_Speaker_to_VocalTract (Art art, Speaker speaker); /* End of file Art_Speaker_to_VocalTract.h */ praat-6.0.04/artsynth/Articulation.cpp000066400000000000000000000030151261542461700177350ustar00rootroot00000000000000/* Articulation.cpp * * Copyright (C) 1992-2011 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Articulation.h" #include "oo_DESTROY.h" #include "Articulation_def.h" #include "oo_COPY.h" #include "Articulation_def.h" #include "oo_EQUAL.h" #include "Articulation_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Articulation_def.h" #include "oo_WRITE_TEXT.h" #include "Articulation_def.h" #include "oo_WRITE_BINARY.h" #include "Articulation_def.h" #include "oo_READ_TEXT.h" #include "Articulation_def.h" #include "oo_READ_BINARY.h" #include "Articulation_def.h" #include "oo_DESCRIPTION.h" #include "Articulation_def.h" #include "enums_getText.h" #include "Articulation_enums.h" #include "enums_getValue.h" #include "Articulation_enums.h" Thing_implement (Art, Daata, 0); autoArt Art_create () { return Thing_new (Art); } /* End of file Articulation.cpp */ praat-6.0.04/artsynth/Articulation.h000066400000000000000000000025061261542461700174060ustar00rootroot00000000000000#ifndef _Articulation_h_ #define _Articulation_h_ /* Articulation.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Art = Articulation */ /* Members represent muscle activities for speech production. */ /* All members have values from 0 (no activity) to 1 (maximum activity). */ #include "Data.h" #include "Articulation_enums.h" #include "Articulation_def.h" oo_CLASS_CREATE (Art, Daata); autoArt Art_create (); /* Return value: an array of double, with indices from enum Art. Postconditions: result -> art [kArt_muscle_LUNGS] == 0.0; ... result -> art [kArt_muscle_BUCCINATOR] = 0.0; */ /* End of file Articulation.h */ #endif praat-6.0.04/artsynth/Articulation_def.h000066400000000000000000000016471261542461700202310ustar00rootroot00000000000000/* Articulation_def.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT Art oo_DEFINE_CLASS (Art, Daata) oo_DOUBLE_SET (art, kArt_muscle) oo_END_CLASS (Art) #undef ooSTRUCT /* End of file Articulation_def.h */ praat-6.0.04/artsynth/Articulation_enums.h000066400000000000000000000066121261542461700206170ustar00rootroot00000000000000/* Articulation_enums.h * * Copyright (C) 1992-2009,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ enums_begin (kArt_muscle, 0) enums_add (kArt_muscle, 0, _, U"_") enums_add (kArt_muscle, 1, LUNGS, U"Lungs") enums_add (kArt_muscle, 2, INTERARYTENOID, U"Interarytenoid") // constriction of larynx; 0 = breathing, 1 = constricted glottis enums_add (kArt_muscle, 3, CRICOTHYROID, U"Cricothyroid") // vocal-cord tension enums_add (kArt_muscle, 4, VOCALIS, U"Vocalis") // vocal-cord tension enums_add (kArt_muscle, 5, THYROARYTENOID, U"Thyroarytenoid") enums_add (kArt_muscle, 6, POSTERIOR_CRICOARYTENOID, U"PosteriorCricoarytenoid") // opening of glottis enums_add (kArt_muscle, 7, LATERAL_CRICOARYTENOID, U"LateralCricoarytenoid") // opening of glottis enums_add (kArt_muscle, 8, STYLOHYOID, U"Stylohyoid") // up movement of hyoid bone enums_add (kArt_muscle, 9, STERNOHYOID, U"Sternohyoid") // down movement of hyoid bone enums_add (kArt_muscle, 10, THYROPHARYNGEUS, U"Thyropharyngeus") // constriction of ventricular folds enums_add (kArt_muscle, 11, LOWER_CONSTRICTOR, U"LowerConstrictor") enums_add (kArt_muscle, 12, MIDDLE_CONSTRICTOR, U"MiddleConstrictor") enums_add (kArt_muscle, 13, UPPER_CONSTRICTOR, U"UpperConstrictor") enums_add (kArt_muscle, 14, SPHINCTER, U"Sphincter") // constriction of pharynx enums_add (kArt_muscle, 15, HYOGLOSSUS, U"Hyoglossus") // down movement of tongue body enums_add (kArt_muscle, 16, STYLOGLOSSUS, U"Styloglossus") // up movement of tongue body enums_add (kArt_muscle, 17, GENIOGLOSSUS, U"Genioglossus") // forward movement of tongue body enums_add (kArt_muscle, 18, UPPER_TONGUE, U"UpperTongue") // up curling of the tongue tip enums_add (kArt_muscle, 19, LOWER_TONGUE, U"LowerTongue") // down curling of the tongue enums_add (kArt_muscle, 20, TRANSVERSE_TONGUE, U"TransverseTongue") // thickening of tongue enums_add (kArt_muscle, 21, VERTICAL_TONGUE, U"VerticalTongue") // thinning of tongue enums_add (kArt_muscle, 22, RISORIUS, U"Risorius") // spreading of lips enums_add (kArt_muscle, 23, ORBICULARIS_ORIS, U"OrbicularisOris") // rounding of lips enums_add (kArt_muscle, 24, LEVATOR_PALATINI, U"LevatorPalatini") // closing of velo-pharyngeal port; 0 = open ("nasal"), 1 = closed ("oral") enums_add (kArt_muscle, 25, TENSOR_PALATINI, U"TensorPalatini") enums_add (kArt_muscle, 26, MASSETER, U"Masseter") // closing of jaw; 0 = open, 1 = closed enums_add (kArt_muscle, 27, MYLOHYOID, U"Mylohyoid") // opening of jaw enums_add (kArt_muscle, 28, LATERAL_PTERYGOID, U"LateralPterygoid") // horizontal jaw position enums_add (kArt_muscle, 29, BUCCINATOR, U"Buccinator") // oral wall tension enums_end (kArt_muscle, 29, LUNGS) /* End of file Articulation.enums */ praat-6.0.04/artsynth/Artword.cpp000066400000000000000000000117231261542461700167260ustar00rootroot00000000000000/* Artword.cpp * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Artword.h" #include "oo_DESTROY.h" #include "Artword_def.h" #include "oo_COPY.h" #include "Artword_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Artword_def.h" #include "oo_EQUAL.h" #include "Artword_def.h" #include "oo_WRITE_TEXT.h" #include "Artword_def.h" #include "oo_READ_TEXT.h" #include "Artword_def.h" #include "oo_WRITE_BINARY.h" #include "Artword_def.h" #include "oo_READ_BINARY.h" #include "Artword_def.h" #include "oo_DESCRIPTION.h" #include "Artword_def.h" Thing_implement (Artword, Daata, 0); autoArtword Artword_create (double totalTime) { autoArtword me = Thing_new (Artword); my totalTime = totalTime; for (int i = 1; i <= kArt_muscle_MAX; i ++) Artword_setDefault (me.get(), i); return me; } void Artword_setDefault (Artword me, int feature) { ArtwordData f = & my data [feature]; NUMvector_free (f -> times, 1); NUMvector_free (f -> targets, 1); f -> times = NUMvector (1, 2); f -> targets = NUMvector (1, 2); f -> numberOfTargets = 2; f -> times [1] = 0.0; f -> targets [1] = 0.0; f -> times [2] = my totalTime; f -> targets [2] = 0.0; f -> _iTarget = 1; } void Artword_setTarget (Artword me, int feature, double time, double target) { try { Melder_assert (feature >= 1); Melder_assert (feature <= kArt_muscle_MAX); ArtwordData f = & my data [feature]; Melder_assert (f -> numberOfTargets >= 2); int insert = 1; if (time < 0.0) time = 0.0; if (time > my totalTime) time = my totalTime; while (insert <= f -> numberOfTargets && f -> times [insert] < time) insert ++; Melder_assert (insert <= f -> numberOfTargets); // can never insert past totalTime if (f -> times [insert] != time) { long numberOfTargets = f -> numberOfTargets; NUMvector_insert (& f -> times, 1, & numberOfTargets, insert); numberOfTargets = f -> numberOfTargets; NUMvector_insert (& f -> targets, 1, & numberOfTargets, insert); f -> numberOfTargets ++; } f -> targets [insert] = target; f -> times [insert] = time; } catch (MelderError) { Melder_throw (me, U": target not set."); } } double Artword_getTarget (Artword me, int feature, double time) { ArtwordData f = & my data [feature]; double *times = f -> times, *targets = f -> targets; int iTarget = f -> _iTarget; if (! iTarget) iTarget = 1; while (time > times [iTarget + 1] && iTarget < f -> numberOfTargets - 1) iTarget ++; while (time < times [iTarget] && iTarget > 1) iTarget --; f -> _iTarget = iTarget; Melder_assert (iTarget > 0 && iTarget < f -> numberOfTargets); return targets [iTarget] + (time - times [iTarget]) * (targets [iTarget + 1] - targets [iTarget]) / (times [iTarget + 1] - times [iTarget]); } void Artword_removeTarget (Artword me, int feature, int iTarget) { ArtwordData f = & my data [feature]; Melder_assert (iTarget >= 1); Melder_assert (iTarget <= f -> numberOfTargets); if (iTarget == 1) f -> targets [iTarget] = 0.0; else if (iTarget == f -> numberOfTargets) f -> targets [f -> numberOfTargets] = 0.0; else { for (int i = iTarget; i < f -> numberOfTargets; i ++) { f -> times [i] = f -> times [i + 1]; f -> targets [i] = f -> targets [i + 1]; } f -> numberOfTargets --; } f -> _iTarget = 1; } void Artword_intoArt (Artword me, Art art, double time) { for (int feature = 1; feature <= kArt_muscle_MAX; feature ++) { art -> art [feature] = Artword_getTarget (me, feature, time); } } void Artword_draw (Artword me, Graphics g, int feature, int garnish) { long numberOfTargets = my data [feature]. numberOfTargets; if (numberOfTargets > 0) { autoNUMvector x (1, numberOfTargets); autoNUMvector y (1, numberOfTargets); Graphics_setInner (g); Graphics_setWindow (g, 0, my totalTime, -1.0, 1.0); for (int i = 1; i <= numberOfTargets; i ++) { x [i] = my data [feature]. times [i]; y [i] = my data [feature]. targets [i]; } Graphics_polyline (g, numberOfTargets, & x [1], & y [1]); Graphics_unsetInner (g); } if (garnish) { Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 3, true, true, true); Graphics_textTop (g, false, kArt_muscle_getText (feature)); Graphics_textBottom (g, true, U"Time (s)"); } } /* End of file Artword.cpp */ praat-6.0.04/artsynth/Artword.h000066400000000000000000000053151261542461700163730ustar00rootroot00000000000000#ifndef _Artword_h_ #define _Artword_h_ /* Artword.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Articulation.h" #include "Graphics.h" #include "Artword_def.h" oo_CLASS_CREATE (Artword, Daata); autoArtword Artword_create (double totalTime); void Artword_setDefault (Artword me, int feature); /* Postconditions: my data [feature]. numberOfTargets == 2; my data [feature]. times [1] == 0.0; my data [feature]. times [2] == self -> totalTime; my data [feature]. targets [1] == 0.0; my data [feature]. targets [2] == 0.0; rest unchanged; */ void Artword_setTarget (Artword me, int feature, double tim, double value); double Artword_getTarget (Artword me, int feature, double tim); void Artword_removeTarget (Artword me, int feature, int iTarget); /* Function: remove one target from the target list of "feature". If "iTarget" is the first or the last target in the list, only set the target to zero (begin and end targets remain). Preconditions: self != nullptr; feature in enum Art_MUSCLE; iTarget >= 1; iTarget <= self -> data [feature]. numberOfTargets; Postconditions: if (iTarget == 1) self -> data [feature]. targets [1] == 0.0; else if (iTarget == self -> data [feature]. numberOfTargets) self -> data [feature]. targets [iTarget] == 0.0; else self -> data [feature]. numberOfTargets == old self -> data [feature]. numberOfTargets - 1; for (i == iTarget..self -> data [feature]. numberOfTargets) self -> data [feature]. times [i] == old self -> data [feature]. times [i + 1]; self -> data [feature]. targets [i] == old self -> data [feature]. targets [i + 1]; */ /* Implemented methods: int Artword::writeText (I, FILE *f) writes an Artword as text to the stream f. */ void Artword_intoArt (Artword me, Art art, double tim); /* Function: Linear interpolation between targets, into an existing Art. Preconditions: me != nullptr; art != nullptr; */ void Artword_draw (Artword me, Graphics graphics, int feature, int garnish); /* End of file Artword.h */ #endif praat-6.0.04/artsynth/ArtwordEditor.cpp000066400000000000000000000143001261542461700200670ustar00rootroot00000000000000/* ArtwordEditor.cpp * * Copyright (C) 1992-2011,2013,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ArtwordEditor.h" #include "machine.h" Thing_implement (ArtwordEditor, Editor, 0); void structArtwordEditor :: v_destroy () { forget (graphics); ArtwordEditor_Parent :: v_destroy (); } static void updateList (ArtwordEditor me) { Artword artword = (Artword) my data; ArtwordData a = & artword -> data [my feature]; GuiList_deleteAllItems (my list); for (int i = 1; i <= a -> numberOfTargets; i ++) { GuiList_insertItem (my list, Melder_cat (Melder_single (a -> times [i]), U" ", Melder_single (a -> targets [i])), i); } Graphics_updateWs (my graphics); } static void gui_button_cb_removeTarget (I, GuiButtonEvent event) { (void) event; iam (ArtwordEditor); Artword artword = (Artword) my data; long numberOfSelectedPositions; long *selectedPositions = GuiList_getSelectedPositions (my list, & numberOfSelectedPositions); // BUG memory if (selectedPositions) { for (long ipos = numberOfSelectedPositions; ipos > 0; ipos --) Artword_removeTarget (artword, my feature, selectedPositions [ipos]); } NUMvector_free (selectedPositions, 1); updateList (me); Editor_broadcastDataChanged (me); } static void gui_button_cb_addTarget (I, GuiButtonEvent event) { (void) event; iam (ArtwordEditor); Artword artword = (Artword) my data; char32 *timeText = GuiText_getString (my time); double tim = Melder_atof (timeText); char32 *valueText = GuiText_getString (my value); double value = Melder_atof (valueText); ArtwordData a = & artword -> data [my feature]; int i = 1, oldCount = a -> numberOfTargets; Melder_free (timeText); Melder_free (valueText); Artword_setTarget (artword, my feature, tim, value); /* Optimization instead of "updateList (me)". */ if (tim < 0) tim = 0; if (tim > artword -> totalTime) tim = artword -> totalTime; while (tim != a -> times [i]) { i ++; Melder_assert (i <= a -> numberOfTargets); // can fail if tim is in an extended precision register } const char32 *itemText = Melder_cat (Melder_single (tim), U" ", Melder_single (value)); if (a -> numberOfTargets == oldCount) { GuiList_replaceItem (my list, itemText, i); } else { GuiList_insertItem (my list, itemText, i); } Graphics_updateWs (my graphics); Editor_broadcastDataChanged (me); } static void gui_radiobutton_cb_toggle (I, GuiRadioButtonEvent event) { iam (ArtwordEditor); my feature = event -> position; Melder_assert (my feature > 0); Melder_assert (my feature <= kArt_muscle_MAX); updateList (me); } static void gui_drawingarea_cb_expose (I, GuiDrawingAreaExposeEvent /* event */) { iam (ArtwordEditor); if (! my graphics) return; Artword artword = (Artword) my data; Graphics_clearWs (my graphics); Artword_draw (artword, my graphics, my feature, true); } static void gui_drawingarea_cb_click (I, GuiDrawingAreaClickEvent event) { iam (ArtwordEditor); if (! my graphics) return; Artword artword = (Artword) my data; Graphics_setWindow (my graphics, 0, artword -> totalTime, -1.0, 1.0); Graphics_setInner (my graphics); double xWC, yWC; Graphics_DCtoWC (my graphics, event -> x, event -> y, & xWC, & yWC); Graphics_unsetInner (my graphics); GuiText_setString (my time, Melder_fixed (xWC, 6)); GuiText_setString (my value, Melder_fixed (yWC, 6)); } void structArtwordEditor :: v_dataChanged () { updateList (this); Graphics_updateWs (graphics); } void structArtwordEditor :: v_createChildren () { int dy = Machine_getMenuBarHeight (); GuiLabel_createShown (d_windowForm, 40, 100, dy + 3, dy + 3 + Gui_LABEL_HEIGHT, U"Targets:", 0); GuiLabel_createShown (d_windowForm, 5, 65, dy + 20, dy + 20 + Gui_LABEL_HEIGHT, U"Times:", 0); GuiLabel_createShown (d_windowForm, 80, 140, dy + 20, dy + 20 + Gui_LABEL_HEIGHT, U"Values:", 0); list = GuiList_createShown (d_windowForm, 0, 140, dy + 40, dy + 340, true, nullptr); GuiButton_createShown (d_windowForm, 10, 130, dy + 410, dy + 410 + Gui_PUSHBUTTON_HEIGHT, U"Remove target", gui_button_cb_removeTarget, this, 0); drawingArea = GuiDrawingArea_createShown (d_windowForm, 170, 470, dy + 10, dy + 310, gui_drawingarea_cb_expose, gui_drawingarea_cb_click, nullptr, nullptr, this, 0); GuiLabel_createShown (d_windowForm, 220, 270, dy + 340, dy + 340 + Gui_LABEL_HEIGHT, U"Time:", 0); time = GuiText_createShown (d_windowForm, 270, 370, dy + 340, dy + 340 + Gui_TEXTFIELD_HEIGHT, 0); GuiLabel_createShown (d_windowForm, 220, 270, dy + 370, dy + 370 + Gui_LABEL_HEIGHT, U"Value:", 0); value = GuiText_createShown (d_windowForm, 270, 370, dy + 370, dy + 370 + Gui_TEXTFIELD_HEIGHT, 0); GuiButton_createShown (d_windowForm, 240, 360, dy + 410, dy + 410 + Gui_PUSHBUTTON_HEIGHT, U"Add target", gui_button_cb_addTarget, this, GuiButton_DEFAULT); dy = Machine_getMenuBarHeight (); GuiRadioGroup_begin (); for (int i = 1; i <= kArt_muscle_MAX; i ++) { button [i] = GuiRadioButton_createShown (d_windowForm, 480, 0, dy, dy + Gui_RADIOBUTTON_HEIGHT, kArt_muscle_getText (i), gui_radiobutton_cb_toggle, this, 0); dy += Gui_RADIOBUTTON_HEIGHT + Gui_RADIOBUTTON_SPACING - 2; } GuiRadioGroup_end (); feature = 1; GuiRadioButton_set (button [feature]); } autoArtwordEditor ArtwordEditor_create (const char32 *title, Artword data) { try { autoArtwordEditor me = Thing_new (ArtwordEditor); Editor_init (me.peek(), 20, 40, 650, 600, title, data); //XtUnmanageChild (my menuBar); my graphics = Graphics_create_xmdrawingarea (my drawingArea); updateList (me.peek()); return me; } catch (MelderError) { Melder_throw (U"Artword window not created."); } } /* End of file ArtwordEditor.cpp */ praat-6.0.04/artsynth/ArtwordEditor.h000066400000000000000000000023751261542461700175450ustar00rootroot00000000000000#ifndef _ArtwordEditor_h_ #define _ArtwordEditor_h_ /* ArtwordEditor.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Editor.h" #include "Artword.h" Thing_define (ArtwordEditor, Editor) { Graphics graphics; int feature; GuiList list; GuiDrawingArea drawingArea; GuiText time, value; GuiRadioButton button [1 + kArt_muscle_MAX]; void v_destroy () override; void v_createChildren () override; void v_dataChanged () override; }; autoArtwordEditor ArtwordEditor_create (const char32 *title, Artword data); /* End of file ArtwordEditor.h */ #endif praat-6.0.04/artsynth/Artword_Speaker.cpp000066400000000000000000000032721261542461700204000ustar00rootroot00000000000000/* Artword_Speaker.cpp * * Copyright (C) 1992-2011 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Art_Speaker.h" #include "Artword_Speaker.h" void Artword_Speaker_draw (Artword artword, Speaker speaker, Graphics g, int numberOfSteps) { double oldLineWidth = Graphics_inqLineWidth (g); autoArt art = Art_create (); for (int i = 0; i <= numberOfSteps; i ++) { Artword_intoArt (artword, art.get(), i * artword -> totalTime / numberOfSteps); Graphics_setLineWidth (g, 2 + i + i); Art_Speaker_draw (art.get(), speaker, g); } Graphics_setLineWidth (g, oldLineWidth); } void Artword_Speaker_movie (Artword artword, Speaker speaker, Graphics g) { double timeStep = 0.00001; autoArt art = Art_create (); for (double tim = 0.0; tim < artword -> totalTime; tim += timeStep) { Artword_intoArt (artword, art.get(), tim); Graphics_setViewport (g, 0, 1, 0, 1); Graphics_clearWs (g); Art_Speaker_draw (art.get(), speaker, g); Graphics_flushWs (g); // TODO: we should pause here a bit } } /* End of file Artword_Speaker.cpp */ praat-6.0.04/artsynth/Artword_Speaker.h000066400000000000000000000020171261542461700200410ustar00rootroot00000000000000/* Artword_Speaker.h * * Copyright (C) 1992-2011 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Artword.h" #include "Speaker.h" #include "Graphics.h" void Artword_Speaker_draw (Artword artword, Speaker speaker, Graphics g, int numberOfSteps); void Artword_Speaker_movie (Artword artword, Speaker speaker, Graphics g); /* End of file Artword_Speaker.h */ praat-6.0.04/artsynth/Artword_Speaker_Sound.cpp000066400000000000000000000035141261542461700215470ustar00rootroot00000000000000/* Artword_Speaker_Sound.cpp * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Artword_Speaker_Sound.h" #include "Artword_Speaker.h" #include "Art_Speaker.h" struct playInfo { Artword artword; Speaker speaker; Graphics graphics; }; static int playCallback (void *playClosure, int /* phase */, double /* tmin */, double /* tmax */, double t) { struct playInfo *me = (struct playInfo *) playClosure; static autoArt art; if (! art) art = Art_create (); Artword_intoArt (my artword, art.get(), t); Graphics_clearWs (my graphics); Art_Speaker_draw (art.get(), my speaker, my graphics); return 1; } void Artword_Speaker_Sound_movie (Artword artword, Speaker speaker, Sound sound, Graphics graphics) { try { static struct playInfo info; // must be static!!! info. artword = artword; info. speaker = speaker; info. graphics = graphics; autoSound mySound = sound ? nullptr : Sound_createSimple (1, artword -> totalTime, 44100); Sound_play (sound ? sound : mySound.peek(), playCallback, & info); } catch (MelderError) { Melder_throw (artword, U" & ", speaker, U": movie not played."); } } /* End of file Artword_Speaker_Sound.cpp */ praat-6.0.04/artsynth/Artword_Speaker_Sound.h000066400000000000000000000017251261542461700212160ustar00rootroot00000000000000/* Artword_Speaker_Sound.h * * Copyright (C) 1992-2011 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Artword.h" #include "Speaker.h" #include "Sound.h" void Artword_Speaker_Sound_movie (Artword artword, Speaker speaker, Sound sound, Graphics graphics); /* End of file Artword_Speaker_Sound.h */ praat-6.0.04/artsynth/Artword_Speaker_to_Sound.cpp000066400000000000000000000457231261542461700222610ustar00rootroot00000000000000/* Artword_Speaker_to_Sound.cpp * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Speaker_to_Delta.h" #include "Art_Speaker_Delta.h" #include "Artword_Speaker_to_Sound.h" #define Dymin 0.00001 #define criticalVelocity 10.0 #define noiseFactor 0.1 #define MONITOR_SAMPLES 11 /* While debugging, some of these can be 1; otherwise, they are all 0: */ #define EQUAL_TUBE_WIDTHS 0 #define CONSTANT_TUBE_LENGTHS 1 #define NO_MOVING_WALLS 0 #define NO_TURBULENCE 0 #define NO_RADIATION_DAMPING 0 #define NO_BERNOULLI_EFFECT 0 #define MASS_LEAPFROG 0 #define B91 0 autoSound Artword_Speaker_to_Sound (Artword artword, Speaker speaker, double fsamp, int oversampling, autoSound *out_w1, int iw1, autoSound *out_w2, int iw2, autoSound *out_w3, int iw3, autoSound *out_p1, int ip1, autoSound *out_p2, int ip2, autoSound *out_p3, int ip3, autoSound *out_v1, int iv1, autoSound *out_v2, int iv2, autoSound *out_v3, int iv3) { try { autoSound result = Sound_createSimple (1, artword -> totalTime, fsamp); long numberOfSamples = result -> nx; double minTract [1+78], maxTract [1+78]; // for drawing double Dt = 1.0 / fsamp / oversampling, rho0 = 1.14, c = 353.0, onebyc2 = 1.0 / (c * c), rho0c2 = rho0 * c * c, halfDt = 0.5 * Dt, twoDt = 2.0 * Dt, halfc2Dt = 0.5 * c * c * Dt, twoc2Dt = 2.0 * c * c * Dt, onebytworho0 = 1.0 / (2.0 * rho0), Dtbytworho0 = Dt / (2.0 * rho0); double tension, rrad, onebygrad, totalVolume; autoArt art = Art_create (); autoDelta delta = Speaker_to_Delta (speaker); autoMelderMonitor monitor (U"Articulatory synthesis"); Artword_intoArt (artword, art.peek(), 0.0); Art_Speaker_intoDelta (art.peek(), speaker, delta.peek()); int M = delta -> numberOfTubes; autoSound w1, w2, w3, p1, p2, p3, v1, v2, v3; if (iw1 > 0 && iw1 <= M) w1 = Sound_createSimple (1, artword -> totalTime, fsamp); else iw1 = 0; if (iw2 > 0 && iw2 <= M) w2 = Sound_createSimple (1, artword -> totalTime, fsamp); else iw2 = 0; if (iw3 > 0 && iw3 <= M) w3 = Sound_createSimple (1, artword -> totalTime, fsamp); else iw3 = 0; if (ip1 > 0 && ip1 <= M) p1 = Sound_createSimple (1, artword -> totalTime, fsamp); else ip1 = 0; if (ip2 > 0 && ip2 <= M) p2 = Sound_createSimple (1, artword -> totalTime, fsamp); else ip2 = 0; if (ip3 > 0 && ip3 <= M) p3 = Sound_createSimple (1, artword -> totalTime, fsamp); else ip3 = 0; if (iv1 > 0 && iv1 <= M) v1 = Sound_createSimple (1, artword -> totalTime, fsamp); else iv1 = 0; if (iv2 > 0 && iv2 <= M) v2 = Sound_createSimple (1, artword -> totalTime, fsamp); else iv2 = 0; if (iv3 > 0 && iv3 <= M) v3 = Sound_createSimple (1, artword -> totalTime, fsamp); else iv3 = 0; /* Initialize drawing. */ for (int i = 1; i <= 78; i ++) { minTract [i] = 100.0; maxTract [i] = -100.0; } totalVolume = 0.0; for (int m = 1; m <= M; m ++) { Delta_Tube t = delta->tube + m; if (! t -> left1 && ! t -> right1) continue; t->Dx = t->Dxeq; t->dDxdt = 0.0; // 5.113 (numbers refer to equations in Boersma (1998) t->Dy = t->Dyeq; t->dDydt = 0.0; // 5.113 t->Dz = t->Dzeq; // 5.113 t->A = t->Dz * ( t->Dy >= t->dy ? t->Dy + Dymin : t->Dy <= - t->dy ? Dymin : (t->dy + t->Dy) * (t->dy + t->Dy) / (4.0 * t->dy) + Dymin ); // 4.4, 4.5 #if EQUAL_TUBE_WIDTHS t->A = 0.0001; #endif t->Jleft = t->Jright = 0.0; // 5.113 t->Qleft = t->Qright = rho0c2; // 5.113 t->pleft = t->pright = 0.0; // 5.114 t->Kleft = t->Kright = 0.0; // 5.114 t->V = t->A * t->Dx; // 5.114 totalVolume += t->V; } //Melder_casual (U"Starting volume: ", totalVolume * 1000, U" litres."); for (long sample = 1; sample <= numberOfSamples; sample ++) { double time = (sample - 1) / fsamp; Artword_intoArt (artword, art.peek(), time); Art_Speaker_intoDelta (art.peek(), speaker, delta.peek()); if (sample % MONITOR_SAMPLES == 0 && monitor.graphics()) { // because we can be in batch Graphics graphics = monitor.graphics(); double area [1+78]; Graphics_Viewport vp; for (int i = 1; i <= 78; i ++) { area [i] = delta -> tube [i]. A; if (area [i] < minTract [i]) minTract [i] = area [i]; if (area [i] > maxTract [i]) maxTract [i] = area [i]; } Graphics_clearWs (graphics); vp = Graphics_insetViewport (monitor.graphics(), 0.0, 0.5, 0.5, 1.0); Graphics_setWindow (graphics, 0.0, 1.0, 0.0, 0.05); Graphics_setColour (graphics, Graphics_RED); Graphics_function (graphics, minTract, 1, 35, 0.0, 0.9); Graphics_function (graphics, maxTract, 1, 35, 0.0, 0.9); Graphics_setColour (graphics, Graphics_BLACK); Graphics_function (graphics, area, 1, 35, 0.0, 0.9); Graphics_setLineType (graphics, Graphics_DOTTED); Graphics_line (graphics, 0.0, 0.0, 1.0, 0.0); Graphics_setLineType (graphics, Graphics_DRAWN); Graphics_resetViewport (graphics, vp); vp = Graphics_insetViewport (graphics, 0, 0.5, 0, 0.5); Graphics_setWindow (graphics, 0.0, 1.0, -0.000003, 0.00001); Graphics_setColour (graphics, Graphics_RED); Graphics_function (graphics, minTract, 36, 37, 0.2, 0.8); Graphics_function (graphics, maxTract, 36, 37, 0.2, 0.8); Graphics_setColour (graphics, Graphics_BLACK); Graphics_function (graphics, area, 36, 37, 0.2, 0.8); Graphics_setLineType (graphics, Graphics_DOTTED); Graphics_line (graphics, 0.0, 0.0, 1.0, 0.0); Graphics_setLineType (graphics, Graphics_DRAWN); Graphics_resetViewport (graphics, vp); vp = Graphics_insetViewport (graphics, 0.5, 1.0, 0.5, 1.0); Graphics_setWindow (graphics, 0.0, 1.0, 0.0, 0.001); Graphics_setColour (graphics, Graphics_RED); Graphics_function (graphics, minTract, 38, 64, 0.0, 1.0); Graphics_function (graphics, maxTract, 38, 64, 0.0, 1.0); Graphics_setColour (graphics, Graphics_BLACK); Graphics_function (graphics, area, 38, 64, 0.0, 1.0); Graphics_setLineType (graphics, Graphics_DOTTED); Graphics_line (graphics, 0.0, 0.0, 1.0, 0.0); Graphics_setLineType (graphics, Graphics_DRAWN); Graphics_resetViewport (graphics, vp); vp = Graphics_insetViewport (graphics, 0.5, 1.0, 0.0, 0.5); Graphics_setWindow (graphics, 0.0, 1.0, 0.001, 0.0); Graphics_setColour (graphics, Graphics_RED); Graphics_function (graphics, minTract, 65, 78, 0.5, 1.0); Graphics_function (graphics, maxTract, 65, 78, 0.5, 1.0); Graphics_setColour (graphics, Graphics_BLACK); Graphics_function (graphics, area, 65, 78, 0.5, 1.0); Graphics_setLineType (graphics, Graphics_DRAWN); Graphics_resetViewport (graphics, vp); Melder_monitor ((double) sample / numberOfSamples, U"Articulatory synthesis: ", Melder_half (time), U" seconds"); } for (int n = 1; n <= oversampling; n ++) { for (int m = 1; m <= M; m ++) { Delta_Tube t = delta -> tube + m; if (! t -> left1 && ! t -> right1) continue; /* New geometry. */ #if CONSTANT_TUBE_LENGTHS t->Dxnew = t->Dx; #else t->dDxdtnew = (t->dDxdt + Dt * 10000.0 * (t->Dxeq - t->Dx)) / (1.0 + 200.0 * Dt); // critical damping, 10 ms t->Dxnew = t->Dx + t->dDxdtnew * Dt; #endif /* 3-way: equal lengths. */ /* This requires left tubes to be processed before right tubes. */ if (t->left1 && t->left1->right2) t->Dxnew = t->left1->Dxnew; t->Dz = t->Dzeq; /* immediate... */ t->eleft = (t->Qleft - t->Kleft) * t->V; // 5.115 t->eright = (t->Qright - t->Kright) * t->V; // 5.115 t->e = 0.5 * (t->eleft + t->eright); // 5.116 t->p = 0.5 * (t->pleft + t->pright); // 5.116 t->DeltaP = t->e / t->V - rho0c2; // 5.117 t->v = t->p / (rho0 + onebyc2 * t->DeltaP); // 5.118 { double dDy = t->Dyeq - t->Dy; double cubic = t->k3 * dDy * dDy; Delta_Tube l1 = t->left1, l2 = t->left2, r1 = t->right1, r2 = t->right2; tension = dDy * (t->k1 + cubic); t->B = 2.0 * t->Brel * sqrt (t->mass * (t->k1 + 3.0 * cubic)); if (t->k1left1 != 0.0 && l1) tension += t->k1left1 * t->k1 * (dDy - (l1->Dyeq - l1->Dy)); if (t->k1left2 != 0.0 && l2) tension += t->k1left2 * t->k1 * (dDy - (l2->Dyeq - l2->Dy)); if (t->k1right1 != 0.0 && r1) tension += t->k1right1 * t->k1 * (dDy - (r1->Dyeq - r1->Dy)); if (t->k1right2 != 0.0 && r2) tension += t->k1right2 * t->k1 * (dDy - (r2->Dyeq - r2->Dy)); } if (t->Dy < t->dy) { if (t->Dy >= - t->dy) { double dDy = t->dy - t->Dy, dDy2 = dDy * dDy; tension += dDy2 / (4.0 * t->dy) * (t->s1 + 0.5 * t->s3 * dDy2); t->B += 2.0 * dDy / (2.0 * t->dy) * sqrt (t->mass * (t->s1 + t->s3 * dDy2)); } else { tension -= t->Dy * (t->s1 + t->s3 * (t->Dy * t->Dy + t->dy * t->dy)); t->B += 2.0 * sqrt (t->mass * (t->s1 + t->s3 * (3.0 * t->Dy * t->Dy + t->dy * t->dy))); } } t->dDydtnew = (t->dDydt + Dt / t->mass * (tension + 2.0 * t->DeltaP * t->Dz * t->Dx)) / (1.0 + t->B * Dt / t->mass); // 5.119 t->Dynew = t->Dy + t->dDydtnew * Dt; // 5.119 #if NO_MOVING_WALLS t->Dynew = t->Dy; #endif t->Anew = t->Dz * ( t->Dynew >= t->dy ? t->Dynew + Dymin : t->Dynew <= - t->dy ? Dymin : (t->dy + t->Dynew) * (t->dy + t->Dynew) / (4.0 * t->dy) + Dymin ); // 4.4, 4.5 #if EQUAL_TUBE_WIDTHS t->Anew = 0.0001; #endif t->Ahalf = 0.5 * (t->A + t->Anew); // 5.120 t->Dxhalf = 0.5 * (t->Dxnew + t->Dx); // 5.121 t->Vnew = t->Anew * t->Dxnew; // 5.128 { double oneByDyav = t->Dz / t->A; /*t->R = 12.0 * 1.86e-5 * t->parallel * t->parallel * oneByDyav * oneByDyav;*/ if (t->Dy < 0.0) t->R = 12.0 * 1.86e-5 / (Dymin * Dymin + t->dy * t->dy); else t->R = 12.0 * 1.86e-5 * t->parallel * t->parallel / ((t->Dy + Dymin) * (t->Dy + Dymin) + t->dy * t->dy); t->R += 0.3 * t->parallel * oneByDyav; /* 5.23 */ } t->r = (1.0 + t->R * Dt / rho0) * t->Dxhalf / t->Anew; // 5.122 t->ehalf = t->e + halfc2Dt * (t->Jleft - t->Jright); // 5.123 t->phalf = (t->p + halfDt * (t->Qleft - t->Qright) / t->Dx) / (1.0 + Dtbytworho0 * t->R); // 5.123 #if MASS_LEAPFROG t->ehalf = t->ehalfold + 2.0 * halfc2Dt * (t->Jleft - t->Jright); #endif t->Jhalf = t->phalf * t->Ahalf; // 5.124 t->Qhalf = t->ehalf / (t->Ahalf * t->Dxhalf) + onebytworho0 * t->phalf * t->phalf; // 5.124 #if NO_BERNOULLI_EFFECT t->Qhalf = t->ehalf / (t->Ahalf * t->Dxhalf); #endif } for (int m = 1; m <= M; m ++) { // compute Jleftnew and Qleftnew Delta_Tube l = delta->tube + m, r1 = l -> right1, r2 = l -> right2, r = r1; Delta_Tube l1 = l, l2 = r ? r -> left2 : nullptr; if (! l->left1) { // closed boundary at the left side (diaphragm)? if (! r) continue; // tube not connected at all l->Jleftnew = 0; // 5.132 l->Qleftnew = (l->eleft - twoc2Dt * l->Jhalf) / l->Vnew; // 5.132 } else // left boundary open to another tube will be handled... (void) 0; // ...together with the right boundary of the tube to the left if (! r) { // open boundary at the right side (lips, nostrils)? rrad = 1.0 - c * Dt / 0.02; // radiation resistance, 5.135 onebygrad = 1.0 / (1.0 + c * Dt / 0.02); // radiation conductance, 5.135 #if NO_RADIATION_DAMPING rrad = 0; onebygrad = 0; #endif l->prightnew = ((l->Dxhalf / Dt + c * onebygrad) * l->pright + 2.0 * ((l->Qhalf - rho0c2) - (l->Qright - rho0c2) * onebygrad)) / (l->r * l->Anew / Dt + c * onebygrad); // 5.136 l->Jrightnew = l->prightnew * l->Anew; // 5.136 l->Qrightnew = (rrad * (l->Qright - rho0c2) + c * (l->prightnew - l->pright)) * onebygrad + rho0c2; // 5.136 } else if (! l2 && ! r2) { // two-way boundary if (l->v > criticalVelocity && l->A < r->A) { l->Pturbrightnew = -0.5 * rho0 * (l->v - criticalVelocity) * (1.0 - l->A / r->A) * (1.0 - l->A / r->A) * l->v; if (l->Pturbrightnew != 0.0) l->Pturbrightnew *= NUMrandomGauss (1.0, noiseFactor) /* * l->A */; } if (r->v < - criticalVelocity && r->A < l->A) { l->Pturbrightnew = 0.5 * rho0 * (r->v + criticalVelocity) * (1.0 - r->A / l->A) * (1.0 - r->A / l->A) * r->v; if (l->Pturbrightnew != 0.0) l->Pturbrightnew *= NUMrandomGauss (1.0, noiseFactor) /* * r->A */; } #if NO_TURBULENCE l->Pturbrightnew = 0.0; #endif l->Jrightnew = r->Jleftnew = (l->Dxhalf * l->pright + r->Dxhalf * r->pleft + twoDt * (l->Qhalf - r->Qhalf + l->Pturbright)) / (l->r + r->r); // 5.127 #if B91 l->Jrightnew = r->Jleftnew = (l->pright + r->pleft + 2.0 * twoDt * (l->Qhalf - r->Qhalf + l->Pturbright) / (l->Dxhalf + r->Dxhalf)) / (l->r / l->Dxhalf + r->r / r->Dxhalf); #endif l->prightnew = l->Jrightnew / l->Anew; // 5.128 r->pleftnew = r->Jleftnew / r->Anew; // 5.128 l->Krightnew = onebytworho0 * l->prightnew * l->prightnew; // 5.128 r->Kleftnew = onebytworho0 * r->pleftnew * r->pleftnew; // 5.128 #if NO_BERNOULLI_EFFECT l->Krightnew = r->Kleftnew = 0.0; #endif l->Qrightnew = (l->eright + r->eleft + twoc2Dt * (l->Jhalf - r->Jhalf) + l->Krightnew * l->Vnew + (r->Kleftnew - l->Pturbrightnew) * r->Vnew) / (l->Vnew + r->Vnew); // 5.131 r->Qleftnew = l->Qrightnew + l->Pturbrightnew; // 5.131 } else if (r2) { // two adjacent tubes at the right side (velic) r1->Jleftnew = (r1->Jleft * r1->Dxhalf * (1.0 / (l->A + r2->A) + 1.0 / r1->A) + twoDt * ((l->Ahalf * l->Qhalf + r2->Ahalf * r2->Qhalf ) / (l->Ahalf + r2->Ahalf) - r1->Qhalf)) / (1.0 / (1.0 / l->r + 1.0 / r2->r) + r1->r); // 5.138 r2->Jleftnew = (r2->Jleft * r2->Dxhalf * (1.0 / (l->A + r1->A) + 1.0 / r2->A) + twoDt * ((l->Ahalf * l->Qhalf + r1->Ahalf * r1->Qhalf ) / (l->Ahalf + r1->Ahalf) - r2->Qhalf)) / (1.0 / (1.0 / l->r + 1.0 / r1->r) + r2->r); // 5.138 l->Jrightnew = r1->Jleftnew + r2->Jleftnew; // 5.139 l->prightnew = l->Jrightnew / l->Anew; // 5.128 r1->pleftnew = r1->Jleftnew / r1->Anew; // 5.128 r2->pleftnew = r2->Jleftnew / r2->Anew; // 5.128 l->Krightnew = onebytworho0 * l->prightnew * l->prightnew; // 5.128 r1->Kleftnew = onebytworho0 * r1->pleftnew * r1->pleftnew; // 5.128 r2->Kleftnew = onebytworho0 * r2->pleftnew * r2->pleftnew; // 5.128 #if NO_BERNOULLI_EFFECT l->Krightnew = r1->Kleftnew = r2->Kleftnew = 0; #endif l->Qrightnew = r1->Qleftnew = r2->Qleftnew = (l->eright + r1->eleft + r2->eleft + twoc2Dt * (l->Jhalf - r1->Jhalf - r2->Jhalf) + l->Krightnew * l->Vnew + r1->Kleftnew * r1->Vnew + r2->Kleftnew * r2->Vnew) / (l->Vnew + r1->Vnew + r2->Vnew); // 5.137 } else { Melder_assert (l2 != nullptr); l1->Jrightnew = (l1->Jright * l1->Dxhalf * (1.0 / (r->A + l2->A) + 1.0 / l1->A) - twoDt * ((r->Ahalf * r->Qhalf + l2->Ahalf * l2->Qhalf ) / (r->Ahalf + l2->Ahalf) - l1->Qhalf)) / (1.0 / (1.0 / r->r + 1.0 / l2->r) + l1->r); // 5.138 l2->Jrightnew = (l2->Jright * l2->Dxhalf * (1.0 / (r->A + l1->A) + 1.0 / l2->A) - twoDt * ((r->Ahalf * r->Qhalf + l1->Ahalf * l1->Qhalf ) / (r->Ahalf + l1->Ahalf) - l2->Qhalf)) / (1.0 / (1.0 / r->r + 1.0 / l1->r) + l2->r); // 5.138 r->Jleftnew = l1->Jrightnew + l2->Jrightnew; // 5.139 r->pleftnew = r->Jleftnew / r->Anew; // 5.128 l1->prightnew = l1->Jrightnew / l1->Anew; // 5.128 l2->prightnew = l2->Jrightnew / l2->Anew; // 5.128 r->Kleftnew = onebytworho0 * r->pleftnew * r->pleftnew; // 5.128 l1->Krightnew = onebytworho0 * l1->prightnew * l1->prightnew; // 5.128 l2->Krightnew = onebytworho0 * l2->prightnew * l2->prightnew; // 5.128 #if NO_BERNOULLI_EFFECT r->Kleftnew = l1->Krightnew = l2->Krightnew = 0.0; #endif r->Qleftnew = l1->Qrightnew = l2->Qrightnew = (r->eleft + l1->eright + l2->eright + twoc2Dt * (l1->Jhalf + l2->Jhalf - r->Jhalf) + r->Kleftnew * r->Vnew + l1->Krightnew * l1->Vnew + l2->Krightnew * l2->Vnew) / (r->Vnew + l1->Vnew + l2->Vnew); // 5.137 } } /* Save some results. */ if (n == (oversampling + 1) / 2) { double out = 0.0; for (int m = 1; m <= M; m ++) { Delta_Tube t = delta->tube + m; out += rho0 * t->Dx * t->Dz * t->dDydt * Dt * 1000.0; // radiation of wall movement, 5.140 if (! t->right1) out += t->Jrightnew - t->Jright; // radiation of open tube end } result -> z [1] [sample] = out /= 4.0 * NUMpi * 0.4 * Dt; // at 0.4 metres if (iw1) w1 -> z [1] [sample] = delta->tube[iw1].Dy; if (iw2) w2 -> z [1] [sample] = delta->tube[iw2].Dy; if (iw3) w3 -> z [1] [sample] = delta->tube[iw3].Dy; if (ip1) p1 -> z [1] [sample] = delta->tube[ip1].DeltaP; if (ip2) p2 -> z [1] [sample] = delta->tube[ip2].DeltaP; if (ip3) p3 -> z [1] [sample] = delta->tube[ip3].DeltaP; if (iv1) v1 -> z [1] [sample] = delta->tube[iv1].v; if (iv2) v2 -> z [1] [sample] = delta->tube[iv2].v; if (iv3) v3 -> z [1] [sample] = delta->tube[iv3].v; } for (int m = 1; m <= M; m ++) { Delta_Tube t = delta->tube + m; t->Jleft = t->Jleftnew; t->Jright = t->Jrightnew; t->Qleft = t->Qleftnew; t->Qright = t->Qrightnew; t->Dy = t->Dynew; t->dDydt = t->dDydtnew; t->A = t->Anew; t->Dx = t->Dxnew; t->dDxdt = t->dDxdtnew; t->eleft = t->eleftnew; t->eright = t->erightnew; #if MASS_LEAPFROG t->ehalfold = t->ehalf; #endif t->pleft = t->pleftnew; t->pright = t->prightnew; t->Kleft = t->Kleftnew; t->Kright = t->Krightnew; t->V = t->Vnew; t->Pturbright = t->Pturbrightnew; } } } totalVolume = 0.0; for (int m = 1; m <= M; m ++) totalVolume += delta->tube [m]. V; //Melder_casual (U"Ending volume: ", totalVolume * 1000, U" litres."); if (out_w1) *out_w1 = w1.move(); if (out_w2) *out_w2 = w2.move(); if (out_w3) *out_w3 = w3.move(); if (out_p1) *out_p1 = p1.move(); if (out_p2) *out_p2 = p2.move(); if (out_p3) *out_p3 = p3.move(); if (out_v1) *out_v1 = v1.move(); if (out_v2) *out_v2 = v2.move(); if (out_v3) *out_v3 = v3.move(); return result; } catch (MelderError) { Melder_throw (artword, U" & ", speaker, U": articulatory synthesis not performed."); } } /* End of file Artword_Speaker_to_Sound.cpp */ praat-6.0.04/artsynth/Artword_Speaker_to_Sound.h000066400000000000000000000023211261542461700217110ustar00rootroot00000000000000/* Artword_Speaker_to_Sound.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Artword.h" #include "Speaker.h" #include "Sound.h" autoSound Artword_Speaker_to_Sound (Artword artword, Speaker speaker, double samplingFrequency, int oversampling, autoSound *w1, int iw1, autoSound *w2, int iw2, autoSound *w3, int iw3, autoSound *p1, int ip1, autoSound *p2, int ip2, autoSound *p3, int ip3, autoSound *v1, int iv1, autoSound *v2, int iv2, autoSound *v3, int iv3); /* End of file Artword_Speaker_to_Sound.h */ praat-6.0.04/artsynth/Artword_def.h000066400000000000000000000023321261542461700172050ustar00rootroot00000000000000/* Artword_def.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT ArtwordData oo_DEFINE_STRUCT (ArtwordData) oo_INT (numberOfTargets) oo_DOUBLE_VECTOR (targets, numberOfTargets) oo_DOUBLE_VECTOR (times, numberOfTargets) #if oo_DECLARING oo_INT (_iTarget) #endif oo_END_STRUCT (ArtwordData) #undef ooSTRUCT #define ooSTRUCT Artword oo_DEFINE_CLASS (Artword, Daata) oo_DOUBLE (totalTime) oo_STRUCT_SET (ArtwordData, data, kArt_muscle) oo_END_CLASS (Artword) #undef ooSTRUCT /* End of file Artword_def.h */ praat-6.0.04/artsynth/Artword_to_Art.cpp000066400000000000000000000020631261542461700202330ustar00rootroot00000000000000/* Artword_to_Art.cpp * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Artword_to_Art.h" autoArt Artword_to_Art (Artword me, double tim) { try { autoArt thee = Art_create (); Artword_intoArt (me, thee.peek(), tim); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Articulation."); } } /* End of file Artword_to_Art.cpp */ praat-6.0.04/artsynth/Artword_to_Art.h000066400000000000000000000016521261542461700177030ustar00rootroot00000000000000/* Artword_to_Art.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Artword.h" autoArt Artword_to_Art (Artword me, double time); /* Function: linear interpolation between targets. */ /* End of file Artword_to_Art.h */ praat-6.0.04/artsynth/Delta.cpp000066400000000000000000000025711261542461700163360ustar00rootroot00000000000000/* Delta.cpp * * Copyright (C) 1992-2011,2012,2013,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Delta.h" Thing_implement (Delta, Thing, 0); void structDelta :: v_destroy () { NUMvector_free (our tube, 1); Delta_Parent :: v_destroy (); } void Delta_init (Delta me, int numberOfTubes) { Melder_assert (numberOfTubes >= 1); my numberOfTubes = numberOfTubes; my tube = NUMvector (1, numberOfTubes); for (int itube = 1; itube <= numberOfTubes; itube ++) { Delta_Tube t = & my tube [itube]; t -> parallel = 1; } } autoDelta Delta_create (int numberOfTubes) { autoDelta me = Thing_new (Delta); Delta_init (me.peek(), numberOfTubes); return me; } /* End of file Delta.cpp */ praat-6.0.04/artsynth/Delta.h000066400000000000000000000046621261542461700160060ustar00rootroot00000000000000#ifndef _Delta_h_ #define _Delta_h_ /* Delta.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Thing.h" typedef struct structDelta_Tube *Delta_Tube; struct structDelta_Tube { /* Structure: static. */ Delta_Tube left1; /* If null: closed at left edge. */ Delta_Tube left2; /* If not null: two merging streams. */ Delta_Tube right1; /* If null: radiation at right edge. */ Delta_Tube right2; /* If not null: a stream splitting into two. */ long parallel; /* Parallel subdivision. */ /* Controlled by articulation: quasistatic. */ double Dxeq, Dyeq, Dzeq; double mass, k1, k3, Brel, s1, s3, dy; double k1left1, k1left2, k1right1, k1right2; /* Linear coupling factors. */ double k3left1, k3left2, k3right1, k3right2; /* Cubic coupling factors. */ /* Dynamic. */ double Jhalf, Jleft, Jleftnew, Jright, Jrightnew; double Qhalf, Qleft, Qleftnew, Qright, Qrightnew; double Dx, Dxnew, dDxdt, dDxdtnew, Dxhalf; double Dy, Dynew, dDydt, dDydtnew; double Dz; double A, Ahalf, Anew, V, Vnew; double e, ehalf, eleft, eleftnew, eright, erightnew, ehalfold; double p, phalf, pleft, pleftnew, pright, prightnew; double Kleft, Kleftnew, Kright, Krightnew, Pturbright, Pturbrightnew; double B, r, R, DeltaP, v; }; Thing_define (Delta, Thing) { int numberOfTubes; // >= 1 struct structDelta_Tube *tube; // tube [1..numberOfTubes] void v_destroy () override; }; void Delta_init (Delta me, int numberOfTubes); autoDelta Delta_create (int numberOfTubes); /* Function: return a new Delta. Preconditions: numberOfTubes >= 1; Postconditions: result -> numberOfTubes = numberOfTubes; all members of result -> tube [1..numberOfTubes] are zero or null, except 'parallel', which is 1. */ /* End of file Delta.h */ #endif praat-6.0.04/artsynth/Makefile000066400000000000000000000013241261542461700162340ustar00rootroot00000000000000# Makefile of the library "artsynth" # Paul Boersma, 24 August 2013 include ../makefile.defs CPPFLAGS = -I ../num -I ../sys -I ../fon -I ../stat OBJECTS = Speaker.o Articulation.o Artword.o \ Art_Speaker.o Art_Speaker_to_VocalTract.o Artword_Speaker.o Artword_Speaker_Sound.o \ Artword_Speaker_to_Sound.o Artword_to_Art.o \ Delta.o Speaker_to_Delta.o Art_Speaker_Delta.o \ ArtwordEditor.o praat_Artsynth.o manual_Artsynth.o .PHONY: all clean all: libartsynth.a clean: $(RM) $(OBJECTS) $(RM) libartsynth.a libartsynth.a: $(OBJECTS) touch libartsynth.a rm libartsynth.a $(AR) cq libartsynth.a $(OBJECTS) $(RANLIB) libartsynth.a $(OBJECTS): *.h ../num/NUM.h ../sys/*.h ../fon/*.h ../stat/*.h praat-6.0.04/artsynth/Speaker.cpp000066400000000000000000000107541261542461700167010ustar00rootroot00000000000000/* Speaker.cpp * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Speaker.h" #include "oo_DESTROY.h" #include "Speaker_def.h" #include "oo_COPY.h" #include "Speaker_def.h" #include "oo_EQUAL.h" #include "Speaker_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Speaker_def.h" #include "oo_WRITE_TEXT.h" #include "Speaker_def.h" #include "oo_READ_TEXT.h" #include "Speaker_def.h" #include "oo_WRITE_BINARY.h" #include "Speaker_def.h" #include "oo_READ_BINARY.h" #include "Speaker_def.h" #include "oo_DESCRIPTION.h" #include "Speaker_def.h" Thing_implement (Speaker, Daata, 0); autoSpeaker Speaker_create (char32 *kindOfSpeaker, int numberOfVocalCordMasses) { autoSpeaker me = Thing_new (Speaker); /* Supralaryngeal dimensions are taken from P. Mermelstein (1973): */ /* "Articulatory model for the study of speech production", */ /* Journal of the Acoustical Society of America 53,1070 - 1082. */ /* That was a male speaker, so we need scaling for other speakers: */ double scaling; if (str32equ (kindOfSpeaker, U"Male")) my relativeSize = 1.1; else if (str32equ (kindOfSpeaker, U"Child")) my relativeSize = 0.7; else my relativeSize = 1.0; scaling = my relativeSize; /* Laryngeal system. Data for male speaker from Ishizaka and Flanagan. */ if (str32equ (kindOfSpeaker, U"Female")) { my lowerCord.thickness = 1.4e-3; // dx, in metres my upperCord.thickness = 0.7e-3; my cord.length = 10e-3; my lowerCord.mass = 0.02e-3; // kilograms my upperCord.mass = 0.01e-3; my lowerCord.k1 = 10; // Newtons per metre my upperCord.k1 = 4; } else if (str32equ (kindOfSpeaker, U"Male")) { my lowerCord.thickness = 2.0e-3; // dx, in metres my upperCord.thickness = 1.0e-3; my cord.length = 18e-3; my lowerCord.mass = 0.1e-3; // kilograms my upperCord.mass = 0.05e-3; my lowerCord.k1 = 12; // Newtons per metre my upperCord.k1 = 4; } else /* "Child" */ { my lowerCord.thickness = 0.7e-3; // dx, in metres my upperCord.thickness = 0.3e-3; my cord.length = 6e-3; my lowerCord.mass = 0.003e-3; // kilograms my upperCord.mass = 0.002e-3; my lowerCord.k1 = 6; // Newtons per metre my upperCord.k1 = 2; } my cord.numberOfMasses = numberOfVocalCordMasses; if (numberOfVocalCordMasses == 1) { my lowerCord.thickness += my upperCord.thickness; my lowerCord.mass += my upperCord.mass; my lowerCord.k1 += my upperCord.k1; } /* Supralaryngeal system. Data from Mermelstein. */ my velum.x = -0.031 * scaling; my velum.y = 0.023 * scaling; my velum.a = atan2 (my velum.y, my velum.x); my palate.radius = sqrt (my velum.x * my velum.x + my velum.y * my velum.y); my tip.length = 0.034 * scaling; my neutralBodyDistance = 0.086 * scaling; my alveoli.x = 0.024 * scaling; my alveoli.y = 0.0302 * scaling; my alveoli.a = atan2 (my alveoli.y, my alveoli.x); my teethCavity.dx1 = -0.009 * scaling; my teethCavity.dx2 = -0.004 * scaling; my teethCavity.dy = -0.011 * scaling; my lowerTeeth.a = -0.30; // radians my lowerTeeth.r = 0.113 * scaling; // metres my upperTeeth.x = 0.036 * scaling; my upperTeeth.y = 0.026 * scaling; my lowerLip.dx = 0.010 * scaling; my lowerLip.dy = -0.004 * scaling; my upperLip.dx = 0.010 * scaling; my upperLip.dy = 0.004 * scaling; my nose.Dx = 0.007 * scaling; my nose.Dz = 0.014 * scaling; my nose.weq [0] = 0.018 * scaling; my nose.weq [1] = 0.016 * scaling; my nose.weq [2] = 0.014 * scaling; my nose.weq [3] = 0.020 * scaling; my nose.weq [4] = 0.023 * scaling; my nose.weq [5] = 0.020 * scaling; my nose.weq [6] = 0.035 * scaling; my nose.weq [7] = 0.035 * scaling; my nose.weq [8] = 0.030 * scaling; my nose.weq [9] = 0.022 * scaling; my nose.weq [10] = 0.016 * scaling; my nose.weq [11] = 0.010 * scaling; my nose.weq [12] = 0.012 * scaling; my nose.weq [13] = 0.013 * scaling; return me; } /* End of file Speaker.cpp */ praat-6.0.04/artsynth/Speaker.h000066400000000000000000000022271261542461700163420ustar00rootroot00000000000000#ifndef _Speaker_h_ #define _Speaker_h_ /* Speaker.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Data.h" #include "Speaker_def.h" oo_CLASS_CREATE (Speaker, Daata); autoSpeaker Speaker_create (char32 *kindOfSpeaker, int numberOfVocalCordMasses); /* Preconditions: */ /* 1 <= numberOfVocalCordMasses <= 2; */ /* Failures: */ /* Kind of speaker is not one of "Female", "Male", or "Child". */ /* End of file Speaker.h */ #endif praat-6.0.04/artsynth/Speaker_def.h000066400000000000000000000070241261542461700171600ustar00rootroot00000000000000/* Speaker_def.h * * Copyright (C) 1992-2011 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT Speaker_CordDimensions oo_DEFINE_STRUCT (Speaker_CordDimensions) oo_INT (numberOfMasses) oo_DOUBLE (length) oo_END_STRUCT (Speaker_CordDimensions) #undef ooSTRUCT #define ooSTRUCT Speaker_CordSpring oo_DEFINE_STRUCT (Speaker_CordSpring) oo_DOUBLE (thickness) oo_DOUBLE (mass) oo_DOUBLE (k1) oo_END_STRUCT (Speaker_CordSpring) #undef ooSTRUCT #define ooSTRUCT Speaker_GlottalShunt oo_DEFINE_STRUCT (Speaker_GlottalShunt) oo_DOUBLE (Dx) oo_DOUBLE (Dy) oo_DOUBLE (Dz) oo_END_STRUCT (Speaker_GlottalShunt) #undef ooSTRUCT #define ooSTRUCT Speaker_Velum oo_DEFINE_STRUCT (Speaker_Velum) /* V */ oo_DOUBLE (x) oo_DOUBLE (y) oo_DOUBLE (a) oo_END_STRUCT (Speaker_Velum) #undef ooSTRUCT #define ooSTRUCT Speaker_Palate oo_DEFINE_STRUCT (Speaker_Palate) /* OM */ oo_DOUBLE (radius) oo_END_STRUCT (Speaker_Palate) #undef ooSTRUCT #define ooSTRUCT Speaker_Tip oo_DEFINE_STRUCT (Speaker_Tip) oo_DOUBLE (length) oo_END_STRUCT (Speaker_Tip) #undef ooSTRUCT #define ooSTRUCT Speaker_Alveoli oo_DEFINE_STRUCT (Speaker_Alveoli) oo_DOUBLE (x) oo_DOUBLE (y) oo_DOUBLE (a) oo_END_STRUCT (Speaker_Alveoli) #undef ooSTRUCT #define ooSTRUCT Speaker_TeethCavity oo_DEFINE_STRUCT (Speaker_TeethCavity) oo_DOUBLE (dx1) oo_DOUBLE (dx2) oo_DOUBLE (dy) oo_END_STRUCT (Speaker_TeethCavity) #undef ooSTRUCT #define ooSTRUCT Speaker_LowerTeeth oo_DEFINE_STRUCT (Speaker_LowerTeeth) /* rest position of J */ oo_DOUBLE (r) oo_DOUBLE (a) oo_END_STRUCT (Speaker_LowerTeeth) #undef ooSTRUCT #define ooSTRUCT Speaker_UpperTeeth oo_DEFINE_STRUCT (Speaker_UpperTeeth) /* U */ oo_DOUBLE (x) oo_DOUBLE (y) oo_END_STRUCT (Speaker_UpperTeeth) #undef ooSTRUCT #define ooSTRUCT Speaker_Lip oo_DEFINE_STRUCT (Speaker_Lip) oo_DOUBLE (dx) oo_DOUBLE (dy) oo_END_STRUCT (Speaker_Lip) #undef ooSTRUCT #define ooSTRUCT Speaker_Nose oo_DEFINE_STRUCT (Speaker_Nose) oo_DOUBLE (Dx) oo_DOUBLE (Dz) oo_DOUBLE_ARRAY (weq, 14, 14) oo_END_STRUCT (Speaker_Nose) #undef ooSTRUCT #define ooSTRUCT Speaker oo_DEFINE_CLASS (Speaker, Daata) oo_DOUBLE (relativeSize) /* Different for female, male, child. */ /* In the larynx. */ oo_STRUCT (Speaker_CordDimensions, cord) oo_STRUCT (Speaker_CordSpring, lowerCord) oo_STRUCT (Speaker_CordSpring, upperCord) oo_STRUCT (Speaker_GlottalShunt, shunt) /* Above the larynx. */ oo_STRUCT (Speaker_Velum, velum) oo_STRUCT (Speaker_Palate, palate) oo_STRUCT (Speaker_Tip, tip) oo_DOUBLE (neutralBodyDistance) oo_STRUCT (Speaker_Alveoli, alveoli) oo_STRUCT (Speaker_TeethCavity, teethCavity) oo_STRUCT (Speaker_LowerTeeth, lowerTeeth) oo_STRUCT (Speaker_UpperTeeth, upperTeeth) oo_STRUCT (Speaker_Lip, lowerLip) oo_STRUCT (Speaker_Lip, upperLip) /* In the nasal cavity. */ oo_STRUCT (Speaker_Nose, nose) oo_END_CLASS (Speaker) #undef ooSTRUCT /* End of file Speaker_def.h */ praat-6.0.04/artsynth/Speaker_to_Delta.cpp000066400000000000000000000323561261542461700205160ustar00rootroot00000000000000/* Speaker_to_Delta.cpp * * Copyright (C) 1992-2011 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Art_Speaker.h" #include "Speaker_to_Delta.h" #define SMOOTH_LUNGS true #define FIRST_TUBE 7 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]; int itube; autoDelta thee = Delta_create (89); Melder_assert (my cord.numberOfMasses == 1 || my cord.numberOfMasses == 2 || my cord.numberOfMasses == 10); /* Lungs: tubes 1..23. */ for (itube = 1; itube <= 23; itube ++) { Delta_Tube t = thy tube + itube; t -> Dx = t -> Dxeq = 10 * f; t -> Dy = t -> Dyeq = 100 * f; t -> Dz = t -> Dzeq = 230 * f; t -> mass = 10 * my relativeSize * t -> Dx * t -> Dz; /* 80 * f; 35 * Dx * Dz */ t -> k1 = 200; /* 90000 * Dx * Dz; Newtons per metre */ t -> k3 = 0.0; t -> Brel = 0.8; t -> parallel = 1000; } /* Bronchi: tubes 24..29. */ for (itube = 24; itube <= 29; itube ++) { Delta_Tube t = thy tube + itube; t -> Dx = t -> Dxeq = 10 * f; t -> Dy = t -> Dyeq = 15 * f; t -> Dz = t -> Dzeq = 30 * f; t -> mass = 10 * f; t -> k1 = 40; /* 125000 * Dx * Dz; Newtons per metre */ t -> k3 = 0.0; t -> Brel = 0.8; } /* Trachea: tubes 30..35; four of these may be replaced by conus elasticus (see below). */ for (itube = 30; itube <= 35; itube ++) { Delta_Tube t = thy tube + itube; t -> Dx = t -> Dxeq = 10 * f; t -> Dy = t -> Dyeq = 15 * f; t -> Dz = t -> Dzeq = 16 * f; t -> mass = 5 * f; t -> k1 = 160; /* 100000 * Dx * Dz; Newtons per metre */ t -> k3 = 0.0; t -> Brel = 0.8; } if (SMOOTH_LUNGS) { struct { int itube; double Dy, Dz, parallel; } data [] = { { 7, 120, 240, 5000 }, { 8, 120, 240, 5000 }, { 9, 120, 240, 5000 }, { 10, 120, 240, 5000 }, { 11, 120, 240, 5000 }, { 12, 120, 240, 5000 }, { 13, 120, 240, 2500 }, { 14, 120, 240, 1250 }, { 15, 120, 240, 640 }, { 16, 120, 240, 320 }, { 17, 120, 240, 160 }, { 18, 120, 140, 80 }, { 19, 70, 70, 40 }, { 20, 35, 35, 20 }, { 21, 18, 18, 10 }, { 22, 12, 12, 5 }, { 23, 12, 12, 3 }, { 24, 18, 9, 2 }, { 25, 18, 19, 2 }, { 0 } }; int i; for (i = 0; data [i]. itube; i ++) { Delta_Tube t = thy tube + data [i]. itube; t -> Dy = t -> Dyeq = data [i]. Dy * f; t -> Dz = t -> Dzeq = data [i]. Dz * f; t -> parallel = data [i]. parallel; } for (itube = 26; itube <= 35; itube ++) { Delta_Tube t = thy tube + itube; t -> Dy = t -> Dyeq = 11 * f; t -> Dz = t -> Dzeq = 14 * f; t -> parallel = 1; } for (itube = FIRST_TUBE; itube <= 18; itube ++) { Delta_Tube t = thy tube + itube; t -> Dx = t -> Dxeq = 10 * f; t -> mass = 10 * my relativeSize * t -> Dx * t -> Dz; /* 10 mm */ t -> k1 = 1e5 * t -> Dx * t -> Dz; /* elastic tissue: 1 mbar/mm */ t -> k3 = 0.0; t -> Brel = 1; } for (itube = 19; itube <= 35; itube ++) { Delta_Tube t = thy tube + itube; t -> Dx = t -> Dxeq = 10 * f; t -> mass = 3 * my relativeSize * t -> Dx * t -> Dz; /* 3 mm */ t -> k1 = 10e5 * t -> Dx * t -> Dz; /* cartilage: 10 mbar/mm */ t -> k3 = 0.0; t -> Brel = 1; } } /* Glottis: tubes 36 and 37; the last one may be disconnected (see below). */ { Delta_Tube t = thy tube + 36; t -> Dx = t -> Dxeq = my lowerCord.thickness; t -> Dy = t -> Dyeq = 0.0; t -> Dz = t -> Dzeq = my cord.length; t -> mass = my lowerCord.mass; t -> k1 = my lowerCord.k1; t -> k3 = t -> k1 * (20 / t -> Dz) * (20 / t -> Dz); t -> Brel = 0.2; } /* * Fill in the values for the upper part of the glottis (tube 37) only if there is no one-mass model. */ if (my cord.numberOfMasses >= 2) { Delta_Tube t = thy tube + 37; t -> Dx = t -> Dxeq = my upperCord.thickness; t -> Dy = t -> Dyeq = 0.0; t -> Dz = t -> Dzeq = my cord.length; t -> mass = my upperCord.mass; t -> k1 = my upperCord.k1; t -> k3 = t -> k1 * (20 / t -> Dz) * (20 / t -> Dz); t -> Brel = 0.2; /* Couple spring with lower cord. */ t -> k1left1 = thy tube [36]. k1right1 = 1.0; } /* * Fill in the values for the conus elasticus (tubes 79..86) only if we want to model it. */ if (my cord.numberOfMasses == 10) { thy tube [79]. Dx = thy tube [79]. Dxeq = 8 * f; thy tube [80]. Dx = thy tube [80]. Dxeq = 7 * f; thy tube [81]. Dx = thy tube [81]. Dxeq = 6 * f; thy tube [82]. Dx = thy tube [82]. Dxeq = 5 * f; thy tube [83]. Dx = thy tube [83]. Dxeq = 4 * f; thy tube [84]. Dx = thy tube [84]. Dxeq = 0.75 * 4 * f + 0.25 * my lowerCord.thickness; thy tube [85]. Dx = thy tube [85]. Dxeq = 0.50 * 4 * f + 0.50 * my lowerCord.thickness; thy tube [86]. Dx = thy tube [86]. Dxeq = 0.25 * 4 * f + 0.75 * my lowerCord.thickness; thy tube [79]. Dy = thy tube [79]. Dyeq = 11 * f; thy tube [80]. Dy = thy tube [80]. Dyeq = 7 * f; thy tube [81]. Dy = thy tube [81]. Dyeq = 4 * f; thy tube [82]. Dy = thy tube [82]. Dyeq = 2 * f; thy tube [83]. Dy = thy tube [83]. Dyeq = 1 * f; thy tube [84]. Dy = thy tube [84]. Dyeq = 0.75 * f; thy tube [85]. Dy = thy tube [85]. Dyeq = 0.50 * f; thy tube [86]. Dy = thy tube [86]. Dyeq = 0.25 * f; thy tube [79]. Dz = thy tube [79]. Dzeq = 16 * f; thy tube [80]. Dz = thy tube [80]. Dzeq = 16 * f; thy tube [81]. Dz = thy tube [81]. Dzeq = 16 * f; thy tube [82]. Dz = thy tube [82]. Dzeq = 16 * f; thy tube [83]. Dz = thy tube [83]. Dzeq = 16 * f; thy tube [84]. Dz = thy tube [84]. Dzeq = 0.75 * 16 * f + 0.25 * my cord.length; thy tube [85]. Dz = thy tube [85]. Dzeq = 0.50 * 16 * f + 0.50 * my cord.length; thy tube [86]. Dz = thy tube [86]. Dzeq = 0.25 * 16 * f + 0.75 * my cord.length; thy tube [79]. k1 = 160; thy tube [80]. k1 = 160; thy tube [81]. k1 = 160; thy tube [82]. k1 = 160; thy tube [83]. k1 = 160; thy tube [84]. k1 = 0.75 * 160 * f + 0.25 * my lowerCord.k1; thy tube [85]. k1 = 0.50 * 160 * f + 0.50 * my lowerCord.k1; thy tube [86]. k1 = 0.25 * 160 * f + 0.75 * my lowerCord.k1; thy tube [79]. Brel = 0.7; thy tube [80]. Brel = 0.6; thy tube [81]. Brel = 0.5; thy tube [82]. Brel = 0.4; thy tube [83]. Brel = 0.3; thy tube [84]. Brel = 0.2; thy tube [85]. Brel = 0.2; thy tube [86]. Brel = 0.2; for (itube = 79; itube <= 86; itube ++) { Delta_Tube t = thy tube + itube; t -> mass = t -> Dx * t -> Dz / (30 * f); t -> k3 = t -> k1 * (20 / t -> Dz) * (20 / t -> Dz); t -> k1left1 = t -> k1right1 = 1.0; } thy tube [79]. k1left1 = 0.0; thy tube [36]. k1left1 = 1.0; /* The essence: couple spring with lower vocal cords. */ } /* * Fill in the values of the glottal shunt only if we want to model it. */ if (my shunt.Dx != 0.0) { for (itube = 87; itube <= 89; itube ++) { Delta_Tube t = thy tube + itube; t -> Dx = t -> Dxeq = my shunt.Dx; t -> Dy = t -> Dyeq = my shunt.Dy; t -> Dz = t -> Dzeq = my shunt.Dz; t -> mass = 3 * my upperCord.mass; /* Heavy... */ t -> k1 = 3 * my upperCord.k1; /* ...and stiff... */ t -> k3 = t -> k1 * (20 / t -> Dz) * (20 / t -> Dz); t -> Brel = 3.0; /* ...and inelastic, so that the walls will not vibrate. */ } } /* Vocal tract from neutral articulation. */ { autoArt art = Art_create (); Art_Speaker_meshVocalTract (art.peek(), me, xi, yi, xe, ye, xmm, ymm, closed); } /* Pharynx and mouth: tubes 38..64. */ for (itube = 38; itube <= 64; itube ++) { Delta_Tube t = thy tube + itube; int i = itube - 37; t -> Dx = 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; t -> Dy = t -> Dyeq; t -> Dz = t -> Dzeq = 0.015; t -> mass = 0.006; t -> k1 = 30; t -> k3 = 0.0; t -> Brel = 1.0; } /* For tongue-tip vibration [r]: thy tube [60]. Brel = 0.1; thy tube [60]. k1 = 3; */ /* Nose: tubes 65..78. */ for (itube = 65; itube <= 78; itube ++) { Delta_Tube t = thy tube + itube; t -> Dx = t -> Dxeq = my nose.Dx; t -> Dy = t -> Dyeq = my nose.weq [itube - 65]; t -> Dz = t -> Dzeq = my nose.Dz; t -> mass = 0.006; t -> k1 = 100; t -> k3 = 0.0; t -> Brel = 1.0; } thy tube [65]. Dy = thy tube [65]. Dyeq = 0.0; /* Override: nasopharyngeal port closed. */ /* The default structure: * every tube is connected on the left to the previous tube (index one lower). * This corresponds to a two-mass model of the vocal cords without shunt. */ for (itube = SMOOTH_LUNGS ? FIRST_TUBE : 1; itube <= thy numberOfTubes; itube ++) { Delta_Tube t = thy tube + itube; t -> s1 = 5e6 * t -> Dx * t -> Dz; t -> s3 = t -> s1 / (0.9e-3 * 0.9e-3); t -> dy = 1e-5; t -> left1 = t - 1; /* Connect to the previous tube on the left. */ t -> right1 = t + 1; /* Connect to the next tube on the right. */ } /***** Connections: boundaries and interfaces. *****/ /* The leftmost boundary: the diaphragm (tube 1). * Disconnect on the left. */ thy tube [SMOOTH_LUNGS ? FIRST_TUBE : 1]. left1 = NULL; /* Closed at diaphragm. */ /* Optional one-mass model of the vocal cords. * Short-circuit over tube 37 (upper glottis). */ if (my cord.numberOfMasses == 1) { /* Connect the right side of tube 36 to the left side of tube 38. */ thy tube [36]. right1 = thy tube + 38; thy tube [38]. left1 = thy tube + 36; /* Disconnect tube 37 on both sides. */ thy tube [37]. left1 = thy tube [37]. right1 = NULL; } /* Optionally couple vocal cords with conus elasticus. * Replace tubes 32..35 (upper trachea) by tubes 79..86 (conus elasticus). */ if (my cord.numberOfMasses == 10) { /* Connect the right side of tube 31 to the left side of tube 79. */ thy tube [31]. right1 = thy tube + 79; thy tube [79]. left1 = thy tube + 31; /* Connect the right side of tube 86 to the left side of tube 36. */ thy tube [86]. right1 = thy tube + 36; thy tube [36]. left1 = thy tube + 86; /* Disconnect tubes 32..35 on both sides. */ thy tube [32]. left1 = thy tube [32]. right1 = NULL; thy tube [33]. left1 = thy tube [33]. right1 = NULL; thy tube [34]. left1 = thy tube [34]. right1 = NULL; thy tube [35]. left1 = thy tube [35]. right1 = NULL; } else { /* Disconnect tubes 79..86 on both sides. */ for (itube = 79; itube <= 86; itube ++) thy tube [itube]. left1 = thy tube [itube]. right1 = NULL; } /* Optionally add a shunt parallel to the glottis. * Create a side branch from tube 34/35 (or 85/86) to tube 38/39 with tubes 87..89. */ if (my shunt.Dx != 0.0) { int topOfTrachea = my cord.numberOfMasses == 10 ? 86 : 35; /* Create a three-way interface below the shunt. * Connect lowest shunt tube (87) with top of trachea (34/35 or 85/86). */ thy tube [topOfTrachea - 1]. right2 = thy tube + 87; /* Trachea to shunt. */ thy tube [87]. left1 = thy tube + topOfTrachea - 1; /* Shunt to trachea. */ thy tube [87]. Dxeq = thy tube [topOfTrachea - 1]. Dxeq = thy tube [topOfTrachea]. Dxeq; /* Equal length. */ thy tube [87]. Dx = thy tube [topOfTrachea - 1]. Dx = thy tube [topOfTrachea]. Dx; /* Create a three-way interface above the shunt. * Connect highest shunt tube (89) with bottom of pharynx (38/39). */ thy tube [89]. right1 = thy tube + 39; /* Shunt to pharynx. */ thy tube [39]. left2 = thy tube + 89; /* Pharynx to shunt. */ thy tube [89]. Dxeq = thy tube [39]. Dxeq = thy tube [38]. Dxeq; /* All three of equal length. */ thy tube [89]. Dx = thy tube [39]. Dx = thy tube [38]. Dx; } else { /* Disconnect tubes 87..89 on both sides. */ for (itube = 87; itube <= 89; itube ++) thy tube [itube]. left1 = thy tube [itube]. right1 = NULL; } /* Create a three-way interface at the nasopharyngeal port. * Connect tubes 50 (pharynx), 51 (mouth), and 65 (nose). */ thy tube [50]. right2 = thy tube + 65; /* Pharynx to nose. */ thy tube [65]. left1 = thy tube + 50; /* Nose to pharynx. */ thy tube [65]. Dxeq = thy tube [51]. Dxeq = thy tube [50]. Dxeq; /* All three must be of equal length. */ thy tube [65]. Dx = thy tube [51]. Dx = thy tube [50]. Dx; /* The rightmost boundaries: the lips (tube 64) and the nostrils (tube 78). * Disconnect on the right. */ thy tube [64]. right1 = NULL; /* Radiation at the lips. */ thy tube [78]. right1 = NULL; /* Radiation at the nostrils. */ for (itube = 1; itube <= thy numberOfTubes; itube ++) { Delta_Tube t = thy tube + itube; Melder_assert (! t->left1 || t->left1->right1 == t || t->left1->right2 == t); Melder_assert (! t->left2 || t->left2->right1 == t); Melder_assert (! t->right1 || t->right1->left1 == t || t->right1->left2 == t); Melder_assert (! t->right2 || t->right2->left1 == t); } return thee; } /* End of file Speaker_to_Delta.cpp */ praat-6.0.04/artsynth/Speaker_to_Delta.h000066400000000000000000000015711261542461700201560ustar00rootroot00000000000000/* Speaker_to_Delta.h * * Copyright (C) 1992-2011 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Speaker.h" #include "Delta.h" autoDelta Speaker_to_Delta (Speaker me); /* End of file Speaker_to_Delta.h */ praat-6.0.04/artsynth/manual_Artsynth.cpp000066400000000000000000000247651261542461700204670ustar00rootroot00000000000000/* manual_Artsynth.cpp * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ManPagesM.h" void manual_Artsynth_init (ManPages me); void manual_Artsynth_init (ManPages me) { MAN_BEGIN (U"Articulatory synthesis", U"ppgb", 201101028) INTRO (U"This is a description of the articulatory synthesis package in Praat. " "For a detailed description of the physics and mathematics behind the model, " "see @@Boersma (1998)@, chapters 2 and 3. " "For examples of how to synthesize utterances, consult http://www.fon.hum.uva.nl/paul/diss/ch5/.") ENTRY (U"How to start (after reading the @Intro)") NORMAL (U"We are going to have the synthesizer say [əpə]. We need a @Speaker and an @Artword object.") NORMAL (U"1. Create a speaker with @@Create Speaker...@ from the @@New menu@.") NORMAL (U"2. Create an articulation word of 0.5 seconds with @@Create Artword...@.") NORMAL (U"3. Edit the Artword by selecting it and clicking ##View & Edit#.") NORMAL (U"4. To set the glottis to a position suitable for phonation, use the ArtwordEditor to " "set the %Interarytenoid activity to 0.5 throughout the utterance. You set two targets: " "0.5 at a time of 0 seconds, and 0.5 at a time of 0.5 seconds.") NORMAL (U"5. To prevent air escaping from the nose, close the nasopharyngeal port " "by setting the %LevatorPalatini activity to 1.0 throughout the utterance.") NORMAL (U"6. To generate the lung pressure needed for phonation, you set the %Lungs activity at 0 seconds to 0.2, " "and at 0.1 seconds to 0.") NORMAL (U"7. To force a jaw movement that closes the lips, set the %Masseter activity at 0.25 seconds to 0.7, " "and the %OrbicularisOris activity at 0.25 seconds to 0.2.") NORMAL (U"8. Select the Speaker and the Artword and click #Movie; " "you will see a closing-and-opening gesture of the mouth.") NORMAL (U"9. Select the Speaker and the Artword and click ##To Sound...# " "(see @@Artword & Speaker: To Sound...@).") NORMAL (U"10. Just click #OK; the synthesis starts.") NORMAL (U"11. If you are sitting at a 1997 computer, this will last for 5 minutes or so; at a 2010 computer, 6 seconds. " "If this is too slow for you, click #Interrupt. " "Otherwise, you can watch the vibrating vocal cords " "and the changing vocal-tract shape.") NORMAL (U"12. You can play, view, and analyse the resulting @Sound as you would any other. " "You can see and hear a sound movie if you select the Speaker, " "the Artword, and the Sound, and click #Play.") MAN_END MAN_BEGIN (U"Artword", U"ppgb", 20030316) INTRO (U"One of the @@types of objects@ in Praat. See @@Articulatory synthesis@.") NORMAL (U"An object of class Artword object represents the activities of several speech muscles as functions of time.") ENTRY (U"Artword commands") LIST_ITEM (U"• @@Create Artword...@: creates an Artword with relaxed muscles") LIST_ITEM (U"• @@Artword & Speaker: To Sound...@: articulatory synthesis") MAN_END MAN_BEGIN (U"Artword & Speaker: To Sound...", U"ppgb", 20040331) INTRO (U"A command to synthesize a @Sound object from the selected @Speaker and the selected @Artword.") NORMAL (U"This is the command that performs the actual articulatory synthesis. " "See @@Articulatory synthesis@.") ENTRY (U"Settings") TAG (U"##Sampling frequency (Hz)") DEFINITION (U"the number of times per second that the equilibrium widths and lengths and the tensions of the muscles " "are recomputed from the Artword. This will also be the sampling frequency of the resulting sound and " "of the optional resulting tube widths, air pressures, and air velocities. The standard value is 22050 Hz.") TAG (U"##Oversampling") DEFINITION (U"the number of times that the aerodynamic quantities and the state of the tube walls " "will be recomputed during each sample period. The standard value is 25.") TAG (U"##Width 1#, ##Width 2#, ##Width 3#") DEFINITION (U"the numbers (see below) of the tubes whose widths you want to monitor. " "E.g., if ##Width 1# is 36, the synthesizer will create a Sound object named $$width36$, " "which contains the width of tube 36 (the lower glottis) as a function of time, expressed in metres. " "To prevent the creation of a $$width$ object, specify $$0$ (the standard value).") TAG (U"##Pressure 1#, ##Pressure 2#, ##Pressure 3#") DEFINITION (U"the numbers (see below) of the tubes whose air pressures you want to monitor. " "E.g., if ##Pressure 3# is 37, the synthesizer will create a Sound object named $$pressure37$, " "which contains the air pressure of tube 37 (the upper glottis) as a function of time, expressed in Pascal. " "To prevent the creation of a $$pressure$ object, specify $$0$ (the standard value).") TAG (U"##Velocity 1#, ##Velocity 2#, ##Velocity 3") DEFINITION (U"the numbers (see below) of the tubes whose air velocities you want to monitor. " "E.g., if ##Velocity 1# is 60, the synthesizer will create a Sound object named $velocity60, " "which contains the air velocity of tube 60 (in the mouth) as a function of time, expressed in metres per second. " "To prevent the creation of a $velocity object, specify $0 (the standard value).") ENTRY (U"Stability") NORMAL (U"The internal sampling frequency for the aerodynamics is the specified ##Sampling frequency#, " "multiplied by the specified #Oversampling. With the standard settings, this is 22050 times 25 = 550750 Hz.") NORMAL (U"To ensure the stability of the synthesis, this internal sampling frequency should not be less than the " "velocity of sound (353 m/s) divided by the length of the shortest tube. For the standard #Female, " "#Male, and #Child speakers, the shortest tube is the upper glottis, which has a length " "of 0.7, 1.0, and 0.3 millimetres, respectively. The minimum internal sampling frequencies, therefore, " "are 504286, 353000, and 1176667 hertz, respectively.") ENTRY (U"Time resolution") NORMAL (U"To capture the microscopic pressure changes in the glottis, you will want maximum time resolution. " "For a female speaker, you could set ##Sampling frequency# to 550750 Hz, and #Oversampling to 1.") ENTRY (U"Tube numbers") NORMAL (U"Here are the tube numbers that you can use for the #Width, #Pressure, and #Velocity settings:") LIST_ITEM (U"1..23: lungs (from bottom to top)") LIST_ITEM (U"24..29: bronchi (from bottom to top)") LIST_ITEM (U"30..35: trachea (from bottom to top)") LIST_ITEM (U"36: lower glottis") LIST_ITEM (U"37: upper glottis (not for a one-mass model)") LIST_ITEM (U"38..49: pharynx (from bottom to top)") LIST_ITEM (U"50..51: nasopharyngeal branching") LIST_ITEM (U"52..64: mouth (from back to front)") LIST_ITEM (U"65..78: nose (from back to front)") LIST_ITEM (U"79..86: conus elasticus (only for a 10-mass model)") LIST_ITEM (U"87..89: glottal shunt between the arytenoids (from bottom to top)") NORMAL (U"Some structural properties:") LIST_ITEM (U"• Tube 1 is closed at the bottom.") LIST_ITEM (U"• Tubes 64 (lips) and 78 (nostrils) radiate into the air.") LIST_ITEM (U"• The nasopharyngeal branch is at tubes 50, 51, and 65. They are constrained to have equal lengths.") LIST_ITEM (U"• For a one-mass model of the vocal cords, tube 36 is connected to 38.") LIST_ITEM (U"• For a 10-mass model, tubes 32..35 are replaced with 79..86, so that " "tube 31 is connected to 79, and 86 is connected to 36.") LIST_ITEM (U"• A glottal shunt will be implemented if the speaker's $$shunt.Dx$ attribute is not zero. " "A branch is then made from tubes 34 and 35 (or 85 and 86) to 87, " "and from tube 89 to 38 and 39.") MAN_END MAN_BEGIN (U"Create Artword...", U"ppgb", 20101212) INTRO (U"A command to create an @Artword object with all muscle activities set to zero. " "See @@Articulatory synthesis@.") ENTRY (U"Settings") TAG (U"##Name") DEFINITION (U"the name that you give to the created object. The standard name is $$hallo$, " "but you should give it a more sensible name, possibly something that represents the utterance " "that it is supposed to generate.") TAG (U"##Duration (seconds)") DEFINITION (U"the duration of the resulting Artword. Should be as long as the utterance that " "you want to generate with it. The standard value is 1 second.") MAN_END MAN_BEGIN (U"Create Speaker...", U"ppgb", 20101212) INTRO (U"A command to create a @Speaker object. See @@Articulatory synthesis@.") ENTRY (U"Settings") TAG (U"##Name") DEFINITION (U"the name that you give to the created object. The standard name is \"speaker\", " "but if you work with multiple Speaker objects, give them sensible names to reduce confusion.") TAG (U"##Kind of speaker") DEFINITION (U"Choose from #Female, #Male, or #Child. The only difference is a relative size.") TAG (U"##Number of tubes in glottis") DEFINITION (U"Choose from #1, #2, or #10. See @@Artword & Speaker: To Sound...@ for details.") MAN_END MAN_BEGIN (U"Create Vocal Tract from phone...", U"ppgb", 19960908) INTRO (U"A way to create a @VocalTract object.") ENTRY (U"Purpose") NORMAL (U"to translate a phone symbol like [a], [u], etc., into a vocal-tract area function.") ENTRY (U"Behaviour") NORMAL (U"The resulting VocalTract will appear in the list of objects, " "with the same name as the phone.") ENTRY (U"Algorithm") NORMAL (U"The area function of the resulting VocalTract is taken from the Russian speaker from @@Fant (1960)@.") MAN_END MAN_BEGIN (U"Speaker", U"ppgb", 19980201) INTRO (U"One of the @@types of objects@ in Praat. See @@Articulatory synthesis@.") ENTRY (U"Speaker commands") LIST_ITEM (U"• @@Create Speaker...") LIST_ITEM (U"• @@Artword & Speaker: To Sound...@: articulatory synthesis") MAN_END MAN_BEGIN (U"VocalTract", U"ppgb", 20030316) INTRO (U"One of the @@types of objects@ in Praat.") NORMAL (U"A VocalTract object represents the area function of the vocal tract, expressed in m^2, " "running from the glottis to the lips.") MAN_END MAN_BEGIN (U"VocalTract: Formula...", U"ppgb", 20021206) INTRO (U"A command for changing the data in all selected @VocalTract objects.") NORMAL (U"See the @Formulas tutorial for examples and explanations.") MAN_END } /* End of file manual_Artsynth.cpp */ praat-6.0.04/artsynth/praat_Artsynth.cpp000066400000000000000000000326171261542461700203140ustar00rootroot00000000000000/* praat_Artsynth.cpp * * Copyright (C) 1992-2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Art_Speaker.h" #include "Artword_Speaker.h" #include "Art_Speaker_to_VocalTract.h" #include "Artword_Speaker_Sound.h" #include "Artword_Speaker_to_Sound.h" #include "Artword_to_Art.h" #include "ArtwordEditor.h" #include "VocalTract_to_Spectrum.h" #include "praat.h" extern "C" Graphics Movie_create (const char32 *title, int width, int height); #undef iam #define iam iam_LOOP /***** ART *****/ FORM (Art_create, U"Create a default Articulation", U"Articulatory synthesis") { WORD (U"Name", U"articulation") OK2 DO autoArt me = Art_create (); praat_new (me.move(), GET_STRING (U"Name")); END2 } FORM (Art_edit, U"View & Edit Articulation", 0) { for (int i = 1; i <= kArt_muscle_MAX; i ++) REAL (kArt_muscle_getText (i), U"0.0") OK2 { Art object = (Art) ONLY_OBJECT; for (int i = 1; i <= kArt_muscle_MAX; i ++) SET_REAL (kArt_muscle_getText (i), object -> art [i]); } DO Art object = (Art) ONLY_OBJECT; if (theCurrentPraatApplication -> batch) Melder_throw (U"Cannot edit an Art from batch."); for (int i = 1; i <= kArt_muscle_MAX; i ++) object -> art [i] = GET_REAL (kArt_muscle_getText (i)); END2 } /***** ARTWORD *****/ FORM (Artword_create, U"Create an empty Artword", U"Create Artword...") { WORD (U"Name", U"hallo") POSITIVE (U"Duration (seconds)", U"1.0") OK2 DO praat_new (Artword_create (GET_REAL (U"Duration")).transfer(), GET_STRING (U"Name")); END2 } FORM (Artword_draw, U"Draw one Artword tier", NULL) { OPTIONMENU (U"Muscle", kArt_muscle_LUNGS) for (int ienum = 1; ienum <= kArt_muscle_MAX; ienum ++) OPTION (kArt_muscle_getText (ienum)) BOOLEAN (U"Garnish", 1) OK2 DO autoPraatPicture picture; LOOP { iam (Artword); Artword_draw (me, GRAPHICS, GET_INTEGER (U"Muscle"), GET_INTEGER (U"Garnish")); } END2 } DIRECT2 (Artword_edit) { if (theCurrentPraatApplication -> batch) Melder_throw (U"Cannot view or edit an Artword from batch."); WHERE (SELECTED) { iam_LOOP (Artword); autoArtwordEditor editor = ArtwordEditor_create (ID_AND_FULL_NAME, me); praat_installEditor (editor.transfer(), IOBJECT); } END2 } FORM (Artword_getTarget, U"Get one Artword target", 0) { REAL (U"Time (seconds)", U"0.0") OPTIONMENU (U"Muscle", kArt_muscle_LUNGS) for (int ienum = 1; ienum <= kArt_muscle_MAX; ienum ++) OPTION (kArt_muscle_getText (ienum)) OK2 DO LOOP { iam (Artword); double target = Artword_getTarget (me, GET_INTEGER (U"Muscle"), GET_REAL (U"Time")); Melder_information (target); } END2 } DIRECT2 (Artword_help) { Melder_help (U"Artword"); END2 } FORM (Artword_setTarget, U"Set one Artword target", 0) { REAL (U"Time (seconds)", U"0.0") REAL (U"Target value (0-1)", U"0.0") OPTIONMENU (U"Muscle", kArt_muscle_LUNGS) for (int ienum = 1; ienum <= kArt_muscle_MAX; ienum ++) OPTION (kArt_muscle_getText (ienum)) OK2 DO double time = GET_REAL (U"Time"); if (time < 0.0) Melder_throw (U"Specified time should not be less than 0."); LOOP { iam (Artword); Artword_setTarget (me, GET_INTEGER (U"Muscle"), time, GET_REAL (U"Target value")); praat_dataChanged (me); } END2 } FORM (Artword_to_Art, U"From Artword to Art", 0) { REAL (U"Time (seconds)", U"0.0") OK2 DO LOOP { iam (Artword); autoArt thee = Artword_to_Art (me, GET_REAL (U"Time")); praat_new (thee.move(), my name); } END2 } /***** ART & SPEAKER *****/ DIRECT2 (Art_Speaker_draw) { autoPraatPicture picture; iam_ONLY (Art); thouart_ONLY (Speaker); Art_Speaker_draw (me, thee, GRAPHICS); END2 } DIRECT2 (Art_Speaker_fillInnerContour) { autoPraatPicture picture; iam_ONLY (Art); thouart_ONLY (Speaker); Art_Speaker_fillInnerContour (me, thee, GRAPHICS); END2 } DIRECT2 (Art_Speaker_drawMesh) { autoPraatPicture picture; iam_ONLY (Art); thouart_ONLY (Speaker); Art_Speaker_drawMesh (me, thee, GRAPHICS); END2 } DIRECT2 (Art_Speaker_to_VocalTract) { iam_ONLY (Art); thouart_ONLY (Speaker); autoVocalTract him = Art_Speaker_to_VocalTract (me, thee); praat_new (him.move(), my name, U"_", thy name); END2 } /***** ARTWORD & SPEAKER *****/ FORM (Artword_Speaker_draw, U"Draw Artword & Speaker", 0) { NATURAL (U"Number of steps", U"5") OK2 DO autoPraatPicture picture; iam_ONLY (Artword); thouart_ONLY (Speaker); Artword_Speaker_draw (me, thee, GRAPHICS, GET_INTEGER (U"Number of steps")); END2 } FORM (Artword_Speaker_to_Sound, U"Articulatory synthesizer", U"Artword & Speaker: To Sound...") { POSITIVE (U"Sampling frequency (Hz)", U"22050") NATURAL (U"Oversampling factor", U"25") INTEGER (U"Width 1", U"0") INTEGER (U"Width 2", U"0") INTEGER (U"Width 3", U"0") INTEGER (U"Pressure 1", U"0") INTEGER (U"Pressure 2", U"0") INTEGER (U"Pressure 3", U"0") INTEGER (U"Velocity 1", U"0") INTEGER (U"Velocity 2", U"0") INTEGER (U"Velocity 3", U"0") OK2 DO autoSound w1, w2, w3, p1, p2, p3, v1, v2, v3; int iw1 = GET_INTEGER (U"Width 1"); int iw2 = GET_INTEGER (U"Width 2"); int iw3 = GET_INTEGER (U"Width 3"); int ip1 = GET_INTEGER (U"Pressure 1"); int ip2 = GET_INTEGER (U"Pressure 2"); int ip3 = GET_INTEGER (U"Pressure 3"); int iv1 = GET_INTEGER (U"Velocity 1"); int iv2 = GET_INTEGER (U"Velocity 2"); int iv3 = GET_INTEGER (U"Velocity 3"); iam_ONLY (Artword); thouart_ONLY (Speaker); autoSound him = Artword_Speaker_to_Sound (me, thee, GET_REAL (U"Sampling frequency"), GET_INTEGER (U"Oversampling factor"), & w1, iw1, & w2, iw2, & w3, iw3, & p1, ip1, & p2, ip2, & p3, ip3, & v1, iv1, & v2, iv2, & v3, iv3); praat_new (him.move(), my name, U"_", thy name); if (iw1) praat_new (w1.move(), U"width", iw1); if (iw2) praat_new (w2.move(), U"width", iw2); if (iw3) praat_new (w3.move(), U"width", iw3); if (ip1) praat_new (p1.move(), U"pressure", ip1); if (ip2) praat_new (p2.move(), U"pressure", ip2); if (ip3) praat_new (p3.move(), U"pressure", ip3); if (iv1) praat_new (v1.move(), U"velocity", iv1); if (iv2) praat_new (v2.move(), U"velocity", iv2); if (iv3) praat_new (v3.move(), U"velocity", iv3); END2 } /***** ARTWORD & SPEAKER [ & SOUND ] *****/ DIRECT2 (Artword_Speaker_movie) { Graphics g = Movie_create (U"Artword & Speaker movie", 300, 300); iam_ONLY (Artword); thouart_ONLY (Speaker); heis_ONLY (Sound); // can be null Artword_Speaker_Sound_movie (me, thee, him, g); END2 } /***** SPEAKER *****/ FORM (Speaker_create, U"Create a Speaker", U"Create Speaker...") { WORD (U"Name", U"speaker") OPTIONMENU (U"Kind of speaker", 1) OPTION (U"Female") OPTION (U"Male") OPTION (U"Child") OPTIONMENU (U"Number of tubes in glottis", 2) OPTION (U"1") OPTION (U"2") OPTION (U"10") OK2 DO autoSpeaker me = Speaker_create (GET_STRING (U"Kind of speaker"), Melder_atoi (GET_STRING (U"Number of tubes in glottis"))); praat_new (me.move(), GET_STRING (U"Name")); END2 } DIRECT2 (Speaker_help) { Melder_help (U"Speaker"); END2 } /***** VOCAL TRACT *****/ FORM (VocalTract_createFromPhone, U"Create Vocal Tract from phone", U"Create Vocal Tract from phone...") { OPTIONMENU (U"Phone", 1) OPTION (U"a") OPTION (U"e") OPTION (U"i") OPTION (U"o") OPTION (U"u") OPTION (U"y1") OPTION (U"y2") OPTION (U"y3") OPTION (U"jery") OPTION (U"p") OPTION (U"t") OPTION (U"k") OPTION (U"x") OPTION (U"pa") OPTION (U"ta") OPTION (U"ka") OPTION (U"pi") OPTION (U"ti") OPTION (U"ki") OPTION (U"pu") OPTION (U"tu") OPTION (U"ku") OK2 DO autoVocalTract me = VocalTract_createFromPhone (GET_STRING (U"Phone")); praat_new (me.move(), GET_STRING (U"Phone")); END2 } DIRECT2 (VocalTract_draw) { autoPraatPicture picture; WHERE (SELECTED) { iam_LOOP (VocalTract); VocalTract_draw (me, GRAPHICS); } END2 } FORM (VocalTract_formula, U"VocalTract Formula", U"Matrix: Formula...") { LABEL (U"label", U"`x' is the distance form the glottis in metres, `col' is the section number, `self' is in m\u00B2") LABEL (U"label", U"x := x1; for col := 1 to ncol do { self [col] := `formula' ; x := x + dx }") TEXTFIELD (U"formula", U"0") OK2 DO LOOP { iam (VocalTract); try { Matrix_formula (me, GET_STRING (U"formula"), interpreter, NULL); praat_dataChanged (me); } catch (MelderError) { praat_dataChanged (me); throw; } } END2 } DIRECT2 (VocalTract_help) { Melder_help (U"VocalTract"); END2 } DIRECT2 (VocalTract_to_Matrix) { WHERE (SELECTED) { iam_LOOP (VocalTract); autoMatrix thee = VocalTract_to_Matrix (me); praat_new (thee.move(), my name); } END2 } FORM (VocalTract_to_Spectrum, U"From Vocal Tract to Spectrum", 0) { LABEL (U"", U"Compute transfer function") NATURAL (U"Number of frequencies", U"4097") POSITIVE (U"Maximum frequency (Hz)", U"5000") REAL (U"Glottal damping", U"0.1") BOOLEAN (U"Radiation damping", 1) BOOLEAN (U"Internal damping", 1) OK2 DO LOOP { iam (VocalTract); autoSpectrum thee = VocalTract_to_Spectrum (me, GET_INTEGER (U"Number of frequencies"), GET_REAL (U"Maximum frequency"), GET_REAL (U"Glottal damping"), GET_INTEGER (U"Radiation damping"), GET_INTEGER (U"Internal damping")); praat_new (thee.move(), my name); } END2 } DIRECT2 (ArticulatorySynthesisTutorial) { Melder_help (U"Articulatory synthesis"); END2 } void manual_Artsynth_init (ManPages me); void praat_uvafon_Artsynth_init (); void praat_uvafon_Artsynth_init () { Thing_recognizeClassesByName (classArt, classArtword, classSpeaker, NULL); praat_addMenuCommand (U"Objects", U"New", U"Articulatory synthesis", 0, 0, 0); praat_addMenuCommand (U"Objects", U"New", U"Articulatory synthesis tutorial", 0, 1, DO_ArticulatorySynthesisTutorial); praat_addMenuCommand (U"Objects", U"New", U"-- new articulatory synthesis -- ", 0, 1, 0); praat_addMenuCommand (U"Objects", U"New", U"Create Articulation...", 0, 1, DO_Art_create); praat_addMenuCommand (U"Objects", U"New", U"Create Speaker...", 0, 1, DO_Speaker_create); praat_addMenuCommand (U"Objects", U"New", U"Create Artword...", 0, 1, DO_Artword_create); praat_addMenuCommand (U"Objects", U"New", U"-- new vocal tract --", 0, 1, 0); praat_addMenuCommand (U"Objects", U"New", U"Create Vocal Tract from phone...", 0, 1, DO_VocalTract_createFromPhone); praat_addAction1 (classArt, 1, U"View & Edit", 0, praat_ATTRACTIVE, DO_Art_edit); praat_addAction1 (classArt, 1, U"Edit", 0, praat_HIDDEN, DO_Art_edit); praat_addAction1 (classArtword, 0, U"Artword help", 0, 0, DO_Artword_help); praat_addAction1 (classArtword, 1, U"View & Edit", 0, praat_ATTRACTIVE, DO_Artword_edit); praat_addAction1 (classArtword, 1, U"Edit", 0, praat_HIDDEN, DO_Artword_edit); praat_addAction1 (classArtword, 0, U"Info", 0, 0, 0); praat_addAction1 (classArtword, 1, U"Get target...", 0, 0, DO_Artword_getTarget); praat_addAction1 (classArtword, 0, U"Draw", 0, 0, 0); praat_addAction1 (classArtword, 0, U"Draw...", 0, 0, DO_Artword_draw); praat_addAction1 (classArtword, 0, U"Modify", 0, 0, 0); praat_addAction1 (classArtword, 1, U"Set target...", 0, 0, DO_Artword_setTarget); praat_addAction1 (classArtword, 0, U"Analyse", 0, 0, 0); praat_addAction1 (classArtword, 0, U"To Art (slice)...", 0, 0, DO_Artword_to_Art); praat_addAction2 (classArt, 1, classSpeaker, 1, U"Draw", 0, 0, 0); praat_addAction2 (classArt, 1, classSpeaker, 1, U"Draw", 0, 0, DO_Art_Speaker_draw); praat_addAction2 (classArt, 1, classSpeaker, 1, U"Fill inner contour", 0, 0, DO_Art_Speaker_fillInnerContour); praat_addAction2 (classArt, 1, classSpeaker, 1, U"Draw mesh", 0, 0, DO_Art_Speaker_drawMesh); praat_addAction2 (classArt, 1, classSpeaker, 1, U"Synthesize", 0, 0, 0); praat_addAction2 (classArt, 1, classSpeaker, 1, U"To VocalTract", 0, 0, DO_Art_Speaker_to_VocalTract); praat_addAction2 (classArtword, 1, classSpeaker, 1, U"Movie", 0, 0, DO_Artword_Speaker_movie); praat_addAction2 (classArtword, 1, classSpeaker, 1, U"Draw", 0, 0, 0); praat_addAction2 (classArtword, 1, classSpeaker, 1, U"Draw...", 0, 0, DO_Artword_Speaker_draw); praat_addAction2 (classArtword, 1, classSpeaker, 1, U"Synthesize", 0, 0, 0); praat_addAction2 (classArtword, 1, classSpeaker, 1, U"To Sound...", 0, 0, DO_Artword_Speaker_to_Sound); praat_addAction3 (classArtword, 1, classSpeaker, 1, classSound, 1, U"Movie", 0, 0, DO_Artword_Speaker_movie); praat_addAction1 (classSpeaker, 0, U"Speaker help", 0, 0, DO_Speaker_help); praat_addAction1 (classVocalTract, 0, U"VocalTract help", 0, 0, DO_VocalTract_help); praat_addAction1 (classVocalTract, 0, U"Draw", 0, 0, 0); praat_addAction1 (classVocalTract, 0, U"Draw", 0, 0, DO_VocalTract_draw); praat_addAction1 (classVocalTract, 0, U"Analyse", 0, 0, 0); praat_addAction1 (classVocalTract, 0, U"To Spectrum...", 0, 0, DO_VocalTract_to_Spectrum); praat_addAction1 (classVocalTract, 0, U"Modify", 0, 0, 0); praat_addAction1 (classVocalTract, 0, U"Formula...", 0, 0, DO_VocalTract_formula); praat_addAction1 (classVocalTract, 0, U"Hack", 0, 0, 0); praat_addAction1 (classVocalTract, 0, U"To Matrix", 0, 0, DO_VocalTract_to_Matrix); manual_Artsynth_init (theCurrentPraatApplication -> manPages); } /* End of file praat_Artsynth.cpp */ praat-6.0.04/contrib/000077500000000000000000000000001261542461700143605ustar00rootroot00000000000000praat-6.0.04/contrib/ola/000077500000000000000000000000001261542461700151335ustar00rootroot00000000000000praat-6.0.04/contrib/ola/BUGS.txt000066400000000000000000000000631261542461700164330ustar00rootroot00000000000000Known bugs: CPrune: progress indicators are borken praat-6.0.04/contrib/ola/ChangeLog.txt000066400000000000000000000021131261542461700175200ustar00rootroot00000000000000-------------------- libOla.a - ChangeLog -------------------- 2008-05-29 * Initial release 2008-08-10 * Bugfixes * Merging with the upstream version of Praat 2008-10-01 * Bugfix: C-Pruner now rejects instance bases of sizes <= 1 * Multithreaded kNN-classification implemented (Linux only) 2009-01-23 * Bugfix: KNN_learn(...) MUX:ing removed; broke scripting * Bugfix: KNN serialization fixed (using the proper version ID) * Removed redundant information from the manual * The TableOfReal output of the KNN classifier now mimics the format of the corresponding output of the FFNet classifier. 2009-01-31 * kNN-classifier no longer executes in a thread of its own * on single-CPU machines 2009-07-02 * Threading disabled on all plattforms * Bugfix: The k-means clustering routine no longer attempts to create clusters when k > number of patterns by means of reseeding. * Bugfix: Inadequate checking of input data in the C-Pruner routine resulting in rare crashes fixed. praat-6.0.04/contrib/ola/FeatureWeights.cpp000066400000000000000000000357201261542461700205740ustar00rootroot00000000000000/* FeatureWeights.cpp * * Copyright (C) 2007-2008 Ola So"der, 2010-2012 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * os 2007/05/29 Initial release * pb 2010/06/06 removed some array-creations-on-the-stack * pb 2011/03/08 tried to repair some of the header file chaos (several procedures here should be in KNN.c instead) * pb 2011/04/12 C++ */ #include "FeatureWeights.h" #include "KNN.h" // BUG #include "oo_DESTROY.h" #include "FeatureWeights_def.h" #include "oo_COPY.h" #include "FeatureWeights_def.h" #include "oo_EQUAL.h" #include "FeatureWeights_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "FeatureWeights_def.h" #include "oo_WRITE_TEXT.h" #include "FeatureWeights_def.h" #include "oo_WRITE_BINARY.h" #include "FeatureWeights_def.h" #include "oo_READ_TEXT.h" #include "FeatureWeights_def.h" #include "oo_READ_BINARY.h" #include "FeatureWeights_def.h" #include "oo_DESCRIPTION.h" #include "FeatureWeights_def.h" void structFeatureWeights :: v_info () { this -> structDaata :: v_info (); MelderInfo_writeLine (U"Number of weights: ", fweights -> numberOfColumns); } Thing_implement (FeatureWeights, Daata, 0); ///////////////////////////////////////////////////////////////////////////////////////////// // Creation... // ///////////////////////////////////////////////////////////////////////////////////////////// FeatureWeights FeatureWeights_create ( /////////////////////////////// // Parameters // /////////////////////////////// long nweights // number of weights ) { try { autoFeatureWeights me = Thing_new (FeatureWeights); my fweights = TableOfReal_create (1, nweights); for (long i = 1; i <= nweights; i ++) { my fweights -> data [1] [i] = 1; } return me.transfer(); } catch (MelderError) { Melder_throw (U"FeatureWeights not created."); } } ///////////////////////////////////////////////////////////////////////////////////////////// // Compute prior probabilities // ///////////////////////////////////////////////////////////////////////////////////////////// long FeatureWeights_computePriors ( /////////////////////////////// // Parameters // /////////////////////////////// Categories c, // source categories // long * indices, // Out: instances indices .. // double * priors // Out: .. and their prior probabilities // ) { long nc = 0; for (long y = 1; y <= c->size; y++) { long ifriend = -1; for (long sc = 0; sc < nc; sc++) if (FeatureWeights_areFriends ((SimpleString) c->item[y], (SimpleString) c->item[indices[sc]])) ifriend = sc; if (ifriend < 0) { indices[nc] = y; priors[nc] = 1; nc++; } else { priors[ifriend]++; } } for (long q = 0; q < nc; q++) priors[q] /= c->size; return(nc); } ///////////////////////////////////////////////////////////////////////////////////////////// // Compute feature weights // ///////////////////////////////////////////////////////////////////////////////////////////// FeatureWeights FeatureWeights_compute // Obsolete ( /////////////////////////////// // Parameters // /////////////////////////////// Pattern pp, // Source pattern // Categories c, // Source categories // long k // k(!) ) { return(FeatureWeights_computeRELIEF(pp, c, k)); } ///////////////////////////////////////////////////////////////////////////////////////////// // Compute feature weights (wrapper), evaluate using folding // ///////////////////////////////////////////////////////////////////////////////////////////// FeatureWeights FeatureWeights_computeWrapperInt ( /////////////////////////////// // Parameters // /////////////////////////////// KNN me, // Classifier // long k, // k(!) // int d, // distance weighting // long nseeds, // the number of seeds // double alfa, // shrinkage factor // double stop, // stop at // int mode, // mode (co/serial) // int emode // evaluation mode (10-fold/L1O) // ) { if (! me) return nullptr; try { double pivot = 0.5; double range = 0.5; autoNUMvector results (0L, nseeds); autoThingVector cs (0L, nseeds); for (long y = 0; y <= nseeds; y++) { cs [y] = FeatureWeights_create (my input -> nx); } for (long x = 1; x <= my input -> nx; x ++) cs [nseeds] -> fweights -> data [1] [x] = pivot; results [nseeds] = KNN_evaluate (me, cs [nseeds], k, d, emode); while (range > 0 && results [nseeds] < stop) { long best = nseeds; if (mode == 2) { for (long x = 1; x <= (my input)->nx; x++) { for (long y = 0; y < nseeds; y++) { cs[y]->fweights->data[1][x] = NUMrandomUniform(OlaMAX(0, cs[nseeds]->fweights->data[1][x] - range), OlaMIN(1, cs[nseeds]->fweights->data[1][x] + range)); results[y] = KNN_evaluate(me, cs[y], k, d, emode); } for (long q = 0; q < nseeds; q++) if (results[q] > results[best]) best = q; if (results[best] > results[nseeds]) { for (long x = 1; x <= (my input)->nx; x++) cs[nseeds]->fweights->data[1][x] = cs[best]->fweights->data[1][x]; results[nseeds] = results[best]; } } } else { for (long y = 0; y < nseeds; y++) { for (long x = 1; x <= (my input)->nx; x++) { cs[y]->fweights->data[1][x] = NUMrandomUniform(OlaMAX(0, cs[nseeds]->fweights->data[1][x] - range), OlaMIN(1, cs[nseeds]->fweights->data[1][x] + range)); } results[y] = KNN_evaluate (me, cs [y], k, d, emode); } for (long q = 0; q < nseeds; q++) if (results[q] > results[best]) best = q; if (results[best] > results[nseeds]) { for (long x = 1; x <= (my input)->nx; x++) cs[nseeds]->fweights->data[1][x] = cs[best]->fweights->data[1][x]; results[nseeds] = results[best]; } } range -= alfa; } FeatureWeights result = cs [nseeds]; cs [nseeds] = nullptr; // prevent destruction return result; } catch (MelderError) { Melder_throw (U"FeatureWeights: wrapper not computed."); } } ///////////////////////////////////////////////////////////////////////////////////////////// // Compute feature weights (wrapper), evaluate using separate test set // ///////////////////////////////////////////////////////////////////////////////////////////// FeatureWeights FeatureWeights_computeWrapperExt ( /////////////////////////////// // Parameters // /////////////////////////////// KNN nn, // Classifier // Pattern pp, // test pattern // Categories c, // test categories // long k, // k(!) // int d, // distance weighting // long nseeds, // the number of seeds // double alfa, // shrinkage factor // double stop, // stop at // int mode // mode (co/serial) // ) { if (! nn) return nullptr; try { double pivot = 0.5; double range = 0.5; autoNUMvector results (0L, nseeds); autoThingVector cs (0L, nseeds); for (long y = 0; y <= nseeds; y++) { cs [y] = FeatureWeights_create (pp -> nx); } for (long x = 1; x <= pp -> nx; x ++) cs [nseeds] -> fweights -> data [1] [x] = pivot; results [nseeds] = FeatureWeights_evaluate (cs [nseeds], nn, pp, c, k, d); while (range > 0 && results [nseeds] < stop) { long best = nseeds; if (mode == 2) { for (long x = 1; x <= pp->nx; x++) { for (long y = 0; y < nseeds; y++) { cs[y]->fweights->data[1][x] = NUMrandomUniform(OlaMAX(0, cs[nseeds]->fweights->data[1][x] - range), OlaMIN(1, cs[nseeds]->fweights->data[1][x] + range)); results[y] = FeatureWeights_evaluate(cs[y], nn, pp, c, k, d); } for (long q = 0; q < nseeds; q++) if (results[q] > results[best]) best = q; if (results[best] > results[nseeds]) { for (long x = 1; x <= pp->nx; x++) cs[nseeds]->fweights->data[1][x] = cs[best]->fweights->data[1][x]; results[nseeds] = results[best]; } } } else { for (long y = 0; y < nseeds; y++) { for (long x = 1; x <= pp->nx; x++) { cs[y]->fweights->data[1][x] = NUMrandomUniform(OlaMAX(0, cs[nseeds]->fweights->data[1][x] - range), OlaMIN(1, cs[nseeds]->fweights->data[1][x] + range)); } results[y] = FeatureWeights_evaluate (cs [y], nn, pp, c, k, d); } for (long q = 0; q < nseeds; q++) if (results[q] > results[best]) best = q; if (results[best] > results[nseeds]) { for (long x = 1; x <= pp->nx; x++) cs[nseeds]->fweights->data[1][x] = cs[best]->fweights->data[1][x]; results[nseeds] = results[best]; } } range -= alfa; } FeatureWeights result = cs [nseeds]; cs [nseeds] = nullptr; // prevent destruction return result; } catch (MelderError) { Melder_throw (U"FeatureWeights: wrapper not computed."); } } ///////////////////////////////////////////////////////////////////////////////////////////// // Evaluate feature weights, wrapper aux. // ///////////////////////////////////////////////////////////////////////////////////////////// double FeatureWeights_evaluate // Obsolete - use *_EvaluateWithTestSet // instead ( /////////////////////////////// // Parameters // /////////////////////////////// FeatureWeights fws, // Weights to evaluate // KNN nn, // Classifier // Pattern pp, // test pattern // Categories c, // test categories // long k, // k(!) // int d // distance weighting // ) { try { autoCategories o = KNN_classifyToCategories (nn, pp, fws, k, d); double hits = 0; for (long y = 1; y <= o->size; y++) if (FeatureWeights_areFriends ((SimpleString) o -> item [y], (SimpleString) c -> item [y])) hits ++; hits /= o -> size; return hits; } catch (MelderError) { throw; return 0; } } ///////////////////////////////////////////////////////////////////////////////////////////// // Compute feature weights according to the RELIEF-F algorithm // ///////////////////////////////////////////////////////////////////////////////////////////// FeatureWeights FeatureWeights_computeRELIEF ( /////////////////////////////// // Parameters // /////////////////////////////// Pattern pp, // source pattern // Categories c, // source categories // long k // k(!) // ) { autoPattern p = (Pattern) Data_copy (pp); autoFeatureWeights me = FeatureWeights_create (p -> nx); ///////////////////////////////// // Initial weights <- 0 // ///////////////////////////////// for (long i = 1; i <= p->nx; i++) { my fweights -> data [1] [i] = 0.0; } ///////////////////////////////// // Normalization // ///////////////////////////////// autoNUMvector min (0L, p->nx - 1); autoNUMvector max (0L, p->nx - 1); for (long x = 1; x <= p -> nx; x ++) { max [x] = p -> z [1] [x]; // BUG: this will just crash because of array index out of bounds min [x] = max [x]; } for (long y = 1; y <= p -> ny; y ++) { for (long x = 1; x <= p->nx; x++) { if (p->z[y][x] > max[x]) max[x] = p->z[y][x]; if (p->z[y][x] < min[x]) min[x] = p->z[y][x]; } } autoNUMvector alfa (0L, p -> nx - 1); for (long x = 1; x <= p -> nx; x ++) { alfa [x] = max [x] - min [x]; // BUG: this will just crash because of array index out of bounds } for (long y = 1; y <= p->ny; y++) { for (long x = 1; x <= p->nx; x++) { if (alfa [x]) { p->z[y][x] = (p->z[y][x] - min[x]) / alfa[x]; } else { p->z[y][x] = 0; } } } ///////////////////////////////// // Computing prior class probs // ///////////////////////////////// autoNUMvector priors (0L, c->size - 1); // worst-case allocations autoNUMvector classes (0L, c->size - 1);// autoNUMvector enemies (0L, c->size - 1);// autoNUMvector friends (0L, c->size - 1);// long nclasses = FeatureWeights_computePriors (c, classes.peek(), priors.peek()); Melder_assert (nclasses >= 2); ///////////////////////////////// // Updating the w.vector // ///////////////////////////////// for (long y = 1; y <= p -> ny; y ++) { long nfriends = KNN_kFriends (p.peek(), p.peek(), c, y, k, friends.peek()); long nenemies = KNN_kUniqueEnemies (p.peek(), p.peek(), c, y, nclasses - 1, enemies.peek()); if (nfriends && nenemies) { autoNUMvector classps (0L, nenemies - 1); for (long eq = 0; eq < nenemies; eq++) { for (long iq = 0; iq < nclasses; iq++) { if (FeatureWeights_areFriends ((SimpleString) c->item[enemies[eq]], (SimpleString) c->item[classes[iq]])) { classps[eq] = priors[iq]; break; } } } for (long x = 1; x <= p->nx; x++) { double p1 = 0.0; double p2 = 0.0; for (long ec = 0; ec < nfriends; ec++) { p1 += fabs(p->z[y][x] - p->z[friends[ec]][x]) / (p->ny * nfriends); } for (long ec = 0; ec < nenemies; ec++) { p2 += (fabs(p->z[y][x] - p->z[enemies[ec]][x]) * classps[ec]) / p->ny; } my fweights -> data [1] [x] = my fweights -> data [1] [x] - p1 + p2; } } } return me.transfer(); } /* End of file FeatureWeights.cpp */ praat-6.0.04/contrib/ola/FeatureWeights.h000066400000000000000000000054511261542461700202370ustar00rootroot00000000000000#ifndef _FeatureWeights_h_ #define _FeatureWeights_h_ /* FeatureWeights.h * * Copyright (C) 2007-2008 Ola Söder * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * os 20080529 Initial release * pb 2011/03/08 */ ///////////////////////////////////////////////////// // Praat datatypes // ///////////////////////////////////////////////////// #include "Data.h" #include "TableOfReal.h" #include "Pattern.h" #include "Categories.h" ///////////////////////////////////////////////////// // Miscs // ///////////////////////////////////////////////////// #include "OlaP.h" ///////////////////////////////////////////////////// // Praat specifics // ///////////////////////////////////////////////////// #include "FeatureWeights_def.h" oo_CLASS_CREATE (FeatureWeights, Daata); ///////////////////////////////////////////////////// // Private definitions and macros // ///////////////////////////////////////////////////// #define FeatureWeights_areFriends(x,y) ! SimpleString_compare (x,y) #define FeatureWeights_areEnemies(x,y) SimpleString_compare (x,y) ///////////////////////////////////////////////////// // Prototypes // ///////////////////////////////////////////////////// // Create FeatureWeights FeatureWeights_create ( long nweights // number of weights ); // Compute prior probabilities long FeatureWeights_computePriors ( Categories c, // source categories long * indices, // Out: instances indices .. double * priors // Out: .. and their prior probabilities ); // Compute feature weights (obsolete) FeatureWeights FeatureWeights_compute ( Pattern pp, // Source pattern Categories c, // Source categories long k // k(!) ); // Compute feature weights according to the RELIEF-F algorithm FeatureWeights FeatureWeights_computeRELIEF ( Pattern pp, // source pattern Categories c, // source categories long k // k(!) ); /* End of file FeatureWeights.h */ #endif praat-6.0.04/contrib/ola/FeatureWeights_def.h000066400000000000000000000020251261542461700210470ustar00rootroot00000000000000/* FeatureWeights_def.h * * Copyright (C) 2007-2009 Ola Söder, 2011 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT FeatureWeights oo_DEFINE_CLASS (FeatureWeights, Daata) oo_OBJECT (TableOfReal, 0, fweights) #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (FeatureWeights) #undef ooSTRUCT /* End of file FeatureWeights_def.h */ praat-6.0.04/contrib/ola/KNN.cpp000066400000000000000000001577201261542461700163010ustar00rootroot00000000000000/* KNN.cpp * * Copyright (C) 2008 Ola So"der, 2010-2012 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * os 2008/05/29 initial release * pb 2010/06/06 removed some array-creations-on-the-stack * pb 2011/04/12 C++ * pb 2011/04/13 removed several memory leaks * pb 2011/07/07 some exception safety */ #include "KNN.h" #include "KNN_threads.h" #include "OlaP.h" #include "oo_DESTROY.h" #include "KNN_def.h" #include "oo_COPY.h" #include "KNN_def.h" #include "oo_EQUAL.h" #include "KNN_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "KNN_def.h" #include "oo_WRITE_TEXT.h" #include "KNN_def.h" #include "oo_WRITE_BINARY.h" #include "KNN_def.h" #include "oo_READ_TEXT.h" #include "KNN_def.h" #include "oo_READ_BINARY.h" #include "KNN_def.h" #include "oo_DESCRIPTION.h" #include "KNN_def.h" Thing_implement (KNN, Daata, 0); ///////////////////////////////////////////////////////////////////////////////////////////// // Praat specifics // ///////////////////////////////////////////////////////////////////////////////////////////// void structKNN :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Size of instancebase: ", nInstances); } ///////////////////////////////////////////////////////////////////////////////////////////// // Creation // ///////////////////////////////////////////////////////////////////////////////////////////// KNN KNN_create () { try { autoKNN me = Thing_new (KNN); my nInstances = 0; return me.transfer(); } catch (MelderError) { Melder_throw (U"KNN classifier not created."); } } ///////////////////////////////////////////////////////////////////////////////////////////// // Learning // ///////////////////////////////////////////////////////////////////////////////////////////// int KNN_learn ( /////////////////////////////// // Parameters // /////////////////////////////// KNN me, // the classifier to be trained // Pattern p, // source pattern // Categories c, // target categories // int method, // method <- REPLACE or APPEND // int ordering // ordering <- SHUFFLE? ) { if (c->size == p->ny) // the number of input vectors must { // equal the number of categories. switch (method) { case kOla_REPLACE: // in REPLACE mode simply // dispose of the current if (my nInstances > 0) // instance base and store { // the new one. forget (my input); forget (my output); } my input = (Pattern) Data_copy (p); // LEAK my output = (Categories) Data_copy (c); my nInstances = c->size; break; case kOla_APPEND: // in APPEND mode a new // instance base is formed // by merging the new and // the old. // if (p->nx == (my input)->nx) // the number of features // of the old and new // instance base must // match; otherwise merging // won't be possible. { /* * Create without change. */ autoPattern tinput = (Pattern) Matrix_appendRows (my input, p, classPattern).transfer(); autoCategories toutput = (Categories) Collections_merge (my output, c); /* * Change without error. */ forget (my input); forget (my output); my input = tinput.transfer(); my output = toutput.transfer(); my nInstances += p->ny; } else // fail { return kOla_DIMENSIONALITY_MISMATCH; } break; } if (ordering == kOla_SHUFFLE) // shuffle the instance base { KNN_shuffleInstances(me); } } else // fail { return kOla_PATTERN_CATEGORIES_MISMATCH; } return kOla_SUCCESS; // success } ///////////////////////////////////////////////////////////////////////////////////////////// // Classification - To Categories // ///////////////////////////////////////////////////////////////////////////////////////////// typedef struct { KNN me; Pattern ps; long * output; FeatureWeights fws; long k; int dist; long istart; long istop; } KNN_input_ToCategories_t; Categories KNN_classifyToCategories ( /////////////////////////////// // Parameters // /////////////////////////////// KNN me, // the classifier being used // Pattern ps, // the pattern to classify // FeatureWeights fws, // feature weights // long k, // the number of sought after neighbours // int dist // distance weighting ) { int nthreads = KNN_getNumberOfCPUs(); long *outputindices = NUMvector (0, ps->ny); long chunksize = ps->ny / nthreads; Melder_assert(nthreads > 0); Melder_assert(k > 0 && k <= my nInstances); if(chunksize < 1) { chunksize = 1; nthreads = ps->ny; } long istart = 1; long istop = chunksize; autoCategories output = Categories_create (); KNN_input_ToCategories_t ** input = (KNN_input_ToCategories_t **) malloc(nthreads * sizeof(KNN_input_ToCategories_t *)); if (!input) return nullptr; for(int i = 0; i < nthreads; ++i) { input[i] = (KNN_input_ToCategories_t *) malloc(sizeof(KNN_input_ToCategories_t)); if(!input[i]) { while(input[i--]) free(input[i]); free(input); return nullptr; } } for(int i = 0; i < nthreads; ++i) { input[i]->me = me; input[i]->ps = ps; input[i]->output = outputindices; input[i]->fws = fws; input[i]->k = k; input[i]->dist = dist; input[i]->istart = istart; if(istop + chunksize > ps->ny) { input[i]->istop = ps->ny; break; } else { input[i]->istop = istop; istart = istop + 1; istop += chunksize; } } enum KNN_thread_status * error = (enum KNN_thread_status *) KNN_threadDistribution(KNN_classifyToCategoriesAux, (void **) input, nthreads); //void *error = KNN_classifyToCategoriesAux (input [0]); for (int i = 0; i < nthreads; ++ i) free (input [i]); free (input); if (error) // Something went very wrong, you ought to inform the user! { free (error); return nullptr; } if (output) { for (long i = 1; i <= ps->ny; ++i) Collection_addItem (output.get(), Data_copy ((SimpleString) my output -> item [outputindices [i]])); } NUMvector_free (outputindices, 0); return output.transfer(); } void * KNN_classifyToCategoriesAux ( /////////////////////////////// // Parameters // /////////////////////////////// void * input ) { Melder_assert(((KNN_input_ToCategories_t *) input)->istart > 0 && ((KNN_input_ToCategories_t *) input)->istop > 0 && ((KNN_input_ToCategories_t *) input)->istart <= ((KNN_input_ToCategories_t *) input)->ps->ny && ((KNN_input_ToCategories_t *) input)->istop <= ((KNN_input_ToCategories_t *) input)->ps->ny && ((KNN_input_ToCategories_t *) input)->istart <= ((KNN_input_ToCategories_t *) input)->istop); long ncollected; long ncategories; long *indices = NUMvector (0, ((KNN_input_ToCategories_t *) input)->k); long *freqindices = NUMvector (0, ((KNN_input_ToCategories_t *) input)->k); double *distances = NUMvector (0, ((KNN_input_ToCategories_t *) input)->k); double *freqs = NUMvector (0, ((KNN_input_ToCategories_t *) input)->k); for (long y = ((KNN_input_ToCategories_t *) input)->istart; y <= ((KNN_input_ToCategories_t *) input)->istop; ++y) { ///////////////////////////////////////// // Localizing the k nearest neighbours // ///////////////////////////////////////// ncollected = KNN_kNeighbours ( ((KNN_input_ToCategories_t *) input)->ps, ((KNN_input_ToCategories_t *) input)->me->input, ((KNN_input_ToCategories_t *) input)->fws, y, ((KNN_input_ToCategories_t *) input)->k, indices, distances ); ///////////////////////////////////////////////// // Computing frequencies and average distances // ///////////////////////////////////////////////// ncategories = KNN_kIndicesToFrequenciesAndDistances ( ((KNN_input_ToCategories_t *) input)->me->output, ((KNN_input_ToCategories_t *) input)->k, indices, distances, freqs, freqindices ); //////////////////////// // Distance weighting // //////////////////////// switch(((KNN_input_ToCategories_t *) input)->dist) { case kOla_DISTANCE_WEIGHTED_VOTING: for (long c = 0; c < ncategories; ++c) freqs[c] *= 1 / OlaMAX(distances[c], kOla_MINFLOAT); break; case kOla_SQUARED_DISTANCE_WEIGHTED_VOTING: for (long c = 0; c < ncategories; ++c) freqs[c] *= 1 / OlaMAX(OlaSQUARE(distances[c]), kOla_MINFLOAT); } KNN_normalizeFloatArray(freqs, ncategories); ((KNN_input_ToCategories_t *) input)->output[y] = freqindices[KNN_max(freqs, ncategories)]; } NUMvector_free (indices, 0); NUMvector_free (freqindices, 0); NUMvector_free (distances, 0); NUMvector_free (freqs, 0); return nullptr; } //////////////////////////////////////////////////////////////////////////////////////////// // Classification - To TableOfReal // ///////////////////////////////////////////////////////////////////////////////////////////// typedef struct { KNN me; Pattern ps; Categories uniqueCategories; TableOfReal output; FeatureWeights fws; long k; int dist; long istart; long istop; } KNN_input_ToTableOfReal_t; TableOfReal KNN_classifyToTableOfReal ( /////////////////////////////// // Parameters // /////////////////////////////// KNN me, // the classifier being used // Pattern ps, // source Pattern // FeatureWeights fws, // feature weights // long k, // the number of sought after neighbours // int dist // distance weighting ) { int nthreads = KNN_getNumberOfCPUs(); long chunksize = ps->ny / nthreads; autoCategories uniqueCategories = Categories_selectUniqueItems (my output, 1); long ncategories = Categories_getSize (uniqueCategories.get()); Melder_assert (nthreads > 0); Melder_assert (ncategories > 0); Melder_assert (k > 0 && k <= my nInstances); if (! ncategories) return nullptr; if(chunksize < 1) { chunksize = 1; nthreads = ps->ny; } long istart = 1; long istop = chunksize; KNN_input_ToTableOfReal_t ** input = (KNN_input_ToTableOfReal_t **) malloc(nthreads * sizeof(KNN_input_ToTableOfReal_t *)); if(!input) return nullptr; TableOfReal output = TableOfReal_create(ps->ny, ncategories); for (long i = 1; i <= ncategories; ++i) TableOfReal_setColumnLabel (output, i, SimpleString_c ((SimpleString) uniqueCategories->item[i])); for(int i = 0; i < nthreads; ++i) { input[i] = (KNN_input_ToTableOfReal_t *) malloc(sizeof(KNN_input_ToTableOfReal_t)); if(!input[i]) { while(input[i--]) free(input[i]); free(input); return nullptr; } } for(int i = 0; i < nthreads; ++i) { input[i]->me = me; input[i]->ps = ps; input[i]->output = output; input[i]->uniqueCategories = uniqueCategories.transfer(); input[i]->fws = fws; input[i]->k = k; input[i]->dist = dist; input[i]->istart = istart; if(istop + chunksize > ps->ny) { input[i]->istop = ps->ny; break; } else { input[i]->istop = istop; istart = istop + 1; istop += chunksize; } } enum KNN_thread_status * error = (enum KNN_thread_status *) KNN_threadDistribution(KNN_classifyToTableOfRealAux, (void **) input, nthreads); for(int i = 0; i < nthreads; ++i) free(input[i]); free(input); if(error) // Something went very wrong, you ought to inform the user! { free(error); return nullptr; } return(output); } void * KNN_classifyToTableOfRealAux ( /////////////////////////////// // Parameters // /////////////////////////////// void * input ) { long ncategories = Categories_getSize (((KNN_input_ToTableOfReal_t *) input)->uniqueCategories); long *indices = NUMvector (0, ((KNN_input_ToTableOfReal_t *) input)->k); double *distances = NUMvector (0, ((KNN_input_ToTableOfReal_t *) input)->k); for (long 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, ((KNN_input_ToTableOfReal_t *) input)->fws, y, ((KNN_input_ToTableOfReal_t *) input)->k, indices, distances); for(long i = 0; i < ((KNN_input_ToTableOfReal_t *) input)->k; ++i) { for(long j = 1; j <= ncategories; ++j) if(FeatureWeights_areFriends ((SimpleString) ((KNN_input_ToTableOfReal_t *) input)->me->output->item[indices[i]], (SimpleString) ((KNN_input_ToTableOfReal_t *) input)->uniqueCategories->item[j])) ++((KNN_input_ToTableOfReal_t *) input)->output->data[y][j]; } } switch (((KNN_input_ToTableOfReal_t *) input)->dist) { case kOla_DISTANCE_WEIGHTED_VOTING: for (long y = ((KNN_input_ToTableOfReal_t *) input)->istart; y <= ((KNN_input_ToTableOfReal_t *) input)->istop; ++y) { double sum = 0; for(long 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(long c = 1; c <= ncategories; ++c) ((KNN_input_ToTableOfReal_t *) input)->output->data[y][c] /= sum; } break; case kOla_SQUARED_DISTANCE_WEIGHTED_VOTING: for (long y = ((KNN_input_ToTableOfReal_t *) input)->istart; y <= ((KNN_input_ToTableOfReal_t *) input)->istop; ++y) { double sum = 0; for(long 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(long c = 1; c <= ncategories; ++c) ((KNN_input_ToTableOfReal_t *) input)->output->data[y][c] /= sum; } break; case kOla_FLAT_VOTING: for (long y = ((KNN_input_ToTableOfReal_t *) input)->istart; y <= ((KNN_input_ToTableOfReal_t *) input)->istop; ++y) { double sum = 0; for(long c = 1; c <= ncategories; ++c) sum += ((KNN_input_ToTableOfReal_t *) input)->output->data[y][c]; for(long c = 1; c <= ncategories; ++c) ((KNN_input_ToTableOfReal_t *) input)->output->data[y][c] /= sum; } } NUMvector_free (indices, 0); NUMvector_free (distances, 0); return nullptr; } ////////////////////////////////////////////////////////////////////////////////////////////// // Classification - Folding // ///////////////////////////////////////////////////////////////////////////////////////////// Categories KNN_classifyFold ( /////////////////////////////// // Parameters // /////////////////////////////// KNN me, // the classifier being used // Pattern ps, // source Pattern // FeatureWeights fws, // feature weights // long k, // the number of sought after neighbours // int dist, // distance weighting // long begin, // fold start, inclusive [... // long end // fold end, inclusive ...] // ) { Melder_assert(k > 0 && k <= ps->ny); Melder_assert(end > 0 && end <= ps->ny); Melder_assert(begin > 0 && begin <= ps->ny); if (begin > end) OlaSWAP(long, begin, end); if (k > my nInstances - (end - begin)) k = my nInstances - (end - begin); long ncollected; long ncategories; autoNUMvector indices (0L, k); autoNUMvector freqindices (0L, k); autoNUMvector distances (0L, k); autoNUMvector freqs (0L, k); autoNUMvector outputindices (0L, ps->ny); long noutputindices = 0; for (long y = begin; y <= end; ++y) { ///////////////////////////////////////// // Localizing the k nearest neighbours // ///////////////////////////////////////// ncollected = KNN_kNeighboursSkipRange (ps, my input, fws, y, k, indices.peek(), distances.peek(), begin, end); ///////////////////////////////////////////////// // Computing frequencies and average distances // ///////////////////////////////////////////////// ncategories = KNN_kIndicesToFrequenciesAndDistances (my output, k, indices.peek(), distances.peek(), freqs.peek(), freqindices.peek()); //////////////////////// // Distance weighting // //////////////////////// switch (dist) { case kOla_DISTANCE_WEIGHTED_VOTING: for (long c = 0; c < ncategories; c ++) freqs [c] *= 1 / OlaMAX (distances [c], kOla_MINFLOAT); break; case kOla_SQUARED_DISTANCE_WEIGHTED_VOTING: for (long c = 0; c < ncategories; c ++) freqs [c] *= 1 / OlaMAX (OlaSQUARE (distances [c]), kOla_MINFLOAT); } KNN_normalizeFloatArray (freqs.peek(), ncategories); outputindices [noutputindices++] = freqindices [KNN_max (freqs.peek(), ncategories)]; } autoCategories output = Categories_create (); for (long o = 0; o < noutputindices; o ++) { Collection_addItem (output.get(), Data_copy ((SimpleString) my output -> item [outputindices [o]])); } return output.transfer(); } ///////////////////////////////////////////////////////////////////////////////////////////// // Evaluation // ///////////////////////////////////////////////////////////////////////////////////////////// double KNN_evaluate ( /////////////////////////////// // Parameters // /////////////////////////////// KNN me, // the classifier being used // FeatureWeights fws, // feature weights // long k, // the number of sought after neighbours // int dist, // distance weighting // int mode // kOla_TEN_FOLD_CROSS_VALIDATION / kOla_LEAVE_ONE_OUT // ) { double correct = 0; long adder; switch(mode) { case kOla_TEN_FOLD_CROSS_VALIDATION: adder = my nInstances / 10; break; case kOla_LEAVE_ONE_OUT: if (my nInstances > 1) adder = 1; else adder = 0; break; default: adder = 0; } if (adder == 0) return -1; for (long begin = 1; begin <= my nInstances; begin += adder) { autoCategories c = KNN_classifyFold (me, my input, fws, k, dist, begin, OlaMIN (begin + adder - 1, my nInstances)); for (long y = 1; y <= c -> size; y ++) if (FeatureWeights_areFriends ((SimpleString) c -> item [y], (SimpleString) my output -> item [begin + y - 1])) ++ correct; } correct /= (double) my nInstances; return correct; } ///////////////////////////////////////////////////////////////////////////////////////////// // Evaluation using a separate test set // ///////////////////////////////////////////////////////////////////////////////////////////// double KNN_evaluateWithTestSet ( /////////////////////////////// // Parameters // /////////////////////////////// KNN me, // the classifier being used // Pattern p, // The vectors of the test set // Categories c, // The categories of the test set // FeatureWeights fws, // feature weights // long k, // the number of sought after neighbours // int dist // distance weighting // ) { double correct = 0; Categories t = KNN_classifyToCategories(me, p, fws, k, dist); if (t) { for (long y = 1; y <= t->size; y++) if (FeatureWeights_areFriends ((SimpleString) t->item[y], (SimpleString) c->item[y])) correct++; forget(t); return(correct / c->size); } else { return(0); } } ///////////////////////////////////////////////////////////////////////////////////////////// // Model search // ///////////////////////////////////////////////////////////////////////////////////////////// typedef struct structsoil { double performance; long dist; long k; } soil; double KNN_modelSearch ( /////////////////////////////// // Parameters // /////////////////////////////// KNN me, // the classifier being used // FeatureWeights fws, // feature weights // long * k, // valid long *, to hold the output value of k // int * dist, // valid int *, to hold the output value dist_weight // int mode, // evaluation mode // double rate, // learning rate // long nseeds // the number of seeds to be used // ) { try { int dists[] = { kOla_SQUARED_DISTANCE_WEIGHTED_VOTING, kOla_DISTANCE_WEIGHTED_VOTING, kOla_FLAT_VOTING }; long max = *k; double range = (double) max / 2; double pivot = range; double dpivot = 1; double drange = 1; double drate = rate / range; soil best = {0, lround(dpivot), lround(dpivot)}; autoNUMvector field (0L, nseeds - 1); while (range > 0) { for (long n = 0; n < nseeds; n++) { field[n].k = lround(NUMrandomUniform(OlaMAX(pivot - range, 1), OlaMIN(pivot + range, max))); field[n].dist = lround(NUMrandomUniform(OlaMAX(dpivot - drange, 0), OlaMIN(dpivot + drange, 2))); field[n].performance = KNN_evaluate(me, fws, field[n].k, dists[field[n].dist], mode); } long maxindex = 0; for (long n = 1; n < nseeds; n++) if (field[n].performance > field[maxindex].performance) maxindex = n; if (field[maxindex].performance > best.performance) { pivot = field[maxindex].k; dpivot = field[maxindex].dist; best.performance = field[maxindex].performance; best.dist = field[maxindex].dist; best.k = field[maxindex].k; } range -= rate; drange -= drate; } *k = best.k; *dist = dists[best.dist]; return best.performance; } catch (MelderError) { Melder_throw (me, U" & ", fws, U": model search not performed."); } } ///////////////////////////////////////////////////////////////////////////////////////////// // Euclidean distance // ///////////////////////////////////////////////////////////////////////////////////////////// double KNN_distanceEuclidean ( Pattern ps, // Pattern 1 // Pattern pt, // Pattern 2 // FeatureWeights fws, // Feature weights // long rows, // Vector index of pattern 1 // long rowt // Vector index of pattern 2 ) { double distance = 0; for (long x = 1; x <= ps->nx; ++x) distance += OlaSQUARE((ps->z[rows][x] - pt->z[rowt][x]) * fws->fweights->data[1][x]); return(sqrt(distance)); } ///////////////////////////////////////////////////////////////////////////////////////////// // Manhattan distance // ///////////////////////////////////////////////////////////////////////////////////////////// double KNN_distanceManhattan ( Pattern ps, // Pattern 1 // Pattern pt, // Pattern 2 // long rows, // Vector index of pattern 1 // long rowt // Vector index of pattern 2 // ) { double distance = 0; for (long x = 1; x <= ps->nx; ++x) distance += fabs(ps->z[rows][x] - pt->z[rowt][x]); return(distance); } ///////////////////////////////////////////////////////////////////////////////////////////// // Find longest distance // ///////////////////////////////////////////////////////////////////////////////////////////// long KNN_max ( double * distances, // an array of distances containing ... // long ndistances // ndistances distances // ) { long maxndx = 0; for(long maxc = 1; maxc < ndistances; ++maxc) if (distances[maxc] > distances[maxndx]) maxndx = maxc; return(maxndx); } //////////////////////////////////////////////////////////////////////////////////////////// // Locate k neighbours, skip one + disposal of distance // ///////////////////////////////////////////////////////////////////////////////////////////// long KNN_kNeighboursSkip ( /////////////////////////////// // Parameters // /////////////////////////////// Pattern j, // source pattern // Pattern p, // target pattern (where neighbours are sought for) // FeatureWeights fws, // feature weights // long jy, // source instance index // long k, // the number of sought after neighbours // long * indices, // memory space to contain the indices of // the k neighbours // long skipper // the index of the instance to be skipped // ) { long maxi; long dc = 0; long py = 1; autoNUMvector distances (0L, k - 1); Melder_assert(jy > 0 && jy <= j->ny); Melder_assert(k > 0 && k <= p->ny); Melder_assert(skipper <= p->ny); while (dc < k && py <= p -> ny) { if (py != jy && py != skipper) { distances [dc] = KNN_distanceEuclidean (j, p, fws, jy, py); indices [dc] = py; ++ dc; } ++ py; } maxi = KNN_max (distances.peek(), k); while (py <= p->ny) { if (py != jy && py != skipper) { double d = KNN_distanceEuclidean (j, p, fws, jy, py); if (d < distances [maxi]) { distances [maxi] = d; indices [maxi] = py; maxi = KNN_max (distances.peek(), k); } } ++ py; } return OlaMIN (k, dc); } ////////////////////////////////////////////////////////////////////////////////// // Locate the k nearest neighbours, exclude instances within the range defined // // by [begin ... end] // ////////////////////////////////////////////////////////////////////////////////// long KNN_kNeighboursSkipRange ( /////////////////////////////// // Parameters // /////////////////////////////// Pattern j, // source-pattern (where the unknown is located) // Pattern p, // target pattern (where neighbours are sought for) // FeatureWeights fws, // feature weights // long jy, // the index of the unknown instance in the source pattern // long k, // the number of sought after neighbours // long * indices, // a pointer to a memory-space big enough for k longs // representing indices to the k neighbours in the // target pattern // double * distances, // a pointer to a memory-space big enough for k // doubles representing the distances to the k // neighbours // long begin, // an index indicating the first instance in the // target pattern to be excluded from the search // long end // an index indicating the last instance in the // range of excluded instances in the target // pattern ) { /////////////////////////////// // Private variables // /////////////////////////////// long maxi; // index indicating the most distant neighbour // among the k nearest // long dc = 0; // fetch counter // long py = 0; // Melder_assert(jy > 0 && jy <= j->ny); Melder_assert(k > 0 && k <= p->ny); Melder_assert(end > 0 && end <= j->ny); Melder_assert(begin > 0 && begin <= j->ny); while (dc < k && (end + py) % p->ny + 1 != begin) // the first k neighbours are the nearest found { // sofar if ((end + py) % p->ny + 1 != jy) // no instance is its own neighbour { distances[dc] = KNN_distanceEuclidean(j, p, fws, jy, (end + py) % p->ny + 1); indices[dc] = (end + py) % p->ny + 1; ++dc; } ++py; } maxi = KNN_max(distances, k); // accept only those instances less distant while ((end + py) % p->ny + 1 != begin) // than the least near one found this far { if ((end + py) % p->ny + 1 != jy) { double d = KNN_distanceEuclidean(j, p, fws, jy, (end + py) % p->ny + 1); if (d < distances[maxi]) { distances[maxi] = d; indices[maxi] = (end + py) % p->ny + 1; maxi = KNN_max(distances, k); } } ++py; } return(OlaMIN(k, dc)); // return the number of found neighbours } ///////////////////////////////////////////////////////////////////////////////////////////// // Locate k neighbours // ///////////////////////////////////////////////////////////////////////////////////////////// long KNN_kNeighbours ( /////////////////////////////// // Parameters // /////////////////////////////// Pattern j, // source-pattern (where the unknown is located) // Pattern p, // target pattern (where neighbours are sought for) // FeatureWeights fws, // feature weights // long jy, // the index of the unknown instance in the source pattern // long k, // the number of sought after neighbours // long * indices, // a pointer to a memory-space big enough for k longs // representing indices to the k neighbours in the // target pattern double * distances // a pointer to a memory-space big enough for k // doubles representing the distances to the k // neighbours // ) { long maxi; long dc = 0; long py = 1; Melder_assert(jy > 0 && jy <= j->ny); Melder_assert(k > 0 && k <= p->ny); Melder_assert(indices); Melder_assert(distances); while (dc < k && py <= p->ny) { if (py != jy) { distances[dc] = KNN_distanceEuclidean(j, p, fws, jy, py); indices[dc] = py; ++dc; } ++py; } maxi = KNN_max(distances, k); while (py <= p->ny) { if (py != jy) { double d = KNN_distanceEuclidean(j, p, fws, jy, py); if (d < distances[maxi]) { distances[maxi] = d; indices[maxi] = py; maxi = KNN_max(distances, k); } } ++py; } long ret = OlaMIN(k, dc); if (ret < 1) { indices[0] = jy; return(0); } else return(ret); } ///////////////////////////////////////////////////////////////////////////////////////////// // Locating k (nearest) friends // ///////////////////////////////////////////////////////////////////////////////////////////// long KNN_kFriends ( /////////////////////////////// // Parameters // /////////////////////////////// Pattern j, // source-pattern // Pattern p, // target pattern (where friends are sought for) // Categories c, // categories // long jy, // the index of the source instance // long k, // the number of sought after friends // long * indices // a pointer to a memory-space big enough for k longs // representing indices to the k friends in the // target pattern ) { long maxi; long dc = 0; long py = 1; double *distances = NUMvector (0, k - 1); Melder_assert(jy <= j->ny && k <= p->ny && k > 0); Melder_assert(indices); while (dc < k && py < p->ny) { if (jy != py && FeatureWeights_areFriends ((SimpleString) c->item[jy], (SimpleString) c->item[py])) { distances[dc] = KNN_distanceManhattan(j, p, jy, py); indices[dc] = py; dc++; } ++py; } maxi = KNN_max(distances, k); while (py <= p->ny) { if (jy != py && FeatureWeights_areFriends ((SimpleString) c->item[jy],(SimpleString) c->item[py])) { double d = KNN_distanceManhattan(j, p, jy, py); if (d < distances[maxi]) { distances[maxi] = d; indices[maxi] = py; maxi = KNN_max(distances, k); } } ++py; } NUMvector_free (distances, 0); return(OlaMIN(k,dc)); } ///////////////////////////////////////////////////////////////////////////////////////////// // Computing the distance to the nearest enemy // ///////////////////////////////////////////////////////////////////////////////////////////// double KNN_nearestEnemy ( /////////////////////////////// // Parameters // /////////////////////////////// Pattern j, // source-pattern // Pattern p, // target pattern (where friends are sought for) // Categories c, // categories // long jy // the index of the source instance // ) { double distance = KNN_distanceManhattan(j, p, jy, 1); Melder_assert(jy > 0 && jy <= j->ny ); for (long y = 2; y <= p->ny; y++) { if (FeatureWeights_areEnemies ((SimpleString) c->item[jy], (SimpleString) c->item[y])) { double newdist = KNN_distanceManhattan(j, p, jy, y); if (newdist > distance) distance = newdist; } } return(distance); } ///////////////////////////////////////////////////////////////////////////////////////////// // Computing the number of friends among k neighbours // ///////////////////////////////////////////////////////////////////////////////////////////// long KNN_friendsAmongkNeighbours ( /////////////////////////////// // Parameters // /////////////////////////////// Pattern j, // source-pattern // Pattern p, // target pattern (where friends are sought for) // Categories c, // categories // long jy, // the index of the source instance // long k // k (!) // ) { autoNUMvector distances (0L, k - 1); autoNUMvector indices (0L, k - 1); long friends = 0; Melder_assert (jy > 0 && jy <= j->ny && k <= p->ny && k > 0); autoFeatureWeights fws = FeatureWeights_create (p -> nx); long ncollected = KNN_kNeighbours (j, p, fws.peek(), jy, k, indices.peek(), distances.peek()); while (ncollected--) if (FeatureWeights_areFriends ((SimpleString) c->item[jy], (SimpleString) c->item[indices[ncollected]])) friends++; return friends ; } ///////////////////////////////////////////////////////////////////////////////////////////// // Locating k unique (nearest) enemies // ///////////////////////////////////////////////////////////////////////////////////////////// long KNN_kUniqueEnemies ( /////////////////////////////// // Parameters // /////////////////////////////// Pattern j, // source-pattern // Pattern p, // target pattern (where friends are sought for) // Categories c, // categories // long jy, // the index of the source instance // long k, // k (!) // long * indices // a memory space to hold the indices of the // located enemies // ) { long maxi; long dc = 0; long py = 1; double *distances = NUMvector (0, k - 1); Melder_assert (jy <= j->ny); Melder_assert (k <= p->ny); Melder_assert (k > 0); Melder_assert (indices); while (dc < k && py <= p->ny) { if (FeatureWeights_areEnemies ((SimpleString) c->item[jy], (SimpleString) c->item[py])) { int hasfriend = 0; for (long sc = 0; sc < dc; ++sc) if (FeatureWeights_areFriends ((SimpleString) c->item[py], (SimpleString) c->item[indices[sc]])) hasfriend = 1; if (!hasfriend) { distances[dc] = KNN_distanceManhattan(j, p, jy, py); indices[dc] = py; ++dc; } } ++py; } maxi = KNN_max(distances, k); while (py <= p->ny) { if (FeatureWeights_areEnemies ((SimpleString) c->item[jy], (SimpleString) c->item[py])) { int hasfriend = 0; for (long sc = 0; sc < dc; ++sc) if (FeatureWeights_areFriends ((SimpleString) c->item[py], (SimpleString) c->item[indices[sc]])) hasfriend = 1; if (!hasfriend) { double d = KNN_distanceManhattan(j, p, jy, py); if (d < distances[maxi] && FeatureWeights_areFriends ((SimpleString) c->item[jy], (SimpleString) c->item[py])) { distances[maxi] = d; indices[maxi] = py; maxi = KNN_max(distances, k); } } } ++py; } NUMvector_free (distances, 0); return(OlaMIN(k,dc)); } ///////////////////////////////////////////////////////////////////////////////////////////// // Compute dissimilarity matrix // ///////////////////////////////////////////////////////////////////////////////////////////// Dissimilarity KNN_patternToDissimilarity ( /////////////////////////////// // Parameters // /////////////////////////////// Pattern p, // Pattern // FeatureWeights fws // Feature weights // ) { autoDissimilarity output = Dissimilarity_create (p -> ny); for (long y = 1; y <= p -> ny; ++ y) for (long x = 1; x <= p -> ny; ++ x) output -> data [y] [x] = KNN_distanceEuclidean (p, p, fws, y, x); return output.transfer(); } ///////////////////////////////////////////////////////////////////////////////////////////// // Compute frequencies // ///////////////////////////////////////////////////////////////////////////////////////////// long KNN_kIndicesToFrequenciesAndDistances ( /////////////////////////////// // Parameters // /////////////////////////////// Categories c, // Source categories // long k, // k (!) // long * indices, // In: indices // double * distances, // Out: distances // double * freqs, // Out: and frequencies (double, sic!) // long *freqindices // Out: and indices -> freqs. ) { long ncategories = 0; Melder_assert(k <= c->size && k > 0); Melder_assert(distances && indices && freqs && freqindices); for (long y = 0; y < k; ++y) { int hasfriend = 0; long ifriend = 0; while (ifriend < ncategories) { if (FeatureWeights_areFriends ((SimpleString) c->item[indices[y]], (SimpleString) c->item[freqindices[ifriend]])) { hasfriend = 1; break; } ++ifriend; } if (!hasfriend) { freqindices[ncategories] = indices[y]; freqs[ncategories] = 1; distances[ncategories] = distances[y]; ncategories++; } else { ++freqs[ifriend]; distances[ifriend] += (distances[y] - distances[ifriend]) / (ncategories + 1); } } return(ncategories); } ///////////////////////////////////////////////////////////////////////////////////////////// // Normalize array // ///////////////////////////////////////////////////////////////////////////////////////////// void KNN_normalizeFloatArray ( /////////////////////////////// // Parameters // /////////////////////////////// double * array, // Array to be normalized // long n // The number of elements // in the array ) { long c = 0; double sum = 0; while(c < n) sum += array[c++]; while(c--) array[c] /= sum; } ///////////////////////////////////////////////////////////////////////////////////////////// // Remove instance // ///////////////////////////////////////////////////////////////////////////////////////////// void KNN_removeInstance ( /////////////////////////////// // Parameters // /////////////////////////////// KNN me, // Classifier // long y // Index of the instance to be purged // ) { if (y == 1 && my nInstances == 1) { my nInstances = 0; forget(my input); forget(my output); return; } Melder_assert(y > 0 && y <= my nInstances); if (y > my nInstances || y < 1) return; // safety belt Pattern newPattern = (Pattern) Pattern_create(my nInstances - 1, (my input)->nx); Melder_assert(newPattern); if (newPattern) { long yt = 1; for (long cy = 1; cy <= my nInstances; ++cy) if (cy != y) { for (long cx = 1; cx <= (my input)->nx; ++cx) newPattern->z[yt][cx] = (my input)->z[cy][cx]; ++yt; } forget(my input); my input = newPattern; Collection_removeItem(my output, y); my nInstances--; } } ///////////////////////////////////////////////////////////////////////////////////////////// // Shuffle instances // ///////////////////////////////////////////////////////////////////////////////////////////// void KNN_shuffleInstances ( /////////////////////////////// // Parameters // /////////////////////////////// KNN me // Classifier whose instance // base is to be shuffled ) { if (my nInstances < 2) return; // It takes atleast two to tango autoPattern new_input = Pattern_create (my nInstances, my input -> nx); autoCategories new_output = Categories_create (); long y = 1; while (my nInstances) { long pick = (long) lround (NUMrandomUniform (1, my nInstances)); Collection_addItem (new_output.peek(), Data_copy ((SimpleString) my output -> item [pick])); for (long x = 1;x <= (my input)->nx; ++x) new_input -> z [y] [x] = my input-> z [pick] [x]; KNN_removeInstance (me, pick); ++y; } forget (my input); forget (my output); my nInstances = new_output -> size; my input = new_input.transfer(); my output = new_output.transfer(); } ///////////////////////////////////////////////////////////////////////////////////////////// // KNN to Permutation (experimental) // ///////////////////////////////////////////////////////////////////////////////////////////// Permutation KNN_SA_ToPermutation ( /////////////////////////////// // Parameters // /////////////////////////////// KNN me, // the classifier being used // long tries, // // long iterations, // // double step_size, // // double boltzmann_c, // // double temp_start, // // double damping_f, // // double temp_stop // // ) { gsl_rng * r; const gsl_rng_type * T; KNN_SA_t * istruct = KNN_SA_t_create(my input); Permutation result = Permutation_create(my nInstances); gsl_siman_params_t params = { (int) tries, (int) iterations, step_size, boltzmann_c, temp_start, damping_f, temp_stop}; gsl_rng_env_setup(); T = gsl_rng_default; r = gsl_rng_alloc(T); gsl_siman_solve(r, istruct, KNN_SA_t_energy, KNN_SA_t_step, KNN_SA_t_metric, nullptr, // KNN_SA_t_print KNN_SA_t_copy, KNN_SA_t_copy_construct, KNN_SA_t_destroy, 0, params); for (long i = 1; i <= my nInstances; ++i) result->p[i] = istruct->indices[i]; KNN_SA_t_destroy(istruct); return(result); } double KNN_SA_t_energy ( /////////////////////////////// // Parameters // /////////////////////////////// void * istruct ) { if(((KNN_SA_t *) istruct)->p->ny < 2) return(0); double eCost = 0; for(long i = 1; i <= ((KNN_SA_t *) istruct)->p->ny; ++i) { /* fast and sloppy version */ double jDist = 0; double kDist = 0; long j = i - 1 > 0 ? i - 1 : ((KNN_SA_t *) istruct)->p->ny; long k = i + 1 <= ((KNN_SA_t *) istruct)->p->ny ? i + 1 : 1; for (long x = 1; x <= ((KNN_SA_t *) istruct)->p->nx; ++x) { jDist += OlaSQUARE(((KNN_SA_t *) istruct)->p->z[((KNN_SA_t *) istruct)->indices[i]][x] - ((KNN_SA_t *) istruct)->p->z[((KNN_SA_t *) istruct)->indices[j]][x]); kDist += OlaSQUARE(((KNN_SA_t *) istruct)->p->z[((KNN_SA_t *) istruct)->indices[i]][x] - ((KNN_SA_t *) istruct)->p->z[((KNN_SA_t *) istruct)->indices[k]][x]); } eCost += ((sqrt(jDist) + sqrt(kDist)) / 2 - eCost) / i; } return(eCost); } double KNN_SA_t_metric ( void * istruct1, void * istruct2 ) { double result = 0; for(long i = ((KNN_SA_t *) istruct1)->p->ny; i >= 1; --i) if(((KNN_SA_t *) istruct1)->indices[i] != ((KNN_SA_t *) istruct2)->indices[i]) ++result; return(result); } void KNN_SA_t_print (void * istruct) { Melder_casual (U"\n"); for (long i = 1; i <= ((KNN_SA_t *) istruct) -> p -> ny; i ++) Melder_casual (((KNN_SA_t *) istruct) -> indices [i]); Melder_casual (U"\n"); } void KNN_SA_t_step ( const gsl_rng * r, void * istruct, double step_size ) { long i1 = lround ((((KNN_SA_t *) istruct) -> p -> ny - 1) * gsl_rng_uniform (r)) + 1; long i2 = (i1 + lround (step_size * gsl_rng_uniform (r))) % ((KNN_SA_t *) istruct) -> p -> ny + 1; if (i1 == i2) return; if (i1 > i2) OlaSWAP (long, i1, i2); long partitions[i2 - i1 + 1]; KNN_SA_partition(((KNN_SA_t *) istruct)->p, i1, i2, partitions); for (long r, l = 1, stop = i2 - i1 + 1; l < stop; l ++) { while (l < stop && partitions [l] == 1) l ++; r = l + 1; while (r <= stop && partitions [r] == 2) r ++; if (r == stop) break; OlaSWAP (long, ((KNN_SA_t *) istruct) -> indices [i1], ((KNN_SA_t *) istruct) -> indices [i2]); } } void KNN_SA_t_copy ( void * istruct_src, void * istruct_dest ) { ((KNN_SA_t *) istruct_dest)->p = ((KNN_SA_t *) istruct_src)->p; for(long i = 1; i <= ((KNN_SA_t *) istruct_dest)->p->ny; ++i) ((KNN_SA_t *) istruct_dest)->indices[i] = ((KNN_SA_t *) istruct_src)->indices[i]; } void * KNN_SA_t_copy_construct ( void * istruct ) { KNN_SA_t * result = (KNN_SA_t *) malloc(sizeof(KNN_SA_t)); result->p = ((KNN_SA_t *) istruct)->p; result->indices = (long *) malloc(sizeof(long) * (result->p->ny + 1)); for(long i = 1; i <= result->p->ny; ++i) result->indices[i] = ((KNN_SA_t *) istruct)->indices[i]; return((void *) result); } KNN_SA_t * KNN_SA_t_create ( Pattern p ) { KNN_SA_t * result = (KNN_SA_t *) malloc(sizeof(KNN_SA_t)); result->p = p; result->indices = (long *) malloc(sizeof(long) * (p->ny + 1)); for(long i = 1; i <= p->ny; ++i) result->indices[i] = i; return(result); } void KNN_SA_t_destroy ( void * istruct ) { free(((KNN_SA_t *) istruct)->indices); free((KNN_SA_t *) istruct); } void KNN_SA_partition ( /////////////////////////////// // Parameters // /////////////////////////////// Pattern p, // // long i1, // i1 < i2 // long i2, // // long * result // [0] anv. ej // ) { long c1 = (long) lround(NUMrandomUniform(i1, i2)); long c2 = (long) lround(NUMrandomUniform(i1, i2)); double *p1 = NUMvector (1, p->nx); double *p2 = NUMvector (1, p->nx); for(long x = 1; x <= p->nx; ++x) { p1[x] = p->z[c1][x]; p2[x] = p->z[c2][x]; } for (bool converging = true; converging; ) { double d1, d2; converging = false; for(long i = i1, j = 1; i <= i2; ++i) { d1 = 0; d2 = 0; for (long x = 1; x <= p->nx; ++x) { d1 += OlaSQUARE(p->z[i][x] - p1[x]); d2 += OlaSQUARE(p->z[i][x] - p2[x]); } d1 = sqrt(d1); d2 = sqrt(d2); if(d1 < d2) { if(result[j] != 1) { converging = true; result[j] = 1; } } else { if(result[j] != 2) { converging = true; result[j] = 2; } } ++j; } for (long x = 1; x <= p -> nx; x ++) { p1[x] = 0; p2[x] = 0; } for (long i = i1, j = 1, j1 = 1, j2 = 1; i <= i2; i ++) { if (result [j] == 1) { for (long x = 1; x <= p->nx; x ++) p1[x] += (p->z[i][x] - p1[x]) / j1; ++j1; } else { for (long x = 1; x <= p -> nx; x ++) p2[x] += (p->z[i][x] - p2[x]) / j2; ++j2; } ++j; } } NUMvector_free (p1, 1); NUMvector_free (p2, 1); } /* End of file KNN.cpp */ praat-6.0.04/contrib/ola/KNN.h000066400000000000000000000333401261542461700157350ustar00rootroot00000000000000#ifndef _KNN_h_ #define _KNN_h_ /* KNN.h * * Copyright (C) 2007-2008 Ola Söder * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * os 20080529 Initial release * pb 2011/03/08 C++ */ ///////////////////////////////////////////////////// // Praat datatypes // ///////////////////////////////////////////////////// #include "Data.h" #include "Pattern.h" #include "Categories.h" #include "TableOfReal.h" #include "Permutation.h" #include "MDS.h" ///////////////////////////////////////////////////// // KNN miscs // ///////////////////////////////////////////////////// #include "OlaP.h" #include "FeatureWeights.h" #include "gsl_siman.h" ///////////////////////////////////////////////////// // Praat specifics // ///////////////////////////////////////////////////// #include "KNN_def.h" oo_CLASS_CREATE (KNN, Daata); ///////////////////////////////////////////////////// // Private definitions and macros // ///////////////////////////////////////////////////// #define kOla_TEN_FOLD_CROSS_VALIDATION 1 #define kOla_LEAVE_ONE_OUT 2 #define kOla_TO_TABLEOFREAL 1 #define kOla_TO_TABLEOFREAL_ALL 2 #define kOla_TO_CATEGORIES 4 #define kOla_SQUARED_DISTANCE_WEIGHTED_VOTING 8 #define kOla_DISTANCE_WEIGHTED_VOTING 16 #define kOla_FLAT_VOTING 32 #define kOla_ERROR 0 #define kOla_SUCCESS 303 #define kOla_APPEND 1 #define kOla_REPLACE 2 #define kOla_SHUFFLE 1 #define kOla_SEQUENTIAL 2 #define kOla_PATTERN_CATEGORIES_MISMATCH 111 #define kOla_DIMENSIONALITY_MISMATCH 222 #define kOla_FWEIGHTS_MISMATCH 333 ///////////////////////////////////////////////////// // Prototypes // ///////////////////////////////////////////////////// // a near-dummy function KNN KNN_create (); // Learning int KNN_learn ( KNN me, // the classifier to be trained Pattern p, // source pattern Categories c, // target categories int method, // method <- REPLACE or APPEND int ordering // ordering <- SHUFFLE? ); // Classification - To Categories Categories KNN_classifyToCategories ( KNN me, // the classifier being used Pattern ps, // target pattern (where neighbours are sought for) FeatureWeights fws, // feature weights long k, // the number of sought after neighbours int dist // distance weighting ); // Classification - To Categories, threading aux void * KNN_classifyToCategoriesAux ( void * input ); // Classification - To TableOfReal TableOfReal KNN_classifyToTableOfReal ( KNN me, // the classifier being used Pattern ps, // target pattern (where neighbours are sought for) FeatureWeights fws, // feature weights long k, // the number of sought after neighbours int dist // distance weighting ); // Classification - To TableOfReal, threading aux void * KNN_classifyToTableOfRealAux ( void * input ); // Classification - To TableOfReal, all candidates TableOfReal KNN_classifyToTableOfRealAll ( KNN me, // the classifier being used Pattern ps, // target pattern (where neighbours are sought for) FeatureWeights fws, // feature weights long k, // the number of sought after neighbours int dist // distance weighting ); // Classification - Folding Categories KNN_classifyFold ( KNN me, // the classifier being used Pattern ps, // target pattern (where neighbours are sought for) FeatureWeights fws, // feature weights long k, // the number of sought after neighbours int dist, // distance weighting long begin, // fold start, inclusive [... long end // fold end, inclusive ...] ); // Evaluation double KNN_evaluate ( KNN me, // the classifier being used FeatureWeights fws, // feature weights long k, // the number of sought after neighbours int dist, // distance weighting int mode // TEN_FOLD_CROSS_VALIDATION / LEAVE_ONE_OUT ); // Evaluation using a separate test set double KNN_evaluateWithTestSet ( KNN me, // the classifier being used Pattern p, // The vectors of the test set Categories c, // The categories of the test set FeatureWeights fws, // feature weights long k, // the number of sought after neighbours int dist // distance weighting ); // Model search double KNN_modelSearch ( KNN me, // the classifier being used FeatureWeights fws, // feature weights long * k, // valid long *, to hold the output value of k int * dist, // valid int *, to hold the output value dist_weight int mode, // evaluation mode double rate, // learning rate long nseeds // the number of seeds to be used ); // Euclidean distance double KNN_distanceEuclidean ( Pattern ps, // Pattern 1 Pattern pt, // Pattern 2 FeatureWeights fws, // Feature weights long rows, // Vector index of pattern 1 long rowt // Vector index of pattern 2 ); // Manhattan distance double KNN_distanceManhattan ( Pattern ps, // Pattern 1 Pattern pt, // Pattern 2 long rows, // Vector index of pattern 1 long rowt // Vector index of pattern 2 ); // Find longest distance long KNN_max ( double * distances, // an array of distances containing ... long ndistances // ndistances distances ); // Locate k neighbours, skip one + disposal of distance long KNN_kNeighboursSkip ( Pattern j, // source pattern Pattern p, // target pattern (where neighbours are sought for) FeatureWeights fws, // feature weights long jy, // source instance index long k, // the number of sought after neighbours long * indices, // memory space to contain the indices of long skipper // the index of the instance to be skipped ); // Locate the k nearest neighbours, exclude instances within the range defined // by [begin ... end] long KNN_kNeighboursSkipRange ( Pattern j, // source-pattern (where the unknown is located) Pattern p, // target pattern (where neighbours are sought for) FeatureWeights fws, // feature weights long jy, // the index of the unknown instance in the source pattern long k, // the number of sought after neighbours long * indices, // a pointer to a memory-space big enough for k longs // representing indices to the k neighbours in the // target pattern double * distances, // a pointer to a memory-space big enough for k // doubles representing the distances to the k // neighbours long begin, // an index indicating the first instance in the // target pattern to be excluded from the search long end // an index indicating the last instance in the // range of excluded instances in the target // pattern ); // Locate k neighbours long KNN_kNeighbours ( Pattern j, // source-pattern (where the unknown is located) Pattern p, // target pattern (where neighbours are sought for) FeatureWeights fws, // feature weights long jy, // the index of the unknown instance in the source pattern long k, // the number of sought after neighbours long * indices, // a pointer to a memory-space big enough for k longs // representing indices to the k neighbours in the // target pattern double * distances // a pointer to a memory-space big enough for k // doubles representing the distances to the k // neighbours ); // Locating k (nearest) friends long KNN_kFriends ( Pattern j, // source-pattern Pattern p, // target pattern (where friends are sought for) Categories c, // categories long jy, // the index of the source instance long k, // the number of sought after friends long * indices // a pointer to a memory-space big enough for k longs // representing indices to the k friends in the // target pattern ); // Computing the distance to the nearest enemy double KNN_nearestEnemy ( Pattern j, // source-pattern Pattern p, // target pattern (where friends are sought for) Categories c, // categories long jy // the index of the source instance ); // Computing the number of friends among k neighbours long KNN_friendsAmongkNeighbours ( Pattern j, // source-pattern Pattern p, // target pattern (where friends are sought for) Categories c, // categories long jy, // the index of the source instance long k // k (!) ); // Locating k unique (nearest) enemies long KNN_kUniqueEnemies ( Pattern j, // source-pattern Pattern p, // target pattern (where friends are sought for) Categories c, // categories long jy, // the index of the source instance long k, // k (!) long * indices // a memory space to hold the indices of the // located enemies ); // Compute dissimilarity matrix Dissimilarity KNN_patternToDissimilarity ( Pattern p, // Pattern FeatureWeights fws // Feature weights ); // Compute frequencies long KNN_kIndicesToFrequenciesAndDistances ( Categories c, // Source categories long k, // k (!) long * indices, // In: indices double * distances, // Out: distances double * freqs, // Out: and frequencies (double, sic!) long *freqindices // Out: and indices -> freqs. ); // Normalize array void KNN_normalizeFloatArray ( double * array, // Array to be normalized long n // The number of elements // in the array ); // Remove instance void KNN_removeInstance ( KNN me, // Classifier long y // Index of the instance to be purged // ); // Shuffle instances void KNN_shuffleInstances ( KNN me // Classifier whose instance // base is to be shuffled ); // Experimental code Permutation KNN_SA_ToPermutation ( KNN me, // the classifier being used long tries, // long iterations, // double step_size, // double boltzmann_c, // double temp_start, // double damping_f, // double temp_stop // // ); // Experimental code typedef struct { Pattern p; long * indices; } KNN_SA_t; // Experimental code double KNN_SA_t_energy ( void * istruct ); // Experimental code double KNN_SA_t_metric ( void * istruct1, void * istruct2 ); // Experimental code void KNN_SA_t_print ( void * istruct ); // Experimental code void KNN_SA_t_step ( const gsl_rng * r, void * istruct, double step_size ); // Experimental code void KNN_SA_t_copy ( void * istruct_src, void * istruct_dest ); // Experimental code void * KNN_SA_t_copy_construct ( void * istruct ); // Experimental code KNN_SA_t * KNN_SA_t_create ( Pattern p ); // Experimental code void KNN_SA_t_destroy ( void * istruct ); // Experimental code void KNN_SA_partition ( Pattern p, long i1, long i2, long * result ); // Compute feature weights (wrapper), evaluate using folding FeatureWeights FeatureWeights_computeWrapperInt ( KNN me, // Classifier long k, // k(!) int d, // distance weighting long nseeds, // the number of seeds double alfa, // shrinkage factor double stop, // stop at int mode, // mode (co/serial) int emode // evaluation mode (10-fold/L1O) ); // Compute feature weights (wrapper), evaluate using separate test set FeatureWeights FeatureWeights_computeWrapperExt ( KNN nn, // Classifier Pattern pp, // test pattern Categories c, // test categories long k, // k(!) int d, // distance weighting long nseeds, // the number of seeds double alfa, // shrinkage factor double stop, // stop at int mode // mode (co/serial) ); // Evaluate feature weights, wrapper aux. double FeatureWeights_evaluate ( FeatureWeights fws, // Weights to evaluate KNN nn, // Classifier Pattern pp, // test pattern Categories c, // test categories long k, // k(!) int d // distance weighting ); /* End of file KNN.h */ #endif praat-6.0.04/contrib/ola/KNN_def.h000066400000000000000000000020731261542461700165520ustar00rootroot00000000000000/* KNN_def.h * * Copyright (C) 2007-2009 Ola Söder, 2011 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Pattern.h" #define ooSTRUCT KNN oo_DEFINE_CLASS (KNN, Daata) oo_LONG (nInstances) oo_OBJECT (Pattern, 2, input) oo_OBJECT (Categories, 0, output) #if oo_DECLARING // overridden methods: virtual void v_info (); #endif oo_END_CLASS (KNN) #undef ooSTRUCT /* End of file KNN_def.h */ praat-6.0.04/contrib/ola/KNN_prune.cpp000066400000000000000000000177001261542461700175030ustar00rootroot00000000000000/* KNN_prune.cpp * * Copyright (C) 2007-2008 Ola So"der, 2010-2011 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * os 2007/05/29 Initial release * os 2009/01/23 Bugfix: Rejects classifiers containing 0 or 1 instances * pb 2010/06/06 removed some array-creations-on-the-stack * pb 2011/04/14 C++ * pb 2011/04/16 removed memory leaks */ #include "KNN_prune.h" ///////////////////////////////////////////////////////////////////////////////////////////// // Prune // ///////////////////////////////////////////////////////////////////////////////////////////// long KNN_prune_prune ( KNN me, // the classifier to be pruned double n, // pruning degree: noise, 0 <= n <= 1 double r, // pruning redundancy: noise, 0 <= n <= 1 long k // k(!) ) { autoCategories uniqueCategories = Categories_selectUniqueItems (my output, 1); if (Categories_getSize (uniqueCategories.peek()) == my nInstances) return 0; long removals = 0; long ncandidates = 0; autoNUMvector candidates (0L, my nInstances - 1); if (my nInstances <= 1) return 0; for (long y = 1; y <= my nInstances; y ++) { if (KNN_prune_noisy (my input, my output, y, k)) { if (n == 1 || NUMrandomUniform (0, 1) <= n) { KNN_removeInstance (me, y); ++ removals; } } } for (long y = 1; y <= my nInstances; ++ y) { if (KNN_prune_superfluous (my input, my output, y, k, 0) && ! KNN_prune_critical (my input, my output, y, k)) candidates [ncandidates ++] = y; } KNN_prune_sort (my input, my output, k, candidates.peek(), ncandidates); for (long y = 0; y < ncandidates; ++ y) { if (KNN_prune_superfluous (my input, my output, candidates [y], k, 0) && ! KNN_prune_critical (my input, my output, candidates [y], k)) { if (r == 1 || NUMrandomUniform (0, 1) <= r) { KNN_removeInstance (me, candidates[y]); for (long i = y + 1; i < ncandidates; ++ i) { if(candidates[i] > candidates[y]) -- candidates[i]; } ++ removals; } } } return removals; } ///////////////////////////////////////////////////////////////////////////////////////////// // sort indices according to pruning order defined by rule 2 // ///////////////////////////////////////////////////////////////////////////////////////////// void KNN_prune_sort ( Pattern p, // source Categories c, // source long k, // k(!) long * indices, // indices of instances to be sorted long nindices // the number of instances to be sorted ) { long n = nindices; autoNUMvector h (0L, nindices - 1); for (long cc = 0; cc < nindices; ++ cc) h [cc] = KNN_friendsAmongkNeighbours (p, p, c, indices [cc], k); while (-- n) { // insertion-sort, is heap-sort worth the effort? for (long m = n; m < nindices - 1; m ++) { if (h [m - 1] > h[m]) break; if (h [m - 1] < h[m]) { OlaSWAP (long, indices [m - 1], indices [m]); } else { if (KNN_nearestEnemy (p, p, c, indices [m - 1]) < KNN_nearestEnemy (p, p, c, indices [m])) { OlaSWAP (long, indices [m - 1], indices [m]); } else { if (NUMrandomUniform (0, 1) > 0.5) { OlaSWAP (long, indices [m - 1], indices [m]); } } } } } } ///////////////////////////////////////////////////////////////////////////////////////////// // k-coverage // ///////////////////////////////////////////////////////////////////////////////////////////// long KNN_prune_kCoverage ( Pattern p, // source Categories c, // source long y, // source instance index long k, // k(!) long * indices // Out: kCoverage set ) { Melder_assert (y <= p->ny); Melder_assert (k > 0 && k <= p->ny); long cc = 0; autoFeatureWeights fws = FeatureWeights_create (p -> nx); autoNUMvector tempindices (0L, p -> ny - 1); for (long yy = 1; yy <= p -> ny; yy++) { if (y != yy && FeatureWeights_areFriends ((SimpleString) c -> item [y], (SimpleString) c -> item [yy])) { long n = KNN_kNeighboursSkip (p, p, fws.peek(), yy, k, tempindices.peek(), y); while (n) { Melder_assert (n <= p -> ny); if (tempindices [-- n] == y) { indices [cc ++] = yy; break; } } } } return cc; } ///////////////////////////////////////////////////////////////////////////////////////////// // testing for superfluousness // ///////////////////////////////////////////////////////////////////////////////////////////// int KNN_prune_superfluous ( Pattern p, // source Categories c, // source long y, // source instance index long k, // k(!) long skipper // Skipping instance skipper ) { if (y > p -> ny) y = p -> ny; // safety belt if (k > p -> ny) k = p -> ny; autoFeatureWeights fws = FeatureWeights_create (p -> nx); autoNUMvector indices (0L, k - 1); autoNUMvector freqindices (0L, k - 1); autoNUMvector distances (0L, k - 1); autoNUMvector freqs (0L, k - 1); if (! KNN_kNeighboursSkip (p, p, fws.peek(), y, k, indices.peek(), skipper)) return 0; long ncategories = KNN_kIndicesToFrequenciesAndDistances (c, k, indices.peek(), distances.peek(), freqs.peek(), freqindices.peek()); int result = FeatureWeights_areFriends ((SimpleString) c -> item [y], (SimpleString) c -> item [freqindices [KNN_max (freqs.peek(), ncategories)]]); if (result) return 1; return 0; } ///////////////////////////////////////////////////////////////////////////////////////////// // testing for criticalness // ///////////////////////////////////////////////////////////////////////////////////////////// int KNN_prune_critical ( Pattern p, // source Categories c, // source long y, // source instance index long k // k(!) ) { if (y > p -> ny) y = p -> ny; // safety belt if (k > p -> ny) k = p -> ny; autoFeatureWeights fws = FeatureWeights_create (p -> nx); autoNUMvector indices (0L, k - 1); long ncollected = KNN_kNeighboursSkip (p, p, fws.peek(), y, k, indices.peek(), y); for (long ic = 0; ic < ncollected; ic ++) { if (! KNN_prune_superfluous (p, c, indices [ic], k, 0) || ! KNN_prune_superfluous (p, c, indices [ic], k, y)) { return 1; } } return 0; } ///////////////////////////////////////////////////////////////////////////////////////////// // testing for noisyness // ///////////////////////////////////////////////////////////////////////////////////////////// int KNN_prune_noisy ( Pattern p, // source Categories c, // source long y, // source instance index long k // k(!) ) { if (y > p -> ny) y = p -> ny; // safety belt if (k > p -> ny) k = p -> ny; autoFeatureWeights fws = FeatureWeights_create (p -> nx); autoNUMvector indices (0L, p->ny - 1); // the coverage is not bounded by k but by n long reachability = KNN_kNeighboursSkip (p, p, fws.peek(), y, k, indices.peek(), y); long coverage = KNN_prune_kCoverage (p, c, y, k, indices.peek()); if (! KNN_prune_superfluous (p, c, y, k, 0) && reachability > coverage) return 1; return 0; } /* End of file KNN_prune.cpp */ praat-6.0.04/contrib/ola/KNN_prune.h000066400000000000000000000053171261542461700171510ustar00rootroot00000000000000#ifndef _KNN_prune_h_ #define _KNN_prune_h_ /* KNN_prune.h * * Copyright (C) 2007-2008 Ola Söder * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * os 20080529 Initial release * pb 2011/03/08 C++ */ ///////////////////////////////////////////////////// // Prune auxs // ///////////////////////////////////////////////////// #include "KNN.h" #include "FeatureWeights.h" #include "OlaP.h" ///////////////////////////////////////////////////// // Prototypes // ///////////////////////////////////////////////////// // Prune long KNN_prune_prune ( KNN me, // the classifier to be pruned double n, // pruning degree: noise, 0 <= n <= 1 double r, // pruning redundancy: noise, 0 <= n <= 1 long k // k(!) ); // sort indices according to pruning order defined by rule 2 void KNN_prune_sort ( Pattern p, // source Categories c, // source long k, // k(!) long * indices, // indices of instances to be sorted long nindices // the number of instances to be sorted ); // k-coverage long KNN_prune_kCoverage ( Pattern p, // source Categories c, // source long y, // source instance index long k, // k(!) long * indices // Out: kCoverage set ); // testing for superfluousness int KNN_prune_superfluous ( Pattern p, // source Categories c, // source long y, // source instance index long k, // k(!) long skipper // Skipping instance skipper ); // testing for criticalness int KNN_prune_critical ( Pattern p, // source Categories c, // source long y, // source instance index long k // k(!) ); // testing for noisyness int KNN_prune_noisy ( Pattern p, // source Categories c, // source long y, // source instance index long k // k(!) ); /* End of file KNN_prune.h */ #endif praat-6.0.04/contrib/ola/KNN_threads.cpp000066400000000000000000000126021261542461700200000ustar00rootroot00000000000000/* KNN_threads.cpp * * Copyright (C) 2009 Ola Söder * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * os 20090123 First version */ ///////////////////////////////////////////////////// // // ///////////////////////////////////////////////////// #include #include "KNN.h" #include "KNN_threads.h" #include "OlaP.h" // Threading disabled /* // Linux... #if defined (__linux__) #define __USE_GNU #include // BSD-style OSes #elif defined (__APPLE__) #include #include #endif // Non-pthreaders, Windows #ifdef _WIN32 #include // The rest of the pack #else #include #endif */ ///////////////////////////////////////////////////// // KNN_getNumberOfCPUs // ///////////////////////////////////////////////////// int KNN_getNumberOfCPUs () { return(1); // Threading disabled /* int ncpus = 0; // Linux... #if defined (__linux__) cpu_set_t * cpuset = (cpu_set_t *) malloc(sizeof(cpu_set_t)); if(cpuset) { sched_getaffinity(0, sizeof(cpu_set_t), cpuset); for(int cpu = 0; cpu <= CPU_SETSIZE; ++cpu) if(CPU_ISSET(cpu, cpuset)) ++ncpus; free(cpuset); } Melder_assert(ncpus >= 1); // BSD-style OSes #elif defined (__APPLE__) int mib[2]; size_t len = sizeof(ncpus); mib[0] = CTL_HW; mib[1] = HW_NCPU; sysctl(mib, 2, &ncpus, &len, 0, 0); // Non-pthreaders, Windows #elif defined (_WIN32) typedef BOOL (WINAPI *LPFN_GLPI) (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD); BOOL done, rc; DWORD returnLength, byteOffset; PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer, ptr; LPFN_GLPI Glpi; Glpi = (LPFN_GLPI) GetProcAddress(GetModuleHandle(TEXT("kernel32")), "GetLogicalProcessorInformation"); if(!Glpi) return(1); done = false; buffer = nullptr; returnLength = 0; while(!done) { rc = Glpi(buffer, &returnLength); if(!rc) { if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) { if(buffer) free(buffer); return (1); } else done = true; } byteOffset = 0; ptr=buffer; while (byteOffset < returnLength) { switch (ptr->Relationship) { case RelationProcessorCore: ++ncpus; default: } byteOffset += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); ++ptr; } } free(buffer); ncpus = 1; // Unknown OS #else ncpus = 1; #endif Melder_assert(ncpus >= 1); return(ncpus); */ } ///////////////////////////////////////////////////// // KNN_threadDistribution // ///////////////////////////////////////////////////// void * KNN_threadDistribution ( void * (* function) (void *), void ** input, int nthreads ) { Melder_assert(function && input && nthreads > 0); if(!(function && input && nthreads > 0)) { KNN_thread_status * error = (KNN_thread_status *) malloc(sizeof(enum KNN_thread_status)); if(error) *error = KNN_THREAD_ERROR; return((void *) error); } if(nthreads > 1) { #ifdef _WIN32 // Threading disabled /* HANDLE hHandle[nthreads]; for(int i = 0; i < nthreds; ++) hHandle[i] = CreateThread(nullptr, 0, function, input[i], 0, nullptr); while(nthreads--) WaitForSingleObject(hHandle[nthreds], INFINITE); */ #else // Threading disabled /* pthread_t thread_ids[nthreads]; for(int i = 0; i < nthreads; ++i) pthread_create(&thread_ids[i], nullptr, function, input[i]); while(nthreads--) pthread_join(thread_ids[nthreads], nullptr); return nullptr; */ #endif } void *result = function (input [0]); return result; } ///////////////////////////////////////////////////// // KNN_threadTest // ///////////////////////////////////////////////////// void KNN_threadTest () { void * dummy[KNN_getNumberOfCPUs()]; KNN_threadDistribution(KNN_threadTestAux, (void **) &dummy, KNN_getNumberOfCPUs()); } ///////////////////////////////////////////////////// // KNN_threadTestAux // ///////////////////////////////////////////////////// void * KNN_threadTestAux (void * dummy) { dummy = nullptr; // dummy assignment to avoid compiler warnings; for(int i = 0; i < 50000; ++i) for(int i = 0; i < 50000; ++i) ; return nullptr; } praat-6.0.04/contrib/ola/KNN_threads.h000066400000000000000000000027671261542461700174600ustar00rootroot00000000000000#ifndef _KNN_threads_h_ #define _KNN_threads_h_ /* KNN_threads.h * * Copyright (C) 2009 Ola Söder * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * os 20090123 First version * pb 2011/03/08 C++ */ ///////////////////////////////////////////////////// // // ///////////////////////////////////////////////////// // Error codes enum KNN_thread_status { KNN_THREAD_OK, KNN_THREAD_ERROR }; // Query the number of available CPUs int KNN_getNumberOfCPUs (); // Distribute the work specified by // (*function) and input over nthreads // threads void * KNN_threadDistribution ( void * (* function) (void *), void ** input, int nthreads ); // Test threading void KNN_threadTest (); // Test threading aux void * KNN_threadTestAux ( void * dummy ); /* End of file KNN_threads.h */ #endif praat-6.0.04/contrib/ola/Makefile000066400000000000000000000013121261542461700165700ustar00rootroot00000000000000# Makefile of the library "contrib/ola" # Ola So"der 19 January 2008 # Paul Boersma, 24 August 2013 include ../../makefile.defs CPPFLAGS = -I ../../dwtools -I ../../fon -I ../../sys -I ../../dwsys -I ../../stat -I ../../num -I ../../external/gsl -D_DEBUG -D_REENTRANT OBJECTS = KNN.o \ KNN_threads.o Pattern_to_Categories_cluster.o KNN_prune.o FeatureWeights.o praat_contrib_Ola_KNN.o manual_KNN.o .PHONY: all clean all: libOla.a clean: $(RM) $(OBJECTS) $(RM) libOla.a libOla.a: $(OBJECTS) touch libOla.a rm libOla.a $(AR) cq libOla.a $(OBJECTS) $(RANLIB) libOla.a $(OBJECTS): *.h ../../sys/*.h ../../dwtools/*.h ../../fon/*.h ../../dwsys/*.h ../../stat/*.h ../../num/*.h ../../external/gsl/*.h praat-6.0.04/contrib/ola/OlaP.h000066400000000000000000000026751261542461700161510ustar00rootroot00000000000000#ifndef _OlaP_h_ #define _OlaP_h_ /* OlaP.h * * Copyright (C) 2007-2008 Ola Söder * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * os 20080529 Initial release */ ///////////////////////////////////////// // Macros // ///////////////////////////////////////// #define OlaSWAP(TYPE, X, Y) {TYPE temp = X; X = Y; Y = temp;} #define OlaMAX(x,y) ((x) > (y) ? (x) : (y)) #define OlaMIN(x,y) ((x) < (y) ? (x) : (y)) #define OlaSQUARE(x) ((x) * (x)) ///////////////////////////////////////// // DEBUG // ///////////////////////////////////////// ///////////////////////////////////////// // Misc defines // ///////////////////////////////////////// #define kOla_MINFLOAT 0.0000000000000000000001 #endif /* _Misc_h_ */ praat-6.0.04/contrib/ola/Pattern_to_Categories_cluster.cpp000066400000000000000000000114531261542461700236700ustar00rootroot00000000000000/* Pattern_to_Categories_cluster.cpp * * Copyright (C) 2007-2008 Ola So"der, 2010-2011 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * os 20070529 initial release * pb 20100606 removed some array-creations-on-the-stack * pb 20100606 corrected some arrary-index-out-of-bounds errors * pb 20100606 corrected some memory leaks * pb 2011/03/08 tried to repair some of the header file chaos (several procedures here should be in KNN.c instead) * pb 2011/04/13 C++ */ #include "Pattern_to_Categories_cluster.h" #include "KNN.h" // BUG ///////////////////////////////////////////////////////////////////////////////////////////// // Pattern_to_Categories_cluster // ///////////////////////////////////////////////////////////////////////////////////////////// Categories Pattern_to_Categories_cluster ( /////////////////////////////// // Parameters // /////////////////////////////// Pattern p, // source // FeatureWeights fws, // feature weights // long k, // k(!) // double s, // clustersize constraint 0 < s <= 1 // long m // reseed maximum // ) { autoCategories categories = Categories_sequentialNumbers (k); if (k == p->ny) return categories.transfer(); autoKNN knn = KNN_create(); if(p->ny % k) if (s > (double) (p->ny / k) / (double) (p->ny / k + 1)) s = (double) (p->ny / k) / (double) (p->ny / k + 1); double progress = m; autoNUMvector sizes (0L, k); autoNUMvector seeds (0L, k); autoPattern centroids = (Pattern) Pattern_create (k, p->nx); autoNUMvector beta (0L, centroids->nx); do { double delta; long nfriends = 0; Melder_progress (1 - (progress - m) / progress, U""); for (long y = 1; y <= centroids->ny; y++) { int ifriend = 1; long ys = (long) lround(NUMrandomUniform(1, p->ny)); if (nfriends) { while (ifriend) { ys = (long) lround(NUMrandomUniform(1, p->ny)); for (long fc = 0; fc < nfriends; fc++) { ifriend = 0; Melder_assert (fc < k); if (seeds [fc] == ys) { ifriend = 1; break; } } } } Melder_assert (nfriends <= k); seeds [nfriends++] = ys; for (long x = 1; x <= centroids->nx; x++) centroids->z[y][x] = p->z[ys][x]; } do { delta = 0; KNN_learn (knn.peek(), centroids.peek(), categories.peek(), kOla_REPLACE, kOla_SEQUENTIAL); autoCategories interim = KNN_classifyToCategories (knn.peek(), p, fws, 1, kOla_FLAT_VOTING); for (long x = 1; x <= k; x++) sizes [x] = 0; for (long yp = 1; yp <= categories->size; yp++) { double alfa = 1; Melder_assert (yp <= centroids->ny); for (long x = 1; x <= centroids->nx; x++) { beta[x] = centroids->z[yp][x]; } for (long ys = 1; ys <= interim->size; ys++) { if (FeatureWeights_areFriends ((SimpleString) categories->item[yp], (SimpleString) interim->item[ys])) { for (long x = 1; x <= p->nx; x++) { Melder_assert (ys <= p->ny); if (alfa == 1) { centroids->z[yp][x] = p->z[ys][x]; } else { centroids->z[yp][x] += (p->z[ys][x] - centroids->z[yp][x]) / alfa; } } Melder_assert (yp <= k); sizes [yp] ++; alfa++; } } for (long x = 1; x <= centroids->nx; x++) { delta += fabs (beta[x] - centroids->z[yp][x]); } } } while (delta != 0.0); double smax = sizes [1]; double smin = sizes [1]; for (long x = 1; x <= k; x++) { if (smax < sizes [x]) smax = sizes [x]; if (smin > sizes [x]) smin = sizes [x]; } sizes [0] = smin / smax; --m; } while (sizes[0] < s && m > 0); autoCategories output = KNN_classifyToCategories (knn.peek(), p, fws, 1, kOla_FLAT_VOTING); return output.transfer(); } /* End of file Pattern_to_Categories_cluster.cpp */ praat-6.0.04/contrib/ola/Pattern_to_Categories_cluster.h000066400000000000000000000037621261542461700233410ustar00rootroot00000000000000/* Pattern_to_Categories_cluster.h * * Copyright (C) 2007-2008 Ola Söder * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * os 20070529 Initial release * pb 2011/03/08 C++ */ ///////////////////////////////////////////////////// // DEBUG // ///////////////////////////////////////////////////// //#define CLUSTERING_DEBUG ///////////////////////////////////////////////////// // Praat datatypes // ///////////////////////////////////////////////////// #include "Pattern.h" #include "Categories.h" ///////////////////////////////////////////////////// // Miscs // ///////////////////////////////////////////////////// #include "FeatureWeights.h" ///////////////////////////////////////////////////// // Prototypes // ///////////////////////////////////////////////////// // Pattern_to_Categories_cluster Categories Pattern_to_Categories_cluster ( Pattern p, // source FeatureWeights fws, // feature weights long k, // k(!) double s, // clustersize constraint 0 < s <= 1 long m // reseed maximum ); /* End of file Pattern_to_Categories_cluster.h */ praat-6.0.04/contrib/ola/TODO.txt000066400000000000000000000000661261542461700164430ustar00rootroot00000000000000Multithreading on Windows. Approx n. search? kD-tree? praat-6.0.04/contrib/ola/manual_KNN.cpp000066400000000000000000001270471261542461700176350ustar00rootroot00000000000000/* manual_KNN.c * * Copyright (C) 2007-2008 Ola Söder * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * os 2008/05/29 Initial release * os 2009/01/23 Removed irrelevant information * pb 2010/12/28 lay-out, spelling */ #include "ManPagesM.h" #include "KNN.h" void manual_KNN_init (ManPages me); void manual_KNN_init (ManPages me) { MAN_BEGIN (U"kNN classifiers", U"Ola Söder", 20080529) INTRO (U"This tutorial describes the use of kNN classifiers in Praat.") NORMAL (U"@@kNN classifiers 1. What is a kNN classifier?|1. What is a kNN classifier?@") NORMAL (U"@@kNN classifiers 1.1. Improving classification accuracy|1.1. Improving classification accuracy@") LIST_ITEM (U"@@kNN classifiers 1.1.1. Feature weighting|1.1.1. Feature weighting@") LIST_ITEM (U"@@kNN classifiers 1.1.1.1. Filter-based feature weighting|1.1.1.1. Filter-based feature weighting@") LIST_ITEM (U"@@kNN classifiers 1.1.1.2. Wrapper-based feature weighting|1.1.1.2. Wrapper-based feature weighting@") LIST_ITEM (U"@@kNN classifiers 1.1.2. Model selection|1.1.2. Model selection@") NORMAL (U"@@kNN classifiers 1.2. Improving resource efficiency|1.2. Improving resource efficiency@") LIST_ITEM (U"@@kNN classifiers 1.2.1. Pruning|1.2.1. Pruning@") NORMAL (U"@@kNN classifiers 2. Quick start|2. Quick start@") NORMAL (U"@@kNN classifiers 3. Command overview|3. Command overview@") MAN_END MAN_BEGIN (U"KNN", U"Ola Söder", 20080529) INTRO (U"One of the @@types of objects@ in Praat.") NORMAL (U"A #KNN classifier can %learn associations between its %input and its %output. " "The @@kNN classifiers@ tutorial gives you an introduction to the usage of %%k%NN learners in Praat.") MAN_END MAN_BEGIN (U"FeatureWeights", U"Ola Söder", 20080729) INTRO (U"One of the @@types of objects@ in Praat.") NORMAL (U"A @FeatureWeights object is a %d-dimensional vector containing weight values used to transform a %d-dimensional space. Feature weighting can be used to improve the classifcation accuracy of @KNN classifiers. It can also be used to generate a @Dissimilarity matrix from a @Pattern object. @Dissimilarity matrices in conjunction with @@Multidimensional scaling|MDS-analysis@ can aid the visualization of high-dimensional data.") MAN_END MAN_BEGIN (U"kNN classifiers 1. What is a kNN classifier?", U"Ola Söder", 20080529) NORMAL (U"%%Instance-based% classifiers such as the %%k%NN classifier operate on the premises that classification of unknown instances " "can be done by relating the unknown to the known according to some @@Euclidean distance|distance/similarity function@. " "The intuition is that two instances far apart in the %%instance space% defined by the appropriate %%distance function% are less likely " "than two closely situated instances to belong to the same class.") ENTRY (U"The learning process") NORMAL (U"Unlike many artificial learners, %%instance-based% learners do not abstract any information from the training data during the learning phase. " "Learning is merely a question of encapsulating the training data. The process of %generalization is postponed until it is absolutely unavoidable, " "that is, at the time of %classification. This property has lead to the referring to %%instance-based% learners as %lazy learners, " "whereas classifiers such as @@Feedforward neural networks 1. What is a feedforward neural network?|feedforward neural networks@, " "where proper %abstraction is done during the learning phase, often are entitled %eager learners.") ENTRY (U"Classification") NORMAL (U"Classification (%generalization) using an %%instance-based% classifier can be a simple matter of locating the nearest neighbour in %%instance space% " "and labelling the unknown instance with the same class label as that of the located (known) neighbour. " "This approach is often referred to as a %%nearest neighbour classifier%. " "The downside of this simple approach is the lack of robustness that characterize the resulting classifiers. " "The high degree of local sensitivity makes %%nearest neighbour classifiers% highly susceptible to noise in the training data.") NORMAL (U"More robust models can be achieved by locating %k, where %k > 1, neighbours and letting the majority vote decide the outcome of the class labelling. " "A higher value of %k results in a smoother, less locally sensitive, function. " "The %%nearest neighbour classifier% can be regarded as a special case of the more general %%k-nearest neighbours classifier%, " "hereafter referred to as a %%k%NN classifier. The drawback of increasing the value of %k is of course that as %k approaches %n, " "where %n is the size of the %%instance base%, the performance of the classifier will approach that of the most straightforward %%statistical baseline%, " "the assumption that all unknown instances belong to the class most most frequently represented in the training data.") NORMAL (U"This problem can be avoided by limiting the influence of distant instances. " "One way of doing so is to assign a weight to each vote, where the weight is a function of the distance between the unknown and the known instance. " "By letting each weight be defined by the inversed squared distance between the known and unknown instances votes cast by distant instances " "will have very little influence on the decision process compared to instances in the near neighbourhood. " "%%Distance weighted voting% usually serves as a good middle ground as far as local sensitivity is concerned.") MAN_END MAN_BEGIN (U"kNN classifiers 1.1. Improving classification accuracy", U"Ola Söder", 20080529) NORMAL (U"This tutorial describes possible ways of improving the classification accuracy of a %%k%NN classifier.") LIST_ITEM (U"@@kNN classifiers 1.1.1. Feature weighting|1.1.1. Feature weighting@") LIST_ITEM (U"@@kNN classifiers 1.1.2. Model selection|1.1.2. Model selection@") MAN_END MAN_BEGIN (U"kNN classifiers 1.1.1. Feature weighting", U"Ola Söder", 20080529) NORMAL (U"A %%k%NN classifier in its most basic form operates under the implicit assumption that all features are of equal value as far as the classification problem at hand is concerned. When irrelevant and noisy features influence the neighbourhood search to the same degree as highly relevant features, the accuracy of the model is likely to deteriorate. %%Feature weighting% is a technique used to approximate the optimal degree of influence of individual features using a training set. When successfully applied relevant features are attributed a high weight value, whereas irrelevant features are given a weight value close to zero. %%Feature weighting% can be used not only to improve classification accuracy but also to discard features with weights below a certain threshold value and thereby increase the resource efficiency of the classifier.") NORMAL (U"Two fundamentally different approaches to this optimization problem can be identified, the %%filter-based% and the %%wrapper-based%. The class of %%filter-based% methods contains algorithms that use no input other than the training data itself to calculate the %%feature weights%, whereas %%wrapper-based% algorithms use feedback from a classifier to guide the search. %%Wrapper-based% algorithms are inherently more powerful than their filter-based counterpart as they implicitly take the %%inductive bias% of the classifier into account. This power comes at a price however; the usage of %%wrapper-based% algorithms increases the risk of %%overfitting% the training data.") NORMAL (U"In @@kNN classifiers 1.1.1.1. Filter-based feature weighting|section 1.1.1.1.@ the %%filter-based% feature weighting algorithm implemented in Praat is presented. @@kNN classifiers 1.1.1.2. Wrapper-based feature weighting|Section 1.1.1.2.@ contains an account of the implemented %%wrapper-based% feature weighting algorithm.") MAN_END MAN_BEGIN (U"kNN classifiers 1.1.1.1. Filter-based feature weighting", U"Ola Söder", 20080529) NORMAL (U"The %%filter-based% %%feature weighting% algorithm implemented in Praat is an extended version of the well known R\\s{ELIEF} algorithm, R\\s{ELIEF-F}, such as it is presented (with one minor exception, see below) in @@Igor Kononenko (1994)|Kononenko (1994)@. Unlike the original R\\s{ELIEF} algorithm, the R\\s{ELIEF-F} algorithm copes with multi class (as in more than 2 classes) data sets. The simple intuition behind the R\\s{ELIEF-F} algorithm is that a good feature is a feature with little within class variance and generous amounts of between-class variance. A bad feature is characterized by within-class and between-class variances of magnitudes roughly equal.") NORMAL (U"The computation of the weight vector is done in an iterative fashion, with all weights initially set to 0. All features in the training set are normalized (all values are set within the range [0 ... 1]) and thereafter used to update the weight vector as follows: On each iteration a random instance is chosen. The nearest hit is located, where hit is an instance of the same class as that of the randomly chosen instance. The nearest misses of all the classes but that of the randomly chosen instance are located, where a miss is an instance of a class different from that of the randomly chosen instance. Each weight is updated by subtracting the difference between the given attribute of the randomly chosen instance and that of the nearest hit and adding the corresponding difference between the chosen instance and all the nearest misses weighted by the prior probabilities of their classes. If the distance between the attribute of the randomly chosen instance and the nearest hit equals the corresponding value for the nearest miss(es) then the weight value will not change, it will thus remain 0 given that the current iteration is the first one. If the difference between the attribute of the chosen instance and the nearest hit is lower than the corresponding value for the miss(es) then the weight value will be increased. On average highly significant attributes will result in absolute values distinct from 0, leading to an absolute increase of the weight, and insignificant attributes will on average result in values near 0, retaining the pessimistic view that all features are of no value as predictors.") NORMAL (U"The implementation of R\\s{ELIEF-F} found in Praat differs slightly from the algorithm described. Instances are not randomly chosen, instead all instances are used to update the weight vector. This simplification is of no concern unless massive data sets are used, in which case the Praat approach would be no less precise, but needlessly slow.") MAN_END MAN_BEGIN (U"kNN classifiers 1.1.1.2. Wrapper-based feature weighting", U"Ola Söder", 20090123) NORMAL (U"The %%wrapper-based% %%feature weighting% algorithm implemented in Praat attempts to find the globally optimal feature weights by means of a greedy local search. The local neighbourhood is defined by a number of random seeds centered around a pivot seed. For each iteration of the algorithm the best performing seed is chosen to be the pivot of the next iteration. At the same time the maximum allowed distance between a seed and the pivot is decreased by a constant factor. Given a sufficient number of seeds and a small shrinkage factor the algorithm will on average home in on a good approximation of the global maximum.") NORMAL (U"Given reasonable parameter settings, the search algorithm on average gives good results without huge memory and CPU requirements. The strong point of the method, the ability to efficiently do a rather thorough search of the weight space, can, as mentioned in @@kNN classifiers 1.1.1. Feature weighting|section 1.1.1.@, lead to overfitting. One way of minimizing this problem is to constrain the algorithm by means of %%early stopping%. In Praat this is done in a very naive fashion, by simply not allowing the algorithm to explore weights achieving an accuracy higher than a specified threshold value.") MAN_END MAN_BEGIN (U"kNN classifiers 1.1.2. Model selection", U"Ola Söder", 20080529) NORMAL (U"%%Model selection% is the process of choosing classifier parameters suitable for the classification task at hand. In most cases this is done manually in an experimental fashion.") NORMAL (U"The search for the optimal model can also be automated. In Praat this is done by means of the same @@kNN classifiers 1.1.1.2. Wrapper-based feature weighting|greedy local search algorithm@ used to search the weight space for feature weights. The %%model selection% search implementation in Praat lets the user limit the search space with respect to the parameter %k. By setting a maximum allowed value of %k the search space can be shrunk considerably.") NORMAL (U"Due to its discrete (%k) and nominal (vote weighting) nature, the size of the search space is normally of no concern, making an experimental/manual search tractable. The %%model selection% feature of Praat becomes an essential tool only when applied to huge instance bases where the expected optimal value of %k is high. In most cases however, manual experimenting will suffice.") MAN_END MAN_BEGIN (U"kNN classifiers 1.2. Improving resource efficiency", U"Ola Söder", 20080529) NORMAL (U"%%Instance-based% learners such as the %%k%NN classifier implemented in Praat are fairly inefficient as far as CPU and memory usage is concerned. The performance can be improved upon by making sure that only those instances that are vital for the accuracy of the classifier are stored and that non-vital instances are disposed of. Praat does give the user the possibility to prune non-vital or harmful instances, making the resulting classifier less memory and CPU hungry and in some cases more accurate even though that is not the primary objective of the pruning algorithm.") MAN_END MAN_BEGIN (U"kNN classifiers 1.2.1. Pruning", U"Ola Söder", 20080529) NORMAL (U"Pruning is the process of discarding instances that do not improve upon the classification accuracy of the classifier. This group of instances includes noisy instances that, at best, make no difference as far as model accuracy is concerned, at worst, induces classification errors. It also includes instances that are redundant; instances that are implied by the defined neighbourhood.") ENTRY (U"The C-Pruner algorithm") NORMAL (U"The C-Pruner algorithm such as it is presented in @@Ke-Ping Zhao et al. (2003)|Zhao et al. (2003)@ identifies pruning candidates and computes the order in which these candidates shall be removed. The ordering is of vital importance since the removal of one candidate might disqualify other candidates, making them non-prunable. In order to understand how the C-Pruner algorithm operates a few definitions are necessary:") LIST_ITEM (U"\\bu The %k-reachability set of an instance %p consists of the %k nearest neighbours of %p") LIST_ITEM (U"\\bu The %k-coverage set of an instance %p consists of those instances of the same class as that of %p having %p as one of their %k nearest neighbours.") LIST_ITEM (U"\\bu An instance %p is superfluous if it is implied by %k-reachability, that is, if it can be correctly classified using %k-reachability as instance base.") LIST_ITEM (U"\\bu An instance %p is critical if at least one instance in the %k-coverage set of %p is not implied by the %k-reachability set of %p or, after %p is deleted, atleast one instance in the %k-coverage set of %p is not implied by the %k-reachability set of %p.") LIST_ITEM (U"\\bu An instance %p is noisy if %p isn't superfluous and the %k-reachability set of %p is bigger than the %k-coverage set of %p.") NORMAL (U"Given these definitions, an instance is tagged for pruning if one of the following conditions hold: It is noisy, or it is superfluous but not critical. This translates to the discarding of instances that are bad class predictors (noise) and of instances that are highly typical of their class and thus are located close to the center of the cluster defining the given class. Instances located close to the class center are very likely implied by the surrounding border instances and thus redundant. In order to avoid destructive domino effects it is important that the pruning starts close to the center of the cluster and works its way out and not the other way around. To impose this ordering the C-Pruner algorithm uses the following heuristics to determine the order of removal of two superfluous instances %p__i_ and %p__j_:") LIST_ITEM (U"\\bu If the %k-reachability set of %p__i_ contains more instances of the same class as that of %p__i_ than the corresponding value for %p__j_ then %p__i_ should be removed before %p__j_.") LIST_ITEM (U"\\bu If the %k-reachability set of %p__i_ contains the same number of instances of the same class as that of %p__i_ as the corresponding value for %p__j_ and the distance between %p__i_ and the closest instance of a class different from the class of %p__i_ is greater than the corresponding value for %p__j_ then %p__i_ should be removed before %p__j_.") LIST_ITEM (U"\\bu If the %k-reachability set of %p__i_ contains the same number of instances of the same class as that of %p__i_ as the corresponding value for %p__j_ and the distance between %p__i_ and the closest instance of a class different from the class of %p__i_ equals the corresponding value for %p__j_ then the order of removal is decided randomly.") NORMAL (U"In order to gain control of the degree of pruning the Praat implementation of the C-Pruner algorithm decides whether to prune or not prune a given instance tagged for pruning on a probabilistic basis. This makes it possible for the user to specify the hardness of the pruning process (e.g. 100 percent (exp.) noise, 50 percent (exp.) redundancy) to be able to find a good compromise between model accuracy and resource requirements.") MAN_END MAN_BEGIN (U"kNN classifiers 2. Quick start", U"Ola Söder", 20080809) ENTRY (U"An example: Learning the Iris data set") NORMAL (U"In the @@Feedforward neural networks|the feedforward neural networks tutorial@ a description of how the @FFNet classifier in Praat can be applied to @@iris data set|the Iris data set@ can be found.") NORMAL (U"The same data can be used to test the %%k%NN feature of Praat. To do so create an example data set using the @@Create iris example...@ command found in the ##Neural nets# submenu. The form prompting for network topology settings can be ignored by selecting OK. Select the newly created @Pattern and @Categories objects and click ##To KNN Classifier...#. A form prompting for a name of the classifier to be created will be shown. The ordering in which instances are to be inserted into the instance base can also be specified, make sure that #Random is selected and thereafter close the form by selecting OK. The newly created and trained classifier will be shown in the list of objects.") NORMAL (U"To estimate how well the classifier can be expected to classify new samples of Irises select ##Query -# \\=> ##Get accuracy estimate...#. A form prompting for %%k%NN parameter settings and evaluation method will be shown. Experiment with the parameter settings until satisfactory results are achieved. If everything worked out the estimate will likely end up somewhere in the range of 94-98 percent.") NORMAL (U"An alternative to manually experimenting with model parameters is to let the computer do the job. This is done be choosing the @KNN object and thereafter selecting ##Query -# \\=> ##Get optimized parameters...#. The form shown prompts for a selection of parameters controlling the search. The default values will in most cases, including this, be appropriate.") NORMAL (U"Another way of improving classification accuracy is to transform the instance space in which the individual instances, in this case Irises, are stored as to maximize the distance between instances of different classes and minimize the distance between instances of the same class. This can be done by means of feature weighting. To do so select the @KNN object and choose ##To FeatureWeights...#. Adjust the %%k%NN settings according to the ones found by the model search algorithm and let the remaining options retain the default values. Click OK. A @FeatureWeights object will be added to the objects list. The feature weights contained within the newly created object can be used by selecting named object in conjunction with the @KNN classifier and thereafter choosing the desired action.") MAN_END MAN_BEGIN (U"k-means clustering", U"Ola Söder", 20080529) INTRO (U"This tutorial describes the use of %%k%-means clustering in Praat. ") NORMAL (U"@@k-means clustering 1. How does k-means clustering work?|1. How does k-means clustering work?@") NORMAL (U"@@k-means clustering 2. Quick start|2. Quick start@") MAN_END MAN_BEGIN (U"k-means clustering 1. How does k-means clustering work?", U"Ola Söder", 20080529) NORMAL (U"The %%k%-means clustering algorithm attempts to split a given anonymous data set (a set containing no information as to class identity) into a fixed number (%k) of clusters.") NORMAL (U"Initially %k number of so called %centroids are chosen. A %centroid is a data point (imaginary or real) at the center of a cluster. In Praat each centroid is an existing data point in the given input data set, picked at random, such that all %centroids are unique (that is, for all %centroids %c__%i_ and %c__%j_, %c__%i_ \\=/ %c__%j_). These %centroids are used to train a @@kNN classifiers 1. What is a kNN classifier?|kNN classifier@. The resulting classifier is used to classify (using %k = 1) the data and thereby produce an initial randomized set of clusters. Each %centroid is thereafter set to the arithmetic mean of the cluster it defines. The process of classification and %centroid adjustment is repeated until the values of the %centroids stabilize. The final %centroids will be used to produce the final classification/clustering of the input data, effectively turning the set of initially anonymous data points into a set of data points, each with a class identity.") MAN_END MAN_BEGIN (U"k-means clustering 2. Quick start", U"Ola Söder", 20080529) NORMAL (U"Clustering using the %%k%-means clustering algorithm in Praat is done by selecting a @Pattern and choosing ##To Categories...#. In the appearing requester the number of sought after clusters (unique categories) can be specified. The cluster size ratio constraint (%z) imposes a constraint on the output such that %cluster size(%x) / %cluster size(%y) > %z for all clusters %x and %y in the resulting set of clusters. Valid values of %z are 0 < %z <= 1 where values near 0 imposes practically no constraints on the cluster sizes and a value of 1 tells the algorithm to attempt to create clusters of equal size. The size ratio constraint is enforced in a very naive fashion, by random reseeding. Since this can be a rather time consuming process it is possible to set an upper bound on the number of reseeds done by the algorithm. This upper bound is defined by the parameter ##Maximum number of reseeds#. It should be noted however that normally there's no need to use the size ratio constraint, selecting the desired number of clusters will, on average, result in clusters of roughly equal size, given well distributed data.") MAN_END MAN_BEGIN (U"Pattern to Dissimilarity", U"Ola Söder", 20080529) NORMAL (U"A @Dissimilarity matrix can be used in conjunction with @@Multidimensional scaling|Multidimensional scaling@ to aid visualization of high-dimensional data. A @Dissimilarity object is a matrix of the distances, according to the chosen @@Euclidean distance|distance function@, between all the data points in the @Pattern object.") NORMAL (U"A @Dissimilarity object can be created by selecting a @Pattern object and choosing ##To Dissimilarity#. The dissimilarity matrix can also be computed using feature weights. This is done by selecting a @Pattern object, an @FeatureWeights object and choosing ##To Dissimilarity#.") MAN_END MAN_BEGIN (U"Euclidean distance", U"Ola Söder", 20080529) NORMAL (U"The Euclidean distance between the %n-dimensional vectors %a and %b can be calculated as follows:") FORMULA (U"\\De__Euclidean_(%x,%y) = \\Vr(\\su__%i=1..%n_(%a__%i_ - %b__%I_)^2)") MAN_END MAN_BEGIN (U"kNN classifiers 3. Command overview", U"Ola Söder", 20080809 ) INTRO (U"KNN commands") ENTRY (U"Creation:") LIST_ITEM (U"\\bu @@Pattern & Categories: To KNN classifier...@") LIST_ITEM (U"\\bu @@Create KNN...@") ENTRY (U"Learning:") LIST_ITEM (U"\\bu @@KNN & Pattern & Categories: Learn...@") ENTRY (U"Classification:") LIST_ITEM (U"\\bu @@KNN & Pattern: To Categories...@") LIST_ITEM (U"\\bu @@KNN & Pattern: To TabelOfReal...@") LIST_ITEM (U"\\bu @@KNN & Pattern & FeatureWeights: To Categories...@") LIST_ITEM (U"\\bu @@KNN & Pattern & FeatureWeights: To TableOfReal...@") ENTRY (U"Evaluation:") LIST_ITEM (U"\\bu @@KNN & Pattern & Categories: Evaluate...@") LIST_ITEM (U"\\bu @@KNN & Pattern & Categories & FeatureWeights: Evaluate...@") ENTRY (U"Queries") LIST_ITEM (U"\\bu @@KNN: Get optimized parameters...@") LIST_ITEM (U"\\bu @@KNN: Get accuracy estimate...@") LIST_ITEM (U"\\bu @@KNN & FeatureWeights: Get accuracy estimate...@") LIST_ITEM (U"\\bu @@KNN: Get size of instance base@") ENTRY (U"Extractions") LIST_ITEM (U"\\bu @@KNN: Extract input Pattern@") LIST_ITEM (U"\\bu @@KNN: Extract output Categories@") ENTRY (U"Modification:") LIST_ITEM (U"\\bu @@KNN: Shuffle@") LIST_ITEM (U"\\bu @@KNN: Prune...@") LIST_ITEM (U"\\bu @@KNN: Reset...@") ENTRY (U"Miscellaneous:") LIST_ITEM (U"\\bu @@KNN: To FeatureWeights...@") LIST_ITEM (U"\\bu @@KNN & Pattern & Categories: To FeatureWeights...@") LIST_ITEM (U"\\bu @@Pattern & Categories: To FeatureWeights...@") ENTRY (U"Pre/post processing:") LIST_ITEM (U"\\bu @@Pattern: To Categories...@") LIST_ITEM (U"\\bu @@Pattern & FeatureWeights: To Categories...@") LIST_ITEM (U"\\bu @@Pattern: To Dissimilarity...@") LIST_ITEM (U"\\bu @@Pattern & FeatureWeights: To Dissimilarity...@") MAN_END MAN_BEGIN (U"Pattern & Categories: To KNN classifier...", U"Ola Söder", 20080726 ) INTRO (U"Create and train a @KNN classifier using the selected @Pattern and @Categories objects as training data.") ENTRY (U"Settings") TAG (U"##Name")\ DEFINITION (U"The name of the @KNN classifier.") ENTRY (U"See also:") LIST_ITEM (U"@@kNN classifiers@") LIST_ITEM (U"@@kNN classifiers 1. What is a kNN classifier?@") MAN_END MAN_BEGIN (U"Create KNN...", U"Ola Söder", 20080718 ) INTRO (U"Create a new @KNN classifier.") ENTRY (U"Settings") TAG (U"##Name") DEFINITION (U"The name of the classifier.") ENTRY (U"See also:") LIST_ITEM (U"@@kNN classifiers@") MAN_END MAN_BEGIN (U"KNN & Pattern & Categories: Learn...", U"Ola Söder", 20080726 ) INTRO (U"Train the selected @KNN classifier using the chosen @Pattern and @Categories objects as training data.") ENTRY (U"Settings") TAG (U"##Name") DEFINITION (U"The name of the classifier.") TAG (U"##Ordering") DEFINITION (U"The order in which the training instances are to be inserted into the instance base.") ENTRY (U"See also:") LIST_ITEM (U"@@kNN classifiers@") LIST_ITEM (U"@@kNN classifiers 1. What is a kNN classifier?@") MAN_END MAN_BEGIN (U"KNN & Pattern: To Categories...", U"Ola Söder", 20080726 ) INTRO (U"Use the selected @KNN classifier to classify the chosen @Pattern. A @Categories object containing the result will be created.") ENTRY (U"Settings") TAG (U"##k neighbours") DEFINITION (U"The size of the neighbourhood.") TAG (U"##Vote weighting") DEFINITION (U"The type of vote weighting to be used.") ENTRY (U"See also:") LIST_ITEM (U"@@kNN classifiers@") LIST_ITEM (U"@@kNN classifiers 1. What is a kNN classifier?@") MAN_END MAN_BEGIN (U"KNN & Pattern: To TabelOfReal...", U"Ola Söder", 20080718 ) INTRO (U"Use the selected @KNN classifier to classify the chosen @Pattern. A @TableOfReal object containing verbose information on the decision process will be created.") ENTRY (U"Settings") TAG (U"##k neighbours") DEFINITION (U"The size of the neighbourhood.") TAG (U"##Vote weighting") DEFINITION (U"The type of vote weighting to be used.") TAG (U"##Output") DEFINITION (U"Specifies the degree of verbosity, where %%winners only% generates a @TableOfReal containing information on the instances of the winning category only whereas %%All candidates% results in a @TableOfReal with verbose information on all unique categories in the neighbourhood defined by the parameter %k.") ENTRY (U"See also:") LIST_ITEM (U"@@kNN classifiers@") LIST_ITEM (U"@@kNN classifiers 1. What is a kNN classifier?@") MAN_END MAN_BEGIN (U"KNN & Pattern & FeatureWeights: To Categories...", U"Ola Söder", 20080726 ) INTRO (U"Use the selected @KNN classifier and @FeatureWeights object to classify the chosen @Pattern. A @Categories object containing the result will be created.") ENTRY (U"Settings") TAG (U"##k neighbours") DEFINITION (U"The size of the neighbourhood.") TAG (U"##Vote weighting") DEFINITION (U"The type of vote weighting to be used.") ENTRY (U"See also:") LIST_ITEM (U"@@kNN classifiers 1.1.1. Feature weighting@") LIST_ITEM (U"@@kNN classifiers 1.1.1.1. Filter-based feature weighting@") LIST_ITEM (U"@@kNN classifiers 1.1.1.2. Wrapper-based feature weighting@") LIST_ITEM (U"@@kNN classifiers 1.1. Improving classification accuracy@") LIST_ITEM (U"@@kNN classifiers 1. What is a kNN classifier?@") LIST_ITEM (U"@@kNN classifiers@") MAN_END MAN_BEGIN (U"KNN & Pattern & FeatureWeights: To TableOfReal...", U"Ola Söder", 20080718 ) INTRO (U"Use the selected @KNN classifier and the feature weights, @FeatureWeights, to classify the chosen @Pattern. A @TableOfReal object containing verbose information on the decision process will be created.") ENTRY (U"Settings") TAG (U"##k neighbours") DEFINITION (U"The size of the neighbourhood.") TAG (U"##Vote weighting") DEFINITION (U"The type of vote weighting to be used.") TAG (U"##Output") DEFINITION (U"Specifies the degree of verbosity, where %%winners only% generates a @TableOfReal containing information on the instances of the winning category only whereas %%All candidates% results in a @TableOfReal with verbose information on all unique categories in the neighbourhood defined by the parameter %k.") ENTRY (U"See also:") LIST_ITEM (U"@@kNN classifiers 1.1.1. Feature weighting@") LIST_ITEM (U"@@kNN classifiers 1.1.1.1. Filter-based feature weighting@") LIST_ITEM (U"@@kNN classifiers 1.1.1.2. Wrapper-based feature weighting@") LIST_ITEM (U"@@kNN classifiers 1.1. Improving classification accuracy@") LIST_ITEM (U"@@kNN classifiers 1. What is a kNN classifier?@") LIST_ITEM (U"@@kNN classifiers@") MAN_END MAN_BEGIN (U"KNN: Get optimized parameters...", U"Ola Söder", 20080718 ) INTRO (U"Perform an automated search for the optimal @KNN parameter settings.") ENTRY (U"Settings") TAG (U"##Evaluation method") DEFINITION (U"The method to be used for estimating the classification accuracy, which in turn is used to guide the model search. " "Supported methods are 10-fold cross-validation and leave-one-out.") TAG (U"##k max") DEFINITION (U"The maximum value of the parameter %k.") TAG (U"##Number of seeds") DEFINITION (U"The size of the parameter neighbourhood to be searched.") TAG (U"##Learning rate") DEFINITION (U"The rate at which the parameter neighbourhood is shrunk (per iteration).") ENTRY (U"See also:") LIST_ITEM (U"@@kNN classifiers 1.1.2. Model selection@") LIST_ITEM (U"@@kNN classifiers 1.1. Improving classification accuracy@") LIST_ITEM (U"@@kNN classifiers 1. What is a kNN classifier?@") LIST_ITEM (U"@@kNN classifiers@") MAN_END MAN_BEGIN (U"KNN: Get accuracy estimate...", U"Ola Söder", 20080718 ) INTRO (U"Estimate the classification accuracy of the selected @KNN classifier.") ENTRY (U"Settings") TAG (U"##Evaluation method") DEFINITION (U"The method to be used for estimating the classification accuracy. Supported methods are 10-fold cross-validation and leave-one-out.") TAG (U"##k neighbours") DEFINITION (U"The size of the neighbourhood.") TAG (U"##Vote weighting") DEFINITION (U"The type of vote weighting to be used.") ENTRY (U"See also:") LIST_ITEM (U"@@KNN & FeatureWeights: Get accuracy estimate...@") LIST_ITEM (U"@@KNN & Pattern & Categories: Evaluate...@") LIST_ITEM (U"@@KNN & Pattern & Categories & FeatureWeights: Evaluate...@") LIST_ITEM (U"@@kNN classifiers 1.1. Improving classification accuracy@") LIST_ITEM (U"@@kNN classifiers 1.1.1. Feature weighting@") LIST_ITEM (U"@@kNN classifiers 1.1.2. Model selection@") LIST_ITEM (U"@@kNN classifiers@") MAN_END MAN_BEGIN (U"KNN & FeatureWeights: Get accuracy estimate...", U"Ola Söder", 20080809) INTRO (U"Estimate the classification accuracy of the @KNN classifier using the chosen @FeatureWeights.") ENTRY (U"Settings") TAG (U"##Evaluation method") DEFINITION (U"The method to be used for estimating the classification accuracy. " "Supported methods are 10-fold cross-validation and leave-one-out.") TAG (U"##k neighbours") DEFINITION (U"The size of the neighbourhood.") TAG (U"##Vote weighting") DEFINITION (U"The type of vote weighting to be used.") ENTRY (U"See also:") LIST_ITEM (U"@@KNN & Pattern & Categories: Evaluate...@") LIST_ITEM (U"@@KNN & Pattern & Categories & FeatureWeights: Evaluate...@") LIST_ITEM (U"@@kNN classifiers 1.1. Improving classification accuracy@") LIST_ITEM (U"@@kNN classifiers 1.1.1. Feature weighting@") LIST_ITEM (U"@@kNN classifiers 1.1.2. Model selection@") LIST_ITEM (U"@@kNN classifiers@") MAN_END MAN_BEGIN (U"KNN & Pattern & Categories: Evaluate...", U"Ola Söder", 20080718) INTRO (U"Estimate the classification accuracy of the chosen @KNN classifier using the selected @Pattern and @Categories objects as test set.") ENTRY (U"Settings") TAG (U"##k neighbours") DEFINITION (U"The size of the neighbourhood.") TAG (U"##Vote weighting") DEFINITION (U"The type of vote weighting to be used.") ENTRY (U"See also:") LIST_ITEM (U"@@KNN & Pattern & Categories & FeatureWeights: Evaluate...@") LIST_ITEM (U"@@KNN: Get accuracy estimate...@") LIST_ITEM (U"@@kNN classifiers 1.1. Improving classification accuracy@") LIST_ITEM (U"@@kNN classifiers 1.1.1. Feature weighting@") LIST_ITEM (U"@@kNN classifiers 1.1.2. Model selection@") LIST_ITEM (U"@@kNN classifiers@") MAN_END MAN_BEGIN (U"KNN & Pattern & Categories & FeatureWeights: Evaluate...", U"Ola Söder", 20080718) INTRO (U"Estimate the classification accuracy of the chosen @KNN classifier using the selected @Pattern and @Categories objects as test set. The selected @FeatureWeights object will be used in the classification process.") ENTRY (U"Settings") TAG (U"##k neighbours") DEFINITION (U"The size of the neighbourhood.") TAG (U"##Vote weighting") DEFINITION (U"The type of vote weighting to be used.") ENTRY (U"See also:") LIST_ITEM (U"@@KNN & Pattern & Categories: Evaluate...@") LIST_ITEM (U"@@KNN: Get accuracy estimate...@") LIST_ITEM (U"@@kNN classifiers 1.1. Improving classification accuracy@") LIST_ITEM (U"@@kNN classifiers 1.1.1. Feature weighting@") LIST_ITEM (U"@@kNN classifiers 1.1.2. Model selection@") LIST_ITEM (U"@@kNN classifiers@") MAN_END MAN_BEGIN (U"KNN: Get size of instance base", U"Ola Söder", 20080718) INTRO (U"Queries the selected @KNN for the number of instances in the instance base. ") ENTRY (U"See also:") LIST_ITEM (U"@@kNN classifiers@") MAN_END MAN_BEGIN (U"KNN: Extract input Pattern", U"Ola Söder", 20080726) INTRO (U"Create a new @Pattern object identical to the one in the instance base of the selected @KNN classifier.") ENTRY (U"See also:") LIST_ITEM (U"@@kNN classifiers@") MAN_END MAN_BEGIN (U"KNN: Extract output Categories", U"Ola Söder", 20080726) INTRO (U"Create a new @Categories object identical to the one in the instance base of the selected @KNN classifier.") ENTRY (U"See also:") LIST_ITEM (U"@@kNN classifiers@") MAN_END MAN_BEGIN (U"KNN: Shuffle", U"Ola Söder", 20080718) INTRO (U"Shuffle the instance base of the selected classifier.") ENTRY (U"See also:") LIST_ITEM (U"@@kNN classifiers@") MAN_END MAN_BEGIN (U"KNN: Prune...", U"Ola Söder", 20080718) INTRO (U"Prune the instance base of the selected classifier.") ENTRY (U"Settings") TAG (U"##Noise pruning degree") DEFINITION (U"A value in the range [0 ... 1] specifying the probability that instances tagged as noisy by @@kNN classifiers 1.2.1. Pruning|the C-Pruner algorithm@ will be pruned.") TAG (U"##Redundancy pruning degree") DEFINITION (U"The probability that instances tagged as redundant by @@kNN classifiers 1.2.1. Pruning|the C-Pruner algorithm@ will be pruned.") TAG (U"##k neighbours") DEFINITION (U"The size of the neighbourhood.") ENTRY (U"See also:") LIST_ITEM (U"@@kNN classifiers 1.2.1. Pruning@") LIST_ITEM (U"@@kNN classifiers 1.2. Improving resource efficiency@") LIST_ITEM (U"@@kNN classifiers@") MAN_END MAN_BEGIN (U"KNN: Reset...", U"Ola Söder", 20080718) INTRO (U"Empty the instance base of the selected classifier.") ENTRY (U"See also:") LIST_ITEM (U"@@kNN classifiers@") MAN_END MAN_BEGIN (U"KNN: To FeatureWeights...", U"Ola Söder", 20080728) INTRO (U"Wrap the selected @KNN and use its feedback to guide the search for the optimal feature weights. A @FeatureWeights object will be created.") ENTRY (U"Settings") TAG (U"##Learning rate") DEFINITION (U"The rate at which the maximum distance between the pivot and a random seed is decremented.") TAG (U"##Number of seeds") DEFINITION (U"The size of the feature weight neighbourhood.") TAG (U"##Stop at") DEFINITION (U"A value specifying a stopping criterion. When feature weights yielding accuracy estimates higher than the specified value the search will stop. A value of 1 imposes no constraints whereas a value of 0.5 will result in the termination of the search algorithm once feature weights resulting in an classification accuracy of 50 percent or better are found.") TAG (U"##Optimization") DEFINITION (U"Specifies whether to search for all features simultaneously or one at a time.") TAG (U"##Evaluation method") DEFINITION (U"The method to be used for estimating the classification accuracy. Supported methods are 10-fold cross-validation and leave-one-out.") TAG (U"##k neighbours") DEFINITION (U"The size of the neighbourhood used for feedback classification.") TAG (U"##Vote weighting") DEFINITION (U"The type of vote weighting to be used.") ENTRY (U"See also:") LIST_ITEM (U"@@kNN classifiers 1.1.1.2. Wrapper-based feature weighting@") LIST_ITEM (U"@@kNN classifiers 1.1.1. Feature weighting@") LIST_ITEM (U"@@kNN classifiers 1.1. Improving classification accuracy@") LIST_ITEM (U"@@KNN & Pattern & Categories & FeatureWeights: Evaluate...@") LIST_ITEM (U"@@kNN classifiers 1. What is a kNN classifier?@") LIST_ITEM (U"@@kNN classifiers@") MAN_END MAN_BEGIN (U"KNN & Pattern & Categories: To FeatureWeights...", U"Ola Söder", 20080809) INTRO (U"Wrap the selected @KNN and use its classification accuracy on the test set constituted by the @Pattern and @Categories objects as feedback to guide the search for the optimal feature weights. A @FeatureWeights object will be created.") ENTRY (U"Settings") TAG (U"##Learning rate") DEFINITION (U"The rate at which the maximum distance between the pivot and a random seed is decremented.") TAG (U"##Number of seeds") DEFINITION (U"The size of the feature weight neighbourhood.") TAG (U"##Stop at") DEFINITION (U"A value specifying a stopping criterion. When feature weights yielding accuracy estimates higher than the specified value the search will stop. A value of 1 imposes no constraints whereas a value of 0.5 will result in the termination of the search algorithm once feature weights resulting in an classification accuracy of 50 percent or better are found.") TAG (U"##Optimization") DEFINITION (U"Specifies whether to search for all features simultaneously or one at a time.") TAG (U"##k neighbours") DEFINITION (U"The size of the neighbourhood used for feedback classification.") TAG (U"##Vote weighting") DEFINITION (U"The type of vote weighting to be used.") ENTRY (U"See also:") LIST_ITEM (U"@@kNN classifiers 1.1.1.2. Wrapper-based feature weighting@") LIST_ITEM (U"@@kNN classifiers 1.1.1. Feature weighting@") LIST_ITEM (U"@@kNN classifiers 1.1. Improving classification accuracy@") LIST_ITEM (U"@@KNN & Pattern & Categories & FeatureWeights: Evaluate...@") LIST_ITEM (U"@@kNN classifiers 1. What is a kNN classifier?@") LIST_ITEM (U"@@kNN classifiers@") MAN_END MAN_BEGIN (U"Pattern & Categories: To FeatureWeights...", U"Ola Söder", 20080809) INTRO (U"Compute an estimate of the optimal feature weights using the @@kNN classifiers 1.1.1.1. Filter-based feature weighting|RELIEF-F algorithm@.") ENTRY (U"Setting") TAG (U"##k neighbours") DEFINITION (U"The size of the neighbourhood.") ENTRY (U"See also:") LIST_ITEM (U"@@kNN classifiers 1.1.1.1. Filter-based feature weighting@") LIST_ITEM (U"@@kNN classifiers 1.1.1.2. Wrapper-based feature weighting@") LIST_ITEM (U"@@kNN classifiers@") MAN_END MAN_BEGIN (U"Pattern: To Categories...", U"Ola Söder", 20080728) INTRO (U"Split the given @Pattern into a fixed number of clusters using the @@k-means clustering|%%k%-means clustering algorithm@. A @Categories object containing numbered categories corresponding to the generated clusters will be created.") ENTRY (U"Settings") TAG (U"##k clusters") DEFINITION (U"The number of clusters to be generated.") TAG (U"##Cluster size ratio constraint") DEFINITION (U"The minimum allowed ratio between the smallest and the biggest cluster.") TAG (U"##Maximum number of reseeds") DEFINITION (U"The maximum allowed number of reseeds used to enforce the cluster size ratio constraint.") ENTRY (U"See also:") LIST_ITEM (U"@@kNN classifiers@") MAN_END MAN_BEGIN (U"Pattern & FeatureWeights: To Categories...", U"Ola Söder", 20080728) INTRO (U"Split the given @Pattern into a fixed number of clusters using the @@k-means clustering|%%k%-means clustering algorithm@ and the feature weights contained within the selected @FeatureWeights object. A @Categories object containing numbered categories corresponding to the generated clusters will be created.") ENTRY (U"Settings") TAG (U"##k clusters") DEFINITION (U"The number of clusters to be generated.") TAG (U"##Cluster size ratio constraint") DEFINITION (U"The minimum allowed ratio between the smallest and the biggest cluster.") TAG (U"##Maximum number of reseeds") DEFINITION (U"The maximum allowed number of reseeds used to enforce the cluster size ratio constraint.") ENTRY (U"See also:") LIST_ITEM (U"@@kNN classifiers@") LIST_ITEM (U"@@kNN classifiers 1.1.1. Feature weighting@") MAN_END MAN_BEGIN (U"Pattern: To Dissimilarity...", U"Ola Söder", 20080718) INTRO (U"Generate a @Dissimilarity matrix from the selected @Pattern. Dissimilarities are computed using the @@Euclidean distance@") ENTRY (U"See also:") LIST_ITEM (U"@@Multidimensional scaling@") LIST_ITEM (U"@@kNN classifiers@") MAN_END MAN_BEGIN (U"Pattern & FeatureWeights: To Dissimilarity...", U"Ola Söder", 20080718) INTRO (U"Generate a @Dissimilarity matrix from the selected @Pattern using the feature weights contained within the selected @FeatureWeights object. Dissimilarities are computed using the @@Euclidean distance@.") ENTRY (U"See also:") LIST_ITEM (U"@@Multidimensional scaling@") LIST_ITEM (U"@@kNN classifiers 1.1.1. Feature weighting@") LIST_ITEM (U"@@kNN classifiers@") MAN_END MAN_BEGIN (U"Ke-Ping Zhao et al. (2003)", U"Ola Söder", 20080718) NORMAL (U"Ke-Ping Zhao et al. (2003): \"C-Pruner: An improved instance pruning algorithm.\" " "In %%Proceedings of the Second International Conference on Machine Learning and Cybernetics%, November 2003, 94\\--99.") MAN_END MAN_BEGIN (U"Igor Kononenko (1994)", U"Ola Söder", 20080718) NORMAL (U"Igor Kononenko (1994): \"Estimating attributes: Analysis and extensions of relief.\" " "In %%ECML-94: Proceedings of the European Conference on Machine Learning%, Secaucus, NJ, USA, 171\\--182. " "New York: Springer.") MAN_END } /* End of file manual_KNN.c */ praat-6.0.04/contrib/ola/praat_contrib_Ola_KNN.cpp000066400000000000000000001103601261542461700217700ustar00rootroot00000000000000/* praat_contrib_Ola_KNN.cpp * * Copyright (C) 2007-2009 Ola Söder, 2010-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * os 2007/05/29 Initial release? * os 2009/01/23 Bugfix: Removed MUX:ing (KNN_learn) incompatible with the scripting engine. Thanks to Paul Boersma for spotting this problem. * pb 2010/12/28 in messages: typos, English, interpunction * pb 2011/07/12 C++ and removed several errors * pb 2011/09/18 made a start with handling dataChanged at all */ #include "KNN.h" #include "KNN_threads.h" #include "KNN_prune.h" #include "Pattern_to_Categories_cluster.h" #include "FeatureWeights.h" #include "praat.h" static const char32 *QUERY_BUTTON = U"Query -"; static const char32 *MODIFY_BUTTON = U"Modify -"; static const char32 *EXTRACT_BUTTON = U"Extract -"; ///////////////////////////////////////////////////////////////////////////////////////// // KNN creations // ///////////////////////////////////////////////////////////////////////////////////////// FORM (KNN_create, U"Create kNN Classifier", U"kNN classifiers 1. What is a kNN classifier?") { WORD (U"Name", U"Classifier") OK2 DO autoKNN knn = KNN_create (); praat_new (knn.move(), GET_STRING (U"Name")); END2 } FORM (KNN_Pattern_Categories_to_KNN, U"Create kNN classifier", U"kNN classifiers 1. What is a kNN classifier?") { WORD (U"Name", U"Classifier") RADIO (U"Ordering", 1) RADIOBUTTON (U"Random") RADIOBUTTON (U"Sequential") OK2 DO iam_ONLY (Pattern); thouart_ONLY (Categories); int ordering = GET_INTEGER (U"Ordering"); autoKNN knn = KNN_create (); switch (ordering) { case 1: ordering = kOla_SHUFFLE; break; case 2: ordering = kOla_SEQUENTIAL; } int result = KNN_learn (knn.peek(), me, thee, kOla_REPLACE, ordering); switch (result) { case kOla_PATTERN_CATEGORIES_MISMATCH: Melder_throw (U"The number of Categories should be equal to the number of rows in Pattern."); case kOla_DIMENSIONALITY_MISMATCH: Melder_throw (U"The dimensionality of Pattern should be equal to that of the instance base."); default: praat_new (knn.move(), GET_STRING(U"Name")); } END2 } ///////////////////////////////////////////////////////////////////////////////////////// // KNN extractions, queries and modifications // ///////////////////////////////////////////////////////////////////////////////////////// DIRECT2 (KNN_getNumberOfInstances) { iam_ONLY (KNN); Melder_information (my nInstances, U" units"); END2 } FORM (KNN_getOptimumModel, U"kNN model selection", U"kNN classifiers 1.1.2. Model selection") { RADIO (U"Evaluation method", 1) RADIOBUTTON (U"Leave one out") RADIOBUTTON (U"10-fold cross-validation") INTEGER (U"k max", U"50") INTEGER (U"Number of seeds", U"10") POSITIVE (U"Learning rate", U"0.2") OK2 DO iam_ONLY (KNN); long k = GET_INTEGER (U"k max"); double lrate = GET_REAL (U"Learning rate"); if (k < 1 || k > my nInstances) Melder_throw (U"Please select a value of k max such that 0 < k max < ", my nInstances + 1, U"."); long nseeds = GET_INTEGER (U"Number of seeds"); if (nseeds < 1) Melder_throw (U"The number of seeds should exceed 1."); int mode = GET_INTEGER (U"Evaluation method"); switch (mode) { case 2: mode = kOla_TEN_FOLD_CROSS_VALIDATION; break; case 1: mode = kOla_LEAVE_ONE_OUT; break; } autoFeatureWeights fws = FeatureWeights_create ((my input) -> nx); int dist; KNN_modelSearch (me, fws.peek(), &k, &dist, mode, lrate, nseeds); switch (dist) { case kOla_SQUARED_DISTANCE_WEIGHTED_VOTING: Melder_information (U"Vote weighting: Inversed squared distance\n", U"k: ", k); break; case kOla_DISTANCE_WEIGHTED_VOTING: Melder_information (U"Vote weighting: Inversed distance\n", U"k: ", k); break; case kOla_FLAT_VOTING: Melder_information (U"Vote weighting: Flat\n", U"k: ", k); break; } END2 } FORM (KNN_evaluate, U"Evaluation", U"KNN: Get accuracy estimate...") { RADIO (U"Evaluation method", 1) RADIOBUTTON (U"Leave one out") RADIOBUTTON (U"10-fold cross-validation") INTEGER (U"k neighbours", U"1") RADIO (U"Vote weighting", 1) RADIOBUTTON (U"Inversed squared distance") RADIOBUTTON (U"Inversed distance") RADIOBUTTON (U"Flat") OK2 DO iam_ONLY (KNN); if (my nInstances < 1) Melder_throw (U"Instance base is empty."); long k = GET_INTEGER (U"k neighbours"); if (k < 1 || k > my nInstances) Melder_throw (U"Please select a value of k such that 0 < k < ", my nInstances + 1, U"."); int vt = GET_INTEGER (U"Vote weighting"); switch (vt) { case 1: vt = kOla_SQUARED_DISTANCE_WEIGHTED_VOTING; break; case 2: vt = kOla_DISTANCE_WEIGHTED_VOTING; break; case 3: vt = kOla_FLAT_VOTING; break; } int mode = GET_INTEGER (U"Evaluation method"); switch (mode) { case 2: mode = kOla_TEN_FOLD_CROSS_VALIDATION; break; case 1: mode = kOla_LEAVE_ONE_OUT; break; } autoFeatureWeights fws = FeatureWeights_create (my input -> nx); double result = KNN_evaluate (me, fws.peek(), k, vt, mode); if (lround (result) == kOla_FWEIGHTS_MISMATCH) Melder_throw (U"The number of feature weights should be equal to the dimensionality of the Pattern."); Melder_information (100 * result, U" percent of the instances correctly classified."); // BUG: use Melder_percent END2 } FORM (KNN_evaluateWithFeatureWeights, U"Evaluation", U"KNN & FeatureWeights: Get accuracy estimate...") { RADIO (U"Evaluation method", 1) RADIOBUTTON (U"Leave one out") RADIOBUTTON (U"10-fold cross-validation") INTEGER (U"k neighbours", U"1") RADIO (U"Vote weighting", 1) RADIOBUTTON (U"Inversed squared distance") RADIOBUTTON (U"Inversed distance") RADIOBUTTON (U"Flat") OK2 DO iam_ONLY (KNN); if (my nInstances < 1) Melder_throw (U"Instance base is empty"); thouart_ONLY (FeatureWeights); long k = GET_INTEGER (U"k neighbours"); if (k < 1 || k > my nInstances) Melder_throw (U"Please select a value of k such that 0 < k < ", my nInstances + 1, U"."); int vt = GET_INTEGER (U"Vote weighting"); switch (vt) { case 1: vt = kOla_SQUARED_DISTANCE_WEIGHTED_VOTING; break; case 2: vt = kOla_DISTANCE_WEIGHTED_VOTING; break; case 3: vt = kOla_FLAT_VOTING; break; } int mode = GET_INTEGER (U"Evaluation method"); switch (mode) { case 2: mode = kOla_TEN_FOLD_CROSS_VALIDATION; break; case 1: mode = kOla_LEAVE_ONE_OUT; break; } double result = KNN_evaluate (me, thee, k, vt, mode); if (lround (result) == kOla_FWEIGHTS_MISMATCH) Melder_throw (U"The number of feature weights should be equal to the dimensionality of the Pattern."); Melder_information (100 * result, U" percent of the instances correctly classified."); END2 } DIRECT2 (KNN_extractInputPatterns) { iam_ONLY (KNN); if (my nInstances <= 0) Melder_throw (U"Instance base is empty."); autoPattern input = Data_copy (my input); praat_new (input.move(), U"Input Patterns"); END2 } DIRECT2 (KNN_extractOutputCategories) { iam_ONLY (KNN); if (my nInstances <= 0) Melder_throw (U"Instance base is empty."); autoCategories output = Data_copy (my output); praat_new (output.move(), U"Output Categories"); END2 } FORM (KNN_reset, U"Reset", U"KNN: Reset...") { LABEL (U"", U"Warning: this command destroys all previous learning.") OK2 DO iam_ONLY (KNN); forget (my input); forget (my output); my nInstances = 0; praat_dataChanged (me); // BUG: this should be inserted much more often END2 } DIRECT2 (KNN_shuffle) { iam_ONLY (KNN); if (my nInstances <= 0) Melder_throw (U"Instance base is empty."); KNN_shuffleInstances (me); END2 } FORM (KNN_prune, U"Pruning", U"KNN: Prune...") { POSITIVE (U"Noise pruning degree", U"1") POSITIVE (U"Redundancy pruning degree", U"1") INTEGER (U"k neighbours", U"1") OK2 DO iam_ONLY (KNN); if (my nInstances <= 0) Melder_throw (U"Instance base is empty."); long oldn = my nInstances; // save before it changes! long k = GET_INTEGER (U"k neighbours"); if (k < 1 || k > my nInstances) Melder_throw (U"Please select a value of k such that 0 < k < ", my nInstances + 1, U"."); double n = GET_REAL (U"Noise pruning degree"); double r = GET_REAL (U"Redundancy pruning degree"); if (n <= 0 || n > 1 || r <= 0 || r > 1) Melder_throw (U"Please select a pruning degree d such that 0 < d <= 1."); long npruned = KNN_prune_prune (me, n, r, k); Melder_information (npruned, U" instances discarded. \n", U"Size of new instance base: ", oldn - npruned); END2 } ///////////////////////////////////////////////////////////////////////////////////////// // Learning // ///////////////////////////////////////////////////////////////////////////////////////// FORM (KNN_learn, U"Learning", U"kNN classifiers 1. What is a kNN classifier?") { RADIO (U"Learning method", 1) RADIOBUTTON (U"Append new information") RADIOBUTTON (U"Replace current intancebase") RADIO (U"Ordering", 1) RADIOBUTTON (U"Random") RADIOBUTTON (U"Sequential") OK2 DO iam_ONLY (KNN); thouart_ONLY (Pattern); heis_ONLY (Categories); int ordering = GET_INTEGER (U"Ordering"); switch (ordering) { case 1: ordering = kOla_SHUFFLE; break; case 2: ordering = kOla_SEQUENTIAL; } int method = GET_INTEGER (U"Learning method"); int result = kOla_ERROR; switch (method) { case 1: result = KNN_learn (me, thee, him, my nInstances == 0 ? kOla_REPLACE : kOla_APPEND, ordering); break; case 2: result = KNN_learn (me, thee, him, kOla_REPLACE, ordering); break; } switch (result) { case kOla_PATTERN_CATEGORIES_MISMATCH: Melder_throw (U"The number of Categories should be equal to the number of rows in Pattern."); case kOla_DIMENSIONALITY_MISMATCH: Melder_throw (U"The dimensionality of Pattern should be equal to that of the instance base."); } END2 } ///////////////////////////////////////////////////////////////////////////////////////// // Evaluation // ///////////////////////////////////////////////////////////////////////////////////////// FORM (KNN_evaluateWithTestSet, U"Evaluation", U"KNN & Pattern & Categories: Evaluate...") { INTEGER (U"k neighbours", U"1") RADIO (U"Vote weighting", 1) RADIOBUTTON (U"Inversed squared distance") RADIOBUTTON (U"Inversed distance") RADIOBUTTON (U"Flat") OK2 DO iam_ONLY (KNN); if (my nInstances <= 0) Melder_throw (U"Instance base is empty"); thouart_ONLY (Pattern); heis_ONLY (Categories); long k = GET_INTEGER (U"k neighbours"); if (k < 1 || k > my nInstances) Melder_throw (U"Please select a value of k such that 0 < k < ", my nInstances + 1, U"."); int vt = GET_INTEGER (U"Vote weighting"); switch (vt) { case 1: vt = kOla_SQUARED_DISTANCE_WEIGHTED_VOTING; break; case 2: vt = kOla_DISTANCE_WEIGHTED_VOTING; break; case 3: vt = kOla_FLAT_VOTING; break; } if (thy ny != his size) Melder_throw (U"The number of Categories should be equal to the number of rows in Pattern."); if (thy nx != (my input)->nx) Melder_throw (U"The dimensionality of Pattern should be equal to that of the instance base."); autoFeatureWeights fws = FeatureWeights_create (thy nx); double result = KNN_evaluateWithTestSet (me, thee, him, fws.peek(), k, vt); Melder_information (100 * result, U" percent of the instances correctly classified."); END2 } FORM (KNN_evaluateWithTestSetAndFeatureWeights, U"Evaluation", U"KNN & Pattern & Categories & FeatureWeights: Evaluate...") { INTEGER (U"k neighbours", U"1") RADIO (U"Vote weighting", 1) RADIOBUTTON (U"Inversed squared distance") RADIOBUTTON (U"Inversed distance") RADIOBUTTON (U"Flat") OK2 DO iam_ONLY (KNN); if (my nInstances <= 0) Melder_throw (U"Instance base is empty"); Pattern p = (Pattern) ONLY (classPattern); Categories c = (Categories) ONLY (classCategories); FeatureWeights fws = (FeatureWeights) ONLY (classFeatureWeights); long k = GET_INTEGER (U"k neighbours"); if (k < 1 || k > my nInstances) Melder_throw (U"Please select a value of k such that 0 < k < ", my nInstances + 1, U"."); int vt = GET_INTEGER (U"Vote weighting"); switch (vt) { case 1: vt = kOla_SQUARED_DISTANCE_WEIGHTED_VOTING; break; case 2: vt = kOla_DISTANCE_WEIGHTED_VOTING; break; case 3: vt = kOla_FLAT_VOTING; break; } if (p -> ny != c -> size) Melder_throw (U"The number of Categories should be equal to the number of rows in Pattern."); if (p -> nx != my input -> nx) Melder_throw (U"The dimensionality of Pattern should be equal to that of the instance base."); if (p->nx != fws -> fweights -> numberOfColumns) Melder_throw (U"The number of feature weights should be equal to the dimensionality of the Pattern."); double result = KNN_evaluateWithTestSet (me, p, c, fws, k, vt); Melder_information (100 * result, U" percent of the instances correctly classified."); END2 } ///////////////////////////////////////////////////////////////////////////////////////// // Classification // ///////////////////////////////////////////////////////////////////////////////////////// FORM (KNN_toCategories, U"Classification", U"KNN & Pattern: To Categories...") { INTEGER (U"k neighbours", U"1") RADIO (U"Vote weighting", 1) RADIOBUTTON (U"Inversed squared distance") RADIOBUTTON (U"Inversed distance") RADIOBUTTON (U"Flat") OK2 DO iam_ONLY (KNN); if (my nInstances <= 0) Melder_throw (U"Instance base is empty."); thouart_ONLY (Pattern); long k = GET_INTEGER (U"k neighbours"); if (k < 1 || k > my nInstances) Melder_throw (U"Please select a value of k such that 0 < k < ", my nInstances + 1, U"."); int vt = GET_INTEGER (U"Vote weighting"); switch (vt) { case 1: vt = kOla_SQUARED_DISTANCE_WEIGHTED_VOTING; break; case 2: vt = kOla_DISTANCE_WEIGHTED_VOTING; break; case 3: vt = kOla_FLAT_VOTING; break; } if (thy nx != my input -> nx) Melder_throw (U"The dimensionality of Pattern should match that of the instance base."); autoFeatureWeights fws = FeatureWeights_create (thy nx); autoCategories result = KNN_classifyToCategories (me, thee, fws.peek(), k, vt); praat_new (result.move(), U"Output"); END2 } FORM (KNN_toTableOfReal, U"Classification", U"KNN & Pattern: To TabelOfReal...") { INTEGER (U"k neighbours", U"1") RADIO (U"Vote weighting", 1) RADIOBUTTON (U"Inversed squared distance") RADIOBUTTON (U"Inversed distance") RADIOBUTTON (U"Flat") OK2 DO iam_ONLY (KNN); if (my nInstances <= 0) Melder_throw (U"Instance base is empty."); thouart_ONLY (Pattern); long k = GET_INTEGER (U"k neighbours"); if (k < 1 || k > my nInstances) Melder_throw (U"Please select a value of k such that 0 < k < ", my nInstances + 1, U"."); autoFeatureWeights fws = FeatureWeights_create(thy nx); int vt = GET_INTEGER (U"Vote weighting"); switch (vt) { case 1: vt = kOla_SQUARED_DISTANCE_WEIGHTED_VOTING; break; case 2: vt = kOla_DISTANCE_WEIGHTED_VOTING; break; case 3: vt = kOla_FLAT_VOTING; break; } if (thy nx != my input -> nx) Melder_throw (U"The dimensionality of Pattern should match that of the instance base."); autoTableOfReal result = KNN_classifyToTableOfReal (me, thee, fws.peek(), k, vt); praat_new (result.move(), U"Output"); END2 } FORM (KNN_toCategoriesWithFeatureWeights, U"Classification", U"KNN & Pattern & FeatureWeights: To Categories...") { INTEGER (U"k neighbours", U"KNN & Pattern & FeatureWeights: To Categories...") RADIO (U"Vote weighting", 1) RADIOBUTTON (U"Inversed squared distance") RADIOBUTTON (U"Inversed distance") RADIOBUTTON (U"Flat") OK2 DO iam_ONLY (KNN); if (my nInstances <= 0) Melder_throw (U"Instance base is empty."); thouart_ONLY (Pattern); heis_ONLY (FeatureWeights); int vt = GET_INTEGER (U"Vote weighting"); switch (vt) { case 1: vt = kOla_SQUARED_DISTANCE_WEIGHTED_VOTING; break; case 2: vt = kOla_DISTANCE_WEIGHTED_VOTING; break; case 3: vt = kOla_FLAT_VOTING; break; } long k = GET_INTEGER (U"k neighbours"); if (k < 1 || k > my nInstances) Melder_throw (U"Please select a value of k such that 0 < k < ", my nInstances + 1, U"."); if (thy nx != (my input)->nx) Melder_throw (U"The dimensionality of Pattern should be equal to that of the instance base."); if (thy nx != his fweights -> numberOfColumns) Melder_throw (U"The number of feature weights should be equal to the dimensionality of the Pattern."); autoCategories result = KNN_classifyToCategories (me, thee, him, k, vt); praat_new (result.move(), U"Output"); END2 } FORM (KNN_toTableOfRealWithFeatureWeights, U"Classification", U"KNN & Pattern & FeatureWeights: To TableOfReal...") { INTEGER (U"k neighbours", U"1") RADIO (U"Vote weighting", 1) RADIOBUTTON (U"Inversed squared distance") RADIOBUTTON (U"Inversed distance") RADIOBUTTON (U"Flat") OK2 DO iam_ONLY (KNN); if (my nInstances <= 0) Melder_throw (U"Instance base is empty."); thouart_ONLY (Pattern); heis_ONLY (FeatureWeights); long k = GET_INTEGER (U"k neighbours"); int vt = GET_INTEGER (U"Vote weighting"); if (k < 1 || k > my nInstances) Melder_throw (U"Please select a value of k such that 0 < k < ", my nInstances + 1, U"\n"); if (thy nx != his fweights -> numberOfColumns) Melder_throw (U"The number of features and the number of feature weights should be equal."); switch (vt) { case 1: vt = kOla_SQUARED_DISTANCE_WEIGHTED_VOTING; break; case 2: vt = kOla_DISTANCE_WEIGHTED_VOTING; break; case 3: vt = kOla_FLAT_VOTING; break; } autoTableOfReal result = KNN_classifyToTableOfReal (me, thee, him, k, vt); praat_new (result.move(), U"Output"); END2 } ///////////////////////////////////////////////////////////////////////////////////////// // Clustering // ///////////////////////////////////////////////////////////////////////////////////////// FORM (Pattern_to_Categories_cluster, U"k-means clustering", U"Pattern: To Categories...") { INTEGER (U"k clusters", U"1") POSITIVE (U"Cluster size ratio constraint", U"0.0000001"); INTEGER (U"Maximum number of reseeds", U"1000") OK2 DO iam_ONLY (Pattern); if (my nx > 0 && my ny > 0) { long k = GET_INTEGER (U"k clusters"); if (k < 1 || k > my ny) Melder_throw (U"Please select a value of k such that 0 < k <= ", my ny, U"."); long rs = GET_INTEGER (U"Maximum number of reseeds"); if (rs < 0) Melder_throw (U"The maximum number of reseeds should not be negative."); double rc = GET_REAL (U"Cluster size ratio constraint"); if (rc > 1 || rc <= 0) Melder_throw (U"Please select a value of the cluster size ratio constraint c such that 0 < c <= 1."); autoFeatureWeights fws = FeatureWeights_create (my nx); autoCategories result = Pattern_to_Categories_cluster (me, fws.peek(), k, rc, rs); praat_new (result.move(), U"Output"); } else { Melder_throw (U"Pattern is empty."); } END2 } FORM (Pattern_to_Categories_clusterWithFeatureWeights, U"k-means clustering", U"Pattern & FeatureWeights: To Categories...") { INTEGER (U"k clusters", U"1") POSITIVE (U"Cluster size ratio constraint", U"0.0000001"); INTEGER (U"Maximum number of reseeds", U"1000") OK2 DO iam_ONLY (Pattern); if (my nx > 0 && my ny > 0) { thouart_ONLY (FeatureWeights); if (my nx != thy fweights -> numberOfColumns) Melder_throw (U"The number of features and the number of feature weights should be equal."); long k = GET_INTEGER(U"k clusters"); if (k < 1 || k > my ny) Melder_throw (U"Please select a value of k such that 0 < k <= ", my ny, U"."); long rs = GET_INTEGER(U"Maximum number of reseeds"); if (rs < 0) Melder_throw (U"The maximum number of reseeds should not be negative."); double rc = GET_REAL(U"Cluster size ratio constraint"); if (rc > 1 || rc <= 0) Melder_throw (U"Please select a value of the cluster size ratio constraint c such that 0 < c <= 1."); autoCategories result = Pattern_to_Categories_cluster (me, thee, k, rc, rs); praat_new (result.move(), U"Output"); } else { Melder_throw (U"Pattern is empty."); } END2 } ///////////////////////////////////////////////////////////////////////////////////////// // Dissimilarity computations // ///////////////////////////////////////////////////////////////////////////////////////// DIRECT2 (KNN_patternToDissimilarity) { iam_ONLY (Pattern); autoFeatureWeights fws = FeatureWeights_create (my nx); autoDissimilarity result = KNN_patternToDissimilarity (me, fws.peek()); praat_new (result.move(), U"Output"); END2 } DIRECT2 (KNN_patternToDissimilarityWithFeatureWeights) { iam_ONLY (Pattern); thouart_ONLY (FeatureWeights); if (my nx != thy fweights -> numberOfColumns) Melder_throw (U"The number of features and the number of feature weights should be equal."); autoDissimilarity result = KNN_patternToDissimilarity (me, thee); praat_new (result.move(), U"Output"); END2 } ///////////////////////////////////////////////////////////////////////////////////////// // Computation of permutation // ///////////////////////////////////////////////////////////////////////////////////////// FORM (KNN_SA_computePermutation, U"To Permutation...", U"Pattern & Categories: To FeatureWeights...") { NATURAL (U"Tries per step", U"200") NATURAL (U"Iterations", U"10") POSITIVE (U"Step size", U"10") POSITIVE (U"Boltzmann constant", U"1.0") POSITIVE (U"Initial temperature", U"0.002") POSITIVE (U"Damping factor", U"1.005") POSITIVE (U"Final temperature", U"0.000002") OK2 DO iam_ONLY (KNN); long tries = GET_INTEGER (U"Tries per step"); long iterations = GET_INTEGER (U"Iterations"); double step_size = GET_REAL (U"Step size"); double bolzmann_c = GET_REAL (U"Boltzmann constant"); double temp_start = GET_REAL (U"Initial temperature"); double temp_damp = GET_REAL (U"Damping factor"); double temp_stop = GET_REAL (U"Final temperature"); autoPermutation result = KNN_SA_ToPermutation (me, tries, iterations, step_size, bolzmann_c, temp_start, temp_damp, temp_stop); praat_new (result.move(), U"Output"); END2 } ///////////////////////////////////////////////////////////////////////////////////////// // Computation of feature weights // ///////////////////////////////////////////////////////////////////////////////////////// FORM (FeatureWeights_computeRELIEF, U"Feature weights", U"Pattern & Categories: To FeatureWeights...") { INTEGER (U"Number of neighbours", U"1") OK2 DO iam_ONLY (Pattern); thouart_ONLY (Categories); if (my ny < 2) Melder_throw (U"The Pattern object should contain at least 2 rows."); if (my ny != thy size) Melder_throw (U"The number of rows in the Pattern object should equal the number of categories in the Categories object."); autoFeatureWeights result = FeatureWeights_compute (me, thee, GET_INTEGER (U"Number of neighbours")); praat_new (result.move(), U"Output"); END2 } FORM (FeatureWeights_computeWrapperExt, U"Feature weights", U"KNN & Pattern & Categories: To FeatureWeights..") { POSITIVE (U"Learning rate", U"0.02") NATURAL (U"Number of seeds", U"20") POSITIVE (U"Stop at", U"1") RADIO (U"Optimization", 1) RADIOBUTTON (U"Co-optimization") RADIOBUTTON (U"Single feature") NATURAL (U"k neighbours", U"1") RADIO (U"Vote weighting", 3) RADIOBUTTON (U"Inversed squared distance") RADIOBUTTON (U"Inversed distance") RADIOBUTTON (U"Flat") OK2 DO iam_ONLY (KNN); if (my nInstances <= 0) Melder_throw (U"Instance base is empty"); thouart_ONLY (Pattern); heis_ONLY (Categories); int mode = GET_INTEGER (U"Vote weighting"); switch (mode) { case 1: mode = kOla_SQUARED_DISTANCE_WEIGHTED_VOTING; break; case 2: mode = kOla_DISTANCE_WEIGHTED_VOTING; break; case 3: mode = kOla_FLAT_VOTING; break; } long k = GET_INTEGER (U"k neighbours"); if (k < 1 || k > my nInstances) Melder_throw (U"Please select a value of k such that 0 < k < ", my nInstances + 1, U"."); if (thy nx != my input -> nx) Melder_throw (U"The dimensionality of Pattern should be equal to that of the instance base."); autoFeatureWeights result = FeatureWeights_computeWrapperExt (me, thee, him, k, mode, GET_INTEGER (U"Number of seeds"), GET_REAL (U"Learning rate"), GET_REAL (U"Stop at"), (int) GET_INTEGER (U"Optimization")); praat_new (result.move(), U"Output"); END2 } FORM (FeatureWeights_computeWrapperInt, U"Feature weights", U"KNN: To FeatureWeights...") { POSITIVE (U"Learning rate", U"0.02") NATURAL (U"Number of seeds", U"10") POSITIVE (U"Stop at", U"1") RADIO (U"Optimization", 1) RADIOBUTTON (U"Co-optimization") RADIOBUTTON (U"Single feature") RADIO (U"Evaluation method", 1) RADIOBUTTON (U"Leave one out") RADIOBUTTON (U"10-fold cross-validation") NATURAL (U"k neighbours", U"1") RADIO (U"Vote weighting", 3) RADIOBUTTON (U"Inversed squared distance") RADIOBUTTON (U"Inversed distance") RADIOBUTTON (U"Flat") OK2 DO iam_ONLY (KNN); if (my nInstances < 1) Melder_throw (U"Instance base is empty"); int emode = GET_INTEGER (U"Evaluation method"); switch (emode) { case 2: emode = kOla_TEN_FOLD_CROSS_VALIDATION; break; case 1: emode = kOla_LEAVE_ONE_OUT; break; } int mode = GET_INTEGER (U"Vote weighting"); switch (mode) { case 1: mode = kOla_SQUARED_DISTANCE_WEIGHTED_VOTING; break; case 2: mode = kOla_DISTANCE_WEIGHTED_VOTING; break; case 3: mode = kOla_FLAT_VOTING; break; } long k = GET_INTEGER (U"k neighbours"); if (k < 1 || k > my nInstances) Melder_throw (U"Please select a value of k such that 0 < k < ", my nInstances + 1, U"."); autoFeatureWeights result = FeatureWeights_computeWrapperInt (me, k, mode, GET_INTEGER (U"Number of seeds"), GET_REAL (U"Learning rate"), GET_REAL (U"Stop at"), (int) GET_INTEGER (U"Optimization"), emode); praat_new (result.move(), U"Output"); END2 } ///////////////////////////////////////////////////////////////////////////////////////// // Creation and processing of auxiliary datatypes // ///////////////////////////////////////////////////////////////////////////////////////// FORM (Pattern_create, U"Create Pattern", 0) { WORD (U"Name", U"1x1") NATURAL (U"Dimension of a pattern", U"1") NATURAL (U"Number of patterns", U"1") OK2 DO autoPattern result = Pattern_create (GET_INTEGER (U"Number of patterns"), GET_INTEGER (U"Dimension of a pattern")); praat_new (result.move(), GET_STRING (U"Name")); END2 } FORM (Categories_create, U"Create Categories", 0) { WORD (U"Name", U"empty") OK2 DO autoCategories result = Categories_create (); praat_new (result.move(), GET_STRING (U"Name")); END2 } FORM (FeatureWeights_create, U"Create FeatureWeights", 0) { WORD (U"Name", U"empty") NATURAL (U"Number of weights", U"1") OK2 DO autoFeatureWeights result = FeatureWeights_create (GET_INTEGER (U"Number of weights")); praat_new (result.move(), GET_STRING (U"Name")); END2 } ///////////////////////////////////////////////////////////////////////////////////////// // DEBUG // ///////////////////////////////////////////////////////////////////////////////////////// // Disabled /* #ifdef _DEBUG DIRECT (KNN_debug_KNN_SA_partition) Pattern p = ONLY (classPattern); autoPattern output = Pattern_create (p->ny, p->nx); autoNUMvector result (0, p->ny); KNN_SA_partition (p, 1, p->ny, result); for (long k = 1, c = 1; k <= output->ny; ++k, ++c) for (long i = 1; i <= p->ny && k <= output->ny; ++i) if(result [i] == c) { for(long j = 1; j <= output->nx; ++j) output->z[k][j] = p->z[i][j]; ++k; } praat_new (output.move(), U"Output"); END DIRECT (KNN_debug_KNN_getNumberOfCPUs) Melder_information (KNN_getNumberOfCPUs(), U" CPUs available"); END DIRECT (KNN_debug_KNN_threadTest) KNN_threadTest(); END #endif */ ///////////////////////////////////////////////////////////////////////////////////////// // Help // ///////////////////////////////////////////////////////////////////////////////////////// DIRECT2 (KNN_help) { Melder_help (U"KNN classifiers"); END2 } DIRECT2 (hint_KNN_and_FeatureWeights_evaluate) { Melder_information (U"The accuracy of a KNN can be estimated by selecting a KNN and a FeatureWeights object and choosing \"Evaluate...\"."); END2 } DIRECT2 (hint_KNN_and_Pattern_classify) { Melder_information (U"You can use the KNN as a classifier by selecting a KNN and a Pattern and choosing \"To Categories...\" or \"To TableOfReal...\"."); END2 } DIRECT2 (hint_KNN_and_Pattern_and_FeatureWeights_classify) { Melder_information (U"You can use the KNN as a classifier by selecting a KNN, a Pattern and an FeatureWeights object and choosing \"To Categories...\" or \"To TableOfReal...\"."); END2 } DIRECT2 (hint_KNN_and_Pattern_and_Categories_learn) { Melder_information (U"You can train a KNN by selecting a KNN, a Pattern and a Categories object together and choosing \"Learn...\"."); END2 } DIRECT2 (hint_KNN_and_Pattern_and_Categories_evaluate) { Melder_information (U"The accuracy of a KNN can be estimated by selecting a KNN, a test Pattern and the corresponding Categories object and choosing \"Evaluate...\"."); END2 } DIRECT2 (hint_KNN_and_Pattern_and_Categories_and_FeatureWeights_evaluate) { Melder_information (U"The accuracy of a KNN can be estimated by selecting a KNN, a test Pattern, an FeatureWeights object, and the corresponding Categories object and choosing \"Evaluate...\"."); END2 } DIRECT2 (hint_Pattern_and_FeatureWeights_to_Categories) { Melder_information (U"A Pattern object and a FeatureWeights object can be used to compute a fixed number of clusters using the k-means clustering clustering algorithm."); END2 } DIRECT2 (hint_Pattern_and_FeatureWeights_to_Dissimilarity) { Melder_information (U"A Dissimilarity matrix can be generated from a Pattern and a FeatureWeights object."); END2 } ///////////////////////////////////////////////////////////////////////////////////////// // Setting callbacks // ///////////////////////////////////////////////////////////////////////////////////////// void praat_contrib_Ola_KNN_init (); void praat_contrib_Ola_KNN_init () { Thing_recognizeClassesByName (classKNN, NULL); Thing_recognizeClassesByName (classFeatureWeights, NULL); ////////// // Menu // ////////// praat_addMenuCommand (U"Objects", U"New", U"kNN classifiers", 0, 0, 0); praat_addMenuCommand (U"Objects", U"New", U"kNN classifiers", 0, 1, DO_KNN_help); praat_addMenuCommand (U"Objects", U"New", U"-- KNN --", 0, 1, 0); praat_addMenuCommand (U"Objects", U"New", U"Create kNN classifier...", 0, 1, DO_KNN_create); praat_addMenuCommand (U"Objects", U"New", U"Advanced", 0, 1, 0); praat_addMenuCommand (U"Objects", U"New", U"Create Pattern...", 0, 2, DO_Pattern_create); praat_addMenuCommand (U"Objects", U"New", U"Create Categories...", 0, 2, DO_Categories_create); praat_addMenuCommand (U"Objects", U"New", U"Create FeatureWeights...", 0, 2, DO_FeatureWeights_create); ///////////// // Actions // ///////////// praat_addAction1 (classKNN, 0, U"kNN help", 0, 0, DO_KNN_help); praat_addAction1 (classKNN, 0, QUERY_BUTTON, 0, 0, 0); praat_addAction1 (classKNN, 1, U"Get optimized parameters...", 0, 2, DO_KNN_getOptimumModel); praat_addAction1 (classKNN, 1, U"Get accuracy estimate...", 0, 2, DO_KNN_evaluate); praat_addAction1 (classKNN, 1, U"Get size of instancebase", 0, 2, DO_KNN_getNumberOfInstances); praat_addAction1 (classKNN, 0, MODIFY_BUTTON, 0, 0, 0); praat_addAction1 (classKNN, 1, U"Shuffle", 0, 1, DO_KNN_shuffle); praat_addAction1 (classKNN, 1, U"Prune...", 0, 1, DO_KNN_prune); praat_addAction1 (classKNN, 1, U"Reset...", 0, 1, DO_KNN_reset); praat_addAction1 (classKNN, 0, EXTRACT_BUTTON, 0, 0, 0); praat_addAction1 (classKNN, 0, U"Extract input Patterns", 0, 1, DO_KNN_extractInputPatterns); praat_addAction1 (classKNN, 0, U"Extract output Categories", 0, 1, DO_KNN_extractOutputCategories); praat_addAction1 (classKNN, 0, U"To FeatureWeights...", 0, 0, DO_FeatureWeights_computeWrapperInt); // praat_addAction1 (classKNN, 0, U"To Permutation...", 0, 0, DO_KNN_SA_computePermutation); // praat_addAction2 (classKNN, 1, classFeatureWeights, 1, U"To Permutation...", 0, 0, DO_KNN_evaluateWithFeatureWeights); praat_addAction (classKNN, 1, classPattern, 1, classCategories, 1, U"Learn...", 0, 0, DO_KNN_learn); praat_addAction2 (classKNN, 1, classFeatureWeights, 1, U"Evaluate...", 0, 0, DO_KNN_evaluateWithFeatureWeights); praat_addAction (classKNN, 1, classPattern, 1, classCategories, 1, U"Evaluate...", 0, 0, DO_KNN_evaluateWithTestSet); praat_addAction4 (classKNN, 1, classPattern, 1, classCategories, 1, classFeatureWeights, 1, U"Evaluate...", 0, 0, DO_KNN_evaluateWithTestSetAndFeatureWeights); praat_addAction (classKNN, 1, classPattern, 1, classCategories, 1, U"To FeatureWeights...", 0, 0, DO_FeatureWeights_computeWrapperExt); praat_addAction2 (classKNN, 1, classPattern, 1, U"To Categories...", 0, 0, DO_KNN_toCategories); praat_addAction2 (classKNN, 1, classPattern, 1, U"To TableOfReal...", 0, 0, DO_KNN_toTableOfReal); praat_addAction (classKNN, 1, classPattern, 1, classFeatureWeights, 1, U"To Categories...", 0, 0, DO_KNN_toCategoriesWithFeatureWeights); praat_addAction (classKNN, 1, classPattern, 1, classFeatureWeights, 1, U"To TableOfReal...", 0, 0, DO_KNN_toTableOfRealWithFeatureWeights); praat_addAction1 (classPattern, 1, U"To Dissimilarity", 0, 1, DO_KNN_patternToDissimilarity); praat_addAction1 (classPattern, 1, U"To Categories...", 0, 1, DO_Pattern_to_Categories_cluster); praat_addAction2 (classPattern, 1, classFeatureWeights, 1, U"To Dissimilarity", 0, 0, DO_KNN_patternToDissimilarityWithFeatureWeights); praat_addAction2 (classPattern, 1, classFeatureWeights, 1, U"To Categories...", 0, 0, DO_Pattern_to_Categories_clusterWithFeatureWeights); praat_addAction2 (classPattern, 1, classCategories, 1, U"To FeatureWeights...", 0, 0, DO_FeatureWeights_computeRELIEF); praat_addAction2 (classPattern, 1, classCategories, 1, U"To KNN Classifier...", 0, 0, DO_KNN_Pattern_Categories_to_KNN); /////////// // DEBUG // /////////// /* #ifdef _DEBUG praat_addAction1 (classKNN, 0, U"_DEBUG: KNN_getNumberOfCPUs", 0, 0, DO_KNN_debug_KNN_getNumberOfCPUs); praat_addAction1 (classKNN, 0, U"_DEBUG: KNN_threadTest", 0, 0, DO_KNN_debug_KNN_threadTest); praat_addAction1 (classPattern, 1, U"_DEBUG: KNN_SA_partition", 0, 1, DO_KNN_debug_KNN_SA_partition); #endif */ /////////// // Hints // /////////// praat_addAction1 (classPattern, 0, U"& FeatureWeights: To Categories?", 0, 0, DO_hint_Pattern_and_FeatureWeights_to_Categories); praat_addAction1 (classPattern, 0, U"& FeatureWeights: To Dissimilarity?", 0, 0, DO_hint_Pattern_and_FeatureWeights_to_Dissimilarity); praat_addAction1 (classKNN, 0, U"& FeatureWeights: Evaluate?", 0, 0, DO_hint_KNN_and_FeatureWeights_evaluate); // praat_addAction1 (classKNN, 0, U"& FeatureWeights: To Permutation?", 0, 0, DO_hint_Pattern_and_FeatureWeights_to_Dissimilarity); praat_addAction1 (classKNN, 0, U"& Pattern: Classify?", 0, 0, DO_hint_KNN_and_Pattern_classify); praat_addAction1 (classKNN, 0, U"& Pattern & FeatureWeights: Classify?", 0, 0, DO_hint_KNN_and_Pattern_and_FeatureWeights_classify); praat_addAction1 (classKNN, 0, U"& Pattern & Categories: Learn?", 0, 0, DO_hint_KNN_and_Pattern_and_Categories_learn); praat_addAction1 (classKNN, 0, U"& Pattern & Categories: Evaluate?", 0, 0, DO_hint_KNN_and_Pattern_and_Categories_evaluate); praat_addAction1 (classKNN, 0, U"& Pattern & Categories & FeatureWeights: Evaluate?", 0, 0, DO_hint_KNN_and_Pattern_and_Categories_and_FeatureWeights_evaluate); INCLUDE_MANPAGES (manual_KNN_init) } /* End of file praat_contrib_Ola_KNN.cpp */ praat-6.0.04/dwsys/000077500000000000000000000000001261542461700140715ustar00rootroot00000000000000praat-6.0.04/dwsys/Collection_extensions.cpp000066400000000000000000000226231261542461700211540ustar00rootroot00000000000000/* Collection_extensions.c * * Copyright (C) 1994-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020812 GPL header djmw 20040420 Fraction in OrderedOfString_difference must be double. djmw 20050511 Skip printing unique labels in OrderedOfString djmw 20061214 djmw 20061214 Changed info to Melder_writeLine format. djmw 20110304 Thing_new */ #include "Collection_extensions.h" #include "Simple_extensions.h" #include "NUM2.h" Collection Collection_and_Permutation_permuteItems (Collection me, Permutation him) { try { if (my size != his numberOfElements) { Melder_throw (me, U"The number of elements are not equal."); } autoNUMvector pos (1, my size); autoCollection thee = static_cast (Data_copy (me)); for (long i = 1; i <= my size; i++) { pos[i] = i; } /* Dual meaning of array pos: */ /* k < i : position of item 'k' */ /* k >= i : the item at position 'k' */ for (long i = 1; i <= my size; i++) { long ti = pos[i], which = Permutation_getValueAtIndex (him, i); long where = pos[which]; /* where >= i */ Daata tmp = static_cast (thy item[i]); if (i == where) { continue; } thy item[i] = thy item[ where ]; thy item[where] = tmp; /* order is important !! */ pos[ti] = where; pos[where] = ti; pos[which] = which <= i ? i : ti; } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not permuted."); } } Collection Collection_permuteItems (Collection me) { try { autoPermutation p = Permutation_create (my size); Permutation_permuteRandomly_inline (p.peek(), 0, 0); autoCollection thee = Collection_and_Permutation_permuteItems (me, p.peek()); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": items not permuted."); } } /****************** class OrderedOfString ******************/ void structOrderedOfString :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Number of strings: ", size); autoOrderedOfString uStrings = OrderedOfString_selectUniqueItems (this, 1); MelderInfo_writeLine (U"Number of unique categories: ", uStrings -> size); } Thing_implement (OrderedOfString, Ordered, 0); int OrderedOfString_init (OrderedOfString me, long initialCapacity) { Ordered_init (me, classSimpleString, initialCapacity); return 1; } OrderedOfString OrderedOfString_create () { try { autoOrderedOfString me = Thing_new (OrderedOfString); OrderedOfString_init (me.peek(), 10); return me.transfer(); } catch (MelderError) { Melder_throw (U"OrderedOfString not created."); } } int OrderedOfString_append (OrderedOfString me, char32 *append) { try { if (append == nullptr) { return 1; // BUG: lege string appenden?? } autoSimpleString item = SimpleString_create (append); Collection_addItem (me, item.transfer()); return 1; } catch (MelderError) { Melder_throw (me, U": text not appended."); } } OrderedOfString OrderedOfString_joinItems (OrderedOfString me, OrderedOfString thee) { try { if (my size != thy size) { Melder_throw (U"sizes must be equal."); } autoOrderedOfString him = Data_copy (me); for (long i = 1; i <= my size; i++) { SimpleString_append ( (SimpleString) his item[i], (SimpleString) thy item[i]); } return him.transfer(); } catch (MelderError) { Melder_throw (U"Items not joinmed."); } } OrderedOfString OrderedOfString_selectUniqueItems (OrderedOfString me, int sort) { try { if (! sort) { autoOrderedOfString him = OrderedOfString_create (); for (long i = 1; i <= my size; i++) { SimpleString ss = (SimpleString) my item[i]; if (! OrderedOfString_indexOfItem_c (him.peek(), ss -> string)) { autoSimpleString item = Data_copy (ss); Collection_addItem (him.peek(), item.transfer()); } } Collection_shrinkToFit (him.peek()); return him.transfer(); } autoSortedSetOfString thee = SortedSetOfString_create (); /* Collection_to_SortedSet (I, int (*compare)(I, thou)) */ for (long i = 1; i <= my size; i++) { if (! SortedSet_hasItem (thee.peek(), my item[i])) { autoSimpleString item = Data_copy ( (SimpleString) my item[i]); Collection_addItem (thee.peek(), item.transfer()); } } autoOrderedOfString him = OrderedOfString_create (); for (long i = 1; i <= thy size; i++) { autoSimpleString item = Data_copy ( (SimpleString) thy item[i]); Collection_addItem (him.peek(), item.transfer()); } return him.transfer(); } catch (MelderError) { Melder_throw (me, U": unique items not selected."); } } void OrderedOfString_frequency (OrderedOfString me, OrderedOfString thee, long *count) { for (long i = 1; i <= my size; i++) { for (long j = 1; j <= thy size; j++) { if (Data_equal ( (Daata) my item[i], (Daata) thy item[j])) { count[j]++; break; } } } } long OrderedOfString_getNumberOfDifferences (OrderedOfString me, OrderedOfString thee) { long numberOfDifferences = 0; if (my size != thy size) { return -1; } for (long i = 1; i <= my size; i++) { if (! Data_equal ( (SimpleString) my item[i], (SimpleString) thy item[i])) { numberOfDifferences++; } } return numberOfDifferences; } double OrderedOfString_getFractionDifferent (OrderedOfString me, OrderedOfString thee) { long numberOfDifferences = OrderedOfString_getNumberOfDifferences (me, thee); if (numberOfDifferences < 0) { return NUMundefined; } return my size == 0 ? 0.0 : (0.0 + numberOfDifferences) / my size; } int OrderedOfString_difference (OrderedOfString me, OrderedOfString thee, long *ndif, double *fraction) { *ndif = 0; *fraction = 1; if (my size != thy size) { Melder_flushError (U"OrderedOfString_difference: the number of items differ"); return 0; } for (long i = 1; i <= my size; i++) { if (! Data_equal ( (SimpleString) my item[i], (SimpleString) thy item[i])) { (*ndif) ++; } } *fraction = *ndif; *fraction /= my size; return 1; } long OrderedOfString_indexOfItem_c (OrderedOfString me, const char32 *str) { long index = 0; autoSimpleString s = SimpleString_create (str); for (long i = 1; i <= my size; i++) { if (Data_equal ( (Daata) my item[i], s.peek())) { index = i; break; } } return index; } const char32 *OrderedOfString_itemAtIndex_c (OrderedOfString me, long index) { return index > 0 && index <= my size ? SimpleString_c ( (SimpleString) my item[index]) : nullptr; } void OrderedOfString_sequentialNumbers (OrderedOfString me, long n) { Collection_removeAllItems (me); for (long i = 1; i <= n; i++) { char32 s[40]; Melder_sprint (s,40, i); autoSimpleString str = SimpleString_create (s); Collection_addItem (me, str.transfer()); } } void OrderedOfString_changeStrings (OrderedOfString me, char32 *search, char32 *replace, int maximumNumberOfReplaces, long *nmatches, long *nstringmatches, int use_regexp) { regexp *compiled_search = nullptr; try { if (! search) { Melder_throw (U"Missing search string."); } if (! replace) { Melder_throw (U"Missing replace string."); } if (use_regexp) { compiled_search = CompileRE_throwable (search, 0); } for (long i = 1; i <= my size; i++) { SimpleString ss = (SimpleString) my item[i]; long nmatches_sub; char32 *r = use_regexp ? str_replace_regexp (ss -> string, compiled_search, replace, maximumNumberOfReplaces, &nmatches_sub) : str_replace_literal (ss -> string, search, replace, maximumNumberOfReplaces, &nmatches_sub); // Change without error: Melder_free (ss -> string); ss -> string = r; if (nmatches_sub > 0) { *nmatches += nmatches_sub; (*nstringmatches) ++; } } if (use_regexp) { free (compiled_search); } } catch (MelderError) { if (use_regexp) { free (compiled_search); } Melder_throw (U"Replace not completed."); } } long OrderedOfString_isSubsetOf (OrderedOfString me, OrderedOfString thee, long *translation) { // ?? test and give number long nStrings = 0; for (long i = 1; i <= my size; i++) { if (translation) { translation[i] = 0; } for (long j = 1; j <= thy size; j++) if (Data_equal ( (SimpleString) my item[i], (SimpleString) thy item[j])) { if (translation) { translation[i] = j; } nStrings++; break; } } return nStrings; } void OrderedOfString_drawItem (OrderedOfString me, Graphics g, long index, double xWC, double yWC) { if (index > 0 && index <= my size) { SimpleString_draw ((SimpleString) my item[index], g, xWC, yWC); } } long OrderedOfString_getSize (OrderedOfString me) { return my size; } void OrderedOfString_removeOccurrences (OrderedOfString me, const char32 *search, int use_regexp) { if (! search) { return; } for (long i = my size; i >= 1; i--) { SimpleString ss = (SimpleString) my item[i]; if ( (use_regexp && strstr_regexp (ss -> string, search)) || (!use_regexp && str32str (ss -> string, search))) { Collection_removeItem (me, i); } } } /* End of file Collection_extensions.c */ praat-6.0.04/dwsys/Collection_extensions.h000066400000000000000000000065771261542461700206330ustar00rootroot00000000000000#ifndef _Collection_extensions_h_ #define _Collection_extensions_h_ /* Collection_extensions.h * * Copyright (C) 1994-2002 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020812 GPL header djmw 20110414 Latest modification. */ #include "Collection.h" #include "Graphics.h" #include "Permutation.h" Collection Collection_and_Permutation_permuteItems (Collection me, Permutation him); Collection Collection_permuteItems (Collection me); /* permute the order of my items */ /****************** class OrderedOfString ******************/ Thing_define (OrderedOfString, Ordered) { void v_info () override; }; OrderedOfString OrderedOfString_create (); int OrderedOfString_init (OrderedOfString me, long initialCapacity); int OrderedOfString_append (OrderedOfString me, char32 *append); OrderedOfString OrderedOfString_joinItems (OrderedOfString me, OrderedOfString thee); /* Join each item */ OrderedOfString OrderedOfString_selectUniqueItems (OrderedOfString me, int sort); /* Postcondition: thy size <= my size */ void OrderedOfString_frequency (OrderedOfString me, OrderedOfString thee, long *count); /* count how often the items in 'thee' occur in 'me' */ /* Precondition: count[1..thy size] exists */ /* To be removed Praat 4.2.4 2004040427 */ int OrderedOfString_difference (OrderedOfString me, OrderedOfString thee, long *ndif, double *fraction); double OrderedOfString_getFractionDifferent (OrderedOfString me, OrderedOfString thee); long OrderedOfString_getNumberOfDifferences (OrderedOfString me, OrderedOfString thee); const char32 *OrderedOfString_itemAtIndex_c (OrderedOfString me, long index); long OrderedOfString_indexOfItem_c (OrderedOfString me, const char32 *str); void OrderedOfString_drawItem (OrderedOfString me, Graphics g, long index, double xWC, double yWC); void OrderedOfString_sequentialNumbers (OrderedOfString me, long n); void OrderedOfString_removeOccurrences (OrderedOfString me, const char32 *search, int user_regexp); void OrderedOfString_changeStrings (OrderedOfString me, char32 *search, char32 *replace, int maximumNumberOfReplaces, long *nmatches, long *nstringmatches, int use_regexp); long OrderedOfString_isSubsetOf (OrderedOfString me, OrderedOfString thee, long *translation); /* Check whether my items are (a subset of)|(in) thy items. * Preconditions: * if (translation) translation[1..my size] exists. * Postconditions: * Return: the number of my labels that are in thee. * if (translation) the returned translation table has the following property: * if (translation[i] > 0) my label[i] = thy label[ translation[i] ]; * else if (translation[i] == 0) my label[i] not in thy labels. */ long OrderedOfString_getSize (OrderedOfString me); /* return my size */ #endif /* _Collection_extensions_h_ */ praat-6.0.04/dwsys/Command.cpp000066400000000000000000000054631261542461700161630ustar00rootroot00000000000000/* Command.cpp * * Copyright (C) 1994-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19950710 djmw 20020812 GPL header djmw 20071007 wchar djmw 20110304 Thing_new */ #include "Command.h" Thing_implement (Command, Thing, 0); void Command_init (I, const char32 *name, Any data, int (*execute) (Any), int (*undo) (Any)) { iam (Command); Melder_assert (execute && undo); Thing_setName (me, name); my data = data; my execute = execute; my undo = undo; } int Command_do (I) { iam (Command); return my execute (me); } int Command_undo (I) { iam (Command); return my undo (me); } Thing_implement (CommandHistory, Ordered, 0); CommandHistory CommandHistory_create (long maximumCapacity) { try { autoCommandHistory me = Thing_new (CommandHistory); Collection_init (me.peek(), classCommand, maximumCapacity); return me.transfer(); } catch (MelderError) { Melder_throw (U"Command not created."); } } void CommandHistory_forth (I) { iam (CommandHistory); my current++; } void CommandHistory_back (I) { iam (CommandHistory); my current--; } Any CommandHistory_getItem (I) { iam (CommandHistory); Melder_assert (my current > 0 && my current <= my size); return my item[my current]; } void CommandHistory_insertItem (I, Any data) { iam (CommandHistory); Melder_assert (data && (Thing_isa ( (Thing) data, my itemClass) || my itemClass == nullptr)); if (my current < my size) { for (long i = my current + 1; i <= my size; i++) { forget ( ( (Command *) my item) [i]); } my size = my current; } if (my size >= my _capacity) { Collection_removeItem (me, 1); } my item[++my size] = data; my current = my size; } int CommandHistory_empty (I) { iam (CommandHistory); return my size == 0; } int CommandHistory_offleft (I) { iam (CommandHistory); return my current == 0; } int CommandHistory_offright (I) { iam (CommandHistory); return my size == 0 || my current == my size + 1; } char32 *CommandHistory_commandName (I, long offsetFromCurrent) { iam (CommandHistory); long pos = my current + offsetFromCurrent; return pos >= 1 && pos <= my size ? Thing_getName ( (Thing) my item[pos]) : nullptr; } /* End of file Command.cpp */ praat-6.0.04/dwsys/Command.h000066400000000000000000000044221261542461700156220ustar00rootroot00000000000000#ifndef _Command_h_ #define _Command_h_ /* Command.h * * Copyright (C) 1994-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19950711 djmw 20020812 GPL header djmw 20110306 Latest modification */ #include "Thing.h" #include "Collection.h" Thing_define (Command, Thing) { // new data: public: Any data; int (*execute) (I); int (*undo) (I); }; void Command_init (I, const char32 *name, Any data, int (*execute)(Any), int (*undo)(Any)); int Command_do (I); int Command_undo (I); Thing_define (CommandHistory, Ordered) { // new data: public: long current; }; /* Active data structure. 'current' is position of the cursor in the list */ /* Queries and insertions are at the current position */ /* Invariants: */ /* 0 <= current <= size + 1; */ CommandHistory CommandHistory_create (long maximumCapacity); void CommandHistory_forth (I); /* Precondition: ! offright */ /* my current++; */ void CommandHistory_back (I); /* Precondition: ! offleft */ /* my current--; */ Any CommandHistory_getItem (I); /* return (pointer to) my item[my current]; */ void CommandHistory_insertItem (I, Any item); /* 1. forget about item[ current+1..size ] */ /* 2. insert item after current. */ /* 3. current = size */ int CommandHistory_empty (I); /* return my size == 0; */ int CommandHistory_offleft (I); /* return my current == 0; */ int CommandHistory_offright (I); /* return my size == 0 || my current == my size + 1; */ char32 *CommandHistory_commandName (I, long offsetFromCurrent); /* offsetFromCurrent may be zero, positive or negative. */ /* References outside the list will return nullptr. */ #endif /* _Command_h_ */ praat-6.0.04/dwsys/DLL.cpp000066400000000000000000000107431261542461700152150ustar00rootroot00000000000000/* DLL.cpp * * Copyright (C) 2011-2013, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "DLL.h" Thing_implement (DLLNode, Daata, 0); void structDLLNode :: v_destroy () { forget (data); DLLNode_Parent :: v_destroy (); } void structDLLNode :: v_copy (thou) { thouart (DLLNode); thy data = Data_copy (our data); } Thing_implement (DLL, Thing, 0); void structDLL :: v_destroy () { DLLNode v = front; while (v) { DLLNode cur = v; v = v -> next; forget (cur); } DLL_Parent :: v_destroy (); } int structDLL :: s_compare (Any /* node1 */, Any /* node2 */) { return 0; } DLLNode DLLNode_create (Daata data) { autoDLLNode me = Thing_new (DLLNode); my data = data; return me.transfer(); } void DLL_init (DLL) { } DLL DLL_create() { try { autoDLL me = Thing_new (DLL); DLL_init (me.peek()); return me.transfer(); } catch (MelderError) { Melder_throw (U"DLL not created."); } } void DLL_addFront (DLL me, DLLNode n) { if (my front) { DLL_addBefore (me, my front, n); } else { // empty list my front = n; my back = n; n -> next = nullptr; n -> prev = nullptr; my numberOfNodes++; } } void DLL_addBack (DLL me, DLLNode n) { if (my back) { DLL_addAfter (me, my back, n); } else { DLL_addFront (me, n); // empty list } } void DLL_addBefore (DLL me, DLLNode pos, DLLNode n) { n -> prev = pos -> prev; n -> next = pos; if (pos -> prev == nullptr) { my front = n; } else { pos -> prev -> next = n; } pos -> prev = n; my numberOfNodes++; } void DLL_addAfter (DLL me, DLLNode pos, DLLNode n) { n -> prev = pos; n -> next = pos -> next; if (pos -> next == nullptr) { my back = n; } else { pos -> next -> prev = n; } pos -> next = n; my numberOfNodes++; } void DLL_remove (DLL me, DLLNode n) { if (my numberOfNodes == 0) { return; } if (n == my front) { my front = my front -> next; my front -> prev = nullptr; } else if (n == my back) { my back = my back -> prev; my back -> next = nullptr; } else { n -> prev -> next = n -> next; n -> next -> prev = n -> prev; } forget (n); my numberOfNodes++; } // Preconditions: // from and to must be part of the list // from must occur before to void DLL_sortPart (DLL me, DLLNode from, DLLNode to) { // Save data if (from == to) { return; // nothing to do } DLLNode from_prev = from -> prev; DLLNode to_next = to -> next; DLLNode my_front = my front; DLLNode my_back = my back; from -> prev = to -> next = nullptr; my front = from; my back = to; DLL_sort (me); // restore complete list my front -> prev = from_prev; if (from_prev) { from_prev -> next = my front; } my back -> next = to_next; if (to_next) { to_next -> prev = my back; } if (my_front != from) { my front = my_front; } if (my_back != to) { my back = my_back; } } void DLL_sort (DLL me) { Data_CompareFunction compare = my v_getCompareFunction (); long increment = 1; DLLNode front = my front, back; for (;;) { DLLNode n1 = front; front = nullptr; back = nullptr; long numberOfMerges = 0; while (n1) { DLLNode n2 = n1, n; long n1size = 0; numberOfMerges++; for (long i = 1; i <= increment; i++) { n1size++; n2 = n2 -> next; if (!n2) { break; } } long n2size = increment; while (n1size > 0 || (n2size > 0 && n2)) { // merge n1 and n2 if (n1size == 0) { n2size--; n = n2; n2 = n2 -> next; } else if (n2size == 0 || !n2) { n1size--; n = n1; n1 = n1 -> next; } else if (compare (n1, n2) <= 0) { n1size--; n = n1; n1 = n1 -> next; } else { n2size--; n = n2; n2 = n2 -> next; } if (back) { back -> next = n; } else { front = n; } n -> prev = back; back = n; } n1 = n2; } back -> next = nullptr; if (numberOfMerges <= 1) { break; } increment *= 2; } // my front = front; my back = back; } // end of file DLL.cpp praat-6.0.04/dwsys/DLL.h000066400000000000000000000031221261542461700146530ustar00rootroot00000000000000#ifndef _DLL_h_ #define _DLL_h_ /* DLL.h * * Copyright (C) 2011 David Weenink, 2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Data.h" Thing_define (DLLNode, Daata) { DLLNode next, prev; Daata data; void v_destroy () override; void v_copy (Any data_to) override; }; Thing_define (DLL, Thing) { long numberOfNodes; DLLNode front, back; void v_destroy () override; static int s_compare (Any data1, Any data2); virtual Data_CompareFunction v_getCompareFunction () { return s_compare; } }; DLLNode DLLNode_create (Daata data); // DLLNode owns the data void DLL_init (DLL me); DLL DLL_create (); void DLL_addFront (DLL me, DLLNode n); void DLL_addBack (DLL me, DLLNode n); void DLL_addBefore (DLL me, DLLNode pos, DLLNode n); void DLL_addAfter (DLL me, DLLNode pos, DLLNode n); void DLL_remove (DLL me, DLLNode n); void DLL_sort (DLL me); void DLL_sortPart (DLL me, DLLNode from, DLLNode to); #endif // _DLL_h_ praat-6.0.04/dwsys/Eigen.cpp000066400000000000000000000374531261542461700156400ustar00rootroot00000000000000/* Eigen.cpp * * Copyright (C) 1993-2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20010719 djmw 20020402 GPL header. djmw 20030701 Modified sorting in Eigen_initFromSquareRootPair. djmw 20030703 Added Eigens_alignEigenvectors. djmw 20030708 Corrected syntax error in Eigens_alignEigenvectors. djmw 20030812 Corrected memory bug in Eigen_initFromSymmetricMatrix. djmw 20030825 Removed praat_USE_LAPACK external variable. djmw 20031101 Documentation djmw 20031107 Moved NUMdmatrix_transpose to NUM2.c djmw 20031210 Added rowLabels to Eigen_drawEigenvector and Eigen_and_Strings_drawEigenvector djmw 20030322 Extra test in Eigen_initFromSquareRootPair. djmw 20040329 Added fractionOfTotal and cumulative parameters in Eigen_drawEigenvalues_scree. djmw 20040622 Less horizontal labels in Eigen_drawEigenvector. djmw 20050706 Shortened horizontal offsets in Eigen_drawEigenvalues from 1 to 0.5 djmw 20051204 Eigen_initFromSquareRoot adapted for nrows < ncols djmw 20071012 Added: o_CAN_WRITE_AS_ENCODING.h djmw 20110304 Thing_new */ #include "Eigen.h" #include "NUMmachar.h" #include "NUMlapack.h" #include "NUMclapack.h" #include "NUM2.h" #include "SVD.h" #include "oo_DESTROY.h" #include "Eigen_def.h" #include "oo_COPY.h" #include "Eigen_def.h" #include "oo_EQUAL.h" #include "Eigen_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Eigen_def.h" #include "oo_WRITE_TEXT.h" #include "Eigen_def.h" #include "oo_READ_TEXT.h" #include "Eigen_def.h" #include "oo_WRITE_BINARY.h" #include "Eigen_def.h" #include "oo_READ_BINARY.h" #include "Eigen_def.h" #include "oo_DESCRIPTION.h" #include "Eigen_def.h" Thing_implement (Eigen, Daata, 0); #define MAX(m,n) ((m) > (n) ? (m) : (n)) #define MIN(m,n) ((m) < (n) ? (m) : (n)) #define SWAP(a,b) {temp=(a);(a)=(b);(b)=temp;} static void Graphics_ticks (Graphics g, double min, double max, bool hasNumber, bool hasTick, bool hasDottedLine, bool integers) { double range = max - min, scale = 1.0, tick = min, dtick = 1.0; if (range == 0.0) { return; } else if (range > 1.0) { while (range / scale > 10.0) { scale *= 10.0; } range /= scale; } else { while (range / scale < 10.0) { scale /= 10.0; } range *= scale; } if (range < 3.0) { dtick = 0.5; } dtick *= scale; tick = dtick * floor (min / dtick); if (tick < min) { tick += dtick; } while (tick <= max) { double num = integers ? round (tick) : tick; Graphics_markBottom (g, num, hasNumber, hasTick, hasDottedLine, nullptr); tick += dtick; } } void Eigen_init (I, long numberOfEigenvalues, long dimension) { iam (Eigen); my numberOfEigenvalues = numberOfEigenvalues; my dimension = dimension; my eigenvalues = NUMvector (1, numberOfEigenvalues); my eigenvectors = NUMmatrix (1, numberOfEigenvalues, 1, dimension); } /* Solve: (A'A - lambda)x = 0 for eigenvalues lambda and eigenvectors x. svd(A) = UDV' => A'A = (UDV')'(UDV') = VD^2V' (VD^2V'-lambda)x = 0 => (D^2 - lambda)V'x = 0 => solution V'x = I => x = V Eigenvectors: the columns of the matrix V Eigenvalues: D_i^2 */ void Eigen_initFromSquareRoot (I, double **a, long numberOfRows, long numberOfColumns) { iam (Eigen); long numberOfZeroed, numberOfEigenvalues; long nsv = MIN (numberOfRows, numberOfColumns); my dimension = numberOfColumns; autoSVD svd = SVD_create_d (a, numberOfRows, numberOfColumns); /* Make sv's that are too small zero. These values occur automatically when the rank of A'A < numberOfColumns. This could occur when for example numberOfRows <= numberOfColumns. (n points in an n-dimensional space define maximally an n-1 dimensional surface for which we maximally need an n-1 dimensional basis.) */ numberOfZeroed = SVD_zeroSmallSingularValues (svd.peek(), 0.0); numberOfEigenvalues = nsv - numberOfZeroed; Eigen_init (me, numberOfEigenvalues, numberOfColumns); long k = 0; for (long i = 1; i <= nsv; i++) { double t = svd -> d[i]; if (t > 0.0) { my eigenvalues[++k] = t * t; for (long j = 1; j <= numberOfColumns; j++) { my eigenvectors[k][j] = svd -> v[j][i]; } } } Eigen_sort (me); } void Eigen_initFromSquareRootPair (I, double **a, long numberOfRows, long numberOfColumns, double **b, long numberOfRows_b) { iam (Eigen); double *u = nullptr, *v = nullptr, maxsv2 = -10.0; char jobu = 'N', jobv = 'N', jobq = 'Q'; long k, ll, m = numberOfRows, n = numberOfColumns, p = numberOfRows_b; long lda = m, ldb = p, ldu = lda, ldv = ldb, ldq = n; long lwork = MAX (MAX (3 * n, m), p) + n, info; /* Melder_assert (numberOfRows >= numberOfColumns || numberOfRows_b >= numberOfColumns);*/ my dimension = numberOfColumns; autoNUMvector alpha (1, n); autoNUMvector beta (1, n); autoNUMvector work (1, lwork); autoNUMvector iwork (1, n); autoNUMmatrix q (1, n, 1, n); autoNUMmatrix ac (NUMmatrix_transpose (a, numberOfRows, numberOfColumns), 1, 1); autoNUMmatrix bc (NUMmatrix_transpose (b, numberOfRows_b, numberOfColumns), 1, 1); (void) NUMlapack_dggsvd (&jobu, &jobv, &jobq, &m, &n, &p, &k, &ll, &ac[1][1], &lda, &bc[1][1], &ldb, &alpha[1], &beta[1], u, &ldu, v, &ldv, &q[1][1], &ldq, &work[1], &iwork[1], &info); if (info != 0) { Melder_throw (U"dggsvd fails."); } // Calculate the eigenvalues (alpha[i]/beta[i])^2 and store in alpha[i]. maxsv2 = -1.0; for (long i = k + 1; i <= k + ll; i++) { double t = alpha[i] / beta[i]; alpha[i] = t * t; if (alpha[i] > maxsv2) { maxsv2 = alpha[i]; } } // Deselect the eigenvalues < eps * max_eigenvalue. n = 0; for (long i = k + 1; i <= k + ll; i++) { if (alpha[i] < NUMfpp -> eps * maxsv2) { n++; alpha[i] = -1.0; } } if (ll - n < 1) { Melder_throw (U"No eigenvectors can be found. Matrix too singular."); } Eigen_init (me, ll - n, numberOfColumns); long ii = 0; for (long i = k + 1; i <= k + ll; i++) { if (alpha[i] == -1.0) { continue; } my eigenvalues[++ii] = alpha[i]; for (long j = 1; j <= numberOfColumns; j++) { my eigenvectors[ii][j] = q[i][j]; } } Eigen_sort (me); NUMnormalizeRows (my eigenvectors, my numberOfEigenvalues, numberOfColumns, 1); } void Eigen_initFromSymmetricMatrix_f (I, float **a, long n) { iam (Eigen); autoNUMmatrix m (1, n, 1, n); for (long i = 1; i <= n; i++) { for (long j = 1; j <= n; j++) { m[i][j] = a[i][j]; } } Eigen_initFromSymmetricMatrix (me, m.peek(), n); } void Eigen_initFromSymmetricMatrix (I, double **a, long n) { iam (Eigen); double wt[1], temp; char jobz = 'V', uplo = 'U'; long lwork = -1, info; my dimension = my numberOfEigenvalues = n; if (! my eigenvectors) { Eigen_init (me, n, n); } NUMmatrix_copyElements (a, my eigenvectors, 1, n, 1, n); // Get size of work array (void) NUMlapack_dsyev (&jobz, &uplo, &n, &my eigenvectors[1][1], &n, &my eigenvalues[1], wt, &lwork, &info); if (info != 0) { Melder_throw (U"dsyev initialization fails"); } lwork = (long) floor (wt[0]); autoNUMvector work (0L, lwork); (void) NUMlapack_dsyev (&jobz, &uplo, &n, &my eigenvectors[1][1], &n, &my eigenvalues[1], work.peek(), &lwork, &info); if (info != 0) { Melder_throw (U"dsyev fails"); } // We want descending order instead of ascending. for (long i = 1; i <= n / 2; i++) { long ilast = n - i + 1; SWAP (my eigenvalues[i], my eigenvalues[ilast]) for (long j = 1; j <= n; j++) { SWAP (my eigenvectors[i][j], my eigenvectors[ilast][j]) } } } Eigen Eigen_create (long numberOfEigenvalues, long dimension) { try { autoEigen me = Thing_new (Eigen); Eigen_init (me.peek(), numberOfEigenvalues, dimension); return me.transfer(); } catch (MelderError) { Melder_throw (U"Eigen not created."); } } long Eigen_getNumberOfEigenvectors (I) { iam (Eigen); return my numberOfEigenvalues; } double Eigen_getEigenvectorElement (I, long ivec, long element) { iam (Eigen); if (ivec > my numberOfEigenvalues || element < 1 || element > my dimension) { return NUMundefined; } return my eigenvectors[ivec][element]; } long Eigen_getDimensionOfComponents (I) { iam (Eigen); return my dimension; } double Eigen_getSumOfEigenvalues (I, long from, long to) { iam (Eigen); if (from < 1) { from = 1; } if (to < 1) { to = my numberOfEigenvalues; } if (to > my numberOfEigenvalues || from > to) { return NUMundefined; } double sum = 0.0; for (long i = from; i <= to; i++) { sum += my eigenvalues[i]; } return sum; } double Eigen_getCumulativeContributionOfComponents (I, long from, long to) { iam (Eigen); double partial = 0.0, sum = 0.0; if (to == 0) { to = my numberOfEigenvalues; } if (from > 0 && to <= my numberOfEigenvalues && from <= to) { for (long i = 1; i <= my numberOfEigenvalues; i++) { sum += my eigenvalues[i]; if (i >= from && i <= to) { partial += my eigenvalues[i]; } } } return sum > 0.0 ? partial / sum : 0.0; } long Eigen_getDimensionOfFraction (I, double fraction) { iam (Eigen); double sum = Eigen_getSumOfEigenvalues (me, 0, 0); if (sum == 0.0) { return 1; } long n = 1; double p = my eigenvalues[1]; while (p / sum < fraction && n < my numberOfEigenvalues) { p += my eigenvalues[++n]; } return n; } void Eigen_sort (I) { iam (Eigen); double temp, *e = my eigenvalues, **v = my eigenvectors; for (long i = 1; i < my numberOfEigenvalues; i++) { long k; double emax = e[k = i]; for (long j = i + 1; j <= my numberOfEigenvalues; j++) { if (e[j] > emax) { emax = e[k = j]; } } if (k != i) { // Swap eigenvalues and eigenvectors SWAP (e[i], e[k]) for (long j = 1; j <= my dimension; j++) { SWAP (v[i][j], v[k][j]) } } } } void Eigen_invertEigenvector (I, long ivec) { iam (Eigen); if (ivec < 1 || ivec > my numberOfEigenvalues) { return; } for (long j = 1; j <= my dimension; j++) { my eigenvectors[ivec][j] = - my eigenvectors[ivec][j]; } } void Eigen_drawEigenvalues (I, Graphics g, long first, long last, double ymin, double ymax, int fractionOfTotal, int cumulative, double size_mm, const char32 *mark, int garnish) { iam (Eigen); double xmin = first, xmax = last, scale = 1.0, sumOfEigenvalues = 0.0; long i; if (first < 1) { first = 1; } if (last < 1 || last > my numberOfEigenvalues) { last = my numberOfEigenvalues; } if (last <= first) { first = 1; last = my numberOfEigenvalues; } xmin = first - 0.5; xmax = last + 0.5; if (fractionOfTotal || cumulative) { sumOfEigenvalues = Eigen_getSumOfEigenvalues (me, 0, 0); if (sumOfEigenvalues <= 0.0) { sumOfEigenvalues = 1.0; } scale = sumOfEigenvalues; } if (ymax <= ymin) { ymax = Eigen_getSumOfEigenvalues (me, (cumulative ? 1 : first), first) / scale; ymin = Eigen_getSumOfEigenvalues (me, (cumulative ? 1 : last), last) / scale; if (ymin > ymax) { double tmp = ymin; ymin = ymax; ymax = tmp; } } Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); for (i = first; i <= last; i++) { double accu = Eigen_getSumOfEigenvalues (me, (cumulative ? 1 : i), i); Graphics_mark (g, i, accu / scale, size_mm, mark); } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textLeft (g, true, fractionOfTotal ? (cumulative ? U"Cumulative fractional eigenvalue" : U"Fractional eigenvalue") : (cumulative ? U"Cumulative eigenvalue" : U"Eigenvalue")); Graphics_ticks (g, first, last, true, true, false, true); Graphics_marksLeft (g, 2, true, true, false); Graphics_textBottom (g, true, U"Index"); } } void Eigen_drawEigenvector (I, Graphics g, long ivec, long first, long last, double ymin, double ymax, int weigh, double size_mm, const char32 *mark, int connect, char32 **rowLabels, int garnish) { iam (Eigen); double xmin = first, xmax = last; if (ivec < 1 || ivec > my numberOfEigenvalues) { return; } if (last <= first) { first = 1; last = my dimension; xmin = 0.5; xmax = last + 0.5; } double *vec = my eigenvectors[ivec]; double w = weigh ? sqrt (my eigenvalues[ivec]) : 1.0; // If ymax < ymin the eigenvector will automatically be drawn inverted. if (ymax == ymin) { NUMvector_extrema (vec, first, last, &ymin, &ymax); ymax *= w; ymin *= w; } Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); for (long i = first; i <= last; i++) { Graphics_mark (g, i, w * vec[i], size_mm, mark); if (connect && i > first) { Graphics_line (g, i - 1.0, w * vec[i - 1], i, w * vec[i]); } } Graphics_unsetInner (g); if (garnish) { Graphics_markBottom (g, first, false, true, false, rowLabels ? rowLabels[first] : Melder_integer (first)); Graphics_markBottom (g, last, false, true, false, rowLabels ? rowLabels[last] : Melder_integer (last)); Graphics_drawInnerBox (g); if (ymin * ymax < 0.0) { Graphics_markLeft (g, 0.0, true, true, true, nullptr); } Graphics_marksLeft (g, 2, true, true, false); if (! rowLabels) { Graphics_textBottom (g, true, U"Element number"); } } } void Eigens_alignEigenvectors (Collection me) { if (my size < 2) { return; } Eigen e1 = (Eigen) my item[1]; double **evec1 = e1 -> eigenvectors; long nev1 = e1 -> numberOfEigenvalues; long dimension = e1 -> dimension; for (long i = 2; i <= my size; i++) { Eigen e2 = (Eigen) my item[i]; if (e2 -> dimension != dimension) { Melder_throw (U"The dimension of the eigenvectors must be equal (offending object is ", i, U")."); } } /* Correlate eigenvectors. If r < 0 then mirror the eigenvector. */ for (long i = 2; i <= my size; i++) { Eigen e2 = (Eigen) my item[i]; double **evec2 = e2 -> eigenvectors; for (long j = 1; j <= MIN (nev1, e2 -> numberOfEigenvalues); j++) { double ip = 0.0; for (long k = 1; k <= dimension; k++) { ip += evec1[j][k] * evec2[j][k]; } if (ip < 0.0) { for (long k = 1; k <= dimension; k++) { evec2[j][k] = - evec2[j][k]; } } } } } static void Eigens_getAnglesBetweenSubspaces (I, thou, long ivec_from, long ivec_to, double *angles_degrees) { iam (Eigen); thouart (Eigen); long nvectors = ivec_to - ivec_from + 1; for (long i = 1; i <= nvectors; i++) { angles_degrees[i] = NUMundefined; } long nmin = my numberOfEigenvalues < thy numberOfEigenvalues ? my numberOfEigenvalues : thy numberOfEigenvalues; if (my dimension != thy dimension) { Melder_throw (U"The eigenvectors must have the same dimension."); } if (ivec_from > ivec_to || ivec_from < 1 || ivec_to > nmin) { Melder_throw (U"Eigenvector range too large."); } autoNUMmatrix c (1, nvectors, 1, nvectors); /* Algorithm 12.4.3 Golub & van Loan Because we deal with eigenvectors we don't have to do the QR-decomposition, the columns in the Q's are the eigenvectors. Compute C. */ for (long i = 1; i <= nvectors; i++) { for (long j = 1; j <= nvectors; j++) { for (long k = 1; k <= my dimension; k++) { c[i][j] += my eigenvectors[ivec_from + i - 1][k] * thy eigenvectors[ivec_from + j - 1][k]; } } } autoSVD svd = SVD_create_d (c.peek(), nvectors, nvectors); for (long i = 1; i <= nvectors; i++) { angles_degrees[i] = acos (svd -> d[i]) * 180.0 / NUMpi; } } double Eigens_getAngleBetweenEigenplanes_degrees (I, thou) { iam (Eigen); thouart (Eigen); double angles_degrees[3]; Eigens_getAnglesBetweenSubspaces (me, thee, 1, 2, angles_degrees); return angles_degrees[2]; } #undef MAX #undef MIN #undef SWAP /* End of file Eigen.cpp */ praat-6.0.04/dwsys/Eigen.h000066400000000000000000000060061261542461700152730ustar00rootroot00000000000000#ifndef _Eigen_h_ #define _Eigen_h_ /* Eigen.h * * Copyright (C) 1993-2012 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header djmw 20110306 Latest modification */ #include "Collection.h" #include "Graphics.h" #include "Strings_.h" #include "Eigen_def.h" oo_CLASS_CREATE (Eigen, Daata); Eigen Eigen_create (long numberOfEigenvalues, long dimension); void Eigen_init (I, long numberOfEigenvalues, long dimension); void Eigen_initFromSymmetricMatrix_f (I, float **a, long n); void Eigen_initFromSymmetricMatrix (I, double **a, long n); void Eigen_initFromSquareRoot (I, double **a, long numberOfRows, long numberOfColumns); /* Calculate eigenstructure for symmetric matrix A'A (e.g. covariance matrix), when only A is given. Precondition: numberOfRows > 1 Method: SVD. */ void Eigen_initFromSquareRootPair (I, double **a, long numberOfRows, long numberOfColumns, double **b, long numberOfRows_b); /* Calculate eigenstructure for A'Ax - lambda B'Bx = 0 Preconditions: numberOfRows >= numberOfColumns && numberOfRows_b >= numberOfColumns Method: Generalized SVD. */ long Eigen_getNumberOfEigenvectors (I); long Eigen_getDimensionOfComponents (I); double Eigen_getCumulativeContributionOfComponents (I, long from, long to); long Eigen_getDimensionOfFraction (I, double fraction); double Eigen_getEigenvectorElement (I, long ivec, long element); double Eigen_getSumOfEigenvalues (I, long from, long to); void Eigen_sort (I); /* Sort eigenvalues and corresponding eigenvectors in decreasing order. */ void Eigen_invertEigenvector (I, long ivec); void Eigen_drawEigenvalues (I, Graphics g, long first, long last, double ymin, double ymax, int fractionOfTotal, int cumulative, double size_mm, const char32 *mark, int garnish); void Eigen_drawEigenvector (I, Graphics g, long ivec, long first, long last, double minimum, double maximum, int weigh, double size_mm, const char32 *mark, int connect, char32 **rowLabels, int garnish); /* Draw eigenvector. When rowLabels != nullptr, draw row text labels on bottom axis. */ void Eigens_alignEigenvectors (Collection me); /* Correlate all eigenvectors with the eigenvectors of the first Eigen. If r < 0 then mirror the eigenvectors of */ double Eigens_getAngleBetweenEigenplanes_degrees (I, thou); /* Get angle between the eigenplanes, spanned by the first two eigenvectors, . */ #endif /* _Eigen_h_ */ praat-6.0.04/dwsys/Eigen_def.h000066400000000000000000000021031261542461700161030ustar00rootroot00000000000000/* Eigen_def.h * * Copyright (C) 1993-2008 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header */ #define ooSTRUCT Eigen oo_DEFINE_CLASS (Eigen, Daata) oo_LONG (numberOfEigenvalues) oo_LONG (dimension) oo_DOUBLE_VECTOR (eigenvalues, numberOfEigenvalues) oo_DOUBLE_MATRIX (eigenvectors, numberOfEigenvalues, dimension) oo_END_CLASS (Eigen) #undef ooSTRUCT /* End of file Eigen_def.h */ praat-6.0.04/dwsys/FileInMemory.cpp000066400000000000000000000214601261542461700171370ustar00rootroot00000000000000/* FileInMemory.cpp * * Copyright (C) 2012-2013, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "FileInMemory.h" #include "Strings_.h" Thing_implement (FileInMemory, Daata, 0); void structFileInMemory :: v_copy (thou) { thouart (FileInMemory); FileInMemory_Parent :: v_copy (thee); thy d_path = Melder_dup (d_path); thy d_id = Melder_dup (d_id); thy d_numberOfBytes = d_numberOfBytes; thy d_data = NUMvector (0, d_numberOfBytes); memcpy (thy d_data, d_data, d_numberOfBytes+1); } void structFileInMemory :: v_destroy () { Melder_free (d_path); Melder_free (d_id); NUMvector_free (d_data, 0); FileInMemory_Parent :: v_destroy (); } void structFileInMemory :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"File name: ", d_path); MelderInfo_writeLine (U"Id: ", d_id); MelderInfo_writeLine (U"Number of bytes: ", d_numberOfBytes); } FileInMemory FileInMemory_create (MelderFile file) { try { if (! MelderFile_readable (file)) { Melder_throw (U"File not readable."); } long length = MelderFile_length (file); if (length <= 0) { Melder_throw (U"File is empty."); } autoFileInMemory me = Thing_new (FileInMemory); my d_path = Melder_dup (file -> path); my d_id = Melder_dup (MelderFile_name (file)); my d_numberOfBytes = length; my d_data = NUMvector (0, my d_numberOfBytes); // one extra for 0-byte at end if text MelderFile_open (file); for (long i = 0; i < my d_numberOfBytes; i++) { unsigned int number = bingetu1 (file -> filePointer); my d_data[i] = number; } my d_data[my d_numberOfBytes] = 0; // one extra MelderFile_close (file); return me.transfer(); } catch (MelderError) { Melder_throw (U"FileInMemory not created from \"", Melder_fileToPath (file), U"\"."); } } FileInMemory FileInMemory_createWithData (long numberOfBytes, const char *data, const char32 *path, const char32 *id) { try { autoFileInMemory me = Thing_new (FileInMemory); my d_path = Melder_dup (path); my d_id = Melder_dup (id); my d_numberOfBytes = numberOfBytes; my d_data = const_cast (data); // copy pointer to data only return me.transfer (); } catch (MelderError) { Melder_throw (U"FileInMemory not create from data."); } } void FileInMemory_setId (FileInMemory me, const char32 *newId) { Melder_free (my d_id); my d_id = Melder_dup (newId); } void FileInMemory_showAsCode (FileInMemory me, const char32 *name, long numberOfBytesPerLine) { if (numberOfBytesPerLine <= 0) numberOfBytesPerLine = 20; // autoNUMvector data (0, my d_numberOfBytes); ???? MelderInfo_writeLine (U"\t\tstatic unsigned char ", name, U"_data[", my d_numberOfBytes+1, U"] = {"); for (long i = 0; i < my d_numberOfBytes; i++) { unsigned char number = my d_data[i]; MelderInfo_write ((i % numberOfBytesPerLine == 0 ? U"\t\t\t" : U""), number, U",", ((i % numberOfBytesPerLine == (numberOfBytesPerLine - 1)) ? U"\n" : U" ")); } MelderInfo_writeLine ((my d_numberOfBytes - 1) % numberOfBytesPerLine == (numberOfBytesPerLine - 1) ? U"\t\t\t0};" : U"0};"); MelderInfo_write (U"\t\tautoFileInMemory ", name, U" = FileInMemory_createWithData ("); MelderInfo_writeLine (my d_numberOfBytes, U", reinterpret_cast (&", name, U"_data), \n\t\t\tU\"", my d_path, U"\", \n\t\t\tU\"", my d_id, U"\");"); } Thing_implement (FilesInMemory, SortedSet, 0); int structFilesInMemory :: s_compare_name (I, thou) { iam (FileInMemory); thouart (FileInMemory); return Melder_cmp (my d_path, thy d_path); } int structFilesInMemory :: s_compare_id (I, thou) { iam (FileInMemory); thouart (FileInMemory); return Melder_cmp (my d_id, thy d_id); } FilesInMemory FilesInMemory_create () { try { autoFilesInMemory me = Thing_new (FilesInMemory); Collection_init (me.peek(), classFileInMemory, 30); return me.transfer(); } catch (MelderError) { Melder_throw (U"FilesInMemory not created."); } } FilesInMemory FilesInMemory_createFromDirectoryContents (const char32 *dirpath, const char32 *fileGlobber) { try { structMelderDir parent = { { 0 } }; Melder_pathToDir (dirpath, &parent); autoStrings thee = Strings_createAsFileList (Melder_cat (dirpath, U"/", fileGlobber)); if (thy numberOfStrings < 1) { Melder_throw (U"No files found."); } autoFilesInMemory me = FilesInMemory_create (); for (long i = 1; i <= thy numberOfStrings; i++) { structMelderFile file = { 0 }; MelderDir_getFile (&parent, thy strings[i], &file); autoFileInMemory fim = FileInMemory_create (&file); Collection_addItem (me.peek(), fim.transfer()); } return me.transfer(); } catch (MelderError) { Melder_throw (U"FilesInMemory not created from directory \"", dirpath, U"\" for files that match \"", fileGlobber, U"\"."); } } void FilesInMemory_showAsCode (FilesInMemory me, const char32 *name, long numberOfBytesPerLine) { autoMelderString one_fim; MelderInfo_writeLine (U"#include \"Collection.h\""); MelderInfo_writeLine (U"#include \"FileInMemory.h\""); MelderInfo_writeLine (U"#include \"melder.h\"\n"); MelderInfo_writeLine (U"FilesInMemory create_", name, U" () {"); MelderInfo_writeLine (U"\ttry {"); MelderInfo_writeLine (U"\t\tautoFilesInMemory me = FilesInMemory_create ();"); for (long ifile = 1; ifile <= my size; ifile++) { FileInMemory fim = (FileInMemory) my item[ifile]; MelderString_copy (&one_fim, name, ifile); FileInMemory_showAsCode (fim, one_fim.string, numberOfBytesPerLine); MelderInfo_writeLine (U"\t\tCollection_addItem (me.peek(), ", one_fim.string, U".transfer());\n"); } MelderInfo_writeLine (U"\t\treturn me.transfer();"); MelderInfo_writeLine (U"\t} catch (MelderError) {"); MelderInfo_writeLine (U"\t\tMelder_throw (L\"FilesInMemory not created.\");"); MelderInfo_writeLine (U"\t}"); MelderInfo_writeLine (U"}\n\n"); } void FilesInMemory_showOneFileAsCode (FilesInMemory me, long index, const char32 *name, long numberOfBytesPerLine) { if (index < 1 || index > my size) return; MelderInfo_writeLine (U"#include \"FileInMemory.h\""); MelderInfo_writeLine (U"#include \"melder.h\"\n"); MelderInfo_writeLine (U"static FileInMemory create_new_object () {"); MelderInfo_writeLine (U"\ttry {"); autoMelderString one_fim; FileInMemory fim = (FileInMemory) my item[index]; MelderString_append (&one_fim, name, index); FileInMemory_showAsCode (fim, U"me", numberOfBytesPerLine); MelderInfo_writeLine (U"\t\treturn me.transfer();"); MelderInfo_writeLine (U"\t} catch (MelderError) {"); MelderInfo_writeLine (U"\t\tMelder_throw (L\"FileInMemory not created.\");"); MelderInfo_writeLine (U"\t}"); MelderInfo_writeLine (U"}\n\n"); MelderInfo_writeLine (U"FileInMemory ", name, U" = create_new_object ();"); } long FilesInMemory_getIndexFromId (FilesInMemory me, const char32 *id) { long index = 0; for (long i = 1; i <= my size; i++) { FileInMemory fim = (FileInMemory) my item[i]; if (Melder_cmp (id, fim -> d_id) == 0) { index = i; break; } } return index; } Strings FilesInMemory_to_Strings_id (FilesInMemory me) { try { autoStrings thee = Thing_new (Strings); thy strings = NUMvector (1, my size); thy numberOfStrings = 0; for (long ifile = 1; ifile <= my size; ifile++) { FileInMemory fim = (FileInMemory) my item[ifile]; thy strings[ifile] = Melder_dup_f (fim -> d_id); thy numberOfStrings++; } return thee.transfer(); } catch (MelderError) { Melder_throw (U"No Strings created from FilesinMemory."); } } char * FilesInMemory_getCopyOfData (FilesInMemory me, const char32 *id, long *numberOfBytes) { *numberOfBytes = 0; long index = FilesInMemory_getIndexFromId (me, id); if (index == 0) return 0; FileInMemory fim = (FileInMemory) my item[index]; char *data = (char *) _Melder_malloc (fim -> d_numberOfBytes); if (data == 0 || ! memcpy (data, fim -> d_data, fim -> d_numberOfBytes)) { //Melder_appendError (U"No memory for dictionary."); return nullptr; } *numberOfBytes = fim -> d_numberOfBytes; return data; } const char * FilesInMemory_getData (FilesInMemory me, const char32 *id, long *numberOfBytes) { *numberOfBytes = 0; long index = FilesInMemory_getIndexFromId (me, id); if (index == 0) return 0; FileInMemory fim = (FileInMemory) my item[index]; *numberOfBytes = fim -> d_numberOfBytes; return fim -> d_data; } /* End of file FileInMemory.cpp */ praat-6.0.04/dwsys/FileInMemory.h000066400000000000000000000047021261542461700166040ustar00rootroot00000000000000#ifndef _FileInMemory_h_ #define _FileInMemory_h_ /* FileInMemory.h * * Copyright (C) 2011-2012 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20120125 */ #include "Collection.h" #include "Strings_.h" #include "melder.h" #include "Strings_.h" Thing_define (FileInMemory, Daata) { char32 *d_path; char32 *d_id; long d_numberOfBytes; char *d_data; void v_copy (Any data_to) override; void v_destroy () override; void v_info () override; }; FileInMemory FileInMemory_create (MelderFile file); FileInMemory FileInMemory_createWithData (long numberOfBytes, const char *data, const char32 *path, const char32 *id); void FileInMemory_dontOwnData (FileInMemory me); void FileInMemory_setId (FileInMemory me, const char32 *newId); void FileInMemory_showAsCode (FileInMemory me, const char32 *name, long numberOfBytesPerLine); Thing_define (FilesInMemory, SortedSet) { int d_sortKey; static int s_compare_name (Any data1, Any data2); static int s_compare_id (Any data1, Any data2); Data_CompareFunction v_getCompareFunction () override { return d_sortKey == 0 ? s_compare_name : s_compare_id; } }; FilesInMemory FilesInMemory_create (); FilesInMemory FilesInMemory_createFromDirectoryContents (const char32 *dirpath, const char32 *file); void FilesInMemory_showAsCode (FilesInMemory me, const char32 *name, long numberOfBytesPerLine); void FilesInMemory_showOneFileAsCode (FilesInMemory me, long index, const char32 *name, long numberOfBytesPerLine); long FilesInMemory_getIndexFromId (FilesInMemory me, const char32 *id); Strings FilesInMemory_to_Strings_id (FilesInMemory me); char * FilesInMemory_getCopyOfData (FilesInMemory me, const char32 *id, long *numberOfBytes); const char * FilesInMemory_getData (FilesInMemory me, const char32 *id, long *numberOfBytes); #endif // _FileInMemory_h_ praat-6.0.04/dwsys/Graphics_extensions.cpp000066400000000000000000000213151261542461700206160ustar00rootroot00000000000000/* Graphics_extensions.c * * Copyright (C) 2012 -2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20120727 latest modification */ #include "Graphics_extensions.h" #include "NUM2.h" #include "Permutation.h" /* Draw a box plot of data[1..ndata]. The vertical center line of the plot is at position 'x'. The rectangle box is 2*w wide, the whisker 2*r. All drawing outside [ymin, ymax] is clipped. */ void Graphics_boxAndWhiskerPlot (Graphics g, double data[], long ndata, double x, double r, double w, double ymin, double ymax) { int lineType = Graphics_inqLineType (g); Melder_assert (r > 0.0 && w > 0.0); if (ndata < 3) { return; } /* Sort the data (ascending: data[1] <= ... <= data[ndata]). Get the median (q50) and the upper and lower quartile points (q25 and q75). Now q25 and q75 are the lower and upper hinges, respectively. The fances can be calcultaed from q25 and q75. The spread is defined as the interquartile range or midrange |q75 - q25|. The fences are defined as: (lower/upper) innerfence = (lower/upper) hinge +/- 1.5 hspread (lower/upper) outerfence = (lower/upper) hinge +/- 3.0 hspread */ NUMsort_d (ndata, data); if (ymax <= ymin) { ymin = data[1]; ymax = data[ndata]; } if (data[1] > ymax || data[ndata] < ymin) { return; } double mean = 0.0; for (long i = 1; i <= ndata; i++) { mean += data[i]; } mean /= ndata; double q25 = NUMquantile (ndata, data, 0.25); double q50 = NUMquantile (ndata, data, 0.5); double q75 = NUMquantile (ndata, data, 0.75); double hspread = fabs (q75 - q25); double lowerOuterFence = q25 - 3.0 * hspread; double lowerInnerFence = q25 - 1.5 * hspread; double upperInnerFence = q75 + 1.5 * hspread; double upperOuterFence = q75 + 3.0 * hspread; /* Decide whether there are outliers that have to be drawn. First process data from below (data are sorted). */ long i = 1, ie = ndata; while (i <= ie && data[i] < ymin) { i++; } Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); while (i <= ie && data[i] < lowerOuterFence) { Graphics_text (g, x, data[i], U"o"); i++; } while (i <= ie && data[i] < lowerInnerFence) { Graphics_text (g, x, data[i], U"*"); i++; } double lowerWhisker = data[i] < q25 ? data[i] : lowerInnerFence; if (lowerWhisker > ymax) { return; } // Next process data from above. i = ndata; ie = i; while (i >= ie && data[i] > ymax) { i--; } while (i >= ie && data[i] > upperOuterFence) { Graphics_text (g, x, data[i], U"o"); i--; } while (i >= ie && data[i] > upperInnerFence) { Graphics_text (g, x, data[i], U"*"); i--; } double upperWhisker = data[i] > q75 ? data[i] : upperInnerFence; if (upperWhisker < ymin) { return; } /* Determine what parts of the "box" have to be drawn within the range [ymin, ymax]. Horizontal lines first. */ double y1 = lowerWhisker; if (ymax > y1 && ymin < y1) { Graphics_line (g, x - r, y1, x + r, y1); } y1 = q25; if (ymax > y1 && ymin < y1) { Graphics_line (g, x - w, y1, x + w, y1); } y1 = q50; if (ymax > y1 && ymin < y1) { Graphics_line (g, x - w, y1, x + w, y1); } y1 = q75; if (ymax > y1 && ymin < y1) { Graphics_line (g, x - w, y1, x + w, y1); } y1 = upperWhisker; if (ymax > y1 && ymin < y1) { Graphics_line (g, x - r, y1, x + r, y1); } // Extension: draw the mean too. y1 = mean; if (ymax > y1 && ymin < y1) { Graphics_setLineType (g, Graphics_DOTTED); Graphics_line (g, x - w, y1, x + w, y1); Graphics_setLineType (g, lineType); } // Now process the vertical lines. y1 = lowerWhisker; double y2 = q25; if (ymax > y1 && ymin < y2) { y1 = y1 > ymin ? y1 : ymin; y2 = y2 < ymax ? y2 : ymax; Graphics_line (g, x, y1, x, y2); } y1 = q25; y2 = q75; if (ymax > y1 && ymin < y2) { y1 = y1 > ymin ? y1 : ymin; y2 = y2 < ymax ? y2 : ymax; Graphics_line (g, x - w, y1, x - w, y2); Graphics_line (g, x + w, y1, x + w, y2); } y1 = q75; y2 = upperWhisker; if (ymax > y1 && ymin < y2) { y1 = y1 > ymin ? y1 : ymin; y2 = y2 < ymax ? y2 : ymax; Graphics_line (g, x, y1, x, y2); } } void Graphics_quantileQuantilePlot (Graphics g, long numberOfQuantiles, double xdata[], long xnumberOfData, double ydata[], long ynumberOfData, double xmin, double xmax, double ymin, double ymax, int labelSize, const char32 *plotLabel) { int fontSize = Graphics_inqFontSize (g); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); Graphics_setFontSize (g, labelSize); autoNUMvector xsorted (NUMvector_copy (xdata, 1, xnumberOfData), 1); autoNUMvector ysorted (NUMvector_copy (ydata, 1, ynumberOfData), 1); NUMsort_d (xnumberOfData, xsorted.peek()); NUMsort_d (ynumberOfData, ysorted.peek()); long numberOfData = xnumberOfData < ynumberOfData ? xnumberOfData : ynumberOfData; numberOfQuantiles = numberOfData < numberOfQuantiles ? numberOfData : numberOfQuantiles; double un = pow (0.5, 1.0 / numberOfQuantiles); double u1 = 1.0 - un; if (xmin == xmax) { xmin = NUMquantile (xnumberOfData, xsorted.peek(), u1); xmax = NUMquantile (xnumberOfData, xsorted.peek(), un); } if (ymin == ymax) { ymin = NUMquantile (ynumberOfData, ysorted.peek(), u1); ymax = NUMquantile (ynumberOfData, ysorted.peek(), un); } for (long i = 1; i <= numberOfQuantiles; i++) { double ui = i == 1 ? u1 : (i == numberOfQuantiles ? un : (i - 0.3175) / (numberOfQuantiles + 0.365)); double qx = NUMquantile (xnumberOfData, xsorted.peek(), ui); double qy = NUMquantile (ynumberOfData, ysorted.peek(), ui); if (qx < xmin || qx > xmax || qy < ymin || qy > ymax) continue; // outside area Graphics_text (g, qx, qy, plotLabel); } Graphics_setLineType (g, Graphics_DOTTED); Graphics_line (g, xmin, ymin, xmax, ymax); Graphics_setLineType (g, Graphics_DRAWN); Graphics_setFontSize (g, fontSize); } void Graphics_matrixAsSquares (Graphics g, double **matrix, long numberOfRows, long numberOfColumns, double zmin, double zmax, double cellSizeFactor, int randomFillOrder) { long numberOfCells = numberOfRows * numberOfColumns; autoPermutation p = Permutation_create (numberOfCells); if (randomFillOrder) { Permutation_permuteRandomly_inline (p.peek(), 1, numberOfCells); } double zAbsMax = fabs (zmax) > fabs (zmin) ? fabs (zmax) : fabs (zmin); Graphics_Colour colour = Graphics_inqColour (g); double x1WC, x2WC, y1WC, y2WC; Graphics_inqWindow (g, &x1WC, &x2WC, &y1WC, &y2WC); double dx = fabs (x2WC - x1WC) / numberOfColumns; double dy = fabs (y2WC - y1WC) / numberOfRows; for (long i = 1; i <= numberOfCells; i++) { long index = Permutation_getValueAtIndex (p.peek(), i); long irow = (index - 1) / numberOfColumns + 1; long icol = (index - 1) % numberOfColumns + 1; double z = matrix[irow][icol]; z = z < zmin ? zmin : z; z = z > zmax ? zmax : z; double zweight = sqrt (fabs (z) / zAbsMax); // Area length^2) double xcenter = (icol - 0.5) * dx; double ycenter = (irow - 0.5) * dy; double x1 = x1WC + xcenter - zweight * 0.5 * dx * cellSizeFactor; x1 = x1 < x1WC ? x1WC : x1; double x2 = x1WC + xcenter + zweight * 0.5 * dx * cellSizeFactor; x2 = x2 > x2WC ? x2WC : x2; double y1 = y1WC + ycenter - zweight * 0.5 * dy * cellSizeFactor; y1 = y1 < y1WC ? y1WC : y1; double y2 = y1WC + ycenter + zweight * 0.5 * dy * cellSizeFactor; y2 = y2 > y2WC ? y2WC : y2; if (z > 0.0) { Graphics_setColour (g, Graphics_WHITE); } Graphics_fillRectangle (g, x1, x2, y1, y2); Graphics_setColour (g, colour); Graphics_rectangle (g, x1, x2 , y1, y2); } } void Graphics_lagPlot (Graphics g, double data[], long numberOfData, double xmin, double xmax, long lag, int labelSize, const char32 *plotLabel) { if (lag < 0 || lag >= numberOfData) { return; } int fontSize = Graphics_inqFontSize (g); Graphics_setFontSize (g, labelSize); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); // plot x[i] vertically and x[i-lag] horizontally for (long i = 1; i <= numberOfData - lag; i++) { double x = data[i + lag], y = data[i]; if (x >= xmin && x <= xmax && y >= xmin && y <= xmax) { Graphics_text (g, x, y, plotLabel); } } Graphics_setLineType (g, Graphics_DRAWN); Graphics_setFontSize (g, fontSize); } /* End of file Graphics_extensions.c */ praat-6.0.04/dwsys/Graphics_extensions.h000066400000000000000000000034351261542461700202660ustar00rootroot00000000000000#ifndef _Graphics_extensions_h_ #define _Graphics_extensions_h_ /* Graphics_extensions.h * * Copyright (C) 2012-2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20120914 Latest modification. */ #include "Graphics.h" /* Draw a box plot of data[1..ndata]. The vertical center line of the plot is at position 'x'. The rectangle box is 2*w wide, the whisker 2*r. All drawing outside [ymin, ymax] is clipped. */ void Graphics_boxAndWhiskerPlot (Graphics g, double data[], long ndata, double x, double r, double w, double ymin, double ymax); void Graphics_quantileQuantilePlot (Graphics g, long numberOfQuantiles, double xdata[], long xnumberOfData, double ydata[], long ynumberOfData, double xmin, double xmax, double ymin, double ymax, int labelSize, const char32 *plotLabel); void Graphics_matrixAsSquares (Graphics g, double **matrix, long numberOfRows, long numberOfColumns, double zmin, double zmax, double cellSizeFactor, int randomFillOrder); void Graphics_lagPlot (Graphics g, double x[], long numberOfData, double xmin, double xmax, long lag, int labelSize, const char32 *plotLabel); #endif /* _Graphics_extensions_h_ */ praat-6.0.04/dwsys/Index.cpp000066400000000000000000000063141261542461700156500ustar00rootroot00000000000000/* Index.cpp * * Copyright (C) 2005-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20050724 djmw 20061212 Changed info to Melder_writeLine format. djmw 20070102 djmw 20071012 Added: o_CAN_WRITE_AS_ENCODING.h djmw 20110304 Thing_new */ #include #include "Index.h" #include "NUM2.h" #include "oo_DESTROY.h" #include "Index_def.h" #include "oo_COPY.h" #include "Index_def.h" #include "oo_EQUAL.h" #include "Index_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Index_def.h" #include "oo_WRITE_TEXT.h" #include "Index_def.h" #include "oo_WRITE_BINARY.h" #include "Index_def.h" #include "oo_READ_TEXT.h" #include "Index_def.h" #include "oo_READ_BINARY.h" #include "Index_def.h" #include "oo_DESCRIPTION.h" #include "Index_def.h" Thing_implement (Index, Daata, 0); void structIndex :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Number of elements: ", numberOfElements); } void Index_init (I, long numberOfElements) { iam (Index); if (numberOfElements < 1) { Melder_throw (U"Cannot create index without elements."); } my classes = Ordered_create (); my numberOfElements = numberOfElements; my classIndex = NUMvector (1, numberOfElements); } Index Index_extractPart (I, long from, long to) { iam (Index); try { if (from == 0) { from = 1; } if (to == 0) { to = my numberOfElements; } if (to < from || from < 1 || to > my numberOfElements) { Melder_throw (U"Range should be in interval [1,", my numberOfElements, U"]."); } autoIndex thee = Data_copy (me); thy numberOfElements = to - from + 1; for (long i = 1; i <= thy numberOfElements; i++) { thy classIndex[i] = my classIndex[from + i - 1]; } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": part not extracted."); } } Thing_implement (StringsIndex, Index, 0); StringsIndex StringsIndex_create (long numberOfElements) { try { autoStringsIndex me = (StringsIndex) Thing_new (StringsIndex); Index_init (me.peek(), numberOfElements); return me.transfer(); } catch (MelderError) { Melder_throw (U"StringsIndex not created."); } } int StringsIndex_getClass (StringsIndex me, char32 *klasLabel) { for (long i = 1; i <= my classes -> size; i++) { SimpleString ss = (SimpleString) my classes -> item[i]; if (Melder_cmp (ss -> string, klasLabel) == 0) { return i; } } return 0; } long StringsIndex_countItems (StringsIndex me, int iclass) { long sum = 0; for (long i = 1; i <= my numberOfElements; i++) if (my classIndex[i] == iclass) { sum++; } return sum; } /* End of Index.cpp */ praat-6.0.04/dwsys/Index.h000066400000000000000000000023031261542461700153070ustar00rootroot00000000000000#ifndef _Index_h_ #define _Index_h_ /* Index.h * * Copyright (C) 2005-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Collection.h" #include "Index_def.h" oo_CLASS_CREATE (Index, Daata); oo_CLASS_CREATE (StringsIndex, Index); void Index_init (I, long numberOfElements); Index Index_extractPart (I, long from, long to); StringsIndex StringsIndex_create (long numberOfElements); int StringsIndex_getClass (StringsIndex me, char32 *classLabel); long StringsIndex_countItems (StringsIndex me, int iclas); #endif /* _Index_h_ */ praat-6.0.04/dwsys/Index_def.h000066400000000000000000000023201261542461700161240ustar00rootroot00000000000000/* Index_def.h * * Copyright (C) 2005-2006 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20050724 djmw 20060529 Added object version numbers. */ #define ooSTRUCT Index oo_DEFINE_CLASS (Index, Daata) oo_OBJECT (Ordered, 0, classes) oo_LONG (numberOfElements) oo_LONG_VECTOR (classIndex, numberOfElements) #if oo_DECLARING void v_info () override; #endif oo_END_CLASS(Index) #undef ooSTRUCT #define ooSTRUCT StringsIndex oo_DEFINE_CLASS (StringsIndex, Index) oo_END_CLASS(StringsIndex) #undef ooSTRUCT /* End of file Index_def.h */ praat-6.0.04/dwsys/Makefile000066400000000000000000000014661261542461700155400ustar00rootroot00000000000000# makefile for library "dwsys". # David Weenink 20130826 include ../makefile.defs CPPFLAGS = -I ../stat -I ../num -I ../sys -I dwsys -I ../external/gsl -I ../kar all: libdwsys.a OBJECTS = Collection_extensions.o Command.o \ DLL.o Eigen.o FileInMemory.o Graphics_extensions.o Index.o \ NUM2.o NUMhuber.o NUMlapack.o NUMmachar.o \ NUMf2c.o NUMcblas.o NUMclapack.o NUMfft_d.o NUMsort2.o \ NUMmathlib.o NUMstring.o \ Permutation.o Permutation_and_Index.o \ regularExp.o SimpleVector.o Simple_extensions.o \ SVD.o .PHONY: all clean all: libdwsys.a clean: $(RM) $(OBJECTS) $(RM) libdwsys.a libdwsys.a: $(OBJECTS) NUMmachar.o touch libdwsys.a rm libdwsys.a $(AR) cq libdwsys.a $(OBJECTS) $(RANLIB) libdwsys.a $(OBJECTS): *.h ../stat/*.h ../num/NUM.h ../sys/*.h ../external/gsl/*.h ../dwsys/*.h ../kar/*.h praat-6.0.04/dwsys/NUM2.cpp000066400000000000000000002310111261542461700153140ustar00rootroot00000000000000/* NUM2.cpp * * Copyright (C) 1993-2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020819 GPL header djmw 20020819 Split nonGLP part off. djmw 20001109 Changed stop criteria in NUMsvdcmp and NUMtqli. djmw 20020819 Split into GPL and nonGPL part. djmw 20021008 Removed SVD_sort. djmw 20030619 Removed calls to NRC svd-routines. djmw 20030623 Removed tqli en tred calls. djmw 20030703 Replaced NUMincompleteBeta with gsl_sf_beta_inc. djmw 20030710 NUMminimize_brent now also returns the minimum function value. djmw 20030731 NUMridders: better approximation for small d. NUMinvFisherQ better approximation for p < 0.5 djmw 20030813 Added NUMmad and NUMstatistics_huber. djmw 20030825 Replaced gsl_sf_beta_inc with NUMincompleteBeta pb 20030828 Improvements for invFisherQ, ridders, studentP, studentQ, invStudentQ, invChiSquareQ: modifications for 'undefined' return values. djmw 20030830 Corrected a bug in NUMtriangularfilter_amplitude djmw 20031111 Added NUMdmatrix_transpose, NUMdmatrix_printMatlabForm djmw 20040105 Added NUMmahalanobisDistance_chi djmw 20040211 Modified NUMstrings_copyElements: if (form[i]==NULL) then {to[i]= NULL}. djmw 20040303 Added NUMstring_containsPrintableCharacter. djmw 20050406 NUMprocrutus->NUMprocrustes djmw 20060319 NUMinverse_cholesky: calculation of determinant is made optional djmw 20060517 Added NUMregexp_compile djmw 20060518 Treat NULL string as empty string in strs_replace_regexp/literal. Don't accept empty search in str_replace_regexp djmw 20060626 Extra NULL argument for ExecRE. djmw 20061021 printf expects %ld for 'long int' for 64-bit systems djmw 20070302 NUMclipLineWithinRectangle djmw 20070614 updated to version 1.30 of regular expressions. djmw 20071022 Removed function NUMfvector_moment2. djmw 20071201 Melder_warning djmw 20080107 Changed assertion to "npoints > 0" in NUMcosinesTable djmw 20080110 Corrected some bugs in str_replace_regexp djmw 20080122 Bug in str_replace_regexp djmw 20080317 +NUMsinc pb 20080410 FisherQ from gsl djmw 20090630 NUMlogNormalP/Q from gsl djmw 20090707 Rename NUMinverse_cholesky to NUMlowerCholeskyInverse, +NUMcovarianceFromColumnCentredMatrix, +NUMmultivariateKurtosis djmw 20100311 +NUMsolveQuadraticEquation djmw 20100426 replace wcstok by Melder_wcstok djmw 20101209 removed NUMwcscmp is Melder_wcscmp now djmw 20110304 Thing_new djmw 20111110 use autostringvector djmw 20140318 NUMvector_avevar now returns variance instead of sigma^2 */ #include #include "SVD.h" #include "Eigen.h" #include "NUMclapack.h" #ifndef _NUM_h_ #include "NUM.h" #endif #include "NUM2.h" #include "NUMmachar.h" #include "melder.h" #include "gsl_randist.h" #include "gsl_errno.h" #include "gsl_sf_bessel.h" #include "gsl_sf_gamma.h" #include "gsl_sf_erf.h" #include "gsl_sf_trig.h" #include "gsl_poly.h" #include "gsl_cdf.h" #define my me -> #undef MAX #undef MIN #define MAX(m,n) ((m) > (n) ? (m) : (n)) #define MIN(m,n) ((m) < (n) ? (m) : (n)) #define SIGN(a,b) ((b < 0) ? -fabs(a) : fabs(a)) using namespace std; struct pdf1_struct { double p; double df; }; struct pdf2_struct { double p; double df1; double df2; }; int NUMdmatrix_hasInfinities (double **m, long rb, long re, long cb, long ce) { double min = m[rb][cb]; double max = min; for (long i = rb; i <= re; i++) { for (long j = cb; j <= ce; j++) { if (m[i][j] > max) { max = m[i][j]; } else if (m[i][j] < min) { min = m[i][j]; } } } if (! NUMfpp) { NUMmachar (); } return max >= NUMfpp -> rmax || min <= - NUMfpp -> rmax; } void NUMdmatrix_printMatlabForm (double **m, long nr, long nc, const char32 *name) { long npc = 5; ldiv_t n = ldiv (nc, npc); MelderInfo_open (); MelderInfo_write (name, U"=["); for (long i = 1; i <= nr; i++) { for (long j = 1; j <= n.quot; j++) { for (long k = 1; k <= npc; k++) { MelderInfo_write (m[i][ (j - 1) *npc + k], (k < npc ? U", " : U"")); } MelderInfo_write (j < n.quot ? U",\n" : U""); } for (long k = 1; k <= n.rem; k++) { MelderInfo_write (m[i][n.quot * npc + k], (k < n.rem ? U", " : U"")); } MelderInfo_write (i < nr ? U";\n" : U"];\n"); } MelderInfo_close (); } void NUMcentreRows (double **a, long rb, long re, long cb, long ce) { for (long i = rb; i <= re; i++) { double rowmean = 0.0; for (long j = cb; j <= ce; j++) { rowmean += a[i][j]; } rowmean /= (ce - cb + 1); for (long j = cb; j <= ce; j++) { a[i][j] -= rowmean; } } } void NUMcentreColumns (double **a, long rb, long re, long cb, long ce, double *centres) { for (long j = cb; j <= ce; j++) { double colmean = 0.0; for (long i = rb; i <= re; i++) { colmean += a[i][j]; } colmean /= (re - rb + 1); for (long i = rb; i <= re; i++) { a[i][j] -= colmean; } if (centres) { centres[j - cb + 1] = colmean; } } } void NUMdoubleCentre (double **a, long rb, long re, long cb, long ce) { NUMcentreRows (a, rb, re, cb, ce); NUMcentreColumns (a, rb, re, cb, ce, NULL); } void NUMnormalizeColumns (double **a, long nr, long nc, double norm) { Melder_assert (norm > 0); for (long j = 1; j <= nc; j++) { double s = 0.0; for (long i = 1; i <= nr; i++) { s += a[i][j] * a[i][j]; } if (s <= 0.0) { continue; } s = sqrt (norm / s); for (long i = 1; i <= nr; i++) { a[i][j] *= s; } } } void NUMnormalizeRows (double **a, long nr, long nc, double norm) { Melder_assert (norm > 0); for (long i = 1; i <= nr; i++) { double s = 0.0; for (long j = 1; j <= nc; j++) { s += a[i][j] * a[i][j]; } if (s <= 0.0) { continue; } s = sqrt (norm / s); for (long j = 1; j <= nc; j++) { a[i][j] *= s; } } } void NUMnormalize (double **a, long nr, long nc, double norm) { Melder_assert (norm > 0); double sq = 0.0; for (long i = 1; i <= nr; i++) { for (long j = 1; j <= nc; j++) { sq += a[i][j] * a[i][j]; } } if (sq <= 0.0) { return; } norm = sqrt (norm / sq); for (long i = 1; i <= nr; i++) { for (long j = 1; j <= nc; j++) { a[i][j] *= norm; } } } void NUMstandardizeColumns (double **a, long rb, long re, long cb, long ce) { long n = re - rb + 1; if (n < 2) { return; } for (long j = cb; j <= ce; j++) { double ep = 0.0, s = 0.0, sdev, var = 0.0; for (long i = rb; i <= re; i++) { s += a[i][j]; } double ave = s / n; for (long i = rb; i <= re; i++) { s = a[i][j] - ave; ep += s; var += s * s; } if (ave != 0.0) { for (long i = rb; i <= re; i++) { a[i][j] -= ave; } } if (var > 0.0) { var = (var - ep * ep / n) / (n - 1); sdev = sqrt (var); for (long i = rb; i <= re; i++) { a[i][j] /= sdev; } } } } void NUMstandardizeRows (double **a, long rb, long re, long cb, long ce) { long n = ce - cb + 1; if (n < 2) { return; } for (long i = rb; i <= re; i++) { double ep = 0.0, s = 0.0, sdev, var = 0.0; for (long j = cb; j <= ce; j++) { s += a[i][j]; } double ave = s / n; for (long j = cb; j <= ce; j++) { s = a[i][j] - ave; ep += s; var += s * s; } if (ave != 0.0) { for (long j = cb; j <= ce; j++) { a[i][j] -= ave; } } if (var > 0.0) { var = (var - ep * ep / n) / (n - 1); sdev = sqrt (var); for (long j = cb; j <= ce; j++) { a[i][j] /= sdev; } } } } void NUMaverageColumns (double **a, long rb, long re, long cb, long ce) { long n = re - rb + 1; if (n < 2) { return; } for (long j = cb; j <= ce; j++) { double ave = 0.0; for (long i = rb; i <= re; i++) { ave += a[i][j]; } ave /= n; for (long i = rb; i <= re; i++) { a[i][j] = ave; } } } void NUMvector_avevar (double *a, long n, double *average, double *variance) { double eps = 0.0, mean = 0.0, var = 0.0; for (long i = 1; i <= n; i++) { mean += a[i]; } mean /= n; if (average) { *average = mean; } if (! variance) { return; } if (n > 1) { for (long i = 1; i <= n; i++) { double s = a[i] - mean; eps += s; var += s * s; } var = (var - eps * eps / n); } else { var = NUMundefined; } *variance = var; } void NUMcolumn_avevar (double **a, long nr, long nc, long icol, double *average, double *variance) { double eps = 0.0, mean = 0.0, var = 0.0; Melder_assert (nr > 0 && nc > 0 && icol > 0 && icol <= nc); for (long i = 1; i <= nr; i++) { mean += a[i][icol]; } mean /= nr; if (average) { *average = mean; } if (! variance) { return; } if (nr > 1) { for (long i = 1; i <= nr; i++) { double s = a[i][icol] - mean; eps += s; var += s * s; } var = (var - eps * eps / nr); } else { var = NUMundefined; } *variance = var; } void NUMcolumn2_avevar (double **a, long nr, long nc, long icol1, long icol2, double *average1, double *variance1, double *average2, double *variance2, double *covariance) { double eps1 = 0.0, eps2 = 0.0, mean1 = 0.0, mean2 = 0.0; double var1 = 0.0, var2 = 0.0, covar = 0.0; Melder_assert (icol1 > 0 && icol1 <= nc && icol2 > 0 && icol2 <= nc); for (long i = 1; i <= nr; i++) { mean1 += a[i][icol1]; mean2 += a[i][icol2]; } mean1 /= nr; mean2 /= nr; if (average1) { *average1 = mean1; } if (average2) { *average2 = mean2; } if (! variance1 && ! variance2 && ! covariance) { return; } if (nr > 1) { for (long i = 1; i <= nr; i++) { double s1 = a[i][icol1] - mean1; double s2 = a[i][icol2] - mean2; eps1 += s1; eps2 += s2; var1 += s1 * s1; var2 += s2 * s2; covar += s1 * s2; } var1 = (var1 - eps1 * eps1 / nr); var2 = (var2 - eps2 * eps2 / nr);; } else { var1 = NUMundefined; var2 = NUMundefined; covar = NUMundefined; } if (variance1) { *variance1 = var1; } if (variance2) { *variance2 = var2; } if (covariance) { *covariance = covar; } if (icol1 == icol2) { *covariance = *variance1; } } void NUMvector_smoothByMovingAverage (double *xin, long n, long nwindow, double *xout) { // simple averaging, out of bound values are zero for (long i = 1; i <= n; i++) { long jfrom = i - nwindow / 2, jto = i + nwindow / 2; if ((nwindow % 2) == 0) { jto--; } jfrom = jfrom < 1 ? 1 : jfrom; jto = jto > n ? n : jto; xout[i] = 0; for (long j = jfrom; j <= jto; j++) { xout[i] += xin[j]; } xout[i] /= jto - jfrom + 1; } } void NUMcovarianceFromColumnCentredMatrix (double **x, long nrows, long ncols, long ndf, double **covar) { if (ndf < 0 || nrows - ndf < 1 || covar == 0) { Melder_throw (U"Invalid arguments."); } for (long i = 1; i <= ncols; i++) { for (long j = i; j <= ncols; j++) { double sum = 0.0; for (long k = 1; k <= nrows; k++) { sum += x[k][i] * x[k][j]; } covar[i][j] = covar[j][i] = sum / (nrows - ndf); } } } double NUMmultivariateKurtosis (double **x, long nrows, long ncols, int method) { double kurt = NUMundefined; if (nrows < 5) { return kurt; } autoNUMvector mean (1, ncols); autoNUMmatrix covar (1, ncols, 1, ncols); NUMcentreColumns (x, 1, nrows, 1, ncols, mean.peek()); NUMcovarianceFromColumnCentredMatrix (x, nrows, ncols, 1, covar.peek()); if (method == 1) { // Schott (2001, page 33) kurt = 0.0; for (long l = 1; l <= ncols; l++) { double zl = 0.0, wl, sll2 = covar[l][l] * covar[l][l]; for (long j = 1; j <= nrows; j++) { double d = x[j][l] - mean[l], d2 = d * d; zl += d2 * d2; } zl = (zl - 6.0 * sll2) / (nrows - 4); wl = (sll2 - zl / nrows) * nrows / (nrows - 1); kurt += zl / wl; } kurt = kurt / (3 * ncols) - 1.0; } return kurt; } void eigenSort (double d[], double **v, long n, int sort) { if (sort == 0) { return; } for (long i = 1; i < n; i++) { long k; double temp = d[k = i]; if (sort > 0) { for (long j = i + 1; j <= n; j++) { if (d[j] > temp) { temp = d[k = j]; } } } else { for (long j = i + 1; j <= n; j++) { if (d[j] < temp) { temp = d[k = j]; } } } if (k != i) { d[k] = d[i]; d[i] = temp; if (v) { for (long j = 1; j <= n; j++) { temp = v[j][i]; v[j][i] = v[j][k]; v[j][k] = temp; } } } } } int NUMstrcmp (const char *s1, const char *s2) { if (! s1 || s1[0] == '\0') { if (s2 && s2[0] != '\0') { return -1; } else { return 0; } } else { if (! s2) { return +1; } else { return strcmp (s1, s2); } } } void NUMlocate_f (float *xx, long n, float x, long *index) { long ju = n + 1, jm, jl = 0; int ascend = xx[n] >= xx[1]; while (ju - jl > 1) { jm = (ju + jl) / 2; if ( (x >= xx[jm]) == ascend) { jl = jm; } else { ju = jm; } } if (x == xx[1]) { *index = 1; } else if (x == xx[n]) { *index = n - 1; } else { *index = jl; } } void NUMlocate (double *xx, long n, double x, long *index) { long ju = n + 1, jm, jl = 0; int ascend = xx[n] >= xx[1]; while (ju - jl > 1) { jm = (ju + jl) / 2; if ( (x >= xx[jm]) == ascend) { jl = jm; } else { ju = jm; } } if (x == xx[1]) { *index = 1; } else if (x == xx[n]) { *index = n - 1; } else { *index = jl; } } /* The following algorithm for monotone regession is on the average 3.5 times faster than Kruskal's algorithm for monotone regression (and much simpler). Regression is ascending */ void NUMmonotoneRegression (const double x[], long n, double xs[]) { double xt = NUMundefined; // Only to stop gcc complaining "may be used unitialized" for (long i = 1; i <= n; i++) { xs[i] = x[i]; } for (long i = 2; i <= n; i++) { if (xs[i] >= xs[i - 1]) { continue; } double sum = xs[i]; long nt = 1; for (long j = 1; j <= i - 1; j++) { sum += xs[i - j]; nt++; xt = sum / nt; // i >= 2 -> xt always gets a value if (j < i - 1 && xt >= xs[i - j - 1]) { break; } } for (long j = i - nt + 1; j <= i; j++) { xs[j] = xt; } } } double NUMvector_getNorm1 (const double v[], long n) { double norm = 0; for (long i = 1; i <= n; i++) { norm += fabs (v[i]); } return norm; } double NUMvector_getNorm2 (const double v[], long n) { double norm = 0.0; for (long i = 1; i <= n; i++) { norm += v[i] * v[i]; } return sqrt (norm); } double NUMvector_normalize1 (double v[], long n) { double norm = 0.0; for (long i = 1; i <= n; i++) { norm += fabs (v[i]); } if (norm > 0.0) { for (long i = 1; i <= n; i++) { v[i] /= norm; } } return norm; } double NUMvector_normalize2 (double v[], long n) { double norm = 0; for (long i = 1; i <= n; i++) { norm += v[i] * v[i]; } norm = sqrt (norm); if (norm > 0) { for (long i = 1; i <= n; i++) { v[i] /= norm; } } return norm; } #undef TINY void NUMcholeskySolve (double **a, long n, double d[], double b[], double x[]) { for (long i = 1; i <= n; i++) { /* Solve L.y=b */ double sum = b[i]; for (long k = i - 1; k >= 1; k--) { sum -= a[i][k] * x[k]; } x[i] = sum / d[i]; } for (long i = n; i >= 1; i--) { /* Solve L^T.x=y */ double sum = x[i]; for (long k = i + 1; k <= n; k++) { sum -= a[k][i] * x[k]; } x[i] = sum / d[i]; } } void NUMdeterminant_cholesky (double **a, long n, double *lnd) { // Save the diagonal autoNUMvector d (1, n); for (long i = 1; i <= n; i++) { d[i] = a[i][i]; } // Cholesky decomposition in lower, leave upper intact char uplo = 'U'; long lda = n, info; NUMlapack_dpotf2 (&uplo, &n, &a[1][1], &lda, &info); if (info != 0) { Melder_throw (U"Cannot determine Cholesky decomposition."); } // Determinant from diagonal, restore diagonal *lnd = 0.0; for (long i = 1; i <= n; i++) { *lnd += log (a[i][i]); a[i][i] = d[i]; } *lnd *= 2.0; // because A = L . L' TODO // Restore lower from upper */ for (long i = 1; i < n; i++) { for (long j = i + 1; j <= n; j++) { a[j][i] = a[i][j]; } } } void NUMlowerCholeskyInverse (double **a, long n, double *lnd) { char uplo = 'U', diag = 'N'; long info; // Cholesky decomposition in lower, leave upper intact // Fortran storage -> use uplo='U' to get 'L'. (void) NUMlapack_dpotf2 (&uplo, &n, &a[1][1], &n, &info); if (info != 0) { Melder_throw (U"dpotf2 fails."); } // Determinant from diagonal, diagonal is now sqrt (a[i][i]) ! if (lnd != NULL) { *lnd = 0.0; for (long i = 1; i <= n; i++) { *lnd += log (a[i][i]); } *lnd *= 2.0; /* because A = L . L' */ } // Get the inverse */ (void) NUMlapack_dtrtri (&uplo, &diag, &n, &a[1][1], &n, &info); if (info != 0) { Melder_throw (U"dtrtri fails."); } } double **NUMinverseFromLowerCholesky (double **m, long n) { autoNUMmatrix r (1, n, 1, n); for (long i = 1; i <= n; i++) { for (long j = 1; j <= i; j++) { double sum = 0; for (long k = i; k <= n; k++) { sum += m[k][i] * m[k][j]; } r[i][j] = r[j][i] = sum; } } return r.transfer(); } double NUMmahalanobisDistance_chi (double **linv, double *v, double *m, long nr, long n) { double chisq = 0; if (nr == 1) { // 1xn matrix for (long j = 1; j <= n; j++) { double t = linv[1][j] * (v[j] - m[j]); chisq += t * t; } } else { // nxn matrix for (long i = n; i > 0; i--) { double t = 0.0; for (long j = 1; j <= i; j++) { t += linv[i][j] * (v[j] - m[j]); } chisq += t * t; } } return chisq; } double NUMtrace (double **a, long n) { double trace = 0.0; for (long i = 1; i <= n; i++) { trace += a[i][i]; } return trace; } double NUMtrace2 (double **a1, double **a2, long n) { double trace = 0.0; for (long i = 1; i <= n; i++) { for (long k = 1; k <= n; k++) { trace += a1[i][k] * a2[k][i]; } } return trace; } void NUMeigensystem (double **a, long n, double **evec, double eval[]) { autoEigen me = Thing_new (Eigen); Eigen_initFromSymmetricMatrix (me.peek(), a, n); if (evec) { NUMmatrix_copyElements (my eigenvectors, evec, 1, n, 1, n); } if (eval) { NUMvector_copyElements (my eigenvalues, eval, 1, n); } } void NUMdominantEigenvector (double **mns, long n, double *q, double *lambda, double tolerance) { autoNUMvector z (1, n); double val, cval = 0.0; for (long k = 1; k <= n; k++) { for (long l = 1; l <= n; l++) { cval += q[k] * mns[k][l] * q[l]; } } if (cval == 0.0) { Melder_throw (U"Zero matrices ??"); } long iter = 0; do { double znorm2 = 0.0; for (long l = 1; l <= n; l++) { z[l] = 0.0; for (long k = 1; k <= n; k++) { z[l] += mns[l][k] * q[k]; } } for (long k = 1; k <= n; k++) { znorm2 += z[k] * z[k]; } znorm2 = sqrt (znorm2); for (long k = 1; k <= n; k++) { q[k] = z[k] / znorm2; } val = cval; cval = 0.0; for (long k = 1; k <= n; k++) { for (long l = 1; l <= n; l++) { cval += q[k] * mns[k][l] * q[l]; } } } while (fabs (cval - val) > tolerance || ++iter < 30); *lambda = cval; } void NUMprincipalComponents (double **a, long n, long nComponents, double **pc) { autoNUMmatrix evec (1, n, 1, n); NUMeigensystem (a, n, evec.peek(), NULL); for (long i = 1; i <= n; i++) { for (long j = 1; j <= nComponents; j++) { double s = 0.0; for (long k = 1; k <= n; k++) { s += a[k][i] * evec[k][j]; /* times sqrt(eigenvalue) ?? */ } pc[i][j] = s; } } } void NUMdmatrix_into_principalComponents (double **m, long nrows, long ncols, long numberOfComponents, double **pc) { Melder_assert (numberOfComponents > 0 && numberOfComponents <= ncols); autoNUMmatrix mc (NUMmatrix_copy (m, 1, nrows, 1, ncols), 1, 1); /*NUMcentreColumns (mc, nrows, ncols);*/ autoSVD svd = SVD_create_d (mc.peek(), nrows, ncols); for (long i = 1; i <= nrows; i++) { for (long j = 1; j <= numberOfComponents; j++) { pc[i][j] = 0.0; for (long k = 1; k <= ncols; k++) { pc[i][j] += svd -> v[k][j] * m[i][k]; } } } } void NUMpseudoInverse (double **y, long nr, long nc, double **yinv, double tolerance) { autoSVD me = SVD_create_d (y, nr, nc); (void) SVD_zeroSmallSingularValues (me.peek(), tolerance); for (long i = 1; i <= nc; i++) { for (long j = 1; j <= nr; j++) { double s = 0.0; for (long k = 1; k <= nc; k++) { if (my d[k] != 0.0) { s += my v[i][k] * my u[j][k] / my d[k]; } } yinv[i][j] = s; } } } long NUMsolveQuadraticEquation (double a, double b, double c, double *x1, double *x2) { return gsl_poly_solve_quadratic (a, b, c, x1, x2); } void NUMsolveEquation (double **a, long nr, long nc, double *b, double tolerance, double *result) { double tol = tolerance > 0 ? tolerance : NUMfpp -> eps * nr; if (nr <= 0 || nc <= 0) { Melder_throw (U"Negative dimensions"); } autoSVD me = SVD_create_d (a, nr, nc); SVD_zeroSmallSingularValues (me.peek(), tol); SVD_solve (me.peek(), b, result); } void NUMsolveEquations (double **a, long nr, long nc, double **b, long ncb, double tolerance, double **x) { double tol = tolerance > 0 ? tolerance : NUMfpp -> eps * nr; if (nr <= 0 || nc <= 0) { Melder_throw (U"Negative dimensions"); } autoSVD me = SVD_create_d (a, nr, nc); autoNUMvector bt (1, nr + nc); double *xt = & bt[nr]; SVD_zeroSmallSingularValues (me.peek(), tol); for (long k = 1; k <= ncb; k++) { for (long j = 1; j <= nr; j++) { bt[j] = b[j][k]; } SVD_solve (me.peek(), bt.peek(), xt); for (long j = 1; j <= nc; j++) { x[j][k] = xt[j]; } } } void NUMsolveNonNegativeLeastSquaresRegression (double **m, long nr, long nc, double *d, double tol, long itermax, double *b) { double difsq, difsqp = 0.0; for (long iter = 1; iter <= itermax; iter++) { // Fix all weights except b[j] for (long j = 1; j <= nc; j++) { double mjr = 0.0, mjmj = 0.0; for (long i = 1; i <= nr; i++) { double ri = d[i], mij = m[i][j]; for (long l = 1; l <= nc; l++) { if (l != j) { ri -= b[l] * m[i][l]; } } mjr += mij * ri; mjmj += mij * mij; } b[j] = mjr / mjmj; if (b[j] < 0.0) { b[j] = 0.0; } } // Calculate t(b) and compare with previous result. difsq = 0.0; for (long i = 1; i <= nr; i++) { double dmb = d[i]; for (long j = 1; j <= nc; j++) { dmb -= m[i][j] * b[j]; } difsq += dmb * dmb; } if (fabs (difsq - difsqp) / difsq < tol) { break; } difsqp = difsq; } } struct nr_struct { double *y, *delta; }; /* f (lambda) = sum (y[i]^2 delta[i] / (delta[i]-lambda)^2, i=1..3) f'(lambda) = 2 * sum (y[i]^2 delta[i] / (delta[i]-lambda)^3, i=1..3) */ static void nr_func (double x, double *f, double *df, void *data) { struct nr_struct *me = (struct nr_struct *) data; *f = *df = 0.0; for (long i = 1; i <= 3; i++) { double t1 = (my delta[i] - x); double t2 = my y[i] / t1; double t3 = t2 * t2 * my delta[i]; *f += t3; *df += t3 * 2 / t1; } } void NUMsolveConstrainedLSQuadraticRegression (double **o, const double d[], long n, double *alpha, double *gamma) { long n3 = 3, info; double eps = 1e-5, t1, t2, t3; autoNUMmatrix ftinv (1, n3, 1, n3); autoNUMmatrix b (1, n3, 1, n3); autoNUMmatrix g (1, n3, 1, n3); autoNUMmatrix p (1, n3, 1, n3); autoNUMvector delta (1, n3); autoNUMmatrix ftinvp (1, n3, 1, n3); autoNUMmatrix ptfinv (1, n3, 1, n3); autoNUMvector otd (1, n3); autoNUMmatrix ptfinvc (1, n3, 1, n3); autoNUMvector y (1, n3); autoNUMvector w (1, n3); autoNUMvector chi (1, n3); autoNUMvector diag (1, n3); // Construct O'.O [1..3][1..3]. for (long i = 1; i <= n3; i++) { for (long j = 1; j <= n3; j++) { for (long k = 1; k <= n; k++) { ftinv[i][j] += o[k][i] * o[k][j]; } } } // Get lower triangular decomposition from O'.O and // get F'^-1 from it (eq. (2)) (F^-1 not done ????) char uplo = 'U'; (void) NUMlapack_dpotf2 (&uplo, &n3, &ftinv[1][1], &n3, &info); if (info != 0) { Melder_throw (U"dpotf2 fails."); } ftinv[1][2] = ftinv[1][3] = ftinv[2][3] = 0.0; // Construct G and its eigen-decomposition (eq. (4,5)) // Sort eigenvalues (& eigenvectors) ascending. b[3][1] = b[1][3] = -0.5; b[2][2] = 1.0; // G = F^-1 B (F')^-1 (eq. 4) for (long i = 1; i <= 3; i++) { for (long j = 1; j <= 3; j++) { for (long k = 1; k <= 3; k++) { if (ftinv[k][i] != 0.0) { for (long l = 1; l <= 3; l++) { g[i][j] += ftinv[k][i] * b[k][l] * ftinv[l][j]; } } } } } // G's eigen-decomposition with eigenvalues (assumed ascending). (eq. 5) NUMeigensystem (g.peek(), 3, p.peek(), delta.peek()); NUMsort_d (3, delta.peek()); /* ascending */ // Construct y = P'.F'.O'.d ==> Solve (F')^-1 . P .y = (O'.d) (page 632) // Get P'F^-1 from the transpose of (F')^-1 . P for (long i = 1; i <= 3; i++) { for (long j = 1; j <= 3; j++) { if (ftinv[i][j] != 0.0) { for (long k = 1; k <= 3; k++) { ftinvp[i][k] += ftinv[i][j] * p[3 + 1 - j][k]; /* is sorted desc. */ } } } for (long k = 1; k <= n; k++) { otd[i] += o[k][i] * d[k]; } } for (long i = 1; i <= 3; i++) { for (long j = 1; j <= 3; j++) { ptfinvc[j][i] = ptfinv[j][i] = ftinvp[i][j]; } } NUMsolveEquation (ftinvp.peek(), 3, 3, otd.peek(), 1e-6, y.peek()); // The solution (3 cases) if (fabs (y[1]) < eps) { // Case 1: page 633 t2 = y[2] / (delta[2] - delta[1]); t3 = y[3] / (delta[3] - delta[1]); /* +- */ w[1] = sqrt (- delta[1] * (t2 * t2 * delta[2] + t3 * t3 * delta[3])); w[2] = t2 * delta[2]; w[3] = t3 * delta[3]; NUMsolveEquation (ptfinv.peek(), 3, 3, w.peek(), 1e-6, chi.peek()); w[1] = -w[1]; if (fabs (chi[3] / chi[1]) < eps) { NUMsolveEquation (ptfinvc.peek(), 3, 3, w.peek(), 1e-6, chi.peek()); } } else if (fabs (y[2]) < eps) { // Case 2: page 633 t1 = y[1] / (delta[1] - delta[2]); t3 = y[3] / (delta[3] - delta[2]); w[1] = t1 * delta[1]; if ( (delta[2] < delta[3] && (t2 = (t1 * t1 * delta[1] + t3 * t3 * delta[3])) < eps)) { w[2] = sqrt (- delta[2] * t2); /* +- */ w[3] = t3 * delta[3]; NUMsolveEquation (ptfinv.peek(), 3, 3, w.peek(), 1e-6, chi.peek()); w[2] = -w[2]; if (fabs (chi[3] / chi[1]) < eps) { NUMsolveEquation (ptfinvc.peek(), 3, 3, w.peek(), 1e-6, chi.peek()); } } else if (((delta[2] < delta[3] + eps) || (delta[2] > delta[3] - eps)) && fabs (y[3]) < eps) { // choose one value for w[2] from an infinite number w[2] = w[1]; w[3] = sqrt (- t1 * t1 * delta[1] * delta[2] - w[2] * w[2]); NUMsolveEquation (ptfinv.peek(), 3, 3, w.peek(), 1e-6, chi.peek()); } } else { // Case 3: page 634 use Newton-Raphson root finder struct nr_struct me; double xlambda, eps2 = (delta[2] - delta[1]) * 1e-6; me.y = y.peek(); me.delta = delta.peek(); NUMnrbis (nr_func, delta[1] + eps, delta[2] - eps2, & me, & xlambda); for (long i = 1; i <= 3; i++) { w[i] = y[i] / (1 - xlambda / delta[i]); } NUMsolveEquation (ptfinv.peek(), 3, 3, w.peek(), 1e-6, chi.peek()); } *alpha = chi[1]; *gamma = chi[3]; } /* f (b) = delta - b / (2 alpha) - sum (x[i]^2 / (c[i] - b)^2, i=1..n) f'(b) = - 1 / (2 alpha) + 2 * sum (x[i]^2 / (c[i] - b)^3, i=1..n) */ struct nr2_struct { long m; double delta, alpha, *x, *c; }; static void nr2_func (double b, double *f, double *df, void *data) { struct nr2_struct *me = (struct nr2_struct *) data; *df = - 0.5 / my alpha; *f = my delta + *df * b; for (long i = 1; i <= my m; i++) { double c1 = (my c[i] - b); double c2 = my x[i] / c1; double c2sq = c2 * c2; *f -= c2sq; *df += 2 * c2sq / c1; } } void NUMsolveWeaklyConstrainedLinearRegression (double **f, long n, long m, double phi[], double alpha, double delta, double t[]) { autoNUMmatrix u (1, m, 1, m); autoNUMvector c (1, m); autoNUMvector x (1, n); autoNUMvector indx (1, m); for (long j = 1; j <= m; j++) { t[j] = 0.0; } autoSVD svd = SVD_create_d (f, n, m); if (alpha == 0.0) { SVD_solve (svd.peek(), phi, t); // standard least squares } // Step 1: Compute U and C from the eigendecomposition F'F = UCU' // Evaluate q, the multiplicity of the smallest eigenvalue in C double *sqrtc = svd -> d; double **ut = svd -> v; NUMindexx (sqrtc, m, indx.peek()); for (long j = m; j > 0; j--) { double tmp = sqrtc [indx[j]]; c[m - j + 1] = tmp * tmp; for (long k = 1; k <= m; k++) { u[m - j + 1][k] = ut [indx[j]] [k]; } } long q = 1; double tol = 1e-6; while (q < m && (c[m - q] - c[m]) < tol) { q++; } // step 2: x = U'F'phi for (long i = 1; i <= m; i++) { for (long j = 1; j <= m; j++) { for (long k = 1; k <= n; k++) { x[i] += u[j][i] * f[k][j] * phi[k]; } } } // step 3: struct nr2_struct me; me.m = m; me.delta = delta; me.alpha = alpha; me.x = x.peek(); me.c = c.peek(); double xqsq = 0.0; for (long j = m - q + 1; j <= m; j++) { xqsq += x[j] * x[j]; } long r = m; if (xqsq < tol) { /* xqsq == 0 */ double fm, df; r = m - q; me.m = r; nr2_func (c[m], &fm, &df, & me); if (fm >= 0.0) { /* step 3.b1 */ x[r + 1] = sqrt (fm); for (long j = 1; j <= r; j++) { x[j] /= c[j] - c[m]; } for (long j = 1; j <= r + 1; j++) { for (long k = 1; k <= r + 1; k++) { t[j] += u[j][k] * x[k]; } } return; } // else continue with r = m - q } // step 3a & 3b2, determine interval lower bound for Newton-Raphson root finder double xCx = 0.0; for (long j = 1; j <= r; j++) { xCx += x[j] * x[j] / c[j]; } double b0, bmin = delta > 0.0 ? - xCx / delta : -2.0 * sqrt (alpha * xCx); double eps = (c[m] - bmin) * tol; // find the root of d(psi(b)/db in interval (bmin, c[m]) NUMnrbis (nr2_func, bmin + eps, c[m] - eps, & me, & b0); for (long j = 1; j <= r; j++) { for (long k = 1; k <= r; k++) { t[j] += u[j][k] * x[k] / (c[k] - b0); } } } void NUMProcrustes (double **x, double **y, long nPoints, long nDimensions, double **t, double v[], double *s) { bool orthogonal = ! v || ! s; // else similarity transform autoNUMmatrix c (1, nDimensions, 1, nDimensions); autoNUMmatrix yc (1, nPoints, 1, nDimensions); NUMmatrix_copyElements (y, yc.peek(), 1, nPoints, 1, nDimensions); /* Reference: Borg & Groenen (1997), Modern multidimensional scaling, Springer 1. Calculate C = X'JY (page 346) for similarity transform else X'Y for othogonal (page 341) JY amounts to centering the columns of Y. */ if (! orthogonal) { NUMcentreColumns (yc.peek(), 1, nPoints, 1, nDimensions, NULL); } for (long i = 1; i <= nDimensions; i++) { for (long j = 1; j <= nDimensions; j++) { for (long k = 1; k <= nPoints; k++) { c[i][j] += x[k][i] * yc[k][j]; } } } // 2. Decompose C by SVD: C = PDQ' (SVD attribute is Q instead of Q'!) autoSVD svd = SVD_create_d (c.peek(), nDimensions, nDimensions); double trace = 0.0; for (long i = 1; i <= nDimensions; i++) { trace += svd -> d[i]; } if (trace == 0.0) { Melder_throw (U"NUMProcrustes: degenerate configuration(s)."); } // 3. T = QP' for (long i = 1; i <= nDimensions; i++) { for (long j = 1; j <= nDimensions; j++) { t[i][j] = 0.0; for (long k = 1; k <= nDimensions; k++) { t[i][j] += svd -> v[i][k] * svd -> u[j][k]; } } } if (! orthogonal) { autoNUMmatrix xc (1, nPoints, 1, nDimensions); NUMmatrix_copyElements (x, xc.peek(), 1, nPoints, 1, nDimensions); autoNUMmatrix yt (1, nPoints, 1, nDimensions); // 4. Dilation factor s = (tr X'JYT) / (tr Y'JY) // First we need YT. for (long i = 1; i <= nPoints; i++) { for (long j = 1; j <= nDimensions; j++) { for (long k = 1; k <= nDimensions; k++) { yt[i][j] += y[i][k] * t[k][j]; } } } // X'J amount to centering the columns of X NUMcentreColumns (xc.peek(), 1, nPoints, 1, nDimensions, NULL); // tr X'J YT == tr xc' yt double traceXtJYT = 0.0; for (long i = 1; i <= nDimensions; i++) { for (long j = 1; j <= nPoints; j++) { traceXtJYT += xc[j][i] * yt[j][i]; } } double traceYtJY = 0.0; for (long i = 1; i <= nDimensions; i++) { for (long j = 1; j <= nPoints; j++) { traceYtJY += y[j][i] * yc[j][i]; } } *s = traceXtJYT / traceYtJY; // 5. Translation vector tr = (X - sYT)'1 / nPoints for (long i = 1; i <= nDimensions; i++) { for (long j = 1; j <= nPoints; j++) { v[i] += x[j][i] - *s * yt[j][i]; } v[i] /= nPoints; } } } void NUMmspline (double knot[], long nKnots, long order, long i, double x, double *y) { long jj, nSplines = nKnots - order; if (nSplines <= 0) { Melder_throw (U"No splines."); } // Find the interval where x is located. // M-splines of order k have degree k-1. // M-splines are zero outside interval [ knot[i], knot[i+order] ). // First and last 'order' knots are equal, i.e., // knot[1] = ... = knot[order] && knot[nKnots-order+1] = ... knot[nKnots]. *y = 0.0; if (i > nSplines || order < 1) { Melder_throw (U"Combination of order and index not correct."); } for (jj = order; jj <= nKnots - order + 1; jj++) { if (x < knot[jj]) { break; } } if (jj < i || (jj > i + order) || jj == order || jj > (nKnots - order + 1)) { return; } // Calculate M[i](x|1,t) according to eq.2. long ito = i + order - 1; autoNUMvector m (i, ito); for (long j = i; j <= ito; j++) { if (x >= knot[j] && x < knot[j + 1]) { m[j] = 1 / (knot[j + 1] - knot[j]); } } // Iterate to get M[i](x|k,t) for (long k = 2; k <= order; k++) { for (long j = i; j <= i + order - k; j++) { double kj = knot[j], kjpk = knot[j + k]; if (kjpk > kj) { m[j] = k * ((x - kj) * m[j] + (kjpk - x) * m[j + 1]) / ((k - 1) * (kjpk - kj)); } } } *y = m[i]; } void NUMispline (double aknot[], long nKnots, long order, long i, double x, double *y) { long j, orderp1 = order + 1; *y = 0.0; for (j = orderp1; j <= nKnots - order; j++) { if (x < aknot[j]) { break; } } j--; if (j < i) { return; } if (j > i + order || (j == nKnots - order && x == aknot[j])) { *y = 1.0; return; } // Equation 5 in Ramsay's article contains some errors!!! // 1. the interval selection must be 'j-k <= i <= j' instead of // 'j-k+1 <= i <= j' // 2. the summation index m starts at 'i+1' instead of 'i' for (long m = i + 1; m <= j; m++) { double r; NUMmspline (aknot, nKnots, orderp1, m, x, &r); *y += (aknot[m + orderp1] - aknot[m]) * r; } *y /= orderp1; } double NUMwilksLambda (double *lambda, long from, long to) { double result = 1.0; for (long i = from; i <= to; i++) { result /= (1.0 + lambda[i]); } return result; } double NUMfactln (int n) { static double table[101]; if (n < 0) { return NUMundefined; } if (n <= 1) { return 0; } return n > 100 ? NUMlnGamma (n + 1.0) : table[n] != 0.0 ? table[n] : (table[n] = NUMlnGamma (n + 1.0)); } void NUMnrbis (void (*f) (double x, double *fx, double *dfx, void *closure), double x1, double x2, void *closure, double *root) { double df, dx, dxold, fx, fh, fl, tmp, xh, xl, tol; long itermax = 60; (*f) (x1, &fl, &df, closure); if (fl == 0.0) { *root = x1; return; } (*f) (x2, &fh, &df, closure); if (fh == 0.0) { *root = x2; return; } if ( (fl > 0.0 && fh > 0.0) || (fl < 0.0 && fh < 0.0)) { *root = NUMundefined; Melder_throw (U"Root must be bracketed."); } if (fl < 0.0) { xl = x1; xh = x2; } else { xh = x1; xl = x2; } dxold = fabs (x2 - x1); dx = dxold; *root = 0.5 * (x1 + x2); (*f) (*root, &fx, &df, closure); for (long iter = 1; iter <= itermax; iter++) { if ( ( ( (*root - xh) * df - fx) * ( (*root - xl) * df - fx) >= 0.0) || (fabs (2.0 * fx) > fabs (dxold * df))) { dxold = dx; dx = 0.5 * (xh - xl); *root = xl + dx; if (xl == *root) { return; } } else { dxold = dx; dx = fx / df; tmp = *root; *root -= dx; if (tmp == *root) { return; } } tol = NUMfpp -> eps * (*root == 0.0 ? 1.0 : fabs (*root)); if (fabs (dx) < tol) { return; } (*f) (*root, &fx, &df, closure); if (fx < 0.0) { xl = *root; } else { xh = *root; } } Melder_warning (U"NUMnrbis: maximum number of iterations (", itermax, U") exceeded."); } double NUMridders (double (*f) (double x, void *closure), double x1, double x2, void *closure) { /* There is still a problem with this implementation: tol may be zero; */ double x3, x4, d, root = NUMundefined; double f1, f2, f3, f4, tol; long itermax = 100; f1 = f (x1, closure); if (f1 == 0.0) { return x1; } if (f1 == NUMundefined) { return NUMundefined; } f2 = f (x2, closure); if (f2 == 0.0) { return x2; } if (f2 == NUMundefined) { return NUMundefined; } if ( (f1 < 0.0 && f2 < 0.0) || (f1 > 0.0 && f2 > 0.0)) { Melder_warning (U"NUMridders: root must be bracketed."); return NUMundefined; } for (long iter = 1; iter <= itermax; iter++) { x3 = 0.5 * (x1 + x2); f3 = f (x3, closure); if (f3 == 0.0) { return x3; } if (f3 == NUMundefined) { return NUMundefined; } // New guess: x4 = x3 + (x3 - x1) * sign(f1 - f2) * f3 / sqrt(f3^2 - f1*f2) d = f3 * f3 - f1 * f2; if (d < 0.0) { Melder_warning (U"d < 0 in ridders (iter = ", iter, U")."); return NUMundefined; } if (d == 0.0) { // pb test added because f1 f2 f3 may be 1e-170 or so tol = NUMfpp -> eps * fabs (x3); if (iter > 1 && fabs (x3 - root) < tol) { return root; } root = x3; // Perform bisection. if (f1 > 0.0) { // falling curve: f1 > 0, f2 < 0 if (f3 > 0.0) { x1 = x3; f1 = f3; // retain invariant: f1 > 0, f2 < 0 } else { // f3 <= 0.0 x2 = x3; f2 = f3; // retain invariant: f1 > 0, f2 < 0 } } else { // rising curve: f1 < 0, f2 > 0 if (f3 > 0.0) { x2 = x3; f2 = f3; // retain invariant: f1 < 0, f2 > 0 } else { // f3 < 0.0 x1 = x3; f1 = f3; // retain invariant: f1 < 0, f2 > 0 } } } else { d = sqrt (d); if (isnan (d)) { // pb: square root of denormalized small number fails on some computers tol = NUMfpp -> eps * fabs (x3); if (iter > 1 && fabs (x3 - root) < tol) { return root; } root = x3; // Perform bisection. if (f1 > 0.0) { // falling curve: f1 > 0, f2 < 0 if (f3 > 0.0) { x1 = x3; f1 = f3; // retain invariant: f1 > 0, f2 < 0 } else { // f3 <= 0.0 x2 = x3; f2 = f3; // retain invariant: f1 > 0, f2 < 0 } } else { // rising curve: f1 < 0, f2 > 0 if (f3 > 0.0) { x2 = x3; f2 = f3; // retain invariant: f1 < 0, f2 > 0 } else { // f3 < 0.0 x1 = x3; f1 = f3; // retain invariant: f1 < 0, f2 > 0 */ } } } else { d = (x3 - x1) * f3 / d; x4 = f1 - f2 < 0 ? x3 - d : x3 + d; tol = NUMfpp -> eps * fabs (x4); if (iter > 1 && fabs (x4 - root) < tol) { return root; } root = x4; f4 = f (x4, closure); if (f4 == 0.0) { return root; } if (f4 == NUMundefined) { return NUMundefined; } if ((f1 > f2) == (d > 0.0) /* pb: instead of x3 < x4 */) { if (SIGN (f3, f4) != f3) { x1 = x3; f1 = f3; x2 = x4; f2 = f4; } else { x1 = x4; f1 = f4; } } else { if (SIGN (f3, f4) != f3) { x1 = x4; f1 = f4; x2 = x3; f2 = f3; } else { x2 = x4; f2 = f4; } } } } if (fabs (x1 - x2) < tol) { return root; } } { static long nwarnings = 0; nwarnings++; Melder_warning (U"NUMridders: maximum number of iterations (", itermax, U") exceeded."); } return root; } double NUMlogNormalP (double x, double zeta, double sigma) { return gsl_cdf_lognormal_P (x, zeta, sigma); } double NUMlogNormalQ (double x, double zeta, double sigma) { return gsl_cdf_lognormal_Q (x, zeta, sigma); } double NUMstudentP (double t, double df) { if (df < 1.0) { return NUMundefined; } double ib = NUMincompleteBeta (0.5 * df, 0.5, df / (df + t * t)); if (ib == NUMundefined) { return NUMundefined; } ib *= 0.5; return t < 0.0 ? ib : 1.0 - ib; } double NUMstudentQ (double t, double df) { if (df < 1) { return NUMundefined; } double ib = NUMincompleteBeta (0.5 * df, 0.5, df / (df + t * t)); if (ib == NUMundefined) { return NUMundefined; } ib *= 0.5; return t > 0.0 ? ib : 1.0 - ib; } double NUMfisherP (double f, double df1, double df2) { if (f < 0.0 || df1 < 1.0 || df2 < 1.0) { return NUMundefined; } double ib = NUMincompleteBeta (0.5 * df2, 0.5 * df1, df2 / (df2 + f * df1)); if (ib == NUMundefined) { return NUMundefined; } return 1.0 - ib; } double NUMfisherQ (double f, double df1, double df2) { if (f < 0.0 || df1 < 1.0 || df2 < 1.0) { return NUMundefined; } if (Melder_debug == 28) { return NUMincompleteBeta (0.5 * df2, 0.5 * df1, df2 / (df2 + f * df1)); } else { double result = gsl_cdf_fdist_Q (f, df1, df2); if (isnan (result)) { return NUMundefined; } return result; } } double NUMinvGaussQ (double p) { double pc = p; if (p <= 0.0 || p >= 1.0) { return NUMundefined; } if (p > 0.5) { pc = 1.0 - p; } double t = sqrt (- 2.0 * log (pc)); t -= (2.515517 + (0.802853 + 0.010328 * t) * t) / (1.0 + (1.432788 + (0.189269 + 0.001308 * t) * t) * t); return p > 0.5 ? -t : t; } static double studentQ_func (double x, void *voidParams) { struct pdf1_struct *params = (struct pdf1_struct *) voidParams; double q = NUMstudentQ (x, params -> df); return q == NUMundefined ? NUMundefined : q - params -> p; } double NUMinvStudentQ (double p, double df) { struct pdf1_struct params; double pc = p > 0.5 ? 1.0 - p : p, xmin, xmax = 1.0, x; if (p < 0.0 || p >= 1.0) { return NUMundefined; } // Bracket the function f(x) = NUMstudentQ (x, df) - p. for (;;) { double q = NUMstudentQ (xmax, df); if (q == NUMundefined) { return NUMundefined; } if (q < pc) { break; } xmax *= 2.0; } xmin = xmax > 1.0 ? xmax / 2.0 : 0.0; // Find zero of f(x) with Ridders' method. params. df = df; params. p = pc; x = NUMridders (studentQ_func, xmin, xmax, & params); if (x == NUMundefined) { return NUMundefined; } return p > 0.5 ? -x : x; } static double chiSquareQ_func (double x, void *voidParams) { struct pdf1_struct *params = (struct pdf1_struct *) voidParams; double q = NUMchiSquareQ (x, params -> df); return q == NUMundefined ? NUMundefined : q - params -> p; } double NUMinvChiSquareQ (double p, double df) { struct pdf1_struct params; double xmin, xmax = 1; if (p < 0.0 || p >= 1.0) { return NUMundefined; } // Bracket the function f(x) = NUMchiSquareQ (x, df) - p. for (;;) { double q = NUMchiSquareQ (xmax, df); if (q == NUMundefined) { return NUMundefined; } if (q < p) { break; } xmax *= 2.0; } xmin = xmax > 1.0 ? xmax / 2.0 : 0.0; // Find zero of f(x) with Ridders' method. params. df = df; params. p = p; return NUMridders (chiSquareQ_func, xmin, xmax, & params); } static double fisherQ_func (double x, void *voidParams) { struct pdf2_struct *params = (struct pdf2_struct *) voidParams; double q = NUMfisherQ (x, params -> df1, params -> df2); return q == NUMundefined ? NUMundefined : q - params -> p; } double NUMinvFisherQ (double p, double df1, double df2) { if (p <= 0.0 || p > 1.0 || df1 < 1.0 || df2 < 1.0) { return NUMundefined; } if (Melder_debug == 29) { //if (p == 1.0) return 0.0; return gsl_cdf_fdist_Qinv (p, df1, df2); } else { struct pdf2_struct params; double top = 1000.0; if (p == 1.0) { return 0.0; } params. p = p; params. df1 = df1; params. df2 = df2; for (;;) { double q = NUMfisherQ (top, df1, df2); if (q == NUMundefined) { return NUMundefined; } if (q < p) { break; } if (top > 0.9e300) { return NUMundefined; } top *= 1e9; } return NUMridders (fisherQ_func, 0.0, p > 0.5 ? 2.2 : top, & params); } } double NUMbeta2 (double z, double w) { gsl_sf_result result; int status = gsl_sf_beta_e (z, w, &result); return status == GSL_SUCCESS ? result.val : NUMundefined; } double NUMlnBeta (double a, double b) { gsl_sf_result result; int status = gsl_sf_lnbeta_e (a, b, &result); return status == GSL_SUCCESS ? result.val : NUMundefined; } double NUMnormalityTest_HenzeZirkler (double **data, long n, long p, double *beta, double *tnb, double *lnmu, double *lnvar) { if (*beta <= 0) { *beta = (1.0 / sqrt (2.0)) * pow ((1.0 + 2 * p) / 4.0, 1.0 / (p + 4)) * pow (n, 1.0 / (p + 4)); } double p2 = p / 2.0; double beta2 = *beta * *beta, beta4 = beta2 * beta2, beta8 = beta4 * beta4; double gamma = 1.0 + 2.0 * beta2, gamma2 = gamma * gamma, gamma4 = gamma2 * gamma2; double delta = 1.0 + beta2 * (4.0 + 3.0 * beta2), delta2 = delta * delta; double prob = NUMundefined; *tnb = *lnmu = *lnvar = NUMundefined; if (n < 2 || p < 1) { return prob; } autoNUMvector zero (1, p); autoNUMmatrix covar (1, p, 1, p); autoNUMmatrix x (NUMmatrix_copy (data, 1, n, 1, p), 1, 1); NUMcentreColumns (x.peek(), 1, n, 1, p, NULL); // x - xmean NUMcovarianceFromColumnCentredMatrix (x.peek(), n, p, 0, covar.peek()); try { NUMlowerCholeskyInverse (covar.peek(), p, NULL); double djk, djj, sumjk = 0.0, sumj = 0.0; double b1 = beta2 / 2.0, b2 = b1 / (1.0 + beta2); /* Heinze & Wagner (1997), page 3 We use d[j][k] = ||Y[j]-Y[k]||^2 = (Y[j]-Y[k])'S^(-1)(Y[j]-Y[k]) So d[j][k]= d[k][j] and d[j][j] = 0 */ for (long j = 1; j <= n; j++) { for (long k = 1; k < j; k++) { djk = NUMmahalanobisDistance_chi (covar.peek(), x[j], x[k], p, p); sumjk += 2.0 * exp (-b1 * djk); // factor 2 because d[j][k] == d[k][j] } sumjk += 1.0; // for k == j djj = NUMmahalanobisDistance_chi (covar.peek(), x[j], zero.peek(), p, p); sumj += exp (-b2 * djj); } *tnb = (1.0 / n) * sumjk - 2.0 * pow (1.0 + beta2, - p2) * sumj + n * pow (gamma, - p2); // n * } catch (MelderError) { Melder_clearError (); *tnb = 4.0 * n; } double mu = 1.0 - pow (gamma, -p2) * (1.0 + p * beta2 / gamma + p * (p + 2) * beta4 / (2.0 * gamma2)); double var = 2.0 * pow (1.0 + 4.0 * beta2, -p2) + 2.0 * pow (gamma, -p) * (1.0 + 2.0 * p * beta4 / gamma2 + 3.0 * p * (p + 2) * beta8 / (4.0 * gamma4)) - 4.0 * pow (delta, -p2) * (1.0 + 3.0 * p * beta4 / (2.0 * delta) + p * (p + 2) * beta8 / (2.0 * delta2)); double mu2 = mu * mu; *lnmu = log (sqrt (mu2 * mu2 / (mu2 + var))); *lnvar = sqrt (log ( (mu2 + var) / mu2)); prob = NUMlogNormalQ (*tnb, *lnmu, *lnvar); return prob; } /*************** Hz <--> other freq reps *********************/ double NUMmelToHertz3 (double mel) { if (mel < 0.0) { return NUMundefined; } return mel < 1000.0 ? mel : 1000.0 * (exp (mel * log10 (2.0) / 1000.0) - 1.0); } double NUMhertzToMel3 (double hz) { if (hz < 0.0) { return NUMundefined; } return hz < 1000.0 ? hz : 1000.0 * log10 (1.0 + hz / 1000.0) / log10 (2.0); } double NUMmelToHertz2 (double mel) { if (mel < 0.0) { return NUMundefined; } return 700.0 * (pow (10.0, mel / 2595.0) - 1.0); } double NUMhertzToMel2 (double hz) { if (hz < 0.0) { return NUMundefined; } return 2595.0 * log10 (1.0 + hz / 700.0); } double NUMhertzToBark_traunmueller (double hz) { if (hz < 0.0) { return NUMundefined; } return 26.81 * hz / (1960.0 + hz) - 0.53; } double NUMbarkToHertz_traunmueller (double bark) { if (bark < 0.0 || bark > 26.28) { return NUMundefined; } return 1960.0 * (bark + 0.53) / (26.28 - bark); } double NUMbarkToHertz_schroeder (double bark) { return 650.0 * sinh (bark / 7.0); } double NUMbarkToHertz_zwickerterhardt (double hz) { if (hz < 0.0) { return NUMundefined; } return 13.0 * atan (0.00076 * hz) + 3.5 * atan (hz / 7500.0); } double NUMhertzToBark_schroeder (double hz) { if (hz < 0.0) { return NUMundefined; } double h650 = hz / 650.0; return 7.0 * log (h650 + sqrt (1.0 + h650 * h650)); } double NUMbarkToHertz2 (double bark) { if (bark < 0.0) { return NUMundefined; } return 650.0 * sinh (bark / 7.0); } double NUMhertzToBark2 (double hz) { if (hz < 0) { return NUMundefined; } double h650 = hz / 650.0; return 7.0 * log (h650 + sqrt (1.0 + h650 * h650)); } double NUMbladonlindblomfilter_amplitude (double zc, double z) { double dz = zc - z + 0.474; return pow (10.0, 1.581 + 0.75 * dz - 1.75 * sqrt (1.0 + dz * dz)); } double NUMsekeyhansonfilter_amplitude (double zc, double z) { double dz = zc - z - 0.215; return pow (10.0, 0.7 - 0.75 * dz - 1.75 * sqrt (0.196 + dz * dz)); } double NUMtriangularfilter_amplitude (double fl, double fc, double fh, double f) { double a = 0.0; if (f > fl && f < fh) { a = f < fc ? (f - fl) / (fc - fl) : (fh - f) / (fh - fc); /* Normalize such that area under the filter is always 1. ??? a /= 2 * (fh - fl);*/ } return a; } double NUMformantfilter_amplitude (double fc, double bw, double f) { double dq = (fc * fc - f * f) / (bw * f); return 1.0 / (dq * dq + 1.0); } /* Childers (1978), Modern Spectrum analysis, IEEE Press, 252-255) */ /* work[1..n+n+n]; b1 = & work[1]; b2 = & work[n+1]; aa = & work[n+n+1]; for (i=1; i<=n+n+n; i++) work[i]=0; */ int NUMburg (double x[], long n, double a[], int m, double *xms) { for (long j = 1; j <= m; j++) { a[j] = 0.0; } autoNUMvector b1 (1, n); autoNUMvector b2 (1, n); autoNUMvector aa (1, m); // (3) double p = 0.0; for (long j = 1; j <= n; j++) { p += x[j] * x[j]; } *xms = p / n; if (*xms <= 0.0) { return 0; // warning empty } // (9) b1[1] = x[1]; b2[n - 1] = x[n]; for (long j = 2; j <= n - 1; j++) { b1[j] = b2[j - 1] = x[j]; } for (long i = 1; i <= m; i++) { // (7) double num = 0.0, denum = 0.0; for (long j = 1; j <= n - i; j++) { num += b1[j] * b2[j]; denum += b1[j] * b1[j] + b2[j] * b2[j]; } if (denum <= 0.0) { return 0; // warning ill-conditioned } a[i] = 2.0 * num / denum; // (10) *xms *= 1.0 - a[i] * a[i]; // (5) for (long j = 1; j <= i - 1; j++) { a[j] = aa[j] - a[i] * aa[i - j]; } if (i < m) { // (8) Watch out: i -> i+1 for (long j = 1; j <= i; j++) { aa[j] = a[j]; } for (long j = 1; j <= n - i - 1; j++) { b1[j] -= aa[i] * b2[j]; b2[j] = b2[j + 1] - aa[i] * b1[j + 1]; } } } return 1; } void NUMdmatrix_to_dBs (double **m, long rb, long re, long cb, long ce, double ref, double factor, double floor) { double ref_db, factor10 = factor * 10.0; double max = m[rb][cb], min = max; Melder_assert (ref > 0 && factor > 0 && rb <= re && cb <= ce); for (long i = rb; i <= re; i++) { for (long j = cb; j <= ce; j++) { if (m[i][j] > max) { max = m[i][j]; } else if (m[i][j] < min) { min = m[i][j]; } } } if (max < 0 || min < 0) { Melder_throw (U"NUMdmatrix_to_dBs: all matrix elements must be positive."); } ref_db = factor10 * log10 (ref); for (long i = rb; i <= re; i++) { for (long j = cb; j <= ce; j++) { double mij = floor; if (m[i][j] > 0.0) { mij = factor10 * log10 (m[i][j]) - ref_db; if (mij < floor) { mij = floor; } } m[i][j] = mij; } } } double **NUMcosinesTable (long first, long last, long npoints) { Melder_assert (0 < first && first <= last && npoints > 0); autoNUMmatrix m (first, last, 1, npoints); for (long i = first; i <= last; i++) { double f = i * NUMpi / npoints; for (long j = 1; j <= npoints; j++) { m[i][j] = cos (f * (j - 0.5)); } } return m.transfer(); } void NUMspline (double x[], double y[], long n, double yp1, double ypn, double y2[]) { autoNUMvector u (1, n - 1); if (yp1 > 0.99e30) { y2[1] = u[1] = 0.0; } else { y2[1] = -0.5; u[1] = (3.0 / (x[2] - x[1])) * ( (y[2] - y[1]) / (x[2] - x[1]) - yp1); } for (long i = 2; i <= n - 1; i++) { double sig = (x[i] - x[i - 1]) / (x[i + 1] - x[i - 1]); double p = sig * y2[i - 1] + 2.0; y2[i] = (sig - 1.0) / p; u[i] = (y[i + 1] - y[i]) / (x[i + 1] - x[i]) - (y[i] - y[i - 1]) / (x[i] - x[i - 1]); u[i] = (6.0 * u[i] / (x[i + 1] - x[i - 1]) - sig * u[i - 1]) / p; } double qn, un; if (ypn > 0.99e30) { qn = un = 0.0; } else { qn = 0.5; un = (3.0 / (x[n] - x[n - 1])) * (ypn - (y[n] - y[n - 1]) / (x[n] - x[n - 1])); } y2[n] = (un - qn * u[n - 1]) / (qn * y2[n - 1] + 1.0); for (long k = n - 1; k >= 1; k--) { y2[k] = y2[k] * y2[k + 1] + u[k]; } } void NUMsplint (double xa[], double ya[], double y2a[], long n, double x, double *y) { long klo = 1, khi = n; while (khi - klo > 1) { long k = (khi + klo) >> 1; if (xa[k] > x) { khi = k; } else { klo = k; } } double h = xa[khi] - xa[klo]; if (h == 0.0) { Melder_throw (U"NUMsplint: bad input value."); } double a = (xa[khi] - x) / h; double b = (x - xa[klo]) / h; *y = a * ya[klo] + b * ya[khi] + ( (a * a * a - a) * y2a[klo] + (b * b * b - b) * y2a[khi]) * (h * h) / 6.0; } double NUMsinc (const double x) { struct gsl_sf_result_struct result; int status = gsl_sf_sinc_e (x / NUMpi, &result); return status == GSL_SUCCESS ? result. val : NUMundefined; } double NUMsincpi (const double x) { struct gsl_sf_result_struct result; int status = gsl_sf_sinc_e (x, &result); return status == GSL_SUCCESS ? result. val : NUMundefined; } /* Does the line segment from (x1,y1) to (x2,y2) intersect with the line segment from (x3,y3) to (x4,y4)? */ int NUMdoLineSegmentsIntersect (double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) { int o11 = NUMgetOrientationOfPoints (x1, y1, x2, y2, x3, y3); int o12 = NUMgetOrientationOfPoints (x1, y1, x2, y2, x4, y4); int o21 = NUMgetOrientationOfPoints (x3, y3, x4, y4, x1, y1); int o22 = NUMgetOrientationOfPoints (x3, y3, x4, y4, x2, y2); return ((o11 * o12 < 0) && (o21 * o22 < 0)) || (o11 *o12 *o21 *o22 == 0); } int NUMgetOrientationOfPoints (double x1, double y1, double x2, double y2, double x3, double y3) { int orientation; double dx2 = x2 - x1, dy2 = y2 - y1; double dx3 = x3 - x1, dy3 = y3 - y1; if (dx2 * dy3 > dy2 * dx3) { orientation = 1; } else if (dx2 * dy3 < dy2 * dx3) { orientation = -1; } else { if ((dx2 * dx3 < 0) || (dy2 * dy3 < 0)) { orientation = -1; } else if ((dx2 * dx2 + dy2 * dy2) >= (dx3 * dx3 + dy3 * dy3)) { orientation = 0; } else { orientation = 1; } } return orientation; } int NUMgetIntersectionsWithRectangle (double x1, double y1, double x2, double y2, double xmin, double ymin, double xmax, double ymax, double *xi, double *yi) { double x[6], y[6]; long ni = 0; x[1] = x[4] = x[5] = xmin; x[2] = x[3] = xmax; y[1] = y[2] = y[5] = ymin; y[3] = y[4] = ymax; /* Calculate intersection of line segment through p1=(x1,y1) to p2(x2,y2) with line segment through p3=(x3,y3) to p4=(x4,y4). Parametrisation of the lines: l1 = p1 + s (p2 - p1), s in (-inf,+inf) l2 = p3 + t (p4 - p3), t in (-inf,+inf). When s and t are in [0,1] we have line segments between the points. At the intersection l1 == l2. We get for the x and y coordinates: x1 + s (x2 - x1) = x3 + t (x4 - x3).............(1) y1 + s (y2 - y1) = y3 + t (y4 - y3).............(2) Multiply (1)*(y2 - y1) and (2)*(x2 - x1): x1 (y2 - y1) + s (x2 - x1)(y2 - y1) = x3 (y2 - y1) + t (x4 - x3)(y2 - y1).......(3) y1 (x2 - x1) + s (y2 - y1)(x2 - x1) = y3 (x2 - x1) + t (y4 - y3)(x2 - x1).......(4) (3)-(4) with y21 = y2 -y1, x21 = x2 - x1, x43 = x4 - x3, ... x1 y21 - y1 x21 = x3 y21 - y3 x21 +t (x43 y21 - y43 x21) Combining: y31 x21 - x31 y21 = t (x43 y21 - y43 x21) Therefor at the intersection we have: t = (y31 x21 - x31 y21) / (x43 y21 - y43 x21) If (x43 y21 - y43 x21) == 0 There is no intersection. If (t < 0 || t >= 1) No intersection in the segment l2 To count intersections in a corner only once we have t < 0 instead of t <= 0! */ for (long i = 1; i <= 4; i++) { double denom = (x[i + 1] - x[i]) * (y2 - y1) - (y[i + 1] - y[i]) * (x2 - x1); double s, t, x3, y3; if (denom == 0.0) { continue; } /* We have an intersection. */ t = ((y[i] - y1) * (x2 - x1) - (x[i] - x1) * (y2 - y1)) / denom; if (t < 0 || t >= 1) { continue; } /* Intersection is within rectangle side. */ x3 = x[i] + t * (x[i + 1] - x[i]); y3 = y[i] + t * (y[i + 1] - y[i]); /* s must also be valid */ if (x1 != x2) { s = (x3 - x1) / (x2 - x1); } else { s = (y3 - y1) / (y2 - y1); } if (s < 0 || s >= 1) { continue; } ni++; if (ni > 2) { Melder_throw (U"Too many intersections."); } xi[ni] = x3; yi[ni] = y3; } return ni; } bool NUMclipLineWithinRectangle (double xl1, double yl1, double xl2, double yl2, double xr1, double yr1, double xr2, double yr2, double *xo1, double *yo1, double *xo2, double *yo2) { int ncrossings = 0; bool xswap, yswap; double a, b, x, y, t, xc[5], yc[5], xmin, xmax, ymin, ymax; *xo1 = xl1; *yo1 = yl1; *xo2 = xl2; *yo2 = yl2; // This test first because we expect the majority of the tested segments to be // within the rectangle if (xl1 >= xr1 && xl1 <= xr2 && yl1 >= yr1 && yl1 <= yr2 && xl2 >= xr1 && xl2 <= xr2 && yl2 >= yr1 && yl2 <= yr2) { return true; } // All lines that are completely outside the rectangle if ( (xl1 <= xr1 && xl2 <= xr1) || (xl1 >= xr2 && xl2 >= xr2) || (yl1 <= yr1 && yl2 <= yr1) || (yl1 >= yr2 && yl2 >= yr2)) { return false; } // At least line spans (part of) the rectangle. // Get extremes in x and y of the line for easy testing further on. if (xl1 < xl2) { xmin = xl1; xmax = xl2; xswap = false; } else { xmin = xl2; xmax = xl1; xswap = true; } if (yl1 < yl2) { ymin = yl1; ymax = yl2; yswap = false; } else { ymin = yl2; ymax = yl1; yswap = true; } bool hline = yl1 == yl2, vline = xl1 == xl2; if (hline) { if (xmin < xr1) { *xo1 = xr1; } if (xmax > xr2) { *xo2 = xr2; } if (xswap) { t = *xo1; *xo1 = *xo2; *xo2 = t; } return true; } if (vline) { if (ymin < yr1) { *yo1 = yr1; } if (ymax > yr2) { *yo2 = yr2; } if (yswap) { t = *yo1; *yo1 = *yo2; *yo2 = t; } return true; } // Now we know that the line from (x1,y1) to (x2,y2) is neither horizontal nor vertical. // Parametrize it as y = ax + b a = (yl1 - yl2) / (xl1 - xl2); b = yl1 - a * xl1; // To determine the crossings we have to avoid counting the crossings in a corner twice. // Therefore we test the corners inclusive (..<=..<=..) on the vertical borders of the rectangle // and exclusive (..<..<) at the horizontal borders. y = a * xr1 + b; // Crossing at y with left border: x = xr1 if (y >= yr1 && y <= yr2 && xmin < xr1) { // Within vertical range? ncrossings++; xc[ncrossings] = xr1; yc[ncrossings] = y; xc[2] = xmax; yc[2] = xl1 > xl2 ? yl1 : yl2; } x = (yr2 - b) / a; // Crossing at x with top border: y = yr2 if (x > xr1 && x < xr2 && ymax > yr2) { // Within horizontal range? ncrossings++; xc[ncrossings] = x; yc[ncrossings] = yr2; if (ncrossings == 1) { yc[2] = ymin; xc[2] = yl1 < yl2 ? xl1 : xl2; } } y = a * xr2 + b; // Crossing at y with right border: x = xr2 if (y >= yr1 && y <= yr2 && xmax > xr2) { // Within vertical range? ncrossings++; xc[ncrossings] = xr2; yc[ncrossings] = y; if (ncrossings == 1) { xc[2] = xmin; yc[2] = xl1 < xl2 ? yl1 : yl2; } } x = (yr1 - b) / a; // Crossing at x with bottom border: y = yr1 if (x > xr1 && x < xr2 && ymin < yr1) { ncrossings++; xc[ncrossings] = x; yc[ncrossings] = yr1; if (ncrossings == 1) { yc[2] = ymax; xc[2] = yl1 > yl2 ? xl1 : xl2; } } if (ncrossings == 0) { return false; } if (ncrossings == 1 || ncrossings == 2) { // if start and endpoint of line are outside rectangle and ncrossings == 1, // than the line only touches. if (ncrossings == 1 && (xl1 < xr1 || xl1 > xr2 || yl1 < yr1 || yl1 > yr2) && (xl2 < xr1 || xl2 > xr2 || yl2 < yr1 || yl2 > yr2)) { return true; } if ( (xc[1] > xc[2] && ! xswap) || (xc[1] < xc[2] && xswap)) { t = xc[1]; xc[1] = xc[2]; xc[2] = t; t = yc[1]; yc[1] = yc[2]; yc[2] = t; } *xo1 = xc[1]; *yo1 = yc[1]; *xo2 = xc[2]; *yo2 = yc[2]; } else { Melder_throw (U"Too many crossings found."); } return true; } void NUMgetEllipseBoundingBox (double a, double b, double cospsi, double *width, double *height) { Melder_assert (cospsi >= -1 && cospsi <= 1); if (cospsi == 1) { // a-axis along x-axis *width = a; *height = b; } else if (cospsi == 0) { // a-axis along y-axis *width = b; *height = a; } else { double psi = acos (cospsi), sn = sin (psi); double phi = atan2 (-b * sn, a * cospsi); *width = fabs (a * cospsi * cos (phi) - b * sn * sin (phi)); phi = atan2 (b * cospsi , a * sn); *height = fabs (a * sn * cos (phi) + b * cospsi * sin (phi)); } } /* Closely modelled after the netlib code by Oleg Keselyov. */ double NUMminimize_brent (double (*f) (double x, void *closure), double a, double b, void *closure, double tol, double *fx) { double x, v, fv, w, fw; const double golden = 1 - NUM_goldenSection; const double sqrt_epsilon = sqrt (NUMfpp -> eps); long itermax = 60; Melder_assert (tol > 0 && a < b); /* First step - golden section */ v = a + golden * (b - a); fv = (*f) (v, closure); x = v; w = v; *fx = fv; fw = fv; for (long iter = 1; iter <= itermax; iter++) { double range = b - a; double middle_range = (a + b) / 2.0; double tol_act = sqrt_epsilon * fabs (x) + tol / 3.0; double new_step; /* Step at this iteration */ if (fabs (x - middle_range) + range / 2.0 <= 2.0 * tol_act) { return x; } // Obtain the golden section step new_step = golden * (x < middle_range ? b - x : a - x); // Decide if the parabolic interpolation can be tried if (fabs (x - w) >= tol_act) { /* Interpolation step is calculated as p/q; division operation is delayed until last moment. */ double t = (x - w) * (*fx - fv); double q = (x - v) * (*fx - fw); double p = (x - v) * q - (x - w) * t; q = 2.0 * (q - t); if (q > 0.0) { p = -p; } else { q = -q; } /* If x+p/q falls in [a,b], not too close to a and b, and isn't too large, it is accepted. If p/q is too large then the golden section procedure can reduce [a,b] range. */ if (fabs (p) < fabs (new_step * q) && p > q * (a - x + 2.0 * tol_act) && p < q * (b - x - 2.0 * tol_act)) { new_step = p / q; } } // Adjust the step to be not less than tolerance. if (fabs (new_step) < tol_act) { new_step = new_step > 0.0 ? tol_act : - tol_act; } // Obtain the next approximation to min and reduce the enveloping range { double t = x + new_step; // Tentative point for the min double ft = (*f) (t, closure); /* If t is a better approximation, reduce the range so that t would fall within it. If x remains the best, reduce the range so that x falls within it. */ if (ft <= *fx) { if (t < x) { b = x; } else { a = x; } v = w; w = x; x = t; fv = fw; fw = *fx; *fx = ft; } else { if (t < x) { a = t; } else { b = t; } if (ft <= fw || w == x) { v = w; w = t; fv = fw; fw = ft; } else if (ft <= fv || v == x || v == w) { v = t; fv = ft; } } } } Melder_warning (U"NUMminimize_brent: maximum number of iterations (", itermax, U") exceeded."); return x; } /* probs is probability vector, i.e. all 0 <= probs[i] <= 1 and sum(i=1;i=nprobs, probs[i])= 1 p is a probability */ long NUMgetIndexFromProbability (double *probs, long nprobs, double p) { long index = 1; double psum = probs[index]; while (p > psum && index < nprobs) { psum += probs[++index]; } return index; } // straight line fitting void NUMlineFit_theil (double *x, double *y, long numberOfPoints, double *m, double *intercept, bool incompleteMethod) { try { /* Theil's incomplete method: * Split (x[i],y[i]) as * (x[i],y[i]), (x[N+i],y[N=i], i=1..numberOfPoints/2 * m[i] = (y[N+i]-y[i])/(x[N+i]-x[i]) * m = median (m[i]) * b = median(y[i]-m*x[i]) */ if (numberOfPoints <= 0) { *m = *intercept = NUMundefined; } else if (numberOfPoints == 1) { *intercept = y[1]; *m = 0; } else if (numberOfPoints == 2) { *m = (y[2] - y[1]) / (x[2] - x[1]); *intercept = y[1] - *m * x[1]; } else { long numberOfCombinations; autoNUMvector mbs; if (incompleteMethod) { // incomplete method numberOfCombinations = numberOfPoints / 2; mbs.reset (1, numberOfPoints); // long n2 = numberOfPoints % 2 == 1 ? numberOfCombinations + 1 : numberOfCombinations; for (long i = 1; i <= numberOfCombinations; i++) { mbs[i] = (y[n2 + i] - y[i]) / (x[n2 + i] - x[i]); } } else { // use all combinations numberOfCombinations = (numberOfPoints - 1) * numberOfPoints / 2; mbs.reset (1, numberOfCombinations); long index = 0; for (long i = 1; i < numberOfPoints; i++) { for (long j = i + 1; j <= numberOfPoints; j++) { mbs[++index] = (y[j] - y[i]) / (x[j] - x[i]); } } } NUMsort_d (numberOfCombinations, mbs.peek()); *m = NUMquantile (numberOfCombinations, mbs.peek(), 0.5); for (long i = 1; i <= numberOfPoints; i++) { mbs[i] = y[i] - *m * x[i]; } NUMsort_d (numberOfPoints, mbs.peek()); *intercept = NUMquantile (numberOfPoints, mbs.peek(), 0.5); } } catch (MelderError) { Melder_throw (U"No line fit (Theil's method)"); } } void NUMlineFit_LS (double *x, double *y, long numberOfPoints, double *m, double *intercept) { double sx = 0.0, sy = 0.0; for (long i = 1; i <= numberOfPoints; i++) { sx += x[i]; sy += y[i]; } double xmean = sx / numberOfPoints; double st2 = 0.0, a = 0.0; for (long i = 1; i <= numberOfPoints; i++) { double t = x[i] - xmean; st2 += t * t; a += t * y[i]; } // y = a*x + b a /= st2; *intercept = (sy - a * sx) / numberOfPoints; *m = a; } void NUMlineFit (double *x, double *y, long numberOfPoints, double *m, double *intercept, int method) { if (method == 1) { NUMlineFit_LS (x, y, numberOfPoints, m, intercept); } else if (method == 3) { NUMlineFit_theil (x, y, numberOfPoints, m, intercept, false); } else { NUMlineFit_theil (x, y, numberOfPoints, m, intercept, true); } } // IEEE: Programs for digital signal processing section 4.3 LPTRN // lpc[1..n] to rc[1..n] void NUMlpc_lpc_to_rc (double *lpc, long p, double *rc) { autoNUMvector b (1, p); autoNUMvector a (NUMvector_copy (lpc, 1, p), 1); for (long m = p; m > 0; m--) { rc[m] = a[m]; if (fabs (rc[m]) > 1) { Melder_throw (U"Relection coefficient [", m, U"] larger than 1."); } for (long i = 1; i < m; i++) { b[i] = a[i]; } for (long i = 1; i < m; i++) { a[i] = (b[i] - rc[m] * b[m - i]) / (1.0 - rc[m] * rc[m]); } } } void NUMlpc_rc_to_area2 (double *rc, long n, double *area); void NUMlpc_rc_to_area2 (double *rc, long n, double *area) { double s = 0.0001; /* 1.0 cm^2 at glottis */ for (long i = n; i > 0; i--) { s *= (1.0 + rc[i]) / (1.0 - rc[i]); area[i] = s; } } void NUMlpc_area_to_lpc2 (double *area, long n, double *lpc); void NUMlpc_area_to_lpc2 (double *area, long n, double *lpc) { // from area to reflection coefficients autoNUMvector rc (1, n); // normalisation: area[n+1] = 0.0001 for (long j = n; j > 0; j--) { double ar = area[j+1] / area[j]; rc[j] = (1 - ar) / (1 + ar); } // LPTRAN works from mouth to lips: for (long j = 1; j <= n; j++) { lpc[j] = rc[n - j + 1]; } for (long j = 2; j <= n; j++) { long nh = j / 2; double q = rc[j]; for (long k = 1; k <= nh; k++) { double at = lpc[k] + q * lpc[j - k]; lpc[j - k] += q * lpc[k]; lpc[k] = at; } } } void NUMlpc_lpc_to_rc2 (double *lpc, long m, double *rc); void NUMlpc_lpc_to_rc2 (double *lpc, long m, double *rc) { // klopt nog niet NUMvector_copyElements (lpc, rc, 1, m); for (long j = 2; j <= m; j++) { long jb = m + 1 - j; long mh = (jb + 1) / 2; double rct = rc[jb+1]; double d = 1.0 - rct * rct; for (long k = 1; k <= mh; k++) { rc[k] *= (1 - rct) / d; } } } // area[1] at lips generates n+1 areas from n rc's void NUMlpc_rc_to_area (double *rc, long m, double *area) { area[m+1] = 0.0001; /* 1.0 cm^2 */ for (long j = 1; j <= m; j++) { double ar = (1.0 - rc[m+1-j]) / (1.0 + rc[m+1-j]); area[m+1-j] = area[m+2-j] / ar; } } // returns m-1 reflection coefficients from m areas void NUMlpc_area_to_rc (double *area, long m, double *rc) { for (long j = 1; j <= m - 1; j++) { double ar = area[j+1] / area[j]; rc[j] = (1.0 - ar) / (1.0 + ar); } } void NUMlpc_rc_to_lpc (double *rc, long m, double *lpc); void NUMlpc_rc_to_lpc (double *rc, long m, double *lpc) { NUMvector_copyElements (rc, lpc, 1, m); for (long j = 2; j <= m; j++) { for (long k = 1; k <= j / 2; k++) { double at = lpc[k] + rc[j] * lpc[j - k]; lpc[j - k] += rc[j] * lpc[k]; lpc[k] = at; } } } void NUMlpc_area_to_lpc (double *area, long m, double *lpc) { // from area to reflection coefficients autoNUMvector rc (1, m); // normalisation: area[n+1] = 0.0001 NUMlpc_area_to_rc (area, m, rc.peek()); NUMlpc_rc_to_lpc (rc.peek(), m - 1, lpc); } void NUMlpc_lpc_to_area (double *lpc, long m, double *area) { autoNUMvector rc (1, m); NUMlpc_lpc_to_rc (lpc, m, rc.peek()); NUMlpc_rc_to_area (rc.peek(), m, area); } #undef MAX #undef MIN #undef SIGN #define SMALL_MEAN 14 /* If n*p < SMALL_MEAN then use BINV algorithm. The ranlib implementation used cutoff=30; * but on my (Brian Gough) computer 14 works better */ #define BINV_CUTOFF 110 /* In BINV, do not permit ix too large */ #define FAR_FROM_MEAN 20 /* If ix-n*p is larger than this, then use the "squeeze" algorithm. * Ranlib used 20, and this seems to be the best choice on my (Brian Gough) machine as well. */ #define LNFACT(x) gsl_sf_lnfact(x) inline static double Stirling (double y1) { double y2 = y1 * y1; double s = (13860.0 - (462.0 - (132.0 - (99.0 - 140.0 / y2) / y2) / y2) / y2) / y1 / 166320.0; return s; } // djmw 20121211 replaced calls to gsl_rng_uniform with NUMrandomUniform (0,1) long NUMrandomBinomial (double p, long n) { if (p < 0.0 || p > 1.0 || n < 0) { return -100000000; } long ix; /* return value */ int flipped = 0; if (n == 0) { return 0; } if (p > 0.5) { p = 1.0 - p; /* work with small p */ flipped = 1; } double q = 1.0 - p; double s = p / q; double np = n * p; /* Inverse cdf logic for small mean (BINV in K+S) */ if (np < SMALL_MEAN) { double f0 = pow (q, n); // djmw gsl_pow_int (q, n); /* f(x), starting with x=0 */ while (1) { /* This while(1) loop will almost certainly only loop once; but * if u=1 to within a few epsilons of machine precision, then it * is possible for roundoff to prevent the main loop over ix to * achieve its proper value. following the ranlib implementation, * we introduce a check for that situation, and when it occurs, * we just try again. */ double f = f0; double u = NUMrandomUniform (0.0, 1.0); //djmw gsl_rng_uniform (rng); for (ix = 0; ix <= BINV_CUTOFF; ++ix) { if (u < f) { goto Finish; } u -= f; /* Use recursion f(x+1) = f(x)*[(n-x)/(x+1)]*[p/(1-p)] */ f *= s * (n - ix) / (ix + 1.0); } /* It should be the case that the 'goto Finish' was encountered * before this point was ever reached. But if we have reached * this point, then roundoff has prevented u from decreasing * all the way to zero. This can happen only if the initial u * was very nearly equal to 1, which is a rare situation. In * that rare situation, we just try again. * * Note, following the ranlib implementation, we loop ix only to * a hardcoded value of SMALL_MEAN_LARGE_N=110; we could have * looped to n, and 99.99...% of the time it won't matter. This * choice, I think is a little more robust against the rare * roundoff error. If n>LARGE_N, then it is technically * possible for ix>LARGE_N, but it is astronomically rare, and * if ix is that large, it is more likely due to roundoff than * probability, so better to nip it at LARGE_N than to take a * chance that roundoff will somehow conspire to produce an even * larger (and more improbable) ix. If n= SMALL_MEAN, we invoke the BTPE algorithm */ double ffm = np + p; /* ffm = n*p+p */ long m = (long) ffm; /* m = int floor[n*p+p] */ double fm = m; /* fm = double m; */ double xm = fm + 0.5; /* xm = half integer mean (tip of triangle) */ double npq = np * q; /* npq = n*p*q */ /* Compute cumulative area of tri, para, exp tails */ /* p1: radius of triangle region; since height=1, also: area of region */ /* p2: p1 + area of parallelogram region */ /* p3: p2 + area of left tail */ /* p4: p3 + area of right tail */ /* pi/p4: probability of i'th area (i=1,2,3,4) */ /* Note: magic numbers 2.195, 4.6, 0.134, 20.5, 15.3 */ /* These magic numbers are not adjustable...at least not easily! */ double p1 = floor (2.195 * sqrt (npq) - 4.6 * q) + 0.5; /* xl, xr: left and right edges of triangle */ double xl = xm - p1; double xr = xm + p1; /* Parameter of exponential tails */ /* Left tail: t(x) = c*exp(-lambda_l*[xl - (x+0.5)]) */ /* Right tail: t(x) = c*exp(-lambda_r*[(x+0.5) - xr]) */ double c = 0.134 + 20.5 / (15.3 + fm); double p2 = p1 * (1.0 + c + c); double al = (ffm - xl) / (ffm - xl * p); double lambda_l = al * (1.0 + 0.5 * al); double ar = (xr - ffm) / (xr * q); double lambda_r = ar * (1.0 + 0.5 * ar); double p3 = p2 + c / lambda_l; double p4 = p3 + c / lambda_r; double var, accept; double u, v; /* random variates */ TryAgain: /* generate random variates, u specifies which region: Tri, Par, Tail */ u = p4 * NUMrandomUniform (0.0, 1.0); // djmw gsl_rng_uniform (rng) * p4; v = NUMrandomUniform (0.0, 1.0); // djmw gsl_rng_uniform (rng); if (u <= p1) { /* Triangular region */ ix = (long) (xm - p1 * v + u); goto Finish; } else if (u <= p2) { /* Parallelogram region */ double x = xl + (u - p1) / c; v = v * c + 1.0 - fabs (x - xm) / p1; if (v > 1.0 || v <= 0.0) { goto TryAgain; } ix = (long) x; } else if (u <= p3) { /* Left tail */ ix = (long) (xl + log (v) / lambda_l); if (ix < 0) { goto TryAgain; } v *= ((u - p2) * lambda_l); } else { /* Right tail */ ix = (long) (xr - log (v) / lambda_r); if (ix > (double) n) { goto TryAgain; } v *= ((u - p3) * lambda_r); } /* At this point, the goal is to test whether v <= f(x)/f(m) * * v <= f(x)/f(m) = (m!(n-m)! / (x!(n-x)!)) * (p/q)^{x-m} * */ /* Here is a direct test using logarithms. It is a little * slower than the various "squeezing" computations below, but * if things are working, it should give exactly the same answer * (given the same random number seed). */ #ifdef DIRECT var = log (v); accept = LNFACT (m) + LNFACT (n - m) - LNFACT (ix) - LNFACT (n - ix) + (ix - m) * log (p / q); #else /* SQUEEZE METHOD */ /* More efficient determination of whether v < f(x)/f(M) */ long k = labs (ix - m); if (k <= FAR_FROM_MEAN) { /* * If ix near m (ie, |ix-m| ix) { for (long i = ix + 1; i <= m; i++) { f /= (g / i - s); } } accept = f; } else { /* If ix is far from the mean m: k=ABS(ix-m) large */ var = log (v); if (k < npq / 2 - 1) { /* "Squeeze" using upper and lower bounds on * log(f(x)) The squeeze condition was derived * under the condition k < npq/2-1 */ double amaxp = k / npq * ((k * (k / 3.0 + 0.625) + (1.0 / 6.0)) / npq + 0.5); double ynorm = -(k * k / (2.0 * npq)); if (var < ynorm - amaxp) { goto Finish; } if (var > ynorm + amaxp) { goto TryAgain; } } /* Now, again: do the test log(v) vs. log f(x)/f(M) */ #if USE_EXACT /* This is equivalent to the above, but is a little (~20%) slower */ /* There are five log's vs three above, maybe that's it? */ accept = LNFACT (m) + LNFACT (n - m) - LNFACT (ix) - LNFACT (n - ix) + (ix - m) * log (p / q); #else /* USE STIRLING */ /* The "#define Stirling" above corresponds to the first five * terms in asymptoic formula for * log Gamma (y) - (y-0.5)log(y) + y - 0.5 log(2*pi); * See Abramowitz and Stegun, eq 6.1.40 */ /* Note below: two Stirling's are added, and two are * subtracted. In both K+S, and in the ranlib * implementation, all four are added. I (jt) believe that * is a mistake -- this has been confirmed by personal * correspondence w/ Dr. Kachitvichyanukul. Note, however, * the corrections are so small, that I couldn't find an * example where it made a difference that could be * observed, let alone tested. In fact, define'ing Stirling * to be zero gave identical results!! In practice, alv is * O(1), ranging 0 to -10 or so, while the Stirling * correction is typically O(10^{-5}) ...setting the * correction to zero gives about a 2% performance boost; * might as well keep it just to be pendantic. */ { double x1 = ix + 1.0; double w1 = n - ix + 1.0; double f1 = fm + 1.0; double z1 = n + 1.0 - fm; accept = xm * log (f1 / x1) + (n - m + 0.5) * log (z1 / w1) + (ix - m) * log (w1 * p / (x1 * q)) + Stirling (f1) + Stirling (z1) - Stirling (x1) - Stirling (w1); } #endif #endif } if (var <= accept) { goto Finish; } else { goto TryAgain; } } Finish: return (flipped) ? (n - ix) : ix; } /* End of file NUM2.cpp */ praat-6.0.04/dwsys/NUM2.h000066400000000000000000001327561261542461700150010ustar00rootroot00000000000000#ifndef _NUM2_h_ #define _NUM2_h_ /* NUM2.h * * Copyright (C) 1997-2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020815 GPL header djmw 20121024 Latest modification. */ #include #include "../num/NUM.h" #include "regularExp.h" /* machine precision */ #define NUMeps 2.2e-16 int NUMstrcmp (const char *s1, const char *s2); /* Compares strings, accepts NUL-strings (NULL < 'a') return s1 == NULL ? (s2 == NULL ? 0 : - 1) : (s2 == NULL ? 1 : strcmp (s1, s2)); */ int NUMstring_containsPrintableCharacter (const char32 *s); void NUMstring_chopWhiteSpaceAtExtremes_inline (char32 *string); double *NUMstring_to_numbers (const char32 *s, long *numbers_found); /* return array with the number of numbers found */ /* * Acceptable ranges e.g. "1 4 2 3:7 4:3 3:5:2" --> * 1, 4, 2, 3, 4, 5, 6, 7, 4, 3, 3, 4, 5, 4, 3, 2 * Overlap is allowed. Ranges can go up and down. */ long *NUMstring_getElementsOfRanges (const char32 *ranges, long maximumElement, long *numberOfElements, long *numberOfMultiples, const char32 *elementType, bool sortedUniques); char32 * NUMstring_timeNoDot (double time); int NUMstrings_equal (const char32 **s1, const char32 **s2, long lo, long hi); void NUMstrings_copyElements (char32 **from, char32**to, long lo, long hi); void NUMstrings_free (char32 **s, long lo, long hi); int NUMstrings_setSequentialNumbering (char32 **s, long lo, long hi, const char32 *precursor, long number, long increment, int asArray); /* Set s[lo] = precursor s[lo+1] = precursor ... s[hi] = precursor */ char32 **NUMstrings_copy (char32 **from, long lo, long hi); regexp *NUMregexp_compile (const char32 *regexp); /* Compiles a regular expression to a datastructure used by the regexp engine */ char32 *strstr_regexp (const char32 *string, const char32 *search_regexp); /* Returns a pointer to the first occurrence in 'string' of the regular expression 'searchRE'. It returns a null pointer if no match is found. */ char32 **strs_replace (char32 **from, long lo, long hi, const char32 *search, const char32 *replace, int maximumNumberOfReplaces, long *nmatches, long *nstringmatches, int use_regexp); /* Searches and replaces in string array of strings. If use_regexp != 0, 'search' and 'replace' will be interpreted as regular expressions. Else these strings are taken literally. 'maximumNumberOfReplaces' is the maximum number of replaces in EACH string in the array of strings (you can replace ALL occurrences by making this number <= 0). The totalnumber of matches found is returned in 'nmatches'. The number of strings with at least one match is returned in 'nstringmatches'. */ char32 *str_replace_literal (const char32 *string, const char32 *search, const char32 *replace, long maximumNumberOfReplaces, long *nmatches); /* Search and replace in 'string'. The maximum number of replaces is limited by 'maximumNumberOfReplaces'. */ char32 *str_replace_regexp (const char32 *string, regexp *search_compiled, const char32 *replace_regexp, long maximumNumberOfReplaces, long *nmatches); /* Searches and replaces 'maximumNumberOfReplaces' times in 'string' on the basis of regular expressions (RE). If maximumNumberOfReplaces <= 0 the interpreted 'replaceRE' replaces ALL occurrences. 'search_regexp' is an efficient representation of the search RE and is the result of the compileRE-function which must be called first before calling this routine. The number of matches found is returned in 'nmatches'. */ void NUMdmatrix_printMatlabForm (double **m, long nr, long nc, const char32 *name); /* Print a matrix in a form that can be used as input for octave/matlab. 1 2 3 Let A be the matrix: 4 5 6 7 8 9 The output from NUMdmatrix_printAsOctaveForm (A, 3, 3, "M") will be M=[1, 2, 3; 4, 5, 6; 7, 8, 9]; */ double **NUMdmatrix_transpose (double **m, long nr, long nc); /* Transpose a nr x nc matrix. */ /* NUMvector_extrema * Function: * compute minimum and maximum values of array v[lo..hi]. * Precondition: * lo and hi must be valid indices in the array. */ template void NUMvector_extrema (T *v, long lo, long hi, double *min, double *max) { T tmin = v[lo]; T tmax = tmin; for (long i = lo + 1; i <= hi; i++) { if (v[i] < tmin) tmin = v[i]; else if (v[i] > tmax) tmax = v[i]; } *min = tmin; *max = tmax; } template void NUMmatrix_extrema (T **x, long rb, long re, long cb, long ce, double *min, double *max) { T xmin, xmax; xmax = xmin = x[rb][cb]; for (long i = rb; i <= re; i++) { for (long j = cb; j <= ce; j++) { T t = x[i][j]; if (t < xmin) xmin = t; else if (t > xmax) xmax = t; } } *min = xmin; *max = xmax; } /* NUMvector_clip Clip array values. c[i] = c[i] < min ? min : (c[i] > max ? max : c[i]) */ template void NUMvector_clip (T *v, long lo, long hi, double min, double max) { T tmin = min, tmax = max; for (long i = lo; i <= hi; i++) { if (v[i] < tmin) v[i] = tmin; else if (v[i] > tmax) v[i] = tmax; } } template T ** NUMmatrix_transpose (T **m, long nr, long nc) { autoNUMmatrix to (1, nc, 1, nr); for (long i = 1; i <= nr; i++) { for (long j = 1; j <= nc; j++) { to[j][i] = m[i][j]; } } return to.transfer(); } int NUMdmatrix_hasInfinities (double **m, long rb, long re, long cb, long ce); double NUMvector_normalize1 (double v[], long n); double NUMvector_normalize2 (double v[], long n); double NUMvector_getNorm1 (const double v[], long n); double NUMvector_getNorm2 (const double v[], long n); void NUMcentreRows (double **a, long rb, long re, long cb, long ce); /* a[i][j] -= a[i][.] */ void NUMcentreColumns (double **a, long rb, long re, long cb, long ce, double *centres); /* a[i][j] -= a[.][j] if centres != NULL the means are returned in centres[1..re-rb+1] */ void NUMdoubleCentre (double **a, long rb, long re, long cb, long ce); /* Function: Make the average value of each column and each row zero. a[i][j] += - a[i][.] - a[.][j] + a[.][.] */ void NUMnormalizeRows (double **a, long nr, long nc, double norm); void NUMnormalizeColumns (double **a, long nr, long nc, double norm); /* Scale a[.][j] such that sqrt (Sum(a[i][j]^2, i=1..nPoints)) = norm. */ void NUMnormalize (double **a, long nr, long nc, double norm); /* Scale all elements of the matrix [1..nr][1..nc] such that (sqrt(Sum( a[i][j]^2, i=1..nr, j=1..nc)) becomes equal to norm. */ void NUMstandardizeColumns (double **a, long rb, long re, long cb, long ce); /* a[i][j] = (a[i][j] - average[j]) / sigma[j] */ void NUMstandardizeRows (double **a, long rb, long re, long cb, long ce); /* a[i][j] = (a[i][j] - average[i]) / sigma[i] */ void NUMaverageColumns (double **a, long rb, long re, long cb, long ce); /* a[i][j] = average[j]) */ void NUMvector_avevar (double *a, long n, double *average, double *variance); void NUMcolumn_avevar (double **a, long nr, long nc, long icol, double *average, double *variance); /* Get mean and variance of a column. When average and/or variance are NULL, the corresponding output is NOT given. */ void NUMcolumn2_avevar (double **a, long nr, long nc, long icol1, long icol2, double *average1, double *variance1, double *average2, double *variance2, double *covariance); /* Get mean and variance of two columns. When average and/or variance are NULL, the corresponding output is NOT given. */ void NUMvector_smoothByMovingAverage (double *xin, long n, long nwindow, double *xout); void NUMcovarianceFromColumnCentredMatrix (double **x, long nrows, long ncols, long ndf, double **covar); /* Calculate covariance matrix(ncols x ncols) from data matrix (nrows x ncols); The matrix covar must already have been allocated and centered. covar[i][j] = sum (k=1..nrows, x[i]k]*x[k][j])/(nrows - ndf) */ double NUMmultivariateKurtosis (double **x, long nrows, long ncols, int method); /* calculate multivariate kurtosis. method = 1 : Schott (2001), J. of Statistical planning and Inference 94, 25-36. */ void NUMmad (double *x, long n, double *location, int wantlocation, double *mad, double *work); /* Computes the median absolute deviation, i.e., the median of the absolute deviations from the median, and adjust by a factor for asymptotically normal consistency, i.e. the returned value is 1.4826*mad which makes the returned value "equal" to the standard deviation if the data is normally distributed. You either GIVE the median location (if wantlocation = 0) or it will be calculated (if wantlocation = 1); work is a working array (1..n) that can be used for efficiency reasons. If work == NULL, the routine allocates (and destroys) its own memory. */ void NUMstatistics_huber (double *x, long n, double *location, int wantlocation, double *scale, int wantscale, double k, double tol, double *work); /* Finds the Huber M-estimator for location with scale specified, scale with location specified, or both if neither is specified. k Winsorizes at `k' standard deviations. work is a working array (1..n) that can be used for efficiency reasons. If work == NULL, the routine allocates (and destroys) its own memory. */ void NUMmonotoneRegression (const double x[], long n, double xs[]); /* Find numbers xs[1..n] that have a monotone relationship with the numbers in x[1..n]. The xs[i] will be ascending. */ /* NUMsort2: NUMsort2 uses heapsort to sort the second array in parallel with the first one. Algorithm follows p. 145 and 642 in: Donald E. Knuth (1998): The art of computer programming. Third edition. Vol. 3: sorting and searching. Boston: Addison-Wesley, printed may 2002. Modification: there is no distinction between record and key and Floyd's optimization (page 642) is used. Sorts (inplace) an array a[1..n] into ascending order using the Heapsort algorithm, while making the corresponding rearrangement of the companion array b[1..n]. A characteristic of heapsort is that it does not conserve the order of equals: e.g., the array 3,1,1,2 will be sorted as 1,1,2,3. It may occur that a_sorted[1] = a_presorted[2] and a_sorted[2] = a_presorted[1] */ template void NUMsort2 (long n, T1 *a, T2 *b) { long l, r, j, i, imin; T1 k, min; T2 kb, min2; if (n < 2) { return; /* Already sorted. */ } if (n == 2) { if (a[1] > a[2]) { min = a[2]; a[2] = a[1]; a[1] = min; min2 = b[2]; b[2] = b[1]; b[1] = min2; } return; } if (n <= 12) { for (i = 1; i < n; i++) { min = a[i]; imin = i; for (j = i + 1; j <= n; j++) { if (a[j] < min) { min = a [j]; imin = j; } } a[imin] = a[i]; a[i] = min; min2 = b[imin]; b[imin] = b[i]; b[i] = min2; } return; } /* H1 */ l = (n >> 1) + 1; r = n; for (;;) { if (l > 1) { l--; k = a[l]; kb = b[l]; } else /* l == 1 */ { k = a[r]; kb = b[r]; a[r] = a[1]; b[r] = b[1]; r--; if (r == 1) { a[1] = k; b[1] = kb; return; } } /* H3 */ j = l; for (;;) { /* H4 */ i = j; j = j << 1; if (j > r) break; if (j < r && a[j] < a[j + 1]) j++; /* H5 */ /* if (k >= a[j]) break; H6 */ a[i] = a[j]; b[i] = b[j]; /* H7 */ } /* a[i] = k; b[i] = kb; H8 */ for (;;) { /*H8' */ j = i; i = j >> 1; /* H9' */ if (j == l || k <= a[i]) { a[j] = k; b[j] = kb; break; } a[j] = a[i]; b[j] = b[i]; } } } void NUMindexx (const double a[], long n, long indx[]); void NUMindexx_s (char32 *a[], long n, long indx[]); /* Indexes the array a[1..n], i.e., outputs the array indx[1..n] such that a[ indx[i] ] is in ascending order for i=1..n; No preservation of order amoung equals (see NUMsort2_...) */ /* NUMrank: * Replace content of array by rank number, including midranking of ties. * E.g. The elements {10, 20.1, 20.1, 20.1, 20.1, 30} in array a will be replaced * by {1, 3.5, 3.5, 3.5, 3.5, 4}, respectively. * */ template void NUMrank (long n, T *a) { long jt, j = 1; while (j < n) { for (jt = j + 1; jt <= n && a[jt] == a[j]; jt++) {} T rank = (j + jt - 1) * 0.5; for (long i = j; i <= jt - 1; i++) { a[i] = rank; } j = jt; } if (j == n) a[n] = n; } void NUMrankColumns (double **m, long rb, long re, long cb, long ce); void NUMlocate_f (float *xx, long n, float x, long *index); void NUMlocate (double *xx, long n, double x, long *index); /* Given an array xx[1..n], and given a value x, returns a value index such that xx[index] < x <= xx[index+1]. Preconditions: xx must be monotonic Error: index = 0 or index = n (out of range) */ int NUMjacobi (float **a, long n, float d[], float **v, long *nrot); /* This version deviates from the NR version. HERE: v[1..n][1..n] is a matrix whose ROWS (and not the columns) contain, on output, the normalized eigenvectors of `a'. Computes all eigenvalues and eigenvectors of a real symmetric matrix a[1..n][1..n]. On output, elements of `a' above the diagonal are destroyed. d[1..n] returns the eigenvalues of `a'. `nrot' returns the number of Jacobi rotations that were required. */ void NUMtred2_f (float **a, long n, float d[], float e[]); void NUMtred2 (double **a, long n, double d[], double e[]); /* Householder reduction of a real, symmetric matrix a[1..n][1..n]. On output, a is replaced by the orthogonal matrix Q effecting the transformation. d[1..n] returns the diagonal elements of the tridiagonal matrix, and e[1..n] the off-diagonal elements, with e[1] = 0. */ int NUMtqli_f (float d[], float e[], long n, float **z); int NUMtqli (double d[], double e[], long n, double **z); /* QL algorithm with implicit shifts, to determine the (sorted) eigenvalues and eigenvectors of a real, symmetric, tridiagonal matrix, or of a real, symmetric matrix previously reduced by NUMtred2 . On input d[1..n] contains the diagonal elements of the tridiagonal matrix. On output, it returns the eigenvalues. The vector e[1..n] inputs the subdiagonal elements of the tridiagonal matrix, with e[1] arbitrary. On output e is destroyed. If the eigenvectors of a tridiagonal matrix are desired, the matrix z[1..n][1..n] is input as the identity matrix. If the eigenvectors of a matrix that has been reduced by NUMtred2 are required, then z is input as the matrix output by NUMtred2. The k-th column of z returns the normalized eigenvector corresponding to d[k]. Returns 0 in case of too many rotations. */ int NUMgaussj (double **a, long n, double **b, long m); int NUMgaussj_f (float **a, long n); /* Calculate inverse of square matrix a[1..n][1..n] (in-place). Method: Gauss-Jordan elimination with full pivoting. Error message in case of singular matrix. */ int NUMsvdcmp (double **a, long m, long n, double w[], double **v); /* Given a matrix a[1..m][1..n], this routine computes its singular value decomposition, A = U.W.V'. The matrix U replaces a on output. The diagonal matrix of singular values W is output as vector w[1..n]. The matrix V (not the transpose V') is output as v[1..n][1..n]. Possible errors: no memory or more than 30 iterations. */ int NUMsvbksb (double **u, double w[], double **v, long m, long n, double b[], double x[]); /* Solves A.X=B for a vector X, where A is specified by the arrays u[1..m][1..n], w[1..n], v[1..n][1..n] as returned by NUMsvdcmp. m and n are the dimensions of a, and will be equal for square matrices. b[1..m] is the input right-hand side. x[1..n] is the output solution vector. Possible errors: no memory. */ int NUMludcmp (double **a, long n, long *indx, double *d); int NUMludcmp_f (float **a, long n, long *indx, float *d); /* Given a matrix a[1..n][1..n], this routine replaces it by the LU decomposition of a rowwise permutation of itself. a : matrix [1..n][1..n] n : dimension of matrix indx : output vector[1..n] that records the row permutation effected by partial pivoting. d : output +/-1 depending on whether the number of ro interchanges was even/odd. */ int NUMcholeskyDecomposition(double **a, long n, double d[]); /* Cholesky decomposition of a symmetric positive definite matrix. */ void NUMcholeskySolve (double **a, long n, double d[], double b[], double x[]); /* Solves A.x=b for x. A[][] and d[] are output from NUMcholeskyDecomposition. */ void NUMlowerCholeskyInverse (double **a, long n, double *lnd); /* Calculates L^-1, where A = L.L' is a symmetric positive definite matrix and ln(determinant). L^-1 in lower, leave upper part intact. */ double **NUMinverseFromLowerCholesky (double **m, long n); /* Return the complete matrix inverse (m x m). Input is the lower Cholesky decomposition of the inverse as calculated by NUMlowerCholeskyInverse. */ void NUMdeterminant_cholesky (double **a, long n, double *lnd); /* ln(determinant) of a symmetric p.s.d. matrix */ double NUMmahalanobisDistance_chi (double **l, double *v, double *m, long nr, long nc); /* Calculates squared Mahalanobis distance: (v-m)'S^-1(v-m). Input matrix (li) is the inverse L^-1 of the Cholesky decomposition S = L.L' as calculated by NUMlowerCholeskyInverse or 1-row for a diagonal matrix (nr =1) Mahalanobis distance calculation. S = L.L' -> S**-1 = L**-1' . L**-1 (x-m)'S**-1 (x-m) = (x-m)'L**-1' . L**-1. (x-m) = (L**-1.(x-m))' . (L**-1.(x-m)) */ double NUMtrace (double **a, long n); double NUMtrace2 (double **a1, double **a2, long n); /* Calculates the trace from the product matrix a1 * a2. a1 and a2 are [1..n][1..n] square matrices. */ void eigenSort (double d[], double **v, long n, int sort); void NUMeigensystem (double **a, long n, double **evec, double eval[]); /* Determines the eigensystem of a real, symmetric matrix[1..][1..n]. Returned are: evec[1..n][1..n] with eigenvectors (columnwise) and eval[1..n], the eigenvalues. No eigenvectors or eigenvalues are returned when the function is called with the corresponding parameter NULL. Eigenvalues (with corresponding eigenvectors) are sorted in descending order. */ void NUMdominantEigenvector (double **mns, long n, double *q, double *lambda, double tolerance); /* Determines the first dominant eigenvector from a GENERAL matrix mns[1..n][1..]. Besides the matrix mns, a first guess for the eigenvector q must be supplied (e.g. 1,0,...,0) and a value for tolerance (iteration stops when fabs(lamda[k] - lambda[k-1]) <= tolerance, where lamda[k] is the eigenvalue at the k-th iteration step. The methos is described in: G. Golub & C. van Loan (1996), Matrix computations, third edition, The Johns Hopkins University Press Ltd., London, (Par. 7.3.1 The Power Method) */ void NUMdmatrix_into_principalComponents (double **m, long nrows, long ncols, long numberOfComponents, double **pc); /* Precondition: numberOfComponents > 0 && numberOfComponents <= ncols pc[1..nrows][1..numberOfComponents] exists Function: Calculates the first 'numberOfComponents' principal components for the matrix m[1..nrows][1..ncols]. Postcondition: Matrix pc contains the principal components Algorithm: Singular Value Decomposition: 1. Centre the columns of m, this results in a new matrix mc 2. SVD the mc matrix -> U.d.V' (Covariance matrix from mc is mc'.mc = (U.d.V')'.(U.d.V') = V.d^2.V') 3. Sort singular values d (descending) and corresponding vectors in V 4. The principal components are now: pc[i][j] = sum (k=1..ncols, v[k][j] * m[i][k]) Remark: The resulting configuration is unique up to reflections along the new principal directions. */ void NUMprincipalComponents (double **a, long n, long nComponents, double **pc); /* Determines the principal components of a real symmetric matrix a[1..n][1..n] as a pc[1..n][1..nComponents] column matrix. */ void NUMpseudoInverse (double **y, long nr, long nc, double **yinv, double tolerance); /* Determines the pseudo-inverse Y^-1 of Y[1..nr][1..nc] via s.v.d. Alternative notation for pseudo-inverse: (Y'.Y)^-1.Y' Returns a [1..nc][1..nr] matrix */ long NUMsolveQuadraticEquation (double a, double b, double c, double *x1, double *x2); /* Finds the real roots of ax^2 + bx + c = 0. The number of real roots is returned and their locations in x1 and x2. If only one root found it is stored in x1. If no roots found then x1 and x2 will not be changed. */ void NUMsolveEquation (double **a, long nr, long nc, double *b, double tol, double *x); /* Solve the equation: a.x = b; a[1..nr][1..nc], b[1..nr] and the unknown x[1..nc] a & b are destroyed during the computation. Algorithm: s.v.d. */ void NUMsolveEquations (double **a, long nr, long nc, double **b, long ncb, double tol, double **x); /* Solve the equation: a.x = b; a[1..nr][1..nc], b[1..nr][1..nc2] and the unknown x[1..nc][1..nc2] a & b are destroyed during the computation. Algorithm: s.v.d. */ void NUMsolveNonNegativeLeastSquaresRegression (double **a, long nr, long nc, double *b, double tol, long itermax, double *x); /* Solve the equation: a.x = b for x under the constraint: all x[i] >= 0; a[1..nr][1..nc], b[1..nr] and x[1..nc]. Algorithm: Alternating least squares. Borg & Groenen (1997), Modern multidimensional scaling, Springer, page 180. */ void NUMsolveConstrainedLSQuadraticRegression (double **o, const double y[], long n, double *alpha, double *gamma); /* Solve y[i] = alpha + beta * x[i] + gamma * x[i]^2, with i = 1..n, subject to the constraint beta^2 = 4 * alpha * gamma, for alpha and gamma (Least Squares). The input Vandermonde-matrix o[1..n,1..3] has columns with 1, x[i] and x[i]^2, respectively. The algorithm is according to: Jos M.F. Ten Berge (1983), A generalization of Verhelst's solution for a constrained regression problem in ALSCAL and related MDS-algorithms, Psychometrika 48, 631-638. */ void NUMsolveWeaklyConstrainedLinearRegression (double **f, long n, long m, double phi[], double alpha, double delta, double t[]); /* Solve g(t) = ||Ft - phi||^2 + alpha (t't - delta)^2 for t[1..m], where F[1..n][1..m] is a matrix, phi[1..n] a given vector, and alpha and delta are fixed numbers. This class of functions is composed of a linear regression function and a penalty function for the sum of squared regression weights. It is weakly constrained because the penalty function prohibits a relatively large departure of t't from delta. The solution is due to: Jos M.F. ten Berge (1991), A general solution for a class of weakly constrained linear regression problems, Psychometrika 56, 601-609. Preconditions: n >= m alpha >= 0 */ void NUMProcrustes (double **x, double **y, long nPoints, long nDimensions, double **t, double v[], double *s); /* Given two configurations x and y (nPoints x nDimensions), find the the Procrustes rotation/reflection matrix T, the translation vector v and the scaling factor s such that Y = sXT+1v' (1 is the nPoints vector with ones). Solution: see Borg and Groenen (1997), Modern Multidimensional Scaling, pp 340-346. When on input v == NULL or s == NULL, only the matrix T will be solved for: the orthogonal Procrustes transform. */ void NUMnrbis (void (*f)(double x, double *fx, double *dfx, void *closure), double x1, double x2, void *closure, double *root); /* Find the root of a function between x1 and x2. Method: Newton-Raphson with bisection (i.e., derivative is known!). Error condition: root not bracketed. */ double NUMridders (double (*f) (double x, void *closure), double x1, double x2, void *closure); /* Return the root of a function f bracketed in [xlow, xhigh]. Error condition: root not bracketed. */ void NUMmspline (double knot[], long nKnots, long order, long i, double x, double *y); /* Calculates an M-spline for a knot sequence. After Ramsay (1988), Monotone splines in action, Statistical Science 4. M-splines of order k have degree k-1. M-splines are zero outside interval [ knot[i], knot[i+order] ). First and last 'order' knots are equal, i.e., knot[1] = ... = knot[order] && knot[nKnots-order+1] = ... knot[nKnots]. Error condition: no memory. */ void NUMispline (double aknot[], long nKnots, long order, long i, double x, double *y); /* Calculates an I-spline for simple knot sequences: only one knot at each interior boundary. After Ramsay (1988), Monotone splines in action, Statistical Science 4. I-splines of order k have degree k (because they Integrate an M-spline of degree k-1). In the calculation of the integral of M(x|k,t), M-splines are used that have two more knots, i.e., M(x|k+1,t). For reasons of efficiency we demand that these extra knots are given, i.e., the 'aknot[]' argument contains the knot positions as if the spline to be integrated were an M(x|k+1,t) spline. knot[1] = ... = knot[order+1] && knot[nKnots-order] = ... knot[nKnots] Error condition: no memory. */ double NUMwilksLambda (double *lambda, long from, long to); /* Calculate: Product (i=from..to; 1/(1+lambda[i])) Preconditions: to >= from */ double NUMlnBeta (double a, double b); /* Computes the logarithm of the beta function log(B(a,b) subject to a and b not being negative integers. */ double NUMbeta2 (double z, double w);//temporarily double NUMbetaContinuedFraction(double a, double b, double x); double NUMfactln (int n); /* Returns ln (n!) */ /***** STATISTICS: PROBABILITY DENSITY FUNCTIONS ********************/ double NUMlogNormalP (double x, double zeta, double sigma); /* Area under log normal from 0 to x */ double NUMlogNormalQ (double x, double zeta, double sigma); /* Area under log normal from x to +infinity */ double NUMstudentP (double t, double df); /* The area under the student T-distribution from -infinity to t. Precondition: df > 0 */ double NUMstudentQ (double t, double df); /* The area under the student T distribution from t to +infinity. Precondition: df > 0 */ double NUMfisherP (double f, double df1, double df2); /* The area under Fisher's F-distribution from 0 to f Preconditions: f >= 0, df1 > 0, df2 > 0 */ double NUMfisherQ (double f, double df1, double df2); /* The area under Fisher's F-distribution from f to +infinity Preconditions: f >= 0, df1 > 0, df2 > 0 */ double NUMinvGaussQ (double p); /* Solves NUMgaussQ (x) == p for x, given p. Precondition: 0 < p < 1 Method: Abramovitz & Stegun 26.2.23 Precision: |eps(p)| < 4.5 10^-4 */ double NUMinvChiSquareQ (double p, double df); /* Solves NUMchiSquareQ (chiSquare, df) == p for chiSquare, given p, df. Preconditions: 0 < p < 1, df > 0 */ double NUMinvStudentQ (double p, double df); /* Solves NUMstudentQ (t, df) == p for t, given p, df. Preconditions: 0 < p < 1, df > 0 */ double NUMinvFisherQ (double p, double df1, double df2); /* Solves NUMfisherQ (f, df1, df2) == p for f, given p, df1, df2 Precondition: 0 < p < 1 */ double NUMtukeyQ (double q, double cc, double df, double rr); /* Computes the probability that the maximum of rr studentized * ranges, each based on cc means and with df degrees of freedom * for the standard error, is larger than q. */ double NUMinvTukeyQ (double p, double cc, double df, double rr); /* Solves NUMtukeyQ (q, rr, cc, df) == p for q given p, rr, cc and df. * Computes the quantiles of the maximum of rr studentized * ranges, each based on cc means and with df degrees of freedom * for the standard error, is larger than q. * p = probability (alpha) * rr = no. of rows or groups * cc = no. of columns or treatments * df = degrees of freedom of error term */ double NUMnormalityTest_HenzeZirkler (double **data, long n, long p, double *beta, double *tnb, double *lnmu, double *lnvar); /* Multivariate normality test of nxp data matrix according to the method described in Henze & Wagner (1997). The test statistic is returned in tnb, together with the lognormal mean 'lnmu' and the lognormal variance 'lnvar'. */ /****** Frequency in Hz to other frequency reps ****/ double NUMmelToHertz2 (double mel); /* Return 700 * (pow (10.0, mel / 2595.0) - 1) */ double NUMhertzToMel2 (double f); /* Return 2595 * log10 (1 + f/700) */ double NUMmelToHertz3 (double mel); /* Return mel < 1000 ? mel : 1000 * (exp (mel * log10(2) / 1000) - 1) */ double NUMhertzToMel3 (double hz); /* Return hz < 1000 ? hz : 1000 * log10 (1 + hz / 1000) / log10 (2) */ double NUMbarkToHertz2 (double bark); /* Return 650 * sinh (bark / 7) */ double NUMhertzToBark2 (double hz); /* Return 7 * ln (hz / 650 + sqrt(1 + (hz / 650)^2)) */ double NUMhertzToBark_traunmueller (double hz); /* return 26.81 * hz /(1960 + hz) -0.53; */ double NUMbarkToHertz_traunmueller (double bark); /* return 1960* (bark + 0.53) / (26.28 - bark); */ double NUMbarkToHertz_schroeder (double bark); /* return 650.0 * sinh (bark / 7.0); */ double NUMbarkToHertz_zwickerterhardt (double hz); /* return 13 * atan (0.00076 * hz) + 3.5 * atan (hz / 7500); */ double NUMhertzToBark_schroeder (double hz); /* return 7.0 * log (hz / 650 + sqrt (1 + (hz / 650)^2)); */ double NUMbladonlindblomfilter_amplitude (double zc, double z); /* Amplitude of filter at dz (barks) from centre frequency. dz may be positive and negative. The bladonlindblomfilter function is: z' = zc - z + 0.474 10 log10 F(z') = 15.81 + 7.5 z' - 17.5 sqrt( 1 + z'^2 ) Reference: Bladon, R.A.W & Lindblom, B., (1980), "Modeling the judgment of vowel quality differences", JASA 69, 1414-1422. The filter has a bandwidth of 1.43 Bark, the maximum occurs at z = zc, and the slopes are -10 dB/Bark and +25 dB/Bark. */ double NUMsekeyhansonfilter_amplitude (double zc, double z); /* Amplitude of filter at dz (barks) from centre frequency. dz may be positive and negative. The sekeyhansonfilter function is: z' = zc - z - 0.215 10 log10 F(z') = 7 - 7.5 * z' - 17.5 * sqrt( 0.196 + z'^2 ) Reference: Sekey, A. & Hanson, B.A. (1984), "Improved 1-Bark bandwidth auditory filter", JASA 75, 1902-1904. The filter function has a bandwidth of 1 Bark, the maximum response occurs at z=zc, and the slopes are +10 dB/Bark and -25 dB/Bark. It is an improved version of bladonlindblomfilter. */ double NUMtriangularfilter_amplitude (double fl, double fc, double fh, double f); /* Filterfunction that intermediates in Mel frequency cepstral coefficients calculation. The filter function is (f-fl)/(fc-fl) fl < f < fc H(z) = (fh-f)/(fh-fc) fc < f < fh 0 otherwise Preconditions: 0 < fl < fh */ double NUMformantfilter_amplitude (double fc, double bw, double f); /* Filterfunction with a formant-like shape on a linear freq. scale. H(f) = 1.0 / (dq * dq + 1.0), where dq = (fc * fc - f * f) / (bw * f) Preconditions: f > 0 && bw > 0 */ int NUMburg (double x[], long n, double a[], int m, double *xms); /* Calculates linear prediction coefficients according to the algorithm from J.P. Burg as described by N.Anderson in Childers, D. (ed), Modern Spectrum Analysis, IEEE Press, 1978, 252-255. */ void NUMdmatrix_to_dBs (double **m, long rb, long re, long cb, long ce, double ref, double factor, double floor); /* Transforms the values in the matrix m[rb..re][cb..ce] to dB's m[i][j] = factor * 10 * log10 (m[i][j] / ref) if (m[i][j] < floor) m[i][j] = floor; Preconditions: rb <= re cb <= ce ref > 0 factor > 0 Errors: Matrix elements < 0; */ double **NUMcosinesTable (long first, long last, long npoints); /* Generate table with cosines. result[i][j] = cos (i * pi * (j - 1/2) / npoints) i=first..last; j=1..npoints Preconditions: 1 <= first <= last npoints > 1 */ /****** Interpolation ****/ void NUMspline (double x[], double y[], long n, double yp1, double ypn, double y2[]); /* Given arrays a[1..n] and y[1..n] containing a tabulated function, i.e., y[i] = f(x[i]), with x[1] < x[2] < ... < x[n], and given values yp1 and ypn for the first derivative of the interpolating function at point 1 and n, respectively, this routine returns an array y2[1..n] that contains the second derivative of the interpolating function at the tabulated point x. If yp1 and/or ypn are greaterequal 10^30, the routine is signaled to set the corresponding boundary condition for a natuarl spline, with zero second derivative on that boundary. */ void NUMsplint (double xa[], double ya[], double y2a[], long n, double x, double *y); /* Given arrays xa[1..n] and ya[1..n] containing a tabulated function, i.e., y[i] = f(x[i]), with x[1] < x[2] < ... < x[n], and given the array y2a[1..n] which is the output of NUMspline above, and given a value of x, this routine returns an interpolated value y. */ double NUMsincpi (const double x); /* Calculates sin(pi*x)/(pi*x) */ double NUMsinc (const double x); /* Calculates sin(x)/(x) */ /*********************** Geometry *************************************/ int NUMgetOrientationOfPoints (double x1, double y1, double x2, double y2, double x3, double y3); /* Traverse points 1, 2 and 3. If we travel counter-clockwise the result will be 1, if we travel clockwise the result will be -1 and the result will be 0 if 3 is on the line segment between 1 and 2. */ int NUMdoLineSegmentsIntersect (double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4); /* Does the line segment from (x1,y1) to (x2,y2) intersect with the line segment from (x3,y3) to (x4,y4)? */ int NUMgetIntersectionsWithRectangle (double x1, double y1, double x2, double y2, double xmin, double ymin, double xmax, double ymax, double *xi, double *yi); /* Get the intersection points of the line through the points (x1,y1) and (x2,y2) with the rectangle with corners (xmin, ymin) and (xmax,ymax). The returned value is the number of intersections found and is either 0 or 1 or 2. */ bool NUMclipLineWithinRectangle (double xl1, double yl1, double xl2, double yl2, double xr1, double yr1, double xr2, double yr2, double *xo1, double *yo1, double *xo2, double *yo2); /* If true, then returns in (xo1, yo1) and (xo2, yo2) the coordinates of that piece of the line (xl1, yl1)..(xl2, yl2) that can be drawn within the rectangle with lowerleft corner (xr1, yr1) and upperright (xr2, yr2). Returns false if there is nothing to be drawn inside. */ void NUMgetEllipseBoundingBox (double a, double b, double cospsi, double *width, double *height); /* Get the width and the height of the bonding box around an ellipse. a and b are the lengths of the long axes. cospsi is the cosine of the angle between the a-axis and the horizontal x-axis (cs == 0 when a-axis and x-axis are perpendicular). Parametrisation of the ellipse: x(phi) = a cos(psi) cos(phi) - b sin (psi) sin(phi) y(phi) = a sin(psi) cos(phi) + b cos(psi) sin(phi) 0 <= phi <= 2 pi Extrema: d x(phi) / dphi == 0 and d y(phi) / dphi == 0 Solution: x(phi1) = a cos(psi) cos(phi1) - b sin (psi) sin(phi1) y(phi2) = a sin(psi) cos(phi2) + b cos(psi) sin(phi2), where phi1 = arctg ( -b/a tg(psi)) phi2 = arctg ( b/a cotg(psi)) Special cases are psi = 0 and pi /2 */ double NUMminimize_brent (double (*f) (double x, void *closure), double a, double b, void *closure, double tol, double *fx); /* The function returns an estimate for the minimum location with accuracy 3 * SQRT_EPSILON * abs(x) + tol. The function always obtains a local minimum which coincides with the global one only if a function under investigation being unimodular. If a function being examined possesses no local minimum within the given range, the function returns 'a' (if f(a) < f(b)), otherwise it returns the right range boundary value b. Algorithm The function makes use of the golden section procedure combined with parabolic interpolation. At every step, the program operates at three abscissae - x, v, and w. x - the last and the best approximation to the minimum location, i.e. f(x) <= f(a) or/and f(x) <= f(b) (if the function f has a local minimum in (a,b), then both conditions are fulfiled after one or two steps). v, w are previous approximations to the minimum location. They may coincide with a, b, or x (although the algorithm tries to make all u, v, and w distinct). Points x, v, and w are used to construct interpolating parabola whose minimum will be treated as a new approximation to the minimum location if the former falls within [a,b] and reduces the range enveloping minimum more efficient than the golden section procedure. When f(x) has a second derivative positive at the minimum location (not coinciding with a or b) the procedure converges superlinearly at a rate order about 1.324 */ /********************** fft ******************************************/ struct structNUMfft_Table_f { long n; /* Data length */ float *trigcache; long *splitcache; }; struct structNUMfft_Table { long n; double *trigcache; long *splitcache; }; typedef struct structNUMfft_Table_f *NUMfft_Table_f; typedef struct structNUMfft_Table *NUMfft_Table; void NUMfft_Table_init_f (NUMfft_Table_f table, long n); void NUMfft_Table_init (NUMfft_Table table, long n); /* n : data size */ struct autoNUMfft_Table : public structNUMfft_Table { autoNUMfft_Table () throw () { n = 0; trigcache = 0; splitcache = 0; } ~autoNUMfft_Table () { NUMvector_free (trigcache, 0); NUMvector_free (splitcache, 0); } }; void NUMfft_forward_f (NUMfft_Table_f table, float *data); void NUMfft_forward (NUMfft_Table table, double *data); /* Function: Calculates the Fourier Transform of a set of n real-valued data points. Replaces this data in array data [1...n] by the positive frequency half of its complex Fourier Transform, with a minus sign in the exponent. Preconditions: data != NULL; table must have been initialised with NUMfft_Table_init_f/d Postconditions: data[1] contains real valued first component (Direct Current) data[2..n-1] even index : real part; odd index: imaginary part of DFT. data[n] contains real valued last component (Nyquist frequency) Output parameters: data r(1) = the sum from i=1 to i=n of r(i) If l =(int) (n+1)/2 then for k = 2,...,l r(2*k-2) = the sum from i = 1 to i = n of r(i)*cos((k-1)*(i-1)*2*pi/n) r(2*k-1) = the sum from i = 1 to i = n of -r(i)*sin((k-1)*(i-1)*2*pi/n) if n is even r(n) = the sum from i = 1 to i = n of (-1)**(i-1)*r(i) i.e., the ordering of the output array will be for n even r(1),(r(2),i(2)),(r(3),i(3)),...,(r(l-1),i(l-1)),r(l). Or ...., (r(l),i(l)) for n uneven. ***** note this transform is unnormalized since a call of NUMfft_forward followed by a call of NUMfft_backward will multiply the input sequence by n. */ void NUMfft_backward_f (NUMfft_Table_f table, float *data); void NUMfft_backward (NUMfft_Table table, double *data); /* Function: Calculates the inverse transform of a complex array if it is the transform of real data. (Result in this case must be multiplied by 1/n.) Preconditions: n is an integer power of 2. data != NULL; data [1] contains real valued first component (Direct Current) data [2..n-1] even index : real part; odd index: imaginary part of DFT. data [n] contains real valued last component (Nyquist frequency) table must have been initialised with NUMfft_Table_init_f/d Output parameters data for n even and for i = 1,...,n r(i) = r(1)+(-1)**(i-1)*r(n) plus the sum from k=2 to k=n/2 of 2.*r(2*k-2)*cos((k-1)*(i-1)*2*pi/n) -2.*r(2*k-1)*sin((k-1)*(i-1)*2*pi/n) for n odd and for i = 1,...,n r(i) = r(1) plus the sum from k=2 to k=(n+1)/2 of 2.*r(2*k-2)*cos((k-1)*(i-1)*2*pi/n) -2.*r(2*k-1)*sin((k-1)*(i-1)*2*pi/n) ***** note this transform is unnormalized since a call of NUMfft_forward followed by a call of NUMfft_backward will multiply the input sequence by n. */ /**** Compatibility with NR fft's */ void NUMforwardRealFastFourierTransform_f (float *data, long n); void NUMforwardRealFastFourierTransform (double *data, long n); /* Function: Calculates the Fourier Transform of a set of n real-valued data points. Replaces this data in array data [1...n] by the positive frequency half of its complex Fourier Transform, with a minus sign in the exponent. Preconditions: n is an integer power of 2. data != NULL; Postconditions: data [1] contains real valued first component (Direct Current) data [2] contains real valued last component (Nyquist frequency) data [3..n] odd index : real part; even index: imaginary part of DFT. */ void NUMreverseRealFastFourierTransform_f (float *data, long n); void NUMreverseRealFastFourierTransform (double *data, long n); /* Function: Calculates the inverse transform of a complex array if it is the transform of real data. (Result in this case must be multiplied by 1/n.) Preconditions: n is an integer power of 2. data != NULL; data [1] contains real valued first component (Direct Current) data [2] contains real valued last component (Nyquist frequency) data [3..n] odd index : real part; even index: imaginary part of DFT. */ void NUMrealft_f (float *data, long n, int direction); /* Please stop using. */ void NUMrealft (double *data, long n, int direction); long NUMgetIndexFromProbability (double *probs, long nprobs, double p); // Fit the line y= ax+b void NUMlineFit (double *x, double *y, long numberOfPoints, double *m, double *intercept, int method); /* method * 1 least squares * 2 rubust incomplete Theil O(N/2) * 3 robust complete Theil (very slow for large N, O(N^2)) */ void NUMlineFit_theil (double *x, double *y, long numberOfPoints, double *m, double *intercept, bool incompleteMethod); /* * Preconditions: * all x[i] must be different, i.e. x[i] != x[j] for all i = 1..(numberOfPoints - 1), j = (i+1) ..numberOfPoints * Algorithm: * Theils robust line fit method: * 1. Use all combination of pairs (x[i],y[i]), (x[j],y[j]) to calculate an intercept m[k] as * m[k] = (y[j] - y[i]) / (x[j] - x[i]). * There will be (numberOfPoints - 1) * numberOfPoints / 2 numbers m[k]. * 2. Take the median value m of all the m[k]. * 3. Calculate the numberOfPoints intercepts b[i] as b[i] = y[i] - m * x[i] * 4. Take the median value b of all the b[i] values * * If incompleteMethod we use Theil's incomplete method to reduce the number of combinations. * I.e. split the data in two equal parts at n2 = numberOfPoints / 2 and then calculate the numberOfPoints/2 intercepts m[i] as * m[i] = (y[n2+i] - y[i]) / (x[n2 + i] - x[i]). * The rest proceeds as outlined above */ void NUMlineFit_LS (double *x, double *y, long numberOfPoints, double *m, double *intercept); /* The binomial distribution has the form, f(x) = n!/(x!(n-x)!) * p^x (1-p)^(n-x) for integer 0 <= x <= n = 0 otherwise This implementation follows the public domain ranlib function "ignbin", the bulk of which is the BTPE (Binomial Triangle Parallelogram Exponential) algorithm introduced in Kachitvichyanukul and Schmeiser[1]. It has been translated to use modern C coding standards. If n is small and/or p is near 0 or near 1 (specifically, if n*min(p,1-p) < SMALL_MEAN), then a different algorithm, called BINV, is used which has an average runtime that scales linearly with n*min(p,1-p). But for larger problems, the BTPE algorithm takes the form of two functions b(x) and t(x) -- "bottom" and "top" -- for which b(x) < f(x)/f(M) < t(x), with M = floor(n*p+p). b(x) defines a triangular region, and t(x) includes a parallelogram and two tails. Details (including a nice drawing) are in the paper. [1] Kachitvichyanukul, V. and Schmeiser, B. W. Binomial Random Variate Generation. Communications of the ACM, 31, 2 (February, 1988) 216. Note, Bruce Schmeiser (personal communication) points out that if you want very fast binomial deviates, and you are happy with approximate results, and/or n and n*p are both large, then you can just use gaussian estimates: mean=n*p, variance=n*p*(1-p). This implementation by James Theiler, April 2003, after obtaining permission -- and some good advice -- from Drs. Kachitvichyanukul and Schmeiser to use their code as a starting point, and then doing a little bit of tweaking. Additional polishing for GSL coding standards by Brian Gough. */ long NUMrandomBinomial (double p, long n); // IEEE: Programs for digital signal processing section 4.3 LPTRN (modfied) // lpc[1..n] to rc[1..n] void NUMlpc_lpc_to_rc (double *lpc, long p, double *rc); // rc[1..n] to area[1..n+1], area[m+1] = 0.0001; (1 cm^2) void NUMlpc_rc_to_area (double *rc, long n, double *area); // area[1..n] to rc[1..n-1] (modification: LPTRN assumes area[n+1]) void NUMlpc_area_to_rc (double *area, long n, double *rc); // area[1..n] to lpc[1..n-1]! (modification: lptrn gives lpc[1] = 1 we don't) void NUMlpc_area_to_lpc (double *area, long n, double *lpc); // lpc[1..n] to area[1..n+1], area[m+1] = 0.0001; (1 cm^2) void NUMlpc_lpc_to_area (double *lpc, long m, double *area); #endif // _NUM2_h_ praat-6.0.04/dwsys/NUMcblas.cpp000066400000000000000000002057441261542461700162550ustar00rootroot00000000000000/* NUMcblas.c -- LAPACK helper routines -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University October 31, 1999 -- translated by f2c (version 19990503) Adapted by David Weenink 20021201 */ /* djmw 20020813 GPL header djmw 20071201 Latest modification pb 20100120 dlamc3_: declare volatile double ret_val to prevent optimization! */ /* #include "blaswrap.h" */ #include "melder.h" #include "NUMcblas.h" #include "NUMf2c.h" #include "NUM2.h" #define MAX(m,n) ((m) > (n) ? (m) : (n)) #define MIN(m,n) ((m) < (n) ? (m) : (n)) static int dlamc1_ (long *beta, long *t, long *rnd, long *ieee1); static int dlamc2_ (long *beta, long *t, long *rnd, double *eps, long *emin, double *rmin, long *emax, double *rmax); static double dlamc3_ (double *, double *); static int dlamc4_ (long *emin, double *start, long *base); static int dlamc5_ (long *beta, long *p, long *emin, long *ieee, long *emax, double *rmax); int NUMblas_daxpy (long *n, double *da, double *dx, long *incx, double *dy, long *incy) { /* System generated locals */ long i__1; /* Local variables */ static long i__, m, ix, iy, mp1; --dy; --dx; /* Function Body */ if (*n <= 0) { return 0; } if (*da == 0.) { return 0; } if (*incx == 1 && *incy == 1) { goto L20; } /* code for unequal increments or equal increments not equal to 1 */ ix = 1; iy = 1; if (*incx < 0) { ix = (- (*n) + 1) * *incx + 1; } if (*incy < 0) { iy = (- (*n) + 1) * *incy + 1; } i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { dy[iy] += *da * dx[ix]; ix += *incx; iy += *incy; /* L10: */ } return 0; /* code for both increments equal to 1 clean-up loop */ L20: m = *n % 4; if (m == 0) { goto L40; } i__1 = m; for (i__ = 1; i__ <= i__1; ++i__) { dy[i__] += *da * dx[i__]; /* L30: */ } if (*n < 4) { return 0; } L40: mp1 = m + 1; i__1 = *n; for (i__ = mp1; i__ <= i__1; i__ += 4) { dy[i__] += *da * dx[i__]; dy[i__ + 1] += *da * dx[i__ + 1]; dy[i__ + 2] += *da * dx[i__ + 2]; dy[i__ + 3] += *da * dx[i__ + 3]; /* L50: */ } return 0; } /* NUMblas_daxpy */ int NUMblas_dcopy (long *n, double *dx, long *incx, double *dy, long *incy) { /* System generated locals */ long i__1; /* Local variables */ static long i__, m, ix, iy, mp1; --dy; --dx; /* Function Body */ if (*n <= 0) { return 0; } if (*incx == 1 && *incy == 1) { goto L20; } /* code for unequal increments or equal increments not equal to 1 */ ix = 1; iy = 1; if (*incx < 0) { ix = (- (*n) + 1) * *incx + 1; } if (*incy < 0) { iy = (- (*n) + 1) * *incy + 1; } i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { dy[iy] = dx[ix]; ix += *incx; iy += *incy; /* L10: */ } return 0; /* code for both increments equal to 1 clean-up loop */ L20: m = *n % 7; if (m == 0) { goto L40; } i__1 = m; for (i__ = 1; i__ <= i__1; ++i__) { dy[i__] = dx[i__]; /* L30: */ } if (*n < 7) { return 0; } L40: mp1 = m + 1; i__1 = *n; for (i__ = mp1; i__ <= i__1; i__ += 7) { dy[i__] = dx[i__]; dy[i__ + 1] = dx[i__ + 1]; dy[i__ + 2] = dx[i__ + 2]; dy[i__ + 3] = dx[i__ + 3]; dy[i__ + 4] = dx[i__ + 4]; dy[i__ + 5] = dx[i__ + 5]; dy[i__ + 6] = dx[i__ + 6]; /* L50: */ } return 0; } /* NUMblas_dcopy */ double NUMblas_ddot (long *n, double *dx, long *incx, double *dy, long *incy) { /* System generated locals */ long i__1; double ret_val; /* Local variables */ static long i__, m; static double dtemp; static long ix, iy, mp1; /* Parameter adjustments */ --dy; --dx; /* Function Body */ ret_val = 0.; dtemp = 0.; if (*n <= 0) { return ret_val; } if (*incx == 1 && *incy == 1) { goto L20; } /* code for unequal increments or equal increments not equal to 1 */ ix = 1; iy = 1; if (*incx < 0) { ix = (- (*n) + 1) * *incx + 1; } if (*incy < 0) { iy = (- (*n) + 1) * *incy + 1; } i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { dtemp += dx[ix] * dy[iy]; ix += *incx; iy += *incy; /* L10: */ } ret_val = dtemp; return ret_val; /* code for both increments equal to 1 clean-up loop */ L20: m = *n % 5; if (m == 0) { goto L40; } i__1 = m; for (i__ = 1; i__ <= i__1; ++i__) { dtemp += dx[i__] * dy[i__]; /* L30: */ } if (*n < 5) { goto L60; } L40: mp1 = m + 1; i__1 = *n; for (i__ = mp1; i__ <= i__1; i__ += 5) { dtemp = dtemp + dx[i__] * dy[i__] + dx[i__ + 1] * dy[i__ + 1] + dx[i__ + 2] * dy[i__ + 2] + dx[i__ + 3] * dy[i__ + 3] + dx[i__ + 4] * dy[i__ + 4]; /* L50: */ } L60: ret_val = dtemp; return ret_val; } /* NUMblas_ddot */ int NUMblas_dgemm (const char *transa, const char *transb, long *m, long *n, long *k, double *alpha, double *a, long *lda, double *b, long *ldb, double *beta, double *c__, long *ldc) { /* System generated locals */ long a_dim1, a_offset, b_dim1, b_offset, c_dim1, c_offset, i__1, i__2, i__3; /* Local variables */ static long info; static long nota, notb; static double temp; static long i__, j, l, ncola; static long nrowa, nrowb; #define a_ref(a_1,a_2) a[(a_2)*a_dim1 + a_1] #define b_ref(a_1,a_2) b[(a_2)*b_dim1 + a_1] #define c___ref(a_1,a_2) c__[(a_2)*c_dim1 + a_1] /* Set NOTA and NOTB as true if A and B respectively are not transposed and set NROWA, NCOLA and NROWB as the number of rows and columns of A and the number of rows of B respectively. Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; b_dim1 = *ldb; b_offset = 1 + b_dim1 * 1; b -= b_offset; c_dim1 = *ldc; c_offset = 1 + c_dim1 * 1; c__ -= c_offset; /* Function Body */ nota = lsame_ (transa, "N"); notb = lsame_ (transb, "N"); if (nota) { nrowa = *m; ncola = *k; } else { nrowa = *k; ncola = *m; } if (notb) { nrowb = *k; } else { nrowb = *n; } /* Test the input parameters. */ info = 0; if (!nota && !lsame_ (transa, "C") && !lsame_ (transa, "T")) { info = 1; } else if (!notb && !lsame_ (transb, "C") && !lsame_ (transb, "T")) { info = 2; } else if (*m < 0) { info = 3; } else if (*n < 0) { info = 4; } else if (*k < 0) { info = 5; } else if (*lda < MAX (1, nrowa)) { info = 8; } else if (*ldb < MAX (1, nrowb)) { info = 10; } else if (*ldc < MAX (1, *m)) { info = 13; } if (info != 0) { xerbla_ ("DGEMM ", &info); return 0; } /* Quick return if possible. */ if (*m == 0 || *n == 0 || ((*alpha == 0. || *k == 0) && *beta == 1.)) { return 0; } /* And if alpha.eq.zero. */ if (*alpha == 0.) { if (*beta == 0.) { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { c___ref (i__, j) = 0.; /* L10: */ } /* L20: */ } } else { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { c___ref (i__, j) = *beta * c___ref (i__, j); /* L30: */ } /* L40: */ } } return 0; } /* Start the operations. */ if (notb) { if (nota) { /* Form C := alpha*A*B + beta*C. */ i__1 = *n; for (j = 1; j <= i__1; ++j) { if (*beta == 0.) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { c___ref (i__, j) = 0.; /* L50: */ } } else if (*beta != 1.) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { c___ref (i__, j) = *beta * c___ref (i__, j); /* L60: */ } } i__2 = *k; for (l = 1; l <= i__2; ++l) { if (b_ref (l, j) != 0.) { temp = *alpha * b_ref (l, j); i__3 = *m; for (i__ = 1; i__ <= i__3; ++i__) { c___ref (i__, j) = c___ref (i__, j) + temp * a_ref (i__, l); /* L70: */ } } /* L80: */ } /* L90: */ } } else { /* Form C := alpha*A'*B + beta*C */ i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { temp = 0.; i__3 = *k; for (l = 1; l <= i__3; ++l) { temp += a_ref (l, i__) * b_ref (l, j); /* L100: */ } if (*beta == 0.) { c___ref (i__, j) = *alpha * temp; } else { c___ref (i__, j) = *alpha * temp + *beta * c___ref (i__, j); } /* L110: */ } /* L120: */ } } } else { if (nota) { /* Form C := alpha*A*B' + beta*C */ i__1 = *n; for (j = 1; j <= i__1; ++j) { if (*beta == 0.) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { c___ref (i__, j) = 0.; /* L130: */ } } else if (*beta != 1.) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { c___ref (i__, j) = *beta * c___ref (i__, j); /* L140: */ } } i__2 = *k; for (l = 1; l <= i__2; ++l) { if (b_ref (j, l) != 0.) { temp = *alpha * b_ref (j, l); i__3 = *m; for (i__ = 1; i__ <= i__3; ++i__) { c___ref (i__, j) = c___ref (i__, j) + temp * a_ref (i__, l); /* L150: */ } } /* L160: */ } /* L170: */ } } else { /* Form C := alpha*A'*B' + beta*C */ i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { temp = 0.; i__3 = *k; for (l = 1; l <= i__3; ++l) { temp += a_ref (l, i__) * b_ref (j, l); /* L180: */ } if (*beta == 0.) { c___ref (i__, j) = *alpha * temp; } else { c___ref (i__, j) = *alpha * temp + *beta * c___ref (i__, j); } /* L190: */ } /* L200: */ } } } return 0; /* End of DGEMM . */ } /* NUMblas_dgemm */ #undef c___ref #undef b_ref #undef a_ref int NUMblas_dger (long *m, long *n, double *alpha, double *x, long *incx, double *y, long *incy, double *a, long *lda) { /* System generated locals */ long a_dim1, a_offset, i__1, i__2; /* Local variables */ static long info; static double temp; static long i__, j, ix, jy, kx; #define a_ref(a_1,a_2) a[(a_2)*a_dim1 + a_1] /* Test the input parameters. Parameter adjustments */ --x; --y; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; /* Function Body */ info = 0; if (*m < 0) { info = 1; } else if (*n < 0) { info = 2; } else if (*incx == 0) { info = 5; } else if (*incy == 0) { info = 7; } else if (*lda < MAX (1, *m)) { info = 9; } if (info != 0) { xerbla_ ("DGER ", &info); return 0; } /* Quick return if possible. */ if (*m == 0 || *n == 0 || *alpha == 0.) { return 0; } /* Start the operations. In this version the elements of A are accessed sequentially with one pass through A. */ if (*incy > 0) { jy = 1; } else { jy = 1 - (*n - 1) * *incy; } if (*incx == 1) { i__1 = *n; for (j = 1; j <= i__1; ++j) { if (y[jy] != 0.) { temp = *alpha * y[jy]; i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { a_ref (i__, j) = a_ref (i__, j) + x[i__] * temp; /* L10: */ } } jy += *incy; /* L20: */ } } else { if (*incx > 0) { kx = 1; } else { kx = 1 - (*m - 1) * *incx; } i__1 = *n; for (j = 1; j <= i__1; ++j) { if (y[jy] != 0.) { temp = *alpha * y[jy]; ix = kx; i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { a_ref (i__, j) = a_ref (i__, j) + x[ix] * temp; ix += *incx; /* L30: */ } } jy += *incy; /* L40: */ } } return 0; } /* NUMblas_dger */ #undef a_ref int NUMblas_dgemv (const char *trans, long *m, long *n, double *alpha, double *a, long *lda, double *x, long *incx, double *beta, double *y, long *incy) { /* System generated locals */ long a_dim1, a_offset, i__1, i__2; /* Local variables */ static long info; static double temp; static long lenx, leny, i__, j; static long ix, iy, jx, jy, kx, ky; #define a_ref(a_1,a_2) a[(a_2)*a_dim1 + a_1] /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --x; --y; /* Function Body */ info = 0; if (!lsame_ (trans, "N") && !lsame_ (trans, "T") && !lsame_ (trans, "C")) { info = 1; } else if (*m < 0) { info = 2; } else if (*n < 0) { info = 3; } else if (*lda < MAX (1, *m)) { info = 6; } else if (*incx == 0) { info = 8; } else if (*incy == 0) { info = 11; } if (info != 0) { xerbla_ ("DGEMV ", &info); return 0; } /* Quick return if possible. */ if (*m == 0 || *n == 0 || (*alpha == 0. && *beta == 1.)) { return 0; } /* Set LENX and LENY, the lengths of the vectors x and y, and set up the start points in X and Y. */ if (lsame_ (trans, "N")) { lenx = *n; leny = *m; } else { lenx = *m; leny = *n; } if (*incx > 0) { kx = 1; } else { kx = 1 - (lenx - 1) * *incx; } if (*incy > 0) { ky = 1; } else { ky = 1 - (leny - 1) * *incy; } /* Start the operations. In this version the elements of A are accessed sequentially with one pass through A. First form y := beta*y. */ if (*beta != 1.) { if (*incy == 1) { if (*beta == 0.) { i__1 = leny; for (i__ = 1; i__ <= i__1; ++i__) { y[i__] = 0.; /* L10: */ } } else { i__1 = leny; for (i__ = 1; i__ <= i__1; ++i__) { y[i__] = *beta * y[i__]; /* L20: */ } } } else { iy = ky; if (*beta == 0.) { i__1 = leny; for (i__ = 1; i__ <= i__1; ++i__) { y[iy] = 0.; iy += *incy; /* L30: */ } } else { i__1 = leny; for (i__ = 1; i__ <= i__1; ++i__) { y[iy] = *beta * y[iy]; iy += *incy; /* L40: */ } } } } if (*alpha == 0.) { return 0; } if (lsame_ (trans, "N")) { /* Form y := alpha*A*x + y. */ jx = kx; if (*incy == 1) { i__1 = *n; for (j = 1; j <= i__1; ++j) { if (x[jx] != 0.) { temp = *alpha * x[jx]; i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { y[i__] += temp * a_ref (i__, j); /* L50: */ } } jx += *incx; /* L60: */ } } else { i__1 = *n; for (j = 1; j <= i__1; ++j) { if (x[jx] != 0.) { temp = *alpha * x[jx]; iy = ky; i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { y[iy] += temp * a_ref (i__, j); iy += *incy; /* L70: */ } } jx += *incx; /* L80: */ } } } else { /* Form y := alpha*A'*x + y. */ jy = ky; if (*incx == 1) { i__1 = *n; for (j = 1; j <= i__1; ++j) { temp = 0.; i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { temp += a_ref (i__, j) * x[i__]; /* L90: */ } y[jy] += *alpha * temp; jy += *incy; /* L100: */ } } else { i__1 = *n; for (j = 1; j <= i__1; ++j) { temp = 0.; ix = kx; i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { temp += a_ref (i__, j) * x[ix]; ix += *incx; /* L110: */ } y[jy] += *alpha * temp; jy += *incy; /* L120: */ } } } return 0; } /* NUMblas_dgemv */ #undef a_ref double NUMblas_dlamch (const char *cmach) { /* Initialized data */ static long first = TRUE; /* System generated locals */ long i__1; double ret_val; /* Builtin functions */ /* Local variables */ static double base; static long beta; static double emin, prec, emax; static long imin, imax; static long lrnd; static double rmin, rmax, t, rmach; static double smal, sfmin; static long it; static double rnd, eps; if (first) { first = FALSE; dlamc2_ (&beta, &it, &lrnd, &eps, &imin, &rmin, &imax, &rmax); base = (double) beta; t = (double) it; if (lrnd) { rnd = 1.; i__1 = 1 - it; eps = pow_di (&base, &i__1) / 2; } else { rnd = 0.; i__1 = 1 - it; eps = pow_di (&base, &i__1); } prec = eps * base; emin = (double) imin; emax = (double) imax; sfmin = rmin; smal = 1. / rmax; if (smal >= sfmin) { /* Use smal plus a bit, to avoid the possibility of rounding causing overflow when computing 1/sfmin. */ sfmin = smal * (eps + 1.); } } if (lsame_ (cmach, "E")) { rmach = eps; } else if (lsame_ (cmach, "S")) { rmach = sfmin; } else if (lsame_ (cmach, "B")) { rmach = base; } else if (lsame_ (cmach, "P")) { rmach = prec; } else if (lsame_ (cmach, "N")) { rmach = t; } else if (lsame_ (cmach, "R")) { rmach = rnd; } else if (lsame_ (cmach, "M")) { rmach = emin; } else if (lsame_ (cmach, "U")) { rmach = rmin; } else if (lsame_ (cmach, "L")) { rmach = emax; } else if (lsame_ (cmach, "O")) { rmach = rmax; } ret_val = rmach; return ret_val; } /* NUMblas_dlamch */ static int dlamc1_ (long *beta, long *t, long *rnd, long *ieee1) { /* -- LAPACK auxiliary routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University October 31, 1992 Purpose ======= DLAMC1 determines the machine parameters given by BETA, T, RND, and IEEE1. Arguments ========= BETA (output) INTEGER The base of the machine. T (output) INTEGER The number of ( BETA ) digits in the mantissa. RND (output) LOGICAL Specifies whether proper rounding ( RND = .TRUE. ) or chopping ( RND = .FALSE. ) occurs in addition. This may not be a reliable guide to the way in which the machine performs its arithmetic. IEEE1 (output) LOGICAL Specifies whether rounding appears to be done in the IEEE 'round to nearest' style. Further Details =============== The routine is based on the routine ENVRON by Malcolm and incorporates suggestions by Gentleman and Marovich. See Malcolm M. A. (1972) Algorithms to reveal properties of floating-point arithmetic. Comms. of the ACM, 15, 949-951. Gentleman W. M. and Marovich S. B. (1974) More on algorithms that reveal properties of floating point arithmetic units. Comms. of the ACM, 17, 276-277. ===================================================================== */ /* Initialized data */ static long first = TRUE; /* System generated locals */ double d__1, d__2; /* Local variables */ static long lrnd; static double a, b, c, f; static long lbeta; static double savec; static long lieee1; static double t1, t2; static long lt; static double one, qtr; if (first) { first = FALSE; one = 1.; /* LBETA, LIEEE1, LT and LRND are the local values of BETA, IEEE1, T and RND. Throughout this routine we use the function DLAMC3 to ensure that relevant values are stored and not held in registers, or are not affected by optimizers. Compute a = 2.0**m with the smallest positive integer m such that fl( a + 1.0 ) = a. */ a = 1.; c = 1.; /* + WHILE( C.EQ.ONE )LOOP */ L10: if (c == one) { a *= 2; c = dlamc3_ (&a, &one); d__1 = -a; c = dlamc3_ (&c, &d__1); goto L10; } /* + END WHILE Now compute b = 2.0**m with the smallest positive integer m such that fl( a + b ) .gt. a. */ b = 1.; c = dlamc3_ (&a, &b); /* + WHILE( C.EQ.A )LOOP */ L20: if (c == a) { b *= 2; c = dlamc3_ (&a, &b); goto L20; } /* + END WHILE Now compute the base. a and c are neighbouring floating point numbers in the interval ( beta**t, beta**( t + 1 ) ) and so their difference is beta. Adding 0.25 to c is to ensure that it is truncated to beta and not ( beta - 1 ). */ qtr = one / 4; savec = c; d__1 = -a; c = dlamc3_ (&c, &d__1); lbeta = (long) (c + qtr); /* Now determine whether rounding or chopping occurs, by adding a bit less than beta/2 and a bit more than beta/2 to a. */ b = (double) lbeta; d__1 = b / 2; d__2 = -b / 100; f = dlamc3_ (&d__1, &d__2); c = dlamc3_ (&f, &a); if (c == a) { lrnd = TRUE; } else { lrnd = FALSE; } d__1 = b / 2; d__2 = b / 100; f = dlamc3_ (&d__1, &d__2); c = dlamc3_ (&f, &a); if (lrnd && c == a) { lrnd = FALSE; } /* Try and decide whether rounding is done in the IEEE 'round to nearest' style. B/2 is half a unit in the last place of the two numbers A and SAVEC. Furthermore, A is even, i.e. has last bit zero, and SAVEC is odd. Thus adding B/2 to A should not change A, but adding B/2 to SAVEC should change SAVEC. */ d__1 = b / 2; t1 = dlamc3_ (&d__1, &a); d__1 = b / 2; t2 = dlamc3_ (&d__1, &savec); lieee1 = t1 == a && t2 > savec && lrnd; /* Now find the mantissa, t. It should be the integer part of log to the base beta of a, however it is safer to determine t by powering. So we find t as the smallest positive integer for which fl( beta**t + 1.0 ) = 1.0. */ lt = 0; a = 1.; c = 1.; /* + WHILE( C.EQ.ONE )LOOP */ L30: if (c == one) { ++lt; a *= lbeta; c = dlamc3_ (&a, &one); d__1 = -a; c = dlamc3_ (&c, &d__1); goto L30; } /* + END WHILE */ } *beta = lbeta; *t = lt; *rnd = lrnd; *ieee1 = lieee1; return 0; } /* dlamc1_ */ static int dlamc2_ (long *beta, long *t, long *rnd, double *eps, long *emin, double *rmin, long *emax, double *rmax) { /* -- LAPACK auxiliary routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University October 31, 1992 Purpose ======= DLAMC2 determines the machine parameters specified in its argument list. Arguments ========= BETA (output) INTEGER The base of the machine. T (output) INTEGER The number of ( BETA ) digits in the mantissa. RND (output) LOGICAL Specifies whether proper rounding ( RND = .TRUE. ) or chopping ( RND = .FALSE. ) occurs in addition. This may not be a reliable guide to the way in which the machine performs its arithmetic. EPS (output) DOUBLE PRECISION The smallest positive number such that fl( 1.0 - EPS ) .LT. 1.0, where fl denotes the computed value. EMIN (output) INTEGER The minimum exponent before (gradual) underflow occurs. RMIN (output) DOUBLE PRECISION The smallest normalized number for the machine, given by BASE**( EMIN - 1 ), where BASE is the floating point value of BETA. EMAX (output) INTEGER The maximum exponent before overflow occurs. RMAX (output) DOUBLE PRECISION The largest positive number for the machine, given by BASE**EMAX * ( 1 - EPS ), where BASE is the floating point value of BETA. Further Details =============== The computation of EPS is based on a routine PARANOIA by W. Kahan of the University of California at Berkeley. ===================================================================== */ /* Table of constant values */ /* Initialized data */ static long first = TRUE; static long iwarn = FALSE; /* System generated locals */ long i__1; double d__1, d__2, d__3, d__4, d__5; /* Builtin functions */ /* Local variables */ static long ieee; static double half; static long lrnd; static double leps, zero, a, b, c; static long i, lbeta; static double rbase; static long lemin, lemax, gnmin; static double smal; static long gpmin; static double third, lrmin, lrmax, sixth; static long lieee1; static long lt, ngnmin, ngpmin; static double one, two; if (first) { first = FALSE; zero = 0.; one = 1.; two = 2.; /* LBETA, LT, LRND, LEPS, LEMIN and LRMIN are the local values of BETA, T, RND, EPS, EMIN and RMIN. Throughout this routine we use the function DLAMC3 to ensure that relevant values are stored and not held in registers, or are not affected by optimizers. DLAMC1 returns the parameters LBETA, LT, LRND and LIEEE1. */ dlamc1_ (&lbeta, <, &lrnd, &lieee1); /* Start to find EPS. */ b = (double) lbeta; i__1 = -lt; a = pow_di (&b, &i__1); leps = a; /* Try some tricks to see whether or not this is the correct EPS. */ b = two / 3; half = one / 2; d__1 = -half; sixth = dlamc3_ (&b, &d__1); third = dlamc3_ (&sixth, &sixth); d__1 = -half; b = dlamc3_ (&third, &d__1); b = dlamc3_ (&b, &sixth); b = fabs (b); if (b < leps) { b = leps; } leps = 1.; /* + WHILE( ( LEPS.GT.B ).AND.( B.GT.ZERO ) )LOOP */ L10: if (leps > b && b > zero) { leps = b; d__1 = half * leps; /* Computing 5th power */ d__3 = two, d__4 = d__3, d__3 *= d__3; /* Computing 2nd power */ d__5 = leps; d__2 = d__4 * (d__3 * d__3) * (d__5 * d__5); c = dlamc3_ (&d__1, &d__2); d__1 = -c; c = dlamc3_ (&half, &d__1); b = dlamc3_ (&half, &c); d__1 = -b; c = dlamc3_ (&half, &d__1); b = dlamc3_ (&half, &c); goto L10; } /* + END WHILE */ if (a < leps) { leps = a; } /* Computation of EPS complete. Now find EMIN. Let A = + or - 1, and + or - (1 + BASE**(-3)). Keep dividing A by BETA until (gradual) underflow occurs. This is detected when we cannot recover the previous A. */ rbase = one / lbeta; smal = one; for (i = 1; i <= 3; ++i) { d__1 = smal * rbase; smal = dlamc3_ (&d__1, &zero); /* L20: */ } a = dlamc3_ (&one, &smal); dlamc4_ (&ngpmin, &one, &lbeta); d__1 = -one; dlamc4_ (&ngnmin, &d__1, &lbeta); dlamc4_ (&gpmin, &a, &lbeta); d__1 = -a; dlamc4_ (&gnmin, &d__1, &lbeta); ieee = FALSE; if (ngpmin == ngnmin && gpmin == gnmin) { if (ngpmin == gpmin) { lemin = ngpmin; /* ( Non twos-complement machines, no gradual underflow; e.g., VAX ) */ } else if (gpmin - ngpmin == 3) { lemin = ngpmin - 1 + lt; ieee = TRUE; /* ( Non twos-complement machines, with gradual underflow; e.g., IEEE standard followers ) */ } else { lemin = MIN (ngpmin, gpmin); /* ( A guess; no known machine ) */ iwarn = TRUE; } } else if (ngpmin == gpmin && ngnmin == gnmin) { if ( (i__1 = ngpmin - ngnmin, labs (i__1)) == 1) { lemin = MAX (ngpmin, ngnmin); /* ( Twos-complement machines, no gradual underflow; e.g., CYBER 205 ) */ } else { lemin = MIN (ngpmin, ngnmin); /* ( A guess; no known machine ) */ iwarn = TRUE; } } else if ( (i__1 = ngpmin - ngnmin, labs (i__1)) == 1 && gpmin == gnmin) { if (gpmin - MIN (ngpmin, ngnmin) == 3) { lemin = MAX (ngpmin, ngnmin) - 1 + lt; /* ( Twos-complement machines with gradual underflow; no known machine ) */ } else { lemin = MIN (ngpmin, ngnmin); /* ( A guess; no known machine ) */ iwarn = TRUE; } } else { /* Computing MIN */ i__1 = MIN (ngpmin, ngnmin), i__1 = MIN (i__1, gpmin); lemin = MIN (i__1, gnmin); /* ( A guess; no known machine ) */ iwarn = TRUE; } /* Comment out this if block if EMIN is ok */ if (iwarn) { first = TRUE; Melder_warning (U"\n\n WARNING. The value EMIN may be incorrect:- " "EMIN = ", lemin, U"\nIf, after inspection, the value EMIN looks acceptable" "please comment out \n the IF block as marked within the" "code of routine DLAMC2, \n otherwise supply EMIN" "explicitly.\n"); } /* ** Assume IEEE arithmetic if we found denormalised numbers above, or if arithmetic seems to round in the IEEE style, determined in routine DLAMC1. A true IEEE machine should have both things true; however, faulty machines may have one or the other. */ ieee = ieee || lieee1; /* Compute RMIN by successive division by BETA. We could compute RMIN as BASE**( EMIN - 1 ), but some machines underflow during this computation. */ lrmin = 1.; i__1 = 1 - lemin; for (i = 1; i <= 1 - lemin; ++i) { d__1 = lrmin * rbase; lrmin = dlamc3_ (&d__1, &zero); /* L30: */ } /* Finally, call DLAMC5 to compute EMAX and RMAX. */ dlamc5_ (&lbeta, <, &lemin, &ieee, &lemax, &lrmax); } *beta = lbeta; *t = lt; *rnd = lrnd; *eps = leps; *emin = lemin; *rmin = lrmin; *emax = lemax; *rmax = lrmax; return 0; } /* dlamc2_ */ static double dlamc3_ (double *a, double *b) /* Purpose ======= dlamc3_ is intended to force A and B to be stored prior to doing the addition of A and B , for use in situations where optimizers might hold one of these in a register. Arguments ========= A, B (input) DOUBLE PRECISION The values A and B. ===================================================================== */ { volatile double ret_val; ret_val = *a + *b; return ret_val; } /* dlamc3_ */ static int dlamc4_ (long *emin, double *start, long *base) { /* -- LAPACK auxiliary routine (version 2.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University October 31, 1992 Purpose ======= DLAMC4 is a service routine for DLAMC2. Arguments ========= EMIN (output) EMIN The minimum exponent before (gradual) underflow, computed by setting A = START and dividing by BASE until the previous A can not be recovered. START (input) DOUBLE PRECISION The starting point for determining EMIN. BASE (input) INTEGER The base of the machine. ===================================================================== */ /* System generated locals */ long i__1; double d__1; /* Local variables */ static double zero, a; static long i; static double rbase, b1, b2, c1, c2, d1, d2; static double one; a = *start; one = 1.; rbase = one / *base; zero = 0.; *emin = 1; d__1 = a * rbase; b1 = dlamc3_ (&d__1, &zero); c1 = a; c2 = a; d1 = a; d2 = a; /* + WHILE( ( C1.EQ.A ).AND.( C2.EQ.A ).AND. $ ( D1.EQ.A ).AND.( D2.EQ.A ) )LOOP */ L10: if (c1 == a && c2 == a && d1 == a && d2 == a) { -- (*emin); a = b1; d__1 = a / *base; b1 = dlamc3_ (&d__1, &zero); d__1 = b1 * *base; c1 = dlamc3_ (&d__1, &zero); d1 = zero; i__1 = *base; for (i = 1; i <= *base; ++i) { d1 += b1; /* L20: */ } d__1 = a * rbase; b2 = dlamc3_ (&d__1, &zero); d__1 = b2 / rbase; c2 = dlamc3_ (&d__1, &zero); d2 = zero; i__1 = *base; for (i = 1; i <= *base; ++i) { d2 += b2; /* L30: */ } goto L10; } /* + END WHILE */ return 0; } /* dlamc4_ */ static int dlamc5_ (long *beta, long *p, long *emin, long *ieee, long *emax, double *rmax) { /* First compute LEXP and UEXP, two powers of 2 that bound abs(EMIN). We then assume that EMAX + abs(EMIN) will sum approximately to the bound that is closest to abs(EMIN). (EMAX is the exponent of the required number RMAX). */ /* Table of constant values */ static double c_b5 = 0.; /* System generated locals */ long i__1; double d__1; /* Local variables */ static long lexp; static double oldy; static long uexp, i; static double y, z; static long nbits; static double recbas; static long exbits, expsum, try__; lexp = 1; exbits = 1; L10: try__ = lexp << 1; if (try__ <= - (*emin)) { lexp = try__; ++exbits; goto L10; } if (lexp == - (*emin)) { uexp = lexp; } else { uexp = try__; ++exbits; } /* Now -LEXP is less than or equal to EMIN, and -UEXP is greater than or equal to EMIN. EXBITS is the number of bits needed to store the exponent. */ if (uexp + *emin > -lexp - *emin) { expsum = lexp << 1; } else { expsum = uexp << 1; } /* EXPSUM is the exponent range, approximately equal to EMAX - EMIN + 1 . */ *emax = expsum + *emin - 1; nbits = exbits + 1 + *p; /* NBITS is the total number of bits needed to store a floating-point number. */ if (nbits % 2 == 1 && *beta == 2) { /* Either there are an odd number of bits used to store a floating-point number, which is unlikely, or some bits are not used in the representation of numbers, which is possible, (e.g. Cray machines) or the mantissa has an implicit bit, (e.g. IEEE machines, Dec Vax machines), which is perhaps the most likely. We have to assume the last alternative. If this is true, then we need to reduce EMAX by one because there must be some way of representing zero in an implicit-bit system. On machines like Cray, we are reducing EMAX by one unnecessarily. */ -- (*emax); } if (*ieee) { /* Assume we are on an IEEE machine which reserves one exponent for infinity and NaN. */ -- (*emax); } /* Now create RMAX, the largest machine number, which should be equal to (1.0 - BETA**(-P)) * BETA**EMAX . First compute 1.0 - BETA**(-P), being careful that the result is less than 1.0 . */ recbas = 1. / *beta; z = *beta - 1.; y = 0.; i__1 = *p; for (i = 1; i <= *p; ++i) { z *= recbas; if (y < 1.) { oldy = y; } y = dlamc3_ (&y, &z); /* L20: */ } if (y >= 1.) { y = oldy; } /* Now multiply by BETA**EMAX to get RMAX. */ i__1 = *emax; for (i = 1; i <= *emax; ++i) { d__1 = y * *beta; y = dlamc3_ (&d__1, &c_b5); /* L30: */ } *rmax = y; return 0; } /* dlamc5_ */ double NUMblas_dnrm2 (long *n, double *x, long *incx) { /* The following loop is equivalent to this call to the LAPACK auxiliary routine: CALL DLASSQ( N, X, INCX, SCALE, SSQ ) */ /* System generated locals */ long i__1, i__2; double ret_val, d__1; /* Local variables */ static double norm, scale, absxi; static long ix; static double ssq; --x; /* Function Body */ if (*n < 1 || *incx < 1) { norm = 0.; } else if (*n == 1) { norm = fabs (x[1]); } else { scale = 0.; ssq = 1.; i__1 = (*n - 1) * *incx + 1; i__2 = *incx; for (ix = 1; i__2 < 0 ? ix >= i__1 : ix <= i__1; ix += i__2) { if (x[ix] != 0.) { absxi = (d__1 = x[ix], fabs (d__1)); if (scale < absxi) { /* Computing 2nd power */ d__1 = scale / absxi; ssq = ssq * (d__1 * d__1) + 1.; scale = absxi; } else { /* Computing 2nd power */ d__1 = absxi / scale; ssq += d__1 * d__1; } } /* L10: */ } norm = scale * sqrt (ssq); } ret_val = norm; return ret_val; } /* NUMblas_dnrm2 */ int NUMblas_drot (long *n, double *dx, long *incx, double *dy, long *incy, double *c__, double *s) { /* System generated locals */ long i__1; /* Local variables */ static long i__; static double dtemp; static long ix, iy; /* applies a plane rotation. jack dongarra, linpack, 3/11/78. modified 12/3/93, array(1) declarations changed to array(*) Parameter adjustments */ --dy; --dx; /* Function Body */ if (*n <= 0) { return 0; } if (*incx == 1 && *incy == 1) { goto L20; } /* code for unequal increments or equal increments not equal to 1 */ ix = 1; iy = 1; if (*incx < 0) { ix = (- (*n) + 1) * *incx + 1; } if (*incy < 0) { iy = (- (*n) + 1) * *incy + 1; } i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { dtemp = *c__ * dx[ix] + *s * dy[iy]; dy[iy] = *c__ * dy[iy] - *s * dx[ix]; dx[ix] = dtemp; ix += *incx; iy += *incy; /* L10: */ } return 0; /* code for both increments equal to 1 */ L20: i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { dtemp = *c__ * dx[i__] + *s * dy[i__]; dy[i__] = *c__ * dy[i__] - *s * dx[i__]; dx[i__] = dtemp; /* L30: */ } return 0; } /* NUMblas_drot */ int NUMblas_dscal (long *n, double *da, double *dx, long *incx) { /* System generated locals */ long i__1, i__2; /* Local variables */ static long i__, m, nincx, mp1; /* Parameter adjustments */ --dx; /* Function Body */ if (*n <= 0 || *incx <= 0) { return 0; } if (*incx == 1) { goto L20; } /* code for increment not equal to 1 */ nincx = *n * *incx; i__1 = nincx; i__2 = *incx; for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) { dx[i__] = *da * dx[i__]; /* L10: */ } return 0; /* code for increment equal to 1 clean-up loop */ L20: m = *n % 5; if (m == 0) { goto L40; } i__2 = m; for (i__ = 1; i__ <= i__2; ++i__) { dx[i__] = *da * dx[i__]; /* L30: */ } if (*n < 5) { return 0; } L40: mp1 = m + 1; i__2 = *n; for (i__ = mp1; i__ <= i__2; i__ += 5) { dx[i__] = *da * dx[i__]; dx[i__ + 1] = *da * dx[i__ + 1]; dx[i__ + 2] = *da * dx[i__ + 2]; dx[i__ + 3] = *da * dx[i__ + 3]; dx[i__ + 4] = *da * dx[i__ + 4]; /* L50: */ } return 0; } /* dscal_ */ int NUMblas_dswap (long *n, double *dx, long *incx, double *dy, long *incy) { /* System generated locals */ long i__1; /* Local variables */ static long i__, m; static double dtemp; static long ix, iy, mp1; /* interchanges two vectors. uses unrolled loops for increments equal one. jack dongarra, linpack, 3/11/78. modified 12/3/93, array(1) declarations changed to array(*) Parameter adjustments */ --dy; --dx; /* Function Body */ if (*n <= 0) { return 0; } if (*incx == 1 && *incy == 1) { goto L20; } /* code for unequal increments or equal increments not equal to 1 */ ix = 1; iy = 1; if (*incx < 0) { ix = (- (*n) + 1) * *incx + 1; } if (*incy < 0) { iy = (- (*n) + 1) * *incy + 1; } i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { dtemp = dx[ix]; dx[ix] = dy[iy]; dy[iy] = dtemp; ix += *incx; iy += *incy; /* L10: */ } return 0; /* code for both increments equal to 1 clean-up loop */ L20: m = *n % 3; if (m == 0) { goto L40; } i__1 = m; for (i__ = 1; i__ <= i__1; ++i__) { dtemp = dx[i__]; dx[i__] = dy[i__]; dy[i__] = dtemp; /* L30: */ } if (*n < 3) { return 0; } L40: mp1 = m + 1; i__1 = *n; for (i__ = mp1; i__ <= i__1; i__ += 3) { dtemp = dx[i__]; dx[i__] = dy[i__]; dy[i__] = dtemp; dtemp = dx[i__ + 1]; dx[i__ + 1] = dy[i__ + 1]; dy[i__ + 1] = dtemp; dtemp = dx[i__ + 2]; dx[i__ + 2] = dy[i__ + 2]; dy[i__ + 2] = dtemp; /* L50: */ } return 0; } /* NUMblas_dswap */ int NUMblas_dsymv (const char *uplo, long *n, double *alpha, double *a, long *lda, double *x, long *incx, double *beta, double *y, long *incy) { /* System generated locals */ long a_dim1, a_offset, i__1, i__2; /* Local variables */ static long info; static double temp1, temp2; static long i__, j; static long ix, iy, jx, jy, kx, ky; #define a_ref(a_1,a_2) a[(a_2)*a_dim1 + a_1] a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --x; --y; /* Function Body */ info = 0; if (!lsame_ (uplo, "U") && !lsame_ (uplo, "L")) { info = 1; } else if (*n < 0) { info = 2; } else if (*lda < MAX (1, *n)) { info = 5; } else if (*incx == 0) { info = 7; } else if (*incy == 0) { info = 10; } if (info != 0) { xerbla_ ("DSYMV ", &info); return 0; } /* Quick return if possible. */ if (*n == 0 || (*alpha == 0. && *beta == 1.)) { return 0; } /* Set up the start points in X and Y. */ if (*incx > 0) { kx = 1; } else { kx = 1 - (*n - 1) * *incx; } if (*incy > 0) { ky = 1; } else { ky = 1 - (*n - 1) * *incy; } /* Start the operations. In this version the elements of A are accessed sequentially with one pass through the triangular part of A. First form y := beta*y. */ if (*beta != 1.) { if (*incy == 1) { if (*beta == 0.) { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { y[i__] = 0.; /* L10: */ } } else { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { y[i__] = *beta * y[i__]; /* L20: */ } } } else { iy = ky; if (*beta == 0.) { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { y[iy] = 0.; iy += *incy; /* L30: */ } } else { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { y[iy] = *beta * y[iy]; iy += *incy; /* L40: */ } } } } if (*alpha == 0.) { return 0; } if (lsame_ (uplo, "U")) { /* Form y when A is stored in upper triangle. */ if (*incx == 1 && *incy == 1) { i__1 = *n; for (j = 1; j <= i__1; ++j) { temp1 = *alpha * x[j]; temp2 = 0.; i__2 = j - 1; for (i__ = 1; i__ <= i__2; ++i__) { y[i__] += temp1 * a_ref (i__, j); temp2 += a_ref (i__, j) * x[i__]; /* L50: */ } y[j] = y[j] + temp1 * a_ref (j, j) + *alpha * temp2; /* L60: */ } } else { jx = kx; jy = ky; i__1 = *n; for (j = 1; j <= i__1; ++j) { temp1 = *alpha * x[jx]; temp2 = 0.; ix = kx; iy = ky; i__2 = j - 1; for (i__ = 1; i__ <= i__2; ++i__) { y[iy] += temp1 * a_ref (i__, j); temp2 += a_ref (i__, j) * x[ix]; ix += *incx; iy += *incy; /* L70: */ } y[jy] = y[jy] + temp1 * a_ref (j, j) + *alpha * temp2; jx += *incx; jy += *incy; /* L80: */ } } } else { /* Form y when A is stored in lower triangle. */ if (*incx == 1 && *incy == 1) { i__1 = *n; for (j = 1; j <= i__1; ++j) { temp1 = *alpha * x[j]; temp2 = 0.; y[j] += temp1 * a_ref (j, j); i__2 = *n; for (i__ = j + 1; i__ <= i__2; ++i__) { y[i__] += temp1 * a_ref (i__, j); temp2 += a_ref (i__, j) * x[i__]; /* L90: */ } y[j] += *alpha * temp2; /* L100: */ } } else { jx = kx; jy = ky; i__1 = *n; for (j = 1; j <= i__1; ++j) { temp1 = *alpha * x[jx]; temp2 = 0.; y[jy] += temp1 * a_ref (j, j); ix = jx; iy = jy; i__2 = *n; for (i__ = j + 1; i__ <= i__2; ++i__) { ix += *incx; iy += *incy; y[iy] += temp1 * a_ref (i__, j); temp2 += a_ref (i__, j) * x[ix]; /* L110: */ } y[jy] += *alpha * temp2; jx += *incx; jy += *incy; /* L120: */ } } } return 0; } /* NUMblas_dsymv */ #undef a_ref int NUMblas_dsyr2 (const char *uplo, long *n, double *alpha, double *x, long *incx, double *y, long *incy, double *a, long *lda) { /* System generated locals */ long a_dim1, a_offset, i__1, i__2; /* Local variables */ static long info; static double temp1, temp2; static long i__, j; static long ix, iy, jx, jy, kx, ky; #define a_ref(a_1,a_2) a[(a_2)*a_dim1 + a_1] --x; --y; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; /* Function Body */ info = 0; if (!lsame_ (uplo, "U") && !lsame_ (uplo, "L")) { info = 1; } else if (*n < 0) { info = 2; } else if (*incx == 0) { info = 5; } else if (*incy == 0) { info = 7; } else if (*lda < MAX (1, *n)) { info = 9; } if (info != 0) { xerbla_ ("DSYR2 ", &info); return 0; } /* Quick return if possible. */ if (*n == 0 || *alpha == 0.) { return 0; } /* Set up the start points in X and Y if the increments are not both unity. */ if (*incx != 1 || *incy != 1) { if (*incx > 0) { kx = 1; } else { kx = 1 - (*n - 1) * *incx; } if (*incy > 0) { ky = 1; } else { ky = 1 - (*n - 1) * *incy; } jx = kx; jy = ky; } /* Start the operations. In this version the elements of A are accessed sequentially with one pass through the triangular part of A. */ if (lsame_ (uplo, "U")) { /* Form A when A is stored in the upper triangle. */ if (*incx == 1 && *incy == 1) { i__1 = *n; for (j = 1; j <= i__1; ++j) { if (x[j] != 0. || y[j] != 0.) { temp1 = *alpha * y[j]; temp2 = *alpha * x[j]; i__2 = j; for (i__ = 1; i__ <= i__2; ++i__) { a_ref (i__, j) = a_ref (i__, j) + x[i__] * temp1 + y[i__] * temp2; /* L10: */ } } /* L20: */ } } else { i__1 = *n; for (j = 1; j <= i__1; ++j) { if (x[jx] != 0. || y[jy] != 0.) { temp1 = *alpha * y[jy]; temp2 = *alpha * x[jx]; ix = kx; iy = ky; i__2 = j; for (i__ = 1; i__ <= i__2; ++i__) { a_ref (i__, j) = a_ref (i__, j) + x[ix] * temp1 + y[iy] * temp2; ix += *incx; iy += *incy; /* L30: */ } } jx += *incx; jy += *incy; /* L40: */ } } } else { /* Form A when A is stored in the lower triangle. */ if (*incx == 1 && *incy == 1) { i__1 = *n; for (j = 1; j <= i__1; ++j) { if (x[j] != 0. || y[j] != 0.) { temp1 = *alpha * y[j]; temp2 = *alpha * x[j]; i__2 = *n; for (i__ = j; i__ <= i__2; ++i__) { a_ref (i__, j) = a_ref (i__, j) + x[i__] * temp1 + y[i__] * temp2; /* L50: */ } } /* L60: */ } } else { i__1 = *n; for (j = 1; j <= i__1; ++j) { if (x[jx] != 0. || y[jy] != 0.) { temp1 = *alpha * y[jy]; temp2 = *alpha * x[jx]; ix = jx; iy = jy; i__2 = *n; for (i__ = j; i__ <= i__2; ++i__) { a_ref (i__, j) = a_ref (i__, j) + x[ix] * temp1 + y[iy] * temp2; ix += *incx; iy += *incy; /* L70: */ } } jx += *incx; jy += *incy; /* L80: */ } } } return 0; } /* NUMblas_dsyr2 */ #undef a_ref int NUMblas_dsyr2k (const char *uplo, const char *trans, long *n, long *k, double *alpha, double *a, long *lda, double *b, long *ldb, double *beta, double *c__, long *ldc) { /* System generated locals */ long a_dim1, a_offset, b_dim1, b_offset, c_dim1, c_offset, i__1, i__2, i__3; /* Local variables */ static long info; static double temp1, temp2; static long i__, j, l; static long nrowa; static long upper; #define a_ref(a_1,a_2) a[(a_2)*a_dim1 + a_1] #define b_ref(a_1,a_2) b[(a_2)*b_dim1 + a_1] #define c___ref(a_1,a_2) c__[(a_2)*c_dim1 + a_1] a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; b_dim1 = *ldb; b_offset = 1 + b_dim1 * 1; b -= b_offset; c_dim1 = *ldc; c_offset = 1 + c_dim1 * 1; c__ -= c_offset; /* Function Body */ if (lsame_ (trans, "N")) { nrowa = *n; } else { nrowa = *k; } upper = lsame_ (uplo, "U"); info = 0; if (!upper && !lsame_ (uplo, "L")) { info = 1; } else if (!lsame_ (trans, "N") && !lsame_ (trans, "T") && !lsame_ (trans, "C")) { info = 2; } else if (*n < 0) { info = 3; } else if (*k < 0) { info = 4; } else if (*lda < MAX (1, nrowa)) { info = 7; } else if (*ldb < MAX (1, nrowa)) { info = 9; } else if (*ldc < MAX (1, *n)) { info = 12; } if (info != 0) { xerbla_ ("DSYR2K", &info); return 0; } /* Quick return if possible. */ if (*n == 0 || ((*alpha == 0. || *k == 0) && *beta == 1.)) { return 0; } /* And when alpha.eq.zero. */ if (*alpha == 0.) { if (upper) { if (*beta == 0.) { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = j; for (i__ = 1; i__ <= i__2; ++i__) { c___ref (i__, j) = 0.; /* L10: */ } /* L20: */ } } else { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = j; for (i__ = 1; i__ <= i__2; ++i__) { c___ref (i__, j) = *beta * c___ref (i__, j); /* L30: */ } /* L40: */ } } } else { if (*beta == 0.) { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *n; for (i__ = j; i__ <= i__2; ++i__) { c___ref (i__, j) = 0.; /* L50: */ } /* L60: */ } } else { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *n; for (i__ = j; i__ <= i__2; ++i__) { c___ref (i__, j) = *beta * c___ref (i__, j); /* L70: */ } /* L80: */ } } } return 0; } /* Start the operations. */ if (lsame_ (trans, "N")) { /* Form C := alpha*A*B' + alpha*B*A' + C. */ if (upper) { i__1 = *n; for (j = 1; j <= i__1; ++j) { if (*beta == 0.) { i__2 = j; for (i__ = 1; i__ <= i__2; ++i__) { c___ref (i__, j) = 0.; /* L90: */ } } else if (*beta != 1.) { i__2 = j; for (i__ = 1; i__ <= i__2; ++i__) { c___ref (i__, j) = *beta * c___ref (i__, j); /* L100: */ } } i__2 = *k; for (l = 1; l <= i__2; ++l) { if (a_ref (j, l) != 0. || b_ref (j, l) != 0.) { temp1 = *alpha * b_ref (j, l); temp2 = *alpha * a_ref (j, l); i__3 = j; for (i__ = 1; i__ <= i__3; ++i__) { c___ref (i__, j) = c___ref (i__, j) + a_ref (i__, l) * temp1 + b_ref (i__, l) * temp2; /* L110: */ } } /* L120: */ } /* L130: */ } } else { i__1 = *n; for (j = 1; j <= i__1; ++j) { if (*beta == 0.) { i__2 = *n; for (i__ = j; i__ <= i__2; ++i__) { c___ref (i__, j) = 0.; /* L140: */ } } else if (*beta != 1.) { i__2 = *n; for (i__ = j; i__ <= i__2; ++i__) { c___ref (i__, j) = *beta * c___ref (i__, j); /* L150: */ } } i__2 = *k; for (l = 1; l <= i__2; ++l) { if (a_ref (j, l) != 0. || b_ref (j, l) != 0.) { temp1 = *alpha * b_ref (j, l); temp2 = *alpha * a_ref (j, l); i__3 = *n; for (i__ = j; i__ <= i__3; ++i__) { c___ref (i__, j) = c___ref (i__, j) + a_ref (i__, l) * temp1 + b_ref (i__, l) * temp2; /* L160: */ } } /* L170: */ } /* L180: */ } } } else { /* Form C := alpha*A'*B + alpha*B'*A + C. */ if (upper) { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = j; for (i__ = 1; i__ <= i__2; ++i__) { temp1 = 0.; temp2 = 0.; i__3 = *k; for (l = 1; l <= i__3; ++l) { temp1 += a_ref (l, i__) * b_ref (l, j); temp2 += b_ref (l, i__) * a_ref (l, j); /* L190: */ } if (*beta == 0.) { c___ref (i__, j) = *alpha * temp1 + *alpha * temp2; } else { c___ref (i__, j) = *beta * c___ref (i__, j) + *alpha * temp1 + *alpha * temp2; } /* L200: */ } /* L210: */ } } else { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *n; for (i__ = j; i__ <= i__2; ++i__) { temp1 = 0.; temp2 = 0.; i__3 = *k; for (l = 1; l <= i__3; ++l) { temp1 += a_ref (l, i__) * b_ref (l, j); temp2 += b_ref (l, i__) * a_ref (l, j); /* L220: */ } if (*beta == 0.) { c___ref (i__, j) = *alpha * temp1 + *alpha * temp2; } else { c___ref (i__, j) = *beta * c___ref (i__, j) + *alpha * temp1 + *alpha * temp2; } /* L230: */ } /* L240: */ } } } return 0; } /* NUMblas_dsyr2k */ #undef c___ref #undef b_ref #undef a_ref int NUMblas_dtrmm (const char *side, const char *uplo, const char *transa, const char *diag, long *m, long *n, double *alpha, double *a, long *lda, double *b, long *ldb) { /* System generated locals */ long a_dim1, a_offset, b_dim1, b_offset, i__1, i__2, i__3; /* Local variables */ static long info; static double temp; static long i__, j, k; static long lside; static long nrowa; static long upper; static long nounit; #define a_ref(a_1,a_2) a[(a_2)*a_dim1 + a_1] #define b_ref(a_1,a_2) b[(a_2)*b_dim1 + a_1] /* Level 3 Blas routine. -- Written on 8-February-1989. Jack Dongarra, Argonne National Laboratory. Iain Duff, AERE Harwell. Jeremy Du Croz, Numerical Algorithms Group Ltd. Sven Hammarling, Numerical Algorithms Group Ltd. Test the input parameters. Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; b_dim1 = *ldb; b_offset = 1 + b_dim1 * 1; b -= b_offset; /* Function Body */ lside = lsame_ (side, "L"); if (lside) { nrowa = *m; } else { nrowa = *n; } nounit = lsame_ (diag, "N"); upper = lsame_ (uplo, "U"); info = 0; if (!lside && !lsame_ (side, "R")) { info = 1; } else if (!upper && !lsame_ (uplo, "L")) { info = 2; } else if (!lsame_ (transa, "N") && !lsame_ (transa, "T") && !lsame_ (transa, "C")) { info = 3; } else if (!lsame_ (diag, "U") && !lsame_ (diag, "N")) { info = 4; } else if (*m < 0) { info = 5; } else if (*n < 0) { info = 6; } else if (*lda < MAX (1, nrowa)) { info = 9; } else if (*ldb < MAX (1, *m)) { info = 11; } if (info != 0) { xerbla_ ("DTRMM ", &info); return 0; } /* Quick return if possible. */ if (*n == 0) { return 0; } /* And when alpha.eq.zero. */ if (*alpha == 0.) { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { b_ref (i__, j) = 0.; /* L10: */ } /* L20: */ } return 0; } /* Start the operations. */ if (lside) { if (lsame_ (transa, "N")) { /* Form B := alpha*A*B. */ if (upper) { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *m; for (k = 1; k <= i__2; ++k) { if (b_ref (k, j) != 0.) { temp = *alpha * b_ref (k, j); i__3 = k - 1; for (i__ = 1; i__ <= i__3; ++i__) { b_ref (i__, j) = b_ref (i__, j) + temp * a_ref (i__, k); /* L30: */ } if (nounit) { temp *= a_ref (k, k); } b_ref (k, j) = temp; } /* L40: */ } /* L50: */ } } else { i__1 = *n; for (j = 1; j <= i__1; ++j) { for (k = *m; k >= 1; --k) { if (b_ref (k, j) != 0.) { temp = *alpha * b_ref (k, j); b_ref (k, j) = temp; if (nounit) { b_ref (k, j) = b_ref (k, j) * a_ref (k, k); } i__2 = *m; for (i__ = k + 1; i__ <= i__2; ++i__) { b_ref (i__, j) = b_ref (i__, j) + temp * a_ref (i__, k); /* L60: */ } } /* L70: */ } /* L80: */ } } } else { /* Form B := alpha*A'*B. */ if (upper) { i__1 = *n; for (j = 1; j <= i__1; ++j) { for (i__ = *m; i__ >= 1; --i__) { temp = b_ref (i__, j); if (nounit) { temp *= a_ref (i__, i__); } i__2 = i__ - 1; for (k = 1; k <= i__2; ++k) { temp += a_ref (k, i__) * b_ref (k, j); /* L90: */ } b_ref (i__, j) = *alpha * temp; /* L100: */ } /* L110: */ } } else { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { temp = b_ref (i__, j); if (nounit) { temp *= a_ref (i__, i__); } i__3 = *m; for (k = i__ + 1; k <= i__3; ++k) { temp += a_ref (k, i__) * b_ref (k, j); /* L120: */ } b_ref (i__, j) = *alpha * temp; /* L130: */ } /* L140: */ } } } } else { if (lsame_ (transa, "N")) { /* Form B := alpha*B*A. */ if (upper) { for (j = *n; j >= 1; --j) { temp = *alpha; if (nounit) { temp *= a_ref (j, j); } i__1 = *m; for (i__ = 1; i__ <= i__1; ++i__) { b_ref (i__, j) = temp * b_ref (i__, j); /* L150: */ } i__1 = j - 1; for (k = 1; k <= i__1; ++k) { if (a_ref (k, j) != 0.) { temp = *alpha * a_ref (k, j); i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { b_ref (i__, j) = b_ref (i__, j) + temp * b_ref (i__, k); /* L160: */ } } /* L170: */ } /* L180: */ } } else { i__1 = *n; for (j = 1; j <= i__1; ++j) { temp = *alpha; if (nounit) { temp *= a_ref (j, j); } i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { b_ref (i__, j) = temp * b_ref (i__, j); /* L190: */ } i__2 = *n; for (k = j + 1; k <= i__2; ++k) { if (a_ref (k, j) != 0.) { temp = *alpha * a_ref (k, j); i__3 = *m; for (i__ = 1; i__ <= i__3; ++i__) { b_ref (i__, j) = b_ref (i__, j) + temp * b_ref (i__, k); /* L200: */ } } /* L210: */ } /* L220: */ } } } else { /* Form B := alpha*B*A'. */ if (upper) { i__1 = *n; for (k = 1; k <= i__1; ++k) { i__2 = k - 1; for (j = 1; j <= i__2; ++j) { if (a_ref (j, k) != 0.) { temp = *alpha * a_ref (j, k); i__3 = *m; for (i__ = 1; i__ <= i__3; ++i__) { b_ref (i__, j) = b_ref (i__, j) + temp * b_ref (i__, k); /* L230: */ } } /* L240: */ } temp = *alpha; if (nounit) { temp *= a_ref (k, k); } if (temp != 1.) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { b_ref (i__, k) = temp * b_ref (i__, k); /* L250: */ } } /* L260: */ } } else { for (k = *n; k >= 1; --k) { i__1 = *n; for (j = k + 1; j <= i__1; ++j) { if (a_ref (j, k) != 0.) { temp = *alpha * a_ref (j, k); i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { b_ref (i__, j) = b_ref (i__, j) + temp * b_ref (i__, k); /* L270: */ } } /* L280: */ } temp = *alpha; if (nounit) { temp *= a_ref (k, k); } if (temp != 1.) { i__1 = *m; for (i__ = 1; i__ <= i__1; ++i__) { b_ref (i__, k) = temp * b_ref (i__, k); /* L290: */ } } /* L300: */ } } } } return 0; } /* NUMblas_dtrmm */ #undef b_ref #undef a_ref int NUMblas_dtrmv (const char *uplo, const char *trans, const char *diag, long *n, double *a, long *lda, double *x, long *incx) { /* System generated locals */ long a_dim1, a_offset, i__1, i__2; /* Local variables */ static long info; static double temp; static long i__, j; static long ix, jx, kx; static long nounit; #define a_ref(a_1,a_2) a[(a_2)*a_dim1 + a_1] /* -- Written on 22-October-1986. Jack Dongarra, Argonne National Lab. Jeremy Du Croz, Nag Central Office. Sven Hammarling, Nag Central Office. Richard Hanson, Sandia National Labs. Test the input parameters. Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --x; /* Function Body */ info = 0; if (!lsame_ (uplo, "U") && !lsame_ (uplo, "L")) { info = 1; } else if (!lsame_ (trans, "N") && !lsame_ (trans, "T") && !lsame_ (trans, "C")) { info = 2; } else if (!lsame_ (diag, "U") && !lsame_ (diag, "N")) { info = 3; } else if (*n < 0) { info = 4; } else if (*lda < MAX (1, *n)) { info = 6; } else if (*incx == 0) { info = 8; } if (info != 0) { xerbla_ ("DTRMV ", &info); return 0; } /* Quick return if possible. */ if (*n == 0) { return 0; } nounit = lsame_ (diag, "N"); /* Set up the start point in X if the increment is not unity. This will be ( N - 1 )*INCX too small for descending loops. */ if (*incx <= 0) { kx = 1 - (*n - 1) * *incx; } else if (*incx != 1) { kx = 1; } /* Start the operations. In this version the elements of A are accessed sequentially with one pass through A. */ if (lsame_ (trans, "N")) { /* Form x := A*x. */ if (lsame_ (uplo, "U")) { if (*incx == 1) { i__1 = *n; for (j = 1; j <= i__1; ++j) { if (x[j] != 0.) { temp = x[j]; i__2 = j - 1; for (i__ = 1; i__ <= i__2; ++i__) { x[i__] += temp * a_ref (i__, j); /* L10: */ } if (nounit) { x[j] *= a_ref (j, j); } } /* L20: */ } } else { jx = kx; i__1 = *n; for (j = 1; j <= i__1; ++j) { if (x[jx] != 0.) { temp = x[jx]; ix = kx; i__2 = j - 1; for (i__ = 1; i__ <= i__2; ++i__) { x[ix] += temp * a_ref (i__, j); ix += *incx; /* L30: */ } if (nounit) { x[jx] *= a_ref (j, j); } } jx += *incx; /* L40: */ } } } else { if (*incx == 1) { for (j = *n; j >= 1; --j) { if (x[j] != 0.) { temp = x[j]; i__1 = j + 1; for (i__ = *n; i__ >= i__1; --i__) { x[i__] += temp * a_ref (i__, j); /* L50: */ } if (nounit) { x[j] *= a_ref (j, j); } } /* L60: */ } } else { kx += (*n - 1) * *incx; jx = kx; for (j = *n; j >= 1; --j) { if (x[jx] != 0.) { temp = x[jx]; ix = kx; i__1 = j + 1; for (i__ = *n; i__ >= i__1; --i__) { x[ix] += temp * a_ref (i__, j); ix -= *incx; /* L70: */ } if (nounit) { x[jx] *= a_ref (j, j); } } jx -= *incx; /* L80: */ } } } } else { /* Form x := A'*x. */ if (lsame_ (uplo, "U")) { if (*incx == 1) { for (j = *n; j >= 1; --j) { temp = x[j]; if (nounit) { temp *= a_ref (j, j); } for (i__ = j - 1; i__ >= 1; --i__) { temp += a_ref (i__, j) * x[i__]; /* L90: */ } x[j] = temp; /* L100: */ } } else { jx = kx + (*n - 1) * *incx; for (j = *n; j >= 1; --j) { temp = x[jx]; ix = jx; if (nounit) { temp *= a_ref (j, j); } for (i__ = j - 1; i__ >= 1; --i__) { ix -= *incx; temp += a_ref (i__, j) * x[ix]; /* L110: */ } x[jx] = temp; jx -= *incx; /* L120: */ } } } else { if (*incx == 1) { i__1 = *n; for (j = 1; j <= i__1; ++j) { temp = x[j]; if (nounit) { temp *= a_ref (j, j); } i__2 = *n; for (i__ = j + 1; i__ <= i__2; ++i__) { temp += a_ref (i__, j) * x[i__]; /* L130: */ } x[j] = temp; /* L140: */ } } else { jx = kx; i__1 = *n; for (j = 1; j <= i__1; ++j) { temp = x[jx]; ix = jx; if (nounit) { temp *= a_ref (j, j); } i__2 = *n; for (i__ = j + 1; i__ <= i__2; ++i__) { ix += *incx; temp += a_ref (i__, j) * x[ix]; /* L150: */ } x[jx] = temp; jx += *incx; /* L160: */ } } } } return 0; } /* NUMblas_dtrmv */ #undef a_ref int NUMblas_dtrsm (const char *side, const char *uplo, const char *transa, const char *diag, long *m, long *n, double *alpha, double *a, long *lda, double *b, long *ldb) { /* System generated locals */ long a_dim1, a_offset, b_dim1, b_offset, i__1, i__2, i__3; /* Local variables */ static long info; static double temp; static long i__, j, k; static long lside; static long nrowa; static long upper; static long nounit; #define a_ref(a_1,a_2) a[(a_2)*a_dim1 + a_1] #define b_ref(a_1,a_2) b[(a_2)*b_dim1 + a_1] a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; b_dim1 = *ldb; b_offset = 1 + b_dim1 * 1; b -= b_offset; /* Function Body */ lside = lsame_ (side, "L"); if (lside) { nrowa = *m; } else { nrowa = *n; } nounit = lsame_ (diag, "N"); upper = lsame_ (uplo, "U"); info = 0; if (!lside && !lsame_ (side, "R")) { info = 1; } else if (!upper && !lsame_ (uplo, "L")) { info = 2; } else if (!lsame_ (transa, "N") && !lsame_ (transa, "T") && !lsame_ (transa, "C")) { info = 3; } else if (!lsame_ (diag, "U") && !lsame_ (diag, "N")) { info = 4; } else if (*m < 0) { info = 5; } else if (*n < 0) { info = 6; } else if (*lda < MAX (1, nrowa)) { info = 9; } else if (*ldb < MAX (1, *m)) { info = 11; } if (info != 0) { xerbla_ ("DTRSM ", &info); return 0; } /* Quick return if possible. */ if (*n == 0) { return 0; } /* And when alpha.eq.zero. */ if (*alpha == 0.) { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { b_ref (i__, j) = 0.; /* L10: */ } /* L20: */ } return 0; } /* Start the operations. */ if (lside) { if (lsame_ (transa, "N")) { /* Form B := alpha*inv( A )*B. */ if (upper) { i__1 = *n; for (j = 1; j <= i__1; ++j) { if (*alpha != 1.) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { b_ref (i__, j) = *alpha * b_ref (i__, j); /* L30: */ } } for (k = *m; k >= 1; --k) { if (b_ref (k, j) != 0.) { if (nounit) { b_ref (k, j) = b_ref (k, j) / a_ref (k, k); } i__2 = k - 1; for (i__ = 1; i__ <= i__2; ++i__) { b_ref (i__, j) = b_ref (i__, j) - b_ref (k, j) * a_ref (i__, k); /* L40: */ } } /* L50: */ } /* L60: */ } } else { i__1 = *n; for (j = 1; j <= i__1; ++j) { if (*alpha != 1.) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { b_ref (i__, j) = *alpha * b_ref (i__, j); /* L70: */ } } i__2 = *m; for (k = 1; k <= i__2; ++k) { if (b_ref (k, j) != 0.) { if (nounit) { b_ref (k, j) = b_ref (k, j) / a_ref (k, k); } i__3 = *m; for (i__ = k + 1; i__ <= i__3; ++i__) { b_ref (i__, j) = b_ref (i__, j) - b_ref (k, j) * a_ref (i__, k); /* L80: */ } } /* L90: */ } /* L100: */ } } } else { /* Form B := alpha*inv( A' )*B. */ if (upper) { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { temp = *alpha * b_ref (i__, j); i__3 = i__ - 1; for (k = 1; k <= i__3; ++k) { temp -= a_ref (k, i__) * b_ref (k, j); /* L110: */ } if (nounit) { temp /= a_ref (i__, i__); } b_ref (i__, j) = temp; /* L120: */ } /* L130: */ } } else { i__1 = *n; for (j = 1; j <= i__1; ++j) { for (i__ = *m; i__ >= 1; --i__) { temp = *alpha * b_ref (i__, j); i__2 = *m; for (k = i__ + 1; k <= i__2; ++k) { temp -= a_ref (k, i__) * b_ref (k, j); /* L140: */ } if (nounit) { temp /= a_ref (i__, i__); } b_ref (i__, j) = temp; /* L150: */ } /* L160: */ } } } } else { if (lsame_ (transa, "N")) { /* Form B := alpha*B*inv( A ). */ if (upper) { i__1 = *n; for (j = 1; j <= i__1; ++j) { if (*alpha != 1.) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { b_ref (i__, j) = *alpha * b_ref (i__, j); /* L170: */ } } i__2 = j - 1; for (k = 1; k <= i__2; ++k) { if (a_ref (k, j) != 0.) { i__3 = *m; for (i__ = 1; i__ <= i__3; ++i__) { b_ref (i__, j) = b_ref (i__, j) - a_ref (k, j) * b_ref (i__, k); /* L180: */ } } /* L190: */ } if (nounit) { temp = 1. / a_ref (j, j); i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { b_ref (i__, j) = temp * b_ref (i__, j); /* L200: */ } } /* L210: */ } } else { for (j = *n; j >= 1; --j) { if (*alpha != 1.) { i__1 = *m; for (i__ = 1; i__ <= i__1; ++i__) { b_ref (i__, j) = *alpha * b_ref (i__, j); /* L220: */ } } i__1 = *n; for (k = j + 1; k <= i__1; ++k) { if (a_ref (k, j) != 0.) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { b_ref (i__, j) = b_ref (i__, j) - a_ref (k, j) * b_ref (i__, k); /* L230: */ } } /* L240: */ } if (nounit) { temp = 1. / a_ref (j, j); i__1 = *m; for (i__ = 1; i__ <= i__1; ++i__) { b_ref (i__, j) = temp * b_ref (i__, j); /* L250: */ } } /* L260: */ } } } else { /* Form B := alpha*B*inv( A' ). */ if (upper) { for (k = *n; k >= 1; --k) { if (nounit) { temp = 1. / a_ref (k, k); i__1 = *m; for (i__ = 1; i__ <= i__1; ++i__) { b_ref (i__, k) = temp * b_ref (i__, k); /* L270: */ } } i__1 = k - 1; for (j = 1; j <= i__1; ++j) { if (a_ref (j, k) != 0.) { temp = a_ref (j, k); i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { b_ref (i__, j) = b_ref (i__, j) - temp * b_ref (i__, k); /* L280: */ } } /* L290: */ } if (*alpha != 1.) { i__1 = *m; for (i__ = 1; i__ <= i__1; ++i__) { b_ref (i__, k) = *alpha * b_ref (i__, k); /* L300: */ } } /* L310: */ } } else { i__1 = *n; for (k = 1; k <= i__1; ++k) { if (nounit) { temp = 1. / a_ref (k, k); i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { b_ref (i__, k) = temp * b_ref (i__, k); /* L320: */ } } i__2 = *n; for (j = k + 1; j <= i__2; ++j) { if (a_ref (j, k) != 0.) { temp = a_ref (j, k); i__3 = *m; for (i__ = 1; i__ <= i__3; ++i__) { b_ref (i__, j) = b_ref (i__, j) - temp * b_ref (i__, k); /* L330: */ } } /* L340: */ } if (*alpha != 1.) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { b_ref (i__, k) = *alpha * b_ref (i__, k); /* L350: */ } } /* L360: */ } } } } return 0; } /* NUMblas_dtrsm */ #undef b_ref #undef a_ref long NUMblas_idamax (long *n, double *dx, long *incx) { /* System generated locals */ long ret_val, i__1; double d__1; /* Local variables */ static double dmax__; static long i__, ix; /* finds the index of element having max. absolute value. jack dongarra, linpack, 3/11/78. modified 3/93 to return if incx .le. 0. modified 12/3/93, array(1) declarations changed to array(*) Parameter adjustments */ --dx; /* Function Body */ ret_val = 0; if (*n < 1 || *incx <= 0) { return ret_val; } ret_val = 1; if (*n == 1) { return ret_val; } if (*incx == 1) { goto L20; } /* code for increment not equal to 1 */ ix = 1; dmax__ = fabs (dx[1]); ix += *incx; i__1 = *n; for (i__ = 2; i__ <= i__1; ++i__) { if ( (d__1 = dx[ix], fabs (d__1)) <= dmax__) { goto L5; } ret_val = i__; dmax__ = (d__1 = dx[ix], fabs (d__1)); L5: ix += *incx; /* L10: */ } return ret_val; /* code for increment equal to 1 */ L20: dmax__ = fabs (dx[1]); i__1 = *n; for (i__ = 2; i__ <= i__1; ++i__) { if ( (d__1 = dx[i__], fabs (d__1)) <= dmax__) { goto L30; } ret_val = i__; dmax__ = (d__1 = dx[i__], fabs (d__1)); L30: ; } return ret_val; } /* NUMblas_idamax */ #undef MAX #undef MIN /* End of file NUMcblas.c */ praat-6.0.04/dwsys/NUMcblas.h000066400000000000000000001046261261542461700157170ustar00rootroot00000000000000 #ifndef _NUMcblas_h_ #define _NUMcblas_h_ /* NUMcblas.h * * Copyright (C) 1994-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020923 GPL header djmw 20110308 Latest modification */ #define xerbla_(src,info) Melder_throw (Melder_peek8to32 (src), U": parameter ", *info, U"not correct!") int NUMblas_daxpy (long *n, double *da, double *dx, long *incx, double *dy, long *incy); /* constant times a vector plus a vector. uses unrolled loops for increments equal to one. */ int NUMblas_dcopy (long *n, double *dx, long *incx, double *dy, long *incy); /* copies a vector, x, to a vector, y. uses unrolled loops for increments equal to one. */ double NUMblas_ddot (long *n, double *dx, long *incx, double *dy, long *incy); /* forms the dot product of two vectors. uses unrolled loops for increments equal to one. */ int NUMblas_dgemm (const char *transa, const char *transb, long *m, long *n, long *k, double *alpha, double *a, long *lda, double *b, long *ldb, double *beta, double *c, long *ldc); /* Purpose ======= NUMblas_dgemm performs one of the matrix-matrix operations C := alpha*op( A )*op( B ) + beta*C, where op( X ) is one of op( X ) = X or op( X ) = X', alpha and beta are scalars, and A, B and C are matrices, with op( A ) an m by k matrix, op( B ) a k by n matrix and C an m by n matrix. Parameters ========== TRANSA - char*. On entry, TRANSA specifies the form of op( A ) to be used in the matrix multiplication as follows: TRANSA = 'N' or 'n', op( A ) = A. TRANSA = 'T' or 't', op( A ) = A'. TRANSA = 'C' or 'c', op( A ) = A'. Unchanged on exit. TRANSB - char*. On entry, TRANSB specifies the form of op( B ) to be used in the matrix multiplication as follows: TRANSB = 'N' or 'n', op( B ) = B. TRANSB = 'T' or 't', op( B ) = B'. TRANSB = 'C' or 'c', op( B ) = B'. Unchanged on exit. M - long. On entry, M specifies the number of rows of the matrix op( A ) and of the matrix C. M must be at least zero. Unchanged on exit. N - long. On entry, N specifies the number of columns of the matrix op( B ) and the number of columns of the matrix C. N must be at least zero. Unchanged on exit. K - long. On entry, K specifies the number of columns of the matrix op( A ) and the number of rows of the matrix op( B ). K must be at least zero. Unchanged on exit. ALPHA - double. On entry, ALPHA specifies the scalar alpha. Unchanged on exit. A - double array of DIMENSION ( LDA, ka ), where ka is k when TRANSA = 'N' or 'n', and is m otherwise. Before entry with TRANSA = 'N' or 'n', the leading m by k part of the array A must contain the matrix A, otherwise the leading k by m part of the array A must contain the matrix A. Unchanged on exit. LDA - long. On entry, LDA specifies the first dimension of A as declared in the calling (sub) program. When TRANSA = 'N' or 'n' then LDA must be at least max( 1, m ), otherwise LDA must be at least max( 1, k ). Unchanged on exit. B - double array of DIMENSION ( LDB, kb ), where kb is n when TRANSB = 'N' or 'n', and is k otherwise. Before entry with TRANSB = 'N' or 'n', the leading k by n part of the array B must contain the matrix B, otherwise the leading n by k part of the array B must contain the matrix B. Unchanged on exit. LDB - long. On entry, LDB specifies the first dimension of B as declared in the calling (sub) program. When TRANSB = 'N' or 'n' then LDB must be at least max( 1, k ), otherwise LDB must be at least max( 1, n ). Unchanged on exit. BETA - double. On entry, BETA specifies the scalar beta. When BETA is supplied as zero then C need not be set on input. Unchanged on exit. C - double array of DIMENSION ( LDC, n ). Before entry, the leading m by n part of the array C must contain the matrix C, except when beta is zero, in which case C need not be set on entry. On exit, the array C is overwritten by the m by n matrix ( alpha*op( A )*op( B ) + beta*C ). LDC - long. On entry, LDC specifies the first dimension of C as declared in the calling (sub) program. LDC must be at least max( 1, m ). Unchanged on exit. Level 3 Blas routine. -- Written on 8-February-1989. Jack Dongarra, Argonne National Laboratory. Iain Duff, AERE Harwell. Jeremy Du Croz, Numerical Algorithms Group Ltd. Sven Hammarling, Numerical Algorithms Group Ltd. */ int NUMblas_dger (long *m, long *n, double *alpha, double *x, long *incx, double *y, long *incy, double *a, long *lda); /* Purpose ======= NUMblas_dger performs the rank 1 operation A := alpha*x*y' + A, where alpha is a scalar, x is an m element vector, y is an n element vector and A is an m by n matrix. Parameters ========== M - long. On entry, M specifies the number of rows of the matrix A. M must be at least zero. Unchanged on exit. N - long. On entry, N specifies the number of columns of the matrix A. N must be at least zero. Unchanged on exit. ALPHA - double. On entry, ALPHA specifies the scalar alpha. Unchanged on exit. X - double array of dimension at least ( 1 + ( m - 1 )*abs( INCX ) ). Before entry, the incremented array X must contain the m element vector x. Unchanged on exit. INCX - long. On entry, INCX specifies the increment for the elements of X. INCX must not be zero. Unchanged on exit. Y - double array of dimension at least ( 1 + ( n - 1 )*abs( INCY ) ). Before entry, the incremented array Y must contain the n element vector y. Unchanged on exit. INCY - long. On entry, INCY specifies the increment for the elements of Y. INCY must not be zero. Unchanged on exit. A - double array of DIMENSION ( LDA, n ). Before entry, the leading m by n part of the array A must contain the matrix of coefficients. On exit, A is overwritten by the updated matrix. LDA - long. On entry, LDA specifies the first dimension of A as declared in the calling (sub) program. LDA must be at least max( 1, m ). Unchanged on exit. Level 2 Blas routine. -- Written on 22-October-1986. Jack Dongarra, Argonne National Lab. Jeremy Du Croz, Nag Central Office. Sven Hammarling, Nag Central Office. Richard Hanson, Sandia National Labs. */ int NUMblas_dgemv (const char *trans, long *m, long *n, double *alpha, double *a, long *lda, double *x, long *incx, double *beta, double *y, long *incy); /* Purpose ======= NUMblas_dgemv performs one of the matrix-vector operations y := alpha*A*x + beta*y, or y := alpha*A'*x + beta*y, where alpha and beta are scalars, x and y are vectors and A is an m by n matrix. Parameters ========== TRANS - char*. On entry, TRANS specifies the operation to be performed as follows: TRANS = 'N' or 'n' y := alpha*A*x + beta*y. TRANS = 'T' or 't' y := alpha*A'*x + beta*y. TRANS = 'C' or 'c' y := alpha*A'*x + beta*y. Unchanged on exit. M - long. On entry, M specifies the number of rows of the matrix A. M must be at least zero. Unchanged on exit. N - long. On entry, N specifies the number of columns of the matrix A. N must be at least zero. Unchanged on exit. ALPHA - double. On entry, ALPHA specifies the scalar alpha. Unchanged on exit. A - double array of DIMENSION ( LDA, n ). Before entry, the leading m by n part of the array A must contain the matrix of coefficients. Unchanged on exit. LDA - long. On entry, LDA specifies the first dimension of A as declared in the calling (sub) program. LDA must be at least max( 1, m ). Unchanged on exit. X - double array of DIMENSION at least ( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n' and at least ( 1 + ( m - 1 )*abs( INCX ) ) otherwise. Before entry, the incremented array X must contain the vector x. Unchanged on exit. INCX - long. On entry, INCX specifies the increment for the elements of X. INCX must not be zero. Unchanged on exit. BETA - double. On entry, BETA specifies the scalar beta. When BETA is supplied as zero then Y need not be set on input. Unchanged on exit. Y - double array of DIMENSION at least ( 1 + ( m - 1 )*abs( INCY ) ) when TRANS = 'N' or 'n' and at least ( 1 + ( n - 1 )*abs( INCY ) ) otherwise. Before entry with BETA non-zero, the incremented array Y must contain the vector y. On exit, Y is overwritten by the updated vector y. INCY - long. On entry, INCY specifies the increment for the elements of Y. INCY must not be zero. Unchanged on exit. Level 2 Blas routine. -- Written on 22-October-1986. Jack Dongarra, Argonne National Lab. Jeremy Du Croz, Nag Central Office. Sven Hammarling, Nag Central Office. Richard Hanson, Sandia National Labs. */ double NUMblas_dlamch (const char *cmach); /* Purpose ======= NUMblas_dlamch determines double machine parameters. Arguments ========= CMACH (input) char* Specifies the value to be returned by DLAMCH: = 'E' or 'e', DLAMCH := eps = 'S' or 's , DLAMCH := sfmin = 'B' or 'b', DLAMCH := base = 'P' or 'p', DLAMCH := eps*base = 'N' or 'n', DLAMCH := t = 'R' or 'r', DLAMCH := rnd = 'M' or 'm', DLAMCH := emin = 'U' or 'u', DLAMCH := rmin = 'L' or 'l', DLAMCH := emax = 'O' or 'o', DLAMCH := rmax where eps = relative machine precision sfmin = safe minimum, such that 1/sfmin does not overflow base = base of the machine prec = eps*base t = number of (base) digits in the mantissa rnd = 1.0 when rounding occurs in addition, 0.0 otherwise emin = minimum exponent before (gradual) underflow rmin = underflow threshold - base**(emin-1) emax = largest exponent before overflow rmax = overflow threshold - (base**emax)*(1-eps) ===================================================================== */ double NUMblas_dnrm2 (long *n, double *x, long *incx); /* NUMblas_dnrm2 returns the euclidean norm of a vector via the function name, so that DNRM2 := sqrt( x'*x ) -- This version written on 25-October-1982. Modified on 14-October-1993 to inline the call to DLASSQ. Sven Hammarling, Nag Ltd. Parameter adjustments */ int NUMblas_drot (long *n, double *dx, long *incx, double *dy, long *incy, double *c__, double *s); /* applies a plane rotation. */ int NUMblas_dscal (long *n, double *da, double *dx, long *incx); /* scales a vector by a constant. uses unrolled loops for increment equal to one. */ int NUMblas_dswap (long *n, double *dx, long *incx, double *dy, long *incy); /* interchanges two vectors. uses unrolled loops for increments equal one. */ int NUMblas_dsymv (const char *uplo, long *n, double *alpha, double *a, long *lda, double *x, long *incx, double *beta, double *y, long *incy); /* Purpose ======= NUMblas_dsymv performs the matrix-vector operation y := alpha*A*x + beta*y, where alpha and beta are scalars, x and y are n element vectors and A is an n by n symmetric matrix. Parameters ========== UPLO - char*. On entry, UPLO specifies whether the upper or lower triangular part of the array A is to be referenced as follows: UPLO = 'U' or 'u' Only the upper triangular part of A is to be referenced. UPLO = 'L' or 'l' Only the lower triangular part of A is to be referenced. Unchanged on exit. N - long. On entry, N specifies the order of the matrix A. N must be at least zero. Unchanged on exit. ALPHA - double. On entry, ALPHA specifies the scalar alpha. Unchanged on exit. A - double array of DIMENSION ( LDA, n ). Before entry with UPLO = 'U' or 'u', the leading n by n upper triangular part of the array A must contain the upper triangular part of the symmetric matrix and the strictly lower triangular part of A is not referenced. Before entry with UPLO = 'L' or 'l', the leading n by n lower triangular part of the array A must contain the lower triangular part of the symmetric matrix and the strictly upper triangular part of A is not referenced. Unchanged on exit. LDA - long. On entry, LDA specifies the first dimension of A as declared in the calling (sub) program. LDA must be at least max( 1, n ). Unchanged on exit. X - double array of dimension at least ( 1 + ( n - 1 )*abs( INCX ) ). Before entry, the incremented array X must contain the n element vector x. Unchanged on exit. INCX - long. On entry, INCX specifies the increment for the elements of X. INCX must not be zero. Unchanged on exit. BETA - double. On entry, BETA specifies the scalar beta. When BETA is supplied as zero then Y need not be set on input. Unchanged on exit. Y - double array of dimension at least ( 1 + ( n - 1 )*abs( INCY ) ). Before entry, the incremented array Y must contain the n element vector y. On exit, Y is overwritten by the updated vector y. INCY - long. On entry, INCY specifies the increment for the elements of Y. INCY must not be zero. Unchanged on exit. */ int NUMblas_dsyr2 (const char *uplo, long *n, double *alpha, double *x, long *incx, double *y, long *incy, double *a, long *lda); /* Purpose ======= NUMblas_dsyr2 performs the symmetric rank 2 operation A := alpha*x*y' + alpha*y*x' + A, where alpha is a scalar, x and y are n element vectors and A is an n by n symmetric matrix. Parameters ========== UPLO - char*. On entry, UPLO specifies whether the upper or lower triangular part of the array A is to be referenced as follows: UPLO = 'U' or 'u' Only the upper triangular part of A is to be referenced. UPLO = 'L' or 'l' Only the lower triangular part of A is to be referenced. Unchanged on exit. N - long. On entry, N specifies the order of the matrix A. N must be at least zero. Unchanged on exit. ALPHA - double. On entry, ALPHA specifies the scalar alpha. Unchanged on exit. X - double array of dimension at least ( 1 + ( n - 1 )*abs( INCX ) ). Before entry, the incremented array X must contain the n element vector x. Unchanged on exit. INCX - long. On entry, INCX specifies the increment for the elements of X. INCX must not be zero. Unchanged on exit. Y - double array of dimension at least ( 1 + ( n - 1 )*abs( INCY ) ). Before entry, the incremented array Y must contain the n element vector y. Unchanged on exit. INCY - long. On entry, INCY specifies the increment for the elements of Y. INCY must not be zero. Unchanged on exit. A - double array of DIMENSION ( LDA, n ). Before entry with UPLO = 'U' or 'u', the leading n by n upper triangular part of the array A must contain the upper triangular part of the symmetric matrix and the strictly lower triangular part of A is not referenced. On exit, the upper triangular part of the array A is overwritten by the upper triangular part of the updated matrix. Before entry with UPLO = 'L' or 'l', the leading n by n lower triangular part of the array A must contain the lower triangular part of the symmetric matrix and the strictly upper triangular part of A is not referenced. On exit, the lower triangular part of the array A is overwritten by the lower triangular part of the updated matrix. LDA - long. On entry, LDA specifies the first dimension of A as declared in the calling (sub) program. LDA must be at least max( 1, n ). Unchanged on exit. */ int NUMblas_dsyr2k (const char *uplo, const char *trans, long *n, long *k, double *alpha, double *a, long *lda, double *b, long *ldb, double *beta, double *c, long *ldc); /* Purpose ======= NUMblas_dsyr2k performs one of the symmetric rank 2k operations C := alpha*A*B' + alpha*B*A' + beta*C, or C := alpha*A'*B + alpha*B'*A + beta*C, where alpha and beta are scalars, C is an n by n symmetric matrix and A and B are n by k matrices in the first case and k by n matrices in the second case. Parameters ========== UPLO - char*. On entry, UPLO specifies whether the upper or lower triangular part of the array C is to be referenced as follows: UPLO = 'U' or 'u' Only the upper triangular part of C is to be referenced. UPLO = 'L' or 'l' Only the lower triangular part of C is to be referenced. Unchanged on exit. TRANS - char*. On entry, TRANS specifies the operation to be performed as follows: TRANS = 'N' or 'n' C := alpha*A*B' + alpha*B*A' + beta*C. TRANS = 'T' or 't' C := alpha*A'*B + alpha*B'*A + beta*C. TRANS = 'C' or 'c' C := alpha*A'*B + alpha*B'*A + beta*C. Unchanged on exit. N - long. On entry, N specifies the order of the matrix C. N must be at least zero. Unchanged on exit. K - long. On entry with TRANS = 'N' or 'n', K specifies the number of columns of the matrices A and B, and on entry with TRANS = 'T' or 't' or 'C' or 'c', K specifies the number of rows of the matrices A and B. K must be at least zero. Unchanged on exit. ALPHA - double. On entry, ALPHA specifies the scalar alpha. Unchanged on exit. A - double array of DIMENSION ( LDA, ka ), where ka is k when TRANS = 'N' or 'n', and is n otherwise. Before entry with TRANS = 'N' or 'n', the leading n by k part of the array A must contain the matrix A, otherwise the leading k by n part of the array A must contain the matrix A. Unchanged on exit. LDA - long. On entry, LDA specifies the first dimension of A as declared in the calling (sub) program. When TRANS = 'N' or 'n' then LDA must be at least max( 1, n ), otherwise LDA must be at least max( 1, k ). Unchanged on exit. B - double array of DIMENSION ( LDB, kb ), where kb is k when TRANS = 'N' or 'n', and is n otherwise. Before entry with TRANS = 'N' or 'n', the leading n by k part of the array B must contain the matrix B, otherwise the leading k by n part of the array B must contain the matrix B. Unchanged on exit. LDB - long. On entry, LDB specifies the first dimension of B as declared in the calling (sub) program. When TRANS = 'N' or 'n' then LDB must be at least max( 1, n ), otherwise LDB must be at least max( 1, k ). Unchanged on exit. BETA - double. On entry, BETA specifies the scalar beta. Unchanged on exit. C - double array of DIMENSION ( LDC, n ). Before entry with UPLO = 'U' or 'u', the leading n by n upper triangular part of the array C must contain the upper triangular part of the symmetric matrix and the strictly lower triangular part of C is not referenced. On exit, the upper triangular part of the array C is overwritten by the upper triangular part of the updated matrix. Before entry with UPLO = 'L' or 'l', the leading n by n lower triangular part of the array C must contain the lower triangular part of the symmetric matrix and the strictly upper triangular part of C is not referenced. On exit, the lower triangular part of the array C is overwritten by the lower triangular part of the updated matrix. LDC - long. On entry, LDC specifies the first dimension of C as declared in the calling (sub) program. LDC must be at least max( 1, n ). Unchanged on exit. Level 3 Blas routine. */ int NUMblas_dtrmm (const char *side, const char *uplo, const char *transa, const char *diag, long *m, long *n, double *alpha, double *a, long *lda, double *b, long *ldb); /* Purpose ======= NUMblas_dtrmm performs one of the matrix-matrix operations B := alpha*op( A )*B, or B := alpha*B*op( A ), where alpha is a scalar, B is an m by n matrix, A is a unit, or non-unit, upper or lower triangular matrix and op( A ) is one of op( A ) = A or op( A ) = A'. Parameters ========== SIDE - char*. On entry, SIDE specifies whether op( A ) multiplies B from the left or right as follows: SIDE = 'L' or 'l' B := alpha*op( A )*B. SIDE = 'R' or 'r' B := alpha*B*op( A ). Unchanged on exit. UPLO - char*. On entry, UPLO specifies whether the matrix A is an upper or lower triangular matrix as follows: UPLO = 'U' or 'u' A is an upper triangular matrix. UPLO = 'L' or 'l' A is a lower triangular matrix. Unchanged on exit. TRANSA - char*. On entry, TRANSA specifies the form of op( A ) to be used in the matrix multiplication as follows: TRANSA = 'N' or 'n' op( A ) = A. TRANSA = 'T' or 't' op( A ) = A'. TRANSA = 'C' or 'c' op( A ) = A'. Unchanged on exit. DIAG - char*. On entry, DIAG specifies whether or not A is unit triangular as follows: DIAG = 'U' or 'u' A is assumed to be unit triangular. DIAG = 'N' or 'n' A is not assumed to be unit triangular. Unchanged on exit. M - long. On entry, M specifies the number of rows of B. M must be at least zero. Unchanged on exit. N - long. On entry, N specifies the number of columns of B. N must be at least zero. Unchanged on exit. ALPHA - double. On entry, ALPHA specifies the scalar alpha. When alpha is zero then A is not referenced and B need not be set before entry. Unchanged on exit. A - double array of DIMENSION ( LDA, k ), where k is m when SIDE = 'L' or 'l' and is n when SIDE = 'R' or 'r'. Before entry with UPLO = 'U' or 'u', the leading k by k upper triangular part of the array A must contain the upper triangular matrix and the strictly lower triangular part of A is not referenced. Before entry with UPLO = 'L' or 'l', the leading k by k lower triangular part of the array A must contain the lower triangular matrix and the strictly upper triangular part of A is not referenced. Note that when DIAG = 'U' or 'u', the diagonal elements of A are not referenced either, but are assumed to be unity. Unchanged on exit. LDA - long. On entry, LDA specifies the first dimension of A as declared in the calling (sub) program. When SIDE = 'L' or 'l' then LDA must be at least max( 1, m ), when SIDE = 'R' or 'r' then LDA must be at least max( 1, n ). Unchanged on exit. B - double array of DIMENSION ( LDB, n ). Before entry, the leading m by n part of the array B must contain the matrix B, and on exit is overwritten by the transformed matrix. LDB - long. On entry, LDB specifies the first dimension of B as declared in the calling (sub) program. LDB must be at least max( 1, m ). Unchanged on exit. Level 3 Blas routine. */ int NUMblas_dtrmv (const char *uplo, const char *trans, const char *diag, long *n, double *a, long *lda, double *x, long *incx); /* Purpose ======= NUMblas_dtrmv performs one of the matrix-vector operations x := A*x, or x := A'*x, where x is an n element vector and A is an n by n unit, or non-unit, upper or lower triangular matrix. Parameters ========== UPLO - char*. On entry, UPLO specifies whether the matrix is an upper or lower triangular matrix as follows: UPLO = 'U' or 'u' A is an upper triangular matrix. UPLO = 'L' or 'l' A is a lower triangular matrix. Unchanged on exit. TRANS - char*. On entry, TRANS specifies the operation to be performed as follows: TRANS = 'N' or 'n' x := A*x. TRANS = 'T' or 't' x := A'*x. TRANS = 'C' or 'c' x := A'*x. Unchanged on exit. DIAG - char*. On entry, DIAG specifies whether or not A is unit triangular as follows: DIAG = 'U' or 'u' A is assumed to be unit triangular. DIAG = 'N' or 'n' A is not assumed to be unit triangular. Unchanged on exit. N - long. On entry, N specifies the order of the matrix A. N must be at least zero. Unchanged on exit. A - double array of DIMENSION ( LDA, n ). Before entry with UPLO = 'U' or 'u', the leading n by n upper triangular part of the array A must contain the upper triangular matrix and the strictly lower triangular part of A is not referenced. Before entry with UPLO = 'L' or 'l', the leading n by n lower triangular part of the array A must contain the lower triangular matrix and the strictly upper triangular part of A is not referenced. Note that when DIAG = 'U' or 'u', the diagonal elements of A are not referenced either, but are assumed to be unity. Unchanged on exit. LDA - long. On entry, LDA specifies the first dimension of A as declared in the calling (sub) program. LDA must be at least max( 1, n ). Unchanged on exit. X - double array of dimension at least ( 1 + ( n - 1 )*abs( INCX ) ). Before entry, the incremented array X must contain the n element vector x. On exit, X is overwritten with the tranformed vector x. INCX - long. On entry, INCX specifies the increment for the elements of X. INCX must not be zero. Unchanged on exit. Level 2 Blas routine. */ int NUMblas_dtrsm (const char *side, const char *uplo, const char *transa, const char *diag, long *m, long *n, double *alpha, double *a, long *lda, double *b, long *ldb); /* Purpose ======= NUMblas_dtrsm solves one of the matrix equations op( A )*X = alpha*B, or X*op( A ) = alpha*B, where alpha is a scalar, X and B are m by n matrices, A is a unit, or non-unit, upper or lower triangular matrix and op( A ) is one of op( A ) = A or op( A ) = A'. The matrix X is overwritten on B. Parameters ========== SIDE - char*. On entry, SIDE specifies whether op( A ) appears on the left or right of X as follows: SIDE = 'L' or 'l' op( A )*X = alpha*B. SIDE = 'R' or 'r' X*op( A ) = alpha*B. Unchanged on exit. UPLO - char*. On entry, UPLO specifies whether the matrix A is an upper or lower triangular matrix as follows: UPLO = 'U' or 'u' A is an upper triangular matrix. UPLO = 'L' or 'l' A is a lower triangular matrix. Unchanged on exit. TRANSA - char*. On entry, TRANSA specifies the form of op( A ) to be used in the matrix multiplication as follows: TRANSA = 'N' or 'n' op( A ) = A. TRANSA = 'T' or 't' op( A ) = A'. TRANSA = 'C' or 'c' op( A ) = A'. Unchanged on exit. DIAG - char*. On entry, DIAG specifies whether or not A is unit triangular as follows: DIAG = 'U' or 'u' A is assumed to be unit triangular. DIAG = 'N' or 'n' A is not assumed to be unit triangular. Unchanged on exit. M - long. On entry, M specifies the number of rows of B. M must be at least zero. Unchanged on exit. N - long. On entry, N specifies the number of columns of B. N must be at least zero. Unchanged on exit. ALPHA - double. On entry, ALPHA specifies the scalar alpha. When alpha is zero then A is not referenced and B need not be set before entry. Unchanged on exit. A - double array of DIMENSION ( LDA, k ), where k is m when SIDE = 'L' or 'l' and is n when SIDE = 'R' or 'r'. Before entry with UPLO = 'U' or 'u', the leading k by k upper triangular part of the array A must contain the upper triangular matrix and the strictly lower triangular part of A is not referenced. Before entry with UPLO = 'L' or 'l', the leading k by k lower triangular part of the array A must contain the lower triangular matrix and the strictly upper triangular part of A is not referenced. Note that when DIAG = 'U' or 'u', the diagonal elements of A are not referenced either, but are assumed to be unity. Unchanged on exit. LDA - long. On entry, LDA specifies the first dimension of A as declared in the calling (sub) program. When SIDE = 'L' or 'l' then LDA must be at least max( 1, m ), when SIDE = 'R' or 'r' then LDA must be at least max( 1, n ). Unchanged on exit. B - double array of DIMENSION ( LDB, n ). Before entry, the leading m by n part of the array B must contain the right-hand side matrix B, and on exit is overwritten by the solution matrix X. LDB - long. On entry, LDB specifies the first dimension of B as declared in the calling (sub) program. LDB must be at least max( 1, m ). Unchanged on exit. */ long NUMblas_idamax (long *n, double *dx, long *incx); /* finds the index of element having max. absolute value.*/ #endif /* _NUMcblas_h_ */ praat-6.0.04/dwsys/NUMclapack.cpp000066400000000000000000017547131261542461700165750ustar00rootroot00000000000000/* NUMclapack.c */ /* -- LAPACK driver routines (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University October 31, 1999 -- translated by f2c (version 19990503). Adapted by David Weenink 20021201 djmw 20030205 Latest modification */ /* #include "blaswrap.h" */ #include "NUMf2c.h" #include "NUMclapack.h" #include "NUMcblas.h" #include "NUM2.h" #include "melder.h" /* Table of constant values */ static long c__0 = 0; static long c__1 = 1; static long c_n1 = -1; static long c__2 = 2; static long c__3 = 3; static long c__4 = 4; static long c__6 = 6; static long c__10 = 10; static long c__11 = 11; static double c_b15 = -.125; static double c_b49 = 1.; static double c_b72 = -1.; static double c_b74 = 0.; static double c_b108 = 1.; static double c_b416 = 0.; static double c_b438 = 1.; #define MAX(m,n) ((m) > (n) ? (m) : (n)) #define MIN(m,n) ((m) < (n) ? (m) : (n)) #define a_ref(a_1,a_2) a[(a_2)*a_dim1 + a_1] #define c___ref(a_1,a_2) c__[(a_2)*c_dim1 + a_1] /* --------------------------------------------------- */ #define u_ref(a_1,a_2) u[(a_2)*u_dim1 + a_1] #define vt_ref(a_1,a_2) vt[(a_2)*vt_dim1 + a_1] int NUMlapack_dbdsqr (const char *uplo, long *n, long *ncvt, long *nru, long *ncc, double *d__, double *e, double *vt, long *ldvt, double *u, long *ldu, double *c__, long *ldc, double *work, long *info) { /* System generated locals */ long c_dim1, c_offset, u_dim1, u_offset, vt_dim1, vt_offset, i__1, i__2; double d__1, d__2, d__3, d__4; /* Local variables */ static double abse; static long idir; static double abss; static long oldm; static double cosl; static long isub, iter; static double unfl, sinl, cosr, smin, smax, sinr; static double f, g, h__; static long i__, j, m; static double r__; static double oldcs; static long oldll; static double shift, sigmn, oldsn; static long maxit; static double sminl, sigmx; static long lower; static double cs; static long ll; static double sn, mu; static double sminoa, thresh; static long rotate; static double sminlo; static long nm1; static double tolmul; static long nm12, nm13, lll; static double eps, sll, tol; /* Parameter adjustments */ --d__; --e; vt_dim1 = *ldvt; vt_offset = 1 + vt_dim1 * 1; vt -= vt_offset; u_dim1 = *ldu; u_offset = 1 + u_dim1 * 1; u -= u_offset; c_dim1 = *ldc; c_offset = 1 + c_dim1 * 1; c__ -= c_offset; --work; /* Function Body */ *info = 0; lower = lsame_ (uplo, "L"); if (!lsame_ (uplo, "U") && !lower) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*ncvt < 0) { *info = -3; } else if (*nru < 0) { *info = -4; } else if (*ncc < 0) { *info = -5; } else if (*ncvt == 0 && *ldvt < 1 || *ncvt > 0 && *ldvt < MAX (1, *n)) { *info = -9; } else if (*ldu < MAX (1, *nru)) { *info = -11; } else if (*ncc == 0 && *ldc < 1 || *ncc > 0 && *ldc < MAX (1, *n)) { *info = -13; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DBDSQR", &i__1); return 0; } if (*n == 0) { return 0; } if (*n == 1) { goto L160; } /* ROTATE is true if any singular vectors desired, false otherwise */ rotate = *ncvt > 0 || *nru > 0 || *ncc > 0; /* If no singular vectors desired, use qd algorithm */ if (!rotate) { NUMlapack_dlasq1 (n, &d__[1], &e[1], &work[1], info); return 0; } nm1 = *n - 1; nm12 = nm1 + nm1; nm13 = nm12 + nm1; idir = 0; /* Get machine constants */ eps = NUMblas_dlamch ("Epsilon"); unfl = NUMblas_dlamch ("Safe minimum"); /* If matrix lower bidiagonal, rotate to be upper bidiagonal by applying Givens rotations on the left */ if (lower) { i__1 = *n - 1; for (i__ = 1; i__ <= i__1; ++i__) { NUMlapack_dlartg (&d__[i__], &e[i__], &cs, &sn, &r__); d__[i__] = r__; e[i__] = sn * d__[i__ + 1]; d__[i__ + 1] = cs * d__[i__ + 1]; work[i__] = cs; work[nm1 + i__] = sn; /* L10: */ } /* Update singular vectors if desired */ if (*nru > 0) { NUMlapack_dlasr ("R", "V", "F", nru, n, &work[1], &work[*n], &u[u_offset], ldu); } if (*ncc > 0) { NUMlapack_dlasr ("L", "V", "F", n, ncc, &work[1], &work[*n], &c__[c_offset], ldc); } } /* Compute singular values to relative accuracy TOL (By setting TOL to be negative, algorithm will compute singular values to absolute accuracy ABS(TOL)*norm(input matrix)) Computing MAX Computing MIN */ d__3 = 100., d__4 = pow (eps, c_b15); d__1 = 10., d__2 = MIN (d__3, d__4); tolmul = MAX (d__1, d__2); tol = tolmul * eps; /* Compute approximate maximum, minimum singular values */ smax = 0.; i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { /* Computing MAX */ d__2 = smax, d__3 = (d__1 = d__[i__], fabs (d__1)); smax = MAX (d__2, d__3); /* L20: */ } i__1 = *n - 1; for (i__ = 1; i__ <= i__1; ++i__) { /* Computing MAX */ d__2 = smax, d__3 = (d__1 = e[i__], fabs (d__1)); smax = MAX (d__2, d__3); /* L30: */ } sminl = 0.; if (tol >= 0.) { /* Relative accuracy desired */ sminoa = fabs (d__[1]); if (sminoa == 0.) { goto L50; } mu = sminoa; i__1 = *n; for (i__ = 2; i__ <= i__1; ++i__) { mu = (d__2 = d__[i__], fabs (d__2)) * (mu / (mu + (d__1 = e[i__ - 1], fabs (d__1)))); sminoa = MIN (sminoa, mu); if (sminoa == 0.) { goto L50; } /* L40: */ } L50: sminoa /= sqrt ( (double) (*n)); /* Computing MAX */ d__1 = tol * sminoa, d__2 = *n * 6 * *n * unfl; thresh = MAX (d__1, d__2); } else { /* Absolute accuracy desired Computing MAX */ d__1 = fabs (tol) * smax, d__2 = *n * 6 * *n * unfl; thresh = MAX (d__1, d__2); } /* Prepare for main iteration loop for the singular values (MAXIT is the maximum number of passes through the inner loop permitted before nonconvergence signalled.) */ maxit = *n * 6 * *n; iter = 0; oldll = -1; oldm = -1; /* M points to last element of unconverged part of matrix */ m = *n; /* Begin main iteration loop */ L60: /* Check for convergence or exceeding iteration count */ if (m <= 1) { goto L160; } if (iter > maxit) { goto L200; } /* Find diagonal block of matrix to work on */ if (tol < 0. && (d__1 = d__[m], fabs (d__1)) <= thresh) { d__[m] = 0.; } smax = (d__1 = d__[m], fabs (d__1)); smin = smax; i__1 = m - 1; for (lll = 1; lll <= i__1; ++lll) { ll = m - lll; abss = (d__1 = d__[ll], fabs (d__1)); abse = (d__1 = e[ll], fabs (d__1)); if (tol < 0. && abss <= thresh) { d__[ll] = 0.; } if (abse <= thresh) { goto L80; } smin = MIN (smin, abss); /* Computing MAX */ d__1 = MAX (smax, abss); smax = MAX (d__1, abse); /* L70: */ } ll = 0; goto L90; L80: e[ll] = 0.; /* Matrix splits since E(LL) = 0 */ if (ll == m - 1) { /* Convergence of bottom singular value, return to top of loop */ --m; goto L60; } L90: ++ll; /* E(LL) through E(M-1) are nonzero, E(LL-1) is zero */ if (ll == m - 1) { /* 2 by 2 block, handle separately */ NUMlapack_dlasv2 (&d__[m - 1], &e[m - 1], &d__[m], &sigmn, &sigmx, &sinr, &cosr, &sinl, &cosl); d__[m - 1] = sigmx; e[m - 1] = 0.; d__[m] = sigmn; /* Compute singular vectors, if desired */ if (*ncvt > 0) { NUMblas_drot (ncvt, &vt_ref (m - 1, 1), ldvt, &vt_ref (m, 1), ldvt, &cosr, &sinr); } if (*nru > 0) { NUMblas_drot (nru, &u_ref (1, m - 1), &c__1, &u_ref (1, m), &c__1, &cosl, &sinl); } if (*ncc > 0) { NUMblas_drot (ncc, &c___ref (m - 1, 1), ldc, &c___ref (m, 1), ldc, &cosl, &sinl); } m += -2; goto L60; } /* If working on new submatrix, choose shift direction (from larger end diagonal element towards smaller) */ if (ll > oldm || m < oldll) { if ( (d__1 = d__[ll], fabs (d__1)) >= (d__2 = d__[m], fabs (d__2))) { /* Chase bulge from top (big end) to bottom (small end) */ idir = 1; } else { /* Chase bulge from bottom (big end) to top (small end) */ idir = 2; } } /* Apply convergence tests */ if (idir == 1) { /* Run convergence test in forward direction First apply standard test to bottom of matrix */ if ( (d__2 = e[m - 1], fabs (d__2)) <= fabs (tol) * (d__1 = d__[m], fabs (d__1)) || tol < 0. && (d__3 = e[m - 1], fabs (d__3)) <= thresh) { e[m - 1] = 0.; goto L60; } if (tol >= 0.) { /* If relative accuracy desired, apply convergence criterion forward */ mu = (d__1 = d__[ll], fabs (d__1)); sminl = mu; i__1 = m - 1; for (lll = ll; lll <= i__1; ++lll) { if ( (d__1 = e[lll], fabs (d__1)) <= tol * mu) { e[lll] = 0.; goto L60; } sminlo = sminl; mu = (d__2 = d__[lll + 1], fabs (d__2)) * (mu / (mu + (d__1 = e[lll], fabs (d__1)))); sminl = MIN (sminl, mu); /* L100: */ } } } else { /* Run convergence test in backward direction First apply standard test to top of matrix */ if ( (d__2 = e[ll], fabs (d__2)) <= fabs (tol) * (d__1 = d__[ll], fabs (d__1)) || tol < 0. && (d__3 = e[ll], fabs (d__3)) <= thresh) { e[ll] = 0.; goto L60; } if (tol >= 0.) { /* If relative accuracy desired, apply convergence criterion backward */ mu = (d__1 = d__[m], fabs (d__1)); sminl = mu; i__1 = ll; for (lll = m - 1; lll >= i__1; --lll) { if ( (d__1 = e[lll], fabs (d__1)) <= tol * mu) { e[lll] = 0.; goto L60; } sminlo = sminl; mu = (d__2 = d__[lll], fabs (d__2)) * (mu / (mu + (d__1 = e[lll], fabs (d__1)))); sminl = MIN (sminl, mu); /* L110: */ } } } oldll = ll; oldm = m; /* Compute shift. First, test if shifting would ruin relative accuracy, and if so set the shift to zero. Computing MAX */ d__1 = eps, d__2 = tol * .01; if (tol >= 0. && *n * tol * (sminl / smax) <= MAX (d__1, d__2)) { /* Use a zero shift to avoid loss of relative accuracy */ shift = 0.; } else { /* Compute the shift from 2-by-2 block at end of matrix */ if (idir == 1) { sll = (d__1 = d__[ll], fabs (d__1)); NUMlapack_dlas2 (&d__[m - 1], &e[m - 1], &d__[m], &shift, &r__); } else { sll = (d__1 = d__[m], fabs (d__1)); NUMlapack_dlas2 (&d__[ll], &e[ll], &d__[ll + 1], &shift, &r__); } /* Test if shift negligible, and if so set to zero */ if (sll > 0.) { /* Computing 2nd power */ d__1 = shift / sll; if (d__1 * d__1 < eps) { shift = 0.; } } } /* Increment iteration count */ iter = iter + m - ll; /* If SHIFT = 0, do simplified QR iteration */ if (shift == 0.) { if (idir == 1) { /* Chase bulge from top to bottom Save cosines and sines for later singular vector updates */ cs = 1.; oldcs = 1.; i__1 = m - 1; for (i__ = ll; i__ <= i__1; ++i__) { d__1 = d__[i__] * cs; NUMlapack_dlartg (&d__1, &e[i__], &cs, &sn, &r__); if (i__ > ll) { e[i__ - 1] = oldsn * r__; } d__1 = oldcs * r__; d__2 = d__[i__ + 1] * sn; NUMlapack_dlartg (&d__1, &d__2, &oldcs, &oldsn, &d__[i__]); work[i__ - ll + 1] = cs; work[i__ - ll + 1 + nm1] = sn; work[i__ - ll + 1 + nm12] = oldcs; work[i__ - ll + 1 + nm13] = oldsn; /* L120: */ } h__ = d__[m] * cs; d__[m] = h__ * oldcs; e[m - 1] = h__ * oldsn; /* Update singular vectors */ if (*ncvt > 0) { i__1 = m - ll + 1; NUMlapack_dlasr ("L", "V", "F", &i__1, ncvt, &work[1], &work[*n], &vt_ref (ll, 1), ldvt); } if (*nru > 0) { i__1 = m - ll + 1; NUMlapack_dlasr ("R", "V", "F", nru, &i__1, &work[nm12 + 1], &work[nm13 + 1], &u_ref (1, ll), ldu); } if (*ncc > 0) { i__1 = m - ll + 1; NUMlapack_dlasr ("L", "V", "F", &i__1, ncc, &work[nm12 + 1], &work[nm13 + 1], &c___ref (ll, 1), ldc); } /* Test convergence */ if ( (d__1 = e[m - 1], fabs (d__1)) <= thresh) { e[m - 1] = 0.; } } else { /* Chase bulge from bottom to top Save cosines and sines for later singular vector updates */ cs = 1.; oldcs = 1.; i__1 = ll + 1; for (i__ = m; i__ >= i__1; --i__) { d__1 = d__[i__] * cs; NUMlapack_dlartg (&d__1, &e[i__ - 1], &cs, &sn, &r__); if (i__ < m) { e[i__] = oldsn * r__; } d__1 = oldcs * r__; d__2 = d__[i__ - 1] * sn; NUMlapack_dlartg (&d__1, &d__2, &oldcs, &oldsn, &d__[i__]); work[i__ - ll] = cs; work[i__ - ll + nm1] = -sn; work[i__ - ll + nm12] = oldcs; work[i__ - ll + nm13] = -oldsn; /* L130: */ } h__ = d__[ll] * cs; d__[ll] = h__ * oldcs; e[ll] = h__ * oldsn; /* Update singular vectors */ if (*ncvt > 0) { i__1 = m - ll + 1; NUMlapack_dlasr ("L", "V", "B", &i__1, ncvt, &work[nm12 + 1], &work[nm13 + 1], &vt_ref (ll, 1), ldvt); } if (*nru > 0) { i__1 = m - ll + 1; NUMlapack_dlasr ("R", "V", "B", nru, &i__1, &work[1], &work[*n], &u_ref (1, ll), ldu); } if (*ncc > 0) { i__1 = m - ll + 1; NUMlapack_dlasr ("L", "V", "B", &i__1, ncc, &work[1], &work[*n], &c___ref (ll, 1), ldc); } /* Test convergence */ if ( (d__1 = e[ll], fabs (d__1)) <= thresh) { e[ll] = 0.; } } } else { /* Use nonzero shift */ if (idir == 1) { /* Chase bulge from top to bottom Save cosines and sines for later singular vector updates */ f = ( (d__1 = d__[ll], fabs (d__1)) - shift) * (d_sign (&c_b49, &d__[ll]) + shift / d__[ll]); g = e[ll]; i__1 = m - 1; for (i__ = ll; i__ <= i__1; ++i__) { NUMlapack_dlartg (&f, &g, &cosr, &sinr, &r__); if (i__ > ll) { e[i__ - 1] = r__; } f = cosr * d__[i__] + sinr * e[i__]; e[i__] = cosr * e[i__] - sinr * d__[i__]; g = sinr * d__[i__ + 1]; d__[i__ + 1] = cosr * d__[i__ + 1]; NUMlapack_dlartg (&f, &g, &cosl, &sinl, &r__); d__[i__] = r__; f = cosl * e[i__] + sinl * d__[i__ + 1]; d__[i__ + 1] = cosl * d__[i__ + 1] - sinl * e[i__]; if (i__ < m - 1) { g = sinl * e[i__ + 1]; e[i__ + 1] = cosl * e[i__ + 1]; } work[i__ - ll + 1] = cosr; work[i__ - ll + 1 + nm1] = sinr; work[i__ - ll + 1 + nm12] = cosl; work[i__ - ll + 1 + nm13] = sinl; /* L140: */ } e[m - 1] = f; /* Update singular vectors */ if (*ncvt > 0) { i__1 = m - ll + 1; NUMlapack_dlasr ("L", "V", "F", &i__1, ncvt, &work[1], &work[*n], &vt_ref (ll, 1), ldvt); } if (*nru > 0) { i__1 = m - ll + 1; NUMlapack_dlasr ("R", "V", "F", nru, &i__1, &work[nm12 + 1], &work[nm13 + 1], &u_ref (1, ll), ldu); } if (*ncc > 0) { i__1 = m - ll + 1; NUMlapack_dlasr ("L", "V", "F", &i__1, ncc, &work[nm12 + 1], &work[nm13 + 1], &c___ref (ll, 1), ldc); } /* Test convergence */ if ( (d__1 = e[m - 1], fabs (d__1)) <= thresh) { e[m - 1] = 0.; } } else { /* Chase bulge from bottom to top Save cosines and sines for later singular vector updates */ f = ( (d__1 = d__[m], fabs (d__1)) - shift) * (d_sign (&c_b49, &d__[m]) + shift / d__[m]); g = e[m - 1]; i__1 = ll + 1; for (i__ = m; i__ >= i__1; --i__) { NUMlapack_dlartg (&f, &g, &cosr, &sinr, &r__); if (i__ < m) { e[i__] = r__; } f = cosr * d__[i__] + sinr * e[i__ - 1]; e[i__ - 1] = cosr * e[i__ - 1] - sinr * d__[i__]; g = sinr * d__[i__ - 1]; d__[i__ - 1] = cosr * d__[i__ - 1]; NUMlapack_dlartg (&f, &g, &cosl, &sinl, &r__); d__[i__] = r__; f = cosl * e[i__ - 1] + sinl * d__[i__ - 1]; d__[i__ - 1] = cosl * d__[i__ - 1] - sinl * e[i__ - 1]; if (i__ > ll + 1) { g = sinl * e[i__ - 2]; e[i__ - 2] = cosl * e[i__ - 2]; } work[i__ - ll] = cosr; work[i__ - ll + nm1] = -sinr; work[i__ - ll + nm12] = cosl; work[i__ - ll + nm13] = -sinl; /* L150: */ } e[ll] = f; /* Test convergence */ if ( (d__1 = e[ll], fabs (d__1)) <= thresh) { e[ll] = 0.; } /* Update singular vectors if desired */ if (*ncvt > 0) { i__1 = m - ll + 1; NUMlapack_dlasr ("L", "V", "B", &i__1, ncvt, &work[nm12 + 1], &work[nm13 + 1], &vt_ref (ll, 1), ldvt); } if (*nru > 0) { i__1 = m - ll + 1; NUMlapack_dlasr ("R", "V", "B", nru, &i__1, &work[1], &work[*n], &u_ref (1, ll), ldu); } if (*ncc > 0) { i__1 = m - ll + 1; NUMlapack_dlasr ("L", "V", "B", &i__1, ncc, &work[1], &work[*n], &c___ref (ll, 1), ldc); } } } /* QR iteration finished, go back and check convergence */ goto L60; /* All singular values converged, so make them positive */ L160: i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { if (d__[i__] < 0.) { d__[i__] = -d__[i__]; /* Change sign of singular vectors, if desired */ if (*ncvt > 0) { NUMblas_dscal (ncvt, &c_b72, &vt_ref (i__, 1), ldvt); } } /* L170: */ } /* Sort the singular values into decreasing order (insertion sort on singular values, but only one transposition per singular vector) */ i__1 = *n - 1; for (i__ = 1; i__ <= i__1; ++i__) { /* Scan for smallest D(I) */ isub = 1; smin = d__[1]; i__2 = *n + 1 - i__; for (j = 2; j <= i__2; ++j) { if (d__[j] <= smin) { isub = j; smin = d__[j]; } /* L180: */ } if (isub != *n + 1 - i__) { /* Swap singular values and vectors */ d__[isub] = d__[*n + 1 - i__]; d__[*n + 1 - i__] = smin; if (*ncvt > 0) { NUMblas_dswap (ncvt, &vt_ref (isub, 1), ldvt, &vt_ref (*n + 1 - i__, 1), ldvt); } if (*nru > 0) { NUMblas_dswap (nru, &u_ref (1, isub), &c__1, &u_ref (1, *n + 1 - i__), &c__1); } if (*ncc > 0) { NUMblas_dswap (ncc, &c___ref (isub, 1), ldc, &c___ref (*n + 1 - i__, 1), ldc); } } /* L190: */ } goto L220; /* Maximum number of iterations exceeded, failure to converge */ L200: *info = 0; i__1 = *n - 1; for (i__ = 1; i__ <= i__1; ++i__) { if (e[i__] != 0.) { ++ (*info); } /* L210: */ } L220: return 0; } /* NUMlapack_dbdsqr */ #undef vt_ref #undef u_ref int NUMlapack_dgebd2 (long *m, long *n, double *a, long *lda, double *d__, double *e, double *tauq, double *taup, double *work, long *info) { /* Table of constant values */ static long c__1 = 1; /* System generated locals */ long a_dim1, a_offset, i__1, i__2, i__3, i__4; /* Local variables */ static long i__; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --d__; --e; --tauq; --taup; --work; /* Function Body */ *info = 0; if (*m < 0) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < MAX (1, *m)) { *info = -4; } if (*info < 0) { i__1 = - (*info); xerbla_ ("DGEBD2", &i__1); return 0; } if (*m >= *n) { /* Reduce to upper bidiagonal form */ i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { /* Generate elementary reflector H(i) to annihilate A(i+1:m,i) Computing MIN */ i__2 = i__ + 1; i__3 = *m - i__ + 1; NUMlapack_dlarfg (&i__3, &a_ref (i__, i__), &a_ref (MIN (i__2, *m), i__), &c__1, &tauq[i__]); d__[i__] = a_ref (i__, i__); a_ref (i__, i__) = 1.; /* Apply H(i) to A(i:m,i+1:n) from the left */ i__2 = *m - i__ + 1; i__3 = *n - i__; NUMlapack_dlarf ("Left", &i__2, &i__3, &a_ref (i__, i__), &c__1, &tauq[i__], &a_ref (i__, i__ + 1), lda, &work[1]); a_ref (i__, i__) = d__[i__]; if (i__ < *n) { /* Generate elementary reflector G(i) to annihilate A(i,i+2:n) Computing MIN */ i__2 = i__ + 2; i__3 = *n - i__; NUMlapack_dlarfg (&i__3, &a_ref (i__, i__ + 1), &a_ref (i__, MIN (i__2, *n)), lda, &taup[i__]); e[i__] = a_ref (i__, i__ + 1); a_ref (i__, i__ + 1) = 1.; /* Apply G(i) to A(i+1:m,i+1:n) from the right */ i__2 = *m - i__; i__3 = *n - i__; NUMlapack_dlarf ("Right", &i__2, &i__3, &a_ref (i__, i__ + 1), lda, &taup[i__], &a_ref (i__ + 1, i__ + 1), lda, &work[1]); a_ref (i__, i__ + 1) = e[i__]; } else { taup[i__] = 0.; } /* L10: */ } } else { /* Reduce to lower bidiagonal form */ i__1 = *m; for (i__ = 1; i__ <= i__1; ++i__) { /* Generate elementary reflector G(i) to annihilate A(i,i+1:n) Computing MIN */ i__2 = i__ + 1; i__3 = *n - i__ + 1; NUMlapack_dlarfg (&i__3, &a_ref (i__, i__), &a_ref (i__, MIN (i__2, *n)), lda, &taup[i__]); d__[i__] = a_ref (i__, i__); a_ref (i__, i__) = 1.; /* Apply G(i) to A(i+1:m,i:n) from the right Computing MIN */ i__2 = i__ + 1; i__3 = *m - i__; i__4 = *n - i__ + 1; NUMlapack_dlarf ("Right", &i__3, &i__4, &a_ref (i__, i__), lda, &taup[i__], &a_ref (MIN (i__2, *m), i__), lda, &work[1]); a_ref (i__, i__) = d__[i__]; if (i__ < *m) { /* Generate elementary reflector H(i) to annihilate A(i+2:m,i) Computing MIN */ i__2 = i__ + 2; i__3 = *m - i__; NUMlapack_dlarfg (&i__3, &a_ref (i__ + 1, i__), &a_ref (MIN (i__2, *m), i__), &c__1, &tauq[i__]); e[i__] = a_ref (i__ + 1, i__); a_ref (i__ + 1, i__) = 1.; /* Apply H(i) to A(i+1:m,i+1:n) from the left */ i__2 = *m - i__; i__3 = *n - i__; NUMlapack_dlarf ("Left", &i__2, &i__3, &a_ref (i__ + 1, i__), &c__1, &tauq[i__], &a_ref (i__ + 1, i__ + 1), lda, &work[1]); a_ref (i__ + 1, i__) = e[i__]; } else { tauq[i__] = 0.; } /* L20: */ } } return 0; } /* NUMlapack_dgebd2 */ int NUMlapack_dgebak (const char *job, const char *side, long *n, long *ilo, long *ihi, double *scale, long *m, double *v, long *ldv, long *info) { /* System generated locals */ long v_dim1, v_offset, i__1; /* Local variables */ static long i__, k; static double s; static int leftv; static long ii; static int rightv; #define v_ref(a_1,a_2) v[(a_2)*v_dim1 + a_1] --scale; v_dim1 = *ldv; v_offset = 1 + v_dim1 * 1; v -= v_offset; /* Function Body */ rightv = lsame_ (side, "R"); leftv = lsame_ (side, "L"); *info = 0; if (!lsame_ (job, "N") && !lsame_ (job, "P") && !lsame_ (job, "S") && !lsame_ (job, "B")) { *info = -1; } else if (!rightv && !leftv) { *info = -2; } else if (*n < 0) { *info = -3; } else if (*ilo < 1 || *ilo > MAX (1, *n)) { *info = -4; } else if (*ihi < MIN (*ilo, *n) || *ihi > *n) { *info = -5; } else if (*m < 0) { *info = -7; } else if (*ldv < MAX (1, *n)) { *info = -9; } if (*info != 0) { i__1 = - (*info); xerbla_ ("NUMlapack_dgebak ", &i__1); return 0; } /* Quick return if possible */ if (*n == 0) { return 0; } if (*m == 0) { return 0; } if (lsame_ (job, "N")) { return 0; } if (*ilo == *ihi) { goto L30; } /* Backward balance */ if (lsame_ (job, "S") || lsame_ (job, "B")) { if (rightv) { i__1 = *ihi; for (i__ = *ilo; i__ <= i__1; ++i__) { s = scale[i__]; NUMblas_dscal (m, &s, &v_ref (i__, 1), ldv); /* L10: */ } } if (leftv) { i__1 = *ihi; for (i__ = *ilo; i__ <= i__1; ++i__) { s = 1. / scale[i__]; NUMblas_dscal (m, &s, &v_ref (i__, 1), ldv); /* L20: */ } } } /* Backward permutation For I = ILO-1 step -1 until 1, IHI+1 step 1 until N do -- */ L30: if (lsame_ (job, "P") || lsame_ (job, "B")) { if (rightv) { i__1 = *n; for (ii = 1; ii <= i__1; ++ii) { i__ = ii; if (i__ >= *ilo && i__ <= *ihi) { goto L40; } if (i__ < *ilo) { i__ = *ilo - ii; } k = (long) scale[i__]; if (k == i__) { goto L40; } NUMblas_dswap (m, &v_ref (i__, 1), ldv, &v_ref (k, 1), ldv); L40: ; } } if (leftv) { i__1 = *n; for (ii = 1; ii <= i__1; ++ii) { i__ = ii; if (i__ >= *ilo && i__ <= *ihi) { goto L50; } if (i__ < *ilo) { i__ = *ilo - ii; } k = (long) scale[i__]; if (k == i__) { goto L50; } NUMblas_dswap (m, &v_ref (i__, 1), ldv, &v_ref (k, 1), ldv); L50: ; } } } return 0; } /* NUMlapack_dgebak */ #undef v_ref int NUMlapack_dgebal (const char *job, long *n, double *a, long *lda, long *ilo, long *ihi, double *scale, long *info) { /* Table of constant values */ static long c__1 = 1; /* System generated locals */ long a_dim1, a_offset, i__1, i__2; double d__1, d__2; /* Local variables */ static long iexc; static double c__, f, g; static long i__, j, k, l, m; static double r__, s; static double sfmin1, sfmin2, sfmax1, sfmax2, ca, ra; static int noconv; static long ica, ira; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --scale; /* Function Body */ *info = 0; if (!lsame_ (job, "N") && !lsame_ (job, "P") && !lsame_ (job, "S") && !lsame_ (job, "B")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < MAX (1, *n)) { *info = -4; } if (*info != 0) { i__1 = - (*info); xerbla_ ("NUMlapack_dgebal ", &i__1); return 0; } k = 1; l = *n; if (*n == 0) { goto L210; } if (lsame_ (job, "N")) { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { scale[i__] = 1.; /* L10: */ } goto L210; } if (lsame_ (job, "S")) { goto L120; } /* Permutation to isolate eigenvalues if possible */ goto L50; /* Row and column exchange. */ L20: scale[m] = (double) j; if (j == m) { goto L30; } NUMblas_dswap (&l, &a_ref (1, j), &c__1, &a_ref (1, m), &c__1); i__1 = *n - k + 1; NUMblas_dswap (&i__1, &a_ref (j, k), lda, &a_ref (m, k), lda); L30: switch (iexc) { case 1: goto L40; case 2: goto L80; } /* Search for rows isolating an eigenvalue and push them down. */ L40: if (l == 1) { goto L210; } --l; L50: for (j = l; j >= 1; --j) { i__1 = l; for (i__ = 1; i__ <= i__1; ++i__) { if (i__ == j) { goto L60; } if (a_ref (j, i__) != 0.) { goto L70; } L60: ; } m = l; iexc = 1; goto L20; L70: ; } goto L90; /* Search for columns isolating an eigenvalue and push them left. */ L80: ++k; L90: i__1 = l; for (j = k; j <= i__1; ++j) { i__2 = l; for (i__ = k; i__ <= i__2; ++i__) { if (i__ == j) { goto L100; } if (a_ref (i__, j) != 0.) { goto L110; } L100: ; } m = k; iexc = 2; goto L20; L110: ; } L120: i__1 = l; for (i__ = k; i__ <= i__1; ++i__) { scale[i__] = 1.; /* L130: */ } if (lsame_ (job, "P")) { goto L210; } /* Balance the submatrix in rows K to L. Iterative loop for norm reduction */ sfmin1 = NUMblas_dlamch ("S") / NUMblas_dlamch ("P"); sfmax1 = 1. / sfmin1; sfmin2 = sfmin1 * 8.; sfmax2 = 1. / sfmin2; L140: noconv = FALSE; i__1 = l; for (i__ = k; i__ <= i__1; ++i__) { c__ = 0.; r__ = 0.; i__2 = l; for (j = k; j <= i__2; ++j) { if (j == i__) { goto L150; } c__ += (d__1 = a_ref (j, i__), fabs (d__1)); r__ += (d__1 = a_ref (i__, j), fabs (d__1)); L150: ; } ica = NUMblas_idamax (&l, &a_ref (1, i__), &c__1); ca = (d__1 = a_ref (ica, i__), fabs (d__1)); i__2 = *n - k + 1; ira = NUMblas_idamax (&i__2, &a_ref (i__, k), lda); ra = (d__1 = a_ref (i__, ira + k - 1), fabs (d__1)); /* Guard against zero C or R due to underflow. */ if (c__ == 0. || r__ == 0.) { goto L200; } g = r__ / 8.; f = 1.; s = c__ + r__; L160: /* Computing MAX */ d__1 = MAX (f, c__); /* Computing MIN */ d__2 = MIN (r__, g); if (c__ >= g || MAX (d__1, ca) >= sfmax2 || MIN (d__2, ra) <= sfmin2) { goto L170; } f *= 8.; c__ *= 8.; ca *= 8.; r__ /= 8.; g /= 8.; ra /= 8.; goto L160; L170: g = c__ / 8.; L180: /* Computing MIN */ d__1 = MIN (f, c__), d__1 = MIN (d__1, g); if (g < r__ || MAX (r__, ra) >= sfmax2 || MIN (d__1, ca) <= sfmin2) { goto L190; } f /= 8.; c__ /= 8.; g /= 8.; ca /= 8.; r__ *= 8.; ra *= 8.; goto L180; /* Now balance. */ L190: if (c__ + r__ >= s * .95) { goto L200; } if (f < 1. && scale[i__] < 1.) { if (f * scale[i__] <= sfmin1) { goto L200; } } if (f > 1. && scale[i__] > 1.) { if (scale[i__] >= sfmax1 / f) { goto L200; } } g = 1. / f; scale[i__] *= f; noconv = TRUE; i__2 = *n - k + 1; NUMblas_dscal (&i__2, &g, &a_ref (i__, k), lda); NUMblas_dscal (&l, &f, &a_ref (1, i__), &c__1); L200: ; } if (noconv) { goto L140; } L210: *ilo = k; *ihi = l; return 0; } /* NUMlapack_dgebal */ int NUMlapack_dgebrd (long *m, long *n, double *a, long *lda, double *d__, double *e, double *tauq, double *taup, double *work, long *lwork, long *info) { /* Table of constant values */ static long c__1 = 1; static long c_n1 = -1; static long c__3 = 3; static long c__2 = 2; static double c_b21 = -1.; static double c_b22 = 1.; /* System generated locals */ long a_dim1, a_offset, i__1, i__2, i__3, i__4; /* Local variables */ static long i__, j; static long nbmin, iinfo, minmn; static long nb; static long nx; static double ws; static long ldwrkx, ldwrky, lwkopt; static long lquery; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --d__; --e; --tauq; --taup; --work; /* Function Body */ *info = 0; /* Computing MAX */ i__1 = 1, i__2 = NUMlapack_ilaenv (&c__1, "DGEBRD", " ", m, n, &c_n1, &c_n1, 6, 1); nb = MAX (i__1, i__2); lwkopt = (*m + *n) * nb; work[1] = (double) lwkopt; lquery = *lwork == -1; if (*m < 0) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < MAX (1, *m)) { *info = -4; } else { /* if(complicated condition) */ /* Computing MAX */ i__1 = MAX (1, *m); if (*lwork < MAX (i__1, *n) && !lquery) { *info = -10; } } if (*info < 0) { i__1 = - (*info); xerbla_ ("DGEBRD", &i__1); return 0; } else if (lquery) { return 0; } /* Quick return if possible */ minmn = MIN (*m, *n); if (minmn == 0) { work[1] = 1.; return 0; } ws = (double) MAX (*m, *n); ldwrkx = *m; ldwrky = *n; if (nb > 1 && nb < minmn) { /* Set the crossover point NX. Computing MAX */ i__1 = nb, i__2 = NUMlapack_ilaenv (&c__3, "DGEBRD", " ", m, n, &c_n1, &c_n1, 6, 1); nx = MAX (i__1, i__2); /* Determine when to switch from blocked to unblocked code. */ if (nx < minmn) { ws = (double) ( (*m + *n) * nb); if ( (double) (*lwork) < ws) { /* Not enough work space for the optimal NB, consider using a smaller block size. */ nbmin = NUMlapack_ilaenv (&c__2, "DGEBRD", " ", m, n, &c_n1, &c_n1, 6, 1); if (*lwork >= (*m + *n) * nbmin) { nb = *lwork / (*m + *n); } else { nb = 1; nx = minmn; } } } } else { nx = minmn; } i__1 = minmn - nx; i__2 = nb; for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) { /* Reduce rows and columns i:i+nb-1 to bidiagonal form and return the matrices X and Y which are needed to update the unreduced part of the matrix */ i__3 = *m - i__ + 1; i__4 = *n - i__ + 1; NUMlapack_dlabrd (&i__3, &i__4, &nb, &a_ref (i__, i__), lda, &d__[i__], &e[i__], &tauq[i__], &taup[i__], &work[1], &ldwrkx, &work[ldwrkx * nb + 1], &ldwrky); /* Update the trailing submatrix A(i+nb:m,i+nb:n), using an update of the form A := A - V*Y' - X*U' */ i__3 = *m - i__ - nb + 1; i__4 = *n - i__ - nb + 1; NUMblas_dgemm ("No transpose", "Transpose", &i__3, &i__4, &nb, &c_b21, &a_ref (i__ + nb, i__), lda, &work[ldwrkx * nb + nb + 1], &ldwrky, &c_b22, &a_ref (i__ + nb, i__ + nb), lda); i__3 = *m - i__ - nb + 1; i__4 = *n - i__ - nb + 1; NUMblas_dgemm ("No transpose", "No transpose", &i__3, &i__4, &nb, &c_b21, &work[nb + 1], &ldwrkx, &a_ref (i__, i__ + nb), lda, &c_b22, &a_ref (i__ + nb, i__ + nb), lda); /* Copy diagonal and off-diagonal elements of B back into A */ if (*m >= *n) { i__3 = i__ + nb - 1; for (j = i__; j <= i__3; ++j) { a_ref (j, j) = d__[j]; a_ref (j, j + 1) = e[j]; /* L10: */ } } else { i__3 = i__ + nb - 1; for (j = i__; j <= i__3; ++j) { a_ref (j, j) = d__[j]; a_ref (j + 1, j) = e[j]; /* L20: */ } } /* L30: */ } /* Use unblocked code to reduce the remainder of the matrix */ i__2 = *m - i__ + 1; i__1 = *n - i__ + 1; NUMlapack_dgebd2 (&i__2, &i__1, &a_ref (i__, i__), lda, &d__[i__], &e[i__], &tauq[i__], &taup[i__], &work[1], &iinfo); work[1] = ws; return 0; } /* NUMlapack_dgebrd */ int NUMlapack_dgeev (const char *jobvl, const char *jobvr, long *n, double *a, long *lda, double *wr, double *wi, double *vl, long *ldvl, double *vr, long *ldvr, double *work, long *lwork, long *info) { /* Table of constant values */ static long c__8 = 8; static long c_n1 = -1; /* System generated locals */ long a_dim1, a_offset, vl_dim1, vl_offset, vr_dim1, vr_offset, i__1, i__2, i__3, i__4; double d__1, d__2; /* Local variables */ static long ibal; static char side[1]; static long maxb; static double anrm; static long ierr, itau; static long iwrk, nout; static long i__, k; static double r__; static double cs; static int scalea; static double cscale; static double sn; static int select[1]; static double bignum; static long minwrk, maxwrk; static int wantvl; static double smlnum; static long hswork; static int lquery, wantvr; static long ihi; static double scl; static long ilo; static double dum[1], eps; #define vl_ref(a_1,a_2) vl[(a_2)*vl_dim1 + a_1] #define vr_ref(a_1,a_2) vr[(a_2)*vr_dim1 + a_1] a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --wr; --wi; vl_dim1 = *ldvl; vl_offset = 1 + vl_dim1 * 1; vl -= vl_offset; vr_dim1 = *ldvr; vr_offset = 1 + vr_dim1 * 1; vr -= vr_offset; --work; /* Function Body */ *info = 0; lquery = *lwork == -1; wantvl = lsame_ (jobvl, "V"); wantvr = lsame_ (jobvr, "V"); if (!wantvl && !lsame_ (jobvl, "N")) { *info = -1; } else if (!wantvr && !lsame_ (jobvr, "N")) { *info = -2; } else if (*n < 0) { *info = -3; } else if (*lda < MAX (1, *n)) { *info = -5; } else if (*ldvl < 1 || wantvl && *ldvl < *n) { *info = -9; } else if (*ldvr < 1 || wantvr && *ldvr < *n) { *info = -11; } /* Compute workspace (Note: Comments in the code beginning "Workspace:" describe the minimal amount of workspace needed at that point in the code, as well as the preferred amount for good performance. NB refers to the optimal block size for the immediately following subroutine, as returned by ILAENV. HSWORK refers to the workspace preferred by NUMlapack_dhseqr , as calculated below. HSWORK is computed assuming ILO=1 and IHI=N, the worst case.) */ minwrk = 1; if (*info == 0 && (*lwork >= 1 || lquery)) { maxwrk = (*n << 1) + *n * NUMlapack_ilaenv (&c__1, "NUMlapack_dgehrd ", " ", n, &c__1, n, &c__0, 6, 1); if (!wantvl && !wantvr) { /* Computing MAX */ i__1 = 1, i__2 = *n * 3; minwrk = MAX (i__1, i__2); /* Computing MAX */ i__1 = NUMlapack_ilaenv (&c__8, "NUMlapack_dhseqr ", "EN", n, &c__1, n, &c_n1, 6, 2); maxb = MAX (i__1, 2); /* Computing MIN Computing MAX */ i__3 = 2, i__4 = NUMlapack_ilaenv (&c__4, "NUMlapack_dhseqr ", "EN", n, &c__1, n, &c_n1, 6, 2); i__1 = MIN (maxb, *n), i__2 = MAX (i__3, i__4); k = MIN (i__1, i__2); /* Computing MAX */ i__1 = k * (k + 2), i__2 = *n << 1; hswork = MAX (i__1, i__2); /* Computing MAX */ i__1 = maxwrk, i__2 = *n + 1, i__1 = MAX (i__1, i__2), i__2 = *n + hswork; maxwrk = MAX (i__1, i__2); } else { /* Computing MAX */ i__1 = 1, i__2 = *n << 2; minwrk = MAX (i__1, i__2); /* Computing MAX */ i__1 = maxwrk, i__2 = (*n << 1) + (*n - 1) * NUMlapack_ilaenv (&c__1, "DOR" "GHR", " ", n, &c__1, n, &c_n1, 6, 1); maxwrk = MAX (i__1, i__2); /* Computing MAX */ i__1 = NUMlapack_ilaenv (&c__8, "NUMlapack_dhseqr ", "SV", n, &c__1, n, &c_n1, 6, 2); maxb = MAX (i__1, 2); /* Computing MIN Computing MAX */ i__3 = 2, i__4 = NUMlapack_ilaenv (&c__4, "NUMlapack_dhseqr ", "SV", n, &c__1, n, &c_n1, 6, 2); i__1 = MIN (maxb, *n), i__2 = MAX (i__3, i__4); k = MIN (i__1, i__2); /* Computing MAX */ i__1 = k * (k + 2), i__2 = *n << 1; hswork = MAX (i__1, i__2); /* Computing MAX */ i__1 = maxwrk, i__2 = *n + 1, i__1 = MAX (i__1, i__2), i__2 = *n + hswork; maxwrk = MAX (i__1, i__2); /* Computing MAX */ i__1 = maxwrk, i__2 = *n << 2; maxwrk = MAX (i__1, i__2); } work[1] = (double) maxwrk; } if (*lwork < minwrk && !lquery) { *info = -13; } if (*info != 0) { i__1 = - (*info); xerbla_ ("NUMlapack_dgeev ", &i__1); return 0; } else if (lquery) { return 0; } /* Quick return if possible */ if (*n == 0) { return 0; } /* Get machine constants */ eps = NUMblas_dlamch ("P"); smlnum = NUMblas_dlamch ("S"); bignum = 1. / smlnum; NUMlapack_dlabad (&smlnum, &bignum); smlnum = sqrt (smlnum) / eps; bignum = 1. / smlnum; /* Scale A if max element outside range [SMLNUM,BIGNUM] */ anrm = NUMlapack_dlange ("M", n, n, &a[a_offset], lda, dum); scalea = FALSE; if (anrm > 0. && anrm < smlnum) { scalea = TRUE; cscale = smlnum; } else if (anrm > bignum) { scalea = TRUE; cscale = bignum; } if (scalea) { NUMlapack_dlascl ("G", &c__0, &c__0, &anrm, &cscale, n, n, &a[a_offset], lda, &ierr); } /* Balance the matrix (Workspace: need N) */ ibal = 1; NUMlapack_dgebal ("B", n, &a[a_offset], lda, &ilo, &ihi, &work[ibal], &ierr); /* Reduce to upper Hessenberg form (Workspace: need 3*N, prefer 2*N+N*NB) */ itau = ibal + *n; iwrk = itau + *n; i__1 = *lwork - iwrk + 1; NUMlapack_dgehrd (n, &ilo, &ihi, &a[a_offset], lda, &work[itau], &work[iwrk], &i__1, &ierr); if (wantvl) { /* Want left eigenvectors Copy Householder vectors to VL */ * (unsigned char *) side = 'L'; NUMlapack_dlacpy ("L", n, n, &a[a_offset], lda, &vl[vl_offset], ldvl); /* Generate orthogonal matrix in VL (Workspace: need 3*N-1, prefer 2*N+(N-1)*NB) */ i__1 = *lwork - iwrk + 1; NUMlapack_dorghr (n, &ilo, &ihi, &vl[vl_offset], ldvl, &work[itau], &work[iwrk], &i__1, &ierr); /* Perform QR iteration, accumulating Schur vectors in VL (Workspace: need N+1, prefer N+HSWORK (see comments) ) */ iwrk = itau; i__1 = *lwork - iwrk + 1; NUMlapack_dhseqr ("S", "V", n, &ilo, &ihi, &a[a_offset], lda, &wr[1], &wi[1], &vl[vl_offset], ldvl, &work[iwrk], &i__1, info); if (wantvr) { /* Want left and right eigenvectors Copy Schur vectors to VR */ * (unsigned char *) side = 'B'; NUMlapack_dlacpy ("F", n, n, &vl[vl_offset], ldvl, &vr[vr_offset], ldvr); } } else if (wantvr) { /* Want right eigenvectors Copy Householder vectors to VR */ * (unsigned char *) side = 'R'; NUMlapack_dlacpy ("L", n, n, &a[a_offset], lda, &vr[vr_offset], ldvr); /* Generate orthogonal matrix in VR (Workspace: need 3*N-1, prefer 2*N+(N-1)*NB) */ i__1 = *lwork - iwrk + 1; NUMlapack_dorghr (n, &ilo, &ihi, &vr[vr_offset], ldvr, &work[itau], &work[iwrk], &i__1, &ierr); /* Perform QR iteration, accumulating Schur vectors in VR (Workspace: need N+1, prefer N+HSWORK (see comments) ) */ iwrk = itau; i__1 = *lwork - iwrk + 1; NUMlapack_dhseqr ("S", "V", n, &ilo, &ihi, &a[a_offset], lda, &wr[1], &wi[1], &vr[vr_offset], ldvr, &work[iwrk], &i__1, info); } else { /* Compute eigenvalues only (Workspace: need N+1, prefer N+HSWORK (see comments) ) */ iwrk = itau; i__1 = *lwork - iwrk + 1; NUMlapack_dhseqr ("E", "N", n, &ilo, &ihi, &a[a_offset], lda, &wr[1], &wi[1], &vr[vr_offset], ldvr, &work[iwrk], &i__1, info); } /* If INFO > 0 from NUMlapack_dhseqr , then quit */ if (*info > 0) { goto L50; } if (wantvl || wantvr) { /* Compute left and/or right eigenvectors (Workspace: need 4*N) */ NUMlapack_dtrevc (side, "B", select, n, &a[a_offset], lda, &vl[vl_offset], ldvl, &vr[vr_offset], ldvr, n, &nout, &work[iwrk], &ierr); } if (wantvl) { /* Undo balancing of left eigenvectors (Workspace: need N) */ NUMlapack_dgebak ("B", "L", n, &ilo, &ihi, &work[ibal], n, &vl[vl_offset], ldvl, &ierr); /* Normalize left eigenvectors and make largest component real */ i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { if (wi[i__] == 0.) { scl = 1. / NUMblas_dnrm2 (n, &vl_ref (1, i__), &c__1); NUMblas_dscal (n, &scl, &vl_ref (1, i__), &c__1); } else if (wi[i__] > 0.) { d__1 = NUMblas_dnrm2 (n, &vl_ref (1, i__), &c__1); d__2 = NUMblas_dnrm2 (n, &vl_ref (1, i__ + 1), &c__1); scl = 1. / NUMlapack_dlapy2 (&d__1, &d__2); NUMblas_dscal (n, &scl, &vl_ref (1, i__), &c__1); NUMblas_dscal (n, &scl, &vl_ref (1, i__ + 1), &c__1); i__2 = *n; for (k = 1; k <= i__2; ++k) { /* Computing 2nd power */ d__1 = vl_ref (k, i__); /* Computing 2nd power */ d__2 = vl_ref (k, i__ + 1); work[iwrk + k - 1] = d__1 * d__1 + d__2 * d__2; /* L10: */ } k = NUMblas_idamax (n, &work[iwrk], &c__1); NUMlapack_dlartg (&vl_ref (k, i__), &vl_ref (k, i__ + 1), &cs, &sn, &r__); NUMblas_drot (n, &vl_ref (1, i__), &c__1, &vl_ref (1, i__ + 1), &c__1, &cs, &sn); vl_ref (k, i__ + 1) = 0.; } /* L20: */ } } if (wantvr) { /* Undo balancing of right eigenvectors (Workspace: need N) */ NUMlapack_dgebak ("B", "R", n, &ilo, &ihi, &work[ibal], n, &vr[vr_offset], ldvr, &ierr); /* Normalize right eigenvectors and make largest component real */ i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { if (wi[i__] == 0.) { scl = 1. / NUMblas_dnrm2 (n, &vr_ref (1, i__), &c__1); NUMblas_dscal (n, &scl, &vr_ref (1, i__), &c__1); } else if (wi[i__] > 0.) { d__1 = NUMblas_dnrm2 (n, &vr_ref (1, i__), &c__1); d__2 = NUMblas_dnrm2 (n, &vr_ref (1, i__ + 1), &c__1); scl = 1. / NUMlapack_dlapy2 (&d__1, &d__2); NUMblas_dscal (n, &scl, &vr_ref (1, i__), &c__1); NUMblas_dscal (n, &scl, &vr_ref (1, i__ + 1), &c__1); i__2 = *n; for (k = 1; k <= i__2; ++k) { /* Computing 2nd power */ d__1 = vr_ref (k, i__); /* Computing 2nd power */ d__2 = vr_ref (k, i__ + 1); work[iwrk + k - 1] = d__1 * d__1 + d__2 * d__2; /* L30: */ } k = NUMblas_idamax (n, &work[iwrk], &c__1); NUMlapack_dlartg (&vr_ref (k, i__), &vr_ref (k, i__ + 1), &cs, &sn, &r__); NUMblas_drot (n, &vr_ref (1, i__), &c__1, &vr_ref (1, i__ + 1), &c__1, &cs, &sn); vr_ref (k, i__ + 1) = 0.; } /* L40: */ } } /* Undo scaling if necessary */ L50: if (scalea) { i__1 = *n - *info; /* Computing MAX */ i__3 = *n - *info; i__2 = MAX (i__3, 1); NUMlapack_dlascl ("G", &c__0, &c__0, &cscale, &anrm, &i__1, &c__1, &wr[*info + 1], &i__2, &ierr); i__1 = *n - *info; /* Computing MAX */ i__3 = *n - *info; i__2 = MAX (i__3, 1); NUMlapack_dlascl ("G", &c__0, &c__0, &cscale, &anrm, &i__1, &c__1, &wi[*info + 1], &i__2, &ierr); if (*info > 0) { i__1 = ilo - 1; NUMlapack_dlascl ("G", &c__0, &c__0, &cscale, &anrm, &i__1, &c__1, &wr[1], n, &ierr); i__1 = ilo - 1; NUMlapack_dlascl ("G", &c__0, &c__0, &cscale, &anrm, &i__1, &c__1, &wi[1], n, &ierr); } } work[1] = (double) maxwrk; return 0; } /* NUMlapack_dgeev */ #undef vr_ref #undef vl_ref int NUMlapack_dgehd2 (long *n, long *ilo, long *ihi, double *a, long *lda, double *tau, double *work, long *info) { /* Table of constant values */ static long c__1 = 1; /* System generated locals */ long a_dim1, a_offset, i__1, i__2, i__3; /* Local variables */ static long i__; static double aii; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --tau; --work; /* Function Body */ *info = 0; if (*n < 0) { *info = -1; } else if (*ilo < 1 || *ilo > MAX (1, *n)) { *info = -2; } else if (*ihi < MIN (*ilo, *n) || *ihi > *n) { *info = -3; } else if (*lda < MAX (1, *n)) { *info = -5; } if (*info != 0) { i__1 = - (*info); xerbla_ ("NUMlapack_dgehd2 ", &i__1); return 0; } i__1 = *ihi - 1; for (i__ = *ilo; i__ <= i__1; ++i__) { /* Compute elementary reflector H(i) to annihilate A(i+2:ihi,i) Computing MIN */ i__2 = i__ + 2; i__3 = *ihi - i__; NUMlapack_dlarfg (&i__3, &a_ref (i__ + 1, i__), &a_ref (MIN (i__2, *n), i__), &c__1, &tau[i__]); aii = a_ref (i__ + 1, i__); a_ref (i__ + 1, i__) = 1.; /* Apply H(i) to A(1:ihi,i+1:ihi) from the right */ i__2 = *ihi - i__; NUMlapack_dlarf ("Right", ihi, &i__2, &a_ref (i__ + 1, i__), &c__1, &tau[i__], &a_ref (1, i__ + 1), lda, &work[1]); /* Apply H(i) to A(i+1:ihi,i+1:n) from the left */ i__2 = *ihi - i__; i__3 = *n - i__; NUMlapack_dlarf ("Left", &i__2, &i__3, &a_ref (i__ + 1, i__), &c__1, &tau[i__], &a_ref (i__ + 1, i__ + 1), lda, &work[1]); a_ref (i__ + 1, i__) = aii; /* L10: */ } return 0; } /* NUMlapack_dgehd2 */ int NUMlapack_dgehrd (long *n, long *ilo, long *ihi, double *a, long *lda, double *tau, double *work, long *lwork, long *info) { /* Table of constant values */ static long c__1 = 1; static long c_n1 = -1; static long c__3 = 3; static long c__2 = 2; static long c__65 = 65; static double c_b25 = -1.; static double c_b26 = 1.; /* System generated locals */ long a_dim1, a_offset, i__1, i__2, i__3, i__4; /* Local variables */ static long i__; static double t[4160] /* was [65][64] */ ; static long nbmin, iinfo; static long ib; static double ei; static long nb, nh; static long nx; static long ldwork, lwkopt; static int lquery; static long iws; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --tau; --work; /* Function Body */ *info = 0; /* Computing MIN */ i__1 = 64, i__2 = NUMlapack_ilaenv (&c__1, "NUMlapack_dgehrd ", " ", n, ilo, ihi, &c_n1, 6, 1); nb = MIN (i__1, i__2); lwkopt = *n * nb; work[1] = (double) lwkopt; lquery = *lwork == -1; if (*n < 0) { *info = -1; } else if (*ilo < 1 || *ilo > MAX (1, *n)) { *info = -2; } else if (*ihi < MIN (*ilo, *n) || *ihi > *n) { *info = -3; } else if (*lda < MAX (1, *n)) { *info = -5; } else if (*lwork < MAX (1, *n) && !lquery) { *info = -8; } if (*info != 0) { i__1 = - (*info); xerbla_ ("NUMlapack_dgehrd ", &i__1); return 0; } else if (lquery) { return 0; } /* Set elements 1:ILO-1 and IHI:N-1 of TAU to zero */ i__1 = *ilo - 1; for (i__ = 1; i__ <= i__1; ++i__) { tau[i__] = 0.; /* L10: */ } i__1 = *n - 1; for (i__ = MAX (1, *ihi); i__ <= i__1; ++i__) { tau[i__] = 0.; /* L20: */ } /* Quick return if possible */ nh = *ihi - *ilo + 1; if (nh <= 1) { work[1] = 1.; return 0; } /* Determine the block size. Computing MIN */ i__1 = 64, i__2 = NUMlapack_ilaenv (&c__1, "NUMlapack_dgehrd ", " ", n, ilo, ihi, &c_n1, 6, 1); nb = MIN (i__1, i__2); nbmin = 2; iws = 1; if (nb > 1 && nb < nh) { /* Determine when to cross over from blocked to unblocked code (last block is always handled by unblocked code). Computing MAX */ i__1 = nb, i__2 = NUMlapack_ilaenv (&c__3, "NUMlapack_dgehrd ", " ", n, ilo, ihi, &c_n1, 6, 1); nx = MAX (i__1, i__2); if (nx < nh) { /* Determine if workspace is large enough for blocked code. */ iws = *n * nb; if (*lwork < iws) { /* Not enough workspace to use optimal NB: determine the minimum value of NB, and reduce NB or force use of unblocked code. Computing MAX */ i__1 = 2, i__2 = NUMlapack_ilaenv (&c__2, "NUMlapack_dgehrd ", " ", n, ilo, ihi, &c_n1, 6, 1); nbmin = MAX (i__1, i__2); if (*lwork >= *n * nbmin) { nb = *lwork / *n; } else { nb = 1; } } } } ldwork = *n; if (nb < nbmin || nb >= nh) { /* Use unblocked code below */ i__ = *ilo; } else { /* Use blocked code */ i__1 = *ihi - 1 - nx; i__2 = nb; for (i__ = *ilo; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) { /* Computing MIN */ i__3 = nb, i__4 = *ihi - i__; ib = MIN (i__3, i__4); /* Reduce columns i:i+ib-1 to Hessenberg form, returning the matrices V and T of the block reflector H = I - V*T*V' which performs the reduction, and also the matrix Y = A*V*T */ NUMlapack_dlahrd (ihi, &i__, &ib, &a_ref (1, i__), lda, &tau[i__], t, &c__65, &work[1], &ldwork); /* Apply the block reflector H to A(1:ihi,i+ib:ihi) from the right, computing A := A - Y * V'. V(i+ib,ib-1) must be set to 1. */ ei = a_ref (i__ + ib, i__ + ib - 1); a_ref (i__ + ib, i__ + ib - 1) = 1.; i__3 = *ihi - i__ - ib + 1; NUMblas_dgemm ("No transpose", "Transpose", ihi, &i__3, &ib, &c_b25, &work[1], &ldwork, &a_ref (i__ + ib, i__), lda, &c_b26, &a_ref (1, i__ + ib), lda); a_ref (i__ + ib, i__ + ib - 1) = ei; /* Apply the block reflector H to A(i+1:ihi,i+ib:n) from the left */ i__3 = *ihi - i__; i__4 = *n - i__ - ib + 1; NUMlapack_dlarfb ("Left", "Transpose", "Forward", "Columnwise", &i__3, &i__4, &ib, &a_ref (i__ + 1, i__), lda, t, &c__65, &a_ref (i__ + 1, i__ + ib), lda, &work[1], &ldwork); /* L30: */ } } /* Use unblocked code to reduce the rest of the matrix */ NUMlapack_dgehd2 (n, &i__, ihi, &a[a_offset], lda, &tau[1], &work[1], &iinfo); work[1] = (double) iws; return 0; } /* NUMlapack_dgehrd */ int NUMlapack_dgelq2 (long *m, long *n, double *a, long *lda, double *tau, double *work, long *info) { /* System generated locals */ long a_dim1, a_offset, i__1, i__2, i__3; /* Local variables */ static long i__, k; static double aii; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --tau; --work; /* Function Body */ *info = 0; if (*m < 0) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < MAX (1, *m)) { *info = -4; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DGELQ2", &i__1); return 0; } k = MIN (*m, *n); i__1 = k; for (i__ = 1; i__ <= i__1; ++i__) { /* Generate elementary reflector H(i) to annihilate A(i,i+1:n) Computing MIN */ i__2 = i__ + 1; i__3 = *n - i__ + 1; NUMlapack_dlarfg (&i__3, &a_ref (i__, i__), &a_ref (i__, MIN (i__2, *n)), lda, &tau[i__]); if (i__ < *m) { /* Apply H(i) to A(i+1:m,i:n) from the right */ aii = a_ref (i__, i__); a_ref (i__, i__) = 1.; i__2 = *m - i__; i__3 = *n - i__ + 1; NUMlapack_dlarf ("Right", &i__2, &i__3, &a_ref (i__, i__), lda, &tau[i__], &a_ref (i__ + 1, i__), lda, &work[1]); a_ref (i__, i__) = aii; } /* L10: */ } return 0; } /* NUMlapack_dgelq2 */ int NUMlapack_dgelqf (long *m, long *n, double *a, long *lda, double *tau, double *work, long *lwork, long *info) { /* Table of constant values */ static long c__1 = 1; static long c_n1 = -1; static long c__3 = 3; static long c__2 = 2; /* System generated locals */ long a_dim1, a_offset, i__1, i__2, i__3, i__4; /* Local variables */ static long i__, k, nbmin, iinfo; static long ib, nb; static long nx; static long ldwork, lwkopt; static long lquery; static long iws; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --tau; --work; /* Function Body */ *info = 0; nb = NUMlapack_ilaenv (&c__1, "DGELQF", " ", m, n, &c_n1, &c_n1, 6, 1); lwkopt = *m * nb; work[1] = (double) lwkopt; lquery = *lwork == -1; if (*m < 0) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < MAX (1, *m)) { *info = -4; } else if (*lwork < MAX (1, *m) && !lquery) { *info = -7; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DGELQF", &i__1); return 0; } else if (lquery) { return 0; } /* Quick return if possible */ k = MIN (*m, *n); if (k == 0) { work[1] = 1.; return 0; } nbmin = 2; nx = 0; iws = *m; if (nb > 1 && nb < k) { /* Determine when to cross over from blocked to unblocked code. Computing MAX */ i__1 = 0, i__2 = NUMlapack_ilaenv (&c__3, "DGELQF", " ", m, n, &c_n1, &c_n1, 6, 1); nx = MAX (i__1, i__2); if (nx < k) { /* Determine if workspace is large enough for blocked code. */ ldwork = *m; iws = ldwork * nb; if (*lwork < iws) { /* Not enough workspace to use optimal NB: reduce NB and determine the minimum value of NB. */ nb = *lwork / ldwork; /* Computing MAX */ i__1 = 2, i__2 = NUMlapack_ilaenv (&c__2, "DGELQF", " ", m, n, &c_n1, &c_n1, 6, 1); nbmin = MAX (i__1, i__2); } } } if (nb >= nbmin && nb < k && nx < k) { /* Use blocked code initially */ i__1 = k - nx; i__2 = nb; for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) { /* Computing MIN */ i__3 = k - i__ + 1; ib = MIN (i__3, nb); /* Compute the LQ factorization of the current block A(i:i+ib-1,i:n) */ i__3 = *n - i__ + 1; NUMlapack_dgelq2 (&ib, &i__3, &a_ref (i__, i__), lda, &tau[i__], &work[1], &iinfo); if (i__ + ib <= *m) { /* Form the triangular factor of the block reflector H = H(i) H(i+1) . . . H(i+ib-1) */ i__3 = *n - i__ + 1; NUMlapack_dlarft ("Forward", "Rowwise", &i__3, &ib, &a_ref (i__, i__), lda, &tau[i__], &work[1], &ldwork); /* Apply H to A(i+ib:m,i:n) from the right */ i__3 = *m - i__ - ib + 1; i__4 = *n - i__ + 1; NUMlapack_dlarfb ("Right", "No transpose", "Forward", "Rowwise", &i__3, &i__4, &ib, &a_ref (i__, i__), lda, &work[1], &ldwork, &a_ref (i__ + ib, i__), lda, &work[ib + 1], &ldwork); } /* L10: */ } } else { i__ = 1; } /* Use unblocked code to factor the last or only block. */ if (i__ <= k) { i__2 = *m - i__ + 1; i__1 = *n - i__ + 1; NUMlapack_dgelq2 (&i__2, &i__1, &a_ref (i__, i__), lda, &tau[i__], &work[1], &iinfo); } work[1] = (double) iws; return 0; } /* NUMlapack_dgelqf */ #define b_ref(a_1,a_2) b[(a_2)*b_dim1 + a_1] int NUMlapack_dgelss (long *m, long *n, long *nrhs, double *a, long *lda, double *b, long *ldb, double *s, double *rcond, long *rank, double *work, long *lwork, long *info) { /* System generated locals */ long a_dim1, a_offset, b_dim1, b_offset, i__1, i__2, i__3, i__4; double d__1; /* Local variables */ static double anrm, bnrm; static long itau; static double vdum[1]; static long i__; static long iascl, ibscl; static long chunk; static double sfmin; static long minmn; static long maxmn, itaup, itauq, mnthr, iwork; static long bl, ie, il; static long mm; static long bdspac; static double bignum; static long ldwork; static long minwrk, maxwrk; static double smlnum; static long lquery; static double eps, thr; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; b_dim1 = *ldb; b_offset = 1 + b_dim1 * 1; b -= b_offset; --s; --work; /* Function Body */ *info = 0; minmn = MIN (*m, *n); maxmn = MAX (*m, *n); mnthr = NUMlapack_ilaenv (&c__6, "DGELSS", " ", m, n, nrhs, &c_n1, 6, 1); lquery = *lwork == -1; if (*m < 0) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*nrhs < 0) { *info = -3; } else if (*lda < MAX (1, *m)) { *info = -5; } else if (*ldb < MAX (1, maxmn)) { *info = -7; } /* Compute workspace (Note: Comments in the code beginning "Workspace:" describe the minimal amount of workspace needed at that point in the code, as well as the preferred amount for good performance. NB refers to the optimal block size for the immediately following subroutine, as returned by ILAENV.) */ minwrk = 1; if (*info == 0 && (*lwork >= 1 || lquery)) { maxwrk = 0; mm = *m; if (*m >= *n && *m >= mnthr) { /* Path 1a - overdetermined, with many more rows than columns */ mm = *n; /* Computing MAX */ i__1 = maxwrk, i__2 = *n + *n * NUMlapack_ilaenv (&c__1, "DGEQRF", " ", m, n, &c_n1, &c_n1, 6, 1); maxwrk = MAX (i__1, i__2); /* Computing MAX */ i__1 = maxwrk, i__2 = *n + *nrhs * NUMlapack_ilaenv (&c__1, "DORMQR", "LT", m, nrhs, n, &c_n1, 6, 2); maxwrk = MAX (i__1, i__2); } if (*m >= *n) { /* Path 1 - overdetermined or exactly determined Compute workspace needed for DBDSQR Computing MAX */ i__1 = 1, i__2 = *n * 5; bdspac = MAX (i__1, i__2); /* Computing MAX */ i__1 = maxwrk, i__2 = *n * 3 + (mm + *n) * NUMlapack_ilaenv (&c__1, "DGEBRD", " ", &mm, n, &c_n1, &c_n1, 6, 1); maxwrk = MAX (i__1, i__2); /* Computing MAX */ i__1 = maxwrk, i__2 = *n * 3 + *nrhs * NUMlapack_ilaenv (&c__1, "DORMBR", "QLT", &mm, nrhs, n, &c_n1, 6, 3); maxwrk = MAX (i__1, i__2); /* Computing MAX */ i__1 = maxwrk, i__2 = *n * 3 + (*n - 1) * NUMlapack_ilaenv (&c__1, "DORGBR", "P", n, n, n, &c_n1, 6, 1); maxwrk = MAX (i__1, i__2); maxwrk = MAX (maxwrk, bdspac); /* Computing MAX */ i__1 = maxwrk, i__2 = *n * *nrhs; maxwrk = MAX (i__1, i__2); /* Computing MAX */ i__1 = *n * 3 + mm, i__2 = *n * 3 + *nrhs, i__1 = MAX (i__1, i__2); minwrk = MAX (i__1, bdspac); maxwrk = MAX (minwrk, maxwrk); } if (*n > *m) { /* Compute workspace needed for DBDSQR Computing MAX */ i__1 = 1, i__2 = *m * 5; bdspac = MAX (i__1, i__2); /* Computing MAX */ i__1 = *m * 3 + *nrhs, i__2 = *m * 3 + *n, i__1 = MAX (i__1, i__2); minwrk = MAX (i__1, bdspac); if (*n >= mnthr) { /* Path 2a - underdetermined, with many more columns than rows */ maxwrk = *m + *m * NUMlapack_ilaenv (&c__1, "DGELQF", " ", m, n, &c_n1, &c_n1, 6, 1); /* Computing MAX */ i__1 = maxwrk, i__2 = *m * *m + (*m << 2) + (*m << 1) * NUMlapack_ilaenv (&c__1, "DGEBRD", " ", m, m, &c_n1, &c_n1, 6, 1); maxwrk = MAX (i__1, i__2); /* Computing MAX */ i__1 = maxwrk, i__2 = *m * *m + (*m << 2) + *nrhs * NUMlapack_ilaenv (&c__1, "DORMBR", "QLT", m, nrhs, m, &c_n1, 6, 3); maxwrk = MAX (i__1, i__2); /* Computing MAX */ i__1 = maxwrk, i__2 = *m * *m + (*m << 2) + (*m - 1) * NUMlapack_ilaenv (&c__1, "DORGBR", "P", m, m, m, &c_n1, 6, 1); maxwrk = MAX (i__1, i__2); /* Computing MAX */ i__1 = maxwrk, i__2 = *m * *m + *m + bdspac; maxwrk = MAX (i__1, i__2); if (*nrhs > 1) { /* Computing MAX */ i__1 = maxwrk, i__2 = *m * *m + *m + *m * *nrhs; maxwrk = MAX (i__1, i__2); } else { /* Computing MAX */ i__1 = maxwrk, i__2 = *m * *m + (*m << 1); maxwrk = MAX (i__1, i__2); } /* Computing MAX */ i__1 = maxwrk, i__2 = *m + *nrhs * NUMlapack_ilaenv (&c__1, "DORMLQ", "LT", n, nrhs, m, &c_n1, 6, 2); maxwrk = MAX (i__1, i__2); } else { /* Path 2 - underdetermined */ maxwrk = *m * 3 + (*n + *m) * NUMlapack_ilaenv (&c__1, "DGEBRD", " ", m, n, &c_n1, &c_n1, 6, 1); /* Computing MAX */ i__1 = maxwrk, i__2 = *m * 3 + *nrhs * NUMlapack_ilaenv (&c__1, "DORMBR", "QLT", m, nrhs, m, &c_n1, 6, 3); maxwrk = MAX (i__1, i__2); /* Computing MAX */ i__1 = maxwrk, i__2 = *m * 3 + *m * NUMlapack_ilaenv (&c__1, "DORGBR", "P", m, n, m, &c_n1, 6, 1); maxwrk = MAX (i__1, i__2); maxwrk = MAX (maxwrk, bdspac); /* Computing MAX */ i__1 = maxwrk, i__2 = *n * *nrhs; maxwrk = MAX (i__1, i__2); } } maxwrk = MAX (minwrk, maxwrk); work[1] = (double) maxwrk; } minwrk = MAX (minwrk, 1); if (*lwork < minwrk && !lquery) { *info = -12; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DGELSS", &i__1); return 0; } else if (lquery) { return 0; } /* Quick return if possible */ if (*m == 0 || *n == 0) { *rank = 0; return 0; } /* Get machine parameters */ eps = NUMblas_dlamch ("P"); sfmin = NUMblas_dlamch ("S"); smlnum = sfmin / eps; bignum = 1. / smlnum; NUMlapack_dlabad (&smlnum, &bignum); /* Scale A if max element outside range [SMLNUM,BIGNUM] */ anrm = NUMlapack_dlange ("M", m, n, &a[a_offset], lda, &work[1]); iascl = 0; if (anrm > 0. && anrm < smlnum) { /* Scale matrix norm up to SMLNUM */ NUMlapack_dlascl ("G", &c__0, &c__0, &anrm, &smlnum, m, n, &a[a_offset], lda, info); iascl = 1; } else if (anrm > bignum) { /* Scale matrix norm down to BIGNUM */ NUMlapack_dlascl ("G", &c__0, &c__0, &anrm, &bignum, m, n, &a[a_offset], lda, info); iascl = 2; } else if (anrm == 0.) { /* Matrix all zero. Return zero solution. */ i__1 = MAX (*m, *n); NUMlapack_dlaset ("F", &i__1, nrhs, &c_b74, &c_b74, &b[b_offset], ldb); NUMlapack_dlaset ("F", &minmn, &c__1, &c_b74, &c_b74, &s[1], &c__1); *rank = 0; goto L70; } /* Scale B if max element outside range [SMLNUM,BIGNUM] */ bnrm = NUMlapack_dlange ("M", m, nrhs, &b[b_offset], ldb, &work[1]); ibscl = 0; if (bnrm > 0. && bnrm < smlnum) { /* Scale matrix norm up to SMLNUM */ NUMlapack_dlascl ("G", &c__0, &c__0, &bnrm, &smlnum, m, nrhs, &b[b_offset], ldb, info); ibscl = 1; } else if (bnrm > bignum) { /* Scale matrix norm down to BIGNUM */ NUMlapack_dlascl ("G", &c__0, &c__0, &bnrm, &bignum, m, nrhs, &b[b_offset], ldb, info); ibscl = 2; } /* Overdetermined case */ if (*m >= *n) { /* Path 1 - overdetermined or exactly determined */ mm = *m; if (*m >= mnthr) { /* Path 1a - overdetermined, with many more rows than columns */ mm = *n; itau = 1; iwork = itau + *n; /* Compute A=Q*R (Workspace: need 2*N, prefer N+N*NB) */ i__1 = *lwork - iwork + 1; NUMlapack_dgeqrf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__1, info); /* Multiply B by transpose(Q) (Workspace: need N+NRHS, prefer N+NRHS*NB) */ i__1 = *lwork - iwork + 1; NUMlapack_dormqr ("L", "T", m, nrhs, n, &a[a_offset], lda, &work[itau], &b[b_offset], ldb, &work[iwork], &i__1, info); /* Zero out below R */ if (*n > 1) { i__1 = *n - 1; i__2 = *n - 1; NUMlapack_dlaset ("L", &i__1, &i__2, &c_b74, &c_b74, &a_ref (2, 1), lda); } } ie = 1; itauq = ie + *n; itaup = itauq + *n; iwork = itaup + *n; /* Bidiagonalize R in A (Workspace: need 3*N+MM, prefer 3*N+(MM+N)*NB) */ i__1 = *lwork - iwork + 1; NUMlapack_dgebrd (&mm, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__1, info); /* Multiply B by transpose of left bidiagonalizing vectors of R (Workspace: need 3*N+NRHS, prefer 3*N+NRHS*NB) */ i__1 = *lwork - iwork + 1; NUMlapack_dormbr ("Q", "L", "T", &mm, nrhs, n, &a[a_offset], lda, &work[itauq], &b[b_offset], ldb, &work[iwork], &i__1, info); /* Generate right bidiagonalizing vectors of R in A (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB) */ i__1 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", n, n, n, &a[a_offset], lda, &work[itaup], &work[iwork], &i__1, info); iwork = ie + *n; /* Perform bidiagonal QR iteration multiply B by transpose of left singular vectors compute right singular vectors in A (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("U", n, n, &c__0, nrhs, &s[1], &work[ie], &a[a_offset], lda, vdum, &c__1, &b[b_offset], ldb, &work[iwork], info); if (*info != 0) { goto L70; } /* Multiply B by reciprocals of singular values Computing MAX */ d__1 = *rcond * s[1]; thr = MAX (d__1, sfmin); if (*rcond < 0.) { /* Computing MAX */ d__1 = eps * s[1]; thr = MAX (d__1, sfmin); } *rank = 0; i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { if (s[i__] > thr) { NUMlapack_drscl (nrhs, &s[i__], &b_ref (i__, 1), ldb); ++ (*rank); } else { NUMlapack_dlaset ("F", &c__1, nrhs, &c_b74, &c_b74, &b_ref (i__, 1), ldb); } /* L10: */ } /* Multiply B by right singular vectors (Workspace: need N, prefer N*NRHS) */ if (*lwork >= *ldb * *nrhs && *nrhs > 1) { NUMblas_dgemm ("T", "N", n, nrhs, n, &c_b108, &a[a_offset], lda, &b[b_offset], ldb, &c_b74, &work[1], ldb); NUMlapack_dlacpy ("G", n, nrhs, &work[1], ldb, &b[b_offset], ldb); } else if (*nrhs > 1) { chunk = *lwork / *n; i__1 = *nrhs; i__2 = chunk; for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) { /* Computing MIN */ i__3 = *nrhs - i__ + 1; bl = MIN (i__3, chunk); NUMblas_dgemm ("T", "N", n, &bl, n, &c_b108, &a[a_offset], lda, &b_ref (1, i__), ldb, &c_b74, &work[1], n); NUMlapack_dlacpy ("G", n, &bl, &work[1], n, &b_ref (1, i__), ldb); /* L20: */ } } else { NUMblas_dgemv ("T", n, n, &c_b108, &a[a_offset], lda, &b[b_offset], &c__1, &c_b74, &work[1], &c__1); NUMblas_dcopy (n, &work[1], &c__1, &b[b_offset], &c__1); } } else { /* if(complicated condition) */ /* Computing MAX */ i__2 = *m, i__1 = (*m << 1) - 4, i__2 = MAX (i__2, i__1), i__2 = MAX (i__2, *nrhs), i__1 = *n - *m * 3; if (*n >= mnthr && *lwork >= (*m << 2) + *m * *m + MAX (i__2, i__1)) { /* Path 2a - underdetermined, with many more columns than rows and sufficient workspace for an efficient algorithm */ ldwork = *m; /* Computing MAX Computing MAX */ i__3 = *m, i__4 = (*m << 1) - 4, i__3 = MAX (i__3, i__4), i__3 = MAX (i__3, *nrhs), i__4 = *n - *m * 3; i__2 = (*m << 2) + *m * *lda + MAX (i__3, i__4), i__1 = *m * *lda + *m + *m * *nrhs; if (*lwork >= MAX (i__2, i__1)) { ldwork = *lda; } itau = 1; iwork = *m + 1; /* Compute A=L*Q (Workspace: need 2*M, prefer M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgelqf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, info); il = iwork; /* Copy L to WORK(IL), zeroing out above it */ NUMlapack_dlacpy ("L", m, m, &a[a_offset], lda, &work[il], &ldwork); i__2 = *m - 1; i__1 = *m - 1; NUMlapack_dlaset ("U", &i__2, &i__1, &c_b74, &c_b74, &work[il + ldwork], &ldwork); ie = il + ldwork * *m; itauq = ie + *m; itaup = itauq + *m; iwork = itaup + *m; /* Bidiagonalize L in WORK(IL) (Workspace: need M*M+5*M, prefer M*M+4*M+2*M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (m, m, &work[il], &ldwork, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, info); /* Multiply B by transpose of left bidiagonalizing vectors of L (Workspace: need M*M+4*M+NRHS, prefer M*M+4*M+NRHS*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dormbr ("Q", "L", "T", m, nrhs, m, &work[il], &ldwork, &work[itauq], &b[b_offset], ldb, &work[iwork], &i__2, info); /* Generate right bidiagonalizing vectors of R in WORK(IL) (Workspace: need M*M+5*M-1, prefer M*M+4*M+(M-1)*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", m, m, m, &work[il], &ldwork, &work[itaup], &work[iwork], &i__2, info); iwork = ie + *m; /* Perform bidiagonal QR iteration, computing right singular vectors of L in WORK(IL) and multiplying B by transpose of left singular vectors (Workspace: need M*M+M+BDSPAC) */ NUMlapack_dbdsqr ("U", m, m, &c__0, nrhs, &s[1], &work[ie], &work[il], &ldwork, &a[a_offset], lda, &b[b_offset], ldb, &work[iwork], info); if (*info != 0) { goto L70; } /* Multiply B by reciprocals of singular values Computing MAX */ d__1 = *rcond * s[1]; thr = MAX (d__1, sfmin); if (*rcond < 0.) { /* Computing MAX */ d__1 = eps * s[1]; thr = MAX (d__1, sfmin); } *rank = 0; i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { if (s[i__] > thr) { NUMlapack_drscl (nrhs, &s[i__], &b_ref (i__, 1), ldb); ++ (*rank); } else { NUMlapack_dlaset ("F", &c__1, nrhs, &c_b74, &c_b74, &b_ref (i__, 1), ldb); } /* L30: */ } iwork = ie; /* Multiply B by right singular vectors of L in WORK(IL) (Workspace: need M*M+2*M, prefer M*M+M+M*NRHS) */ if (*lwork >= *ldb * *nrhs + iwork - 1 && *nrhs > 1) { NUMblas_dgemm ("T", "N", m, nrhs, m, &c_b108, &work[il], &ldwork, &b[b_offset], ldb, &c_b74, &work[iwork], ldb); NUMlapack_dlacpy ("G", m, nrhs, &work[iwork], ldb, &b[b_offset], ldb); } else if (*nrhs > 1) { chunk = (*lwork - iwork + 1) / *m; i__2 = *nrhs; i__1 = chunk; for (i__ = 1; i__1 < 0 ? i__ >= i__2 : i__ <= i__2; i__ += i__1) { /* Computing MIN */ i__3 = *nrhs - i__ + 1; bl = MIN (i__3, chunk); NUMblas_dgemm ("T", "N", m, &bl, m, &c_b108, &work[il], &ldwork, &b_ref (1, i__), ldb, &c_b74, &work[iwork], n); NUMlapack_dlacpy ("G", m, &bl, &work[iwork], n, &b_ref (1, i__), ldb); /* L40: */ } } else { NUMblas_dgemv ("T", m, m, &c_b108, &work[il], &ldwork, &b_ref (1, 1), &c__1, &c_b74, &work[iwork], &c__1); NUMblas_dcopy (m, &work[iwork], &c__1, &b_ref (1, 1), &c__1); } /* Zero out below first M rows of B */ i__1 = *n - *m; NUMlapack_dlaset ("F", &i__1, nrhs, &c_b74, &c_b74, &b_ref (*m + 1, 1), ldb); iwork = itau + *m; /* Multiply transpose(Q) by B (Workspace: need M+NRHS, prefer M+NRHS*NB) */ i__1 = *lwork - iwork + 1; NUMlapack_dormlq ("L", "T", n, nrhs, m, &a[a_offset], lda, &work[itau], &b[b_offset], ldb, &work[iwork], &i__1, info); } else { /* Path 2 - remaining underdetermined cases */ ie = 1; itauq = ie + *m; itaup = itauq + *m; iwork = itaup + *m; /* Bidiagonalize A (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB) */ i__1 = *lwork - iwork + 1; NUMlapack_dgebrd (m, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__1, info); /* Multiply B by transpose of left bidiagonalizing vectors (Workspace: need 3*M+NRHS, prefer 3*M+NRHS*NB) */ i__1 = *lwork - iwork + 1; NUMlapack_dormbr ("Q", "L", "T", m, nrhs, n, &a[a_offset], lda, &work[itauq], &b[b_offset], ldb, &work[iwork], &i__1, info); /* Generate right bidiagonalizing vectors in A (Workspace: need 4*M, prefer 3*M+M*NB) */ i__1 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", m, n, m, &a[a_offset], lda, &work[itaup], &work[iwork], &i__1, info); iwork = ie + *m; /* Perform bidiagonal QR iteration, computing right singular vectors of A in A and multiplying B by transpose of left singular vectors (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("L", m, n, &c__0, nrhs, &s[1], &work[ie], &a[a_offset], lda, vdum, &c__1, &b[b_offset], ldb, &work[iwork], info); if (*info != 0) { goto L70; } /* Multiply B by reciprocals of singular values Computing MAX */ d__1 = *rcond * s[1]; thr = MAX (d__1, sfmin); if (*rcond < 0.) { /* Computing MAX */ d__1 = eps * s[1]; thr = MAX (d__1, sfmin); } *rank = 0; i__1 = *m; for (i__ = 1; i__ <= i__1; ++i__) { if (s[i__] > thr) { NUMlapack_drscl (nrhs, &s[i__], &b_ref (i__, 1), ldb); ++ (*rank); } else { NUMlapack_dlaset ("F", &c__1, nrhs, &c_b74, &c_b74, &b_ref (i__, 1), ldb); } /* L50: */ } /* Multiply B by right singular vectors of A (Workspace: need N, prefer N*NRHS) */ if (*lwork >= *ldb * *nrhs && *nrhs > 1) { NUMblas_dgemm ("T", "N", n, nrhs, m, &c_b108, &a[a_offset], lda, &b[b_offset], ldb, &c_b74, &work[1], ldb); NUMlapack_dlacpy ("F", n, nrhs, &work[1], ldb, &b[b_offset], ldb); } else if (*nrhs > 1) { chunk = *lwork / *n; i__1 = *nrhs; i__2 = chunk; for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) { /* Computing MIN */ i__3 = *nrhs - i__ + 1; bl = MIN (i__3, chunk); NUMblas_dgemm ("T", "N", n, &bl, m, &c_b108, &a[a_offset], lda, &b_ref (1, i__), ldb, &c_b74, &work[1], n); NUMlapack_dlacpy ("F", n, &bl, &work[1], n, &b_ref (1, i__), ldb); /* L60: */ } } else { NUMblas_dgemv ("T", m, n, &c_b108, &a[a_offset], lda, &b[b_offset], &c__1, &c_b74, &work[1], &c__1); NUMblas_dcopy (n, &work[1], &c__1, &b[b_offset], &c__1); } } } /* Undo scaling */ if (iascl == 1) { NUMlapack_dlascl ("G", &c__0, &c__0, &anrm, &smlnum, n, nrhs, &b[b_offset], ldb, info); NUMlapack_dlascl ("G", &c__0, &c__0, &smlnum, &anrm, &minmn, &c__1, &s[1], &minmn, info); } else if (iascl == 2) { NUMlapack_dlascl ("G", &c__0, &c__0, &anrm, &bignum, n, nrhs, &b[b_offset], ldb, info); NUMlapack_dlascl ("G", &c__0, &c__0, &bignum, &anrm, &minmn, &c__1, &s[1], &minmn, info); } if (ibscl == 1) { NUMlapack_dlascl ("G", &c__0, &c__0, &smlnum, &bnrm, n, nrhs, &b[b_offset], ldb, info); } else if (ibscl == 2) { NUMlapack_dlascl ("G", &c__0, &c__0, &bignum, &bnrm, n, nrhs, &b[b_offset], ldb, info); } L70: work[1] = (double) maxwrk; return 0; } /* NUMlapack_dgelss */ #undef b_ref int NUMlapack_dgeqpf (long *m, long *n, double *a, long *lda, long *jpvt, double *tau, double *work, long *info) { /* Table of constant values */ static long c__1 = 1; /* System generated locals */ long a_dim1, a_offset, i__1, i__2, i__3; double d__1, d__2; /* Local variables */ static double temp; static double temp2; static long i__, j; static long itemp; static long ma, mn; static double aii; static long pvt; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --jpvt; --tau; --work; /* Function Body */ *info = 0; if (*m < 0) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < MAX (1, *m)) { *info = -4; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DGEQPF", &i__1); return 0; } mn = MIN (*m, *n); /* Move initial columns up front */ itemp = 1; i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { if (jpvt[i__] != 0) { if (i__ != itemp) { NUMblas_dswap (m, &a_ref (1, i__), &c__1, &a_ref (1, itemp), &c__1); jpvt[i__] = jpvt[itemp]; jpvt[itemp] = i__; } else { jpvt[i__] = i__; } ++itemp; } else { jpvt[i__] = i__; } /* L10: */ } --itemp; /* Compute the QR factorization and update remaining columns */ if (itemp > 0) { ma = MIN (itemp, *m); NUMlapack_dgeqr2 (m, &ma, &a[a_offset], lda, &tau[1], &work[1], info); if (ma < *n) { i__1 = *n - ma; NUMlapack_dorm2r ("Left", "Transpose", m, &i__1, &ma, &a[a_offset], lda, &tau[1], &a_ref (1, ma + 1), lda, &work[1], info); } } if (itemp < mn) { /* Initialize partial column norms. The first n elements of work store the exact column norms. */ i__1 = *n; for (i__ = itemp + 1; i__ <= i__1; ++i__) { i__2 = *m - itemp; work[i__] = NUMblas_dnrm2 (&i__2, &a_ref (itemp + 1, i__), &c__1); work[*n + i__] = work[i__]; /* L20: */ } /* Compute factorization */ i__1 = mn; for (i__ = itemp + 1; i__ <= i__1; ++i__) { /* Determine ith pivot column and swap if necessary */ i__2 = *n - i__ + 1; pvt = i__ - 1 + NUMblas_idamax (&i__2, &work[i__], &c__1); if (pvt != i__) { NUMblas_dswap (m, &a_ref (1, pvt), &c__1, &a_ref (1, i__), &c__1); itemp = jpvt[pvt]; jpvt[pvt] = jpvt[i__]; jpvt[i__] = itemp; work[pvt] = work[i__]; work[*n + pvt] = work[*n + i__]; } /* Generate elementary reflector H(i) */ if (i__ < *m) { i__2 = *m - i__ + 1; NUMlapack_dlarfg (&i__2, &a_ref (i__, i__), &a_ref (i__ + 1, i__), &c__1, &tau[i__]); } else { NUMlapack_dlarfg (&c__1, &a_ref (*m, *m), &a_ref (*m, *m), &c__1, &tau[*m]); } if (i__ < *n) { /* Apply H(i) to A(i:m,i+1:n) from the left */ aii = a_ref (i__, i__); a_ref (i__, i__) = 1.; i__2 = *m - i__ + 1; i__3 = *n - i__; NUMlapack_dlarf ("LEFT", &i__2, &i__3, &a_ref (i__, i__), &c__1, &tau[i__], &a_ref (i__, i__ + 1), lda, &work[ (*n << 1) + 1]); a_ref (i__, i__) = aii; } /* Update partial column norms */ i__2 = *n; for (j = i__ + 1; j <= i__2; ++j) { if (work[j] != 0.) { /* Computing 2nd power */ d__2 = (d__1 = a_ref (i__, j), fabs (d__1)) / work[j]; temp = 1. - d__2 * d__2; temp = MAX (temp, 0.); /* Computing 2nd power */ d__1 = work[j] / work[*n + j]; temp2 = temp * .05 * (d__1 * d__1) + 1.; if (temp2 == 1.) { if (*m - i__ > 0) { i__3 = *m - i__; work[j] = NUMblas_dnrm2 (&i__3, &a_ref (i__ + 1, j), &c__1); work[*n + j] = work[j]; } else { work[j] = 0.; work[*n + j] = 0.; } } else { work[j] *= sqrt (temp); } } /* L30: */ } /* L40: */ } } return 0; } /* NUMlapack_dgeqpf */ int NUMlapack_dgeqr2 (long *m, long *n, double *a, long *lda, double *tau, double *work, long *info) { /* Table of constant values */ static long c__1 = 1; /* System generated locals */ long a_dim1, a_offset, i__1, i__2, i__3; /* Local variables */ static long i__, k; static double aii; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --tau; --work; /* Function Body */ *info = 0; if (*m < 0) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < MAX (1, *m)) { *info = -4; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DGEQR2", &i__1); return 0; } k = MIN (*m, *n); i__1 = k; for (i__ = 1; i__ <= i__1; ++i__) { /* Generate elementary reflector H(i) to annihilate A(i+1:m,i) Computing MIN */ i__2 = i__ + 1; i__3 = *m - i__ + 1; NUMlapack_dlarfg (&i__3, &a_ref (i__, i__), &a_ref (MIN (i__2, *m), i__), &c__1, &tau[i__]); if (i__ < *n) { /* Apply H(i) to A(i:m,i+1:n) from the left */ aii = a_ref (i__, i__); a_ref (i__, i__) = 1.; i__2 = *m - i__ + 1; i__3 = *n - i__; NUMlapack_dlarf ("Left", &i__2, &i__3, &a_ref (i__, i__), &c__1, &tau[i__], &a_ref (i__, i__ + 1), lda, &work[1]); a_ref (i__, i__) = aii; } /* L10: */ } return 0; } /* NUMlapack_dgeqr2 */ int NUMlapack_dgeqrf (long *m, long *n, double *a, long *lda, double *tau, double *work, long *lwork, long *info) { /* Table of constant values */ static long c__1 = 1; static long c_n1 = -1; static long c__3 = 3; static long c__2 = 2; /* System generated locals */ long a_dim1, a_offset, i__1, i__2, i__3, i__4; /* Local variables */ static long i__, k, nbmin, iinfo; static long ib, nb; static long nx; static long ldwork, lwkopt; static long lquery; static long iws; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --tau; --work; /* Function Body */ *info = 0; nb = NUMlapack_ilaenv (&c__1, "DGEQRF", " ", m, n, &c_n1, &c_n1, 6, 1); lwkopt = *n * nb; work[1] = (double) lwkopt; lquery = *lwork == -1; if (*m < 0) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < MAX (1, *m)) { *info = -4; } else if (*lwork < MAX (1, *n) && !lquery) { *info = -7; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DGEQRF", &i__1); return 0; } else if (lquery) { return 0; } /* Quick return if possible */ k = MIN (*m, *n); if (k == 0) { work[1] = 1.; return 0; } nbmin = 2; nx = 0; iws = *n; if (nb > 1 && nb < k) { /* Determine when to cross over from blocked to unblocked code. Computing MAX */ i__1 = 0, i__2 = NUMlapack_ilaenv (&c__3, "DGEQRF", " ", m, n, &c_n1, &c_n1, 6, 1); nx = MAX (i__1, i__2); if (nx < k) { /* Determine if workspace is large enough for blocked code. */ ldwork = *n; iws = ldwork * nb; if (*lwork < iws) { /* Not enough workspace to use optimal NB: reduce NB and determine the minimum value of NB. */ nb = *lwork / ldwork; /* Computing MAX */ i__1 = 2, i__2 = NUMlapack_ilaenv (&c__2, "DGEQRF", " ", m, n, &c_n1, &c_n1, 6, 1); nbmin = MAX (i__1, i__2); } } } if (nb >= nbmin && nb < k && nx < k) { /* Use blocked code initially */ i__1 = k - nx; i__2 = nb; for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) { /* Computing MIN */ i__3 = k - i__ + 1; ib = MIN (i__3, nb); /* Compute the QR factorization of the current block A(i:m,i:i+ib-1) */ i__3 = *m - i__ + 1; NUMlapack_dgeqr2 (&i__3, &ib, &a_ref (i__, i__), lda, &tau[i__], &work[1], &iinfo); if (i__ + ib <= *n) { /* Form the triangular factor of the block reflector H = H(i) H(i+1) . . . H(i+ib-1) */ i__3 = *m - i__ + 1; NUMlapack_dlarft ("Forward", "Columnwise", &i__3, &ib, &a_ref (i__, i__), lda, &tau[i__], &work[1], &ldwork); /* Apply H' to A(i:m,i+ib:n) from the left */ i__3 = *m - i__ + 1; i__4 = *n - i__ - ib + 1; NUMlapack_dlarfb ("Left", "Transpose", "Forward", "Columnwise", &i__3, &i__4, &ib, &a_ref (i__, i__), lda, &work[1], &ldwork, &a_ref (i__, i__ + ib), lda, &work[ib + 1], &ldwork); } /* L10: */ } } else { i__ = 1; } /* Use unblocked code to factor the last or only block. */ if (i__ <= k) { i__2 = *m - i__ + 1; i__1 = *n - i__ + 1; NUMlapack_dgeqr2 (&i__2, &i__1, &a_ref (i__, i__), lda, &tau[i__], &work[1], &iinfo); } work[1] = (double) iws; return 0; } /* NUMlapack_dgeqrf */ int NUMlapack_dgerq2 (long *m, long *n, double *a, long *lda, double *tau, double *work, long *info) { /* System generated locals */ long a_dim1, a_offset, i__1, i__2; /* Local variables */ static long i__, k; static double aii; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --tau; --work; /* Function Body */ *info = 0; if (*m < 0) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < MAX (1, *m)) { *info = -4; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DGERQ2", &i__1); return 0; } k = MIN (*m, *n); for (i__ = k; i__ >= 1; --i__) { /* Generate elementary reflector H(i) to annihilate A(m-k+i,1:n-k+i-1) */ i__1 = *n - k + i__; NUMlapack_dlarfg (&i__1, &a_ref (*m - k + i__, *n - k + i__), &a_ref (*m - k + i__, 1), lda, &tau[i__]); /* Apply H(i) to A(1:m-k+i-1,1:n-k+i) from the right */ aii = a_ref (*m - k + i__, *n - k + i__); a_ref (*m - k + i__, *n - k + i__) = 1.; i__1 = *m - k + i__ - 1; i__2 = *n - k + i__; NUMlapack_dlarf ("Right", &i__1, &i__2, &a_ref (*m - k + i__, 1), lda, &tau[i__], &a[a_offset], lda, &work[1]); a_ref (*m - k + i__, *n - k + i__) = aii; /* L10: */ } return 0; } /* NUMlapack_dgerq2 */ int NUMlapack_dgesv (long *n, long *nrhs, double *a, long *lda, long *ipiv, double *b, long *ldb, long *info) { /* System generated locals */ long a_dim1, a_offset, b_dim1, b_offset, i__1; /* Local variables */ a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --ipiv; b_dim1 = *ldb; b_offset = 1 + b_dim1 * 1; b -= b_offset; /* Function Body */ *info = 0; if (*n < 0) { *info = -1; } else if (*nrhs < 0) { *info = -2; } else if (*lda < MAX (1, *n)) { *info = -4; } else if (*ldb < MAX (1, *n)) { *info = -7; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DGESV ", &i__1); return 0; } /* Compute the LU factorization of A. */ NUMlapack_dgetrf (n, n, &a[a_offset], lda, &ipiv[1], info); if (*info == 0) { /* Solve the system A*X = B, overwriting B with X. */ NUMlapack_dgetrs ("No transpose", n, nrhs, &a[a_offset], lda, &ipiv[1], &b[b_offset], ldb, info); } return 0; } /* NUMlapack_dgesv */ #define u_ref(a_1,a_2) u[(a_2)*u_dim1 + a_1] #define vt_ref(a_1,a_2) vt[(a_2)*vt_dim1 + a_1] int NUMlapack_dgesvd (const char *jobu, const char *jobvt, long *m, long *n, double *a, long *lda, double *s, double *u, long *ldu, double *vt, long *ldvt, double *work, long *lwork, long *info) { /* System generated locals */ const char *a__1[2]; long a_dim1, a_offset, u_dim1, u_offset, vt_dim1, vt_offset, i__1[2], i__2, i__3, i__4; char ch__1[2]; /* Local variables */ static long iscl; static double anrm; static long ierr, itau, ncvt, nrvt, i__; static long chunk, minmn, wrkbl, itaup, itauq, mnthr, iwork; static long wntua, wntva, wntun, wntuo, wntvn, wntvo, wntus, wntvs; static long ie; static long ir, bdspac, iu; static double bignum; static long ldwrkr, minwrk, ldwrku, maxwrk; static double smlnum; static long lquery, wntuas, wntvas; static long blk, ncu; static double dum[1], eps; static long nru; /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --s; u_dim1 = *ldu; u_offset = 1 + u_dim1 * 1; u -= u_offset; vt_dim1 = *ldvt; vt_offset = 1 + vt_dim1 * 1; vt -= vt_offset; --work; /* Function Body */ *info = 0; minmn = MIN (*m, *n); /* Writing concatenation */ i__1[0] = 1, a__1[0] = jobu; i__1[1] = 1, a__1[1] = jobvt; s_cat (ch__1, a__1, i__1, &c__2, 2); mnthr = NUMlapack_ilaenv (&c__6, "DGESVD", ch__1, m, n, &c__0, &c__0, 6, 2); wntua = lsame_ (jobu, "A"); wntus = lsame_ (jobu, "S"); wntuas = wntua || wntus; wntuo = lsame_ (jobu, "O"); wntun = lsame_ (jobu, "N"); wntva = lsame_ (jobvt, "A"); wntvs = lsame_ (jobvt, "S"); wntvas = wntva || wntvs; wntvo = lsame_ (jobvt, "O"); wntvn = lsame_ (jobvt, "N"); minwrk = 1; lquery = *lwork == -1; if (! (wntua || wntus || wntuo || wntun)) { *info = -1; } else if (! (wntva || wntvs || wntvo || wntvn) || wntvo && wntuo) { *info = -2; } else if (*m < 0) { *info = -3; } else if (*n < 0) { *info = -4; } else if (*lda < MAX (1, *m)) { *info = -6; } else if (*ldu < 1 || wntuas && *ldu < *m) { *info = -9; } else if (*ldvt < 1 || wntva && *ldvt < *n || wntvs && *ldvt < minmn) { *info = -11; } /* Compute workspace (Note: Comments in the code beginning "Workspace:" describe the minimal amount of workspace needed at that point in the code, as well as the preferred amount for good performance. NB refers to the optimal block size for the immediately following subroutine, as returned by ILAENV.) */ if (*info == 0 && (*lwork >= 1 || lquery) && *m > 0 && *n > 0) { if (*m >= *n) { /* Compute space needed for DBDSQR */ bdspac = *n * 5; if (*m >= mnthr) { if (wntun) { /* Path 1 (M much larger than N, JOBU='N') */ maxwrk = *n + *n * NUMlapack_ilaenv (&c__1, "DGEQRF", " ", m, n, &c_n1, &c_n1, 6, 1); /* Computing MAX */ i__2 = maxwrk, i__3 = *n * 3 + (*n << 1) * NUMlapack_ilaenv (&c__1, "DGEBRD", " ", n, n, &c_n1, &c_n1, 6, 1); maxwrk = MAX (i__2, i__3); if (wntvo || wntvas) { /* Computing MAX */ i__2 = maxwrk, i__3 = *n * 3 + (*n - 1) * NUMlapack_ilaenv (&c__1, "DORGBR", "P", n, n, n, &c_n1, 6, 1); maxwrk = MAX (i__2, i__3); } maxwrk = MAX (maxwrk, bdspac); /* Computing MAX */ i__2 = *n << 2; minwrk = MAX (i__2, bdspac); maxwrk = MAX (maxwrk, minwrk); } else if (wntuo && wntvn) { /* Path 2 (M much larger than N, JOBU='O', JOBVT='N') */ wrkbl = *n + *n * NUMlapack_ilaenv (&c__1, "DGEQRF", " ", m, n, &c_n1, &c_n1, 6, 1); /* Computing MAX */ i__2 = wrkbl, i__3 = *n + *n * NUMlapack_ilaenv (&c__1, "DORGQR", " ", m, n, n, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *n * 3 + (*n << 1) * NUMlapack_ilaenv (&c__1, "DGEBRD", " ", n, n, &c_n1, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *n * 3 + *n * NUMlapack_ilaenv (&c__1, "DORGBR", "Q", n, n, n, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); wrkbl = MAX (wrkbl, bdspac); /* Computing MAX */ i__2 = *n * *n + wrkbl, i__3 = *n * *n + *m * *n + *n; maxwrk = MAX (i__2, i__3); /* Computing MAX */ i__2 = *n * 3 + *m; minwrk = MAX (i__2, bdspac); maxwrk = MAX (maxwrk, minwrk); } else if (wntuo && wntvas) { /* Path 3 (M much larger than N, JOBU='O', JOBVT='S' or 'A') */ wrkbl = *n + *n * NUMlapack_ilaenv (&c__1, "DGEQRF", " ", m, n, &c_n1, &c_n1, 6, 1); /* Computing MAX */ i__2 = wrkbl, i__3 = *n + *n * NUMlapack_ilaenv (&c__1, "DORGQR", " ", m, n, n, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *n * 3 + (*n << 1) * NUMlapack_ilaenv (&c__1, "DGEBRD", " ", n, n, &c_n1, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *n * 3 + *n * NUMlapack_ilaenv (&c__1, "DORGBR", "Q", n, n, n, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *n * 3 + (*n - 1) * NUMlapack_ilaenv (&c__1, "DORGBR", "P", n, n, n, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); wrkbl = MAX (wrkbl, bdspac); /* Computing MAX */ i__2 = *n * *n + wrkbl, i__3 = *n * *n + *m * *n + *n; maxwrk = MAX (i__2, i__3); /* Computing MAX */ i__2 = *n * 3 + *m; minwrk = MAX (i__2, bdspac); maxwrk = MAX (maxwrk, minwrk); } else if (wntus && wntvn) { /* Path 4 (M much larger than N, JOBU='S', JOBVT='N') */ wrkbl = *n + *n * NUMlapack_ilaenv (&c__1, "DGEQRF", " ", m, n, &c_n1, &c_n1, 6, 1); /* Computing MAX */ i__2 = wrkbl, i__3 = *n + *n * NUMlapack_ilaenv (&c__1, "DORGQR", " ", m, n, n, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *n * 3 + (*n << 1) * NUMlapack_ilaenv (&c__1, "DGEBRD", " ", n, n, &c_n1, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *n * 3 + *n * NUMlapack_ilaenv (&c__1, "DORGBR", "Q", n, n, n, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); wrkbl = MAX (wrkbl, bdspac); maxwrk = *n * *n + wrkbl; /* Computing MAX */ i__2 = *n * 3 + *m; minwrk = MAX (i__2, bdspac); maxwrk = MAX (maxwrk, minwrk); } else if (wntus && wntvo) { /* Path 5 (M much larger than N, JOBU='S', JOBVT='O') */ wrkbl = *n + *n * NUMlapack_ilaenv (&c__1, "DGEQRF", " ", m, n, &c_n1, &c_n1, 6, 1); /* Computing MAX */ i__2 = wrkbl, i__3 = *n + *n * NUMlapack_ilaenv (&c__1, "DORGQR", " ", m, n, n, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *n * 3 + (*n << 1) * NUMlapack_ilaenv (&c__1, "DGEBRD", " ", n, n, &c_n1, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *n * 3 + *n * NUMlapack_ilaenv (&c__1, "DORGBR", "Q", n, n, n, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *n * 3 + (*n - 1) * NUMlapack_ilaenv (&c__1, "DORGBR", "P", n, n, n, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); wrkbl = MAX (wrkbl, bdspac); maxwrk = (*n << 1) * *n + wrkbl; /* Computing MAX */ i__2 = *n * 3 + *m; minwrk = MAX (i__2, bdspac); maxwrk = MAX (maxwrk, minwrk); } else if (wntus && wntvas) { /* Path 6 (M much larger than N, JOBU='S', JOBVT='S' or 'A') */ wrkbl = *n + *n * NUMlapack_ilaenv (&c__1, "DGEQRF", " ", m, n, &c_n1, &c_n1, 6, 1); /* Computing MAX */ i__2 = wrkbl, i__3 = *n + *n * NUMlapack_ilaenv (&c__1, "DORGQR", " ", m, n, n, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *n * 3 + (*n << 1) * NUMlapack_ilaenv (&c__1, "DGEBRD", " ", n, n, &c_n1, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *n * 3 + *n * NUMlapack_ilaenv (&c__1, "DORGBR", "Q", n, n, n, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *n * 3 + (*n - 1) * NUMlapack_ilaenv (&c__1, "DORGBR", "P", n, n, n, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); wrkbl = MAX (wrkbl, bdspac); maxwrk = *n * *n + wrkbl; /* Computing MAX */ i__2 = *n * 3 + *m; minwrk = MAX (i__2, bdspac); maxwrk = MAX (maxwrk, minwrk); } else if (wntua && wntvn) { /* Path 7 (M much larger than N, JOBU='A', JOBVT='N') */ wrkbl = *n + *n * NUMlapack_ilaenv (&c__1, "DGEQRF", " ", m, n, &c_n1, &c_n1, 6, 1); /* Computing MAX */ i__2 = wrkbl, i__3 = *n + *m * NUMlapack_ilaenv (&c__1, "DORGQR", " ", m, m, n, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *n * 3 + (*n << 1) * NUMlapack_ilaenv (&c__1, "DGEBRD", " ", n, n, &c_n1, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *n * 3 + *n * NUMlapack_ilaenv (&c__1, "DORGBR", "Q", n, n, n, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); wrkbl = MAX (wrkbl, bdspac); maxwrk = *n * *n + wrkbl; /* Computing MAX */ i__2 = *n * 3 + *m; minwrk = MAX (i__2, bdspac); maxwrk = MAX (maxwrk, minwrk); } else if (wntua && wntvo) { /* Path 8 (M much larger than N, JOBU='A', JOBVT='O') */ wrkbl = *n + *n * NUMlapack_ilaenv (&c__1, "DGEQRF", " ", m, n, &c_n1, &c_n1, 6, 1); /* Computing MAX */ i__2 = wrkbl, i__3 = *n + *m * NUMlapack_ilaenv (&c__1, "DORGQR", " ", m, m, n, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *n * 3 + (*n << 1) * NUMlapack_ilaenv (&c__1, "DGEBRD", " ", n, n, &c_n1, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *n * 3 + *n * NUMlapack_ilaenv (&c__1, "DORGBR", "Q", n, n, n, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *n * 3 + (*n - 1) * NUMlapack_ilaenv (&c__1, "DORGBR", "P", n, n, n, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); wrkbl = MAX (wrkbl, bdspac); maxwrk = (*n << 1) * *n + wrkbl; /* Computing MAX */ i__2 = *n * 3 + *m; minwrk = MAX (i__2, bdspac); maxwrk = MAX (maxwrk, minwrk); } else if (wntua && wntvas) { /* Path 9 (M much larger than N, JOBU='A', JOBVT='S' or 'A') */ wrkbl = *n + *n * NUMlapack_ilaenv (&c__1, "DGEQRF", " ", m, n, &c_n1, &c_n1, 6, 1); /* Computing MAX */ i__2 = wrkbl, i__3 = *n + *m * NUMlapack_ilaenv (&c__1, "DORGQR", " ", m, m, n, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *n * 3 + (*n << 1) * NUMlapack_ilaenv (&c__1, "DGEBRD", " ", n, n, &c_n1, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *n * 3 + *n * NUMlapack_ilaenv (&c__1, "DORGBR", "Q", n, n, n, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *n * 3 + (*n - 1) * NUMlapack_ilaenv (&c__1, "DORGBR", "P", n, n, n, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); wrkbl = MAX (wrkbl, bdspac); maxwrk = *n * *n + wrkbl; /* Computing MAX */ i__2 = *n * 3 + *m; minwrk = MAX (i__2, bdspac); maxwrk = MAX (maxwrk, minwrk); } } else { /* Path 10 (M at least N, but not much larger) */ maxwrk = *n * 3 + (*m + *n) * NUMlapack_ilaenv (&c__1, "DGEBRD", " ", m, n, &c_n1, &c_n1, 6, 1); if (wntus || wntuo) { /* Computing MAX */ i__2 = maxwrk, i__3 = *n * 3 + *n * NUMlapack_ilaenv (&c__1, "DORG" "BR", "Q", m, n, n, &c_n1, 6, 1); maxwrk = MAX (i__2, i__3); } if (wntua) { /* Computing MAX */ i__2 = maxwrk, i__3 = *n * 3 + *m * NUMlapack_ilaenv (&c__1, "DORG" "BR", "Q", m, m, n, &c_n1, 6, 1); maxwrk = MAX (i__2, i__3); } if (!wntvn) { /* Computing MAX */ i__2 = maxwrk, i__3 = *n * 3 + (*n - 1) * NUMlapack_ilaenv (&c__1, "DORGBR", "P", n, n, n, &c_n1, 6, 1); maxwrk = MAX (i__2, i__3); } maxwrk = MAX (maxwrk, bdspac); /* Computing MAX */ i__2 = *n * 3 + *m; minwrk = MAX (i__2, bdspac); maxwrk = MAX (maxwrk, minwrk); } } else { /* Compute space needed for DBDSQR */ bdspac = *m * 5; if (*n >= mnthr) { if (wntvn) { /* Path 1t(N much larger than M, JOBVT='N') */ maxwrk = *m + *m * NUMlapack_ilaenv (&c__1, "DGELQF", " ", m, n, &c_n1, &c_n1, 6, 1); /* Computing MAX */ i__2 = maxwrk, i__3 = *m * 3 + (*m << 1) * NUMlapack_ilaenv (&c__1, "DGEBRD", " ", m, m, &c_n1, &c_n1, 6, 1); maxwrk = MAX (i__2, i__3); if (wntuo || wntuas) { /* Computing MAX */ i__2 = maxwrk, i__3 = *m * 3 + *m * NUMlapack_ilaenv (&c__1, "DORGBR", "Q", m, m, m, &c_n1, 6, 1); maxwrk = MAX (i__2, i__3); } maxwrk = MAX (maxwrk, bdspac); /* Computing MAX */ i__2 = *m << 2; minwrk = MAX (i__2, bdspac); maxwrk = MAX (maxwrk, minwrk); } else if (wntvo && wntun) { /* Path 2t(N much larger than M, JOBU='N', JOBVT='O') */ wrkbl = *m + *m * NUMlapack_ilaenv (&c__1, "DGELQF", " ", m, n, &c_n1, &c_n1, 6, 1); /* Computing MAX */ i__2 = wrkbl, i__3 = *m + *m * NUMlapack_ilaenv (&c__1, "DORGLQ", " ", m, n, m, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *m * 3 + (*m << 1) * NUMlapack_ilaenv (&c__1, "DGEBRD", " ", m, m, &c_n1, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *m * 3 + (*m - 1) * NUMlapack_ilaenv (&c__1, "DORGBR", "P", m, m, m, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); wrkbl = MAX (wrkbl, bdspac); /* Computing MAX */ i__2 = *m * *m + wrkbl, i__3 = *m * *m + *m * *n + *m; maxwrk = MAX (i__2, i__3); /* Computing MAX */ i__2 = *m * 3 + *n; minwrk = MAX (i__2, bdspac); maxwrk = MAX (maxwrk, minwrk); } else if (wntvo && wntuas) { /* Path 3t(N much larger than M, JOBU='S' or 'A', JOBVT='O') */ wrkbl = *m + *m * NUMlapack_ilaenv (&c__1, "DGELQF", " ", m, n, &c_n1, &c_n1, 6, 1); /* Computing MAX */ i__2 = wrkbl, i__3 = *m + *m * NUMlapack_ilaenv (&c__1, "DORGLQ", " ", m, n, m, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *m * 3 + (*m << 1) * NUMlapack_ilaenv (&c__1, "DGEBRD", " ", m, m, &c_n1, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *m * 3 + (*m - 1) * NUMlapack_ilaenv (&c__1, "DORGBR", "P", m, m, m, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *m * 3 + *m * NUMlapack_ilaenv (&c__1, "DORGBR", "Q", m, m, m, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); wrkbl = MAX (wrkbl, bdspac); /* Computing MAX */ i__2 = *m * *m + wrkbl, i__3 = *m * *m + *m * *n + *m; maxwrk = MAX (i__2, i__3); /* Computing MAX */ i__2 = *m * 3 + *n; minwrk = MAX (i__2, bdspac); maxwrk = MAX (maxwrk, minwrk); } else if (wntvs && wntun) { /* Path 4t(N much larger than M, JOBU='N', JOBVT='S') */ wrkbl = *m + *m * NUMlapack_ilaenv (&c__1, "DGELQF", " ", m, n, &c_n1, &c_n1, 6, 1); /* Computing MAX */ i__2 = wrkbl, i__3 = *m + *m * NUMlapack_ilaenv (&c__1, "DORGLQ", " ", m, n, m, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *m * 3 + (*m << 1) * NUMlapack_ilaenv (&c__1, "DGEBRD", " ", m, m, &c_n1, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *m * 3 + (*m - 1) * NUMlapack_ilaenv (&c__1, "DORGBR", "P", m, m, m, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); wrkbl = MAX (wrkbl, bdspac); maxwrk = *m * *m + wrkbl; /* Computing MAX */ i__2 = *m * 3 + *n; minwrk = MAX (i__2, bdspac); maxwrk = MAX (maxwrk, minwrk); } else if (wntvs && wntuo) { /* Path 5t(N much larger than M, JOBU='O', JOBVT='S') */ wrkbl = *m + *m * NUMlapack_ilaenv (&c__1, "DGELQF", " ", m, n, &c_n1, &c_n1, 6, 1); /* Computing MAX */ i__2 = wrkbl, i__3 = *m + *m * NUMlapack_ilaenv (&c__1, "DORGLQ", " ", m, n, m, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *m * 3 + (*m << 1) * NUMlapack_ilaenv (&c__1, "DGEBRD", " ", m, m, &c_n1, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *m * 3 + (*m - 1) * NUMlapack_ilaenv (&c__1, "DORGBR", "P", m, m, m, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *m * 3 + *m * NUMlapack_ilaenv (&c__1, "DORGBR", "Q", m, m, m, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); wrkbl = MAX (wrkbl, bdspac); maxwrk = (*m << 1) * *m + wrkbl; /* Computing MAX */ i__2 = *m * 3 + *n; minwrk = MAX (i__2, bdspac); maxwrk = MAX (maxwrk, minwrk); } else if (wntvs && wntuas) { /* Path 6t(N much larger than M, JOBU='S' or 'A', JOBVT='S') */ wrkbl = *m + *m * NUMlapack_ilaenv (&c__1, "DGELQF", " ", m, n, &c_n1, &c_n1, 6, 1); /* Computing MAX */ i__2 = wrkbl, i__3 = *m + *m * NUMlapack_ilaenv (&c__1, "DORGLQ", " ", m, n, m, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *m * 3 + (*m << 1) * NUMlapack_ilaenv (&c__1, "DGEBRD", " ", m, m, &c_n1, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *m * 3 + (*m - 1) * NUMlapack_ilaenv (&c__1, "DORGBR", "P", m, m, m, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *m * 3 + *m * NUMlapack_ilaenv (&c__1, "DORGBR", "Q", m, m, m, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); wrkbl = MAX (wrkbl, bdspac); maxwrk = *m * *m + wrkbl; /* Computing MAX */ i__2 = *m * 3 + *n; minwrk = MAX (i__2, bdspac); maxwrk = MAX (maxwrk, minwrk); } else if (wntva && wntun) { /* Path 7t(N much larger than M, JOBU='N', JOBVT='A') */ wrkbl = *m + *m * NUMlapack_ilaenv (&c__1, "DGELQF", " ", m, n, &c_n1, &c_n1, 6, 1); /* Computing MAX */ i__2 = wrkbl, i__3 = *m + *n * NUMlapack_ilaenv (&c__1, "DORGLQ", " ", n, n, m, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *m * 3 + (*m << 1) * NUMlapack_ilaenv (&c__1, "DGEBRD", " ", m, m, &c_n1, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *m * 3 + (*m - 1) * NUMlapack_ilaenv (&c__1, "DORGBR", "P", m, m, m, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); wrkbl = MAX (wrkbl, bdspac); maxwrk = *m * *m + wrkbl; /* Computing MAX */ i__2 = *m * 3 + *n; minwrk = MAX (i__2, bdspac); maxwrk = MAX (maxwrk, minwrk); } else if (wntva && wntuo) { /* Path 8t(N much larger than M, JOBU='O', JOBVT='A') */ wrkbl = *m + *m * NUMlapack_ilaenv (&c__1, "DGELQF", " ", m, n, &c_n1, &c_n1, 6, 1); /* Computing MAX */ i__2 = wrkbl, i__3 = *m + *n * NUMlapack_ilaenv (&c__1, "DORGLQ", " ", n, n, m, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *m * 3 + (*m << 1) * NUMlapack_ilaenv (&c__1, "DGEBRD", " ", m, m, &c_n1, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *m * 3 + (*m - 1) * NUMlapack_ilaenv (&c__1, "DORGBR", "P", m, m, m, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *m * 3 + *m * NUMlapack_ilaenv (&c__1, "DORGBR", "Q", m, m, m, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); wrkbl = MAX (wrkbl, bdspac); maxwrk = (*m << 1) * *m + wrkbl; /* Computing MAX */ i__2 = *m * 3 + *n; minwrk = MAX (i__2, bdspac); maxwrk = MAX (maxwrk, minwrk); } else if (wntva && wntuas) { /* Path 9t(N much larger than M, JOBU='S' or 'A', JOBVT='A') */ wrkbl = *m + *m * NUMlapack_ilaenv (&c__1, "DGELQF", " ", m, n, &c_n1, &c_n1, 6, 1); /* Computing MAX */ i__2 = wrkbl, i__3 = *m + *n * NUMlapack_ilaenv (&c__1, "DORGLQ", " ", n, n, m, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *m * 3 + (*m << 1) * NUMlapack_ilaenv (&c__1, "DGEBRD", " ", m, m, &c_n1, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *m * 3 + (*m - 1) * NUMlapack_ilaenv (&c__1, "DORGBR", "P", m, m, m, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); /* Computing MAX */ i__2 = wrkbl, i__3 = *m * 3 + *m * NUMlapack_ilaenv (&c__1, "DORGBR", "Q", m, m, m, &c_n1, 6, 1); wrkbl = MAX (i__2, i__3); wrkbl = MAX (wrkbl, bdspac); maxwrk = *m * *m + wrkbl; /* Computing MAX */ i__2 = *m * 3 + *n; minwrk = MAX (i__2, bdspac); maxwrk = MAX (maxwrk, minwrk); } } else { /* Path 10t(N greater than M, but not much larger) */ maxwrk = *m * 3 + (*m + *n) * NUMlapack_ilaenv (&c__1, "DGEBRD", " ", m, n, &c_n1, &c_n1, 6, 1); if (wntvs || wntvo) { /* Computing MAX */ i__2 = maxwrk, i__3 = *m * 3 + *m * NUMlapack_ilaenv (&c__1, "DORG" "BR", "P", m, n, m, &c_n1, 6, 1); maxwrk = MAX (i__2, i__3); } if (wntva) { /* Computing MAX */ i__2 = maxwrk, i__3 = *m * 3 + *n * NUMlapack_ilaenv (&c__1, "DORG" "BR", "P", n, n, m, &c_n1, 6, 1); maxwrk = MAX (i__2, i__3); } if (!wntun) { /* Computing MAX */ i__2 = maxwrk, i__3 = *m * 3 + (*m - 1) * NUMlapack_ilaenv (&c__1, "DORGBR", "Q", m, m, m, &c_n1, 6, 1); maxwrk = MAX (i__2, i__3); } maxwrk = MAX (maxwrk, bdspac); /* Computing MAX */ i__2 = *m * 3 + *n; minwrk = MAX (i__2, bdspac); maxwrk = MAX (maxwrk, minwrk); } } work[1] = (double) maxwrk; } if (*lwork < minwrk && !lquery) { *info = -13; } if (*info != 0) { i__2 = - (*info); xerbla_ ("DGESVD", &i__2); return 0; } else if (lquery) { return 0; } /* Quick return if possible */ if (*m == 0 || *n == 0) { if (*lwork >= 1) { work[1] = 1.; } return 0; } /* Get machine constants */ eps = NUMblas_dlamch ("P"); smlnum = sqrt (NUMblas_dlamch ("S")) / eps; bignum = 1. / smlnum; /* Scale A if max element outside range [SMLNUM,BIGNUM] */ anrm = NUMlapack_dlange ("M", m, n, &a[a_offset], lda, dum); iscl = 0; if (anrm > 0. && anrm < smlnum) { iscl = 1; NUMlapack_dlascl ("G", &c__0, &c__0, &anrm, &smlnum, m, n, &a[a_offset], lda, &ierr); } else if (anrm > bignum) { iscl = 1; NUMlapack_dlascl ("G", &c__0, &c__0, &anrm, &bignum, m, n, &a[a_offset], lda, &ierr); } if (*m >= *n) { /* A has at least as many rows as columns. If A has sufficiently more rows than columns, first reduce using the QR decomposition (if sufficient workspace available) */ if (*m >= mnthr) { if (wntun) { /* Path 1 (M much larger than N, JOBU='N') No left singular vectors to be computed */ itau = 1; iwork = itau + *n; /* Compute A=Q*R (Workspace: need 2*N, prefer N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgeqrf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); /* Zero out below R */ i__2 = *n - 1; i__3 = *n - 1; NUMlapack_dlaset ("L", &i__2, &i__3, &c_b416, &c_b416, &a_ref (2, 1), lda); ie = 1; itauq = ie + *n; itaup = itauq + *n; iwork = itaup + *n; /* Bidiagonalize R in A (Workspace: need 4*N, prefer 3*N+2*N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (n, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); ncvt = 0; if (wntvo || wntvas) { /* If right singular vectors desired, generate P'. (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", n, n, n, &a[a_offset], lda, &work[itaup], &work[iwork], &i__2, &ierr); ncvt = *n; } iwork = ie + *n; /* Perform bidiagonal QR iteration, computing right singular vectors of A in A if desired (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("U", n, &ncvt, &c__0, &c__0, &s[1], &work[ie], &a[a_offset], lda, dum, &c__1, dum, &c__1, &work[iwork], info); /* If right singular vectors desired in VT, copy them there */ if (wntvas) { NUMlapack_dlacpy ("F", n, n, &a[a_offset], lda, &vt[vt_offset], ldvt); } } else if (wntuo && wntvn) { /* Path 2 (M much larger than N, JOBU='O', JOBVT='N') N left singular vectors to be overwritten on A and no right singular vectors to be computed Computing MAX */ i__2 = *n << 2; if (*lwork >= *n * *n + MAX (i__2, bdspac)) { /* Sufficient workspace for a fast algorithm */ ir = 1; /* Computing MAX */ i__2 = wrkbl, i__3 = *lda * *n + *n; if (*lwork >= MAX (i__2, i__3) + *lda * *n) { /* WORK(IU) is LDA by N, WORK(IR) is LDA by N */ ldwrku = *lda; ldwrkr = *lda; } else { /* if(complicated condition) */ /* Computing MAX */ i__2 = wrkbl, i__3 = *lda * *n + *n; if (*lwork >= MAX (i__2, i__3) + *n * *n) { /* WORK(IU) is LDA by N, WORK(IR) is N by N */ ldwrku = *lda; ldwrkr = *n; } else { /* WORK(IU) is LDWRKU by N, WORK(IR) is N by N */ ldwrku = (*lwork - *n * *n - *n) / *n; ldwrkr = *n; } } itau = ir + ldwrkr * *n; iwork = itau + *n; /* Compute A=Q*R (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgeqrf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); /* Copy R to WORK(IR) and zero out below it */ NUMlapack_dlacpy ("U", n, n, &a[a_offset], lda, &work[ir], &ldwrkr); i__2 = *n - 1; i__3 = *n - 1; NUMlapack_dlaset ("L", &i__2, &i__3, &c_b416, &c_b416, &work[ir + 1], &ldwrkr); /* Generate Q in A (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgqr (m, n, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); ie = itau; itauq = ie + *n; itaup = itauq + *n; iwork = itaup + *n; /* Bidiagonalize R in WORK(IR) (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (n, n, &work[ir], &ldwrkr, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); /* Generate left vectors bidiagonalizing R (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("Q", n, n, n, &work[ir], &ldwrkr, &work[itauq], &work[iwork], &i__2, &ierr); iwork = ie + *n; /* Perform bidiagonal QR iteration, computing left singular vectors of R in WORK(IR) (Workspace: need N*N+BDSPAC) */ NUMlapack_dbdsqr ("U", n, &c__0, n, &c__0, &s[1], &work[ie], dum, &c__1, &work[ir], &ldwrkr, dum, &c__1, &work[iwork], info); iu = ie + *n; /* Multiply Q in A by left singular vectors of R in WORK(IR), storing result in WORK(IU) and copying to A (Workspace: need N*N+2*N, prefer N*N+M*N+N) */ i__2 = *m; i__3 = ldwrku; for (i__ = 1; i__3 < 0 ? i__ >= i__2 : i__ <= i__2; i__ += i__3) { /* Computing MIN */ i__4 = *m - i__ + 1; chunk = MIN (i__4, ldwrku); NUMblas_dgemm ("N", "N", &chunk, n, n, &c_b438, &a_ref (i__, 1), lda, &work[ir], &ldwrkr, &c_b416, &work[iu], &ldwrku); NUMlapack_dlacpy ("F", &chunk, n, &work[iu], &ldwrku, &a_ref (i__, 1), lda); /* L10: */ } } else { /* Insufficient workspace for a fast algorithm */ ie = 1; itauq = ie + *n; itaup = itauq + *n; iwork = itaup + *n; /* Bidiagonalize A (Workspace: need 3*N+M, prefer 3*N+(M+N)*NB) */ i__3 = *lwork - iwork + 1; NUMlapack_dgebrd (m, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__3, &ierr); /* Generate left vectors bidiagonalizing A (Workspace: need 4*N, prefer 3*N+N*NB) */ i__3 = *lwork - iwork + 1; NUMlapack_dorgbr ("Q", m, n, n, &a[a_offset], lda, &work[itauq], &work[iwork], &i__3, &ierr); iwork = ie + *n; /* Perform bidiagonal QR iteration, computing left singular vectors of A in A (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("U", n, &c__0, m, &c__0, &s[1], &work[ie], dum, &c__1, &a[a_offset], lda, dum, &c__1, &work[iwork], info); } } else if (wntuo && wntvas) { /* Path 3 (M much larger than N, JOBU='O', JOBVT='S' or 'A') N left singular vectors to be overwritten on A and N right singular vectors to be computed in VT Computing MAX */ i__3 = *n << 2; if (*lwork >= *n * *n + MAX (i__3, bdspac)) { /* Sufficient workspace for a fast algorithm */ ir = 1; /* Computing MAX */ i__3 = wrkbl, i__2 = *lda * *n + *n; if (*lwork >= MAX (i__3, i__2) + *lda * *n) { /* WORK(IU) is LDA by N and WORK(IR) is LDA by N */ ldwrku = *lda; ldwrkr = *lda; } else { /* if(complicated condition) */ /* Computing MAX */ i__3 = wrkbl, i__2 = *lda * *n + *n; if (*lwork >= MAX (i__3, i__2) + *n * *n) { /* WORK(IU) is LDA by N and WORK(IR) is N by N */ ldwrku = *lda; ldwrkr = *n; } else { /* WORK(IU) is LDWRKU by N and WORK(IR) is N by N */ ldwrku = (*lwork - *n * *n - *n) / *n; ldwrkr = *n; } } itau = ir + ldwrkr * *n; iwork = itau + *n; /* Compute A=Q*R (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */ i__3 = *lwork - iwork + 1; NUMlapack_dgeqrf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__3, &ierr); /* Copy R to VT, zeroing out below it */ NUMlapack_dlacpy ("U", n, n, &a[a_offset], lda, &vt[vt_offset], ldvt); i__3 = *n - 1; i__2 = *n - 1; NUMlapack_dlaset ("L", &i__3, &i__2, &c_b416, &c_b416, &vt_ref (2, 1), ldvt); /* Generate Q in A (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */ i__3 = *lwork - iwork + 1; NUMlapack_dorgqr (m, n, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__3, &ierr); ie = itau; itauq = ie + *n; itaup = itauq + *n; iwork = itaup + *n; /* Bidiagonalize R in VT, copying result to WORK(IR) (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB) */ i__3 = *lwork - iwork + 1; NUMlapack_dgebrd (n, n, &vt[vt_offset], ldvt, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__3, &ierr); NUMlapack_dlacpy ("L", n, n, &vt[vt_offset], ldvt, &work[ir], &ldwrkr); /* Generate left vectors bidiagonalizing R in WORK(IR) (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB) */ i__3 = *lwork - iwork + 1; NUMlapack_dorgbr ("Q", n, n, n, &work[ir], &ldwrkr, &work[itauq], &work[iwork], &i__3, &ierr); /* Generate right vectors bidiagonalizing R in VT (Workspace: need N*N+4*N-1, prefer N*N+3*N+(N-1)*NB) */ i__3 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", n, n, n, &vt[vt_offset], ldvt, &work[itaup], &work[iwork], &i__3, &ierr); iwork = ie + *n; /* Perform bidiagonal QR iteration, computing left singular vectors of R in WORK(IR) and computing right singular vectors of R in VT (Workspace: need N*N+BDSPAC) */ NUMlapack_dbdsqr ("U", n, n, n, &c__0, &s[1], &work[ie], &vt[vt_offset], ldvt, &work[ir], &ldwrkr, dum, &c__1, &work[iwork], info); iu = ie + *n; /* Multiply Q in A by left singular vectors of R in WORK(IR), storing result in WORK(IU) and copying to A (Workspace: need N*N+2*N, prefer N*N+M*N+N) */ i__3 = *m; i__2 = ldwrku; for (i__ = 1; i__2 < 0 ? i__ >= i__3 : i__ <= i__3; i__ += i__2) { /* Computing MIN */ i__4 = *m - i__ + 1; chunk = MIN (i__4, ldwrku); NUMblas_dgemm ("N", "N", &chunk, n, n, &c_b438, &a_ref (i__, 1), lda, &work[ir], &ldwrkr, &c_b416, &work[iu], &ldwrku); NUMlapack_dlacpy ("F", &chunk, n, &work[iu], &ldwrku, &a_ref (i__, 1), lda); /* L20: */ } } else { /* Insufficient workspace for a fast algorithm */ itau = 1; iwork = itau + *n; /* Compute A=Q*R (Workspace: need 2*N, prefer N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgeqrf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); /* Copy R to VT, zeroing out below it */ NUMlapack_dlacpy ("U", n, n, &a[a_offset], lda, &vt[vt_offset], ldvt); i__2 = *n - 1; i__3 = *n - 1; NUMlapack_dlaset ("L", &i__2, &i__3, &c_b416, &c_b416, &vt_ref (2, 1), ldvt); /* Generate Q in A (Workspace: need 2*N, prefer N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgqr (m, n, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); ie = itau; itauq = ie + *n; itaup = itauq + *n; iwork = itaup + *n; /* Bidiagonalize R in VT (Workspace: need 4*N, prefer 3*N+2*N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (n, n, &vt[vt_offset], ldvt, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); /* Multiply Q in A by left vectors bidiagonalizing R (Workspace: need 3*N+M, prefer 3*N+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dormbr ("Q", "R", "N", m, n, n, &vt[vt_offset], ldvt, &work[itauq], &a[a_offset], lda, &work[iwork], &i__2, &ierr); /* Generate right vectors bidiagonalizing R in VT (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", n, n, n, &vt[vt_offset], ldvt, &work[itaup], &work[iwork], &i__2, &ierr); iwork = ie + *n; /* Perform bidiagonal QR iteration, computing left singular vectors of A in A and computing right singular vectors of A in VT (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("U", n, n, m, &c__0, &s[1], &work[ie], &vt[vt_offset], ldvt, &a[a_offset], lda, dum, &c__1, &work[iwork], info); } } else if (wntus) { if (wntvn) { /* Path 4 (M much larger than N, JOBU='S', JOBVT='N') N left singular vectors to be computed in U and no right singular vectors to be computed Computing MAX */ i__2 = *n << 2; if (*lwork >= *n * *n + MAX (i__2, bdspac)) { /* Sufficient workspace for a fast algorithm */ ir = 1; if (*lwork >= wrkbl + *lda * *n) { /* WORK(IR) is LDA by N */ ldwrkr = *lda; } else { /* WORK(IR) is N by N */ ldwrkr = *n; } itau = ir + ldwrkr * *n; iwork = itau + *n; /* Compute A=Q*R (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgeqrf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); /* Copy R to WORK(IR), zeroing out below it */ NUMlapack_dlacpy ("U", n, n, &a[a_offset], lda, &work[ir], &ldwrkr); i__2 = *n - 1; i__3 = *n - 1; NUMlapack_dlaset ("L", &i__2, &i__3, &c_b416, &c_b416, &work[ir + 1], &ldwrkr); /* Generate Q in A (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgqr (m, n, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); ie = itau; itauq = ie + *n; itaup = itauq + *n; iwork = itaup + *n; /* Bidiagonalize R in WORK(IR) (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (n, n, &work[ir], &ldwrkr, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); /* Generate left vectors bidiagonalizing R in WORK(IR) (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("Q", n, n, n, &work[ir], &ldwrkr, &work[itauq], &work[iwork], &i__2, &ierr); iwork = ie + *n; /* Perform bidiagonal QR iteration, computing left singular vectors of R in WORK(IR) (Workspace: need N*N+BDSPAC) */ NUMlapack_dbdsqr ("U", n, &c__0, n, &c__0, &s[1], &work[ie], dum, &c__1, &work[ir], &ldwrkr, dum, &c__1, &work[iwork], info); /* Multiply Q in A by left singular vectors of R in WORK(IR), storing result in U (Workspace: need N*N) */ NUMblas_dgemm ("N", "N", m, n, n, &c_b438, &a[a_offset], lda, &work[ir], &ldwrkr, &c_b416, &u[u_offset], ldu); } else { /* Insufficient workspace for a fast algorithm */ itau = 1; iwork = itau + *n; /* Compute A=Q*R, copying result to U (Workspace: need 2*N, prefer N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgeqrf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); NUMlapack_dlacpy ("L", m, n, &a[a_offset], lda, &u[u_offset], ldu); /* Generate Q in U (Workspace: need 2*N, prefer N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgqr (m, n, n, &u[u_offset], ldu, &work[itau], &work[iwork], &i__2, &ierr); ie = itau; itauq = ie + *n; itaup = itauq + *n; iwork = itaup + *n; /* Zero out below R in A */ i__2 = *n - 1; i__3 = *n - 1; NUMlapack_dlaset ("L", &i__2, &i__3, &c_b416, &c_b416, &a_ref (2, 1), lda); /* Bidiagonalize R in A (Workspace: need 4*N, prefer 3*N+2*N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (n, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); /* Multiply Q in U by left vectors bidiagonalizing R (Workspace: need 3*N+M, prefer 3*N+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dormbr ("Q", "R", "N", m, n, n, &a[a_offset], lda, &work[itauq], &u[u_offset], ldu, &work[iwork], &i__2, &ierr); iwork = ie + *n; /* Perform bidiagonal QR iteration, computing left singular vectors of A in U (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("U", n, &c__0, m, &c__0, &s[1], &work[ie], dum, &c__1, &u[u_offset], ldu, dum, &c__1, &work[iwork], info); } } else if (wntvo) { /* Path 5 (M much larger than N, JOBU='S', JOBVT='O') N left singular vectors to be computed in U and N right singular vectors to be overwritten on A Computing MAX */ i__2 = *n << 2; if (*lwork >= (*n << 1) * *n + MAX (i__2, bdspac)) { /* Sufficient workspace for a fast algorithm */ iu = 1; if (*lwork >= wrkbl + (*lda << 1) * *n) { /* WORK(IU) is LDA by N and WORK(IR) is LDA by N */ ldwrku = *lda; ir = iu + ldwrku * *n; ldwrkr = *lda; } else if (*lwork >= wrkbl + (*lda + *n) * *n) { /* WORK(IU) is LDA by N and WORK(IR) is N by N */ ldwrku = *lda; ir = iu + ldwrku * *n; ldwrkr = *n; } else { /* WORK(IU) is N by N and WORK(IR) is N by N */ ldwrku = *n; ir = iu + ldwrku * *n; ldwrkr = *n; } itau = ir + ldwrkr * *n; iwork = itau + *n; /* Compute A=Q*R (Workspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgeqrf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); /* Copy R to WORK(IU), zeroing out below it */ NUMlapack_dlacpy ("U", n, n, &a[a_offset], lda, &work[iu], &ldwrku); i__2 = *n - 1; i__3 = *n - 1; NUMlapack_dlaset ("L", &i__2, &i__3, &c_b416, &c_b416, &work[iu + 1], &ldwrku); /* Generate Q in A (Workspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgqr (m, n, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); ie = itau; itauq = ie + *n; itaup = itauq + *n; iwork = itaup + *n; /* Bidiagonalize R in WORK(IU), copying result to WORK(IR) (Workspace: need 2*N*N+4*N, prefer 2*N*N+3*N+2*N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (n, n, &work[iu], &ldwrku, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); NUMlapack_dlacpy ("U", n, n, &work[iu], &ldwrku, &work[ir], &ldwrkr); /* Generate left bidiagonalizing vectors in WORK(IU) (Workspace: need 2*N*N+4*N, prefer 2*N*N+3*N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("Q", n, n, n, &work[iu], &ldwrku, &work[itauq], &work[iwork], &i__2, &ierr); /* Generate right bidiagonalizing vectors in WORK(IR) (Workspace: need 2*N*N+4*N-1, prefer 2*N*N+3*N+(N-1)*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", n, n, n, &work[ir], &ldwrkr, &work[itaup], &work[iwork], &i__2, &ierr); iwork = ie + *n; /* Perform bidiagonal QR iteration, computing left singular vectors of R in WORK(IU) and computing right singular vectors of R in WORK(IR) (Workspace: need 2*N*N+BDSPAC) */ NUMlapack_dbdsqr ("U", n, n, n, &c__0, &s[1], &work[ie], &work[ir], &ldwrkr, &work[iu], &ldwrku, dum, &c__1, &work[iwork], info); /* Multiply Q in A by left singular vectors of R in WORK(IU), storing result in U (Workspace: need N*N) */ NUMblas_dgemm ("N", "N", m, n, n, &c_b438, &a[a_offset], lda, &work[iu], &ldwrku, &c_b416, &u[u_offset], ldu); /* Copy right singular vectors of R to A (Workspace: need N*N) */ NUMlapack_dlacpy ("F", n, n, &work[ir], &ldwrkr, &a[a_offset], lda); } else { /* Insufficient workspace for a fast algorithm */ itau = 1; iwork = itau + *n; /* Compute A=Q*R, copying result to U (Workspace: need 2*N, prefer N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgeqrf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); NUMlapack_dlacpy ("L", m, n, &a[a_offset], lda, &u[u_offset], ldu); /* Generate Q in U (Workspace: need 2*N, prefer N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgqr (m, n, n, &u[u_offset], ldu, &work[itau], &work[iwork], &i__2, &ierr); ie = itau; itauq = ie + *n; itaup = itauq + *n; iwork = itaup + *n; /* Zero out below R in A */ i__2 = *n - 1; i__3 = *n - 1; NUMlapack_dlaset ("L", &i__2, &i__3, &c_b416, &c_b416, &a_ref (2, 1), lda); /* Bidiagonalize R in A (Workspace: need 4*N, prefer 3*N+2*N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (n, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); /* Multiply Q in U by left vectors bidiagonalizing R (Workspace: need 3*N+M, prefer 3*N+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dormbr ("Q", "R", "N", m, n, n, &a[a_offset], lda, &work[itauq], &u[u_offset], ldu, &work[iwork], &i__2, &ierr); /* Generate right vectors bidiagonalizing R in A (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", n, n, n, &a[a_offset], lda, &work[itaup], &work[iwork], &i__2, &ierr); iwork = ie + *n; /* Perform bidiagonal QR iteration, computing left singular vectors of A in U and computing right singular vectors of A in A (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("U", n, n, m, &c__0, &s[1], &work[ie], &a[a_offset], lda, &u[u_offset], ldu, dum, &c__1, &work[iwork], info); } } else if (wntvas) { /* Path 6 (M much larger than N, JOBU='S', JOBVT='S' or 'A') N left singular vectors to be computed in U and N right singular vectors to be computed in VT Computing MAX */ i__2 = *n << 2; if (*lwork >= *n * *n + MAX (i__2, bdspac)) { /* Sufficient workspace for a fast algorithm */ iu = 1; if (*lwork >= wrkbl + *lda * *n) { /* WORK(IU) is LDA by N */ ldwrku = *lda; } else { /* WORK(IU) is N by N */ ldwrku = *n; } itau = iu + ldwrku * *n; iwork = itau + *n; /* Compute A=Q*R (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgeqrf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); /* Copy R to WORK(IU), zeroing out below it */ NUMlapack_dlacpy ("U", n, n, &a[a_offset], lda, &work[iu], &ldwrku); i__2 = *n - 1; i__3 = *n - 1; NUMlapack_dlaset ("L", &i__2, &i__3, &c_b416, &c_b416, &work[iu + 1], &ldwrku); /* Generate Q in A (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgqr (m, n, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); ie = itau; itauq = ie + *n; itaup = itauq + *n; iwork = itaup + *n; /* Bidiagonalize R in WORK(IU), copying result to VT (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (n, n, &work[iu], &ldwrku, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); NUMlapack_dlacpy ("U", n, n, &work[iu], &ldwrku, &vt[vt_offset], ldvt); /* Generate left bidiagonalizing vectors in WORK(IU) (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("Q", n, n, n, &work[iu], &ldwrku, &work[itauq], &work[iwork], &i__2, &ierr); /* Generate right bidiagonalizing vectors in VT (Workspace: need N*N+4*N-1, prefer N*N+3*N+(N-1)*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", n, n, n, &vt[vt_offset], ldvt, &work[itaup], &work[iwork], &i__2, &ierr); iwork = ie + *n; /* Perform bidiagonal QR iteration, computing left singular vectors of R in WORK(IU) and computing right singular vectors of R in VT (Workspace: need N*N+BDSPAC) */ NUMlapack_dbdsqr ("U", n, n, n, &c__0, &s[1], &work[ie], &vt[vt_offset], ldvt, &work[iu], &ldwrku, dum, &c__1, &work[iwork], info); /* Multiply Q in A by left singular vectors of R in WORK(IU), storing result in U (Workspace: need N*N) */ NUMblas_dgemm ("N", "N", m, n, n, &c_b438, &a[a_offset], lda, &work[iu], &ldwrku, &c_b416, &u[u_offset], ldu); } else { /* Insufficient workspace for a fast algorithm */ itau = 1; iwork = itau + *n; /* Compute A=Q*R, copying result to U (Workspace: need 2*N, prefer N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgeqrf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); NUMlapack_dlacpy ("L", m, n, &a[a_offset], lda, &u[u_offset], ldu); /* Generate Q in U (Workspace: need 2*N, prefer N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgqr (m, n, n, &u[u_offset], ldu, &work[itau], &work[iwork], &i__2, &ierr); /* Copy R to VT, zeroing out below it */ NUMlapack_dlacpy ("U", n, n, &a[a_offset], lda, &vt[vt_offset], ldvt); i__2 = *n - 1; i__3 = *n - 1; NUMlapack_dlaset ("L", &i__2, &i__3, &c_b416, &c_b416, &vt_ref (2, 1), ldvt); ie = itau; itauq = ie + *n; itaup = itauq + *n; iwork = itaup + *n; /* Bidiagonalize R in VT (Workspace: need 4*N, prefer 3*N+2*N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (n, n, &vt[vt_offset], ldvt, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); /* Multiply Q in U by left bidiagonalizing vectors in VT (Workspace: need 3*N+M, prefer 3*N+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dormbr ("Q", "R", "N", m, n, n, &vt[vt_offset], ldvt, &work[itauq], &u[u_offset], ldu, &work[iwork], &i__2, &ierr); /* Generate right bidiagonalizing vectors in VT (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", n, n, n, &vt[vt_offset], ldvt, &work[itaup], &work[iwork], &i__2, &ierr); iwork = ie + *n; /* Perform bidiagonal QR iteration, computing left singular vectors of A in U and computing right singular vectors of A in VT (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("U", n, n, m, &c__0, &s[1], &work[ie], &vt[vt_offset], ldvt, &u[u_offset], ldu, dum, &c__1, &work[iwork], info); } } } else if (wntua) { if (wntvn) { /* Path 7 (M much larger than N, JOBU='A', JOBVT='N') M left singular vectors to be computed in U and no right singular vectors to be computed Computing MAX */ i__2 = *n + *m, i__3 = *n << 2, i__2 = MAX (i__2, i__3); if (*lwork >= *n * *n + MAX (i__2, bdspac)) { /* Sufficient workspace for a fast algorithm */ ir = 1; if (*lwork >= wrkbl + *lda * *n) { /* WORK(IR) is LDA by N */ ldwrkr = *lda; } else { /* WORK(IR) is N by N */ ldwrkr = *n; } itau = ir + ldwrkr * *n; iwork = itau + *n; /* Compute A=Q*R, copying result to U (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgeqrf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); NUMlapack_dlacpy ("L", m, n, &a[a_offset], lda, &u[u_offset], ldu); /* Copy R to WORK(IR), zeroing out below it */ NUMlapack_dlacpy ("U", n, n, &a[a_offset], lda, &work[ir], &ldwrkr); i__2 = *n - 1; i__3 = *n - 1; NUMlapack_dlaset ("L", &i__2, &i__3, &c_b416, &c_b416, &work[ir + 1], &ldwrkr); /* Generate Q in U (Workspace: need N*N+N+M, prefer N*N+N+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgqr (m, m, n, &u[u_offset], ldu, &work[itau], &work[iwork], &i__2, &ierr); ie = itau; itauq = ie + *n; itaup = itauq + *n; iwork = itaup + *n; /* Bidiagonalize R in WORK(IR) (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (n, n, &work[ir], &ldwrkr, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); /* Generate left bidiagonalizing vectors in WORK(IR) (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("Q", n, n, n, &work[ir], &ldwrkr, &work[itauq], &work[iwork], &i__2, &ierr); iwork = ie + *n; /* Perform bidiagonal QR iteration, computing left singular vectors of R in WORK(IR) (Workspace: need N*N+BDSPAC) */ NUMlapack_dbdsqr ("U", n, &c__0, n, &c__0, &s[1], &work[ie], dum, &c__1, &work[ir], &ldwrkr, dum, &c__1, &work[iwork], info); /* Multiply Q in U by left singular vectors of R in WORK(IR), storing result in A (Workspace: need N*N) */ NUMblas_dgemm ("N", "N", m, n, n, &c_b438, &u[u_offset], ldu, &work[ir], &ldwrkr, &c_b416, &a[a_offset], lda); /* Copy left singular vectors of A from A to U */ NUMlapack_dlacpy ("F", m, n, &a[a_offset], lda, &u[u_offset], ldu); } else { /* Insufficient workspace for a fast algorithm */ itau = 1; iwork = itau + *n; /* Compute A=Q*R, copying result to U (Workspace: need 2*N, prefer N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgeqrf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); NUMlapack_dlacpy ("L", m, n, &a[a_offset], lda, &u[u_offset], ldu); /* Generate Q in U (Workspace: need N+M, prefer N+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgqr (m, m, n, &u[u_offset], ldu, &work[itau], &work[iwork], &i__2, &ierr); ie = itau; itauq = ie + *n; itaup = itauq + *n; iwork = itaup + *n; /* Zero out below R in A */ i__2 = *n - 1; i__3 = *n - 1; NUMlapack_dlaset ("L", &i__2, &i__3, &c_b416, &c_b416, &a_ref (2, 1), lda); /* Bidiagonalize R in A (Workspace: need 4*N, prefer 3*N+2*N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (n, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); /* Multiply Q in U by left bidiagonalizing vectors in A (Workspace: need 3*N+M, prefer 3*N+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dormbr ("Q", "R", "N", m, n, n, &a[a_offset], lda, &work[itauq], &u[u_offset], ldu, &work[iwork], &i__2, &ierr); iwork = ie + *n; /* Perform bidiagonal QR iteration, computing left singular vectors of A in U (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("U", n, &c__0, m, &c__0, &s[1], &work[ie], dum, &c__1, &u[u_offset], ldu, dum, &c__1, &work[iwork], info); } } else if (wntvo) { /* Path 8 (M much larger than N, JOBU='A', JOBVT='O') M left singular vectors to be computed in U and N right singular vectors to be overwritten on A Computing MAX */ i__2 = *n + *m, i__3 = *n << 2, i__2 = MAX (i__2, i__3); if (*lwork >= (*n << 1) * *n + MAX (i__2, bdspac)) { /* Sufficient workspace for a fast algorithm */ iu = 1; if (*lwork >= wrkbl + (*lda << 1) * *n) { /* WORK(IU) is LDA by N and WORK(IR) is LDA by N */ ldwrku = *lda; ir = iu + ldwrku * *n; ldwrkr = *lda; } else if (*lwork >= wrkbl + (*lda + *n) * *n) { /* WORK(IU) is LDA by N and WORK(IR) is N by N */ ldwrku = *lda; ir = iu + ldwrku * *n; ldwrkr = *n; } else { /* WORK(IU) is N by N and WORK(IR) is N by N */ ldwrku = *n; ir = iu + ldwrku * *n; ldwrkr = *n; } itau = ir + ldwrkr * *n; iwork = itau + *n; /* Compute A=Q*R, copying result to U (Workspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgeqrf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); NUMlapack_dlacpy ("L", m, n, &a[a_offset], lda, &u[u_offset], ldu); /* Generate Q in U (Workspace: need 2*N*N+N+M, prefer 2*N*N+N+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgqr (m, m, n, &u[u_offset], ldu, &work[itau], &work[iwork], &i__2, &ierr); /* Copy R to WORK(IU), zeroing out below it */ NUMlapack_dlacpy ("U", n, n, &a[a_offset], lda, &work[iu], &ldwrku); i__2 = *n - 1; i__3 = *n - 1; NUMlapack_dlaset ("L", &i__2, &i__3, &c_b416, &c_b416, &work[iu + 1], &ldwrku); ie = itau; itauq = ie + *n; itaup = itauq + *n; iwork = itaup + *n; /* Bidiagonalize R in WORK(IU), copying result to WORK(IR) (Workspace: need 2*N*N+4*N, prefer 2*N*N+3*N+2*N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (n, n, &work[iu], &ldwrku, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); NUMlapack_dlacpy ("U", n, n, &work[iu], &ldwrku, &work[ir], &ldwrkr); /* Generate left bidiagonalizing vectors in WORK(IU) (Workspace: need 2*N*N+4*N, prefer 2*N*N+3*N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("Q", n, n, n, &work[iu], &ldwrku, &work[itauq], &work[iwork], &i__2, &ierr); /* Generate right bidiagonalizing vectors in WORK(IR) (Workspace: need 2*N*N+4*N-1, prefer 2*N*N+3*N+(N-1)*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", n, n, n, &work[ir], &ldwrkr, &work[itaup], &work[iwork], &i__2, &ierr); iwork = ie + *n; /* Perform bidiagonal QR iteration, computing left singular vectors of R in WORK(IU) and computing right singular vectors of R in WORK(IR) (Workspace: need 2*N*N+BDSPAC) */ NUMlapack_dbdsqr ("U", n, n, n, &c__0, &s[1], &work[ie], &work[ir], &ldwrkr, &work[iu], &ldwrku, dum, &c__1, &work[iwork], info); /* Multiply Q in U by left singular vectors of R in WORK(IU), storing result in A (Workspace: need N*N) */ NUMblas_dgemm ("N", "N", m, n, n, &c_b438, &u[u_offset], ldu, &work[iu], &ldwrku, &c_b416, &a[a_offset], lda); /* Copy left singular vectors of A from A to U */ NUMlapack_dlacpy ("F", m, n, &a[a_offset], lda, &u[u_offset], ldu); /* Copy right singular vectors of R from WORK(IR) to A */ NUMlapack_dlacpy ("F", n, n, &work[ir], &ldwrkr, &a[a_offset], lda); } else { /* Insufficient workspace for a fast algorithm */ itau = 1; iwork = itau + *n; /* Compute A=Q*R, copying result to U (Workspace: need 2*N, prefer N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgeqrf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); NUMlapack_dlacpy ("L", m, n, &a[a_offset], lda, &u[u_offset], ldu); /* Generate Q in U (Workspace: need N+M, prefer N+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgqr (m, m, n, &u[u_offset], ldu, &work[itau], &work[iwork], &i__2, &ierr); ie = itau; itauq = ie + *n; itaup = itauq + *n; iwork = itaup + *n; /* Zero out below R in A */ i__2 = *n - 1; i__3 = *n - 1; NUMlapack_dlaset ("L", &i__2, &i__3, &c_b416, &c_b416, &a_ref (2, 1), lda); /* Bidiagonalize R in A (Workspace: need 4*N, prefer 3*N+2*N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (n, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); /* Multiply Q in U by left bidiagonalizing vectors in A (Workspace: need 3*N+M, prefer 3*N+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dormbr ("Q", "R", "N", m, n, n, &a[a_offset], lda, &work[itauq], &u[u_offset], ldu, &work[iwork], &i__2, &ierr); /* Generate right bidiagonalizing vectors in A (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", n, n, n, &a[a_offset], lda, &work[itaup], &work[iwork], &i__2, &ierr); iwork = ie + *n; /* Perform bidiagonal QR iteration, computing left singular vectors of A in U and computing right singular vectors of A in A (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("U", n, n, m, &c__0, &s[1], &work[ie], &a[a_offset], lda, &u[u_offset], ldu, dum, &c__1, &work[iwork], info); } } else if (wntvas) { /* Path 9 (M much larger than N, JOBU='A', JOBVT='S' or 'A') M left singular vectors to be computed in U and N right singular vectors to be computed in VT Computing MAX */ i__2 = *n + *m, i__3 = *n << 2, i__2 = MAX (i__2, i__3); if (*lwork >= *n * *n + MAX (i__2, bdspac)) { /* Sufficient workspace for a fast algorithm */ iu = 1; if (*lwork >= wrkbl + *lda * *n) { /* WORK(IU) is LDA by N */ ldwrku = *lda; } else { /* WORK(IU) is N by N */ ldwrku = *n; } itau = iu + ldwrku * *n; iwork = itau + *n; /* Compute A=Q*R, copying result to U (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgeqrf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); NUMlapack_dlacpy ("L", m, n, &a[a_offset], lda, &u[u_offset], ldu); /* Generate Q in U (Workspace: need N*N+N+M, prefer N*N+N+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgqr (m, m, n, &u[u_offset], ldu, &work[itau], &work[iwork], &i__2, &ierr); /* Copy R to WORK(IU), zeroing out below it */ NUMlapack_dlacpy ("U", n, n, &a[a_offset], lda, &work[iu], &ldwrku); i__2 = *n - 1; i__3 = *n - 1; NUMlapack_dlaset ("L", &i__2, &i__3, &c_b416, &c_b416, &work[iu + 1], &ldwrku); ie = itau; itauq = ie + *n; itaup = itauq + *n; iwork = itaup + *n; /* Bidiagonalize R in WORK(IU), copying result to VT (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (n, n, &work[iu], &ldwrku, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); NUMlapack_dlacpy ("U", n, n, &work[iu], &ldwrku, &vt[vt_offset], ldvt); /* Generate left bidiagonalizing vectors in WORK(IU) (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("Q", n, n, n, &work[iu], &ldwrku, &work[itauq], &work[iwork], &i__2, &ierr); /* Generate right bidiagonalizing vectors in VT (Workspace: need N*N+4*N-1, prefer N*N+3*N+(N-1)*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", n, n, n, &vt[vt_offset], ldvt, &work[itaup], &work[iwork], &i__2, &ierr); iwork = ie + *n; /* Perform bidiagonal QR iteration, computing left singular vectors of R in WORK(IU) and computing right singular vectors of R in VT (Workspace: need N*N+BDSPAC) */ NUMlapack_dbdsqr ("U", n, n, n, &c__0, &s[1], &work[ie], &vt[vt_offset], ldvt, &work[iu], &ldwrku, dum, &c__1, &work[iwork], info); /* Multiply Q in U by left singular vectors of R in WORK(IU), storing result in A (Workspace: need N*N) */ NUMblas_dgemm ("N", "N", m, n, n, &c_b438, &u[u_offset], ldu, &work[iu], &ldwrku, &c_b416, &a[a_offset], lda); /* Copy left singular vectors of A from A to U */ NUMlapack_dlacpy ("F", m, n, &a[a_offset], lda, &u[u_offset], ldu); } else { /* Insufficient workspace for a fast algorithm */ itau = 1; iwork = itau + *n; /* Compute A=Q*R, copying result to U (Workspace: need 2*N, prefer N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgeqrf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); NUMlapack_dlacpy ("L", m, n, &a[a_offset], lda, &u[u_offset], ldu); /* Generate Q in U (Workspace: need N+M, prefer N+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgqr (m, m, n, &u[u_offset], ldu, &work[itau], &work[iwork], &i__2, &ierr); /* Copy R from A to VT, zeroing out below it */ NUMlapack_dlacpy ("U", n, n, &a[a_offset], lda, &vt[vt_offset], ldvt); i__2 = *n - 1; i__3 = *n - 1; NUMlapack_dlaset ("L", &i__2, &i__3, &c_b416, &c_b416, &vt_ref (2, 1), ldvt); ie = itau; itauq = ie + *n; itaup = itauq + *n; iwork = itaup + *n; /* Bidiagonalize R in VT (Workspace: need 4*N, prefer 3*N+2*N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (n, n, &vt[vt_offset], ldvt, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); /* Multiply Q in U by left bidiagonalizing vectors in VT (Workspace: need 3*N+M, prefer 3*N+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dormbr ("Q", "R", "N", m, n, n, &vt[vt_offset], ldvt, &work[itauq], &u[u_offset], ldu, &work[iwork], &i__2, &ierr); /* Generate right bidiagonalizing vectors in VT (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", n, n, n, &vt[vt_offset], ldvt, &work[itaup], &work[iwork], &i__2, &ierr); iwork = ie + *n; /* Perform bidiagonal QR iteration, computing left singular vectors of A in U and computing right singular vectors of A in VT (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("U", n, n, m, &c__0, &s[1], &work[ie], &vt[vt_offset], ldvt, &u[u_offset], ldu, dum, &c__1, &work[iwork], info); } } } } else { /* M .LT. MNTHR Path 10 (M at least N, but not much larger) Reduce to bidiagonal form without QR decomposition */ ie = 1; itauq = ie + *n; itaup = itauq + *n; iwork = itaup + *n; /* Bidiagonalize A (Workspace: need 3*N+M, prefer 3*N+(M+N)*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (m, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); if (wntuas) { /* If left singular vectors desired in U, copy result to U and generate left bidiagonalizing vectors in U (Workspace: need 3*N+NCU, prefer 3*N+NCU*NB) */ NUMlapack_dlacpy ("L", m, n, &a[a_offset], lda, &u[u_offset], ldu); if (wntus) { ncu = *n; } if (wntua) { ncu = *m; } i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("Q", m, &ncu, n, &u[u_offset], ldu, &work[itauq], &work[iwork], &i__2, &ierr); } if (wntvas) { /* If right singular vectors desired in VT, copy result to VT and generate right bidiagonalizing vectors in VT (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB) */ NUMlapack_dlacpy ("U", n, n, &a[a_offset], lda, &vt[vt_offset], ldvt); i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", n, n, n, &vt[vt_offset], ldvt, &work[itaup], &work[iwork], &i__2, &ierr); } if (wntuo) { /* If left singular vectors desired in A, generate left bidiagonalizing vectors in A (Workspace: need 4*N, prefer 3*N+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("Q", m, n, n, &a[a_offset], lda, &work[itauq], &work[iwork], &i__2, &ierr); } if (wntvo) { /* If right singular vectors desired in A, generate right bidiagonalizing vectors in A (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", n, n, n, &a[a_offset], lda, &work[itaup], &work[iwork], &i__2, &ierr); } iwork = ie + *n; if (wntuas || wntuo) { nru = *m; } if (wntun) { nru = 0; } if (wntvas || wntvo) { ncvt = *n; } if (wntvn) { ncvt = 0; } if (!wntuo && !wntvo) { /* Perform bidiagonal QR iteration, if desired, computing left singular vectors in U and computing right singular vectors in VT (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("U", n, &ncvt, &nru, &c__0, &s[1], &work[ie], &vt[vt_offset], ldvt, &u[u_offset], ldu, dum, &c__1, &work[iwork], info); } else if (!wntuo && wntvo) { /* Perform bidiagonal QR iteration, if desired, computing left singular vectors in U and computing right singular vectors in A (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("U", n, &ncvt, &nru, &c__0, &s[1], &work[ie], &a[a_offset], lda, &u[u_offset], ldu, dum, &c__1, &work[iwork], info); } else { /* Perform bidiagonal QR iteration, if desired, computing left singular vectors in A and computing right singular vectors in VT (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("U", n, &ncvt, &nru, &c__0, &s[1], &work[ie], &vt[vt_offset], ldvt, &a[a_offset], lda, dum, &c__1, &work[iwork], info); } } } else { /* A has more columns than rows. If A has sufficiently more columns than rows, first reduce using the LQ decomposition (if sufficient workspace available) */ if (*n >= mnthr) { if (wntvn) { /* Path 1t(N much larger than M, JOBVT='N') No right singular vectors to be computed */ itau = 1; iwork = itau + *m; /* Compute A=L*Q (Workspace: need 2*M, prefer M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgelqf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); /* Zero out above L */ i__2 = *m - 1; i__3 = *m - 1; NUMlapack_dlaset ("U", &i__2, &i__3, &c_b416, &c_b416, &a_ref (1, 2), lda); ie = 1; itauq = ie + *m; itaup = itauq + *m; iwork = itaup + *m; /* Bidiagonalize L in A (Workspace: need 4*M, prefer 3*M+2*M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (m, m, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); if (wntuo || wntuas) { /* If left singular vectors desired, generate Q (Workspace: need 4*M, prefer 3*M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("Q", m, m, m, &a[a_offset], lda, &work[itauq], &work[iwork], &i__2, &ierr); } iwork = ie + *m; nru = 0; if (wntuo || wntuas) { nru = *m; } /* Perform bidiagonal QR iteration, computing left singular vectors of A in A if desired (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("U", m, &c__0, &nru, &c__0, &s[1], &work[ie], dum, &c__1, &a[a_offset], lda, dum, &c__1, &work[iwork], info); /* If left singular vectors desired in U, copy them there */ if (wntuas) { NUMlapack_dlacpy ("F", m, m, &a[a_offset], lda, &u[u_offset], ldu); } } else if (wntvo && wntun) { /* Path 2t(N much larger than M, JOBU='N', JOBVT='O') M right singular vectors to be overwritten on A and no left singular vectors to be computed Computing MAX */ i__2 = *m << 2; if (*lwork >= *m * *m + MAX (i__2, bdspac)) { /* Sufficient workspace for a fast algorithm */ ir = 1; /* Computing MAX */ i__2 = wrkbl, i__3 = *lda * *n + *m; if (*lwork >= MAX (i__2, i__3) + *lda * *m) { /* WORK(IU) is LDA by N and WORK(IR) is LDA by M */ ldwrku = *lda; chunk = *n; ldwrkr = *lda; } else { /* if(complicated condition) */ /* Computing MAX */ i__2 = wrkbl, i__3 = *lda * *n + *m; if (*lwork >= MAX (i__2, i__3) + *m * *m) { /* WORK(IU) is LDA by N and WORK(IR) is M by M */ ldwrku = *lda; chunk = *n; ldwrkr = *m; } else { /* WORK(IU) is M by CHUNK and WORK(IR) is M by M */ ldwrku = *m; chunk = (*lwork - *m * *m - *m) / *m; ldwrkr = *m; } } itau = ir + ldwrkr * *m; iwork = itau + *m; /* Compute A=L*Q (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgelqf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); /* Copy L to WORK(IR) and zero out above it */ NUMlapack_dlacpy ("L", m, m, &a[a_offset], lda, &work[ir], &ldwrkr); i__2 = *m - 1; i__3 = *m - 1; NUMlapack_dlaset ("U", &i__2, &i__3, &c_b416, &c_b416, &work[ir + ldwrkr], &ldwrkr); /* Generate Q in A (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorglq (m, n, m, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); ie = itau; itauq = ie + *m; itaup = itauq + *m; iwork = itaup + *m; /* Bidiagonalize L in WORK(IR) (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (m, m, &work[ir], &ldwrkr, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); /* Generate right vectors bidiagonalizing L (Workspace: need M*M+4*M-1, prefer M*M+3*M+(M-1)*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", m, m, m, &work[ir], &ldwrkr, &work[itaup], &work[iwork], &i__2, &ierr); iwork = ie + *m; /* Perform bidiagonal QR iteration, computing right singular vectors of L in WORK(IR) (Workspace: need M*M+BDSPAC) */ NUMlapack_dbdsqr ("U", m, m, &c__0, &c__0, &s[1], &work[ie], &work[ir], &ldwrkr, dum, &c__1, dum, &c__1, &work[iwork], info); iu = ie + *m; /* Multiply right singular vectors of L in WORK(IR) by Q in A, storing result in WORK(IU) and copying to A (Workspace: need M*M+2*M, prefer M*M+M*N+M) */ i__2 = *n; i__3 = chunk; for (i__ = 1; i__3 < 0 ? i__ >= i__2 : i__ <= i__2; i__ += i__3) { /* Computing MIN */ i__4 = *n - i__ + 1; blk = MIN (i__4, chunk); NUMblas_dgemm ("N", "N", m, &blk, m, &c_b438, &work[ir], &ldwrkr, &a_ref (1, i__), lda, &c_b416, &work[iu], &ldwrku); NUMlapack_dlacpy ("F", m, &blk, &work[iu], &ldwrku, &a_ref (1, i__), lda); /* L30: */ } } else { /* Insufficient workspace for a fast algorithm */ ie = 1; itauq = ie + *m; itaup = itauq + *m; iwork = itaup + *m; /* Bidiagonalize A (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB) */ i__3 = *lwork - iwork + 1; NUMlapack_dgebrd (m, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__3, &ierr); /* Generate right vectors bidiagonalizing A (Workspace: need 4*M, prefer 3*M+M*NB) */ i__3 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", m, n, m, &a[a_offset], lda, &work[itaup], &work[iwork], &i__3, &ierr); iwork = ie + *m; /* Perform bidiagonal QR iteration, computing right singular vectors of A in A (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("L", m, n, &c__0, &c__0, &s[1], &work[ie], &a[a_offset], lda, dum, &c__1, dum, &c__1, &work[iwork], info); } } else if (wntvo && wntuas) { /* Path 3t(N much larger than M, JOBU='S' or 'A', JOBVT='O') M right singular vectors to be overwritten on A and M left singular vectors to be computed in U Computing MAX */ i__3 = *m << 2; if (*lwork >= *m * *m + MAX (i__3, bdspac)) { /* Sufficient workspace for a fast algorithm */ ir = 1; /* Computing MAX */ i__3 = wrkbl, i__2 = *lda * *n + *m; if (*lwork >= MAX (i__3, i__2) + *lda * *m) { /* WORK(IU) is LDA by N and WORK(IR) is LDA by M */ ldwrku = *lda; chunk = *n; ldwrkr = *lda; } else { /* if(complicated condition) */ /* Computing MAX */ i__3 = wrkbl, i__2 = *lda * *n + *m; if (*lwork >= MAX (i__3, i__2) + *m * *m) { /* WORK(IU) is LDA by N and WORK(IR) is M by M */ ldwrku = *lda; chunk = *n; ldwrkr = *m; } else { /* WORK(IU) is M by CHUNK and WORK(IR) is M by M */ ldwrku = *m; chunk = (*lwork - *m * *m - *m) / *m; ldwrkr = *m; } } itau = ir + ldwrkr * *m; iwork = itau + *m; /* Compute A=L*Q (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */ i__3 = *lwork - iwork + 1; NUMlapack_dgelqf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__3, &ierr); /* Copy L to U, zeroing about above it */ NUMlapack_dlacpy ("L", m, m, &a[a_offset], lda, &u[u_offset], ldu); i__3 = *m - 1; i__2 = *m - 1; NUMlapack_dlaset ("U", &i__3, &i__2, &c_b416, &c_b416, &u_ref (1, 2), ldu); /* Generate Q in A (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */ i__3 = *lwork - iwork + 1; NUMlapack_dorglq (m, n, m, &a[a_offset], lda, &work[itau], &work[iwork], &i__3, &ierr); ie = itau; itauq = ie + *m; itaup = itauq + *m; iwork = itaup + *m; /* Bidiagonalize L in U, copying result to WORK(IR) (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB) */ i__3 = *lwork - iwork + 1; NUMlapack_dgebrd (m, m, &u[u_offset], ldu, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__3, &ierr); NUMlapack_dlacpy ("U", m, m, &u[u_offset], ldu, &work[ir], &ldwrkr); /* Generate right vectors bidiagonalizing L in WORK(IR) (Workspace: need M*M+4*M-1, prefer M*M+3*M+(M-1)*NB) */ i__3 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", m, m, m, &work[ir], &ldwrkr, &work[itaup], &work[iwork], &i__3, &ierr); /* Generate left vectors bidiagonalizing L in U (Workspace: need M*M+4*M, prefer M*M+3*M+M*NB) */ i__3 = *lwork - iwork + 1; NUMlapack_dorgbr ("Q", m, m, m, &u[u_offset], ldu, &work[itauq], &work[iwork], &i__3, &ierr); iwork = ie + *m; /* Perform bidiagonal QR iteration, computing left singular vectors of L in U, and computing right singular vectors of L in WORK(IR) (Workspace: need M*M+BDSPAC) */ NUMlapack_dbdsqr ("U", m, m, m, &c__0, &s[1], &work[ie], &work[ir], &ldwrkr, &u[u_offset], ldu, dum, &c__1, &work[iwork], info); iu = ie + *m; /* Multiply right singular vectors of L in WORK(IR) by Q in A, storing result in WORK(IU) and copying to A (Workspace: need M*M+2*M, prefer M*M+M*N+M)) */ i__3 = *n; i__2 = chunk; for (i__ = 1; i__2 < 0 ? i__ >= i__3 : i__ <= i__3; i__ += i__2) { /* Computing MIN */ i__4 = *n - i__ + 1; blk = MIN (i__4, chunk); NUMblas_dgemm ("N", "N", m, &blk, m, &c_b438, &work[ir], &ldwrkr, &a_ref (1, i__), lda, &c_b416, &work[iu], &ldwrku); NUMlapack_dlacpy ("F", m, &blk, &work[iu], &ldwrku, &a_ref (1, i__), lda); /* L40: */ } } else { /* Insufficient workspace for a fast algorithm */ itau = 1; iwork = itau + *m; /* Compute A=L*Q (Workspace: need 2*M, prefer M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgelqf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); /* Copy L to U, zeroing out above it */ NUMlapack_dlacpy ("L", m, m, &a[a_offset], lda, &u[u_offset], ldu); i__2 = *m - 1; i__3 = *m - 1; NUMlapack_dlaset ("U", &i__2, &i__3, &c_b416, &c_b416, &u_ref (1, 2), ldu); /* Generate Q in A (Workspace: need 2*M, prefer M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorglq (m, n, m, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); ie = itau; itauq = ie + *m; itaup = itauq + *m; iwork = itaup + *m; /* Bidiagonalize L in U (Workspace: need 4*M, prefer 3*M+2*M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (m, m, &u[u_offset], ldu, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); /* Multiply right vectors bidiagonalizing L by Q in A (Workspace: need 3*M+N, prefer 3*M+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dormbr ("P", "L", "T", m, n, m, &u[u_offset], ldu, &work[itaup], &a[a_offset], lda, &work[iwork], &i__2, &ierr); /* Generate left vectors bidiagonalizing L in U (Workspace: need 4*M, prefer 3*M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("Q", m, m, m, &u[u_offset], ldu, &work[itauq], &work[iwork], &i__2, &ierr); iwork = ie + *m; /* Perform bidiagonal QR iteration, computing left singular vectors of A in U and computing right singular vectors of A in A (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("U", m, n, m, &c__0, &s[1], &work[ie], &a[a_offset], lda, &u[u_offset], ldu, dum, &c__1, &work[iwork], info); } } else if (wntvs) { if (wntun) { /* Path 4t(N much larger than M, JOBU='N', JOBVT='S') M right singular vectors to be computed in VT and no left singular vectors to be computed Computing MAX */ i__2 = *m << 2; if (*lwork >= *m * *m + MAX (i__2, bdspac)) { /* Sufficient workspace for a fast algorithm */ ir = 1; if (*lwork >= wrkbl + *lda * *m) { /* WORK(IR) is LDA by M */ ldwrkr = *lda; } else { /* WORK(IR) is M by M */ ldwrkr = *m; } itau = ir + ldwrkr * *m; iwork = itau + *m; /* Compute A=L*Q (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgelqf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); /* Copy L to WORK(IR), zeroing out above it */ NUMlapack_dlacpy ("L", m, m, &a[a_offset], lda, &work[ir], &ldwrkr); i__2 = *m - 1; i__3 = *m - 1; NUMlapack_dlaset ("U", &i__2, &i__3, &c_b416, &c_b416, &work[ir + ldwrkr], &ldwrkr); /* Generate Q in A (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorglq (m, n, m, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); ie = itau; itauq = ie + *m; itaup = itauq + *m; iwork = itaup + *m; /* Bidiagonalize L in WORK(IR) (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (m, m, &work[ir], &ldwrkr, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); /* Generate right vectors bidiagonalizing L in WORK(IR) (Workspace: need M*M+4*M, prefer M*M+3*M+(M-1)*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", m, m, m, &work[ir], &ldwrkr, &work[itaup], &work[iwork], &i__2, &ierr); iwork = ie + *m; /* Perform bidiagonal QR iteration, computing right singular vectors of L in WORK(IR) (Workspace: need M*M+BDSPAC) */ NUMlapack_dbdsqr ("U", m, m, &c__0, &c__0, &s[1], &work[ie], &work[ir], &ldwrkr, dum, &c__1, dum, &c__1, &work[iwork], info); /* Multiply right singular vectors of L in WORK(IR) by Q in A, storing result in VT (Workspace: need M*M) */ NUMblas_dgemm ("N", "N", m, n, m, &c_b438, &work[ir], &ldwrkr, &a[a_offset], lda, &c_b416, &vt[vt_offset], ldvt); } else { /* Insufficient workspace for a fast algorithm */ itau = 1; iwork = itau + *m; /* Compute A=L*Q (Workspace: need 2*M, prefer M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgelqf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); /* Copy result to VT */ NUMlapack_dlacpy ("U", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt); /* Generate Q in VT (Workspace: need 2*M, prefer M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorglq (m, n, m, &vt[vt_offset], ldvt, &work[itau], &work[iwork], &i__2, &ierr); ie = itau; itauq = ie + *m; itaup = itauq + *m; iwork = itaup + *m; /* Zero out above L in A */ i__2 = *m - 1; i__3 = *m - 1; NUMlapack_dlaset ("U", &i__2, &i__3, &c_b416, &c_b416, &a_ref (1, 2), lda); /* Bidiagonalize L in A (Workspace: need 4*M, prefer 3*M+2*M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (m, m, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); /* Multiply right vectors bidiagonalizing L by Q in VT (Workspace: need 3*M+N, prefer 3*M+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dormbr ("P", "L", "T", m, n, m, &a[a_offset], lda, &work[itaup], &vt[vt_offset], ldvt, &work[iwork], &i__2, &ierr); iwork = ie + *m; /* Perform bidiagonal QR iteration, computing right singular vectors of A in VT (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("U", m, n, &c__0, &c__0, &s[1], &work[ie], &vt[vt_offset], ldvt, dum, &c__1, dum, &c__1, &work[iwork], info); } } else if (wntuo) { /* Path 5t(N much larger than M, JOBU='O', JOBVT='S') M right singular vectors to be computed in VT and M left singular vectors to be overwritten on A Computing MAX */ i__2 = *m << 2; if (*lwork >= (*m << 1) * *m + MAX (i__2, bdspac)) { /* Sufficient workspace for a fast algorithm */ iu = 1; if (*lwork >= wrkbl + (*lda << 1) * *m) { /* WORK(IU) is LDA by M and WORK(IR) is LDA by M */ ldwrku = *lda; ir = iu + ldwrku * *m; ldwrkr = *lda; } else if (*lwork >= wrkbl + (*lda + *m) * *m) { /* WORK(IU) is LDA by M and WORK(IR) is M by M */ ldwrku = *lda; ir = iu + ldwrku * *m; ldwrkr = *m; } else { /* WORK(IU) is M by M and WORK(IR) is M by M */ ldwrku = *m; ir = iu + ldwrku * *m; ldwrkr = *m; } itau = ir + ldwrkr * *m; iwork = itau + *m; /* Compute A=L*Q (Workspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgelqf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); /* Copy L to WORK(IU), zeroing out below it */ NUMlapack_dlacpy ("L", m, m, &a[a_offset], lda, &work[iu], &ldwrku); i__2 = *m - 1; i__3 = *m - 1; NUMlapack_dlaset ("U", &i__2, &i__3, &c_b416, &c_b416, &work[iu + ldwrku], &ldwrku); /* Generate Q in A (Workspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorglq (m, n, m, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); ie = itau; itauq = ie + *m; itaup = itauq + *m; iwork = itaup + *m; /* Bidiagonalize L in WORK(IU), copying result to WORK(IR) (Workspace: need 2*M*M+4*M, prefer 2*M*M+3*M+2*M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (m, m, &work[iu], &ldwrku, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); NUMlapack_dlacpy ("L", m, m, &work[iu], &ldwrku, &work[ir], &ldwrkr); /* Generate right bidiagonalizing vectors in WORK(IU) (Workspace: need 2*M*M+4*M-1, prefer 2*M*M+3*M+(M-1)*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", m, m, m, &work[iu], &ldwrku, &work[itaup], &work[iwork], &i__2, &ierr); /* Generate left bidiagonalizing vectors in WORK(IR) (Workspace: need 2*M*M+4*M, prefer 2*M*M+3*M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("Q", m, m, m, &work[ir], &ldwrkr, &work[itauq], &work[iwork], &i__2, &ierr); iwork = ie + *m; /* Perform bidiagonal QR iteration, computing left singular vectors of L in WORK(IR) and computing right singular vectors of L in WORK(IU) (Workspace: need 2*M*M+BDSPAC) */ NUMlapack_dbdsqr ("U", m, m, m, &c__0, &s[1], &work[ie], &work[iu], &ldwrku, &work[ir], &ldwrkr, dum, &c__1, &work[iwork], info); /* Multiply right singular vectors of L in WORK(IU) by Q in A, storing result in VT (Workspace: need M*M) */ NUMblas_dgemm ("N", "N", m, n, m, &c_b438, &work[iu], &ldwrku, &a[a_offset], lda, &c_b416, &vt[vt_offset], ldvt); /* Copy left singular vectors of L to A (Workspace: need M*M) */ NUMlapack_dlacpy ("F", m, m, &work[ir], &ldwrkr, &a[a_offset], lda); } else { /* Insufficient workspace for a fast algorithm */ itau = 1; iwork = itau + *m; /* Compute A=L*Q, copying result to VT (Workspace: need 2*M, prefer M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgelqf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); NUMlapack_dlacpy ("U", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt); /* Generate Q in VT (Workspace: need 2*M, prefer M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorglq (m, n, m, &vt[vt_offset], ldvt, &work[itau], &work[iwork], &i__2, &ierr); ie = itau; itauq = ie + *m; itaup = itauq + *m; iwork = itaup + *m; /* Zero out above L in A */ i__2 = *m - 1; i__3 = *m - 1; NUMlapack_dlaset ("U", &i__2, &i__3, &c_b416, &c_b416, &a_ref (1, 2), lda); /* Bidiagonalize L in A (Workspace: need 4*M, prefer 3*M+2*M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (m, m, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); /* Multiply right vectors bidiagonalizing L by Q in VT (Workspace: need 3*M+N, prefer 3*M+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dormbr ("P", "L", "T", m, n, m, &a[a_offset], lda, &work[itaup], &vt[vt_offset], ldvt, &work[iwork], &i__2, &ierr); /* Generate left bidiagonalizing vectors of L in A (Workspace: need 4*M, prefer 3*M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("Q", m, m, m, &a[a_offset], lda, &work[itauq], &work[iwork], &i__2, &ierr); iwork = ie + *m; /* Perform bidiagonal QR iteration, compute left singular vectors of A in A and compute right singular vectors of A in VT (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("U", m, n, m, &c__0, &s[1], &work[ie], &vt[vt_offset], ldvt, &a[a_offset], lda, dum, &c__1, &work[iwork], info); } } else if (wntuas) { /* Path 6t(N much larger than M, JOBU='S' or 'A', JOBVT='S') M right singular vectors to be computed in VT and M left singular vectors to be computed in U Computing MAX */ i__2 = *m << 2; if (*lwork >= *m * *m + MAX (i__2, bdspac)) { /* Sufficient workspace for a fast algorithm */ iu = 1; if (*lwork >= wrkbl + *lda * *m) { /* WORK(IU) is LDA by N */ ldwrku = *lda; } else { /* WORK(IU) is LDA by M */ ldwrku = *m; } itau = iu + ldwrku * *m; iwork = itau + *m; /* Compute A=L*Q (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgelqf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); /* Copy L to WORK(IU), zeroing out above it */ NUMlapack_dlacpy ("L", m, m, &a[a_offset], lda, &work[iu], &ldwrku); i__2 = *m - 1; i__3 = *m - 1; NUMlapack_dlaset ("U", &i__2, &i__3, &c_b416, &c_b416, &work[iu + ldwrku], &ldwrku); /* Generate Q in A (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorglq (m, n, m, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); ie = itau; itauq = ie + *m; itaup = itauq + *m; iwork = itaup + *m; /* Bidiagonalize L in WORK(IU), copying result to U (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (m, m, &work[iu], &ldwrku, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); NUMlapack_dlacpy ("L", m, m, &work[iu], &ldwrku, &u[u_offset], ldu); /* Generate right bidiagonalizing vectors in WORK(IU) (Workspace: need M*M+4*M-1, prefer M*M+3*M+(M-1)*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", m, m, m, &work[iu], &ldwrku, &work[itaup], &work[iwork], &i__2, &ierr); /* Generate left bidiagonalizing vectors in U (Workspace: need M*M+4*M, prefer M*M+3*M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("Q", m, m, m, &u[u_offset], ldu, &work[itauq], &work[iwork], &i__2, &ierr); iwork = ie + *m; /* Perform bidiagonal QR iteration, computing left singular vectors of L in U and computing right singular vectors of L in WORK(IU) (Workspace: need M*M+BDSPAC) */ NUMlapack_dbdsqr ("U", m, m, m, &c__0, &s[1], &work[ie], &work[iu], &ldwrku, &u[u_offset], ldu, dum, &c__1, &work[iwork], info); /* Multiply right singular vectors of L in WORK(IU) by Q in A, storing result in VT (Workspace: need M*M) */ NUMblas_dgemm ("N", "N", m, n, m, &c_b438, &work[iu], &ldwrku, &a[a_offset], lda, &c_b416, &vt[vt_offset], ldvt); } else { /* Insufficient workspace for a fast algorithm */ itau = 1; iwork = itau + *m; /* Compute A=L*Q, copying result to VT (Workspace: need 2*M, prefer M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgelqf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); NUMlapack_dlacpy ("U", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt); /* Generate Q in VT (Workspace: need 2*M, prefer M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorglq (m, n, m, &vt[vt_offset], ldvt, &work[itau], &work[iwork], &i__2, &ierr); /* Copy L to U, zeroing out above it */ NUMlapack_dlacpy ("L", m, m, &a[a_offset], lda, &u[u_offset], ldu); i__2 = *m - 1; i__3 = *m - 1; NUMlapack_dlaset ("U", &i__2, &i__3, &c_b416, &c_b416, &u_ref (1, 2), ldu); ie = itau; itauq = ie + *m; itaup = itauq + *m; iwork = itaup + *m; /* Bidiagonalize L in U (Workspace: need 4*M, prefer 3*M+2*M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (m, m, &u[u_offset], ldu, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); /* Multiply right bidiagonalizing vectors in U by Q in VT (Workspace: need 3*M+N, prefer 3*M+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dormbr ("P", "L", "T", m, n, m, &u[u_offset], ldu, &work[itaup], &vt[vt_offset], ldvt, &work[iwork], &i__2, &ierr); /* Generate left bidiagonalizing vectors in U (Workspace: need 4*M, prefer 3*M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("Q", m, m, m, &u[u_offset], ldu, &work[itauq], &work[iwork], &i__2, &ierr); iwork = ie + *m; /* Perform bidiagonal QR iteration, computing left singular vectors of A in U and computing right singular vectors of A in VT (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("U", m, n, m, &c__0, &s[1], &work[ie], &vt[vt_offset], ldvt, &u[u_offset], ldu, dum, &c__1, &work[iwork], info); } } } else if (wntva) { if (wntun) { /* Path 7t(N much larger than M, JOBU='N', JOBVT='A') N right singular vectors to be computed in VT and no left singular vectors to be computed Computing MAX */ i__2 = *n + *m, i__3 = *m << 2, i__2 = MAX (i__2, i__3); if (*lwork >= *m * *m + MAX (i__2, bdspac)) { /* Sufficient workspace for a fast algorithm */ ir = 1; if (*lwork >= wrkbl + *lda * *m) { /* WORK(IR) is LDA by M */ ldwrkr = *lda; } else { /* WORK(IR) is M by M */ ldwrkr = *m; } itau = ir + ldwrkr * *m; iwork = itau + *m; /* Compute A=L*Q, copying result to VT (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgelqf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); NUMlapack_dlacpy ("U", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt); /* Copy L to WORK(IR), zeroing out above it */ NUMlapack_dlacpy ("L", m, m, &a[a_offset], lda, &work[ir], &ldwrkr); i__2 = *m - 1; i__3 = *m - 1; NUMlapack_dlaset ("U", &i__2, &i__3, &c_b416, &c_b416, &work[ir + ldwrkr], &ldwrkr); /* Generate Q in VT (Workspace: need M*M+M+N, prefer M*M+M+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorglq (n, n, m, &vt[vt_offset], ldvt, &work[itau], &work[iwork], &i__2, &ierr); ie = itau; itauq = ie + *m; itaup = itauq + *m; iwork = itaup + *m; /* Bidiagonalize L in WORK(IR) (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (m, m, &work[ir], &ldwrkr, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); /* Generate right bidiagonalizing vectors in WORK(IR) (Workspace: need M*M+4*M-1, prefer M*M+3*M+(M-1)*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", m, m, m, &work[ir], &ldwrkr, &work[itaup], &work[iwork], &i__2, &ierr); iwork = ie + *m; /* Perform bidiagonal QR iteration, computing right singular vectors of L in WORK(IR) (Workspace: need M*M+BDSPAC) */ NUMlapack_dbdsqr ("U", m, m, &c__0, &c__0, &s[1], &work[ie], &work[ir], &ldwrkr, dum, &c__1, dum, &c__1, &work[iwork], info); /* Multiply right singular vectors of L in WORK(IR) by Q in VT, storing result in A (Workspace: need M*M) */ NUMblas_dgemm ("N", "N", m, n, m, &c_b438, &work[ir], &ldwrkr, &vt[vt_offset], ldvt, &c_b416, &a[a_offset], lda); /* Copy right singular vectors of A from A to VT */ NUMlapack_dlacpy ("F", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt); } else { /* Insufficient workspace for a fast algorithm */ itau = 1; iwork = itau + *m; /* Compute A=L*Q, copying result to VT (Workspace: need 2*M, prefer M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgelqf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); NUMlapack_dlacpy ("U", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt); /* Generate Q in VT (Workspace: need M+N, prefer M+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorglq (n, n, m, &vt[vt_offset], ldvt, &work[itau], &work[iwork], &i__2, &ierr); ie = itau; itauq = ie + *m; itaup = itauq + *m; iwork = itaup + *m; /* Zero out above L in A */ i__2 = *m - 1; i__3 = *m - 1; NUMlapack_dlaset ("U", &i__2, &i__3, &c_b416, &c_b416, &a_ref (1, 2), lda); /* Bidiagonalize L in A (Workspace: need 4*M, prefer 3*M+2*M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (m, m, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); /* Multiply right bidiagonalizing vectors in A by Q in VT (Workspace: need 3*M+N, prefer 3*M+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dormbr ("P", "L", "T", m, n, m, &a[a_offset], lda, &work[itaup], &vt[vt_offset], ldvt, &work[iwork], &i__2, &ierr); iwork = ie + *m; /* Perform bidiagonal QR iteration, computing right singular vectors of A in VT (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("U", m, n, &c__0, &c__0, &s[1], &work[ie], &vt[vt_offset], ldvt, dum, &c__1, dum, &c__1, &work[iwork], info); } } else if (wntuo) { /* Path 8t(N much larger than M, JOBU='O', JOBVT='A') N right singular vectors to be computed in VT and M left singular vectors to be overwritten on A Computing MAX */ i__2 = *n + *m, i__3 = *m << 2, i__2 = MAX (i__2, i__3); if (*lwork >= (*m << 1) * *m + MAX (i__2, bdspac)) { /* Sufficient workspace for a fast algorithm */ iu = 1; if (*lwork >= wrkbl + (*lda << 1) * *m) { /* WORK(IU) is LDA by M and WORK(IR) is LDA by M */ ldwrku = *lda; ir = iu + ldwrku * *m; ldwrkr = *lda; } else if (*lwork >= wrkbl + (*lda + *m) * *m) { /* WORK(IU) is LDA by M and WORK(IR) is M by M */ ldwrku = *lda; ir = iu + ldwrku * *m; ldwrkr = *m; } else { /* WORK(IU) is M by M and WORK(IR) is M by M */ ldwrku = *m; ir = iu + ldwrku * *m; ldwrkr = *m; } itau = ir + ldwrkr * *m; iwork = itau + *m; /* Compute A=L*Q, copying result to VT (Workspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgelqf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); NUMlapack_dlacpy ("U", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt); /* Generate Q in VT (Workspace: need 2*M*M+M+N, prefer 2*M*M+M+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorglq (n, n, m, &vt[vt_offset], ldvt, &work[itau], &work[iwork], &i__2, &ierr); /* Copy L to WORK(IU), zeroing out above it */ NUMlapack_dlacpy ("L", m, m, &a[a_offset], lda, &work[iu], &ldwrku); i__2 = *m - 1; i__3 = *m - 1; NUMlapack_dlaset ("U", &i__2, &i__3, &c_b416, &c_b416, &work[iu + ldwrku], &ldwrku); ie = itau; itauq = ie + *m; itaup = itauq + *m; iwork = itaup + *m; /* Bidiagonalize L in WORK(IU), copying result to WORK(IR) (Workspace: need 2*M*M+4*M, prefer 2*M*M+3*M+2*M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (m, m, &work[iu], &ldwrku, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); NUMlapack_dlacpy ("L", m, m, &work[iu], &ldwrku, &work[ir], &ldwrkr); /* Generate right bidiagonalizing vectors in WORK(IU) (Workspace: need 2*M*M+4*M-1, prefer 2*M*M+3*M+(M-1)*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", m, m, m, &work[iu], &ldwrku, &work[itaup], &work[iwork], &i__2, &ierr); /* Generate left bidiagonalizing vectors in WORK(IR) (Workspace: need 2*M*M+4*M, prefer 2*M*M+3*M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("Q", m, m, m, &work[ir], &ldwrkr, &work[itauq], &work[iwork], &i__2, &ierr); iwork = ie + *m; /* Perform bidiagonal QR iteration, computing left singular vectors of L in WORK(IR) and computing right singular vectors of L in WORK(IU) (Workspace: need 2*M*M+BDSPAC) */ NUMlapack_dbdsqr ("U", m, m, m, &c__0, &s[1], &work[ie], &work[iu], &ldwrku, &work[ir], &ldwrkr, dum, &c__1, &work[iwork], info); /* Multiply right singular vectors of L in WORK(IU) by Q in VT, storing result in A (Workspace: need M*M) */ NUMblas_dgemm ("N", "N", m, n, m, &c_b438, &work[iu], &ldwrku, &vt[vt_offset], ldvt, &c_b416, &a[a_offset], lda); /* Copy right singular vectors of A from A to VT */ NUMlapack_dlacpy ("F", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt); /* Copy left singular vectors of A from WORK(IR) to A */ NUMlapack_dlacpy ("F", m, m, &work[ir], &ldwrkr, &a[a_offset], lda); } else { /* Insufficient workspace for a fast algorithm */ itau = 1; iwork = itau + *m; /* Compute A=L*Q, copying result to VT (Workspace: need 2*M, prefer M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgelqf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); NUMlapack_dlacpy ("U", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt); /* Generate Q in VT (Workspace: need M+N, prefer M+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorglq (n, n, m, &vt[vt_offset], ldvt, &work[itau], &work[iwork], &i__2, &ierr); ie = itau; itauq = ie + *m; itaup = itauq + *m; iwork = itaup + *m; /* Zero out above L in A */ i__2 = *m - 1; i__3 = *m - 1; NUMlapack_dlaset ("U", &i__2, &i__3, &c_b416, &c_b416, &a_ref (1, 2), lda); /* Bidiagonalize L in A (Workspace: need 4*M, prefer 3*M+2*M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (m, m, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); /* Multiply right bidiagonalizing vectors in A by Q in VT (Workspace: need 3*M+N, prefer 3*M+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dormbr ("P", "L", "T", m, n, m, &a[a_offset], lda, &work[itaup], &vt[vt_offset], ldvt, &work[iwork], &i__2, &ierr); /* Generate left bidiagonalizing vectors in A (Workspace: need 4*M, prefer 3*M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("Q", m, m, m, &a[a_offset], lda, &work[itauq], &work[iwork], &i__2, &ierr); iwork = ie + *m; /* Perform bidiagonal QR iteration, computing left singular vectors of A in A and computing right singular vectors of A in VT (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("U", m, n, m, &c__0, &s[1], &work[ie], &vt[vt_offset], ldvt, &a[a_offset], lda, dum, &c__1, &work[iwork], info); } } else if (wntuas) { /* Path 9t(N much larger than M, JOBU='S' or 'A', JOBVT='A') N right singular vectors to be computed in VT and M left singular vectors to be computed in U Computing MAX */ i__2 = *n + *m, i__3 = *m << 2, i__2 = MAX (i__2, i__3); if (*lwork >= *m * *m + MAX (i__2, bdspac)) { /* Sufficient workspace for a fast algorithm */ iu = 1; if (*lwork >= wrkbl + *lda * *m) { /* WORK(IU) is LDA by M */ ldwrku = *lda; } else { /* WORK(IU) is M by M */ ldwrku = *m; } itau = iu + ldwrku * *m; iwork = itau + *m; /* Compute A=L*Q, copying result to VT (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgelqf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); NUMlapack_dlacpy ("U", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt); /* Generate Q in VT (Workspace: need M*M+M+N, prefer M*M+M+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorglq (n, n, m, &vt[vt_offset], ldvt, &work[itau], &work[iwork], &i__2, &ierr); /* Copy L to WORK(IU), zeroing out above it */ NUMlapack_dlacpy ("L", m, m, &a[a_offset], lda, &work[iu], &ldwrku); i__2 = *m - 1; i__3 = *m - 1; NUMlapack_dlaset ("U", &i__2, &i__3, &c_b416, &c_b416, &work[iu + ldwrku], &ldwrku); ie = itau; itauq = ie + *m; itaup = itauq + *m; iwork = itaup + *m; /* Bidiagonalize L in WORK(IU), copying result to U (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (m, m, &work[iu], &ldwrku, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); NUMlapack_dlacpy ("L", m, m, &work[iu], &ldwrku, &u[u_offset], ldu); /* Generate right bidiagonalizing vectors in WORK(IU) (Workspace: need M*M+4*M, prefer M*M+3*M+(M-1)*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", m, m, m, &work[iu], &ldwrku, &work[itaup], &work[iwork], &i__2, &ierr); /* Generate left bidiagonalizing vectors in U (Workspace: need M*M+4*M, prefer M*M+3*M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("Q", m, m, m, &u[u_offset], ldu, &work[itauq], &work[iwork], &i__2, &ierr); iwork = ie + *m; /* Perform bidiagonal QR iteration, computing left singular vectors of L in U and computing right singular vectors of L in WORK(IU) (Workspace: need M*M+BDSPAC) */ NUMlapack_dbdsqr ("U", m, m, m, &c__0, &s[1], &work[ie], &work[iu], &ldwrku, &u[u_offset], ldu, dum, &c__1, &work[iwork], info); /* Multiply right singular vectors of L in WORK(IU) by Q in VT, storing result in A (Workspace: need M*M) */ NUMblas_dgemm ("N", "N", m, n, m, &c_b438, &work[iu], &ldwrku, &vt[vt_offset], ldvt, &c_b416, &a[a_offset], lda); /* Copy right singular vectors of A from A to VT */ NUMlapack_dlacpy ("F", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt); } else { /* Insufficient workspace for a fast algorithm */ itau = 1; iwork = itau + *m; /* Compute A=L*Q, copying result to VT (Workspace: need 2*M, prefer M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgelqf (m, n, &a[a_offset], lda, &work[itau], &work[iwork], &i__2, &ierr); NUMlapack_dlacpy ("U", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt); /* Generate Q in VT (Workspace: need M+N, prefer M+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorglq (n, n, m, &vt[vt_offset], ldvt, &work[itau], &work[iwork], &i__2, &ierr); /* Copy L to U, zeroing out above it */ NUMlapack_dlacpy ("L", m, m, &a[a_offset], lda, &u[u_offset], ldu); i__2 = *m - 1; i__3 = *m - 1; NUMlapack_dlaset ("U", &i__2, &i__3, &c_b416, &c_b416, &u_ref (1, 2), ldu); ie = itau; itauq = ie + *m; itaup = itauq + *m; iwork = itaup + *m; /* Bidiagonalize L in U (Workspace: need 4*M, prefer 3*M+2*M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (m, m, &u[u_offset], ldu, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); /* Multiply right bidiagonalizing vectors in U by Q in VT (Workspace: need 3*M+N, prefer 3*M+N*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dormbr ("P", "L", "T", m, n, m, &u[u_offset], ldu, &work[itaup], &vt[vt_offset], ldvt, &work[iwork], &i__2, &ierr); /* Generate left bidiagonalizing vectors in U (Workspace: need 4*M, prefer 3*M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("Q", m, m, m, &u[u_offset], ldu, &work[itauq], &work[iwork], &i__2, &ierr); iwork = ie + *m; /* Perform bidiagonal QR iteration, computing left singular vectors of A in U and computing right singular vectors of A in VT (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("U", m, n, m, &c__0, &s[1], &work[ie], &vt[vt_offset], ldvt, &u[u_offset], ldu, dum, &c__1, &work[iwork], info); } } } } else { /* N .LT. MNTHR Path 10t(N greater than M, but not much larger) Reduce to bidiagonal form without LQ decomposition */ ie = 1; itauq = ie + *m; itaup = itauq + *m; iwork = itaup + *m; /* Bidiagonalize A (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dgebrd (m, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &work[itaup], &work[iwork], &i__2, &ierr); if (wntuas) { /* If left singular vectors desired in U, copy result to U and generate left bidiagonalizing vectors in U (Workspace: need 4*M-1, prefer 3*M+(M-1)*NB) */ NUMlapack_dlacpy ("L", m, m, &a[a_offset], lda, &u[u_offset], ldu); i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("Q", m, m, n, &u[u_offset], ldu, &work[itauq], &work[iwork], &i__2, &ierr); } if (wntvas) { /* If right singular vectors desired in VT, copy result to VT and generate right bidiagonalizing vectors in VT (Workspace: need 3*M+NRVT, prefer 3*M+NRVT*NB) */ NUMlapack_dlacpy ("U", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt); if (wntva) { nrvt = *n; } if (wntvs) { nrvt = *m; } i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", &nrvt, n, m, &vt[vt_offset], ldvt, &work[itaup], &work[iwork], &i__2, &ierr); } if (wntuo) { /* If left singular vectors desired in A, generate left bidiagonalizing vectors in A (Workspace: need 4*M-1, prefer 3*M+(M-1)*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("Q", m, m, n, &a[a_offset], lda, &work[itauq], &work[iwork], &i__2, &ierr); } if (wntvo) { /* If right singular vectors desired in A, generate right bidiagonalizing vectors in A (Workspace: need 4*M, prefer 3*M+M*NB) */ i__2 = *lwork - iwork + 1; NUMlapack_dorgbr ("P", m, n, m, &a[a_offset], lda, &work[itaup], &work[iwork], &i__2, &ierr); } iwork = ie + *m; if (wntuas || wntuo) { nru = *m; } if (wntun) { nru = 0; } if (wntvas || wntvo) { ncvt = *n; } if (wntvn) { ncvt = 0; } if (!wntuo && !wntvo) { /* Perform bidiagonal QR iteration, if desired, computing left singular vectors in U and computing right singular vectors in VT (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("L", m, &ncvt, &nru, &c__0, &s[1], &work[ie], &vt[vt_offset], ldvt, &u[u_offset], ldu, dum, &c__1, &work[iwork], info); } else if (!wntuo && wntvo) { /* Perform bidiagonal QR iteration, if desired, computing left singular vectors in U and computing right singular vectors in A (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("L", m, &ncvt, &nru, &c__0, &s[1], &work[ie], &a[a_offset], lda, &u[u_offset], ldu, dum, &c__1, &work[iwork], info); } else { /* Perform bidiagonal QR iteration, if desired, computing left singular vectors in A and computing right singular vectors in VT (Workspace: need BDSPAC) */ NUMlapack_dbdsqr ("L", m, &ncvt, &nru, &c__0, &s[1], &work[ie], &vt[vt_offset], ldvt, &a[a_offset], lda, dum, &c__1, &work[iwork], info); } } } /* If DBDSQR failed to converge, copy unconverged superdiagonals to WORK( 2:MINMN ) */ if (*info != 0) { if (ie > 2) { i__2 = minmn - 1; for (i__ = 1; i__ <= i__2; ++i__) { work[i__ + 1] = work[i__ + ie - 1]; /* L50: */ } } if (ie < 2) { for (i__ = minmn - 1; i__ >= 1; --i__) { work[i__ + 1] = work[i__ + ie - 1]; /* L60: */ } } } /* Undo scaling if necessary */ if (iscl == 1) { if (anrm > bignum) { NUMlapack_dlascl ("G", &c__0, &c__0, &bignum, &anrm, &minmn, &c__1, &s[1], &minmn, &ierr); } if (*info != 0 && anrm > bignum) { i__2 = minmn - 1; NUMlapack_dlascl ("G", &c__0, &c__0, &bignum, &anrm, &i__2, &c__1, &work[2], &minmn, &ierr); } if (anrm < smlnum) { NUMlapack_dlascl ("G", &c__0, &c__0, &smlnum, &anrm, &minmn, &c__1, &s[1], &minmn, &ierr); } if (*info != 0 && anrm < smlnum) { i__2 = minmn - 1; NUMlapack_dlascl ("G", &c__0, &c__0, &smlnum, &anrm, &i__2, &c__1, &work[2], &minmn, &ierr); } } /* Return optimal workspace in WORK(1) */ work[1] = (double) maxwrk; return 0; } /* NUMlapack_dgesvd */ #undef vt_ref #undef u_ref int NUMlapack_dgetf2 (long *m, long *n, double *a, long *lda, long *ipiv, long *info) { /* Table of constant values */ static long c__1 = 1; static double c_b6 = -1.; /* System generated locals */ long a_dim1, a_offset, i__1, i__2, i__3; double d__1; /* Local variables */ static long j; static long jp; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --ipiv; /* Function Body */ *info = 0; if (*m < 0) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < MAX (1, *m)) { *info = -4; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DGETF2", &i__1); return 0; } /* Quick return if possible */ if (*m == 0 || *n == 0) { return 0; } i__1 = MIN (*m, *n); for (j = 1; j <= i__1; ++j) { /* Find pivot and test for singularity. */ i__2 = *m - j + 1; jp = j - 1 + NUMblas_idamax (&i__2, &a_ref (j, j), &c__1); ipiv[j] = jp; if (a_ref (jp, j) != 0.) { /* Apply the interchange to columns 1:N. */ if (jp != j) { NUMblas_dswap (n, &a_ref (j, 1), lda, &a_ref (jp, 1), lda); } /* Compute elements J+1:M of J-th column. */ if (j < *m) { i__2 = *m - j; d__1 = 1. / a_ref (j, j); NUMblas_dscal (&i__2, &d__1, &a_ref (j + 1, j), &c__1); } } else if (*info == 0) { *info = j; } if (j < MIN (*m, *n)) { /* Update trailing submatrix. */ i__2 = *m - j; i__3 = *n - j; NUMblas_dger (&i__2, &i__3, &c_b6, &a_ref (j + 1, j), &c__1, &a_ref (j, j + 1), lda, &a_ref (j + 1, j + 1), lda); } /* L10: */ } return 0; } /* NUMlapack_dgetf2 */ int NUMlapack_dgetri (long *n, double *a, long *lda, long *ipiv, double *work, long *lwork, long *info) { /* Table of constant values */ static long c__1 = 1; static long c_n1 = -1; static long c__2 = 2; static double c_b20 = -1.; static double c_b22 = 1.; /* System generated locals */ long a_dim1, a_offset, i__1, i__2, i__3; /* Local variables */ static long i__, j; static long nbmin; static long jb, nb, jj, jp, nn; static long ldwork; static long lwkopt; static long lquery; static long iws; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --ipiv; --work; /* Function Body */ *info = 0; nb = NUMlapack_ilaenv (&c__1, "DGETRI", " ", n, &c_n1, &c_n1, &c_n1, 6, 1); lwkopt = *n * nb; work[1] = (double) lwkopt; lquery = *lwork == -1; if (*n < 0) { *info = -1; } else if (*lda < MAX (1, *n)) { *info = -3; } else if (*lwork < MAX (1, *n) && !lquery) { *info = -6; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DGETRI", &i__1); return 0; } else if (lquery) { return 0; } /* Quick return if possible */ if (*n == 0) { return 0; } /* Form inv(U). If INFO > 0 from DTRTRI, then U is singular, and the inverse is not computed. */ NUMlapack_dtrtri ("Upper", "Non-unit", n, &a[a_offset], lda, info); if (*info > 0) { return 0; } nbmin = 2; ldwork = *n; if (nb > 1 && nb < *n) { /* Computing MAX */ i__1 = ldwork * nb; iws = MAX (i__1, 1); if (*lwork < iws) { nb = *lwork / ldwork; /* Computing MAX */ i__1 = 2, i__2 = NUMlapack_ilaenv (&c__2, "DGETRI", " ", n, &c_n1, &c_n1, &c_n1, 6, 1); nbmin = MAX (i__1, i__2); } } else { iws = *n; } /* Solve the equation inv(A)*L = inv(U) for inv(A). */ if (nb < nbmin || nb >= *n) { /* Use unblocked code. */ for (j = *n; j >= 1; --j) { /* Copy current column of L to WORK and replace with zeros. */ i__1 = *n; for (i__ = j + 1; i__ <= i__1; ++i__) { work[i__] = a_ref (i__, j); a_ref (i__, j) = 0.; /* L10: */ } /* Compute current column of inv(A). */ if (j < *n) { i__1 = *n - j; NUMblas_dgemv ("No transpose", n, &i__1, &c_b20, &a_ref (1, j + 1), lda, &work[j + 1], &c__1, &c_b22, &a_ref (1, j), &c__1); } /* L20: */ } } else { /* Use blocked code. */ nn = (*n - 1) / nb * nb + 1; i__1 = -nb; for (j = nn; i__1 < 0 ? j >= 1 : j <= 1; j += i__1) { /* Computing MIN */ i__2 = nb, i__3 = *n - j + 1; jb = MIN (i__2, i__3); /* Copy current block column of L to WORK and replace with zeros. */ i__2 = j + jb - 1; for (jj = j; jj <= i__2; ++jj) { i__3 = *n; for (i__ = jj + 1; i__ <= i__3; ++i__) { work[i__ + (jj - j) * ldwork] = a_ref (i__, jj); a_ref (i__, jj) = 0.; /* L30: */ } /* L40: */ } /* Compute current block column of inv(A). */ if (j + jb <= *n) { i__2 = *n - j - jb + 1; NUMblas_dgemm ("No transpose", "No transpose", n, &jb, &i__2, &c_b20, &a_ref (1, j + jb), lda, &work[j + jb], &ldwork, &c_b22, &a_ref (1, j), lda); } NUMblas_dtrsm ("Right", "Lower", "No transpose", "Unit", n, &jb, &c_b22, &work[j], &ldwork, &a_ref (1, j), lda); /* L50: */ } } /* Apply column interchanges. */ for (j = *n - 1; j >= 1; --j) { jp = ipiv[j]; if (jp != j) { NUMblas_dswap (n, &a_ref (1, j), &c__1, &a_ref (1, jp), &c__1); } /* L60: */ } work[1] = (double) iws; return 0; } /* NUMlapack_dgetri */ int NUMlapack_dgetrf (long *m, long *n, double *a, long *lda, long *ipiv, long *info) { /* Table of constant values */ static long c__1 = 1; static long c_n1 = -1; static double c_b16 = 1.; static double c_b19 = -1.; /* System generated locals */ long a_dim1, a_offset, i__1, i__2, i__3, i__4, i__5; /* Local variables */ static long i__, j; static long iinfo; static long jb, nb; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --ipiv; /* Function Body */ *info = 0; if (*m < 0) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < MAX (1, *m)) { *info = -4; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DGETRF", &i__1); return 0; } /* Quick return if possible */ if (*m == 0 || *n == 0) { return 0; } /* Determine the block size for this environment. */ nb = NUMlapack_ilaenv (&c__1, "DGETRF", " ", m, n, &c_n1, &c_n1, 6, 1); if (nb <= 1 || nb >= MIN (*m, *n)) { /* Use unblocked code. */ NUMlapack_dgetf2 (m, n, &a[a_offset], lda, &ipiv[1], info); } else { /* Use blocked code. */ i__1 = MIN (*m, *n); i__2 = nb; for (j = 1; i__2 < 0 ? j >= i__1 : j <= i__1; j += i__2) { /* Computing MIN */ i__3 = MIN (*m, *n) - j + 1; jb = MIN (i__3, nb); /* Factor diagonal and subdiagonal blocks and test for exact singularity. */ i__3 = *m - j + 1; NUMlapack_dgetf2 (&i__3, &jb, &a_ref (j, j), lda, &ipiv[j], &iinfo); /* Adjust INFO and the pivot indices. */ if (*info == 0 && iinfo > 0) { *info = iinfo + j - 1; } /* Computing MIN */ i__4 = *m, i__5 = j + jb - 1; i__3 = MIN (i__4, i__5); for (i__ = j; i__ <= i__3; ++i__) { ipiv[i__] = j - 1 + ipiv[i__]; /* L10: */ } /* Apply interchanges to columns 1:J-1. */ i__3 = j - 1; i__4 = j + jb - 1; NUMlapack_dlaswp (&i__3, &a[a_offset], lda, &j, &i__4, &ipiv[1], &c__1); if (j + jb <= *n) { /* Apply interchanges to columns J+JB:N. */ i__3 = *n - j - jb + 1; i__4 = j + jb - 1; NUMlapack_dlaswp (&i__3, &a_ref (1, j + jb), lda, &j, &i__4, &ipiv[1], &c__1); /* Compute block row of U. */ i__3 = *n - j - jb + 1; NUMblas_dtrsm ("Left", "Lower", "No transpose", "Unit", &jb, &i__3, &c_b16, &a_ref (j, j), lda, &a_ref (j, j + jb), lda); if (j + jb <= *m) { /* Update trailing submatrix. */ i__3 = *m - j - jb + 1; i__4 = *n - j - jb + 1; NUMblas_dgemm ("No transpose", "No transpose", &i__3, &i__4, &jb, &c_b19, &a_ref (j + jb, j), lda, &a_ref (j, j + jb), lda, &c_b16, &a_ref (j + jb, j + jb), lda); } } /* L20: */ } } return 0; } /* NUMlapack_dgetrf */ int NUMlapack_dgetrs (const char *trans, long *n, long *nrhs, double *a, long *lda, long *ipiv, double *b, long *ldb, long *info) { /* Table of constant values */ static long c__1 = 1; static double c_b12 = 1.; static long c_n1 = -1; /* System generated locals */ long a_dim1, a_offset, b_dim1, b_offset, i__1; /* Local variables */ static long notran; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --ipiv; b_dim1 = *ldb; b_offset = 1 + b_dim1 * 1; b -= b_offset; /* Function Body */ *info = 0; notran = lsame_ (trans, "N"); if (!notran && !lsame_ (trans, "T") && !lsame_ (trans, "C")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*nrhs < 0) { *info = -3; } else if (*lda < MAX (1, *n)) { *info = -5; } else if (*ldb < MAX (1, *n)) { *info = -8; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DGETRS", &i__1); return 0; } /* Quick return if possible */ if (*n == 0 || *nrhs == 0) { return 0; } if (notran) { /* Solve A * X = B. Apply row interchanges to the right hand sides. */ NUMlapack_dlaswp (nrhs, &b[b_offset], ldb, &c__1, n, &ipiv[1], &c__1); /* Solve L*X = B, overwriting B with X. */ NUMblas_dtrsm ("Left", "Lower", "No transpose", "Unit", n, nrhs, &c_b12, &a[a_offset], lda, &b[b_offset], ldb); /* Solve U*X = B, overwriting B with X. */ NUMblas_dtrsm ("Left", "Upper", "No transpose", "Non-unit", n, nrhs, &c_b12, &a[a_offset], lda, &b[b_offset], ldb); } else { /* Solve A' * X = B. Solve U'*X = B, overwriting B with X. */ NUMblas_dtrsm ("Left", "Upper", "Transpose", "Non-unit", n, nrhs, &c_b12, &a[a_offset], lda, &b[b_offset], ldb); /* Solve L'*X = B, overwriting B with X. */ NUMblas_dtrsm ("Left", "Lower", "Transpose", "Unit", n, nrhs, &c_b12, &a[a_offset], lda, &b[b_offset], ldb); /* Apply row interchanges to the solution vectors. */ NUMlapack_dlaswp (nrhs, &b[b_offset], ldb, &c__1, n, &ipiv[1], &c_n1); } return 0; } /* NUMlapack_dgetrs */ int NUMlapack_dggsvd (const char *jobu, const char *jobv, const char *jobq, long *m, long *n, long *p, long *k, long *l, double *a, long *lda, double *b, long *ldb, double *alpha, double *beta, double *u, long *ldu, double *v, long *ldv, double *q, long *ldq, double *work, long *iwork, long *info) { /* Table of constant values */ static long c__1 = 1; /* System generated locals */ long a_dim1, a_offset, b_dim1, b_offset, q_dim1, q_offset, u_dim1, u_offset, v_dim1, v_offset, i__1, i__2; /* Local variables */ static long ibnd; static double tola; static long isub; static double tolb, unfl, temp, smax; static long i__, j; static double anorm, bnorm; static long wantq, wantu, wantv; static long ncycle; static double ulp; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; b_dim1 = *ldb; b_offset = 1 + b_dim1 * 1; b -= b_offset; --alpha; --beta; u_dim1 = *ldu; u_offset = 1 + u_dim1 * 1; u -= u_offset; v_dim1 = *ldv; v_offset = 1 + v_dim1 * 1; v -= v_offset; q_dim1 = *ldq; q_offset = 1 + q_dim1 * 1; q -= q_offset; --work; --iwork; /* Function Body */ wantu = lsame_ (jobu, "U"); wantv = lsame_ (jobv, "V"); wantq = lsame_ (jobq, "Q"); *info = 0; if (! (wantu || lsame_ (jobu, "N"))) { *info = -1; } else if (! (wantv || lsame_ (jobv, "N"))) { *info = -2; } else if (! (wantq || lsame_ (jobq, "N"))) { *info = -3; } else if (*m < 0) { *info = -4; } else if (*n < 0) { *info = -5; } else if (*p < 0) { *info = -6; } else if (*lda < MAX (1, *m)) { *info = -10; } else if (*ldb < MAX (1, *p)) { *info = -12; } else if (*ldu < 1 || wantu && *ldu < *m) { *info = -16; } else if (*ldv < 1 || wantv && *ldv < *p) { *info = -18; } else if (*ldq < 1 || wantq && *ldq < *n) { *info = -20; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DGGSVD", &i__1); return 0; } /* Compute the Frobenius norm of matrices A and B */ anorm = NUMlapack_dlange ("1", m, n, &a[a_offset], lda, &work[1]); bnorm = NUMlapack_dlange ("1", p, n, &b[b_offset], ldb, &work[1]); /* Get machine precision and set up threshold for determining the effective numerical rank of the matrices A and B. */ ulp = NUMblas_dlamch ("Precision"); unfl = NUMblas_dlamch ("Safe Minimum"); tola = MAX (*m, *n) * MAX (anorm, unfl) * ulp; tolb = MAX (*p, *n) * MAX (bnorm, unfl) * ulp; /* Preprocessing */ NUMlapack_dggsvp (jobu, jobv, jobq, m, p, n, &a[a_offset], lda, &b[b_offset], ldb, &tola, &tolb, k, l, &u[u_offset], ldu, &v[v_offset], ldv, &q[q_offset], ldq, &iwork[1], &work[1], &work[*n + 1], info); /* Compute the GSVD of two upper "triangular" matrices */ NUMlapack_dtgsja (jobu, jobv, jobq, m, p, n, k, l, &a[a_offset], lda, &b[b_offset], ldb, &tola, &tolb, &alpha[1], &beta[1], &u[u_offset], ldu, &v[v_offset], ldv, &q[q_offset], ldq, &work[1], &ncycle, info); /* Sort the singular values and store the pivot indices in IWORK Copy ALPHA to WORK, then sort ALPHA in WORK */ NUMblas_dcopy (n, &alpha[1], &c__1, &work[1], &c__1); /* Computing MIN */ i__1 = *l, i__2 = *m - *k; ibnd = MIN (i__1, i__2); i__1 = ibnd; for (i__ = 1; i__ <= i__1; ++i__) { /* Scan for largest ALPHA(K+I) */ isub = i__; smax = work[*k + i__]; i__2 = ibnd; for (j = i__ + 1; j <= i__2; ++j) { temp = work[*k + j]; if (temp > smax) { isub = j; smax = temp; } /* L10: */ } if (isub != i__) { work[*k + isub] = work[*k + i__]; work[*k + i__] = smax; iwork[*k + i__] = *k + isub; } else { iwork[*k + i__] = *k + i__; } /* L20: */ } return 0; } /* NUMlapack_dggsvd */ #define b_ref(a_1,a_2) b[(a_2)*b_dim1 + a_1] #define u_ref(a_1,a_2) u[(a_2)*u_dim1 + a_1] #define v_ref(a_1,a_2) v[(a_2)*v_dim1 + a_1] int NUMlapack_dggsvp (const char *jobu, const char *jobv, const char *jobq, long *m, long *p, long *n, double *a, long *lda, double *b, long *ldb, double *tola, double *tolb, long *k, long *l, double *u, long *ldu, double *v, long *ldv, double *q, long *ldq, long *iwork, double *tau, double *work, long *info) { /* Table of constant values */ static double c_b12 = 0.; static double c_b22 = 1.; /* System generated locals */ long a_dim1, a_offset, b_dim1, b_offset, q_dim1, q_offset, u_dim1, u_offset, v_dim1, v_offset, i__1, i__2, i__3; double d__1; /* Local variables */ static long i__, j; static long wantq, wantu, wantv; static long forwrd; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; b_dim1 = *ldb; b_offset = 1 + b_dim1 * 1; b -= b_offset; u_dim1 = *ldu; u_offset = 1 + u_dim1 * 1; u -= u_offset; v_dim1 = *ldv; v_offset = 1 + v_dim1 * 1; v -= v_offset; q_dim1 = *ldq; q_offset = 1 + q_dim1 * 1; q -= q_offset; --iwork; --tau; --work; /* Function Body */ wantu = lsame_ (jobu, "U"); wantv = lsame_ (jobv, "V"); wantq = lsame_ (jobq, "Q"); forwrd = TRUE; *info = 0; if (! (wantu || lsame_ (jobu, "N"))) { *info = -1; } else if (! (wantv || lsame_ (jobv, "N"))) { *info = -2; } else if (! (wantq || lsame_ (jobq, "N"))) { *info = -3; } else if (*m < 0) { *info = -4; } else if (*p < 0) { *info = -5; } else if (*n < 0) { *info = -6; } else if (*lda < MAX (1, *m)) { *info = -8; } else if (*ldb < MAX (1, *p)) { *info = -10; } else if (*ldu < 1 || wantu && *ldu < *m) { *info = -16; } else if (*ldv < 1 || wantv && *ldv < *p) { *info = -18; } else if (*ldq < 1 || wantq && *ldq < *n) { *info = -20; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DGGSVP", &i__1); return 0; } /* QR with column pivoting of B: B*P = V*( S11 S12 ) ( 0 0 ) */ i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { iwork[i__] = 0; /* L10: */ } NUMlapack_dgeqpf (p, n, &b[b_offset], ldb, &iwork[1], &tau[1], &work[1], info); /* Update A := A*P */ NUMlapack_dlapmt (&forwrd, m, n, &a[a_offset], lda, &iwork[1]); /* Determine the effective rank of matrix B. */ *l = 0; i__1 = MIN (*p, *n); for (i__ = 1; i__ <= i__1; ++i__) { if ( (d__1 = b_ref (i__, i__), fabs (d__1)) > *tolb) { ++ (*l); } /* L20: */ } if (wantv) { /* Copy the details of V, and form V. */ NUMlapack_dlaset ("Full", p, p, &c_b12, &c_b12, &v[v_offset], ldv); if (*p > 1) { i__1 = *p - 1; NUMlapack_dlacpy ("Lower", &i__1, n, &b_ref (2, 1), ldb, &v_ref (2, 1), ldv); } i__1 = MIN (*p, *n); NUMlapack_dorg2r (p, p, &i__1, &v[v_offset], ldv, &tau[1], &work[1], info); } /* Clean up B */ i__1 = *l - 1; for (j = 1; j <= i__1; ++j) { i__2 = *l; for (i__ = j + 1; i__ <= i__2; ++i__) { b_ref (i__, j) = 0.; /* L30: */ } /* L40: */ } if (*p > *l) { i__1 = *p - *l; NUMlapack_dlaset ("Full", &i__1, n, &c_b12, &c_b12, &b_ref (*l + 1, 1), ldb); } if (wantq) { /* Set Q = I and Update Q := Q*P */ NUMlapack_dlaset ("Full", n, n, &c_b12, &c_b22, &q[q_offset], ldq); NUMlapack_dlapmt (&forwrd, n, n, &q[q_offset], ldq, &iwork[1]); } if (*p >= *l && *n != *l) { /* RQ factorization of (S11 S12): ( S11 S12 ) = ( 0 S12 )*Z */ NUMlapack_dgerq2 (l, n, &b[b_offset], ldb, &tau[1], &work[1], info); /* Update A := A*Z' */ NUMlapack_dormr2 ("Right", "Transpose", m, n, l, &b[b_offset], ldb, &tau[1], &a[a_offset], lda, &work[1], info); if (wantq) { /* Update Q := Q*Z' */ NUMlapack_dormr2 ("Right", "Transpose", n, n, l, &b[b_offset], ldb, &tau[1], &q[q_offset], ldq, &work[1], info); } /* Clean up B */ i__1 = *n - *l; NUMlapack_dlaset ("Full", l, &i__1, &c_b12, &c_b12, &b[b_offset], ldb); i__1 = *n; for (j = *n - *l + 1; j <= i__1; ++j) { i__2 = *l; for (i__ = j - *n + *l + 1; i__ <= i__2; ++i__) { b_ref (i__, j) = 0.; /* L50: */ } /* L60: */ } } /* Let N-L L A = ( A11 A12 ) M, then the following does the complete QR decomposition of A11: A11 = U*( 0 T12 )*P1' ( 0 0 ) */ i__1 = *n - *l; for (i__ = 1; i__ <= i__1; ++i__) { iwork[i__] = 0; /* L70: */ } i__1 = *n - *l; NUMlapack_dgeqpf (m, &i__1, &a[a_offset], lda, &iwork[1], &tau[1], &work[1], info); /* Determine the effective rank of A11 */ *k = 0; /* Computing MIN */ i__2 = *m, i__3 = *n - *l; i__1 = MIN (i__2, i__3); for (i__ = 1; i__ <= i__1; ++i__) { if ( (d__1 = a_ref (i__, i__), fabs (d__1)) > *tola) { ++ (*k); } /* L80: */ } /* Update A12 := U'*A12, where A12 = A( 1:M, N-L+1:N ) Computing MIN */ i__2 = *m, i__3 = *n - *l; i__1 = MIN (i__2, i__3); NUMlapack_dorm2r ("Left", "Transpose", m, l, &i__1, &a[a_offset], lda, &tau[1], &a_ref (1, *n - *l + 1), lda, &work[1], info); if (wantu) { /* Copy the details of U, and form U */ NUMlapack_dlaset ("Full", m, m, &c_b12, &c_b12, &u[u_offset], ldu); if (*m > 1) { i__1 = *m - 1; i__2 = *n - *l; NUMlapack_dlacpy ("Lower", &i__1, &i__2, &a_ref (2, 1), lda, &u_ref (2, 1), ldu); } /* Computing MIN */ i__2 = *m, i__3 = *n - *l; i__1 = MIN (i__2, i__3); NUMlapack_dorg2r (m, m, &i__1, &u[u_offset], ldu, &tau[1], &work[1], info); } if (wantq) { /* Update Q( 1:N, 1:N-L ) = Q( 1:N, 1:N-L )*P1 */ i__1 = *n - *l; NUMlapack_dlapmt (&forwrd, n, &i__1, &q[q_offset], ldq, &iwork[1]); } /* Clean up A: set the strictly lower triangular part of A(1:K, 1:K) = 0, and A( K+1:M, 1:N-L ) = 0. */ i__1 = *k - 1; for (j = 1; j <= i__1; ++j) { i__2 = *k; for (i__ = j + 1; i__ <= i__2; ++i__) { a_ref (i__, j) = 0.; /* L90: */ } /* L100: */ } if (*m > *k) { i__1 = *m - *k; i__2 = *n - *l; NUMlapack_dlaset ("Full", &i__1, &i__2, &c_b12, &c_b12, &a_ref (*k + 1, 1), lda); } if (*n - *l > *k) { /* RQ factorization of ( T11 T12 ) = ( 0 T12 )*Z1 */ i__1 = *n - *l; NUMlapack_dgerq2 (k, &i__1, &a[a_offset], lda, &tau[1], &work[1], info); if (wantq) { /* Update Q( 1:N,1:N-L ) = Q( 1:N,1:N-L )*Z1' */ i__1 = *n - *l; NUMlapack_dormr2 ("Right", "Transpose", n, &i__1, k, &a[a_offset], lda, &tau[1], &q[q_offset], ldq, &work[1], info); } /* Clean up A */ i__1 = *n - *l - *k; NUMlapack_dlaset ("Full", k, &i__1, &c_b12, &c_b12, &a[a_offset], lda); i__1 = *n - *l; for (j = *n - *l - *k + 1; j <= i__1; ++j) { i__2 = *k; for (i__ = j - *n + *l + *k + 1; i__ <= i__2; ++i__) { a_ref (i__, j) = 0.; /* L110: */ } /* L120: */ } } if (*m > *k) { /* QR factorization of A( K+1:M,N-L+1:N ) */ i__1 = *m - *k; NUMlapack_dgeqr2 (&i__1, l, &a_ref (*k + 1, *n - *l + 1), lda, &tau[1], &work[1], info); if (wantu) { /* Update U(:,K+1:M) := U(:,K+1:M)*U1 */ i__1 = *m - *k; /* Computing MIN */ i__3 = *m - *k; i__2 = MIN (i__3, *l); NUMlapack_dorm2r ("Right", "No transpose", m, &i__1, &i__2, &a_ref (*k + 1, *n - *l + 1), lda, &tau[1], &u_ref (1, *k + 1), ldu, &work[1], info); } /* Clean up */ i__1 = *n; for (j = *n - *l + 1; j <= i__1; ++j) { i__2 = *m; for (i__ = j - *n + *k + *l + 1; i__ <= i__2; ++i__) { a_ref (i__, j) = 0.; /* L130: */ } /* L140: */ } } return 0; } /* NUMlapack_dggsvp */ #undef v_ref #undef u_ref #undef b_ref int NUMlapack_dhseqr (const char *job, const char *compz, long *n, long *ilo, long *ihi, double *h__, long *ldh, double *wr, double *wi, double *z__, long *ldz, double *work, long *lwork, long *info) { /* Table of constant values */ static double c_b9 = 0.; static double c_b10 = 1.; static long c__4 = 4; static long c_n1 = -1; static long c__2 = 2; static long c__8 = 8; static long c__15 = 15; static int c_false = FALSE; static long c__1 = 1; /* System generated locals */ const char *a__1[2]; long h_dim1, h_offset, z_dim1, z_offset, i__1, i__2, i__3[2], i__4, i__5; double d__1, d__2; char ch__1[2]; /* Local variables */ static long maxb; static double absw; static long ierr; static double unfl, temp, ovfl; static long i__, j, k, l; static double s[225] /* was [15][15] */ , v[16]; static long itemp; static long i1, i2; static int initz, wantt, wantz; static long ii, nh; static long nr, ns; static long nv; static double vv[16]; static double smlnum; static int lquery; static long itn; static double tau; static long its; static double ulp, tst1; #define h___ref(a_1,a_2) h__[(a_2)*h_dim1 + a_1] #define s_ref(a_1,a_2) s[(a_2)*15 + a_1 - 16] #define z___ref(a_1,a_2) z__[(a_2)*z_dim1 + a_1] h_dim1 = *ldh; h_offset = 1 + h_dim1 * 1; h__ -= h_offset; --wr; --wi; z_dim1 = *ldz; z_offset = 1 + z_dim1 * 1; z__ -= z_offset; --work; /* Function Body */ wantt = lsame_ (job, "S"); initz = lsame_ (compz, "I"); wantz = initz || lsame_ (compz, "V"); *info = 0; work[1] = (double) MAX (1, *n); lquery = *lwork == -1; if (!lsame_ (job, "E") && !wantt) { *info = -1; } else if (!lsame_ (compz, "N") && !wantz) { *info = -2; } else if (*n < 0) { *info = -3; } else if (*ilo < 1 || *ilo > MAX (1, *n)) { *info = -4; } else if (*ihi < MIN (*ilo, *n) || *ihi > *n) { *info = -5; } else if (*ldh < MAX (1, *n)) { *info = -7; } else if (*ldz < 1 || wantz && *ldz < MAX (1, *n)) { *info = -11; } else if (*lwork < MAX (1, *n) && !lquery) { *info = -13; } if (*info != 0) { i__1 = - (*info); xerbla_ ("NUMlapack_dhseqr ", &i__1); return 0; } else if (lquery) { return 0; } /* Initialize Z, if necessary */ if (initz) { NUMlapack_dlaset ("Full", n, n, &c_b9, &c_b10, &z__[z_offset], ldz); } /* Store the eigenvalues isolated by NUMlapack_dgebal. */ i__1 = *ilo - 1; for (i__ = 1; i__ <= i__1; ++i__) { wr[i__] = h___ref (i__, i__); wi[i__] = 0.; /* L10: */ } i__1 = *n; for (i__ = *ihi + 1; i__ <= i__1; ++i__) { wr[i__] = h___ref (i__, i__); wi[i__] = 0.; /* L20: */ } /* Quick return if possible. */ if (*n == 0) { return 0; } if (*ilo == *ihi) { wr[*ilo] = h___ref (*ilo, *ilo); wi[*ilo] = 0.; return 0; } /* Set rows and columns ILO to IHI to zero below the first subdiagonal. */ i__1 = *ihi - 2; for (j = *ilo; j <= i__1; ++j) { i__2 = *n; for (i__ = j + 2; i__ <= i__2; ++i__) { h___ref (i__, j) = 0.; /* L30: */ } /* L40: */ } nh = *ihi - *ilo + 1; /* Determine the order of the multi-shift QR algorithm to be used. Writing concatenation */ i__3[0] = 1, a__1[0] = job; i__3[1] = 1, a__1[1] = compz; s_cat ( (char *) ch__1, a__1, i__3, &c__2, 2); ns = NUMlapack_ilaenv (&c__4, "NUMlapack_dhseqr ", ch__1, n, ilo, ihi, &c_n1, 6, 2); /* Writing concatenation */ i__3[0] = 1, a__1[0] = job; i__3[1] = 1, a__1[1] = compz; s_cat (ch__1, a__1, i__3, &c__2, 2); maxb = NUMlapack_ilaenv (&c__8, "NUMlapack_dhseqr ", ch__1, n, ilo, ihi, &c_n1, 6, 2); if (ns <= 2 || ns > nh || maxb >= nh) { /* Use the standard double-shift algorithm */ NUMlapack_dlahqr (&wantt, &wantz, n, ilo, ihi, &h__[h_offset], ldh, &wr[1], &wi[1], ilo, ihi, &z__[z_offset], ldz, info); return 0; } maxb = MAX (3, maxb); /* Computing MIN */ i__1 = MIN (ns, maxb); ns = MIN (i__1, 15); /* Now 2 < NS <= MAXB < NH. Set machine-dependent constants for the stopping criterion. If norm(H) <= sqrt(OVFL), overflow should not occur. */ unfl = NUMblas_dlamch ("Safe minimum"); ovfl = 1. / unfl; NUMlapack_dlabad (&unfl, &ovfl); ulp = NUMblas_dlamch ("Precision"); smlnum = unfl * (nh / ulp); /* I1 and I2 are the indices of the first row and last column of H to which transformations must be applied. If eigenvalues only are being computed, I1 and I2 are set inside the main loop. */ if (wantt) { i1 = 1; i2 = *n; } /* ITN is the total number of multiple-shift QR iterations allowed. */ itn = nh * 30; /* The main loop begins here. I is the loop index and decreases from IHI to ILO in steps of at most MAXB. Each iteration of the loop works with the active submatrix in rows and columns L to I. Eigenvalues I+1 to IHI have already converged. Either L = ILO or H(L,L-1) is negligible so that the matrix splits. */ i__ = *ihi; L50: l = *ilo; if (i__ < *ilo) { goto L170; } /* Perform multiple-shift QR iterations on rows and columns ILO to I until a submatrix of order at most MAXB splits off at the bottom because a subdiagonal element has become negligible. */ i__1 = itn; for (its = 0; its <= i__1; ++its) { /* Look for a single small subdiagonal element. */ i__2 = l + 1; for (k = i__; k >= i__2; --k) { tst1 = (d__1 = h___ref (k - 1, k - 1), fabs (d__1)) + (d__2 = h___ref (k, k), fabs (d__2)); if (tst1 == 0.) { i__4 = i__ - l + 1; tst1 = NUMlapack_dlanhs ("1", &i__4, &h___ref (l, l), ldh, &work[1]); } /* Computing MAX */ d__2 = ulp * tst1; if ( (d__1 = h___ref (k, k - 1), fabs (d__1)) <= MAX (d__2, smlnum)) { goto L70; } /* L60: */ } L70: l = k; if (l > *ilo) { /* H(L,L-1) is negligible. */ h___ref (l, l - 1) = 0.; } /* Exit from loop if a submatrix of order <= MAXB has split off. */ if (l >= i__ - maxb + 1) { goto L160; } /* Now the active submatrix is in rows and columns L to I. If eigenvalues only are being computed, only the active submatrix need be transformed. */ if (!wantt) { i1 = l; i2 = i__; } if (its == 20 || its == 30) { /* Exceptional shifts. */ i__2 = i__; for (ii = i__ - ns + 1; ii <= i__2; ++ii) { wr[ii] = ( (d__1 = h___ref (ii, ii - 1), fabs (d__1)) + (d__2 = h___ref (ii, ii), fabs (d__2))) * 1.5; wi[ii] = 0.; /* L80: */ } } else { /* Use eigenvalues of trailing submatrix of order NS as shifts. */ NUMlapack_dlacpy ("Full", &ns, &ns, &h___ref (i__ - ns + 1, i__ - ns + 1), ldh, s, &c__15); NUMlapack_dlahqr (&c_false, &c_false, &ns, &c__1, &ns, s, &c__15, &wr[i__ - ns + 1], &wi[i__ - ns + 1], &c__1, &ns, &z__[z_offset], ldz, &ierr); if (ierr > 0) { /* If NUMlapack_dlahqr failed to compute all NS eigenvalues, use the unconverged diagonal elements as the remaining shifts. */ i__2 = ierr; for (ii = 1; ii <= i__2; ++ii) { wr[i__ - ns + ii] = s_ref (ii, ii); wi[i__ - ns + ii] = 0.; /* L90: */ } } } /* Form the first column of (G-w(1)) (G-w(2)) . . . (G-w(ns)) where G is the Hessenberg submatrix H(L:I,L:I) and w is the vector of shifts (stored in WR and WI). The result is stored in the local array V. */ v[0] = 1.; i__2 = ns + 1; for (ii = 2; ii <= i__2; ++ii) { v[ii - 1] = 0.; /* L100: */ } nv = 1; i__2 = i__; for (j = i__ - ns + 1; j <= i__2; ++j) { if (wi[j] >= 0.) { if (wi[j] == 0.) { /* real shift */ i__4 = nv + 1; NUMblas_dcopy (&i__4, v, &c__1, vv, &c__1); i__4 = nv + 1; d__1 = -wr[j]; NUMblas_dgemv ("No transpose", &i__4, &nv, &c_b10, &h___ref (l, l), ldh, vv, &c__1, &d__1, v, &c__1); ++nv; } else if (wi[j] > 0.) { /* complex conjugate pair of shifts */ i__4 = nv + 1; NUMblas_dcopy (&i__4, v, &c__1, vv, &c__1); i__4 = nv + 1; d__1 = wr[j] * -2.; NUMblas_dgemv ("No transpose", &i__4, &nv, &c_b10, &h___ref (l, l), ldh, v, &c__1, &d__1, vv, &c__1); i__4 = nv + 1; itemp = NUMblas_idamax (&i__4, vv, &c__1); /* Computing MAX */ d__2 = (d__1 = vv[itemp - 1], fabs (d__1)); temp = 1. / MAX (d__2, smlnum); i__4 = nv + 1; NUMblas_dscal (&i__4, &temp, vv, &c__1); absw = NUMlapack_dlapy2 (&wr[j], &wi[j]); temp = temp * absw * absw; i__4 = nv + 2; i__5 = nv + 1; NUMblas_dgemv ("No transpose", &i__4, &i__5, &c_b10, &h___ref (l, l), ldh, vv, &c__1, &temp, v, &c__1); nv += 2; } /* Scale V(1:NV) so that MAX (fabs (V(i))) = 1. If V is zero, reset it to the unit vector. */ itemp = NUMblas_idamax (&nv, v, &c__1); temp = (d__1 = v[itemp - 1], fabs (d__1)); if (temp == 0.) { v[0] = 1.; i__4 = nv; for (ii = 2; ii <= i__4; ++ii) { v[ii - 1] = 0.; /* L110: */ } } else { temp = MAX (temp, smlnum); d__1 = 1. / temp; NUMblas_dscal (&nv, &d__1, v, &c__1); } } /* L120: */ } /* Multiple-shift QR step */ i__2 = i__ - 1; for (k = l; k <= i__2; ++k) { /* The first iteration of this loop determines a reflection G from the vector V and applies it from left and right to H, thus creating a nonzero bulge below the subdiagonal. Each subsequent iteration determines a reflection G to restore the Hessenberg form in the (K-1)th column, and thus chases the bulge one step toward the bottom of the active submatrix. NR is the order of G. Computing MIN */ i__4 = ns + 1, i__5 = i__ - k + 1; nr = MIN (i__4, i__5); if (k > l) { NUMblas_dcopy (&nr, &h___ref (k, k - 1), &c__1, v, &c__1); } NUMlapack_dlarfg (&nr, v, &v[1], &c__1, &tau); if (k > l) { h___ref (k, k - 1) = v[0]; i__4 = i__; for (ii = k + 1; ii <= i__4; ++ii) { h___ref (ii, k - 1) = 0.; /* L130: */ } } v[0] = 1.; /* Apply G from the left to transform the rows of the matrix in columns K to I2. */ i__4 = i2 - k + 1; NUMlapack_dlarfx ("Left", &nr, &i__4, v, &tau, &h___ref (k, k), ldh, &work[1]); /* Apply G from the right to transform the columns of the matrix in rows I1 to MIN (K+NR,I). Computing MIN */ i__5 = k + nr; i__4 = MIN (i__5, i__) - i1 + 1; NUMlapack_dlarfx ("Right", &i__4, &nr, v, &tau, &h___ref (i1, k), ldh, &work[1]); if (wantz) { /* Accumulate transformations in the matrix Z */ NUMlapack_dlarfx ("Right", &nh, &nr, v, &tau, &z___ref (*ilo, k), ldz, &work[1]); } /* L140: */ } /* L150: */ } /* Failure to converge in remaining number of iterations */ *info = i__; return 0; L160: /* A submatrix of order <= MAXB in rows and columns L to I has split off. Use the double-shift QR algorithm to handle it. */ NUMlapack_dlahqr (&wantt, &wantz, n, &l, &i__, &h__[h_offset], ldh, &wr[1], &wi[1], ilo, ihi, &z__[z_offset], ldz, info); if (*info > 0) { return 0; } /* Decrement number of remaining iterations, and return to start of the main loop with a new value of I. */ itn -= its; i__ = l - 1; goto L50; L170: work[1] = (double) MAX (1, *n); return 0; } /* NUMlapack_dhseqr */ #undef z___ref #undef s_ref #undef h___ref int NUMlapack_dlabad (double *smal, double *large) { if (log10 (*large) > 2e3) { *smal = sqrt (*smal); *large = sqrt (*large); } return 0; } /* NUMlapack_dlabad */ #define x_ref(a_1,a_2) x[(a_2)*x_dim1 + a_1] #define y_ref(a_1,a_2) y[(a_2)*y_dim1 + a_1] int NUMlapack_dlabrd (long *m, long *n, long *nb, double *a, long *lda, double *d__, double *e, double *tauq, double *taup, double *x, long *ldx, double *y, long *ldy) { /* Table of constant values */ static double c_b4 = -1.; static double c_b5 = 1.; static long c__1 = 1; static double c_b16 = 0.; /* System generated locals */ long a_dim1, a_offset, x_dim1, x_offset, y_dim1, y_offset, i__1, i__2, i__3; /* Local variables */ static long i__; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --d__; --e; --tauq; --taup; x_dim1 = *ldx; x_offset = 1 + x_dim1 * 1; x -= x_offset; y_dim1 = *ldy; y_offset = 1 + y_dim1 * 1; y -= y_offset; /* Function Body */ if (*m <= 0 || *n <= 0) { return 0; } if (*m >= *n) { /* Reduce to upper bidiagonal form */ i__1 = *nb; for (i__ = 1; i__ <= i__1; ++i__) { /* Update A(i:m,i) */ i__2 = *m - i__ + 1; i__3 = i__ - 1; NUMblas_dgemv ("No transpose", &i__2, &i__3, &c_b4, &a_ref (i__, 1), lda, &y_ref (i__, 1), ldy, &c_b5, &a_ref (i__, i__), &c__1); i__2 = *m - i__ + 1; i__3 = i__ - 1; NUMblas_dgemv ("No transpose", &i__2, &i__3, &c_b4, &x_ref (i__, 1), ldx, &a_ref (1, i__), &c__1, &c_b5, &a_ref (i__, i__), &c__1); /* Generate reflection Q(i) to annihilate A(i+1:m,i) Computing MIN */ i__2 = i__ + 1; i__3 = *m - i__ + 1; NUMlapack_dlarfg (&i__3, &a_ref (i__, i__), &a_ref (MIN (i__2, *m), i__), &c__1, &tauq[i__]); d__[i__] = a_ref (i__, i__); if (i__ < *n) { a_ref (i__, i__) = 1.; /* Compute Y(i+1:n,i) */ i__2 = *m - i__ + 1; i__3 = *n - i__; NUMblas_dgemv ("Transpose", &i__2, &i__3, &c_b5, &a_ref (i__, i__ + 1), lda, &a_ref (i__, i__), &c__1, &c_b16, &y_ref (i__ + 1, i__), &c__1); i__2 = *m - i__ + 1; i__3 = i__ - 1; NUMblas_dgemv ("Transpose", &i__2, &i__3, &c_b5, &a_ref (i__, 1), lda, &a_ref (i__, i__), &c__1, &c_b16, &y_ref (1, i__), &c__1); i__2 = *n - i__; i__3 = i__ - 1; NUMblas_dgemv ("No transpose", &i__2, &i__3, &c_b4, &y_ref (i__ + 1, 1), ldy, &y_ref (1, i__), &c__1, &c_b5, &y_ref (i__ + 1, i__), &c__1); i__2 = *m - i__ + 1; i__3 = i__ - 1; NUMblas_dgemv ("Transpose", &i__2, &i__3, &c_b5, &x_ref (i__, 1), ldx, &a_ref (i__, i__), &c__1, &c_b16, &y_ref (1, i__), &c__1); i__2 = i__ - 1; i__3 = *n - i__; NUMblas_dgemv ("Transpose", &i__2, &i__3, &c_b4, &a_ref (1, i__ + 1), lda, &y_ref (1, i__), &c__1, &c_b5, &y_ref (i__ + 1, i__), &c__1); i__2 = *n - i__; NUMblas_dscal (&i__2, &tauq[i__], &y_ref (i__ + 1, i__), &c__1); /* Update A(i,i+1:n) */ i__2 = *n - i__; NUMblas_dgemv ("No transpose", &i__2, &i__, &c_b4, &y_ref (i__ + 1, 1), ldy, &a_ref (i__, 1), lda, &c_b5, &a_ref (i__, i__ + 1), lda); i__2 = i__ - 1; i__3 = *n - i__; NUMblas_dgemv ("Transpose", &i__2, &i__3, &c_b4, &a_ref (1, i__ + 1), lda, &x_ref (i__, 1), ldx, &c_b5, &a_ref (i__, i__ + 1), lda); /* Generate reflection P(i) to annihilate A(i,i+2:n) Computing MIN */ i__2 = i__ + 2; i__3 = *n - i__; NUMlapack_dlarfg (&i__3, &a_ref (i__, i__ + 1), &a_ref (i__, MIN (i__2, *n)), lda, &taup[i__]); e[i__] = a_ref (i__, i__ + 1); a_ref (i__, i__ + 1) = 1.; /* Compute X(i+1:m,i) */ i__2 = *m - i__; i__3 = *n - i__; NUMblas_dgemv ("No transpose", &i__2, &i__3, &c_b5, &a_ref (i__ + 1, i__ + 1), lda, &a_ref (i__, i__ + 1), lda, &c_b16, &x_ref (i__ + 1, i__), &c__1); i__2 = *n - i__; NUMblas_dgemv ("Transpose", &i__2, &i__, &c_b5, &y_ref (i__ + 1, 1), ldy, &a_ref (i__, i__ + 1), lda, &c_b16, &x_ref (1, i__), &c__1); i__2 = *m - i__; NUMblas_dgemv ("No transpose", &i__2, &i__, &c_b4, &a_ref (i__ + 1, 1), lda, &x_ref (1, i__), &c__1, &c_b5, &x_ref (i__ + 1, i__), &c__1); i__2 = i__ - 1; i__3 = *n - i__; NUMblas_dgemv ("No transpose", &i__2, &i__3, &c_b5, &a_ref (1, i__ + 1), lda, &a_ref (i__, i__ + 1), lda, &c_b16, &x_ref (1, i__), &c__1); i__2 = *m - i__; i__3 = i__ - 1; NUMblas_dgemv ("No transpose", &i__2, &i__3, &c_b4, &x_ref (i__ + 1, 1), ldx, &x_ref (1, i__), &c__1, &c_b5, &x_ref (i__ + 1, i__), &c__1); i__2 = *m - i__; NUMblas_dscal (&i__2, &taup[i__], &x_ref (i__ + 1, i__), &c__1); } /* L10: */ } } else { /* Reduce to lower bidiagonal form */ i__1 = *nb; for (i__ = 1; i__ <= i__1; ++i__) { /* Update A(i,i:n) */ i__2 = *n - i__ + 1; i__3 = i__ - 1; NUMblas_dgemv ("No transpose", &i__2, &i__3, &c_b4, &y_ref (i__, 1), ldy, &a_ref (i__, 1), lda, &c_b5, &a_ref (i__, i__), lda); i__2 = i__ - 1; i__3 = *n - i__ + 1; NUMblas_dgemv ("Transpose", &i__2, &i__3, &c_b4, &a_ref (1, i__), lda, &x_ref (i__, 1), ldx, &c_b5, &a_ref (i__, i__), lda); /* Generate reflection P(i) to annihilate A(i,i+1:n) Computing MIN */ i__2 = i__ + 1; i__3 = *n - i__ + 1; NUMlapack_dlarfg (&i__3, &a_ref (i__, i__), &a_ref (i__, MIN (i__2, *n)), lda, &taup[i__]); d__[i__] = a_ref (i__, i__); if (i__ < *m) { a_ref (i__, i__) = 1.; /* Compute X(i+1:m,i) */ i__2 = *m - i__; i__3 = *n - i__ + 1; NUMblas_dgemv ("No transpose", &i__2, &i__3, &c_b5, &a_ref (i__ + 1, i__), lda, &a_ref (i__, i__), lda, &c_b16, &x_ref (i__ + 1, i__), &c__1); i__2 = *n - i__ + 1; i__3 = i__ - 1; NUMblas_dgemv ("Transpose", &i__2, &i__3, &c_b5, &y_ref (i__, 1), ldy, &a_ref (i__, i__), lda, &c_b16, &x_ref (1, i__), &c__1); i__2 = *m - i__; i__3 = i__ - 1; NUMblas_dgemv ("No transpose", &i__2, &i__3, &c_b4, &a_ref (i__ + 1, 1), lda, &x_ref (1, i__), &c__1, &c_b5, &x_ref (i__ + 1, i__), &c__1); i__2 = i__ - 1; i__3 = *n - i__ + 1; NUMblas_dgemv ("No transpose", &i__2, &i__3, &c_b5, &a_ref (1, i__), lda, &a_ref (i__, i__), lda, &c_b16, &x_ref (1, i__), &c__1); i__2 = *m - i__; i__3 = i__ - 1; NUMblas_dgemv ("No transpose", &i__2, &i__3, &c_b4, &x_ref (i__ + 1, 1), ldx, &x_ref (1, i__), &c__1, &c_b5, &x_ref (i__ + 1, i__), &c__1); i__2 = *m - i__; NUMblas_dscal (&i__2, &taup[i__], &x_ref (i__ + 1, i__), &c__1); /* Update A(i+1:m,i) */ i__2 = *m - i__; i__3 = i__ - 1; NUMblas_dgemv ("No transpose", &i__2, &i__3, &c_b4, &a_ref (i__ + 1, 1), lda, &y_ref (i__, 1), ldy, &c_b5, &a_ref (i__ + 1, i__), &c__1); i__2 = *m - i__; NUMblas_dgemv ("No transpose", &i__2, &i__, &c_b4, &x_ref (i__ + 1, 1), ldx, &a_ref (1, i__), &c__1, &c_b5, &a_ref (i__ + 1, i__), &c__1); /* Generate reflection Q(i) to annihilate A(i+2:m,i) Computing MIN */ i__2 = i__ + 2; i__3 = *m - i__; NUMlapack_dlarfg (&i__3, &a_ref (i__ + 1, i__), &a_ref (MIN (i__2, *m), i__), &c__1, &tauq[i__]); e[i__] = a_ref (i__ + 1, i__); a_ref (i__ + 1, i__) = 1.; /* Compute Y(i+1:n,i) */ i__2 = *m - i__; i__3 = *n - i__; NUMblas_dgemv ("Transpose", &i__2, &i__3, &c_b5, &a_ref (i__ + 1, i__ + 1), lda, &a_ref (i__ + 1, i__), &c__1, &c_b16, &y_ref (i__ + 1, i__), &c__1); i__2 = *m - i__; i__3 = i__ - 1; NUMblas_dgemv ("Transpose", &i__2, &i__3, &c_b5, &a_ref (i__ + 1, 1), lda, &a_ref (i__ + 1, i__), &c__1, &c_b16, &y_ref (1, i__), &c__1); i__2 = *n - i__; i__3 = i__ - 1; NUMblas_dgemv ("No transpose", &i__2, &i__3, &c_b4, &y_ref (i__ + 1, 1), ldy, &y_ref (1, i__), &c__1, &c_b5, &y_ref (i__ + 1, i__), &c__1); i__2 = *m - i__; NUMblas_dgemv ("Transpose", &i__2, &i__, &c_b5, &x_ref (i__ + 1, 1), ldx, &a_ref (i__ + 1, i__), &c__1, &c_b16, &y_ref (1, i__), &c__1); i__2 = *n - i__; NUMblas_dgemv ("Transpose", &i__, &i__2, &c_b4, &a_ref (1, i__ + 1), lda, &y_ref (1, i__), &c__1, &c_b5, &y_ref (i__ + 1, i__), &c__1); i__2 = *n - i__; NUMblas_dscal (&i__2, &tauq[i__], &y_ref (i__ + 1, i__), &c__1); } /* L20: */ } } return 0; } /* NUMlapack_dlabrd */ #undef y_ref #undef x_ref #define b_ref(a_1,a_2) b[(a_2)*b_dim1 + a_1] int NUMlapack_dlacpy (const char *uplo, long *m, long *n, double *a, long *lda, double *b, long *ldb) { /* System generated locals */ long a_dim1, a_offset, b_dim1, b_offset, i__1, i__2; /* Local variables */ static long i__, j; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; b_dim1 = *ldb; b_offset = 1 + b_dim1 * 1; b -= b_offset; /* Function Body */ if (lsame_ (uplo, "U")) { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = MIN (j, *m); for (i__ = 1; i__ <= i__2; ++i__) { b_ref (i__, j) = a_ref (i__, j); /* L10: */ } /* L20: */ } } else if (lsame_ (uplo, "L")) { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *m; for (i__ = j; i__ <= i__2; ++i__) { b_ref (i__, j) = a_ref (i__, j); /* L30: */ } /* L40: */ } } else { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { b_ref (i__, j) = a_ref (i__, j); /* L50: */ } /* L60: */ } } return 0; } /* NUMlapack_dlacpy */ #undef b_ref int NUMlapack_dladiv (double *a, double *b, double *c, double *d, double *p, double *q) { static double e, f; if (fabs (*d) < fabs (*c)) { e = *d / *c; f = *c + *d * e; *p = (*a + *b * e) / f; *q = (*b - *a * e) / f; } else { e = *c / *d; f = *d + *c * e; *p = (*b + *a * e) / f; *q = (- (*a) + *b * e) / f; } return 0; } /* NUMlapack_dladiv */ int NUMlapack_dlae2 (double *a, double *b, double *c__, double *rt1, double *rt2) { /* System generated locals */ double d__1; /* Local variables */ static double acmn, acmx, ab, df, tb, sm, rt, adf; sm = *a + *c__; df = *a - *c__; adf = fabs (df); tb = *b + *b; ab = fabs (tb); // djmw 20110721 changed abs(*a) to fabs(*a) if (fabs (*a) > fabs (*c__)) { acmx = *a; acmn = *c__; } else { acmx = *c__; acmn = *a; } if (adf > ab) { /* Computing 2nd power */ d__1 = ab / adf; rt = adf * sqrt (d__1 * d__1 + 1.); } else if (adf < ab) { /* Computing 2nd power */ d__1 = adf / ab; rt = ab * sqrt (d__1 * d__1 + 1.); } else { /* Includes case AB=ADF=0 */ rt = ab * sqrt (2.); } if (sm < 0.) { *rt1 = (sm - rt) * .5; /* Order of execution important. To get fully accurate smaller eigenvalue, next line needs to be executed in higher precision. */ *rt2 = acmx / *rt1 * acmn - *b / *rt1 * *b; } else if (sm > 0.) { *rt1 = (sm + rt) * .5; /* Order of execution important. To get fully accurate smaller eigenvalue, next line needs to be executed in higher precision. */ *rt2 = acmx / *rt1 * acmn - *b / *rt1 * *b; } else { /* Includes case RT1 = RT2 = 0 */ *rt1 = rt * .5; *rt2 = rt * -.5; } return 0; } /* NUMlapack_dlae2 */ int NUMlapack_dlaev2 (double *a, double *b, double *c__, double *rt1, double *rt2, double *cs1, double *sn1) { /* System generated locals */ double d__1; /* Local variables */ static double acmn, acmx, ab, df, cs, ct, tb, sm, tn, rt, adf, acs; static long sgn1, sgn2; sm = *a + *c__; df = *a - *c__; adf = fabs (df); tb = *b + *b; ab = fabs (tb); if (fabs (*a) > fabs (*c__)) { acmx = *a; acmn = *c__; } else { acmx = *c__; acmn = *a; } if (adf > ab) { /* Computing 2nd power */ d__1 = ab / adf; rt = adf * sqrt (d__1 * d__1 + 1.); } else if (adf < ab) { /* Computing 2nd power */ d__1 = adf / ab; rt = ab * sqrt (d__1 * d__1 + 1.); } else { /* Includes case AB=ADF=0 */ rt = ab * sqrt (2.); } if (sm < 0.) { *rt1 = (sm - rt) * .5; sgn1 = -1; /* Order of execution important. To get fully accurate smaller eigenvalue, next line needs to be executed in higher precision. */ *rt2 = acmx / *rt1 * acmn - *b / *rt1 * *b; } else if (sm > 0.) { *rt1 = (sm + rt) * .5; sgn1 = 1; /* Order of execution important. To get fully accurate smaller eigenvalue, next line needs to be executed in higher precision. */ *rt2 = acmx / *rt1 * acmn - *b / *rt1 * *b; } else { /* Includes case RT1 = RT2 = 0 */ *rt1 = rt * .5; *rt2 = rt * -.5; sgn1 = 1; } /* Compute the eigenvector */ if (df >= 0.) { cs = df + rt; sgn2 = 1; } else { cs = df - rt; sgn2 = -1; } acs = fabs (cs); if (acs > ab) { ct = -tb / cs; *sn1 = 1. / sqrt (ct * ct + 1.); *cs1 = ct * *sn1; } else { if (ab == 0.) { *cs1 = 1.; *sn1 = 0.; } else { tn = -cs / tb; *cs1 = 1. / sqrt (tn * tn + 1.); *sn1 = tn * *cs1; } } if (sgn1 == sgn2) { tn = *cs1; *cs1 = - (*sn1); *sn1 = tn; } return 0; } /* NUMlapack_dlaev2 */ int NUMlapack_dlags2 (long *upper, double *a1, double *a2, double *a3, double *b1, double *b2, double *b3, double *csu, double *snu, double *csv, double *snv, double *csq, double *snq) { /* System generated locals */ double d__1; /* Local variables */ static double aua11, aua12, aua21, aua22, avb11, avb12, avb21, avb22; double ua11r, ua22r, vb11r, vb22r, a, b, c__, d__, r__, s1, s2; static double ua11, ua12, ua21, ua22, vb11, vb12, vb21, vb22, csl, csr, snl, snr; if (*upper) { /* Input matrices A and B are upper triangular matrices Form matrix C = A*adj(B) = ( a b ) ( 0 d ) */ a = *a1 * *b3; d__ = *a3 * *b1; b = *a2 * *b1 - *a1 * *b2; /* The SVD of real 2-by-2 triangular C ( CSL -SNL )*( A B )*( CSR SNR ) = ( R 0 ) ( SNL CSL ) ( 0 D ) ( -SNR CSR ) ( 0 T ) */ NUMlapack_dlasv2 (&a, &b, &d__, &s1, &s2, &snr, &csr, &snl, &csl); if (fabs (csl) >= fabs (snl) || fabs (csr) >= fabs (snr)) { /* Compute the (1,1) and (1,2) elements of U'*A and V'*B, and (1,2) element of |U|'*|A| and |V|'*|B|. */ ua11r = csl * *a1; ua12 = csl * *a2 + snl * *a3; vb11r = csr * *b1; vb12 = csr * *b2 + snr * *b3; aua12 = fabs (csl) * fabs (*a2) + fabs (snl) * fabs (*a3); avb12 = fabs (csr) * fabs (*b2) + fabs (snr) * fabs (*b3); /* zero (1,2) elements of U'*A and V'*B */ if (fabs (ua11r) + fabs (ua12) != 0.) { if (aua12 / (fabs (ua11r) + fabs (ua12)) <= avb12 / (fabs (vb11r) + fabs (vb12))) { d__1 = -ua11r; NUMlapack_dlartg (&d__1, &ua12, csq, snq, &r__); } else { d__1 = -vb11r; NUMlapack_dlartg (&d__1, &vb12, csq, snq, &r__); } } else { d__1 = -vb11r; NUMlapack_dlartg (&d__1, &vb12, csq, snq, &r__); } *csu = csl; *snu = -snl; *csv = csr; *snv = -snr; } else { /* Compute the (2,1) and (2,2) elements of U'*A and V'*B, and (2,2) element of |U|'*|A| and |V|'*|B|. */ ua21 = -snl * *a1; ua22 = -snl * *a2 + csl * *a3; vb21 = -snr * *b1; vb22 = -snr * *b2 + csr * *b3; aua22 = fabs (snl) * fabs (*a2) + fabs (csl) * fabs (*a3); avb22 = fabs (snr) * fabs (*b2) + fabs (csr) * fabs (*b3); /* zero (2,2) elements of U'*A and V'*B, and then swap. */ if (fabs (ua21) + fabs (ua22) != 0.) { if (aua22 / (fabs (ua21) + fabs (ua22)) <= avb22 / (fabs (vb21) + fabs (vb22))) { d__1 = -ua21; NUMlapack_dlartg (&d__1, &ua22, csq, snq, &r__); } else { d__1 = -vb21; NUMlapack_dlartg (&d__1, &vb22, csq, snq, &r__); } } else { d__1 = -vb21; NUMlapack_dlartg (&d__1, &vb22, csq, snq, &r__); } *csu = snl; *snu = csl; *csv = snr; *snv = csr; } } else { /* Input matrices A and B are lower triangular matrices Form matrix C = A*adj(B) = ( a 0 ) ( c d ) */ a = *a1 * *b3; d__ = *a3 * *b1; c__ = *a2 * *b3 - *a3 * *b2; /* The SVD of real 2-by-2 triangular C ( CSL -SNL )*( A 0 )*( CSR SNR ) = ( R 0 ) ( SNL CSL ) ( C D ) ( -SNR CSR ) ( 0 T ) */ NUMlapack_dlasv2 (&a, &c__, &d__, &s1, &s2, &snr, &csr, &snl, &csl); if (fabs (csr) >= fabs (snr) || fabs (csl) >= fabs (snl)) { /* Compute the (2,1) and (2,2) elements of U'*A and V'*B, and (2,1) element of |U|'*|A| and |V|'*|B|. */ ua21 = -snr * *a1 + csr * *a2; ua22r = csr * *a3; vb21 = -snl * *b1 + csl * *b2; vb22r = csl * *b3; aua21 = fabs (snr) * fabs (*a1) + fabs (csr) * fabs (*a2); avb21 = fabs (snl) * fabs (*b1) + fabs (csl) * fabs (*b2); /* zero (2,1) elements of U'*A and V'*B. */ if (fabs (ua21) + fabs (ua22r) != 0.) { if (aua21 / (fabs (ua21) + fabs (ua22r)) <= avb21 / (fabs (vb21) + fabs (vb22r))) { NUMlapack_dlartg (&ua22r, &ua21, csq, snq, &r__); } else { NUMlapack_dlartg (&vb22r, &vb21, csq, snq, &r__); } } else { NUMlapack_dlartg (&vb22r, &vb21, csq, snq, &r__); } *csu = csr; *snu = -snr; *csv = csl; *snv = -snl; } else { /* Compute the (1,1) and (1,2) elements of U'*A and V'*B, and (1,1) element of |U|'*|A| and |V|'*|B|. */ ua11 = csr * *a1 + snr * *a2; ua12 = snr * *a3; vb11 = csl * *b1 + snl * *b2; vb12 = snl * *b3; aua11 = fabs (csr) * fabs (*a1) + fabs (snr) * fabs (*a2); avb11 = fabs (csl) * fabs (*b1) + fabs (snl) * fabs (*b2); /* zero (1,1) elements of U'*A and V'*B, and then swap. */ if (fabs (ua11) + fabs (ua12) != 0.) { if (aua11 / (fabs (ua11) + fabs (ua12)) <= avb11 / (fabs (vb11) + fabs (vb12))) { NUMlapack_dlartg (&ua12, &ua11, csq, snq, &r__); } else { NUMlapack_dlartg (&vb12, &vb11, csq, snq, &r__); } } else { NUMlapack_dlartg (&vb12, &vb11, csq, snq, &r__); } *csu = snr; *snu = csr; *csv = snl; *snv = csl; } } return 0; } /* NUMlapack_dlags2 */ int NUMlapack_dlahqr (int *wantt, int *wantz, long *n, long *ilo, long *ihi, double *h__, long *ldh, double *wr, double *wi, long *iloz, long *ihiz, double *z__, long *ldz, long *info) { /* Table of constant values */ static long c__1 = 1; /* System generated locals */ long h_dim1, h_offset, z_dim1, z_offset, i__1, i__2, i__3, i__4; double d__1, d__2; /* Local variables */ static double h43h34, disc, unfl, ovfl; static double work[1]; static long i__, j, k, l, m; static double s, v[3]; static long i1, i2; static double t1, t2, t3, v1, v2, v3; static double h00, h10, h11, h12, h21, h22, h33, h44; static long nh; static double cs; static long nr; static double sn; static long nz; static double smlnum, ave, h33s, h44s; static long itn, its; static double ulp, sum, tst1; #define h___ref(a_1,a_2) h__[(a_2)*h_dim1 + a_1] #define z___ref(a_1,a_2) z__[(a_2)*z_dim1 + a_1] h_dim1 = *ldh; h_offset = 1 + h_dim1 * 1; h__ -= h_offset; --wr; --wi; z_dim1 = *ldz; z_offset = 1 + z_dim1 * 1; z__ -= z_offset; /* Function Body */ *info = 0; /* Quick return if possible */ if (*n == 0) { return 0; } if (*ilo == *ihi) { wr[*ilo] = h___ref (*ilo, *ilo); wi[*ilo] = 0.; return 0; } nh = *ihi - *ilo + 1; nz = *ihiz - *iloz + 1; /* Set machine-dependent constants for the stopping criterion. If norm(H) <= sqrt(OVFL), overflow should not occur. */ unfl = NUMblas_dlamch ("Safe minimum"); ovfl = 1. / unfl; NUMlapack_dlabad (&unfl, &ovfl); ulp = NUMblas_dlamch ("Precision"); smlnum = unfl * (nh / ulp); /* I1 and I2 are the indices of the first row and last column of H to which transformations must be applied. If eigenvalues only are being computed, I1 and I2 are set inside the main loop. */ if (*wantt) { i1 = 1; i2 = *n; } /* ITN is the total number of QR iterations allowed. */ itn = nh * 30; /* The main loop begins here. I is the loop index and decreases from IHI to ILO in steps of 1 or 2. Each iteration of the loop works with the active submatrix in rows and columns L to I. Eigenvalues I+1 to IHI have already converged. Either L = ILO or H(L,L-1) is negligible so that the matrix splits. */ i__ = *ihi; L10: l = *ilo; if (i__ < *ilo) { goto L150; } /* Perform QR iterations on rows and columns ILO to I until a submatrix of order 1 or 2 splits off at the bottom because a subdiagonal element has become negligible. */ i__1 = itn; for (its = 0; its <= i__1; ++its) { /* Look for a single small subdiagonal element. */ i__2 = l + 1; for (k = i__; k >= i__2; --k) { tst1 = (d__1 = h___ref (k - 1, k - 1), fabs (d__1)) + (d__2 = h___ref (k, k), fabs (d__2)); if (tst1 == 0.) { i__3 = i__ - l + 1; tst1 = NUMlapack_dlanhs ("1", &i__3, &h___ref (l, l), ldh, work); } /* Computing MAX */ d__2 = ulp * tst1; if ( (d__1 = h___ref (k, k - 1), fabs (d__1)) <= MAX (d__2, smlnum)) { goto L30; } /* L20: */ } L30: l = k; if (l > *ilo) { /* H(L,L-1) is negligible */ h___ref (l, l - 1) = 0.; } /* Exit from loop if a submatrix of order 1 or 2 has split off. */ if (l >= i__ - 1) { goto L140; } /* Now the active submatrix is in rows and columns L to I. If eigenvalues only are being computed, only the active submatrix need be transformed. */ if (! (*wantt)) { i1 = l; i2 = i__; } if (its == 10 || its == 20) { /* Exceptional shift. */ s = (d__1 = h___ref (i__, i__ - 1), fabs (d__1)) + (d__2 = h___ref (i__ - 1, i__ - 2), fabs (d__2)); h44 = s * .75 + h___ref (i__, i__); h33 = h44; h43h34 = s * -.4375 * s; } else { /* Prepare to use Francis' double shift (i.e. 2nd degree generalized Rayleigh quotient) */ h44 = h___ref (i__, i__); h33 = h___ref (i__ - 1, i__ - 1); h43h34 = h___ref (i__, i__ - 1) * h___ref (i__ - 1, i__); s = h___ref (i__ - 1, i__ - 2) * h___ref (i__ - 1, i__ - 2); disc = (h33 - h44) * .5; disc = disc * disc + h43h34; if (disc > 0.) { /* Real roots: use Wilkinson's shift twice */ disc = sqrt (disc); ave = (h33 + h44) * .5; if (fabs (h33) - fabs (h44) > 0.) { h33 = h33 * h44 - h43h34; h44 = h33 / (d_sign (&disc, &ave) + ave); } else { h44 = d_sign (&disc, &ave) + ave; } h33 = h44; h43h34 = 0.; } } /* Look for two consecutive small subdiagonal elements. */ i__2 = l; for (m = i__ - 2; m >= i__2; --m) { /* Determine the effect of starting the double-shift QR iteration at row M, and see if this would make H(M,M-1) negligible. */ h11 = h___ref (m, m); h22 = h___ref (m + 1, m + 1); h21 = h___ref (m + 1, m); h12 = h___ref (m, m + 1); h44s = h44 - h11; h33s = h33 - h11; v1 = (h33s * h44s - h43h34) / h21 + h12; v2 = h22 - h11 - h33s - h44s; v3 = h___ref (m + 2, m + 1); s = fabs (v1) + fabs (v2) + fabs (v3); v1 /= s; v2 /= s; v3 /= s; v[0] = v1; v[1] = v2; v[2] = v3; if (m == l) { goto L50; } h00 = h___ref (m - 1, m - 1); h10 = h___ref (m, m - 1); tst1 = fabs (v1) * (fabs (h00) + fabs (h11) + fabs (h22)); if (fabs (h10) * (fabs (v2) + fabs (v3)) <= ulp * tst1) { goto L50; } /* L40: */ } L50: /* Double-shift QR step */ i__2 = i__ - 1; for (k = m; k <= i__2; ++k) { /* The first iteration of this loop determines a reflection G from the vector V and applies it from left and right to H, thus creating a nonzero bulge below the subdiagonal. Each subsequent iteration determines a reflection G to restore the Hessenberg form in the (K-1)th column, and thus chases the bulge one step toward the bottom of the active submatrix. NR is the order of G. Computing MIN */ i__3 = 3, i__4 = i__ - k + 1; nr = MIN (i__3, i__4); if (k > m) { NUMblas_dcopy (&nr, &h___ref (k, k - 1), &c__1, v, &c__1); } NUMlapack_dlarfg (&nr, v, &v[1], &c__1, &t1); if (k > m) { h___ref (k, k - 1) = v[0]; h___ref (k + 1, k - 1) = 0.; if (k < i__ - 1) { h___ref (k + 2, k - 1) = 0.; } } else if (m > l) { h___ref (k, k - 1) = -h___ref (k, k - 1); } v2 = v[1]; t2 = t1 * v2; if (nr == 3) { v3 = v[2]; t3 = t1 * v3; /* Apply G from the left to transform the rows of the matrix in columns K to I2. */ i__3 = i2; for (j = k; j <= i__3; ++j) { sum = h___ref (k, j) + v2 * h___ref (k + 1, j) + v3 * h___ref (k + 2, j); h___ref (k, j) = h___ref (k, j) - sum * t1; h___ref (k + 1, j) = h___ref (k + 1, j) - sum * t2; h___ref (k + 2, j) = h___ref (k + 2, j) - sum * t3; /* L60: */ } /* Apply G from the right to transform the columns of the matrix in rows I1 to MIN (K+3,I). Computing MIN */ i__4 = k + 3; i__3 = MIN (i__4, i__); for (j = i1; j <= i__3; ++j) { sum = h___ref (j, k) + v2 * h___ref (j, k + 1) + v3 * h___ref (j, k + 2); h___ref (j, k) = h___ref (j, k) - sum * t1; h___ref (j, k + 1) = h___ref (j, k + 1) - sum * t2; h___ref (j, k + 2) = h___ref (j, k + 2) - sum * t3; /* L70: */ } if (*wantz) { /* Accumulate transformations in the matrix Z */ i__3 = *ihiz; for (j = *iloz; j <= i__3; ++j) { sum = z___ref (j, k) + v2 * z___ref (j, k + 1) + v3 * z___ref (j, k + 2); z___ref (j, k) = z___ref (j, k) - sum * t1; z___ref (j, k + 1) = z___ref (j, k + 1) - sum * t2; z___ref (j, k + 2) = z___ref (j, k + 2) - sum * t3; /* L80: */ } } } else if (nr == 2) { /* Apply G from the left to transform the rows of the matrix in columns K to I2. */ i__3 = i2; for (j = k; j <= i__3; ++j) { sum = h___ref (k, j) + v2 * h___ref (k + 1, j); h___ref (k, j) = h___ref (k, j) - sum * t1; h___ref (k + 1, j) = h___ref (k + 1, j) - sum * t2; /* L90: */ } /* Apply G from the right to transform the columns of the matrix in rows I1 to MIN (K+3,I). */ i__3 = i__; for (j = i1; j <= i__3; ++j) { sum = h___ref (j, k) + v2 * h___ref (j, k + 1); h___ref (j, k) = h___ref (j, k) - sum * t1; h___ref (j, k + 1) = h___ref (j, k + 1) - sum * t2; /* L100: */ } if (*wantz) { /* Accumulate transformations in the matrix Z */ i__3 = *ihiz; for (j = *iloz; j <= i__3; ++j) { sum = z___ref (j, k) + v2 * z___ref (j, k + 1); z___ref (j, k) = z___ref (j, k) - sum * t1; z___ref (j, k + 1) = z___ref (j, k + 1) - sum * t2; /* L110: */ } } } /* L120: */ } /* L130: */ } /* Failure to converge in remaining number of iterations */ *info = i__; return 0; L140: if (l == i__) { /* H(I,I-1) is negligible: one eigenvalue has converged. */ wr[i__] = h___ref (i__, i__); wi[i__] = 0.; } else if (l == i__ - 1) { /* H(I-1,I-2) is negligible: a pair of eigenvalues have converged. Transform the 2-by-2 submatrix to standard Schur form, and compute and store the eigenvalues. */ NUMlapack_dlanv2 (&h___ref (i__ - 1, i__ - 1), &h___ref (i__ - 1, i__), &h___ref (i__, i__ - 1), &h___ref (i__, i__), &wr[i__ - 1], &wi[i__ - 1], &wr[i__], &wi[i__], &cs, &sn); if (*wantt) { /* Apply the transformation to the rest of H. */ if (i2 > i__) { i__1 = i2 - i__; NUMblas_drot (&i__1, &h___ref (i__ - 1, i__ + 1), ldh, &h___ref (i__, i__ + 1), ldh, &cs, &sn); } i__1 = i__ - i1 - 1; NUMblas_drot (&i__1, &h___ref (i1, i__ - 1), &c__1, &h___ref (i1, i__), &c__1, &cs, &sn); } if (*wantz) { /* Apply the transformation to Z. */ NUMblas_drot (&nz, &z___ref (*iloz, i__ - 1), &c__1, &z___ref (*iloz, i__), &c__1, &cs, &sn); } } /* Decrement number of remaining iterations, and return to start of the main loop with new value of I. */ itn -= its; i__ = l - 1; goto L10; L150: return 0; } /* NUMlapack_dlahqr */ #undef z___ref #undef h___ref int NUMlapack_dlahrd (long *n, long *k, long *nb, double *a, long *lda, double *tau, double *t, long *ldt, double *y, long *ldy) { /* Table of constant values */ static double c_b4 = -1.; static double c_b5 = 1.; static long c__1 = 1; static double c_b38 = 0.; /* System generated locals */ long a_dim1, a_offset, t_dim1, t_offset, y_dim1, y_offset, i__1, i__2, i__3; double d__1; /* Local variables */ static long i__; static double ei; #define t_ref(a_1,a_2) t[(a_2)*t_dim1 + a_1] #define y_ref(a_1,a_2) y[(a_2)*y_dim1 + a_1] --tau; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; t_dim1 = *ldt; t_offset = 1 + t_dim1 * 1; t -= t_offset; y_dim1 = *ldy; y_offset = 1 + y_dim1 * 1; y -= y_offset; /* Function Body */ if (*n <= 1) { return 0; } i__1 = *nb; for (i__ = 1; i__ <= i__1; ++i__) { if (i__ > 1) { /* Update A(1:n,i) Compute i-th column of A - Y * V' */ i__2 = i__ - 1; NUMblas_dgemv ("No transpose", n, &i__2, &c_b4, &y[y_offset], ldy, &a_ref (*k + i__ - 1, 1), lda, &c_b5, &a_ref (1, i__), &c__1); /* Apply I - V * T' * V' to this column (call it b) from the left, using the last column of T as workspace Let V = ( V1 ) and b = ( b1 ) (first I-1 rows) ( V2 ) ( b2 ) where V1 is unit lower triangular w := V1' * b1 */ i__2 = i__ - 1; NUMblas_dcopy (&i__2, &a_ref (*k + 1, i__), &c__1, &t_ref (1, *nb), &c__1); i__2 = i__ - 1; NUMblas_dtrmv ("Lower", "Transpose", "Unit", &i__2, &a_ref (*k + 1, 1), lda, &t_ref (1, *nb), &c__1); /* w := w + V2'*b2 */ i__2 = *n - *k - i__ + 1; i__3 = i__ - 1; NUMblas_dgemv ("Transpose", &i__2, &i__3, &c_b5, &a_ref (*k + i__, 1), lda, &a_ref (*k + i__, i__), &c__1, &c_b5, &t_ref (1, *nb), &c__1); /* w := T'*w */ i__2 = i__ - 1; NUMblas_dtrmv ("Upper", "Transpose", "Non-unit", &i__2, &t[t_offset], ldt, &t_ref (1, *nb), &c__1); /* b2 := b2 - V2*w */ i__2 = *n - *k - i__ + 1; i__3 = i__ - 1; NUMblas_dgemv ("No transpose", &i__2, &i__3, &c_b4, &a_ref (*k + i__, 1), lda, &t_ref (1, *nb), &c__1, &c_b5, &a_ref (*k + i__, i__), &c__1); /* b1 := b1 - V1*w */ i__2 = i__ - 1; NUMblas_dtrmv ("Lower", "No transpose", "Unit", &i__2, &a_ref (*k + 1, 1), lda, &t_ref (1, *nb), &c__1); i__2 = i__ - 1; NUMblas_daxpy (&i__2, &c_b4, &t_ref (1, *nb), &c__1, &a_ref (*k + 1, i__), &c__1); a_ref (*k + i__ - 1, i__ - 1) = ei; } /* Generate the elementary reflector H(i) to annihilate A(k+i+1:n,i) Computing MIN */ i__2 = *k + i__ + 1; i__3 = *n - *k - i__ + 1; NUMlapack_dlarfg (&i__3, &a_ref (*k + i__, i__), &a_ref (MIN (i__2, *n), i__), &c__1, &tau[i__]); ei = a_ref (*k + i__, i__); a_ref (*k + i__, i__) = 1.; /* Compute Y(1:n,i) */ i__2 = *n - *k - i__ + 1; NUMblas_dgemv ("No transpose", n, &i__2, &c_b5, &a_ref (1, i__ + 1), lda, &a_ref (*k + i__, i__), &c__1, &c_b38, &y_ref (1, i__), &c__1); i__2 = *n - *k - i__ + 1; i__3 = i__ - 1; NUMblas_dgemv ("Transpose", &i__2, &i__3, &c_b5, &a_ref (*k + i__, 1), lda, &a_ref (*k + i__, i__), &c__1, &c_b38, &t_ref (1, i__), &c__1); i__2 = i__ - 1; NUMblas_dgemv ("No transpose", n, &i__2, &c_b4, &y[y_offset], ldy, &t_ref (1, i__), &c__1, &c_b5, &y_ref (1, i__), &c__1); NUMblas_dscal (n, &tau[i__], &y_ref (1, i__), &c__1); /* Compute T(1:i,i) */ i__2 = i__ - 1; d__1 = -tau[i__]; NUMblas_dscal (&i__2, &d__1, &t_ref (1, i__), &c__1); i__2 = i__ - 1; NUMblas_dtrmv ("Upper", "No transpose", "Non-unit", &i__2, &t[t_offset], ldt, &t_ref (1, i__), &c__1); t_ref (i__, i__) = tau[i__]; /* L10: */ } a_ref (*k + *nb, *nb) = ei; return 0; } /* NUMlapack_dlahrd */ #undef y_ref #undef t_ref int NUMlapack_dlaln2 (int *ltrans, long *na, long *nw, double *smin, double *ca, double *a, long *lda, double *d1, double *d2, double *b, long *ldb, double *wr, double *wi, double *x, long *ldx, double *scale, double *xnorm, long *info) { /* Initialized data */ static int zswap[4] = { FALSE, FALSE, TRUE, TRUE }; static int rswap[4] = { FALSE, TRUE, FALSE, TRUE }; static long ipivot[16] /* was [4][4] */ = { 1, 2, 3, 4, 2, 1, 4, 3, 3, 4, 1, 2, 4, 3, 2, 1 }; /* System generated locals */ long a_dim1, a_offset, b_dim1, b_offset, x_dim1, x_offset; double d__1, d__2, d__3, d__4, d__5, d__6; static double equiv_0[4], equiv_1[4]; /* Local variables */ static double bbnd, cmax, ui11r, ui12s, temp, ur11r, ur12s; static long j; static double u22abs; static long icmax; static double bnorm, cnorm, smini; #define ci (equiv_0) #define cr (equiv_1) static double bignum, bi1, bi2, br1, br2, smlnum, xi1, xi2, xr1, xr2, ci21, ci22, cr21, cr22, li21, csi, ui11, lr21, ui12, ui22; #define civ (equiv_0) static double csr, ur11, ur12, ur22; #define crv (equiv_1) #define b_ref(a_1,a_2) b[(a_2)*b_dim1 + a_1] #define x_ref(a_1,a_2) x[(a_2)*x_dim1 + a_1] #define ci_ref(a_1,a_2) ci[(a_2)*2 + a_1 - 3] #define cr_ref(a_1,a_2) cr[(a_2)*2 + a_1 - 3] #define ipivot_ref(a_1,a_2) ipivot[(a_2)*4 + a_1 - 5] a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; b_dim1 = *ldb; b_offset = 1 + b_dim1 * 1; b -= b_offset; x_dim1 = *ldx; x_offset = 1 + x_dim1 * 1; x -= x_offset; /* Function Body Compute BIGNUM */ smlnum = 2. * NUMblas_dlamch ("Safe minimum"); bignum = 1. / smlnum; smini = MAX (*smin, smlnum); /* Don't check for input errors */ *info = 0; /* Standard Initializations */ *scale = 1.; if (*na == 1) { /* 1 x 1 (i.e., scalar) system C X = B */ if (*nw == 1) { /* Real 1x1 system. C = ca A - w D */ csr = *ca * a_ref (1, 1) - *wr * *d1; cnorm = fabs (csr); /* If | C | < SMINI, use C = SMINI */ if (cnorm < smini) { csr = smini; cnorm = smini; *info = 1; } /* Check scaling for X = B / C */ bnorm = (d__1 = b_ref (1, 1), fabs (d__1)); if (cnorm < 1. && bnorm > 1.) { if (bnorm > bignum * cnorm) { *scale = 1. / bnorm; } } /* Compute X */ x_ref (1, 1) = b_ref (1, 1) * *scale / csr; *xnorm = (d__1 = x_ref (1, 1), fabs (d__1)); } else { /* Complex 1x1 system (w is complex) C = ca A - w D */ csr = *ca * a_ref (1, 1) - *wr * *d1; csi = - (*wi) * *d1; cnorm = fabs (csr) + fabs (csi); /* If | C | < SMINI, use C = SMINI */ if (cnorm < smini) { csr = smini; csi = 0.; cnorm = smini; *info = 1; } /* Check scaling for X = B / C */ bnorm = (d__1 = b_ref (1, 1), fabs (d__1)) + (d__2 = b_ref (1, 2), fabs (d__2)); if (cnorm < 1. && bnorm > 1.) { if (bnorm > bignum * cnorm) { *scale = 1. / bnorm; } } /* Compute X */ d__1 = *scale * b_ref (1, 1); d__2 = *scale * b_ref (1, 2); NUMlapack_dladiv (&d__1, &d__2, &csr, &csi, &x_ref (1, 1), &x_ref (1, 2)); *xnorm = (d__1 = x_ref (1, 1), fabs (d__1)) + (d__2 = x_ref (1, 2), fabs (d__2)); } } else { /* 2x2 System Compute the real part of C = ca A - w D (or ca A' - w D ) */ cr_ref (1, 1) = *ca * a_ref (1, 1) - *wr * *d1; cr_ref (2, 2) = *ca * a_ref (2, 2) - *wr * *d2; if (*ltrans) { cr_ref (1, 2) = *ca * a_ref (2, 1); cr_ref (2, 1) = *ca * a_ref (1, 2); } else { cr_ref (2, 1) = *ca * a_ref (2, 1); cr_ref (1, 2) = *ca * a_ref (1, 2); } if (*nw == 1) { /* Real 2x2 system (w is real) Find the largest element in C */ cmax = 0.; icmax = 0; for (j = 1; j <= 4; ++j) { if ( (d__1 = crv[j - 1], fabs (d__1)) > cmax) { cmax = (d__1 = crv[j - 1], fabs (d__1)); icmax = j; } /* L10: */ } /* If norm(C) < SMINI, use SMINI*identity. */ if (cmax < smini) { /* Computing MAX */ d__3 = (d__1 = b_ref (1, 1), fabs (d__1)), d__4 = (d__2 = b_ref (2, 1), fabs (d__2)); bnorm = MAX (d__3, d__4); if (smini < 1. && bnorm > 1.) { if (bnorm > bignum * smini) { *scale = 1. / bnorm; } } temp = *scale / smini; x_ref (1, 1) = temp * b_ref (1, 1); x_ref (2, 1) = temp * b_ref (2, 1); *xnorm = temp * bnorm; *info = 1; return 0; } /* Gaussian elimination with complete pivoting. */ ur11 = crv[icmax - 1]; cr21 = crv[ipivot_ref (2, icmax) - 1]; ur12 = crv[ipivot_ref (3, icmax) - 1]; cr22 = crv[ipivot_ref (4, icmax) - 1]; ur11r = 1. / ur11; lr21 = ur11r * cr21; ur22 = cr22 - ur12 * lr21; /* If smaller pivot < SMINI, use SMINI */ if (fabs (ur22) < smini) { ur22 = smini; *info = 1; } if (rswap[icmax - 1]) { br1 = b_ref (2, 1); br2 = b_ref (1, 1); } else { br1 = b_ref (1, 1); br2 = b_ref (2, 1); } br2 -= lr21 * br1; /* Computing MAX */ d__2 = (d__1 = br1 * (ur22 * ur11r), fabs (d__1)), d__3 = fabs (br2); bbnd = MAX (d__2, d__3); if (bbnd > 1. && fabs (ur22) < 1.) { if (bbnd >= bignum * fabs (ur22)) { *scale = 1. / bbnd; } } xr2 = br2 * *scale / ur22; xr1 = *scale * br1 * ur11r - xr2 * (ur11r * ur12); if (zswap[icmax - 1]) { x_ref (1, 1) = xr2; x_ref (2, 1) = xr1; } else { x_ref (1, 1) = xr1; x_ref (2, 1) = xr2; } /* Computing MAX */ d__1 = fabs (xr1), d__2 = fabs (xr2); *xnorm = MAX (d__1, d__2); /* Further scaling if norm(A) norm(X) > overflow */ if (*xnorm > 1. && cmax > 1.) { if (*xnorm > bignum / cmax) { temp = cmax / bignum; x_ref (1, 1) = temp * x_ref (1, 1); x_ref (2, 1) = temp * x_ref (2, 1); *xnorm = temp * *xnorm; *scale = temp * *scale; } } } else { /* Complex 2x2 system (w is complex) Find the largest element in C */ ci_ref (1, 1) = - (*wi) * *d1; ci_ref (2, 1) = 0.; ci_ref (1, 2) = 0.; ci_ref (2, 2) = - (*wi) * *d2; cmax = 0.; icmax = 0; for (j = 1; j <= 4; ++j) { if ( (d__1 = crv[j - 1], fabs (d__1)) + (d__2 = civ[j - 1], fabs (d__2)) > cmax) { cmax = (d__1 = crv[j - 1], fabs (d__1)) + (d__2 = civ[j - 1], fabs (d__2)); icmax = j; } /* L20: */ } /* If norm(C) < SMINI, use SMINI*identity. */ if (cmax < smini) { /* Computing MAX */ d__5 = (d__1 = b_ref (1, 1), fabs (d__1)) + (d__2 = b_ref (1, 2), fabs (d__2)), d__6 = (d__3 = b_ref (2, 1), fabs (d__3)) + (d__4 = b_ref (2, 2), fabs (d__4)); bnorm = MAX (d__5, d__6); if (smini < 1. && bnorm > 1.) { if (bnorm > bignum * smini) { *scale = 1. / bnorm; } } temp = *scale / smini; x_ref (1, 1) = temp * b_ref (1, 1); x_ref (2, 1) = temp * b_ref (2, 1); x_ref (1, 2) = temp * b_ref (1, 2); x_ref (2, 2) = temp * b_ref (2, 2); *xnorm = temp * bnorm; *info = 1; return 0; } /* Gaussian elimination with complete pivoting. */ ur11 = crv[icmax - 1]; ui11 = civ[icmax - 1]; cr21 = crv[ipivot_ref (2, icmax) - 1]; ci21 = civ[ipivot_ref (2, icmax) - 1]; ur12 = crv[ipivot_ref (3, icmax) - 1]; ui12 = civ[ipivot_ref (3, icmax) - 1]; cr22 = crv[ipivot_ref (4, icmax) - 1]; ci22 = civ[ipivot_ref (4, icmax) - 1]; if (icmax == 1 || icmax == 4) { /* Code when off-diagonals of pivoted C are real */ if (fabs (ur11) > fabs (ui11)) { temp = ui11 / ur11; /* Computing 2nd power */ d__1 = temp; ur11r = 1. / (ur11 * (d__1 * d__1 + 1.)); ui11r = -temp * ur11r; } else { temp = ur11 / ui11; /* Computing 2nd power */ d__1 = temp; ui11r = -1. / (ui11 * (d__1 * d__1 + 1.)); ur11r = -temp * ui11r; } lr21 = cr21 * ur11r; li21 = cr21 * ui11r; ur12s = ur12 * ur11r; ui12s = ur12 * ui11r; ur22 = cr22 - ur12 * lr21; ui22 = ci22 - ur12 * li21; } else { /* Code when diagonals of pivoted C are real */ ur11r = 1. / ur11; ui11r = 0.; lr21 = cr21 * ur11r; li21 = ci21 * ur11r; ur12s = ur12 * ur11r; ui12s = ui12 * ur11r; ur22 = cr22 - ur12 * lr21 + ui12 * li21; ui22 = -ur12 * li21 - ui12 * lr21; } u22abs = fabs (ur22) + fabs (ui22); /* If smaller pivot < SMINI, use SMINI */ if (u22abs < smini) { ur22 = smini; ui22 = 0.; *info = 1; } if (rswap[icmax - 1]) { br2 = b_ref (1, 1); br1 = b_ref (2, 1); bi2 = b_ref (1, 2); bi1 = b_ref (2, 2); } else { br1 = b_ref (1, 1); br2 = b_ref (2, 1); bi1 = b_ref (1, 2); bi2 = b_ref (2, 2); } br2 = br2 - lr21 * br1 + li21 * bi1; bi2 = bi2 - li21 * br1 - lr21 * bi1; /* Computing MAX */ // djmw 20110721 changed abs(br2) to fabs(br2) d__1 = (fabs (br1) + fabs (bi1)) * (u22abs * (fabs (ur11r) + fabs (ui11r))), d__2 = fabs (br2) + fabs (bi2); bbnd = MAX (d__1, d__2); if (bbnd > 1. && u22abs < 1.) { if (bbnd >= bignum * u22abs) { *scale = 1. / bbnd; br1 = *scale * br1; bi1 = *scale * bi1; br2 = *scale * br2; bi2 = *scale * bi2; } } NUMlapack_dladiv (&br2, &bi2, &ur22, &ui22, &xr2, &xi2); xr1 = ur11r * br1 - ui11r * bi1 - ur12s * xr2 + ui12s * xi2; xi1 = ui11r * br1 + ur11r * bi1 - ui12s * xr2 - ur12s * xi2; if (zswap[icmax - 1]) { x_ref (1, 1) = xr2; x_ref (2, 1) = xr1; x_ref (1, 2) = xi2; x_ref (2, 2) = xi1; } else { x_ref (1, 1) = xr1; x_ref (2, 1) = xr2; x_ref (1, 2) = xi1; x_ref (2, 2) = xi2; } /* Computing MAX */ d__1 = fabs (xr1) + fabs (xi1), d__2 = fabs (xr2) + fabs (xi2); *xnorm = MAX (d__1, d__2); /* Further scaling if norm(A) norm(X) > overflow */ if (*xnorm > 1. && cmax > 1.) { if (*xnorm > bignum / cmax) { temp = cmax / bignum; x_ref (1, 1) = temp * x_ref (1, 1); x_ref (2, 1) = temp * x_ref (2, 1); x_ref (1, 2) = temp * x_ref (1, 2); x_ref (2, 2) = temp * x_ref (2, 2); *xnorm = temp * *xnorm; *scale = temp * *scale; } } } } return 0; } /* NUMlapack_NUMlapack_dlaln2 */ #undef ipivot_ref #undef cr_ref #undef ci_ref #undef x_ref #undef b_ref #undef crv #undef civ #undef cr #undef ci double NUMlapack_dlange (const char *norm, long *m, long *n, double *a, long *lda, double *work) { /* Table of constant values */ static long c__1 = 1; /* System generated locals */ long a_dim1, a_offset, i__1, i__2; double ret_val, d__1, d__2, d__3; /* Local variables */ static long i__, j; static double scale; static double value; static double sum; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --work; /* Function Body */ if (MIN (*m, *n) == 0) { value = 0.; } else if (lsame_ (norm, "M")) { /* Find MAX(abs(A(i,j))). */ value = 0.; i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { /* Computing MAX */ d__2 = value, d__3 = (d__1 = a_ref (i__, j), fabs (d__1)); value = MAX (d__2, d__3); /* L10: */ } /* L20: */ } } else if (lsame_ (norm, "O") || * (unsigned char *) norm == '1') { /* Find norm1(A). */ value = 0.; i__1 = *n; for (j = 1; j <= i__1; ++j) { sum = 0.; i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { sum += (d__1 = a_ref (i__, j), fabs (d__1)); /* L30: */ } value = MAX (value, sum); /* L40: */ } } else if (lsame_ (norm, "I")) { /* Find normI(A). */ i__1 = *m; for (i__ = 1; i__ <= i__1; ++i__) { work[i__] = 0.; /* L50: */ } i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { work[i__] += (d__1 = a_ref (i__, j), fabs (d__1)); /* L60: */ } /* L70: */ } value = 0.; i__1 = *m; for (i__ = 1; i__ <= i__1; ++i__) { /* Computing MAX */ d__1 = value, d__2 = work[i__]; value = MAX (d__1, d__2); /* L80: */ } } else if (lsame_ (norm, "F") || lsame_ (norm, "E")) { /* Find normF(A). */ scale = 0.; sum = 1.; i__1 = *n; for (j = 1; j <= i__1; ++j) { NUMlapack_dlassq (m, &a_ref (1, j), &c__1, &scale, &sum); /* L90: */ } value = scale * sqrt (sum); } ret_val = value; return ret_val; } /* NUMlapack_dlange */ double NUMlapack_dlanhs (const char *norm, long *n, double *a, long *lda, double *work) { /* Table of constant values */ static long c__1 = 1; /* System generated locals */ long a_dim1, a_offset, i__1, i__2, i__3, i__4; double ret_val, d__1, d__2, d__3; /* Local variables */ static long i__, j; static double scale; static double value; static double sum; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --work; /* Function Body */ if (*n == 0) { value = 0.; } else if (lsame_ (norm, "M")) { /* Find MAX (fabs (A(i,j))). */ value = 0.; i__1 = *n; for (j = 1; j <= i__1; ++j) { /* Computing MIN */ i__3 = *n, i__4 = j + 1; i__2 = MIN (i__3, i__4); for (i__ = 1; i__ <= i__2; ++i__) { /* Computing MAX */ d__2 = value, d__3 = (d__1 = a_ref (i__, j), fabs (d__1)); value = MAX (d__2, d__3); /* L10: */ } /* L20: */ } } else if (lsame_ (norm, "O") || * (unsigned char *) norm == '1') { /* Find norm1(A). */ value = 0.; i__1 = *n; for (j = 1; j <= i__1; ++j) { sum = 0.; /* Computing MIN */ i__3 = *n, i__4 = j + 1; i__2 = MIN (i__3, i__4); for (i__ = 1; i__ <= i__2; ++i__) { sum += (d__1 = a_ref (i__, j), fabs (d__1)); /* L30: */ } value = MAX (value, sum); /* L40: */ } } else if (lsame_ (norm, "I")) { /* Find normI(A). */ i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { work[i__] = 0.; /* L50: */ } i__1 = *n; for (j = 1; j <= i__1; ++j) { /* Computing MIN */ i__3 = *n, i__4 = j + 1; i__2 = MIN (i__3, i__4); for (i__ = 1; i__ <= i__2; ++i__) { work[i__] += (d__1 = a_ref (i__, j), fabs (d__1)); /* L60: */ } /* L70: */ } value = 0.; i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { /* Computing MAX */ d__1 = value, d__2 = work[i__]; value = MAX (d__1, d__2); /* L80: */ } } else if (lsame_ (norm, "F") || lsame_ (norm, "E")) { /* Find normF(A). */ scale = 0.; sum = 1.; i__1 = *n; for (j = 1; j <= i__1; ++j) { /* Computing MIN */ i__3 = *n, i__4 = j + 1; i__2 = MIN (i__3, i__4); NUMlapack_dlassq (&i__2, &a_ref (1, j), &c__1, &scale, &sum); /* L90: */ } value = scale * sqrt (sum); } ret_val = value; return ret_val; } /* NUMlapack_dlanhs */ double NUMlapack_dlanst (const char *norm, long *n, double *d__, double *e) { /* Table of constant values */ static long c__1 = 1; /* System generated locals */ long i__1; double ret_val, d__1, d__2, d__3, d__4, d__5; static long i__; static double scale; static double anorm; static double sum; --e; --d__; /* Function Body */ if (*n <= 0) { anorm = 0.; } else if (lsame_ (norm, "M")) { /* Find max(abs(A(i,j))). */ anorm = (d__1 = d__[*n], fabs (d__1)); i__1 = *n - 1; for (i__ = 1; i__ <= i__1; ++i__) { /* Computing MAX */ d__2 = anorm, d__3 = (d__1 = d__[i__], fabs (d__1)); anorm = MAX (d__2, d__3); /* Computing MAX */ d__2 = anorm, d__3 = (d__1 = e[i__], fabs (d__1)); anorm = MAX (d__2, d__3); /* L10: */ } } else if (lsame_ (norm, "O") || * (unsigned char *) norm == '1' || lsame_ (norm, "I")) { /* Find norm1(A). */ if (*n == 1) { anorm = fabs (d__[1]); } else { /* Computing MAX */ d__3 = fabs (d__[1]) + fabs (e[1]), d__4 = (d__1 = e[*n - 1], fabs (d__1)) + (d__2 = d__[*n], fabs (d__2)); anorm = MAX (d__3, d__4); i__1 = *n - 1; for (i__ = 2; i__ <= i__1; ++i__) { /* Computing MAX */ d__4 = anorm, d__5 = (d__1 = d__[i__], fabs (d__1)) + (d__2 = e[i__], fabs (d__2)) + (d__3 = e[i__ - 1], fabs (d__3)); anorm = MAX (d__4, d__5); /* L20: */ } } } else if (lsame_ (norm, "F") || lsame_ (norm, "E")) { /* Find normF(A). */ scale = 0.; sum = 1.; if (*n > 1) { i__1 = *n - 1; NUMlapack_dlassq (&i__1, &e[1], &c__1, &scale, &sum); sum *= 2; } NUMlapack_dlassq (n, &d__[1], &c__1, &scale, &sum); anorm = scale * sqrt (sum); } ret_val = anorm; return ret_val; } /* NUMlapack_dlanst */ double NUMlapack_dlansy (const char *norm, const char *uplo, long *n, double *a, long *lda, double *work) { /* Table of constant values */ static long c__1 = 1; /* System generated locals */ long a_dim1, a_offset, i__1, i__2; double ret_val, d__1, d__2, d__3; /* Local variables */ static double absa; static long i__, j; static double scale; static double value; static double sum; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --work; /* Function Body */ if (*n == 0) { value = 0.; } else if (lsame_ (norm, "M")) { /* Find max(abs(A(i,j))). */ value = 0.; if (lsame_ (uplo, "U")) { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = j; for (i__ = 1; i__ <= i__2; ++i__) { /* Computing MAX */ d__2 = value, d__3 = (d__1 = a_ref (i__, j), fabs (d__1)); value = MAX (d__2, d__3); /* L10: */ } /* L20: */ } } else { i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *n; for (i__ = j; i__ <= i__2; ++i__) { /* Computing MAX */ d__2 = value, d__3 = (d__1 = a_ref (i__, j), fabs (d__1)); value = MAX (d__2, d__3); /* L30: */ } /* L40: */ } } } else if (lsame_ (norm, "I") || lsame_ (norm, "O") || * (unsigned char *) norm == '1') { /* Find normI(A) ( = norm1(A), since A is symmetric). */ value = 0.; if (lsame_ (uplo, "U")) { i__1 = *n; for (j = 1; j <= i__1; ++j) { sum = 0.; i__2 = j - 1; for (i__ = 1; i__ <= i__2; ++i__) { absa = (d__1 = a_ref (i__, j), fabs (d__1)); sum += absa; work[i__] += absa; /* L50: */ } work[j] = sum + (d__1 = a_ref (j, j), fabs (d__1)); /* L60: */ } i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { /* Computing MAX */ d__1 = value, d__2 = work[i__]; value = MAX (d__1, d__2); /* L70: */ } } else { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { work[i__] = 0.; /* L80: */ } i__1 = *n; for (j = 1; j <= i__1; ++j) { sum = work[j] + (d__1 = a_ref (j, j), fabs (d__1)); i__2 = *n; for (i__ = j + 1; i__ <= i__2; ++i__) { absa = (d__1 = a_ref (i__, j), fabs (d__1)); sum += absa; work[i__] += absa; /* L90: */ } value = MAX (value, sum); /* L100: */ } } } else if (lsame_ (norm, "F") || lsame_ (norm, "E")) { /* Find normF(A). */ scale = 0.; sum = 1.; if (lsame_ (uplo, "U")) { i__1 = *n; for (j = 2; j <= i__1; ++j) { i__2 = j - 1; NUMlapack_dlassq (&i__2, &a_ref (1, j), &c__1, &scale, &sum); /* L110: */ } } else { i__1 = *n - 1; for (j = 1; j <= i__1; ++j) { i__2 = *n - j; NUMlapack_dlassq (&i__2, &a_ref (j + 1, j), &c__1, &scale, &sum); /* L120: */ } } sum *= 2; i__1 = *lda + 1; NUMlapack_dlassq (n, &a[a_offset], &i__1, &scale, &sum); value = scale * sqrt (sum); } ret_val = value; return ret_val; } /* NUMlapack_dlansy */ int NUMlapack_dlanv2 (double *a, double *b, double *c__, double *d__, double *rt1r, double *rt1i, double *rt2r, double *rt2i, double *cs, double *sn) { /* Table of constant values */ static double c_b4 = 1.; /* System generated locals */ double d__1, d__2; /* Local variables */ static double temp, p, scale, bcmax, z__, bcmis, sigma; static double aa, bb, cc, dd; static double cs1, sn1, sab, sac, eps, tau; eps = NUMblas_dlamch ("P"); if (*c__ == 0.) { *cs = 1.; *sn = 0.; goto L10; } else if (*b == 0.) { /* Swap rows and columns */ *cs = 0.; *sn = 1.; temp = *d__; *d__ = *a; *a = temp; *b = - (*c__); *c__ = 0.; goto L10; } else if (*a - *d__ == 0. && d_sign (&c_b4, b) != d_sign (&c_b4, c__)) { *cs = 1.; *sn = 0.; goto L10; } else { temp = *a - *d__; p = temp * .5; /* Computing MAX */ d__1 = fabs (*b), d__2 = fabs (*c__); bcmax = MAX (d__1, d__2); /* Computing MIN */ d__1 = fabs (*b), d__2 = fabs (*c__); bcmis = MIN (d__1, d__2) * d_sign (&c_b4, b) * d_sign (&c_b4, c__); /* Computing MAX */ d__1 = fabs (p); scale = MAX (d__1, bcmax); z__ = p / scale * p + bcmax / scale * bcmis; /* If Z is of the order of the machine accuracy, postpone the decision on the nature of eigenvalues */ if (z__ >= eps * 4.) { /* Real eigenvalues. Compute A and D. */ d__1 = sqrt (scale) * sqrt (z__); z__ = p + d_sign (&d__1, &p); *a = *d__ + z__; *d__ -= bcmax / z__ * bcmis; /* Compute B and the rotation matrix */ tau = NUMlapack_dlapy2 (c__, &z__); *cs = z__ / tau; *sn = *c__ / tau; *b -= *c__; *c__ = 0.; } else { /* Complex eigenvalues, or real (almost) equal eigenvalues. Make diagonal elements equal. */ sigma = *b + *c__; tau = NUMlapack_dlapy2 (&sigma, &temp); *cs = sqrt ( (fabs (sigma) / tau + 1.) * .5); *sn = - (p / (tau * *cs)) * d_sign (&c_b4, &sigma); /* Compute [ AA BB ] = [ A B ] [ CS -SN ] [ CC DD ] [ C D ] [ SN CS ] */ aa = *a * *cs + *b * *sn; bb = - (*a) * *sn + *b * *cs; cc = *c__ * *cs + *d__ * *sn; dd = - (*c__) * *sn + *d__ * *cs; /* Compute [ A B ] = [ CS SN ] [ AA BB ] [ C D ] [-SN CS ] [ CC DD ] */ *a = aa * *cs + cc * *sn; *b = bb * *cs + dd * *sn; *c__ = -aa * *sn + cc * *cs; *d__ = -bb * *sn + dd * *cs; temp = (*a + *d__) * .5; *a = temp; *d__ = temp; if (*c__ != 0.) { if (*b != 0.) { if (d_sign (&c_b4, b) == d_sign (&c_b4, c__)) { /* Real eigenvalues: reduce to upper triangular form */ sab = sqrt ( (fabs (*b))); sac = sqrt ( (fabs (*c__))); d__1 = sab * sac; p = d_sign (&d__1, c__); tau = 1. / sqrt ( (d__1 = *b + *c__, fabs (d__1))); *a = temp + p; *d__ = temp - p; *b -= *c__; *c__ = 0.; cs1 = sab * tau; sn1 = sac * tau; temp = *cs * cs1 - *sn * sn1; *sn = *cs * sn1 + *sn * cs1; *cs = temp; } } else { *b = - (*c__); *c__ = 0.; temp = *cs; *cs = - (*sn); *sn = temp; } } } } L10: /* Store eigenvalues in (RT1R,RT1I) and (RT2R,RT2I). */ *rt1r = *a; *rt2r = *d__; if (*c__ == 0.) { *rt1i = 0.; *rt2i = 0.; } else { *rt1i = sqrt ( (fabs (*b))) * sqrt ( (fabs (*c__))); *rt2i = - (*rt1i); } return 0; } /* NUMlapack_dlanv2 */ int NUMlapack_dlapll (long *n, double *x, long *incx, double *y, long *incy, double *ssmin) { /* System generated locals */ long i__1; /* Local variables */ static double c__; static double ssmax, a11, a12, a22; static double tau; --y; --x; /* Function Body */ if (*n <= 1) { *ssmin = 0.; return 0; } /* Compute the QR factorization of the N-by-2 matrix ( X Y ) */ NUMlapack_dlarfg (n, &x[1], &x[*incx + 1], incx, &tau); a11 = x[1]; x[1] = 1.; c__ = -tau * NUMblas_ddot (n, &x[1], incx, &y[1], incy); NUMblas_daxpy (n, &c__, &x[1], incx, &y[1], incy); i__1 = *n - 1; NUMlapack_dlarfg (&i__1, &y[*incy + 1], &y[ (*incy << 1) + 1], incy, &tau); a12 = y[1]; a22 = y[*incy + 1]; /* Compute the SVD of 2-by-2 Upper triangular matrix. */ NUMlapack_dlas2 (&a11, &a12, &a22, ssmin, &ssmax); return 0; } /* NUMlapack_dlapll */ #define x_ref(a_1,a_2) x[(a_2)*x_dim1 + a_1] int NUMlapack_dlapmt (long *forwrd, long *m, long *n, double *x, long *ldx, long *k) { /* System generated locals */ long x_dim1, x_offset, i__1, i__2; /* Local variables */ static double temp; static long i__, j, ii, in; x_dim1 = *ldx; x_offset = 1 + x_dim1 * 1; x -= x_offset; --k; /* Function Body */ if (*n <= 1) { return 0; } i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { k[i__] = -k[i__]; /* L10: */ } if (*forwrd) { /* Forward permutation */ i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { if (k[i__] > 0) { goto L40; } j = i__; k[j] = -k[j]; in = k[j]; L20: if (k[in] > 0) { goto L40; } i__2 = *m; for (ii = 1; ii <= i__2; ++ii) { temp = x_ref (ii, j); x_ref (ii, j) = x_ref (ii, in); x_ref (ii, in) = temp; /* L30: */ } k[in] = -k[in]; j = in; in = k[in]; goto L20; L40: /* L50: */ ; } } else { /* Backward permutation */ i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { if (k[i__] > 0) { goto L80; } k[i__] = -k[i__]; j = k[i__]; L60: if (j == i__) { goto L80; } i__2 = *m; for (ii = 1; ii <= i__2; ++ii) { temp = x_ref (ii, i__); x_ref (ii, i__) = x_ref (ii, j); x_ref (ii, j) = temp; /* L70: */ } k[j] = -k[j]; j = k[j]; goto L60; L80: /* L90: */ ; } } return 0; } /* NUMlapack_dlapmt */ #undef x_ref double NUMlapack_dlapy2 (double *x, double *y) { /* System generated locals */ double ret_val, d__1; /* Local variables */ static double xabs, yabs, w, z__; xabs = fabs (*x); yabs = fabs (*y); w = MAX (xabs, yabs); z__ = MIN (xabs, yabs); if (z__ == 0.) { ret_val = w; } else { /* Computing 2nd power */ d__1 = z__ / w; ret_val = w * sqrt (d__1 * d__1 + 1.); } return ret_val; } /* NUMlapack_dlapy2 */ #define work_ref(a_1,a_2) work[(a_2)*work_dim1 + a_1] #define v_ref(a_1,a_2) v[(a_2)*v_dim1 + a_1] int NUMlapack_dlarfb (const char *side, const char *trans, const char *direct, const char *storev, long *m, long *n, long *k, double *v, long *ldv, double *t, long *ldt, double *c__, long *ldc, double *work, long *ldwork) { /* Table of constant values */ static long c__1 = 1; static double c_b14 = 1.; static double c_b25 = -1.; /* System generated locals */ long c_dim1, c_offset, t_dim1, t_offset, v_dim1, v_offset; long work_dim1, work_offset, i__1, i__2; /* Local variables */ static long i__, j; static char transt[1]; v_dim1 = *ldv; v_offset = 1 + v_dim1 * 1; v -= v_offset; t_dim1 = *ldt; t_offset = 1 + t_dim1 * 1; t -= t_offset; c_dim1 = *ldc; c_offset = 1 + c_dim1 * 1; c__ -= c_offset; work_dim1 = *ldwork; work_offset = 1 + work_dim1 * 1; work -= work_offset; /* Function Body */ if (*m <= 0 || *n <= 0) { return 0; } if (lsame_ (trans, "N")) { * (unsigned char *) transt = 'T'; } else { * (unsigned char *) transt = 'N'; } if (lsame_ (storev, "C")) { if (lsame_ (direct, "F")) { /* Let V = ( V1 ) (first K rows) ( V2 ) where V1 is unit lower triangular. */ if (lsame_ (side, "L")) { /* Form H * C or H' * C where C = ( C1 ) ( C2 ) W := C' * V = (C1'*V1 + C2'*V2) (stored in WORK) W := C1' */ i__1 = *k; for (j = 1; j <= i__1; ++j) { NUMblas_dcopy (n, &c___ref (j, 1), ldc, &work_ref (1, j), &c__1); /* L10: */ } /* W := W * V1 */ NUMblas_dtrmm ("Right", "Lower", "No transpose", "Unit", n, k, &c_b14, &v[v_offset], ldv, &work[work_offset], ldwork); if (*m > *k) { /* W := W + C2'*V2 */ i__1 = *m - *k; NUMblas_dgemm ("Transpose", "No transpose", n, k, &i__1, &c_b14, &c___ref (*k + 1, 1), ldc, &v_ref (*k + 1, 1), ldv, &c_b14, &work[work_offset], ldwork); } /* W := W * T' or W * T */ NUMblas_dtrmm ("Right", "Upper", transt, "Non-unit", n, k, &c_b14, &t[t_offset], ldt, &work[work_offset], ldwork); /* C := C - V * W' */ if (*m > *k) { /* C2 := C2 - V2 * W' */ i__1 = *m - *k; NUMblas_dgemm ("No transpose", "Transpose", &i__1, n, k, &c_b25, &v_ref (*k + 1, 1), ldv, &work[work_offset], ldwork, &c_b14, &c___ref (*k + 1, 1), ldc); } /* W := W * V1' */ NUMblas_dtrmm ("Right", "Lower", "Transpose", "Unit", n, k, &c_b14, &v[v_offset], ldv, &work[work_offset], ldwork); /* C1 := C1 - W' */ i__1 = *k; for (j = 1; j <= i__1; ++j) { i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { c___ref (j, i__) = c___ref (j, i__) - work_ref (i__, j); /* L20: */ } /* L30: */ } } else if (lsame_ (side, "R")) { /* Form C * H or C * H' where C = ( C1 C2 ) W := C * V = (C1*V1 + C2*V2) (stored in WORK) W := C1 */ i__1 = *k; for (j = 1; j <= i__1; ++j) { NUMblas_dcopy (m, &c___ref (1, j), &c__1, &work_ref (1, j), &c__1); /* L40: */ } /* W := W * V1 */ NUMblas_dtrmm ("Right", "Lower", "No transpose", "Unit", m, k, &c_b14, &v[v_offset], ldv, &work[work_offset], ldwork); if (*n > *k) { /* W := W + C2 * V2 */ i__1 = *n - *k; NUMblas_dgemm ("No transpose", "No transpose", m, k, &i__1, &c_b14, &c___ref (1, *k + 1), ldc, &v_ref (*k + 1, 1), ldv, &c_b14, &work[work_offset], ldwork); } /* W := W * T or W * T' */ NUMblas_dtrmm ("Right", "Upper", trans, "Non-unit", m, k, &c_b14, &t[t_offset], ldt, &work[work_offset], ldwork); /* C := C - W * V' */ if (*n > *k) { /* C2 := C2 - W * V2' */ i__1 = *n - *k; NUMblas_dgemm ("No transpose", "Transpose", m, &i__1, k, &c_b25, &work[work_offset], ldwork, &v_ref (*k + 1, 1), ldv, &c_b14, &c___ref (1, *k + 1), ldc); } /* W := W * V1' */ NUMblas_dtrmm ("Right", "Lower", "Transpose", "Unit", m, k, &c_b14, &v[v_offset], ldv, &work[work_offset], ldwork); /* C1 := C1 - W */ i__1 = *k; for (j = 1; j <= i__1; ++j) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { c___ref (i__, j) = c___ref (i__, j) - work_ref (i__, j); /* L50: */ } /* L60: */ } } } else { /* Let V = ( V1 ) ( V2 ) (last K rows) where V2 is unit upper triangular. */ if (lsame_ (side, "L")) { /* Form H * C or H' * C where C = ( C1 ) ( C2 ) W := C' * V = (C1'*V1 + C2'*V2) (stored in WORK) W := C2' */ i__1 = *k; for (j = 1; j <= i__1; ++j) { NUMblas_dcopy (n, &c___ref (*m - *k + j, 1), ldc, &work_ref (1, j), &c__1); /* L70: */ } /* W := W * V2 */ NUMblas_dtrmm ("Right", "Upper", "No transpose", "Unit", n, k, &c_b14, &v_ref (*m - *k + 1, 1), ldv, &work[work_offset], ldwork); if (*m > *k) { /* W := W + C1'*V1 */ i__1 = *m - *k; NUMblas_dgemm ("Transpose", "No transpose", n, k, &i__1, &c_b14, &c__[c_offset], ldc, &v[v_offset], ldv, &c_b14, &work[work_offset], ldwork); } /* W := W * T' or W * T */ NUMblas_dtrmm ("Right", "Lower", transt, "Non-unit", n, k, &c_b14, &t[t_offset], ldt, &work[work_offset], ldwork); /* C := C - V * W' */ if (*m > *k) { /* C1 := C1 - V1 * W' */ i__1 = *m - *k; NUMblas_dgemm ("No transpose", "Transpose", &i__1, n, k, &c_b25, &v[v_offset], ldv, &work[work_offset], ldwork, &c_b14, &c__[c_offset], ldc); } /* W := W * V2' */ NUMblas_dtrmm ("Right", "Upper", "Transpose", "Unit", n, k, &c_b14, &v_ref (*m - *k + 1, 1), ldv, &work[work_offset], ldwork); /* C2 := C2 - W' */ i__1 = *k; for (j = 1; j <= i__1; ++j) { i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { c___ref (*m - *k + j, i__) = c___ref (*m - *k + j, i__) - work_ref (i__, j); /* L80: */ } /* L90: */ } } else if (lsame_ (side, "R")) { /* Form C * H or C * H' where C = ( C1 C2 ) W := C * V = (C1*V1 + C2*V2) (stored in WORK) W := C2 */ i__1 = *k; for (j = 1; j <= i__1; ++j) { NUMblas_dcopy (m, &c___ref (1, *n - *k + j), &c__1, &work_ref (1, j), &c__1); /* L100: */ } /* W := W * V2 */ NUMblas_dtrmm ("Right", "Upper", "No transpose", "Unit", m, k, &c_b14, &v_ref (*n - *k + 1, 1), ldv, &work[work_offset], ldwork); if (*n > *k) { /* W := W + C1 * V1 */ i__1 = *n - *k; NUMblas_dgemm ("No transpose", "No transpose", m, k, &i__1, &c_b14, &c__[c_offset], ldc, &v[v_offset], ldv, &c_b14, &work[work_offset], ldwork); } /* W := W * T or W * T' */ NUMblas_dtrmm ("Right", "Lower", trans, "Non-unit", m, k, &c_b14, &t[t_offset], ldt, &work[work_offset], ldwork); /* C := C - W * V' */ if (*n > *k) { /* C1 := C1 - W * V1' */ i__1 = *n - *k; NUMblas_dgemm ("No transpose", "Transpose", m, &i__1, k, &c_b25, &work[work_offset], ldwork, &v[v_offset], ldv, &c_b14, &c__[c_offset], ldc); } /* W := W * V2' */ NUMblas_dtrmm ("Right", "Upper", "Transpose", "Unit", m, k, &c_b14, &v_ref (*n - *k + 1, 1), ldv, &work[work_offset], ldwork); /* C2 := C2 - W */ i__1 = *k; for (j = 1; j <= i__1; ++j) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { c___ref (i__, *n - *k + j) = c___ref (i__, *n - *k + j) - work_ref (i__, j); /* L110: */ } /* L120: */ } } } } else if (lsame_ (storev, "R")) { if (lsame_ (direct, "F")) { /* Let V = ( V1 V2 ) (V1: first K columns) where V1 is unit upper triangular. */ if (lsame_ (side, "L")) { /* Form H * C or H' * C where C = ( C1 ) ( C2 ) W := C' * V' = (C1'*V1' + C2'*V2') (stored in WORK) W := C1' */ i__1 = *k; for (j = 1; j <= i__1; ++j) { NUMblas_dcopy (n, &c___ref (j, 1), ldc, &work_ref (1, j), &c__1); /* L130: */ } /* W := W * V1' */ NUMblas_dtrmm ("Right", "Upper", "Transpose", "Unit", n, k, &c_b14, &v[v_offset], ldv, &work[work_offset], ldwork); if (*m > *k) { /* W := W + C2'*V2' */ i__1 = *m - *k; NUMblas_dgemm ("Transpose", "Transpose", n, k, &i__1, &c_b14, &c___ref (*k + 1, 1), ldc, &v_ref (1, *k + 1), ldv, &c_b14, &work[work_offset], ldwork); } /* W := W * T' or W * T */ NUMblas_dtrmm ("Right", "Upper", transt, "Non-unit", n, k, &c_b14, &t[t_offset], ldt, &work[work_offset], ldwork); /* C := C - V' * W' */ if (*m > *k) { /* C2 := C2 - V2' * W' */ i__1 = *m - *k; NUMblas_dgemm ("Transpose", "Transpose", &i__1, n, k, &c_b25, &v_ref (1, *k + 1), ldv, &work[work_offset], ldwork, &c_b14, &c___ref (*k + 1, 1), ldc); } /* W := W * V1 */ NUMblas_dtrmm ("Right", "Upper", "No transpose", "Unit", n, k, &c_b14, &v[v_offset], ldv, &work[work_offset], ldwork); /* C1 := C1 - W' */ i__1 = *k; for (j = 1; j <= i__1; ++j) { i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { c___ref (j, i__) = c___ref (j, i__) - work_ref (i__, j); /* L140: */ } /* L150: */ } } else if (lsame_ (side, "R")) { /* Form C * H or C * H' where C = ( C1 C2 ) W := C * V' = (C1*V1' + C2*V2') (stored in WORK) W := C1 */ i__1 = *k; for (j = 1; j <= i__1; ++j) { NUMblas_dcopy (m, &c___ref (1, j), &c__1, &work_ref (1, j), &c__1); /* L160: */ } /* W := W * V1' */ NUMblas_dtrmm ("Right", "Upper", "Transpose", "Unit", m, k, &c_b14, &v[v_offset], ldv, &work[work_offset], ldwork); if (*n > *k) { /* W := W + C2 * V2' */ i__1 = *n - *k; NUMblas_dgemm ("No transpose", "Transpose", m, k, &i__1, &c_b14, &c___ref (1, *k + 1), ldc, &v_ref (1, *k + 1), ldv, &c_b14, &work[work_offset], ldwork); } /* W := W * T or W * T' */ NUMblas_dtrmm ("Right", "Upper", trans, "Non-unit", m, k, &c_b14, &t[t_offset], ldt, &work[work_offset], ldwork); /* C := C - W * V */ if (*n > *k) { /* C2 := C2 - W * V2 */ i__1 = *n - *k; NUMblas_dgemm ("No transpose", "No transpose", m, &i__1, k, &c_b25, &work[work_offset], ldwork, &v_ref (1, *k + 1), ldv, &c_b14, &c___ref (1, *k + 1), ldc); } /* W := W * V1 */ NUMblas_dtrmm ("Right", "Upper", "No transpose", "Unit", m, k, &c_b14, &v[v_offset], ldv, &work[work_offset], ldwork); /* C1 := C1 - W */ i__1 = *k; for (j = 1; j <= i__1; ++j) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { c___ref (i__, j) = c___ref (i__, j) - work_ref (i__, j); /* L170: */ } /* L180: */ } } } else { /* Let V = ( V1 V2 ) (V2: last K columns) where V2 is unit lower triangular. */ if (lsame_ (side, "L")) { /* Form H * C or H' * C where C = ( C1 ) ( C2 ) W := C' * V' = (C1'*V1' + C2'*V2') (stored in WORK) W := C2' */ i__1 = *k; for (j = 1; j <= i__1; ++j) { NUMblas_dcopy (n, &c___ref (*m - *k + j, 1), ldc, &work_ref (1, j), &c__1); /* L190: */ } /* W := W * V2' */ NUMblas_dtrmm ("Right", "Lower", "Transpose", "Unit", n, k, &c_b14, &v_ref (1, *m - *k + 1), ldv, &work[work_offset], ldwork); if (*m > *k) { /* W := W + C1'*V1' */ i__1 = *m - *k; NUMblas_dgemm ("Transpose", "Transpose", n, k, &i__1, &c_b14, &c__[c_offset], ldc, &v[v_offset], ldv, &c_b14, &work[work_offset], ldwork); } /* W := W * T' or W * T */ NUMblas_dtrmm ("Right", "Lower", transt, "Non-unit", n, k, &c_b14, &t[t_offset], ldt, &work[work_offset], ldwork); /* C := C - V' * W' */ if (*m > *k) { /* C1 := C1 - V1' * W' */ i__1 = *m - *k; NUMblas_dgemm ("Transpose", "Transpose", &i__1, n, k, &c_b25, &v[v_offset], ldv, &work[work_offset], ldwork, &c_b14, &c__[c_offset], ldc); } /* W := W * V2 */ NUMblas_dtrmm ("Right", "Lower", "No transpose", "Unit", n, k, &c_b14, &v_ref (1, *m - *k + 1), ldv, &work[work_offset], ldwork); /* C2 := C2 - W' */ i__1 = *k; for (j = 1; j <= i__1; ++j) { i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { c___ref (*m - *k + j, i__) = c___ref (*m - *k + j, i__) - work_ref (i__, j); /* L200: */ } /* L210: */ } } else if (lsame_ (side, "R")) { /* Form C * H or C * H' where C = ( C1 C2 ) W := C * V' = (C1*V1' + C2*V2') (stored in WORK) W := C2 */ i__1 = *k; for (j = 1; j <= i__1; ++j) { NUMblas_dcopy (m, &c___ref (1, *n - *k + j), &c__1, &work_ref (1, j), &c__1); /* L220: */ } /* W := W * V2' */ NUMblas_dtrmm ("Right", "Lower", "Transpose", "Unit", m, k, &c_b14, &v_ref (1, *n - *k + 1), ldv, &work[work_offset], ldwork); if (*n > *k) { /* W := W + C1 * V1' */ i__1 = *n - *k; NUMblas_dgemm ("No transpose", "Transpose", m, k, &i__1, &c_b14, &c__[c_offset], ldc, &v[v_offset], ldv, &c_b14, &work[work_offset], ldwork); } /* W := W * T or W * T' */ NUMblas_dtrmm ("Right", "Lower", trans, "Non-unit", m, k, &c_b14, &t[t_offset], ldt, &work[work_offset], ldwork); /* C := C - W * V */ if (*n > *k) { /* C1 := C1 - W * V1 */ i__1 = *n - *k; NUMblas_dgemm ("No transpose", "No transpose", m, &i__1, k, &c_b25, &work[work_offset], ldwork, &v[v_offset], ldv, &c_b14, &c__[c_offset], ldc); } /* W := W * V2 */ NUMblas_dtrmm ("Right", "Lower", "No transpose", "Unit", m, k, &c_b14, &v_ref (1, *n - *k + 1), ldv, &work[work_offset], ldwork); /* C1 := C1 - W */ i__1 = *k; for (j = 1; j <= i__1; ++j) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { c___ref (i__, *n - *k + j) = c___ref (i__, *n - *k + j) - work_ref (i__, j); /* L230: */ } /* L240: */ } } } } return 0; } /* NUMlapack_dlarfb */ #undef v_ref #undef work_ref int NUMlapack_dlarf (const char *side, long *m, long *n, double *v, long *incv, double *tau, double *c__, long *ldc, double *work) { /* Table of constant values */ static double c_b4 = 1.; static double c_b5 = 0.; static long c__1 = 1; /* System generated locals */ long c_dim1, c_offset; double d__1; /* Local variables */ --v; c_dim1 = *ldc; c_offset = 1 + c_dim1 * 1; c__ -= c_offset; --work; /* Function Body */ if (lsame_ (side, "L")) { /* Form H * C */ if (*tau != 0.) { /* w := C' * v */ NUMblas_dgemv ("Transpose", m, n, &c_b4, &c__[c_offset], ldc, &v[1], incv, &c_b5, &work[1], &c__1); /* C := C - v * w' */ d__1 = - (*tau); NUMblas_dger (m, n, &d__1, &v[1], incv, &work[1], &c__1, &c__[c_offset], ldc); } } else { /* Form C * H */ if (*tau != 0.) { /* w := C * v */ NUMblas_dgemv ("No transpose", m, n, &c_b4, &c__[c_offset], ldc, &v[1], incv, &c_b5, &work[1], &c__1); /* C := C - w * v' */ d__1 = - (*tau); NUMblas_dger (m, n, &d__1, &work[1], &c__1, &v[1], incv, &c__[c_offset], ldc); } } return 0; } /* NUMlapack_dlarf */ int NUMlapack_dlarfg (long *n, double *alpha, double *x, long *incx, double *tau) { /* System generated locals */ long i__1; double d__1; /* Local variables */ static double beta; static long j; static double xnorm; static double safmin, rsafmn; static long knt; --x; /* Function Body */ if (*n <= 1) { *tau = 0.; return 0; } i__1 = *n - 1; xnorm = NUMblas_dnrm2 (&i__1, &x[1], incx); if (xnorm == 0.) { /* H = I */ *tau = 0.; } else { /* general case */ d__1 = NUMlapack_dlapy2 (alpha, &xnorm); beta = -d_sign (&d__1, alpha); safmin = NUMblas_dlamch ("S") / NUMblas_dlamch ("E"); if (fabs (beta) < safmin) { /* XNORM, BETA may be inaccurate; scale X and recompute them */ rsafmn = 1. / safmin; knt = 0; L10: ++knt; i__1 = *n - 1; NUMblas_dscal (&i__1, &rsafmn, &x[1], incx); beta *= rsafmn; *alpha *= rsafmn; if (fabs (beta) < safmin) { goto L10; } /* New BETA is at most 1, at least SAFMIN */ i__1 = *n - 1; xnorm = NUMblas_dnrm2 (&i__1, &x[1], incx); d__1 = NUMlapack_dlapy2 (alpha, &xnorm); beta = -d_sign (&d__1, alpha); *tau = (beta - *alpha) / beta; i__1 = *n - 1; d__1 = 1. / (*alpha - beta); NUMblas_dscal (&i__1, &d__1, &x[1], incx); /* If ALPHA is subnormal, it may lose relative accuracy */ *alpha = beta; i__1 = knt; for (j = 1; j <= i__1; ++j) { *alpha *= safmin; /* L20: */ } } else { *tau = (beta - *alpha) / beta; i__1 = *n - 1; d__1 = 1. / (*alpha - beta); NUMblas_dscal (&i__1, &d__1, &x[1], incx); *alpha = beta; } } return 0; } /* NUMlapack_dlarfg */ #define t_ref(a_1,a_2) t[(a_2)*t_dim1 + a_1] #define v_ref(a_1,a_2) v[(a_2)*v_dim1 + a_1] int NUMlapack_dlarft (const char *direct, const char *storev, long *n, long *k, double *v, long *ldv, double *tau, double *t, long *ldt) { /* Table of constant values */ static long c__1 = 1; static double c_b8 = 0.; /* System generated locals */ long t_dim1, t_offset, v_dim1, v_offset, i__1, i__2, i__3; double d__1; /* Local variables */ static long i__, j; static double vii; v_dim1 = *ldv; v_offset = 1 + v_dim1 * 1; v -= v_offset; --tau; t_dim1 = *ldt; t_offset = 1 + t_dim1 * 1; t -= t_offset; /* Function Body */ if (*n == 0) { return 0; } if (lsame_ (direct, "F")) { i__1 = *k; for (i__ = 1; i__ <= i__1; ++i__) { if (tau[i__] == 0.) { /* H(i) = I */ i__2 = i__; for (j = 1; j <= i__2; ++j) { t_ref (j, i__) = 0.; /* L10: */ } } else { /* general case */ vii = v_ref (i__, i__); v_ref (i__, i__) = 1.; if (lsame_ (storev, "C")) { /* T(1:i-1,i) := - tau(i) * V(i:n,1:i-1)' * V(i:n,i) */ i__2 = *n - i__ + 1; i__3 = i__ - 1; d__1 = -tau[i__]; NUMblas_dgemv ("Transpose", &i__2, &i__3, &d__1, &v_ref (i__, 1), ldv, &v_ref (i__, i__), &c__1, &c_b8, &t_ref (1, i__), &c__1); } else { /* T(1:i-1,i) := - tau(i) * V(1:i-1,i:n) * V(i,i:n)' */ i__2 = i__ - 1; i__3 = *n - i__ + 1; d__1 = -tau[i__]; NUMblas_dgemv ("No transpose", &i__2, &i__3, &d__1, &v_ref (1, i__), ldv, &v_ref (i__, i__), ldv, &c_b8, &t_ref (1, i__), &c__1); } v_ref (i__, i__) = vii; /* T(1:i-1,i) := T(1:i-1,1:i-1) * T(1:i-1,i) */ i__2 = i__ - 1; NUMblas_dtrmv ("Upper", "No transpose", "Non-unit", &i__2, &t[t_offset], ldt, &t_ref (1, i__), &c__1); t_ref (i__, i__) = tau[i__]; } /* L20: */ } } else { for (i__ = *k; i__ >= 1; --i__) { if (tau[i__] == 0.) { /* H(i) = I */ i__1 = *k; for (j = i__; j <= i__1; ++j) { t_ref (j, i__) = 0.; /* L30: */ } } else { /* general case */ if (i__ < *k) { if (lsame_ (storev, "C")) { vii = v_ref (*n - *k + i__, i__); v_ref (*n - *k + i__, i__) = 1.; /* T(i+1:k,i) := - tau(i) * V(1:n-k+i,i+1:k)' * V(1:n-k+i,i) */ i__1 = *n - *k + i__; i__2 = *k - i__; d__1 = -tau[i__]; NUMblas_dgemv ("Transpose", &i__1, &i__2, &d__1, &v_ref (1, i__ + 1), ldv, &v_ref (1, i__), &c__1, &c_b8, &t_ref (i__ + 1, i__), &c__1); v_ref (*n - *k + i__, i__) = vii; } else { vii = v_ref (i__, *n - *k + i__); v_ref (i__, *n - *k + i__) = 1.; /* T(i+1:k,i) := - tau(i) * V(i+1:k,1:n-k+i) * V(i,1:n-k+i)' */ i__1 = *k - i__; i__2 = *n - *k + i__; d__1 = -tau[i__]; NUMblas_dgemv ("No transpose", &i__1, &i__2, &d__1, &v_ref (i__ + 1, 1), ldv, &v_ref (i__, 1), ldv, &c_b8, &t_ref (i__ + 1, i__), &c__1); v_ref (i__, *n - *k + i__) = vii; } /* T(i+1:k,i) := T(i+1:k,i+1:k) * T(i+1:k,i) */ i__1 = *k - i__; NUMblas_dtrmv ("Lower", "No transpose", "Non-unit", &i__1, &t_ref (i__ + 1, i__ + 1), ldt, &t_ref (i__ + 1, i__), &c__1); } t_ref (i__, i__) = tau[i__]; } /* L40: */ } } return 0; } /* NUMlapack_dlarft */ #undef v_ref #undef t_ref int NUMlapack_dlartg (double *f, double *g, double *cs, double *sn, double *r__) { /* Initialized data */ static long first = TRUE; /* System generated locals */ long i__1; double d__1, d__2; /* Local variables */ static long i__; static double scale; static long count; static double f1, g1, safmn2, safmx2; static double safmin, eps; if (first) { first = FALSE; safmin = NUMblas_dlamch ("S"); eps = NUMblas_dlamch ("E"); d__1 = NUMblas_dlamch ("B"); i__1 = (long) (log (safmin / eps) / log (NUMblas_dlamch ("B")) / 2.); safmn2 = pow_di (&d__1, &i__1); safmx2 = 1. / safmn2; } if (*g == 0.) { *cs = 1.; *sn = 0.; *r__ = *f; } else if (*f == 0.) { *cs = 0.; *sn = 1.; *r__ = *g; } else { f1 = *f; g1 = *g; /* Computing MAX */ d__1 = fabs (f1), d__2 = fabs (g1); scale = MAX (d__1, d__2); if (scale >= safmx2) { count = 0; L10: ++count; f1 *= safmn2; g1 *= safmn2; /* Computing MAX */ d__1 = fabs (f1), d__2 = fabs (g1); scale = MAX (d__1, d__2); if (scale >= safmx2) { goto L10; } /* Computing 2nd power */ d__1 = f1; /* Computing 2nd power */ d__2 = g1; *r__ = sqrt (d__1 * d__1 + d__2 * d__2); *cs = f1 / *r__; *sn = g1 / *r__; i__1 = count; for (i__ = 1; i__ <= i__1; ++i__) { *r__ *= safmx2; /* L20: */ } } else if (scale <= safmn2) { count = 0; L30: ++count; f1 *= safmx2; g1 *= safmx2; /* Computing MAX */ d__1 = fabs (f1), d__2 = fabs (g1); scale = MAX (d__1, d__2); if (scale <= safmn2) { goto L30; } /* Computing 2nd power */ d__1 = f1; /* Computing 2nd power */ d__2 = g1; *r__ = sqrt (d__1 * d__1 + d__2 * d__2); *cs = f1 / *r__; *sn = g1 / *r__; i__1 = count; for (i__ = 1; i__ <= i__1; ++i__) { *r__ *= safmn2; /* L40: */ } } else { /* Computing 2nd power */ d__1 = f1; /* Computing 2nd power */ d__2 = g1; *r__ = sqrt (d__1 * d__1 + d__2 * d__2); *cs = f1 / *r__; *sn = g1 / *r__; } if (fabs (*f) > fabs (*g) && *cs < 0.) { *cs = - (*cs); *sn = - (*sn); *r__ = - (*r__); } } return 0; } /* NUMlapack_dlartg */ int NUMlapack_dlarfx (const char *side, long *m, long *n, double *v, double *tau, double *c__, long *ldc, double *work) { /* Table of constant values */ static double c_b14 = 1.; static long c__1 = 1; static double c_b16 = 0.; /* System generated locals */ long c_dim1, c_offset, i__1; double d__1; /* Local variables */ static long j; static double t1, t2, t3, t4, t5, t6, t7, t8, t9, v1, v2, v3, v4, v5, v6, v7, v8, v9, t10, v10, sum; --v; c_dim1 = *ldc; c_offset = 1 + c_dim1 * 1; c__ -= c_offset; --work; /* Function Body */ if (*tau == 0.) { return 0; } if (lsame_ (side, "L")) { /* Form H * C, where H has order m. */ switch (*m) { case 1: goto L10; case 2: goto L30; case 3: goto L50; case 4: goto L70; case 5: goto L90; case 6: goto L110; case 7: goto L130; case 8: goto L150; case 9: goto L170; case 10: goto L190; } /* Code for general M w := C'*v */ NUMblas_dgemv ("Transpose", m, n, &c_b14, &c__[c_offset], ldc, &v[1], &c__1, &c_b16, &work[1], &c__1); /* C := C - tau * v * w' */ d__1 = - (*tau); NUMblas_dger (m, n, &d__1, &v[1], &c__1, &work[1], &c__1, &c__[c_offset], ldc); goto L410; L10: /* Special code for 1 x 1 Householder */ t1 = 1. - *tau * v[1] * v[1]; i__1 = *n; for (j = 1; j <= i__1; ++j) { c___ref (1, j) = t1 * c___ref (1, j); /* L20: */ } goto L410; L30: /* Special code for 2 x 2 Householder */ v1 = v[1]; t1 = *tau * v1; v2 = v[2]; t2 = *tau * v2; i__1 = *n; for (j = 1; j <= i__1; ++j) { sum = v1 * c___ref (1, j) + v2 * c___ref (2, j); c___ref (1, j) = c___ref (1, j) - sum * t1; c___ref (2, j) = c___ref (2, j) - sum * t2; /* L40: */ } goto L410; L50: /* Special code for 3 x 3 Householder */ v1 = v[1]; t1 = *tau * v1; v2 = v[2]; t2 = *tau * v2; v3 = v[3]; t3 = *tau * v3; i__1 = *n; for (j = 1; j <= i__1; ++j) { sum = v1 * c___ref (1, j) + v2 * c___ref (2, j) + v3 * c___ref (3, j); c___ref (1, j) = c___ref (1, j) - sum * t1; c___ref (2, j) = c___ref (2, j) - sum * t2; c___ref (3, j) = c___ref (3, j) - sum * t3; /* L60: */ } goto L410; L70: /* Special code for 4 x 4 Householder */ v1 = v[1]; t1 = *tau * v1; v2 = v[2]; t2 = *tau * v2; v3 = v[3]; t3 = *tau * v3; v4 = v[4]; t4 = *tau * v4; i__1 = *n; for (j = 1; j <= i__1; ++j) { sum = v1 * c___ref (1, j) + v2 * c___ref (2, j) + v3 * c___ref (3, j) + v4 * c___ref (4, j); c___ref (1, j) = c___ref (1, j) - sum * t1; c___ref (2, j) = c___ref (2, j) - sum * t2; c___ref (3, j) = c___ref (3, j) - sum * t3; c___ref (4, j) = c___ref (4, j) - sum * t4; /* L80: */ } goto L410; L90: /* Special code for 5 x 5 Householder */ v1 = v[1]; t1 = *tau * v1; v2 = v[2]; t2 = *tau * v2; v3 = v[3]; t3 = *tau * v3; v4 = v[4]; t4 = *tau * v4; v5 = v[5]; t5 = *tau * v5; i__1 = *n; for (j = 1; j <= i__1; ++j) { sum = v1 * c___ref (1, j) + v2 * c___ref (2, j) + v3 * c___ref (3, j) + v4 * c___ref (4, j) + v5 * c___ref (5, j); c___ref (1, j) = c___ref (1, j) - sum * t1; c___ref (2, j) = c___ref (2, j) - sum * t2; c___ref (3, j) = c___ref (3, j) - sum * t3; c___ref (4, j) = c___ref (4, j) - sum * t4; c___ref (5, j) = c___ref (5, j) - sum * t5; /* L100: */ } goto L410; L110: /* Special code for 6 x 6 Householder */ v1 = v[1]; t1 = *tau * v1; v2 = v[2]; t2 = *tau * v2; v3 = v[3]; t3 = *tau * v3; v4 = v[4]; t4 = *tau * v4; v5 = v[5]; t5 = *tau * v5; v6 = v[6]; t6 = *tau * v6; i__1 = *n; for (j = 1; j <= i__1; ++j) { sum = v1 * c___ref (1, j) + v2 * c___ref (2, j) + v3 * c___ref (3, j) + v4 * c___ref (4, j) + v5 * c___ref (5, j) + v6 * c___ref (6, j); c___ref (1, j) = c___ref (1, j) - sum * t1; c___ref (2, j) = c___ref (2, j) - sum * t2; c___ref (3, j) = c___ref (3, j) - sum * t3; c___ref (4, j) = c___ref (4, j) - sum * t4; c___ref (5, j) = c___ref (5, j) - sum * t5; c___ref (6, j) = c___ref (6, j) - sum * t6; /* L120: */ } goto L410; L130: /* Special code for 7 x 7 Householder */ v1 = v[1]; t1 = *tau * v1; v2 = v[2]; t2 = *tau * v2; v3 = v[3]; t3 = *tau * v3; v4 = v[4]; t4 = *tau * v4; v5 = v[5]; t5 = *tau * v5; v6 = v[6]; t6 = *tau * v6; v7 = v[7]; t7 = *tau * v7; i__1 = *n; for (j = 1; j <= i__1; ++j) { sum = v1 * c___ref (1, j) + v2 * c___ref (2, j) + v3 * c___ref (3, j) + v4 * c___ref (4, j) + v5 * c___ref (5, j) + v6 * c___ref (6, j) + v7 * c___ref (7, j); c___ref (1, j) = c___ref (1, j) - sum * t1; c___ref (2, j) = c___ref (2, j) - sum * t2; c___ref (3, j) = c___ref (3, j) - sum * t3; c___ref (4, j) = c___ref (4, j) - sum * t4; c___ref (5, j) = c___ref (5, j) - sum * t5; c___ref (6, j) = c___ref (6, j) - sum * t6; c___ref (7, j) = c___ref (7, j) - sum * t7; /* L140: */ } goto L410; L150: /* Special code for 8 x 8 Householder */ v1 = v[1]; t1 = *tau * v1; v2 = v[2]; t2 = *tau * v2; v3 = v[3]; t3 = *tau * v3; v4 = v[4]; t4 = *tau * v4; v5 = v[5]; t5 = *tau * v5; v6 = v[6]; t6 = *tau * v6; v7 = v[7]; t7 = *tau * v7; v8 = v[8]; t8 = *tau * v8; i__1 = *n; for (j = 1; j <= i__1; ++j) { sum = v1 * c___ref (1, j) + v2 * c___ref (2, j) + v3 * c___ref (3, j) + v4 * c___ref (4, j) + v5 * c___ref (5, j) + v6 * c___ref (6, j) + v7 * c___ref (7, j) + v8 * c___ref (8, j); c___ref (1, j) = c___ref (1, j) - sum * t1; c___ref (2, j) = c___ref (2, j) - sum * t2; c___ref (3, j) = c___ref (3, j) - sum * t3; c___ref (4, j) = c___ref (4, j) - sum * t4; c___ref (5, j) = c___ref (5, j) - sum * t5; c___ref (6, j) = c___ref (6, j) - sum * t6; c___ref (7, j) = c___ref (7, j) - sum * t7; c___ref (8, j) = c___ref (8, j) - sum * t8; /* L160: */ } goto L410; L170: /* Special code for 9 x 9 Householder */ v1 = v[1]; t1 = *tau * v1; v2 = v[2]; t2 = *tau * v2; v3 = v[3]; t3 = *tau * v3; v4 = v[4]; t4 = *tau * v4; v5 = v[5]; t5 = *tau * v5; v6 = v[6]; t6 = *tau * v6; v7 = v[7]; t7 = *tau * v7; v8 = v[8]; t8 = *tau * v8; v9 = v[9]; t9 = *tau * v9; i__1 = *n; for (j = 1; j <= i__1; ++j) { sum = v1 * c___ref (1, j) + v2 * c___ref (2, j) + v3 * c___ref (3, j) + v4 * c___ref (4, j) + v5 * c___ref (5, j) + v6 * c___ref (6, j) + v7 * c___ref (7, j) + v8 * c___ref (8, j) + v9 * c___ref (9, j); c___ref (1, j) = c___ref (1, j) - sum * t1; c___ref (2, j) = c___ref (2, j) - sum * t2; c___ref (3, j) = c___ref (3, j) - sum * t3; c___ref (4, j) = c___ref (4, j) - sum * t4; c___ref (5, j) = c___ref (5, j) - sum * t5; c___ref (6, j) = c___ref (6, j) - sum * t6; c___ref (7, j) = c___ref (7, j) - sum * t7; c___ref (8, j) = c___ref (8, j) - sum * t8; c___ref (9, j) = c___ref (9, j) - sum * t9; /* L180: */ } goto L410; L190: /* Special code for 10 x 10 Householder */ v1 = v[1]; t1 = *tau * v1; v2 = v[2]; t2 = *tau * v2; v3 = v[3]; t3 = *tau * v3; v4 = v[4]; t4 = *tau * v4; v5 = v[5]; t5 = *tau * v5; v6 = v[6]; t6 = *tau * v6; v7 = v[7]; t7 = *tau * v7; v8 = v[8]; t8 = *tau * v8; v9 = v[9]; t9 = *tau * v9; v10 = v[10]; t10 = *tau * v10; i__1 = *n; for (j = 1; j <= i__1; ++j) { sum = v1 * c___ref (1, j) + v2 * c___ref (2, j) + v3 * c___ref (3, j) + v4 * c___ref (4, j) + v5 * c___ref (5, j) + v6 * c___ref (6, j) + v7 * c___ref (7, j) + v8 * c___ref (8, j) + v9 * c___ref (9, j) + v10 * c___ref (10, j); c___ref (1, j) = c___ref (1, j) - sum * t1; c___ref (2, j) = c___ref (2, j) - sum * t2; c___ref (3, j) = c___ref (3, j) - sum * t3; c___ref (4, j) = c___ref (4, j) - sum * t4; c___ref (5, j) = c___ref (5, j) - sum * t5; c___ref (6, j) = c___ref (6, j) - sum * t6; c___ref (7, j) = c___ref (7, j) - sum * t7; c___ref (8, j) = c___ref (8, j) - sum * t8; c___ref (9, j) = c___ref (9, j) - sum * t9; c___ref (10, j) = c___ref (10, j) - sum * t10; /* L200: */ } goto L410; } else { /* Form C * H, where H has order n. */ switch (*n) { case 1: goto L210; case 2: goto L230; case 3: goto L250; case 4: goto L270; case 5: goto L290; case 6: goto L310; case 7: goto L330; case 8: goto L350; case 9: goto L370; case 10: goto L390; } /* Code for general N w := C * v */ NUMblas_dgemv ("No transpose", m, n, &c_b14, &c__[c_offset], ldc, &v[1], &c__1, &c_b16, &work[1], &c__1); /* C := C - tau * w * v' */ d__1 = - (*tau); NUMblas_dger (m, n, &d__1, &work[1], &c__1, &v[1], &c__1, &c__[c_offset], ldc); goto L410; L210: /* Special code for 1 x 1 Householder */ t1 = 1. - *tau * v[1] * v[1]; i__1 = *m; for (j = 1; j <= i__1; ++j) { c___ref (j, 1) = t1 * c___ref (j, 1); /* L220: */ } goto L410; L230: /* Special code for 2 x 2 Householder */ v1 = v[1]; t1 = *tau * v1; v2 = v[2]; t2 = *tau * v2; i__1 = *m; for (j = 1; j <= i__1; ++j) { sum = v1 * c___ref (j, 1) + v2 * c___ref (j, 2); c___ref (j, 1) = c___ref (j, 1) - sum * t1; c___ref (j, 2) = c___ref (j, 2) - sum * t2; /* L240: */ } goto L410; L250: /* Special code for 3 x 3 Householder */ v1 = v[1]; t1 = *tau * v1; v2 = v[2]; t2 = *tau * v2; v3 = v[3]; t3 = *tau * v3; i__1 = *m; for (j = 1; j <= i__1; ++j) { sum = v1 * c___ref (j, 1) + v2 * c___ref (j, 2) + v3 * c___ref (j, 3); c___ref (j, 1) = c___ref (j, 1) - sum * t1; c___ref (j, 2) = c___ref (j, 2) - sum * t2; c___ref (j, 3) = c___ref (j, 3) - sum * t3; /* L260: */ } goto L410; L270: /* Special code for 4 x 4 Householder */ v1 = v[1]; t1 = *tau * v1; v2 = v[2]; t2 = *tau * v2; v3 = v[3]; t3 = *tau * v3; v4 = v[4]; t4 = *tau * v4; i__1 = *m; for (j = 1; j <= i__1; ++j) { sum = v1 * c___ref (j, 1) + v2 * c___ref (j, 2) + v3 * c___ref (j, 3) + v4 * c___ref (j, 4); c___ref (j, 1) = c___ref (j, 1) - sum * t1; c___ref (j, 2) = c___ref (j, 2) - sum * t2; c___ref (j, 3) = c___ref (j, 3) - sum * t3; c___ref (j, 4) = c___ref (j, 4) - sum * t4; /* L280: */ } goto L410; L290: /* Special code for 5 x 5 Householder */ v1 = v[1]; t1 = *tau * v1; v2 = v[2]; t2 = *tau * v2; v3 = v[3]; t3 = *tau * v3; v4 = v[4]; t4 = *tau * v4; v5 = v[5]; t5 = *tau * v5; i__1 = *m; for (j = 1; j <= i__1; ++j) { sum = v1 * c___ref (j, 1) + v2 * c___ref (j, 2) + v3 * c___ref (j, 3) + v4 * c___ref (j, 4) + v5 * c___ref (j, 5); c___ref (j, 1) = c___ref (j, 1) - sum * t1; c___ref (j, 2) = c___ref (j, 2) - sum * t2; c___ref (j, 3) = c___ref (j, 3) - sum * t3; c___ref (j, 4) = c___ref (j, 4) - sum * t4; c___ref (j, 5) = c___ref (j, 5) - sum * t5; /* L300: */ } goto L410; L310: /* Special code for 6 x 6 Householder */ v1 = v[1]; t1 = *tau * v1; v2 = v[2]; t2 = *tau * v2; v3 = v[3]; t3 = *tau * v3; v4 = v[4]; t4 = *tau * v4; v5 = v[5]; t5 = *tau * v5; v6 = v[6]; t6 = *tau * v6; i__1 = *m; for (j = 1; j <= i__1; ++j) { sum = v1 * c___ref (j, 1) + v2 * c___ref (j, 2) + v3 * c___ref (j, 3) + v4 * c___ref (j, 4) + v5 * c___ref (j, 5) + v6 * c___ref (j, 6); c___ref (j, 1) = c___ref (j, 1) - sum * t1; c___ref (j, 2) = c___ref (j, 2) - sum * t2; c___ref (j, 3) = c___ref (j, 3) - sum * t3; c___ref (j, 4) = c___ref (j, 4) - sum * t4; c___ref (j, 5) = c___ref (j, 5) - sum * t5; c___ref (j, 6) = c___ref (j, 6) - sum * t6; /* L320: */ } goto L410; L330: /* Special code for 7 x 7 Householder */ v1 = v[1]; t1 = *tau * v1; v2 = v[2]; t2 = *tau * v2; v3 = v[3]; t3 = *tau * v3; v4 = v[4]; t4 = *tau * v4; v5 = v[5]; t5 = *tau * v5; v6 = v[6]; t6 = *tau * v6; v7 = v[7]; t7 = *tau * v7; i__1 = *m; for (j = 1; j <= i__1; ++j) { sum = v1 * c___ref (j, 1) + v2 * c___ref (j, 2) + v3 * c___ref (j, 3) + v4 * c___ref (j, 4) + v5 * c___ref (j, 5) + v6 * c___ref (j, 6) + v7 * c___ref (j, 7); c___ref (j, 1) = c___ref (j, 1) - sum * t1; c___ref (j, 2) = c___ref (j, 2) - sum * t2; c___ref (j, 3) = c___ref (j, 3) - sum * t3; c___ref (j, 4) = c___ref (j, 4) - sum * t4; c___ref (j, 5) = c___ref (j, 5) - sum * t5; c___ref (j, 6) = c___ref (j, 6) - sum * t6; c___ref (j, 7) = c___ref (j, 7) - sum * t7; /* L340: */ } goto L410; L350: /* Special code for 8 x 8 Householder */ v1 = v[1]; t1 = *tau * v1; v2 = v[2]; t2 = *tau * v2; v3 = v[3]; t3 = *tau * v3; v4 = v[4]; t4 = *tau * v4; v5 = v[5]; t5 = *tau * v5; v6 = v[6]; t6 = *tau * v6; v7 = v[7]; t7 = *tau * v7; v8 = v[8]; t8 = *tau * v8; i__1 = *m; for (j = 1; j <= i__1; ++j) { sum = v1 * c___ref (j, 1) + v2 * c___ref (j, 2) + v3 * c___ref (j, 3) + v4 * c___ref (j, 4) + v5 * c___ref (j, 5) + v6 * c___ref (j, 6) + v7 * c___ref (j, 7) + v8 * c___ref (j, 8); c___ref (j, 1) = c___ref (j, 1) - sum * t1; c___ref (j, 2) = c___ref (j, 2) - sum * t2; c___ref (j, 3) = c___ref (j, 3) - sum * t3; c___ref (j, 4) = c___ref (j, 4) - sum * t4; c___ref (j, 5) = c___ref (j, 5) - sum * t5; c___ref (j, 6) = c___ref (j, 6) - sum * t6; c___ref (j, 7) = c___ref (j, 7) - sum * t7; c___ref (j, 8) = c___ref (j, 8) - sum * t8; /* L360: */ } goto L410; L370: /* Special code for 9 x 9 Householder */ v1 = v[1]; t1 = *tau * v1; v2 = v[2]; t2 = *tau * v2; v3 = v[3]; t3 = *tau * v3; v4 = v[4]; t4 = *tau * v4; v5 = v[5]; t5 = *tau * v5; v6 = v[6]; t6 = *tau * v6; v7 = v[7]; t7 = *tau * v7; v8 = v[8]; t8 = *tau * v8; v9 = v[9]; t9 = *tau * v9; i__1 = *m; for (j = 1; j <= i__1; ++j) { sum = v1 * c___ref (j, 1) + v2 * c___ref (j, 2) + v3 * c___ref (j, 3) + v4 * c___ref (j, 4) + v5 * c___ref (j, 5) + v6 * c___ref (j, 6) + v7 * c___ref (j, 7) + v8 * c___ref (j, 8) + v9 * c___ref (j, 9); c___ref (j, 1) = c___ref (j, 1) - sum * t1; c___ref (j, 2) = c___ref (j, 2) - sum * t2; c___ref (j, 3) = c___ref (j, 3) - sum * t3; c___ref (j, 4) = c___ref (j, 4) - sum * t4; c___ref (j, 5) = c___ref (j, 5) - sum * t5; c___ref (j, 6) = c___ref (j, 6) - sum * t6; c___ref (j, 7) = c___ref (j, 7) - sum * t7; c___ref (j, 8) = c___ref (j, 8) - sum * t8; c___ref (j, 9) = c___ref (j, 9) - sum * t9; /* L380: */ } goto L410; L390: /* Special code for 10 x 10 Householder */ v1 = v[1]; t1 = *tau * v1; v2 = v[2]; t2 = *tau * v2; v3 = v[3]; t3 = *tau * v3; v4 = v[4]; t4 = *tau * v4; v5 = v[5]; t5 = *tau * v5; v6 = v[6]; t6 = *tau * v6; v7 = v[7]; t7 = *tau * v7; v8 = v[8]; t8 = *tau * v8; v9 = v[9]; t9 = *tau * v9; v10 = v[10]; t10 = *tau * v10; i__1 = *m; for (j = 1; j <= i__1; ++j) { sum = v1 * c___ref (j, 1) + v2 * c___ref (j, 2) + v3 * c___ref (j, 3) + v4 * c___ref (j, 4) + v5 * c___ref (j, 5) + v6 * c___ref (j, 6) + v7 * c___ref (j, 7) + v8 * c___ref (j, 8) + v9 * c___ref (j, 9) + v10 * c___ref (j, 10); c___ref (j, 1) = c___ref (j, 1) - sum * t1; c___ref (j, 2) = c___ref (j, 2) - sum * t2; c___ref (j, 3) = c___ref (j, 3) - sum * t3; c___ref (j, 4) = c___ref (j, 4) - sum * t4; c___ref (j, 5) = c___ref (j, 5) - sum * t5; c___ref (j, 6) = c___ref (j, 6) - sum * t6; c___ref (j, 7) = c___ref (j, 7) - sum * t7; c___ref (j, 8) = c___ref (j, 8) - sum * t8; c___ref (j, 9) = c___ref (j, 9) - sum * t9; c___ref (j, 10) = c___ref (j, 10) - sum * t10; /* L400: */ } goto L410; } L410: return 0; } /* NUMlapack_dlarfx */ int NUMlapack_dlas2 (double *f, double *g, double *h__, double *ssmin, double *ssmax) { /* System generated locals */ double d__1, d__2; /* Local variables */ static double fhmn, fhmx, c__, fa, ga, ha, as, at, au; fa = fabs (*f); ga = fabs (*g); ha = fabs (*h__); fhmn = MIN (fa, ha); fhmx = MAX (fa, ha); if (fhmn == 0.) { *ssmin = 0.; if (fhmx == 0.) { *ssmax = ga; } else { /* Computing 2nd power */ d__1 = MIN (fhmx, ga) / MAX (fhmx, ga); *ssmax = MAX (fhmx, ga) * sqrt (d__1 * d__1 + 1.); } } else { if (ga < fhmx) { as = fhmn / fhmx + 1.; at = (fhmx - fhmn) / fhmx; /* Computing 2nd power */ d__1 = ga / fhmx; au = d__1 * d__1; c__ = 2. / (sqrt (as * as + au) + sqrt (at * at + au)); *ssmin = fhmn * c__; *ssmax = fhmx / c__; } else { au = fhmx / ga; if (au == 0.) { /* Avoid possible harmful underflow if exponent range asymmetric (true SSMIN may not underflow even if AU underflows) */ *ssmin = fhmn * fhmx / ga; *ssmax = ga; } else { as = fhmn / fhmx + 1.; at = (fhmx - fhmn) / fhmx; /* Computing 2nd power */ d__1 = as * au; /* Computing 2nd power */ d__2 = at * au; c__ = 1. / (sqrt (d__1 * d__1 + 1.) + sqrt (d__2 * d__2 + 1.)); *ssmin = fhmn * c__ * au; *ssmin += *ssmin; *ssmax = ga / (c__ + c__); } } } return 0; } /* NUMlapack_dlas2 */ int NUMlapack_dlascl (const char *type__, long *kl, long *ku, double *cfrom, double *cto, long *m, long *n, double *a, long *lda, long *info) { /* System generated locals */ long a_dim1, a_offset, i__1, i__2, i__3, i__4, i__5; /* Local variables */ static long done; static double ctoc; static long i__, j; static long itype, k1, k2, k3, k4; static double cfrom1; static double cfromc; static double bignum, smlnum, mul, cto1; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; /* Function Body */ *info = 0; if (lsame_ (type__, "G")) { itype = 0; } else if (lsame_ (type__, "L")) { itype = 1; } else if (lsame_ (type__, "U")) { itype = 2; } else if (lsame_ (type__, "H")) { itype = 3; } else if (lsame_ (type__, "B")) { itype = 4; } else if (lsame_ (type__, "Q")) { itype = 5; } else if (lsame_ (type__, "Z")) { itype = 6; } else { itype = -1; } if (itype == -1) { *info = -1; } else if (*cfrom == 0.) { *info = -4; } else if (*m < 0) { *info = -6; } else if (*n < 0 || itype == 4 && *n != *m || itype == 5 && *n != *m) { *info = -7; } else if (itype <= 3 && *lda < MAX (1, *m)) { *info = -9; } else if (itype >= 4) { /* Computing MAX */ i__1 = *m - 1; if (*kl < 0 || *kl > MAX (i__1, 0)) { *info = -2; } else { /* if(complicated condition) */ /* Computing MAX */ i__1 = *n - 1; if (*ku < 0 || *ku > MAX (i__1, 0) || (itype == 4 || itype == 5) && *kl != *ku) { *info = -3; } else if (itype == 4 && *lda < *kl + 1 || itype == 5 && *lda < *ku + 1 || itype == 6 && *lda < (*kl << 1) + *ku + 1) { *info = -9; } } } if (*info != 0) { i__1 = - (*info); xerbla_ ("DLASCL", &i__1); return 0; } /* Quick return if possible */ if (*n == 0 || *m == 0) { return 0; } /* Get machine parameters */ smlnum = NUMblas_dlamch ("S"); bignum = 1. / smlnum; cfromc = *cfrom; ctoc = *cto; L10: cfrom1 = cfromc * smlnum; cto1 = ctoc / bignum; if (fabs (cfrom1) > fabs (ctoc) && ctoc != 0.) { mul = smlnum; done = FALSE; cfromc = cfrom1; } else if (fabs (cto1) > fabs (cfromc)) { mul = bignum; done = FALSE; ctoc = cto1; } else { mul = ctoc / cfromc; done = TRUE; } if (itype == 0) { /* Full matrix */ i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { a_ref (i__, j) = a_ref (i__, j) * mul; /* L20: */ } /* L30: */ } } else if (itype == 1) { /* Lower triangular matrix */ i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *m; for (i__ = j; i__ <= i__2; ++i__) { a_ref (i__, j) = a_ref (i__, j) * mul; /* L40: */ } /* L50: */ } } else if (itype == 2) { /* Upper triangular matrix */ i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = MIN (j, *m); for (i__ = 1; i__ <= i__2; ++i__) { a_ref (i__, j) = a_ref (i__, j) * mul; /* L60: */ } /* L70: */ } } else if (itype == 3) { /* Upper Hessenberg matrix */ i__1 = *n; for (j = 1; j <= i__1; ++j) { /* Computing MIN */ i__3 = j + 1; i__2 = MIN (i__3, *m); for (i__ = 1; i__ <= i__2; ++i__) { a_ref (i__, j) = a_ref (i__, j) * mul; /* L80: */ } /* L90: */ } } else if (itype == 4) { /* Lower half of a symmetric band matrix */ k3 = *kl + 1; k4 = *n + 1; i__1 = *n; for (j = 1; j <= i__1; ++j) { /* Computing MIN */ i__3 = k3, i__4 = k4 - j; i__2 = MIN (i__3, i__4); for (i__ = 1; i__ <= i__2; ++i__) { a_ref (i__, j) = a_ref (i__, j) * mul; /* L100: */ } /* L110: */ } } else if (itype == 5) { /* Upper half of a symmetric band matrix */ k1 = *ku + 2; k3 = *ku + 1; i__1 = *n; for (j = 1; j <= i__1; ++j) { /* Computing MAX */ i__2 = k1 - j; i__3 = k3; for (i__ = MAX (i__2, 1); i__ <= i__3; ++i__) { a_ref (i__, j) = a_ref (i__, j) * mul; /* L120: */ } /* L130: */ } } else if (itype == 6) { /* Band matrix */ k1 = *kl + *ku + 2; k2 = *kl + 1; k3 = (*kl << 1) + *ku + 1; k4 = *kl + *ku + 1 + *m; i__1 = *n; for (j = 1; j <= i__1; ++j) { /* Computing MAX */ i__3 = k1 - j; /* Computing MIN */ i__4 = k3, i__5 = k4 - j; i__2 = MIN (i__4, i__5); for (i__ = MAX (i__3, k2); i__ <= i__2; ++i__) { a_ref (i__, j) = a_ref (i__, j) * mul; /* L140: */ } /* L150: */ } } if (!done) { goto L10; } return 0; } /* NUMlapack_dlascl */ int NUMlapack_dlaset (const char *uplo, long *m, long *n, double *alpha, double *beta, double *a, long *lda) { /* System generated locals */ long a_dim1, a_offset, i__1, i__2, i__3; /* Local variables */ static long i__, j; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; /* Function Body */ if (lsame_ (uplo, "U")) { /* Set the strictly upper triangular or trapezoidal part of the array to ALPHA. */ i__1 = *n; for (j = 2; j <= i__1; ++j) { /* Computing MIN */ i__3 = j - 1; i__2 = MIN (i__3, *m); for (i__ = 1; i__ <= i__2; ++i__) { a_ref (i__, j) = *alpha; /* L10: */ } /* L20: */ } } else if (lsame_ (uplo, "L")) { /* Set the strictly lower triangular or trapezoidal part of the array to ALPHA. */ i__1 = MIN (*m, *n); for (j = 1; j <= i__1; ++j) { i__2 = *m; for (i__ = j + 1; i__ <= i__2; ++i__) { a_ref (i__, j) = *alpha; /* L30: */ } /* L40: */ } } else { /* Set the leading m-by-n submatrix to ALPHA. */ i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { a_ref (i__, j) = *alpha; /* L50: */ } /* L60: */ } } /* Set the first MIN(M,N) diagonal elements to BETA. */ i__1 = MIN (*m, *n); for (i__ = 1; i__ <= i__1; ++i__) { a_ref (i__, i__) = *beta; /* L70: */ } return 0; } /* NUMlapack_dlaset */ int NUMlapack_dlasq1 (long *n, double *d__, double *e, double *work, long *info) { /* System generated locals */ long i__1, i__2; double d__1, d__2, d__3; /* Local variables */ static long i__; static double scale; static long iinfo; static double sigmn; static double sigmx; static double safmin; static double eps; /* Parameter adjustments */ --work; --e; --d__; /* Function Body */ *info = 0; if (*n < 0) { *info = -2; i__1 = - (*info); xerbla_ ("DLASQ1", &i__1); return 0; } else if (*n == 0) { return 0; } else if (*n == 1) { d__[1] = fabs (d__[1]); return 0; } else if (*n == 2) { NUMlapack_dlas2 (&d__[1], &e[1], &d__[2], &sigmn, &sigmx); d__[1] = sigmx; d__[2] = sigmn; return 0; } /* Estimate the largest singular value. */ sigmx = 0.; i__1 = *n - 1; for (i__ = 1; i__ <= i__1; ++i__) { d__[i__] = (d__1 = d__[i__], fabs (d__1)); /* Computing MAX */ d__2 = sigmx, d__3 = (d__1 = e[i__], fabs (d__1)); sigmx = MAX (d__2, d__3); /* L10: */ } d__[*n] = (d__1 = d__[*n], fabs (d__1)); /* Early return if SIGMX is zero (matrix is already diagonal). */ if (sigmx == 0.) { NUMlapack_dlasrt ("D", n, &d__[1], &iinfo); return 0; } i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { /* Computing MAX */ d__1 = sigmx, d__2 = d__[i__]; sigmx = MAX (d__1, d__2); /* L20: */ } /* Copy D and E into WORK (in the Z format) and scale (squaring the input data makes scaling by a power of the radix pointless). */ eps = NUMblas_dlamch ("Precision"); safmin = NUMblas_dlamch ("Safe minimum"); scale = sqrt (eps / safmin); NUMblas_dcopy (n, &d__[1], &c__1, &work[1], &c__2); i__1 = *n - 1; NUMblas_dcopy (&i__1, &e[1], &c__1, &work[2], &c__2); i__1 = (*n << 1) - 1; i__2 = (*n << 1) - 1; NUMlapack_dlascl ("G", &c__0, &c__0, &sigmx, &scale, &i__1, &c__1, &work[1], &i__2, &iinfo); /* Compute the q's and e's. */ i__1 = (*n << 1) - 1; for (i__ = 1; i__ <= i__1; ++i__) { /* Computing 2nd power */ d__1 = work[i__]; work[i__] = d__1 * d__1; /* L30: */ } work[*n * 2] = 0.; NUMlapack_dlasq2 (n, &work[1], info); if (*info == 0) { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { d__[i__] = sqrt (work[i__]); /* L40: */ } NUMlapack_dlascl ("G", &c__0, &c__0, &scale, &sigmx, n, &c__1, &d__[1], n, &iinfo); } return 0; } /* NUMlapack_dlasq1 */ int NUMlapack_dlasq2 (long *n, double *z__, long *info) { /* System generated locals */ long i__1, i__2, i__3; double d__1, d__2; /* Local variables */ static long ieee; static long nbig; static double dmin__, emin, emax; static long ndiv, iter; static double qmin, temp, qmax, zmax; static long splt; static double d__, e; static long k; static double s, t; static long nfail; static double desig, trace, sigma; static long iinfo, i0, i4, n0; static long pp, iwhila, iwhilb; static double oldemn, safmin; static double eps, tol; static long ipn4; static double tol2; /* Parameter adjustments */ --z__; /* Function Body */ *info = 0; eps = NUMblas_dlamch ("Precision"); safmin = NUMblas_dlamch ("Safe minimum"); tol = eps * 100.; /* Computing 2nd power */ d__1 = tol; tol2 = d__1 * d__1; if (*n < 0) { *info = -1; xerbla_ ("DLASQ2", &c__1); return 0; } else if (*n == 0) { return 0; } else if (*n == 1) { /* 1-by-1 case. */ if (z__[1] < 0.) { *info = -201; xerbla_ ("DLASQ2", &c__2); } return 0; } else if (*n == 2) { /* 2-by-2 case. */ if (z__[2] < 0. || z__[3] < 0.) { *info = -2; xerbla_ ("DLASQ2", &c__2); return 0; } else if (z__[3] > z__[1]) { d__ = z__[3]; z__[3] = z__[1]; z__[1] = d__; } z__[5] = z__[1] + z__[2] + z__[3]; if (z__[2] > z__[3] * tol2) { t = (z__[1] - z__[3] + z__[2]) * .5; s = z__[3] * (z__[2] / t); if (s <= t) { s = z__[3] * (z__[2] / (t * (sqrt (s / t + 1.) + 1.))); } else { s = z__[3] * (z__[2] / (t + sqrt (t) * sqrt (t + s))); } t = z__[1] + (s + z__[2]); z__[3] *= z__[1] / t; z__[1] = t; } z__[2] = z__[3]; z__[6] = z__[2] + z__[1]; return 0; } /* Check for negative data and compute sums of q's and e's. */ z__[*n * 2] = 0.; emin = z__[2]; qmax = 0.; zmax = 0.; d__ = 0.; e = 0.; i__1 = *n - 1 << 1; for (k = 1; k <= i__1; k += 2) { if (z__[k] < 0.) { *info = - (k + 200); xerbla_ ("DLASQ2", &c__2); return 0; } else if (z__[k + 1] < 0.) { *info = - (k + 201); xerbla_ ("DLASQ2", &c__2); return 0; } d__ += z__[k]; e += z__[k + 1]; /* Computing MAX */ d__1 = qmax, d__2 = z__[k]; qmax = MAX (d__1, d__2); /* Computing MIN */ d__1 = emin, d__2 = z__[k + 1]; emin = MIN (d__1, d__2); /* Computing MAX */ d__1 = MAX (qmax, zmax), d__2 = z__[k + 1]; zmax = MAX (d__1, d__2); /* L10: */ } if (z__[ (*n << 1) - 1] < 0.) { *info = - ( (*n << 1) + 199); xerbla_ ("DLASQ2", &c__2); return 0; } d__ += z__[ (*n << 1) - 1]; /* Computing MAX */ d__1 = qmax, d__2 = z__[ (*n << 1) - 1]; qmax = MAX (d__1, d__2); zmax = MAX (qmax, zmax); /* Check for diagonality. */ if (e == 0.) { i__1 = *n; for (k = 2; k <= i__1; ++k) { z__[k] = z__[ (k << 1) - 1]; /* L20: */ } NUMlapack_dlasrt ("D", n, &z__[1], &iinfo); z__[ (*n << 1) - 1] = d__; return 0; } trace = d__ + e; /* Check for zero data. */ if (trace == 0.) { z__[ (*n << 1) - 1] = 0.; return 0; } /* Check whether the machine is IEEE conformable. */ ieee = NUMlapack_ilaenv (&c__10, "DLASQ2", "N", &c__1, &c__2, &c__3, &c__4, 6, 1) == 1 && NUMlapack_ilaenv (&c__11, "DLASQ2", "N", &c__1, &c__2, &c__3, &c__4, 6, 1) == 1; /* Rearrange data for locality: Z=(q1,qq1,e1,ee1,q2,qq2,e2,ee2,...). */ for (k = *n << 1; k >= 2; k += -2) { z__[k * 2] = 0.; z__[ (k << 1) - 1] = z__[k]; z__[ (k << 1) - 2] = 0.; z__[ (k << 1) - 3] = z__[k - 1]; /* L30: */ } i0 = 1; n0 = *n; /* Reverse the qd-array, if warranted. */ if (z__[ (i0 << 2) - 3] * 1.5 < z__[ (n0 << 2) - 3]) { ipn4 = i0 + n0 << 2; i__1 = i0 + n0 - 1 << 1; for (i4 = i0 << 2; i4 <= i__1; i4 += 4) { temp = z__[i4 - 3]; z__[i4 - 3] = z__[ipn4 - i4 - 3]; z__[ipn4 - i4 - 3] = temp; temp = z__[i4 - 1]; z__[i4 - 1] = z__[ipn4 - i4 - 5]; z__[ipn4 - i4 - 5] = temp; /* L40: */ } } /* Initial split checking via dqd and Li's test. */ pp = 0; for (k = 1; k <= 2; ++k) { d__ = z__[ (n0 << 2) + pp - 3]; i__1 = (i0 << 2) + pp; for (i4 = (n0 - 1 << 2) + pp; i4 >= i__1; i4 += -4) { if (z__[i4 - 1] <= tol2 * d__) { z__[i4 - 1] = 0.; d__ = z__[i4 - 3]; } else { d__ = z__[i4 - 3] * (d__ / (d__ + z__[i4 - 1])); } /* L50: */ } /* dqd maps Z to ZZ plus Li's test. */ emin = z__[ (i0 << 2) + pp + 1]; d__ = z__[ (i0 << 2) + pp - 3]; i__1 = (n0 - 1 << 2) + pp; for (i4 = (i0 << 2) + pp; i4 <= i__1; i4 += 4) { z__[i4 - (pp << 1) - 2] = d__ + z__[i4 - 1]; if (z__[i4 - 1] <= tol2 * d__) { z__[i4 - 1] = 0.; z__[i4 - (pp << 1) - 2] = d__; z__[i4 - (pp << 1)] = 0.; d__ = z__[i4 + 1]; } else if (safmin * z__[i4 + 1] < z__[i4 - (pp << 1) - 2] && safmin * z__[i4 - (pp << 1) - 2] < z__[i4 + 1]) { temp = z__[i4 + 1] / z__[i4 - (pp << 1) - 2]; z__[i4 - (pp << 1)] = z__[i4 - 1] * temp; d__ *= temp; } else { z__[i4 - (pp << 1)] = z__[i4 + 1] * (z__[i4 - 1] / z__[i4 - (pp << 1) - 2]); d__ = z__[i4 + 1] * (d__ / z__[i4 - (pp << 1) - 2]); } /* Computing MIN */ d__1 = emin, d__2 = z__[i4 - (pp << 1)]; emin = MIN (d__1, d__2); /* L60: */ } z__[ (n0 << 2) - pp - 2] = d__; /* Now find qmax. */ qmax = z__[ (i0 << 2) - pp - 2]; i__1 = (n0 << 2) - pp - 2; for (i4 = (i0 << 2) - pp + 2; i4 <= i__1; i4 += 4) { /* Computing MAX */ d__1 = qmax, d__2 = z__[i4]; qmax = MAX (d__1, d__2); /* L70: */ } /* Prepare for the next iteration on K. */ pp = 1 - pp; /* L80: */ } iter = 2; nfail = 0; ndiv = n0 - i0 << 1; i__1 = *n + 1; for (iwhila = 1; iwhila <= i__1; ++iwhila) { if (n0 < 1) { goto L150; } /* While array unfinished do E(N0) holds the value of SIGMA when submatrix in I0:N0 splits from the rest of the array, but is negated. */ desig = 0.; if (n0 == *n) { sigma = 0.; } else { sigma = -z__[ (n0 << 2) - 1]; } if (sigma < 0.) { *info = 1; return 0; } /* Find last unreduced submatrix's top index I0, find QMAX and EMIN. Find Gershgorin-type bound if Q's much greater than E's. */ emax = 0.; if (n0 > i0) { emin = (d__1 = z__[ (n0 << 2) - 5], fabs (d__1)); } else { emin = 0.; } qmin = z__[ (n0 << 2) - 3]; qmax = qmin; for (i4 = n0 << 2; i4 >= 8; i4 += -4) { if (z__[i4 - 5] <= 0.) { goto L100; } if (qmin >= emax * 4.) { /* Computing MIN */ d__1 = qmin, d__2 = z__[i4 - 3]; qmin = MIN (d__1, d__2); /* Computing MAX */ d__1 = emax, d__2 = z__[i4 - 5]; emax = MAX (d__1, d__2); } /* Computing MAX */ d__1 = qmax, d__2 = z__[i4 - 7] + z__[i4 - 5]; qmax = MAX (d__1, d__2); /* Computing MIN */ d__1 = emin, d__2 = z__[i4 - 5]; emin = MIN (d__1, d__2); /* L90: */ } i4 = 4; L100: i0 = i4 / 4; /* Store EMIN for passing to DLASQ3. */ z__[ (n0 << 2) - 1] = emin; /* Put -(initial shift) into DMIN. Computing MAX */ d__1 = 0., d__2 = qmin - sqrt (qmin) * 2. * sqrt (emax); dmin__ = -MAX (d__1, d__2); /* Now I0:N0 is unreduced. PP = 0 for ping, PP = 1 for pong. */ pp = 0; nbig = (n0 - i0 + 1) * 30; i__2 = nbig; for (iwhilb = 1; iwhilb <= i__2; ++iwhilb) { if (i0 > n0) { goto L130; } /* While submatrix unfinished take a good dqds step. */ NUMlapack_dlasq3 (&i0, &n0, &z__[1], &pp, &dmin__, &sigma, &desig, &qmax, &nfail, &iter, &ndiv, &ieee); pp = 1 - pp; /* When EMIN is very small check for splits. */ if (pp == 0 && n0 - i0 >= 3) { if (z__[n0 * 4] <= tol2 * qmax || z__[ (n0 << 2) - 1] <= tol2 * sigma) { splt = i0 - 1; qmax = z__[ (i0 << 2) - 3]; emin = z__[ (i0 << 2) - 1]; oldemn = z__[i0 * 4]; i__3 = n0 - 3 << 2; for (i4 = i0 << 2; i4 <= i__3; i4 += 4) { if (z__[i4] <= tol2 * z__[i4 - 3] || z__[i4 - 1] <= tol2 * sigma) { z__[i4 - 1] = -sigma; splt = i4 / 4; qmax = 0.; emin = z__[i4 + 3]; oldemn = z__[i4 + 4]; } else { /* Computing MAX */ d__1 = qmax, d__2 = z__[i4 + 1]; qmax = MAX (d__1, d__2); /* Computing MIN */ d__1 = emin, d__2 = z__[i4 - 1]; emin = MIN (d__1, d__2); /* Computing MIN */ d__1 = oldemn, d__2 = z__[i4]; oldemn = MIN (d__1, d__2); } /* L110: */ } z__[ (n0 << 2) - 1] = emin; z__[n0 * 4] = oldemn; i0 = splt + 1; } } /* L120: */ } *info = 2; return 0; /* end IWHILB */ L130: /* L140: */ ; } *info = 3; return 0; /* end IWHILA */ L150: /* Move q's to the front. */ i__1 = *n; for (k = 2; k <= i__1; ++k) { z__[k] = z__[ (k << 2) - 3]; /* L160: */ } /* Sort and compute sum of eigenvalues. */ NUMlapack_dlasrt ("D", n, &z__[1], &iinfo); e = 0.; for (k = *n; k >= 1; --k) { e += z__[k]; /* L170: */ } /* Store trace, sum(eigenvalues) and information on performance. */ z__[ (*n << 1) + 1] = trace; z__[ (*n << 1) + 2] = e; z__[ (*n << 1) + 3] = (double) iter; /* Computing 2nd power */ i__1 = *n; z__[ (*n << 1) + 4] = (double) ndiv / (double) (i__1 * i__1); z__[ (*n << 1) + 5] = nfail * 100. / (double) iter; return 0; } /* NUMlapack_dlasq2 */ int NUMlapack_dlasq3 (long *i0, long *n0, double *z__, long *pp, double *dmin__, double *sigma, double *desig, double *qmax, long *nfail, long *iter, long *ndiv, long *ieee) { /* Initialized data */ static long ttype = 0; static double dmin1 = 0.; static double dmin2 = 0.; static double dn = 0.; static double dn1 = 0.; static double dn2 = 0.; static double tau = 0.; /* System generated locals */ long i__1; double d__1, d__2; /* Local variables */ static double temp, s, t; static long j4; static long nn; static double safmin, eps, tol; static long n0in, ipn4; static double tol2; --z__; /* Function Body */ n0in = *n0; eps = NUMblas_dlamch ("Precision"); safmin = NUMblas_dlamch ("Safe minimum"); tol = eps * 100.; /* Computing 2nd power */ d__1 = tol; tol2 = d__1 * d__1; /* Check for deflation. */ L10: if (*n0 < *i0) { return 0; } if (*n0 == *i0) { goto L20; } nn = (*n0 << 2) + *pp; if (*n0 == *i0 + 1) { goto L40; } /* Check whether E(N0-1) is negligible, 1 eigenvalue. */ if (z__[nn - 5] > tol2 * (*sigma + z__[nn - 3]) && z__[nn - (*pp << 1) - 4] > tol2 * z__[nn - 7]) { goto L30; } L20: z__[ (*n0 << 2) - 3] = z__[ (*n0 << 2) + *pp - 3] + *sigma; -- (*n0); goto L10; /* Check whether E(N0-2) is negligible, 2 eigenvalues. */ L30: if (z__[nn - 9] > tol2 * *sigma && z__[nn - (*pp << 1) - 8] > tol2 * z__[nn - 11]) { goto L50; } L40: if (z__[nn - 3] > z__[nn - 7]) { s = z__[nn - 3]; z__[nn - 3] = z__[nn - 7]; z__[nn - 7] = s; } if (z__[nn - 5] > z__[nn - 3] * tol2) { t = (z__[nn - 7] - z__[nn - 3] + z__[nn - 5]) * .5; s = z__[nn - 3] * (z__[nn - 5] / t); if (s <= t) { s = z__[nn - 3] * (z__[nn - 5] / (t * (sqrt (s / t + 1.) + 1.))); } else { s = z__[nn - 3] * (z__[nn - 5] / (t + sqrt (t) * sqrt (t + s))); } t = z__[nn - 7] + (s + z__[nn - 5]); z__[nn - 3] *= z__[nn - 7] / t; z__[nn - 7] = t; } z__[ (*n0 << 2) - 7] = z__[nn - 7] + *sigma; z__[ (*n0 << 2) - 3] = z__[nn - 3] + *sigma; *n0 += -2; goto L10; L50: /* Reverse the qd-array, if warranted. */ if (*dmin__ <= 0. || *n0 < n0in) { if (z__[ (*i0 << 2) + *pp - 3] * 1.5 < z__[ (*n0 << 2) + *pp - 3]) { ipn4 = *i0 + *n0 << 2; i__1 = *i0 + *n0 - 1 << 1; for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) { temp = z__[j4 - 3]; z__[j4 - 3] = z__[ipn4 - j4 - 3]; z__[ipn4 - j4 - 3] = temp; temp = z__[j4 - 2]; z__[j4 - 2] = z__[ipn4 - j4 - 2]; z__[ipn4 - j4 - 2] = temp; temp = z__[j4 - 1]; z__[j4 - 1] = z__[ipn4 - j4 - 5]; z__[ipn4 - j4 - 5] = temp; temp = z__[j4]; z__[j4] = z__[ipn4 - j4 - 4]; z__[ipn4 - j4 - 4] = temp; /* L60: */ } if (*n0 - *i0 <= 4) { z__[ (*n0 << 2) + *pp - 1] = z__[ (*i0 << 2) + *pp - 1]; z__[ (*n0 << 2) - *pp] = z__[ (*i0 << 2) - *pp]; } /* Computing MIN */ d__1 = dmin2, d__2 = z__[ (*n0 << 2) + *pp - 1]; dmin2 = MIN (d__1, d__2); /* Computing MIN */ d__1 = z__[ (*n0 << 2) + *pp - 1], d__2 = z__[ (*i0 << 2) + *pp - 1], d__1 = MIN (d__1, d__2), d__2 = z__[ (*i0 << 2) + *pp + 3]; z__[ (*n0 << 2) + *pp - 1] = MIN (d__1, d__2); /* Computing MIN */ d__1 = z__[ (*n0 << 2) - *pp], d__2 = z__[ (*i0 << 2) - *pp], d__1 = MIN (d__1, d__2), d__2 = z__[ (*i0 << 2) - *pp + 4]; z__[ (*n0 << 2) - *pp] = MIN (d__1, d__2); /* Computing MAX */ d__1 = *qmax, d__2 = z__[ (*i0 << 2) + *pp - 3], d__1 = MAX (d__1, d__2), d__2 = z__[ (*i0 << 2) + *pp + 1]; *qmax = MAX (d__1, d__2); *dmin__ = 0.; } } /* L70: Computing MIN */ d__1 = z__[ (*n0 << 2) + *pp - 1], d__2 = z__[ (*n0 << 2) + *pp - 9], d__1 = MIN (d__1, d__2), d__2 = dmin2 + z__[ (*n0 << 2) - *pp]; if (*dmin__ < 0. || safmin * *qmax < MIN (d__1, d__2)) { /* Choose a shift. */ NUMlapack_dlasq4 (i0, n0, &z__[1], pp, &n0in, dmin__, &dmin1, &dmin2, &dn, &dn1, &dn2, &tau, &ttype); /* Call dqds until DMIN > 0. */ L80: NUMlapack_dlasq5 (i0, n0, &z__[1], pp, &tau, dmin__, &dmin1, &dmin2, &dn, &dn1, &dn2, ieee); *ndiv += *n0 - *i0 + 2; ++ (*iter); /* Check status. */ if (*dmin__ >= 0. && dmin1 > 0.) { /* Success. */ goto L100; } else if (*dmin__ < 0. && dmin1 > 0. && z__[ (*n0 - 1 << 2) - *pp] < tol * (*sigma + dn1) && fabs (dn) < tol * *sigma) { /* Convergence hidden by negative DN. */ z__[ (*n0 - 1 << 2) - *pp + 2] = 0.; *dmin__ = 0.; goto L100; } else if (*dmin__ < 0.) { /* TAU too big. Select new TAU and try again. */ ++ (*nfail); if (ttype < -22) { /* Failed twice. Play it safe. */ tau = 0.; } else if (dmin1 > 0.) { /* Late failure. Gives excellent shift. */ tau = (tau + *dmin__) * (1. - eps * 2.); ttype += -11; } else { /* Early failure. Divide by 4. */ tau *= .25; ttype += -12; } goto L80; } else if (*dmin__ != *dmin__) { /* NaN. */ tau = 0.; goto L80; } else { /* Possible underflow. Play it safe. */ goto L90; } } /* Risk of underflow. */ L90: NUMlapack_dlasq6 (i0, n0, &z__[1], pp, dmin__, &dmin1, &dmin2, &dn, &dn1, &dn2); *ndiv += *n0 - *i0 + 2; ++ (*iter); tau = 0.; L100: if (tau < *sigma) { *desig += tau; t = *sigma + *desig; *desig -= t - *sigma; } else { t = *sigma + tau; *desig = *sigma - (t - tau) + *desig; } *sigma = t; return 0; } /* NUMlapack_dlasq3 */ int NUMlapack_dlasq4 (long *i0, long *n0, double *z__, long *pp, long *n0in, double *dmin__, double *dmin1, double *dmin2, double *dn, double *dn1, double *dn2, double *tau, long *ttype) { /* Initialized data */ static double g = 0.; /* System generated locals */ long i__1; double d__1, d__2; /* Local variables */ static double s, a2, b1, b2; static long i4, nn, np; static double gam, gap1, gap2; /* Parameter adjustments */ --z__; /* Function Body A negative DMIN forces the shift to take that absolute value TTYPE records the type of shift. */ if (*dmin__ <= 0.) { *tau = - (*dmin__); *ttype = -1; return 0; } nn = (*n0 << 2) + *pp; if (*n0in == *n0) { /* No eigenvalues deflated. */ if (*dmin__ == *dn || *dmin__ == *dn1) { b1 = sqrt (z__[nn - 3]) * sqrt (z__[nn - 5]); b2 = sqrt (z__[nn - 7]) * sqrt (z__[nn - 9]); a2 = z__[nn - 7] + z__[nn - 5]; /* Cases 2 and 3. */ if (*dmin__ == *dn && *dmin1 == *dn1) { gap2 = *dmin2 - a2 - *dmin2 * .25; if (gap2 > 0. && gap2 > b2) { gap1 = a2 - *dn - b2 / gap2 * b2; } else { gap1 = a2 - *dn - (b1 + b2); } if (gap1 > 0. && gap1 > b1) { /* Computing MAX */ d__1 = *dn - b1 / gap1 * b1, d__2 = *dmin__ * .5; s = MAX (d__1, d__2); *ttype = -2; } else { s = 0.; if (*dn > b1) { s = *dn - b1; } if (a2 > b1 + b2) { /* Computing MIN */ d__1 = s, d__2 = a2 - (b1 + b2); s = MIN (d__1, d__2); } /* Computing MAX */ d__1 = s, d__2 = *dmin__ * .333; s = MAX (d__1, d__2); *ttype = -3; } } else { /* Case 4. */ *ttype = -4; s = *dmin__ * .25; if (*dmin__ == *dn) { gam = *dn; a2 = 0.; if (z__[nn - 5] > z__[nn - 7]) { return 0; } b2 = z__[nn - 5] / z__[nn - 7]; np = nn - 9; } else { np = nn - (*pp << 1); b2 = z__[np - 2]; gam = *dn1; if (z__[np - 4] > z__[np - 2]) { return 0; } a2 = z__[np - 4] / z__[np - 2]; if (z__[nn - 9] > z__[nn - 11]) { return 0; } b2 = z__[nn - 9] / z__[nn - 11]; np = nn - 13; } /* Approximate contribution to norm squared from I < NN-1. */ a2 += b2; i__1 = (*i0 << 2) - 1 + *pp; for (i4 = np; i4 >= i__1; i4 += -4) { if (b2 == 0.) { goto L20; } b1 = b2; if (z__[i4] > z__[i4 - 2]) { return 0; } b2 *= z__[i4] / z__[i4 - 2]; a2 += b2; if (MAX (b2, b1) * 100. < a2 || .563 < a2) { goto L20; } /* L10: */ } L20: a2 *= 1.05; /* Rayleigh quotient residual bound. */ if (a2 < .563) { s = gam * (1. - sqrt (a2)) / (a2 + 1.); } } } else if (*dmin__ == *dn2) { /* Case 5. */ *ttype = -5; s = *dmin__ * .25; /* Compute contribution to norm squared from I > NN-2. */ np = nn - (*pp << 1); b1 = z__[np - 2]; b2 = z__[np - 6]; gam = *dn2; if (z__[np - 8] > b2 || z__[np - 4] > b1) { return 0; } a2 = z__[np - 8] / b2 * (z__[np - 4] / b1 + 1.); /* Approximate contribution to norm squared from I < NN-2. */ if (*n0 - *i0 > 2) { b2 = z__[nn - 13] / z__[nn - 15]; a2 += b2; i__1 = (*i0 << 2) - 1 + *pp; for (i4 = nn - 17; i4 >= i__1; i4 += -4) { if (b2 == 0.) { goto L40; } b1 = b2; if (z__[i4] > z__[i4 - 2]) { return 0; } b2 *= z__[i4] / z__[i4 - 2]; a2 += b2; if (MAX (b2, b1) * 100. < a2 || .563 < a2) { goto L40; } /* L30: */ } L40: a2 *= 1.05; } if (a2 < .563) { s = gam * (1. - sqrt (a2)) / (a2 + 1.); } } else { /* Case 6, no information to guide us. */ if (*ttype == -6) { g += (1. - g) * .333; } else if (*ttype == -18) { g = .083250000000000005; } else { g = .25; } s = g * *dmin__; *ttype = -6; } } else if (*n0in == *n0 + 1) { /* One eigenvalue just deflated. Use DMIN1, DN1 for DMIN and DN. */ if (*dmin1 == *dn1 && *dmin2 == *dn2) { /* Cases 7 and 8. */ *ttype = -7; s = *dmin1 * .333; if (z__[nn - 5] > z__[nn - 7]) { return 0; } b1 = z__[nn - 5] / z__[nn - 7]; b2 = b1; if (b2 == 0.) { goto L60; } i__1 = (*i0 << 2) - 1 + *pp; for (i4 = (*n0 << 2) - 9 + *pp; i4 >= i__1; i4 += -4) { a2 = b1; if (z__[i4] > z__[i4 - 2]) { return 0; } b1 *= z__[i4] / z__[i4 - 2]; b2 += b1; if (MAX (b1, a2) * 100. < b2) { goto L60; } /* L50: */ } L60: b2 = sqrt (b2 * 1.05); /* Computing 2nd power */ d__1 = b2; a2 = *dmin1 / (d__1 * d__1 + 1.); gap2 = *dmin2 * .5 - a2; if (gap2 > 0. && gap2 > b2 * a2) { /* Computing MAX */ d__1 = s, d__2 = a2 * (1. - a2 * 1.01 * (b2 / gap2) * b2); s = MAX (d__1, d__2); } else { /* Computing MAX */ d__1 = s, d__2 = a2 * (1. - b2 * 1.01); s = MAX (d__1, d__2); *ttype = -8; } } else { /* Case 9. */ s = *dmin1 * .25; if (*dmin1 == *dn1) { s = *dmin1 * .5; } *ttype = -9; } } else if (*n0in == *n0 + 2) { /* Two eigenvalues deflated. Use DMIN2, DN2 for DMIN and DN. Cases 10 and 11. */ if (*dmin2 == *dn2 && z__[nn - 5] * 2. < z__[nn - 7]) { *ttype = -10; s = *dmin2 * .333; if (z__[nn - 5] > z__[nn - 7]) { return 0; } b1 = z__[nn - 5] / z__[nn - 7]; b2 = b1; if (b2 == 0.) { goto L80; } i__1 = (*i0 << 2) - 1 + *pp; for (i4 = (*n0 << 2) - 9 + *pp; i4 >= i__1; i4 += -4) { if (z__[i4] > z__[i4 - 2]) { return 0; } b1 *= z__[i4] / z__[i4 - 2]; b2 += b1; if (b1 * 100. < b2) { goto L80; } /* L70: */ } L80: b2 = sqrt (b2 * 1.05); /* Computing 2nd power */ d__1 = b2; a2 = *dmin2 / (d__1 * d__1 + 1.); gap2 = z__[nn - 7] + z__[nn - 9] - sqrt (z__[nn - 11]) * sqrt (z__[nn - 9]) - a2; if (gap2 > 0. && gap2 > b2 * a2) { /* Computing MAX */ d__1 = s, d__2 = a2 * (1. - a2 * 1.01 * (b2 / gap2) * b2); s = MAX (d__1, d__2); } else { /* Computing MAX */ d__1 = s, d__2 = a2 * (1. - b2 * 1.01); s = MAX (d__1, d__2); } } else { s = *dmin2 * .25; *ttype = -11; } } else if (*n0in > *n0 + 2) { /* Case 12, more than two eigenvalues deflated. No information. */ s = 0.; *ttype = -12; } *tau = s; return 0; } /* NUMlapack_dlasq4 */ int NUMlapack_dlasq5 (long *i0, long *n0, double *z__, long *pp, double *tau, double *dmin__, double *dmin1, double *dmin2, double *dn, double *dnm1, double *dnm2, long *ieee) { /* System generated locals */ long i__1; double d__1, d__2; /* Local variables */ static double emin, temp, d__; static long j4, j4p2; --z__; /* Function Body */ if (*n0 - *i0 - 1 <= 0) { return 0; } j4 = (*i0 << 2) + *pp - 3; emin = z__[j4 + 4]; d__ = z__[j4] - *tau; *dmin__ = d__; *dmin1 = -z__[j4]; if (*ieee) { /* Code for IEEE arithmetic. */ if (*pp == 0) { i__1 = *n0 - 3 << 2; for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) { z__[j4 - 2] = d__ + z__[j4 - 1]; temp = z__[j4 + 1] / z__[j4 - 2]; d__ = d__ * temp - *tau; *dmin__ = MIN (*dmin__, d__); z__[j4] = z__[j4 - 1] * temp; /* Computing MIN */ d__1 = z__[j4]; emin = MIN (d__1, emin); /* L10: */ } } else { i__1 = *n0 - 3 << 2; for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) { z__[j4 - 3] = d__ + z__[j4]; temp = z__[j4 + 2] / z__[j4 - 3]; d__ = d__ * temp - *tau; *dmin__ = MIN (*dmin__, d__); z__[j4 - 1] = z__[j4] * temp; /* Computing MIN */ d__1 = z__[j4 - 1]; emin = MIN (d__1, emin); /* L20: */ } } /* Unroll last two steps. */ *dnm2 = d__; *dmin2 = *dmin__; j4 = (*n0 - 2 << 2) - *pp; j4p2 = j4 + (*pp << 1) - 1; z__[j4 - 2] = *dnm2 + z__[j4p2]; z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]); *dnm1 = z__[j4p2 + 2] * (*dnm2 / z__[j4 - 2]) - *tau; *dmin__ = MIN (*dmin__, *dnm1); *dmin1 = *dmin__; j4 += 4; j4p2 = j4 + (*pp << 1) - 1; z__[j4 - 2] = *dnm1 + z__[j4p2]; z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]); *dn = z__[j4p2 + 2] * (*dnm1 / z__[j4 - 2]) - *tau; *dmin__ = MIN (*dmin__, *dn); } else { /* Code for non IEEE arithmetic. */ if (*pp == 0) { i__1 = *n0 - 3 << 2; for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) { z__[j4 - 2] = d__ + z__[j4 - 1]; if (d__ < 0.) { return 0; } else { z__[j4] = z__[j4 + 1] * (z__[j4 - 1] / z__[j4 - 2]); d__ = z__[j4 + 1] * (d__ / z__[j4 - 2]) - *tau; } *dmin__ = MIN (*dmin__, d__); /* Computing MIN */ d__1 = emin, d__2 = z__[j4]; emin = MIN (d__1, d__2); /* L30: */ } } else { i__1 = *n0 - 3 << 2; for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) { z__[j4 - 3] = d__ + z__[j4]; if (d__ < 0.) { return 0; } else { z__[j4 - 1] = z__[j4 + 2] * (z__[j4] / z__[j4 - 3]); d__ = z__[j4 + 2] * (d__ / z__[j4 - 3]) - *tau; } *dmin__ = MIN (*dmin__, d__); /* Computing MIN */ d__1 = emin, d__2 = z__[j4 - 1]; emin = MIN (d__1, d__2); /* L40: */ } } /* Unroll last two steps. */ *dnm2 = d__; *dmin2 = *dmin__; j4 = (*n0 - 2 << 2) - *pp; j4p2 = j4 + (*pp << 1) - 1; z__[j4 - 2] = *dnm2 + z__[j4p2]; if (*dnm2 < 0.) { return 0; } else { z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]); *dnm1 = z__[j4p2 + 2] * (*dnm2 / z__[j4 - 2]) - *tau; } *dmin__ = MIN (*dmin__, *dnm1); *dmin1 = *dmin__; j4 += 4; j4p2 = j4 + (*pp << 1) - 1; z__[j4 - 2] = *dnm1 + z__[j4p2]; if (*dnm1 < 0.) { return 0; } else { z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]); *dn = z__[j4p2 + 2] * (*dnm1 / z__[j4 - 2]) - *tau; } *dmin__ = MIN (*dmin__, *dn); } z__[j4 + 2] = *dn; z__[ (*n0 << 2) - *pp] = emin; return 0; } /* NUMlapack_dlasq5 */ int NUMlapack_dlasq6 (long *i0, long *n0, double *z__, long *pp, double *dmin__, double *dmin1, double *dmin2, double *dn, double *dnm1, double *dnm2) { /* System generated locals */ long i__1; double d__1, d__2; /* Local variables */ static double emin, temp, d__; static long j4; static double safmin; static long j4p2; /* Parameter adjustments */ --z__; /* Function Body */ if (*n0 - *i0 - 1 <= 0) { return 0; } safmin = NUMblas_dlamch ("Safe minimum"); j4 = (*i0 << 2) + *pp - 3; emin = z__[j4 + 4]; d__ = z__[j4]; *dmin__ = d__; if (*pp == 0) { i__1 = *n0 - 3 << 2; for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) { z__[j4 - 2] = d__ + z__[j4 - 1]; if (z__[j4 - 2] == 0.) { z__[j4] = 0.; d__ = z__[j4 + 1]; *dmin__ = d__; emin = 0.; } else if (safmin * z__[j4 + 1] < z__[j4 - 2] && safmin * z__[j4 - 2] < z__[j4 + 1]) { temp = z__[j4 + 1] / z__[j4 - 2]; z__[j4] = z__[j4 - 1] * temp; d__ *= temp; } else { z__[j4] = z__[j4 + 1] * (z__[j4 - 1] / z__[j4 - 2]); d__ = z__[j4 + 1] * (d__ / z__[j4 - 2]); } *dmin__ = MIN (*dmin__, d__); /* Computing MIN */ d__1 = emin, d__2 = z__[j4]; emin = MIN (d__1, d__2); /* L10: */ } } else { i__1 = *n0 - 3 << 2; for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) { z__[j4 - 3] = d__ + z__[j4]; if (z__[j4 - 3] == 0.) { z__[j4 - 1] = 0.; d__ = z__[j4 + 2]; *dmin__ = d__; emin = 0.; } else if (safmin * z__[j4 + 2] < z__[j4 - 3] && safmin * z__[j4 - 3] < z__[j4 + 2]) { temp = z__[j4 + 2] / z__[j4 - 3]; z__[j4 - 1] = z__[j4] * temp; d__ *= temp; } else { z__[j4 - 1] = z__[j4 + 2] * (z__[j4] / z__[j4 - 3]); d__ = z__[j4 + 2] * (d__ / z__[j4 - 3]); } *dmin__ = MIN (*dmin__, d__); /* Computing MIN */ d__1 = emin, d__2 = z__[j4 - 1]; emin = MIN (d__1, d__2); /* L20: */ } } /* Unroll last two steps. */ *dnm2 = d__; *dmin2 = *dmin__; j4 = (*n0 - 2 << 2) - *pp; j4p2 = j4 + (*pp << 1) - 1; z__[j4 - 2] = *dnm2 + z__[j4p2]; if (z__[j4 - 2] == 0.) { z__[j4] = 0.; *dnm1 = z__[j4p2 + 2]; *dmin__ = *dnm1; emin = 0.; } else if (safmin * z__[j4p2 + 2] < z__[j4 - 2] && safmin * z__[j4 - 2] < z__[j4p2 + 2]) { temp = z__[j4p2 + 2] / z__[j4 - 2]; z__[j4] = z__[j4p2] * temp; *dnm1 = *dnm2 * temp; } else { z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]); *dnm1 = z__[j4p2 + 2] * (*dnm2 / z__[j4 - 2]); } *dmin__ = MIN (*dmin__, *dnm1); *dmin1 = *dmin__; j4 += 4; j4p2 = j4 + (*pp << 1) - 1; z__[j4 - 2] = *dnm1 + z__[j4p2]; if (z__[j4 - 2] == 0.) { z__[j4] = 0.; *dn = z__[j4p2 + 2]; *dmin__ = *dn; emin = 0.; } else if (safmin * z__[j4p2 + 2] < z__[j4 - 2] && safmin * z__[j4 - 2] < z__[j4p2 + 2]) { temp = z__[j4p2 + 2] / z__[j4 - 2]; z__[j4] = z__[j4p2] * temp; *dn = *dnm1 * temp; } else { z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]); *dn = z__[j4p2 + 2] * (*dnm1 / z__[j4 - 2]); } *dmin__ = MIN (*dmin__, *dn); z__[j4 + 2] = *dn; z__[ (*n0 << 2) - *pp] = emin; return 0; } /* NUMlapack_dlasq6 */ int NUMlapack_dlasr (const char *side, const char *pivot, const char *direct, long *m, long *n, double *c__, double *s, double *a, long *lda) { /* System generated locals */ long a_dim1, a_offset, i__1, i__2; /* Local variables */ static long info; static double temp; static long i__, j; static double ctemp, stemp; --c__; --s; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; /* Function Body */ info = 0; if (! (lsame_ (side, "L") || lsame_ (side, "R"))) { info = 1; } else if (! (lsame_ (pivot, "V") || lsame_ (pivot, "T") || lsame_ (pivot, "B"))) { info = 2; } else if (! (lsame_ (direct, "F") || lsame_ (direct, "B"))) { info = 3; } else if (*m < 0) { info = 4; } else if (*n < 0) { info = 5; } else if (*lda < MAX (1, *m)) { info = 9; } if (info != 0) { xerbla_ ("DLASR ", &info); return 0; } /* Quick return if possible */ if (*m == 0 || *n == 0) { return 0; } if (lsame_ (side, "L")) { /* Form P * A */ if (lsame_ (pivot, "V")) { if (lsame_ (direct, "F")) { i__1 = *m - 1; for (j = 1; j <= i__1; ++j) { ctemp = c__[j]; stemp = s[j]; if (ctemp != 1. || stemp != 0.) { i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { temp = a_ref (j + 1, i__); a_ref (j + 1, i__) = ctemp * temp - stemp * a_ref (j, i__); a_ref (j, i__) = stemp * temp + ctemp * a_ref (j, i__); /* L10: */ } } /* L20: */ } } else if (lsame_ (direct, "B")) { for (j = *m - 1; j >= 1; --j) { ctemp = c__[j]; stemp = s[j]; if (ctemp != 1. || stemp != 0.) { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { temp = a_ref (j + 1, i__); a_ref (j + 1, i__) = ctemp * temp - stemp * a_ref (j, i__); a_ref (j, i__) = stemp * temp + ctemp * a_ref (j, i__); /* L30: */ } } /* L40: */ } } } else if (lsame_ (pivot, "T")) { if (lsame_ (direct, "F")) { i__1 = *m; for (j = 2; j <= i__1; ++j) { ctemp = c__[j - 1]; stemp = s[j - 1]; if (ctemp != 1. || stemp != 0.) { i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { temp = a_ref (j, i__); a_ref (j, i__) = ctemp * temp - stemp * a_ref (1, i__); a_ref (1, i__) = stemp * temp + ctemp * a_ref (1, i__); /* L50: */ } } /* L60: */ } } else if (lsame_ (direct, "B")) { for (j = *m; j >= 2; --j) { ctemp = c__[j - 1]; stemp = s[j - 1]; if (ctemp != 1. || stemp != 0.) { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { temp = a_ref (j, i__); a_ref (j, i__) = ctemp * temp - stemp * a_ref (1, i__); a_ref (1, i__) = stemp * temp + ctemp * a_ref (1, i__); /* L70: */ } } /* L80: */ } } } else if (lsame_ (pivot, "B")) { if (lsame_ (direct, "F")) { i__1 = *m - 1; for (j = 1; j <= i__1; ++j) { ctemp = c__[j]; stemp = s[j]; if (ctemp != 1. || stemp != 0.) { i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { temp = a_ref (j, i__); a_ref (j, i__) = stemp * a_ref (*m, i__) + ctemp * temp; a_ref (*m, i__) = ctemp * a_ref (*m, i__) - stemp * temp; /* L90: */ } } /* L100: */ } } else if (lsame_ (direct, "B")) { for (j = *m - 1; j >= 1; --j) { ctemp = c__[j]; stemp = s[j]; if (ctemp != 1. || stemp != 0.) { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { temp = a_ref (j, i__); a_ref (j, i__) = stemp * a_ref (*m, i__) + ctemp * temp; a_ref (*m, i__) = ctemp * a_ref (*m, i__) - stemp * temp; /* L110: */ } } /* L120: */ } } } } else if (lsame_ (side, "R")) { /* Form A * P' */ if (lsame_ (pivot, "V")) { if (lsame_ (direct, "F")) { i__1 = *n - 1; for (j = 1; j <= i__1; ++j) { ctemp = c__[j]; stemp = s[j]; if (ctemp != 1. || stemp != 0.) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { temp = a_ref (i__, j + 1); a_ref (i__, j + 1) = ctemp * temp - stemp * a_ref (i__, j); a_ref (i__, j) = stemp * temp + ctemp * a_ref (i__, j); /* L130: */ } } /* L140: */ } } else if (lsame_ (direct, "B")) { for (j = *n - 1; j >= 1; --j) { ctemp = c__[j]; stemp = s[j]; if (ctemp != 1. || stemp != 0.) { i__1 = *m; for (i__ = 1; i__ <= i__1; ++i__) { temp = a_ref (i__, j + 1); a_ref (i__, j + 1) = ctemp * temp - stemp * a_ref (i__, j); a_ref (i__, j) = stemp * temp + ctemp * a_ref (i__, j); /* L150: */ } } /* L160: */ } } } else if (lsame_ (pivot, "T")) { if (lsame_ (direct, "F")) { i__1 = *n; for (j = 2; j <= i__1; ++j) { ctemp = c__[j - 1]; stemp = s[j - 1]; if (ctemp != 1. || stemp != 0.) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { temp = a_ref (i__, j); a_ref (i__, j) = ctemp * temp - stemp * a_ref (i__, 1); a_ref (i__, 1) = stemp * temp + ctemp * a_ref (i__, 1); /* L170: */ } } /* L180: */ } } else if (lsame_ (direct, "B")) { for (j = *n; j >= 2; --j) { ctemp = c__[j - 1]; stemp = s[j - 1]; if (ctemp != 1. || stemp != 0.) { i__1 = *m; for (i__ = 1; i__ <= i__1; ++i__) { temp = a_ref (i__, j); a_ref (i__, j) = ctemp * temp - stemp * a_ref (i__, 1); a_ref (i__, 1) = stemp * temp + ctemp * a_ref (i__, 1); /* L190: */ } } /* L200: */ } } } else if (lsame_ (pivot, "B")) { if (lsame_ (direct, "F")) { i__1 = *n - 1; for (j = 1; j <= i__1; ++j) { ctemp = c__[j]; stemp = s[j]; if (ctemp != 1. || stemp != 0.) { i__2 = *m; for (i__ = 1; i__ <= i__2; ++i__) { temp = a_ref (i__, j); a_ref (i__, j) = stemp * a_ref (i__, *n) + ctemp * temp; a_ref (i__, *n) = ctemp * a_ref (i__, *n) - stemp * temp; /* L210: */ } } /* L220: */ } } else if (lsame_ (direct, "B")) { for (j = *n - 1; j >= 1; --j) { ctemp = c__[j]; stemp = s[j]; if (ctemp != 1. || stemp != 0.) { i__1 = *m; for (i__ = 1; i__ <= i__1; ++i__) { temp = a_ref (i__, j); a_ref (i__, j) = stemp * a_ref (i__, *n) + ctemp * temp; a_ref (i__, *n) = ctemp * a_ref (i__, *n) - stemp * temp; /* L230: */ } } /* L240: */ } } } } return 0; } /* NUMlapack_dlasr */ #define stack_ref(a_1,a_2) stack[(a_2)*2 + a_1 - 3] int NUMlapack_dlasrt (const char *id, long *n, double *d__, long *info) { /* System generated locals */ long i__1, i__2; /* Local variables */ static long endd, i__, j; static long stack[64] /* was [2][32] */ ; static double dmnmx, d1, d2, d3; static long start; static long stkpnt, dir; static double tmp; --d__; /* Function Body */ *info = 0; dir = -1; if (lsame_ (id, "D")) { dir = 0; } else if (lsame_ (id, "I")) { dir = 1; } if (dir == -1) { *info = -1; } else if (*n < 0) { *info = -2; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DLASRT", &i__1); return 0; } /* Quick return if possible */ if (*n <= 1) { return 0; } stkpnt = 1; stack_ref (1, 1) = 1; stack_ref (2, 1) = *n; L10: start = stack_ref (1, stkpnt); endd = stack_ref (2, stkpnt); --stkpnt; if (endd - start <= 20 && endd - start > 0) { /* Do Insertion sort on D( START:ENDD ) */ if (dir == 0) { /* Sort into decreasing order */ i__1 = endd; for (i__ = start + 1; i__ <= i__1; ++i__) { i__2 = start + 1; for (j = i__; j >= i__2; --j) { if (d__[j] > d__[j - 1]) { dmnmx = d__[j]; d__[j] = d__[j - 1]; d__[j - 1] = dmnmx; } else { goto L30; } /* L20: */ } L30: ; } } else { /* Sort into increasing order */ i__1 = endd; for (i__ = start + 1; i__ <= i__1; ++i__) { i__2 = start + 1; for (j = i__; j >= i__2; --j) { if (d__[j] < d__[j - 1]) { dmnmx = d__[j]; d__[j] = d__[j - 1]; d__[j - 1] = dmnmx; } else { goto L50; } /* L40: */ } L50: ; } } } else if (endd - start > 20) { /* Partition D( START:ENDD ) and stack parts, largest one first Choose partition entry as median of 3 */ d1 = d__[start]; d2 = d__[endd]; i__ = (start + endd) / 2; d3 = d__[i__]; if (d1 < d2) { if (d3 < d1) { dmnmx = d1; } else if (d3 < d2) { dmnmx = d3; } else { dmnmx = d2; } } else { if (d3 < d2) { dmnmx = d2; } else if (d3 < d1) { dmnmx = d3; } else { dmnmx = d1; } } if (dir == 0) { /* Sort into decreasing order */ i__ = start - 1; j = endd + 1; L60: L70: --j; if (d__[j] < dmnmx) { goto L70; } L80: ++i__; if (d__[i__] > dmnmx) { goto L80; } if (i__ < j) { tmp = d__[i__]; d__[i__] = d__[j]; d__[j] = tmp; goto L60; } if (j - start > endd - j - 1) { ++stkpnt; stack_ref (1, stkpnt) = start; stack_ref (2, stkpnt) = j; ++stkpnt; stack_ref (1, stkpnt) = j + 1; stack_ref (2, stkpnt) = endd; } else { ++stkpnt; stack_ref (1, stkpnt) = j + 1; stack_ref (2, stkpnt) = endd; ++stkpnt; stack_ref (1, stkpnt) = start; stack_ref (2, stkpnt) = j; } } else { /* Sort into increasing order */ i__ = start - 1; j = endd + 1; L90: L100: --j; if (d__[j] > dmnmx) { goto L100; } L110: ++i__; if (d__[i__] < dmnmx) { goto L110; } if (i__ < j) { tmp = d__[i__]; d__[i__] = d__[j]; d__[j] = tmp; goto L90; } if (j - start > endd - j - 1) { ++stkpnt; stack_ref (1, stkpnt) = start; stack_ref (2, stkpnt) = j; ++stkpnt; stack_ref (1, stkpnt) = j + 1; stack_ref (2, stkpnt) = endd; } else { ++stkpnt; stack_ref (1, stkpnt) = j + 1; stack_ref (2, stkpnt) = endd; ++stkpnt; stack_ref (1, stkpnt) = start; stack_ref (2, stkpnt) = j; } } } if (stkpnt > 0) { goto L10; } return 0; } /* NUMlapack_dlasrt */ #undef stack_ref int NUMlapack_dlassq (long *n, double *x, long *incx, double *scale, double *sumsq) { /* System generated locals */ long i__1, i__2; double d__1; /* Local variables */ static double absxi; static long ix; --x; /* Function Body */ if (*n > 0) { i__1 = (*n - 1) * *incx + 1; i__2 = *incx; for (ix = 1; i__2 < 0 ? ix >= i__1 : ix <= i__1; ix += i__2) { if (x[ix] != 0.) { absxi = (d__1 = x[ix], fabs (d__1)); if (*scale < absxi) { /* Computing 2nd power */ d__1 = *scale / absxi; *sumsq = *sumsq * (d__1 * d__1) + 1; *scale = absxi; } else { /* Computing 2nd power */ d__1 = absxi / *scale; *sumsq += d__1 * d__1; } } /* L10: */ } } return 0; } /* NUMlapack_dlassq */ int NUMlapack_dlasv2 (double *f, double *g, double *h__, double *ssmin, double *ssmax, double *snr, double *csr, double *snl, double *csl) { /* Table of constant values */ static double c_b3 = 2.; static double c_b4 = 1.; /* System generated locals */ double d__1; /* Local variables */ static long pmax; static double temp; static long swap; static double a, d__, l, m, r__, s, t, tsign, fa, ga, ha; static double ft, gt, ht, mm; static long gasmal; static double tt, clt, crt, slt, srt; ft = *f; fa = fabs (ft); ht = *h__; ha = fabs (*h__); /* PMAX points to the maximum absolute element of matrix PMAX = 1 if F largest in absolute values PMAX = 2 if G largest in absolute values PMAX = 3 if H largest in absolute values */ pmax = 1; swap = ha > fa; if (swap) { pmax = 3; temp = ft; ft = ht; ht = temp; temp = fa; fa = ha; ha = temp; /* Now FA .ge. HA */ } gt = *g; ga = fabs (gt); if (ga == 0.) { /* Diagonal matrix */ *ssmin = ha; *ssmax = fa; clt = 1.; crt = 1.; slt = 0.; srt = 0.; } else { gasmal = TRUE; if (ga > fa) { pmax = 2; if (fa / ga < NUMblas_dlamch ("EPS")) { /* Case of very large GA */ gasmal = FALSE; *ssmax = ga; if (ha > 1.) { *ssmin = fa / (ga / ha); } else { *ssmin = fa / ga * ha; } clt = 1.; slt = ht / gt; srt = 1.; crt = ft / gt; } } if (gasmal) { /* Normal case */ d__ = fa - ha; if (d__ == fa) { /* Copes with infinite F or H */ l = 1.; } else { l = d__ / fa; } /* Note that 0 .le. L .le. 1 */ m = gt / ft; /* Note that abs(M) .le. 1/macheps */ t = 2. - l; /* Note that T .ge. 1 */ mm = m * m; tt = t * t; s = sqrt (tt + mm); /* Note that 1 .le. S .le. 1 + 1/macheps */ if (l == 0.) { r__ = fabs (m); } else { r__ = sqrt (l * l + mm); } /* Note that 0 .le. R .le. 1 + 1/macheps */ a = (s + r__) * .5; /* Note that 1 .le. A .le. 1 + abs(M) */ *ssmin = ha / a; *ssmax = fa * a; if (mm == 0.) { /* Note that M is very tiny */ if (l == 0.) { t = d_sign (&c_b3, &ft) * d_sign (&c_b4, >); } else { t = gt / d_sign (&d__, &ft) + m / t; } } else { t = (m / (s + t) + m / (r__ + l)) * (a + 1.); } l = sqrt (t * t + 4.); crt = 2. / l; srt = t / l; clt = (crt + srt * m) / a; slt = ht / ft * srt / a; } } if (swap) { *csl = srt; *snl = crt; *csr = slt; *snr = clt; } else { *csl = clt; *snl = slt; *csr = crt; *snr = srt; } /* Correct signs of SSMAX and SSMIN */ if (pmax == 1) { tsign = d_sign (&c_b4, csr) * d_sign (&c_b4, csl) * d_sign (&c_b4, f); } if (pmax == 2) { tsign = d_sign (&c_b4, snr) * d_sign (&c_b4, csl) * d_sign (&c_b4, g); } if (pmax == 3) { tsign = d_sign (&c_b4, snr) * d_sign (&c_b4, snl) * d_sign (&c_b4, h__); } *ssmax = d_sign (ssmax, &tsign); d__1 = tsign * d_sign (&c_b4, f) * d_sign (&c_b4, h__); *ssmin = d_sign (ssmin, &d__1); return 0; } /* NUMlapack_dlasv2 */ int NUMlapack_dlaswp (long *n, double *a, long *lda, long *k1, long *k2, long *ipiv, long *incx) { /* System generated locals */ long a_dim1, a_offset, i__1, i__2, i__3, i__4; /* Local variables */ static double temp; static long i__, j, k, i1, i2, n32, ip, ix, ix0, inc; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --ipiv; /* Function Body */ if (*incx > 0) { ix0 = *k1; i1 = *k1; i2 = *k2; inc = 1; } else if (*incx < 0) { ix0 = (1 - *k2) * *incx + 1; i1 = *k2; i2 = *k1; inc = -1; } else { return 0; } n32 = *n / 32 << 5; if (n32 != 0) { i__1 = n32; for (j = 1; j <= i__1; j += 32) { ix = ix0; i__2 = i2; i__3 = inc; for (i__ = i1; i__3 < 0 ? i__ >= i__2 : i__ <= i__2; i__ += i__3) { ip = ipiv[ix]; if (ip != i__) { i__4 = j + 31; for (k = j; k <= i__4; ++k) { temp = a_ref (i__, k); a_ref (i__, k) = a_ref (ip, k); a_ref (ip, k) = temp; /* L10: */ } } ix += *incx; /* L20: */ } /* L30: */ } } if (n32 != *n) { ++n32; ix = ix0; i__1 = i2; i__3 = inc; for (i__ = i1; i__3 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__3) { ip = ipiv[ix]; if (ip != i__) { i__2 = *n; for (k = n32; k <= i__2; ++k) { temp = a_ref (i__, k); a_ref (i__, k) = a_ref (ip, k); a_ref (ip, k) = temp; /* L40: */ } } ix += *incx; /* L50: */ } } return 0; } /* NUMlapack_dlaswp */ #define w_ref(a_1,a_2) w[(a_2)*w_dim1 + a_1] int NUMlapack_dlatrd (const char *uplo, long *n, long *nb, double *a, long *lda, double *e, double *tau, double *w, long *ldw) { /* Table of constant values */ static double c_b5 = -1.; static double c_b6 = 1.; static long c__1 = 1; static double c_b16 = 0.; /* System generated locals */ long a_dim1, a_offset, w_dim1, w_offset, i__1, i__2, i__3; /* Local variables */ static long i__; static double alpha; static long iw; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --e; --tau; w_dim1 = *ldw; w_offset = 1 + w_dim1 * 1; w -= w_offset; /* Function Body */ if (*n <= 0) { return 0; } if (lsame_ (uplo, "U")) { /* Reduce last NB columns of upper triangle */ i__1 = *n - *nb + 1; for (i__ = *n; i__ >= i__1; --i__) { iw = i__ - *n + *nb; if (i__ < *n) { /* Update A(1:i,i) */ i__2 = *n - i__; NUMblas_dgemv ("No transpose", &i__, &i__2, &c_b5, &a_ref (1, i__ + 1), lda, &w_ref (i__, iw + 1), ldw, &c_b6, &a_ref (1, i__), &c__1); i__2 = *n - i__; NUMblas_dgemv ("No transpose", &i__, &i__2, &c_b5, &w_ref (1, iw + 1), ldw, &a_ref (i__, i__ + 1), lda, &c_b6, &a_ref (1, i__), &c__1); } if (i__ > 1) { /* Generate elementary reflector H(i) to annihilate A(1:i-2,i) */ i__2 = i__ - 1; NUMlapack_dlarfg (&i__2, &a_ref (i__ - 1, i__), &a_ref (1, i__), &c__1, &tau[i__ - 1]); e[i__ - 1] = a_ref (i__ - 1, i__); a_ref (i__ - 1, i__) = 1.; /* Compute W(1:i-1,i) */ i__2 = i__ - 1; NUMblas_dsymv ("Upper", &i__2, &c_b6, &a[a_offset], lda, &a_ref (1, i__), &c__1, &c_b16, &w_ref (1, iw), &c__1); if (i__ < *n) { i__2 = i__ - 1; i__3 = *n - i__; NUMblas_dgemv ("Transpose", &i__2, &i__3, &c_b6, &w_ref (1, iw + 1), ldw, &a_ref (1, i__), &c__1, &c_b16, &w_ref (i__ + 1, iw), &c__1); i__2 = i__ - 1; i__3 = *n - i__; NUMblas_dgemv ("No transpose", &i__2, &i__3, &c_b5, &a_ref (1, i__ + 1), lda, &w_ref (i__ + 1, iw), &c__1, &c_b6, &w_ref (1, iw), &c__1); i__2 = i__ - 1; i__3 = *n - i__; NUMblas_dgemv ("Transpose", &i__2, &i__3, &c_b6, &a_ref (1, i__ + 1), lda, &a_ref (1, i__), &c__1, &c_b16, &w_ref (i__ + 1, iw), &c__1); i__2 = i__ - 1; i__3 = *n - i__; NUMblas_dgemv ("No transpose", &i__2, &i__3, &c_b5, &w_ref (1, iw + 1), ldw, &w_ref (i__ + 1, iw), &c__1, &c_b6, &w_ref (1, iw), &c__1); } i__2 = i__ - 1; NUMblas_dscal (&i__2, &tau[i__ - 1], &w_ref (1, iw), &c__1); i__2 = i__ - 1; alpha = tau[i__ - 1] * -.5 * NUMblas_ddot (&i__2, &w_ref (1, iw), &c__1, &a_ref (1, i__), &c__1); i__2 = i__ - 1; NUMblas_daxpy (&i__2, &alpha, &a_ref (1, i__), &c__1, &w_ref (1, iw), &c__1); } /* L10: */ } } else { /* Reduce first NB columns of lower triangle */ i__1 = *nb; for (i__ = 1; i__ <= i__1; ++i__) { /* Update A(i:n,i) */ i__2 = *n - i__ + 1; i__3 = i__ - 1; NUMblas_dgemv ("No transpose", &i__2, &i__3, &c_b5, &a_ref (i__, 1), lda, &w_ref (i__, 1), ldw, &c_b6, &a_ref (i__, i__), &c__1); i__2 = *n - i__ + 1; i__3 = i__ - 1; NUMblas_dgemv ("No transpose", &i__2, &i__3, &c_b5, &w_ref (i__, 1), ldw, &a_ref (i__, 1), lda, &c_b6, &a_ref (i__, i__), &c__1); if (i__ < *n) { /* Generate elementary reflector H(i) to annihilate A(i+2:n,i) Computing MIN */ i__2 = i__ + 2; i__3 = *n - i__; NUMlapack_dlarfg (&i__3, &a_ref (i__ + 1, i__), &a_ref (MIN (i__2, *n), i__), &c__1, &tau[i__]); e[i__] = a_ref (i__ + 1, i__); a_ref (i__ + 1, i__) = 1.; /* Compute W(i+1:n,i) */ i__2 = *n - i__; NUMblas_dsymv ("Lower", &i__2, &c_b6, &a_ref (i__ + 1, i__ + 1), lda, &a_ref (i__ + 1, i__), &c__1, &c_b16, &w_ref (i__ + 1, i__), &c__1); i__2 = *n - i__; i__3 = i__ - 1; NUMblas_dgemv ("Transpose", &i__2, &i__3, &c_b6, &w_ref (i__ + 1, 1), ldw, &a_ref (i__ + 1, i__), &c__1, &c_b16, &w_ref (1, i__), &c__1); i__2 = *n - i__; i__3 = i__ - 1; NUMblas_dgemv ("No transpose", &i__2, &i__3, &c_b5, &a_ref (i__ + 1, 1), lda, &w_ref (1, i__), &c__1, &c_b6, &w_ref (i__ + 1, i__), &c__1); i__2 = *n - i__; i__3 = i__ - 1; NUMblas_dgemv ("Transpose", &i__2, &i__3, &c_b6, &a_ref (i__ + 1, 1), lda, &a_ref (i__ + 1, i__), &c__1, &c_b16, &w_ref (1, i__), &c__1); i__2 = *n - i__; i__3 = i__ - 1; NUMblas_dgemv ("No transpose", &i__2, &i__3, &c_b5, &w_ref (i__ + 1, 1), ldw, &w_ref (1, i__), &c__1, &c_b6, &w_ref (i__ + 1, i__), &c__1); i__2 = *n - i__; NUMblas_dscal (&i__2, &tau[i__], &w_ref (i__ + 1, i__), &c__1); i__2 = *n - i__; alpha = tau[i__] * -.5 * NUMblas_ddot (&i__2, &w_ref (i__ + 1, i__), &c__1, &a_ref (i__ + 1, i__), &c__1); i__2 = *n - i__; NUMblas_daxpy (&i__2, &alpha, &a_ref (i__ + 1, i__), &c__1, &w_ref (i__ + 1, i__), &c__1); } /* L20: */ } } return 0; } /* NUMlapack_dlatrd */ #undef w_ref int NUMlapack_dorg2l (long *m, long *n, long *k, double *a, long *lda, double *tau, double *work, long *info) { /* Table of constant values */ static long c__1 = 1; /* System generated locals */ long a_dim1, a_offset, i__1, i__2, i__3; double d__1; /* Local variables */ static long i__, j, l; static long ii; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --tau; --work; /* Function Body */ *info = 0; if (*m < 0) { *info = -1; } else if (*n < 0 || *n > *m) { *info = -2; } else if (*k < 0 || *k > *n) { *info = -3; } else if (*lda < MAX (1, *m)) { *info = -5; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DORG2L", &i__1); return 0; } /* Quick return if possible */ if (*n <= 0) { return 0; } /* Initialise columns 1:n-k to columns of the unit matrix */ i__1 = *n - *k; for (j = 1; j <= i__1; ++j) { i__2 = *m; for (l = 1; l <= i__2; ++l) { a_ref (l, j) = 0.; /* L10: */ } a_ref (*m - *n + j, j) = 1.; /* L20: */ } i__1 = *k; for (i__ = 1; i__ <= i__1; ++i__) { ii = *n - *k + i__; /* Apply H(i) to A(1:m-k+i,1:n-k+i) from the left */ a_ref (*m - *n + ii, ii) = 1.; i__2 = *m - *n + ii; i__3 = ii - 1; NUMlapack_dlarf ("Left", &i__2, &i__3, &a_ref (1, ii), &c__1, &tau[i__], &a[a_offset], lda, &work[1]); i__2 = *m - *n + ii - 1; d__1 = -tau[i__]; NUMblas_dscal (&i__2, &d__1, &a_ref (1, ii), &c__1); a_ref (*m - *n + ii, ii) = 1. - tau[i__]; /* Set A(m-k+i+1:m,n-k+i) to zero */ i__2 = *m; for (l = *m - *n + ii + 1; l <= i__2; ++l) { a_ref (l, ii) = 0.; /* L30: */ } /* L40: */ } return 0; } /* NUMlapack_dorg2l */ int NUMlapack_dorg2r (long *m, long *n, long *k, double *a, long *lda, double *tau, double *work, long *info) { /* Table of constant values */ static long c__1 = 1; /* System generated locals */ long a_dim1, a_offset, i__1, i__2; double d__1; /* Local variables */ static long i__, j, l; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --tau; --work; /* Function Body */ *info = 0; if (*m < 0) { *info = -1; } else if (*n < 0 || *n > *m) { *info = -2; } else if (*k < 0 || *k > *n) { *info = -3; } else if (*lda < MAX (1, *m)) { *info = -5; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DORG2R", &i__1); return 0; } /* Quick return if possible */ if (*n <= 0) { return 0; } /* Initialise columns k+1:n to columns of the unit matrix */ i__1 = *n; for (j = *k + 1; j <= i__1; ++j) { i__2 = *m; for (l = 1; l <= i__2; ++l) { a_ref (l, j) = 0.; /* L10: */ } a_ref (j, j) = 1.; /* L20: */ } for (i__ = *k; i__ >= 1; --i__) { /* Apply H(i) to A(i:m,i:n) from the left */ if (i__ < *n) { a_ref (i__, i__) = 1.; i__1 = *m - i__ + 1; i__2 = *n - i__; NUMlapack_dlarf ("Left", &i__1, &i__2, &a_ref (i__, i__), &c__1, &tau[i__], &a_ref (i__, i__ + 1), lda, &work[1]); } if (i__ < *m) { i__1 = *m - i__; d__1 = -tau[i__]; NUMblas_dscal (&i__1, &d__1, &a_ref (i__ + 1, i__), &c__1); } a_ref (i__, i__) = 1. - tau[i__]; /* Set A(1:i-1,i) to zero */ i__1 = i__ - 1; for (l = 1; l <= i__1; ++l) { a_ref (l, i__) = 0.; /* L30: */ } /* L40: */ } return 0; } /* NUMlapack_dorg2r */ int NUMlapack_dorgbr (const char *vect, long *m, long *n, long *k, double *a, long *lda, double *tau, double *work, long *lwork, long *info) { /* Table of constant values */ static long c__1 = 1; static long c_n1 = -1; /* System generated locals */ long a_dim1, a_offset, i__1, i__2, i__3; /* Local variables */ static long i__, j; static long iinfo; static long wantq; static long nb, mn; static long lwkopt; static long lquery; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --tau; --work; /* Function Body */ *info = 0; wantq = lsame_ (vect, "Q"); mn = MIN (*m, *n); lquery = *lwork == -1; if (!wantq && !lsame_ (vect, "P")) { *info = -1; } else if (*m < 0) { *info = -2; } else if (*n < 0 || wantq && (*n > *m || *n < MIN (*m, *k)) || !wantq && (*m > *n || *m < MIN (*n, *k))) { *info = -3; } else if (*k < 0) { *info = -4; } else if (*lda < MAX (1, *m)) { *info = -6; } else if (*lwork < MAX (1, mn) && !lquery) { *info = -9; } if (*info == 0) { if (wantq) { nb = NUMlapack_ilaenv (&c__1, "DORGQR", " ", m, n, k, &c_n1, 6, 1); } else { nb = NUMlapack_ilaenv (&c__1, "DORGLQ", " ", m, n, k, &c_n1, 6, 1); } lwkopt = MAX (1, mn) * nb; work[1] = (double) lwkopt; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DORGBR", &i__1); return 0; } else if (lquery) { return 0; } /* Quick return if possible */ if (*m == 0 || *n == 0) { work[1] = 1.; return 0; } if (wantq) { /* Form Q, determined by a call to DGEBRD to reduce an m-by-k matrix */ if (*m >= *k) { /* If m >= k, assume m >= n >= k */ NUMlapack_dorgqr (m, n, k, &a[a_offset], lda, &tau[1], &work[1], lwork, &iinfo); } else { /* If m < k, assume m = n Shift the vectors which define the elementary reflectors one column to the right, and set the first row and column of Q to those of the unit matrix */ for (j = *m; j >= 2; --j) { a_ref (1, j) = 0.; i__1 = *m; for (i__ = j + 1; i__ <= i__1; ++i__) { a_ref (i__, j) = a_ref (i__, j - 1); /* L10: */ } /* L20: */ } a_ref (1, 1) = 1.; i__1 = *m; for (i__ = 2; i__ <= i__1; ++i__) { a_ref (i__, 1) = 0.; /* L30: */ } if (*m > 1) { /* Form Q(2:m,2:m) */ i__1 = *m - 1; i__2 = *m - 1; i__3 = *m - 1; NUMlapack_dorgqr (&i__1, &i__2, &i__3, &a_ref (2, 2), lda, &tau[1], &work[1], lwork, &iinfo); } } } else { /* Form P', determined by a call to DGEBRD to reduce a k-by-n matrix */ if (*k < *n) { /* If k < n, assume k <= m <= n */ NUMlapack_dorglq (m, n, k, &a[a_offset], lda, &tau[1], &work[1], lwork, &iinfo); } else { /* If k >= n, assume m = n Shift the vectors which define the elementary reflectors one row downward, and set the first row and column of P' to those of the unit matrix */ a_ref (1, 1) = 1.; i__1 = *n; for (i__ = 2; i__ <= i__1; ++i__) { a_ref (i__, 1) = 0.; /* L40: */ } i__1 = *n; for (j = 2; j <= i__1; ++j) { for (i__ = j - 1; i__ >= 2; --i__) { a_ref (i__, j) = a_ref (i__ - 1, j); /* L50: */ } a_ref (1, j) = 0.; /* L60: */ } if (*n > 1) { /* Form P'(2:n,2:n) */ i__1 = *n - 1; i__2 = *n - 1; i__3 = *n - 1; NUMlapack_dorglq (&i__1, &i__2, &i__3, &a_ref (2, 2), lda, &tau[1], &work[1], lwork, &iinfo); } } } work[1] = (double) lwkopt; return 0; } /* NUMlapack_dorgbr */ int NUMlapack_dorghr (long *n, long *ilo, long *ihi, double *a, long *lda, double *tau, double *work, long *lwork, long *info) { /* Table of constant values */ static long c__1 = 1; static long c_n1 = -1; /* System generated locals */ long a_dim1, a_offset, i__1, i__2; /* Local variables */ static long i__, j, iinfo, nb, nh; static long lwkopt; static int lquery; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --tau; --work; /* Function Body */ *info = 0; nh = *ihi - *ilo; lquery = *lwork == -1; if (*n < 0) { *info = -1; } else if (*ilo < 1 || *ilo > MAX (1, *n)) { *info = -2; } else if (*ihi < MIN (*ilo, *n) || *ihi > *n) { *info = -3; } else if (*lda < MAX (1, *n)) { *info = -5; } else if (*lwork < MAX (1, nh) && !lquery) { *info = -8; } if (*info == 0) { nb = NUMlapack_ilaenv (&c__1, "DORGQR", " ", &nh, &nh, &nh, &c_n1, 6, 1); lwkopt = MAX (1, nh) * nb; work[1] = (double) lwkopt; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DORGHR", &i__1); return 0; } else if (lquery) { return 0; } /* Quick return if possible */ if (*n == 0) { work[1] = 1.; return 0; } /* Shift the vectors which define the elementary reflectors one column to the right, and set the first ilo and the last n-ihi rows and columns to those of the unit matrix */ i__1 = *ilo + 1; for (j = *ihi; j >= i__1; --j) { i__2 = j - 1; for (i__ = 1; i__ <= i__2; ++i__) { a_ref (i__, j) = 0.; /* L10: */ } i__2 = *ihi; for (i__ = j + 1; i__ <= i__2; ++i__) { a_ref (i__, j) = a_ref (i__, j - 1); /* L20: */ } i__2 = *n; for (i__ = *ihi + 1; i__ <= i__2; ++i__) { a_ref (i__, j) = 0.; /* L30: */ } /* L40: */ } i__1 = *ilo; for (j = 1; j <= i__1; ++j) { i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { a_ref (i__, j) = 0.; /* L50: */ } a_ref (j, j) = 1.; /* L60: */ } i__1 = *n; for (j = *ihi + 1; j <= i__1; ++j) { i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { a_ref (i__, j) = 0.; /* L70: */ } a_ref (j, j) = 1.; /* L80: */ } if (nh > 0) { /* Generate Q(ilo+1:ihi,ilo+1:ihi) */ NUMlapack_dorgqr (&nh, &nh, &nh, &a_ref (*ilo + 1, *ilo + 1), lda, &tau[*ilo], &work[1], lwork, &iinfo); } work[1] = (double) lwkopt; return 0; } /* NUMlapack_dorghr */ int NUMlapack_dorgl2 (long *m, long *n, long *k, double *a, long *lda, double *tau, double *work, long *info) { /* System generated locals */ long a_dim1, a_offset, i__1, i__2; double d__1; /* Local variables */ static long i__, j, l; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --tau; --work; /* Function Body */ *info = 0; if (*m < 0) { *info = -1; } else if (*n < *m) { *info = -2; } else if (*k < 0 || *k > *m) { *info = -3; } else if (*lda < MAX (1, *m)) { *info = -5; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DORGL2", &i__1); return 0; } /* Quick return if possible */ if (*m <= 0) { return 0; } if (*k < *m) { /* Initialise rows k+1:m to rows of the unit matrix */ i__1 = *n; for (j = 1; j <= i__1; ++j) { i__2 = *m; for (l = *k + 1; l <= i__2; ++l) { a_ref (l, j) = 0.; /* L10: */ } if (j > *k && j <= *m) { a_ref (j, j) = 1.; } /* L20: */ } } for (i__ = *k; i__ >= 1; --i__) { /* Apply H(i) to A(i:m,i:n) from the right */ if (i__ < *n) { if (i__ < *m) { a_ref (i__, i__) = 1.; i__1 = *m - i__; i__2 = *n - i__ + 1; NUMlapack_dlarf ("Right", &i__1, &i__2, &a_ref (i__, i__), lda, &tau[i__], &a_ref (i__ + 1, i__), lda, &work[1]); } i__1 = *n - i__; d__1 = -tau[i__]; NUMblas_dscal (&i__1, &d__1, &a_ref (i__, i__ + 1), lda); } a_ref (i__, i__) = 1. - tau[i__]; /* Set A(i,1:i-1) to zero */ i__1 = i__ - 1; for (l = 1; l <= i__1; ++l) { a_ref (i__, l) = 0.; /* L30: */ } /* L40: */ } return 0; } /* NUMlapack_dorgl2 */ int NUMlapack_dorglq (long *m, long *n, long *k, double *a, long *lda, double *tau, double *work, long *lwork, long *info) { /* Table of constant values */ static long c__1 = 1; static long c_n1 = -1; static long c__3 = 3; static long c__2 = 2; /* System generated locals */ long a_dim1, a_offset, i__1, i__2, i__3; /* Local variables */ static long i__, j, l, nbmin, iinfo; static long ib, nb, ki, kk; static long nx; static long ldwork, lwkopt; static long lquery; static long iws; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --tau; --work; /* Function Body */ *info = 0; nb = NUMlapack_ilaenv (&c__1, "DORGLQ", " ", m, n, k, &c_n1, 6, 1); lwkopt = MAX (1, *m) * nb; work[1] = (double) lwkopt; lquery = *lwork == -1; if (*m < 0) { *info = -1; } else if (*n < *m) { *info = -2; } else if (*k < 0 || *k > *m) { *info = -3; } else if (*lda < MAX (1, *m)) { *info = -5; } else if (*lwork < MAX (1, *m) && !lquery) { *info = -8; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DORGLQ", &i__1); return 0; } else if (lquery) { return 0; } /* Quick return if possible */ if (*m <= 0) { work[1] = 1.; return 0; } nbmin = 2; nx = 0; iws = *m; if (nb > 1 && nb < *k) { /* Determine when to cross over from blocked to unblocked code. Computing MAX */ i__1 = 0, i__2 = NUMlapack_ilaenv (&c__3, "DORGLQ", " ", m, n, k, &c_n1, 6, 1); nx = MAX (i__1, i__2); if (nx < *k) { /* Determine if workspace is large enough for blocked code. */ ldwork = *m; iws = ldwork * nb; if (*lwork < iws) { /* Not enough workspace to use optimal NB: reduce NB and determine the minimum value of NB. */ nb = *lwork / ldwork; /* Computing MAX */ i__1 = 2, i__2 = NUMlapack_ilaenv (&c__2, "DORGLQ", " ", m, n, k, &c_n1, 6, 1); nbmin = MAX (i__1, i__2); } } } if (nb >= nbmin && nb < *k && nx < *k) { /* Use blocked code after the last block. The first kk rows are handled by the block method. */ ki = (*k - nx - 1) / nb * nb; /* Computing MIN */ i__1 = *k, i__2 = ki + nb; kk = MIN (i__1, i__2); /* Set A(kk+1:m,1:kk) to zero. */ i__1 = kk; for (j = 1; j <= i__1; ++j) { i__2 = *m; for (i__ = kk + 1; i__ <= i__2; ++i__) { a_ref (i__, j) = 0.; /* L10: */ } /* L20: */ } } else { kk = 0; } /* Use unblocked code for the last or only block. */ if (kk < *m) { i__1 = *m - kk; i__2 = *n - kk; i__3 = *k - kk; NUMlapack_dorgl2 (&i__1, &i__2, &i__3, &a_ref (kk + 1, kk + 1), lda, &tau[kk + 1], &work[1], &iinfo); } if (kk > 0) { /* Use blocked code */ i__1 = -nb; for (i__ = ki + 1; i__1 < 0 ? i__ >= 1 : i__ <= 1; i__ += i__1) { /* Computing MIN */ i__2 = nb, i__3 = *k - i__ + 1; ib = MIN (i__2, i__3); if (i__ + ib <= *m) { /* Form the triangular factor of the block reflector H = H(i) H(i+1) . . . H(i+ib-1) */ i__2 = *n - i__ + 1; NUMlapack_dlarft ("Forward", "Rowwise", &i__2, &ib, &a_ref (i__, i__), lda, &tau[i__], &work[1], &ldwork); /* Apply H' to A(i+ib:m,i:n) from the right */ i__2 = *m - i__ - ib + 1; i__3 = *n - i__ + 1; NUMlapack_dlarfb ("Right", "Transpose", "Forward", "Rowwise", &i__2, &i__3, &ib, &a_ref (i__, i__), lda, &work[1], &ldwork, &a_ref (i__ + ib, i__), lda, &work[ib + 1], &ldwork); } /* Apply H' to columns i:n of current block */ i__2 = *n - i__ + 1; NUMlapack_dorgl2 (&ib, &i__2, &ib, &a_ref (i__, i__), lda, &tau[i__], &work[1], &iinfo); /* Set columns 1:i-1 of current block to zero */ i__2 = i__ - 1; for (j = 1; j <= i__2; ++j) { i__3 = i__ + ib - 1; for (l = i__; l <= i__3; ++l) { a_ref (l, j) = 0.; /* L30: */ } /* L40: */ } /* L50: */ } } work[1] = (double) iws; return 0; } /* NUMlapack_dorglq */ int NUMlapack_dorgql (long *m, long *n, long *k, double *a, long *lda, double *tau, double *work, long *lwork, long *info) { /* Table of constant values */ static long c__1 = 1; static long c_n1 = -1; static long c__3 = 3; static long c__2 = 2; /* System generated locals */ long a_dim1, a_offset, i__1, i__2, i__3, i__4; /* Local variables */ static long i__, j, l, nbmin, iinfo; static long ib, nb, kk; static long nx; static long ldwork, lwkopt; static long lquery; static long iws; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --tau; --work; /* Function Body */ *info = 0; nb = NUMlapack_ilaenv (&c__1, "DORGQL", " ", m, n, k, &c_n1, 6, 1); lwkopt = MAX (1, *n) * nb; work[1] = (double) lwkopt; lquery = *lwork == -1; if (*m < 0) { *info = -1; } else if (*n < 0 || *n > *m) { *info = -2; } else if (*k < 0 || *k > *n) { *info = -3; } else if (*lda < MAX (1, *m)) { *info = -5; } else if (*lwork < MAX (1, *n) && !lquery) { *info = -8; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DORGQL", &i__1); return 0; } else if (lquery) { return 0; } /* Quick return if possible */ if (*n <= 0) { work[1] = 1.; return 0; } nbmin = 2; nx = 0; iws = *n; if (nb > 1 && nb < *k) { /* Determine when to cross over from blocked to unblocked code. Computing MAX */ i__1 = 0, i__2 = NUMlapack_ilaenv (&c__3, "DORGQL", " ", m, n, k, &c_n1, 6, 1); nx = MAX (i__1, i__2); if (nx < *k) { /* Determine if workspace is large enough for blocked code. */ ldwork = *n; iws = ldwork * nb; if (*lwork < iws) { /* Not enough workspace to use optimal NB: reduce NB and determine the minimum value of NB. */ nb = *lwork / ldwork; /* Computing MAX */ i__1 = 2, i__2 = NUMlapack_ilaenv (&c__2, "DORGQL", " ", m, n, k, &c_n1, 6, 1); nbmin = MAX (i__1, i__2); } } } if (nb >= nbmin && nb < *k && nx < *k) { /* Use blocked code after the first block. The last kk columns are handled by the block method. Computing MIN */ i__1 = *k, i__2 = (*k - nx + nb - 1) / nb * nb; kk = MIN (i__1, i__2); /* Set A(m-kk+1:m,1:n-kk) to zero. */ i__1 = *n - kk; for (j = 1; j <= i__1; ++j) { i__2 = *m; for (i__ = *m - kk + 1; i__ <= i__2; ++i__) { a_ref (i__, j) = 0.; /* L10: */ } /* L20: */ } } else { kk = 0; } /* Use unblocked code for the first or only block. */ i__1 = *m - kk; i__2 = *n - kk; i__3 = *k - kk; NUMlapack_dorg2l (&i__1, &i__2, &i__3, &a[a_offset], lda, &tau[1], &work[1], &iinfo); if (kk > 0) { /* Use blocked code */ i__1 = *k; i__2 = nb; for (i__ = *k - kk + 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) { /* Computing MIN */ i__3 = nb, i__4 = *k - i__ + 1; ib = MIN (i__3, i__4); if (*n - *k + i__ > 1) { /* Form the triangular factor of the block reflector H = H(i+ib-1) . . . H(i+1) H(i) */ i__3 = *m - *k + i__ + ib - 1; NUMlapack_dlarft ("Backward", "Columnwise", &i__3, &ib, &a_ref (1, *n - *k + i__), lda, &tau[i__], &work[1], &ldwork); /* Apply H to A(1:m-k+i+ib-1,1:n-k+i-1) from the left */ i__3 = *m - *k + i__ + ib - 1; i__4 = *n - *k + i__ - 1; NUMlapack_dlarfb ("Left", "No transpose", "Backward", "Columnwise", &i__3, &i__4, &ib, &a_ref (1, *n - *k + i__), lda, &work[1], &ldwork, &a[a_offset], lda, &work[ib + 1], &ldwork); } /* Apply H to rows 1:m-k+i+ib-1 of current block */ i__3 = *m - *k + i__ + ib - 1; NUMlapack_dorg2l (&i__3, &ib, &ib, &a_ref (1, *n - *k + i__), lda, &tau[i__], &work[1], &iinfo); /* Set rows m-k+i+ib:m of current block to zero */ i__3 = *n - *k + i__ + ib - 1; for (j = *n - *k + i__; j <= i__3; ++j) { i__4 = *m; for (l = *m - *k + i__ + ib; l <= i__4; ++l) { a_ref (l, j) = 0.; /* L30: */ } /* L40: */ } /* L50: */ } } work[1] = (double) iws; return 0; } /* NUMlapack_dorgql */ int NUMlapack_dorgqr (long *m, long *n, long *k, double *a, long *lda, double *tau, double *work, long *lwork, long *info) { /* Table of constant values */ static long c__1 = 1; static long c_n1 = -1; static long c__3 = 3; static long c__2 = 2; /* System generated locals */ long a_dim1, a_offset, i__1, i__2, i__3; /* Local variables */ static long i__, j, l, nbmin, iinfo; static long ib, nb, ki, kk; static long nx; static long ldwork, lwkopt; static long lquery; static long iws; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --tau; --work; /* Function Body */ *info = 0; nb = NUMlapack_ilaenv (&c__1, "DORGQR", " ", m, n, k, &c_n1, 6, 1); lwkopt = MAX (1, *n) * nb; work[1] = (double) lwkopt; lquery = *lwork == -1; if (*m < 0) { *info = -1; } else if (*n < 0 || *n > *m) { *info = -2; } else if (*k < 0 || *k > *n) { *info = -3; } else if (*lda < MAX (1, *m)) { *info = -5; } else if (*lwork < MAX (1, *n) && !lquery) { *info = -8; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DORGQR", &i__1); return 0; } else if (lquery) { return 0; } /* Quick return if possible */ if (*n <= 0) { work[1] = 1.; return 0; } nbmin = 2; nx = 0; iws = *n; if (nb > 1 && nb < *k) { /* Determine when to cross over from blocked to unblocked code. Computing MAX */ i__1 = 0, i__2 = NUMlapack_ilaenv (&c__3, "DORGQR", " ", m, n, k, &c_n1, 6, 1); nx = MAX (i__1, i__2); if (nx < *k) { /* Determine if workspace is large enough for blocked code. */ ldwork = *n; iws = ldwork * nb; if (*lwork < iws) { /* Not enough workspace to use optimal NB: reduce NB and determine the minimum value of NB. */ nb = *lwork / ldwork; /* Computing MAX */ i__1 = 2, i__2 = NUMlapack_ilaenv (&c__2, "DORGQR", " ", m, n, k, &c_n1, 6, 1); nbmin = MAX (i__1, i__2); } } } if (nb >= nbmin && nb < *k && nx < *k) { /* Use blocked code after the last block. The first kk columns are handled by the block method. */ ki = (*k - nx - 1) / nb * nb; /* Computing MIN */ i__1 = *k, i__2 = ki + nb; kk = MIN (i__1, i__2); /* Set A(1:kk,kk+1:n) to zero. */ i__1 = *n; for (j = kk + 1; j <= i__1; ++j) { i__2 = kk; for (i__ = 1; i__ <= i__2; ++i__) { a_ref (i__, j) = 0.; /* L10: */ } /* L20: */ } } else { kk = 0; } /* Use unblocked code for the last or only block. */ if (kk < *n) { i__1 = *m - kk; i__2 = *n - kk; i__3 = *k - kk; NUMlapack_dorg2r (&i__1, &i__2, &i__3, &a_ref (kk + 1, kk + 1), lda, &tau[kk + 1], &work[1], &iinfo); } if (kk > 0) { /* Use blocked code */ i__1 = -nb; for (i__ = ki + 1; i__1 < 0 ? i__ >= 1 : i__ <= 1; i__ += i__1) { /* Computing MIN */ i__2 = nb, i__3 = *k - i__ + 1; ib = MIN (i__2, i__3); if (i__ + ib <= *n) { /* Form the triangular factor of the block reflector H = H(i) H(i+1) . . . H(i+ib-1) */ i__2 = *m - i__ + 1; NUMlapack_dlarft ("Forward", "Columnwise", &i__2, &ib, &a_ref (i__, i__), lda, &tau[i__], &work[1], &ldwork); /* Apply H to A(i:m,i+ib:n) from the left */ i__2 = *m - i__ + 1; i__3 = *n - i__ - ib + 1; NUMlapack_dlarfb ("Left", "No transpose", "Forward", "Columnwise", &i__2, &i__3, &ib, &a_ref (i__, i__), lda, &work[1], &ldwork, &a_ref (i__, i__ + ib), lda, &work[ib + 1], &ldwork); } /* Apply H to rows i:m of current block */ i__2 = *m - i__ + 1; NUMlapack_dorg2r (&i__2, &ib, &ib, &a_ref (i__, i__), lda, &tau[i__], &work[1], &iinfo); /* Set rows 1:i-1 of current block to zero */ i__2 = i__ + ib - 1; for (j = i__; j <= i__2; ++j) { i__3 = i__ - 1; for (l = 1; l <= i__3; ++l) { a_ref (l, j) = 0.; /* L30: */ } /* L40: */ } /* L50: */ } } work[1] = (double) iws; return 0; } /* NUMlapack_dorgqr */ int NUMlapack_dorgtr (const char *uplo, long *n, double *a, long *lda, double *tau, double *work, long *lwork, long *info) { /* Table of constant values */ static long c__1 = 1; static long c_n1 = -1; /* System generated locals */ long a_dim1, a_offset, i__1, i__2, i__3; /* Local variables */ static long i__, j; static long iinfo; static long upper; static long nb; static long lwkopt; static long lquery; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --tau; --work; /* Function Body */ *info = 0; lquery = *lwork == -1; upper = lsame_ (uplo, "U"); if (!upper && !lsame_ (uplo, "L")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < MAX (1, *n)) { *info = -4; } else { /* if(complicated condition) */ /* Computing MAX */ i__1 = 1, i__2 = *n - 1; if (*lwork < MAX (i__1, i__2) && !lquery) { *info = -7; } } if (*info == 0) { if (upper) { i__1 = *n - 1; i__2 = *n - 1; i__3 = *n - 1; nb = NUMlapack_ilaenv (&c__1, "DORGQL", " ", &i__1, &i__2, &i__3, &c_n1, 6, 1); } else { i__1 = *n - 1; i__2 = *n - 1; i__3 = *n - 1; nb = NUMlapack_ilaenv (&c__1, "DORGQR", " ", &i__1, &i__2, &i__3, &c_n1, 6, 1); } /* Computing MAX */ i__1 = 1, i__2 = *n - 1; lwkopt = MAX (i__1, i__2) * nb; work[1] = (double) lwkopt; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DORGTR", &i__1); return 0; } else if (lquery) { return 0; } /* Quick return if possible */ if (*n == 0) { work[1] = 1.; return 0; } if (upper) { /* Q was determined by a call to DSYTRD with UPLO = 'U' Shift the vectors which define the elementary reflectors one column to the left, and set the last row and column of Q to those of the unit matrix */ i__1 = *n - 1; for (j = 1; j <= i__1; ++j) { i__2 = j - 1; for (i__ = 1; i__ <= i__2; ++i__) { a_ref (i__, j) = a_ref (i__, j + 1); /* L10: */ } a_ref (*n, j) = 0.; /* L20: */ } i__1 = *n - 1; for (i__ = 1; i__ <= i__1; ++i__) { a_ref (i__, *n) = 0.; /* L30: */ } a_ref (*n, *n) = 1.; /* Generate Q(1:n-1,1:n-1) */ i__1 = *n - 1; i__2 = *n - 1; i__3 = *n - 1; NUMlapack_dorgql (&i__1, &i__2, &i__3, &a[a_offset], lda, &tau[1], &work[1], lwork, &iinfo); } else { /* Q was determined by a call to DSYTRD with UPLO = 'L'. Shift the vectors which define the elementary reflectors one column to the right, and set the first row and column of Q to those of the unit matrix */ for (j = *n; j >= 2; --j) { a_ref (1, j) = 0.; i__1 = *n; for (i__ = j + 1; i__ <= i__1; ++i__) { a_ref (i__, j) = a_ref (i__, j - 1); /* L40: */ } /* L50: */ } a_ref (1, 1) = 1.; i__1 = *n; for (i__ = 2; i__ <= i__1; ++i__) { a_ref (i__, 1) = 0.; /* L60: */ } if (*n > 1) { /* Generate Q(2:n,2:n) */ i__1 = *n - 1; i__2 = *n - 1; i__3 = *n - 1; NUMlapack_dorgqr (&i__1, &i__2, &i__3, &a_ref (2, 2), lda, &tau[1], &work[1], lwork, &iinfo); } } work[1] = (double) lwkopt; return 0; } /* NUMlapack_dorgtr */ int NUMlapack_dorm2r (const char *side, const char *trans, long *m, long *n, long *k, double *a, long *lda, double *tau, double *c__, long *ldc, double *work, long *info) { /* Table of constant values */ static long c__1 = 1; /* System generated locals */ long a_dim1, a_offset, c_dim1, c_offset, i__1, i__2; /* Local variables */ static long left; static long i__; static long i1, i2, i3, ic, jc, mi, ni, nq; static long notran; static double aii; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --tau; c_dim1 = *ldc; c_offset = 1 + c_dim1 * 1; c__ -= c_offset; --work; /* Function Body */ *info = 0; left = lsame_ (side, "L"); notran = lsame_ (trans, "N"); /* NQ is the order of Q */ if (left) { nq = *m; } else { nq = *n; } if (!left && !lsame_ (side, "R")) { *info = -1; } else if (!notran && !lsame_ (trans, "T")) { *info = -2; } else if (*m < 0) { *info = -3; } else if (*n < 0) { *info = -4; } else if (*k < 0 || *k > nq) { *info = -5; } else if (*lda < MAX (1, nq)) { *info = -7; } else if (*ldc < MAX (1, *m)) { *info = -10; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DORM2R", &i__1); return 0; } /* Quick return if possible */ if (*m == 0 || *n == 0 || *k == 0) { return 0; } if (left && !notran || !left && notran) { i1 = 1; i2 = *k; i3 = 1; } else { i1 = *k; i2 = 1; i3 = -1; } if (left) { ni = *n; jc = 1; } else { mi = *m; ic = 1; } i__1 = i2; i__2 = i3; for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) { if (left) { /* H(i) is applied to C(i:m,1:n) */ mi = *m - i__ + 1; ic = i__; } else { /* H(i) is applied to C(1:m,i:n) */ ni = *n - i__ + 1; jc = i__; } /* Apply H(i) */ aii = a_ref (i__, i__); a_ref (i__, i__) = 1.; NUMlapack_dlarf (side, &mi, &ni, &a_ref (i__, i__), &c__1, &tau[i__], &c___ref (ic, jc), ldc, &work[1]); a_ref (i__, i__) = aii; /* L10: */ } return 0; } /* NUMlapack_dorm2r */ int NUMlapack_dormbr (const char *vect, const char *side, const char *trans, long *m, long *n, long *k, double *a, long *lda, double *tau, double *c__, long *ldc, double *work, long *lwork, long *info) { /* Table of constant values */ static long c__1 = 1; static long c_n1 = -1; static long c__2 = 2; /* System generated locals */ const char *a__1[2]; long a_dim1, a_offset, c_dim1, c_offset, i__1, i__2, i__3[2]; char ch__1[2]; /* Local variables */ static long left; static long iinfo, i1, i2, nb, mi, ni, nq, nw; static long notran; static long applyq; static char transt[1]; static long lwkopt; static long lquery; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --tau; c_dim1 = *ldc; c_offset = 1 + c_dim1 * 1; c__ -= c_offset; --work; /* Function Body */ *info = 0; applyq = lsame_ (vect, "Q"); left = lsame_ (side, "L"); notran = lsame_ (trans, "N"); lquery = *lwork == -1; /* NQ is the order of Q or P and NW is the minimum dimension of WORK */ if (left) { nq = *m; nw = *n; } else { nq = *n; nw = *m; } if (!applyq && !lsame_ (vect, "P")) { *info = -1; } else if (!left && !lsame_ (side, "R")) { *info = -2; } else if (!notran && !lsame_ (trans, "T")) { *info = -3; } else if (*m < 0) { *info = -4; } else if (*n < 0) { *info = -5; } else if (*k < 0) { *info = -6; } else { /* if(complicated condition) */ /* Computing MAX */ i__1 = 1, i__2 = MIN (nq, *k); if (applyq && *lda < MAX (1, nq) || !applyq && *lda < MAX (i__1, i__2)) { *info = -8; } else if (*ldc < MAX (1, *m)) { *info = -11; } else if (*lwork < MAX (1, nw) && !lquery) { *info = -13; } } if (*info == 0) { if (applyq) { if (left) { /* Writing concatenation */ i__3[0] = 1, a__1[0] = side; i__3[1] = 1, a__1[1] = trans; s_cat (ch__1, a__1, i__3, &c__2, 2); i__1 = *m - 1; i__2 = *m - 1; nb = NUMlapack_ilaenv (&c__1, "DORMQR", ch__1, &i__1, n, &i__2, &c_n1, 6, 2); } else { /* Writing concatenation */ i__3[0] = 1, a__1[0] = side; i__3[1] = 1, a__1[1] = trans; s_cat (ch__1, a__1, i__3, &c__2, 2); i__1 = *n - 1; i__2 = *n - 1; nb = NUMlapack_ilaenv (&c__1, "DORMQR", ch__1, m, &i__1, &i__2, &c_n1, 6, 2); } } else { if (left) { /* Writing concatenation */ i__3[0] = 1, a__1[0] = side; i__3[1] = 1, a__1[1] = trans; s_cat (ch__1, a__1, i__3, &c__2, 2); i__1 = *m - 1; i__2 = *m - 1; nb = NUMlapack_ilaenv (&c__1, "DORMLQ", ch__1, &i__1, n, &i__2, &c_n1, 6, 2); } else { /* Writing concatenation */ i__3[0] = 1, a__1[0] = side; i__3[1] = 1, a__1[1] = trans; s_cat (ch__1, a__1, i__3, &c__2, 2); i__1 = *n - 1; i__2 = *n - 1; nb = NUMlapack_ilaenv (&c__1, "DORMLQ", ch__1, m, &i__1, &i__2, &c_n1, 6, 2); } } lwkopt = MAX (1, nw) * nb; work[1] = (double) lwkopt; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DORMBR", &i__1); return 0; } else if (lquery) { return 0; } /* Quick return if possible */ work[1] = 1.; if (*m == 0 || *n == 0) { return 0; } if (applyq) { /* Apply Q */ if (nq >= *k) { /* Q was determined by a call to DGEBRD with nq >= k */ NUMlapack_dormqr (side, trans, m, n, k, &a[a_offset], lda, &tau[1], &c__[c_offset], ldc, &work[1], lwork, &iinfo); } else if (nq > 1) { /* Q was determined by a call to DGEBRD with nq < k */ if (left) { mi = *m - 1; ni = *n; i1 = 2; i2 = 1; } else { mi = *m; ni = *n - 1; i1 = 1; i2 = 2; } i__1 = nq - 1; NUMlapack_dormqr (side, trans, &mi, &ni, &i__1, &a_ref (2, 1), lda, &tau[1], &c___ref (i1, i2), ldc, &work[1], lwork, &iinfo); } } else { /* Apply P */ if (notran) { * (unsigned char *) transt = 'T'; } else { * (unsigned char *) transt = 'N'; } if (nq > *k) { /* P was determined by a call to DGEBRD with nq > k */ NUMlapack_dormlq (side, transt, m, n, k, &a[a_offset], lda, &tau[1], &c__[c_offset], ldc, &work[1], lwork, &iinfo); } else if (nq > 1) { /* P was determined by a call to DGEBRD with nq <= k */ if (left) { mi = *m - 1; ni = *n; i1 = 2; i2 = 1; } else { mi = *m; ni = *n - 1; i1 = 1; i2 = 2; } i__1 = nq - 1; NUMlapack_dormlq (side, transt, &mi, &ni, &i__1, &a_ref (1, 2), lda, &tau[1], &c___ref (i1, i2), ldc, &work[1], lwork, &iinfo); } } work[1] = (double) lwkopt; return 0; } /* NUMlapack_dormbr */ int NUMlapack_dorml2 (const char *side, const char *trans, long *m, long *n, long *k, double *a, long *lda, double *tau, double *c__, long *ldc, double *work, long *info) { /* System generated locals */ long a_dim1, a_offset, c_dim1, c_offset, i__1, i__2; /* Local variables */ static long left; static long i__; static long i1, i2, i3, ic, jc, mi, ni, nq; static long notran; static double aii; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --tau; c_dim1 = *ldc; c_offset = 1 + c_dim1 * 1; c__ -= c_offset; --work; /* Function Body */ *info = 0; left = lsame_ (side, "L"); notran = lsame_ (trans, "N"); /* NQ is the order of Q */ if (left) { nq = *m; } else { nq = *n; } if (!left && !lsame_ (side, "R")) { *info = -1; } else if (!notran && !lsame_ (trans, "T")) { *info = -2; } else if (*m < 0) { *info = -3; } else if (*n < 0) { *info = -4; } else if (*k < 0 || *k > nq) { *info = -5; } else if (*lda < MAX (1, *k)) { *info = -7; } else if (*ldc < MAX (1, *m)) { *info = -10; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DORML2", &i__1); return 0; } /* Quick return if possible */ if (*m == 0 || *n == 0 || *k == 0) { return 0; } if (left && notran || !left && !notran) { i1 = 1; i2 = *k; i3 = 1; } else { i1 = *k; i2 = 1; i3 = -1; } if (left) { ni = *n; jc = 1; } else { mi = *m; ic = 1; } i__1 = i2; i__2 = i3; for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) { if (left) { /* H(i) is applied to C(i:m,1:n) */ mi = *m - i__ + 1; ic = i__; } else { /* H(i) is applied to C(1:m,i:n) */ ni = *n - i__ + 1; jc = i__; } /* Apply H(i) */ aii = a_ref (i__, i__); a_ref (i__, i__) = 1.; NUMlapack_dlarf (side, &mi, &ni, &a_ref (i__, i__), lda, &tau[i__], &c___ref (ic, jc), ldc, &work[1]); a_ref (i__, i__) = aii; /* L10: */ } return 0; } /* NUMlapack_dorml2 */ int NUMlapack_dormlq (const char *side, const char *trans, long *m, long *n, long *k, double *a, long *lda, double *tau, double *c__, long *ldc, double *work, long *lwork, long *info) { /* Table of constant values */ static long c__1 = 1; static long c_n1 = -1; static long c__2 = 2; static long c__65 = 65; /* System generated locals */ char *a__1[2]; long a_dim1, a_offset, c_dim1, c_offset, i__1, i__2, i__3[2], i__4, i__5; char ch__1[2]; /* Local variables */ static long left; static long i__; static double t[4160] /* was [65][64] */ ; static long nbmin, iinfo, i1, i2, i3; static long ib, ic, jc, nb, mi, ni; static long nq, nw; static long notran; static long ldwork; static char transt[1]; static long lwkopt; static long lquery; static long iws; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --tau; c_dim1 = *ldc; c_offset = 1 + c_dim1 * 1; c__ -= c_offset; --work; /* Function Body */ *info = 0; left = lsame_ (side, "L"); notran = lsame_ (trans, "N"); lquery = *lwork == -1; /* NQ is the order of Q and NW is the minimum dimension of WORK */ if (left) { nq = *m; nw = *n; } else { nq = *n; nw = *m; } if (!left && !lsame_ (side, "R")) { *info = -1; } else if (!notran && !lsame_ (trans, "T")) { *info = -2; } else if (*m < 0) { *info = -3; } else if (*n < 0) { *info = -4; } else if (*k < 0 || *k > nq) { *info = -5; } else if (*lda < MAX (1, *k)) { *info = -7; } else if (*ldc < MAX (1, *m)) { *info = -10; } else if (*lwork < MAX (1, nw) && !lquery) { *info = -12; } if (*info == 0) { /* Determine the block size. NB may be at most NBMAX, where NBMAX is used to define the local array T. Computing MIN Writing concatenation */ i__3[0] = 1, a__1[0] = (char *) side; i__3[1] = 1, a__1[1] = (char *) trans; s_cat (ch__1, (const char **) a__1, i__3, &c__2, 2); i__1 = 64, i__2 = NUMlapack_ilaenv (&c__1, "DORMLQ", ch__1, m, n, k, &c_n1, 6, 2); nb = MIN (i__1, i__2); lwkopt = MAX (1, nw) * nb; work[1] = (double) lwkopt; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DORMLQ", &i__1); return 0; } else if (lquery) { return 0; } /* Quick return if possible */ if (*m == 0 || *n == 0 || *k == 0) { work[1] = 1.; return 0; } nbmin = 2; ldwork = nw; if (nb > 1 && nb < *k) { iws = nw * nb; if (*lwork < iws) { nb = *lwork / ldwork; /* Computing MAX Writing concatenation */ i__3[0] = 1, a__1[0] = (char *) side; i__3[1] = 1, a__1[1] = (char *) trans; s_cat (ch__1, (const char **) a__1, i__3, &c__2, 2); i__1 = 2, i__2 = NUMlapack_ilaenv (&c__2, "DORMLQ", ch__1, m, n, k, &c_n1, 6, 2); nbmin = MAX (i__1, i__2); } } else { iws = nw; } if (nb < nbmin || nb >= *k) { /* Use unblocked code */ NUMlapack_dorml2 (side, trans, m, n, k, &a[a_offset], lda, &tau[1], &c__[c_offset], ldc, &work[1], &iinfo); } else { /* Use blocked code */ if (left && notran || !left && !notran) { i1 = 1; i2 = *k; i3 = nb; } else { i1 = (*k - 1) / nb * nb + 1; i2 = 1; i3 = -nb; } if (left) { ni = *n; jc = 1; } else { mi = *m; ic = 1; } if (notran) { * (unsigned char *) transt = 'T'; } else { * (unsigned char *) transt = 'N'; } i__1 = i2; i__2 = i3; for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) { /* Computing MIN */ i__4 = nb, i__5 = *k - i__ + 1; ib = MIN (i__4, i__5); /* Form the triangular factor of the block reflector H = H(i) H(i+1) . . . H(i+ib-1) */ i__4 = nq - i__ + 1; NUMlapack_dlarft ("Forward", "Rowwise", &i__4, &ib, &a_ref (i__, i__), lda, &tau[i__], t, &c__65); if (left) { /* H or H' is applied to C(i:m,1:n) */ mi = *m - i__ + 1; ic = i__; } else { /* H or H' is applied to C(1:m,i:n) */ ni = *n - i__ + 1; jc = i__; } /* Apply H or H' */ NUMlapack_dlarfb (side, transt, "Forward", "Rowwise", &mi, &ni, &ib, &a_ref (i__, i__), lda, t, &c__65, &c___ref (ic, jc), ldc, &work[1], &ldwork); /* L10: */ } } work[1] = (double) lwkopt; return 0; } /* NUMlapack_dormlq */ int NUMlapack_dormqr (const char *side, const char *trans, long *m, long *n, long *k, double *a, long *lda, double *tau, double *c__, long *ldc, double *work, long *lwork, long *info) { /* Table of constant values */ static long c__1 = 1; static long c_n1 = -1; static long c__2 = 2; static long c__65 = 65; /* System generated locals */ char *a__1[2]; long a_dim1, a_offset, c_dim1, c_offset, i__1, i__2, i__3[2], i__4, i__5; char ch__1[2]; /* Local variables */ static long left; static long i__; static double t[4160] /* was [65][64] */ ; static long nbmin, iinfo, i1, i2, i3; static long ib, ic, jc, nb, mi, ni; static long nq, nw; static long notran; static long ldwork, lwkopt; static long lquery; static long iws; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --tau; c_dim1 = *ldc; c_offset = 1 + c_dim1 * 1; c__ -= c_offset; --work; /* Function Body */ *info = 0; left = lsame_ (side, "L"); notran = lsame_ (trans, "N"); lquery = *lwork == -1; /* NQ is the order of Q and NW is the minimum dimension of WORK */ if (left) { nq = *m; nw = *n; } else { nq = *n; nw = *m; } if (!left && !lsame_ (side, "R")) { *info = -1; } else if (!notran && !lsame_ (trans, "T")) { *info = -2; } else if (*m < 0) { *info = -3; } else if (*n < 0) { *info = -4; } else if (*k < 0 || *k > nq) { *info = -5; } else if (*lda < MAX (1, nq)) { *info = -7; } else if (*ldc < MAX (1, *m)) { *info = -10; } else if (*lwork < MAX (1, nw) && !lquery) { *info = -12; } if (*info == 0) { /* Determine the block size. NB may be at most NBMAX, where NBMAX is used to define the local array T. Computing MIN Writing concatenation */ i__3[0] = 1, a__1[0] = (char *) side; i__3[1] = 1, a__1[1] = (char *) trans; s_cat (ch__1, (const char **) a__1, i__3, &c__2, 2); i__1 = 64, i__2 = NUMlapack_ilaenv (&c__1, "DORMQR", ch__1, m, n, k, &c_n1, 6, 2); nb = MIN (i__1, i__2); lwkopt = MAX (1, nw) * nb; work[1] = (double) lwkopt; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DORMQR", &i__1); return 0; } else if (lquery) { return 0; } /* Quick return if possible */ if (*m == 0 || *n == 0 || *k == 0) { work[1] = 1.; return 0; } nbmin = 2; ldwork = nw; if (nb > 1 && nb < *k) { iws = nw * nb; if (*lwork < iws) { nb = *lwork / ldwork; /* Computing MAX Writing concatenation */ i__3[0] = 1, a__1[0] = (char *) side; i__3[1] = 1, a__1[1] = (char *) trans; s_cat (ch__1, (const char **) a__1, i__3, &c__2, 2); i__1 = 2, i__2 = NUMlapack_ilaenv (&c__2, "DORMQR", ch__1, m, n, k, &c_n1, 6, 2); nbmin = MAX (i__1, i__2); } } else { iws = nw; } if (nb < nbmin || nb >= *k) { /* Use unblocked code */ NUMlapack_dorm2r (side, trans, m, n, k, &a[a_offset], lda, &tau[1], &c__[c_offset], ldc, &work[1], &iinfo); } else { /* Use blocked code */ if (left && !notran || !left && notran) { i1 = 1; i2 = *k; i3 = nb; } else { i1 = (*k - 1) / nb * nb + 1; i2 = 1; i3 = -nb; } if (left) { ni = *n; jc = 1; } else { mi = *m; ic = 1; } i__1 = i2; i__2 = i3; for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) { /* Computing MIN */ i__4 = nb, i__5 = *k - i__ + 1; ib = MIN (i__4, i__5); /* Form the triangular factor of the block reflector H = H(i) H(i+1) . . . H(i+ib-1) */ i__4 = nq - i__ + 1; NUMlapack_dlarft ("Forward", "Columnwise", &i__4, &ib, &a_ref (i__, i__), lda, &tau[i__], t, &c__65); if (left) { /* H or H' is applied to C(i:m,1:n) */ mi = *m - i__ + 1; ic = i__; } else { /* H or H' is applied to C(1:m,i:n) */ ni = *n - i__ + 1; jc = i__; } /* Apply H or H' */ NUMlapack_dlarfb (side, trans, "Forward", "Columnwise", &mi, &ni, &ib, &a_ref (i__, i__), lda, t, &c__65, &c___ref (ic, jc), ldc, &work[1], &ldwork); /* L10: */ } } work[1] = (double) lwkopt; return 0; } /* NUMlapack_dormqr */ int NUMlapack_dormr2 (const char *side, const char *trans, long *m, long *n, long *k, double *a, long *lda, double *tau, double *c__, long *ldc, double *work, long *info) { /* System generated locals */ long a_dim1, a_offset, c_dim1, c_offset, i__1, i__2; /* Local variables */ static long left; static long i__; static long i1, i2, i3, mi, ni, nq; static long notran; static double aii; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --tau; c_dim1 = *ldc; c_offset = 1 + c_dim1 * 1; c__ -= c_offset; --work; /* Function Body */ *info = 0; left = lsame_ (side, "L"); notran = lsame_ (trans, "N"); /* NQ is the order of Q */ if (left) { nq = *m; } else { nq = *n; } if (!left && !lsame_ (side, "R")) { *info = -1; } else if (!notran && !lsame_ (trans, "T")) { *info = -2; } else if (*m < 0) { *info = -3; } else if (*n < 0) { *info = -4; } else if (*k < 0 || *k > nq) { *info = -5; } else if (*lda < MAX (1, *k)) { *info = -7; } else if (*ldc < MAX (1, *m)) { *info = -10; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DORMR2", &i__1); return 0; } /* Quick return if possible */ if (*m == 0 || *n == 0 || *k == 0) { return 0; } if (left && !notran || !left && notran) { i1 = 1; i2 = *k; i3 = 1; } else { i1 = *k; i2 = 1; i3 = -1; } if (left) { ni = *n; } else { mi = *m; } i__1 = i2; i__2 = i3; for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) { if (left) { /* H(i) is applied to C(1:m-k+i,1:n) */ mi = *m - *k + i__; } else { /* H(i) is applied to C(1:m,1:n-k+i) */ ni = *n - *k + i__; } /* Apply H(i) */ aii = a_ref (i__, nq - *k + i__); a_ref (i__, nq - *k + i__) = 1.; NUMlapack_dlarf (side, &mi, &ni, &a_ref (i__, 1), lda, &tau[i__], &c__[c_offset], ldc, &work[1]); a_ref (i__, nq - *k + i__) = aii; /* L10: */ } return 0; } /* NUMlapack_dormr2 */ int NUMlapack_dpotf2 (const char *uplo, long *n, double *a, long *lda, long *info) { /* Table of constant values */ static double c_b10 = -1.; static double c_b12 = 1.; /* System generated locals */ long a_dim1, a_offset, i__1, i__2, i__3; double d__1; /* Local variables */ static long j; static int upper; static double ajj; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; /* Function Body */ *info = 0; upper = lsame_ (uplo, "U"); if (!upper && !lsame_ (uplo, "L")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < MAX (1, *n)) { *info = -4; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DPOTF2", &i__1); return 0; } /* Quick return if possible */ if (*n == 0) { return 0; } if (upper) { /* Compute the Cholesky factorization A = U'*U. */ i__1 = *n; for (j = 1; j <= i__1; ++j) { /* Compute U(J,J) and test for non-positive-definiteness. */ i__2 = j - 1; ajj = a_ref (j, j) - NUMblas_ddot (&i__2, &a_ref (1, j), &c__1, &a_ref (1, j), &c__1); if (ajj <= 0.) { a_ref (j, j) = ajj; goto L30; } ajj = sqrt (ajj); a_ref (j, j) = ajj; /* Compute elements J+1:N of row J. */ if (j < *n) { i__2 = j - 1; i__3 = *n - j; NUMblas_dgemv ("Transpose", &i__2, &i__3, &c_b10, &a_ref (1, j + 1), lda, &a_ref (1, j), &c__1, &c_b12, &a_ref (j, j + 1), lda); i__2 = *n - j; d__1 = 1. / ajj; NUMblas_dscal (&i__2, &d__1, &a_ref (j, j + 1), lda); } /* L10: */ } } else { /* Compute the Cholesky factorization A = L*L'. */ i__1 = *n; for (j = 1; j <= i__1; ++j) { /* Compute L(J,J) and test for non-positive-definiteness. */ i__2 = j - 1; ajj = a_ref (j, j) - NUMblas_ddot (&i__2, &a_ref (j, 1), lda, &a_ref (j, 1), lda); if (ajj <= 0.) { a_ref (j, j) = ajj; goto L30; } ajj = sqrt (ajj); a_ref (j, j) = ajj; /* Compute elements J+1:N of column J. */ if (j < *n) { i__2 = *n - j; i__3 = j - 1; NUMblas_dgemv ("No transpose", &i__2, &i__3, &c_b10, &a_ref (j + 1, 1), lda, &a_ref (j, 1), lda, &c_b12, &a_ref (j + 1, j), &c__1); i__2 = *n - j; d__1 = 1. / ajj; NUMblas_dscal (&i__2, &d__1, &a_ref (j + 1, j), &c__1); } /* L20: */ } } goto L40; L30: *info = j; L40: return 0; } /* NUMlapack_dpotf2_ */ int NUMlapack_drscl (long *n, double *sa, double *sx, long *incx) { static double cden; static long done; static double cnum, cden1, cnum1; static double bignum, smlnum, mul; --sx; /* Function Body */ if (*n <= 0) { return 0; } /* Get machine parameters */ smlnum = NUMblas_dlamch ("S"); bignum = 1. / smlnum; NUMlapack_dlabad (&smlnum, &bignum); /* Initialize the denominator to SA and the numerator to 1. */ cden = *sa; cnum = 1.; L10: cden1 = cden * smlnum; cnum1 = cnum / bignum; if (fabs (cden1) > fabs (cnum) && cnum != 0.) { /* Pre-multiply X by SMLNUM if CDEN is large compared to CNUM. */ mul = smlnum; done = FALSE; cden = cden1; } else if (fabs (cnum1) > fabs (cden)) { /* Pre-multiply X by BIGNUM if CDEN is small compared to CNUM. */ mul = bignum; done = FALSE; cnum = cnum1; } else { /* Multiply X by CNUM / CDEN and return. */ mul = cnum / cden; done = TRUE; } /* Scale the vector X by MUL */ NUMblas_dscal (n, &mul, &sx[1], incx); if (!done) { goto L10; } return 0; } /* NUMlapack_drscl */ #define z___ref(a_1,a_2) z__[(a_2)*z_dim1 + a_1] int NUMlapack_dsteqr (const char *compz, long *n, double *d__, double *e, double *z__, long *ldz, double *work, long *info) { /* Table of constant values */ static double c_b9 = 0.; static double c_b10 = 1.; static long c__0 = 0; static long c__1 = 1; static long c__2 = 2; /* System generated locals */ long z_dim1, z_offset, i__1, i__2; double d__1, d__2; /* Local variables */ static long lend, jtot; static double b, c__, f, g; static long i__, j, k, l, m; static double p, r__, s; static double anorm; static long l1; static long lendm1, lendp1; static long ii; static long mm, iscale; static double safmin; static double safmax; static long lendsv; static double ssfmin; static long nmaxit, icompz; static double ssfmax; static long lm1, mm1, nm1; static double rt1, rt2, eps; static long lsv; static double tst, eps2; --d__; --e; z_dim1 = *ldz; z_offset = 1 + z_dim1 * 1; z__ -= z_offset; --work; /* Function Body */ *info = 0; if (lsame_ (compz, "N")) { icompz = 0; } else if (lsame_ (compz, "V")) { icompz = 1; } else if (lsame_ (compz, "I")) { icompz = 2; } else { icompz = -1; } if (icompz < 0) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*ldz < 1 || icompz > 0 && *ldz < MAX (1, *n)) { *info = -6; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DSTEQR", &i__1); return 0; } /* Quick return if possible */ if (*n == 0) { return 0; } if (*n == 1) { if (icompz == 2) { z___ref (1, 1) = 1.; } return 0; } /* Determine the unit roundoff and over/underflow thresholds. */ eps = NUMblas_dlamch ("E"); /* Computing 2nd power */ d__1 = eps; eps2 = d__1 * d__1; safmin = NUMblas_dlamch ("S"); safmax = 1. / safmin; ssfmax = sqrt (safmax) / 3.; ssfmin = sqrt (safmin) / eps2; /* Compute the eigenvalues and eigenvectors of the tridiagonal matrix. */ if (icompz == 2) { NUMlapack_dlaset ("Full", n, n, &c_b9, &c_b10, &z__[z_offset], ldz); } nmaxit = *n * 30; jtot = 0; /* Determine where the matrix splits and choose QL or QR iteration for each block, according to whether top or bottom diagonal element is smaller. */ l1 = 1; nm1 = *n - 1; L10: if (l1 > *n) { goto L160; } if (l1 > 1) { e[l1 - 1] = 0.; } if (l1 <= nm1) { i__1 = nm1; for (m = l1; m <= i__1; ++m) { tst = (d__1 = e[m], fabs (d__1)); if (tst == 0.) { goto L30; } if (tst <= sqrt ( (d__1 = d__[m], fabs (d__1))) * sqrt ( (d__2 = d__[m + 1], fabs (d__2))) * eps) { e[m] = 0.; goto L30; } /* L20: */ } } m = *n; L30: l = l1; lsv = l; lend = m; lendsv = lend; l1 = m + 1; if (lend == l) { goto L10; } /* Scale submatrix in rows and columns L to LEND */ i__1 = lend - l + 1; anorm = NUMlapack_dlanst ("I", &i__1, &d__[l], &e[l]); iscale = 0; if (anorm == 0.) { goto L10; } if (anorm > ssfmax) { iscale = 1; i__1 = lend - l + 1; NUMlapack_dlascl ("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &d__[l], n, info); i__1 = lend - l; NUMlapack_dlascl ("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &e[l], n, info); } else if (anorm < ssfmin) { iscale = 2; i__1 = lend - l + 1; NUMlapack_dlascl ("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &d__[l], n, info); i__1 = lend - l; NUMlapack_dlascl ("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &e[l], n, info); } /* Choose between QL and QR iteration */ if ( (d__1 = d__[lend], fabs (d__1)) < (d__2 = d__[l], fabs (d__2))) { lend = lsv; l = lendsv; } if (lend > l) { /* QL Iteration Look for small subdiagonal element. */ L40: if (l != lend) { lendm1 = lend - 1; i__1 = lendm1; for (m = l; m <= i__1; ++m) { /* Computing 2nd power */ d__2 = (d__1 = e[m], fabs (d__1)); tst = d__2 * d__2; if (tst <= eps2 * (d__1 = d__[m], fabs (d__1)) * (d__2 = d__[m + 1], fabs (d__2)) + safmin) { goto L60; } /* L50: */ } } m = lend; L60: if (m < lend) { e[m] = 0.; } p = d__[l]; if (m == l) { goto L80; } /* If remaining matrix is 2-by-2, use DLAE2 or SLAEV2 to compute its eigensystem. */ if (m == l + 1) { if (icompz > 0) { NUMlapack_dlaev2 (&d__[l], &e[l], &d__[l + 1], &rt1, &rt2, &c__, &s); work[l] = c__; work[*n - 1 + l] = s; NUMlapack_dlasr ("R", "V", "B", n, &c__2, &work[l], &work[*n - 1 + l], &z___ref (1, l), ldz); } else { NUMlapack_dlae2 (&d__[l], &e[l], &d__[l + 1], &rt1, &rt2); } d__[l] = rt1; d__[l + 1] = rt2; e[l] = 0.; l += 2; if (l <= lend) { goto L40; } goto L140; } if (jtot == nmaxit) { goto L140; } ++jtot; /* Form shift. */ g = (d__[l + 1] - p) / (e[l] * 2.); r__ = NUMlapack_dlapy2 (&g, &c_b10); g = d__[m] - p + e[l] / (g + d_sign (&r__, &g)); s = 1.; c__ = 1.; p = 0.; /* Inner loop */ mm1 = m - 1; i__1 = l; for (i__ = mm1; i__ >= i__1; --i__) { f = s * e[i__]; b = c__ * e[i__]; NUMlapack_dlartg (&g, &f, &c__, &s, &r__); if (i__ != m - 1) { e[i__ + 1] = r__; } g = d__[i__ + 1] - p; r__ = (d__[i__] - g) * s + c__ * 2. * b; p = s * r__; d__[i__ + 1] = g + p; g = c__ * r__ - b; /* If eigenvectors are desired, then save rotations. */ if (icompz > 0) { work[i__] = c__; work[*n - 1 + i__] = -s; } /* L70: */ } /* If eigenvectors are desired, then apply saved rotations. */ if (icompz > 0) { mm = m - l + 1; NUMlapack_dlasr ("R", "V", "B", n, &mm, &work[l], &work[*n - 1 + l], &z___ref (1, l), ldz); } d__[l] -= p; e[l] = g; goto L40; /* Eigenvalue found. */ L80: d__[l] = p; ++l; if (l <= lend) { goto L40; } goto L140; } else { /* QR Iteration Look for small superdiagonal element. */ L90: if (l != lend) { lendp1 = lend + 1; i__1 = lendp1; for (m = l; m >= i__1; --m) { /* Computing 2nd power */ d__2 = (d__1 = e[m - 1], fabs (d__1)); tst = d__2 * d__2; if (tst <= eps2 * (d__1 = d__[m], fabs (d__1)) * (d__2 = d__[m - 1], fabs (d__2)) + safmin) { goto L110; } /* L100: */ } } m = lend; L110: if (m > lend) { e[m - 1] = 0.; } p = d__[l]; if (m == l) { goto L130; } /* If remaining matrix is 2-by-2, use DLAE2 or SLAEV2 to compute its eigensystem. */ if (m == l - 1) { if (icompz > 0) { NUMlapack_dlaev2 (&d__[l - 1], &e[l - 1], &d__[l], &rt1, &rt2, &c__, &s); work[m] = c__; work[*n - 1 + m] = s; NUMlapack_dlasr ("R", "V", "F", n, &c__2, &work[m], &work[*n - 1 + m], &z___ref (1, l - 1), ldz); } else { NUMlapack_dlae2 (&d__[l - 1], &e[l - 1], &d__[l], &rt1, &rt2); } d__[l - 1] = rt1; d__[l] = rt2; e[l - 1] = 0.; l += -2; if (l >= lend) { goto L90; } goto L140; } if (jtot == nmaxit) { goto L140; } ++jtot; /* Form shift. */ g = (d__[l - 1] - p) / (e[l - 1] * 2.); r__ = NUMlapack_dlapy2 (&g, &c_b10); g = d__[m] - p + e[l - 1] / (g + d_sign (&r__, &g)); s = 1.; c__ = 1.; p = 0.; /* Inner loop */ lm1 = l - 1; i__1 = lm1; for (i__ = m; i__ <= i__1; ++i__) { f = s * e[i__]; b = c__ * e[i__]; NUMlapack_dlartg (&g, &f, &c__, &s, &r__); if (i__ != m) { e[i__ - 1] = r__; } g = d__[i__] - p; r__ = (d__[i__ + 1] - g) * s + c__ * 2. * b; p = s * r__; d__[i__] = g + p; g = c__ * r__ - b; /* If eigenvectors are desired, then save rotations. */ if (icompz > 0) { work[i__] = c__; work[*n - 1 + i__] = s; } /* L120: */ } /* If eigenvectors are desired, then apply saved rotations. */ if (icompz > 0) { mm = l - m + 1; NUMlapack_dlasr ("R", "V", "F", n, &mm, &work[m], &work[*n - 1 + m], &z___ref (1, m), ldz); } d__[l] -= p; e[lm1] = g; goto L90; /* Eigenvalue found. */ L130: d__[l] = p; --l; if (l >= lend) { goto L90; } goto L140; } /* Undo scaling if necessary */ L140: if (iscale == 1) { i__1 = lendsv - lsv + 1; NUMlapack_dlascl ("G", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &d__[lsv], n, info); i__1 = lendsv - lsv; NUMlapack_dlascl ("G", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &e[lsv], n, info); } else if (iscale == 2) { i__1 = lendsv - lsv + 1; NUMlapack_dlascl ("G", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &d__[lsv], n, info); i__1 = lendsv - lsv; NUMlapack_dlascl ("G", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &e[lsv], n, info); } /* Check for no convergence to an eigenvalue after a total of N*MAXIT iterations. */ if (jtot < nmaxit) { goto L10; } i__1 = *n - 1; for (i__ = 1; i__ <= i__1; ++i__) { if (e[i__] != 0.) { ++ (*info); } /* L150: */ } goto L190; /* Order eigenvalues and eigenvectors. */ L160: if (icompz == 0) { /* Use Quick Sort */ NUMlapack_dlasrt ("I", n, &d__[1], info); } else { /* Use Selection Sort to minimize swaps of eigenvectors */ i__1 = *n; for (ii = 2; ii <= i__1; ++ii) { i__ = ii - 1; k = i__; p = d__[i__]; i__2 = *n; for (j = ii; j <= i__2; ++j) { if (d__[j] < p) { k = j; p = d__[j]; } /* L170: */ } if (k != i__) { d__[k] = d__[i__]; d__[i__] = p; NUMblas_dswap (n, &z___ref (1, i__), &c__1, &z___ref (1, k), &c__1); } /* L180: */ } } L190: return 0; } /* NUMlapack_dsteqr */ #undef z___ref int NUMlapack_dsterf (long *n, double *d__, double *e, long *info) { /* Table of constant values */ static long c__0 = 0; static long c__1 = 1; static double c_b32 = 1.; /* System generated locals */ long i__1; double d__1, d__2, d__3; /* Local variables */ static double oldc; static long lend, jtot; static double c__; static long i__, l, m; static double p, gamma, r__, s, alpha, sigma, anorm; static long l1; static double bb; static long iscale; static double oldgam, safmin; static double safmax; static long lendsv; static double ssfmin; static long nmaxit; static double ssfmax, rt1, rt2, eps, rte; static long lsv; static double eps2; --e; --d__; /* Function Body */ *info = 0; /* Quick return if possible */ if (*n < 0) { *info = -1; i__1 = - (*info); xerbla_ ("DSTERF", &i__1); return 0; } if (*n <= 1) { return 0; } /* Determine the unit roundoff for this environment. */ eps = NUMblas_dlamch ("E"); /* Computing 2nd power */ d__1 = eps; eps2 = d__1 * d__1; safmin = NUMblas_dlamch ("S"); safmax = 1. / safmin; ssfmax = sqrt (safmax) / 3.; ssfmin = sqrt (safmin) / eps2; /* Compute the eigenvalues of the tridiagonal matrix. */ nmaxit = *n * 30; sigma = 0.; jtot = 0; /* Determine where the matrix splits and choose QL or QR iteration for each block, according to whether top or bottom diagonal element is smaller. */ l1 = 1; L10: if (l1 > *n) { goto L170; } if (l1 > 1) { e[l1 - 1] = 0.; } i__1 = *n - 1; for (m = l1; m <= i__1; ++m) { if ( (d__3 = e[m], fabs (d__3)) <= sqrt ( (d__1 = d__[m], fabs (d__1))) * sqrt ( (d__2 = d__[m + 1], fabs (d__2))) * eps) { e[m] = 0.; goto L30; } /* L20: */ } m = *n; L30: l = l1; lsv = l; lend = m; lendsv = lend; l1 = m + 1; if (lend == l) { goto L10; } /* Scale submatrix in rows and columns L to LEND */ i__1 = lend - l + 1; anorm = NUMlapack_dlanst ("I", &i__1, &d__[l], &e[l]); iscale = 0; if (anorm > ssfmax) { iscale = 1; i__1 = lend - l + 1; NUMlapack_dlascl ("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &d__[l], n, info); i__1 = lend - l; NUMlapack_dlascl ("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &e[l], n, info); } else if (anorm < ssfmin) { iscale = 2; i__1 = lend - l + 1; NUMlapack_dlascl ("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &d__[l], n, info); i__1 = lend - l; NUMlapack_dlascl ("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &e[l], n, info); } i__1 = lend - 1; for (i__ = l; i__ <= i__1; ++i__) { /* Computing 2nd power */ d__1 = e[i__]; e[i__] = d__1 * d__1; /* L40: */ } /* Choose between QL and QR iteration */ if ( (d__1 = d__[lend], fabs (d__1)) < (d__2 = d__[l], fabs (d__2))) { lend = lsv; l = lendsv; } if (lend >= l) { /* QL Iteration Look for small subdiagonal element. */ L50: if (l != lend) { i__1 = lend - 1; for (m = l; m <= i__1; ++m) { if ( (d__2 = e[m], fabs (d__2)) <= eps2 * (d__1 = d__[m] * d__[m + 1], fabs (d__1))) { goto L70; } /* L60: */ } } m = lend; L70: if (m < lend) { e[m] = 0.; } p = d__[l]; if (m == l) { goto L90; } /* If remaining matrix is 2 by 2, use DLAE2 to compute its eigenvalues. */ if (m == l + 1) { rte = sqrt (e[l]); NUMlapack_dlae2 (&d__[l], &rte, &d__[l + 1], &rt1, &rt2); d__[l] = rt1; d__[l + 1] = rt2; e[l] = 0.; l += 2; if (l <= lend) { goto L50; } goto L150; } if (jtot == nmaxit) { goto L150; } ++jtot; /* Form shift. */ rte = sqrt (e[l]); sigma = (d__[l + 1] - p) / (rte * 2.); r__ = NUMlapack_dlapy2 (&sigma, &c_b32); sigma = p - rte / (sigma + d_sign (&r__, &sigma)); c__ = 1.; s = 0.; gamma = d__[m] - sigma; p = gamma * gamma; /* Inner loop */ i__1 = l; for (i__ = m - 1; i__ >= i__1; --i__) { bb = e[i__]; r__ = p + bb; if (i__ != m - 1) { e[i__ + 1] = s * r__; } oldc = c__; c__ = p / r__; s = bb / r__; oldgam = gamma; alpha = d__[i__]; gamma = c__ * (alpha - sigma) - s * oldgam; d__[i__ + 1] = oldgam + (alpha - gamma); if (c__ != 0.) { p = gamma * gamma / c__; } else { p = oldc * bb; } /* L80: */ } e[l] = s * p; d__[l] = sigma + gamma; goto L50; /* Eigenvalue found. */ L90: d__[l] = p; ++l; if (l <= lend) { goto L50; } goto L150; } else { /* QR Iteration Look for small superdiagonal element. */ L100: i__1 = lend + 1; for (m = l; m >= i__1; --m) { if ( (d__2 = e[m - 1], fabs (d__2)) <= eps2 * (d__1 = d__[m] * d__[m - 1], fabs (d__1))) { goto L120; } /* L110: */ } m = lend; L120: if (m > lend) { e[m - 1] = 0.; } p = d__[l]; if (m == l) { goto L140; } /* If remaining matrix is 2 by 2, use DLAE2 to compute its eigenvalues. */ if (m == l - 1) { rte = sqrt (e[l - 1]); NUMlapack_dlae2 (&d__[l], &rte, &d__[l - 1], &rt1, &rt2); d__[l] = rt1; d__[l - 1] = rt2; e[l - 1] = 0.; l += -2; if (l >= lend) { goto L100; } goto L150; } if (jtot == nmaxit) { goto L150; } ++jtot; /* Form shift. */ rte = sqrt (e[l - 1]); sigma = (d__[l - 1] - p) / (rte * 2.); r__ = NUMlapack_dlapy2 (&sigma, &c_b32); sigma = p - rte / (sigma + d_sign (&r__, &sigma)); c__ = 1.; s = 0.; gamma = d__[m] - sigma; p = gamma * gamma; /* Inner loop */ i__1 = l - 1; for (i__ = m; i__ <= i__1; ++i__) { bb = e[i__]; r__ = p + bb; if (i__ != m) { e[i__ - 1] = s * r__; } oldc = c__; c__ = p / r__; s = bb / r__; oldgam = gamma; alpha = d__[i__ + 1]; gamma = c__ * (alpha - sigma) - s * oldgam; d__[i__] = oldgam + (alpha - gamma); if (c__ != 0.) { p = gamma * gamma / c__; } else { p = oldc * bb; } /* L130: */ } e[l - 1] = s * p; d__[l] = sigma + gamma; goto L100; /* Eigenvalue found. */ L140: d__[l] = p; --l; if (l >= lend) { goto L100; } goto L150; } /* Undo scaling if necessary */ L150: if (iscale == 1) { i__1 = lendsv - lsv + 1; NUMlapack_dlascl ("G", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &d__[lsv], n, info); } if (iscale == 2) { i__1 = lendsv - lsv + 1; NUMlapack_dlascl ("G", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &d__[lsv], n, info); } /* Check for no convergence to an eigenvalue after a total of N*MAXIT iterations. */ if (jtot < nmaxit) { goto L10; } i__1 = *n - 1; for (i__ = 1; i__ <= i__1; ++i__) { if (e[i__] != 0.) { ++ (*info); } /* L160: */ } goto L180; /* Sort eigenvalues in increasing order. */ L170: NUMlapack_dlasrt ("I", n, &d__[1], info); L180: return 0; } /* NUMlapack_dsterf */ int NUMlapack_dsyev (const char *jobz, const char *uplo, long *n, double *a, long *lda, double *w, double *work, long *lwork, long *info) { /* Table of constant values */ static long c__1 = 1; static long c_n1 = -1; static long c__0 = 0; static double c_b17 = 1.; /* System generated locals */ long a_dim1, a_offset, i__1, i__2; double d__1; /* Local variables */ static long inde; static double anrm; static long imax; static double rmin, rmax; static long lopt; static double sigma; static long iinfo; static long lower, wantz; static long nb; static long iscale; static double safmin; static double bignum; static long indtau; static long indwrk; static long llwork; static double smlnum; static long lwkopt; static long lquery; static double eps; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --w; --work; /* Function Body */ wantz = lsame_ (jobz, "V"); lower = lsame_ (uplo, "L"); lquery = *lwork == -1; *info = 0; if (! (wantz || lsame_ (jobz, "N"))) { *info = -1; } else if (! (lower || lsame_ (uplo, "U"))) { *info = -2; } else if (*n < 0) { *info = -3; } else if (*lda < MAX (1, *n)) { *info = -5; } else { /* if(complicated condition) */ /* Computing MAX */ i__1 = 1, i__2 = *n * 3 - 1; if (*lwork < MAX (i__1, i__2) && !lquery) { *info = -8; } } if (*info == 0) { nb = NUMlapack_ilaenv (&c__1, "DSYTRD", uplo, n, &c_n1, &c_n1, &c_n1, 6, 1); /* Computing MAX */ i__1 = 1, i__2 = (nb + 2) * *n; lwkopt = MAX (i__1, i__2); work[1] = (double) lwkopt; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DSYEV ", &i__1); return 0; } else if (lquery) { return 0; } /* Quick return if possible */ if (*n == 0) { work[1] = 1.; return 0; } if (*n == 1) { w[1] = a_ref (1, 1); work[1] = 3.; if (wantz) { a_ref (1, 1) = 1.; } return 0; } /* Get machine constants. */ safmin = NUMblas_dlamch ("Safe minimum"); eps = NUMblas_dlamch ("Precision"); smlnum = safmin / eps; bignum = 1. / smlnum; rmin = sqrt (smlnum); rmax = sqrt (bignum); /* Scale matrix to allowable range, if necessary. */ anrm = NUMlapack_dlansy ("M", uplo, n, &a[a_offset], lda, &work[1]); iscale = 0; if (anrm > 0. && anrm < rmin) { iscale = 1; sigma = rmin / anrm; } else if (anrm > rmax) { iscale = 1; sigma = rmax / anrm; } if (iscale == 1) { NUMlapack_dlascl (uplo, &c__0, &c__0, &c_b17, &sigma, n, n, &a[a_offset], lda, info); } /* Call DSYTRD to reduce symmetric matrix to tridiagonal form. */ inde = 1; indtau = inde + *n; indwrk = indtau + *n; llwork = *lwork - indwrk + 1; NUMlapack_dsytrd (uplo, n, &a[a_offset], lda, &w[1], &work[inde], &work[indtau], &work[indwrk], &llwork, &iinfo); lopt = (long) ( (*n << 1) + work[indwrk]); /* For eigenvalues only, call DSTERF. For eigenvectors, first call DORGTR to generate the orthogonal matrix, then call DSTEQR. */ if (!wantz) { NUMlapack_dsterf (n, &w[1], &work[inde], info); } else { NUMlapack_dorgtr (uplo, n, &a[a_offset], lda, &work[indtau], &work[indwrk], &llwork, &iinfo); NUMlapack_dsteqr (jobz, n, &w[1], &work[inde], &a[a_offset], lda, &work[indtau], info); } /* If matrix was scaled, then rescale eigenvalues appropriately. */ if (iscale == 1) { if (*info == 0) { imax = *n; } else { imax = *info - 1; } d__1 = 1. / sigma; NUMblas_dscal (&imax, &d__1, &w[1], &c__1); } /* Set WORK(1) to optimal workspace size. */ work[1] = (double) lwkopt; return 0; } /* NUMlapack_dsyev */ int NUMlapack_dsytd2 (const char *uplo, long *n, double *a, long *lda, double *d__, double *e, double *tau, long *info) { /* Table of constant values */ static long c__1 = 1; static double c_b8 = 0.; static double c_b14 = -1.; /* System generated locals */ long a_dim1, a_offset, i__1, i__2, i__3; /* Local variables */ static double taui; static long i__; static double alpha; static long upper; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --d__; --e; --tau; /* Function Body */ *info = 0; upper = lsame_ (uplo, "U"); if (!upper && !lsame_ (uplo, "L")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < MAX (1, *n)) { *info = -4; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DSYTD2", &i__1); return 0; } /* Quick return if possible */ if (*n <= 0) { return 0; } if (upper) { /* Reduce the upper triangle of A */ for (i__ = *n - 1; i__ >= 1; --i__) { /* Generate elementary reflector H(i) = I - tau * v * v' to annihilate A(1:i-1,i+1) */ NUMlapack_dlarfg (&i__, &a_ref (i__, i__ + 1), &a_ref (1, i__ + 1), &c__1, &taui); e[i__] = a_ref (i__, i__ + 1); if (taui != 0.) { /* Apply H(i) from both sides to A(1:i,1:i) */ a_ref (i__, i__ + 1) = 1.; /* Compute x := tau * A * v storing x in TAU(1:i) */ NUMblas_dsymv (uplo, &i__, &taui, &a[a_offset], lda, &a_ref (1, i__ + 1), &c__1, &c_b8, &tau[1], &c__1); /* Compute w := x - 1/2 * tau * (x'*v) * v */ alpha = taui * -.5 * NUMblas_ddot (&i__, &tau[1], &c__1, &a_ref (1, i__ + 1), &c__1); NUMblas_daxpy (&i__, &alpha, &a_ref (1, i__ + 1), &c__1, &tau[1], &c__1); /* Apply the transformation as a rank-2 update: A := A - v * w' - w * v' */ NUMblas_dsyr2 (uplo, &i__, &c_b14, &a_ref (1, i__ + 1), &c__1, &tau[1], &c__1, &a[a_offset], lda); a_ref (i__, i__ + 1) = e[i__]; } d__[i__ + 1] = a_ref (i__ + 1, i__ + 1); tau[i__] = taui; /* L10: */ } d__[1] = a_ref (1, 1); } else { /* Reduce the lower triangle of A */ i__1 = *n - 1; for (i__ = 1; i__ <= i__1; ++i__) { /* Generate elementary reflector H(i) = I - tau * v * v' to annihilate A(i+2:n,i) Computing MIN */ i__2 = i__ + 2; i__3 = *n - i__; NUMlapack_dlarfg (&i__3, &a_ref (i__ + 1, i__), &a_ref (MIN (i__2, *n), i__), &c__1, &taui); e[i__] = a_ref (i__ + 1, i__); if (taui != 0.) { /* Apply H(i) from both sides to A(i+1:n,i+1:n) */ a_ref (i__ + 1, i__) = 1.; /* Compute x := tau * A * v storing y in TAU(i:n-1) */ i__2 = *n - i__; NUMblas_dsymv (uplo, &i__2, &taui, &a_ref (i__ + 1, i__ + 1), lda, &a_ref (i__ + 1, i__), &c__1, &c_b8, &tau[i__], &c__1); /* Compute w := x - 1/2 * tau * (x'*v) * v */ i__2 = *n - i__; alpha = taui * -.5 * NUMblas_ddot (&i__2, &tau[i__], &c__1, &a_ref (i__ + 1, i__), &c__1); i__2 = *n - i__; NUMblas_daxpy (&i__2, &alpha, &a_ref (i__ + 1, i__), &c__1, &tau[i__], &c__1); /* Apply the transformation as a rank-2 update: A := A - v * w' - w * v' */ i__2 = *n - i__; NUMblas_dsyr2 (uplo, &i__2, &c_b14, &a_ref (i__ + 1, i__), &c__1, &tau[i__], &c__1, &a_ref (i__ + 1, i__ + 1), lda); a_ref (i__ + 1, i__) = e[i__]; } d__[i__] = a_ref (i__, i__); tau[i__] = taui; /* L20: */ } d__[*n] = a_ref (*n, *n); } return 0; } /* NUMlapack_dsytd2 */ int NUMlapack_dsytrd (const char *uplo, long *n, double *a, long *lda, double *d__, double *e, double *tau, double *work, long *lwork, long *info) { /* Table of constant values */ static long c__1 = 1; static long c_n1 = -1; static long c__3 = 3; static long c__2 = 2; static double c_b22 = -1.; static double c_b23 = 1.; /* System generated locals */ long a_dim1, a_offset, i__1, i__2, i__3; /* Local variables */ static long i__, j; static long nbmin, iinfo; static long upper; static long nb, kk, nx; static long ldwork, lwkopt; static long lquery; static long iws; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; --d__; --e; --tau; --work; /* Function Body */ *info = 0; upper = lsame_ (uplo, "U"); lquery = *lwork == -1; if (!upper && !lsame_ (uplo, "L")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < MAX (1, *n)) { *info = -4; } else if (*lwork < 1 && !lquery) { *info = -9; } if (*info == 0) { /* Determine the block size. */ nb = NUMlapack_ilaenv (&c__1, "DSYTRD", uplo, n, &c_n1, &c_n1, &c_n1, 6, 1); lwkopt = *n * nb; work[1] = (double) lwkopt; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DSYTRD", &i__1); return 0; } else if (lquery) { return 0; } /* Quick return if possible */ if (*n == 0) { work[1] = 1.; return 0; } nx = *n; iws = 1; if (nb > 1 && nb < *n) { /* Determine when to cross over from blocked to unblocked code (last block is always handled by unblocked code). Computing MAX */ i__1 = nb, i__2 = NUMlapack_ilaenv (&c__3, "DSYTRD", uplo, n, &c_n1, &c_n1, &c_n1, 6, 1); nx = MAX (i__1, i__2); if (nx < *n) { /* Determine if workspace is large enough for blocked code. */ ldwork = *n; iws = ldwork * nb; if (*lwork < iws) { /* Not enough workspace to use optimal NB: determine the minimum value of NB, and reduce NB or force use of unblocked code by setting NX = N. Computing MAX */ i__1 = *lwork / ldwork; nb = MAX (i__1, 1); nbmin = NUMlapack_ilaenv (&c__2, "DSYTRD", uplo, n, &c_n1, &c_n1, &c_n1, 6, 1); if (nb < nbmin) { nx = *n; } } } else { nx = *n; } } else { nb = 1; } if (upper) { /* Reduce the upper triangle of A. Columns 1:kk are handled by the unblocked method. */ kk = *n - (*n - nx + nb - 1) / nb * nb; i__1 = kk + 1; i__2 = -nb; for (i__ = *n - nb + 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) { /* Reduce columns i:i+nb-1 to tridiagonal form and form the matrix W which is needed to update the unreduced part of the matrix */ i__3 = i__ + nb - 1; NUMlapack_dlatrd (uplo, &i__3, &nb, &a[a_offset], lda, &e[1], &tau[1], &work[1], &ldwork); /* Update the unreduced submatrix A(1:i-1,1:i-1), using an update of the form: A := A - V*W' - W*V' */ i__3 = i__ - 1; NUMblas_dsyr2k (uplo, "No transpose", &i__3, &nb, &c_b22, &a_ref (1, i__), lda, &work[1], &ldwork, &c_b23, &a[a_offset], lda); /* Copy superdiagonal elements back into A, and diagonal elements into D */ i__3 = i__ + nb - 1; for (j = i__; j <= i__3; ++j) { a_ref (j - 1, j) = e[j - 1]; d__[j] = a_ref (j, j); /* L10: */ } /* L20: */ } /* Use unblocked code to reduce the last or only block */ NUMlapack_dsytd2 (uplo, &kk, &a[a_offset], lda, &d__[1], &e[1], &tau[1], &iinfo); } else { /* Reduce the lower triangle of A */ i__2 = *n - nx; i__1 = nb; for (i__ = 1; i__1 < 0 ? i__ >= i__2 : i__ <= i__2; i__ += i__1) { /* Reduce columns i:i+nb-1 to tridiagonal form and form the matrix W which is needed to update the unreduced part of the matrix */ i__3 = *n - i__ + 1; NUMlapack_dlatrd (uplo, &i__3, &nb, &a_ref (i__, i__), lda, &e[i__], &tau[i__], &work[1], &ldwork); /* Update the unreduced submatrix A(i+ib:n,i+ib:n), using an update of the form: A := A - V*W' - W*V' */ i__3 = *n - i__ - nb + 1; NUMblas_dsyr2k (uplo, "No transpose", &i__3, &nb, &c_b22, &a_ref (i__ + nb, i__), lda, &work[nb + 1], &ldwork, &c_b23, &a_ref (i__ + nb, i__ + nb), lda); /* Copy subdiagonal elements back into A, and diagonal elements into D */ i__3 = i__ + nb - 1; for (j = i__; j <= i__3; ++j) { a_ref (j + 1, j) = e[j]; d__[j] = a_ref (j, j); /* L30: */ } /* L40: */ } /* Use unblocked code to reduce the last or only block */ i__1 = *n - i__ + 1; NUMlapack_dsytd2 (uplo, &i__1, &a_ref (i__, i__), lda, &d__[i__], &e[i__], &tau[i__], &iinfo); } work[1] = (double) lwkopt; return 0; } /* NUMlapack_dsytrd */ #define b_ref(a_1,a_2) b[(a_2)*b_dim1 + a_1] #define q_ref(a_1,a_2) q[(a_2)*q_dim1 + a_1] #define u_ref(a_1,a_2) u[(a_2)*u_dim1 + a_1] #define v_ref(a_1,a_2) v[(a_2)*v_dim1 + a_1] int NUMlapack_dtgsja (const char *jobu, const char *jobv, const char *jobq, long *m, long *p, long *n, long *k, long *l, double *a, long *lda, double *b, long *ldb, double *tola, double *tolb, double *alpha, double *beta, double *u, long *ldu, double *v, long *ldv, double *q, long *ldq, double *work, long *ncycle, long *info) { /* Table of constant values */ static double c_b13 = 0.; static double c_b14 = 1.; static long c__1 = 1; static double c_b43 = -1.; /* System generated locals */ long a_dim1, a_offset, b_dim1, b_offset, q_dim1, q_offset, u_dim1, u_offset, v_dim1, v_offset, i__1, i__2, i__3, i__4; double d__1; /* Local variables */ static long i__, j; static double gamma; static double a1; static long initq; static double a2, a3, b1; static long initu, initv, wantq, upper; static double b2, b3; static long wantu, wantv; static double error, ssmin; static long kcycle; static double csq, csu, csv, snq, rwk, snu, snv; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; b_dim1 = *ldb; b_offset = 1 + b_dim1 * 1; b -= b_offset; --alpha; --beta; u_dim1 = *ldu; u_offset = 1 + u_dim1 * 1; u -= u_offset; v_dim1 = *ldv; v_offset = 1 + v_dim1 * 1; v -= v_offset; q_dim1 = *ldq; q_offset = 1 + q_dim1 * 1; q -= q_offset; --work; /* Function Body */ initu = lsame_ (jobu, "I"); wantu = initu || lsame_ (jobu, "U"); initv = lsame_ (jobv, "I"); wantv = initv || lsame_ (jobv, "V"); initq = lsame_ (jobq, "I"); wantq = initq || lsame_ (jobq, "Q"); *info = 0; if (! (initu || wantu || lsame_ (jobu, "N"))) { *info = -1; } else if (! (initv || wantv || lsame_ (jobv, "N"))) { *info = -2; } else if (! (initq || wantq || lsame_ (jobq, "N"))) { *info = -3; } else if (*m < 0) { *info = -4; } else if (*p < 0) { *info = -5; } else if (*n < 0) { *info = -6; } else if (*lda < MAX (1, *m)) { *info = -10; } else if (*ldb < MAX (1, *p)) { *info = -12; } else if (*ldu < 1 || wantu && *ldu < *m) { *info = -18; } else if (*ldv < 1 || wantv && *ldv < *p) { *info = -20; } else if (*ldq < 1 || wantq && *ldq < *n) { *info = -22; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DTGSJA", &i__1); return 0; } /* Initialize U, V and Q, if necessary */ if (initu) { NUMlapack_dlaset ("Full", m, m, &c_b13, &c_b14, &u[u_offset], ldu); } if (initv) { NUMlapack_dlaset ("Full", p, p, &c_b13, &c_b14, &v[v_offset], ldv); } if (initq) { NUMlapack_dlaset ("Full", n, n, &c_b13, &c_b14, &q[q_offset], ldq); } /* Loop until convergence */ upper = FALSE; for (kcycle = 1; kcycle <= 40; ++kcycle) { upper = !upper; i__1 = *l - 1; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = *l; for (j = i__ + 1; j <= i__2; ++j) { a1 = 0.; a2 = 0.; a3 = 0.; if (*k + i__ <= *m) { a1 = a_ref (*k + i__, *n - *l + i__); } if (*k + j <= *m) { a3 = a_ref (*k + j, *n - *l + j); } b1 = b_ref (i__, *n - *l + i__); b3 = b_ref (j, *n - *l + j); if (upper) { if (*k + i__ <= *m) { a2 = a_ref (*k + i__, *n - *l + j); } b2 = b_ref (i__, *n - *l + j); } else { if (*k + j <= *m) { a2 = a_ref (*k + j, *n - *l + i__); } b2 = b_ref (j, *n - *l + i__); } NUMlapack_dlags2 (&upper, &a1, &a2, &a3, &b1, &b2, &b3, &csu, &snu, &csv, &snv, &csq, &snq); /* Update (K+I)-th and (K+J)-th rows of matrix A: U'*A */ if (*k + j <= *m) { NUMblas_drot (l, &a_ref (*k + j, *n - *l + 1), lda, &a_ref (*k + i__, *n - *l + 1), lda, &csu, &snu); } /* Update I-th and J-th rows of matrix B: V'*B */ NUMblas_drot (l, &b_ref (j, *n - *l + 1), ldb, &b_ref (i__, *n - *l + 1), ldb, &csv, &snv); /* Update (N-L+I)-th and (N-L+J)-th columns of matrices A and B: A*Q and B*Q Computing MIN */ i__4 = *k + *l; i__3 = MIN (i__4, *m); NUMblas_drot (&i__3, &a_ref (1, *n - *l + j), &c__1, &a_ref (1, *n - *l + i__), &c__1, &csq, &snq); NUMblas_drot (l, &b_ref (1, *n - *l + j), &c__1, &b_ref (1, *n - *l + i__), &c__1, &csq, &snq); if (upper) { if (*k + i__ <= *m) { a_ref (*k + i__, *n - *l + j) = 0.; } b_ref (i__, *n - *l + j) = 0.; } else { if (*k + j <= *m) { a_ref (*k + j, *n - *l + i__) = 0.; } b_ref (j, *n - *l + i__) = 0.; } /* Update orthogonal matrices U, V, Q, if desired. */ if (wantu && *k + j <= *m) { NUMblas_drot (m, &u_ref (1, *k + j), &c__1, &u_ref (1, *k + i__), &c__1, &csu, &snu); } if (wantv) { NUMblas_drot (p, &v_ref (1, j), &c__1, &v_ref (1, i__), &c__1, &csv, &snv); } if (wantq) { NUMblas_drot (n, &q_ref (1, *n - *l + j), &c__1, &q_ref (1, *n - *l + i__), &c__1, &csq, &snq); } /* L10: */ } /* L20: */ } if (!upper) { /* The matrices A13 and B13 were lower triangular at the start of the cycle, and are now upper triangular. Convergence test: test the parallelism of the corresponding rows of A and B. */ error = 0.; /* Computing MIN */ i__2 = *l, i__3 = *m - *k; i__1 = MIN (i__2, i__3); for (i__ = 1; i__ <= i__1; ++i__) { i__2 = *l - i__ + 1; NUMblas_dcopy (&i__2, &a_ref (*k + i__, *n - *l + i__), lda, &work[1], &c__1); i__2 = *l - i__ + 1; NUMblas_dcopy (&i__2, &b_ref (i__, *n - *l + i__), ldb, &work[*l + 1], &c__1); i__2 = *l - i__ + 1; NUMlapack_dlapll (&i__2, &work[1], &c__1, &work[*l + 1], &c__1, &ssmin); error = MAX (error, ssmin); /* L30: */ } if (fabs (error) <= MIN (*tola, *tolb)) { goto L50; } } /* End of cycle loop L40: */ } /* The algorithm has not converged after MAXIT cycles. */ *info = 1; goto L100; L50: /* If ERROR <= MIN(TOLA,TOLB), then the algorithm has converged. Compute the generalized singular value pairs (ALPHA, BETA), and set the triangular matrix R to array A. */ i__1 = *k; for (i__ = 1; i__ <= i__1; ++i__) { alpha[i__] = 1.; beta[i__] = 0.; /* L60: */ } /* Computing MIN */ i__2 = *l, i__3 = *m - *k; i__1 = MIN (i__2, i__3); for (i__ = 1; i__ <= i__1; ++i__) { a1 = a_ref (*k + i__, *n - *l + i__); b1 = b_ref (i__, *n - *l + i__); if (a1 != 0.) { gamma = b1 / a1; /* change sign if necessary */ if (gamma < 0.) { i__2 = *l - i__ + 1; NUMblas_dscal (&i__2, &c_b43, &b_ref (i__, *n - *l + i__), ldb); if (wantv) { NUMblas_dscal (p, &c_b43, &v_ref (1, i__), &c__1); } } d__1 = fabs (gamma); NUMlapack_dlartg (&d__1, &c_b14, &beta[*k + i__], &alpha[*k + i__], &rwk); if (alpha[*k + i__] >= beta[*k + i__]) { i__2 = *l - i__ + 1; d__1 = 1. / alpha[*k + i__]; NUMblas_dscal (&i__2, &d__1, &a_ref (*k + i__, *n - *l + i__), lda); } else { i__2 = *l - i__ + 1; d__1 = 1. / beta[*k + i__]; NUMblas_dscal (&i__2, &d__1, &b_ref (i__, *n - *l + i__), ldb); i__2 = *l - i__ + 1; NUMblas_dcopy (&i__2, &b_ref (i__, *n - *l + i__), ldb, &a_ref (*k + i__, *n - *l + i__), lda); } } else { alpha[*k + i__] = 0.; beta[*k + i__] = 1.; i__2 = *l - i__ + 1; NUMblas_dcopy (&i__2, &b_ref (i__, *n - *l + i__), ldb, &a_ref (*k + i__, *n - *l + i__), lda); } /* L70: */ } /* Post-assignment */ i__1 = *k + *l; for (i__ = *m + 1; i__ <= i__1; ++i__) { alpha[i__] = 0.; beta[i__] = 1.; /* L80: */ } if (*k + *l < *n) { i__1 = *n; for (i__ = *k + *l + 1; i__ <= i__1; ++i__) { alpha[i__] = 0.; beta[i__] = 0.; /* L90: */ } } L100: *ncycle = kcycle; return 0; } /* NUMlapack_dtgsja */ #undef v_ref #undef u_ref #undef q_ref #undef b_ref int NUMlapack_dtrevc (const char *side, const char *howmny, int *select, long *n, double *t, long *ldt, double *vl, long *ldvl, double *vr, long *ldvr, long *mm, long *m, double *work, long *info) { /* Table of constant values */ static int c_false = FALSE; static long c__1 = 1; static double c_b22 = 1.; static double c_b25 = 0.; static long c__2 = 2; static int c_true = TRUE; /* System generated locals */ long t_dim1, t_offset, vl_dim1, vl_offset, vr_dim1, vr_offset, i__1, i__2, i__3; double d__1, d__2, d__3, d__4, d__5, d__6; /* Local variables */ static double beta, emax; static int pair; static int allv; static long ierr; static double unfl, ovfl, smin; static int over; static double vmax; static long jnxt, i__, j, k; static double scale, x[4] /* was [2][2] */ ; static double remax; static int leftv, bothv; static double vcrit; static int somev; static long j1, j2, n2; static double xnorm; static long ii, ki; static long ip, is; static double wi; static double wr; static double bignum; static int rightv; static double smlnum, rec, ulp; #define t_ref(a_1,a_2) t[(a_2)*t_dim1 + a_1] #define x_ref(a_1,a_2) x[(a_2)*2 + a_1 - 3] #define vl_ref(a_1,a_2) vl[(a_2)*vl_dim1 + a_1] #define vr_ref(a_1,a_2) vr[(a_2)*vr_dim1 + a_1] --select; t_dim1 = *ldt; t_offset = 1 + t_dim1 * 1; t -= t_offset; vl_dim1 = *ldvl; vl_offset = 1 + vl_dim1 * 1; vl -= vl_offset; vr_dim1 = *ldvr; vr_offset = 1 + vr_dim1 * 1; vr -= vr_offset; --work; /* Function Body */ bothv = lsame_ (side, "B"); rightv = lsame_ (side, "R") || bothv; leftv = lsame_ (side, "L") || bothv; allv = lsame_ (howmny, "A"); over = lsame_ (howmny, "B"); somev = lsame_ (howmny, "S"); *info = 0; if (!rightv && !leftv) { *info = -1; } else if (!allv && !over && !somev) { *info = -2; } else if (*n < 0) { *info = -4; } else if (*ldt < MAX (1, *n)) { *info = -6; } else if (*ldvl < 1 || leftv && *ldvl < *n) { *info = -8; } else if (*ldvr < 1 || rightv && *ldvr < *n) { *info = -10; } else { /* Set M to the number of columns required to store the selected eigenvectors, standardize the array SELECT if necessary, and test MM. */ if (somev) { *m = 0; pair = FALSE; i__1 = *n; for (j = 1; j <= i__1; ++j) { if (pair) { pair = FALSE; select[j] = FALSE; } else { if (j < *n) { if (t_ref (j + 1, j) == 0.) { if (select[j]) { ++ (*m); } } else { pair = TRUE; if (select[j] || select[j + 1]) { select[j] = TRUE; *m += 2; } } } else { if (select[*n]) { ++ (*m); } } } /* L10: */ } } else { *m = *n; } if (*mm < *m) { *info = -11; } } if (*info != 0) { i__1 = - (*info); xerbla_ ("NUMlapack_dtrevc", &i__1); return 0; } /* Quick return if possible. */ if (*n == 0) { return 0; } /* Set the constants to control overflow. */ unfl = NUMblas_dlamch ("Safe minimum"); ovfl = 1. / unfl; NUMlapack_dlabad (&unfl, &ovfl); ulp = NUMblas_dlamch ("Precision"); smlnum = unfl * (*n / ulp); bignum = (1. - ulp) / smlnum; /* Compute 1-norm of each column of strictly upper triangular part of T to control overflow in triangular solver. */ work[1] = 0.; i__1 = *n; for (j = 2; j <= i__1; ++j) { work[j] = 0.; i__2 = j - 1; for (i__ = 1; i__ <= i__2; ++i__) { work[j] += (d__1 = t_ref (i__, j), fabs (d__1)); /* L20: */ } /* L30: */ } /* Index IP is used to specify the real or complex eigenvalue: IP = 0, real eigenvalue, 1, first of conjugate complex pair: (wr,wi) -1, second of conjugate complex pair: (wr,wi) */ n2 = *n << 1; if (rightv) { /* Compute right eigenvectors. */ ip = 0; is = *m; for (ki = *n; ki >= 1; --ki) { if (ip == 1) { goto L130; } if (ki == 1) { goto L40; } if (t_ref (ki, ki - 1) == 0.) { goto L40; } ip = -1; L40: if (somev) { if (ip == 0) { if (!select[ki]) { goto L130; } } else { if (!select[ki - 1]) { goto L130; } } } /* Compute the KI-th eigenvalue (WR,WI). */ wr = t_ref (ki, ki); wi = 0.; if (ip != 0) { wi = sqrt ( (d__1 = t_ref (ki, ki - 1), fabs (d__1))) * sqrt ( (d__2 = t_ref (ki - 1, ki), fabs (d__2))); } /* Computing MAX */ d__1 = ulp * (fabs (wr) + fabs (wi)); smin = MAX (d__1, smlnum); if (ip == 0) { /* Real right eigenvector */ work[ki + *n] = 1.; /* Form right-hand side */ i__1 = ki - 1; for (k = 1; k <= i__1; ++k) { work[k + *n] = -t_ref (k, ki); /* L50: */ } /* Solve the upper quasi-triangular system: (T(1:KI-1,1:KI-1) - WR)*X = SCALE*WORK. */ jnxt = ki - 1; for (j = ki - 1; j >= 1; --j) { if (j > jnxt) { goto L60; } j1 = j; j2 = j; jnxt = j - 1; if (j > 1) { if (t_ref (j, j - 1) != 0.) { j1 = j - 1; jnxt = j - 2; } } if (j1 == j2) { /* 1-by-1 diagonal block */ NUMlapack_dlaln2 (&c_false, &c__1, &c__1, &smin, &c_b22, &t_ref (j, j), ldt, &c_b22, &c_b22, &work[j + *n], n, &wr, &c_b25, x, &c__2, &scale, &xnorm, &ierr); /* Scale X(1,1) to avoid overflow when updating the right-hand side. */ if (xnorm > 1.) { if (work[j] > bignum / xnorm) { x_ref (1, 1) = x_ref (1, 1) / xnorm; scale /= xnorm; } } /* Scale if necessary */ if (scale != 1.) { NUMblas_dscal (&ki, &scale, &work[*n + 1], &c__1); } work[j + *n] = x_ref (1, 1); /* Update right-hand side */ i__1 = j - 1; d__1 = -x_ref (1, 1); NUMblas_daxpy (&i__1, &d__1, &t_ref (1, j), &c__1, &work[*n + 1], &c__1); } else { /* 2-by-2 diagonal block */ NUMlapack_dlaln2 (&c_false, &c__2, &c__1, &smin, &c_b22, &t_ref (j - 1, j - 1), ldt, &c_b22, &c_b22, &work[j - 1 + *n], n, &wr, &c_b25, x, &c__2, &scale, &xnorm, &ierr); /* Scale X(1,1) and X(2,1) to avoid overflow when updating the right-hand side. */ if (xnorm > 1.) { /* Computing MAX */ d__1 = work[j - 1], d__2 = work[j]; beta = MAX (d__1, d__2); if (beta > bignum / xnorm) { x_ref (1, 1) = x_ref (1, 1) / xnorm; x_ref (2, 1) = x_ref (2, 1) / xnorm; scale /= xnorm; } } /* Scale if necessary */ if (scale != 1.) { NUMblas_dscal (&ki, &scale, &work[*n + 1], &c__1); } work[j - 1 + *n] = x_ref (1, 1); work[j + *n] = x_ref (2, 1); /* Update right-hand side */ i__1 = j - 2; d__1 = -x_ref (1, 1); NUMblas_daxpy (&i__1, &d__1, &t_ref (1, j - 1), &c__1, &work[*n + 1], &c__1); i__1 = j - 2; d__1 = -x_ref (2, 1); NUMblas_daxpy (&i__1, &d__1, &t_ref (1, j), &c__1, &work[*n + 1], &c__1); } L60: ; } /* Copy the vector x or Q*x to VR and normalize. */ if (!over) { NUMblas_dcopy (&ki, &work[*n + 1], &c__1, &vr_ref (1, is), &c__1); ii = NUMblas_idamax (&ki, &vr_ref (1, is), &c__1); remax = 1. / (d__1 = vr_ref (ii, is), fabs (d__1)); NUMblas_dscal (&ki, &remax, &vr_ref (1, is), &c__1); i__1 = *n; for (k = ki + 1; k <= i__1; ++k) { vr_ref (k, is) = 0.; /* L70: */ } } else { if (ki > 1) { i__1 = ki - 1; NUMblas_dgemv ("N", n, &i__1, &c_b22, &vr[vr_offset], ldvr, &work[*n + 1], &c__1, &work[ki + *n], &vr_ref (1, ki), &c__1); } ii = NUMblas_idamax (n, &vr_ref (1, ki), &c__1); remax = 1. / (d__1 = vr_ref (ii, ki), fabs (d__1)); NUMblas_dscal (n, &remax, &vr_ref (1, ki), &c__1); } } else { /* Complex right eigenvector. Initial solve [ (T(KI-1,KI-1) T(KI-1,KI) ) - (WR + I* WI)]*X = 0. [ (T(KI,KI-1) T(KI,KI) ) ] */ if ( (d__1 = t_ref (ki - 1, ki), fabs (d__1)) >= (d__2 = t_ref (ki, ki - 1), fabs (d__2))) { work[ki - 1 + *n] = 1.; work[ki + n2] = wi / t_ref (ki - 1, ki); } else { work[ki - 1 + *n] = -wi / t_ref (ki, ki - 1); work[ki + n2] = 1.; } work[ki + *n] = 0.; work[ki - 1 + n2] = 0.; /* Form right-hand side */ i__1 = ki - 2; for (k = 1; k <= i__1; ++k) { work[k + *n] = -work[ki - 1 + *n] * t_ref (k, ki - 1); work[k + n2] = -work[ki + n2] * t_ref (k, ki); /* L80: */ } /* Solve upper quasi-triangular system: (T(1:KI-2,1:KI-2) - (WR+i*WI))*X = SCALE*(WORK+i*WORK2) */ jnxt = ki - 2; for (j = ki - 2; j >= 1; --j) { if (j > jnxt) { goto L90; } j1 = j; j2 = j; jnxt = j - 1; if (j > 1) { if (t_ref (j, j - 1) != 0.) { j1 = j - 1; jnxt = j - 2; } } if (j1 == j2) { /* 1-by-1 diagonal block */ NUMlapack_dlaln2 (&c_false, &c__1, &c__2, &smin, &c_b22, &t_ref (j, j), ldt, &c_b22, &c_b22, &work[j + *n], n, &wr, &wi, x, &c__2, &scale, &xnorm, &ierr); /* Scale X(1,1) and X(1,2) to avoid overflow when updating the right-hand side. */ if (xnorm > 1.) { if (work[j] > bignum / xnorm) { x_ref (1, 1) = x_ref (1, 1) / xnorm; x_ref (1, 2) = x_ref (1, 2) / xnorm; scale /= xnorm; } } /* Scale if necessary */ if (scale != 1.) { NUMblas_dscal (&ki, &scale, &work[*n + 1], &c__1); NUMblas_dscal (&ki, &scale, &work[n2 + 1], &c__1); } work[j + *n] = x_ref (1, 1); work[j + n2] = x_ref (1, 2); /* Update the right-hand side */ i__1 = j - 1; d__1 = -x_ref (1, 1); NUMblas_daxpy (&i__1, &d__1, &t_ref (1, j), &c__1, &work[*n + 1], &c__1); i__1 = j - 1; d__1 = -x_ref (1, 2); NUMblas_daxpy (&i__1, &d__1, &t_ref (1, j), &c__1, &work[n2 + 1], &c__1); } else { /* 2-by-2 diagonal block */ NUMlapack_dlaln2 (&c_false, &c__2, &c__2, &smin, &c_b22, &t_ref (j - 1, j - 1), ldt, &c_b22, &c_b22, &work[j - 1 + *n], n, &wr, &wi, x, &c__2, &scale, &xnorm, &ierr); /* Scale X to avoid overflow when updating the right-hand side. */ if (xnorm > 1.) { /* Computing MAX */ d__1 = work[j - 1], d__2 = work[j]; beta = MAX (d__1, d__2); if (beta > bignum / xnorm) { rec = 1. / xnorm; x_ref (1, 1) = x_ref (1, 1) * rec; x_ref (1, 2) = x_ref (1, 2) * rec; x_ref (2, 1) = x_ref (2, 1) * rec; x_ref (2, 2) = x_ref (2, 2) * rec; scale *= rec; } } /* Scale if necessary */ if (scale != 1.) { NUMblas_dscal (&ki, &scale, &work[*n + 1], &c__1); NUMblas_dscal (&ki, &scale, &work[n2 + 1], &c__1); } work[j - 1 + *n] = x_ref (1, 1); work[j + *n] = x_ref (2, 1); work[j - 1 + n2] = x_ref (1, 2); work[j + n2] = x_ref (2, 2); /* Update the right-hand side */ i__1 = j - 2; d__1 = -x_ref (1, 1); NUMblas_daxpy (&i__1, &d__1, &t_ref (1, j - 1), &c__1, &work[*n + 1], &c__1); i__1 = j - 2; d__1 = -x_ref (2, 1); NUMblas_daxpy (&i__1, &d__1, &t_ref (1, j), &c__1, &work[*n + 1], &c__1); i__1 = j - 2; d__1 = -x_ref (1, 2); NUMblas_daxpy (&i__1, &d__1, &t_ref (1, j - 1), &c__1, &work[n2 + 1], &c__1); i__1 = j - 2; d__1 = -x_ref (2, 2); NUMblas_daxpy (&i__1, &d__1, &t_ref (1, j), &c__1, &work[n2 + 1], &c__1); } L90: ; } /* Copy the vector x or Q*x to VR and normalize. */ if (!over) { NUMblas_dcopy (&ki, &work[*n + 1], &c__1, &vr_ref (1, is - 1), &c__1); NUMblas_dcopy (&ki, &work[n2 + 1], &c__1, &vr_ref (1, is), &c__1); emax = 0.; i__1 = ki; for (k = 1; k <= i__1; ++k) { /* Computing MAX */ d__3 = emax, d__4 = (d__1 = vr_ref (k, is - 1), fabs (d__1)) + (d__2 = vr_ref (k, is), fabs (d__2)); emax = MAX (d__3, d__4); /* L100: */ } remax = 1. / emax; NUMblas_dscal (&ki, &remax, &vr_ref (1, is - 1), &c__1); NUMblas_dscal (&ki, &remax, &vr_ref (1, is), &c__1); i__1 = *n; for (k = ki + 1; k <= i__1; ++k) { vr_ref (k, is - 1) = 0.; vr_ref (k, is) = 0.; /* L110: */ } } else { if (ki > 2) { i__1 = ki - 2; NUMblas_dgemv ("N", n, &i__1, &c_b22, &vr[vr_offset], ldvr, &work[*n + 1], &c__1, &work[ki - 1 + *n], &vr_ref (1, ki - 1), &c__1); i__1 = ki - 2; NUMblas_dgemv ("N", n, &i__1, &c_b22, &vr[vr_offset], ldvr, &work[n2 + 1], &c__1, &work[ki + n2], &vr_ref (1, ki), &c__1); } else { NUMblas_dscal (n, &work[ki - 1 + *n], &vr_ref (1, ki - 1), &c__1); NUMblas_dscal (n, &work[ki + n2], &vr_ref (1, ki), &c__1); } emax = 0.; i__1 = *n; for (k = 1; k <= i__1; ++k) { /* Computing MAX */ d__3 = emax, d__4 = (d__1 = vr_ref (k, ki - 1), fabs (d__1)) + (d__2 = vr_ref (k, ki), fabs (d__2)); emax = MAX (d__3, d__4); /* L120: */ } remax = 1. / emax; NUMblas_dscal (n, &remax, &vr_ref (1, ki - 1), &c__1); NUMblas_dscal (n, &remax, &vr_ref (1, ki), &c__1); } } --is; if (ip != 0) { --is; } L130: if (ip == 1) { ip = 0; } if (ip == -1) { ip = 1; } /* L140: */ } } if (leftv) { /* Compute left eigenvectors. */ ip = 0; is = 1; i__1 = *n; for (ki = 1; ki <= i__1; ++ki) { if (ip == -1) { goto L250; } if (ki == *n) { goto L150; } if (t_ref (ki + 1, ki) == 0.) { goto L150; } ip = 1; L150: if (somev) { if (!select[ki]) { goto L250; } } /* Compute the KI-th eigenvalue (WR,WI). */ wr = t_ref (ki, ki); wi = 0.; if (ip != 0) { wi = sqrt ( (d__1 = t_ref (ki, ki + 1), fabs (d__1))) * sqrt ( (d__2 = t_ref (ki + 1, ki), fabs (d__2))); } /* Computing MAX */ d__1 = ulp * (fabs (wr) + fabs (wi)); smin = MAX (d__1, smlnum); if (ip == 0) { /* Real left eigenvector. */ work[ki + *n] = 1.; /* Form right-hand side */ i__2 = *n; for (k = ki + 1; k <= i__2; ++k) { work[k + *n] = -t_ref (ki, k); /* L160: */ } /* Solve the quasi-triangular system: (T(KI+1:N,KI+1:N) - WR)'*X = SCALE*WORK */ vmax = 1.; vcrit = bignum; jnxt = ki + 1; i__2 = *n; for (j = ki + 1; j <= i__2; ++j) { if (j < jnxt) { goto L170; } j1 = j; j2 = j; jnxt = j + 1; if (j < *n) { if (t_ref (j + 1, j) != 0.) { j2 = j + 1; jnxt = j + 2; } } if (j1 == j2) { /* 1-by-1 diagonal block Scale if necessary to avoid overflow when forming the right-hand side. */ if (work[j] > vcrit) { rec = 1. / vmax; i__3 = *n - ki + 1; NUMblas_dscal (&i__3, &rec, &work[ki + *n], &c__1); vmax = 1.; vcrit = bignum; } i__3 = j - ki - 1; work[j + *n] -= NUMblas_ddot (&i__3, &t_ref (ki + 1, j), &c__1, &work[ki + 1 + *n], &c__1); /* Solve (T(J,J)-WR)'*X = WORK */ NUMlapack_dlaln2 (&c_false, &c__1, &c__1, &smin, &c_b22, &t_ref (j, j), ldt, &c_b22, &c_b22, &work[j + *n], n, &wr, &c_b25, x, &c__2, &scale, &xnorm, &ierr); /* Scale if necessary */ if (scale != 1.) { i__3 = *n - ki + 1; NUMblas_dscal (&i__3, &scale, &work[ki + *n], &c__1); } work[j + *n] = x_ref (1, 1); /* Computing MAX */ d__2 = (d__1 = work[j + *n], fabs (d__1)); vmax = MAX (d__2, vmax); vcrit = bignum / vmax; } else { /* 2-by-2 diagonal block Scale if necessary to avoid overflow when forming the right-hand side. Computing MAX */ d__1 = work[j], d__2 = work[j + 1]; beta = MAX (d__1, d__2); if (beta > vcrit) { rec = 1. / vmax; i__3 = *n - ki + 1; NUMblas_dscal (&i__3, &rec, &work[ki + *n], &c__1); vmax = 1.; vcrit = bignum; } i__3 = j - ki - 1; work[j + *n] -= NUMblas_ddot (&i__3, &t_ref (ki + 1, j), &c__1, &work[ki + 1 + *n], &c__1); i__3 = j - ki - 1; work[j + 1 + *n] -= NUMblas_ddot (&i__3, &t_ref (ki + 1, j + 1), &c__1, &work[ki + 1 + *n], &c__1); /* Solve [T(J,J)-WR T(J,J+1) ]'* X = SCALE*( WORK1 ) [T(J+1,J) T(J+1,J+1)-WR] ( WORK2 ) */ NUMlapack_dlaln2 (&c_true, &c__2, &c__1, &smin, &c_b22, &t_ref (j, j), ldt, &c_b22, &c_b22, &work[j + *n], n, &wr, &c_b25, x, &c__2, &scale, &xnorm, &ierr); /* Scale if necessary */ if (scale != 1.) { i__3 = *n - ki + 1; NUMblas_dscal (&i__3, &scale, &work[ki + *n], &c__1); } work[j + *n] = x_ref (1, 1); work[j + 1 + *n] = x_ref (2, 1); /* Computing MAX */ d__3 = (d__1 = work[j + *n], fabs (d__1)), d__4 = (d__2 = work[j + 1 + *n], fabs (d__2)), d__3 = MAX (d__3, d__4); vmax = MAX (d__3, vmax); vcrit = bignum / vmax; } L170: ; } /* Copy the vector x or Q*x to VL and normalize. */ if (!over) { i__2 = *n - ki + 1; NUMblas_dcopy (&i__2, &work[ki + *n], &c__1, &vl_ref (ki, is), &c__1); i__2 = *n - ki + 1; ii = NUMblas_idamax (&i__2, &vl_ref (ki, is), &c__1) + ki - 1; remax = 1. / (d__1 = vl_ref (ii, is), fabs (d__1)); i__2 = *n - ki + 1; NUMblas_dscal (&i__2, &remax, &vl_ref (ki, is), &c__1); i__2 = ki - 1; for (k = 1; k <= i__2; ++k) { vl_ref (k, is) = 0.; /* L180: */ } } else { if (ki < *n) { i__2 = *n - ki; NUMblas_dgemv ("N", n, &i__2, &c_b22, &vl_ref (1, ki + 1), ldvl, &work[ki + 1 + *n], &c__1, &work[ki + *n], &vl_ref (1, ki), &c__1); } ii = NUMblas_idamax (n, &vl_ref (1, ki), &c__1); remax = 1. / (d__1 = vl_ref (ii, ki), fabs (d__1)); NUMblas_dscal (n, &remax, &vl_ref (1, ki), &c__1); } } else { /* Complex left eigenvector. Initial solve: ((T(KI,KI) T(KI,KI+1) )' - (WR - I* WI))*X = 0. ((T(KI+1,KI) T(KI+1,KI+1)) ) */ if ( (d__1 = t_ref (ki, ki + 1), fabs (d__1)) >= (d__2 = t_ref (ki + 1, ki), fabs (d__2))) { work[ki + *n] = wi / t_ref (ki, ki + 1); work[ki + 1 + n2] = 1.; } else { work[ki + *n] = 1.; work[ki + 1 + n2] = -wi / t_ref (ki + 1, ki); } work[ki + 1 + *n] = 0.; work[ki + n2] = 0.; /* Form right-hand side */ i__2 = *n; for (k = ki + 2; k <= i__2; ++k) { work[k + *n] = -work[ki + *n] * t_ref (ki, k); work[k + n2] = -work[ki + 1 + n2] * t_ref (ki + 1, k); /* L190: */ } /* Solve complex quasi-triangular system: ( T(KI+2,N:KI+2,N) - (WR-i*WI) )*X = WORK1+i*WORK2 */ vmax = 1.; vcrit = bignum; jnxt = ki + 2; i__2 = *n; for (j = ki + 2; j <= i__2; ++j) { if (j < jnxt) { goto L200; } j1 = j; j2 = j; jnxt = j + 1; if (j < *n) { if (t_ref (j + 1, j) != 0.) { j2 = j + 1; jnxt = j + 2; } } if (j1 == j2) { /* 1-by-1 diagonal block Scale if necessary to avoid overflow when forming the right-hand side elements. */ if (work[j] > vcrit) { rec = 1. / vmax; i__3 = *n - ki + 1; NUMblas_dscal (&i__3, &rec, &work[ki + *n], &c__1); i__3 = *n - ki + 1; NUMblas_dscal (&i__3, &rec, &work[ki + n2], &c__1); vmax = 1.; vcrit = bignum; } i__3 = j - ki - 2; work[j + *n] -= NUMblas_ddot (&i__3, &t_ref (ki + 2, j), &c__1, &work[ki + 2 + *n], &c__1); i__3 = j - ki - 2; work[j + n2] -= NUMblas_ddot (&i__3, &t_ref (ki + 2, j), &c__1, &work[ki + 2 + n2], &c__1); /* Solve (T(J,J)-(WR-i*WI))*(X11+i*X12)= WK+I*WK2 */ d__1 = -wi; NUMlapack_dlaln2 (&c_false, &c__1, &c__2, &smin, &c_b22, &t_ref (j, j), ldt, &c_b22, &c_b22, &work[j + *n], n, &wr, &d__1, x, &c__2, &scale, &xnorm, &ierr); /* Scale if necessary */ if (scale != 1.) { i__3 = *n - ki + 1; NUMblas_dscal (&i__3, &scale, &work[ki + *n], &c__1); i__3 = *n - ki + 1; NUMblas_dscal (&i__3, &scale, &work[ki + n2], &c__1); } work[j + *n] = x_ref (1, 1); work[j + n2] = x_ref (1, 2); /* Computing MAX */ d__3 = (d__1 = work[j + *n], fabs (d__1)), d__4 = (d__2 = work[j + n2], fabs (d__2)), d__3 = MAX (d__3, d__4); vmax = MAX (d__3, vmax); vcrit = bignum / vmax; } else { /* 2-by-2 diagonal block Scale if necessary to avoid overflow when forming the right-hand side elements. Computing MAX */ d__1 = work[j], d__2 = work[j + 1]; beta = MAX (d__1, d__2); if (beta > vcrit) { rec = 1. / vmax; i__3 = *n - ki + 1; NUMblas_dscal (&i__3, &rec, &work[ki + *n], &c__1); i__3 = *n - ki + 1; NUMblas_dscal (&i__3, &rec, &work[ki + n2], &c__1); vmax = 1.; vcrit = bignum; } i__3 = j - ki - 2; work[j + *n] -= NUMblas_ddot (&i__3, &t_ref (ki + 2, j), &c__1, &work[ki + 2 + *n], &c__1); i__3 = j - ki - 2; work[j + n2] -= NUMblas_ddot (&i__3, &t_ref (ki + 2, j), &c__1, &work[ki + 2 + n2], &c__1); i__3 = j - ki - 2; work[j + 1 + *n] -= NUMblas_ddot (&i__3, &t_ref (ki + 2, j + 1), &c__1, &work[ki + 2 + *n], &c__1); i__3 = j - ki - 2; work[j + 1 + n2] -= NUMblas_ddot (&i__3, &t_ref (ki + 2, j + 1), &c__1, &work[ki + 2 + n2], &c__1); /* Solve 2-by-2 complex linear equation ([T(j,j) T(j,j+1) ]'-(wr-i*wi)*I)*X = SCALE*B ([T(j+1,j) T(j+1,j+1)] ) */ d__1 = -wi; NUMlapack_dlaln2 (&c_true, &c__2, &c__2, &smin, &c_b22, &t_ref (j, j), ldt, &c_b22, &c_b22, &work[j + *n], n, &wr, &d__1, x, &c__2, &scale, &xnorm, &ierr); /* Scale if necessary */ if (scale != 1.) { i__3 = *n - ki + 1; NUMblas_dscal (&i__3, &scale, &work[ki + *n], &c__1); i__3 = *n - ki + 1; NUMblas_dscal (&i__3, &scale, &work[ki + n2], &c__1); } work[j + *n] = x_ref (1, 1); work[j + n2] = x_ref (1, 2); work[j + 1 + *n] = x_ref (2, 1); work[j + 1 + n2] = x_ref (2, 2); /* Computing MAX */ d__5 = (d__1 = x_ref (1, 1), fabs (d__1)), d__6 = (d__2 = x_ref (1, 2), fabs (d__2)), d__5 = MAX (d__5, d__6), d__6 = (d__3 = x_ref (2, 1), fabs (d__3)), d__5 = MAX (d__5, d__6), d__6 = (d__4 = x_ref (2, 2), fabs (d__4)), d__5 = MAX (d__5, d__6); vmax = MAX (d__5, vmax); vcrit = bignum / vmax; } L200: ; } /* Copy the vector x or Q*x to VL and normalize. L210: */ if (!over) { i__2 = *n - ki + 1; NUMblas_dcopy (&i__2, &work[ki + *n], &c__1, &vl_ref (ki, is), &c__1); i__2 = *n - ki + 1; NUMblas_dcopy (&i__2, &work[ki + n2], &c__1, &vl_ref (ki, is + 1), &c__1); emax = 0.; i__2 = *n; for (k = ki; k <= i__2; ++k) { /* Computing MAX */ d__3 = emax, d__4 = (d__1 = vl_ref (k, is), fabs (d__1)) + (d__2 = vl_ref (k, is + 1), fabs (d__2)); emax = MAX (d__3, d__4); /* L220: */ } remax = 1. / emax; i__2 = *n - ki + 1; NUMblas_dscal (&i__2, &remax, &vl_ref (ki, is), &c__1); i__2 = *n - ki + 1; NUMblas_dscal (&i__2, &remax, &vl_ref (ki, is + 1), &c__1); i__2 = ki - 1; for (k = 1; k <= i__2; ++k) { vl_ref (k, is) = 0.; vl_ref (k, is + 1) = 0.; /* L230: */ } } else { if (ki < *n - 1) { i__2 = *n - ki - 1; NUMblas_dgemv ("N", n, &i__2, &c_b22, &vl_ref (1, ki + 2), ldvl, &work[ki + 2 + *n], &c__1, &work[ki + *n], &vl_ref (1, ki), &c__1); i__2 = *n - ki - 1; NUMblas_dgemv ("N", n, &i__2, &c_b22, &vl_ref (1, ki + 2), ldvl, &work[ki + 2 + n2], &c__1, &work[ki + 1 + n2], &vl_ref (1, ki + 1), &c__1); } else { NUMblas_dscal (n, &work[ki + *n], &vl_ref (1, ki), &c__1); NUMblas_dscal (n, &work[ki + 1 + n2], &vl_ref (1, ki + 1), &c__1); } emax = 0.; i__2 = *n; for (k = 1; k <= i__2; ++k) { /* Computing MAX */ d__3 = emax, d__4 = (d__1 = vl_ref (k, ki), fabs (d__1)) + (d__2 = vl_ref (k, ki + 1), fabs (d__2)); emax = MAX (d__3, d__4); /* L240: */ } remax = 1. / emax; NUMblas_dscal (n, &remax, &vl_ref (1, ki), &c__1); NUMblas_dscal (n, &remax, &vl_ref (1, ki + 1), &c__1); } } ++is; if (ip != 0) { ++is; } L250: if (ip == -1) { ip = 0; } if (ip == 1) { ip = -1; } /* L260: */ } } return 0; } /* NUMlapack_dtrevc */ #undef vr_ref #undef vl_ref #undef x_ref #undef t_ref int NUMlapack_dtrti2 (const char *uplo, const char *diag, long *n, double *a, long *lda, long *info) { /* Table of constant values */ static long c__1 = 1; /* System generated locals */ long a_dim1, a_offset, i__1, i__2; /* Local variables */ static long j; static long upper; static long nounit; static double ajj; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; /* Function Body */ *info = 0; upper = lsame_ (uplo, "U"); nounit = lsame_ (diag, "N"); if (!upper && !lsame_ (uplo, "L")) { *info = -1; } else if (!nounit && !lsame_ (diag, "U")) { *info = -2; } else if (*n < 0) { *info = -3; } else if (*lda < MAX (1, *n)) { *info = -5; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DTRTI2", &i__1); return 0; } if (upper) { /* Compute inverse of upper triangular matrix. */ i__1 = *n; for (j = 1; j <= i__1; ++j) { if (nounit) { a_ref (j, j) = 1. / a_ref (j, j); ajj = -a_ref (j, j); } else { ajj = -1.; } /* Compute elements 1:j-1 of j-th column. */ i__2 = j - 1; NUMblas_dtrmv ("Upper", "No transpose", diag, &i__2, &a[a_offset], lda, &a_ref (1, j), &c__1); i__2 = j - 1; NUMblas_dscal (&i__2, &ajj, &a_ref (1, j), &c__1); /* L10: */ } } else { /* Compute inverse of lower triangular matrix. */ for (j = *n; j >= 1; --j) { if (nounit) { a_ref (j, j) = 1. / a_ref (j, j); ajj = -a_ref (j, j); } else { ajj = -1.; } if (j < *n) { /* Compute elements j+1:n of j-th column. */ i__1 = *n - j; NUMblas_dtrmv ("Lower", "No transpose", diag, &i__1, &a_ref (j + 1, j + 1), lda, &a_ref (j + 1, j), &c__1); i__1 = *n - j; NUMblas_dscal (&i__1, &ajj, &a_ref (j + 1, j), &c__1); } /* L20: */ } } return 0; } /* NUMlapack_dtrti2 */ int NUMlapack_dtrtri (const char *uplo, const char *diag, long *n, double *a, long *lda, long *info) { /* Table of constant values */ static long c__1 = 1; static long c_n1 = -1; static long c__2 = 2; static double c_b18 = 1.; static double c_b22 = -1.; /* System generated locals */ char *a__1[2]; long a_dim1, a_offset, i__1, i__2[2], i__3, i__4, i__5; char ch__1[2]; /* Local variables */ static long j; static long upper; static long jb, nb, nn; static long nounit; a_dim1 = *lda; a_offset = 1 + a_dim1 * 1; a -= a_offset; /* Function Body */ *info = 0; upper = lsame_ (uplo, "U"); nounit = lsame_ (diag, "N"); if (!upper && !lsame_ (uplo, "L")) { *info = -1; } else if (!nounit && !lsame_ (diag, "U")) { *info = -2; } else if (*n < 0) { *info = -3; } else if (*lda < MAX (1, *n)) { *info = -5; } if (*info != 0) { i__1 = - (*info); xerbla_ ("DTRTRI", &i__1); return 0; } /* Quick return if possible */ if (*n == 0) { return 0; } /* Check for singularity if non-unit. */ if (nounit) { i__1 = *n; for (*info = 1; *info <= i__1; ++ (*info)) { if (a_ref (*info, *info) == 0.) { return 0; } /* L10: */ } *info = 0; } /* Determine the block size for this environment. Writing concatenation */ i__2[0] = 1, a__1[0] = (char *) uplo; i__2[1] = 1, a__1[1] = (char *) diag; s_cat (ch__1, (const char **) a__1, i__2, &c__2, 2); nb = NUMlapack_ilaenv (&c__1, "DTRTRI", ch__1, n, &c_n1, &c_n1, &c_n1, 6, 2); if (nb <= 1 || nb >= *n) { /* Use unblocked code */ NUMlapack_dtrti2 (uplo, diag, n, &a[a_offset], lda, info); } else { /* Use blocked code */ if (upper) { /* Compute inverse of upper triangular matrix */ i__1 = *n; i__3 = nb; for (j = 1; i__3 < 0 ? j >= i__1 : j <= i__1; j += i__3) { /* Computing MIN */ i__4 = nb, i__5 = *n - j + 1; jb = MIN (i__4, i__5); /* Compute rows 1:j-1 of current block column */ i__4 = j - 1; NUMblas_dtrmm ("Left", "Upper", "No transpose", diag, &i__4, &jb, &c_b18, &a[a_offset], lda, &a_ref (1, j), lda); i__4 = j - 1; NUMblas_dtrsm ("Right", "Upper", "No transpose", diag, &i__4, &jb, &c_b22, &a_ref (j, j), lda, &a_ref (1, j), lda); /* Compute inverse of current diagonal block */ NUMlapack_dtrti2 ("Upper", diag, &jb, &a_ref (j, j), lda, info); /* L20: */ } } else { /* Compute inverse of lower triangular matrix */ nn = (*n - 1) / nb * nb + 1; i__3 = -nb; for (j = nn; i__3 < 0 ? j >= 1 : j <= 1; j += i__3) { /* Computing MIN */ i__1 = nb, i__4 = *n - j + 1; jb = MIN (i__1, i__4); if (j + jb <= *n) { /* Compute rows j+jb:n of current block column */ i__1 = *n - j - jb + 1; NUMblas_dtrmm ("Left", "Lower", "No transpose", diag, &i__1, &jb, &c_b18, &a_ref (j + jb, j + jb), lda, &a_ref (j + jb, j), lda); i__1 = *n - j - jb + 1; NUMblas_dtrsm ("Right", "Lower", "No transpose", diag, &i__1, &jb, &c_b22, &a_ref (j, j), lda, &a_ref (j + jb, j), lda); } /* Compute inverse of current diagonal block */ NUMlapack_dtrti2 ("Lower", diag, &jb, &a_ref (j, j), lda, info); /* L30: */ } } } return 0; } /* NUMlapack_dtrtri */ long NUMlapack_ieeeck (long *ispec, float *zero, float *one) { /* System generated locals */ long ret_val; /* Local variables */ static float neginf, posinf, negzro, newzro, nan1, nan2, nan3, nan4, nan5, nan6; ret_val = 1; posinf = *one / *zero; if (posinf <= *one) { ret_val = 0; return ret_val; } neginf = - (*one) / *zero; if (neginf >= *zero) { ret_val = 0; return ret_val; } negzro = *one / (neginf + *one); if (negzro != *zero) { ret_val = 0; return ret_val; } neginf = *one / negzro; if (neginf >= *zero) { ret_val = 0; return ret_val; } newzro = negzro + *zero; if (newzro != *zero) { ret_val = 0; return ret_val; } posinf = *one / newzro; if (posinf <= *one) { ret_val = 0; return ret_val; } neginf *= posinf; if (neginf >= *zero) { ret_val = 0; return ret_val; } posinf *= posinf; if (posinf <= *one) { ret_val = 0; return ret_val; } /* Return if we were only asked to check infinity arithmetic */ if (*ispec == 0) { return ret_val; } nan1 = posinf + neginf; nan2 = posinf / neginf; nan3 = posinf / posinf; nan4 = posinf * *zero; nan5 = neginf * negzro; nan6 = nan5 * 0.f; if (nan1 == nan1) { ret_val = 0; return ret_val; } if (nan2 == nan2) { ret_val = 0; return ret_val; } if (nan3 == nan3) { ret_val = 0; return ret_val; } if (nan4 == nan4) { ret_val = 0; return ret_val; } if (nan5 == nan5) { ret_val = 0; return ret_val; } if (nan6 == nan6) { ret_val = 0; return ret_val; } return ret_val; } /* NUMlapack_ieeeck */ long NUMlapack_ilaenv (long *ispec, const char *name__, const char *opts, long *n1, long *n2, long *n3, long *n4, long name_len, long opts_len) { /* Table of constant values */ static long c__0 = 0; static float c_b162 = 0.f; static float c_b163 = 1.f; static long c__1 = 1; /* System generated locals */ long ret_val; /* Local variables */ static long i__; static long cname, sname; static long nbmin; static char c1[1], c2[2], c3[3], c4[2]; static long ic, nb; static long iz, nx; static char subnam[6]; (void) opts; (void) n3; (void) opts_len; switch (*ispec) { case 1: goto L100; case 2: goto L100; case 3: goto L100; case 4: goto L400; case 5: goto L500; case 6: goto L600; case 7: goto L700; case 8: goto L800; case 9: goto L900; case 10: goto L1000; case 11: goto L1100; } /* Invalid value for ISPEC */ ret_val = -1; return ret_val; L100: /* Convert NAME to upper case if the first character is lower case. */ ret_val = 1; s_copy (subnam, (char *) name__, 6, name_len); ic = * (unsigned char *) subnam; iz = 'Z'; if (iz == 90 || iz == 122) { /* ASCII character set */ if (ic >= 97 && ic <= 122) { * (unsigned char *) subnam = (char) (ic - 32); for (i__ = 2; i__ <= 6; ++i__) { ic = * (unsigned char *) &subnam[i__ - 1]; if (ic >= 97 && ic <= 122) { * (unsigned char *) &subnam[i__ - 1] = (char) (ic - 32); } /* L10: */ } } } else if (iz == 233 || iz == 169) { /* EBCDIC character set */ if (ic >= 129 && ic <= 137 || ic >= 145 && ic <= 153 || ic >= 162 && ic <= 169) { * (unsigned char *) subnam = (char) (ic + 64); for (i__ = 2; i__ <= 6; ++i__) { ic = * (unsigned char *) &subnam[i__ - 1]; if (ic >= 129 && ic <= 137 || ic >= 145 && ic <= 153 || ic >= 162 && ic <= 169) { * (unsigned char *) &subnam[i__ - 1] = (char) (ic + 64); } /* L20: */ } } } else if (iz == 218 || iz == 250) { /* Prime machines: ASCII+128 */ if (ic >= 225 && ic <= 250) { * (unsigned char *) subnam = (char) (ic - 32); for (i__ = 2; i__ <= 6; ++i__) { ic = * (unsigned char *) &subnam[i__ - 1]; if (ic >= 225 && ic <= 250) { * (unsigned char *) &subnam[i__ - 1] = (char) (ic - 32); } /* L30: */ } } } * (unsigned char *) c1 = * (unsigned char *) subnam; sname = * (unsigned char *) c1 == 'S' || * (unsigned char *) c1 == 'D'; cname = * (unsigned char *) c1 == 'C' || * (unsigned char *) c1 == 'Z'; if (! (cname || sname)) { return ret_val; } s_copy (c2, subnam + 1, 2, 2); s_copy (c3, subnam + 3, 3, 3); s_copy (c4, c3 + 1, 2, 2); switch (*ispec) { case 1: goto L110; case 2: goto L200; case 3: goto L300; } L110: /* ISPEC = 1: block size In these examples, separate code is provided for setting NB for real and complex. We assume that NB will take the same value in single or double precision. */ nb = 1; if (s_cmp (c2, "GE", 2, 2) == 0) { if (s_cmp (c3, "TRF", 3, 3) == 0) { if (sname) { nb = 64; } else { nb = 64; } } else if (s_cmp (c3, "QRF", 3, 3) == 0 || s_cmp (c3, "RQF", 3, 3) == 0 || s_cmp (c3, "LQF", 3, 3) == 0 || s_cmp (c3, "QLF", 3, 3) == 0) { if (sname) { nb = 32; } else { nb = 32; } } else if (s_cmp (c3, "HRD", 3, 3) == 0) { if (sname) { nb = 32; } else { nb = 32; } } else if (s_cmp (c3, "BRD", 3, 3) == 0) { if (sname) { nb = 32; } else { nb = 32; } } else if (s_cmp (c3, "TRI", 3, 3) == 0) { if (sname) { nb = 64; } else { nb = 64; } } } else if (s_cmp (c2, "PO", 2, 2) == 0) { if (s_cmp (c3, "TRF", 3, 3) == 0) { if (sname) { nb = 64; } else { nb = 64; } } } else if (s_cmp (c2, "SY", 2, 2) == 0) { if (s_cmp (c3, "TRF", 3, 3) == 0) { if (sname) { nb = 64; } else { nb = 64; } } else if (sname && s_cmp (c3, "TRD", 3, 3) == 0) { nb = 32; } else if (sname && s_cmp (c3, "GST", 3, 3) == 0) { nb = 64; } } else if (cname && s_cmp (c2, "HE", 2, 2) == 0) { if (s_cmp (c3, "TRF", 3, 3) == 0) { nb = 64; } else if (s_cmp (c3, "TRD", 3, 3) == 0) { nb = 32; } else if (s_cmp (c3, "GST", 3, 3) == 0) { nb = 64; } } else if (sname && s_cmp (c2, "OR", 2, 2) == 0) { if (* (unsigned char *) c3 == 'G') { if (s_cmp (c4, "QR", 2, 2) == 0 || s_cmp (c4, "RQ", 2, 2) == 0 || s_cmp (c4, "LQ", 2, 2) == 0 || s_cmp (c4, "QL", 2, 2) == 0 || s_cmp (c4, "HR", 2, 2) == 0 || s_cmp (c4, "TR", 2, 2) == 0 || s_cmp (c4, "BR", 2, 2) == 0) { nb = 32; } } else if (* (unsigned char *) c3 == 'M') { if (s_cmp (c4, "QR", 2, 2) == 0 || s_cmp (c4, "RQ", 2, 2) == 0 || s_cmp (c4, "LQ", 2, 2) == 0 || s_cmp (c4, "QL", 2, 2) == 0 || s_cmp (c4, "HR", 2, 2) == 0 || s_cmp (c4, "TR", 2, 2) == 0 || s_cmp (c4, "BR", 2, 2) == 0) { nb = 32; } } } else if (cname && s_cmp (c2, "UN", 2, 2) == 0) { if (* (unsigned char *) c3 == 'G') { if (s_cmp (c4, "QR", 2, 2) == 0 || s_cmp (c4, "RQ", 2, 2) == 0 || s_cmp (c4, "LQ", 2, 2) == 0 || s_cmp (c4, "QL", 2, 2) == 0 || s_cmp (c4, "HR", 2, 2) == 0 || s_cmp (c4, "TR", 2, 2) == 0 || s_cmp (c4, "BR", 2, 2) == 0) { nb = 32; } } else if (* (unsigned char *) c3 == 'M') { if (s_cmp (c4, "QR", 2, 2) == 0 || s_cmp (c4, "RQ", 2, 2) == 0 || s_cmp (c4, "LQ", 2, 2) == 0 || s_cmp (c4, "QL", 2, 2) == 0 || s_cmp (c4, "HR", 2, 2) == 0 || s_cmp (c4, "TR", 2, 2) == 0 || s_cmp (c4, "BR", 2, 2) == 0) { nb = 32; } } } else if (s_cmp (c2, "GB", 2, 2) == 0) { if (s_cmp (c3, "TRF", 3, 3) == 0) { if (sname) { if (*n4 <= 64) { nb = 1; } else { nb = 32; } } else { if (*n4 <= 64) { nb = 1; } else { nb = 32; } } } } else if (s_cmp (c2, "PB", 2, 2) == 0) { if (s_cmp (c3, "TRF", 3, 3) == 0) { if (sname) { if (*n2 <= 64) { nb = 1; } else { nb = 32; } } else { if (*n2 <= 64) { nb = 1; } else { nb = 32; } } } } else if (s_cmp (c2, "TR", 2, 2) == 0) { if (s_cmp (c3, "TRI", 3, 3) == 0) { if (sname) { nb = 64; } else { nb = 64; } } } else if (s_cmp (c2, "LA", 2, 2) == 0) { if (s_cmp (c3, "UUM", 3, 3) == 0) { if (sname) { nb = 64; } else { nb = 64; } } } else if (sname && s_cmp (c2, "ST", 2, 2) == 0) { if (s_cmp (c3, "EBZ", 3, 3) == 0) { nb = 1; } } ret_val = nb; return ret_val; L200: /* ISPEC = 2: minimum block size */ nbmin = 2; if (s_cmp (c2, "GE", 2, 2) == 0) { if (s_cmp (c3, "QRF", 3, 3) == 0 || s_cmp (c3, "RQF", 3, 3) == 0 || s_cmp (c3, "LQF", 3, 3) == 0 || s_cmp (c3, "QLF", 3, 3) == 0) { if (sname) { nbmin = 2; } else { nbmin = 2; } } else if (s_cmp (c3, "HRD", 3, 3) == 0) { if (sname) { nbmin = 2; } else { nbmin = 2; } } else if (s_cmp (c3, "BRD", 3, 3) == 0) { if (sname) { nbmin = 2; } else { nbmin = 2; } } else if (s_cmp (c3, "TRI", 3, 3) == 0) { if (sname) { nbmin = 2; } else { nbmin = 2; } } } else if (s_cmp (c2, "SY", 2, 2) == 0) { if (s_cmp (c3, "TRF", 3, 3) == 0) { if (sname) { nbmin = 8; } else { nbmin = 8; } } else if (sname && s_cmp (c3, "TRD", 3, 3) == 0) { nbmin = 2; } } else if (cname && s_cmp (c2, "HE", 2, 2) == 0) { if (s_cmp (c3, "TRD", 3, 3) == 0) { nbmin = 2; } } else if (sname && s_cmp (c2, "OR", 2, 2) == 0) { if (* (unsigned char *) c3 == 'G') { if (s_cmp (c4, "QR", 2, 2) == 0 || s_cmp (c4, "RQ", 2, 2) == 0 || s_cmp (c4, "LQ", 2, 2) == 0 || s_cmp (c4, "QL", 2, 2) == 0 || s_cmp (c4, "HR", 2, 2) == 0 || s_cmp (c4, "TR", 2, 2) == 0 || s_cmp (c4, "BR", 2, 2) == 0) { nbmin = 2; } } else if (* (unsigned char *) c3 == 'M') { if (s_cmp (c4, "QR", 2, 2) == 0 || s_cmp (c4, "RQ", 2, 2) == 0 || s_cmp (c4, "LQ", 2, 2) == 0 || s_cmp (c4, "QL", 2, 2) == 0 || s_cmp (c4, "HR", 2, 2) == 0 || s_cmp (c4, "TR", 2, 2) == 0 || s_cmp (c4, "BR", 2, 2) == 0) { nbmin = 2; } } } else if (cname && s_cmp (c2, "UN", 2, 2) == 0) { if (* (unsigned char *) c3 == 'G') { if (s_cmp (c4, "QR", 2, 2) == 0 || s_cmp (c4, "RQ", 2, 2) == 0 || s_cmp (c4, "LQ", 2, 2) == 0 || s_cmp (c4, "QL", 2, 2) == 0 || s_cmp (c4, "HR", 2, 2) == 0 || s_cmp (c4, "TR", 2, 2) == 0 || s_cmp (c4, "BR", 2, 2) == 0) { nbmin = 2; } } else if (* (unsigned char *) c3 == 'M') { if (s_cmp (c4, "QR", 2, 2) == 0 || s_cmp (c4, "RQ", 2, 2) == 0 || s_cmp (c4, "LQ", 2, 2) == 0 || s_cmp (c4, "QL", 2, 2) == 0 || s_cmp (c4, "HR", 2, 2) == 0 || s_cmp (c4, "TR", 2, 2) == 0 || s_cmp (c4, "BR", 2, 2) == 0) { nbmin = 2; } } } ret_val = nbmin; return ret_val; L300: /* ISPEC = 3: crossover point */ nx = 0; if (s_cmp (c2, "GE", 2, 2) == 0) { if (s_cmp (c3, "QRF", 3, 3) == 0 || s_cmp (c3, "RQF", 3, 3) == 0 || s_cmp (c3, "LQF", 3, 3) == 0 || s_cmp (c3, "QLF", 3, 3) == 0) { if (sname) { nx = 128; } else { nx = 128; } } else if (s_cmp (c3, "HRD", 3, 3) == 0) { if (sname) { nx = 128; } else { nx = 128; } } else if (s_cmp (c3, "BRD", 3, 3) == 0) { if (sname) { nx = 128; } else { nx = 128; } } } else if (s_cmp (c2, "SY", 2, 2) == 0) { if (sname && s_cmp (c3, "TRD", 3, 3) == 0) { nx = 32; } } else if (cname && s_cmp (c2, "HE", 2, 2) == 0) { if (s_cmp (c3, "TRD", 3, 3) == 0) { nx = 32; } } else if (sname && s_cmp (c2, "OR", 2, 2) == 0) { if (* (unsigned char *) c3 == 'G') { if (s_cmp (c4, "QR", 2, 2) == 0 || s_cmp (c4, "RQ", 2, 2) == 0 || s_cmp (c4, "LQ", 2, 2) == 0 || s_cmp (c4, "QL", 2, 2) == 0 || s_cmp (c4, "HR", 2, 2) == 0 || s_cmp (c4, "TR", 2, 2) == 0 || s_cmp (c4, "BR", 2, 2) == 0) { nx = 128; } } } else if (cname && s_cmp (c2, "UN", 2, 2) == 0) { if (* (unsigned char *) c3 == 'G') { if (s_cmp (c4, "QR", 2, 2) == 0 || s_cmp (c4, "RQ", 2, 2) == 0 || s_cmp (c4, "LQ", 2, 2) == 0 || s_cmp (c4, "QL", 2, 2) == 0 || s_cmp (c4, "HR", 2, 2) == 0 || s_cmp (c4, "TR", 2, 2) == 0 || s_cmp (c4, "BR", 2, 2) == 0) { nx = 128; } } } ret_val = nx; return ret_val; L400: /* ISPEC = 4: number of shifts (used by xHSEQR) */ ret_val = 6; return ret_val; L500: /* ISPEC = 5: minimum column dimension (not used) */ ret_val = 2; return ret_val; L600: /* ISPEC = 6: crossover point for SVD (used by xGELSS and xGESVD) */ ret_val = (long) ( (float) MIN (*n1, *n2) * 1.6f); return ret_val; L700: /* ISPEC = 7: number of processors (not used) */ ret_val = 1; return ret_val; L800: /* ISPEC = 8: crossover point for multishift (used by xHSEQR) */ ret_val = 50; return ret_val; L900: /* ISPEC = 9: maximum size of the subproblems at the bottom of the computation tree in the divide-and-conquer algorithm (used by xGELSD and xGESDD) */ ret_val = 25; return ret_val; L1000: /* ISPEC = 10: ieee NaN arithmetic can be trusted not to trap ILAENV = 0 */ ret_val = 1; if (ret_val == 1) { ret_val = NUMlapack_ieeeck (&c__0, &c_b162, &c_b163); } return ret_val; L1100: /* ISPEC = 11: infinity arithmetic can be trusted not to trap ILAENV = 0 */ ret_val = 1; if (ret_val == 1) { ret_val = NUMlapack_ieeeck (&c__1, &c_b162, &c_b163); } return ret_val; } /* NUMlapack_ilaenv */ #undef a_ref #undef c___ref #undef MAX #undef MIN /* End of file NUMclapack.c */ praat-6.0.04/dwsys/NUMclapack.h000066400000000000000000007277351261542461700162450ustar00rootroot00000000000000#ifndef _NUMclapack_h_ #define _NUMclapack_h_ /* NUMclapack.h * * Copyright (C) 1994-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020923 GPL header djmw 20030310 Latest modification */ /* The following routines all use FORTRAN column-major storage of matrices. A consequence is that all matrices must have been allocated as a single block of mxn elements. All matrices are passed as a vector of mxn elements. matrix[i][j] => vector[(j-1)*m + i] "Fortran" matrix[i][j] => vector[(i-1)*n + j] "C" The consequence is that you have to transpose C matrices before you pass them to a CLAPACK routine. Sometimes you can avoid transposition by considering the solution of the transposed problem (e.g. See code in SVD_compute). */ int NUMlapack_dbdsqr(const char *uplo, long *n, long *ncvt, long *nru, long *ncc, double *d, double *e, double *vt, long *ldvt, double *u, long *ldu, double *c, long *ldc, double *work, long *info); /* Purpose ======= NUMlapack_dbdsqr computes the singular value decomposition (SVD) of a real N-by-N (upper or lower) bidiagonal matrix B: B = Q * S * P' (P' denotes the transpose of P), where S is a diagonal matrix with non-negative diagonal elements (the singular values of B), and Q and P are orthogonal matrices. The routine computes S, and optionally computes U * Q, P' * VT, or Q' * C, for given real input matrices U, VT, and C. See "Computing Small Singular Values of Bidiagonal Matrices With Guaranteed High Relative Accuracy," by J. Demmel and W. Kahan, LAPACK Working Note #3 (or SIAM J. Sci. Statist. Comput. vol. 11, no. 5, pp. 873-912, Sept 1990) and "Accurate singular values and differential qd algorithms," by B. Parlett and V. Fernando, Technical Report CPAM-554, Mathematics Department, University of California at Berkeley, July 1992 for a detailed description of the algorithm. Arguments ========= UPLO (input) char* = 'U': B is upper bidiagonal; = 'L': B is lower bidiagonal. N (input) long The order of the matrix B. N >= 0. NCVT (input) long The number of columns of the matrix VT. NCVT >= 0. NRU (input) long The number of rows of the matrix U. NRU >= 0. NCC (input) long The number of columns of the matrix C. NCC >= 0. D (input/output) double array, dimension (N) On entry, the n diagonal elements of the bidiagonal matrix B. On exit, if INFO=0, the singular values of B in decreasing order. E (input/output) double array, dimension (N) On entry, the elements of E contain the offdiagonal elements of the bidiagonal matrix whose SVD is desired. On normal exit (INFO = 0), E is destroyed. If the algorithm does not converge (INFO > 0), D and E will contain the diagonal and superdiagonal elements of a bidiagonal matrix orthogonally equivalent to the one given as input. E(N) is used for workspace. VT (input/output) double array, dimension (LDVT, NCVT) On entry, an N-by-NCVT matrix VT. On exit, VT is overwritten by P' * VT. VT is not referenced if NCVT = 0. LDVT (input) long The leading dimension of the array VT. LDVT >= max(1,N) if NCVT > 0; LDVT >= 1 if NCVT = 0. U (input/output) double array, dimension (LDU, N) On entry, an NRU-by-N matrix U. On exit, U is overwritten by U * Q. U is not referenced if NRU = 0. LDU (input) long The leading dimension of the array U. LDU >= max(1,NRU). C (input/output) double array, dimension (LDC, NCC) On entry, an N-by-NCC matrix C. On exit, C is overwritten by Q' * C. C is not referenced if NCC = 0. LDC (input) long The leading dimension of the array C. LDC >= max(1,N) if NCC > 0; LDC >=1 if NCC = 0. WORK (workspace) double array, dimension (4*N) INFO (output) long = 0: successful exit < 0: If INFO = -i, the i-th argument had an illegal value > 0: the algorithm did not converge; D and E contain the elements of a bidiagonal matrix which is orthogonally similar to the input matrix B; if INFO = i, i elements of E have not converged to zero. Internal Parameters =================== TOLMUL double, default = max(10,min(100,EPS**(-1/8))) TOLMUL controls the convergence criterion of the QR loop. If it is positive, TOLMUL*EPS is the desired relative precision in the computed singular values. If it is negative, abs(TOLMUL*EPS*sigma_max) is the desired absolute accuracy in the computed singular values (corresponds to relative accuracy abs(TOLMUL*EPS) in the largest singular value. abs(TOLMUL) should be between 1 and 1/EPS, and preferably between 10 (for fast convergence) and .1/EPS (for there to be some accuracy in the results). Default is to lose at either one eighth or 2 of the available decimal digits in each computed singular value (whichever is smaller). MAXITR long, default = 6 MAXITR controls the maximum number of passes of the algorithm through its inner loop. The algorithms stops (and so fails to converge) if the number of passes through the inner loop exceeds MAXITR*N**2. ===================================================================== */ int NUMlapack_dgebd2(long *m, long *n, double *a, long *lda, double *d, double *e, double *tauq, double *taup, double *work, long *info); /* Purpose ======= NUMlapack_dgebd2 reduces a real general m by n matrix A to upper or lower bidiagonal form B by an orthogonal transformation: Q' * A * P = B. If m >= n, B is upper bidiagonal; if m < n, B is lower bidiagonal. Arguments ========= M (input) long The number of rows in the matrix A. M >= 0. N (input) long The number of columns in the matrix A. N >= 0. A (input/output) double array, dimension (LDA,N) On entry, the m by n general matrix to be reduced. On exit, if m >= n, the diagonal and the first superdiagonal are overwritten with the upper bidiagonal matrix B; the elements below the diagonal, with the array TAUQ, represent the orthogonal matrix Q as a product of elementary reflectors, and the elements above the first superdiagonal, with the array TAUP, represent the orthogonal matrix P as a product of elementary reflectors; if m < n, the diagonal and the first subdiagonal are overwritten with the lower bidiagonal matrix B; the elements below the first subdiagonal, with the array TAUQ, represent the orthogonal matrix Q as a product of elementary reflectors, and the elements above the diagonal, with the array TAUP, represent the orthogonal matrix P as a product of elementary reflectors. See Further Details. LDA (input) long The leading dimension of the array A. LDA >= max(1,M). D (output) double array, dimension (min(M,N)) The diagonal elements of the bidiagonal matrix B: D(i) = A(i,i). E (output) double array, dimension (min(M,N)-1) The off-diagonal elements of the bidiagonal matrix B: if m >= n, E(i) = A(i,i+1) for i = 1,2,...,n-1; if m < n, E(i) = A(i+1,i) for i = 1,2,...,m-1. TAUQ (output) double array dimension (min(M,N)) The scalar factors of the elementary reflectors which represent the orthogonal matrix Q. See Further Details. TAUP (output) double array, dimension (min(M,N)) The scalar factors of the elementary reflectors which represent the orthogonal matrix P. See Further Details. WORK (workspace) double array, dimension (max(M,N)) INFO (output) long = 0: successful exit. < 0: if INFO = -i, the i-th argument had an illegal value. Further Details =============== The matrices Q and P are represented as products of elementary reflectors: If m >= n, Q = H(1) H(2) . . . H(n) and P = G(1) G(2) . . . G(n-1) Each H(i) and G(i) has the form: H(i) = I - tauq * v * v' and G(i) = I - taup * u * u' where tauq and taup are real scalars, and v and u are real vectors; v(1:i-1) = 0, v(i) = 1, and v(i+1:m) is stored on exit in A(i+1:m,i); u(1:i) = 0, u(i+1) = 1, and u(i+2:n) is stored on exit in A(i,i+2:n); tauq is stored in TAUQ(i) and taup in TAUP(i). If m < n, Q = H(1) H(2) . . . H(m-1) and P = G(1) G(2) . . . G(m) Each H(i) and G(i) has the form: H(i) = I - tauq * v * v' and G(i) = I - taup * u * u' where tauq and taup are real scalars, and v and u are real vectors; v(1:i) = 0, v(i+1) = 1, and v(i+2:m) is stored on exit in A(i+2:m,i); u(1:i-1) = 0, u(i) = 1, and u(i+1:n) is stored on exit in A(i,i+1:n); tauq is stored in TAUQ(i) and taup in TAUP(i). The contents of A on exit are illustrated by the following examples: m = 6 and n = 5 (m > n): m = 5 and n = 6 (m < n): ( d e u1 u1 u1 ) ( d u1 u1 u1 u1 u1 ) ( v1 d e u2 u2 ) ( e d u2 u2 u2 u2 ) ( v1 v2 d e u3 ) ( v1 e d u3 u3 u3 ) ( v1 v2 v3 d e ) ( v1 v2 e d u4 u4 ) ( v1 v2 v3 v4 d ) ( v1 v2 v3 e d u5 ) ( v1 v2 v3 v4 v5 ) where d and e denote diagonal and off-diagonal elements of B, vi denotes an element of the vector defining H(i), and ui an element of the vector defining G(i). ===================================================================== */ int NUMlapack_dgebrd(long *m, long *n, double *a, long *lda, double *d, double *e, double *tauq, double *taup, double *work, long *lwork, long *info); /* Purpose ======= NUMlapack_dgebrd reduces a general real M-by-N matrix A to upper or lower bidiagonal form B by an orthogonal transformation: Q**T * A * P = B. If m >= n, B is upper bidiagonal; if m < n, B is lower bidiagonal. Arguments ========= M (input) long The number of rows in the matrix A. M >= 0. N (input) long The number of columns in the matrix A. N >= 0. A (input/output) double array, dimension (LDA,N) On entry, the M-by-N general matrix to be reduced. On exit, if m >= n, the diagonal and the first superdiagonal are overwritten with the upper bidiagonal matrix B; the elements below the diagonal, with the array TAUQ, represent the orthogonal matrix Q as a product of elementary reflectors, and the elements above the first superdiagonal, with the array TAUP, represent the orthogonal matrix P as a product of elementary reflectors; if m < n, the diagonal and the first subdiagonal are overwritten with the lower bidiagonal matrix B; the elements below the first subdiagonal, with the array TAUQ, represent the orthogonal matrix Q as a product of elementary reflectors, and the elements above the diagonal, with the array TAUP, represent the orthogonal matrix P as a product of elementary reflectors. See Further Details. LDA (input) long The leading dimension of the array A. LDA >= max(1,M). D (output) double array, dimension (min(M,N)) The diagonal elements of the bidiagonal matrix B: D(i) = A(i,i). E (output) double array, dimension (min(M,N)-1) The off-diagonal elements of the bidiagonal matrix B: if m >= n, E(i) = A(i,i+1) for i = 1,2,...,n-1; if m < n, E(i) = A(i+1,i) for i = 1,2,...,m-1. TAUQ (output) double array dimension (min(M,N)) The scalar factors of the elementary reflectors which represent the orthogonal matrix Q. See Further Details. TAUP (output) double array, dimension (min(M,N)) The scalar factors of the elementary reflectors which represent the orthogonal matrix P. See Further Details. WORK (workspace/output) double array, dimension (LWORK) On exit, if INFO = 0, WORK(1) returns the optimal LWORK. LWORK (input) long The length of the array WORK. LWORK >= max(1,M,N). For optimum performance LWORK >= (M+N)*NB, where NB is the optimal blocksize. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value. Further Details =============== The matrices Q and P are represented as products of elementary reflectors: If m >= n, Q = H(1) H(2) . . . H(n) and P = G(1) G(2) . . . G(n-1) Each H(i) and G(i) has the form: H(i) = I - tauq * v * v' and G(i) = I - taup * u * u' where tauq and taup are real scalars, and v and u are real vectors; v(1:i-1) = 0, v(i) = 1, and v(i+1:m) is stored on exit in A(i+1:m,i); u(1:i) = 0, u(i+1) = 1, and u(i+2:n) is stored on exit in A(i,i+2:n); tauq is stored in TAUQ(i) and taup in TAUP(i). If m < n, Q = H(1) H(2) . . . H(m-1) and P = G(1) G(2) . . . G(m) Each H(i) and G(i) has the form: H(i) = I - tauq * v * v' and G(i) = I - taup * u * u' where tauq and taup are real scalars, and v and u are real vectors; v(1:i) = 0, v(i+1) = 1, and v(i+2:m) is stored on exit in A(i+2:m,i); u(1:i-1) = 0, u(i) = 1, and u(i+1:n) is stored on exit in A(i,i+1:n); tauq is stored in TAUQ(i) and taup in TAUP(i). The contents of A on exit are illustrated by the following examples: m = 6 and n = 5 (m > n): m = 5 and n = 6 (m < n): ( d e u1 u1 u1 ) ( d u1 u1 u1 u1 u1 ) ( v1 d e u2 u2 ) ( e d u2 u2 u2 u2 ) ( v1 v2 d e u3 ) ( v1 e d u3 u3 u3 ) ( v1 v2 v3 d e ) ( v1 v2 e d u4 u4 ) ( v1 v2 v3 v4 d ) ( v1 v2 v3 e d u5 ) ( v1 v2 v3 v4 v5 ) where d and e denote diagonal and off-diagonal elements of B, vi denotes an element of the vector defining H(i), and ui an element of the vector defining G(i). ===================================================================== */ int NUMlapack_dgebak (const char *job, const char *side, long *n, long *ilo, long *ihi, double *scale, long *m, double *v, long *ldv, long *info); /* -- LAPACK routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University September 30, 1994 Purpose ======= NUMlapack_dgebak forms the right or left eigenvectors of a real general matrix by backward transformation on the computed eigenvectors of the balanced matrix output by NUMlapack_dgebal. Arguments ========= JOB (input) char* Specifies the type of backward transformation required: = 'N', do nothing, return immediately; = 'P', do backward transformation for permutation only; = 'S', do backward transformation for scaling only; = 'B', do backward transformations for both permutation and scaling. JOB must be the same as the argument JOB supplied to NUMlapack_dgebal. SIDE (input) char* = 'R': V contains right eigenvectors; = 'L': V contains left eigenvectors. N (input) long The number of rows of the matrix V. N >= 0. ILO (input) long IHI (input) long The integers ILO and IHI determined by NUMlapack_dgebal. 1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0. SCALE (input) double array, dimension (N) Details of the permutation and scaling factors, as returned by NUMlapack_dgebal. M (input) long The number of columns of the matrix V. M >= 0. V (input/output) double array, dimension (LDV,M) On entry, the matrix of right or left eigenvectors to be transformed, as returned by DHSEIN or NUMlapack_dtrevc. On exit, V is overwritten by the transformed eigenvectors. LDV (input) long The leading dimension of the array V. LDV >= max(1,N). INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value. ===================================================================== */ int NUMlapack_dgebal (const char *job, long *n, double *a, long *lda, long *ilo, long *ihi, double *scale, long *info); /* -- LAPACK routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University June 30, 1999 Purpose ======= NUMlapack_dgebal balances a general real matrix A. This involves, first, permuting A by a similarity transformation to isolate eigenvalues in the first 1 to ILO-1 and last IHI+1 to N elements on the diagonal; and second, applying a diagonal similarity transformation to rows and columns ILO to IHI to make the rows and columns as close in norm as possible. Both steps are optional. Balancing may reduce the 1-norm of the matrix, and improve the accuracy of the computed eigenvalues and/or eigenvectors. Arguments ========= JOB (input) char* Specifies the operations to be performed on A: = 'N': none: simply set ILO = 1, IHI = N, SCALE(I) = 1.0 for i = 1,...,N; = 'P': permute only; = 'S': scale only; = 'B': both permute and scale. N (input) long The order of the matrix A. N >= 0. A (input/output) double array, dimension (LDA,N) On entry, the input matrix A. On exit, A is overwritten by the balanced matrix. If JOB = 'N', A is not referenced. See Further Details. LDA (input) long The leading dimension of the array A. LDA >= max(1,N). ILO (output) long IHI (output) long ILO and IHI are set to integers such that on exit A(i,j) = 0 if i > j and j = 1,...,ILO-1 or I = IHI+1,...,N. If JOB = 'N' or 'S', ILO = 1 and IHI = N. SCALE (output) double array, dimension (N) Details of the permutations and scaling factors applied to A. If P(j) is the index of the row and column interchanged with row and column j and D(j) is the scaling factor applied to row and column j, then SCALE(j) = P(j) for j = 1,...,ILO-1 = D(j) for j = ILO,...,IHI = P(j) for j = IHI+1,...,N. The order in which the interchanges are made is N to IHI+1, then 1 to ILO-1. INFO (output) long = 0: successful exit. < 0: if INFO = -i, the i-th argument had an illegal value. Further Details =============== The permutations consist of row and column interchanges which put the matrix in the form ( T1 X Y ) P A P = ( 0 B Z ) ( 0 0 T2 ) where T1 and T2 are upper triangular matrices whose eigenvalues lie along the diagonal. The column indices ILO and IHI mark the starting and ending columns of the submatrix B. Balancing consists of applying a diagonal similarity transformation inv(D) * B * D to make the 1-norms of each row of B and its corresponding column nearly equal. The output matrix is ( T1 X*D Y ) ( 0 inv(D)*B*D inv(D)*Z ). ( 0 0 T2 ) Information about the permutations P and the diagonal matrix D is returned in the vector SCALE. This subroutine is based on the EISPACK routine BALANC. Modified by Tzu-Yi Chen, Computer Science Division, University of California at Berkeley, USA ===================================================================== */ int NUMlapack_dgeev (const char *jobvl, const char *jobvr, long *n, double *a, long *lda, double *wr, double *wi, double *vl, long *ldvl, double *vr, long *ldvr, double *work, long *lwork, long *info); /* -- LAPACK driver routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University December 8, 1999 Purpose ======= NUMlapack_dgeev computes for an N-by-N real nonsymmetric matrix A, the eigenvalues and, optionally, the left and/or right eigenvectors. The right eigenvector v(j) of A satisfies A * v(j) = lambda(j) * v(j) where lambda(j) is its eigenvalue. The left eigenvector u(j) of A satisfies u(j)**H * A = lambda(j) * u(j)**H where u(j)**H denotes the conjugate transpose of u(j). The computed eigenvectors are normalized to have Euclidean norm equal to 1 and largest component real. Arguments ========= JOBVL (input) char* = 'N': left eigenvectors of A are not computed; = 'V': left eigenvectors of A are computed. JOBVR (input) char* = 'N': right eigenvectors of A are not computed; = 'V': right eigenvectors of A are computed. N (input) long The order of the matrix A. N >= 0. A (input/output) double array, dimension (LDA,N) On entry, the N-by-N matrix A. On exit, A has been overwritten. LDA (input) long The leading dimension of the array A. LDA >= max(1,N). WR (output) double array, dimension (N) WI (output) double array, dimension (N) WR and WI contain the real and imaginary parts, respectively, of the computed eigenvalues. Complex conjugate pairs of eigenvalues appear consecutively with the eigenvalue having the positive imaginary part first. VL (output) double array, dimension (LDVL,N) If JOBVL = 'V', the left eigenvectors u(j) are stored one after another in the columns of VL, in the same order as their eigenvalues. If JOBVL = 'N', VL is not referenced. If the j-th eigenvalue is real, then u(j) = VL(:,j), the j-th column of VL. If the j-th and (j+1)-st eigenvalues form a complex conjugate pair, then u(j) = VL(:,j) + i*VL(:,j+1) and u(j+1) = VL(:,j) - i*VL(:,j+1). LDVL (input) long The leading dimension of the array VL. LDVL >= 1; if JOBVL = 'V', LDVL >= N. VR (output) double array, dimension (LDVR,N) If JOBVR = 'V', the right eigenvectors v(j) are stored one after another in the columns of VR, in the same order as their eigenvalues. If JOBVR = 'N', VR is not referenced. If the j-th eigenvalue is real, then v(j) = VR(:,j), the j-th column of VR. If the j-th and (j+1)-st eigenvalues form a complex conjugate pair, then v(j) = VR(:,j) + i*VR(:,j+1) and v(j+1) = VR(:,j) - i*VR(:,j+1). LDVR (input) long The leading dimension of the array VR. LDVR >= 1; if JOBVR = 'V', LDVR >= N. WORK (workspace/output) double array, dimension (LWORK) On exit, if INFO = 0, WORK(1) returns the optimal LWORK. LWORK (input) long The dimension of the array WORK. LWORK >= max(1,3*N), and if JOBVL = 'V' or JOBVR = 'V', LWORK >= 4*N. For good performance, LWORK must generally be larger. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value. > 0: if INFO = i, the QR algorithm failed to compute all the eigenvalues, and no eigenvectors have been computed; elements i+1:N of WR and WI contain eigenvalues which have converged. ===================================================================== */ int NUMlapack_dgehd2 (long *n, long *ilo, long *ihi, double *a, long *lda, double *tau, double *work, long *info); /* -- LAPACK routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University October 31, 1992 Purpose ======= NUMlapack_dgehd2 reduces a real general matrix A to upper Hessenberg form H by an orthogonal similarity transformation: Q' * A * Q = H . Arguments ========= N (input) long The order of the matrix A. N >= 0. ILO (input) long IHI (input) long It is assumed that A is already upper triangular in rows and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally set by a previous call to NUMlapack_dgebal; otherwise they should be set to 1 and N respectively. See Further Details. 1 <= ILO <= IHI <= max(1,N). A (input/output) double array, dimension (LDA,N) On entry, the n by n general matrix to be reduced. On exit, the upper triangle and the first subdiagonal of A are overwritten with the upper Hessenberg matrix H, and the elements below the first subdiagonal, with the array TAU, represent the orthogonal matrix Q as a product of elementary reflectors. See Further Details. LDA (input) long The leading dimension of the array A. LDA >= max(1,N). TAU (output) double array, dimension (N-1) The scalar factors of the elementary reflectors (see Further Details). WORK (workspace) double array, dimension (N) INFO (output) long = 0: successful exit. < 0: if INFO = -i, the i-th argument had an illegal value. Further Details =============== The matrix Q is represented as a product of (ihi-ilo) elementary reflectors Q = H(ilo) H(ilo+1) . . . H(ihi-1). Each H(i) has the form H(i) = I - tau * v * v' where tau is a real scalar, and v is a real vector with v(1:i) = 0, v(i+1) = 1 and v(ihi+1:n) = 0; v(i+2:ihi) is stored on exit in A(i+2:ihi,i), and tau in TAU(i). The contents of A are illustrated by the following example, with n = 7, ilo = 2 and ihi = 6: on entry, on exit, ( a a a a a a a ) ( a a h h h h a ) ( a a a a a a ) ( a h h h h a ) ( a a a a a a ) ( h h h h h h ) ( a a a a a a ) ( v2 h h h h h ) ( a a a a a a ) ( v2 v3 h h h h ) ( a a a a a a ) ( v2 v3 v4 h h h ) ( a ) ( a ) where a denotes an element of the original matrix A, h denotes a modified element of the upper Hessenberg matrix H, and vi denotes an element of the vector defining H(i). ===================================================================== */ int NUMlapack_dgehrd (long *n, long *ilo, long *ihi, double *a, long *lda, double *tau, double *work, long *lwork, long *info); /* -- LAPACK routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University June 30, 1999 Purpose ======= NUMlapack_dgehrd reduces a real general matrix A to upper Hessenberg form H by an orthogonal similarity transformation: Q' * A * Q = H . Arguments ========= N (input) long The order of the matrix A. N >= 0. ILO (input) long IHI (input) long It is assumed that A is already upper triangular in rows and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally set by a previous call to NUMlapack_dgebal; otherwise they should be set to 1 and N respectively. See Further Details. 1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0. A (input/output) double array, dimension (LDA,N) On entry, the N-by-N general matrix to be reduced. On exit, the upper triangle and the first subdiagonal of A are overwritten with the upper Hessenberg matrix H, and the elements below the first subdiagonal, with the array TAU, represent the orthogonal matrix Q as a product of elementary reflectors. See Further Details. LDA (input) long The leading dimension of the array A. LDA >= max(1,N). TAU (output) double array, dimension (N-1) The scalar factors of the elementary reflectors (see Further Details). Elements 1:ILO-1 and IHI:N-1 of TAU are set to zero. WORK (workspace/output) double array, dimension (LWORK) On exit, if INFO = 0, WORK(1) returns the optimal LWORK. LWORK (input) long The length of the array WORK. LWORK >= max(1,N). For optimum performance LWORK >= N*NB, where NB is the optimal blocksize. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value. Further Details =============== The matrix Q is represented as a product of (ihi-ilo) elementary reflectors Q = H(ilo) H(ilo+1) . . . H(ihi-1). Each H(i) has the form H(i) = I - tau * v * v' where tau is a real scalar, and v is a real vector with v(1:i) = 0, v(i+1) = 1 and v(ihi+1:n) = 0; v(i+2:ihi) is stored on exit in A(i+2:ihi,i), and tau in TAU(i). The contents of A are illustrated by the following example, with n = 7, ilo = 2 and ihi = 6: on entry, on exit, ( a a a a a a a ) ( a a h h h h a ) ( a a a a a a ) ( a h h h h a ) ( a a a a a a ) ( h h h h h h ) ( a a a a a a ) ( v2 h h h h h ) ( a a a a a a ) ( v2 v3 h h h h ) ( a a a a a a ) ( v2 v3 v4 h h h ) ( a ) ( a ) where a denotes an element of the original matrix A, h denotes a modified element of the upper Hessenberg matrix H, and vi denotes an element of the vector defining H(i). ===================================================================== */ int NUMlapack_dgelq2 (long *m, long *n, double *a, long *lda, double *tau, double *work, long *info); /* Purpose ======= NUMlapack_dgelq2 computes an LQ factorization of a real m by n matrix A: A = L * Q. Arguments ========= M (input) long The number of rows of the matrix A. M >= 0. N (input) long The number of columns of the matrix A. N >= 0. A (input/output) double array, dimension (LDA,N) On entry, the m by n matrix A. On exit, the elements on and below the diagonal of the array contain the m by min(m,n) lower trapezoidal matrix L (L is lower triangular if m <= n); the elements above the diagonal, with the array TAU, represent the orthogonal matrix Q as a product of elementary reflectors (see Further Details). LDA (input) long The leading dimension of the array A. LDA >= max(1,M). TAU (output) double array, dimension (min(M,N)) The scalar factors of the elementary reflectors (see Further Details). WORK (workspace) double array, dimension (M) INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value Further Details =============== The matrix Q is represented as a product of elementary reflectors Q = H(k) . . . H(2) H(1), where k = min(m,n). Each H(i) has the form H(i) = I - tau * v * v' where tau is a real scalar, and v is a real vector with v(1:i-1) = 0 and v(i) = 1; v(i+1:n) is stored on exit in A(i,i+1:n), and tau in TAU(i). ===================================================================== */ int NUMlapack_dgelqf (long *m, long *n, double *a, long *lda, double *tau, double *work, long *lwork, long *info); /* Purpose ======= NUMlapack_dgelqf computes an LQ factorization of a real M-by-N matrix A: A = L * Q. Arguments ========= M (input) long The number of rows of the matrix A. M >= 0. N (input) long The number of columns of the matrix A. N >= 0. A (input/output) double array, dimension (LDA,N) On entry, the M-by-N matrix A. On exit, the elements on and below the diagonal of the array contain the m-by-min(m,n) lower trapezoidal matrix L (L is lower triangular if m <= n); the elements above the diagonal, with the array TAU, represent the orthogonal matrix Q as a product of elementary reflectors (see Further Details). LDA (input) long The leading dimension of the array A. LDA >= max(1,M). TAU (output) double array, dimension (min(M,N)) The scalar factors of the elementary reflectors (see Further Details). WORK (workspace/output) double array, dimension (LWORK) On exit, if INFO = 0, WORK(1) returns the optimal LWORK. LWORK (input) long The dimension of the array WORK. LWORK >= max(1,M). For optimum performance LWORK >= M*NB, where NB is the optimal blocksize. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value Further Details =============== The matrix Q is represented as a product of elementary reflectors Q = H(k) . . . H(2) H(1), where k = min(m,n). Each H(i) has the form H(i) = I - tau * v * v' where tau is a real scalar, and v is a real vector with v(1:i-1) = 0 and v(i) = 1; v(i+1:n) is stored on exit in A(i,i+1:n), and tau in TAU(i). ===================================================================== */ int NUMlapack_dgelss (long *m, long *n, long *nrhs, double *a, long *lda, double *b, long *ldb, double *s, double *rcond, long *rank, double *work, long *lwork, long *info); /* Purpose ======= NUMlapack_dgelss computes the minimum norm solution to a real linear least squares problem: Minimize 2-norm(| b - A*x |). using the singular value decomposition (SVD) of A. A is an M-by-N matrix which may be rank-deficient. Several right hand side vectors b and solution vectors x can be handled in a single call; they are stored as the columns of the M-by-NRHS right hand side matrix B and the N-by-NRHS solution matrix X. The effective rank of A is determined by treating as zero those singular values which are less than RCOND times the largest singular value. Arguments ========= M (input) long The number of rows of the matrix A. M >= 0. N (input) long The number of columns of the matrix A. N >= 0. NRHS (input) long The number of right hand sides, i.e., the number of columns of the matrices B and X. NRHS >= 0. A (input/output) double array, dimension (LDA,N) On entry, the M-by-N matrix A. On exit, the first min(m,n) rows of A are overwritten with its right singular vectors, stored rowwise. LDA (input) long The leading dimension of the array A. LDA >= max(1,M). B (input/output) double array, dimension (LDB,NRHS) On entry, the M-by-NRHS right hand side matrix B. On exit, B is overwritten by the N-by-NRHS solution matrix X. If m >= n and RANK = n, the residual sum-of-squares for the solution in the i-th column is given by the sum of squares of elements n+1:m in that column. LDB (input) long The leading dimension of the array B. LDB >= max(1,max(M,N)). S (output) double array, dimension (min(M,N)) The singular values of A in decreasing order. The condition number of A in the 2-norm = S(1)/S(min(m,n)). RCOND (input) double RCOND is used to determine the effective rank of A. Singular values S(i) <= RCOND*S(1) are treated as zero. If RCOND < 0, machine precision is used instead. RANK (output) long The effective rank of A, i.e., the number of singular values which are greater than RCOND*S(1). WORK (workspace/output) double array, dimension (LWORK) On exit, if INFO = 0, WORK(1) returns the optimal LWORK. LWORK (input) long The dimension of the array WORK. LWORK >= 1, and also: LWORK >= 3*min(M,N) + max( 2*min(M,N), max(M,N), NRHS ) For good performance, LWORK should generally be larger. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value. > 0: the algorithm for computing the SVD failed to converge; if INFO = i, i off-diagonal elements of an intermediate bidiagonal form did not converge to zero. ===================================================================== */ int NUMlapack_dgeqpf (long *m, long *n, double *a, long *lda, long *jpvt, double *tau, double *work, long *info); /* Purpose ======= This routine is deprecated and has been replaced by routine DGEQP3. NUMlapack_dgeqpf computes a QR factorization with column pivoting of a real M-by-N matrix A: A*P = Q*R. Arguments ========= M (input) long The number of rows of the matrix A. M >= 0. N (input) long The number of columns of the matrix A. N >= 0 A (input/output) double array, dimension (LDA,N) On entry, the M-by-N matrix A. On exit, the upper triangle of the array contains the min(M,N)-by-N upper triangular matrix R; the elements below the diagonal, together with the array TAU, represent the orthogonal matrix Q as a product of min(m,n) elementary reflectors. LDA (input) long The leading dimension of the array A. LDA >= max(1,M). JPVT (input/output) long array, dimension (N) On entry, if JPVT(i) .ne. 0, the i-th column of A is permuted to the front of A*P (a leading column); if JPVT(i) = 0, the i-th column of A is a free column. On exit, if JPVT(i) = k, then the i-th column of A*P was the k-th column of A. TAU (output) double array, dimension (min(M,N)) The scalar factors of the elementary reflectors. WORK (workspace) double array, dimension (3*N) INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value Further Details =============== The matrix Q is represented as a product of elementary reflectors Q = H(1) H(2) . . . H(n) Each H(i) has the form H = I - tau * v * v' where tau is a real scalar, and v is a real vector with v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i). The matrix P is represented in jpvt as follows: If jpvt(j) = i then the jth column of P is the ith canonical unit vector. ===================================================================== */ int NUMlapack_dgeqr2 (long *m, long *n, double *a, long *lda, double *tau, double *work, long *info); /* Purpose ======= NUMlapack_dgeqr2 computes a QR factorization of a real m by n matrix A: A = Q * R. Arguments ========= M (input) long The number of rows of the matrix A. M >= 0. N (input) long The number of columns of the matrix A. N >= 0. A (input/output) double array, dimension (LDA,N) On entry, the m by n matrix A. On exit, the elements on and above the diagonal of the array contain the min(m,n) by n upper trapezoidal matrix R (R is upper triangular if m >= n); the elements below the diagonal, with the array TAU, represent the orthogonal matrix Q as a product of elementary reflectors (see Further Details). LDA (input) long The leading dimension of the array A. LDA >= max(1,M). TAU (output) double array, dimension (min(M,N)) The scalar factors of the elementary reflectors (see Further Details). WORK (workspace) double array, dimension (N) INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value Further Details =============== The matrix Q is represented as a product of elementary reflectors Q = H(1) H(2) . . . H(k), where k = min(m,n). Each H(i) has the form H(i) = I - tau * v * v' where tau is a real scalar, and v is a real vector with v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i), and tau in TAU(i). ===================================================================== */ int NUMlapack_dgeqrf(long *m, long *n, double *a, long *lda, double *tau, double *work, long *lwork, long *info); /* Purpose ======= NUMlapack_dgeqrf computes a QR factorization of a real M-by-N matrix A: A = Q * R. Arguments ========= M (input) long The number of rows of the matrix A. M >= 0. N (input) long The number of columns of the matrix A. N >= 0. A (input/output) double array, dimension (LDA,N) On entry, the M-by-N matrix A. On exit, the elements on and above the diagonal of the array contain the min(M,N)-by-N upper trapezoidal matrix R (R is upper triangular if m >= n); the elements below the diagonal, with the array TAU, represent the orthogonal matrix Q as a product of min(m,n) elementary reflectors (see Further Details). LDA (input) long The leading dimension of the array A. LDA >= max(1,M). TAU (output) double array, dimension (min(M,N)) The scalar factors of the elementary reflectors (see Further Details). WORK (workspace/output) double array, dimension (LWORK) On exit, if INFO = 0, WORK(1) returns the optimal LWORK. LWORK (input) long The dimension of the array WORK. LWORK >= max(1,N). For optimum performance LWORK >= N*NB, where NB is the optimal blocksize. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value Further Details =============== The matrix Q is represented as a product of elementary reflectors Q = H(1) H(2) . . . H(k), where k = min(m,n). Each H(i) has the form H(i) = I - tau * v * v' where tau is a real scalar, and v is a real vector with v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i), and tau in TAU(i). ===================================================================== */ int NUMlapack_dgerq2(long *m, long *n, double *a, long *lda, double *tau, double *work, long *info); /* Purpose ======= NUMlapack_dgerq2 computes an RQ factorization of a real m by n matrix A: A = R * Q. Arguments ========= M (input) long The number of rows of the matrix A. M >= 0. N (input) long The number of columns of the matrix A. N >= 0. A (input/output) double array, dimension (LDA,N) On entry, the m by n matrix A. On exit, if m <= n, the upper triangle of the subarray A(1:m,n-m+1:n) contains the m by m upper triangular matrix R; if m >= n, the elements on and above the (m-n)-th subdiagonal contain the m by n upper trapezoidal matrix R; the remaining elements, with the array TAU, represent the orthogonal matrix Q as a product of elementary reflectors (see Further Details). LDA (input) long The leading dimension of the array A. LDA >= max(1,M). TAU (output) double array, dimension (min(M,N)) The scalar factors of the elementary reflectors (see Further Details). WORK (workspace) double array, dimension (M) INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value Further Details =============== The matrix Q is represented as a product of elementary reflectors Q = H(1) H(2) . . . H(k), where k = min(m,n). Each H(i) has the form H(i) = I - tau * v * v' where tau is a real scalar, and v is a real vector with v(n-k+i+1:n) = 0 and v(n-k+i) = 1; v(1:n-k+i-1) is stored on exit in A(m-k+i,1:n-k+i-1), and tau in TAU(i). ===================================================================== */ int NUMlapack_dgesv (long *n, long *nrhs, double *a, long *lda, long *ipiv, double *b, long *ldb, long *info); /* Purpose ======= NUMlapack_dgesv computes the solution to a real system of linear equations A * X = B, where A is an N-by-N matrix and X and B are N-by-NRHS matrices. The LU decomposition with partial pivoting and row interchanges is used to factor A as A = P * L * U, where P is a permutation matrix, L is unit lower triangular, and U is upper triangular. The factored form of A is then used to solve the system of equations A * X = B. Arguments ========= N (input) long The number of linear equations, i.e., the order of the matrix A. N >= 0. NRHS (input) long The number of right hand sides, i.e., the number of columns of the matrix B. NRHS >= 0. A (input/output) double array, dimension (LDA,N) On entry, the N-by-N coefficient matrix A. On exit, the factors L and U from the factorization A = P*L*U; the unit diagonal elements of L are not stored. LDA (input) long The leading dimension of the array A. LDA >= max(1,N). IPIV (output) long array, dimension (N) The pivot indices that define the permutation matrix P; row i of the matrix was interchanged with row IPIV(i). B (input/output) double array, dimension (LDB,NRHS) On entry, the N-by-NRHS matrix of right hand side matrix B. On exit, if INFO = 0, the N-by-NRHS solution matrix X. LDB (input) long The leading dimension of the array B. LDB >= max(1,N). INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value > 0: if INFO = i, U(i,i) is exactly zero. The factorization has been completed, but the factor U is exactly singular, so the solution could not be computed. ===================================================================== */ int NUMlapack_dgesvd (const char *jobu, const char *jobvt, long *m, long *n, double *a, long *lda, double *s, double *u, long *ldu, double *vt, long *ldvt, double *work, long *lwork, long *info); /* Purpose ======= NUMlapack_dgesvd computes the singular value decomposition (SVD) of a real M-by-N matrix A, optionally computing the left and/or right singular vectors. The SVD is written A = U * SIGMA * transpose(V) where SIGMA is an M-by-N matrix which is zero except for its min(m,n) diagonal elements, U is an M-by-M orthogonal matrix, and V is an N-by-N orthogonal matrix. The diagonal elements of SIGMA are the singular values of A; they are real and non-negative, and are returned in descending order. The first min(m,n) columns of U and V are the left and right singular vectors of A. Note that the routine returns V**T, not V. Arguments ========= JOBU (input) char* Specifies options for computing all or part of the matrix U: = 'A': all M columns of U are returned in array U: = 'S': the first min(m,n) columns of U (the left singular vectors) are returned in the array U; = 'O': the first min(m,n) columns of U (the left singular vectors) are overwritten on the array A; = 'N': no columns of U (no left singular vectors) are computed. JOBVT (input) char* Specifies options for computing all or part of the matrix V**T: = 'A': all N rows of V**T are returned in the array VT; = 'S': the first min(m,n) rows of V**T (the right singular vectors) are returned in the array VT; = 'O': the first min(m,n) rows of V**T (the right singular vectors) are overwritten on the array A; = 'N': no rows of V**T (no right singular vectors) are computed. JOBVT and JOBU cannot both be 'O'. M (input) long The number of rows of the input matrix A. M >= 0. N (input) long The number of columns of the input matrix A. N >= 0. A (input/output) double array, dimension (LDA,N) On entry, the M-by-N matrix A. On exit, if JOBU = 'O', A is overwritten with the first min(m,n) columns of U (the left singular vectors, stored columnwise); if JOBVT = 'O', A is overwritten with the first min(m,n) rows of V**T (the right singular vectors, stored rowwise); if JOBU .ne. 'O' and JOBVT .ne. 'O', the contents of A are destroyed. LDA (input) long The leading dimension of the array A. LDA >= max(1,M). S (output) double array, dimension (min(M,N)) The singular values of A, sorted so that S(i) >= S(i+1). U (output) double array, dimension (LDU,UCOL) (LDU,M) if JOBU = 'A' or (LDU,min(M,N)) if JOBU = 'S'. If JOBU = 'A', U contains the M-by-M orthogonal matrix U; if JOBU = 'S', U contains the first min(m,n) columns of U (the left singular vectors, stored columnwise); if JOBU = 'N' or 'O', U is not referenced. LDU (input) long The leading dimension of the array U. LDU >= 1; if JOBU = 'S' or 'A', LDU >= M. VT (output) double array, dimension (LDVT,N) If JOBVT = 'A', VT contains the N-by-N orthogonal matrix V**T; if JOBVT = 'S', VT contains the first min(m,n) rows of V**T (the right singular vectors, stored rowwise); if JOBVT = 'N' or 'O', VT is not referenced. LDVT (input) long The leading dimension of the array VT. LDVT >= 1; if JOBVT = 'A', LDVT >= N; if JOBVT = 'S', LDVT >= min(M,N). WORK (workspace/output) double array, dimension (LWORK) On exit, if INFO = 0, WORK(1) returns the optimal LWORK; if INFO > 0, WORK(2:MIN(M,N)) contains the unconverged superdiagonal elements of an upper bidiagonal matrix B whose diagonal is in S (not necessarily sorted). B satisfies A = U * B * VT, so it has the same singular values as A, and singular vectors related by U and VT. LWORK (input) long The dimension of the array WORK. LWORK >= 1. LWORK >= MAX(3*MIN(M,N)+MAX(M,N),5*MIN(M,N)). For good performance, LWORK should generally be larger. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. INFO (output) long = 0: successful exit. < 0: if INFO = -i, the i-th argument had an illegal value. > 0: if DBDSQR did not converge, INFO specifies how many superdiagonals of an intermediate bidiagonal form B did not converge to zero. See the description of WORK above for details. ===================================================================== */ int NUMlapack_dgetf2 (long *m, long *n, double *a, long *lda, long *ipiv, long *info); /* Purpose ======= NUMlapack_dgetf2 computes an LU factorization of a general m-by-n matrix A using partial pivoting with row interchanges. The factorization has the form A = P * L * U where P is a permutation matrix, L is lower triangular with unit diagonal elements (lower trapezoidal if m > n), and U is upper triangular (upper trapezoidal if m < n). This is the right-looking Level 2 BLAS version of the algorithm. Arguments ========= M (input) long The number of rows of the matrix A. M >= 0. N (input) long The number of columns of the matrix A. N >= 0. A (input/output) double array, dimension (LDA,N) On entry, the m by n matrix to be factored. On exit, the factors L and U from the factorization A = P*L*U; the unit diagonal elements of L are not stored. LDA (input) long The leading dimension of the array A. LDA >= max(1,M). IPIV (output) long array, dimension (min(M,N)) The pivot indices; for 1 <= i <= min(M,N), row i of the matrix was interchanged with row IPIV(i). INFO (output) long = 0: successful exit < 0: if INFO = -k, the k-th argument had an illegal value > 0: if INFO = k, U(k,k) is exactly zero. The factorization has been completed, but the factor U is exactly singular, and division by zero will occur if it is used to solve a system of equations. ===================================================================== */ int NUMlapack_dgetri (long *n, double *a, long *lda, long *ipiv, double *work, long *lwork, long *info); /* Purpose ======= NUMlapack_dgetri computes the inverse of a matrix using the LU factorization computed by NUMlapack_dgetrf. This method inverts U and then computes inv(A) by solving the system inv(A)*L = inv(U) for inv(A). Arguments ========= N (input) long The order of the matrix A. N >= 0. A (input/output) double array, dimension (LDA,N) On entry, the factors L and U from the factorization A = P*L*U as computed by DGETRF. On exit, if INFO = 0, the inverse of the original matrix A. LDA (input) long The leading dimension of the array A. LDA >= max(1,N). IPIV (input) long array, dimension (N) The pivot indices from DGETRF; for 1<=i<=N, row i of the matrix was interchanged with row IPIV(i). WORK (workspace/output) double array, dimension (LWORK) On exit, if INFO=0, then WORK(1) returns the optimal LWORK. LWORK (input) long The dimension of the array WORK. LWORK >= max(1,N). For optimal performance LWORK >= N*NB, where NB is the optimal blocksize returned by NUMlapack_ilaenv. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value > 0: if INFO = i, U(i,i) is exactly zero; the matrix is singular and its inverse could not be computed. ===================================================================== */ int NUMlapack_dgetrf (long *m, long *n, double *a, long *lda, long *ipiv, long *info); /* Purpose ======= NUMlapack_dgetrf computes an LU factorization of a general M-by-N matrix A using partial pivoting with row interchanges. The factorization has the form A = P * L * U where P is a permutation matrix, L is lower triangular with unit diagonal elements (lower trapezoidal if m > n), and U is upper triangular (upper trapezoidal if m < n). This is the right-looking Level 3 BLAS version of the algorithm. Arguments ========= M (input) long The number of rows of the matrix A. M >= 0. N (input) long The number of columns of the matrix A. N >= 0. A (input/output) double array, dimension (LDA,N) On entry, the M-by-N matrix to be factored. On exit, the factors L and U from the factorization A = P*L*U; the unit diagonal elements of L are not stored. LDA (input) long The leading dimension of the array A. LDA >= max(1,M). IPIV (output) long array, dimension (min(M,N)) The pivot indices; for 1 <= i <= min(M,N), row i of the matrix was interchanged with row IPIV(i). INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value > 0: if INFO = i, U(i,i) is exactly zero. The factorization has been completed, but the factor U is exactly singular, and division by zero will occur if it is used to solve a system of equations. ===================================================================== */ int NUMlapack_dgetrs (const char *trans, long *n, long *nrhs, double *a, long *lda, long *ipiv, double *b, long *ldb, long *info); /* Purpose ======= NUMlapack_dgetrs solves a system of linear equations A * X = B or A' * X = B with a general N-by-N matrix A using the LU factorization computed by DGETRF. Arguments ========= TRANS (input) char* Specifies the form of the system of equations: = 'N': A * X = B (No transpose) = 'T': A'* X = B (Transpose) = 'C': A'* X = B (Conjugate transpose = Transpose) N (input) long The order of the matrix A. N >= 0. NRHS (input) long The number of right hand sides, i.e., the number of columns of the matrix B. NRHS >= 0. A (input) double array, dimension (LDA,N) The factors L and U from the factorization A = P*L*U as computed by DGETRF. LDA (input) long The leading dimension of the array A. LDA >= max(1,N). IPIV (input) long array, dimension (N) The pivot indices from DGETRF; for 1<=i<=N, row i of the matrix was interchanged with row IPIV(i). B (input/output) double array, dimension (LDB,NRHS) On entry, the right hand side matrix B. On exit, the solution matrix X. LDB (input) long The leading dimension of the array B. LDB >= max(1,N). INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value ===================================================================== */ int NUMlapack_dggsvd (const char *jobu, const char *jobv, const char *jobq, long *m, long *n, long *p, long *k, long *l, double *a, long *lda, double *b, long *ldb, double *alpha, double *beta, double *u, long *ldu, double *v, long *ldv, double *q, long *ldq, double *work, long *iwork, long *info); /* Purpose ======= NUMlapack_dggsvd computes the generalized singular value decomposition (GSVD) of an M-by-N real matrix A and P-by-N real matrix B: U'*A*Q = D1*( 0 R ), V'*B*Q = D2*( 0 R ) where U, V and Q are orthogonal matrices, and Z' is the transpose of Z. Let K+L = the effective numerical rank of the matrix (A',B')', then R is a K+L-by-K+L nonsingular upper triangular matrix, D1 and D2 are M-by-(K+L) and P-by-(K+L) "diagonal" matrices and of the following structures, respectively: If M-K-L >= 0, K L D1 = K ( I 0 ) L ( 0 C ) M-K-L ( 0 0 ) K L D2 = L ( 0 S ) P-L ( 0 0 ) N-K-L K L ( 0 R ) = K ( 0 R11 R12 ) L ( 0 0 R22 ) where C = diag( ALPHA(K+1), ... , ALPHA(K+L) ), S = diag( BETA(K+1), ... , BETA(K+L) ), C**2 + S**2 = I. R is stored in A(1:K+L,N-K-L+1:N) on exit. If M-K-L < 0, K M-K K+L-M D1 = K ( I 0 0 ) M-K ( 0 C 0 ) K M-K K+L-M D2 = M-K ( 0 S 0 ) K+L-M ( 0 0 I ) P-L ( 0 0 0 ) N-K-L K M-K K+L-M ( 0 R ) = K ( 0 R11 R12 R13 ) M-K ( 0 0 R22 R23 ) K+L-M ( 0 0 0 R33 ) where C = diag( ALPHA(K+1), ... , ALPHA(M) ), S = diag( BETA(K+1), ... , BETA(M) ), C**2 + S**2 = I. (R11 R12 R13 ) is stored in A(1:M, N-K-L+1:N), and R33 is stored ( 0 R22 R23 ) in B(M-K+1:L,N+M-K-L+1:N) on exit. The routine computes C, S, R, and optionally the orthogonal transformation matrices U, V and Q. In particular, if B is an N-by-N nonsingular matrix, then the GSVD of A and B implicitly gives the SVD of A*inv(B): A*inv(B) = U*(D1*inv(D2))*V'. If ( A',B')' has orthonormal columns, then the GSVD of A and B is also equal to the CS decomposition of A and B. Furthermore, the GSVD can be used to derive the solution of the eigenvalue problem: A'*A x = lambda* B'*B x. In some literature, the GSVD of A and B is presented in the form U'*A*X = ( 0 D1 ), V'*B*X = ( 0 D2 ) where U and V are orthogonal and X is nonsingular, D1 and D2 are ``diagonal''. The former GSVD form can be converted to the latter form by taking the nonsingular matrix X as X = Q*( I 0 ) ( 0 inv(R) ). Arguments ========= JOBU (input) char* = 'U': Orthogonal matrix U is computed; = 'N': U is not computed. JOBV (input) char* = 'V': Orthogonal matrix V is computed; = 'N': V is not computed. JOBQ (input) char* = 'Q': Orthogonal matrix Q is computed; = 'N': Q is not computed. M (input) long The number of rows of the matrix A. M >= 0. N (input) long The number of columns of the matrices A and B. N >= 0. P (input) long The number of rows of the matrix B. P >= 0. K (output) long L (output) long On exit, K and L specify the dimension of the subblocks described in the Purpose section. K + L = effective numerical rank of (A',B')'. A (input/output) double array, dimension (LDA,N) On entry, the M-by-N matrix A. On exit, A contains the triangular matrix R, or part of R. See Purpose for details. LDA (input) long The leading dimension of the array A. LDA >= max(1,M). B (input/output) double array, dimension (LDB,N) On entry, the P-by-N matrix B. On exit, B contains the triangular matrix R if M-K-L < 0. See Purpose for details. LDB (input) long The leading dimension of the array B. LDA >= max(1,P). ALPHA (output) double array, dimension (N) BETA (output) double array, dimension (N) On exit, ALPHA and BETA contain the generalized singular value pairs of A and B; ALPHA(1:K) = 1, BETA(1:K) = 0, and if M-K-L >= 0, ALPHA(K+1:K+L) = C, BETA(K+1:K+L) = S, or if M-K-L < 0, ALPHA(K+1:M)=C, ALPHA(M+1:K+L)=0 BETA(K+1:M) =S, BETA(M+1:K+L) =1 and ALPHA(K+L+1:N) = 0 BETA(K+L+1:N) = 0 U (output) double array, dimension (LDU,M) If JOBU = 'U', U contains the M-by-M orthogonal matrix U. If JOBU = 'N', U is not referenced. LDU (input) long The leading dimension of the array U. LDU >= max(1,M) if JOBU = 'U'; LDU >= 1 otherwise. V (output) double array, dimension (LDV,P) If JOBV = 'V', V contains the P-by-P orthogonal matrix V. If JOBV = 'N', V is not referenced. LDV (input) long The leading dimension of the array V. LDV >= max(1,P) if JOBV = 'V'; LDV >= 1 otherwise. Q (output) double array, dimension (LDQ,N) If JOBQ = 'Q', Q contains the N-by-N orthogonal matrix Q. If JOBQ = 'N', Q is not referenced. LDQ (input) long The leading dimension of the array Q. LDQ >= max(1,N) if JOBQ = 'Q'; LDQ >= 1 otherwise. WORK (workspace) double array, dimension (max(3*N,M,P)+N) IWORK (workspace/output) long array, dimension (N) On exit, IWORK stores the sorting information. More precisely, the following loop will sort ALPHA for I = K+1, min(M,K+L) swap ALPHA(I) and ALPHA(IWORK(I)) endfor such that ALPHA(1) >= ALPHA(2) >= ... >= ALPHA(N). INFO (output)long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value. > 0: if INFO = 1, the Jacobi-type procedure failed to converge. For further details, see subroutine NUMlapack_dtgsja. Internal Parameters =================== TOLA double TOLB double TOLA and TOLB are the thresholds to determine the effective rank of (A',B')'. Generally, they are set to TOLA = MAX(M,N)*norm(A)*MAZHEPS, TOLB = MAX(P,N)*norm(B)*MAZHEPS. The size of TOLA and TOLB may affect the size of backward errors of the decomposition. ===================================================================== */ int NUMlapack_dggsvp (const char *jobu, const char *jobv, const char *jobq, long *m, long *p, long *n, double *a, long *lda, double *b, long *ldb, double *tola, double *tolb, long *k, long *l, double *u, long *ldu, double *v, long *ldv, double *q, long *ldq, long *iwork, double *tau, double *work, long *info); /* Purpose ======= NUMlapack_dggsvp computes orthogonal matrices U, V and Q such that N-K-L K L U'*A*Q = K ( 0 A12 A13 ) if M-K-L >= 0; L ( 0 0 A23 ) M-K-L ( 0 0 0 ) N-K-L K L = K ( 0 A12 A13 ) if M-K-L < 0; M-K ( 0 0 A23 ) N-K-L K L V'*B*Q = L ( 0 0 B13 ) P-L ( 0 0 0 ) where the K-by-K matrix A12 and L-by-L matrix B13 are nonsingular upper triangular; A23 is L-by-L upper triangular if M-K-L >= 0, otherwise A23 is (M-K)-by-L upper trapezoidal. K+L = the effective numerical rank of the (M+P)-by-N matrix (A',B')'. Z' denotes the transpose of Z. This decomposition is the preprocessing step for computing the Generalized Singular Value Decomposition (GSVD), see subroutine NUMlapack_dggsvd. Arguments ========= JOBU (input) char* = 'U': Orthogonal matrix U is computed; = 'N': U is not computed. JOBV (input) char* = 'V': Orthogonal matrix V is computed; = 'N': V is not computed. JOBQ (input) char* = 'Q': Orthogonal matrix Q is computed; = 'N': Q is not computed. M (input) long The number of rows of the matrix A. M >= 0. P (input) long The number of rows of the matrix B. P >= 0. N (input) long The number of columns of the matrices A and B. N >= 0. A (input/output) double array, dimension (LDA,N) On entry, the M-by-N matrix A. On exit, A contains the triangular (or trapezoidal) matrix described in the Purpose section. LDA (input) long The leading dimension of the array A. LDA >= max(1,M). B (input/output) double array, dimension (LDB,N) On entry, the P-by-N matrix B. On exit, B contains the triangular matrix described in the Purpose section. LDB (input) long The leading dimension of the array B. LDB >= max(1,P). TOLA (input) double TOLB (input) double TOLA and TOLB are the thresholds to determine the effective numerical rank of matrix B and a subblock of A. Generally, they are set to TOLA = MAX(M,N)*norm(A)*MAZHEPS, TOLB = MAX(P,N)*norm(B)*MAZHEPS. The size of TOLA and TOLB may affect the size of backward errors of the decomposition. K (output) long L (output) long On exit, K and L specify the dimension of the subblocks described in Purpose. K + L = effective numerical rank of (A',B')'. U (output) double array, dimension (LDU,M) If JOBU = 'U', U contains the orthogonal matrix U. If JOBU = 'N', U is not referenced. LDU (input) long The leading dimension of the array U. LDU >= max(1,M) if JOBU = 'U'; LDU >= 1 otherwise. V (output) double array, dimension (LDV,M) If JOBV = 'V', V contains the orthogonal matrix V. If JOBV = 'N', V is not referenced. LDV (input) long The leading dimension of the array V. LDV >= max(1,P) if JOBV = 'V'; LDV >= 1 otherwise. Q (output) double array, dimension (LDQ,N) If JOBQ = 'Q', Q contains the orthogonal matrix Q. If JOBQ = 'N', Q is not referenced. LDQ (input) long The leading dimension of the array Q. LDQ >= max(1,N) if JOBQ = 'Q'; LDQ >= 1 otherwise. IWORK (workspace) long array, dimension (N) TAU (workspace) double array, dimension (N) WORK (workspace) double array, dimension (max(3*N,M,P)) INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value. Further Details =============== The subroutine uses LAPACK subroutine DGEQPF for the QR factorization with column pivoting to detect the effective numerical rank of the a matrix. It may be replaced by a better rank determination strategy. ===================================================================== */ int NUMlapack_dhseqr (const char *job, const char *compz, long *n, long *ilo, long *ihi, double *h, long *ldh, double *wr, double *wi, double *z, long *ldz, double *work, long *lwork, long *info); /* -- LAPACK routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University June 30, 1999 Purpose ======= NUMlapack_dhseqr computes the eigenvalues of a real upper Hessenberg matrix H and, optionally, the matrices T and Z from the Schur decomposition H = Z T Z**T, where T is an upper quasi-triangular matrix (the Schur form), and Z is the orthogonal matrix of Schur vectors. Optionally Z may be postmultiplied into an input orthogonal matrix Q, so that this routine can give the Schur factorization of a matrix A which has been reduced to the Hessenberg form H by the orthogonal matrix Q: A = Q*H*Q**T = (QZ)*T*(QZ)**T. Arguments ========= JOB (input) char* = 'E': compute eigenvalues only; = 'S': compute eigenvalues and the Schur form T. COMPZ (input) char* = 'N': no Schur vectors are computed; = 'I': Z is initialized to the unit matrix and the matrix Z of Schur vectors of H is returned; = 'V': Z must contain an orthogonal matrix Q on entry, and the product Q*Z is returned. N (input) long The order of the matrix H. N >= 0. ILO (input) long IHI (input) long It is assumed that H is already upper triangular in rows and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally set by a previous call to NUMlapack_dgebal, and then passed to SGEHRD when the matrix output by NUMlapack_dgebal is reduced to Hessenberg form. Otherwise ILO and IHI should be set to 1 and N respectively. 1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0. H (input/output) double array, dimension (LDH,N) On entry, the upper Hessenberg matrix H. On exit, if JOB = 'S', H contains the upper quasi-triangular matrix T from the Schur decomposition (the Schur form); 2-by-2 diagonal blocks (corresponding to complex conjugate pairs of eigenvalues) are returned in standard form, with H(i,i) = H(i+1,i+1) and H(i+1,i)*H(i,i+1) < 0. If JOB = 'E', the contents of H are unspecified on exit. LDH (input) long The leading dimension of the array H. LDH >= max(1,N). WR (output) double array, dimension (N) WI (output) double array, dimension (N) The real and imaginary parts, respectively, of the computed eigenvalues. If two eigenvalues are computed as a complex conjugate pair, they are stored in consecutive elements of WR and WI, say the i-th and (i+1)th, with WI(i) > 0 and WI(i+1) < 0. If JOB = 'S', the eigenvalues are stored in the same order as on the diagonal of the Schur form returned in H, with WR(i) = H(i,i) and, if H(i:i+1,i:i+1) is a 2-by-2 diagonal block, WI(i) = sqrt(H(i+1,i)*H(i,i+1)) and WI(i+1) = -WI(i). Z (input/output) double array, dimension (LDZ,N) If COMPZ = 'N': Z is not referenced. If COMPZ = 'I': on entry, Z need not be set, and on exit, Z contains the orthogonal matrix Z of the Schur vectors of H. If COMPZ = 'V': on entry Z must contain an N-by-N matrix Q, which is assumed to be equal to the unit matrix except for the submatrix Z(ILO:IHI,ILO:IHI); on exit Z contains Q*Z. Normally Q is the orthogonal matrix generated by NUMlapack_dorghr after the call to NUMlapack_dgehrd which formed the Hessenberg matrix H. LDZ (input) long The leading dimension of the array Z. LDZ >= max(1,N) if COMPZ = 'I' or 'V'; LDZ >= 1 otherwise. WORK (workspace/output) double array, dimension (LWORK) On exit, if INFO = 0, WORK(1) returns the optimal LWORK. LWORK (input) long The dimension of the array WORK. LWORK >= max(1,N). If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value > 0: if INFO = i, NUMlapack_dhseqr failed to compute all of the eigenvalues in a total of 30*(IHI-ILO+1) iterations; elements 1:ilo-1 and i+1:n of WR and WI contain those eigenvalues which have been successfully computed. ===================================================================== */ int NUMlapack_dlabad (double *smal, double *large); /* Purpose ======= NUMlapack_dlabad takes as input the values computed by DLAMCH for underflow and overflow, and returns the square root of each of these values if the log of LARGE is sufficiently large. This subroutine is intended to identify machines with a large exponent range, such as the Crays, and redefine the underflow and overflow limits to be the square roots of the values computed by DLAMCH. This subroutine is needed because DLAMCH does not compensate for poor arithmetic in the upper half of the exponent range, as is found on a Cray. Arguments ========= smal (input/output) double On entry, the underflow threshold as computed by DLAMCH. On exit, if LOG10(LARGE) is sufficiently large, the square root of smal, otherwise unchanged. LARGE (input/output) double On entry, the overflow threshold as computed by DLAMCH. On exit, if LOG10(LARGE) is sufficiently large, the square root of LARGE, otherwise unchanged. ===================================================================== If it looks like we're on a Cray, take the square root of smal and LARGE to avoid overflow and underflow problems. */ int NUMlapack_dlabrd (long *m, long *n, long *nb, double *a, long *lda, double *d, double *e, double *tauq, double *taup, double *x, long *ldx, double *y, long *ldy); /* Purpose ======= NUMlapack_dlabrd reduces the first NB rows and columns of a real general m by n matrix A to upper or lower bidiagonal form by an orthogonal transformation Q' * A * P, and returns the matrices X and Y which are needed to apply the transformation to the unreduced part of A. If m >= n, A is reduced to upper bidiagonal form; if m < n, to lower bidiagonal form. This is an auxiliary routine called by DGEBRD Arguments ========= M (input) long The number of rows in the matrix A. N (input) long The number of columns in the matrix A. NB (input) long The number of leading rows and columns of A to be reduced. A (input/output) double array, dimension (LDA,N) On entry, the m by n general matrix to be reduced. On exit, the first NB rows and columns of the matrix are overwritten; the rest of the array is unchanged. If m >= n, elements on and below the diagonal in the first NB columns, with the array TAUQ, represent the orthogonal matrix Q as a product of elementary reflectors; and elements above the diagonal in the first NB rows, with the array TAUP, represent the orthogonal matrix P as a product of elementary reflectors. If m < n, elements below the diagonal in the first NB columns, with the array TAUQ, represent the orthogonal matrix Q as a product of elementary reflectors, and elements on and above the diagonal in the first NB rows, with the array TAUP, represent the orthogonal matrix P as a product of elementary reflectors. See Further Details. LDA (input) long The leading dimension of the array A. LDA >= max(1,M). D (output) double array, dimension (NB) The diagonal elements of the first NB rows and columns of the reduced matrix. D(i) = A(i,i). E (output) double array, dimension (NB) The off-diagonal elements of the first NB rows and columns of the reduced matrix. TAUQ (output) double array dimension (NB) The scalar factors of the elementary reflectors which represent the orthogonal matrix Q. See Further Details. TAUP (output) double array, dimension (NB) The scalar factors of the elementary reflectors which represent the orthogonal matrix P. See Further Details. X (output) double array, dimension (LDX,NB) The m-by-nb matrix X required to update the unreduced part of A. LDX (input) long The leading dimension of the array X. LDX >= M. Y (output) double array, dimension (LDY,NB) The n-by-nb matrix Y required to update the unreduced part of A. LDY (output) long The leading dimension of the array Y. LDY >= N. Further Details =============== The matrices Q and P are represented as products of elementary reflectors: Q = H(1) H(2) . . . H(nb) and P = G(1) G(2) . . . G(nb) Each H(i) and G(i) has the form: H(i) = I - tauq * v * v' and G(i) = I - taup * u * u' where tauq and taup are real scalars, and v and u are real vectors. If m >= n, v(1:i-1) = 0, v(i) = 1, and v(i:m) is stored on exit in A(i:m,i); u(1:i) = 0, u(i+1) = 1, and u(i+1:n) is stored on exit in A(i,i+1:n); tauq is stored in TAUQ(i) and taup in TAUP(i). If m < n, v(1:i) = 0, v(i+1) = 1, and v(i+1:m) is stored on exit in A(i+2:m,i); u(1:i-1) = 0, u(i) = 1, and u(i:n) is stored on exit in A(i,i+1:n); tauq is stored in TAUQ(i) and taup in TAUP(i). The elements of the vectors v and u together form the m-by-nb matrix V and the nb-by-n matrix U' which are needed, with X and Y, to apply the transformation to the unreduced part of the matrix, using a block update of the form: A := A - V*Y' - X*U'. The contents of A on exit are illustrated by the following examples with nb = 2: m = 6 and n = 5 (m > n): m = 5 and n = 6 (m < n): ( 1 1 u1 u1 u1 ) ( 1 u1 u1 u1 u1 u1 ) ( v1 1 1 u2 u2 ) ( 1 1 u2 u2 u2 u2 ) ( v1 v2 a a a ) ( v1 1 a a a a ) ( v1 v2 a a a ) ( v1 v2 a a a a ) ( v1 v2 a a a ) ( v1 v2 a a a a ) ( v1 v2 a a a ) where a denotes an element of the original matrix which is unchanged, vi denotes an element of the vector defining H(i), and ui an element of the vector defining G(i). ===================================================================== */ int NUMlapack_dlacpy (const char *uplo, long *m, long *n, double *a, long *lda, double *b, long *ldb); /* Purpose ======= NUMlapack_dlacpy copies all or part of a two-dimensional matrix A to another matrix B. Arguments ========= UPLO (input) char* Specifies the part of the matrix A to be copied to B. = 'U': Upper triangular part = 'L': Lower triangular part Otherwise: All of the matrix A M (input) long The number of rows of the matrix A. M >= 0. N (input) long The number of columns of the matrix A. N >= 0. A (input) double array, dimension (LDA,N) The m by n matrix A. If UPLO = 'U', only the upper triangle or trapezoid is accessed; if UPLO = 'L', only the lower triangle or trapezoid is accessed. LDA (input) long The leading dimension of the array A. LDA >= max(1,M). B (output) double array, dimension (LDB,N) On exit, B = A in the locations specified by UPLO. LDB (input) long The leading dimension of the array B. LDB >= max(1,M). ===================================================================== */ int NUMlapack_dladiv (double *a, double *b, double *c, double *d, double *p, double *q); /* -- LAPACK auxiliary routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University October 31, 1992 Purpose ======= NUMlapack_dladiv performs complex division in real arithmetic a + i*b p + i*q = --------- c + i*d The algorithm is due to Robert L. Smith and can be found in D. Knuth, The art of Computer Programming, Vol.2, p.195 Arguments ========= A (input) double B (input) double C (input) double D (input) double The scalars a, b, c, and d in the above expression. P (output) double Q (output) double The scalars p and q in the above expression. ===================================================================== */ int NUMlapack_dlae2 (double *a, double *b, double *c, double *rt1, double *rt2); /* Purpose ======= NUMlapack_dlae2 computes the eigenvalues of a 2-by-2 symmetric matrix [ A B ] [ B C ]. On return, RT1 is the eigenvalue of larger absolute value, and RT2 is the eigenvalue of smaller absolute value. Arguments ========= A (input) double The (1,1) element of the 2-by-2 matrix. B (input) double The (1,2) and (2,1) elements of the 2-by-2 matrix. C (input) double The (2,2) element of the 2-by-2 matrix. RT1 (output) double The eigenvalue of larger absolute value. RT2 (output) double The eigenvalue of smaller absolute value. Further Details =============== RT1 is accurate to a few ulps barring over/underflow. RT2 may be inaccurate if there is massive cancellation in the determinant A*C-B*B; higher precision or correctly rounded or correctly truncated arithmetic would be needed to compute RT2 accurately in all cases. Overflow is possible only if RT1 is within a factor of 5 of overflow. Underflow is harmless if the input data is 0 or exceeds underflow_threshold / macheps. ===================================================================== */ int NUMlapack_dlaev2 (double *a, double *b, double *c, double *rt1, double *rt2, double *cs1, double *sn1); /* Purpose ======= NUMlapack_dlaev2 computes the eigendecomposition of a 2-by-2 symmetric matrix [ A B ] [ B C ]. On return, RT1 is the eigenvalue of larger absolute value, RT2 is the eigenvalue of smaller absolute value, and (CS1,SN1) is the unit right eigenvector for RT1, giving the decomposition [ CS1 SN1 ] [ A B ] [ CS1 -SN1 ] = [ RT1 0 ] [-SN1 CS1 ] [ B C ] [ SN1 CS1 ] [ 0 RT2 ]. Arguments ========= A (input) double The (1,1) element of the 2-by-2 matrix. B (input) double The (1,2) element and the conjugate of the (2,1) element of the 2-by-2 matrix. C (input) double The (2,2) element of the 2-by-2 matrix. RT1 (output) double The eigenvalue of larger absolute value. RT2 (output) double The eigenvalue of smaller absolute value. CS1 (output) double SN1 (output) double The vector (CS1, SN1) is a unit right eigenvector for RT1. Further Details =============== RT1 is accurate to a few ulps barring over/underflow. RT2 may be inaccurate if there is massive cancellation in the determinant A*C-B*B; higher precision or correctly rounded or correctly truncated arithmetic would be needed to compute RT2 accurately in all cases. CS1 and SN1 are accurate to a few ulps barring over/underflow. Overflow is possible only if RT1 is within a factor of 5 of overflow. Underflow is harmless if the input data is 0 or exceeds underflow_threshold / macheps. ===================================================================== */ int NUMlapack_dlags2 (long *upper, double *a1, double *a2, double *a3, double *b1, double *b2, double *b3, double *csu, double *snu, double *csv, double *snv, double *csq, double *snq); /* Purpose ======= NUMlapack_dlags2 computes 2-by-2 orthogonal matrices U, V and Q, such that if ( UPPER ) then U'*A*Q = U'*( A1 A2 )*Q = ( x 0 ) ( 0 A3 ) ( x x ) and V'*B*Q = V'*( B1 B2 )*Q = ( x 0 ) ( 0 B3 ) ( x x ) or if ( .NOT.UPPER ) then U'*A*Q = U'*( A1 0 )*Q = ( x x ) ( A2 A3 ) ( 0 x ) and V'*B*Q = V'*( B1 0 )*Q = ( x x ) ( B2 B3 ) ( 0 x ) The rows of the transformed A and B are parallel, where U = ( CSU SNU ), V = ( CSV SNV ), Q = ( CSQ SNQ ) ( -SNU CSU ) ( -SNV CSV ) ( -SNQ CSQ ) Z' denotes the transpose of Z. Arguments ========= UPPER (input) long* (boolean) = TRUE: the input matrices A and B are upper triangular. = FALSE: the input matrices A and B are lower triangular. A1 (input) double A2 (input) double A3 (input) double On entry, A1, A2 and A3 are elements of the input 2-by-2 upper (lower) triangular matrix A. B1 (input) double B2 (input) double B3 (input) double On entry, B1, B2 and B3 are elements of the input 2-by-2 upper (lower) triangular matrix B. CSU (output) double SNU (output) double The desired orthogonal matrix U. CSV (output) double SNV (output) double The desired orthogonal matrix V. CSQ (output) double SNQ (output) double The desired orthogonal matrix Q. ===================================================================== */ int NUMlapack_dlahqr (int * wantt, int * wantz, long *n, long *ilo, long *ihi, double *h, long *ldh, double *wr, double *wi, long *iloz, long *ihiz, double *z, long *ldz, long *info); /* -- LAPACK auxiliary routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University June 30, 1999 Purpose ======= NUMlapack_dlahqr is an auxiliary routine called by NUMlapack_dhseqr to update the eigenvalues and Schur decomposition already computed by NUMlapack_dhseqr, by dealing with the Hessenberg submatrix in rows and columns ILO to IHI. Arguments ========= WANTT (input) int = .TRUE. : the full Schur form T is required; = .FALSE.: only eigenvalues are required. WANTZ (input) int = .TRUE. : the matrix of Schur vectors Z is required; = .FALSE.: Schur vectors are not required. N (input) long The order of the matrix H. N >= 0. ILO (input) long IHI (input) long It is assumed that H is already upper quasi-triangular in rows and columns IHI+1:N, and that H(ILO,ILO-1) = 0 (unless ILO = 1). NUMlapack_dlahqr works primarily with the Hessenberg submatrix in rows and columns ILO to IHI, but applies transformations to all of H if WANTT is .TRUE.. 1 <= ILO <= max(1,IHI); IHI <= N. H (input/output) double array, dimension (LDH,N) On entry, the upper Hessenberg matrix H. On exit, if WANTT is .TRUE., H is upper quasi-triangular in rows and columns ILO:IHI, with any 2-by-2 diagonal blocks in standard form. If WANTT is .FALSE., the contents of H are unspecified on exit. LDH (input) long The leading dimension of the array H. LDH >= max(1,N). WR (output) double array, dimension (N) WI (output) double array, dimension (N) The real and imaginary parts, respectively, of the computed eigenvalues ILO to IHI are stored in the corresponding elements of WR and WI. If two eigenvalues are computed as a complex conjugate pair, they are stored in consecutive elements of WR and WI, say the i-th and (i+1)th, with WI(i) > 0 and WI(i+1) < 0. If WANTT is .TRUE., the eigenvalues are stored in the same order as on the diagonal of the Schur form returned in H, with WR(i) = H(i,i), and, if H(i:i+1,i:i+1) is a 2-by-2 diagonal block, WI(i) = sqrt(H(i+1,i)*H(i,i+1)) and WI(i+1) = -WI(i). ILOZ (input) long IHIZ (input) long Specify the rows of Z to which transformations must be applied if WANTZ is .TRUE.. 1 <= ILOZ <= ILO; IHI <= IHIZ <= N. Z (input/output) double array, dimension (LDZ,N) If WANTZ is .TRUE., on entry Z must contain the current matrix Z of transformations accumulated by NUMlapack_dhseqr, and on exit Z has been updated; transformations are applied only to the submatrix Z(ILOZ:IHIZ,ILO:IHI). If WANTZ is .FALSE., Z is not referenced. LDZ (input) long The leading dimension of the array Z. LDZ >= max(1,N). INFO (output) long = 0: successful exit > 0: NUMlapack_dlahqr failed to compute all the eigenvalues ILO to IHI in a total of 30*(IHI-ILO+1) iterations; if INFO = i, elements i+1:ihi of WR and WI contain those eigenvalues which have been successfully computed. Further Details =============== 2-96 Based on modifications by David Day, Sandia National Laboratory, USA ===================================================================== */ int NUMlapack_dlahrd (long *n, long *k, long *nb, double *a, long *lda, double *tau, double *t, long *ldt, double *y, long *ldy); /* -- LAPACK auxiliary routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University June 30, 1999 Purpose ======= NUMlapack_dlahrd reduces the first NB columns of a real general n-by-(n-k+1) matrix A so that elements below the k-th subdiagonal are zero. The reduction is performed by an orthogonal similarity transformation Q' * A * Q. The routine returns the matrices V and T which determine Q as a block reflector I - V*T*V', and also the matrix Y = A * V * T. This is an auxiliary routine called by NUMlapack_dgehrd. Arguments ========= N (input) long The order of the matrix A. K (input) long The offset for the reduction. Elements below the k-th subdiagonal in the first NB columns are reduced to zero. NB (input) long The number of columns to be reduced. A (input/output) double array, dimension (LDA,N-K+1) On entry, the n-by-(n-k+1) general matrix A. On exit, the elements on and above the k-th subdiagonal in the first NB columns are overwritten with the corresponding elements of the reduced matrix; the elements below the k-th subdiagonal, with the array TAU, represent the matrix Q as a product of elementary reflectors. The other columns of A are unchanged. See Further Details. LDA (input) long The leading dimension of the array A. LDA >= max(1,N). TAU (output) double array, dimension (NB) The scalar factors of the elementary reflectors. See Further Details. T (output) double array, dimension (LDT,NB) The upper triangular matrix T. LDT (input) long The leading dimension of the array T. LDT >= NB. Y (output) double array, dimension (LDY,NB) The n-by-nb matrix Y. LDY (input) long The leading dimension of the array Y. LDY >= N. Further Details =============== The matrix Q is represented as a product of nb elementary reflectors Q = H(1) H(2) . . . H(nb). Each H(i) has the form H(i) = I - tau * v * v' where tau is a real scalar, and v is a real vector with v(1:i+k-1) = 0, v(i+k) = 1; v(i+k+1:n) is stored on exit in A(i+k+1:n,i), and tau in TAU(i). The elements of the vectors v together form the (n-k+1)-by-nb matrix V which is needed, with T and Y, to apply the transformation to the unreduced part of the matrix, using an update of the form: A := (I - V*T*V') * (A - Y*V'). The contents of A on exit are illustrated by the following example with n = 7, k = 3 and nb = 2: ( a h a a a ) ( a h a a a ) ( a h a a a ) ( h h a a a ) ( v1 h a a a ) ( v1 v2 a a a ) ( v1 v2 a a a ) where a denotes an element of the original matrix A, h denotes a modified element of the upper Hessenberg matrix H, and vi denotes an element of the vector defining H(i). ===================================================================== */ int NUMlapack_dlaln2 (int * ltrans, long *na, long *nw, double *smin, double *ca, double *a, long *lda, double *d1, double *d2, double *b, long *ldb, double *wr, double *wi, double *x, long *ldx, double *scale, double *xnorm, long *info); /* -- LAPACK auxiliary routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University October 31, 1992 Purpose ======= NUMlapack_dlaln2 solves a system of the form (ca A - w D ) X = s B or (ca A' - w D) X = s B with possible scaling ("s") and perturbation of A. (A' means A-transpose.) A is an NA x NA real matrix, ca is a real scalar, D is an NA x NA real diagonal matrix, w is a real or complex value, and X and B are NA x 1 matrices -- real if w is real, complex if w is complex. NA may be 1 or 2. If w is complex, X and B are represented as NA x 2 matrices, the first column of each being the real part and the second being the imaginary part. "s" is a scaling factor (.LE. 1), computed by NUMlapack_dlaln2, which is so chosen that X can be computed without overflow. X is further scaled if necessary to assure that norm(ca A - w D)*norm(X) is less than overflow. If both singular values of (ca A - w D) are less than SMIN, SMIN*identity will be used instead of (ca A - w D). If only one singular value is less than SMIN, one element of (ca A - w D) will be perturbed enough to make the smallest singular value roughly SMIN. If both singular values are at least SMIN, (ca A - w D) will not be perturbed. In any case, the perturbation will be at most some small multiple of max( SMIN, ulp*norm(ca A - w D) ). The singular values are computed by infinity-norm approximations, and thus will only be correct to a factor of 2 or so. Note: all input quantities are assumed to be smaller than overflow by a reasonable factor. (See BIGNUM.) Arguments ========== LTRANS (input) int =.TRUE.: A-transpose will be used. =.FALSE.: A will be used (not transposed.) NA (input) long The size of the matrix A. It may (only) be 1 or 2. NW (input) long 1 if "w" is real, 2 if "w" is complex. It may only be 1 or 2. SMIN (input) double The desired lower bound on the singular values of A. This should be a safe distance away from underflow or overflow, say, between (underflow/machine precision) and (machine precision * overflow ). (See BIGNUM and ULP.) CA (input) double The coefficient c, which A is multiplied by. A (input) double array, dimension (LDA,NA) The NA x NA matrix A. LDA (input) long The leading dimension of A. It must be at least NA. D1 (input) double The 1,1 element in the diagonal matrix D. D2 (input) double The 2,2 element in the diagonal matrix D. Not used if NW=1. B (input) double array, dimension (LDB,NW) The NA x NW matrix B (right-hand side). If NW=2 ("w" is complex), column 1 contains the real part of B and column 2 contains the imaginary part. LDB (input) long The leading dimension of B. It must be at least NA. WR (input) double The real part of the scalar "w". WI (input) double The imaginary part of the scalar "w". Not used if NW=1. X (output) double array, dimension (LDX,NW) The NA x NW matrix X (unknowns), as computed by NUMlapack_dlaln2. If NW=2 ("w" is complex), on exit, column 1 will contain the real part of X and column 2 will contain the imaginary part. LDX (input) long The leading dimension of X. It must be at least NA. SCALE (output) double The scale factor that B must be multiplied by to insure that overflow does not occur when computing X. Thus, (ca A - w D) X will be SCALE*B, not B (ignoring perturbations of A.) It will be at most 1. XNORM (output) double The infinity-norm of X, when X is regarded as an NA x NW real matrix. INFO (output) long An error flag. It will be set to zero if no error occurs, a negative number if an argument is in error, or a positive number if ca A - w D had to be perturbed. The possible values are: = 0: No error occurred, and (ca A - w D) did not have to be perturbed. = 1: (ca A - w D) had to be perturbed to make its smallest (or only) singular value greater than SMIN. NOTE: In the interests of speed, this routine does not check the inputs for errors. ===================================================================== */ double NUMlapack_dlange (const char *norm, long *m, long *n, double *a, long *lda, double *work); /* Purpose ======= NUMlapack_dlange returns the value of the one norm, or the Frobenius norm, or the infinity norm, or the element of largest absolute value of a real matrix A. Description =========== DLANGE returns the value DLANGE = ( max(abs(A(i,j))), NORM = 'M' or 'm' ( ( norm1(A), NORM = '1', 'O' or 'o' ( ( normI(A), NORM = 'I' or 'i' ( ( normF(A), NORM = 'F', 'f', 'E' or 'e' where norm1 denotes the one norm of a matrix (maximum column sum), normI denotes the infinity norm of a matrix (maximum row sum) and normF denotes the Frobenius norm of a matrix (square root of sum of squares). Note that max(abs(A(i,j))) is not a matrix norm. Arguments ========= NORM (input) char* Specifies the value to be returned in DLANGE as described above. M (input) long The number of rows of the matrix A. M >= 0. When M = 0, DLANGE is set to zero. N (input) long The number of columns of the matrix A. N >= 0. When N = 0, DLANGE is set to zero. A (input) double array, dimension (LDA,N) The m by n matrix A. LDA (input) long The leading dimension of the array A. LDA >= max(M,1). WORK (workspace) double array, dimension (LWORK), where LWORK >= M when NORM = 'I'; otherwise, WORK is not referenced. ===================================================================== */ double NUMlapack_dlanhs (const char *norm, long *n, double *a, long *lda, double *work); /* -- LAPACK auxiliary routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University October 31, 1992 Purpose ======= NUMlapack_dlanhs returns the value of the one norm, or the Frobenius norm, or the infinity norm, or the element of largest absolute value of a Hessenberg matrix A. Description =========== NUMlapack_dlanhs returns the value NUMlapack_dlanhs = ( max(abs(A(i,j))), NORM = 'M' or 'm' ( ( norm1(A), NORM = '1', 'O' or 'o' ( ( normI(A), NORM = 'I' or 'i' ( ( normF(A), NORM = 'F', 'f', 'E' or 'e' where norm1 denotes the one norm of a matrix (maximum column sum), normI denotes the infinity norm of a matrix (maximum row sum) and normF denotes the Frobenius norm of a matrix (square root of sum of squares). Note that max(abs(A(i,j))) is not a matrix norm. Arguments ========= NORM (input) char* Specifies the value to be returned in NUMlapack_dlanhs as described above. N (input) long The order of the matrix A. N >= 0. When N = 0, NUMlapack_dlanhs is set to zero. A (input) double array, dimension (LDA,N) The n by n upper Hessenberg matrix A; the part of A below the first sub-diagonal is not referenced. LDA (input) long The leading dimension of the array A. LDA >= max(N,1). WORK (workspace) double array, dimension (LWORK), where LWORK >= N when NORM = 'I'; otherwise, WORK is not referenced. ===================================================================== */ double NUMlapack_dlanst (const char *norm, long *n, double *d, double *e); /* Purpose ======= NUMlapack_dlanst returns the value of the one norm, or the Frobenius norm, or the infinity norm, or the element of largest absolute value of a real symmetric tridiagonal matrix A. Description =========== NUMlapack_dlanst returns the value NUMlapack_dlanst = ( max(abs(A(i,j))), NORM = 'M' or 'm' ( ( norm1(A), NORM = '1', 'O' or 'o' ( ( normI(A), NORM = 'I' or 'i' ( ( normF(A), NORM = 'F', 'f', 'E' or 'e' where norm1 denotes the one norm of a matrix (maximum column sum), normI denotes the infinity norm of a matrix (maximum row sum) and normF denotes the Frobenius norm of a matrix (square root of sum of squares). Note that max(abs(A(i,j))) is not a matrix norm. Arguments ========= NORM (input) char* Specifies the value to be returned in DLANST as described above. N (input) long The order of the matrix A. N >= 0. When N = 0, DLANST is set to zero. D (input) double array, dimension (N) The diagonal elements of A. E (input) double array, dimension (N-1) The (n-1) sub-diagonal or super-diagonal elements of A. ===================================================================== */ double NUMlapack_dlansy (const char *norm, const char *uplo, long *n, double *a, long *lda, double *work); /* Purpose ======= NUMlapack_dlansy returns the value of the one norm, or the Frobenius norm, or the infinity norm, or the element of largest absolute value of a real symmetric matrix A. Description =========== NUMlapack_dlansy returns the value ( max(abs(A(i,j))), NORM = 'M' or 'm' ( ( norm1(A), NORM = '1', 'O' or 'o' ( ( normI(A), NORM = 'I' or 'i' ( ( normF(A), NORM = 'F', 'f', 'E' or 'e' where norm1 denotes the one norm of a matrix (maximum column sum), normI denotes the infinity norm of a matrix (maximum row sum) and normF denotes the Frobenius norm of a matrix (square root of sum of squares). Note that max(abs(A(i,j))) is not a matrix norm. Arguments ========= NORM (input) char* Specifies the value to be returned in DLANSY as described above. UPLO (input) char* Specifies whether the upper or lower triangular part of the symmetric matrix A is to be referenced. = 'U': Upper triangular part of A is referenced = 'L': Lower triangular part of A is referenced N (input) long The order of the matrix A. N >= 0. When N = 0, DLANSY is set to zero. A (input) double array, dimension (LDA,N) The symmetric matrix A. If UPLO = 'U', the leading n by n upper triangular part of A contains the upper triangular part of the matrix A, and the strictly lower triangular part of A is not referenced. If UPLO = 'L', the leading n by n lower triangular part of A contains the lower triangular part of the matrix A, and the strictly upper triangular part of A is not referenced. LDA (input) long The leading dimension of the array A. LDA >= max(N,1). WORK (workspace) double array, dimension (LWORK), where LWORK >= N when NORM = 'I' or '1' or 'O'; otherwise, WORK is not referenced. ===================================================================== */ int NUMlapack_dlanv2 (double *a, double *b, double *c, double *d, double *rt1r, double *rt1i, double *rt2r, double *rt2i, double *cs, double *sn); /* -- LAPACK driver routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University June 30, 1999 Purpose ======= NUMlapack_dlanv2 computes the Schur factorization of a real 2-by-2 nonsymmetric matrix in standard form: [ A B ] = [ CS -SN ] [ AA BB ] [ CS SN ] [ C D ] [ SN CS ] [ CC DD ] [-SN CS ] where either 1) CC = 0 so that AA and DD are real eigenvalues of the matrix, or 2) AA = DD and BB*CC < 0, so that AA + or - sqrt(BB*CC) are complex conjugate eigenvalues. Arguments ========= A (input/output) double B (input/output) double C (input/output) double D (input/output) double On entry, the elements of the input matrix. On exit, they are overwritten by the elements of the standardised Schur form. RT1R (output) double RT1I (output) double RT2R (output) double RT2I (output) double The real and imaginary parts of the eigenvalues. If the eigenvalues are a complex conjugate pair, RT1I > 0. CS (output) double SN (output) double Parameters of the rotation matrix. Further Details =============== Modified by V. Sima, Research Institute for Informatics, Bucharest, Romania, to reduce the risk of cancellation errors, when computing real eigenvalues, and to ensure, if possible, that abs(RT1R) >= abs(RT2R). ===================================================================== */ int NUMlapack_dlapll(long *n, double *x, long *incx, double *y, long *incy, double *ssmin); /* Purpose ======= Given two column vectors X and Y, let A = ( X Y ). The subroutine first computes the QR factorization of A = Q*R, and then computes the SVD of the 2-by-2 upper triangular matrix R. The smaller singular value of R is returned in SSMIN, which is used as the measurement of the linear dependency of the vectors X and Y. Arguments ========= N (input) long The length of the vectors X and Y. X (input/output) double array, dimension (1+(N-1)*INCX) On entry, X contains the N-vector X. On exit, X is overwritten. INCX (input) long The increment between successive elements of X. INCX > 0. Y (input/output) double array, dimension (1+(N-1)*INCY) On entry, Y contains the N-vector Y. On exit, Y is overwritten. INCY (input) long The increment between successive elements of Y. INCY > 0. SSMIN (output) double The smallest singular value of the N-by-2 matrix A = ( X Y ). ===================================================================== */ double NUMlapack_dlapy2 (double *x, double *y); /* Purpose ======= NUMlapack_dlapy2 returns sqrt(x**2+y**2), taking care not to cause unnecessary overflow. Arguments ========= X (input) double Y (input) double X and Y specify the values x and y. ===================================================================== */ int NUMlapack_dlapmt (long *forwrd, long *m, long *n, double *x, long *ldx, long *k); /* Purpose ======= NUMlapack_dlapmt rearranges the columns of the M by N matrix X as specified by the permutation K(1),K(2),...,K(N) of the integers 1,...,N. If FORWRD = TRUE, forward permutation: X(*,K(J)) is moved X(*,J) for J = 1,2,...,N. If FORWRD = FALSE, backward permutation: X(*,J) is moved to X(*,K(J)) for J = 1,2,...,N. Arguments ========= FORWRD (input) long* (boolean) = TRUE, forward permutation = FALSE, backward permutation M (input) long The number of rows of the matrix X. M >= 0. N (input) long The number of columns of the matrix X. N >= 0. X (input/output) double array, dimension (LDX,N) On entry, the M by N matrix X. On exit, X contains the permuted matrix X. LDX (input) long The leading dimension of the array X, LDX >= MAX(1,M). K (input) long array, dimension (N) On entry, K contains the permutation vector. ===================================================================== */ int NUMlapack_dlarf (const char *side, long *m, long *n, double *v, long *incv, double *tau, double *c, long *ldc, double *work); /* Purpose ======= NUMlapack_dlarf applies a real elementary reflector H to a real m by n matrix C, from either the left or the right. H is represented in the form H = I - tau * v * v' where tau is a real scalar and v is a real vector. If tau = 0, then H is taken to be the unit matrix. Arguments ========= SIDE (input) char* = 'L': form H * C = 'R': form C * H M (input) long The number of rows of the matrix C. N (input) long The number of columns of the matrix C. V (input) double array, dimension (1 + (M-1)*abs(INCV)) if SIDE = 'L' or (1 + (N-1)*abs(INCV)) if SIDE = 'R' The vector v in the representation of H. V is not used if TAU = 0. INCV (input) long The increment between elements of v. INCV <> 0. TAU (input) double The value tau in the representation of H. C (input/output) double array, dimension (LDC,N) On entry, the m by n matrix C. On exit, C is overwritten by the matrix H * C if SIDE = 'L', or C * H if SIDE = 'R'. LDC (input) long The leading dimension of the array C. LDC >= max(1,M). WORK (workspace) double array, dimension (N) if SIDE = 'L' or (M) if SIDE = 'R' ===================================================================== */ int NUMlapack_dlarfb (const char *side, const char *trans, const char *direct, const char *storev, long *m, long *n, long *k, double *v, long *ldv, double *t, long *ldt, double *c, long *ldc, double *work, long *ldwork); /* Purpose ======= NUMlapack_dlarfb applies a real block reflector H or its transpose H' to a real m by n matrix C, from either the left or the right. Arguments ========= SIDE (input) char* = 'L': apply H or H' from the Left = 'R': apply H or H' from the Right TRANS (input) char* = 'N': apply H (No transpose) = 'T': apply H' (Transpose) DIRECT (input) char* Indicates how H is formed from a product of elementary reflectors = 'F': H = H(1) H(2) . . . H(k) (Forward) = 'B': H = H(k) . . . H(2) H(1) (Backward) STOREV (input) char* Indicates how the vectors which define the elementary reflectors are stored: = 'C': Columnwise = 'R': Rowwise M (input) long The number of rows of the matrix C. N (input) long The number of columns of the matrix C. K (input) long The order of the matrix T (= the number of elementary reflectors whose product defines the block reflector). V (input) double array, dimension (LDV,K) if STOREV = 'C' (LDV,M) if STOREV = 'R' and SIDE = 'L' (LDV,N) if STOREV = 'R' and SIDE = 'R' The matrix V. See further details. LDV (input) long The leading dimension of the array V. If STOREV = 'C' and SIDE = 'L', LDV >= max(1,M); if STOREV = 'C' and SIDE = 'R', LDV >= max(1,N); if STOREV = 'R', LDV >= K. T (input) double array, dimension (LDT,K) The triangular k by k matrix T in the representation of the block reflector. LDT (input) long The leading dimension of the array T. LDT >= K. C (input/output) double array, dimension (LDC,N) On entry, the m by n matrix C. On exit, C is overwritten by H*C or H'*C or C*H or C*H'. LDC (input) long The leading dimension of the array C. LDA >= max(1,M). WORK (workspace) double array, dimension (LDWORK,K) LDWORK (input) long The leading dimension of the array WORK. If SIDE = 'L', LDWORK >= max(1,N); if SIDE = 'R', LDWORK >= max(1,M). ===================================================================== */ int NUMlapack_dlarfg (long *n, double *alpha, double *x, long *incx, double *tau); /* Purpose ======= NUMlapack_dlarfg generates a real elementary reflector H of order n, such that H * ( alpha ) = ( beta ), H' * H = I. ( x ) ( 0 ) where alpha and beta are scalars, and x is an (n-1)-element real vector. H is represented in the form H = I - tau * ( 1 ) * ( 1 v' ) , ( v ) where tau is a real scalar and v is a real (n-1)-element vector. If the elements of x are all zero, then tau = 0 and H is taken to be the unit matrix. Otherwise 1 <= tau <= 2. Arguments ========= N (input) long The order of the elementary reflector. ALPHA (input/output) double On entry, the value alpha. On exit, it is overwritten with the value beta. X (input/output) double array, dimension (1+(N-2)*abs(INCX)) On entry, the vector x. On exit, it is overwritten with the vector v. INCX (input) long The increment between elements of X. INCX > 0. TAU (output) double The value tau. ===================================================================== */ int NUMlapack_dlarft (const char *direct, const char *storev, long *n, long *k, double *v, long *ldv, double *tau, double *t, long *ldt); /* Purpose ======= NUMlapack_dlarft forms the triangular factor T of a real block reflector H of order n, which is defined as a product of k elementary reflectors. If DIRECT = 'F', H = H(1) H(2) . . . H(k) and T is upper triangular; If DIRECT = 'B', H = H(k) . . . H(2) H(1) and T is lower triangular. If STOREV = 'C', the vector which defines the elementary reflector H(i) is stored in the i-th column of the array V, and H = I - V * T * V' If STOREV = 'R', the vector which defines the elementary reflector H(i) is stored in the i-th row of the array V, and H = I - V' * T * V Arguments ========= DIRECT (input) char* Specifies the order in which the elementary reflectors are multiplied to form the block reflector: = 'F': H = H(1) H(2) . . . H(k) (Forward) = 'B': H = H(k) . . . H(2) H(1) (Backward) STOREV (input) char* Specifies how the vectors which define the elementary reflectors are stored (see also Further Details): = 'C': columnwise = 'R': rowwise N (input) long The order of the block reflector H. N >= 0. K (input) long The order of the triangular factor T (= the number of elementary reflectors). K >= 1. V (input/output) double array, dimension (LDV,K) if STOREV = 'C' (LDV,N) if STOREV = 'R' The matrix V. See further details. LDV (input) long The leading dimension of the array V. If STOREV = 'C', LDV >= max(1,N); if STOREV = 'R', LDV >= K. TAU (input) double array, dimension (K) TAU(i) must contain the scalar factor of the elementary reflector H(i). T (output) double array, dimension (LDT,K) The k by k triangular factor T of the block reflector. If DIRECT = 'F', T is upper triangular; if DIRECT = 'B', T is lower triangular. The rest of the array is not used. LDT (input) long The leading dimension of the array T. LDT >= K. Further Details =============== The shape of the matrix V and the storage of the vectors which define the H(i) is best illustrated by the following example with n = 5 and k = 3. The elements equal to 1 are not stored; the corresponding array elements are modified but restored on exit. The rest of the array is not used. DIRECT = 'F' and STOREV = 'C': DIRECT = 'F' and STOREV = 'R': V = ( 1 ) V = ( 1 v1 v1 v1 v1 ) ( v1 1 ) ( 1 v2 v2 v2 ) ( v1 v2 1 ) ( 1 v3 v3 ) ( v1 v2 v3 ) ( v1 v2 v3 ) DIRECT = 'B' and STOREV = 'C': DIRECT = 'B' and STOREV = 'R': V = ( v1 v2 v3 ) V = ( v1 v1 1 ) ( v1 v2 v3 ) ( v2 v2 v2 1 ) ( 1 v2 v3 ) ( v3 v3 v3 v3 1 ) ( 1 v3 ) ( 1 ) ===================================================================== */ int NUMlapack_dlarfx (const char *side, long *m, long *n, double *v, double *tau, double *c, long *ldc, double *work); /* -- LAPACK auxiliary routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University February 29, 1992 Purpose ======= NUMlapack_dlarfx applies a real elementary reflector H to a real m by n matrix C, from either the left or the right. H is represented in the form H = I - tau * v * v' where tau is a real scalar and v is a real vector. If tau = 0, then H is taken to be the unit matrix This version uses inline code if H has order < 11. Arguments ========= SIDE (input) char* = 'L': form H * C = 'R': form C * H M (input) long The number of rows of the matrix C. N (input) long The number of columns of the matrix C. V (input) double array, dimension (M) if SIDE = 'L' or (N) if SIDE = 'R' The vector v in the representation of H. TAU (input) double The value tau in the representation of H. C (input/output) double array, dimension (LDC,N) On entry, the m by n matrix C. On exit, C is overwritten by the matrix H * C if SIDE = 'L', or C * H if SIDE = 'R'. LDC (input) long The leading dimension of the array C. LDA >= (1,M). WORK (workspace) double array, dimension (N) if SIDE = 'L' or (M) if SIDE = 'R' WORK is not referenced if H has order < 11. ===================================================================== */ int NUMlapack_dlartg (double *f, double *g, double *cs, double *sn, double *r); /* Purpose ======= NUMlapack_dlartg generate a plane rotation so that [ CS SN ] . [ F ] = [ R ] where CS**2 + SN**2 = 1. [ -SN CS ] [ G ] [ 0 ] This is a slower, more accurate version of the BLAS1 routine DROTG, with the following other differences: F and G are unchanged on return. If G=0, then CS=1 and SN=0. If F=0 and (G .ne. 0), then CS=0 and SN=1 without doing any floating point operations (saves work in DBDSQR when there are zeros on the diagonal). If F exceeds G in magnitude, CS will be positive. Arguments ========= F (input) double The first component of vector to be rotated. G (input) double The second component of vector to be rotated. CS (output) double The cosine of the rotation. SN (output) double The sine of the rotation. R (output) double The nonzero component of the rotated vector. ===================================================================== */ int NUMlapack_dlas2 (double *f, double *g, double *h, double *ssmin, double *ssmax); /* Purpose ======= NUMlapack_dlas2 computes the singular values of the 2-by-2 matrix [ F G ] [ 0 H ]. On return, SSMIN is the smaller singular value and SSMAX is the larger singular value. Arguments ========= F (input) double The (1,1) element of the 2-by-2 matrix. G (input) double The (1,2) element of the 2-by-2 matrix. H (input) double The (2,2) element of the 2-by-2 matrix. SSMIN (output) double The smaller singular value. SSMAX (output) double The larger singular value. Further Details =============== Barring over/underflow, all output quantities are correct to within a few units in the last place (ulps), even in the absence of a guard digit in addition/subtraction. In IEEE arithmetic, the code works correctly if one matrix element is infinite. Overflow will not occur unless the largest singular value itself overflows, or is within a few ulps of overflow. (On machines with partial overflow, like the Cray, overflow may occur if the largest singular value is within a factor of 2 of overflow.) Underflow is harmless if underflow is gradual. Otherwise, results may correspond to a matrix modified by perturbations of size near the underflow threshold. ==================================================================== */ int NUMlapack_dlascl (const char *type, long *kl, long *ku, double *cfrom, double *cto, long *m, long *n, double *a, long *lda, long *info); /* Purpose ======= NUMlapack_dlascl multiplies the M by N real matrix A by the real scalar CTO/CFROM. This is done without over/underflow as long as the final result CTO*A(I,J)/CFROM does not over/underflow. TYPE specifies that A may be full, upper triangular, lower triangular, upper Hessenberg, or banded. Arguments ========= TYPE (input) char* TYPE indices the storage type of the input matrix. = 'G': A is a full matrix. = 'L': A is a lower triangular matrix. = 'U': A is an upper triangular matrix. = 'H': A is an upper Hessenberg matrix. = 'B': A is a symmetric band matrix with lower bandwidth KL and upper bandwidth KU and with the only the lower half stored. = 'Q': A is a symmetric band matrix with lower bandwidth KL and upper bandwidth KU and with the only the upper half stored. = 'Z': A is a band matrix with lower bandwidth KL and upper bandwidth KU. KL (input) long The lower bandwidth of A. Referenced only if TYPE = 'B', 'Q' or 'Z'. KU (input) long The upper bandwidth of A. Referenced only if TYPE = 'B', 'Q' or 'Z'. CFROM (input) double CTO (input) double The matrix A is multiplied by CTO/CFROM. A(I,J) is computed without over/underflow if the final result CTO*A(I,J)/CFROM can be represented without over/underflow. CFROM must be nonzero. M (input) long The number of rows of the matrix A. M >= 0. N (input) long The number of columns of the matrix A. N >= 0. A (input/output) double array, dimension (LDA,M) The matrix to be multiplied by CTO/CFROM. See TYPE for the storage type. LDA (input) long The leading dimension of the array A. LDA >= max(1,M). INFO (output) long 0 - successful exit <0 - if INFO = -i, the i-th argument had an illegal value. ===================================================================== */ int NUMlapack_dlaset (const char *uplo, long *m, long *n, double *alpha, double *beta, double *a, long *lda); /* Purpose ======= NUMlapack_dlaset initializes an m-by-n matrix A to BETA on the diagonal and ALPHA on the offdiagonals. Arguments ========= UPLO (input) char* Specifies the part of the matrix A to be set. = 'U': Upper triangular part is set; the strictly lower triangular part of A is not changed. = 'L': Lower triangular part is set; the strictly upper triangular part of A is not changed. Otherwise: All of the matrix A is set. M (input) long The number of rows of the matrix A. M >= 0. N (input) long The number of columns of the matrix A. N >= 0. ALPHA (input) double The constant to which the offdiagonal elements are to be set. BETA (input) double The constant to which the diagonal elements are to be set. A (input/output) double array, dimension (LDA,N) On exit, the leading m-by-n submatrix of A is set as follows: if UPLO = 'U', A(i,j) = ALPHA, 1<=i<=j-1, 1<=j<=n, if UPLO = 'L', A(i,j) = ALPHA, j+1<=i<=m, 1<=j<=n, otherwise, A(i,j) = ALPHA, 1<=i<=m, 1<=j<=n, i.ne.j, and, for all UPLO, A(i,i) = BETA, 1<=i<=min(m,n). LDA (input) long The leading dimension of the array A. LDA >= max(1,M). ===================================================================== */ int NUMlapack_dlasq1 (long *n, double *d, double *e, double *work, long *info); /* Purpose ======= NUMlapack_dlasq1 computes the singular values of a real N-by-N bidiagonal matrix with diagonal D and off-diagonal E. The singular values are computed to high relative accuracy, in the absence of denormalization, underflow and overflow. The algorithm was first presented in "Accurate singular values and differential qd algorithms" by K. V. Fernando and B. N. Parlett, Numer. Math., Vol-67, No. 2, pp. 191-230, 1994, and the present implementation is described in "An implementation of the dqds Algorithm (Positive Case)", LAPACK Working Note. Arguments ========= N (input) long The number of rows and columns in the matrix. N >= 0. D (input/output) double array, dimension (N) On entry, D contains the diagonal elements of the bidiagonal matrix whose SVD is desired. On normal exit, D contains the singular values in decreasing order. E (input/output) double array, dimension (N) On entry, elements E(1:N-1) contain the off-diagonal elements of the bidiagonal matrix whose SVD is desired. On exit, E is overwritten. WORK (workspace) double array, dimension (4*N) INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value > 0: the algorithm failed = 1, a split was marked by a positive value in E = 2, current block of Z not diagonalized after 30*N iterations (in inner while loop) = 3, termination criterion of outer while loop not met (program created more than N unreduced blocks) ===================================================================== */ int NUMlapack_dlasq2 (long *n, double *z, long *info); /* Purpose ======= NUMlapack_dlasq2 computes all the eigenvalues of the symmetric positive definite tridiagonal matrix associated with the qd array Z to high relative accuracy are computed to high relative accuracy, in the absence of denormalization, underflow and overflow. To see the relation of Z to the tridiagonal matrix, let L be a unit lower bidiagonal matrix with subdiagonals Z(2,4,6,,..) and let U be an upper bidiagonal matrix with 1's above and diagonal Z(1,3,5,,..). The tridiagonal is L*U or, if you prefer, the symmetric tridiagonal to which it is similar. Note : NUMlapack_dlasq2 defines a long* (boolean) variable, IEEE, which is true on machines which follow ieee-754 floating-point standard in their handling of infinities and NaNs, and false otherwise. This variable is passed to NUMlapack_dlasq3. Arguments ========= N (input) long The number of rows and columns in the matrix. N >= 0. Z (workspace) double array, dimension ( 4*N ) On entry Z holds the qd array. On exit, entries 1 to N hold the eigenvalues in decreasing order, Z( 2*N+1 ) holds the trace, and Z( 2*N+2 ) holds the sum of the eigenvalues. If N > 2, then Z( 2*N+3 ) holds the iteration count, Z( 2*N+4 ) holds NDIVS/NIN^2, and Z( 2*N+5 ) holds the percentage of shifts that failed. INFO (output) long = 0: successful exit < 0: if the i-th argument is a scalar and had an illegal value, then INFO = -i, if the i-th argument is an array and the j-entry had an illegal value, then INFO = -(i*100+j) > 0: the algorithm failed = 1, a split was marked by a positive value in E = 2, current block of Z not diagonalized after 30*N iterations (in inner while loop) = 3, termination criterion of outer while loop not met (program created more than N unreduced blocks) Further Details =============== Local Variables: I0:N0 defines a current unreduced segment of Z. The shifts are accumulated in SIGMA. Iteration count is in ITER. Ping-pong is controlled by PP (alternates between 0 and 1). ===================================================================== */ int NUMlapack_dlasq3 (long *i0, long *n0, double *z, long *pp, double *dmin, double *sigma, double *desig, double *qmax, long *nfail, long *iter, long *ndiv, long *ieee); /* Purpose ======= NUMlapack_dlasq3 checks for deflation, computes a shift (TAU) and calls dqds. In case of failure it changes shifts, and tries again until output is positive. Arguments ========= I0 (input) long First index. N0 (input) long Last index. Z (input) double array, dimension ( 4*N ) Z holds the qd array. PP (input) long PP=0 for ping, PP=1 for pong. DMIN (output) double Minimum value of d. SIGMA (output) double Sum of shifts used in current segment. DESIG (input/output) double Lower order part of SIGMA QMAX (input) double Maximum value of q. NFAIL (output) long Number of times shift was too big. ITER (output) long Number of iterations. NDIV (output) long Number of divisions. TTYPE (output) long Shift type. IEEE (input) long* (boolean) Flag for IEEE or non IEEE arithmetic (passed to DLASQ5). ===================================================================== */ int NUMlapack_dlasq4 (long *i0, long *n0, double *z, long *pp, long *n0in, double *dmin, double *dmin1, double *dmin2, double *dn, double *dn1, double *dn2, double *tau, long *ttype); /* Purpose ======= NUMlapack_dlasq4 computes an approximation TAU to the smallest eigenvalue using values of d from the previous transform. I0 (input) long First index. N0 (input) long Last index. Z (input) double array, dimension ( 4*N ) Z holds the qd array. PP (input) long PP=0 for ping, PP=1 for pong. NOIN (input) long The value of N0 at start of EIGTEST. DMIN (input) double Minimum value of d. DMIN1 (input) double Minimum value of d, excluding D( N0 ). DMIN2 (input) double Minimum value of d, excluding D( N0 ) and D( N0-1 ). DN (input) double d(N) DN1 (input) double d(N-1) DN2 (input) double d(N-2) TAU (output) double This is the shift. TTYPE (output) long Shift type. Further Details =============== CNST1 = 9/16 ===================================================================== */ int NUMlapack_dlasq5 (long *i0, long *n0, double *z, long *pp, double *tau, double *dmin, double *dmin1, double *dmin2, double *dn, double *dnm1, double *dnm2, long *ieee); /* Purpose ======= NUMlapack_dlasq5 computes one dqds transform in ping-pong form, one version for IEEE machines another for non IEEE machines. Arguments ========= I0 (input) long First index. N0 (input) long Last index. Z (input) double array, dimension ( 4*N ) Z holds the qd array. EMIN is stored in Z(4*N0) to avoid an extra argument. PP (input) long PP=0 for ping, PP=1 for pong. TAU (input) double This is the shift. DMIN (output) double Minimum value of d. DMIN1 (output) double Minimum value of d, excluding D( N0 ). DMIN2 (output) double Minimum value of d, excluding D( N0 ) and D( N0-1 ). DN (output) double d(N0), the last value of d. DNM1 (output) double d(N0-1). DNM2 (output) double d(N0-2). IEEE (input) long* (boolean) Flag for IEEE or non IEEE arithmetic. ===================================================================== */ int NUMlapack_dlasq6 (long *i0, long *n0, double *z, long *pp, double *dmin, double *dmin1, double *dmin2, double *dn, double *dnm1, double *dnm2); /* Purpose ======= NUMlapack_dlasq6 computes one dqd (shift equal to zero) transform in ping-pong form, with protection against underflow and overflow. Arguments ========= I0 (input) long First index. N0 (input) long Last index. Z (input) double array, dimension ( 4*N ) Z holds the qd array. EMIN is stored in Z(4*N0) to avoid an extra argument. PP (input) long PP=0 for ping, PP=1 for pong. DMIN (output) double Minimum value of d. DMIN1 (output) double Minimum value of d, excluding D( N0 ). DMIN2 (output) double Minimum value of d, excluding D( N0 ) and D( N0-1 ). DN (output) double d(N0), the last value of d. DNM1 (output) double d(N0-1). DNM2 (output) double d(N0-2). ===================================================================== */ int NUMlapack_dlasr (const char *side, const char *pivot, const char *direct, long *m, long *n, double *c, double *s, double *a, long *lda); /* Purpose ======= NUMlapack_dlasr performs the transformation A := P*A, when SIDE = 'L' or 'l' ( Left-hand side ) A := A*P', when SIDE = 'R' or 'r' ( Right-hand side ) where A is an m by n real matrix and P is an orthogonal matrix, consisting of a sequence of plane rotations determined by the parameters PIVOT and DIRECT as follows ( z = m when SIDE = 'L' or 'l' and z = n when SIDE = 'R' or 'r' ): When DIRECT = 'F' or 'f' ( Forward sequence ) then P = P( z - 1 )*...*P( 2 )*P( 1 ), and when DIRECT = 'B' or 'b' ( Backward sequence ) then P = P( 1 )*P( 2 )*...*P( z - 1 ), where P( k ) is a plane rotation matrix for the following planes: when PIVOT = 'V' or 'v' ( Variable pivot ), the plane ( k, k + 1 ) when PIVOT = 'T' or 't' ( Top pivot ), the plane ( 1, k + 1 ) when PIVOT = 'B' or 'b' ( Bottom pivot ), the plane ( k, z ) c( k ) and s( k ) must contain the cosine and sine that define the matrix P( k ). The two by two plane rotation part of the matrix P( k ), R( k ), is assumed to be of the form R( k ) = ( c( k ) s( k ) ). ( -s( k ) c( k ) ) This version vectorises across rows of the array A when SIDE = 'L'. Arguments ========= SIDE (input) char* Specifies whether the plane rotation matrix P is applied to A on the left or the right. = 'L': Left, compute A := P*A = 'R': Right, compute A:= A*P' DIRECT (input) char* Specifies whether P is a forward or backward sequence of plane rotations. = 'F': Forward, P = P( z - 1 )*...*P( 2 )*P( 1 ) = 'B': Backward, P = P( 1 )*P( 2 )*...*P( z - 1 ) PIVOT (input) char* Specifies the plane for which P(k) is a plane rotation matrix. = 'V': Variable pivot, the plane (k,k+1) = 'T': Top pivot, the plane (1,k+1) = 'B': Bottom pivot, the plane (k,z) M (input) long The number of rows of the matrix A. If m <= 1, an immediate return is effected. N (input) long The number of columns of the matrix A. If n <= 1, an immediate return is effected. C, S (input) double arrays, dimension (M-1) if SIDE = 'L' (N-1) if SIDE = 'R' c(k) and s(k) contain the cosine and sine that define the matrix P(k). The two by two plane rotation part of the matrix P(k), R(k), is assumed to be of the form R( k ) = ( c( k ) s( k ) ). ( -s( k ) c( k ) ) A (input/output) double array, dimension (LDA,N) The m by n matrix A. On exit, A is overwritten by P*A if SIDE = 'R' or by A*P' if SIDE = 'L'. LDA (input) long The leading dimension of the array A. LDA >= max(1,M). ===================================================================== */ int NUMlapack_dlasrt (const char *id, long *n, double *d, long *info); /* Purpose ======= Sort the numbers in D in increasing order (if ID = 'I') or in decreasing order (if ID = 'D' ). Use Quick Sort, reverting to Insertion sort on arrays of size <= 20. Dimension of STACK limits N to about 2**32. Arguments ========= ID (input) char* = 'I': sort D in increasing order; = 'D': sort D in decreasing order. N (input) long The length of the array D. D (input/output) double array, dimension (N) On entry, the array to be sorted. On exit, D has been sorted into increasing order (D(1) <= ... <= D(N) ) or into decreasing order (D(1) >= ... >= D(N) ), depending on ID. INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value ===================================================================== */ int NUMlapack_dlassq (long *n, double *x, long *incx, double *scale, double *sumsq); /* Purpose ======= NUMlapack_dlassq returns the values scl and smsq such that ( scl**2 )*smsq = x( 1 )**2 +...+ x( n )**2 + ( scale**2 )*sumsq, where x( i ) = X( 1 + ( i - 1 )*INCX ). The value of sumsq is assumed to be non-negative and scl returns the value scl = max( scale, abs( x( i ) ) ). scale and sumsq must be supplied in SCALE and SUMSQ and scl and smsq are overwritten on SCALE and SUMSQ respectively. The routine makes only one pass through the vector x. Arguments ========= N (input) long The number of elements to be used from the vector X. X (input) double array, dimension (N) The vector for which a scaled sum of squares is computed. x( i ) = X( 1 + ( i - 1 )*INCX ), 1 <= i <= n. INCX (input) long The increment between successive values of the vector X. INCX > 0. SCALE (input/output) double On entry, the value scale in the equation above. On exit, SCALE is overwritten with scl , the scaling factor for the sum of squares. SUMSQ (input/output) double On entry, the value sumsq in the equation above. On exit, SUMSQ is overwritten with smsq , the basic sum of squares from which scl has been factored out. ===================================================================== */ int NUMlapack_dlasv2 (double *f, double *g, double *h, double *ssmin, double *ssmax, double *snr, double *csr, double *snl, double *csl); /* Purpose ======= NUMlapack_dlasv2 computes the singular value decomposition of a 2-by-2 triangular matrix [ F G ] [ 0 H ]. On return, abs(SSMAX) is the larger singular value, abs(SSMIN) is the smaller singular value, and (CSL,SNL) and (CSR,SNR) are the left and right singular vectors for abs(SSMAX), giving the decomposition [ CSL SNL ] [ F G ] [ CSR -SNR ] = [ SSMAX 0 ] [-SNL CSL ] [ 0 H ] [ SNR CSR ] [ 0 SSMIN ]. Arguments ========= F (input) double The (1,1) element of the 2-by-2 matrix. G (input) double The (1,2) element of the 2-by-2 matrix. H (input) double The (2,2) element of the 2-by-2 matrix. SSMIN (output) double abs(SSMIN) is the smaller singular value. SSMAX (output) double abs(SSMAX) is the larger singular value. SNL (output) double CSL (output) double The vector (CSL, SNL) is a unit left singular vector for the singular value abs(SSMAX). SNR (output) double CSR (output) double The vector (CSR, SNR) is a unit right singular vector for the singular value abs(SSMAX). Further Details =============== Any input parameter may be aliased with any output parameter. Barring over/underflow and assuming a guard digit in subtraction, all output quantities are correct to within a few units in the last place (ulps). In IEEE arithmetic, the code works correctly if one matrix element is infinite. Overflow will not occur unless the largest singular value itself overflows or is within a few ulps of overflow. (On machines with partial overflow, like the Cray, overflow may occur if the largest singular value is within a factor of 2 of overflow.) Underflow is harmless if underflow is gradual. Otherwise, results may correspond to a matrix modified by perturbations of size near the underflow threshold. ===================================================================== */ int NUMlapack_dlaswp (long *n, double *a, long *lda, long *k1, long *k2, long *ipiv, long *incx); /* Purpose ======= NUMlapack_dlaswp performs a series of row interchanges on the matrix A. One row interchange is initiated for each of rows K1 through K2 of A. Arguments ========= N (input) long The number of columns of the matrix A. A (input/output) double array, dimension (LDA,N) On entry, the matrix of column dimension N to which the row interchanges will be applied. On exit, the permuted matrix. LDA (input) long The leading dimension of the array A. K1 (input) long The first element of IPIV for which a row interchange will be done. K2 (input) long The last element of IPIV for which a row interchange will be done. IPIV (input) long array, dimension (M*abs(INCX)) The vector of pivot indices. Only the elements in positions K1 through K2 of IPIV are accessed. IPIV(K) = L implies rows K and L are to be interchanged. INCX (input) long The increment between successive values of IPIV. If IPIV is negative, the pivots are applied in reverse order. ===================================================================== */ int NUMlapack_dlatrd (const char *uplo, long *n, long *nb, double *a, long *lda, double *e, double *tau, double *w, long *ldw); /* Purpose ======= NUMlapack_dlatrd reduces NB rows and columns of a real symmetric matrix A to symmetric tridiagonal form by an orthogonal similarity transformation Q' * A * Q, and returns the matrices V and W which are needed to apply the transformation to the unreduced part of A. If UPLO = 'U', DLATRD reduces the last NB rows and columns of a matrix, of which the upper triangle is supplied; if UPLO = 'L', DLATRD reduces the first NB rows and columns of a matrix, of which the lower triangle is supplied. This is an auxiliary routine called by NUMlapack_dsytrd. Arguments ========= UPLO (input) CHARACTER Specifies whether the upper or lower triangular part of the symmetric matrix A is stored: = 'U': Upper triangular = 'L': Lower triangular N (input) long The order of the matrix A. NB (input) long The number of rows and columns to be reduced. A (input/output) double array, dimension (LDA,N) On entry, the symmetric matrix A. If UPLO = 'U', the leading n-by-n upper triangular part of A contains the upper triangular part of the matrix A, and the strictly lower triangular part of A is not referenced. If UPLO = 'L', the leading n-by-n lower triangular part of A contains the lower triangular part of the matrix A, and the strictly upper triangular part of A is not referenced. On exit: if UPLO = 'U', the last NB columns have been reduced to tridiagonal form, with the diagonal elements overwriting the diagonal elements of A; the elements above the diagonal with the array TAU, represent the orthogonal matrix Q as a product of elementary reflectors; if UPLO = 'L', the first NB columns have been reduced to tridiagonal form, with the diagonal elements overwriting the diagonal elements of A; the elements below the diagonal with the array TAU, represent the orthogonal matrix Q as a product of elementary reflectors. See Further Details. LDA (input) long The leading dimension of the array A. LDA >= (1,N). E (output) double array, dimension (N-1) If UPLO = 'U', E(n-nb:n-1) contains the superdiagonal elements of the last NB columns of the reduced matrix; if UPLO = 'L', E(1:nb) contains the subdiagonal elements of the first NB columns of the reduced matrix. TAU (output) double array, dimension (N-1) The scalar factors of the elementary reflectors, stored in TAU(n-nb:n-1) if UPLO = 'U', and in TAU(1:nb) if UPLO = 'L'. See Further Details. W (output) double array, dimension (LDW,NB) The n-by-nb matrix W required to update the unreduced part of A. LDW (input) long The leading dimension of the array W. LDW >= max(1,N). Further Details =============== If UPLO = 'U', the matrix Q is represented as a product of elementary reflectors Q = H(n) H(n-1) . . . H(n-nb+1). Each H(i) has the form H(i) = I - tau * v * v' where tau is a real scalar, and v is a real vector with v(i:n) = 0 and v(i-1) = 1; v(1:i-1) is stored on exit in A(1:i-1,i), and tau in TAU(i-1). If UPLO = 'L', the matrix Q is represented as a product of elementary reflectors Q = H(1) H(2) . . . H(nb). Each H(i) has the form H(i) = I - tau * v * v' where tau is a real scalar, and v is a real vector with v(1:i) = 0 and v(i+1) = 1; v(i+1:n) is stored on exit in A(i+1:n,i), and tau in TAU(i). The elements of the vectors v together form the n-by-nb matrix V which is needed, with W, to apply the transformation to the unreduced part of the matrix, using a symmetric rank-2k update of the form: A := A - V*W' - W*V'. The contents of A on exit are illustrated by the following examples with n = 5 and nb = 2: if UPLO = 'U': if UPLO = 'L': ( a a a v4 v5 ) ( d ) ( a a v4 v5 ) ( 1 d ) ( a 1 v5 ) ( v1 1 a ) ( d 1 ) ( v1 v2 a a ) ( d ) ( v1 v2 a a a ) where d denotes a diagonal element of the reduced matrix, a denotes an element of the original matrix that is unchanged, and vi denotes an element of the vector defining H(i). ===================================================================== */ int NUMlapack_dorg2l (long *m, long *n, long *k, double * a, long *lda, double *tau, double *work, long *info); /* Purpose ======= NUMlapack_dorg2l generates an m by n real matrix Q with orthonormal columns, which is defined as the last n columns of a product of k elementary reflectors of order m Q = H(k) . . . H(2) H(1) as returned by NUMlapack_dgeqlf. Arguments ========= M (input) long The number of rows of the matrix Q. M >= 0. N (input) long The number of columns of the matrix Q. M >= N >= 0. K (input) long The number of elementary reflectors whose product defines the matrix Q. N >= K >= 0. A (input/output) double array, dimension (LDA,N) On entry, the (n-k+i)-th column must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by DGEQLF in the last k columns of its array argument A. On exit, the m by n matrix Q. LDA (input) long The first dimension of the array A. LDA >= max(1,M). TAU (input) double array, dimension (K) TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DGEQLF. WORK (workspace) double array, dimension (N) INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument has an illegal value ===================================================================== */ int NUMlapack_dorg2r (long *m, long *n, long *k, double *a, long *lda, double *tau, double *work, long *info); /* Purpose ======= NUMlapack_dorg2r generates an m by n real matrix Q with orthonormal columns, which is defined as the first n columns of a product of k elementary reflectors of order m Q = H(1) H(2) . . . H(k) as returned by NUMlapack_dgeqrf. Arguments ========= M (input) long The number of rows of the matrix Q. M >= 0. N (input) long The number of columns of the matrix Q. M >= N >= 0. K (input) long The number of elementary reflectors whose product defines the matrix Q. N >= K >= 0. A (input/output) double array, dimension (LDA,N) On entry, the i-th column must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by DGEQRF in the first k columns of its array argument A. On exit, the m-by-n matrix Q. LDA (input) long The first dimension of the array A. LDA >= max(1,M). TAU (input) double array, dimension (K) TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DGEQRF. WORK (workspace) double array, dimension (N) INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument has an illegal value ===================================================================== */ int NUMlapack_dorgbr (const char *vect, long *m, long *n, long *k, double *a, long *lda, double *tau, double *work, long *lwork, long *info); /* Purpose ======= NUMlapack_dorgbr generates one of the real orthogonal matrices Q or P**T determined by DGEBRD when reducing a real matrix A to bidiagonal form: A = Q * B * P**T. Q and P**T are defined as products of elementary reflectors H(i) or G(i) respectively. If VECT = 'Q', A is assumed to have been an M-by-K matrix, and Q is of order M: if m >= k, Q = H(1) H(2) . . . H(k) and NUMlapack_dorgbr returns the first n columns of Q, where m >= n >= k; if m < k, Q = H(1) H(2) . . . H(m-1) and NUMlapack_dorgbr returns Q as an M-by-M matrix. If VECT = 'P', A is assumed to have been a K-by-N matrix, and P**T is of order N: if k < n, P**T = G(k) . . . G(2) G(1) and NUMlapack_dorgbr returns the first m rows of P**T, where n >= m >= k; if k >= n, P**T = G(n-1) . . . G(2) G(1) and NUMlapack_dorgbr returns P**T as an N-by-N matrix. Arguments ========= VECT (input) char* Specifies whether the matrix Q or the matrix P**T is required, as defined in the transformation applied by DGEBRD: = 'Q': generate Q; = 'P': generate P**T. M (input) long The number of rows of the matrix Q or P**T to be returned. M >= 0. N (input) long The number of columns of the matrix Q or P**T to be returned. N >= 0. If VECT = 'Q', M >= N >= min(M,K); if VECT = 'P', N >= M >= min(N,K). K (input) long If VECT = 'Q', the number of columns in the original M-by-K matrix reduced by DGEBRD. If VECT = 'P', the number of rows in the original K-by-N matrix reduced by DGEBRD. K >= 0. A (input/output) double array, dimension (LDA,N) On entry, the vectors which define the elementary reflectors, as returned by DGEBRD. On exit, the M-by-N matrix Q or P**T. LDA (input) long The leading dimension of the array A. LDA >= max(1,M). TAU (input) double array, dimension (min(M,K)) if VECT = 'Q' (min(N,K)) if VECT = 'P' TAU(i) must contain the scalar factor of the elementary reflector H(i) or G(i), which determines Q or P**T, as returned by DGEBRD in its array argument TAUQ or TAUP. WORK (workspace/output) double array, dimension (LWORK) On exit, if INFO = 0, WORK(1) returns the optimal LWORK. LWORK (input) long The dimension of the array WORK. LWORK >= max(1,min(M,N)). For optimum performance LWORK >= min(M,N)*NB, where NB is the optimal blocksize. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value ===================================================================== */ int NUMlapack_dorghr (long *n, long *ilo, long *ihi, double *a, long *lda, double *tau, double *work, long *lwork, long *info); /* -- LAPACK routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University June 30, 1999 Purpose ======= NUMlapack_dorghr generates a real orthogonal matrix Q which is defined as the product of IHI-ILO elementary reflectors of order N, as returned by NUMlapack_dgehrd: Q = H(ilo) H(ilo+1) . . . H(ihi-1). Arguments ========= N (input) long The order of the matrix Q. N >= 0. ILO (input) long IHI (input) long ILO and IHI must have the same values as in the previous call of NUMlapack_dgehrd. Q is equal to the unit matrix except in the submatrix Q(ilo+1:ihi,ilo+1:ihi). 1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0. A (input/output) double array, dimension (LDA,N) On entry, the vectors which define the elementary reflectors, as returned by NUMlapack_dgehrd. On exit, the N-by-N orthogonal matrix Q. LDA (input) long The leading dimension of the array A. LDA >= max(1,N). TAU (input) double array, dimension (N-1) TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by NUMlapack_dgehrd. WORK (workspace/output) double array, dimension (LWORK) On exit, if INFO = 0, WORK(1) returns the optimal LWORK. LWORK (input) long The dimension of the array WORK. LWORK >= IHI-ILO. For optimum performance LWORK >= (IHI-ILO)*NB, where NB is the optimal blocksize. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value ===================================================================== */ int NUMlapack_dorgl2 (long *m, long *n, long *k, double *a, long *lda, double *tau, double *work, long *info); /* Purpose ======= NUMlapack_dorgl2 generates an m by n real matrix Q with orthonormal rows, which is defined as the first m rows of a product of k elementary reflectors of order n Q = H(k) . . . H(2) H(1) as returned by NUMlapack_dgelqf. Arguments ========= M (input) long The number of rows of the matrix Q. M >= 0. N (input) long The number of columns of the matrix Q. N >= M. K (input) long The number of elementary reflectors whose product defines the matrix Q. M >= K >= 0. A (input/output) double array, dimension (LDA,N) On entry, the i-th row must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by NUMlapack_dgelqf in the first k rows of its array argument A. On exit, the m-by-n matrix Q. LDA (input) long The first dimension of the array A. LDA >= max(1,M). TAU (input) double array, dimension (K) TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by NUMlapack_dgelqf. WORK (workspace) double array, dimension (M) INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument has an illegal value ===================================================================== */ int NUMlapack_dorglq (long *m, long *n, long *k, double *a, long *lda, double *tau, double *work, long *lwork, long *info); /* Purpose ======= NUMlapack_dorglq generates an M-by-N real matrix Q with orthonormal rows, which is defined as the first M rows of a product of K elementary reflectors of order N Q = H(k) . . . H(2) H(1) as returned by DGELQf. Arguments ========= M (input) long The number of rows of the matrix Q. M >= 0. N (input) long The number of columns of the matrix Q. N >= M. K (input) long The number of elementary reflectors whose product defines the matrix Q. M >= K >= 0. A (input/output) double array, dimension (LDA,N) On entry, the i-th row must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by NUMlapack_dgelqf in the first k rows of its array argument A. On exit, the M-by-N matrix Q. LDA (input) long The first dimension of the array A. LDA >= max(1,M). TAU (input) double array, dimension (K) TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by NUMlapack_dgelqf. WORK (workspace/output) double array, dimension (LWORK) On exit, if INFO = 0, WORK(1) returns the optimal LWORK. LWORK (input) long The dimension of the array WORK. LWORK >= max(1,M). For optimum performance LWORK >= M*NB, where NB is the optimal blocksize. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument has an illegal value ===================================================================== */ int NUMlapack_dorgql (long *m, long *n, long *k, double *a, long *lda, double *tau, double *work, long *lwork, long *info); /* Purpose ======= NUMlapack_dorgql generates an M-by-N real matrix Q with orthonormal columns, which is defined as the last N columns of a product of K elementary reflectors of order M Q = H(k) . . . H(2) H(1) as returned by DGEQLF. Arguments ========= M (input) long The number of rows of the matrix Q. M >= 0. N (input) long The number of columns of the matrix Q. M >= N >= 0. K (input) long The number of elementary reflectors whose product defines the matrix Q. N >= K >= 0. A (input/output) double array, dimension (LDA,N) On entry, the (n-k+i)-th column must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by DGEQLF in the last k columns of its array argument A. On exit, the M-by-N matrix Q. LDA (input) long The first dimension of the array A. LDA >= max(1,M). TAU (input) double array, dimension (K) TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DGEQLF. WORK (workspace/output) double array, dimension (LWORK) On exit, if INFO = 0, WORK(1) returns the optimal LWORK. LWORK (input) long The dimension of the array WORK. LWORK >= max(1,N). For optimum performance LWORK >= N*NB, where NB is the optimal blocksize. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument has an illegal value ===================================================================== */ int NUMlapack_dorgqr (long *m, long *n, long *k, double *a, long *lda, double *tau, double *work, long *lwork, long *info); /* Purpose ======= NUMlapack_dorgqr generates an M-by-N real matrix Q with orthonormal columns, which is defined as the first N columns of a product of K elementary reflectors of order M Q = H(1) H(2) . . . H(k) as returned by DGEQRF. Arguments ========= M (input) long The number of rows of the matrix Q. M >= 0. N (input) long The number of columns of the matrix Q. M >= N >= 0. K (input) long The number of elementary reflectors whose product defines the matrix Q. N >= K >= 0. A (input/output) double array, dimension (LDA,N) On entry, the i-th column must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by DGEQRF in the first k columns of its array argument A. On exit, the M-by-N matrix Q. LDA (input) long The first dimension of the array A. LDA >= max(1,M). TAU (input) double array, dimension (K) TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DGEQRF. WORK (workspace/output) double array, dimension (LWORK) On exit, if INFO = 0, WORK(1) returns the optimal LWORK. LWORK (input) long The dimension of the array WORK. LWORK >= max(1,N). For optimum performance LWORK >= N*NB, where NB is the optimal blocksize. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument has an illegal value ===================================================================== */ int NUMlapack_dorgtr (const char *uplo, long *n, double *a, long *lda, double *tau, double *work, long *lwork, long *info); /* Purpose ======= NUMlapack_dorgtr generates a real orthogonal matrix Q which is defined as the product of n-1 elementary reflectors of order N, as returned by NUMlapack_dsytrd: if UPLO = 'U', Q = H(n-1) . . . H(2) H(1), if UPLO = 'L', Q = H(1) H(2) . . . H(n-1). Arguments ========= UPLO (input) char* = 'U': Upper triangle of A contains elementary reflectors from NUMlapack_dsytrd; = 'L': Lower triangle of A contains elementary reflectors from NUMlapack_dsytrd. N (input) long The order of the matrix Q. N >= 0. A (input/output) double array, dimension (LDA,N) On entry, the vectors which define the elementary reflectors, as returned by NUMlapack_dsytrd. On exit, the N-by-N orthogonal matrix Q. LDA (input) long The leading dimension of the array A. LDA >= max(1,N). TAU (input) double array, dimension (N-1) TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by NUMlapack_dsytrd. WORK (workspace/output) double array, dimension (LWORK) On exit, if INFO = 0, WORK(1) returns the optimal LWORK. LWORK (input) long The dimension of the array WORK. LWORK >= max(1,N-1). For optimum performance LWORK >= (N-1)*NB, where NB is the optimal blocksize. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value ===================================================================== */ int NUMlapack_dorm2r (const char *side, const char *trans, long *m, long *n, long *k, double *a, long *lda, double *tau, double *c, long *ldc, double *work, long *info); /* Purpose ======= NUMlapack_dorm2r overwrites the general real m by n matrix C with Q * C if SIDE = 'L' and TRANS = 'N', or Q'* C if SIDE = 'L' and TRANS = 'T', or C * Q if SIDE = 'R' and TRANS = 'N', or C * Q' if SIDE = 'R' and TRANS = 'T', where Q is a real orthogonal matrix defined as the product of k elementary reflectors Q = H(1) H(2) . . . H(k) as returned by DGEQRF. Q is of order m if SIDE = 'L' and of order n if SIDE = 'R'. Arguments ========= SIDE (input) char* = 'L': apply Q or Q' from the Left = 'R': apply Q or Q' from the Right TRANS (input) char* = 'N': apply Q (No transpose) = 'T': apply Q' (Transpose) M (input) long The number of rows of the matrix C. M >= 0. N (input) long The number of columns of the matrix C. N >= 0. K (input) long The number of elementary reflectors whose product defines the matrix Q. If SIDE = 'L', M >= K >= 0; if SIDE = 'R', N >= K >= 0. A (input) double array, dimension (LDA,K) The i-th column must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by DGEQRF in the first k columns of its array argument A. A is modified by the routine but restored on exit. LDA (input) long The leading dimension of the array A. If SIDE = 'L', LDA >= max(1,M); if SIDE = 'R', LDA >= max(1,N). TAU (input) double array, dimension (K) TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DGEQRF. C (input/output) double array, dimension (LDC,N) On entry, the m by n matrix C. On exit, C is overwritten by Q*C or Q'*C or C*Q' or C*Q. LDC (input) long The leading dimension of the array C. LDC >= max(1,M). WORK (workspace) double array, dimension (N) if SIDE = 'L', (M) if SIDE = 'R' INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value ===================================================================== */ int NUMlapack_dormbr (const char *vect, const char *side, const char *trans, long *m, long *n, long *k, double *a, long *lda, double *tau, double *c, long *ldc, double *work, long *lwork, long *info); /* Purpose ======= If VECT = 'Q', NUMlapack_dormbr overwrites the general real M-by-N matrix C with SIDE = 'L' SIDE = 'R' TRANS = 'N': Q * C C * Q TRANS = 'T': Q**T * C C * Q**T If VECT = 'P', NUMlapack_dormbr overwrites the general real M-by-N matrix C with SIDE = 'L' SIDE = 'R' TRANS = 'N': P * C C * P TRANS = 'T': P**T * C C * P**T Here Q and P**T are the orthogonal matrices determined by DGEBRD when reducing a real matrix A to bidiagonal form: A = Q * B * P**T. Q and P**T are defined as products of elementary reflectors H(i) and G(i) respectively. Let nq = m if SIDE = 'L' and nq = n if SIDE = 'R'. Thus nq is the order of the orthogonal matrix Q or P**T that is applied. If VECT = 'Q', A is assumed to have been an NQ-by-K matrix: if nq >= k, Q = H(1) H(2) . . . H(k); if nq < k, Q = H(1) H(2) . . . H(nq-1). If VECT = 'P', A is assumed to have been a K-by-NQ matrix: if k < nq, P = G(1) G(2) . . . G(k); if k >= nq, P = G(1) G(2) . . . G(nq-1). Arguments ========= VECT (input) char* = 'Q': apply Q or Q**T; = 'P': apply P or P**T. SIDE (input) char* = 'L': apply Q, Q**T, P or P**T from the Left; = 'R': apply Q, Q**T, P or P**T from the Right. TRANS (input) char* = 'N': No transpose, apply Q or P; = 'T': Transpose, apply Q**T or P**T. M (input) long The number of rows of the matrix C. M >= 0. N (input) long The number of columns of the matrix C. N >= 0. K (input) long If VECT = 'Q', the number of columns in the original matrix reduced by DGEBRD. If VECT = 'P', the number of rows in the original matrix reduced by DGEBRD. K >= 0. A (input) double array, dimension (LDA,min(nq,K)) if VECT = 'Q' (LDA,nq) if VECT = 'P' The vectors which define the elementary reflectors H(i) and G(i), whose products determine the matrices Q and P, as returned by DGEBRD. LDA (input) long The leading dimension of the array A. If VECT = 'Q', LDA >= max(1,nq); if VECT = 'P', LDA >= max(1,min(nq,K)). TAU (input) double array, dimension (min(nq,K)) TAU(i) must contain the scalar factor of the elementary reflector H(i) or G(i) which determines Q or P, as returned by DGEBRD in the array argument TAUQ or TAUP. C (input/output) double array, dimension (LDC,N) On entry, the M-by-N matrix C. On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q or P*C or P**T*C or C*P or C*P**T. LDC (input) long The leading dimension of the array C. LDC >= max(1,M). WORK (workspace/output) double array, dimension (LWORK) On exit, if INFO = 0, WORK(1) returns the optimal LWORK. LWORK (input) long The dimension of the array WORK. If SIDE = 'L', LWORK >= max(1,N); if SIDE = 'R', LWORK >= max(1,M). For optimum performance LWORK >= N*NB if SIDE = 'L', and LWORK >= M*NB if SIDE = 'R', where NB is the optimal blocksize. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value ===================================================================== */ int NUMlapack_dorml2 (const char *side, const char *trans, long *m, long *n, long *k, double *a, long *lda, double *tau, double *c, long *ldc, double *work, long *info); /* Purpose ======= NUMlapack_dorml2 overwrites the general real m by n matrix C with Q * C if SIDE = 'L' and TRANS = 'N', or Q'* C if SIDE = 'L' and TRANS = 'T', or C * Q if SIDE = 'R' and TRANS = 'N', or C * Q' if SIDE = 'R' and TRANS = 'T', where Q is a real orthogonal matrix defined as the product of k elementary reflectors Q = H(k) . . . H(2) H(1) as returned by NUMlapack_dgelqf. Q is of order m if SIDE = 'L' and of order n if SIDE = 'R'. Arguments ========= SIDE (input) char* = 'L': apply Q or Q' from the Left = 'R': apply Q or Q' from the Right TRANS (input) char* = 'N': apply Q (No transpose) = 'T': apply Q' (Transpose) M (input) long The number of rows of the matrix C. M >= 0. N (input) long The number of columns of the matrix C. N >= 0. K (input) long The number of elementary reflectors whose product defines the matrix Q. If SIDE = 'L', M >= K >= 0; if SIDE = 'R', N >= K >= 0. A (input) double array, dimension (LDA,M) if SIDE = 'L', (LDA,N) if SIDE = 'R' The i-th row must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by NUMlapack_dgelqf in the first k rows of its array argument A. A is modified by the routine but restored on exit. LDA (input) long The leading dimension of the array A. LDA >= max(1,K). TAU (input) double array, dimension (K) TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by NUMlapack_dgelqf. C (input/output) double array, dimension (LDC,N) On entry, the m by n matrix C. On exit, C is overwritten by Q*C or Q'*C or C*Q' or C*Q. LDC (input) long The leading dimension of the array C. LDC >= max(1,M). WORK (workspace) double array, dimension (N) if SIDE = 'L', (M) if SIDE = 'R' INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value ===================================================================== */ int NUMlapack_dormlq (const char *side, const char *trans, long *m, long *n, long *k, double *a, long *lda, double *tau, double *c, long *ldc, double *work, long *lwork, long *info); /* Purpose ======= NUMlapack_dormlq overwrites the general real M-by-N matrix C with SIDE = 'L' SIDE = 'R' TRANS = 'N': Q * C C * Q TRANS = 'T': Q**T * C C * Q**T where Q is a real orthogonal matrix defined as the product of k elementary reflectors Q = H(k) . . . H(2) H(1) as returned by NUMlapack_dgelqf. Q is of order M if SIDE = 'L' and of order N if SIDE = 'R'. Arguments ========= SIDE (input) char* = 'L': apply Q or Q**T from the Left; = 'R': apply Q or Q**T from the Right. TRANS (input) char* = 'N': No transpose, apply Q; = 'T': Transpose, apply Q**T. M (input) long The number of rows of the matrix C. M >= 0. N (input) long The number of columns of the matrix C. N >= 0. K (input) long The number of elementary reflectors whose product defines the matrix Q. If SIDE = 'L', M >= K >= 0; if SIDE = 'R', N >= K >= 0. A (input) double array, dimension (LDA,M) if SIDE = 'L', (LDA,N) if SIDE = 'R' The i-th row must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by NUMlapack_dgelqf in the first k rows of its array argument A. A is modified by the routine but restored on exit. LDA (input) long The leading dimension of the array A. LDA >= max(1,K). TAU (input) double array, dimension (K) TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by NUMlapack_dgelqf. C (input/output) double array, dimension (LDC,N) On entry, the M-by-N matrix C. On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q. LDC (input) long The leading dimension of the array C. LDC >= max(1,M). WORK (workspace/output) double array, dimension (LWORK) On exit, if INFO = 0, WORK(1) returns the optimal LWORK. LWORK (input) long The dimension of the array WORK. If SIDE = 'L', LWORK >= max(1,N); if SIDE = 'R', LWORK >= max(1,M). For optimum performance LWORK >= N*NB if SIDE = 'L', and LWORK >= M*NB if SIDE = 'R', where NB is the optimal blocksize. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value ===================================================================== */ int NUMlapack_dormqr (const char *side, const char *trans, long *m, long *n, long *k, double *a, long *lda, double *tau, double *c, long *ldc, double *work, long *lwork, long *info); /* Purpose ======= NUMlapack_dormqr overwrites the general real M-by-N matrix C with SIDE = 'L' SIDE = 'R' TRANS = 'N': Q * C C * Q TRANS = 'T': Q**T * C C * Q**T where Q is a real orthogonal matrix defined as the product of k elementary reflectors Q = H(1) H(2) . . . H(k) as returned by DGEQRF. Q is of order M if SIDE = 'L' and of order N if SIDE = 'R'. Arguments ========= SIDE (input) char* = 'L': apply Q or Q**T from the Left; = 'R': apply Q or Q**T from the Right. TRANS (input) char* = 'N': No transpose, apply Q; = 'T': Transpose, apply Q**T. M (input) long The number of rows of the matrix C. M >= 0. N (input) long The number of columns of the matrix C. N >= 0. K (input) long The number of elementary reflectors whose product defines the matrix Q. If SIDE = 'L', M >= K >= 0; if SIDE = 'R', N >= K >= 0. A (input) double array, dimension (LDA,K) The i-th column must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by DGEQRF in the first k columns of its array argument A. A is modified by the routine but restored on exit. LDA (input) long The leading dimension of the array A. If SIDE = 'L', LDA >= max(1,M); if SIDE = 'R', LDA >= max(1,N). TAU (input) double array, dimension (K) TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DGEQRF. C (input/output) double array, dimension (LDC,N) On entry, the M-by-N matrix C. On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q. LDC (input) long The leading dimension of the array C. LDC >= max(1,M). WORK (workspace/output) double array, dimension (LWORK) On exit, if INFO = 0, WORK(1) returns the optimal LWORK. LWORK (input) long The dimension of the array WORK. If SIDE = 'L', LWORK >= max(1,N); if SIDE = 'R', LWORK >= max(1,M). For optimum performance LWORK >= N*NB if SIDE = 'L', and LWORK >= M*NB if SIDE = 'R', where NB is the optimal blocksize. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value ===================================================================== */ int NUMlapack_dormr2 (const char *side, const char *trans, long *m, long *n, long *k, double *a, long *lda, double *tau, double *c, long *ldc, double *work, long *info); /* Purpose ======= NUMlapack_dormr2 overwrites the general real m by n matrix C with Q * C if SIDE = 'L' and TRANS = 'N', or Q'* C if SIDE = 'L' and TRANS = 'T', or C * Q if SIDE = 'R' and TRANS = 'N', or C * Q' if SIDE = 'R' and TRANS = 'T', where Q is a real orthogonal matrix defined as the product of k elementary reflectors Q = H(1) H(2) . . . H(k) as returned by DGERQF. Q is of order m if SIDE = 'L' and of order n if SIDE = 'R'. Arguments ========= SIDE (input) char* = 'L': apply Q or Q' from the Left = 'R': apply Q or Q' from the Right TRANS (input) char* = 'N': apply Q (No transpose) = 'T': apply Q' (Transpose) M (input) long The number of rows of the matrix C. M >= 0. N (input) long The number of columns of the matrix C. N >= 0. K (input) long The number of elementary reflectors whose product defines the matrix Q. If SIDE = 'L', M >= K >= 0; if SIDE = 'R', N >= K >= 0. A (input) double array, dimension (LDA,M) if SIDE = 'L', (LDA,N) if SIDE = 'R' The i-th row must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by DGERQF in the last k rows of its array argument A. A is modified by the routine but restored on exit. LDA (input) long The leading dimension of the array A. LDA >= max(1,K). TAU (input) double array, dimension (K) TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DGERQF. C (input/output) double array, dimension (LDC,N) On entry, the m by n matrix C. On exit, C is overwritten by Q*C or Q'*C or C*Q' or C*Q. LDC (input) long The leading dimension of the array C. LDC >= max(1,M). WORK (workspace) double array, dimension (N) if SIDE = 'L', (M) if SIDE = 'R' INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value ===================================================================== */ int NUMlapack_dpotf2 (const char *uplo, long *n, double *a, long *lda, long *info); /* -- LAPACK routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University February 29, 1992 Purpose ======= NUMlapack_dpotf2 computes the Cholesky factorization of a real symmetric positive definite matrix A. The factorization has the form A = U' * U , if UPLO = 'U', or A = L * L', if UPLO = 'L', where U is an upper triangular matrix and L is lower triangular. This is the unblocked version of the algorithm, calling Level 2 BLAS. Arguments ========= UPLO (input) char * Specifies whether the upper or lower triangular part of the symmetric matrix A is stored. = 'U': Upper triangular = 'L': Lower triangular N (input) long The order of the matrix A. N >= 0. A (input/output) double array, dimension (LDA,N) On entry, the symmetric matrix A. If UPLO = 'U', the leading n by n upper triangular part of A contains the upper triangular part of the matrix A, and the strictly lower triangular part of A is not referenced. If UPLO = 'L', the leading n by n lower triangular part of A contains the lower triangular part of the matrix A, and the strictly upper triangular part of A is not referenced. On exit, if INFO = 0, the factor U or L from the Cholesky factorization A = U'*U or A = L*L'. LDA (input) long The leading dimension of the array A. LDA >= max(1,N). INFO (output) long = 0: successful exit < 0: if INFO = -k, the k-th argument had an illegal value > 0: if INFO = k, the leading minor of order k is not positive definite, and the factorization could not be completed. */ int NUMlapack_drscl (long *n, double *sa, double *sx, long *incx); /* Purpose ======= NUMlapack_drscl multiplies an n-element real vector x by the real scalar 1/a. This is done without overflow or underflow as long as the final result x/a does not overflow or underflow. Arguments ========= N (input) long The number of components of the vector x. SA (input) double The scalar a which is used to divide each component of x. SA must be >= 0, or the subroutine will divide by zero. SX (input/output) double array, dimension (1+(N-1)*abs(INCX)) The n-element vector x. INCX (input) long The increment between successive values of the vector SX. > 0: SX(1) = X(1) and SX(1+(i-1)*INCX) = x(i), 1< i<= n ===================================================================== */ int NUMlapack_dsteqr (const char *compz, long *n, double *d, double *e, double *z, long *ldz, double *work, long *info); /* Purpose ======= NUMlapack_dsteqr computes all eigenvalues and, optionally, eigenvectors of a symmetric tridiagonal matrix using the implicit QL or QR method. The eigenvectors of a full or band symmetric matrix can also be found if NUMlapack_dsytrd or DSPTRD or DSBTRD has been used to reduce this matrix to tridiagonal form. Arguments ========= COMPZ (input) char* = 'N': Compute eigenvalues only. = 'V': Compute eigenvalues and eigenvectors of the original symmetric matrix. On entry, Z must contain the orthogonal matrix used to reduce the original matrix to tridiagonal form. = 'I': Compute eigenvalues and eigenvectors of the tridiagonal matrix. Z is initialized to the identity matrix. N (input) long The order of the matrix. N >= 0. D (input/output) double array, dimension (N) On entry, the diagonal elements of the tridiagonal matrix. On exit, if INFO = 0, the eigenvalues in ascending order. E (input/output) double array, dimension (N-1) On entry, the (n-1) subdiagonal elements of the tridiagonal matrix. On exit, E has been destroyed. Z (input/output) double array, dimension (LDZ, N) On entry, if COMPZ = 'V', then Z contains the orthogonal matrix used in the reduction to tridiagonal form. On exit, if INFO = 0, then if COMPZ = 'V', Z contains the orthonormal eigenvectors of the original symmetric matrix, and if COMPZ = 'I', Z contains the orthonormal eigenvectors of the symmetric tridiagonal matrix. If COMPZ = 'N', then Z is not referenced. LDZ (input) long The leading dimension of the array Z. LDZ >= 1, and if eigenvectors are desired, then LDZ >= max(1,N). WORK (workspace) double array, dimension (max(1,2*N-2)) If COMPZ = 'N', then WORK is not referenced. INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value > 0: the algorithm has failed to find all the eigenvalues in a total of 30*N iterations; if INFO = i, then i elements of E have not converged to zero; on exit, D and E contain the elements of a symmetric tridiagonal matrix which is orthogonally similar to the original matrix. ===================================================================== */ int NUMlapack_dsterf (long *n, double *d, double *e, long *info); /* Purpose ======= NUMlapack_dsterf computes all eigenvalues of a symmetric tridiagonal matrix using the Pal-Walker-Kahan variant of the QL or QR algorithm. Arguments ========= N (input) long The order of the matrix. N >= 0. D (input/output) double array, dimension (N) On entry, the n diagonal elements of the tridiagonal matrix. On exit, if INFO = 0, the eigenvalues in ascending order. E (input/output) double array, dimension (N-1) On entry, the (n-1) subdiagonal elements of the tridiagonal matrix. On exit, E has been destroyed. INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value > 0: the algorithm failed to find all of the eigenvalues in a total of 30*N iterations; if INFO = i, then i elements of E have not converged to zero. ===================================================================== */ int NUMlapack_dsyev (const char *jobz, const char *uplo, long *n, double *a, long *lda, double *w, double *work, long *lwork, long *info); /* Purpose ======= NUMlapack_dsyev computes all eigenvalues and, optionally, eigenvectors of a real symmetric matrix A. Arguments ========= JOBZ (input) char* = 'N': Compute eigenvalues only; = 'V': Compute eigenvalues and eigenvectors. UPLO (input) char* = 'U': Upper triangle of A is stored; = 'L': Lower triangle of A is stored. N (input) long The order of the matrix A. N >= 0. A (input/output) double array, dimension (LDA, N) On entry, the symmetric matrix A. If UPLO = 'U', the leading N-by-N upper triangular part of A contains the upper triangular part of the matrix A. If UPLO = 'L', the leading N-by-N lower triangular part of A contains the lower triangular part of the matrix A. On exit, if JOBZ = 'V', then if INFO = 0, A contains the orthonormal eigenvectors of the matrix A. If JOBZ = 'N', then on exit the lower triangle (if UPLO='L') or the upper triangle (if UPLO='U') of A, including the diagonal, is destroyed. LDA (input) long The leading dimension of the array A. LDA >= max(1,N). W (output) double array, dimension (N) If INFO = 0, the eigenvalues in ascending order. WORK (workspace/output) double array, dimension (LWORK) On exit, if INFO = 0, WORK(1) returns the optimal LWORK. LWORK (input) long The length of the array WORK. LWORK >= max(1,3*N-1). For optimal efficiency, LWORK >= (NB+2)*N, where NB is the blocksize for NUMlapack_dsytrd returned by NUMlapack_ilaenv. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value > 0: if INFO = i, the algorithm failed to converge; i off-diagonal elements of an intermediate tridiagonal form did not converge to zero. ===================================================================== */ int NUMlapack_dsytd2 (const char *uplo, long *n, double *a, long *lda, double *d, double *e, double *tau, long *info); /* Purpose ======= NUMlapack_dsytd2 reduces a real symmetric matrix A to symmetric tridiagonal form T by an orthogonal similarity transformation: Q' * A * Q = T. Arguments ========= UPLO (input) char* Specifies whether the upper or lower triangular part of the symmetric matrix A is stored: = 'U': Upper triangular = 'L': Lower triangular N (input) long The order of the matrix A. N >= 0. A (input/output) double array, dimension (LDA,N) On entry, the symmetric matrix A. If UPLO = 'U', the leading n-by-n upper triangular part of A contains the upper triangular part of the matrix A, and the strictly lower triangular part of A is not referenced. If UPLO = 'L', the leading n-by-n lower triangular part of A contains the lower triangular part of the matrix A, and the strictly upper triangular part of A is not referenced. On exit, if UPLO = 'U', the diagonal and first superdiagonal of A are overwritten by the corresponding elements of the tridiagonal matrix T, and the elements above the first superdiagonal, with the array TAU, represent the orthogonal matrix Q as a product of elementary reflectors; if UPLO = 'L', the diagonal and first subdiagonal of A are over- written by the corresponding elements of the tridiagonal matrix T, and the elements below the first subdiagonal, with the array TAU, represent the orthogonal matrix Q as a product of elementary reflectors. See Further Details. LDA (input) long The leading dimension of the array A. LDA >= max(1,N). D (output) double array, dimension (N) The diagonal elements of the tridiagonal matrix T: D(i) = A(i,i). E (output) double array, dimension (N-1) The off-diagonal elements of the tridiagonal matrix T: E(i) = A(i,i+1) if UPLO = 'U', E(i) = A(i+1,i) if UPLO = 'L'. TAU (output) double array, dimension (N-1) The scalar factors of the elementary reflectors (see Further Details). INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value. Further Details =============== If UPLO = 'U', the matrix Q is represented as a product of elementary reflectors Q = H(n-1) . . . H(2) H(1). Each H(i) has the form H(i) = I - tau * v * v' where tau is a real scalar, and v is a real vector with v(i+1:n) = 0 and v(i) = 1; v(1:i-1) is stored on exit in A(1:i-1,i+1), and tau in TAU(i). If UPLO = 'L', the matrix Q is represented as a product of elementary reflectors Q = H(1) H(2) . . . H(n-1). Each H(i) has the form H(i) = I - tau * v * v' where tau is a real scalar, and v is a real vector with v(1:i) = 0 and v(i+1) = 1; v(i+2:n) is stored on exit in A(i+2:n,i), and tau in TAU(i). The contents of A on exit are illustrated by the following examples with n = 5: if UPLO = 'U': if UPLO = 'L': ( d e v2 v3 v4 ) ( d ) ( d e v3 v4 ) ( e d ) ( d e v4 ) ( v1 e d ) ( d e ) ( v1 v2 e d ) ( d ) ( v1 v2 v3 e d ) where d and e denote diagonal and off-diagonal elements of T, and vi denotes an element of the vector defining H(i). ===================================================================== */ int NUMlapack_dsytrd (const char *uplo, long *n, double *a, long *lda, double *d, double *e, double *tau, double *work, long *lwork, long *info); /* Purpose ======= NUMlapack_dsytrd reduces a real symmetric matrix A to real symmetric tridiagonal form T by an orthogonal similarity transformation: Q**T * A * Q = T. Arguments ========= UPLO (input) char* = 'U': Upper triangle of A is stored; = 'L': Lower triangle of A is stored. N (input) long The order of the matrix A. N >= 0. A (input/output) double array, dimension (LDA,N) On entry, the symmetric matrix A. If UPLO = 'U', the leading N-by-N upper triangular part of A contains the upper triangular part of the matrix A, and the strictly lower triangular part of A is not referenced. If UPLO = 'L', the leading N-by-N lower triangular part of A contains the lower triangular part of the matrix A, and the strictly upper triangular part of A is not referenced. On exit, if UPLO = 'U', the diagonal and first superdiagonal of A are overwritten by the corresponding elements of the tridiagonal matrix T, and the elements above the first superdiagonal, with the array TAU, represent the orthogonal matrix Q as a product of elementary reflectors; if UPLO = 'L', the diagonal and first subdiagonal of A are over- written by the corresponding elements of the tridiagonal matrix T, and the elements below the first subdiagonal, with the array TAU, represent the orthogonal matrix Q as a product of elementary reflectors. See Further Details. LDA (input) long The leading dimension of the array A. LDA >= max(1,N). D (output) double array, dimension (N) The diagonal elements of the tridiagonal matrix T: D(i) = A(i,i). E (output) double array, dimension (N-1) The off-diagonal elements of the tridiagonal matrix T: E(i) = A(i,i+1) if UPLO = 'U', E(i) = A(i+1,i) if UPLO = 'L'. TAU (output) double array, dimension (N-1) The scalar factors of the elementary reflectors (see Further Details). WORK (workspace/output) double array, dimension (LWORK) On exit, if INFO = 0, WORK(1) returns the optimal LWORK. LWORK (input) long The dimension of the array WORK. LWORK >= 1. For optimum performance LWORK >= N*NB, where NB is the optimal blocksize. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value Further Details =============== If UPLO = 'U', the matrix Q is represented as a product of elementary reflectors Q = H(n-1) . . . H(2) H(1). Each H(i) has the form H(i) = I - tau * v * v' where tau is a real scalar, and v is a real vector with v(i+1:n) = 0 and v(i) = 1; v(1:i-1) is stored on exit in A(1:i-1,i+1), and tau in TAU(i). If UPLO = 'L', the matrix Q is represented as a product of elementary reflectors Q = H(1) H(2) . . . H(n-1). Each H(i) has the form H(i) = I - tau * v * v' where tau is a real scalar, and v is a real vector with v(1:i) = 0 and v(i+1) = 1; v(i+2:n) is stored on exit in A(i+2:n,i), and tau in TAU(i). The contents of A on exit are illustrated by the following examples with n = 5: if UPLO = 'U': if UPLO = 'L': ( d e v2 v3 v4 ) ( d ) ( d e v3 v4 ) ( e d ) ( d e v4 ) ( v1 e d ) ( d e ) ( v1 v2 e d ) ( d ) ( v1 v2 v3 e d ) where d and e denote diagonal and off-diagonal elements of T, and vi denotes an element of the vector defining H(i). ===================================================================== */ int NUMlapack_dtgsja(const char *jobu, const char *jobv, const char *jobq, long *m, long *p, long *n, long *k, long *l, double *a, long *lda, double *b, long *ldb, double *tola, double *tolb, double *alpha, double *beta, double *u, long *ldu, double *v, long *ldv, double *q, long *ldq, double *work, long *ncycle, long *info); /* Purpose ======= NUMlapack_dtgsja computes the generalized singular value decomposition (GSVD) of two real upper triangular (or trapezoidal) matrices A and B. On entry, it is assumed that matrices A and B have the following forms, which may be obtained by the preprocessing subroutine NUMlapack_dggsvp from a general M-by-N matrix A and P-by-N matrix B: N-K-L K L A = K ( 0 A12 A13 ) if M-K-L >= 0; L ( 0 0 A23 ) M-K-L ( 0 0 0 ) N-K-L K L A = K ( 0 A12 A13 ) if M-K-L < 0; M-K ( 0 0 A23 ) N-K-L K L B = L ( 0 0 B13 ) P-L ( 0 0 0 ) where the K-by-K matrix A12 and L-by-L matrix B13 are nonsingular upper triangular; A23 is L-by-L upper triangular if M-K-L >= 0, otherwise A23 is (M-K)-by-L upper trapezoidal. On exit, U'*A*Q = D1*( 0 R ), V'*B*Q = D2*( 0 R ), where U, V and Q are orthogonal matrices, Z' denotes the transpose of Z, R is a nonsingular upper triangular matrix, and D1 and D2 are ``diagonal'' matrices, which are of the following structures: If M-K-L >= 0, K L D1 = K ( I 0 ) L ( 0 C ) M-K-L ( 0 0 ) K L D2 = L ( 0 S ) P-L ( 0 0 ) N-K-L K L ( 0 R ) = K ( 0 R11 R12 ) K L ( 0 0 R22 ) L where C = diag( ALPHA(K+1), ... , ALPHA(K+L) ), S = diag( BETA(K+1), ... , BETA(K+L) ), C**2 + S**2 = I. R is stored in A(1:K+L,N-K-L+1:N) on exit. If M-K-L < 0, K M-K K+L-M D1 = K ( I 0 0 ) M-K ( 0 C 0 ) K M-K K+L-M D2 = M-K ( 0 S 0 ) K+L-M ( 0 0 I ) P-L ( 0 0 0 ) N-K-L K M-K K+L-M ( 0 R ) = K ( 0 R11 R12 R13 ) M-K ( 0 0 R22 R23 ) K+L-M ( 0 0 0 R33 ) where C = diag( ALPHA(K+1), ... , ALPHA(M) ), S = diag( BETA(K+1), ... , BETA(M) ), C**2 + S**2 = I. R = ( R11 R12 R13 ) is stored in A(1:M, N-K-L+1:N) and R33 is stored ( 0 R22 R23 ) in B(M-K+1:L,N+M-K-L+1:N) on exit. The computation of the orthogonal transformation matrices U, V or Q is optional. These matrices may either be formed explicitly, or they may be postmultiplied into input matrices U1, V1, or Q1. Arguments ========= JOBU (input) char* = 'U': U must contain an orthogonal matrix U1 on entry, and the product U1*U is returned; = 'I': U is initialized to the unit matrix, and the orthogonal matrix U is returned; = 'N': U is not computed. JOBV (input) char* = 'V': V must contain an orthogonal matrix V1 on entry, and the product V1*V is returned; = 'I': V is initialized to the unit matrix, and the orthogonal matrix V is returned; = 'N': V is not computed. JOBQ (input) char* = 'Q': Q must contain an orthogonal matrix Q1 on entry, and the product Q1*Q is returned; = 'I': Q is initialized to the unit matrix, and the orthogonal matrix Q is returned; = 'N': Q is not computed. M (input) long The number of rows of the matrix A. M >= 0. P (input) long The number of rows of the matrix B. P >= 0. N (input) long The number of columns of the matrices A and B. N >= 0. K (input) long L (input) long K and L specify the subblocks in the input matrices A and B: A23 = A(K+1:MIN(K+L,M),N-L+1:N) and B13 = B(1:L,N-L+1:N) of A and B, whose GSVD is going to be computed by NUMlapack_dtgsja. See Further details. A (input/output) double array, dimension (LDA,N) On entry, the M-by-N matrix A. On exit, A(N-K+1:N,1:MIN(K+L,M) ) contains the triangular matrix R or part of R. See Purpose for details. LDA (input) long The leading dimension of the array A. LDA >= max(1,M). B (input/output) double array, dimension (LDB,N) On entry, the P-by-N matrix B. On exit, if necessary, B(M-K+1:L,N+M-K-L+1:N) contains a part of R. See Purpose for details. LDB (input) long The leading dimension of the array B. LDB >= max(1,P). TOLA (input) double TOLB (input) double TOLA and TOLB are the convergence criteria for the Jacobi- Kogbetliantz iteration procedure. Generally, they are the same as used in the preprocessing step, say TOLA = max(M,N)*norm(A)*MAZHEPS, TOLB = max(P,N)*norm(B)*MAZHEPS. ALPHA (output) double array, dimension (N) BETA (output) double array, dimension (N) On exit, ALPHA and BETA contain the generalized singular value pairs of A and B; ALPHA(1:K) = 1, BETA(1:K) = 0, and if M-K-L >= 0, ALPHA(K+1:K+L) = diag(C), BETA(K+1:K+L) = diag(S), or if M-K-L < 0, ALPHA(K+1:M)= C, ALPHA(M+1:K+L)= 0 BETA(K+1:M) = S, BETA(M+1:K+L) = 1. Furthermore, if K+L < N, ALPHA(K+L+1:N) = 0 and BETA(K+L+1:N) = 0. U (input/output) double array, dimension (LDU,M) On entry, if JOBU = 'U', U must contain a matrix U1 (usually the orthogonal matrix returned by NUMlapack_dggsvp). On exit, if JOBU = 'I', U contains the orthogonal matrix U; if JOBU = 'U', U contains the product U1*U. If JOBU = 'N', U is not referenced. LDU (input) long The leading dimension of the array U. LDU >= max(1,M) if JOBU = 'U'; LDU >= 1 otherwise. V (input/output) double array, dimension (LDV,P) On entry, if JOBV = 'V', V must contain a matrix V1 (usually the orthogonal matrix returned by NUMlapack_dggsvp). On exit, if JOBV = 'I', V contains the orthogonal matrix V; if JOBV = 'V', V contains the product V1*V. If JOBV = 'N', V is not referenced. LDV (input) long The leading dimension of the array V. LDV >= max(1,P) if JOBV = 'V'; LDV >= 1 otherwise. Q (input/output) double array, dimension (LDQ,N) On entry, if JOBQ = 'Q', Q must contain a matrix Q1 (usually the orthogonal matrix returned by NUMlapack_dggsvp). On exit, if JOBQ = 'I', Q contains the orthogonal matrix Q; if JOBQ = 'Q', Q contains the product Q1*Q. If JOBQ = 'N', Q is not referenced. LDQ (input) long The leading dimension of the array Q. LDQ >= max(1,N) if JOBQ = 'Q'; LDQ >= 1 otherwise. WORK (workspace) double array, dimension (2*N) NCYCLE (output) long The number of cycles required for convergence. INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value. = 1: the procedure does not converge after MAXIT cycles. Internal Parameters =================== MAXIT long MAXIT specifies the total loops that the iterative procedure may take. If after MAXIT cycles, the routine fails to converge, we return INFO = 1. Further Details =============== NUMlapack_dtgsja essentially uses a variant of Kogbetliantz algorithm to reduce min(L,M-K)-by-L triangular (or trapezoidal) matrix A23 and L-by-L matrix B13 to the form: U1'*A13*Q1 = C1*R1; V1'*B13*Q1 = S1*R1, where U1, V1 and Q1 are orthogonal matrix, and Z' is the transpose of Z. C1 and S1 are diagonal matrices satisfying C1**2 + S1**2 = I, and R1 is an L-by-L nonsingular upper triangular matrix. ===================================================================== */ int NUMlapack_dtrevc (const char *side, const char *howmny, int * select, long *n, double *t, long *ldt, double *vl, long *ldvl, double *vr, long *ldvr, long *mm, long *m, double *work, long *info); /* -- LAPACK routine (version 3.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University June 30, 1999 Purpose ======= NUMlapack_dtrevc computes some or all of the right and/or left eigenvectors of a real upper quasi-triangular matrix T. The right eigenvector x and the left eigenvector y of T corresponding to an eigenvalue w are defined by: T*x = w*x, y'*T = w*y' where y' denotes the conjugate transpose of the vector y. If all eigenvectors are requested, the routine may either return the matrices X and/or Y of right or left eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an input orthogonal matrix. If T was obtained from the real-Schur factorization of an original matrix A = Q*T*Q', then Q*X and Q*Y are the matrices of right or left eigenvectors of A. T must be in Schur canonical form (as returned by NUMlapack_dhseqr), that is, block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each 2-by-2 diagonal block has its diagonal elements equal and its off-diagonal elements of opposite sign. Corresponding to each 2-by-2 diagonal block is a complex conjugate pair of eigenvalues and eigenvectors; only one eigenvector of the pair is computed, namely the one corresponding to the eigenvalue with positive imaginary part. Arguments ========= SIDE (input) char* = 'R': compute right eigenvectors only; = 'L': compute left eigenvectors only; = 'B': compute both right and left eigenvectors. HOWMNY (input) char* = 'A': compute all right and/or left eigenvectors; = 'B': compute all right and/or left eigenvectors, and backtransform them using the input matrices supplied in VR and/or VL; = 'S': compute selected right and/or left eigenvectors, specified by the int array SELECT. SELECT (input/output) int array, dimension (N) If HOWMNY = 'S', SELECT specifies the eigenvectors to be computed. If HOWMNY = 'A' or 'B', SELECT is not referenced. To select the real eigenvector corresponding to a real eigenvalue w(j), SELECT(j) must be set to .TRUE.. To select the complex eigenvector corresponding to a complex conjugate pair w(j) and w(j+1), either SELECT(j) or SELECT(j+1) must be set to .TRUE.; then on exit SELECT(j) is .TRUE. and SELECT(j+1) is .FALSE.. N (input) long The order of the matrix T. N >= 0. T (input) double array, dimension (LDT,N) The upper quasi-triangular matrix T in Schur canonical form. LDT (input) long The leading dimension of the array T. LDT >= max(1,N). VL (input/output) double array, dimension (LDVL,MM) On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must contain an N-by-N matrix Q (usually the orthogonal matrix Q of Schur vectors returned by NUMlapack_dhseqr). On exit, if SIDE = 'L' or 'B', VL contains: if HOWMNY = 'A', the matrix Y of left eigenvectors of T; VL has the same quasi-lower triangular form as T'. If T(i,i) is a real eigenvalue, then the i-th column VL(i) of VL is its corresponding eigenvector. If T(i:i+1,i:i+1) is a 2-by-2 block whose eigenvalues are complex-conjugate eigenvalues of T, then VL(i)+sqrt(-1)*VL(i+1) is the complex eigenvector corresponding to the eigenvalue with positive real part. if HOWMNY = 'B', the matrix Q*Y; if HOWMNY = 'S', the left eigenvectors of T specified by SELECT, stored consecutively in the columns of VL, in the same order as their eigenvalues. A complex eigenvector corresponding to a complex eigenvalue is stored in two consecutive columns, the first holding the real part, and the second the imaginary part. If SIDE = 'R', VL is not referenced. LDVL (input) long The leading dimension of the array VL. LDVL >= max(1,N) if SIDE = 'L' or 'B'; LDVL >= 1 otherwise. VR (input/output) double array, dimension (LDVR,MM) On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must contain an N-by-N matrix Q (usually the orthogonal matrix Q of Schur vectors returned by NUMlapack_dhseqr). On exit, if SIDE = 'R' or 'B', VR contains: if HOWMNY = 'A', the matrix X of right eigenvectors of T; VR has the same quasi-upper triangular form as T. If T(i,i) is a real eigenvalue, then the i-th column VR(i) of VR is its corresponding eigenvector. If T(i:i+1,i:i+1) is a 2-by-2 block whose eigenvalues are complex-conjugate eigenvalues of T, then VR(i)+sqrt(-1)*VR(i+1) is the complex eigenvector corresponding to the eigenvalue with positive real part. if HOWMNY = 'B', the matrix Q*X; if HOWMNY = 'S', the right eigenvectors of T specified by SELECT, stored consecutively in the columns of VR, in the same order as their eigenvalues. A complex eigenvector corresponding to a complex eigenvalue is stored in two consecutive columns, the first holding the real part and the second the imaginary part. If SIDE = 'L', VR is not referenced. LDVR (input) long The leading dimension of the array VR. LDVR >= max(1,N) if SIDE = 'R' or 'B'; LDVR >= 1 otherwise. MM (input) long The number of columns in the arrays VL and/or VR. MM >= M. M (output) long The number of columns in the arrays VL and/or VR actually used to store the eigenvectors. If HOWMNY = 'A' or 'B', M is set to N. Each selected real eigenvector occupies one column and each selected complex eigenvector occupies two columns. WORK (workspace) double array, dimension (3*N) INFO (output) INTEGER = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value Further Details =============== The algorithm used in this program is basically backward (forward) substitution, with scaling to make the the code robust against possible overflow. Each eigenvector is normalized so that the element of largest magnitude has magnitude 1; here the magnitude of a complex number (x,y) is taken to be |x| + |y|. ===================================================================== */ int NUMlapack_dtrti2 (const char *uplo, const char *diag, long *n, double *a, long *lda, long *info); /* Purpose ======= NUMlapack_dtrti2 computes the inverse of a real upper or lower triangular matrix. This is the Level 2 BLAS version of the algorithm. Arguments ========= UPLO (input) char* Specifies whether the matrix A is upper or lower triangular. = 'U': Upper triangular = 'L': Lower triangular DIAG (input) char* Specifies whether or not the matrix A is unit triangular. = 'N': Non-unit triangular = 'U': Unit triangular N (input) long The order of the matrix A. N >= 0. A (input/output) double array, dimension (LDA,N) On entry, the triangular matrix A. If UPLO = 'U', the leading n by n upper triangular part of the array A contains the upper triangular matrix, and the strictly lower triangular part of A is not referenced. If UPLO = 'L', the leading n by n lower triangular part of the array A contains the lower triangular matrix, and the strictly upper triangular part of A is not referenced. If DIAG = 'U', the diagonal elements of A are also not referenced and are assumed to be 1. On exit, the (triangular) inverse of the original matrix, in the same storage format. LDA (input) long The leading dimension of the array A. LDA >= max(1,N). INFO (output) long = 0: successful exit < 0: if INFO = -k, the k-th argument had an illegal value ===================================================================== */ int NUMlapack_dtrtri (const char *uplo, const char *diag, long *n, double * a, long *lda, long *info); /* Purpose ======= NUMlapack_dtrtri computes the inverse of a real upper or lower triangular matrix A. This is the Level 3 BLAS version of the algorithm. Arguments ========= UPLO (input) char* = 'U': A is upper triangular; = 'L': A is lower triangular. DIAG (input) char* = 'N': A is non-unit triangular; = 'U': A is unit triangular. N (input) long The order of the matrix A. N >= 0. A (input/output) double array, dimension (LDA,N) On entry, the triangular matrix A. If UPLO = 'U', the leading N-by-N upper triangular part of the array A contains the upper triangular matrix, and the strictly lower triangular part of A is not referenced. If UPLO = 'L', the leading N-by-N lower triangular part of the array A contains the lower triangular matrix, and the strictly upper triangular part of A is not referenced. If DIAG = 'U', the diagonal elements of A are also not referenced and are assumed to be 1. On exit, the (triangular) inverse of the original matrix, in the same storage format. LDA (input) long The leading dimension of the array A. LDA >= max(1,N). INFO (output) long = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value > 0: if INFO = i, A(i,i) is exactly zero. The triangular matrix is singular and its inverse can not be computed. ===================================================================== */ long NUMlapack_ieeeck (long *ispec, float *zero, float *one); /* Purpose ======= NUMlapack_ieeeck is called from the NUMlapack_ilaenv to verify that Infinity and possibly NaN arithmetic is safe (i.e. will not trap). Arguments ========= ISPEC (input) long Specifies whether to test just for inifinity arithmetic or whether to test for infinity and NaN arithmetic. = 0: Verify infinity arithmetic only. = 1: Verify infinity and NaN arithmetic. ZERO (input) REAL Must contain the value 0.0 This is passed to prevent the compiler from optimizing away this code. ONE (input) REAL Must contain the value 1.0 This is passed to prevent the compiler from optimizing away this code. RETURN VALUE: long = 0: Arithmetic failed to produce the correct answers = 1: Arithmetic produced the correct answers */ long NUMlapack_ilaenv (long *ispec, const char *name, const char *opts, long *n1, long *n2, long *n3, long *n4, long name_len, long opts_len); /* Purpose ======= NUMlapack_ilaenv is called from the LAPACK routines to choose problem-dependent parameters for the local environment. See ISPEC for a description of the parameters. This version provides a set of parameters which should give good, but not optimal, performance on many of the currently available computers. Users are encouraged to modify this subroutine to set the tuning parameters for their particular machine using the option and problem size information in the arguments. This routine will not function correctly if it is converted to all lower case. Converting it to all upper case is allowed. Arguments ========= ISPEC (input) long Specifies the parameter to be returned as the value of NUMlapack_ilaenv. = 1: the optimal blocksize; if this value is 1, an unblocked algorithm will give the best performance. = 2: the minimum block size for which the block routine should be used; if the usable block size is less than this value, an unblocked routine should be used. = 3: the crossover point (in a block routine, for N less than this value, an unblocked routine should be used) = 4: the number of shifts, used in the nonsymmetric eigenvalue routines = 5: the minimum column dimension for blocking to be used; rectangular blocks must have dimension at least k by m, where k is given by NUMlapack_ilaenv(2,...) and m by NUMlapack_ilaenv(5,...) = 6: the crossover point for the SVD (when reducing an m by n matrix to bidiagonal form, if max(m,n)/min(m,n) exceeds this value, a QR factorization is used first to reduce the matrix to a triangular form.) = 7: the number of processors = 8: the crossover point for the multishift QR and QZ methods for nonsymmetric eigenvalue problems. = 9: maximum size of the subproblems at the bottom of the computation tree in the divide-and-conquer algorithm (used by xGELSD and xGESDD) =10: ieee NaN arithmetic can be trusted not to trap =11: infinity arithmetic can be trusted not to trap NAME (input) CHARACTER*(*) The name of the calling subroutine, in either upper case or lower case. OPTS (input) CHARACTER*(*) The character options to the subroutine NAME, concatenated into a single character string. For example, UPLO = 'U', TRANS = 'T', and DIAG = 'N' for a triangular routine would be specified as OPTS = 'UTN'. N1 (input) long N2 (input) long N3 (input) long N4 (input) long Problem dimensions for the subroutine NAME; these may not all be required. (NUMlapack_ilaenv) (output) long >= 0: the value of the parameter specified by ISPEC < 0: if NUMlapack_ilaenv = -k, the k-th argument had an illegal value. Further Details =============== The following conventions have been used when calling NUMlapack_ilaenv from the LAPACK routines: 1) OPTS is a concatenation of all of the character options to subroutine NAME, in the same order that they appear in the argument list for NAME, even if they are not used in determining the value of the parameter specified by ISPEC. 2) The problem dimensions N1, N2, N3, N4 are specified in the order that they appear in the argument list for NAME. N1 is used first, N2 second, and so on, and unused problem dimensions are passed a value of -1. 3) The parameter value returned by NUMlapack_ilaenv is checked for validity in the calling subroutine. For example, NUMlapack_ilaenv is used to retrieve the optimal blocksize for STRTRI as follows: NB = NUMlapack_ilaenv( 1, 'STRTRI', UPLO // DIAG, N, -1, -1, -1 ) IF( NB.LE.1 ) NB = MAX( 1, N ) ===================================================================== */ #endif /* _NUMclapack_h_ */ praat-6.0.04/dwsys/NUMf2c.cpp000066400000000000000000000052131261542461700156300ustar00rootroot00000000000000/* NUMf2c.c */ #include #include "NUMf2c.h" #include "melder.h" double d_sign (double *a, double *b) { double x; x = (*a >= 0.0 ? *a : - *a); return (*b >= 0.0 ? x : -x); } long int lsame_ (const char *ca, const char *cb) { int a = * (unsigned char *) ca; int b = * (unsigned char *) cb; return tolower (a) == tolower (b); } double pow_di (double *ap, long *bp) { double pow, x; long n; unsigned long u; pow = 1; x = *ap; n = *bp; if (n != 0) { if (n < 0) { n = -n; x = 1.0 / x; } for (u = n; ;) { if (u & 01) { pow *= x; } if (u >>= 1) { x *= x; } else { break; } } } return (pow); } void s_cat (char *lp, const char *rpp[], long rnp[], long *np, long ll) { long i, nc; char *rp; long n = *np; #ifndef NO_OVERWRITE long L, m; char *lp0, *lp1; lp0 = 0; lp1 = lp; L = ll; i = 0; while (i < n) { rp = (char *) rpp[i]; m = rnp[i++]; if (rp >= lp1 || rp + m <= lp) { if ( (L -= m) <= 0) { n = i; break; } lp1 += m; continue; } lp0 = lp; lp = lp1 = Melder_malloc_f (char, L = ll); break; } lp1 = lp; #endif /* NO_OVERWRITE */ for (i = 0 ; i < n ; ++i) { nc = ll; if (rnp[i] < nc) { nc = rnp[i]; } ll -= nc; rp = (char *) rpp[i]; while (--nc >= 0) { *lp++ = *rp++; } } while (--ll >= 0) { *lp++ = ' '; } #ifndef NO_OVERWRITE if (lp0) { memcpy (lp0, lp1, L); free (lp1); } #endif } /* compare two strings */ long s_cmp (const char *a0, const char *b0, long la, long lb) { register unsigned char *a, *aend, *b, *bend; a = (unsigned char *) a0; b = (unsigned char *) b0; aend = a + la; bend = b + lb; if (la <= lb) { while (a < aend) if (*a != *b) { return (*a - *b); } else { ++a; ++b; } while (b < bend) if (*b != ' ') { return (' ' - *b); } else { ++b; } } else { while (b < bend) if (*a == *b) { ++a; ++b; } else { return (*a - *b); } while (a < aend) if (*a != ' ') { return (*a - ' '); } else { ++a; } } return (0); } void s_copy (register char *a, register char *b, long la, long lb) { register char *aend, *bend; aend = a + la; if (la <= lb) #ifndef NO_OVERWRITE if (a <= b || a >= b + la) #endif while (a < aend) { *a++ = *b++; } #ifndef NO_OVERWRITE else for (b += la; a < aend;) { *--aend = *--b; } #endif else { bend = b + lb; #ifndef NO_OVERWRITE if (a <= b || a >= bend) #endif while (b < bend) { *a++ = *b++; } #ifndef NO_OVERWRITE else { a += lb; while (b < bend) { *--a = *--bend; } a += lb; } #endif while (a < aend) { *a++ = ' '; } } } /* End of file NUMf2c.c */ praat-6.0.04/dwsys/NUMf2c.h000066400000000000000000000032371261542461700153010ustar00rootroot00000000000000#ifndef _NUMf2c_h_ #define _NUMf2c_h_ /* NUMf2c.h -- Standard Fortran to C header file * Auxiliary f2c routines. * * Copyright (C) 1994-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020923 GPL header djmw 20110308 Latest modification */ double d_sign(double *a, double *b); /* returns sign(b)*fabs(a) */ long int lsame_(const char *ca, const char *cb); /* Returns true if ca[0] is the same letter as cb[0] regardless of case. */ double pow_di(double *ap, long *bp); void s_cat(char *lp, const char *rpp[], long rnp[], long *np, long ll); /* Unless compiled with -DNO_OVERWRITE, this variant of s_cat allows the * target of a concatenation to appear on its right-hand side (contrary * to the Fortran 77 Standard, but in accordance with Fortran 90). */ long s_cmp(const char *a0, const char *b0, long la, long lb); void s_copy(register char *a, register char *b, long la, long lb); /* assign strings: a = b (when no null byte at end of string)*/ #endif /* _NUMf2c_h_ */ praat-6.0.04/dwsys/NUMfft_core.h000066400000000000000000000577441261542461700164320ustar00rootroot00000000000000/******************************************************************** * * * THIS FILE IS PART OF THE OggSQUISH SOFTWARE CODEC SOURCE CODE. * * * ******************************************************************** function: Fast discrete Fourier and cosine transforms and inverses author: Monty modifications by: Monty last modification date: Jul 1 1996 djmw 20030630 Adapted for praat (replaced 'int' declarations with 'long'). djmw 20040511 Made all local variables type double to increase numerical precision. ********************************************************************/ /* These Fourier routines were originally based on the Fourier routines of the same names from the NETLIB bihar and fftpack fortran libraries developed by Paul N. Swarztrauber at the National Center for Atmospheric Research in Boulder, CO USA. They have been reimplemented in C and optimized in a few ways for OggSquish. */ /* As the original fortran libraries are public domain, the C Fourier routines in this file are hereby released to the public domain as well. The C routines here produce output exactly equivalent to the original fortran routines. Of particular interest are the facts that (like the original fortran), these routines can work on arbitrary length vectors that need not be powers of two in length. */ static void drfti1 (long n, FFT_DATA_TYPE * wa, long *ifac) { static long ntryh[4] = { 4, 2, 3, 5 }; static double tpi = 6.28318530717958647692528676655900577; double arg, argh, argld, fi; long ntry = 0, i, j = -1; long k1, l1, l2, ib; long ld, ii, ip, is, nq, nr; long ido, ipm, nfm1; long nl = n; long nf = 0; L101: j++; if (j < 4) ntry = ntryh[j]; else ntry += 2; L104: nq = nl / ntry; nr = nl - ntry * nq; if (nr != 0) goto L101; nf++; ifac[nf + 1] = ntry; nl = nq; if (ntry != 2) goto L107; if (nf == 1) goto L107; for (i = 1; i < nf; i++) { ib = nf - i + 1; ifac[ib + 1] = ifac[ib]; } ifac[2] = 2; L107: if (nl != 1) goto L104; ifac[0] = n; ifac[1] = nf; argh = tpi / n; is = 0; nfm1 = nf - 1; l1 = 1; if (nfm1 == 0) return; for (k1 = 0; k1 < nfm1; k1++) { ip = ifac[k1 + 2]; ld = 0; l2 = l1 * ip; ido = n / l2; ipm = ip - 1; for (j = 0; j < ipm; j++) { ld += l1; i = is; argld = (double) ld *argh; fi = 0.; for (ii = 2; ii < ido; ii += 2) { fi += 1.; arg = fi * argld; wa[i++] = cos (arg); wa[i++] = sin (arg); } is += ido; } l1 = l2; } } static void NUMrffti (long n, FFT_DATA_TYPE * wsave, long *ifac) { if (n == 1) return; drfti1 (n, wsave + n, ifac); } /* void NUMcosqi(long n, FFT_DATA_TYPE *wsave, long *ifac){ static double pih = 1.57079632679489661923132169163975; static long k; static double fk, dt; dt=pih/n; fk=0.; for(k=0;k> 1; ipp2 = ip; idp2 = ido; nbd = (ido - 1) >> 1; t0 = l1 * ido; t10 = ip * ido; if (ido == 1) goto L119; for (ik = 0; ik < idl1; ik++) ch2[ik] = c2[ik]; t1 = 0; for (j = 1; j < ip; j++) { t1 += t0; t2 = t1; for (k = 0; k < l1; k++) { ch[t2] = c1[t2]; t2 += ido; } } is = -ido; t1 = 0; if (nbd > l1) { for (j = 1; j < ip; j++) { t1 += t0; is += ido; t2 = -ido + t1; for (k = 0; k < l1; k++) { idij = is - 1; t2 += ido; t3 = t2; for (i = 2; i < ido; i += 2) { idij += 2; t3 += 2; ch[t3 - 1] = wa[idij - 1] * c1[t3 - 1] + wa[idij] * c1[t3]; ch[t3] = wa[idij - 1] * c1[t3] - wa[idij] * c1[t3 - 1]; } } } } else { for (j = 1; j < ip; j++) { is += ido; idij = is - 1; t1 += t0; t2 = t1; for (i = 2; i < ido; i += 2) { idij += 2; t2 += 2; t3 = t2; for (k = 0; k < l1; k++) { ch[t3 - 1] = wa[idij - 1] * c1[t3 - 1] + wa[idij] * c1[t3]; ch[t3] = wa[idij - 1] * c1[t3] - wa[idij] * c1[t3 - 1]; t3 += ido; } } } } t1 = 0; t2 = ipp2 * t0; if (nbd < l1) { for (j = 1; j < ipph; j++) { t1 += t0; t2 -= t0; t3 = t1; t4 = t2; for (i = 2; i < ido; i += 2) { t3 += 2; t4 += 2; t5 = t3 - ido; t6 = t4 - ido; for (k = 0; k < l1; k++) { t5 += ido; t6 += ido; c1[t5 - 1] = ch[t5 - 1] + ch[t6 - 1]; c1[t6 - 1] = ch[t5] - ch[t6]; c1[t5] = ch[t5] + ch[t6]; c1[t6] = ch[t6 - 1] - ch[t5 - 1]; } } } } else { for (j = 1; j < ipph; j++) { t1 += t0; t2 -= t0; t3 = t1; t4 = t2; for (k = 0; k < l1; k++) { t5 = t3; t6 = t4; for (i = 2; i < ido; i += 2) { t5 += 2; t6 += 2; c1[t5 - 1] = ch[t5 - 1] + ch[t6 - 1]; c1[t6 - 1] = ch[t5] - ch[t6]; c1[t5] = ch[t5] + ch[t6]; c1[t6] = ch[t6 - 1] - ch[t5 - 1]; } t3 += ido; t4 += ido; } } } L119: for (ik = 0; ik < idl1; ik++) c2[ik] = ch2[ik]; t1 = 0; t2 = ipp2 * idl1; for (j = 1; j < ipph; j++) { t1 += t0; t2 -= t0; t3 = t1 - ido; t4 = t2 - ido; for (k = 0; k < l1; k++) { t3 += ido; t4 += ido; c1[t3] = ch[t3] + ch[t4]; c1[t4] = ch[t4] - ch[t3]; } } ar1 = 1.; ai1 = 0.; t1 = 0; t2 = ipp2 * idl1; t3 = (ip - 1) * idl1; for (l = 1; l < ipph; l++) { t1 += idl1; t2 -= idl1; ar1h = dcp * ar1 - dsp * ai1; ai1 = dcp * ai1 + dsp * ar1; ar1 = ar1h; t4 = t1; t5 = t2; t6 = t3; t7 = idl1; for (ik = 0; ik < idl1; ik++) { ch2[t4++] = c2[ik] + ar1 * c2[t7++]; ch2[t5++] = ai1 * c2[t6++]; } dc2 = ar1; ds2 = ai1; ar2 = ar1; ai2 = ai1; t4 = idl1; t5 = (ipp2 - 1) * idl1; for (j = 2; j < ipph; j++) { t4 += idl1; t5 -= idl1; ar2h = dc2 * ar2 - ds2 * ai2; ai2 = dc2 * ai2 + ds2 * ar2; ar2 = ar2h; t6 = t1; t7 = t2; t8 = t4; t9 = t5; for (ik = 0; ik < idl1; ik++) { ch2[t6++] += ar2 * c2[t8++]; ch2[t7++] += ai2 * c2[t9++]; } } } t1 = 0; for (j = 1; j < ipph; j++) { t1 += idl1; t2 = t1; for (ik = 0; ik < idl1; ik++) ch2[ik] += c2[t2++]; } if (ido < l1) goto L132; t1 = 0; t2 = 0; for (k = 0; k < l1; k++) { t3 = t1; t4 = t2; for (i = 0; i < ido; i++) cc[t4++] = ch[t3++]; t1 += ido; t2 += t10; } goto L135; L132: for (i = 0; i < ido; i++) { t1 = i; t2 = i; for (k = 0; k < l1; k++) { cc[t2] = ch[t1]; t1 += ido; t2 += t10; } } L135: t1 = 0; t2 = ido << 1; t3 = 0; t4 = ipp2 * t0; for (j = 1; j < ipph; j++) { t1 += t2; t3 += t0; t4 -= t0; t5 = t1; t6 = t3; t7 = t4; for (k = 0; k < l1; k++) { cc[t5 - 1] = ch[t6]; cc[t5] = ch[t7]; t5 += t10; t6 += ido; t7 += ido; } } if (ido == 1) return; if (nbd < l1) goto L141; t1 = -ido; t3 = 0; t4 = 0; t5 = ipp2 * t0; for (j = 1; j < ipph; j++) { t1 += t2; t3 += t2; t4 += t0; t5 -= t0; t6 = t1; t7 = t3; t8 = t4; t9 = t5; for (k = 0; k < l1; k++) { for (i = 2; i < ido; i += 2) { ic = idp2 - i; cc[i + t7 - 1] = ch[i + t8 - 1] + ch[i + t9 - 1]; cc[ic + t6 - 1] = ch[i + t8 - 1] - ch[i + t9 - 1]; cc[i + t7] = ch[i + t8] + ch[i + t9]; cc[ic + t6] = ch[i + t9] - ch[i + t8]; } t6 += t10; t7 += t10; t8 += ido; t9 += ido; } } return; L141: t1 = -ido; t3 = 0; t4 = 0; t5 = ipp2 * t0; for (j = 1; j < ipph; j++) { t1 += t2; t3 += t2; t4 += t0; t5 -= t0; for (i = 2; i < ido; i += 2) { t6 = idp2 + t1 - i; t7 = i + t3; t8 = i + t4; t9 = i + t5; for (k = 0; k < l1; k++) { cc[t7 - 1] = ch[t8 - 1] + ch[t9 - 1]; cc[t6 - 1] = ch[t8 - 1] - ch[t9 - 1]; cc[t7] = ch[t8] + ch[t9]; cc[t6] = ch[t9] - ch[t8]; t6 += t10; t7 += t10; t8 += ido; t9 += ido; } } } } static void drftf1 (long n, FFT_DATA_TYPE * c, FFT_DATA_TYPE * ch, FFT_DATA_TYPE * wa, long *ifac) { long i, k1, l1, l2; long na, kh, nf; long ip, iw, ido, idl1, ix2, ix3; nf = ifac[1]; na = 1; l2 = n; iw = n; for (k1 = 0; k1 < nf; k1++) { kh = nf - k1; ip = ifac[kh + 1]; l1 = l2 / ip; ido = n / l2; idl1 = ido * l1; iw -= (ip - 1) * ido; na = 1 - na; if (ip != 4) goto L102; ix2 = iw + ido; ix3 = ix2 + ido; if (na != 0) dradf4 (ido, l1, ch, c, wa + iw - 1, wa + ix2 - 1, wa + ix3 - 1); else dradf4 (ido, l1, c, ch, wa + iw - 1, wa + ix2 - 1, wa + ix3 - 1); goto L110; L102: if (ip != 2) goto L104; if (na != 0) goto L103; dradf2 (ido, l1, c, ch, wa + iw - 1); goto L110; L103: dradf2 (ido, l1, ch, c, wa + iw - 1); goto L110; L104: if (ido == 1) na = 1 - na; if (na != 0) goto L109; dradfg (ido, ip, l1, idl1, c, c, c, ch, ch, wa + iw - 1); na = 1; goto L110; L109: dradfg (ido, ip, l1, idl1, ch, ch, ch, c, c, wa + iw - 1); na = 0; L110: l2 = l1; } if (na == 1) return; for (i = 0; i < n; i++) c[i] = ch[i]; } static void dradb2 (long ido, long l1, FFT_DATA_TYPE * cc, FFT_DATA_TYPE * ch, FFT_DATA_TYPE * wa1) { long i, k, t0, t1, t2, t3, t4, t5, t6; double ti2, tr2; t0 = l1 * ido; t1 = 0; t2 = 0; t3 = (ido << 1) - 1; for (k = 0; k < l1; k++) { ch[t1] = cc[t2] + cc[t3 + t2]; ch[t1 + t0] = cc[t2] - cc[t3 + t2]; t2 = (t1 += ido) << 1; } if (ido < 2) return; if (ido == 2) goto L105; t1 = 0; t2 = 0; for (k = 0; k < l1; k++) { t3 = t1; t5 = (t4 = t2) + (ido << 1); t6 = t0 + t1; for (i = 2; i < ido; i += 2) { t3 += 2; t4 += 2; t5 -= 2; t6 += 2; ch[t3 - 1] = cc[t4 - 1] + cc[t5 - 1]; tr2 = cc[t4 - 1] - cc[t5 - 1]; ch[t3] = cc[t4] - cc[t5]; ti2 = cc[t4] + cc[t5]; ch[t6 - 1] = wa1[i - 2] * tr2 - wa1[i - 1] * ti2; ch[t6] = wa1[i - 2] * ti2 + wa1[i - 1] * tr2; } t2 = (t1 += ido) << 1; } if (ido % 2 == 1) return; L105: t1 = ido - 1; t2 = ido - 1; for (k = 0; k < l1; k++) { ch[t1] = cc[t2] + cc[t2]; ch[t1 + t0] = -(cc[t2 + 1] + cc[t2 + 1]); t1 += ido; t2 += ido << 1; } } static void dradb3 (long ido, long l1, FFT_DATA_TYPE * cc, FFT_DATA_TYPE * ch, FFT_DATA_TYPE * wa1, FFT_DATA_TYPE * wa2) { static double taur = -.5; static double taui = .86602540378443864676372317075293618; long i, k, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10; double ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2; t0 = l1 * ido; t1 = 0; t2 = t0 << 1; t3 = ido << 1; t4 = ido + (ido << 1); t5 = 0; for (k = 0; k < l1; k++) { tr2 = cc[t3 - 1] + cc[t3 - 1]; cr2 = cc[t5] + (taur * tr2); ch[t1] = cc[t5] + tr2; ci3 = taui * (cc[t3] + cc[t3]); ch[t1 + t0] = cr2 - ci3; ch[t1 + t2] = cr2 + ci3; t1 += ido; t3 += t4; t5 += t4; } if (ido == 1) return; t1 = 0; t3 = ido << 1; for (k = 0; k < l1; k++) { t7 = t1 + (t1 << 1); t6 = (t5 = t7 + t3); t8 = t1; t10 = (t9 = t1 + t0) + t0; for (i = 2; i < ido; i += 2) { t5 += 2; t6 -= 2; t7 += 2; t8 += 2; t9 += 2; t10 += 2; tr2 = cc[t5 - 1] + cc[t6 - 1]; cr2 = cc[t7 - 1] + (taur * tr2); ch[t8 - 1] = cc[t7 - 1] + tr2; ti2 = cc[t5] - cc[t6]; ci2 = cc[t7] + (taur * ti2); ch[t8] = cc[t7] + ti2; cr3 = taui * (cc[t5 - 1] - cc[t6 - 1]); ci3 = taui * (cc[t5] + cc[t6]); dr2 = cr2 - ci3; dr3 = cr2 + ci3; di2 = ci2 + cr3; di3 = ci2 - cr3; ch[t9 - 1] = wa1[i - 2] * dr2 - wa1[i - 1] * di2; ch[t9] = wa1[i - 2] * di2 + wa1[i - 1] * dr2; ch[t10 - 1] = wa2[i - 2] * dr3 - wa2[i - 1] * di3; ch[t10] = wa2[i - 2] * di3 + wa2[i - 1] * dr3; } t1 += ido; } } static void dradb4 (long ido, long l1, FFT_DATA_TYPE * cc, FFT_DATA_TYPE * ch, FFT_DATA_TYPE * wa1, FFT_DATA_TYPE * wa2, FFT_DATA_TYPE * wa3) { static double sqrt2 = 1.4142135623730950488016887242097; long i, k, t0, t1, t2, t3, t4, t5, t6, t7, t8; double ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4; t0 = l1 * ido; t1 = 0; t2 = ido << 2; t3 = 0; t6 = ido << 1; for (k = 0; k < l1; k++) { t4 = t3 + t6; t5 = t1; tr3 = cc[t4 - 1] + cc[t4 - 1]; tr4 = cc[t4] + cc[t4]; tr1 = cc[t3] - cc[(t4 += t6) - 1]; tr2 = cc[t3] + cc[t4 - 1]; ch[t5] = tr2 + tr3; ch[t5 += t0] = tr1 - tr4; ch[t5 += t0] = tr2 - tr3; ch[t5 += t0] = tr1 + tr4; t1 += ido; t3 += t2; } if (ido < 2) return; if (ido == 2) goto L105; t1 = 0; for (k = 0; k < l1; k++) { t5 = (t4 = (t3 = (t2 = t1 << 2) + t6)) + t6; t7 = t1; for (i = 2; i < ido; i += 2) { t2 += 2; t3 += 2; t4 -= 2; t5 -= 2; t7 += 2; ti1 = cc[t2] + cc[t5]; ti2 = cc[t2] - cc[t5]; ti3 = cc[t3] - cc[t4]; tr4 = cc[t3] + cc[t4]; tr1 = cc[t2 - 1] - cc[t5 - 1]; tr2 = cc[t2 - 1] + cc[t5 - 1]; ti4 = cc[t3 - 1] - cc[t4 - 1]; tr3 = cc[t3 - 1] + cc[t4 - 1]; ch[t7 - 1] = tr2 + tr3; cr3 = tr2 - tr3; ch[t7] = ti2 + ti3; ci3 = ti2 - ti3; cr2 = tr1 - tr4; cr4 = tr1 + tr4; ci2 = ti1 + ti4; ci4 = ti1 - ti4; ch[(t8 = t7 + t0) - 1] = wa1[i - 2] * cr2 - wa1[i - 1] * ci2; ch[t8] = wa1[i - 2] * ci2 + wa1[i - 1] * cr2; ch[(t8 += t0) - 1] = wa2[i - 2] * cr3 - wa2[i - 1] * ci3; ch[t8] = wa2[i - 2] * ci3 + wa2[i - 1] * cr3; ch[(t8 += t0) - 1] = wa3[i - 2] * cr4 - wa3[i - 1] * ci4; ch[t8] = wa3[i - 2] * ci4 + wa3[i - 1] * cr4; } t1 += ido; } if (ido % 2 == 1) return; L105: t1 = ido; t2 = ido << 2; t3 = ido - 1; t4 = ido + (ido << 1); for (k = 0; k < l1; k++) { t5 = t3; ti1 = cc[t1] + cc[t4]; ti2 = cc[t4] - cc[t1]; tr1 = cc[t1 - 1] - cc[t4 - 1]; tr2 = cc[t1 - 1] + cc[t4 - 1]; ch[t5] = tr2 + tr2; ch[t5 += t0] = sqrt2 * (tr1 - ti1); ch[t5 += t0] = ti2 + ti2; ch[t5 += t0] = -sqrt2 * (tr1 + ti1); t3 += ido; t1 += t2; t4 += t2; } } static void dradbg (long ido, long ip, long l1, long idl1, FFT_DATA_TYPE * cc, FFT_DATA_TYPE * c1, FFT_DATA_TYPE * c2, FFT_DATA_TYPE * ch, FFT_DATA_TYPE * ch2, FFT_DATA_TYPE * wa) { static double tpi = 6.28318530717958647692528676655900577; long idij, ipph, i, j, k, l, ik, is, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12; double dc2, ai1, ai2, ar1, ar2, ds2; long nbd; double dcp, arg, dsp, ar1h, ar2h; long ipp2; t10 = ip * ido; t0 = l1 * ido; arg = tpi / (double) ip; dcp = cos (arg); dsp = sin (arg); nbd = (ido - 1) >> 1; ipp2 = ip; ipph = (ip + 1) >> 1; if (ido < l1) goto L103; t1 = 0; t2 = 0; for (k = 0; k < l1; k++) { t3 = t1; t4 = t2; for (i = 0; i < ido; i++) { ch[t3] = cc[t4]; t3++; t4++; } t1 += ido; t2 += t10; } goto L106; L103: t1 = 0; for (i = 0; i < ido; i++) { t2 = t1; t3 = t1; for (k = 0; k < l1; k++) { ch[t2] = cc[t3]; t2 += ido; t3 += t10; } t1++; } L106: t1 = 0; t2 = ipp2 * t0; t7 = (t5 = ido << 1); for (j = 1; j < ipph; j++) { t1 += t0; t2 -= t0; t3 = t1; t4 = t2; t6 = t5; for (k = 0; k < l1; k++) { ch[t3] = cc[t6 - 1] + cc[t6 - 1]; ch[t4] = cc[t6] + cc[t6]; t3 += ido; t4 += ido; t6 += t10; } t5 += t7; } if (ido == 1) goto L116; if (nbd < l1) goto L112; t1 = 0; t2 = ipp2 * t0; t7 = 0; for (j = 1; j < ipph; j++) { t1 += t0; t2 -= t0; t3 = t1; t4 = t2; t7 += (ido << 1); t8 = t7; for (k = 0; k < l1; k++) { t5 = t3; t6 = t4; t9 = t8; t11 = t8; for (i = 2; i < ido; i += 2) { t5 += 2; t6 += 2; t9 += 2; t11 -= 2; ch[t5 - 1] = cc[t9 - 1] + cc[t11 - 1]; ch[t6 - 1] = cc[t9 - 1] - cc[t11 - 1]; ch[t5] = cc[t9] - cc[t11]; ch[t6] = cc[t9] + cc[t11]; } t3 += ido; t4 += ido; t8 += t10; } } goto L116; L112: t1 = 0; t2 = ipp2 * t0; t7 = 0; for (j = 1; j < ipph; j++) { t1 += t0; t2 -= t0; t3 = t1; t4 = t2; t7 += (ido << 1); t8 = t7; t9 = t7; for (i = 2; i < ido; i += 2) { t3 += 2; t4 += 2; t8 += 2; t9 -= 2; t5 = t3; t6 = t4; t11 = t8; t12 = t9; for (k = 0; k < l1; k++) { ch[t5 - 1] = cc[t11 - 1] + cc[t12 - 1]; ch[t6 - 1] = cc[t11 - 1] - cc[t12 - 1]; ch[t5] = cc[t11] - cc[t12]; ch[t6] = cc[t11] + cc[t12]; t5 += ido; t6 += ido; t11 += t10; t12 += t10; } } } L116: ar1 = 1.; ai1 = 0.; t1 = 0; t9 = (t2 = ipp2 * idl1); t3 = (ip - 1) * idl1; for (l = 1; l < ipph; l++) { t1 += idl1; t2 -= idl1; ar1h = dcp * ar1 - dsp * ai1; ai1 = dcp * ai1 + dsp * ar1; ar1 = ar1h; t4 = t1; t5 = t2; t6 = 0; t7 = idl1; t8 = t3; for (ik = 0; ik < idl1; ik++) { c2[t4++] = ch2[t6++] + ar1 * ch2[t7++]; c2[t5++] = ai1 * ch2[t8++]; } dc2 = ar1; ds2 = ai1; ar2 = ar1; ai2 = ai1; t6 = idl1; t7 = t9 - idl1; for (j = 2; j < ipph; j++) { t6 += idl1; t7 -= idl1; ar2h = dc2 * ar2 - ds2 * ai2; ai2 = dc2 * ai2 + ds2 * ar2; ar2 = ar2h; t4 = t1; t5 = t2; t11 = t6; t12 = t7; for (ik = 0; ik < idl1; ik++) { c2[t4++] += ar2 * ch2[t11++]; c2[t5++] += ai2 * ch2[t12++]; } } } t1 = 0; for (j = 1; j < ipph; j++) { t1 += idl1; t2 = t1; for (ik = 0; ik < idl1; ik++) ch2[ik] += ch2[t2++]; } t1 = 0; t2 = ipp2 * t0; for (j = 1; j < ipph; j++) { t1 += t0; t2 -= t0; t3 = t1; t4 = t2; for (k = 0; k < l1; k++) { ch[t3] = c1[t3] - c1[t4]; ch[t4] = c1[t3] + c1[t4]; t3 += ido; t4 += ido; } } if (ido == 1) goto L132; if (nbd < l1) goto L128; t1 = 0; t2 = ipp2 * t0; for (j = 1; j < ipph; j++) { t1 += t0; t2 -= t0; t3 = t1; t4 = t2; for (k = 0; k < l1; k++) { t5 = t3; t6 = t4; for (i = 2; i < ido; i += 2) { t5 += 2; t6 += 2; ch[t5 - 1] = c1[t5 - 1] - c1[t6]; ch[t6 - 1] = c1[t5 - 1] + c1[t6]; ch[t5] = c1[t5] + c1[t6 - 1]; ch[t6] = c1[t5] - c1[t6 - 1]; } t3 += ido; t4 += ido; } } goto L132; L128: t1 = 0; t2 = ipp2 * t0; for (j = 1; j < ipph; j++) { t1 += t0; t2 -= t0; t3 = t1; t4 = t2; for (i = 2; i < ido; i += 2) { t3 += 2; t4 += 2; t5 = t3; t6 = t4; for (k = 0; k < l1; k++) { ch[t5 - 1] = c1[t5 - 1] - c1[t6]; ch[t6 - 1] = c1[t5 - 1] + c1[t6]; ch[t5] = c1[t5] + c1[t6 - 1]; ch[t6] = c1[t5] - c1[t6 - 1]; t5 += ido; t6 += ido; } } } L132: if (ido == 1) return; for (ik = 0; ik < idl1; ik++) c2[ik] = ch2[ik]; t1 = 0; for (j = 1; j < ip; j++) { t2 = (t1 += t0); for (k = 0; k < l1; k++) { c1[t2] = ch[t2]; t2 += ido; } } if (nbd > l1) goto L139; is = -ido - 1; t1 = 0; for (j = 1; j < ip; j++) { is += ido; t1 += t0; idij = is; t2 = t1; for (i = 2; i < ido; i += 2) { t2 += 2; idij += 2; t3 = t2; for (k = 0; k < l1; k++) { c1[t3 - 1] = wa[idij - 1] * ch[t3 - 1] - wa[idij] * ch[t3]; c1[t3] = wa[idij - 1] * ch[t3] + wa[idij] * ch[t3 - 1]; t3 += ido; } } } return; L139: is = -ido - 1; t1 = 0; for (j = 1; j < ip; j++) { is += ido; t1 += t0; t2 = t1; for (k = 0; k < l1; k++) { idij = is; t3 = t2; for (i = 2; i < ido; i += 2) { idij += 2; t3 += 2; c1[t3 - 1] = wa[idij - 1] * ch[t3 - 1] - wa[idij] * ch[t3]; c1[t3] = wa[idij - 1] * ch[t3] + wa[idij] * ch[t3 - 1]; } t2 += ido; } } } static void drftb1 (long n, FFT_DATA_TYPE * c, FFT_DATA_TYPE * ch, FFT_DATA_TYPE * wa, long *ifac) { long i, k1, l1, l2; long na; long nf, ip, iw, ix2, ix3, ido, idl1; nf = ifac[1]; na = 0; l1 = 1; iw = 1; for (k1 = 0; k1 < nf; k1++) { ip = ifac[k1 + 2]; l2 = ip * l1; ido = n / l2; idl1 = ido * l1; if (ip != 4) goto L103; ix2 = iw + ido; ix3 = ix2 + ido; if (na != 0) dradb4 (ido, l1, ch, c, wa + iw - 1, wa + ix2 - 1, wa + ix3 - 1); else dradb4 (ido, l1, c, ch, wa + iw - 1, wa + ix2 - 1, wa + ix3 - 1); na = 1 - na; goto L115; L103: if (ip != 2) goto L106; if (na != 0) dradb2 (ido, l1, ch, c, wa + iw - 1); else dradb2 (ido, l1, c, ch, wa + iw - 1); na = 1 - na; goto L115; L106: if (ip != 3) goto L109; ix2 = iw + ido; if (na != 0) dradb3 (ido, l1, ch, c, wa + iw - 1, wa + ix2 - 1); else dradb3 (ido, l1, c, ch, wa + iw - 1, wa + ix2 - 1); na = 1 - na; goto L115; L109: /* The radix five case can be translated later..... */ /* if(ip!=5)goto L112; ix2=iw+ido; ix3=ix2+ido; ix4=ix3+ido; if(na!=0) dradb5(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1,wa+ix4-1); else dradb5(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1,wa+ix4-1); na=1-na; goto L115; L112: */ if (na != 0) dradbg (ido, ip, l1, idl1, ch, ch, ch, c, c, wa + iw - 1); else dradbg (ido, ip, l1, idl1, c, c, c, ch, ch, wa + iw - 1); if (ido == 1) na = 1 - na; L115: l1 = l2; iw += (ip - 1) * ido; } if (na == 0) return; for (i = 0; i < n; i++) c[i] = ch[i]; } /* End of file NUMfft_core.h */ praat-6.0.04/dwsys/NUMfft_d.cpp000066400000000000000000000045061261542461700162440ustar00rootroot00000000000000/* NUMfft_d.c * * Copyright (C) 1997-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header djmw 20040511 Added n>1 test for compatibility with old behaviour. djmw 20110308 struct renaming */ #include "NUM2.h" #include "melder.h" #define my me -> #define FFT_DATA_TYPE double #include "NUMfft_core.h" void NUMforwardRealFastFourierTransform (double *data, long n) { autoNUMfft_Table table; NUMfft_Table_init (& table, n); NUMfft_forward (& table, data); if (n > 1) { // To be compatible with old behaviour double tmp = data[n]; for (long i = n; i > 2; i--) { data[i] = data[i - 1]; } data[2] = tmp; } } void NUMreverseRealFastFourierTransform (double *data, long n) { autoNUMfft_Table table; if (n > 1) { // To be compatible with old behaviour double tmp = data[2]; for (long i = 2; i < n; i++) { data[i] = data[i + 1]; } data[n] = tmp; } NUMfft_Table_init (& table, n); NUMfft_backward (& table, data); } void NUMfft_forward (NUMfft_Table me, double *data) { if (my n == 1) { return; } drftf1 (my n, &data[1], my trigcache, my trigcache + my n, my splitcache); } void NUMfft_backward (NUMfft_Table me, double *data) { if (my n == 1) { return; } drftb1 (my n, &data[1], my trigcache, my trigcache + my n, my splitcache); } void NUMfft_Table_init (NUMfft_Table me, long n) { my n = n; my trigcache = NUMvector (0, 3 * n - 1); my splitcache = NUMvector (0, 31); NUMrffti (n, my trigcache, my splitcache); } void NUMrealft (double *data, long n, int isign) { isign == 1 ? NUMforwardRealFastFourierTransform (data, n) : NUMreverseRealFastFourierTransform (data, n); } /* End of file NUMfft.c */ praat-6.0.04/dwsys/NUMfft_f.cpp000066400000000000000000000051401261542461700162410ustar00rootroot00000000000000/* NUMfft_f.c * * Copyright (C) 1997-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020701 GPL header djmw 20040511 Added n>1 test for compatibility with old behaviour. */ #include "NUM2.h" #include "melder.h" #define my me -> #define FFT_DATA_TYPE float #include "NUMfft_core.h" void NUMforwardRealFastFourierTransform_f (float *data, long n) { struct NUMfft_Table_f table_struct; NUMfft_Table_f table = &table_struct; NUMfft_Table_init_f (table, n); NUMfft_forward_f (table, data); if (n > 1) { // To be compatible with old behaviour float tmp = data[n]; for (long i = n; i > 2; i--) { data[i] = data[i - 1]; } data[2] = tmp; } NUMfft_Table_free_f (table); } void NUMreverseRealFastFourierTransform_f (float *data, long n) { struct NUMfft_Table_f table_struct; NUMfft_Table_f table = &table_struct; if (n > 1) { // To be compatible with old behaviour float tmp = data[2]; for (long i = 2; i < n; i++) { data[i] = data[i + 1]; } data[n] = tmp; } NUMfft_Table_init_f (table, n); NUMfft_backward_f (table, data); NUMfft_Table_free_f (table); } void NUMfft_forward_f (NUMfft_Table_f me, float *data) { if (my n == 1) { return; } drftf1 (my n, &data[1], my trigcache, my trigcache + my n, my splitcache); } void NUMfft_backward_f (NUMfft_Table_f me, float *data) { if (my n == 1) { return; } drftb1 (my n, &data[1], my trigcache, my trigcache + my n, my splitcache); } void NUMfft_Table_init_f (NUMfft_Table_f me, long n) { my n = n; my trigcache = NUMvector (0, 3 * n - 1); my splitcache = NUMvector (0, 31); NUMrffti (n, my trigcache, my splitcache); } void NUMfft_Table_free_f (NUMfft_Table_f me) { if (me) { NUMvector_free (my trigcache, 0); NUMvector_free (my splitcache, 0); } } void NUMrealft_f (float *data, long n, int isign) { isign == 1 ? NUMforwardRealFastFourierTransform_f (data, n) : NUMreverseRealFastFourierTransform_f (data, n); } /* End of file NUMfft.cpp */ praat-6.0.04/dwsys/NUMhuber.cpp000066400000000000000000000056031261542461700162660ustar00rootroot00000000000000/* NUMhuber.cpp * * Copyright (C) 1994-2008, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20030814 First version djmw 20080122 float -> double */ #include "NUM2.h" void NUMmad (double *x, long n, double *location, int wantlocation, double *mad, double *work) { double *tmp = work; *mad = NUMundefined; if (n < 1) { Melder_throw (U"The dimension must be at least 1"); } if (n == 1) { *location = x[1]; return; } autoNUMvector atmp; if (! work) { atmp.reset (1, n); tmp = atmp.peek(); } for (long i = 1; i <= n; i++) { tmp[i] = x[i]; } if (wantlocation) { NUMsort_d (n, tmp); *location = NUMquantile (n, tmp, 0.5); } for (long i = 1; i <= n; i++) { tmp[i] = fabs (tmp[i] - *location); } NUMsort_d (n, tmp); *mad = 1.4826 * NUMquantile (n, tmp, 0.5); } static double NUMgauss (double x) { return NUM1_sqrt2pi * exp (- 0.5 * x * x); } void NUMstatistics_huber (double *x, long n, double *location, int wantlocation, double *scale, int wantscale, double k, double tol, double *work) { double *tmp = work; double theta = 2.0 * NUMgaussP (k) - 1.0; double beta = theta + k * k * (1.0 - theta) - 2.0 * k * NUMgauss (k); long n1 = n; autoNUMvector atmp; if (work == 0) { atmp.reset (1, n); tmp = atmp.peek(); } double mad; NUMmad (x, n, location, wantlocation, & mad, tmp); if (wantscale) { *scale = mad; } if (*scale == 0) { Melder_throw (U"Scale is zero."); } double mu0, mu1 = *location; double s0, s1 = *scale; if (wantlocation) { n1 = n - 1; } do { mu0 = mu1; s0 = s1; double low = mu0 - k * s0; double high = mu0 + k * s0; for (long i = 1; i <= n; i++) { if (x[i] < low) { tmp[i] = low; } else if (x[i] > high) { tmp[i] = high; } else { tmp[i] = x[i]; } } if (wantlocation) { mu1 = 0.0; for (long i = 1; i <= n; i++) { mu1 += tmp[i]; } mu1 /= n; } if (wantscale) { s1 = 0.0; for (long i = 1; i <= n; i++) { double dx = tmp[i] - mu1; s1 += dx * dx; } s1 = sqrt (s1 / (n1 * beta)); } } while (fabs (mu0 - mu1) > tol * s0 || fabs (s0 - s1) > tol * s0); //TODO fabs (mu0 - mu1) > tol * s0 ?? if (wantlocation) { *location = mu1; } if (wantscale) { *scale = s1; } } praat-6.0.04/dwsys/NUMlapack.cpp000066400000000000000000001103711261542461700164130ustar00rootroot00000000000000/* NUMlapack.cpp * * Copyright (C) 1994-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020812 GPL header djmw 20030205 Latest modification (NUMmacros) djmw 20071022 NUMmatricesToUpperTriangularForms now inializes l=0 */ #include "NUM.h" #include "NUMlapack.h" #include "NUMmachar.h" #include "melder.h" #define MAX(m,n) ((m) > (n) ? (m) : (n)) #define MIN(m,n) ((m) < (n) ? (m) : (n)) #define SIGN(x,s) ((s) < 0 ? -fabs (x) : fabs(x)) #define TOVEC(x) (&(x) - 1) void NUMidentity (double **a, long rb, long re, long cb) { for (long i = rb; i <= re; i++) { for (long j = cb; j <= cb + (re - rb); j++) { a[i][j] = 0; } a[i][i] = 1; } } double NUMpythagoras (double a, double b) { double absa = fabs (a), absb = fabs (b); double w = MAX (absa, absb); double z = MIN (absa, absb); if (z == 0) { return w; } double t = z / w; return w * sqrt (1 + t * t); } double NUMnorm2 (long n, double *x, long incx) { if (n < 1 || incx < 1) { return 0; } if (n == 1) { return fabs (x[1]); } double scale = 0, ssq = 1; for (long i = 1; i <= 1 + (n - 1) * incx; i += incx) { if (x[i] != 0) { double absxi = fabs (x[i]); if (scale < absxi) { double tmp = scale / absxi; ssq = 1 + ssq * tmp * tmp; scale = absxi; } else { double tmp = absxi / scale; ssq += tmp * tmp; } } } return scale * sqrt (ssq); } double NUMfrobeniusnorm (long m, long n, double **x) { if (n < 1 || m < 1) { return 0; } double scale = 0, ssq = 1; for (long i = 1; i <= m; i++) { for (long j = 1; j <= n; j++) { if (x[i][j] != 0) { double absxi = fabs (x[i][j]); if (scale < absxi) { double t = scale / absxi; ssq = 1 + ssq * t * t; scale = absxi; } else { double t = absxi / scale; ssq += t * t; } } } } return scale * sqrt (ssq); } double NUMdotproduct (long n, double x[], long incx, double y[], long incy) { long ix = 1, iy = 1; if (n <= 0) { return 0; } if (incx < 0) { ix = (-n + 1) * incx + 1; } if (incy < 0) { iy = (-n + 1) * incy + 1; } double dot = 0; for (long i = 1; i <= n; i++, ix += incx, iy += incy) { dot += x[ix] * y[iy]; } return dot; } void NUMdaxpy (long n, double da, double x[], long incx, double y[], long incy) { long ix = 1, iy = 1; if (n <= 0) { return; } if (incx < 0) { ix = (-n + 1) * incx + 1; } if (incy < 0) { iy = (-n + 1) * incy + 1; } for (long i = 1; i <= n; i++, ix += incx, iy += incy) { y[iy] += da * x[ix]; } } void NUMvector_scale (long n, double da, double dx[], long incx) { if (n < 1 || incx < 1) { return; } for (long i = 1; i <= n * incx; i += incx) { dx[i] *= da; } } void NUMcopyElements (long n, double x[], long incx, double y[], long incy) { if (n <= 0) { return; } if (incx == 1 && incy == 1) { for (long i = 1; i <= n; i++) { y[i] = x[i]; } } else { long ix = 1, iy = 1; if (incx < 0) { ix = (-n + 1) * incx + 1; } if (incy < 0) { iy = (-n + 1) * incy + 1; } for (long i = 1; i <= n; i++, ix += incx, iy += incy) { y[iy] = x[ix]; } } } void NUMplaneRotation (long n, double x[], long incx, double y[], long incy, double c, double s) { if (n < 1) { return; } if (incx == 1 && incy == 1) { for (long i = 1; i <= n; i++) { double xt = c * x[i] + s * y[i]; y[i] = c * y[i] - s * x[i]; x[i] = xt; } } else { long ix = 1, iy = 1; if (incx < 0) { ix = (-n + 1) * incx + 1; } if (incy < 0) { iy = (-n + 1) * incy + 1; } for (long i = 1; i <= n; i++, ix += incx, iy += incy) { double xt = c * x[ix] + s * y[iy]; y[iy] = c * y[iy] - s * x[ix]; x[ix] = xt; } } } void NUMpermuteColumns (int forward, long m, long n, double **x, long *perm) { if (n <= 1) { return; } for (long i = 1; i <= n; i++) { perm[i] = - perm[i]; } if (forward) { for (long i = 1; i <= n; i++) { if (perm[i] > 0) { continue; } long j = i; perm[j] = -perm[j]; long in = perm[j]; for (;;) { if (perm[in] > 0) { break; } for (long ii = 1; ii <= m; ii++) { double tmp = x[ii][j]; x[ii][j] = x[ii][in]; x[ii][in] = tmp; } perm[in] = -perm[in]; j = in; in = perm[in]; } } } else { for (long i = 1; i <= n; i++) { if (perm[i] > 0) { continue; } long j = perm[i] = - perm[i]; for (;;) { if (j == i) { break; } for (long ii = 1; ii <= m; ii++) { double tmp = x[ii][i]; x[ii][i] = x[ii][j]; x[ii][j] = tmp; } perm[j] = -perm[j]; j = perm[j]; } } } } void NUMfindHouseholder (long n, double *alpha, double x[], long incx, double *tau) { double xnorm; if (n < 2 || (xnorm = NUMnorm2 (n - 1, x, incx)) == 0) { *tau = 0; return; } double beta = NUMpythagoras (*alpha, xnorm); if (*alpha > 0) { beta = - beta; } if (! NUMfpp) { NUMmachar (); } double safmin = NUMfpp -> sfmin / NUMfpp -> eps; if (fabs (beta) >= safmin) { *tau = (beta - *alpha) / beta; NUMvector_scale (n - 1, 1 / (*alpha - beta), x, incx); *alpha = beta; } else { // xnorm, beta may be inaccurate; scale x and recompute them double rsafmn = 1 / safmin; long knt = 0; do { knt++; NUMvector_scale (n - 1, rsafmn, x, incx); beta *= rsafmn; *alpha *= rsafmn; } while (fabs (beta) < safmin); /* New beta is at most 1, at least safmin */ xnorm = NUMnorm2 (n - 1, x, incx); beta = NUMpythagoras (*alpha, xnorm); if (*alpha > 0) { beta = - beta; } *tau = (beta - *alpha) / beta; NUMvector_scale (n - 1, 1 / (*alpha - beta), x, incx); /* If alpha is subnormal, it may lose relative accuracy */ *alpha = beta; for (long i = 1; i <= knt; i++) { *alpha *= safmin; } } } void NUMfindGivens (double f, double g, double *cs, double *sn, double *r) { long count; if (! NUMfpp) { NUMmachar (); } double safmn2 = pow (NUMfpp -> base, (long) (log (NUMfpp -> sfmin / NUMfpp -> eps) / log (NUMfpp -> base) / 2.)); double safmx2 = 1 / safmn2; if (g == 0) { *cs = 1; *sn = 0; *r = f; return; } if (f == 0) { *cs = 0; *sn = 1; *r = g; return; } double f1 = f, g1 = g; double scale = MAX (fabs (f1), fabs (g1)); if (scale >= safmx2) { count = 0; do { count++; f1 *= safmn2; g1 *= safmn2; scale = MAX (fabs (f1), fabs (g1)); } while (scale >= safmx2); *r = sqrt (f1 * f1 + g1 * g1); *cs = f1 / *r; *sn = g1 / *r; for (long i = 1; i <= count; i++) { *r *= safmx2; } } else if (scale <= safmn2) { count = 0; do { count++; f1 *= safmx2; g1 *= safmx2; scale = MAX (fabs (f1), fabs (g1)); } while (scale <= safmn2); *r = sqrt (f1 * f1 + g1 * g1); *cs = f1 / *r; *sn = g1 / *r; for (long i = 1; i <= count; i++) { *r *= safmn2; } } else { *r = sqrt (f1 * f1 + g1 * g1); *cs = f1 / *r; *sn = g1 / *r; } if (fabs (f) > fabs (g) && *cs < 0) { *cs = -*cs; *sn = -*sn; *r = -*r; } } void NUMapplyFactoredHouseholder (double **c, long rb, long re, long cb, long ce, double v[], long incv, double tau, int side) { long i, j, iv; double sum; Melder_assert ( (re - rb) >= 0 && (ce - cb) >= 0 && incv != 0); if (tau == 0) { return; } if (side == NUM_LEFT) { /* Form Q * C: 1. w := C' * v 2. C := C - v * w' */ for (j = cb; j <= ce; j++) { for (sum = 0, iv = 1, i = rb; i <= re; i++, iv += incv) { sum += c[i][j] * v[iv]; } sum *= tau; for (iv = 1, i = rb; i <= re; i++, iv += incv) { c[i][j] -= v[iv] * sum; } } } else { /* side == NUM_RIGHT */ /* Form C * Q 1. w := C * v 2. C := C - w * v' */ for (i = rb; i <= re; i++) { for (sum = 0, iv = 1, j = cb; j <= ce; j++, iv += incv) { sum += c[i][j] * v[iv]; } sum *= tau; for (iv = 1, j = cb; j <= ce; j++, iv += incv) { c[i][j] -= sum * v[iv]; } } } } void NUMapplyFactoredHouseholders (double **c, long rb, long re, long cb, long ce, double **v, long rbv, long rev, long cbv, long cev, long incv, double tau[], int side, int trans) { int left = side == NUM_LEFT, transpose = trans != NUM_NOTRANSPOSE; long mv = rev - rbv + 1, nv = cev - cbv + 1; long i_begin, i_end, i_inc, numberOfHouseholders, order_v; long m = re - rb + 1, n = ce - cb + 1; long rbc = rb, rec = re, cbc = cb, cec = ce; if (incv != 1) { /* by column (QR) */ numberOfHouseholders = mv > nv ? nv : mv - 1; order_v = mv; } else { /* by row (RQ) */ numberOfHouseholders = nv > mv ? mv : nv - 1; order_v = nv; } Melder_assert (m > 0 && n > 0 && mv > 0 && nv > 0); Melder_assert (numberOfHouseholders <= MAX (m, n)); Melder_assert ( (left && m == order_v) || (! left && n == order_v)); if ( (left && ! transpose) || (! left && transpose)) { i_begin = numberOfHouseholders; i_end = 0; i_inc = -1; } else { i_begin = 1; i_end = numberOfHouseholders + 1; i_inc = 1; } long i = i_begin; while (i != i_end) { double save, *v1; long vr, vc; if (incv == 1) { vr = rev - i + 1; vc = cev - i + 1; if (left) { rec = re - i + 1; } else { cec = ce - i + 1; } v1 = v[vr]; } else { vr = rbv + i - 1; vc = cbv + i - 1; if (left) { rbc = rb + i - 1; } else { cbc = cb + i - 1; } v1 = TOVEC (v[vr][vc]); } save = v[vr][vc]; v[vr][vc] = 1; NUMapplyFactoredHouseholder (c, rbc, rec, cbc, cec, v1, incv, tau[i], side); v[vr][vc] = save; i += i_inc; } } void NUMhouseholderQR (double **a, long rb, long re, long cb, long ce, long lda, double tau[]) { long m = re - rb + 1, n = ce - cb + 1; long numberOfHouseholders = MIN (m, n); Melder_assert (numberOfHouseholders > 0); if (numberOfHouseholders == m) { tau[m] = 0; numberOfHouseholders--; } for (long i = 1; i <= numberOfHouseholders; i++) { long ri = rb + i - 1, ci = cb + i - 1; // Generate elementary reflector H(i) to annihilate "A(i+1:m,i)" NUMfindHouseholder (m - i + 1, &a[ri][ci], TOVEC (a[ri + 1][ci]), lda, &tau[i]); if (i < n) { // Apply H(i) to "A(i:m, i+1:n)" from the left double save = a[ri][ci]; a[ri][ci] = 1; NUMapplyFactoredHouseholder (a, ri, re, cb + i, ce, TOVEC (a[ri][ci]), lda, tau[i], NUM_LEFT); a[ri][ci] = save; } } } void NUMhouseholderQRwithColumnPivoting (long m, long n, double **a, long lda, long pivot[], double tau[]) { long numberOfHouseholders = MIN (m, n); Melder_assert (numberOfHouseholders > 0); if (! pivot) { NUMhouseholderQR (a, 1, m, 1, n, lda, tau); return; } if (numberOfHouseholders == m) { tau[m] = 0; numberOfHouseholders--; } autoNUMvector colnorm (1, 2 * n); long itmp = 1; for (long i = 1; i <= n; i++) { if (pivot[i] != 0) { if (i != itmp) { for (long j = 1; j <= m; j++) { double tmp = a[j][i]; a[j][i] = a[j][itmp]; a[j][itmp] = tmp; } pivot[i] = pivot[itmp]; pivot[itmp] = i; } else { pivot[i] = i; } itmp++; } else { pivot[i] = i; } } itmp--; // Compute the QR factorization and update remaining columns if (itmp > 0) { long ma = MIN (itmp, m); NUMhouseholderQR (a, 1, m, 1, ma, lda, tau); if (ma < n) NUMapplyFactoredHouseholders (a, 1, m, ma + 1, n, a, 1, m, 1, ma, lda, tau, NUM_LEFT, NUM_TRANSPOSE); } if (itmp >= numberOfHouseholders) { return; // goto end; } // Initialize partial column norms. the first n elements of // colnorm store the exact column norms. for (long i = itmp + 1; i <= n; i++) { colnorm[n + i] = colnorm[i] = NUMnorm2 (m - itmp, TOVEC (a[itmp + 1][i]), lda); } // Compute factorization for (long i = itmp + 1; i <= numberOfHouseholders; i++) { // Determine ith pivot column and swap if necessary double max = colnorm[i]; long pvt = i; for (long j = i + 1; j <= n; j++) { if (fabs (colnorm[j]) > max) { max = fabs (colnorm[j]); pvt = j; } } if (pvt != i) { for (long j = 1; j <= m; j++) { double tmp = a[j][i]; a[j][i] = a[j][pvt]; a[j][pvt] = tmp; } itmp = pivot[pvt]; pivot[pvt] = pivot[i]; pivot[i] = itmp; colnorm[pvt] = colnorm[i]; colnorm[n + pvt] = colnorm[n + i]; } // Generate elementary reflector H(i) NUMfindHouseholder (m - i + 1, &a[i][i], TOVEC (a[i + 1][i]), lda, &tau[i]); if (i < n) { // Apply H(i) to A(i:m,i+1:n) from the left double save = a[i][i]; a[i][i] = 1; NUMapplyFactoredHouseholder (a, i, m, i + 1, n, TOVEC (a[i][i]), lda, tau[i], NUM_LEFT); a[i][i] = save; } // Update partial column norms. for (long j = i + 1; j <= n; j++) { if (colnorm[j] == 0) { continue; } double t = a[i][j] / colnorm[j]; double tmp = 1 - t * t; if (tmp < 0) { tmp = 0; } t = colnorm[j] / colnorm[n + j]; if ( (1 + 0.05 * tmp * t * t) == 1) { if (m - i > 0) { colnorm[n + j] = colnorm[j] = NUMnorm2 (m - i, TOVEC (a[i + 1][j]), lda); } else { colnorm[j] = colnorm[n + j] = 0; } } else { colnorm[j] *= sqrt (tmp); } } } } void NUMhouseholderRQ (double **a, long rb, long re, long cb, long ce, double tau[]) { long m = re - rb + 1, n = ce - cb + 1; long numberOfHouseholders = MIN (m, n); Melder_assert (numberOfHouseholders > 0); if (numberOfHouseholders == n) { tau[n] = 0; numberOfHouseholders--; } for (long i = 1; i <= numberOfHouseholders; i++) { // Generate elementary reflector H(i) to annihilate "A(m-i+1,1:n-i)" long ri = re - i + 1, ci = ce - i + 1, order = n - i + 1; NUMfindHouseholder (order, &a[ri][ci], a[ri], 1, &tau[i]); if (i < m) { // Apply H(i) to "A(1:m-i,1:n-i+1)" from the right double save = a[ri][ci]; a[ri][ci] = 1; NUMapplyFactoredHouseholder (a, rb, re - i, cb, ci, a[ri], 1, tau[i], NUM_RIGHT); a[ri][ci] = save; } } } void NUMparallelVectors (long n, double x[], long incx, double y[], long incy, double *svmin) { double a11, c, svmax, tau; if (n <= 1) { *svmin = 0; return; } // Compute the QR factorization of the n-by-2 matrix ( x y ) NUMfindHouseholder (n, &x[1], TOVEC (x[1 + incx]), incx, &tau); a11 = x[1]; x[1] = 1; c = - tau * NUMdotproduct (n, x, incx, y, incy); NUMdaxpy (n, c, x, incx, y, incy); NUMfindHouseholder (n - 1, &y[1 + incy], TOVEC (y[1 + 2 * incy]), incy, &tau); // Compute the svd of 2-by-2 upper triangular matrix. NUMsvcmp22 (a11, y[1], y[1 + incy], svmin, &svmax); } void NUMsvdcmp22 (double f, double g, double h, double *svmin, double *svmax, double *snr, double *csr, double *snl, double *csl) { double a, clt, crt, slt, srt, tsign; double ft = f, fa = fabs (f); double ht = h, ha = fabs (h); double gt = g, ga = fabs (g); long pmax = 1; // pmax: maximum absolute entry of matrix (f=1, g=2, h=3). bool swap = ha > fa; if (swap) { double tmp = ft; ft = ht; ht = tmp; tmp = fa; fa = ha; ha = tmp; pmax = 3; } if (ga == 0) { // diagonal matrix *svmin = ha; *svmax = fa; clt = crt = 1; slt = srt = 0; } else { int gasmal = 1; if (ga > fa) { pmax = 2; if (! NUMfpp) { NUMmachar (); } if (fa / ga <= NUMfpp -> eps) { /* very large ga */ gasmal = 0; *svmax = ga; *svmin = ha > 1 ? fa / (ga / ha) : (fa / ga) * ha; clt = 1; slt = ht / gt; srt = 1; crt = ft / gt; } } if (gasmal) { // normal case double m, mm, l, t, tt, r, s, d = fa - ha; l = d == fa ? 1 : d / fa; /* copes with infinite f or h. */ m = gt / ft; mm = m * m; t = 2 - l; tt = t * t; s = sqrt (tt + mm); r = l == 0 ? fabs (m) : sqrt (l * l + mm); a = 0.5 * (s + r); *svmin = ha / a; *svmax = fa * a; t = mm == 0 ? (l == 0 ? SIGN (2, ft) * SIGN (1, gt) : gt / SIGN (d, ft) + m / t) : (m / (s + t) + m / (r + l)) * (1 + a); l = sqrt (t * t + 4); crt = 2 / l; srt = t / l; clt = (crt + srt * m) / a; slt = (ht / ft) * srt / a; } } if (swap) { *csl = srt; *snl = crt; *csr = slt; *snr = clt; } else { *csl = clt; *snl = slt; *csr = crt; *snr = srt; } // Correct the signs of svmin and svmax if (pmax == 1) { tsign = SIGN (1, *csr) * SIGN (1, *csl) * SIGN (1, f); } else if (pmax == 2) { tsign = SIGN (1, *snr) * SIGN (1, *csl) * SIGN (1, g); } else { /* pmax == 3 */ tsign = SIGN (1, *snr) * SIGN (1, *snl) * SIGN (1, h); } *svmax = SIGN (*svmax, tsign); *svmin = SIGN (*svmin, tsign * SIGN (1, f) * SIGN (1, h)); } /* Bai & Demmel, page 1472 */ void NUMgsvdcmp22 (int upper, int productsvd, double a1, double a2, double a3, double b1, double b2, double b3, double *csu, double *snu, double *csv, double *snv, double *csq, double *snq) { double a, aua11, aua12, aua21, aua22, avb12, avb11; double avb21, avb22, b, c, csl, csr, d, g, r, s1, s2; double snl, snr, ua11, ua11r, ua12, ua21, ua22; double ua22r, vb11, vb11r, vb12, vb21, vb22, vb22r; if (upper) { // Input matrices A and B are upper triangular matrices // Form matrix C = A * adj(B) = ( a b ) // ( 0 d ) if (productsvd) { /* This is to simplistic, will not work. Form: C = A.B: a = a1 * b1; d = a3 * b3; b = a1 * b2 + a2 * b3; Form C = B.A */ a = a1 * b1; d = a3 * b3; b = a2 * b2 + a3 * b2; } else { a = a1 * b3; d = a3 * b1; b = a2 * b1 - a1 * b2; } /* the svd of real 2-by-2 triangular C ( csl -snl )*( a b )*( csr snr ) = ( r 0 ) ( snl csl ) ( 0 d ) ( -snr csr ) ( 0 t ) */ NUMsvdcmp22 (a, b, d, &s1, &s2, &snr, &csr, &snl, &csl); if (fabs (csl) >= fabs (snl) || fabs (csr) >= fabs (snr)) { // Compute the (1,1) and (1,2) elements of U' * A and V' * B, // and (1,2) element of |U|' * |A| and |V|' * |B|. ua11r = csl * a1; ua12 = csl * a2 + snl * a3; vb11r = csr * b1; vb12 = csr * b2 + snr * b3; aua12 = fabs (csl) * fabs (a2) + fabs (snl) * fabs (a3); avb12 = fabs (csr) * fabs (b2) + fabs (snr) * fabs (b3); g = fabs (ua11r) + fabs (ua12); // Zero (1,2) elements of U'*A and V' * B if (g != 0 && aua12 / g <= avb12 / (fabs (vb11r) + fabs (vb12))) { NUMfindGivens (-ua11r, ua12, csq, snq, &r); } else { NUMfindGivens (-vb11r, vb12, csq, snq, &r); } *csu = csl; *snu = -snl; *csv = csr; *snv = -snr; } else { /* Compute the (2,1) and (2,2) elements of U' * A and V' * B, and (2,2) element of |U|' * |A| and |V|' * |B|. */ ua21 = -snl * a1; ua22 = -snl * a2 + csl * a3; vb21 = -snr * b1; vb22 = -snr * b2 + csr * b3; aua22 = fabs (snl) * fabs (a2) + fabs (csl) * fabs (a3); avb22 = fabs (snr) * fabs (b2) + fabs (csr) * fabs (b3); g = fabs (ua21) + fabs (ua22); // Zero (2,2) elements of U' * A and V' * B, and then swap. if (g != 0 && aua22 / g <= avb22 / (fabs (vb21) + fabs (vb22))) { NUMfindGivens (-ua21, ua22, csq, snq, &r); } else { NUMfindGivens (-vb21, vb22, csq, snq, &r); } *csu = snl; *snu = csl; *csv = snr; *snv = csr; } } else { // Input matrices A and B are lower triangular matrices // Form matrix C = A * adj(B) = ( a 0 ) // ( c d ) if (productsvd) { a = a1 * b1; d = a3 * b3; c = a2 * b1 + a3 * b2; } else { a = a1 * b3; d = a3 * b1; c = a2 * b3 - a3 * b2; } // The svd of real 2-by-2 triangular C // ( csl -snl ) * ( a 0 ) * ( csr snr ) = ( r 0 ) // ( snl csl ) ( c d ) ( -snr csr ) ( 0 t ) NUMsvdcmp22 (a, c, d, &s1, &s2, &snr, &csr, &snl, &csl); if (fabs (csr) >= fabs (snr) || fabs (csl) >= fabs (snl)) { // Compute the (2,1) and (2,2) elements of U' * A and V' * B, // and (2,1) element of |U|' * |A| and |V|' * |B|. ua21 = -snr * a1 + csr * a2; ua22r = csr * a3; vb21 = -snl * b1 + csl * b2; vb22r = csl * b3; aua21 = fabs (snr) * fabs (a1) + fabs (csr) * fabs (a2); avb21 = fabs (snl) * fabs (b1) + fabs (csl) * fabs (b2); g = fabs (ua21) + fabs (ua22r); // Zero (2,1) elements of U' * A and V' * B. if (g != 0 && aua21 / g <= avb21 / (fabs (vb21) + fabs (vb22r))) { NUMfindGivens (ua22r, ua21, csq, snq, &r); } else { NUMfindGivens (vb22r, vb21, csq, snq, &r); } *csu = csr; *snu = -snr; *csv = csl; *snv = -snl; } else { // Compute the (1,1) and (1,2) elements of U' * A and V' * B, // and (1,1) element of |U|' * |A| and |V|' * |B|. ua11 = csr * a1 + snr * a2; ua12 = snr * a3; vb11 = csl * b1 + snl * b2; vb12 = snl * b3; aua11 = fabs (csr) * fabs (a1) + fabs (snr) * fabs (a2); avb11 = fabs (csl) * fabs (b1) + fabs (snl) * fabs (b2); g = fabs (ua11) + fabs (ua12); // Zero (1,1) elements of U' * A and V' * B, and then swap. if (g != 0 && aua11 / g <= avb11 / (fabs (vb11) + fabs (vb12))) { NUMfindGivens (ua12, ua11, csq, snq, &r); } else { NUMfindGivens (vb12, vb11, csq, snq, &r); } *csu = snr; *snu = csr; *csv = snl; *snv = csl; } } } void NUMsvcmp22 (double f, double g, double h, double *svmin, double *svmax) { double as, at, au, c; double fa = fabs (f), ga = fabs (g), ha = fabs (h); double fhmn = MIN (fa, ha), fhmx = MAX (fa, ha); if (fhmn == 0) { *svmin = 0; if (fhmx == 0) { *svmax = ga; } else { double tmp = MIN (fhmx, ga) / MAX (fhmx, ga); *svmax = MAX (fhmx, ga) * sqrt (1 + tmp * tmp); } } else { if (ga < fhmx) { as = 1 + fhmn / fhmx; at = (fhmx - fhmn) / fhmx; au = ga / fhmx; au *= au; c = 2 / (sqrt (as * as + au) + sqrt (at * at + au)); *svmin = fhmn * c; *svmax = fhmx / c; } else { au = fhmx / ga; if (au == 0) { // Avoid possible harmful underflow if exponent range // asymmetric (true svmin may not underflow even if au underflows) *svmin = (fhmn * fhmx) / ga; *svmax = ga; } else { double t1, t2; as = 1 + fhmn / fhmx; at = (fhmx - fhmn) / fhmx; t1 = as * au; t2 = at * au; c = 1 / (sqrt (1 + t1 * t1) + sqrt (1 + t2 * t2)); *svmin = (fhmn * c) * au; *svmin += *svmin; *svmax = ga / (c + c); } } } } #define MAXIT 50 void NUMgsvdFromUpperTriangulars (double **a, long m, long n, double **b, long p, int product, long k, long l, double tola, double tolb, double *alpha, double *beta, double **u, double **v, double **q, long *ncycle) { int upper = 0; long iter, maxmn = MAX (m, n); double a1, a2, a3, b1, b2, b3, csq, csu, csv; double snq, snu, snv; Melder_assert (m > 0 && p > 0 && n > 0 && k <= maxmn && l <= maxmn); autoNUMvector work (1, 2 * n); for (iter = 1; iter <= MAXIT; iter++) { upper = ! upper; for (long i = 1; i <= l - 1; i++) { for (long j = i + 1; j <= l; j++) { a1 = a2 = a3 = 0; if (k + i <= m) { a1 = a[k + i][n - l + i]; } if (k + j <= m) { a3 = a[k + j][n - l + j]; } b1 = b[i][n - l + i]; b3 = b[j][n - l + j]; if (upper) { if (k + i <= m) { a2 = a[k + i][n - l + j]; } b2 = b[i][n - l + j]; } else { if (k + j <= m) { a2 = a[k + j][n - l + i]; } b2 = b[j][n - l + i]; } NUMgsvdcmp22 (upper, product, a1, a2, a3, b1, b2, b3, &csu, &snu, &csv, &snv, &csq, &snq); // Update (k+i)-th and (k+j)-th rows of matrix A: U'*A if (k + j <= m) NUMplaneRotation (l, TOVEC (a[k + j][n - l + 1]), 1, TOVEC (a[k + i][n - l + 1]), 1, csu, snu); // Update i-th and j-th rows of matrix B: V' * B NUMplaneRotation (l, TOVEC (b[j][n - l + 1]), 1, TOVEC (b[i][n - l + 1]), 1, csv, snv); // Update (n-l+i)-th and (n-l+j)-th columns of matrices A and B: A * Q and B * Q NUMplaneRotation (MIN (k + l, m), TOVEC (a[1][n - l + j]), n, TOVEC (a[1][n - l + i]), n, csq, snq); NUMplaneRotation (l, TOVEC (b[1][n - l + j]), n, TOVEC (b[1][n - l + i]), n, csq, snq); if (upper) { if (k + i <= m) { a[k + i][n - l + j] = 0; } b[i][n - l + j] = 0; } else { if (k + j <= m) { a[k + j][n - l + i] = 0; } b[j][n - l + i] = 0; } // Update columns of orthogonal matrices U, V, Q, if desired. if (u && k + j <= m) { NUMplaneRotation (m, TOVEC (u[1][k + j]), m, TOVEC (u[1][k + i]), m, csu, snu); } if (v) { NUMplaneRotation (p, TOVEC (v[1][j]), p, TOVEC (v[1][i]), p, csv, snv); } if (q) { NUMplaneRotation (n, TOVEC (q[1][n - l + j]), n, TOVEC (q[1][n - l + i]), n, csq, snq); } } } if (! upper) { // The matrices A13 and B13 were lower triangular at the start // of the cycle, and are now upper triangular. // Convergence test: test the parallelism of the corresponding rows of A and B. double error = 0, svmin; for (long i = 1; i <= MIN (l, m - k); i++) { long jj = n - l + i; for (long j = 1; j <= l - i + 1; j++, jj++) { work[j] = a[k + i][jj]; work[l + j] = b[i][jj]; } NUMparallelVectors (l - i + 1, work.peek(), 1, TOVEC (work[l + 1]), 1, &svmin); if (svmin > error) { error = svmin; } } if (fabs (error) <= MIN (tola, tolb) * n) { break; } } } // Has the algorithm converged after maxit cycles? if (iter == MAXIT + 1) { *ncycle = MAXIT; Melder_throw (U"No convergence after ", MAXIT, U" iterations."); } *ncycle = iter; // Compute the generalized singular value pairs (alpha, beta), and // set the triangular matrix R to matrix a. for (long i = 1; i <= k; i++) { alpha[i] = 1; beta[i] = 0; } for (long i = 1; i <= MIN (l, m - k); i++) { a1 = a[k + i][n - l + i]; b1 = b[i][n - l + i]; if (a1 != 0) { double gamma = b1 / a1, rwk; if (gamma < 0) { /* Change sign of i-th row of B and i-th column of V: B(i, n-l+i:n) := - B(i, n-l+i:n) V(1:p, i) := - V(1:p, i) */ for (long j = n - l + i; j <= n; j++) { b[i][j] = -b[i][j]; } if (v) for (long j = 1; j <= p; j++) { v[j][i] = - v[j][i]; } } NUMfindGivens (fabs (gamma), 1, &beta[k + i], &alpha[k + i], &rwk); if (alpha[k + i] >= beta[k + i]) { for (long j = n - l + i; j <= n; j++) { a[k + i][j] /= alpha[k + i]; } } else { for (long j = n - l + i; j <= n; j++) { b[i][j] /= beta[k + i]; a[k + i][j] = b[i][j]; } } } else { alpha[k + i] = 0; beta[k + i] = 1; for (long j = n - l + i; j <= n; j++) { a[k + i][j] = b[i][j]; } } } // Post-assignment for (long i = m + 1; i <= k + l; i++) { alpha[i] = 0; beta[i] = 1; } if (k + l < n) { for (long i = k + l + 1; i <= n; i++) { alpha[i] = beta[i] = 0; } } } void NUMmatricesToUpperTriangularForms (double **a, long m, long n, double **b, long p, double tola, double tolb, long *kk, long *ll, double **u, double **v, double **q) { int forward = 1; long i, j, k = 0, l = 0, lda = n, ldb = n; Melder_assert (m > 0 && p > 0 && n > 0); *kk = *ll = 0; autoNUMvector pivot (1, n); autoNUMvector tau (1, n); if (v) { NUMidentity (v, 1, p, 1); } if (u) { NUMidentity (u, 1, m, 1); } if (q) { NUMidentity (q, 1, n, 1); } /* QR with column pivoting of B: B * P = V * ( B11 B12 ) ( 0 0 ), where V = H(1)H(2)...H(min(p,n)) */ NUMhouseholderQRwithColumnPivoting (p, n, b, ldb, pivot.peek(), tau.peek()); if (v) NUMapplyFactoredHouseholders (v, 1, p, 1, p, b, 1, p, 1, n, ldb, tau.peek(), NUM_RIGHT, NUM_NOTRANSPOSE); if (q) { NUMpermuteColumns (forward, n, n, q, pivot.peek()); } // Update A := A * P NUMpermuteColumns (forward, m, n, a, pivot.peek()); // Determine the effective rank of matrix B and clean up B. for (l = 0, i = 1; i <= MIN (p, n); i++) { if (fabs (b[i][i]) > tolb) { l++; } } for (i = 2; i <= p; i++) { for (j = 1; j <= (i <= l ? i - 1 : n); j++) { b[i][j] = 0; } } if (p >= l && n != l) { // RQ factorization of (B11 B12): ( B11 B12 ) = ( 0 B12 ) * Z NUMhouseholderRQ (b, 1, l, 1, n, tau.peek()); // Update A := A * Z' and Q := Q * Z' // Householder vectors are stored in rows of B. NUMapplyFactoredHouseholders (a, 1, m, 1, n, b, 1, l, 1, n, 1, tau.peek(), NUM_RIGHT, NUM_NOTRANSPOSE); if (q) NUMapplyFactoredHouseholders (q, 1, n, 1, n, b, 1, l, 1, n, 1, tau.peek(), NUM_RIGHT, NUM_NOTRANSPOSE); // Clean up B for (i = 1; i <= l; i++) { for (j = 1; j <= n - l + i - 1; j++) { b[i][j] = 0; } } } /* We are done with B, now proceed with A. Let n-l l A = ( A11 A12 ) m, then the following does the complete QR decomposition of A11: A11 = U * ( 0 T12 ) * P1' ( 0 0 ) */ if (n - l > 0) { for (i = 1; i <= n - l; i++) { pivot[i] = 0; } NUMhouseholderQRwithColumnPivoting (m, n - l, a, lda, pivot.peek(), tau.peek()); // Determine the effective rank of A11 for (k = 0, i = 1; i <= MIN (m, n - l); i++) { if (fabs (a[i][i]) > tola) { k++; } } // Update A12 := U' * A12, where A12 = A (1:m, n-l+1:n) NUMapplyFactoredHouseholders (a, 1, m, n - l + 1, n, a, 1, m, 1, n - l, lda, tau.peek(), NUM_LEFT, NUM_TRANSPOSE); if (u) NUMapplyFactoredHouseholders (u, 1, m, 1, m, a, 1, m, 1, n - l, lda, tau.peek(), NUM_RIGHT, NUM_NOTRANSPOSE); // Update Q(1:n, 1:n-l) = Q(1:n, 1:n-l) * P1 if (q) { NUMpermuteColumns (forward, n, n - l, q, pivot.peek()); } // Clean up A: set the strictly lower triangular part of // A(1:k, 1:k) = 0, and A(k+1:m, 1:n-l) = 0. for (i = 2; i <= k; i++) { for (j = 1; j <= i - 1; j++) { a[i][j] = 0; } } for (i = k + 1; i <= m; i++) { for (j = 1; j <= n - l; j++) { a[i][j] = 0; } } } if (n - l > k) { // RQ factorization of ( T11 T12 ) = ( 0 T12 ) * Z1 NUMhouseholderRQ (a, 1, k, 1, n - l, tau.peek()); // Update Q(1:n,1:n-l) = Q(1:n,1:n-l ) * Z1' // djmw: was transpose instead of no_transpose if (q) NUMapplyFactoredHouseholders (q, 1, n, 1, n - l, a, 1, k, 1, n - l, 1, tau.peek(), NUM_RIGHT, NUM_NOTRANSPOSE); // Clean up A for (i = 1; i <= k; i++) { for (j = 1; j <= n - l - k + i - 1; j++) { a[i][j] = 0; } } } if (m > k) { // QR factorization of A (k+1:m, n-l+1:n) NUMhouseholderQR (a, k + 1, m, n - l + 1, n, lda, tau.peek()); // Update U(:,k+1:m) := U(:,k+1:m)*U1 if (u) NUMapplyFactoredHouseholders (u, 1, m, k + 1, m, a, k + 1, m, n - l + 1, n, lda, tau.peek(), NUM_RIGHT, NUM_NOTRANSPOSE); // Clean up for (j = n - l + 1; j <= n; j++) { for (i = j - n + k + l + 1; i <= m; i++) { a[i][j] = 0; } } } *kk = k; *ll = l; } void NUMgsvdcmp (double **a, long m, long n, double **b, long p, int productsvd, long *k, long *l, double *alpha, double *beta, double **u, double **v, double **q, int invertR) { long ncycle; Melder_assert (m > 0 && n > 0 && p > 0); /* Get machine precision and set up threshold for determining the effective numerical rank of the matrices a and b. */ if (! NUMfpp) { NUMmachar (); } double anorm = NUMfrobeniusnorm (m, n, a); double bnorm = NUMfrobeniusnorm (p, n, b); if (anorm == 0 || bnorm == 0) { Melder_throw (U"NUMgsvdcmp: empty matrix."); } double tola = MAX (m, n) * MAX (anorm, NUMfpp -> sfmin) * NUMfpp -> prec; double tolb = MAX (p, n) * MAX (bnorm, NUMfpp -> sfmin) * NUMfpp -> prec; NUMmatricesToUpperTriangularForms (a, m, n, b, p, tola, tolb, k, l, u, v, q); NUMgsvdFromUpperTriangulars (a, m, n, b, p, productsvd, *k, *l, tola, tolb, alpha, beta, u, v, q, &ncycle); if (q && invertR) { long i, j, ki, nr = *k + *l; int upper, unitDiagonal; autoNUMmatrix r (1, nr, 1, nr); autoNUMvector norms (1, *l); autoNUMvector xrow (n - *k - *l + 1, n); if (m - *k - *l >= 0) { /* n-k-l k l ( 0 R ) = k ( 0 R11 R12 ) l ( 0 0 R22 ) R is stored in A (1:k+l, n-k-l+1:n). */ for (i = 1; i <= nr; i++) { for (j = i; j <= nr; j++) { r[i][j] = a[i][n - *k - *l + j]; } } } else { /* n-k-l k m-k k+l-m ( 0 R ) = k ( 0 R11 R12 R13 ) m-k ( 0 0 R22 R23 ) k+l-m ( 0 0 0 R33 ) (R11 R12 R13 ) is stored in A (1:m, n-k-l+1:n), and R33 is stored ( 0 R22 R23 ) in B (m-k+1:l, n+m-k-l+1:n). */ for (i = 1; i <= m; i++) { for (j = i; j <= nr; j++) { r[i][j] = a[i][n - *k - *l + j]; } } for (i = m + 1; i <= nr; i++) { for (j = i; j <= nr; j++) { r[i][j] = b[i - *k][n - *k - *l + j]; } } } /* Form X = Q * ( I 0 ) ( 0 inv(R) ) and store result in Q. */ NUMtriangularInverse ( (upper = 1), (unitDiagonal = 0), nr, r.peek()); for (i = 1; i <= n; i++) { for (j = n - *k - *l + 1; j <= n; j++) { xrow[j] = 0; for (ki = n - *k - *l + 1; ki <= j; ki++) { xrow[j] += q[i][ki] * r[ki][j]; } } for (j = n - *k - *l + 1; j <= n; j++) { q[i][j] = xrow[j]; } } /* Get norms of eigenvectors. */ for (i = 1; i <= *l; i++) { norms[i] = NUMnorm2 (n, TOVEC (q[1][*k + i]), n); printf ("%f ", norms[i]); } } } void NUMtriangularInverse (int upper, int unitDiagonal, long n, double **a) { long j, i, k; double ajj, tmp; Melder_assert (n > 0); if (upper) { for (j = 1; j <= n; j++) { if (! unitDiagonal) { a[j][j] = 1 / a[j][j]; ajj = -a[j][j]; } else { ajj = -1; } /* Compute elements 1:j-1 of j-th column. */ for (k = 1; k <= j - 1; k++) { if (a[k][j] == 0) { continue; } tmp = a[k][j]; for (i = 1; i <= k - 1; i++) { a[i][j] += tmp * a[i][k]; } if (! unitDiagonal) { a[k][j] *= a[k][k]; } } for (k = 1; k <= j - 1; k++) { a[k][j] *= ajj; } } } else { for (j = n; j >= 1; j--) { if (! unitDiagonal) { a[j][j] = 1 / a[j][j]; ajj = -a[j][j]; } else { ajj = -1; } if (j < n) { /* Compute elements j+1:n of j-th column. */ for (k = n; k >= j + 1; k--) { if (a[k][j] == 0) { continue; } tmp = a[k][j]; for (i = n; i >= k + 1; i--) { a[i][j] += tmp * a[i][k]; } if (! unitDiagonal) { a[k][j] *= a[k][k]; } } for (k = 1; k <= n - j; k++) { a[j + k][j] *= ajj; } } } } } void NUMeigencmp22 (double a, double b, double c, double *rt1, double *rt2, double *cs1, double *sn1) { long sgn1, sgn2; double ab, acmn, acmx, acs, adf, cs, ct, df, rt, sm, tb, tn; sm = a + c; df = a - c; adf = fabs (df); tb = b + b; ab = fabs (tb); if (fabs (a) > fabs (c)) { acmx = a; acmn = c; } else { acmx = c; acmn = a; } if (adf > ab) { tn = ab / adf; rt = adf * sqrt (1 + tn * tn); } else if (adf < ab) { tn = adf / ab; rt = ab * sqrt (1 + tn * tn); } else { rt = ab * sqrt (2); } if (sm < 0) { *rt1 = 0.5 * (sm - rt); sgn1 = -1; /* Order of execution important. To get fully accurate smaller eigenvalue, next line needs to be executed in higher precision. */ *rt2 = (acmx / *rt1) * acmn - (b / *rt1) * b; } else if (sm > 0) { *rt1 = 0.5 * (sm + rt); sgn1 = 1; /* Order of execution important. To get fully accurate smaller eigenvalue, next line needs to be executed in higher precision. */ *rt2 = (acmx / *rt1) * acmn - (b / *rt1) * b; } else { *rt1 = 0.5 * rt; *rt2 = -0.5 * rt; sgn1 = 1; } /* Compute the eigenvector */ if (df >= 0) { cs = df + rt; sgn2 = 1; } else { cs = df - rt; sgn2 = -1; } acs = fabs (cs); if (acs > ab) { ct = -tb / cs; *sn1 = 1 / sqrt (1 + ct * ct); *cs1 = ct * *sn1; } else { if (ab == 0) { *cs1 = 1; *sn1 = 0; } else { tn = -cs / tb; *cs1 = 1 / sqrt (1 + tn * tn); *sn1 = tn * *cs1; } } if (sgn1 == sgn2) { tn = *cs1; *cs1 = -*sn1; *sn1 = tn; } } /* End of file NUMlapack.cpp */ praat-6.0.04/dwsys/NUMlapack.h000066400000000000000000001014011261542461700160520ustar00rootroot00000000000000/* NUMlapack.h * * Copyright (C) 1994-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020418 Notify that product svd does not work. djmw 20110308 Latest modification */ #ifndef _NUMlapack_h_ #define _NUMlapack_h_ #ifndef _NUM2_h_ #include "NUM2.h" #endif #define NUM_NOTRANSPOSE 0 #define NUM_TRANSPOSE 1 #define NUM_LEFT 0 #define NUM_RIGHT 1 #define NUM_BYROW 1 #define NUM_BYCOLUMN 0 /* From: http://www.netlib.org/lapack/faq.html LAPACK is a freely-available software package. It is available from netlib via anonymous ftp and the World Wide Web. Thus, it can be included in commercial software packages (and has been). We only ask that proper credit be given to the authors. Like all software, it is copyrighted. It is not trademarked, but we do ask the following: If you modify the source for these routines we ask that you change the name of the routine and comment the changes made to the original. We will gladly answer any questions regarding the software. If a modification is done, however, it is the responsibility of the person who modified the outine to provide support. */ /* The following routines are modified C versions of LAPACK fortran sources. Although there also is an official C-version of these fortran routines the latter have severe drawbacks. They all imply call-by-reference and a fortran like array structure (column-wise storage). We have changed the following things: 1. Our matrices are all dimensioned a[1:m, 1:n] (contrary to standard C where numbering starts at 0). 2. All the matrices should be allocated as one contiguous block of storage (in C only the rows need to be contiguously allocated). A number of procedures depend critically on this fact: all procedures that approach the columns of a matrix as a vector by indexing its first element and then using an 'increment' of size 'number of columns' to approach the next elements of the vector. 3. In C, array storage is row wise. The leading dimension hack in many routines therefor works opposite to the fortran implementation: it must be used for indexing COLUMNS instead of rows (lda =1 to index by row, lda=n to index by column). This also implies that the leading dimension of a matrix equals the number of columns. With this trick we can also address vectors from a matrix by column and by row, however we have to use a little trick. In the fortran routines it often happens that a sub-row or a sub-column is passed to a subroutine in which it is referenced as a VECTOR, i.e. someArgument(i). To copy this in C we have to translate call sub (.., A(I,J), ..) into: sub (.., &A[i][j] - 1, ..) We do this with a macro: #define TOVEC(x) &(x) - 1, because our matrices are dimensioned as A[1:m,1:n] For addressing submatrices in C we can not imitate the fortran trick call somesub (..., A(I,J), lda,...), however. We therefor use explicit indexing, i.e., we address the part to be updated: as in NUMapplyFactoredHouseholder (c, rb, re, cb, ce,...) where rb/re and cb/ce refer to the start/end rows and columns, respectively. 3. We changed routine names: dnrm2 NUMnorm2 dlapy2 NUMpythagoras dcopy NUMcopyElements ddot NUMdotproduct daxpy NUMdaxpy dscal NUMvector_scale drot NUMplaneRotation dlas2 NUMsvcmp22 dlartg NUMfindGivens dgeqr2 NUMhouseholderQR dgerq2 NUMhouseholderRQ dgeqpf NUMhouseholderQRwithColumnPivoting dlarfg NUMfindHouseholder dlarf NUMapplyFactoredHouseholder dorm2r NUMapplyFactoredHouseholders dlapll NUMparallelVectors dlapmt NUMpermuteColumns dlasv2 NUMsvdcmp22 dlags2 NUMgsvdcmp22 dtgsja NUMgsvdFromUpperTriangulars dggsvp NUMmatricesToUpperTriangularForms */ void NUMidentity (double **a, long rb, long re, long cb); /* Set a[rb:re, cb:cb+re-rb] to identity matrix. */ double NUMpythagoras (double a, double b); /* Returns sqrt (a^2 + b^2), taking care not to cause unnecessary overflow. */ double NUMnorm2 (long n, double *x, long incx); /* Returns the euclidean norm of a vector so that NUMvector_norm2 := sqrt (x'*x) */ double NUMfrobeniusnorm (long m, long n, double **x); /* Returns frobenius norm of matrix sqrt (sum (i=1:m, j=1:n, x[i][j]^2)) */ double NUMdotproduct (long n, double x[], long incx, double y[], long incy); /* Returns the dot product of two vectors. */ void NUMcopyElements (long n, double x[], long incx, double y[], long incy); /* Copies a vector, x, to a vector, y. */ void NUMdaxpy (long n, double da, double x[], long incx, double y[], long incy); /* Constant times a vector plus a vector y[] += da*x[]. */ void NUMvector_scale (long n, double da, double dx[], long incx); /* Scales a vector by a constant. */ void NUMplaneRotation (long n, double x[], long incx, double y[], long incy, double c, double s); /* Rotates vector's x and y. */ void NUMpermuteColumns (int forward, long m, long n, double **x, long *perm); /* Rearranges the columns of the m by n matrix X as specified by the permutation perm[1], perm[2], ..., perm[n] of the integers 1, ..., n. if forward != 0, forward permutation: x[*,perm[j]] is moved to x[*,j] for j = 1, 2, ..., n. if forward == 0, backward permutation: x[*,j] is moved to x[*,perm[j]] for j = 1, 2, ..., n. arguments ========= forward != 0 forward permutation == 0 backward permutation m the number of rows of the matrix X. m > 0. n the number of columns of the matrix X. n > 0. x on entry, the matrix x[1:m, 1:n]. on exit, x contains the permuted matrix X. perm the permutation vector [1..n]. */ void NUMfindHouseholder (long n, double *alpha, double x[], long incx, double *tau); /* Find a real elementary reflector H of order n, such that H * ( alpha ) = ( beta ), H' * H = i. ( x ) ( 0 ) where alpha and beta are scalars, and x is an (n-1)-element real vector. H is represented in the form H = I - tau * ( 1 ) * ( 1 v' ) , ( v ) where tau is a real scalar and v is a real (n-1)-element vector. If the elements of x are all zero, then tau = 0 and H is taken to be the unit matrix. otherwise 1 <= tau <= 2. arguments ========= n the order of the elementary reflector. alpha (input/output) double on entry, the value alpha. on exit, it is overwritten with the value beta. x (input/output) double array, dimension (1+(n-2)*abs(incx)) on entry, the vector x. on exit, it is overwritten with the vector v. incx the increment between elements of x. incx > 0. tau (output) the value tau. */ void NUMfindGivens (double f, double g, double *cs, double *sn, double *r); /* Generate a 2 dimensional rotation so that [ cs sn ] . [ f ] = [ r ] where cs**2 + sn**2 = 1. [ -sn cs ] [ g ] [ 0 ] if g=0, then cs=1 and sn=0. if f=0 and (g != 0), then cs=0 and sn=1 if f exceeds g in magnitude, cs will be positive. Arguments ========= f the first component of vector to be rotated. g the second component of vector to be rotated. cs the cosine of the rotation. sn the sine of the rotation. r the nonzero component of the rotated vector. */ void NUMapplyFactoredHouseholder (double **c, long rb, long re, long cb, long ce, double v[], long incv, double tau, int side); /* Applies a real elementary reflector H to the (rb:re, cb:ce) part of a real matrix C (1:,1;), from either the left or the right. H is represented in the form H = i - tau * v * v' where tau is a real scalar and v is a real vector. if tau = 0, then H is taken to be the unit matrix. arguments ========= side (input) int = NUM_LEFTSIDE: form H * C = NUM_RIGHTSIDE: form C * H rb, re begin/end row of the (sub) matrix. cb, ce begin/end columns of the (sub) matrix. v double array, dimension (1 + (m-1)*abs(incv)) if side = NUM_LEFTSIDE or (1 + (n-1)*abs(incv)) if side = NUM_RIGHTSIDE the vector v in the representation of H. v is not used if tau = 0. incv integer the increment between elements of v. incv <> 0. tau (input) double the value tau in the representation of H. c (input/output) double array, dimension (m,n) on entry, the m by n matrix C. on exit, C is overwritten by the matrix H * C or C * H. */ void NUMapplyFactoredHouseholders (double **c, long rb, long re, long cb, long ce, double **v, long rbv, long rev, long cbv, long cev, long incv, double tau[], int side, int trans); /* Overwrites the general real m by n matrix C with Q * C if side = NUM_LEFTSIDE and trans = NUM_NOTRANSPOSE, or Q'* C if side = NUM_LEFTSIDE and trans = NUM_TRANSPOSE, or C * Q if side = NUM_RIGHTSIDE and trans = NUM_NOTRANSPOSE, or C * Q' if side = NUM_RIGHTSIDE and trans = NUM_TRANSPOSE, where Q is a real orthogonal matrix defined as the product of k elementary reflectors Q = H(1) H(2) . . . H(k) Q is of order m if side = NUM_LEFTSIDE and of order n if side = NUM_RIGHTSIDE. arguments ========= c on entry, the matrix c[rb:re, cb:ce]. on exit, C is overwritten by Q*C or Q'*C or C*Q' or C*Q. rb, re begin/end rows of the matrix C. (m = (re-rb+1)) >= 0. cb, ce begin/end columns of the matrix C. (n = (ce-cb+1)) >= 0. k (input) integer the number of elementary reflectors whose product defines the matrix Q. if side = NUM_LEFTSIDE, m >= k >= 0; if side = NUM_RIGHTSIDE, n >= k >= 0. v (input) double array [rbv:rev, cbv:cev]. the i-th row or column must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k. v is modified by the routine but restored on exit. rbv, rev begin/end rows of the matrix V. cbv, cev begin/end columns of the matrix V. incv the increment between elements of v. incv <> 0. if incv = 1 the H(i) are row vectors if incv > 1 the H(i) are columnvectors tau (input) double array[1:n] tau[i] must contain the scalar factor of the elementary reflector H(i), as returned by one of the QR or RQ factorizations. side (input) int = NUM_LEFTSIDE: apply Q or Q' from the left = NUM_RIGHTSIDE: apply Q or Q' from the right trans (input) int = NUM_NOTRANSPOSE: apply Q (no transpose) = NUM_TRANSPOSE: apply Q' (transpose) */ void NUMeigencmp22 (double a, double b, double c, double *rt1, double *rt2, double *cs1, double *sn1 ); /* NUMeigencmp22 computes the eigendecomposition of a 2-by-2 symmetric matrix [ a b ] [ b c ]. on return, rt1 is the eigenvalue of larger absolute value, rt2 is the eigenvalue of smaller absolute value, and (cs1,sn1) is the unit right eigenvector for rt1, giving the decomposition [ cs1 sn1 ] [ a b ] [ cs1 -sn1 ] = [ rt1 0 ] [-sn1 cs1 ] [ b c ] [ sn1 cs1 ] [ 0 rt2 ]. rt1 is accurate to a few ulps barring over/underflow. rt2 may be inaccurate if there is massive cancellation in the determinant a*c-b*b; higher precision or correctly rounded or correctly truncated arithmetic would be needed to compute rt2 accurately in all cases. cs1 and sn1 are accurate to a few ulps barring over/underflow. overflow is possible only if rt1 is within a factor of 5 of overflow. underflow is harmless if the input data is 0 or exceeds underflow_threshold / macheps. */ void NUMhouseholderQR (double **a, long rb, long re, long cb, long ce, long ncol, double tau[]); /* Computes a QR factorization of a real (sub) matrix (rb:re, cb:ce) of A (:, :lda) A = Q * R. arguments ========= a (input/output) double precision array, dimension (m,n) on entry, the m by n matrix A. on exit, the elements on and above the diagonal of the array contain the min(m,n) by n upper trapezoidal matrix R (R is upper triangular if m >= n); the elements below the diagonal, with the array tau, represent the orthogonal matrix Q as a product of elementary reflectors (see further details). rb, re (input) begin/end rows of the matrix A. (re - rb) >= 0. cb, ce (input) begin/end columns of the matrix A. (ce - cb) >= 0 lda (input) the leading dimension of the array a, i.e., the number of rows. tau (output) double array, dimension (min(m,n)) the scalar factors of the elementary reflectors (see further details). Further details =============== The matrix Q is represented as a product of elementary reflectors Q = H(1) H(2) . . . H(k), where k = min(m,n). each H(i) has the form H(i) = i - tau * v * v' where tau is a real scalar, and v is a real vector with v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in a(rb+i-1:ce, cb+i-1), and tau in tau(i). */ void NUMhouseholderQRwithColumnPivoting (long m, long n, double **a, long ncol, long *pivot, double tau[]); /* Computes a QR factorization with column pivoting of a real m-by-n matrix A: A*P = Q*R. arguments ========= m the number of rows of the matrix A. m >= 0. n the number of columns of the matrix A. n >= 0 a on entry, the m-by-n matrix A. on exit, the upper triangle of the array contains the min(m,n)-by-n upper triangular matrix R; the elements below the diagonal, together with the array tau, represent the orthogonal matrix Q as a product of min(m,n) elementary reflectors. ncol the leading dimension of the array A, number of columns pivot on entry, if pivot[i] != 0, the i-th column of A is permuted to the front of A*P (A leading column); if pivot[i] = 0, the i-th column of A is a free column. on exit, if pivot[i] = k, then the i-th column of A*P was the k-th column of A. tau (output) double array, dimension (min(m,n)) the scalar factors of the elementary reflectors. Further details =============== The matrix Q is represented as a product of elementary reflectors Q = H(1) H(2) . . . H(n) Each H(i) has the form H = I - tau * v * v' where tau is a real scalar, and v is a real vector with v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i). The matrix P is represented in pivot as follows: If pivot[j] = i then the jth column of P is the ith canonical unit vector. */ void NUMhouseholderRQ (double **a, long rb, long re, long cb, long ce, double tau[]); /* Computes an RQ factorization of a real m by n matrix A: A = R * Q. arguments ========= rb, re begin/end rows of the matrix A ==> m = re - rb + 1. cb, ce begin/end columns of the matrix A ==> n = ce -cb + 1. a (input/output) double array, dimension (rb:re, cb:ce) on entry, the m by n matrix A. on exit, if m <= n, the upper triangle of the subarray a(1:m,n-m+1:n) contains the m by m upper triangular matrix R; if m >= n, the elements on and above the (m-n)-th subdiagonal contain the m by n upper trapezoidal matrix R; the remaining elements, with the array tau, represent the orthogonal matrix Q as a product of elementary reflectors (see further details). tau (output) double array [1: (min(m,n)]. the scalar factors of the elementary reflectors (see further details). Further details =============== The matrix Q is represented as a product of elementary reflectors Q = H(1) H(2) . . . H(k), where k = min (m,n). each H(i) has the form H(i) = I - tau * v * v' where tau is a real scalar, and v is a real vector with v(n-k+i+1:n) = 0 and v(n-k+i) = 1; v(1:n-k+i-1) is stored on exit in A(m-k+i,1:n-k+i-1), and tau in tau(i). */ void NUMparallelVectors (long n, double x[], long incx, double y[], long incy, double *svmin); /* Given two column vectors x and y, let A = ( x y ). the subroutine first computes the QR factorization of A = Q*R, and then computes the svd of the 2-by-2 upper triangular matrix R. The smaller singular value of R is returned in svmin, which is used as the measurement of the linear dependency of the vectors x and y. arguments ========= n the length of the vectors x and y. x (input/output) double array [1: (1+(n-1)*incx]. on entry, x contains the n-vector x. on exit, x is overwritten. incx the increment between successive elements of x. incx > 0. y (input/output) double array [1: (1+(n-1)*incy]. on entry, y contains the n-vector y. on exit, y is overwritten. incy the increment between successive elements of y. incy > 0. svmin the smallest singular value of the n-by-2 matrix A = ( x y ). */ void NUMsvdcmp22 (double f, double g, double h, double *svmin, double *svmax, double *snr, double *csr, double *snl, double *csl); /* Computes the SVD of a 2x2 triangular matrix: [ csl snl ] . [ f g ] . [ csr -snr ] = [ svmax 0 ] [-snl csl ] [ 0 h ] [ snr csr] [ 0 svmin ] The absolute value of svmax is larger singular value, absolute value of svmin is smaller singular value. Both csr^2 + snr^2 = 1 and csl^2 + snl^2 = 1. Arguments ========= f, g, h the (1,1), (1,2) and (2,2) element of the 2-by-2 matrix. svmin abs(svmin) is the smaller singular value. svmax abs(svmax) is the larger singular value. csl, the vector (csl, snl) is a unit left singular vector for the snl singular value abs(svmax). csr, the vector (csr, snr) is a unit right singular vector for the snr singular value abs(svmax). Further Details =============== Any input parameter may be aliased with any output parameter. Barring over/underflow and assuming a guard digit in subtraction, all output quantities are correct to within a few units in the last place (ulps). In IEEE arithmetic, the code works correctly if one matrix element is infinite. Overflow will not occur unless the largest singular value itself overflows or is within a few ulps of overflow. (On machines with partial overflow, like the Cray, overflow may occur if the largest singular value is within a factor of 2 of overflow.) Underflow is harmless if underflow is gradual. Otherwise, results may correspond to a matrix modified by perturbations of size near the underflow threshold. Z. Bai & J. Demmel (1993), "Computing the generalized singular value decomposition", SIAM J. Sci. Comput. 14, 1464 - 1486. */ void NUMgsvdcmp22 (int upper, int product, double a1, double a2, double a3, double b1, double b2, double b3, double *csu, double *snu, double *csv, double *snv, double *csq, double *snq); /* Compute 2-by-2 orthogonal matrices U, V and Q, such that if (upper) then U'*A*Q = U'*( a1 a2 )*Q = ( x 0 ) ( 0 a3 ) ( x x ) and V'*B*Q = V'*( b1 b2 )*Q = ( x 0 ) ( 0 b3 ) ( x x ) or if (! upper ) then U'*A*Q = U'*( a1 0 )*Q = ( x x ) ( a2 a3 ) ( 0 x ) and V'*B*Q = V'*( b1 0 )*Q = ( x x ) ( b2 b3 ) ( 0 x ) the rows of the transformed A and B are parallel, where U = ( csu snu ), V = ( csv snv ), Q = ( csq snq ) ( -snu csu ) ( -snv csv ) ( -snq csq ) Z' denotes the transpose of Z. Arguments ========= upper != 0: the input matrices A and B are upper triangular. = 0: the input matrices A and B are lower triangular. product if true the product svd is calculated intead of the quotient svd. a1, a2, a3 elements of the input 2-by-2 upper (lower) triangular matrix A. b1, b2, b3 elements of the input 2-by-2 upper (lower) triangular matrix B. csu, snu the desired orthogonal matrix U. csv, snv the desired orthogonal matrix V. csq, snq the desired orthogonal matrix Q. */ void NUMsvcmp22 (double f, double g, double h, double *svmin, double *svmax ); /* Compute the singular values of the 2-by-2 triangular matrix [ f g ] [ 0 h ]. On return, svmin is the smaller singular value and svmax is the larger singular value. Arguments ========= f, g, h the [1,1] [1,2] and [2,1] elements of the 2-by-2 matrix. svmin the smaller singular value. svmax the larger singular value. Further details =============== Barring over/underflow, all output quantities are correct to within a few units in the last place (ulps), even in the absence of a guard digit in addition/subtraction. In ieee arithmetic, the code works correctly if one matrix element is infinite. Overflow will not occur unless the largest singular value itself overflows, or is within a few ulps of overflow (on machines with partial overflow, like the cray, overflow may occur if the largest singular value is within a factor of 2 of overflow). Underflow is harmless if underflow is gradual. Otherwise, results may correspond to a matrix modified by perturbations of size near the underflow threshold. */ void NUMgsvdFromUpperTriangulars (double **a, long m, long n, double **b, long p, int product, long k, long l, double tola, double tolb, double *alpha, double *beta, double **u, double **v, double **q, long *ncycle); /* Computes the generalized singular value decomposition (gsvd) of two real upper triangular (or trapezoidal) matrices A and B. On entry, it is assumed that matrices A and B have the following forms, which may be obtained by the preprocessing subroutine dggsvp from a general m-by-n matrix A and p-by-n matrix B: n-k-l k l A = k ( 0 A12 A13 ) if m-k-l >= 0; l ( 0 0 A23 ) m-k-l ( 0 0 0 ) n-k-l k l A = k ( 0 A12 A13 ) if m-k-l < 0; m-k ( 0 0 A23 ) n-k-l k l B = l ( 0 0 B13 ) p-l ( 0 0 0 ) where the k-by-k matrix A12 and l-by-l matrix B13 are nonsingular upper triangular; A23 is l-by-l upper triangular if m-k-l >= 0, otherwise A23 is (m-k)-by-l upper trapezoidal. On exit, U'*A*Q = D1*( 0 R ), V'*B*Q = D2*( 0 R ), where U, V and Q are orthogonal matrices, Z' denotes the transpose of Z, R is a nonsingular upper triangular matrix, and D1 and D2 are ``diagonal'' matrices, which are of the following structures: if m-k-l >= 0, k l D1 = k ( I 0 ) l ( 0 C ) m-k-l ( 0 0 ) k l D2 = l ( 0 S ) p-l ( 0 0 ) n-k-l k l ( 0 R ) = k ( 0 R11 R12 ) k l ( 0 0 R22 ) l where C = Diag (alpha(k+1), ... , alpha(k+l)), S = Diag (beta(k+1), ... , beta(k+l)), C**2 + S**2 = i. R is stored in A(1:k+l,n-k-l+1:n) on exit. if m-k-l < 0, k m-k k+l-m D1 = k ( I 0 0 ) m-k ( 0 C 0 ) k m-k k+l-m D2 = m-k ( 0 S 0 ) k+l-m ( 0 0 I ) p-l ( 0 0 0 ) n-k-l k m-k k+l-m ( 0 R ) = k ( 0 R11 R12 R13 ) m-k ( 0 0 R22 R23 ) k+l-m ( 0 0 0 R33 ) where C = Diag (alpha(k+1), ... , alpha(m)), S = Diag (beta(k+1), ... , beta(m)), C**2 + S**2 = i. R = ( R11 R12 R13 ) is stored in A(1:m, n-k-l+1:n) and R33 is stored ( 0 R22 R23 ) in B(m-k+1:l,n+m-k-l+1:n) on exit. the computation of the orthogonal transformation matrices U, V or Q is optional. these matrices may either be formed explicitly, or they may be postmultiplied into input matrices U1, V1, or Q1. arguments ========= m the number of rows of the matrix A. m >= 0. p the number of rows of the matrix B. p >= 0. n the number of columns of the matrices A and B. n >= 0. k, l k and l specify the subblocks in the input matrices A and B: A23 = A(k+1:min(k+l,m), n-l+1:n) and B13 = B(1:l, n-l+1:n) of A and B, whose gsvd is going to be computed. see further details. a on entry, the m-by-n matrix A. on exit, A(n-k+1:n, 1:min(k+l,m) ) contains the triangular matrix R or part of R. see purpose for details. b on entry, the p-by-n matrix B. on exit, if necessary, B(m-k+1:l, n+m-k-l+1:n) contains a part of R. see purpose for details. product if true the product svd is calculated instead of the quotient svd tola, the convergence criteria for the Jacobi- Kogbetliantz tolb iteration procedure. Generally, they are the same as used in the preprocessing step, say tola = max(m,n) * norm(a) * macheps, tolb = max(p,n) * norm(b) * macheps. alpha, array[1:n] beta on exit, alpha and beta contain the generalized singular value pairs of A and B; alpha(1:k) = 1, beta(1:k) = 0, and if m-k-l >= 0, alpha(k+1:k+l) = diag(C), beta(k+1:k+l) = diag(S), or if m-k-l < 0, alpha(k+1:m)= C, alpha(m+1:k+l)= 0 beta(k+1:m) = S, beta(m+1:k+l) = 1. furthermore, if k+l < n, alpha(k+l+1:n) = 0 and beta(k+l+1:n) = 0. u on entry, if u != NULL, u must contain a matrix U1 (usually the orthogonal matrix returned by NUMmatricesToUpperTriangularForms). on exit, if u != NULL, u contains the product U1*U. if u == NULL, u is not referenced. v on entry, if v != NULL, v must contain a matrix V1 (usually the orthogonal matrix returned by NUMmatricesToUpperTriangularForms). on exit, if u != NULL, v contains the product V1*V. if u == NULL, v is not referenced. q on entry, if u != NULL, q must contain a matrix Q1 (usually the orthogonal matrix returned by NUMmatricesToUpperTriangularForms). on exit, if u != NULL, q contains the product Q1*Q. if u == NULL, q is not referenced. ncycle the number of cycles required for convergence. internal parameters =================== maxit specifies the total loops that the iterative procedure may take. if after maxit cycles, the routine fails to converge, we return with an error message. Further details =============== NUMgsvdFromUpperTriangulars essentially uses a variant of Kogbetliantz algorithm to reduce min(l,m-k)-by-l triangular (or trapezoidal) matrix A23 and l-by-l matrix B13 to the form: U1'*A13*Q1 = C1*R1; V1'*B13*Q1 = S1*R1, where U1, V1 and Q1 are orthogonal matrix, and Z' is the transpose of Z. C1 and S1 are diagonal matrices satisfying C1**2 + S1**2 = I, and R1 is an l-by-l nonsingular upper triangular matrix. */ void NUMmatricesToUpperTriangularForms (double **a, long m, long n, double **b, long p, double tola, double tolb, long *kk, long *ll, double **u, double **v, double **q); /* Computes orthogonal matrices U, V and Q such that n-k-l k l U'*A*Q = k ( 0 A12 A13 ) if m-k-l >= 0; l ( 0 0 A23 ) m-k-l ( 0 0 0 ) n-k-l k l = k ( 0 A12 A13 ) if m-k-l < 0; m-k ( 0 0 A23 ) n-k-l k l V'*B*Q = l ( 0 0 B13 ) p-l ( 0 0 0 ) where the k-by-k matrix A12 and l-by-l matrix B13 are nonsingular upper triangular; A23 is l-by-l upper triangular if m-k-l >= 0, otherwise A23 is (m-k)-by-l upper trapezoidal. k+l = the effective numerical rank of the (m+p)-by-n matrix (A',B')'. Z' denotes the transpose of Z. This decomposition is the preprocessing step for computing the generalized singular value decomposition (gsvd), see subroutine NUMgsvdFromUpperTriangulars. arguments ========= m the number of rows of the matrix A. m > 0. p the number of rows of the matrix B. p > 0. n the number of columns of the matrices A and B. n > 0. a on entry, the m-by-n matrix A. on exit, A contains the triangular (or trapezoidal) matrix described in the purpose section. b on entry, the p-by-n matrix B. on exit, B contains the triangular matrix described in the purpose section. tola, the thresholds to determine the effective numerical rank of matrix B tolb and a subblock of A. Generally, they are set to tola = max(m,n)*norm(A)*macheps, tolb = max(p,n)*norm(B)*macheps. the size of tola and tolb may affect the size of backward errors of the decomposition. k, l on exit, k and l specify the dimension of the subblocks described in purpose. k + l = effective numerical rank of (A',B')'. u if u != NULL, u contains the orthogonal matrix U. if u == NULL, u is not referenced. v if v != NULL, v contains the orthogonal matrix V. if v == NULL, v is not referenced. q if q != NULL, q contains the orthogonal matrix Q. if q == NULL, q is not referenced. Further details =============== The program uses NUMhouseholderQRwithColumnPivoting for the QR factorization to detect the effective numerical rank of the A matrix. It may be replaced by a better rank determination strategy. */ void NUMgsvdcmp (double **a, long m, long n, double **b, long p, int product, long *k, long *l, double *alpha, double *beta, double **u, double **v, double **q, int invertR); /* Computes the generalized singular value decomposition (gsvd) of an m-by-n real matrix A and p-by-n real matrix B: U'*A*Q = D1*( 0 R ), V'*B*Q = D2*( 0 R ) where U, V and Q are orthogonal matrices, and Z' is the transpose of Z. Let k+l = the effective numerical rank of the matrix (A',B')', then R is a k+l-by-k+l nonsingular upper triangular matrix, D1 and D2 are m-by-(k+l) and p-by-(k+l) "diagonal" matrices and of the following structures, respectively: if m-k-l >= 0, k l D1 = k ( I 0 ) l ( 0 C ) m-k-l ( 0 0 ) k l D2 = l ( 0 S ) p-l ( 0 0 ) n-k-l k l ( 0 R ) = k ( 0 R11 R12 ) l ( 0 0 R22 ) where C = Diag( alpha(k+1), ... , alpha(k+l) ), S = Diag( beta(k+1), ... , beta(k+l) ), C**2 + S**2 = I. R is stored in A(1:k+l,n-k-l+1:n) on exit. if m-k-l < 0, k m-k k+l-m D1 = k ( I 0 0 ) m-k ( 0 C 0 ) k m-k k+l-m D2 = m-k ( 0 S 0 ) k+l-m ( 0 0 I ) p-l ( 0 0 0 ) n-k-l k m-k k+l-m ( 0 R ) = k ( 0 R11 R12 R13 ) m-k ( 0 0 R22 R23 ) k+l-m ( 0 0 0 R33 ) where C = diag( alpha(k+1), ... , alpha(m) ), S = diag( beta(k+1), ... , beta(m) ), C**2 + S**2 = I. (R11 R12 R13 ) is stored in A(1:m, n-k-l+1:n), and R33 is stored ( 0 R22 R23 ) in B(m-k+1:l,n+m-k-l+1:n) on exit. The routine computes C, S, R, and optionally the orthogonal transformation matrices U, V and Q. In particular, if B is an n-by-n nonsingular matrix and product == 0, then the gsvd of A and B implicitly gives the (quotient) svd of A * inv(B): A * inv(B) = U*(D1*inv(D2))*V', If product != 0 then the gsvd of A and B implicitly gives the product svd of A * B: A * B = U * (D1 * D2) * V'. If ( A',B')' has orthonormal columns, then the gsvd of A and B is also equal to the CS decomposition of A and B. Furthermore, the gsvd can be used to derive the solution of the eigenvalue problem: A'*A x = lambda* B'*B x. In some literature, the gsvd of A and B is presented in the form U'*A*X = ( 0 D1 ), V'*B*X = ( 0 D2 ) where U and V are orthogonal and X is nonsingular, D1 and D2 are ``diagonal''. The former gsvd form can be converted to the latter form by taking the nonsingular matrix X as X = Q*( I 0 ) ( 0 inv(R) ). arguments ========= a on entry, the m-by-n matrix A. on exit, a contains the triangular matrix R, or part of R. see purpose for details. m the number of rows of the matrix A. m > 0. n the number of columns of the matrices A and B. n > 0. b on entry, the p-by-n matrix B. on exit, b contains the triangular matrix R if m-k-l < 0. see purpose for details. p the number of rows of the matrix B. p > 0. k, l on exit, k and l specify the dimension of the subblocks described in the purpose section. k + l = effective numerical rank of (A',B')'. product svd of A * B instead of A * inv (B). Watch out: you can only use product=0 (i.e. QSVD). alpha, on exit, alpha and beta contain the generalized singular beta value pairs of A and B; alpha(1:k) = 1, beta(1:k) = 0, and if m-k-l >= 0, alpha(k+1:k+l) = C, beta(k+1:k+l) = S, or if m-k-l < 0, alpha(k+1:m)=C, alpha(m+1:k+l)=0 beta(k+1:m) =S, beta(m+1:k+l) =1 and alpha(k+l+1:n) = 0 beta(k+l+1:n) = 0 u if u != NULL, u contains the m-by-m orthogonal matrix U. if u == NULL, u is not referenced. v if v != NULL, v contains the p-by-p orthogonal matrix V. if v == NULL, v is not referenced. q if q != NULL, q contains the n-by-n orthogonal matrix Q. if q == NULL, q is not referenced. Internal parameters =================== tola double tolb double tola and tolb are the thresholds to determine the effective rank of (A',B')'. Generally, they are set to tola = max(m,n) * norm(A) * macheps, tolb = max(p,n) * norm(B) * macheps. the size of tola and tolb may affect the size of backward errors of the decomposition. */ void NUMtriangularInverse (int upper, int unitDiagonal, long n, double **a); /* Computes inverse of triangular matrix. */ #endif /* _NUMlapack_h_ */ praat-6.0.04/dwsys/NUMmachar.cpp000066400000000000000000000043411261542461700164120ustar00rootroot00000000000000/* NUMmachar.c * * Copyright (C) 1994-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020812 GPL header */ #include "NUMmachar.h" #include "melder.h" #ifndef _NUMcblas_h_ #include "NUMcblas.h" #endif static struct structmachar_Table machar_table; machar_Table NUMfpp = NULL; /* Floating point properties: NR LAPACK dlamch ibeta base 'B' base of the machine it t 'N' number of (base) digits in the mantissa machep eps prec 'P' eps*base ('quantization step') negep epsneg eps 'E' relative machine precision ('quantization error') iexp minexp emin 'M' minimum exponent before (gradual) underflow xmin rmin 'U' underflow threshold - base**(emin-1) maxexp emax 'U' largest exponent before overflow xmax rmax 'O' overflow threshold - (base**emax)*(1-eps) irnd rnd 'R' 1 when rounding occurs in addition, 0 otherwise ngrd sfmin 'S' safe minimum, such that 1/sfmin does not overflow */ void NUMmachar () { if (NUMfpp) { return; } NUMfpp = & machar_table; NUMfpp -> base = (int) NUMblas_dlamch ("Base"); NUMfpp -> t = (int) NUMblas_dlamch ("Number of digits in mantissa"); NUMfpp -> emin = (int) NUMblas_dlamch ("Minimum exponent"); NUMfpp -> emax = (int) NUMblas_dlamch ("Largest exponent"); NUMfpp -> rnd = (int) NUMblas_dlamch ("Rounding mode"); NUMfpp -> prec = NUMblas_dlamch ("Precision"); NUMfpp -> eps = NUMblas_dlamch ("Epsilon"); NUMfpp -> rmin = NUMblas_dlamch ("Underflow threshold"); NUMfpp -> sfmin = NUMblas_dlamch ("Safe minimum"); NUMfpp -> rmax = NUMblas_dlamch ("Overflow threshold"); } /* End of file NUMmachar.c */ praat-6.0.04/dwsys/NUMmachar.h000066400000000000000000000031301261542461700160520ustar00rootroot00000000000000#ifndef _NUMmachar_h_ #define _NUMmachar_h_ /* NUMmachar.h * * Copyright (C) 1994-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020812 GPL header djmw 20110308 Latest modification */ struct structmachar_Table { int base; /* Radix in which numbers are presented. */ int t; /* Number of base digits in mantissa*/ int emin; /* Minimum exponent before (gradual) underflow */ int emax; /* Largest exponent before overflow */ int rnd; /* 1 when rounding occurs in addition, 0 otherwise */ double prec; /* Quantization step (eps*base) */ double eps; /* Quantization error (relative machine precision) */ double rmin; /* Underflow threshold - base**(emin-1) */ double sfmin; /* Safe minimum, such that 1/sfmin does not overflow */ double rmax; /* Overflow threshold - (base**emax)*(1-eps)*/ }; typedef struct structmachar_Table *machar_Table; extern machar_Table NUMfpp; void NUMmachar (); #endif /* _NUMmachar_h_ */ praat-6.0.04/dwsys/NUMmathlib.cpp000066400000000000000000000437721261542461700166120ustar00rootroot00000000000000/* * Mathlib : A C Library of Special Functions * Copyright (C) 1998 Ross Ihaka * Copyright (C) 2000--2007 The R Core Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, a copy is available at * http://www.r-project.org/Licenses/ * * SYNOPSIS * * #include * double ptukey(q, rr, cc, df, lower_tail, log_p); * * DESCRIPTION * * Computes the probability that the maximum of rr studentized * ranges, each based on cc means and with df degrees of freedom * for the standard error, is less than q. * * The algorithm is based on that of the reference. * * REFERENCE * * Copenhaver, Margaret Diponzio & Holland, Burt S. * Multiple comparisons of simple effects in * the two-way analysis of variance with fixed effects. * Journal of Statistical Computation and Simulation, * Vol.30, pp.1-15, 1988. */ #include "NUM2.h" #define R_Q_P01_boundaries(p, _LEFT_, _RIGHT_) \ if (log_p) { \ if(p > 0) \ return NUMundefined; \ if(p == 0) /* upper bound*/ \ return lower_tail ? _RIGHT_ : _LEFT_; \ if(p == NUMundefined) /* cannot occur*/ \ return lower_tail ? _LEFT_ : _RIGHT_; \ } else { /* !log_p */ \ if(p < 0 || p > 1) \ return NUMundefined; \ if(p == 0) \ return lower_tail ? _LEFT_ : _RIGHT_; \ if(p == 1) \ return lower_tail ? _RIGHT_ : _LEFT_; \ } #define R_D_Lval(p) (lower_tail ? (p) : (0.5 - (p) + 0.5)) #define R_DT_qIv(p) (log_p ? (lower_tail ? exp(p) : - expm1(p)) : R_D_Lval(p)) #define R_D__0 (log_p ? NUMundefined : 0.) /* 0 */ #define R_D__1 (log_p ? 0. : 1.) /* 1 */ #define R_DT_0 (lower_tail ? R_D__0 : R_D__1) /* 0 */ #define R_DT_1 (lower_tail ? R_D__1 : R_D__0) /* 1 */ #define R_D_val(x) (log_p ? log(x) : (x)) #define R_D_Clog(p) (log_p ? log1p(-(p)) : (0.5 - (p) + 0.5)) /* [log](1-p) */ #define R_DT_val(x) (lower_tail ? R_D_val(x) : R_D_Clog(x)) static double wprob(double w, double rr, double cc) { /* wprob() : This function calculates probability integral of Hartley's form of the range. w = value of range rr = no. of rows or groups cc = no. of columns or treatments ir = error flag = 1 if pr_w probability > 1 pr_w = returned probability integral from (0, w) program will not terminate if ir is raised. bb = upper limit of legendre integration iMax = maximum acceptable value of integral nleg = order of legendre quadrature ihalf = int ((nleg + 1) / 2) wlar = value of range above which wincr1 intervals are used to calculate second part of integral, else wincr2 intervals are used. C1, C2, C3 = values which are used as cutoffs for terminating or modifying a calculation. M_1_SQRT_2PI = 1 / sqrt(2 * pi); from abramowitz & stegun, p. 3. M_SQRT2 = sqrt(2) xleg = legendre 12-point nodes aleg = legendre 12-point coefficients */ #define nleg 12 #define ihalf 6 /* looks like this is suboptimal for double precision. (see how C1-C3 are used) */ /* const double iMax = 1.; not used if = 1*/ const static double C1 = -30.; const static double C2 = -50.; const static double C3 = 60.; const static double bb = 8.; const static double wlar = 3.; const static double wincr1 = 2.; const static double wincr2 = 3.; const static double xleg[ihalf] = { 0.981560634246719250690549090149, 0.904117256370474856678465866119, 0.769902674194304687036893833213, 0.587317954286617447296702418941, 0.367831498998180193752691536644, 0.125233408511468915472441369464 }; const static double aleg[ihalf] = { 0.047175336386511827194615961485, 0.106939325995318430960254718194, 0.160078328543346226334652529543, 0.203167426723065921749064455810, 0.233492536538354808760849898925, 0.249147045813402785000562436043 }; double a, ac, pr_w, b, binc, c, cc1, pminus, pplus, qexpo, qsqz, rinsum, wi, wincr, xx; long double blb, bub, einsum, elsum; int j, jj; qsqz = w * 0.5; /* if w >= 16 then the integral lower bound (occurs for c=20) */ /* is 0.99999999999995 so return a value of 1. */ if (qsqz >= bb) return 1.0; /* find (f(w/2) - 1) ^ cc */ /* (first term in integral of hartley's form). */ // djwm: pnorm(q,m,s,1,0) = NUMgaussP((q-m)/s) // pr_w = 2 * pnorm(qsqz, 0.,1., 1,0) - 1.; /* erf(qsqz / M_SQRT2) */ pr_w = 2 * NUMgaussP (qsqz) - 1.0; /* if pr_w ^ cc < 2e-22 then set pr_w = 0 */ if (pr_w >= exp(C2 / cc)) pr_w = pow(pr_w, cc); else pr_w = 0.0; /* if w is large then the second component of the */ /* integral is small, so fewer intervals are needed. */ if (w > wlar) wincr = wincr1; else wincr = wincr2; /* find the integral of second term of hartley's form */ /* for the integral of the range for equal-length */ /* intervals using legendre quadrature. limits of */ /* integration are from (w/2, 8). two or three */ /* equal-length intervals are used. */ /* blb and bub are lower and upper limits of integration. */ blb = qsqz; binc = (bb - qsqz) / wincr; bub = blb + binc; einsum = 0.0; /* integrate over each interval */ cc1 = cc - 1.0; for (wi = 1; wi <= wincr; wi++) { elsum = 0.0; a = (double)(0.5 * (bub + blb)); /* legendre quadrature with order = nleg */ b = (double)(0.5 * (bub - blb)); for (jj = 1; jj <= nleg; jj++) { if (ihalf < jj) { j = (nleg - jj) + 1; xx = xleg[j-1]; } else { j = jj; xx = -xleg[j-1]; } c = b * xx; ac = a + c; /* if exp(-qexpo/2) < 9e-14, */ /* then doesn't contribute to integral */ qexpo = ac * ac; if (qexpo > C3) break; pplus = 2 * NUMgaussP (ac); // djmw: 2 * pnorm(ac, 0., 1., 1,0); pminus= 2 * NUMgaussP (ac - w); // djmw: 2 * pnorm(ac, w, 1., 1,0); /* if rinsum ^ (cc-1) < 9e-14, */ /* then doesn't contribute to integral */ rinsum = (pplus * 0.5) - (pminus * 0.5); if (rinsum >= exp(C1 / cc1)) { rinsum = (aleg[j-1] * exp(-(0.5 * qexpo))) * pow(rinsum, cc1); elsum += rinsum; } } elsum *= (((2.0 * b) * cc) * NUM1_sqrt2pi); einsum += elsum; blb = bub; bub += binc; } /* if pr_w ^ rr < 9e-14, then return 0 */ pr_w += (double) einsum; if (pr_w <= exp(C1 / rr)) return 0.; pr_w = pow(pr_w, rr); if (pr_w >= 1.)/* 1 was iMax was eps */ return 1.; return pr_w; } /* wprob() */ static double ptukey(double q, double rr, double cc, double df, int lower_tail, int log_p) { /* function ptukey() [was qprob() ]: q = value of studentized range rr = no. of rows or groups cc = no. of columns or treatments df = degrees of freedom of error term ir[0] = error flag = 1 if wprob probability > 1 ir[1] = error flag = 1 if qprob probability > 1 qprob = returned probability integral over [0, q] The program will not terminate if ir[0] or ir[1] are raised. All references in wprob to Abramowitz and Stegun are from the following reference: Abramowitz, Milton and Stegun, Irene A. Handbook of Mathematical Functions. New York: Dover publications, Inc. (1970). All constants taken from this text are given to 25 significant digits. nlegq = order of legendre quadrature ihalfq = int ((nlegq + 1) / 2) eps = max. allowable value of integral eps1 & eps2 = values below which there is no contribution to integral. d.f. <= dhaf: integral is divided into ulen1 length intervals. else d.f. <= dquar: integral is divided into ulen2 length intervals. else d.f. <= deigh: integral is divided into ulen3 length intervals. else d.f. <= dlarg: integral is divided into ulen4 length intervals. d.f. > dlarg: the range is used to calculate integral. M_LN2 = log(2) xlegq = legendre 16-point nodes alegq = legendre 16-point coefficients The coefficients and nodes for the legendre quadrature used in qprob and wprob were calculated using the algorithms found in: Stroud, A. H. and Secrest, D. Gaussian Quadrature Formulas. Englewood Cliffs, New Jersey: Prentice-Hall, Inc, 1966. All values matched the tables (provided in same reference) to 30 significant digits. f(x) = .5 + erf(x / sqrt(2)) / 2 for x > 0 f(x) = erfc( -x / sqrt(2)) / 2 for x < 0 where f(x) is standard normal c. d. f. if degrees of freedom large, approximate integral with range distribution. */ #define nlegq 16 #define ihalfq 8 /* const double eps = 1.0; not used if = 1 */ const static double eps1 = -30.0; const static double eps2 = 1.0e-14; const static double dhaf = 100.0; const static double dquar = 800.0; const static double deigh = 5000.0; const static double dlarg = 25000.0; const static double ulen1 = 1.0; const static double ulen2 = 0.5; const static double ulen3 = 0.25; const static double ulen4 = 0.125; const static double xlegq[ihalfq] = { 0.989400934991649932596154173450, 0.944575023073232576077988415535, 0.865631202387831743880467897712, 0.755404408355003033895101194847, 0.617876244402643748446671764049, 0.458016777657227386342419442984, 0.281603550779258913230460501460, 0.950125098376374401853193354250e-1 }; const static double alegq[ihalfq] = { 0.271524594117540948517805724560e-1, 0.622535239386478928628438369944e-1, 0.951585116824927848099251076022e-1, 0.124628971255533872052476282192, 0.149595988816576732081501730547, 0.169156519395002538189312079030, 0.182603415044923588866763667969, 0.189450610455068496285396723208 }; double ans, f2, f21, f2lf, ff4, otsum, qsqz, rotsum, t1, twa1, ulen, wprb; int i, j, jj; if (q == NUMundefined || rr == NUMundefined || cc == NUMundefined || df == NUMundefined) { return NUMundefined; } if (q <= 0) return R_DT_0; /* df must be > 1 */ /* there must be at least two values */ if (df < 2 || rr < 1 || cc < 2) { return NUMundefined; } // if(q == NUMundefined) { return R_DT_1; } if (df > dlarg) return R_DT_val(wprob(q, rr, cc)); /* calculate leading constant */ f2 = df * 0.5; /* lgammafn(u) = log(gamma(u)) */ f2lf = ((f2 * log(df)) - (df * NUMln2)) - NUMlnGamma (f2); //lgammafn(f2); f21 = f2 - 1.0; /* integral is divided into unit, half-unit, quarter-unit, or */ /* eighth-unit length intervals depending on the value of the */ /* degrees of freedom. */ ff4 = df * 0.25; if (df <= dhaf) ulen = ulen1; else if (df <= dquar) ulen = ulen2; else if (df <= deigh) ulen = ulen3; else ulen = ulen4; f2lf += log(ulen); /* integrate over each subinterval */ ans = 0.0; for (i = 1; i <= 50; i++) { otsum = 0.0; /* legendre quadrature with order = nlegq */ /* nodes (stored in xlegq) are symmetric around zero. */ twa1 = (2 * i - 1) * ulen; for (jj = 1; jj <= nlegq; jj++) { if (ihalfq < jj) { j = jj - ihalfq - 1; t1 = (f2lf + (f21 * log(twa1 + (xlegq[j] * ulen)))) - (((xlegq[j] * ulen) + twa1) * ff4); } else { j = jj - 1; t1 = (f2lf + (f21 * log(twa1 - (xlegq[j] * ulen)))) + (((xlegq[j] * ulen) - twa1) * ff4); } /* if exp(t1) < 9e-14, then doesn't contribute to integral */ if (t1 >= eps1) { if (ihalfq < jj) { qsqz = q * sqrt(((xlegq[j] * ulen) + twa1) * 0.5); } else { qsqz = q * sqrt(((-(xlegq[j] * ulen)) + twa1) * 0.5); } /* call wprob to find integral of range portion */ wprb = wprob(qsqz, rr, cc); rotsum = (wprb * alegq[j]) * exp(t1); otsum += rotsum; } /* end legendre integral for interval i */ /* L200: */ } /* if integral for interval i < 1e-14, then stop. * However, in order to avoid small area under left tail, * at least 1 / ulen intervals are calculated. */ if (i * ulen >= 1.0 && otsum <= eps2) break; /* end of interval i */ /* L330: */ ans += otsum; } if(otsum > eps2) { /* not converged */ Melder_throw (U"Not converged"); } if (ans > 1.) ans = 1.; return R_DT_val(ans); } /* * Mathlib : A C Library of Special Functions * Copyright (C) 1998 Ross Ihaka * Copyright (C) 2000--2005 The R Core Team * based in part on AS70 (C) 1974 Royal Statistical Society * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, a copy is available at * http://www.r-project.org/Licenses/ * * SYNOPSIS * * double qtukey(p, rr, cc, df, lower_tail, log_p); * * DESCRIPTION * * Computes the quantiles of the maximum of rr studentized * ranges, each based on cc means and with df degrees of freedom * for the standard error, is less than q. * * The algorithm is based on that of the reference. * * REFERENCE * * Copenhaver, Margaret Diponzio & Holland, Burt S. * Multiple comparisons of simple effects in * the two-way analysis of variance with fixed effects. * Journal of Statistical Computation and Simulation, * Vol.30, pp.1-15, 1988. */ /* qinv() : * this function finds percentage point of the studentized range * which is used as initial estimate for the secant method. * function is adapted from portion of algorithm as 70 * from applied statistics (1974) ,vol. 23, no. 1 * by odeh, r. e. and evans, j. o. * * p = percentage point * c = no. of columns or treatments * v = degrees of freedom * qinv = returned initial estimate * * vmax is cutoff above which degrees of freedom * is treated as infinity. */ static double qinv(double p, double c, double v) { const static double p0 = 0.322232421088; const static double q0 = 0.993484626060e-01; const static double p1 = -1.0; const static double q1 = 0.588581570495; const static double p2 = -0.342242088547; const static double q2 = 0.531103462366; const static double p3 = -0.204231210125; const static double q3 = 0.103537752850; const static double p4 = -0.453642210148e-04; const static double q4 = 0.38560700634e-02; const static double c1 = 0.8832; const static double c2 = 0.2368; const static double c3 = 1.214; const static double c4 = 1.208; const static double c5 = 1.4142; const static double vmax = 120.0; double ps, q, t, yi; ps = 0.5 - 0.5 * p; yi = sqrt (log (1.0 / (ps * ps))); t = yi + (((( yi * p4 + p3) * yi + p2) * yi + p1) * yi + p0) / (((( yi * q4 + q3) * yi + q2) * yi + q1) * yi + q0); if (v < vmax) t += (t * t * t + t) / v / 4.0; q = c1 - c2 * t; if (v < vmax) q += -c3 / v + c4 * t / v; return t * (q * log (c - 1.0) + c5); } /* * Copenhaver, Margaret Diponzio & Holland, Burt S. * Multiple comparisons of simple effects in * the two-way analysis of variance with fixed effects. * Journal of Statistical Computation and Simulation, * Vol.30, pp.1-15, 1988. * * Uses the secant method to find critical values. * * p = confidence level (1 - alpha) * rr = no. of rows or groups * cc = no. of columns or treatments * df = degrees of freedom of error term * * ir(1) = error flag = 1 if wprob probability > 1 * ir(2) = error flag = 1 if ptukey probability > 1 * ir(3) = error flag = 1 if convergence not reached in 50 iterations * = 2 if df < 2 * * qtukey = returned critical value * * If the difference between successive iterates is less than eps, * the search is terminated */ static double qtukey(double p, double rr, double cc, double df, int lower_tail, int log_p) { const static double eps = 0.0001; const int maxiter = 50; double ans = 0.0, valx0, valx1, x0, x1, xabs; int iter; if (p == NUMundefined || rr == NUMundefined || cc == NUMundefined || df == NUMundefined) { return NUMundefined; } /* df must be > 1 ; there must be at least two values */ if (df < 2 || rr < 1 || cc < 2) { return NUMundefined; } //R_Q_P01_boundaries(p, 0, ML_POSINF); R_Q_P01_boundaries(p, 0, NUMundefined); p = R_DT_qIv(p); /* lower_tail,non-log "p" */ /* Initial value */ x0 = qinv (p, cc, df); /* Find prob(value < x0) */ valx0 = ptukey (x0, rr, cc, df, /*LOWER*/TRUE, /*LOG_P*/FALSE) - p; /* Find the second iterate and prob(value < x1). */ /* If the first iterate has probability value */ /* exceeding p then second iterate is 1 less than */ /* first iterate; otherwise it is 1 greater. */ if (valx0 > 0.0) x1 = x0 > 1 ? x0 - 1 : 0; // djmw: fmax2 (0.0, x0 - 1.0); else x1 = x0 + 1.0; valx1 = ptukey(x1, rr, cc, df, /*LOWER*/TRUE, /*LOG_P*/FALSE) - p; /* Find new iterate */ for(iter=1 ; iter < maxiter ; iter++) { ans = x1 - ((valx1 * (x1 - x0)) / (valx1 - valx0)); valx0 = valx1; /* New iterate must be >= 0 */ x0 = x1; if (ans < 0.0) { ans = 0.0; valx1 = -p; } /* Find prob(value < new iterate) */ valx1 = ptukey(ans, rr, cc, df, /*LOWER*/TRUE, /*LOG_P*/FALSE) - p; x1 = ans; /* If the difference between two successive */ /* iterates is less than eps, stop */ xabs = fabs(x1 - x0); if (xabs < eps) return ans; } /* The process did not converge in 'maxiter' iterations */ Melder_warning (U"Maximum number of iterations exceeded."); return ans; } double NUMinvTukeyQ (double p, double cc, double df, double rr) { return qtukey (p, rr, cc, df, 0, 0); } double NUMtukeyQ (double q, double cc, double df, double rr) { return ptukey (q, rr, cc, df, 0, 0); } praat-6.0.04/dwsys/NUMsort2.cpp000066400000000000000000000134451261542461700162350ustar00rootroot00000000000000/* NUMsort.cpp * * Copyright (C) 1993-2012 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20030121 Initial version djmw 20030627 Removed bug in MACRO_NUMindex djmw 20120305 Latest modification */ #include "NUM2.h" #include "melder.h" /* NUMsort2 uses heapsort to sort the second array in parallel with the first one. Algorithm follows p. 145 and 642 in: Donald E. Knuth (1998): The art of computer programming. Third edition. Vol. 3: sorting and searching. Boston: Addison-Wesley, printed may 2002. Modification: there is no distinction between record and key and Floyd's optimization (page 642) is used. */ void NUMrankColumns (double **m, long rb, long re, long cb, long ce) { long nr = re - rb + 1; autoNUMvector v (1, nr); autoNUMvector index (1, nr); for (long j = cb; j <= ce; j++) { for (long i = 1; i <= nr; i++) { v[i] = m[rb + i - 1][j]; } for (long i = 1; i <= nr; i++) { index[i] = i; } NUMsort2 (nr, v.peek(), index.peek()); NUMrank (nr, v.peek()); for (long i = 1; i <= nr; i++) { m[rb + index[i] - 1][j] = v[i]; } } } template void NUMindexx (const T a[], long n, long index[], int (*compare) (void *, void *)) { long ii, imin; T min; for (long j = 1; j <= n; j++) { index[j] = j; } if (n < 2) return; // Already sorted if (n == 2) { if (COMPARELT(a[2], a[1])) { index[1] = 2; index[2] = 1; } return; } if (n <= 12) { for (long i = 1; i < n; i++) { imin = i; min = a[index[imin]]; for (long j = i + 1; j <= n; j++) { if (COMPARELT(a[index[j]], min)) { imin = j; min = a[index[j]]; } } ii = index[imin]; index[imin] = index[i]; index[i] = ii; } return; } // H1 long l = n / 2 + 1, r = n; for (;;) { // H2 long k, i; if (l > 1) { l--; k = index[l]; } else { // l == 1 k = index[r]; index[r] = index[1]; r--; if (r == 1) { index[1] = k; break; } } // H3 long j = l; for (;;) { // H4 i = j; j *= 2; if (j > r) { break; } if (j < r && COMPARELT (a[index[j]], a[index[j + 1]])) { j++; // H5 } index[i] = index[j]; // H7 } for (;;) { // H8' j = i; i = j >> 1; // H9' if (j == l || COMPARELT (a[k], a[index[i]])) { index[j] = k; break; } index[j] = index[i]; } } } #define MACRO_NUMindex(TYPE) \ { \ long l, r, j, i, ii, k, imin; \ TYPE min; \ for (j = 1; j <= n; j++) index[j] = j; \ if (n < 2) return; /* Already sorted. */ \ if (n == 2) \ { \ if (COMPARELT(a[2], a[1])) \ {\ index[1] = 2; index[2] = 1; \ } \ return; \ } \ if (n <= 12) \ { \ for (i = 1; i < n; i++) \ { \ imin = i; \ min = a[index[imin]]; \ for (j = i + 1; j <= n; j++) \ {\ if (COMPARELT(a[index[j]], min))\ { \ imin = j; \ min = a[index[j]]; \ } \ } \ ii = index[imin]; index[imin] = index[i]; index[i] = ii; \ } \ return; \ } \ /* H1 */\ l = n / 2 + 1; \ r = n; \ for (;;) /* H2 */\ { \ if (l > 1) \ { \ l--; \ k = index[l]; \ } \ else /* l == 1 */ \ { \ k = index[r]; \ index[r] = index[1]; \ r--; \ if (r == 1) \ { \ index[1] = k; break; \ } \ } \ /* H3 */ \ j = l; \ for (;;) \ { \ /* H4 */ \ i = j; \ j *= 2; \ if (j > r) break; \ if (j < r && COMPARELT (a[index[j]], a[index[j + 1]])) j++; /* H5 */\ index[i] = index[j]; /* H7 */\ } \ for (;;) /*H8' */\ {\ j = i; \ i = j >> 1; \ /* H9' */ \ if (j == l || COMPARELT (a[k], a[index[i]])) \ { \ index[j] = k; break; \ } \ index[j] = index[i]; \ }\ } \ } #define COMPARELT(x,y) ((x) < (y)) void NUMindexx (const double a[], long n, long index[]) MACRO_NUMindex (double) #undef COMPARELT #define COMPARELT(x,y) (Melder_cmp (x,y) < 0) void NUMindexx_s (char32 **a, long n, long index[]) MACRO_NUMindex (char32 *) #undef COMPARELT #undef MACRO_INDEXX template void NUMsort1 (long n, T a[]) { /* Knuth's heapsort algorithm (vol. 3, page 145), modified with Floyd's optimization (vol. 3, page 642). */ T min; if (n < 2) return; // Already sorted. /* This n<2 step is absent from Press et al.'s implementation, which will therefore not terminate on if(--ir==1). Knuth's initial assumption is now fulfilled: n >= 2. */ if (n == 2) { if (a[1] > a[2]) { min = a[2]; a[2] = a[1]; a[1] = min; } return; } if (n <= 12) { long imin; for (long i = 1; i < n; i++) { min = a[i]; imin = i; for (long j = i + 1; j <= n; j++) { if (a[j] < min) { min = a [j]; imin = j; } } a[imin] = a[i]; a[i] = min; } return; } // H1 long l = (n >> 1) + 1, r = n; for (;;) { // H2 T ak; if (l > 1) { l--; ak = a[l]; } else { // l == 1 ak = a[r]; a[r] = a[1]; r--; if (r == 1) { a[1] = ak; return; } } // H3 long i, j = l; for (;;) { // H4 i = j; j = j << 1; if (j > r) { break; } if (j < r && a[j] < a[j + 1]) { j++; // H5 } // if (k >= a[j]) break; a[i] = a[j]; // H7 } // a[i] = k; H8 for (;;) { // H8' j = i; i = j >> 1; // H9' if (j == l || ak <= a[i]) { a[j] = ak; break; } a[j] = a[i]; } } } /* End of file NUMsort.cpp */ praat-6.0.04/dwsys/NUMstring.cpp000066400000000000000000000356621261542461700164770ustar00rootroot00000000000000/* NUMstring.cpp * * Copyright (C) 2012 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20121005 First version */ #include #include #include "Interpreter.h" #include "NUM2.h" int NUMstring_containsPrintableCharacter (const char32 *s) { long len; if (s == NULL || ( (len = str32len (s)) == 0)) { return 0; } for (long i = 0; i < len; i++) { if (isgraph ((int) s[i])) { return 1; } } return 0; } void NUMstring_chopWhiteSpaceAtExtremes_inline (char32 *string) { int64 start = 0; while (iswspace ((int) string[start]) != 0) { start++; } int64 end = str32len (string); while (end != start && iswspace((int) string[end - 1]) != 0) { end--; } int64 n = end - start; memmove (string, string + start, (size_t) (n * (int64) sizeof (char32))); string[n] = 0; } double *NUMstring_to_numbers (const char32 *s, long *numbers_found) { *numbers_found = Melder_countTokens (s); if (*numbers_found < 1) { Melder_throw (U"Empty string."); } autoNUMvector numbers (1, *numbers_found); long inum = 1; for (char32 *token = Melder_firstToken (s); token != 0; token = Melder_nextToken (), inum++) { Interpreter_numericExpression (0, token, &numbers[inum]); } return numbers.transfer(); } void NUMstrings_copyElements (char32 **from, char32 **to, long lo, long hi) { for (long i = lo; i <= hi; i++) { Melder_free (to[i]); if (from[i]) { to[i] = Melder_dup (from[i]); } } } void NUMstrings_free (char32 **s, long lo, long hi) { if (s == NULL) { return; } for (long i = lo; i <= hi; i++) { Melder_free (s[i]); } NUMvector_free (s, lo); } char32 **NUMstrings_copy (char32 **from, long lo, long hi) { autoNUMvector to (lo, hi); NUMstrings_copyElements (from, to.peek(), lo, hi); return to.transfer(); } static char32 *appendNumberToString (const char32 *s, long number, int asArray) { return Melder_dup ( asArray == 0 ? Melder_cat (s, number) : asArray == 1 ? Melder_cat (s, U"[", number, U"]") : Melder_cat (s, U"(", number, U")")); } int NUMstrings_setSequentialNumbering (char32 **s, long lo, long hi, const char32 *pre, long number, long increment, int asArray) { for (long i = lo; i <= hi; i++, number += increment) { char32 *newc = appendNumberToString (pre, number, asArray); if (newc == NULL) { return 0; } Melder_free (s[i]); s[i] = newc; } return 1; } #define HIGHBYTE(x) ((unsigned char) ((x) & 0xFF)) #define LOWBYTE(x) ((unsigned char) ((x) >> 8 & 0xFF)) /* a+b=c in radix 256 */ void NUMstring_add (unsigned char *a, unsigned char *b, unsigned char *c, long n); void NUMstring_add (unsigned char *a, unsigned char *b, unsigned char *c, long n) { int j; unsigned short reg = 0; for (j = n; j > 1; j--) { reg = a[j] + b[j] + HIGHBYTE (reg); c[j + 1] = LOWBYTE (reg); } } char32 *strstr_regexp (const char32 *string, const char32 *search_regexp) { char32 *charp = 0; regexp *compiled_regexp = CompileRE_throwable (search_regexp, 0); if (ExecRE (compiled_regexp, NULL, string, NULL, 0, '\0', '\0', NULL, NULL, NULL)) { charp = compiled_regexp -> startp[0]; } free (compiled_regexp); return charp; } char32 *str_replace_literal (const char32 *string, const char32 *search, const char32 *replace, long maximumNumberOfReplaces, long *nmatches) { if (string == 0 || search == 0 || replace == 0) { return NULL; } int len_string = str32len (string); if (len_string == 0) { maximumNumberOfReplaces = 1; } int len_search = str32len (search); if (len_search == 0) { maximumNumberOfReplaces = 1; } /* To allocate memory for 'result' only once, we have to know how many matches will occur. */ const char32 *pos = string; //current position / start of current match *nmatches = 0; if (maximumNumberOfReplaces <= 0) { maximumNumberOfReplaces = LONG_MAX; } if (len_search == 0) { /* Search is empty string... */ if (len_string == 0) { *nmatches = 1; /* ...only matches empty string */ } } else { if (len_string != 0) { /* Because empty string always matches */ while ( (pos = str32str (pos, search)) && *nmatches < maximumNumberOfReplaces) { pos += len_search; (*nmatches) ++; } } } int64 len_replace = str32len (replace); int64 len_result = len_string + *nmatches * (len_replace - len_search); char32 *result = Melder_malloc (char32, (len_result + 1) * (int64) sizeof (char32)); result[len_result] = '\0'; const char32 *posp = pos = string; int nchar = 0, result_nchar = 0; for (long i = 1; i <= *nmatches; i++) { pos = str32str (pos, search); /* Copy gap between end of previous match and start of current. */ nchar = (pos - posp); if (nchar > 0) { str32ncpy (result + result_nchar, posp, nchar); result_nchar += nchar; } /* Insert the replace string in result. */ str32ncpy (result + result_nchar, replace, len_replace); result_nchar += len_replace; /* Next search starts after the match. */ pos += len_search; posp = pos; } /* Copy gap between end of match and end of string. */ pos = string + len_string; nchar = pos - posp; if (nchar > 0) { str32ncpy (result + result_nchar, posp, nchar); } return result; } char32 *str_replace_regexp (const char32 *string, regexp *compiledSearchRE, const char32 *replaceRE, long maximumNumberOfReplaces, long *nmatches) { int buf_nchar = 0; /* # characters in 'buf' */ int gap_copied = 0; int nchar, reverse = 0; int errorType; char32 prev_char = '\0'; const char32 *pos; /* current position in 'string' / start of current match */ const char32 *posp; /* end of previous match */ autostring32 buf; *nmatches = 0; if (string == 0 || compiledSearchRE == 0 || replaceRE == 0) { return 0; } int string_length = str32len (string); //int replace_length = str32len (replaceRE); if (string_length == 0) { maximumNumberOfReplaces = 1; } long i = maximumNumberOfReplaces > 0 ? 0 : - string_length; /* We do not know the size of the replaced string in advance, therefor, we allocate a replace buffer twice the size of the original string. After all replaces have taken place we do a final realloc to the then exactly known size. If during the replace, the size of the buffer happens to be too small (this is signalled by the replaceRE function), we double its size and restart the replace. */ int buf_size = 2 * string_length; buf_size = buf_size < 100 ? 100 : buf_size; buf.resize (buf_size); pos = posp = string; while (ExecRE (compiledSearchRE, 0, pos, 0, reverse, prev_char, '\0', 0, 0, 0) && i++ < maximumNumberOfReplaces) { /* Copy gap between the end of the previous match and the start of the current match. Check buffer overflow. pos == posp ? '\0' : pos[-1], */ pos = compiledSearchRE -> startp[0]; nchar = pos - posp; if (nchar > 0 && ! gap_copied) { if (buf_nchar + nchar + 1 > buf_size) { buf_size *= 2; buf.resize (buf_size); } str32ncpy (buf.peek() + buf_nchar, posp, nchar); buf_nchar += nchar; } gap_copied = 1; /* Do the substitution. We can only check afterwards for buffer overflow. SubstituteRE puts null byte at last replaced position and signals when overflow. */ if ( (SubstituteRE (compiledSearchRE, replaceRE, buf.peek() + buf_nchar, buf_size - buf_nchar, &errorType)) == false) { if (errorType == 1) { // not enough memory buf_size *= 2; buf.resize (buf_size); Melder_clearError (); i--; // retry continue; } Melder_throw (U"Error during substitution."); } // Buffer is not full, get number of characters added; nchar = str32len (buf.peek() + buf_nchar); buf_nchar += nchar; // Update next start position in search string. posp = pos; pos = (char32 *) compiledSearchRE -> endp[0]; if (pos != posp) { prev_char = pos[-1]; } gap_copied = 0; posp = pos; //pb 20080121 (*nmatches) ++; // at end of string? // we need this because .* matches at end of a string if (pos - string == string_length) { break; } } // Copy last part of string to destination string nchar = (string + string_length) - pos; buf_size = buf_nchar + nchar + 1; buf.resize (buf_size); str32ncpy (buf.peek() + buf_nchar, pos, nchar); buf[buf_size - 1] = '\0'; return buf.transfer(); } static char32 **strs_replace_literal (char32 **from, long lo, long hi, const char32 *search, const char32 *replace, int maximumNumberOfReplaces, long *nmatches, long *nstringmatches) { if (search == NULL || replace == NULL) { return NULL; } autostring32vector result (lo, hi); long nmatches_sub = 0; *nmatches = 0; *nstringmatches = 0; for (long i = lo; i <= hi; i++) { /* Treat a NULL as an empty string */ const char32 *string = from[i] == NULL ? U"" : from[i]; result[i] = str_replace_literal (string, search, replace, maximumNumberOfReplaces, &nmatches_sub); if (nmatches_sub > 0) { *nmatches += nmatches_sub; (*nstringmatches) ++; } } return result.transfer(); } static char32 **strs_replace_regexp (char32 **from, long lo, long hi, const char32 *searchRE, const char32 *replaceRE, int maximumNumberOfReplaces, long *nmatches, long *nstringmatches) { if (searchRE == NULL || replaceRE == NULL) { return NULL; } autostring32vector result; long nmatches_sub = 0; regexp *compiledRE = CompileRE_throwable (searchRE, 0); result.reset (lo, hi); *nmatches = 0; *nstringmatches = 0; for (long i = lo; i <= hi; i++) { /* Treat a NULL as an empty string */ const char32 *string = from[i] == NULL ? U"" : from[i]; result [i] = str_replace_regexp (string, compiledRE, replaceRE, maximumNumberOfReplaces, &nmatches_sub); if (nmatches_sub > 0) { *nmatches += nmatches_sub; (*nstringmatches) ++; } } return result.transfer(); } char32 **strs_replace (char32 **from, long lo, long hi, const char32 *search, const char32 *replace, int maximumNumberOfReplaces, long *nmatches, long *nstringmatches, int use_regexp) { if (use_regexp) return strs_replace_regexp (from, lo, hi, search, replace, maximumNumberOfReplaces, nmatches, nstringmatches); else return strs_replace_literal (from, lo, hi, search, replace, maximumNumberOfReplaces, nmatches, nstringmatches); } /* * Acceptable ranges e.g. "1 4 2 3:7 4:3 3:5:2" --> * 1, 4, 2, 3, 4, 5, 6, 7, 4, 3, 3, 4, 5, 4, 3, 2 * Overlap is allowed. Ranges can go up and down. */ static long *getElementsOfRanges (const char32 *ranges, long maximumElement, long *numberOfElements, const char32 *elementType) { /* * Count the elements. */ long previousElement = 0; *numberOfElements = 0; const char32 *p = & ranges [0]; for (;;) { while (*p == U' ' || *p == U'\t') p ++; if (*p == U'\0') break; if (isdigit ((int) *p)) { long currentElement = Melder_atoi (p); if (currentElement == 0) Melder_throw (U"No such ", elementType, U": 0 (minimum is 1)."); if (currentElement > maximumElement) Melder_throw (U"No such ", elementType, U": ", currentElement, U" (maximum is ", maximumElement, U")."); *numberOfElements += 1; previousElement = currentElement; do { p ++; } while (isdigit ((int) *p)); } else if (*p == ':') { if (previousElement == 0) Melder_throw (U"Cannot start range with colon."); do { p ++; } while (*p == U' ' || *p == U'\t'); if (*p == U'\0') Melder_throw (U"Cannot end range with colon."); if (! isdigit ((int) *p)) Melder_throw (U"End of range should be a positive whole number."); long currentElement = Melder_atoi (p); if (currentElement == 0) Melder_throw (U"No such ", elementType, U": 0 (minimum is 1)."); if (currentElement > maximumElement) Melder_throw (U"No such ", elementType, U": ", currentElement, U" (maximum is ", maximumElement, U")."); if (currentElement > previousElement) { *numberOfElements += currentElement - previousElement; } else { *numberOfElements += previousElement - currentElement; } previousElement = currentElement; do { p ++; } while (isdigit ((int) *p)); } else { Melder_throw (U"Start of range should be a positive whole number."); } } /* * Create room for the elements. */ autoNUMvector elements (1, *numberOfElements); /* * Store the elements. */ previousElement = 0; *numberOfElements = 0; p = & ranges [0]; for (;;) { while (*p == U' ' || *p == U'\t') p ++; if (*p == U'\0') break; if (isdigit ((int) *p)) { long currentElement = Melder_atoi (p); elements [++ *numberOfElements] = currentElement; previousElement = currentElement; do { p ++; } while (isdigit ((int) *p)); } else if (*p == U':') { do { p ++; } while (*p == U' ' || *p == U'\t'); long currentElement = Melder_atoi (p); if (currentElement > previousElement) { for (long ielement = previousElement + 1; ielement <= currentElement; ielement ++) { elements [++ *numberOfElements] = ielement; } } else { for (long ielement = previousElement - 1; ielement >= currentElement; ielement --) { elements [++ *numberOfElements] = ielement; } } previousElement = currentElement; do { p ++; } while (isdigit ((int) *p)); } } return elements.transfer(); } static void NUMlvector_getUniqueNumbers (long *numbers, long *numberOfElements, long *numberOfMultiples) { autoNUMvector sorted (NUMvector_copy (numbers, 1, *numberOfElements), 1); NUMsort_l (*numberOfElements, sorted.peek()); if (numberOfMultiples != 0) { *numberOfMultiples = 0; } numbers[1] = sorted[1]; long i = 2, n = 1; while (i <= *numberOfElements) { if (sorted[i] != sorted[i - 1]) { numbers[++n] = sorted[i]; } else { if ((i > 2 && sorted[i - 1] != sorted[i - 1]) || i == 2) { if (numberOfMultiples) { (*numberOfMultiples)++; } } } i++; } *numberOfElements = n; } long *NUMstring_getElementsOfRanges (const char32 *ranges, long maximumElement, long *numberOfElements, long *numberOfMultiples, const char32 *elementType, bool sortedUniques) { autoNUMvector elements (getElementsOfRanges (ranges, maximumElement, numberOfElements, elementType), 1); if (sortedUniques) { NUMlvector_getUniqueNumbers (elements.peek(), numberOfElements, numberOfMultiples); } return elements.transfer(); } char32 * NUMstring_timeNoDot (double time) { static char32 string[100]; long seconds = (long) floor (time); long ms = lround ((time - seconds) * 1000.0); Melder_sprint (string,100, U"_", seconds, U"_", ms); return string; } /* End of file NUMstring.cpp */ praat-6.0.04/dwsys/Permutation.cpp000066400000000000000000000310561261542461700171110ustar00rootroot00000000000000/* Permutation.cpp * * Copyright (C) 2005-2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20050706 djmw 20050722 Latest modification. djmw 20061212 Changed info to Melder_writeLine format. djmw 20071012 Added: o_CAN_WRITE_AS_ENCODING.h djmw 20100521 Next and Previous djmw 20100818 Permutation_permuteTwoItems/Numbers djmw 20110304 Thing_new */ #include #include "Permutation.h" #include "oo_DESTROY.h" #include "Permutation_def.h" #include "oo_COPY.h" #include "Permutation_def.h" #include "oo_EQUAL.h" #include "Permutation_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Permutation_def.h" #include "oo_WRITE_TEXT.h" #include "Permutation_def.h" #include "oo_WRITE_BINARY.h" #include "Permutation_def.h" #include "oo_READ_BINARY.h" #include "Permutation_def.h" #include "oo_DESCRIPTION.h" #include "Permutation_def.h" Thing_implement (Permutation, Daata, 0); static long Permutation_checkRange (Permutation me, long *from, long *to) { if ( (*from < 0 || *from > my numberOfElements) || (*to < 0 || *to > my numberOfElements)) { Melder_throw (U"Range must be in [1, ", my numberOfElements, U"]."); } if (*from == 0) { *from = 1; } if (*to == 0) { *to = my numberOfElements; } return *to - *from + 1; } void Permutation_checkInvariant (Permutation me) { autoPermutation thee = Data_copy (me); NUMsort_l (thy numberOfElements, thy p); for (long i = 1; i <= my numberOfElements; i++) { if (thy p[i] != i) { Melder_throw (me, U":not a valid permutation."); } } } void structPermutation :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Number of elements: ", numberOfElements); } void structPermutation :: v_readText (MelderReadText text, int /*formatVersion*/) { numberOfElements = texgeti4 (text); if (numberOfElements < 1) { Melder_throw (U"Found a negative mumber of elements during reading."); } p = NUMvector_readText_i4 (1, numberOfElements, text, "p"); Permutation_checkInvariant (this); } void Permutation_init (Permutation me, long numberOfElements) { my numberOfElements = numberOfElements; my p = NUMvector (1, numberOfElements); Permutation_sort (me); } Permutation Permutation_create (long numberOfElements) { try { autoPermutation me = Thing_new (Permutation); Permutation_init (me.peek(), numberOfElements); return me.transfer(); } catch (MelderError) { Melder_throw (U"Permulation not created."); } } void Permutation_sort (Permutation me) { for (long i = 1; i <= my numberOfElements; i++) { my p[i] = i; } } void Permutation_swapPositions (Permutation me, long i1, long i2) { try { if (i1 < 1 || i1 > my numberOfElements || i2 < 1 || i2 > my numberOfElements) { Melder_throw (U"Invalid positions."); } long tmp = my p[i1]; my p[i1] = my p[i2]; my p[i2] = tmp; } catch (MelderError) { Melder_throw (me, U":positions not swapped."); } } void Permutation_swapNumbers (Permutation me, long i1, long i2) { try { long ip = 0; if (i1 < 1 || i1 > my numberOfElements || i2 < 1 || i2 > my numberOfElements) { Melder_throw (U""); } if (i1 == i2) { return; } for (long i = 1; i <= my numberOfElements; i++) { if (my p[i] == i1) { my p[i] = i2; ip++; } else if (my p[i] == i2) { my p[i] = i1; ip++; } if (ip == 2) { break; } } Melder_assert (ip == 2); } catch (MelderError) { Melder_throw (me, U": numbers not swapped."); } } void Permutation_swapBlocks (Permutation me, long from, long to, long blocksize) { try { if (blocksize < 1 || blocksize > my numberOfElements) Melder_throw (U"Blocksize must be in [1, %d] range.", my numberOfElements / 2); if (from < 0 || from + blocksize - 1 > my numberOfElements || to < 0 || to + blocksize - 1 > my numberOfElements) { Melder_throw (U"Start and finish positions of the two blocks must be in [1,", my numberOfElements, U"] range."); } if (from == to) { return; } for (long i = 1; i <= blocksize; i++) { long tmp = my p[from + i - 1]; my p[from + i - 1] = my p[to + i - 1]; my p[to + i - 1] = tmp; } } catch (MelderError) { Melder_throw (me, U": blocks not swapped."); } } void Permutation_permuteRandomly_inline (Permutation me, long from, long to) { try { long n = Permutation_checkRange (me, &from, &to); if (n == 1) { return; } for (long i = from; i < to; i++) { long newpos = NUMrandomInteger (from, to); long pi = my p[i]; my p[i] = my p[newpos]; my p[newpos] = pi; } } catch (MelderError) { Melder_throw (me, U": not permuted randomly."); } } Permutation Permutation_permuteRandomly (Permutation me, long from, long to) { try { autoPermutation thee = Data_copy (me); Permutation_permuteRandomly_inline (thee.peek(), from, to); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not permuted."); } } Permutation Permutation_rotate (Permutation me, long from, long to, long step) { try { long n = Permutation_checkRange (me, &from, &to); step = (step - 1) % n + 1; autoPermutation thee = Data_copy (me); for (long i = from; i <= to; i++) { long ifrom = i + step; if (ifrom > to) { ifrom -= n; } if (ifrom < from) { ifrom += n; } thy p[ifrom] = my p[i]; } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not rotated."); } } void Permutation_swapOneFromRange (Permutation me, long from, long to, long pos, int forbidsame) { try { long n = Permutation_checkRange (me, &from, &to); long newpos = NUMrandomInteger (from, to); if (newpos == pos && forbidsame) { if (n == 1) { Melder_throw (U"Impossible to satisfy \"forbid same\" constraint within the chosen range."); } while ((newpos = NUMrandomInteger (from, to)) == pos) { ; } } long tmp = my p[pos]; my p[pos] = my p[newpos]; my p[newpos] = tmp; } catch (MelderError) { Melder_throw (me, U": one from range not swapped."); } } Permutation Permutation_permuteBlocksRandomly (Permutation me, long from, long to, long blocksize, int permuteWithinBlocks, int noDoublets) { try { long n = Permutation_checkRange (me, &from, &to); if (blocksize == 1 || (blocksize >= n && permuteWithinBlocks)) { autoPermutation thee = Permutation_permuteRandomly (me, from, to); return thee.transfer(); } autoPermutation thee = Data_copy (me); if (blocksize >= n) { return thee.transfer(); } long nblocks = n / blocksize, nrest = n % blocksize; if (nrest != 0) Melder_throw (U"It is not possible to fit an integer number of blocks " U"in the range.\n(The last block is only of size ", nrest, U")."); autoPermutation pblocks = Permutation_create (nblocks); Permutation_permuteRandomly_inline (pblocks.peek(), 1, nblocks); long first = from; for (long iblock = 1; iblock <= nblocks; iblock++, first += blocksize) { /* (n1,n2,n3,...) means: move block n1 to position 1 etc... */ long blocktomove = Permutation_getValueAtIndex (pblocks.peek(), iblock); for (long j = 1; j <= blocksize; j++) { thy p[first - 1 + j] = my p[from - 1 + (blocktomove - 1) * blocksize + j]; } if (permuteWithinBlocks) { long last = first + blocksize - 1; Permutation_permuteRandomly_inline (thee.peek(), first, last); if (noDoublets && iblock > 0 && (thy p[first - 1] % blocksize) == (thy p[first] % blocksize)) { Permutation_swapOneFromRange (thee.peek(), first + 1, last, first, 0); } } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not permuted block randomly."); } } Permutation Permutation_interleave (Permutation me, long from, long to, long blocksize, long offset) { try { long n = Permutation_checkRange (me, &from, &to); long nblocks = n / blocksize; long nrest = n % blocksize; if (nrest != 0) { Melder_throw (U"There is not an integer number of blocks in the range.\n" U"(The last block is only of size ", nrest, U" instead of ", blocksize, U")."); } if (offset >= blocksize) { Melder_throw (U"Offset must be smaller than blocksize."); } autoPermutation thee = Data_copy (me); if (nblocks == 1) { return thee.transfer(); } autoNUMvector occupied (1, blocksize); long posinblock = 1 - offset; for (long i = 1; i <= n; i++) { long index, rblock = (i - 1) % nblocks + 1; posinblock += offset; if (posinblock > blocksize) { posinblock -= blocksize; } if (i % nblocks == 1) { long count = blocksize; while (occupied[posinblock] == 1 && count > 0) { posinblock++; count--; if (posinblock > blocksize) { posinblock -= blocksize; } } occupied[posinblock] = 1; } index = from - 1 + (rblock - 1) * blocksize + posinblock; thy p[from - 1 + i] = my p[index]; } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not interleaved."); } } long Permutation_getValueAtIndex (Permutation me, long i) { return i > 0 && i <= my numberOfElements ? my p[i] : -1; } long Permutation_getIndexAtValue (Permutation me, long value) { for (long i = 1; i <= my numberOfElements; i++) { if (my p[i] == value) { return i; } } return -1; } Permutation Permutation_invert (Permutation me) { try { autoPermutation thee = Data_copy (me); for (long i = 1; i <= my numberOfElements; i++) { thy p[my p[i]] = i; } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not inverted."); } } Permutation Permutation_reverse (Permutation me, long from, long to) { try { long n = Permutation_checkRange (me, &from, &to); autoPermutation thee = Data_copy (me); for (long i = 1; i <= n; i++) { thy p[from + i - 1] = my p[to - i + 1]; } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not reversed."); } } /* Replaces p with the next permutation (in the standard lexicographical ordering. Adapted from the GSL library */ void Permutation_next_inline (Permutation me) { long size = my numberOfElements; long *p = & my p[1]; if (size < 2) { Melder_throw (U"Only one element."); } long i = size - 2; while ((p[i] > p[i + 1]) && (i != 0)) { i--; } if ((i == 0) && (p[0] > p[1])) { Melder_throw (U"No next."); } long k = i + 1; for (long j = i + 2; j < size; j++) { if ((p[j] > p[i]) && (p[j] < p[k])) { k = j; } } long tmp = p[i]; p[i] = p[k]; p[k] = tmp; for (long j = i + 1; j <= (size + i) / 2; j++) { tmp = p[j]; p[j] = p[size + i - j]; p[size + i - j] = tmp; } } /* Replaces p with the previous permutation (in the standard lexicographical ordering. Adapted from the GSL library */ void Permutation_previous_inline (Permutation me) { long size = my numberOfElements; long *p = & my p[1]; if (size < 2) { Melder_throw (U"Only one element."); } long i = size - 2; while ((p[i] < p[i + 1]) && (i != 0)) { i--; } if ((i == 0) && (p[0] < p[1])) { Melder_throw (U"No previous"); } long k = i + 1; for (long j = i + 2; j < size; j++) { if ((p[j] < p[i]) && (p[j] > p[k])) { k = j; } } long tmp = p[i]; p[i] = p[k]; p[k] = tmp; for (long j = i + 1; j <= ( (size + i) / 2); j++) { tmp = p[j]; p[j] = p[size + i - j]; p[size + i - j] = tmp; } } Permutation Permutations_multiply2 (Permutation me, Permutation thee) { try { if (my numberOfElements != thy numberOfElements) { Melder_throw (U"Number of elements must be equal."); } autoPermutation him = Data_copy (me); for (long i = 1; i <= my numberOfElements; i++) { his p[i] = my p[thy p[i]]; } return him.transfer(); } catch (MelderError) { Melder_throw (me, U" & ", thee, U" not multiplied."); } } Permutation Permutations_multiply (Collection me) { try { if (my size < 2) { Melder_throw (U"There must be at least 2 Permutations in the set."); } autoPermutation thee = Permutations_multiply2 ( (Permutation) my item[1], (Permutation) my item[2]); for (long i = 3; i <= my size; i++) { thee.reset (Permutations_multiply2 (thee.peek(), (Permutation) my item[i])); } return thee.transfer(); } catch (MelderError) { Melder_throw (U"Permutations not multiplied."); } } /* End of Permutation.cpp */ praat-6.0.04/dwsys/Permutation.h000066400000000000000000000064111261542461700165530ustar00rootroot00000000000000#ifndef _Permutation_h_ #define _Permutation_h_ /* Permutation.h * * Copyright (C) 2005-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Collection.h" #include "Permutation_def.h" oo_CLASS_CREATE (Permutation, Daata); /* Class invariant: any permutation equals the identity permutation after all its elements are sorted ascendingly. */ void Permutation_init (Permutation me, long numberOfElements); Permutation Permutation_create (long numberOfElements); /* Create the Permutation data structure and fill with the identical permutation (1,2,..n) */ void Permutation_checkInvariant (Permutation me); /* Check that the elements, if sorted ascendingly, are exactly equal to the identity (1,2,...). */ void Permutation_sort (Permutation me); /* Set p[1..n]=1,..n */ void Permutation_permuteRandomly_inline (Permutation me, long from, long to); Permutation Permutation_permuteRandomly (Permutation me, long from, long to); /* Generate a new sequence by permuting the elements from..to */ Permutation Permutation_rotate (Permutation me, long from, long to, long step); void Permutation_swapOneFromRange (Permutation me, long from, long to, long pos, int forbidsame); /* Swap item at pos with one randomly chosen in interval [from,to]. If pos in [from,to] and forbidsame==true then new position may not be equal to pos. */ void Permutation_swapBlocks (Permutation me, long from, long to, long blocksize); /* Swap two blocks */ void Permutation_swapPositions (Permutation me, long i1, long i2); void Permutation_swapNumbers (Permutation me, long i1, long i2); Permutation Permutation_interleave (Permutation me, long from, long to, long blocksize, long offset); Permutation Permutation_permuteBlocksRandomly (Permutation me, long from, long to, long blocksize, int permuteWithinBlocks, int noDoublets); /* Permute blocks of size blocksize randomly. If permuteWithinBlocks=true and noDoublets=true forbid that the last number in a block and the first number in the following block are 'equal modulo blocksize'. */ long Permutation_getValueAtIndex (Permutation me, long i); /* return i > 0 && i < my n ? my p[i] : -1 */ long Permutation_getIndexAtValue (Permutation me, long value); /* Find i for which p[i] = value */ Permutation Permutation_invert (Permutation me); /* */ Permutation Permutation_reverse (Permutation me, long from, long to); /* (n1,n2,...nn) to (nn,...n2,n1) */ void Permutation_next_inline (Permutation me); void Permutation_previous_inline (Permutation me); Permutation Permutations_multiply2 (Permutation me, Permutation thee); Permutation Permutations_multiply (Collection me); #endif /* _Permutation_h_ */ praat-6.0.04/dwsys/Permutation_and_Index.cpp000066400000000000000000000045631261542461700210650ustar00rootroot00000000000000/* Permutation_and_Index.cpp * * Copyright (C) 2005-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * djmw 20050725 * djmw 20110503 Latest modification */ #include "Permutation_and_Index.h" Permutation Index_to_Permutation_permuteRandomly (Index me, int permuteWithinClasses) { try { long numberOfClasses = my classes -> size; autoPermutation thee = Permutation_create (my numberOfElements); autoPermutation classes = Permutation_create (numberOfClasses); Permutation_permuteRandomly_inline (classes.peek(), 0, 0); autoPermutation classesinv = Permutation_invert (classes.peek()); autoNUMmatrix indices (0, numberOfClasses, 1, 4); for (long i = 1; i <= my numberOfElements; i++) { indices[my classIndex[i]][2]++; /* col 2: number of elements in class */ } /* Get some other indices ready */ for (long i = 1; i <= numberOfClasses; i++) { long klass = classes -> p[i]; indices[i][1] = klass; indices[i][3] = indices[i - 1][3] + indices[i - 1][2]; /* col 3: index at start of class */ } for (long i = 1; i <= my numberOfElements; i++) { long klass = my classIndex[i]; long newindex = classesinv -> p[klass]; indices[newindex][4]++; /* col 4: number of elements processed for class */ long newpos = indices[newindex][3] + indices[newindex][4]; thy p[newpos] = i; } if (permuteWithinClasses) { for (long i = 1; i <= numberOfClasses; i++) { long from = indices[i][3] + 1; long to = from + indices[i][2] - 1; if (to > from) { Permutation_permuteRandomly_inline (thee.peek(), from, to); } } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": Permutation not created."); } } /* End of file Permutation_and_Index.cpp */ praat-6.0.04/dwsys/Permutation_and_Index.h000066400000000000000000000020431261542461700205210ustar00rootroot00000000000000#ifndef _Permutation_and_Index_h_ #define _Permutation_and_Index_h_ /* Permutation_and_Index.h * * Copyright (C) 2005-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * djmw 20110307 Latest modification */ #include "Permutation.h" #include "Index.h" Permutation Index_to_Permutation_permuteRandomly (Index me, int permuteWithinClass); #endif /* _Permutation_and_Index_h_ */ praat-6.0.04/dwsys/Permutation_def.h000066400000000000000000000020271261542461700173700ustar00rootroot00000000000000/* Permutation_def.h * * Copyright (C) 2005-2008 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT Permutation oo_DEFINE_CLASS (Permutation, Daata) oo_LONG (numberOfElements) oo_LONG_VECTOR (p, numberOfElements) #if oo_DECLARING void v_info () override; #endif oo_END_CLASS(Permutation) #undef ooSTRUCT /* End of file Permutation_def.h */ praat-6.0.04/dwsys/SVD.cpp000066400000000000000000000305131261542461700152330ustar00rootroot00000000000000/* SVD.cpp * * Copyright (C) 1994-2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20010719 djmw 20020408 GPL + cosmetic changes. djmw 20020415 +SVD_synthesize. djmw 20030624 Removed NRC svd calls. djmw 20030825 Removed praat_USE_LAPACK external variable. djmw 20031018 Removed bug in SVD_solve that caused incorrect output when nrow > ncol djmw 20031101 Changed documentation in SVD_compute + bug correction in SVD_synthesize. djmw 20031111 Added GSVD_create_d. djmw 20051201 Adapt for numberOfRows < numberOfColumns djmw 20060810 Removed #include praat.h djmw 20061212 Changed info to Melder_writeLine format. djmw 20070102 Removed the #include "TableOfReal.h" djmw 20071012 Added: o_CAN_WRITE_AS_ENCODING.h djmw 20110304 Thing_new */ #include "SVD.h" #include "NUMlapack.h" #include "NUMmachar.h" #include "Collection.h" #include "NUMclapack.h" #include "NUMcblas.h" #include "oo_DESTROY.h" #include "SVD_def.h" #include "oo_COPY.h" #include "SVD_def.h" #include "oo_EQUAL.h" #include "SVD_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "SVD_def.h" #include "oo_WRITE_TEXT.h" #include "SVD_def.h" #include "oo_WRITE_BINARY.h" #include "SVD_def.h" #include "oo_READ_TEXT.h" #include "SVD_def.h" #include "oo_READ_BINARY.h" #include "SVD_def.h" #include "oo_DESCRIPTION.h" #include "SVD_def.h" #define MAX(m,n) ((m) > (n) ? (m) : (n)) #define MIN(m,n) ((m) < (n) ? (m) : (n)) void structSVD :: v_info () { MelderInfo_writeLine (U"Number of rows: ", numberOfRows); MelderInfo_writeLine (U"Number of columns: ", numberOfColumns); } Thing_implement (SVD, Daata, 0); static void NUMtranspose_d (double **m, long n); /* if A=UDV' then A' = (UDV')'=VDU' */ static void SVD_transpose (SVD me) { long tmpl = my numberOfRows; double **tmpd = my u; my u = my v; my v = tmpd; my numberOfRows = my numberOfColumns; my numberOfColumns = tmpl; } /* m >=n, mxn matrix A has svd UDV', where u is mxn, D is n and V is nxn. m < n, mxn matrix A. Consider A' with svd (UDV')'= VDU', where v is mxm, D is m and U' is mxn */ void SVD_init (I, long numberOfRows, long numberOfColumns) { iam (SVD); long mn_min = MIN (numberOfRows, numberOfColumns); my numberOfRows = numberOfRows; my numberOfColumns = numberOfColumns; if (! NUMfpp) { NUMmachar (); } my tolerance = NUMfpp -> eps * MAX (numberOfRows, numberOfColumns); my u = NUMmatrix (1, numberOfRows, 1, mn_min); my v = NUMmatrix (1, numberOfColumns, 1, mn_min); my d = NUMvector (1, mn_min); } SVD SVD_create (long numberOfRows, long numberOfColumns) { try { autoSVD me = Thing_new (SVD); SVD_init (me.peek(), numberOfRows, numberOfColumns); return me.transfer(); } catch (MelderError) { Melder_throw (U"SVD not created."); } } SVD SVD_create_d (double **m, long numberOfRows, long numberOfColumns) { try { autoSVD me = SVD_create (numberOfRows, numberOfColumns); SVD_svd_d (me.peek(), m); return me.transfer(); } catch (MelderError) { Melder_throw (U"SVD not created from vector."); } } SVD SVD_create_f (float **m, long numberOfRows, long numberOfColumns) { try { autoSVD me = SVD_create (numberOfRows, numberOfColumns); SVD_svd_f (me.peek(), m); return me.transfer(); } catch (MelderError) { Melder_throw (U"SVD not created from vector."); } } void SVD_svd_d (SVD me, double **m) { if (my numberOfRows >= my numberOfColumns) { // Store m in u for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= my numberOfColumns; j++) { my u[i][j] = m[i][j]; } } } else { // Store m transposed in v for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= my numberOfColumns; j++) { my v[j][i] = m[i][j]; } } } SVD_compute (me); } void SVD_svd_f (SVD me, float **m) { if (my numberOfRows >= my numberOfColumns) { // Store in u for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= my numberOfColumns; j++) { my u[j][i] = m[i][j]; } } } else { // Store transposed in v for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= my numberOfColumns; j++) { my v[i][j] = m[j][i]; } } } SVD_compute (me); } void SVD_setTolerance (SVD me, double tolerance) { my tolerance = tolerance; } double SVD_getTolerance (SVD me) { return my tolerance; } static void NUMtranspose_d (double **m, long n) { for (long i = 1; i <= n - 1; i++) { for (long j = i + 1; j <= n; j++) { double t = m[i][j]; m[i][j] = m[j][i]; m[j][i] = t; } } } /* Compute svd(A) = U D Vt. The svd routine from CLAPACK uses (fortran) column major storage, while C uses row major storage. To solve the problem above we have to transpose the matrix A, calculate the solution and transpose the U and Vt matrices of the solution. However, if we solve the transposed problem svd(A') = V D U', we have less work to do: We may call the algorithm with reverted row/column dimensions, and we switch the U and V' output arguments. The only thing that we have to do afterwards is transposing the (small) V matrix because the SVD-object has row vectors in v. The sv's are already sorted. int NUMlapack_dgesvd (char *jobu, char *jobvt, long *m, long *n, double *a, long *lda, double *s, double *u, long *ldu, double *vt, long *ldvt, double *work, long *lwork, long *info); */ void SVD_compute (SVD me) { try { char jobu = 'S', jobvt = 'O'; long m, lda, ldu, ldvt, info, lwork = -1; double wt[2]; int transpose = my numberOfRows < my numberOfColumns; // Transpose: if rows < cols then data in v if (transpose) { SVD_transpose (me); } lda = ldu = ldvt = m = my numberOfColumns; long n = my numberOfRows; (void) NUMlapack_dgesvd (&jobu, &jobvt, &m, &n, &my u[1][1], &lda, &my d[1], &my v[1][1], &ldu, nullptr, &ldvt, wt, &lwork, &info); if (info != 0) { Melder_throw (U"SVD not precomputed."); } lwork = wt[0]; autoNUMvector work (0L, lwork); (void) NUMlapack_dgesvd (&jobu, &jobvt, &m, &n, &my u[1][1], &lda, &my d[1], &my v[1][1], &ldu, nullptr, &ldvt, work.peek(), &lwork, &info); if (info != 0) { Melder_throw (U"SVD not computed."); } NUMtranspose_d (my v, MIN (m, n)); if (transpose) { SVD_transpose (me); } } catch (MelderError) { Melder_throw (me, U": SVD could not be computed."); } } // V D^2 V'or V D^-2 V void SVD_getSquared (SVD me, double **m, bool inverse) { for (long i = 1; i <= my numberOfColumns; i++) { for (long j = 1; j <= my numberOfColumns; j++) { double val = 0.0; for (long k = 1; k <= my numberOfColumns; k++) { if (my d[k] > 0.0) { double dsq = my d[k] * my d[k]; double factor = inverse ? 1.0 / dsq : dsq; val += my v[i][k] * my v[j][k] * factor; } } m[i][j] = val; } } } void SVD_solve (SVD me, double b[], double x[]) { try { long mn_min = MIN (my numberOfRows, my numberOfColumns); autoNUMvector t (1, mn_min); /* Solve UDV' x = b. Solution: x = V D^-1 U' b */ for (long j = 1; j <= mn_min; j++) { double tmp = 0.0; if (my d[j] > 0.0) { for (long i = 1; i <= my numberOfRows; i++) { tmp += my u[i][j] * b[i]; } tmp /= my d[j]; } t[j] = tmp; } for (long j = 1; j <= my numberOfColumns; j++) { double tmp = 0.0; for (long i = 1; i <= mn_min; i++) { tmp += my v[j][i] * t[i]; } x[j] = tmp; } } catch (MelderError) { Melder_throw (me, U": not solved."); } } void SVD_sort (SVD me) { try { long mn_min = MIN (my numberOfRows, my numberOfColumns); autoSVD thee = Data_copy (me); autoNUMvector index (1, mn_min); NUMindexx (my d, mn_min, index.peek()); for (long j = 1; j <= mn_min; j++) { long from = index[mn_min - j + 1]; my d[j] = thy d[from]; for (long i = 1; i <= my numberOfRows; i++) { my u[i][j] = thy u[i][from]; } for (long i = 1; i <= my numberOfColumns; i++) { my v[i][j] = thy v[i][from]; } } } catch (MelderError) { Melder_throw (me, U": not sorted."); } } long SVD_zeroSmallSingularValues (SVD me, double tolerance) { long numberOfZeroed = 0, mn_min = MIN (my numberOfRows, my numberOfColumns); double dmax = my d[1]; if (tolerance == 0.0) { tolerance = my tolerance; } for (long i = 2; i <= mn_min; i++) { if (my d[i] > dmax) { dmax = my d[i]; } } for (long i = 1; i <= mn_min; i++) { if (my d[i] < dmax * tolerance) { my d[i] = 0.0; numberOfZeroed++; } } return numberOfZeroed; } long SVD_getRank (SVD me) { long rank = 0, mn_min = MIN (my numberOfRows, my numberOfColumns); for (long i = 1; i <= mn_min; i++) { if (my d[i] > 0.0) { rank++; } } return rank; } /* SVD of A = U D V'. If u[i] is the i-th column vector of U and v[i] the i-th column vector of V and s[i] the i-th singular value, we can write the svd expansion A = sum_{i=1}^n {d[i] u[i] v[i]'}. Golub & van Loan, 3rd ed, p 71. */ void SVD_synthesize (SVD me, long sv_from, long sv_to, double **m) { try { long mn_min = MIN (my numberOfRows, my numberOfColumns); if (sv_to == 0) { sv_to = mn_min; } if (sv_from > sv_to || sv_from < 1 || sv_to > mn_min) { Melder_throw (U"Indices must be in range [1, ", mn_min, U"]."); } for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= my numberOfColumns; j++) { m[i][j] = 0.0; } } for (long k = sv_from; k <= sv_to; k++) { for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= my numberOfColumns; j++) { m[i][j] += my d[k] * my u[i][k] * my v[j][k]; } } } } catch (MelderError) { Melder_throw (me, U": no synthesis."); } } Thing_implement (GSVD, Daata, 0); void structGSVD :: v_info () { MelderInfo_writeLine (U"Number of columns: ", numberOfColumns); } GSVD GSVD_create (long numberOfColumns) { try { autoGSVD me = Thing_new (GSVD); my numberOfColumns = numberOfColumns; my q = NUMmatrix (1, numberOfColumns, 1, numberOfColumns); my r = NUMmatrix (1, numberOfColumns, 1, numberOfColumns); my d1 = NUMvector (1, numberOfColumns); my d2 = NUMvector (1, numberOfColumns); return me.transfer(); } catch (MelderError) { Melder_throw (U"GSVD not created."); } } GSVD GSVD_create_d (double **m1, long numberOfRows1, long numberOfColumns, double **m2, long numberOfRows2) { try { long m = numberOfRows1, n = numberOfColumns, p = numberOfRows2; long lwork = MAX (MAX (3 * n, m), p) + n; // Store the matrices a and b as column major! autoNUMmatrix a (NUMmatrix_transpose (m1, m, n), 1, 1); autoNUMmatrix b (NUMmatrix_transpose (m2, p, n), 1, 1); autoNUMmatrix q (1, n, 1, n); autoNUMvector alpha (1, n); autoNUMvector beta (1, n); autoNUMvector work (1, lwork); autoNUMvector iwork (1, n); char jobu1 = 'N', jobu2 = 'N', jobq = 'Q'; long k, l, info; NUMlapack_dggsvd (&jobu1, &jobu2, &jobq, &m, &n, &p, &k, &l, &a[1][1], &m, &b[1][1], &p, &alpha[1], &beta[1], nullptr, &m, nullptr, &p, &q[1][1], &n, &work[1], &iwork[1], &info); if (info != 0) { Melder_throw (U"dggsvd failed, error = ", info); } long kl = k + l; autoGSVD me = GSVD_create (kl); for (long i = 1; i <= kl; i++) { my d1[i] = alpha[i]; my d2[i] = beta[i]; } // Transpose q for (long i = 1; i <= n; i++) { for (long j = i + 1; j <= n; j++) { my q[i][j] = q[j][i]; my q[j][i] = q[i][j]; } my q[i][i] = q[i][i]; } // Get R from a(1:k+l,n-k-l+1:n) double *pr = &a[1][1]; for (long i = 1; i <= kl; i++) { for (long j = i; j <= kl; j++) { my r[i][j] = pr[i - 1 + (n - kl + j - 1) * m]; /* from col-major */ } } return me.transfer(); } catch (MelderError) { Melder_throw (U"GSVD not created."); } } void GSVD_setTolerance (GSVD me, double tolerance) { my tolerance = tolerance; } double GSVD_getTolerance (GSVD me) { return my tolerance; } #undef MAX #undef MIN /* End of file SVD.c */ praat-6.0.04/dwsys/SVD.h000066400000000000000000000055031261542461700147010ustar00rootroot00000000000000/* SVD.h * * Copyright (C) 1994-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020423 GPL header djmw 20120808 Latest modification. */ #ifndef _SVD_h_ #define _SVD_h_ #include "NUM2.h" #include "Data.h" #include "SVD_def.h" oo_CLASS_CREATE (SVD, Daata); #define GSVD__methods(klas) Data__methods(klas) oo_CLASS_CREATE (GSVD, Daata); void SVD_init (I, long numberOfRows, long numberOfColumns); SVD SVD_create (long numberOfRows, long numberOfColumns); /* my tolerance = eps * MAX (numberOfRows, numberOfColumns) where eps is the floating point precision, approximately 2.2e-16 */ SVD SVD_create_d (double **m, long numberOfRows, long numberOfColumns); SVD SVD_create_f (float **m, long numberOfRows, long numberOfColumns); /* Copy matrix into svd->u and calculate U D V' */ void SVD_svd_d (SVD me, double **m); void SVD_svd_f (SVD me, float **m); /* Perform SVD analysis on matrix M, i.e., decompose M as M = UDV'. Watch out: dataType contains V, not V' !! */ void SVD_compute (SVD me); void SVD_solve (SVD me, double b[], double x[]); /* Solve Ax = b */ void SVD_sort (SVD me); /* Sort singular values (and corresponding column vectors of U and V) in decreasing order. */ void SVD_setTolerance (SVD me, double tolerance); double SVD_getTolerance (SVD me); long SVD_zeroSmallSingularValues (SVD me, double tolerance); /* Zero singular values smaller than maximum_singular_value * tolerance If tolerance == 0 then then my tolerance will be used. Return the number of s.v.'s zeroed. */ void SVD_synthesize (SVD me, long sv_from, long sv_to, double **m); /* Synthesize matrix as U D(sv_from:sv_to) V'. (The synthesized matrix is an approximation of the svd'ed matrix with only a selected number of sv's). Matrix m is [numberOfRows x numberOfColumns] and must be allocated by caller! */ void SVD_getSquared (SVD me, double **m, bool inverse); // compute V D^2 V' or V D^-2 V' long SVD_getRank (SVD me); GSVD GSVD_create (long numberOfColumns); GSVD GSVD_create_d (double **m1, long numberOfRows1, long numberOfColumns, double **m2, long numberOfRows2); void GSVD_setTolerance (GSVD me, double tolerance); double GSVD_getTolerance (GSVD me); #endif /* _SVD_h_ */ praat-6.0.04/dwsys/SVD_def.h000066400000000000000000000032451261542461700155200ustar00rootroot00000000000000/* SVD_def.h * * Copyright (C) 1994-2008 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT SVD oo_DEFINE_CLASS (SVD, Daata) oo_DOUBLE (tolerance) oo_LONG (numberOfRows) oo_LONG (numberOfColumns) oo_DOUBLE_MATRIX (u, numberOfRows, (numberOfColumns < numberOfRows ? numberOfColumns : numberOfRows)) oo_DOUBLE_MATRIX (v, numberOfColumns, (numberOfColumns < numberOfRows ? numberOfColumns : numberOfRows)) oo_DOUBLE_VECTOR (d, (numberOfColumns < numberOfRows ? numberOfColumns : numberOfRows)) #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (SVD) #undef ooSTRUCT #define ooSTRUCT GSVD oo_DEFINE_CLASS (GSVD, Daata) oo_DOUBLE (tolerance) oo_LONG (numberOfColumns) oo_DOUBLE_MATRIX ( q, numberOfColumns, numberOfColumns) oo_DOUBLE_MATRIX ( r, numberOfColumns, numberOfColumns) oo_DOUBLE_VECTOR (d1, numberOfColumns) oo_DOUBLE_VECTOR (d2, numberOfColumns) #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (GSVD) #undef ooSTRUCT /* End of file SVD_def.h */ praat-6.0.04/dwsys/SimpleVector.cpp000066400000000000000000000044171261542461700172170ustar00rootroot00000000000000/* SimpleVector.cpp * * Copyright (C) 1994-2012 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020812 GPL header djmw 20071012 Added: o_CAN_WRITE_AS_ENCODING.h */ #include "SimpleVector.h" #include "oo_DESTROY.h" #include "SimpleVector_def.h" #include "oo_COPY.h" #include "SimpleVector_def.h" #include "oo_EQUAL.h" #include "SimpleVector_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "SimpleVector_def.h" #include "oo_WRITE_TEXT.h" #include "SimpleVector_def.h" #include "oo_WRITE_BINARY.h" #include "SimpleVector_def.h" #include "oo_READ_TEXT.h" #include "SimpleVector_def.h" #include "oo_READ_BINARY.h" #include "SimpleVector_def.h" #include "oo_DESCRIPTION.h" #include "SimpleVector_def.h" Thing_implement (DoubleVector, Daata, 0); void DoubleVector_init (I, long min, long max) { iam (DoubleVector); my min = min; my max = max; my v = NUMvector (min, max); } DoubleVector DoubleVector_create (long min, long max) { try { autoDoubleVector me = Thing_new (DoubleVector); DoubleVector_init (me.peek(), min, max); return me.transfer(); } catch (MelderError) { Melder_throw (U"DoubleVector not created."); } } Thing_implement (ComplexVector, Daata, 0); void ComplexVector_init (I, long min, long max) { iam (ComplexVector); my min = min; my max = max; my v = NUMvector (min, max); } ComplexVector ComplexVector_create (long min, long max) { try { autoComplexVector me = Thing_new (ComplexVector); ComplexVector_init (me.peek(), min, max); return me.transfer(); } catch (MelderError) { Melder_throw (U"ComplexVector not created."); } } /* End of file SimpleVector.cpp */ praat-6.0.04/dwsys/SimpleVector.h000066400000000000000000000022431261542461700166570ustar00rootroot00000000000000#ifndef _SimpleVector_h_ #define _SimpleVector_h_ /* SimpleVector.h * * Copyright (C) 1994-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Data.h" #include "SimpleVector_def.h" oo_CLASS_CREATE (DoubleVector, Daata); oo_CLASS_CREATE (ComplexVector, Daata); void DoubleVector_init (I, long min, long max); DoubleVector DoubleVector_create (long min, long max); void ComplexVector_init (I, long min, long max); ComplexVector ComplexVector_create (long min, long max); #endif /* _SimpleVector_h_ */ praat-6.0.04/dwsys/SimpleVector_def.h000066400000000000000000000023001261542461700174670ustar00rootroot00000000000000/* SimpleVector_def.h * * Copyright (C) 1994-2008 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020606 GPL header */ #define ooSTRUCT DoubleVector oo_DEFINE_CLASS (DoubleVector, Daata) oo_LONG (min) oo_LONG (max) oo_DOUBLE_VECTOR_FROM (v, min, max) oo_END_CLASS (DoubleVector) #undef ooSTRUCT #define ooSTRUCT ComplexVector oo_DEFINE_CLASS (ComplexVector, Daata) oo_LONG (min) oo_LONG (max) oo_DCOMPLEX_VECTOR_FROM (v, min, max) oo_END_CLASS (ComplexVector) #undef ooSTRUCT /* End of file SimpleVector_def.h */ praat-6.0.04/dwsys/Simple_extensions.cpp000066400000000000000000000053611261542461700203120ustar00rootroot00000000000000/* Simple_extensions.cpp * * Copyright (C) 1994-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020812 GPL header djmw & pb wchar */ #include "Simple_extensions.h" #include "longchar.h" void SimpleString_init (SimpleString me, const char32 *string) { my string = Melder_dup (string); } int SimpleString_compare (SimpleString me, SimpleString thee) { return str32cmp (my string, thy string); } const char32 *SimpleString_c (SimpleString me) { return my string; } void SimpleString_append (SimpleString me, SimpleString thee) { SimpleString_append_c (me, thy string); } void SimpleString_append_c (SimpleString me, const char32 *str) { if (! str) { return; } long myLength = str32len (my string); my string = (char32 *) Melder_realloc (my string, (myLength + str32len (str) + 1) * (int64) sizeof (char32)); str32cpy (& my string[myLength], str); } SimpleString SimpleString_concat (SimpleString me, SimpleString thee) { autoSimpleString him = Data_copy (me); SimpleString_append_c (him.peek(), thy string); return him.transfer(); } SimpleString SimpleString_concat_c (SimpleString me, const char32 *str) { autoSimpleString him = Data_copy (me); SimpleString_append_c (him.peek(), str); return him.transfer(); } void SimpleString_replace_c (SimpleString me, const char32 *str) { char32 *ptr = Melder_dup (str); Melder_free (my string); my string = ptr; } long SimpleString_length (SimpleString me) { return str32len (my string); } void SimpleString_draw (SimpleString me, Graphics g, double xWC, double yWC) { Graphics_text (g, xWC, yWC, my string); } const char32 *SimpleString_nativize_c (SimpleString me, int educateQuotes) { autoSimpleString thee = Data_copy (me); Longchar_nativize32 (thy string, my string, educateQuotes); return my string; } const char32 *SimpleString_genericize_c (SimpleString me) { autoSimpleString thee = Data_copy (me); my string = (char32 *) Melder_realloc (my string, (3 * str32len (my string) + 1) * (int64) sizeof (char32)); Longchar_genericize32 (thy string, my string); return my string; } /* End of file Simple_extensions.cpp */ praat-6.0.04/dwsys/Simple_extensions.h000066400000000000000000000037231261542461700177570ustar00rootroot00000000000000#ifndef _Simple_extensions_h_ #define _Simple_extensions_h_ /* Simple_extensions.h * * Copyright (C) 1994-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19950616 djmw 20020812 GPL header */ #include "Data.h" #include "Graphics.h" #include "Simple.h" void SimpleString_init (SimpleString me, const char32 *value); /* return 0 when value == NULL */ const char32 *SimpleString_c (SimpleString me); /* return pointer to the string */ int SimpleString_compare (SimpleString me, SimpleString thee); void SimpleString_append (SimpleString me, SimpleString thee); void SimpleString_append_c (SimpleString me, const char32 *str); /* append string to me */ SimpleString SimpleString_concat (SimpleString me, SimpleString thee); SimpleString SimpleString_concat_c (SimpleString me, const char32 *str); /* concatenate two strings */ void SimpleString_replace_c (SimpleString me, const char32 *replacement); /* replace my value with new string */ long SimpleString_length (SimpleString me); /* return my length */ void SimpleString_draw (SimpleString me, Graphics g, double xWC, double yWC); /* draw the string */ const char32 * SimpleString_nativize_c (SimpleString me, int educateQuotes); const char32 * SimpleString_genericize_c (SimpleString me); /* see longchar.h for info */ #endif /* _Simple_extensions_h_ */ praat-6.0.04/dwsys/regularExp.cpp000066400000000000000000004020521261542461700167160ustar00rootroot00000000000000/*------------------------------------------------------------------------* * static const char CVSID[] = "$Id: regularExp.c,v 1.30 2006/08/13 21:47:45 yooden Exp $"; * `CompileRE', `ExecRE', and `substituteRE' -- regular expression parsing * * This is a HIGHLY ALTERED VERSION of Henry Spencer's `regcomp' and * `regexec' code adapted for NEdit. * * .-------------------------------------------------------------------. * | ORIGINAL COPYRIGHT NOTICE: | * | | * | Copyright (c) 1986 by University of Toronto. | * | Written by Henry Spencer. Not derived from licensed software. | * | | * | Permission is granted to anyone to use this software for any | * | purpose on any computer system, and to redistribute it freely, | * | subject to the following restrictions: | * | | * | 1. The author is not responsible for the consequences of use of | * | this software, no matter how awful, even if they arise | * | from defects in it. | * | | * | 2. The origin of this software must not be misrepresented, either | * | by explicit claim or by omission. | * | | * | 3. Altered versions must be plainly marked as such, and must not | * | be misrepresented as being the original software. | * `-------------------------------------------------------------------' * * This is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. In addition, you may distribute version of this program linked to * Motif or Open Motif. See README for details. * * This software is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along with * software; if not, write to the Free Software Foundation, Inc., 59 Temple * Place, Suite 330, Boston, MA 02111-1307 USA * * * BEWARE that some of this code is subtly aware of the way operator * precedence is structured in regular expressions. Serious changes in * regular-expression syntax might require a total rethink. * -- Henry Spencer * (Yes, it did!) -- Christopher Conrad, Dec. 1999 * * January, 1994, Mark Edel * Consolidated files, changed names of external functions to avoid * potential conflicts with native regcomp and regexec functions, changed * error reporting to NEdit form, added multi-line and reverse searching, * and added \n \t \u \U \l \L. * * June, 1996, Mark Edel * Bug in NEXT macro, didn't work for expressions which compiled to over * 256 bytes. * * December, 1999, Christopher Conrad * Reformatted code for readability, improved error output, added octal and * hexadecimal escapes, added back-references (\1-\9), added positive look * ahead: (?=...), added negative lookahead: (?!...), added non-capturing * parentheses: (?:...), added case insensitive constructs (?i...) and * (?I...), added newline matching constructs (?n...) and (?N...), added * regex comments: (?#...), added shortcut escapes: \d\D\l\L\s\S\w\W\y\Y. * Added "not a word boundary" anchor \B. * * July, 2002, Eddy De Greef * Added look behind, both positive (?<=...) and negative (? format * djmw 20070614 updated from version 1.25 to 1.30 * djmw 20080110 Extra parameter for SubstituteRE to allow error differentiation (not enough memory can be repaired upstream). * Changed Melder_information in reg_error to Melder_error. * djmw 20101119 Changed NULL to '\0' in makeDelimiterTable */ #include #include #include "regularExp.h" /* The first byte of the regexp internal `program' is a magic number to help guard against corrupted data; the compiled regex code really begins in the second byte. */ #define MAGIC 0234 /* The "internal use only" fields in `regexp.h' are present to pass info from * `CompileRE' to `ExecRE' which permits the execute phase to run lots faster on * simple cases. They are: * * match_start Character that must begin a match; '\0' if none obvious. * anchor Is the match anchored (at beginning-of-line only)? * * `match_start' and `anchor' permit very fast decisions on suitable starting * points for a match, considerably reducing the work done by ExecRE. */ /* STRUCTURE FOR A REGULAR EXPRESSION (regex) `PROGRAM'. * * This is essentially a linear encoding of a nondeterministic finite-state * machine or NFA (aka syntax charts or `railroad normal form' in parsing * technology). Each node is an opcode plus a NEXT pointer, possibly * followed by operands. NEXT pointers of all nodes except BRANCH implement * concatenation; a NEXT pointer with a BRANCH on both ends of it is * connecting two alternatives. (Here we have one of the subtle syntax * dependencies: an individual BRANCH (as opposed to a collection of them) is * never concatenated with anything because of operator precedence.) The * operand of some types of nodes is a literal string; for others, it is a node * leading into a sub-FSM. In particular, the operand of a BRANCH node is the * first node of the branch. (NB this is _NOT_ a tree structure: the tail of * the branch connects to the thing following the set of BRANCHes.) * * The opcodes are: */ /* DEFINITION VALUE MEANING */ #define END 1 /* End of program. */ /* Zero width positional assertions. */ #define BOL 2 /* Match position at beginning of line. */ #define EOL 3 /* Match position at end of line. */ #define BOWORD 4 /* Match "" representing word delimiter or BOL */ #define EOWORD 5 /* Match "" representing word delimiter or EOL */ #define NOT_BOUNDARY 6 /* Not word boundary (\B, opposite of < and >) */ /* Op codes with null terminated string operands. */ #define EXACTLY 7 /* Match this string. */ #define SIMILAR 8 /* Match this case insensitive string */ #define ANY_OF 9 /* Match any character in the set. */ #define ANY_BUT 10 /* Match any character not in the set. */ /* Op codes to match any character. */ #define ANY 11 /* Match any one character (implements '.') */ #define EVERY 12 /* Same as ANY but matches newline. */ /* Shortcut escapes, \d, \D, \l, \L, \s, \S, \w, \W, \y, \Y. */ #define DIGIT 13 /* Match any digit, i.e. [0123456789] */ #define NOT_DIGIT 14 /* Match any non-digit, i.e. [^0123456789] */ #define LETTER 15 /* Match any letter character [a-zA-Z] */ #define NOT_LETTER 16 /* Match any non-letter character [^a-zA-Z] */ #define SPACE 17 /* Match any whitespace character EXCEPT \n */ #define SPACE_NL 18 /* Match any whitespace character INCLUDING \n */ #define NOT_SPACE 19 /* Match any non-whitespace character */ #define NOT_SPACE_NL 20 /* Same as NOT_SPACE but matches newline. */ #define WORD_CHAR 21 /* Match any word character [a-zA-Z0-9_] */ #define NOT_WORD_CHAR 22 /* Match any non-word character [^a-zA-Z0-9_] */ #define IS_DELIM 23 /* Match any character that's a word delimiter */ #define NOT_DELIM 24 /* Match any character NOT a word delimiter */ /* Quantifier nodes. (Only applied to SIMPLE nodes. Quantifiers applied to non SIMPLE nodes or larger atoms are implemented using complex constructs.)*/ #define STAR 25 /* Match this (simple) thing 0 or more times. */ #define LAZY_STAR 26 /* Minimal matching STAR */ #define QUESTION 27 /* Match this (simple) thing 0 or 1 times. */ #define LAZY_QUESTION 28 /* Minimal matching QUESTION */ #define PLUS 29 /* Match this (simple) thing 1 or more times. */ #define LAZY_PLUS 30 /* Minimal matching PLUS */ #define BRACE 31 /* Match this (simple) thing m to n times. */ #define LAZY_BRACE 32 /* Minimal matching BRACE */ /* Nodes used to build complex constructs. */ #define NOTHING 33 /* Match empty string (always matches) */ #define BRANCH 34 /* Match this alternative, or the next... */ #define BACK 35 /* Always matches, NEXT ptr points backward. */ #define INIT_COUNT 36 /* Initialize {m,n} counter to zero */ #define INC_COUNT 37 /* Increment {m,n} counter by one */ #define TEST_COUNT 38 /* Test {m,n} counter against operand */ /* Back Reference nodes. */ #define BACK_REF 39 /* Match latest matched parenthesized text */ #define BACK_REF_CI 40 /* Case insensitive version of BACK_REF */ #define X_REGEX_BR 41 /* Cross-Regex Back-Ref for syntax highlighting */ #define X_REGEX_BR_CI 42 /* Case insensitive version of X_REGEX_BR_CI */ /* Various nodes used to implement parenthetical constructs. */ #define POS_AHEAD_OPEN 43 /* Begin positive look ahead */ #define NEG_AHEAD_OPEN 44 /* Begin negative look ahead */ #define LOOK_AHEAD_CLOSE 45 /* End positive or negative look ahead */ #define POS_BEHIND_OPEN 46 /* Begin positive look behind */ #define NEG_BEHIND_OPEN 47 /* Begin negative look behind */ #define LOOK_BEHIND_CLOSE 48 /* Close look behind */ #define OPEN 49 /* Open for capturing parentheses. */ /* OPEN+1 is number 1, etc. */ #define CLOSE (OPEN + NSUBEXP) /* Close for capturing parentheses. */ #define LAST_PAREN (CLOSE + NSUBEXP) #if (LAST_PAREN > UCHAR_MAX) #error "Too many parentheses for storage in an unsigned char (LAST_PAREN too big.)" #endif /* The next_ptr () function can consume up to 30% of the time during matching because it is called an immense number of times (an average of 25 next_ptr() calls per match() call was witnessed for Perl syntax highlighting). Therefore it is well worth removing some of the function call overhead by selectively inlining the next_ptr() calls. Moreover, the inlined code can be simplified for matching because one of the tests, only necessary during compilation, can be left out. The net result of using this inlined version at two critical places is a 25% speedup (again, witnesses on Perl syntax highlighting). */ #define NEXT_PTR(in_ptr, out_ptr)\ next_ptr_offset = GET_OFFSET (in_ptr);\ if (next_ptr_offset == 0)\ out_ptr = NULL;\ else {\ if (GET_OP_CODE (in_ptr) == BACK)\ out_ptr = in_ptr - next_ptr_offset;\ else \ out_ptr = in_ptr + next_ptr_offset;\ } /* OPCODE NOTES: ------------ All nodes consist of an 8 bit op code followed by 2 bytes that make up a 16 bit NEXT pointer. Some nodes have a null terminated character string operand following the NEXT pointer. Other nodes may have an 8 bit index operand. The TEST_COUNT node has an index operand followed by a 16 bit test value. The BRACE and LAZY_BRACE nodes have two 16 bit values for min and max but no index value. SIMILAR Operand(s): null terminated string Implements a case insensitive match of a string. Mostly intended for use in syntax highlighting patterns for keywords of languages like FORTRAN and Ada that are case insensitive. The regex text in this node is converted to lower case during regex compile. DIGIT, NOT_DIGIT, LETTER, NOT_LETTER, SPACE, NOT_SPACE, WORD_CHAR, NOT_WORD_CHAR Operand(s): None Implements shortcut escapes \d, \D, \l, \L, \s, \S, \w, \W. The locale aware ANSI functions isdigit(), isalpha(), isalnun(), and isspace() are used to implement these in the hopes of increasing portability. NOT_BOUNDARY Operand(s): None Implements \B as a zero width assertion that the current character is NOT on a word boundary. Word boundaries are defined to be the position between two characters where one of those characters is one of the dynamically defined word delimiters, and the other character is not. IS_DELIM Operand(s): None Implements \y as any character that is one of the dynamically specified word delimiters. NOT_DELIM Operand(s): None Implements \Y as any character that is NOT one of the dynamically specified word delimiters. STAR, PLUS, QUESTION, and complex '*', '+', and '?' Operand(s): None (Note: NEXT pointer is usually zero. The code that processes this node skips over it.) Complex (parenthesized) versions implemented as circular BRANCH structures using BACK. SIMPLE versions (one character per match) are implemented separately for speed and to minimize recursion. BRACE, LAZY_BRACE Operand(s): minimum value (2 bytes), maximum value (2 bytes) Implements the {m,n} construct for atoms that are SIMPLE. BRANCH Operand(s): None The set of branches constituting a single choice are hooked together with their NEXT pointers, since precedence prevents anything being concatenated to any individual branch. The NEXT pointer of the last BRANCH in a choice points to the thing following the whole choice. This is also where the final NEXT pointer of each individual branch points; each branch starts with the operand node of a BRANCH node. BACK Operand(s): None Normal NEXT pointers all implicitly point forward. Back implicitly points backward. BACK exists to make loop structures possible. INIT_COUNT Operand(s): index (1 byte) Initializes the count array element referenced by the index operand. This node is used to build general (i.e. parenthesized) {m,n} constructs. INC_COUNT Operand(s): index (1 byte) Increments the count array element referenced by the index operand. This node is used to build general (i.e. parenthesized) {m,n} constructs. TEST_COUNT Operand(s): index (1 byte), test value (2 bytes) Tests the current value of the count array element specified by the index operand against the test value. If the current value is less than the test value, control passes to the node after that TEST_COUNT node. Otherwise control passes to the node referenced by the NEXT pointer for the TEST_COUNT node. This node is used to build general (i.e. parenthesized) {m,n} constructs. BACK_REF, BACK_REF_CI Operand(s): index (1 byte, value 1-9) Implements back references. This node will attempt to match whatever text was most recently captured by the index'th set of parentheses. BACK_REF_CI is case insensitive version. X_REGEX_BR, X_REGEX_BR_CI (NOT IMPLEMENTED YET) Operand(s): index (1 byte, value 1-9) Implements back references into a previously matched but separate regular expression. This is used by syntax highlighting patterns. This node will attempt to match whatever text was most captured by the index'th set of parentheses of the separate regex passed to ExecRE. X_REGEX_BR_CI is case insensitive version. POS_AHEAD_OPEN, NEG_AHEAD_OPEN, LOOK_AHEAD_CLOSE Operand(s): None Implements positive and negative look ahead. Look ahead is an assertion that something is either there or not there. Once this is determined the regex engine backtracks to where it was just before the look ahead was encountered, i.e. look ahead is a zero width assertion. POS_BEHIND_OPEN, NEG_BEHIND_OPEN, LOOK_BEHIND_CLOSE Operand(s): 2x2 bytes for OPEN (match boundaries), None for CLOSE Implements positive and negative look behind. Look behind is an assertion that something is either there or not there in front of the current position. Look behind is a zero width assertion, with the additional constraint that it must have a bounded length (for complexity and efficiency reasons; note that most other implementation even impose fixed length). OPEN, CLOSE Operand(s): None OPEN + n = Start of parenthesis 'n', CLOSE + n = Close of parenthesis 'n', and are numbered at compile time. */ /* A node is one char of opcode followed by two chars of NEXT pointer plus * any operands. NEXT pointers are stored as two 8-bit pieces, high order * first. The value is a positive offset from the opcode of the node * containing it. An operand, if any, simply follows the node. (Note that * much of the code generation knows about this implicit relationship.) * * Using two bytes for NEXT_PTR_SIZE is vast overkill for most things, * but allows patterns to get big without disasters. */ #define OP_CODE_SIZE 1 #define NEXT_PTR_SIZE 2 #define INDEX_SIZE 1 #define LENGTH_SIZE 4 #define NODE_SIZE (NEXT_PTR_SIZE + OP_CODE_SIZE) #define GET_OP_CODE(p) (*(char32 *)(p)) #define OPERAND(p) ((p) + NODE_SIZE) #define GET_OFFSET(p) ((( *((p) + 1) & 0377) << 8) + (( *((p) + 2)) & 0377)) #define PUT_OFFSET_L(v) (char32)(((v) >> 8) & 0377) #define PUT_OFFSET_R(v) (char32) ((v) & 0377) #define GET_LOWER(p) ((( *((p) + NODE_SIZE) & 0377) << 8) + \ (( *((p) + NODE_SIZE+1)) & 0377)) #define GET_UPPER(p) ((( *((p) + NODE_SIZE+2) & 0377) << 8) + \ (( *((p) + NODE_SIZE+3)) & 0377)) /* Utility definitions. */ #define REG_FAIL(m) {*Error_Ptr = (m); return (NULL);} #define IS_QUANTIFIER(c) ((c) == '*' || (c) == '+' || \ (c) == '?' || (c) == Brace_Char) #define SET_BIT(i,n) ((i) |= (1 << ((n) - 1))) #define TEST_BIT(i,n) ((i) & (1 << ((n) - 1))) #define U_CHAR_AT(p) ((unsigned int) *(char32 *)(p)) /* Flags to be passed up and down via function parameters during compile. */ #define WORST 0 /* Worst case. No assumptions can be made.*/ #define HAS_WIDTH 1 /* Known never to match null string. */ #define SIMPLE 2 /* Simple enough to be STAR/PLUS operand. */ #define NO_PAREN 0 /* Only set by initial call to "chunk". */ #define PAREN 1 /* Used for normal capturing parentheses. */ #define NO_CAPTURE 2 /* Non-capturing parentheses (grouping only). */ #define INSENSITIVE 3 /* Case insensitive parenthetical construct */ #define SENSITIVE 4 /* Case sensitive parenthetical construct */ #define NEWLINE 5 /* Construct to match newlines in most cases */ #define NO_NEWLINE 6 /* Construct to match newlines normally */ #define REG_INFINITY 0UL #define REG_ZERO 0UL #define REG_ONE 1UL /* Flags for function shortcut_escape() */ #define CHECK_ESCAPE 0 /* Check an escape sequence for validity only. */ #define CHECK_CLASS_ESCAPE 1 /* Check the validity of an escape within a character class */ #define EMIT_CLASS_BYTES 2 /* Emit equivalent character class bytes, e.g \d=0123456789 */ #define EMIT_NODE 3 /* Emit the appropriate node. */ /* Array sizes for arrays used by function init_ansi_classes. */ #define WHITE_SPACE_SIZE 16 #define ALNUM_CHAR_SIZE 256 /* Number of bytes to offset from the beginning of the regex program to the start of the actual compiled regex code, i.e. skipping over the MAGIC number and the two counters at the front. */ #define REGEX_START_OFFSET 3 #define MAX_COMPILED_SIZE 32767UL /* Largest size a compiled regex can be. Probably could be 65535UL. */ /* Global work variables for `CompileRE'. */ static char32 *Reg_Parse; /* Input scan ptr (scans user's regex) */ static int Total_Paren; /* Parentheses, (), counter. */ static int Num_Braces; /* Number of general {m,n} constructs. {m,n} quantifiers of SIMPLE atoms are not included in this count. */ static int Closed_Parens; /* Bit flags indicating () closure. */ static int Paren_Has_Width; /* Bit flags indicating ()'s that are known to not match the empty string */ static char32 Compute_Size; /* Address of this used as flag. */ static char32 *Code_Emit_Ptr; /* When Code_Emit_Ptr is set to &Compute_Size no code is emitted. Instead, the size of code that WOULD have been generated is accumulated in Reg_Size. Otherwise, Code_Emit_Ptr points to where compiled regex code is to be written. */ static unsigned long Reg_Size; /* Size of compiled regex code. */ static const char32 **Error_Ptr; /* Place to store error messages so they can be returned by `CompileRE' */ static char32 Error_Text [128];/* Sting to build error messages in. */ static char32 White_Space [WHITE_SPACE_SIZE]; /* Arrays used by */ static char32 Word_Char [ALNUM_CHAR_SIZE]; /* functions */ static char32 Letter_Char [ALNUM_CHAR_SIZE]; /* init_ansi_classes () */ /* and shortcut_escape (). */ static char32 ASCII_Digits [] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '\0' }; /* Same for all */ /* locales. */ static int Is_Case_Insensitive; static int Match_Newline; static int Enable_Counting_Quantifier = 1; static char32 Brace_Char; static char32 Default_Meta_Char [] = { '{', '.', '*', '+', '?', '[', '(', '|', ')', '^', '<', '>', '$', '\0' }; static char32 *Meta_Char; typedef struct { long lower; long upper; } len_range; /* Forward declarations for functions used by `CompileRE'. */ static char32 *alternative (int *flag_param, len_range *range_param); static char32 *back_ref (char32 *c, int *flag_param, int emit); static char32 *chunk (int paren, int *flag_param, len_range *range_param); static void emit_byte (char32 c); static void emit_class_byte (char32 c); static char32 *emit_node (int op_code); static char32 *emit_special (char32 op_code, unsigned long test_val, int index); static char32 literal_escape (char32 c); static char32 numeric_escape (char32 c, char32 **parse); static char32 *atom (int *flag_param, len_range *range_param); static void reg_error (const char32_t *str); static char32 *insert (char32 op, char32 *opnd, long min, long max, int index); static char32 *next_ptr (char32 *ptr); static void offset_tail (char32 *ptr, int offset, char32 *val); static void branch_tail (char32 *ptr, int offset, char32 *val); static char32 *piece (int *flag_param, len_range *range_param); static void tail (char32 *search_from, char32 *point_t); static char32 *shortcut_escape (char32 c, int *flag_param, int emit); static int init_ansi_classes (); /*----------------------------------------------------------------------* * CompileRE * * Compiles a regular expression into the internal format used by * `ExecRE'. * * The default behaviour wrt. case sensitivity and newline matching can * be controlled through the defaultFlags argument (Markus Schwarzenberg). * Future extensions are possible by using other flag bits. * Note that currently only the case sensitivity flag is effectively used. * * Beware that the optimization and preparation code in here knows about * some of the structure of the compiled regexp. *----------------------------------------------------------------------*/ regexp *CompileRE_throwable (const char32 *exp, int defaultFlags) { const char32 *compileMessage; regexp *compiledRE = CompileRE (exp, & compileMessage, defaultFlags); if (compiledRE == NULL) { Melder_throw (U"Regular expression: ", compileMessage, U"."); } return compiledRE; } regexp *CompileRE (const char32 *exp, const char32 **errorText, int defaultFlags) { regexp *comp_regex = NULL; char32 *scan; int flags_local, pass; len_range range_local; if (Enable_Counting_Quantifier) { Brace_Char = '{'; Meta_Char = &Default_Meta_Char [0]; } else { Brace_Char = '*'; /* Bypass the '{' in */ Meta_Char = &Default_Meta_Char [1]; /* Default_Meta_Char */ } /* Set up errorText to receive failure reports. */ Error_Ptr = errorText; *Error_Ptr = U""; if (exp == NULL) { REG_FAIL (U"NULL argument, `CompileRE\'"); } /* Initialize arrays used by function `shortcut_escape'. */ if (!init_ansi_classes ()) { REG_FAIL (U"internal error #1, `CompileRE\'"); } Code_Emit_Ptr = &Compute_Size; Reg_Size = 0UL; /* We can't allocate space until we know how big the compiled form will be, but we can't compile it (and thus know how big it is) until we've got a place to put the code. So we cheat: we compile it twice, once with code generation turned off and size counting turned on, and once "for real". This also means that we don't allocate space until we are sure that the thing really will compile successfully, and we never have to move the code and thus invalidate pointers into it. (Note that it has to be in one piece because free() must be able to free it all.) */ for (pass = 1; pass <= 2; pass++) { /*-------------------------------------------* * FIRST PASS: Determine size and legality. * * SECOND PASS: Emit code. * *-------------------------------------------*/ /* Schwarzenberg: * If defaultFlags = 0 use standard defaults: * Is_Case_Insensitive: Case sensitive is the default * Match_Newline: Newlines are NOT matched by default * in character classes */ Is_Case_Insensitive = ( (defaultFlags & REDFLT_CASE_INSENSITIVE) ? 1 : 0); Match_Newline = 0; /* ((defaultFlags & REDFLT_MATCH_NEWLINE) ? 1 : 0); Currently not used. Uncomment if needed. */ Reg_Parse = (char32 *) exp; Total_Paren = 1; Num_Braces = 0; Closed_Parens = 0; Paren_Has_Width = 0; emit_byte (MAGIC); emit_byte ('%'); /* Placeholder for num of capturing parentheses. */ emit_byte ('%'); /* Placeholder for num of general {m,n} constructs. */ if (chunk (NO_PAREN, &flags_local, &range_local) == NULL) { return (NULL); /* Something went wrong */ } if (pass == 1) { if (Reg_Size >= MAX_COMPILED_SIZE) { /* Too big for NEXT pointers NEXT_PTR_SIZE bytes long to span. This is a real issue since the first BRANCH node usually points to the end of the compiled regex code. */ Melder_sprint (Error_Text,128, U"regexp > ", MAX_COMPILED_SIZE, U" bytes"); REG_FAIL (Error_Text); } /* Allocate memory. */ comp_regex = (regexp *) malloc (sizeof (regexp) + Reg_Size * sizeof (char32)); if (comp_regex == NULL) { REG_FAIL (U"out of memory in `CompileRE\'"); } Code_Emit_Ptr = (char32 *) comp_regex->program; } } comp_regex->program [1] = (char32) Total_Paren - 1; comp_regex->program [2] = (char32) Num_Braces; /*----------------------------------------* * Dig out information for optimizations. * *----------------------------------------*/ comp_regex->match_start = '\0'; /* Worst-case defaults. */ comp_regex->anchor = 0; /* First BRANCH. */ scan = (char32 *) (comp_regex->program + REGEX_START_OFFSET); if (GET_OP_CODE (next_ptr (scan)) == END) { /* Only one top-level choice. */ scan = OPERAND (scan); /* Starting-point info. */ if (GET_OP_CODE (scan) == EXACTLY) { comp_regex->match_start = *OPERAND (scan); } else if (PLUS <= GET_OP_CODE (scan) && GET_OP_CODE (scan) <= LAZY_PLUS) { /* Allow x+ or x+? at the start of the regex to be optimized. */ if (GET_OP_CODE (scan + NODE_SIZE) == EXACTLY) { comp_regex->match_start = *OPERAND (scan + NODE_SIZE); } } else if (GET_OP_CODE (scan) == BOL) { comp_regex->anchor++; } } return (comp_regex); } /*----------------------------------------------------------------------* * chunk * * * * Process main body of regex or process a parenthesized "thing". * * * * Caller must absorb opening parenthesis. * * * * Combining parenthesis handling with the base level of regular * * expression is a trifle forced, but the need to tie the tails of the * * branches to what follows makes it hard to avoid. * *----------------------------------------------------------------------*/ static char32 *chunk (int paren, int *flag_param, len_range *range_param) { char32 *ret_val = NULL; char32 *this_branch; char32 *ender = NULL; int this_paren = 0; int flags_local, first = 1, zero_width, i; int old_sensitive = Is_Case_Insensitive; int old_newline = Match_Newline; len_range range_local; int look_only = 0; char32 *emit_look_behind_bounds = NULL; *flag_param = HAS_WIDTH; /* Tentatively. */ range_param->lower = 0; /* Idem */ range_param->upper = 0; /* Make an OPEN node, if parenthesized. */ if (paren == PAREN) { if (Total_Paren >= NSUBEXP) { Melder_sprint (Error_Text,128, U"number of ()'s > ", NSUBEXP); REG_FAIL (Error_Text); } this_paren = Total_Paren; Total_Paren++; ret_val = emit_node (OPEN + this_paren); } else if (paren == POS_AHEAD_OPEN || paren == NEG_AHEAD_OPEN) { *flag_param = WORST; /* Look ahead is zero width. */ look_only = 1; ret_val = emit_node (paren); } else if (paren == POS_BEHIND_OPEN || paren == NEG_BEHIND_OPEN) { *flag_param = WORST; /* Look behind is zero width. */ look_only = 1; /* We'll overwrite the zero length later on, so we save the ptr */ ret_val = emit_special (paren, 0, 0); emit_look_behind_bounds = ret_val + NODE_SIZE; } else if (paren == INSENSITIVE) { Is_Case_Insensitive = 1; } else if (paren == SENSITIVE) { Is_Case_Insensitive = 0; } else if (paren == NEWLINE) { Match_Newline = 1; } else if (paren == NO_NEWLINE) { Match_Newline = 0; } /* Pick up the branches, linking them together. */ do { this_branch = alternative (&flags_local, &range_local); if (this_branch == NULL) { return (NULL); } if (first) { first = 0; *range_param = range_local; if (ret_val == NULL) { ret_val = this_branch; } } else if (range_param->lower >= 0) { if (range_local.lower >= 0) { if (range_local.lower < range_param->lower) { range_param->lower = range_local.lower; } if (range_local.upper > range_param->upper) { range_param->upper = range_local.upper; } } else { range_param->lower = -1; /* Branches have different lengths */ range_param->upper = -1; } } tail (ret_val, this_branch); /* Connect BRANCH -> BRANCH. */ /* If any alternative could be zero width, consider the whole parenthisized thing to be zero width. */ if (! (flags_local & HAS_WIDTH)) { *flag_param &= ~HAS_WIDTH; } /* Are there more alternatives to process? */ if (*Reg_Parse != '|') { break; } Reg_Parse++; } while (1); /* Make a closing node, and hook it on the end. */ if (paren == PAREN) { ender = emit_node (CLOSE + this_paren); } else if (paren == NO_PAREN) { ender = emit_node (END); } else if (paren == POS_AHEAD_OPEN || paren == NEG_AHEAD_OPEN) { ender = emit_node (LOOK_AHEAD_CLOSE); } else if (paren == POS_BEHIND_OPEN || paren == NEG_BEHIND_OPEN) { ender = emit_node (LOOK_BEHIND_CLOSE); } else { ender = emit_node (NOTHING); } tail (ret_val, ender); /* Hook the tails of the branch alternatives to the closing node. */ for (this_branch = ret_val; this_branch != NULL;) { branch_tail (this_branch, NODE_SIZE, ender); this_branch = next_ptr (this_branch); } /* Check for proper termination. */ if (paren != NO_PAREN && *Reg_Parse++ != ')') { REG_FAIL (U"missing right parenthesis \')\'"); } else if (paren == NO_PAREN && *Reg_Parse != '\0') { if (*Reg_Parse == ')') { REG_FAIL (U"missing left parenthesis \'(\'"); } else { REG_FAIL (U"junk on end"); /* "Can't happen" - NOTREACHED */ } } /* Check whether look behind has a fixed size */ if (emit_look_behind_bounds) { if (range_param->lower < 0) { REG_FAIL (U"look-behind does not have a bounded size"); } if (range_param->upper > 65535L) { REG_FAIL (U"max. look-behind size is too large (>65535)") } if (Code_Emit_Ptr != &Compute_Size) { *emit_look_behind_bounds++ = PUT_OFFSET_L (range_param->lower); *emit_look_behind_bounds++ = PUT_OFFSET_R (range_param->lower); *emit_look_behind_bounds++ = PUT_OFFSET_L (range_param->upper); *emit_look_behind_bounds = PUT_OFFSET_R (range_param->upper); } } /* For look ahead/behind, the length must be set to zero again */ if (look_only) { range_param->lower = 0; range_param->upper = 0; } zero_width = 0; /* Set a bit in Closed_Parens to let future calls to function `back_ref' know that we have closed this set of parentheses. */ if (paren == PAREN && this_paren <= (int) sizeof (Closed_Parens) * CHAR_BIT) { SET_BIT (Closed_Parens, this_paren); /* Determine if a parenthesized expression is modified by a quantifier that can have zero width. */ if (* (Reg_Parse) == '?' || * (Reg_Parse) == '*') { zero_width++; } else if (* (Reg_Parse) == '{' && Brace_Char == '{') { if (* (Reg_Parse + 1) == ',' || * (Reg_Parse + 1) == '}') { zero_width++; } else if (* (Reg_Parse + 1) == '0') { i = 2; while (* (Reg_Parse + i) == '0') { i++; } if (* (Reg_Parse + i) == ',') { zero_width++; } } } } /* If this set of parentheses is known to never match the empty string, set a bit in Paren_Has_Width to let future calls to function back_ref know that this set of parentheses has non-zero width. This will allow star (*) or question (?) quantifiers to be aplied to a back-reference that refers to this set of parentheses. */ if ( (*flag_param & HAS_WIDTH) && paren == PAREN && !zero_width && this_paren <= (int) (sizeof (Paren_Has_Width) * CHAR_BIT)) { SET_BIT (Paren_Has_Width, this_paren); } Is_Case_Insensitive = old_sensitive; Match_Newline = old_newline; return (ret_val); } /*----------------------------------------------------------------------* * alternative * * Processes one alternative of an '|' operator. Connects the NEXT * pointers of each regex atom together sequentialy. *----------------------------------------------------------------------*/ static char32 *alternative (int *flag_param, len_range *range_param) { char32 *ret_val; char32 *chain; char32 *latest; int flags_local; len_range range_local; *flag_param = WORST; /* Tentatively. */ range_param->lower = 0; /* Idem */ range_param->upper = 0; ret_val = emit_node (BRANCH); chain = NULL; /* Loop until we hit the start of the next alternative, the end of this set of alternatives (end of parentheses), or the end of the regex. */ while (*Reg_Parse != '|' && *Reg_Parse != ')' && *Reg_Parse != '\0') { latest = piece (&flags_local, &range_local); if (latest == NULL) { return (NULL); /* Something went wrong. */ } *flag_param |= flags_local & HAS_WIDTH; if (range_local.lower < 0) { /* Not a fixed length */ range_param->lower = -1; range_param->upper = -1; } else if (range_param->lower >= 0) { range_param->lower += range_local.lower; range_param->upper += range_local.upper; } if (chain != NULL) { /* Connect the regex atoms together sequentialy. */ tail (chain, latest); } chain = latest; } if (chain == NULL) { /* Loop ran zero times. */ (void) emit_node (NOTHING); } return (ret_val); } /*----------------------------------------------------------------------* * piece - something followed by possible '*', '+', '?', or "{m,n}" * * Note that the branching code sequences used for the general cases of * *, +. ?, and {m,n} are somewhat optimized: they use the same * NOTHING node as both the endmarker for their branch list and the * body of the last branch. It might seem that this node could be * dispensed with entirely, but the endmarker role is not redundant. *----------------------------------------------------------------------*/ static char32 *piece (int *flag_param, len_range *range_param) { char32 *ret_val; char32 *next; char32 op_code; unsigned long min_max [2] = {REG_ZERO, REG_INFINITY}; int flags_local, i, brace_present = 0; int lazy = 0, comma_present = 0; int digit_present [2] = {0, 0}; len_range range_local; ret_val = atom (&flags_local, &range_local); if (ret_val == NULL) { return (NULL); /* Something went wrong. */ } op_code = *Reg_Parse; if (!IS_QUANTIFIER (op_code)) { *flag_param = flags_local; *range_param = range_local; return (ret_val); } else if (op_code == '{') { /* {n,m} quantifier present */ brace_present++; Reg_Parse++; /* This code will allow specifying a counting range in any of the following forms: {m,n} between m and n. {,n} same as {0,n} or between 0 and infinity. {m,} same as {m,0} or between m and infinity. {m} same as {m,m} or exactly m. {,} same as {0,0} or between 0 and infinity or just '*'. {} same as {0,0} or between 0 and infinity or just '*'. Note that specifying a max of zero, {m,0} is not allowed in the regex itself, but it is implemented internally that way to support '*', '+', and {min,} constructs and signals an unlimited number. */ for (i = 0; i < 2; i++) { /* Look for digits of number and convert as we go. The numeric maximum value for max and min of 65,535 is due to using 2 bytes to store each value in the compiled regex code. */ while (isdigit ((int) *Reg_Parse)) { /* (6553 * 10 + 6) > 65535 (16 bit max) */ if ( (min_max [i] == 6553UL && (*Reg_Parse - '0') <= 5) || (min_max [i] <= 6552UL)) { min_max [i] = (min_max [i] * 10UL) + (unsigned long) (*Reg_Parse - '0'); Reg_Parse++; digit_present [i]++; } else { if (i == 0) { Melder_sprint (Error_Text,128, U"min operand of {", min_max [0], *Reg_Parse, U",???} > 65535"); } else { Melder_sprint (Error_Text,128, U"max operand of {", min_max [0], U",", min_max [1], *Reg_Parse, U"} > 65535"); } REG_FAIL (Error_Text); } } if (!comma_present && *Reg_Parse == ',') { comma_present++; Reg_Parse++; } } /* A max of zero cannot be specified directly in the regex since it would signal a max of infinity. This code specifically disallows `{0,0}', `{,0}', and `{0}' which really means nothing to humans but would be interpreted as `{0,infinity}' or `*' if we didn't make this check. */ if (digit_present [0] && (min_max [0] == REG_ZERO) && !comma_present) { REG_FAIL (U"{0} is an invalid range"); } else if (digit_present [0] && (min_max [0] == REG_ZERO) && digit_present [1] && (min_max [1] == REG_ZERO)) { REG_FAIL (U"{0,0} is an invalid range"); } else if (digit_present [1] && (min_max [1] == REG_ZERO)) { if (digit_present [0]) { Melder_sprint (Error_Text,128, U"{", min_max [0], U",0} is an invalid range"); REG_FAIL (Error_Text); } else { REG_FAIL (U"{,0} is an invalid range"); } } if (!comma_present) { min_max [1] = min_max [0]; } /* {x} means {x,x} */ if (*Reg_Parse != '}') { REG_FAIL (U"{m,n} specification missing right \'}\'"); } else if (min_max [1] != REG_INFINITY && min_max [0] > min_max [1]) { /* Disallow a backward range. */ Melder_sprint (Error_Text,128, U"{", min_max [0], U",", min_max [1], U"} is an invalid range"); REG_FAIL (Error_Text); } } Reg_Parse++; /* Check for a minimal matching (non-greedy or "lazy") specification. */ if (*Reg_Parse == '?') { lazy = 1; Reg_Parse++; } /* Avoid overhead of counting if possible */ if (op_code == '{') { if (min_max [0] == REG_ZERO && min_max [1] == REG_INFINITY) { op_code = '*'; } else if (min_max [0] == REG_ONE && min_max [1] == REG_INFINITY) { op_code = '+'; } else if (min_max [0] == REG_ZERO && min_max [1] == REG_ONE) { op_code = '?'; } else if (min_max [0] == REG_ONE && min_max [1] == REG_ONE) { /* "x{1,1}" is the same as "x". No need to pollute the compiled regex with such nonsense. */ *flag_param = flags_local; *range_param = range_local; return (ret_val); } else if (Num_Braces > (int) UCHAR_MAX) { Melder_sprint (Error_Text,128, U"number of {m,n} constructs > ", UCHAR_MAX); REG_FAIL (Error_Text); } } if (op_code == '+') { min_max [0] = REG_ONE; } if (op_code == '?') { min_max [1] = REG_ONE; } /* It is dangerous to apply certain quantifiers to a possibly zero width item. */ if (! (flags_local & HAS_WIDTH)) { if (brace_present) { Melder_sprint (Error_Text,128, U"{", min_max [0], U",", min_max [1], U"} operand could be empty"); } else { Melder_sprint (Error_Text,128, op_code, U" operand could be empty"); } REG_FAIL (Error_Text); } *flag_param = (min_max [0] > REG_ZERO) ? (WORST | HAS_WIDTH) : WORST; if (range_local.lower >= 0) { if (min_max[1] != REG_INFINITY) { range_param->lower = range_local.lower * min_max[0]; range_param->upper = range_local.upper * min_max[1]; } else { range_param->lower = -1; /* Not a fixed-size length */ range_param->upper = -1; } } else { range_param->lower = -1; /* Not a fixed-size length */ range_param->upper = -1; } /*---------------------------------------------------------------------* * Symbol Legend For Node Structure Diagrams *---------------------------------------------------------------------* * (...) = general grouped thing * B = (B)ranch, K = bac(K), N = (N)othing * I = (I)nitialize count, C = Increment (C)ount * T~m = (T)est against mini(m)um- go to NEXT pointer if >= operand * T~x = (T)est against ma(x)imum- go to NEXT pointer if >= operand * '~' = NEXT pointer, \___| = forward pointer, |___/ = Backward pointer *---------------------------------------------------------------------*/ if (op_code == '*' && (flags_local & SIMPLE)) { insert ( (lazy ? LAZY_STAR : STAR), ret_val, 0UL, 0UL, 0); } else if (op_code == '+' && (flags_local & SIMPLE)) { insert (lazy ? LAZY_PLUS : PLUS, ret_val, 0UL, 0UL, 0); } else if (op_code == '?' && (flags_local & SIMPLE)) { insert (lazy ? LAZY_QUESTION : QUESTION, ret_val, 0UL, 0UL, 0); } else if (op_code == '{' && (flags_local & SIMPLE)) { insert (lazy ? LAZY_BRACE : BRACE, ret_val, min_max [0], min_max [1], 0); } else if ( (op_code == '*' || op_code == '+') && lazy) { /* Node structure for (x)*? Node structure for (x)+? construct. * construct. (Same as (x)*? except for initial * forward jump into parenthesis.) * * ___6____ * _______5_______ /________|______ * | _4__ 1_\ /| ____ | _\ * |/ | / |\ / |/ | | / |\ * B~ N~ B~ (...)~ K~ N~ N~ B~ N~ B~ (...)~ K~ N~ * \ \___2_______| \ \___________| * \_____3_______| \_____________| * */ tail (ret_val, emit_node (BACK)); /* 1 */ (void) insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 2,4 */ (void) insert (NOTHING, ret_val, 0UL, 0UL, 0); /* 3 */ next = emit_node (NOTHING); /* 2,3 */ offset_tail (ret_val, NODE_SIZE, next); /* 2 */ tail (ret_val, next); /* 3 */ insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 4,5 */ tail (ret_val, ret_val + (2 * NODE_SIZE)); /* 4 */ offset_tail (ret_val, 3 * NODE_SIZE, ret_val); /* 5 */ if (op_code == '+') { insert (NOTHING, ret_val, 0UL, 0UL, 0); /* 6 */ tail (ret_val, ret_val + (4 * NODE_SIZE)); /* 6 */ } } else if (op_code == '*') { /* Node structure for (x)* construct. * ____1_____ * | \ * B~ (...)~ K~ B~ N~ * \ \_|2 |\_| * \__3_______| 4 */ insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 1,3 */ offset_tail (ret_val, NODE_SIZE, emit_node (BACK)); /* 2 */ offset_tail (ret_val, NODE_SIZE, ret_val); /* 1 */ tail (ret_val, emit_node (BRANCH)); /* 3 */ tail (ret_val, emit_node (NOTHING)); /* 4 */ } else if (op_code == '+') { /* Node structure for (x)+ construct. * * ____2_____ * | \ * (...)~ B~ K~ B~ N~ * \_|\____|\_| * 1 3 4 */ next = emit_node (BRANCH); /* 1 */ tail (ret_val, next); /* 1 */ tail (emit_node (BACK), ret_val); /* 2 */ tail (next, emit_node (BRANCH)); /* 3 */ tail (ret_val, emit_node (NOTHING)); /* 4 */ } else if (op_code == '?' && lazy) { /* Node structure for (x)?? construct. * _4__ 1_ * / | / | * B~ N~ B~ (...)~ N~ * \ \___2____| * \_____3____| */ (void) insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 2,4 */ (void) insert (NOTHING, ret_val, 0UL, 0UL, 0); /* 3 */ next = emit_node (NOTHING); /* 1,2,3 */ offset_tail (ret_val, 2 * NODE_SIZE, next); /* 1 */ offset_tail (ret_val, NODE_SIZE, next); /* 2 */ tail (ret_val, next); /* 3 */ insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 4 */ tail (ret_val, (ret_val + (2 * NODE_SIZE))); /* 4 */ } else if (op_code == '?') { /* Node structure for (x)? construct. * ___1____ _2 * / |/ | * B~ (...)~ B~ N~ * \__3_| */ insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 1 */ tail (ret_val, emit_node (BRANCH)); /* 1 */ next = emit_node (NOTHING); /* 2,3 */ tail (ret_val, next); /* 2 */ offset_tail (ret_val, NODE_SIZE, next); /* 3 */ } else if (op_code == '{' && min_max [0] == min_max [1]) { /* Node structure for (x){m}, (x){m}?, (x){m,m}, or (x){m,m}? constructs. * Note that minimal and maximal matching mean the same thing when we * specify the minimum and maximum to be the same value. * _______3_____ * | 1_ _2 \ * | / |/ | \ * I~ (...)~ C~ T~m K~ N~ * \_| \_____| * 5 4 */ tail (ret_val, emit_special (INC_COUNT, 0UL, Num_Braces)); /* 1 */ tail (ret_val, emit_special (TEST_COUNT, min_max [0], Num_Braces));/* 2 */ tail (emit_node (BACK), ret_val); /* 3 */ tail (ret_val, emit_node (NOTHING)); /* 4 */ next = insert (INIT_COUNT, ret_val, 0UL, 0UL, Num_Braces); /* 5 */ tail (ret_val, next); /* 5 */ Num_Braces++; } else if (op_code == '{' && lazy) { if (min_max [0] == REG_ZERO && min_max [1] != REG_INFINITY) { /* Node structure for (x){0,n}? or {,n}? construct. * _________3____________ * 8_| _4__ 1_ _2 \ * / |/ | / |/ | \ * I~ B~ N~ B~ (...)~ C~ T~x K~ N~ * \ \ \__7__| * \ \_________6_______| * \______5____________| */ tail (ret_val, emit_special (INC_COUNT, 0UL, Num_Braces)); /* 1 */ next = emit_special (TEST_COUNT, min_max [0], Num_Braces); /* 2,7 */ tail (ret_val, next); /* 2 */ (void) insert (BRANCH, ret_val, 0UL, 0UL, Num_Braces); /* 4,6 */ (void) insert (NOTHING, ret_val, 0UL, 0UL, Num_Braces); /* 5 */ (void) insert (BRANCH, ret_val, 0UL, 0UL, Num_Braces); /* 3,4,8 */ tail (emit_node (BACK), ret_val); /* 3 */ tail (ret_val, ret_val + (2 * NODE_SIZE)); /* 4 */ next = emit_node (NOTHING); /* 5,6,7 */ offset_tail (ret_val, NODE_SIZE, next); /* 5 */ offset_tail (ret_val, 2 * NODE_SIZE, next); /* 6 */ offset_tail (ret_val, 3 * NODE_SIZE, next); /* 7 */ next = insert (INIT_COUNT, ret_val, 0UL, 0UL, Num_Braces); /* 8 */ tail (ret_val, next); /* 8 */ } else if (min_max [0] > REG_ZERO && min_max [1] == REG_INFINITY) { /* Node structure for (x){m,}? construct. * ______8_________________ * | _______3_____ \ * | _7__ | 1_ _2 \ \ * |/ | | / |/ | \ \ * I~ B~ N~ B~ (...)~ C~ T~m K~ K~ N~ * \_____\__\_| \_4___| | * 9 \ \_________5__________| * \_______6______________| */ tail (ret_val, emit_special (INC_COUNT, 0UL, Num_Braces)); /* 1 */ next = emit_special (TEST_COUNT, min_max [0], Num_Braces); /* 2,4 */ tail (ret_val, next); /* 2 */ tail (emit_node (BACK), ret_val); /* 3 */ tail (ret_val, emit_node (BACK)); /* 4 */ (void) insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 5,7 */ (void) insert (NOTHING, ret_val, 0UL, 0UL, 0); /* 6 */ next = emit_node (NOTHING); /* 5,6 */ offset_tail (ret_val, NODE_SIZE, next); /* 5 */ tail (ret_val, next); /* 6 */ (void) insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 7,8 */ tail (ret_val, ret_val + (2 * NODE_SIZE)); /* 7 */ offset_tail (ret_val, 3 * NODE_SIZE, ret_val); /* 8 */ (void) insert (INIT_COUNT, ret_val, 0UL, 0UL, Num_Braces); /* 9 */ tail (ret_val, ret_val + INDEX_SIZE + (4 * NODE_SIZE)); /* 9 */ } else { /* Node structure for (x){m,n}? construct. * ______9_____________________ * | _____________3___ \ * | __8_ | 1_ _2 \ \ * |/ | | / |/ | \ \ * I~ B~ N~ B~ (...)~ C~ T~x T~m K~ K~ N~ * \_____\__\_| \ \__4__| | * 10 \ \ \_7_________| * \ \_________6_____________| * \_______5_________________| */ tail (ret_val, emit_special (INC_COUNT, 0UL, Num_Braces)); /* 1 */ next = emit_special (TEST_COUNT, min_max [1], Num_Braces); /* 2,7 */ tail (ret_val, next); /* 2 */ next = emit_special (TEST_COUNT, min_max [0], Num_Braces); /* 4 */ tail (emit_node (BACK), ret_val); /* 3 */ tail (next, emit_node (BACK)); /* 4 */ (void) insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 6,8 */ (void) insert (NOTHING, ret_val, 0UL, 0UL, 0); /* 5 */ (void) insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 8,9 */ next = emit_node (NOTHING); /* 5,6,7 */ offset_tail (ret_val, NODE_SIZE, next); /* 5 */ offset_tail (ret_val, 2 * NODE_SIZE, next); /* 6 */ offset_tail (ret_val, 3 * NODE_SIZE, next); /* 7 */ tail (ret_val, ret_val + (2 * NODE_SIZE)); /* 8 */ offset_tail (next, -NODE_SIZE, ret_val); /* 9 */ insert (INIT_COUNT, ret_val, 0UL, 0UL, Num_Braces); /* 10 */ tail (ret_val, ret_val + INDEX_SIZE + (4 * NODE_SIZE)); /* 10 */ } Num_Braces++; } else if (op_code == '{') { if (min_max [0] == REG_ZERO && min_max [1] != REG_INFINITY) { /* Node structure for (x){0,n} or (x){,n} construct. * * ___3____________ * | 1_ _2 \ 5_ * | / |/ | \ / | * I~ B~ (...)~ C~ T~x K~ B~ N~ * \_|\ \_6___|__| * 7 \________4________| */ tail (ret_val, emit_special (INC_COUNT, 0UL, Num_Braces)); /* 1 */ next = emit_special (TEST_COUNT, min_max [1], Num_Braces); /* 2,6 */ tail (ret_val, next); /* 2 */ (void) insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 3,4,7 */ tail (emit_node (BACK), ret_val); /* 3 */ next = emit_node (BRANCH); /* 4,5 */ tail (ret_val, next); /* 4 */ tail (next, emit_node (NOTHING)); /* 5,6 */ offset_tail (ret_val, NODE_SIZE, next); /* 6 */ next = insert (INIT_COUNT, ret_val, 0UL, 0UL, Num_Braces); /* 7 */ tail (ret_val, next); /* 7 */ } else if (min_max [0] > REG_ZERO && min_max [1] == REG_INFINITY) { /* Node structure for (x){m,} construct. * __________4________ * | __3__________ \ * _|___| 1_ _2 \ \ _7 * / | 8 | / |/ | \ \ / | * I~ B~ (...)~ C~ T~m K~ K~ B~ N~ * \ \_5___| | * \__________6__________| */ tail (ret_val, emit_special (INC_COUNT, 0UL, Num_Braces)); /* 1 */ next = emit_special (TEST_COUNT, min_max [0], Num_Braces); /* 2 */ tail (ret_val, next); /* 2 */ tail (emit_node (BACK), ret_val); /* 3 */ (void) insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 4,6 */ next = emit_node (BACK); /* 4 */ tail (next, ret_val); /* 4 */ offset_tail (ret_val, NODE_SIZE, next); /* 5 */ tail (ret_val, emit_node (BRANCH)); /* 6 */ tail (ret_val, emit_node (NOTHING)); /* 7 */ insert (INIT_COUNT, ret_val, 0UL, 0UL, Num_Braces); /* 8 */ tail (ret_val, ret_val + INDEX_SIZE + (2 * NODE_SIZE)); /* 8 */ } else { /* Node structure for (x){m,n} construct. * _____6________________ * | _____________3___ \ * 9_|__| 1_ _2 \ \ _8 * / | | / |/ | \ \ / | * I~ B~ (...)~ C~ T~x T~m K~ K~ B~ N~ * \ \ \__4__| | | * \ \_7_________|__| * \_________5_____________| */ tail (ret_val, emit_special (INC_COUNT, 0UL, Num_Braces)); /* 1 */ next = emit_special (TEST_COUNT, min_max [1], Num_Braces); /* 2,4 */ tail (ret_val, next); /* 2 */ next = emit_special (TEST_COUNT, min_max [0], Num_Braces); /* 4 */ tail (emit_node (BACK), ret_val); /* 3 */ tail (next, emit_node (BACK)); /* 4 */ (void) insert (BRANCH, ret_val, 0UL, 0UL, 0); /* 5,6 */ next = emit_node (BRANCH); /* 5,8 */ tail (ret_val, next); /* 5 */ offset_tail (next, -NODE_SIZE, ret_val); /* 6 */ next = emit_node (NOTHING); /* 7,8 */ offset_tail (ret_val, NODE_SIZE, next); /* 7 */ offset_tail (next, -NODE_SIZE, next); /* 8 */ (void) insert (INIT_COUNT, ret_val, 0UL, 0UL, Num_Braces); /* 9 */ tail (ret_val, ret_val + INDEX_SIZE + (2 * NODE_SIZE)); /* 9 */ } Num_Braces++; } else { /* We get here if the IS_QUANTIFIER macro is not coordinated properly with this function. */ REG_FAIL (U"internal error #2, `piece\'"); } if (IS_QUANTIFIER (*Reg_Parse)) { if (op_code == '{') { Melder_sprint (Error_Text,128, U"nested quantifiers, {m,n}", *Reg_Parse); } else { Melder_sprint (Error_Text,128, U"nested quantifiers, ", op_code, *Reg_Parse); } REG_FAIL (Error_Text); } return (ret_val); } /*----------------------------------------------------------------------* * atom * * Process one regex item at the lowest level * * OPTIMIZATION: Lumps a continuous sequence of ordinary characters * together so that it can turn them into a single EXACTLY node, which * is smaller to store and faster to run. *----------------------------------------------------------------------*/ static char32 *atom (int *flag_param, len_range *range_param) { char32 *ret_val; char32 test; int flags_local; len_range range_local; *flag_param = WORST; /* Tentatively. */ range_param->lower = 0; /* Idem */ range_param->upper = 0; /* Process any regex comments, e.g. `(?# match next token->)'. The terminating right parenthesis cannot be escaped. The comment stops at the first right parenthesis encountered (or the end of the regex string)... period. Handles multiple sequential comments, e.g. `(?# one)(?# two)...' */ while (*Reg_Parse == '(' && * (Reg_Parse + 1) == '?' && * (Reg_Parse + 2) == '#') { Reg_Parse += 3; while (*Reg_Parse != ')' && *Reg_Parse != '\0') { Reg_Parse++; } if (*Reg_Parse == ')') { Reg_Parse++; } if (*Reg_Parse == ')' || *Reg_Parse == '|' || *Reg_Parse == '\0') { /* Hit end of regex string or end of parenthesized regex; have to return "something" (i.e. a NOTHING node) to avoid generating an error. */ ret_val = emit_node (NOTHING); return (ret_val); } } switch (*Reg_Parse++) { case '^': ret_val = emit_node (BOL); break; case '$': ret_val = emit_node (EOL); break; case '<': ret_val = emit_node (BOWORD); break; case '>': ret_val = emit_node (EOWORD); break; case '.': if (Match_Newline) { ret_val = emit_node (EVERY); } else { ret_val = emit_node (ANY); } *flag_param |= (HAS_WIDTH | SIMPLE); range_param->lower = 1; range_param->upper = 1; break; case '(': if (*Reg_Parse == '?') { /* Special parenthetical expression */ Reg_Parse++; range_local.lower = 0; /* Make sure it is always used */ range_local.upper = 0; if (*Reg_Parse == ':') { Reg_Parse++; ret_val = chunk (NO_CAPTURE, &flags_local, &range_local); } else if (*Reg_Parse == '=') { Reg_Parse++; ret_val = chunk (POS_AHEAD_OPEN, &flags_local, &range_local); } else if (*Reg_Parse == '!') { Reg_Parse++; ret_val = chunk (NEG_AHEAD_OPEN, &flags_local, &range_local); } else if (*Reg_Parse == 'i') { Reg_Parse++; ret_val = chunk (INSENSITIVE, &flags_local, &range_local); } else if (*Reg_Parse == 'I') { Reg_Parse++; ret_val = chunk (SENSITIVE, &flags_local, &range_local); } else if (*Reg_Parse == 'n') { Reg_Parse++; ret_val = chunk (NEWLINE, &flags_local, &range_local); } else if (*Reg_Parse == 'N') { Reg_Parse++; ret_val = chunk (NO_NEWLINE, &flags_local, &range_local); } else if (*Reg_Parse == '<') { Reg_Parse++; if (*Reg_Parse == '=') { Reg_Parse++; ret_val = chunk (POS_BEHIND_OPEN, &flags_local, &range_local); } else if (*Reg_Parse == '!') { Reg_Parse++; ret_val = chunk (NEG_BEHIND_OPEN, &flags_local, &range_local); } else { Melder_sprint (Error_Text,128, U"invalid look-behind syntax, \"(?<", *Reg_Parse, U"...)\""); REG_FAIL (Error_Text); } } else { Melder_sprint (Error_Text,128, U"invalid grouping syntax, \"(?", *Reg_Parse, U"...)\""); REG_FAIL (Error_Text); } } else { /* Normal capturing parentheses */ ret_val = chunk (PAREN, &flags_local, &range_local); } if (ret_val == NULL) { return (NULL); /* Something went wrong. */ } /* Add HAS_WIDTH flag if it was set by call to chunk. */ *flag_param |= flags_local & HAS_WIDTH; *range_param = range_local; break; case '\0': case '|': case ')': REG_FAIL (U"internal error #3, `atom\'"); /* Supposed to be */ /* caught earlier. */ case '?': case '+': case '*': Melder_sprint (Error_Text,128, * (Reg_Parse - 1), U" follows nothing"); REG_FAIL (Error_Text); case '{': if (Enable_Counting_Quantifier) { REG_FAIL (U"{m,n} follows nothing"); } else { ret_val = emit_node (EXACTLY); /* Treat braces as literals. */ emit_byte ('{'); emit_byte ('\0'); range_param->lower = 1; range_param->upper = 1; } break; case '[': { unsigned int second_value; unsigned int last_value; char32 last_emit = 0; /* Handle characters that can only occur at the start of a class. */ if (*Reg_Parse == '^') { /* Complement of range. */ ret_val = emit_node (ANY_BUT); Reg_Parse++; /* All negated classes include newline unless escaped with a "(?n)" switch. */ if (!Match_Newline) { emit_byte ('\n'); } } else { ret_val = emit_node (ANY_OF); } if (*Reg_Parse == ']' || *Reg_Parse == '-') { /* If '-' or ']' is the first character in a class, it is a literal character in the class. */ last_emit = *Reg_Parse; emit_byte (*Reg_Parse); Reg_Parse++; } /* Handle the rest of the class characters. */ while (*Reg_Parse != '\0' && *Reg_Parse != ']') { if (*Reg_Parse == '-') { /* Process a range, e.g [a-z]. */ Reg_Parse++; if (*Reg_Parse == ']' || *Reg_Parse == '\0') { /* If '-' is the last character in a class it is a literal character. If `Reg_Parse' points to the end of the regex string, an error will be generated later. */ emit_byte ('-'); last_emit = '-'; } else { /* We must get the range starting character value from the emitted code since it may have been an escaped character. `second_value' is set one larger than the just emitted character value. This is done since `second_value' is used as the start value for the loop that emits the values in the range. Since we have already emitted the first character of the class, we do not want to emit it again. */ second_value = ( (unsigned int) last_emit) + 1; if (*Reg_Parse == '\\') { /* Handle escaped characters within a class range. Specifically disallow shortcut escapes as the end of a class range. To allow this would be ambiguous since shortcut escapes represent a set of characters, and it would not be clear which character of the class should be treated as the "last" character. */ Reg_Parse++; if ( (test = numeric_escape (*Reg_Parse, &Reg_Parse))) { last_value = (unsigned int) test; } else if ( (test = literal_escape (*Reg_Parse))) { last_value = (unsigned int) test; } else if (shortcut_escape (*Reg_Parse, NULL, CHECK_CLASS_ESCAPE)) { Melder_sprint (Error_Text, 128, U"\\", *Reg_Parse, U" is not allowed as range operand"); REG_FAIL (Error_Text); } else { Melder_sprint (Error_Text, 128, U"\\", *Reg_Parse, U" is an invalid char class escape sequence"); REG_FAIL (Error_Text); } } else { last_value = U_CHAR_AT (Reg_Parse); } if (Is_Case_Insensitive) { second_value = (unsigned int) tolower ( (int) second_value); last_value = (unsigned int) tolower ( (int) last_value); } /* For case insensitive, something like [A-_] will generate an error here since ranges are converted to lower case. */ if (second_value - 1 > last_value) { REG_FAIL (U"invalid [] range"); } /* If only one character in range (e.g [a-a]) then this loop is not run since the first character of any range was emitted by the previous iteration of while loop. */ for (; second_value <= last_value; second_value++) { emit_class_byte (second_value); } last_emit = (char32) last_value; Reg_Parse++; } /* End class character range code. */ } else if (*Reg_Parse == '\\') { Reg_Parse++; if ( (test = numeric_escape (*Reg_Parse, &Reg_Parse)) != '\0') { emit_class_byte (test); last_emit = test; } else if ( (test = literal_escape (*Reg_Parse)) != '\0') { emit_byte (test); last_emit = test; } else if (shortcut_escape (*Reg_Parse, NULL, CHECK_CLASS_ESCAPE)) { if (* (Reg_Parse + 1) == '-') { /* Specifically disallow shortcut escapes as the start of a character class range (see comment above.) */ Melder_sprint (Error_Text,128, U"\\", *Reg_Parse, U" not allowed as range operand"); REG_FAIL (Error_Text); } else { /* Emit the bytes that are part of the shortcut escape sequence's range (e.g. \d = 0123456789) */ shortcut_escape (*Reg_Parse, NULL, EMIT_CLASS_BYTES); } } else { Melder_sprint (Error_Text,128, U"\\", *Reg_Parse, U" is an invalid char class escape sequence"); REG_FAIL (Error_Text); } Reg_Parse++; /* End of class escaped sequence code */ } else { emit_class_byte (*Reg_Parse); /* Ordinary class character. */ last_emit = *Reg_Parse; Reg_Parse++; } } /* End of while (*Reg_Parse != '\0' && *Reg_Parse != ']') */ if (*Reg_Parse != ']') { REG_FAIL (U"missing right \']\'"); } emit_byte ('\0'); /* NOTE: it is impossible to specify an empty class. This is because [] would be interpreted as "begin character class" followed by a literal ']' character and no "end character class" delimiter (']'). Because of this, it is always safe to assume that a class HAS_WIDTH. */ Reg_Parse++; *flag_param |= HAS_WIDTH | SIMPLE; range_param->lower = 1; range_param->upper = 1; } break; /* End of character class code. */ case '\\': /* Force Error_Text to have a length of zero. This way we can tell if either of the calls to shortcut_escape() or back_ref() fill Error_Text with an error message. */ Error_Text [0] = '\0'; if ( (ret_val = shortcut_escape (*Reg_Parse, flag_param, EMIT_NODE))) { Reg_Parse++; range_param->lower = 1; range_param->upper = 1; break; } else if ( (ret_val = back_ref (Reg_Parse, flag_param, EMIT_NODE))) { /* Can't make any assumptions about a back-reference as to SIMPLE or HAS_WIDTH. For example (^|<) is neither simple nor has width. So we don't flip bits in flag_param here. */ Reg_Parse++; /* Back-references always have an unknown length */ range_param->lower = -1; range_param->upper = -1; break; } if (str32len (Error_Text) > 0) { REG_FAIL (Error_Text); } /* At this point it is apparent that the escaped character is not a shortcut escape or back-reference. Back up one character to allow the default code to include it as an ordinary character. */ /* Fall through to Default case to handle literal escapes and numeric escapes. */ default: Reg_Parse--; /* If we fell through from the above code, we are now pointing at the back slash (\) character. */ { char32 *parse_save; int len = 0; if (Is_Case_Insensitive) { ret_val = emit_node (SIMILAR); } else { ret_val = emit_node (EXACTLY); } /* Loop until we find a meta character, shortcut escape, back reference, or end of regex string. */ for (; *Reg_Parse != '\0' && ! str32chr (Meta_Char, *Reg_Parse); len++) { /* Save where we are in case we have to back this character out. */ parse_save = Reg_Parse; if (*Reg_Parse == '\\') { Reg_Parse++; /* Point to escaped character */ Error_Text [0] = '\0'; /* See comment above. */ if ( (test = numeric_escape (*Reg_Parse, &Reg_Parse))) { if (Is_Case_Insensitive) { emit_byte (tolower ((int) test)); } else { emit_byte (test); } } else if ( (test = literal_escape (*Reg_Parse))) { emit_byte (test); } else if (back_ref (Reg_Parse, NULL, CHECK_ESCAPE)) { /* Leave back reference for next `atom' call */ Reg_Parse--; break; } else if (shortcut_escape (*Reg_Parse, NULL, CHECK_ESCAPE)) { /* Leave shortcut escape for next `atom' call */ Reg_Parse--; break; } else { if (str32len (Error_Text) == 0) { /* None of the above calls generated an error message so generate our own here. */ Melder_sprint (Error_Text,128, U"\\", *Reg_Parse, U" is an invalid escape sequence"); } REG_FAIL (Error_Text); } Reg_Parse++; } else { /* Ordinary character */ if (Is_Case_Insensitive) { emit_byte (tolower ((int) *Reg_Parse)); } else { emit_byte (*Reg_Parse); } Reg_Parse++; } /* If next regex token is a quantifier (?, +. *, or {m,n}) and our EXACTLY node so far is more than one character, leave the last character to be made into an EXACTLY node one character wide for the multiplier to act on. For example 'abcd* would have an EXACTLY node with an 'abc' operand followed by a STAR node followed by another EXACTLY node with a 'd' operand. */ if (IS_QUANTIFIER (*Reg_Parse) && len > 0) { Reg_Parse = parse_save; /* Point to previous regex token. */ if (Code_Emit_Ptr == &Compute_Size) { Reg_Size--; } else { Code_Emit_Ptr--; /* Write over previously emitted byte. */ } break; } } if (len <= 0) { REG_FAIL (U"internal error #4, `atom\'"); } *flag_param |= HAS_WIDTH; if (len == 1) { *flag_param |= SIMPLE; } range_param->lower = len; range_param->upper = len; emit_byte ('\0'); } } /* END switch (*Reg_Parse++) */ return (ret_val); } /*----------------------------------------------------------------------* * emit_node * * Emit (if appropriate) the op code for a regex node atom. * * The NEXT pointer is initialized to NULL. * * Returns a pointer to the START of the emitted node. *----------------------------------------------------------------------*/ static char32 *emit_node (int op_code) { char32 *ret_val; char32 *ptr; ret_val = Code_Emit_Ptr; /* Return address of start of node */ if (ret_val == &Compute_Size) { Reg_Size += NODE_SIZE; } else { ptr = ret_val; *ptr++ = op_code; *ptr++ = '\0'; /* Null "NEXT" pointer. */ *ptr++ = '\0'; Code_Emit_Ptr = ptr; } return (ret_val); } /*----------------------------------------------------------------------* * emit_byte * * Emit (if appropriate) a byte of code (usually part of an operand.) *----------------------------------------------------------------------*/ static void emit_byte (char32 c) { if (Code_Emit_Ptr == &Compute_Size) { Reg_Size++; } else { *Code_Emit_Ptr++ = c; } } /*----------------------------------------------------------------------* * emit_class_byte * * Emit (if appropriate) a byte of code (usually part of a character * class operand.) *----------------------------------------------------------------------*/ static void emit_class_byte (char32 c) { if (Code_Emit_Ptr == &Compute_Size) { Reg_Size++; if (Is_Case_Insensitive && iswalpha ((int) c)) { Reg_Size++; } } else if (Is_Case_Insensitive && iswalpha ((int) c)) { /* For case insensitive character classes, emit both upper and lower case versions of alphabetical characters. */ *Code_Emit_Ptr++ = (char32) towlower ((int) c); *Code_Emit_Ptr++ = (char32) towupper ((int) c); } else { *Code_Emit_Ptr++ = c; } } /*----------------------------------------------------------------------* * emit_special * * Emit nodes that need special processing. *----------------------------------------------------------------------*/ static char32 *emit_special ( char32 op_code, unsigned long test_val, int index) { char32 *ret_val = &Compute_Size; char32 *ptr; if (Code_Emit_Ptr == &Compute_Size) { switch (op_code) { case POS_BEHIND_OPEN: case NEG_BEHIND_OPEN: Reg_Size += LENGTH_SIZE; /* Length of the look-behind match */ Reg_Size += NODE_SIZE; /* Make room for the node */ break; case TEST_COUNT: Reg_Size += NEXT_PTR_SIZE; /* Make room for a test value. */ case INC_COUNT: Reg_Size += INDEX_SIZE; /* Make room for an index value. */ default: Reg_Size += NODE_SIZE; /* Make room for the node. */ } } else { ret_val = emit_node (op_code); /* Return the address for start of node. */ ptr = Code_Emit_Ptr; if (op_code == INC_COUNT || op_code == TEST_COUNT) { *ptr++ = (char32) index; if (op_code == TEST_COUNT) { *ptr++ = PUT_OFFSET_L (test_val); *ptr++ = PUT_OFFSET_R (test_val); } } else if (op_code == POS_BEHIND_OPEN || op_code == NEG_BEHIND_OPEN) { *ptr++ = PUT_OFFSET_L (test_val); *ptr++ = PUT_OFFSET_R (test_val); *ptr++ = PUT_OFFSET_L (test_val); *ptr++ = PUT_OFFSET_R (test_val); } Code_Emit_Ptr = ptr; } return (ret_val); } /*----------------------------------------------------------------------* * insert * * Insert a node in front of already emitted node(s). Means relocating * the operand. Code_Emit_Ptr points one byte past the just emitted * node and operand. The parameter `insert_pos' points to the location * where the new node is to be inserted. *----------------------------------------------------------------------*/ static char32 *insert ( char32 op, char32 *insert_pos, long min, long max, int index) { char32 *src; char32 *dst; char32 *place; int insert_size = NODE_SIZE; if (op == BRACE || op == LAZY_BRACE) { /* Make room for the min and max values. */ insert_size += (2 * NEXT_PTR_SIZE); } else if (op == INIT_COUNT) { /* Make room for an index value . */ insert_size += INDEX_SIZE; } if (Code_Emit_Ptr == &Compute_Size) { Reg_Size += insert_size; return &Compute_Size; } src = Code_Emit_Ptr; Code_Emit_Ptr += insert_size; dst = Code_Emit_Ptr; /* Relocate the existing emitted code to make room for the new node. */ while (src > insert_pos) { *--dst = *--src; } place = insert_pos; /* Where operand used to be. */ *place++ = op; /* Inserted operand. */ *place++ = '\0'; /* NEXT pointer for inserted operand. */ *place++ = '\0'; if (op == BRACE || op == LAZY_BRACE) { *place++ = PUT_OFFSET_L (min); *place++ = PUT_OFFSET_R (min); *place++ = PUT_OFFSET_L (max); *place++ = PUT_OFFSET_R (max); } else if (op == INIT_COUNT) { *place++ = (char32) index; } return place; /* Return a pointer to the start of the code moved. */ } /*----------------------------------------------------------------------* * tail - Set the next-pointer at the end of a node chain. *----------------------------------------------------------------------*/ static void tail (char32 *search_from, char32 *point_to) { char32 *scan; char32 *next; int offset; if (search_from == &Compute_Size) { return; } /* Find the last node in the chain (node with a null NEXT pointer) */ scan = search_from; for (;;) { next = next_ptr (scan); if (!next) { break; } scan = next; } if (GET_OP_CODE (scan) == BACK) { offset = scan - point_to; } else { offset = point_to - scan; } /* Set NEXT pointer */ * (scan + 1) = PUT_OFFSET_L (offset); * (scan + 2) = PUT_OFFSET_R (offset); } /*--------------------------------------------------------------------* * offset_tail * * Perform a tail operation on (ptr + offset). *--------------------------------------------------------------------*/ static void offset_tail (char32 *ptr, int offset, char32 *val) { if (ptr == &Compute_Size || ptr == NULL) { return; } tail (ptr + offset, val); } /*--------------------------------------------------------------------* * branch_tail * * Perform a tail operation on (ptr + offset) but only if `ptr' is a * BRANCH node. *--------------------------------------------------------------------*/ static void branch_tail (char32 *ptr, int offset, char32 *val) { if (ptr == &Compute_Size || ptr == NULL || GET_OP_CODE (ptr) != BRANCH) { return; } tail (ptr + offset, val); } /*--------------------------------------------------------------------* * shortcut_escape * * Implements convenient escape sequences that represent entire * character classes or special location assertions (similar to escapes * supported by Perl) * _ * \d Digits [0-9] | * \D NOT a digit [^0-9] | (Examples * \l Letters [a-zA-Z] | at left * \L NOT a Letter [^a-zA-Z] | are * \s Whitespace [ \t\n\r\f\v] | for * \S NOT Whitespace [^ \t\n\r\f\v] | C * \w "Word" character [a-zA-Z0-9_] | Locale) * \W NOT a "Word" character [^a-zA-Z0-9_] _| * * \B Matches any character that is NOT a word-delimiter * * Codes for the "emit" parameter: * * EMIT_NODE * Emit a shortcut node. Shortcut nodes have an implied set of * class characters. This helps keep the compiled regex string * small. * * EMIT_CLASS_BYTES * Emit just the equivalent characters of the class. This makes * the escape usable from within a class, e.g. [a-fA-F\d]. Only * \d, \D, \s, \S, \w, and \W can be used within a class. * * CHECK_ESCAPE * Only verify that this is a valid shortcut escape. * * CHECK_CLASS_ESCAPE * Same as CHECK_ESCAPE but only allows characters valid within * a klas. * *--------------------------------------------------------------------*/ static char32 *shortcut_escape ( char32 c, int *flag_param, int emit) { char32 *klas = NULL; static const char32 *codes = U"ByYdDlLsSwW"; char32 *ret_val = (char32 *) 1; /* Assume success. */ const char32 *valid_codes; if (emit == EMIT_CLASS_BYTES || emit == CHECK_CLASS_ESCAPE) { valid_codes = codes + 3; /* \B, \y and \Y are not allowed in classes */ } else { valid_codes = codes; } if (! str32chr (valid_codes, c)) { return NULL; /* Not a valid shortcut escape sequence */ } else if (emit == CHECK_ESCAPE || emit == CHECK_CLASS_ESCAPE) { return ret_val; /* Just checking if this is a valid shortcut escape. */ } switch (c) { case 'd': case 'D': if (emit == EMIT_CLASS_BYTES) { klas = ASCII_Digits; } else if (emit == EMIT_NODE) { ret_val = (iswlower ((int) c) ? emit_node (DIGIT) : emit_node (NOT_DIGIT)); } break; case 'l': case 'L': if (emit == EMIT_CLASS_BYTES) { klas = Letter_Char; } else if (emit == EMIT_NODE) { ret_val = (iswlower ((int) c) ? emit_node (LETTER) : emit_node (NOT_LETTER)); } break; case 's': case 'S': if (emit == EMIT_CLASS_BYTES) { if (Match_Newline) { emit_byte ('\n'); } klas = White_Space; } else if (emit == EMIT_NODE) { if (Match_Newline) { ret_val = (iswlower ((int) c) ? emit_node (SPACE_NL) : emit_node (NOT_SPACE_NL)); } else { ret_val = (iswlower ((int) c) ? emit_node (SPACE) : emit_node (NOT_SPACE)); } } break; case 'w': case 'W': if (emit == EMIT_CLASS_BYTES) { klas = Word_Char; } else if (emit == EMIT_NODE) { ret_val = (iswlower ((int) c) ? emit_node (WORD_CHAR) : emit_node (NOT_WORD_CHAR)); } break; /* Since the delimiter table is not available at regex compile time \B, \Y and \Y can only generate a node. At run time, the delimiter table will be available for these nodes to use. */ case 'y': if (emit == EMIT_NODE) { ret_val = emit_node (IS_DELIM); } else { REG_FAIL (U"internal error #5 `shortcut_escape\'"); } break; case 'Y': if (emit == EMIT_NODE) { ret_val = emit_node (NOT_DELIM); } else { REG_FAIL (U"internal error #6 `shortcut_escape\'"); } break; case 'B': if (emit == EMIT_NODE) { ret_val = emit_node (NOT_BOUNDARY); } else { REG_FAIL (U"internal error #7 `shortcut_escape\'"); } break; default: /* We get here if there isn't a case for every character in the string "codes" */ REG_FAIL (U"internal error #8 `shortcut_escape\'"); } if (emit == EMIT_NODE && c != 'B') { *flag_param |= (HAS_WIDTH | SIMPLE); } if (klas) { /* Emit bytes within a character class operand. */ while (*klas != '\0') { emit_byte (*klas++); } } return ret_val; } /*--------------------------------------------------------------------* * numeric_escape * * Implements hex and octal numeric escape sequence syntax. * * Hexadecimal Escape: \x## Max of two digits Must have leading 'x'. * Octal Escape: \0### Max of three digits and not greater * than 377 octal. Must have leading zero. * * Returns the actual character value or NULL if not a valid hex or * octal escape. REG_FAIL is called if \x0, \x00, \0, \00, \000, or * \0000 is specified. *--------------------------------------------------------------------*/ static char32 numeric_escape ( char32 c, char32 **parse) { static char32 digits [] = { 'f', 'e', 'd', 'c', 'b', 'a', 'F', 'E', 'D', 'C', 'B', 'A', '9', '8', '7', '6', '5', '4', '3', '2', '1', '0', '\0' }; static unsigned int digit_val [] = { 15, 14, 13, 12, 11, 10, /* Lower case Hex digits */ 15, 14, 13, 12, 11, 10, /* Upper case Hex digits */ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; /* Decimal Digits */ char32 *scan; char32 *pos_ptr; char32 *digit_str; unsigned int value = 0; unsigned int radix = 8; int width = 3; /* Can not be bigger than \0377 */ int pos_delta = 14; int i, pos; switch (c) { case '0': digit_str = digits + pos_delta; /* Only use Octal digits, i.e. 0-7. */ break; case 'x': case 'X': width = 2; /* Can not be bigger than \0377 */ radix = 16; pos_delta = 0; digit_str = digits; /* Use all of the digit characters. */ break; default: return ('\0'); /* Not a numeric escape */ } scan = *parse; scan++; /* Only change *parse on success. */ pos_ptr = str32chr (digit_str, *scan); for (i = 0; pos_ptr != NULL && (i < width); i++) { pos = (pos_ptr - digit_str) + pos_delta; value = (value * radix) + digit_val [pos]; /* If this digit makes the value over 255, treat this digit as a literal character instead of part of the numeric escape. For example, \0777 will be processed as \077 (an 'M') and a literal '7' character, NOT 511 decimal which is > 255. */ if (value > 255) { /* Back out calculations for last digit processed. */ value -= digit_val [pos]; value /= radix; break; /* Note that scan will not be incremented and still points to the digit that caused overflow. It will be decremented by the "else" below to point to the last character that is considered to be part of the octal escape. */ } scan++; pos_ptr = str32chr (digit_str, *scan); } /* Handle the case of "\0" i.e. trying to specify a NULL character. */ if (value == 0) { if (c == '0') { Melder_sprint (Error_Text,128, U"\\00 is an invalid octal escape"); } else { Melder_sprint (Error_Text,128, U"\\", c, U"0 is an invalid hexadecimal escape"); } } else { /* Point to the last character of the number on success. */ scan--; *parse = scan; } return value; } /*--------------------------------------------------------------------* * literal_escape * * Recognize escaped literal characters (prefixed with backslash), * and translate them into the corresponding character. * * Returns the proper character value or NULL if not a valid literal * escape. *--------------------------------------------------------------------*/ static char32 literal_escape (char32 c) { static char32 valid_escape [] = { 'a', 'b', 'e', 'f', 'n', 'r', 't', 'v', '(', ')', '-', '[', ']', '<', '>', '{', '}', '.', '\\', '|', '^', '$', '*', '+', '?', '&', '\0' }; static char32 value [] = { '\a', '\b', #ifdef EBCDIC_CHARSET 0x27, /* Escape character in IBM's EBCDIC character set. */ #else 0x1B, /* Escape character in ASCII character set. */ #endif '\f', '\n', '\r', '\t', '\v', '(', ')', '-', '[', ']', '<', '>', '{', '}', '.', '\\', '|', '^', '$', '*', '+', '?', '&', '\0' }; int i; for (i = 0; valid_escape [i] != '\0'; i++) { if (c == valid_escape [i]) { return value [i]; } } return '\0'; } /*--------------------------------------------------------------------* * back_ref * * Process a request to match a previous parenthesized thing. * Parenthetical entities are numbered beginning at 1 by counting * opening parentheses from left to to right. \0 would represent * whole match, but would confuse numeric_escape as an octal escape, * so it is forbidden. * * Constructs of the form \~1, \~2, etc. are cross-regex back * references and are used in syntax highlighting patterns to match * text previously matched by another regex. *** IMPLEMENT LATER *** *--------------------------------------------------------------------*/ static char32 *back_ref ( char32 *c, int *flag_param, int emit) { int paren_no, c_offset = 0, is_cross_regex = 0; char32 *ret_val; /* Implement cross regex backreferences later. */ /* if (*c == (regularExp_CHAR) ('~')) { c_offset++; is_cross_regex++; } */ paren_no = (int) (* (c + c_offset) - (char32) ('0')); if (!iswdigit ((int) * (c + c_offset)) || /* Only \1, \2, ... \9 are supported. */ paren_no == 0) { /* Should be caught by numeric_escape. */ return NULL; } /* Make sure parentheses for requested back-reference are complete. */ if (!is_cross_regex && !TEST_BIT (Closed_Parens, paren_no)) { Melder_sprint (Error_Text,128, U"\\", paren_no, U" is an illegal back reference"); return NULL; } if (emit == EMIT_NODE) { if (is_cross_regex) { Reg_Parse++; /* Skip past the '~' in a cross regex back reference. We only do this if we are emitting code. */ if (Is_Case_Insensitive) { ret_val = emit_node (X_REGEX_BR_CI); } else { ret_val = emit_node (X_REGEX_BR); } } else { if (Is_Case_Insensitive) { ret_val = emit_node (BACK_REF_CI); } else { ret_val = emit_node (BACK_REF); } } emit_byte ((char32) paren_no); if (is_cross_regex || TEST_BIT (Paren_Has_Width, paren_no)) { *flag_param |= HAS_WIDTH; } } else if (emit == CHECK_ESCAPE) { ret_val = (char32 *) 1; } else { ret_val = NULL; } return ret_val; } /*======================================================================* * Regex execution related code *======================================================================*/ /* Global work variables for `ExecRE'. */ static char32 *Reg_Input; /* String-input pointer. */ static const char32 *Start_Of_String; /* Beginning of input, for ^ */ /* and < checks. */ static const char32 *End_Of_String; /* Logical end of input (if supplied, till \0 otherwise) */ static const char32 *Look_Behind_To; /* Position till were look behind can safely check back */ static char32 **Start_Ptr_Ptr; /* Pointer to `startp' array. */ static char32 **End_Ptr_Ptr; /* Ditto for `endp'. */ static char32 *Extent_Ptr_FW; /* Forward extent pointer */ static char32 *Extent_Ptr_BW; /* Backward extent pointer */ static char32 *Back_Ref_Start [10]; /* Back_Ref_Start [0] and */ static char32 *Back_Ref_End [10]; /* Back_Ref_End [0] are not */ /* used. This simplifies */ /* indexing. */ /* * Measured recursion limits: * Linux: +/- 40 000 (up to 110 000) * Solaris: +/- 85 000 * HP-UX 11: +/- 325 000 * * So 10 000 ought to be safe. */ #define REGEX_RECURSION_LIMIT 10000 static int Recursion_Count; /* Recursion counter */ static int Recursion_Limit_Exceeded; /* Recursion limit exceeded flag */ #define AT_END_OF_STRING(X) (*(X) == U'\0' || (End_Of_String != NULL && (X) >= End_Of_String)) /* static regexp *Cross_Regex_Backref; */ static int Prev_Is_BOL; static int Succ_Is_EOL; static int Prev_Is_Delim; static int Succ_Is_Delim; /* Define a pointer to an array to hold general (...){m,n} counts. */ typedef struct brace_counts { unsigned long count [1]; /* More unwarranted chumminess with compiler. */ } brace_counts; static struct brace_counts *Brace; /* Default table for determining whether a character is a word delimiter. */ static char32 Default_Delimiters [UCHAR_MAX] = {0}; static char32 *Current_Delimiters; /* Current delimiter table */ /* Forward declarations of functions used by `ExecRE' */ static int attempt (regexp *, char32 *); static int match (char32 *, int *); static unsigned long greedy (char32 *, long); static void adjustcase (char32 *, int, char32); static char32 * makeDelimiterTable (const char32 *, char32 *); /* * ExecRE - match a `regexp' structure against a string * * If `end' is non-NULL, matches may not BEGIN past end, but may extend past * it. If reverse is true, `end' must be specified, and searching begins at * `end'. "isbol" should be set to true if the beginning of the string is the * actual beginning of a line (since `ExecRE' can't look backwards from the * beginning to find whether there was a newline before). Likewise, "isbow" * asks whether the string is preceded by a word delimiter. End of string is * always treated as a word and line boundary (there may be cases where it * shouldn't be, in which case, this should be changed). "delimit" (if * non-null) specifies a null-terminated string of characters to be considered * word delimiters matching "<" and ">". if "delimit" is NULL, the default * delimiters (as set in SetREDefaultWordDelimiters) are used. * Look_behind_to indicates the position till where it is safe to * perform look-behind matches. If set, it should be smaller than or equal * to the start position of the search (pointed at by string). If it is NULL, * it defaults to the start position. * Finally, match_to indicates the logical end of the string, till where * matches are allowed to extend. Note that look-ahead patterns may look * past that boundary. If match_to is set to NULL, the terminating \0 is * assumed to correspond to the logical boundary. Match_to, if set, must be * larger than or equal to end, if set. */ int ExecRE ( regexp *prog, regexp *cross_regex_backref, const char32 *string, const char32 *end, int reverse, char32 prev_char, char32 succ_char, const char32 *delimiters, const char32 *look_behind_to, const char32 *match_to) { char32 *str; char32 **s_ptr; char32 **e_ptr; int ret_val = 0; char32 tempDelimitTable [256]; int i; (void) cross_regex_backref; s_ptr = (char32 **) prog->startp; e_ptr = (char32 **) prog->endp; /* Check for valid parameters. */ if (prog == NULL || string == NULL) { reg_error (U"NULL parameter to `ExecRE\'"); goto SINGLE_RETURN; } /* Check validity of program. */ if (U_CHAR_AT (prog->program) != MAGIC) { reg_error (U"corrupted program"); goto SINGLE_RETURN; } /* If caller has supplied delimiters, make a delimiter table */ if (delimiters == NULL) { Current_Delimiters = Default_Delimiters; } else { Current_Delimiters = makeDelimiterTable (delimiters, tempDelimitTable); } /* Remember the logical end of the string. */ End_Of_String = match_to; if (end == NULL && reverse) { for (end = string; !AT_END_OF_STRING (end); end++) { ; } succ_char = '\n'; } else if (end == NULL) { succ_char = '\n'; } /* Initialize arrays used by shortcut_escape. */ if (!init_ansi_classes ()) { goto SINGLE_RETURN; } /* Remember the beginning of the string for matching BOL */ Start_Of_String = string; Look_Behind_To = look_behind_to ? look_behind_to : string; Prev_Is_BOL = ( (prev_char == '\n') || (prev_char == '\0') ? 1 : 0); Succ_Is_EOL = ( (succ_char == '\n') || (succ_char == '\0') ? 1 : 0); Prev_Is_Delim = (Current_Delimiters [prev_char] ? 1 : 0); Succ_Is_Delim = (Current_Delimiters [succ_char] ? 1 : 0); Total_Paren = (int) (prog->program [1]); Num_Braces = (int) (prog->program [2]); /* Reset the recursion detection flag */ Recursion_Limit_Exceeded = 0; /* Cross_Regex_Backref = cross_regex_backref; */ /* Allocate memory for {m,n} construct counting variables if need be. */ if (Num_Braces > 0) { Brace = (brace_counts *) malloc (sizeof (brace_counts) * (size_t) Num_Braces); if (Brace == NULL) { reg_error (U"out of memory in `ExecRE\'"); goto SINGLE_RETURN; } } else { Brace = NULL; } /* Initialize the first nine (9) capturing parentheses start and end pointers to point to the start of the search string. This is to prevent crashes when later trying to reference captured parens that do not exist in the compiled regex. We only need to do the first nine since users can only specify \1, \2, ... \9. */ for (i = 9; i > 0; i--) { *s_ptr++ = (char32 *) string; *e_ptr++ = (char32 *) string; } if (!reverse) { /* Forward Search */ if (prog->anchor) { /* Search is anchored at BOL */ if (attempt (prog, (char32 *) string)) { ret_val = 1; goto SINGLE_RETURN; } for (str = (char32 *) string; !AT_END_OF_STRING (str) && str != (char32 *) end && !Recursion_Limit_Exceeded; str++) { if (*str == '\n') { if (attempt (prog, str + 1)) { ret_val = 1; break; } } } goto SINGLE_RETURN; } else if (prog->match_start != '\0') { /* We know what char match must start with. */ for (str = (char32 *) string; !AT_END_OF_STRING (str) && str != (char32 *) end && !Recursion_Limit_Exceeded; str++) { if (*str == (char32) prog->match_start) { if (attempt (prog, str)) { ret_val = 1; break; } } } goto SINGLE_RETURN; } else { /* General case */ for (str = (char32 *) string; !AT_END_OF_STRING (str) && str != (char32 *) end && !Recursion_Limit_Exceeded; str++) { if (attempt (prog, str)) { ret_val = 1; break; } } /* Beware of a single $ matching \0 */ if (!Recursion_Limit_Exceeded && !ret_val && AT_END_OF_STRING (str) && str != (char32 *) end) { if (attempt (prog, str)) { ret_val = 1; } } goto SINGLE_RETURN; } } else { /* Search reverse, same as forward, but loops run backward */ /* Make sure that we don't start matching beyond the logical end */ if (End_Of_String != NULL && (char32 *) end > End_Of_String) { end = (const char32 *) End_Of_String; } if (prog->anchor) { /* Search is anchored at BOL */ for (str = (char32 *) (end - 1); str >= (char32 *) string && !Recursion_Limit_Exceeded; str--) { if (*str == '\n') { if (attempt (prog, str + 1)) { ret_val = 1; goto SINGLE_RETURN; } } } if (!Recursion_Limit_Exceeded && attempt (prog, (char32 *) string)) { ret_val = 1; goto SINGLE_RETURN; } goto SINGLE_RETURN; } else if (prog->match_start != '\0') { /* We know what char match must start with. */ for (str = (char32 *) end; str >= (char32 *) string && !Recursion_Limit_Exceeded; str--) { if (*str == (char32) prog->match_start) { if (attempt (prog, str)) { ret_val = 1; break; } } } goto SINGLE_RETURN; } else { /* General case */ for (str = (char32 *) end; str >= (char32 *) string && !Recursion_Limit_Exceeded; str--) { if (attempt (prog, str)) { ret_val = 1; break; } } } } SINGLE_RETURN: if (Brace) { free (Brace); } if (Recursion_Limit_Exceeded) { return (0); } return (ret_val); } /*--------------------------------------------------------------------* * init_ansi_classes * * Generate character class sets using locale aware ANSI C functions. * *--------------------------------------------------------------------*/ static int init_ansi_classes () { static int initialized = 0; static int underscore = (int) '_'; int i, word_count, letter_count, space_count; if (!initialized) { initialized = 1; /* Only need to generate character sets once. */ word_count = 0; letter_count = 0; space_count = 0; for (i = 1; i < (int) UCHAR_MAX; i++) { if (isalnum (i) || i == underscore) { Word_Char [word_count++] = (char32) i; } if (isalpha (i)) { Letter_Char [letter_count++] = (char32) i; } /* Note: Whether or not newline is considered to be whitespace is handled by switches within the original regex and is thus omitted here. */ if (isspace (i) && (i != (int) '\n')) { White_Space [space_count++] = (char32) i; } /* Make sure arrays are big enough. ("- 2" because of zero array origin and we need to leave room for the NULL terminator.) */ if (word_count > (ALNUM_CHAR_SIZE - 2) || space_count > (WHITE_SPACE_SIZE - 2) || letter_count > (ALNUM_CHAR_SIZE - 2)) { reg_error (U"internal error #9 `init_ansi_classes\'"); return (0); } } Word_Char [word_count] = '\0'; Letter_Char [word_count] = '\0'; White_Space [space_count] = '\0'; } return (1); } /*----------------------------------------------------------------------* * attempt - try match at specific point, returns: 0 failure, 1 success *----------------------------------------------------------------------*/ static int attempt (regexp *prog, char32 *string) { int i; char32 **s_ptr; char32 **e_ptr; int branch_index = 0; /* Must be set to zero ! */ Reg_Input = string; Start_Ptr_Ptr = (char32 **) prog->startp; End_Ptr_Ptr = (char32 **) prog->endp; s_ptr = (char32 **) prog->startp; e_ptr = (char32 **) prog->endp; /* Reset the recursion counter. */ Recursion_Count = 0; /* Overhead due to capturing parentheses. */ Extent_Ptr_BW = string; Extent_Ptr_FW = NULL; for (i = Total_Paren + 1; i > 0; i--) { *s_ptr++ = NULL; *e_ptr++ = NULL; } if (match ( (char32 *) (prog->program + REGEX_START_OFFSET), &branch_index)) { prog->startp [0] = (char32 *) string; prog->endp [0] = (char32 *) Reg_Input; /* <-- One char AFTER */ prog->extentpBW = (char32 *) Extent_Ptr_BW; /* matched string! */ prog->extentpFW = (char32 *) Extent_Ptr_FW; prog->top_branch = branch_index; return (1); } else { return (0); } } /*----------------------------------------------------------------------* * match - main matching routine * * Conceptually the strategy is simple: check to see whether the * current node matches, call self recursively to see whether the rest * matches, and then act accordingly. In practice we make some effort * to avoid recursion, in particular by going through "ordinary" nodes * (that don't need to know whether the rest of the match failed) by a * loop instead of by recursion. Returns 0 failure, 1 success. *----------------------------------------------------------------------*/ #define MATCH_RETURN(X)\ { --Recursion_Count; return (X); } #define CHECK_RECURSION_LIMIT\ if (Recursion_Limit_Exceeded) MATCH_RETURN (0); static int match (char32 *prog, int *branch_index_param) { char32 *scan; /* Current node. */ char32 *next; /* Next node. */ int next_ptr_offset; /* Used by the NEXT_PTR () macro */ if (++Recursion_Count > REGEX_RECURSION_LIMIT) { if (!Recursion_Limit_Exceeded) { /* Prevent duplicate errors */ reg_error (U"recursion limit exceeded, please respecify expression"); } Recursion_Limit_Exceeded = 1; MATCH_RETURN (0); } scan = prog; while (scan != NULL) { NEXT_PTR (scan, next); switch (GET_OP_CODE (scan)) { case BRANCH: { char32 *save; int branch_index_local = 0; if (GET_OP_CODE (next) != BRANCH) { /* No choice. */ next = OPERAND (scan); /* Avoid recursion. */ } else { do { save = Reg_Input; if (match (OPERAND (scan), NULL)) { if (branch_index_param) { *branch_index_param = branch_index_local; } MATCH_RETURN (1); } CHECK_RECURSION_LIMIT ++branch_index_local; Reg_Input = save; /* Backtrack. */ NEXT_PTR (scan, scan); } while (scan != NULL && GET_OP_CODE (scan) == BRANCH); MATCH_RETURN (0); /* NOT REACHED */ } } break; case EXACTLY: { int len; char32 *opnd; opnd = OPERAND (scan); /* Inline the first character, for speed. */ if (*opnd != *Reg_Input) { MATCH_RETURN (0); } len = str32len (opnd); if (End_Of_String != NULL && Reg_Input + len > End_Of_String) { MATCH_RETURN (0); } if (len > 1 && str32ncmp (opnd, Reg_Input, len) != 0) { MATCH_RETURN (0); } Reg_Input += len; } break; case SIMILAR: { char32 *opnd; char32 test; opnd = OPERAND (scan); /* Note: the SIMILAR operand was converted to lower case during regex compile. */ while ( (test = *opnd++) != '\0') { if (AT_END_OF_STRING (Reg_Input) || towlower ((int) *Reg_Input++) != test) { MATCH_RETURN (0); } } } break; case BOL: /* `^' (beginning of line anchor) */ if (Reg_Input == Start_Of_String) { if (Prev_Is_BOL) { break; } } else if (* (Reg_Input - 1) == '\n') { break; } MATCH_RETURN (0); case EOL: /* `$' anchor matches end of line and end of string */ if (*Reg_Input == '\n' || (AT_END_OF_STRING (Reg_Input) && Succ_Is_EOL)) { break; } MATCH_RETURN (0); case BOWORD: /* `<' (beginning of word anchor) */ /* Check to see if the current character is not a delimiter and the preceding character is. */ { int prev_is_delim; if (Reg_Input == Start_Of_String) { prev_is_delim = Prev_Is_Delim; } else { prev_is_delim = Current_Delimiters [ * (Reg_Input - 1) ]; } if (prev_is_delim) { int current_is_delim; if (AT_END_OF_STRING (Reg_Input)) { current_is_delim = Succ_Is_Delim; } else { current_is_delim = Current_Delimiters [ *Reg_Input ]; } if (!current_is_delim) { break; } } } MATCH_RETURN (0); case EOWORD: /* `>' (end of word anchor) */ /* Check to see if the current character is a delimiter and the preceding character is not. */ { int prev_is_delim; if (Reg_Input == Start_Of_String) { prev_is_delim = Prev_Is_Delim; } else { prev_is_delim = Current_Delimiters [ * (Reg_Input - 1) ]; } if (!prev_is_delim) { int current_is_delim; if (AT_END_OF_STRING (Reg_Input)) { current_is_delim = Succ_Is_Delim; } else { current_is_delim = Current_Delimiters [ *Reg_Input ]; } if (current_is_delim) { break; } } } MATCH_RETURN (0); case NOT_BOUNDARY: { /* \B (NOT a word boundary) */ int prev_is_delim; int current_is_delim; if (Reg_Input == Start_Of_String) { prev_is_delim = Prev_Is_Delim; } else { prev_is_delim = Current_Delimiters [ * (Reg_Input - 1) ]; } if (AT_END_OF_STRING (Reg_Input)) { current_is_delim = Succ_Is_Delim; } else { current_is_delim = Current_Delimiters [ *Reg_Input ]; } if (! (prev_is_delim ^ current_is_delim)) { break; } } MATCH_RETURN (0); case IS_DELIM: /* \y (A word delimiter character.) */ if (Current_Delimiters [ *Reg_Input ] && !AT_END_OF_STRING (Reg_Input)) { Reg_Input++; break; } MATCH_RETURN (0); case NOT_DELIM: /* \Y (NOT a word delimiter character.) */ if (!Current_Delimiters [ *Reg_Input ] && !AT_END_OF_STRING (Reg_Input)) { Reg_Input++; break; } MATCH_RETURN (0); case WORD_CHAR: /* \w (word character; alpha-numeric or underscore) */ if ( (isalnum ( (int) *Reg_Input) || *Reg_Input == '_') && !AT_END_OF_STRING (Reg_Input)) { Reg_Input++; break; } MATCH_RETURN (0); case NOT_WORD_CHAR:/* \W (NOT a word character) */ if (isalnum ( (int) *Reg_Input) || *Reg_Input == '_' || *Reg_Input == '\n' || AT_END_OF_STRING (Reg_Input)) { MATCH_RETURN (0); } Reg_Input++; break; case ANY: /* `.' (matches any character EXCEPT newline) */ if (AT_END_OF_STRING (Reg_Input) || *Reg_Input == '\n') { MATCH_RETURN (0); } Reg_Input++; break; case EVERY: /* `.' (matches any character INCLUDING newline) */ if (AT_END_OF_STRING (Reg_Input)) { MATCH_RETURN (0); } Reg_Input++; break; case DIGIT: /* \d, same as [0123456789] */ if (!isdigit ( (int) *Reg_Input) || AT_END_OF_STRING (Reg_Input)) { MATCH_RETURN (0); } Reg_Input++; break; case NOT_DIGIT: /* \D, same as [^0123456789] */ if (isdigit ( (int) *Reg_Input) || *Reg_Input == '\n' || AT_END_OF_STRING (Reg_Input)) { MATCH_RETURN (0); } Reg_Input++; break; case LETTER: /* \l, same as [a-zA-Z] */ if (!isalpha ( (int) *Reg_Input) || AT_END_OF_STRING (Reg_Input)) { MATCH_RETURN (0); } Reg_Input++; break; case NOT_LETTER: /* \L, same as [^0123456789] */ if (isalpha ( (int) *Reg_Input) || *Reg_Input == '\n' || AT_END_OF_STRING (Reg_Input)) { MATCH_RETURN (0); } Reg_Input++; break; case SPACE: /* \s, same as [ \t\r\f\v] */ if (!isspace ( (int) *Reg_Input) || *Reg_Input == '\n' || AT_END_OF_STRING (Reg_Input)) { MATCH_RETURN (0); } Reg_Input++; break; case SPACE_NL: /* \s, same as [\n \t\r\f\v] */ if (!isspace ( (int) *Reg_Input) || AT_END_OF_STRING (Reg_Input)) { MATCH_RETURN (0); } Reg_Input++; break; case NOT_SPACE: /* \S, same as [^\n \t\r\f\v] */ if (isspace ( (int) *Reg_Input) || AT_END_OF_STRING (Reg_Input)) { MATCH_RETURN (0); } Reg_Input++; break; case NOT_SPACE_NL: /* \S, same as [^ \t\r\f\v] */ if ( (isspace ( (int) *Reg_Input) && *Reg_Input != '\n') || AT_END_OF_STRING (Reg_Input)) { MATCH_RETURN (0); } Reg_Input++; break; case ANY_OF: /* [...] character class. */ if (AT_END_OF_STRING (Reg_Input)) { MATCH_RETURN (0); } /* Needed because strchr () considers \0 as a member of the character set. */ if (str32chr (OPERAND (scan), *Reg_Input) == NULL) { MATCH_RETURN (0); } Reg_Input++; break; case ANY_BUT: /* [^...] Negated character class-- does NOT normally match newline (\n added usually to operand at compile time.) */ if (AT_END_OF_STRING (Reg_Input)) { MATCH_RETURN (0); /* See comment for ANY_OF. */ } if (str32chr (OPERAND (scan), *Reg_Input) != NULL) { MATCH_RETURN (0); } Reg_Input++; break; case NOTHING: case BACK: break; case STAR: case PLUS: case QUESTION: case BRACE: case LAZY_STAR: case LAZY_PLUS: case LAZY_QUESTION: case LAZY_BRACE: { unsigned long num_matched = REG_ZERO; unsigned long min = ULONG_MAX, max = REG_ZERO; char32 *save; char32 next_char; char32 *next_op; int lazy = 0; /* Lookahead (when possible) to avoid useless match attempts when we know what character comes next. */ if (GET_OP_CODE (next) == EXACTLY) { next_char = *OPERAND (next); } else { next_char = '\0';/* i.e. Don't know what next character is. */ } next_op = OPERAND (scan); switch (GET_OP_CODE (scan)) { case LAZY_STAR: lazy = 1; case STAR: min = REG_ZERO; max = ULONG_MAX; break; case LAZY_PLUS: lazy = 1; case PLUS: min = REG_ONE; max = ULONG_MAX; break; case LAZY_QUESTION: lazy = 1; case QUESTION: min = REG_ZERO; max = REG_ONE; break; case LAZY_BRACE: lazy = 1; case BRACE: min = (unsigned long) GET_OFFSET (scan + NEXT_PTR_SIZE); max = (unsigned long) GET_OFFSET (scan + (2 * NEXT_PTR_SIZE)); if (max <= REG_INFINITY) { max = ULONG_MAX; } next_op = OPERAND (scan + (2 * NEXT_PTR_SIZE)); } save = Reg_Input; if (lazy) { if (min > REG_ZERO) { num_matched = greedy (next_op, min); } } else { num_matched = greedy (next_op, max); } while (min <= num_matched && num_matched <= max) { if (next_char == '\0' || next_char == *Reg_Input) { if (match (next, NULL)) { MATCH_RETURN (1); } CHECK_RECURSION_LIMIT } /* Couldn't or didn't match. */ if (lazy) { if (!greedy (next_op, 1)) { MATCH_RETURN (0); } num_matched++; /* Inch forward. */ } else if (num_matched > REG_ZERO) { num_matched--; /* Back up. */ } else if (min == REG_ZERO && num_matched == REG_ZERO) { break; } Reg_Input = save + num_matched; } MATCH_RETURN (0); } break; case END: if (Extent_Ptr_FW == NULL || (Reg_Input - Extent_Ptr_FW) > 0) { Extent_Ptr_FW = Reg_Input; } MATCH_RETURN (1); /* Success! */ break; case INIT_COUNT: Brace->count [*OPERAND (scan)] = REG_ZERO; break; case INC_COUNT: Brace->count [*OPERAND (scan)]++; break; case TEST_COUNT: if (Brace->count [*OPERAND (scan)] < (unsigned long) GET_OFFSET (scan + NEXT_PTR_SIZE + INDEX_SIZE)) { next = scan + NODE_SIZE + INDEX_SIZE + NEXT_PTR_SIZE; } break; case BACK_REF: case BACK_REF_CI: /* case X_REGEX_BR: */ /* case X_REGEX_BR_CI: *** IMPLEMENT LATER */ { char32 *captured, *finish; int paren_no; paren_no = (int) * OPERAND (scan); /* if (GET_OP_CODE (scan) == X_REGEX_BR || GET_OP_CODE (scan) == X_REGEX_BR_CI) { if (Cross_Regex_Backref == NULL) MATCH_RETURN (0); captured = (regularExp_CHAR *) Cross_Regex_Backref->startp [paren_no]; finish = (regularExp_CHAR *) Cross_Regex_Backref->endp [paren_no]; } else { */ captured = Back_Ref_Start [paren_no]; finish = Back_Ref_End [paren_no]; /* } */ if ( (captured != NULL) && (finish != NULL)) { if (captured > finish) { MATCH_RETURN (0); } if (GET_OP_CODE (scan) == BACK_REF_CI /* || GET_OP_CODE (scan) == X_REGEX_BR_CI*/) { while (captured < finish) { if (AT_END_OF_STRING (Reg_Input) || tolower (*captured++) != tolower (*Reg_Input++)) { MATCH_RETURN (0); } } } else { while (captured < finish) { if (AT_END_OF_STRING (Reg_Input) || *captured++ != *Reg_Input++) { MATCH_RETURN (0); } } } break; } else { MATCH_RETURN (0); } } case POS_AHEAD_OPEN: case NEG_AHEAD_OPEN: { char32 *save; const char32 *saved_end; int answer; save = Reg_Input; /* Temporarily ignore the logical end of the string, to allow lookahead past the end. */ saved_end = End_Of_String; End_Of_String = NULL; answer = match (next, NULL); /* Does the look-ahead regex match? */ CHECK_RECURSION_LIMIT if ( (GET_OP_CODE (scan) == POS_AHEAD_OPEN) ? answer : !answer) { /* Remember the last (most to the right) character position that we consume in the input for a successful match. This is info that may be needed should an attempt be made to match the exact same text at the exact same place. Since look-aheads backtrack, a regex with a trailing look-ahead may need more text than it matches to accomplish a re-match. */ if (Extent_Ptr_FW == NULL || (Reg_Input - Extent_Ptr_FW) > 0) { Extent_Ptr_FW = Reg_Input; } Reg_Input = save; /* Backtrack to look-ahead start. */ End_Of_String = saved_end; /* Restore logical end. */ /* Jump to the node just after the (?=...) or (?!...) Construct. */ next = next_ptr (OPERAND (scan)); /* Skip 1st branch */ /* Skip the chain of branches inside the look-ahead */ while (GET_OP_CODE (next) == BRANCH) { next = next_ptr (next); } next = next_ptr (next); /* Skip the LOOK_AHEAD_CLOSE */ } else { Reg_Input = save; /* Backtrack to look-ahead start. */ End_Of_String = saved_end; /* Restore logical end. */ MATCH_RETURN (0); } } break; case POS_BEHIND_OPEN: case NEG_BEHIND_OPEN: { char32 *save; int answer; int offset, upper; int lower; int found = 0; const char32 *saved_end; save = Reg_Input; saved_end = End_Of_String; /* Prevent overshoot (greedy matching could end past the current position) by tightening the matching boundary. Lookahead inside lookbehind can still cross that boundary. */ End_Of_String = Reg_Input; lower = GET_LOWER (scan); upper = GET_UPPER (scan); /* Start with the shortest match first. This is the most efficient direction in general. Note! Negative look behind is _very_ tricky when the length is not constant: we have to make sure the expression doesn't match for _any_ of the starting positions. */ for (offset = lower; offset <= upper; ++offset) { Reg_Input = save - offset; if (Reg_Input < Look_Behind_To) { /* No need to look any further */ break; } answer = match (next, NULL); /* Does the look-behind regex match? */ CHECK_RECURSION_LIMIT /* The match must have ended at the current position; otherwise it is invalid */ if (answer && Reg_Input == save) { /* It matched, exactly far enough */ found = 1; /* Remember the last (most to the left) character position that we consume in the input for a successful match. This is info that may be needed should an attempt be made to match the exact same text at the exact same place. Since look-behind backtracks, a regex with a leading look-behind may need more text than it matches to accomplish a re-match. */ if (Extent_Ptr_BW == NULL || (Extent_Ptr_BW - (save - offset)) > 0) { Extent_Ptr_BW = save - offset; } break; } } /* Always restore the position and the logical string end. */ Reg_Input = save; End_Of_String = saved_end; if ( (GET_OP_CODE (scan) == POS_BEHIND_OPEN) ? found : !found) { /* The look-behind matches, so we must jump to the next node. The look-behind node is followed by a chain of branches (contents of the look-behind expression), and terminated by a look-behind-close node. */ next = next_ptr (OPERAND (scan) + LENGTH_SIZE); /* 1st branch */ /* Skip the chained branches inside the look-ahead */ while (GET_OP_CODE (next) == BRANCH) { next = next_ptr (next); } next = next_ptr (next); /* Skip LOOK_BEHIND_CLOSE */ } else { /* Not a match */ MATCH_RETURN (0); } } break; case LOOK_AHEAD_CLOSE: case LOOK_BEHIND_CLOSE: MATCH_RETURN (1); /* We have reached the end of the look-ahead or look-behind which implies that we matched it, so return `true`. */ default: if ( (GET_OP_CODE (scan) > OPEN) && (GET_OP_CODE (scan) < OPEN + NSUBEXP)) { int no; char32 *save; no = GET_OP_CODE (scan) - OPEN; save = Reg_Input; if (no < 10) { Back_Ref_Start [no] = save; Back_Ref_End [no] = NULL; } if (match (next, NULL)) { /* Do not set `Start_Ptr_Ptr' if some later invocation (think recursion) of the same parentheses already has. */ if (Start_Ptr_Ptr [no] == NULL) { Start_Ptr_Ptr [no] = save; } MATCH_RETURN (1); } else { MATCH_RETURN (0); } } else if ( (GET_OP_CODE (scan) > CLOSE) && (GET_OP_CODE (scan) < CLOSE + NSUBEXP)) { int no; char32 *save; no = GET_OP_CODE (scan) - CLOSE; save = Reg_Input; if (no < 10) { Back_Ref_End [no] = save; } if (match (next, NULL)) { /* Do not set `End_Ptr_Ptr' if some later invocation of the same parentheses already has. */ if (End_Ptr_Ptr [no] == NULL) { End_Ptr_Ptr [no] = save; } MATCH_RETURN (1); } else { MATCH_RETURN (0); } } else { reg_error (U"memory corruption, `match\'"); MATCH_RETURN (0); } break; } scan = next; } /* We get here only if there's trouble -- normally "case END" is the terminating point. */ reg_error (U"corrupted pointers, `match\'"); MATCH_RETURN (0); } /*----------------------------------------------------------------------* * greedy * * Repeatedly match something simple up to "max" times. If max <= 0 * then match as much as possible (max = infinity). Uses unsigned long * variables to maximize the amount of text matchable for unbounded * qualifiers like '*' and '+'. This will allow at least 4,294,967,295 * matches (4 Gig!) for an ANSI C compliant compiler. If you are * applying a regex to something bigger than that, you shouldn't be * using NEdit! * * Returns the actual number of matches. *----------------------------------------------------------------------*/ static unsigned long greedy (char32 *p, long max) { char32 *input_str; char32 *operand; unsigned long count = REG_ZERO; unsigned long max_cmp; input_str = Reg_Input; operand = OPERAND (p); /* Literal char or start of class characters. */ max_cmp = (max > 0) ? (unsigned long) max : ULONG_MAX; switch (GET_OP_CODE (p)) { case ANY: /* Race to the end of the line or string. Dot DOESN'T match newline. */ while (count < max_cmp && *input_str != '\n' && !AT_END_OF_STRING (input_str)) { count++; input_str++; } break; case EVERY: /* Race to the end of the line or string. Dot DOES match newline. */ while (count < max_cmp && !AT_END_OF_STRING (input_str)) { count++; input_str++; } break; case EXACTLY: /* Count occurrences of single character operand. */ while (count < max_cmp && *operand == *input_str && !AT_END_OF_STRING (input_str)) { count++; input_str++; } break; case SIMILAR: /* Case insensitive version of EXACTLY */ while (count < max_cmp && *operand == (char32) towlower ((int) *input_str) && !AT_END_OF_STRING (input_str)) { count++; input_str++; } break; case ANY_OF: /* [...] character class. */ while (count < max_cmp && str32chr (operand, *input_str) != NULL && !AT_END_OF_STRING (input_str)) { count++; input_str++; } break; case ANY_BUT: /* [^...] Negated character class- does NOT normally match newline (\n added usually to operand at compile time.) */ while (count < max_cmp && str32chr (operand, *input_str) == NULL && !AT_END_OF_STRING (input_str)) { count++; input_str++; } break; case IS_DELIM: /* \y (not a word delimiter char) NOTE: '\n' and '\0' are always word delimiters. */ while (count < max_cmp && Current_Delimiters [ *input_str ] && !AT_END_OF_STRING (input_str)) { count++; input_str++; } break; case NOT_DELIM: /* \Y (not a word delimiter char) NOTE: '\n' and '\0' are always word delimiters. */ while (count < max_cmp && !Current_Delimiters [ *input_str ] && !AT_END_OF_STRING (input_str)) { count++; input_str++; } break; case WORD_CHAR: /* \w (word character, alpha-numeric or underscore) */ while (count < max_cmp && (iswalnum ( (int) *input_str) || *input_str == U'_') && !AT_END_OF_STRING (input_str)) { count++; input_str++; } break; case NOT_WORD_CHAR:/* \W (NOT a word character) */ while (count < max_cmp && !iswalnum ( (int) *input_str) && *input_str != U'_' && *input_str != U'\n' && !AT_END_OF_STRING (input_str)) { count++; input_str++; } break; case DIGIT: /* same as [0123456789] */ while (count < max_cmp && isdigit ( (int) *input_str) && !AT_END_OF_STRING (input_str)) { count++; input_str++; } break; case NOT_DIGIT: /* same as [^0123456789] */ while (count < max_cmp && !iswdigit ( (int) *input_str) && *input_str != U'\n' && !AT_END_OF_STRING (input_str)) { count++; input_str++; } break; case SPACE: /* same as [ \t\r\f\v]-- doesn't match newline. */ while (count < max_cmp && iswspace ( (int) *input_str) && *input_str != U'\n' && !AT_END_OF_STRING (input_str)) { count++; input_str++; } break; case SPACE_NL: /* same as [\n \t\r\f\v]-- matches newline. */ while (count < max_cmp && iswspace ( (int) *input_str) && !AT_END_OF_STRING (input_str)) { count++; input_str++; } break; case NOT_SPACE: /* same as [^\n \t\r\f\v]-- doesn't match newline. */ while (count < max_cmp && !iswspace ( (int) *input_str) && !AT_END_OF_STRING (input_str)) { count++; input_str++; } break; case NOT_SPACE_NL: /* same as [^ \t\r\f\v]-- matches newline. */ while (count < max_cmp && (!iswspace ( (int) *input_str) || *input_str == '\n') && !AT_END_OF_STRING (input_str)) { count++; input_str++; } break; case LETTER: /* same as [a-zA-Z] */ while (count < max_cmp && iswalpha ( (int) *input_str) && !AT_END_OF_STRING (input_str)) { count++; input_str++; } break; case NOT_LETTER: /* same as [^a-zA-Z] */ while (count < max_cmp && !iswalpha ( (int) *input_str) && *input_str != '\n' && !AT_END_OF_STRING (input_str)) { count++; input_str++; } break; default: /* Called inappropriately. Only atoms that are SIMPLE should generate a call to greedy. The above cases should cover all the atoms that are SIMPLE. */ reg_error (U"internal error #10 `greedy\'"); count = 0U; /* Best we can do. */ } /* Point to character just after last matched character. */ Reg_Input = input_str; return (count); } /*----------------------------------------------------------------------* * next_ptr - compute the address of a node's "NEXT" pointer. * Note: a simplified inline version is available via the NEXT_PTR() macro, * but that one is only to be used at time-critical places (see the * description of the macro). *----------------------------------------------------------------------*/ static char32 *next_ptr (char32 *ptr) { int offset; if (ptr == &Compute_Size) { return (NULL); } offset = GET_OFFSET (ptr); if (offset == 0) { return (NULL); } if (GET_OP_CODE (ptr) == BACK) { return (ptr - offset); } else { return (ptr + offset); } } /* ** SubstituteRE - Perform substitutions after a `regexp' match. ** ** This function cleanly shortens results of more than max length to max. ** To give the caller a chance to react to this the function returns False ** on any error. The substitution will still be executed. */ int SubstituteRE (const regexp *prog, const char32 *source, char32 *dest, int max, int *errorType) { const char32 *src; const char32 *src_alias; char32 *dst; char32 c; char32 test; int paren_no; int len; char32 chgcase; int anyWarnings = FALSE; *errorType = 0; if (prog == NULL || source == NULL || dest == NULL) { reg_error (U"NULL parm to `SubstituteRE\'"); *errorType = 2; return FALSE; } if (U_CHAR_AT (prog->program) != MAGIC) { *errorType = 3; reg_error (U"damaged regexp passed to `SubstituteRE\'"); return FALSE; } src = source; dst = dest; while ( (c = *src++) != '\0') { chgcase = '\0'; paren_no = -1; if (c == '\\') { /* Process any case altering tokens, i.e \u, \U, \l, \L. */ if (*src == 'u' || *src == 'U' || *src == 'l' || *src == 'L') { chgcase = *src; src++; c = *src++; if (c == '\0') { break; } } } if (c == '&') { paren_no = 0; } else if (c == '\\') { /* Can not pass register variable `&src' to function `numeric_escape' so make a non-register copy that we can take the address of. */ src_alias = src; if ('1' <= *src && *src <= '9') { paren_no = (int) * src++ - (int) '0'; } else if ( (test = literal_escape (*src)) != '\0') { c = test; src++; } else if ( (test = numeric_escape (*src, (char32 **) &src_alias)) != '\0') { c = test; src = src_alias; src++; /* NOTE: if an octal escape for zero is attempted (e.g. \000), it will be treated as a literal string. */ } else if (*src == '\0') { /* If '\' is the last character of the replacement string, it is interpreted as a literal backslash. */ c = '\\'; } else { c = *src++; /* Allow any escape sequence (This is */ } /* INCONSISTENT with the `CompileRE' */ } /* mind set of issuing an error! */ if (paren_no < 0) { /* Ordinary character. */ if ( (dst - dest) >= (max - 1)) { *errorType = 1; reg_error (U"replacing expression in `SubstituteRE\' too long; truncating"); anyWarnings = TRUE; break; } else { *dst++ = c; } } else if (prog->startp [paren_no] != NULL && prog->endp [paren_no] != NULL) { len = prog->endp [paren_no] - prog->startp [paren_no]; if ( (dst + len - dest) >= max - 1) { *errorType = 1; reg_error (U"replacing expression in `SubstituteRE\' too long; truncating"); anyWarnings = TRUE; len = max - (dst - dest) - 1; } (void) str32ncpy (dst, prog->startp [paren_no], len); if (chgcase != '\0') { adjustcase (dst, len, chgcase); } dst += len; if (len != 0 && * (dst - 1) == '\0') { /* strncpy hit NUL. */ *errorType = 3; reg_error (U"damaged match string in `SubstituteRE\'"); anyWarnings = TRUE; } } } *dst = '\0'; return !anyWarnings; } static void adjustcase (char32 *str, int len, char32 chgcase) { char32 *string = str; int i; /* The tokens \u and \l only modify the first character while the tokens \U and \L modify the entire string. */ if (iswlower ((int) chgcase) && len > 0) { len = 1; } switch (chgcase) { case 'u': case 'U': for (i = 0; i < len; i++) { * (string + i) = (char32) towupper ( (int) * (string + i)); } break; case 'l': case 'L': for (i = 0; i < len; i++) { * (string + i) = (char32) towlower ( (int) * (string + i)); } break; } } /*----------------------------------------------------------------------* * reg_error *----------------------------------------------------------------------*/ static void reg_error (const char32 *str) { Melder_appendError (U"Internal error processing regular expression: ", str); } /*----------------------------------------------------------------------* * makeDelimiterTable * * Translate a null-terminated string of delimiters into a 256 byte * lookup table for determining whether a character is a delimiter or * not. * * Table must be allocated by the caller. * * Return value is a pointer to the table. *----------------------------------------------------------------------*/ static char32 *makeDelimiterTable ( const char32 *delimiters, char32 *table) { const char32 *c; memset (table, 0, 256); for (c = delimiters; *c != '\0'; c++) { table [*c] = 1; } table [ (int) '\0'] = 1; /* These */ table [ (int) '\t'] = 1; /* characters */ table [ (int) '\n'] = 1; /* are always */ table [ (int) ' ' ] = 1; /* delimiters. */ return table; } /*----------------------------------------------------------------------* * SetREDefaultWordDelimiters * * Builds a default delimiter table that persists across `ExecRE' calls. *----------------------------------------------------------------------*/ void SetREDefaultWordDelimiters (char32 *delimiters) { makeDelimiterTable (delimiters, Default_Delimiters); } void EnableCountingQuantifier (int is_enabled) { Enable_Counting_Quantifier = is_enabled; } /* End of file regularExp.cpp */ praat-6.0.04/dwsys/regularExp.h000066400000000000000000000140161261542461700163620ustar00rootroot00000000000000#ifndef _regularExp_h_ #define _regularExp_h_ /******************************************************************************* * * * regularExp.h -- Nirvana Editor Regular Expression Package Header File * * * * Copyright 2002 The NEdit Developers * * * * This is free software; you can redistribute it and/or modify it under the * * terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. In addition, you may distribute version of this program linked to * * Motif or Open Motif. See README for details. * * * * This software is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * * for more details. * * * * You should have received a copy of the GNU General Public License along with * * software; if not, write to the Free Software Foundation, Inc., 59 Temple * * Place, Suite 330, Boston, MA 02111-1307 USA * * * * Nirvana Text Editor * * July 31, 2001 * * * * * *******************************************************************************/ /* djmw 20080110 Extra parameter for SubstituteRE to allow error differentiation */ /* Number of text capturing parentheses allowed. */ #include "melder.h" #define NSUBEXP 50 /* Structure to contain the compiled form of a regular expression plus pointers to matched text. `program' is the actual compiled regex code. */ typedef struct regexp { char32 *startp [NSUBEXP]; /* Captured text starting locations. */ char32 *endp [NSUBEXP]; /* Captured text ending locations. */ char32 *extentpBW; /* Points to the maximum extent of text scanned by ExecRE in front of the string to achieve a match (needed because of positive look-behind.) */ char32 *extentpFW; /* Points to the maximum extent of text scanned by ExecRE to achieve a match (needed because of positive look-ahead.) */ int top_branch; /* Zero-based index of the top branch that matches. Used by syntax highlighting only. */ char32 match_start; /* Internal use only. */ char32 anchor; /* Internal use only. */ char32 program [1]; /* Unwarranted chumminess with compiler. */ } regexp; /* Flags for CompileRE default settings (Markus Schwarzenberg) */ typedef enum { REDFLT_STANDARD = 0, REDFLT_CASE_INSENSITIVE = 1 /* REDFLT_MATCH_NEWLINE = 2 Currently not used. */ } RE_DEFAULT_FLAG; /* Compiles a regular expression into the internal format used by `ExecRE'. */ regexp * CompileRE ( const char32 *exp, /* String containing the regex specification. */ const char32 **errorText, /* Text of any error message produced. */ int defaultFlags); /* Flags for default RE-operation */ regexp *CompileRE_throwable (const char32 *exp, int defaultFlags); /* Match a `regexp' structure against a string. */ int ExecRE ( regexp *prog, /* Compiled regex. */ regexp *cross_regex_backref, /* Pointer to a `regexp' that was used in a previous execution of ExecRE. Used to implement back references across regular expressions for use in syntax highlighting.*/ const char32 *string, /* Text to search within. */ const char32 *end, /* Pointer to the end of `string'. If NULL will scan from `string' until '\0' is found. */ int reverse, /* Backward search. */ char32 prev_char, /* Character immediately prior to `string'. Set to '\n' or '\0' if true beginning of text. */ char32 succ_char, /* Character immediately after `end'. Set to '\n' or '\0' if true beginning of text. */ const char32 *delimiters, /* Word delimiters to use (NULL for default) */ const char32 *look_behind_to,/* Boundary for look-behind; defaults to "string" if NULL */ const char32 *match_till); /* Boundary to where match can extend. \0 is assumed to be the boundary if not set. Lookahead can cross the boundary. */ /* Perform substitutions after a `regexp' match. */ int SubstituteRE ( const regexp *prog, const char32 *source, char32 *dest, int max, int *errorType); // djmw 20080110 0: ok; 1: is not enough memory /* Builds a default delimiter table that persists across `ExecRE' calls that is identical to `delimiters'. Pass NULL for "default default" set of delimiters. */ void SetREDefaultWordDelimiters ( char32 *delimiters); /* Enable (or disable) brace counting quantifiers, e.g. `(foo){0,3}'. */ void EnableCountingQuantifier (int is_enabled); #endif /* _regularExp_h_ */ praat-6.0.04/dwtest/000077500000000000000000000000001261542461700142325ustar00rootroot00000000000000praat-6.0.04/dwtest/Hayes_table_10.18.1.txt000066400000000000000000000004011261542461700200740ustar00rootroot00000000000000Group Data I 20 I 18 I 26 I 19 I 26 I 24 I 26 II 24 II 22 II 25 II 25 II 20 II 21 II 34 II 18 II 32 II 23 II 22 III 20 III 22 III 30 III 27 III 22 III 24 III 28 III 21 III 23 III 25 III 18 III 30 III 32 IV 27 IV 35 IV 18 IV 24 IV 28 IV 32 IV 16 IV 18 IV 25 praat-6.0.04/dwtest/Hayes_table_12.7.1.txt000066400000000000000000000020701261542461700200200ustar00rootroot00000000000000Norms Standing Data College Above 52 College Above 48 College Above 43 College Above 50 College Above 43 College Above 44 College Above 46 College Above 46 College Above 43 College Above 49 College Average 28 College Average 35 College Average 34 College Average 32 College Average 34 College Average 27 College Average 31 College Average 27 College Average 29 College Average 25 College Below 15 College Below 14 College Below 23 College Below 21 College Below 14 College Below 20 College Below 21 College Below 16 College Below 20 College Below 14 Athlete Above 38 Athlete Above 42 Athlete Above 42 Athlete Above 35 Athlete Above 33 Athlete Above 38 Athlete Above 39 Athlete Above 34 Athlete Above 33 Athlete Above 34 Athlete Average 43 Athlete Average 34 Athlete Average 33 Athlete Average 42 Athlete Average 41 Athlete Average 37 Athlete Average 37 Athlete Average 40 Athlete Average 36 Athlete Average 35 Athlete Below 23 Athlete Below 25 Athlete Below 18 Athlete Below 26 Athlete Below 18 Athlete Below 26 Athlete Below 20 Athlete Below 19 Athlete Below 22 Athlete Below 17 praat-6.0.04/dwtest/Hayes_table_19.7.1.txt000066400000000000000000000003371261542461700200330ustar00rootroot00000000000000Group Data I 6 I 11 I 12 I 20 I 24 I 21 I 18 I 15 I 14 I 10 I 8 I 14 II 31 II 7 II 9 II 11 II 16 II 19 II 17 II 11 II 22 II 23 II 27 II 26 III 13 III 32 III 31 III 30 III 28 III 29 III 25 III 26 III 26 III 27 III 26 III 19 praat-6.0.04/dwtest/KlattGrid_test.praat000066400000000000000000000240111261542461700202050ustar00rootroot00000000000000# KlattGrid_test.praat # djmw 20081208, 20090420, 20140113 printline =========== KlattGrid test start call test_get_add_remove_extract_replace_old_interface call test_get_add_remove_replace printline =========== KlattGrid test end procedure test_get_add_remove_replace numberOfOralFormants = 6 numberOfNasalFormants = 1 numberOfTrachealFormants = 1 numberOfFricationFormants = 5 numberOfNasalAntiFormants = 1 numberOfTrachealAntiFormants = 1 numberOfDeltaFormants = 1 tmin = 0 tmax = 1 kg = Create KlattGrid... kg tmin tmax numberOfOralFormants numberOfNasalFormants numberOfNasalAntiFormants ... numberOfFricationFormants numberOfTrachealFormants numberOfTrachealAntiFormants numberOfDeltaFormants printline =========== KlattGrid test_get_add_remove_extract_replace start for .itime to 20 call setget_1 "pitch" 130 call setget_1 "voicing amplitude" 90 call setget_1 "flutter" 0.5 call setget_1 "power1" 2 call setget_1 "power2" 3 call setget_1 "open phase" 0.5 call setget_1 "collision phase" 0.035 call setget_1 "double pulsing" 0.4 call setget_1 "spectral tilt" 20 call setget_1 "aspiration amplitude" 90 call setget_1 "breathiness amplitude" 90 call setget_1 "frication bypass" 20 call setget_1 "frication amplitude" 50 call setget_formants Oral call setget_formants Nasal call setget_formants Tracheal call setget_formants Delta call setget_formants Frication call setget_antiformants Nasal call setget_antiformants Tracheal endfor call test_deltaFormants removeObject (kg) printline =========== KlattGrid test_get_add_remove_extract_replace succesful endproc procedure test_get_add_remove_extract_replace_old_interface numberOfOralFormants = 6 numberOfNormalFormants = numberOfOralFormants numberOfNasalFormants = 1 numberOfTrachealFormants = 1 numberOfFricationFormants = 5 numberOfNasalAntiFormants = 1 numberOfTrachealAntiFormants = 1 numberOfDeltaFormants = 1 tmin = 0 tmax = 1 printline =========== KlattGrid test_get_add_remove_extract_replace_old_interface start kg = Create KlattGrid... kg tmin tmax numberOfOralFormants numberOfNasalFormants numberOfNasalAntiFormants ... numberOfFricationFormants numberOfTrachealFormants numberOfTrachealAntiFormants numberOfDeltaFormants for .itime to 20 call setget_1 "pitch" 130 call setget_1 "voicing amplitude" 90 call setget_1 "flutter" 0.5 call setget_1 "power1" 2 call setget_1 "power2" 3 call setget_1 "open phase" 0.5 call setget_1 "collision phase" 0.035 call setget_1 "double pulsing" 0.4 call setget_1 "spectral tilt" 20 call setget_1 "aspiration amplitude" 90 call setget_1 "breathiness amplitude" 90 call setget_1 "frication bypass" 20 call setget_1 "frication amplitude" 50 call setget_formants_old Normal call setget_formants_old Nasal call setget_formants_old Tracheal call setget_formants_old Frication call setget_antiformants_old Nasal call setget_antiformants_old Tracheal call setget_deltaformants endfor call test_deltaFormants_old removeObject (kg) printline =========== KlattGrid test_get_add_remove_extract_replace_old_interface succesful endproc procedure setget_1 .var$ .value selectObject (kg) .time = randomUniform (tmin,tmax) Add '.var$' point... .time .value .val = Get '.var$' at time... .time .vt = Extract '.var$' tier selectObject (kg) Remove '.var$' points between... tmin tmax .val1 = Get '.var$' at time... .time assert .val1 = undefined; Add '.var$' at time... '.time' '.value' plusObject (.vt) Replace '.var$' tier selectObject (kg) .val1 = Get '.var$' at time... .time assert .val1 =.val; Add '.var$' at time... '.time' '.value' removeObject (.vt) endproc procedure setget_2p .var$ .ifor .time .value selectObject (kg) Add delta '.var$' point... .ifor .time .value .val = Get delta '.var$' at time... .ifor .time assert .val = .value; Add delta '.var$' point... .ifor .time .value .fg = Extract delta formant grid selectObject (kg) Remove delta '.var$' points between... .ifor tmin tmax .val1 = Get delta '.var$' at time... .ifor .time assert .val1 = undefined; Get delta '.var$' at time... .ifor .time plusObject (.fg) Replace delta formant grid selectObject (kg) .val1 = Get delta '.var$' at time... .ifor .time assert .val1 =.val; Get delta '.var$' at time... .ifor .time removeObject (.fg) endproc procedure setget_3_old .var$ .choice$ .ifor .time .value selectObject (kg) Add '.var$' point... "'.choice$'" .ifor .time .value .val = Get '.var$' at time... "'.choice$'" .ifor .time assert .val = .value; Add '.var$' point... "'.choice$'" .ifor .time .value .fg = Extract formant grid... '.choice$' selectObject (kg) Remove '.var$' points between... "'.choice$'" .ifor tmin tmax .val1 = Get '.var$' at time... "'.choice$'" .ifor .time assert .val1 = undefined; Get '.var$' at time... "'.choice$'" .ifor .time plusObject (.fg) Replace formant grid... '.choice$' selectObject (kg) .val1 = Get '.var$' at time... "'.choice$'" .ifor .time assert .val1 =.val; Get '.var$' at time... "'.choice$'" .ifor .time removeObject (.fg) endproc procedure setget_3a_old .var$ .choice$ .ifor .time .value selectObject (kg) Add '.var$' point... "'.choice$'" .ifor .time .value .val = Get '.var$' at time... "'.choice$'" .ifor .time assert .val = .value; Add '.var$' point... "'.choice$'" .ifor .time .value .tier = Extract amplitude tier... "'.choice$'" .ifor selectObject (kg) Remove '.var$' points between... "'.choice$'" .ifor tmin tmax .val1 = Get '.var$' at time... "'.choice$'" .ifor .time assert .val1 = undefined; Get '.var$' at time... "'.choice$'" .ifor .time plusObject (.tier) Replace amplitude tier... "'.choice$'" .ifor selectObject (kg) .val1 = Get '.var$' at time... "'.choice$'" .ifor .time assert .val1 =.val; Get '.var$' at time... "'.choice$'" .ifor .time removeObject (.tier) endproc procedure setget_formants_old .type$ for .i to numberOf'.type$'Formants .time = randomUniform (tmin, tmax) .f = (2*.i-1) * randomUniform (450, 550) .b = .f /10 .a = randomUniform (70, 90) call setget_3_old "formant" "'.type$' formant" .i .time .f call setget_3_old "bandwidth" "'.type$' formant" .i .time .b call setget_3a_old "amplitude" "'.type$' formant" .i .time .a endfor selectObject (kg) Formula (frequencies)... "'.type$' formant" self + 100 Formula (bandwidths)... "'.type$' formant" self * 2 endproc procedure setget_3 .type$ .formant$ .var$ .ifor .time .value selectObject (kg) what$ = "'.type$' '.formant$' '.var$'" Remove 'what$' points... .ifor tmin tmax Add 'what$' point... .ifor .time .value .val = Get 'what$' at time... .ifor .time assert .val = .value; '.val' '.value' (Get 'what$' at time... '.ifor' '.time') .fg = Extract '.type$' '.formant$' grid selectObject (kg) Remove 'what$' points... .ifor tmin tmax .val1 = Get 'what$' at time... .ifor .time assert .val1 = undefined; '.val1' (Get 'what$' at time... '.ifor' '.time') plusObject (.fg) Replace '.type$' '.formant$' grid selectObject (kg) .val1 = Get 'what$' at time... .ifor .time if .var$ = "amplitude" .val = undefined endif assert .val1 =.val; '.val1' '.val' (Get 'what$' at time... '.ifor' '.time') removeObject (.fg) endproc procedure setget_formants .tYPE$ .type$ = replace_regex$ (.tYPE$, "(^.)","\L\1", 1) for .i to numberOf'.tYPE$'Formants .time = randomUniform (tmin, tmax) .f = (2*.i-1) * randomUniform (450, 550) .b = .f /10 .a = randomUniform (70, 90) call setget_3 '.type$' "formant" "frequency" .i .time .f call setget_3 '.type$' "formant" "bandwidth" .i .time .b if .tYPE$ <> "Delta" call setget_3 '.type$' "formant" "amplitude" .i .time .a endif endfor selectObject (kg) Formula ('.type$' formant frequencies)... self + 100 Formula ('.type$' formant bandwidths)... self * 2 endproc procedure setget_antiformants .tYPE$ .type$ = replace_regex$ (.tYPE$, "(^.)","\L\1", 1) for .i to numberOf'.tYPE$'AntiFormants .time = randomUniform (tmin, tmax) .f = (2*.i-1) * randomUniform (450, 550) .b = .f /10 call setget_3 '.type$' "antiformant" "frequency" .i .time .f call setget_3 '.type$' "antiformant" "bandwidth" .i .time .b endfor selectObject (kg) Formula ('.type$' antiformant frequencies)... self + 100 Formula ('.type$' antiformant bandwidths)... self * 2 endproc procedure setget_deltaformants for .i to numberOfDeltaFormants .time = randomUniform (tmin, tmax) .f = randomUniform (50, 60) .b = .f /10 call setget_2p "formant" .i .time .f call setget_2p "bandwidth" .i .time .b endfor endproc procedure setget_antiformants_old .type$ for .i to numberOf'.type$'AntiFormants .time = randomUniform (tmin, tmax) .f = (2*.i-1) * randomUniform (450, 550) .b = .f /10 call setget_3_old "formant" "'.type$' antiformant" .i .time .f call setget_3_old "bandwidth" "'.type$' antiformant" .i .time .b endfor endproc procedure test_deltaFormants_old .kg = Create KlattGrid... kg 0 1 6 1 1 6 1 1 1 Add pitch point... 0.5 100 Add voicing amplitude point... 0.5 90 Add bandwidth point... "Normal formant" 1 0.5 50 Add delta formant point... 1 0.5 500 Remove formant points between... "Normal formant" 1 0 2 Add formant point... "Normal formant" 1 0 400 Add formant point... "Normal formant" 1 1 600 Add formant point... "Normal formant" 1 0.003553 400 Add formant point... "Normal formant" 1 0.002 300 Add formant point... "Normal formant" 1 0.0112 430 .sound = To Sound selectObject (.kg) .fg = Extract formant grid (open phases)... 0.1 removeObject (.sound, .kg, .fg) endproc procedure test_deltaFormants .kg = Create KlattGrid... kg 0 1 6 1 1 6 1 1 1 Add pitch point... 0.5 100 Add voicing amplitude point... 0.5 90 Add oral formant bandwidth point... 1 0.5 50 Add delta formant frequency point... 1 0.5 500 Remove oral formant frequency points... 1 0 2 Add oral formant frequency point... 1 0 400 Add oral formant frequency point... 1 1 600 Add oral formant frequency point... 1 0.003553 400 Add oral formant frequency point... 1 0.002 300 Add oral formant frequency point... 1 0.0112 430 .sound = To Sound selectObject (.kg) .fg = Extract oral formant grid (open phases)... 0.1 removeObject (.sound, .fg, .kg) endproc praat-6.0.04/dwtest/TIMIT_train_dr1_fcjf0_sa1.phn000066400000000000000000000010271261542461700214060ustar00rootroot000000000000000 3050 h# 3050 4559 sh 4559 5723 ix 5723 6642 hv 6642 8772 eh 8772 9190 dcl 9190 10337 jh 10337 11517 ih 11517 12500 dcl 12500 12640 d 12640 14714 ah 14714 15870 kcl 15870 16334 k 16334 18088 s 18088 20417 ux 20417 21199 q 21199 22560 en 22560 22920 gcl 22920 23271 g 23271 24229 r 24229 25566 ix 25566 27156 s 27156 28064 ix 28064 29660 w 29660 31719 ao 31719 33360 sh 33360 33754 epi 33754 34715 w 34715 36080 ao 36080 36326 dx 36326 37556 axr 37556 39561 ao 39561 40313 l 40313 42059 y 42059 43479 ih 43479 44586 axr 44586 46720 h# praat-6.0.04/dwtest/Table_onewayaKruskalWallis.txt000066400000000000000000000001571261542461700222610ustar00rootroot00000000000000Group Data a1 27 a1 2 a1 4 a1 18 a1 7 a1 9 a2 20 a2 8 a2 14 a2 36 a2 21 a2 22 a3 34 a3 31 a3 3 a3 23 a3 30 a3 6praat-6.0.04/dwtest/Table_onewayaKruskalWallis2.txt000066400000000000000000000002351261542461700223400ustar00rootroot00000000000000Group Data a1 6.4 a1 6.8 a1 7.2 a1 8.3 a1 8.4 a1 9.1 a1 9.4 a1 9.7 a2 2.5 a2 3.7 a2 4.9 a2 5.4 a2 5.9 a2 8.1 a2 8.2 a3 1.3 a3 4.1 a3 4.9 a3 5.2 a3 5.5 a3 8.2praat-6.0.04/dwtest/Table_onewayanovadata.txt000066400000000000000000000001511261542461700212600ustar00rootroot00000000000000Group Data a1 6 a1 8 a1 4 a1 5 a1 3 a1 4 a2 8 a2 12 a2 9 a2 11 a2 6 a2 8 a3 13 a3 9 a3 11 a3 8 a3 7 a3 12praat-6.0.04/dwtest/Table_twowayanovadata.txt000066400000000000000000000002751261542461700213170ustar00rootroot00000000000000A B Data a1 b1 4.1 a1 b1 3.9 a1 b1 4.3 a1 b2 3.1 a1 b2 2.8 a1 b2 3.3 a1 b3 3.5 a1 b3 3.2 a1 b3 3.6 a2 b1 2.7 a2 b1 3.1 a2 b1 2.6 a2 b2 1.9 a2 b2 2.2 a2 b2 2.3 a2 b3 2.7 a2 b3 2.3 a2 b3 2.5 praat-6.0.04/dwtest/ba-da-continuum.praat000066400000000000000000000042671261542461700202570ustar00rootroot00000000000000# ba-da-continuum.praat # djmw 20090506 # de KlattGrid versie nsounds = 10 t1 = 0.05 t2 = t1+0.05 tm = 0.3 kg = Create KlattGrid... kg 0 tm 9 1 1 6 1 1 1 Add pitch point... 0 150 Add pitch point... tm 100 Add voicing amplitude point... t1 65 Add voicing amplitude point... t2 80 Add open phase point... t1 0.7 Add collision phase point... t1 0.05 #Add aspiration amplitude point... t1 30 #Add aspiration amplitude point... t2 40 Add oral formant frequency point... 1 t1 100 Add oral formant bandwidth point... 1 t1 50 Add oral formant frequency point... 1 t2 800 Add oral formant bandwidth point... 2 t1 100 Add delta formant bandwidth point... 1 t1 100 for iformant from 3 to 9 frequency = (2 * iformant - 1) * 500 Add oral formant frequency point... iformant t2 frequency Add oral formant bandwidth point... iformant t1 frequency Add oral formant bandwidth point... iformant t2 frequency / 15 endfor for isound to nsounds select kg Remove oral formant frequency points... 2 0 tm f2 = 100 + (2900 / (nsounds - 1)) * (isound - 1) Add oral formant frequency point... 2 t1 f2 Add oral formant frequency point... 2 t2 1200 To Sound Fade out... All tm -0.005 y Rename... bada'isound' endfor # cleanup select kg #Remove # old style according manual Source-filter synthesis 3. does not work nbeacause of error in script procedure ba_da_old_style tm = 0.4 t1 = 0.05 pt = Create PitchTier... f0 0 tm Add point... 0 150 Add point... tm 100 pp = To PointProcess Remove points between... 0 t1 Remove points between... tm-0.05 tm s = To Sound (phonation)... 44100 0.6 0.05 0.7 0.03 3.0 4.0 intens = Create IntensityTier... intens 0 tm Add point... t1 60 Add point... t1+0.05 80 plus s source = Multiply for i to 10 f2_locus = 500+(2500/9)*(i-1) fg = Create FormantGrid... filter 0 tm 9 0.001 1000 0 100 Remove formant points between... 1 0 tm Add formant point... 1 t1 100 Add bandwidth point... 1 t1 50 Add formant point... 2 t1 f2_locus Add bandwidth point... 2 t1 100 plus source Filter Rename... old_bada'i' select fg Remove endfor select source plus s plus intens plus pp plus pt Remove endproc praat-6.0.04/dwtest/discriminant_tableofreal_mahalanobis.praat000066400000000000000000000021721261542461700246470ustar00rootroot00000000000000# discriminant_tableofreal_mahalanobis.praat # djmw 20100106 # This scripts calculates the amount of overlap between two normal distributions # both distributions have sigma = 1 # mu1 = 0 and mu2 varies from 1 to 5 n = 20000 t0 = Create TableOfReal... t0 n 1 for i to n/2 Set row label (index)... i 1 endfor for i from n/2+1 to n Set row label (index)... i 2 endfor for mu to 5 select t0 Formula... randomGauss ((if row < n/2 then 0 else mu fi), 1) d = To Discriminant for j to 2 select d plus t0 t'j' = To TableOfReal (mahalanobis)... 'j' n endfor tt = Copy... tt for nsigma to 5 Formula... Object_'t1'[row,col] < nsigma and Object_'t2'[row,col] < nsigma nr = 0 for kr to n if Object_'tt'[kr,1] = 1 nr += 1 endif endfor z12 = 0 + nsigma z21 = mu - nsigma expect = 0 if z21 < z12 # we have overlap expect = (gaussQ (z21) - gaussQ (z12)) * n endif diff = nr - expect printline For d='mu' and 'nsigma'-sigma: 'nr' from 'n' overlap; diff = 'diff:1' (expect = 'expect:1') endfor select d plus t1 plus t2 plus tt Remove endforpraat-6.0.04/dwtest/regexp_textgrid_test.praat000066400000000000000000000004271261542461700215310ustar00rootroot00000000000000# regexp_textgrid_test.praat # djmw 20081119 Create Sound from formula... sineWithNoise Mono 0 1 44100 1/2 * sin(2*pi*377*x) + randomGauss(0,0.1) To TextGrid... hhhhh select TextGrid sineWithNoise for i to 5 Insert boundary... 1 0.1*i Set interval text... 1 i+1 'i' endforpraat-6.0.04/dwtest/runAllTests.praat000066400000000000000000000013621261542461700175450ustar00rootroot00000000000000# run_all_tests.praat tests = Create Strings as file list... tests test_*.praat ntests = Get number of strings for itest to ntests select tests test$ = Get string... itest printline 'test$' report_before$ = Report memory use execute 'test$' @check_memory: report_before$, " " endfor procedure check_memory: .report_before$, .preprint$ .m$[1] = "Strings: " .m$[2] = "Arrays: " .m$[3] = "Things: " .report_after$ = Report memory use appendInfoLine: .preprint$, "Memory:" for .i to 3 .nb = extractNumber (.report_before$, .m$[.i]) .na = extractNumber (.report_after$, .m$[.i]) .post$ = if .nb <> .na then " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" else "" endif appendInfoLine: .preprint$, .m$[.i], .nb, " ", .na, .post$ endfor endproc praat-6.0.04/dwtest/salaries_gender.txt000066400000000000000000000006421261542461700201240ustar00rootroot00000000000000Gender Education Salary Female Degree 24 Female Degree 26 Female Degree 25 Female Degree 24 Female Degree 27 Female Degree 24 Female Degree 27 Female Degree 23 Female No degree 15 Female No degree 17 Female No degree 20 Female No degree 16 Male Degree 25 Male Degree 29 Male Degree 27 Male No degree 19 Male No degree 18 Male No degree 21 Male No degree 20 Male No degree 21 Male No degree 22 Male No degree 19 praat-6.0.04/dwtest/test_Confusion.praat000066400000000000000000000025161261542461700202710ustar00rootroot00000000000000# test_Confusion.praat # djmw 20110511, 20151020 printline test_Confusion.praat l$[1] = "u" l$[2] = "i" l$[3] = "e" nlabels = 3 c1 = Create simple Confusion... test 'l$[1]' 'l$[2]' 'l$[3]' nrows = Get number of rows ncols = Get number of columns assert nrows = ncols assert nrows = nlabels for i to nlabels rl$ = Get row label... i cl$ = Get column label... i assert rl$ = cl$ and l$[i] = rl$ endfor for i to 10 stim$ = l$[1] resp$ = l$[2] Increase... 'stim$' 'resp$' val = Get value (labels)... 'stim$' 'resp$' assert val = i ssum = Get stimulus sum... 'stim$' rsum = Get response sum... 'resp$' assert ssum = rsum and ssum = i endfor Remove printline ...2 c2 = Create simple Confusion... test 'l$[1]' 'l$[2]' 'l$[3]' Set value... 1 1 6 Set value... 1 2 2 Set value... 1 3 1 Set value... 2 1 3 Set value... 2 2 4 Set value... 2 3 2 Set value... 3 1 1 Set value... 3 2 4 Set value... 3 3 4 select c2 c3 = Group stimuli... "u i" high 1 v = Get value (labels)... high u assert v = 9 v = Get value (labels)... high i assert v = 6 v = Get value (labels)... high e assert v = 3 Remove printline ...3 select c2 c4 = Group responses... "i e" front 1 v = Get value (labels)... u front assert v = 3 v = Get value (labels)... i front assert v = 6 v = Get value (labels)... e front assert v = 8 plus c2 Remove printline test_Confusion.praat OK praat-6.0.04/dwtest/test_Correlation.praat000066400000000000000000000007031261542461700206030ustar00rootroot00000000000000# test_Correlation.praat # djmw 20110518 printline test_Correlation t = Create TableOfReal (Pols 1973)... no Formula... log10(self) cor = To Correlation # table 3.1 Weenink (2006) c21ref$ = "-0.302" c31ref$ = "0.195" c32ref$ = "0.120" c21 = Get value... 2 1 c31 = Get value... 3 1 c32 = Get value... 3 2 assert fixed$(c21,3) = c21ref$ assert fixed$(c31,3) = c31ref$ assert fixed$(c32,3) = c32ref$ plus t Remove printline test_Correlation OK praat-6.0.04/dwtest/test_DTW.praat000066400000000000000000000017461261542461700167700ustar00rootroot00000000000000# test_DTW.praat # djmw 20100504, 20120223 printline DTW_test start stepSize = 0.005 s1 = Create Sound from formula... s1 Mono 0 1 44100 1/2 * sin(2*pi*377*x) + randomGauss(0,0.1) s2 = Copy... s2 plus s1 dtw = To DTW... 0.015 stepSize 0.1 1/2 < slope < 2 printline 'tab$' Slope constraint nx = Get maximum consecutive steps... X assert nx <= 2 ny = Get maximum consecutive steps... Y assert ny <= 2 for i to 20 t = i * 0.04 ty = Get y time... t assert (ty - stepSize) < t and t < (ty + stepSize) tx = Get x time... t assert (tx - stepSize) < t and t < (tx + stepSize) endfor select dtw printline 'tab$' To Polygon... pol = To Polygon... 0.1 1/2 < slope < 2 Remove select dtw pol = To Polygon... 0.1 1/3 < slope < 3 Remove select dtw pol = To Polygon... 0.1 2/3 < slope < 3/2 Remove printline 'tab$' To Matrix select dtw mat = To Matrix (distances) Remove select dtw To Matrix (cumm. distances)... 0.05 2/3 < slope < 3/2 Remove select dtw plus s1 plus s2 Remove printline test_DTW end O.K. praat-6.0.04/dwtest/test_Discriminant.praat000066400000000000000000000005741261542461700207540ustar00rootroot00000000000000# test_Discriminant.praat # djmw 20110518, 20141030 appendInfoLine: "test_Discriminant" t = Create TableOfReal (Pols 1973): "no" Formula: "log10(self)" dis = To Discriminant plus t clas = To ClassificationTable: "yes", "yes" conf = To Confusion: "no" fc = Get fraction correct assert fc -0.74 < 0.00001 removeObject: t, dis, clas, conf appendInfoLine: "test_Discriminant OK" praat-6.0.04/dwtest/test_EditCostTable.praat000066400000000000000000000037011261542461700210110ustar00rootroot00000000000000# test_EditCostTable.praat # djmw 20120522 printline test_EditCostTable numberOfTargets = 4 numberOfSources = 4 table = Create empty EditCostsTable... editCosts numberOfTargets numberOfSources printline 'tab$'Set values... for i to numberOfTargets targetSymbol$[i] = "t'i'" Set target symbol (index)... i t'i' Set insertion costs... t'i' numberOfSources*i endfor for i to numberOfSources sourceSymbol$[i] = "s'i'" Set source symbol (index)... i s'i' Set deletion costs... s'i' numberOfTargets*i endfor cost = 0 for i to numberOfTargets for j to numberOfSources cost += 1 Set substitution costs... t'i' s'j' cost endfor endfor for i to numberOfSources Set substitution costs... nomatch s'i' 20 endfor for i to numberOfTargets Set substitution costs... t'i' nomatch 21 endfor Set costs (others)... 1 2 3 4 costs = Get cost (others)... Insertion assert costs = 1 costs = Get cost (others)... Deletion assert costs = 2 costs = Get cost (others)... Equality assert costs = 3 costs = Get cost (others)... Inequality assert costs = 4 printline 'tab$'Get values... for i to numberOfTargets target$ = targetSymbol$[i] index = Get target index... 'target$' assert index = i cost = Get insertion cost... 'target$' assert cost = numberOfSources*i endfor for i to numberOfSources source$ = sourceSymbol$[i] index = Get source index... 'source$' assert index = i cost = Get deletion cost... 'source$' assert cost = numberOfTargets*i endfor cost = 0 for i to numberOfTargets target$ = targetSymbol$[i] for j to numberOfSources source$ = sourceSymbol$[j] cost += 1 scost = Get substitution cost... 'target$' 'source$' assert scost = cost endfor endfor for i to numberOfSources source$ = sourceSymbol$[i] cost = Get substitution cost... nomatch 'source$' assert cost = 20 endfor for i to numberOfTargets target$ = targetSymbol$[i] cost = Get substitution cost... 'target$' nomatch assert cost = 21 endfor Remove printline test_EditCostTable OKpraat-6.0.04/dwtest/test_FFNet.praat000066400000000000000000000016071261542461700172700ustar00rootroot00000000000000# test_FFNet.praat # djmw 20110512 printline test FFNet Create iris example... 0 0 ffnet = selected ("FFNet") pattern = selected ("Pattern") cat = selected ("Categories") ntries = 10 error1 = Get total costs... Minimum-squared-error tab = Create Table with column names... results ntries costsb costsa fc for i to ntries select ffnet Reset... 0.1 plus pattern plus cat costsb = Get total costs... Minimum-squared-error Learn... 200 1e-7 Minimum-squared-error costsa = Get total costs... Minimum-squared-error select ffnet plus pattern cati = To Categories... Winner-takes-all plus cat fd = Get fraction different fc = 1 -fd select tab Set numeric value... i costsb costsb Set numeric value... i costsa costsa Set numeric value... i fc fc select cati Remove endfor select tab mean = Get mean... fc assert fc > 0.97 plus ffnet plus pattern plus cat Remove printline FFNet ok praat-6.0.04/dwtest/test_FilterBank.praat000066400000000000000000000043611261542461700203470ustar00rootroot00000000000000# test_Filterbank.praat # djmw 20110907 eps = 1.6e-16 printline test_FilterBank starttime = 0 endtime = 1 fs = 44100 s = Create Sound from formula... sineWithNoise 1 starttime endtime fs 1/2 * sin(2*pi*377*x) + randomGauss(0,0.1) call test_FormantFilter s call test_BarkFilter s call test_MelFilter s select s Remove printline test_FilterBank OK procedure test_FormantFilter .s printline 'tab$' test FormantFilter bf_first = 100 fdistance = 50 timestep = 0.005 select .s .ff = To FormantFilter... 0.015 timestep bf_first fdistance 0 1.1 75 600 call queries .ff call modifies .ff call commons .ff select .ff Remove endproc procedure test_BarkFilter .s printline 'tab$' test BarkFilter select .s bf_first = 1 fdistance = 1 .bf = To BarkFilter... 0.015 timestep 1 1 0 call queries .bf call modifies .bf call commons .bf select .bf Remove endproc procedure test_MelFilter .s printline 'tab$' test MelFilter select .s bf_first = 100 fdistance = 100 .mf = To MelFilter... 0.015 timestep bf_first fdistance 0 call queries .mf call modifies .mf call commons .mf select .mf .mfcc = To MFCC... 12 Remove select .mf Remove endproc procedure commons .bf select .bf .in = To Intensity Remove select .bf .mat = To Matrix Remove endproc procedure queries .fb select .fb .starttime = Get start time .endtime = Get end time .dur = Get total duration assert abs( .dur -(.endtime-.starttime)) <= eps assert .starttime = starttime assert .endtime = endtime .timestep = Get time step assert .timestep = timestep; '.timestep' 'timestep' .bf_first = Get lowest frequency assert .bf_first >= 0; '.bf_first' 'bf_first' .bf_last = Get highest frequency assert .bf_last <= fs/2 .nf = Get number of frequencies assert .nf >= 1 .fdistance = Get frequency distance assert .fdistance=fdistance; '.fdistance' 'fdistance' .f_from_row[1] = Get frequency from row... 1 for .i from 2 to .nf .f_from_row[.i] = Get frequency from row... .i .fi = .f_from_row[.i] .fim1 = .f_from_row[.i-1] assert .f_from_row[.i] >.f_from_row[.i-1]; '.fi' >.'fim1' endfor for .i to .nf .time = randomUniform (.starttime, endtime) .vali = Get value in cell... .time .i endfor endproc procedure modifies .fb select .fb Equalize intensities... 80 endproc praat-6.0.04/dwtest/test_KlattGrid.praat000066400000000000000000000104021261542461700202040ustar00rootroot00000000000000# test_KlattGrid.praat # djmw 20151020 printline test_KlattGrid.praat t = Create Table with column names... t 25 tier min max nf Set string value... 1 tier pitch Set string value... 2 tier voicing amplitude Set string value... 3 tier flutter Set string value... 4 tier power1 Set string value... 5 tier power2 Set string value... 6 tier open phase Set string value... 7 tier collision phase Set string value... 8 tier double pulsing Set string value... 9 tier spectral tilt Set string value... 10 tier aspiration amplitude Set string value... 11 tier breathiness amplitude Set numeric value... 1 min 80 Set numeric value... 2 min 0 Set numeric value... 3 min 0 Set numeric value... 4 min 1 Set numeric value... 5 min 2 Set numeric value... 6 min 0 Set numeric value... 7 min 0 Set numeric value... 8 min 0 Set numeric value... 9 min 0 Set numeric value... 10 min 0 Set numeric value... 11 min 0 Set numeric value... 1 max 400 Set numeric value... 2 max 93 Set numeric value... 3 max 1 Set numeric value... 4 max 4 Set numeric value... 5 max 5 Set numeric value... 6 max 0.9 Set numeric value... 7 max 0.05 Set numeric value... 8 max 1 Set numeric value... 9 max 40 Set numeric value... 10 max 90 Set numeric value... 11 max 90 Set string value... 12 tier oral formant frequency Set string value... 13 tier nasal formant frequency Set string value... 14 tier nasal antiformant frequency Set string value... 15 tier tracheal formant frequency Set string value... 16 tier tracheal antiformant frequency Set string value... 17 tier delta formant frequency Set string value... 18 tier frication formant frequency Set numeric value... 12 min 100 Set numeric value... 13 min 100 Set numeric value... 14 min 0 Set numeric value... 15 min 200 Set numeric value... 16 min 100 Set numeric value... 17 min 0 Set numeric value... 18 min 100 Set numeric value... 12 max 6000 Set numeric value... 13 max 6000 Set numeric value... 14 max 6000 Set numeric value... 15 max 2000 Set numeric value... 16 max 1000 Set numeric value... 17 max 1000 Set numeric value... 18 max 8000 Set string value... 19 tier oral formant bandwidth Set string value... 20 tier nasal formant bandwidth Set string value... 21 tier nasal antiformant bandwidth Set string value... 22 tier tracheal formant bandwidth Set string value... 23 tier tracheal antiformant bandwidth Set string value... 24 tier delta formant bandwidth Set string value... 25 tier frication formant bandwidth nof = 8 nnf = 3 nnaf = 4 ntf = 4 ntaf = 2 ndf = 2 nff = 6 Set numeric value... 12 nf nof Set numeric value... 13 nf nnf Set numeric value... 14 nf nnaf Set numeric value... 15 nf ntf Set numeric value... 16 nf ntaf Set numeric value... 17 nf ndf Set numeric value... 18 nf nff for i from 19 to 25 bwmin = Object_'t'[i-7, "min"] bwmax = Object_'t'[i-7, "max"] nf = Object_'t'[i-7, "nf"] Set numeric value... i min bwmin/10 Set numeric value... i max bwmax/10 Set numeric value... i nf nf endfor nPhonationTiers = 11 tmin = 0 tmax = 1 kg = Create KlattGrid... kg tmin tmax nof nnf nnaf nff ntf ntaf ndf ntimes = 5 dt = 0.0001 for i to nPhonationTiers select kg tier$ = Object_'t'$[i,"tier"] vmin = Object_'t'[i,"min"] vmax = Object_'t'[i,"max"] for itime to ntimes time[itime] = randomUniform (tmin, tmax) val[itime] = randomUniform (vmin, vmax) Add 'tier$' point... time[itime] val[itime] endfor for itime to ntimes val = Get 'tier$' at time... time[itime] assert val = val[itime] endfor Remove 'tier$' points... tmin tmax tier = Extract 'tier$' tier Remove printline ... 'tier$' endfor for i from nPhonationTiers+1 to 25 select kg tier$ = Object_'t'$ [i, "tier"] vmin = Object_'t' [i, "min"] vmax = Object_'t' [i, "max"] nf = Object_'t' [i, "nf"] print ... 'tier$' for ifor from 1 to nf select kg for itime to ntimes time[itime] = randomUniform (tmin, tmax) val[itime] = randomUniform (vmin, vmax) Add 'tier$' point... ifor time[itime] val[itime] endfor for itime to ntimes val = Get 'tier$' at time... ifor time[itime] assert val = val[itime] endfor Remove 'tier$' points... ifor tmin tmax grid$ = replace$ (tier$, " frequency", "", 1) grid$ = replace$ (grid$, " bandwidth", "", 1) grid = Extract 'grid$' grid print 'ifor' Remove endfor print 'newline$' endfor removeObject: kg, t printline test_KlattGrid.praat OKpraat-6.0.04/dwtest/test_KruskalWallis.praat000066400000000000000000000010441261542461700211110ustar00rootroot00000000000000# test_KruskalWallis.praat printline test_KruskalWallis.praat table = Read from file... Hayes_table_19.7.1.txt report$ = Report one-way Kruskal-Wallis... Data Group hprime = extractNumber (report$, "Chi squared:") groupI = extractNumber (report$, " I") groupII = extractNumber (report$, " II") groupIII = extractNumber (report$, " III") printline 'hprime' 'groupI' 'groupII' 'groupIII' assert abs(hprime-13.8443) < 0.0001 assert groupI = 139 assert groupII = 200 assert groupIII = 327 removeObject: table printline test_KruskalWallis.praat OK praat-6.0.04/dwtest/test_LPC.praat000066400000000000000000000035271261542461700167470ustar00rootroot00000000000000# test_LPC.praat # djmw 20080122, 20110528 printline test_LPC # formants of straigth tube for i to 5 f[i] = (2*i-1)*500 b[i] = i * 50 endfor debug = 0 pt = Create PitchTier... empty 0 0.5 Add point... 0 150 source = To Sound (pulse train)... 44100 1 0.05 2000 no ft = Create FormantTier... empty 0 0.5 Add point... 0 'f[1]' 'b[1]' 'f[2]' 'b[2]' 'f[3]' 'b[3]' 'f[4]' 'b[4]' 'f[5]' 'b[5]' plus source soundpre = Filter sound = Resample... 10000 50 select pt plus source plus ft plus soundpre Remove for imethod to 4 select sound if imethod = 1 method$ = "auto" lpc = To LPC (autocorrelation)... 10 0.025 0.005 50 elsif imethod = 2 method$ = "covar" lpc = To LPC (covariance)... 10 0.025 0.005 50 elsif imethod = 3 method$ = "burg" lpc = To LPC (burg)... 10 0.025 0.005 50 elsif imethod = 4 method$ = "marple" lpc = To LPC (marple)... 10 0.025 0.005 50 1e-06 1e-06 endif call get_formants 'lpc' 'method$' deltaf1 = deltaf deltab1 = deltab assert deltaf1 < 0.07 and deltab1 < 3.2; ('method$') select lpc plus sound lpcr = To LPC (robust)... 0.025 50 1.5 5 1e-06 no call get_formants lpcr 'method$':robust deltaf2 = deltaf deltab2 = deltab assert deltaf2 < 0.005 and deltab2 < 0.2; ('method$':robust) select lpc plus lpcr Remove endfor select sound Remove printline test_LPC OK procedure get_formants .lpc .method$ select .lpc .f = To Formant (keep all) deltaf = 0 deltab = 0 for .nf to 5 .f[.nf] = Get quantile... .nf 0 0 Hertz 0.5 .b[.nf] = Get quantile of bandwidth... .nf 0 0 Hertz 0.5 if .nf <= 3 deltaf += abs(f[.nf]- .f[.nf]) / f[.nf] deltab += abs(b[.nf]- .b[.nf]) / b[.nf] endif endfor deltaf /= 3 deltab /= 3 printline deltaf = 'deltaf:4' deltab = 'deltab:4' '.f[1]:0' '.b[1]:0' '.f[2]:0' '.b[2]:0' '.f[3]:0' '.b[3]:0' '.f[4]:0' '.b[4]:0' '.f[5]:0' '.b]5:0' ('.method$') select .f Remove endproc praat-6.0.04/dwtest/test_Ltas_reportSpectralTilt.praat000066400000000000000000000022761261542461700231620ustar00rootroot00000000000000# test_Ltas_reportSpectralTilt.praat # djmw 20130813 appendInfoLine ("test_Ltas_reportSpectralTilt") s[1] = do ("Create Sound from formula...", "sineWithNoise", 1, 0, 1, 44100, "randomGauss(0,0.1)") s[2] = do ("Filter (de-emphasis)...", 50) # some of the following values are rough guesses, if the assertion failes adapt the values somewhat slope[1] = 0 ; dB/Hz (this value is exact) slopemargin[1] = 0.5 ; approximate slope[2] = -20 ; dB/decade (this value is exact) slopemargin[2] = 1.5 ; approximate offset[1] = 30.8 ; dB approximate offsetmargin[1] = 3 ; approximate offset[2] = 95 ; dB ; approximate offsetmargin[2] = 4 ; approximate for i to 2 selectObject (s[i]) ltas = do ("To Ltas...", 100) info$ = do$ ("Report spectral tilt...", 100, 10000, "Logarithmic", "Robust") slope = extractNumber (info$, "Slope:") offset = extractNumber (info$, "Offset:") appendInfoLine (tab$, "Slope= ", fixed$ (slope, 4), "; Offset= ", fixed$ (offset, 4)) assert slope > (slope[i] - slopemargin[i]) and slope < (slope[i] + slopemargin[i]) assert offset > (offset[i] - offsetmargin[i]) and offset < (offset[i] + offsetmargin[i]) removeObject (s[i], ltas) endfor appendInfoLine ("test_Ltas_reportSpectralTilt OK") praat-6.0.04/dwtest/test_MDS.praat000066400000000000000000000031351261542461700167470ustar00rootroot00000000000000# test_MDS.praat printline test MDS dr = Create letter R example... 0 c[1] = To Configuration (monotone mds)... 2 "Primary approach" 1e-05 50 1 select dr c[2] = To Configuration (i-spline mds)... 2 1 1 1e-05 50 1 select dr c[3] = To Configuration (interval mds)... 2 1e-05 50 1 select dr c[4] = To Configuration (ratio mds)... 2 1e-05 50 1 select dr c[5] = To Configuration (absolute mds)... 2 1e-05 50 1 select dr c[6] = To Configuration (kruskal)... 2 2 "Primary approach" Formula1 1e-05 50 1 printline ... comparing configurations for i from 2 to 6 select c[1] plus c[i] p1 = To Procrustes... no plus c[i] ct[i] = To Configuration plus c[1] p2 = To Procrustes... no call check_if_identity_transform p2 plus p1 Remove endfor ct[1] = c[1] printline .... INDSCAL select c[1] for i from 2 to 6 plus ct[i] endfor To Distance for i to 6 dist[i] = selected ("Distance", i) endfor To Configuration (indscal)... 2 yes 1e-5 100 1 ic = selected ("Configuration") is = selected ("Salience") select c[1] plus ic p3 = To Procrustes... no plus ic cp3 = To Configuration plus c[1] p4 = To Procrustes... no call check_if_identity_transform p4 select dr plus ic plus is plus p3 plus p4 plus cp3 for i to 6 plus c[i] plus ct[i] plus dist[i] endfor Remove printline test MDS ok procedure check_if_identity_transform .p select .p .scale = Get scale assert .scale > 1 - 1e-4 for .j to 2 tj = Get translation element... .j assert abs(tj) < 1e-6 for .k to 2 tjk = Get transformation element... .j .k if .j = .k assert tjk > 1 - 1e-4 else assert abs(tjk) < 1e-6 endif endfor endfor endproc praat-6.0.04/dwtest/test_Matrix_solve.praat000066400000000000000000000016331261542461700210010ustar00rootroot00000000000000# test_Matrix_solve.praat # djmw 20031020 procedure matrix_solve ncols for i to 4 nrows = i * ncols printline nrows = 'nrows'; ncols = 'ncols' eps = nrows * 1e-7 Create simple Matrix... n'i' nrows ncols+1 0 Formula... if (col <= ((row - 1) mod ncols)+1) then 1 else 0 fi Formula... if col = 1 then self + ((row-1) div ncols) else self fi Formula... if col = ncols+1 then (row-1) mod ncols + 1 + ((row-1) div ncols) else self fi Solve equation... 0 # solution must be all ones. for j to ncols s = Get value in cell... 1 j assert (s - 1) < eps ; nowsr = 'nrows' ncols = 'ncols' endfor select Matrix n'i' plus Matrix n'i'_solution Remove endfor endproc printline ----- test_Matrix_solve.praat ----- # test for several dimensions call matrix_solve 1 call matrix_solve 10 call matrix_solve 100 printline ----- test_Matrix_solve.praat (end) ----- praat-6.0.04/dwtest/test_OnewayAnova.praat000066400000000000000000000007621261542461700205560ustar00rootroot00000000000000# test_OnewayAnova.praat # djmw 20120625 printline test_OnewayAnova.praat # unequal groups hayes pg 371 table = Read from file... Hayes_table_10.18.1.txt report$ = Report one-way anova... Data Group n n n between = extractNumber (report$, "Between") within = extractNumber (report$, "Within") total = extractNumber (report$, "Total") assert abs (between-22.57) < 0.01 assert abs (within - 878.93) < 0.01 assert abs (total - 901.5) < 0.1 removeObject: table printline test_OnewayAnova.praat OK praat-6.0.04/dwtest/test_PCA.praat000066400000000000000000000021101261542461700167170ustar00rootroot00000000000000# test_PCA.praat # djmw 20110525 printline test_PCA # 5 points, # p1, p2,p3 on a line throug the origin with an angle of pi/6 with variance 6 # p4, p2, p5 orthogonal with variance 2 # tol = 1e-12 npoints = 5 t = Create TableOfReal... t npoints 2 Set value... 1 1 -sqrt(2) Set value... 1 2 -1 Set value... 2 1 0 Set value... 2 2 0 Set value... 3 1 sqrt(2) Set value... 3 2 1 Set value... 4 1 -1/sqrt(3) Set value... 4 2 sqrt(2/3) Set value... 5 1 1/sqrt(3) Set value... 5 2 -sqrt(2/3) pca = To PCA printline ... eigenvalues ss1 = Get eigenvalue... 1 ss2 = Get eigenvalue... 2 assert abs(ss1 - 6/(npoints-1)) < tol assert abs(ss2 - 2/(npoints-1)) < tol printline ... fraction variance accounted for fvaf = Get fraction variance accounted for... 1 1 assert abs(fvaf - 6/8)< tol printline ... centroid at (0,) printline ...eigenvectors othogonal ev11 = Get eigenvector element... 1 1 ev12 = Get eigenvector element... 1 2 ev21 = Get eigenvector element... 2 1 ev22 = Get eigenvector element... 2 2 inprod = ev11*ev21+ev12*ev22 assert abs(inprod) < tol plus t Remove printline test_PCA OK praat-6.0.04/dwtest/test_Permutation.praat000066400000000000000000000037321261542461700206360ustar00rootroot00000000000000# test_Permutation.praat # djmw 20050710, 20070820, 20100525, 20100819, 20110418 printline test_Permutation call test_600_12 call rotate call sequence call swap call invertp printline test_Permutation OK procedure rotate printline ..Rotate for .i to 20 .p = Create Permutation... test .i y print '.i' for .k to .i select .p .pk = Rotate... 0 0 .k .pkk = Get value... .k+1 if .pkk > 0 assert .pkk = 1 ; i='.i', k='.k' endif .pki = Rotate... 0 0 -.k for .l to .k .pkil = Get value... .l assert .pkil = .l endfor plus .pk Remove print . endfor printline ..o.k. select .p Remove endfor endproc procedure invertp printline ..Invert for .i to 20 .p = Create Permutation... test .i y .pin = Invert plus .p .pm = Multiply for .k to .i .pmk = Get value... .k assert .pmk = .k ; i='.i', k='.k' endfor print . plus .pin plus .p Remove endfor printline ..o.k. endproc procedure test_600_12 printline ..test_600_12 .p = Create Permutation... 600 600 y .pin = Interleave... 0 0 12 1 .pininv = Invert plus .pin .pm = Multiply for .l to 600 .pkil = Get value... .l assert .pkil = .l; l='.l' endfor plus .pin plus .pininv plus .p Remove printline ..o.k. endproc procedure sequence printline ..Sequences .n = 4 .np = 4*3*2 - 1 Create Permutation... ps .n y for .j to .np for .i to .j Next endfor for .i to .j Previous endfor for .i to .n .val = Get value... .i assert .val = .i endfor print . endfor Remove printline ..o.k. endproc procedure swap print ..Swap positions .p = Create Permutation... id 10 y for .i to 10 for .j to 10 select .p .ps = Copy... swap Swap positions... .i .j for .k to 10 select .p .pk = Get value... .k select .ps .psk = Get value... .k if .k <> .i and .k <> .j assert .pk = .psk endif endfor select .ps Remove print . endfor endfor select .p Remove printline ..o.k. endproc praat-6.0.04/dwtest/test_Polygon_getLocationOfPoint.praat000066400000000000000000000035561261542461700236110ustar00rootroot00000000000000# test_Polygon_getLocationOfPoint.praat eps = 1e-15 # minimal crossing Polygon px[1] = 0.123 py[1] = 0 px[2] = 0.123 py[2] = 1 px[3] = 1.123 py[3] = 0 px[4] = 1.123 py[4] = 1 np = 4 p = Create simple Polygon... p 'px[1]' 'py[1]' 'px[2]' 'py[2]' 'px[3]' 'py[3]' 'px[4]' 'py[4]' px[5] = px[1] py[5] = py[1] printline ... x left xm = px[1] - 0.1 for i to 100 ym = randomUniform(py[1]-1, py[2]+1) loc$ = Get location of point... xm ym eps assert loc$="O"; 'xm' 'ym' endfor printline ... x right xm = px[3] + 0.1 for i to 100 ym = randomUniform(py[1]-1, py[2]+1) loc$ = Get location of point... xm ym eps assert loc$="O"; 'xm' 'ym' endfor printline ... y top ym = py[2] + 0.1 for i to 100 xm = randomUniform(px[1]-1, px[3]+1) loc$ = Get location of point... xm ym eps assert loc$="O"; 'xm' 'ym' endfor printline ... y bottom ym = py[1] - 0.1 for i to 100 xm = randomUniform(px[1]-1, px[3]+1) loc$ = Get location of point... xm ym eps assert loc$="O"; 'xm' 'ym' endfor printline ... vertices for i to np loc$ = Get location of point... px[i] py[i] eps assert loc$ = "V" endfor printline ... edges for i to np for j to 100 f = randomUniform(0,1) xm = px[i]+f*(px[i+1]-px[i]) ym = py[i] +f*(py[i+1]-py[i]) loc$ = Get location of point... xm ym eps assert loc$ = "E"; 'xm' 'ym' endfor endfor printline ... inside for i to 100 fx = randomUniform (0,0.5) fy = randomUniform (fx, 1-fx) xm = px[1]+fx ym = py[1]+fy loc$ = Get location of point... xm ym eps assert loc$ = "I"; 'xm' 'ym' fx = 1 - fx xm = px[1]+fx loc$ = Get location of point... xm ym eps assert loc$ = "I"; 'xm' 'ym' endfor printline ... outside #could be done better for i to 100 fx = randomUniform (0,0.5) fy = randomUniform (0, fx) xm = px[1] + fx ym = py[1] + fy loc$ = Get location of point... xm ym eps assert loc$ = "O"; 'xm' 'ym' endfor select p Remove # now use epsilon ... praat-6.0.04/dwtest/test_Polygon_simplify.Matrix000066400000000000000000000075441261542461700220340ustar00rootroot00000000000000File type = "ooTextFile" Object class = "Matrix 2" 0.5 100.5 100 1 1 0.5 2.5 2 1 1 0.48494076548132437 0.3321202587919751 0.30575672507518403 0.5305516746271928 0.2599470570028398 0.5749720815675041 0.6568742600238754 0.5758106616051097 0.46187961356672635 0.6815312283403661 0.616230423407458 0.6321887679830146 0.6119354592509548 0.619551772114672 0.6747820467027944 0.6053507104944407 0.6744852219347941 0.6521442623629092 0.646942498647082 0.6005431430760269 0.7444762685436419 0.602694678796173 0.7537035926627527 0.7584031538763572 0.6433457606714617 0.6348722288713303 0.7212837441824056 0.7748849145111145 0.6139716959288507 0.7860608322666525 0.2754973056106338 0.2540510068018146 0.44523987620541766 0.07841666575037853 0.4476892768753488 0.11494484316267783 0.6951687272378206 0.583362092525197 0.06631533522833533 0.004101374898366705 0.20261300439857216 0.037034547300827475 0.07402422831306754 0.11109557366596974 0.2191164138565274 0.07546885050441515 0.20483237480364308 0.11615170786986552 0.0381762502754693 0.22263612718720172 0.24336045934786105 0.38598629534869333 0.3204142278104345 0.2601792060240761 0.23247216773041696 0.3757999653852862 0.35928993545506094 0.2509779533453429 0.3643402858148399 0.39632173362710965 0.575687752657507 0.5008732988612786 0.6623919444480774 0.7018043580937466 0.5272871798689759 0.667728311792801 0.6078956020384904 0.4345651922346484 0.5996588130635248 0.7210772003637764 0.42722139243296087 0.35439395239148813 0.7147388704593604 0.4106699658179282 0.3497431011883906 0.5418106542233493 0.560760510938887 0.35225313431311434 0.37402953664800237 0.2297375025660875 0.3577860386183956 0.326537381451767 0.2555420237036465 0.23473207264267626 0.4151883693106389 0.44186282463665766 0.3187782544457513 0.4179154540744977 0.375950547896465 0.44699979421403335 0.4611164668526019 0.4662246206335853 0.4532316308167651 0.4664393408109246 0.464904870758072 0.45197274569258394 0.4762751032293594 0.47350284112275876 0.44706448046952557 0.47657503153322334 0.373882258337215 0.565023074734028 0.5979973624582261 0.316834244300302 0.6552939749607231 0.261275255319136 0.15883580138739917 0.26022639822217686 0.4027260797555509 0.1279960066767012 0.2484533679828127 0.21901575109033694 0.2563760888394433 0.24232663031610985 0.14044590850980773 0.2685226689756044 0.1409934473703218 0.18220477764168244 0.1918002295199586 0.2773909652564597 0.23281209116981214 0.2767245930113652 0.2299542103399049 0.22849866529477975 0.26413416634955944 0.26675858311227507 0.23999526474359578 0.22339394510145336 0.273231882593264 0.2199325471167417 0.1666814158170059 0.16444459392484748 0.18438535164865283 0.1461261538722861 0.1846408210464268 0.14993599666356897 0.210452615303554 0.198791324446648 0.14486400037544028 0.1383751628513299 0.7268245365843252 0.23599918983685594 0.3456479528893672 0.45553879410243736 0.7757457055074936 0.34993025627844104 0.7334034313736815 0.4705267271181671 0.23938354773119475 0.7861792156769964 0.7040039608388684 0.13846996297533598 0.39847358183491394 0.6373149701654086 0.747177759226148 0.17886037238004648 0.2443252523281113 0.6737993923336767 0.22429981437337299 0.0974883155182058 0.20607801190196628 0.16078471238645148 0.2585694587915902 0.2824300654698769 0.17677589808844632 0.2618001404607727 0.22557691478424613 0.12064122698553205 0.22059029346765746 0.2940980062641696 0.18890017166854678 0.16282857878272833 0.29182893904514007 0.1829749042674011 0.1611636143260534 0.2299221351040896 0.23670601971201685 0.16206218444907913 0.16985794791226932 0.11820264920743995 0.2508346492459872 0.21846745453760127 0.14493083645601043 0.1233759986186354 0.3102916814097617 0.3379209419144153 0.21043059160196745 0.3131163814622285 0.2696493524010856 0.3432417879794276 0.5294488406227182 0.5968283346691314 0.4254433064292403 0.5996606176290806 0.5794200727622666 0.4088378856908003 0.7293999958330161 0.6928322599903348 0.34409503699143845 0.7333562231180648 praat-6.0.04/dwtest/test_Polygon_simplify.praat000066400000000000000000000016271261542461700216730ustar00rootroot00000000000000# test_Polygon_simplify.praat printline test_Polygon_simplify for j to 10 m = Create simple Matrix... ps 2 100 randomUniform (0,1) p1x = Get value in cell... 1 1 p1y = Get value in cell... 2 1 p2x = Get value in cell... 1 10 p2y = Get value in cell... 2 10 for i from 2 to 99 if ( i mod 10) =0 p1x = Get value in cell... 1 i p1y = Get value in cell... 2 i p2x = Get value in cell... 1 i+10 p2y = Get value in cell... 2 i+10 elsif ( i mod 10) >0 # 9 points on the edge from p(i) to point(i+10) af = randomUniform (0,1) xn = p1x +af*(p2x-p1x) yn = p1y + af*(p2y-p1y) Set value... 1 i xn Set value... 2 i yn endif endfor p = To Polygon for k to 10 select p p3 = Circular permutation... randomUniform (1, 100) p4 = Simplify np = Get number of points assert np = 11 plus p3 Remove endfor select m plus p Remove endfor printline test_Polygon_simplify OK praat-6.0.04/dwtest/test_Procrustes.praat000066400000000000000000000072331261542461700205000ustar00rootroot00000000000000# test_Procrustes.praat # djmw 20040117, 20070820 printline ----- test_Procrustes.praat ----- call test_orthogional_procrustes_gvl_12_4_3 call test_procrustes_bg_19_4 call test_procrustes_random_configurations 12 printline printline ----- succeeded: test_Procrustes.praat (end) ----- procedure test_procrustes_bg_19_4 # example Borg&Groenen section 19.4 printline test example in Borg & Groenen section 19.4 nr = 4 nc = 2 s = 0.5 t1 = 1 t2 = 2 alpha = 30 eps = 2.3e-16 Create Configuration... X nr nc 0 Set value... 1 1 1 Set value... 1 2 2 Set value... 2 1 -1 Set value... 2 2 2 Set value... 3 1 -1 Set value... 3 2 -2 Set value... 4 1 1 Set value... 4 2 -2 for i to 4 Set row label (index)... i x_'i' endfor Copy... Y ! Horizontal reflection Invert dimension... 1 Rotate... 1 2 alpha Formula... 0.5*self + (if col=1 then t1 else t2 fi) plus Configuration X To Procrustes... 0 Rename... X_Y plus Configuration Y To Configuration Rename... Z Formula... self-Configuration_X[] for i to 4 for j to 2 assert Configuration_Z[i,j] < nr*nc*eps; Configuration_Z['i','j'] < 'nr'*'nc'*'eps' endfor endfor select Procrustes X_Y Invert Rename... X_Yi for i to 2 tp = Get translation element... i assert t'i' - tp < nr*nc*eps; translation['i'] endfor sp = Get scale assert s - tp < nr*nc*eps; scale select Configuration X plus Configuration Y plus Configuration Z plus Procrustes X_Y plus Procrustes X_Yi Remove endproc procedure test_procrustes_random_configurations numconf printline 'numconf' randomly generated configurations of dimension 2^1 x 2 .. 2^12 x 2 nr = 2 print Configuration: for k to numconf print 'k' Create Configuration... X nr nc randomUniform(-1,1) Copy... Y Invert dimension... 1 alpha = randomUniform (0,90) Rotate... 1 2 alpha t1 = randomUniform (0,2) t2 = randomUniform (0,2) scale = randomUniform(0.5,2) Formula... scale*self + (if col=1 then t1 else t2 fi) plus Configuration X To Procrustes... 0 Rename... X_Y plus Configuration Y To Configuration Rename... Z Formula... self-Configuration_X[] .eps = 10 * nr * nc * eps for i to nr for j to 2 assert Configuration_Z[i,j] < .eps; Configuration_Z['i','j'] < '.eps' endfor endfor select Procrustes X_Y Invert 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 # printline o.k.: nr='nr', nc='nc', alpha='alpha' degrees, scale='scale', t=('t1', 't2') nr *= 2 select Configuration X plus Configuration Y plus Configuration Z plus Procrustes X_Y plus Procrustes X_Yi Remove endfor endproc procedure test_orthogional_procrustes_gvl_12_4_3 printline test orthognal Procrustes transform (example 12.4.1 Golub & van Loan) Create Configuration... a 4 2 0 Set value... 1 1 1 Set value... 2 1 3 Set value... 3 1 5 Set value... 4 1 7 Set value... 1 2 2 Set value... 2 2 4 Set value... 3 2 6 Set value... 4 2 8 Create Configuration... b 4 2 0 Set value... 1 1 1.2 Set value... 2 1 2.9 Set value... 3 1 5.2 Set value... 4 1 6.8 Set value... 1 2 2.1 Set value... 2 2 4.3 Set value... 3 2 6.1 Set value... 4 2 8.1 plus Configuration a To Procrustes... y t2 = Get translation element... 2 assert t2 = 0 s = Get scale assert s = 1; eps = 5e-5 r11 = Get transformation element... 1 1 r22 = Get transformation element... 2 2 assert r11-r22 < eps assert r11-0.9999 < eps r12 = Get transformation element... 1 2 r21 = Get transformation element... 2 1 assert r12+0.0126 < eps assert r21-0.0126 < eps plus Configuration a plus Configuration b Remove endproc praat-6.0.04/dwtest/test_Sound_draw_where.praat000066400000000000000000000045331261542461700216260ustar00rootroot00000000000000# Sound_drawWhere_test.praat # djmw 20091031,20100912, 20110524 Erase all printline Draw where... Begin tests # maximally steep printline Top: sawtooth in black with parts above 0.5 in blue s = Create Sound from formula... s Mono 0 1 44100 20*((x mod 0.1) - 0.05) ymin = -1.1 ymax = 1.1 Select outer viewport... 0 6 0 3 Blue Draw where... 0 0.4 ymin ymax n Curve self>0.5 Black Draw where... 0 0.4 ymin ymax n Curve self<=0.5 One mark left... 0.5 y y y Draw inner box Text top... n sawtooth in black with parts above 0.5 in blue Remove # corner cases printline Second figure, interpolation between sample points: three sample points, parts above 0.5 in blue s =Create Sound from formula... s Mono 0 0.0003 10000 0 Select outer viewport... 0 6 3 6 Blue Formula... if col=1 then -1 else if col=2 then 1 else -1 fi fi Draw where... 0 0 ymin ymax n Curve self>0.5 Black Draw where... 0 0 ymin ymax n Curve self<=0.5 One mark left... 0.5 y y y Formula... if col=1 then 1 else if col=2 then -1 else 1 fi fi Blue Draw where... 0 0 ymin ymax n Curve self>0.5 Black Draw where... 0 0 ymin ymax n Curve self<=0.5 One mark left... 0.5 y y y # Compatibility with Draw... : only draw in blue Formula... 0.6 Blue Draw where... 0 0 ymin ymax n Curve 1 Black Draw where... 0 0 ymin ymax n Curve 0 Draw inner box Text top... n (2x) three sample points, parts above 0.5 in blue + blue straight Remove # random, selection on amplitudes printline Random amplitudes draw parts > 0.5 in blue Select outer viewport... 0 6 6 9 s = Create Sound from formula... s Mono 0 0.01 10000 randomUniform(-1,1) Blue Draw where... 0 0 ymin ymax n Curve self>0.5 Black Draw where... 0 0 ymin ymax n Curve self<=0.5 One mark left... 0.5 y y y Draw inner box Text top... n Random amplitudes: parts > 0.5 in blue # complementary selections in amplitude and time domain printline Random amplitudes: parts > 0.5 in blue only in the first half of every 0.001 s Select outer viewport... 0 6 9 12 Blue Draw where... 0.001 0.01 ymin ymax n Curve (self>0.5 and x mod 0.001 < 0.0005) Black Draw where... 0.001 0.01 ymin ymax n Curve not (self>0.5 and x mod 0.001 < 0.0005) One mark left... 0.5 y y y Marks bottom every... 1 0.0005 n y y Marks bottom every... 1 0.001 y y y Draw inner box Text top... n Random amplitudes: parts > 0.5 blue only in the first half of every 0.001 s Remove printline Draw where... End tests praat-6.0.04/dwtest/test_Sound_paint_where.praat000066400000000000000000000021311261542461700217740ustar00rootroot00000000000000# test_Sound_paint_where.praat # djmw 20110524 Erase all s1 = Create Sound from formula... s Mono 0 1 10000 0.5*sin (2*pi*5*x) s2 = Create Sound from formula... 1odx Mono 0 20 100 1/x s3 = Create Sound from formula... line Mono 0 1 10000 x/2 Select outer viewport... 0 6 0 3 select s1 Paint where... Red 0 0 -1 1 -1 y 1 Paint where... Green 0 0 -1 1 1 n 1 Text top... n Paint where: green above, red below the sin of 5 Hz Select outer viewport... 0 6 3 6 Paint where... Red 0 0 -1 1 0 n self>0 Paint where... Green 0 0 -1 1 0 y self<0 Text top... n Paint where: green is positive area , red is negative area of sin of 5 Hz select s2 Select outer viewport... 0 6 6 9 Draw... 0 20 0 1.5 y Curve Paint where... Grey 0 20 0 1.5 0 y (x>=1 and x<2) or (x>=4 and x<8) One mark bottom... 1 y y n One mark bottom... 2 y y n One mark bottom... 4 y y n One mark bottom... 8 y y n Text top... n Paint where: grey intervals (1,2) and (4,8) Remove select s3 plus s1 Select outer viewport... 0 6 9 12 Paint enclosed... Grey 0 0 -1 1 yes Text top... n Paint enclosed: between sine and straight line removeObject: s1, s3 praat-6.0.04/dwtest/test_SpeechSynthesizer.praat000066400000000000000000000013541261542461700220040ustar00rootroot00000000000000# test_SpeechSynthesizer.praat # djmw 20120130, 20120522 printline SpeechSynthesizer test... variantslist = Create copy from FilesInMemory... variants_names nvariants = Get number of strings voiceslist = Create copy from FilesInMemory... voices_names nvoices = Get number of strings for ivoice to nvoices select voiceslist voice$ = Get string... ivoice printline 'tab$' 'voice$' for ivariant to nvariants select variantslist variant$ = Get string... ivariant printline 'tab$''tab$' 'variant$' # some voices have spaces! ss = Create SpeechSynthesizer... "'voice$'" 'variant$' sound = To Sound... a e u Remove select ss Remove endfor endfor select variantslist plus voiceslist Remove printline SpeechSynthesizer test OK praat-6.0.04/dwtest/test_TableOfReal_and_Permutation.praat000066400000000000000000000020741261542461700236560ustar00rootroot00000000000000# test_TableOfReal_and_Permutation.praat # djmw 20050713, 20070829 nrows = 30 Create TableOfReal... test nrows 2 testtab = selected ("TableOfReal") Formula... row*col labels$ = "aabbccddeeffgghhiijjk" printline test: TableOfReal_and_Permutation.praat for itry to 10 select testtab for i to nrows randomIndex = randomInteger (1,20) label$ = mid$ (labels$, randomIndex, 1) Set row label (index)... i 'label$' endfor To Permutation (sort row labels) pid = selected ("Permutation") plus testtab Permute rows testtabp = selected ("TableOfReal") label$ = Get row label... 1 for i from 2 to nrows lab$ = Get row label... i assert lab$ >= label$ ; i='i' 'lab$' > 'label$' label$ = lab$ endfor select pid Invert pidi = selected ("Permutation") plus testtabp Permute rows testtabpi = selected ("TableOfReal") Formula... self - TableOfReal_test[] stdev = Get column stdev (index)... 1 assert stdev = 0 select pid plus testtabp plus pidi plus testtabpi Remove print . endfor printline o.k. select testtab Remove praat-6.0.04/dwtest/test_TableOfReal_extensions.praat000066400000000000000000000016431261542461700227250ustar00rootroot00000000000000# test_TableOfReal_extensions.praat eps = 2.3e-16 printline TableOfReal_extensions test call means_by_row_labels printline TableOfReal_extensions test... OK procedure means_by_row_labels printline 'tab$'means_by_row_labels .nrows = 100 .ncols = 3 .tab1 = Create TableOfReal... tab .nrows .ncols for .i to .nrows if (.i mod 2) = 0 Set row label (index)... .i even else Set row label (index)... .i odd endif endfor Formula... if (row mod 2) = 0 then col else 2*col fi .tabm = To TableOfReal (means by row labels)... no .nrowsm = Get number of rows .ncolsm = Get number of columns assert .nrowsm = 2 assert .ncolsm = .ncols for .i to .nrowsm .rowLabel$ = Get row label... .i for .j to .ncols if .rowLabel$ = "even" .dif = abs (Object_'.tabm'[.i,.j] - .j) else .dif = abs(Object_'.tabm'[.i,.j] - .j*2) endif assert .dif <= eps endfor endfor removeObject: .tab1, .tabm endproc praat-6.0.04/dwtest/test_Table_extractMahalanobisWhere.praat000066400000000000000000000017071261542461700242420ustar00rootroot00000000000000# test_Table_extractMahalanobisWhere.praat # djmw 20140509 appendInfoLine: "Table_extractMahalanobisWhere test" t = Create Table with column names: "t", 1000, "f x y" Formula (column range): "f", "f", "randomInteger (1,1)" Formula (column range): "x", "y", "randomGauss (self[1],0.1)" tm = Extract rows where (mahalanobis): "x y", "greater than", 3, "f", "1" tm1 = Extract rows where: "self$[""f""]=""1""" nm1 = Get number of rows selectObject: t t1 = Extract rows where: "self$[""f""]=""1""" t1m1 = Extract rows where (mahalanobis): "x y", "greater than", 3, "", "1" n1m1 = Get number of rows assert nm1 = n1m1 # only for interactive use ; @draw procedure draw Erase all selectObject: t Select outer viewport: 0, 6, 0, 6 Scatter plot: "x", 0, 4, "y", 0, 4, "f", 10, "yes" Colour: "Red" Draw ellipses: "x", 0, 4, "y", 0, 4, "f", 3, 12, "no" Colour: "Black" endproc removeObject: t, tm, tm1, t1, t1m1 appendInfoLine: "Table_extractMahalanobisWhere test OK" praat-6.0.04/dwtest/test_Table_getMedianAbsoluteDeviation.praat000066400000000000000000000007521261542461700246740ustar00rootroot00000000000000# test_Table_getMedianAbsoluteDeviation.praat # djmw 20120405 # create dataset with median 2 tab = Create Table with column names... table 7 c1 Set numeric value... 1 c1 1 Set numeric value... 2 c1 1 Set numeric value... 3 c1 2 Set numeric value... 4 c1 2 Set numeric value... 5 c1 4 Set numeric value... 6 c1 6 Set numeric value... 7 c1 9 mad = Get median absolute deviation... c1 assert abs (mad -1.4826) < 1.1e-16 Remove printline test_Table_getMedianAbsoluteDeviation ok praat-6.0.04/dwtest/test_TextGrid_extensions.praat000066400000000000000000000011631261542461700223340ustar00rootroot00000000000000# test_TextGrid_extensions.praat # djmw 20110523, 20140904 appendInfoLine: "test_TextGrid_extensions" s = Read Strings from raw text file: "TIMIT_train_dr1_fcjf0_sa1.phn" ns = Get number of strings tg = Read from file: "TIMIT_train_dr1_fcjf0_sa1.phn" ntiers = Get number of tiers assert ntiers = 2 nints = Get number of intervals: 1 assert nints = ns for i to ns selectObject: s string$ = Get string: i slabel$ = replace_regex$ (string$, "[0-9\s]", "", 0) selectObject: tg tglabel$ = Get label of interval: 1, i assert slabel$ = tglabel$ endfor removeObject: s, tg appendInfoLine: "test_TextGrid_extensions OK" praat-6.0.04/dwtest/test_angle_between_planes.praat000066400000000000000000000020541261542461700224640ustar00rootroot00000000000000# test_angle_between_planes # djmw 20041021, 20070820 printline ----- test_angle_between_planes ----- for i to 200 hoek = randomInteger (0,90) nrow = randomInteger (10,1000) call test hoek nrow 3 endfor printline ----- succeeded: test_angle_between_planes ----- procedure test degrees nrow ncol idt1 = Create TableOfReal... t nrow ncol Formula... if col=1 then randomGauss(0,10) else self endif Formula... if col=2 then randomGauss(0,5) else self endif Formula... if col=3 then randomGauss(0,2.5) else self endif # Centering is very important Centre columns c = To Configuration Rotate (pc) idt2 = To TableOfReal pc1 = To PCA select c # The rotation is in the pc-coordinates frame Rotate... 1 3 degrees idt3 = To TableOfReal pc2 = To PCA plus pc1 degrees_found = Get angle between pc1-pc2 planes # assert abs(degrees-degrees_found) < 2e-6; 'nrow' 'degrees' 'degrees_found' printline 'nrow' 'degrees' 'degrees_found' plus idt1 plus idt2 plus idt3 plus pc1 plus pc2 plus c Remove endproc praat-6.0.04/dwtest/test_gsl.praat000066400000000000000000000151271261542461700171150ustar00rootroot00000000000000# test_gsl.praat # djmw 20071017, 20080317, 20120223 debug = 0 eps = 2.2204460492503131e-16 tol0 = 2.0*eps tol_2= 4.0*eps tol1 = 16.0*eps tol2 = 256.0*eps tol3 = 2048.0*eps tol4 = 16384.0*eps tol5 = 131072.0*eps tol6 = 1048576.0*eps sqrt_tol0 = sqrt(2.0*eps) call test_besselI call test_besselK call test_erfc call test_erf call test_lnGamma call test_incompleteBeta call test_incompleteGammaP call test_sincpi procedure func_1arg .func$ .arg .r .tol assert$ = "" .res = '.func$' (.arg) .denom = .res+.r if .denom = 0 .denom = 1 endif .z = abs ((.res-.r) / .denom) if .z > .tol assert$ = "!!Assertion failed: " endif if debug <> 0 or assert$ <> "" .neps = .z / eps printline 'assert$' '.func$'('.arg')='.res' ('.r'), n*eps='.neps:2' endif endproc procedure func_1argzero .func$ .arg .tol assert$ = "" .res = '.func$' (.arg) .z = abs (.res) if .z > .tol assert$ = "!!Assertion failed: " endif if debug <> 0 or assert$ <> "" .neps = .z / eps printline 'assert$' '.func$'('.arg')=0, n*eps='.neps:2' endif endproc procedure func_2args .func$ .arg1 .arg2 .r .tol .res = '.func$' (.arg1,.arg2) .denom = .res+.r if .denom <> 0 if debug = 1 .z = abs((.res-.r)/(.res+.r)) .neps = .z/eps printline '.neps:2' '.z' '.func$'('.arg1','.arg2')='.res' ('.r') endif assert abs((.res-.r)/(.res+.r)) < .tol; '.res'='.func$' ('.arg1', '.arg2') ('.r') else if debug = 1 .z = abs(.res-.r) .neps = .z / eps printline '.neps:2' '.z' '.func$'('.arg1','.arg2')='.res' ('.r') endif assert abs(.res-.r) < .tol; '.res'='.func$' ('.arg1', '.arg2') ('.r') endif endproc procedure func_3args .func$ .arg1 .arg2 .arg3 .r .tol .res = '.func$' (.arg1,.arg2, .arg3) .denom = .res+.r if .denom <> 0 if debug = 1 .z = abs((.res-.r)/(.res+.r)) .neps = .z/eps printline '.neps:2' '.z' '.func$'('.arg1','.arg2', '.arg3')='.res' ('.r') endif assert abs((.res-.r)/(.res+.r)) < .tol; '.res'='.func$' ('.arg1', '.arg2', '.arg3') ('.r') else if debug = 1 .z = abs(.res-.r) .neps = .z / eps printline '.neps:2' '.z' '.func$'('.arg1','.arg2', '.arg3')='.res' ('.r') endif assert abs(.res-.r) < .tol; '.res'='.func$' ('.arg1', '.arg2', '.arg3') ('.r') endif endproc procedure test_besselI printline test_besselI: start call func_2args besselI 4 0.1 2.6054690212996573677e-07 tol0 call func_2args besselI 5 2.0 0.009825679323131702321 tol0 call func_2args besselI 100 100.0 4.641534941616199114e+21 tol2 printline test_besselI: success endproc procedure test_besselK printline test_besselK: start call func_2args besselK 4 0.1 479600.2497925682849 tol_2 call func_2args besselK 5 2.0 9.431049100596467443 tol0 call func_2args besselK 100 100.0 7.617129630494085416e-25 tol2 printline test_besselK: success endproc procedure test_erfc printline test_erfc: start call func_1arg erfc -10.0 2.0 tol0 call func_1arg erfc -5.0000002 1.9999999999984625433 tol0 call func_1arg erfc -5.0 1.9999999999984625402 tol0 call func_1arg erfc -1.0 1.8427007929497148693 tol0 call func_1arg erfc -0.5 1.5204998778130465377 tol0 call func_1arg erfc 1.0 0.15729920705028513066 tol0 call func_1arg erfc 3.0 0.000022090496998585441373 tol1 call func_1arg erfc 7.0 4.183825607779414399e-23 tol2 call func_1arg erfc 10.0 2.0884875837625447570e-45 tol2 printline test_erfc: success endproc procedure test_erf printline test_erf: start call func_1arg erf -10.0 -1.0000000000000000000 tol0 call func_1arg erf 0.5 0.5204998778130465377 tol0 call func_1arg erf 1.0 0.8427007929497148693 tol0 call func_1arg erf 10.0 1.0000000000000000000 tol0 printline test_erf: success endproc procedure test_lnGamma printline test_lnGamma: start call func_1arg lnGamma -0.1 2.368961332728788655 tol0 call func_1arg lnGamma -1.0/256.0 5.547444766967471595 tol0 call func_1arg lnGamma 1.0e-08 18.420680738180208905 tol0 call func_1arg lnGamma 0.1 2.252712651734205 tol0 call func_1arg lnGamma 1.0+1.0/256.0 -0.0022422226599611501448 tol0 call func_1arg lnGamma 2.0+1.0/256.0 0.0016564177556961728692 tol0 call func_1arg lnGamma 100.0 359.1342053695753 tol0 call func_1arg lnGamma -1.0-1.0/65536.0 11.090348438090047844 tol0 call func_1arg lnGamma -1.0-1.0/268435456.0 19.408121054103474300 tol0 call func_1arg lnGamma -100.5 -364.9009683094273518 tol0 call func_1arg lnGamma -100-1.0/65536.0 -352.6490910117097874 tol0 call func_1arg lnGamma -1.5 ln(4*sqrt(pi)/3) tol1 call func_1arg lnGamma 0.5 0.5*ln(pi) tol0 call func_1arg lnGamma 1 0 tol0 call func_1arg lnGamma 1.5 ln(sqrt(pi)/2) tol2 call func_1arg lnGamma 2 0 tol0 call func_1arg lnGamma 2.5 ln(3*sqrt(pi)/4) tol1 call func_1arg lnGamma 3 ln(2) tol_2 call func_1arg lnGamma 3.5 ln(15*sqrt(pi)/8) tol_2 call func_1arg lnGamma 4 ln(6) tol_2 printline test_lnGamma: success endproc # incompleteBeta # Limiting values: $I_0(a,b)=0 I_1(a,b)=1$ # Symmetry: $I_x(a,b) = 1 - I_{1-x}(b,a)$ procedure test_incompleteBeta printline test_incompleteBeta: start printline incompleteBeta (a,b,0) = 0 and incompleteBeta (a,b,1) = 1 for .i to 20 .a = randomUniform (0, 50) .b = randomUniform (0, 50) call func_3args incompleteBeta .a .b 0 0 tol0 call func_3args incompleteBeta .a .b 1 1 tol0 endfor printline incompleteBeta(i, 1, 0.1)=10^(-i) & incompleteBeta(a,b,x)=1-incompleteBeta(b,a,1-x) for .i to 310 .a = .i .b = 1 .x = 0.1 call func_3args incompleteBeta .a .b .x 10^(-.i) tol1*.i # if i > 16 then 1-10^(-.i) equals 1! call func_3args incompleteBeta .b .a 1-.x 1-10^(-.i) tol1*.i endfor printline test_incompleteBeta: success endproc procedure test_incompleteGammaP printline test_incompleteGammaP: start printline incompleteGammaP(a,0)=0 &incompleteGammaP(a,inf)=1 for .i to 20 .a = randomUniform (0, 100) call func_2args incompleteGammaP .a 0 0 tol0 call func_2args incompleteGammaP .a 10^200 1 tol0 endfor printline incompleteGammaP(1,x)=1-exp(-x) emax = round(19*ln(10)) for .i to 100 .x = randomUniform (0, emax) call func_2args incompleteGammaP 1 .x 1-exp(-.x) tol1 endfor printline incompleteGammaP(2,x)=(1-(1+x)*exp(-x))/2 for .i to 100 .x = randomUniform (0, emax) call func_2args incompleteGammaP 2 .x 1-(1+.x)*exp(-.x) tol3 endfor printline incompleteGammaP(3,x)=(1-(1+x+0.5*x^2)*exp(-x))/2 for .i to 100 .x = randomUniform (0, emax) call func_2args incompleteGammaP 3 .x 1-(1+.x+0.5*.x^2)*exp(-.x) 2*tol4 endfor printline test_incompleteGammaP: succes endproc procedure test_sincpi printline test_sincpi: start call func_1arg sincpi 0 1 tol0 for .i to 200 .arg = .i call func_1argzero sincpi .arg tol0 .arg = -.arg call func_1argzero sincpi .arg tol0 endfor printline test_sincpi: succes endproc praat-6.0.04/dwtest/test_henzeZirklerMultivariateNormalityTest.praat000066400000000000000000000016431261542461700261300ustar00rootroot00000000000000# henzeZirklerMultivariateNormalityTest.praat # djmw 20090707,20110526 printline test_henzeZirklerMultivariateNormalityTest ir = Create iris data set ir50 = Extract row ranges... 1:50 report$ = Report multivariate normality... 0 tol = 1e-10 stat = extractNumber (report$, "statistic:") assert abs(stat - 0.9583666347568522) double djmw 20110304 Thing_new */ #include "Activation.h" Thing_implement (Activation, Matrix, 2); int _Activation_checkElements (Activation me) { for (long i = 1; i <= my ny; i++) { for (long j = 1; j <= my nx; j++) { if (my z[i][j] < 0.0 || my z[i][j] > 1) { return 0; } } } return 1; } void Activation_init (Activation me, long ny, long nx) { Matrix_init (me, 1.0, nx, nx, 1.0, 1.0, 1.0, ny, ny, 1.0, 1.0); } autoActivation Activation_create (long ny, long nx) { try { autoActivation me = Thing_new (Activation); Activation_init (me.peek(), ny, nx); return me; } catch (MelderError) { Melder_throw (U"Activation not created."); } } autoActivation Matrix_to_Activation (Matrix me) { try { autoActivation thee = Activation_create (my ny, my nx); NUMmatrix_copyElements (my z, thy z, 1, my ny, 1, my nx); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Activation."); } } autoMatrix Activation_to_Matrix (Activation me) { try { autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, my ymin, my ymax, my ny, my dy, my y1); NUMmatrix_copyElements (my z, thy z, 1, my ny, 1, my nx); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Matrix."); } } /* End of file Activation.cpp */ praat-6.0.04/dwtools/Activation.h000066400000000000000000000027401261542461700166700ustar00rootroot00000000000000#ifndef _Activation_h_ #define _Activation_h_ /* Activation.h * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free oftware; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020315 GPL header. djmw 20110505 Latest modification. */ #include "Matrix.h" Thing_define (Activation, Matrix) { }; /* Attributes: xmin :1 xmax :#units nx :#units dx :1 x1 :1 ymin :1 ymax :#patterns ny :#patterns dy :1 y1 :1 z[iy][ix] :the activities */ void Activation_init (Activation me, long ny, long nx); autoActivation Activation_create (long ny, long nx); autoActivation Matrix_to_Activation (Matrix me); autoMatrix Activation_to_Matrix (Activation me); int _Activation_checkElements (Activation me); /* Return 1 if all elements are in interval [0,1] else 0. */ #endif /* _Activation_h_ */ praat-6.0.04/dwtools/AffineTransform.cpp000066400000000000000000000072551261542461700202140ustar00rootroot00000000000000/* AffineTransform.cpp * * Copyright (C) 1993-2013, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 2001 djmw 20020315 GPL header djmw 20041027 Added AffineTransform_extractMatrix djmw 20050726 Added AffineTransform_extractTranslationVector djmw 20061021 printf expects %ld for 'long int' djmw 20071012 Added: o_CAN_WRITE_AS_ENCODING.h djmw 20110304 Thing_new */ #include "AffineTransform.h" #include "NUM2.h" #include "oo_DESTROY.h" #include "AffineTransform_def.h" #include "oo_COPY.h" #include "AffineTransform_def.h" #include "oo_EQUAL.h" #include "AffineTransform_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "AffineTransform_def.h" #include "oo_WRITE_TEXT.h" #include "AffineTransform_def.h" #include "oo_WRITE_BINARY.h" #include "AffineTransform_def.h" #include "oo_READ_TEXT.h" #include "AffineTransform_def.h" #include "oo_READ_BINARY.h" #include "AffineTransform_def.h" #include "oo_DESCRIPTION.h" #include "AffineTransform_def.h" void structAffineTransform :: v_transform (double **in, long nrows, double **out) { for (long i = 1; i <= nrows; i++) { for (long j = 1; j <= n; j++) { double tmp = 0; for (long k = 1; k <= n; k++) { tmp += in[i][k] * r[k][j]; } out[i][j] = tmp + t[j]; } } } Any structAffineTransform :: v_invert () { autoAffineTransform thee = Data_copy (this); double tolerance = 0.000001; NUMpseudoInverse (r, n, n, thy r, tolerance); for (long i = 1; i <= n; i++) { thy t[i] = 0.0; for (long j = 1; j <= thy n; j++) { thy t[i] -= thy r[i][j] * t[j]; } } return thee.transfer(); } Thing_implement (AffineTransform, Daata, 0); void AffineTransform_init (AffineTransform me, long n) { if (n < 1) { Melder_throw (U"Dimensionality must be at least 1."); } my n = n; my r = NUMmatrix (1, n, 1, n); my t = NUMvector (1, n); } autoAffineTransform AffineTransform_create (long n) { try { autoAffineTransform me = Thing_new (AffineTransform); AffineTransform_init (me.peek(), n); return me; } catch (MelderError) { Melder_throw (U"AffineTransform not created."); } } Any AffineTransform_invert (AffineTransform me) { AffineTransform thee = (AffineTransform) my v_invert (); return thee; } autoTableOfReal AffineTransform_extractMatrix (AffineTransform me) { try { autoTableOfReal thee = TableOfReal_create (my n, my n); NUMmatrix_copyElements (my r, thy data, 1, my n, 1, my n); for (long i = 1; i <= my n; i++) { char32 label[40]; Melder_sprint (label,40, i); TableOfReal_setRowLabel (thee.peek(), i, label); TableOfReal_setColumnLabel (thee.peek(), i, label); } return thee; } catch (MelderError) { Melder_throw (me, U": transformation matrix not extracted."); } } autoTableOfReal AffineTransform_extractTranslationVector (AffineTransform me) { try { autoTableOfReal thee = TableOfReal_create (1, my n); for (long i = 1; i <= my n; i++) { thy data[1][i] = my t[i]; } return thee; } catch (MelderError) { Melder_throw (me, U": translation vector not extracted."); } } /* End of file AffineTransform.cpp */ praat-6.0.04/dwtools/AffineTransform.h000066400000000000000000000025261261542461700176550ustar00rootroot00000000000000#ifndef _AffineTransform_h_ #define _AffineTransform_h_ /* AffineTransform.h * * Copyright (C) 2001-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Data.h" #include "TableOfReal.h" #include "AffineTransform_def.h" oo_CLASS_CREATE (AffineTransform, Daata); void AffineTransform_init (AffineTransform me, long n); autoAffineTransform AffineTransform_create (long n); Any AffineTransform_invert (AffineTransform me); /* Get inverse transform for y = A x + t: x = A^(-1)y - A^(-1) t */ autoTableOfReal AffineTransform_extractMatrix (AffineTransform me); autoTableOfReal AffineTransform_extractTranslationVector (AffineTransform me); #endif /* _AffineTransform_h_ */ praat-6.0.04/dwtools/AffineTransform_def.h000066400000000000000000000022041261542461700204640ustar00rootroot00000000000000/* AffineTransform_def.h * * Copyright (C) 1993-2008,2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT AffineTransform oo_DEFINE_CLASS (AffineTransform, Daata) oo_LONG (n) oo_DOUBLE_VECTOR (t, n) oo_DOUBLE_MATRIX (r, n, n) #if oo_DECLARING // new methods: virtual void v_transform (double **in, long nrows, double **out); virtual Any v_invert (); #endif oo_END_CLASS(AffineTransform) #undef ooSTRUCT /* End of file AffineTransform_def.h */ praat-6.0.04/dwtools/CC.cpp000066400000000000000000000145631261542461700154150ustar00rootroot00000000000000/* CC.cpp * * Copyright (C) 1993-2012, 2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20011016 removed some causes for compiler warnings djmw 20020315 GPL header djmw 20061212 Changed info to Melder_writeLine format. djmw 20071012 Added: o_CAN_WRITE_AS_ENCODING.h djmw 20080122 float -> double djmw 20080513 CC_getValue */ #include "CC.h" #include "NUM2.h" #include "oo_DESTROY.h" #include "CC_def.h" #include "oo_COPY.h" #include "CC_def.h" #include "oo_EQUAL.h" #include "CC_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "CC_def.h" #include "oo_WRITE_TEXT.h" #include "CC_def.h" #include "oo_WRITE_BINARY.h" #include "CC_def.h" #include "oo_READ_TEXT.h" #include "CC_def.h" #include "oo_READ_BINARY.h" #include "CC_def.h" #include "oo_DESCRIPTION.h" #include "CC_def.h" Thing_implement (CC, Sampled, 1); void structCC :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Time domain:", xmin, U" to ", xmax, U" seconds"); MelderInfo_writeLine (U"Number of frames: ", nx); MelderInfo_writeLine (U"Time step: ", dx, U" seconds"); MelderInfo_writeLine (U"First frame at: ", x1, U" seconds"); MelderInfo_writeLine (U"Number of coefficients: ", maximumNumberOfCoefficients); MelderInfo_writeLine (U"Minimum frequency: ", fmin, U" Hz"); MelderInfo_writeLine (U"Maximum frequency: ", fmax, U" Hz"); } void CC_Frame_init (CC_Frame me, long numberOfCoefficients) { my c = NUMvector (1, numberOfCoefficients); my numberOfCoefficients = numberOfCoefficients; } void CC_init (I, double tmin, double tmax, long nt, double dt, double t1, long maximumNumberOfCoefficients, double fmin, double fmax) { iam (CC); my fmin = fmin; my fmax = fmax; my maximumNumberOfCoefficients = maximumNumberOfCoefficients; Sampled_init (me, tmin, tmax, nt, dt, t1); my frame = NUMvector (1, nt); } Matrix CC_to_Matrix (I) { iam (CC); try { autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, 1, my maximumNumberOfCoefficients, my maximumNumberOfCoefficients, 1.0, 1.0); for (long i = 1; i <= my nx; i++) { CC_Frame cf = & my frame[i]; for (long j = 1; j <= cf -> numberOfCoefficients; j++) { thy z[j][i] = cf -> c[j]; } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not converted to Matrix."); } } void CC_paint (I, Graphics g, double xmin, double xmax, long cmin, long cmax, double minimum, double maximum, int garnish) { iam (CC); autoMatrix thee = CC_to_Matrix (me); Matrix_paintCells (thee.peek(), g, xmin, xmax, cmin, cmax, minimum, maximum); if (garnish) { Graphics_marksBottom (g, 2, true, true, false); Graphics_textBottom (g, true, U"Time (s)"); Graphics_marksLeft (g, 2, true, true, false); Graphics_textLeft (g, true, U"Coefficients"); } } void CC_drawC0 (I, Graphics g, double xmin, double xmax, double ymin, double ymax, int garnish) { iam (CC); (void) garnish; if (xmin >= xmax) { xmin = my xmin; xmax = my xmax; } long bframe, eframe; (void) Sampled_getWindowSamples (me, xmin, xmax, &bframe, &eframe); autoNUMvector c (bframe, eframe); for (long i = bframe; i <= eframe; i++) { CC_Frame cf = & my frame[i]; c[i] = cf -> c0; } if (ymin >= ymax) { NUMvector_extrema (c.peek(), bframe, eframe, &ymin, &ymax); if (ymax <= ymin) { ymin -= 1.0; ymax += 1.0; } } else { NUMvector_clip (c.peek(), bframe, eframe, ymin, ymax); } Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_function (g, c.peek(), bframe, eframe, xmin, xmax); Graphics_unsetInner (g); } void CC_getNumberOfCoefficients_extrema (I, long startframe, long endframe, long *min, long *max) { iam (CC); Melder_assert (startframe <= endframe); if (startframe == 0 && endframe == 0) { startframe = 1; endframe = my nx; } if (startframe < 1) { startframe = 1; } if (endframe > my nx) { endframe = my nx; } *min = my maximumNumberOfCoefficients; *max = 0; for (long i = startframe; i <= endframe; i++) { CC_Frame f = & my frame[i]; long nc = f -> numberOfCoefficients; if (nc < *min) { *min = nc; } else if (nc > *max) { *max = nc; } } } long CC_getMinimumNumberOfCoefficients (I, long startframe, long endframe) { iam (CC); long min, max; CC_getNumberOfCoefficients_extrema (me, startframe, endframe, &min, &max); return min; } long CC_getMaximumNumberOfCoefficients (I, long startframe, long endframe) { iam (CC); long min, max; CC_getNumberOfCoefficients_extrema (me, startframe, endframe, &min, &max); return max; } long CC_getNumberOfCoefficients (I, long iframe) { iam (CC); if (iframe < 1 || iframe > my nx) { return 0; } CC_Frame cf = & me -> frame[iframe]; return cf -> numberOfCoefficients; } double CC_getValueInFrame (I, long iframe, long index) { iam (CC); if (iframe < 1 || iframe > my nx) { return NUMundefined; } CC_Frame cf = & me -> frame[iframe]; return index > cf -> numberOfCoefficients ? NUMundefined : cf -> c[index]; } double CC_getValueAtTime (I, double t, long index) { iam (CC); long iframe = Sampled_xToNearestIndex (me, t); return CC_getValueInFrame (me, iframe, index); } double CC_getValue (I, double t, long index) { iam (CC); long iframe = Sampled_xToNearestIndex (me, t); if (iframe < 1 || iframe > my nx) { return NUMundefined; } CC_Frame cf = & me -> frame[iframe]; return index > cf -> numberOfCoefficients ? NUMundefined : cf -> c[index]; } double CC_getC0ValueInFrame (I, long iframe) { iam (CC); if (iframe < 1 || iframe > my nx) { return NUMundefined; } CC_Frame cf = & me -> frame[iframe]; return cf -> c0; } double CC_getC0ValueAtTime (I, double t) { iam (CC); long iframe = Sampled_xToNearestIndex (me, t); return CC_getC0ValueInFrame (me, iframe); } /* End of file CC.cpp */ praat-6.0.04/dwtools/CC.h000066400000000000000000000037731261542461700150630ustar00rootroot00000000000000#ifndef _CC_h_ #define _CC_h_ /* CC.h * * Copyright (C) 1993-2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20010219 Cepstral Coefficients (abstract) class. djmw 20020402 GPL header djmw 20030612 Include CC_def.h djmw 20110306 Latest modification. */ #include "Graphics.h" #include "Matrix.h" #include "CC_def.h" oo_CLASS_CREATE (CC, Sampled); void CC_init (I, double tmin, double tmax, long nt, double dt, double t1, long maximumNumberOfCoefficients, double fmin, double fmax); void CC_getNumberOfCoefficients_extrema (I, long startframe, long endframe, long *min, long *max); long CC_getMinimumNumberOfCoefficients (I, long startframe, long endframe); long CC_getMaximumNumberOfCoefficients (I, long startframe, long endframe); long CC_getNumberOfCoefficients (I, long iframe); double CC_getValueInFrame (I, long iframe, long index); double CC_getC0ValueInFrame (I, long iframe); void CC_paint (I, Graphics g, double xmin, double xmax, long cmin, long cmax, double minimum, double maximum, int garnish); void CC_drawC0 (I, Graphics g, double xmin, double xmax, double ymin, double ymax, int garnish); Matrix CC_to_Matrix (I); double CC_getValue (I, double t, long index); /******************* Frames ************************************************/ void CC_Frame_init (CC_Frame me, long numberOfCoefficients); #endif /* _CC_h_ */ praat-6.0.04/dwtools/CCA.cpp000066400000000000000000000245341261542461700155150ustar00rootroot00000000000000/* CCA.c * * Copyright (C) 1993-2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 2001 djmw 20020402 GPL header djme 20021008 removed SVD_sort djmw 20031023 Removed one argument from CCA_and_TableOfReal_scores djmw 20031106 Removed bug from CCA_and_TableOfReal_scores djmw 20031221 Removed bug: CCA_and_TableOfReal_scores (wrong dimensions to Eigen_project_into). djmw 20061212 Changed info to Melder_writeLine format. djmw 20071012 Added: o_CAN_WRITE_AS_ENCODING.h djmw 20081119 Check in TableOfReal_to_CCA if TableOfReal_areAllCellsDefined */ #include "CCA_and_Correlation.h" #include "NUM2.h" #include "NUMlapack.h" #include "SVD.h" #include "Strings_extensions.h" #include "TableOfReal_extensions.h" #include "Eigen_and_TableOfReal.h" #include "oo_DESTROY.h" #include "CCA_def.h" #include "oo_COPY.h" #include "CCA_def.h" #include "oo_EQUAL.h" #include "CCA_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "CCA_def.h" #include "oo_WRITE_TEXT.h" #include "CCA_def.h" #include "oo_WRITE_BINARY.h" #include "CCA_def.h" #include "oo_READ_TEXT.h" #include "CCA_def.h" #include "oo_READ_BINARY.h" #include "CCA_def.h" #include "oo_DESCRIPTION.h" #include "CCA_def.h" void structCCA :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Number of coefficients: ", numberOfCoefficients); MelderInfo_writeLine (U"ny: ", y -> dimension); MelderInfo_writeLine (U"nx: ", x -> dimension); } Thing_implement (CCA, Daata, 0); autoCCA CCA_create (long numberOfCoefficients, long ny, long nx) { try { autoCCA me = Thing_new (CCA); my numberOfCoefficients = numberOfCoefficients; my yLabels = Thing_new (Strings); my xLabels = Thing_new (Strings); my y = Eigen_create (numberOfCoefficients, ny); my x = Eigen_create (numberOfCoefficients, nx); return me; } catch (MelderError) { Melder_throw (U"CCA not created."); } } void CCA_drawEigenvector (CCA me, Graphics g, int x_or_y, long ivec, long first, long last, double ymin, double ymax, int weigh, double size_mm, const char32 *mark, int connect, int garnish) { Eigen e = my x.peek(); Strings labels = my xLabels.peek(); if (x_or_y == 1) { e = my y.peek(); labels = my yLabels.peek(); } Eigen_drawEigenvector (e, g, ivec, first, last, ymin, ymax, weigh, size_mm, mark, connect, labels -> strings, garnish); } double CCA_getEigenvectorElement (CCA me, int x_or_y, long ivec, long element) { Eigen e = x_or_y == 1 ? my y.peek() : my x.peek(); return Eigen_getEigenvectorElement (e, ivec, element); } autoCCA TableOfReal_to_CCA (TableOfReal me, long ny) { try { long n = my numberOfRows, nx = my numberOfColumns - ny; if (ny < 1 || ny > my numberOfColumns - 1) { Melder_throw (U"Dimension of first part not correct."); } if (ny > nx) { Melder_throw (U"The dimension of the dependent part (", ny, U") must be less than or equal to " "the dimension of the independent part (", nx, U")."); } if (n < ny) { Melder_throw (U"The number of observations must be larger then ", ny, U"."); } TableOfReal_areAllCellsDefined (me, 0, 0, 0, 0); // Use svd as (temporary) storage, and copy data autoSVD svdy = SVD_create (n, ny); autoSVD svdx = SVD_create (n, nx); for (long i = 1; i <= n; i++) { for (long j = 1; j <= ny; j++) { svdy -> u[i][j] = my data[i][j]; } for (long j = 1; j <= nx; j++) { svdx -> u[i][j] = my data[i][ny + j]; } } double **uy = svdy -> u; double **vy = svdy -> v; double **ux = svdx -> u; double **vx = svdx -> v; double fnormy = NUMfrobeniusnorm (n, ny, uy); double fnormx = NUMfrobeniusnorm (n, nx, ux); if (fnormy == 0.0 || fnormx == 0.0) { Melder_throw (U"One of the parts of the table contains only zeros."); } // Centre the data and svd it. NUMcentreColumns (uy, 1, n, 1, ny, nullptr); NUMcentreColumns (ux, 1, n, 1, nx, nullptr); SVD_compute (svdy.peek()); SVD_compute (svdx.peek()); long numberOfZeroedy = SVD_zeroSmallSingularValues (svdy.peek(), 0.0); long numberOfZeroedx = SVD_zeroSmallSingularValues (svdx.peek(), 0.0); // Form the matrix C = ux' uy (use svd-object storage) autoSVD svdc = SVD_create (nx, ny); double **uc = svdc -> u; double **vc = svdc -> v; for (long i = 1; i <= nx; i++) { for (long j = 1; j <= ny; j++) { double t = 0; for (long q = 1; q <= n; q++) { t += ux[q][i] * uy[q][j]; } uc[i][j] = t; } } SVD_compute (svdc.peek()); long numberOfZeroedc = SVD_zeroSmallSingularValues (svdc.peek(), 0.0); long numberOfCoefficients = ny - numberOfZeroedc; autoCCA thee = CCA_create (numberOfCoefficients, ny, nx); thy yLabels = strings_to_Strings (my columnLabels, 1, ny); thy xLabels = strings_to_Strings (my columnLabels, ny + 1, my numberOfColumns); double **evecy = thy y -> eigenvectors; double **evecx = thy x -> eigenvectors; thy numberOfObservations = n; /* Y = Vy * inv(Dy) * Vc X = Vx * inv(Dx) * Uc For the eigenvectors we want a row representation: colums(Y) = rows(Y') = rows(Vc' * inv(Dy) * Vy') colums(X) = rows(X') = rows(Uc' * inv(Dx) * Vx') rows(Y') = evecy[i][j] = Vc[k][i] * Vy[j][k] / Dy[k] rows(X') = evecx[i][j] = Uc[k][i] * Vx[j][k] / Dx[k] */ for (long i = 1; i <= numberOfCoefficients; i++) { double ccc = svdc -> d[i]; thy y -> eigenvalues[i] = thy x -> eigenvalues[i] = ccc * ccc; for (long j = 1; j <= ny; j++) { double t = 0.0; for (long q = 1; q <= ny - numberOfZeroedy; q++) { t += vc[q][i] * vy[j][q] / svdy -> d[q]; } evecy[i][j] = t; } for (long j = 1; j <= nx; j++) { double t = 0.0; for (long q = 1; q <= nx - numberOfZeroedx; q++) { t += uc[q][i] * vx[j][q] / svdx -> d[q]; } evecx[i][j] = t; } } // Normalize eigenvectors. NUMnormalizeRows (thy y -> eigenvectors, numberOfCoefficients, ny, 1); NUMnormalizeRows (thy x -> eigenvectors, numberOfCoefficients, nx, 1); Melder_assert (thy x -> dimension == thy xLabels -> numberOfStrings && thy y -> dimension == thy yLabels -> numberOfStrings); return thee; } catch (MelderError) { Melder_throw (me, U": CCA not created."); } } autoTableOfReal CCA_and_TableOfReal_scores (CCA me, TableOfReal thee, long numberOfFactors) { try { long n = thy numberOfRows; long nx = my x -> dimension, ny = my y -> dimension; if (ny + nx != thy numberOfColumns) { Melder_throw (U"The number of columns in the table (", thy numberOfColumns, U") does not agree with the dimensions of the CCA object (ny + nx = ", ny, U" + ", nx, U")."); } if (numberOfFactors == 0) { numberOfFactors = my numberOfCoefficients; } if (numberOfFactors < 1 || numberOfFactors > my numberOfCoefficients) { Melder_throw (U"The number of factors must be in interval [1, ", my numberOfCoefficients, U"]."); } autoTableOfReal him = TableOfReal_create (n, 2 * numberOfFactors); NUMstrings_copyElements (thy rowLabels, his rowLabels, 1, thy numberOfRows); Eigen_and_TableOfReal_project_into (my y.peek(), thee, 1, ny, him.peek(), 1, numberOfFactors); Eigen_and_TableOfReal_project_into (my x.peek(), thee, ny + 1, thy numberOfColumns, him.peek(), numberOfFactors + 1, his numberOfColumns); TableOfReal_setSequentialColumnLabels (him.peek(), 1, numberOfFactors, U"y_", 1, 1); TableOfReal_setSequentialColumnLabels (him.peek(), numberOfFactors + 1, his numberOfColumns, U"x_", 1, 1); return him; } catch (MelderError) { Melder_throw (me, U": no TableOfReal with scores created."); } } autoTableOfReal CCA_and_TableOfReal_predict (CCA me, TableOfReal thee, long from) { try { long ny = my y -> dimension, nx = my x -> dimension; long nev = my y -> numberOfEigenvalues; /* We can only predict when we have the largest dimension as input and the number of coefficients equals the dimension of the smallest. */ if (ny != nev) { Melder_throw (U"There are not enough correlations present for prediction."); } if (from == 0) { from = 1; } long ncols = thy numberOfColumns - from + 1; if (from < 1 || ncols != nx) { Melder_throw (U"The number of columns to analyze must be equal to ", nx, U"."); } // ???? dimensions if nx .. ny ?? autoTableOfReal him = Eigen_and_TableOfReal_project (my x.peek(), thee, from, ny); autoNUMvector buf (1, ny); // u = V a -> a = V'u double **v = my y -> eigenvectors; double *d = my y -> eigenvalues; for (long i = 1; i <= thy numberOfRows; i++) { NUMvector_copyElements (his data[i], buf.peek(), 1, ny); for (long j = 1; j <= ny; j++) { double t = 0.0; for (long k = 1; k <= ny; k++) { t += sqrt (d[k]) * v[k][j] * buf[k]; } his data [i][j] = t; } } return him; } catch (MelderError) { Melder_throw (me, U": no predictions created."); } } autoTableOfReal CCA_and_TableOfReal_factorLoadings (CCA me, TableOfReal thee) { try { autoCorrelation c = TableOfReal_to_Correlation (thee); autoTableOfReal him = CCA_and_Correlation_factorLoadings (me, c.peek()); return him; } catch (MelderError) { Melder_throw (me, U": no factor loadings created."); } } double CCA_getCorrelationCoefficient (CCA me, long index) { if (index < 1 || index > my numberOfCoefficients) { return NUMundefined; } return sqrt (my y -> eigenvalues[index]); } void CCA_getZeroCorrelationProbability (CCA me, long index, double *chisq, long *ndf, double *probability) { double lambda = 1.0, *ev = my y -> eigenvalues; long nev = my y -> numberOfEigenvalues; long ny = my y -> dimension, nx = my x -> dimension; *chisq = *probability = NUMundefined; *ndf = 0; if (index < 1 || index > nev) { return; } for (long i = index; i <= nev; i++) { lambda *= (1.0 - ev[i]); } *ndf = (ny - index + 1) * (nx - index + 1); *chisq = - (my numberOfObservations - (ny + nx + 3.0) / 2.0) * log (lambda); *probability = NUMchiSquareQ (*chisq, *ndf); } /* End of file CCA.c */ praat-6.0.04/dwtools/CCA.h000066400000000000000000000074051261542461700151600ustar00rootroot00000000000000#ifndef _CCA_h_ #define _CCA_h_ /* CCA.h * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 2001 djmw 20020423 GPL header djmw 20110306 Latest modification. */ #include "Eigen.h" #include "TableOfReal.h" #include "CCA_def.h" oo_CLASS_CREATE (CCA, Daata); /* Class CCA represents the Canonical Correlation Analysis of two datasets (two tables with multivariate data, Table 1 was N rows x p columns, Table 2 was N rows x q columns, and p <= q). Interpretation: The eigenvectors v1[i] en v2[i] have the property that for the linear compounds c1[1] = v1[1]' . Table1 c2[1]= v2[1]' . Table2 .............................................. c1[p] = v1[p]' . Table1 c2[p]= v2[p]' . Table2 the sample correlation of c1[1] and c2[1] is greatest, the sample correlation of c1[2] and c2[2] is greatest amoung all linear compounds uncorrelated with c1[1] and c2[1], and so on, for all p possible pairs. */ autoCCA CCA_create (long numberOfCoefficients, long ny, long nx); void CCA_drawEigenvector (CCA me, Graphics g, int x_or_y, long ivec, long first, long last, double ymin, double ymax, int weigh, double size_mm, const char32 *mark, int connect, int garnish); double CCA_getEigenvectorElement (CCA me, int x_or_y, long ivec, long element); autoCCA TableOfReal_to_CCA (TableOfReal me, long ny); /* Solves the canonical correlation analysis equations: (S12*inv(S22)*S12' - lambda S11)X1 = 0 (1) (S12'*inv(S11)*S12 - lambda S22)X2 = 0 (2) Where S12 = T1' * T2, S11 = T1' * T1 and S22 = T2' * T2. Given the following svd's: svd (T1) = U1 D1 V1' svd (T2) = U2 D2 V2' We can write down: inv(S11) = V1 * D1^-2 * V1' and inv(S22) = V2 * D2^-2 * V2', and S12*inv(S22)*S12' simplifies to: V1*D1*U1'*U2 * U2'*U1*D1*V1' and (1) becomes: (V1*D1*U1'*U2 * U2'*U1*D1*V1' -lambda V1*D1 * D1*V1')X1 = 0 This can be written as: (V1*D1*U1'*U2 * U2'*U1 -lambda V1*D1) D1*V1'*X1 = 0 multiplying from the left with: D1^-1*V1' results in (U1'*U2 * U2'*U1 -lambda) D1*V1'*X1 = 0 Taking the svd(U2'*U1) = U D V' we get: (D^2 -lambda)V'*D1*V1'*X1 = 0 The eigenvectors X1 can be formally written as: X1 = V1*inv(D1)*V Equation (2) results in: X2 = V2*inv(D2)*U */ autoTableOfReal CCA_and_TableOfReal_scores (CCA me, TableOfReal thee, long numberOfFactors); /* Return the factors in a table with 2*numberOfFactors columns. The first 'numberOfFactors' columns are the scores for the dependent part of the table the following 'numberOfFactors' columns are for the independent part. */ autoTableOfReal CCA_and_TableOfReal_factorLoadings (CCA me, TableOfReal thee); /* Get the canonical factor loadings (also structure correlation coefficients), the correlation of a canonical variable with an original variable. */ double CCA_getCorrelationCoefficient (CCA me, long index); void CCA_getZeroCorrelationProbability (CCA me, long index, double *chisq, long *ndf, double *probability); autoTableOfReal CCA_and_TableOfReal_predict (CCA me, TableOfReal thee, long from); /* Given independent table, predict the dependent one, on the basis of the canonical correlations. */ #endif /* CCA.h */ praat-6.0.04/dwtools/CCA_and_Correlation.cpp000066400000000000000000000121101261542461700206630ustar00rootroot00000000000000/* CCA_and_Correlation.cpp * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 2001 djmw 20020525 GPL header. djmw 20060323 Stewart-Love redundancy added. djmw 20071022 Melder_error */ #include "CCA_and_Correlation.h" #include "NUM2.h" autoTableOfReal CCA_and_Correlation_factorLoadings (CCA me, Correlation thee) { try { long ny = my y -> dimension, nx = my x -> dimension; if (ny + nx != thy numberOfColumns) { Melder_throw (U"The number of columns in the Correlation must equal the sum of the dimensions in the CCA object"); } autoTableOfReal him = TableOfReal_create (2 * my numberOfCoefficients, thy numberOfColumns); NUMstrings_copyElements (thy columnLabels, his columnLabels, 1, thy numberOfColumns); TableOfReal_setSequentialRowLabels (him.peek(), 1, my numberOfCoefficients, U"dv", 1, 1); TableOfReal_setSequentialRowLabels (him.peek(), my numberOfCoefficients + 1, 2 * my numberOfCoefficients, U"iv", 1, 1); double **evecy = my y -> eigenvectors, **evecx = my x -> eigenvectors; for (long i = 1; i <= thy numberOfRows; i++) { for (long j = 1; j <= my numberOfCoefficients; j++) { double t = 0.0; for (long k = 1; k <= ny; k++) { t += thy data[i][k] * evecy[j][k]; } his data[j][i] = t; } for (long j = 1; j <= my numberOfCoefficients; j++) { double t = 0.0; for (long k = 1; k <= nx; k++) { t += thy data[i][ny + k] * evecx[j][k]; } his data[my numberOfCoefficients + j][i] = t; } } return him; } catch (MelderError) { Melder_throw (U"TableOfReal not created from CCA & Correlation."); } } static void _CCA_and_Correlation_check (CCA me, Correlation thee, int canonicalVariate_from, int canonicalVariate_to) { if (my y -> dimension + my x -> dimension != thy numberOfColumns) { Melder_throw (U"The number of columns in the Correlation object must equal the sum of the dimensions in the CCA object"); } if (canonicalVariate_to < canonicalVariate_from) { Melder_throw (U"The second value in the \"Canonical variate range\" must be equal or larger than the first."); } if (canonicalVariate_from < 1 || canonicalVariate_to > my numberOfCoefficients) { Melder_throw (U"The \"Canonical variate range\" must be within the interval [1, ", my numberOfCoefficients, U"]."); } } double CCA_and_Correlation_getVarianceFraction (CCA me, Correlation thee, int x_or_y, int canonicalVariate_from, int canonicalVariate_to) { _CCA_and_Correlation_check (me, thee, canonicalVariate_from, canonicalVariate_to); /* For the formulas see: William W. Cooley & Paul R. Lohnes (1971), Multivariate data Analysis, John Wiley & Sons, pag 170-... varianceFraction = s'.s / n, where e.g. for the independent set x: s = Rxx . c, and Rxx is the correlation matrix of x, c is the factor coefficient for x, nx is the dimension of x, The factor coefficient c is the eigenvector e for x scaled by the st.dev of the component, i.e. c = e / sqrt (e'.R.e) (pag 32-33). Therefore: varianceFraction = s'.s / n = c'Rxx' Rxx c/n = (e'.Rxx' Rxx.e) /(e'.Rxx.e) * 1/n (for one can. variate) */ long n = my x -> dimension; double **evec = my x -> eigenvectors; long ioffset = my y -> dimension; if (x_or_y == 1) { /* y: dependent set */ n = my y -> dimension; evec = my y -> eigenvectors; ioffset = 0; } double varianceFraction = 0.0; for (long icv = canonicalVariate_from; icv <= canonicalVariate_to; icv++) { double variance = 0.0, varianceScaling = 0.0; for (long i = 1; i <= n; i++) { double si = 0.0; for (long j = 1; j <= n; j++) { si += thy data[ioffset + i][ioffset + j] * evec[icv][j]; /* Rxx.e */ } variance += si * si; /* (Rxx.e)'(Rxx.e) = e'.Rxx'.Rxx.e */ varianceScaling += evec[icv][i] * si; /* e'.Rxx.e*/ } varianceFraction += (variance / varianceScaling) / n; } return varianceFraction; } double CCA_and_Correlation_getRedundancy_sl (CCA me, Correlation thee, int x_or_y, int canonicalVariate_from, int canonicalVariate_to) { _CCA_and_Correlation_check (me, thee, canonicalVariate_from, canonicalVariate_to); double redundancy = 0.0; for (long icv = canonicalVariate_from; icv <= canonicalVariate_to; icv++) { double varianceFraction = CCA_and_Correlation_getVarianceFraction (me, thee, x_or_y, icv, icv); if (varianceFraction == NUMundefined) { return NUMundefined; } redundancy += varianceFraction * my y -> eigenvalues[icv]; } return redundancy; } /* End of file CCA_and_Correlation.cpp */ praat-6.0.04/dwtools/CCA_and_Correlation.h000066400000000000000000000035651261542461700203460ustar00rootroot00000000000000#ifndef _CCA_and_Correlation_h_ #define _CCA_and_Correlation_h_ /* CCA_and_Correlation.h * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 2001 djmw 20020516 GPL header djmw 20110307 Latest modification. */ #include "CCA.h" #include "SSCP.h" autoTableOfReal CCA_and_Correlation_factorLoadings (CCA me, Correlation thee); /* Get the canonical factor loadings (also structure correlation coefficients), the correlation of a canonical variable with an original variable. */ double CCA_and_Correlation_getVarianceFraction (CCA me, Correlation thee, int x_or_y, int canonicalVariate_from, int canonicalVariate_to); /* Get the fraction of variance extracted from the dependent/independent set by the canonical variate range. */ double CCA_and_Correlation_getRedundancy_sl (CCA me, Correlation thee, int x_or_y, int canonicalVariate_from, int canonicalVariate_to); /* The Stewart-Love redundancy is the fraction of variance extracted by the canonical variate times the fraction of shared variance between the canonical variate and the corresponding canonical variate of the other set. redundancy = VarianceFraction * (canonical correlation)^2 */ #endif /* _CCA_and_Correlation_h_ */ praat-6.0.04/dwtools/CCA_def.h000066400000000000000000000024171261542461700157740ustar00rootroot00000000000000/* CCA_def.h * * Copyright (C) 1993-2008, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 2001 djmw 20020423 GPL header djmw 20031214 Added x/yLabels djmw 20060529 Added object version numbers. djmw 20080122 float -> double */ #define ooSTRUCT CCA oo_DEFINE_CLASS (CCA, Daata) oo_LONG (numberOfCoefficients) oo_LONG (numberOfObservations) oo_AUTO_OBJECT (Strings, 0, yLabels) oo_AUTO_OBJECT (Strings, 0, xLabels) oo_AUTO_OBJECT(Eigen, 0, y) oo_AUTO_OBJECT(Eigen, 0, x) #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (CCA) #undef ooSTRUCT /* End of file CCA_def.h */ praat-6.0.04/dwtools/CC_def.h000066400000000000000000000027731261542461700157000ustar00rootroot00000000000000/* CC_def.h * * Copyright (C) 1993-2013 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT CC_Frame oo_DEFINE_STRUCT (CC_Frame) oo_LONG (numberOfCoefficients) #if oo_READING_BINARY if (formatVersion == 0) { oo_FLOAT (c0) oo_FLOAT_VECTOR (c, numberOfCoefficients) } else { oo_DOUBLE (c0) oo_DOUBLE_VECTOR (c, numberOfCoefficients) } #else oo_DOUBLE (c0) oo_DOUBLE_VECTOR (c, numberOfCoefficients) #endif oo_END_STRUCT (CC_Frame) #undef ooSTRUCT #define ooSTRUCT CC oo_DEFINE_CLASS (CC, Sampled) oo_DOUBLE (fmin) oo_DOUBLE (fmax) // c[0]..c[maximumNumberOfCoefficients] ; needed for inverse transform oo_LONG (maximumNumberOfCoefficients) oo_STRUCT_VECTOR (CC_Frame, frame, nx) #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (CC) #undef ooSTRUCT /* End of file CC_def.h */ praat-6.0.04/dwtools/CCs_to_DTW.cpp000066400000000000000000000072451261542461700170170ustar00rootroot00000000000000/* CCs_to_DTW.c * * Dynamic Time Warp of two CCs. * * Copyright (C) 1993-2013, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 2001 djmw 20020315 GPL header djmw 20080122 float -> double */ #include "CCs_to_DTW.h" static void regression (CC me, long frame, double r[], long nr) { // sum(i^2;i=-n..n) = 2n^3/3 + n^2 +n/3 = n (n (2n/3 + 1) + 1/3); long nrd2 = nr / 2; double sumsq = nrd2 * (nrd2 * (nr / 3.0 + 1.0) + 1.0 / 3.0); if (frame <= nrd2 || frame >= my nx - nrd2) { return; } for (long i = 0; i <= my maximumNumberOfCoefficients; i++) { r[i] = 0.0; } long nmin = CC_getMinimumNumberOfCoefficients (me, frame - nrd2, frame + nrd2); for (long i = 0; i <= nmin; i++) { double ri = 0; for (long j = -nrd2; j <= nrd2; j++) { CC_Frame cf = & my frame[frame + j]; double c = i == 0 ? cf -> c0 : cf -> c[i]; ri += c * j; } r[i] = ri / sumsq / my dx; } } autoDTW CCs_to_DTW (CC me, CC thee, double wc, double wle, double wr, double wer, double dtr) { try { if (my maximumNumberOfCoefficients != thy maximumNumberOfCoefficients) { Melder_throw (U"CC orders must be equal."); } long nr = (long) floor (dtr / my dx); if (wr != 0.0 && nr < 2) { Melder_throw (U"Time window for regression is too small."); } if (nr % 2 == 0) { nr++; } if (wr != 0.0) { Melder_casual (nr, U" frames used for regression coefficients."); } autoDTW him = DTW_create (my xmin, my xmax, my nx, my dx, my x1, thy xmin, thy xmax, thy nx, thy dx, thy x1); autoNUMvector ri (0L, my maximumNumberOfCoefficients); autoNUMvector rj (0L, my maximumNumberOfCoefficients); // Calculate distance matrix autoMelderProgress progess (U"CCs_to_DTW"); for (long i = 1; i <= my nx; i++) { CC_Frame fi = & my frame[i]; regression (me, i, ri.peek(), nr); for (long j = 1; j <= thy nx; j++) { CC_Frame fj = & thy frame[j]; double dist = 0.0, distr = 0.0; // Cepstral distance if (wc != 0.0) { for (long k = 1; k <= fj -> numberOfCoefficients; k++) { double d = fi -> c[k] - fj -> c[k]; dist += d * d; } dist *= wc; } // Log energy distance if (wle != 0.0) { double d = fi -> c0 - fj -> c0; dist += wle * d * d; } // Regression distance if (wr != 0.0) { regression (thee, j, rj.peek(), nr); for (long k = 1; k <= fj -> numberOfCoefficients; k++) { double d = ri[k] - rj[k]; distr += d * d; } dist += wr * distr; } // Regression on c[0]: log(energy) if (wer != 0.0) { if (wr == 0.0) { regression (thee, j, rj.peek(), nr); } double d = ri[0] - rj[0]; dist += wer * d * d; } dist /= wc + wle + wr + wer; his z[i][j] = sqrt (dist); /* prototype along y-direction */ } if ((i % 10) == 1) { Melder_progress (0.999 * i / my nx, U"Calculate distances: frame ", i, U" from ", my nx, U"."); } } return him; } catch (MelderError) { Melder_throw (U"DTW not created from CCs."); } } /* End of file CCs_to_DTW.cpp */ praat-6.0.04/dwtools/CCs_to_DTW.h000066400000000000000000000032471261542461700164620ustar00rootroot00000000000000#ifndef _CCs_to_DTW_h_ #define _CCs_to_DTW_h_ /* CCs_to_DTW.h * * Dynamic Time Warp of two CCs. * * Copyright (C) 1993-2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020315 GPL header */ #include "CC.h" #include "DTW.h" autoDTW CCs_to_DTW (CC me, CC thee, double wc, double wle, double wr, double wer, double dtr); /* 1. Calculate distances between CCs: Distance between frame i (from me) and j (from thee) is wc * d1 + wle * d2 + wr * d3 + wer * d4, where wc, wle, wr & wer are weights and d1 = Sum (k=1; k=nCoefficients; (c[i,k]-c[j,k])^2) d2 = (c[0,k]-c[0,k])^2 d3 = Sum (k=1; k=nCoefficients; (r[i,k]-r[j,k])^2), with r[i,k] the regression coefficient of the cepstral coefficients from the frames within a time span of 'dtr' seconds. c[i,j] is jth cepstral coefficient in frame i. d4 = regression on energy (c[0]) 2. Find optimum path through the distance matrix (see DTW). PRECONDITIONS: at least one of wc, wle, wr, wer != 0 */ #endif /* _CCs_to_DTW_h_ */ praat-6.0.04/dwtools/Categories.cpp000066400000000000000000000103371261542461700172100ustar00rootroot00000000000000/* Categories.cpp * * Copyright (C) 1993-2013, 2015 David Weenink, 2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020315 GPL header djmw 20110304 Thing_new */ #include "Categories.h" void structCategories :: v_readText (MelderReadText a_text, int /*formatVersion*/) { long l_size = texgeti4 (a_text); if (l_size == 0) { OrderedOfString_init (this, 1); } else if (l_size < 0) { Melder_throw (U"Size cannot be negative."); } else { OrderedOfString_init (this, l_size); } for (long i = 1; i <= l_size; i ++) { autoSimpleString itemi = Thing_new (SimpleString); itemi -> v_readText (a_text, 0); Ordered_addItemPos (this, itemi.transfer(), i); } } void structCategories :: v_writeText (MelderFile file) { texputi4 (file, size, U"size", 0, 0, 0, 0, 0); for (long i = 1; i <= size; i++) { SimpleString data = (SimpleString) item [i]; texputintro (file, U"item" " [", Melder_integer (i), U"]:", nullptr, nullptr, nullptr); data -> structSimpleString :: v_writeText (file); texexdent (file); } } Thing_implement (Categories, OrderedOfString, 0); void Categories_init (Categories me, long size) { OrderedOfString_init (me, size); } autoCategories Categories_create () { try { autoCategories me = Thing_new (Categories); Categories_init (me.peek(), 10); return me; } catch (MelderError) { Melder_throw (U"Categories not created."); } } autoCategories Categories_sequentialNumbers (long n) { try { autoCategories me = Thing_new (Categories); OrderedOfString_init (me.peek(), 5); OrderedOfString_sequentialNumbers (me.peek(), n); return me; } catch (MelderError) { Melder_throw (U"Sequential number Categories not created."); } } autoCategories Categories_selectUniqueItems (Categories me, int sorted) { try { autoOrderedOfString s = OrderedOfString_selectUniqueItems (me, sorted); autoCategories thee = OrderedOfString_to_Categories (s.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": no unique categories created."); } } void Categories_drawItem (Categories me, Graphics g, long position, double xWC, double yWC) { if (position < 1 || position > my size) { return; } SimpleString_draw ((SimpleString) my item[position], g, xWC, yWC); } autoCategories OrderedOfString_to_Categories (OrderedOfString me) { try { autoCategories thee = Categories_create(); for (long i = 1; i <= my size; i++) { autoSimpleString item = Data_copy ( (SimpleString) my item [i]); Collection_addItem (thee.peek(), item.transfer()); } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Categories."); } } long Categories_getSize (Categories me) { return my size; } /* TableOfReal_Rowlabels_to_Categories ??? */ autoCategories TableOfReal_to_CategoriesRow (TableOfReal me) { try { autoCategories thee = Categories_create (); for (long i = 1; i <= my numberOfRows; i++) { if (my rowLabels[i]) { autoSimpleString s = SimpleString_create (my rowLabels[i]); Collection_addItem (thee.peek(), s.transfer()); } } return thee; } catch (MelderError) { Melder_throw (me, U": row labels not converted to Categories."); } } autoCategories TableOfReal_to_CategoriesColumn (TableOfReal me) { try { autoCategories thee = Categories_create (); for (long i = 1; i <= my numberOfColumns; i++) { if (my columnLabels[i]) { autoSimpleString s = SimpleString_create (my columnLabels[i]); Collection_addItem (thee.peek(), s.transfer()); } } return thee; } catch (MelderError) { Melder_throw (me, U": columnlabels not converted to Categories."); } } /* End of file Categories.cpp */ praat-6.0.04/dwtools/Categories.h000066400000000000000000000032641261542461700166560ustar00rootroot00000000000000#ifndef _Categories_h_ #define _Categories_h_ /* Categories.h * * Copyright (C) 1993-2011, 2015 David Weenink, 2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Collection_extensions.h" #include "Simple_extensions.h" #include "TableOfReal.h" #include "Graphics.h" Thing_define (Categories, OrderedOfString) { void v_readText (MelderReadText text, int formatVersion) override; void v_writeText (MelderFile file) override; }; void Categories_init (Categories me, long size); autoCategories Categories_create (); autoCategories Categories_sequentialNumbers (long n); autoCategories Categories_selectUniqueItems (Categories me, int sorted); void Categories_drawItem (Categories me, Graphics g, long position, double xWC, double yWC); autoCategories OrderedOfString_to_Categories (OrderedOfString me); long Categories_getSize (Categories me); /* return my size */ autoCategories TableOfReal_to_CategoriesRow (TableOfReal me); autoCategories TableOfReal_to_CategoriesColumn (TableOfReal me); #endif /* _Categories_h_ */ praat-6.0.04/dwtools/CategoriesEditor.cpp000066400000000000000000000654631261542461700203710ustar00rootroot00000000000000/* CategoriesEditor.cpp * * Copyright (C) 1993-2013 David Weenink, 2008,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 1995 djmw 19980225 repaired a memory leak, caused by wrong inheritance for CategoriesEditorInsert command. djmw 20020408 GPL djmw 20020408 Modified 'createMenus' djmw 20060111 Replaced Resources.h with Preferences.h djmw 20060328 Changed last argument to 0 in XtVaSetValues, XtVaGetValues and XtVaCreateManagedWidget for 64-bit compatibility. djmw 20070620 Latest modification. pb 20080320 split off Help menu pb 20080321 new Editor API djmw 20090107 Removed a bug in update that caused editor to crash on replace djmw 20090203 Removed potential crashes in CategoriesEditor_create. djmw 20110304 Thing_new djmw 20111110 Use autostringvector */ #define CategoriesEditor_TEXTMAXLENGTH 100 #include "CategoriesEditor.h" //#include "Preferences.h" #include "EditorM.h" Thing_implement (CategoriesEditor, Editor, 0); /* forward declarations */ static void update (I, long from, long to, const long *select, long nSelect); static void update_dos (I); const char32 *CategoriesEditor_EMPTYLABEL = U"(empty)"; static void menu_cb_help (EDITOR_ARGS) { EDITOR_IAM (CategoriesEditor); Melder_help (U"CategoriesEditor"); } /**************** Some methods for Collection ****************/ /* Preconditions: */ /* 1 <= (position[i], newpos) <= size; */ /* newpos <= position[1] || newpos >= position[npos] */ static void Ordered_moveItems (I, long position[], long npos, long newpos) { iam (Ordered); long pos, min = position[1], max = position[1]; for (long i = 2; i <= npos; i++) { if (position[i] > max) { max = position[i]; } else if (position[i] < min) { min = position[i]; } } Melder_assert (min >= 1 && max <= my size && (newpos <= min || newpos >= max)); autoNUMvector tmp (1, npos); // 'remove' for (long i = 1; i <= npos; i++) { tmp[i] = (Daata) my item[position[i]]; my item[position[i]] = 0; } // create a contiguous 'hole' if (newpos <= min) { pos = max; for (long i = max; i >= newpos; i--) { if (my item[i]) { my item[pos--] = my item[i]; } } pos = newpos; } else { pos = min; for (long i = min; i <= newpos; i++) { if (my item[i]) { my item[pos++] = my item[i]; } } pos = newpos - npos + 1; } // fill the 'hole' for (long i = 1; i <= npos; i++) { my item[pos++] = tmp[i]; } } static void Collection_replaceItemPos (I, Any item, long pos) { iam (Collection); if (pos < 1 || pos > my size) { return; } forget (((SimpleString *) my item) [pos]); my item[pos] = item; } /* Remove the item at position 'from' and insert it at position 'to'. */ static void Ordered_moveItem (I, long from, long to) { iam (Ordered); if (from < 1 || from > my size) { from = my size; } if (to < 1 || to > my size) { to = my size; } if (from == to) { return; } Daata tmp = (Daata) my item[from]; if (from > to) { for (long i = from; i > to; i--) { my item[i] = my item[i - 1]; } } else { for (long i = from; i < to; i++) { my item[i] = my item[i + 1]; } } my item[to] = tmp; } /********************** General Command **********************/ Thing_define (CategoriesEditorCommand, Command) { // new data: public: autoCategories categories; long *selection; long nSelected, newPos; // overridden methods: virtual void v_destroy (); }; Thing_implement (CategoriesEditorCommand, Command, 0); void structCategoriesEditorCommand :: v_destroy () { NUMvector_free (selection, 1); CategoriesEditorCommand_Parent :: v_destroy (); } static void CategoriesEditorCommand_init (CategoriesEditorCommand me, const char32 *name, Any data, int (*execute) (Any), int (*undo) (Any), int /*nCategories*/, int nSelected) { my nSelected = nSelected; Command_init (me, name, data, execute, undo); my categories = Categories_create(); my selection = NUMvector (1, nSelected); } /*********************** Insert Command ***********************/ Thing_define (CategoriesEditorInsert, CategoriesEditorCommand) { }; Thing_implement (CategoriesEditorInsert, CategoriesEditorCommand, 0); static int CategoriesEditorInsert_execute (I) { iam (CategoriesEditorInsert); CategoriesEditor editor = (CategoriesEditor) my data; Categories categories = (Categories) editor -> data; autoSimpleString str = Data_copy ((SimpleString) my categories -> item[1]); Ordered_addItemPos (categories, str.transfer(), my selection[1]); update (editor, my selection[1], 0, my selection, 1); return 1; } static int CategoriesEditorInsert_undo (I) { iam (CategoriesEditorInsert); CategoriesEditor editor = (CategoriesEditor) my data; Categories categories = (Categories) editor -> data; Collection_removeItem (categories, my selection[1]); update (editor, my selection[1], 0, my selection, 1); return 1; } static CategoriesEditorInsert CategoriesEditorInsert_create (Any data, Any str, int position) { try { autoCategoriesEditorInsert me = Thing_new (CategoriesEditorInsert); CategoriesEditorCommand_init (me.peek(), U"Insert", data, CategoriesEditorInsert_execute, CategoriesEditorInsert_undo, 1, 1); my selection[1] = position; Collection_addItem (my categories.peek(), (SimpleString) str); return me.transfer(); } catch (MelderError) { Melder_throw (U"CategoriesEditorInsert not created."); } } /*********************** Remove Command ***********************/ Thing_define (CategoriesEditorRemove, CategoriesEditorCommand) { }; Thing_implement (CategoriesEditorRemove, CategoriesEditorCommand, 0); static int CategoriesEditorRemove_execute (I) { iam (CategoriesEditorRemove); CategoriesEditor editor = (CategoriesEditor) my data; Categories l_categories = (Categories) editor -> data; // David, weer link: tweemaal dezelfde naam (categories): is ok, geen conflict. Naam toch maar aangepast for (long i = my nSelected; i >= 1; i--) { Ordered_addItemPos (my categories.peek(), (SimpleString) l_categories -> item[my selection[i]], 1); l_categories -> item[my selection[i]] = 0; Collection_removeItem (l_categories, my selection[i]); } update (editor, my selection[1], 0, 0, 0); return 1; } static int CategoriesEditorRemove_undo (I) { iam (CategoriesEditorRemove); CategoriesEditor editor = (CategoriesEditor) my data; Categories categories = (Categories) editor -> data; for (long i = 1; i <= my nSelected; i++) { autoSimpleString item = Data_copy ( (SimpleString) my categories -> item[i]); Ordered_addItemPos (categories, item.transfer(), my selection[i]); } update (editor, my selection[1], 0, my selection, my nSelected); return 1; } static CategoriesEditorRemove CategoriesEditorRemove_create (Any data, long *posList, long posCount) { try { autoCategoriesEditorRemove me = Thing_new (CategoriesEditorRemove); CategoriesEditorCommand_init (me.peek(), U"Remove", data, CategoriesEditorRemove_execute, CategoriesEditorRemove_undo, posCount, posCount); for (long i = 1; i <= posCount; i++) { my selection[i] = posList[i]; } return me.transfer(); } catch (MelderError) { Melder_throw (U"CategoriesEditorRemove not created."); } } //update (me); /*********************** Replace Command ***********************/ Thing_define (CategoriesEditorReplace, CategoriesEditorCommand) { }; Thing_implement (CategoriesEditorReplace, CategoriesEditorCommand, 0); static int CategoriesEditorReplace_execute (I) { iam (CategoriesEditorReplace); CategoriesEditor editor = (CategoriesEditor) my data; Categories categories = (Categories) editor -> data; for (long i = my nSelected; i >= 1; i--) { autoSimpleString str = Data_copy ((SimpleString) my categories -> item[1]); Ordered_addItemPos (my categories.peek(), (SimpleString) categories -> item[my selection[i]], 2); categories -> item[my selection[i]] = str.transfer(); } update (editor, my selection[1], my selection[my nSelected], my selection, my nSelected); return 1; } static int CategoriesEditorReplace_undo (I) { iam (CategoriesEditorReplace); CategoriesEditor editor = (CategoriesEditor) my data; Categories categories = (Categories) editor -> data; for (long i = 1; i <= my nSelected; i++) { autoSimpleString str = Data_copy ( (SimpleString) my categories -> item[i + 1]); Collection_replaceItemPos (categories, str.transfer(), my selection[i]); } update (editor, my selection[1], my selection[my nSelected], my selection, my nSelected); return 1; } static CategoriesEditorReplace CategoriesEditorReplace_create (Any data, Any str, long *posList, long posCount) { try { autoCategoriesEditorReplace me = Thing_new (CategoriesEditorReplace); CategoriesEditorCommand_init (me.peek(), U"Replace", data, CategoriesEditorReplace_execute, CategoriesEditorReplace_undo, posCount + 1, posCount); for (long i = 1; i <= posCount; i++) { my selection[i] = posList[i]; } Collection_addItem (my categories.peek(), (SimpleString) str); return me.transfer(); } catch (MelderError) { Melder_throw (U"CategoriesEditorReplace not created."); } } /*********************** MoveUp Command ***********************/ Thing_define (CategoriesEditorMoveUp, CategoriesEditorCommand) { }; Thing_implement (CategoriesEditorMoveUp, CategoriesEditorCommand, 0); static int CategoriesEditorMoveUp_execute (I) { iam (CategoriesEditorMoveUp); CategoriesEditor editor = (CategoriesEditor) my data; Ordered_moveItems (editor->data, my selection, my nSelected, my newPos); autoNUMvector selection (1, my nSelected); for (long i = 1; i <= my nSelected; i++) { selection[i] = my newPos + i - 1; } update (editor, my newPos, my selection[my nSelected], selection.peek(), my nSelected); return 1; } static int CategoriesEditorMoveUp_undo (I) { iam (CategoriesEditorMoveUp); CategoriesEditor editor = (CategoriesEditor) my data; for (long i = 1; i <= my nSelected; i++) { Ordered_moveItem (editor->data, my newPos, my selection[my nSelected]); } update (editor, my newPos, my selection[my nSelected], my selection, my nSelected); return 1; } static CategoriesEditorMoveUp CategoriesEditorMoveUp_create (Any data, long *posList, long posCount, long newPos) { try { autoCategoriesEditorMoveUp me = Thing_new (CategoriesEditorMoveUp); CategoriesEditorCommand_init (me.peek(), U"Move up", data, CategoriesEditorMoveUp_execute, CategoriesEditorMoveUp_undo, 0, posCount); for (long i = 1; i <= posCount; i++) { my selection[i] = posList[i]; } my newPos = newPos; return me.transfer(); } catch (MelderError) { Melder_throw (U"CategoriesEditorMoveUp not created."); } } /*********************** MoveDown Command ***********************/ Thing_define (CategoriesEditorMoveDown, CategoriesEditorCommand) { }; Thing_implement (CategoriesEditorMoveDown, CategoriesEditorCommand, 0); static int CategoriesEditorMoveDown_execute (I) { iam (CategoriesEditorMoveDown); CategoriesEditor editor = (CategoriesEditor) my data; Ordered_moveItems ( (Ordered) editor -> data, my selection, my nSelected, my newPos); autoNUMvector selection (1, my nSelected); for (long i = 1; i <= my nSelected; i++) { selection[i] = my newPos - my nSelected + i; } update (editor, my selection[1], my newPos, selection.peek(), my nSelected); return 1; } static int CategoriesEditorMoveDown_undo (I) { iam (CategoriesEditorMoveDown); CategoriesEditor editor = (CategoriesEditor) my data; for (long i = 1; i <= my nSelected; i++) { Ordered_moveItem (editor -> data, my newPos, my selection[1]); // TODO 1 or i ?? } long from = my selection[1]; update (editor, (from > 1 ? from-- : from), my newPos, my selection, my nSelected); return 1; } static CategoriesEditorMoveDown CategoriesEditorMoveDown_create (Any data, long *posList, long posCount, long newPos) { try { autoCategoriesEditorMoveDown me = Thing_new (CategoriesEditorMoveDown); CategoriesEditorCommand_init (me.peek(), U"Move down", data, CategoriesEditorMoveDown_execute, CategoriesEditorMoveDown_undo, 0, posCount); for (long i = 1; i <= posCount; i++) { my selection[i] = posList[i]; } my newPos = newPos; return me.transfer(); } catch (MelderError) { Melder_throw (U"CategoriesEditorMoveDown not created."); } } /********************* Commands (End) *************************************/ static void notifyOutOfView (I) { iam (CategoriesEditor); autoMelderString tmp; MelderString_copy (&tmp, U""); long posCount; autoNUMvector posList (GuiList_getSelectedPositions (my list, & posCount), 1); if (posList.peek() != 0) { long outOfView = 0, top = GuiList_getTopPosition (my list), bottom = GuiList_getBottomPosition (my list); for (long i = posCount; i > 0; i--) { if (posList[i] < top || posList[i] > bottom) { outOfView++; } } if (outOfView > 0) { MelderString_append (&tmp, outOfView, U" selection(s) out of view"); } } GuiLabel_setText (my outOfView, tmp.string); } static void update_dos (I) { iam (CategoriesEditor); bool undoSense = true, redoSense = true; // undo const char32 *name; if (! (name = CommandHistory_commandName (my history, 0))) { name = U"nothing"; undoSense = false; } GuiButton_setText (my undo, Melder_cat (U"Undo ", U"\"", name, U"\"")); GuiThing_setSensitive (my undo, undoSense); // redo if (! (name = CommandHistory_commandName (my history, 1))) { name = U"nothing"; redoSense = false; } GuiButton_setText (my redo, Melder_cat (U"Redo ", U"\"", name, U"\"")); GuiThing_setSensitive (my redo, redoSense); } static void updateWidgets (I) { /*all buttons except undo & redo */ iam (CategoriesEditor); long size = ( (Categories) my data)->size; bool insert = false, insertAtEnd = true, replace = false, remove = false; bool moveUp = false, moveDown = false; long posCount; autoNUMvector posList (GuiList_getSelectedPositions (my list, & posCount), 1); if (posList.peek() != 0) { 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) { update_dos (me); } notifyOutOfView (me); } static void update (I, long from, long to, const long *select, long nSelect) { iam (CategoriesEditor); long size = ((Categories) my data) -> size; if (size == 0) { autoSimpleString str = SimpleString_create (CategoriesEditor_EMPTYLABEL); Collection_addItem ( (Categories) my data, str.transfer()); update (me, 0, 0, 0, 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); } } static void gui_button_cb_remove (I, GuiButtonEvent /* event */) { iam (CategoriesEditor); long posCount; autoNUMvector posList (GuiList_getSelectedPositions (my list, & posCount), 1); if (posList.peek() != 0) { autoCategoriesEditorRemove command = CategoriesEditorRemove_create (me, posList.peek(), posCount); if (! Command_do (command.peek())) { return; } if (my history) { CommandHistory_insertItem (my history, command.transfer()); } updateWidgets (me); } } static void insert (I, int position) { iam (CategoriesEditor); autostring32 text = GuiText_getString (my text); if (str32len (text.peek()) != 0) { autoSimpleString str = SimpleString_create (text.peek()); autoCategoriesEditorInsert command = CategoriesEditorInsert_create (me, str.transfer(), position); Command_do (command.peek()); if (my history) { CommandHistory_insertItem (my history, command.transfer()); } updateWidgets (me); } } static void gui_button_cb_insert (I, GuiButtonEvent /* event */) { iam (CategoriesEditor); insert (me, my position); } static void gui_button_cb_insertAtEnd (I, GuiButtonEvent /* event */) { iam (CategoriesEditor); Categories categories = (Categories) my data; insert (me, categories -> size + 1); my position = categories -> size; } static void gui_button_cb_replace (I, GuiButtonEvent /* event */) { iam (CategoriesEditor); long posCount; autoNUMvector posList (GuiList_getSelectedPositions (my list, & posCount), 1); if (posCount > 0) { autostring32 text = GuiText_getString (my text); if (str32len (text.peek()) != 0) { autoSimpleString str = SimpleString_create (text.peek()); autoCategoriesEditorReplace command = CategoriesEditorReplace_create (me, str.transfer(), posList.peek(), posCount); Command_do (command.peek()); if (my history) { CommandHistory_insertItem (my history, command.transfer()); } updateWidgets (me); } } } /* Precondition: contiguous selection */ static void gui_button_cb_moveUp (I, GuiButtonEvent /* event */) { iam (CategoriesEditor); long posCount; autoNUMvector posList (GuiList_getSelectedPositions (my list, & posCount), 1); if (posCount > 0) { autoCategoriesEditorMoveUp command = CategoriesEditorMoveUp_create (me, posList.peek(), posCount, posList[1] - 1); Command_do (command.peek()); if (my history) { CommandHistory_insertItem (my history, command.transfer()); } updateWidgets (me); } } /* Precondition: contiguous selection */ static void gui_button_cb_moveDown (I, GuiButtonEvent /* event */) { iam (CategoriesEditor); long posCount; autoNUMvector posList (GuiList_getSelectedPositions (my list, & posCount), 1); if (posCount > 0) { autoCategoriesEditorMoveDown command = CategoriesEditorMoveDown_create (me, posList.peek(), posCount, posList[posCount] + 1); Command_do (command.peek()); if (my history) { CommandHistory_insertItem (my history, command.transfer()); } updateWidgets (me); } } static void gui_cb_scroll (GUI_ARGS) { GUI_IAM (CategoriesEditor); notifyOutOfView (me); } static void gui_list_cb_double_click (void *void_me, GuiListEvent /* event */) { iam (CategoriesEditor); const char32 *catg = OrderedOfString_itemAtIndex_c ((OrderedOfString) my data, my position); GuiText_setString (my text, catg); } static void gui_list_cb_extended (void *void_me, GuiListEvent /* event */) { iam (CategoriesEditor); updateWidgets (me); } static void gui_button_cb_undo (I, GuiButtonEvent /* event */) { iam (CategoriesEditor); if (CommandHistory_offleft (my history)) { return; } Command_undo (CommandHistory_getItem (my history)); CommandHistory_back (my history); updateWidgets (me); } static void gui_button_cb_redo (I, GuiButtonEvent /* event */) { iam (CategoriesEditor); CommandHistory_forth (my history); if (CommandHistory_offright (my history)) { return; } Command_do (CommandHistory_getItem (my history)); updateWidgets (me); } void structCategoriesEditor :: v_destroy () { forget (history); /* !! Editor */ CategoriesEditor_Parent :: v_destroy (); } void structCategoriesEditor :: v_createHelpMenuItems (EditorMenu menu) { CategoriesEditor_Parent :: v_createHelpMenuItems (menu); EditorMenu_addCommand (menu, U"CategoriesEditor help", '?', menu_cb_help); } // origin is at top left. void structCategoriesEditor :: v_createChildren () { double menuBarOffset = 40; double button_width = 90, button_height = menuBarOffset, list_width = 260, list_height = 200, list_bottom; double delta_x = 15, delta_y = menuBarOffset / 2, text_button_height = button_height / 2; double left, right, top, bottom, buttons_left, buttons_top; left = 5; right = left + button_width; top = 3 + menuBarOffset; bottom = top + text_button_height; GuiLabel_createShown (d_windowForm, left, right, top, bottom, U"Positions:", 0); left = right + delta_x ; right = left + button_width; GuiLabel_createShown (d_windowForm, left, right, top, bottom, U"Values:", 0); left = 0; right = left + list_width; buttons_top = (top = bottom + delta_y); list_bottom = bottom = top + list_height; list = GuiList_create (d_windowForm, left, right, top, bottom, true, 0); GuiList_setSelectionChangedCallback (list, gui_list_cb_extended, this); GuiList_setDoubleClickCallback (list, gui_list_cb_double_click, this); GuiThing_show (list); buttons_left = left = right + 2 * delta_x; right = left + button_width; bottom = top + button_height; GuiLabel_createShown (d_windowForm, left, right, top, bottom, U"Value:", 0); left = right + delta_x; right = left + button_width; text = GuiText_createShown (d_windowForm, left, right, top, bottom, 0); GuiText_setString (text, CategoriesEditor_EMPTYLABEL); left = buttons_left; right = left + button_width; top = bottom + delta_y; bottom = top + button_height; insert = GuiButton_createShown (d_windowForm, left, right, top, bottom, U"Insert", gui_button_cb_insert, this, GuiButton_DEFAULT); left = right + delta_x; right = left + button_width; replace = GuiButton_createShown (d_windowForm, left, right, top, bottom, U"Replace", gui_button_cb_replace, this, 0); left = buttons_left; right = left + 1.5 * button_width; top = bottom + delta_y; bottom = top + button_height; insertAtEnd = GuiButton_createShown (d_windowForm, left, right, top, bottom, U"Insert at end", gui_button_cb_insertAtEnd, this, 0); top = bottom + delta_y; bottom = top + button_height; undo = GuiButton_createShown (d_windowForm, left, right, top, bottom, U"Undo", gui_button_cb_undo, this, 0); top = bottom + delta_y; bottom = top + button_height; redo = GuiButton_createShown (d_windowForm, left, right, top, bottom, U"Redo", gui_button_cb_redo, this, 0); top = bottom + delta_y; bottom = top + button_height; remove = GuiButton_createShown (d_windowForm, left, right, top, bottom, U"Remove", gui_button_cb_remove, this, 0); top = bottom + delta_y; bottom = top + button_height; moveUp = GuiButton_createShown (d_windowForm, left, right, top, bottom, U"Move selection up", gui_button_cb_moveUp, this, 0); top = bottom + delta_y; bottom = top + button_height; moveDown = GuiButton_createShown (d_windowForm, left, right, top, bottom, U"Move selection down", gui_button_cb_moveDown, this, 0); top = list_bottom + delta_y; bottom = top + button_height; left = 5; right = left + 200; outOfView = GuiLabel_createShown (d_windowForm, left, right, top, bottom, U"", 0); } void structCategoriesEditor :: v_dataChanged () { update (this, 0, 0, 0, 0); updateWidgets (this); } CategoriesEditor CategoriesEditor_create (const char32 *title, Categories data) { try { autoCategoriesEditor me = Thing_new (CategoriesEditor); Editor_init (me.peek(), 20, 40, 600, 600, title, data); my history = CommandHistory_create (100); update (me.peek(), 0, 0, 0, 0); updateWidgets (me.peek()); return me.transfer(); } catch (MelderError) { Melder_throw (U"Categories window not created."); } } /* End of file CategoriesEditor.cpp */ praat-6.0.04/dwtools/CategoriesEditor.h000066400000000000000000000026051261542461700200230ustar00rootroot00000000000000#ifndef _CategoriesEditor_h_ #define _CategoriesEditor_h_ /* CategoriesEditor.h * * Copyright (C) 1993-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Command.h" #include "Editor.h" #include "Categories.h" Thing_define (CategoriesEditor, Editor) { // new data: public: CommandHistory history; int position; GuiList list; GuiText text; GuiButton undo, redo; GuiLabel outOfView; GuiButton remove, insert, insertAtEnd, replace, moveUp, moveDown; // overridden methods: void v_destroy (); void v_createChildren (); void v_createHelpMenuItems (EditorMenu menu); void v_dataChanged (); }; CategoriesEditor CategoriesEditor_create (const char32 *title, Categories data); #endif /* _CategoriesEditor_h_ */praat-6.0.04/dwtools/Categories_and_Strings.cpp000066400000000000000000000035601261542461700215430ustar00rootroot00000000000000/* Categories_and_Strings.cpp * * Copyright (C) 1993-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020315 GPL header djmw 20110304 Thing_new */ #include "Categories_and_Strings.h" Strings Categories_to_Strings (Categories me) { try { if (my size < 1) { Melder_throw (U"No elements."); } autoStrings thee = Thing_new (Strings); thy strings = NUMvector (1, my size); thy numberOfStrings = my size; for (long i = 1; i <= my size; i++) { SimpleString s = (SimpleString) my item[i]; thy strings[i] = Melder_dup (s -> string); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not converted to Strings."); } } Categories Strings_to_Categories (Strings me) { try { if (my numberOfStrings < 1) { Melder_throw (U"Empty strings."); } autoCategories thee = Thing_new (Categories); Categories_init (thee.peek(), my numberOfStrings); for (long i = 1; i <= my numberOfStrings; i++) { autoSimpleString s = SimpleString_create (my strings[i]); Collection_addItem (thee.peek(), s.transfer()); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not converted."); } } /* End of file Categories_and_Strings.cpp */ praat-6.0.04/dwtools/Categories_and_Strings.h000066400000000000000000000021131261542461700212010ustar00rootroot00000000000000#ifndef _Categories_and_Strings_h_ #define _Categories_and_Strings_h_ /* Categories_and_Strings.h * * Copyright (C) 2001-2012 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020315 GPL header djmw 20121018 Latest modification */ #include "Categories.h" #include "Strings_.h" Strings Categories_to_Strings (Categories me); Categories Strings_to_Categories (Strings me); #endif /* _Categories_and_Strings_h_ */ praat-6.0.04/dwtools/Categories_def.h000066400000000000000000000017031261542461700174700ustar00rootroot00000000000000/* Categories_def.c * * Copyright (C) 1993-2008 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020315 GPL header */ #define ooSTRUCT Categories oo_DEFINE_CLASS (Categories, OrderedOfString) oo_END_CLASS (Categories) #undef ooSTRUCT /* End of file Categories_def.h */ praat-6.0.04/dwtools/ClassificationTable.cpp000066400000000000000000000115461261542461700210310ustar00rootroot00000000000000/* ClassificationTable.cpp * * Copyright (C) 1993-2011, 2014, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 1998 djmw 20020315 GPL header djmw 20040422 Added ClassificationTable_to_Categories_maximumProbability djmw 20040623 Added ClassificationTable_to_Strings_maximumProbability djmw 20040824 Added Strings_extensions.h header djmw 20101122 ClassificationTable_to_Correlation_columns djmw 20110304 Thing_new */ #include "ClassificationTable.h" #include "Distributions_and_Strings.h" #include "Strings_extensions.h" #include "NUM2.h" Thing_implement (ClassificationTable, TableOfReal, 0); autoClassificationTable ClassificationTable_create (long numberOfRows, long numberOfClasses) { try { autoClassificationTable me = Thing_new (ClassificationTable); TableOfReal_init (me.peek(), numberOfRows, numberOfClasses ); return me; } catch (MelderError) { Melder_throw (U"ClassificationTable not created."); } } autoConfusion ClassificationTable_to_Confusion (ClassificationTable me, bool onlyClassLabels) { try { autoStrings responses = TableOfReal_extractColumnLabelsAsStrings (me); autoStrings s2 = TableOfReal_extractRowLabelsAsStrings (me); autoDistributions d2 = Strings_to_Distributions (s2.peek()); autoStrings stimuli = TableOfReal_extractRowLabelsAsStrings (d2.peek()); autoConfusion thee = Confusion_createFromStringses (( onlyClassLabels ? responses.peek() : stimuli.peek() ), responses.peek()); Confusion_and_ClassificationTable_increase (thee.peek(), me); return thee; } catch (MelderError) { Melder_throw (me, U": confusions cannot be calculated."); } } void Confusion_and_ClassificationTable_increase (Confusion me, ClassificationTable thee) { if (my numberOfColumns != thy numberOfColumns) { Melder_throw (U"The number of columns must be equal."); } for (long irow = 1; irow <= thy numberOfRows; irow++) { long index = TableOfReal_getColumnIndexAtMaximumInRow (thee, irow); Confusion_increase (me, thy rowLabels[irow], my columnLabels[index]); } } autoStrings ClassificationTable_to_Strings_maximumProbability (ClassificationTable me) { try { autoStrings thee = Strings_createFixedLength (my numberOfRows); for (long i = 1; i <= my numberOfRows; i++) { double max = my data[i][1]; long col = 1; for (long j = 2; j <= my numberOfColumns; j++) { if (my data[i][j] > max) { max = my data[i][j]; col = j; } } if (my columnLabels[col] != 0) { Strings_replace (thee.peek(), i, my columnLabels[col]); } } return thee; } catch (MelderError) { Melder_throw (me, U": strings cannot be created."); } } autoCategories ClassificationTable_to_Categories_maximumProbability (ClassificationTable me) { try { autoCategories thee = Categories_create (); for (long i = 1; i <= my numberOfRows; i++) { double max = my data[i][1]; long col = 1; for (long j = 2; j <= my numberOfColumns; j++) { if (my data[i][j] > max) { max = my data[i][j]; col = j; } } OrderedOfString_append (thee.peek(), my columnLabels[col]); } return thee; } catch (MelderError) { Melder_throw (me, U": no Categories created."); } } autoCorrelation ClassificationTable_to_Correlation_columns (ClassificationTable me) { try { autoCorrelation thee = Correlation_create (my numberOfColumns); for (long icol = 1; icol <= thy numberOfColumns; icol++) { char32 *label = my columnLabels[icol]; TableOfReal_setRowLabel (thee.peek(), icol, label); TableOfReal_setColumnLabel (thee.peek(), icol, label); } for (long irow = 1; irow <= thy numberOfColumns; irow++) { thy data[irow][irow] = 1.0; for (long icol = irow + 1; icol <= thy numberOfColumns; icol++) { double n11 = 0.0, n22 = 0.0, n12 = 0.0; for (long i = 1; i <= my numberOfRows; i++) { n12 += my data[i][irow] * my data[i][icol]; n11 += my data[i][irow] * my data[i][irow]; n22 += my data[i][icol] * my data[i][icol]; } // probabilities might be very low! if (n12 > 0.0 && n22 > 0.0) { thy data[irow][icol] = thy data[icol][irow] = n12 / sqrt (n11 * n22); } } } thy numberOfObservations = my numberOfRows; return thee; } catch (MelderError) { Melder_throw (me, U": no correlation created."); } } /* End of file ClassificationTable.cpp */ praat-6.0.04/dwtools/ClassificationTable.h000066400000000000000000000031341261542461700204700ustar00rootroot00000000000000#ifndef _ClassificationTable_h_ #define _ClassificationTable_h_ /* ClassificationTable.h * * Copyright (C) 1993-2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "TableOfReal.h" #include "SSCP.h" #include "Confusion.h" #include "Strings_.h" Thing_define (ClassificationTable, TableOfReal) { }; autoClassificationTable ClassificationTable_create (long numberOfRows, long numberOfColumns); autoCategories ClassificationTable_to_Categories_maximumProbability (ClassificationTable me); autoStrings ClassificationTable_to_Strings_maximumProbability (ClassificationTable me); autoConfusion ClassificationTable_to_Confusion (ClassificationTable me, bool onlyClassLabels); /* Correlations between the classes (columns) */ autoCorrelation ClassificationTable_to_Correlation_columns (ClassificationTable me); void Confusion_and_ClassificationTable_increase (Confusion me, ClassificationTable thee); #endif /* _ClassificationTable_h_ */ praat-6.0.04/dwtools/ComplexSpectrogram.cpp000066400000000000000000000245701261542461700207450ustar00rootroot00000000000000/* ComplexSpectrogram.cpp * * Copyright (C) 2014-2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ComplexSpectrogram.h" #include "Sound_and_Spectrum.h" #include "oo_DESTROY.h" #include "ComplexSpectrogram_def.h" #include "oo_COPY.h" #include "ComplexSpectrogram_def.h" #include "oo_EQUAL.h" #include "ComplexSpectrogram_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "ComplexSpectrogram_def.h" #include "oo_WRITE_TEXT.h" #include "ComplexSpectrogram_def.h" #include "oo_WRITE_BINARY.h" #include "ComplexSpectrogram_def.h" #include "oo_READ_TEXT.h" #include "ComplexSpectrogram_def.h" #include "oo_READ_BINARY.h" #include "ComplexSpectrogram_def.h" #include "oo_DESCRIPTION.h" #include "ComplexSpectrogram_def.h" Thing_implement (ComplexSpectrogram, Matrix, 2); autoComplexSpectrogram ComplexSpectrogram_create (double tmin, double tmax, long nt, double dt, double t1, double fmin, double fmax, long nf, double df, double f1) { try { autoComplexSpectrogram me = Thing_new (ComplexSpectrogram); Matrix_init (me.peek(), tmin, tmax, nt, dt, t1, fmin, fmax, nf, df, f1); my phase = NUMmatrix (1, my ny, 1, my nx); return me; } catch (MelderError) { Melder_throw (U"ComplexSpectrogram not created."); } } autoComplexSpectrogram Sound_to_ComplexSpectrogram (Sound me, double windowLength, double timeStep) { try { double samplingFrequency = 1.0 / my dx, myDuration = my xmax - my xmin, t1; if (windowLength > myDuration) { Melder_throw (U"Your sound is too short:\nit should be at least as long as one window length."); } long nsamp_window = (long) floor (windowLength / my dx); long halfnsamp_window = nsamp_window / 2 - 1; nsamp_window = halfnsamp_window * 2; if (nsamp_window < 2) { Melder_throw (U"Your analysis window is too short: less than two samples."); } long numberOfFrames; Sampled_shortTermAnalysis (me, windowLength, timeStep, &numberOfFrames, &t1); // Compute sampling of the spectrum long numberOfFrequencies = halfnsamp_window + 1; double df = samplingFrequency / (numberOfFrequencies - 1); autoComplexSpectrogram thee = ComplexSpectrogram_create (my xmin, my xmax, numberOfFrames, timeStep, t1, 0.0, 0.5 * samplingFrequency, numberOfFrequencies, df, 0.0); // autoSound analysisWindow = Sound_create (1, 0.0, nsamp_window * my dx, nsamp_window, my dx, 0.5 * my dx); for (long iframe = 1; iframe <= numberOfFrames; iframe++) { double t = Sampled_indexToX (thee.peek(), iframe); long leftSample = Sampled_xToLowIndex (me, t), rightSample = leftSample + 1; long startSample = rightSample - halfnsamp_window; long endSample = leftSample + halfnsamp_window; Melder_assert (startSample >= 1); Melder_assert (endSample <= my nx); for (long j = 1; j <= nsamp_window; j++) { analysisWindow -> z[1][j] = my z[1][startSample - 1 + j]; } // window ? autoSpectrum spec = Sound_to_Spectrum (analysisWindow.peek(), 0); thy z[1][iframe] = spec -> z[1][1] * spec -> z[1][1]; thy phase[1][iframe] = 0.0; for (long ifreq = 2; ifreq <= numberOfFrequencies - 1; ifreq++) { double x = spec -> z[1][ifreq], y = spec -> z[2][ifreq]; thy z[ifreq][iframe] = x * x + y * y; // power thy phase[ifreq][iframe] = atan2 (y, x); // phase [-pi,+pi] } // even number of samples thy z[numberOfFrequencies][iframe] = spec -> z[1][numberOfFrequencies] * spec -> z[1][numberOfFrequencies]; thy phase[numberOfFrequencies][iframe] = 0.0; } return thee; } catch (MelderError) { Melder_throw (me, U": no ComplexSpectrogram created."); } } autoSound ComplexSpectrogram_to_Sound (ComplexSpectrogram me, double stretchFactor) { try { /* original number of samples is odd: imaginary part of last spectral value is zero -> * phase is either zero or +/-pi */ double pi = atan2 (0.0, - 0.5); double samplingFrequency = 2.0 * my ymax; double lastFrequency = my y1 + (my ny - 1) * my dy, lastPhase = my phase[my ny][1]; int originalNumberOfSamplesProbablyOdd = (lastPhase != 0.0 && lastPhase != pi && lastPhase != -pi) || my ymax - lastFrequency > 0.25 * my dx; if (my y1 != 0.0) { Melder_throw (U"A Fourier-transformable ComplexSpectrogram must have a first frequency of 0 Hz, not ", my y1, U" Hz."); } long nsamp_window = 2 * my ny - (originalNumberOfSamplesProbablyOdd ? 1 : 2 ); long halfnsamp_window = nsamp_window / 2; double synthesisWindowDuration = nsamp_window / samplingFrequency; autoSpectrum spectrum = Spectrum_create (my ymax, my ny); autoSound synthesisWindow = Sound_createSimple (1, synthesisWindowDuration, samplingFrequency); double newDuration = (my xmax - my xmin) * stretchFactor; autoSound thee = Sound_createSimple (1, newDuration, samplingFrequency); //TODO double thyStartTime; for (long iframe = 1; iframe <= my nx; iframe++) { // "original" sound : double tmid = Sampled_indexToX (me, iframe); long leftSample = Sampled_xToLowIndex (thee.peek(), tmid); long rightSample = leftSample + 1; long startSample = rightSample - halfnsamp_window; double startTime = Sampled_indexToX (thee.peek(), startSample); if (iframe == 1) { thyStartTime = Sampled_indexToX (thee.peek(), startSample); } //long endSample = leftSample + halfnsamp_window; // New Sound with stretch long thyStartSample = Sampled_xToLowIndex (thee.peek(),thyStartTime); double thyEndTime = thyStartTime + my dx * stretchFactor; long thyEndSample = Sampled_xToLowIndex (thee.peek(), thyEndTime); long stretchedStepSizeSamples = thyEndSample - thyStartSample + 1; //double extraTime = (thyStartSample - startSample + 1) * thy dx; double extraTime = (thyStartTime - startTime); spectrum -> z[1][1] = sqrt (my z[1][iframe]); for (long ifreq = 2; ifreq <= my ny; ifreq++) { double f = my y1 + (ifreq - 1) * my dy; double a = sqrt (my z[ifreq][iframe]); double phi = my phase[ifreq][iframe], intPart; double extraPhase = 2.0 * pi * modf (extraTime * f, &intPart); // fractional part phi += extraPhase; spectrum -> z[1][ifreq] = a * cos (phi); spectrum -> z[2][ifreq] = a * sin (phi); } autoSound synthesis = Spectrum_to_Sound (spectrum.peek()); // Where should the sound be placed? long thyEndSampleP = (long) floor (fmin (thyStartSample + synthesis -> nx - 1, thyStartSample + stretchedStepSizeSamples - 1)); // guard against extreme stretches if (iframe == my nx) { thyEndSampleP = (long) floor (fmin (thy nx, thyStartSample + synthesis -> nx - 1)); // ppgb: waarom naar beneden afgerond? } for (long j = thyStartSample; j <= thyEndSampleP; j++) { thy z[1][j] = synthesis -> z[1][j - thyStartSample + 1]; } thyStartTime += my dx * stretchFactor; } return thee; } catch (MelderError) { Melder_throw (me, U": no Sound created."); } } static autoSound ComplexSpectrogram_to_Sound2 (ComplexSpectrogram me, double stretchFactor) { try { /* original number of samples is odd: imaginary part of last spectral value is zero -> * phase is either zero or pi */ double pi = atan2 (0.0, - 0.5); double samplingFrequency = 2.0 * my ymax; double lastFrequency = my y1 + (my ny - 1) * my dy; int originalNumberOfSamplesProbablyOdd = (my phase [my ny][1] != 0.0 && my phase[my ny][1] != pi) || my ymax - lastFrequency > 0.25 * my dx; if (my y1 != 0.0) { Melder_throw (U"A Fourier-transformable Spectrum must have a first frequency of 0 Hz, not ", my y1, U" Hz."); } long numberOfSamples = 2 * my ny - (originalNumberOfSamplesProbablyOdd ? 1 : 2 ); double synthesisWindowDuration = numberOfSamples / samplingFrequency; autoSpectrum spectrum = Spectrum_create (my ymax, my ny); autoSound synthesisWindow = Sound_createSimple (1, synthesisWindowDuration, samplingFrequency); long stepSizeSamples = my dx * samplingFrequency * stretchFactor; double newDuration = (my xmax - my xmin) * stretchFactor + 0.05; autoSound thee = Sound_createSimple (1, newDuration, samplingFrequency); //TODO long istart = 1, iend = istart + stepSizeSamples - 1; for (long iframe = 1; iframe <= my nx; iframe++) { spectrum -> z[1][1] = sqrt (my z[1][iframe]); for (long ifreq = 2; ifreq <= my ny; ifreq++) { double f = my y1 + (ifreq - 1) * my dy; double a = sqrt (my z[ifreq][iframe]); double phi = my phase[ifreq][iframe]; double extraPhase = 2.0 * pi * (stretchFactor - 1.0) * my dx * f; phi += extraPhase; spectrum -> z[1][ifreq] = a * cos (phi); spectrum -> z[2][ifreq] = a * sin (phi); } autoSound synthesis = Spectrum_to_Sound (spectrum.peek()); for (long j = istart; j <= iend; j++) { thy z[1][j] = synthesis -> z[1][j - istart + 1]; } istart = iend + 1; iend = istart + stepSizeSamples - 1; } return thee; } catch (MelderError) { Melder_throw (me, U": no Sound created."); } } autoSpectrogram ComplexSpectrogram_to_Spectrogram (ComplexSpectrogram me) { try { autoSpectrogram thee = Spectrogram_create (my xmin, my xmax, my nx, my dx, my x1, my ymin, my ymax, my ny, my dy, my y1); NUMmatrix_copyElements (my z, thy z, 1, my ny, 1, my nx); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Spectrogram."); } } autoSpectrum ComplexSpectrogram_to_Spectrum (ComplexSpectrogram me, double time) { try { long iframe = Sampled_xToLowIndex (me, time); // ppgb: geen Sampled_xToIndex gebruiken voor integers (afrondingen altijd expliciet maken) iframe = iframe < 1 ? 1 : (iframe > my nx ? my nx : iframe); autoSpectrum thee = Spectrum_create (my ymax, my ny); for (long ifreq = 1; ifreq <= my ny; ifreq++) { double a = sqrt (my z[ifreq][iframe]); double phi = my phase[ifreq][iframe]; thy z[1][ifreq] = a * cos (phi); thy z[2][ifreq] = a * sin (phi); } return thee; } catch (MelderError) { Melder_throw (me, U": no Spectrum created."); } } /* End of file ComplexSpectrogram.cpp */ praat-6.0.04/dwtools/ComplexSpectrogram.h000066400000000000000000000030621261542461700204030ustar00rootroot00000000000000#ifndef _ComplexSpectrogram_h_ #define _ComplexSpectrogram_h_ /* ComplexSpectrogram.h * * Copyright (C) 2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Sound.h" #include "Spectrum.h" #include "Spectrogram.h" #include "ComplexSpectrogram_def.h" oo_CLASS_CREATE (ComplexSpectrogram, Matrix); autoComplexSpectrogram ComplexSpectrogram_create (double tmin, double tmax, long nt, double dt, double t1, double fmin, double fmax, long nf, double df, double f1); autoComplexSpectrogram Sound_to_ComplexSpectrogram (Sound me, double windowLength, double timeStep); /* Hann window because we want to reconstruct */ autoSound ComplexSpectrogram_to_Sound (ComplexSpectrogram me, double stretchFactor); autoSpectrogram ComplexSpectrogram_to_Spectrogram (ComplexSpectrogram me); autoSpectrum ComplexSpectrogram_to_Spectrum (ComplexSpectrogram me, double time); #endif /* _ComplexSpectrogram_h_ */ praat-6.0.04/dwtools/ComplexSpectrogram_def.h000066400000000000000000000017351261542461700212260ustar00rootroot00000000000000/* ComplexSpectrogram_def.h * * Copyright (C) 2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT ComplexSpectrogram oo_DEFINE_CLASS (ComplexSpectrogram, Matrix) oo_DOUBLE_MATRIX (phase, ny, nx) oo_END_CLASS (ComplexSpectrogram) #undef ooSTRUCT /* End of file ComplexSpectrogram_def.h */ praat-6.0.04/dwtools/Configuration.cpp000066400000000000000000000410361261542461700177320ustar00rootroot00000000000000/* Configuration.cpp * * Copyright (C) 1993-2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20010920 +Configuration_getDilationFactor djmw 20020315 GPL header djmw 20030513 applied change in numeric label generation djmw 20030801 Configuration_drawConcentrationEllipses extra argument djmw 20040303 Moved containsPrintableCharacter to NUM2.c djmw 20041026 Removed non-used code. djmw 20050314 Configuration_draw crashed when rowlabel==nullptr djmw 20061021 printf expects %ld for 'long int' djmw 20061212 Changed info to Melder_writeLine format. djmw 20071009 wchar djmw 20071012 Added: o_CAN_WRITE_AS_ENCODING.h djmw 20100302 Extra test in Configuration_rotate djmw 20110304 Thing_new */ #include #include "SVD.h" #include "PCA.h" #include "Configuration.h" #include "Configuration_AffineTransform.h" #include "TableOfReal_extensions.h" #include "SSCP.h" #include "oo_DESTROY.h" #include "Configuration_def.h" #include "oo_COPY.h" #include "Configuration_def.h" #include "oo_EQUAL.h" #include "Configuration_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Configuration_def.h" #include "oo_WRITE_TEXT.h" #include "Configuration_def.h" #include "oo_WRITE_BINARY.h" #include "Configuration_def.h" #include "oo_READ_TEXT.h" #include "Configuration_def.h" #include "oo_READ_BINARY.h" #include "Configuration_def.h" #include "oo_DESCRIPTION.h" #include "Configuration_def.h" Thing_implement (Configuration, TableOfReal, 0); void structConfiguration :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Number of points: ", numberOfRows); MelderInfo_writeLine (U"Number of dimensions: ", numberOfColumns); MelderInfo_writeLine (U"Metric: ", metric); } autoConfiguration Configuration_create (long numberOfPoints, long numberOfDimensions) { try { autoConfiguration me = Thing_new (Configuration); TableOfReal_init (me.peek(), numberOfPoints, numberOfDimensions); my w = NUMvector (1, numberOfDimensions); TableOfReal_setSequentialRowLabels (me.peek(), 0, 0, nullptr, 1, 1); TableOfReal_setSequentialColumnLabels (me.peek(), 0, 0, U"dimension ", 1, 1); my metric = 2; Configuration_setDefaultWeights (me.peek()); Configuration_randomize (me.peek()); return me; } catch (MelderError) { Melder_throw (U"Configuration not created."); } } void Configuration_setMetric (Configuration me, long metric) { my metric = metric; } void Configuration_setDefaultWeights (Configuration me) { for (long i = 1; i <= my numberOfColumns; i++) { my w[i] = 1; } } void Configuration_setSqWeights (Configuration me, const double weight[]) { for (long i = 1; i <= my numberOfColumns; i++) { my w[i] = sqrt (weight[i]); } } void Configuration_normalize (Configuration me, double sumsq, int columns) { TableOfReal_centreColumns (me); if (columns) { sumsq = sumsq <= 0.0 ? 1.0 : sqrt (sumsq); NUMnormalizeColumns (my data, my numberOfRows, my numberOfColumns, sumsq); } else { if (sumsq <= 0.0) { sumsq = my numberOfRows; } NUMnormalize (my data, my numberOfRows, my numberOfColumns, sqrt (sumsq)); } } void Configuration_randomize (Configuration me) { for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= my numberOfColumns; j++) { my data[i][j] = NUMrandomUniform (-1.0, 1.0); } } } void Configuration_rotate (Configuration me, long dimension1, long dimension2, double angle_degrees) { double f = NUMpi * (2.0 - angle_degrees / 180.0); double cosa = cos (f), sina = sin (f); if (dimension1 == dimension2 || angle_degrees == 0) { return; } if (dimension1 > dimension2) { long dt = dimension1; dimension1 = dimension2; dimension2 = dt; } if (dimension1 < 1 || dimension2 > my numberOfColumns) { return; } for (long i = 1; i <= my numberOfRows; i++) { double x1 = my data[i][dimension1], x2 = my data[i][dimension2]; my data[i][dimension1] = cosa * x1 + sina * x2; my data[i][dimension2] = - sina * x1 + cosa * x2; } } void Configuration_invertDimension (Configuration me, int dimension) { if (dimension < 1 || dimension > my numberOfColumns) { return; } for (long i = 1; i <= my numberOfRows; i++) { my data[i][dimension] = - my data[i][dimension]; } } static double NUMsquaredVariance (double **a, long nr, long nc, int rawPowers) { double v4 = 0.0; for (long j = 1; j <= nc; j++) { double sum4 = 0.0, mean = 0.0; for (long i = 1; i <= nr; i++) { double sq = a[i][j] * a[i][j]; sum4 += sq * sq; mean += sq; } v4 += sum4; if (! rawPowers) { v4 -= mean * mean / nr; } } return v4; } /* Varimax rotation, implementation according to: Jos Ten Berge (1995), "Suppressing permutations or rigid planar rotations: a remedy against nonoptimal varimax rotations", Psychometrika 60, 437-446. */ static void NUMvarimax (double **xm, double **ym, long nr, long nc, int normalizeRows, int quartimax, long maximumNumberOfIterations, double tolerance) { Melder_assert (nr > 0 && nc > 0); NUMmatrix_copyElements (xm, ym, 1, nr, 1, nc); if (nc == 1) { return; } if (nc == 2) { maximumNumberOfIterations = 1; } autoNUMvector u (1, nr); autoNUMvector v (1, nr); autoNUMvector norm; // Normalize sum of squares of each row to one. // After rotation we have to rescale. if (normalizeRows) { norm.reset (1, nr); for (long i = 1; i <= nr; i++) { for (long j = 1; j <= nc; j++) { norm[i] += ym[i][j] * ym[i][j]; } if (norm[i] <= 0.0) { continue; } norm[i] = sqrt (norm[i]); for (long j = 1; j <= nc; j++) { ym[i][j] /= norm[i]; } } } // Initial squared "variance". double varianceSq = NUMsquaredVariance (ym, nr, nc, quartimax); if (varianceSq == 0.0) { return; } // Treat columns pairwise. double varianceSq_old; long numberOfIterations = 0; do { for (long c1 = 1; c1 <= nc; c1++) { for (long c2 = c1 + 1; c2 <= nc; c2++) { double um = 0.0, vm = 0.0; for (long i = 1; i <= nr; i++) { double x = ym[i][c1], y = ym[i][c2]; u[i] = x * x - y * y; um += u[i]; v[i] = 2.0 * x * y; vm += v[i]; } um /= nr; vm /= nr; if (quartimax || nr == 1) { um = vm = 0.0; } /* In the paper just before equation (1): a = 2n u'v, b = n(u'u-v'v), c = sqrt(a^2+b^2) w = -sign(a) sqrt((b+c) / 2c) Tricks: multiplication with n drops out! a's multiplication by 2 outside the loop. */ double a = 0.0, b = 0.0; for (long i = 1; i <= nr; i++) { double ui = u[i] - um, vi = v[i] - vm; a += ui * vi; b += ui * ui - vi * vi; } double c = sqrt (4.0 * a * a + b * b); double w = sqrt ( (c + b) / (2.0 * c)); if (a > 0.0) { w = -w; } double cost = sqrt (0.5 + 0.5 * w); double sint = sqrt (0.5 - 0.5 * w); double t22 = cost; double t11 = cost; double t12 = sint; double t21 = -sint; // Prevent permutations: when w < 0, i.e., a > 0, swap columns of T:/ if (w < 0.0) { t11 = sint; t12 = t21 = cost; t22 = -sint; } // Rotate in the plane spanned by c1 and c2. for (long i = 1; i <= nr; i++) { double *xt = ym[i], xtc1 = xt[c1]; xt[c1] = xtc1 * t11 + xt[c2] * t21; xt[c2] = xtc1 * t12 + xt[c2] * t22; } } } numberOfIterations++; varianceSq_old = varianceSq; varianceSq = NUMsquaredVariance (ym, nr, nc, quartimax); } while (fabs (varianceSq_old - varianceSq) / varianceSq_old > tolerance && numberOfIterations < maximumNumberOfIterations); if (normalizeRows) { for (long i = 1; i <= nr; i++) { for (long j = 1; j <= nc; j++) { ym[i][j] *= norm[i]; } } } } autoConfiguration Configuration_varimax (Configuration me, int normalizeRows, int quartimax, long maximumNumberOfIterations, double tolerance) { try { autoConfiguration thee = Data_copy (me); NUMvarimax (my data, thy data, my numberOfRows, my numberOfColumns, normalizeRows, quartimax, maximumNumberOfIterations, tolerance); return thee; } catch (MelderError) { Melder_throw (me, U": varimax rotation not performed."); } } autoConfiguration Configuration_congruenceRotation (Configuration me, Configuration thee, long maximumNumberOfIterations, double tolerance) { try { autoAffineTransform at = Configurations_to_AffineTransform_congruence (me, thee, maximumNumberOfIterations, tolerance); autoConfiguration him = Configuration_and_AffineTransform_to_Configuration (me, at.peek()); return him; } catch (MelderError) { Melder_throw (me, U": congruence rotation not performed."); } } /* Replace by TableOfReal_to_Configuration_pca ??? */ void Configuration_rotateToPrincipalDirections (Configuration me) { try { autoNUMmatrix m (NUMmatrix_copy (my data, 1, my numberOfRows, 1, my numberOfColumns), 1, 1); NUMdmatrix_into_principalComponents (my data, my numberOfRows, my numberOfColumns, my numberOfColumns, m.peek()); NUMvector_free (my data, 1); my data = m.transfer(); } catch (MelderError) { Melder_throw (me, U": not rotated to principal directions."); } } void Configuration_draw (Configuration me, Graphics g, int xCoordinate, int yCoordinate, double xmin, double xmax, double ymin, double ymax, int labelSize, int useRowLabels, const char32 *label, int garnish) { long nPoints = my numberOfRows, numberOfDimensions = my numberOfColumns; if (numberOfDimensions > 1 && (xCoordinate > numberOfDimensions || yCoordinate > numberOfDimensions)) { return; } if (numberOfDimensions == 1) { xCoordinate = 1; } int fontSize = Graphics_inqFontSize (g), noLabel = 0; if (labelSize == 0) { labelSize = fontSize; } autoNUMvector x (1, nPoints); autoNUMvector y (1, nPoints); for (long i = 1; i <= nPoints; i++) { x[i] = my data[i][xCoordinate] * my w[xCoordinate]; y[i] = numberOfDimensions > 1 ? my data[i][yCoordinate] * my w[yCoordinate] : 0.0; } if (xmax <= xmin) { NUMvector_extrema (x.peek(), 1, nPoints, &xmin, &xmax); } if (xmax <= xmin) { xmax += 1.0; xmin -= 1.0; } if (ymax <= ymin) { NUMvector_extrema (y.peek(), 1, nPoints, &ymin, &ymax); } if (ymax <= ymin) { ymax += 1.0; ymin -= 1.0; } Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_setInner (g); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); Graphics_setFontSize (g, labelSize); for (long i = 1; i <= my numberOfRows; i++) { if (x[i] >= xmin && x[i] <= xmax && y[i] >= ymin && y[i] <= ymax) { const char32 *plotLabel = useRowLabels ? my rowLabels[i] : label; if (NUMstring_containsPrintableCharacter (plotLabel)) { Graphics_text (g, x[i], y[i], plotLabel); } else { noLabel++; } } } Graphics_setFontSize (g, fontSize); Graphics_setTextAlignment (g, Graphics_LEFT, Graphics_BOTTOM); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, true, true, false); if (numberOfDimensions > 1) { Graphics_marksLeft (g, 2, true, true, false); if (my columnLabels[xCoordinate]) { Graphics_textBottom (g, true, my columnLabels[xCoordinate]); } if (my columnLabels[yCoordinate]) { Graphics_textLeft (g, true, my columnLabels[yCoordinate]); } } } if (noLabel > 0) { Melder_warning (U"Configuration_draw: ", noLabel, U" from ", my numberOfRows, U" labels are not visible because they are empty or they contain only spaces or they contain only non-printable characters"); } } void Configuration_drawConcentrationEllipses (Configuration me, Graphics g, double scale, int confidence, const char32 *label, long d1, long d2, double xmin, double xmax, double ymin, double ymax, int fontSize, int garnish) { autoSSCPs sscps = TableOfReal_to_SSCPs_byLabel (me); SSCPs_drawConcentrationEllipses (sscps.peek(), g, scale, confidence, label, d1, d2, xmin, xmax, ymin, ymax, fontSize, garnish); } autoConfiguration TableOfReal_to_Configuration (TableOfReal me) { try { autoConfiguration thee = Configuration_create (my numberOfRows, my numberOfColumns); NUMmatrix_copyElements (my data, thy data, 1, my numberOfRows, 1, my numberOfColumns); TableOfReal_copyLabels (me, thee.peek(), 1, 1); return thee; } catch (MelderError) { Melder_throw (me, U": not converted."); } } autoConfiguration TableOfReal_to_Configuration_pca (TableOfReal me, long numberOfDimensions) { try { if (numberOfDimensions < 1 || numberOfDimensions > my numberOfColumns) { numberOfDimensions = my numberOfColumns; } autoPCA pca = TableOfReal_to_PCA (me); autoConfiguration thee = PCA_and_TableOfReal_to_Configuration (pca.peek(), me, numberOfDimensions); return thee; } catch (MelderError) { Melder_throw (me, U": pca not performed."); } } /********************** Examples *********************************************/ autoConfiguration Configuration_createLetterRExample (int choice) { double x1[33] = { 0, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -4, -3, -2, -1, 0, 1, 2.25, 3, 3, 2.25, 1, 0, -1, -2, -3, -4, -1, 0, 1, 2, 3 }; double y1[33] = { 0, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 3.5, 2, 1, -0.5, -1, -1, -1, -1, -1, -1, -2, -3, -4, -5, -6 }; double x2[33] = {0, 0.94756043346272423, 0.73504466902509913, 0.4528453515175927, 0.46311499024105723, 0.30345454816993439, 0.075184942115601547, -0.090010071904764719, -0.19630977381424003, -0.36341509807865086, -0.54216996409132612, -0.68704678013309872, -0.67370169194623086, -0.69336494336440502, -0.67809065144478664, -0.61382610572366281, -0.68656530656078996, -0.57704879646736551, -0.63417502349009069, -0.37153350651419026, -0.091809666009009777, 0.054833807442559397, 0.1445593164362155, 0.055587230806920782, 0.18201798315035453, 0.048445620192953162, 0.081595930742961439, 0.20063623749033621, 0.28546520751183313, 0.39384438699721991, 0.62832258520372286, 0.78548335015622228, 1.0610707888793069 }; double y2[33] = {0, 0.49630791172076621, 0.53320347382055022, 0.62384637225470441, 0.47592708487655661, 0.50364353255684202, 0.55311720162084443, 0.55118713773007066, 0.50007736370068601, 0.40432332354648709, 0.49817059660482677, 0.49803436631629411, 0.33213829258059019, 0.14585700576425648, -0.022110500334692869, -0.1752555003289698, -0.29448744336706828, -0.45639468287493545, -0.59177815505008013, -0.74980550818568981, -0.78095916436791279, -0.64447562732895125, -0.49526830813007033, -0.22443396573313243, -0.066378148077667398, -0.03498490725857361, 0.16196028200653381, 0.30633527000982519, -0.14894460651161745, -0.30808798640907431, -0.35920781945385832, -0.62766325578928184, -0.60389363590825562 }; try { double *x, *y; autoConfiguration me = Configuration_create (32, 2); if (choice == 2) { x = x2; y = y2; Thing_setName (me.peek(), U"R_fit"); } else { x = x1; y = y1; Thing_setName (me.peek(), U"R"); } for (long i = 1; i <= 32; i++) { char32 s[20]; Melder_sprint (s,20, i); TableOfReal_setRowLabel (me.peek(), i, s); my data [i][1] = x[i]; my data [i][2] = y[i]; } return me; } catch (MelderError) { Melder_throw (U"Letter R Configuration not created."); } } autoConfiguration Configuration_createCarrollWishExample () { double x[10] = {0.0, -1.0, 0.0, 1.0, -1.0, 0.0, 1.0, -1.0, 0.0, 1.0}; double y[10] = {0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0}; char32 const *label[] = { U"", U"A", U"B", U"C", U"D", U"E", U"F", U"G", U"H", U"I"}; try { long nObjects = 9; autoConfiguration me = Configuration_create (nObjects, 2); for (long i = 1; i <= nObjects; i++) { my data[i][1] = x[i]; my data[i][2] = y[i]; TableOfReal_setRowLabel (me.peek(), i, label[i]); } return me; } catch (MelderError) { Melder_throw (U"Carroll Wish Configuration not created."); } } /************ CONFIGURATIONS **************************************/ Thing_implement (Configurations, Ordered, 0); autoConfigurations Configurations_create () { try { autoConfigurations me = Thing_new (Configurations); Ordered_init (me.peek(), classConfiguration, 10); return me; } catch (MelderError) { Melder_throw (U"Configurations not created."); } } /* End of file Configuration.cpp */ praat-6.0.04/dwtools/Configuration.h000066400000000000000000000077211261542461700174020ustar00rootroot00000000000000#ifndef _Configuration_h_ #define _Configuration_h_ /* Configuration.h * * Copyright (C) 1992-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Graphics.h" #include "TableOfReal.h" #include "Collection.h" #include "Configuration_def.h" oo_CLASS_CREATE (Configuration, TableOfReal); autoConfiguration Configuration_create (long numberOfPoints, long numberOfDimensions); void Configuration_setMetric (Configuration me, long metric); void Configuration_setDefaultWeights (Configuration me); /* All w[i] = 1 */ void Configuration_setSqWeights (Configuration me, const double weight[]); /* All w[i] = sqrt (weight[i]) */ void Configuration_randomize (Configuration me); /* new x[i][j] = randomUniform (-1,1) */ void Configuration_normalize (Configuration me, double variance, int choice); /* 1. centre columns 2. choice == !0 : each column == 0 : normalize matrix */ void Configuration_rotate (Configuration me, long dimension1, long dimension2, double angle_degrees); /* Precondition: dimension1 != dimension2 1 <= dimension1, dimension2 <= my numberOfColumns */ void Configuration_invertDimension (Configuration me, int dimension); /* Function: Invert one dimension. for (i=1; i <= my numberOfRows; i++) my data[i][dimension] = - my data[i][dimension]; */ autoConfiguration Configuration_congruenceRotation (Configuration me, Configuration thee, long maximumNumberOfIterations, double tolerance); /* Rotate thee for maximum congruence. Algorithm: Henk Kiers & Patrick Groenen (1996), "A monotonically convergent algorithm for orthogonal congruence rotation", Psychometrika 61, 375-389. */ autoConfiguration Configuration_varimax (Configuration me, int normalizeRows, int quartimax, long maximumNumberOfIterations, double tolerance); /* Perform varimax rotation. Algorithm with extra security from: Jos Ten Berge (1995), "Suppressing permutations or rigid planar rotations: a remedy against nonoptimal varimax rotations", Psychometrika 60, 437-446. */ void Configuration_rotateToPrincipalDirections (Configuration me); void Configuration_draw (Configuration me, Graphics g, int xCoordinate, int yCoordinate, double xmin, double xmax, double ymin, double ymax, int labelSize, int useRowLabels, const char32 *label, int garnish); void Configuration_drawConcentrationEllipses (Configuration me, Graphics g, double scale, int confidence, const char32 *label, long d1, long d2, double xmin, double xmax, double ymin, double ymax, int fontSize, int garnish); autoConfiguration TableOfReal_to_Configuration (TableOfReal me); autoConfiguration TableOfReal_to_Configuration_pca (TableOfReal me, long numberOfDimensions); /* Precondition: numberOfDimensions > 0 Function: principal component analysis Postcondition: (Configuration) numberOfColumns = MIN (my numberOfColumns, numberOfDimensions) */ autoConfiguration Configuration_createLetterRExample (int choice); /* Create a two-dimensional configuartion from the letter R. choice = 1 : undistorted; choice = 2 : result of monotone fit on distorted (d^2 + 5 +32.5*z) */ autoConfiguration Configuration_createCarrollWishExample (); /************************** class Configurations **************************************/ Thing_define (Configurations, Ordered) { }; autoConfigurations Configurations_create (); #endif /* _Configuration_h_ */ praat-6.0.04/dwtools/Configuration_AffineTransform.cpp000066400000000000000000000125751261542461700231040ustar00rootroot00000000000000/* Configuration_AffineTransform.cpp * * Copyright (C) 1993-2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020315 GPL header */ #include "Configuration_AffineTransform.h" #include "Configuration_and_Procrustes.h" #include "Procrustes.h" #include "SVD.h" #undef your #define your ((AffineTransform_Table) thy methods) -> static void do_steps45 (double **w, double **t, double **c, long n, double *f) { // Step 4 || 10: If W'T has negative diagonal elements, multiply corresponding columns in T by -1. for (long i = 1; i <= n; i++) { double d = 0.0; for (long k = 1; k <= n; k++) { d += w[k][i] * t[k][i]; } if (d < 0.0) { for (long k = 1; k <= n; k++) { t[k][i] = -t[k][i]; } } } // Step 5 & 11: f = tr W'T (Diag (T'CT))^-1/2 *f = 0.0; for (long i = 1; i <= n; i++) { double d = 0.0, tct = 0.0; for (long k = 1; k <= n; k++) { d += w[k][i] * t[k][i]; for (long j = 1; j <= n; j++) { tct += t[k][i] * c[k][j] * t[j][i]; } } if (tct > 0.0) { *f += d / sqrt (tct); } } } static void NUMmaximizeCongruence (double **b, double **a, long nr, long nc, double **t, long maximumNumberOfIterations, double tolerance) { long numberOfIterations = 0; Melder_assert (nr > 0 && nc > 0); Melder_assert (t); if (nc == 1) { t[1][1] = 1; return; } autoNUMmatrix c (1, nc, 1, nc); autoNUMmatrix w (1, nc, 1, nc); autoNUMmatrix u (1, nc, 1, nc); autoNUMvector evec (1, nc); autoSVD svd = SVD_create (nc, nc); // Steps 1 & 2: C = A'A and W = A'B double checkc = 0, checkw = 0; for (long i = 1; i <= nc; i++) { for (long j = 1; j <= nc; j++) { for (long k = 1; k <= nr; k++) { c[i][j] += a[k][i] * a[k][j]; w[i][j] += a[k][i] * b[k][j]; } checkc += c[i][j]; checkw += w[i][j]; } } if (checkc == 0.0 || checkw == 0.0) { Melder_throw (U"NUMmaximizeCongruence: we cannot rotate a zero matrix."); } // Scale W by (diag(B'B))^-1/2 for (long j = 1; j <= nc; j++) { double scale = 0.0; for (long k = 1; k <= nr; k++) { scale += b[k][j] * b[k][j]; } if (scale > 0.0) { scale = 1.0 / sqrt (scale); } for (long i = 1; i <= nc; i++) { w[i][j] *= scale; } } // Step 3: largest eigenvalue of C evec[1] = 1.0; double rho, f, f_old; NUMdominantEigenvector (c.peek(), nc, evec.peek(), &rho, 1.0e-6); do_steps45 (w.peek(), t, c.peek(), nc, &f); do { for (long j = 1; j <= nc; j++) { // Step 7.a double p = 0.0; for (long k = 1; k <= nc; k++) { for (long i = 1; i <= nc; i++) { p += t[k][j] * c[k][i] * t[i][j]; } } // Step 7.b double q = 0.0; for (long k = 1; k <= nc; k++) { q += w[k][j] * t[k][j]; } // Step 7.c if (q == 0.0) { for (long i = 1; i <= nc; i++) { u[i][j] = 0.0; } } else { double ww = 0.0; for (long k = 1; k <= nc; k++) { ww += w[k][j] * w[k][j]; } for (long i = 1; i <= nc; i++) { double ct = 0.0; for (long k = 1; k <= nc; k++) { ct += c[i][k] * t[k][j]; } u[i][j] = (q * (ct - rho * t[i][j]) / p - 2.0 * ww * t[i][j] / q - w[i][j]) / sqrt (p); } } } // Step 8 SVD_svd_d (svd.peek(), u.peek()); // Step 9 for (long i = 1; i <= nc; i++) { for (long j = 1; j <= nc; j++) { t[i][j] = 0.0; for (long k = 1; k <= nc; k++) { t[i][j] -= svd -> u[i][k] * svd -> v[j][k]; } } } numberOfIterations++; f_old = f; // Steps 10 & 11 equal steps 4 & 5 do_steps45 (w.peek(), t, c.peek(), nc, &f); } while (fabs (f_old - f) / f_old > tolerance && numberOfIterations < maximumNumberOfIterations); } autoAffineTransform Configurations_to_AffineTransform_congruence (Configuration me, Configuration thee, long maximumNumberOfIterations, double tolerance) { try { // Use Procrustes transform to obtain starting configuration. // (We only need the transformation matrix T.) autoProcrustes p = Configurations_to_Procrustes (me, thee, 0); NUMmaximizeCongruence (my data, thy data, my numberOfRows, p -> n, p -> r, maximumNumberOfIterations, tolerance); autoAffineTransform at = AffineTransform_create (p -> n); NUMmatrix_copyElements (p -> r, at -> r, 1, p -> n, 1, p -> n); return at; } catch (MelderError) { Melder_throw (me, U": no congruence transformation created."); } } autoConfiguration Configuration_and_AffineTransform_to_Configuration (Configuration me, AffineTransform thee) { try { if (my numberOfColumns != thy n) { Melder_throw (U"Dimensions do not agree."); } autoConfiguration him = (Configuration) Data_copy (me); // Apply transformation YT thy v_transform (my data, my numberOfRows, his data); return him; } catch (MelderError) { Melder_throw (U"Configuration not created."); } } /* End of file Configuration_AffineTransform.cpp */ praat-6.0.04/dwtools/Configuration_AffineTransform.h000066400000000000000000000024471261542461700225460ustar00rootroot00000000000000#ifndef _Configuration_AffineTransform_h_ #define _Configuration_AffineTransform_h_ /* Configuration_AffineTransform.c * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020315 GPL header djmw 20110307 Latest modification */ #include "Configuration.h" #include "AffineTransform.h" autoAffineTransform Configurations_to_AffineTransform_congruence (Configuration me, Configuration thee, long maximumNumberOfIterations, double tolerance); autoConfiguration Configuration_and_AffineTransform_to_Configuration (Configuration me, AffineTransform thee); #endif /* _Configuration_AffineTransform_h_ */ praat-6.0.04/dwtools/Configuration_and_Procrustes.cpp000066400000000000000000000033131261542461700230010ustar00rootroot00000000000000/* Configuration_and_Procrustes.c * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020424 GPL djmw 20020704 Changed header NUMclasses.h to SVD.h djmw 20041022 Added orthogonal argument to Configurations_to_Procrustes. */ #include "Configuration_and_Procrustes.h" #include "NUM2.h" autoProcrustes Configurations_to_Procrustes (Configuration me, Configuration thee, int orthogonal) { try { if (my numberOfRows != thy numberOfRows || my numberOfColumns != thy numberOfColumns) { Melder_throw (U"Configurations must have the same number of points and the same dimension."); } autoProcrustes p = Procrustes_create (my numberOfColumns); double *translation = 0, *scale = 0; if (! orthogonal) { translation = p -> t; scale = & (p -> s); } NUMProcrustes (my data, thy data, my numberOfRows, my numberOfColumns, p -> r, translation, scale); return p; } catch (MelderError) { Melder_throw (U"Procrustes from two Configurations not created."); } } /* End of file Configuration_and_Procrustes.c */ praat-6.0.04/dwtools/Configuration_and_Procrustes.h000066400000000000000000000022641261542461700224520ustar00rootroot00000000000000#ifndef _Configuration_and_Procrustes_h_ #define _Configuration_and_Procrustes_h_ /* Configuration_and_Procrustes.h * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header djmw 20110307 Latest modification. */ #ifndef _Configuration_h_ #include "Configuration.h" #endif #ifndef _Procrustes_h_ #include "Procrustes.h" #endif autoProcrustes Configurations_to_Procrustes (Configuration me, Configuration thee, int orthogonal); #endif /* _Configuration_and_Procrustes_h_ */ praat-6.0.04/dwtools/Configuration_def.h000066400000000000000000000020341261542461700202100ustar00rootroot00000000000000/* Configuration_def.h * * Copyright (C) 1993-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT Configuration oo_DEFINE_CLASS (Configuration, TableOfReal) oo_LONG (metric) oo_DOUBLE_VECTOR (w, numberOfColumns) #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (Configuration) #undef ooSTRUCT /* End of file Configuration_def.h */ praat-6.0.04/dwtools/Confusion.cpp000066400000000000000000000456311261542461700170730ustar00rootroot00000000000000/* Confusion.cpp * * Copyright (C) 1993-2011, 2014, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20010628 djmw 20020813 GPL header djmw 20061214 Changed info to Melder_writeLine format. djmw 20070620 Latest modification. djmw 20080521 +Confusion_drawAsNumbers djmw 20110304 Thing_new djmw 20111110 Use autostringvector */ #include "Confusion.h" #include "Polygon_extensions.h" #include "Matrix_extensions.h" #include "TableOfReal_extensions.h" #include "Collection_extensions.h" #include "Distributions_and_Strings.h" #include "NUM2.h" Thing_implement (Confusion, TableOfReal, 0); void structConfusion :: v_info () { double h, hx, hy, hygx, hxgy, uygx, uxgy, uxy, frac; long nCorrect; Confusion_getEntropies (this, & h, & hx, & hy, & hygx, & hxgy, & uygx, & uxgy, & uxy); Confusion_getFractionCorrect (this, & frac, & nCorrect); MelderInfo_writeLine (U"Number of rows: ", numberOfRows); MelderInfo_writeLine (U"Number of colums: ", numberOfColumns); MelderInfo_writeLine (U"Entropies (y is row variable):"); MelderInfo_writeLine (U" Total: ", h); MelderInfo_writeLine (U" Y: ", hy); MelderInfo_writeLine (U" X: ", hx); MelderInfo_writeLine (U" Y given x: ", hygx); MelderInfo_writeLine (U" X given y: ", hxgy); MelderInfo_writeLine (U" Dependency of y on x; ", uygx); MelderInfo_writeLine (U" Dependency of x on y: ", uxgy); MelderInfo_writeLine (U" Symmetrical dependency: ", uxy); MelderInfo_writeLine (U" Total number of entries: ", Confusion_getNumberOfEntries (this)); MelderInfo_writeLine (U" Fraction correct: ", frac); } autoConfusion Confusion_createFromStringses (Strings me, Strings thee) { try { if (my numberOfStrings < 1 || thy numberOfStrings < 1) { Melder_throw (U"Empty Strings."); } autoConfusion him = Confusion_create (my numberOfStrings, thy numberOfStrings); for (long irow = 1; irow <= my numberOfStrings; irow++) { const char32 *label = my strings[irow]; TableOfReal_setRowLabel (him.peek(), irow, label); } for (long icol = 1; icol <= thy numberOfStrings; icol++) { const char32 *label = thy strings[icol]; TableOfReal_setColumnLabel (him.peek(), icol, label); } return him; } catch (MelderError) { Melder_throw (me, U": could not create Confusion with ", thee); } } autoConfusion Confusion_create (long numberOfStimuli, long numberOfResponses) { try { autoConfusion me = Thing_new (Confusion); TableOfReal_init (me.peek(), numberOfStimuli, numberOfResponses); return me; } catch (MelderError) { Melder_throw (U"Confusion not created."); } } autoConfusion Confusion_createSimple (const char32 *labels) { try { long numberOfLabels = Melder_countTokens (labels); if (numberOfLabels < 1) { Melder_throw (U"Not enough labels."); } autoConfusion me = Confusion_create (numberOfLabels, numberOfLabels); long ilabel = 1; for (char32 *token = Melder_firstToken (labels); token != 0; token = Melder_nextToken ()) { for (long i = 1; i <= ilabel - 1; i++) { if (Melder_cmp (token, my rowLabels[i]) == 0) { Melder_throw (U"Label ", i, U"and ", ilabel, U"may not be equal."); } } TableOfReal_setRowLabel (me.peek(), ilabel, token); TableOfReal_setColumnLabel (me.peek(), ilabel, token); ilabel++; } return me; } catch (MelderError) { Melder_throw (U"Simple Confusion not created."); } } autoConfusion Categories_to_Confusion (Categories me, Categories thee) { try { if (my size != thy size) { Melder_throw (U"Categories_to_Confusion: dimensions do not agree."); } autoCategories ul1 = Categories_selectUniqueItems (me, 1); autoCategories ul2 = Categories_selectUniqueItems (thee, 1); autoConfusion him = Confusion_create (ul1 -> size, ul2 -> size); for (long i = 1; i <= ul1 -> size; i++) { SimpleString s = (SimpleString) ul1 -> item[i]; TableOfReal_setRowLabel (him.peek(), i, s -> string); } for (long i = 1; i <= ul2 -> size; i++) { SimpleString s = (SimpleString) ul2 -> item[i]; TableOfReal_setColumnLabel (him.peek(), i, s -> string); } for (long i = 1; i <= my size; i++) { SimpleString myi = (SimpleString) my item[i], thyi = (SimpleString) thy item[i]; Confusion_increase (him.peek(), SimpleString_c (myi), SimpleString_c (thyi)); } return him; } catch (MelderError) { Melder_throw (me, U": no Confusion created."); } } #define TINY 1.0e-30 void Confusion_getEntropies (Confusion me, double *h, double *hx, double *hy, double *hygx, double *hxgy, double *uygx, double *uxgy, double *uxy) { *h = *hx = *hy = *hxgy = *hygx = *uygx = *uxgy = *uxy = 0.0; autoNUMvector rowSum (1, my numberOfRows); autoNUMvector colSum (1, my numberOfColumns); double sum = 0.0; for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= my numberOfColumns; j++) { rowSum[i] += my data[i][j]; colSum[j] += my data[i][j]; sum += my data[i][j]; } } for (long i = 1; i <= my numberOfRows; i++) { if (rowSum[i] > 0.0) { *hy -= rowSum[i] / sum * NUMlog2 (rowSum[i] / sum); } } for (long j = 1; j <= my numberOfColumns; j++) { if (colSum[j] > 0.0) { *hx -= colSum[j] / sum * NUMlog2 (colSum[j] / sum); } } for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= my numberOfColumns; j++) { if (my data[i][j] > 0.0) { *h -= my data[i][j] / sum * NUMlog2 (my data[i][j] / sum); } } } *hygx = *h - *hx; *hxgy = *h - *hy; *uygx = (*hy - *hygx) / (*hy + TINY); *uxgy = (*hx - *hxgy) / (*hx + TINY); *uxy = 2.0 * (*hx + *hy - *h) / (*hx + *hy + TINY); } void Confusion_increase (Confusion me, const char32 *stim, const char32 *resp) { try { long stimIndex = TableOfReal_rowLabelToIndex (me, stim); if (stimIndex < 1) { Melder_throw (U"Stimulus not valid."); } long respIndex = TableOfReal_columnLabelToIndex (me, resp); if (respIndex < 1) { Melder_throw (U"Response not valid."); } my data[stimIndex][respIndex] += 1.0; } catch (MelderError) { Melder_throw (me, U": not increased."); } } double Confusion_getValue (Confusion me, const char32 *stim, const char32 *resp) { long stimIndex = TableOfReal_rowLabelToIndex (me, stim); if (stimIndex < 1) { Melder_throw (U"Stimulus not valid."); } long respIndex = TableOfReal_columnLabelToIndex (me, resp); if (respIndex < 1) { Melder_throw (U"Response not valid."); } return my data[stimIndex][respIndex]; } void Confusion_getFractionCorrect (Confusion me, double *fraction, long *numberOfCorrect) { *fraction = NUMundefined; *numberOfCorrect = -1; double c = 0.0, ct = 0.0; for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= my numberOfColumns; j++) { if (! my rowLabels[i] || ! my columnLabels[j]) { return; } ct += my data[i][j]; if (str32cmp (my rowLabels[i], my columnLabels[j]) == 0) { c += my data[i][j]; } } } if (ct != 0.0) { *fraction = c / ct; } *numberOfCorrect = (long) floor (c); } /*************** Confusion_Matrix_draw ****************************************/ #define NPOINTS 6 static autoPolygon Polygon_createPointer () { try { double x[NPOINTS + 1] = { 0.0, 0.0, 0.9, 1.0, 0.9, 0.0, 0.0 }; double y[NPOINTS + 1] = { 0.0, 0.0, 0.0, 0.5, 1.0, 1.0, 0.0 }; autoPolygon me = Polygon_create (NPOINTS); for (long i = 1; i <= NPOINTS; i++) { my x[i] = x[i]; my y[i] = y[i]; } return me; } catch (MelderError) { Melder_throw (U"Polygon not created."); } } static void Polygon_drawInside (Polygon me, Graphics g) { Graphics_polyline (g, my numberOfPoints, & my x[1], & my y[1]); } void Confusion_Matrix_draw (Confusion me, Matrix thee, Graphics g, long index, double lowerPercentage, double xmin, double xmax, double ymin, double ymax, int garnish) { long ib = 1, ie = my numberOfRows; if (index > 0 && index <= my numberOfColumns) { ib = ie = index; } if (thy ny != my numberOfRows) { Melder_throw (U"Wrong number of positions."); } if (xmax <= xmin) { (void) Matrix_getWindowExtrema (thee, 1, 1, 1, thy ny, &xmin, &xmax); } if (xmax <= xmin) { return; } if (ymax <= ymin) { (void) Matrix_getWindowExtrema (thee, 2, 2, 1, thy ny, &ymin, &ymax); } if (ymax <= ymin) { return; } double rmax = fabs (xmax - xmin) / 10.0; double rmin = rmax / 10; Graphics_setInner (g); Graphics_setWindow (g, xmin - rmax, xmax + rmax, ymin - rmax, ymax + rmax); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); for (long i = 1; i <= my numberOfRows; i++) { Graphics_text (g, thy z[i][1], thy z[i][2], my rowLabels[i]); } for (long i = ib; i <= ie; i++) { double xSum = 0.0; for (long j = 1; j <= my numberOfColumns; j++) { xSum += my data[i][j]; } if (xSum <= 0.0) { continue; /* no confusions */ } double x1 = thy z[i][1]; double y1 = thy z[i][2]; double r = rmax * my data[i][i] / xSum; Graphics_circle (g, x1, y1, r > rmin ? r : rmin); for (long j = 1; j <= my numberOfColumns; j++) { double x2 = thy z[j][1], y2 = thy z[j][2]; double perc = 100.0 * my data[i][j] / xSum; double dx = x2 - x1, dy = y2 - y1; double alpha = atan2 (dy, dx); if (perc == 0.0 || perc < lowerPercentage || j == i) { continue; } xmin = x1; xmax = x2; if (x2 < x1) { xmin = x2; xmax = x1; } ymin = y1; xmax = y2; if (y2 < y1) { ymin = y2; ymax = y1; } autoPolygon p = Polygon_createPointer(); double xs = sqrt (dx * dx + dy * dy) - 2.2 * r; if (xs < 0.0) { xs = 0.0; } double ys = perc * rmax / 100.0; Polygon_scale (p.peek(), xs, ys); Polygon_translate (p.peek(), x1, y1 - ys / 2); Polygon_rotate (p.peek(), alpha, x1, y1); Polygon_translate (p.peek(), 1.1 * r * cos (alpha), 1.1 * r * sin (alpha)); Polygon_drawInside (p.peek(), g); } } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, true, true, false); if (ymin * ymax < 0.0) { Graphics_markLeft (g, 0.0, true, true, true, nullptr); } Graphics_marksLeft (g, 2, true, true, false); if (xmin * xmax < 0.0) { Graphics_markBottom (g, 0.0, true, true, true, nullptr); } } } autoMatrix Confusion_difference (Confusion me, Confusion thee) { try { /* categories must be the same too*/ if (my numberOfColumns != thy numberOfColumns || my numberOfRows != thy numberOfRows) { Melder_throw (U"Dimensions not equal."); } autoMatrix him = Matrix_create (0.5, my numberOfColumns + 0.5, my numberOfColumns, 1.0, 1.0, 0.5, my numberOfRows + 0.5, my numberOfRows, 1.0, 1.0); for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= my numberOfColumns; j++) { his z[i][j] = my data[i][j] - thy data[i][j]; } } return him; } catch (MelderError) { Melder_throw (U"Matrix not created from two Confusions."); } } long Confusion_getNumberOfEntries (Confusion me) { double total = 0.0; for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= my numberOfColumns; j++) { total += my data[i][j]; } } return (long) floor (total); } static void create_index (char32 **s, long sb, long se, char32 **ref, long rb, long re, long *index) { for (long i = sb; i <= se; i++) { long indxj = 0; for (long j = rb; j <= re; j++) { if (str32equ (s[i], ref[j])) { indxj = j; break; } } index[i] = indxj; } } autoConfusion Confusion_condense (Confusion me, const char32 *search, const char32 *replace, long maximumNumberOfReplaces, int use_regexp) { try { long nmatches, nstringmatches; if (my rowLabels == 0 || my columnLabels == 0) { Melder_throw (U"No row or column labels."); } autostring32vector rowLabels (strs_replace (my rowLabels, 1, my numberOfRows, search, replace, maximumNumberOfReplaces, &nmatches, &nstringmatches, use_regexp), 1, my numberOfRows); autostring32vector columnLabels (strs_replace (my columnLabels, 1, my numberOfColumns, search, replace, maximumNumberOfReplaces, &nmatches, &nstringmatches, use_regexp), 1, my numberOfColumns); autoStrings srow = Thing_new (Strings); srow -> numberOfStrings = my numberOfRows; srow -> strings = rowLabels.transfer(); autoStrings scol = Thing_new (Strings); scol -> numberOfStrings = my numberOfColumns; scol -> strings = columnLabels.transfer(); /* Find dimension of new Confusion */ autoDistributions dcol = Strings_to_Distributions (scol.peek()); long nresp = dcol -> numberOfRows; autoDistributions drow = Strings_to_Distributions (srow.peek()); long nstim = drow -> numberOfRows; autoConfusion thee = Confusion_create (nstim, nresp); NUMstrings_copyElements (drow -> rowLabels, thy rowLabels, 1, nstim); NUMstrings_copyElements (dcol -> rowLabels, thy columnLabels, 1, nresp); autoNUMvector rowIndex (1, my numberOfRows); create_index (srow -> strings, 1, my numberOfRows, drow -> rowLabels, 1, nstim, rowIndex.peek()); autoNUMvector columnIndex (1, my numberOfColumns); create_index (scol -> strings, 1, my numberOfColumns, dcol -> rowLabels, 1, nresp, columnIndex.peek()); for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= my numberOfColumns; j++) { thy data [rowIndex [i]][columnIndex[j]] += my data[i][j]; } } return thee; } catch (MelderError) { Melder_throw (me, U": not condensed."); } } autoConfusion TableOfReal_to_Confusion (TableOfReal me) { try { if (! TableOfReal_checkPositive (me)) { Melder_throw (U"Elements may not be less than zero."); } autoConfusion thee = Thing_new (Confusion); my structTableOfReal :: v_copy (thee.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Confusion."); } } autoConfusion Confusion_group (Confusion me, const char32 *labels, const char32 *newLabel, long newpos) { try { autoConfusion stim = Confusion_groupStimuli (me, labels, newLabel, newpos); autoConfusion thee = Confusion_groupResponses (stim.peek(), labels, newLabel, newpos); return thee; } catch (MelderError) { Melder_throw (me, U": not grouped."); } } autoConfusion Confusion_groupStimuli (Confusion me, const char32 *labels, const char32 *newLabel, long newpos) { try { long ncondense = Melder_countTokens (labels); autoNUMvector irow (1, my numberOfRows); for (long i = 1; i <= my numberOfRows; i++) { irow[i] = i; } for (char32 *token = Melder_firstToken (labels); token != nullptr; token = Melder_nextToken ()) { for (long i = 1; i <= my numberOfRows; i++) { if (Melder_equ (token, my rowLabels[i])) { irow[i] = 0; break; } } } long nfound = 0; for (long i = 1; i <= my numberOfRows; i++) { if (irow[i] == 0) { nfound ++; } } if (nfound == 0) { Melder_throw (U"Invalid stimulus labels."); } if (nfound != ncondense) { Melder_warning (U"One or more of the given stimulus labels are suspect."); } long newnstim = my numberOfRows - nfound + 1; if (newpos < 1) { newpos = 1; } if (newpos > newnstim) { newpos = newnstim; } autoConfusion thee = Confusion_create (newnstim, my numberOfColumns); NUMstrings_copyElements (my columnLabels, thy columnLabels, 1, my numberOfColumns); TableOfReal_setRowLabel (thee.peek(), newpos, newLabel); long inewrow = 1; for (long i = 1; i <= my numberOfRows; i++) { long rowpos = newpos; if (irow[i] > 0) { if (inewrow == newpos) { inewrow++; } rowpos = inewrow; inewrow++; TableOfReal_setRowLabel (thee.peek(), rowpos, my rowLabels[i]); } for (long j = 1; j <= my numberOfColumns; j++) { thy data[rowpos][j] += my data[i][j]; } } return thee; } catch (MelderError) { Melder_throw (me, U": stimuli not grouped."); } } autoConfusion Confusion_groupResponses (Confusion me, const char32 *labels, const char32 *newLabel, long newpos) { try { long ncondense = Melder_countTokens (labels); autoNUMvector icol (1, my numberOfColumns); for (long i = 1; i <= my numberOfColumns; i++) { icol[i] = i; } for (char32 *token = Melder_firstToken (labels); token != 0; token = Melder_nextToken ()) { for (long i = 1; i <= my numberOfColumns; i++) { if (Melder_equ (token, my columnLabels[i])) { icol[i] = 0; break; } } } long nfound = 0; for (long i = 1; i <= my numberOfColumns; i++) { if (icol[i] == 0) { nfound ++; } } if (nfound == 0) { Melder_throw (U"Invalid response labels."); } if (nfound != ncondense) { Melder_warning (U"One or more of the given response labels are suspect."); } long newnresp = my numberOfColumns - nfound + 1; if (newpos < 1) { newpos = 1; } if (newpos > newnresp) { newpos = newnresp; } autoConfusion thee = Confusion_create (my numberOfRows, newnresp); NUMstrings_copyElements (my rowLabels, thy rowLabels, 1, my numberOfRows); TableOfReal_setColumnLabel (thee.peek(), newpos, newLabel); long inewcol = 1; for (long i = 1; i <= my numberOfColumns; i++) { long colpos = newpos; if (icol[i] > 0) { if (inewcol == newpos) { inewcol++; } colpos = inewcol; inewcol++; TableOfReal_setColumnLabel (thee.peek(), colpos, my columnLabels[i]); } for (long j = 1; j <= my numberOfRows; j++) { thy data[j][colpos] += my data[j][i]; } } return thee; } catch (MelderError) { Melder_throw (me, U": responses not grouped."); } } autoTableOfReal Confusion_to_TableOfReal_marginals (Confusion me) { try { autoTableOfReal thee = TableOfReal_create (my numberOfRows + 1, my numberOfColumns + 1); double total = 0.0; for (long i = 1; i <= my numberOfRows; i++) { double rowsum = 0.0; for (long j = 1; j <= my numberOfColumns; j++) { thy data[i][j] = my data[i][j]; rowsum += my data[i][j]; } thy data[i][my numberOfColumns + 1] = rowsum; total += rowsum; } thy data[my numberOfRows + 1][my numberOfColumns + 1] = total; for (long j = 1; j <= my numberOfColumns; j++) { double colsum = 0; for (long i = 1; i <= my numberOfRows; i++) { colsum += my data[i][j]; } thy data[my numberOfRows + 1][j] = colsum; } NUMstrings_copyElements (my rowLabels, thy rowLabels, 1, my numberOfRows); NUMstrings_copyElements (my columnLabels, thy columnLabels, 1, my numberOfColumns); return thee; } catch (MelderError) { Melder_throw (me, U": table with marginals not created."); } } void Confusion_drawAsNumbers (Confusion me, Graphics g, int marginals, int iformat, int precision) { TableOfReal thee = me; autoTableOfReal athee; if (marginals) { athee = Confusion_to_TableOfReal_marginals (me); thee = athee.peek(); } TableOfReal_drawAsNumbers (thee, g, 1, thy numberOfRows, iformat, precision); } /* End of file Confusion.cpp */ praat-6.0.04/dwtools/Confusion.h000066400000000000000000000075211261542461700165340ustar00rootroot00000000000000#ifndef _Confusion_h_ #define _Confusion_h_ /* Confusion.h * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "TableOfReal.h" #include "Categories.h" #include "Graphics.h" #include "Matrix.h" Thing_define (Confusion, TableOfReal) { void v_info () override; }; /* A Confusion matrix has both row and column labels. */ autoConfusion Confusion_create (long numberOfStimuli, long numberOfResponses); autoConfusion Confusion_createSimple (const char32 *labels); autoConfusion Confusion_createFromStringses (Strings stimulusLabels, Strings responseLabels); autoConfusion Categories_to_Confusion (Categories me, Categories thee); void Confusion_increase (Confusion me, const char32 *stimulus, const char32 *response); /* data['stim']['resp'] += 1; */ double Confusion_getValue (Confusion me, const char32 *stim, const char32 *resp); /* data['stim']['resp'] ; */ void Confusion_getEntropies (Confusion me, double *h, double *hx, double *hy, double *hygx, double *hxgy, double *uygx, double *uxgy, double *uxy); /* x is column variable, y is row variable * *h entropy of whole table; * *hx entropy of x variable * *hy entropy of y variable * *hygx entropy of y given x * *hxgy entropy of x given y * *uygx dependency of y on x * *uxgy dependency of x on y * *uxy symmetrical dependency */ void Confusion_getFractionCorrect (Confusion me, double *fraction, long *numberOfCorrect); void Confusion_Matrix_draw (Confusion me, Matrix thee, Graphics g, long index, double lowerPercentage, double xmin, double xmax, double ymin, double ymax, int garnish); /* 1. Draw my rowLabels centered at ( matrix->z[i][1], matrix->z[i][2]). * 2. Draw arrows and circles according to: * for (i=1; i <= my numberOfRows; i++) * { * if (index != 0 && index != i) continue; * draw circle at i of width: my z[i][i]/rowSum; * for (j=1; j <= my numberOfColumns; j++) * { * if (i != j && 100*my data[i][j]/rowSum > lowerPercentage) * draw arrow from i to j of width: my data[i][j]/rowSum; * } * } */ autoMatrix Confusion_difference (Confusion me, Confusion thee); /* return matrix with the difference between the two confusion matrices */ long Confusion_getNumberOfEntries (Confusion me); autoConfusion Confusion_groupStimuli (Confusion me, const char32 *labels, const char32 *newLabel, long newpos); autoConfusion Confusion_groupResponses (Confusion me, const char32 *labels, const char32 *newLabel, long newpos); autoConfusion Confusion_group (Confusion me, const char32 *labels, const char32 *newLabel, long newpos); autoConfusion Confusion_condense (Confusion me, const char32 *search, const char32 *replace, long maximumNumberOfReplaces, int use_regexp); /* Group row and column labels according to search and replace. */ autoConfusion TableOfReal_to_Confusion (TableOfReal me); autoTableOfReal Confusion_to_TableOfReal_marginals (Confusion me); /* Create a table with one extra row and one extra column with marginals, i.e., column and row sums. */ void Confusion_drawAsNumbers (Confusion me, Graphics g, int marginals, int iformat, int precision); // option marginals draw one extra row and column with sums. #endif /* _Confusion_h_ */ praat-6.0.04/dwtools/ContingencyTable.cpp000066400000000000000000000143351261542461700203550ustar00rootroot00000000000000/* ContingencyTable.cpp * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ContingencyTable.h" #include "TableOfReal_extensions.h" #include "NUM2.h" Thing_implement (ContingencyTable, TableOfReal, 0); #define TINY 1e-30 void structContingencyTable :: v_info () { structDaata :: v_info (); double ndf; double h, hx, hy, hygx, hxgy, uygx, uxgy, uxy, chisq; ContingencyTable_entropies (this, &h, &hx, &hy, &hygx, &hxgy, &uygx, &uxgy, &uxy); ContingencyTable_chisq (this, &chisq, &ndf); MelderInfo_writeLine (U"Number of rows: ", numberOfRows); MelderInfo_writeLine (U"Number of columns: ", numberOfColumns); MelderInfo_writeLine (U"Entropies (y is row variable):"); MelderInfo_writeLine (U" Total: ", h); MelderInfo_writeLine (U" Y: ", hy); MelderInfo_writeLine (U" X: ", hx); MelderInfo_writeLine (U" Y given x: ", hygx); MelderInfo_writeLine (U" X given y: ", hxgy); MelderInfo_writeLine (U" Dependency of y on x: ", uygx); MelderInfo_writeLine (U" Dependency of x on y: ", uxgy); MelderInfo_writeLine (U" Symmetrical dependency: ", uxy); MelderInfo_writeLine (U" Chi squared: ", chisq); MelderInfo_writeLine (U" Degrees of freedom: ", ndf); MelderInfo_writeLine (U" Probability: ", ContingencyTable_chisqProbability (this)); } autoContingencyTable ContingencyTable_create (long numberOfRows, long numberOfColumns) { try { autoContingencyTable me = Thing_new (ContingencyTable); TableOfReal_init (me.peek(), numberOfRows, numberOfColumns); return me; } catch (MelderError) { Melder_throw (U"ContingencyTable not created."); } } double ContingencyTable_chisqProbability (ContingencyTable me) { double chisq, df; ContingencyTable_chisq (me, &chisq, &df); if (chisq == 0.0 && df == 0.0) { return 0.0; } return NUMchiSquareQ (chisq, df); } double ContingencyTable_cramersStatistic (ContingencyTable me) { double chisq, sum = 0.0, df; long nr = my numberOfRows, nc = my numberOfColumns, nmin = nr; if (nr == 1 || nc == 1) { return 0.0; } for (long i = 1; i <= nr; i++) { for (long j = 1; j <= nc; j++) { sum += my data[i][j]; } } if (nc < nr) { nmin = nc; } nmin--; ContingencyTable_chisq (me, &chisq, &df); if (chisq == 0.0 && df == 0.0) { return 0.0; } return sqrt (chisq / (sum * nmin)); } double ContingencyTable_contingencyCoefficient (ContingencyTable me) { double chisq, sum = 0.0, df; long nr = my numberOfRows, nc = my numberOfColumns; for (long i = 1; i <= nr; i++) { for (long j = 1; j <= nc; j++) { sum += my data[i][j]; } } ContingencyTable_chisq (me, &chisq, &df); if (chisq == 0.0 && df == 0.0) { return 0.0; } return sqrt (chisq / (chisq + sum)); } void ContingencyTable_chisq (ContingencyTable me, double *chisq, double *df) { long nr = my numberOfRows, nc = my numberOfColumns; *chisq = 0.0; *df = 0.0; autoNUMvector rowsum (1, nr); autoNUMvector colsum (1, nc); // row and column marginals double sum = 0.0; for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= my numberOfColumns; j++) { rowsum[i] += my data[i][j]; colsum[j] += my data[i][j]; } sum += rowsum[i]; } for (long i = 1; i <= my numberOfRows; i++) { if (rowsum[i] == 0.0) { --nr; } } for (long j = 1; j <= my numberOfColumns; j++) { if (colsum[j] == 0.0) { --nc; } } *df = (nr - 1.0) * (nc - 1.0); for (long i = 1; i <= my numberOfRows; i++) { if (rowsum[i] == 0.0) { continue; } for (long j = 1; j <= my numberOfColumns; j++) { if (colsum[j] == 0.0) { continue; } double expt = rowsum[i] * colsum[j] / sum; double tmp = my data[i][j] - expt; *chisq += tmp * tmp / expt; } } } void ContingencyTable_entropies (ContingencyTable me, double *h, double *hx, double *hy, double *hygx, double *hxgy, double *uygx, double *uxgy, double *uxy) { *h = *hx = *hy = *hxgy = *hygx = *uygx = *uxgy = *uxy = 0; autoNUMvector rowsum (1, my numberOfRows); autoNUMvector colsum (1, my numberOfColumns); // row and column totals double sum = 0.0; for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= my numberOfColumns; j++) { rowsum[i] += my data[i][j]; colsum[j] += my data[i][j]; } sum += rowsum[i]; } // Entropy of x distribution for (long j = 1; j <= my numberOfColumns; j++) { if (colsum[j] > 0.0) { double p = colsum[j] / sum; *hx -= p * NUMlog2 (p); } } // Entropy of y distribution for (long i = 1; i <= my numberOfRows; i++) { if (rowsum[i] > 0.0) { double p = rowsum[i] / sum; *hy -= p * NUMlog2 (p); } } // Total entropy for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= my numberOfColumns; j++) { if (my data[i][j] > 0.0) { double p = my data[i][j] / sum; *h -= p * NUMlog2 (p); } } } // Conditional entropies *hygx = *h - *hx; *hxgy = *h - *hy; *uygx = (*hy - *hygx) / (*hy + TINY); *uxgy = (*hx - *hxgy) / (*hx + TINY); *uxy = 2.0 * (*hx + *hy - *h) / (*hx + *hy + TINY); } autoContingencyTable Confusion_to_ContingencyTable (Confusion me) { try { autoContingencyTable thee = Thing_new (ContingencyTable); my structTableOfReal :: v_copy (thee.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to ContingencyTable."); } } autoContingencyTable TableOfReal_to_ContingencyTable (TableOfReal me) { try { TableOfReal_checkPositive (me); autoContingencyTable thee = Thing_new (ContingencyTable); my structTableOfReal :: v_copy (thee.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to ContingencyTable."); } } // End of file ContingencyTable.cpp praat-6.0.04/dwtools/ContingencyTable.h000066400000000000000000000032601261542461700200150ustar00rootroot00000000000000#ifndef _ContingencyTable_h_ #define _ContingencyTable_h_ /* ContingencyTable.h * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "TableOfReal.h" #include "Confusion.h" Thing_define (ContingencyTable, TableOfReal) { void v_info () override; }; // entries must be nonnegative numbers autoContingencyTable ContingencyTable_create (long numberOfRows, long numberOfColumns); double ContingencyTable_chisqProbability (ContingencyTable me); double ContingencyTable_cramersStatistic (ContingencyTable me); double ContingencyTable_contingencyCoefficient (ContingencyTable me); void ContingencyTable_chisq (ContingencyTable me, double *chisq, double *df); void ContingencyTable_entropies (ContingencyTable me, double *h, double *hx, double *hy, double *hygx, double *hxgy, double *uygx, double *uxgy, double *uxy); autoContingencyTable Confusion_to_ContingencyTable (Confusion me); autoContingencyTable TableOfReal_to_ContingencyTable (TableOfReal me); #endif // _ContingencyTable_h_ praat-6.0.04/dwtools/DTW.cpp000066400000000000000000001441341261542461700155640ustar00rootroot00000000000000/* DTW.cpp * * Copyright (C) 1993-2013, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header djmw 20050302 Path finder modified with sakoe-chiba band djmw 20050305 DTW_to_Polygon djmw 20050306 DTW_swapAxes djmw 20050530 Added Matrices_to_DTW djmw 20060909 DTW_getPathY linear behaviour outside domains. djmw 20061205 Pitches_to_DTW djmw 20061214 Changed info to Melder_writeLine format. djmw 20071012 Added: o_CAN_WRITE_AS_ENCODING.h djmw 20071016 To Melder_error djmw 20071022 Extra comments + possible bug correction in DTW_Path_recode. djmw 20071201 Melder_warning. djmw 20071204 DTW_and_Sounds_draw. djmw 20080122 float -> double djmw 20081123 DTW_and_Sounds_checkDomains did not swap sounds correctly. djmw 20091009 Removed a bug in DTW_Path_recode that could cause two identical x and y times in succesion at the end. djmw 20100504 extra check in DTW_Path_makeIndex djmw 20110304 Thing_new */ #include "DTW.h" #include "Sound_extensions.h" #include "NUM2.h" #include "NUMmachar.h" #include "oo_DESTROY.h" #include "DTW_def.h" #include "oo_COPY.h" #include "DTW_def.h" #include "oo_EQUAL.h" #include "DTW_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "DTW_def.h" #include "oo_WRITE_TEXT.h" #include "DTW_def.h" #include "oo_WRITE_BINARY.h" #include "DTW_def.h" #include "oo_READ_TEXT.h" #include "DTW_def.h" #include "oo_READ_BINARY.h" #include "DTW_def.h" #include "oo_DESCRIPTION.h" #include "DTW_def.h" Thing_implement (DTW, Matrix, 2); #define DTW_BIG 1e308 void structDTW :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Domain prototype:", ymin, U" to ", ymax, U" (s)."); // ppgb: Wat is een domain prototype? MelderInfo_writeLine (U"Domain candidate:", xmin, U" to ", xmax, U" (s)."); // ppgb: Wat is een domain candidate? MelderInfo_writeLine (U"Number of frames prototype: ", ny); MelderInfo_writeLine (U"Number of frames candidate: ", nx); MelderInfo_writeLine (U"Path length (frames): ", pathLength); MelderInfo_writeLine (U"Global warped distance: ", weightedDistance); if (nx == ny) { double dd = 0; for (long i = 1; i <= nx; i++) { dd += z[i][i]; } MelderInfo_writeLine (U"Distance along diagonal: ", dd / nx); } } static void DTW_drawWarpX_raw (DTW me, Graphics g, double xmin, double xmax, double ymin, double ymax, double tx, int garnish, int inset); static void DTW_paintDistances_raw (DTW me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum, int garnish, int inset); static void DTW_drawPath_raw (DTW me, Graphics g, double xmin, double xmax, double ymin, double ymax, int garnish, int inset); static double _DTW_and_Sounds_getPartY (Graphics g, double dtw_part_x); static void DTW_findPath_special (DTW me, int matchStart, int matchEnd, int slope, autoMatrix *cummulativeDists); /* Two 'slope lines, lh and ll, start in the lower left corner, the upper/lower has the maximum/minimum allowed slope. Two other lines, ru and rl, end in the upper-right corner. The upper/lower line have minimum/maximum slope. 1. the four lines with the two intersections determine a diamond For vertical line at x we return the upper and lower y of the two intersections 1. When we don't have a diamond, we return an error and the vertical distance between the slopelines in ylow. */ /* The actual path will be interpolated as follows: The distance matrix has cells of dimensions dx by dy. The optimal path connects these cells with one another in the following ways: In a diagonal ''path'' segment, i.e. when cells have no side in common, the interplated path runs from the lowerleft corner to the upperright corner. If a path segment is horizontal or vertical the path also runs from lowerleft to upperright. It is only when a horizontal and a vertical segment have a cell in common that we have to make some adjustments to the path in the common cell. This will be done as follows: Let nx and ny be the number of horizontal and vertical cells in this path segment. The path will always start at the lowerleft of the leftmost block and end at the upperright of the rightmost block. In the common cell we have to introduce an extra point in the path at (x1,y1) where the line from the horizontal segment and the line from the vertical segment intersect. Let the lowerleft and upperright point of the common cell be (0,0) and (dx,dy), then the coordinates (x,y) of the intersection can be calculated as follows: If we have two lines y = a1*x+b1 and y = a2*x+b2 they intersect at (x,y) = (b2-b1, a1*b2-a2*b1)/(a1-a2) For horizontal-vertical (hv) cells: a1 = dy/(nx*dx), a2 = ny*dy/dx b1 = dy*(nx-1)/nx, b2 = 0 Then: (x,y) = (dx, dy*ny ) * (nx-1)/(nx*ny-1) For vertical-horizontal (vh) cells: a1 = ny*dy/dx, a2 = dy/(nx*dx) b1 = -(ny-1)*dy b2 = 0 Then: (x,y) = (nx*dx, dy) * (ny-1)/(nx*ny-1) */ /* DTW_getXTime (DTW me, (DTW_getYTime (DTW me, double tx)) == tx */ double DTW_getYTimeFromXTime (DTW me, double tx) { DTW_Path_Query thee = & my pathQuery; if (tx < my xmin) { return my ymin - (my xmin - tx); } if (tx > my xmax) { return my ymax + (tx - my xmax); } if (! NUMfpp) { NUMmachar (); } double eps = 3 * NUMfpp -> eps; /* Find in which column is tx */ long ib, ie; long ix = (long) floor ( (tx - my x1) / my dx + 1.5); if (ix < 1) { ib = 1; ie = 2; } else if (ix > my nx) { ib = thy nxy - 1; ie = thy nxy; } else { ib = thy xindex[ix].ibegin; ie = thy xindex[ix].iend; } if (ie - ib > 1) { long it = ib + 1; while (tx - thy xytimes[it].x > eps) { it++; } ie = it; ib = it - 1; } double a = (thy xytimes[ib].y - thy xytimes[ie].y) / (thy xytimes[ib].x - thy xytimes[ie].x); double b = thy xytimes[ib].y - a * thy xytimes[ib].x; return a * tx + b; } double DTW_getXTimeFromYTime (DTW me, double ty) { DTW_Path_Query thee = & my pathQuery; if (ty < my ymin) { return my ymin - (my ymin - ty); } if (ty > my ymax) { return my ymax + (ty - my ymax); } if (! NUMfpp) { NUMmachar (); } double eps = 3 * NUMfpp -> eps; /* Find in which row is ty */ long ib, ie; long iy = (long) floor ( (ty - my y1) / my dy + 1.5); if (iy < 1) { ib = 1; ie = 2; } else if (iy > my ny) { ib = thy nxy - 1; ie = thy nxy; } else { ib = thy yindex[iy].ibegin; ie = thy yindex[iy].iend; } if (ie - ib > 1) { long it = ib + 1; while (ty - thy xytimes[it].y > eps) { it++; } ie = it; ib = it - 1; } double a = (thy xytimes[ib].y - thy xytimes[ie].y) / (thy xytimes[ib].x - thy xytimes[ie].x); double b = thy xytimes[ib].y - a * thy xytimes[ib].x; return (ty - b) / a; } void DTW_Path_Query_init (DTW_Path_Query me, long ny, long nx) { Melder_assert (ny > 0 && nx > 0); my ny = ny; my nx = nx; my nxy = 2 * (ny > nx ? ny : nx) + 2; // maximum number of points my xytimes = NUMvector (1, my nxy); my yindex = NUMvector (1, my ny); my xindex = NUMvector (1, my nx); } static void DTW_Path_makeIndex (DTW me, int xory) { DTW_Path_Query thee = & my pathQuery; DTW_Path_Index index; double x1, dx; long nx; if (! NUMfpp) { NUMmachar (); } double eps = 3 * NUMfpp -> eps; if (xory == DTW_X) { index = thy xindex; nx = my nx; x1 = my x1; dx = my dx; } else { index = thy yindex; nx = my ny; x1 = my y1; dx = my dy; } double xy_x2 = xory == DTW_X ? thy xytimes[3].x : thy xytimes[3].y; long i = 3; for (long j = 1; j <= nx; j++) { double xlow = x1 + (j - 1 - 0.5) * dx; double xhigh = xlow + dx; if (xlow - xy_x2 > -eps && i < thy nxy) { // i.e. xlow >= xy_x2 i++; xy_x2 = xory == DTW_X ? thy xytimes[i].x : thy xytimes[i].y; } index[j].ibegin = i - 1; while (xhigh - xy_x2 > eps && i < thy nxy) { // i.e. xhigh > xy_x2 i++; xy_x2 = xory == DTW_X ? thy xytimes[i].x : thy xytimes[i].y; } index[j].iend = i; } } /* Recode the path from a chain of cells to a piecewise linear path. */ void DTW_Path_recode (DTW me) { DTW_Path_Query thee = & my pathQuery; long nxy; // current number of elements in recoded path long nx = 1; // current number of successive horizontal cells in the cells chain long ny = 1; // current number of successive vertical cells in the cells chain long nd = 0; // current number of successive diagonal cells in the cells chain int isv = 0; // previous segment in the original path was vertical int ish = 0; // previous segment in the original path was horizontal long ixp = 0, iyp = 0; // previous cell /* Algorithm 1: get all the points in the path 2. get the x and y indices */ /* 1. Starting point always at origin */ thy xytimes[1].x = my xmin; thy xytimes[1].y = my ymin; nx = my path[1].x; ixp = nx - 1; thy xytimes[2].x = my x1 + (nx - 1 - 0.5) * my dx; ny = my path[1].y; iyp = ny - 1; thy xytimes[2].y = my y1 + (ny - 1 - 0.5) * my dy; // implicit: my x1 - 0.5 * my dx > my xmin && my y1 - 0.5 * my dy > my ymin nxy = 2; for (long j = 1; j <= my pathLength; j++) { long index; // where are we in the new path? long ix = my path[j].x, iy = my path[j].y; double xright = my x1 + (ix - 1 + 0.5) * my dx; double x, y, f, ytop = my y1 + (iy - 1 + 0.5) * my dy; if (iy == iyp) { // horizontal path? ish = 1; if (isv) { // we came from vertical direction? // We came from a vertical direction so this is the second horizontal cell in a row. // The statement after this "if" updates nx to 2. nx = 1; isv = 0; } nx++; if (ny > 1 || nd > 1) { // Previous segment was diagonal or vertical: modify intersection // The vh intersection (x,y) = (nx*dx, dy) * (ny-1)/(nx*ny-1) // A diagonal segment has ny = 1. f = (ny - 1.0) / (nx * ny - 1); x = xright - nx * my dx + nx * my dx * f; y = ytop - my dy + my dy * f; index = nxy - 1; if (nx == 2) { index = nxy; nxy++; } thy xytimes[index].x = x; thy xytimes[index].y = y; } nd = 0; } else if (ix == ixp) { // vertical isv = 1; if (ish) { ny = 1; ish = 0; } ny++; if (nx > 1 || nd > 1) { // The hv intersection (x,y) = (dx, dy*ny ) * (nx-1)/(nx*ny-1) f = (nx - 1.0) / (nx * ny - 1); x = xright - my dx + my dx * f; y = ytop - ny * my dy + ny * my dy * f; index = nxy - 1; if (ny == 2) { index = nxy; nxy++; } thy xytimes[index].x = x; thy xytimes[index].y = y; } nd = 0; } else if (ix == (ixp + 1) && iy == (iyp + 1)) { // diagonal nd++; if (nd == 1) { nxy++; } nx = ny = 1; } else { Melder_throw (U"The path goes back in time."); } // update thy xytimes[nxy].x = xright; thy xytimes[nxy].y = ytop; ixp = ix; iyp = iy; } if (my xmax > thy xytimes[nxy].x || my ymax > thy xytimes[nxy].y) { nxy++; thy xytimes[nxy].x = my xmax; thy xytimes[nxy].y = my ymax; } Melder_assert (nxy <= 2 * (my ny > my nx ? my ny : my nx) + 2); thy nxy = nxy; DTW_Path_makeIndex (me, DTW_X); DTW_Path_makeIndex (me, DTW_Y); } void DTW_pathRemoveRedundantNodes (DTW me) { long i = 1, skip = 0; for (long j = 2; j <= my pathLength; j++) { if ( (my path[j].y == my path[i].y) || my path[j].x == my path[i].x) { skip++; } else { /* if (j-1)^th was the last of a series: store it */ if (skip > 0) { my path[++i] = my path[j - 1]; } /* same check again */ skip = 0; if ( (my path[j].y == my path[i].y) || my path[j].x == my path[i].x) { skip++; } else { my path[++i] = my path[j]; } } } if (skip > 0) { my path[++i] = my path[my pathLength]; } my pathLength = i; } /* Prototype must be on y-axis and test on x-axis */ autoDTW DTW_create (double tminp, double tmaxp, long ntp, double dtp, double t1p, double tminc, double tmaxc, long ntc, double dtc, double t1c) { try { autoDTW me = Thing_new (DTW); Matrix_init (me.peek(), tminc, tmaxc, ntc, dtc, t1c, tminp, tmaxp, ntp, dtp, t1p); my path = NUMvector (1, ntc + ntp - 1); DTW_Path_Query_init (& my pathQuery, ntp, ntc); my wx = 1; my wy = 1; my wd = 2; return me; } catch (MelderError) { Melder_throw (U"DTW not created."); } } void DTW_setWeights (DTW me, double wx, double wy, double wd) { my wx = wx; my wy = wy; my wd = wd; } autoDTW DTW_swapAxes (DTW me) { try { autoDTW thee = DTW_create (my xmin, my xmax, my nx, my dx, my x1, my ymin, my ymax, my ny, my dy, my y1); for (long x = 1; x <= my nx; x++) { for (long y = 1; y <= my ny; y++) { thy z[x][y] = my z[y][x]; } } thy pathLength = my pathLength; for (long i = 1; i <= my pathLength; i++) { thy path[i].x = my path[i].y; thy path[i].y = my path[i].x; } return thee; } catch (MelderError) { Melder_throw (me, U": axes not swapped."); } } double DTW_getPathY (DTW me, double tx) { // Assume linear behaviour outside domains // Other option: scale with x_domain/y_domain if (tx < my xmin) { return my ymin - (my xmin - tx); } if (tx > my xmax) { return my ymax + (tx - my xmax); } // Find column in DTW matrix long ix = (long) floor ((tx - my x1) / my dx) + 1; if (ix < 1) { ix = 1; } if (ix > my nx) { ix = my nx; } // Find index in the path and the row number (iy) long i = ix + my path[1].x - 1; while (i <= my pathLength && my path[i].x != ix) { i++; } if (i > my pathLength) { return NUMundefined; } long iy = my path[i].y; /* row */ /* We like to have a "continuous" interpretation of time for the quantized x and y times. A time block is specified by lower left (x,y) and upper right (x+dx,y+dy). The path is interpreted as piecewise linear. Two special cases: 1. the local path is horizontal, i.e. two or more path elements with the same path.y value. We calculate the y-time from the line that connects the lower-left position of the leftmost horizontal time block to the upper-right position of the rightmost time horizontal block. (lowest column number to highest column number) For the first column and the last column we need to do something special if 2. the local path is vertical, i.e. two or path elements with the same path.x value. We calculate the y-time from the line that connects the lower-left position of the bottommost vertical time block to the upper-right position of the topmost time horizontal block. (lowest row number to highest row number) */ // Horizontal path? Find left and right positions. long ileft = i - 1; while (ileft >= 1 && my path[ileft].y == iy) { ileft--; } ileft++; if (ileft == 1 && ix > 1 && my path[ileft].y > 1) { ileft++; } long iright = i + 1; while (iright <= my pathLength && my path[iright].y == iy) { iright++; } iright--; if (iright == my pathLength && ix < my nx && my path[iright].y < my ny) { iright--; } long nxx = iright - ileft + 1; // Vertical path? Only if not already horizontal. long ibottom = i; long itop = i; if (nxx == 1) { ibottom--; while (ibottom >= 1 && my path[ibottom].x == ix) { ibottom--; } ibottom++; itop++; while (itop <= 1 && my path[itop].x == ix) { itop--; } itop++; } long nyy = itop - ibottom + 1; double boxx = nxx * my dx; double boxy = nyy * my dy; double ty; // Corrections at extreme left and right if path[1].x=1 && path[1].y>1 if (ix == my nx) { boxx = my xmax - (my x1 + (ix - 1) * my dx - my dx / 2); boxy = my ymax - (my y1 + (iy - 1) * my dy - my dy / 2); ty = my ymax - (boxy - (boxx - (my xmax - tx)) * boxy / boxx); } else if (ix == 1) { boxx = my x1 + my dx / 2 - my xmin; boxy = my y1 + (itop - 1) * my dy + my dy / 2 - my ymin; ty = (tx - my xmin) * boxy / boxx + my ymin; } else { // Diagonal interpolation in a box with lower left (0,0) and upper right (nxx*dx, nyy*dy). double ty0 = (tx - (my x1 + (my path[ileft].x - 1) * my dx - my dx / 2)) * boxy / boxx; ty = my y1 + (my path[ibottom].y - 1) * my dy - my dy / 2 + ty0; } return ty; } long DTW_getMaximumConsecutiveSteps (DTW me, int direction) { long nglobal = 1, nlocal = 1; for (long i = 2; i <= my pathLength; i++) { int localdirection; if (my path[i].y == my path[i - 1].y) { localdirection = DTW_X; } else if (my path[i].x == my path[i - 1].x) { localdirection = DTW_Y; } else { localdirection = DTW_XANDY; } if (localdirection == direction) { nlocal += 1; } if (direction != localdirection || i == my pathLength) { if (nlocal > nglobal) { nglobal = nlocal; } nlocal = 1; } } return nglobal; } static void DTW_paintDistances_raw (DTW me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum, int garnish, int inset) { long ixmin, ixmax, iymin, iymax; if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } (void) Matrix_getWindowSamplesX (me, xmin - 0.49999 * my dx, xmax + 0.49999 * my dx, & ixmin, & ixmax); (void) Matrix_getWindowSamplesY (me, ymin - 0.49999 * my dy, ymax + 0.49999 * my dy, & iymin, & iymax); if (maximum <= minimum) { (void) Matrix_getWindowExtrema (me, ixmin, ixmax, iymin, iymax, & minimum, & maximum); } if (maximum <= minimum) { minimum -= 1.0; maximum += 1.0; } if (xmin >= xmax || ymin >= ymax) { return; } if (inset) { Graphics_setInner (g); } Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_cellArray (g, my z, ixmin, ixmax, Matrix_columnToX (me, ixmin - 0.5), Matrix_columnToX (me, ixmax + 0.5), iymin, iymax, Matrix_rowToY (me, iymin - 0.5), Matrix_rowToY (me, iymax + 0.5), minimum, maximum); Graphics_rectangle (g, xmin, xmax, ymin, ymax); if (inset) { Graphics_unsetInner (g); } if (garnish) { Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); } } void DTW_paintDistances (DTW me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum, int garnish) { DTW_paintDistances_raw (me, g, xmin, xmax, ymin, ymax, minimum, maximum, garnish, 1); } static void DTW_drawPath_raw (DTW me, Graphics g, double xmin, double xmax, double ymin, double ymax, int garnish, int inset) { DTW_Path_Query thee = & my pathQuery; if (xmin >= xmax) { xmin = my xmin; xmax = my xmax; } if (ymin >= ymax) { ymin = my ymin; ymax = my ymax; } if (inset) { Graphics_setInner (g); } Graphics_setWindow (g, xmin, xmax, ymin, ymax); for (long i = 1; i < thy nxy; i++) { double x1, y1, x2, y2; if (NUMclipLineWithinRectangle (thy xytimes[i].x, thy xytimes[i].y, thy xytimes[i + 1].x, thy xytimes[i + 1].y, xmin, ymin, xmax, ymax, &x1, &y1, &x2, &y2)) { Graphics_line (g, x1, y1, x2, y2); } } if (inset) { Graphics_unsetInner (g); } if (garnish) { Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); } } void DTW_drawPath (DTW me, Graphics g, double xmin, double xmax, double ymin, double ymax, int garnish) { DTW_drawPath_raw (me, g, xmin, xmax, ymin, ymax, garnish, 1); } static void DTW_drawWarpX_raw (DTW me, Graphics g, double xmin, double xmax, double ymin, double ymax, double tx, int garnish, int inset) { double ty = DTW_getYTimeFromXTime (me, tx); int lineType = Graphics_inqLineType (g); if (xmin >= xmax) { xmin = my xmin; xmax = my xmax; } if (ymin >= ymax) { ymin = my ymin; ymax = my ymax; } if (inset) { Graphics_setInner (g); } Graphics_setWindow (g, xmin, xmax, ymin, ymax); ty = DTW_getYTimeFromXTime (me, tx); Graphics_setLineType (g, Graphics_DOTTED); if (ty <= ymax) { Graphics_line (g, tx, ymin, tx, ty); Graphics_line (g, tx, ty, xmin, ty); } else { Graphics_line (g, tx, ymin, tx, ymax); } Graphics_setLineType (g, lineType); if (inset) { Graphics_unsetInner (g); } if (garnish) { Graphics_markBottom (g, tx, true, true, false, nullptr); if (ty <= ymax) { Graphics_markLeft (g, ty, true, true, false, nullptr); } } } void DTW_drawWarpX (DTW me, Graphics g, double xmin, double xmax, double ymin, double ymax, double tx, int garnish) { DTW_drawWarpX_raw (me, g, xmin, xmax, ymin, ymax, tx, garnish, 1); } static void DTW_and_Sounds_checkDomains (DTW me, Sound *y, Sound *x, double *xmin, double *xmax, double *ymin, double *ymax) { if (my ymin == (*y) -> xmin && my ymax == (*y) -> xmax) { if (my xmin != (*x) -> xmin || my xmax != (*x) -> xmax) { Melder_throw (U"The domains of the DTW and the sound(s) don't match"); } } else if (my ymin == (*x) -> xmin && my ymax == (*x) -> xmax) { if (my xmin != (*y) -> xmin || my xmax != (*y) -> xmax) { Melder_throw (U"The domains of the DTW and the sound(s) don't match"); } Sound tmp = *y; *y = *x; *x = tmp; // swap x and y } else { Melder_throw (U"The domains of the DTW and the sound(s) don't match"); } if (*xmin >= *xmax) { *xmin = my xmin; *xmax = my xmax; } if (*ymin >= *ymax) { *ymin = my ymin; *ymax = my ymax; } } static void drawBox (Graphics g) { double x1WC, x2WC, y1WC, y2WC; double lineWidth = Graphics_inqLineWidth (g); Graphics_inqWindow (g, &x1WC, &x2WC, &y1WC, &y2WC); Graphics_setLineWidth (g, 2.0 * lineWidth); Graphics_rectangle (g, x1WC, x2WC, y1WC, y2WC); Graphics_setLineWidth (g, lineWidth); } /* In a picture with a DTW and a left and bottom Sound, we want "width" of the vertical sound and the "height" of the horizontal Sound t be equal. Given the horizontal fraction of the DTW-part, this routine returns the vertical part. */ static double _DTW_and_Sounds_getPartY (Graphics g, double dtw_part_x) { double x1NDC, x2NDC, y1NDC, y2NDC; Graphics_inqViewport (g, &x1NDC, &x2NDC, &y1NDC, &y2NDC); return 1 - ( (1 - dtw_part_x) * (x2NDC - x1NDC)) / (y2NDC - y1NDC); } void DTW_and_Sounds_draw (DTW me, Sound y, Sound x, Graphics g, double xmin, double xmax, double ymin, double ymax, int garnish) { DTW_and_Sounds_checkDomains (me, &y, &x, &xmin, &xmax, &ymin, &ymax); Graphics_setInner (g); Graphics_Viewport ovp = g -> outerViewport; // save for unsetInner double dtw_part_x = 0.85; double dtw_part_y = _DTW_and_Sounds_getPartY (g, dtw_part_x); /* DTW */ Graphics_Viewport vp = Graphics_insetViewport (g, 1 - dtw_part_x, 1, 1 - dtw_part_y, 1); DTW_paintDistances_raw (me, g, xmin, xmax, ymin, ymax, 0, 0, 0, 0); DTW_drawPath_raw (me, g, xmin, xmax, ymin, ymax, 0, 0); drawBox (g); Graphics_resetViewport (g, vp); /* Sound y */ vp = Graphics_insetViewport (g, 0, 1 - dtw_part_x, 1 - dtw_part_y, 1); Sound_draw_btlr (y, g, ymin, ymax, -1, 1, FROM_BOTTOM_TO_TOP, 0); if (garnish) { drawBox (g); } Graphics_resetViewport (g, vp); /* Sound x */ vp = Graphics_insetViewport (g, 1 - dtw_part_x, 1, 0, 1 - dtw_part_y); Sound_draw_btlr (x, g, xmin, xmax, -1, 1, FROM_LEFT_TO_RIGHT, 0); if (garnish) { drawBox (g); } Graphics_resetViewport (g, vp); /* Set window coordinates so that margins will work, i.e. extend time domains */ double xmin3 = xmax - (xmax - xmin) / dtw_part_x; double ymin3 = ymax - (ymax - ymin) / dtw_part_y; Graphics_setWindow (g, xmin3, xmax, ymin3, ymax); g -> outerViewport = ovp; // restore from _setInner Graphics_unsetInner (g); if (garnish) { Graphics_markLeft (g, ymin, true, true, false, nullptr); Graphics_markLeft (g, ymax, true, true, false, nullptr); Graphics_markBottom (g, xmin, true, true, false, nullptr); Graphics_markBottom (g, xmax, true, true, false, nullptr); } } void DTW_and_Sounds_drawWarpX (DTW me, Sound yy, Sound xx, Graphics g, double xmin, double xmax, double ymin, double ymax, double tx, int garnish) { Sound y = yy, x = xx; int lineType = Graphics_inqLineType (g); DTW_and_Sounds_checkDomains (me, &y, &x, &xmin, &xmax, &ymin, &ymax); Graphics_setInner (g); double dtw_part_x = 0.85; double dtw_part_y = _DTW_and_Sounds_getPartY (g, dtw_part_x); xmin = xmax - (xmax - xmin) / dtw_part_x; ymin = ymax - (ymax - ymin) / dtw_part_y; Graphics_setWindow (g, xmin, xmax, ymin, ymax); double ty = DTW_getYTimeFromXTime (me, tx); Graphics_setLineType (g, Graphics_DOTTED); Graphics_line (g, tx, ymin, tx, ty); Graphics_line (g, tx, ty, xmin, ty); Graphics_setLineType (g, lineType); Graphics_unsetInner (g); if (garnish) { Graphics_markBottom (g, tx, true, true, false, nullptr); Graphics_markLeft (g, ty, true, true, false, nullptr); } } autoMatrix DTW_to_Matrix_distances (DTW me) { try { autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, my ymin, my ymax, my ny, my dy, my y1); NUMmatrix_copyElements (my z, thy z, 1, my ny, 1, my nx); return thee; } catch (MelderError) { Melder_throw (me, U": distances not converted to Matrix."); } } /* nog aanpassen, dl = sqrt (dx^2 + dy^2) */ void DTW_drawDistancesAlongPath (DTW me, Graphics g, double xmin, double xmax, double dmin, double dmax, int garnish) { if (xmin >= xmax) { xmin = my xmin; xmax = my xmax; } long ixmax, ixmin; if (! Matrix_getWindowSamplesX (me, xmin, xmax, &ixmin, &ixmax)) { return; } long ii = 1; while (ii < my pathLength && my path[ii].x < ixmin) { ii++; } ixmin = ii; while (ii <= my pathLength && my path[ii].x < ixmax) { ii++; } ixmax = ii; autoNUMvector d (ixmin, ixmax); for (long i = ixmin; i <= ixmax; i++) { d[i] = my z[my path[i].y][i]; } if (dmin >= dmax) { NUMvector_extrema (d.peek(), ixmin, ixmax, &dmin, &dmax); } else { for (long i = ixmin; i <= ixmax; i++) { if (d[i] > dmax) { d[i] = dmax; } else if (d[i] < dmin) { d[i] = dmin; } } } Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, dmin, dmax); Graphics_function (g, d.peek(), ixmin, ixmax, xmin, xmax); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textLeft (g, true, U"distance"); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); } } /* metric = 1...n (sum (a_i^n))^(1/n) */ autoDTW Matrices_to_DTW (Matrix me, Matrix thee, int matchStart, int matchEnd, int slope, double metric) { try { if (thy ny != my ny) { Melder_throw (U"Columns must have the same dimensions."); } autoDTW him = DTW_create (my xmin, my xmax, my nx, my dx, my x1, thy xmin, thy xmax, thy nx, thy dx, thy x1); autoMelderProgress progess (U"Calculate distances"); for (long i = 1; i <= my nx; i++) { for (long j = 1; j <= thy nx; j++) { /* First divide distance by maximum to prevent overflow when metric is a large number. d = (x^n)^(1/n) may overflow if x>1 & n >>1 even if d would not overflow! */ double dmax = 0, d = 0, dtmp; for (long k = 1; k <= my ny; k++) { dtmp = fabs (my z[k][i] - thy z[k][j]); if (dtmp > dmax) { dmax = dtmp; } } if (dmax > 0) { for (long k = 1; k <= my ny; k++) { dtmp = fabs (my z[k][i] - thy z[k][j]) / dmax; d += pow (dtmp, metric); } } d = dmax * pow (d, 1.0 / metric); his z[i][j] = d / my ny; /* == d * dy / ymax */ } if ( (i % 10) == 1) { Melder_progress (0.999 * i / my nx, U"Calculate distances: column ", i, U" from ", my nx, U"."); } } DTW_findPath (him.peek(), matchStart, matchEnd, slope); return him; } catch (MelderError) { Melder_throw (U"DTW not created from matrices."); } } autoDTW Spectrograms_to_DTW (Spectrogram me, Spectrogram thee, int matchStart, int matchEnd, int slope, double metric) { try { if (my xmin != thy xmin || my ymax != thy ymax || my ny != thy ny) { Melder_throw (U"The number of frequencies and/or frequency ranges do not match."); } autoMatrix m1 = Spectrogram_to_Matrix (me); autoMatrix m2 = Spectrogram_to_Matrix (thee); // Take log10 for dB's (4e-10 scaling not necessary) for (long i = 1; i <= my ny; i++) { for (long j = 1; j <= my nx; j++) { m1 -> z[i][j] = 10 * log10 (m1 -> z[i][j]); } } for (long i = 1; i <= thy ny; i++) { for (long j = 1; j <= thy nx; j++) { m2 -> z[i][j] = 10 * log10 (m2 -> z[i][j]); } } autoDTW him = Matrices_to_DTW (m1.peek(), m2.peek(), matchStart, matchEnd, slope, metric); return him; } catch (MelderError) { Melder_throw (U"DTW not created from Spectrograms."); } } #define FREQUENCY(frame) ((frame) -> candidate [1]. frequency) #define NOT_VOICED(f) ((f) <= 0.0 || (f) >= my ceiling) /* This includes NUMundefined! */ static int Pitch_findFirstAndLastVoicedFrame (Pitch me, long *first, long *last) { *first = 1; while (*first <= my nx && ! Pitch_isVoiced_i (me, *first)) { (*first) ++; } *last = my nx; while (*last >= *first && ! Pitch_isVoiced_i (me, *last)) { (*last)--; } return *first <= my nx && *last >= 1; } autoDTW Pitches_to_DTW_sgc (Pitch me, Pitch thee, double vuv_costs, double time_weight, int matchStart, int matchEnd, int slope); autoDTW Pitches_to_DTW_sgc (Pitch me, Pitch thee, double vuv_costs, double time_weight, int matchStart, int matchEnd, int slope) { // vuv_costs=24, time_weight=10 ? try { if (vuv_costs < 0) { Melder_throw (U"Voiced-unvoiced costs may not be negative."); } if (time_weight < 0) { Melder_throw (U"Time costs weight may not be negative."); } long myfirst, mylast, thyfirst, thylast; if (! Pitch_findFirstAndLastVoicedFrame (me, &myfirst, &mylast) || ! Pitch_findFirstAndLastVoicedFrame (thee, &thyfirst, &thylast)) { Melder_throw (U"No voiced frames."); } /* We do not want the silences before the first voiced frame and after the last voiced frame to determine the distances. We create paths from (1,1)...(thyfirst,myfirst) and (thylast,mylast)...(thy nx,my nx) by making the other cell's distances very large. */ autoDTW him = DTW_create (my xmin, my xmax, my nx, my dx, my x1, thy xmin, thy xmax, thy nx, thy dx, thy x1); autoNUMvector pitchx (1, thy nx); int unit = kPitch_unit_SEMITONES_100; for (long j = 1; j <= thy nx; j++) { pitchx[j] = Sampled_getValueAtSample (thee, j, Pitch_LEVEL_FREQUENCY, unit); } for (long i = 1; i <= my nx; i++) { double pitchy = Sampled_getValueAtSample (me, i, Pitch_LEVEL_FREQUENCY, unit); double t1 = my x1 + (i - 1) * my dx; for (long j = 1; j <= thy nx; j++) { double t2 = thy x1 + (j - 1) * thy dx; double dist_f = 0; // based on pitch difference double dist_t = fabs (t1 - t2); if (pitchy == NUMundefined) { if (pitchx[j] != NUMundefined) { dist_f = vuv_costs; } } else if (pitchx[j] == NUMundefined) { dist_f = vuv_costs; } else { dist_f = fabs (pitchy - pitchx[j]); } his z[i][j] = sqrt (dist_f * dist_f + time_weight * dist_t * dist_t); } } DTW_findPath (him.peek(), matchStart, matchEnd, slope); return him; } catch (MelderError) { Melder_throw (U"DTW not created from Pitches."); } } autoDTW Pitches_to_DTW (Pitch me, Pitch thee, double vuv_costs, double time_weight, int matchStart, int matchEnd, int slope) { // vuv_costs=24, time_weight=10 ? try { if (vuv_costs < 0) { Melder_throw (U"Voiced-unvoiced costs must not be negative."); } if (time_weight < 0) { Melder_throw (U"Time costs weight must not be negative."); } autoDTW him = DTW_create (my xmin, my xmax, my nx, my dx, my x1, thy xmin, thy xmax, thy nx, thy dx, thy x1); autoNUMvector pitchx (1, thy nx); int unit = kPitch_unit_SEMITONES_100; for (long j = 1; j <= thy nx; j++) { pitchx[j] = Sampled_getValueAtSample (thee, j, Pitch_LEVEL_FREQUENCY, unit); } for (long i = 1; i <= my nx; i++) { double pitchy = Sampled_getValueAtSample (me, i, Pitch_LEVEL_FREQUENCY, unit); double t1 = my x1 + (i - 1) * my dx; for (long j = 1; j <= thy nx; j++) { double t2 = thy x1 + (j - 1) * thy dx; double dist_f = 0; // based on pitch difference double dist_t = fabs (t1 - t2); if (pitchy == NUMundefined) { if (pitchx[j] != NUMundefined) { dist_f = vuv_costs; } } else if (pitchx[j] == NUMundefined) { dist_f = vuv_costs; } else { dist_f = fabs (pitchy - pitchx[j]); } his z[i][j] = sqrt (dist_f * dist_f + time_weight * dist_t * dist_t); } } DTW_findPath (him.peek(), matchStart, matchEnd, slope); return him; } catch (MelderError) { Melder_throw (U"DTW not created from Pitches."); } } autoDurationTier DTW_to_DurationTier (DTW me) { (void) me; DurationTier thee = nullptr; return thee; } void DTW_and_Matrix_replace (DTW me, Matrix thee) { try { if (my xmin != thy xmin || my xmax != thy xmax || my ymin != thy ymin || my ymax != thy ymax) { Melder_throw (U"The X and Y domains of the matrix and the DTW must be equal."); } if (my nx != thy nx || my dx != thy dx || my ny != thy ny || my dy != thy dy) { Melder_throw (U"The sampling of the matrix and the DTW must be equal."); } double minimum, maximum; Matrix_getWindowExtrema (me, 0, 0, 0, 0, & minimum, & maximum); if (minimum < 0) { Melder_throw (U"Distances must not be negative."); } NUMmatrix_copyElements (thy z, my z, 1, my ny, 1, my nx); } catch (MelderError) { Melder_throw (me, U": distances not replaced."); } } /****************** new implementation ********/ void DTW_findPath (DTW me, int matchStart, int matchEnd, int slope) { DTW_findPath_special (me, matchStart, matchEnd, slope, nullptr); } autoMatrix DTW_to_Matrix_cummulativeDistances (DTW me, double sakoeChibaBand, int slope) { try { autoMatrix cummulativeDistances; DTW_findPath_bandAndSlope (me, sakoeChibaBand, slope, &cummulativeDistances); return cummulativeDistances; } catch (MelderError) { Melder_throw (me, U": cummulative costs matrix not created."); } } static void DTW_checkSlopeConstraints (DTW me, double band, int slope) { try { double slopes[5] = { DTW_BIG, DTW_BIG, 3, 2, 1.5 } ; double dtw_slope = (my ymax - my ymin - band) / (my xmax - my xmin - band); if (slope < 1 || slope > 4) { Melder_throw (U"Invalid slope constraint."); } if (dtw_slope <= 0 && slope != 1) { Melder_throw (U"Band too wide."); } if (dtw_slope < 1) { dtw_slope = 1 / dtw_slope; } if (dtw_slope > slopes[slope]) { Melder_warning (U"There is a conflict between the chosen slope constraint and the relative duration. " "The duration ratio of the longest and the shortest object is ", dtw_slope, U". This implies that the largest slope in the constraint must have a value greater or equal to this ratio."); } } catch (MelderError) { Melder_throw (U"Slope constraints cannot be met."); } } static void DTW_and_Polygon_setUnreachableParts (DTW me, Polygon thee, long **psi) { try { double eps = my dx / 100; // safely enough double dtw_slope = (my ymax - my ymin) / (my xmax - my xmin); double xmin, xmax, ymin, ymax; Polygon_getExtrema (thee, &xmin, &xmax, &ymin, &ymax); // if the Polygon and the DTW don't overlap everything is unreachable! if (xmax <= my xmin || xmin >= my xmax || ymax <= my ymin || ymin >= my ymax) { Melder_throw (U"DTW and Polygon don't overlap."); } // find border "above" polygon for (long ix = 1; ix <= my nx; ix++) { double x = my x1 + (ix - 1) * my dx; long iystart = (long) floor (dtw_slope * ix * (my dx / my dy)) + 1; for (long iy = iystart + 1; iy <= my ny; iy++) { double y = my y1 + (iy - 1) * my dy; if (Polygon_getLocationOfPoint (thee, x, y, eps) == Polygon_OUTSIDE) { for (long k = iy; k <= my ny; k++) { psi[k][ix] = DTW_UNREACHABLE; } break; } } } // find border "below" polygon for (long ix = 2; ix <= my nx; ix++) { double x = my x1 + (ix - 1) * my dx; long iystart = (long) floor (dtw_slope * ix * (my dx / my dy)); // start 1 lower if (iystart > my ny) iystart = my ny; for (long iy = iystart - 1; iy >= 1; iy--) { double y = my y1 + (iy - 1) * my dy; if (Polygon_getLocationOfPoint (thee, x, y, eps) == Polygon_OUTSIDE) { for (long k = iy; k >= 1; k--) { psi[k][ix] = DTW_UNREACHABLE; } break; } } } } catch (MelderError) { Melder_throw (me, U" cannot set unreachable parts."); } } #define DTW_ISREACHABLE(y,x) ((psi[y][x] != DTW_UNREACHABLE) && (psi[y][x] != DTW_FORBIDDEN)) static void DTW_findPath_special (DTW me, int matchStart, int matchEnd, int slope, autoMatrix *cummulativeDists) { (void) matchStart; (void) matchEnd; try { autoPolygon thee = DTW_to_Polygon (me, 0.0, slope); DTW_and_Polygon_findPathInside (me, thee.peek(), slope, cummulativeDists); } catch (MelderError) { Melder_throw (me, U": cannot find path."); } } // Intersection of two straight lines y = a[i]*x+b[i], where a[2] = 1 / a[1]. Point (x1,y1) is on first line, // point (x2,y2) is on second line. static void getIntersectionPoint (double x1, double y1, double x2, double y2, double a, double *x3, double *y3) { *x3 = (y2 - y1 + a * x1 - x2 / a) / (a - 1 / a); *y3 = a * *x3 + y1 - a * x1; } autoPolygon DTW_to_Polygon (DTW me, double band, int slope) { try { DTW_checkSlopeConstraints (me, band, slope); double slopes[5] = { DTW_BIG, DTW_BIG, 3, 2, 1.5 } ; if (band <= 0) { if (slope == 1) { autoPolygon thee = Polygon_create (4); thy x[1] = my xmin; thy y[1] = my ymin; thy x[2] = my xmin; thy y[2] = my ymax; thy x[3] = my xmax; thy y[3] = my ymax; thy x[4] = my xmax; thy y[4] = my ymin; return thee; } else { autoPolygon thee = Polygon_create (4); thy x[1] = my xmin; thy y[1] = my ymin; thy x[3] = my xmax; thy y[3] = my ymax; double x, y; getIntersectionPoint (my xmin, my ymin, my xmax, my ymax, slopes[slope], &x, &y); if (x < my xmin) x = my xmin; if (x > my xmax) x = my xmax; if (y < my ymin) y = my ymin; if (y > my ymax) y = my ymax; thy x[2] = x; thy y[2] = y; getIntersectionPoint (my xmin, my ymin, my xmax, my ymax, 1 / slopes[slope], &x, &y); if (x < my xmin) x = my xmin; if (x > my xmax) x = my xmax; if (y < my ymin) y = my ymin; if (y > my ymax) y = my ymax; thy x[4] = x; thy y[4] = y; return thee; } } else { if (slope == 1) { autoPolygon thee = Polygon_create (6); thy x[1] = my xmin; thy y[1] = my ymin; thy x[2] = my xmin; thy y[2] = my ymin + band; thy x[3] = my xmax - band; thy y[3] = my ymax; thy x[4] = my xmax; thy y[4] = my ymax; thy x[5] = my xmax; thy y[5] = my ymax - band; thy x[6] = my xmin + band; thy y[6] = my ymin; return thee; } else { autoPolygon thee = Polygon_create (8); double x, y; thy x[1] = my xmin; thy y[1] = my ymin; thy x[2] = my xmin; thy y[2] = my ymin + band; getIntersectionPoint (my xmin, my ymin + band, my xmax - band, my ymax, slopes[slope], &x, &y); if (x < my xmin) x = my xmin; if (x > my xmax) x = my xmax; if (y < my ymin) y = my ymin; if (y > my ymax) y = my ymax; thy x[3] = x; thy y[3] = y; thy x[4] = my xmax - band; thy y[4] = my ymax; thy x[5] = my xmax; thy y[5]= my ymax; thy x[6] = my xmax; thy y[6] = my ymax - band; getIntersectionPoint (my xmin + band, my ymin, my xmax, my ymax - band, 1 / slopes[slope], &x, &y); if (x < my xmin) x = my xmin; if (x > my xmax) x = my xmax; if (y < my ymin) y = my ymin; if (y > my ymax) y = my ymax; thy x[7] = x; thy y[7] = y; thy x[8] = my xmin + band; thy y[8] = my ymin; return thee; } } } catch (MelderError) { Melder_throw (me, U" no Polygon created."); } } autoMatrix DTW_and_Polygon_to_Matrix_cummulativeDistances (DTW me, Polygon thee, int localSlope) { try { autoMatrix cummulativeDistances; DTW_and_Polygon_findPathInside (me, thee, localSlope, &cummulativeDistances); return cummulativeDistances; } catch (MelderError) { Melder_throw (me, U": cummulative costs matrix not created from DTW and Polygon."); } } void DTW_findPath_bandAndSlope (DTW me, double sakoeChibaBand, int localSlope, autoMatrix *cummulativeDists) { try { autoPolygon thee = DTW_to_Polygon (me, sakoeChibaBand, localSlope); DTW_and_Polygon_findPathInside (me, thee.peek(), localSlope, cummulativeDists); } catch (MelderError) { Melder_throw (me, U" cannot determine the path."); } } void DTW_and_Polygon_findPathInside (DTW me, Polygon thee, int localSlope, autoMatrix *cummulativeDists) { try { double slopes[5] = { DTW_BIG, DTW_BIG, 3, 2, 1.5 }; long pathIndex = my nx + my ny - 1; /* Maximum path length */ // if localSlope == 1 start of path is within 10% of minimum duration. Starts farther away long delta_xy = (my nx < my ny ? my nx : my ny) / 10; // if localSlope == 1 start within 10% of if (localSlope < 1 || localSlope > 4) { Melder_throw (U"Local slope parameter is illegal."); } autoNUMmatrix delta (-2, my ny, -2, my nx); autoNUMmatrix psi (-2, my ny, -2, my nx); for (long i = 1; i <= my ny; i++) { for (long j = 1; j <= my nx; j++) { delta[i][j] = my z[i][j]; } } // start by making the outside unreachable for (long k = -2; k <= 1; k++) { for (long j = -2; j <= my nx; j++) { // delta[k][j] = DTW_BIG; psi[k][j] = DTW_UNREACHABLE; } for (long i = 1; i <= my ny; i++) { // delta[i][k] = DTW_BIG; psi[i][k] = DTW_UNREACHABLE; } } // Make begin part of first column reachable long rowto = delta_xy; if (localSlope != 1) rowto = (long) floor (slopes[localSlope]) + 1; for (long iy = 2; iy <= rowto; iy++) { if (localSlope != 1) { delta[iy][1] = delta[iy - 1][1] + my z[iy][1]; psi[iy][1] = DTW_Y; } else { psi[iy][1] = DTW_START; // will be adapted by DTW_and_Polygon_setUnreachableParts } } // Make begin part of first row reachable long colto = delta_xy; if (localSlope != 1) colto = (long) floor (slopes[localSlope]) + 1; for (long ix = 2; ix <= colto; ix++) { if (localSlope != 1) { delta[1][ix] = delta[1][ix -1] + my z[1][ix]; psi[1][ix] = DTW_X; } else { psi[1][ix] = DTW_START; // will be adapted by DTW_and_Polygon_setUnreachableParts } } // Now we can set the unreachable parts from the Polygon DTW_and_Polygon_setUnreachableParts (me, thee, psi.peek()); // Forward pass. long numberOfIsolatedPoints = 0; autoMelderProgress progress (U"Find path"); for (long j = 2; j <= my nx; j++) { for (long i = 2; i <= my ny; i++) { if (! DTW_ISREACHABLE (i, j)) continue; double g, gmin = DTW_BIG; long direction = 0; if (DTW_ISREACHABLE (i - 1, j - 1)) { gmin = delta[i - 1][j - 1] + 2 * my z[i][j]; direction = DTW_XANDY; } else if (DTW_ISREACHABLE (i, j - 1)) { gmin = delta[i][j - 1] + my z[i][j]; direction = DTW_X; } else if (DTW_ISREACHABLE (i - 1, j)) { gmin = delta[i - 1][j] + my z[i][j]; direction = DTW_Y; } else { numberOfIsolatedPoints++; continue; } switch (localSlope) { case 1: { // no restriction if (DTW_ISREACHABLE (i, j - 1) && ((g = delta[i][j - 1] + my z[i][j]) < gmin)) { gmin = g; direction = DTW_X; } if (DTW_ISREACHABLE (i - 1, j) && ((g = delta[i - 1][j] + my z[i][j]) < gmin)) { gmin = g; direction = DTW_Y; } } break; // P = 1/2 case 2: { // P = 1/2 if (DTW_ISREACHABLE (i - 1, j - 3) && psi[i][j - 1] == DTW_X && psi[i][j - 2] == DTW_XANDY && (g = delta[i-1][j-3] + 2 * my z[i][j-2] + my z[i][j-1] + my z[i][j]) < gmin) { gmin = g; direction = DTW_X; } if (DTW_ISREACHABLE (i - 1, j - 2) && psi[i][j - 1] == DTW_XANDY && (g = delta[i - 1][j - 2] + 2 * my z[i][j - 1] + my z[i][j]) < gmin) { gmin = g; direction = DTW_X; } if (DTW_ISREACHABLE (i - 2, j - 1) && psi[i - 1][j] == DTW_XANDY && (g = delta[i - 2][j - 1] + 2 * my z[i - 1][j] + my z[i][j]) < gmin) { gmin = g; direction = DTW_Y; } if (DTW_ISREACHABLE (i - 3, j - 1) && psi[i - 1][j] == DTW_Y && psi[i - 2][j] == DTW_XANDY && (g = delta[i-3][j-1] + 2 * my z[i-2][j] + my z[i-1][j] + my z[i][j]) < gmin) { gmin = g; direction = DTW_Y; } } break; // P = 1 case 3: { if (DTW_ISREACHABLE (i - 1, j - 2) && psi[i][j - 1] == DTW_XANDY && (g = delta[i - 1][j - 2] + 2 * my z[i][j - 1] + my z[i][j]) < gmin) { gmin = g; direction = DTW_X; } if (DTW_ISREACHABLE (i - 2, j - 1) && psi[i - 1][j] == DTW_XANDY && (g = delta[i - 2][j - 1] + 2 * my z[i - 1][j] + my z[i][j]) < gmin) { gmin = g; direction = DTW_Y; } } break; // P = 2 case 4: { if (DTW_ISREACHABLE (i - 2, j - 3) && psi[i][j - 1] == DTW_XANDY && psi[i - 1][j - 2] == DTW_XANDY && (g = delta[i-2][j-3] + 2 * my z[i-1][j-2] + 2 * my z[i][j-1] + my z[i][j]) < gmin) { gmin = g; direction = DTW_X; } if (DTW_ISREACHABLE (i - 3, j - 2) && psi[i - 1][j] == DTW_XANDY && psi[i - 2][j - 1] == DTW_XANDY && (g = delta[i-3][j-2] + 2 * my z[i-2][j-1] + 2 * my z[i-1][j] + my z[i][j]) < gmin) { gmin = g; direction = DTW_Y; } } break; default: break; } Melder_assert (direction != 0); psi[i][j] = direction; delta[i][j] = gmin; } if ((j % 10) == 2) { Melder_progress (0.999 * j / my nx, U"Calculate time warp: frame ", j, U" from ", my nx, U"."); } } // Find minimum at end of path and trace back. long iy = my ny; double minimum = delta[iy][my nx]; for (long i = my ny - 1; i > 0; i--) { if (! DTW_ISREACHABLE (i, my nx)) { break; // we're in unreachable places } else if (delta[i][my nx] < minimum) { minimum = delta[iy = i][my nx]; } } my weightedDistance = minimum / (my nx + my ny); my path[pathIndex].y = iy; long ix = my path[pathIndex].x = my nx; // Fill path backwards. while (ix > 1) { if (psi[iy][ix] == DTW_XANDY) { ix--; iy--; } else if (psi[iy][ix] == DTW_X) { ix--; } else if (psi[iy][ix] == DTW_Y) { iy--; } else if (psi[iy][ix] == DTW_START) { break; } if (pathIndex < 2 || iy < 1) break; //Melder_assert (pathIndex > 1 && iy > 0); my path[--pathIndex].x = ix; my path[pathIndex].y = iy; } my pathLength = my nx + my ny - pathIndex; if (pathIndex > 1) { for (long j = 1; j <= my pathLength; j++) { my path[j] = my path[pathIndex++]; } } DTW_Path_recode (me); if (cummulativeDists) { autoMatrix him = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, my ymin, my ymax, my ny, my dy, my y1); for (long i = 1; i <= my ny; i++) { for (long j = 1; j <= my nx; j++) { his z[i][j] = delta[i][j]; } } *cummulativeDists = him.move(); } } catch (MelderError) { Melder_throw (me, U": cannot find path."); } } /* End of file DTW.cpp */ praat-6.0.04/dwtools/DTW.h000066400000000000000000000103311261542461700152200ustar00rootroot00000000000000#ifndef _DTW_h_ #define _DTW_h_ /* DTW.h * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header djmw 20110306 Latest modification. */ #include "Spectrogram.h" #include "Polygon_extensions.h" #include "Pitch.h" #include "DurationTier.h" #include "Sound.h" #include "DTW_def.h" oo_CLASS_CREATE (DTW, Matrix); #define DTW_SAKOECHIBA 1 #define DTW_SLOPES 2 #define DTW_UNREACHABLE -1 #define DTW_FORBIDDEN -2 #define DTW_START 3 #define DTW_XANDY 2 #define DTW_X 4 #define DTW_Y 6 void DTW_Path_Query_init (DTW_Path_Query me, long ny, long nx); /* Prototype on y-axis and test on x-axis */ autoDTW DTW_create (double tminp, double tmaxp, long ntp, double dtp, double t1p, double tminc, double tmaxc, long ntc, double dtc, double t1c); void DTW_setWeights (DTW me, double wx, double wy, double wd); autoDTW DTW_swapAxes (DTW me); void DTW_findPath_bandAndSlope (DTW me, double sakoeChibaBand, int localSlope, autoMatrix *cummulativeDists); void DTW_findPath (DTW me, int matchStart, int matchEnd, int slope); // deprecated /* Obsolete Function: Calculate the minimum path (through a distance matrix). Possible constraints: matchStart: path starts at position (1,1) (bottom-left) matchEnd: path ends at (I,J) (top-right) slope: 1 no constraints 2 1/3 < slope < 3 3 1/2 < slope < 2 4 2/3 < slope < 3/2 For algorithm and DP-equations see the article (& especially table I) in: Sakoe, H. & Chiba, S. (1978), Dynamic Programming Algorithm Optimization for Spoken Word recognition, IEEE Trans. on ASSP, vol 26, 43-49. */ void DTW_Path_recode (DTW me); double DTW_getPathY (DTW me, double tx); /* Get the time Y-time that corresponds to time t (along X). */ double DTW_getYTimeFromXTime (DTW me, double tx); double DTW_getXTimeFromYTime (DTW me, double ty); long DTW_getMaximumConsecutiveSteps (DTW me, int direction); void DTW_paintDistances (DTW me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum, int garnish); void DTW_drawPath (DTW me, Graphics g, double xmin, double xmax, double ymin, double ymax, int garnish); void DTW_drawWarpX (DTW me, Graphics g, double xmin, double xmax, double ymin, double ymax, double tx, int garnish); void DTW_pathRemoveRedundantNodes (DTW me); void DTW_pathQueryRecode (DTW me); void DTW_drawDistancesAlongPath (DTW me, Graphics g, double xmin, double xmax, double dmin, double dmax, int garnish); void DTW_and_Sounds_draw (DTW me, Sound yy, Sound xx, Graphics g, double xmin, double xmax, double ymin, double ymax, int garnish); void DTW_and_Sounds_drawWarpX (DTW me, Sound yy, Sound xx, Graphics g, double xmin, double xmax, double ymin, double ymax, double tx, int garnish); autoPolygon DTW_to_Polygon (DTW me, double band, int slope); void DTW_and_Polygon_findPathInside (DTW me, Polygon thee, int localSlope, autoMatrix *cummulativeDists); autoMatrix DTW_to_Matrix_distances(DTW me); autoMatrix DTW_to_Matrix_cummulativeDistances (DTW me, double sakoeChibaBand, int slope); autoMatrix DTW_and_Polygon_to_Matrix_cummulativeDistances (DTW me, Polygon thee, int localSlope); autoDTW Matrices_to_DTW (Matrix me, Matrix thee, int matchStart, int matchEnd, int slope, double metric); autoDTW Spectrograms_to_DTW (Spectrogram me, Spectrogram thee, int matchStart, int matchEnd, int slope, double metric); autoDTW Pitches_to_DTW (Pitch me, Pitch thee, double vuv_costs, double time_weight, int matchStart, int matchEnd, int slope); autoDurationTier DTW_to_DurationTier (DTW me); void DTW_and_Matrix_replace (DTW me, Matrix thee); #endif /* _DTW_h_ */ praat-6.0.04/dwtools/DTW_and_TextGrid.cpp000066400000000000000000000234311261542461700202140ustar00rootroot00000000000000/* DTW_and_TextGrid.cpp * * Copyright (C) 1993-2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20060906 djmw 20070306: Reverse x and y. Reference should always be vertical! djmw 20110304 Thing_new */ #include "DTW_and_TextGrid.h" // begin old prototypes for compatibility reasons with the past autoTextGrid DTW_and_TextGrid_to_TextGrid_old (DTW me, TextGrid thee); autoIntervalTier DTW_and_IntervalTier_to_IntervalTier_old (DTW me, IntervalTier thee); autoTextTier DTW_and_TextTier_to_TextTier_old (DTW me, TextTier thee); // end old /* Get times from TextGrid and substitute new time form the y-times of the DTW. */ autoTextTier DTW_and_TextTier_to_TextTier (DTW me, TextTier thee, double precision) { try { if (fabs (my ymin - thy xmin) <= precision && fabs (my ymax - thy xmax) <= precision) { // map from Y to X autoTextTier him = Data_copy (thee); his xmin = my xmin; his xmax = my xmax; for (long i = 1; i <= his points -> size; i++) { TextPoint textpoint = (TextPoint) his points -> item[i]; double time = DTW_getXTimeFromYTime (me, textpoint -> number); textpoint -> number = time; } return him; } else if (fabs (my xmin - thy xmin) <= precision && fabs (my xmax - thy xmax) <= precision) { // map from X to Y autoTextTier him = Data_copy (thee); his xmin = my ymin; his xmax = my ymax; for (long i = 1; i <= his points -> size; i++) { TextPoint textpoint = (TextPoint) his points -> item[i]; double time = DTW_getYTimeFromXTime (me, textpoint -> number); textpoint -> number = time; } return him; } else { Melder_throw (U"The domain of the TextTier and one of the domains of the DTW must be equal."); } } catch (MelderError) { Melder_throw (U"TextTier not created from DTW & TextTier."); } } autoIntervalTier DTW_and_IntervalTier_to_IntervalTier (DTW me, IntervalTier thee, double precision) { try { if (fabs (my ymin - thy xmin) <= precision && fabs (my ymax - thy xmax) <= precision) { // map from Y to X autoIntervalTier him = Data_copy (thee); his xmin = my xmin; his xmax = my xmax; for (long i = 1; i <= his intervals -> size; i++) { TextInterval textinterval = (TextInterval) his intervals -> item[i]; double xmin = DTW_getXTimeFromYTime (me, textinterval -> xmin); textinterval -> xmin = xmin; double xmax = DTW_getXTimeFromYTime (me, textinterval -> xmax); textinterval -> xmax = xmax; } return him; } else if (fabs (my xmin - thy xmin) <= precision && fabs (my xmax - thy xmax) <= precision) { // map from X to Y autoIntervalTier him = Data_copy (thee); his xmin = my ymin; his xmax = my ymax; for (long i = 1; i <= his intervals -> size; i++) { TextInterval textinterval = (TextInterval) his intervals -> item[i]; double xmin = DTW_getYTimeFromXTime (me, textinterval -> xmin); textinterval -> xmin = xmin; double xmax = DTW_getYTimeFromXTime (me, textinterval -> xmax); textinterval -> xmax = xmax; } return him; } else { Melder_throw (U"The domain of the IntervalTier and one of the domains of the DTW must be equal."); } } catch (MelderError) { Melder_throw (U"IntervalTier not created from DTW & IntervalTier."); } } autoTextGrid DTW_and_TextGrid_to_TextGrid (DTW me, TextGrid thee, double precision) { try { double tmin, tmax; if (fabs (my ymin - thy xmin) <= precision && fabs (my ymax - thy xmax) <= precision) { tmin = my xmin; tmax = my xmax; } else if (fabs (my xmin - thy xmin) <= precision && fabs (my xmax - thy xmax) <= precision) { tmin = my ymin; tmax = my ymax; } else { Melder_throw (U"The domain of the TextGrid must be equal to one of the domains of the DTW."); } autoTextGrid him = TextGrid_createWithoutTiers (tmin, tmax); for (long i = 1; i <= thy tiers -> size; i++) { Function anyTier = (Function) thy tiers -> item[i]; if (anyTier -> classInfo == classIntervalTier) { autoIntervalTier tier = DTW_and_IntervalTier_to_IntervalTier (me, (IntervalTier) anyTier, precision); TextGrid_addTier_copy (him.peek(), tier.peek()); } else if (anyTier -> classInfo == classTextTier) { autoTextTier tier = DTW_and_TextTier_to_TextTier (me, (TextTier) anyTier, precision); TextGrid_addTier_copy (him.peek(), tier.peek()); } else { Melder_throw (U"Unknown tier."); } } return him; } catch (MelderError) { Melder_throw (U"TextGrid not created from DTW & TextGrid."); } } autoTable DTW_and_IntervalTier_to_Table (DTW me, IntervalTier thee, double precision) { try { long numberOfIntervals = thy intervals -> size; autoTable him = Table_createWithColumnNames (numberOfIntervals, U"tmin tmax label dist"); if (fabs (my ymin - thy xmin) <= precision && fabs (my ymax - thy xmax) <= precision) { // map from Y to X long pathIndex = 1; for (long i = 1; i <= numberOfIntervals; i++) { TextInterval textinterval = (TextInterval) thy intervals -> item[i]; double xmin = DTW_getXTimeFromYTime (me, textinterval -> xmin); double xmax = DTW_getXTimeFromYTime (me, textinterval -> xmax); long ixmin, ixmax; long numberOfFrames = Matrix_getWindowSamplesX (me, xmin, xmax, &ixmin, &ixmax); double sumOfDistances = 0; while (pathIndex < my pathLength && my path[pathIndex].x < ixmax) { sumOfDistances += my z[my path[pathIndex].y][my path[pathIndex].x]; pathIndex++; } Table_setNumericValue (him.peek(), i, 1, textinterval -> xmin); Table_setNumericValue (him.peek(), i, 2, textinterval -> xmax); Table_setStringValue (him.peek(), i, 3, textinterval -> text); Table_setNumericValue (him.peek(), i, 4, sumOfDistances / numberOfFrames); } } else if (fabs (my xmin - thy xmin) <= precision && fabs (my xmax - thy xmax) <= precision) { // map from X to Y long pathIndex = 1; for (long i = 1; i <= numberOfIntervals; i++) { TextInterval textinterval = (TextInterval) thy intervals -> item[i]; double ymin = DTW_getYTimeFromXTime (me, textinterval -> xmin); double ymax = DTW_getYTimeFromXTime (me, textinterval -> xmax); long iymin, iymax; long numberOfFrames = Matrix_getWindowSamplesY (me, ymin, ymax, &iymin, &iymax); double sumOfDistances = 0; while (pathIndex < my pathLength && my path[pathIndex].y < iymax) { sumOfDistances += my z[my path[pathIndex].y][my path[pathIndex].x]; pathIndex++; } Table_setNumericValue (him.peek(), i, 1, textinterval -> xmin); Table_setNumericValue (him.peek(), i, 2, textinterval -> xmax); Table_setStringValue (him.peek(), i, 3, textinterval -> text); Table_setNumericValue (him.peek(), i, 4, sumOfDistances / numberOfFrames); } } else { Melder_throw (U"The domain of the IntervalTier and one of the domains of the DTW must be equal."); } return him; } catch (MelderError) { Melder_throw (me, U": no Table with distances created."); } } /* Get times from TextGrid and substitute new time form the y-times of the DTW. */ autoTextTier DTW_and_TextTier_to_TextTier_old (DTW me, TextTier thee) { try { if (my xmin != thy xmin || my xmax != thy xmax) { Melder_throw (U"The domain of the TextTier and the DTW must be equal."); } autoTextTier him = Data_copy (thee); his xmin = my ymin; his xmax = my ymax; for (long i = 1; i <= his points -> size; i++) { TextPoint textpoint = (TextPoint) his points -> item[i]; double time = DTW_getPathY (me, textpoint -> number); textpoint -> number = time; } return him; } catch (MelderError) { Melder_throw (U"TextTier not created."); } } autoIntervalTier DTW_and_IntervalTier_to_IntervalTier_old (DTW me, IntervalTier thee) { try { if ( (my xmin != thy xmin) || my xmax != thy xmax) Melder_throw (U"The domain of the IntervalTier and the DTW must be equal."); autoIntervalTier him = Data_copy (thee); his xmin = my ymin; his xmax = my ymax; for (long i = 1; i <= his intervals -> size; i++) { TextInterval textinterval = (TextInterval) his intervals -> item[i]; double xmin = DTW_getPathY (me, textinterval -> xmin); textinterval -> xmin = xmin; double xmax = DTW_getPathY (me, textinterval -> xmax); textinterval -> xmax = xmax; } return him; } catch (MelderError) { Melder_throw (U"IntervalTier not created."); } } autoTextGrid DTW_and_TextGrid_to_TextGrid_old (DTW me, TextGrid thee) { try { autoTextGrid him = Thing_new (TextGrid); if (my xmin != thy xmin || my xmax != thy xmax) { Melder_throw (U"The domain of the TextGrid and the y-domain of the DTW must be equal."); } his xmin = my ymin; his xmax = my ymax; his tiers = Ordered_create (); for (long i = 1; i <= thy tiers -> size; i++) { Daata anyTier = (Daata) thy tiers -> item[i]; if (anyTier -> classInfo == classIntervalTier) { autoIntervalTier tier = DTW_and_IntervalTier_to_IntervalTier_old (me, (IntervalTier) anyTier); TextGrid_addTier_copy (him.peek(), tier.peek()); } else if (anyTier -> classInfo == classTextTier) { autoTextTier tier = DTW_and_TextTier_to_TextTier_old (me, (TextTier) anyTier); TextGrid_addTier_copy (him.peek(), tier.peek()); } else { Melder_throw (U"Unknown tier."); } } return him; } catch (MelderError) { Melder_throw (U"TextGrid not created."); } } /* End of file DTW_and_TextGrid.cpp */ praat-6.0.04/dwtools/DTW_and_TextGrid.h000066400000000000000000000025571261542461700176670ustar00rootroot00000000000000#ifndef _DTW_and_TextGrid_h_ #define _DTW_and_TextGrid_h_ /* DTW_and_TextGrid.h * * Copyright (C) 1993-2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20060906 */ #include "DTW.h" #include "TextGrid.h" #include "Table.h" autoTextTier DTW_and_TextTier_to_TextTier (DTW me, TextTier thee, double precision); autoIntervalTier DTW_and_IntervalTier_to_IntervalTier (DTW me, IntervalTier thee, double precision); autoTextGrid DTW_and_TextGrid_to_TextGrid (DTW me, TextGrid thee, double precision); /* Purpose: Create the new TextGrid with all times determined by the DTW. */ autoTable DTW_and_IntervalTier_to_Table (DTW me, IntervalTier thee, double precision); #endif /* _DTW_and_TextGrid_h_ */ praat-6.0.04/dwtools/DTW_def.h000066400000000000000000000040201261542461700160340ustar00rootroot00000000000000/* DTW_def.h * * Copyright (C) 1993-2008 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19981207 djmw 20020813 GPL header djmw 20070216 Latest modification */ #define ooSTRUCT DTW_Path oo_DEFINE_STRUCT (DTW_Path) oo_LONG (x) oo_LONG (y) oo_END_STRUCT (DTW_Path) #undef ooSTRUCT #define ooSTRUCT DTW_Path_Index oo_DEFINE_STRUCT (DTW_Path_Index) oo_LONG (ibegin) oo_LONG (iend) oo_END_STRUCT (DTW_Path_Index) #undef ooSTRUCT #define ooSTRUCT DTW_Path_xytime oo_DEFINE_STRUCT (DTW_Path_xytime) oo_DOUBLE (x) oo_DOUBLE (y) oo_END_STRUCT (DTW_Path_xytime) #undef ooSTRUCT #define ooSTRUCT DTW_Path_Query oo_DEFINE_STRUCT (DTW_Path_Query) oo_LONG (nx) oo_LONG (ny) oo_LONG (nxy) oo_STRUCT_VECTOR (DTW_Path_xytime, xytimes, nxy) oo_STRUCT_VECTOR (DTW_Path_Index, xindex, nx) oo_STRUCT_VECTOR (DTW_Path_Index, yindex, ny) oo_END_STRUCT (DTW_Path_Query) #undef ooSTRUCT #define ooSTRUCT DTW oo_DEFINE_CLASS (DTW, Matrix) oo_DOUBLE (weightedDistance) oo_LONG (pathLength) oo_STRUCT_VECTOR (DTW_Path, path, pathLength) #if ! oo_READING && ! oo_WRITING oo_DOUBLE (wx) oo_DOUBLE (wy) oo_DOUBLE (wd) oo_STRUCT (DTW_Path_Query, pathQuery) #endif #if oo_READING DTW_Path_Query_init (& pathQuery, ny, nx); DTW_Path_recode (this); #endif #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (DTW) #undef ooSTRUCT /* End of file DTW_def.h */ praat-6.0.04/dwtools/DataModeler.cpp000066400000000000000000002525531261542461700173140ustar00rootroot00000000000000/* DataModeler.cpp * * Copyright (C) 2014-2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20140217 */ #include "DataModeler.h" #include "NUM2.h" #include "NUMmachar.h" #include "SVD.h" #include "Strings_extensions.h" #include "Sound_and_LPC_robust.h" #include "Table_extensions.h" #include "oo_DESTROY.h" #include "DataModeler_def.h" #include "oo_COPY.h" #include "DataModeler_def.h" #include "oo_EQUAL.h" #include "DataModeler_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "DataModeler_def.h" #include "oo_WRITE_TEXT.h" #include "DataModeler_def.h" #include "oo_WRITE_BINARY.h" #include "DataModeler_def.h" #include "oo_READ_TEXT.h" #include "DataModeler_def.h" #include "oo_READ_BINARY.h" #include "DataModeler_def.h" #include "oo_DESCRIPTION.h" #include "DataModeler_def.h" extern machar_Table NUMfpp; void FormantModeler_getSumOfVariancesBetweenShiftedAndEstimatedTracks (FormantModeler me, int shiftDirection, long *fromFormant, long *toFormant, double var[]); Thing_implement (DataModeler, Function, 0); void structDataModeler :: v_info () { MelderInfo_writeLine (U" Time domain:"); MelderInfo_writeLine (U" Start time: ", xmin, U" seconds"); MelderInfo_writeLine (U" End time: ", xmax, U" seconds"); MelderInfo_writeLine (U" Total duration: ", xmax - xmin, U" seconds"); double ndf, rSquared = DataModeler_getCoefficientOfDetermination (this, nullptr, nullptr); double probability, chisq = DataModeler_getChiSquaredQ (this, useSigmaY, &probability, &ndf); MelderInfo_writeLine (U" Fit:"); MelderInfo_writeLine (U" Number of data points: ", numberOfDataPoints); MelderInfo_writeLine (U" Number of parameters: ", numberOfParameters); MelderInfo_writeLine (U" Each data point has ", useSigmaY == DataModeler_DATA_WEIGH_EQUAL ? U" the same weight (estimated)." : useSigmaY == DataModeler_DATA_WEIGH_SIGMA ? U"a different weight (sigmaY)." : useSigmaY == DataModeler_DATA_WEIGH_RELATIVE ? U"a different relative weight (Y_value/sigmaY)." : U"a different weight (SQRT(sigmaY))."); MelderInfo_writeLine (U" Chi squared: ", chisq); MelderInfo_writeLine (U" Number of degrees of freedom: ", ndf); MelderInfo_writeLine (U" Probability: ", probability); MelderInfo_writeLine (U" R-squared: ", rSquared); for (long ipar = 1; ipar <= numberOfParameters; ipar++) { double sigma = parameterStatus[ipar] == DataModeler_PARAMETER_FIXED ? 0 : sqrt (parameterCovariances -> data[ipar][ipar]); MelderInfo_writeLine (U" p[", ipar, U"] = ", parameter[ipar], U"; sigma = ", sigma); } } static double polynomial_evaluate (DataModeler me, double xin, double p[]) { double xpi = 1, result = p[1]; // From domain [xmin, xmax] to domain [-(xmax -xmin)/2, (xmax-xmin)/2] double x = (2.0 * xin - my xmin - my xmax) / 2.0; for (long i = 2; i <= my numberOfParameters; i++) { xpi *= x; result += p[i] * xpi; } return result; } static void polynomial_evaluateBasisFunctions (DataModeler me, double xin, double term[]) { term[1] = 1; // From domain [xmin, xmax] to domain [-(xmax -xmin)/2, (xmax-xmin)/2] double x = (2.0 * xin - my xmin - my xmax) / 2.0; for (long i = 2; i <= my numberOfParameters; i++) { term[i] = term[i-1] * x; } } static double legendre_evaluate (DataModeler me, double xin, double p[]) { // From domain [xmin, xmax] to domain [-1, 1] double x = (2.0 * xin - my xmin - my xmax) / (my xmax - my xmin); double pti, ptim1, ptim2 = 1, result = p[1]; if (my numberOfParameters > 1) { double twox = 2.0 * x, f2 = x, d = 1.0; result += p[2] * (ptim1 = x); for (long i = 3; i <= my numberOfParameters; i++) { double f1 = d++; f2 += twox; result += p[i] * (pti = (f2 * ptim1 - f1 * ptim2) / d); ptim2 = ptim1; ptim1 = pti; } } return result; } static void legendre_evaluateBasisFunctions (DataModeler me, double xin, double term[]) { term[1] = 1.0; /* transform x from domain [xmin, xmax] to domain [-1, 1] */ double x = (2.0 * xin - my xmin - my xmax) / (my xmax - my xmin); if (my numberOfParameters > 1) { double twox = 2.0 * x, f2 = term[2] = x, d = 1.0; for (long i = 3; i <= my numberOfParameters; i++) { double f1 = d++; f2 += twox; term[i] = (f2 * term[i-1] - f1 * term[i-2]) / d; } } } static void chisqFromZScores (double *zscores, long numberOfZScores, double *chisq, long *numberOfValidZScores) { long numberOfValid = numberOfZScores; double chisqt = 0.0; for (long i = 1; i <= numberOfZScores; i++) { if (NUMdefined (zscores[i])) { chisqt += zscores[i] * zscores[i]; } else { numberOfValid--; } } if (chisq) { *chisq = chisqt; } if (numberOfValidZScores) { *numberOfValidZScores = numberOfValid; } } static double DataModeler_getDataPointInverseWeight (DataModeler me, long iPoint, int useSigmaY ) { double iweight = 1.0; if (iPoint > 0 && iPoint <= my numberOfDataPoints && my dataPointStatus[iPoint] != DataModeler_DATA_INVALID) { if (useSigmaY == DataModeler_DATA_WEIGH_SIGMA) { iweight = my sigmaY[iPoint]; } else if (useSigmaY == DataModeler_DATA_WEIGH_RELATIVE) { double q = my y[iPoint] / my sigmaY[iPoint]; iweight = 500.0 / q; // } else if (useSigmaY == DataModeler_DATA_WEIGH_SQRT) { iweight = 7.071 * sqrt (my sigmaY[iPoint]); // .bw = 50 gives 50 } } return iweight; } double DataModeler_getModelValueAtX (DataModeler me, double x) { double f = NUMundefined; if (x >= my xmin && x <= my xmax) { f = my f_evaluate (me, x, my parameter); } return f; } double DataModeler_getModelValueAtIndex (DataModeler me, long index) { double f = NUMundefined; if (index > 0 && index <= my numberOfDataPoints) { f = my f_evaluate (me, my x[index], my parameter); } return f; } void DataModeler_getExtremaY (DataModeler me, double *ymin, double *ymax) { double min = 1e308, max = -min; for (long i = 1; i <= my numberOfDataPoints; i++) { if (my dataPointStatus[i] != DataModeler_DATA_INVALID) { if (my y[i] < min) { min = my y[i]; } if (my y[i] > max) { max = my y[i]; } } } if (ymin) { *ymin = min; } if (ymax) { *ymax = max; } } double DataModeler_getDataPointValue (DataModeler me, long index) { double value = NUMundefined; if (index > 0 && index <= my numberOfDataPoints && my dataPointStatus[index] != DataModeler_DATA_INVALID) { value = my y[index]; } return value; } void DataModeler_setDataPointValue (DataModeler me, long index, double value) { if (index > 0 && index <= my numberOfDataPoints) { my y[index] = value; } } void DataModeler_setDataPointSigma (DataModeler me, long index, double sigma) { if (index > 0 && index <= my numberOfDataPoints) { my sigmaY[index] = sigma; } } double DataModeler_getDataPointSigma (DataModeler me, long index) { double sigma = NUMundefined; if (index > 0 && index <= my numberOfDataPoints) { sigma = my sigmaY[index]; } return sigma; } int DataModeler_getDataPointStatus (DataModeler me, long index) { int value = DataModeler_DATA_INVALID; if (index > 0 && index <= my numberOfDataPoints) { value = my dataPointStatus[index]; } return value; } void DataModeler_setDataPointStatus (DataModeler me, long index, int status) { if (index > 0 && index <= my numberOfDataPoints) { if (status == DataModeler_DATA_VALID && ! NUMdefined (my y[index])) { Melder_throw (U"Your data value is undefined. First set the value and then its status."); } my dataPointStatus[index] = status; } } static void DataModeler_setDataPointValueAndStatus (DataModeler me, long index, double value, int dataStatus) { if (index > 0 && index <= my numberOfDataPoints) { my y[index] = value; my dataPointStatus[index] = dataStatus; } } void DataModeler_setParameterValue (DataModeler me, long index, double value, int status) { if (index > 0 && index <= my numberOfParameters) { my parameter[index] = value; my parameterStatus[index] = status; } } void DataModeler_setParameterValueFixed (DataModeler me, long index, double value) { DataModeler_setParameterValue (me, index, value, DataModeler_PARAMETER_FIXED); } double DataModeler_getParameterValue (DataModeler me, long index) { double value = NUMundefined; if (index > 0 && index <= my numberOfParameters) { value = my parameter[index]; } return value; } int DataModeler_getParameterStatus (DataModeler me, long index) { int status = DataModeler_PARAMETER_UNDEFINED; if (index > 0 && index <= my numberOfParameters) { status = my parameterStatus[index]; } return status; } double DataModeler_getParameterStandardDeviation (DataModeler me, long index) { double stdev = NUMundefined; if (index > 0 && index <= my numberOfParameters) { stdev = sqrt (my parameterCovariances -> data[index][index]); } return stdev; } double DataModeler_getVarianceOfParameters (DataModeler me, long fromIndex, long toIndex, long *numberOfFreeParameters) { double variance = NUMundefined; if (toIndex < fromIndex || (toIndex == 0 && fromIndex == 0)) { fromIndex = 1; toIndex = my numberOfParameters; } long numberOfParameters = 0; if (fromIndex <= toIndex && fromIndex > 0 && toIndex <= my numberOfParameters) { variance = 0; for (long index = fromIndex; index <= toIndex; index++) { if (my parameterStatus[index] != DataModeler_PARAMETER_FIXED) { variance += my parameterCovariances -> data[index][index]; numberOfParameters++; } } } if (numberOfFreeParameters) { *numberOfFreeParameters = numberOfParameters; } return variance; } void DataModeler_setParametersFree (DataModeler me, long fromIndex, long toIndex) { if (toIndex < fromIndex || (toIndex == 0 && fromIndex == 0)) { fromIndex = 1; toIndex = my numberOfParameters; } if (fromIndex <= toIndex && fromIndex > 0 && toIndex <= my numberOfParameters) { for (long index = fromIndex; index <= toIndex; index++) { my parameterStatus[index] = DataModeler_PARAMETER_FREE; } } } void DataModeler_setParameterValuesToZero (DataModeler me, double numberOfSigmas) { long numberOfChangedParameters = 0; for (long i = my numberOfParameters; i > 0; i--) { if (my parameterStatus[i] != DataModeler_PARAMETER_FIXED) { double value = my parameter[i]; double sigmas = numberOfSigmas * DataModeler_getParameterStandardDeviation (me, i); if ((value - sigmas) * (value + sigmas) < 0) { DataModeler_setParameterValueFixed (me, i, 0.0); numberOfChangedParameters++; } } } } static long DataModeler_getNumberOfFreeParameters (DataModeler me) { long numberOfFreeParameters = 0; for (long i = 1; i <= my numberOfParameters; i++) { if (my parameterStatus[i] == DataModeler_PARAMETER_FREE) numberOfFreeParameters++; } return numberOfFreeParameters; } long DataModeler_getNumberOfFixedParameters (DataModeler me) { return my numberOfParameters - DataModeler_getNumberOfFreeParameters (me); } static long DataModeler_getNumberOfValidDataPoints (DataModeler me) { long numberOfValidDataPoints = 0; for (long i = 1; i <= my numberOfDataPoints; i++) { if (my dataPointStatus[i] != DataModeler_DATA_INVALID) { numberOfValidDataPoints++; } } return numberOfValidDataPoints; } long DataModeler_getNumberOfInvalidDataPoints (DataModeler me) { return my numberOfDataPoints - DataModeler_getNumberOfValidDataPoints (me); } void DataModeler_setTolerance (DataModeler me, double tolerance) { my tolerance = tolerance > 0.0 ? tolerance : my numberOfDataPoints * NUMfpp -> eps; } double DataModeler_getDegreesOfFreedom (DataModeler me) { long numberOfDataPoints = 0; for (long i = 1; i <= my numberOfDataPoints; i++) { if (my dataPointStatus[i] != DataModeler_DATA_INVALID) { numberOfDataPoints++; } } double ndf = numberOfDataPoints - DataModeler_getNumberOfFreeParameters (me); return ndf; } void DataModeler_getZScores (DataModeler me, int useSigmaY, double zscores[]) { try { Melder_assert (zscores != nullptr); double estimatedSigmaY; if (useSigmaY == DataModeler_DATA_WEIGH_EQUAL) { long numberOfValidDataPoints; double rss = DataModeler_getResidualSumOfSquares (me, &numberOfValidDataPoints); if (numberOfValidDataPoints < 2) { Melder_throw (U"Not enough data points to calculate sigma."); } estimatedSigmaY = rss / (numberOfValidDataPoints - 1); } for (long i = 1; i <= my numberOfDataPoints; i++) { double value = NUMundefined; if (my dataPointStatus[i] != DataModeler_DATA_INVALID) { double estimate = my f_evaluate (me, my x[i], my parameter); double sigma = useSigmaY == DataModeler_DATA_WEIGH_EQUAL ? estimatedSigmaY : DataModeler_getDataPointInverseWeight (me, i, useSigmaY); value = (my y[i] - estimate) / sigma; } zscores[i] = value; } } catch (MelderError) { Melder_throw (U"No z-scores calculated."); } } // chisq and zscores may be the same arrays! static void DataModeler_getChisqScoresFromZScores (DataModeler me, double *zscores, bool substituteAverage, double *chisq) { Melder_assert (zscores != nullptr && chisq != nullptr); long numberOfDefined = my numberOfDataPoints; double sumchisq = 0.0; for (long i = 1; i <= my numberOfDataPoints; i++) { if (NUMdefined (zscores[i])) { chisq[i] = zscores[i] * zscores[i]; sumchisq += chisq[i]; } else { numberOfDefined--; chisq[i] = NUMundefined; } } if (substituteAverage && numberOfDefined != my numberOfDataPoints && numberOfDefined > 0) { for (long i = 1; i <= my numberOfDataPoints; i++) { if (! NUMdefined (chisq[i])) { chisq[i] = sumchisq / numberOfDefined; } } } } double DataModeler_getChiSquaredQ (DataModeler me, int useSigmaY, double *probability, double *ndf) { double chisq; long numberOfValidZScores; autoNUMvector zscores (1, my numberOfDataPoints); DataModeler_getZScores (me, useSigmaY, zscores.peek()); chisqFromZScores (zscores.peek(), my numberOfDataPoints, & chisq, & numberOfValidZScores); double dof = numberOfValidZScores; dof = useSigmaY == DataModeler_DATA_WEIGH_EQUAL ? dof - 1.0 : dof; // we loose one dof if sigma is estimated from the data if (probability) { *probability = NUMchiSquareQ (chisq, dof); } if (ndf) { *ndf = dof; } return chisq; } double DataModeler_getWeightedMean (DataModeler me) { double ysum = 0.0, wsum = 0.0; for (long i = 1; i <= my numberOfDataPoints; i++) { if (my dataPointStatus[i] != DataModeler_DATA_INVALID) { double s = DataModeler_getDataPointInverseWeight (me, i, my useSigmaY); double weight = 1.0 / (s * s); ysum += my y[i] * weight; wsum += weight; } } return ysum / wsum; } double DataModeler_getCoefficientOfDetermination (DataModeler me, double *ssreg, double *sstot) { /* We cannot use the standard expressions for ss_tot, and ss_reg because our data are weighted by 1 / sigma[i]. * We need the weighted mean and we need to weigh all sums-of-squares accordingly; * if all sigma[i] terms are equal, the formulas reduce to the standard ones. * Ref: A. Buse (1973): Goodness of Fit in Generalized Least Squares Estimation, The American Statician, vol 27, 106-108 */ double ymean = DataModeler_getWeightedMean (me); double ss_tot = 0.0, ss_reg = 0.0; for (long i = 1; i <= my numberOfDataPoints; i++) { if (my dataPointStatus[i] != DataModeler_DATA_INVALID) { double s = DataModeler_getDataPointInverseWeight (me, i, my useSigmaY); double diff = (my y[i] - ymean) / s; ss_tot += diff * diff; // total sum of squares double estimate = my f_evaluate (me, my x[i], my parameter); diff = (estimate - my y[i]) / s; ss_reg += diff * diff; // regression sum of squares } } double rSquared = ss_tot > 0.0 ? 1.0 - ss_reg / ss_tot : 1.0; if (ssreg) { *ssreg = ss_tot - ss_reg; } if (sstot) { *sstot = ss_tot; } return rSquared; } static void DataModeler_drawBasisFunction_inside (DataModeler me, Graphics g, double xmin, double xmax, double ymin, double ymax, long iterm, bool scale, long numberOfPoints) { if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } autoNUMvector x (1, numberOfPoints); autoNUMvector y (1, numberOfPoints); autoNUMvector term (1, my numberOfParameters); for (long i = 1; i <= numberOfPoints; i++) { x[i] = xmin + (i - 0.5) * (xmax - xmin) / numberOfPoints; my f_evaluateBasisFunctions (me, x[i], term.peek()); y[i] = term[iterm]; y[i] = scale ? y[i] * my parameter[iterm] : y[i]; } if (ymax <= ymin) { ymin = 1e308; ymax = -ymin; for (long i = 1; i <= numberOfPoints; i++) { ymax = y[i] > ymax ? y[i] : ymax; ymin = y[i] < ymin ? y[i] : ymin; } } Graphics_setWindow (g, xmin, xmax, ymin, ymax); for (long i = 2; i <= numberOfPoints; i++) { Graphics_line (g, x[i-1], y[i-1], x[i], y[i]); } } static long DataModeler_drawingSpecifiers_x (DataModeler me, double *xmin, double *xmax, long *ixmin, long *ixmax) { if (*xmax <= *xmin) { *xmin = my xmin; *xmax = my xmax; } *ixmin = 2; while (my x[*ixmin] < *xmin && *ixmin < my numberOfDataPoints) { (*ixmin)++; } (*ixmin)--; *ixmax = my numberOfDataPoints - 1; while (my x[*ixmax] > *xmax && *ixmax > 1) { (*ixmax)--; } (*ixmax)++; return *ixmax - *ixmin + 1; } void DataModeler_drawOutliersMarked_inside (DataModeler me, Graphics g, double xmin, double xmax, double ymin, double ymax, double numberOfSigmas, int useSigmaY, char32 *mark, int marksFontSize, double horizontalOffset_mm) { long ixmin, ixmax; if (DataModeler_drawingSpecifiers_x (me, &xmin, &xmax, &ixmin, &ixmax) < 1) return; autoNUMvector zscores (1, my numberOfDataPoints); DataModeler_getZScores (me, useSigmaY, zscores.peek()); double horizontalOffset_wc = Graphics_dxMMtoWC (g, horizontalOffset_mm); Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_setFontSize (g, marksFontSize); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); int currentFontSize = Graphics_inqFontSize (g); for (long idata = 1; idata <= my numberOfDataPoints; idata++) { if (my dataPointStatus[idata] != DataModeler_DATA_INVALID) { double x = my x[idata], y = my y[idata]; if (x >= xmin && x <= xmax && y >= ymin && y <= ymax) { if (fabs (zscores[idata]) > numberOfSigmas) { Graphics_text (g, x + horizontalOffset_wc, y, mark); } } } } Graphics_setFontSize (g, currentFontSize); } void DataModeler_draw_inside (DataModeler me, Graphics g, double xmin, double xmax, double ymin, double ymax, int estimated, long numberOfParameters, int errorbars, int connectPoints, double barWidth_mm, double horizontalOffset_mm, int drawDots) { if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } long ixmin = 2; while (my x[ixmin] < xmin && ixmin < my numberOfDataPoints) { ixmin++; } ixmin--; long ixmax = my numberOfDataPoints - 1; while (my x[ixmax] > xmax && ixmax > 1) { ixmax--; } ixmax++; if (ixmin >= ixmax) { return; // nothing to draw } numberOfParameters = numberOfParameters > my numberOfParameters ? my numberOfParameters : numberOfParameters; autoNUMvector parameter (1, my numberOfParameters); NUMvector_copyElements (my parameter, parameter.peek(), 1, numberOfParameters); Graphics_setWindow (g, xmin, xmax, ymin, ymax); double horizontalOffset_wc = Graphics_dxMMtoWC (g, horizontalOffset_mm); double barWidth_wc = barWidth_mm <= 0.0 ? 0.0 : Graphics_dxMMtoWC (g, barWidth_mm); double x1, y1, x2, y2; bool x1defined = false, x2defined = false; for (long idata = ixmin; idata <= ixmax; idata++) { if (my dataPointStatus[idata] != DataModeler_DATA_INVALID) { double x = my x[idata], y = my y[idata]; if (! x1defined) { x1 = x; y1 = estimated ? my f_evaluate (me, x, parameter.peek()) : y; x1defined = true; } else { x2 = x; y2 = estimated ? my f_evaluate (me, x, parameter.peek()) : y; x2defined = true; } if (x1defined && drawDots) { if (y >= ymin && y <= ymax) { Graphics_speckle (g, x + horizontalOffset_wc, y); } } if (x2defined) { // if (x1defined && x2defined) if (connectPoints) { double xo1, yo1, xo2, yo2; if (NUMclipLineWithinRectangle (x1 + horizontalOffset_wc, y1, x2 + horizontalOffset_wc, y2, xmin, ymin, xmax, ymax, &xo1, &yo1, &xo2, &yo2)) { Graphics_line (g, xo1, yo1, xo2, yo2); } // Graphics_line (g, x1 + horizontalOffset_wc, y1, x2 + horizontalOffset_wc, y2); } x1 = x; y1 = y2; } if (x1defined && errorbars != 0) { double sigma = my sigmaY[idata]; // DataModeler_getDataPointInverseWeight ? double ym = y1; double yt = ym + 0.5 * sigma, yb = ym - 0.5 * sigma; if (estimated) { yt = (y - y1) > 0.0 ? y : y1; yb = (y - y1) > 0.0 ? y1 : y; } int topOutside = yt > ymax, bottomOutside = yb < ymin; yt = topOutside ? ymax : yt; yb = bottomOutside ? ymin : yb; Graphics_line (g, x1 + horizontalOffset_wc, yb, x1 + horizontalOffset_wc, yt); if (barWidth_wc > 0.0 && ! estimated) { double xl = x1 - 0.5 * barWidth_wc + horizontalOffset_wc; double xr = xl + barWidth_wc; if (! topOutside) { Graphics_line (g, xl, yt, xr, yt); } if (! bottomOutside) { Graphics_line (g, xl, yb, xr, yb); } } } } } } void DataModeler_drawTrack_inside (DataModeler me, Graphics g, double xmin, double xmax, double ymin, double ymax, int estimated, long numberOfParameters, double horizontalOffset_mm) { int errorbars = 0, connectPoints = 1; double barWidth_mm = 0; DataModeler_draw_inside (me, g, xmin, xmax, ymin, ymax, estimated, numberOfParameters, errorbars, connectPoints, barWidth_mm, horizontalOffset_mm, 0); } void DataModeler_drawTrack (DataModeler me, Graphics g, double xmin, double xmax, double ymin, double ymax, int estimated, long numberOfParameters, double horizontalOffset_mm, int garnish) { if (ymax <= ymin) { DataModeler_getExtremaY (me, &ymin, &ymax); } Graphics_setInner (g); DataModeler_drawTrack_inside (me, g, xmin, xmax, ymin, ymax, estimated, numberOfParameters, horizontalOffset_mm); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); } } void DataModeler_speckle_inside (DataModeler me, Graphics g, double xmin, double xmax, double ymin, double ymax, int estimated, long numberOfParameters, int errorbars, double barWidth_mm, double horizontalOffset_mm) { int connectPoints = 0; DataModeler_draw_inside (me, g, xmin, xmax, ymin, ymax, estimated, numberOfParameters, errorbars, connectPoints, barWidth_mm, horizontalOffset_mm, 1); } void DataModeler_speckle (DataModeler me, Graphics g, double xmin, double xmax, double ymin, double ymax, int estimated, long numberOfParameters, int errorbars, double barWidth_mm, double horizontalOffset_mm, int garnish) { if (ymax <= ymin) { DataModeler_getExtremaY (me, &ymin, &ymax); } Graphics_setInner (g); DataModeler_speckle_inside (me, g, xmin, xmax, ymin, ymax, estimated, numberOfParameters, errorbars, barWidth_mm, horizontalOffset_mm); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); } } autoTable DataModeler_to_Table_zscores (DataModeler me, int useSigmaY) { try { autoTable ztable = Table_createWithColumnNames (my numberOfDataPoints, U"x z"); autoNUMvector zscores (1, my numberOfDataPoints); DataModeler_getZScores (me, useSigmaY, zscores.peek()); for (long i = 1; i <= my numberOfDataPoints; i++) { Table_setNumericValue (ztable.peek(), i, 1, my x[i]); Table_setNumericValue (ztable.peek(), i, 2, zscores[i]); } return ztable; } catch (MelderError) { Melder_throw (U"Table not created."); } } static void DataModeler_normalProbabilityPlot (DataModeler me, Graphics g, int useSigmaY, long numberOfQuantiles, double numberOfSigmas, int labelSize, const char32 *label, int garnish) { try { autoTable thee = DataModeler_to_Table_zscores (me, useSigmaY); Table_normalProbabilityPlot (thee.peek(), g, 2, numberOfQuantiles, numberOfSigmas, labelSize, label, garnish); } catch (MelderError) { // ignore } } void DataModeler_setBasisFunctions (DataModeler me, int type) { if (type == DataModeler_TYPE_LEGENDRE) { my f_evaluate = legendre_evaluate; my f_evaluateBasisFunctions = legendre_evaluateBasisFunctions; } else { my f_evaluate = polynomial_evaluate; my f_evaluateBasisFunctions = polynomial_evaluateBasisFunctions; } my type = type; } void DataModeler_init (DataModeler me, double xmin, double xmax, long numberOfDataPoints, long numberOfParameters, int type) { my xmin = xmin; my xmax = xmax; DataModeler_setBasisFunctions (me, type); my numberOfDataPoints = numberOfDataPoints; my x = NUMvector (1, numberOfDataPoints); my y = NUMvector (1, numberOfDataPoints); my sigmaY = NUMvector (1, numberOfDataPoints); my dataPointStatus = NUMvector (1, numberOfDataPoints); my numberOfParameters = numberOfParameters; if (numberOfParameters <= 0) { Melder_throw (U"The number of parameters must be greater than zero."); } if (numberOfParameters > numberOfDataPoints) { Melder_throw (U"The number of parameters must be smaller than the number of data points"); } my parameter = NUMvector (1, numberOfParameters); my parameterStatus = NUMvector (1, numberOfParameters); my parameterNames = Strings_createFixedLength (numberOfParameters); my parameterCovariances = Covariance_create (numberOfParameters); } autoDataModeler DataModeler_create (double xmin, double xmax, long numberOfDataPoints, long numberOfParameters, int type) { try { autoDataModeler me = Thing_new (DataModeler); DataModeler_init (me.peek(), xmin, xmax, numberOfDataPoints, numberOfParameters, type); my xmin = xmin; my xmax = xmax; return me; } catch (MelderError) { Melder_throw (U"DataModeler not created."); } } autoDataModeler DataModeler_createSimple (double xmin, double xmax, long numberOfDataPoints, char32 *parameters, double gaussianNoiseStd, int type) { try { long numberOfParameters; autoNUMvector parameter (NUMstring_to_numbers (parameters, &numberOfParameters), 1); if (numberOfParameters < 1) { Melder_throw (U"At least one parameter must be defined."); } if (xmin >= xmax) { Melder_throw (U"The domain must be defined properly."); } autoDataModeler me = DataModeler_create (xmin, xmax, numberOfDataPoints, numberOfParameters, type); for (long i = 1; i <= numberOfParameters; i++) { my parameter[i] = parameter[i]; // parameter status ok } // generate the data that belong to the parameter values for (long i = 1; i <= numberOfDataPoints; i++) { my x[i] = xmin + (i - 0.5) * (xmax - xmin) / numberOfDataPoints; double modelY = my f_evaluate (me.peek(), my x[i], my parameter); my y[i] = modelY + NUMrandomGauss (0.0, gaussianNoiseStd); my sigmaY[i] = NUMundefined; } my useSigmaY = DataModeler_DATA_WEIGH_EQUAL; return me; } catch (MelderError) { Melder_throw (U"No simple DataModeler created."); } } void DataModeler_fit (DataModeler me) { try { // Count the number of parameters to be fitted long numberOfParameters = DataModeler_getNumberOfFreeParameters (me); if (numberOfParameters == 0) return; long numberOfDataPoints = DataModeler_getNumberOfValidDataPoints (me); autoNUMvector b (1, numberOfDataPoints); autoNUMvector term (1, my numberOfParameters); autoNUMvector parameter (1, my numberOfParameters); autoNUMmatrix design (1, numberOfDataPoints, 1, numberOfParameters); // For function evaluation with only the FIXED parameters for (long ipar = 1; ipar <= my numberOfParameters; ipar++) { parameter[ipar] = my parameterStatus[ipar] == DataModeler_PARAMETER_FIXED ? my parameter[ipar] : 0.0; } // estimate sigma if we weigh all datapoint equally. // This is necessary to get the parameter covariances right double sigmaY = my useSigmaY == DataModeler_DATA_WEIGH_EQUAL ? DataModeler_estimateSigmaY (me) : NUMundefined; long idata = 0; // Accumulate coefficients of the design matrix for (long i = 1; i <= my numberOfDataPoints; i++) { if (my dataPointStatus[i] != DataModeler_DATA_INVALID) { // function evaluation with only the FIXED parameters double xi = my x[i], yi = my y[i]; double yFixed = my f_evaluate (me, xi, parameter.peek()); double si = my useSigmaY != DataModeler_DATA_WEIGH_EQUAL ? DataModeler_getDataPointInverseWeight (me, i, my useSigmaY) : sigmaY; // individual terms of the function my f_evaluateBasisFunctions (me, xi, term.peek()); long ipar = 0; ++idata; for (long j = 1; j <= my numberOfParameters; j++) { if (my parameterStatus[j] != DataModeler_PARAMETER_FIXED) { design[idata][++ipar] = term[j] / si; } } // only 'residual variance' must be explained by the model b[idata] = (yi - yFixed) / si; } } // Singular value decomposition and evaluation of the singular values autoSVD thee = SVD_create_d (design.peek(), numberOfDataPoints, numberOfParameters); if (! NUMfpp) { NUMmachar (); } SVD_zeroSmallSingularValues (thee.peek(), my tolerance > 0.0 ? my tolerance : numberOfDataPoints * NUMfpp -> eps); SVD_solve (thee.peek(), b.peek(), parameter.peek()); // re-use parameter // Put the calculated parameters at the correct position in 'my p' Covariance cov = my parameterCovariances; long ipar = 0; for (long j = 1; j <= my numberOfParameters; j++) { if (my parameterStatus[j] != DataModeler_PARAMETER_FIXED) { my parameter[j] = parameter[++ipar]; } cov -> centroid[j] = my parameter[j]; } cov -> numberOfObservations = numberOfDataPoints; // estimate covariances between parameters if (numberOfParameters < my numberOfParameters) { autoNUMmatrix covtmp (1, numberOfParameters, 1, numberOfParameters); SVD_getSquared (thee.peek(), covtmp.peek(), true); // Set fixed parameters variances and covariances to zero. for (long i = 1; i <= my numberOfParameters; i++) { for (long j = i; j <= my numberOfParameters; j++) { cov -> data[i][j] = cov -> data[j][i] = 0.0; } } ipar = 0; for (long i = 1; i <= my numberOfParameters; i++) { if (my parameterStatus[i] != DataModeler_PARAMETER_FIXED) { long jpar = 0; ipar++; for (long j = 1; j <= my numberOfParameters; j++) { if (my parameterStatus[j] != DataModeler_PARAMETER_FIXED) { jpar++; cov -> data[i][j] = covtmp[ipar][jpar]; } } } } } else { SVD_getSquared (thee.peek(), cov -> data, true); } } catch (MelderError) { Melder_throw (U"DataModeler no fit."); } } void DataModeler_setDataWeighing (DataModeler me, int useSigmaY) { if (my useSigmaY != useSigmaY) { my useSigmaY = useSigmaY; DataModeler_fit (me); // because sigma has changed! } } autoCovariance DataModeler_to_Covariance_parameters (DataModeler me) { try { autoCovariance cov = (Covariance) Data_copy (my parameterCovariances); return cov; } catch (MelderError) { Melder_throw (U"Covariance not created."); } } autoDataModeler Table_to_DataModeler (Table me, double xmin, double xmax, long xcolumn, long ycolumn, long scolumn, long numberOfParameters, int type) { try { Table_checkSpecifiedColumnNumberWithinRange (me, xcolumn); Table_checkSpecifiedColumnNumberWithinRange (me, ycolumn); int useSigmaY = scolumn > 0; if (useSigmaY) { Table_checkSpecifiedColumnNumberWithinRange (me, scolumn); } long numberOfRows = my rows -> size, numberOfData = 0; autoNUMvector x (1, numberOfRows), y (1, numberOfRows), sy (1, numberOfRows); for (long i = 1; i <= numberOfRows; i++) { double val = Table_getNumericValue_Assert (me, i, xcolumn); if (NUMdefined (val)) { numberOfData++; x[numberOfData] = val; if (numberOfData > 1) { if (val < x[numberOfData - 1]) { Melder_throw (U"Data with x-values must be sorted."); } else if (val == x[numberOfData - 1]) { Melder_throw (U"All x-values must be different."); } } y[numberOfData] = Table_getNumericValue_Assert (me, i, ycolumn); sy[numberOfData] = useSigmaY ? Table_getNumericValue_Assert (me, i, scolumn) : 1; } } if (xmax <= xmin) { NUMvector_extrema (x.peek(), 1, numberOfData, &xmin, &xmax); } if (xmin >= xmax) { Melder_throw (U"Range of x-values too small."); } long numberOfDataPoints = 0, validData = 0; for (long i = 1; i <= numberOfData; i++) { if (x[i] >= xmin && x[i] <= xmax) { numberOfDataPoints++; } } autoDataModeler thee = DataModeler_create (xmin, xmax, numberOfDataPoints, numberOfParameters, type); numberOfDataPoints = 0; for (long i = 1; i <= numberOfData; i++) { if (x[i] >= xmin && x[i] <= xmax) { thy x[++numberOfDataPoints] = x[i]; thy dataPointStatus[numberOfDataPoints] = DataModeler_DATA_INVALID; if (NUMdefined (y[i])) { thy y[numberOfDataPoints] = y[i]; thy sigmaY[numberOfDataPoints] = sy[i]; thy dataPointStatus[numberOfDataPoints] = DataModeler_DATA_VALID; validData++; } } } thy useSigmaY = useSigmaY; thy numberOfDataPoints = numberOfDataPoints; thy tolerance = 1e-5; if (validData < numberOfParameters) { Melder_throw (U"The number of parameters must not exceed the number of data points."); } DataModeler_setDataWeighing (thee.peek(), DataModeler_DATA_WEIGH_SIGMA); DataModeler_fit (thee.peek()); return thee; } catch (MelderError) { Melder_throw (U"Datamodeler not created from Table."); } } Thing_implement (FormantModeler, Function, 0); void structFormantModeler :: v_info () { MelderInfo_writeLine (U"Time domain:"); MelderInfo_writeLine (U" Start time: ", xmin, U" seconds"); MelderInfo_writeLine (U" End time: ", xmax, U" seconds"); MelderInfo_writeLine (U" Total duration: ", xmax - xmin, U" seconds"); for (long iformant = 1; iformant <= trackmodelers -> size; iformant++) { DataModeler ffi = (DataModeler) trackmodelers -> item[iformant]; MelderInfo_writeLine (U"Formant ", iformant); ffi -> v_info(); } } double DataModeler_getResidualSumOfSquares (DataModeler me, long *numberOfDataPoints) { long n = 0; double rss = 0.0; for (long i = 1; i <= my numberOfDataPoints; i++) { if (my dataPointStatus[i] != DataModeler_DATA_INVALID) { ++n; double dif = my y[i] - my f_evaluate (me, my x[i], my parameter); rss += dif * dif; } } if (numberOfDataPoints) { *numberOfDataPoints = n; } return n > 0 ? rss : NUMundefined; } double DataModeler_estimateSigmaY (DataModeler me) { try { long numberOfDataPoints = 0; autoNUMvector y (1, my numberOfDataPoints); for (long i = 1; i <= my numberOfDataPoints; i++) { if (my dataPointStatus[i] != DataModeler_DATA_INVALID) { y[++numberOfDataPoints] = my y[i]; } } double variance; NUMvector_avevar (y.peek(), numberOfDataPoints, nullptr, &variance); double sigma = NUMdefined (variance) ? sqrt (variance / (numberOfDataPoints - 1)) : NUMundefined; return sigma; } catch (MelderError) { Melder_throw (U"Cannot estimate sigma."); } } double FormantModeler_getStandardDeviation (FormantModeler me, long iformant) { double sigma = NUMundefined; if (iformant > 0 && iformant <= my trackmodelers -> size) { DataModeler ff = (DataModeler) my trackmodelers -> item[iformant]; sigma = DataModeler_estimateSigmaY (ff); } return sigma; } double FormantModeler_getDataPointValue (FormantModeler me, long iformant, long index) { double value = NUMundefined; if (iformant > 0 && iformant <= my trackmodelers -> size) { DataModeler ff = (DataModeler) my trackmodelers -> item[iformant]; value = DataModeler_getDataPointValue (ff, index); } return value; } void FormantModeler_setDataPointValue (FormantModeler me, long iformant, long index, double value) { if (iformant > 0 && iformant <= my trackmodelers -> size) { DataModeler ff = (DataModeler) my trackmodelers -> item[iformant]; DataModeler_setDataPointValue (ff, index, value); } } double FormantModeler_getDataPointSigma (FormantModeler me, long iformant, long index) { double sigma = NUMundefined; if (iformant > 0 && iformant <= my trackmodelers -> size) { DataModeler ff = (DataModeler) my trackmodelers -> item[iformant]; sigma = DataModeler_getDataPointSigma (ff, index); } return sigma; } void FormantModeler_setDataPointSigma (FormantModeler me, long iformant, long index, double sigma) { if (iformant > 0 && iformant <= my trackmodelers -> size) { DataModeler ff = (DataModeler) my trackmodelers -> item[iformant]; DataModeler_setDataPointSigma (ff, index, sigma); } } int FormantModeler_getDataPointStatus (FormantModeler me, long iformant, long index) { int value = DataModeler_DATA_INVALID; if (iformant > 0 && iformant <= my trackmodelers -> size) { DataModeler ff = (DataModeler) my trackmodelers -> item[iformant]; value = DataModeler_getDataPointStatus (ff, index); } return value; } void FormantModeler_setDataPointStatus (FormantModeler me, long iformant, long index, int status) { if (iformant > 0 && iformant <= my trackmodelers -> size) { DataModeler ff = (DataModeler) my trackmodelers -> item[iformant]; DataModeler_setDataPointStatus (ff, index, status); } } static void FormantModeler_setDataPointValueAndStatus (FormantModeler me, long iformant, long index, double value, int dataStatus) { if (iformant > 0 && iformant <= my trackmodelers -> size) { DataModeler ff = (DataModeler) my trackmodelers -> item[iformant]; DataModeler_setDataPointValueAndStatus (ff, index, value, dataStatus); } } void FormantModeler_setParameterValueFixed (FormantModeler me, long iformant, long index, double value) { if (iformant > 0 && iformant <= my trackmodelers -> size) { DataModeler ffi = (DataModeler) my trackmodelers -> item[iformant]; DataModeler_setParameterValueFixed (ffi, index, value); } } void FormantModeler_setParametersFree (FormantModeler me, long fromFormant, long toFormant, long fromIndex, long toIndex) { long numberOfFormants = my trackmodelers -> size; if (toFormant < fromFormant || (fromFormant == toFormant && fromFormant == 0)) { fromFormant = 1; toFormant= numberOfFormants; } if (! (toFormant >= 1 && toFormant <= numberOfFormants && fromFormant >= 1 && fromFormant <= numberOfFormants && fromFormant <= toFormant)) { Melder_throw (U"Formant number(s) must be in the interval [1, ", numberOfFormants, U"]."); } for (long iformant = fromFormant; iformant <= toFormant; iformant++) { DataModeler ffi = (DataModeler) my trackmodelers -> item[iformant]; DataModeler_setParametersFree (ffi, fromIndex, toIndex); } } void FormantModeler_setDataWeighing (FormantModeler me, long fromFormant, long toFormant, int useSigmaY) { long numberOfFormants = my trackmodelers -> size; if (toFormant < fromFormant || (fromFormant == toFormant && fromFormant == 0)) { fromFormant = 1; toFormant= numberOfFormants; } if (! (toFormant >= 1 && toFormant <= numberOfFormants && fromFormant >= 1 && fromFormant <= numberOfFormants && fromFormant <= toFormant)) { Melder_throw (U"Formant number(s) must be in the interval [1, ", numberOfFormants, U"]."); } for (long iformant = fromFormant; iformant <= toFormant; iformant++) { DataModeler ffi = (DataModeler) my trackmodelers -> item[iformant]; DataModeler_setDataWeighing (ffi, useSigmaY); } } void FormantModeler_fit (FormantModeler me) { for (long iformant = 1; iformant <= my trackmodelers -> size; iformant++) { DataModeler ffi = (DataModeler) my trackmodelers -> item[iformant]; DataModeler_fit (ffi); } } void FormantModeler_drawBasisFunction (FormantModeler me, Graphics g, double tmin, double tmax, double fmin, double fmax, long iformant, long iterm, bool scaled, long numberOfPoints, int garnish) { if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } if (iformant < 1 || iformant > my trackmodelers -> size) { return; } Graphics_setInner (g); DataModeler ffi = (DataModeler) my trackmodelers -> item[iformant]; DataModeler_drawBasisFunction_inside (ffi, g, tmin, tmax, fmin, fmax, iterm, scaled, numberOfPoints); Graphics_unsetInner (g); if (garnish) { Graphics_inqWindow (g, &tmin, &tmax, &fmin, &fmax); Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Time (s)"); Graphics_textLeft (g, true, (scaled ? U"Frequency (Hz)" : U"Amplitude")); Graphics_marksBottom (g, 2, true, true, false); Graphics_markLeft (g, fmin, true, true, false, U""); Graphics_markLeft (g, fmax, true, true, false, U""); } } static long FormantModeler_drawingSpecifiers_x (FormantModeler me, double *xmin, double *xmax, long *ixmin, long *ixmax) { DataModeler fm = (DataModeler) my trackmodelers -> item[1]; return DataModeler_drawingSpecifiers_x (fm, xmin, xmax, ixmin, ixmax); } static void FormantModeler_getCumulativeChiScores (FormantModeler me, int useSigmaY, double chisq[]) { try { long numberOfDataPoints = FormantModeler_getNumberOfDataPoints (me); long numberOfFormants = my trackmodelers -> size; autoNUMvector zscores (1, numberOfDataPoints); for (long iformant = 1; iformant <= numberOfFormants; iformant++) { DataModeler fm = (DataModeler) my trackmodelers -> item[iformant]; DataModeler_getZScores (fm, useSigmaY, zscores.peek()); DataModeler_getChisqScoresFromZScores (fm, zscores.peek(), true, zscores.peek()); // undefined -> average for (long i = 1; i <= numberOfDataPoints; i++) { chisq[i] += zscores[i]; } } } catch (MelderError) { Melder_throw (me, U"cannot determine cummulative chi squares."); } } void FormantModeler_drawVariancesOfShiftedTracks (FormantModeler me, Graphics g, double xmin, double xmax, double ymin, double ymax, int shiftDirection, long fromFormant, long toFormant, int garnish) { try { long ixmin, ixmax; if (FormantModeler_drawingSpecifiers_x (me, &xmin, &xmax, &ixmin, &ixmax) < 1) { Melder_throw (me, U" not enough data points in drawing range."); } long numberOfDataPoints = FormantModeler_getNumberOfDataPoints (me); autoNUMvector var (1, numberOfDataPoints); autoNUMvector varShifted (1, numberOfDataPoints); FormantModeler_getSumOfVariancesBetweenShiftedAndEstimatedTracks (me, shiftDirection, &fromFormant, &toFormant, varShifted.peek()); FormantModeler_getSumOfVariancesBetweenShiftedAndEstimatedTracks (me, 0, &fromFormant, &toFormant, var.peek()); for (long i = ixmin + 1; i <= ixmax; i++) { if (NUMdefined (varShifted[i]) && NUMdefined (var[i])) { var[i] -= varShifted[i]; } } if (ymax <= ymin) { NUMvector_extrema (var.peek(), ixmin, ixmax, &ymin, &ymax); } Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); DataModeler thee = (DataModeler) my trackmodelers -> item[1]; while (! NUMdefined (var[ixmin]) && ixmin <= ixmax) { ixmin++; } double xp = thy x[ixmin], yp = var[ixmin]; for (long i = ixmin + 1; i <= ixmax; i++) { if (NUMdefined (var[i])) { Graphics_line (g, xp, yp, thy x[i], var[i]); xp = thy x[i]; yp = var[i]; } } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); } } catch (MelderError) { Melder_clearError (); } } void FormantModeler_drawCumulativeChiScores (FormantModeler me, Graphics g, double xmin, double xmax, double ymin, double ymax, int useSigmaY, int garnish) { try { long ixmin, ixmax; if (FormantModeler_drawingSpecifiers_x (me, &xmin, &xmax, &ixmin, &ixmax) < 1) { Melder_throw (me, U" not enough data points in drawing range."); } long numberOfDataPoints = FormantModeler_getNumberOfDataPoints (me); autoNUMvector chisq (1, numberOfDataPoints); FormantModeler_getCumulativeChiScores (me, useSigmaY, chisq.peek()); if (ymax <= ymin) { NUMvector_extrema (chisq.peek(), ixmin, ixmax, &ymin, &ymax); } Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); DataModeler thee = (DataModeler) my trackmodelers -> item[1]; for (long i = ixmin + 1; i <= ixmax; i++) { Graphics_line (g, thy x[i-1], chisq[i-1], thy x[i], chisq[i]); } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); } } catch (MelderError) { // } } void FormantModeler_drawOutliersMarked (FormantModeler me, Graphics g, double tmin, double tmax, double fmax, long fromTrack, long toTrack, double numberOfSigmas, int useSigmaY, char32 *mark, int marksFontSize, double horizontalOffset_mm, int garnish) { if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } long maxTrack = my trackmodelers -> size; if (toTrack == 0 && fromTrack == 0) { fromTrack = 1; toTrack = maxTrack; } if (fromTrack > maxTrack) return; if (toTrack > maxTrack) { toTrack = maxTrack; } Graphics_setInner (g); int currectFontSize = Graphics_inqFontSize (g); for (long iformant = fromTrack; iformant <= toTrack; iformant++) { DataModeler ffi = (DataModeler) my trackmodelers -> item[iformant]; double xOffset_mm = (iformant % 2 == 1) ? horizontalOffset_mm : -horizontalOffset_mm; DataModeler_drawOutliersMarked_inside (ffi, g, tmin, tmax, 0, fmax, numberOfSigmas, useSigmaY, mark, marksFontSize, xOffset_mm); } Graphics_setFontSize (g, currectFontSize); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Time (s)"); Graphics_textLeft (g, true, U"Formant frequency (Hz)"); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeftEvery (g, 1.0, 1000.0, true, true, true); } } void FormantModeler_normalProbabilityPlot (FormantModeler me, Graphics g, long iformant, int useSigmaY, long numberOfQuantiles, double numberOfSigmas, int labelSize, const char32 *label, int garnish) { if (iformant > 0 || iformant <= my trackmodelers -> size) { DataModeler ff = (DataModeler) my trackmodelers ->item[iformant]; DataModeler_normalProbabilityPlot (ff, g, useSigmaY, numberOfQuantiles, numberOfSigmas, labelSize, label, garnish); } } static void FormantModeler_drawTracks_inside (FormantModeler me, Graphics g, double xmin, double xmax, double fmax, long fromTrack, long toTrack, int estimated, long numberOfParameters, double horizontalOffset_mm) { for (long iformant = fromTrack; iformant <= toTrack; iformant++) { DataModeler ffi = (DataModeler) my trackmodelers -> item[iformant]; double xOffset_mm = (iformant % 2 == 1) ? horizontalOffset_mm : -horizontalOffset_mm; DataModeler_drawTrack_inside (ffi, g, xmin, xmax, 0, fmax, estimated, numberOfParameters, xOffset_mm); } } void FormantModeler_drawTracks (FormantModeler me, Graphics g, double tmin, double tmax, double fmax, long fromTrack, long toTrack, int estimated, long numberOfParameters, double horizontalOffset_mm, int garnish) { if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } long maxTrack = my trackmodelers -> size; if (toTrack == 0 && fromTrack == 0) { fromTrack = 1; toTrack = maxTrack; } if (fromTrack > maxTrack) return; if (toTrack > maxTrack) { toTrack = maxTrack; } Graphics_setInner (g); FormantModeler_drawTracks_inside (me, g, tmin, tmax, fmax, fromTrack, toTrack, estimated, numberOfParameters, horizontalOffset_mm); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Time (s)"); Graphics_textLeft (g, true, U"Formant frequency (Hz)"); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeftEvery (g, 1.0, 1000.0, true, true, true); } } void FormantModeler_speckle_inside (FormantModeler me, Graphics g, double xmin, double xmax, double fmax, long fromTrack, long toTrack, int estimated, long numberOfParameters, int errorBars, double barWidth_mm, double horizontalOffset_mm) { for (long iformant = fromTrack; iformant <= toTrack; iformant++) { DataModeler ffi = (DataModeler) my trackmodelers -> item[iformant]; double xOffset_mm = (iformant % 2 == 1) ? horizontalOffset_mm : -horizontalOffset_mm; DataModeler_speckle_inside (ffi, g, xmin, xmax, 0, fmax, estimated, numberOfParameters, errorBars, barWidth_mm, xOffset_mm); } } void FormantModeler_speckle (FormantModeler me, Graphics g, double tmin, double tmax, double fmax, long fromTrack, long toTrack, int estimated, long numberOfParameters, int errorBars, double barWidth_mm, double horizontalOffset_mm, int garnish) { if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } long maxTrack = my trackmodelers -> size; if (toTrack == 0 && fromTrack == 0) { fromTrack = 1; toTrack = maxTrack; } if (fromTrack > maxTrack) return; if (toTrack > maxTrack) { toTrack = maxTrack; } Graphics_setInner (g); FormantModeler_speckle_inside (me, g, tmin, tmax, fmax, fromTrack, toTrack, estimated, numberOfParameters, errorBars, barWidth_mm, horizontalOffset_mm); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Time (s)"); Graphics_textLeft (g, true, U"Formant frequency (Hz)"); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeftEvery (g, 1.0, 1000.0, true, true, true); } } autoFormantModeler FormantModeler_create (double tmin, double tmax, long numberOfFormants, long numberOfDataPoints, long numberOfParameters) { try { autoFormantModeler me = Thing_new (FormantModeler); my xmin = tmin; my xmax = tmax; my trackmodelers = Ordered_create (); for (long itrack = 1; itrack <= numberOfFormants; itrack++) { autoDataModeler ff = DataModeler_create (tmin, tmax, numberOfDataPoints, numberOfParameters, DataModeler_TYPE_LEGENDRE); Collection_addItem (my trackmodelers, ff.transfer()); } return me; } catch (MelderError) { Melder_throw (U"FormantModeler not created."); } } double FormantModeler_getModelValueAtTime (FormantModeler me, long iformant, double time) { double f = NUMundefined; if (iformant >= 1 && iformant <= my trackmodelers -> size) { DataModeler thee = (DataModeler) my trackmodelers -> item[iformant]; f = DataModeler_getModelValueAtX (thee, time); } return f; } double FormantModeler_getModelValueAtIndex (FormantModeler me, long iformant, long index) { double f = NUMundefined; if (iformant >= 1 && iformant <= my trackmodelers -> size) { DataModeler thee = (DataModeler) my trackmodelers -> item[iformant]; f = DataModeler_getModelValueAtIndex (thee, index); } return f; } double FormantModeler_getWeightedMean (FormantModeler me, long iformant) { double f = NUMundefined; if (iformant >= 1 && iformant <= my trackmodelers -> size) { DataModeler thee = (DataModeler) my trackmodelers -> item[iformant]; f = DataModeler_getWeightedMean (thee); } return f; } long FormantModeler_getMaximumNumberOfParameters (FormantModeler me) { long maxnum = 1; for (long i = 1; i <= my trackmodelers -> size; i++) { DataModeler ffi = (DataModeler) my trackmodelers -> item[i]; if (ffi -> numberOfParameters > maxnum) { maxnum = ffi -> numberOfParameters; } } return maxnum; } long FormantModeler_getNumberOfTracks (FormantModeler me) { return my trackmodelers -> size; } long FormantModeler_getNumberOfParameters (FormantModeler me, long iformant) { long numberOfParameters = 0; if (iformant > 0 && iformant <= my trackmodelers -> size) { DataModeler ff = (DataModeler) my trackmodelers -> item[iformant]; numberOfParameters = ff -> numberOfParameters; } return numberOfParameters; } long FormantModeler_getNumberOfFixedParameters (FormantModeler me, long iformant) { long numberOfParameters = 0; if (iformant > 0 && iformant <= my trackmodelers -> size) { DataModeler ff = (DataModeler) my trackmodelers -> item[iformant]; numberOfParameters = ff -> numberOfParameters; numberOfParameters -= DataModeler_getNumberOfFreeParameters (ff); } return numberOfParameters; } long FormantModeler_getNumberOfInvalidDataPoints (FormantModeler me, long iformant) { long numberOfInvalidDataPoints = 0; if (iformant > 0 && iformant <= my trackmodelers -> size) { DataModeler ff = (DataModeler) my trackmodelers -> item[iformant]; numberOfInvalidDataPoints = DataModeler_getNumberOfInvalidDataPoints (ff); } return numberOfInvalidDataPoints; } double FormantModeler_getParameterValue (FormantModeler me, long iformant, long iparameter) { double value = NUMundefined; if (iformant > 0 && iformant <= my trackmodelers -> size) { DataModeler ff = (DataModeler) my trackmodelers -> item[iformant]; value = DataModeler_getParameterValue (ff, iparameter); } return value; } int FormantModeler_getParameterStatus (FormantModeler me, long iformant, long index) { int status = DataModeler_PARAMETER_UNDEFINED; if (iformant > 0 && iformant <= my trackmodelers -> size) { DataModeler ff = (DataModeler) my trackmodelers -> item[iformant]; status = DataModeler_getParameterStatus (ff, index); } return status; } double FormantModeler_getParameterStandardDeviation ( FormantModeler me, long iformant, long index) { double stdev = NUMundefined; if (iformant > 0 && iformant <= my trackmodelers -> size) { DataModeler ff = (DataModeler) my trackmodelers -> item[iformant]; stdev = DataModeler_getParameterStandardDeviation (ff, index); } return stdev; } double FormantModeler_getDegreesOfFreedom (FormantModeler me, long iformant) { double dof = 0.0; if (iformant > 0 && iformant <= my trackmodelers -> size) { DataModeler ff = (DataModeler) my trackmodelers -> item[iformant]; dof = DataModeler_getDegreesOfFreedom (ff); } return dof; } double FormantModeler_getVarianceOfParameters (FormantModeler me, long fromFormant, long toFormant, long fromIndex, long toIndex, long *numberOfFreeParameters) { double variance = NUMundefined; long numberOfFormants = my trackmodelers -> size, numberOfParameters = 0, nofp; if (toFormant < fromFormant || (toFormant == 0 && fromFormant == 0)) { fromFormant = 1; toFormant = numberOfFormants; } if (fromFormant <= toFormant && fromFormant > 0 && toFormant <= numberOfFormants) { variance = 0.0; for (long iformant = fromFormant; iformant <= toFormant; iformant++) { DataModeler ff = (DataModeler) my trackmodelers -> item[iformant]; variance += DataModeler_getVarianceOfParameters (ff, fromIndex, toIndex, &nofp); numberOfParameters += nofp; } } if (numberOfFreeParameters) { *numberOfFreeParameters = numberOfParameters; } return variance; } long FormantModeler_getNumberOfDataPoints (FormantModeler me) { DataModeler thee = (DataModeler) my trackmodelers -> item[1]; // all tracks have the same number of data points return thy numberOfDataPoints; } autoTable FormantModeler_to_Table_zscores (FormantModeler me, int useSigmaY) { try { long icolt = 1, numberOfFormants = my trackmodelers -> size; long numberOfDataPoints = FormantModeler_getNumberOfDataPoints (me); autoNUMvector zscores (1, numberOfDataPoints); autoTable ztable = Table_createWithoutColumnNames (numberOfDataPoints, numberOfFormants + 1); Table_setColumnLabel (ztable.peek(), icolt, U"time"); for (long iformant = 1; iformant <= numberOfFormants; iformant++) { long icolz = iformant + 1; Table_setColumnLabel (ztable.peek(), icolz, Melder_cat (U"z", iformant)); DataModeler ffi = (DataModeler) my trackmodelers -> item[iformant]; if (iformant == 1) { for (long i = 1; i <= numberOfDataPoints; i++) { // only once all tracks have same x-values Table_setNumericValue (ztable.peek(), i, icolt, ffi -> x[i]); } } DataModeler_getZScores (ffi, useSigmaY, zscores.peek()); for (long i = 1; i <= numberOfDataPoints; i++) { Table_setNumericValue (ztable.peek(), i, icolz, zscores[i]); } } return ztable; } catch (MelderError) { Melder_throw (U"Table not created."); } } autoDataModeler FormantModeler_extractDataModeler (FormantModeler me, long iformant) { try { if (! (iformant > 0 && iformant <= my trackmodelers -> size)) { Melder_throw (U""); } DataModeler ff = (DataModeler) my trackmodelers -> item[iformant]; autoDataModeler thee = (DataModeler) Data_copy (ff); return thee; } catch (MelderError) { Melder_throw (U"DataModeler not created."); } } autoCovariance FormantModeler_to_Covariance_parameters (FormantModeler me, long iformant) { try { if (iformant < 1 || iformant > my trackmodelers -> size) { Melder_throw (U"The formant should be greater than zero and smaller than or equal to ", my trackmodelers -> size); } DataModeler thee = (DataModeler) my trackmodelers -> item[iformant]; autoCovariance cov = (Covariance) Data_copy (thy parameterCovariances); return cov; } catch (MelderError) { Melder_throw (U"Covariance not created."); } } void FormantModeler_setTolerance (FormantModeler me, double tolerance) { for (long iformant = 1; iformant <= my trackmodelers -> size; iformant++) { DataModeler ffi = (DataModeler) my trackmodelers -> item[iformant]; DataModeler_setTolerance (ffi, tolerance); } } double FormantModeler_indexToTime (FormantModeler me, long index) { DataModeler thee = (DataModeler) my trackmodelers -> item[1]; return index > 0 && index <= thy numberOfDataPoints ? thy x[index] : NUMundefined; } autoFormantModeler Formant_to_FormantModeler (Formant me, double tmin, double tmax, long numberOfFormants, long numberOfParametersPerTrack, int bandwidthEstimatesSigma) { try { long ifmin, ifmax, posInCollection = 0; if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } long numberOfDataPoints = Sampled_getWindowSamples (me, tmin, tmax, &ifmin, &ifmax); if (numberOfDataPoints < numberOfParametersPerTrack) { Melder_throw (U"Not enought data points, extend the selection."); } autoFormantModeler thee = FormantModeler_create (tmin, tmax, numberOfFormants, numberOfDataPoints, numberOfParametersPerTrack); for (long iformant = 1; iformant <= numberOfFormants; iformant++) { posInCollection++; DataModeler ffi = (DataModeler) thy trackmodelers -> item[posInCollection]; long idata = 0, validData = 0; for (long iframe = ifmin; iframe <= ifmax; iframe++) { Formant_Frame curFrame = & my d_frames[iframe]; ffi -> x[++idata] = Sampled_indexToX (me, iframe); ffi -> dataPointStatus[idata] = DataModeler_DATA_INVALID; if (iformant <= curFrame -> nFormants) { double frequency = curFrame -> formant[iformant].frequency; if (NUMdefined (frequency)) { double bw = curFrame -> formant[iformant].bandwidth; ffi -> y[idata] = curFrame -> formant[iformant].frequency; ffi -> sigmaY[idata] = bw; ffi -> dataPointStatus[idata] = DataModeler_DATA_VALID; validData++; } } } ffi -> useSigmaY = bandwidthEstimatesSigma; ffi -> numberOfDataPoints = idata; ffi -> tolerance = 1e-5; if (validData < numberOfParametersPerTrack) { // remove don't throw exception Collection_removeItem (thy trackmodelers, posInCollection); posInCollection--; } } if (posInCollection == 0) { Melder_throw (U"Not enought data points in all the formants!"); } FormantModeler_fit (thee.peek()); return thee; } catch (MelderError) { Melder_throw (U"FormantModeler not created."); } } autoFormant FormantModeler_to_Formant (FormantModeler me, int useEstimates, int estimateUndefineds) { try { long numberOfFormants = my trackmodelers -> size; DataModeler ff = (DataModeler) my trackmodelers -> item[1]; long numberOfFrames = ff -> numberOfDataPoints; double t1 = ff -> x[1], dt = ff -> x[2] -ff -> x[1]; autoFormant thee = Formant_create (my xmin, my xmax, numberOfFrames, dt, t1, numberOfFormants); autoNUMvector sigma (1, numberOfFormants); if (useEstimates || estimateUndefineds) { for (long iformant = 1; iformant <= numberOfFormants; iformant++) { sigma[iformant] = FormantModeler_getStandardDeviation (me, iformant); } } for (long iframe = 1; iframe <= numberOfFrames; iframe++) { Formant_Frame thyFrame = & thy d_frames [iframe]; thyFrame -> intensity = 1.0; //??? thyFrame -> formant = NUMvector (1, numberOfFormants); for (long iformant = 1; iformant <= numberOfFormants; iformant++) { DataModeler ffi = (DataModeler) my trackmodelers -> item[iformant]; double f = NUMundefined, b = f; if (ffi -> dataPointStatus[iframe] != DataModeler_DATA_INVALID) { f = useEstimates ? DataModeler_getModelValueAtX (ffi, ffi -> x[iframe]) : ffi -> y[iframe]; b = ff -> sigmaY[iframe]; // copy original value } else { if (estimateUndefineds) { f = FormantModeler_getModelValueAtTime (me, iformant, ffi -> x[iframe]); b = sigma[iformant]; } } thyFrame -> formant[iformant].frequency = f; thyFrame -> formant[iformant].bandwidth = b; } } return thee; } catch (MelderError) { Melder_throw (U"Cannot create Formant from FormantModeler."); } } double FormantModeler_getChiSquaredQ (FormantModeler me, long fromFormant, long toFormant, int useSigmaY, double *probability, double *ndf) { double chisq = NUMundefined, ndfTotal = 0.0; if (toFormant < fromFormant || (fromFormant == 0 && toFormant == 0)) { fromFormant = 1; toFormant = my trackmodelers -> size; } if (fromFormant >= 1 && toFormant <= my trackmodelers -> size) { chisq = 0.0; long numberOfDefined = 0; for (long iformant= fromFormant; iformant <= toFormant; iformant++) { DataModeler ffi = (DataModeler) my trackmodelers -> item[iformant]; double p, df, chisqi = DataModeler_getChiSquaredQ (ffi, useSigmaY, &p, &df); if (NUMdefined (chisqi)) { chisq += df * chisqi; ndfTotal += df; numberOfDefined++; } } if (numberOfDefined == toFormant - fromFormant + 1) { // chisq of all tracks defined chisq /= ndfTotal; if (ndf) { *ndf = ndfTotal; } if (probability) { *probability = NUMchiSquareQ (chisq, ndfTotal); } } } return chisq; } double FormantModeler_getCoefficientOfDetermination (FormantModeler me, long fromFormant, long toFormant) { double rSquared = NUMundefined; if (fromFormant == 0 && toFormant == 0) { fromFormant = 1; toFormant = my trackmodelers -> size; } if (fromFormant >= 1 && toFormant <= my trackmodelers -> size) { double ssreg = 0.0, sstot = 0.0, ssregi, sstoti; for (long iformant= fromFormant; iformant <= toFormant; iformant++) { DataModeler ffi = (DataModeler) my trackmodelers -> item[iformant]; DataModeler_getCoefficientOfDetermination (ffi, &ssregi, &sstoti); sstot += sstoti; ssreg += ssregi; } rSquared = sstot > 0.0 ? ssreg / sstot : 1.0; } return rSquared; } double FormantModeler_getResidualSumOfSquares (FormantModeler me, long iformant, long *numberOfDataPoints) { double rss = NUMundefined; if (iformant > 0 && iformant <= my trackmodelers -> size) { DataModeler ff = (DataModeler) my trackmodelers -> item[iformant]; rss = DataModeler_getResidualSumOfSquares (ff, numberOfDataPoints); } return rss; } void FormantModeler_setParameterValuesToZero (FormantModeler me, long fromFormant, long toFormant, double numberOfSigmas) { if (fromFormant == 0 && toFormant == 0) { fromFormant = 1; toFormant = my trackmodelers -> size; } if (fromFormant >= 1 && toFormant <= my trackmodelers -> size) { for (long iformant= fromFormant; iformant <= toFormant; iformant++) { DataModeler ffi = (DataModeler) my trackmodelers -> item[iformant]; DataModeler_setParameterValuesToZero (ffi, numberOfSigmas); } } } void FormantModeler_getVariancesBetweenTrackAndEstimatedTrack (FormantModeler me, long iformant, long estimatedFormant, double var[]) { long numberOfDataPoints = FormantModeler_getNumberOfDataPoints (me); long numberOfFormants = my trackmodelers -> size; if (iformant < 1 || iformant > numberOfFormants || estimatedFormant < 1 || estimatedFormant > numberOfFormants) { return; } DataModeler fi = (DataModeler) my trackmodelers -> item[iformant]; DataModeler fe = (DataModeler) my trackmodelers -> item[estimatedFormant]; for (long i = 1; i <= numberOfDataPoints; i++) { var[i] = NUMundefined; if (fi -> dataPointStatus[i] != DataModeler_DATA_INVALID) { double ye = fe -> f_evaluate (fe, fe -> x[i], fe -> parameter); double diff = ye - fi -> y[i]; var[i] = diff * diff; } } } void FormantModeler_getSumOfVariancesBetweenShiftedAndEstimatedTracks (FormantModeler me, int shiftDirection, long *fromFormant, long *toFormant, double var[]) { try { long numberOfFormants = my trackmodelers -> size; if (*fromFormant < 1 || *fromFormant > numberOfFormants || *toFormant < 1 || *toFormant > numberOfFormants || *toFormant < *fromFormant) { *toFormant = 1; *fromFormant = numberOfFormants; } long formantTrack = *fromFormant, estimatedFormantTrack = *fromFormant; // FormantModeler_NOSHIFT_TRACKS if (shiftDirection == FormantModeler_DOWNSHIFT_TRACKS) { estimatedFormantTrack = *fromFormant; formantTrack = *fromFormant + 1; *fromFormant = *fromFormant == 1 ? 2 : *fromFormant; } else if (shiftDirection == FormantModeler_UPSHIFT_TRACKS) { formantTrack = *fromFormant; estimatedFormantTrack = *fromFormant + 1; *toFormant = *toFormant == numberOfFormants ? numberOfFormants - 1 : *toFormant; } long numberOfDataPoints = FormantModeler_getNumberOfDataPoints (me); autoNUMvector vari (1, numberOfDataPoints); for (long iformant = *fromFormant; iformant <= *toFormant; iformant++) { FormantModeler_getVariancesBetweenTrackAndEstimatedTrack (me, formantTrack, estimatedFormantTrack, vari.peek()); for (long i = 1; i <= numberOfDataPoints; i++) { if (NUMdefined (vari[i])) { var[i] += vari[i]; } } formantTrack++; estimatedFormantTrack++; } } catch (MelderError) { Melder_throw (me, U" cannot get variances."); } } autoFormantModeler FormantModeler_processOutliers (FormantModeler me, double numberOfSigmas, int useSigmaY) { try { long numberOfFormants = my trackmodelers -> size; if (numberOfFormants < 3) { Melder_throw (U"We need at least three formants to process outliers."); } long numberOfDataPoints = FormantModeler_getNumberOfDataPoints (me); autoNUMvector x (1, numberOfDataPoints); // also store x-values autoNUMmatrix z (1, numberOfFormants, 1, numberOfDataPoints); // maybe some of the formants had NUMundefind's. // 1. calculate z-scores for each formant and sort them in descending order DataModeler ff = (DataModeler) my trackmodelers -> item[1]; NUMvector_copyElements (ff -> x, x.peek(), 1, numberOfDataPoints); for (long iformant = 1; iformant <= numberOfFormants; iformant++) { DataModeler ffi = (DataModeler) my trackmodelers -> item[iformant]; DataModeler_getZScores (ffi, useSigmaY, z[iformant]); } // 2. Do the manipulation in a copy autoFormantModeler thee = (FormantModeler) Data_copy (me); for (long i = 1; i <= numberOfDataPoints; i++) { // First the easy one: first formant missing: F1' = F2; F2' = F3 if (NUMdefined (z[1][i]) && NUMdefined (z[1][i]) && NUMdefined (z[3][i])) { if (z[1][i] > numberOfSigmas && z[2][i] > numberOfSigmas && z[3][i] > numberOfSigmas) { // all deviations have the same sign: // probably F1 is missing // try if f2 <- F1 and f3 <- F2 reduces chisq double f2 = FormantModeler_getDataPointValue (me, 1, i); // F1 double f3 = FormantModeler_getDataPointValue (me, 2, i); // F2 FormantModeler_setDataPointStatus (thee.peek(), 1, i, DataModeler_DATA_INVALID); FormantModeler_setDataPointValueAndStatus (thee.peek(), 2, i, f2, FormantModeler_UPSHIFT_TRACKS); FormantModeler_setDataPointValueAndStatus (thee.peek(), 3, i, f3, FormantModeler_UPSHIFT_TRACKS); } } } FormantModeler_fit (thee.peek()); return thee; } catch (MelderError) { Melder_throw (U"Cannot calculate track discontinuities"); } } double FormantModeler_getSmoothnessValue (FormantModeler me, long fromFormant, long toFormant, long numberOfParametersPerTrack, double power) { double smoothness = NUMundefined; if (toFormant < fromFormant || (toFormant == 0 && fromFormant == 0)) { fromFormant = 1; toFormant = my trackmodelers -> size; } if (fromFormant > 0 && fromFormant <= toFormant && toFormant <= my trackmodelers -> size) { long nofp; double ndof, var = FormantModeler_getVarianceOfParameters (me, fromFormant, toFormant, 1, numberOfParametersPerTrack, &nofp); double chisq = FormantModeler_getChiSquaredQ (me, fromFormant, toFormant, true, nullptr, &ndof); if (NUMdefined (var) && NUMdefined (chisq) && nofp > 0) { smoothness = log10 (pow (var / nofp, power) * (chisq / ndof)); } } return smoothness; } double FormantModeler_getAverageDistanceBetweenTracks (FormantModeler me, long track1, long track2, int type) { double diff = NUMundefined; if (track1 == track2) { return 0; } if (track1 <= my trackmodelers -> size && track2 <= my trackmodelers -> size) { DataModeler fi = (DataModeler) my trackmodelers -> item[track1]; DataModeler fj = (DataModeler) my trackmodelers -> item[track2]; // fi and fj have equal number of data points long numberOfDataPoints = 0; diff = 0.0; for (long i = 1; i <= fi -> numberOfDataPoints; i++) { if (type != 0) { double fie = fi -> f_evaluate (fi, fi -> x[i], fi -> parameter); double fje = fj -> f_evaluate (fj, fj -> x[i], fj -> parameter); diff += fabs (fie - fje); numberOfDataPoints++; } else if (fi -> dataPointStatus[i] != DataModeler_DATA_INVALID && fj -> dataPointStatus[i] != DataModeler_DATA_INVALID) { diff += fabs (fi -> y[i] - fj -> y[i]); numberOfDataPoints++; } } diff /= numberOfDataPoints; } return diff; } double FormantModeler_getFormantsConstraintsFactor (FormantModeler me, double minF1, double maxF1, double minF2, double maxF2, double minF3) { double f1 = FormantModeler_getParameterValue (me, 1, 1); // trackmodelers -> item[1] -> parameter[1] double minF1Factor = f1 > minF1 ? 1 : sqrt (minF1 - f1 + 1.0); double maxF1Factor = f1 < maxF1 ? 1 : sqrt (f1 - maxF1 + 1.0); double f2 = FormantModeler_getParameterValue (me, 2, 1); // trackmodelers -> item[2] -> parameter[1] double minF2Factor = f2 > minF2 ? 1 : sqrt (minF2 - f2 + 1.0); double maxF2Factor = f2 < maxF2 ? 1 : sqrt (f2 - maxF2 + 1.0); double f3 = FormantModeler_getParameterValue (me, 3, 1); // trackmodelers -> item[3] -> parameter[1] double minF3Factor = f3 > minF3 ? 1 : sqrt (minF3 - f3 + 1.0); return minF1Factor * maxF1Factor * minF2Factor * maxF2Factor * minF3Factor; } long Formants_getSmoothestInInterval (Collection me, double tmin, double tmax, long numberOfFormantTracks, long numberOfParametersPerTrack, int useBandWidthsForTrackEstimation, int useConstraints, double numberOfSigmas, double power, double minF1, double maxF1, double minF2, double maxF2, double minF3) { try { long numberOfFormantObjects = my size, minNumberOfFormants = 1000000; if (numberOfFormantObjects == 1) { return 1; } autoNUMvector numberOfFormants (1, numberOfFormantObjects); autoNUMvector invalid (1, numberOfFormantObjects); double tminf = 0.0, tmaxf = 0.0; for (long iobject = 1; iobject <= numberOfFormantObjects; iobject++) { // Check that all Formants have the same domain Formant fi = (Formant) my item[iobject]; if (tminf == tmaxf) { tminf = fi -> xmin; tmaxf = fi -> xmax; } else if (fi -> xmin != tminf || fi -> xmax != tmaxf) { Melder_throw (U"All Formant objects must have the same starting and finishing times."); } // Find the one that has least formant tracks numberOfFormants[iobject] = Formant_getMaxNumFormants (fi); if (numberOfFormants[iobject] < minNumberOfFormants) { minNumberOfFormants = numberOfFormants[iobject]; } } if (numberOfFormantTracks == 0) { // default numberOfFormantTracks = minNumberOfFormants; } if (numberOfFormantTracks > minNumberOfFormants) { // make formants with not enough tracks invalid for the competition long numberOfInvalids = 0; for (long iobject = 1; iobject <= numberOfFormantObjects; iobject++) { if (numberOfFormants[iobject] < numberOfFormantTracks) { invalid[iobject] = 1; numberOfInvalids++; } } if (numberOfInvalids == numberOfFormantObjects) { Melder_throw (U"None of the Formants has enough formant tracks. Lower your upper formant number."); } } if (tmax <= tmin) { // default tmin = tminf; tmax = tmaxf; } if (! (tmin >= tminf && tmax <= tmaxf)) { Melder_throw (U"The selected interval needs to be within the Formant object's domain."); } /* The chisq is not meaningfull as a the only test whether one model is better than the other because if we have two models * 1 & 2 with the same data points (x1[i]=x2[i] and y1[i]= y2[i] but if sigma1[i] < sigma2[i] than chisq1 > chisq2. * This is not what we want. * We test therefore the variances of the parameters because if sigma1[i] < sigma2[i] than pvar1 < pvar2. */ double minChiVar = 1e308; long index = 0; for (long iobject = 1; iobject <= numberOfFormantObjects; iobject++) { if (invalid[iobject] != 1) { Formant fi = (Formant) my item[iobject]; autoFormantModeler fs = Formant_to_FormantModeler (fi, tmin, tmax, numberOfFormantTracks, numberOfParametersPerTrack, useBandWidthsForTrackEstimation); FormantModeler_setParameterValuesToZero (fs.peek(), 1, numberOfFormantTracks, numberOfSigmas); double cf = useConstraints ? FormantModeler_getFormantsConstraintsFactor (fs.peek(), minF1, maxF1, minF2, maxF2, minF3) : 1; double chiVar = FormantModeler_getSmoothnessValue (fs.peek(), 1, numberOfFormantTracks, numberOfParametersPerTrack, power); if (NUMdefined (chiVar) && cf * chiVar < minChiVar) { minChiVar = cf * chiVar; index = iobject; } } } return index; } catch (MelderError) { Melder_throw (U"No Formant object could be selected."); } } autoFormant Formant_extractPart (Formant me, double tmin, double tmax) { try { if (tmin >= tmax) { tmin = my xmin; tmax = my xmax; } if (tmin >= my xmax || tmax <= my xmin) { Melder_throw (U"Your start and end time should be between ", my xmin, U" and ", my xmax, U"."); } long thyindex = 1, ifmin, ifmax; long numberOfFrames = Sampled_getWindowSamples (me, tmin, tmax, &ifmin, &ifmax); double t1 = Sampled_indexToX (me, ifmin); autoFormant thee = Formant_create (tmin, tmax, numberOfFrames, my dx, t1, my maxnFormants); for (long iframe = ifmin; iframe <= ifmax; iframe++, thyindex++) { Formant_Frame myFrame = & my d_frames [iframe]; Formant_Frame thyFrame = & thy d_frames [thyindex]; myFrame -> copy (thyFrame); } return thee; } catch (MelderError) { Melder_throw (U"Formant part could not be extracted."); } } autoFormant Formants_extractSmoothestPart (Collection me, double tmin, double tmax, long numberOfFormantTracks, long numberOfParametersPerTrack, int useBandWidthsForTrackEstimation, double numberOfSigmas, double power) { try { long index = Formants_getSmoothestInInterval (me, tmin, tmax, numberOfFormantTracks, numberOfParametersPerTrack, useBandWidthsForTrackEstimation, 0, numberOfSigmas, power, 1.0, 1.0, 1.0, 1.0, 1.0); // last five are just fillers Formant bestfit = (Formant) my item[index]; autoFormant thee = Formant_extractPart (bestfit, tmin, tmax); return thee; } catch (MelderError) { Melder_throw (U"Smoothest Formant part could not be extracted."); } } autoFormant Formants_extractSmoothestPart_withFormantsConstraints (Collection me, double tmin, double tmax, long numberOfFormantTracks, long numberOfParametersPerTrack, int useBandWidthsForTrackEstimation, double numberOfSigmas, double power, double minF1, double maxF1, double minF2, double maxF2, double minF3) { try { long index = Formants_getSmoothestInInterval (me, tmin, tmax, numberOfFormantTracks, numberOfParametersPerTrack, useBandWidthsForTrackEstimation, 1, numberOfSigmas, power, minF1, maxF1, minF2, maxF2, minF3); Formant bestfit = (Formant) my item[index]; autoFormant thee = Formant_extractPart (bestfit, tmin, tmax); return thee; } catch (MelderError) { Melder_throw (U"Smoothest Formant part could not be extracted."); } } Thing_implement (PitchModeler, DataModeler, 0); autoPitchModeler Pitch_to_PitchModeler (Pitch me, double tmin, double tmax, long numberOfParameters) { try { long ifmin, ifmax; if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } long numberOfDataPoints = Sampled_getWindowSamples (me, tmin, tmax, &ifmin, &ifmax); if (numberOfDataPoints < numberOfParameters) { Melder_throw (U"Not enough data points, extend the selection."); } autoPitchModeler thee = Thing_new (PitchModeler); DataModeler_init (thee.peek(), tmin, tmax, numberOfDataPoints, numberOfParameters, DataModeler_TYPE_LEGENDRE); long idata = 0, validData = 0; for (long iframe = ifmin; iframe <= ifmax; iframe++) { thy x[++idata] = Sampled_indexToX (me, iframe); thy dataPointStatus[idata] = DataModeler_DATA_INVALID; if (Pitch_isVoiced_i (me, iframe)) { thy y[idata] = my frame [iframe]. candidate [1]. frequency; thy dataPointStatus[idata] = DataModeler_DATA_VALID; validData++; } } thy numberOfDataPoints = idata; if (validData < numberOfParameters) { // remove don't throw exception Melder_throw (U"Not enough valid data in interval."); } DataModeler_fit (thee.peek()); return thee; } catch (MelderError) { Melder_throw (U"No PitchModeler could be created."); } } void PitchModeler_draw (PitchModeler me, Graphics g, double tmin, double tmax, double fmin, double fmax, long numberOfParameters, int garnish) { Graphics_setInner (g); DataModeler_drawTrack_inside (me, g, tmin, tmax, fmin, fmax, 1, numberOfParameters, 0); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Time (s)"); Graphics_textLeft (g, true, U"Frequency (Hz)"); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeftEvery (g, 1.0, 100.0, true, true, true); } } double Sound_getOptimalFormantCeiling (Sound me, double startTime, double endTime, double windowLength, double timeStep, double minFreq, double maxFreq, long numberOfFrequencySteps, double preemphasisFrequency, long numberOfFormantTracks, long numberOfParametersPerTrack, int weighData, double numberOfSigmas, double power) { double optimalCeiling; autoFormant thee = Sound_to_Formant_interval (me, startTime, endTime, windowLength, timeStep, minFreq, maxFreq, numberOfFrequencySteps, preemphasisFrequency, numberOfFormantTracks, numberOfParametersPerTrack, weighData, numberOfSigmas, power, false, 0.0, 5000.0, 0.0, 5000.0, 0.0, &optimalCeiling); return optimalCeiling; } autoFormant Sound_to_Formant_interval (Sound me, double startTime, double endTime, double windowLength, double timeStep, double minFreq, double maxFreq, long numberOfFrequencySteps, double preemphasisFrequency, long numberOfFormantTracks, long numberOfParametersPerTrack, int weighData, double numberOfSigmas, double power, bool useConstraints, double minF1, double maxF1, double minF2, double maxF2, double minF3, double *optimalCeiling) { try { // parameter check if (endTime <= startTime) { startTime = my xmin; endTime = my xmax; } double nyquistFrequency = 0.5 / my dx; if (maxFreq > nyquistFrequency) { Melder_throw (U"The upper value of the maximum frequency range is higher than the Nyquist frequency of the sound."); } double df = 0, mincriterium = 1e28; if (minFreq >= maxFreq) { numberOfFrequencySteps = 1; } else { df = (maxFreq - minFreq) / (numberOfFrequencySteps - 1); } double ceiling_best = minFreq; long i_best = 0; // extract part +- windowLength because of Gaussian windowing in the formant analysis // +timeStep/2 to have the analysis points maximally spread in the new domain. autoSound part = Sound_extractPart (me, startTime - windowLength + timeStep / 2.0, endTime + windowLength + timeStep / 2.0, kSound_windowShape_RECTANGULAR, 1, 1); // Resample to 2*maxFreq to reduce resampling load in Sound_to_Formant autoSound resampled = Sound_resample (part.peek(), 2.0 * maxFreq, 50); autoOrdered formants = Ordered_create (); Melder_progressOff (); for (long i = 1; i <= numberOfFrequencySteps; i++) { double currentCeiling = minFreq + (i - 1) * df; autoFormant formant = Sound_to_Formant_burg (resampled.peek(), timeStep, 5.0, currentCeiling, windowLength, preemphasisFrequency); autoFormantModeler fm = Formant_to_FormantModeler (formant.peek(), startTime, endTime, numberOfFormantTracks, numberOfParametersPerTrack, weighData); FormantModeler_setParameterValuesToZero (fm.peek(), 1, numberOfFormantTracks, numberOfSigmas); Collection_addItem (formants.peek(), formant.transfer()); double cf = useConstraints ? FormantModeler_getFormantsConstraintsFactor (fm.peek(), minF1, maxF1, minF2, maxF2, minF3) : 1; double chiVar = FormantModeler_getSmoothnessValue (fm.peek(), 1, numberOfFormantTracks, numberOfParametersPerTrack, power); double criterium = chiVar * cf; if (NUMdefined (chiVar) && criterium < mincriterium) { mincriterium = criterium; ceiling_best= currentCeiling; i_best = i; } } autoFormant thee = Formant_extractPart ((Formant) formants -> item[i_best], startTime, endTime); Melder_progressOn (); if (optimalCeiling) { *optimalCeiling = ceiling_best; } return thee; } catch (MelderError) { Melder_throw (U"No Formant object created."); } } autoFormant Sound_to_Formant_interval_robust (Sound me, double startTime, double endTime, double windowLength, double timeStep, double minFreq, double maxFreq, long numberOfFrequencySteps, double preemphasisFrequency, long numberOfFormantTracks, long numberOfParametersPerTrack, int weighData, double numberOfSigmas, double power, bool useConstraints, double minF1, double maxF1, double minF2, double maxF2, double minF3, double *optimalCeiling) { try { // parameter check if (endTime <= startTime) { startTime = my xmin; endTime = my xmax; } double nyquistFrequency = 0.5 / my dx; if (maxFreq > nyquistFrequency) { Melder_throw (U"The upper value of the maximum frequency range is higher than the Nyquist frequency of the sound."); } double df = 0, mincriterium = 1e28; if (minFreq >= maxFreq) { numberOfFrequencySteps = 1; } else { df = (maxFreq - minFreq) / (numberOfFrequencySteps - 1); } long i_best = 0; double ceiling_best = minFreq; // extract part +- windowLength because of Gaussian windowing in the formant analysis // +timeStep/2 to have the analysis points maximally spread in the new domain. autoSound part = Sound_extractPart (me, startTime - windowLength + timeStep / 2, endTime + windowLength + timeStep / 2, kSound_windowShape_RECTANGULAR, 1, 1); // Resample to 2*maxFreq to reduce resampling load in Sound_to_Formant autoSound resampled = Sound_resample (part.peek(), 2.0 * maxFreq, 50); autoOrdered formants = Ordered_create (); Melder_progressOff (); for (long i = 1; i <= numberOfFrequencySteps; i++) { double currentCeiling = minFreq + (i - 1) * df; autoFormant formant = Sound_to_Formant_robust (resampled.peek(), timeStep, 5.0, currentCeiling, windowLength, preemphasisFrequency, 50.0, 1.5, 3, 0.0000001, 1); autoFormantModeler fm = Formant_to_FormantModeler (formant.peek(), startTime, endTime, numberOfFormantTracks, numberOfParametersPerTrack, weighData); FormantModeler_setParameterValuesToZero (fm.peek(), 1, numberOfFormantTracks, numberOfSigmas); Collection_addItem (formants.peek(), formant.transfer()); double cf = useConstraints ? FormantModeler_getFormantsConstraintsFactor (fm.peek(), minF1, maxF1, minF2, maxF2, minF3) : 1; double chiVar = FormantModeler_getSmoothnessValue (fm.peek(), 1, numberOfFormantTracks, numberOfParametersPerTrack, power); double criterium = chiVar * cf; if (NUMdefined (chiVar) && criterium < mincriterium) { mincriterium = criterium; ceiling_best= currentCeiling; i_best = i; } } autoFormant thee = Formant_extractPart ((Formant) formants -> item[i_best], startTime, endTime); Melder_progressOn (); if (optimalCeiling) { *optimalCeiling = ceiling_best; } return thee; } catch (MelderError) { Melder_throw (U"No Formant object created."); } } void FormantModeler_Formant_correctFormantsProbablyIndexedFalsely (FormantModeler me, Formant thee) { try { (void) thee; autoFormantModeler him = (FormantModeler) Data_copy (me); } catch (MelderError) { Melder_throw (U"Nothing corrected."); } } // If e.g. first formant is obviously "missing" then assign F1 as void FormantModeler_correctFormantsProbablyIndexedFalsely (FormantModeler me) { (void) me; /* if shift down F1 ("correct" F1 missed) * elsif shift down F2 ("correct" F2 missed) * else if spurious formant before F1 * else if spurious formant between F1 and F2 * endif * */ } autoOptimalCeilingTier Sound_to_OptimalCeilingTier (Sound me, double windowLength, double timeStep, double minCeiling, double maxCeiling, long numberOfFrequencySteps, double preemphasisFrequency, double smoothingWindow, long numberOfFormantTracks, long numberOfParametersPerTrack, int weighData, double numberOfSigmas, double power) { try { autoOrdered formants = Ordered_create (); double frequencyStep = numberOfFrequencySteps > 1 ? (maxCeiling - minCeiling) / (numberOfFrequencySteps - 1) : 0; for (long i = 1; i <= numberOfFrequencySteps; i++) { double ceiling = minCeiling + (i - 1) * frequencyStep; autoFormant formant = Sound_to_Formant_burg (me, timeStep, 5, ceiling, windowLength, preemphasisFrequency); Collection_addItem (formants.peek(), formant.transfer()); } long numberOfFrames; double firstTime, modelingTimeStep = timeStep; autoOptimalCeilingTier octier = OptimalCeilingTier_create (my xmin, my xmax); Sampled_shortTermAnalysis (me, smoothingWindow, modelingTimeStep, & numberOfFrames, & firstTime); for (long iframe = 1; iframe <= numberOfFrames; iframe++) { double time = firstTime + (iframe - 1) * modelingTimeStep; double tmin = time - smoothingWindow / 2.0; double tmax = tmin + smoothingWindow; long index = Formants_getSmoothestInInterval (formants.peek(), tmin, tmax, numberOfFormantTracks, numberOfParametersPerTrack, weighData, 0, numberOfSigmas, power, 200.0, 1500.0, 300.0, 3000.0, 1000.0); // min/max values are not used double ceiling = minCeiling + (index - 1) * frequencyStep; RealTier_addPoint (octier.peek(), time, ceiling); } return octier; } catch (MelderError) { Melder_throw (me, U" no OptimalCeilingTier calculated."); } } /* End of file DataModeler.cpp */ praat-6.0.04/dwtools/DataModeler.h000066400000000000000000000344641261542461700167600ustar00rootroot00000000000000#ifndef _DataModeler_h_ #define _DataModeler_h_ /* DataModeler.h * * Copyright (C) 2014-2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20140217 */ #define DataModeler_TYPE_POLYNOMIAL 0 #define DataModeler_TYPE_LEGENDRE 1 #define DataModeler_PARAMETER_FREE 0 #define DataModeler_PARAMETER_FIXED 1 #define DataModeler_PARAMETER_UNDEFINED -1 #define DataModeler_DATA_WEIGH_EQUAL 0 #define DataModeler_DATA_WEIGH_SIGMA 1 #define DataModeler_DATA_WEIGH_RELATIVE 2 #define DataModeler_DATA_WEIGH_SQRT 3 #define DataModeler_DATA_WEIGH_SQRT 3 #define DataModeler_DATA_VALID 0 #define DataModeler_DATA_INVALID -1 #define DataModeler_DATA_FROM_FIT 1 #define DataModeler_DATA_FROM_COPY1 2 #define DataModeler_DATA_FROM_COPY2 3 #define DataModeler_DATA_FROM_COPY3 4 #define DataModeler_DATA_FROM_COPY4 5 #define FormantModeler_NOSHIFT_TRACKS 0 #define FormantModeler_UPSHIFT_TRACKS 1 #define FormantModeler_DOWNSHIFT_TRACKS 2 #define FormantModeler_DATA_FROM_LOWER 12 #define FormantModeler_DATA_FROM_UPPER 13 #include "Collection.h" #include "Pitch.h" #include "OptimalCeilingTier.h" #include "Sound_to_Formant.h" #include "SSCP.h" #include "Table.h" #include "DataModeler_def.h" oo_CLASS_CREATE (DataModeler, Function); oo_CLASS_CREATE (FormantModeler, Function); Thing_define (PitchModeler, DataModeler) { // void v_info () // override; }; void DataModeler_init (DataModeler me, double xmin, double xmax, long numberOfDataPoints, long numberOfParameters, int type); autoDataModeler DataModeler_create (double xmin, double xmax, long numberOfDataPoints, long numberOfParameters, int type); autoDataModeler DataModeler_createSimple (double xmin, double xmax, long numberOfDataPoints, char32 *parameters, double gaussianNoiseStd, int type); void DataModeler_setBasisFunctions (DataModeler me, int type); void DataModeler_draw_inside (DataModeler me, Graphics g, double xmin, double xmax, double ymin, double ymax, int estimated, long numberOfParameters, int errorbars, int connectPoints, double barWidth_mm, double horizontalOffset_mm, int drawDots); void DataModeler_speckle_inside (DataModeler me, Graphics g, double xmin, double xmax, double ymin, double ymax, int estimated, long numberOfParameters, int errorbars, double barWidth_mm, double horizontalOffset_mm); void DataModeler_speckle (DataModeler me, Graphics g, double xmin, double xmax, double ymin, double ymax, int estimated, long numberOfParameters, int errorbars, double barWidth_mm, double horizontalOffset_mm, int garnish); void DataModeler_drawTrack (DataModeler me, Graphics g, double xmin, double xmax, double ymin, double ymax, int estimated, long numberOfParameters, double horizontalOffset_mm, int garnish); void DataModeler_drawTrack_inside (DataModeler me, Graphics g, double xmin, double xmax, double ymin, double ymax, int estimated, long numberOfParameters, double horizontalOffset_mm); void DataModeler_drawOutliersMarked_inside (DataModeler me, Graphics g, double xmin, double xmax, double ymin, double ymax, double numberOfSigmas, int useSigmaY, char32 *mark, int marksFontSize, double horizontalOffset_mm); /* Get the y-value of the fitted function at x */ void DataModeler_setTolerance (DataModeler me, double tolerance); void DataModeler_fit (DataModeler me); // sigmaY used in fit or not. void DataModeler_setDataWeighing (DataModeler me, int useSigmaY); long DataModeler_getNumberOfFixedParameters (DataModeler me); void DataModeler_setParameterValue (DataModeler me, long index, double value, int status); void DataModeler_setParameterValueFixed (DataModeler me, long index, double value); void DataModeler_setParametersFree (DataModeler me, long fromIndex, long toIndex); double DataModeler_getParameterValue (DataModeler me, long index); int DataModeler_getParameterStatus (DataModeler me, long index); double DataModeler_getParameterStandardDeviation (DataModeler me, long index); double DataModeler_getVarianceOfParameters (DataModeler me, long fromIndex, long toIndex, long *numberOfFreeParameters); void DataModeler_setParameterValuesToZero (DataModeler me, double numberOfSigmas); double DataModeler_estimateSigmaY (DataModeler me); void DataModeler_getExtremaY (DataModeler me, double *ymin, double *ymax); double DataModeler_getModelValueAtX (DataModeler me, double x); double DataModeler_getModelValueAtIndex (DataModeler me, long index); double DataModeler_getWeightedMean (DataModeler me); long DataModeler_getNumberOfInvalidDataPoints (DataModeler me); double DataModeler_getDataPointValue (DataModeler me, long index); void DataModeler_setDataPointValue (DataModeler me, long index, double value); int DataModeler_getDataPointStatus (DataModeler me, long index); void DataModeler_setDataPointStatus (DataModeler me, long index, int status); void DataModeler_setDataPointSigma (DataModeler me, long index, double sigma); double DataModeler_getDataPointSigma (DataModeler me, long index); double DataModeler_getResidualSumOfSquares (DataModeler me, long *numberOfDataPoints); void DataModeler_getZScores (DataModeler me, int useSigmaY, double zscores[]); double DataModeler_getDegreesOfFreedom (DataModeler me); double DataModeler_getChiSquaredQ (DataModeler me, int useSigmaY, double *probability, double *ndf); double DataModeler_getCoefficientOfDetermination (DataModeler me, double *ssreg, double *sstot); autoFormant Formant_extractPart (Formant me, double tmin, double tmax); autoCovariance DataModeler_to_Covariance_parameters (DataModeler me); autoTable DataModeler_to_Table_zscores (DataModeler me, int useSigmaY); autoFormantModeler FormantModeler_create (double tmin, double tmax, long numberOfFormants, long numberOfDataPoints, long numberOfParameters); double FormantModeler_indexToTime (FormantModeler me, long index); void FormantModeler_fit (FormantModeler me); void FormantModeler_drawBasisFunction (FormantModeler me, Graphics g, double tmin, double tmax, double fmin, double fmax, long iformant, long iterm, bool scaled, long numberOfPoints, int garnish); void FormantModeler_setDataWeighing (FormantModeler me, long fromFormant, long toFormant, int useSigmaY); void FormantModeler_setParameterValueFixed (FormantModeler me, long iformant, long index, double value); void FormantModeler_setParametersFree (FormantModeler me, long fromFormant, long toFormant, long fromIndex, long toIndex); void FormantModeler_setParameterValuesToZero (FormantModeler me, long fromFormant, long toFormant, double numberOfSigmas); void FormantModeler_setTolerance (FormantModeler me, double tolerance); void FormantModeler_speckle (FormantModeler me, Graphics g, double tmin, double tmax, double fmax, long fromTrack, long toTrack, int estimated, long numberOfParameters, int errorBars, double barWidth_mm, double horizontalOffset_mm, int garnish); void FormantModeler_drawTracks (FormantModeler me, Graphics g, double tmin, double tmax, double fmax, long fromTrack, long toTrack, int estimated, long numberOfParameters, double horizontalOffset_mm, int garnish); void FormantModeler_drawOutliersMarked (FormantModeler me, Graphics g, double tmin, double tmax, double fmax, long fromTrack, long toTrack, double numberOfSigmas, int useSigmaY, char32 *mark, int marksFontSize, double horizontalOffset_mm, int garnish); void FormantModeler_drawCumulativeChiScores (FormantModeler me, Graphics g, double xmin, double xmax, double ymin, double ymax, int useSigmaY, int garnish); void FormantModeler_drawVariancesOfShiftedTracks (FormantModeler me, Graphics g, double xmin, double xmax, double ymin, double ymax, int shiftDirection, long fromFormant, long toFormant, int garnish); void FormantModeler_normalProbabilityPlot (FormantModeler me, Graphics g, long iformant, int useSigmaY, long numberOfQuantiles, double numberOfSigmas, int labelSize, const char32 *label, int garnish); autoTable FormantModeler_to_Table_zscores (FormantModeler me, int useSigmaY); autoCovariance FormantModeler_to_Covariance_parameters (FormantModeler me, long iformant); double FormantModeler_getChiSquaredQ (FormantModeler me, long fromFormant, long toFormant, int useSigmaY, double *probability, double *ndf); double FormantModeler_getCoefficientOfDetermination (FormantModeler me, long fromFormant, long toFormant); double FormantModeler_getStandardDeviation (FormantModeler me, long iformant); double FormantModeler_getResidualSumOfSquares (FormantModeler me, long iformant, long *numberOfDataPoints); double FormantModeler_getEstimatedValueAtTime (FormantModeler me, long iformant, double time); long FormantModeler_getNumberOfParameters (FormantModeler me, long iformant); long FormantModeler_getNumberOfFixedParameters (FormantModeler me, long iformant); double FormantModeler_getParameterStandardDeviation ( FormantModeler me, long iformant, long index); double FormantModeler_getVarianceOfParameters (FormantModeler me, long fromFormant, long toFormant, long fromIndex, long toIndex, long *numberOfFreeParameters); int FormantModeler_getParameterStatus (FormantModeler me, long iformant, long index); long FormantModeler_getNumberOfDataPoints (FormantModeler me); long FormantModeler_getNumberOfInvalidDataPoints (FormantModeler me, long iformant); void FormantModeler_setDataPointStatus (FormantModeler me, long iformant, long index, int status); int FormantModeler_getDataPointStatus (FormantModeler me, long iformant, long index); double FormantModeler_getDataPointValue (FormantModeler me, long iformant, long index); void FormantModeler_setDataPointValue (FormantModeler me, long iformant, long index, double value); double FormantModeler_getDataPointSigma (FormantModeler me, long iformant, long index); void FormantModeler_setDataPointSigma (FormantModeler me, long iformant, long index, double sigma); double FormantModeler_getDegreesOfFreedom (FormantModeler me, long iformant); long FormantModeler_getNumberOfTracks (FormantModeler me); double FormantModeler_getModelValueAtTime (FormantModeler me, long iformant, double time); double FormantModeler_getModelValueAtIndex (FormantModeler me, long iformant, long index); double FormantModeler_getWeightedMean (FormantModeler me, long iformant); double FormantModeler_getParameterValue (FormantModeler me, long iformant, long iparameter); autoFormantModeler Formant_to_FormantModeler (Formant me, double tmin, double tmax, long numberOfFormants, long numberOfParametersPerTrack, int bandwidthEstimatesSigma); autoFormant FormantModeler_to_Formant (FormantModeler me, int estimate, int estimateUndefined); autoFormantModeler FormantModeler_processOutliers (FormantModeler me, double numberOfSigmas, int useSigmaY); double FormantModeler_getSmoothnessValue (FormantModeler me, long fromFormant, long toFormant, long numberOfParametersPerTrack, double power); double FormantModeler_getAverageDistanceBetweenTracks (FormantModeler me, long track1, long track2, int type); long Formants_getSmoothestInInterval (Collection me, double tmin, double tmax, long numberOfFormantTracks, long numberOfParametersPerTrack, int useBandWidthsForTrackEstimation, int useConstraints, double numberOfSigmas, double power, double minF1, double maxF1, double minF2, double maxF2, double minF3); double FormantModeler_getFormantsConstraintsFactor (FormantModeler me, double minF1, double maxF1, double minF2, double maxF2, double minF3); autoFormant Formants_extractSmoothestPart (Collection me, double tmin, double tmax, long numberOfFormantTracks, long numberOfParametersPerTrack, int useBandWidthsForTrackEstimation, double numberOfSigmas, double power); autoFormant Formants_extractSmoothestPart_withFormantsConstraints (Collection me, double tmin, double tmax, long numberOfFormantTracks, long numberOfParametersPerTrack, int useBandWidthsForTrackEstimation, double numberOfSigmas, double power, double minF1, double maxF1, double minF2, double maxF2, double minF3); autoDataModeler FormantModeler_extractDataModeler (FormantModeler me, long iformant); autoPitchModeler Pitch_to_PitchModeler (Pitch me, double tmin, double tmax, long numberOfParameters); void PitchModeler_draw (PitchModeler me, Graphics g, double tmin, double tmax, double fmin, double fmax, long numberOfParameters, int garnish); autoDataModeler Table_to_DataModeler (Table me, double xmin, double xmax, long xcolumn, long ycolumn, long scolumn, long numberOfParameters, int type); autoFormant Sound_to_Formant_interval (Sound me, double startTime, double endTime, double windowLength, double timeStep, double minFreq, double maxFreq, long numberOfFrequencySteps, double preemphasisFrequency, long numberOfFormantTracks, long numberOfParametersPerTrack, int weighData, double numberOfSigmas, double power, bool useConstraints, double minF1, double maxF1, double minF2, double maxF2, double minF3, double *optimalCeiling); autoFormant Sound_to_Formant_interval_robust (Sound me, double startTime, double endTime, double windowLength, double timeStep, double minFreq, double maxFreq, long numberOfFrequencySteps, double preemphasisFrequency, long numberOfFormantTracks, long numberOfParametersPerTrack, int weighData, double numberOfSigmas, double power, bool useConstraints, double minF1, double maxF1, double minF2, double maxF2, double minF3, double *optimalCeiling); double Sound_getOptimalFormantCeiling (Sound me, double startTime, double endTime, double windowLength, double timeStep, double minFreq, double maxFreq, long numberOfFrequencySteps, double preemphasisFrequency, long numberOfFormantTracks, long numberOfParametersPerTrack, int weighData, double numberOfSigmas, double power); autoOptimalCeilingTier Sound_to_OptimalCeilingTier (Sound me, double windowLength, double timeStep, double minCeiling, double maxCeiling, long numberOfFrequencySteps, double preemphasisFrequency, double smoothingWindow, long numberOfFormantTracks, long numberOfParametersPerTrack, int weighData, double numberOfSigmas, double power); #endif /* _DataModeler_h_ */ praat-6.0.04/dwtools/DataModeler_def.h000066400000000000000000000024361261542461700175700ustar00rootroot00000000000000/* DataModeler_def.h */ /* David Weenink, 20140216 */ #define ooSTRUCT DataModeler oo_DEFINE_CLASS (DataModeler, Function) oo_INT (type) // polynomial, legendre ... oo_LONG (numberOfDataPoints) oo_LONG (numberOfParameters) oo_DOUBLE_VECTOR (x, numberOfDataPoints) oo_DOUBLE_VECTOR (y, numberOfDataPoints) oo_DOUBLE_VECTOR (sigmaY, numberOfDataPoints) oo_INT_VECTOR (dataPointStatus, numberOfDataPoints) oo_DOUBLE_VECTOR (parameter, numberOfParameters) oo_INT_VECTOR (parameterStatus, numberOfParameters) oo_DOUBLE (tolerance) oo_INT (useSigmaY) oo_AUTO_OBJECT (Strings, 0, parameterNames) oo_OBJECT (Covariance, 0, parameterCovariances) #if oo_DECLARING double (*f_evaluate) (DataModeler me, double x, double p[]); void (*f_evaluateBasisFunctions) (DataModeler me, double x, double term[]); void v_info () override; #endif #if oo_COPYING DataModeler_setBasisFunctions (thee, thy type); #endif #if oo_READING DataModeler_setBasisFunctions (this, type); #endif oo_END_CLASS (DataModeler) #undef ooSTRUCT #define ooSTRUCT FormantModeler oo_DEFINE_CLASS (FormantModeler, Function) oo_COLLECTION (Ordered, trackmodelers, DataModeler, 0) #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (FormantModeler) #undef ooSTRUCT /* End of file DataModeler_def.h */ praat-6.0.04/dwtools/Discriminant.cpp000066400000000000000000000651551261542461700175570ustar00rootroot00000000000000/* Discriminant.c * * Copyright (C) 1993-2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20011016 removed some causes for compiler warnings djmw 20020313 removed obsolete TableOfReal_sortByLabels method djmw 20020314 +Discriminant_extractWithinGroupSSCP, +Discriminant_extractGroupLabels, +Discriminant_setGroupLabels. djmw 20020327 modified Discriminant_and_TableOfReal_to_Configuration djmw 20020418 Removed some causes for compiler warnings djmw 20020502 modified call Eigen_and_TableOfReal_project_into djmw 20030801 Discriminant_drawConcentrationEllipses extra argument djmw 20050405 Modified column label: eigenvector->Eigenvector djmw 20061021 printf expects %ld for 'long int' djmw 20061212 Changed info to Melder_writeLine format. djmw 20071009 wchar djmw 20071012 Added: o_CAN_WRITE_AS_ENCODING.h djmw 20071201 Melder_warning djmw 20081119 Check in TableOfReal_to_Discriminant if TableOfReal_areAllCellsDefined djmw 20100107 +Discriminant_and_TableOfReal_mahalanobis djmw 20110304 Thing_new */ #include "Discriminant.h" #include "SSCP.h" #include "Eigen_and_SSCP.h" #include "Eigen_and_TableOfReal.h" #include "NUMlapack.h" #include "SVD.h" #include "NUM2.h" #include "TableOfReal_extensions.h" #include "oo_DESTROY.h" #include "Discriminant_def.h" #include "oo_COPY.h" #include "Discriminant_def.h" #include "oo_EQUAL.h" #include "Discriminant_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Discriminant_def.h" #include "oo_WRITE_TEXT.h" #include "Discriminant_def.h" #include "oo_READ_TEXT.h" #include "Discriminant_def.h" #include "oo_WRITE_BINARY.h" #include "Discriminant_def.h" #include "oo_READ_BINARY.h" #include "Discriminant_def.h" #include "oo_DESCRIPTION.h" #include "Discriminant_def.h" #define MAX(m,n) ((m) > (n) ? (m) : (n)) #define MIN(m,n) ((m) < (n) ? (m) : (n)) Thing_implement (Discriminant, Eigen, 0); void structDiscriminant :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Number of groups: ", numberOfGroups); MelderInfo_writeLine (U"Number of variables: ", dimension); MelderInfo_writeLine (U"Number of discriminant functions: ", Discriminant_getNumberOfFunctions (this)); MelderInfo_writeLine (U"Number of observations (total): ", Discriminant_getNumberOfObservations (this, 0)); } autoDiscriminant Discriminant_create (long numberOfGroups, long numberOfEigenvalues, long dimension) { try { autoDiscriminant me = Thing_new (Discriminant); my numberOfGroups = numberOfGroups; Eigen_init (me.peek(), numberOfEigenvalues, dimension); my groups = SSCPs_create (); my total = SSCP_create (dimension); my aprioriProbabilities = NUMvector (1, numberOfGroups); my costs = NUMmatrix (1, numberOfGroups, 1, numberOfGroups); return me; } catch (MelderError) { Melder_throw (U"Discriminant not created."); } } long Discriminant_groupLabelToIndex (Discriminant me, const char32 *label) { char32 *name; for (long i = 1; i <= my numberOfGroups; i++) { if ( (name = Thing_getName ( (Thing) my groups -> item[i])) && str32equ (name, label)) { return i; } } return 0; } long Discriminant_getNumberOfGroups (Discriminant me) { return my numberOfGroups; } long Discriminant_getNumberOfObservations (Discriminant me, long group) { if (group == 0) { SSCP sscp = (SSCP) my total; return (long) floor (sscp -> numberOfObservations); } else if (group >= 1 && group <= my numberOfGroups) { SSCP sscp = (SSCP) my groups -> item[group]; return (long) floor (sscp -> numberOfObservations); } else { return -1; } } void Discriminant_setAprioriProbability (Discriminant me, long group, double p) { if (group < 1 || group > my numberOfGroups) { Melder_throw (U"The group number (", group, U") must be in the interval [1, ", my numberOfGroups, U"]; the supplied value (", group, U") falls outside it."); } if (p < 0 || p > 1) { Melder_throw (U"The probability must be in the interval [0, 1]; the supplied value (", p, U") falls outside it."); } my aprioriProbabilities[group] = p; } long Discriminant_getNumberOfFunctions (Discriminant me) { long nf = MIN (my numberOfGroups - 1, my dimension); nf = MIN (nf, my numberOfEigenvalues); return nf; } void Discriminant_setGroupLabels (Discriminant me, Strings thee) { if (my numberOfGroups != thy numberOfStrings) Melder_throw (U"The number of strings must equal the number of groups."); for (long i = 1; i <= my numberOfGroups; i++) { const char32 *noname = U"", *name; name = thy strings[i]; if (name == 0) { name = noname; } Thing_setName ( (Thing) my groups -> item[i], name); } } autoStrings Discriminant_extractGroupLabels (Discriminant me) { try { autoStrings thee = Thing_new (Strings); thy strings = NUMvector (1, my numberOfGroups); thy numberOfStrings = my numberOfGroups; for (long i = 1; i <= my numberOfGroups; i++) { char32 *name = Thing_getName ( (Thing) my groups -> item[i]); thy strings[i] = Melder_dup (name); } return thee; } catch (MelderError) { Melder_throw (me, U": group labels not extracted."); } } autoTableOfReal Discriminant_extractGroupCentroids (Discriminant me) { try { long m = my groups -> size, n = my dimension; autoTableOfReal thee = TableOfReal_create (m, n); for (long i = 1; i <= m; i++) { SSCP sscp = (SSCP) my groups -> item[i]; TableOfReal_setRowLabel (thee.peek(), i, Thing_getName (sscp)); NUMvector_copyElements (sscp -> centroid, thy data[i], 1, n); } NUMstrings_copyElements ( ( (SSCP) my groups -> item[m]) -> columnLabels, thy columnLabels, 1, n); return thee; } catch (MelderError) { Melder_throw (me, U": group centroids not extracted."); } } autoTableOfReal Discriminant_extractGroupStandardDeviations (Discriminant me) { try { long m = my groups -> size, n = my dimension; autoTableOfReal thee = TableOfReal_create (m, n); for (long i = 1; i <= m; i++) { SSCP sscp = (SSCP) my groups -> item[i]; TableOfReal_setRowLabel (thee.peek(), i, Thing_getName (sscp)); long numberOfObservationsm1 = (long) floor (sscp -> numberOfObservations) - 1; for (long j = 1; j <= n; j++) { thy data[i][j] = numberOfObservationsm1 > 0 ? sqrt (sscp -> data[j][j] / numberOfObservationsm1) : NUMundefined; } } NUMstrings_copyElements ( ( (SSCP) my groups -> item[m]) -> columnLabels, thy columnLabels, 1, n); return thee; } catch (MelderError) { Melder_throw (me, U": group standard deviations not extracted."); } } double Discriminant_getWilksLambda (Discriminant me, long from) { long numberOfFunctions = Discriminant_getNumberOfFunctions (me); if (from >= numberOfFunctions) { return 1; } if (from < 1) { from = 1; } return NUMwilksLambda (my eigenvalues, 1 + from, numberOfFunctions); } /* raw r[j]: eigenvec[i][j] unstandardized u[j]: sqrt(N-g) * r[j] standardized s[j]: u[j] sqrt (w[i][i] / (N-g)) */ autoTableOfReal Discriminant_extractCoefficients (Discriminant me, int choice) { try { int raw = choice == 0, standardized = choice == 2; long nx = my dimension, ny = my numberOfEigenvalues; SSCP total = my total; autoTableOfReal thee = TableOfReal_create (ny, nx + 1); NUMstrings_copyElements (my total -> columnLabels, thy columnLabels, 1, nx); autoSSCP within; if (standardized) { within = Discriminant_extractPooledWithinGroupsSSCP (me); } TableOfReal_setColumnLabel (thee.peek(), nx + 1, U"constant"); TableOfReal_setSequentialRowLabels (thee.peek(), 1, ny, U"function_", 1, 1); double scale = sqrt (total -> numberOfObservations - my numberOfGroups); double *centroid = my total -> centroid; for (long i = 1; i <= ny; i++) { double u0 = 0.0, ui; for (long j = 1; j <= nx; j++) { if (standardized) { scale = sqrt (within -> data[j][j]); } thy data[i][j] = ui = scale * my eigenvectors[i][j];; u0 += ui * centroid[j]; } thy data[i][nx + 1] = raw ? 0.0 : -u0; } return thee; } catch (MelderError) { Melder_throw (me, U": coefficients not extracted."); } } static long Discriminant_getDegreesOfFreedom (Discriminant me) { long ndf = 0; for (long i = 1; i <= my groups -> size; i++) { ndf += SSCP_getDegreesOfFreedom ((SSCP) my groups -> item[i]); } return ndf; } void Discriminant_getPartialDiscriminationProbability (Discriminant me, long numberOfDimensions, double *probability, double *chisq, long *ndf) { long g = my numberOfGroups; long p = my dimension, k = numberOfDimensions; long numberOfFunctions = Discriminant_getNumberOfFunctions (me); double degreesOfFreedom = Discriminant_getDegreesOfFreedom (me); double lambda; *probability = 1.0; *chisq = 0.0; *ndf = 0; if (k >= numberOfFunctions) { return; } lambda = NUMwilksLambda (my eigenvalues, k + 1, numberOfFunctions); if (lambda == 1.0) { return; } *chisq = - (degreesOfFreedom + (g - p) / 2.0 - 1.0) * log (lambda); *ndf = (p - k) * (g - k - 1); *probability = NUMchiSquareQ (*chisq, *ndf); } double Discriminant_getConcentrationEllipseArea (Discriminant me, long group, double scale, bool confidence, int discriminantDirections, long d1, long d2) { SSCPs groups = my groups; double area = NUMundefined; if (group < 1 || group > my numberOfGroups) { return area; } if (discriminantDirections) { autoSSCP thee = Eigen_and_SSCP_project (me, (SSCP) groups -> item[group]); area = SSCP_getConcentrationEllipseArea (thee.peek(), scale, confidence, d1, d2); } else { area = SSCP_getConcentrationEllipseArea ((SSCP) groups -> item[group], scale, confidence, d1, d2); } return area; } double Discriminant_getLnDeterminant_group (Discriminant me, long group) { if (group < 1 || group > my numberOfGroups) { return NUMundefined; } autoCovariance c = SSCP_to_Covariance ( (SSCP) my groups -> item[group], 1); double ln_d = SSCP_getLnDeterminant (c.peek()); return ln_d; } double Discriminant_getLnDeterminant_total (Discriminant me) { autoCovariance c = SSCP_to_Covariance (my total, 1); double ln_d = SSCP_getLnDeterminant (c.peek()); return ln_d; } autoSSCP Discriminant_extractPooledWithinGroupsSSCP (Discriminant me) { return SSCPs_to_SSCP_pool (my groups); } autoSSCP Discriminant_extractWithinGroupSSCP (Discriminant me, long index) { try { if (index < 1 || index > my numberOfGroups) Melder_throw (U"Index must be in interval [1,", my numberOfGroups, U"]."); autoSSCP thee = Data_copy ( (SSCP) my groups -> item[index]); return thee; } catch (MelderError) { Melder_throw (me, U": within group SSCP not created."); } } autoSSCP Discriminant_extractBetweenGroupsSSCP (Discriminant me) { try { long n = my total -> numberOfRows; autoSSCP b = Data_copy (my total); autoSSCP w = SSCPs_to_SSCP_pool (my groups); for (long i = 1; i <= n; i++) { for (long j = i; j <= n; j++) { b -> data[j][i] = (b -> data[i][j] -= w -> data[i][j]); } } return b; } catch (MelderError) { Melder_throw (me, U": between group SSCP not created."); } } void Discriminant_drawTerritorialMap (Discriminant me, Graphics g, int discriminantDirections, long d1, long d2, double xmin, double xmax, double ymin, double ymax, int fontSize, int poolCovarianceMatrices, int garnish) { (void) me; (void) g; (void) discriminantDirections; (void) d1; (void) d2; (void) xmin; (void) xmax; (void) ymin; (void) ymax; (void) fontSize; (void) poolCovarianceMatrices; (void) garnish; } void Discriminant_drawConcentrationEllipses (Discriminant me, Graphics g, double scale, int confidence, char32 *label, int discriminantDirections, long d1, long d2, double xmin, double xmax, double ymin, double ymax, int fontSize, int garnish) { long numberOfFunctions = Discriminant_getNumberOfFunctions (me); if (! discriminantDirections) { SSCPs_drawConcentrationEllipses (my groups, g, scale, confidence, label, d1, d2, xmin, xmax, ymin, ymax, fontSize, garnish); return; } if (numberOfFunctions <= 1) { Melder_warning (U"Discriminant_drawConcentrationEllipses: Nothing drawn " U"because there is only one dimension in the discriminant space."); return; } // Project SSCPs on eigenvectors. if (d1 == 0 && d2 == 0) { d1 = 1; d2 = MIN (numberOfFunctions, d1 + 1); } else if (d1 < 0 || d2 > numberOfFunctions) { return; } double *v1 = my eigenvectors[d1]; double *v2 = my eigenvectors[d2]; autoSSCPs thee = SSCPs_toTwoDimensions (my groups, v1, v2); SSCPs_drawConcentrationEllipses (thee.peek(), g, scale, confidence, label, 1, 2, xmin, xmax, ymin, ymax, fontSize, 0); if (garnish) { char32 llabel[40]; Graphics_drawInnerBox (g); Graphics_marksLeft (g, 2, true, true, false); Melder_sprint (llabel,40, U"function ", d2); Graphics_textLeft (g, true, llabel); Graphics_marksBottom (g, 2, true, true, false); Melder_sprint (llabel,40, U"function ", d1); Graphics_textBottom (g, true, llabel); } } autoDiscriminant TableOfReal_to_Discriminant (TableOfReal me) { try { autoDiscriminant thee = Thing_new (Discriminant); long dimension = my numberOfColumns; TableOfReal_areAllCellsDefined (me, 0, 0, 0, 0); if (NUMdmatrix_hasInfinities (my data, 1, my numberOfRows, 1, dimension)) { Melder_throw (U"Table contains infinities."); } if (! TableOfReal_hasRowLabels (me)) { Melder_throw (U"At least one of the rows has no label."); } autoTableOfReal mew = TableOfReal_sortOnlyByRowLabels (me); if (! TableOfReal_hasColumnLabels (mew.peek())) { TableOfReal_setSequentialColumnLabels (mew.peek(), 0, 0, U"c", 1, 1); } thy groups = TableOfReal_to_SSCPs_byLabel (mew.peek()); thy total = TableOfReal_to_SSCP (mew.peek(), 0, 0, 0, 0); if ( (thy numberOfGroups = thy groups -> size) < 2) { Melder_throw (U"Number of groups must be greater than one."); } TableOfReal_centreColumns_byRowLabel (mew.peek()); // Overall centroid and apriori probabilities and costs. autoNUMvector centroid (1, dimension); autoNUMmatrix between (1, thy numberOfGroups, 1, dimension); thy aprioriProbabilities = NUMvector (1, thy numberOfGroups); thy costs = NUMmatrix (1, thy numberOfGroups, 1, thy numberOfGroups); double sum = 0, scale; for (long k = 1; k <= thy numberOfGroups; k++) { SSCP m = (SSCP) thy groups -> item[k]; sum += scale = SSCP_getNumberOfObservations (m); for (long j = 1; j <= dimension; j++) { centroid[j] += scale * m -> centroid[j]; } } for (long j = 1; j <= dimension; j++) { centroid[j] /= sum; } for (long k = 1; k <= thy numberOfGroups; k++) { SSCP m = (SSCP) thy groups -> item[k]; scale = SSCP_getNumberOfObservations (m); thy aprioriProbabilities[k] = scale / my numberOfRows; for (long j = 1; j <= dimension; j++) { between[k][j] = sqrt (scale) * (m -> centroid[j] - centroid[j]); } } // We need to solve B'B.x = lambda W'W.x, where B'B and W'W are the between and within covariance matrices. // We do not calculate these covariance matrices directly from the data but instead use the GSVD to solve for // the eigenvalues and eigenvectors of the equation. Eigen_initFromSquareRootPair (thee.peek(), between.peek(), thy numberOfGroups, dimension, mew -> data, my numberOfRows); // Default priors and costs for (long k = 1; k <= thy numberOfGroups; k++) { for (long j = k + 1; j <= thy numberOfGroups; j++) { thy costs[k][j] = thy costs[j][k] = 1; } } return thee; } catch (MelderError) { Melder_throw (me, U": Discriminant not created."); } } autoConfiguration Discriminant_and_TableOfReal_to_Configuration (Discriminant me, TableOfReal thee, long numberOfDimensions) { try { if (numberOfDimensions == 0) { numberOfDimensions = Discriminant_getNumberOfFunctions (me); } autoConfiguration him = Configuration_create (thy numberOfRows, numberOfDimensions); Eigen_and_TableOfReal_project_into (me, thee, 1, thy numberOfColumns, him.peek(), 1, numberOfDimensions); TableOfReal_copyLabels (thee, him.peek(), 1, 0); TableOfReal_setSequentialColumnLabels (him.peek(), 0, 0, U"Eigenvector ", 1, 1); return him; } catch (MelderError) { Melder_throw (U"Configuration not created."); } } /* Calculate squared Mahalanobis distance: (v-m)'S^-1(v-m). Input matrix (li) is the inverse L^-1 of the Cholesky decomposition S = L.L'. */ static double mahalanobisDistanceSq (double **li, long n, double *v, double *m, double *buf) { for (long i = 1; i <= n; i++) { buf[i] = v[i] - m[i]; } double chisq = 0; for (long i = n; i > 0; i--) { double t = 0; for (long j = 1; j <= i; j++) { t += li[i][j] * buf[j]; } chisq += t * t; } return chisq; } autoTableOfReal Discriminant_and_TableOfReal_mahalanobis (Discriminant me, TableOfReal thee, long group, bool poolCovarianceMatrices) { try { if (group < 1 || group > my numberOfGroups) { Melder_throw (U"Group does not exist."); } autoSSCP pool = SSCPs_to_SSCP_pool (my groups); autoCovariance covg = SSCP_to_Covariance (pool.peek(), my numberOfGroups); autoCovariance cov = SSCP_to_Covariance ( (SSCP) my groups -> item[group], 1); autoTableOfReal him; if (poolCovarianceMatrices) { // use group mean instead of overall mean! NUMvector_copyElements (cov -> centroid, covg -> centroid, 1, cov -> numberOfColumns); him.reset (Covariance_and_TableOfReal_mahalanobis (covg.peek(), thee, false)); } else { him.reset (Covariance_and_TableOfReal_mahalanobis (cov.peek(), thee, false)); } return him; } catch (MelderError) { Melder_throw (U"TableOfReal not created."); } } autoClassificationTable Discriminant_and_TableOfReal_to_ClassificationTable (Discriminant me, TableOfReal thee, int poolCovarianceMatrices, int useAprioriProbabilities) { try { long g = Discriminant_getNumberOfGroups (me); long p = Eigen_getDimensionOfComponents (me); long m = thy numberOfRows; if (p != thy numberOfColumns) { Melder_throw (U"The number of columns does not agree with the dimension of the discriminant."); } autoNUMvector log_p (1, g); autoNUMvector log_apriori (1, g); autoNUMvector ln_determinant (1, g); autoNUMvector buf (1, p); autoNUMvector sscpvec (1, g); autoSSCP pool = SSCPs_to_SSCP_pool (my groups); autoClassificationTable him = ClassificationTable_create (m, g); NUMstrings_copyElements (thy rowLabels, his rowLabels, 1, m); // Scale the sscp to become a covariance matrix. for (long i = 1; i <= p; i++) { for (long k = i; k <= p; k++) { pool -> data[k][i] = (pool -> data[i][k] /= (pool -> numberOfObservations - g)); } } double lnd; autoSSCPs agroups; SSCPs groups; if (poolCovarianceMatrices) { /* Covariance matrix S can be decomposed as S = L.L'. Calculate L^-1. L^-1 will be used later in the Mahalanobis distance calculation: v'.S^-1.v == v'.L^-1'.L^-1.v == (L^-1.v)'.(L^-1.v). */ NUMlowerCholeskyInverse (pool -> data, p, &lnd); for (long j = 1; j <= g; j++) { ln_determinant[j] = lnd; sscpvec[j] = pool.peek(); } groups = (SSCPs) my groups; } else { // Calculate the inverses of all group covariance matrices. // In case of a singular matrix, substitute inverse of pooled. agroups = Data_copy ((SSCPs) my groups); groups = agroups.peek(); long npool = 0; for (long j = 1; j <= g; j++) { SSCP t = (SSCP) groups -> item[j]; long no = (long) floor (SSCP_getNumberOfObservations (t)); for (long i = 1; i <= p; i++) { for (long k = i; k <= p; k++) { t -> data[k][i] = (t -> data[i][k] /= (no - 1)); } } sscpvec[j] = (SSCP) groups -> item[j]; try { NUMlowerCholeskyInverse (t -> data, p, &ln_determinant[j]); } catch (MelderError) { // Try the alternative: the pooled covariance matrix. // Clear the error. Melder_clearError (); if (npool == 0) { NUMlowerCholeskyInverse (pool -> data, p, &lnd); } npool++; sscpvec[j] = pool.peek(); ln_determinant[j] = lnd; } } if (npool > 0) { Melder_warning (npool, U" groups use pooled covariance matrix."); } } // Labels for columns in ClassificationTable for (long j = 1; j <= g; j++) { const char32 *name = Thing_getName ( (Thing) my groups -> item[j]); if (! name) { name = U"?"; } TableOfReal_setColumnLabel (him.peek(), j, name); } // Normalize the sum of the apriori probabilities to 1. // Next take ln (p) because otherwise probabilities might be too small to represent. NUMvector_normalize1 (my aprioriProbabilities, g); double logg = log (g); for (long j = 1; j <= g; j++) { log_apriori[j] = useAprioriProbabilities ? log (my aprioriProbabilities[j]) : - logg; } // Generalized squared distance function: // D^2(x) = (x - mu)' S^-1 (x - mu) + ln (determinant(S)) - 2 ln (apriori) for (long i = 1; i <= m; i++) { double norm = 0, pt_max = -1e308; for (long j = 1; j <= g; j++) { SSCP t = (SSCP) groups -> item[j]; double md = mahalanobisDistanceSq (sscpvec[j] -> data, p, thy data[i], t -> centroid, buf.peek()); double pt = log_apriori[j] - 0.5 * (ln_determinant[j] + md); if (pt > pt_max) { pt_max = pt; } log_p[j] = pt; } for (long j = 1; j <= g; j++) { norm += (log_p[j] = exp (log_p[j] - pt_max)); } for (long j = 1; j <= g; j++) { his data[i][j] = log_p[j] / norm; } } return him; } catch (MelderError) { Melder_throw (U"ClassificationTable from Discriminant & TableOfReal not created."); } } autoClassificationTable Discriminant_and_TableOfReal_to_ClassificationTable_dw (Discriminant me, TableOfReal thee, int poolCovarianceMatrices, int useAprioriProbabilities, double alpha, double minProb, autoTableOfReal *displacements) { try { long g = Discriminant_getNumberOfGroups (me); long p = Eigen_getDimensionOfComponents (me); long m = thy numberOfRows; if (p != thy numberOfColumns) Melder_throw (U"The number of columns does not agree with the dimension of the discriminant."); autoNUMvector log_p (1, g); autoNUMvector log_apriori (1, g); autoNUMvector ln_determinant (1, g); autoNUMvector buf (1, p); autoNUMvector displacement (1, p); autoNUMvector x (1, p); autoNUMvector sscpvec (1, g); autoSSCP pool = SSCPs_to_SSCP_pool (my groups); autoClassificationTable him = ClassificationTable_create (m, g); NUMstrings_copyElements (thy rowLabels, his rowLabels, 1, m); autoTableOfReal adisplacements = Data_copy (thee); // Scale the sscp to become a covariance matrix. for (long i = 1; i <= p; i++) { for (long k = i; k <= p; k++) { pool -> data[k][i] = (pool -> data[i][k] /= (pool -> numberOfObservations - g)); } } double lnd; autoSSCPs agroups; SSCPs groups; if (poolCovarianceMatrices) { // Covariance matrix S can be decomposed as S = L.L'. Calculate L^-1. // L^-1 will be used later in the Mahalanobis distance calculation: // v'.S^-1.v == v'.L^-1'.L^-1.v == (L^-1.v)'.(L^-1.v). NUMlowerCholeskyInverse (pool -> data, p, &lnd); for (long j = 1; j <= g; j++) { ln_determinant[j] = lnd; sscpvec[j] = pool.peek(); } groups = my groups; } else { //Calculate the inverses of all group covariance matrices. // In case of a singular matrix, substitute inverse of pooled. agroups = Data_copy ((SSCPs) my groups); groups = agroups.peek(); long npool = 0; for (long j = 1; j <= g; j++) { SSCP t = (SSCP) groups -> item[j]; long no = (long) floor (SSCP_getNumberOfObservations (t)); for (long i = 1; i <= p; i++) { for (long k = i; k <= p; k++) { t -> data[k][i] = (t -> data[i][k] /= (no - 1)); } } sscpvec[j] = (SSCP) groups -> item[j]; try { NUMlowerCholeskyInverse (t -> data, p, &ln_determinant[j]); } catch (MelderError) { // Try the alternative: the pooled covariance matrix. // Clear the error. Melder_clearError (); if (npool == 0) { NUMlowerCholeskyInverse (pool -> data, p, &lnd); } npool++; sscpvec[j] = pool.peek(); ln_determinant[j] = lnd; } } if (npool > 0) { Melder_warning (npool, U" groups use pooled covariance matrix."); } } // Labels for columns in ClassificationTable for (long j = 1; j <= g; j++) { const char32 *name = Thing_getName ( (Thing) my groups -> item[j]); if (! name) { name = U"?"; } TableOfReal_setColumnLabel (him.peek(), j, name); } // Normalize the sum of the apriori probabilities to 1. // Next take ln (p) because otherwise probabilities might be too small to represent. double logg = log (g); NUMvector_normalize1 (my aprioriProbabilities, g); for (long j = 1; j <= g; j++) { log_apriori[j] = useAprioriProbabilities ? log (my aprioriProbabilities[j]) : - logg; } // Generalized squared distance function: // D^2(x) = (x - mu)' S^-1 (x - mu) + ln (determinant(S)) - 2 ln (apriori) for (long i = 1; i <= m; i++) { SSCP winner; double norm = 0, pt_max = -1e308; long iwinner = 1; for (long k = 1; k <= p; k++) { x[k] = thy data[i][k] + displacement[k]; } for (long j = 1; j <= g; j++) { SSCP t = (SSCP) groups -> item[j]; double md = mahalanobisDistanceSq (sscpvec[j] -> data, p, x.peek(), t -> centroid, buf.peek()); double pt = log_apriori[j] - 0.5 * (ln_determinant[j] + md); if (pt > pt_max) { pt_max = pt; iwinner = j; } log_p[j] = pt; } for (long j = 1; j <= g; j++) { norm += (log_p[j] = exp (log_p[j] - pt_max)); } for (long j = 1; j <= g; j++) { his data[i][j] = log_p[j] / norm; } // Save old displacement, calculate new displacement winner = (SSCP) groups -> item[iwinner]; for (long k = 1; k <= p; k++) { adisplacements -> data[i][k] = displacement[k]; if (his data[i][iwinner] > minProb) { double delta_k = winner -> centroid[k] - x[k]; displacement[k] += alpha * delta_k; } } } *displacements = adisplacements.move(); return him; } catch (MelderError) { Melder_throw (U"ClassificationTable for Weenink procedure not created."); } } autoConfiguration TableOfReal_to_Configuration_lda (TableOfReal me, long numberOfDimensions) { try { autoDiscriminant thee = TableOfReal_to_Discriminant (me); autoConfiguration him = Discriminant_and_TableOfReal_to_Configuration (thee.peek(), me, numberOfDimensions); return him; } catch (MelderError) { Melder_throw (me, U": Configuration with lda data not created."); } } #undef MAX #undef MIN /* End of file Discriminant.cpp */ praat-6.0.04/dwtools/Discriminant.h000066400000000000000000000075621261542461700172220ustar00rootroot00000000000000#ifndef _Discriminant_h_ #define _Discriminant_h_ /* Discriminant.h * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Graphics.h" #include "Configuration.h" #include "ClassificationTable.h" #include "Eigen.h" #include "SSCP.h" #include "Discriminant_def.h" oo_CLASS_CREATE (Discriminant, Eigen); autoDiscriminant Discriminant_create (long numberOfGroups, long numberOfEigenvalues, long dimension); long Discriminant_groupLabelToIndex (Discriminant me, const char32 *label); void Discriminant_setAprioriProbability (Discriminant me, long group, double p); long Discriminant_getNumberOfGroups (Discriminant me); long Discriminant_getNumberOfObservations (Discriminant me, long group); long Discriminant_getNumberOfFunctions (Discriminant me); double Discriminant_getWilksLambda (Discriminant me, long numberOfDimensions); void Discriminant_getPartialDiscriminationProbability (Discriminant me, long numberOfDimensions, double *probability, double *chisq, long *ndf); double Discriminant_getConcentrationEllipseArea (Discriminant me, long group, double scale, bool confidence, int discriminantDirections, long d1, long d2); double Discriminant_getLnDeterminant_group (Discriminant me, long group); double Discriminant_getLnDeterminant_total (Discriminant me); void Discriminant_drawTerritorialMap (Discriminant me, Graphics g, int discriminantDirections, long d1, long d2, double xmin, double xmax, double ymin, double ymax, int fontSize, int poolCovarianceMatrices, int garnish); void Discriminant_drawConcentrationEllipses (Discriminant me, Graphics g, double scale, int confidence, char32 *label, int discriminantDirections, long d1, long d2, double xmin, double xmax, double ymin, double ymax, int fontSize, int garnish); autoTableOfReal Discriminant_extractCoefficients (Discriminant me, int choice); autoTableOfReal Discriminant_extractGroupCentroids (Discriminant me); autoTableOfReal Discriminant_extractGroupStandardDeviations (Discriminant me); autoSSCP Discriminant_extractPooledWithinGroupsSSCP (Discriminant me); autoSSCP Discriminant_extractWithinGroupSSCP (Discriminant me, long index); autoSSCP Discriminant_extractBetweenGroupsSSCP (Discriminant me); autoStrings Discriminant_extractGroupLabels (Discriminant me); void Discriminant_setGroupLabels (Discriminant me, Strings thee); autoConfiguration Discriminant_and_TableOfReal_to_Configuration (Discriminant me, TableOfReal thee, long numberOfDimensions); autoClassificationTable Discriminant_and_TableOfReal_to_ClassificationTable (Discriminant me, TableOfReal thee, int poolCovarianceMatrices, int useAprioriProbabilities); autoClassificationTable Discriminant_and_TableOfReal_to_ClassificationTable_dw (Discriminant me, TableOfReal thee, int poolCovarianceMatrices, int useAprioriProbabilities, double alpha, double minProb, autoTableOfReal *displacements); autoTableOfReal Discriminant_and_TableOfReal_mahalanobis (Discriminant me, TableOfReal thee, long group, bool poolCovarianceMatrices); /* Mahalanobis distance with respect to group mean */ autoDiscriminant TableOfReal_to_Discriminant (TableOfReal me); autoConfiguration TableOfReal_to_Configuration_lda (TableOfReal me, long numberOfDimensions); #endif /* _Discriminant_h_ */ praat-6.0.04/dwtools/Discriminant_Pattern_Categories.cpp000066400000000000000000000035511261542461700234110ustar00rootroot00000000000000/* Discriminant_Pattern_Categories.cpp * * Copyright (C) 2004-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20040422 Initial version */ #include "Discriminant_Pattern_Categories.h" #include "TableOfReal.h" #include "Matrix_Categories.h" autoDiscriminant Pattern_and_Categories_to_Discriminant (Pattern me, Categories thee) { try { autoTableOfReal t = Matrix_and_Categories_to_TableOfReal (me, thee); autoDiscriminant him = TableOfReal_to_Discriminant (t.peek()); return him; } catch (MelderError) { Melder_throw (U"Discriminant not created from Pattern & Categories."); } } autoCategories Discriminant_and_Pattern_to_Categories (Discriminant me, Pattern thee, int poolCovarianceMatrices, int useAprioriProbabilities) { try { autoTableOfReal t = Matrix_to_TableOfReal (thee); autoClassificationTable ct = Discriminant_and_TableOfReal_to_ClassificationTable (me, t.peek(), poolCovarianceMatrices, useAprioriProbabilities); autoCategories him = ClassificationTable_to_Categories_maximumProbability (ct.peek()); return him; } catch (MelderError) { Melder_throw (U"Categories not created from Pattern & Discriminant."); } } /* End of file Discriminant_Pattern_Categories.cpp */ praat-6.0.04/dwtools/Discriminant_Pattern_Categories.h000066400000000000000000000025701261542461700230560ustar00rootroot00000000000000#ifndef _Discriminant_Pattern_Categories_h_ #define _Discriminant_Pattern_Categories_h_ /* Discriminant_Pattern_Categories.h * * Copyright (C) 2004-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20040422 Initial version djmw 20110307 Latest modification */ #ifndef _Discriminant_h_ #include "Discriminant.h" #endif #ifndef _Pattern_h_ #include "Pattern.h" #endif #ifndef _Categories_h_ #include "Categories.h" #endif autoDiscriminant Pattern_and_Categories_to_Discriminant (Pattern me, Categories thee); autoCategories Discriminant_and_Pattern_to_Categories (Discriminant me, Pattern thee, int poolCovarianceMatrices, int useAprioriProbabilities); #endif /* _Discriminant_Pattern_Categories_h_ */ praat-6.0.04/dwtools/Discriminant_def.h000066400000000000000000000022371261542461700200320ustar00rootroot00000000000000/* Discriminant_def.h * * Copyright (C) 1993-2008 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT Discriminant oo_DEFINE_CLASS (Discriminant, Eigen) oo_LONG (numberOfGroups) oo_OBJECT (SSCPs, 0, groups) oo_OBJECT (SSCP, 0, total) oo_DOUBLE_VECTOR (aprioriProbabilities, numberOfGroups) oo_DOUBLE_MATRIX (costs, numberOfGroups, numberOfGroups) #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (Discriminant) #undef ooSTRUCT /* End of file Discriminant_def.h */ praat-6.0.04/dwtools/Distance.cpp000066400000000000000000000023671261542461700166610ustar00rootroot00000000000000/* Distance.cpp * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header djmw 20110304 Thing_new */ #include "Distance.h" Thing_implement (Distance, Proximity, 0); autoDistance Distance_create (long numberOfPoints) { try { autoDistance me = Thing_new (Distance); Proximity_init (me.peek(), numberOfPoints); return me; } catch (MelderError) { Melder_throw (U"Distance not created."); } } void Distance_drawDendogram (Distance me, Graphics g, int method) { (void) me; (void) g; (void) method; } /* End of file Distance.cpp */ praat-6.0.04/dwtools/Distance.h000066400000000000000000000020251261542461700163150ustar00rootroot00000000000000#ifndef _Distance_h_ #define _Distance_h_ /* Distance.h * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Proximity.h" #include "Graphics.h" Thing_define (Distance, Proximity) { }; autoDistance Distance_create (long numberOfPoints); void Distance_drawDendogram (Distance me, Graphics g, int method); #endif /* _Distance_h_ */ praat-6.0.04/dwtools/EEG_extensions.cpp000066400000000000000000000266271261542461700200130ustar00rootroot00000000000000/* EEG_extensions.cpp * * Copyright (C) 2012-2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ICA.h" #include "EEG_extensions.h" #include "NUM2.h" #include "Sound_and_PCA.h" #include "Sound_extensions.h" #include "Spectrum_extensions.h" #include "Sound_and_Spectrum.h" static EEG EEG_copyWithoutSound (EEG me) { try { autoEEG thee = EEG_create (my xmin, my xmax); thy numberOfChannels = my numberOfChannels; thy textgrid = (TextGrid) Data_copy (my textgrid); autostring32vector channelNames (1, my numberOfChannels); for (long i = 1; i <= my numberOfChannels; i++) { channelNames[i] = Melder_dup (my channelNames[i]); } thy channelNames = channelNames.transfer(); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not copied."); } } static long *EEG_channelNames_to_channelNumbers (EEG me, char32 **channelNames, long numberOfChannelNames) { try { autoNUMvector channelNumbers (1, numberOfChannelNames); for (long i = 1; i <= numberOfChannelNames; i++) { for (long j = 1; j <= my numberOfChannels; j++) { if (Melder_equ (channelNames[i], my channelNames[j])) { channelNumbers[i] = j; } } if (channelNumbers[i] == 0) { Melder_throw (U"Channel name \"", channelNames[i], U"\" not found."); } } return channelNumbers.transfer(); } catch (MelderError) { Melder_throw (me, U": channelNames not found."); } } static void EEG_setChannelNames_selected (EEG me, const char32 *precursor, long *channelNumbers, long numberOfChannels) { autoMelderString name; const char32 *zero = U"0"; for (long i = 1; i <= numberOfChannels; i++) { MelderString_copy (&name, precursor); if (my numberOfChannels > 100) { if (i < 10) { MelderString_append (&name, zero); } if (i < 100) { MelderString_append (&name, zero); } } else if (i < 10) { MelderString_append (&name, zero); } MelderString_append (&name, i); EEG_setChannelName (me, channelNumbers[i], name.string); } } CrossCorrelationTable EEG_to_CrossCorrelationTable (EEG me, double startTime, double endTime, double lagStep, const char32 *channelRanges) { try { // autowindow if (startTime == endTime) { startTime = my xmin; endTime = my xmax; } // don't allow times outside domain if (startTime < my xmin) { startTime = my xmin; } if (endTime > my xmax) { endTime = my xmax; } autoEEG thee = EEG_extractPart (me, startTime, endTime, true); long numberOfChannels; autoNUMvector channels (NUMstring_getElementsOfRanges (channelRanges, thy numberOfChannels, & numberOfChannels, nullptr, U"channel", true), 1); autoSound soundPart = Sound_copyChannelRanges (thy sound, channelRanges); autoCrossCorrelationTable him = Sound_to_CrossCorrelationTable (soundPart.peek(), startTime, endTime, lagStep); // assign channel names for (long i = 1; i <= numberOfChannels; i++) { long ichannel = channels[i]; char32 *label = my channelNames[ichannel]; TableOfReal_setRowLabel (him.peek(), i, label); TableOfReal_setColumnLabel (him.peek(), i, label); } return him.transfer(); } catch (MelderError) { Melder_throw (me, U": no CrossCorrelationTable calculated."); } } Covariance EEG_to_Covariance (EEG me, double startTime, double endTime, const char32 *channelRanges) { try { double lagStep = 0.0; autoCrossCorrelationTable thee = EEG_to_CrossCorrelationTable (me, startTime, endTime, lagStep, channelRanges); autoCovariance him = Thing_new (Covariance); thy structCrossCorrelationTable :: v_copy (him.peek()); return him.transfer(); } catch (MelderError) { Melder_throw (me, U": no Covariance calculated."); } } CrossCorrelationTables EEG_to_CrossCorrelationTables (EEG me, double startTime, double endTime, double lagStep, long ncovars, const char32 *channelRanges) { try { // autowindow if (startTime == endTime) { startTime = my xmin; endTime = my xmax; } // don't allow times outside domain if (startTime < my xmin) { startTime = my xmin; } if (endTime > my xmax) { endTime = my xmax; } autoEEG thee = EEG_extractPart (me, startTime, endTime, true); long numberOfChannels; autoNUMvector channels (NUMstring_getElementsOfRanges (channelRanges, thy numberOfChannels, & numberOfChannels, nullptr, U"channel", true), 1); autoSound soundPart = Sound_copyChannelRanges (thy sound, channelRanges); autoCrossCorrelationTables him = Sound_to_CrossCorrelationTables (soundPart.peek(), startTime, endTime, lagStep, ncovars); return him.transfer(); } catch (MelderError) { Melder_throw (me, U": no CrossCorrelationTables calculated."); } } PCA EEG_to_PCA (EEG me, double startTime, double endTime, const char32 *channelRanges, int fromCorrelation) { try { autoCovariance cov = EEG_to_Covariance (me, startTime, endTime, channelRanges); if (fromCorrelation) { autoCorrelation cor = SSCP_to_Correlation (cov.peek()); autoPCA him = SSCP_to_PCA (cor.peek()); return him.transfer(); } else { autoPCA him = SSCP_to_PCA (cov.peek()); return him.transfer(); } } catch (MelderError) { Melder_throw (me, U": no PCA calculated."); } } EEG EEG_and_PCA_to_EEG_whiten (EEG me, PCA thee, long numberOfComponents) { try { if (numberOfComponents <= 0 || numberOfComponents > thy numberOfEigenvalues) { numberOfComponents = thy numberOfEigenvalues; } numberOfComponents = numberOfComponents > my numberOfChannels ? my numberOfChannels : numberOfComponents; autoNUMvector channelNumbers (EEG_channelNames_to_channelNumbers (me, thy labels, thy dimension), 1); autoEEG him = (EEG) Data_copy (me); autoSound white = Sound_and_PCA_whitenSelectedChannels (my sound, thee, numberOfComponents, channelNumbers.peek(), thy dimension); for (long i = 1; i <= thy dimension; i++) { long ichannel = channelNumbers[i]; NUMvector_copyElements (white -> z[i], his sound -> z[ichannel], 1, his sound -> nx); } EEG_setChannelNames_selected (him.peek(), U"wh", channelNumbers.peek(), thy dimension); return him.transfer(); } catch(MelderError) { Melder_throw (me, U": not whitened with ", thee); } } EEG EEG_and_PCA_to_EEG_principalComponents (EEG me, PCA thee, long numberOfComponents) { try { if (numberOfComponents <= 0 || numberOfComponents > thy numberOfEigenvalues) { numberOfComponents = thy numberOfEigenvalues; } numberOfComponents = numberOfComponents > my numberOfChannels ? my numberOfChannels : numberOfComponents; autoNUMvector channelNumbers (EEG_channelNames_to_channelNumbers (me, thy labels, thy dimension), 1); autoEEG him = (EEG) Data_copy (me); autoSound pc = Sound_and_PCA_to_Sound_pc_selectedChannels (my sound, thee, numberOfComponents, channelNumbers.peek(), thy dimension); for (long i = 1; i <= thy dimension; i++) { long ichannel = channelNumbers[i]; NUMvector_copyElements (pc -> z[i], his sound -> z[ichannel], 1, his sound -> nx); } EEG_setChannelNames_selected (him.peek(), U"pc", channelNumbers.peek(), thy dimension); return him.transfer(); } catch (MelderError) { Melder_throw (me, U": not projected."); } } EEG EEG_to_EEG_bss (EEG me, double startTime, double endTime, long ncovars, double lagStep, const char32 *channelRanges, int whiteningMethod, int diagonalizerMethod, long maxNumberOfIterations, double tol) { try { // autowindow if (startTime == endTime) { startTime = my xmin; endTime = my xmax; } // don't allow times outside domain if (startTime < my xmin) { startTime = my xmin; } if (endTime > my xmax) { endTime = my xmax; } long numberOfChannels; autoNUMvector channelNumbers (NUMstring_getElementsOfRanges (channelRanges, my numberOfChannels, & numberOfChannels, nullptr, U"channel", true), 1); autoEEG thee = EEG_extractPart (me, startTime, endTime, true); if (whiteningMethod != 0) { bool fromCorrelation = whiteningMethod == 2; autoPCA pca = EEG_to_PCA (thee.peek(), thy xmin, thy xmax, channelRanges, fromCorrelation); autoEEG white = EEG_and_PCA_to_EEG_whiten (thee.peek(), pca.peek(), 0); thee.reset (white.transfer()); } autoMixingMatrix mm = Sound_to_MixingMatrix (thy sound, startTime, endTime, ncovars, lagStep, maxNumberOfIterations, tol, diagonalizerMethod); autoEEG him = EEG_copyWithoutSound (me); his sound = Sound_and_MixingMatrix_unmix (my sound, mm.peek()); EEG_setChannelNames_selected (him.peek(), U"ic", channelNumbers.peek(), numberOfChannels); // Calculate the cross-correlations between eye-channels and the ic's return him.transfer(); } catch (MelderError) { Melder_throw (me, U": no independent components determined."); } } Sound EEG_to_Sound_modulated (EEG me, double baseFrequency, double channelBandwidth, const char32 *channelRanges) { try { long numberOfChannels; autoNUMvector channelNumbers (NUMstring_getElementsOfRanges (channelRanges, my numberOfChannels, & numberOfChannels, nullptr, U"channel", true), 1); double maxFreq = baseFrequency + my numberOfChannels * channelBandwidth; double samplingFrequency = 2 * maxFreq; samplingFrequency = samplingFrequency < 44100 ? 44100 : samplingFrequency; autoSound thee = Sound_createSimple (1, my xmax - my xmin, samplingFrequency); for (long i = 1; i <= numberOfChannels; i++) { long ichannel = channelNumbers[i]; double fbase = baseFrequency;// + (ichannel - 1) * channelBandwidth; autoSound si = Sound_extractChannel (my sound, ichannel); autoSpectrum spi = Sound_to_Spectrum (si.peek(), 1); Spectrum_passHannBand (spi.peek(), 0.5, channelBandwidth - 0.5, 0.5); autoSpectrum spi_shifted = Spectrum_shiftFrequencies (spi.peek(), fbase, samplingFrequency / 2, 30); autoSound resampled = Spectrum_to_Sound (spi_shifted.peek()); long nx = resampled -> nx < thy nx ? resampled -> nx : thy nx; for (long j = 1; j <= nx; j++) { thy z[1][j] += resampled -> z[1][j]; } } Vector_scale (thee.peek(), 0.99); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no playable sound created."); } } Sound EEG_to_Sound_frequencyShifted (EEG me, long channel, double frequencyShift, double samplingFrequency, double maxAmp) { try { autoSound si = Sound_extractChannel (my sound, channel); autoSpectrum spi = Sound_to_Spectrum (si.peek(), 1); autoSpectrum spi_shifted = Spectrum_shiftFrequencies (spi.peek(), frequencyShift, samplingFrequency / 2, 30); autoSound thee = Spectrum_to_Sound (spi_shifted.peek()); if (maxAmp > 0) { Vector_scale (thee.peek(), maxAmp); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": channel not converted to sound."); } } /* End of file EEG_extensions.cpp */ praat-6.0.04/dwtools/EEG_extensions.h000066400000000000000000000037701261542461700174520ustar00rootroot00000000000000#ifndef _EEG_extensions_h_ #define _EEG_extensions_h_ /* EEG_extensions.h * * Copyright (C) 2012 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20120926 Initial */ #include "ICA.h" #include "EEG.h" CrossCorrelationTable EEG_to_CrossCorrelationTable (EEG me, double startTime, double endTime, double lagTime, const char32 *channelRanges); Covariance EEG_to_Covariance (EEG me, double startTime, double endTime, const char32 *channelRanges); CrossCorrelationTables EEG_to_CrossCorrelationTables (EEG me, double startTime, double endTime, double lagTime, long ncovars, const char32 *channelRanges); PCA EEG_to_PCA (EEG me, double startTime, double endTime, const char32 *channelRanges, int fromCorrelation); EEG EEG_and_PCA_to_EEG_whiten (EEG me, PCA thee, long numberOfComponents); EEG EEG_and_PCA_to_EEG_principalComponents (EEG me, PCA thee, long numberOfComponents); EEG EEG_to_EEG_bss (EEG me, double startTime, double endTime, long ncovars, double lagTime, const char32 *channelRanges, int whiteningMethod, int diagonalizerMethod, long maxNumberOfIterations, double tol); Sound EEG_to_Sound_frequencyShifted (EEG me, long channel, double frequencyShift, double samplingFrequency, double maxAmp); Sound EEG_to_Sound_modulated (EEG me, double baseFrequency, double channelBandWidth, const char32 *channelRanges); #endif /* _EEG_extensions_h_ */ praat-6.0.04/dwtools/EditDistanceTable.cpp000066400000000000000000000530651261542461700204400ustar00rootroot00000000000000/* EditDistanceTable.c * * Copyright (C) 2012, 2014, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20120407 First implementation */ #include "EditDistanceTable.h" #include "oo_DESTROY.h" #include "EditDistanceTable_def.h" #include "oo_COPY.h" #include "EditDistanceTable_def.h" #include "oo_EQUAL.h" #include "EditDistanceTable_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "EditDistanceTable_def.h" #include "oo_WRITE_TEXT.h" #include "EditDistanceTable_def.h" #include "oo_WRITE_BINARY.h" #include "EditDistanceTable_def.h" #include "oo_READ_TEXT.h" #include "EditDistanceTable_def.h" #include "oo_READ_BINARY.h" #include "EditDistanceTable_def.h" #include "oo_DESCRIPTION.h" #include "EditDistanceTable_def.h" // prototypes autoEditCostsTable EditCostsTable_createDefault (); /* The insertion, deletion and substitution costs are specified in a TableOfReal * 1..n-2 target symbols/alphabet * 1..m-2 source symbols/alphabet * row n-1 and col m-1 specify nomatch symbols * cells [n][1..m-2] specify insertion costs * cells [1..n-1][m] specify deletion costs * cell [n-1][m-1] if nomatch target == nomatch source * cell [n][m] if nomatch target != nomatch source */ Thing_implement (WarpingPath, Daata, 0); autoWarpingPath WarpingPath_create (long length) { try { autoWarpingPath me = Thing_new (WarpingPath); my path = NUMvector (1, length); my _capacity = my pathLength = length; return me; } catch (MelderError) { Melder_throw (U"WarpPath not created."); } } static void WarpingPath_reset (WarpingPath me) { for (long i = 1; i <= my _capacity; i++) { my path[i].x = my path[i].y = 0; } my pathLength = my _capacity; } static void WarpingPath_getPath (WarpingPath me, short **psi, long iy, long ix) { // psi[0..nrows-1][0..ncols-1] long index = my pathLength; my path[index].x = ix; my path[index].y = iy; while (!(ix == 0 && iy == 0)) { if (psi[iy][ix] == WARPING_fromLeft) { ix--; } else if (psi[iy][ix] == WARPING_fromBelow) { iy--; } else { // WARPING_fromDiag ix--; iy--; } my path[--index].x = ix; my path[index].y = iy; } if (index > 1) { long k = 1; for (long i = index; i <= my pathLength; i++) { my path[k++] = my path[i]; my path[i].x = my path[i].y = 0; } my pathLength = k - 1; } } static void WarpingPath_shiftPathByOne (WarpingPath me) { for (long i = 1; i <= my pathLength; i++) { (my path[i].x)++; (my path[i].y)++; } } long WarpingPath_getColumnsFromRowIndex (WarpingPath me, long iy, long *ix1, long *ix2) { if (iy <= 0) { return 0; } *ix1 = 0; *ix2 = 0; for (long i = 1; i <= my pathLength; i++) { if (my path[i].y < iy) { continue; } else if (my path[i].y == iy) { if (*ix1 == 0) *ix1 = my path[i].x; *ix2 = my path[i].x; } else { break; } } return *ix2 - *ix1 + 1; } long WarpingPath_getRowsFromColumnIndex (WarpingPath me, long ix, long *iy1, long *iy2) { if (ix <= 0) { return 0; } *iy1 = 0; *iy2 = 0; for (long i = 1; i <= my pathLength; i++) { if (my path[i].x < ix) { continue; } else if (my path[i].x == ix) { if (*iy1 == 0) *iy1 = my path[i].y; *iy2 = my path[i].y; } else { break; } } return *iy2 - *iy1 + 1; } Thing_implement (EditCostsTable, TableOfReal, 0); void structEditCostsTable :: v_info () { EditDistanceTable_Parent :: v_info (); MelderInfo_writeLine (U"Target:", numberOfRows - 2, U" symbols."); MelderInfo_writeLine (U"Source:", numberOfColumns - 2, U" symbols."); } bool structEditCostsTable :: v_matchTargetSymbol (const char32 *targetSymbol, const char32 *symbol) { return Melder_equ (targetSymbol, symbol); } bool structEditCostsTable :: v_matchSourceSymbol (const char32 *sourceSymbol, const char32 *symbol) { return Melder_equ (sourceSymbol, symbol); } bool structEditCostsTable :: v_matchTargetWithSourceSymbol (const char32 *targetSymbol, const char32 *sourceSymbol) { return Melder_equ (targetSymbol, sourceSymbol); } autoEditCostsTable EditCostsTable_create (long targetAlphabetSize, long sourceAlphabetSize) { try{ autoEditCostsTable me = Thing_new (EditCostsTable); TableOfReal_init (me.peek(), targetAlphabetSize + 2, sourceAlphabetSize + 2); return me; } catch (MelderError) { Melder_throw (U"EditCostsTable not created."); } } autoEditCostsTable EditCostsTable_createDefault () { try { autoEditCostsTable me = EditCostsTable_create (0, 0); my data[1][1] = 0; // default substitution cost (nomatch == nomatch) my data[2][2] = 2; // default substitution cost (nomatch != nomatch) my data[2][1] = 1; // default insertion cost my data[1][2] = 1; // default deletion cost return me; } catch (MelderError) { Melder_throw (U"Default EditCostsTable not created."); } } void EditCostsTable_setDefaultCosts (EditCostsTable me, double insertionCosts, double deletionCosts, double substitutionCosts) { my data[my numberOfRows - 1][my numberOfColumns - 1] = 0; my data[my numberOfRows][my numberOfColumns] = substitutionCosts; my data[my numberOfRows][my numberOfColumns - 1] = deletionCosts; my data[my numberOfRows - 1][my numberOfColumns] = insertionCosts; } long EditCostsTable_getTargetIndex (EditCostsTable me, const char32 *symbol) { for (long i = 1; i <= my numberOfRows - 2; i++) { if (my v_matchTargetSymbol (my rowLabels[i], symbol)) { return i; } } return 0; } long EditCostsTable_getSourceIndex (EditCostsTable me, const char32 *symbol) { for (long j = 1; j <= my numberOfColumns - 2; j++) { if (my v_matchSourceSymbol (my columnLabels[j], symbol)) { return j; } } return 0; } void EditCostsTable_setInsertionCosts (EditCostsTable me, char32 *targets, double cost) { for (char32 *token = Melder_firstToken (targets); token != 0; token = Melder_nextToken ()) { long irow = EditCostsTable_getTargetIndex (me, token); irow = irow > 0 ? irow : my numberOfRows - 1; // nomatch condition to penultimate row my data[irow][my numberOfColumns] = cost; } } void EditCostsTable_setDeletionCosts (EditCostsTable me, char32 *sources, double cost) { for (char32 *token = Melder_firstToken (sources); token != 0; token = Melder_nextToken ()) { long icol = EditCostsTable_getSourceIndex (me, token); icol = icol > 0 ? icol : my numberOfColumns - 1; // nomatch condition to penultimate column my data[my numberOfRows][icol] = cost; } } void EditCostsTable_setOthersCosts (EditCostsTable me, double insertionCost, double deletionCost, double substitutionCost_equal, double substitutionCost_unequal) { my data[my numberOfRows - 1][my numberOfColumns] = insertionCost; my data[my numberOfRows][my numberOfColumns - 1] = deletionCost; my data[my numberOfRows - 1][my numberOfColumns - 1] = substitutionCost_unequal; my data[my numberOfRows][my numberOfColumns] = substitutionCost_equal; } double EditCostsTable_getOthersCost (EditCostsTable me, int costType) { return costType == 1 ? my data[my numberOfRows - 1][my numberOfColumns] : //insertion costType == 2 ? my data[my numberOfRows][my numberOfColumns - 1] : // deletion costType == 3 ? my data[my numberOfRows][my numberOfColumns] : // equality my data[my numberOfRows - 1][my numberOfColumns -1]; // inequality } void EditCostsTable_setSubstitutionCosts (EditCostsTable me, char32 *targets, char32 *sources, double cost) { try { autoNUMvector targetIndex (1, my numberOfRows); autoNUMvector sourceIndex (1, my numberOfRows); long numberOfTargetSymbols = 0; for (char32 *token = Melder_firstToken (targets); token != 0; token = Melder_nextToken ()) { long index = EditCostsTable_getTargetIndex (me, token); if (index > 0) { targetIndex[++numberOfTargetSymbols] = index; } } if (numberOfTargetSymbols == 0) { targetIndex[++numberOfTargetSymbols] = my numberOfRows - 1; } long numberOfSourceSymbols = 0; for (char32 *token = Melder_firstToken (sources); token != 0; token = Melder_nextToken ()) { long index = EditCostsTable_getSourceIndex (me, token); if (index > 0) { sourceIndex[++numberOfSourceSymbols] = index; } } if (numberOfSourceSymbols == 0) { sourceIndex[++numberOfSourceSymbols] = my numberOfColumns - 1; } for (long i = 1; i <= numberOfTargetSymbols; i++) { long irow = targetIndex[i]; for (long j = 1; j <= numberOfSourceSymbols; j++) { my data [irow][sourceIndex[j]] = cost; } } } catch (MelderError) { Melder_throw (me, U": substitution costs not set."); } } double EditCostsTable_getInsertionCost (EditCostsTable me, const char32 *symbol) { long irow = EditCostsTable_getTargetIndex (me, symbol); irow = irow == 0 ? my numberOfRows - 1 : irow; // others is penultimate row return my data[irow][my numberOfColumns]; } double EditCostsTable_getDeletionCost (EditCostsTable me, const char32 *sourceSymbol) { long icol = EditCostsTable_getSourceIndex (me, sourceSymbol); icol = icol == 0 ? my numberOfColumns - 1 : icol; // others is penultimate column return my data[my numberOfRows][icol]; } double EditCostsTable_getSubstitutionCost (EditCostsTable me, const char32 *symbol, const char32 *replacement) { long irow = EditCostsTable_getTargetIndex (me, symbol); long icol = EditCostsTable_getSourceIndex (me, replacement); if (irow == 0 && icol == 0) { // nomatch irow = my numberOfRows; icol = my numberOfColumns; if (my v_matchTargetWithSourceSymbol (symbol, replacement)) { --irow; --icol; } } else { irow = irow == 0 ? my numberOfRows - 1 : irow; icol = icol == 0 ? my numberOfColumns - 1 : icol; } return my data[irow][icol]; } autoTableOfReal EditCostsTable_to_TableOfReal (EditCostsTable me) { try { autoTableOfReal thee = TableOfReal_create (my numberOfRows, my numberOfColumns); for (long j = 1; j <= my numberOfColumns; j++) { thy columnLabels[j] = Melder_dup (my columnLabels[j]); } for (long i = 1; i <= my numberOfRows; i++) { thy rowLabels[i] = Melder_dup (my rowLabels[i]); } NUMmatrix_copyElements (my data, thy data, 1, my numberOfRows, 1, my numberOfColumns); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to TableOfReal."); } } Thing_implement (EditDistanceTable, TableOfReal, 0); void structEditDistanceTable :: v_info () { EditDistanceTable_Parent :: v_info (); MelderInfo_writeLine (U"Target:", numberOfRows, U" symbols."); MelderInfo_writeLine (U"Source:", numberOfColumns, U" symbols."); } autoEditDistanceTable EditDistanceTable_create (Strings target, Strings source) { try { autoEditDistanceTable me = Thing_new (EditDistanceTable); long numberOfSourceSymbols = source -> numberOfStrings, numberOfTargetSymbols = target -> numberOfStrings; TableOfReal_init (me.peek(), numberOfTargetSymbols + 1, numberOfSourceSymbols + 1); TableOfReal_setColumnLabel (me.peek(), 1, U""); for (long j = 1; j <= numberOfSourceSymbols; j++) { my columnLabels[j + 1] = Melder_dup (source -> strings[j]); } TableOfReal_setRowLabel (me.peek(), 1, U""); for (long i = 1; i <= numberOfTargetSymbols; i++) { my rowLabels[i + 1] = Melder_dup (target -> strings[i]); } my warpingPath = WarpingPath_create (numberOfTargetSymbols + numberOfSourceSymbols + 1); my editCostsTable = EditCostsTable_createDefault (); EditDistanceTable_findPath (me.peek(), 0); return me; } catch (MelderError) { Melder_throw (U"EditDistanceTable not created."); } } void EditDistanceTable_setEditCosts (EditDistanceTable me, EditCostsTable thee) { try { my editCostsTable = Data_copy (thee); } catch (MelderError) { Melder_throw (me, U": edit costs not set."); } } autoEditDistanceTable EditDistanceTable_createFromCharacterStrings (const char32 *chars1, const char32 *chars2) { try { autoStrings s1 = Strings_createAsCharacters (chars1); autoStrings s2 = Strings_createAsCharacters (chars2); autoEditDistanceTable me = EditDistanceTable_create (s1.peek(), s2.peek()); return me; } catch (MelderError) { Melder_throw (U"EditDistanceTable not created from character strings."); } } static void NUMrationalize (double x, long *numerator, long *denominator) { double epsilon = 1e-6; *numerator = 1; for (*denominator = 1; *denominator <= 100000; (*denominator) ++) { double numerator_d = x * *denominator, rounded = round (numerator_d); if (fabs (rounded - numerator_d) < epsilon) { *numerator = (long) rounded; return; } } *denominator = 0; /* Failure. */ } static void fixRows (TableOfReal me, long *rowmin, long *rowmax) { if (*rowmax < *rowmin) { *rowmin = 1; *rowmax = my numberOfRows; } else if (*rowmin < 1) *rowmin = 1; else if (*rowmax > my numberOfRows) *rowmax = my numberOfRows; } static void print4 (char *buffer, double value, int iformat, int width, int precision) { char formatString [40]; if (iformat == 4) { long numerator, denominator; NUMrationalize (value, & numerator, & denominator); if (numerator == 0) snprintf (buffer, 40, "0"); else if (denominator > 1) snprintf (buffer, 40, "%ld/%ld", numerator, denominator); else snprintf (buffer, 40, "%.7g", value); } else { snprintf (formatString, 40, "%%%d.%d%c", width, precision, iformat == 1 ? 'f' : iformat == 2 ? 'e' : 'g'); snprintf (buffer, 40, formatString, value); } } static double getMaxRowLabelWidth (TableOfReal me, Graphics graphics, long rowmin, long rowmax) { double maxWidth = 0.0; if (! my rowLabels) return 0.0; fixRows (me, & rowmin, & rowmax); for (long irow = rowmin; irow <= rowmax; irow ++) if (my rowLabels [irow] && my rowLabels [irow] [0]) { double textWidth = Graphics_textWidth_ps (graphics, my rowLabels [irow], true); /* SILIPA is bigger than XIPA */ if (textWidth > maxWidth) maxWidth = textWidth; } return maxWidth; } static double getLeftMargin (Graphics graphics) { return Graphics_dxMMtoWC (graphics, 1); } static double getLineSpacing (Graphics graphics) { return Graphics_dyMMtoWC (graphics, 1.5 * Graphics_inqFontSize (graphics) * 25.4 / 72); } void EditDistanceTable_draw (EditDistanceTable me, Graphics graphics, int iformat, int precision, double angle) { long rowmin = 1, rowmax = my numberOfRows; Graphics_setInner (graphics); Graphics_setWindow (graphics, 0.5, my numberOfColumns + 0.5, 0, 1); double leftMargin = getLeftMargin (graphics); // not earlier! double lineSpacing = getLineSpacing (graphics); // not earlier! double maxTextWidth = getMaxRowLabelWidth (me, graphics, rowmin, rowmax); double y = 1 + 0.1 * lineSpacing; autoNUMmatrix onPath (1, my numberOfRows, 1, my numberOfColumns); for (long i = 1; i <= my warpingPath -> pathLength; i++) { structPairOfInteger poi = my warpingPath -> path[i]; onPath[poi.y] [poi.x] = true; } for (long irow = my numberOfRows; irow > 0; irow --) { Graphics_setTextAlignment (graphics, Graphics_RIGHT, Graphics_HALF); if (my rowLabels && my rowLabels [irow] && my rowLabels [irow] [0]) Graphics_text (graphics, 0.5 - leftMargin, y, my rowLabels [irow]); Graphics_setTextAlignment (graphics, Graphics_CENTRE, Graphics_HALF); for (long icol = 1; icol <= my numberOfColumns; icol ++) { char text [40]; print4 (text, my data [irow] [icol], iformat, 0, precision); Graphics_setBold (graphics, onPath[irow][icol]); Graphics_text (graphics, icol, y, Melder_peek8to32 (text)); if (onPath[irow][icol]) { Graphics_rectangle (graphics, icol-0.5, icol+0.5, y - 0.5*lineSpacing, y + 0.5*lineSpacing); } } y -= lineSpacing; Graphics_setBold (graphics, false); } double left = 0.5; if (maxTextWidth > 0.0) left -= maxTextWidth + 2 * leftMargin; Graphics_line (graphics, left, y, my numberOfColumns + 0.5, y); Graphics_setTextRotation (graphics, angle); if (angle < 0) { y -= 0.3*lineSpacing; Graphics_setTextAlignment (graphics, Graphics_LEFT, Graphics_HALF); } else if (angle > 0) { Graphics_setTextAlignment (graphics, Graphics_RIGHT, Graphics_HALF); y -= 0.3*lineSpacing; } else { Graphics_setTextAlignment (graphics, Graphics_CENTRE, Graphics_TOP); } for (long icol = 1; icol <= my numberOfColumns; icol ++) { if (my columnLabels && my columnLabels [icol] && my columnLabels [icol] [0]) Graphics_text (graphics, icol, y, my columnLabels [icol]); } Graphics_setTextRotation (graphics, 0); y -= lineSpacing; Graphics_line (graphics, 0.5, y, 0.5, 1 + 0.5 * lineSpacing); Graphics_unsetInner (graphics); } void EditDistanceTable_drawEditOperations (EditDistanceTable me, Graphics graphics) { const char32 *oinsertion = U"i", *insertion = U"*", *odeletion = U"d", *deletion = U"*", *osubstitution = U"s", *oequal = U""; Graphics_setWindow (graphics, 0.5, my warpingPath -> pathLength - 0.5, 0, 1); // pathLength-1 symbols double lineSpacing = getLineSpacing (graphics); double ytarget = 1 - lineSpacing, ysource = ytarget - 2 * lineSpacing, yoper = ysource - lineSpacing; Graphics_setTextAlignment (graphics, Graphics_CENTRE, Graphics_BOTTOM); for (long i = 2; i <= my warpingPath -> pathLength; i++) { structPairOfInteger p = my warpingPath -> path[i], p1 = my warpingPath -> path[i - 1]; double x = i - 1; if (p.x == p1.x) { // insertion Graphics_text (graphics, x, ytarget, my rowLabels[p.y]); Graphics_text (graphics, x, ysource, deletion); Graphics_text (graphics, x, yoper, oinsertion); } else if (p.y == p1.y) { // deletion Graphics_text (graphics, x, ytarget, insertion); Graphics_text (graphics, x, ysource, my columnLabels[p.x]); Graphics_text (graphics, x, yoper, odeletion); } else { // substitution ? Graphics_text (graphics, x, ytarget, my rowLabels[p.y]); Graphics_text (graphics, x, ysource, my columnLabels[p.x]); Graphics_text (graphics, x, yoper, (Melder_equ (my rowLabels[p.y], my columnLabels[p.x]) ? oequal : osubstitution)); } Graphics_line (graphics, x, ysource + lineSpacing, x, ytarget - 0.1 * lineSpacing); } } void EditDistanceTable_setDefaultCosts (EditDistanceTable me, double insertionCosts, double deletionCosts, double substitutionCosts) { EditCostsTable_setDefaultCosts (my editCostsTable.peek(), insertionCosts, deletionCosts, substitutionCosts); EditDistanceTable_findPath (me, 0); } autoTableOfReal EditDistanceTable_to_TableOfReal_directions (EditDistanceTable me) { autoTableOfReal tor; EditDistanceTable_findPath (me, &tor); return tor; } void EditDistanceTable_findPath (EditDistanceTable me, autoTableOfReal *directions) { try { /* What do we have to do to source to get target? * Origin [0][0] is at bottom-left corner * Target vertical, source horizontal * Going in the vertical direction is a deletion, horizontal is insertion, diagonal is substitution */ long numberOfSources = my numberOfColumns - 1, numberOfTargets = my numberOfRows - 1; autoNUMmatrix psi (0, numberOfTargets, 0, numberOfSources); autoNUMmatrix delta (0, numberOfTargets, 0, numberOfSources); for (long j = 1; j <= numberOfSources; j++) { delta[0][j] = delta[0][j - 1] + EditCostsTable_getDeletionCost (my editCostsTable.peek(), my columnLabels[j+1]); psi[0][j] = WARPING_fromLeft; } for (long i = 1; i <= numberOfTargets; i++) { delta[i][0] = delta[i - 1][0] + EditCostsTable_getInsertionCost (my editCostsTable.peek(), my rowLabels[i+1]); psi[i][0] = WARPING_fromBelow; } for (long j = 1; j <= numberOfSources; j++) { for (long i = 1; i <= numberOfTargets; i++) { // the substitution, deletion and insertion costs. double left = delta[i][j - 1] + EditCostsTable_getInsertionCost (my editCostsTable.peek(), my rowLabels[i+1]); double bottom = delta[i - 1][j] + EditCostsTable_getDeletionCost (my editCostsTable.peek(), my columnLabels[j+1]); double mindist = delta[i - 1][j - 1] + EditCostsTable_getSubstitutionCost (my editCostsTable.peek(), my rowLabels[i+1], my columnLabels[j+1]); // diag psi[i][j] = WARPING_fromDiag; if (bottom < mindist) { mindist = bottom; psi[i][j] = WARPING_fromBelow; } if (left < mindist) { mindist = left; psi[i][j] = WARPING_fromLeft; } delta[i][j] = mindist; } } // find minimum distance in last column long iy = numberOfTargets, ix = numberOfSources; WarpingPath_reset (my warpingPath.peek()); WarpingPath_getPath (my warpingPath.peek(), psi.peek(), iy, ix); WarpingPath_shiftPathByOne (my warpingPath.peek()); for (long i = 0; i <= numberOfTargets; i++) { for (long j = 0; j <= numberOfSources; j++) { my data[i+1][j+1] = delta[i][j]; } } if (directions != 0) { autoTableOfReal him = EditDistanceTable_to_TableOfReal (me); for (long i = 0; i <= numberOfTargets; i++) { for (long j = 0; j <= numberOfSources; j++) { his data[i+1][j+1] = psi[i][j]; } } *directions = him.move(); } } catch (MelderError) { Melder_throw (me, U": minimum path not found."); } } autoTableOfReal EditDistanceTable_to_TableOfReal (EditDistanceTable me) { try { autoTableOfReal thee = TableOfReal_create (my numberOfRows, my numberOfColumns); for (long j = 1; j <= my numberOfColumns; j++) { thy columnLabels[j] = Melder_dup (my columnLabels[j]); } for (long i = 1; i <= my numberOfRows; i++) { thy rowLabels[i] = Melder_dup (my rowLabels[i]); } NUMmatrix_copyElements (my data, thy data, 1, my numberOfRows, 1, my numberOfColumns); return thee; } catch (MelderError) { Melder_throw (me, U": no TableOfReal created."); } } /* End of file EditDistanceTable.cpp */ praat-6.0.04/dwtools/EditDistanceTable.h000066400000000000000000000100231261542461700200700ustar00rootroot00000000000000#ifndef _EditDistanceTable_h_ #define _EditDistanceTable_h_ /* EditDistanceTable.h * * Copyright (C) 2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Strings_extensions.h" #include "TableOfReal.h" #define WARPING_fromLeft 1 #define WARPING_fromBelow 2 #define WARPING_fromDiag 4 #include "EditDistanceTable_def.h" oo_CLASS_CREATE (WarpingPath, Daata); oo_CLASS_CREATE (EditCostsTable, TableOfReal); oo_CLASS_CREATE (EditDistanceTable, TableOfReal); autoWarpingPath WarpingPath_create (long length); // Search the path for the corresponding axis value. If path is horizontal/vertical // ivar1 and ivar2 will not be equal. The return value is the length of the path segment (ivar2-ivar1 +1) long WarpingPath_getColumnsFromRowIndex (WarpingPath me, long irow, long *icol1, long *icol2); long WarpingPath_getRowsFromColumnIndex (WarpingPath me, long icol, long *irow1, long *irow2); autoEditCostsTable EditCostsTable_create (long targetAlphabetSize, long sourceAlphabetSize); /* The insertion, deletion and substitution costs are specified in this table * 1..n-2 target symbols (target alphabet) * 1..m-2 source symbols (source alphabet) * row n-1 and col m-1 specify no-match symbols * cells [n][1..m-1] specify insertion costs * cells [1..n-1][m] specify deletion costs * cell [n-1][m-1] no-match target == no-match source * cell [n][m] no-match target != no-match source */ void EditCostsTable_setDefaultCosts (EditCostsTable me, double insertionCosts, double deletionCosts, double substitutionCosts); long EditCostsTable_getTargetIndex (EditCostsTable me, const char32 *symbol); long EditCostsTable_getSourceIndex (EditCostsTable me, const char32 *symbol); double EditCostsTable_getInsertionCost (EditCostsTable me, const char32 *symbol); void EditCostsTable_setInsertionCosts (EditCostsTable me, char32 *targets, double cost); void EditCostsTable_setOthersCosts (EditCostsTable me, double insertionCosts, double deletionCost, double substitutionCost_equal, double substitutionCost_unequal); double EditCostsTable_getOthersCost (EditCostsTable me, int type); double EditCostsTable_getDeletionCost (EditCostsTable me, const char32 *symbol); void EditCostsTable_setDeletionCosts (EditCostsTable me, char32 *sources, double cost); double EditCostsTable_getSubstitutionCost (EditCostsTable me, const char32 *symbol, const char32 *replacement); void EditCostsTable_setSubstitutionCosts (EditCostsTable me, char32 *targets, char32 *sources, double cost); autoTableOfReal EditCostsTable_to_TableOfReal (EditCostsTable me); autoEditDistanceTable EditDistanceTable_create (Strings target, Strings source); autoEditDistanceTable EditDistanceTable_createFromCharacterStrings (const char32 *chars1, const char32 *chars2); void EditDistanceTable_draw (EditDistanceTable me, Graphics graphics, int iformat, int precision, double angle); void EditDistanceTable_drawEditOperations (EditDistanceTable me, Graphics graphics); void EditDistanceTable_setDefaultCosts (EditDistanceTable me, double insertionCosts, double deletionCosts, double substitutionCosts); void EditDistanceTable_findPath (EditDistanceTable me, autoTableOfReal *directions); void EditDistanceTable_setEditCosts (EditDistanceTable me, EditCostsTable thee); autoTableOfReal EditDistanceTable_to_TableOfReal_directions (EditDistanceTable me); autoTableOfReal EditDistanceTable_to_TableOfReal (EditDistanceTable me); #endif /* _EditDistanceTable_h_ */ praat-6.0.04/dwtools/EditDistanceTable_def.h000066400000000000000000000036311261542461700207150ustar00rootroot00000000000000/* EditDistanceTable_def.h * * Copyright (C) 2012,2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20120406 First version */ #define ooSTRUCT PairOfInteger oo_DEFINE_STRUCT (PairOfInteger) oo_LONG (x) oo_LONG (y) oo_END_STRUCT (PairOfInteger) #undef ooSTRUCT #define ooSTRUCT WarpingPath oo_DEFINE_CLASS (WarpingPath, Daata) oo_LONG (_capacity) oo_LONG (pathLength) oo_STRUCT_VECTOR (PairOfInteger, path, pathLength) oo_END_CLASS (WarpingPath) #undef ooSTRUCT #define ooSTRUCT EditCostsTable oo_DEFINE_CLASS (EditCostsTable, TableOfReal) #if oo_DECLARING void v_info () override; virtual bool v_matchTargetSymbol (const char32 *targetSymbol, const char32 *symbol); virtual bool v_matchSourceSymbol (const char32 *sourceSymbol, const char32 *symbol); virtual bool v_matchTargetWithSourceSymbol (const char32 *targetSymbol, const char32 *sourceSymbol); #endif oo_END_CLASS (EditCostsTable) #undef ooSTRUCT #define ooSTRUCT EditDistanceTable oo_DEFINE_CLASS (EditDistanceTable, TableOfReal) oo_AUTO_OBJECT (WarpingPath, 0, warpingPath) #if oo_DECLARING oo_AUTO_OBJECT (EditCostsTable, 0, editCostsTable) void v_info () override; #endif oo_END_CLASS (EditDistanceTable) #undef ooSTRUCT /* End of file EditDistanceTable_def.h */ praat-6.0.04/dwtools/Eigen_and_Matrix.cpp000066400000000000000000000040761261542461700203230ustar00rootroot00000000000000/* Eigen_and_Matrix.cpp * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 2002 djmw 20020813 GPL header */ #include "Eigen_and_Matrix.h" autoMatrix Eigen_and_Matrix_project (Eigen me, Matrix thee, long numberOfComponents) { try { if (numberOfComponents == 0) { numberOfComponents = my numberOfEigenvalues; } autoMatrix him = Matrix_create (thy xmin, thy xmax, thy nx, thy dx, thy x1, 0.5, 0.5 + numberOfComponents, numberOfComponents, 1, 1); Eigen_and_Matrix_project_into (me, thee, & him); return him; } catch (MelderError) { Melder_throw (U"Projection Matrix not created."); } } void Eigen_and_Matrix_project_into (Eigen me, Matrix thee, autoMatrix *him) { if (my dimension != thy ny) { Melder_throw (U"The number of rows in the 'from' Matrix must equal the dimension of the eigenvector."); } if ((*him)-> nx != thy nx) { Melder_throw (U"The number of columns in the Matrixes must be equal."); } if ((*him) -> ny > my numberOfEigenvalues) { Melder_throw (U"The number of rows in the 'to' Matrix cannot exceed the number of eigenvectors."); } for (long i = 1; i <= thy nx; i++) { for (long j = 1; j <= (*him) -> ny; j++) { double r = 0; for (long k = 1; k <= my dimension; k++) { // eigenvector in row, data in column r += my eigenvectors[j][k] * thy z[k][i]; } (*him) -> z[j][i] = r; } } } /* End of file Eigen_and_Matrix.cpp */ praat-6.0.04/dwtools/Eigen_and_Matrix.h000066400000000000000000000025221261542461700177620ustar00rootroot00000000000000#ifndef _Eigen_and_Matrix_h_ #define _Eigen_and_Matrix_h_ /* Eigen_and_Matrix.h * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020327 djmw 20020813 GPL header djmw 20110307 Latest modification */ #include "Eigen.h" #include "Matrix.h" autoMatrix Eigen_and_Matrix_project (Eigen me, Matrix thee, long numberOfComponents); /* Purpose: project the columns of the matrix (thou) on the eigenspace (me). */ void Eigen_and_Matrix_project_into (Eigen me, Matrix thee, autoMatrix *p_him); /* Purpose: project the columns of the Matrix (thou) on the eigenspace (me). Result in existing Matrix (him). */ #endif /* _Eigen_and_Matrix_h_ */ praat-6.0.04/dwtools/Eigen_and_Procrustes.cpp000066400000000000000000000037261261542461700212310ustar00rootroot00000000000000/* Eigen_and_Procrustes.cpp * Copyright (C) 2005-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 2004 Initial version */ #include "Eigen_and_Procrustes.h" #include "Configuration_and_Procrustes.h" #include "NUM2.h" autoProcrustes Eigens_to_Procrustes (Eigen me,Eigen thee, long evec_from, long evec_to) { try { long nvectors = evec_to - evec_from + 1; long nmin = my numberOfEigenvalues < thy numberOfEigenvalues ? my numberOfEigenvalues : thy numberOfEigenvalues; if (my dimension != thy dimension) { Melder_throw (U"The eigenvectors must have the same dimension."); } if (evec_from > evec_to || evec_from < 1 || evec_to > nmin) { Melder_throw (U"Eigenvector range too large."); } autoNUMmatrix x (1, my dimension, 1, nvectors); autoNUMmatrix y (1, my dimension, 1, nvectors); for (long j = 1; j <= nvectors; j++) { for (long i = 1; i <= my dimension; i++) { x[i][j] = my eigenvectors[evec_from + j - 1][i]; y[i][j] = thy eigenvectors[evec_from + j - 1][i]; } } autoProcrustes him = Procrustes_create (nvectors); NUMProcrustes (x.peek(), y.peek(), my dimension, nvectors, his r, nullptr, nullptr); return him; } catch (MelderError) { Melder_throw (U"Procrustes not created from Eigens."); } } /* End of file Eigen_and_Procrustes.cpp */ praat-6.0.04/dwtools/Eigen_and_Procrustes.h000066400000000000000000000021121261542461700206620ustar00rootroot00000000000000#ifndef _Eigen_and_Procrustes_h_ #define _Eigen_and_Procrustes_h_ /* Eigen_and_Procrustes.h * Copyright (C) 2004-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * djmw 20041025 Initial version * djmw 20110307 Latest modification */ #include "Eigen.h" #include "Procrustes.h" autoProcrustes Eigens_to_Procrustes (Eigen me, Eigen thee, long evec_from, long evec_to); #endif /* _Eigen_and_Procrustes_h_ */ praat-6.0.04/dwtools/Eigen_and_SSCP.cpp000066400000000000000000000044721261542461700176270ustar00rootroot00000000000000/* Eigen_and_SSCP.c * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020327 djmw 20020813 GPL header djmw 20040219 Eigen_and_Covariance_project added. */ #include "Eigen_and_SSCP.h" static void Eigen_and_SSCP_project_ (Eigen me, SSCP thee, SSCP him) { for (long i = 1; i <= my numberOfEigenvalues; i++) { for (long j = i; j <= my numberOfEigenvalues; j++) { double tmp = 0; for (long k = 1; k <= my dimension; k++) { for (long m = 1; m <= my dimension; m++) { tmp += my eigenvectors[i][k] * thy data[k][m] * my eigenvectors[j][m]; } } his data[i][j] = his data[j][i] = tmp; } double tmp = 0; for (long m = 1; m <= my dimension; m++) { tmp += thy centroid[m] * my eigenvectors[i][m]; } his centroid[i] = tmp; } his numberOfObservations = SSCP_getNumberOfObservations (thee); } autoSSCP Eigen_and_SSCP_project (Eigen me, SSCP thee) { try { if (thy numberOfRows != my dimension) { Melder_throw (U"SSCP_and_Eigen_project: dimensions don't agree."); } autoSSCP him = SSCP_create (my numberOfEigenvalues); Eigen_and_SSCP_project_ (me, thee, him.peek()); return him; } catch (MelderError) { Melder_throw (U"SSCP not projected."); } } autoCovariance Eigen_and_Covariance_project (Eigen me, Covariance thee) { try { if (thy numberOfRows != my dimension) { Melder_throw (U"Covariance_and_Eigen_project: dimensions don't agree."); } autoCovariance him = Covariance_create (my numberOfEigenvalues); Eigen_and_SSCP_project_ (me, thee, him.peek()); return him; } catch (MelderError) { Melder_throw (U"Covariance not projected."); } } /* End of file Eigen_and_SSCP.cpp */ praat-6.0.04/dwtools/Eigen_and_SSCP.h000066400000000000000000000023341261542461700172670ustar00rootroot00000000000000#ifndef _Eigen_and_SSCP_h_ #define _Eigen_and_SSCP_h_ /* Eigen_and_SSCP.h * * Copyright (C) 1993-2004, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020327 Initial version djmw 20040219 GPL header */ #include "Eigen.h" #include "SSCP.h" autoSSCP Eigen_and_SSCP_project (Eigen me, SSCP thee); autoCovariance Eigen_and_Covariance_project (Eigen me, Covariance thee); /* Purpose: project the SSCP (thee) on the eigenspace (me): S' = E' S E Returns SSCP-object with square matrix dimension 'my numberOfEigenvalues' */ #endif /* _Eigen_and_SSCP_h_ */ praat-6.0.04/dwtools/Eigen_and_TableOfReal.cpp000066400000000000000000000062471261542461700212010ustar00rootroot00000000000000/* Eigen_and_TableOfReal.cpp * * Copyright (C) 1993-2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020327 Initial version. djmw 20020429 _project: copy rowLabels too. djmw 20020502 Added from index to projections. djmw 20020813 GPL header djmw 20110304 Thing_new */ #include "Eigen_and_TableOfReal.h" #include "NUM2.h" autoTableOfReal Eigen_and_TableOfReal_project (Eigen me, TableOfReal thee, long from, long numberOfComponents) { try { if (numberOfComponents == 0) { numberOfComponents = my numberOfEigenvalues; } autoTableOfReal him = TableOfReal_create (thy numberOfRows, numberOfComponents); Eigen_and_TableOfReal_project_into (me, thee, from, thy numberOfColumns, him.peek(), 1, numberOfComponents); NUMstrings_copyElements (thy rowLabels, his rowLabels, 1, thy numberOfRows); return him.transfer(); } catch (MelderError) { Melder_throw (U"TableOfReal not created from projection."); } } void Eigen_and_TableOfReal_project_into (Eigen me, TableOfReal thee, long thee_from, long thee_to, TableOfReal him, long his_from, long his_to) { long thee_ncols = thee_to - thee_from + 1; long his_ncols = his_to - his_from + 1; if (thee_from < 1 || thee_to > thy numberOfColumns || his_from < 1 || his_to > his numberOfColumns) { Melder_throw (U"Column selection not correct."); } if (thee_ncols != my dimension) { Melder_throw (U"The number of selected columns to project (", thee_ncols, U") must equal the dimension of the eigenvectors (", my dimension, U")."); } if (his_ncols > my numberOfEigenvalues) { Melder_throw (U"The number of selected columns in the result (", his_ncols, U") cannot exceed the number of eigenvectors (", my numberOfEigenvalues, U")."); } for (long i = 1; i <= thy numberOfRows; i++) { /* row */ for (long j = 1; j <= his_ncols; j++) { double r = 0; for (long k = 1; k <= my dimension; k++) { /* eigenvector in row, data in row */ r += my eigenvectors[j][k] * thy data[i][thee_from + k - 1]; } his data[i][his_from + j - 1] = r; } } } autoEigen TablesOfReal_to_Eigen_gsvd (TableOfReal me, TableOfReal thee) { try { if (my numberOfColumns != thy numberOfColumns) { Melder_throw (U"TablesOfReal_to_Eigen: Number of columns must be equal."); } autoEigen him = Thing_new (Eigen); Eigen_initFromSquareRootPair (him.peek(), my data, my numberOfRows, my numberOfColumns, thy data, thy numberOfRows); return him; } catch (MelderError) { Melder_throw (me, U": Eigen not created."); } } /* End of file Eigen_and_TableOfReal.cpp */ praat-6.0.04/dwtools/Eigen_and_TableOfReal.h000066400000000000000000000031431261542461700206360ustar00rootroot00000000000000#ifndef _Eigen_and_TableOfReal_h_ #define _Eigen_and_TableOfReal_h_ /* Eigen_and_TableOfReal.h * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020327 Initial version djmw 20020813 GPL header djmw 20110307 Latest modification */ #include "Eigen.h" #include "TableOfReal.h" autoTableOfReal Eigen_and_TableOfReal_project (Eigen me, TableOfReal thee, long from, long numberOfComponents); /* Purpose: project the rows of the TableOfReal (thee) starting at index 'from' on the eigenspace (me). */ void Eigen_and_TableOfReal_project_into (Eigen me, TableOfReal thee, long thee_from, long thee_to, TableOfReal him, long his_from, long his_to); /* Purpose: project the rows of the TableOfReal (thee) on the eigenspace (me). Result in existing TableOfReal (him). */ autoEigen TablesOfReal_to_Eigen_gsvd (TableOfReal me, TableOfReal thee); /* Solve A'A x -lambda B'B x = 0 */ #endif /* _Eigen_and_TableOfReal_h_ */ praat-6.0.04/dwtools/Excitations.cpp000066400000000000000000000060341261542461700174140ustar00rootroot00000000000000/* Excitations.cpp * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header djmw 20071009 wchar djmw 20071017 Melder_error djmw 20090914 getItem modified djmw 20110304 Thing_new */ #include "Excitations.h" /* static int readText (I, FILE *f) { iam (Excitations); my itemClass = classExcitation; return inherited (Ordered) readText (me, f); } static int readBinary (I, FILE *f) { iam (Excitations); my itemClass = classExcitation; return inherited (Ordered) readBinary (me, f); } */ Thing_implement (Excitations, Ordered, 0); autoExcitations Excitations_create (long initialCapacity) { try { autoExcitations me = Thing_new (Excitations); Ordered_init (me.peek(), classExcitation, initialCapacity); return me; } catch (MelderError) { Melder_throw (U"Excitations not created."); } } autoPattern Excitations_to_Pattern (Excitations me, long join) { try { Melder_assert (my size > 0); Matrix m = (Matrix) my item[1]; if (join < 1) { join = 1; } if ( (my size % join) != 0) { Melder_throw (U"Number of rows is not a multiple of join."); } autoPattern thee = Pattern_create (my size / join, join * m -> nx); long r = 0, c = 1; for (long i = 1; i <= my size; i++) { double *z = ( (Matrix) my item[i])->z[1]; if ( (i - 1) % join == 0) { r++; c = 1; } for (long j = 1; j <= m -> nx; j++) { thy z[r][c++] = z[j]; } } return thee; } catch (MelderError) { Melder_throw (me, U": no Pattern created."); } } autoTableOfReal Excitations_to_TableOfReal (Excitations me) { try { Melder_assert (my size > 0); Matrix m = (Matrix) my item[1]; autoTableOfReal thee = TableOfReal_create (my size, m -> nx); for (long i = 1; i <= my size; i++) { double *z = ( (Matrix) my item[i]) -> z[1]; for (long j = 1; j <= m -> nx; j++) { thy data[i][j] = z[j]; } } return thee; } catch (MelderError) { Melder_throw (me, U": no TableOfReal created."); } } autoExcitation Excitations_getItem (Excitations me, long item) { try { if (item < 1 || item > my size) { Melder_throw (U"Not a valid element number."); } autoExcitation thee = Data_copy ( (Excitation) my item[item]); Thing_setName (thee.peek(), Thing_getName ( (Thing) my item[item])); return thee; } catch (MelderError) { Melder_throw (me, U": no Excitation created."); } } /* End of file Excitations.cpp */ praat-6.0.04/dwtools/Excitations.h000066400000000000000000000027451261542461700170660ustar00rootroot00000000000000#ifndef _Excitations_h_ #define _Excitations_h_ /* Excitations.h * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header djmw 20110306 Latest modification. */ #include "Collection.h" #include "Excitation.h" #include "Pattern.h" #include "TableOfReal.h" Thing_define (Excitations, Ordered) { }; /* Excitations is a collection of objects of the same class Excitation */ autoExcitations Excitations_create (long initialCapacity); autoPattern Excitations_to_Pattern (Excitations me, long join); /* Precondition: my size >= 1, all items have same dimension */ autoTableOfReal Excitations_to_TableOfReal (Excitations me); /* Precondition: my size >= 1, all items have same dimension */ autoExcitation Excitations_getItem (Excitations m, long item); #endif /* _Excitations_h_ */ praat-6.0.04/dwtools/FilterBank.cpp000066400000000000000000001142451261542461700171470ustar00rootroot00000000000000/* FilterBank.cpp * * Copyright (C) 1993-2012, 2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20010718 djmw 20020813 GPL header djmw 20030901 Added fiter function drawing and frequency scale drawing. djmw 20050731 +FilterBank_and_PCA_drawComponent djmw 20071017 Melder_error djmw 20071201 Melder_warning djmw 20080122 float -> double djmw 20110304 Thing_new */ #include "Eigen_and_Matrix.h" #include "FilterBank.h" #include "Matrix_extensions.h" #include "Sound_and_Spectrum.h" #include "Sound_extensions.h" #include "Sound_to_Pitch.h" #include "NUM2.h" #define MAX(m,n) ((m) > (n) ? (m) : (n)) #define MIN(m,n) ((m) < (n) ? (m) : (n)) static double scaleFrequency (double f, int scale_from, int scale_to) { double fhz = NUMundefined; if (scale_from == scale_to) { return f; } if (scale_from == FilterBank_HERTZ) { fhz = f; } else if (scale_from == FilterBank_BARK) { fhz = BARKTOHZ (f); } else if (scale_from == FilterBank_MEL) { fhz = MELTOHZ (f); } if (scale_to == FilterBank_HERTZ || fhz == NUMundefined) { return fhz; } if (scale_to == FilterBank_BARK) { f = HZTOBARK (fhz); } else if (scale_to == FilterBank_MEL) { f = HZTOMEL (fhz); } else { return NUMundefined; } return f; } static char32 const *GetFreqScaleText (int scale) { char32 const *hertz = U"Frequency (Hz)"; char32 const *bark = U"Frequency (Bark)"; char32 const *mel = U"Frequency (mel)"; char32 const *error = U"Frequency (undefined)"; if (scale == FilterBank_HERTZ) { return hertz; } else if (scale == FilterBank_BARK) { return bark; } else if (scale == FilterBank_MEL) { return mel; } return error; } static int checkLimits (Matrix me, int fromFreqScale, int toFreqScale, int *fromFilter, int *toFilter, double *zmin, double *zmax, int dbScale, double *ymin, double *ymax) { if (*fromFilter == 0) { *fromFilter = 1; } if (*toFilter == 0) { *toFilter = my ny; } if (*toFilter < *fromFilter) { *fromFilter = 1; *toFilter = my ny; } if (*fromFilter < 1) { *fromFilter = 1; } if (*toFilter > my ny) { *toFilter = my ny; } if (*fromFilter > *toFilter) { Melder_warning (U"Filter numbers must be in range [1, ", my ny, U"]"); return 0; } if (*zmin < 0 || *zmax < 0) { Melder_warning (U"Frequencies must be positive."); return 0; } if (*zmax <= *zmin) { *zmin = scaleFrequency (my ymin, fromFreqScale, toFreqScale); *zmax = scaleFrequency (my ymax, fromFreqScale, toFreqScale); } if (*ymax <= *ymin) { *ymax = 1; *ymin = 0; if (dbScale) { *ymax = 0; *ymin = -60; } } return 1; } static double to_dB (double a, double factor, double ref_dB) { if (a <= 0) { return ref_dB; } a = factor * log10 (a); if (a < ref_dB) { a = ref_dB; } return a; } static void setDrawingLimits (double *a, long n, double amin, double amax, long *ibegin, long *iend) { *ibegin = 0; *iend = n + 1; long lower = 1; for (long i = 1; i <= n; i++) { if (a[i] == NUMundefined) { if (lower == 0) { /* high frequency part */ *iend = i; break; } *ibegin = i; continue; } lower = 0; if (a[i] < amin) { a[i] = amin; } else if (a[i] > amax) { a[i] = amax; } } (*ibegin) ++; (*iend)--; } Thing_implement (FilterBank, Matrix, 2); Thing_implement (BarkFilter, FilterBank, 2); BarkFilter BarkFilter_create (double tmin, double tmax, long nt, double dt, double t1, double fmin, double fmax, long nf, double df, double f1) { try { autoBarkFilter me = Thing_new (BarkFilter); Matrix_init (me.peek(), tmin, tmax, nt, dt, t1, fmin, fmax, nf, df, f1); return me.transfer(); } catch (MelderError) { Melder_throw (U"BarkFilter not created."); } } double FilterBank_getFrequencyInHertz (I, double f, int scale_from) { (void) void_me; return scaleFrequency (f, scale_from, FilterBank_HERTZ); } double FilterBank_getFrequencyInBark (I, double f, int scale_from) { (void) void_me; return scaleFrequency (f, scale_from, FilterBank_BARK); } double FilterBank_getFrequencyInMel (I, double f, int scale_from) { (void) void_me; return scaleFrequency (f, scale_from, FilterBank_MEL); } int FilterBank_getFrequencyScale (I) { iam (FilterBank); return my v_getFrequencyScale (); } void FilterBank_drawFrequencyScales (I, Graphics g, int horizontalScale, double xmin, double xmax, int verticalScale, double ymin, double ymax, int garnish) { iam (FilterBank); int myFreqScale = FilterBank_getFrequencyScale (me); if (xmin < 0 || xmax < 0 || ymin < 0 || ymax < 0) { Melder_warning (U"Frequencies must be >= 0."); return; } if (xmin >= xmax) { double xmint = my ymin; double xmaxt = my ymax; if (ymin < ymax) { xmint = scaleFrequency (ymin, verticalScale, myFreqScale); xmaxt = scaleFrequency (ymax, verticalScale, myFreqScale); } xmin = scaleFrequency (xmint, myFreqScale, horizontalScale); xmax = scaleFrequency (xmaxt, myFreqScale, horizontalScale); } if (ymin >= ymax) { ymin = scaleFrequency (xmin, horizontalScale, verticalScale); ymax = scaleFrequency (xmax, horizontalScale, verticalScale); } long n = 2000; autoNUMvector a (1, n); Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); double df = (xmax - xmin) / (n - 1); for (long i = 1; i <= n; i++) { double f = xmin + (i - 1) * df; a[i] = scaleFrequency (f, horizontalScale, verticalScale); } long ibegin, iend; setDrawingLimits (a.peek(), n, ymin, ymax, & ibegin, & iend); if (ibegin <= iend) { double fmin = xmin + (ibegin - 1) * df; double fmax = xmax - (n - iend) * df; Graphics_function (g, a.peek(), ibegin, iend, fmin, fmax); } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksLeft (g, 2, true, true, false); Graphics_textLeft (g, true, GetFreqScaleText (verticalScale)); Graphics_marksBottom (g, 2, true, true, false); Graphics_textBottom (g, true, GetFreqScaleText (horizontalScale)); } } void FilterBank_paint (FilterBank me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum, int garnish) { if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } long ixmin, ixmax, iymin, iymax; (void) Matrix_getWindowSamplesX (me, xmin - 0.49999 * my dx, xmax + 0.49999 * my dx, &ixmin, &ixmax); (void) Matrix_getWindowSamplesY (me, ymin - 0.49999 * my dy, ymax + 0.49999 * my dy, &iymin, &iymax); if (maximum <= minimum) { (void) Matrix_getWindowExtrema (me, ixmin, ixmax, iymin, iymax, &minimum, &maximum); } if (maximum <= minimum) { minimum -= 1.0; maximum += 1.0; } if (xmin >= xmax || ymin >= ymax) { return; } Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_image (g, my z, ixmin, ixmax, Sampled_indexToX (me, ixmin - 0.5), Sampled_indexToX (me, ixmax + 0.5), iymin, iymax, SampledXY_indexToY (me, iymin - 0.5), SampledXY_indexToY (me, iymax + 0.5), minimum, maximum); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksLeft (g, 2, true, true, false); Graphics_textLeft (g, true, GetFreqScaleText (my v_getFrequencyScale ())); Graphics_marksBottom (g, 2, true, true, false); Graphics_textBottom (g, true, U"Time (s)"); } } void BarkFilter_drawSekeyHansonFilterFunctions (BarkFilter me, Graphics g, int toFreqScale, int fromFilter, int toFilter, double zmin, double zmax, int dbScale, double ymin, double ymax, int garnish) { if (! checkLimits (me, FilterBank_BARK, toFreqScale, & fromFilter, & toFilter, & zmin, & zmax, dbScale, & ymin, & ymax)) { return; } long n = 1000; autoNUMvector a (1, n); Graphics_setInner (g); Graphics_setWindow (g, zmin, zmax, ymin, ymax); for (long j = fromFilter; j <= toFilter; j++) { double df = (zmax - zmin) / (n - 1); double zMid = Matrix_rowToY (me, j); long ibegin, iend; for (long i = 1; i <= n; i++) { double f = zmin + (i - 1) * df; double z = scaleFrequency (f, toFreqScale, FilterBank_BARK); if (z == NUMundefined) { a[i] = NUMundefined; } else { z -= zMid + 0.215; a[i] = 7.0 - 7.5 * z - 17.5 * sqrt (0.196 + z * z); if (! dbScale) { a[i] = pow (10.0, a[i]); } } } setDrawingLimits (a.peek(), n, ymin, ymax, &ibegin, &iend); if (ibegin <= iend) { double fmin = zmin + (ibegin - 1) * df; double fmax = zmax - (n - iend) * df; Graphics_function (g, a.peek(), ibegin, iend, fmin, fmax); } } Graphics_unsetInner (g); if (garnish) { double distance = dbScale ? 10.0 : 1.0; const char32 *ytext = dbScale ? U"Amplitude (dB)" : U"Amplitude"; Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeftEvery (g, 1.0, distance, true, true, false); Graphics_textLeft (g, true, ytext); Graphics_textBottom (g, true, GetFreqScaleText (toFreqScale)); } } Thing_implement (MelFilter, FilterBank, 2); MelFilter MelFilter_create (double tmin, double tmax, long nt, double dt, double t1, double fmin, double fmax, long nf, double df, double f1) { try { autoMelFilter me = Thing_new (MelFilter); Matrix_init (me.peek(), tmin, tmax, nt, dt, t1, fmin, fmax, nf, df, f1); return me.transfer(); } catch (MelderError) { Melder_throw (U"MelFilter not created."); } } /* void FilterBank_drawFilters (I, Graphics g, long fromf, long tof, double xmin, double xmax, int xlinear, double ymin, double ymax, int ydb, double (*tolinf)(double f), double (*tononlin) (double f), double (*filteramp)(double f0, double b, double f)) { iam (Matrix); }*/ void FilterBank_drawTimeSlice (I, Graphics g, double t, double fmin, double fmax, double min, double max, const char32 *xlabel, int garnish) { iam (Matrix); Matrix_drawSliceY (me, g, t, fmin, fmax, min, max); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); if (xlabel) { Graphics_textBottom (g, false, xlabel); } } } void MelFilter_drawFilterFunctions (MelFilter me, Graphics g, int toFreqScale, int fromFilter, int toFilter, double zmin, double zmax, int dbScale, double ymin, double ymax, int garnish) { if (! checkLimits (me, FilterBank_MEL, toFreqScale, & fromFilter, & toFilter, & zmin, & zmax, dbScale, & ymin, & ymax)) { return; } long n = 1000; autoNUMvector a (1, n); Graphics_setInner (g); Graphics_setWindow (g, zmin, zmax, ymin, ymax); for (long j = fromFilter; j <= toFilter; j++) { double df = (zmax - zmin) / (n - 1); double fc_mel = my y1 + (j - 1) * my dy; double fc_hz = MELTOHZ (fc_mel); double fl_hz = MELTOHZ (fc_mel - my dy); double fh_hz = MELTOHZ (fc_mel + my dy); long ibegin, iend; for (long i = 1; i <= n; i++) { // Filterfunction: triangular on a linear frequency scale AND a linear amplitude scale. double f = zmin + (i - 1) * df; double z = scaleFrequency (f, toFreqScale, FilterBank_HERTZ); if (z == NUMundefined) { a[i] = NUMundefined; } else { a[i] = NUMtriangularfilter_amplitude (fl_hz, fc_hz, fh_hz, z); if (dbScale) { a[i] = to_dB (a[i], 10, ymin); } } } setDrawingLimits (a.peek(), n, ymin, ymax, &ibegin, &iend); if (ibegin <= iend) { double fmin = zmin + (ibegin - 1) * df; double fmax = zmax - (n - iend) * df; Graphics_function (g, a.peek(), ibegin, iend, fmin, fmax); } } Graphics_unsetInner (g); if (garnish) { double distance = dbScale ? 10.0 : 1.0; char32 const *ytext = dbScale ? U"Amplitude (dB)" : U"Amplitude"; Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeftEvery (g, 1.0, distance, true, true, false); Graphics_textLeft (g, true, ytext); Graphics_textBottom (g, true, GetFreqScaleText (toFreqScale)); } } /* void MelFilter_drawFilters (MelFilter me, Graphics g, long from, long to, double fmin, double fmax, double ymin, double ymax, int dbscale, int garnish) { long i; double df = my dy; if (fmin >= fmax) { fmin = my ymin; fmax = my ymax; } if (from >= to) { from = 1; to = my ny; } Graphics_setWindow (g, my ymin, my ymax, 0.0, 1.0); Graphics_setInner (g); for (i = from; i <= to; i++) { double fc = my y1 + (i - 1) * df; double fc_hz = MELTOHZ (fc); double fl_hz = MELTOHZ (fc - df); double fh_hz = MELTOHZ (fc + df); *//* Draw triangle *//* Graphics_line (g, fl_hz, 0.0, fc_hz, 1.0); Graphics_line (g, fc_hz, 1.0, fh_hz, 0.0); } Graphics_unsetInner (g); } */ Matrix FilterBank_to_Matrix (I) { iam (Matrix); try { autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, my ymin, my ymax, my ny, my dy, my y1); NUMmatrix_copyElements (my z, thy z, 1, my ny, 1, my nx); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not converted to Matrix."); } } BarkFilter Matrix_to_BarkFilter (I) { iam (Matrix); try { autoBarkFilter thee = BarkFilter_create (my xmin, my xmax, my nx, my dx, my x1, my ymin, my ymax, my ny, my dy, my y1); NUMmatrix_copyElements (my z, thy z, 1, my ny, 1, my nx); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not converted to BarkFilter."); } } MelFilter Matrix_to_MelFilter (I) { iam (Matrix); try { autoMelFilter thee = MelFilter_create (my xmin, my xmax, my nx, my dx, my x1, my ymin, my ymax, my ny, my dy, my y1); NUMmatrix_copyElements (my z, thy z, 1, my ny, 1, my nx); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not converted to MelFilter."); } } Thing_implement (FormantFilter, FilterBank, 2); FormantFilter FormantFilter_create (double tmin, double tmax, long nt, double dt, double t1, double fmin, double fmax, long nf, double df, double f1) { try { autoFormantFilter me = Thing_new (FormantFilter); Matrix_init (me.peek(), tmin, tmax, nt, dt, t1, fmin, fmax, nf, df, f1); return me.transfer(); } catch (MelderError) { Melder_throw (U"FormantFilter not created."); } } void FormantFilter_drawFilterFunctions (FormantFilter me, Graphics g, double bandwidth, int toFreqScale, int fromFilter, int toFilter, double zmin, double zmax, int dbScale, double ymin, double ymax, int garnish) { if (! checkLimits (me, FilterBank_HERTZ, toFreqScale, & fromFilter, & toFilter, & zmin, & zmax, dbScale, & ymin, & ymax)) { return; } if (bandwidth <= 0) { Melder_warning (U"Bandwidth must be greater than zero."); } long n = 1000; autoNUMvectora (1, n); Graphics_setInner (g); Graphics_setWindow (g, zmin, zmax, ymin, ymax); for (long j = fromFilter; j <= toFilter; j++) { double df = (zmax - zmin) / (n - 1); double fc = my y1 + (j - 1) * my dy; long ibegin, iend; for (long i = 1; i <= n; i++) { double f = zmin + (i - 1) * df; double z = scaleFrequency (f, toFreqScale, FilterBank_HERTZ); if (z == NUMundefined) { a[i] = NUMundefined; } else { a[i] = NUMformantfilter_amplitude (fc, bandwidth, z); if (dbScale) { a[i] = to_dB (a[i], 10, ymin); } } } setDrawingLimits (a.peek(), n, ymin, ymax, &ibegin, &iend); if (ibegin <= iend) { double fmin = zmin + (ibegin - 1) * df; double fmax = zmax - (n - iend) * df; Graphics_function (g, a.peek(), ibegin, iend, fmin, fmax); } } Graphics_unsetInner (g); if (garnish) { double distance = dbScale ? 10 : 1; char32 const *ytext = dbScale ? U"Amplitude (dB)" : U"Amplitude"; Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeftEvery (g, 1.0, distance, true, true, false); Graphics_textLeft (g, true, ytext); Graphics_textBottom (g, true, GetFreqScaleText (toFreqScale)); } } FormantFilter Matrix_to_FormantFilter (I) { iam (Matrix); try { autoFormantFilter thee = FormantFilter_create (my xmin, my xmax, my nx, my dx, my x1, my ymin, my ymax, my ny, my dy, my y1); NUMmatrix_copyElements (my z, thy z, 1, my ny, 1, my nx); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not converted to FormantFilter."); } } Spectrum FormantFilter_to_Spectrum_slice (FormantFilter me, double t) { try { double sqrtref = sqrt (FilterBank_DBREF); double factor2 = 2 * 10 * FilterBank_DBFAC; autoSpectrum thee = Spectrum_create (my ymax, my ny); thy xmin = my ymin; thy xmax = my ymax; thy x1 = my y1; thy dx = my dy; /* Frequency step. */ long frame = Sampled_xToNearestIndex (me, t); if (frame < 1) { frame = 1; } if (frame > my nx) { frame = my nx; } for (long i = 1; i <= my ny; i++) { /* power = ref * 10 ^ (value / 10) sqrt(power) = sqrt(ref) * 10 ^ (value / (2*10)) */ thy z[1][i] = sqrtref * pow (10, my z[i][frame] / factor2); thy z[2][i] = 0.0; } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": Spectral slice not created."); } } Intensity FilterBank_to_Intensity (I) { iam (Matrix); try { autoIntensity thee = Intensity_create (my xmin, my xmax, my nx, my dx, my x1); double db_ref = 10 * log10 (FilterBank_DBREF); for (long j = 1; j <= my nx; j++) { double p = 0; for (long i = 1; i <= my ny; i++) { p += FilterBank_DBREF * exp (NUMln10 * my z[i][j] / 10); } thy z[1][j] = 10 * log10 (p) - db_ref; } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": Intensity not created."); } } void FilterBank_equalizeIntensities (I, double intensity_db) { iam (Matrix); for (long j = 1; j <= my nx; j++) { double p = 0; for (long i = 1; i <= my ny; i++) { p += FilterBank_DBREF * exp (NUMln10 * my z[i][j] / 10); } double delta_db = intensity_db - 10 * log10 (p / FilterBank_DBREF); for (long i = 1; i <= my ny; i++) { my z[i][j] += delta_db; } } } void FilterBank_and_PCA_drawComponent (I, PCA thee, Graphics g, long component, double dblevel, double frequencyOffset, double scale, double tmin, double tmax, double fmin, double fmax) { iam (FilterBank); if (component < 1 || component > thy numberOfEigenvalues) { Melder_throw (U"Component too large."); } // Scale Intensity autoFilterBank fcopy = (FilterBank) Data_copy (me); FilterBank_equalizeIntensities (fcopy.peek(), dblevel); autoMatrix him = Eigen_and_Matrix_project (thee, fcopy.peek(), component); for (long j = 1; j <= my nx; j++) { fcopy -> z[component][j] = frequencyOffset + scale * fcopy -> z[component][j]; } Matrix_drawRows (fcopy.peek(), g, tmin, tmax, component - 0.5, component + 0.5, fmin, fmax); } // Convert old types to new types MelSpectrogram MelFilter_to_MelSpectrogram (MelFilter me) { try { autoMelSpectrogram thee = MelSpectrogram_create (my xmin, my xmax, my nx, my dx, my x1, my ymin, my ymax, my ny, my dy, my y1); for (long i = 1; i <= my ny; i++) { for (long j = 1; j <= my nx; j++) { thy z[i][j] = 4e-10 * pow (10, my z[i][j] / 10); } } return thee.transfer (); } catch (MelderError) { Melder_throw (U"MelSpectrogram not created."); } } BarkSpectrogram BarkFilter_to_BarkSpectrogram (BarkFilter me) { try { autoBarkSpectrogram thee = BarkSpectrogram_create (my xmin, my xmax, my nx, my dx, my x1, my ymin, my ymax, my ny, my dy, my y1); for (long i = 1; i <= my ny; i++) { for (long j = 1; j <= my nx; j++) { thy z[i][j] = 4e-10 * pow (10, my z[i][j] / 10); } } return thee.transfer (); } catch (MelderError) { Melder_throw (U"BarkSpectrogram not created."); } } Spectrogram FormantFilter_to_Spectrogram (FormantFilter me) { try { autoSpectrogram thee = Spectrogram_create (my xmin, my xmax, my nx, my dx, my x1, my ymin, my ymax, my ny, my dy, my y1); for (long i = 1; i <= my ny; i++) { for (long j = 1; j <= my nx; j++) { thy z[i][j] = 4e-10 * pow (10, my z[i][j] / 10); } } return thee.transfer (); } catch (MelderError) { Melder_throw (U"Spectrogram not created."); } } /* MelFilter_and_MFCC.cpp */ static double **NUMcosinesTable (long n) { autoNUMmatrix costab (1, n, 1, n); for (long k = 1; k <= n; k++) { for (long j = 1; j <= n; j++) { costab[k][j] = cos (NUMpi * (k - 1) * (j - 0.5) / n); } } return costab.transfer(); } // x[1..n] : input, y[1..n] : output static void NUMcosineTransform (double *x, double *y, long n, double **cosinesTable) { for (long k = 1; k <= n; k++) { y[k] = 0; for (long j = 1; j <= n; j++) { y[k] += x[j] * cosinesTable[k][j]; } } } // x: input, y: output static void NUMinverseCosineTransform (double *x, double *y, long n, double **cosinesTable) { for (long j = 1; j <= n; j++) { y[j] = 0.5 * x[1]; // * cosinesTable[1][j]; for (long k = 2; k <= n; k++) { y[j] += x[k] * cosinesTable[k][j]; } y[j] *= 2.0 / n; } } static double testCosineTransform (long n) { try { autoNUMvector x (1, n); autoNUMvector y (1, n); autoNUMvector x2 (1, n); autoNUMmatrix cosinesTable (NUMcosinesTable (n), 1, 1); for (long i = 1 ; i <= n; i++) { x[i] = NUMrandomUniform (0, 70); } NUMcosineTransform (x.peek(), y.peek(), n, cosinesTable.peek()); NUMinverseCosineTransform (y.peek(), x2.peek(), n, cosinesTable.peek()); double delta = 0; for (long i =1 ; i <= n; i++) { double dif = x[i] - x2[i]; delta += dif * dif; } delta = sqrt (delta); return delta; } catch (MelderError) { Melder_throw (U"Test cosine transform error"); } } MFCC MelFilter_to_MFCC (MelFilter me, long numberOfCoefficients) { try { autoNUMmatrix cosinesTable (NUMcosinesTable (my ny), 1, 1); autoNUMvector x (1, my ny); autoNUMvector y (1, my ny); //double fmax_mel = my y1 + (my ny - 1) * my dy; numberOfCoefficients = numberOfCoefficients > my ny - 1 ? my ny - 1 : numberOfCoefficients; Melder_assert (numberOfCoefficients > 0); // 20130220 new interpretation of maximumNumberOfCoefficients necessary for inverse transform autoMFCC thee = MFCC_create (my xmin, my xmax, my nx, my dx, my x1, my ny - 1, my ymin, my ymax); for (long frame = 1; frame <= my nx; frame++) { CC_Frame cf = (CC_Frame) & thy frame[frame]; for (long i = 1; i <= my ny; i++) { x[i] = my z[i][frame]; } NUMcosineTransform (x.peek(), y.peek(), my ny, cosinesTable.peek()); CC_Frame_init (cf, numberOfCoefficients); for (long i = 1; i <= numberOfCoefficients; i++) { cf -> c[i] = y[i + 1]; } cf -> c0 = y[1]; } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no MFCC created."); } } MelFilter MFCC_to_MelFilter (MFCC me, long first, long last) { try { long nf = my maximumNumberOfCoefficients + 1; autoNUMmatrix cosinesTable (NUMcosinesTable (nf), 1, 1); autoNUMvector x (1, nf); autoNUMvector y (1, nf); if (first >= last) { first = 0; last = nf - 1; } if (first < 0 || last > nf - 1) { Melder_throw (U"MFCC_to_MelFilter: coefficients must be in interval [0,", my maximumNumberOfCoefficients, U"]."); } double df = (my fmax - my fmin) / (nf + 1); autoMelFilter thee = MelFilter_create (my xmin, my xmax, my nx, my dx, my x1, my fmin, my fmax, nf, df, df); for (long frame = 1; frame <= my nx; frame++) { CC_Frame cf = (CC_Frame) & my frame[frame]; long iend = MIN (last, cf -> numberOfCoefficients); x[1] = first == 0 ? cf -> c0 : 0; for (long i = 1; i <= my maximumNumberOfCoefficients; i++) { x[i + 1] = i < first || i > iend ? 0 : cf -> c[i]; } NUMinverseCosineTransform (x.peek(), y.peek(), nf, cosinesTable.peek()); for (long i = 1; i <= nf; i++) { thy z[i][frame] = y[i]; } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no MelFilter created."); } } static MelFilter MFCC_to_MelFilter2 (MFCC me, long first_cc, long last_cc, double f1_mel, double df_mel) { try { int use_c0 = 0; long nf = lround ((my fmax - my fmin) / df_mel); double fmin = MAX (f1_mel - df_mel, 0), fmax = f1_mel + (nf + 1) * df_mel; if (nf < 1) { Melder_throw (U"MFCC_to_MelFilter: the position of the first filter, the distance between the filters, " U"and, the maximum do not result in a positive number of filters."); } // Default values if (first_cc == 0) { first_cc = 1; use_c0 = 1; } if (last_cc == 0) { last_cc = my maximumNumberOfCoefficients; } // Be strict if (last_cc < first_cc || first_cc < 1 || last_cc > my maximumNumberOfCoefficients) { Melder_throw (U"MFCC_to_MelFilter: coefficients must be in interval [1,", my maximumNumberOfCoefficients, U"]."); } autoNUMmatrix dct (NUMcosinesTable (first_cc, last_cc, nf), first_cc, 1); // TODO ?? //if ((dct = NUMcosinesTable (first_cc, last_cc, nf)) == nullptr) return nullptr; autoMelFilter thee = MelFilter_create (my xmin, my xmax, my nx, my dx, my x1, fmin, fmax, nf, df_mel, f1_mel); for (long frame = 1; frame <= my nx; frame++) { CC_Frame cf = (CC_Frame) & my frame[frame]; long ie = MIN (last_cc, cf -> numberOfCoefficients); for (long j = 1; j <= nf; j++) { double t = 0; for (long i = first_cc; i <= ie; i++) { t += cf -> c[i] * dct[i][j]; } // The inverse CT has a factor 1/N t /= nf; if (use_c0) { t += cf -> c0; } thy z[j][frame] = t; } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no MelFilter created."); } } /* Sound_and_FilterBank.cpp */ // prototypes Sound FilterBank_as_Sound (FilterBank me); /* The gaussian(x) = (exp(-48*((i-(n+1)/2)/(n+1))^2)-exp(-12))/(1-exp(-12)); For power we need the area under the square of this window: Integrate (gaussian(i)^2,i=1..n) = (sqrt(Pi)*sqrt(3)*sqrt(2)*erf(2*(n-1)*sqrt(3)*sqrt(2)/(n+1))*(n+1)+ 24*exp(-24)*(n-1)+ -4*sqrt(Pi)*sqrt(3)*exp(-12)*erf(2*(n-1)*sqrt(3)/(n+1))*(n+1))/ (24 * (-1+exp(-12))^2) To compare with the rectangular window we need to divide this by the window width (n-1) x 1^2. */ static double gaussian_window_squared_correction (long n) { double e12 = exp (-12), denum = (e12 - 1) * (e12 - 1) * 24 * (n - 1); double sqrt3 = sqrt (3), sqrt2 = sqrt (2), sqrtpi = sqrt (NUMpi); double arg1 = 2 * sqrt3 * (n - 1) / (n + 1), arg2 = arg1 * sqrt2; double p2 = sqrtpi * sqrt3 * sqrt2 * (1 - NUMerfcc (arg2)) * (n + 1); double p1 = 4 * sqrtpi * sqrt3 * e12 * (1 - NUMerfcc (arg1)) * (n + 1); return (p2 - p1 + 24 * (n - 1) * e12 * e12) / denum; } static Matrix Sound_to_spectralpower (Sound me) { try { autoSpectrum s = Sound_to_Spectrum (me, true); autoMatrix thee = Matrix_create (s -> xmin, s -> xmax, s -> nx, s -> dx, s -> x1, 1, 1, 1, 1, 1); double scale = 2.0 * s -> dx / (my xmax - my xmin); // factor '2' because of positive and negative frequencies // s -> dx : width of frequency bin // my xmax - my xmin : duration of sound double *z = thy z[1], *re = s -> z[1], *im = s -> z[2]; for (long i = 1; i <= s -> nx; i++) { z[i] = scale * (re[i] * re[i] + im[i] * im [i]); } // Frequency bins at 0 Hz and nyquist don't count for two. z[1] *= 0.5; z[s -> nx] *= 0.5; return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no Matrix with spectral power created."); } } static int Sound_into_BarkFilter_frame (Sound me, BarkFilter thee, long frame) { autoMatrix pv = Sound_to_spectralpower (me); long nf = pv -> nx; autoNUMvector z (1, nf); for (long j = 1; j <= nf; j++) { z[j] = HZTOBARK (pv -> x1 + (j - 1) * pv -> dx); } for (long i = 1; i <= thy ny; i++) { double p = 0; double z0 = thy y1 + (i - 1) * thy dy; double *pow = pv -> z[1]; // TODO ?? for (long j = 1; j <= nf; j++) { // Sekey & Hanson filter is defined in the power domain. // We therefore multiply the power with a (and not a^2). // integral (F(z),z=0..25) = 1.58/9 double a = NUMsekeyhansonfilter_amplitude (z0, z[j]); p += a * pow[j] ; } thy z[i][frame] = p; } return 1; } BarkFilter Sound_to_BarkFilter (Sound me, double analysisWidth, double dt, double f1_bark, double fmax_bark, double df_bark) { try { double t1, nyquist = 0.5 / my dx, samplingFrequency = 2 * nyquist; double windowDuration = 2 * analysisWidth; /* gaussian window */ double zmax = NUMhertzToBark2 (nyquist); double fmin_bark = 0; long nt, frameErrorCount = 0; // Check defaults. if (f1_bark <= 0) { f1_bark = 1; } if (fmax_bark <= 0) { fmax_bark = zmax; } if (df_bark <= 0) { df_bark = 1; } fmax_bark = MIN (fmax_bark, zmax); long nf = lround ( (fmax_bark - f1_bark) / df_bark); if (nf <= 0) { Melder_throw (U"The combination of filter parameters is not valid."); } Sampled_shortTermAnalysis (me, windowDuration, dt, & nt, & t1); autoSound sframe = Sound_createSimple (1, windowDuration, samplingFrequency); autoSound window = Sound_createGaussian (windowDuration, samplingFrequency); autoBarkFilter thee = BarkFilter_create (my xmin, my xmax, nt, dt, t1, fmin_bark, fmax_bark, nf, df_bark, f1_bark); autoMelderProgress progess (U"BarkFilter analysis"); for (long i = 1; i <= nt; i++) { double t = Sampled_indexToX (thee.peek(), i); Sound_into_Sound (me, sframe.peek(), t - windowDuration / 2); Sounds_multiply (sframe.peek(), window.peek()); if (! Sound_into_BarkFilter_frame (sframe.peek(), thee.peek(), i)) { frameErrorCount++; } if ( (i % 10) == 1) { Melder_progress ( (double) i / nt, U"BarkFilter analysis: frame ", i, U" from ", nt, U"."); } } if (frameErrorCount > 0) { Melder_warning (U"Analysis results of ", frameErrorCount, U" frame(s) out of ", nt, U" will be suspect."); } double ref = FilterBank_DBREF * gaussian_window_squared_correction (window -> nx); NUMdmatrix_to_dBs (thy z, 1, thy ny, 1, thy nx, ref, FilterBank_DBFAC, FilterBank_DBFLOOR); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no BarkFilter created."); } } static int Sound_into_MelFilter_frame (Sound me, MelFilter thee, long frame) { autoMatrix pv = Sound_to_spectralpower (me); double z1 = pv -> x1; double dz = pv -> dx; long nf = pv -> nx; double df = thy dy; for (long i = 1; i <= thy ny; i++) { double p = 0; double fc_mel = thy y1 + (i - 1) * df; double fc_hz = MELTOHZ (fc_mel); double fl_hz = MELTOHZ (fc_mel - df); double fh_hz = MELTOHZ (fc_mel + df); double *pow = pv -> z[1]; for (long j = 1; j <= nf; j++) { // Bin with a triangular filter the power (=amplitude-squared) double f = z1 + (j - 1) * dz; double a = NUMtriangularfilter_amplitude (fl_hz, fc_hz, fh_hz, f); p += a * pow[j]; } thy z[i][frame] = p; } return 1; } MelFilter Sound_to_MelFilter (Sound me, double analysisWidth, double dt, double f1_mel, double fmax_mel, double df_mel) { try { double t1, samplingFrequency = 1 / my dx, nyquist = 0.5 * samplingFrequency; double windowDuration = 2 * analysisWidth; /* gaussian window */ double fmin_mel = 0; double fbottom = HZTOMEL (100.0), fceiling = HZTOMEL (nyquist); long nt, frameErrorCount = 0; // Check defaults. if (fmax_mel <= 0 || fmax_mel > fceiling) { fmax_mel = fceiling; } if (fmax_mel <= f1_mel) { f1_mel = fbottom; fmax_mel = fceiling; } if (f1_mel <= 0) { f1_mel = fbottom; } if (df_mel <= 0) { df_mel = 100.0; } // Determine the number of filters. long nf = lround ((fmax_mel - f1_mel) / df_mel); fmax_mel = f1_mel + nf * df_mel; Sampled_shortTermAnalysis (me, windowDuration, dt, &nt, &t1); autoSound sframe = Sound_createSimple (1, windowDuration, samplingFrequency); autoSound window = Sound_createGaussian (windowDuration, samplingFrequency); autoMelFilter thee = MelFilter_create (my xmin, my xmax, nt, dt, t1, fmin_mel, fmax_mel, nf, df_mel, f1_mel); autoMelderProgress progress (U"MelFilters analysis"); for (long i = 1; i <= nt; i++) { double t = Sampled_indexToX (thee.peek(), i); Sound_into_Sound (me, sframe.peek(), t - windowDuration / 2); Sounds_multiply (sframe.peek(), window.peek()); if (! Sound_into_MelFilter_frame (sframe.peek(), thee.peek(), i)) { frameErrorCount++; } if ( (i % 10) == 1) { Melder_progress ((double) i / nt, U"Frame ", i, U" out of ", nt, U"."); } } if (frameErrorCount) { Melder_warning (U"Analysis results of ", frameErrorCount, U" frame(s) out of ", nt, U" will be suspect."); } // Window correction. double ref = FilterBank_DBREF * gaussian_window_squared_correction (window -> nx); NUMdmatrix_to_dBs (thy z, 1, thy ny, 1, thy nx, ref, FilterBank_DBFAC, FilterBank_DBFLOOR); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no MelFilter created."); } } /* Analog formant filter response : H(f) = i f B / (f1^2 - f^2 + i f B) */ static int Sound_into_FormantFilter_frame (Sound me, FormantFilter thee, long frame, double bw) { Melder_assert (bw > 0); autoMatrix pv = Sound_to_spectralpower (me); double z1 = pv -> x1; double dz = pv -> dx; long nf = pv -> nx; for (long i = 1; i <= thy ny; i++) { double p = 0; double fc = thy y1 + (i - 1) * thy dy; double *pow = pv -> z[1]; for (long j = 1; j <= nf; j++) { // H(f) = ifB / (fc^2 - f^2 + ifB) // H(f)| = fB / sqrt ((fc^2 - f^2)^2 + f^2B^2) //|H(f)|^2 = f^2B^2 / ((fc^2 - f^2)^2 + f^2B^2) // = 1 / (((fc^2 - f^2) /fB)^2 + 1) double f = z1 + (j - 1) * dz; double a = NUMformantfilter_amplitude (fc, bw, f); p += a * pow[j]; } thy z[i][frame] = p; } return 1; } FormantFilter Sound_to_FormantFilter (Sound me, double analysisWidth, double dt, double f1_hz, double fmax_hz, double df_hz, double relative_bw, double minimumPitch, double maximumPitch) { try { double floor = 80, ceiling = 600; if (minimumPitch >= maximumPitch) { minimumPitch = floor; maximumPitch = ceiling; } if (minimumPitch <= 0) { minimumPitch = floor; } if (maximumPitch <= 0) { maximumPitch = ceiling; } autoPitch thee = Sound_to_Pitch (me, dt, minimumPitch, maximumPitch); autoFormantFilter ff = Sound_and_Pitch_to_FormantFilter (me, thee.peek(), analysisWidth, dt, f1_hz, fmax_hz, df_hz, relative_bw); return ff.transfer(); } catch (MelderError) { Melder_throw (me, U": no FormantFilter created."); } } FormantFilter Sound_and_Pitch_to_FormantFilter (Sound me, Pitch thee, double analysisWidth, double dt, double f1_hz, double fmax_hz, double df_hz, double relative_bw) { try { double t1, windowDuration = 2 * analysisWidth; /* gaussian window */ double nyquist = 0.5 / my dx, samplingFrequency = 2 * nyquist, fmin_hz = 0; long nt, f0_undefined = 0; if (my xmin > thy xmin || my xmax > thy xmax) Melder_throw (U"The domain of the Sound is not included in the domain of the Pitch."); double f0_median = Pitch_getQuantile (thee, thy xmin, thy xmax, 0.5, kPitch_unit_HERTZ); if (f0_median == NUMundefined || f0_median == 0) { f0_median = 100; Melder_warning (U"Pitch values undefined. Bandwith fixed to 100 Hz. "); } if (f1_hz <= 0) { f1_hz = 100; } if (fmax_hz <= 0) { fmax_hz = nyquist; } if (df_hz <= 0) { df_hz = f0_median / 2; } if (relative_bw <= 0) { relative_bw = 1.1; } fmax_hz = MIN (fmax_hz, nyquist); long nf = lround ( (fmax_hz - f1_hz) / df_hz); Sampled_shortTermAnalysis (me, windowDuration, dt, &nt, &t1); autoFormantFilter him = FormantFilter_create (my xmin, my xmax, nt, dt, t1, fmin_hz, fmax_hz, nf, df_hz, f1_hz); // Temporary objects autoSound sframe = Sound_createSimple (1, windowDuration, samplingFrequency); autoSound window = Sound_createGaussian (windowDuration, samplingFrequency); autoMelderProgress progress (U"Sound & Pitch: To FormantFilter"); for (long i = 1; i <= nt; i++) { double t = Sampled_indexToX (him.peek(), i); double b, f0 = Pitch_getValueAtTime (thee, t, kPitch_unit_HERTZ, 0); if (f0 == NUMundefined || f0 == 0) { f0_undefined++; f0 = f0_median; } b = relative_bw * f0; Sound_into_Sound (me, sframe.peek(), t - windowDuration / 2); Sounds_multiply (sframe.peek(), window.peek()); Sound_into_FormantFilter_frame (sframe.peek(), him.peek(), i, b); if ( (i % 10) == 1) { Melder_progress ( (double) i / nt, U"Frame ", i, U" out of ", nt, U"."); } } double ref = FilterBank_DBREF * gaussian_window_squared_correction (window -> nx); NUMdmatrix_to_dBs (his z, 1, his ny, 1, his nx, ref, FilterBank_DBFAC, FilterBank_DBFLOOR); return him.transfer(); } catch (MelderError) { Melder_throw (U"FormantFilter not created from Pitch & FormantFilter."); } } Sound FilterBank_as_Sound (FilterBank me) { try { autoSound thee = Sound_create (my ny, my xmin, my xmax, my nx, my dx, my x1); for (long i = 1; i <= my ny; i++) { for (long j = 1; j <= my nx; j++) thy z[i][j] = my z[i][j]; } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no Sound created."); } } Sound FilterBanks_crossCorrelate (FilterBank me, FilterBank thee, enum kSounds_convolve_scaling scaling, enum kSounds_convolve_signalOutsideTimeDomain signalOutsideTimeDomain) { try { autoSound cc = Sounds_crossCorrelate ((Sound) me, (Sound) thee, scaling, signalOutsideTimeDomain); return cc.transfer(); } catch (MelderError) { Melder_throw (me, U" and ", thee, U" not cross-correlated."); } } Sound FilterBanks_convolve (FilterBank me, FilterBank thee, enum kSounds_convolve_scaling scaling, enum kSounds_convolve_signalOutsideTimeDomain signalOutsideTimeDomain) { try { autoSound cc = Sounds_convolve ((Sound) me, (Sound) thee, scaling, signalOutsideTimeDomain); return cc.transfer(); } catch (MelderError) { Melder_throw (me, U" and ", thee, U" not convolved."); } } #undef MAX #undef MIN /* End of file Filterbank.cpp */ praat-6.0.04/dwtools/FilterBank.h000066400000000000000000000160571261542461700166160ustar00rootroot00000000000000#ifndef _FilterBank_h_ #define _FilterBank_h_ /* FilterBank.h * * Copyright (C) 1993-2011, 2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20010609 djmw 20020813 GPL header djmw 20040702 Corrected MELTOBARK formula. djmw 20110306 Latest modification. */ #include "TableOfReal.h" #include "Spectrum.h" #include "MFCC.h" #include "Intensity.h" #include "PCA.h" #include "Pitch.h" #include "Spectrogram_extensions.h" #define HZTOBARK(x) NUMhertzToBark2(x) #define HZTOMEL(x) NUMhertzToMel2(x) #define BARKTOHZ(x) NUMbarkToHertz2(x) #define MELTOHZ(x) NUMmelToHertz2(x) #define BARKTOMEL(x) HZTOMEL(BARKTOHZ(x)) #define MELTOBARK(x) HZTOBARK(MELTOHZ(x)) #define FilterBank_DBREF 4e-10 #define FilterBank_DBFAC 1 #define FilterBank_DBFLOOR -20 #define FilterBank_HERTZ 1 #define FilterBank_BARK 2 #define FilterBank_MEL 3 // FilterBank, BarkFilter, MelFilter are deprecated as of october 2014. // New types are BandFilterSpectrogram, BarkSpectrogram and MelSpectrogram. // This interface is maintained because older scripts still have to work. Thing_define (FilterBank, Matrix) { virtual int v_getFrequencyScale () { return FilterBank_HERTZ; } virtual const char32 *v_getFrequencyUnit () { return U"Hz"; } // compatibility with BandFilterSpectrogram }; Thing_define (BarkFilter, FilterBank) { int v_getFrequencyScale () override { return FilterBank_BARK; } const char32 *v_getFrequencyUnit () override { return U"bark"; } }; /* Interpretation: xmin, xmax, x1, dx, nx like Sampled. ymin, ymax lowest and highest frequencies in Barks. y1 mid of first filter (bark). dy distance between filters (bark). ny the number of filters. */ double FilterBank_getFrequencyInHertz (I, double f, int scale_from); double FilterBank_getFrequencyInBark (I, double f, int scale_from); double FilterBank_getFrequencyInMel (I, double f, int scale_from); int FilterBank_getFrequencyScale (I); void FilterBank_drawFrequencyScales (I, Graphics g, int horizontalScale, double xmin, double xmax, int verticalScale, double ymin, double ymax, int garnish); void BarkFilter_drawSekeyHansonFilterFunctions (BarkFilter me, Graphics g, int freqScale, int fromFilter, int toFilter, double zmin, double zmax, int dbScale, double ymin, double ymax, int garnish); void FilterBank_drawTimeSlice (I, Graphics g, double t, double fmin, double fmax, double min, double max, const char32 *xlabel, int garnish); void FilterBank_paint (FilterBank me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum, int garnish); BarkFilter BarkFilter_create (double tmin, double tmax, long nt, double dt, double t1, double fmin, double fmax, long nf, double df, double f1); BarkFilter Matrix_to_BarkFilter (I); Thing_define (MelFilter, FilterBank) { int v_getFrequencyScale () override { return FilterBank_MEL; } const char32 *v_getFrequencyUnit () override { return U"mel"; } }; /* Interpretation: xmin, xmax, x1, dx, nx like Sampled. ymin, ymax lowest and highest frequencies in mels. y1 mid of first filter (mels). dy distance between filters (mel). ny the number of filters. */ MelFilter MelFilter_create (double tmin, double tmax, long nt, double dt, double t1, double fmin, double fmax, long nf, double df, double f1); MelFilter Matrix_to_MelFilter (I); void MelFilter_drawFilterFunctions (MelFilter me, Graphics g, int freqScale, int fromFilter, int toFilter, double zmin, double zmax, int dbScale, double ymin, double ymax, int garnish); MFCC MelFilter_to_MFCC (MelFilter me, long numberOfCoefficients); Thing_define (FormantFilter, FilterBank) { const char32 *v_getFrequencyUnit () override { return U"Hz"; } }; FormantFilter FormantFilter_create (double tmin, double tmax, long nt, double dt, double t1, double fmin, double fmax, long nf, double df, double f1); void FormantFilter_drawFilterFunctions (FormantFilter me, Graphics g, double bandwidth, int freqScale, int fromFilter, int toFilter, double zmin, double zmax, int dbScale, double ymin, double ymax, int garnish); FormantFilter Matrix_to_FormantFilter (I); void FilterBank_equalizeIntensities (I, double intensity_db); Matrix FilterBank_to_Matrix (I); /* Generieke ...Filters_to_Matrix */ Spectrum FormantFilter_to_Spectrum_slice (FormantFilter me, double t); /* Calculate amplitude spectrum at time t. power[i] = ref * 10 ^ (my z[i][t] / 10) spec->z[1][i] = sqrt(power[i]) = sqrt(ref) * 10 ^ (my z[i][t] / (2*10)) spec->z[2][i] = 0 */ Intensity FilterBank_to_Intensity (I); void FilterBank_and_PCA_drawComponent (I, PCA thee, Graphics g, long component, double dblevel, double frequencyOffset, double scale, double tmin, double tmax, double fmin, double fmax); // Convert old types to new types MelSpectrogram MelFilter_to_MelSpectrogram (MelFilter me); BarkSpectrogram BarkFilter_to_BarkSpectrogram (BarkFilter me); Spectrogram FormantFilter_to_Spectrogram (FormantFilter me); MFCC MelFilter_to_MFCC (MelFilter me, long numberOfCoefficients); /* Calculates the Cosine Transform of the filterbank values. */ MelFilter MFCC_to_MelFilter (MFCC me, long firstCoefficient, long lastCoefficient); /* Calculates the Inverse CT of cepstral coefficients. */ BarkFilter Sound_to_BarkFilter (Sound me, double analysisWidth, double dt, double f1_bark, double fmax_bark, double df_bark); /* Filtering with filters on a Bark scale as defined by Andrew Sekey & Brian Hanson (1984), "Improved 1-Bark bandwidth "auditory filter", Jasa 75, 1902-1904. Although not explicitely stated the filter function is defined in the power domain. 10 log F(z) = 15.8 + 7.5(z + 0.5) - 17.5 * sqrt(1 + (z + 0.5)^2) */ MelFilter Sound_to_MelFilter (Sound me, double analysisWidth, double dt, double f1_mel, double fmax_mel, double df_mel); FormantFilter Sound_to_FormantFilter (Sound me, double analysisWidth, double dt, double f1_hz, double fmax_hz, double df_hz, double relative_bw, double minimumPitch, double maximumPitch); FormantFilter Sound_and_Pitch_to_FormantFilter (Sound me, Pitch thee, double analysisWidth, double dt, double f1_hz, double fmax_hz, double df_hz, double relative_bw); Sound FilterBanks_crossCorrelate (FilterBank me, FilterBank thee, enum kSounds_convolve_scaling scaling, enum kSounds_convolve_signalOutsideTimeDomain signalOutsideTimeDomain); Sound FilterBanks_convolve (FilterBank me, FilterBank thee, enum kSounds_convolve_scaling scaling, enum kSounds_convolve_signalOutsideTimeDomain signalOutsideTimeDomain); #endif /* _FilterBank_h_ */ praat-6.0.04/dwtools/FormantGrid_extensions.cpp000066400000000000000000000064611261542461700216210ustar00rootroot00000000000000/* FormantGrid_extensions.c * * Copyright (C) 2009-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20090310 */ #include "FormantGrid_extensions.h" #include "NUM2.h" void FormantGrid_draw (FormantGrid me, Graphics g, double xmin, double xmax, double ymin, double ymax, bool bandwidths, bool garnish, const char32 *method) { Ordered tiers = bandwidths ? my bandwidths : my formants; if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (ymax <= ymin) { ymin = 0; ymax = bandwidths ? 1000 : 8000; } for (long iformant = 1; iformant <= my formants -> size; iformant++) { const char32 *quantity = 0; bool garnish2 = false; RealTier tier = (RealTier) tiers -> item[iformant]; if (iformant == my formants -> size) { quantity = U"Frequency (Hz)"; if (garnish) { garnish2 = true; } } RealTier_draw (tier, g, xmin, xmax, ymin, ymax, garnish2, method, quantity); } } static void FormantGrid_removeFormantTier (FormantGrid me, int position) { if (position < 1 || position > my formants -> size) { return; } Collection_removeItem (my formants, position); } static void FormantGrid_removeBandwidthTier (FormantGrid me, int position) { if (position < 1 || position > my bandwidths -> size) { return; } Collection_removeItem (my bandwidths, position); } void FormantGrid_removeFormantAndBandwidthTiers (FormantGrid me, int position) { FormantGrid_removeFormantTier (me, position); FormantGrid_removeBandwidthTier (me, position); } static void FormantGrid_addFormantTier (FormantGrid me, int position) { if (position > my formants -> size || position < 1) { position = my formants -> size + 1; } autoRealTier rt = RealTier_create (my xmin, my xmax); Ordered_addItemPos (my formants, rt.transfer(), position); } static void FormantGrid_addBandwidthTier (FormantGrid me, int position) { if (position > my bandwidths -> size || position < 1) { position = my bandwidths -> size + 1; } autoRealTier rt = RealTier_create (my xmin, my xmax); Ordered_addItemPos (my bandwidths, rt.transfer(), position); } void FormantGrid_addFormantAndBandwidthTiers (FormantGrid me, int position) { try { if (my formants -> size != my bandwidths -> size) { Melder_throw (U"Number of formants and bandwidths must be equal."); } if (position > my formants -> size || position < 1) { position = my formants -> size + 1; } FormantGrid_addFormantTier (me, position); try { FormantGrid_addBandwidthTier (me, position); } catch (MelderError) { FormantGrid_removeFormantTier (me, position); throw MelderError (); } } catch (MelderError) { Melder_throw (me, U": no ties added."); } } /* End of file FormantGrid_extensions.cpp */ praat-6.0.04/dwtools/FormantGrid_extensions.h000066400000000000000000000024421261542461700212610ustar00rootroot00000000000000#ifndef _FormantGrid_extensions_h_ #define _FormantGrid_extensions_h_ /* FormantGrid_extensions.h * * Copyright (C) 2009-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20090310 djmw 20110307 Latest modification */ #include "FormantGrid.h" #include "Graphics.h" void FormantGrid_draw (FormantGrid me, Graphics g, double xmin, double xmax, double ymin, double ymax, bool bandwidths, bool garnish, const char32 *method); void FormantGrid_removeFormantAndBandwidthTiers (FormantGrid me, int position); void FormantGrid_addFormantAndBandwidthTiers (FormantGrid me, int position); #endif /* _FormantGrid_extensions_h_ */ praat-6.0.04/dwtools/GaussianMixture.cpp000066400000000000000000001501231261542461700202510ustar00rootroot00000000000000/* GaussianMixture.cpp * * Copyright (C) 2011-2014, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20101021 Initial version */ #include "Distributions_and_Strings.h" #include "GaussianMixture.h" #include "NUMlapack.h" #include "NUMmachar.h" #include "NUM2.h" #include "Strings_extensions.h" #include "oo_DESTROY.h" #include "GaussianMixture_def.h" #include "oo_COPY.h" #include "GaussianMixture_def.h" #include "oo_EQUAL.h" #include "GaussianMixture_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "GaussianMixture_def.h" #include "oo_WRITE_TEXT.h" #include "GaussianMixture_def.h" #include "oo_READ_TEXT.h" #include "GaussianMixture_def.h" #include "oo_WRITE_BINARY.h" #include "GaussianMixture_def.h" #include "oo_READ_BINARY.h" #include "GaussianMixture_def.h" #include "oo_DESCRIPTION.h" #include "GaussianMixture_def.h" Thing_implement (GaussianMixture, Daata, 0); const char32 *GaussianMixture_criterionText (int criterion) { const char32 *criterionText[6] = { U"(1/n)*LLH", U"(1/n)*MML", U"(1/n)*BIC", U"(1/n)*AIC", U"(1/n)*AICc", U"(1/n)*CD_LLH" }; return criterion >= 0 && criterion < 7 ? criterionText[criterion] : U"(1/n)*ln(p)"; } void GaussianMixture_removeComponent (GaussianMixture me, long component); void GaussianMixture_removeComponent_bookkeeping (GaussianMixture me, long component, double **p, long numberOfRows); int GaussianMixture_and_TableOfReal_getProbabilities (GaussianMixture me, TableOfReal thee, long component, double **p); void GaussianMixture_and_TableOfReal_getGammas (GaussianMixture me, TableOfReal thee, double **gamma, double *lnp); double GaussianMixture_getLikelihoodValue (GaussianMixture me, double **p, long numberOfRows, int onlyLikelyhood); void GaussianMixture_updateProbabilityMarginals (GaussianMixture me, double **p, long numberOfRows); long GaussianMixture_getNumberOfParametersInComponent (GaussianMixture me); static void NUMdvector_scaleAsProbabilities (double *v, long n) { double sum = 0; for (long i = 1; i <= n; i++) { sum += v[i]; } if (sum > 0) for (long i = 1; i <= n; i++) { v[i] /= sum; } } static void GaussianMixture_updateCovariance (GaussianMixture me, long component, double **data, long numberOfRows, double **p) { if (component < 1 || component > my numberOfComponents) { return; } Covariance thee = (Covariance) my covariances -> item[component]; double mixprob = my mixingProbabilities[component]; double gsum = p[numberOfRows + 1][component]; // update the means for (long j = 1; j <= thy numberOfColumns; j++) { thy centroid[j] = 0; for (long i = 1; i <= numberOfRows; i++) { double gamma = mixprob * p[i][component] / p[i][my numberOfComponents + 1]; thy centroid[j] += gamma * data[i][j] ; // eq. Bishop 9.17 } thy centroid[j] /= gsum; } // update covariance with the new mean if (thy numberOfRows == 1) { // 1xn covariance for (long j = 1; j <= thy numberOfColumns; j++) { thy data[1][j] = 0; } for (long i = 1; i <= numberOfRows; i++) { double gamma = mixprob * p[i][component] / p[i][my numberOfComponents + 1]; double gdn = gamma / gsum; for (long j = 1; j <= thy numberOfColumns; j++) { double xj = thy centroid[j] - data[i][j]; thy data[1][j] += gdn * xj * xj; } } } else { // nxn covariance for (long j = 1; j <= thy numberOfRows; j++) for (long k = j; k <= thy numberOfColumns; k++) { thy data[k][j] = thy data[j][k] = 0; } for (long i = 1; i <= numberOfRows; i++) { double gamma = mixprob * p[i][component] / p[i][my numberOfComponents + 1]; double gdn = gamma / gsum; // we cannot divide by nk - 1, this could cause instability for (long j = 1; j <= thy numberOfColumns; j++) { double xj = thy centroid[j] - data[i][j]; for (long k = j; k <= thy numberOfColumns; k++) { thy data[j][k] = thy data[k][j] += gdn * xj * (thy centroid[k] - data[i][k]); } } } } thy numberOfObservations = my mixingProbabilities[component] * numberOfRows; } static void GaussianMixture_addCovarianceFraction (GaussianMixture me, long im, Covariance him, double fraction) { if (im < 1 || im > my numberOfComponents || fraction == 0) { return; } Covariance thee = (Covariance) my covariances -> item[im]; // prevent instability: add lambda fraction of global covariances if (thy numberOfRows == 1) { for (long j = 1; j <= thy numberOfColumns; j++) { thy data[1][j] += fraction * his data[j][j]; } } else { for (long j = 1; j <= thy numberOfColumns; j++) { for (long k = j; k <= thy numberOfColumns; k++) { thy data[k][j] = thy data[j][k] += fraction * his data[j][k]; } } } } void structGaussianMixture :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Number of components: ", numberOfComponents); MelderInfo_writeLine (U"Dimension of component: ", dimension); MelderInfo_writeLine (U"Mixing probabilities:"); for (long im = 1; im <= numberOfComponents; im++) { MelderInfo_writeLine (U" ", im, U": p = ", mixingProbabilities[im], U" Name = \"", Thing_getName ( (Thing) covariances -> item[im]), U"\""); } } static void GaussianMixture_setLabelsFromTableOfReal (GaussianMixture me, TableOfReal thee) { for (long im = 1; im <= my numberOfComponents; im++) { Covariance cov = (Covariance) my covariances -> item[im]; for (long j = 1; j <= my dimension; j++) { TableOfReal_setColumnLabel (cov, j, thy columnLabels[j]); } } } // only from big to reduced or same static void Covariance_into_Covariance (Covariance me, Covariance thee) { if (my numberOfColumns != thy numberOfColumns) { Melder_throw (U"Dimensions must be equal."); } SSCP_unExpand (thee); // to its original state thy numberOfObservations = my numberOfObservations; // copy centroid & column labels for (long ic = 1; ic <= my numberOfColumns; ic++) { thy centroid[ic] = my centroid[ic]; } NUMstrings_copyElements (my columnLabels, thy columnLabels, 1, thy numberOfColumns); // Are the matrix sizes equal if (my numberOfRows == thy numberOfRows) { NUMstrings_copyElements (my rowLabels, thy rowLabels, 1, thy numberOfRows); NUMmatrix_copyElements (my data, thy data, 1, my numberOfRows, 1, my numberOfColumns); return; } else { for (long ir = 1; ir <= my numberOfRows; ir++) { for (long ic = ir; ic <= my numberOfColumns; ic++) { long dij = ic - ir; if (dij < thy numberOfRows) { thy data[dij + 1][ic] = my data[ir][ic]; } } } } } static void GaussianMixture_setDefaultMixtureNames (GaussianMixture me) { for (long im = 1; im <= my numberOfComponents; im++) { Covariance cov = (Covariance) my covariances -> item[im]; Thing_setName (cov, Melder_cat (U"m", im)); } } autoGaussianMixture GaussianMixture_create (long numberOfComponents, long dimension, long storage) { try { autoGaussianMixture me = Thing_new (GaussianMixture); my numberOfComponents = numberOfComponents; my dimension = dimension; my mixingProbabilities = NUMvector (1, numberOfComponents); my covariances = Ordered_create (); for (long im = 1; im <= numberOfComponents; im++) { autoCovariance cov = Covariance_create_reduceStorage (dimension, storage); Ordered_addItemPos (my covariances, cov.transfer(), im); } for (long im = 1; im <= numberOfComponents; im++) { my mixingProbabilities[im] = 1.0 / numberOfComponents; } GaussianMixture_setDefaultMixtureNames (me.peek()); return me; } catch (MelderError) { Melder_throw (U"GaussianMixture not created."); } } /* c is double vector 1..dimension !!!!!! */ int GaussianMixture_generateOneVector (GaussianMixture me, double *c, char32 **covname, double *buf) { try { double p = NUMrandomUniform (0, 1); long im = NUMgetIndexFromProbability (my mixingProbabilities, my numberOfComponents, p); Covariance thee = (Covariance) my covariances -> item[im]; *covname = thy name; if (thy numberOfRows == 1) { // 1xn reduced form for (long i = 1; i <= my dimension; i++) { c[i] = NUMrandomGauss (thy centroid[i], sqrt (thy data[1][i])); } } else { // nxn if (thy pca == 0) { SSCP_expandPCA (thee); // on demand expanding } Covariance_and_PCA_generateOneVector (thee, thy pca, c, buf); } return 1; } catch (MelderError) { Melder_throw (me, U": vector not generated."); } } autoGaussianMixture TableOfReal_to_GaussianMixture_fromRowLabels (TableOfReal me, long storage) { try { autoStrings rowLabels = TableOfReal_extractRowLabels (me); autoDistributions dist = Strings_to_Distributions (rowLabels.peek()); long numberOfComponents = dist -> numberOfRows; autoGaussianMixture thee = GaussianMixture_create (numberOfComponents, my numberOfColumns, storage); GaussianMixture_setLabelsFromTableOfReal (thee.peek(), me); for (long i = 1; i <= numberOfComponents; i++) { autoTableOfReal tab = TableOfReal_extractRowsWhereLabel (me, kMelder_string_EQUAL_TO, dist->rowLabels[i]); autoCovariance cov = TableOfReal_to_Covariance (tab.peek()); Covariance_into_Covariance (cov.peek(), (Covariance) thy covariances -> item[i]); Thing_setName ( (Thing) thy covariances -> item[i], dist -> rowLabels[i]); } for (long im = 1; im <= numberOfComponents; im++) { thy mixingProbabilities[im] = dist -> data[im][1] / my numberOfRows; } return thee; } catch (MelderError) { Melder_throw (me, U": no GaussianMixture created."); } } autoCovariance GaussianMixture_to_Covariance_between (GaussianMixture me) { try { autoCovariance thee = Covariance_create (my dimension); // First the new centroid, based on the mixture centroids double nobs_total = 0; for (long i = 1; i <= my numberOfComponents; i++) { Covariance him = (Covariance) my covariances -> item[i]; double nobs = his numberOfObservations; // the weighting factor for (long ic = 1; ic <= my dimension; ic++) { thy centroid[ic] += nobs * his centroid[ic]; } nobs_total += nobs; } for (long ic = 1; ic <= my dimension; ic++) { thy centroid[ic] /= nobs_total; } Covariance cov = (Covariance) my covariances -> item[1]; for (long i = 1; i <= thy numberOfColumns; i++) { if (cov -> columnLabels[i]) { TableOfReal_setColumnLabel (thee.peek(), i, cov -> columnLabels[i]); TableOfReal_setRowLabel (thee.peek(), i, cov -> columnLabels[i]); // if diagonal ! } } // Between covariance, scale by the number of observations for (long i = 1; i <= my numberOfComponents; i++) { Covariance him = (Covariance) my covariances -> item[i]; double nobs = his numberOfObservations - 1; // we loose 1 degree of freedom for (long ir = 1; ir <= my dimension; ir++) { double dir = his centroid[ir] - thy centroid[ir]; for (long ic = ir; ic <= my dimension; ic++) { double dic = his centroid[ic] - thy centroid[ic]; thy data[ir][ic] = thy data[ic][ir] += nobs * dir * dic; } } } // Scale back for (long ir = 1; ir <= my dimension; ir++) { for (long ic = ir; ic <= my dimension; ic++) { thy data[ir][ic] = thy data[ic][ir] /= nobs_total; } } thy numberOfObservations = nobs_total; return thee; } catch (MelderError) { Melder_throw (me, U": no Covariance (between) created."); } } autoCovariance GaussianMixture_to_Covariance_within (GaussianMixture me) { try { autoCovariance thee = Covariance_create (my dimension); for (long i = 1; i <= my numberOfComponents; i++) { double p = my mixingProbabilities[i]; Covariance him = (Covariance) my covariances -> item[i]; if (his numberOfRows == 1) { for (long ic = 1; ic <= my dimension; ic++) { thy data[ic][ic] += p * his data[1][ic]; } } else { for (long ir = 1; ir <= my dimension; ir++) { for (long ic = ir; ic <= my dimension; ic++) { thy data[ir][ic] = thy data[ic][ir] += p * his data[ir][ic]; } } } thy numberOfObservations += his numberOfObservations - 1; // we loose a degree of freedom? } // Leave centroid at 0 so we can add the within and between covariance nicely // Copy row labels from columns, because covar might be diagonal TableOfReal_copyLabels ((Covariance) my covariances -> item[1], thee.peek(), -1, 1); return thee; } catch (MelderError) { Melder_throw (me, U": no Covariance (within) created."); } } autoCovariance GaussianMixture_to_Covariance_total (GaussianMixture me) { try { autoCovariance thee = GaussianMixture_to_Covariance_between (me); autoCovariance within = GaussianMixture_to_Covariance_within (me); for (long ir = 1; ir <= my dimension; ir++) { for (long ic = ir; ic <= my dimension; ic++) { thy data[ir][ic] = thy data[ic][ir] += within -> data[ir][ic]; } } return thee; } catch (MelderError) { Melder_throw (me, U": no Covariance (total) created."); } } autoCovariance GaussianMixture_extractComponent (GaussianMixture me, long component) { try { if (component < 1 || component > my numberOfComponents) { Melder_throw (U"Illegal component."); } autoCovariance thee = Data_copy ((Covariance) my covariances -> item[component]); return thee; } catch (MelderError) { Melder_throw (me, U": no component extracted."); } } autoTableOfReal GaussianMixture_extractMixingProbabilities (GaussianMixture me) { try { autoTableOfReal thee = TableOfReal_create (my numberOfComponents, 2); TableOfReal_setColumnLabel (thee.peek(), 1, U"p"); TableOfReal_setColumnLabel (thee.peek(), 2, U"n"); for (long im = 1; im <= my numberOfComponents; im++) { Covariance cov = (Covariance) my covariances -> item[im]; thy data[im][1] = my mixingProbabilities[im]; thy data[im][2] = cov -> numberOfObservations; TableOfReal_setRowLabel (thee.peek(), im, Thing_getName (cov)); } return thee; } catch (MelderError) { Melder_throw (me, U": no mixing probabilities extracted."); } } autoTableOfReal GaussianMixture_extractCentroids (GaussianMixture me) { try { autoTableOfReal thee = TableOfReal_create (my numberOfComponents, my dimension); for (long im = 1; im <= my numberOfComponents; im++) { Covariance cov = (Covariance) my covariances -> item[im]; if (im == 1) { for (long j = 1; j <= my dimension; j++) { TableOfReal_setColumnLabel (thee.peek(), j, cov -> columnLabels[j]); } } TableOfReal_setRowLabel (thee.peek(), im, Thing_getName (cov)); for (long j = 1; j <= my dimension; j++) { thy data[im][j] = cov -> centroid[j]; } } return thee; } catch (MelderError) { Melder_throw (me, U": no centroid extracted."); } } autoPCA GaussianMixture_to_PCA (GaussianMixture me) { try { autoCovariance him = GaussianMixture_to_Covariance_total (me); autoPCA thee = SSCP_to_PCA (him.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": no PCA calculated."); } } void GaussianMixture_getIntervalsAlongDirections (GaussianMixture me, long d1, long d2, double nsigmas, double *xmin, double *xmax, double *ymin, double *ymax) { *xmin = *xmax = *ymin = *ymax = NUMundefined; if (d1 < 1 || d1 > my dimension || d2 < 1 || d2 > my dimension) { Melder_throw (U"Incorrect directions."); } autoSSCPs sscps = SSCPs_extractTwoDimensions ((SSCPs) my covariances, d1, d2); SSCPs_getEllipsesBoundingBoxCoordinates (sscps.peek(), -nsigmas, 0, xmin, xmax, ymin, ymax); } void GaussianMixture_getIntervalAlongDirection (GaussianMixture me, long d, double nsigmas, double *xmin, double *xmax) { double ymin, ymax; GaussianMixture_getIntervalsAlongDirections (me, d, d, nsigmas, xmin, xmax, &ymin, &ymax); } void GaussianMixture_and_PCA_getIntervalsAlongDirections (GaussianMixture me, PCA thee, long d1, long d2, double nsigmas, double *xmin, double *xmax, double *ymin, double *ymax) { *xmin = *xmax = *ymin = *ymax = NUMundefined; if (my dimension != thy dimension || d1 < 1 || d1 > my dimension || d2 < 1 || d2 > my dimension) { Melder_throw (U"Incorrect directions."); } autoSSCPs sscps = SSCPs_toTwoDimensions ( (SSCPs) my covariances, thy eigenvectors[d1], thy eigenvectors[d2]); SSCPs_getEllipsesBoundingBoxCoordinates (sscps.peek(), -nsigmas, 0, xmin, xmax, ymin, ymax); } void GaussianMixture_and_PCA_getIntervalAlongDirection (GaussianMixture me, PCA thee, long d, double nsigmas, double *xmin, double *xmax) { double ymin, ymax; GaussianMixture_and_PCA_getIntervalsAlongDirections (me, thee, d, d, nsigmas, xmin, xmax, &ymin, &ymax); } void GaussianMixture_and_PCA_drawMarginalPdf (GaussianMixture me, PCA thee, Graphics g, long d, double xmin, double xmax, double ymin, double ymax, long npoints, long nbins, int garnish) { if (my dimension != thy dimension || d < 1 || d > my dimension) { Melder_warning (U"Dimensions don't agree."); return; } if (npoints <= 1) { npoints = 1000; } autoNUMvector p (1, npoints); double nsigmas = 2; if (xmax <= xmin) { GaussianMixture_and_PCA_getIntervalAlongDirection (me, thee, d, nsigmas, &xmin, &xmax); } double pmax = 0, dx = (xmax - xmin) / npoints, x1 = xmin + 0.5 * dx; double scalef = nbins <= 0 ? 1 : 1; // TODO for (long i = 1; i <= npoints; i++) { double x = x1 + (i - 1) * dx; p[i] = scalef * GaussianMixture_getMarginalProbabilityAtPosition (me, thy eigenvectors[d], x); if (p[i] > pmax) { pmax = p[i]; } } if (ymin >= ymax) { ymin = 0; ymax = pmax; } Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_function (g, p.peek(), 1, npoints, x1, xmax - 0.5 * dx); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_markBottom (g, xmin, true, true, false, nullptr); Graphics_markBottom (g, xmax, true, true, false, nullptr); Graphics_markLeft (g, ymin, true, true, false, nullptr); Graphics_markLeft (g, ymax, true, true, false, nullptr); } } void GaussianMixture_drawMarginalPdf (GaussianMixture me, Graphics g, long d, double xmin, double xmax, double ymin, double ymax, long npoints, long nbins, int garnish) { if (d < 1 || d > my dimension) { Melder_warning (U"Dimension doesn't agree."); return; } if (npoints <= 1) { npoints = 1000; } autoNUMvector p (1, npoints); autoNUMvector v (1, my dimension); double nsigmas = 2; if (xmax <= xmin) { GaussianMixture_getIntervalAlongDirection (me, d, nsigmas, &xmin, &xmax); } double pmax = 0, dx = (xmax - xmin) / (npoints - 1); double scalef = nbins <= 0 ? 1 : 1; // TODO for (long i = 1; i <= npoints; i++) { double x = xmin + (i - 1) * dx; for (long k = 1; k <= my dimension; k++) { v[k] = k == d ? 1 : 0; } p[i] = scalef * GaussianMixture_getMarginalProbabilityAtPosition (me, v.peek(), x); if (p[i] > pmax) { pmax = p[i]; } } if (ymin >= ymax) { ymin = 0; ymax = pmax; } Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_function (g, p.peek(), 1, npoints, xmin, xmax); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_markBottom (g, xmin, true, true, false, nullptr); Graphics_markBottom (g, xmax, true, true, false, nullptr); Graphics_markLeft (g, ymin, true, true, false, nullptr); Graphics_markLeft (g, ymax, true, true, false, nullptr); } } void GaussianMixture_and_PCA_drawConcentrationEllipses (GaussianMixture me, PCA him, Graphics g, double scale, int confidence, char32 *label, long d1, long d2, double xmin, double xmax, double ymin, double ymax, int fontSize, int garnish) { if (my dimension != his dimension) { Melder_warning (U"Dimensions don't agree."); return; } int d1_inverted = 0, d2_inverted = 0; if (d1 < 0) { d1 = labs (d1); Eigen_invertEigenvector (him, d1); d1_inverted = 1; } if (d2 < 0) { d2 = labs (d2); Eigen_invertEigenvector (him, d2); d2_inverted = 1; } autoSSCPs thee = SSCPs_toTwoDimensions ( (SSCPs) my covariances, his eigenvectors[d1], his eigenvectors[d2]); if (d1_inverted) { Eigen_invertEigenvector (him, d1); } if (d2_inverted) { Eigen_invertEigenvector (him, d2); } SSCPs_drawConcentrationEllipses (thee.peek(), g, -scale, confidence, label, 1, 2, xmin, xmax, ymin, ymax, fontSize, 0); if (garnish) { char32 llabel[40]; Graphics_drawInnerBox (g); Graphics_marksLeft (g, 2, true, true, false); Melder_sprint (llabel,40, U"pc ", d2); Graphics_textLeft (g, true, llabel); Graphics_marksBottom (g, 2, true, true, false); Melder_sprint (llabel,40, U"pc ", d1); Graphics_textBottom (g, true, llabel); } } void GaussianMixture_drawConcentrationEllipses (GaussianMixture me, Graphics g, double scale, int confidence, char32 *label, int pcaDirections, long d1, long d2, double xmin, double xmax, double ymin, double ymax, int fontSize, int garnish) { if (d1 == 0 && d2 == 0) { d1 = 1; d2 = 2; } if (labs (d1) > my dimension || labs (d2) > my dimension) { return; } if (! pcaDirections) { SSCPs_drawConcentrationEllipses ( (SSCPs) my covariances, g, -scale, confidence, label, labs (d1), labs (d2), xmin, xmax, ymin, ymax, fontSize, garnish); return; } autoPCA him = GaussianMixture_to_PCA (me); GaussianMixture_and_PCA_drawConcentrationEllipses (me, him.peek(), g, scale, confidence, label, d1, d2, xmin, xmax, ymin, ymax, fontSize, garnish); } void GaussianMixture_initialGuess (GaussianMixture me, TableOfReal thee, double nSigmas, double ru_range) { try { autoCovariance cov_t = TableOfReal_to_Covariance (thee); // assume equal probabilities for mixture // assume equal covariance matrices // spread centroids on an ellips in pc1-pc2 plane? if (my dimension == 1) { double dm = 2 * sqrt (cov_t -> data[1][1]) / my numberOfComponents; double m1 = cov_t -> centroid[1] - dm; for (long im = 1; im <= my numberOfComponents; im++) { Covariance covi = (Covariance) my covariances -> item[im]; covi -> centroid[1] = m1; covi -> data[1][1] = dm * dm; m1 += dm; covi -> numberOfObservations = thy numberOfRows / my numberOfComponents; } } else { autoPCA pca = SSCP_to_PCA (cov_t.peek()); autoSSCP s2d = SSCP_toTwoDimensions (cov_t.peek(), pca -> eigenvectors[1], pca -> eigenvectors[2]); autoConfiguration means2d = Configuration_create (my numberOfComponents, 2); double a, b, cs, sn; NUMeigencmp22 (s2d -> data[1][1], s2d -> data[1][2], s2d -> data[2][2], &a, &b, &cs, &sn); a = nSigmas * sqrt (a); b = nSigmas * sqrt (b); double angle = 0, angle_inc = NUM2pi / my numberOfComponents; for (long im = 1; im <= my numberOfComponents; im++, angle += angle_inc) { double xc = a * (1.0 + NUMrandomUniform (-ru_range, ru_range)) * cos (angle); double yc = b * (1.0 + NUMrandomUniform (-ru_range, ru_range)) * sin (angle); means2d -> data[im][1] = s2d -> centroid[1] + xc * cs - yc * sn; means2d -> data[im][2] = s2d -> centroid[2] + xc * sn + yc * cs; } // reconstruct the n-dimensional means from the 2-d from the eigenvectors autoTableOfReal means = PCA_and_Configuration_to_TableOfReal_reconstruct (pca.peek(), means2d.peek()); for (long im = 1; im <= my numberOfComponents; im++) { Covariance covi = (Covariance) my covariances -> item[im]; for (long ic = 1; ic <= my dimension; ic++) { covi -> centroid[ic] = means -> data[im][ic]; } covi -> numberOfObservations = thy numberOfRows / my numberOfComponents; } // Trick: use the new means to get the between SSCP, // if there is only one component the cov_b will be zero! autoCovariance cov_b = GaussianMixture_to_Covariance_between (me); double var_t = SSCP_getTotalVariance (cov_t.peek()); double var_b = SSCP_getTotalVariance (cov_b.peek()); if (var_b >= var_t) { // we have chosen our initial values too far out double scale = 0.9 * sqrt (var_t / var_b); for (long im = 1; im <= my numberOfComponents; im++) { Covariance covi = (Covariance) my covariances -> item[im]; for (long ic = 1; ic <= my dimension; ic++) { covi -> centroid[ic] -= (1.0 - scale) * (covi -> centroid[ic] - cov_b -> centroid[ic]); } } cov_b = GaussianMixture_to_Covariance_between (me); } // Within variances are now (total - between) / numberOfComponents; for (long ir = 1; ir <= my dimension; ir++) { for (long ic = ir; ic <= my dimension; ic++) { double scalef = my numberOfComponents == 1 ? 1.0 : (var_b / var_t) / my numberOfComponents; cov_t -> data[ic][ir] = cov_t -> data[ir][ic] *= scalef; } } // Copy them for (long im = 1; im <= my numberOfComponents; im++) { Covariance cov = (Covariance) my covariances -> item[im]; if (cov -> numberOfRows == 1) { for (long ic = 1; ic <= my dimension; ic++) { cov -> data[1][ic] = cov_t -> data[ic][ic]; } } else { for (long ir = 1; ir <= my dimension; ir++) { for (long ic = ir; ic <= my dimension; ic++) { cov -> data[ir][ic] = cov -> data[ic][ir] = cov_t -> data[ir][ic]; } } } } } } catch (MelderError) { Melder_throw (me, U" & ", thee, U": no initial guess possible."); } } autoClassificationTable GaussianMixture_and_TableOfReal_to_ClassificationTable (GaussianMixture me, TableOfReal thee) { try { autoClassificationTable him = ClassificationTable_create (thy numberOfRows, my numberOfComponents); for (long im = 1; im <= my numberOfComponents; im++) { Covariance cov = (Covariance) my covariances -> item[im]; SSCP_expandLowerCholesky (cov); TableOfReal_setColumnLabel (him.peek(), im, Thing_getName (cov)); } double ln2pid = -0.5 * my dimension * log (NUM2pi); autoNUMvector lnN (1, my numberOfComponents); for (long i = 1; i <= thy numberOfRows; i++) { double psum = 0.0; for (long im = 1; im <= my numberOfComponents; im++) { Covariance cov = (Covariance) my covariances -> item[im]; double dsq = NUMmahalanobisDistance_chi (cov -> lowerCholesky, thy data[i], cov -> centroid, cov -> numberOfRows, my dimension); lnN[im] = ln2pid - 0.5 * (cov -> lnd + dsq); psum += his data[i][im] = my mixingProbabilities[im] * exp (lnN[im]); } if (psum == 0) { // p's might be too small (underflow), make the largest equal to sfmin double lnmax = -INFINITY; long imm = 1; for (long im = 1; im <= my numberOfComponents; im++) { if (lnN[im] > lnmax) { lnmax = lnN[im]; } imm = im; } his data[i][imm] = NUMfpp -> sfmin; } // for (long im = 1; im <= my numberOfComponents; im++) { his data[i][im] /= psum; } TableOfReal_setRowLabel (him.peek(), i, thy rowLabels[i]); } return him; } catch (MelderError) { Melder_throw (U"No ClassificationTable created from GaussianMixture & TableOfReal."); } } void GaussianMixture_and_TableOfReal_getGammas (GaussianMixture me, TableOfReal thee, double **gamma, double *lnp) { try { for (long im = 1; im <= my numberOfComponents; im++) { Covariance cov = (Covariance) my covariances -> item[im]; SSCP_expandLowerCholesky (cov); } double *nk = gamma[thy numberOfRows + 1]; for (long im = 1; im <= my numberOfComponents; im++) { nk[im] = 0.0; } *lnp = 0.0; double ln2pid = - 0.5 * my dimension * log (NUM2pi); autoNUMvector lnN (1, my numberOfComponents); for (long i = 1; i <= thy numberOfRows; i++) { double rowsum = 0.0; for (long im = 1; im <= my numberOfComponents; im++) { Covariance cov = (Covariance) my covariances -> item[im]; double dsq = NUMmahalanobisDistance_chi (cov -> lowerCholesky, thy data[i], cov -> centroid, cov -> numberOfRows, my dimension); lnN[im] = ln2pid - 0.5 * (cov -> lnd + dsq); gamma[i][im] = my mixingProbabilities[im] * exp (lnN[im]); // eq. Bishop 9.16 rowsum += gamma[i][im]; } // If the gamma[i]'s are too small, their sum will be zero and the scaling will overflow if (rowsum == 0.0) { continue; // This is ok because gamma[i]'s will all be zero } // scale gamma and get log(likehood) (Bishop eq. 9.40) for (long im = 1; im <= my numberOfComponents; im++) { gamma[i][im] /= rowsum; // eq. Bishop 9.16 nk[im] += gamma[i][im]; // eq. Bishop 9.18 *lnp += gamma[i][im] * (log (my mixingProbabilities[im]) + lnN[im]); // eq. Bishop 9.40 } } } catch (MelderError) { Melder_throw (me, U" & ", thee, U": no gammas."); } } void GaussianMixture_splitComponent (GaussianMixture me, long component) { try { if (component < 1 || component > my numberOfComponents) { Melder_throw (U"Illegal component."); } Covariance thee = (Covariance) my covariances -> item[component]; // Always new PCA because we cannot be sure of data unchanged. SSCP_expandPCA (thee); autoCovariance cov1 = Data_copy ( (Covariance) thee); autoCovariance cov2 = Data_copy ( (Covariance) thee); SSCP_unExpandPCA (cov1.peek()); SSCP_unExpandPCA (cov2.peek()); // Eventually cov1 replaces component, cov2 at end autoNUMvector mixingProbabilities (1, my numberOfComponents + 1); for (long i = 1; i <= my numberOfComponents; i++) { mixingProbabilities[i] = my mixingProbabilities[i]; } double gamma = 0.5, lambda = 0.5, eta = 0.5, mu = 0.5; mixingProbabilities[component] = gamma * my mixingProbabilities[component]; mixingProbabilities[my numberOfComponents + 1] = (1.0 - gamma) * my mixingProbabilities[component]; double mp12 = mixingProbabilities[component] / mixingProbabilities[my numberOfComponents + 1]; double factor1 = (eta - eta * lambda * lambda - 1) / gamma + 1; double factor2 = (eta * lambda * lambda - eta - lambda * lambda) / (1.0 - gamma) + 1.0; double *ev = thy pca -> eigenvectors[1]; double d2 = thy pca -> eigenvalues[1]; for (long i = 1; i <= my dimension; i++) { cov1 -> centroid[i] -= (1 / sqrt (mp12)) * sqrt (d2) * mu * ev[i]; cov2 -> centroid[i] += sqrt (mp12) * sqrt (d2) * mu * ev[i]; if (thy numberOfRows == 1) { // diagonal cov1 -> data[1][i] = cov1 -> data [1][i] / mp12 + factor1 * d2; cov1 -> data[1][i] = cov2 -> data [i][i] * mp12 + factor2 * d2; } else { for (long j = i; j <= my dimension; j++) { cov1 -> data[j][i] = cov1 -> data[i][j] = cov1 -> data [i][j] / mp12 + factor1 * d2 * ev[i] * ev[j]; cov2 -> data[j][i] = cov2 -> data[i][j] = cov2 -> data [i][j] * mp12 + factor2 * d2 * ev[i] * ev[j]; } } } cov1 -> numberOfObservations *= gamma; cov2 -> numberOfObservations *= 1 - gamma; // Replace cov1 at component + add cov2. If something goes wrong we must be able to restore original! try { Thing_setName (cov2.peek(), Melder_cat (Thing_getName (cov2.peek()), U"-", my numberOfComponents + 1)); Collection_addItem (my covariances, cov2.transfer()); } catch (MelderError) { Melder_throw (me, U" cannot add new component."); } my covariances -> item[component] = cov1.transfer(); my numberOfComponents++; NUMvector_free (my mixingProbabilities, 1); my mixingProbabilities = mixingProbabilities.transfer(); } catch (MelderError) { Melder_throw (me, U": component ", component, U" cannot be split."); } } int GaussianMixture_and_TableOfReal_getProbabilities (GaussianMixture me, TableOfReal thee, long component, double **p) { try { double ln2pid = my dimension * log (NUM2pi); // Update only one component or all? long icb = 1, ice = my numberOfComponents; if (component > 0 && component <= my numberOfComponents) { icb = ice = component; } for (long ic = icb; ic <= ice; ic++) { Covariance him = (Covariance) my covariances -> item[ic]; SSCP_expandLowerCholesky (him); for (long i = 1; i <= thy numberOfRows; i++) { double dsq = NUMmahalanobisDistance_chi (his lowerCholesky, thy data[i], his centroid, his numberOfRows, my dimension); double prob = exp (- 0.5 * (ln2pid + his lnd + dsq)); prob = prob < 1e-300 ? 1e-300 : prob; // prevent p from being zero p[i][ic] = prob; } } GaussianMixture_updateProbabilityMarginals (me, p, thy numberOfRows); return 1; } catch (MelderError) { Melder_throw (me, U" & ", thee, U": no probabilies could be calculated."); } } void GaussianMixture_expandPCA (GaussianMixture me) { for (long im = 1; im <= my numberOfComponents; im++) { Covariance him = (Covariance) my covariances -> item[im]; if (his numberOfRows == 1) { Melder_throw (U"Nothing to expand."); } his pca = SSCP_to_PCA (him); } } void GaussianMixture_unExpandPCA (GaussianMixture me) { for (long im = 1; im <= my numberOfComponents; im++) { SSCP_unExpandPCA ((SSCP) my covariances -> item[im]); } } void GaussianMixture_and_TableOfReal_improveLikelihood (GaussianMixture me, TableOfReal thee, double delta_lnp, long maxNumberOfIterations, double lambda, int criterion) { try { const char32 *criterionText = GaussianMixture_criterionText (criterion); // The global covariance matrix is added with scaling coefficient lambda during updating the // mixture covariances to prevent numerical instabilities. autoCovariance covg = TableOfReal_to_Covariance (thee); autoNUMmatrix pp (1, thy numberOfRows + 1, 1, my numberOfComponents + 1); double *nk = pp[thy numberOfRows + 1]; // last row has the column marginals n(k) if (! GaussianMixture_and_TableOfReal_getProbabilities (me, thee, 0, pp.peek())) { Melder_throw (U"Iteration not started. Too many components?"); } double lnp = GaussianMixture_getLikelihoodValue (me, pp.peek(), thy numberOfRows, criterion); long iter = 0; autoMelderProgress progress (U"Improve likelihood..."); try { double lnp_prev, lnp_start = lnp / thy numberOfRows; do { // E-step: get responsabilities (gamma) with current parameters // See C. Bishop (2006), Pattern reconition and machine learning, Springer, page 439... lnp_prev = lnp; iter++; // M-step: 1. new means & covariances for (long im = 1; im <= my numberOfComponents; im++) { GaussianMixture_updateCovariance (me, im, thy data, thy numberOfRows, pp.peek()); GaussianMixture_addCovarianceFraction (me, im, covg.peek(), lambda); } // M-step: 2. new mixingProbabilities for (long im = 1; im <= my numberOfComponents; im++) { my mixingProbabilities[im] = nk[im] / thy numberOfRows; } if (! GaussianMixture_and_TableOfReal_getProbabilities (me, thee, 0, pp.peek())) { break; } lnp = GaussianMixture_getLikelihoodValue (me, pp.peek(), thy numberOfRows, criterion); Melder_progress ((double) iter / double (maxNumberOfIterations), criterionText, U": ", lnp / thy numberOfRows, U", L0: ", lnp_start); } while (fabs ( (lnp - lnp_prev) / lnp_prev) > delta_lnp && iter < maxNumberOfIterations); } catch (MelderError) { Melder_clearError (); } // During EM, covariances were underestimated by a factor of (n-1)/n. Correction now. for (long im = 1; im <= my numberOfComponents; im++) { Covariance cov = (Covariance) my covariances -> item[im]; if (cov -> numberOfObservations > 1.5) { if (cov -> numberOfRows == 1) { for (long j = 1; j <= thy numberOfColumns; j++) { cov -> data[1][j] *= cov -> numberOfObservations / (cov -> numberOfObservations - 1); } } else { for (long j = 1; j <= thy numberOfColumns; j++) for (long k = j; k <= thy numberOfColumns; k++) { cov -> data[j][k] = cov -> data[k][j] *= cov -> numberOfObservations / (cov -> numberOfObservations - 1.0); } } } } } catch (MelderError) { Melder_throw (me, U" & ", thee, U": likelihood cannot be improved."); } } long GaussianMixture_getNumberOfParametersInComponent (GaussianMixture me) { Covariance thee = (Covariance) my covariances -> item[1]; // if diagonal) d (means) + d (stdev) // else n + n(n+1)/2 return thy numberOfRows == 1 ? 2 * thy numberOfColumns : thy numberOfColumns * (thy numberOfColumns + 3) / 2; } void GaussianMixture_updateProbabilityMarginals (GaussianMixture me, double **p, long numberOfRows) { long nocp1 = my numberOfComponents + 1, norp1 = numberOfRows + 1; for (long ic = 1; ic <= my numberOfComponents; ic++) { p[norp1][ic] = 0; } for (long i = 1; i <= numberOfRows; i++) { double rowsum = 0; for (long ic = 1; ic <= my numberOfComponents; ic++) { rowsum += my mixingProbabilities[ic] * p[i][ic]; } p[i][nocp1] = rowsum; for (long ic = 1; ic <= my numberOfComponents; ic++) { p[norp1][ic] += my mixingProbabilities[ic] * p[i][ic] / p[i][nocp1]; } } } void GaussianMixture_removeComponent_bookkeeping (GaussianMixture me, long component, double **p, long numberOfRows) { // p is (NumberOfRows+1) by (numberOfComponents+1) ! for (long i = 1; i <= numberOfRows + 1; i++) { for (long ic = component; ic <= my numberOfComponents; ic++) { p[i][ic] = p[i][ic + 1]; } } GaussianMixture_updateProbabilityMarginals (me, p, numberOfRows); GaussianMixture_removeComponent (me, component); } double GaussianMixture_and_TableOfReal_getLikelihoodValue (GaussianMixture me, TableOfReal thee, int criterion) { double value = NUMundefined; autoNUMmatrix pp (1, thy numberOfRows + 1, 1, my numberOfComponents + 1); if (GaussianMixture_and_TableOfReal_getProbabilities (me, thee, 0, pp.peek())) { value = GaussianMixture_getLikelihoodValue (me, pp.peek(), thy numberOfRows, criterion); } return value; } double GaussianMixture_getLikelihoodValue (GaussianMixture me, double **p, long numberOfRows, int criterion) { // Because we try to _maximize_ a criterion, all criteria are negative numbers. if (criterion == GaussianMixture_CD_LIKELIHOOD) { double lnpcd = 0.0; for (long i = 1; i <= numberOfRows; i++) { double psum = 0, lnsum = 0; for (long ic = 1; ic <= my numberOfComponents; ic++) { double pp = my mixingProbabilities[ic] * p[i][ic]; psum += pp; lnsum += pp * log (pp); } if (psum > 0) { lnpcd += lnsum / psum; } } return lnpcd; } // The common factor for all other criteria is the log(likelihood) double lnp = 0.0; for (long i = 1; i <= numberOfRows; i++) { double psum = 0.0; for (long ic = 1; ic <= my numberOfComponents; ic++) { psum += my mixingProbabilities[ic] * p[i][ic]; } if (psum > 0.0) { lnp += log (psum); } } if (criterion == GaussianMixture_LIKELIHOOD) { return lnp; } double npars = GaussianMixture_getNumberOfParametersInComponent (me), np = npars * my numberOfComponents; if (criterion == GaussianMixture_MML) { /* Equation (15) in Mario A.T. Figueiredo, and Anil K. Jain, Unsupervised Learning of Finite Mixture Models : IEEE TRANSACTIONS ON PATTERN ANALYSIS AND MACHINE INTELLIGENCE, VOL. 24, NO. 3, MARCH 2002 L(theta,Y)= N/2*sum(m=1..k, log(n*alpha[k]/12)) +k/2*ln(n/12) +k(N+1)/2 - log (sum(i=1..n, sum(m=1..k, alpha[k]*p(k)))) */ double logmpn = 0.0; for (long ic = 1; ic <= my numberOfComponents; ic++) { logmpn += log (my mixingProbabilities[ic]); } // a rewritten L(theta,Y) is return lnp - 0.5 * my numberOfComponents * (npars + 1) * (log (numberOfRows / 12.0) + 1.0) + 0.5 * npars * logmpn; } else if (criterion == GaussianMixture_BIC) { return 2.0 * lnp - np * log (numberOfRows); } else if (criterion == GaussianMixture_AIC) { return 2.0 * (lnp - np); } else if (criterion == GaussianMixture_AICC) { np = npars * my numberOfComponents; return 2.0 * (lnp - np * (numberOfRows / (numberOfRows - np - 1.0))); } return lnp; } autoGaussianMixture GaussianMixture_and_TableOfReal_to_GaussianMixture_CEMM (GaussianMixture gm, TableOfReal thee, long minNumberOfComponents, double delta_l, long maxNumberOfIterations, double lambda, int criterion) { try { const char32 *criterionText = GaussianMixture_criterionText (criterion); bool deleteWeakComponents = ( minNumberOfComponents > 0 ); autoGaussianMixture me = Data_copy (gm); autoNUMmatrix p (1, thy numberOfRows + 2, 1, my numberOfComponents + 1); double *gsum = p[thy numberOfRows + 1]; // convenience array with sums autoCovariance covg = TableOfReal_to_Covariance (thee); double npars = GaussianMixture_getNumberOfParametersInComponent (me.peek()); double nparsd2 = deleteWeakComponents ? npars / 2.0 : 0.0; // Initial E-step: Update all p's. GaussianMixture_and_TableOfReal_getProbabilities (me.peek(), thee, 0, p.peek()); double lnew = GaussianMixture_getLikelihoodValue (me.peek(), p.peek(), thy numberOfRows, criterion); autoMelderProgress progress (U"Gaussian mixture..."); autoGaussianMixture best; try { double lstart = lnew / thy numberOfRows; long iter = 0, component; double lmax = -INFINITY, lprev; while (my numberOfComponents >= minNumberOfComponents) { do { iter++; component = 1; lprev = lnew; while (component <= my numberOfComponents) { // M-step for means and covariances GaussianMixture_updateProbabilityMarginals (me.peek(), p.peek(), thy numberOfRows); GaussianMixture_updateCovariance (me.peek(), component, thy data, thy numberOfRows, p.peek()); if (lambda > 0) { GaussianMixture_addCovarianceFraction (me.peek(), component, covg.peek(), lambda); } // Now check if enough support for a component exists double support_im = gsum[component] - nparsd2, support = 0; for (long ic = 1; ic <= my numberOfComponents; ic++) { double support_ic = gsum[ic] - nparsd2; if (support_ic > 0) { support += support_ic; } } my mixingProbabilities[component] = support_im > 0.0 ? support_im : 0.0; if (support > 0) { my mixingProbabilities[component] /= support; } NUMdvector_scaleAsProbabilities (my mixingProbabilities, my numberOfComponents); if (my mixingProbabilities[component] > 0.0) { // update p for component GaussianMixture_and_TableOfReal_getProbabilities (me.peek(), thee, component, p.peek()); component++; } else { // "Remove" the component column from p by shifting row values GaussianMixture_removeComponent_bookkeeping (me.peek(), component, p.peek(), thy numberOfRows); // Now numberOfComponents is one less! // MelderInfo_writeLine (U"Removed component ", component); } } // L(theta,Y)=N/2 sum(m=1..k, log(n*mixingP[m]/12))+k/2log(n/12)+k/2(N+1)-loglikelihood reduces to: // k/2 (N+1){log(n/12)+1}+N/2sum(m=1..k,mixingP[m]) - loglikelihood lnew = GaussianMixture_getLikelihoodValue (me.peek(), p.peek(), thy numberOfRows, criterion); Melder_progress ((double) iter / (double) maxNumberOfIterations, U", ", criterionText, U": ", lnew / thy numberOfRows, U"\nComponents: ", my numberOfComponents, U"\nL0: ", lstart); } while (lnew > lprev && fabs ( (lprev - lnew) / lnew) > delta_l && iter < maxNumberOfIterations); if (lnew > lmax) { best = Data_copy (me.peek()); lmax = lnew; if (! deleteWeakComponents) { break; // TODO was got end; is dat hetzelfde? } } if (my numberOfComponents > 1) { // remove smallest component component = 1; double mpmin = my mixingProbabilities[component]; for (long ic = 2; ic <= my numberOfComponents; ic++) { if (my mixingProbabilities[ic] < mpmin) { mpmin = my mixingProbabilities[ic]; component = ic; } } GaussianMixture_removeComponent_bookkeeping (me.peek(), component, p.peek(), thy numberOfRows); } else { break; } } } catch (MelderError) { Melder_clearError (); } return best; } catch (MelderError) { Melder_throw (U"GaussianMixture not improved."); } } // The numberOfElemnts per covariance needs to be updated later void GaussianMixture_removeComponent (GaussianMixture me, long component) { if (component < 1 || component > my numberOfComponents || my numberOfComponents == 1) { return; } Collection_removeItem (my covariances, component); my numberOfComponents --; for (long ic = component; ic <= my numberOfComponents; ic++) { my mixingProbabilities[ic] = my mixingProbabilities[ic + 1]; } NUMdvector_scaleAsProbabilities (my mixingProbabilities, my numberOfComponents); } autoGaussianMixture TableOfReal_to_GaussianMixture (TableOfReal me, long numberOfComponents, double delta_lnp, long maxNumberOfIterations, double lambda, int storage, int criterion) { try { if (my numberOfRows < 2 * numberOfComponents) { Melder_throw (U"The number of data points must at least be twice the number of components."); } autoGaussianMixture thee = GaussianMixture_create (numberOfComponents, my numberOfColumns, storage); GaussianMixture_setLabelsFromTableOfReal (thee.peek(), me); GaussianMixture_initialGuess (thee.peek(), me, 1.0, 0.05); if (maxNumberOfIterations <= 0) { return thee; } GaussianMixture_and_TableOfReal_improveLikelihood (thee.peek(), me, delta_lnp, maxNumberOfIterations, lambda, criterion); return thee; } catch (MelderError) { Melder_throw (me, U": no GaussianMixture created."); } } autoCorrelation GaussianMixture_and_TableOfReal_to_Correlation (GaussianMixture me, thou) { try { thouart (TableOfReal); if (my dimension != thy numberOfColumns) { Melder_throw (U"Dimensions must be equal."); } autoClassificationTable ct = GaussianMixture_and_TableOfReal_to_ClassificationTable (me, thee); autoCorrelation him = ClassificationTable_to_Correlation_columns (ct.peek()); return him; } catch (MelderError) { Melder_throw (U"Correlation not created from GaussianMixture & TableOfReal."); } } double GaussianMixture_getProbabilityAtPosition_string (GaussianMixture me, const char32 *vector) { autoNUMvector v (1, my dimension); long i = 0; for (char32 *token = Melder_firstToken (vector); token != nullptr; token = Melder_nextToken ()) { v[++i] = Melder_atof (token); if (i == my dimension) { break; } } double p = GaussianMixture_getProbabilityAtPosition (me, v.peek()); return p; } double GaussianMixture_getMarginalProbabilityAtPosition (GaussianMixture me, double *vector, double x) { double p = 0; for (long im = 1; im <= my numberOfComponents; im++) { double pim = Covariance_getMarginalProbabilityAtPosition ( (Covariance) my covariances -> item[im], vector, x); p += my mixingProbabilities[im] * pim; } return p; } double GaussianMixture_getProbabilityAtPosition (GaussianMixture me, double *xpos) { double p = 0.0; for (long im = 1; im <= my numberOfComponents; im++) { double pim = Covariance_getProbabilityAtPosition ( (Covariance) my covariances -> item[im], xpos); p += my mixingProbabilities[im] * pim; } return p; } autoMatrix GaussianMixture_and_PCA_to_Matrix_density (GaussianMixture me, PCA thee, long d1, long d2, double xmin, double xmax, long nx, double ymin, double ymax, long ny) { try { if (my dimension != thy dimension) { Melder_throw (U"Dimensions must be equal."); } if (d1 > thy numberOfEigenvalues || d2 > thy numberOfEigenvalues) { Melder_throw (U"Direction index too high."); } autoNUMvector v (1, my dimension); if (xmax == xmin || ymax == ymin) { double xmind, xmaxd, ymind, ymaxd, nsigmas = 2.0; GaussianMixture_and_PCA_getIntervalsAlongDirections (me, thee, d1, d2, nsigmas, &xmind, &xmaxd, &ymind, &ymaxd); if (xmax == xmin) { xmin = xmind; xmax = xmaxd; } if (ymax == ymin) { ymin = ymind; ymax = ymaxd; } } // xmin,xmax and ymin,ymax are coordinates in the pc1 vs pc2 plane double dx = fabs (xmax - xmin) / nx, dy = fabs (ymax - ymin) / ny; double x1 = xmin + 0.5 * dx, y1 = ymin + 0.5 * dy; autoMatrix him = Matrix_create (xmin, xmax, nx, dx, x1, ymin, ymax, ny, dy, y1); for (long i = 1; i <= ny; i++) { double y = y1 + (i - 1) * dy; for (long j = 1; j <= nx; j++) { double x = x1 + (j - 1) * dx; for (long k = 1; k <= my dimension; k++) { v[k] = x * thy eigenvectors[d1][k] + y * thy eigenvectors[d2][k]; } his z[i][j] = GaussianMixture_getProbabilityAtPosition (me, v.peek()); } } return him; } catch (MelderError) { Melder_throw (me, U" & ", thee, U": no Matrix density created."); } } autoTableOfReal GaussianMixture_to_TableOfReal_randomSampling (GaussianMixture me, long numberOfPoints) { try { Covariance cov = (Covariance) my covariances -> item[1]; autoTableOfReal thee = TableOfReal_create (numberOfPoints, my dimension); autoNUMvector buf (1, my dimension); NUMstrings_copyElements (cov -> columnLabels, thy columnLabels, 1, my dimension); for (long i = 1; i <= numberOfPoints; i++) { char32 *covname; GaussianMixture_generateOneVector (me, thy data[i], &covname, buf.peek()); TableOfReal_setRowLabel (thee.peek(), i, covname); } GaussianMixture_unExpandPCA (me); return thee; } catch (MelderError) { GaussianMixture_unExpandPCA (me); Melder_throw (U"TableOfReal with random ssampling not created."); } } autoTableOfReal GaussianMixture_and_TableOfReal_to_TableOfReal_BHEPNormalityTests (GaussianMixture me, TableOfReal thee, double h) { try { long n = thy numberOfRows, d = thy numberOfColumns, nocp1 = my numberOfComponents + 1; if (d != my dimension) { Melder_throw (U"Dimensions do not agree."); } // We cannot use a classification table because this could weigh a far-off data point with high probability autoNUMmatrix p (1, thy numberOfRows + 1, 1, my numberOfComponents + 1); GaussianMixture_and_TableOfReal_getProbabilities (me, thee, 0, p.peek()); // prob, beta, tnbo, lnmu, lnvar, ndata, ncol autoTableOfReal him = TableOfReal_create (my numberOfComponents, 7); // labels long iprob = 1, ih = 2, itnb = 3, ilnmu = 4, ilnvar = 5, indata = 6, id = 7; const char32 *label[8] = { U"", U"p", U"h", U"tnb", U"lnmu", U"lnvar", U"ndata", U"d" }; for (long icol = 1; icol <= 7; icol++) { TableOfReal_setColumnLabel (him.peek(), icol, label[icol]); } for (long irow = 1; irow <= my numberOfComponents; irow++) { Covariance cov = (Covariance) my covariances -> item[irow]; TableOfReal_setRowLabel (him.peek(), irow, Thing_getName (cov)); } for (long icol = 1 ; icol <= my numberOfComponents; icol++) { his data[icol][indata] = p[n + 1][icol]; } for (long im = 1; im <= my numberOfComponents; im++) { Covariance cov = (Covariance) my covariances -> item[im]; double mixingP = my mixingProbabilities[im]; double nd = his data[im][indata], d2 = d / 2.0; double beta = h > 0.0 ? NUMsqrt1_2 / h : NUMsqrt1_2 * pow ( (1.0 + 2.0 * d) / 4.0, 1.0 / (d + 4.0)) * pow (nd, 1.0 / (d + 4.0)); double beta2 = beta * beta, beta4 = beta2 * beta2, beta8 = beta4 * beta4; double gamma = 1.0 + 2.0 * beta2, gamma2 = gamma * gamma, gamma4 = gamma2 * gamma2; double delta = 1.0 + beta2 * (4.0 + 3.0 * beta2), delta2 = delta * delta; double mu = 1.0 - pow (gamma, -d2) * (1.0 + d * beta2 / gamma + d * (d + 2.0) * beta4 / (2.0 * gamma2)); double var = 2.0 * pow (1.0 + 4.0 * beta2, -d2) + 2.0 * pow (gamma, -d) * (1.0 + 2.0 * d * beta4 / gamma2 + 3.0 * d * (d + 2.0) * beta8 / (4.0 * gamma4)) - 4.0 * pow (delta, -d2) * (1.0 + 3.0 * d * beta4 / (2.0 * delta) + d * (d + 2.0) * beta8 / (2.0 * delta2)); double mu2 = mu * mu; double prob = NUMundefined, tnb = NUMundefined, lnmu = NUMundefined, lnvar = NUMundefined; try { SSCP_expandLowerCholesky (cov); } catch (MelderError) { tnb = 4.0 * nd; } double djk, djj, sumjk = 0.0, sumj = 0.0; double b1 = beta2 / 2.0, b2 = b1 / (1.0 + beta2); /* Heinze & Wagner (1997), page 3 We use d[j][k] = ||Y[j]-Y[k]||^2 = (Y[j]-Y[k])'S^(-1)(Y[j]-Y[k]) So d[j][k]= d[k][j] and d[j][j] = 0 */ for (long j = 1; j <= n; j++) { double wj = p[j][nocp1] > 0.0 ? mixingP * p[j][im] / p[j][nocp1] : 0.0; for (long k = 1; k < j; k++) { djk = NUMmahalanobisDistance_chi (cov -> lowerCholesky, thy data[j], thy data[k], d, d); double w = p[k][nocp1] > 0.0 ? wj * mixingP * p[k][im] / p[k][nocp1] : 0.0; sumjk += 2.0 * w * exp (-b1 * djk); // factor 2 because d[j][k] == d[k][j] } sumjk += wj * wj; // for k == j. Is this ok now for probability weighing ???? djj = NUMmahalanobisDistance_chi (cov -> lowerCholesky, thy data[j], cov -> centroid, d, d); sumj += wj * exp (-b2 * djj); } tnb = (1.0 / nd) * sumjk - 2.0 * pow (1.0 + beta2, - d2) * sumj + nd * pow (gamma, - d2); // n * his data[im][ilnmu] = lnmu = 0.5 * log (mu2 * mu2 / (mu2 + var)); //log (sqrt (mu2 * mu2 /(mu2 + var))); his data[im][ilnvar] = lnvar = sqrt (log ( (mu2 + var) / mu2)); his data[im][iprob] = prob = NUMlogNormalQ (tnb, lnmu, lnvar); his data[im][ih] = NUMsqrt1_2 / beta; his data[im][id] = d; his data[im][itnb] = tnb; } return him; } catch (MelderError) { Melder_throw (U"TableOfReal for BHEP not created."); } } /* End of file GaussianMixture.cpp 1555*/ praat-6.0.04/dwtools/GaussianMixture.h000066400000000000000000000143441261542461700177220ustar00rootroot00000000000000#ifndef _GaussianMixture_h_ #define _GaussianMixture_h_ /* GaussianMixture.h * * Copyright (C) 2010-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20101021 initial version djmw 20110306 Latest modification. */ #include "ClassificationTable.h" #include "Matrix.h" #include "SSCP.h" #include "TableOfReal_extensions.h" #include "GaussianMixture_def.h" oo_CLASS_CREATE (GaussianMixture, Daata); /* Constraints for a Gaussian mixture: all covariances have the same 'dimension' parameter */ autoGaussianMixture GaussianMixture_create (long numberOfComponents, long dimension, long storage); /* Start each function with expand and end with unExpand */ void GaussianMixture_expandPCA (GaussianMixture me); void GaussianMixture_unExpandPCA (GaussianMixture me); void GaussianMixture_drawConcentrationEllipses (GaussianMixture me, Graphics g, double scale, int confidence, char32 *label, int pcaDirections, long d1, long d2, double xmin, double xmax, double ymin, double ymax, int fontSize, int garnish); void GaussianMixture_and_PCA_drawConcentrationEllipses (GaussianMixture me, PCA him, Graphics g, double scale, int confidence, char32 *label, long d1, long d2, double xmin, double xmax, double ymin, double ymax, int fontSize, int garnish); void GaussianMixture_drawMarginalPdf (GaussianMixture me, Graphics g, long d, double xmin, double xmax, double ymin, double ymax, long npoints, long nbins, int garnish); void GaussianMixture_and_PCA_drawMarginalPdf (GaussianMixture me, PCA him, Graphics g, long d, double xmin, double xmax, double ymin, double ymax, long npoints, long nbins, int garnish); autoGaussianMixture TableOfReal_to_GaussianMixture_fromRowLabels (TableOfReal me, long storage); void GaussianMixture_initialGuess (GaussianMixture me, TableOfReal thee, double nSigmas, double ru_range); /* Give an initial guess for the centroids and covariances of the GaussianMixture based on the data in the table. Position centroids on the nSigma-ellips in the pc1-pc2 plane with some random variation and the covariances as a scaled down version of the total covariance. The randomly varied position of a centroid on the ellipse is parametrized as: x = a * (1 + randomUniform (-ru_range, ru_range)) * cos (alpha) y = b * (1 + randomUniform (-ru_range, ru_range)) * sin (alpha). where a and b are the axes of the ellipse and 0<= alpha <= 2pi. */ #define GaussianMixture_LIKELIHOOD 0 #define GaussianMixture_MML 1 #define GaussianMixture_BIC 2 #define GaussianMixture_AIC 3 #define GaussianMixture_AICC 4 #define GaussianMixture_CD_LIKELIHOOD 5 const char32 *GaussianMixture_criterionText (int criterion); autoGaussianMixture TableOfReal_to_GaussianMixture (TableOfReal me, long numberOfComponents, double delta_lnp, long maxNumberOfIterations, double lambda, int storage, int criterion); void GaussianMixture_and_TableOfReal_improveLikelihood (GaussianMixture me, TableOfReal thee, double delta_lnp, long maxNumberOfIterations, double lambda, int criterion); autoGaussianMixture GaussianMixture_and_TableOfReal_to_GaussianMixture_CEMM (GaussianMixture me, TableOfReal thee, long minNumberOfComponents, double delta_l, long maxNumberOfIterations, double lambda, int criterion); void GaussianMixture_splitComponent (GaussianMixture me, long component); autoClassificationTable GaussianMixture_and_TableOfReal_to_ClassificationTable (GaussianMixture me, TableOfReal thee); autoTableOfReal GaussianMixture_and_TableOfReal_to_TableOfReal_BHEPNormalityTests (GaussianMixture me, TableOfReal thee, double h); double GaussianMixture_and_TableOfReal_getLikelihoodValue (GaussianMixture me, TableOfReal thee, int criterion); double GaussianMixture_getProbabilityAtPosition (GaussianMixture me, double *vector); double GaussianMixture_getProbabilityAtPosition_string (GaussianMixture me, const char32 *vector); double GaussianMixture_getMarginalProbabilityAtPosition (GaussianMixture me, double *vector, double x); autoCorrelation GaussianMixture_and_TableOfReal_to_Correlation (GaussianMixture me, thou); /* Correlation between components based on the data in the table */ autoCovariance GaussianMixture_to_Covariance_total (GaussianMixture me); autoCovariance GaussianMixture_to_Covariance_between (GaussianMixture me); autoCovariance GaussianMixture_to_Covariance_within (GaussianMixture me); autoCovariance GaussianMixture_extractComponent(GaussianMixture me, long component); autoTableOfReal GaussianMixture_extractCentroids (GaussianMixture me); autoTableOfReal GaussianMixture_extractMixingProbabilities (GaussianMixture me); autoPCA GaussianMixture_to_PCA (GaussianMixture me); autoMatrix GaussianMixture_and_PCA_to_Matrix_density (GaussianMixture me, PCA pca, long d1, long d2, double xmin, double xmax, long nx, double ymin, double ymax, long ny); void GaussianMixture_and_PCA_getIntervalsAlongDirections (GaussianMixture me, PCA thee, long d1, long d2, double nsigmas, double *xmin, double *xmax, double *ymin, double *ymax); void GaussianMixture_and_PCA_getIntervalAlongDirection (GaussianMixture me, PCA thee, long d, double nsigmas, double *xmin, double *xmax); void GaussianMixture_getIntervalAlongDirection (GaussianMixture me, long d, double nsigmas, double *xmin, double *xmax); void GaussianMixture_getIntervalsAlongDirections (GaussianMixture me, long d1, long d2, double nsigmas, double *xmin, double *xmax, double *ymin, double *ymax); /* with on demand expand of pca ! */ int GaussianMixture_generateOneVector (GaussianMixture me, double *c, char32 **covname, double *buf); autoTableOfReal GaussianMixture_to_TableOfReal_randomSampling (GaussianMixture me, long numberOfPoints); #endif /* _GaussianMixture_h_ */ praat-6.0.04/dwtools/GaussianMixture_def.h000066400000000000000000000022011261542461700205250ustar00rootroot00000000000000/* GaussianMixture_def.h * * Copyright (C) 2010 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT GaussianMixture oo_DEFINE_CLASS (GaussianMixture, Daata) oo_LONG (numberOfComponents) oo_LONG (dimension) oo_DOUBLE_VECTOR (mixingProbabilities, numberOfComponents) oo_COLLECTION (Ordered, covariances, Covariance, 0) #if oo_DECLARING void v_info () override; #endif oo_END_CLASS(GaussianMixture) #undef ooSTRUCT /* End of file GaussianMixture_def.h */ praat-6.0.04/dwtools/HMM.cpp000066400000000000000000001637421261542461700155550ustar00rootroot00000000000000/* HMM.cpp * * Copyright (C) 2010-2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20110304 Thing_new */ #include "Distributions_and_Strings.h" #include "HMM.h" #include "Index.h" #include "NUM2.h" #include "Strings_extensions.h" #include "oo_DESTROY.h" #include "HMM_def.h" #include "oo_COPY.h" #include "HMM_def.h" #include "oo_EQUAL.h" #include "HMM_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "HMM_def.h" #include "oo_WRITE_TEXT.h" #include "HMM_def.h" #include "oo_WRITE_BINARY.h" #include "HMM_def.h" #include "oo_READ_TEXT.h" #include "HMM_def.h" #include "oo_READ_BINARY.h" #include "HMM_def.h" #include "oo_DESCRIPTION.h" #include "HMM_def.h" /* Whenever a routine returns ln(p), the result for p=0 is -INFINITY. On IEEE floating point hardware this number behaves reasonably. This means that when the variable q equals INFINITY, q + a -> INFINITY, where a is a finite number. */ // helpers int NUMget_line_intersection_with_circle (double xc, double yc, double r, double a, double b, double *x1, double *y1, double *x2, double *y2); void HMMObservation_init (I, const char32 *label, long numberOfComponents, long dimension, long storage); autoHMMObservation HMMObservation_create (const char32 *label, long numberOfComponents, long dimension, long storage); long HMM_and_HMMObservationSequence_getLongestSequence (HMM me, HMMObservationSequence thee, long symbolNumber); long StringsIndex_getLongestSequence (StringsIndex me, long index, long *pos); long Strings_getLongestSequence (Strings me, char32 *string, long *pos); void HMMState_init (I, const char32 *label); autoHMMState HMMState_create (const char32 *label); autoHMMBaumWelch HMMBaumWelch_create (long nstates, long nsymbols, long capacity); void HMMBaumWelch_getGamma (HMMBaumWelch me); autoHMMBaumWelch HMM_forward (HMM me, long *obs, long nt); void HMMBaumWelch_reInit (HMMBaumWelch me); void HMM_and_HMMBaumWelch_getXi (HMM me, HMMBaumWelch thee, long *obs); void HMM_and_HMMBaumWelch_reestimate (HMM me, HMMBaumWelch thee); void HMM_and_HMMBaumWelch_addEstimate (HMM me, HMMBaumWelch thee, long *obs); void HMM_and_HMMBaumWelch_forward (HMM me, HMMBaumWelch thee, long *obs); void HMM_and_HMMBaumWelch_backward (HMM me, HMMBaumWelch thee, long *obs); void HMM_and_HMMViterbi_decode (HMM me, HMMViterbi thee, long *obs); double HMM_getProbabilityOfObservations (HMM me, long *obs, long numberOfTimes); autoTableOfReal StringsIndex_to_TableOfReal_transitions (StringsIndex me, int probabilities); autoStringsIndex HMM_and_HMMStateSequence_to_StringsIndex (HMM me, HMMStateSequence thee); autoHMMViterbi HMMViterbi_create (long nstates, long ntimes); autoHMMViterbi HMM_to_HMMViterbi (HMM me, long *obs, long ntimes); // evaluate the numbers given to probabilities static double *NUMwstring_to_probs (char32 *s, long nwanted) { long numbers_found; autoNUMvector numbers (NUMstring_to_numbers (s, &numbers_found), 1); if (numbers_found != nwanted) { Melder_throw (U"You supplied ", numbers_found, U", while ", nwanted, U" numbers needed."); } double sum = 0; for (long i = 1; i <= numbers_found; i++) { if (numbers[i] < 0) { Melder_throw (U"Numbers have to be positive."); } sum += numbers[i]; } if (sum <= 0) { Melder_throw (U"All probabilities cannot be zero."); } for (long i = 1; i <= numbers_found; i++) { numbers[i] /= sum; } return numbers.transfer(); } int NUMget_line_intersection_with_circle (double xc, double yc, double r, double a, double b, double *x1, double *y1, double *x2, double *y2) { double ca = a * a + 1.0, bmyc = (b - yc); double cb = 2.0 * (a * bmyc - xc); double cc = bmyc * bmyc + xc * xc - r * r; long nroots = NUMsolveQuadraticEquation (ca, cb, cc, x1, x2); if (nroots == 1) { *y1 = a * *x1 + b; *x2 = *x1; *y2 = *y1; } else if (nroots == 2) { if (*x1 > *x2) { double tmp = *x1; *x1 = *x2; *x2 = tmp; } *y1 = *x1 * a + b; *y2 = *x2 * a + b; } return nroots; } // D(l_1,l_2)=1/n( log p(O_2|l_1) - log p(O_2|l_2) static double HMM_and_HMM_getCrossEntropy_asym (HMM me, HMM thee, long observationLength) { autoHMMObservationSequence os = HMM_to_HMMObservationSequence (thee, 0, observationLength); double ce = HMM_and_HMMObservationSequence_getCrossEntropy (me, os.peek()); if (ce == NUMundefined || ce == INFINITY) { return ce; } double ce2 = HMM_and_HMMObservationSequence_getCrossEntropy (thee, os.peek()); if (ce2 == NUMundefined || ce2 == INFINITY) { return ce2; } return ce - ce2; } /**************** HMMObservation ******************************/ Thing_implement (HMMObservation, Daata, 0); void HMMObservation_init (HMMObservation me, const char32 *label, long numberOfComponents, long dimension, long storage) { my label = Melder_dup (label); my gm = GaussianMixture_create (numberOfComponents, dimension, storage); } autoHMMObservation HMMObservation_create (const char32 *label, long numberOfComponents, long dimension, long storage) { try { autoHMMObservation me = Thing_new (HMMObservation); HMMObservation_init (me.peek(), label, numberOfComponents, dimension, storage); return me; } catch (MelderError) { Melder_throw (U"HMMObservation not created."); } } long Strings_getLongestSequence (Strings me, char32 *string, long *pos) { long length = 0, longest = 0, lpos = 0; for (long i = 1; i <= my numberOfStrings; i++) { if (Melder_equ (my strings[i], string)) { if (length == 0) { lpos = i; } length++; } else { if (length > 0) { if (length > longest) { longest = length; *pos = lpos; } length = 0; } } } return length; } long StringsIndex_getLongestSequence (StringsIndex me, long index, long *pos) { long length = 0, longest = 0, lpos = 0; for (long i = 1; i <= my numberOfElements; i++) { if (my classIndex[i] == index) { if (length == 0) { lpos = i; } length++; } else { if (length > 0) { if (length > longest) { longest = length; *pos = lpos; } length = 0; } } } return length; } /**************** HMMState ******************************/ Thing_implement (HMMState, Daata, 0); void HMMState_init (HMMState me, const char32 *label) { my label = Melder_dup (label); } autoHMMState HMMState_create (const char32 *label) { try { autoHMMState me = Thing_new (HMMState); HMMState_init (me.peek(), label); return me; } catch (MelderError) { Melder_throw (U"HMMState not created."); } } void HMMState_setLabel (HMMState me, char32 *label) { Melder_free (my label); my label = Melder_dup (label); } /**************** HMMBaumWelch ******************************/ Thing_implement (HMMBaumWelch, Daata, 0); void structHMMBaumWelch :: v_destroy () { for (long it = 1; it <= capacity; it++) { NUMmatrix_free (xi[it], 1, 1); } NUMvector_free (xi, 1); NUMvector_free (scale, 1); NUMmatrix_free (beta, 1, 1); NUMmatrix_free (alpha, 1, 1); NUMmatrix_free (gamma, 1, 1); NUMmatrix_free (aij_num, 0, 1); NUMmatrix_free (aij_denom, 0, 1); NUMmatrix_free (bik_num, 1, 1); NUMmatrix_free (bik_denom, 1, 1); } autoHMMBaumWelch HMMBaumWelch_create (long nstates, long nsymbols, long capacity) { try { autoHMMBaumWelch me = Thing_new (HMMBaumWelch); my numberOfTimes = my capacity = capacity; my numberOfStates = nstates; my numberOfSymbols = nsymbols; my alpha = NUMmatrix (1, nstates, 1, capacity); my beta = NUMmatrix (1, nstates, 1, capacity); my scale = NUMvector (1, capacity); my xi = NUMvector (1, capacity); my aij_num = NUMmatrix (0, nstates, 1, nstates + 1); my aij_denom = NUMmatrix (0, nstates, 1, nstates + 1); my bik_num = NUMmatrix (1, nstates, 1, nsymbols); my bik_denom = NUMmatrix (1, nstates, 1, nsymbols); my gamma = NUMmatrix (1, nstates, 1, capacity); for (long it = 1; it <= capacity; it++) { my xi[it] = NUMmatrix (1, nstates, 1, nstates); } return me; } catch (MelderError) { Melder_throw (U"HMMBaumWelch not created."); } } void HMMBaumWelch_getGamma (HMMBaumWelch me) { for (long it = 1; it <= my numberOfTimes; it++) { double sum = 0.0; for (long is = 1; is <= my numberOfStates; is++) { my gamma[is][it] = my alpha[is][it] * my beta[is][it]; sum += my gamma[is][it]; } for (long is = 1; is <= my numberOfStates; is++) { my gamma[is][it] /= sum; } } } /**************** HMMViterbi ******************************/ Thing_implement (HMMViterbi, Daata, 0); autoHMMViterbi HMMViterbi_create (long nstates, long ntimes) { try { autoHMMViterbi me = Thing_new (HMMViterbi); my numberOfTimes = ntimes; my numberOfStates = nstates; my viterbi = NUMmatrix (1, nstates, 1 , ntimes); my bp = NUMmatrix (1, nstates, 1 , ntimes); my path = NUMvector (1, ntimes); return me; } catch (MelderError) { Melder_throw (U"HMMViterbi not created."); } } /******************* HMMObservationSequence & HMMStateSequence ***/ Thing_implement (HMMObservationSequence, Table, 0); autoHMMObservationSequence HMMObservationSequence_create (long numberOfItems, long dataLength) { try { autoHMMObservationSequence me = Thing_new (HMMObservationSequence); Table_initWithoutColumnNames (me.peek(), numberOfItems, dataLength + 1); return me; } catch (MelderError) { Melder_throw (U"HMMObservationSequence not created."); } } long HMMObservationSequence_getNumberOfObservations (HMMObservationSequence me) { return my rows -> size; } void HMMObservationSequence_removeObservation (HMMObservationSequence me, long index) { Table_removeRow ( (Table) me, index); } autoStrings HMMObservationSequence_to_Strings (HMMObservationSequence me) { try { long numberOfStrings = my rows -> size; autoStrings thee = Thing_new (Strings); thy strings = NUMvector (1, numberOfStrings); for (long i = 1; i <= numberOfStrings; i++) { thy strings[i] = Melder_dup_f (Table_getStringValue_Assert ( (Table) me, i, 1)); (thy numberOfStrings) ++; } return thee; } catch (MelderError) { Melder_throw (me, U": no Strings created."); } } autoHMMObservationSequence Strings_to_HMMObservationSequence (Strings me) { try { autoHMMObservationSequence thee = HMMObservationSequence_create (my numberOfStrings, 0); for (long i = 1; i <= my numberOfStrings; i++) { Table_setStringValue ( (Table) thee.peek(), i, 1, my strings[i]); } return thee; } catch (MelderError) { Melder_throw (me, U": no HMMObservationSequence created."); } } autoStringsIndex HMMObservationSequence_to_StringsIndex (HMMObservationSequence me) { try { autoStrings s = HMMObservationSequence_to_Strings (me); autoStringsIndex thee = Strings_to_StringsIndex (s.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": no StringsIndex created."); } } long HMM_and_HMMObservationSequence_getLongestSequence (HMM me, HMMObservationSequence thee, long symbolNumber) { autoStringsIndex si = HMM_and_HMMObservationSequence_to_StringsIndex (me, thee); // TODO (void) symbolNumber; return 1; } Thing_implement (HMMObservationSequences, Collection, 0); autoHMMObservationSequences HMMObservationSequences_create () { try { autoHMMObservationSequences me = Thing_new (HMMObservationSequences); Collection_init (me.peek(), classHMMObservationSequence, 1000); return me; } catch (MelderError) { Melder_throw (U"HMMObservationSequences not created."); } } long HMMObservationSequences_getLongestSequence (HMMObservationSequences me) { long longest = 0; for (long i = 1; i <= my size; i++) { HMMObservationSequence thee = (HMMObservationSequence) my item[i]; if (thy rows -> size > longest) { longest = thy rows -> size; } } return longest; } Thing_implement (HMMStateSequence, Strings, 0); autoHMMStateSequence HMMStateSequence_create (long numberOfItems) { try { autoHMMStateSequence me = Thing_new (HMMStateSequence); my strings = NUMvector (1, numberOfItems); return me; } catch (MelderError) { Melder_throw (U"HMMStateSequence not created."); } } autoStrings HMMStateSequence_to_Strings (HMMStateSequence me) { try { autoStrings thee = Thing_new (Strings); my structStrings :: v_copy (thee.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": no Strings created."); } } /**************** HMM ******************************/ Thing_implement (HMM, Daata, 0); void structHMM :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Number of states: ", numberOfStates); for (long i = 1; i <= numberOfStates; i++) { HMMState hmms = (HMMState) states -> item[i]; MelderInfo_writeLine (U" ", hmms -> label); } MelderInfo_writeLine (U"Number of symbols: ", numberOfObservationSymbols); for (long i = 1; i <= numberOfObservationSymbols; i++) { HMMObservation hmms = (HMMObservation) observationSymbols -> item[i]; MelderInfo_writeLine (U" ", hmms -> label); } } static void HMM_init (HMM me, long numberOfStates, long numberOfObservationSymbols, int leftToRight) { my numberOfStates = numberOfStates; my numberOfObservationSymbols = numberOfObservationSymbols; my componentStorage = 1; my leftToRight = leftToRight; my states = Ordered_create (); my observationSymbols = Ordered_create (); my transitionProbs = NUMmatrix (0, numberOfStates, 1, numberOfStates + 1); my emissionProbs = NUMmatrix (1, numberOfStates, 1, numberOfObservationSymbols); } autoHMM HMM_create (int leftToRight, long numberOfStates, long numberOfObservationSymbols) { try { autoHMM me = Thing_new (HMM); HMM_init (me.peek(), numberOfStates, numberOfObservationSymbols, leftToRight); HMM_setDefaultStates (me.peek()); HMM_setDefaultObservations (me.peek()); HMM_setDefaultTransitionProbs (me.peek()); HMM_setDefaultStartProbs (me.peek()); HMM_setDefaultEmissionProbs (me.peek()); return me; } catch (MelderError) { Melder_throw (U"HMM not created."); } } void HMM_setDefaultStates (HMM me) { for (long i = 1; i <= my numberOfStates; i++) { autoHMMState hmms = HMMState_create (Melder_cat (U"S", i)); HMM_addState (me, hmms.transfer()); } } autoHMM HMM_createFullContinuousModel (int leftToRight, long numberOfStates, long numberOfObservationSymbols, long numberOfFeatureStreams, long *dimensionOfStream, long *numberOfGaussiansforStream) { (void) leftToRight; (void) numberOfStates; (void) numberOfObservationSymbols; (void) numberOfFeatureStreams; (void) dimensionOfStream; (void) numberOfGaussiansforStream; return nullptr; } autoHMM HMM_createContinuousModel (int leftToRight, long numberOfStates, long numberOfObservationSymbols, long numberOfMixtureComponentsPerSymbol, long componentDimension, long componentStorage) { try { autoHMM me = Thing_new (HMM); HMM_init (me.peek(), numberOfStates, numberOfObservationSymbols, leftToRight); my numberOfMixtureComponents = numberOfMixtureComponentsPerSymbol; my componentDimension = componentDimension; my componentStorage = componentStorage; for (long i = 1; i <= numberOfStates; i++) { autoHMMState state = HMMState_create (Melder_cat (U"S", i)); HMM_addState (me.peek(), state.transfer()); } for (long j = 1; j <= numberOfObservationSymbols; j++) { autoHMMObservation obs = HMMObservation_create (Melder_cat (U"s", j), numberOfMixtureComponentsPerSymbol, componentDimension, componentStorage); HMM_addObservation (me.peek(), obs.transfer()); } HMM_setDefaultTransitionProbs (me.peek()); HMM_setDefaultStartProbs (me.peek()); HMM_setDefaultEmissionProbs (me.peek()); HMM_setDefaultMixingProbabilities (me.peek()); return me; } catch (MelderError) { Melder_throw (U"Continuous model HMM not created."); } } // for a simple non-hidden model leave either states empty or symbols empty !!! autoHMM HMM_createSimple (int leftToRight, const char32 *states_string, const char32 *symbols_string) { try { autoHMM me = Thing_new (HMM); const char32 *states = states_string; const char32 *symbols = symbols_string; long numberOfStates = Melder_countTokens (states_string); long numberOfObservationSymbols = Melder_countTokens (symbols_string); if (numberOfStates == 0 and numberOfObservationSymbols == 0) { Melder_throw (U"No states and no symbols given."); } if (numberOfStates > 0) { if (numberOfObservationSymbols <= 0) { numberOfObservationSymbols = numberOfStates; symbols = states_string; my notHidden = 1; } } else if (numberOfObservationSymbols > 0) { numberOfStates = numberOfObservationSymbols; states = symbols_string; my notHidden = 1; } HMM_init (me.peek(), numberOfStates, numberOfObservationSymbols, leftToRight); for (char32 *token = Melder_firstToken (states); token != 0; token = Melder_nextToken ()) { autoHMMState state = HMMState_create (token); HMM_addState (me.peek(), state.transfer()); } for (char32 *token = Melder_firstToken (symbols); token != nullptr; token = Melder_nextToken ()) { autoHMMObservation symbol = HMMObservation_create (token, 0, 0, 0); HMM_addObservation (me.peek(), symbol.transfer()); } HMM_setDefaultTransitionProbs (me.peek()); HMM_setDefaultStartProbs (me.peek()); HMM_setDefaultEmissionProbs (me.peek()); return me; } catch (MelderError) { Melder_throw (U"Simple HMM not created."); } } void HMM_setDefaultObservations (HMM me) { const char32 *def = my notHidden ? U"S" : U"s"; for (long i = 1; i <= my numberOfObservationSymbols; i++) { autoHMMObservation hmms = HMMObservation_create (Melder_cat (def, i), 0, 0, 0); HMM_addObservation (me, hmms.transfer()); } } void HMM_setDefaultTransitionProbs (HMM me) { for (long i = 1; i <= my numberOfStates; i++) { double p = my leftToRight ? 1.0 / (my numberOfStates - i + 1.0) : 1.0 / my numberOfStates; for (long j = 1; j <= my numberOfStates; j++) { my transitionProbs[i][j] = my leftToRight && j < i ? 0.0 : p; } } // leftToRight must have end state! if (my leftToRight) my transitionProbs[my numberOfStates][my numberOfStates] = my transitionProbs[my numberOfStates][my numberOfStates + 1] = 0.5; } void HMM_setDefaultStartProbs (HMM me) { double p = 1.0 / my numberOfStates; for (long j = 1; j <= my numberOfStates; j++) { my transitionProbs[0][j] = p; } } void HMM_setDefaultEmissionProbs (HMM me) { double p = 1.0 / my numberOfObservationSymbols; for (long i = 1; i <= my numberOfStates; i++) for (long j = 1; j <= my numberOfObservationSymbols; j++) { my emissionProbs[i][j] = my notHidden ? (i == j ? 1.0 : 0.0) : p; } } void HMM_setDefaultMixingProbabilities (HMM me) { double mp = 1.0 / my numberOfMixtureComponents; for (long is = 1; is <= my numberOfObservationSymbols; is++) { HMMObservation hmmo = (HMMObservation) my observationSymbols -> item[is]; for (long im = 1; im <= my numberOfMixtureComponents; im++) { hmmo -> gm -> mixingProbabilities[im] = mp; } } } void HMM_setStartProbabilities (HMM me, char32 *probs) { try { autoNUMvector p (NUMwstring_to_probs (probs, my numberOfStates), 1); for (long i = 1; i <= my numberOfStates; i++) { my transitionProbs[0][i] = p[i]; } } catch (MelderError) { Melder_throw (me, U": no start probabilities set."); } } void HMM_setTransitionProbabilities (HMM me, long state_number, char32 *state_probs) { try { if (state_number > my states -> size) { Melder_throw (U"State number too large."); } autoNUMvector p (NUMwstring_to_probs (state_probs, my numberOfStates), 1); for (long i = 1; i <= my numberOfStates + 1; i++) { my transitionProbs[state_number][i] = p[i]; } } catch (MelderError) { Melder_throw (me, U": no transition probabilities set."); } } void HMM_setEmissionProbabilities (HMM me, long state_number, char32 *emission_probs) { try { if (state_number > my states -> size) { Melder_throw (U"State number too large."); } if (my notHidden) { Melder_throw (U"The emission probs of this model are fixed."); } autoNUMvector p (NUMwstring_to_probs (emission_probs, my numberOfObservationSymbols), 1); for (long i = 1; i <= my numberOfObservationSymbols; i++) { my emissionProbs[state_number][i] = p[i]; } } catch (MelderError) { Melder_throw (me, U": no emission probabilities set."); } } void HMM_addObservation (HMM me, thou) { thouart (HMMObservation); long ns = my observationSymbols -> size + 1; if (ns > my numberOfObservationSymbols) { Melder_throw (U"Observation list is full."); } Ordered_addItemPos (my observationSymbols, thee, ns); } void HMM_addState (HMM me, thou) { thouart (HMMState); long ns = my states -> size + 1; if (ns > my numberOfStates) { Melder_throw (U"States list is full."); } Ordered_addItemPos (my states, thee, ns); } autoTableOfReal HMM_extractTransitionProbabilities (HMM me) { try { autoTableOfReal thee = TableOfReal_create (my numberOfStates + 1, my numberOfStates + 1); for (long is = 1; is <= my numberOfStates; is++) { HMMState hmms = (HMMState) my states -> item[is]; TableOfReal_setRowLabel (thee.peek(), is + 1, hmms -> label); TableOfReal_setColumnLabel (thee.peek(), is, hmms -> label); for (long js = 1; js <= my numberOfStates; js++) { thy data[is + 1][js] = my transitionProbs[is][js]; } } TableOfReal_setRowLabel (thee.peek(), 1, U"START"); TableOfReal_setColumnLabel (thee.peek(), my numberOfStates + 1, U"END"); for (long is = 1; is <= my numberOfStates; is++) { thy data[1][is] = my transitionProbs[0][is]; thy data[is + 1][my numberOfStates + 1] = my transitionProbs[is][my numberOfStates + 1]; } return thee; } catch (MelderError) { Melder_throw (me, U": no transition probabilities extracted."); } } autoTableOfReal HMM_extractEmissionProbabilities (HMM me) { try { autoTableOfReal thee = TableOfReal_create (my numberOfStates, my numberOfObservationSymbols); for (long js = 1; js <= my numberOfObservationSymbols; js++) { HMMObservation hmms = (HMMObservation) my observationSymbols -> item[js]; TableOfReal_setColumnLabel (thee.peek(), js, hmms -> label); } for (long is = 1; is <= my numberOfStates; is++) { HMMState hmms = (HMMState) my states -> item[is]; TableOfReal_setRowLabel (thee.peek(), is, hmms -> label); for (long js = 1; js <= my numberOfObservationSymbols; js++) { thy data[is][js] = my emissionProbs[is][js]; } } return thee; } catch (MelderError) { Melder_throw (me, U": no emission probabilities extracted."); }; } double HMM_getExpectedValueOfDurationInState (HMM me, long istate) { if (istate < 0 || istate > my numberOfStates) { return NUMundefined; } return 1 / (1 - my transitionProbs[istate][istate]); } double HMM_getProbabilityOfStayingInState (HMM me, long istate, long numberOfTimeUnits) { if (istate < 0 || istate > my numberOfStates) { return NUMundefined; } return pow (my transitionProbs[istate][istate], numberOfTimeUnits - 1.0) * (1.0 - my transitionProbs[istate][istate]); } double HMM_and_HMM_getCrossEntropy (HMM me, HMM thee, long observationLength, int symmetric) { double ce1 = HMM_and_HMM_getCrossEntropy_asym (me, thee, observationLength); if (! symmetric || ce1 == NUMundefined || ce1 == INFINITY) { return ce1; } double ce2 = HMM_and_HMM_getCrossEntropy_asym (thee, me, observationLength); if (ce2 == NUMundefined || ce2 == INFINITY) { return ce2; } return (ce1 + ce2) / 2.0; } double HMM_and_HMM_and_HMMObservationSequence_getCrossEntropy (HMM me, HMM thee, HMMObservationSequence him) { double ce1 = HMM_and_HMMObservationSequence_getCrossEntropy (me, him); if (ce1 == NUMundefined || ce1 == INFINITY) { return ce1; } double ce2 = HMM_and_HMMObservationSequence_getCrossEntropy (thee, him); if (ce2 == NUMundefined || ce2 == INFINITY) { return ce2; } return (ce1 + ce2) / 2.0; } void HMM_draw (HMM me, Graphics g, int garnish) { double xwidth = sqrt (my numberOfStates); double rstate = 0.3 / xwidth, r = xwidth / 3.0; double xmax = 1.2 * xwidth / 2.0, xmin = -xmax, ymin = xmin, ymax = xmax; autoNUMvector xs (1, my numberOfStates); autoNUMvector ys (1, my numberOfStates); Graphics_setWindow (g, xmin, xmax, ymin, ymax); // heuristic: all states on a circle until we have a better graph drawing algorithm. xs[1] = ys[1] = 0; if (my numberOfStates > 1) { for (long is = 1; is <= my numberOfStates; is++) { double alpha = - NUMpi + NUMpi * 2.0 * (is - 1) / my numberOfStates; xs[is] = r * cos (alpha); ys[is] = r * sin (alpha); } } // reorder the positions such that state number 1 is most left and last state number is right. // if > 5 may be one in the middle with the most connections // ... // find fontsize int fontSize = Graphics_inqFontSize (g); const char32 *widest_label = U""; double max_width = 0.0; for (long is = 1; is <= my numberOfStates; is++) { HMMState hmms = (HMMState) my states -> item[is]; double w = ( hmms -> label == nullptr ? 0.0 : Graphics_textWidth (g, hmms -> label) ); if (w > max_width) { widest_label = hmms -> label; max_width = w; } } int new_fontSize = fontSize; while (max_width > 2.0 * rstate && new_fontSize > 4) { new_fontSize --; Graphics_setFontSize (g, new_fontSize); max_width = Graphics_textWidth (g, widest_label); } Graphics_setFontSize (g, new_fontSize); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); for (long is = 1; is <= my numberOfStates; is++) { HMMState hmms = (HMMState) my states -> item[is]; Graphics_circle (g, xs[is], ys[is], rstate); Graphics_text (g, xs[is], ys[is], hmms -> label); } // draw connections from is to js // 1 -> 2 / 2-> : increase / decrease angle between 1 and 2 with pi /10 // use cos(a+b) and cos(a -b) rules double cosb = cos (NUMpi / 10.0), sinb = sin (NUMpi / 10.0); for (long is = 1; is <= my numberOfStates; is++) { double x1 = xs[is], y1 = ys[is]; for (long js = 1; js <= my numberOfStates; js++) { if (my transitionProbs[is][js] > 0.0 && is != js) { double x2 = xs[js], y2 = ys[js]; double dx = x2 - x1, dy = y2 - y1, h = sqrt (dx * dx + dy * dy), cosa = dx / h, sina = dy / h; double cosabp = cosa * cosb - sina * sinb, cosabm = cosa * cosb + sina * sinb; double sinabp = cosa * sinb + sina * cosb, sinabm = -cosa * sinb + sina * cosb; Graphics_arrow (g, x1 + rstate * cosabp, y1 + rstate * sinabp, x2 - rstate * cosabm, y2 - rstate * sinabm); } if (is == js) { double dx = - x1, dy = - y1, h = sqrt (dx * dx + dy * dy), cosa = dx / h, sina = dy / h; Graphics_doubleArrow (g, x1 - rstate * cosa, y1 - rstate * sina, x1 - 1.4 * rstate * cosa, y1 - 1.4 * rstate * sina); } } } if (garnish) { Graphics_drawInnerBox (g); } } void HMM_unExpandPCA (HMM me) { if (my componentDimension <= 0) { return; // nothing to do } for (long is = 1; is <= my numberOfObservationSymbols; is++) { HMMObservation s = (HMMObservation) my observationSymbols -> item[is]; GaussianMixture_unExpandPCA (s -> gm.peek()); } } autoHMMObservationSequence HMM_to_HMMObservationSequence (HMM me, long startState, long numberOfItems) { try { autoHMMObservationSequence thee = HMMObservationSequence_create (numberOfItems, my componentDimension); autoNUMvector obs; autoNUMvector buf; if (my componentDimension > 0) { obs.reset (1, my componentDimension); buf.reset (1, my componentDimension); } long istate = startState == 0 ? NUMgetIndexFromProbability (my transitionProbs[0], my numberOfStates, NUMrandomUniform (0.0, 1.0)) : startState; for (long i = 1; i <= numberOfItems; i++) { // Emit a symbol from istate long isymbol = NUMgetIndexFromProbability (my emissionProbs[istate], my numberOfObservationSymbols, NUMrandomUniform (0.0, 1.0)); HMMObservation s = (HMMObservation) my observationSymbols -> item[isymbol]; if (my componentDimension > 0) { char32 *name; GaussianMixture_generateOneVector (s -> gm.peek(), obs.peek(), &name, buf.peek()); for (long j = 1; j <= my componentDimension; j++) { Table_setNumericValue ( (Table) thee.peek(), i, 1 + j, obs[j]); } } Table_setStringValue ( (Table) thee.peek(), i, 1, s -> label); // get next state istate = NUMgetIndexFromProbability (my transitionProbs[istate], my numberOfStates + 1, NUMrandomUniform (0.0, 1.0)); if (istate == my numberOfStates + 1) { // final state for (long j = numberOfItems; j > i; j--) { HMMObservationSequence_removeObservation (thee.peek(), j); } break; } } HMM_unExpandPCA (me); return thee; } catch (MelderError) { HMM_unExpandPCA (me); Melder_throw (me, U":no HMMObservationSequence created."); } } autoHMMBaumWelch HMM_forward (HMM me, long *obs, long nt) { try { autoHMMBaumWelch thee = HMMBaumWelch_create (my numberOfStates, my numberOfObservationSymbols, nt); HMM_and_HMMBaumWelch_forward (me, thee.peek(), obs); return thee; } catch (MelderError) { Melder_throw (me, U": no HMMBaumWelch created."); } } autoHMMViterbi HMM_to_HMMViterbi (HMM me, long *obs, long ntimes) { try { autoHMMViterbi thee = HMMViterbi_create (my numberOfStates, ntimes); HMM_and_HMMViterbi_decode (me, thee.peek(), obs); return thee; } catch (MelderError) { Melder_throw (me, U": no HMMViterbi created."); } } void HMMBaumWelch_reInit (HMMBaumWelch me) { my totalNumberOfSequences = 0; my lnProb = 0; /* The _num and _denum matrices are asigned as += in the iteration loop and therefore need to be zeroed at the start of each new iteration. The elements of alpha, beta, scale, gamma & xi are always calculated directly and need not be initialised. */ for (long is = 0; is <= my numberOfStates; is++) { for (long js = 1; js <= my numberOfStates + 1; js++) { my aij_num[is][js] = 0.0; my aij_denom[is][js] = 0.0; } } for (long is = 1; is <= my numberOfStates; is++) { for (long js = 1; js <= my numberOfSymbols; js++) { my bik_num[is][js] = 0.0; my bik_denom[is][js] = 0.0; } } } void HMM_and_HMMObservationSequences_learn (HMM me, HMMObservationSequences thee, double delta_lnp, double minProb, int info) { try { // act as if all observation sequences are in memory long capacity = HMMObservationSequences_getLongestSequence (thee); autoHMMBaumWelch bw = HMMBaumWelch_create (my numberOfStates, my numberOfObservationSymbols, capacity); bw -> minProb = minProb; if (info) { MelderInfo_open (); } long iter = 0; double lnp; do { lnp = bw -> lnProb; HMMBaumWelch_reInit (bw.peek()); for (long ios = 1; ios <= thy size; ios++) { HMMObservationSequence hmm_os = (HMMObservationSequence) thy item[ios]; autoStringsIndex si = HMM_and_HMMObservationSequence_to_StringsIndex (me, hmm_os); // TODO outside the loop or more efficiently long *obs = si -> classIndex, nobs = si -> numberOfElements; // convenience // Interpretation of unknowns: end of sequence long istart = 1, iend = nobs; while (istart <= nobs) { while (istart <= nobs && obs[istart] == 0) { istart++; }; if (istart > nobs) { break; } iend = istart + 1; while (iend <= nobs && obs[iend] != 0) { iend++; } iend --; bw -> numberOfTimes = iend - istart + 1; (bw -> totalNumberOfSequences) ++; HMM_and_HMMBaumWelch_forward (me, bw.peek(), obs + istart - 1); // get new alphas HMM_and_HMMBaumWelch_backward (me, bw.peek(), obs + istart - 1); // get new betas HMMBaumWelch_getGamma (bw.peek()); HMM_and_HMMBaumWelch_getXi (me, bw.peek(), obs + istart - 1); HMM_and_HMMBaumWelch_addEstimate (me, bw.peek(), obs + istart - 1); istart = iend + 1; } } // we have processed all observation sequences, now it is time to estimate new probabilities. iter++; HMM_and_HMMBaumWelch_reestimate (me, bw.peek()); if (info) { MelderInfo_writeLine (U"Iteration: ", iter, U" ln(prob): ", bw -> lnProb); } } while (fabs ((lnp - bw -> lnProb) / bw -> lnProb) > delta_lnp); if (info) { MelderInfo_writeLine (U"******** Learning summary *********"); MelderInfo_writeLine (U" Processed ", thy size, U" sequences,"); MelderInfo_writeLine (U" consisting of ", bw -> totalNumberOfSequences, U" observation sequences."); MelderInfo_writeLine (U" Longest observation sequence had ", capacity, U" items"); MelderInfo_close(); } } catch (MelderError) { Melder_throw (me, U" & ", thee, U": not learned."); } } // xc1 < xc2 void HMM_and_HMMStateSequence_drawTrellis (HMM me, HMMStateSequence thee, Graphics g, int connect, int garnish) { long numberOfTimes = thy numberOfStrings; autoStringsIndex si = HMM_and_HMMStateSequence_to_StringsIndex (me, thee); double xmin = 0.0, xmax = numberOfTimes + 1.0, ymin = 0.5, ymax = my numberOfStates + 0.5; Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); double r = 0.2 / (numberOfTimes > my numberOfStates ? numberOfTimes : my numberOfStates); for (long it = 1; it <= numberOfTimes; it++) { for (long js = 1; js <= my numberOfStates; js++) { double xc = it, yc = js, x2 = it, y2 = js; Graphics_circle (g, xc, yc, r); if (it > 1) { for (long is = 1; is <= my numberOfStates; is++) { bool indexedConnection = si -> classIndex[it - 1] == is && si -> classIndex[it] == js; Graphics_setLineWidth (g, indexedConnection ? 2.0 : 1.0); Graphics_setLineType (g, indexedConnection ? Graphics_DRAWN : Graphics_DOTTED); double x1 = it - 1, y1 = is; if (connect || indexedConnection) { double a = (y1 - y2) / (x1 - x2), b = y1 - a * x1; // double xs11 = x1 - r / (a * a + 1), ys11 = a * xs11 + b; double xs12 = x1 + r / (a * a + 1), ys12 = a * xs12 + b; double xs21 = x2 - r / (a * a + 1), ys21 = a * xs21 + b; // double xs22 = x2 + r / (a * a + 1), ys22 = a * xs22 + b; Graphics_line (g, xs12, ys12, xs21, ys21); } } } } } Graphics_unsetInner (g); Graphics_setLineWidth (g, 1.0); Graphics_setLineType (g, Graphics_DRAWN); if (garnish) { Graphics_drawInnerBox (g); for (long js = 1; js <= my numberOfStates; js++) { HMMState hmms = (HMMState) my states -> item[js]; Graphics_markLeft (g, js, false, false, false, hmms -> label); } Graphics_marksBottomEvery (g, 1.0, 1.0, true, true, false); Graphics_textBottom (g, true, U"Time index"); } } void HMM_drawBackwardProbabilitiesIllustration (Graphics g, bool garnish) { double xmin = 0.0, xmax = 1.0, ymin = 0.0, ymax = 1.0; Graphics_setWindow (g, xmin, xmax, ymin, ymax); double xleft = 0.1, xright = 0.9, r = 0.03; long np = 6; double dy = (1.0 - 0.3) / (np - 1); double x0 = xleft, y0 = 0.5; Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_circle (g, x0, y0, r); double x = xright, y = 0.9; for (long i = 1; i <= np; i++) { if (i < 4 or i == np) { Graphics_circle (g, x, y, r); double xx = x0 - x, yy = y - y0; double c = sqrt (xx * xx + yy * yy); double cosa = xx / c, sina = yy / c; Graphics_line (g, x0 - r * cosa, y0 + r * sina, x + r * cosa, y - r * sina); } else if (i == 4) { double ddy = 3*dy/4; Graphics_fillCircle (g, x, y + dy - ddy, 0.5 * r); Graphics_fillCircle (g, x, y + dy - 2 * ddy, 0.5 * r); Graphics_fillCircle (g, x, y + dy - 3 * ddy, 0.5 * r); } y -= dy; } if (garnish) { double x1 = xright + 1.5 * r, x2 = x1 - 0.2, y1 = 0.9; Graphics_setTextAlignment (g, Graphics_LEFT, Graphics_HALF); Graphics_text (g, x1, y1, U"%s__1_"); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); Graphics_text (g, x2, y1, U"%a__%i1_"); y1 = 0.9 - dy; Graphics_setTextAlignment (g, Graphics_LEFT, Graphics_HALF); Graphics_text (g, x1, y1, U"%s__2_"); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); Graphics_text (g, x2, y1, U"%a__%i2_"); y1 = 0.9 - (np - 1) * dy; Graphics_setTextAlignment (g, Graphics_LEFT, Graphics_HALF); Graphics_text (g, x1, y1, U"%s__%N_"); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); Graphics_text (g, x2, y1, U"%a__%%iN%_"); Graphics_setTextAlignment (g, Graphics_RIGHT, Graphics_HALF); Graphics_text (g, x0 - 1.5 * r, y0, U"%s__%i_"); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_BOTTOM); Graphics_text (g, x0, 0.0, U"%t"); Graphics_text (g, x, 0.0, U"%t+1"); double y3 = 0.10; Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); Graphics_text (g, x0, y3, U"%\\be__%t_(%i)%"); Graphics_text (g, x, y3, U"%\\be__%t+1_(%j)"); } } void HMM_drawForwardProbabilitiesIllustration (Graphics g, bool garnish) { double xmin = 0.0, xmax = 1.0, ymin = 0.0, ymax = 1.0; Graphics_setWindow (g, xmin, xmax, ymin, ymax); double xleft = 0.1, xright = 0.9, r = 0.03; long np = 6; double dy = (1.0 - 0.3) / (np - 1); double x0 = xright, y0 = 0.5; Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_circle (g, x0, y0, r); double x = xleft, y = 0.9; for (long i = 1; i <= np; i++) { if (i < 4 or i == np) { Graphics_circle (g, x, y, r); double xx = x0 - x, yy = y - y0; double c = sqrt (xx * xx + yy * yy); double cosa = xx / c, sina = yy / c; Graphics_line (g, x0 - r * cosa, y0 + r * sina, x + r * cosa, y - r * sina); } else if (i == 4) { double ddy = 3.0 * dy / 4.0; Graphics_fillCircle (g, x, y + dy - ddy, 0.5 * r); Graphics_fillCircle (g, x, y + dy - 2 * ddy, 0.5 * r); Graphics_fillCircle (g, x, y + dy - 3 * ddy, 0.5 * r); } y -= dy; } if (garnish) { double x1 = xleft - 1.5 * r, x2 = x1 + 0.2, y1 = 0.9; Graphics_setTextAlignment (g, Graphics_RIGHT, Graphics_HALF); Graphics_text (g, x1, y1, U"%s__1_"); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); Graphics_text (g, x2, y1, U"%a__1%j_"); y1 = 0.9 - dy; Graphics_setTextAlignment (g, Graphics_RIGHT, Graphics_HALF); Graphics_text (g, x1, y1, U"%s__2_"); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); Graphics_text (g, x2, y1, U"%a__2%j_"); y1 = 0.9 - (np - 1) * dy; Graphics_setTextAlignment (g, Graphics_RIGHT, Graphics_HALF); Graphics_text (g, x1, y1, U"%s__%N_"); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); Graphics_text (g, x2, y1, U"%a__%%Nj%_"); Graphics_setTextAlignment (g, Graphics_LEFT, Graphics_HALF); Graphics_text (g, x0 + 1.5 * r, y0, U"%s__%j_"); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_BOTTOM); Graphics_text (g, x, 0.0, U"%t"); Graphics_text (g, x0, 0.0, U"%t+1"); double y3 = 0.10; Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); Graphics_text (g, x, y3, U"%\\al__%t_(%i)%"); Graphics_text (g, x0, y3, U"%\\al__%t+1_(%j)"); } } void HMM_drawForwardAndBackwardProbabilitiesIllustration (Graphics g, bool garnish) { double xfrac = 0.1, xs = 1.0 / (0.5 - xfrac), r = 0.03; Graphics_Viewport vp = Graphics_insetViewport (g, 0.0, 0.5-xfrac, 0.0, 1.0); HMM_drawForwardProbabilitiesIllustration (g, false); Graphics_resetViewport (g, vp); Graphics_insetViewport (g, 0.5 + xfrac, 1.0, 0.0, 1.0); HMM_drawBackwardProbabilitiesIllustration (g, false); Graphics_resetViewport (g, vp); Graphics_setWindow (g, 0.0, xs, 0.0, 1.0); if (garnish) { double rx1 = 1.0 + xs * 2.0 * xfrac + 0.1, rx2 = rx1 + 0.9 - 0.1, y1 = 0.1; Graphics_line (g, 0.9 + r, 0.5, rx1 - r, 0.5); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_BOTTOM); Graphics_text (g, 0.9, 0.5 + r, U"%s__%i_"); Graphics_text (g, rx1, 0.5 + r, U"%s__%j_"); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_TOP); Graphics_text (g, 1.0 + xfrac * xs, 0.5, U"%a__%%ij%_%b__%j_(O__%t+1_)"); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_BOTTOM); Graphics_text (g, 0.1, 0.0, U"%t-1"); Graphics_text (g, 0.9, 0.0, U"%t"); Graphics_text (g, rx1, 0.0, U"%t+1"); Graphics_text (g, rx2, 0.0, U"%t+2"); Graphics_setLineType (g, Graphics_DASHED); double x4 = rx1 - 0.06, x3 = 0.9 + 0.06; Graphics_line (g, x3, 0.7, x3, 0.0); Graphics_line (g, x4, 0.7, x4, 0.0); Graphics_setLineType (g, Graphics_DRAWN); Graphics_arrow (g, x4, y1, x4 + 0.2, y1); Graphics_arrow (g, x3, y1, x3 - 0.2, y1); Graphics_setTextAlignment (g, Graphics_RIGHT, Graphics_BOTTOM); Graphics_text (g, x3 - 0.01, y1, U"\\al__%t_(i)"); Graphics_setTextAlignment (g, Graphics_LEFT, Graphics_BOTTOM); Graphics_text (g, x4 + 0.01, y1, U"\\be__%t+1_(j)"); } } void HMM_and_HMMBaumWelch_getXi (HMM me, HMMBaumWelch thee, long *obs) { for (long it = 1; it <= thy numberOfTimes - 1; it++) { double sum = 0.0; for (long is = 1; is <= thy numberOfStates; is++) { for (long js = 1; js <= thy numberOfStates; js++) { thy xi[it][is][js] = thy alpha[is][it] * thy beta[js][it + 1] * my transitionProbs[is][js] * my emissionProbs[js][ obs[it + 1] ]; sum += thy xi[it][is][js]; } } for (long is = 1; is <= my numberOfStates; is++) { for (long js = 1; js <= my numberOfStates; js++) { thy xi[it][is][js] /= sum; } } } } void HMM_and_HMMBaumWelch_addEstimate (HMM me, HMMBaumWelch thee, long *obs) { for (long is = 1; is <= my numberOfStates; is++) { // only for valid start states with p > 0 if (my transitionProbs[0][is] > 0.0) { thy aij_num[0][is] += thy gamma[is][1]; thy aij_denom[0][is] += 1.0; } } for (long is = 1; is <= my numberOfStates; is++) { double gammasum = 0.0; for (long it = 1; it <= thy numberOfTimes - 1; it++) { gammasum += thy gamma[is][it]; } for (long js = 1; js <= my numberOfStates; js++) { double xisum = 0.0; for (long it = 1; it <= thy numberOfTimes - 1; it++) { xisum += thy xi[it][is][js]; } // zero probs signal invalid connections, don't reestimate if (my transitionProbs[is][js] > 0.0) { thy aij_num[is][js] += xisum; thy aij_denom[is][js] += gammasum; } } /* Only reestimate the emissionProbs for a hidden markov model. A not hidden model is emulated with fixed emissionProbs. */ if (!my notHidden) { gammasum += thy gamma[is][thy numberOfTimes]; // Now sum all, add last term for (long k = 1; k <= my numberOfObservationSymbols; k++) { double gammasum_k = 0.0; for (long it = 1; it <= thy numberOfTimes; it++) { if (obs[it] == k) { gammasum_k += thy gamma[is][it]; } } // only reestimate probs > 0 ! if (my emissionProbs[is][k] > 0.0) { thy bik_num[is][k] += gammasum_k; thy bik_denom[is][k] += gammasum; } } } // For a left-to-right model the final state determines the transition prob to go to the END state if (my leftToRight) { thy aij_num[is][my numberOfStates + 1] += thy gamma[is][thy numberOfTimes]; thy aij_denom[is][my numberOfStates + 1] += 1.0; } } } void HMM_and_HMMBaumWelch_reestimate (HMM me, HMMBaumWelch thee) { double p; /* If we only have a couple of training sequences and they all happen to start with the same symbol, one or more starting probabilities can be zero. What to do with the P_k (see Rabiner formulas 109-110)? */ for (long is = 1; is <= my numberOfStates; is++) { /* If we have not enough observation sequences it can happen that some probabilities become zero. This means that for some future observation sequences the probability evaluation returns p=0 for sequences where these transitions turn up. This makes recognition impossible and also comparisons between models are difficult. We can prevent this from happening by asumimg a minimal probability for valid transitions i.e. which have initially p > 0. */ if (my transitionProbs[0][is] > 0.0) { p = thy aij_num[0][is] / thy aij_denom[0][is]; my transitionProbs[0][is] = p > 0.0 ? p : thy minProb; } for (long js = 1; js <= my numberOfStates; js++) { if (my transitionProbs[is][js] > 0.0) { p = thy aij_num[is][js] / thy aij_denom[is][js]; my transitionProbs[is][js] = p > 0.0 ? p : thy minProb; } } if (! my notHidden) { for (long k = 1; k <= my numberOfObservationSymbols; k++) { if (my emissionProbs[is][k] > 0.0) { p = thy bik_num[is][k] / thy bik_denom[is][k]; my emissionProbs[is][k] = p > 0.0 ? p : thy minProb; } } } if (my leftToRight && my transitionProbs[is][my numberOfStates + 1] > 0.0) { p = thy aij_num[is][my numberOfStates + 1] / thy aij_denom[is][my numberOfStates + 1]; my transitionProbs[is][my numberOfStates + 1] = p > 0.0 ? p : thy minProb; } } } void HMM_and_HMMBaumWelch_forward (HMM me, HMMBaumWelch thee, long *obs) { // initialise at t = 1 & scale thy scale[1] = 0.0; for (long js = 1; js <= my numberOfStates; js++) { thy alpha[js][1] = my transitionProbs[0][js] * my emissionProbs[js][ obs[1] ]; thy scale[1] += thy alpha[js][1]; } for (long js = 1; js <= my numberOfStates; js++) { thy alpha[js][1] /= thy scale[1]; } // recursion for (long it = 2; it <= thy numberOfTimes; it++) { thy scale[it] = 0.0; for (long js = 1; js <= my numberOfStates; js++) { double sum = 0.0; for (long is = 1; is <= my numberOfStates; is++) { sum += thy alpha[is][it - 1] * my transitionProbs[is][js]; } thy alpha[js][it] = sum * my emissionProbs[js][ obs[it] ]; thy scale[it] += thy alpha[js][it]; } for (long js = 1; js <= my numberOfStates; js++) { thy alpha[js][it] /= thy scale[it]; } } for (long it = 1; it <= thy numberOfTimes; it++) { thy lnProb += log (thy scale[it]); } } void HMM_and_HMMBaumWelch_backward (HMM me, HMMBaumWelch thee, long *obs) { for (long is = 1; is <= my numberOfStates; is++) { thy beta[is][thy numberOfTimes] = 1.0 / thy scale[thy numberOfTimes]; } for (long it = thy numberOfTimes - 1; it >= 1; it--) { for (long is = 1; is <= my numberOfStates; is++) { double sum = 0.0; for (long js = 1; js <= my numberOfStates; js++) { sum += thy beta[js][it + 1] * my transitionProbs[is][js] * my emissionProbs[js][ obs[it + 1] ]; } thy beta[is][it] = sum / thy scale[it]; } } } /*************************** HMM decoding ***********************************/ // precondition: valid symbols, i.e. 1 <= o[i] <= my numberOfSymbols for i=1..nt void HMM_and_HMMViterbi_decode (HMM me, HMMViterbi thee, long *obs) { long ntimes = thy numberOfTimes; // initialisation for (long is = 1; is <= my numberOfStates; is++) { thy viterbi[is][1] = my transitionProbs[0][is] * my emissionProbs[is][ obs[1] ]; thy bp[is][1] = 0; } // recursion for (long it = 2; it <= ntimes; it++) { for (long is = 1; is <= my numberOfStates; is++) { // all transitions isp -> is from previous time to current double max_score = -1; // any negative number is ok for (long isp = 1; isp <= my numberOfStates; isp++) { double score = thy viterbi[isp][it - 1] * my transitionProbs[isp][is]; // * my emissionProbs[is][ obs[it] ] if (score > max_score) { max_score = score; thy bp[is][it] = isp; } } thy viterbi[is][it] = max_score * my emissionProbs[is][ obs[it] ]; } } // path starts at state with best end probability thy path[ntimes] = 1; thy prob = thy viterbi[1][ntimes]; for (long is = 2; is <= my numberOfStates; is++) { if (thy viterbi[is][ntimes] > thy prob) { thy prob = thy viterbi[ thy path[ntimes] = is ][ntimes]; } } // trace back and get path for (long it = ntimes; it > 1; it--) { thy path[it - 1] = thy bp[ thy path[it] ][it]; } } autoHMMStateSequence HMM_and_HMMObservationSequence_to_HMMStateSequence (HMM me, HMMObservationSequence thee) { try { autoStringsIndex si = HMM_and_HMMObservationSequence_to_StringsIndex (me, thee); long *obs = si -> classIndex; // convenience long numberOfUnknowns = StringsIndex_countItems (si.peek(), 0); if (numberOfUnknowns > 0) { Melder_throw (U"Unknown observation symbol(s) (# = ", numberOfUnknowns, U")."); } long numberOfTimes = thy rows -> size; autoHMMViterbi v = HMM_to_HMMViterbi (me, obs, numberOfTimes); autoHMMStateSequence him = HMMStateSequence_create (numberOfTimes); // trace the path and get states for (long it = 1; it <= numberOfTimes; it++) { HMMState hmms = (HMMState) my states -> item[ v -> path[it] ]; his strings [it] = Melder_dup (hmms -> label); his numberOfStrings ++; } return him; } catch (MelderError) { Melder_throw (me, U": no HMMStateSequence created."); } } double HMM_and_HMMStateSequence_getProbability (HMM me, HMMStateSequence thee) { autoStringsIndex si = HMM_and_HMMStateSequence_to_StringsIndex (me, thee); long numberOfUnknowns = StringsIndex_countItems (si.peek(), 0); long *index = si -> classIndex; if (index == 0) { return NUMundefined; } if (numberOfUnknowns > 0) { Melder_warning (U"Unknown states (# = ", numberOfUnknowns, U")."); return NUMundefined; } double p0 = my transitionProbs [0][ index[1] ]; if (p0 == 0) { Melder_throw (U"You cannot start with this state."); } double lnp = log (p0); for (long it = 2; it <= thy numberOfStrings; it++) { lnp += log (my transitionProbs[ index[it - 1] ] [ index[it] ]); } return lnp; } double HMM_getProbabilityAtTimeBeingInState (HMM me, long itime, long istate) { if (istate < 1 || istate > my numberOfStates) { return NUMundefined; } autoNUMvector scale (1, itime); autoNUMvector alpha_t (1, my numberOfStates); autoNUMvector alpha_tm1 (1, my numberOfStates); for (long js = 1; js <= my numberOfStates; js++) { alpha_t[js] = my transitionProbs[0][js]; scale[1] += alpha_t[js]; } for (long js = 1; js <= my numberOfStates; js++) { alpha_t[js] /= scale[1]; } // recursion for (long it = 2; it <= itime; it++) { for (long js = 1; js <= my numberOfStates; js++) { alpha_tm1[js] = alpha_t[js]; } for (long js = 1; js <= my numberOfStates; js++) { double sum = 0.0; for (long is = 1; is <= my numberOfStates; is++) { sum += alpha_tm1[is] * my transitionProbs[is][js]; } alpha_t[js] = sum; scale[it] += alpha_t[js]; } for (long js = 1; js <= my numberOfStates; js++) { alpha_t[js] /= scale[it]; } } double lnp = 0.0; for (long it = 1; it <= itime; it++) { lnp += log (scale[it]); } lnp = alpha_t[istate] > 0 ? lnp + log (alpha_t[istate]) : -INFINITY; // p = 0 -> ln(p)=-infinity return lnp; } double HMM_getProbabilityAtTimeBeingInStateEmittingSymbol (HMM me, long itime, long istate, long isymbol) { // for a notHidden model emissionProbs may be zero! if (isymbol < 1 || isymbol > my numberOfObservationSymbols || my emissionProbs[istate][isymbol] == 0) { return NUMundefined; } double lnp = HMM_getProbabilityAtTimeBeingInState (me, itime, istate); return lnp != NUMundefined && lnp != -INFINITY ? lnp + log (my emissionProbs[istate][isymbol]) : lnp; } double HMM_getProbabilityOfObservations (HMM me, long *obs, long numberOfTimes) { autoNUMvector scale (1, numberOfTimes); autoNUMvector alpha_t (1, my numberOfStates); autoNUMvector alpha_tm1 (1, my numberOfStates); // initialise for (long js = 1; js <= my numberOfStates; js++) { alpha_t[js] = my transitionProbs[0][js] * my emissionProbs[js][ obs[1] ]; scale[1] += alpha_t[js]; } if (scale[1] == 0) { Melder_throw (U"The observation sequence starts with a symbol which state has starting probability zero."); } for (long js = 1; js <= my numberOfStates; js++) { alpha_t[js] /= scale[1]; } // recursion for (long it = 2; it <= numberOfTimes; it++) { for (long js = 1; js <= my numberOfStates; js++) { alpha_tm1[js] = alpha_t[js]; } for (long js = 1; js <= my numberOfStates; js++) { double sum = 0.0; for (long is = 1; is <= my numberOfStates; is++) { sum += alpha_tm1[is] * my transitionProbs[is][js]; } alpha_t[js] = sum * my emissionProbs[js][ obs[it] ]; scale[it] += alpha_t[js]; } if (scale[it] <= 0) { return -INFINITY; } for (long js = 1; js <= my numberOfStates; js++) { alpha_t[js] /= scale[it]; } } double lnp = 0; for (long it = 1; it <= numberOfTimes; it++) { lnp += log (scale[it]); } return lnp; } double HMM_and_HMMObservationSequence_getProbability (HMM me, HMMObservationSequence thee) { autoStringsIndex si = HMM_and_HMMObservationSequence_to_StringsIndex (me, thee); long *index = si -> classIndex; long numberOfUnknowns = StringsIndex_countItems (si.peek(), 0); if (numberOfUnknowns > 0) { Melder_throw (U"Unknown observations (# = ", numberOfUnknowns, U")."); } return HMM_getProbabilityOfObservations (me, index, thy rows -> size); } double HMM_and_HMMObservationSequence_getCrossEntropy (HMM me, HMMObservationSequence thee) { double lnp = HMM_and_HMMObservationSequence_getProbability (me, thee); return lnp == NUMundefined ? NUMundefined : (lnp == -INFINITY ? INFINITY : -lnp / (NUMln10 * HMMObservationSequence_getNumberOfObservations (thee))); } double HMM_and_HMMObservationSequence_getPerplexity (HMM me, HMMObservationSequence thee) { double ce = HMM_and_HMMObservationSequence_getCrossEntropy (me, thee); return ce == NUMundefined ? NUMundefined : (ce == INFINITY ? INFINITY : pow (2, ce)); } autoHMM HMM_createFromHMMObservationSequence (HMMObservationSequence me, long numberOfStates, int leftToRight) { try { autoHMM thee = Thing_new (HMM); autoStrings s = HMMObservationSequence_to_Strings (me); autoDistributions d = Strings_to_Distributions (s.peek()); long numberOfObservationSymbols = d -> numberOfRows; thy notHidden = numberOfStates < 1; numberOfStates = numberOfStates > 0 ? numberOfStates : numberOfObservationSymbols; HMM_init (thee.peek(), numberOfStates, numberOfObservationSymbols, leftToRight); for (long i = 1; i <= numberOfObservationSymbols; i++) { const char32 *label = d -> rowLabels[i]; autoHMMObservation hmmo = HMMObservation_create (label, 0, 0, 0); HMM_addObservation (thee.peek(), hmmo.transfer()); if (thy notHidden) { autoHMMState hmms = HMMState_create (label); HMM_addState (thee.peek(), hmms.transfer()); } } if (! thy notHidden) { HMM_setDefaultStates (thee.peek()); } HMM_setDefaultTransitionProbs (thee.peek()); HMM_setDefaultStartProbs (thee.peek()); HMM_setDefaultEmissionProbs (thee.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": no HMM created."); } } autoTableOfReal HMMObservationSequence_to_TableOfReal_transitions (HMMObservationSequence me, int probabilities) { try { autoStrings thee = HMMObservationSequence_to_Strings (me); autoTableOfReal him = Strings_to_TableOfReal_transitions (thee.peek(), probabilities); return him; } catch (MelderError) { Melder_throw (me, U": no transitions created."); } } autoStringsIndex HMM_and_HMMObservationSequence_to_StringsIndex (HMM me, HMMObservationSequence thee) { try { autoStrings classes = Thing_new (Strings); classes -> strings = NUMvector (1, my numberOfObservationSymbols); for (long is = 1; is <= my numberOfObservationSymbols; is++) { HMMObservation hmmo = (HMMObservation) my observationSymbols -> item[is]; classes -> strings[is] = Melder_dup (hmmo -> label); (classes -> numberOfStrings) ++; } autoStrings obs = HMMObservationSequence_to_Strings (thee); autoStringsIndex him = Stringses_to_StringsIndex (obs.peek(), classes.peek()); return him; } catch (MelderError) { Melder_throw (me, U": no StringsIndex created."); } } autoStringsIndex HMM_and_HMMStateSequence_to_StringsIndex (HMM me, HMMStateSequence thee) { try { autoStrings classes = Thing_new (Strings); classes -> strings = NUMvector (1, my numberOfObservationSymbols); for (long is = 1; is <= my numberOfStates; is++) { HMMState hmms = (HMMState) my states -> item[is]; classes -> strings[is] = Melder_dup (hmms -> label); (classes -> numberOfStrings) ++; } autoStrings sts = HMMStateSequence_to_Strings (thee); autoStringsIndex him = Stringses_to_StringsIndex (sts.peek(), classes.peek()); return him; } catch (MelderError) { Melder_throw (me, U": no StringsIndex created."); } } autoTableOfReal HMM_and_HMMObservationSequence_to_TableOfReal_transitions (HMM me, HMMObservationSequence thee, int probabilities) { try { autoStringsIndex si = HMM_and_HMMObservationSequence_to_StringsIndex (me, thee); autoTableOfReal him = StringsIndex_to_TableOfReal_transitions (si.peek(), probabilities); return him; } catch (MelderError) { Melder_throw (me, U": no transition table created for HMMObservationSequence."); } } autoTableOfReal HMM_and_HMMStateSequence_to_TableOfReal_transitions (HMM me, HMMStateSequence thee, int probabilities) { try { autoStringsIndex si = HMM_and_HMMStateSequence_to_StringsIndex (me, thee); autoTableOfReal him = StringsIndex_to_TableOfReal_transitions (si.peek(), probabilities); return him; } catch (MelderError) { Melder_throw (me, U": no transition table created for HMMStateSequence."); } } autoTableOfReal StringsIndex_to_TableOfReal_transitions (StringsIndex me, int probabilities) { try { long numberOfTypes = my classes -> size; autoTableOfReal thee = TableOfReal_create (numberOfTypes + 1, numberOfTypes + 1); for (long i = 1; i <= numberOfTypes; i++) { SimpleString s = (SimpleString) my classes -> item[i]; TableOfReal_setRowLabel (thee.peek(), i, s -> string); TableOfReal_setColumnLabel (thee.peek(), i, s -> string); } for (long i = 2; i <= my numberOfElements; i++) { if (my classIndex[i - 1] > 0 && my classIndex[i] > 0) { // a zero is a restart! thy data [my classIndex[i - 1]][my classIndex[i]] ++; } } double sum = 0; for (long i = 1; i <= numberOfTypes; i++) { double rowSum = 0, colSum = 0; for (long j = 1; j <= numberOfTypes; j++) { rowSum += thy data[i][j]; } thy data[i][numberOfTypes + 1] = rowSum; for (long j = 1; j <= numberOfTypes; j++) { colSum += thy data[j][i]; } thy data[numberOfTypes + 1][i] = colSum; sum += colSum; } thy data[numberOfTypes + 1][numberOfTypes + 1] = sum; if (probabilities && sum > 0) { for (long i = 1; i <= numberOfTypes; i++) { if (thy data[i][numberOfTypes + 1] > 0) { for (long j = 1; j <= numberOfTypes; j++) { thy data[i][j] /= thy data[i][numberOfTypes + 1]; } } } for (long i = 1; i <= numberOfTypes; i++) { thy data[i][numberOfTypes + 1] /= sum; thy data[numberOfTypes + 1][i] /= sum; } } return thee; } catch (MelderError) { Melder_throw (me, U": no transition table created."); } } autoTableOfReal Strings_to_TableOfReal_transitions (Strings me, int probabilities) { try { autoStringsIndex him = Strings_to_StringsIndex (me); autoTableOfReal thee = StringsIndex_to_TableOfReal_transitions (him.peek(), probabilities); return thee; } catch (MelderError) { Melder_throw (me, U": no transition table created."); } } /* End of file HMM.cpp */ praat-6.0.04/dwtools/HMM.h000066400000000000000000000147311261542461700152130ustar00rootroot00000000000000#ifndef _HMM_h_ #define _HMM_h_ /* HMM.h * * Copyright (C) 2010-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Strings_extensions.h" #include "TableOfReal.h" #include "Collection.h" #include "GaussianMixture.h" #include "SSCP.h" #include "Index.h" #include "HMM_def.h" oo_CLASS_CREATE (HMMState, Daata); oo_CLASS_CREATE (HMMObservation, Daata); oo_CLASS_CREATE (HMMViterbi, Daata); oo_CLASS_CREATE (HMM, Daata); Thing_define (HMMBaumWelch, Daata) { // new data: public: long capacity; long numberOfTimes; long totalNumberOfSequences; long numberOfStates; long numberOfSymbols; double lnProb; double minProb; double **alpha; double **beta; double *scale; double **gamma; double ***xi; double **aij_num, **aij_denom; double **bik_num, **bik_denom; // overridden methods: virtual void v_destroy (); }; Thing_define (HMMStateSequence, Strings) { }; Thing_define (HMMObservationSequence, Table) { }; // First column is always a symbol, if only 1 column then symbols only Thing_define (HMMObservationSequences, Collection) { }; autoHMMObservationSequence HMMObservationSequence_create (long numberOfItems, long dataLength); void HMMObservationSequence_removeObservation (HMMObservationSequence me, long index); autoStrings HMMObservationSequence_to_Strings (HMMObservationSequence me); autoHMMObservationSequence Strings_to_HMMObservationSequence (Strings me); autoStringsIndex HMMObservationSequence_to_StringsIndex (HMMObservationSequence me); autoStringsIndex HMM_and_HMMObservationSequence_to_StringsIndex (HMM me, HMMObservationSequence thee); autoTableOfReal HMMObservationSequence_to_TableOfReal_transitions (HMMObservationSequence me, int probabilities); autoTableOfReal HMM_and_HMMObservationSequence_to_TableOfReal_transitions (HMM me, HMMObservationSequence thee, int probabilities); autoHMMObservationSequences HMMObservationSequences_create (); long HMMObservationSequence_getNumberOfObservations (HMMObservationSequence me); long HMMObservationSequences_getLongestSequence (HMMObservationSequences me); autoTableOfReal HMMStateSequence_to_TableOfReal_transitions (HMMStateSequence me); autoTableOfReal HMM_and_HMMStateSequence_to_TableOfReal_transitions (HMM me, HMMStateSequence thee, int probabilities); autoHMMStateSequence HMMStateSequence_create (long numberOfItems); autoStrings HMMStateSequence_to_Strings (HMMStateSequence me); void HMMState_setLabel (HMMState me, char32 *label); autoHMM HMM_create (int leftToRight, long numberOfStates, long numberOfObservationSymbols); autoHMM HMM_createSimple (int leftToRight, const char32 *states_string, const char32 *symbols_string); autoHMM HMM_createContinuousModel (int leftToRight, long numberOfStates, long numberOfObservationSymbols, long numberOfMixtureComponentsPerSymbol, long componentDimension, long componentStorage); autoHMM HMM_createFullContinuousModel (int leftToRight, long numberOfStates, long numberOfObservationSymbols, long numberOfFeatureStreams, long *dimensionOfStream, long *numberOfGaussiansforStream); autoHMM HMM_createFromHMMObservationSequence (HMMObservationSequence me, long numberOfStates, int leftToRight); void HMM_draw (HMM me, Graphics g, int garnish); void HMM_drawBackwardProbabilitiesIllustration (Graphics g, bool garnish); void HMM_drawForwardProbabilitiesIllustration (Graphics g, bool garnish); void HMM_drawForwardAndBackwardProbabilitiesIllustration (Graphics g, bool garnish); void HMM_addObservation (HMM me, thou); void HMM_addState (HMM me, thou); void HMM_setDefaultStates (HMM me); void HMM_setDefaultObservations (HMM me); void HMM_setDefaultTransitionProbs (HMM me); void HMM_setDefaultStartProbs (HMM me); void HMM_setDefaultEmissionProbs (HMM me); void HMM_setDefaultMixingProbabilities (HMM me); void HMM_unExpandPCA (HMM me); /* Unexpand all the PCA's in the gaussian mixtures */ /* Set the probabilities. A probability zero value indicates that this p cannot be changed during training/learning. */ void HMM_setTransitionProbabilities (HMM me, long state_number, char32 *state_probs); void HMM_setEmissionProbabilities (HMM me, long state_number, char32 *emission_probs); void HMM_setStartProbabilities (HMM me, char32 *probs); double HMM_getProbabilityAtTimeBeingInState (HMM me, long itime, long istate); double HMM_getProbabilityAtTimeBeingInStateEmittingSymbol (HMM me, long itime, long istate, long isymbol); double HMM_getExpectedValueOfDurationInState (HMM me, long istate); double HMM_getProbabilityOfStayingInState (HMM me, long istate, long numberOfTimeUnits); double HMM_and_HMM_getCrossEntropy (HMM me, HMM thee, long observationLength, int symmetric); double HMM_and_HMM_and_HMMObservationSequence_getCrossEntropy (HMM me, HMM thee, HMMObservationSequence him); autoTableOfReal HMM_extractTransitionProbabilities (HMM me); autoTableOfReal HMM_extractEmissionProbabilities (HMM me); /* HMM & HMMObservationSequence ****/ autoHMMObservationSequence HMM_to_HMMObservationSequence (HMM me, long initialState, long numberOfItems); autoHMMStateSequence HMM_and_HMMObservationSequence_to_HMMStateSequence (HMM me, HMMObservationSequence thee); double HMM_and_HMMStateSequence_getProbability (HMM me, HMMStateSequence thee); void HMM_and_HMMObservationSequences_learn (HMM me, HMMObservationSequences thee, double delta_lnp, double minProb, int info); void HMM_and_HMMStateSequence_drawTrellis (HMM me, HMMStateSequence thee, Graphics g, int connect, int garnish); double HMM_and_HMMObservationSequence_getProbability (HMM me, HMMObservationSequence thee); double HMM_and_HMMObservationSequence_getCrossEntropy (HMM me, HMMObservationSequence thee); double HMM_and_HMMObservationSequence_getPerplexity (HMM me, HMMObservationSequence thee); // somewhere else void MelderInfo_lnp (double logp); autoTableOfReal Strings_to_TableOfReal_transitions (Strings me, int probabilities); #endif /* _HMM_h_ */ praat-6.0.04/dwtools/HMM_def.h000066400000000000000000000041611261542461700160250ustar00rootroot00000000000000/* HMM_def.h * * Copyright (C) 2010-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20100929 Initial definition. djmw 20110329 oo_STRINGW -> oo_STRING */ #define ooSTRUCT HMMState oo_DEFINE_CLASS (HMMState, Daata) oo_STRING(label) oo_END_CLASS(HMMState) #undef ooSTRUCT #define ooSTRUCT HMMObservation oo_DEFINE_CLASS (HMMObservation, Daata) oo_STRING(label) oo_AUTO_OBJECT (GaussianMixture, 1, gm) oo_END_CLASS(HMMObservation) #undef ooSTRUCT #define ooSTRUCT HMM oo_DEFINE_CLASS (HMM, Daata) oo_INT (notHidden) // to model a Markov model instead of HMM oo_INT (leftToRight) oo_LONG (numberOfStates) oo_LONG (numberOfObservationSymbols) oo_LONG (numberOfMixtureComponents) oo_LONG (componentDimension) oo_INT (componentStorage) oo_DOUBLE_MATRIX_FROM (transitionProbs, 0, numberOfStates, 1, numberOfStates + 1) // row 0: initial probabilities oo_DOUBLE_MATRIX (emissionProbs, numberOfStates, numberOfObservationSymbols) oo_OBJECT (Ordered, 1, states) oo_OBJECT (Ordered, 1, observationSymbols) #if oo_DECLARING void v_info () override; #endif oo_END_CLASS(HMM) #undef ooSTRUCT #define ooSTRUCT HMMViterbi oo_DEFINE_CLASS (HMMViterbi, Daata) oo_LONG (numberOfTimes) oo_LONG (numberOfStates) oo_DOUBLE (prob) oo_DOUBLE_MATRIX (viterbi, numberOfStates, numberOfTimes) oo_LONG_MATRIX (bp, numberOfStates, numberOfTimes) oo_LONG_VECTOR (path, numberOfTimes) oo_END_CLASS(HMMViterbi) #undef ooSTRUCT /* End of file HMM_def.h */ praat-6.0.04/dwtools/ICA.cpp000066400000000000000000001035211261542461700155150ustar00rootroot00000000000000/* ICA.c * * Copyright (C) 2010-2012 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20101202 Initial version djmw 20110304 Thing_new */ #include "ICA.h" #include "Interpreter.h" #include "NUM2.h" #include "Sound_and_PCA.h" #include "SVD.h" // matrix multiply R = V*C*V', V is nrv x ncv, C is ncv x ncv, R is nrv x nrv static void NUMdmatrices_multiply_VCVp (double **r, double **v, long nrv, long ncv, double **c, int csym) { for (long i = 1; i <= nrv; i++) { long jstart = csym ? i : 1; for (long j = jstart; j <= nrv; j++) { // V_ik C_kl V'_lj = V_ik C_kl V_jl double vcv = 0; for (long k = 1; k <= ncv; k++) { for (long l = 1; l <= ncv; l++) { vcv += v[i][k] * c[k][l] * v[j][l]; } } r[i][j] = vcv; if (csym) { r[j][i] = vcv; } } } } // matrix multiply R = V'*C*V, V is nrv x ncv, C is ncv x ncv, R is nrv x nrv static void NUMdmatrices_multiply_VpCV (double **r, double **v, long nrv, long ncv, double **c, int csym) { for (long i = 1; i <= ncv; i++) { long jstart = csym ? i : 1; for (long j = jstart; j <= ncv; j++) { // V'_ik C_kl V_lj = V_ki C_kl V_lj double vcv = 0; for (long k = 1; k <= nrv; k++) { for (long l = 1; l <= ncv; l++) { vcv += v[k][i] * c[k][l] * v[l][j]; } } r[i][j] = vcv; if (csym) { r[j][i] = vcv; } } } } // matrix multiply V*C, V is nrv x ncv, C is ncv x ncc, R is nrv x ncc; static void NUMdmatrices_multiply_VC (double **r, double **v, long nrv, long ncv, double **c, long ncc) { for (long i = 1; i <= nrv; i++) { for (long j = 1; j <= ncc; j++) { // V_ik C_kj double vc = 0; for (long k = 1; k <= ncv; k++) { vc += v[i][k] * c[k][j]; } r[i][j] = vc; } } } // matrix multiply V'*C, V is nrv x ncv, C is nrv x ncc, R is ncv x ncc; static void NUMdmatrices_multiply_VpC (double **r, double **v, long nrv, long ncv, double **c, long ncc) { for (long i = 1; i <= ncv; i++) { for (long j = 1; j <= ncc; j++) { // V'_ik C_kj double vc = 0; for (long k = 1; k <= nrv; k++) { vc += v[k][i] * c[k][j]; } r[i][j] = vc; } } } // D += scalef * M * M', M = nrm x ncm, D is nrm x nrm static void NUMdmatrices_multiplyScaleAdd (double **r, double **m, long nrm, long ncm, double scalef) { for (long i = 1; i <= nrm; i++) { for (long j = 1; j <= nrm; j++) { // M_ik M'_kj = M_ik M_jk double mm = 0; for (long k = 1; k <= ncm; k++) { mm += m[i][k] * m[j][k]; } r[i][j] += scalef * mm; } } } /* d = diag(diag(W'*C0*W)); W = W*d^(-1/2); D_ij = W'_ik C_kl W_lj => D_ii = W_ki C_kl W_li */ static void NUMdmatrix_normalizeColumnVectors (double **w, long nrw, long ncw, double **c) { for (long i = 1; i <= ncw; i++) { double di = 0; for (long k = 1; k <= ncw; k++) for (long l = 1; l <= nrw; l++) { di += w[k][i] * c[k][l] * w[l][i]; } di = 1 / sqrt (di); for (long j = 1; j <= nrw; j++) { w[j][i] *= di; } } } static double NUMdmatrix_diagonalityMeasure (double **v, long dimension) { double dmsq = 0; if (dimension < 2) { return 0; } for (long i = 1; i <= dimension; i++) { for (long j = 1; j <= dimension; j++) { if (i != j) { dmsq += v[i][j] * v[i][j]; } } } return dmsq / (dimension * (dimension - 1)); } static double NUMdmatrix_diagonalityIndex (double **v, long dimension) { double dindex = 0; for (long irow = 1; irow <= dimension; irow++) { double rowmax = fabs (v[irow][1]), rowsum = 0; for (long icol = 2; icol <= dimension; icol++) { if (fabs (v[irow][icol]) > rowmax) { rowmax = fabs (v[irow][icol]); } } for (long icol = 1; icol <= dimension; icol++) { rowsum += fabs (v[irow][icol]) / rowmax; } dindex += rowsum - 1; } for (long icol = 1; icol <= dimension; icol++) { double colmax = fabs (v[icol][1]), colsum = 0; for (long irow = 2; irow <= dimension; irow++) { if (fabs (v[irow][icol]) > colmax) { colmax = fabs (v[irow][icol]); } } for (long irow = 1; irow <= dimension; irow++) { colsum += fabs (v[irow][icol]) / colmax; } dindex += colsum - 1; } return dindex; } /* This routine is modeled after qdiag.m from Andreas Ziehe, Pavel Laskov, Guido Nolte, Klaus-Robert Müller, A Fast Algorithm for Joint Diagonalization with Non-orthogonal Transformations and its Application to Blind Source Separation, Journal of Machine Learning Research 5 (2004), 777–800. */ static void Diagonalizer_and_CrossCorrelationTables_ffdiag (Diagonalizer me, CrossCorrelationTables thee, long maxNumberOfIterations, double delta) { try { long iter = 0, dimension = my numberOfRows; double **v = my data; autoCrossCorrelationTables ccts = CrossCorrelationTables_and_Diagonalizer_diagonalize (thee, me); autoNUMmatrix w (1, dimension, 1, dimension); autoNUMmatrix vnew (1, dimension, 1, dimension); autoNUMmatrix cc (1, dimension, 1, dimension); for (long i = 1; i <= dimension; i++) { w[i][i] = 1; } autoMelderProgress progress (U"Simultaneous diagonalization of many CrossCorrelationTables..."); double dm_new = CrossCorrelationTables_getDiagonalityMeasure (ccts.peek(), nullptr, 0, 0); try { double dm_old, theta = 1, dm_start = dm_new; do { dm_old = dm_new; for (long i = 1; i <= dimension; i++) { for (long j = i + 1; j <= dimension; j++) { double zii = 0, zij = 0, zjj = 0, yij = 0, yji = 0; // zij = zji for (long k = 1; k <= ccts -> size; k++) { CrossCorrelationTable ct = (CrossCorrelationTable) ccts -> item [k]; zii += ct -> data[i][i] * ct -> data[i][i]; zij += ct -> data[i][i] * ct -> data[j][j]; zjj += ct -> data[j][j] * ct -> data[j][j]; yij += ct -> data[j][j] * ct -> data[i][j]; yji += ct -> data[i][i] * ct -> data[i][j]; } double denom = zjj * zii - zij * zij; if (denom != 0) { w[i][j] = (zij * yji - zii * yij) / denom; w[j][i] = (zij * yij - zjj * yji) / denom; } } } double norma = 0; for (long i = 1; i <= dimension; i++) { double normai = 0; for (long j = 1; j <= dimension; j++) { if (i != j) { normai += fabs (w[i][j]); } } if (normai > norma) { norma = normai; } } // evaluate the norm if (norma > theta) { double normf = 0; for (long i = 1; i <= dimension; i++) for (long j = 1; j <= dimension; j++) if (i != j) { normf += w[i][j] * w[i][j]; } double scalef = theta / sqrt (normf); for (long i = 1; i <= dimension; i++) { for (long j = 1; j <= dimension; j++) { if (i != j) { w[i][j] *= scalef; } } } } // update V NUMmatrix_copyElements (v, vnew.peek(), 1, dimension, 1, dimension); NUMdmatrices_multiply_VC (v, w.peek(), dimension, dimension, vnew.peek(), dimension); for (long k = 1; k <= ccts -> size; k++) { CrossCorrelationTable ct = (CrossCorrelationTable) ccts -> item[k]; NUMmatrix_copyElements (ct -> data, cc.peek(), 1, dimension, 1, dimension); NUMdmatrices_multiply_VCVp (ct -> data, w.peek(), dimension, dimension, cc.peek(), 1); } dm_new = CrossCorrelationTables_getDiagonalityMeasure (ccts.peek(), 0, 0, 0); iter++; Melder_progress ((double) iter / (double) maxNumberOfIterations, U"Iteration: ", iter, U", measure: ", dm_new, U"\n fractional measure: ", dm_new / dm_start); } while (fabs ((dm_old - dm_new) / dm_new) > delta && iter < maxNumberOfIterations); } catch (MelderError) { Melder_clearError (); } } catch (MelderError) { Melder_throw (me, U" & ", thee, U": no joint diagonalization (ffdiag)."); } } /* The folowing two routines are modeled after qdiag.m from R. Vollgraf and K. Obermayer, Quadratic Optimization for Simultaneous Matrix Diagonalization, IEEE Transaction on Signal Processing, 2006, */ static void update_one_column (CrossCorrelationTables me, double **d, double *wp, double *wvec, double scalef, double *work) { long dimension = ( (CrossCorrelationTable) (my item[1])) -> numberOfColumns; for (long ic = 2; ic <= my size; ic++) { // exclude C0 SSCP cov = (SSCP) my item[ic]; double **c = cov -> data; // m1 = C * wvec for (long i = 1; i <= dimension; i++) { double r = 0; for (long j = 1; j <= dimension; j++) { r += c[i][j] * wvec[j]; } work[i] = r; } // D = D +/- 2*p(t)*(m1*m1'); for (long i = 1; i <= dimension; i++) { for (long j = 1; j <= dimension; j++) { d[i][j] += 2 * scalef * wp[ic] * work[i] * work[j]; } } } } static void Diagonalizer_and_CrossCorrelationTable_qdiag (Diagonalizer me, CrossCorrelationTables thee, double *cweights, long maxNumberOfIterations, double delta) { try { CrossCorrelationTable c0 = (CrossCorrelationTable) thy item[1]; double **w = my data; long dimension = c0 -> numberOfColumns; autoEigen eigen = Thing_new (Eigen); autoCrossCorrelationTables ccts = Data_copy (thee); autoNUMmatrix pinv (1, dimension, 1, dimension); autoNUMmatrix d (1, dimension, 1, dimension); autoNUMmatrix p (1, dimension, 1, dimension); autoNUMmatrix m1 (1, dimension, 1, dimension); autoNUMmatrix wc (1, dimension, 1, dimension); autoNUMvector wvec (1, dimension); autoNUMvector wnew (1, dimension); autoNUMvector mvec (1, dimension); for (long i = 1; i <= dimension; i++) // Transpose W for (long j = 1; j <= dimension; j++) { wc[i][j] = w[j][i]; } // d = diag(diag(W'*C0*W)); // W = W*d^(-1/2); NUMdmatrix_normalizeColumnVectors (wc.peek(), dimension, dimension, c0 -> data); // scale eigenvectors for sphering // [vb,db] = eig(C0); // P = db^(-1/2)*vb'; Eigen_initFromSymmetricMatrix (eigen.peek(), c0 -> data, dimension); for (long i = 1; i <= dimension; i++) { if (eigen -> eigenvalues[i] < 0) { Melder_throw (U"Covariance matrix not positive definite, eigenvalue[", i, U"] is negative."); } double scalef = 1 / sqrt (eigen -> eigenvalues[i]); for (long j = 1; j <= dimension; j++) { p[dimension - i + 1][j] = scalef * eigen -> eigenvectors[i][j]; } } // P*C[i]*P' for (long ic = 1; ic <= thy size; ic++) { CrossCorrelationTable cov1 = (CrossCorrelationTable) thy item[ic]; CrossCorrelationTable cov2 = (CrossCorrelationTable) ccts -> item[ic]; NUMdmatrices_multiply_VCVp (cov2 -> data, p.peek(), dimension, dimension, cov1 -> data, 1); } // W = P'\W == inv(P') * W NUMpseudoInverse (p.peek(), dimension, dimension, pinv.peek(), 0); NUMdmatrices_multiply_VpC (w, pinv.peek(), dimension, dimension, wc.peek(), dimension); // initialisation for order KN^3 for (long ic = 2; ic <= thy size; ic++) { CrossCorrelationTable cov = (CrossCorrelationTable) ccts -> item[ic]; // C * W NUMdmatrices_multiply_VC (m1.peek(), cov -> data, dimension, dimension, w, dimension); // D += scalef * M1*M1' NUMdmatrices_multiplyScaleAdd (d.peek(), m1.peek(), dimension, dimension, 2 * cweights[ic]); } long iter = 0; double delta_w; autoMelderProgress progress (U"Simultaneous diagonalization of many CrossCorrelationTables..."); try { do { // the standard diagonality measure is rather expensive to calculate so we compare the norms of // differences of eigenvectors. delta_w = 0; for (long kol = 1; kol <= dimension; kol++) { for (long i = 1; i <= dimension; i++) { wvec[i] = w[i][kol]; } update_one_column (ccts.peek(), d.peek(), cweights, wvec.peek(), -1, mvec.peek()); Eigen_initFromSymmetricMatrix (eigen.peek(), d.peek(), dimension); // Eigenvalues already sorted; get eigenvector of smallest ! for (long i = 1; i <= dimension; i++) { wnew[i] = eigen -> eigenvectors[dimension][i]; } update_one_column (ccts.peek(), d.peek(), cweights, wnew.peek(), 1, mvec.peek()); for (long i = 1; i <= dimension; i++) { w[i][kol] = wnew[i]; } // compare norms of eigenvectors. We have to compare ||wvec +/- w_new|| because eigenvectors // may change sign. double normp = 0, normm = 0; for (long j = 1; j <= dimension; j++) { double dm = wvec[j] - wnew[j], dp = wvec[j] + wnew[j]; normp += dm * dm; normm += dp * dp; } normp = normp < normm ? normp : normm; normp = sqrt (normp); delta_w = normp > delta_w ? normp : delta_w; } iter++; Melder_progress ((double) iter / (double) (maxNumberOfIterations + 1), U"Iteration: ", iter, U", norm: ", delta_w); } while (delta_w > delta && iter < maxNumberOfIterations); } catch (MelderError) { Melder_clearError (); } // Revert the sphering W = P'*W; // Take transpose to make W*C[i]W' diagonal instead of W'*C[i]*W => (P'*W)'=W'*P NUMmatrix_copyElements (w, wc.peek(), 1, dimension, 1, dimension); NUMdmatrices_multiply_VpC (w, wc.peek(), dimension, dimension, p.peek(), dimension); // W = W'*P: final result // Calculate the "real" diagonality measure // double dm = CrossCorrelationTables_and_Diagonalizer_getDiagonalityMeasure (thee, me, cweights, 1, thy size); } catch (MelderError) { Melder_throw (me, U" & ", thee, U": no joint diagonalization (qdiag)."); } } void MixingMatrix_and_CrossCorrelationTables_improveUnmixing (MixingMatrix me, CrossCorrelationTables thee, long maxNumberOfIterations, double tol, int method) { autoDiagonalizer him = MixingMatrix_to_Diagonalizer (me); Diagonalizer_and_CrossCorrelationTables_improveDiagonality (him.peek(), thee, maxNumberOfIterations, tol, method); NUMpseudoInverse (his data, his numberOfRows, his numberOfColumns, my data, 0); } /* Preconditions: * x[1..nrows][1..ncols], cc[1..nrows][1..nrows], centroid[1..nrows] * if (lag>0) {i2 + lag <= ncols} else {i1-lag >= 1} * no array boundary checks! * lag >= 0 */ static void NUMcrossCorrelate_rows (double **x, long nrows, long icol1, long icol2, long lag, double **cc, double *centroid, double scale) { lag = labs (lag); long nsamples = icol2 - icol1 + 1 + lag; for (long i = 1; i <= nrows; i++) { double sum = 0; for (long k = icol1; k <= icol2 + lag; k++) { sum += x[i][k]; } centroid[i] = sum / nsamples; } for (long i = 1; i <= nrows; i++) { for (long j = i; j <= nrows; j++) { double ccor = 0; for (long k = icol1; k <= icol2; k++) { ccor += (x[i][k] - centroid[i]) * (x[j][k + lag] - centroid[j]); } cc[j][i] = cc[i][j] = ccor * scale; } } } /* This is for multi-channel "sounds" like EEG signals. The cross-correlation between channel i and channel j is defined as sum(k=1..nsamples, (z[i][k] - mean[i])(z[j][k + tau] - mean[j]))*samplingTime */ autoCrossCorrelationTable Sound_to_CrossCorrelationTable (Sound me, double startTime, double endTime, double lagStep) { try { if (endTime <= startTime) { startTime = my xmin; endTime = my xmax; } long lag = (long) floor (lagStep / my dx); // ppgb: voor al dit soort dingen geldt: waarom afronden naar beneden? long i1 = Sampled_xToNearestIndex (me, startTime); if (i1 < 1) { i1 = 1; } long i2 = Sampled_xToNearestIndex (me, endTime); if (i2 > my nx) { i2 = my nx; } i2 -= lag; long nsamples = i2 - i1 + 1; if (nsamples <= my ny) { Melder_throw (U"Not enough samples, choose a longer interval."); } autoCrossCorrelationTable thee = CrossCorrelationTable_create (my ny); NUMcrossCorrelate_rows (my z, my ny, i1, i2, lag, thy data, thy centroid, my dx); thy numberOfObservations = nsamples; return thee; } catch (MelderError) { Melder_throw (me, U": CrossCorrelationTable not created."); } } /* Calculate the CrossCorrelationTable between the channels of two multichannel sounds irrespective of the domains. * Both sounds are treated as if their domain runs from 0 to duration. * Outside the chosen interval the sounds are assumed to be zero */ autoCrossCorrelationTable Sounds_to_CrossCorrelationTable_combined (Sound me, Sound thee, double relativeStartTime, double relativeEndTime, double lagStep) { try { if (my dx != thy dx) { Melder_throw (U"Sampling frequencies must be equal."); } if (relativeEndTime <= relativeStartTime) { relativeStartTime = my xmin; relativeEndTime = my xmax; } long ndelta = (long) floor (lagStep / my dx), nchannels = my ny + thy ny; long i1 = Sampled_xToNearestIndex (me, relativeStartTime); if (i1 < 1) { i1 = 1; } long i2 = Sampled_xToNearestIndex (me, relativeEndTime); if (i2 > my nx) { i2 = my nx; } i2 -= ndelta; long nsamples = i2 - i1 + 1; if (nsamples <= nchannels) { Melder_throw (U"Not enough samples"); } autoCrossCorrelationTable him = CrossCorrelationTable_create (nchannels); autoNUMvector data (1, nchannels); for (long i = 1; i <= my ny; i++) { data[i] = my z[i]; } for (long i = 1; i <= thy ny; i++) { data[i + my ny] = thy z[i]; } NUMcrossCorrelate_rows (data.peek(), nchannels, i1, i2, ndelta, his data, his centroid, my dx); his numberOfObservations = nsamples; return him; } catch (MelderError) { Melder_throw (me, U": CrossCorrelationTable not created."); } } autoCovariance Sound_to_Covariance_channels (Sound me, double startTime, double endTime) { try { double lagStep = 0.0; autoCrossCorrelationTable thee = Sound_to_CrossCorrelationTable (me, startTime, endTime, lagStep); autoCovariance him = Thing_new (Covariance); thy structCrossCorrelationTable :: v_copy (him.peek()); return him; } catch (MelderError) { Melder_throw (me, U": no Covariance created."); } } autoCrossCorrelationTables Sound_to_CrossCorrelationTables (Sound me, double startTime, double endTime, double lagStep, long ncovars) { try { if (lagStep < my dx) { lagStep = my dx; } if (endTime <= startTime) { startTime = my xmin; endTime = my xmax; } if (startTime + ncovars * lagStep >= endTime) { Melder_throw (U"Lag time too large."); } autoCrossCorrelationTables thee = CrossCorrelationTables_create (); for (long i = 1; i <= ncovars; i++) { double lag = (i - 1) * lagStep; autoCrossCorrelationTable ct = Sound_to_CrossCorrelationTable (me, startTime, endTime, lag); Collection_addItem (thee.peek(), ct.transfer()); } return thee; } catch (MelderError) { Melder_throw (me, U": no CrossCorrelationTables created."); } } Sound Sound_to_Sound_BSS (Sound me, double startTime, double endTime, long ncovars, double lagStep, long maxNumberOfIterations, double tol, int method) { try { autoMixingMatrix him = Sound_to_MixingMatrix (me, startTime, endTime, ncovars, lagStep, maxNumberOfIterations, tol, method); autoSound thee = Sound_and_MixingMatrix_unmix (me, him.peek()); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not separated."); } } /************************ Diagonalizer **********************************/ Thing_implement (Diagonalizer, TableOfReal, 0); Diagonalizer Diagonalizer_create (long dimension) { try { autoDiagonalizer me = Thing_new (Diagonalizer); TableOfReal_init (me.peek(), dimension, dimension); for (long i = 1; i <= dimension; i++) { my data[i][i] = 1; } return me.transfer(); } catch (MelderError) { Melder_throw (U"Diagonalizer not created."); } } /************************ MixingMatrix **********************************/ Thing_implement (MixingMatrix, TableOfReal, 0); autoMixingMatrix MixingMatrix_create (long numberOfChannels, long numberOfComponents) { try { autoMixingMatrix me = Thing_new (MixingMatrix); TableOfReal_init (me.peek(), numberOfChannels, numberOfComponents); MixingMatrix_initializeRandom (me.peek()); return me; } catch (MelderError) { Melder_throw (U"MixingMatrix not created."); } } autoMixingMatrix MixingMatrix_createSimple (long numberOfChannels, long numberOfComponents, char32 *elements) { try { long inum = 1, ntokens = Melder_countTokens (elements); if (ntokens == 0) { Melder_throw (U"No matrix elements."); } long nwanted = numberOfChannels * numberOfComponents; autoMixingMatrix me = MixingMatrix_create (numberOfChannels, numberOfComponents); // Construct the full matrix from the elements double number; for (char32 *token = Melder_firstToken (elements); token != nullptr && inum <= ntokens; token = Melder_nextToken (), inum++) { long irow = (inum - 1) / numberOfComponents + 1; long icol = (inum - 1) % numberOfComponents + 1; Interpreter_numericExpression (0, token, &number); my data[irow][icol] = number; } if (ntokens < nwanted) { for (long i = inum; i <= nwanted; i++) { long irow = (inum - 1) / numberOfComponents + 1; long icol = (inum - 1) % numberOfComponents + 1; my data[irow][icol] = number; // repeat the last number given! } } return me; } catch (MelderError) { Melder_throw (U"MixingMatrix not created."); } } void MixingMatrix_initializeRandom (MixingMatrix me) { for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= my numberOfColumns; j++) { my data[i][j] = NUMrandomGauss (0, 1); } } } /***************** Diagonalizer & MixingMatrix *************************/ autoDiagonalizer MixingMatrix_to_Diagonalizer (MixingMatrix me) { try { if (my numberOfRows != my numberOfColumns) { Melder_throw (U"The number of channels and the number of components must be equal."); } autoDiagonalizer thee = Diagonalizer_create (my numberOfRows); NUMpseudoInverse (my data, my numberOfRows, my numberOfColumns, thy data, 0); return thee; } catch (MelderError) { Melder_throw (me, U": no Diagonalizer created."); } } autoMixingMatrix Diagonalizer_to_MixingMatrix (Diagonalizer me) { try { autoMixingMatrix thee = MixingMatrix_create (my numberOfRows, my numberOfColumns); NUMpseudoInverse (my data, my numberOfRows, my numberOfColumns, thy data, 0); return thee; } catch (MelderError) { Melder_throw (me, U": no MixingMatrix created."); } } /********************* Sound & MixingMatrix ************************************/ Sound Sound_and_MixingMatrix_mix (Sound me, MixingMatrix thee) { try { if (my ny != thy numberOfColumns) { Melder_throw (U"The number of components in the MixingMatrix and the number of channels in the Sound must be equal."); } autoSound him = Sound_create (thy numberOfRows, my xmin, my xmax, my nx, my dx, my x1); for (long i = 1; i <= thy numberOfRows; i++) { for (long j = 1; j <= my nx; j++) { double mix = 0; for (long k = 1; k <= my ny; k++) { mix += thy data[i][k] * my z[k][j]; } his z[i][j] = mix; } } return him.transfer(); } catch (MelderError) { Melder_throw (me, U": not mixed."); } } Sound Sound_and_MixingMatrix_unmix (Sound me, MixingMatrix thee) { try { if (my ny != thy numberOfRows) { Melder_throw (U"The MixingMatrix and the Sound must have the same number of channels."); } autoNUMmatrix minv (1, thy numberOfColumns, 1, thy numberOfRows); NUMpseudoInverse (thy data, thy numberOfRows, thy numberOfColumns, minv.peek(), 0); autoSound him = Sound_create (thy numberOfColumns, my xmin, my xmax, my nx, my dx, my x1); for (long i = 1; i <= thy numberOfColumns; i++) { for (long j = 1; j <= my nx; j++) { double s = 0; for (long k = 1; k <= my ny; k++) { s += minv[i][k] * my z[k][j]; } his z[i][j] = s; } } return him.transfer(); } catch (MelderError) { Melder_throw (me, U": not unmixed."); } } autoMixingMatrix Sound_to_MixingMatrix (Sound me, double startTime, double endTime, long ncovars, double lagStep, long maxNumberOfIterations, double tol, int method) { try { autoCrossCorrelationTables ccs = Sound_to_CrossCorrelationTables (me, startTime, endTime, lagStep, ncovars); autoMixingMatrix thee = MixingMatrix_create (my ny, my ny); MixingMatrix_and_CrossCorrelationTables_improveUnmixing (thee.peek(), ccs.peek(), maxNumberOfIterations, tol, method); return thee; } catch (MelderError) { Melder_throw (me, U": no MixingMatrix created."); } } autoMixingMatrix TableOfReal_to_MixingMatrix (TableOfReal me) { try { if (my numberOfColumns != my numberOfRows) { Melder_throw (U"Number of rows and columns must be equal."); } autoMixingMatrix thee = Thing_new (MixingMatrix); my structTableOfReal :: v_copy (thee.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to MixingMatrix."); } } /************* CrossCorrelationTable *****************************/ Thing_implement (CrossCorrelationTable, SSCP, 0); void structCrossCorrelationTable :: v_info () { structSSCP :: v_info (); double dm = CrossCorrelationTable_getDiagonalityMeasure (this); MelderInfo_writeLine (U"Diagonality measure: ", dm); } autoCrossCorrelationTable CrossCorrelationTable_create (long dimension) { try { autoCrossCorrelationTable me = Thing_new (CrossCorrelationTable); SSCP_init (me.peek(), dimension, dimension); return me; } catch (MelderError) { Melder_throw (U"CrossCorrelationTable not created."); } } autoCrossCorrelationTable CrossCorrelationTable_createSimple (char32 *covars, char32 *centroid, long numberOfSamples) { try { long dimension = Melder_countTokens (centroid); long ncovars = Melder_countTokens (covars); long ncovars_wanted = dimension * (dimension + 1) / 2; if (ncovars != ncovars_wanted) Melder_throw (U"The number of matrix elements and the number of " U"centroid elements are not in concordance. There should be \"d(d+1)/2\" matrix values and \"d\" centroid values."); autoCrossCorrelationTable me = CrossCorrelationTable_create (dimension); // Construct the full matrix from the upper-diagonal elements long inum = 1, irow = 1; for (char32 *token = Melder_firstToken (covars); token != nullptr && inum <= ncovars_wanted; token = Melder_nextToken (), inum++) { double number; long nmissing = (irow - 1) * irow / 2; long inumc = inum + nmissing; irow = (inumc - 1) / dimension + 1; long icol = ( (inumc - 1) % dimension) + 1; Interpreter_numericExpression (nullptr, token, &number); my data[irow][icol] = my data[icol][irow] = number; if (icol == dimension) { irow++; } } inum = 1; for (char32 *token = Melder_firstToken (centroid); token != nullptr && inum <= dimension; token = Melder_nextToken (), inum++) { double number; Interpreter_numericExpression (nullptr, token, &number); my centroid[inum] = number; } my numberOfObservations = numberOfSamples; return me; } catch (MelderError) { Melder_throw (U"CrossCorrelationTable not created."); } } double CrossCorrelationTable_getDiagonalityMeasure (CrossCorrelationTable me) { return NUMdmatrix_diagonalityMeasure (my data, my numberOfColumns); } /************* CrossCorrelationTables *****************************/ void structCrossCorrelationTables :: v_info () { structOrdered :: v_info (); CrossCorrelationTable thee = (CrossCorrelationTable) item[1]; MelderInfo_writeLine (U" Number of rows and columns: ", thy numberOfRows); for (long i = 1; i <= size; i++) { double dm = CrossCorrelationTable_getDiagonalityMeasure ( (CrossCorrelationTable) item[i]); MelderInfo_writeLine (U"Diagonality measure for item ", i, U": ", dm); } } Thing_implement (CrossCorrelationTables, Ordered, 0); autoCrossCorrelationTables CrossCorrelationTables_create () { try { autoCrossCorrelationTables me = Thing_new (CrossCorrelationTables); Ordered_init (me.peek(), classCrossCorrelationTable, 30); return me; } catch (MelderError) { Melder_throw (U"CrossCorrelationTables not created."); } } double CrossCorrelationTables_getDiagonalityMeasure (CrossCorrelationTables me, double *w, long start, long end) { if (start >= end) { start = 1; end = my size; } if (start < 1) { start = 1; } if (end > my size) { end = my size; } long ntables = end - start + 1; long dimension = ((Covariance) my item[1]) -> numberOfColumns; double dmsq = 0; for (long k = start; k <= end; k++) { CrossCorrelationTable thee = (CrossCorrelationTable) my item[k]; double dmksq = NUMdmatrix_diagonalityMeasure (thy data, dimension); dmsq += ( w ? dmksq * w[k] : dmksq / ntables ); } return dmsq; } /************************** CrossCorrelationTables & Diagonalizer *******************************/ double CrossCorrelationTables_and_Diagonalizer_getDiagonalityMeasure (CrossCorrelationTables me, Diagonalizer thee, double *w, long start, long end) { autoCrossCorrelationTables him = CrossCorrelationTables_and_Diagonalizer_diagonalize (me, thee); double dm = CrossCorrelationTables_getDiagonalityMeasure (him.peek(), w, start, end); return dm; } autoCrossCorrelationTable CrossCorrelationTable_and_Diagonalizer_diagonalize (CrossCorrelationTable me, Diagonalizer thee) { try { if (my numberOfRows != thy numberOfRows) { Melder_throw (U"The CrossCorrelationTable and the Diagonalizer matrix dimensions must be equal."); } autoCrossCorrelationTable him = CrossCorrelationTable_create (my numberOfColumns); NUMdmatrices_multiply_VCVp (his data, thy data, my numberOfColumns, my numberOfColumns, my data, 1); return him; } catch (MelderError) { Melder_throw (U"CrossCorrelationTable not diagonalized."); } } autoCrossCorrelationTables CrossCorrelationTables_and_Diagonalizer_diagonalize (CrossCorrelationTables me, Diagonalizer thee) { try { autoCrossCorrelationTables him = CrossCorrelationTables_create (); for (long i = 1; i <= my size; i++) { CrossCorrelationTable item = (CrossCorrelationTable) my item[i]; autoCrossCorrelationTable ct = CrossCorrelationTable_and_Diagonalizer_diagonalize (item, thee); Collection_addItem (him.peek(), ct.transfer()); } return him.transfer(); } catch (MelderError) { Melder_throw (U"CrossCorrelationTables not diagonalized."); } } autoDiagonalizer CrossCorrelationTables_to_Diagonalizer (CrossCorrelationTables me, long maxNumberOfIterations, double tol, int method) { try { CrossCorrelationTable him = (CrossCorrelationTable) my item[1]; autoDiagonalizer thee = Diagonalizer_create (his numberOfColumns); Diagonalizer_and_CrossCorrelationTables_improveDiagonality (thee.peek(), me, maxNumberOfIterations, tol, method); return thee.transfer(); } catch (MelderError) { Melder_throw (U"Diagonalizer not created from CrossCorrelationTables."); }; } void Diagonalizer_and_CrossCorrelationTables_improveDiagonality (Diagonalizer me, CrossCorrelationTables thee, long maxNumberOfIterations, double tol, int method) { if (method == 1) { autoNUMvector cweights (1, thy size); for (long i = 1; i <= thy size; i++) { cweights[i] = 1.0 / thy size; } Diagonalizer_and_CrossCorrelationTable_qdiag (me, thee, cweights.peek(), maxNumberOfIterations, tol); } else { Diagonalizer_and_CrossCorrelationTables_ffdiag (me, thee, maxNumberOfIterations, tol); } } Sound Sound_whitenChannels (Sound me, double varianceFraction) { try { autoCovariance cov = Sound_to_Covariance_channels (me, 0.0, 0.0); autoSound thee = Sound_and_Covariance_whitenChannels (me, cov.peek(), varianceFraction); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not whitened."); } } Sound Sound_and_Covariance_whitenChannels (Sound me, Covariance thee, double varianceFraction) { try { autoPCA pca = SSCP_to_PCA (thee); long numberOfComponents = Eigen_getDimensionOfFraction (pca.peek(), varianceFraction); autoSound him = Sound_and_PCA_whitenChannels (me, pca.peek(), numberOfComponents); return him.transfer (); } catch (MelderError) { Melder_throw (me, U": not whitened from ", thee); } } /* * Generate n different cct's that have a common diagonalizer. */ autoCrossCorrelationTables CrossCorrelationTables_createTestSet (long dimension, long n, int firstPositiveDefinite, double sigma) { try { // Start with a square matrix with random gaussian elements and make its singular value decomposition UDV' // The V matrix will be the common diagonalizer matrix that we use. autoNUMmatrix d (1, dimension, 1, dimension); for (long i = 1; i <= dimension; i++) { // Generate the rotation matrix for (long j = 1; j <= dimension; j++) { d[i][j] = NUMrandomGauss (0, 1); } } autoNUMmatrix v (1, dimension, 1, dimension); autoSVD svd = SVD_create_d (d.peek(), dimension, dimension); autoCrossCorrelationTables me = CrossCorrelationTables_create (); for (long i = 1; i <= dimension; i++) { for (long j = 1; j <= dimension; j++) { d[i][j] = 0; } } // Start with a diagonal matrix D and calculate V'DV for (long k = 1; k <= n; k++) { autoCrossCorrelationTable ct = CrossCorrelationTable_create (dimension); double low = k == 1 && firstPositiveDefinite ? 0.1 : -1; for (long i = 1; i <= dimension; i++) { d[i][i] = NUMrandomUniform (low, 1); } for (long i = 1; i <= dimension; i++) { for (long j = 1; j <= dimension; j++) { v[i][j] = NUMrandomGauss (svd -> v[i][j], sigma); } } // we need V'DV, however our V has eigenvectors row-wise -> VDV' NUMdmatrices_multiply_VCVp (ct -> data, v.peek(), dimension, dimension, d.peek(), 1); Collection_addItem (me.peek(), ct.transfer()); } return me; } catch (MelderError) { Melder_throw (U"CrossCorrelationTables test set not created."); } } static void Sound_and_MixingMatrix_improveUnmixing_fica (Sound me, MixingMatrix thee, long maxNumberOfIterations, double tol, int method) { (void) tol; (void) method; try { long iter = 0; if (my ny != thy numberOfColumns) { Melder_throw (U"Dimensions do not agree."); } autoNUMmatrix x (NUMmatrix_copy (my z, 1, my ny, 1, my nx), 1, 1); do { iter++; } while (/*fabs((dm_old - dm_new) / dm_new) > tol &&*/ iter < maxNumberOfIterations); } catch (MelderError) { Melder_throw (me, U" & ", thee, U" ."); } } /* End of file ICA.cpp 987*/ praat-6.0.04/dwtools/ICA.h000066400000000000000000000132271261542461700151650ustar00rootroot00000000000000#ifndef _ICA_h_ #define _ICA_h_ /* ICA.h * * Copyright (C) 2010-2014, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20101202 Initial version djmw 20120406 Latest modification. */ #include "SSCP.h" #include "Sound.h" Thing_define (MixingMatrix, TableOfReal) { }; Thing_define (Diagonalizer, TableOfReal) { }; Thing_define (CrossCorrelationTable, SSCP) { void v_info () override; }; Thing_define (CrossCorrelationTables, Ordered) { void v_info () override; }; /* Cell [i,j] of a CrossCorrelationTable contains the cross-correlation between signal i and signal j (for one particular lag time). For example, the CrossCorrelation of an n-channel sound is a nxn table where cell [i,j] contains the cross-correlation of channel i with channel j for a particlular lag time tau. In the statistical literature sometimes the cross-correlation between signals is also called "covariance". However, the only thing a Covariance has in common with a CrossCorrelationTable is that both are symmetric matrices. Differences between a CrossCorrelationTable and a Covariance: 1. a Covariance matrix is always positive definite, for a cross-correlation table this is only guaranteed for lag time tau = 0. 2. The elements c[i][j] in a Covariance always satisfy |c[i][j]/sqrt(c[i][i]*c[j][j])| <= 1, this is in general not the case for cross-correlations. */ autoCrossCorrelationTable CrossCorrelationTable_create (long dimension); autoCrossCorrelationTable CrossCorrelationTable_createSimple (char32 *covars, char32 *centroid, long numberOfSamples); /* (sum(i,j=1..dimension, i!=j; C[i][j]^2))/(dimension*(dimension-1)) */ double CrossCorrelationTable_getDiagonalityMeasure (CrossCorrelationTable me); autoCrossCorrelationTable CrossCorrelationTable_and_Diagonalizer_diagonalize (CrossCorrelationTable me, Diagonalizer thee); autoCrossCorrelationTables CrossCorrelationTables_create (); double CrossCorrelationTables_getDiagonalityMeasure (CrossCorrelationTables me, double *w, long start, long end); double CrossCorrelationTables_and_Diagonalizer_getDiagonalityMeasure (CrossCorrelationTables me, Diagonalizer thee, double *w, long start, long end); autoCrossCorrelationTables CrossCorrelationTables_createTestSet (long dimension, long n, int firstPositiveDefinite, double sigma); autoMixingMatrix MixingMatrix_create (long numberOfChannels, long numberOfComponents); autoMixingMatrix MixingMatrix_createSimple (long numberOfChannels, long numberOfComponents, char32 *elements); void MixingMatrix_initializeRandom (MixingMatrix me); Diagonalizer Diagonalizer_create (long dimension); Sound Sound_and_MixingMatrix_mix (Sound me, MixingMatrix thee); Sound Sound_and_MixingMatrix_unmix (Sound me, MixingMatrix thee); autoMixingMatrix Sound_to_MixingMatrix (Sound me, double startTime, double endTime, long ncovars, double lagStep, long maxNumberOfIterations, double delta_w, int method); Sound Sound_to_Sound_BSS (Sound me, double startTime, double endTime, long ncovars, double lagStep, long maxNumberOfIterations, double delta_w, int method); Sound Sound_whitenChannels (Sound me, double varianceFraction); Sound Sound_and_Covariance_whitenChannels (Sound me, Covariance thee, double varianceFraction); void MixingMatrix_and_CrossCorrelationTables_improveUnmixing (MixingMatrix me, CrossCorrelationTables thee, long maxNumberOfIterations, double tol, int method); /* Determine the matrix that diagonalizes a series of CrossCorrelationTables as well as possible. */ autoDiagonalizer CrossCorrelationTables_to_Diagonalizer (CrossCorrelationTables me, long maxNumberOfIterations, double tol, int method); void Diagonalizer_and_CrossCorrelationTables_improveDiagonality (Diagonalizer me, CrossCorrelationTables thee, long maxNumberOfIterations, double tol, int method); /* Determine V*C[k]*V' for k=1..n, where V is the diagonalizer matrix and C[k} the k-th CrossCorrelationTable. */ autoCrossCorrelationTables CrossCorrelationTables_and_Diagonalizer_diagonalize (CrossCorrelationTables me, Diagonalizer thee); autoDiagonalizer MixingMatrix_to_Diagonalizer (MixingMatrix me); autoMixingMatrix Diagonalizer_to_MixingMatrix (Diagonalizer me); /* For multi-channel "sounds" like EEG signals. The cross-correlation between channel i and channel j is defined as sum(k=1..nsamples; (z[i][k] - mean[i])(z[j][k + lag] - mean[j])) / (nsamples - 1). */ autoCrossCorrelationTable Sound_to_CrossCorrelationTable (Sound me, double startTime, double endTime, double lagStep); autoCrossCorrelationTable Sounds_to_CrossCorrelationTable_combined (Sound me, Sound thee, double relativeStartTime, double relativeEndTime, double lagStep); // The covariance is the cross-correlation with lag 0. autoCovariance Sound_to_Covariance_channels (Sound me, double startTime, double endTime); /* Determine a CrossCorrelationTable for lags (k-1)*lagStep, where k = 1...n. */ autoCrossCorrelationTables Sound_to_CrossCorrelationTables (Sound me, double startTime, double endTime, double lagStep, long n); autoMixingMatrix TableOfReal_to_MixingMatrix (TableOfReal me); #endif /*_ICA_h_ */ praat-6.0.04/dwtools/Intensity_extensions.cpp000066400000000000000000000127121261542461700213670ustar00rootroot00000000000000/* Intensity_extensions.cpp * * Copyright (C) 2007-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20061204 Initial version djmw 20070129 Extra argument for Vector_getAndX djmw 20071201 Melder_warning djmw 20090818 Intensity_to_TextGrid_detectSilences: mark last interval also if sounding */ #include "Intensity_extensions.h" #include "TextGrid_extensions.h" static void IntervalTier_addBoundaryUnsorted (IntervalTier me, long iinterval, double time, const char32 *leftLabel) { if (time <= my xmin || time >= my xmax) { Melder_throw (U"Time is outside interval."); } // Find interval to split if (iinterval <= 0) { iinterval = IntervalTier_timeToLowIndex (me, time); } // Modify end time of left label TextInterval ti = (TextInterval) my intervals -> item[iinterval]; ti -> xmax = time; TextInterval_setText (ti, leftLabel); autoTextInterval ti_new = TextInterval_create (time, my xmax, U""); Sorted_addItem_unsorted (my intervals, ti_new.transfer()); } autoTextGrid Intensity_to_TextGrid_detectSilences (Intensity me, double silenceThreshold_dB, double minSilenceDuration, double minSoundingDuration, const char32 *silenceLabel, const char32 *soundingLabel) { try { double duration = my xmax - my xmin, time; if (silenceThreshold_dB >= 0) { Melder_throw (U"The silence threshold w.r.t. the maximum intensity should be a negative number."); } autoTextGrid thee = TextGrid_create (my xmin, my xmax, U"silences", U""); IntervalTier it = (IntervalTier) thy tiers -> item[1]; TextInterval_setText ( (TextInterval) it -> intervals -> item[1], soundingLabel); if (minSilenceDuration > duration) { return thee; } double intensity_max_db, intensity_min_db, xOfMaximum, xOfMinimum; Vector_getMaximumAndX (me, 0, 0, 1, NUM_PEAK_INTERPOLATE_PARABOLIC, &intensity_max_db, &xOfMaximum); Vector_getMinimumAndX (me, 0, 0, 1, NUM_PEAK_INTERPOLATE_PARABOLIC, &intensity_min_db, &xOfMinimum); double intensity_dbRange = intensity_max_db - intensity_min_db; if (intensity_dbRange < 10) { Melder_warning (U"The loudest and softest part in your sound only differ by ", intensity_dbRange, U" dB."); } double intensityThreshold = intensity_max_db - fabs (silenceThreshold_dB); if (minSilenceDuration > duration || intensityThreshold < intensity_min_db) { return thee; } int inSilenceInterval = my z[1][1] < intensityThreshold; long iinterval = 1; const char32 *label; for (long i = 2; i <= my nx; i++) { int addBoundary = 0; if (my z[1][i] < intensityThreshold) { if (!inSilenceInterval) { // Start of silence addBoundary = 1; inSilenceInterval = 1; label = soundingLabel; } } else { if (inSilenceInterval) { // End of silence addBoundary = 1; inSilenceInterval = 0; label = silenceLabel; } } if (addBoundary) { time = my x1 + (i - 1) * my dx; IntervalTier_addBoundaryUnsorted (it, iinterval, time, label); iinterval++; } } // (re)label last interval */ label = inSilenceInterval ? silenceLabel : soundingLabel; TextInterval_setText ( (TextInterval) it -> intervals -> item[iinterval], label); Sorted_sort (it -> intervals); // First remove short non-silence intervals in-between silence intervals and // then remove the remaining short silence intervals. // This works much better than first removing short silence intervals and // then short non-silence intervals. IntervalTier_cutIntervals_minimumDuration (it, soundingLabel, minSoundingDuration); IntervalTier_cutIntervalsOnLabelMatch (it, silenceLabel); IntervalTier_cutIntervals_minimumDuration (it, silenceLabel, minSilenceDuration); IntervalTier_cutIntervalsOnLabelMatch (it, soundingLabel); return thee; } catch (MelderError) { Melder_throw (me, U": TextGrid not created."); } } autoIntensity IntensityTier_to_Intensity (IntensityTier me, double dt) { try { long nt = (long) floor ((my xmax - my xmin) / dt); double t1 = 0.5 * dt; autoIntensity thee = Intensity_create (my xmin, my xmax, nt, dt, t1); for (long i = 1; i <= nt; i++) { double time = t1 + (i - 1) * dt; thy z[1][i] = RealTier_getValueAtTime (me, time); } return thee; } catch (MelderError) { Melder_throw (me, U" no Intensity created."); } } autoTextGrid IntensityTier_to_TextGrid_detectSilences (IntensityTier me, double dt, double silenceThreshold_dB, double minSilenceDuration, double minSoundingDuration, const char32 *silenceLabel, const char32 *soundingLabel) { try { autoIntensity intensity = IntensityTier_to_Intensity (me, dt); autoTextGrid thee = Intensity_to_TextGrid_detectSilences (intensity.peek(), silenceThreshold_dB, minSilenceDuration, minSoundingDuration, silenceLabel, soundingLabel); return thee; } catch (MelderError) { Melder_throw (me, U" no TextGrid created."); } } /* End of file Intensity_extensions.cpp */ praat-6.0.04/dwtools/Intensity_extensions.h000066400000000000000000000037401261542461700210350ustar00rootroot00000000000000#ifndef _Intensity_extensions_h_ #define _Intensity_extensions_h_ /* Intensity_extensions.h * * Copyright (C) 2006-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20061204 Initial version djmw 20110307 Latewst modification */ #include "Sound.h" #include "Intensity.h" #include "IntensityTier.h" #include "TextGrid.h" autoTextGrid Intensity_to_TextGrid_detectSilences (Intensity me, double silenceThreshold_dB, double minSilenceDuration, double minSoundingDuration, const char32 *silenceLabel, const char32 *soundingLabel); /* Marks "silence" intervals in a sound as intervals in a TextGrid. silenceThreshold_dB: silence-to-speech and speech-to-silence threshold as dB's below maximum intensity We have speech if: local_intensity >= max_intensity - silenceThreshold. Silence if: local_intensity < max_intensity - silenceThreshold. If minSilenceDuration > 0 then only intervals with a duration > minSilenceDuration will be labelled as silences in the IntervalTier. */ autoIntensity IntensityTier_to_Intensity (IntensityTier me, double dt); autoTextGrid IntensityTier_to_TextGrid_detectSilences (IntensityTier me, double dt, double silenceThreshold_dB, double minSilenceDuration, double minSoundingDuration, const char32 *silenceLabel, const char32 *soundingLabel); #endif /* _Intensity_extensions_h_ */ praat-6.0.04/dwtools/KlattGrid.cpp000066400000000000000000003440771261542461700170230ustar00rootroot00000000000000/* KlattGrid.cpp * * Copyright (C) 2008-2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20080917 Initial version djmw 20090109 Add formulas for formant frequencies and bandwidths. djmw 20090123 Add PlayOptions. djmw 20090129 KlattGrid_draw text in boxes displays better djmw 20090311 Add RealTier_valuesInRange djmw 20090312 Add klattGrid_addFormantAndBandwidthTier djmw 20090326 Changed DBSPL_to_A into DB_to_A for bypass and formant amplitudes. djmw 20100223 Removed gsl dependency djmw 20110304 Thing_new djmw 20110308 struc connections -> struct structconnections djmw 20110329 Table_get(Numeric|String)Value is now Table_get(Numeric|String)Value_Assert djmw 20111011 Sound_VocalTractGrid_CouplingGrid_filter_cascade: group warnings */ #include "FormantGrid_extensions.h" #include "Formula.h" #include "KlattGrid.h" #include "KlattTable.h" #include "Resonator.h" #include "Pitch_to_PitchTier.h" #include "PitchTier_to_Sound.h" #include "PitchTier_to_PointProcess.h" #include "NUM2.h" #include "Sound_to_Formant.h" #include "Sound_to_Intensity.h" #include "Sound_to_Pitch.h" #include "oo_DESTROY.h" #include "KlattGrid_def.h" #include "oo_COPY.h" #include "KlattGrid_def.h" #include "oo_EQUAL.h" #include "KlattGrid_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "KlattGrid_def.h" #include "oo_WRITE_TEXT.h" #include "KlattGrid_def.h" #include "oo_WRITE_BINARY.h" #include "KlattGrid_def.h" #include "oo_READ_TEXT.h" #include "KlattGrid_def.h" #include "oo_READ_BINARY.h" #include "KlattGrid_def.h" #include "oo_DESCRIPTION.h" #include "KlattGrid_def.h" /* * A KlattGrid consists of a great many tiers that can be independently modified. * * For any particular formant, the formant frequency tier and the formant bandwidth tier can only be added or removed jointly * because they are part of a FormantGrid object. There will always be an equal number of formant frequency tiers and * formant bandwidth tiers. * * For parallel synthesis we also need, besides the frequency and bandwidth tier, an additional amplitude tier for each formant. * It is not necessary that there are an equal number of formant frequency tiers (nf) and amplitude tiers (na). * During parallel synthesis we simply synthesize with min(nf,na) number of formants. * These numbers nf and na can get out of sync because of the following (add, remove, replace) actions: * - we replace a FormantGrid that has not the same number of tiers as the corresponding number of amplitude tiers * - we remove/add a formant tier and a bandwidth tier together and not the corresponding amplitude tier * - we remove/add an amplitude tier and not the corresponding formant&bandwidth tiers * * As of 20130113 the KlattGrid_addFormant (/remove) which also added automatically an amplitude tier has been split into two explicit actions * KlattGrid_addFormantFrequencyAndBandwidth (/remove) * KlattGrid_addFormantAmplitudeTier (/remove) * */ // Prototypes autoPointProcess PitchTier_to_PointProcess_flutter (PitchTier pitch, RealTier flutter, double maximumPeriod); void _Sound_FormantGrid_filterWithOneFormant_inline (Sound me, thou, long iformant, int antiformant); autoSound Sound_VocalTractGrid_CouplingGrid_filter_parallel (Sound me, VocalTractGrid thee, CouplingGrid coupling); autoSound PhonationGrid_PhonationTier_to_Sound_voiced (PhonationGrid me, PhonationTier thee, double samplingFrequency); autoSound KlattGrid_to_Sound_aspiration (KlattGrid me, double samplingFrequency); #undef MIN #undef MAX #define MIN(x,y) ((x) < (y) ? (x) : (y)) #define MAX(x,y) ((x) > (y) ? (x) : (y)) #define KlattGrid_OPENPHASE_DEFAULT 0.7 #define KlattGrid_POWER1_DEFAULT 3 #define KlattGrid_POWER2_DEFAULT (KlattGrid_POWER1_DEFAULT+1) /* Amplitude scaling: maximum amplitude (-1,+1) corresponds to 91 dB */ /*static double NUMinterpolateLinear (double x1, double y1, double x2, double y2, double x) { if (y1 == y2) return y1; if (x1 == x2) return NUMundefined; return (y2 - y1) * (x - x1) / (x2 - x1) + y1; }*/ static void rel_to_abs (double *w, double *ws, long n, double d) { double sum = 0; for (long i = 1; i <= n; i++) { // relative sum += w[i]; } if (sum != 0) { double dw = d / sum; sum = 0; for (long i = 1; i <= n; i++) { // to absolute w[i] *= dw; sum += w[i]; ws[i] = sum; } } } static bool RealTier_valuesInRange (I, double min, double max) { iam (RealTier); for (long i = 1; i <= my points -> size; i++) { RealPoint p = (RealPoint) my points -> item[i]; if (NUMdefined (min) && p -> value < min) { return false; } if (NUMdefined (max) && p -> value < max) { return false; } } return true; } static double PointProcess_getPeriodAtIndex (PointProcess me, long it, double maximumPeriod) { double period = NUMundefined; if (it >= 2) { period = my t[it] - my t[it - 1]; if (period > maximumPeriod) { period = NUMundefined; } } if (period == NUMundefined) { if (it < my nt) { period = my t[it + 1] - my t[it]; if (period > maximumPeriod) { period = NUMundefined; } } } // NUMundefined can only occur for a single isolated pulse. return period; } #define UPDATE_TIER RealTier_addPoint (thee.peek(), mytime, myvalue); \ lasttime=mytime; myindex++; \ if (myindex <= numberOfValues)\ {\ mypoint = (RealPoint) my points -> item [myindex];\ mytime = mypoint -> number; myvalue = mypoint -> value;\ }\ else mytime = my xmax;\ static RealTier RealTier_updateWithDelta (RealTier me, RealTier delta, PhonationTier glottis, double openglottis_fadeFraction) { try { long myindex = 1; RealPoint mypoint = (RealPoint) my points -> item [myindex]; long numberOfValues = my points -> size; double mytime = mypoint -> number; double myvalue = mypoint -> value; double lasttime = my xmin - 0.001; // sometime before xmin autoRealTier thee = RealTier_create (my xmin, my xmax); if (openglottis_fadeFraction <= 0) { openglottis_fadeFraction = 0.0001; } if (openglottis_fadeFraction >= 0.5) { openglottis_fadeFraction = 0.4999; } for (long ipoint = 1; ipoint <= glottis -> points -> size; ipoint++) { PhonationPoint point = (PhonationPoint) glottis -> points -> item [ipoint]; double t4 = point -> time; // glottis closing double openDuration = point -> te ; double t1 = t4 - openDuration; double t2 = t1 + openglottis_fadeFraction * openDuration; double t3 = t4 - openglottis_fadeFraction * openDuration; // Add my points that lie before t1 and after previous t4 while (mytime > lasttime && mytime < t1) { UPDATE_TIER } if (t2 > t1) { // Set new value at t1 double myvalue1 = RealTier_getValueAtTime (me, t1); RealTier_addPoint (thee.peek(), t1, myvalue1); // Add my points between t1 and t2 while (mytime > lasttime && mytime < t2) { double dvalue = RealTier_getValueAtTime (delta, mytime); if (NUMdefined (dvalue)) { double fraction = (mytime - t1) / (openglottis_fadeFraction * openDuration); myvalue += dvalue * fraction; } UPDATE_TIER } } double myvalue2 = RealTier_getValueAtTime (me, t2); double dvalue = RealTier_getValueAtTime (delta, t2); if (NUMdefined (dvalue)) { myvalue2 += dvalue; } RealTier_addPoint (thee.peek(), t2, myvalue2); // Add points between t2 and t3 while (mytime > lasttime && mytime < t3) { dvalue = RealTier_getValueAtTime (delta, mytime); if (NUMdefined (dvalue)) { myvalue += dvalue; } UPDATE_TIER } // set new value at t3 double myvalue3 = RealTier_getValueAtTime (me, t3); dvalue = RealTier_getValueAtTime (delta, t3); if (NUMdefined (dvalue)) { myvalue3 += dvalue; } RealTier_addPoint (thee.peek(), t3, myvalue3); if (t4 > t3) { // Add my points between t3 and t4 while (mytime > lasttime && mytime < t4) { dvalue = RealTier_getValueAtTime (delta, mytime); if (NUMdefined (dvalue)) { double fraction = 1 - (mytime - t3) / (openglottis_fadeFraction * openDuration); myvalue += dvalue * fraction; } UPDATE_TIER } // Set new value at t4 double myvalue4 = RealTier_getValueAtTime (me, t4); RealTier_addPoint (thee.peek(), t4, myvalue4); } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not updated with delta."); } } static bool FormantGrid_isFormantDefined (FormantGrid me, long iformant) { // formant and bandwidth are always in sync RealTier ftier = (RealTier) my formants -> item[iformant]; RealTier btier = (RealTier) my bandwidths -> item[iformant]; return ftier -> points -> size != 0 and btier -> points -> size != 0; } static bool FormantGrid_Intensities_isFormantDefined (FormantGrid me, Ordered thee, long iformant) { bool exists = false; if (iformant <= my formants -> size && iformant <= my bandwidths -> size && iformant <= thy size) { RealTier ftier = (RealTier) my formants -> item[iformant]; RealTier btier = (RealTier) my bandwidths -> item[iformant]; RealTier atier = (RealTier) thy item[iformant]; exists = ftier -> points -> size != 0 and btier -> points -> size != 0 and atier -> points -> size != 0; } return exists; } static void check_formants (long numberOfFormants, long *ifb, long *ife) { if (numberOfFormants <= 0 || *ifb > numberOfFormants || *ife < *ifb || *ife < 1) { *ife = 0; // overrules everything *ifb value is a don't care now return; } if (*ifb <= 1) { *ifb = 1; } if (*ife > numberOfFormants) { *ife = numberOfFormants; } } static autoSound Sound_createEmptyMono (double xmin, double xmax, double samplingFrequency) { long nt = (long) ceil ( (xmax - xmin) * samplingFrequency); double dt = 1.0 / samplingFrequency; double tmid = (xmin + xmax) / 2; double t1 = tmid - 0.5 * (nt - 1) * dt; return Sound_create (1, xmin, xmax, nt, dt, t1); } static void _Sounds_add_inline (Sound me, Sound thee) { for (long i = 1; i <= my nx; i++) { my z[1][i] += thy z[1][i]; } } static autoSound _Sound_diff (Sound me, int scale) { try { autoSound thee = Data_copy (me); // extremum double amax1 = -1.0e34, amax2 = amax1, val, pval = 0; if (scale) { for (long i = 1; i <= thy nx; i++) { val = fabs (thy z[1][i]); if (val > amax1) { amax1 = val; } } } // x[n]-x[n-1] for (long i = 1; i <= thy nx; i++) { val = thy z[1][i]; thy z[1][i] -= pval; pval = val; } if (scale) { for (long i = 1; i <= thy nx; i++) { val = fabs (thy z[1][i]); if (val > amax2) { amax2 = val; } } // scale for (long i = 1; i <= thy nx; i++) { thy z[1][i] *= amax1 / amax2; } } return thee; } catch (MelderError) { Melder_throw (me, U": not differenced."); } } /*static void _Sounds_addDifferentiated_inline (Sound me, Sound thee) { double pval = 0, dx = my dx; for (long i = 1; i <= my nx; i++) { double val = thy z[1][i]; my z[1][i] += (val - pval) / dx; // dx makes amplitude of dz/dt independent of sampling. pval = val; } }*/ typedef struct structconnections { long numberOfConnections; double *x, *y; } *connections; static void connections_free (connections me) { if (! me) { return; } NUMvector_free (my x, 1); NUMvector_free (my y, 1); Melder_free (me); } static connections connections_create (long numberOfConnections) { connections me = 0; try { me = (connections) Melder_malloc (structconnections, 1); my numberOfConnections = numberOfConnections; my x = NUMvector (1, numberOfConnections); my y = NUMvector (1, numberOfConnections); return me; } catch (MelderError) { connections_free (me); Melder_throw (U"Connections not created."); } } // Calculates the intersection point (xi,yi) of a line with a circle. // The line starts at the origin and P (xp, yp) is on that line. static void NUMcircle_radial_intersection_sq (double x, double y, double r, double xp, double yp, double *xi, double *yi) { double dx = xp - x, dy = yp - y; double d = sqrt (dx * dx + dy * dy); if (d > 0) { *xi = x + dx * r / d; *yi = y + dy * r / d; } else { *xi = *yi = NUMundefined; } } static void summer_draw (Graphics g, double x, double y, double r, int alternating) { Graphics_setLineWidth (g, 2); Graphics_circle (g, x, y, r); double dy = 3 * r / 4; // + symbol if (alternating) { y += r / 4; } Graphics_line (g, x, y + r / 2, x, y - r / 2); Graphics_line (g, x - r / 2, y, x + r / 2, y); if (alternating) { Graphics_line (g, x - r / 2, y - dy , x + r / 2, y - dy); } } static void _summer_drawConnections (Graphics g, double x, double y, double r, connections thee, int arrow, int alternating, double horizontalFraction) { summer_draw (g, x, y, r, alternating); for (long i = 1; i <= thy numberOfConnections; i++) { double xto, yto, xp = thy x[i], yp = thy y[i]; if (horizontalFraction > 0) { double dx = x - xp; if (dx > 0) { xp += horizontalFraction * dx; Graphics_line (g, thy x[i], yp, xp, yp); } } NUMcircle_radial_intersection_sq (x, y, r, xp, yp, &xto, &yto); if (xto == NUMundefined || yto == NUMundefined) { continue; } if (arrow) { Graphics_arrow (g, xp, yp, xto, yto); } else { Graphics_line (g, xp, yp, xto, yto); } } } static void summer_drawConnections (Graphics g, double x, double y, double r, connections thee, int arrow, double horizontalFraction) { _summer_drawConnections (g, x, y, r, thee, arrow, 0, horizontalFraction); } static void alternatingSummer_drawConnections (Graphics g, double x, double y, double r, connections thee, int arrow, double horizontalFraction) { _summer_drawConnections (g, x, y, r, thee, arrow, 1, horizontalFraction); } static void draw_oneSection (Graphics g, double xmin, double xmax, double ymin, double ymax, const char32 *line1, const char32 *line2, const char32 *line3) { long numberOfTextLines = 0, iline = 0; Graphics_rectangle (g, xmin, xmax, ymin, ymax); if (line1 != 0) { numberOfTextLines++; } if (line2 != 0) { numberOfTextLines++; } if (line3 != 0) { numberOfTextLines++; } double y = ymax, dy = (ymax - ymin) / (numberOfTextLines + 1), ddy = dy / 10; double x = (xmax + xmin) / 2; if (line1 != 0) { iline++; y -= dy - (numberOfTextLines == 2 ? ddy : 0); // extra spacing for two lines Graphics_text (g, x, y, line1); } if (line2 != 0) { iline++; y -= dy - (numberOfTextLines == 2 ? (iline == 1 ? ddy : -iline * ddy) : 0); Graphics_text (g, x, y, line2); } if (line3 != 0) { iline++; y -= dy - (numberOfTextLines == 2 ? -iline * ddy : 0); Graphics_text (g, x, y, line3); } } // Maximum amplitue (-1,1) at 93.97940008672037 dB #define DBSPL_to_A(x) (pow (10.0, x / 20.0) * 2.0e-5) // Normal dB's #define DB_to_A(x) (pow (10.0, x / 20.0)) /********************* PhonationTier ************************/ Thing_implement (PhonationPoint, Daata, 0); autoPhonationPoint PhonationPoint_create (double time, double period, double openPhase, double collisionPhase, double te, double power1, double power2, double pulseScale) { try { autoPhonationPoint me = Thing_new (PhonationPoint); my time = time; my period = period; my openPhase = openPhase; my collisionPhase = collisionPhase; my te = te; my power1 = power1; my power2 = power2; my pulseScale = pulseScale; return me.transfer(); } catch (MelderError) { Melder_throw (U"PhonationPoint not created."); } } Thing_implement (PhonationTier, Function, 0); autoPhonationTier PhonationTier_create (double tmin, double tmax) { try { autoPhonationTier me = Thing_new (PhonationTier); Function_init (me.peek(), tmin, tmax); my points = SortedSetOfDouble_create (); return me; } catch (MelderError) { Melder_throw (U"PhonationTier not created."); } } autoPointProcess PhonationTier_to_PointProcess_closures (PhonationTier me) { try { long nt = my points -> size; autoPointProcess thee = PointProcess_create (my xmin, my xmax, nt); for (long ip = 1; ip <= nt; ip++) { PhonationPoint fp = (PhonationPoint) my points -> item[ip]; PointProcess_addPoint (thee.peek(), fp -> time); } return thee; } catch (MelderError) { Melder_throw (me, U": no PointProcess with closure times created."); } } /********************** PhonationGridPlayOptions **********************/ Thing_implement (PhonationGridPlayOptions, Daata, 0); static void PhonationGridPlayOptions_setDefaults (PhonationGridPlayOptions me) { my flowDerivative = my voicing = 1; my aspiration = my breathiness = 1; my flutter = my doublePulsing = 1; my collisionPhase = my spectralTilt = 1; my flowFunction = 1; // User defined flow tiers (power1 & power2) my maximumPeriod = 0; } autoPhonationGridPlayOptions PhonationGridPlayOptions_create () { try { autoPhonationGridPlayOptions me = Thing_new (PhonationGridPlayOptions); return me; } catch (MelderError) { Melder_throw (U"PhonationGridPlayOptions not created."); } } /********************** PhonationGrid **********************/ Thing_implement (PhonationGrid, Function, 0); void structPhonationGrid :: v_info () { structDaata :: v_info (); const char32 *in1 = U" ", *in2 = U" "; MelderInfo_writeLine (in1, U"Time domain:"); MelderInfo_writeLine (in2, U"Start time: ", xmin, U" seconds"); MelderInfo_writeLine (in2, U"End time: ", xmax, U" seconds"); MelderInfo_writeLine (in2, U"Total duration: ", xmax - xmin, U" seconds"); MelderInfo_writeLine (in1, U"\nNumber of points in the PHONATION tiers:"); MelderInfo_writeLine (in2, U"pitch: ", pitch -> points -> size); MelderInfo_writeLine (in2, U"voicingAmplitude: ", voicingAmplitude -> points -> size); MelderInfo_writeLine (in2, U"openPhase: ", openPhase -> points -> size); MelderInfo_writeLine (in2, U"collisionPhase: ", collisionPhase -> points -> size); MelderInfo_writeLine (in2, U"power1: ", power1 -> points -> size); MelderInfo_writeLine (in2, U"power2: ", power2 -> points -> size); MelderInfo_writeLine (in2, U"flutter: ", flutter -> points -> size); MelderInfo_writeLine (in2, U"doublePulsing: ", doublePulsing -> points -> size); MelderInfo_writeLine (in2, U"spectralTilt: ", spectralTilt -> points -> size); MelderInfo_writeLine (in2, U"aspirationAmplitude: ", aspirationAmplitude -> points -> size); MelderInfo_writeLine (in2, U"breathinessAmplitude:", breathinessAmplitude -> points -> size); } void PhonationGrid_setNames (PhonationGrid me) { Thing_setName (my pitch.get(), U"pitch"); Thing_setName (my voicingAmplitude.get(), U"voicingAmplitude"); Thing_setName (my openPhase.get(), U"openPhase"); Thing_setName (my collisionPhase.get(), U"collisionPhase"); Thing_setName (my power1.get(), U"power1"); Thing_setName (my power2.get(), U"power2"); Thing_setName (my flutter.get(), U"flutter"); Thing_setName (my doublePulsing.get(), U"doublePulsing"); Thing_setName (my spectralTilt.get(), U"spectralTilt"); Thing_setName (my aspirationAmplitude.get(), U"aspirationAmplitude"); Thing_setName (my breathinessAmplitude.get(), U"breathinessAmplitude"); } autoPhonationGrid PhonationGrid_create (double tmin, double tmax) { try { autoPhonationGrid me = Thing_new (PhonationGrid); Function_init (me.peek(), tmin, tmax); my pitch = PitchTier_create (tmin, tmax); my voicingAmplitude = IntensityTier_create (tmin, tmax).transfer(); my openPhase = RealTier_create (tmin, tmax); my collisionPhase = RealTier_create (tmin, tmax); my power1 = RealTier_create (tmin, tmax); my power2 = RealTier_create (tmin, tmax); my flutter = RealTier_create (tmin, tmax); my doublePulsing = RealTier_create (tmin, tmax); my spectralTilt = IntensityTier_create (tmin, tmax).transfer(); my aspirationAmplitude = IntensityTier_create (tmin, tmax).transfer(); my breathinessAmplitude = IntensityTier_create (tmin, tmax).transfer(); my options = PhonationGridPlayOptions_create (); PhonationGrid_setNames (me.peek()); return me.transfer(); } catch (MelderError) { Melder_throw (U"PhonationGrid not created."); } } static void PhonationGrid_checkFlowFunction (PhonationGrid me) { int hasPower1Points = my power1 -> points -> size > 0; int hasPower2Points = my power2 -> points -> size > 0; long ipoint = 1; do { double time = hasPower1Points ? ( (RealPoint) (my power1 -> points -> item[ipoint])) -> number : 0.5 * (my xmin + my xmax); double power1 = RealTier_getValueAtIndex (my power1.get(), ipoint); if (power1 == NUMundefined) { power1 = KlattGrid_POWER1_DEFAULT; } if (power1 <= 0) { Melder_throw (U"All power1 values must greater than zero."); } double power2 = RealTier_getValueAtTime (my power2.get(), time); if (power2 == NUMundefined) { power2 = KlattGrid_POWER2_DEFAULT; } if (power2 <= power1) { Melder_throw (U"At all times a power1 value must be smaller than the corresponding power2 value."); } } while (++ipoint < my power1 -> points -> size); // Now check power2 values. This is necessary to catch situations where power2 has a valley: // power1(0) = 3; power2(1)= 4; power2(1)= 4; power2(0.5) = 3; ipoint = 1; do { double time = hasPower2Points ? ( (RealPoint) (my power2 -> points -> item[ipoint])) -> number : 0.5 * (my xmin + my xmax); double power2 = RealTier_getValueAtIndex (my power2.get(), ipoint); if (power2 == NUMundefined) { power2 = KlattGrid_POWER2_DEFAULT; } double power1 = RealTier_getValueAtTime (my power1.get(), time); if (power1 == NUMundefined) { power1 = KlattGrid_POWER1_DEFAULT; } if (power2 <= power1) { Melder_throw (U"At all times the power2 value must be greater than the corresponding power1 value."); } } while (++ipoint < my power2 -> points -> size); } static void PhonationGrid_draw_inside (PhonationGrid me, Graphics g, double xmin, double xmax, double ymin, double ymax, double dy, double *yout) { // dum voicing conn tilt conn summer (void) me; double xw[6] = { 0, 1, 0.5, 1, 0.5, 0.5 }, xws[6]; connections thee = connections_create (2); rel_to_abs (xw, xws, 5, xmax - xmin); dy = (ymax - ymin) / (1 + (dy < 0 ? 0 : dy) + 1); double x1 = xmin, x2 = x1 + xw[1]; double y2 = ymax, y1 = y2 - dy; draw_oneSection (g, x1, x2, y1, y2, nullptr, U"Voicing", 0); x1 = x2; x2 = x1 + xw[2]; double ymid = (y1 + y2) / 2; Graphics_line (g, x1, ymid, x2, ymid); x1 = x2; x2 = x1 + xw[3]; draw_oneSection (g, x1, x2, y1, y2, nullptr, U"Tilt", 0); thy x[1] = x2; thy y[1] = ymid; y2 = y1 - 0.5 * dy; y1 = y2 - dy; ymid = (y1 + y2) / 2; x2 = xmin + xws[3]; x1 = x2 - 1.5 * xw[3]; // some extra space draw_oneSection (g, x1, x2, y1, y2, nullptr, U"Aspiration", 0); thy x[2] = x2; thy y[2] = ymid; double r = xw[5] / 2; double xs = xmax - r, ys = (ymax + ymin) / 2; int arrow = 1; summer_drawConnections (g, xs, ys, r, thee, arrow, 0.4); connections_free (thee); if (yout != 0) { *yout = ys; } } void PhonationGrid_draw (PhonationGrid me, Graphics g) { double xmin = 0, xmax2 = 0.9, xmax = 1, ymin = 0, ymax = 1, dy = 0.5, yout; Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); PhonationGrid_draw_inside (me, g, xmin, xmax2, ymin, ymax, dy, &yout); Graphics_arrow (g, xmax2, yout, xmax, yout); Graphics_unsetInner (g); } double PhonationGrid_getMaximumPeriod (PhonationGrid me) { double minimumPitch = RealTier_getMinimumValue (my pitch.get()); return 2 / ( (minimumPitch == NUMundefined || minimumPitch == 0) ? (my xmax - my xmin) : minimumPitch); } autoPointProcess PitchTier_to_PointProcess_flutter (PitchTier pitch, RealTier flutter, double maximumPeriod) { try { autoPointProcess thee = PitchTier_to_PointProcess (pitch); if (flutter == 0) { return thee.transfer(); } double tsum = 0; for (long it = 2; it <= thy nt; it++) { double t = thy t[it - 1]; double period = thy t[it] - thy t[it - 1]; if (period < maximumPeriod && flutter -> points -> size > 0) { double fltr = RealTier_getValueAtTime (flutter, t); if (NUMdefined (fltr)) { // newF0 = f0 * (1 + (val / 50) * (sin ... + ...)); double newPeriod = period / (1 + (fltr / 50) * (sin (2 * NUMpi * 12.7 * t) + sin (2 * NUMpi * 7.1 * t) + sin (2 * NUMpi * 4.7 * t))); tsum += newPeriod - period; } } thy t[it] += tsum; } return thee.transfer(); } catch (MelderError) { Melder_throw (pitch, U": no flutter PointProcess created."); } } autoSound PhonationGrid_to_Sound_aspiration (PhonationGrid me, double samplingFrequency) { try { autoSound thee = Sound_createEmptyMono (my xmin, my xmax, samplingFrequency); // Noise spectrum is tilted down by soft low-pass filter having a pole near // the origin in the z-plane, i.e. y[n] = x[n] + (0.75 * y[n-1]) double lastval = 0; if (my aspirationAmplitude -> points -> size > 0) { for (long i = 1; i <= thy nx; i++) { double t = thy x1 + (i - 1) * thy dx; double val = NUMrandomUniform (-1, 1); double a = DBSPL_to_A (RealTier_getValueAtTime (my aspirationAmplitude.get(), t)); if (NUMdefined (a)) { thy z[1][i] = lastval = val + 0.75 * lastval; lastval = (val += 0.75 * lastval); // soft low-pass thy z[1][i] = val * a; } } } return thee; } catch (MelderError) { Melder_throw (me, U": no aspiration Sound created."); } } static void Sound_PhonationGrid_spectralTilt_inline (Sound thee, PhonationGrid me) { if (my spectralTilt -> points -> size > 0) { /* Spectral tilt Filter y[n] = a * x[n] + b * y[n-1] => H(z) = a / (1 - bz^(-1)). We need attenuation, i.e. low-pass. Therefore 0 <= b <= 1. |H(f)| = a / sqrt (1 - 2*b*cos(2*pi*f*T) + b^2), |H(0)|= a /(1 - b) => if |H(0)| == 1, then a = 1 - b. Now solve 20 log|H(F)|= -c (at F=3 kHz and c > 0) Solution: if q = (1 - D * cos(2*pi*F*T)) / (1 - D), with D = 10^(-c/10) then b = q -sqrt(q^2 - 1) */ double cosf = cos (2 * NUMpi * 3000 * thy dx), ynm1 = 0; // samplingFrequency > 6000 ! for (long i = 1; i <= thy nx; i++) { double t = thy x1 + (i - 1) * thy dx; double tilt_db = RealTier_getValueAtTime (my spectralTilt.get(), t); if (tilt_db > 0) { double d = pow (10, -tilt_db / 10); double q = (1 - d * cosf) / (1 - d); double b = q - sqrt (q * q - 1); double a = 1 - b; thy z[1][i] = a * thy z[1][i] + b * ynm1; ynm1 = thy z[1][i]; } } } } struct nrfunction_struct { double n; double m; double a; }; static void nrfunction (double x, double *fx, double *dfx, void *closure) { struct nrfunction_struct *nrfs = (struct nrfunction_struct *) closure; double mplusax = nrfs -> m + nrfs -> a * x; double mminn = nrfs -> m - nrfs -> n; *fx = pow (x, mminn) - (nrfs -> n + nrfs -> a * x) / mplusax; *dfx = mminn * pow (x, mminn - 1) - nrfs -> a * mminn / (mplusax * mplusax); } static double get_collisionPoint_x (double n, double m, double collisionPhase) { double y = NUMundefined; /* Domain [0,1]: The glottal flow is given by: U(y) = y^n - y^m 0<= y <= x, and m > n (x^n - x^m)exp(-a(y-x)) y >= x, where a = 1 / collisionPhase The x where this occurs is the point where the amplitudes as well as the derivatives are equal. I.e. the x where n x^(n-1) - m x^(m-1) = (x^n-x^m)(-a). This can be simplified: find x in (0,1) where f(x) = x^(m-n) - (n+ax)/(m+ax) == 0. For m - n == 1, f(x) is a second order equation f(x)= a x^2 + (m-a) x - n == 0. In all other cases we solve with Newton-Raphson. For these cases we also need the derivative: f'(x)= (m - n)x^(m - n - 1)- a(m - n) / (m + a x)^2 */ if (collisionPhase <= 0) { return 1; } double a = 1 / collisionPhase; if (m - n == 1) { double b = m - a; double c = - n, y1, y2; long nroots = NUMsolveQuadraticEquation (a, b, c, &y1, &y2); if (nroots == 2) { y = y2; } else if (nroots == 1) { y = y1; } } else { // Newton-Raphson // search in the interval from where the flow is a maximum to 1 struct nrfunction_struct nrfs = {n, m, a}; double root, xmaxFlow = pow (n / m, 1.0 / (m - n)); NUMnrbis (&nrfunction, xmaxFlow, 1, &nrfs, &root); y = root; } return y; } autoPhonationTier PhonationGrid_to_PhonationTier (PhonationGrid me) { try { long diplophonicPulseIndex = 0; PhonationGridPlayOptions pp = my options.get(); PhonationGrid_checkFlowFunction (me); if (my pitch -> points -> size == 0) { Melder_throw (U"Pitch tier is empty."); } if (pp -> maximumPeriod == 0) { pp -> maximumPeriod = PhonationGrid_getMaximumPeriod (me); } autoPointProcess point = PitchTier_to_PointProcess_flutter (my pitch.get(), (pp -> flutter ? my flutter.get() : nullptr), pp -> maximumPeriod); autoPhonationTier thee = PhonationTier_create (my xmin, my xmax); /* Cycle through the points of the point PointProcess. Each will become a period. We assume that the planning for the pitch period occurs approximately at a time T before the glottal closure. For each point t[i]: Determine the f0 -> period T[i] Determine time t[i]-T[i] the open quotient, power1, power2, collisionphase etc. Generate the period. */ for (long it = 1; it <= point -> nt; it++) { double re, t = point -> t[it]; // the glottis "closing" point double pulseDelay = 0; // For alternate pulses in case of diplophonia double pulseScale = 1; // For alternate pulses in case of diplophonia double period = PointProcess_getPeriodAtIndex (point.peek(), it, pp -> maximumPeriod); if (period == NUMundefined) { period = 0.5 * pp -> maximumPeriod; // Some default value } // Calculate the point where the exponential decay starts: // Query tiers where period starts . double periodStart = t - period; // point where period starts: double collisionPhase = pp -> collisionPhase ? RealTier_getValueAtTime (my collisionPhase.get(), periodStart) : 0; if (collisionPhase == NUMundefined) { collisionPhase = 0; } double power1 = pp -> flowFunction == 1 ? RealTier_getValueAtTime (my power1.get(), periodStart) : pp -> flowFunction; if (power1 == NUMundefined) { power1 = KlattGrid_POWER1_DEFAULT; } double power2 = pp -> flowFunction == 1 ? RealTier_getValueAtTime (my power2.get(), periodStart) : pp -> flowFunction + 1; if (power2 == NUMundefined) { power2 = KlattGrid_POWER2_DEFAULT; } try { re = get_collisionPoint_x (power1, power2, collisionPhase); } catch (MelderError) { Melder_warning (U"Illegal collision point at t = ", t, U" (power1=", power1, U", power2=", power2, U"colPhase=", collisionPhase, U")"); } double openPhase = RealTier_getValueAtTime (my openPhase.get(), periodStart); if (openPhase == NUMundefined) { openPhase = KlattGrid_OPENPHASE_DEFAULT; } double te = re * period * openPhase; // In case of diplophonia alternate pulses get modified. // A modified puls is delayed in time and its amplitude attenuated. // This delay scales to maximally equal the closed phase of the next period. // The doublePulsing scales the amplitudes as well as the delay linearly. double doublePulsing = pp -> doublePulsing ? RealTier_getValueAtTime (my doublePulsing.get(), periodStart) : 0.0; if (doublePulsing == NUMundefined) { doublePulsing = 0.0; } if (doublePulsing > 0.0) { diplophonicPulseIndex++; if (diplophonicPulseIndex % 2 == 1) { // the odd one double nextPeriod = PointProcess_getPeriodAtIndex (point.peek(), it + 1, pp -> maximumPeriod); if (nextPeriod == NUMundefined) { nextPeriod = period; } double openPhase2 = KlattGrid_OPENPHASE_DEFAULT; if (my openPhase -> points -> size > 0) { openPhase2 = RealTier_getValueAtTime (my openPhase.get(), t); } double maxDelay = period * (1.0 - openPhase2); pulseDelay = maxDelay * doublePulsing; pulseScale *= (1.0 - doublePulsing); } } else { diplophonicPulseIndex = 0; } t += pulseDelay; autoPhonationPoint phonationPoint = PhonationPoint_create (t, period, openPhase, collisionPhase, te, power1, power2, pulseScale); AnyTier_addPoint (thee.peek(), phonationPoint.transfer()); } return thee; } catch (MelderError) { Melder_throw (me, U": no PhonationTier created."); } } autoSound PhonationGrid_PhonationTier_to_Sound_voiced (PhonationGrid me, PhonationTier thee, double samplingFrequency) { try { PhonationGridPlayOptions p = my options.get(); double lastVal = NUMundefined; if (my voicingAmplitude -> points -> size == 0) { Melder_throw (U"Voicing amplitude tier is empty."); } autoSound him = Sound_createEmptyMono (my xmin, my xmax, samplingFrequency); autoSound breathy; if (p -> breathiness && my breathinessAmplitude -> points -> size > 0) { breathy = Sound_createEmptyMono (my xmin, my xmax, samplingFrequency); } /* Cycle through the points of the PhonationTier. Each will become a period. We assume that the planning for the pitch period occurs approximately at a time T before the glottal closure. For each point t[i]: Determine the f0 -> period T[i] Determine time t[i]-T[i] the open quotient, power1, power2, collisionphase etc. Generate the period. */ double *sound = his z[1]; for (long it = 1; it <= thy points -> size; it++) { PhonationPoint point = (PhonationPoint) thy points -> item[it]; double t = point -> time; // the glottis "closing" point double te = point -> te; double period = point -> period; // duration of the current period double openPhase = point -> openPhase; double collisionPhase = point -> collisionPhase; double pulseScale = point -> pulseScale; // For alternate pulses in case of diplophonia double power1 = point -> power1, power2 = point -> power2; double phase; // 0..1 double flow; //- double amplitude = pulseScale * (power1 + power2 + 1.0) / (power2 - power1); //- amplitude /= period * openPhase; // Maximum of U(x) = x^n - x^m is where the derivative U'(x) = n x^(n-1) - m x^(m-1) == 0, // i.e. (n/m) = x^(m-n), so xmax = (n/m)^(1/(m-n)) // U(xmax) = x^n (1-x^(m-n)) = (n/m)^(n/(m-n))(1-n/m) double amplitude = pulseScale / (pow (power1 / power2, 1 / (power2 / power1 - 1)) * (1 - power1 / power2)); // Fill in the samples to the left of the current point. long midSample = Sampled_xToLowIndex (him.peek(), t), beginSample; beginSample = midSample - (long) floor (te / his dx); if (beginSample < 1) { beginSample = 0; } if (midSample > his nx) { midSample = his nx; } for (long i = beginSample; i <= midSample; i++) { double tsamp = his x1 + (i - 1) * his dx; phase = (tsamp - (t - te)) / (period * openPhase); if (phase > 0.0) { flow = amplitude * (pow (phase, power1) - pow (phase, power2)); if (i == 0) { lastVal = flow; // For the derivative continue; } sound[i] += flow; // Breathiness only during open part modulated by the flow if (breathy.peek() != 0) { double val = flow * NUMrandomUniform (-1, 1); double a = RealTier_getValueAtTime (my breathinessAmplitude.get(), t); breathy -> z[1][i] += val * DBSPL_to_A (a); } } } // Determine the signal parameters at the current point. phase = te / (period * openPhase); //- double flow = amplitude * (period * openPhase) * (pow (phase, power1) - pow (phase, power2)); flow = amplitude * (pow (phase, power1) - pow (phase, power2)); // Fill in the samples to the right of the current point. if (flow > 0.0) { double ta = collisionPhase * (period * openPhase); double factorPerSample = exp (- his dx / ta); double value = flow * exp (- (his x1 + midSample * his dx - t) / ta); long endSample = midSample + (long) floor (20 * ta / his dx); if (endSample > his nx) { endSample = his nx; } for (long i = midSample + 1; i <= endSample; i++) { sound[i] += value; value *= factorPerSample; } } } // Scale voiced part and add breathiness during open phase if (p -> flowDerivative) { double extremum = Vector_getAbsoluteExtremum (him.peek(), 0, 0, Vector_VALUE_INTERPOLATION_CUBIC); if (! NUMdefined (lastVal)) { lastVal = 0; } for (long i = 1; i <= his nx; i++) { double val = his z[1][i]; his z[1][i] -= lastVal; lastVal = val; } Vector_scale (him.peek(), extremum); } for (long i = 1; i <= his nx; i++) { double t = his x1 + (i - 1) * his dx; his z[1][i] *= DBSPL_to_A (RealTier_getValueAtTime (my voicingAmplitude.get(), t)); if (breathy.peek() != 0) { his z[1][i] += breathy -> z[1][i]; } } return him; } catch (MelderError) { Melder_throw (me, U": no Sound created."); } } static Sound PhonationGrid_to_Sound_voiced (PhonationGrid me, double samplingFrequency) { try { autoPhonationTier thee = PhonationGrid_to_PhonationTier (me); autoSound him = PhonationGrid_PhonationTier_to_Sound_voiced (me, thee.peek(), samplingFrequency); return him.transfer(); } catch (MelderError) { Melder_throw (me, U": no voiced Sound created."); } } static Sound PhonationGrid_to_Sound (PhonationGrid me, CouplingGrid him, double samplingFrequency) { try { PhonationGridPlayOptions pp = my options.get(); autoSound thee; if (pp -> voicing) { if (him && his glottis -> points -> size > 0) { thee = PhonationGrid_PhonationTier_to_Sound_voiced (me, his glottis.get(), samplingFrequency); } else { thee = PhonationGrid_to_Sound_voiced (me, samplingFrequency); } if (pp -> spectralTilt) { Sound_PhonationGrid_spectralTilt_inline (thee.peek(), me); } } if (pp -> aspiration) { autoSound aspiration = PhonationGrid_to_Sound_aspiration (me, samplingFrequency); if (! thee.peek()) { thee = aspiration.move(); } else { _Sounds_add_inline (thee.peek(), aspiration.peek()); } } if (! thee.peek()) { thee = Sound_createEmptyMono (my xmin, my xmax, samplingFrequency); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no Sound created."); } } static Ordered formantsAmplitudes_create (double tmin, double tmax, long numberOfFormants) { try { autoOrdered me = Ordered_create (); for (long i = 1; i <= numberOfFormants; i++) { autoIntensityTier a = IntensityTier_create (tmin, tmax); Collection_addItem (me.peek(), a.transfer()); } return me.transfer(); } catch (MelderError) { Melder_throw (U"No formants amplitudes created."); }; } /********************** VocalTractGridPlayOptions **********************/ Thing_implement (VocalTractGridPlayOptions, Daata, 0); static void VocalTractGridPlayOptions_setDefaults (VocalTractGridPlayOptions me, VocalTractGrid thee) { my filterModel = KlattGrid_FILTER_CASCADE; my endOralFormant = MIN (thy oral_formants -> formants -> size, thy oral_formants -> bandwidths -> size); my startOralFormant = 1; my endNasalFormant = MIN (thy nasal_formants -> formants -> size, thy nasal_formants -> bandwidths -> size); my startNasalFormant = 1; my endNasalAntiFormant = MIN (thy nasal_antiformants -> formants -> size, thy nasal_antiformants -> bandwidths -> size); my startNasalAntiFormant = 1; } autoVocalTractGridPlayOptions VocalTractGridPlayOptions_create () { try { autoVocalTractGridPlayOptions me = Thing_new (VocalTractGridPlayOptions); return me; } catch (MelderError) { Melder_throw (U"VocalTractGridPlayOptions not created."); } } /********************** VocalTractGrid ***************************************/ static long FormantGrid_getNumberOfFormantPoints (FormantGrid me, long iformant) { if (iformant < 1 || iformant > my formants -> size) { return -1; } RealTier f = (RealTier) my formants -> item[iformant]; return f -> points -> size; } static long FormantGrid_getNumberOfBandwidthPoints (FormantGrid me, long iformant) { if (iformant < 1 || iformant > my bandwidths -> size) { return -1; } RealTier b = (RealTier) my bandwidths -> item[iformant]; return b -> points -> size; } static long Ordered_getNumberOfAmplitudePoints (Ordered me, long iformant) { if (me == 0 || iformant < 1 || iformant > my size) { return -1; } RealTier t = (RealTier) my item[iformant]; return t -> points -> size; } static void FormantGrid_info (FormantGrid me, Ordered amplitudes, const char32 *in1, const char32 *in2) { long nformants = my formants -> size; long namplitudes = amplitudes ? amplitudes -> size : 0; long nmax = MAX (nformants, namplitudes); for (long iformant = 1; iformant <= nmax; iformant++) { MelderInfo_writeLine (in1, U"Formant ", iformant, U":"); if (iformant <= my formants -> size) { long nfp = FormantGrid_getNumberOfFormantPoints (me, iformant); long nbp = FormantGrid_getNumberOfBandwidthPoints (me, iformant); MelderInfo_writeLine (in2, U"formants: ", (nfp >= 0 ? Melder_integer (nfp) : U"--undefined--")); MelderInfo_writeLine (in2, U"bandwidths: ", (nbp >= 0 ? Melder_integer (nbp) : U"--undefined--")); } if (amplitudes) { long nap = Ordered_getNumberOfAmplitudePoints (amplitudes, iformant); MelderInfo_writeLine (in2, U"amplitudes: ", (nap >= 0 ? Melder_integer (nap) : U"--undefined--")); } } } void structVocalTractGrid :: v_info () { structDaata :: v_info (); const char32 *in1 = U" ", *in2 = U" ", *in3 = U" "; MelderInfo_writeLine (in1, U"Time domain:"); MelderInfo_writeLine (in2, U"Start time: ", xmin, U" seconds"); MelderInfo_writeLine (in2, U"End time: ", xmax, U" seconds"); MelderInfo_writeLine (in2, U"Total duration: ", xmax - xmin, U" seconds"); MelderInfo_writeLine (in1, U"\nNumber of points in the ORAL FORMANT tiers:"); FormantGrid_info (our oral_formants.get(), oral_formants_amplitudes, in2, in3); MelderInfo_writeLine (in1, U"\nNumber of points in the NASAL FORMANT tiers:"); FormantGrid_info (our nasal_formants.get(), nasal_formants_amplitudes, in2, in3); MelderInfo_writeLine (in1, U"\nNumber of points in the NASAL ANTIFORMANT tiers:"); FormantGrid_info (our nasal_antiformants.get(), nullptr, in2, in3); } Thing_implement (VocalTractGrid, Function, 0); void VocalTractGrid_setNames (VocalTractGrid me) { Thing_setName (my oral_formants.get(), U"oral_formants"); Thing_setName (my nasal_formants.get(), U"nasal_formants"); Thing_setName (my nasal_antiformants.get(), U"nasal_antiformants"); Thing_setName (my oral_formants_amplitudes, U"oral_formants_amplitudes"); Thing_setName (my nasal_formants_amplitudes, U"nasal_formants_amplitudes"); } autoVocalTractGrid VocalTractGrid_create (double tmin, double tmax, long numberOfFormants, long numberOfNasalFormants, long numberOfNasalAntiFormants) { try { autoVocalTractGrid me = Thing_new (VocalTractGrid); Function_init (me.peek(), tmin, tmax); my oral_formants = FormantGrid_createEmpty (tmin, tmax, numberOfFormants).transfer(); my nasal_formants = FormantGrid_createEmpty (tmin, tmax, numberOfNasalFormants).transfer(); my nasal_antiformants = FormantGrid_createEmpty (tmin, tmax, numberOfNasalAntiFormants).transfer(); my oral_formants_amplitudes = formantsAmplitudes_create (tmin, tmax, numberOfFormants); my nasal_formants_amplitudes = formantsAmplitudes_create (tmin, tmax, numberOfNasalFormants); my options = VocalTractGridPlayOptions_create (); VocalTractGrid_setNames (me.peek()); return me; } catch (MelderError) { Melder_throw (U"VocalTractGrid not created."); } } static void VocalTractGrid_CouplingGrid_drawCascade_inline (VocalTractGrid me, CouplingGrid thee, Graphics g, double xmin, double xmax, double ymin, double ymax, double *yin, double *yout) { long numberOfOralFormants = my oral_formants -> formants -> size; long numberOfNasalFormants = my nasal_formants -> formants -> size; long numberOfNasalAntiFormants = my nasal_antiformants -> formants -> size; long numberOfTrachealFormants = thee ? thy tracheal_formants -> formants -> size : 0; long numberOfTrachealAntiFormants = thee ? thy tracheal_antiformants -> formants -> size : 0; double x1, y1 = ymin, x2, y2 = ymax, dx, ddx = 0.2, ymid = (y1 + y2) / 2; const char32 *text[6] = { 0, U"TF", U"TAF", U"NF", U"NAF", U""}; long nf[6] = {0, numberOfTrachealFormants, numberOfTrachealAntiFormants, numberOfNasalFormants, numberOfNasalAntiFormants, numberOfOralFormants}; long numberOfXSections = 5, nsx = 0; autoMelderString ff, fb; long numberOfFilters = numberOfNasalFormants + numberOfNasalAntiFormants + numberOfTrachealFormants + numberOfTrachealAntiFormants + numberOfOralFormants; if (numberOfFilters == 0) { x2 = xmax; Graphics_line (g, xmin, ymid, x2, ymid); goto end; } for (long isection = 1; isection <= numberOfXSections; isection++) if (nf[isection] > 0) { nsx++; } dx = (xmax - xmin) / (numberOfFilters + (nsx - 1) * ddx); x1 = xmin; for (long isection = 1; isection <= numberOfXSections; isection++) { long numberOfFormants = nf[isection]; if (numberOfFormants == 0) { continue; } x2 = x1 + dx; for (long i = 1; i <= numberOfFormants; i++) { MelderString_copy (&ff, U"F", i); MelderString_copy (&fb, U"B", i); // ppgb: met Melder_cat kan het misschien ook, // maar je weet niet of Graphics (in draw_oneSection) niet indirect de cat-buffers gebruikt, // dus deze methode is veiliger (kost bovendien maar 1 heap-allocatie voor de hele loop); // alleen Melder_sprint is nog simpeler, omdat je weet dat 40 chars genoeg is draw_oneSection (g, x1, x2, y1, y2, text[isection], ff.string, fb.string); if (i < numberOfFormants) { x1 = x2; x2 = x1 + dx; } } if (isection < numberOfXSections) { x1 = x2; x2 = x1 + ddx * dx; Graphics_line (g, x1, ymid, x2, ymid); x1 = x2; } } end: if (yin != 0) { *yin = ymid; } if (yout != 0) { *yout = ymid; } } static void VocalTractGrid_CouplingGrid_drawParallel_inline (VocalTractGrid me, CouplingGrid thee, Graphics g, double xmin, double xmax, double ymin, double ymax, double dy, double *yin, double *yout) { // (0: filler) (1: hor. line to split) (2: split to diff) (3: diff) (4: diff to split) // (5: split to filter) (6: filters) (7: conn to summer) (8: summer) double xw[9] = { 0, 0.3, 0.2, 1.5, 0.5, 0.5, 1, 0.5, 0.5 }, xws[9]; long numberOfXSections = 8, ic = 0, numberOfYSections = 4; long numberOfNasalFormants = my nasal_formants -> formants -> size; long numberOfOralFormants = my oral_formants -> formants -> size; long numberOfTrachealFormants = thee ? thy tracheal_formants -> formants -> size : 0; long numberOfFormants = numberOfNasalFormants + numberOfOralFormants + numberOfTrachealFormants; long numberOfUpperPartFormants = numberOfNasalFormants + (numberOfOralFormants > 0 ? 1 : 0); long numberOfLowerPartFormants = numberOfFormants - numberOfUpperPartFormants; double ddy = dy < 0 ? 0 : dy, x1, y1, x2, y2, x3, r, ymid; const char32 *text[5] = { 0, U"Nasal", U"", U"", U"Tracheal"}; long nffrom[5] = {0, 1, 1, 2, 1}; long nfto[5] = {0, numberOfNasalFormants, (numberOfOralFormants > 0 ? 1 : 0), numberOfOralFormants, numberOfTrachealFormants}; autoMelderString fba; rel_to_abs (xw, xws, numberOfXSections, xmax - xmin); if (numberOfFormants == 0) { y1 = y2 = (ymin + ymax) / 2; Graphics_line (g, xmin, y1, xmax, y1); if (yin) { *yin = y1; } if (yout) { *yout = y2; } return; } dy = (ymax - ymin) / (numberOfFormants * (1 + ddy) - ddy); connections local_in = connections_create (numberOfFormants); connections local_out = connections_create (numberOfFormants); // parallel section x1 = xmin + xws[5]; x2 = x1 + xw[6]; y2 = ymax; x3 = xmin + xws[4]; for (long isection = 1; isection <= numberOfYSections; isection++) { long ifrom = nffrom[isection], ito = nfto[isection]; if (ito < ifrom) { continue; } for (long i = ifrom; i <= ito; i++) { y1 = y2 - dy; ymid = (y1 + y2) / 2; const char32 *fi = Melder_integer (i); MelderString_copy (&fba, U"A", fi, U" F", fi, U" B", fi); draw_oneSection (g, x1, x2, y1, y2, text[isection], fba.string, nullptr); Graphics_line (g, x3, ymid, x1, ymid); // to the left ic++; local_in -> x[ic] = x3; local_out -> x[ic] = x2; local_in -> y[ic] = local_out -> y[ic] = ymid; y2 = y1 - 0.5 * dy; } } ic = 0; x1 = local_in -> y[1]; if (numberOfUpperPartFormants > 0) { x1 = local_in -> x[numberOfUpperPartFormants]; y1 = local_in -> y[numberOfUpperPartFormants]; if (numberOfUpperPartFormants > 1) { Graphics_line (g, x1, y1, local_in -> x[1], local_in -> y[1]); // vertical } x2 = xmin; if (numberOfLowerPartFormants > 0) { x2 += xw[1]; } Graphics_line (g, x1, y1, x2, y1); // done } if (numberOfLowerPartFormants > 0) { long ifrom = numberOfUpperPartFormants + 1; x1 = local_in -> x[ifrom]; y1 = local_in -> y[ifrom]; // at the split if (numberOfLowerPartFormants > 1) { Graphics_line (g, x1, y1, local_in -> x[numberOfFormants], local_in -> y[numberOfFormants]); // vertical } x2 = xmin + xws[3]; // right of diff Graphics_line (g, x1, y1, x2, y1); // from vertical to diff x1 = xmin + xws[2]; // left of diff draw_oneSection (g, x1, x2, y1 + 0.5 * dy, y1 - 0.5 * dy, U"Pre-emphasis", nullptr, nullptr); x2 = x1; if (numberOfUpperPartFormants > 0) { x2 = xmin + xw[1]; y2 = y1; // at split Graphics_line (g, x1, y1, x2, y1); // to split y1 += (1 + ddy) * dy; Graphics_line (g, x2, y2, x2, y1); // vertical y1 -= 0.5 * (1 + ddy) * dy; } Graphics_line (g, xmin, y1, x2, y1); } r = xw[8] / 2; x2 = xmax - r; y2 = (ymin + ymax) / 2; alternatingSummer_drawConnections (g, x2, y2, r, local_out, 1, 0.4); connections_free (local_out); connections_free (local_in); if (yin) { *yin = y1; } if (yout) { *yout = y2; } } static void VocalTractGrid_CouplingGrid_draw_inside (VocalTractGrid me, CouplingGrid thee, Graphics g, int filterModel, double xmin, double xmax, double ymin, double ymax, double dy, double *yin, double *yout) { filterModel == KlattGrid_FILTER_CASCADE ? VocalTractGrid_CouplingGrid_drawCascade_inline (me, thee, g, xmin, xmax, ymin, ymax, yin, yout) : VocalTractGrid_CouplingGrid_drawParallel_inline (me, thee, g, xmin, xmax, ymin, ymax, dy, yin, yout); } static void VocalTractGrid_CouplingGrid_draw (VocalTractGrid me, CouplingGrid thee, Graphics g, int filterModel) { double xmin = 0, xmin1 = 0.05, xmax1 = 0.95, xmax = 1, ymin = 0, ymax = 1, dy = 0.5, yin, yout; Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); Graphics_setLineWidth (g, 2); VocalTractGrid_CouplingGrid_draw_inside (me, thee, g, filterModel, xmin1, xmax1, ymin, ymax, dy, &yin, &yout); Graphics_line (g, xmin, yin, xmin1, yin); Graphics_arrow (g, xmax1, yout, xmax, yout); Graphics_unsetInner (g); } static autoSound Sound_VocalTractGrid_CouplingGrid_filter_cascade (Sound me, VocalTractGrid thee, CouplingGrid coupling) { try { VocalTractGridPlayOptions pv = thy options.get(); CouplingGridPlayOptions pc = coupling -> options.get(); bool useOpenGlottisInfo = pc -> openglottis && coupling && coupling -> glottis && coupling -> glottis -> points -> size > 0; FormantGrid oral_formants = thy oral_formants.get(); FormantGrid nasal_formants = thy nasal_formants.get(); FormantGrid nasal_antiformants = thy nasal_antiformants.get(); FormantGrid tracheal_formants = coupling -> tracheal_formants.get(); FormantGrid tracheal_antiformants = coupling -> tracheal_antiformants.get(); int antiformants = 0; long numberOfFormants = oral_formants -> formants -> size; long numberOfTrachealFormants = tracheal_formants -> formants -> size; long numberOfTrachealAntiFormants = tracheal_antiformants -> formants -> size; long numberOfNasalFormants = nasal_formants -> formants -> size; long numberOfNasalAntiFormants = nasal_antiformants -> formants -> size; check_formants (numberOfFormants, & (pv -> startOralFormant), & (pv -> endOralFormant)); check_formants (numberOfNasalFormants, & (pv -> startNasalFormant), & (pv -> endNasalFormant)); check_formants (numberOfTrachealFormants, & (pc -> startTrachealFormant), & (pc -> endTrachealFormant)); check_formants (numberOfNasalAntiFormants, & (pv -> startNasalAntiFormant), & (pv -> endNasalAntiFormant)); check_formants (numberOfTrachealAntiFormants, & (pc -> startTrachealAntiFormant), & (pc -> endTrachealAntiFormant)); autoSound him = Data_copy (me); autoFormantGrid formants; if (useOpenGlottisInfo) { formants = Data_copy (thy oral_formants.get()); FormantGrid_CouplingGrid_updateOpenPhases (formants.peek(), coupling); } long nasal_formant_warning = 0, any_warning = 0; if (pv -> endNasalFormant > 0) { // Nasal formants antiformants = 0; for (long iformant = pv -> startNasalFormant; iformant <= pv -> endNasalFormant; iformant++) { if (FormantGrid_isFormantDefined (thy nasal_formants.get(), iformant)) { _Sound_FormantGrid_filterWithOneFormant_inline (him.peek(), thy nasal_formants.get(), iformant, antiformants); } else { // Melder_warning ("Nasal formant", iformant, ": frequency and/or bandwidth missing."); nasal_formant_warning++; any_warning++; } } } long nasal_antiformant_warning = 0; if (pv -> endNasalAntiFormant > 0) { // Nasal anti formants antiformants = 1; for (long iformant = pv -> startNasalAntiFormant; iformant <= pv -> endNasalAntiFormant; iformant++) { if (FormantGrid_isFormantDefined (thy nasal_antiformants.get(), iformant)) { _Sound_FormantGrid_filterWithOneFormant_inline (him.peek(), thy nasal_antiformants.get(), iformant, antiformants); } else { // Melder_warning ("Nasal antiformant", iformant, ": frequency and/or bandwidth missing."); nasal_antiformant_warning++; any_warning++; } } } long tracheal_formant_warning = 0; if (pc -> endTrachealFormant > 0) { // Tracheal formants antiformants = 0; for (long iformant = pc -> startTrachealFormant; iformant <= pc -> endTrachealFormant; iformant++) { if (FormantGrid_isFormantDefined (tracheal_formants, iformant)) { _Sound_FormantGrid_filterWithOneFormant_inline (him.peek(), tracheal_formants, iformant, antiformants); } else { // Melder_warning ("Tracheal formant", iformant, ": frequency and/or bandwidth missing."); tracheal_formant_warning++; any_warning++; } } } long tracheal_antiformant_warning = 0; if (pc -> endTrachealAntiFormant > 0) { // Tracheal anti formants antiformants = 1; for (long iformant = pc -> startTrachealAntiFormant; iformant <= pc -> endTrachealAntiFormant; iformant++) { if (FormantGrid_isFormantDefined (tracheal_antiformants, iformant)) { _Sound_FormantGrid_filterWithOneFormant_inline (him.peek(), tracheal_antiformants, iformant, antiformants); } else { // Melder_warning ("Tracheal antiformant", iformant, ": frequency and/or bandwidth missing."); tracheal_antiformant_warning++; any_warning++; } } } long oral_formant_warning = 0; if (pv -> endOralFormant > 0) { // Oral formants antiformants = 0; if (! formants) { formants = thy oral_formants.get(); // yuck } for (long iformant = pv -> startOralFormant; iformant <= pv -> endOralFormant; iformant++) { if (FormantGrid_isFormantDefined (formants.peek(), iformant)) { _Sound_FormantGrid_filterWithOneFormant_inline (him.peek(), formants.peek(), iformant, antiformants); } else { // Melder_warning ("Oral formant", iformant, ": frequency and/or bandwidth missing."); oral_formant_warning++; any_warning++; } } } if (any_warning > 0) { autoMelderString warning; if (nasal_formant_warning > 0) { MelderString_append (&warning, U"\tNasal formants: one or more are missing.\n"); } if (nasal_antiformant_warning) { MelderString_append (&warning, U"\tNasal antiformants: one or more are missing.\n"); } if (tracheal_formant_warning) { MelderString_append (&warning, U"\tTracheal formants: one or more are missing.\n"); } if (tracheal_antiformant_warning) { MelderString_append (&warning, U"\tTracheal antiformants: one or more are missing.\n"); } if (oral_formant_warning) { MelderString_append (&warning, U"\tOral formants: one or more are missing.\n"); } MelderInfo_write (U"\nWarning:\n", warning.string); MelderInfo_drain (); } return him; } catch (MelderError) { Melder_throw (me, U": not filtered by vocaltract and coupling grid."); } } autoSound Sound_VocalTractGrid_CouplingGrid_filter_parallel (Sound me, VocalTractGrid thee, CouplingGrid coupling) { try { VocalTractGridPlayOptions pv = thy options.get(); CouplingGridPlayOptions pc = coupling -> options.get(); autoSound him; FormantGrid oral_formants = thy oral_formants.get(); autoFormantGrid aof; int alternatingSign = 0; // 0: no alternating signs in parallel adding of filter outputs, 1/-1 start sign bool useOpenGlottisInfo = pc -> openglottis && coupling -> glottis && coupling -> glottis -> points -> size > 0; int scale = 1; long numberOfFormants = thy oral_formants -> formants -> size; long numberOfNasalFormants = thy nasal_formants -> formants -> size; long numberOfTrachealFormants = coupling -> tracheal_formants -> formants -> size; check_formants (numberOfFormants, & (pv -> startOralFormant), & (pv -> endOralFormant)); check_formants (numberOfNasalFormants, & (pv -> startNasalFormant), & (pv -> endNasalFormant)); check_formants (numberOfTrachealFormants, & (pc -> startTrachealFormant), & (pc -> endTrachealFormant)); if (useOpenGlottisInfo) { aof = Data_copy (thy oral_formants.get()); oral_formants = aof.peek(); FormantGrid_CouplingGrid_updateOpenPhases (oral_formants, coupling); } if (pv -> endOralFormant > 0) { if (pv -> startOralFormant == 1) { him = Data_copy (me); if (oral_formants -> formants -> size > 0) { Sound_FormantGrid_Intensities_filterWithOneFormant_inline (him.peek(), oral_formants, thy oral_formants_amplitudes, 1); } } } if (pv -> endNasalFormant > 0) { alternatingSign = 0; autoSound nasal = Sound_FormantGrid_Intensities_filter (me, thy nasal_formants.get(), thy nasal_formants_amplitudes, pv -> startNasalFormant, pv -> endNasalFormant, alternatingSign); if (! him) { him = Data_copy (nasal.peek()); } else { _Sounds_add_inline (him.peek(), nasal.peek()); } } // Formants 2 and up, with alternating signs. // We perform pre-emphasis by differentiating. // Klatt (1980) states that a first difference for the higher formants is necessary to remove low-frequency // energy from them. This energy would otherwise distort the spectrum in the region of F1 during the synthesis // of some vowels. autoSound me_diff = _Sound_diff (me, scale); if (pv -> endOralFormant >= 2) { long startOralFormant2 = pv -> startOralFormant > 2 ? pv -> startOralFormant : 2; alternatingSign = startOralFormant2 % 2 == 0 ? -1 : 1; // 2 starts with negative sign if (startOralFormant2 <= oral_formants -> formants -> size) { autoSound vocalTract = Sound_FormantGrid_Intensities_filter (me_diff.peek(), oral_formants, thy oral_formants_amplitudes, startOralFormant2, pv -> endOralFormant, alternatingSign); if (! him) { him = Data_copy (vocalTract.peek()); } else { _Sounds_add_inline (him.peek(), vocalTract.peek()); } } } if (pc -> endTrachealFormant > 0) { // Tracheal formants alternatingSign = 0; autoSound trachea = Sound_FormantGrid_Intensities_filter (me_diff.peek(), coupling -> tracheal_formants.get(), coupling -> tracheal_formants_amplitudes, pc -> startTrachealFormant, pc -> endTrachealFormant, alternatingSign); if (! him) { him = Data_copy (trachea.peek()); } else { _Sounds_add_inline (him.peek(), trachea.peek()); } } if (! him) { him = Data_copy (me); } return him; } catch (MelderError) { Melder_throw (me, U": not filtered in parallel."); } } autoSound Sound_VocalTractGrid_CouplingGrid_filter (Sound me, VocalTractGrid thee, CouplingGrid coupling) { return thy options -> filterModel == KlattGrid_FILTER_CASCADE ? Sound_VocalTractGrid_CouplingGrid_filter_cascade (me, thee, coupling) : Sound_VocalTractGrid_CouplingGrid_filter_parallel (me, thee, coupling); } /********************** CouplingGridPlayOptions **********************/ Thing_implement (CouplingGridPlayOptions, Daata, 0); static void CouplingGridPlayOptions_setDefaults (CouplingGridPlayOptions me, CouplingGrid thee) { my fadeFraction = 0.1; my openglottis = 1; my endTrachealFormant = MIN (thy tracheal_formants -> formants -> size, thy tracheal_formants -> bandwidths -> size); my startTrachealFormant = 1; my endTrachealAntiFormant = MIN (thy tracheal_antiformants -> formants -> size, thy tracheal_antiformants -> bandwidths -> size); my startTrachealAntiFormant = 1; my startDeltaFormant = 1; my endDeltaFormant = thy delta_formants -> formants -> size; my startDeltaBandwidth = 1; my endDeltaBandwidth = thy delta_formants -> bandwidths -> size; } autoCouplingGridPlayOptions CouplingGridPlayOptions_create () { try { autoCouplingGridPlayOptions me = Thing_new (CouplingGridPlayOptions); return me; } catch (MelderError) { Melder_throw (U"CouplingGridPlayOptions not created."); } } /********************** CouplingGrid *************************************/ Thing_implement (CouplingGrid, Function, 0); void structCouplingGrid :: v_info () { structDaata :: v_info (); const char32 *in1 = U" ", *in2 = U" ", *in3 = U" "; MelderInfo_writeLine (in1, U"Time domain:"); MelderInfo_writeLine (in2, U"Start time: ", xmin, U" seconds"); MelderInfo_writeLine (in2, U"End time: ", xmax, U" seconds"); MelderInfo_writeLine (in2, U"Total duration: ", xmax - xmin, U" seconds"); MelderInfo_writeLine (in1, U"\nNumber of points in the TRACHEAL FORMANT tiers:"); FormantGrid_info (our tracheal_formants.get(), tracheal_formants_amplitudes, in2, in3); MelderInfo_writeLine (in1, U"\nNumber of points in the TRACHEAL ANTIFORMANT tiers:"); FormantGrid_info (our tracheal_antiformants.get(), nullptr, in2, in3); MelderInfo_writeLine (in1, U"\nNumber of points in the DELTA FORMANT tiers:"); FormantGrid_info (our delta_formants.get(), nullptr, in2, in3); } void CouplingGrid_setNames (CouplingGrid me) { Thing_setName (my tracheal_formants.get(), U"tracheal_formants"); Thing_setName (my tracheal_antiformants.get(), U"tracheal_antiformants"); Thing_setName (my tracheal_formants_amplitudes, U"tracheal_formants_amplitudes"); Thing_setName (my delta_formants.get(), U"delta_formants"); Thing_setName (my glottis.get(), U"glottis"); } autoCouplingGrid CouplingGrid_create (double tmin, double tmax, long numberOfTrachealFormants, long numberOfTrachealAntiFormants, long numberOfDeltaFormants) { try { autoCouplingGrid me = Thing_new (CouplingGrid); Function_init (me.peek(), tmin, tmax); my tracheal_formants = FormantGrid_createEmpty (tmin, tmax, numberOfTrachealFormants).transfer(); my tracheal_antiformants = FormantGrid_createEmpty (tmin, tmax, numberOfTrachealAntiFormants).transfer(); my tracheal_formants_amplitudes = formantsAmplitudes_create (tmin, tmax, numberOfTrachealFormants); my delta_formants = FormantGrid_createEmpty (tmin, tmax, numberOfDeltaFormants).transfer(); my glottis = PhonationTier_create (tmin, tmax); my options = CouplingGridPlayOptions_create (); CouplingGrid_setNames (me.peek()); return me; } catch (MelderError) { Melder_throw (U"CouplingGrid not created."); } } /********************** FormantGrid & CouplingGrid *************************************/ void FormantGrid_CouplingGrid_updateOpenPhases (FormantGrid me, CouplingGrid thee) { try { CouplingGridPlayOptions pc = thy options.get(); for (long itier = 1; itier <= thy delta_formants -> formants -> size; itier++) { RealTier delta = (RealTier) thy delta_formants -> formants -> item[itier]; if (itier <= my formants -> size) { if (delta -> points -> size > 0) { autoRealTier rt = RealTier_updateWithDelta ( (RealTier) my formants -> item[itier], delta, thy glottis.get(), pc -> fadeFraction); if (! RealTier_valuesInRange (rt.peek(), 0, NUMundefined)) { Melder_throw (U"Formant ", itier, U" coupling gives negative values."); } forget ( ( (Thing *) my formants -> item) [itier]); my formants -> item[itier] = rt.transfer(); } } delta = (RealTier) thy delta_formants -> bandwidths -> item[itier]; if (itier <= my bandwidths -> size) { if (delta -> points -> size > 0) { autoRealTier rt = RealTier_updateWithDelta ( (RealTier) my bandwidths -> item[itier], delta, thy glottis.get(), pc -> fadeFraction); if (! RealTier_valuesInRange (rt.peek(), 0, NUMundefined)) { Melder_throw (U"Bandwidth ", itier, U" coupling gives negative values."); } forget ( ( (Thing *) my bandwidths -> item) [itier]); my bandwidths -> item[itier] = rt.transfer(); } } } } catch (MelderError) { Melder_throw (me, U": not updated with open hase information."); } } /************************ Sound & FormantGrid *********************************************/ void _Sound_FormantGrid_filterWithOneFormant_inline (Sound me, thou, long iformant, int antiformant) { thouart (FormantGrid); if (iformant < 1 || iformant > thy formants -> size) { Melder_warning (U"Formant ", iformant, U" does not exist."); return; } RealTier ftier = (RealTier) thy formants -> item[iformant]; RealTier btier = (RealTier) thy bandwidths -> item[iformant]; if (ftier -> points -> size == 0 && btier -> points -> size == 0) { return; } else if (ftier -> points -> size == 0 || btier -> points -> size == 0) { Melder_throw (U"Empty tier"); } double nyquist = 0.5 / my dx; autoFilter r; if (antiformant != 0) { r = AntiResonator_create (my dx); } else { r = Resonator_create (my dx, Resonator_NORMALISATION_H0); } for (long is = 1; is <= my nx; is++) { double t = my x1 + (is - 1) * my dx; double f = RealTier_getValueAtTime (ftier, t); double b = RealTier_getValueAtTime (btier, t); if (f <= nyquist && NUMdefined (b)) { Filter_setFB (r.peek(), f, b); } my z[1][is] = Filter_getOutput (r.peek(), my z[1][is]); } } void Sound_FormantGrid_filterWithOneAntiFormant_inline (Sound me, FormantGrid thee, long iformant) { _Sound_FormantGrid_filterWithOneFormant_inline (me, thee, iformant, 1); } void Sound_FormantGrid_filterWithOneFormant_inline (Sound me, FormantGrid thee, long iformant) { _Sound_FormantGrid_filterWithOneFormant_inline (me, thee, iformant, 0); } void Sound_FormantGrid_Intensities_filterWithOneFormant_inline (Sound me, FormantGrid thee, Ordered amplitudes, long iformant) { try { if (iformant < 1 || iformant > thy formants -> size) { Melder_throw (U"Formant ", iformant, U" not defined. \nThis formant will not be used."); } double nyquist = 0.5 / my dx; RealTier ftier = (RealTier) thy formants -> item[iformant]; RealTier btier = (RealTier) thy bandwidths -> item[iformant]; RealTier atier = (RealTier) amplitudes -> item[iformant]; if (ftier -> points -> size == 0 || btier -> points -> size == 0 || atier -> points -> size == 0) { return; // nothing to do } autoResonator r = Resonator_create (my dx, Resonator_NORMALISATION_HMAX); for (long is = 1; is <= my nx; is++) { double t = my x1 + (is - 1) * my dx; double f = RealTier_getValueAtTime (ftier, t); double b = RealTier_getValueAtTime (btier, t); double a; if (f <= nyquist && NUMdefined (b)) { Filter_setFB (r.peek(), f, b); a = RealTier_getValueAtTime (atier, t); if (NUMdefined (a)) { r -> a *= DB_to_A (a); } } my z[1][is] = Filter_getOutput (r.peek(), my z[1][is]); } } catch (MelderError) { Melder_throw (me, U": not filtered with one formant filter."); } } autoSound Sound_FormantGrid_Intensities_filter (Sound me, FormantGrid thee, Ordered amplitudes, long iformantb, long iformante, int alternatingSign) { try { if (iformantb > iformante) { iformantb = 1; iformante = thy formants -> size; } if (iformantb < 1 || iformantb > thy formants -> size || iformante < 1 || iformante > thy formants -> size) { Melder_throw (U"No such formant number."); } autoSound him = Sound_create (my ny, my xmin, my xmax, my nx, my dx, my x1); for (long iformant = iformantb; iformant <= iformante; iformant++) { if (FormantGrid_Intensities_isFormantDefined (thee, amplitudes, iformant)) { autoSound tmp = Data_copy (me); Sound_FormantGrid_Intensities_filterWithOneFormant_inline (tmp.peek(), thee, amplitudes, iformant); for (long is = 1; is <= my nx; is++) { his z[1][is] += alternatingSign >= 0 ? tmp -> z[1][is] : - tmp -> z[1][is]; } if (alternatingSign != 0) { alternatingSign = -alternatingSign; } } } return him; } catch (MelderError) { Melder_throw (me, U": not filtered."); } } /********************** FricationGridPlayOptions **********************/ Thing_implement (FricationGridPlayOptions, Daata, 0); static void FricationGridPlayOptions_setDefaults (FricationGridPlayOptions me, FricationGrid thee) { my endFricationFormant = MIN (thy frication_formants -> formants -> size, thy frication_formants -> bandwidths -> size); my startFricationFormant = 2; my bypass = 1; } autoFricationGridPlayOptions FricationGridPlayOptions_create () { try { autoFricationGridPlayOptions me = Thing_new (FricationGridPlayOptions); return me; } catch (MelderError) { Melder_throw (U"FricationGridPlayOptions not created."); } } /************************ FricationGrid (& Sound) *********************************************/ void structFricationGrid :: v_info () { structDaata :: v_info (); const static char32 *in1 = U" ", *in2 = U" ", *in3 = U" "; MelderInfo_writeLine (in1, U"Time domain:"); MelderInfo_writeLine (in2, U"Start time: ", xmin, U" seconds"); MelderInfo_writeLine (in2, U"End time: ", xmax, U" seconds"); MelderInfo_writeLine (in2, U"Total duration: ", xmax - xmin, U" seconds"); MelderInfo_writeLine (in1, U"\nNumber of points in the FRICATION tiers:"); MelderInfo_writeLine (in2, U"fricationAmplitude: ", fricationAmplitude -> points -> size); MelderInfo_writeLine (in2, U"bypass: ", bypass -> points -> size); MelderInfo_writeLine (in1, U"\nNumber of points in the FRICATION FORMANT tiers:"); FormantGrid_info (our frication_formants.get(), frication_formants_amplitudes, in2, in3); } Thing_implement (FricationGrid, Function, 0); void FricationGrid_setNames (FricationGrid me) { Thing_setName (my fricationAmplitude.get(), U"fricationAmplitude"); Thing_setName (my frication_formants.get(), U"frication_formants"); Thing_setName (my bypass.get(), U"bypass"); Thing_setName (my frication_formants_amplitudes, U"frication_formants_amplitudes"); } autoFricationGrid FricationGrid_create (double tmin, double tmax, long numberOfFormants) { try { autoFricationGrid me = Thing_new (FricationGrid); Function_init (me.peek(), tmin, tmax); my fricationAmplitude = IntensityTier_create (tmin, tmax); my frication_formants = FormantGrid_createEmpty (tmin, tmax, numberOfFormants).transfer(); my bypass = IntensityTier_create (tmin, tmax); my frication_formants_amplitudes = formantsAmplitudes_create (tmin, tmax, numberOfFormants); my options = FricationGridPlayOptions_create (); FricationGrid_setNames (me.peek()); return me; } catch (MelderError) { Melder_throw (U"FricationGrid not created."); } } static void FricationGrid_draw_inside (FricationGrid me, Graphics g, double xmin, double xmax, double ymin, double ymax, double dy, double *yout) { long numberOfXSections = 5; long numberOfFormants = my frication_formants -> formants -> size; long numberOfParts = numberOfFormants + (numberOfFormants > 1 ? 0 : 1) ; // 2..number + bypass // dum noise, connections, filter, connections, adder double xw[6] = { 0, 2, 0.6, 1.5, 0.6, 0.5 }, xws[6]; double r, x1, y1, x2, y2, x3, xs, ys, ymid = (ymin + ymax) / 2; rel_to_abs (xw, xws, numberOfXSections, xmax - xmin); dy = dy < 0 ? 0 : dy; dy = (ymax - ymin) / (numberOfParts * (1 + dy) - dy); connections cp = connections_create (numberOfParts); if (cp == 0) { return; } // section 1 x1 = xmin; x2 = x1 + xw[1]; y1 = ymid - 0.5 * dy; y2 = y1 + dy; draw_oneSection (g, x1, x2, y1, y2, U"Frication", U"noise", nullptr); // section 2, horizontal line halfway, vertical line x1 = x2; x2 = x1 + xw[2] / 2; Graphics_line (g, x1, ymid, x2, ymid); Graphics_line (g, x2, ymax - dy / 2, x2, ymin + dy / 2); x3 = x2; // final connection to section 2 , filters , connections to adder x1 = xmin + xws[2]; x2 = x1 + xw[3]; y2 = ymax; autoMelderString fba; for (long i = 1; i <= numberOfParts; i++) { const char32 *fi = Melder_integer (i + 1); y1 = y2 - dy; if (i < numberOfParts) { MelderString_copy (&fba, U"A", fi, U" F", fi, U" B", fi); } else { MelderString_copy (&fba, U"Bypass"); } draw_oneSection (g, x1, x2, y1, y2, nullptr, fba.string, nullptr); double ymidi = (y1 + y2) / 2; Graphics_line (g, x3, ymidi, x1, ymidi); // from noise to filter cp -> x[i] = x2; cp -> y[i] = ymidi; y2 = y1 - 0.5 * dy; } r = xw[5] / 2; xs = xmax - r; ys = ymid; if (numberOfParts > 1) { alternatingSummer_drawConnections (g, xs, ys, r, cp, 1, 0.4); } else { Graphics_line (g, cp -> x[1], cp -> y[1], xs + r, ys); } connections_free (cp); if (yout) { *yout = ys; } } void FricationGrid_draw (FricationGrid me, Graphics g) { double xmin = 0, xmax = 1, xmax2 = 0.9, ymin = 0, ymax = 1, dy = 0.5, yout; Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); Graphics_setLineWidth (g, 2); FricationGrid_draw_inside (me, g, xmin, xmax2, ymin, ymax, dy, &yout); Graphics_arrow (g, xmax2, yout, xmax, yout); Graphics_unsetInner (g); } autoSound FricationGrid_to_Sound (FricationGrid me, double samplingFrequency) { try { autoSound thee = Sound_createEmptyMono (my xmin, my xmax, samplingFrequency); double lastval = 0; for (long i = 1; i <= thy nx; i++) { double t = thy x1 + (i - 1) * thy dx; double val = NUMrandomUniform (-1, 1); double a = 0; if (my fricationAmplitude -> points -> size > 0) { double dba = RealTier_getValueAtTime (my fricationAmplitude.get(), t); a = dba == NUMundefined ? 0 : DBSPL_to_A (dba); } lastval = (val += 0.75 * lastval); // TODO: soft low-pass coefficient must be Fs dependent! thy z[1][i] = val * a; } autoSound him = Sound_FricationGrid_filter (thee.peek(), me); return him; } catch (MelderError) { Melder_throw (me, U": no frication Sound created."); } } /************************ Sound & FricationGrid *********************************************/ autoSound Sound_FricationGrid_filter (Sound me, FricationGrid thee) { try { FricationGridPlayOptions pf = thy options.get(); autoSound him = 0; long numberOfFricationFormants = thy frication_formants -> formants -> size; check_formants (numberOfFricationFormants, & (pf -> startFricationFormant), & (pf -> endFricationFormant)); if (pf -> endFricationFormant > 1) { long startFricationFormant2 = pf -> startFricationFormant > 2 ? pf -> startFricationFormant : 2; int alternatingSign = startFricationFormant2 % 2 == 0 ? 1 : -1; // 2 starts with positive sign him = Sound_FormantGrid_Intensities_filter (me, thy frication_formants.get(), thy frication_formants_amplitudes, startFricationFormant2, pf -> endFricationFormant, alternatingSign); } if (! him) { him = Data_copy (me); } if (pf -> bypass) { for (long is = 1; is <= his nx; is++) { // Bypass double t = his x1 + (is - 1) * his dx; double ab = 0; if (thy bypass -> points -> size > 0) { double val = RealTier_getValueAtTime (thy bypass.get(), t); ab = val == NUMundefined ? 0 : DB_to_A (val); } his z[1][is] += my z[1][is] * ab; } } return him; } catch (MelderError) { Melder_throw (me, U": not filtered by frication filter."); } } /********************** KlattGridPlayOptions **********************/ Thing_implement (KlattGridPlayOptions, Daata, 0); static void KlattGridPlayOptions_setDefaults (KlattGridPlayOptions me, KlattGrid thee) { my samplingFrequency = 44100; my scalePeak = 1; my xmin = thy xmin; my xmax = thy xmax; } autoKlattGridPlayOptions KlattGridPlayOptions_create () { try { autoKlattGridPlayOptions me = Thing_new (KlattGridPlayOptions); return me; } catch (MelderError) { Melder_throw (U"KlattGridPlayOptions not created."); } } void KlattGrid_setDefaultPlayOptions (KlattGrid me) { KlattGridPlayOptions_setDefaults (my options.get(), me); PhonationGridPlayOptions_setDefaults (my phonation -> options.get()); VocalTractGridPlayOptions_setDefaults (my vocalTract -> options.get(), my vocalTract.get()); CouplingGridPlayOptions_setDefaults (my coupling -> options.get(), my coupling.get()); FricationGridPlayOptions_setDefaults (my frication -> options.get(), my frication.get()); } /************************ KlattGrid *********************************************/ Thing_implement (KlattGrid, Function, 0); void structKlattGrid :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Time domain:"); MelderInfo_writeLine (U" Start time: ", xmin, U" seconds"); MelderInfo_writeLine (U" End time: ", xmax, U" seconds"); MelderInfo_writeLine (U" Total duration: ", xmax - xmin, U" seconds"); MelderInfo_writeLine (U"\n--- PhonationGrid ---\n"); phonation -> v_info (); MelderInfo_writeLine (U"\n--- VocalTractGrid ---\n"); vocalTract -> v_info (); MelderInfo_writeLine (U"\n--- CouplingGrid ---\n"); coupling -> v_info (); MelderInfo_writeLine (U"\n--- FricationgGrid ---\n"); frication -> v_info (); } void KlattGrid_setNames (KlattGrid me) { Thing_setName (my phonation.get(), U"phonation"); Thing_setName (my vocalTract.get(), U"vocalTract"); Thing_setName (my coupling.get(), U"coupling"); Thing_setName (my frication.get(), U"frication"); Thing_setName (my gain.get(), U"gain"); } autoKlattGrid KlattGrid_create (double tmin, double tmax, long numberOfFormants, long numberOfNasalFormants, long numberOfNasalAntiFormants, long numberOfTrachealFormants, long numberOfTrachealAntiFormants, long numberOfFricationFormants, long numberOfDeltaFormants) { try { autoKlattGrid me = Thing_new (KlattGrid); Function_init (me.peek(), tmin, tmax); my phonation = PhonationGrid_create (tmin, tmax); my vocalTract = VocalTractGrid_create (tmin, tmax, numberOfFormants, numberOfNasalFormants, numberOfNasalAntiFormants); my coupling = CouplingGrid_create (tmin, tmax, numberOfTrachealFormants, numberOfTrachealAntiFormants, numberOfDeltaFormants); my frication = FricationGrid_create (tmin, tmax, numberOfFricationFormants); my gain = IntensityTier_create (tmin, tmax); my options = KlattGridPlayOptions_create (); KlattGrid_setDefaultPlayOptions (me.peek()); KlattGrid_setNames (me.peek()); return me; } catch (MelderError) { Melder_throw (U"KlattGrid not created."); } } autoKlattGrid KlattGrid_createExample () { try { autoKlattTable thee = KlattTable_createExample (); autoKlattGrid me = KlattTable_to_KlattGrid (thee.peek(), 0.005); return me; } catch (MelderError) { Melder_throw (U"KlattGrid example not created."); }; } // y is the heigth in units of the height of one section, // y1 is the heigth from the top to the split between the uppper, non-diffed, and lower diffed part static void _KlattGrid_queryParallelSplit (KlattGrid me, double dy, double *y, double *y1) { long ny = my vocalTract -> nasal_formants -> formants -> size + my vocalTract -> oral_formants -> formants -> size + my coupling -> tracheal_formants -> formants -> size; long n1 = my vocalTract -> nasal_formants -> formants -> size + (my vocalTract -> oral_formants -> formants -> size > 0 ? 1 : 0); long n2 = ny - n1; if (ny == 0) { *y = 0; *y1 = 0; return; } *y = ny + (ny - 1) * dy; if (n1 == 0) { *y1 = 0.5; } else if (n2 == 0) { *y1 = *y - 0.5; } else { *y1 = n1 + (n1 - 1) * dy + 0.5 * dy; } return; } static void getYpositions (double h1, double h2, double h3, double h4, double h5, double fractionOverlap, double *dy, double *ymin1, double *ymax1, double *ymin2, double *ymax2, double *ymin3, double *ymax3) { // Given: five 'blocks' with relative heights h1..h5 in arbitrary units. // Problem: scale all h1..h5 such that: // 1. blocks h1 and h2 form one unit, with h1 on top of h2, the quotient h1/h2 is fixed // 2. blocks h3 and h4 form one unit, with h3 on top of h4, the quotient h3/h4 is fixed // 3. blocks h1 and h3 have the same baseline. // 4. h5 is always underneath (h1,h2) but may partially overlap (0.45) with h4. // 5. After scaling the new h1+h2 >= 0.3 // 6. Optimally use the vertical space from 0.. 1, i.e the top of h1 or h3 is at 1, // the bottom of h5 is at 0. Preferably scale all blocks with the same factor, if not possible than // scale h3,h4 and h5 the same // // h1 h3 // h2 h4 // h5 /* Cases: x x ^ x x x x x x | h1 x x x x x x x x h3 | h13 ----------------------------------------------------------- h2 x x x x x x x x h4 x x x x x x x x x x x x x x h5 x x x x x x x x */ double h; // h12_min = 0.3; not yet double h13 = h1 > h3 ? h1 : h3; // baselines are now equal if (h2 >= h4) { h = h13 + h2 + h5; } else { // h2 < h4 double maximumOverlap3 = fractionOverlap * h5; if (maximumOverlap3 < (h1 + h2)) { maximumOverlap3 = 0; } else if (maximumOverlap3 > (h4 - h2)) { maximumOverlap3 = h4 - h2; } h = h13 + h4 + h5 - maximumOverlap3; } *dy = 1 / (1.1 * h); *ymin1 = 1 - (h13 + h2) * *dy; *ymax1 = *ymin1 + (h1 + h2) * *dy; *ymin2 = 1 - (h13 + h4) * *dy; *ymax2 = *ymin2 + (h3 + h4) * *dy; *ymin3 = 0; *ymax3 = h5 * *dy; } void KlattGrid_drawVocalTract (KlattGrid me, Graphics g, int filterModel, int withTrachea) { VocalTractGrid_CouplingGrid_draw (my vocalTract.get(), withTrachea ? my coupling.get() : nullptr, g, filterModel); } void KlattGrid_draw (KlattGrid me, Graphics g, int filterModel) { double xs1, xs2, ys1, ys2, xf1, xf2, yf1, yf2; double xp1, xp2, yp1, yp2, xc1, xc2, yc1, yc2; double dy, r, xs, ys; double xmin = 0, xmax2 = 0.90, xmax3 = 0.95, xmax = 1, ymin = 0, ymax = 1; double xws[6]; double height_phonation = 0.3; double dy_phonation = 0.5, dy_vocalTract_p = 0.5, dy_frication = 0.5; connections tf = connections_create (2); if (tf == 0) { return; } Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); Graphics_setLineWidth (g, 2); long nff = my frication -> frication_formants -> formants -> size - 1 + 1; double yh_frication = nff > 0 ? nff + (nff - 1) * dy_frication : 1; double yh_phonation = 1 + dy_phonation + 1; double yout_phonation, yout_frication; dy = height_phonation / yh_phonation; // 1 vertical unit in source section height units if (filterModel == KlattGrid_FILTER_CASCADE) { // Cascade section // source connection tract connection, out // frication double xw[6] = {0, 1.75, 0.125, 3, 0.25, 0.125 }; double yin_vocalTract_c, yout_vocalTract_c; rel_to_abs (xw, xws, 5, xmax2 - xmin); // limit height of frication unit dy ! height_phonation = yh_phonation / (yh_phonation + yh_frication); if (height_phonation < 0.3) { height_phonation = 0.3; } dy = height_phonation / yh_phonation; xs1 = xmin; xs2 = xs1 + xw[1]; ys2 = ymax; ys1 = ys2 - height_phonation; PhonationGrid_draw_inside (my phonation.get(), g, xs1, xs2, ys1, ys2, dy_phonation, &yout_phonation); // units in cascade have same heigth as units in source part. xc1 = xmin + xws[2]; xc2 = xc1 + xw[3]; yc2 = yout_phonation + dy / 2; yc1 = yc2 - dy; VocalTractGrid_CouplingGrid_drawCascade_inline (my vocalTract.get(), my coupling.get(), g, xc1, xc2, yc1, yc2, &yin_vocalTract_c, &yout_vocalTract_c); tf -> x[1] = xc2; tf -> y[1] = yout_vocalTract_c; Graphics_line (g, xs2, yout_phonation, xc1, yin_vocalTract_c); xf1 = xmin + xws[2]; xf2 = xf1 + xw[3]; yf2 = ymax - height_phonation; yf1 = 0; FricationGrid_draw_inside (my frication.get(), g, xf1, xf2, yf1, yf2, dy_frication, &yout_frication); } else { // Parallel // source connection tract connection, out // frication double yf_parallel, yh_parallel, yh_overlap = 0.3, yin_vocalTract_p, yout_vocalTract_p; double xw[6] = { 0, 1.75, 0.125, 3, 0.25, 0.125 }; rel_to_abs (xw, xws, 5, xmax2 - xmin); // optimize the vertical space for source, parallel and frication // source part is relatively fixed. let the number of vertical section units be the divisor // connector line from source to parallel has to be horizontal // determine y's of source and parallel section _KlattGrid_queryParallelSplit (me, dy_vocalTract_p, &yh_parallel, &yf_parallel); if (yh_parallel == 0) { yh_parallel = yh_phonation; yf_parallel = yh_parallel / 2; yh_overlap = -0.1; } height_phonation = yh_phonation / (yh_phonation + yh_frication); if (height_phonation < 0.3) { height_phonation = 0.3; } //double yunit = (ymax - ymin) / (yh_parallel + (1 - yh_overlap) * yh_frication); // some overlap //double ycs = ymax - 0.5 * height_phonation; // source output connector //double ycp = ymax - yf_parallel * yunit; // parallel input connector //double ytrans_phonation = ycs > ycp ? ycp - ycs : 0; //double ytrans_parallel = ycp > ycs ? ycs - ycp : 0; // source, tract, frication xs1 = xmin; xs2 = xs1 + xw[1]; double h1 = yh_phonation / 2, h2 = h1, h3 = yf_parallel, h4 = yh_parallel - h3, h5 = yh_frication; getYpositions (h1, h2, h3, h4, h5, yh_overlap, &dy, &ys1, &ys2, &yp1, &yp2, &yf1, &yf2); PhonationGrid_draw_inside (my phonation.get(), g, xs1, xs2, ys1, ys2, dy_phonation, &yout_phonation); xp1 = xmin + xws[2]; xp2 = xp1 + xw[3]; VocalTractGrid_CouplingGrid_drawParallel_inline (my vocalTract.get(), my coupling.get(), g, xp1, xp2, yp1, yp2, dy_vocalTract_p, &yin_vocalTract_p, &yout_vocalTract_p); tf -> x[1] = xp2; tf -> y[1] = yout_vocalTract_p; Graphics_line (g, xs2, yout_phonation, xp1, yin_vocalTract_p); xf1 = xmin /*+ 0.5 * xws[1]*/; xf2 = xf1 + 0.55 * (xw[2] + xws[3]); FricationGrid_draw_inside (my frication.get(), g, xf1, xf2, yf1, yf2, dy_frication, &yout_frication); } tf -> x[2] = xf2; tf -> y[2] = yout_frication; r = (xmax3 - xmax2) / 2; xs = xmax2 + r / 2; ys = (ymax - ymin) / 2; summer_drawConnections (g, xs, ys, r, tf, 1, 0.6); Graphics_arrow (g, xs + r, ys, xmax, ys); Graphics_unsetInner (g); connections_free (tf); } /**** Query, Add, Remove, Extract Replace ********/ #define PhonationGrid_QUERY_ADD_REMOVE_EXTRACT_REPLACE(Name,name,tierType) \ double KlattGrid_get##Name##AtTime (KlattGrid me, double t) \ { return RealTier_getValueAtTime ((RealTier) my phonation -> name.get(), t); } \ void KlattGrid_add##Name##Point (KlattGrid me, double t, double value) \ { RealTier_addPoint ((RealTier) my phonation -> name.get(), t, value);} \ void KlattGrid_remove##Name##Points (KlattGrid me, double t1, double t2) \ { AnyTier_removePointsBetween ((RealTier) my phonation -> name.get(), t1, t2); } \ auto##tierType KlattGrid_extract##Name##Tier (KlattGrid me) \ { return Data_copy ((tierType) my phonation -> name.get()); } \ void KlattGrid_replace##Name##Tier (KlattGrid me, tierType thee) \ { try {\ if (my xmin != thy xmin || my xmax != thy xmax) Melder_throw (U"Domains must be equal"); \ auto##tierType any = Data_copy ((tierType) thee); \ my phonation -> name = any.move(); \ } catch (MelderError) { Melder_throw (me, U": tier not replaced."); } \ } // Generate 55 functions PhonationGrid_QUERY_ADD_REMOVE_EXTRACT_REPLACE (Pitch, pitch, PitchTier) PhonationGrid_QUERY_ADD_REMOVE_EXTRACT_REPLACE (VoicingAmplitude, voicingAmplitude, IntensityTier) PhonationGrid_QUERY_ADD_REMOVE_EXTRACT_REPLACE (Flutter, flutter, RealTier) PhonationGrid_QUERY_ADD_REMOVE_EXTRACT_REPLACE (Power1, power1, RealTier) PhonationGrid_QUERY_ADD_REMOVE_EXTRACT_REPLACE (Power2, power2, RealTier) PhonationGrid_QUERY_ADD_REMOVE_EXTRACT_REPLACE (OpenPhase, openPhase, RealTier) PhonationGrid_QUERY_ADD_REMOVE_EXTRACT_REPLACE (CollisionPhase, collisionPhase, RealTier) PhonationGrid_QUERY_ADD_REMOVE_EXTRACT_REPLACE (DoublePulsing, doublePulsing, RealTier) PhonationGrid_QUERY_ADD_REMOVE_EXTRACT_REPLACE (SpectralTilt, spectralTilt, IntensityTier) PhonationGrid_QUERY_ADD_REMOVE_EXTRACT_REPLACE (AspirationAmplitude, aspirationAmplitude, IntensityTier) PhonationGrid_QUERY_ADD_REMOVE_EXTRACT_REPLACE (BreathinessAmplitude, breathinessAmplitude, IntensityTier) autoFormantGrid* KlattGrid_getAddressOfFormantGrid (KlattGrid me, int formantType) { return formantType == KlattGrid_ORAL_FORMANTS ? & (my vocalTract -> oral_formants) : formantType == KlattGrid_NASAL_FORMANTS ? & (my vocalTract -> nasal_formants) : formantType == KlattGrid_FRICATION_FORMANTS ? & (my frication -> frication_formants) : formantType == KlattGrid_TRACHEAL_FORMANTS ? & (my coupling -> tracheal_formants) : formantType == KlattGrid_NASAL_ANTIFORMANTS ? & (my vocalTract -> nasal_antiformants) : formantType == KlattGrid_TRACHEAL_ANTIFORMANTS ? & (my coupling -> tracheal_antiformants) : formantType == KlattGrid_DELTA_FORMANTS ? & (my coupling -> delta_formants) : nullptr; } Ordered *KlattGrid_getAddressOfAmplitudes (KlattGrid me, int formantType) { return formantType == KlattGrid_ORAL_FORMANTS ? & (my vocalTract -> oral_formants_amplitudes) : formantType == KlattGrid_NASAL_FORMANTS ? & (my vocalTract -> nasal_formants_amplitudes) : formantType == KlattGrid_FRICATION_FORMANTS ? & (my frication -> frication_formants_amplitudes) : formantType == KlattGrid_TRACHEAL_FORMANTS ? & (my coupling -> tracheal_formants_amplitudes) : nullptr; } #define KlattGrid_QUERY_ADD_REMOVE(Name) \ double KlattGrid_get##Name##AtTime (KlattGrid me, int formantType, long iformant, double t) \ { \ autoFormantGrid* fg = KlattGrid_getAddressOfFormantGrid (me, formantType); \ return FormantGrid_get##Name##AtTime (fg->get(), iformant, t); \ } \ void KlattGrid_add##Name##Point (KlattGrid me, int formantType, long iformant, double t, double value) \ { \ autoFormantGrid* fg = KlattGrid_getAddressOfFormantGrid (me, formantType); \ FormantGrid_add##Name##Point (fg->get(), iformant, t, value); \ } \ void KlattGrid_remove##Name##Points (KlattGrid me, int formantType, long iformant, double t1, double t2) \ { \ autoFormantGrid* fg = KlattGrid_getAddressOfFormantGrid (me, formantType); \ FormantGrid_remove##Name##PointsBetween (fg->get(), iformant, t1, t2); \ } // 6 functions KlattGrid_QUERY_ADD_REMOVE (Formant) KlattGrid_QUERY_ADD_REMOVE (Bandwidth) void KlattGrid_formula_frequencies (KlattGrid me, int formantType, const char32 *expression, Interpreter interpreter) { autoFormantGrid* fg = KlattGrid_getAddressOfFormantGrid (me, formantType); FormantGrid_formula_frequencies (fg->get(), expression, interpreter, 0); } void KlattGrid_formula_bandwidths (KlattGrid me, int formantType, const char32 *expression, Interpreter interpreter) { autoFormantGrid* fg = KlattGrid_getAddressOfFormantGrid (me, formantType); FormantGrid_formula_bandwidths (fg->get(), expression, interpreter, 0); } void KlattGrid_formula_amplitudes (KlattGrid me, int formantType, const char32 *expression, Interpreter interpreter) { try { Ordered *ordered = KlattGrid_getAddressOfAmplitudes (me, formantType); Formula_compile (interpreter, *ordered, expression, kFormula_EXPRESSION_TYPE_NUMERIC, true); for (long irow = 1; irow <= (*ordered) -> size; irow++) { RealTier amplitudes = (RealTier) (*ordered) -> item[irow]; for (long icol = 1; icol <= amplitudes -> points -> size; icol++) { struct Formula_Result result; Formula_run (irow, icol, & result); if (result. result.numericResult == NUMundefined) { Melder_throw (U"Cannot put an undefined value into the tier.\nFormula not finished."); } ( (RealPoint) amplitudes -> points -> item [icol]) -> value = result. result.numericResult; } } } catch (MelderError) { Melder_throw (me, U": formula not finished on amplitudes."); } } double KlattGrid_getAmplitudeAtTime (KlattGrid me, int formantType, long iformant, double t) { Ordered *ordered = KlattGrid_getAddressOfAmplitudes (me, formantType); if (iformant < 0 || iformant > (*ordered) -> size) { return NUMundefined; } return RealTier_getValueAtTime ( (RealTier) (*ordered) -> item[iformant], t); } void KlattGrid_addAmplitudePoint (KlattGrid me, int formantType, long iformant, double t, double value) { Ordered *ordered = KlattGrid_getAddressOfAmplitudes (me, formantType); if (iformant < 0 || iformant > (*ordered) -> size) { Melder_throw (U"Formant amplitude tier ", iformant, U"does not exist."); } RealTier_addPoint ( (RealTier) (*ordered) -> item[iformant], t, value); } void KlattGrid_removeAmplitudePoints (KlattGrid me, int formantType, long iformant, double t1, double t2) { Ordered *ordered = KlattGrid_getAddressOfAmplitudes (me, formantType); if (iformant < 0 || iformant > (*ordered) ->size) { return; } AnyTier_removePointsBetween ( (*ordered) -> item[iformant], t1, t2); } autoIntensityTier KlattGrid_extractAmplitudeTier (KlattGrid me, int formantType, long iformant) { try { Ordered *ordered = KlattGrid_getAddressOfAmplitudes (me, formantType); if (iformant < 0 || iformant > (*ordered) ->size) { Melder_throw (U"Formant amplitude tier ", iformant, U" does not exist."); } autoIntensityTier thee = Data_copy ( (IntensityTier) (*ordered) -> item[iformant]); return thee; } catch (MelderError) { Melder_throw (me, U": no IntensityTier extracted."); } } void KlattGrid_replaceAmplitudeTier (KlattGrid me, int formantType, long iformant, IntensityTier thee) { try { if (my xmin != thy xmin || my xmax != thy xmax) { Melder_throw (U"Domains must be equal"); } Ordered *ordered = KlattGrid_getAddressOfAmplitudes (me, formantType); if (iformant < 0 || iformant > (*ordered) -> size) { Melder_throw (U"Formant amplitude tier ", iformant, U" does not exist."); } autoIntensityTier any = Data_copy (thee); forget ( ( (Thing *) (*ordered) -> item) [iformant]); (*ordered) -> item[iformant] = any.transfer(); } catch (MelderError) { Melder_throw (me, U": no ampitude tier replaced."); } } autoFormantGrid KlattGrid_extractFormantGrid (KlattGrid me, int formantType) { try { autoFormantGrid* fg = KlattGrid_getAddressOfFormantGrid (me, formantType); autoFormantGrid thee = Data_copy (fg->get()); return thee; } catch (MelderError) { Melder_throw (me, U": no FormantGrid extracted."); } } void KlattGrid_replaceFormantGrid (KlattGrid me, int formantType, FormantGrid thee) { try { if (my xmin != thy xmin || my xmax != thy xmax) { Melder_throw (U"Domains must be equal"); } autoFormantGrid *fg = KlattGrid_getAddressOfFormantGrid (me, formantType); *fg = Data_copy (thee); } catch (MelderError) { Melder_throw (me, U": no FormantGrid replaced."); } } void KlattGrid_addFormantAmplitudeTier (KlattGrid me, int formantType, long position) { try { if (formantType == KlattGrid_NASAL_ANTIFORMANTS || formantType == KlattGrid_TRACHEAL_ANTIFORMANTS || formantType == KlattGrid_DELTA_FORMANTS) { Melder_throw (U"Cannot add amplitude tier to this formant type."); } Ordered *ordered = KlattGrid_getAddressOfAmplitudes (me, formantType); long noa = (*ordered) -> size; if (position > noa || position < 1) { position = noa + 1; } autoIntensityTier it = IntensityTier_create (my xmin, my xmax); Ordered_addItemPos ( (*ordered), it.transfer(), position); } catch (MelderError) { Melder_throw (me, U": no formant amplitude tier added."); } } void KlattGrid_removeFormantAmplitudeTier (KlattGrid me, int formantType, long position) { try { if (formantType == KlattGrid_NASAL_ANTIFORMANTS || formantType == KlattGrid_TRACHEAL_ANTIFORMANTS || formantType == KlattGrid_DELTA_FORMANTS) { Melder_throw (U"Cannot remove amplitude tier from this formant type."); } Ordered *ordered = KlattGrid_getAddressOfAmplitudes (me, formantType); if (position > 0 && position <= (*ordered) -> size) { Collection_removeItem (*ordered, position); } } catch (MelderError) { Melder_throw (me, U": no formant amplitude tier removed."); } } // The following two routines are deprecated. // We do this intwo separate steps now void KlattGrid_addFormant (KlattGrid me, int formantType, long position) { try { autoFormantGrid* fg = KlattGrid_getAddressOfFormantGrid (me, formantType); if (! *fg) { Melder_throw (U"Formant type ", formantType, U" does not exist."); } long nof = (*fg) -> formants -> size; if (position > nof || position < 1) { position = nof + 1; } if (formantType == KlattGrid_NASAL_ANTIFORMANTS || formantType == KlattGrid_TRACHEAL_ANTIFORMANTS || formantType == KlattGrid_DELTA_FORMANTS) { FormantGrid_addFormantAndBandwidthTiers (fg->get(), position); return; } Ordered *ordered = KlattGrid_getAddressOfAmplitudes (me, formantType); long noa = (*ordered) -> size; if (nof != noa) { Melder_throw (U"The number of formants (", nof, U") and the number of amplitudes (", noa, U") must be equal."); } FormantGrid_addFormantAndBandwidthTiers (fg->get(), position); try { autoIntensityTier it = IntensityTier_create (my xmin, my xmax); Ordered_addItemPos ( (*ordered), it.transfer(), position); } catch (MelderError) { // restore original FormantGrid_removeFormantAndBandwidthTiers (fg->get(), position); } } catch (MelderError) { Melder_throw (me, U": no formant added."); } } void KlattGrid_removeFormant (KlattGrid me, int formantType, long position) { autoFormantGrid* fg = KlattGrid_getAddressOfFormantGrid (me, formantType); long nof = (*fg) -> formants -> size; if (formantType == KlattGrid_NASAL_ANTIFORMANTS || formantType == KlattGrid_TRACHEAL_ANTIFORMANTS || formantType == KlattGrid_DELTA_FORMANTS) { if (position < 1 || position > nof) { return; } FormantGrid_removeFormantAndBandwidthTiers (fg->get(), position); } else { // oral & nasal & tracheal formants can have amplitudes // only remove a formant and its amplitude tier if number of formants and amplitudes are the same Ordered *ordered = KlattGrid_getAddressOfAmplitudes (me, formantType); long noa = (*ordered) -> size; if (position < 1 || position > nof || position > noa) { if (nof != noa) { Melder_warning (U"The number of formant tiers (", nof, U") and the number of amplitude tiers (", noa, U") don't match. Nothing removed."); } return; } FormantGrid_removeFormantAndBandwidthTiers (fg->get(), position); Collection_removeItem (*ordered, position); } } void KlattGrid_addFormantFrequencyAndBandwidthTiers (KlattGrid me, int formantType, long position) { autoFormantGrid* fg = KlattGrid_getAddressOfFormantGrid (me, formantType); FormantGrid_addFormantAndBandwidthTiers (fg->get(), position); } void KlattGrid_removeFormantFrequencyAndBandwidthTiers (KlattGrid me, int formantType, long position) { autoFormantGrid* fg = KlattGrid_getAddressOfFormantGrid (me, formantType); FormantGrid_removeFormantAndBandwidthTiers (fg->get(), position); } double KlattGrid_getDeltaFormantAtTime (KlattGrid me, long iformant, double t) { return FormantGrid_getFormantAtTime (my coupling -> delta_formants.get(), iformant, t); } void KlattGrid_addDeltaFormantPoint (KlattGrid me, long iformant, double t, double value) { FormantGrid_addFormantPoint (my coupling -> delta_formants.get(), iformant, t, value); } void KlattGrid_removeDeltaFormantPoints (KlattGrid me, long iformant, double t1, double t2) { FormantGrid_removeFormantPointsBetween (my coupling -> delta_formants.get(), iformant, t1, t2); } double KlattGrid_getDeltaBandwidthAtTime (KlattGrid me, long iformant, double t) { return FormantGrid_getBandwidthAtTime (my coupling -> delta_formants.get(), iformant, t); } void KlattGrid_addDeltaBandwidthPoint (KlattGrid me, long iformant, double t, double value) { FormantGrid_addBandwidthPoint (my coupling -> delta_formants.get(), iformant, t, value); } void KlattGrid_removeDeltaBandwidthPoints (KlattGrid me, long iformant, double t1, double t2) { FormantGrid_removeBandwidthPointsBetween (my coupling -> delta_formants.get(), iformant, t1, t2); } autoFormantGrid KlattGrid_extractDeltaFormantGrid (KlattGrid me) { try { autoFormantGrid* fg = KlattGrid_getAddressOfFormantGrid (me, KlattGrid_DELTA_FORMANTS); autoFormantGrid thee = Data_copy (fg->get()); return thee; } catch (MelderError) { Melder_throw (me, U": no delta FormantGrid extracted."); } } void KlattGrid_replaceDeltaFormantGrid (KlattGrid me, FormantGrid thee) { try { if (my xmin != thy xmin || my xmax != thy xmax) { Melder_throw (U"Domains must be equal"); } autoFormantGrid* fg = KlattGrid_getAddressOfFormantGrid (me, KlattGrid_DELTA_FORMANTS); autoFormantGrid him = Data_copy (thee); *fg = him.move(); } catch (MelderError) { Melder_throw (me, U": no delta FormantGrid replaced."); } } autoFormantGrid KlattGrid_to_oralFormantGrid_openPhases (KlattGrid me, double fadeFraction) { try { if (my vocalTract -> oral_formants -> formants -> size == 0 && my vocalTract -> oral_formants -> bandwidths -> size == 0) { Melder_throw (U"Formant grid is empty."); } if (fadeFraction < 0) { fadeFraction = 0; } if (fadeFraction >= 0.5) { Melder_throw (U"Fade fraction must be smaller than 0.5"); } my coupling -> options -> fadeFraction = fadeFraction; autoFormantGrid thee = Data_copy ( (FormantGrid) my vocalTract -> oral_formants.get()); KlattGrid_setGlottisCoupling (me); FormantGrid_CouplingGrid_updateOpenPhases (thee.peek(), my coupling.get()); return thee; } catch (MelderError) { Melder_throw (me, U": no \"open phase\" oral FormantGrid created."); } } autoPointProcess KlattGrid_extractPointProcess_glottalClosures (KlattGrid me) { try { // Update PhonationTier autoPhonationTier pt = PhonationGrid_to_PhonationTier (my phonation.get()); autoPointProcess thee = PhonationTier_to_PointProcess_closures (pt.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": no glottal closure points extracted."); } } double KlattGrid_getFricationAmplitudeAtTime (KlattGrid me, double t) { return RealTier_getValueAtTime (my frication -> fricationAmplitude.get(), t); } void KlattGrid_addFricationAmplitudePoint (KlattGrid me, double t, double value) { RealTier_addPoint (my frication -> fricationAmplitude.get(), t, value); } void KlattGrid_removeFricationAmplitudePoints (KlattGrid me, double t1, double t2) { AnyTier_removePointsBetween (my frication -> fricationAmplitude.get(), t1, t2); } autoIntensityTier KlattGrid_extractFricationAmplitudeTier (KlattGrid me) { return Data_copy (my frication -> fricationAmplitude.get()); } void KlattGrid_replaceFricationAmplitudeTier (KlattGrid me, IntensityTier thee) { try { if (my xmin != thy xmin || my xmax != thy xmax) { Melder_throw (U"Domains must be equal"); } my frication -> fricationAmplitude = Data_copy (thee); } catch (MelderError) { Melder_throw (me, U": no frication amplitude tier replaced."); } } double KlattGrid_getFricationBypassAtTime (KlattGrid me, double t) { return RealTier_getValueAtTime (my frication -> bypass.get(), t); } void KlattGrid_addFricationBypassPoint (KlattGrid me, double t, double value) { RealTier_addPoint (my frication -> bypass.get(), t, value); } void KlattGrid_removeFricationBypassPoints (KlattGrid me, double t1, double t2) { AnyTier_removePointsBetween (my frication -> bypass.get(), t1, t2); } autoIntensityTier KlattGrid_extractFricationBypassTier (KlattGrid me) { return Data_copy (my frication -> bypass.get()); } void KlattGrid_replaceFricationBypassTier (KlattGrid me, IntensityTier thee) { try { if (my xmin != thy xmin || my xmax != thy xmax) { Melder_throw (U"Domains must be equal"); } my frication -> bypass = Data_copy (thee); } catch (MelderError) { Melder_throw (me, U": no frication bypass tier replaced."); } } void KlattGrid_setGlottisCoupling (KlattGrid me) { try { my coupling -> glottis = PhonationGrid_to_PhonationTier (my phonation.get()); if (my coupling -> glottis == 0) { Melder_throw (U"Empty phonation tier."); } } catch (MelderError) { Melder_throw (me, U": no coupling could be set."); } } autoSound KlattGrid_to_Sound_aspiration (KlattGrid me, double samplingFrequency) { return PhonationGrid_to_Sound_aspiration (my phonation.get(), samplingFrequency); } autoSound KlattGrid_to_Sound_phonation (KlattGrid me) { return PhonationGrid_to_Sound (my phonation.get(), 0, my options -> samplingFrequency); } autoSound KlattGrid_to_Sound (KlattGrid me) { try { autoSound thee; PhonationGridPlayOptions pp = my phonation -> options.get(); FricationGridPlayOptions pf = my frication -> options.get(); double samplingFrequency = my options -> samplingFrequency; if (pp -> voicing) { KlattGrid_setGlottisCoupling (me); } if (pp -> aspiration || pp -> voicing) { // No vocal tract filtering if no glottal source signal present autoSound source = PhonationGrid_to_Sound (my phonation.get(), my coupling.get(), samplingFrequency); thee = Sound_VocalTractGrid_CouplingGrid_filter (source.peek(), my vocalTract.get(), my coupling.get()); } if (pf -> endFricationFormant > 0 || pf -> bypass) { autoSound frication = FricationGrid_to_Sound (my frication.get(), samplingFrequency); if (thee) { _Sounds_add_inline (thee.peek(), frication.peek()); } else { thee = frication.move(); } } if (thee) { Vector_scale (thee.peek(), 0.99); } else if (my options -> scalePeak) { thee = Sound_createEmptyMono (my xmin, my xmax, samplingFrequency); } return thee; } catch (MelderError) { Melder_throw (me, U": no Sound created."); } } void KlattGrid_playSpecial (KlattGrid me) { try { autoSound thee = KlattGrid_to_Sound (me); KlattGridPlayOptions him = my options.get(); if (his scalePeak) { Vector_scale (thee.peek(), 0.99); } if (his xmin == 0 && his xmax == 0) { his xmin = my xmin; his xmax = my xmax; } Sound_playPart (thee.peek(), his xmin, his xmax, 0, 0); } catch (MelderError) { Melder_throw (me, U": not played."); } } void KlattGrid_play (KlattGrid me) { KlattGrid_setDefaultPlayOptions (me); KlattGrid_playSpecial (me); } /************************* Sound(s) & KlattGrid **************************************************/ autoSound Sound_KlattGrid_filter_frication (Sound me, KlattGrid thee) { return Sound_FricationGrid_filter (me, thy frication.get()); } autoSound Sound_KlattGrid_filterByVocalTract (Sound me, KlattGrid thee, int filterModel) { try { if (my xmin != thy xmin || my xmax != thy xmax) { Melder_throw (U"Domains must be equal."); } KlattGrid_setDefaultPlayOptions (thee); thy coupling -> options -> openglottis = 0; // don't trust openglottis info! thy vocalTract -> options -> filterModel = filterModel; return Sound_VocalTractGrid_CouplingGrid_filter (me, thy vocalTract.get(), thy coupling.get()); } catch (MelderError) { Melder_throw (me, U": not filtered by KlattGrid."); } } /******************* KlattTable to KlattGrid *********************/ autoKlattGrid KlattTable_to_KlattGrid (KlattTable me, double frameDuration) { try { Table kt = (Table) me; long nrows = my rows -> size; double tmin = 0, tmax = nrows * frameDuration; double dBNul = -300; double dB_offset = -20 * log10 (2.0e-5) - 87; // in KlattTable maximum in DB_to_LIN is at 87 dB : 32767 double dB_offset_voicing = 20 * log10 (320000 / 32767); // V'[n] in range (-320000,32000) double dB_offset_noise = -20 * log10 (32.767 / 8.192); // noise in range (-8192,8192) // double dB_offset_noise = -20 * log10 (320000/32767) - 20 * log10 (32.767 / 8.192); double ap[7] = {0, 0.4, 0.15, 0.06, 0.04, 0.022, 0.03 }; long numberOfFormants = 6; long numberOfNasalFormants = 1; long numberOfNasalAntiFormants = numberOfNasalFormants; long numberOfTrachealFormants = 0; long numberOfTrachealAntiFormants = numberOfTrachealFormants; long numberOfFricationFormants = 6; long numberOfDeltaFormants = 1; autoKlattGrid thee = KlattGrid_create (tmin, tmax, numberOfFormants, numberOfNasalFormants, numberOfNasalAntiFormants, numberOfTrachealFormants, numberOfTrachealAntiFormants, numberOfFricationFormants, numberOfDeltaFormants); for (long irow = 1; irow <= nrows; irow++) { double t = (irow - 1) * frameDuration; long icol = 1; double val = Table_getNumericValue_Assert (kt, irow, icol) / 10; // F0hz10 double f0 = val; RealTier_addPoint (thy phonation -> pitch.get(), t, f0); icol++; val = Table_getNumericValue_Assert (kt, irow, icol); // AVdb // dB values below 13 were put to zero in the DBtoLIN function val -= 7; if (val < 13) { val = dBNul; } // RealTier_addPoint (thy source -> voicingAmplitude, t, val); for (long kf = 1; kf <= 6; kf++) { icol++; double fk = val = Table_getNumericValue_Assert (kt, irow, icol); // Fhz RealTier_addPoint ( (RealTier) thy vocalTract -> oral_formants -> formants -> item[kf], t, val); RealTier_addPoint ( (RealTier) thy frication -> frication_formants -> formants -> item[kf], t, val); // only amplitudes and bandwidths in frication section icol++; val = Table_getNumericValue_Assert (kt, irow, icol); // Bhz if (val <= 0) { val = fk / 10; } RealTier_addPoint ( (RealTier) thy vocalTract -> oral_formants -> bandwidths -> item[kf], t, val); } icol++; val = Table_getNumericValue_Assert (kt, irow, icol); // FNZhz RealTier_addPoint ( (RealTier) thy vocalTract -> nasal_antiformants -> formants -> item[1], t, val); icol++; val = Table_getNumericValue_Assert (kt, irow, icol); // BNZhz RealTier_addPoint ( (RealTier) thy vocalTract -> nasal_antiformants -> bandwidths -> item[1], t, val); icol++; val = Table_getNumericValue_Assert (kt, irow, icol); // FNPhz RealTier_addPoint ( (RealTier) thy vocalTract -> nasal_formants -> formants -> item[1], t, val); icol++; val = Table_getNumericValue_Assert (kt, irow, icol); // BNPhz RealTier_addPoint ( (RealTier) thy vocalTract -> nasal_formants -> bandwidths -> item[1], t, val); icol++; val = Table_getNumericValue_Assert (kt, irow, icol); // ah if (val < 13) { val = dBNul; } else { val += 20 * log10 (0.05) + dB_offset_noise; } RealTier_addPoint (thy phonation -> aspirationAmplitude.get(), t, val); icol++; val = Table_getNumericValue_Assert (kt, irow, icol); // Kopen double openPhase = f0 > 0 ? (val / 16000) * f0 : 0.7; RealTier_addPoint (thy phonation -> openPhase.get(), t, openPhase); icol++; val = Table_getNumericValue_Assert (kt, irow, icol); // Aturb breathinessAmplitude during voicing (max is 8192) if (val < 13) { val = dBNul; } else { val += 20 * log10 (0.1) + dB_offset_noise; } RealTier_addPoint (thy phonation -> breathinessAmplitude.get(), t, val); icol++; val = Table_getNumericValue_Assert (kt, irow, icol); // TLTdb RealTier_addPoint (thy phonation -> spectralTilt.get(), t, val); icol++; val = Table_getNumericValue_Assert (kt, irow, icol); // AF if (val < 13) { val = dBNul; } else { val += 20 * log10 (0.25) + dB_offset_noise; } RealTier_addPoint (thy frication -> fricationAmplitude.get(), t, val); icol++; val = Table_getNumericValue_Assert (kt, irow, icol); // Kskew ??? //RealTier_addPoint (, t, val); for (long kf = 1; kf <= 6; kf++) { icol++; val = Table_getNumericValue_Assert (kt, irow, icol); // Ap if (val < 13) { val = dBNul; } else { val += 20 * log10 (ap[kf]) + dB_offset; } RealTier_addPoint ( (RealTier) thy vocalTract -> oral_formants_amplitudes -> item[kf], t, val); RealTier_addPoint ( (RealTier) thy frication -> frication_formants_amplitudes -> item[kf], t, val); icol++; val = Table_getNumericValue_Assert (kt, irow, icol); // Bhz RealTier_addPoint ( (RealTier) thy frication -> frication_formants -> bandwidths -> item[kf], t, val); } icol++; val = Table_getNumericValue_Assert (kt, irow, icol); // ANP if (val < 13) { val = dBNul; } else { val += 20 * log10 (0.6) + dB_offset; } RealTier_addPoint ( (RealTier) thy vocalTract -> nasal_formants_amplitudes -> item[1], t, val); icol++; val = Table_getNumericValue_Assert (kt, irow, icol); // AB if (val < 13) { val = dBNul; } else { val += 20 * log10 (0.05) + dB_offset_noise; } RealTier_addPoint (thy frication -> bypass.get(), t, val); icol++; val = Table_getNumericValue_Assert (kt, irow, icol); // AVpdb RealTier_addPoint (thy phonation -> voicingAmplitude.get(), t, val + dB_offset_voicing); icol++; val = Table_getNumericValue_Assert (kt, irow, icol); // Gain0 val -= 3; if (val <= 0) { val = 57; } RealTier_addPoint (thy gain.get(), t, val + dB_offset); } // We don't need the following low-pass: we do not use oversampling !! //RealTier_addPoint (thy tracheal_formants -> formants -> item[1], 0.5*(tmin+tmax), 0.095*samplingFrequency); //RealTier_addPoint (thy tracheal_formants -> bandwidths -> item[1], 0.5*(tmin+tmax), 0.063*samplingFrequency); return thee; } catch (MelderError) { Melder_throw (me, U": no KlattGrid created."); } } autoKlattGrid Sound_to_KlattGrid_simple (Sound me, double timeStep, long maximumNumberOfFormants, double maximumFormantFrequency, double windowLength, double preEmphasisFrequency, double minimumPitch, double maximumPitch, double pitchFloorIntensity, int subtractMean) { try { long numberOfFormants = maximumNumberOfFormants; long numberOfNasalFormants = 1; long numberOfNasalAntiFormants = numberOfNasalFormants; long numberOfTrachealFormants = 1; long numberOfTrachealAntiFormants = numberOfTrachealFormants; long numberOfFricationFormants = maximumNumberOfFormants; long numberOfDeltaFormants = 1; autoSound sound = Data_copy (me); Vector_subtractMean (sound.peek()); autoFormant f = Sound_to_Formant_burg (sound.peek(), timeStep, maximumNumberOfFormants, maximumFormantFrequency, windowLength, preEmphasisFrequency); autoFormantGrid fgrid = Formant_downto_FormantGrid (f.peek()); autoPitch p = Sound_to_Pitch (sound.peek(), timeStep, minimumPitch, maximumPitch); autoPitchTier ptier = Pitch_to_PitchTier (p.peek()); autoIntensity i = Sound_to_Intensity (sound.peek(), pitchFloorIntensity, timeStep, subtractMean); autoIntensityTier itier = Intensity_downto_IntensityTier (i.peek()); autoKlattGrid thee = KlattGrid_create (my xmin, my xmax, numberOfFormants, numberOfNasalFormants, numberOfNasalAntiFormants, numberOfTrachealFormants, numberOfTrachealAntiFormants, numberOfFricationFormants, numberOfDeltaFormants); KlattGrid_replacePitchTier (thee.peek(), ptier.peek()); KlattGrid_replaceFormantGrid (thee.peek(), KlattGrid_ORAL_FORMANTS, fgrid.peek()); KlattGrid_replaceVoicingAmplitudeTier (thee.peek(), itier.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": no simple KlattGrid created."); } } /* End of file KlattGrid.cpp */ praat-6.0.04/dwtools/KlattGrid.h000066400000000000000000000300211261542461700164450ustar00rootroot00000000000000#ifndef _KlattGrid_h_ #define _KlattGrid_h_ /* KlattGrid.h * * Copyright (C) 2008-2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * djmw 20080917 Initial version * djmw 20140113 Latest modification */ #include "Collection.h" #include "PointProcess.h" #include "Sound.h" #include "IntensityTier.h" #include "PitchTier.h" #include "FormantGrid.h" #include "KlattTable.h" #include "Interpreter_decl.h" #include "KlattGrid_def.h" oo_CLASS_CREATE (PhonationPoint, Daata); oo_CLASS_CREATE (PhonationTier, Function); oo_CLASS_CREATE (PhonationGridPlayOptions, Daata); oo_CLASS_CREATE (PhonationGrid, Function); oo_CLASS_CREATE (VocalTractGridPlayOptions, Daata); oo_CLASS_CREATE (VocalTractGrid, Function); oo_CLASS_CREATE (CouplingGridPlayOptions, Daata); oo_CLASS_CREATE (CouplingGrid, Function); oo_CLASS_CREATE (FricationGridPlayOptions, Daata); oo_CLASS_CREATE (FricationGrid, Function); oo_CLASS_CREATE (KlattGridPlayOptions, Daata); oo_CLASS_CREATE (KlattGrid, Function); /******************** PhonationPoint & Tier ************************************/ autoPhonationPoint PhonationPoint_create (double time, double period, double openPhase, double collisionPhase, double te, double power1, double power2, double pulseScale); autoPhonationTier PhonationTier_create (double tmin, double tmax); autoPointProcess PhonationTier_to_PointProcess_closures (PhonationTier me); /************************ PhonationGrid *********************************************/ autoPhonationGrid PhonationGrid_create (double tmin, double tmax); autoPhonationGridPlayOptions PhonationGridPlayOptions_create (); void PhonationGrid_setNames (PhonationGrid me); autoSound PhonationGrid_to_Sound_aspiration (PhonationGrid me, double samplingFrequency); void PhonationGrid_draw (PhonationGrid me, Graphics g); double PhonationGrid_getMaximumPeriod (PhonationGrid me); autoPhonationTier PhonationGrid_to_PhonationTier (PhonationGrid me); /************************ VocalTractGrid *********************************************/ autoVocalTractGrid VocalTractGrid_create (double tmin, double tmax, long numberOfFormants, long numberOfNasalFormants, long numberOfNasalAntiFormants); autoVocalTractGridPlayOptions VocalTractGridPlayOptions_create (); void VocalTractGrid_setNames (VocalTractGrid me); void VocalTractGrid_draw (VocalTractGrid me, Graphics g, int filterModel); /************************ CouplingGrid *********************************************/ autoCouplingGrid CouplingGrid_create (double tmin, double tmax, long numberOfTrachealFormants, long numberOfTrachealAntiFormants, long numberOfDeltaFormants); autoCouplingGridPlayOptions CouplingGridPlayOptions_create (); void CouplingGrid_setNames (CouplingGrid me); double CouplingGrid_getDeltaFormantAtTime (CouplingGrid me, long iformant, double t); double CouplingGrid_getDeltaBandwidthAtTime (CouplingGrid me, long iformant, double t); /********************** FormantGrid & CouplingGrid *************************************/ void FormantGrid_CouplingGrid_updateOpenPhases (FormantGrid me, CouplingGrid thee); /********************** Sound & FormantGrid (& IntensityTier) *************************************/ void Sound_FormantGrid_filterWithOneFormant_inline (Sound me, FormantGrid thee, long iformant); void Sound_FormantGrid_filterWithOneAntiFormant_inline (Sound me, FormantGrid thee, long iformant); void Sound_FormantGrid_Intensities_filterWithOneFormant_inline (Sound me, FormantGrid thee, Ordered amplitudes, long iformant); autoSound Sound_FormantGrid_Intensities_filter (Sound me, FormantGrid thee, Ordered amplitudes, long iformantb, long iformante, int alternatingSign); /************************ FricationGrid *********************************************/ autoFricationGrid FricationGrid_create (double tmin, double tmax, long numberOfFormants); autoFricationGridPlayOptions FricationGridPlayOptions_create (); void FricationGrid_setNames (FricationGrid me); void FricationGrid_draw (FricationGrid me, Graphics g); autoSound FricationGrid_to_Sound (FricationGrid me, double samplingFrequency); autoSound Sound_FricationGrid_filter (Sound me, FricationGrid thee); /************************ Sound & VocalTractGrid & CouplingGrid *********************************************/ autoSound Sound_VocalTractGrid_CouplingGrid_filter (Sound me, VocalTractGrid thee, CouplingGrid coupling); /************************ KlattGrid *********************************************/ autoKlattGrid KlattGrid_create (double tmin, double tmax, long numberOfFormants, long numberOfNasalFormants, long numberOfNasalAntiFormants, long numberOfTrachealFormants, long numberOfTrachealAntiFormants, long numberOfFricationFormants, long numberOfDeltaFormants); autoKlattGrid KlattGrid_createExample (); autoKlattGridPlayOptions KlattGridPlayOptions_create (); void KlattGrid_setNames (KlattGrid me); autoKlattGrid KlattTable_to_KlattGrid (KlattTable me, double frameDuration); void KlattGrid_draw (KlattGrid me, Graphics g, int filterModel); void klattGrid_drawPhonation (KlattGrid me, Graphics g); void KlattGrid_drawVocalTract (KlattGrid me, Graphics g, int filterModel, int withTrachea); #define KlattGrid_FILTER_CASCADE 0 #define KlattGrid_FILTER_PARALLEL 1 #define KlattGrid_ORAL_FORMANTS 1 #define KlattGrid_NASAL_FORMANTS 2 #define KlattGrid_FRICATION_FORMANTS 3 #define KlattGrid_TRACHEAL_FORMANTS 4 #define KlattGrid_NASAL_ANTIFORMANTS 5 #define KlattGrid_TRACHEAL_ANTIFORMANTS 6 #define KlattGrid_DELTA_FORMANTS 7 // Add, Remove, Extract, Replace from PhonationGrid #define PhonationGrid_QUERY_ADD_REMOVE_EXTRACT_REPLACE_PROTO(Name,tierType) \ double KlattGrid_get##Name##AtTime (KlattGrid me, double t); \ void KlattGrid_add##Name##Point (KlattGrid me, double t, double value); \ void KlattGrid_remove##Name##Points (KlattGrid me, double t1, double t2); \ auto##tierType KlattGrid_extract##Name##Tier (KlattGrid me); \ void KlattGrid_replace##Name##Tier (KlattGrid me, tierType thee); // Generate 55 prototypes PhonationGrid_QUERY_ADD_REMOVE_EXTRACT_REPLACE_PROTO (Pitch, PitchTier) PhonationGrid_QUERY_ADD_REMOVE_EXTRACT_REPLACE_PROTO (Flutter, RealTier) PhonationGrid_QUERY_ADD_REMOVE_EXTRACT_REPLACE_PROTO (DoublePulsing, RealTier) PhonationGrid_QUERY_ADD_REMOVE_EXTRACT_REPLACE_PROTO (OpenPhase, RealTier) PhonationGrid_QUERY_ADD_REMOVE_EXTRACT_REPLACE_PROTO (CollisionPhase, RealTier) PhonationGrid_QUERY_ADD_REMOVE_EXTRACT_REPLACE_PROTO (SpectralTilt, IntensityTier) PhonationGrid_QUERY_ADD_REMOVE_EXTRACT_REPLACE_PROTO (Power1, RealTier) PhonationGrid_QUERY_ADD_REMOVE_EXTRACT_REPLACE_PROTO (Power2, RealTier) PhonationGrid_QUERY_ADD_REMOVE_EXTRACT_REPLACE_PROTO (VoicingAmplitude, IntensityTier) PhonationGrid_QUERY_ADD_REMOVE_EXTRACT_REPLACE_PROTO (AspirationAmplitude, IntensityTier) PhonationGrid_QUERY_ADD_REMOVE_EXTRACT_REPLACE_PROTO (BreathinessAmplitude, IntensityTier) #define KlattGrid_QUERY_ADD_REMOVE_PROTO(Name) \ double KlattGrid_get##Name##AtTime (KlattGrid me, int formantType, long iformant, double t); \ void KlattGrid_add##Name##Point (KlattGrid me, int formantType, long iformant, double t, double value); \ void KlattGrid_remove##Name##Points (KlattGrid me, int formantType, long iformant, double t1, double t2); \ double KlattGrid_getDelta##Name##AtTime (KlattGrid me, long iformant, double t); \ void KlattGrid_addDelta##Name##Point (KlattGrid me, long iformant, double t, double value); \ void KlattGrid_removeDelta##Name##Points (KlattGrid me, long iformant, double t1, double t2); // 12 prototypes KlattGrid_QUERY_ADD_REMOVE_PROTO(Formant) KlattGrid_QUERY_ADD_REMOVE_PROTO(Bandwidth) void KlattGrid_formula_frequencies (KlattGrid me, int formantType, const char32 *expression, Interpreter interpreter); void KlattGrid_formula_bandwidths (KlattGrid me, int formantType, const char32 *expression, Interpreter interpreter); void KlattGrid_formula_amplitudes (KlattGrid me, int formantType, const char32 *expression, Interpreter interpreter); autoFormantGrid KlattGrid_extractFormantGrid (KlattGrid me, int formantType); void KlattGrid_replaceFormantGrid (KlattGrid me, int formantType, FormantGrid thee); autoFormantGrid KlattGrid_extractDeltaFormantGrid (KlattGrid me); void KlattGrid_replaceDeltaFormantGrid (KlattGrid me, FormantGrid thee); autoFormantGrid KlattGrid_to_oralFormantGrid_openPhases (KlattGrid me, double fadeFraction); autoPointProcess KlattGrid_extractPointProcess_glottalClosures (KlattGrid me); double KlattGrid_getAmplitudeAtTime (KlattGrid me, int formantType, long iformant, double t); void KlattGrid_addAmplitudePoint (KlattGrid me, int formantType, long iformant, double t, double value); void KlattGrid_removeAmplitudePoints (KlattGrid me, int formantType, long iformant, double t1, double t2); autoIntensityTier KlattGrid_extractAmplitudeTier (KlattGrid me, int formantType, long iformant); void KlattGrid_replaceAmplitudeTier (KlattGrid me, int formantType, long iformant, IntensityTier thee); double KlattGrid_getFricationAmplitudeAtTime (KlattGrid me, double t); void KlattGrid_addFricationAmplitudePoint (KlattGrid me, double t, double value); void KlattGrid_removeFricationAmplitudePoints (KlattGrid me, double t1, double t2); autoIntensityTier KlattGrid_extractFricationAmplitudeTier (KlattGrid me); void KlattGrid_replaceFricationAmplitudeTier (KlattGrid me, IntensityTier thee); double KlattGrid_getFricationBypassAtTime (KlattGrid me, double t); void KlattGrid_addFricationBypassPoint (KlattGrid me, double t, double value); void KlattGrid_removeFricationBypassPoints (KlattGrid me, double t1, double t2); autoIntensityTier KlattGrid_extractFricationBypassTier (KlattGrid me); void KlattGrid_replaceFricationBypassTier (KlattGrid me, IntensityTier thee); void KlattGrid_setGlottisCoupling (KlattGrid me); autoFormantGrid * KlattGrid_getAddressOfFormantGrid (KlattGrid me, int formantType); Ordered * KlattGrid_getAddressOfAmplitudes (KlattGrid me, int formantType); // add/remove frequency + bandwidth (+amplitude) tiers void KlattGrid_addFormant (KlattGrid me,int formantType, long position); void KlattGrid_removeFormant (KlattGrid me,int formantType, long position); // add/remove frequency + bandwidth tiers void KlattGrid_addFormantFrequencyAndBandwidthTiers (KlattGrid me, int formantType, long position); void KlattGrid_removeFormantFrequencyAndBandwidthTiers (KlattGrid me, int formantType, long position); void KlattGrid_addFormantAmplitudeTier (KlattGrid me, int formantType, long position); void KlattGrid_removeFormantAmplitudeTier (KlattGrid me, int formantType, long position); /***************** KlattGrid & Sound *************************************/ // reset PlayOptions to defaults void KlattGrid_play (KlattGrid me); // use playOptions void KlattGrid_playSpecial (KlattGrid me); void KlattGrid_setDefaultPlayOptions (KlattGrid me); autoSound KlattGrid_to_Sound (KlattGrid me); autoSound KlattGrid_to_Sound_phonation (KlattGrid me); int KlattGrid_synthesize (KlattGrid me, double t1, double t2, double samplingFrequency, double maximumPeriod); /* glottal: phonation+aspiration, before entering the filter frication: noise before entering the parallel frication filter section. */ autoSound Sound_KlattGrid_filterByVocalTract (Sound me, KlattGrid thee, int filterModel); autoSound Sound_KlattGrid_filter_frication (Sound me, KlattGrid thee); autoKlattGrid Sound_to_KlattGrid_simple (Sound me, double timeStep, long maximumNumberOfFormants, double maximumFormantFrequency, double windowLength, double preEmphasisFrequency, double minimumPitch, double maximumPitch, double minimumPitchIntensity, int subtractMean); #endif /* _KlattGrid_h_ */ praat-6.0.04/dwtools/KlattGridEditors.cpp000066400000000000000000000321571261542461700203460ustar00rootroot00000000000000/* KlattGridEditors.c * * Copyright (C) 2009-2011 david Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * djmw 20090123 * djmw 20090128 Remove source menu from formant grid editor. * djmw 20090420 dbEditor * djmw 20090527 Protect FormantGridEditor against empty FormantGrids. * djmw 20110304 Thing_new */ #include "Preferences.h" #include "KlattGridEditors.h" #include "EditorM.h" static void KlattGrid_Editor_defaultPlay (KlattGrid me, double tmin, double tmax) { my options -> xmin = tmin; my options-> xmax = tmax; KlattGrid_playSpecial (me); } /************************** KlattGrid_RealTierEditor *********************************/ Thing_implement (KlattGrid_RealTierEditor, RealTierEditor, 0); static void menu_cb_KlattGridHelp (EDITOR_ARGS) { EDITOR_IAM (KlattGrid_RealTierEditor); Melder_help (U"KlattGrid"); } void structKlattGrid_RealTierEditor :: v_createHelpMenuItems (EditorMenu menu) { KlattGrid_RealTierEditor_Parent :: v_createHelpMenuItems (menu); EditorMenu_addCommand (menu, U"KlattGrid help", 0, menu_cb_KlattGridHelp); } void structKlattGrid_RealTierEditor :: v_play (double ltmin, double ltmax) { KlattGrid_Editor_defaultPlay (klattgrid, ltmin, ltmax); } void KlattGrid_RealTierEditor_init (KlattGrid_RealTierEditor me, const char32 *title, KlattGrid klattgrid, RealTier data) { my klattgrid = klattgrid; RealTierEditor_init (me, title, data, 0, 0); } /************************** KlattGrid_PitchTierEditor *********************************/ Thing_implement (KlattGrid_PitchTierEditor, KlattGrid_RealTierEditor, 0); static void menu_cb_KlattGrid_PitchTierEditorHelp (EDITOR_ARGS) { EDITOR_IAM (KlattGrid_PitchTierEditor); Melder_help (U"PitchTierEditor"); } static void menu_cb_PitchTierHelp (EDITOR_ARGS) { EDITOR_IAM (KlattGrid_PitchTierEditor); Melder_help (U"PitchTier"); } void structKlattGrid_PitchTierEditor :: v_createHelpMenuItems (EditorMenu menu) { EditorMenu_addCommand (menu, U"PitchTierEditor help", 0, menu_cb_KlattGrid_PitchTierEditorHelp); EditorMenu_addCommand (menu, U"PitchTier help", 0, menu_cb_PitchTierHelp); } autoKlattGrid_PitchTierEditor KlattGrid_PitchTierEditor_create (const char32 *title, KlattGrid klattgrid) { try { autoKlattGrid_PitchTierEditor me = Thing_new (KlattGrid_PitchTierEditor); RealTier tier = klattgrid -> phonation -> pitch.get(); KlattGrid_RealTierEditor_init (me.peek(), title, klattgrid, tier); return me; } catch (MelderError) { Melder_throw (U"KlattGrid pitch window not created."); } } /************************** KlattGrid_IntensityTierEditor *********************************/ Thing_implement (KlattGrid_IntensityTierEditor, KlattGrid_RealTierEditor, 0); static void menu_cb_IntensityTierHelp (EDITOR_ARGS) { EDITOR_IAM (KlattGrid_IntensityTierEditor); Melder_help (U"IntensityTier"); } void structKlattGrid_IntensityTierEditor :: v_createHelpMenuItems (EditorMenu menu) { KlattGrid_IntensityTierEditor_Parent :: v_createHelpMenuItems (menu); EditorMenu_addCommand (menu, U"IntensityTier help", 0, menu_cb_IntensityTierHelp); } void KlattGrid_IntensityTierEditor_init (KlattGrid_IntensityTierEditor me, const char32 *title, KlattGrid klattgrid, RealTier tier) { KlattGrid_RealTierEditor_init (me, title, klattgrid, tier); } /************************** KlattGrid_DecibelTierEditor *********************************/ Thing_implement (KlattGrid_DecibelTierEditor, KlattGrid_IntensityTierEditor, 0); autoKlattGrid_DecibelTierEditor KlattGrid_DecibelTierEditor_create (const char32 *title, KlattGrid klattgrid, RealTier tier) { try { autoKlattGrid_DecibelTierEditor me = Thing_new (KlattGrid_DecibelTierEditor); KlattGrid_IntensityTierEditor_init (me.peek(), title, klattgrid, tier); return me; } catch (MelderError) { Melder_throw (U"KlattGrid decibel window not created."); } } /************************** KlattGrid_VoicingAmplitudeTierEditor *********************************/ Thing_implement (KlattGrid_VoicingAmplitudeTierEditor, KlattGrid_IntensityTierEditor, 0); autoKlattGrid_VoicingAmplitudeTierEditor KlattGrid_VoicingAmplitudeTierEditor_create (const char32 *title, KlattGrid klattgrid) { try { autoKlattGrid_VoicingAmplitudeTierEditor me = Thing_new (KlattGrid_VoicingAmplitudeTierEditor); RealTier tier = klattgrid -> phonation -> voicingAmplitude.get(); KlattGrid_IntensityTierEditor_init (me.peek(), title, klattgrid, tier); return me; } catch (MelderError) { Melder_throw (U"KlattGrid voicing amplitude window not created."); } } /************************** KlattGrid_AspirationAmplitudeTierEditor *********************************/ Thing_implement (KlattGrid_AspirationAmplitudeTierEditor, KlattGrid_IntensityTierEditor, 0); autoKlattGrid_AspirationAmplitudeTierEditor KlattGrid_AspirationAmplitudeTierEditor_create (const char32 *title, KlattGrid klattgrid) { try { autoKlattGrid_AspirationAmplitudeTierEditor me = Thing_new (KlattGrid_AspirationAmplitudeTierEditor); RealTier tier = klattgrid -> phonation -> aspirationAmplitude.get(); KlattGrid_IntensityTierEditor_init (me.peek(), title, klattgrid, tier); return me; } catch (MelderError) { Melder_throw (U"KlattGrid aspiration amplitude window not created."); } } /************************** KlattGrid_BreathinessAmplitudeTierEditor *********************************/ Thing_implement (KlattGrid_BreathinessAmplitudeTierEditor, KlattGrid_IntensityTierEditor, 0); autoKlattGrid_BreathinessAmplitudeTierEditor KlattGrid_BreathinessAmplitudeTierEditor_create (const char32 *title, KlattGrid klattgrid) { try { autoKlattGrid_BreathinessAmplitudeTierEditor me = Thing_new (KlattGrid_BreathinessAmplitudeTierEditor); RealTier tier = klattgrid -> phonation -> breathinessAmplitude.get(); KlattGrid_IntensityTierEditor_init (me.peek(), title, klattgrid, tier); return me; } catch (MelderError) { Melder_throw (U"KlattGrid breathiness amplitude window not created."); } } /************************** KlattGrid_SpectralTiltTierEditor *********************************/ Thing_implement (KlattGrid_SpectralTiltTierEditor, KlattGrid_IntensityTierEditor, 0); autoKlattGrid_SpectralTiltTierEditor KlattGrid_SpectralTiltTierEditor_create (const char32 *title, KlattGrid klattgrid) { try { autoKlattGrid_SpectralTiltTierEditor me = Thing_new (KlattGrid_SpectralTiltTierEditor); RealTier tier = klattgrid -> phonation -> spectralTilt.get(); KlattGrid_IntensityTierEditor_init (me.peek(), title, klattgrid, tier); return me; } catch (MelderError) { Melder_throw (U"KlattGrid spectral tilt window not created."); } } /************************** KlattGrid_FricationBypassTierEditor *********************************/ Thing_implement (KlattGrid_FricationBypassTierEditor, KlattGrid_IntensityTierEditor, 0); autoKlattGrid_FricationBypassTierEditor KlattGrid_FricationBypassTierEditor_create (const char32 *title, KlattGrid klattgrid) { try { autoKlattGrid_FricationBypassTierEditor me = Thing_new (KlattGrid_FricationBypassTierEditor); RealTier tier = klattgrid -> frication -> bypass.get(); KlattGrid_IntensityTierEditor_init (me.peek(), title, klattgrid, tier); return me; } catch (MelderError) { Melder_throw (U"KlattGrid frication bypass window not created."); } } /************************** KlattGrid_FricationAmplitudeTierEditor *********************************/ Thing_implement (KlattGrid_FricationAmplitudeTierEditor, KlattGrid_IntensityTierEditor, 0); autoKlattGrid_FricationAmplitudeTierEditor KlattGrid_FricationAmplitudeTierEditor_create (const char32 *title, KlattGrid klattgrid) { try { autoKlattGrid_FricationAmplitudeTierEditor me = Thing_new (KlattGrid_FricationAmplitudeTierEditor); RealTier tier = klattgrid -> frication -> fricationAmplitude.get(); KlattGrid_IntensityTierEditor_init (me.peek(), title, klattgrid, tier); return me; } catch (MelderError) { Melder_throw (U"KlattGrid frication amplitude window not created."); } } /************************** KlattGrid_OpenPhaseTierEditor *********************************/ Thing_implement (KlattGrid_OpenPhaseTierEditor, KlattGrid_RealTierEditor, 0); autoKlattGrid_OpenPhaseTierEditor KlattGrid_OpenPhaseTierEditor_create (const char32 *title, KlattGrid klattgrid) { try { autoKlattGrid_OpenPhaseTierEditor me = Thing_new (KlattGrid_OpenPhaseTierEditor); RealTier tier = klattgrid -> phonation -> openPhase.get(); KlattGrid_RealTierEditor_init (me.peek(), title, klattgrid, tier); return me; } catch (MelderError) { Melder_throw (U"KlattGrid open phase window not created."); } } /************************** KlattGrid_CollisionPhaseTierEditor *********************************/ Thing_implement (KlattGrid_CollisionPhaseTierEditor, KlattGrid_RealTierEditor, 0); autoKlattGrid_CollisionPhaseTierEditor KlattGrid_CollisionPhaseTierEditor_create (const char32 *title, KlattGrid klattgrid) { try { autoKlattGrid_CollisionPhaseTierEditor me = Thing_new (KlattGrid_CollisionPhaseTierEditor); RealTier tier = klattgrid -> phonation -> collisionPhase.get(); KlattGrid_RealTierEditor_init (me.peek(), title, klattgrid, tier); return me; } catch (MelderError) { Melder_throw (U"KlattGrid collision phase window not created."); } } /************************** KlattGrid_Power1TierEditor *********************************/ Thing_implement (KlattGrid_Power1TierEditor, KlattGrid_RealTierEditor, 0); autoKlattGrid_Power1TierEditor KlattGrid_Power1TierEditor_create (const char32 *title, KlattGrid klattgrid) { try { autoKlattGrid_Power1TierEditor me = Thing_new (KlattGrid_Power1TierEditor); RealTier tier = klattgrid -> phonation -> power1.get(); KlattGrid_RealTierEditor_init (me.peek(), title, klattgrid, tier); return me; } catch (MelderError) { Melder_throw (U"KlattGrid power1 window not created."); } } /************************** KlattGrid_Power2TierEditor *********************************/ Thing_implement (KlattGrid_Power2TierEditor, KlattGrid_RealTierEditor, 0); autoKlattGrid_Power2TierEditor KlattGrid_Power2TierEditor_create (const char32 *title, KlattGrid klattgrid) { try { autoKlattGrid_Power2TierEditor me = Thing_new (KlattGrid_Power2TierEditor); RealTier tier = klattgrid -> phonation -> power2.get(); KlattGrid_RealTierEditor_init (me.peek(), title, klattgrid, tier); return me; } catch (MelderError) { Melder_throw (U"KlattGrid power2 window not created."); } } /************************** KlattGrid_FlutterTierEditor *********************************/ Thing_implement (KlattGrid_FlutterTierEditor, KlattGrid_RealTierEditor, 0); autoKlattGrid_FlutterTierEditor KlattGrid_FlutterTierEditor_create (const char32 *title, KlattGrid klattgrid) { try { autoKlattGrid_FlutterTierEditor me = Thing_new (KlattGrid_FlutterTierEditor); RealTier tier = klattgrid -> phonation -> flutter.get(); KlattGrid_RealTierEditor_init (me.peek(), title, klattgrid, tier); return me; } catch (MelderError) { Melder_throw (U"KlattGrid flutter window not created."); } } /************************** KlattGrid_DoublePulsingTierEditor *********************************/ Thing_implement (KlattGrid_DoublePulsingTierEditor, KlattGrid_RealTierEditor, 0); autoKlattGrid_DoublePulsingTierEditor KlattGrid_DoublePulsingTierEditor_create (const char32 *title, KlattGrid klattgrid) { try { autoKlattGrid_DoublePulsingTierEditor me = Thing_new (KlattGrid_DoublePulsingTierEditor); RealTier tier = klattgrid -> phonation -> doublePulsing.get(); KlattGrid_RealTierEditor_init (me.peek(), title, klattgrid, tier); return me; } catch (MelderError) { Melder_throw (U"KlattGrid double pulsing window not created."); } } /************************** KlattGrid_FormantGridEditor *********************************/ Thing_implement (KlattGrid_FormantGridEditor, FormantGridEditor, 0); static bool FormantGrid_isEmpty (FormantGrid me) { return my formants -> size == 0 || my bandwidths -> size == 0; } void structKlattGrid_FormantGridEditor :: v_play (double ltmin, double ltmax) { KlattGrid_Editor_defaultPlay (klattgrid, ltmin, ltmax); } autoKlattGrid_FormantGridEditor KlattGrid_FormantGridEditor_create (const char32 *title, KlattGrid data, int formantType) { try { Melder_assert (data); autoFormantGrid* fg = KlattGrid_getAddressOfFormantGrid (data, formantType); if (fg) { Melder_throw (U"Formant type unknown."); } if (FormantGrid_isEmpty (fg->get())) { Melder_throw (U"Cannot edit an empty formant grid."); } autoKlattGrid_FormantGridEditor me = Thing_new (KlattGrid_FormantGridEditor); my klattgrid = data; FormantGridEditor_init (me.peek(), title, fg->get()); return me; } catch (MelderError) { Melder_throw (U"KlattGrid formant window not created."); } } /* End of file KlattGridEditors.cpp */ praat-6.0.04/dwtools/KlattGridEditors.h000066400000000000000000000317301261542461700200070ustar00rootroot00000000000000#ifndef _KlattGridEditors_h_ #define _KlattGridEditors_h_ /* KlattGridEditors.h * * Copyright (C) 2009-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "KlattGrid.h" #include "PitchTier.h" #include "IntensityTier.h" #include "RealTierEditor.h" #include "FormantGridEditor.h" Thing_define (KlattGrid_RealTierEditor, RealTierEditor) { KlattGrid klattgrid; void v_createHelpMenuItems (EditorMenu menu) override; void v_play (double tmin, double tmax) override; }; void KlattGrid_RealTierEditor_init (KlattGrid_RealTierEditor me, const char32 *title, KlattGrid klattgrid, RealTier data); Thing_define (KlattGrid_OpenPhaseTierEditor, KlattGrid_RealTierEditor) { double v_minimumLegalValue () override { return 0.0; } double v_maximumLegalValue () override { return 1.0; } const char32 * v_quantityText () override { return U"Open phase (0..1)"; } const char32 * v_quantityKey () override { return U"Open phase"; } const char32 * v_rightTickUnits () override { return U""; } double v_defaultYmin () override { return 0.0; } double v_defaultYmax () override { return 1.0; } const char32 * v_setRangeTitle () override { return U"Set open phase range..."; } const char32 * v_defaultYminText () override { return U"0.0"; } const char32 * v_defaultYmaxText () override { return U"1.0"; } const char32 * v_yminText () override { return U"Minimum (0..1)"; } const char32 * v_ymaxText () override { return U"Maximum (0..1)"; } const char32 * v_yminKey () override { return U"Minimum"; } const char32 * v_ymaxKey () override { return U"Maximum"; } }; autoKlattGrid_OpenPhaseTierEditor KlattGrid_OpenPhaseTierEditor_create (const char32 *title, KlattGrid klattgrid); Thing_define (KlattGrid_CollisionPhaseTierEditor, KlattGrid_RealTierEditor) { double v_minimumLegalValue () override { return 0.0; } double v_maximumLegalValue () override { return 1.0; } const char32 * v_quantityText () override { return U"Collision phase (0..1)"; } const char32 * v_quantityKey () override { return U"Collision phase"; } const char32 * v_rightTickUnits () override { return U""; } double v_defaultYmin () override { return 0.0; } double v_defaultYmax () override { return 0.1; } const char32 * v_setRangeTitle () override { return U"Set collision phase range..."; } const char32 * v_defaultYminText () override { return U"0.0"; } const char32 * v_defaultYmaxText () override { return U"0.1"; } const char32 * v_yminText () override { return U"Minimum (0..1)"; } const char32 * v_ymaxText () override { return U"Maximum (0..1)"; } const char32 * v_yminKey () override { return U"Minimum"; } const char32 * v_ymaxKey () override { return U"Maximum"; } }; autoKlattGrid_CollisionPhaseTierEditor KlattGrid_CollisionPhaseTierEditor_create (const char32 *title, KlattGrid klattgrid); Thing_define (KlattGrid_Power1TierEditor, KlattGrid_RealTierEditor) { double v_minimumLegalValue () override { return 0.0; } const char32 * v_quantityText () override { return U"Power1"; } const char32 * v_quantityKey () override { return U"Power1"; } const char32 * v_rightTickUnits () override { return U""; } double v_defaultYmin () override { return 0.0; } double v_defaultYmax () override { return 4.0; } const char32 * v_setRangeTitle () override { return U"Set power1 range..."; } const char32 * v_defaultYminText () override { return U"0"; } const char32 * v_defaultYmaxText () override { return U"4"; } const char32 * v_yminText () override { return U"Minimum"; } const char32 * v_ymaxText () override { return U"Maximum"; } const char32 * v_yminKey () override { return U"Minimum"; } const char32 * v_ymaxKey () override { return U"Maximum"; } }; autoKlattGrid_Power1TierEditor KlattGrid_Power1TierEditor_create (const char32 *title, KlattGrid klattgrid); Thing_define (KlattGrid_Power2TierEditor, KlattGrid_RealTierEditor) { double v_minimumLegalValue () override { return 0.0; } const char32 * v_quantityText () override { return U"Power2"; } const char32 * v_quantityKey () override { return U"Power2"; } const char32 * v_rightTickUnits () override { return U""; } double v_defaultYmin () override { return 0.0; } double v_defaultYmax () override { return 5.0; } const char32 * v_setRangeTitle () override { return U"Set power2 range..."; } const char32 * v_defaultYminText () override { return U"0"; } const char32 * v_defaultYmaxText () override { return U"5"; } const char32 * v_yminText () override { return U"Minimum"; } const char32 * v_ymaxText () override { return U"Maximum"; } const char32 * v_yminKey () override { return U"Minimum"; } const char32 * v_ymaxKey () override { return U"Maximum"; } }; autoKlattGrid_Power2TierEditor KlattGrid_Power2TierEditor_create (const char32 *title, KlattGrid klattgrid); Thing_define (KlattGrid_DoublePulsingTierEditor, KlattGrid_RealTierEditor) { double v_minimumLegalValue () override { return 0.0; } double v_maximumLegalValue () override { return 1.0; } const char32 * v_quantityText () override { return U"Double pulsing (0..1)"; } const char32 * v_quantityKey () override { return U"Double pulsing"; } const char32 * v_rightTickUnits () override { return U""; } double v_defaultYmin () override { return 0.0; } double v_defaultYmax () override { return 1.0; } const char32 * v_setRangeTitle () override { return U"Set double pulsing range..."; } const char32 * v_defaultYminText () override { return U"0.0"; } const char32 * v_defaultYmaxText () override { return U"1.0"; } const char32 * v_yminText () override { return U"Minimum (0..1)"; } const char32 * v_ymaxText () override { return U"Maximum (0..1)"; } const char32 * v_yminKey () override { return U"Minimum"; } const char32 * v_ymaxKey () override { return U"Maximum"; } }; autoKlattGrid_DoublePulsingTierEditor KlattGrid_DoublePulsingTierEditor_create (const char32 *title, KlattGrid klattgrid); Thing_define (KlattGrid_PitchTierEditor, KlattGrid_RealTierEditor) { void v_createHelpMenuItems (EditorMenu menu) override; double v_minimumLegalValue () override { return 0.0; } const char32 * v_quantityText () override { return U"Frequency (Hz)"; } const char32 * v_quantityKey () override { return U"Frequency"; } const char32 * v_rightTickUnits () override { return U" Hz"; } double v_defaultYmin () override { return 50.0; } double v_defaultYmax () override { return 600.0; } const char32 * v_setRangeTitle () override { return U"Set frequency range..."; } const char32 * v_defaultYminText () override { return U"50.0"; } const char32 * v_defaultYmaxText () override { return U"600.0"; } const char32 * v_yminText () override { return U"Minimum frequency (Hz)"; } const char32 * v_ymaxText () override { return U"Maximum frequency (Hz)"; } const char32 * v_yminKey () override { return U"Minimum frequency"; } const char32 * v_ymaxKey () override { return U"Maximum frequency"; } }; autoKlattGrid_PitchTierEditor KlattGrid_PitchTierEditor_create (const char32 *title, KlattGrid klattgrid); Thing_define (KlattGrid_FlutterTierEditor, KlattGrid_RealTierEditor) { double v_minimumLegalValue () override { return 0.0; } double v_maximumLegalValue () override { return 1.0; } const char32 * v_quantityText () override { return U"Flutter (0..1)"; } const char32 * v_quantityKey () override { return U"Flutter"; } const char32 * v_rightTickUnits () override { return U""; } double v_defaultYmin () override { return 0.0; } double v_defaultYmax () override { return 1.0; } const char32 * v_setRangeTitle () override { return U"Set flutter range..."; } const char32 * v_defaultYminText () override { return U"0.0"; } const char32 * v_defaultYmaxText () override { return U"1.0"; } const char32 * v_yminText () override { return U"Minimum (0..1)"; } const char32 * v_ymaxText () override { return U"Maximum (0..1)"; } const char32 * v_yminKey () override { return U"Minimum"; } const char32 * v_ymaxKey () override { return U"Maximum"; } }; autoKlattGrid_FlutterTierEditor KlattGrid_FlutterTierEditor_create (const char32 *title, KlattGrid klattgrid); Thing_define (KlattGrid_IntensityTierEditor, KlattGrid_RealTierEditor) { void v_createHelpMenuItems (EditorMenu menu) override; const char32 * v_quantityText () override { return U"Intensity (dB)"; } const char32 * v_quantityKey () override { return U"Intensity"; } const char32 * v_rightTickUnits () override { return U" dB"; } double v_defaultYmin () override { return 50.0; } double v_defaultYmax () override { return 100.0; } const char32 * v_setRangeTitle () override { return U"Set intensity range..."; } const char32 * v_defaultYminText () override { return U"50.0"; } const char32 * v_defaultYmaxText () override { return U"100.0"; } const char32 * v_yminText () override { return U"Minimum intensity (dB)"; } const char32 * v_ymaxText () override { return U"Maximum intensity (dB)"; } const char32 * v_yminKey () override { return U"Minimum intensity"; } const char32 * v_ymaxKey () override { return U"Maximum intensity"; } }; void KlattGrid_IntensityTierEditor_init (KlattGrid_IntensityTierEditor me, const char32 *title, KlattGrid klattgrid, RealTier tier); Thing_define (KlattGrid_DecibelTierEditor, KlattGrid_IntensityTierEditor) { const char32 * v_quantityText () override { return U"Amplitude (dB)"; } const char32 * v_quantityKey () override { return U"Amplitude"; } const char32 * v_rightTickUnits () override { return U" dB"; } double v_defaultYmin () override { return -30.0; } double v_defaultYmax () override { return 30.0; } const char32 * v_setRangeTitle () override { return U"Set amplitude range..."; } const char32 * v_defaultYminText () override { return U"-30.0"; } const char32 * v_defaultYmaxText () override { return U"30.0"; } const char32 * v_yminText () override { return U"Minimum amplitude (dB)"; } const char32 * v_ymaxText () override { return U"Maximum amplitude (dB)"; } const char32 * v_yminKey () override { return U"Minimum amplitude"; } const char32 * v_ymaxKey () override { return U"Maximum amplitude"; } }; autoKlattGrid_DecibelTierEditor KlattGrid_DecibelTierEditor_create (const char32 *title, KlattGrid klattgrid, RealTier data); Thing_define (KlattGrid_VoicingAmplitudeTierEditor, KlattGrid_IntensityTierEditor) { }; autoKlattGrid_VoicingAmplitudeTierEditor KlattGrid_VoicingAmplitudeTierEditor_create (const char32 *title, KlattGrid klattgrid); Thing_define (KlattGrid_AspirationAmplitudeTierEditor, KlattGrid_IntensityTierEditor) { }; autoKlattGrid_AspirationAmplitudeTierEditor KlattGrid_AspirationAmplitudeTierEditor_create (const char32 *title, KlattGrid klattgrid); Thing_define (KlattGrid_BreathinessAmplitudeTierEditor, KlattGrid_IntensityTierEditor) { }; autoKlattGrid_BreathinessAmplitudeTierEditor KlattGrid_BreathinessAmplitudeTierEditor_create (const char32 *title, KlattGrid klattgrid); Thing_define (KlattGrid_SpectralTiltTierEditor, KlattGrid_IntensityTierEditor) { double v_defaultYmin () override { return -50.0; } double v_defaultYmax () override { return 10.0; } const char32 * v_defaultYminText () override { return U"-50.0"; } const char32 * v_defaultYmaxText () override { return U"10.0"; } }; autoKlattGrid_SpectralTiltTierEditor KlattGrid_SpectralTiltTierEditor_create (const char32 *title, KlattGrid klattgrid); Thing_define (KlattGrid_FricationBypassTierEditor, KlattGrid_IntensityTierEditor) { double v_defaultYmin () override { return -50.0; } double v_defaultYmax () override { return 10.0; } const char32 * v_defaultYminText () override { return U"-50.0"; } const char32 * v_defaultYmaxText () override { return U"10.0"; } }; autoKlattGrid_FricationBypassTierEditor KlattGrid_FricationBypassTierEditor_create (const char32 *title, KlattGrid klattgrid); Thing_define (KlattGrid_FricationAmplitudeTierEditor, KlattGrid_IntensityTierEditor) { }; autoKlattGrid_FricationAmplitudeTierEditor KlattGrid_FricationAmplitudeTierEditor_create (const char32 *title, KlattGrid klattgrid); Thing_define (KlattGrid_FormantGridEditor, FormantGridEditor) { KlattGrid klattgrid; void v_play (double tmin, double tmax) override; bool v_hasSourceMenu () override { return false; } }; autoKlattGrid_FormantGridEditor KlattGrid_FormantGridEditor_create (const char32 *title, KlattGrid data, int formantType); /* End of file KlattGridEditors.h */ #endif praat-6.0.04/dwtools/KlattGrid_def.h000066400000000000000000000151351261542461700172740ustar00rootroot00000000000000/* KlattGrid_def.h * * Copyright (C) 2008-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT PhonationPoint oo_DEFINE_CLASS (PhonationPoint, Daata) oo_DOUBLE (time) /* AnyPoint : glottis closing time */ oo_DOUBLE (period) /* 1/F0 */ oo_DOUBLE (openPhase) oo_DOUBLE (collisionPhase) oo_DOUBLE (te) // time from glottis open to exponential decay or closing oo_DOUBLE (power1) /* flow function */ oo_DOUBLE (power2) oo_DOUBLE (pulseScale) /* multiplier for diplophonia, shimmer */ oo_END_CLASS (PhonationPoint) #undef ooSTRUCT #define ooSTRUCT PhonationTier oo_DEFINE_CLASS (PhonationTier, Function) oo_COLLECTION (SortedSetOfDouble, points, PhonationPoint, 0) oo_END_CLASS (PhonationTier) #undef ooSTRUCT #define ooSTRUCT PhonationGridPlayOptions oo_DEFINE_CLASS (PhonationGridPlayOptions, Daata) oo_INT (voicing) oo_INT (aspiration) oo_INT (breathiness) oo_INT (flutter) oo_INT (doublePulsing) oo_INT (collisionPhase) oo_INT (spectralTilt) oo_INT (flowFunction) // 1: User defined with tiers (power1, power2); 2: (2,3); 3: (3,4) oo_INT (flowDerivative) oo_DOUBLE (maximumPeriod) oo_END_CLASS (PhonationGridPlayOptions) #undef ooSTRUCT #define ooSTRUCT PhonationGrid oo_DEFINE_CLASS (PhonationGrid, Function) oo_AUTO_OBJECT (PitchTier, 0, pitch) oo_AUTO_OBJECT (RealTier, 0, flutter) // [0,1] oo_AUTO_OBJECT (IntensityTier, 0, voicingAmplitude) // dB oo_AUTO_OBJECT (RealTier, 0, doublePulsing) // [0,1] oo_AUTO_OBJECT (RealTier, 0, openPhase) // (0,1) oo_AUTO_OBJECT (RealTier, 0, collisionPhase) // oo_AUTO_OBJECT (RealTier, 0, power1) // 2,3.. oo_AUTO_OBJECT (RealTier, 0, power2) // 3,4.. power2>power1 oo_AUTO_OBJECT (IntensityTier, 0, spectralTilt) // dB oo_AUTO_OBJECT (IntensityTier, 0, aspirationAmplitude) // dB oo_AUTO_OBJECT (IntensityTier, 0, breathinessAmplitude) // dB #if !oo_READING && !oo_WRITING oo_AUTO_OBJECT (PhonationGridPlayOptions, 0, options) #endif #if oo_READING options = PhonationGridPlayOptions_create (); PhonationGrid_setNames (this); #endif #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (PhonationGrid) #undef ooSTRUCT #define ooSTRUCT VocalTractGridPlayOptions oo_DEFINE_CLASS (VocalTractGridPlayOptions, Daata) oo_INT (filterModel) oo_LONG (startOralFormant) oo_LONG (endOralFormant) oo_LONG (startNasalFormant) oo_LONG (endNasalFormant) oo_LONG (startNasalAntiFormant) oo_LONG (endNasalAntiFormant) oo_END_CLASS (VocalTractGridPlayOptions) #undef ooSTRUCT #define ooSTRUCT VocalTractGrid oo_DEFINE_CLASS (VocalTractGrid, Function) oo_AUTO_OBJECT (FormantGrid, 0, oral_formants) oo_AUTO_OBJECT (FormantGrid, 0, nasal_formants) oo_AUTO_OBJECT (FormantGrid, 0, nasal_antiformants) // for parallel synthesis oo_COLLECTION (Ordered, oral_formants_amplitudes, IntensityTier, 0) oo_COLLECTION (Ordered, nasal_formants_amplitudes, IntensityTier, 0) #if !oo_READING && !oo_WRITING oo_AUTO_OBJECT (VocalTractGridPlayOptions, 0, options) #endif #if oo_READING options = VocalTractGridPlayOptions_create (); VocalTractGrid_setNames (this); #endif #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (VocalTractGrid) #undef ooSTRUCT #define ooSTRUCT CouplingGridPlayOptions oo_DEFINE_CLASS (CouplingGridPlayOptions, Daata) oo_LONG (startTrachealFormant) oo_LONG (endTrachealFormant) oo_LONG (startTrachealAntiFormant) oo_LONG (endTrachealAntiFormant) oo_LONG (startDeltaFormant) oo_LONG (endDeltaFormant) oo_LONG (startDeltaBandwidth) oo_LONG (endDeltaBandwidth) oo_INT (openglottis) oo_DOUBLE (fadeFraction) oo_END_CLASS (CouplingGridPlayOptions) #undef ooSTRUCT #define ooSTRUCT CouplingGrid oo_DEFINE_CLASS (CouplingGrid, Function) oo_AUTO_OBJECT (FormantGrid, 0, tracheal_formants) oo_AUTO_OBJECT (FormantGrid, 0, tracheal_antiformants) oo_COLLECTION (Ordered, tracheal_formants_amplitudes, IntensityTier, 0) oo_AUTO_OBJECT (FormantGrid, 0, delta_formants) #if !oo_READING && !oo_WRITING oo_AUTO_OBJECT (PhonationTier, 0, glottis) oo_AUTO_OBJECT (CouplingGridPlayOptions, 0, options) #endif #if oo_READING options = CouplingGridPlayOptions_create (); glottis = PhonationTier_create (xmin, xmax); CouplingGrid_setNames (this); #endif #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (CouplingGrid) #undef ooSTRUCT #define ooSTRUCT FricationGridPlayOptions oo_DEFINE_CLASS (FricationGridPlayOptions, Daata) oo_LONG (startFricationFormant) oo_LONG (endFricationFormant) oo_INT (bypass) oo_END_CLASS (FricationGridPlayOptions) #undef ooSTRUCT #define ooSTRUCT FricationGrid oo_DEFINE_CLASS (FricationGrid, Function) oo_AUTO_OBJECT (IntensityTier, 0, fricationAmplitude) // dB oo_AUTO_OBJECT (FormantGrid, 0, frication_formants) oo_COLLECTION (Ordered, frication_formants_amplitudes, RealTier, 0) oo_AUTO_OBJECT (IntensityTier, 0, bypass) // dB #if !oo_READING && !oo_WRITING oo_AUTO_OBJECT (FricationGridPlayOptions, 0, options) #endif #if oo_READING options = FricationGridPlayOptions_create (); FricationGrid_setNames (this); #endif #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (FricationGrid) #undef ooSTRUCT #define ooSTRUCT KlattGridPlayOptions oo_DEFINE_CLASS (KlattGridPlayOptions, Daata) oo_DOUBLE (samplingFrequency) oo_INT (scalePeak) oo_DOUBLE (xmin) oo_DOUBLE (xmax) oo_END_CLASS (KlattGridPlayOptions) #undef ooSTRUCT #define ooSTRUCT KlattGrid oo_DEFINE_CLASS (KlattGrid, Function) oo_AUTO_OBJECT (PhonationGrid, 0, phonation) // Glottal source oo_AUTO_OBJECT (VocalTractGrid, 0, vocalTract) // Filter oo_AUTO_OBJECT (CouplingGrid, 0, coupling) // Coupling between source and filter oo_AUTO_OBJECT (FricationGrid, 0, frication) // Frication source oo_AUTO_OBJECT (IntensityTier, 0, gain) // final scaling #if !oo_READING && !oo_WRITING oo_AUTO_OBJECT (KlattGridPlayOptions, 0, options) #endif #if oo_READING options = KlattGridPlayOptions_create (); KlattGrid_setNames (this); #endif #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (KlattGrid) #undef ooSTRUCT praat-6.0.04/dwtools/KlattTable.cpp000066400000000000000000010126211261542461700171510ustar00rootroot00000000000000/* KlattTable.cpp * * Copyright (C) 2008-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* The README file that accompanied the version 3.03 softare: Klatt Cascade-Parallel Formant Synthesizer v 3.03 (April 1994) -------------------------------------------------------------- Jon Iles j.p.iles@cs.bham.ac.uk Nick Ing-Simmons nicki@lobby.ti.com History ------- This file contains a version of the Klatt Cascade-Parallel Formant Speech Synthesizer. The software for this synthesizer was originally described in (1) and an updated version of the software was described in (2). The most recent version of the software synthesizer as described in (2) is commercially available from Sensimetrics Inc. (3) The code contained within this directory is a translation of the original Fortran, into C, by Dennis Klatt. In terms of the two articles referred to above, this version seems to be the mid point of the development between the two systems described. Modifications ------------- The main part of the code in this directory was posted to comp.speech in early 1993 as part of a crude text to speech conversion system. The code taken from comp.speech seemed to have been modified considerably from the original, and for use of the synthesizer in research it was necessary to "fix" the changes that had been made. The major changes that have been made are: 1. Re-introduced the parallel-only / cascade-parallel switch. This allows choice of synthesis method, either using both branches, or just using the parallel branch. 2. Correct use of bandwidth parameters. One of the cascade bandwidth parameters was being wrongly used in the parallel branch of the synthesizer. 3. Modified operation of natural voicing source. The amplitude of the natural voicing source was very much smaller than the amplitude of the impulse source, making it difficult to swap between them to evaluate the differences. 4. Removed the software synthesizer from the context of a text to speech system. The synthesizer is now a stand-alone program, accepting input as a set of parameters from a file, and allowing output to a file or to stdout. 5. Increased the number of parameters available for use in the input file. The original comp.speech software made assumptions about a number of the control parameters. To provide the greatest flexibility, these parameters have been made specific in the input file. It is important to note that the input file format is NOT compatible with that used by the software originally posted to the comp.speech news group. 6. Added command line options to control the parameters that remain constant during synthesis. 7. Added F0 flutter control, as described in (2). 8. Subsequently the code in parwave was re-written by Nick to improve efficiency, and add a more acceptable ANSI style, and generally make an elegant implementation. 9. Further re-writes have been carried out to remove all global references. All parameters are passed around in structures. 10. The facility to use a sampled natural excitation waveform has been implemented. Naturalness of the resulting synthetic speech can be greatly improved by using the glottal excitation waveform from a natural speaker, especially if it is the speaker on whose voice the synthesis is actually based. This may be obtained indirectly by inverse-filtering a vowel. 11. This synthesizer appears in modified form as part of Nick's rsynth text-to-speech system. This may be found at svr-ftp.eng.cam.ac.uk in comp.speech/sources. 12. Fixed bug to the antiresonator code that caused overflow problems when compiling on a PC 13. Various minor modifications to ensure correct compilation using Microsoft C 7.0 (tested) and Borland C (untested). 14. Modified random number generation for noise production as previously it was dependent on the size of the "long" type. Input File Format ----------------- The input file consists of a series of parameter frames. Each frame of parameters (usually) represents 10ms of audio output, although this figure can be adjusted down to 1ms per frame. The parameters in each frame are described below. To avoid confusion, note that the cascade and parallel branch of the synthesizer duplicate some of the control parameters. f0 This is the fundamental frequency (pitch) of the utterance in this case it is specified in steps of 0.1 Hz, hence 100Hz will be represented by a value of 1000. av Amplitude of voicing for the cascade branch of the synthesizer in dB0. Range 0-70, value usually 60 for a vowel sound. f1 First formant frequency in 200-1300 Hz. b1 Cascade branch bandwidth of first formant in the range 40-1000 Hz. f2 Second formant frequency in the range 550 - 3000 Hz. b2 Cascade branch bandwidth of second formant in the range 40-1000 Hz. f3 Third formant frequency in the range 1200-4999 Hz. b3 Cascade branch bandwidth of third formant in the range 40-1000 Hz. f4 Fourth formant frequency in 1200-4999 Hz. b4 Cascade branch bandwidth of fourth formant in the range 40-1000 Hz. f5 Fifth formant frequency in the range 1200-4999 Hz. b5 Cascade branch bandwidth of fifth formant in the range 40-1000 Hz. f6 Sixth formant frequency in the range 1200-4999 Hz. b6 Cascade branch bandwidth of sixth formant in the range 40-2000 Hz. fnz Frequency of the nasal zero in the range 248-528 Hz. (cascade branch only) An implementation of a Klatt cascade-parallel formant synthesizer. A re-implementation in C of Dennis Klatt's Fortran code, by: Jon Iles (j.p.iles@cs.bham.ac.uk) Nick Ing-Simmons (nicki@lobby.ti.com) This code is a slightly modified version of the code of bnz Bandwidth of the nasal zero in the range 40-1000 Hz (cascade branch only) fnp Frequency of the nasal pole in the range 248-528 Hz bnp Bandwidth of the nasal pole in the range 40-1000 Hz ah Amplitude of aspiration 0-70 dB. kopen Open quotient of voicing waveform, range 0-60, usually 30. Will influence the gravelly or smooth quality of the voice. Only works with impulse and antural simulations. For the sampled glottal excitation waveform the open quotient is fixed. aturb Amplitude of turbulence 0-80 dB. A value of 40 is useful. Can be used to simulate "breathy" voice quality. tilt Spectral tilt in dB, range 0-24. Tilts down the output spectrum. The value refers to dB down at 3Khz. Increasing the value emphasizes the low frequency content of the speech and attenuates the high frequency content. af Amplitude of frication in dB, range 0-80 (parallel branch) skew Spectral Skew - skewness of alternate periods, range 0-40 a1 Amplitude of first formant in the parallel branch, in 0-80 dB. b1p Bandwidth of the first formant in the parallel branch, in Hz. a2 Amplitude of parallel branch second formant. b2p Bandwidth of parallel branch second formant. a3 Amplitude of parallel branch third formant. b3p Bandwidth of parallel branch third formant. a4 Amplitude of parallel branch fourth formant. b4p Bandwidth of parallel branch fourth formant. a5 Amplitude of parallel branch fifth formant. b5p Bandwidth of parallel branch fifth formant. a6 Amplitude of parallel branch sixth formant. b6p Bandwidth of parallel branch sixth formant. anp Amplitude of the parallel branch nasal formant. ab Amplitude of bypass frication in dB. 0-80. avp Amplitude of voicing for the parallel branch, 0-70 dB. gain Overall gain in dB range 0-80. Command Line Options -------------------- -h Displays a help message. -i sets input filename. -o sets output filename. If output filename not specified, stdout is used. -q quiet - print no messages. -t select output waveform (RTFC !) -c select cascade-parallel configuration. Parallel only configuration is default. -n Number of formants in cascade branch. Default is 5. -s set sample rate Default is 10Khz. -f set number of milliseconds per frame. Default is 10ms per frame -v Specifies that the voicing source to be used. 1 = impulse train. 2 = natural simulation. 3 = natural samples. Default is natural voicing -V Specifies the filename for a sampled natural excitation waveform. See man page for format details. -r Output raw binary samples, rather than ASCII integer samples. 1 = high byte, low byte arrangement. 2 = low byte, high byte arrangement. -F percentage of f0 flutter Default is 0 Example Parameter File ---------------------- Some example parameter files for a short segments of speech are included in this distribution. e.g. file called example1.par. Use the following to produce the output waveforms: klatt -i example1.par -o example1.dat -f 5 -v 2 klatt -i example2.par -o example2.dat -f 5 -s 16000 -v 2 The '-r' option can be used to produce raw binary output, which can then be converted to many different formats using utilities such as 'sox' (sound exchange) which are available from major ftp sites. An example is given below of conversion to the ulaw encoded format used by Sun Sparc SLC's sox -r 16000 -s -w example.raw -r 8000 -b -U example.au Beware of the byte ordering of your machine - if the above procedure produces distored rubbish, try using -r 2 instead of -r 1. This just reverses the byte ordering in the raw binary output file. It is also worth noting that the above example reduces the quality of the output, as the sampling rate is being halved and the number of bits per sample is being halved. Ideally output should be at 16kHz with 16 bits per sample. Notes ----- This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Bug reports, comments etc. to j.p.iles@cs.bham.ac.uk References ---------- (1) @article{klatt1980, AUTHOR = {Klatt,D.H.}, JOURNAL = {Journal of the Acoustic Society of America}, PAGES = {971--995}, TITLE = {Software for a cascade/parallel formant synthesizer}, VOLUME = {67}, NUMBER = {3}, MONTH = {March}, YEAR = 1980} (2) @Article{klatt1990, author = "Klatt,D.H. and Klatt, L.C.", title = "Analysis, synthesis and perception of voice quality variations among female and male talkers.", journal = "Journal of the Acoustical Society of America", year = "1990", volume = "87", number = "2", pages = "820--857", month = "February"} (3) Dr. David Williams at Sensimetrics Corporation, 64 Sidney Street, Cambridge, MA 02139. Fax: (617) 225-0470 Tel: (617) 225-2442 e-mail sensimetrics@sens.com */ /* djmw 20081019 first implementation. djmw 20081128 Parallel section: rnp filters dif(source)+frication instead of source only. djmw 20090708 +Table_to_KlattTable, KlattTable_to_Table djmw 20110308 Thing_new + struct KlattFrame -> struct structKlattFrame djmw 20110329 Table_get(Numeric|String)Value is now Table_get(Numeric|String)Value_Assert */ #include "KlattTable.h" #include "Resonator.h" Thing_implement (KlattTable, Table, 0); #define CASCADE_PARALLEL 1 /* Type of synthesis model */ #define ALL_PARALLEL 2 #define KlattTable_NPAR 40 /* Number of control parameters */ #define MAX_SAM 20000 /* Maximum sample rate */ #define IMPULSIVE 1 /* Type of voicing source */ #define NATURAL 2 #define SAMPLED 3 #define NUMBER_OF_SAMPLES 100 #define SAMPLE_FACTOR 0.00001 /* Structure for Klatt Parameters */ typedef struct structKlattFrame { long F0hz10; /* Voicing fund freq in units of 0.1 Hz */ long AVdb; /* Amp of voicing in dB, 0 to 70 */ long Fhz[9]; /* Formant freqs in Hz */ long Bhz[9]; /* bandwidths in Hz */ long Bphz[7]; /* Bandwidths, parallel branch */ long A[7]; /* Formant amplitudes parallel branch */ long FNZhz; /* Nasal zero freq in Hz, 248 to 528 */ long BNZhz; /* Nasal zero bw in Hz, 40 to 1000 */ long FNPhz; /* Nasal pole freq in Hz, 248 to 528 */ long BNPhz; /* Nasal pole bw in Hz, 40 to 1000 */ long ah; /* Amp of aspiration in dB, 0 to 70 */ long Kopen; /* # of samples in open period, 10 to 65 */ long Aturb; /* Breathiness in voicing, 0 to 80 */ long TLTdb; /* Voicing spectral tilt in dB, 0 to 24 */ long AF; /* Amp of frication in dB, 0 to 80 */ long Kskew; /* Skewness of alternate periods, 0 to 40 in sample#/2 */ long ANP; /* Amp of par nasal pole in dB, 0 to 80 */ long AB; /* Amp of bypass fric. in dB, 0 to 80 */ long AVpdb; /* Amp of voicing, par in dB, 0 to 70 */ long Gain0; /* Overall gain, 60 dB is unity, 0 to 60 */ } *KlattFrame; static const char32 *columnNames = U"f0 av f1 b1 f2 b2 f3 b3 f4 b4 f5 b5 f6 b6 fnz bnz fnp bnp ah kopen aturb tilt af skew a1 b1p a2 b2p a3 b3p a4 b4p a5 b5p a6 b6p anp ab avp gain"; static const char32 *columnNamesA[KlattTable_NPAR + 1] = {U"", U"f0", U"av", U"f1", U"b1", U"f2", U"b2", U"f3", U"b3", U"f4", U"b4", U"f5", U"b5", U"f6", U"b6", U"fnz", U"bnz", U"fnp", U"bnp", U"ah", U"kopen", U"aturb", U"tilt", U"af", U"skew", U"a1", U"b1p", U"a2", U"b2p", U"a3", U"b3p", U"a4", U"b4p", U"a5", U"b5p", U"a6", U"b6p", U"anp", U"ab", U"avp", U"gain"}; static double DBtoLIN (long dB) { static double amptable[88] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 13.0, 14.0, 16.0, 18.0, 20.0, 22.0, 25.0, 28.0, 32.0, 35.0, 40.0, 45.0, 51.0, 57.0, 64.0, 71.0, 80.0, 90.0, 101.0, 114.0, 128.0, 142.0, 159.0, 179.0, 202.0, 227.0, 256.0, 284.0, 318.0, 359.0, 405.0, 455.0, 512.0, 568.0, 638.0, 719.0, 811.0, 911.0, 1024.0, 1137.0, 1276.0, 1438.0, 1622.0, 1823.0, 2048.0, 2273.0, 2552.0, 2875.0, 3244.0, 3645.0, 4096.0, 4547.0, 5104.0, 5751.0, 6488.0, 7291.0, 8192.0, 9093.0, 10207.0, 11502.0, 12976.0, 14582.0, 16384.0, 18350.0, 20644.0, 23429.0, 26214.0, 29491.0, 32767 }; return (dB < 0) || (dB > 87) ? 0 : amptable[dB] * .001; } /* Structure for Klatt Globals */ typedef struct structKlattGlobal { int synthesis_model; /* cascade-parallel or all-parallel */ int outsl; /* Output waveform selector */ long samrate; /* Number of output samples per second */ long FLPhz ; /* Frequeny of glottal downsample low-pass filter */ long BLPhz ; /* Bandwidth of glottal downsample low-pass filter */ long nfcascade; /* Number of formants in cascade vocal tract */ int glsource; /* Type of glottal source */ int f0_flutter; /* Percentage of f0 flutter 0-100 */ long nspfr; /* number of samples per frame */ long nper; /* Counter for number of samples in a pitch period */ long ns; long T0; /* Fundamental period in output samples times 4 */ long nopen; /* Number of samples in open phase of period */ long nmod; /* Position in period to begin noise amp. modul */ long Kopen; /* # of samples in open period, 10 to 65 */ long Kskew; /* Skewness of alternate periods, 0 to 40 in sample#/2 */ double TLTdb; /* Voicing spectral tilt in dB, 0 to 24 */ long nrand; /* Varible used by random number generator */ double pulse_shape_a; /* Makes waveshape of glottal pulse when open */ double pulse_shape_b; /* Makes waveshape of glottal pulse when open */ double onemd; double decay; double amp_bypas; /* AB converted to linear gain */ double AVdb; /* Amp of voicing in dB, 0 to 70 */ double amp_voice; /* AVdb converted to linear gain */ double par_amp_voice; /* AVpdb converted to linear gain */ double amp_aspir; /* AP converted to linear gain */ double amp_frica; /* AF converted to linear gain */ double Aturb; /* Breathiness in voicing, 0 to 80 */ double amp_breth; /* ATURB converted to linear gain */ double amp_gain0; /* G0 converted to linear gain */ long num_samples; /* number of glottal samples */ double sample_factor; /* multiplication factor for glottal samples */ short *natural_samples; /* pointer to an array of glottal samples */ long F0hz10; /* Voicing fund freq in units of 0.1 Hz */ long original_f0; /* original value of f0 not modified by flutter (kanweg) */ autoResonator rp[7], rc[9], rnpp, rnpc, rgl, rlp, rout; autoAntiResonator rnz; } *KlattGlobal; autoKlattTable KlattTable_readFromRawTextFile (MelderFile fs) { try { autoMatrix thee = Matrix_readFromRawTextFile (fs); if (thy nx != KlattTable_NPAR) { Melder_throw (U"A KlattTable needs ", KlattTable_NPAR, U" columns."); } autoKlattTable me = Thing_new (KlattTable); Table_initWithColumnNames (me.peek(), thy ny, columnNames); for (long irow = 1; irow <= thy ny; irow++) { for (long jcol = 1; jcol <= KlattTable_NPAR; jcol++) { double val = thy z[irow][jcol]; if (jcol > 3 && jcol < 13 && (jcol % 2 == 0) && val <= 0) { // bw == 0? val = thy z[irow][jcol - 1] / 10; } Table_setNumericValue ( (Table) me.peek(), irow, jcol, val); } } return me; } catch (MelderError) { Melder_throw (U"KlattTable not read from file."); } } static void KlattGlobal_free (KlattGlobal me) { Melder_free (me); } static KlattGlobal KlattGlobal_create (double samplingFrequency) { KlattGlobal me = 0; try { me = (KlattGlobal) _Melder_calloc_f (1, sizeof (struct structKlattGlobal)); my samrate = (long) floor (samplingFrequency); double dT = 1.0 / my samrate; for (long i = 1; i <= 8; i++) { my rc[i] = Resonator_create (dT, Resonator_NORMALISATION_H0); if (i <= 6) { my rp[i] = Resonator_create (dT, Resonator_NORMALISATION_H0); } } my rnpp = Resonator_create (dT, Resonator_NORMALISATION_H0); my rnpc = Resonator_create (dT, Resonator_NORMALISATION_H0); my rgl = Resonator_create (dT, Resonator_NORMALISATION_H0); my rlp = Resonator_create (dT, Resonator_NORMALISATION_H0); my rout = Resonator_create (dT, Resonator_NORMALISATION_H0); my rnz = AntiResonator_create (dT); return me; } catch (MelderError) { KlattGlobal_free (me); Melder_throw (U"KlattGlobal not created."); } } static void KlattGlobal_init (KlattGlobal me, int synthesisModel, int numberOfFormants, int glottalSource, double frameDuration, long flutter, int outputType) { static short natural_samples[NUMBER_OF_SAMPLES] = { -310, -400, 530, 356, 224, 89, 23, -10, -58, -16, 461, 599, 536, 701, 770, 605, 497, 461, 560, 404, 110, 224, 131, 104, -97, 155, 278, -154, -1165, -598, 737, 125, -592, 41, 11, -247, -10, 65, 92, 80, -304, 71, 167, -1, 122, 233, 161, -43, 278, 479, 485, 407, 266, 650, 134, 80, 236, 68, 260, 269, 179, 53, 140, 275, 293, 296, 104, 257, 152, 311, 182, 263, 245, 125, 314, 140, 44, 203, 230, -235, -286, 23, 107, 92, -91, 38, 464, 443, 176, 98, -784, -2449, -1891, -1045, -1600, -1462, -1384, -1261, -949, -730 }; my nspfr = (long) floor (my samrate * frameDuration); /* average number of samples per frame */ my synthesis_model = synthesisModel; my nfcascade = numberOfFormants; my glsource = glottalSource; my natural_samples = natural_samples; my num_samples = NUMBER_OF_SAMPLES; my sample_factor = (float) SAMPLE_FACTOR; my outsl = outputType; my f0_flutter = flutter; my FLPhz = (long) floor (0.0950 * my samrate); // depends on samplingFrequency ???? my BLPhz = (long) floor (0.0630 * my samrate); Filter_setFB (my rlp.peek(), my FLPhz, my BLPhz); } static KlattFrame KlattFrame_create () { return Melder_malloc (structKlattFrame, 1); } static void KlattFrame_free (KlattFrame me) { Melder_free (me); } autoKlattTable KlattTable_create (double frameDuration, double totalDuration) { try { autoKlattTable me = (KlattTable) Thing_new (KlattTable); long nrows = (long) floor (totalDuration / frameDuration) + 1; Table_initWithColumnNames (me.peek(), nrows, columnNames); return me; } catch (MelderError) { Melder_throw (U"KlattTable not created."); } } //static void frame_init(KlattGlobal_ptr globals, KlattFrame_ptr frame) static void KlattGlobal_getFrame (KlattGlobal me, KlattFrame thee) { double amp_parF[7] = {0, 0.4, 0.15, 0.06, 0.04, 0.022, 0.03}; my F0hz10 = thy F0hz10; my original_f0 = my F0hz10 / 10; my Kopen = thy Kopen; my Kskew = thy Kskew; my TLTdb = thy TLTdb; my Aturb = thy Aturb; my AVdb = thy AVdb; my AVdb -= 7; if (my AVdb < 0) { my AVdb = 0; } my amp_aspir = DBtoLIN (thy ah) * 0.05; my amp_frica = DBtoLIN (thy AF) * 0.25; my par_amp_voice = DBtoLIN (thy AVpdb); double amp_parFNP = DBtoLIN (thy ANP) * 0.6; my amp_bypas = DBtoLIN (thy AB) * 0.05; thy Gain0 -= 3; if (thy Gain0 <= 0) { thy Gain0 = 57; } my amp_gain0 = DBtoLIN (thy Gain0); /* Set coefficients of variable cascade resonators */ for (long i = 8; i > 0; i--) { if (my nfcascade >= i) { Filter_setFB (my rc[i].peek(), thy Fhz[i], thy Bhz[i]); } } /* Set coefficients of nasal resonator and zero antiresonator */ Filter_setFB (my rnpc.peek(), thy FNPhz, thy BNPhz); Filter_setFB (my rnz.peek(), thy FNZhz, thy BNZhz); /* Set coefficients of parallel resonators, and amplitude of outputs */ for (long i = 1; i <= 6; i++) { Filter_setFB (my rp[i].peek(), thy Fhz[i], thy Bphz[i]); my rp[i] -> a *= amp_parF[i] * DBtoLIN (thy A[i]); } Filter_setFB (my rnpp.peek(), thy FNPhz, thy BNPhz); my rnpp -> a *= amp_parFNP; /* output low-pass filter */ Filter_setFB (my rout.peek(), 0, (long) (my samrate / 2)); } /* This function adds F0 flutter, as specified in: "Analysis, synthesis and perception of voice quality variations among female and male talkers" D.H. Klatt and L.C. Klatt JASA 87(2) February 1990. Flutter is added by applying a quasi-random element constructed from three slowly varying sine waves. */ static void KlattFrame_flutter (KlattGlobal me) { static long time_count = 0; double fla = (double) my f0_flutter / 50; double flb = (double) my original_f0 / 100; double flc = sin (2 * NUMpi * 12.7 * time_count); double fld = sin (2 * NUMpi * 7.1 * time_count); double fle = sin (2 * NUMpi * 4.7 * time_count); double delta_f0 = fla * flb * (flc + fld + fle) * 10; my F0hz10 += (long) delta_f0; time_count++; } /* Random number generator (return a number between -8191 and +8191) Noise spectrum is tilted down by soft low-pass filter having a pole near the origin in the z-plane, i.e. output = input + (0.75 * lastoutput) */ static double KlattGlobal_gen_noise (KlattGlobal me) { // ppgb: dit was een float; kan niet goed zijn static double nlast = 0; double noise; my nrand = ( (rand() % (int) ( ( (8191) + 1) - (-8191))) + (-8191)); noise = my nrand + (0.75 * nlast); nlast = noise; return noise; } /* Generate a low pass filtered train of impulses as an approximation of a natural excitation waveform. Low-pass filter the differentiated impulse with a critically-damped second-order filter, time constant proportional to Kopen. */ static double KlattGlobal_impulsive_source (KlattGlobal me) { // ppgb: dit was een float; kan niet goed zijn static double doublet[] = {0.0, 13000000.0, -13000000.0}; static double vwave; vwave = my nper < 3 ? doublet[my nper] : 0; return Filter_getOutput (my rgl.peek(), vwave); } /* Vwave is the differentiated glottal flow waveform, there is a weak spectral zero around 800 Hz, magic constants a,b reset pitch synchronously. */ static double KlattGlobal_natural_source (KlattGlobal me) { // ppgb: dit was een float; kan niet goed zijn static double vwave = 0; double lgtemp = 0; if (my nper < my nopen) { my pulse_shape_a -= my pulse_shape_b; vwave += my pulse_shape_a; lgtemp = vwave * 0.028; } else { vwave = 0.0; } return lgtemp; } /* Allows the use of a glottal excitation waveform sampled from a real voice. */ static double KlattGlobal_sampled_source (KlattGlobal me) { // ppgb: dit was een float; kan niet goed zijn double result = 0; if (my T0 != 0) { double ftemp = my nper; ftemp *= my num_samples / my T0; long itemp = (long) floor (ftemp); double temp_diff = ftemp - itemp; long current_value = my natural_samples[itemp]; long next_value = my natural_samples[itemp + 1]; double diff_value = next_value - current_value; diff_value = diff_value * temp_diff; result = my natural_samples[itemp] + diff_value; result = result * my sample_factor; } return result; } /* Reset selected parameters pitch-synchronously. Constant B0 controls shape of glottal pulse as a function of desired duration of open phase N0 (Note that N0 is specified in terms of 40,000 samples/sec of speech) Assume voicing waveform V(t) has form: k1 t**2 - k2 t**3 If the radiation characterivative, a temporal derivative is folded in, and we go from continuous time to discrete integers n: dV/dt = vwave[n] = sum over i=1,2,...,n of { a - (i * b) } = a n - b/2 n**2 where the constants a and b control the detailed shape and amplitude of the voicing waveform over the open portion of the voicing cycle "nopen". Let integral of dV/dt have no net dc flow --> a = (b * nopen) / 3 Let maximum of dUg(n)/dn be constant --> b = gain / (nopen * nopen) meaning as nopen gets bigger, V has bigger peak proportional to n Thus, to generate the table below for 40 <= nopen <= 263: B0[nopen - 40] = 1920000 / (nopen * nopen) Modified calculation by djmw 20081127 Given a and b as above (which are wrong, see below) V'[n]= b*N/3*n - b/2*n^2. V'[N]=b/3*N^2-b/2*N^2=b/6*N^2 Given the table B0 for N=40, b=1200 and V'[N]=1200/6*(40)^2=320000 Also b=G/N^2 then V'[n]=-G/6 (=1920000/6=320000)! (We have not implemented the following correct calculations in the code) N=nopen dV/dt = vwave[n]=sum(i=1, n, a-i*b) = a*n-b*1/2*n*(n+1)=(a-b/2)*n-b/2 * n^2 (Here they forgot that sum(i=1,N,i)=1/2*n*(n+1) ! ) We want the sum(i=1,N, dV/dt[n])==0, therefore (a-b/2)*1/2*N*(N+1)-b*1/2*1/6*N*(N+1)*(2*N+1)==0. It follows that (a-b/2) - b*1/6*(2*N+1)==0 => a = b*(N+2)/3 we can rewrite with only b: V'[n] = b/2 {(2N+1)/3*n - n^2} The maximum of V'[n] is where (2N+1)/3-2n==0 => for n=(2N+1)/6 This maximum is b/2{(2N+1)/3*(2N+1)/(2*3)-((2N+1)/(2*3))^2} = 1/72*b*(2N+1)^2 The minimum is at n=N and equals V'[N]=b/6 {N-N^2}. This minimum has larger amplitude than the maximum. b = 6*gain/(N^2-N), b approx 6*gain/N^2. With a maximum gain of 32767 we arrive at b= 196602 / (N^2-N) Their value is 20*log10(1920000/196602) = 19.79 dB too high! The noise is in the range [-8192,8192], */ static void KlattGlobal_pitch_synch_par_reset (KlattGlobal me) { static long skew; static short B0[224] = { 1200, 1142, 1088, 1038, 991, 948, 907, 869, 833, 799, 768, 738, 710, 683, 658, 634, 612, 590, 570, 551, 533, 515, 499, 483, 468, 454, 440, 427, 415, 403, 391, 380, 370, 360, 350, 341, 332, 323, 315, 307, 300, 292, 285, 278, 272, 265, 259, 253, 247, 242, 237, 231, 226, 221, 217, 212, 208, 204, 199, 195, 192, 188, 184, 180, 177, 174, 170, 167, 164, 161, 158, 155, 153, 150, 147, 145, 142, 140, 137, 135, 133, 131, 128, 126, 124, 122, 120, 119, 117, 115, 113, 111, 110, 108, 106, 105, 103, 102, 100, 99, 97, 96, 95, 93, 92, 91, 90, 88, 87, 86, 85, 84, 83, 82, 80, 79, 78, 77, 76, 75, 75, 74, 73, 72, 71, 70, 69, 68, 68, 67, 66, 65, 64, 64, 63, 62, 61, 61, 60, 59, 59, 58, 57, 57, 56, 56, 55, 55, 54, 54, 53, 53, 52, 52, 51, 51, 50, 50, 49, 49, 48, 48, 47, 47, 46, 46, 45, 45, 44, 44, 43, 43, 42, 42, 41, 41, 41, 41, 40, 40, 39, 39, 38, 38, 38, 38, 37, 37, 36, 36, 36, 36, 35, 35, 35, 35, 34, 34, 33, 33, 33, 33, 32, 32, 32, 32, 31, 31, 31, 31, 30, 30, 30, 30, 29, 29, 29, 29, 28, 28, 28, 28, 27, 27 }; if (my F0hz10 > 0) { /* T0 is 4* the number of samples in one pitch period */ my T0 = (40 * my samrate) / my F0hz10; my amp_voice = DBtoLIN ((long) floor (my AVdb)); /* Duration of period before amplitude modulation */ my nmod = my T0; if (my AVdb > 0) { my nmod >>= 1; } /* Breathiness of voicing waveform */ my amp_breth = DBtoLIN ((long) floor (my Aturb)) * 0.1; /* Set open phase of glottal period where 40 <= open phase <= 263 */ my nopen = 4 * my Kopen; if ( (my glsource == IMPULSIVE) && (my nopen > 263)) { my nopen = 263; } if (my nopen >= (my T0 - 1)) { my nopen = my T0 - 2; Melder_warning (U"Glottal open period cannot exceed T0, truncated"); } if (my nopen < 40) { /* F0 max = 1000 Hz */ my nopen = 40; Melder_warning (U"Warning: minimum glottal open period is 10 samples.\n" U"truncated, nopen = ", my nopen); } /* Reset a & b, which determine shape of "natural" glottal waveform */ my pulse_shape_b = B0[my nopen - 40]; my pulse_shape_a = (my pulse_shape_b * my nopen) * 0.333; /* Reset width of "impulsive" glottal pulse */ long temp = my samrate / my nopen; Filter_setFB (my rgl.peek(), 0, temp); // Only used for impulsive source. /* Make gain at F1 about constant */ double temp1 = my nopen * 0.00833; my rgl -> a *= temp1 * temp1; /* Truncate skewness so as not to exceed duration of closed phase of glottal period. */ temp = my T0 - my nopen; if (my Kskew > temp) { Melder_information (U"Kskew duration=", my Kskew, U" > glottal closed period=", my T0 - my nopen, U" truncate"); my Kskew = temp; } if (skew >= 0) { skew = my Kskew; } else { skew = - my Kskew; } /* Add skewness to closed portion of voicing period */ my T0 = my T0 + skew; skew = - skew; } else { my T0 = 4; /* Default for f0 undefined */ my amp_voice = 0.0; my nmod = my T0; my amp_breth = 0.0; my pulse_shape_a = 0.0; my pulse_shape_b = 0.0; } /* Reset these pars pitch synchronously or at update rate if f0=0 */ if ( (my T0 != 4) || (my ns == 0)) { /* Set one-pole low-pass filter that tilts glottal source */ my decay = (0.033 * my TLTdb); my onemd = my decay > 0.0 ? 1.0 - my decay : 1; } } // This is Klatt80 with improved source model. static void KlattGlobal_synthesizeFrame (KlattGlobal me, short *output) { double out, frics, glotout, aspiration, par_glotout, noise, sourc, voice = 0; static double vlast = 0, glotlast = 0; KlattFrame_flutter (me); /* MAIN LOOP, for each output sample of current frame: */ for (my ns = 0; my ns < my nspfr; my ns++) { /* Get low-passed random number for aspiration and frication noise */ noise = KlattGlobal_gen_noise (me); /* Amplitude modulate noise (reduce noise amplitude during second half of glottal period) if voicing simultaneously present. */ if (my nper > my nmod) { noise *= 0.5; } /* Compute frication noise */ frics = my amp_frica * noise; /* Compute voicing waveform. Run glottal source simulation at 4 times normal sample rate to minimize quantization noise in period of female voice. */ for (long n4 = 0; n4 < 4; n4++) { switch (my glsource) { case IMPULSIVE: voice = KlattGlobal_impulsive_source (me); break; case NATURAL: voice = KlattGlobal_natural_source (me); break; case SAMPLED: voice = KlattGlobal_sampled_source (me); break; } /* Reset period when counter 'nper' reaches T0 */ if (my nper >= my T0) { my nper = 0; KlattGlobal_pitch_synch_par_reset (me); } /* Low-pass filter voicing waveform before downsampling from 4*samrate to samrate samples/sec. Resonator f=.09*samrate, bw=.06*samrate */ voice = Filter_getOutput (my rlp.peek(), voice); /* Increment counter that keeps track of 4*samrate samples per sec */ my nper++; } /* Tilt spectrum of voicing source down by soft low-pass filtering, amount of tilt determined by TLTdb */ voice = (voice * my onemd) + (vlast * my decay); vlast = voice; /* Add breathiness during glottal open phase. Amount of breathiness determined by parameter Aturb Use nrand rather than noise because noise is low-passed. */ if (my nper < my nopen) { voice += my amp_breth * my nrand; } /* Set voicing amplitude */ glotout = my amp_voice * voice; par_glotout = my par_amp_voice * voice; /* Compute aspiration amplitude and add to voicing source */ aspiration = my amp_aspir * noise; glotout += aspiration; par_glotout += aspiration; /* Cascade vocal tract, excited by laryngeal sources. Nasal antiresonator, then formants FNP, F5, F4, F3, F2, F1 */ if (my synthesis_model != ALL_PARALLEL) { out = Filter_getOutput (my rnz.peek(), glotout); /* anti resonator */ out = Filter_getOutput (my rnpc.peek(), out); for (long i = 8; i > 0; i--) { if (my nfcascade >= i) { out = Filter_getOutput (my rc[i].peek(), out); } } } else { /* we are not using the cascade tract, set out to zero */ out = 0; } /* Excite parallel F1 and FNP by voicing waveform */ sourc = par_glotout; /* Source is voicing plus aspiration */ /* Standard parallel vocal tract Formants F6,F5,F4,F3,F2, outputs added with alternating sign. Sound sourc for other parallel resonators is frication plus first difference of voicing waveform. In Klatt80: source: through r1, diff(source)+frication: through filters rnp, r2, r3, r4 frication: through r5, r6 and ab. In the original code of Iles and Ing it was source: through r1 and rnp diff(source)+frication: r2, r3, r4 , r5, r6, ab Problem: The source signal is already v'[n], and we are differentiating here again ??? */ out += Filter_getOutput (my rp[1].peek(), sourc); sourc = frics + par_glotout - glotlast; // diff glotlast = par_glotout; out += Filter_getOutput (my rnpp.peek(), sourc); for (long i = 6; i >= 2; i--) { if (my nfcascade >= i) { out = Filter_getOutput (my rp[i].peek(), sourc) - out; } } double outbypas = my amp_bypas * sourc; out = outbypas - out; if (my outsl != 0) { switch (my outsl) { case 1: out = voice; break; case 2: out = aspiration; break; case 3: out = frics; break; case 4: out = glotout; break; case 5: out = par_glotout; break; case 6: out = outbypas; break; case 7: out = sourc; break; } } out = Filter_getOutput (my rout.peek(), out); double temp = out * my amp_gain0; /* Convert back to integer */ if (temp < -32768.0) { temp = -32768.0; } if (temp > 32767.0) { temp = 32767.0; } *output++ = temp; // ppgb: truncatie naar 0, dus compressie; is dat de bedoeling? } } static int KlattTable_checkLimits (KlattTable me) { long nviolations_upper[KlattTable_NPAR + 1] = { 0 }, nviolations_lower[KlattTable_NPAR + 1] = { 0 }; long lower[KlattTable_NPAR + 1] = { 0, // dummy 10, 0, // f0, av 200, 40, 550, 40, 1200, 40, 1200, 40, 1200, 40, 1200, 40, // f1,b1 -- f6,b6 248, 40, 248, 40, // fnz, bnz, fnp, bnp 0, 0, 0, 0, 0, 0, // ah, kopen, aturb, tilt, af, skew 0, 40, 0, 40, 0, 40, 0, 40, 0, 40, 0, 40, // a1,b1p -- a6,b6p 0, 0, 0, 0 // anp, ab, avp, gain }; long upper[KlattTable_NPAR + 1] = { 0, // dummy 10000, 70, // f0, av 1300, 1000, 3000, 1000, 4999, 1000, 4999, 1000, 6999, 1000, 7000, 1000, // f1,b1 -- f6,b6 528, 1000, 528, 1000, // fnz, bnz, fnp, bnp 70, 60, 80, 24, 80, 40, // ah, kopen, aturb, tilt, af, skew 80, 1000, 80, 1000, 80, 1000, 80, 1000, 80, 1000, 80, 1000, // a1,b1p -- a6,b6p 80, 80, 70, 80 // anp, ab, avp, gain }; long nv = 0; for (long irow = 1; irow <= my rows -> size; irow++) { for (long j = 1; j <= KlattTable_NPAR; j++) { long val = Table_getNumericValue_Assert ( (Table) me, irow, j); // ppgb: truncatie? kan dat kloppen? if (val < lower[j]) { nviolations_lower[j]++; nv++; } else if (val > upper[j]) { nviolations_upper[j]++; nv++; } } } if (nv > 0) { MelderInfo_open (); MelderInfo_writeLine (U"Diagnostics for KlattTable \"", Thing_getName (me), U"\":"); MelderInfo_writeLine (U"Number of frames: ", my rows -> size); for (long j = 1; j <= KlattTable_NPAR; j++) { if (nviolations_lower[j] > 0) { if (nviolations_upper[j] > 0) { MelderInfo_writeLine (columnNamesA[j], U": ", nviolations_lower[j], U" frame(s) < min = ", nviolations_lower[j], U"; ", nviolations_upper[j], U" frame(s) > max = ", upper[j]); } else { MelderInfo_writeLine (columnNamesA[j], U": ", nviolations_lower[j], U" frame(s) < min = ", lower[j]); } } else if (nviolations_upper[j] > 0) { MelderInfo_writeLine (columnNamesA[j], U": ", nviolations_upper[j], U" frame(s) > max = ", upper[j]); } } MelderInfo_close (); return 0; } return 1; } autoSound KlattTable_to_Sound (KlattTable me, double samplingFrequency, int synthesisModel, int numberOfFormants, double frameDuration, int glottalSource, double flutter, int outputType) { KlattGlobal thee = 0; KlattFrame frame = 0; try { long numberOfSamples = 1, par[KlattTable_NPAR + 1]; if (! KlattTable_checkLimits (me)) { Melder_warning (U"Some values in the KlattTable are outside the limits, the resulting sound may sound weird."); } thee = KlattGlobal_create (samplingFrequency); frame = KlattFrame_create (); autoNUMvector iwave (0L, MAX_SAM); thy samrate = (long) floor (samplingFrequency); KlattGlobal_init (thee, synthesisModel, numberOfFormants, glottalSource, frameDuration, (long) floor (flutter), outputType); autoSound him = Sound_createSimple (1, frameDuration * my rows -> size, samplingFrequency); for (long irow = 1 ; irow <= my rows -> size; irow++) { for (long col = 1; col <= KlattTable_NPAR; col++) { par[col] = Table_getNumericValue_Assert ( (Table) me, irow, col); // ppgb: truncatie? } long jcol = 1; frame -> F0hz10 = par[jcol++]; frame -> AVdb = par[jcol++]; frame -> Fhz[1] = par[jcol++]; frame -> Bhz[1] = par[jcol++]; frame -> Fhz[2] = par[jcol++]; frame -> Bhz[2] = par[jcol++]; frame -> Fhz[3] = par[jcol++]; frame -> Bhz[3] = par[jcol++]; frame -> Fhz[4] = par[jcol++]; frame -> Bhz[4] = par[jcol++]; frame -> Fhz[5] = par[jcol++]; frame -> Bhz[5] = par[jcol++]; frame -> Fhz[6] = par[jcol++]; frame -> Bhz[6] = par[jcol++]; frame -> FNZhz = par[jcol++]; frame -> BNZhz = par[jcol++]; frame -> FNPhz = par[jcol++]; frame -> BNPhz = par[jcol++]; frame -> ah = par[jcol++]; frame -> Kopen = par[jcol++]; frame -> Aturb = par[jcol++]; frame -> TLTdb = par[jcol++]; frame -> AF = par[jcol++]; frame -> Kskew = par[jcol++]; frame -> A[1] = par[jcol++]; frame -> Bphz[1] = par[jcol++]; frame -> A[2] = par[jcol++]; frame -> Bphz[2] = par[jcol++]; frame -> A[3] = par[jcol++]; frame -> Bphz[3] = par[jcol++]; frame -> A[4] = par[jcol++]; frame -> Bphz[4] = par[jcol++]; frame -> A[5] = par[jcol++]; frame -> Bphz[5] = par[jcol++]; frame -> A[6] = par[jcol++]; frame -> Bphz[6] = par[jcol++]; frame -> ANP = par[jcol++]; frame -> AB = par[jcol++]; frame -> AVpdb = par[jcol++]; frame -> Gain0 = par[jcol++];; frame -> Fhz[7] = 6500; frame -> Bhz[7] = 600; frame -> Fhz[8] = 7500; frame -> Bhz[8] = 600; KlattGlobal_getFrame (thee, frame); KlattGlobal_synthesizeFrame (thee, iwave.peek()); for (long isam = 0; isam < thy nspfr; isam++) { his z[1][numberOfSamples++] = iwave[isam] / 32768.0; } } KlattGlobal_free (thee); KlattFrame_free (frame); return him; } catch (MelderError) { KlattGlobal_free (thee); KlattFrame_free (frame); Melder_throw (me, U": no Sound created."); } } autoKlattTable KlattTable_createExample () { long nrows = 1376; struct klatt_params { short p[40]; } klatt_data [1376] = { {{ 1000, 0, 542, 0, 1372, 0, 2634, 0, 3737, 0, 5740, 0, 6914, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 52, 0, 56, 0, 71, 0, 66, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1000, 0, 542, 0, 1372, 0, 2634, 0, 3737, 0, 5740, 0, 6914, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 52, 0, 56, 0, 71, 0, 66, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1010, 0, 542, 0, 1372, 0, 2634, 0, 3737, 0, 5740, 0, 6914, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 52, 0, 56, 0, 71, 0, 66, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1020, 0, 542, 0, 1372, 0, 2634, 0, 3737, 0, 5740, 0, 6914, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 52, 0, 56, 0, 71, 0, 66, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1030, 0, 542, 0, 1372, 0, 2634, 0, 3737, 0, 5740, 0, 6914, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 52, 0, 56, 0, 71, 0, 66, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1040, 0, 542, 0, 1372, 0, 2634, 0, 3737, 0, 5740, 0, 6914, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 52, 0, 56, 0, 71, 0, 66, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1050, 0, 542, 0, 1372, 0, 2634, 0, 3737, 0, 5740, 0, 6914, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 52, 0, 56, 0, 71, 0, 66, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1060, 0, 542, 0, 1372, 0, 2634, 0, 3737, 0, 5740, 0, 6914, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 52, 0, 56, 0, 71, 0, 66, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1070, 0, 542, 0, 1372, 0, 2634, 0, 3737, 0, 5740, 0, 6914, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 52, 0, 56, 0, 71, 0, 66, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1080, 0, 542, 0, 1372, 0, 2634, 0, 3737, 0, 5740, 0, 6914, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 52, 0, 56, 0, 71, 0, 66, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1090, 0, 542, 0, 1372, 0, 2634, 0, 3737, 0, 5740, 0, 6914, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 52, 0, 56, 0, 71, 0, 66, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1100, 0, 542, 0, 1372, 0, 2634, 0, 3737, 0, 5740, 0, 6914, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 52, 0, 56, 0, 71, 0, 66, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1110, 0, 542, 0, 1372, 0, 2634, 0, 3737, 0, 5740, 0, 6914, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 52, 0, 56, 0, 71, 0, 66, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1120, 0, 542, 0, 1372, 0, 2634, 0, 3737, 0, 5740, 0, 6914, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 52, 0, 56, 0, 71, 0, 66, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1130, 0, 542, 0, 1372, 0, 2634, 0, 3737, 0, 5740, 0, 6914, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 52, 0, 56, 0, 71, 0, 66, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1140, 0, 542, 0, 1372, 0, 2634, 0, 3737, 0, 5740, 0, 6914, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 52, 0, 56, 0, 71, 0, 66, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1150, 0, 542, 0, 1372, 0, 2634, 0, 3737, 0, 5740, 0, 6914, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 52, 0, 56, 0, 71, 0, 66, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1160, 0, 542, 0, 1372, 0, 2634, 0, 3737, 0, 5740, 0, 6914, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 52, 0, 56, 0, 71, 0, 66, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1170, 0, 542, 0, 1372, 0, 2634, 0, 3737, 0, 5740, 0, 6914, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 52, 0, 56, 0, 71, 0, 66, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1180, 0, 542, 0, 1372, 0, 2634, 0, 3737, 0, 5740, 0, 6914, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 52, 0, 56, 0, 71, 0, 66, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1190, 0, 506, 0, 752, 0, 3029, 0, 3545, 0, 6301, 0, 7523, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 37, 41, 73, 79, 56, 108, 53, 65, 43, 80, 37, 80, 0, 0, 28, 60 }}, {{ 1200, 0, 506, 0, 752, 0, 3029, 0, 3545, 0, 6301, 0, 7523, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 37, 41, 73, 79, 56, 108, 53, 65, 43, 80, 37, 80, 0, 0, 31, 60 }}, {{ 1207, 0, 506, 0, 752, 0, 3029, 0, 3545, 0, 6301, 0, 7523, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 37, 41, 73, 79, 56, 108, 53, 65, 43, 80, 37, 80, 0, 0, 34, 60 }}, {{ 1214, 0, 506, 0, 752, 0, 3029, 0, 3545, 0, 6301, 0, 7523, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 37, 41, 73, 79, 56, 108, 53, 65, 43, 80, 37, 80, 0, 0, 36, 60 }}, {{ 1221, 0, 506, 0, 752, 0, 3029, 0, 3545, 0, 6301, 0, 7523, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 37, 41, 73, 79, 56, 108, 53, 65, 43, 80, 37, 80, 0, 0, 39, 60 }}, {{ 1228, 0, 506, 0, 752, 0, 3029, 0, 3545, 0, 6301, 0, 7523, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 37, 41, 73, 79, 56, 108, 53, 65, 43, 80, 37, 80, 0, 0, 42, 60 }}, {{ 1234, 0, 506, 0, 752, 0, 3029, 0, 3545, 0, 6301, 0, 7523, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 37, 41, 73, 79, 56, 108, 53, 65, 43, 80, 37, 80, 0, 0, 42, 60 }}, {{ 1241, 0, 506, 0, 752, 0, 3029, 0, 3545, 0, 6301, 0, 7523, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 37, 41, 73, 79, 56, 108, 53, 65, 43, 80, 37, 80, 0, 0, 42, 60 }}, {{ 1248, 0, 506, 0, 752, 0, 3029, 0, 3545, 0, 6301, 0, 7523, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 37, 41, 73, 79, 56, 108, 53, 65, 43, 80, 37, 80, 0, 0, 42, 60 }}, {{ 1255, 0, 506, 0, 752, 0, 3029, 0, 3545, 0, 6301, 0, 7523, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 37, 41, 73, 79, 56, 108, 53, 65, 43, 80, 37, 80, 0, 0, 42, 60 }}, {{ 1262, 0, 510, 0, 765, 0, 3006, 0, 3547, 0, 6283, 0, 7484, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 37, 42, 72, 78, 56, 106, 53, 65, 43, 80, 37, 80, 0, 0, 42, 60 }}, {{ 1269, 0, 518, 0, 792, 0, 2961, 0, 3552, 0, 6248, 0, 7407, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 38, 43, 71, 75, 56, 102, 53, 64, 43, 80, 37, 80, 0, 0, 44, 60 }}, {{ 1276, 0, 530, 0, 833, 0, 2899, 0, 3560, 0, 6197, 0, 7302, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 39, 45, 70, 71, 56, 98, 52, 63, 43, 80, 38, 80, 0, 0, 45, 60 }}, {{ 1282, 0, 543, 0, 892, 0, 2825, 0, 3572, 0, 6132, 0, 7176, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 41, 47, 67, 66, 55, 92, 51, 62, 43, 80, 38, 80, 0, 0, 46, 60 }}, {{ 1289, 0, 556, 0, 969, 0, 2749, 0, 3592, 0, 6055, 0, 7046, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 42, 50, 65, 62, 55, 86, 50, 61, 43, 80, 39, 80, 0, 0, 48, 60 }}, {{ 1296, 0, 567, 0, 1068, 0, 2680, 0, 3622, 0, 5969, 0, 6926, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 43, 52, 62, 58, 55, 81, 50, 61, 44, 80, 39, 80, 0, 0, 50, 60 }}, {{ 1303, 0, 573, 0, 1156, 0, 2642, 0, 3651, 0, 5903, 0, 6858, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 54, 61, 57, 56, 78, 50, 63, 44, 80, 39, 80, 0, 0, 51, 60 }}, {{ 1310, 0, 576, 0, 1230, 0, 2624, 0, 3677, 0, 5854, 0, 6823, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 55, 59, 56, 56, 76, 50, 64, 44, 80, 39, 80, 0, 0, 52, 60 }}, {{ 1322, 0, 576, 0, 1287, 0, 2617, 0, 3699, 0, 5819, 0, 6809, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 55, 59, 57, 56, 76, 50, 66, 44, 80, 39, 80, 0, 0, 54, 60 }}, {{ 1335, 0, 576, 0, 1326, 0, 2616, 0, 3714, 0, 5797, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 55, 58, 57, 57, 75, 50, 67, 44, 80, 39, 80, 0, 0, 56, 60 }}, {{ 1348, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 0, 0, 57, 60 }}, {{ 1360, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 0, 0, 58, 60 }}, {{ 1372, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1385, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 1, 0, 60, 60 }}, {{ 1398, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 3, 0, 59, 60 }}, {{ 1410, 0, 585, 0, 1342, 0, 2619, 0, 3715, 0, 5810, 0, 6804, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 59, 58, 57, 79, 50, 68, 44, 80, 39, 80, 4, 0, 58, 60 }}, {{ 1422, 0, 603, 0, 1337, 0, 2628, 0, 3706, 0, 5849, 0, 6803, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 55, 60, 61, 58, 85, 51, 67, 44, 80, 40, 80, 6, 0, 56, 60 }}, {{ 1435, 0, 624, 0, 1341, 0, 2649, 0, 3705, 0, 5883, 0, 6805, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 51, 61, 65, 60, 95, 52, 65, 45, 80, 40, 80, 9, 0, 54, 60 }}, {{ 1448, 0, 643, 0, 1367, 0, 2692, 0, 3727, 0, 5885, 0, 6814, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 62, 72, 62, 110, 54, 61, 47, 80, 39, 80, 12, 0, 51, 60 }}, {{ 1460, 0, 650, 0, 1417, 0, 2754, 0, 3776, 0, 5837, 0, 6833, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 80, 65, 125, 56, 56, 49, 80, 39, 80, 16, 0, 49, 60 }}, {{ 1460, 0, 649, 0, 1470, 0, 2811, 0, 3830, 0, 5769, 0, 6852, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 87, 68, 137, 58, 51, 52, 80, 38, 80, 19, 0, 47, 60 }}, {{ 1460, 0, 644, 0, 1513, 0, 2855, 0, 3874, 0, 5707, 0, 6867, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 92, 70, 145, 60, 47, 54, 80, 37, 80, 23, 0, 46, 60 }}, {{ 1460, 0, 641, 0, 1537, 0, 2879, 0, 3899, 0, 5672, 0, 6876, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 94, 71, 149, 60, 45, 55, 80, 37, 80, 26, 0, 45, 60 }}, {{ 1460, 0, 641, 0, 1537, 0, 2879, 0, 3899, 0, 5672, 0, 6876, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 94, 71, 149, 60, 45, 55, 80, 37, 80, 29, 0, 45, 60 }}, {{ 1460, 0, 640, 0, 1543, 0, 2885, 0, 3905, 0, 5663, 0, 6878, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 95, 71, 150, 61, 44, 56, 80, 37, 80, 31, 0, 45, 60 }}, {{ 1460, 0, 640, 0, 1543, 0, 2885, 0, 3905, 0, 5663, 0, 6878, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 95, 71, 150, 61, 44, 56, 80, 37, 80, 32, 0, 45, 60 }}, {{ 1460, 0, 640, 0, 1543, 0, 2885, 0, 3905, 0, 5663, 0, 6878, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 95, 71, 150, 61, 44, 56, 80, 37, 80, 34, 0, 45, 60 }}, {{ 1460, 0, 640, 0, 1543, 0, 2885, 0, 3905, 0, 5663, 0, 6878, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 95, 71, 150, 61, 44, 56, 80, 37, 80, 35, 0, 45, 60 }}, {{ 1460, 0, 640, 0, 1543, 0, 2885, 0, 3905, 0, 5663, 0, 6878, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 95, 71, 150, 61, 44, 56, 80, 37, 80, 35, 0, 45, 60 }}, {{ 1460, 0, 640, 0, 1543, 0, 2885, 0, 3905, 0, 5663, 0, 6878, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 95, 71, 150, 61, 44, 56, 80, 37, 80, 35, 0, 45, 60 }}, {{ 1460, 0, 640, 0, 1540, 0, 2882, 0, 3903, 0, 5668, 0, 6876, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 94, 71, 149, 61, 45, 55, 80, 37, 80, 35, 0, 45, 60 }}, {{ 1460, 0, 641, 0, 1532, 0, 2876, 0, 3899, 0, 5677, 0, 6872, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 94, 70, 148, 60, 45, 55, 80, 37, 80, 35, 0, 45, 60 }}, {{ 1460, 0, 642, 0, 1522, 0, 2868, 0, 3894, 0, 5691, 0, 6867, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 92, 70, 146, 60, 46, 55, 80, 37, 80, 35, 0, 45, 60 }}, {{ 1460, 0, 643, 0, 1509, 0, 2856, 0, 3886, 0, 5709, 0, 6861, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 91, 69, 143, 60, 47, 54, 80, 37, 80, 35, 0, 45, 60 }}, {{ 1460, 0, 644, 0, 1493, 0, 2843, 0, 3877, 0, 5730, 0, 6855, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 89, 69, 140, 59, 48, 53, 80, 38, 80, 35, 0, 45, 60 }}, {{ 1460, 0, 644, 0, 1477, 0, 2827, 0, 3866, 0, 5753, 0, 6849, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 87, 68, 136, 59, 50, 52, 80, 38, 80, 35, 0, 45, 60 }}, {{ 1460, 0, 643, 0, 1461, 0, 2809, 0, 3853, 0, 5779, 0, 6846, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 84, 67, 132, 58, 51, 51, 80, 38, 80, 35, 0, 45, 60 }}, {{ 1460, 0, 641, 0, 1447, 0, 2789, 0, 3839, 0, 5804, 0, 6846, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 62, 81, 66, 127, 57, 53, 50, 80, 39, 80, 35, 0, 45, 60 }}, {{ 1460, 0, 636, 0, 1435, 0, 2769, 0, 3824, 0, 5829, 0, 6850, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 62, 79, 65, 121, 57, 55, 49, 80, 39, 80, 35, 0, 45, 60 }}, {{ 1460, 0, 629, 0, 1428, 0, 2747, 0, 3808, 0, 5852, 0, 6860, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 61, 76, 64, 116, 56, 57, 48, 80, 39, 80, 35, 0, 45, 60 }}, {{ 1460, 0, 618, 0, 1428, 0, 2725, 0, 3791, 0, 5870, 0, 6879, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 61, 73, 63, 110, 55, 58, 47, 80, 39, 80, 35, 0, 45, 60 }}, {{ 1460, 0, 603, 0, 1436, 0, 2703, 0, 3773, 0, 5884, 0, 6908, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 60, 70, 62, 103, 55, 60, 47, 80, 39, 80, 35, 0, 45, 60 }}, {{ 1460, 0, 583, 0, 1454, 0, 2682, 0, 3755, 0, 5890, 0, 6950, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 561, 0, 1481, 0, 2665, 0, 3740, 0, 5888, 0, 6997, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 538, 0, 1513, 0, 2651, 0, 3726, 0, 5879, 0, 7049, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 514, 0, 1548, 0, 2640, 0, 3715, 0, 5866, 0, 7102, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 491, 0, 1586, 0, 2632, 0, 3705, 0, 5849, 0, 7155, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 468, 0, 1623, 0, 2625, 0, 3697, 0, 5831, 0, 7206, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 448, 0, 1659, 0, 2620, 0, 3690, 0, 5813, 0, 7254, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 429, 0, 1692, 0, 2617, 0, 3684, 0, 5795, 0, 7298, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 413, 0, 1722, 0, 2614, 0, 3680, 0, 5778, 0, 7336, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 399, 0, 1746, 0, 2612, 0, 3676, 0, 5764, 0, 7368, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 389, 0, 1765, 0, 2611, 0, 3674, 0, 5753, 0, 7392, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 382, 0, 1779, 0, 2610, 0, 3672, 0, 5746, 0, 7409, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 46, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 45, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 35, 0, 0, 60 }}, {{ 1460, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 43, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 0, 0, 56, 60 }}, {{ 1460, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 0, 0, 58, 60 }}, {{ 1460, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1460, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1460, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1460, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1460, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1460, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1460, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1460, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1460, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1460, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1460, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1460, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1460, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1460, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1460, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1460, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1460, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1460, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1460, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1460, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1460, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1460, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1460, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 72, 60, 0, 0, 0, 0, 0, 100, 50, 100, 50, 100, 50, 100, 35, 100, 0, 100, 0, 0, 0, 60 }}, {{ 1460, 0, 304, 0, 1265, 0, 2343, 0, 3343, 0, 6085, 0, 7150, 0, 0, 0, 200, 30, 72, 60, 0, 0, 0, 0, 0, 100, 50, 100, 50, 100, 50, 100, 35, 100, 0, 100, 0, 0, 0, 60 }}, {{ 1460, 0, 384, 0, 1107, 0, 2418, 0, 3392, 0, 6038, 0, 7106, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 100, 50, 100, 50, 100, 50, 100, 35, 100, 0, 100, 0, 0, 0, 60 }}, {{ 1460, 0, 491, 0, 864, 0, 2707, 0, 3511, 0, 6110, 0, 7147, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 100, 50, 100, 50, 100, 50, 100, 35, 100, 0, 100, 0, 0, 0, 60 }}, {{ 1475, 0, 518, 0, 779, 0, 2921, 0, 3582, 0, 6230, 0, 7231, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 100, 50, 100, 50, 100, 50, 100, 35, 100, 0, 100, 0, 0, 0, 60 }}, {{ 1490, 0, 518, 0, 779, 0, 2921, 0, 3582, 0, 6230, 0, 7231, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 100, 50, 100, 50, 100, 50, 100, 35, 100, 0, 100, 0, 0, 0, 60 }}, {{ 1505, 0, 518, 0, 779, 0, 2921, 0, 3582, 0, 6230, 0, 7231, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 48, 68, 63, 53, 87, 50, 61, 42, 80, 38, 80, 0, 0, 58, 60 }}, {{ 1520, 0, 518, 0, 779, 0, 2921, 0, 3582, 0, 6230, 0, 7231, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 48, 68, 63, 53, 87, 50, 61, 42, 80, 38, 80, 0, 0, 58, 60 }}, {{ 1519, 0, 518, 0, 779, 0, 2921, 0, 3582, 0, 6230, 0, 7231, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 48, 68, 63, 53, 87, 50, 61, 42, 80, 38, 80, 0, 0, 59, 60 }}, {{ 1517, 0, 518, 0, 779, 0, 2921, 0, 3582, 0, 6230, 0, 7231, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 48, 68, 63, 53, 87, 50, 61, 42, 80, 38, 80, 0, 0, 60, 60 }}, {{ 1516, 0, 518, 0, 779, 0, 2921, 0, 3582, 0, 6230, 0, 7231, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 48, 68, 63, 53, 87, 50, 61, 42, 80, 38, 80, 0, 0, 60, 60 }}, {{ 1514, 0, 518, 0, 779, 0, 2921, 0, 3582, 0, 6230, 0, 7231, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 48, 68, 63, 53, 87, 50, 61, 42, 80, 38, 80, 0, 0, 60, 60 }}, {{ 1513, 0, 518, 0, 779, 0, 2921, 0, 3582, 0, 6230, 0, 7231, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 48, 68, 63, 53, 87, 50, 61, 42, 80, 38, 80, 0, 0, 60, 60 }}, {{ 1511, 0, 518, 0, 779, 0, 2921, 0, 3582, 0, 6230, 0, 7231, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 48, 68, 63, 53, 87, 50, 61, 42, 80, 38, 80, 1, 0, 60, 60 }}, {{ 1510, 0, 518, 0, 779, 0, 2921, 0, 3582, 0, 6230, 0, 7231, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 48, 68, 63, 53, 87, 50, 61, 42, 80, 38, 80, 2, 0, 60, 60 }}, {{ 1509, 0, 518, 0, 779, 0, 2921, 0, 3582, 0, 6230, 0, 7231, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 48, 68, 63, 53, 87, 50, 61, 42, 80, 38, 80, 5, 0, 59, 60 }}, {{ 1507, 0, 540, 0, 841, 0, 2890, 0, 3588, 0, 6186, 0, 7205, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 47, 68, 66, 55, 93, 51, 62, 43, 80, 38, 80, 8, 0, 56, 60 }}, {{ 1506, 0, 578, 0, 984, 0, 2848, 0, 3623, 0, 6083, 0, 7144, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 40, 42, 68, 73, 58, 105, 53, 62, 45, 80, 39, 80, 12, 0, 53, 60 }}, {{ 1504, 0, 619, 0, 1239, 0, 2836, 0, 3731, 0, 5894, 0, 7026, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 39, 28, 66, 84, 64, 126, 57, 57, 49, 80, 38, 80, 17, 0, 49, 60 }}, {{ 1503, 0, 635, 0, 1436, 0, 2862, 0, 3840, 0, 5745, 0, 6931, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 38, 13, 64, 91, 68, 142, 59, 49, 53, 80, 37, 80, 22, 0, 47, 60 }}, {{ 1501, 0, 640, 0, 1543, 0, 2885, 0, 3905, 0, 5663, 0, 6878, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 95, 71, 150, 61, 44, 56, 80, 37, 80, 27, 0, 45, 60 }}, {{ 1500, 0, 640, 0, 1543, 0, 2885, 0, 3905, 0, 5663, 0, 6878, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 95, 71, 150, 61, 44, 56, 80, 37, 80, 30, 0, 45, 60 }}, {{ 1497, 0, 640, 0, 1543, 0, 2885, 0, 3905, 0, 5663, 0, 6878, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 95, 71, 150, 61, 44, 56, 80, 37, 80, 32, 0, 45, 60 }}, {{ 1493, 0, 640, 0, 1543, 0, 2885, 0, 3905, 0, 5663, 0, 6878, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 95, 71, 150, 61, 44, 56, 80, 37, 80, 34, 0, 45, 60 }}, {{ 1490, 0, 640, 0, 1543, 0, 2885, 0, 3905, 0, 5663, 0, 6878, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 95, 71, 150, 61, 44, 56, 80, 37, 80, 35, 0, 45, 60 }}, {{ 1487, 0, 640, 0, 1543, 0, 2885, 0, 3905, 0, 5663, 0, 6878, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 95, 71, 150, 61, 44, 56, 80, 37, 80, 35, 0, 45, 60 }}, {{ 1483, 0, 642, 0, 1530, 0, 2871, 0, 3891, 0, 5683, 0, 6873, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 93, 70, 148, 60, 46, 55, 80, 37, 80, 35, 0, 45, 60 }}, {{ 1480, 0, 645, 0, 1504, 0, 2845, 0, 3864, 0, 5722, 0, 6864, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 91, 69, 143, 59, 48, 54, 80, 37, 80, 35, 0, 45, 60 }}, {{ 1477, 0, 649, 0, 1468, 0, 2809, 0, 3827, 0, 5772, 0, 6851, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 86, 68, 136, 58, 51, 52, 80, 38, 80, 35, 0, 46, 60 }}, {{ 1473, 0, 650, 0, 1427, 0, 2765, 0, 3786, 0, 5825, 0, 6836, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 81, 66, 127, 57, 55, 50, 80, 39, 80, 35, 0, 49, 60 }}, {{ 1470, 0, 647, 0, 1387, 0, 2718, 0, 3746, 0, 5870, 0, 6822, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 75, 63, 117, 55, 59, 48, 80, 39, 80, 35, 0, 52, 60 }}, {{ 1467, 0, 637, 0, 1354, 0, 2673, 0, 3715, 0, 5890, 0, 6810, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 62, 69, 61, 104, 53, 63, 46, 80, 40, 80, 35, 0, 56, 60 }}, {{ 1463, 0, 622, 0, 1339, 0, 2646, 0, 3704, 0, 5880, 0, 6804, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 52, 61, 65, 59, 94, 52, 66, 45, 80, 40, 80, 0, 0, 58, 60 }}, {{ 1460, 0, 606, 0, 1337, 0, 2630, 0, 3705, 0, 5854, 0, 6803, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 54, 60, 61, 58, 86, 51, 67, 44, 80, 40, 80, 0, 0, 60, 60 }}, {{ 1455, 0, 592, 0, 1339, 0, 2622, 0, 3711, 0, 5825, 0, 6804, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 55, 59, 59, 57, 81, 51, 67, 44, 80, 40, 80, 0, 0, 60, 60 }}, {{ 1450, 0, 581, 0, 1344, 0, 2618, 0, 3718, 0, 5800, 0, 6805, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 58, 57, 77, 50, 68, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1445, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1440, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1435, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1430, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1425, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1420, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1415, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 0, 0, 54, 60 }}, {{ 1410, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 0, 0, 54, 60 }}, {{ 1405, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1400, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1383, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1367, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1350, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1333, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1317, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1283, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1267, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1250, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1233, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 56, 0, 57, 0, 75, 0, 68, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1217, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 64, 60, 0, 0, 0, 0, 0, 100, 50, 100, 50, 100, 65, 100, 75, 100, 65, 100, 0, 0, 0, 60 }}, {{ 1200, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 64, 60, 0, 0, 0, 0, 0, 100, 50, 100, 50, 100, 65, 100, 75, 100, 65, 100, 0, 0, 0, 60 }}, {{ 1150, 0, 517, 0, 2038, 0, 2845, 0, 3850, 0, 5703, 0, 7608, 0, 0, 0, 200, 30, 0, 60, 0, 0, 45, 0, 0, 100, 50, 100, 60, 100, 65, 100, 70, 100, 55, 100, 0, 0, 0, 60 }}, {{ 1100, 0, 528, 0, 1991, 0, 2822, 0, 3840, 0, 5691, 0, 7551, 0, 0, 0, 200, 30, 0, 60, 0, 0, 45, 0, 0, 100, 50, 100, 60, 100, 65, 100, 70, 100, 55, 100, 0, 0, 0, 60 }}, {{ 1090, 0, 543, 0, 1921, 0, 2791, 0, 3827, 0, 5674, 0, 7470, 0, 0, 0, 200, 30, 0, 60, 0, 0, 45, 0, 0, 100, 50, 100, 60, 100, 65, 100, 70, 100, 55, 100, 0, 0, 0, 60 }}, {{ 1080, 0, 562, 0, 1831, 0, 2757, 0, 3812, 0, 5655, 0, 7370, 0, 0, 0, 200, 30, 0, 60, 0, 0, 45, 0, 0, 100, 50, 100, 60, 100, 65, 100, 70, 100, 55, 100, 0, 0, 0, 60 }}, {{ 1070, 0, 583, 0, 1720, 0, 2724, 0, 3796, 0, 5637, 0, 7260, 0, 0, 0, 200, 30, 0, 60, 0, 0, 45, 0, 0, 100, 50, 100, 60, 100, 65, 100, 70, 100, 55, 100, 0, 0, 0, 60 }}, {{ 1060, 0, 605, 0, 1592, 0, 2701, 0, 3782, 0, 5621, 0, 7149, 0, 0, 0, 200, 30, 0, 60, 0, 0, 45, 0, 0, 100, 50, 100, 60, 100, 65, 100, 70, 100, 55, 100, 0, 0, 0, 60 }}, {{ 1050, 0, 624, 0, 1450, 0, 2696, 0, 3773, 0, 5612, 0, 7048, 0, 0, 0, 200, 30, 0, 60, 0, 0, 45, 0, 0, 100, 50, 100, 60, 100, 65, 100, 70, 100, 55, 100, 0, 0, 0, 60 }}, {{ 1040, 0, 637, 0, 1332, 0, 2711, 0, 3772, 0, 5613, 0, 6986, 0, 0, 0, 200, 30, 0, 60, 0, 0, 45, 0, 0, 100, 50, 100, 60, 100, 65, 100, 70, 100, 55, 100, 0, 0, 0, 60 }}, {{ 1030, 0, 644, 0, 1239, 0, 2736, 0, 3774, 0, 5619, 0, 6952, 0, 0, 0, 200, 30, 0, 60, 0, 0, 45, 0, 0, 100, 50, 100, 60, 100, 65, 100, 70, 100, 55, 100, 0, 0, 0, 60 }}, {{ 1020, 0, 648, 0, 1166, 0, 2765, 0, 3779, 0, 5628, 0, 6936, 0, 0, 0, 200, 30, 0, 60, 0, 0, 42, 0, 0, 100, 50, 100, 60, 100, 65, 100, 70, 100, 55, 100, 0, 0, 0, 60 }}, {{ 1010, 0, 650, 0, 1113, 0, 2791, 0, 3785, 0, 5637, 0, 6931, 0, 0, 0, 200, 30, 0, 60, 0, 0, 35, 0, 0, 100, 50, 100, 60, 100, 65, 100, 70, 100, 55, 100, 0, 0, 0, 60 }}, {{ 1000, 0, 651, 0, 1078, 0, 2811, 0, 3789, 0, 5644, 0, 6931, 0, 0, 0, 200, 30, 0, 60, 0, 0, 32, 0, 0, 100, 50, 100, 60, 100, 65, 100, 70, 100, 55, 100, 0, 0, 0, 60 }}, {{ 990, 0, 651, 0, 1061, 0, 2822, 0, 3791, 0, 5648, 0, 6932, 0, 0, 0, 200, 30, 0, 60, 0, 0, 32, 0, 0, 100, 50, 100, 60, 100, 65, 100, 70, 100, 55, 100, 0, 0, 0, 60 }}, {{ 980, 0, 651, 0, 1061, 0, 2822, 0, 3791, 0, 5648, 0, 6932, 0, 0, 0, 200, 30, 0, 60, 0, 0, 45, 0, 0, 100, 50, 100, 60, 100, 65, 100, 70, 100, 55, 100, 0, 0, 0, 60 }}, {{ 970, 0, 651, 0, 1061, 0, 2822, 0, 3791, 0, 5648, 0, 6932, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 46, 44, 59, 52, 55, 68, 52, 64, 45, 80, 41, 80, 0, 0, 57, 60 }}, {{ 960, 0, 651, 0, 1061, 0, 2822, 0, 3791, 0, 5648, 0, 6932, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 46, 44, 59, 52, 55, 68, 52, 64, 45, 80, 41, 80, 0, 0, 58, 60 }}, {{ 958, 0, 651, 0, 1061, 0, 2822, 0, 3791, 0, 5648, 0, 6932, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 46, 44, 59, 52, 55, 68, 52, 64, 45, 80, 41, 80, 0, 0, 58, 60 }}, {{ 957, 0, 651, 0, 1061, 0, 2822, 0, 3791, 0, 5648, 0, 6932, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 46, 44, 59, 52, 55, 68, 52, 64, 45, 80, 41, 80, 0, 0, 59, 60 }}, {{ 955, 0, 651, 0, 1061, 0, 2822, 0, 3791, 0, 5648, 0, 6932, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 46, 44, 59, 52, 55, 68, 52, 64, 45, 80, 41, 80, 0, 0, 59, 60 }}, {{ 953, 0, 651, 0, 1061, 0, 2822, 0, 3791, 0, 5648, 0, 6932, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 46, 44, 59, 52, 55, 68, 52, 64, 45, 80, 41, 80, 0, 0, 60, 60 }}, {{ 952, 0, 651, 0, 1061, 0, 2822, 0, 3791, 0, 5648, 0, 6932, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 46, 44, 59, 52, 55, 68, 52, 64, 45, 80, 41, 80, 0, 0, 60, 60 }}, {{ 950, 0, 651, 0, 1061, 0, 2822, 0, 3791, 0, 5648, 0, 6932, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 46, 44, 59, 52, 55, 68, 52, 64, 45, 80, 41, 80, 0, 0, 60, 60 }}, {{ 948, 0, 651, 0, 1061, 0, 2822, 0, 3791, 0, 5648, 0, 6932, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 46, 44, 59, 52, 55, 68, 52, 64, 45, 80, 41, 80, 0, 0, 60, 60 }}, {{ 947, 0, 651, 0, 1061, 0, 2822, 0, 3791, 0, 5648, 0, 6932, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 46, 44, 59, 52, 55, 68, 52, 64, 45, 80, 41, 80, 0, 0, 60, 60 }}, {{ 945, 0, 651, 0, 1061, 0, 2822, 0, 3791, 0, 5648, 0, 6932, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 46, 44, 59, 52, 55, 68, 52, 64, 45, 80, 41, 80, 0, 0, 60, 60 }}, {{ 943, 0, 651, 0, 1061, 0, 2822, 0, 3791, 0, 5648, 0, 6932, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 46, 44, 59, 52, 55, 68, 52, 64, 45, 80, 41, 80, 0, 0, 60, 60 }}, {{ 942, 0, 650, 0, 1068, 0, 2817, 0, 3790, 0, 5651, 0, 6931, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 46, 44, 59, 52, 55, 68, 52, 64, 45, 80, 41, 80, 0, 0, 60, 60 }}, {{ 940, 0, 647, 0, 1082, 0, 2808, 0, 3788, 0, 5658, 0, 6930, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 46, 44, 59, 53, 55, 69, 52, 64, 45, 80, 41, 80, 0, 0, 60, 60 }}, {{ 938, 0, 644, 0, 1102, 0, 2794, 0, 3785, 0, 5667, 0, 6929, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 46, 45, 58, 53, 56, 69, 52, 65, 45, 80, 41, 80, 0, 0, 60, 60 }}, {{ 937, 0, 639, 0, 1130, 0, 2777, 0, 3782, 0, 5678, 0, 6928, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 46, 46, 58, 53, 56, 70, 52, 65, 45, 80, 41, 80, 0, 0, 60, 60 }}, {{ 935, 0, 632, 0, 1166, 0, 2757, 0, 3778, 0, 5692, 0, 6928, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 46, 46, 58, 54, 56, 72, 52, 65, 44, 80, 41, 80, 0, 0, 60, 60 }}, {{ 933, 0, 623, 0, 1209, 0, 2735, 0, 3773, 0, 5708, 0, 6929, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 46, 47, 58, 55, 56, 73, 52, 66, 44, 80, 40, 80, 0, 0, 60, 60 }}, {{ 932, 0, 612, 0, 1260, 0, 2713, 0, 3769, 0, 5725, 0, 6933, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 45, 48, 58, 56, 57, 74, 52, 67, 44, 80, 40, 80, 0, 0, 60, 60 }}, {{ 930, 0, 597, 0, 1321, 0, 2691, 0, 3764, 0, 5743, 0, 6941, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 45, 49, 58, 58, 57, 76, 52, 67, 44, 80, 40, 80, 0, 0, 60, 60 }}, {{ 928, 0, 580, 0, 1390, 0, 2672, 0, 3761, 0, 5761, 0, 6953, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 57, 59, 58, 78, 52, 68, 45, 80, 39, 80, 0, 0, 60, 60 }}, {{ 927, 0, 559, 0, 1470, 0, 2656, 0, 3758, 0, 5778, 0, 6972, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 51, 57, 61, 58, 80, 53, 69, 45, 80, 39, 80, 0, 0, 60, 60 }}, {{ 925, 0, 533, 0, 1560, 0, 2647, 0, 3757, 0, 5792, 0, 6998, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 52, 57, 64, 59, 81, 53, 70, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 923, 0, 502, 0, 1662, 0, 2646, 0, 3757, 0, 5805, 0, 7033, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 52, 56, 67, 60, 83, 53, 70, 45, 80, 37, 80, 0, 0, 60, 60 }}, {{ 922, 0, 471, 0, 1758, 0, 2654, 0, 3760, 0, 5812, 0, 7071, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 40, 52, 56, 70, 61, 85, 54, 71, 46, 80, 36, 80, 0, 0, 60, 60 }}, {{ 920, 0, 440, 0, 1848, 0, 2668, 0, 3764, 0, 5816, 0, 7112, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 39, 52, 55, 73, 62, 86, 54, 72, 46, 80, 36, 80, 0, 0, 60, 60 }}, {{ 919, 0, 411, 0, 1930, 0, 2686, 0, 3768, 0, 5816, 0, 7152, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 38, 52, 55, 76, 63, 87, 55, 72, 47, 80, 35, 80, 0, 0, 60, 60 }}, {{ 918, 0, 384, 0, 2006, 0, 2706, 0, 3773, 0, 5815, 0, 7192, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 37, 52, 55, 79, 64, 87, 55, 73, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 916, 0, 359, 0, 2073, 0, 2728, 0, 3778, 0, 5812, 0, 7229, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 36, 51, 54, 81, 64, 88, 56, 73, 48, 80, 34, 80, 0, 0, 60, 60 }}, {{ 915, 0, 337, 0, 2131, 0, 2749, 0, 3784, 0, 5808, 0, 7262, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 35, 51, 54, 83, 65, 88, 56, 73, 48, 80, 33, 80, 0, 0, 60, 60 }}, {{ 914, 0, 318, 0, 2181, 0, 2768, 0, 3788, 0, 5804, 0, 7292, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 50, 54, 85, 66, 88, 57, 73, 49, 80, 33, 80, 0, 0, 60, 60 }}, {{ 912, 0, 302, 0, 2220, 0, 2785, 0, 3792, 0, 5801, 0, 7316, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 33, 50, 54, 87, 66, 89, 57, 74, 49, 80, 32, 80, 0, 0, 60, 60 }}, {{ 911, 0, 290, 0, 2251, 0, 2798, 0, 3795, 0, 5798, 0, 7335, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 33, 49, 54, 88, 66, 89, 57, 74, 49, 80, 32, 80, 0, 0, 60, 60 }}, {{ 910, 0, 282, 0, 2271, 0, 2807, 0, 3797, 0, 5796, 0, 7348, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 32, 49, 54, 89, 67, 89, 57, 74, 49, 80, 32, 80, 0, 0, 60, 60 }}, {{ 909, 0, 278, 0, 2281, 0, 2812, 0, 3799, 0, 5795, 0, 7354, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 32, 49, 53, 89, 67, 89, 57, 74, 50, 80, 32, 80, 0, 0, 60, 60 }}, {{ 908, 0, 278, 0, 2281, 0, 2812, 0, 3799, 0, 5795, 0, 7354, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 32, 49, 53, 89, 67, 89, 57, 74, 50, 80, 32, 80, 0, 0, 60, 60 }}, {{ 906, 0, 278, 0, 2281, 0, 2812, 0, 3799, 0, 5795, 0, 7354, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 32, 49, 53, 89, 67, 89, 57, 74, 50, 80, 32, 80, 0, 0, 60, 60 }}, {{ 905, 0, 278, 0, 2281, 0, 2812, 0, 3799, 0, 5795, 0, 7354, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 32, 49, 53, 89, 67, 89, 57, 74, 50, 80, 32, 80, 1, 0, 60, 60 }}, {{ 904, 0, 278, 0, 2281, 0, 2812, 0, 3799, 0, 5795, 0, 7354, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 32, 49, 53, 89, 67, 89, 57, 74, 50, 80, 32, 80, 2, 0, 60, 60 }}, {{ 902, 0, 278, 0, 2281, 0, 2812, 0, 3799, 0, 5795, 0, 7354, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 32, 49, 53, 89, 67, 89, 57, 74, 50, 80, 32, 80, 3, 0, 60, 60 }}, {{ 901, 0, 278, 0, 2281, 0, 2812, 0, 3799, 0, 5795, 0, 7354, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 32, 49, 53, 89, 67, 89, 57, 74, 50, 80, 32, 80, 5, 0, 60, 60 }}, {{ 900, 0, 278, 0, 2281, 0, 2812, 0, 3799, 0, 5795, 0, 7354, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 32, 49, 53, 89, 67, 89, 57, 74, 50, 80, 32, 80, 7, 0, 59, 60 }}, {{ 899, 0, 284, 0, 2238, 0, 2783, 0, 3772, 0, 5820, 0, 7318, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 33, 49, 53, 87, 66, 90, 57, 72, 49, 80, 32, 80, 9, 0, 57, 60 }}, {{ 898, 0, 294, 0, 2148, 0, 2732, 0, 3724, 0, 5864, 0, 7253, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 35, 50, 53, 82, 65, 93, 57, 69, 48, 80, 33, 80, 12, 0, 55, 60 }}, {{ 896, 0, 308, 0, 2006, 0, 2673, 0, 3661, 0, 5910, 0, 7171, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 38, 52, 52, 75, 63, 95, 56, 65, 46, 80, 34, 80, 15, 0, 53, 60 }}, {{ 895, 0, 325, 0, 1801, 0, 2629, 0, 3595, 0, 5935, 0, 7095, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 40, 55, 53, 67, 61, 96, 56, 60, 44, 80, 35, 80, 18, 0, 50, 60 }}, {{ 894, 0, 337, 0, 1579, 0, 2623, 0, 3549, 0, 5918, 0, 7055, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 60, 54, 62, 60, 93, 55, 57, 43, 80, 37, 80, 21, 0, 48, 60 }}, {{ 892, 0, 345, 0, 1402, 0, 2644, 0, 3529, 0, 5877, 0, 7049, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 64, 55, 58, 59, 90, 55, 56, 42, 80, 38, 80, 23, 0, 47, 60 }}, {{ 891, 0, 348, 0, 1279, 0, 2670, 0, 3522, 0, 5837, 0, 7056, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 56, 57, 58, 86, 55, 56, 41, 80, 39, 80, 25, 0, 46, 60 }}, {{ 890, 0, 350, 0, 1216, 0, 2687, 0, 3520, 0, 5813, 0, 7063, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 56, 56, 58, 84, 55, 56, 41, 80, 39, 80, 27, 0, 45, 60 }}, {{ 894, 0, 350, 0, 1216, 0, 2687, 0, 3520, 0, 5813, 0, 7063, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 56, 56, 58, 84, 55, 56, 41, 80, 39, 80, 28, 0, 45, 60 }}, {{ 897, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 29, 0, 45, 60 }}, {{ 901, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 30, 0, 45, 60 }}, {{ 904, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 30, 0, 45, 60 }}, {{ 908, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 30, 0, 45, 60 }}, {{ 911, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 30, 0, 45, 60 }}, {{ 915, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 30, 0, 45, 60 }}, {{ 919, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 30, 0, 45, 60 }}, {{ 922, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 30, 0, 45, 60 }}, {{ 926, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 30, 0, 45, 60 }}, {{ 929, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 30, 0, 45, 60 }}, {{ 933, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 30, 0, 45, 60 }}, {{ 936, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 30, 0, 45, 60 }}, {{ 940, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 941, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 942, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 943, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 944, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 945, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 946, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 947, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 948, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 949, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 950, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 951, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 952, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 953, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 954, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 955, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 956, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 957, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 958, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 959, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 960, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 961, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 962, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 963, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 964, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 965, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 966, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 967, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 968, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 969, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 970, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 971, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 972, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 973, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 974, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 975, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 976, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 977, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 978, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 0, 60 }}, {{ 979, 0, 350, 0, 1200, 0, 2691, 0, 3520, 0, 5807, 0, 7065, 0, 0, 0, 200, 30, 0, 60, 0, 0, 38, 0, 0, 50, 57, 56, 58, 83, 55, 56, 41, 80, 39, 80, 0, 0, 43, 60 }}, {{ 980, 0, 471, 0, 1524, 0, 2823, 0, 3809, 0, 5731, 0, 6964, 0, 0, 0, 200, 30, 0, 60, 0, 0, 45, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 51, 60 }}, {{ 989, 0, 471, 0, 1524, 0, 2823, 0, 3809, 0, 5731, 0, 6964, 0, 0, 0, 200, 30, 0, 60, 0, 0, 45, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 51, 60 }}, {{ 998, 0, 471, 0, 1524, 0, 2823, 0, 3809, 0, 5731, 0, 6964, 0, 0, 0, 200, 30, 0, 60, 0, 0, 45, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 51, 60 }}, {{ 1006, 0, 481, 0, 1539, 0, 2809, 0, 3806, 0, 5770, 0, 6975, 0, 0, 0, 200, 30, 0, 60, 0, 0, 34, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 51, 60 }}, {{ 1015, 0, 500, 0, 1570, 0, 2785, 0, 3803, 0, 5839, 0, 6997, 0, 0, 0, 200, 30, 0, 60, 0, 0, 11, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 52, 60 }}, {{ 1024, 0, 528, 0, 1617, 0, 2761, 0, 3805, 0, 5917, 0, 7031, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 54, 60 }}, {{ 1032, 0, 566, 0, 1680, 0, 2752, 0, 3819, 0, 5978, 0, 7080, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 55, 60 }}, {{ 1041, 0, 602, 0, 1744, 0, 2770, 0, 3846, 0, 5988, 0, 7130, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 47, 59, 78, 64, 111, 57, 71, 46, 80, 38, 80, 0, 0, 57, 60 }}, {{ 1050, 0, 630, 0, 1793, 0, 2800, 0, 3875, 0, 5962, 0, 7170, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 48, 59, 80, 64, 112, 58, 80, 45, 80, 38, 80, 0, 0, 59, 60 }}, {{ 1048, 0, 648, 0, 1825, 0, 2828, 0, 3898, 0, 5928, 0, 7198, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 49, 59, 82, 65, 114, 58, 88, 44, 80, 39, 80, 0, 0, 59, 60 }}, {{ 1046, 0, 657, 0, 1842, 0, 2844, 0, 3911, 0, 5907, 0, 7212, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 49, 60, 83, 65, 115, 58, 92, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1044, 0, 657, 0, 1842, 0, 2844, 0, 3911, 0, 5907, 0, 7212, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 49, 60, 83, 65, 115, 58, 92, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1042, 0, 647, 0, 1829, 0, 2837, 0, 3911, 0, 5885, 0, 7175, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 59, 82, 65, 113, 58, 91, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1040, 0, 624, 0, 1796, 0, 2809, 0, 3897, 0, 5855, 0, 7101, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 52, 59, 79, 64, 108, 57, 87, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1038, 0, 591, 0, 1751, 0, 2751, 0, 3857, 0, 5818, 0, 7004, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 54, 58, 75, 63, 100, 55, 82, 45, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1036, 0, 552, 0, 1698, 0, 2646, 0, 3769, 0, 5783, 0, 6904, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 55, 57, 70, 61, 90, 53, 75, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 1034, 0, 511, 0, 1643, 0, 2469, 0, 3603, 0, 5762, 0, 6825, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 56, 57, 64, 59, 77, 51, 67, 46, 80, 37, 80, 0, 0, 60, 60 }}, {{ 1032, 0, 483, 0, 1607, 0, 2292, 0, 3425, 0, 5763, 0, 6798, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 54, 57, 59, 56, 67, 49, 60, 46, 80, 36, 80, 0, 0, 60, 60 }}, {{ 1030, 0, 466, 0, 1586, 0, 2138, 0, 3266, 0, 5775, 0, 6799, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 53, 57, 56, 54, 60, 47, 55, 47, 80, 35, 80, 0, 0, 60, 60 }}, {{ 1026, 0, 456, 0, 1574, 0, 2025, 0, 3147, 0, 5788, 0, 6810, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 51, 58, 54, 52, 55, 46, 52, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1022, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1018, 0, 457, 0, 1544, 0, 1983, 0, 3092, 0, 5812, 0, 6824, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 54, 46, 51, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1014, 0, 466, 0, 1494, 0, 2019, 0, 3109, 0, 5845, 0, 6838, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 59, 53, 51, 58, 46, 52, 46, 80, 35, 80, 0, 0, 58, 60 }}, {{ 1010, 0, 479, 0, 1421, 0, 2078, 0, 3137, 0, 5892, 0, 6864, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 60, 54, 51, 64, 46, 54, 45, 80, 35, 80, 0, 0, 57, 60 }}, {{ 1006, 0, 494, 0, 1325, 0, 2168, 0, 3178, 0, 5954, 0, 6910, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 61, 56, 52, 71, 47, 56, 44, 80, 35, 80, 0, 0, 56, 60 }}, {{ 1002, 0, 507, 0, 1208, 0, 2296, 0, 3235, 0, 6028, 0, 6986, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 49, 63, 58, 52, 79, 48, 58, 44, 80, 36, 80, 0, 0, 54, 60 }}, {{ 998, 0, 516, 0, 1072, 0, 2473, 0, 3312, 0, 6112, 0, 7103, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 47, 66, 63, 53, 88, 49, 60, 43, 80, 36, 80, 0, 0, 52, 60 }}, {{ 994, 0, 518, 0, 962, 0, 2641, 0, 3383, 0, 6178, 0, 7223, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 41, 46, 68, 67, 54, 95, 50, 62, 43, 80, 37, 80, 0, 0, 51, 60 }}, {{ 990, 0, 516, 0, 876, 0, 2787, 0, 3445, 0, 6229, 0, 7334, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 39, 44, 70, 72, 55, 101, 52, 63, 43, 80, 37, 80, 0, 0, 50, 60 }}, {{ 995, 0, 512, 0, 820, 0, 2892, 0, 3488, 0, 6261, 0, 7414, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 38, 43, 71, 75, 56, 104, 52, 64, 43, 80, 37, 80, 0, 0, 48, 60 }}, {{ 1000, 0, 513, 0, 834, 0, 2865, 0, 3477, 0, 6253, 0, 7394, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 38, 43, 71, 74, 55, 103, 52, 64, 43, 80, 37, 80, 0, 0, 47, 60 }}, {{ 1005, 0, 515, 0, 855, 0, 2827, 0, 3461, 0, 6241, 0, 7364, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 39, 43, 71, 73, 55, 102, 52, 64, 43, 80, 37, 80, 0, 0, 48, 60 }}, {{ 1010, 0, 516, 0, 883, 0, 2776, 0, 3440, 0, 6225, 0, 7325, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 39, 44, 70, 71, 55, 100, 51, 63, 43, 80, 37, 80, 0, 0, 49, 60 }}, {{ 1015, 0, 517, 0, 918, 0, 2714, 0, 3414, 0, 6204, 0, 7278, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 40, 45, 69, 70, 54, 98, 51, 63, 43, 80, 37, 80, 0, 0, 49, 60 }}, {{ 1020, 0, 518, 0, 960, 0, 2643, 0, 3384, 0, 6179, 0, 7225, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 41, 46, 68, 67, 54, 95, 50, 62, 43, 80, 37, 80, 0, 0, 50, 60 }}, {{ 1025, 0, 518, 0, 1011, 0, 2563, 0, 3350, 0, 6149, 0, 7167, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 41, 47, 67, 65, 54, 92, 50, 61, 43, 80, 37, 80, 0, 0, 51, 60 }}, {{ 1030, 0, 516, 0, 1069, 0, 2477, 0, 3313, 0, 6113, 0, 7106, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 42, 47, 66, 63, 53, 88, 49, 60, 43, 80, 36, 80, 0, 0, 51, 60 }}, {{ 1035, 0, 513, 0, 1136, 0, 2386, 0, 3274, 0, 6072, 0, 7044, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 43, 48, 65, 61, 53, 84, 48, 59, 43, 80, 36, 80, 0, 0, 52, 60 }}, {{ 1040, 0, 507, 0, 1211, 0, 2292, 0, 3233, 0, 6026, 0, 6983, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 43, 49, 63, 58, 52, 79, 48, 58, 44, 80, 36, 80, 0, 0, 53, 60 }}, {{ 1045, 0, 499, 0, 1280, 0, 2214, 0, 3198, 0, 5982, 0, 6936, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 50, 62, 57, 52, 74, 47, 56, 44, 80, 36, 80, 0, 0, 53, 60 }}, {{ 1050, 0, 491, 0, 1343, 0, 2150, 0, 3170, 0, 5942, 0, 6900, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 61, 55, 52, 69, 47, 55, 45, 80, 35, 80, 0, 0, 54, 60 }}, {{ 1052, 0, 483, 0, 1398, 0, 2098, 0, 3146, 0, 5907, 0, 6874, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 60, 54, 51, 65, 46, 54, 45, 80, 35, 80, 0, 0, 55, 60 }}, {{ 1055, 0, 475, 0, 1446, 0, 2057, 0, 3127, 0, 5876, 0, 6854, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 59, 54, 51, 62, 46, 53, 46, 80, 35, 80, 0, 0, 55, 60 }}, {{ 1058, 0, 468, 0, 1487, 0, 2025, 0, 3112, 0, 5850, 0, 6840, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 59, 53, 51, 59, 46, 52, 46, 80, 35, 80, 0, 0, 56, 60 }}, {{ 1060, 0, 462, 0, 1519, 0, 2000, 0, 3100, 0, 5828, 0, 6831, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 56, 46, 52, 46, 80, 34, 80, 0, 0, 57, 60 }}, {{ 1062, 0, 457, 0, 1544, 0, 1983, 0, 3092, 0, 5812, 0, 6824, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 54, 46, 51, 47, 80, 34, 80, 0, 0, 57, 60 }}, {{ 1065, 0, 453, 0, 1560, 0, 1971, 0, 3087, 0, 5801, 0, 6821, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 53, 45, 51, 47, 80, 34, 80, 0, 0, 58, 60 }}, {{ 1068, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 59, 60 }}, {{ 1070, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 59, 60 }}, {{ 1072, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 52, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1075, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 52, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 56, 60 }}, {{ 1078, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 52, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 53, 60 }}, {{ 1080, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 52, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 49, 60 }}, {{ 1082, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 52, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 46, 60 }}, {{ 1085, 0, 451, 0, 1570, 0, 2013, 0, 3118, 0, 5791, 0, 6824, 0, 0, 0, 200, 30, 52, 60, 0, 0, 0, 0, 43, 50, 58, 54, 52, 57, 46, 52, 46, 80, 34, 80, 0, 0, 42, 60 }}, {{ 1088, 0, 450, 0, 1573, 0, 2105, 0, 3185, 0, 5782, 0, 6835, 0, 0, 0, 200, 30, 52, 60, 0, 0, 0, 0, 43, 50, 58, 56, 53, 66, 48, 55, 46, 80, 35, 80, 0, 0, 38, 60 }}, {{ 1090, 0, 450, 0, 1574, 0, 2234, 0, 3282, 0, 5769, 0, 6851, 0, 0, 0, 200, 30, 52, 60, 0, 0, 0, 0, 42, 50, 57, 60, 56, 79, 50, 59, 45, 80, 36, 80, 0, 0, 35, 60 }}, {{ 1092, 0, 451, 0, 1572, 0, 2391, 0, 3406, 0, 5755, 0, 6873, 0, 0, 0, 200, 30, 52, 60, 0, 0, 0, 0, 41, 50, 57, 64, 58, 93, 52, 62, 45, 80, 36, 80, 0, 0, 31, 60 }}, {{ 1095, 0, 455, 0, 1563, 0, 2562, 0, 3551, 0, 5742, 0, 6902, 0, 0, 0, 200, 30, 52, 60, 0, 0, 0, 0, 40, 48, 57, 68, 61, 106, 55, 63, 45, 80, 37, 80, 0, 0, 28, 60 }}, {{ 1098, 0, 460, 0, 1551, 0, 2680, 0, 3659, 0, 5736, 0, 6926, 0, 0, 0, 200, 30, 52, 60, 0, 0, 40, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 24, 60 }}, {{ 1100, 0, 465, 0, 1539, 0, 2756, 0, 3736, 0, 5733, 0, 6945, 0, 0, 0, 200, 30, 0, 60, 0, 0, 42, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 469, 0, 1529, 0, 2802, 0, 3785, 0, 5731, 0, 6958, 0, 0, 0, 200, 30, 0, 60, 0, 0, 43, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 471, 0, 1524, 0, 2823, 0, 3809, 0, 5731, 0, 6964, 0, 0, 0, 200, 30, 0, 60, 0, 0, 45, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 471, 0, 1524, 0, 2823, 0, 3809, 0, 5731, 0, 6964, 0, 0, 0, 200, 30, 0, 60, 0, 0, 46, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 471, 0, 1524, 0, 2823, 0, 3809, 0, 5731, 0, 6964, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 471, 0, 1524, 0, 2823, 0, 3809, 0, 5731, 0, 6964, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 471, 0, 1524, 0, 2823, 0, 3809, 0, 5731, 0, 6964, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 471, 0, 1524, 0, 2823, 0, 3809, 0, 5731, 0, 6964, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 471, 0, 1524, 0, 2823, 0, 3809, 0, 5731, 0, 6964, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 471, 0, 1524, 0, 2823, 0, 3809, 0, 5731, 0, 6964, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 471, 0, 1524, 0, 2823, 0, 3809, 0, 5731, 0, 6964, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 471, 0, 1524, 0, 2823, 0, 3809, 0, 5731, 0, 6964, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 471, 0, 1524, 0, 2823, 0, 3809, 0, 5731, 0, 6964, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 471, 0, 1524, 0, 2823, 0, 3809, 0, 5731, 0, 6964, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 471, 0, 1524, 0, 2823, 0, 3809, 0, 5731, 0, 6964, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 469, 0, 1519, 0, 2817, 0, 3799, 0, 5719, 0, 6958, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 464, 0, 1511, 0, 2805, 0, 3778, 0, 5695, 0, 6947, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 457, 0, 1500, 0, 2783, 0, 3742, 0, 5661, 0, 6934, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 448, 0, 1487, 0, 2748, 0, 3687, 0, 5622, 0, 6923, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 439, 0, 1474, 0, 2694, 0, 3607, 0, 5580, 0, 6920, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 429, 0, 1461, 0, 2617, 0, 3495, 0, 5541, 0, 6932, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 420, 0, 1453, 0, 2508, 0, 3340, 0, 5512, 0, 6967, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 413, 0, 1451, 0, 2358, 0, 3133, 0, 5499, 0, 7036, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 410, 0, 1455, 0, 2205, 0, 2925, 0, 5505, 0, 7121, 0, 0, 0, 200, 30, 0, 60, 0, 0, 48, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 408, 0, 1464, 0, 2057, 0, 2727, 0, 5525, 0, 7213, 0, 0, 0, 200, 30, 0, 60, 0, 0, 47, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 409, 0, 1475, 0, 1923, 0, 2548, 0, 5551, 0, 7302, 0, 0, 0, 200, 30, 0, 60, 0, 0, 46, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 410, 0, 1486, 0, 1808, 0, 2396, 0, 5577, 0, 7382, 0, 0, 0, 200, 30, 0, 60, 0, 0, 43, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 411, 0, 1495, 0, 1718, 0, 2276, 0, 5601, 0, 7447, 0, 0, 0, 200, 30, 0, 60, 0, 0, 41, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 413, 0, 1502, 0, 1656, 0, 2194, 0, 5619, 0, 7492, 0, 0, 0, 200, 30, 0, 60, 0, 0, 39, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 413, 0, 1506, 0, 1624, 0, 2152, 0, 5628, 0, 7516, 0, 0, 0, 200, 30, 0, 60, 0, 0, 39, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 413, 0, 1506, 0, 1624, 0, 2152, 0, 5628, 0, 7516, 0, 0, 0, 200, 30, 0, 60, 0, 0, 39, 0, 0, 10, 0, 10, 55, 100, 0, 10, 60, 200, 0, 10, 0, 0, 0, 60 }}, {{ 1100, 0, 413, 0, 1506, 0, 1624, 0, 2152, 0, 5628, 0, 7516, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 39, 12, 69, 75, 48, 127, 52, 85, 39, 80, 31, 80, 0, 0, 36, 60 }}, {{ 1100, 0, 413, 0, 1506, 0, 1624, 0, 2152, 0, 5628, 0, 7516, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 39, 12, 69, 75, 48, 127, 52, 85, 39, 80, 31, 80, 0, 0, 39, 60 }}, {{ 1101, 0, 413, 0, 1506, 0, 1624, 0, 2152, 0, 5628, 0, 7516, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 39, 12, 69, 75, 48, 127, 52, 85, 39, 80, 31, 80, 0, 0, 42, 60 }}, {{ 1103, 0, 413, 0, 1506, 0, 1624, 0, 2152, 0, 5628, 0, 7516, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 39, 12, 69, 75, 48, 127, 52, 85, 39, 80, 31, 80, 0, 0, 45, 60 }}, {{ 1104, 0, 413, 0, 1510, 0, 1634, 0, 2170, 0, 5615, 0, 7497, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 39, 13, 68, 75, 48, 127, 52, 85, 39, 80, 31, 80, 0, 0, 48, 60 }}, {{ 1106, 0, 411, 0, 1518, 0, 1655, 0, 2206, 0, 5589, 0, 7460, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 39, 14, 68, 74, 48, 126, 53, 85, 39, 80, 31, 80, 0, 0, 49, 60 }}, {{ 1107, 0, 408, 0, 1530, 0, 1687, 0, 2259, 0, 5552, 0, 7406, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 39, 15, 67, 73, 49, 126, 53, 84, 39, 80, 31, 80, 0, 0, 49, 60 }}, {{ 1109, 0, 405, 0, 1547, 0, 1729, 0, 2329, 0, 5505, 0, 7337, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 39, 17, 66, 72, 50, 125, 53, 84, 39, 80, 32, 80, 0, 0, 50, 60 }}, {{ 1110, 0, 400, 0, 1570, 0, 1784, 0, 2416, 0, 5451, 0, 7256, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 38, 19, 64, 71, 51, 125, 53, 83, 40, 80, 32, 80, 0, 0, 50, 60 }}, {{ 1111, 0, 394, 0, 1599, 0, 1850, 0, 2517, 0, 5393, 0, 7166, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 38, 22, 62, 70, 52, 125, 53, 82, 40, 80, 33, 80, 0, 0, 51, 60 }}, {{ 1113, 0, 386, 0, 1635, 0, 1929, 0, 2633, 0, 5334, 0, 7071, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 38, 24, 61, 69, 54, 125, 54, 82, 40, 80, 34, 80, 0, 0, 52, 60 }}, {{ 1114, 0, 377, 0, 1680, 0, 2021, 0, 2762, 0, 5279, 0, 6975, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 37, 27, 59, 69, 55, 125, 55, 81, 41, 80, 34, 80, 0, 0, 52, 60 }}, {{ 1116, 0, 366, 0, 1735, 0, 2128, 0, 2902, 0, 5233, 0, 6885, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 37, 29, 57, 68, 57, 127, 55, 80, 42, 80, 35, 80, 0, 0, 53, 60 }}, {{ 1117, 0, 353, 0, 1802, 0, 2251, 0, 3053, 0, 5201, 0, 6805, 0, 0, 0, 200, 30, 16, 60, 0, 0, 0, 0, 37, 32, 54, 69, 60, 130, 56, 79, 42, 80, 35, 80, 0, 0, 53, 60 }}, {{ 1119, 0, 340, 0, 1866, 0, 2364, 0, 3182, 0, 5189, 0, 6753, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 36, 33, 53, 70, 62, 134, 57, 78, 43, 80, 36, 80, 0, 0, 54, 60 }}, {{ 1120, 0, 327, 0, 1927, 0, 2467, 0, 3294, 0, 5192, 0, 6721, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 36, 34, 51, 71, 63, 137, 58, 77, 43, 80, 36, 80, 0, 0, 55, 60 }}, {{ 1122, 0, 316, 0, 1984, 0, 2559, 0, 3388, 0, 5206, 0, 6704, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 35, 34, 50, 73, 65, 141, 59, 77, 44, 80, 36, 80, 0, 0, 55, 60 }}, {{ 1123, 0, 306, 0, 2034, 0, 2640, 0, 3467, 0, 5225, 0, 6699, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 35, 35, 49, 74, 66, 145, 60, 76, 44, 80, 36, 80, 0, 0, 56, 60 }}, {{ 1125, 0, 297, 0, 2078, 0, 2708, 0, 3530, 0, 5247, 0, 6701, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 35, 35, 49, 76, 68, 148, 61, 76, 44, 80, 36, 80, 0, 0, 56, 60 }}, {{ 1127, 0, 290, 0, 2114, 0, 2763, 0, 3580, 0, 5268, 0, 6706, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 34, 48, 77, 69, 151, 61, 75, 45, 80, 36, 80, 0, 0, 57, 60 }}, {{ 1128, 0, 284, 0, 2142, 0, 2805, 0, 3617, 0, 5285, 0, 6712, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 34, 48, 78, 69, 154, 62, 75, 45, 80, 35, 80, 0, 0, 58, 60 }}, {{ 1130, 0, 281, 0, 2160, 0, 2833, 0, 3641, 0, 5298, 0, 6717, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 34, 48, 79, 70, 155, 62, 75, 45, 80, 35, 80, 0, 0, 58, 60 }}, {{ 1132, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 34, 47, 79, 70, 156, 62, 75, 45, 80, 35, 80, 0, 0, 59, 60 }}, {{ 1133, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 34, 47, 79, 70, 156, 62, 75, 45, 80, 35, 80, 0, 0, 59, 60 }}, {{ 1135, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 34, 47, 79, 70, 156, 62, 75, 45, 80, 35, 80, 0, 0, 60, 60 }}, {{ 1137, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 34, 47, 79, 70, 156, 62, 75, 45, 80, 35, 80, 0, 0, 60, 60 }}, {{ 1138, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 34, 47, 79, 70, 156, 62, 75, 45, 80, 35, 80, 0, 0, 60, 60 }}, {{ 1140, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 34, 47, 79, 70, 156, 62, 75, 45, 80, 35, 80, 0, 0, 60, 60 }}, {{ 1142, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 34, 47, 79, 70, 156, 62, 75, 45, 80, 35, 80, 0, 0, 59, 60 }}, {{ 1143, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 34, 47, 79, 70, 156, 62, 75, 45, 80, 35, 80, 0, 0, 58, 60 }}, {{ 1145, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 34, 47, 79, 70, 156, 62, 75, 45, 80, 35, 80, 0, 0, 58, 60 }}, {{ 1147, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 34, 47, 79, 70, 156, 62, 75, 45, 80, 35, 80, 0, 0, 57, 60 }}, {{ 1148, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 34, 47, 79, 70, 156, 62, 75, 45, 80, 35, 80, 0, 0, 56, 60 }}, {{ 1150, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 34, 47, 79, 70, 156, 62, 75, 45, 80, 35, 80, 0, 0, 54, 60 }}, {{ 1152, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 34, 47, 79, 70, 156, 62, 75, 45, 80, 35, 80, 0, 0, 53, 60 }}, {{ 1153, 0, 282, 0, 2160, 0, 2843, 0, 3653, 0, 5313, 0, 6724, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 34, 48, 79, 70, 155, 62, 75, 45, 80, 35, 80, 0, 0, 51, 60 }}, {{ 1155, 0, 289, 0, 2142, 0, 2835, 0, 3654, 0, 5329, 0, 6730, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 35, 48, 79, 70, 154, 62, 74, 45, 80, 35, 80, 0, 0, 49, 60 }}, {{ 1157, 0, 299, 0, 2114, 0, 2824, 0, 3654, 0, 5353, 0, 6740, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 35, 35, 48, 79, 69, 152, 62, 73, 45, 80, 35, 80, 0, 0, 48, 60 }}, {{ 1158, 0, 312, 0, 2077, 0, 2809, 0, 3655, 0, 5383, 0, 6753, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 35, 36, 49, 78, 69, 150, 61, 72, 45, 80, 36, 80, 0, 0, 45, 60 }}, {{ 1160, 0, 328, 0, 2032, 0, 2792, 0, 3657, 0, 5420, 0, 6769, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 35, 37, 50, 78, 68, 146, 61, 71, 45, 80, 36, 80, 0, 0, 43, 60 }}, {{ 1162, 0, 347, 0, 1979, 0, 2774, 0, 3659, 0, 5463, 0, 6787, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 36, 38, 51, 77, 68, 143, 60, 70, 45, 80, 36, 80, 0, 0, 41, 60 }}, {{ 1163, 0, 369, 0, 1918, 0, 2754, 0, 3662, 0, 5511, 0, 6808, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 36, 39, 52, 77, 67, 139, 60, 68, 46, 80, 36, 80, 0, 0, 39, 60 }}, {{ 1165, 0, 393, 0, 1850, 0, 2735, 0, 3666, 0, 5561, 0, 6830, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 37, 40, 53, 76, 66, 134, 59, 66, 46, 80, 36, 80, 0, 0, 36, 60 }}, {{ 1167, 0, 419, 0, 1776, 0, 2717, 0, 3671, 0, 5615, 0, 6853, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 38, 41, 54, 75, 66, 129, 58, 64, 46, 80, 37, 80, 0, 0, 35, 60 }}, {{ 1168, 0, 447, 0, 1696, 0, 2703, 0, 3679, 0, 5668, 0, 6876, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 39, 43, 56, 74, 65, 124, 58, 63, 46, 80, 37, 80, 0, 0, 33, 60 }}, {{ 1170, 0, 473, 0, 1619, 0, 2693, 0, 3687, 0, 5717, 0, 6898, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 39, 44, 57, 73, 64, 119, 57, 61, 46, 80, 37, 80, 0, 0, 31, 60 }}, {{ 1172, 0, 496, 0, 1552, 0, 2689, 0, 3696, 0, 5756, 0, 6915, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 40, 44, 58, 72, 63, 114, 56, 60, 46, 80, 38, 80, 0, 0, 30, 60 }}, {{ 1173, 0, 515, 0, 1494, 0, 2689, 0, 3705, 0, 5787, 0, 6929, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 40, 45, 59, 71, 63, 111, 56, 59, 46, 80, 38, 80, 0, 0, 28, 60 }}, {{ 1175, 0, 531, 0, 1445, 0, 2692, 0, 3713, 0, 5811, 0, 6940, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 46, 59, 71, 62, 108, 56, 58, 47, 80, 38, 80, 0, 0, 27, 60 }}, {{ 1177, 0, 545, 0, 1405, 0, 2696, 0, 3720, 0, 5830, 0, 6949, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 46, 60, 70, 62, 105, 55, 57, 47, 80, 38, 80, 0, 0, 26, 60 }}, {{ 1178, 0, 555, 0, 1371, 0, 2701, 0, 3727, 0, 5844, 0, 6956, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 46, 60, 70, 62, 103, 55, 57, 47, 80, 38, 80, 0, 0, 26, 60 }}, {{ 1180, 0, 564, 0, 1345, 0, 2706, 0, 3732, 0, 5854, 0, 6961, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 46, 61, 69, 61, 101, 55, 57, 47, 80, 39, 80, 0, 0, 25, 60 }}, {{ 1182, 0, 570, 0, 1326, 0, 2710, 0, 3737, 0, 5861, 0, 6964, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 46, 61, 69, 61, 100, 55, 56, 47, 80, 39, 80, 0, 0, 24, 60 }}, {{ 1183, 0, 574, 0, 1313, 0, 2713, 0, 3739, 0, 5866, 0, 6967, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 47, 61, 69, 61, 99, 55, 56, 47, 80, 39, 80, 0, 0, 24, 60 }}, {{ 1185, 0, 576, 0, 1307, 0, 2715, 0, 3741, 0, 5868, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 47, 61, 69, 61, 99, 55, 56, 47, 80, 39, 80, 0, 0, 24, 60 }}, {{ 1187, 0, 576, 0, 1307, 0, 2715, 0, 3741, 0, 5868, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 47, 61, 69, 61, 99, 55, 56, 47, 80, 39, 80, 0, 0, 24, 60 }}, {{ 1188, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1190, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1184, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1177, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1171, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1164, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1158, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1151, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1145, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1139, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1132, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1126, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1119, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1113, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1106, 0, 462, 0, 1513, 0, 2553, 0, 3535, 0, 5746, 0, 6910, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 100, 50, 100, 50, 100, 50, 100, 35, 100, 0, 100, 0, 0, 60, 60 }}, {{ 1100, 0, 466, 0, 1520, 0, 2560, 0, 3550, 0, 5757, 0, 6909, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 100, 50, 100, 50, 100, 50, 100, 35, 100, 0, 100, 0, 0, 60, 60 }}, {{ 1075, 0, 474, 0, 1530, 0, 2570, 0, 3573, 0, 5773, 0, 6909, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 40, 49, 58, 68, 61, 104, 54, 62, 45, 80, 37, 80, 0, 0, 50, 60 }}, {{ 1050, 0, 484, 0, 1544, 0, 2585, 0, 3603, 0, 5793, 0, 6911, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 49, 58, 68, 61, 103, 54, 62, 45, 80, 37, 80, 0, 0, 51, 60 }}, {{ 1048, 0, 496, 0, 1563, 0, 2603, 0, 3638, 0, 5816, 0, 6916, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 49, 58, 68, 61, 102, 54, 62, 45, 80, 37, 80, 0, 0, 53, 60 }}, {{ 1045, 0, 512, 0, 1587, 0, 2626, 0, 3679, 0, 5840, 0, 6927, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 50, 58, 69, 62, 101, 55, 63, 46, 80, 37, 80, 0, 0, 55, 60 }}, {{ 1043, 0, 530, 0, 1616, 0, 2654, 0, 3722, 0, 5864, 0, 6945, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 58, 70, 62, 101, 55, 65, 46, 80, 38, 80, 0, 0, 57, 60 }}, {{ 1041, 0, 552, 0, 1652, 0, 2686, 0, 3767, 0, 5885, 0, 6975, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 58, 72, 62, 102, 55, 67, 46, 80, 38, 80, 0, 0, 58, 60 }}, {{ 1038, 0, 575, 0, 1691, 0, 2720, 0, 3808, 0, 5900, 0, 7012, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 58, 74, 63, 103, 56, 71, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 1036, 0, 595, 0, 1726, 0, 2750, 0, 3840, 0, 5907, 0, 7053, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 58, 76, 63, 105, 56, 75, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 1034, 0, 612, 0, 1758, 0, 2777, 0, 3864, 0, 5910, 0, 7092, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 50, 59, 78, 64, 108, 57, 79, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 1031, 0, 627, 0, 1786, 0, 2800, 0, 3882, 0, 5910, 0, 7129, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 59, 79, 64, 110, 57, 83, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1029, 0, 640, 0, 1809, 0, 2819, 0, 3896, 0, 5908, 0, 7161, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 59, 81, 64, 112, 58, 87, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1027, 0, 649, 0, 1826, 0, 2833, 0, 3905, 0, 5905, 0, 7186, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 59, 82, 65, 113, 58, 90, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1024, 0, 655, 0, 1838, 0, 2843, 0, 3911, 0, 5903, 0, 7204, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 60, 83, 65, 115, 58, 91, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1022, 0, 658, 0, 1844, 0, 2848, 0, 3914, 0, 5901, 0, 7213, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 60, 83, 65, 115, 58, 92, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1020, 0, 658, 0, 1844, 0, 2848, 0, 3914, 0, 5901, 0, 7213, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 60, 83, 65, 115, 58, 92, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1017, 0, 658, 0, 1844, 0, 2848, 0, 3914, 0, 5899, 0, 7211, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 60, 83, 65, 115, 58, 92, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1015, 0, 655, 0, 1840, 0, 2845, 0, 3913, 0, 5895, 0, 7202, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 60, 83, 65, 114, 58, 92, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1013, 0, 651, 0, 1834, 0, 2841, 0, 3912, 0, 5890, 0, 7188, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 59, 83, 65, 114, 58, 91, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1010, 0, 646, 0, 1827, 0, 2836, 0, 3910, 0, 5883, 0, 7171, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 51, 59, 82, 65, 112, 58, 91, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1008, 0, 639, 0, 1818, 0, 2829, 0, 3907, 0, 5874, 0, 7149, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 51, 59, 81, 64, 111, 58, 90, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1006, 0, 631, 0, 1807, 0, 2819, 0, 3903, 0, 5864, 0, 7124, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 52, 59, 80, 64, 109, 57, 88, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1003, 0, 622, 0, 1795, 0, 2807, 0, 3896, 0, 5853, 0, 7097, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 52, 59, 79, 64, 107, 57, 87, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1001, 0, 612, 0, 1781, 0, 2791, 0, 3886, 0, 5841, 0, 7066, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 53, 58, 78, 64, 105, 56, 86, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 999, 0, 602, 0, 1766, 0, 2772, 0, 3873, 0, 5829, 0, 7034, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 53, 58, 76, 63, 102, 56, 84, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 996, 0, 590, 0, 1750, 0, 2748, 0, 3855, 0, 5816, 0, 7001, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 54, 58, 75, 63, 100, 55, 82, 45, 80, 39, 80, 0, 0, 60, 60 }}, {{ 994, 0, 578, 0, 1733, 0, 2719, 0, 3832, 0, 5804, 0, 6967, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 55, 58, 73, 62, 97, 55, 80, 45, 80, 39, 80, 0, 0, 60, 60 }}, {{ 992, 0, 565, 0, 1715, 0, 2684, 0, 3802, 0, 5792, 0, 6934, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 55, 57, 71, 62, 93, 54, 77, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 989, 0, 551, 0, 1697, 0, 2642, 0, 3766, 0, 5782, 0, 6902, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 55, 57, 70, 61, 89, 53, 75, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 987, 0, 538, 0, 1678, 0, 2592, 0, 3720, 0, 5773, 0, 6872, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 56, 57, 68, 60, 86, 52, 72, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 985, 0, 524, 0, 1660, 0, 2533, 0, 3665, 0, 5766, 0, 6846, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 56, 57, 66, 60, 81, 52, 69, 46, 80, 38, 80, 0, 0, 60, 60 }}, {{ 982, 0, 512, 0, 1644, 0, 2473, 0, 3607, 0, 5762, 0, 6826, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 56, 57, 64, 59, 77, 51, 67, 46, 80, 37, 80, 0, 0, 60, 60 }}, {{ 980, 0, 501, 0, 1630, 0, 2413, 0, 3548, 0, 5760, 0, 6813, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 55, 57, 62, 58, 74, 50, 64, 46, 80, 37, 80, 0, 0, 60, 60 }}, {{ 977, 0, 492, 0, 1618, 0, 2354, 0, 3489, 0, 5761, 0, 6804, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 55, 57, 60, 57, 70, 49, 62, 46, 80, 36, 80, 0, 0, 60, 60 }}, {{ 974, 0, 484, 0, 1608, 0, 2297, 0, 3430, 0, 5763, 0, 6799, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 54, 57, 59, 56, 67, 49, 60, 46, 80, 36, 80, 0, 0, 60, 60 }}, {{ 971, 0, 477, 0, 1599, 0, 2242, 0, 3374, 0, 5766, 0, 6797, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 54, 57, 58, 55, 65, 48, 58, 46, 80, 36, 80, 0, 0, 60, 60 }}, {{ 968, 0, 471, 0, 1592, 0, 2191, 0, 3321, 0, 5770, 0, 6797, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 53, 57, 57, 54, 62, 48, 57, 47, 80, 35, 80, 0, 0, 60, 60 }}, {{ 965, 0, 467, 0, 1586, 0, 2144, 0, 3272, 0, 5774, 0, 6799, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 53, 57, 56, 54, 60, 47, 55, 47, 80, 35, 80, 0, 0, 60, 60 }}, {{ 962, 0, 463, 0, 1581, 0, 2101, 0, 3227, 0, 5779, 0, 6802, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 52, 57, 55, 53, 58, 47, 54, 47, 80, 35, 80, 0, 0, 60, 60 }}, {{ 959, 0, 459, 0, 1578, 0, 2063, 0, 3188, 0, 5783, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 52, 57, 54, 53, 56, 46, 53, 47, 80, 35, 80, 0, 0, 60, 60 }}, {{ 956, 0, 457, 0, 1574, 0, 2031, 0, 3154, 0, 5787, 0, 6810, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 51, 58, 54, 52, 55, 46, 52, 47, 80, 35, 80, 0, 0, 60, 60 }}, {{ 953, 0, 455, 0, 1572, 0, 2005, 0, 3126, 0, 5790, 0, 6813, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 51, 58, 53, 52, 54, 46, 52, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 950, 0, 453, 0, 1570, 0, 1986, 0, 3105, 0, 5793, 0, 6816, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 51, 58, 53, 52, 53, 46, 51, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 947, 0, 452, 0, 1569, 0, 1972, 0, 3091, 0, 5795, 0, 6818, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 46, 51, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 944, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 941, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 938, 0, 451, 0, 1568, 0, 1971, 0, 3090, 0, 5797, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 51, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 935, 0, 450, 0, 1566, 0, 1983, 0, 3103, 0, 5799, 0, 6820, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 51, 58, 53, 51, 52, 46, 51, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 932, 0, 449, 0, 1564, 0, 2000, 0, 3122, 0, 5802, 0, 6822, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 51, 58, 53, 52, 53, 46, 51, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 929, 0, 447, 0, 1561, 0, 2022, 0, 3146, 0, 5805, 0, 6824, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 52, 58, 53, 52, 53, 46, 51, 47, 80, 34, 80, 0, 0, 59, 60 }}, {{ 926, 0, 445, 0, 1558, 0, 2050, 0, 3176, 0, 5810, 0, 6828, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 53, 57, 53, 52, 53, 46, 51, 47, 80, 34, 80, 0, 0, 59, 60 }}, {{ 923, 0, 442, 0, 1554, 0, 2082, 0, 3211, 0, 5815, 0, 6832, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 53, 57, 53, 52, 54, 46, 52, 47, 80, 35, 80, 0, 0, 58, 60 }}, {{ 920, 0, 439, 0, 1551, 0, 2118, 0, 3250, 0, 5820, 0, 6839, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 54, 57, 54, 53, 54, 46, 52, 47, 80, 35, 80, 0, 0, 58, 60 }}, {{ 917, 0, 436, 0, 1549, 0, 2157, 0, 3293, 0, 5825, 0, 6847, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 55, 57, 54, 53, 55, 47, 53, 47, 80, 35, 80, 0, 0, 57, 60 }}, {{ 914, 0, 432, 0, 1547, 0, 2200, 0, 3338, 0, 5830, 0, 6858, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 56, 57, 54, 54, 55, 47, 53, 46, 80, 35, 80, 0, 0, 56, 60 }}, {{ 911, 0, 428, 0, 1546, 0, 2245, 0, 3385, 0, 5834, 0, 6873, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 56, 56, 55, 54, 56, 47, 54, 46, 80, 35, 80, 0, 0, 56, 60 }}, {{ 908, 0, 424, 0, 1548, 0, 2291, 0, 3433, 0, 5838, 0, 6891, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 57, 56, 55, 55, 57, 48, 54, 46, 80, 35, 80, 0, 0, 55, 60 }}, {{ 905, 0, 419, 0, 1552, 0, 2338, 0, 3481, 0, 5841, 0, 6913, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 57, 56, 56, 55, 58, 48, 55, 46, 80, 35, 80, 0, 0, 54, 60 }}, {{ 902, 0, 415, 0, 1558, 0, 2385, 0, 3527, 0, 5842, 0, 6940, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 57, 56, 57, 55, 59, 49, 56, 46, 80, 35, 80, 0, 0, 53, 60 }}, {{ 899, 0, 410, 0, 1569, 0, 2431, 0, 3571, 0, 5840, 0, 6973, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 56, 55, 57, 56, 60, 49, 57, 46, 80, 35, 80, 0, 0, 52, 60 }}, {{ 896, 0, 405, 0, 1583, 0, 2474, 0, 3610, 0, 5837, 0, 7013, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 55, 55, 58, 56, 61, 50, 58, 46, 80, 35, 80, 0, 0, 50, 60 }}, {{ 893, 0, 401, 0, 1600, 0, 2508, 0, 3639, 0, 5831, 0, 7054, 0, 0, 0, 200, 30, 0, 60, 0, 0, 42, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 49, 60 }}, {{ 890, 0, 397, 0, 1618, 0, 2536, 0, 3661, 0, 5824, 0, 7096, 0, 0, 0, 200, 30, 0, 60, 0, 0, 42, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 48, 60 }}, {{ 890, 0, 394, 0, 1637, 0, 2558, 0, 3676, 0, 5816, 0, 7138, 0, 0, 0, 200, 30, 0, 60, 0, 0, 42, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 47, 60 }}, {{ 891, 0, 391, 0, 1657, 0, 2574, 0, 3686, 0, 5807, 0, 7178, 0, 0, 0, 200, 30, 0, 60, 0, 0, 42, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 46, 60 }}, {{ 891, 0, 388, 0, 1677, 0, 2587, 0, 3691, 0, 5797, 0, 7217, 0, 0, 0, 200, 30, 0, 60, 0, 0, 42, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 46, 60 }}, {{ 891, 0, 386, 0, 1696, 0, 2596, 0, 3692, 0, 5788, 0, 7254, 0, 0, 0, 200, 30, 0, 60, 0, 0, 42, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 45, 60 }}, {{ 892, 0, 384, 0, 1714, 0, 2602, 0, 3691, 0, 5779, 0, 7288, 0, 0, 0, 200, 30, 0, 60, 0, 0, 42, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 44, 60 }}, {{ 892, 0, 383, 0, 1731, 0, 2606, 0, 3689, 0, 5771, 0, 7319, 0, 0, 0, 200, 30, 0, 60, 0, 0, 42, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 44, 60 }}, {{ 892, 0, 382, 0, 1745, 0, 2608, 0, 3685, 0, 5763, 0, 7346, 0, 0, 0, 200, 30, 0, 60, 0, 0, 42, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 43, 60 }}, {{ 893, 0, 380, 0, 1758, 0, 2609, 0, 3682, 0, 5756, 0, 7369, 0, 0, 0, 200, 30, 0, 60, 0, 0, 42, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 43, 60 }}, {{ 893, 0, 380, 0, 1769, 0, 2610, 0, 3678, 0, 5751, 0, 7388, 0, 0, 0, 200, 30, 0, 60, 0, 0, 42, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 42, 60 }}, {{ 893, 0, 379, 0, 1777, 0, 2610, 0, 3675, 0, 5746, 0, 7402, 0, 0, 0, 200, 30, 0, 60, 0, 0, 42, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 42, 60 }}, {{ 894, 0, 379, 0, 1782, 0, 2610, 0, 3673, 0, 5743, 0, 7412, 0, 0, 0, 200, 30, 0, 60, 0, 0, 42, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 42, 60 }}, {{ 894, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 42, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 42, 60 }}, {{ 894, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 42, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 42, 60 }}, {{ 895, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 42, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 42, 60 }}, {{ 895, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 42, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 42, 60 }}, {{ 895, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 42, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 42, 60 }}, {{ 896, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 41, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 41, 60 }}, {{ 896, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 39, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 39, 60 }}, {{ 896, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 35, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 35, 60 }}, {{ 897, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 30, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 30, 60 }}, {{ 897, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 25, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 25, 60 }}, {{ 897, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 18, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 18, 60 }}, {{ 898, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 1, 60, 0, 0, 12, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 12, 60 }}, {{ 898, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 1, 60, 0, 0, 7, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 7, 60 }}, {{ 898, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 1, 60, 0, 0, 4, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 4, 60 }}, {{ 899, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 1, 60, 0, 0, 2, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 2, 60 }}, {{ 899, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 1, 60, 0, 0, 1, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 1, 60 }}, {{ 899, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 1, 60, 0, 0, 1, 0, 0, 40, 35, 40, 50, 50, 65, 100, 75, 200, 65, 100, 0, 0, 1, 60 }}, {{ 900, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 900, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 900, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 901, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 901, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 902, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 902, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 902, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 903, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 903, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 904, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 904, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 904, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 905, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 905, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 906, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 906, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 906, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 907, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 907, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 908, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 908, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 908, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 909, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 909, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 910, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 910, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 910, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 911, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 911, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 912, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 912, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 912, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 913, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 913, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 914, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 914, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 914, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 915, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 915, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 916, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 916, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 916, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 917, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 917, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 918, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 918, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 918, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 919, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 919, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 920, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 920, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 920, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 921, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 921, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 922, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 922, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 922, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 923, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 923, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 924, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 924, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 924, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 925, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 925, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 926, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 926, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 926, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 927, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 927, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 928, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 928, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 928, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 929, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 929, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 930, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 930, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 930, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 931, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 931, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 932, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 932, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 932, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 933, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 933, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 934, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 934, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 934, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 935, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 935, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 936, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 936, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 936, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 937, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 937, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 938, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 938, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 938, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 939, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 939, 0, 379, 0, 1785, 0, 2610, 0, 3672, 0, 5742, 0, 7417, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 64, 0, 67, 0, 63, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 940, 0, 591, 0, 1313, 0, 2691, 0, 3779, 0, 5717, 0, 6857, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 57, 75, 51, 70, 44, 80, 40, 80, 30, 0, 39, 60 }}, {{ 940, 0, 591, 0, 1313, 0, 2691, 0, 3779, 0, 5717, 0, 6857, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 57, 75, 51, 70, 44, 80, 40, 80, 30, 0, 42, 60 }}, {{ 945, 0, 591, 0, 1313, 0, 2691, 0, 3779, 0, 5717, 0, 6857, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 57, 75, 51, 70, 44, 80, 40, 80, 30, 0, 45, 60 }}, {{ 950, 0, 591, 0, 1313, 0, 2691, 0, 3779, 0, 5717, 0, 6857, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 57, 75, 51, 70, 44, 80, 40, 80, 30, 0, 45, 60 }}, {{ 955, 0, 591, 0, 1313, 0, 2691, 0, 3779, 0, 5717, 0, 6857, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 57, 75, 51, 70, 44, 80, 40, 80, 30, 0, 45, 60 }}, {{ 960, 0, 590, 0, 1314, 0, 2690, 0, 3779, 0, 5720, 0, 6856, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 57, 75, 51, 70, 44, 80, 40, 80, 30, 0, 45, 60 }}, {{ 965, 0, 589, 0, 1315, 0, 2688, 0, 3777, 0, 5724, 0, 6853, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 57, 75, 51, 70, 44, 80, 40, 80, 30, 0, 45, 60 }}, {{ 970, 0, 588, 0, 1317, 0, 2683, 0, 3774, 0, 5730, 0, 6850, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 57, 75, 51, 69, 44, 80, 40, 80, 30, 0, 46, 60 }}, {{ 975, 0, 587, 0, 1319, 0, 2678, 0, 3770, 0, 5737, 0, 6844, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 57, 75, 51, 69, 44, 80, 40, 80, 30, 0, 49, 60 }}, {{ 980, 0, 585, 0, 1323, 0, 2670, 0, 3764, 0, 5746, 0, 6838, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 58, 57, 57, 75, 51, 69, 44, 80, 40, 80, 30, 0, 52, 60 }}, {{ 985, 0, 583, 0, 1327, 0, 2660, 0, 3757, 0, 5756, 0, 6831, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 54, 58, 57, 57, 75, 51, 69, 44, 80, 40, 80, 0, 0, 56, 60 }}, {{ 990, 0, 580, 0, 1332, 0, 2649, 0, 3748, 0, 5766, 0, 6824, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 55, 58, 57, 57, 75, 50, 69, 44, 80, 40, 80, 0, 0, 58, 60 }}, {{ 994, 0, 579, 0, 1337, 0, 2639, 0, 3740, 0, 5773, 0, 6818, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 55, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 998, 0, 577, 0, 1340, 0, 2631, 0, 3733, 0, 5778, 0, 6813, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 55, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1001, 0, 576, 0, 1343, 0, 2624, 0, 3728, 0, 5782, 0, 6810, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 55, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1005, 0, 576, 0, 1345, 0, 2620, 0, 3724, 0, 5785, 0, 6807, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1009, 0, 575, 0, 1346, 0, 2618, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1012, 0, 575, 0, 1346, 0, 2618, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1016, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 1, 0, 60, 60 }}, {{ 1020, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 2, 0, 60, 60 }}, {{ 1024, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 3, 0, 60, 60 }}, {{ 1028, 0, 575, 0, 1346, 0, 2617, 0, 3722, 0, 5786, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 56, 58, 57, 57, 75, 50, 68, 44, 80, 39, 80, 5, 0, 59, 60 }}, {{ 1031, 0, 557, 0, 1344, 0, 2602, 0, 3692, 0, 5820, 0, 6861, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 55, 58, 58, 57, 76, 51, 65, 44, 80, 39, 80, 8, 0, 58, 60 }}, {{ 1035, 0, 519, 0, 1335, 0, 2584, 0, 3639, 0, 5871, 0, 6953, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 54, 58, 59, 57, 78, 51, 60, 45, 80, 38, 80, 11, 0, 56, 60 }}, {{ 1039, 0, 464, 0, 1308, 0, 2584, 0, 3578, 0, 5904, 0, 7046, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 56, 58, 59, 57, 80, 53, 56, 44, 80, 38, 80, 15, 0, 53, 60 }}, {{ 1042, 0, 409, 0, 1265, 0, 2617, 0, 3538, 0, 5885, 0, 7085, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 61, 58, 58, 58, 82, 54, 54, 43, 80, 38, 80, 19, 0, 50, 60 }}, {{ 1046, 0, 373, 0, 1227, 0, 2658, 0, 3524, 0, 5844, 0, 7080, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 57, 58, 83, 55, 55, 42, 80, 39, 80, 22, 0, 47, 60 }}, {{ 1050, 0, 355, 0, 1205, 0, 2684, 0, 3520, 0, 5815, 0, 7069, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 55, 41, 80, 39, 80, 25, 0, 46, 60 }}, {{ 1055, 0, 355, 0, 1205, 0, 2684, 0, 3520, 0, 5815, 0, 7069, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 57, 56, 58, 83, 55, 55, 41, 80, 39, 80, 27, 0, 45, 60 }}, {{ 1060, 0, 267, 0, 1676, 0, 2414, 0, 3530, 0, 5966, 0, 7193, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 52, 55, 55, 46, 50, 47, 47, 80, 33, 80, 28, 0, 45, 60 }}, {{ 1065, 0, 267, 0, 1676, 0, 2414, 0, 3530, 0, 5966, 0, 7193, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 52, 55, 55, 46, 50, 47, 47, 80, 33, 80, 29, 0, 45, 60 }}, {{ 1070, 0, 267, 0, 1676, 0, 2414, 0, 3530, 0, 5966, 0, 7193, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 52, 55, 55, 46, 50, 47, 47, 80, 33, 80, 30, 0, 45, 60 }}, {{ 1075, 0, 267, 0, 1676, 0, 2414, 0, 3530, 0, 5966, 0, 7193, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 52, 55, 55, 46, 50, 47, 47, 80, 33, 80, 30, 0, 45, 60 }}, {{ 1080, 0, 268, 0, 1679, 0, 2416, 0, 3528, 0, 5969, 0, 7190, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 52, 55, 55, 47, 50, 47, 47, 80, 33, 80, 30, 0, 45, 60 }}, {{ 1085, 0, 271, 0, 1685, 0, 2420, 0, 3523, 0, 5974, 0, 7184, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 52, 56, 55, 50, 50, 48, 47, 80, 33, 80, 30, 0, 45, 60 }}, {{ 1090, 0, 275, 0, 1695, 0, 2427, 0, 3517, 0, 5978, 0, 7174, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 52, 57, 56, 53, 50, 49, 46, 80, 33, 80, 30, 0, 46, 60 }}, {{ 1095, 0, 279, 0, 1709, 0, 2438, 0, 3510, 0, 5980, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 52, 58, 56, 58, 51, 51, 46, 80, 33, 80, 30, 0, 47, 60 }}, {{ 1100, 0, 284, 0, 1730, 0, 2454, 0, 3504, 0, 5974, 0, 7139, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 52, 59, 57, 64, 52, 53, 45, 80, 34, 80, 30, 0, 49, 60 }}, {{ 1105, 0, 289, 0, 1759, 0, 2477, 0, 3501, 0, 5956, 0, 7110, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 52, 61, 58, 72, 52, 55, 45, 80, 34, 80, 30, 0, 51, 60 }}, {{ 1110, 0, 293, 0, 1797, 0, 2509, 0, 3503, 0, 5919, 0, 7073, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 52, 63, 59, 82, 54, 58, 45, 80, 34, 80, 30, 0, 54, 60 }}, {{ 1115, 0, 295, 0, 1848, 0, 2553, 0, 3513, 0, 5857, 0, 7024, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 39, 56, 52, 66, 61, 94, 55, 61, 44, 80, 35, 80, 0, 0, 56, 60 }}, {{ 1120, 0, 295, 0, 1906, 0, 2605, 0, 3530, 0, 5773, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 38, 53, 51, 69, 63, 106, 56, 64, 44, 80, 35, 80, 0, 0, 58, 60 }}, {{ 1122, 0, 294, 0, 1963, 0, 2656, 0, 3552, 0, 5682, 0, 6914, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 37, 49, 51, 71, 64, 118, 58, 67, 44, 80, 35, 80, 0, 0, 59, 60 }}, {{ 1123, 0, 291, 0, 2016, 0, 2705, 0, 3575, 0, 5591, 0, 6864, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 37, 46, 50, 74, 66, 128, 59, 69, 44, 80, 35, 80, 0, 0, 60, 60 }}, {{ 1124, 0, 288, 0, 2064, 0, 2748, 0, 3598, 0, 5506, 0, 6820, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 36, 42, 49, 75, 67, 137, 60, 71, 44, 80, 35, 80, 0, 0, 60, 60 }}, {{ 1126, 0, 285, 0, 2104, 0, 2786, 0, 3618, 0, 5432, 0, 6782, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 35, 39, 49, 77, 68, 144, 61, 73, 44, 80, 35, 80, 0, 0, 60, 60 }}, {{ 1128, 0, 282, 0, 2135, 0, 2815, 0, 3634, 0, 5373, 0, 6753, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 35, 37, 48, 78, 69, 150, 61, 74, 45, 80, 35, 80, 0, 0, 59, 60 }}, {{ 1129, 0, 280, 0, 2156, 0, 2834, 0, 3646, 0, 5332, 0, 6733, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 35, 48, 79, 70, 154, 62, 74, 45, 80, 35, 80, 0, 0, 58, 60 }}, {{ 1131, 0, 279, 0, 2167, 0, 2845, 0, 3652, 0, 5310, 0, 6723, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 34, 48, 79, 70, 155, 62, 75, 45, 80, 35, 80, 0, 0, 56, 60 }}, {{ 1132, 0, 279, 0, 2167, 0, 2845, 0, 3652, 0, 5310, 0, 6723, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 34, 48, 79, 70, 155, 62, 75, 45, 80, 35, 80, 0, 0, 53, 60 }}, {{ 1134, 0, 294, 0, 2129, 0, 2830, 0, 3654, 0, 5340, 0, 6735, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 35, 48, 79, 69, 153, 62, 74, 45, 80, 35, 80, 0, 0, 49, 60 }}, {{ 1135, 0, 323, 0, 2048, 0, 2798, 0, 3656, 0, 5407, 0, 6764, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 35, 37, 50, 78, 69, 147, 61, 71, 45, 80, 36, 80, 0, 0, 45, 60 }}, {{ 1137, 0, 364, 0, 1931, 0, 2758, 0, 3661, 0, 5500, 0, 6803, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 36, 39, 52, 77, 67, 139, 60, 68, 46, 80, 36, 80, 0, 0, 39, 60 }}, {{ 1138, 0, 417, 0, 1783, 0, 2719, 0, 3671, 0, 5609, 0, 6850, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 38, 41, 54, 75, 66, 129, 58, 65, 46, 80, 37, 80, 0, 0, 35, 60 }}, {{ 1140, 0, 476, 0, 1610, 0, 2693, 0, 3688, 0, 5722, 0, 6900, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 39, 44, 57, 73, 64, 118, 57, 61, 46, 80, 37, 80, 0, 0, 31, 60 }}, {{ 1141, 0, 519, 0, 1482, 0, 2690, 0, 3707, 0, 5793, 0, 6932, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 45, 59, 71, 63, 110, 56, 59, 46, 80, 38, 80, 0, 0, 28, 60 }}, {{ 1143, 0, 549, 0, 1391, 0, 2698, 0, 3723, 0, 5836, 0, 6952, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 46, 60, 70, 62, 104, 55, 57, 47, 80, 38, 80, 0, 0, 26, 60 }}, {{ 1144, 0, 568, 0, 1333, 0, 2708, 0, 3735, 0, 5859, 0, 6963, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 46, 61, 69, 61, 101, 55, 57, 47, 80, 39, 80, 0, 0, 25, 60 }}, {{ 1146, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 47, 61, 69, 61, 99, 55, 56, 47, 80, 39, 80, 0, 0, 24, 60 }}, {{ 1147, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 47, 61, 69, 61, 99, 55, 56, 47, 80, 39, 80, 0, 0, 24, 60 }}, {{ 1149, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1150, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1154, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1157, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1161, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1164, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1168, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1171, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1175, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1179, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1182, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1186, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1189, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1193, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1196, 0, 462, 0, 1513, 0, 2553, 0, 3535, 0, 5746, 0, 6910, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 100, 50, 100, 50, 100, 50, 100, 35, 100, 0, 100, 0, 0, 60, 60 }}, {{ 1200, 0, 466, 0, 1520, 0, 2560, 0, 3550, 0, 5757, 0, 6909, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 100, 50, 100, 50, 100, 50, 100, 35, 100, 0, 100, 0, 0, 60, 60 }}, {{ 1235, 0, 474, 0, 1530, 0, 2570, 0, 3573, 0, 5773, 0, 6909, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 40, 49, 58, 68, 61, 104, 54, 62, 45, 80, 37, 80, 0, 0, 50, 60 }}, {{ 1270, 0, 484, 0, 1544, 0, 2585, 0, 3603, 0, 5793, 0, 6911, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 49, 58, 68, 61, 103, 54, 62, 45, 80, 37, 80, 0, 0, 51, 60 }}, {{ 1276, 0, 496, 0, 1563, 0, 2603, 0, 3638, 0, 5816, 0, 6916, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 49, 58, 68, 61, 102, 54, 62, 45, 80, 37, 80, 0, 0, 53, 60 }}, {{ 1282, 0, 512, 0, 1587, 0, 2626, 0, 3679, 0, 5840, 0, 6927, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 50, 58, 69, 62, 101, 55, 63, 46, 80, 37, 80, 0, 0, 55, 60 }}, {{ 1288, 0, 530, 0, 1616, 0, 2654, 0, 3722, 0, 5864, 0, 6945, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 58, 70, 62, 101, 55, 65, 46, 80, 38, 80, 0, 0, 57, 60 }}, {{ 1294, 0, 552, 0, 1652, 0, 2686, 0, 3767, 0, 5885, 0, 6975, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 58, 72, 62, 102, 55, 67, 46, 80, 38, 80, 0, 0, 58, 60 }}, {{ 1300, 0, 575, 0, 1691, 0, 2720, 0, 3808, 0, 5900, 0, 7012, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 58, 74, 63, 103, 56, 71, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 1306, 0, 595, 0, 1726, 0, 2750, 0, 3840, 0, 5907, 0, 7053, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 58, 76, 63, 105, 56, 75, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 1312, 0, 612, 0, 1758, 0, 2777, 0, 3864, 0, 5910, 0, 7092, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 50, 59, 78, 64, 108, 57, 79, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 1318, 0, 627, 0, 1786, 0, 2800, 0, 3882, 0, 5910, 0, 7129, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 59, 79, 64, 110, 57, 83, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1324, 0, 640, 0, 1809, 0, 2819, 0, 3896, 0, 5908, 0, 7161, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 59, 81, 64, 112, 58, 87, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1330, 0, 649, 0, 1826, 0, 2833, 0, 3905, 0, 5905, 0, 7186, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 59, 82, 65, 113, 58, 90, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1336, 0, 655, 0, 1838, 0, 2843, 0, 3911, 0, 5903, 0, 7204, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 60, 83, 65, 115, 58, 91, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1342, 0, 658, 0, 1844, 0, 2848, 0, 3914, 0, 5901, 0, 7213, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 60, 83, 65, 115, 58, 92, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1348, 0, 658, 0, 1844, 0, 2848, 0, 3914, 0, 5901, 0, 7213, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 60, 83, 65, 115, 58, 92, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1354, 0, 658, 0, 1844, 0, 2848, 0, 3914, 0, 5899, 0, 7211, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 60, 83, 65, 115, 58, 92, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1360, 0, 655, 0, 1840, 0, 2845, 0, 3913, 0, 5895, 0, 7202, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 60, 83, 65, 114, 58, 92, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1366, 0, 651, 0, 1834, 0, 2841, 0, 3912, 0, 5890, 0, 7188, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 59, 83, 65, 114, 58, 91, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1372, 0, 646, 0, 1827, 0, 2836, 0, 3910, 0, 5883, 0, 7171, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 51, 59, 82, 65, 112, 58, 91, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1378, 0, 639, 0, 1818, 0, 2829, 0, 3907, 0, 5874, 0, 7149, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 51, 59, 81, 64, 111, 58, 90, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1384, 0, 631, 0, 1807, 0, 2819, 0, 3903, 0, 5864, 0, 7124, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 52, 59, 80, 64, 109, 57, 88, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1390, 0, 622, 0, 1795, 0, 2807, 0, 3896, 0, 5853, 0, 7097, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 52, 59, 79, 64, 107, 57, 87, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1396, 0, 612, 0, 1781, 0, 2791, 0, 3886, 0, 5841, 0, 7066, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 53, 58, 78, 64, 105, 56, 86, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1402, 0, 602, 0, 1766, 0, 2772, 0, 3873, 0, 5829, 0, 7034, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 53, 58, 76, 63, 102, 56, 84, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1408, 0, 590, 0, 1750, 0, 2748, 0, 3855, 0, 5816, 0, 7001, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 54, 58, 75, 63, 100, 55, 82, 45, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1414, 0, 578, 0, 1733, 0, 2719, 0, 3832, 0, 5804, 0, 6967, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 55, 58, 73, 62, 97, 55, 80, 45, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1420, 0, 565, 0, 1715, 0, 2684, 0, 3802, 0, 5792, 0, 6934, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 55, 57, 71, 62, 93, 54, 77, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 1426, 0, 551, 0, 1697, 0, 2642, 0, 3766, 0, 5782, 0, 6902, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 55, 57, 70, 61, 89, 53, 75, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 1432, 0, 538, 0, 1678, 0, 2592, 0, 3720, 0, 5773, 0, 6872, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 56, 57, 68, 60, 86, 52, 72, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 1438, 0, 524, 0, 1660, 0, 2533, 0, 3665, 0, 5766, 0, 6846, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 56, 57, 66, 60, 81, 52, 69, 46, 80, 38, 80, 0, 0, 60, 60 }}, {{ 1444, 0, 512, 0, 1644, 0, 2473, 0, 3607, 0, 5762, 0, 6826, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 56, 57, 64, 59, 77, 51, 67, 46, 80, 37, 80, 0, 0, 60, 60 }}, {{ 1450, 0, 501, 0, 1630, 0, 2413, 0, 3548, 0, 5760, 0, 6813, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 55, 57, 62, 58, 74, 50, 64, 46, 80, 37, 80, 0, 0, 60, 60 }}, {{ 1456, 0, 492, 0, 1618, 0, 2354, 0, 3489, 0, 5761, 0, 6804, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 55, 57, 60, 57, 70, 49, 62, 46, 80, 36, 80, 0, 0, 60, 60 }}, {{ 1462, 0, 484, 0, 1608, 0, 2297, 0, 3430, 0, 5763, 0, 6799, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 54, 57, 59, 56, 67, 49, 60, 46, 80, 36, 80, 0, 0, 60, 60 }}, {{ 1468, 0, 477, 0, 1599, 0, 2242, 0, 3374, 0, 5766, 0, 6797, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 54, 57, 58, 55, 65, 48, 58, 46, 80, 36, 80, 0, 0, 60, 60 }}, {{ 1474, 0, 471, 0, 1592, 0, 2191, 0, 3321, 0, 5770, 0, 6797, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 53, 57, 57, 54, 62, 48, 57, 47, 80, 35, 80, 0, 0, 60, 60 }}, {{ 1480, 0, 467, 0, 1586, 0, 2144, 0, 3272, 0, 5774, 0, 6799, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 53, 57, 56, 54, 60, 47, 55, 47, 80, 35, 80, 0, 0, 60, 60 }}, {{ 1486, 0, 463, 0, 1581, 0, 2101, 0, 3227, 0, 5779, 0, 6802, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 52, 57, 55, 53, 58, 47, 54, 47, 80, 35, 80, 0, 0, 60, 60 }}, {{ 1492, 0, 459, 0, 1578, 0, 2063, 0, 3188, 0, 5783, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 52, 57, 54, 53, 56, 46, 53, 47, 80, 35, 80, 0, 0, 60, 60 }}, {{ 1498, 0, 457, 0, 1574, 0, 2031, 0, 3154, 0, 5787, 0, 6810, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 51, 58, 54, 52, 55, 46, 52, 47, 80, 35, 80, 0, 0, 60, 60 }}, {{ 1504, 0, 455, 0, 1572, 0, 2005, 0, 3126, 0, 5790, 0, 6813, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 51, 58, 53, 52, 54, 46, 52, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1510, 0, 453, 0, 1570, 0, 1986, 0, 3105, 0, 5793, 0, 6816, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 51, 58, 53, 52, 53, 46, 51, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1516, 0, 452, 0, 1569, 0, 1972, 0, 3091, 0, 5795, 0, 6818, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 46, 51, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1522, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1528, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1534, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1540, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1546, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1552, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1558, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1564, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1570, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1576, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 53, 60 }}, {{ 1582, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 47, 60 }}, {{ 1588, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 40, 60 }}, {{ 1594, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 33, 60 }}, {{ 1600, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 27, 60 }}, {{ 1606, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 20, 60 }}, {{ 1612, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 14, 60 }}, {{ 1618, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 7, 60 }}, {{ 1624, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1630, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1626, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1622, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1618, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1613, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1609, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1605, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1601, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1597, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1593, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1589, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1585, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1580, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1576, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1572, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1568, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1564, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1560, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1556, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1552, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1547, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1543, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1539, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1535, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1531, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1527, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1523, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1519, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1514, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1510, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1506, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1502, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1498, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1494, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1490, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1486, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1481, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1477, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1473, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1469, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1465, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1461, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1457, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1453, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1448, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1444, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1440, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1436, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1432, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1428, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1424, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1420, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1415, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1411, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1407, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1403, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1399, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1395, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1391, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1387, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1382, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1378, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1374, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1370, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1366, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1362, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1358, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1354, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1349, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1345, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1341, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1337, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1333, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1329, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1325, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1321, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1316, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1312, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1308, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1304, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 30, 0, 88, 0, 109, 0, 96, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1285, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 30, 0, 88, 0, 109, 0, 96, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1270, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 30, 0, 88, 0, 109, 0, 96, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1255, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 30, 0, 88, 0, 109, 0, 96, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1240, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 30, 0, 88, 0, 109, 0, 96, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1225, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 30, 0, 88, 0, 109, 0, 96, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1210, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 30, 0, 88, 0, 109, 0, 96, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1195, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 30, 0, 88, 0, 109, 0, 96, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1180, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 30, 0, 88, 0, 109, 0, 96, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1165, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 30, 0, 88, 0, 109, 0, 96, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1150, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 30, 0, 88, 0, 109, 0, 96, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1135, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 30, 0, 88, 0, 109, 0, 96, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1120, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 30, 0, 88, 0, 109, 0, 96, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1105, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 30, 0, 88, 0, 109, 0, 96, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1090, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 30, 0, 88, 0, 109, 0, 96, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1075, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 30, 0, 88, 0, 109, 0, 96, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1060, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 30, 0, 88, 0, 109, 0, 96, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1045, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 30, 0, 88, 0, 109, 0, 96, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1030, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 30, 0, 88, 0, 109, 0, 96, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1015, 0, 523, 0, 2043, 0, 2848, 0, 3848, 0, 5725, 0, 7619, 0, 0, 0, 200, 30, 0, 60, 0, 0, 36, 0, 0, 100, 55, 100, 70, 100, 70, 100, 55, 100, 35, 100, 0, 0, 48, 60 }}, {{ 1000, 0, 545, 0, 2007, 0, 2830, 0, 3836, 0, 5758, 0, 7582, 0, 0, 0, 200, 30, 0, 60, 0, 0, 36, 0, 0, 100, 55, 100, 70, 100, 70, 100, 55, 100, 35, 100, 0, 0, 48, 60 }}, {{ 975, 0, 576, 0, 1954, 0, 2806, 0, 3820, 0, 5807, 0, 7529, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 34, 57, 84, 63, 109, 60, 92, 44, 80, 36, 80, 0, 0, 50, 60 }}, {{ 950, 0, 616, 0, 1885, 0, 2776, 0, 3804, 0, 5869, 0, 7464, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 36, 58, 82, 63, 109, 59, 88, 44, 80, 37, 80, 0, 0, 52, 60 }}, {{ 950, 0, 662, 0, 1802, 0, 2744, 0, 3793, 0, 5943, 0, 7392, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 45, 38, 59, 80, 62, 109, 59, 82, 45, 80, 38, 80, 0, 0, 54, 60 }}, {{ 951, 0, 712, 0, 1705, 0, 2713, 0, 3792, 0, 6027, 0, 7318, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 47, 39, 60, 78, 62, 107, 58, 74, 45, 80, 39, 80, 0, 0, 56, 60 }}, {{ 951, 0, 763, 0, 1598, 0, 2689, 0, 3809, 0, 6118, 0, 7249, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 49, 39, 62, 76, 62, 104, 58, 63, 47, 80, 39, 80, 0, 0, 58, 60 }}, {{ 952, 0, 800, 0, 1511, 0, 2677, 0, 3839, 0, 6190, 0, 7206, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 50, 37, 63, 76, 63, 100, 57, 52, 49, 80, 39, 80, 0, 0, 60, 60 }}, {{ 952, 0, 827, 0, 1442, 0, 2674, 0, 3874, 0, 6246, 0, 7180, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 51, 35, 64, 76, 63, 96, 57, 42, 51, 80, 39, 80, 0, 0, 60, 60 }}, {{ 952, 0, 845, 0, 1389, 0, 2676, 0, 3909, 0, 6288, 0, 7167, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 52, 33, 65, 77, 63, 93, 57, 33, 53, 80, 39, 80, 0, 0, 60, 60 }}, {{ 953, 0, 858, 0, 1350, 0, 2680, 0, 3940, 0, 6318, 0, 7161, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 52, 31, 65, 77, 64, 90, 57, 26, 55, 80, 39, 80, 0, 0, 59, 60 }}, {{ 953, 0, 865, 0, 1325, 0, 2683, 0, 3962, 0, 6337, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 52, 30, 66, 78, 64, 88, 57, 21, 56, 80, 39, 80, 0, 0, 57, 60 }}, {{ 954, 0, 868, 0, 1313, 0, 2686, 0, 3974, 0, 6346, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 52, 29, 66, 78, 64, 86, 56, 18, 57, 80, 39, 80, 0, 0, 55, 60 }}, {{ 954, 0, 868, 0, 1313, 0, 2686, 0, 3974, 0, 6346, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 52, 29, 66, 78, 64, 86, 56, 18, 57, 80, 39, 80, 0, 0, 53, 60 }}, {{ 955, 0, 864, 0, 1330, 0, 2683, 0, 3958, 0, 6334, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 52, 30, 65, 77, 64, 88, 57, 22, 56, 80, 39, 80, 0, 0, 50, 60 }}, {{ 955, 0, 853, 0, 1364, 0, 2678, 0, 3928, 0, 6307, 0, 7163, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 52, 32, 65, 77, 64, 91, 57, 28, 54, 80, 39, 80, 0, 0, 46, 60 }}, {{ 955, 0, 836, 0, 1418, 0, 2674, 0, 3889, 0, 6266, 0, 7173, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 51, 34, 64, 76, 63, 95, 57, 38, 52, 80, 39, 80, 0, 0, 42, 60 }}, {{ 956, 0, 808, 0, 1492, 0, 2676, 0, 3848, 0, 6206, 0, 7198, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 51, 37, 63, 76, 63, 99, 57, 49, 50, 80, 39, 80, 0, 0, 38, 60 }}, {{ 956, 0, 767, 0, 1590, 0, 2687, 0, 3811, 0, 6125, 0, 7245, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 49, 39, 62, 76, 62, 104, 58, 62, 47, 80, 39, 80, 0, 0, 35, 60 }}, {{ 957, 0, 707, 0, 1715, 0, 2716, 0, 3792, 0, 6019, 0, 7324, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 47, 39, 60, 78, 62, 107, 58, 75, 45, 80, 38, 80, 0, 0, 32, 60 }}, {{ 957, 0, 649, 0, 1825, 0, 2752, 0, 3795, 0, 5923, 0, 7411, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 45, 38, 59, 80, 63, 109, 59, 84, 45, 80, 38, 80, 0, 0, 29, 60 }}, {{ 957, 0, 598, 0, 1917, 0, 2789, 0, 3810, 0, 5840, 0, 7493, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 35, 58, 83, 63, 109, 60, 90, 44, 80, 37, 80, 0, 0, 27, 60 }}, {{ 958, 0, 556, 0, 1988, 0, 2821, 0, 3829, 0, 5776, 0, 7562, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 33, 57, 85, 63, 109, 60, 93, 45, 80, 36, 80, 0, 0, 26, 60 }}, {{ 958, 0, 527, 0, 2037, 0, 2845, 0, 3846, 0, 5731, 0, 7612, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 40, 31, 56, 87, 64, 109, 61, 95, 45, 80, 35, 80, 0, 0, 25, 60 }}, {{ 959, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 39, 30, 56, 88, 64, 109, 61, 96, 45, 80, 35, 80, 0, 0, 24, 60 }}, {{ 959, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 39, 30, 56, 88, 64, 109, 61, 96, 45, 80, 35, 80, 0, 0, 24, 60 }}, {{ 960, 0, 868, 0, 1313, 0, 2686, 0, 3974, 0, 6346, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 29, 0, 78, 0, 86, 0, 18, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 960, 0, 868, 0, 1313, 0, 2686, 0, 3974, 0, 6346, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 29, 0, 78, 0, 86, 0, 18, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 961, 0, 868, 0, 1313, 0, 2686, 0, 3974, 0, 6346, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 29, 0, 78, 0, 86, 0, 18, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 962, 0, 868, 0, 1313, 0, 2686, 0, 3974, 0, 6346, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 29, 0, 78, 0, 86, 0, 18, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 964, 0, 868, 0, 1313, 0, 2686, 0, 3974, 0, 6346, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 29, 0, 78, 0, 86, 0, 18, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 965, 0, 868, 0, 1313, 0, 2686, 0, 3974, 0, 6346, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 29, 0, 78, 0, 86, 0, 18, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 966, 0, 868, 0, 1313, 0, 2686, 0, 3974, 0, 6346, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 29, 0, 78, 0, 86, 0, 18, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 968, 0, 868, 0, 1313, 0, 2686, 0, 3974, 0, 6346, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 29, 0, 78, 0, 86, 0, 18, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 969, 0, 857, 0, 1328, 0, 2698, 0, 3979, 0, 6330, 0, 7151, 0, 0, 0, 200, 30, 0, 60, 0, 0, 36, 0, 0, 100, 55, 100, 70, 100, 70, 100, 55, 100, 35, 100, 0, 0, 48, 60 }}, {{ 970, 0, 833, 0, 1358, 0, 2723, 0, 3989, 0, 6297, 0, 7136, 0, 0, 0, 200, 30, 0, 60, 0, 0, 36, 0, 0, 100, 55, 100, 70, 100, 70, 100, 55, 100, 35, 100, 0, 0, 48, 60 }}, {{ 980, 0, 797, 0, 1404, 0, 2756, 0, 4000, 0, 6245, 0, 7113, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 49, 30, 64, 80, 66, 100, 58, 26, 55, 80, 38, 80, 0, 0, 50, 60 }}, {{ 990, 0, 749, 0, 1467, 0, 2795, 0, 4008, 0, 6174, 0, 7081, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 47, 31, 63, 81, 67, 109, 58, 31, 55, 80, 38, 80, 0, 0, 52, 60 }}, {{ 990, 0, 689, 0, 1548, 0, 2835, 0, 4006, 0, 6080, 0, 7041, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 45, 31, 61, 83, 68, 118, 59, 37, 53, 80, 38, 80, 0, 0, 54, 60 }}, {{ 990, 0, 617, 0, 1648, 0, 2870, 0, 3986, 0, 5960, 0, 6989, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 32, 59, 83, 69, 128, 60, 44, 52, 80, 37, 80, 0, 0, 56, 60 }}, {{ 990, 0, 533, 0, 1771, 0, 2893, 0, 3941, 0, 5811, 0, 6927, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 40, 33, 57, 84, 69, 138, 60, 53, 50, 80, 37, 80, 0, 0, 58, 60 }}, {{ 990, 0, 460, 0, 1880, 0, 2898, 0, 3882, 0, 5676, 0, 6871, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 38, 33, 54, 83, 70, 145, 61, 59, 49, 80, 36, 80, 0, 0, 60, 60 }}, {{ 990, 0, 400, 0, 1974, 0, 2891, 0, 3818, 0, 5557, 0, 6822, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 36, 34, 52, 82, 70, 150, 61, 65, 47, 80, 36, 80, 0, 0, 60, 60 }}, {{ 990, 0, 351, 0, 2051, 0, 2878, 0, 3758, 0, 5459, 0, 6782, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 35, 34, 50, 81, 70, 153, 62, 69, 46, 80, 36, 80, 0, 0, 60, 60 }}, {{ 990, 0, 315, 0, 2110, 0, 2864, 0, 3708, 0, 5383, 0, 6752, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 35, 34, 49, 80, 70, 154, 62, 72, 46, 80, 35, 80, 0, 0, 59, 60 }}, {{ 990, 0, 291, 0, 2150, 0, 2853, 0, 3672, 0, 5331, 0, 6731, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 34, 48, 80, 70, 156, 62, 74, 45, 80, 35, 80, 0, 0, 57, 60 }}, {{ 990, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 34, 47, 79, 70, 156, 62, 75, 45, 80, 35, 80, 0, 0, 55, 60 }}, {{ 990, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 34, 47, 79, 70, 156, 62, 75, 45, 80, 35, 80, 0, 0, 53, 60 }}, {{ 990, 0, 289, 0, 2141, 0, 2835, 0, 3654, 0, 5330, 0, 6731, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 35, 48, 79, 70, 154, 62, 74, 45, 80, 35, 80, 0, 0, 50, 60 }}, {{ 990, 0, 309, 0, 2085, 0, 2812, 0, 3655, 0, 5377, 0, 6751, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 35, 36, 49, 79, 69, 150, 61, 72, 45, 80, 36, 80, 0, 0, 46, 60 }}, {{ 990, 0, 339, 0, 2002, 0, 2782, 0, 3658, 0, 5445, 0, 6780, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 36, 37, 51, 78, 68, 144, 60, 70, 45, 80, 36, 80, 0, 0, 42, 60 }}, {{ 990, 0, 377, 0, 1896, 0, 2748, 0, 3663, 0, 5528, 0, 6815, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 37, 39, 52, 76, 67, 137, 59, 67, 46, 80, 36, 80, 0, 0, 38, 60 }}, {{ 990, 0, 422, 0, 1768, 0, 2716, 0, 3672, 0, 5620, 0, 6855, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 38, 41, 54, 75, 66, 128, 58, 64, 46, 80, 37, 80, 0, 0, 35, 60 }}, {{ 990, 0, 471, 0, 1624, 0, 2694, 0, 3687, 0, 5714, 0, 6896, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 39, 44, 57, 73, 64, 119, 57, 61, 46, 80, 37, 80, 0, 0, 32, 60 }}, {{ 990, 0, 509, 0, 1511, 0, 2689, 0, 3702, 0, 5778, 0, 6925, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 40, 45, 58, 72, 63, 112, 56, 59, 46, 80, 38, 80, 0, 0, 29, 60 }}, {{ 990, 0, 538, 0, 1426, 0, 2694, 0, 3716, 0, 5820, 0, 6945, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 46, 60, 71, 62, 106, 55, 58, 47, 80, 38, 80, 0, 0, 27, 60 }}, {{ 990, 0, 558, 0, 1364, 0, 2702, 0, 3728, 0, 5847, 0, 6957, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 46, 60, 70, 62, 103, 55, 57, 47, 80, 39, 80, 0, 0, 26, 60 }}, {{ 990, 0, 570, 0, 1325, 0, 2710, 0, 3737, 0, 5862, 0, 6965, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 46, 61, 69, 61, 100, 55, 56, 47, 80, 39, 80, 0, 0, 25, 60 }}, {{ 990, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 47, 61, 69, 61, 99, 55, 56, 47, 80, 39, 80, 0, 0, 24, 60 }}, {{ 990, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 47, 61, 69, 61, 99, 55, 56, 47, 80, 39, 80, 0, 0, 24, 60 }}, {{ 990, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 990, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 990, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 990, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 990, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 990, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 990, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 990, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 990, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 990, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 990, 0, 461, 0, 1512, 0, 2551, 0, 3531, 0, 5744, 0, 6910, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 100, 50, 100, 50, 100, 50, 100, 35, 100, 0, 100, 0, 0, 60, 60 }}, {{ 990, 0, 463, 0, 1516, 0, 2555, 0, 3541, 0, 5750, 0, 6909, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 100, 50, 100, 50, 100, 50, 100, 35, 100, 0, 100, 0, 0, 60, 60 }}, {{ 995, 0, 468, 0, 1522, 0, 2562, 0, 3555, 0, 5760, 0, 6909, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 40, 48, 58, 67, 61, 104, 54, 62, 45, 80, 37, 80, 0, 0, 49, 60 }}, {{ 1000, 0, 474, 0, 1530, 0, 2570, 0, 3573, 0, 5773, 0, 6909, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 40, 49, 58, 68, 61, 104, 54, 62, 45, 80, 37, 80, 0, 0, 50, 60 }}, {{ 1002, 0, 481, 0, 1540, 0, 2581, 0, 3595, 0, 5788, 0, 6910, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 49, 58, 68, 61, 103, 54, 62, 45, 80, 37, 80, 0, 0, 52, 60 }}, {{ 1005, 0, 490, 0, 1554, 0, 2594, 0, 3621, 0, 5805, 0, 6913, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 49, 58, 68, 61, 102, 54, 62, 45, 80, 37, 80, 0, 0, 53, 60 }}, {{ 1008, 0, 501, 0, 1570, 0, 2610, 0, 3650, 0, 5823, 0, 6919, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 49, 58, 68, 61, 102, 54, 62, 46, 80, 37, 80, 0, 0, 54, 60 }}, {{ 1010, 0, 513, 0, 1589, 0, 2628, 0, 3682, 0, 5842, 0, 6928, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 58, 69, 62, 101, 55, 63, 46, 80, 38, 80, 0, 0, 55, 60 }}, {{ 1012, 0, 527, 0, 1611, 0, 2649, 0, 3715, 0, 5860, 0, 6942, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 58, 70, 62, 101, 55, 64, 46, 80, 38, 80, 0, 0, 56, 60 }}, {{ 1015, 0, 543, 0, 1638, 0, 2673, 0, 3750, 0, 5877, 0, 6962, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 58, 71, 62, 102, 55, 66, 46, 80, 38, 80, 0, 0, 58, 60 }}, {{ 1018, 0, 562, 0, 1668, 0, 2700, 0, 3785, 0, 5892, 0, 6990, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 58, 72, 63, 102, 55, 69, 46, 80, 38, 80, 0, 0, 59, 60 }}, {{ 1020, 0, 578, 0, 1698, 0, 2726, 0, 3815, 0, 5902, 0, 7020, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 58, 74, 63, 104, 56, 72, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 1022, 0, 594, 0, 1725, 0, 2749, 0, 3839, 0, 5907, 0, 7051, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 58, 76, 63, 105, 56, 75, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 1025, 0, 608, 0, 1750, 0, 2771, 0, 3858, 0, 5910, 0, 7082, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 50, 58, 77, 64, 107, 57, 78, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 1028, 0, 621, 0, 1773, 0, 2790, 0, 3874, 0, 5910, 0, 7112, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 59, 79, 64, 109, 57, 82, 45, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1030, 0, 631, 0, 1793, 0, 2806, 0, 3887, 0, 5909, 0, 7139, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 59, 80, 64, 110, 57, 84, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1032, 0, 640, 0, 1810, 0, 2820, 0, 3897, 0, 5907, 0, 7163, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 59, 81, 64, 112, 58, 87, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1035, 0, 648, 0, 1824, 0, 2832, 0, 3904, 0, 5905, 0, 7183, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 59, 82, 65, 113, 58, 89, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1038, 0, 653, 0, 1835, 0, 2840, 0, 3909, 0, 5903, 0, 7199, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 59, 83, 65, 114, 58, 91, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1040, 0, 657, 0, 1842, 0, 2846, 0, 3913, 0, 5902, 0, 7210, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 60, 83, 65, 115, 58, 92, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1042, 0, 659, 0, 1846, 0, 2849, 0, 3914, 0, 5901, 0, 7215, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 49, 60, 83, 65, 115, 58, 93, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1045, 0, 659, 0, 1846, 0, 2849, 0, 3914, 0, 5901, 0, 7215, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 49, 60, 83, 65, 115, 58, 93, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1048, 0, 658, 0, 1845, 0, 2848, 0, 3914, 0, 5900, 0, 7213, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 60, 83, 65, 115, 58, 93, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1050, 0, 657, 0, 1843, 0, 2847, 0, 3914, 0, 5898, 0, 7207, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 60, 83, 65, 115, 58, 92, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1052, 0, 654, 0, 1839, 0, 2845, 0, 3913, 0, 5895, 0, 7200, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 60, 83, 65, 114, 58, 92, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1055, 0, 651, 0, 1835, 0, 2842, 0, 3912, 0, 5891, 0, 7190, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 59, 83, 65, 114, 58, 92, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1058, 0, 648, 0, 1830, 0, 2838, 0, 3911, 0, 5886, 0, 7177, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 59, 82, 65, 113, 58, 91, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1060, 0, 643, 0, 1824, 0, 2833, 0, 3909, 0, 5880, 0, 7163, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 51, 59, 82, 65, 112, 58, 90, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1062, 0, 638, 0, 1816, 0, 2828, 0, 3907, 0, 5873, 0, 7146, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 51, 59, 81, 64, 111, 58, 90, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1065, 0, 632, 0, 1808, 0, 2820, 0, 3903, 0, 5865, 0, 7128, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 51, 59, 80, 64, 110, 57, 89, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1068, 0, 626, 0, 1799, 0, 2812, 0, 3898, 0, 5857, 0, 7107, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 52, 59, 79, 64, 108, 57, 88, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1070, 0, 619, 0, 1789, 0, 2801, 0, 3892, 0, 5849, 0, 7085, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 52, 59, 79, 64, 106, 57, 87, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1072, 0, 611, 0, 1779, 0, 2789, 0, 3884, 0, 5840, 0, 7062, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 53, 58, 78, 64, 105, 56, 85, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1075, 0, 603, 0, 1768, 0, 2775, 0, 3874, 0, 5831, 0, 7038, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 53, 58, 77, 63, 103, 56, 84, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1078, 0, 594, 0, 1756, 0, 2758, 0, 3862, 0, 5821, 0, 7014, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 54, 58, 75, 63, 101, 56, 83, 45, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1080, 0, 585, 0, 1743, 0, 2738, 0, 3847, 0, 5812, 0, 6988, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 54, 58, 74, 63, 99, 55, 81, 45, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1082, 0, 576, 0, 1730, 0, 2715, 0, 3828, 0, 5803, 0, 6963, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 55, 58, 73, 62, 96, 55, 79, 45, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1085, 0, 566, 0, 1717, 0, 2689, 0, 3806, 0, 5794, 0, 6938, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 55, 57, 72, 62, 94, 54, 78, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 1088, 0, 556, 0, 1703, 0, 2659, 0, 3780, 0, 5786, 0, 6914, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 55, 57, 70, 61, 91, 54, 76, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 1090, 0, 546, 0, 1690, 0, 2624, 0, 3749, 0, 5778, 0, 6890, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 56, 57, 69, 61, 88, 53, 74, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 1092, 0, 536, 0, 1676, 0, 2585, 0, 3714, 0, 5772, 0, 6869, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 56, 57, 67, 60, 85, 52, 72, 46, 80, 38, 80, 0, 0, 60, 60 }}, {{ 1095, 0, 525, 0, 1662, 0, 2541, 0, 3672, 0, 5766, 0, 6849, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 56, 57, 66, 60, 82, 52, 70, 46, 80, 38, 80, 0, 0, 60, 60 }}, {{ 1098, 0, 516, 0, 1649, 0, 2496, 0, 3629, 0, 5763, 0, 6833, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 56, 57, 64, 59, 79, 51, 68, 46, 80, 37, 80, 0, 0, 60, 60 }}, {{ 1100, 0, 507, 0, 1638, 0, 2451, 0, 3585, 0, 5761, 0, 6821, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 55, 57, 63, 58, 76, 50, 66, 46, 80, 37, 80, 0, 0, 60, 60 }}, {{ 1104, 0, 500, 0, 1628, 0, 2406, 0, 3541, 0, 5760, 0, 6811, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 55, 57, 62, 58, 73, 50, 64, 46, 80, 37, 80, 0, 0, 60, 60 }}, {{ 1107, 0, 493, 0, 1619, 0, 2362, 0, 3496, 0, 5761, 0, 6805, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 55, 57, 61, 57, 71, 49, 62, 46, 80, 37, 80, 0, 0, 60, 60 }}, {{ 1110, 0, 487, 0, 1612, 0, 2318, 0, 3452, 0, 5762, 0, 6800, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 55, 57, 60, 56, 68, 49, 61, 46, 80, 36, 80, 0, 0, 60, 60 }}, {{ 1114, 0, 481, 0, 1605, 0, 2276, 0, 3409, 0, 5764, 0, 6798, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 54, 57, 59, 56, 66, 48, 60, 46, 80, 36, 80, 0, 0, 60, 60 }}, {{ 1117, 0, 476, 0, 1599, 0, 2236, 0, 3368, 0, 5766, 0, 6797, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 54, 57, 58, 55, 64, 48, 58, 46, 80, 36, 80, 0, 0, 60, 60 }}, {{ 1121, 0, 472, 0, 1593, 0, 2198, 0, 3328, 0, 5769, 0, 6797, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 53, 57, 57, 55, 62, 48, 57, 47, 80, 36, 80, 0, 0, 60, 60 }}, {{ 1124, 0, 468, 0, 1588, 0, 2161, 0, 3290, 0, 5773, 0, 6798, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 53, 57, 56, 54, 61, 47, 56, 47, 80, 35, 80, 0, 0, 60, 60 }}, {{ 1128, 0, 465, 0, 1584, 0, 2127, 0, 3255, 0, 5776, 0, 6800, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 53, 57, 55, 54, 59, 47, 55, 47, 80, 35, 80, 0, 0, 60, 60 }}, {{ 1131, 0, 462, 0, 1581, 0, 2096, 0, 3222, 0, 5779, 0, 6803, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 52, 57, 55, 53, 58, 47, 54, 47, 80, 35, 80, 0, 0, 60, 60 }}, {{ 1135, 0, 460, 0, 1578, 0, 2068, 0, 3193, 0, 5783, 0, 6805, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 52, 57, 54, 53, 56, 46, 53, 47, 80, 35, 80, 0, 0, 60, 60 }}, {{ 1138, 0, 458, 0, 1576, 0, 2043, 0, 3166, 0, 5786, 0, 6808, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 51, 58, 54, 52, 55, 46, 53, 47, 80, 35, 80, 0, 0, 60, 60 }}, {{ 1142, 0, 456, 0, 1573, 0, 2021, 0, 3143, 0, 5788, 0, 6811, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 51, 58, 54, 52, 54, 46, 52, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1145, 0, 454, 0, 1572, 0, 2003, 0, 3124, 0, 5791, 0, 6813, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 51, 58, 53, 52, 54, 46, 51, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1149, 0, 453, 0, 1571, 0, 1988, 0, 3108, 0, 5793, 0, 6815, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 51, 58, 53, 52, 53, 46, 51, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1152, 0, 452, 0, 1570, 0, 1977, 0, 3096, 0, 5794, 0, 6817, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 53, 46, 51, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1156, 0, 452, 0, 1569, 0, 1969, 0, 3088, 0, 5795, 0, 6818, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 51, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1159, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1163, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1166, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1170, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1173, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1177, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1180, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1184, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1187, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1191, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1194, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1198, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 55, 60 }}, {{ 1201, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 50, 60 }}, {{ 1205, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 45, 60 }}, {{ 1208, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 40, 60 }}, {{ 1212, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 35, 60 }}, {{ 1215, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 30, 60 }}, {{ 1219, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 25, 60 }}, {{ 1222, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 20, 60 }}, {{ 1226, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 15, 60 }}, {{ 1229, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 10, 60 }}, {{ 1233, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 5, 60 }}, {{ 1236, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1240, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1244, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1249, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1253, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1257, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1262, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1266, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1270, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1275, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1279, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1283, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1288, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1292, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1296, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1301, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1305, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1309, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1314, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1318, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1322, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1327, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1331, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1335, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1340, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1344, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1348, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1353, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1357, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1361, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1366, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1370, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1374, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1379, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1383, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1387, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1392, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1396, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1400, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1405, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1409, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1413, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1418, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1422, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1426, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1431, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1435, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1439, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1444, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1448, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1452, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1457, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1461, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1465, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1470, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1474, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1478, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1483, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1487, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1491, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1496, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 39, 60 }}, {{ 1500, 0, 868, 0, 1313, 0, 2686, 0, 3974, 0, 6346, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 52, 29, 66, 78, 64, 86, 56, 18, 57, 80, 39, 80, 0, 0, 42, 60 }}, {{ 1498, 0, 868, 0, 1313, 0, 2686, 0, 3974, 0, 6346, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 52, 29, 66, 78, 64, 86, 56, 18, 57, 80, 39, 80, 0, 0, 45, 60 }}, {{ 1495, 0, 868, 0, 1313, 0, 2686, 0, 3974, 0, 6346, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 52, 29, 66, 78, 64, 86, 56, 18, 57, 80, 39, 80, 0, 0, 48, 60 }}, {{ 1492, 0, 868, 0, 1313, 0, 2686, 0, 3974, 0, 6346, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 52, 29, 66, 78, 64, 86, 56, 18, 57, 80, 39, 80, 0, 0, 51, 60 }}, {{ 1490, 0, 868, 0, 1313, 0, 2686, 0, 3974, 0, 6346, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 52, 29, 66, 78, 64, 86, 56, 18, 57, 80, 39, 80, 0, 0, 54, 60 }}, {{ 1488, 0, 868, 0, 1313, 0, 2686, 0, 3974, 0, 6346, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 52, 29, 66, 78, 64, 86, 56, 18, 57, 80, 39, 80, 0, 0, 57, 60 }}, {{ 1485, 0, 868, 0, 1313, 0, 2686, 0, 3974, 0, 6346, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 52, 29, 66, 78, 64, 86, 56, 18, 57, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1482, 0, 868, 0, 1313, 0, 2686, 0, 3974, 0, 6346, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 52, 29, 66, 78, 64, 86, 56, 18, 57, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1480, 0, 868, 0, 1313, 0, 2686, 0, 3974, 0, 6346, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 52, 29, 66, 78, 64, 86, 56, 18, 57, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1478, 0, 868, 0, 1313, 0, 2686, 0, 3974, 0, 6346, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 52, 29, 66, 78, 64, 86, 56, 18, 57, 80, 39, 80, 0, 0, 60, 60 }}, {{ 1475, 0, 868, 0, 1313, 0, 2686, 0, 3974, 0, 6346, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 52, 29, 66, 78, 64, 86, 56, 18, 57, 80, 39, 80, 1, 0, 60, 60 }}, {{ 1472, 0, 868, 0, 1313, 0, 2686, 0, 3974, 0, 6346, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 52, 29, 66, 78, 64, 86, 56, 18, 57, 80, 39, 80, 2, 0, 60, 60 }}, {{ 1470, 0, 868, 0, 1313, 0, 2686, 0, 3974, 0, 6346, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 52, 29, 66, 78, 64, 86, 56, 18, 57, 80, 39, 80, 4, 0, 60, 60 }}, {{ 1468, 0, 868, 0, 1313, 0, 2686, 0, 3974, 0, 6346, 0, 7159, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 52, 29, 66, 78, 64, 86, 56, 18, 57, 80, 39, 80, 5, 0, 60, 60 }}, {{ 1465, 0, 858, 0, 1312, 0, 2712, 0, 3995, 0, 6326, 0, 7131, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 51, 29, 66, 78, 65, 89, 57, 19, 57, 80, 39, 80, 7, 0, 59, 60 }}, {{ 1462, 0, 837, 0, 1312, 0, 2761, 0, 4033, 0, 6282, 0, 7081, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 50, 30, 65, 79, 66, 94, 57, 21, 57, 80, 39, 80, 10, 0, 58, 60 }}, {{ 1460, 0, 806, 0, 1319, 0, 2823, 0, 4073, 0, 6213, 0, 7015, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 48, 30, 65, 81, 67, 101, 57, 24, 56, 80, 39, 80, 13, 0, 56, 60 }}, {{ 1458, 0, 767, 0, 1340, 0, 2883, 0, 4099, 0, 6114, 0, 6946, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 45, 28, 65, 84, 68, 111, 58, 28, 56, 80, 39, 80, 16, 0, 54, 60 }}, {{ 1455, 0, 721, 0, 1386, 0, 2922, 0, 4085, 0, 5977, 0, 6890, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 23, 64, 87, 70, 124, 59, 33, 56, 80, 38, 80, 19, 0, 51, 60 }}, {{ 1452, 0, 687, 0, 1439, 0, 2926, 0, 4038, 0, 5858, 0, 6869, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 64, 90, 70, 134, 59, 37, 56, 80, 38, 80, 22, 0, 49, 60 }}, {{ 1450, 0, 663, 0, 1487, 0, 2913, 0, 3981, 0, 5763, 0, 6868, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 64, 92, 71, 142, 60, 41, 56, 80, 37, 80, 25, 0, 48, 60 }}, {{ 1448, 0, 647, 0, 1524, 0, 2896, 0, 3932, 0, 5697, 0, 6873, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 94, 71, 147, 60, 43, 56, 80, 37, 80, 28, 0, 46, 60 }}, {{ 1445, 0, 640, 0, 1543, 0, 2885, 0, 3905, 0, 5663, 0, 6878, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 95, 71, 150, 61, 44, 56, 80, 37, 80, 30, 0, 45, 60 }}, {{ 1442, 0, 640, 0, 1543, 0, 2885, 0, 3905, 0, 5663, 0, 6878, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 95, 71, 150, 61, 44, 56, 80, 37, 80, 31, 0, 45, 60 }}, {{ 1440, 0, 640, 0, 1543, 0, 2885, 0, 3905, 0, 5663, 0, 6878, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 95, 71, 150, 61, 44, 56, 80, 37, 80, 33, 0, 45, 60 }}, {{ 1438, 0, 640, 0, 1543, 0, 2885, 0, 3905, 0, 5663, 0, 6878, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 95, 71, 150, 61, 44, 56, 80, 37, 80, 34, 0, 45, 60 }}, {{ 1435, 0, 640, 0, 1543, 0, 2885, 0, 3905, 0, 5663, 0, 6878, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 95, 71, 150, 61, 44, 56, 80, 37, 80, 35, 0, 45, 60 }}, {{ 1432, 0, 640, 0, 1543, 0, 2885, 0, 3905, 0, 5663, 0, 6878, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 95, 71, 150, 61, 44, 56, 80, 37, 80, 35, 0, 45, 60 }}, {{ 1430, 0, 640, 0, 1543, 0, 2885, 0, 3905, 0, 5663, 0, 6878, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 95, 71, 150, 61, 44, 56, 80, 37, 80, 35, 0, 45, 60 }}, {{ 1428, 0, 640, 0, 1542, 0, 2883, 0, 3905, 0, 5666, 0, 6876, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 95, 71, 150, 61, 44, 55, 80, 37, 80, 35, 0, 45, 60 }}, {{ 1425, 0, 642, 0, 1539, 0, 2879, 0, 3903, 0, 5674, 0, 6872, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 94, 71, 149, 60, 45, 55, 80, 37, 80, 35, 0, 45, 60 }}, {{ 1422, 0, 644, 0, 1535, 0, 2874, 0, 3902, 0, 5685, 0, 6865, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 93, 70, 148, 60, 45, 55, 80, 37, 80, 35, 0, 45, 60 }}, {{ 1420, 0, 646, 0, 1529, 0, 2867, 0, 3899, 0, 5699, 0, 6857, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 92, 70, 146, 60, 46, 55, 80, 37, 80, 35, 0, 45, 60 }}, {{ 1418, 0, 649, 0, 1523, 0, 2858, 0, 3897, 0, 5716, 0, 6848, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 91, 70, 144, 60, 46, 54, 80, 37, 80, 35, 0, 45, 60 }}, {{ 1415, 0, 653, 0, 1516, 0, 2848, 0, 3894, 0, 5736, 0, 6838, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 90, 69, 142, 59, 47, 54, 80, 37, 80, 35, 0, 45, 60 }}, {{ 1412, 0, 656, 0, 1509, 0, 2837, 0, 3890, 0, 5757, 0, 6827, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 88, 69, 139, 59, 48, 53, 80, 38, 80, 35, 0, 45, 60 }}, {{ 1410, 0, 660, 0, 1503, 0, 2825, 0, 3886, 0, 5781, 0, 6818, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 63, 86, 68, 136, 59, 49, 53, 80, 38, 80, 35, 0, 45, 60 }}, {{ 1408, 0, 663, 0, 1498, 0, 2813, 0, 3882, 0, 5805, 0, 6810, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 62, 85, 68, 133, 58, 50, 52, 80, 38, 80, 35, 0, 45, 60 }}, {{ 1405, 0, 667, 0, 1494, 0, 2800, 0, 3878, 0, 5830, 0, 6804, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 62, 83, 67, 130, 58, 51, 51, 80, 39, 80, 35, 0, 45, 60 }}, {{ 1402, 0, 669, 0, 1492, 0, 2788, 0, 3873, 0, 5855, 0, 6801, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 32, 0, 81, 0, 126, 0, 53, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1400, 0, 671, 0, 1494, 0, 2776, 0, 3869, 0, 5878, 0, 6803, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 36, 0, 79, 0, 123, 0, 55, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1398, 0, 671, 0, 1499, 0, 2765, 0, 3864, 0, 5899, 0, 6811, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 39, 0, 78, 0, 120, 0, 57, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1396, 0, 670, 0, 1509, 0, 2755, 0, 3860, 0, 5918, 0, 6826, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 42, 0, 76, 0, 116, 0, 59, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1394, 0, 667, 0, 1525, 0, 2748, 0, 3856, 0, 5932, 0, 6849, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 45, 0, 75, 0, 113, 0, 61, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1392, 0, 662, 0, 1547, 0, 2743, 0, 3852, 0, 5941, 0, 6882, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 47, 0, 74, 0, 111, 0, 64, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1390, 0, 655, 0, 1578, 0, 2741, 0, 3849, 0, 5944, 0, 6926, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 49, 0, 74, 0, 108, 0, 67, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1388, 0, 646, 0, 1613, 0, 2743, 0, 3847, 0, 5940, 0, 6977, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 74, 0, 106, 0, 70, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1385, 0, 635, 0, 1651, 0, 2748, 0, 3846, 0, 5930, 0, 7033, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 49, 0, 74, 0, 105, 0, 73, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1383, 0, 624, 0, 1691, 0, 2754, 0, 3846, 0, 5917, 0, 7092, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 49, 0, 75, 0, 104, 0, 76, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1381, 0, 612, 0, 1732, 0, 2763, 0, 3845, 0, 5899, 0, 7153, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 48, 0, 76, 0, 104, 0, 79, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1379, 0, 599, 0, 1773, 0, 2773, 0, 3846, 0, 5880, 0, 7214, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 46, 0, 77, 0, 104, 0, 81, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1377, 0, 587, 0, 1815, 0, 2783, 0, 3846, 0, 5859, 0, 7274, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 44, 0, 78, 0, 104, 0, 84, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1375, 0, 575, 0, 1854, 0, 2794, 0, 3847, 0, 5837, 0, 7333, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 42, 0, 80, 0, 105, 0, 86, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1373, 0, 564, 0, 1892, 0, 2804, 0, 3848, 0, 5815, 0, 7388, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 40, 0, 81, 0, 105, 0, 88, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1371, 0, 553, 0, 1927, 0, 2815, 0, 3850, 0, 5795, 0, 7440, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 38, 0, 82, 0, 106, 0, 90, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1369, 0, 543, 0, 1959, 0, 2825, 0, 3851, 0, 5775, 0, 7487, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 37, 0, 84, 0, 106, 0, 91, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1367, 0, 535, 0, 1987, 0, 2833, 0, 3852, 0, 5757, 0, 7528, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 35, 0, 85, 0, 107, 0, 93, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1365, 0, 527, 0, 2011, 0, 2841, 0, 3853, 0, 5742, 0, 7564, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 33, 0, 86, 0, 108, 0, 94, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1363, 0, 521, 0, 2031, 0, 2847, 0, 3854, 0, 5729, 0, 7593, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 32, 0, 86, 0, 108, 0, 95, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1360, 0, 516, 0, 2046, 0, 2852, 0, 3854, 0, 5719, 0, 7615, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 31, 0, 87, 0, 108, 0, 95, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1358, 0, 513, 0, 2056, 0, 2856, 0, 3855, 0, 5712, 0, 7630, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 31, 0, 88, 0, 109, 0, 96, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1356, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 30, 0, 88, 0, 109, 0, 96, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1354, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 30, 0, 88, 0, 109, 0, 96, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1352, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 0, 60, 0, 0, 36, 0, 0, 100, 55, 100, 70, 100, 70, 100, 55, 100, 35, 100, 0, 0, 48, 60 }}, {{ 1350, 0, 512, 0, 2061, 0, 2857, 0, 3855, 0, 5709, 0, 7638, 0, 0, 0, 200, 30, 0, 60, 0, 0, 36, 0, 0, 100, 55, 100, 70, 100, 70, 100, 55, 100, 35, 100, 0, 0, 48, 60 }}, {{ 1325, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 47, 0, 69, 0, 99, 0, 56, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 47, 0, 69, 0, 99, 0, 56, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 47, 0, 69, 0, 99, 0, 56, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 47, 0, 69, 0, 99, 0, 56, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 47, 0, 69, 0, 99, 0, 56, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 47, 0, 69, 0, 99, 0, 56, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 47, 0, 69, 0, 99, 0, 56, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 47, 0, 69, 0, 99, 0, 56, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 47, 0, 69, 0, 99, 0, 56, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 47, 0, 69, 0, 99, 0, 56, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 47, 0, 69, 0, 99, 0, 56, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 47, 0, 69, 0, 99, 0, 56, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 47, 0, 69, 0, 99, 0, 56, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 47, 0, 69, 0, 99, 0, 56, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 47, 0, 69, 0, 99, 0, 56, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 47, 0, 69, 0, 99, 0, 56, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 47, 0, 69, 0, 99, 0, 56, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 47, 0, 69, 0, 99, 0, 56, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 47, 0, 69, 0, 99, 0, 56, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 47, 0, 69, 0, 99, 0, 56, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 47, 0, 69, 0, 99, 0, 56, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 47, 0, 69, 0, 99, 0, 56, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 47, 0, 69, 0, 99, 0, 56, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 47, 0, 69, 0, 99, 0, 56, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1300, 0, 463, 0, 1825, 0, 2082, 0, 2944, 0, 5259, 0, 6818, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 100, 50, 100, 50, 100, 50, 100, 35, 100, 0, 100, 0, 0, 60, 60 }}, {{ 1300, 0, 465, 0, 1830, 0, 2122, 0, 2989, 0, 5250, 0, 6805, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 100, 50, 100, 50, 100, 50, 100, 35, 100, 0, 100, 0, 0, 60, 60 }}, {{ 1285, 0, 468, 0, 1839, 0, 2181, 0, 3055, 0, 5240, 0, 6787, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 38, 16, 57, 74, 60, 131, 56, 72, 46, 80, 35, 80, 0, 0, 50, 60 }}, {{ 1270, 0, 472, 0, 1850, 0, 2257, 0, 3141, 0, 5229, 0, 6765, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 38, 16, 57, 75, 61, 135, 56, 72, 47, 80, 35, 80, 0, 0, 53, 60 }}, {{ 1266, 0, 478, 0, 1863, 0, 2348, 0, 3246, 0, 5221, 0, 6741, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 37, 16, 56, 77, 63, 140, 57, 71, 47, 80, 35, 80, 0, 0, 55, 60 }}, {{ 1263, 0, 485, 0, 1879, 0, 2451, 0, 3367, 0, 5219, 0, 6716, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 37, 15, 56, 80, 65, 145, 58, 70, 48, 80, 36, 80, 0, 0, 58, 60 }}, {{ 1260, 0, 492, 0, 1893, 0, 2533, 0, 3464, 0, 5224, 0, 6699, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 37, 15, 56, 82, 66, 149, 59, 69, 49, 80, 36, 80, 0, 0, 60, 60 }}, {{ 1256, 0, 498, 0, 1903, 0, 2595, 0, 3540, 0, 5232, 0, 6688, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 36, 14, 55, 83, 68, 152, 60, 68, 49, 80, 36, 80, 0, 0, 60, 60 }}, {{ 1253, 0, 503, 0, 1911, 0, 2639, 0, 3595, 0, 5241, 0, 6681, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 36, 13, 55, 84, 68, 155, 60, 66, 50, 80, 36, 80, 0, 0, 60, 60 }}, {{ 1249, 0, 506, 0, 1916, 0, 2668, 0, 3631, 0, 5248, 0, 6677, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 36, 13, 55, 85, 69, 156, 60, 66, 50, 80, 36, 80, 0, 0, 60, 60 }}, {{ 1246, 0, 508, 0, 1919, 0, 2683, 0, 3649, 0, 5252, 0, 6675, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 36, 13, 55, 86, 69, 157, 61, 65, 50, 80, 36, 80, 0, 0, 60, 60 }}, {{ 1242, 0, 508, 0, 1919, 0, 2683, 0, 3649, 0, 5252, 0, 6675, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 36, 13, 55, 86, 69, 157, 61, 65, 50, 80, 36, 80, 0, 0, 60, 60 }}, {{ 1239, 0, 508, 0, 1920, 0, 2679, 0, 3647, 0, 5261, 0, 6676, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 36, 14, 55, 85, 69, 156, 60, 65, 50, 80, 36, 80, 0, 0, 60, 60 }}, {{ 1235, 0, 507, 0, 1922, 0, 2673, 0, 3642, 0, 5281, 0, 6676, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 36, 15, 55, 85, 69, 154, 60, 66, 50, 80, 36, 80, 0, 0, 60, 60 }}, {{ 1232, 0, 505, 0, 1924, 0, 2664, 0, 3637, 0, 5309, 0, 6679, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 37, 18, 55, 84, 69, 152, 60, 66, 50, 80, 36, 80, 0, 0, 60, 60 }}, {{ 1228, 0, 502, 0, 1929, 0, 2653, 0, 3630, 0, 5346, 0, 6684, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 37, 21, 55, 83, 68, 149, 60, 66, 49, 80, 36, 80, 0, 0, 60, 60 }}, {{ 1225, 0, 497, 0, 1937, 0, 2642, 0, 3623, 0, 5389, 0, 6693, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 38, 24, 55, 81, 68, 144, 59, 67, 49, 80, 36, 80, 0, 0, 60, 60 }}, {{ 1221, 0, 491, 0, 1947, 0, 2631, 0, 3617, 0, 5439, 0, 6708, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 38, 28, 54, 80, 67, 140, 59, 67, 48, 80, 36, 80, 0, 0, 60, 60 }}, {{ 1218, 0, 481, 0, 1962, 0, 2623, 0, 3614, 0, 5493, 0, 6731, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 38, 32, 54, 79, 67, 134, 58, 68, 48, 80, 36, 80, 0, 0, 60, 60 }}, {{ 1214, 0, 468, 0, 1983, 0, 2620, 0, 3615, 0, 5549, 0, 6767, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 38, 36, 54, 78, 66, 128, 58, 69, 47, 80, 36, 80, 0, 0, 60, 60 }}, {{ 1211, 0, 451, 0, 2010, 0, 2623, 0, 3622, 0, 5605, 0, 6816, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 38, 40, 54, 78, 66, 122, 57, 70, 47, 80, 36, 80, 0, 0, 60, 60 }}, {{ 1207, 0, 428, 0, 2047, 0, 2636, 0, 3637, 0, 5660, 0, 6884, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 38, 44, 54, 78, 65, 115, 57, 71, 47, 80, 35, 80, 0, 0, 60, 60 }}, {{ 1204, 0, 404, 0, 2084, 0, 2656, 0, 3657, 0, 5701, 0, 6957, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 37, 46, 54, 79, 65, 109, 57, 71, 47, 80, 35, 80, 0, 0, 60, 60 }}, {{ 1200, 0, 380, 0, 2121, 0, 2680, 0, 3680, 0, 5732, 0, 7030, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 37, 48, 54, 81, 65, 104, 57, 72, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1198, 0, 357, 0, 2157, 0, 2706, 0, 3704, 0, 5754, 0, 7101, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 36, 49, 54, 82, 66, 100, 57, 72, 48, 80, 34, 80, 0, 0, 60, 60 }}, {{ 1196, 0, 337, 0, 2190, 0, 2732, 0, 3727, 0, 5769, 0, 7168, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 35, 49, 53, 84, 66, 97, 57, 73, 48, 80, 33, 80, 0, 0, 60, 60 }}, {{ 1194, 0, 318, 0, 2219, 0, 2756, 0, 3749, 0, 5780, 0, 7227, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 49, 53, 86, 66, 94, 57, 73, 49, 80, 33, 80, 0, 0, 60, 60 }}, {{ 1192, 0, 303, 0, 2243, 0, 2777, 0, 3768, 0, 5787, 0, 7276, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 33, 49, 53, 87, 66, 92, 57, 73, 49, 80, 32, 80, 0, 0, 60, 60 }}, {{ 1190, 0, 291, 0, 2262, 0, 2794, 0, 3783, 0, 5791, 0, 7315, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 33, 49, 53, 88, 66, 90, 57, 74, 49, 80, 32, 80, 0, 0, 59, 60 }}, {{ 1188, 0, 282, 0, 2274, 0, 2806, 0, 3793, 0, 5793, 0, 7341, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 33, 49, 53, 89, 67, 89, 57, 74, 49, 80, 32, 80, 0, 0, 58, 60 }}, {{ 1186, 0, 278, 0, 2281, 0, 2812, 0, 3799, 0, 5795, 0, 7354, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 32, 49, 53, 89, 67, 89, 57, 74, 50, 80, 32, 80, 0, 0, 56, 60 }}, {{ 1184, 0, 278, 0, 2281, 0, 2812, 0, 3799, 0, 5795, 0, 7354, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 32, 49, 53, 89, 67, 89, 57, 74, 50, 80, 32, 80, 0, 0, 53, 60 }}, {{ 1182, 0, 296, 0, 2239, 0, 2788, 0, 3785, 0, 5799, 0, 7313, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 33, 49, 54, 87, 66, 90, 57, 73, 49, 80, 32, 80, 0, 0, 49, 60 }}, {{ 1180, 0, 331, 0, 2156, 0, 2745, 0, 3761, 0, 5809, 0, 7235, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 35, 50, 54, 84, 65, 92, 57, 73, 48, 80, 33, 80, 0, 0, 45, 60 }}, {{ 1178, 0, 379, 0, 2033, 0, 2693, 0, 3731, 0, 5821, 0, 7136, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 37, 51, 54, 79, 64, 94, 56, 71, 47, 80, 34, 80, 0, 0, 39, 60 }}, {{ 1176, 0, 436, 0, 1873, 0, 2648, 0, 3705, 0, 5836, 0, 7035, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 39, 51, 55, 74, 63, 97, 55, 69, 46, 80, 36, 80, 0, 0, 35, 60 }}, {{ 1174, 0, 496, 0, 1678, 0, 2629, 0, 3693, 0, 5851, 0, 6958, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 51, 57, 70, 62, 99, 55, 65, 46, 80, 37, 80, 0, 0, 31, 60 }}, {{ 1172, 0, 534, 0, 1526, 0, 2643, 0, 3701, 0, 5860, 0, 6935, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 58, 68, 61, 99, 54, 62, 46, 80, 38, 80, 0, 0, 28, 60 }}, {{ 1170, 0, 558, 0, 1414, 0, 2672, 0, 3717, 0, 5865, 0, 6942, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 48, 60, 68, 61, 99, 54, 59, 46, 80, 38, 80, 0, 0, 26, 60 }}, {{ 1168, 0, 571, 0, 1341, 0, 2699, 0, 3732, 0, 5868, 0, 6957, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 47, 60, 68, 61, 99, 55, 57, 46, 80, 39, 80, 0, 0, 25, 60 }}, {{ 1166, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 47, 61, 69, 61, 99, 55, 56, 47, 80, 39, 80, 0, 0, 24, 60 }}, {{ 1164, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 47, 61, 69, 61, 99, 55, 56, 47, 80, 39, 80, 0, 0, 24, 60 }}, {{ 1162, 0, 278, 0, 2281, 0, 2812, 0, 3799, 0, 5795, 0, 7354, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 49, 0, 89, 0, 89, 0, 74, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1160, 0, 278, 0, 2281, 0, 2812, 0, 3799, 0, 5795, 0, 7354, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 49, 0, 89, 0, 89, 0, 74, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1149, 0, 278, 0, 2281, 0, 2812, 0, 3799, 0, 5795, 0, 7354, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 49, 0, 89, 0, 89, 0, 74, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1138, 0, 278, 0, 2281, 0, 2812, 0, 3799, 0, 5795, 0, 7354, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 49, 0, 89, 0, 89, 0, 74, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1127, 0, 278, 0, 2281, 0, 2812, 0, 3799, 0, 5795, 0, 7354, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 49, 0, 89, 0, 89, 0, 74, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1116, 0, 278, 0, 2281, 0, 2812, 0, 3799, 0, 5795, 0, 7354, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 49, 0, 89, 0, 89, 0, 74, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1105, 0, 278, 0, 2281, 0, 2812, 0, 3799, 0, 5795, 0, 7354, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 49, 0, 89, 0, 89, 0, 74, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1094, 0, 278, 0, 2281, 0, 2812, 0, 3799, 0, 5795, 0, 7354, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 49, 0, 89, 0, 89, 0, 74, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1083, 0, 278, 0, 2281, 0, 2812, 0, 3799, 0, 5795, 0, 7354, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 49, 0, 89, 0, 89, 0, 74, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1072, 0, 278, 0, 2281, 0, 2812, 0, 3799, 0, 5795, 0, 7354, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 49, 0, 89, 0, 89, 0, 74, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 1061, 0, 235, 0, 1987, 0, 2058, 0, 2877, 0, 5298, 0, 6768, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 100, 50, 100, 50, 100, 50, 100, 35, 100, 0, 100, 0, 0, 60, 60 }}, {{ 1050, 0, 238, 0, 2002, 0, 2134, 0, 2950, 0, 5285, 0, 6756, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 100, 50, 100, 50, 100, 50, 100, 35, 100, 0, 100, 0, 0, 60, 60 }}, {{ 985, 0, 241, 0, 2025, 0, 2244, 0, 3056, 0, 5269, 0, 6741, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 37, 43, 49, 63, 60, 113, 55, 74, 42, 80, 34, 80, 0, 0, 51, 60 }}, {{ 920, 0, 247, 0, 2056, 0, 2385, 0, 3193, 0, 5258, 0, 6725, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 36, 41, 48, 66, 62, 123, 57, 76, 42, 80, 35, 80, 0, 0, 54, 60 }}, {{ 919, 0, 256, 0, 2094, 0, 2551, 0, 3356, 0, 5257, 0, 6714, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 35, 39, 48, 71, 65, 135, 59, 76, 43, 80, 35, 80, 0, 0, 57, 60 }}, {{ 918, 0, 264, 0, 2125, 0, 2675, 0, 3479, 0, 5269, 0, 6712, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 35, 37, 48, 74, 67, 144, 60, 76, 44, 80, 35, 80, 0, 0, 60, 60 }}, {{ 916, 0, 271, 0, 2147, 0, 2763, 0, 3568, 0, 5284, 0, 6715, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 36, 48, 77, 68, 150, 61, 76, 44, 80, 35, 80, 0, 0, 59, 60 }}, {{ 915, 0, 276, 0, 2162, 0, 2820, 0, 3625, 0, 5297, 0, 6718, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 35, 47, 79, 69, 154, 62, 75, 45, 80, 35, 80, 0, 0, 57, 60 }}, {{ 914, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 34, 47, 79, 70, 156, 62, 75, 45, 80, 35, 80, 0, 0, 54, 60 }}, {{ 912, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 34, 34, 47, 79, 70, 156, 62, 75, 45, 80, 35, 80, 0, 0, 50, 60 }}, {{ 911, 0, 302, 0, 2106, 0, 2821, 0, 3654, 0, 5360, 0, 6743, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 35, 35, 49, 79, 69, 151, 61, 73, 45, 80, 35, 80, 0, 0, 45, 60 }}, {{ 910, 0, 346, 0, 1982, 0, 2775, 0, 3659, 0, 5461, 0, 6786, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 36, 38, 51, 77, 68, 143, 60, 70, 45, 80, 36, 80, 0, 0, 39, 60 }}, {{ 909, 0, 409, 0, 1806, 0, 2724, 0, 3669, 0, 5594, 0, 6843, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 38, 41, 54, 75, 66, 131, 59, 65, 46, 80, 36, 80, 0, 0, 34, 60 }}, {{ 908, 0, 483, 0, 1590, 0, 2691, 0, 3691, 0, 5734, 0, 6905, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 40, 44, 57, 73, 64, 117, 57, 60, 46, 80, 37, 80, 0, 0, 30, 60 }}, {{ 906, 0, 533, 0, 1441, 0, 2692, 0, 3713, 0, 5813, 0, 6941, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 46, 59, 71, 62, 107, 56, 58, 47, 80, 38, 80, 0, 0, 27, 60 }}, {{ 905, 0, 562, 0, 1349, 0, 2705, 0, 3731, 0, 5853, 0, 6960, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 46, 60, 69, 61, 102, 55, 57, 47, 80, 39, 80, 0, 0, 25, 60 }}, {{ 904, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 47, 61, 69, 61, 99, 55, 56, 47, 80, 39, 80, 0, 0, 24, 60 }}, {{ 902, 0, 576, 0, 1305, 0, 2715, 0, 3741, 0, 5869, 0, 6968, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 47, 61, 69, 61, 99, 55, 56, 47, 80, 39, 80, 0, 0, 24, 60 }}, {{ 901, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 900, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 900, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 900, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 900, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 900, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 900, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 900, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 900, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 900, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 900, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 900, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 900, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 900, 0, 279, 0, 2170, 0, 2847, 0, 3653, 0, 5305, 0, 6720, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 34, 0, 79, 0, 156, 0, 75, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 900, 0, 462, 0, 1513, 0, 2553, 0, 3535, 0, 5746, 0, 6910, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 100, 50, 100, 50, 100, 50, 100, 35, 100, 0, 100, 0, 0, 60, 60 }}, {{ 900, 0, 466, 0, 1520, 0, 2560, 0, 3550, 0, 5757, 0, 6909, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 100, 50, 100, 50, 100, 50, 100, 35, 100, 0, 100, 0, 0, 60, 60 }}, {{ 870, 0, 474, 0, 1530, 0, 2570, 0, 3573, 0, 5773, 0, 6909, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 40, 49, 58, 68, 61, 104, 54, 62, 45, 80, 37, 80, 0, 0, 50, 60 }}, {{ 840, 0, 484, 0, 1544, 0, 2585, 0, 3603, 0, 5793, 0, 6911, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 49, 58, 68, 61, 103, 54, 62, 45, 80, 37, 80, 0, 0, 51, 60 }}, {{ 840, 0, 496, 0, 1563, 0, 2603, 0, 3638, 0, 5816, 0, 6916, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 49, 58, 68, 61, 102, 54, 62, 45, 80, 37, 80, 0, 0, 53, 60 }}, {{ 839, 0, 512, 0, 1587, 0, 2626, 0, 3679, 0, 5840, 0, 6927, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 50, 58, 69, 62, 101, 55, 63, 46, 80, 37, 80, 0, 0, 55, 60 }}, {{ 839, 0, 530, 0, 1616, 0, 2654, 0, 3722, 0, 5864, 0, 6945, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 58, 70, 62, 101, 55, 65, 46, 80, 38, 80, 0, 0, 57, 60 }}, {{ 839, 0, 552, 0, 1652, 0, 2686, 0, 3767, 0, 5885, 0, 6975, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 58, 72, 62, 102, 55, 67, 46, 80, 38, 80, 0, 0, 58, 60 }}, {{ 838, 0, 575, 0, 1691, 0, 2720, 0, 3808, 0, 5900, 0, 7012, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 58, 74, 63, 103, 56, 71, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 838, 0, 595, 0, 1726, 0, 2750, 0, 3840, 0, 5907, 0, 7053, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 58, 76, 63, 105, 56, 75, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 838, 0, 612, 0, 1758, 0, 2777, 0, 3864, 0, 5910, 0, 7092, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 50, 59, 78, 64, 108, 57, 79, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 837, 0, 627, 0, 1786, 0, 2800, 0, 3882, 0, 5910, 0, 7129, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 59, 79, 64, 110, 57, 83, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 837, 0, 640, 0, 1809, 0, 2819, 0, 3896, 0, 5908, 0, 7161, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 59, 81, 64, 112, 58, 87, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 837, 0, 649, 0, 1826, 0, 2833, 0, 3905, 0, 5905, 0, 7186, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 59, 82, 65, 113, 58, 90, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 836, 0, 655, 0, 1838, 0, 2843, 0, 3911, 0, 5903, 0, 7204, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 60, 83, 65, 115, 58, 91, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 836, 0, 658, 0, 1844, 0, 2848, 0, 3914, 0, 5901, 0, 7213, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 60, 83, 65, 115, 58, 92, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 836, 0, 658, 0, 1844, 0, 2848, 0, 3914, 0, 5901, 0, 7213, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 60, 83, 65, 115, 58, 92, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 835, 0, 658, 0, 1844, 0, 2848, 0, 3914, 0, 5899, 0, 7211, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 60, 83, 65, 115, 58, 92, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 835, 0, 655, 0, 1840, 0, 2845, 0, 3913, 0, 5895, 0, 7202, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 60, 83, 65, 114, 58, 92, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 835, 0, 651, 0, 1834, 0, 2841, 0, 3912, 0, 5890, 0, 7188, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 50, 59, 83, 65, 114, 58, 91, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 834, 0, 646, 0, 1827, 0, 2836, 0, 3910, 0, 5883, 0, 7171, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 51, 59, 82, 65, 112, 58, 91, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 834, 0, 639, 0, 1818, 0, 2829, 0, 3907, 0, 5874, 0, 7149, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 51, 59, 81, 64, 111, 58, 90, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 834, 0, 631, 0, 1807, 0, 2819, 0, 3903, 0, 5864, 0, 7124, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 52, 59, 80, 64, 109, 57, 88, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 833, 0, 622, 0, 1795, 0, 2807, 0, 3896, 0, 5853, 0, 7097, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 52, 59, 79, 64, 107, 57, 87, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 833, 0, 612, 0, 1781, 0, 2791, 0, 3886, 0, 5841, 0, 7066, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 53, 58, 78, 64, 105, 56, 86, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 833, 0, 602, 0, 1766, 0, 2772, 0, 3873, 0, 5829, 0, 7034, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 53, 58, 76, 63, 102, 56, 84, 44, 80, 39, 80, 0, 0, 60, 60 }}, {{ 832, 0, 590, 0, 1750, 0, 2748, 0, 3855, 0, 5816, 0, 7001, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 54, 58, 75, 63, 100, 55, 82, 45, 80, 39, 80, 0, 0, 60, 60 }}, {{ 832, 0, 578, 0, 1733, 0, 2719, 0, 3832, 0, 5804, 0, 6967, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 55, 58, 73, 62, 97, 55, 80, 45, 80, 39, 80, 0, 0, 60, 60 }}, {{ 832, 0, 565, 0, 1715, 0, 2684, 0, 3802, 0, 5792, 0, 6934, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 55, 57, 71, 62, 93, 54, 77, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 831, 0, 551, 0, 1697, 0, 2642, 0, 3766, 0, 5782, 0, 6902, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 55, 57, 70, 61, 89, 53, 75, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 831, 0, 538, 0, 1678, 0, 2592, 0, 3720, 0, 5773, 0, 6872, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 56, 57, 68, 60, 86, 52, 72, 45, 80, 38, 80, 0, 0, 60, 60 }}, {{ 831, 0, 524, 0, 1660, 0, 2533, 0, 3665, 0, 5766, 0, 6846, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 56, 57, 66, 60, 81, 52, 69, 46, 80, 38, 80, 0, 0, 60, 60 }}, {{ 830, 0, 512, 0, 1644, 0, 2473, 0, 3607, 0, 5762, 0, 6826, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 41, 56, 57, 64, 59, 77, 51, 67, 46, 80, 37, 80, 0, 0, 60, 60 }}, {{ 830, 0, 501, 0, 1630, 0, 2413, 0, 3548, 0, 5760, 0, 6813, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 55, 57, 62, 58, 74, 50, 64, 46, 80, 37, 80, 0, 0, 60, 60 }}, {{ 830, 0, 492, 0, 1618, 0, 2354, 0, 3489, 0, 5761, 0, 6804, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 55, 57, 60, 57, 70, 49, 62, 46, 80, 36, 80, 0, 0, 60, 60 }}, {{ 830, 0, 484, 0, 1608, 0, 2297, 0, 3430, 0, 5763, 0, 6799, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 54, 57, 59, 56, 67, 49, 60, 46, 80, 36, 80, 0, 0, 60, 60 }}, {{ 830, 0, 477, 0, 1599, 0, 2242, 0, 3374, 0, 5766, 0, 6797, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 42, 54, 57, 58, 55, 65, 48, 58, 46, 80, 36, 80, 0, 0, 60, 60 }}, {{ 830, 0, 471, 0, 1592, 0, 2191, 0, 3321, 0, 5770, 0, 6797, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 53, 57, 57, 54, 62, 48, 57, 47, 80, 35, 80, 0, 0, 60, 60 }}, {{ 830, 0, 467, 0, 1586, 0, 2144, 0, 3272, 0, 5774, 0, 6799, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 53, 57, 56, 54, 60, 47, 55, 47, 80, 35, 80, 0, 0, 60, 60 }}, {{ 830, 0, 463, 0, 1581, 0, 2101, 0, 3227, 0, 5779, 0, 6802, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 52, 57, 55, 53, 58, 47, 54, 47, 80, 35, 80, 0, 0, 60, 60 }}, {{ 830, 0, 459, 0, 1578, 0, 2063, 0, 3188, 0, 5783, 0, 6806, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 52, 57, 54, 53, 56, 46, 53, 47, 80, 35, 80, 0, 0, 60, 60 }}, {{ 830, 0, 457, 0, 1574, 0, 2031, 0, 3154, 0, 5787, 0, 6810, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 43, 51, 58, 54, 52, 55, 46, 52, 47, 80, 35, 80, 0, 0, 60, 60 }}, {{ 830, 0, 455, 0, 1572, 0, 2005, 0, 3126, 0, 5790, 0, 6813, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 51, 58, 53, 52, 54, 46, 52, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 830, 0, 453, 0, 1570, 0, 1986, 0, 3105, 0, 5793, 0, 6816, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 51, 58, 53, 52, 53, 46, 51, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1972, 0, 3091, 0, 5795, 0, 6818, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 46, 51, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 60, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 53, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 47, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 40, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 33, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 27, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 20, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 14, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 44, 50, 58, 53, 51, 52, 45, 50, 47, 80, 34, 80, 0, 0, 7, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 452, 0, 1569, 0, 1966, 0, 3084, 0, 5796, 0, 6819, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 50, 0, 53, 0, 52, 0, 50, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 920, 0, 1445, 0, 2804, 0, 3915, 0, 5969, 0, 6256, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 87, 0, 62, 0, 103, 0, 105, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 920, 0, 1445, 0, 2804, 0, 3915, 0, 5969, 0, 6256, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 87, 0, 62, 0, 103, 0, 105, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 920, 0, 1445, 0, 2804, 0, 3915, 0, 5969, 0, 6256, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 87, 0, 62, 0, 103, 0, 105, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 920, 0, 1445, 0, 2804, 0, 3915, 0, 5969, 0, 6256, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 87, 0, 62, 0, 103, 0, 105, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 920, 0, 1445, 0, 2804, 0, 3915, 0, 5969, 0, 6256, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 87, 0, 62, 0, 103, 0, 105, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 920, 0, 1445, 0, 2804, 0, 3915, 0, 5969, 0, 6256, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 87, 0, 62, 0, 103, 0, 105, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 920, 0, 1445, 0, 2804, 0, 3915, 0, 5969, 0, 6256, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 87, 0, 62, 0, 103, 0, 105, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 920, 0, 1445, 0, 2804, 0, 3915, 0, 5969, 0, 6256, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 87, 0, 62, 0, 103, 0, 105, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 920, 0, 1445, 0, 2804, 0, 3915, 0, 5969, 0, 6256, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 87, 0, 62, 0, 103, 0, 105, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 920, 0, 1445, 0, 2804, 0, 3915, 0, 5969, 0, 6256, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 87, 0, 62, 0, 103, 0, 105, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 920, 0, 1445, 0, 2804, 0, 3915, 0, 5969, 0, 6256, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 87, 0, 62, 0, 103, 0, 105, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 920, 0, 1445, 0, 2804, 0, 3915, 0, 5969, 0, 6256, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 87, 0, 62, 0, 103, 0, 105, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 920, 0, 1445, 0, 2804, 0, 3915, 0, 5969, 0, 6256, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 87, 0, 62, 0, 103, 0, 105, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 920, 0, 1445, 0, 2804, 0, 3915, 0, 5969, 0, 6256, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 87, 0, 62, 0, 103, 0, 105, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 920, 0, 1445, 0, 2804, 0, 3915, 0, 5969, 0, 6256, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 87, 0, 62, 0, 103, 0, 105, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 920, 0, 1445, 0, 2804, 0, 3915, 0, 5969, 0, 6256, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 87, 0, 62, 0, 103, 0, 105, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 920, 0, 1445, 0, 2804, 0, 3915, 0, 5969, 0, 6256, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 87, 0, 62, 0, 103, 0, 105, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 920, 0, 1445, 0, 2804, 0, 3915, 0, 5969, 0, 6256, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 87, 0, 62, 0, 103, 0, 105, 0, 80, 0, 80, 0, 0, 0, 60 }}, {{ 830, 0, 920, 0, 1445, 0, 2804, 0, 3915, 0, 5969, 0, 6256, 0, 0, 0, 200, 30, 0, 60, 0, 0, 0, 0, 0, 87, 0, 62, 0, 103, 0, 105, 0, 80, 0, 80, 0, 0, 0, 60 }} }; try { autoKlattTable me = (KlattTable) Thing_new (KlattTable); Table_initWithColumnNames (me.peek(), nrows, columnNames); for (long irow = 1; irow <= nrows; irow++) { for (long jcol = 1; jcol <= KlattTable_NPAR; jcol++) { double val = klatt_data[irow - 1].p[jcol - 1]; if (jcol > 3 && jcol < 13 && (jcol % 2 == 0) && val <= 0) { // bw == 0? val = klatt_data[irow - 1].p[jcol] / 10; } Table_setNumericValue ( (Table) me.peek(), irow, jcol, val); } } return me; } catch (MelderError) { Melder_throw (U" KlattTable example not created."); } } autoKlattTable Table_to_KlattTable (Table me) { try { if (my numberOfColumns != KlattTable_NPAR) { Melder_throw (U"A KlattTable needs ", KlattTable_NPAR, U" columns."); } autoKlattTable thee = Thing_new (KlattTable); my structTable :: v_copy (thee.peek()); return thee; } catch (MelderError) { Melder_throw (U"KlattTable not created from Table."); } } autoTable KlattTable_to_Table (KlattTable me) { try { autoTable thee = Thing_new (Table); my structTable :: v_copy (thee.peek()); return thee; } catch (MelderError) { Melder_throw (U"Table not created from KlattTable."); } } /* End of file KlattTable.cpp */ praat-6.0.04/dwtools/KlattTable.h000066400000000000000000000110441261542461700166130ustar00rootroot00000000000000#ifndef _KlattTable_h_ #define _KlattTable_h_ /* KlattTable.h * * Copyright (C) 2008-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20081018 Initial version djmw 20110306 Latest modification */ #include "TableOfReal.h" #include "Sound.h" #include "Table.h" Thing_define (KlattTable, Table) { }; autoKlattTable KlattTable_create (double frameDuration, double totalDuration); /* f0 (08) This is the fundamental frequency (pitch) of the utterance. In this case it is specified in steps of 0.1 Hz, hence 100Hz will be represented by a value of 1000. av (08) Amplitude of voicing for the cascade branch of the synthesizer in dB0. Range 0-70, value usually 60 for a vowel sound. f1 (08) First formant frequency in 200-1300 Hz. b1 (08) Cascade branch bandwidth of first formant in the range 40-1000 Hz. f2 (08) Second formant frequency in the range 550 - 3000 Hz. b2 (08) Cascade branch bandwidth of second formant in the range 40-1000 Hz. f3 (08) Third formant frequency in the range 1200-4999 Hz. b3 (08) Cascade branch bandwidth of third formant in the range 40-1000 Hz. f4 (08) Fourth formant frequency in 1200-4999 Hz. b4 (08) Cascade branch bandwidth of fourth formant in the range 40-1000 Hz. f5 (08) Fifth formant frequency in the range 1200-4999 Hz. b5 (08) Cascade branch bandwidth of fifth formant in the range 40-1000 Hz. f6 (08) Sixth formant frequency in the range 1200-4999 Hz. b6 (08) Cascade branch bandwidth of sixth formant in the range 40-2000 Hz. fnz (08) Frequency of the nasal zero in the range 248-528 Hz. (cascade branch only) bnz (08) Bandwidth of the nasal zero in the range 40-1000 Hz (cascade branch only) fnp (08) Frequency of the nasal pole in the range 248-528 Hz bnp (08) Bandwidth of the nasal pole in the range 40-1000 Hz ah (08) Amplitude of aspiration 0-70 dB. kopen (-8) Open quotient of voicing waveform, range 0-60, usually 30. Will influence the gravelly or smooth quality of the voice. Only works with impulse and antural simulations. For the sampled glottal excitation waveform the open quotient is fixed. aturb Amplitude of turbulence 0-80 dB. A value of 40 is useful. Can be used to simulate "breathy" voice quality. tltdb (-8) Spectral tilt in dB, range 0-24. Tilts down the output spectrum. The value refers to dB down at 3Khz. Increasing the value emphasizes the low frequency content of the speech and attenuates the high frequency content. af (08) Amplitude of frication in dB, range 0-80 (parallel branch) skew Spectral Skew - skewness of alternate periods, range 0-40 a1 (08) Amplitude of first formant in the parallel branch, in 0-80 dB. b1p (-8) Bandwidth of the first formant in the parallel branch, in Hz. a2 (08) Amplitude of parallel branch second formant. b2p (-8) Bandwidth of parallel branch second formant. a3 (08) Amplitude of parallel branch third formant. b3p (-8) Bandwidth of parallel branch third formant. a4 (08) Amplitude of parallel branch fourth formant. b4p (-8) Bandwidth of parallel branch fourth formant. a5 (08) Amplitude of parallel branch fifth formant. b5p (-8) Bandwidth of parallel branch fifth formant. a6 (08) Amplitude of parallel branch sixth formant. b6p (-8) Bandwidth of parallel branch sixth formant. anp Amplitude of the parallel branch nasal formant. ab (08) Amplitude of bypass frication in dB. 0-80. avp Amplitude of voicing for the parallel branch, 0-70 dB. gain Overall gain in dB range 0-80. */ autoSound KlattTable_to_Sound (KlattTable me, double samplingFrequency, int synthesisModel, int numberOfFormants, double frameDuration, int voicing, double flutter, int outputType); autoSound KlattTable_and_Sound_to_Sound (KlattTable me, Sound thee); autoKlattTable KlattTable_createExample (); autoKlattTable Table_to_KlattTable (Table me); autoTable KlattTable_to_Table (KlattTable me); autoKlattTable KlattTable_readFromRawTextFile (MelderFile fs); #endif /* _KlattTable_h_ */ praat-6.0.04/dwtools/LFCC.cpp000066400000000000000000000024541261542461700156330ustar00rootroot00000000000000/* LFCC.cpp * * Linear Frequency Cepstral Coefficients class. * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20001228 djmw 20020813 GPL header djmw 20110304 Thing_new */ #include "LFCC.h" Thing_implement (LFCC, CC, 1); autoLFCC LFCC_create (double tmin, double tmax, long nt, double dt, double t1, long maximumNumberOfCoefficients, double fmin, double fmax) { try { autoLFCC me = Thing_new (LFCC); CC_init (me.peek(), tmin, tmax, nt, dt, t1, maximumNumberOfCoefficients, fmin, fmax); return me; } catch (MelderError) { Melder_throw (U"LFCC not created."); } } /* End of file LFCC.cpp */ praat-6.0.04/dwtools/LFCC.h000066400000000000000000000021721261542461700152750ustar00rootroot00000000000000#ifndef _LFCC_h_ #define _LFCC_h_ /* LFCC.h * * Linear Frequency Cepstral Coefficients class. * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20001213 djmw 20020813 GPL header djmw 20110306 Latest modification. */ #include "CC.h" Thing_define (LFCC, CC) { }; autoLFCC LFCC_create (double tmin, double tmax, long nt, double dt, double t1, long maximumNumberOfCoefficients, double fmin, double fmax); #endif /* _LFCC_h_ */ praat-6.0.04/dwtools/LongSound_extensions.cpp000066400000000000000000000230341261542461700213100ustar00rootroot00000000000000/* LongSound_extensions.c * * Copyright (C) 1993-2013, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020627 GPL header djmw 20030913 changed 'f' to 'file' as argument in Melder_checkSoundFile djmw 20060206 Set errno = 0: "An application that needs to examine the value of errno to determine the error should set it to 0 before a function call, then inspect it before a subsequent function call." djmw 20061213 MelderFile_truncate also works for MacOS X djmw 20061212 Header unistd.h for MacOS X added. djmw 20070129 Sounds may be multichannel djmw 20071030 MelderFile->wpath to MelderFile->path */ #include "LongSound_extensions.h" #if defined (_WIN32) #include "winport_on.h" #include #include "winport_off.h" #elif defined(linux) #include #include #include #elif defined (macintosh) #include #endif #include "NUM2.h" #include /* Precondition: size (my buffer) >= nbuf */ static void _LongSound_to_multichannel_buffer (LongSound me, short *buffer, long nbuf, int nchannels, int ichannel, long ibuf) { long numberOfReads = (my nx - 1) / nbuf + 1; long n_to_read = 0; if (ibuf <= numberOfReads) { n_to_read = ibuf == numberOfReads ? (my nx - 1) % nbuf + 1 : nbuf; long imin = (ibuf - 1) * nbuf + 1; LongSound_readAudioToShort (me, my buffer, imin, n_to_read); for (long i = 1; i <= n_to_read; i++) { buffer[nchannels * (i - 1) + ichannel] = my buffer[i]; } } if (ibuf >= numberOfReads) { for (long i = n_to_read + 1; i <= nbuf; i++) { buffer[nchannels * (i - 1) + ichannel] = 0; } } } void LongSounds_writeToStereoAudioFile16 (LongSound me, LongSound thee, int audioFileType, MelderFile file) { try { long nbuf = my nmax < thy nmax ? my nmax : thy nmax; long nx = my nx > thy nx ? my nx : thy nx; long numberOfReads = (nx - 1) / nbuf + 1, numberOfBitsPerSamplePoint = 16; if (thy numberOfChannels != my numberOfChannels || my numberOfChannels != 1) { Melder_throw (U"LongSounds should be mono."); } if (my sampleRate != thy sampleRate) { Melder_throw (U"Sample rates should be equal."); } /* Allocate a stereo buffer of size (2 * the smallest)! WE SUPPOSE THAT SMALL IS LARGE ENOUGH. Read the same number of samples from both files, despite potential differences in internal buffer size. */ long nchannels = 2; autoNUMvector buffer (1, nchannels * nbuf); autoMelderFile f = MelderFile_create (file); MelderFile_writeAudioFileHeader (file, audioFileType, (long) floor (my sampleRate), nx, nchannels, numberOfBitsPerSamplePoint); for (long i = 1; i <= numberOfReads; i++) { long n_to_write = i == numberOfReads ? (nx - 1) % nbuf + 1 : nbuf; _LongSound_to_multichannel_buffer (me, buffer.peek(), nbuf, nchannels, 1, i); _LongSound_to_multichannel_buffer (thee, buffer.peek(), nbuf, nchannels, 2, i); MelderFile_writeShortToAudio (file, nchannels, Melder_defaultAudioFileEncoding (audioFileType, numberOfBitsPerSamplePoint), buffer.peek(), n_to_write); } MelderFile_writeAudioFileTrailer (file, audioFileType, (long) floor (my sampleRate), nx, nchannels, numberOfBitsPerSamplePoint); f.close (); } catch (MelderError) { Melder_throw (me, U": no stereo audio file created."); } } /* BSD systems provide ftruncate, several others supply chsize, and a few may provide a (possibly undocumented) fcntl option F_FREESP. Under MS-DOS, you can sometimes use write(fd, "", 0). However, there is no portable solution, nor a way to delete blocks at the beginning. */ static void MelderFile_truncate (MelderFile me, long size) { #if defined(_WIN32) HANDLE hFile; DWORD fdwAccess = GENERIC_READ | GENERIC_WRITE, fPos; DWORD fdwShareMode = 0; /* File cannot be shared */ LPSECURITY_ATTRIBUTES lpsa = nullptr; DWORD fdwCreate = OPEN_EXISTING; LARGE_INTEGER fileSize; MelderFile_close (me); hFile = CreateFileW (Melder_peek32toW (my path), fdwAccess, fdwShareMode, lpsa, fdwCreate, FILE_ATTRIBUTE_NORMAL, nullptr); if (hFile == INVALID_HANDLE_VALUE) { Melder_throw (U"Can't open file ", me, U"."); } // Set current file pointer to position 'size' fileSize.LowPart = size; fileSize.HighPart = 0; /* Limit the file size to 2^32 - 2 bytes */ fPos = SetFilePointer (hFile, fileSize.LowPart, &fileSize.HighPart, FILE_BEGIN); if (fPos == 0xFFFFFFFF) { Melder_throw (U"Can't set the position at size ", size, U"for file ", me, U"."); } // Limit the file size as the current position of the file pointer. SetEndOfFile (hFile); CloseHandle (hFile); #elif defined(linux) || defined(macintosh) MelderFile_close (me); if (truncate (Melder_peek32to8 (my path), size) == -1) { Melder_throw (U"Truncating failed for file ", MelderFile_messageName (me), U" (", Melder_peek8to32 (strerror (errno)), U")."); } #else Melder_throw (U"Don't know what to do."); #endif } static void writePartToOpenFile16 (LongSound me, int audioFileType, long imin, long n, MelderFile file) { long offset = imin; long numberOfBuffers = (n - 1) / my nmax + 1, numberOfBitsPerSamplePoint = 16; long numberOfSamplesInLastBuffer = (n - 1) % my nmax + 1; if (file -> filePointer) { for (long ibuffer = 1; ibuffer <= numberOfBuffers; ibuffer ++) { long numberOfSamplesToCopy = ibuffer < numberOfBuffers ? my nmax : numberOfSamplesInLastBuffer; LongSound_readAudioToShort (me, my buffer, offset, numberOfSamplesToCopy); offset += numberOfSamplesToCopy; MelderFile_writeShortToAudio (file, my numberOfChannels, Melder_defaultAudioFileEncoding (audioFileType, numberOfBitsPerSamplePoint), my buffer, numberOfSamplesToCopy); } } /* * We "have" no samples any longer. */ my imin = 1; my imax = 0; } void LongSounds_appendToExistingSoundFile (Collection me, MelderFile file) { long pre_append_endpos = 0, numberOfBitsPerSamplePoint = 16; try { if (my size < 1) { Melder_throw (U"No Sound or LongSound objects to append."); } /* We have to open with "r+" mode because this will position the stream at the beginning of the file. The "a" mode does not allow us to seek before the end-of-file. For Linux: If the file is already opened (e.g. by a LongSound) object we should deny access! Under Windows deny access is default?! */ autofile f = Melder_fopen (file, "r+b"); file -> filePointer = f; // essential !! double sampleRate_d; long startOfData; int32 numberOfSamples; int numberOfChannels, encoding; int audioFileType = MelderFile_checkSoundFile (file, &numberOfChannels, &encoding, &sampleRate_d, &startOfData, &numberOfSamples); if (audioFileType == 0) { Melder_throw (U"Not a sound file."); } // Check whether all the sample rates and channels match. long sampleRate = (long) floor (sampleRate_d); for (long i = 1; i <= my size; i++) { int sampleRatesMatch, numbersOfChannelsMatch; Sampled data = (Sampled) my item [i]; if (data -> classInfo == classSound) { Sound sound = (Sound) data; sampleRatesMatch = floor (1.0 / sound -> dx + 0.5) == sampleRate; numbersOfChannelsMatch = sound -> ny == numberOfChannels; numberOfSamples += sound -> nx; } else { LongSound longSound = (LongSound) data; sampleRatesMatch = longSound -> sampleRate == sampleRate; numbersOfChannelsMatch = longSound -> numberOfChannels == numberOfChannels; numberOfSamples += longSound -> nx; } if (! sampleRatesMatch) { Melder_throw (U"Sample rates do not match."); } if (! numbersOfChannelsMatch) { Melder_throw (U"Cannot mix stereo and mono."); } } // Search the end of the file, count the number of bytes and append. MelderFile_seek (file, 0, SEEK_END); pre_append_endpos = MelderFile_tell (file); errno = 0; for (long i = 1; i <= my size; i++) { Sampled data = (Sampled) my item [i]; if (data -> classInfo == classSound) { Sound sound = (Sound) data; MelderFile_writeFloatToAudio (file, sound -> ny, Melder_defaultAudioFileEncoding (audioFileType, numberOfBitsPerSamplePoint), sound -> z, sound -> nx, true); } else { LongSound longSound = (LongSound) data; writePartToOpenFile16 (longSound, audioFileType, 1, longSound -> nx, file); } if (errno != 0) { Melder_throw (U"Error during writing."); } } // Update header MelderFile_rewind (file); MelderFile_writeAudioFileHeader (file, audioFileType, sampleRate, numberOfSamples, numberOfChannels, numberOfBitsPerSamplePoint); MelderFile_writeAudioFileTrailer (file, audioFileType, sampleRate, numberOfSamples, numberOfChannels, numberOfBitsPerSamplePoint); f.close (file); return; } catch (MelderError) { if (errno != 0 && pre_append_endpos > 0) { // Restore file at original size int error = errno; MelderFile_truncate (file, pre_append_endpos); Melder_throw (U"File ", MelderFile_messageName (file), U" restored to original size (", Melder_peek8to32 (strerror (error)), U")."); } throw; } } /* End of file LongSound_extensions.cpp */ praat-6.0.04/dwtools/LongSound_extensions.h000066400000000000000000000022261261542461700207550ustar00rootroot00000000000000#ifndef _LongSound_extensions_h_ #define _LongSound_extensions_h_ /* LongSound_extensions.h * * Copyright (C) 1993-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020627 djmw 20020813 GPL header djmw 20110702 Latest modification */ #include "LongSound.h" void LongSounds_writeToStereoAudioFile16 (LongSound me, LongSound thee, int audioFileType, MelderFile file); void LongSounds_appendToExistingSoundFile (Collection me, MelderFile file); #endif /* _LongSound_extensions_h_ */ praat-6.0.04/dwtools/Ltas_extensions.cpp000066400000000000000000000032321261542461700203010ustar00rootroot00000000000000/* Ltas_extensions.cpp * * Copyright (C) 2012-2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Ltas_extensions.h" #include "NUM2.h" void Ltas_fitTiltLine (Ltas me, double fmin, double fmax, bool lnf, int method, double *a, double *b) { try { if (fmax <= fmin) { fmin = my xmin; fmax = my xmax; } long ifmin, ifmax, numberOfSamples = Sampled_getWindowSamples (me, fmin, fmax, &ifmin, &ifmax); if (numberOfSamples < 2) { Melder_throw (U"There must be at least two data points to fit a line."); } autoNUMvector x (1, numberOfSamples); autoNUMvector y (1, numberOfSamples); for (long i = ifmin; i <= ifmax; i++) { long ixy = i - ifmin + 1; x[ixy] = my x1 + (i - 1) * my dx; if (lnf) { // For Ltas always x1 > 0 x[ixy] = log10 (x[ixy]); } y[ixy] = my z[1][i]; } NUMlineFit (x.peek(), y.peek(), numberOfSamples, a, b, method); } catch (MelderError) { Melder_throw (U"Tilt line not determined."); } } /* End of file Ltas_extensions.cpp */ praat-6.0.04/dwtools/Ltas_extensions.h000066400000000000000000000017261261542461700177540ustar00rootroot00000000000000#ifndef _Ltas_extensions_h_ #define _Ltas_extensions_h_ /* Ltas_extensions.h * * Copyright (C) 2012-2013 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Ltas.h" void Ltas_fitTiltLine (Ltas me, double fmin, double fmax, bool lnf, int method, double *a, double *b); #endif /* _Ltas_extensions_h_ */ praat-6.0.04/dwtools/MDS.cpp000066400000000000000000003201621261542461700155460ustar00rootroot00000000000000/* MDS.cpp * * Copyright (C) 1993-2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020408 GPL djmw 20020513 Applied TableOfReal_setSequential{Column/Row}Labels djmw 20030623 Modified calls to NUMeigensystem_d djmw 20040309 Extra tests for empty objects. djmw 20061218 Changed to Melder_information format. djmw 20071022 Removed unused code. djmw 20071106 drawSplines: to wchar djmw 20071201 Melder_warning djmw 20071213 Removed Preference. djmw 20080724 Thing_classNameW ->Thing_className djmw 20110304 Thing_new */ #include "SVD.h" #include "Matrix_extensions.h" #include "TableOfReal_extensions.h" #include "MDS.h" #include "SSCP.h" #include "PCA.h" #define TINY 1e-30 /********************** NUMERICAL STUFF **************************************/ static void NUMdmatrix_into_vector (double **m, double *v, long r1, long r2, long c1, long c2) { long k = 1; for (long i = r1; i <= r2; i++) { for (long j = c1; j <= c2; j++) { v[k++] = m[i][j]; } } } static void NUMdvector_into_matrix (const double *v, double **m, long r1, long r2, long c1, long c2) { long k = 1; for (long i = r1; i <= r2; i++) { for (long j = c1; j <= c2; j++) { m[i][j] = v[k++]; } } } static void NUMdmatrix_normalizeRows (double **m, long nr, long nc) { for (long i = 1; i <= nr; i++) { double rowSum = 0.0; for (long j = 1; j <= nc; j++) { rowSum += m[i][j]; } if (rowSum != 0.0) { for (long j = 1; j <= nc; j++) { m[i][j] /= rowSum; } } } } static long NUMdmatrix_countZeros (double **m, long nr, long nc) { long nZeros = 0; for (long i = 1; i <= nr; i++) { for (long j = 1; j <= nc; j++) { if (m[i][j] == 0) { nZeros++; } } } return nZeros; } static void NUMsort3 (double *data, long *iPoint, long *jPoint, long ifrom, long ito, int ascending) { if (ifrom > ito || ifrom < 1) { Melder_throw (U"invalid range."); } long n = ito - ifrom + 1; if (n == 1) { return; } autoNUMvector indx (ifrom, ito); autoNUMvector atmp (ifrom, ito); autoNUMvector itmp (ifrom, ito); //NUMindexx (data + ifrom - 1, n, indx + ifrom - 1); NUMindexx (&data [ifrom - 1], n, &indx [ifrom - 1]); if (! ascending) { for (long j = ifrom; j <= ifrom + n / 2; j++) { long tmp = indx[j]; indx[j] = indx[ito - j + ifrom]; indx[ito - j + ifrom] = tmp; } } for (long j = ifrom; j <= ito; j++) { indx[j] += ifrom - 1; } for (long j = ifrom; j <= ito; j++) { atmp[j] = data[j]; } for (long j = ifrom; j <= ito; j++) { data[j] = atmp[indx[j]]; } for (long j = ifrom; j <= ito; j++) { itmp[j] = iPoint[j]; } for (long j = ifrom; j <= ito; j++) { iPoint[j] = itmp[indx[j]]; } for (long j = ifrom; j <= ito; j++) { itmp[j] = jPoint[j]; } for (long j = ifrom; j <= ito; j++) { jPoint[j] = itmp[indx[j]]; } } /************ Configurations & Similarity **************************/ Distances Configurations_to_Distances (Configurations me) { try { autoDistances thee = Distances_create (); for (long i = 1; i <= my size; i++) { Configuration conf = (Configuration) (my item[i]); autoDistance d = Configuration_to_Distance (conf); Thing_setName (d.peek(), Thing_getName (conf)); Collection_addItem (thee.peek(), d.transfer()); } return thee.transfer(); } catch (MelderError) { Melder_throw (U"Distances not created form Configurations."); } } Similarity Configurations_to_Similarity_cc (Configurations me, Weight weight) { try { autoDistances d = Configurations_to_Distances (me); autoSimilarity thee = Distances_to_Similarity_cc (d.peek(), weight); return thee.transfer(); } catch (MelderError) { Melder_throw (U"Similarity not created form Configurations."); } } Similarity Distances_to_Similarity_cc (Distances me, Weight w) { try { if (my size == 0) { Melder_throw (U"Distances is empty."); } if (! TablesOfReal_checkDimensions (me)) { Melder_throw (U"All matrices must have the same dimensions."); } autoWeight aw; if (! w) { aw.reset (Weight_create (((Distance) (my item[1])) -> numberOfRows)); w = aw.peek(); } autoSimilarity thee = Similarity_create (my size); for (long i = 1; i <= my size; i++) { Distance di = (Distance) (my item[i]); char32 *name = Thing_getName (di); TableOfReal_setRowLabel (thee.peek(), i, name); TableOfReal_setColumnLabel (thee.peek(), i, name); thy data[i][i] = 1; for (long j = i + 1; j <= my size; j++) { Distance dj = (Distance) (my item[j]); thy data[i][j] = thy data[j][i] = Distance_Weight_congruenceCoefficient (di, dj, w); } } return thee.transfer(); } catch (MelderError) { Melder_throw (U"Similarity not created form Distancess."); } } /***************** Transformator **********************************************/ Thing_implement (Transformator, Thing, 0); Distance structTransformator :: v_transform (MDSVec vec, Distance dist, Weight /* w */) { try { autoDistance thee = Distance_create (numberOfPoints); TableOfReal_copyLabels (dist, thee.peek(), 1, 1); // Absolute scaling for (long i = 1; i <= vec -> nProximities; i++) { long ii = vec -> iPoint[i]; long jj = vec -> jPoint[i]; thy data[ii][jj] = thy data[jj][ii] = vec -> proximity[i]; } return thee.transfer(); } catch (MelderError) { Melder_throw (U"Distance not created."); } } void Transformator_init (Transformator me, long numberOfPoints) { my numberOfPoints = numberOfPoints; my normalization = 1; } Transformator Transformator_create (long numberOfPoints) { try { autoTransformator me = Thing_new (Transformator); Transformator_init (me.peek(), numberOfPoints); my normalization = 0; return me.transfer(); } catch (MelderError) { Melder_throw (U"No Transformator created."); } } Distance Transformator_transform (Transformator me, MDSVec vec, Distance d, Weight w) { try { if (my numberOfPoints != vec -> nPoints || my numberOfPoints != d -> numberOfRows || d -> numberOfRows != w -> numberOfRows) { Melder_throw (U"Dimensions do not agree."); } return my v_transform (vec, d, w); } catch (MelderError) { Melder_throw (me, U"Distance not created."); } } Thing_implement (RatioTransformator, Transformator, 0); Distance structRatioTransformator :: v_transform (MDSVec vec, Distance d, Weight w) { autoDistance thee = Distance_create (numberOfPoints); TableOfReal_copyLabels (d, thee.peek(), 1, 1); // Determine ratio (eq. 9.4) double etaSq = 0.0, rho = 0.0; for (long i = 1; i <= vec -> nProximities; i++) { long ii = vec -> iPoint[i]; long jj = vec -> jPoint[i]; double delta_ij = vec -> proximity[i], d_ij = d -> data[ii][jj]; double tmp = w -> data[ii][jj] * delta_ij * delta_ij; etaSq += tmp; rho += tmp * d_ij * d_ij; } // transform if (etaSq == 0.0) { Melder_throw (U"Eta squared is zero."); } this -> ratio = rho / etaSq; for (long i = 1; i <= vec -> nProximities; i++) { long ii = vec -> iPoint[i]; long jj = vec -> jPoint[i]; thy data[ii][jj] = thy data[jj][ii] = this -> ratio * vec -> proximity[i]; } if (normalization) { Distance_Weight_smacofNormalize (thee.peek(), w); } return thee.transfer(); } RatioTransformator RatioTransformator_create (long numberOfPoints) { try { autoRatioTransformator me = Thing_new (RatioTransformator); Transformator_init (me.peek(), numberOfPoints); return me.transfer(); } catch (MelderError) { Melder_throw (U"RatioTransformator not created."); } } Thing_implement (MonotoneTransformator, Transformator, 0); Distance structMonotoneTransformator :: v_transform (MDSVec vec, Distance d, Weight w) { try { autoDistance thee = MDSVec_Distance_monotoneRegression (vec, d, tiesProcessing); if (normalization) { Distance_Weight_smacofNormalize (thee.peek(), w); } return thee.transfer(); } catch (MelderError) { Melder_throw (U"Distance not created."); } } MonotoneTransformator MonotoneTransformator_create (long numberOfPoints) { try { autoMonotoneTransformator me = Thing_new (MonotoneTransformator); Transformator_init (me.peek(), numberOfPoints); my tiesProcessing = MDS_PRIMARY_APPROACH; return me.transfer(); } catch (MelderError) { Melder_throw (U"MonotoneTransformator not created."); } } void MonotoneTransformator_setTiesProcessing (MonotoneTransformator me, int tiesProcessing) { my tiesProcessing = tiesProcessing; } Thing_implement (ISplineTransformator, Transformator, 0); void structISplineTransformator :: v_destroy () { NUMvector_free (b, 1); NUMvector_free (knot, 1); NUMmatrix_free (m, 1, 1); ISplineTransformator_Parent :: v_destroy (); } Distance structISplineTransformator :: v_transform (MDSVec vec, Distance dist, Weight w) { double tol = 1e-6; long itermax = 20, nx = vec -> nProximities; long nKnots = numberOfInteriorKnots + order + order + 2; autoDistance thee = Distance_create (dist -> numberOfRows); TableOfReal_copyLabels (dist, thee.peek(), 1, -1); autoNUMvector d (1, nx); for (long i = 1; i <= nx; i++) { d[i] = dist -> data[vec -> iPoint[i]][vec -> jPoint[i]]; } /* Process knots. Put interior knots at quantiles. Guarantee that for each proximity x[i]: knot[j] <= x[i] < knot[j+1] */ for (long i = 1; i <= order + 1; i++) { knot [i] = vec -> proximity [1]; knot [nKnots - i + 1] = vec -> proximity [nx] * 1.000001; } for (long i = 1; i <= numberOfInteriorKnots; i++) { double fraction = (double) i / (numberOfInteriorKnots + 1); knot [order + 1 + i] = NUMquantile (nx, vec -> proximity, fraction); } // Calculate data matrix m. for (long i = 1; i <= nx; i++) { double y, x = vec -> proximity [i]; m[i][1] = 1.0; for (long j = 2; j <= numberOfParameters; j++) { try { NUMispline (knot, nKnots, order, j - 1, x, & y); } catch (MelderError) { Melder_throw (U"I-spline[", j - 1, U"], data[", i, U"d] = ", x); } m[i][j] = y; } } NUMsolveNonNegativeLeastSquaresRegression (m, nx, numberOfParameters, d.peek(), tol, itermax, b); for (long i = 1; i <= nx; i++) { long ii = vec->iPoint[i]; long jj = vec->jPoint[i]; double r = 0.0; for (long j = 1; j <= numberOfParameters; j++) { r += m[i][j] * b[j]; } thy data[ii][jj] = thy data[jj][ii] = r; } if (normalization) { Distance_Weight_smacofNormalize (thee.peek(), w); } return thee.transfer(); } ISplineTransformator ISplineTransformator_create (long numberOfPoints, long numberOfInteriorKnots, long order) { try { autoISplineTransformator me = Thing_new (ISplineTransformator); long nData = (numberOfPoints - 1) * numberOfPoints / 2; Transformator_init (me.peek(), numberOfPoints); /* 1 extra parameter for the intercept. 2 extra knots for the I-spline. */ my numberOfParameters = numberOfInteriorKnots + order + 1; long numberOfKnots = numberOfInteriorKnots + order + order + 2; my b = NUMvector (1, my numberOfParameters); my knot = NUMvector (1, numberOfKnots); my m = NUMmatrix (1, nData, 1, my numberOfParameters); for (long i = 1; i <= my numberOfParameters; i++) { my b[i] = NUMrandomUniform (0.0, 1.0); } my numberOfInteriorKnots = numberOfInteriorKnots; my order = order; return me.transfer(); } catch (MelderError) { Melder_throw (U"ISplineTransformator not created."); } } /***************** CONTINGENCYTABLE **************************************/ Configuration ContingencyTable_to_Configuration_ca (ContingencyTable me, long numberOfDimensions, int scaling) { try { long nr = my numberOfRows, nc = my numberOfColumns; long dimmin = nr < nc ? nr : nc; autoNUMmatrix h (NUMmatrix_copy (my data, 1, nr, 1, nc), 1, 1); autoNUMvector rowsum (1, nr); autoNUMvector colsum (1, nc); autoConfiguration thee = Configuration_create (nr + nc, numberOfDimensions); if (numberOfDimensions == 0) { numberOfDimensions = dimmin - 1; } if (numberOfDimensions >= dimmin) { Melder_throw (U"Dimension too high."); } // Ref: A. Gifi (1990), Nonlinear Multivariate Analysis, Wiley & Sons, reprinted 1996, // Chapter 8, Multidimensional scaling and Correspondence Analysis. // Get row and column marginals double sum = 0.0; for (long i = 1; i <= nr; i++) { for (long j = 1; j <= nc; j++) { rowsum[i] += my data[i][j]; colsum[j] += my data[i][j]; } if (rowsum[i] <= 0.0) { Melder_throw (U"Empty row: ", i, U"."); } sum += rowsum[i]; } for (long j = 1; j <= nc; j++) { if (colsum[j] <= 0.0) { Melder_throw (U"Empty column: ", j, U"."); } } // Remove trivial singular vectors (Eq. 8.24), // construct Dr^(-1/2) H Dc^(-1/2) - Dr^(1/2) uu' Dc^(1/2) / N for (long i = 1; i <= nr; i++) { for (long j = 1; j <= nc; j++) { double rc = sqrt (rowsum[i] * colsum[j]); h[i][j] = h[i][j] / rc - rc / sum; } } // Singular value decomposition of h autoSVD svd = SVD_create_d (h.peek(), nr, nc); SVD_zeroSmallSingularValues (svd.peek(), 0); // Scale row vectors and column vectors to configuration. for (long j = 1; j <= numberOfDimensions; j++) { double rootsum = sqrt (sum), xfactor, yfactor, lambda = svd -> d[j]; if (scaling == 1) { // Scale row points in the centre of gravity of column points (eq 8.5.a) xfactor = rootsum * lambda; yfactor = rootsum; } else if (scaling == 2) { // Scale column points in the centre of gravity of row points (8.5.b) xfactor = rootsum; yfactor = rootsum * lambda; } else if (scaling == 3) { // Treat row and columns symmetrically (8.5.c). xfactor = yfactor = rootsum * sqrt (lambda); } else { break; } for (long i = 1; i <= nr; i++) { thy data[i][j] = svd -> u[i][j] * xfactor / sqrt (rowsum[i]); } for (long i = 1; i <= nc; i++) { thy data[nr + i][j] = svd -> v[i][j] * yfactor / sqrt (colsum[i]); } } TableOfReal_setSequentialColumnLabels (thee.peek(), 0, 0, nullptr, 1, 1); NUMstrings_copyElements (my rowLabels, thy rowLabels, 1, nr); for (long i = 1; i <= nc; i++) { if (my columnLabels[i]) { TableOfReal_setRowLabel (thee.peek(), nr + i, my columnLabels[i]); } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no Configuration created."); } } Dissimilarity TableOfReal_to_Dissimilarity (TableOfReal me) { try { if (my numberOfRows != my numberOfColumns) { Melder_throw (U"TableOfReal must be a square tabel."); } TableOfReal_checkPositive (me); autoDissimilarity thee = Thing_new (Dissimilarity); my structTableOfReal :: v_copy (thee.peek()); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not converted to Dissimilarity."); } } Similarity TableOfReal_to_Similarity (TableOfReal me) { try { if (my numberOfRows != my numberOfColumns) { Melder_throw (U"TableOfReal must be a square table."); } TableOfReal_checkPositive (me); autoSimilarity thee = Thing_new (Similarity); my structTableOfReal :: v_copy (thee.peek()); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not converted to Similarity."); } } Distance TableOfReal_to_Distance (TableOfReal me) { try { if (my numberOfRows != my numberOfColumns) { Melder_throw (U"TableOfReal must be a square table."); } TableOfReal_checkPositive (me); autoDistance thee = Thing_new (Distance); my structTableOfReal :: v_copy (thee.peek()); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not converted to Distance."); } } Salience TableOfReal_to_Salience (TableOfReal me) { try { TableOfReal_checkPositive (me); autoSalience thee = Thing_new (Salience); my structTableOfReal :: v_copy (thee.peek()); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not converted to Salience."); } } Weight TableOfReal_to_Weight (TableOfReal me) { try { TableOfReal_checkPositive (me); autoWeight thee = Thing_new (Weight); my structTableOfReal :: v_copy (thee.peek()); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not converted to Weight."); } } ScalarProduct TableOfReal_to_ScalarProduct (TableOfReal me) { try { if (my numberOfRows != my numberOfColumns) { Melder_throw (U"TableOfReal must be a square table."); } autoScalarProduct thee = Thing_new (ScalarProduct); my structTableOfReal :: v_copy (thee.peek()); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not converted to ScalarProduct."); } } /**************** Covariance & Correlation to Configuration *****************/ Configuration SSCP_to_Configuration (SSCP me, long numberOfDimensions) { try { autoConfiguration thee = Configuration_create (my numberOfRows, numberOfDimensions); autoPCA a = SSCP_to_PCA (me); TableOfReal_setSequentialColumnLabels (thee.peek(), 0, 0, nullptr, 1, 1); for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= numberOfDimensions; j++) { double s = 0.0; for (long k = 1; k <= my numberOfRows; k++) { s += my data[k][i] * a -> eigenvectors[k][j]; } thy data[i][j] = s; } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no Configuration created."); } } Configuration Covariance_to_Configuration (Covariance me, long numberOfDimensions) { return SSCP_to_Configuration (me, numberOfDimensions); } Configuration Correlation_to_Configuration (Correlation me, long numberOfDimensions) { return SSCP_to_Configuration (me, numberOfDimensions); } /**************************** Weight *****************************************/ Thing_implement (Weight, TableOfReal, 0); Weight Weight_create (long numberOfPoints) { try { autoWeight me = Thing_new (Weight); TableOfReal_init (me.peek(), numberOfPoints, numberOfPoints); for (long i = 1; i <= numberOfPoints; i++) { for (long j = 1; j <= numberOfPoints; j++) { my data[i][j] = 1.0; } } return me.transfer(); } catch (MelderError) { Melder_throw (U"Weight not created."); } } /**************** Salience *****************************************/ Thing_implement (Salience, TableOfReal, 0); Salience Salience_create (long numberOfSources, long numberOfDimensions) { try { autoSalience me = Thing_new (Salience); TableOfReal_init (me.peek(), numberOfSources, numberOfDimensions); Salience_setDefaults (me.peek()); return me.transfer(); } catch (MelderError) { Melder_throw (U"Salience not created."); } } long Salience_correctNegatives (Salience me) { /* The weights might be negative. We correct this by simply making them positive. */ long nNegatives = 0; for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= my numberOfColumns; j++) { if (my data[i][j] < 0.0) { nNegatives++; my data[i][j] = - my data[i][j]; } } } return nNegatives; } void Salience_setDefaults (Salience me) { for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= my numberOfColumns; j++) { my data[i][j] = 1.0 / sqrt (my numberOfColumns); } } for (long j = 1; j <= my numberOfColumns; j++) { TableOfReal_setColumnLabel (me, j, Melder_cat (U"dimension ", j)); } } void Salience_draw (Salience me, Graphics g, int ix, int iy, int garnish) { long nc2, nc1 = ix < iy ? (nc2 = iy, ix) : (nc2 = ix, iy); double xmin = 0.0, xmax = 1.0, ymin = 0.0, ymax = 1.0, wmax = 1.0; if (ix < 1 || ix > my numberOfColumns || iy < 1 || iy > my numberOfColumns) { return; } for (long i = 1; i <= my numberOfRows; i++) { for (long j = nc1; j <= nc2; j++) { if (my data[i][j] > wmax) { wmax = my data[i][j]; } } } xmax = ymax = wmax; Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); for (long i = 1; i <= my numberOfRows; i++) { if (my rowLabels[i]) { Graphics_text (g, my data[i][ix], my data[i][iy], my rowLabels[i]); } } Graphics_setTextAlignment (g, Graphics_LEFT, Graphics_BOTTOM); Graphics_line (g, xmin, ymax, xmin, ymin); Graphics_line (g, xmin, ymin, xmax, ymin); /* Graphics_arc (g, xmin, ymin, xmax - xmin, 0, 90); */ Graphics_unsetInner (g); if (garnish) { if (my columnLabels[ix]) { Graphics_textBottom (g, false, my columnLabels[ix]); } if (my columnLabels[iy]) { Graphics_textLeft (g, false, my columnLabels[iy]); } } } /******** MDSVEC *******************************************/ Thing_implement (MDSVec, Daata, 0); void structMDSVec :: v_destroy () { NUMvector_free (proximity, 1); NUMvector_free (iPoint, 1); NUMvector_free (jPoint, 1); MDSVec_Parent :: v_destroy (); } MDSVec MDSVec_create (long nPoints) { try { autoMDSVec me = Thing_new (MDSVec); my nPoints = nPoints; my nProximities = nPoints * (nPoints - 1) / 2; my proximity = NUMvector (1, my nProximities); my iPoint = NUMvector (1, my nProximities); my jPoint = NUMvector (1, my nProximities); return me.transfer(); } catch (MelderError) { Melder_throw (U"MDSVec not created."); } } MDSVec Dissimilarity_to_MDSVec (Dissimilarity me) { try { autoMDSVec thee = MDSVec_create (my numberOfRows); long k = 0; for (long i = 1; i <= my numberOfRows - 1; i++) { for (long j = i + 1; j <= my numberOfColumns; j++) { double f = (my data[i][j] + my data[j][i]) / 2; if (f > 0.0) { k++; thy proximity[k] = f; thy iPoint[k] = i; thy jPoint[k] = j; } } } thy nProximities = k; NUMsort3 (thy proximity, thy iPoint, thy jPoint, 1, k, 1); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no MDSVec created."); } } /*********************** MDSVECS *******************************************/ Thing_implement (MDSVecs, Ordered, 0); MDSVecs MDSVecs_create () { try { autoMDSVecs me = Thing_new (MDSVecs); Ordered_init (me.peek(), classMDSVec, 10); return me.transfer(); } catch (MelderError) { Melder_throw (U"MDSVecs not created."); } } MDSVecs Dissimilarities_to_MDSVecs (Dissimilarities me) { try { autoMDSVecs thee = MDSVecs_create (); for (long i = 1; i <= my size; i++) { autoMDSVec him = Dissimilarity_to_MDSVec ( (Dissimilarity) (my item[i])); Thing_setName (him.peek(), Thing_getName ( (Thing) my item[i])); Collection_addItem (thee.peek(), him.transfer()); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no MDSVecs created."); } } /************************** CONFUSIONS **************************************/ Thing_implement (Confusions, Proximities, 0); Confusions Confusions_create () { try { autoConfusions me = Thing_new (Confusions); Proximities_init (me.peek(), classConfusion); return me.transfer(); } catch (MelderError) { Melder_throw (U"Confusions not created."); } } Confusion Confusions_sum (Confusions me) { try { autoTableOfReal sum = TablesOfReal_sum (me); autoConfusion thee = TableOfReal_to_Confusion (sum.peek()); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": sum not created."); } } /************************** DISTANCES **************************************/ Thing_implement (Distances, Proximities, 0); Distances Distances_create () { try { autoDistances me = Thing_new (Distances); Proximities_init (me.peek(), classDistance); return me.transfer(); } catch (MelderError) { Melder_throw (U"Distances not created."); } } /***************** SCALARPRODUCT ***************************************/ Thing_implement (ScalarProduct, TableOfReal, 0); ScalarProduct ScalarProduct_create (long numberOfPoints) { try { autoScalarProduct me = Thing_new (ScalarProduct); TableOfReal_init (me.peek(), numberOfPoints, numberOfPoints); return me.transfer(); } catch (MelderError) { Melder_throw (U"ScalarProduct not created."); } } /************* SCALARPRODUCTS **************************************/ Thing_implement (ScalarProducts, TablesOfReal, 0); ScalarProducts ScalarProducts_create () { try { autoScalarProducts me = Thing_new (ScalarProducts); TablesOfReal_init (me.peek(), classScalarProduct); return me.transfer(); } catch (MelderError) { Melder_throw (U"ScalarProducts not created."); } } /****************** DISSIMILARITY **********************************/ Thing_implement (Dissimilarity, Proximity, 0); Dissimilarity Dissimilarity_create (long numberOfPoints) { try { autoDissimilarity me = Thing_new (Dissimilarity); Proximity_init (me.peek(), numberOfPoints); return me.transfer(); } catch (MelderError) { Melder_throw (U"Dissimilarity not created."); } } static double Dissimilarity_getAverage (Dissimilarity me) { double sum = 0.0; long numberOfPositives = 0; for (long i = 1; i <= my numberOfRows - 1; i++) { for (long j = i + 1; j <= my numberOfRows; j++) { double proximity = (my data[i][j] + my data[j][i]) / 2.0; if (proximity > 0.0) { numberOfPositives++; sum += proximity; } } } return numberOfPositives > 0 ? sum /= numberOfPositives : NUMundefined; } double Dissimilarity_getAdditiveConstant (Dissimilarity me) { double additiveConstant = NUMundefined; try { long nPoints = my numberOfRows, nPoints2 = 2 * nPoints; // Return c = average dissimilarity in case of failure if (nPoints < 1) { Melder_throw (U"Matrix part is empty."); } additiveConstant = Dissimilarity_getAverage (me); if (additiveConstant == NUMundefined) { Melder_throw (U"There are no positive dissimilarities."); } autoNUMmatrix wd (1, nPoints, 1, nPoints); autoNUMmatrix wdsqrt (1, nPoints, 1, nPoints); autoNUMmatrix b (1, nPoints2, 1, nPoints2); autoNUMvector eigenvalue (1, nPoints2); // The matrices D & D1/2 with distances (squared and linear) for (long i = 1; i <= nPoints - 1; i++) { for (long j = i + 1; j <= nPoints; j++) { double proximity = (my data[i][j] + my data[j][i]) / 2.0; wdsqrt[i][j] = - proximity / 2.0; wd[i][j] = - proximity * proximity / 2.0; } } NUMdoubleCentre (wdsqrt.peek(), 1, nPoints, 1, nPoints); NUMdoubleCentre (wd.peek(), 1, nPoints, 1, nPoints); // Calculate the B matrix according to eq. 6 for (long i = 1; i <= nPoints; i++) { for (long j = 1; j <= nPoints; j++) { b[i][nPoints + j] = 2.0 * wd[i][j]; b[nPoints + i][nPoints + j] = -4.0 * wdsqrt[i][j]; b[nPoints + i][i] = -1.0; } } // Get eigenvalues and sort them descending NUMeigensystem (b.peek(), nPoints2, nullptr, eigenvalue.peek()); if (eigenvalue[1] <= 0.0) { Melder_throw (U"Negative eigenvalue."); } additiveConstant = eigenvalue[1]; return additiveConstant; } catch (MelderError) { Melder_throw (U"Additive constant not calculated."); } } /*************** DISSIMILARITIES **************************************/ Thing_implement (Dissimilarities, Proximities, 0); Dissimilarities Dissimilarities_create () { try { autoDissimilarities me = Thing_new (Dissimilarities); Proximities_init (me.peek(), classDissimilarity); return me.transfer(); } catch (MelderError) { Melder_throw (U"Dissimilarities not created."); } } /************* SIMILARITY *****************************************/ Thing_implement (Similarity, Proximity, 0); Similarity Similarity_create (long numberOfPoints) { try { autoSimilarity me = Thing_new (Similarity); Proximity_init (me.peek(), numberOfPoints); return me.transfer(); } catch (MelderError) { Melder_throw (U"Similarity not created."); } } Similarity Confusion_to_Similarity (Confusion me, int normalize, int symmetrizeMethod) { try { if (my numberOfColumns != my numberOfRows) { Melder_throw (U"Confusion must be a square table."); } long nxy = my numberOfColumns; autoSimilarity thee = Similarity_create (nxy); TableOfReal_copyLabels (me, thee.peek(), 1, 1); NUMmatrix_copyElements (my data, thy data, 1, my numberOfRows, 1, my numberOfColumns); if (normalize) { NUMdmatrix_normalizeRows (thy data, nxy, nxy); } if (symmetrizeMethod == 1) { return thee.transfer(); } if (symmetrizeMethod == 2) { // Average data for (long i = 1; i <= nxy - 1; i++) { for (long j = i + 1; j <= nxy; j++) { thy data[i][j] = thy data[j][i] = (thy data[i][j] + thy data[j][i]) / 2; } } } else if (symmetrizeMethod == 3) { // Method Houtgast. autoNUMmatrix p (NUMmatrix_copy (thy data, 1, nxy, 1, nxy), 1, 1); for (long i = 1; i <= nxy; i++) { for (long j = i; j <= nxy; j++) { double tmp = 0; for (long k = 1; k <= nxy; k++) { tmp += p[i][k] < p[j][k] ? p[i][k] : p[j][k]; } thy data[j][i] = thy data[i][j] = tmp; } } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no Similarity created."); } } Dissimilarity Similarity_to_Dissimilarity (Similarity me, double maximumDissimilarity) { try { long nxy = my numberOfColumns; double max = 0; autoDissimilarity thee = Dissimilarity_create (nxy); TableOfReal_copyLabels (me, thee.peek(), 1, 1); NUMmatrix_copyElements (my data, thy data, 1, my numberOfRows, 1, my numberOfColumns); for (long i = 1; i <= nxy; i++) { for (long j = 1; j <= nxy; j++) { if (thy data[i][j] > max) { max = thy data[i][j]; } } } if (maximumDissimilarity <= 0) { maximumDissimilarity = max; } if (maximumDissimilarity < max) Melder_warning (U"Your maximumDissimilarity is smaller than the maximum similarity. Some data may be lost."); for (long i = 1; i <= nxy; i++) { for (long j = 1; j <= nxy; j++) { double d = maximumDissimilarity - thy data[i][j]; thy data[i][j] = d > 0 ? d : 0; } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no Dissimilarity created."); } } Distance Dissimilarity_to_Distance (Dissimilarity me, int scale) { try { double additiveConstant = 0; autoDistance thee = Distance_create (my numberOfRows); TableOfReal_copyLabels (me, thee.peek(), 1, 1); if (scale == MDS_ORDINAL) { if ((additiveConstant = Dissimilarity_getAdditiveConstant (me)) == NUMundefined) { Melder_warning (U"Dissimilarity_to_Distance: could not determine \"additive constant\", the average dissimilarity was used as its value."); } } for (long i = 1; i <= my numberOfRows - 1; i++) { for (long j = i + 1; j <= my numberOfColumns; j++) { double d = 0.5 * (my data[i][j] + my data[j][i]) + additiveConstant; thy data[i][j] = thy data[j][i] = d; } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no Distance created."); } } Weight Dissimilarity_to_Weight (Dissimilarity me) { try { autoWeight thee = Weight_create (my numberOfRows); TableOfReal_copyLabels (me, thee.peek(), 1, 1); for (long i = 1; i <= my numberOfRows; i++) { for (long j = i; j <= my numberOfRows; j++) { if (my data[i][j] > 0.0) { thy data[i][j] = 1.0; } } thy data[i][i] = 0.0; } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no Weight created."); } } Dissimilarity Confusion_to_Dissimilarity_pdf (Confusion me, double minimumConfusionLevel) { try { if (my numberOfColumns != my numberOfRows) { Melder_throw (U"Confusion must be a square table."); } Melder_assert (minimumConfusionLevel > 0.0); autoDissimilarity thee = Dissimilarity_create (my numberOfColumns); TableOfReal_copyLabels (me, thee.peek(), 1, 1); NUMmatrix_copyElements (my data, thy data, 1, my numberOfRows, 1, my numberOfColumns); // Correct "zero" responses. for (long i = 1; i <= my numberOfColumns; i++) { for (long j = 1; j <= my numberOfColumns; j++) { if (thy data[i][j] == 0.0) { thy data[i][j] = minimumConfusionLevel; } } } NUMdmatrix_normalizeRows (thy data, my numberOfColumns, my numberOfColumns); /* Consider the fraction as the fraction overlap between two gaussians with unequal sigmas (1 & s). We have two matrix elements p[i][j] && p[j][i] N (x, m, s) = 1 / (s * sqrt(2 pi)) exp(-((x - m) / s)^2 / 2) N1 (x) = N (x, 0, 1) N2 (x) = N (x, m, s) These two gaussians cross each other at a point X that can be found by solving N1 (x) == N2 (x). The solution that is important to us is: X = (- m + s sqrt (m^2 - 2 (s^2 - 1) ln(s))) / (s^2 - 1) (1) This point X must be the solution of F (X, 0, 1) == p[i][j], where F (x, m, s) = P (x>X, m, s) = Integral (x, infinity, N (x, m, s) dx) We can solve for m and obtain: m = X + s sqrt (X^2 + 2 ln (s)) (2) We also have Integral (-Infinity, X, N2 (x) dx) == p[j][i]; By changing integration variables, (x - m) / s = y, we get Integral ((x-m)/s, Infinity, N (y, 0, 1) dy) == p[j][i] Let this equation result in a value Y, i.e., (X - m) / s = Y (3) (2) and (3) together and solve for m: m = X + Y * exp ((Y * y - X * X) / 2); Make maximum dissimilarity equal to 4sigma. */ for (long i = 1; i <= my numberOfColumns; i++) { for (long j = i + 1; j <= my numberOfColumns; j++) { double x = thy data[i][j] <= thy data[j][i] ? thy data[i][j] : thy data[j][i]; double y = thy data[i][j] > thy data[j][i] ? thy data[i][j] : thy data[j][i]; x = NUMinvGaussQ (x); y = NUMinvGaussQ (y); double d = x + y * exp ( (y * y - x * x) / 2.0); /* Melder_info ("i, j, x, y, d: %d %d %.17g %.17g %.17g", i, j, x, y, d); */ thy data[i][j] = thy data [j][i] = d; } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no Dissimilarity created from pdf."); } } void Distance_and_Configuration_drawScatterDiagram (Distance me, Configuration him, Graphics g, double xmin, double xmax, double ymin, double ymax, double size_mm, const char32 *mark, int garnish) { autoDistance dist = Configuration_to_Distance (him); Proximity_Distance_drawScatterDiagram (me, dist.peek(), g, xmin, xmax, ymin, ymax, size_mm, mark, garnish); } Dissimilarity Distance_to_Dissimilarity (Distance me) { try { autoDissimilarity thee = Dissimilarity_create (my numberOfRows); TableOfReal_copyLabels (me, thee.peek(), 1, 1); NUMmatrix_copyElements (my data, thy data, 1, my numberOfRows, 1, my numberOfColumns); return thee.transfer(); } catch (MelderError) { Melder_throw (U"Dissimilarity not created from Distance."); } } Configuration Distance_to_Configuration_torsca (Distance me, int numberOfDimensions) { try { if (numberOfDimensions > my numberOfRows) { Melder_throw (U"Number of dimensions too high."); } autoScalarProduct sp = Distance_to_ScalarProduct (me, 0); autoConfiguration thee = Configuration_create (my numberOfRows, numberOfDimensions); TableOfReal_copyLabels (me, thee.peek(), 1, 0); NUMprincipalComponents (sp -> data, my numberOfRows, numberOfDimensions, thy data); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no Configuration created (torsca method)."); } } ScalarProduct Distance_to_ScalarProduct (Distance me, int normalize) { try { autoScalarProduct thee = ScalarProduct_create (my numberOfRows); TableOfReal_copyLabels (me, thee.peek(), 1, 1); for (long i = 1; i <= my numberOfRows - 1; i++) { for (long j = i + 1; j <= my numberOfColumns; j++) { // force symmetry by averaging! double d = 0.5 * (my data[i][j] + my data[j][i]); thy data[i][j] = thy data[j][i] = - 0.5 * d * d; } } TableOfReal_doubleCentre (thee.peek()); if (my name) { Thing_setName (thee.peek(), my name); } if (normalize) { TableOfReal_normalizeTable (thee.peek(), 1); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no ScalarProduct created."); } } /********** Configuration & ..... ***********************************/ Distance Configuration_to_Distance (Configuration me) { try { autoDistance thee = Distance_create (my numberOfRows); TableOfReal_copyLabels (me, thee.peek(), 1, -1); for (long i = 1; i <= thy numberOfRows - 1; i++) { for (long j = i + 1; j <= thy numberOfColumns; j++) { double dmax = 0.0, d = 0.0; /* first divide distance by maximum to prevent overflow when metric is a large number. d = (x^n)^(1/n) may overflow if x>1 & n >>1 even if d would not overflow! metric changed 24/11/97 my w[k] * pow (|i-j|) instead of pow (my w[k] * |i-j|) */ for (long k = 1; k <= my numberOfColumns; k++) { double dtmp = fabs (my data[i][k] - my data[j][k]); if (dtmp > dmax) { dmax = dtmp; } } if (dmax > 0.0) { for (long k = 1; k <= my numberOfColumns; k++) { double arg = fabs (my data[i][k] - my data[j][k]) / dmax; d += my w[k] * pow (arg, my metric); } } thy data[i][j] = thy data[j][i] = dmax * pow (d, 1.0 / my metric); } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no Distance created."); } } void Proximity_Distance_drawScatterDiagram (I, Distance thee, Graphics g, double xmin, double xmax, double ymin, double ymax, double size_mm, const char32 *mark, int garnish) { iam (Proximity); long n = my numberOfRows * (my numberOfRows - 1) / 2; double **x = my data, **y = thy data; if (n == 0) { return; } if (! TableOfReal_equalLabels (me, thee, 1, 1)) { Melder_throw (U"Proximity_Distance_drawScatterDiagram: Dimensions and labels must be the same."); } if (xmax <= xmin) { xmin = xmax = x[1][2]; for (long i = 1; i <= thy numberOfRows - 1; i++) { for (long j = i + 1; j <= thy numberOfColumns; j++) { if (x[i][j] > xmax) { xmax = x[i][j]; } else if (x[i][j] < xmin) { xmin = x[i][j]; } } } } if (ymax <= ymin) { ymin = ymax = y[1][2]; for (long i = 1; i <= my numberOfRows - 1; i++) { for (long j = i + 1; j <= my numberOfColumns; j++) { if (y[i][j] > ymax) { ymax = y[i][j]; } else if (y[i][j] < ymin) { ymin = y[i][j]; } } } } Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_setInner (g); for (long i = 1; i <= thy numberOfRows - 1; i++) { for (long j = i + 1; j <= thy numberOfColumns; j++) { if (x[i][j] >= xmin && x[i][j] <= xmax && y[i][j] >= ymin && y[i][j] <= ymax) { Graphics_mark (g, x[i][j], y[i][j], size_mm, mark); } } } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textLeft (g, true, U"Distance"); Graphics_textBottom (g, true, U"Dissimilarity"); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); } } Distances MDSVecs_Distance_monotoneRegression (MDSVecs me, Distance thee, int tiesProcessing) { try { autoDistances him = Distances_create (); for (long i = 1; i <= my size; i++) { autoMDSVec vec = (MDSVec) my item[i]; if (vec -> nPoints != thy numberOfRows) { Melder_throw (U"Dimension of MDSVec and Distance must be equal."); } autoDistance fit = MDSVec_Distance_monotoneRegression (vec.peek(), thee, tiesProcessing); Collection_addItem (him.peek(), fit.transfer()); } return him.transfer(); } catch (MelderError) { Melder_throw (U"No Distances created from MDSVecs & Distance."); } } Distance MDSVec_Distance_monotoneRegression (MDSVec me, Distance thee, int tiesProcessing) { try { long nProximities = my nProximities; if (thy numberOfRows != my nPoints) { Melder_throw (U"Distance and MDSVVec dimension do not agreee."); } autoNUMvector distance (1, nProximities); autoNUMvector fit (1, nProximities); autoDistance him = Distance_create (thy numberOfRows); TableOfReal_copyLabels (thee, him.peek(), 1, 1); long *iPoint = my iPoint, *jPoint = my jPoint; for (long i = 1; i <= nProximities; i++) { distance[i] = thy data[iPoint[i]][jPoint[i]]; } if (tiesProcessing == MDS_PRIMARY_APPROACH || MDS_SECONDARY_APPROACH) { /* Kruskal's primary approach to tie-blocks: Sort corresponding distances, with iPoint, and jPoint. Kruskal's secondary approach: Substitute average distance in each tie block */ long ib = 1; for (long i = 2; i <= nProximities; i++) { if (my proximity[i] == my proximity[i - 1]) { continue; } if (i - ib > 1) { if (tiesProcessing == MDS_PRIMARY_APPROACH) { NUMsort3 (distance.peek(), iPoint, jPoint, ib, i - 1, 1); // sort ascending } else if (tiesProcessing == MDS_SECONDARY_APPROACH) { double mean = 0.0; for (long j = ib; j <= i - 1; j++) { mean += distance[j]; } mean /= (i - ib); for (long j = ib; j <= i - 1; j++) { distance[j] = mean; } } } ib = i; } } NUMmonotoneRegression (distance.peek(), nProximities, fit.peek()); // Fill Distance with monotone regressed distances for (long i = 1; i <= nProximities; i++) { long ip = iPoint[i], jp = jPoint[i]; his data[ip][jp] = his data[jp][ip] = fit[i]; } // Make rest of distances equal to the maximum fit. for (long i = 1; i <= his numberOfRows - 1; i++) { for (long j = i + 1; j <= his numberOfColumns; j++) { if (his data[i][j] == 0.0) { his data[i][j] = his data[j][i] = fit[nProximities]; } } } return him.transfer(); } catch (MelderError) { Melder_throw (U"Distance not created."); } } Distance Dissimilarity_Distance_monotoneRegression (Dissimilarity me, Distance thee, int tiesProcessing) { try { if (thy numberOfRows != my numberOfRows) { Melder_throw (U"Dimensions do not agree."); } autoMDSVec vec = Dissimilarity_to_MDSVec (me); autoDistance him = MDSVec_Distance_monotoneRegression (vec.peek(), thee, tiesProcessing); return him.transfer(); } catch (MelderError) { Melder_throw (U"Distance not created."); } } /*************** class Proximities **************************************/ Thing_implement (Proximities, TablesOfReal, 0); void Proximities_init (Proximities me, ClassInfo klas) { TablesOfReal_init (me, klas); } Proximities Proximities_create () { try { autoProximities me = Thing_new (Proximities); Proximities_init (me.peek(), classProximity); return me.transfer(); } catch (MelderError) { Melder_throw (U"Proximities not created."); } } ScalarProducts Distances_to_ScalarProducts (Distances me, int normalize) { try { autoScalarProducts thee = ScalarProducts_create (); for (long i = 1; i <= my size; i++) { autoScalarProduct sp = Distance_to_ScalarProduct ((Distance) (my item[i]), normalize); Collection_addItem (thee.peek(), sp.transfer()); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no ScalarProducts created."); } } void Distances_to_Configuration_ytl (Distances me, int numberOfDimensions, int normalizeScalarProducts, autoConfiguration *out1, autoSalience *out2) { try { autoScalarProducts sp = Distances_to_ScalarProducts (me, normalizeScalarProducts); ScalarProducts_to_Configuration_ytl (sp.peek(), numberOfDimensions, out1, out2); } catch (MelderError) { Melder_throw (me, U": no Configuration created (ytl method)."); } } void ScalarProducts_to_Configuration_ytl (ScalarProducts me, int numberOfDimensions, autoConfiguration *out1, autoSalience *out2) { long numberOfSources = my size; autoNUMvector ci (1, numberOfSources); try { long nPoints = ((ScalarProduct) my item[1]) -> numberOfRows; autoConfiguration thee = Configuration_create (nPoints, numberOfDimensions); autoSalience mdsw = Salience_create (numberOfSources, numberOfDimensions); TableOfReal_copyLabels ((TableOfReal) my item[1], thee.peek(), 1, 0); autoNUMvector eval (1, numberOfSources); autoNUMmatrix cl (1, numberOfDimensions, 1, numberOfDimensions); autoNUMmatrix pmean (1, nPoints, 1, nPoints); autoNUMmatrix y (1, nPoints, 1, numberOfDimensions); autoNUMmatrix yinv (1, numberOfDimensions, 1, nPoints); autoNUMmatrix a (1, numberOfSources, 1, numberOfSources); autoNUMmatrix evec (1, numberOfSources, 1, numberOfSources); autoNUMmatrix K (1, numberOfDimensions, 1, numberOfDimensions); Thing_setName (mdsw.peek(), U"ytl"); Thing_setName (thee.peek(), U"ytl"); TableOfReal_labelsFromCollectionItemNames (mdsw.peek(), me, 1, 0); // Determine the average scalar product matrix (Pmean) of // dimension [1..nPoints][1..nPoints]. for (long i = 1; i <= numberOfSources; i++) { ScalarProduct sp = (ScalarProduct) my item[i]; for (long j = 1; j <= nPoints; j++) { for (long k = 1; k <= nPoints; k++) { pmean[j][k] += sp-> data[j][k]; } } } if (numberOfSources > 1) { for (long j = 1; j <= nPoints; j++) { for (long k = 1; k <= nPoints; k++) { pmean[j][k] /= numberOfSources; } } } // Up to a rotation K, the initial configuration can be found by // extracting the first 'numberOfDimensions' principal components of Pmean. NUMdmatrix_into_principalComponents (pmean.peek(), nPoints, nPoints, numberOfDimensions, y.peek()); NUMmatrix_copyElements (y.peek(), thy data, 1, nPoints, 1, numberOfDimensions); // We cannot determine weights from only one sp-matrix. if (numberOfSources == 1) { Melder_throw (U"Only one source."); } // Calculate the C[i] matrices [1..numberOfDimensions][1..numberOfDimensions] // from the P[i] by: C[i] = (y'.y)^-1 . y' . P[i] . y . (y'.y)^-1 == // yinv P[i] yinv' NUMpseudoInverse (y.peek(), nPoints, numberOfDimensions, yinv.peek(), 1e-14); for (long i = 1; i <= numberOfSources; i++) { ScalarProduct sp = (ScalarProduct) my item[i]; ci[i] = NUMmatrix (1, numberOfDimensions, 1, numberOfDimensions); for (long j = 1; j <= numberOfDimensions; j++) { for (long k = 1; k <= numberOfDimensions; k++) { for (long l = 1; l <= nPoints; l++) { if (yinv[j][l] != 0.0) { for (long m = 1; m <= nPoints; m++) { ci[i][j][k] += yinv[j][l] * sp -> data[l][m] * yinv[k][m]; } } } } } } // Calculate the A[1..numberOfSources][1..numberOfSources] matrix by (eq.12): // a[i][j] = trace (C[i]*C[j]) - trace (C[i]) * trace (C[j]) / numberOfDimensions; // Get the first eigenvector and form matrix cl from a linear combination of the C[i]'s for (long i = 1; i <= numberOfSources; i++) { for (long j = i; j <= numberOfSources; j++) { a[j][i] = a[i][j] = NUMtrace2 (ci[i], ci[j], numberOfDimensions) - NUMtrace (ci[i], numberOfDimensions) * NUMtrace (ci[j], numberOfDimensions) / numberOfDimensions; } } NUMeigensystem (a.peek(), numberOfSources, evec.peek(), eval.peek()); for (long i = 1; i <= numberOfSources; i++) { for (long j = 1; j <= numberOfDimensions; j++) { for (long k = 1; k <= numberOfDimensions; k++) { cl[j][k] += ci[i][j][k] * evec[i][1]; /* eq. (7) */ } } } // The rotation K is obtained from the eigenvectors of cl // Is the following still correct??? eigensystem was not sorted?? NUMeigensystem (cl.peek(), numberOfDimensions, K.peek(), nullptr); // Now get the configuration: X = Y.K for (long i = 1; i <= nPoints; i++) { for (long j = 1; j <= numberOfDimensions; j++) { double x = 0.0; for (long k = 1; k <= numberOfDimensions; k++) { x += y[i][k] * K[k][j]; } thy data [i][j] = x; } } Configuration_normalize (thee.peek(), 0, 1); // And finally the weights: W[i] = K' C[i] K (eq. (5)). // We are only interested in the diagonal of the resulting matrix W[i]. for (long i = 1; i <= numberOfSources; i++) { for (long j = 1; j <= numberOfDimensions; j++) { double wt = 0.0; for (long k = 1; k <= numberOfDimensions; k++) { if (K[k][j] != 0.0) { for (long l = 1; l <= numberOfDimensions; l++) { wt += K[k][j] * ci[i][k][l] * K[l][j]; } } } mdsw -> data[i][j] = wt; } } *out1 = thee.move(); *out2 = mdsw.move(); for (long i = 1; i <= numberOfSources; i++) { NUMmatrix_free (ci[i], 1, 1); } } catch (MelderError) { for (long i = 1; i <= numberOfSources; i++) { NUMmatrix_free (ci[i], 1, 1); }; Melder_throw (me, U": no Configuration (ytl) created."); } } Dissimilarities Distances_to_Dissimilarities (Distances me) { try { autoDissimilarities thee = Dissimilarities_create (); for (long i = 1; i <= my size; i++) { char32 *name = Thing_getName ( (Thing) my item[i]); autoDissimilarity him = Distance_to_Dissimilarity ( (Distance) (my item[i])); Thing_setName (him.peek(), name ? name : U"untitled"); Collection_addItem (thee.peek(), him.transfer()); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no Dissimilarities created."); } } Distances Dissimilarities_to_Distances (Dissimilarities me, int measurementLevel) { try { autoDistances thee = Distances_create (); for (long i = 1; i <= my size; i++) { autoDistance him = Dissimilarity_to_Distance ( (Dissimilarity) my item[i], measurementLevel == MDS_ORDINAL); char32 *name = Thing_getName ( (Thing) my item[i]); Thing_setName (him.peek(), name ? name : U"untitled"); Collection_addItem (thee.peek(), him.transfer()); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no Distances created."); } } /***************** Kruskal *****************************************/ static void smacof_guttmanTransform (Configuration cx, Configuration cz, Distance disp, Weight weight, double **vplus) { long nPoints = cx -> numberOfRows, nDimensions = cx -> numberOfColumns; double **z = cz -> data; autoNUMmatrix b (1, nPoints, 1, nPoints); autoDistance distZ = Configuration_to_Distance (cz); // compute B(Z) (eq. 8.25) for (long i = 1; i <= nPoints; i++) { double sum = 0.0; for (long j = 1; j <= nPoints; j++) { double dzij = distZ -> data[i][j]; if (i == j || dzij == 0.0) { continue; } b[i][j] = - weight -> data[i][j] * disp -> data[i][j] / dzij; sum += b[i][j]; } b[i][i] = - sum; } // Guttman transform: Xu = (V+)B(Z)Z (eq. 8.29) for (long i = 1; i <= nPoints; i++) { for (long j = 1; j <= nDimensions; j++) { double xij = 0.0; for (long k = 1; k <= nPoints; k++) { for (long l = 1; l <= nPoints; l++) { xij += vplus[i][k] * b[k][l] * z[l][j]; } } cx -> data[i][j] = xij; } } } double Distance_Weight_stress (Distance fit, Distance conf, Weight weight, int type) { double eta_fit, eta_conf, rho, stress = NUMundefined, denum, tmp; Distance_Weight_rawStressComponents (fit, conf, weight, &eta_fit, &eta_conf, &rho); // All formula's for stress, except for raw stress, are independent of the // scale of the configuration, i.e., the distances conf[i][j]. if (type == MDS_NORMALIZED_STRESS) { denum = eta_fit * eta_conf; if (denum > 0.0) { stress = 1.0 - rho * rho / denum; } } else if (type == MDS_STRESS_1) { denum = eta_fit * eta_conf; if (denum > 0.0) { tmp = 1.0 - rho * rho / denum; if (tmp > 0.0) { stress = sqrt (tmp); } } } else if (type == MDS_STRESS_2) { double m = 0.0, wsum = 0.0, var = 0.0, **w = weight -> data; double **c = conf -> data; long nPoints = conf -> numberOfRows; // Get average distance for (long i = 1; i <= nPoints - 1; i++) { for (long j = i + 1; j <= nPoints; j++) { m += w[i][j] * c[i][j]; wsum += w[i][j]; } } m /= wsum; if (m > 0.0) { // Get variance for (long i = 1; i <= nPoints - 1; i++) { for (long j = i + 1; j <= nPoints; j++) { tmp = c[i][j] - m; var += w[i][j] * tmp * tmp; } } denum = var * eta_fit; if (denum > 0.0) { stress = sqrt ( (eta_fit * eta_conf - rho * rho) / denum); } } } else if (type == MDS_RAW_STRESS) { stress = eta_fit + eta_conf - 2.0 * rho ; } return stress; } void Distance_Weight_rawStressComponents (Distance fit, Distance conf, Weight weight, double *p_etafit, double *p_etaconf, double *p_rho) { long nPoints = conf -> numberOfRows; double etafit = 0.0, etaconf = 0.0, rho = 0.0; for (long i = 1; i <= nPoints - 1; i++) { double *wi = weight -> data[i]; double *fiti = fit -> data[i]; double *confi = conf -> data[i]; for (long j = i + 1; j <= nPoints; j++) { etafit += wi[j] * fiti[j] * fiti[j]; etaconf += wi[j] * confi[j] * confi[j]; rho += wi[j] * fiti[j] * confi[j]; } } if (p_etafit) { *p_etafit = etafit; } if (p_etaconf) { *p_etaconf = etaconf; } if (p_rho) { *p_rho = rho; } } double Dissimilarity_Configuration_Transformator_Weight_stress (Dissimilarity d, Configuration c, Transformator t, Weight w, int type) { long nPoints = d -> numberOfRows; double stress = NUMundefined; if (nPoints < 1 || nPoints != c -> numberOfRows || nPoints != t -> numberOfPoints || (w && nPoints != w -> numberOfRows)) { Melder_throw (U"Incorrect number of points."); } autoWeight aw; if (! w) { aw.reset (Weight_create (nPoints)); w = aw.peek(); } autoDistance cdist = Configuration_to_Distance (c); autoMDSVec vec = Dissimilarity_to_MDSVec (d); autoDistance fit = Transformator_transform (t, vec.peek(), cdist.peek(), w); stress = Distance_Weight_stress (fit.peek(), cdist.peek(), w, type); return stress; } double Dissimilarity_Configuration_Weight_absolute_stress (Dissimilarity d, Configuration c, Weight w, int type) { autoTransformator t = Transformator_create (d -> numberOfRows); double stress = Dissimilarity_Configuration_Transformator_Weight_stress (d, c, t.peek(), w, type); return stress; } double Dissimilarity_Configuration_Weight_ratio_stress (Dissimilarity d, Configuration c, Weight w, int type) { autoRatioTransformator t = RatioTransformator_create (d -> numberOfRows); double stress = Dissimilarity_Configuration_Transformator_Weight_stress (d, c, t.peek(), w, type); return stress; } double Dissimilarity_Configuration_Weight_interval_stress (Dissimilarity d, Configuration c, Weight w, int type) { autoISplineTransformator t = ISplineTransformator_create (d -> numberOfRows, 0, 1); double stress = Dissimilarity_Configuration_Transformator_Weight_stress (d, c, t.peek(), w, type); return stress; } double Dissimilarity_Configuration_Weight_monotone_stress (Dissimilarity d, Configuration c, Weight w, int tiesProcessing, int type) { autoMonotoneTransformator t = MonotoneTransformator_create (d -> numberOfRows); MonotoneTransformator_setTiesProcessing (t.peek(), tiesProcessing); double stress = Dissimilarity_Configuration_Transformator_Weight_stress (d, c, t.peek(), w, type); return stress; } double Dissimilarity_Configuration_Weight_ispline_stress (Dissimilarity d, Configuration c, Weight w, long numberOfInteriorKnots, long order, int type) { autoISplineTransformator t = ISplineTransformator_create (d -> numberOfRows, numberOfInteriorKnots, order); double stress = Dissimilarity_Configuration_Transformator_Weight_stress (d, c, t.peek(), w, type); return stress; } void Distance_Weight_smacofNormalize (Distance me, Weight w) { double sumsq = 0.0; for (long i = 1; i <= my numberOfRows - 1; i++) { double *wi = w -> data[i]; double *di = my data[i]; for (long j = i + 1; j <= my numberOfRows; j++) { sumsq += wi[j] * di[j] * di[j]; } } double scale = sqrt (my numberOfRows * (my numberOfRows - 1) / (2.0 * sumsq)); for (long i = 1; i <= my numberOfRows - 1; i++) { for (long j = i + 1; j <= my numberOfRows; j++) { my data[j][i] = (my data[i][j] *= scale); } } } double Distance_Weight_congruenceCoefficient (Distance x, Distance y, Weight w) { long nPoints = x -> numberOfRows; if (y -> numberOfRows != nPoints || w -> numberOfRows != nPoints) { return 0.0; } double xy = 0.0, x2 = 0.0, y2 = 0.0; for (long i = 1; i <= nPoints - 1; i++) { double *xi = x -> data[i]; double *yi = y -> data[i]; double *wi = w -> data[i]; for (long j = i + 1; j <= nPoints - 1; j++) { xy += wi[j] * xi[j] * yi[j]; x2 += wi[j] * xi[j] * xi[j]; y2 += wi[j] * yi[j] * yi[j]; } } return xy / (sqrt (x2) * sqrt (y2)); } Configuration Dissimilarity_Configuration_Weight_Transformator_smacof (Dissimilarity me, Configuration conf, Weight weight, Transformator t, double tolerance, long numberOfIterations, int showProgress, double *stress) { try { long nPoints = conf -> numberOfRows; long nDimensions = conf -> numberOfColumns; double tol = 1e-6, stressp = 1e308, stres; bool no_weight = ! weight; if (my numberOfRows != nPoints || (!no_weight && weight -> numberOfRows != nPoints) || t -> numberOfPoints != nPoints) { Melder_throw (U"Dimensions not in concordance."); } autoWeight aw = 0; if (no_weight) { aw.reset (Weight_create (nPoints)); weight = aw.peek(); } autoNUMmatrix v (1, nPoints, 1, nPoints); autoNUMmatrix vplus (1, nPoints, 1, nPoints); autoConfiguration z = Data_copy (conf); autoMDSVec vec = Dissimilarity_to_MDSVec (me); double **w = weight -> data; if (showProgress) { Melder_progress (0.0, U"MDS analysis"); } // Get V (eq. 8.19). for (long i = 1; i <= nPoints; i++) { double wsum = 0; for (long j = 1; j <= nPoints; j++) { if (i == j) { continue; } v[i][j] = - w[i][j]; wsum += w[i][j]; } v[i][i] = wsum; } // V is row and column centered and therefore: rank(V) <= nPoints-1. // V^-1 does not exist -> get Moore-Penrose inverse. NUMpseudoInverse (v.peek(), nPoints, nPoints, vplus.peek(), tol); for (long iter = 1; iter <= numberOfIterations; iter++) { autoDistance dist = Configuration_to_Distance (conf); // transform & normalization autoDistance fit = Transformator_transform (t, vec.peek(), dist.peek(), weight); // Make conf the Guttman transform of z smacof_guttmanTransform (conf, z.peek(), fit.peek(), weight, vplus.peek()); // Compute stress autoDistance cdist = Configuration_to_Distance (conf); stres = Distance_Weight_stress (fit.peek(), cdist.peek(), weight, MDS_NORMALIZED_STRESS); // Check stop criterium if (fabs (stres - stressp) / stressp < tolerance) { break; } // Make Z = X NUMmatrix_copyElements (conf -> data, z -> data, 1, nPoints, 1, nDimensions); stressp = stres; if (showProgress) { Melder_progress ((double) iter / (numberOfIterations + 1), U"kruskal: stress ", stres); } } if (showProgress) { Melder_progress (1.0); } if (stress) { *stress = stres; } return z.transfer(); } catch (MelderError) { if (showProgress) { Melder_progress (1.0); } Melder_throw (me, U": no improved Configuration created (smacof method)."); } } Configuration Dissimilarity_Configuration_Weight_Transformator_multiSmacof (Dissimilarity me, Configuration conf, Weight w, Transformator t, double tolerance, long numberOfIterations, long numberOfRepetitions, int showProgress) { int showMulti = showProgress && numberOfRepetitions > 1; try { int showSingle = showProgress && numberOfRepetitions == 1; double stress, stressmax = 1e308; autoConfiguration cstart = Data_copy (conf); autoConfiguration cbest = Data_copy (conf); if (showMulti) { Melder_progress (0.0, U"MDS many times"); } for (long i = 1; i <= numberOfRepetitions; i++) { autoConfiguration cresult = Dissimilarity_Configuration_Weight_Transformator_smacof (me, cstart.peek(), w, t, tolerance, numberOfIterations, showSingle, &stress); if (stress < stressmax) { stressmax = stress; cbest = cresult.move(); } Configuration_randomize (cstart.peek()); TableOfReal_centreColumns (cstart.peek()); if (showMulti) { Melder_progress ( (double) i / (numberOfRepetitions + 1), i, U" from ", numberOfRepetitions); } } if (showMulti) { Melder_progress (1.0); } return cbest.transfer(); } catch (MelderError) { if (showMulti) { Melder_progress (1.0); } Melder_throw (me, U": no improved Configuration created (smacodf method)."); } } Configuration Dissimilarity_Configuration_Weight_absolute_mds (Dissimilarity me, Configuration cstart, Weight w, double tolerance, long numberOfIterations, long numberOfRepetitions, int showProgress) { try { autoTransformator t = Transformator_create (my numberOfRows); autoConfiguration c = Dissimilarity_Configuration_Weight_Transformator_multiSmacof (me, cstart, w, t.peek(), tolerance, numberOfIterations, numberOfRepetitions, showProgress); return c.transfer(); } catch (MelderError) { Melder_throw (me, U": no improved Configuration created (absolute mds method)."); } } Configuration Dissimilarity_Configuration_Weight_ratio_mds (Dissimilarity me, Configuration cstart, Weight w, double tolerance, long numberOfIterations, long numberOfRepetitions, int showProgress) { try { autoRatioTransformator t = RatioTransformator_create (my numberOfRows); autoConfiguration c = Dissimilarity_Configuration_Weight_Transformator_multiSmacof (me, cstart, w, t.peek(), tolerance, numberOfIterations, numberOfRepetitions, showProgress); return c.transfer(); } catch (MelderError) { Melder_throw (me, U": no improved Configuration created (ratio mds method)."); } } Configuration Dissimilarity_Configuration_Weight_interval_mds (Dissimilarity me, Configuration cstart, Weight w, double tolerance, long numberOfIterations, long numberOfRepetitions, int showProgress) { try { autoISplineTransformator t = ISplineTransformator_create (my numberOfRows, 0, 1); autoConfiguration c = Dissimilarity_Configuration_Weight_Transformator_multiSmacof (me, cstart, w, t.peek(), tolerance, numberOfIterations, numberOfRepetitions, showProgress); return c.transfer(); } catch (MelderError) { Melder_throw (me, U": no improved Configuration created (interval mds method)."); } } Configuration Dissimilarity_Configuration_Weight_monotone_mds (Dissimilarity me, Configuration cstart, Weight w, int tiesProcessing, double tolerance, long numberOfIterations, long numberOfRepetitions, int showProgress) { try { autoMonotoneTransformator t = MonotoneTransformator_create (my numberOfRows); MonotoneTransformator_setTiesProcessing (t.peek(), tiesProcessing); autoConfiguration c = Dissimilarity_Configuration_Weight_Transformator_multiSmacof (me, cstart, w, t.peek(), tolerance, numberOfIterations, numberOfRepetitions, showProgress); return c.transfer(); } catch (MelderError) { Melder_throw (me, U": no improved Configuration created (monotone mds method)."); } } Configuration Dissimilarity_Configuration_Weight_ispline_mds (Dissimilarity me, Configuration cstart, Weight w, long numberOfInteriorKnots, long order, double tolerance, long numberOfIterations, long numberOfRepetitions, int showProgress) { try { autoISplineTransformator t = ISplineTransformator_create (my numberOfRows, numberOfInteriorKnots, order); autoConfiguration c = Dissimilarity_Configuration_Weight_Transformator_multiSmacof (me, cstart, w, t.peek(), tolerance, numberOfIterations, numberOfRepetitions, showProgress); return c.transfer(); } catch (MelderError) { Melder_throw (me, U": no improved Configuration created (ispline mds method)."); } } Configuration Dissimilarity_Weight_absolute_mds (Dissimilarity me, Weight w, long numberOfDimensions, double tolerance, long numberOfIterations, long numberOfRepetitions, int showProgress) { try { autoDistance d = Dissimilarity_to_Distance (me, MDS_ABSOLUTE); autoConfiguration cstart = Distance_to_Configuration_torsca (d.peek(), numberOfDimensions); autoConfiguration c = Dissimilarity_Configuration_Weight_absolute_mds (me, cstart.peek(), w, tolerance, numberOfIterations, numberOfRepetitions, showProgress); return c.transfer(); } catch (MelderError) { Melder_throw (me, U": no Configuration created (absolute mds method)."); } } Configuration Dissimilarity_Weight_interval_mds (Dissimilarity me, Weight w, long numberOfDimensions, double tolerance, long numberOfIterations, long numberOfRepetitions, int showProgress) { try { autoDistance d = Dissimilarity_to_Distance (me, MDS_RATIO); autoConfiguration cstart = Distance_to_Configuration_torsca (d.peek(), numberOfDimensions); autoConfiguration c = Dissimilarity_Configuration_Weight_interval_mds (me, cstart.peek(), w, tolerance, numberOfIterations, numberOfRepetitions, showProgress); return c.transfer(); } catch (MelderError) { Melder_throw (me, U": no Configuration created (interval mds method)."); } } Configuration Dissimilarity_Weight_monotone_mds (Dissimilarity me, Weight w, long numberOfDimensions, int tiesProcessing, double tolerance, long numberOfIterations, long numberOfRepetitions, int showProgress) { try { autoDistance d = Dissimilarity_to_Distance (me, MDS_ORDINAL); autoConfiguration cstart = Distance_to_Configuration_torsca (d.peek(), numberOfDimensions); autoConfiguration c = Dissimilarity_Configuration_Weight_monotone_mds (me, cstart.peek(), w, tiesProcessing, tolerance, numberOfIterations, numberOfRepetitions, showProgress); return c.transfer(); } catch (MelderError) { Melder_throw (me, U": no Configuration created (monotone mds method)."); } } Configuration Dissimilarity_Weight_ratio_mds (Dissimilarity me, Weight w, long numberOfDimensions, double tolerance, long numberOfIterations, long numberOfRepetitions, int showProgress) { try { autoDistance d = Dissimilarity_to_Distance (me, MDS_RATIO); autoConfiguration cstart = Distance_to_Configuration_torsca (d.peek(), numberOfDimensions); autoConfiguration c = Dissimilarity_Configuration_Weight_ratio_mds (me, cstart.peek(), w, tolerance, numberOfIterations, numberOfRepetitions, showProgress); return c.transfer(); } catch (MelderError) { Melder_throw (me, U": no Configuration created (ratio mds method)."); } } Configuration Dissimilarity_Weight_ispline_mds (Dissimilarity me, Weight w, long numberOfDimensions, long numberOfInteriorKnots, long order, double tolerance, long numberOfIterations, long numberOfRepetitions, int showProgress) { try { autoDistance d = Dissimilarity_to_Distance (me, MDS_ORDINAL); autoConfiguration cstart = Distance_to_Configuration_torsca (d.peek(), numberOfDimensions); autoConfiguration c = Dissimilarity_Configuration_Weight_ispline_mds (me, cstart.peek(), w, numberOfInteriorKnots, order, tolerance, numberOfIterations, numberOfRepetitions, showProgress); return c.transfer(); } catch (MelderError) { Melder_throw (me, U": no Configuration created (ispline mds method)."); } } /***** classical **/ static void MDSVec_Distances_getStressValues (MDSVec me, Distance ddist, Distance dfit, int stress_formula, double *stress, double *s, double *t, double *dbar) { long nProximities = my nProximities; long *iPoint = my iPoint, *jPoint = my jPoint; double **dist = ddist -> data, **fit = dfit -> data; *s = *t = *dbar = 0.0; if (stress_formula == 2) { for (long i = 1; i <= nProximities; i++) { *dbar += dist[iPoint[i]][jPoint[i]]; } *dbar /= nProximities; } for (long i = 1; i <= nProximities; i++) { long ii = iPoint[i], jj = jPoint[i]; double st = dist[ii][jj] - fit[ii][jj]; double tt = dist[ii][jj] - *dbar; *s += st * st; *t += tt * tt; } *stress = *t > 0.0 ? sqrt (*s / *t) : 0.0; } static double func (Daata object, const double p[]) { Kruskal me = (Kruskal) object; MDSVec him = my vec; double **x = my configuration -> data, s, t, dbar, stress; double metric = my configuration -> metric; long numberOfDimensions = my configuration -> numberOfColumns; long numberOfPoints = my configuration -> numberOfRows; int tiesProcessing = my process == MDS_CONTINUOUS ? 1 : 0; // Substitute results of minimizer into configuration and // normalize the configuration NUMdvector_into_matrix (p, x, 1, numberOfPoints, 1, numberOfDimensions); // Normalize NUMcentreColumns (x, 1, numberOfPoints, 1, numberOfDimensions, nullptr); NUMnormalize (x, numberOfPoints, numberOfDimensions, sqrt (numberOfPoints)); // Calculate interpoint distances from the configuration autoDistance dist = Configuration_to_Distance (my configuration.peek()); // Monotone regression autoDistance fit = MDSVec_Distance_monotoneRegression (my vec, dist.peek(), tiesProcessing); // Get numerator and denominator of stress MDSVec_Distances_getStressValues (my vec, dist.peek(), fit.peek(), my stress_formula, &stress, &s, &t, &dbar); // Gradient calculation. for (long i = 1; i <= numberOfPoints; i++) { for (long j = 1; j <= numberOfDimensions; j++) { my dx[i][j] = 0.0; } } // Prevent overflow when stress is small if (stress < 1e-6) { return stress; } for (long i = 1; i <= his nProximities; i++) { long ii = my vec -> iPoint[i], jj = my vec -> jPoint[i]; double g1 = stress * ((dist->data[ii][jj] - fit->data[ii][jj]) / s - (dist->data[ii][jj] - dbar) / t); for (long j = 1; j <= numberOfDimensions; j++) { double dj = x[ii][j] - x[jj][j]; double g2 = g1 * pow (fabs (dj) / dist->data[ii][jj], metric - 1.0); if (dj < 0.0) { g2 = -g2; } my dx[ii][j] += g2; my dx[jj][j] -= g2; } } // Increment the number of times this function has been called (my minimizer -> funcCalls) ++; return stress; } /* Precondition: configuration was not changed since previous call to func */ static void dfunc (Daata object, const double * /* p */, double dp[]) { Kruskal me = (Kruskal) object; Configuration thee = my configuration.peek(); long k = 1; for (long i = 1; i <= thy numberOfRows; i++) { for (long j = 1; j <= thy numberOfColumns; j++) { dp[k++] = my dx[i][j]; } } } Thing_implement (Kruskal, Thing, 0); void structKruskal :: v_destroy () { NUMmatrix_free (dx, 1, 1); forget (proximities); forget (vec); forget (minimizer); Kruskal_Parent :: v_destroy (); } Kruskal Kruskal_create (long numberOfPoints, long numberOfDimensions) { try { autoKruskal me = Thing_new (Kruskal); my proximities = Proximities_create (); my configuration = Configuration_create (numberOfPoints, numberOfDimensions); my dx = NUMmatrix (1, numberOfPoints, 1, numberOfDimensions); return me.transfer(); } catch (MelderError) { Melder_throw (U"Kruskal not created."); } } Configuration Dissimilarity_kruskal (Dissimilarity me, long numberOfDimensions, long /* metric */, int tiesProcessing, int stress_formula, double tolerance, long numberOfIterations, long numberOfRepetitions) { try { int scale = 1; autoDistance d = Dissimilarity_to_Distance (me, scale); autoConfiguration c = Distance_to_Configuration_torsca (d.peek(), numberOfDimensions); Configuration_normalize (c.peek(), 1.0, 0); autoConfiguration thee = Dissimilarity_Configuration_kruskal (me, c.peek(), tiesProcessing, stress_formula, tolerance, numberOfIterations, numberOfRepetitions); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no Configuration created (kruskal method)."); } } void Dissimilarity_Configuration_drawShepardDiagram (Dissimilarity me, Configuration him, Graphics g, double xmin, double xmax, double ymin, double ymax, double size_mm, const char32 *mark, int garnish) { autoDistance dist = Configuration_to_Distance (him); Proximity_Distance_drawScatterDiagram (me, dist.peek(), g, xmin, xmax, ymin, ymax, size_mm, mark, garnish); } Distance Dissimilarity_Configuration_monotoneRegression (Dissimilarity dissimilarity, Configuration configuration, int tiesProcessing) { try { autoDistance dist = Configuration_to_Distance (configuration); autoDistance result = Dissimilarity_Distance_monotoneRegression (dissimilarity, dist.peek(), tiesProcessing); return result.transfer(); } catch (MelderError) { Melder_throw (U"No Distance created (monotone regression)."); } } Distances Dissimilarities_Configuration_monotoneRegression (Dissimilarities me, Configuration configuration, int tiesProcessing) { try { autoDistances result = Distances_create (); autoDistance dist = Configuration_to_Distance (configuration); for (long i = 1; i <= my size; i++) { autoDistance d = Dissimilarity_Distance_monotoneRegression ((Dissimilarity) my item[i], dist.peek(), tiesProcessing); Collection_addItem (result.peek(), d.transfer()); } return result.transfer(); } catch (MelderError) { Melder_throw (U"No Distances created (monotone regression)."); } } void Dissimilarity_Configuration_drawMonotoneRegression (Dissimilarity me, Configuration him, Graphics g, int tiesProcessing, double xmin, double xmax, double ymin, double ymax, double size_mm, const char32 *mark, int garnish) { /* obsolete replace by transformator */ autoDistance fit = Dissimilarity_Configuration_monotoneRegression (me, him, tiesProcessing); Proximity_Distance_drawScatterDiagram (me, fit.peek(), g, xmin, xmax, ymin, ymax, size_mm, mark, garnish); } void Dissimilarity_Configuration_Weight_drawAbsoluteRegression (Dissimilarity d, Configuration c, Weight w, Graphics g, double xmin, double xmax, double ymin, double ymax, double size_mm, const char32 *mark, int garnish) { autoTransformator t = Transformator_create (d -> numberOfRows); autoDistance fit = Dissimilarity_Configuration_Transformator_Weight_transform (d, c, t.peek(), w); Proximity_Distance_drawScatterDiagram (d, fit.peek(), g, xmin, xmax, ymin, ymax, size_mm, mark, garnish); } void Dissimilarity_Configuration_Weight_drawRatioRegression (Dissimilarity d, Configuration c, Weight w, Graphics g, double xmin, double xmax, double ymin, double ymax, double size_mm, const char32 *mark, int garnish) { autoRatioTransformator t = RatioTransformator_create (d -> numberOfRows); autoDistance fit = Dissimilarity_Configuration_Transformator_Weight_transform (d, c, t.peek(), w); Proximity_Distance_drawScatterDiagram (d, fit.peek(), g, xmin, xmax, ymin, ymax, size_mm, mark, garnish); } void Dissimilarity_Configuration_Weight_drawIntervalRegression (Dissimilarity d, Configuration c, Weight w, Graphics g, double xmin, double xmax, double ymin, double ymax, double size_mm, const char32 *mark, int garnish) { Dissimilarity_Configuration_Weight_drawISplineRegression (d, c, w, g, 0.0, 1.0, xmin, xmax, ymin, ymax, size_mm, mark, garnish); } void Dissimilarity_Configuration_Weight_drawMonotoneRegression (Dissimilarity d, Configuration c, Weight w, Graphics g, int tiesProcessing, double xmin, double xmax, double ymin, double ymax, double size_mm, const char32 *mark, int garnish) { autoMonotoneTransformator t = MonotoneTransformator_create (d->numberOfRows); MonotoneTransformator_setTiesProcessing (t.peek(), tiesProcessing); autoDistance fit = Dissimilarity_Configuration_Transformator_Weight_transform (d, c, t.peek(), w); Proximity_Distance_drawScatterDiagram (d, fit.peek(), g, xmin, xmax, ymin, ymax, size_mm, mark, garnish); } void Dissimilarity_Configuration_Weight_drawISplineRegression (Dissimilarity d, Configuration c, Weight w, Graphics g, long numberOfInternalKnots, long order, double xmin, double xmax, double ymin, double ymax, double size_mm, const char32 *mark, int garnish) { autoISplineTransformator t = ISplineTransformator_create (d->numberOfRows, numberOfInternalKnots, order); autoDistance fit = Dissimilarity_Configuration_Transformator_Weight_transform (d, c, t.peek(), w); Proximity_Distance_drawScatterDiagram (d, fit.peek(), g, xmin, xmax, ymin, ymax, size_mm, mark, garnish); } Distance Dissimilarity_Configuration_Transformator_Weight_transform (Dissimilarity d, Configuration c, Transformator t, Weight w) { try { autoWeight aw; if (! w) { aw.reset (Weight_create (d -> numberOfRows)); w = aw.peek(); } autoDistance cdist = Configuration_to_Distance (c); autoMDSVec v = Dissimilarity_to_MDSVec (d); autoDistance thee = Transformator_transform (t, v.peek(), cdist.peek(), w); return thee.transfer(); } catch (MelderError) { Melder_throw (U"Distance not created."); } } double Dissimilarity_Configuration_Weight_Transformator_normalizedStress (Dissimilarity me, Configuration conf, Weight weight, Transformator t) { autoDistance cdist = Configuration_to_Distance (conf); autoMDSVec vec = Dissimilarity_to_MDSVec (me); autoDistance fdist = Transformator_transform (t, vec.peek(), cdist.peek(), weight); double stress = Distance_Weight_stress (fdist.peek(), cdist.peek(), weight, MDS_NORMALIZED_STRESS); return stress; } double Dissimilarity_Configuration_getStress (Dissimilarity me, Configuration him, int tiesProcessing, int stress_formula) { autoDistance dist = Configuration_to_Distance (him); autoMDSVec vec = Dissimilarity_to_MDSVec (me); autoDistance fit = MDSVec_Distance_monotoneRegression (vec.peek(), dist.peek(), tiesProcessing); double s, t, dbar, stress; MDSVec_Distances_getStressValues (vec.peek(), dist.peek(), fit.peek(), stress_formula, &stress, &s, &t, &dbar); return stress; } Configuration Dissimilarity_Configuration_kruskal (Dissimilarity me, Configuration him, int tiesProcessing, int stress_formula, double tolerance, long numberOfIterations, long numberOfRepetitions) { try { // The Configuration is normalized: each dimension centred + // total variance set long numberOfCoordinates = my numberOfRows * his numberOfColumns; long numberOfParameters = numberOfCoordinates - his numberOfColumns - 1; long numberOfData = my numberOfRows * (my numberOfRows - 1) / 2; if (numberOfData < numberOfParameters) { Melder_throw (U"The number of data must be larger than number of parameters in the model."); } autoKruskal thee = Kruskal_create (my numberOfRows, his numberOfColumns); TableOfReal_copyLabels (me, thy configuration.peek(), 1, 0); autoDissimilarity dissimilarity = Data_copy (me); Collection_addItem (thy proximities, dissimilarity.transfer()); thy vec = Dissimilarity_to_MDSVec (me); thy minimizer = (Minimizer) VDSmagtMinimizer_create (numberOfCoordinates, (Daata) thee.peek(), func, dfunc); NUMdmatrix_into_vector (his data, thy minimizer -> p, 1, his numberOfRows, 1, his numberOfColumns); thy stress_formula = stress_formula; thy process = tiesProcessing; Configuration_setMetric (thy configuration.peek(), his metric); Minimizer_minimizeManyTimes (thy minimizer, numberOfRepetitions, numberOfIterations, tolerance); // call the function to get the best configuration (void) func ((Daata) thee.peek(), ((Minimizer) (thy minimizer)) -> p); autoConfiguration result = Data_copy (thy configuration.peek()); return result.transfer(); } catch (MelderError) { Melder_throw (me, U": no Configuration created."); } } /************************** INDSCAL **************************************/ /* Ten Berge, Kiers & Krijnen (1993), Computational Solutions for the Problem of Negative Saliences and Nonsymmetry in INDSCAL, Journal of Classification 10, 115-124. */ static void indscal_iteration_tenBerge (ScalarProducts zc, Configuration xc, Salience weights) { long nPoints = xc -> numberOfRows, nDimensions = xc -> numberOfColumns; long nSources = zc -> size; double **x = xc -> data, **w = weights -> data, lambda; // tolerance = 1e-4 is nearly optimal for dominant eigenvector estimation. double tolerance = 1e-4; autoNUMmatrix wsih (1, nPoints, 1, nPoints); autoNUMvector solution (1, nPoints); for (long h = 1; h <= nDimensions; h++) { autoCollection sprc = Data_copy ( (Collection) zc); for (long k = 1; k <= nPoints; k++) { for (long l = 1; l <= nPoints; l++) { wsih[k][l] = 0.0; } } for (long i = 1; i <= nSources; i++) { ScalarProduct spr = (ScalarProduct) sprc -> item[i]; double **sih = spr -> data; // Construct the S[i][h] matrices (eq. 6) for (long j = 1; j <= nDimensions; j++) { if (j == h) { continue; } for (long k = 1; k <= nPoints; k++) { for (long l = 1; l <= nPoints; l++) { sih[k][l] -= x[k][j] * x[l][j] * w[i][j]; } } } // the weighted S matrix (eq. 8) for (long k = 1; k <= nPoints; k++) { for (long l = 1; l <= nPoints; l++) { wsih[k][l] += w[i][h] * sih[k][l]; } } } // largest eigenvalue of m (nonsymmetric matrix!!) is optimal solution for this dimension for (long k = 1; k <= nPoints; k++) { solution[k] = x[k][h]; } NUMdominantEigenvector (wsih.peek(), nPoints, solution.peek(), &lambda, tolerance); // normalize the solution: centre and x'x = 1 double mean = 0.0; for (long k = 1; k <= nPoints; k++) { mean += solution[k]; } mean /= nPoints; if (mean == 0.0) { continue; } double scale = 0.0; for (long k = 1; k <= nPoints; k++) { solution[k] -= mean; scale += solution[k] * solution[k]; } for (long k = 1; k <= nPoints; k++) { x[k][h] = solution[k] / sqrt (scale); } // update weights. Make negative weights zero. for (long i = 1; i <= nSources; i++) { ScalarProduct spr = (ScalarProduct) sprc -> item[i]; double **sih = spr -> data, wih = 0; for (long k = 1; k <= nPoints; k++) { for (long l = 1; l <= nPoints; l++) { wih += x[k][h] * sih[k][l] * x[l][h]; } } if (wih < 0.0) { wih = 0.0; } w[i][h] = wih; } } } void ScalarProducts_Configuration_Salience_indscal (ScalarProducts sp, Configuration configuration, Salience weights, double tolerance, long numberOfIterations, int showProgress, autoConfiguration *out1, autoSalience *out2, double *varianceAccountedFor) { try { double tol = 1e-6, vafp = 0.0, vaf; long nZeros = 0, nSources = sp -> size, iter; autoConfiguration x = Data_copy (configuration); autoSalience w = Data_copy (weights); if (showProgress) { Melder_progress (0.0, U"INDSCAL analysis"); } // Solve for X, and W matrix via Alternating Least Squares. for (iter = 1; iter <= numberOfIterations; iter++) { indscal_iteration_tenBerge (sp, x.peek(), w.peek()); // Goodness of fit and test criterion. ScalarProducts_Configuration_Salience_vaf (sp, x.peek(), w.peek(), &vaf); if (vaf > 1.0 - tol || fabs (vaf - vafp) / vafp < tolerance) { break; } vafp = vaf; if (showProgress) { Melder_progress ( (double) iter / (numberOfIterations + 1), U"indscal: vaf ", vaf); } } // Count number of zero weights nZeros = NUMdmatrix_countZeros (w -> data, w -> numberOfRows, w -> numberOfColumns); // Set labels & names. Thing_setName (x.peek(), U"indscal"); Thing_setName (w.peek(), U"indscal"); TableOfReal_labelsFromCollectionItemNames (w.peek(), sp, 1, 0); *out1 = x.move(); *out2 = w.move(); if (varianceAccountedFor) { *varianceAccountedFor = vaf; } if (showProgress) { MelderInfo_writeLine (U"**************** INDSCAL results on Distances *******************\n\n", Thing_className (sp), U"number of objects: ", nSources); for (long i = 1; i <= nSources; i++) { MelderInfo_writeLine (U" ", Thing_getName ( (Thing) sp -> item[i])); } if (nZeros > 0) { MelderInfo_writeLine (U"WARNING: ", nZeros, U" zero weight", (nZeros > 1 ? U"s" : U""), U"!"); } MelderInfo_writeLine (U"\n\nVariance Accounted For = ", vaf, U"\nThe optimal configuration was reached in ", (iter > numberOfIterations ? numberOfIterations : iter), U" iterations."); MelderInfo_drain(); } if (showProgress) { Melder_progress (1.0); } } catch (MelderError) { if (showProgress) { Melder_progress (1.0); } Melder_throw (U"No indscal configuration calculated."); } } void Distances_Configuration_Salience_indscal (Distances distances, Configuration configuration, Salience weights, int normalizeScalarProducts, double tolerance, long numberOfIterations, int showProgress, autoConfiguration *out1, autoSalience *out2, double *vaf) { try { autoScalarProducts sp = Distances_to_ScalarProducts (distances, normalizeScalarProducts); ScalarProducts_Configuration_Salience_indscal (sp.peek(), configuration, weights, tolerance, numberOfIterations, showProgress, out1, out2, vaf); } catch (MelderError) { Melder_throw (U"No indscal configuration calculated."); } } void Dissimilarities_Configuration_Salience_indscal (Dissimilarities dissims, Configuration configuration, Salience weights, int tiesProcessing, int normalizeScalarProducts, double tolerance, long numberOfIterations, int showProgress, autoConfiguration *out1, autoSalience *out2, double *varianceAccountedFor) { try { double tol = 1e-6, vafp = 0, vaf; long iter, nSources = dissims -> size;; autoConfiguration x = Data_copy (configuration); autoSalience w = Data_copy (weights); autoMDSVecs vecs = Dissimilarities_to_MDSVecs (dissims); if (showProgress) { Melder_progress (0.0, U"INDSCAL analysis"); } for (iter = 1; iter <= numberOfIterations; iter++) { autoDistances distances = MDSVecs_Configuration_Salience_monotoneRegression (vecs.peek(), x.peek(), w.peek(), tiesProcessing); autoScalarProducts sp = Distances_to_ScalarProducts (distances.peek(), normalizeScalarProducts); indscal_iteration_tenBerge (sp.peek(), x.peek(), w.peek()); // Goodness of fit and test criterion. Distances_Configuration_Salience_vaf (distances.peek(), x.peek(), w.peek(), normalizeScalarProducts, &vaf); if (vaf > 1.0 - tol || fabs (vaf - vafp) / vafp < tolerance) { break; } vafp = vaf; if (showProgress) { Melder_progress ((double) iter / (numberOfIterations + 1), U"indscal: vaf ", vaf); } } // Count number of zero weights long nZeros = NUMdmatrix_countZeros (w -> data, w -> numberOfRows, w -> numberOfColumns); // Set labels & names. Thing_setName (x.peek(), U"indscal_mr"); Thing_setName (w.peek(), U"indscal_mr"); TableOfReal_labelsFromCollectionItemNames (w.peek(), dissims, 1, 0); *out1 = x.move(); *out2 = w.move(); if (varianceAccountedFor) { *varianceAccountedFor = vaf; } if (showProgress) { MelderInfo_writeLine (U"**************** INDSCAL with monotone regression *******************"); MelderInfo_writeLine (Thing_className (dissims)); MelderInfo_writeLine (U"Number of objects: ", nSources); for (long i = 1; i <= nSources; i++) { MelderInfo_writeLine (U" ", Thing_getName ( (Thing) dissims -> item[i])); } if (nZeros > 0) { MelderInfo_writeLine (U"WARNING: ", nZeros, U" zero weight", (nZeros > 1 ? U"s" : U"")); } MelderInfo_writeLine (U"Variance Accounted For: ", vaf); MelderInfo_writeLine (U"Based on MONOTONE REGRESSION"); MelderInfo_writeLine (U"number of iterations: ", (iter > numberOfIterations ? numberOfIterations : iter)); MelderInfo_drain(); } if (showProgress) { Melder_progress (1.0); } } catch (MelderError) { if (showProgress) { Melder_progress (1.0); } Melder_throw (U"no inscal configuration calculated."); } } void Distances_Configuration_indscal (Distances dists, Configuration conf, int normalizeScalarProducts, double tolerance, long numberOfIterations, int showProgress, autoConfiguration *out1, autoSalience *out2) { try { autoSalience w = Salience_create (dists -> size, conf -> numberOfColumns); double vaf; Distances_Configuration_Salience_indscal (dists, conf, w.peek(), normalizeScalarProducts, tolerance, numberOfIterations, showProgress, out1, out2, &vaf); } catch (MelderError) { Melder_throw (U"No indscal performed."); } } Distances MDSVecs_Configuration_Salience_monotoneRegression (MDSVecs vecs, Configuration conf, Salience weights, int tiesProcessing) { try { long nDimensions = conf -> numberOfColumns; autoNUMvector w (NUMvector_copy (conf -> w, 1, nDimensions), 1); autoDistances distances = Distances_create (); for (long i = 1; i <= vecs -> size; i++) { NUMvector_copyElements (weights -> data[i], conf -> w, 1, nDimensions); autoDistance dc = Configuration_to_Distance (conf); autoDistance dist = MDSVec_Distance_monotoneRegression ((MDSVec) vecs -> item[i], dc.peek(), tiesProcessing); Collection_addItem (distances.peek(), dist.transfer()); } Configuration_setDefaultWeights (conf); return distances.transfer(); } catch (MelderError) { Melder_throw (U"No Distances created."); } } Salience Distances_Configuration_to_Salience (Distances d, Configuration c, int normalize) { try { autoScalarProducts sp = Distances_to_ScalarProducts (d, normalize); autoSalience w = ScalarProducts_Configuration_to_Salience (sp.peek(), c); return w.transfer(); } catch (MelderError) { Melder_throw (U"No Salience created."); } } Salience ScalarProducts_Configuration_to_Salience (ScalarProducts me, Configuration him) { try { autoSalience salience = Salience_create (my size, his numberOfColumns); autoConfiguration cx = Data_copy (him); indscal_iteration_tenBerge (me, cx.peek(), salience.peek()); return salience.transfer(); } catch (MelderError) { Melder_throw (U"No Salience created."); } } Salience Dissimilarities_Configuration_to_Salience (Dissimilarities me, Configuration him, int tiesProcessing, int normalizeScalarProducts) { try { autoDistances distances = Dissimilarities_Configuration_monotoneRegression (me, him, tiesProcessing); autoSalience w = Distances_Configuration_to_Salience (distances.peek(), him, normalizeScalarProducts); return w.transfer(); } catch (MelderError) { Melder_throw (U"No Salience created."); } } void Dissimilarities_Configuration_indscal (Dissimilarities dissims, Configuration conf, int tiesProcessing, int normalizeScalarProducts, double tolerance, long numberOfIterations, int showProgress, autoConfiguration *out1, autoSalience *out2) { try { autoDistances distances = Dissimilarities_Configuration_monotoneRegression (dissims, conf, tiesProcessing); autoSalience weights = Distances_Configuration_to_Salience (distances.peek(), conf, normalizeScalarProducts); double vaf; Dissimilarities_Configuration_Salience_indscal (dissims, conf, weights.peek(), tiesProcessing, normalizeScalarProducts, tolerance, numberOfIterations, showProgress, out1, out2, &vaf); } catch (MelderError) { Melder_throw (U"No indscal performed."); } } void Dissimilarities_indscal (Dissimilarities me, long numberOfDimensions, int tiesProcessing, int normalizeScalarProducts, double tolerance, long numberOfIterations, long numberOfRepetitions, int showProgress, autoConfiguration *out1, autoSalience *out2) { int showMulti = showProgress && numberOfRepetitions > 1; try { int showSingle = showProgress && numberOfRepetitions == 1; double vaf, vafmin = 0.0; autoDistances distances = Dissimilarities_to_Distances (me, MDS_ORDINAL); autoConfiguration cstart; autoSalience wstart; Distances_to_Configuration_ytl (distances.peek(), numberOfDimensions, normalizeScalarProducts, &cstart, &wstart); autoConfiguration cbest = Data_copy (cstart.peek()); autoSalience wbest = Data_copy (wstart.peek()); if (showMulti) { Melder_progress (0.0, U"Indscal many times"); } for (long iter = 1; iter <= numberOfRepetitions; iter++) { autoConfiguration cresult; autoSalience wresult; Dissimilarities_Configuration_Salience_indscal (me, cstart.peek(), wstart.peek(), tiesProcessing, normalizeScalarProducts, tolerance, numberOfIterations, showSingle, &cresult, &wresult, &vaf); if (vaf > vafmin) { vafmin = vaf; cbest = cresult.move(); wbest = wresult.move(); } Configuration_randomize (cstart.peek()); Configuration_normalize (cstart.peek(), 1.0, 1); Salience_setDefaults (wstart.peek()); if (showMulti) { Melder_progress ( (double) iter / (numberOfRepetitions + 1), iter, U" from ", numberOfRepetitions); } } *out1 = cbest.move(); *out2 = wbest.move(); if (showMulti) { Melder_progress (1.0); } } catch (MelderError) { if (showMulti) { Melder_progress (1.0); } Melder_throw (me, U": no indscal performed."); } } void Distances_indscal (Distances distances, long numberOfDimensions, int normalizeScalarProducts, double tolerance, long numberOfIterations, long numberOfRepetitions, int showProgress, autoConfiguration *out1, autoSalience *out2) { int showMulti = showProgress && numberOfRepetitions > 1; try { int showSingle = showProgress && numberOfRepetitions == 1; double vaf, vafmin = 0; autoConfiguration cstart; autoSalience wstart; Distances_to_Configuration_ytl (distances, numberOfDimensions, normalizeScalarProducts, &cstart, &wstart); autoConfiguration cbest = Data_copy (cstart.peek()); autoSalience wbest = Data_copy (wstart.peek()); if (showMulti) { Melder_progress (0.0, U"Indscal many times"); } for (long i = 1; i <= numberOfRepetitions; i++) { autoConfiguration cresult; autoSalience wresult; Distances_Configuration_Salience_indscal (distances, cstart.peek(), wstart.peek(), normalizeScalarProducts, tolerance, numberOfIterations, showSingle, &cresult, &wresult, &vaf); if (vaf > vafmin) { vafmin = vaf; cbest = cresult.move(); wbest = wresult.move(); } Configuration_randomize (cstart.peek()); Configuration_normalize (cstart.peek(), 1.0, 1); Salience_setDefaults (wstart.peek()); if (showMulti) { Melder_progress ((double) i / (numberOfRepetitions + 1), i, U" from ", numberOfRepetitions); } } *out1 = cbest.move(); *out2 = wbest.move(); if (showMulti) { Melder_progress (1.0); } } catch (MelderError) { if (showMulti) { Melder_progress (1.0); } Melder_throw (distances, U": no indscal performed."); } } void Dissimilarities_Configuration_Salience_vaf (Dissimilarities me, Configuration thee, Salience him, int tiesProcessing, int normalizeScalarProducts, double *vaf) { autoDistances distances = Dissimilarities_Configuration_monotoneRegression (me, thee, tiesProcessing); Distances_Configuration_Salience_vaf (distances.peek(), thee, him, normalizeScalarProducts, vaf); } void Distances_Configuration_vaf (Distances me, Configuration thee, int normalizeScalarProducts, double *vaf) { autoSalience w = Distances_Configuration_to_Salience (me, thee, normalizeScalarProducts); Distances_Configuration_Salience_vaf (me, thee, w.peek(), normalizeScalarProducts, vaf); } void Dissimilarities_Configuration_vaf (Dissimilarities me, Configuration thee, int tiesProcessing, int normalizeScalarProducts, double *vaf) { autoSalience w = Dissimilarities_Configuration_to_Salience (me, thee, tiesProcessing, normalizeScalarProducts); Dissimilarities_Configuration_Salience_vaf (me, thee, w.peek(), tiesProcessing, normalizeScalarProducts, vaf); } void Distances_Configuration_Salience_vaf (Distances me, Configuration thee, Salience him, int normalizeScalarProducts, double *vaf) { if (my size != his numberOfRows || thy numberOfColumns != his numberOfColumns) { Melder_throw (U"Dimensions must conform."); } autoScalarProducts sp = Distances_to_ScalarProducts (me, normalizeScalarProducts); ScalarProducts_Configuration_Salience_vaf (sp.peek(), thee, him, vaf); } void ScalarProduct_Configuration_getVariances (ScalarProduct me, Configuration thee, double *varianceExplained, double *varianceTotal) { double varExplained = 0.0, varTotal = 0.0; autoDistance distance = Configuration_to_Distance (thee); autoScalarProduct fit = Distance_to_ScalarProduct (distance.peek(), 0); // ScalarProduct is double centred, i.e., mean == 0. for (long j = 1; j <= my numberOfRows; j++) { for (long k = 1; k <= my numberOfColumns; k++) { double d2 = my data[j][k] - fit -> data[j][k]; varExplained += d2 * d2; varTotal += my data[j][k] * my data[j][k]; } } if (varianceExplained) { *varianceExplained = varExplained; } if (varianceTotal) { *varianceTotal = varTotal; } } void ScalarProducts_Configuration_Salience_vaf (ScalarProducts me, Configuration thee, Salience him, double *vaf) { autoNUMvector w (NUMvector_copy (thy w, 1, thy numberOfColumns), 1); // save weights try { if (my size != his numberOfRows || thy numberOfColumns != his numberOfColumns) { Melder_throw (U"Dimensions of input objects must conform."); } double t = 0.0, n = 0.0; for (long i = 1; i <= my size; i++) { ScalarProduct sp = (ScalarProduct) my item[i]; if (sp -> numberOfRows != thy numberOfRows) { Melder_throw (U"ScalarProduct ", i, U" does not match Configuration."); } // weigh configuration before calculating variances for (long j = 1; j <= thy numberOfColumns; j++) { thy w[j] = sqrt (his data[i][j]); } double vare, vart; ScalarProduct_Configuration_getVariances (sp, thee, &vare, &vart); t += vare; n += vart; } if (vaf) { *vaf = n > 0.0 ? 1.0 - t / n : 0.0; } NUMvector_copyElements (w.peek(), thy w, 1, thy numberOfColumns); // restore weights } catch (MelderError) { NUMvector_copyElements (w.peek(), thy w, 1, thy numberOfColumns); Melder_throw (U"No vaf calculasted."); } } /********************** Examples *********************************************/ Dissimilarity Dissimilarity_createLetterRExample (double noiseStd) { try { autoConfiguration r = Configuration_createLetterRExample (1); autoDistance d = Configuration_to_Distance (r.peek()); autoDissimilarity me = Distance_to_Dissimilarity (d.peek()); Thing_setName (me.peek(), U"R"); for (long i = 1; i <= my numberOfRows - 1; i++) { for (long j = i + 1; j <= my numberOfRows; j++) { double dis = my data[i][j]; my data[j][i] = my data[i][j] = dis * dis + 5.0 + NUMrandomUniform (0.0, noiseStd); } } return me.transfer(); } catch (MelderError) { Melder_throw (U"Dissimilarity for letter R example not created."); } } Salience Salience_createCarrollWishExample () { try { long numberOfSources = 8; double wx[9] = {0, 1.0, 0.866, 0.707, 0.5, 0.1, 0.5, 0.354, 0.1}; double wy[9] = {0, 0.1, 0.5, 0.707, 0.866, 1, 0.1, 0.354, 0.5}; const char32 *name[] = { U"", U"1", U"2", U"3", U"4", U"5", U"6", U"7", U"8"}; autoSalience me = Salience_create (numberOfSources, 2); for (long i = 1; i <= numberOfSources; i++) { my data[i][1] = wx[i]; my data[i][2] = wy[i]; TableOfReal_setRowLabel (me.peek(), i, name[i]); } return me.transfer(); } catch (MelderError) { Melder_throw (U"Salience for Carroll Wish example not created."); } } Collection INDSCAL_createCarrollWishExample (double noiseRange) { try { autoConfiguration c = Configuration_createCarrollWishExample (); long numberOfObjects = c -> numberOfRows, numberOfSources = 8; autoSalience s = Salience_createCarrollWishExample (); autoCollection me = Collection_create (classDaata, numberOfSources); for (long l = 1; l <= numberOfSources; l++) { c -> w[1] = s -> data[l][1]; c -> w[2] = s -> data[l][2]; autoDistance d = Configuration_to_Distance (c.peek()); autoDissimilarity dissim = Distance_to_Dissimilarity (d.peek()); for (long i = 1; i <= numberOfObjects - 1; i++) { for (long j = i + 1; j <= numberOfObjects; j++) { dissim -> data[i][j] = (dissim -> data[j][i] += NUMrandomUniform (0.0, noiseRange)); } } Thing_setName (dissim.peek(), s -> rowLabels[l]); Collection_addItem (me.peek(), dissim.transfer()); } Thing_setName (me.peek(), U"CarrollWish"); return me.transfer(); } catch (MelderError) { Melder_throw (U"Collection not created."); } } void drawSplines (Graphics g, double low, double high, double ymin, double ymax, int type, long order, const char32 *interiorKnots, int garnish) { long k = order, numberOfKnots, numberOfInteriorKnots = 0; long nSplines, n = 1000; double knot[101], y[1001]; if (type == MDS_ISPLINE) { k++; } for (long i = 1; i <= k; i++) { knot[i] = low; } numberOfKnots = k; { // scope char *start = Melder_peek32to8 (interiorKnots), *end; // UGLY; because of non-availability of str32tod while (*start) { double value = strtod (start, &end); start = end; if (value < low || value > high) { Melder_warning (U"drawSplines: knots must be in interval (", low, U", ", high, U")"); return; } if (numberOfKnots == 100) { Melder_warning (U"drawSplines: too many knots (101)"); return; } knot[++numberOfKnots] = value; } } numberOfInteriorKnots = numberOfKnots - k; for (long i = 1; i <= k; i++) { knot[++numberOfKnots] = high; } nSplines = order + numberOfInteriorKnots; if (nSplines == 0) { return; } Graphics_setWindow (g, low, high, ymin, ymax); Graphics_setInner (g); for (long i = 1; i <= nSplines; i++) { double x, yx, dx = (high - low) / (n - 1); for (long j = 1; j <= n; j++) { x = low + dx * (j - 1); if (type == MDS_MSPLINE) { (void) NUMmspline (knot, numberOfKnots, order, i, x, &yx); } else { (void) NUMispline (knot, numberOfKnots, order, i, x, &yx); } y[j] = yx < ymin ? ymin : yx > ymax ? ymax : yx; } Graphics_function (g, y, 1, n, low, high); } Graphics_unsetInner (g); if (garnish) { static MelderString ts { 0 }; long lastKnot = type == MDS_ISPLINE ? numberOfKnots - 2 : numberOfKnots; Graphics_drawInnerBox (g); Graphics_textLeft (g, false, type == MDS_MSPLINE ? U"\\s{M}\\--spline" : U"\\s{I}\\--spline"); Graphics_marksTop (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); if (low <= knot[order]) { if (order == 1) { MelderString_copy (&ts, U"t__1_"); } else if (order == 2) { MelderString_copy (&ts, U"{t__1_, t__2_}"); } else { MelderString_copy (&ts, U"{t__1_..t__", order, U"_}"); } Graphics_markBottom (g, low, false, false, false, ts.string); } for (long i = 1; i <= numberOfInteriorKnots; i++) { if (low <= knot[k + i] && knot[k + i] < high) { MelderString_copy (&ts, U"t__", order + i, U"_"); Graphics_markBottom (g, knot[k + i], false, true, true, ts.string); Graphics_markTop (g, knot[k + i], true, false, false, nullptr); } } if (knot[lastKnot - order + 1] <= high) { if (order == 1) { MelderString_copy (&ts, U"t__", lastKnot, U"_"); } else { MelderString_copy (&ts, U"{t__", (order == 2 ? lastKnot - 1 : lastKnot - order + 1), U"_, t__", lastKnot, U"_}"); } Graphics_markBottom (g, high, false, false, false, ts.string); } } } void drawMDSClassRelations (Graphics g) { long nBoxes = 6; double boxWidth = 0.3, boxWidth2 = boxWidth / 2.0, boxWidth3 = boxWidth / 3.0; double boxHeight = 0.1, boxHeight2 = boxHeight / 2.0; double boxHeight3 = boxHeight / 3.0; double r_mm = 3, dxt = 0.025, dyt = 0.03; double dboxx = 1.0 - 0.2 - 2.0 * boxWidth, dboxy = (1.0 - 4.0 * boxHeight) / 3.0; double x1, x2, xm, x23, x13, y1, y2, ym, y23, y13; double x[7] = {0.0, 0.2, 0.2, 0.7, 0.2, 0.7, 0.2}; /* left */ double y[7] = {0.0, 0.9, 0.6, 0.6, 0.3, 0.3, 0.0}; /* bottom */ const char32 *text[7] = {U"", U"Confusion", U"Dissimilarity %\\de__%%ij%_", U"Similarity", U"Distance %d__%%ij%_, %d\\'p__%%ij%_", U"ScalarProduct", U"Configuration" }; Graphics_setWindow (g, -0.05, 1.05, -0.05, 1.05); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); for (long i = 1; i <= nBoxes; i++) { x2 = x[i] + boxWidth; y2 = y[i] + boxHeight; xm = x[i] + boxWidth2; ym = y[i] + boxHeight2; Graphics_roundedRectangle (g, x[i], x2, y[i], y2, r_mm); Graphics_text (g, xm, ym, text[i]); } Graphics_setLineWidth (g, 2); Graphics_setTextAlignment (g, Graphics_LEFT, Graphics_BOTTOM); // Confusion to Dissimilarity xm = x[1] + boxWidth2; y2 = y[2] + boxHeight; Graphics_arrow (g, xm, y[1], xm, y2); Graphics_text (g, xm + dxt, y2 + dboxy / 2, U"pdf"); // Confusion to Similarity x1 = x[1] + boxWidth; xm = x[3] + boxWidth2; ym = y[1] + boxHeight2; y2 = y[3] + boxHeight; Graphics_line (g, x1, ym, xm, ym); Graphics_arrow (g, xm, ym, xm, y2); y2 += + dboxy / 2 + dyt / 2; Graphics_text (g, xm + dxt, y2, U"average"); y2 -= dyt; Graphics_text (g, xm + dxt, y2, U"houtgast"); // Dissimilarity to Similarity x1 = x[2] + boxWidth; y23 = y[2] + 2 * boxHeight3; Graphics_arrow (g, x1, y23, x[3], y23); y13 = y[2] + boxHeight3; Graphics_arrow (g, x[3], y13, x1, y13); // Dissimilarity to Distance x13 = x[4] + boxWidth3; y1 = y[4] + boxHeight; Graphics_arrow (g, x13, y1, x13, y[2]); x23 = x[4] + 2 * boxWidth3; Graphics_arrow (g, x23, y[2], x23, y1); x1 = x23 + dxt; y1 = y[2] - dyt; x2 = 0 + dxt; y1 -= dyt; Graphics_text (g, x1, y1, U"%d\\'p__%%ij%_ = %\\de__%%ij%_"); Graphics_text (g, x2, y1, U"absolute"); y1 -= dyt; Graphics_text (g, x1, y1, U"%d\\'p__%%ij%_ = %b\\.c%\\de__%%ij%_"); Graphics_text (g, x2, y1, U"ratio"); y1 -= dyt; Graphics_text (g, x1, y1, U"%d\\'p__%%ij%_ = %b\\.c%\\de__%%ij%_+%a"); Graphics_text (g, x2, y1, U"interval"); y1 -= dyt; Graphics_text (g, x1, y1, U"%d\\'p__%%ij%_ = \\s{I}-spline (%\\de__%%ij%_)"); Graphics_text (g, x2, y1, U"\\s{I}\\--spline"); y1 -= dyt; Graphics_text (g, x1, y1, U"%d\\'p__%%ij%_ = monotone (%\\de__%%ij%_)"); Graphics_text (g, x2, y1, U"monotone"); // Distance to ScalarProduct x1 = x[4] + boxWidth; ym = y[4] + boxHeight2; Graphics_arrow (g, x1, ym, x[5], ym); // Distance to Configuration y1 = y[6] + boxHeight; Graphics_arrow (g, x13, y1, x13, y[4]); // ScalarProduct to Configuration x13 = x[5] + boxWidth3; x23 = x[6] + 2 * boxWidth3; y1 = y[5] - dboxy / 2; Graphics_line (g, x13, y[5], x13, y1); Graphics_line (g, x13, y1, x23, y1); Graphics_arrow (g, x23, y1, x23, y[6] + boxHeight); x1 = x[6] + boxWidth + dboxx / 2; Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_BOTTOM); Graphics_text (g, x1, y1, U"\\s{TORSCA}"); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_TOP); Graphics_text (g, x1, y1, U"\\s{YTL}"); Graphics_setLineType (g, Graphics_DOTTED); x23 = x[5] + 2 * boxWidth3; ym = y[6] + boxHeight2; Graphics_line (g, x23, y[5], x23, ym); Graphics_arrow (g, x23, ym, x[6] + boxWidth, ym); x1 = x[6] + boxWidth + dboxx / 2 + boxWidth3; Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_BOTTOM); Graphics_text (g, x1, ym, U"\\s{INDSCAL}"); // Dissimilarity to Configuration ym = y[2] + boxHeight2; y2 = y[6] + boxHeight2; Graphics_line (g, x[2], ym, 0, ym); Graphics_line (g, 0, ym, 0, y2); Graphics_arrow (g, 0, y2, x[6], y2); // Restore settings Graphics_setLineType (g, Graphics_DRAWN); Graphics_setLineWidth (g, 1.0); Graphics_setTextAlignment (g, Graphics_LEFT, Graphics_BOTTOM); } /* End of file MDS.cpp */ praat-6.0.04/dwtools/MDS.h000066400000000000000000000517341261542461700152210ustar00rootroot00000000000000#ifndef _MDS_h_ #define _MDS_h_ /* MDS.h * * Multi Dimensional Scaling * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header djmw 20110306 Latest modification. */ #define KRUSKAL_MAXDIMENSION 10 /* process */ #define MDS_DISCRETE 0 #define MDS_CONTINUOUS 1 /* measurement conditionality */ #define MDS_UNCONDITIONAL 0 #define MDS_MATRIXCONDITIONAL 1 #define MDS_ROWCONDITIONAL 2 /* analysis level */ #define MDS_ABSOLUTE 0 #define MDS_RATIO 1 #define MDS_INTERVAL 2 #define MDS_SPLINE 3 #define MDS_ORDINAL 4 #define MDS_NOMINAL 5 /* normalization */ #define CONFIGURATION_COLUMNS 1 #define CONFIGURATION_MATRIX 2 /* ties processing */ #define MDS_PRIMARY_APPROACH 1 #define MDS_SECONDARY_APPROACH 2 /* stress */ #define MDS_NORMALIZED_STRESS 1 #define MDS_STRESS_1 2 #define MDS_STRESS_2 3 #define MDS_RAW_STRESS 4 #define MDS_MSPLINE 1 #define MDS_ISPLINE 2 #include "Graphics.h" #include "Minimizers.h" #include "Confusion.h" #include "ContingencyTable.h" #include "TableOfReal_extensions.h" #include "Proximity.h" #include "Distance.h" #include "Configuration.h" #include "SSCP.h" /************************** class Weight **************************************/ Thing_define (Weight, TableOfReal) { }; Weight Weight_create (long numberOfPoints); /************************** class Salience **************************************/ Thing_define (Salience, TableOfReal) { }; Salience Salience_create (long numberOfSources, long numberOfDimensions); void Salience_setDefaults (Salience me); long Salience_correctNegatives (Salience me); void Salience_draw (Salience me, Graphics g, int xdimension, int ydimension, int garnish); /************************** class MDSVec ******************************/ Thing_define (MDSVec, Daata) { // new data: public: long nProximities, nPoints; double *proximity; long *iPoint, *jPoint; // overridden methods: protected: virtual void v_destroy (); }; MDSVec MDSVec_create (long nObjects); /************** class MDSVecs *********************************/ Thing_define (MDSVecs, Ordered) { }; MDSVecs MDSVecs_create (); Configuration ContingencyTable_to_Configuration_ca (ContingencyTable me, long numberOfDimensions, int scaling); /********************* class Proximities *******************************/ Thing_define (Proximities, TablesOfReal) { }; void Proximities_init (Proximities me, ClassInfo klas); Proximities Proximities_create (); /****************** class Confusions **********************************/ Thing_define (Confusions, Proximities) { }; Confusions Confusions_create (); Confusion Confusions_sum (Confusions me); /************* class Distances **************************************/ Thing_define (Distances, Proximities) { }; Distances Distances_create (); /**************** class ScalarProduct **************************************/ Thing_define (ScalarProduct, TableOfReal) { }; ScalarProduct ScalarProduct_create (long numberOfPoints); /************** class ScalarProducts ********************************/ Thing_define (ScalarProducts, TablesOfReal) { }; ScalarProducts ScalarProducts_create (); /************* class Dissimilarity *********************************/ Thing_define (Dissimilarity, Proximity) { }; Dissimilarity Dissimilarity_create (long numberOfPoints); double Dissimilarity_getAdditiveConstant (Dissimilarity me); /* Get the best estimate for the additive constant: "distance = dissimilarity + constant" F. Cailliez (1983), The analytical solution of the additive constant problem, Psychometrika 48, 305-308. */ /****************** class Transformator *******************************/ Thing_define (Transformator, Thing) { // new data: public: long numberOfPoints; int normalization; // new methods: virtual Distance v_transform (MDSVec vec, Distance dist, Weight w); }; void Transformator_init (Transformator me, long numberOfPoints); Transformator Transformator_create (long numberOfPoints); void Transformator_setNormalization (Transformator me, int normalization); Distance Transformator_transform (Transformator me, MDSVec vec, Distance dist, Weight w); Thing_define (ISplineTransformator, Transformator) { // new data: public: long numberOfInteriorKnots, order, numberOfParameters; double **m, *b, *knot; // overridden methods: virtual void v_destroy (); virtual Distance v_transform (MDSVec vec, Distance dist, Weight w); }; ISplineTransformator ISplineTransformator_create (long numberOfPoints, long numberOfInteriorKnots, long order); Thing_define (RatioTransformator, Transformator) { // new data: public: double ratio; // overridden methods: virtual Distance v_transform (MDSVec vec, Distance dist, Weight w); }; RatioTransformator RatioTransformator_create (long numberOfPoints); Thing_define (MonotoneTransformator, Transformator) { // new data: public: int tiesProcessing; // overridden methods: virtual Distance v_transform (MDSVec vec, Distance dist, Weight w); }; MonotoneTransformator MonotoneTransformator_create (long numberPoints); void MonotoneTransformator_setTiesProcessing (MonotoneTransformator, int tiesProcessing); /*************** class Dissimilarities ****************************/ Thing_define (Dissimilarities, Proximities) { }; Dissimilarities Dissimilarities_create (); /**************** class Similarity *****************************/ Thing_define (Similarity, Proximity) { }; Similarity Similarity_create (long numberOfPoints); /************** KRUSKAL *********************************************/ Thing_define (Kruskal, Thing) { // new data: public: int process; int measurementLevel; int conditionality; autoConfiguration configuration; Proximities proximities; int stress_formula; MDSVec vec; double **dx; Minimizer minimizer; // overridden methods: virtual void v_destroy (); }; Kruskal Kruskal_create (long numberOfpoints, long numberOfDimensions); double Dissimilarity_Configuration_Weight_Transformator_normalizedStress (Dissimilarity me, Configuration conf, Weight weight, Transformator t); double Distance_Weight_stress (Distance fit, Distance c, Weight w, int type); /* Calculates stress. type is one of (MDS_NORMALIZED_STRESS, MDS_STRESS_1, MDS_STRESS_2, MDS_RAW_STRESS) */ double Distance_Weight_congruenceCoefficient (Distance x, Distance y, Weight w); /* Congruence coefficient B&G page 350. */ void Distance_Weight_rawStressComponents (Distance fit, Distance conf, Weight weight, double *eta_fit, double *eta_conf, double *rho); /* Computes eta_fit = sum (i 0); autoNUMvector c (1, my maximumNumberOfCoefficients); for (long i = 1; i <= my maximumNumberOfCoefficients; i++) { c[i] = (1 + lifter / 2 * sin (NUMpi * i / lifter)); } for (long frame = 1; frame <= my nx; frame++) { CC_Frame cf = (CC_Frame) & my frame[frame]; for (long i = 1; i <= cf -> numberOfCoefficients; i++) { cf -> c[i] *= c[i]; } } } catch (MelderError) { Melder_throw (me, U": not lifted."); } } TableOfReal MFCC_to_TableOfReal (MFCC me, bool includeC0) { try { long numberOfColumns = my maximumNumberOfCoefficients + (includeC0 ? 1 : 0); autoTableOfReal thee = TableOfReal_create (my nx, numberOfColumns); for (long i = 1; i <= numberOfColumns; i++) { TableOfReal_setColumnLabel (thee.peek(), i, Melder_cat (U"c", includeC0 ? i - 1 : i)); } long offset = includeC0 ? 1 : 0; for (long iframe = 1; iframe <= my nx; iframe++) { CC_Frame cf = (CC_Frame) & my frame[iframe]; for (long j = 1; j <= cf -> numberOfCoefficients; j++) { thy data[iframe][j + offset] = cf -> c[j]; } if (includeC0) { thy data[iframe][1] = cf -> c0; } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not converted to TabelOfReal."); } } // as_Sound not to_Sound Sound MFCC_to_Sound (MFCC me) { try { autoSound thee = Sound_create (my maximumNumberOfCoefficients, my xmin, my xmax, my nx, my dx, my x1); for (long iframe = 1; iframe <= my nx; iframe++) { CC_Frame cf = (CC_Frame) & my frame[iframe]; for (long j = 1; j <= my maximumNumberOfCoefficients; j++) { thy z[j][iframe] = cf -> c[j]; } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not represented as Sound."); } } Sound MFCCs_crossCorrelate (MFCC me, MFCC thee, enum kSounds_convolve_scaling scaling, enum kSounds_convolve_signalOutsideTimeDomain signalOutsideTimeDomain) { try { if (my dx != thy dx) { Melder_throw (U"The samplings of the two MFCC's have to be equal."); } if (my maximumNumberOfCoefficients != thy maximumNumberOfCoefficients) { Melder_throw (U"The number of coefficients in the two MFCC's have to be equal."); } autoSound target = MFCC_to_Sound (me); autoSound source = MFCC_to_Sound (thee); autoSound cc = Sounds_crossCorrelate (target.peek(), source.peek(), scaling, signalOutsideTimeDomain); return cc.transfer(); } catch (MelderError) { Melder_throw (U"No cross-correlation between ", me, U" and ", thee, U" calculated."); } } Sound MFCCs_convolve (MFCC me, MFCC thee, enum kSounds_convolve_scaling scaling, enum kSounds_convolve_signalOutsideTimeDomain signalOutsideTimeDomain) { try { if (my dx != thy dx) { Melder_throw (U"The samplings of the two MFCC's have to be equal."); } if (my maximumNumberOfCoefficients != thy maximumNumberOfCoefficients) { Melder_throw (U"The number of coefficients in the two MFCC's have to be equal."); } autoSound target = MFCC_to_Sound (me); autoSound source = MFCC_to_Sound (thee); autoSound cc = Sounds_convolve (target.peek(), source.peek(), scaling, signalOutsideTimeDomain); return cc.transfer(); } catch (MelderError) { Melder_throw (me, U" and ", thee, U" not convolved."); } } static double CC_Frames_distance (CC_Frame me, CC_Frame thee, bool includeEnergy) { double dist = 0; if (includeEnergy) { double d0 = my c0 - thy c0; dist += d0 * d0; } for (long i = 1; i <= my numberOfCoefficients; i++) { double di = my c[i] - thy c[i]; dist += di * di; } return sqrt (dist); } /* 1: cepstral difference function (d) * 2: spectral stability (dstab) * 3: spectral center of gravity (gs) * 4: stable internal duration */ Matrix MFCC_to_Matrix_features (MFCC me, double windowLength, bool includeEnergy) { try { long nw = (long) floor (windowLength / my dx / 2); autoMelSpectrogram him = MFCC_to_MelSpectrogram (me, 0, 0, 1); autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, 1, 4, 4, 1, 1); thy z[1][1] = thy z[1][my nx] = 0; // first & last frame for (long iframe = 2; iframe <= my nx - 1; iframe++) { CC_Frame cfi = (CC_Frame) & my frame[iframe]; // 1. cepstral difference long nwi = iframe > nw ? nw : iframe - 1; nwi = iframe < my nx - nwi ? nwi : my nx - iframe; double numer = 0; for (long j = 1; j <= nwi; j++) { numer += j * j; } numer *= 2; double dsq = 0; if (includeEnergy) { double sumj = 0; for (long j = 1; j <= nwi; j++) { CC_Frame cfp = (CC_Frame) & my frame[iframe + j]; CC_Frame cfm = (CC_Frame) & my frame[iframe - j]; sumj += j * (cfp -> c0 - cfm -> c0); } sumj /= numer; dsq += sumj * sumj; } for (long i = 1; i <= my maximumNumberOfCoefficients; i++) { double sumj = 0; for (long j = 1; j <= nwi; j++) { CC_Frame cfp = (CC_Frame) & my frame[iframe + j]; CC_Frame cfm = (CC_Frame) & my frame[iframe - j]; sumj += j * (cfp -> c[j] - cfm -> c[j]); } sumj /= numer; dsq += sumj * sumj; } thy z[1][iframe] = dsq; // 2: spectral stability (dstab) CC_Frame cfp = (CC_Frame) & my frame[iframe + 1]; CC_Frame cfm = (CC_Frame) & my frame[iframe - 1]; double dim1 = CC_Frames_distance (cfi, cfm, includeEnergy); double dip1 = CC_Frames_distance (cfi, cfp, includeEnergy); thy z[2][iframe] = (dim1 + dip1) / 2; // 3: spectral centere of gravity (gs) double msm = 0, sm = 0; for (long j = 1; j <= his ny; j++) { sm += his z[j][iframe]; msm += j * his z[j][iframe]; } double gs = sm == 0 ? 0 : msm / sm; thy z[3][iframe] = gs; // 4: stable internal duration } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no features calculated."); } } /* End of file MFCC.cpp */ praat-6.0.04/dwtools/MFCC.h000066400000000000000000000046221261542461700153000ustar00rootroot00000000000000#ifndef _MFCC_h_ #define _MFCC_h_ /* MFCC.h * * Mel Frequency Cepstral Coefficients class. * * Copyright (C) 1993-2013 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20010501 djmw 20020813 GPL header djmw 20120504 Latest modification. */ #include "CC.h" #include "Sound.h" #include "TableOfReal.h" Thing_define (MFCC, CC) { }; /* Three slightly "different" definitions of MFCC 1. Davis & Mermelstein MFCC[i] = SUM (j=1..N, f[j] * cos (i(j-1/2)pi/N)), i = 1..N-1 2. Vergin & O'Shaughnessy MFCC[i] = SUM (j=0..N-1, f[j] * cos (i(j+1/2)pi/N)), i = 0..N-1 3. HTK-book MFCC[i] = sqrt(2/n) SUM (j=1..N, f[j] * cos (i(j-1/2)pi/N)), i = 0..N-1 The f[j]'s are the MelSpectrogram values converted to dB. We follow the definition of Davis and Mermelstein: MFCC[i] = SUM (j=1..N, f[j] * cos (i(j-1/2)pi/N)), i=1..N-1, */ /* Interpretation: Mel frequency cepstral coefficient vectors as a function of time. c0 represents the sum of the dB filter outputs. */ MFCC MFCC_create (double tmin, double tmax, long nt, double dt, double t1, long maximumNumberOfCoefficients, double fmin_mel, double fmax_mel); void MFCC_lifter (MFCC me, long lifter); /* Lifter the cepstral coefficients: c[i] *= (1 + lifter / 2 * sin (NUMpi * i / lifter)) */ TableOfReal MFCC_to_TableOfReal (MFCC me, bool includeC0); Sound MFCC_to_Sound (MFCC me); Sound MFCCs_crossCorrelate (MFCC me, MFCC thee, enum kSounds_convolve_scaling scaling, enum kSounds_convolve_signalOutsideTimeDomain signalOutsideTimeDomain); Sound MFCCs_convolve (MFCC me, MFCC thee, enum kSounds_convolve_scaling scaling, enum kSounds_convolve_signalOutsideTimeDomain signalOutsideTimeDomain); Matrix MFCC_to_Matrix_features (MFCC me, double windowLength, bool includeEnergy); #endif /* _MFCC_h_ */ praat-6.0.04/dwtools/Makefile000066400000000000000000000044331261542461700160570ustar00rootroot00000000000000# Makefile of the library "dwtools" # David Weenink, 22 February 2010 # djmw 20150803 Latest modification include ../makefile.defs CPPFLAGS = -I ../num -I ../LPC -I ../fon -I ../sys -I ../stat -I ../dwsys -I ../external/portaudio -I ../external/espeak -I ../EEG -I ../kar OBJECTS = Activation.o AffineTransform.o \ Categories.o CategoriesEditor.o \ Categories_and_Strings.o CCA.o CCA_and_Correlation.o \ CC.o CCs_to_DTW.o \ ClassificationTable.o Confusion.o \ ComplexSpectrogram.o Configuration.o ContingencyTable.o \ Configuration_AffineTransform.o \ Configuration_and_Procrustes.o DataModeler.o Distance.o \ DTW.o DTW_and_TextGrid.o \ Discriminant.o Discriminant_Pattern_Categories.o \ EditDistanceTable.o EEG_extensions.o \ Eigen_and_Matrix.o Eigen_and_Procrustes.o \ Eigen_and_TableOfReal.o\ Eigen_and_SSCP.o Excitations.o \ FilterBank.o FormantGrid_extensions.o \ GaussianMixture.o \ HMM.o \ ICA.o Intensity_extensions.o \ LFCC.o LongSound_extensions.o \ KlattGrid.o KlattGridEditors.o KlattTable.o \ Ltas_extensions.o \ MFCC.o \ manual_DataModeler.o manual_dwtools.o manual_BSS.o manual_HMM.o \ manual_KlattGrid.o manual_MDS.o manual_Permutation.o \ Minimizers.o \ Matrix_extensions.o \ Matrix_Categories.o MDS.o \ OptimalCeilingTier.o OptimalCeilingTierEditor.o \ Pattern.o PCA.o \ Pitch_extensions.o Polynomial.o \ Polygon_extensions.o Procrustes.o \ Proximity.o \ Resonator.o \ Sampled2.o \ Sound_and_Spectrogram_extensions.o Sound_and_PCA.o Sound_extensions.o \ Sound_to_MFCC.o Sounds_to_DTW.o \ Sound_to_Pitch2.o Sound_to_SPINET.o SPINET.o SPINET_to_Pitch.o \ Spectrogram_extensions.o Spectrum_extensions.o SSCP.o Strings_extensions.o \ SpeechSynthesizer.o SpeechSynthesizer_and_TextGrid.o\ Table_extensions.o TableOfReal_and_SVD.o\ TableOfReal_extensions.o \ TableOfReal_and_Permutation.o \ TextGrid_extensions.o \ VowelEditor.o \ praat_MDS_init.o praat_BSS_init.o praat_HMM_init.o \ praat_KlattGrid_init.o praat_DataModeler_init.o praat_David_init.o .PHONY: all clean all: libdwtools.a clean: $(RM) $(OBJECTS) $(RM) libdwtools.a libdwtools.a: $(OBJECTS) touch libdwtools.a rm libdwtools.a $(AR) cq libdwtools.a $(OBJECTS) $(RANLIB) libdwtools.a $(OBJECTS): *.h ../num/NUM.h ../sys/*.h ../fon/*.h ../dwsys/*.h ../stat/*.h ../LPC/*.h ../external/espeak/*.h praat-6.0.04/dwtools/Matrix_Categories.cpp000066400000000000000000000031111261542461700205240ustar00rootroot00000000000000/* Matrix_Categories.cpp * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header */ #include "Matrix_Categories.h" #include "TableOfReal_extensions.h" 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."); } } /* End of file Matrix_Categories.cpp */ praat-6.0.04/dwtools/Matrix_Categories.h000066400000000000000000000021071261542461700201750ustar00rootroot00000000000000#ifndef _Matrix_Categories_h_ #define _Matrix_Categories_h_ /* Matrix_Categories.h * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header djmw 20110307 Latest modification */ #include "Matrix.h" #include "Categories.h" #include "TableOfReal.h" autoTableOfReal Matrix_and_Categories_to_TableOfReal (Matrix me, Categories thee); #endif /* _Matrix_Categories_h_ */ praat-6.0.04/dwtools/Matrix_extensions.cpp000066400000000000000000000256611261542461700206540ustar00rootroot00000000000000/* Matrix_extensions.cpp * * Copyright (C) 1993-2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header djmw 20040226 Matrix_drawAsSquares: respect the colour environment (fill with current colour). djmw 20041110 Matrix_drawDistribution did't draw lowest bin correctly. djmw 20050221 Matrix_drawDistribution would draw outside window. djmw 20050405 Matrix_drawDistribution crashed if minimum > data minimum5 djmw 20080122 float -> double */ #include "Matrix_extensions.h" #include "Eigen.h" #include "NUM2.h" void Matrix_scatterPlot (Matrix me, Graphics g, long icx, long icy, double xmin, double xmax, double ymin, double ymax, double size_mm, const char32 *mark, int garnish) { long ix = labs (icx), iy = labs (icy); if (ix < 1 || ix > my nx || iy < 1 || iy > my nx) { return; } if (xmax <= xmin) { (void) Matrix_getWindowExtrema (me, ix, ix, 1, my ny, & xmin, & xmax); if (xmax <= xmin) { xmin -= 0.5; xmax += 0.5; } } if (ymax <= ymin) { (void) Matrix_getWindowExtrema (me, iy, iy, 1, my ny, & ymin, & ymax); if (ymax <= ymin) { ymin -= 0.5; ymax += 0.5; } } Graphics_setInner (g); if (icx < 0) { double t = xmin; xmin = xmax; xmax = t; } if (icy < 0) { double t = ymin; ymin = ymax; ymax = t; } Graphics_setWindow (g, xmin, xmax, ymin, ymax); for (long i = 1; i <= my ny; i++) { if (my z[i][ix] >= xmin && my z[i][ix] <= xmax && my z[i][iy] >= ymin && my z[i][iy] <= ymax) { Graphics_mark (g, my z[i][ix], my z[i][iy], size_mm, mark); } } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksLeft (g, 2, true, true, false); if (ymin * ymax < 0.0) { Graphics_markLeft (g, 0.0, true, true, true, nullptr); } Graphics_marksBottom (g, 2, true, true, false); if (xmin * xmax < 0.0) { Graphics_markBottom (g, 0.0, true, true, true, nullptr); } } } void Matrix_drawAsSquares (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, int garnish) { Graphics_Colour colour = Graphics_inqColour (g); long ixmin, ixmax, iymin, iymax; if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } long nx = Matrix_getWindowSamplesX (me, xmin, xmax, &ixmin, &ixmax); if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } long ny = Matrix_getWindowSamplesY (me, ymin, ymax, &iymin, &iymax); double min, max = nx > ny ? nx : ny; double dx = (xmax - xmin) / max, dy = (ymax - ymin) / max; Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); Matrix_getWindowExtrema (me, ixmin, ixmax, iymin, iymax, & min, & max); double wAbsMax = fabs (max) > fabs (min) ? fabs (max) : fabs (min); for (long i = iymin; i <= iymax; i++) { double y = Matrix_rowToY (me, i); for (long j = ixmin; j <= ixmax; j++) { double x = Matrix_columnToX (me, j); double d = 0.95 * sqrt (fabs (my z[i][j]) / wAbsMax); if (d > 0) { double x1WC = x - d * dx / 2, x2WC = x + d * dx / 2; double y1WC = y - d * dy / 2, y2WC = y + d * dy / 2; if (my z[i][j] > 0) { Graphics_setColour (g, Graphics_WHITE); } Graphics_fillRectangle (g, x1WC, x2WC, y1WC, y2WC); Graphics_setColour (g, colour); Graphics_rectangle (g, x1WC, x2WC , y1WC, y2WC); } } } Graphics_setGrey (g, 0.0); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksLeft (g, 2, true, true, false); if (ymin * ymax < 0.0) { Graphics_markLeft (g, 0.0, true, true, true, nullptr); } Graphics_marksBottom (g, 2, true, true, false); if (xmin * xmax < 0.0) { Graphics_markBottom (g, 0.0, true, true, true, nullptr); } } } void Matrix_scale (Matrix me, int choice) { double min, max, extremum; long nZero = 0; if (choice == 2) { /* by row */ for (long i = 1; i <= my ny; i++) { Matrix_getWindowExtrema (me, 1, my nx, i, i, &min, &max); extremum = fabs (max) > fabs (min) ? fabs (max) : fabs (min); if (extremum == 0.0) { nZero++; } else for (long j = 1; j <= my nx; j++) { my z[i][j] /= extremum; } } } else if (choice == 3) { /* by col */ for (long j = 1; j <= my nx; j++) { Matrix_getWindowExtrema (me, j, j, 1, my ny, &min, &max); extremum = fabs (max) > fabs (min) ? fabs (max) : fabs (min); if (extremum == 0.0) { nZero++; } else for (long i = 1; i <= my ny; i++) { my z[i][j] /= extremum; } } } else if (choice == 1) { /* overall */ Matrix_getWindowExtrema (me, 1, my nx, 1, my ny, &min, &max); extremum = fabs (max) > fabs (min) ? fabs (max) : fabs (min); if (extremum == 0.0) { nZero++; } else { for (long i = 1; i <= my ny; i++) { for (long j = 1; j <= my nx; j++) { my z[i][j] /= extremum; } } } } else { Melder_flushError (U"Matrix_scale: choice must be > 0 && <= 3."); return; } if (nZero) { Melder_warning (U"Matrix_scale: extremum == 0, (part of) matrix unscaled."); } } autoMatrix Matrix_transpose (Matrix me) { try { autoMatrix thee = Matrix_create (my ymin, my ymax, my ny, my dy, my y1, my xmin, my xmax, my nx, my dx, my x1); for (long i = 1; i <= my ny; i++) { for (long j = 1; j <= my nx; j++) { thy z[j][i] = my z[i][j]; } } return thee; } catch (MelderError) { Melder_throw (me, U": not transposed."); } } void Matrix_drawDistribution (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum, long nBins, double freqMin, double freqMax, int cumulative, int garnish) { if (nBins <= 0) { return; } if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } long ixmin, ixmax, iymin, iymax; if ((Matrix_getWindowSamplesX (me, xmin, xmax, & ixmin, & ixmax) == 0) || (Matrix_getWindowSamplesY (me, ymin, ymax, & iymin, & iymax) == 0)) { return; } if (maximum <= minimum) { Matrix_getWindowExtrema (me, ixmin, ixmax, iymin, iymax, & minimum, & maximum); } if (maximum <= minimum) { minimum -= 1.0; maximum += 1.0; } // Count the numbers per bin and the total if (nBins < 1) { nBins = 10; } autoNUMvector freq (1, nBins); double binWidth = (maximum - minimum) / nBins; long nxy = 0; for (long i = iymin; i <= iymax; i++) { for (long j = ixmin; j <= ixmax; j++) { long bin = 1 + (long) floor ( (my z[i][j] - minimum) / binWidth); if (bin <= nBins && bin > 0) { freq[bin]++; nxy ++; } } } if (freqMax <= freqMin) { if (cumulative) { freqMin = 0; freqMax = 1.0; } else { NUMvector_extrema (freq.peek(), 1, nBins, & freqMin, & freqMax); if (freqMax <= freqMin) { freqMin = freqMin > 1.0 ? freqMin - 1.0 : 0.0; freqMax += 1.0; } } } Graphics_setInner (g); Graphics_setWindow (g, minimum, maximum, freqMin, freqMax); double fi = 0.0; for (long i = 1; i <= nBins; i++) { double ftmp = freq[i]; fi = cumulative ? fi + freq[i] / nxy : freq[i]; ftmp = fi; if (ftmp > freqMax) { ftmp = freqMax; } if (ftmp > freqMin) { Graphics_rectangle (g, minimum + (i - 1) * binWidth, minimum + i * binWidth, freqMin, ftmp); } } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); if (! cumulative) { Graphics_textLeft (g, true, U"Number/bin"); } } } void Matrix_drawSliceY (Matrix me, Graphics g, double x, double ymin, double ymax, double min, double max) { if (x < my xmin || x > my xmax) { return; } long ix = Matrix_xToNearestColumn (me, x); if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } long iymin, iymax; long ny = Matrix_getWindowSamplesY (me, ymin, ymax, &iymin, &iymax); if (ny < 1) { return; } if (max <= min) { Matrix_getWindowExtrema (me, ix, ix, iymin, iymax, &min, &max); } if (max <= min) { min -= 0.5; max += 0.5; } autoNUMvector y (iymin, iymax); Graphics_setWindow (g, ymin, ymax, min, max); Graphics_setInner (g); for (long i = iymin; i <= iymax; i++) { y[i] = my z[i][ix]; } Graphics_function (g, y.peek(), iymin, iymax, Matrix_rowToY (me, iymin), Matrix_rowToY (me, iymax)); Graphics_unsetInner (g); } autoMatrix Matrix_solveEquation (Matrix me, double tolerance) { try { long nr = my ny, nc = my nx - 1; if (nc == 0) { Melder_throw (U"Matrix_solveEquation: there must be at least 2 columns in the matrix."); } if (nr < nc) { Melder_warning (U"Matrix_solveEquation: solution is not unique (fewer equations than unknowns)."); } autoNUMmatrix u (1, nr, 1, nc); autoNUMvector b (1, nr); autoNUMvector x (1, nc); autoMatrix thee = Matrix_create (0.5, 0.5 + nc, nc, 1, 1, 0.5, 1.5, 1, 1, 1); for (long i = 1; i <= nr; i++) { for (long j = 1; j <= nc; j++) { u[i][j] = my z[i][j]; } b[i] = my z[i][my nx]; } NUMsolveEquation (u.peek(), nr, nc, b.peek(), 0, x.peek()); for (long j = 1; j <= nc; j++) { thy z[1][j] = x[j]; } return thee.transfer(); } catch (MelderError) { Melder_throw (U"Matrix equation not solved."); } } double Matrix_getMean (Matrix me, double xmin, double xmax, double ymin, double ymax) { if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } long ixmin, ixmax, iymin, iymax; if ((Matrix_getWindowSamplesX (me, xmin, xmax, & ixmin, & ixmax) == 0) || (Matrix_getWindowSamplesY (me, ymin, ymax, & iymin, & iymax) == 0)) { return NUMundefined; } double sum = 0.0; for (long row = iymin; row <= iymax; row++) { for (long col = ixmin; col <= ixmax; col++) { sum += my z[row][col]; } } return sum / ((iymax - iymin + 1) * (ixmax - ixmin + 1)); } double Matrix_getStandardDeviation (Matrix me, double xmin, double xmax, double ymin, double ymax) { if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } long ixmin, ixmax, iymin, iymax; if ((Matrix_getWindowSamplesX (me, xmin, xmax, & ixmin, & ixmax) == 0) || (Matrix_getWindowSamplesY (me, ymin, ymax, & iymin, & iymax) == 0)) { return NUMundefined; } long nx = ixmax - ixmin + 1, ny = iymax - iymin + 1; if (nx == 1 && ny == 1) { return NUMundefined; } double mean = Matrix_getMean (me, xmin, xmax, ymin, ymax), sum = 0; for (long row = iymin; row <= iymax; row++) { for (long col = ixmin; col <= ixmax; col++) { double val = my z[row][col] - mean; sum += val * val; } } return sqrt (sum / (nx * ny - 1)); } /* End of file Matrix_extensions.cpp */ praat-6.0.04/dwtools/Matrix_extensions.h000066400000000000000000000051021261542461700203050ustar00rootroot00000000000000#ifndef _Matrix_extensions_h_ #define _Matrix_extensions_h_ /* Matrix_extensions.h * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header djmw 20121110 Latest modification */ #include "Matrix.h" #include "Graphics.h" void Matrix_scatterPlot (Matrix me, Graphics g, long icx, long icy, double xmin, double xmax, double ymin, double ymax, double size_mm, const char32 *mark, int garnish); /* Draw my columns ix and iy as a scatterplot (with squares) */ void Matrix_drawAsSquares (Matrix me, Graphics graphics, double xmin, double xmax, double ymin, double ymax, int garnished); /* Draw a Matrix as small squares whose area correspond to the matrix element */ /* The square is filled with black if the weights are negative */ void Matrix_drawRowsAsLineSegments (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum, int connect); /* draw a row as segments */ void Matrix_scale (Matrix me, int choice); /* choice = 1 :divide each elmnt by the maximum (abs) */ /* choice = 2 :rows, divide each row elmnt by the maximum (abs) of that row */ /* choice = 3 :columns, divide each col elmnt by the maximum of that col */ autoMatrix Matrix_transpose (Matrix me); void Matrix_drawDistribution (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum, long nBins, double freqMin, double freqmax, int cumulative, int garnish); void Matrix_drawSliceY (Matrix me, Graphics g, double x, double ymin, double ymax, double min, double max); int Matrix_fitPolynomial (Matrix me, long maxDegree); autoMatrix Matrix_solveEquation (Matrix me, double tolerance); double Matrix_getMean (Matrix me, double xmin, double xmax, double ymin, double ymax); double Matrix_getStandardDeviation (Matrix me, double xmin, double xmax, double ymin, double ymax); #endif /* _Matrix_extensions_h_ */ praat-6.0.04/dwtools/Minimizers.cpp000066400000000000000000000362601261542461700172540ustar00rootroot00000000000000/* Minimizers.cpp * * Copyright (C) 2001-2013, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* David Weenink, 20011016 djmw 20011016 removed some causes for compiler warnings djmw 20030205 Latest modification djmw 20030701 Removed non-GPL minimizations djmw 20040421 Bug removed: delayed message when learning was interrupted by user. djmw 20080122 float -> double djmw 20110304 Thing_new */ #include "NUM2.h" #include "Graphics.h" #include "Minimizers.h" #define SIGN(x,s) ((s) < 0 ? -fabs (x) : fabs(x)) #define GOLD 1.618034 #define CGOLD 0.3819660 #define ITMAX 100.0 #define TINY 1.0e-20 #define ZEPS 1.0e-10 #define EPS 1.0e-10 #define TOL 2e-4 #define SHFT(a, b, c, d) (a) = (b); (b) = (c); (c) = (d); #define MOV3(a, b, c, d, e, f) (a) = (d); (b) = (e); (c) = (f); #define FUNC1(fx, x) for (i=1; i <= my nParameters; i++) my ptry[i] = p[i] + (x) * direction[i]; \ (fx) = my func (my object, my ptry); #define DFUNC1(df, x) for (i=1; i <= my nParameters; i++) my ptry[i] = p[i] + (x) * direction[i]; \ my dfunc (my object, my ptry, my dp); for (df=0, i=1; i <= my nParameters; i++) df += my dp[i] * direction[i]; Thing_implement (Minimizer, Thing, 0); void structMinimizer :: v_destroy () { NUMvector_free (p, 1); NUMvector_free (history, 1); Minimizer_Parent :: v_destroy (); } static void classMinimizer_after (Minimizer me, Any /* aclosure */) { if (my success || ! my gmonitor) { return; } if (my start == 1) { Minimizer_drawHistory (me, my gmonitor, 0, my maxNumOfIterations, 0.0, 1.1 * my history[1], 1); Graphics_textTop (my gmonitor, false, Melder_cat (U"Dimension of search space: ", my nParameters)); } Graphics_setInner (my gmonitor); Graphics_line (my gmonitor, my iteration, my history[my iteration], my iteration, my history[my iteration]); Graphics_unsetInner (my gmonitor); Melder_monitor ((double) (my iteration) / my maxNumOfIterations, U"Iterations: ", my iteration, U", Function calls: ", my funcCalls, U", Cost: ", my minimum); } void Minimizer_init (Minimizer me, long nParameters, Daata object) { my nParameters = nParameters; my p = NUMvector (1, nParameters); my object = object; my minimum = 1.0e30; my after = classMinimizer_after; Minimizer_reset (me, nullptr); /* added 27/11/97 */ } void Minimizer_setParameters (Minimizer me, Any parameters) { my v_setParameters (parameters); } static void monitor_off (Minimizer me) { Melder_monitor (1.1); if (my gmonitor) { Graphics_clearWs (my gmonitor); // DON'T forget (my gmonitor) my gmonitor = nullptr; } } void Minimizer_minimize (Minimizer me, long maxNumOfIterations, double tolerance, int monitor) { try { my tolerance = tolerance; if (maxNumOfIterations <= 0) { return; } if (my iteration + maxNumOfIterations > my maxNumOfIterations) { my maxNumOfIterations += maxNumOfIterations; if (my history) { // clumsy because vector must have been allocated before one can append NUMvector_append (& my history, 1, & my maxNumOfIterations); } else { my history = NUMvector (1, my maxNumOfIterations); } } if (monitor) { my gmonitor = (Graphics) Melder_monitor (0.0, U"Starting..."); } my start = 1; /* for my after() */ my v_minimize (); if (monitor) { monitor_off (me); } if (my success) Melder_casual (U"Minimizer_minimize:", U" minimum ", my minimum, U" reached \nafter ", my iteration, U" iterations and ", my funcCalls, U" function calls."); } catch (MelderError) { if (monitor) { monitor_off (me); // temporarily until better monitor facilities } Melder_clearError(); // memory error in history mechanism is not fatal } } void Minimizer_minimizeManyTimes (Minimizer me, long numberOfTimes, long maxIterationsPerTime, double tolerance) { double fopt = my minimum; int monitorSingle = numberOfTimes == 1; autoNUMvector popt (NUMvector_copy (my p, 1, my nParameters), 1); if (! monitorSingle) { Melder_progress (0.0, U"Minimize many times"); } /* on first iteration start with current parameters 27/11/97 */ for (long i = 1; i <= numberOfTimes; i++) { Minimizer_minimize (me, maxIterationsPerTime, tolerance, monitorSingle); Melder_casual (U"Current ", i, U": minimum = ", my minimum); if (my minimum < fopt) { NUMvector_copyElements (my p, popt.peek(), 1, my nParameters); fopt = my minimum; } Minimizer_reset (me, nullptr); if (! monitorSingle) { try { Melder_progress ((double) i / numberOfTimes, i, U" from ", numberOfTimes); } catch (MelderError) { Melder_clearError (); // interrupted, no error break; } } } if (! monitorSingle) { Melder_progress (1.0); } Minimizer_reset (me, popt.peek()); } void Minimizer_setAfterEachIteration (Minimizer me, void (*after) (Minimizer me, Any aclosure), Any aclosure) { my after = after; my aclosure = aclosure; } void Minimizer_reset (Minimizer me, const double guess[]) { if (guess) { for (long i = 1; i <= my nParameters; i++) { my p[i] = guess[i]; } } else { for (long i = 1; i <= my nParameters; i++) { my p[i] = NUMrandomUniform (-1.0, 1.0); } } NUMvector_free (my history, 1); my history = nullptr; my maxNumOfIterations = my success = my funcCalls = my iteration = 0; my minimum = 1.0e38; my v_reset (); } void Minimizer_drawHistory (Minimizer me, Graphics g, long iFrom, long iTo, double hmin, double hmax, int garnish) { if (! my history) { return; } if (iTo <= iFrom) { iFrom = 1; iTo = my iteration; } long itmin = iFrom, itmax = iTo; if (itmin < 1) { itmin = 1; } if (itmax > my iteration) { itmax = my iteration; } if (hmax <= hmin) { NUMvector_extrema (my history, itmin, itmax, & hmin, & hmax); } if (hmax <= hmin) { hmin -= 0.5 * fabs (hmin); hmax += 0.5 * fabs (hmax); } Graphics_setInner (g); Graphics_setWindow (g, iFrom, iTo, hmin, hmax); Graphics_function (g, my history, itmin, itmax, itmin, itmax); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Number of iterations"); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); } } double Minimizer_getMinimum (Minimizer me) { return my minimum; } /************** class SteepestDescentMinimizer **********************/ Thing_implement (SteepestDescentMinimizer, Minimizer, 0); void structSteepestDescentMinimizer :: v_minimize () { autoNUMvector dp (1, nParameters); autoNUMvector dpp (1, nParameters); double fret = func (object, p); while (iteration < maxNumOfIterations) { dfunc (object, p, dp.peek()); for (long i = 1; i <= nParameters; i++) { dpp[i] = - eta * dp[i] + momentum * dpp[i]; p[i] += dpp[i]; } history[++iteration] = minimum = func (object, p); success = 2.0 * fabs (fret - minimum) < tolerance * (fabs (fret) + fabs (minimum)); if (after) { try { after (this, aclosure); } catch (MelderError) { Melder_casual (U"Interrupted after ", iteration, U" iterations."); Melder_clearError (); break; } } if (success) { break; } fret = minimum; } } void structSteepestDescentMinimizer :: v_setParameters (Any parameters) { if (p) { SteepestDescentMinimizer_parameters thee = (SteepestDescentMinimizer_parameters) parameters; eta = thy eta; momentum = thy momentum; } else { eta = 0.1; momentum = 0.9; } } SteepestDescentMinimizer SteepestDescentMinimizer_create (long nParameters, Daata object, double (*func) (Daata object, const double p[]), void (*dfunc) (Daata object, const double p[], double dp[])) { try { autoSteepestDescentMinimizer me = Thing_new (SteepestDescentMinimizer); Minimizer_init (me.peek(), nParameters, object); my func = func; my dfunc = dfunc; return me.transfer(); } catch (MelderError) { Melder_throw (U"SteepestDescentMinimizer not created."); } } /***************** class VDSmagtMinimizer ******************************/ Thing_implement (VDSmagtMinimizer, Minimizer, 0); void structVDSmagtMinimizer :: v_minimize () { int decrease_direction_found = 1; int l_iteration = 1; // yes, we can iterate in steps, therefore local and global counter double rtemp, rtemp2; // df is estimate of function reduction obtainable during line search // restart = 2 => line search in direction of steepest descent // restart = 1 => line search with Powell-restart. // flag = 1 => no decrease in function value during previous line search; // flag = 2 => line search did not decrease gradient // OK; must restart if (restart_flag) { minimum = func (object, p); dfunc (object, p, dp); df = minimum; restart = 2; one_up = flag = 0; gcg0 = gopt_sq = 0.0; } restart_flag = 1; while (++ this -> iteration <= maxNumOfIterations) { if (flag & 1) { if (one_up) { decrease_direction_found = 0; this -> iteration --; break; } else { one_up = 1; } } else { one_up = 0; } if (flag & 2) { restart = 2; /* flag & 1 ??? */ } else if (fabs ((double) gcg0) > 0.2 * gopt_sq) { restart = 1; } if (restart == 0) { rtemp = rtemp2 = 0.0; for (long i = 1; i <= nParameters; i++) { rtemp += gc[i] * grst[i]; rtemp2 += gc[i] * srst[i]; } gamma = rtemp / gamma_in; if (fabs (beta * gropt - gamma * rtemp2) > 0.2 * gopt_sq) { restart = 1; } else { for (long i = 1; i <= nParameters; i++) { s[i] = beta * s[i] + gamma * srst[i] - gc[i]; } } } if (restart == 2) { for (long i = 1; i <= nParameters; i++) { s[i] = - dp[i]; } restart = 1; } else if (restart == 1) { gamma_in = gropt - gr0; for (long i = 1; i <= nParameters; i++) { srst[i] = s[i]; s[i] = beta * s[i] - gc[i]; grst[i] = gc[i] - g0[i]; } restart = 0; } // Begin line search // lineSearch_iteration = #iterations during current line search flag = 0; lineSearch_iteration = 0; rtemp = 0.0; for (long i = 1; i <= nParameters; i++) { rtemp += dp[i] * s[i]; g0[i] = dp[i]; } gr0 = gropt = rtemp; if (l_iteration == 1) { alphamin = fabs (df / gropt); } if (gr0 > 0) { flag = 1; restart = 2; continue; } f0 = minimum; // alpha = length of step along line; // dalpha = change in alpha // alphamin = position of min along line alplim = -1; again = -1; rtemp = fabs (df / gropt); dalpha = alphamin < rtemp ? alphamin : rtemp; alphamin = 0; do { do { if (lineSearch_iteration) { if (! (fch == 0)) { gr2s += (temp + temp) / dalpha; } if (alplim < -0.5) { dalpha = 9.0 * alphamin; } else { dalpha = 0.5 * (alplim - alphamin); } grs = gropt + dalpha * gr2s; if (gropt * grs < 0) { dalpha *= gropt / (gropt - grs); } } alpha = alphamin + dalpha; for (long i = 1; i <= nParameters; i++) { pc[i] = p[i] + dalpha * s[i]; } fc = func (object, pc); dfunc (object, pc, gc); l_iteration ++; lineSearch_iteration++; gsq = grc = 0.0; for (long i = 1; i <= nParameters; i++) { gsq += gc[i] * gc[i]; grc += gc[i] * s[i]; } fch = fc - minimum; gr2s = (grc - gropt) / dalpha; temp = (fch + fch) / dalpha - grc - gropt; if ((fc < minimum) || ((fc == minimum) && (grc / gropt > -1))) { double *tmp; gopt_sq = gsq; history [this -> iteration] = minimum = fc; tmp = p; p = pc; pc = tmp; tmp = dp; dp = gc; gc = tmp; if (grc *gropt <= 0) { alplim = alphamin; } alphamin = alpha; gropt = grc; dalpha = - dalpha; success = gsq < tolerance; if (after) { try { after (this, aclosure); } catch (MelderError) { Melder_casual (U"Interrupted after ", this -> iteration, U" iterations."); Melder_clearError (); break; } } if (success) { return; } if (fabs (gropt / gr0) < lineSearchGradient) { break; } } else { alplim = alpha; } } while (lineSearch_iteration <= lineSearchMaxNumOfIterations); fc = history [this -> iteration] = minimum; rtemp = 0.0; for (long i = 1; i <= nParameters; i++) { pc[i] = p[i]; gc[i] = dp[i]; rtemp += gc[i] * g0[i]; } gcg0 = rtemp; if (fabs (gropt - gr0) > tolerance) { beta = (gopt_sq - gcg0) / (gropt - gr0); if (fabs (beta * gropt) < 0.2 * gopt_sq) { break; } } again++; if (again > 0) { flag += 2; } } while (flag < 1); if (f0 <= minimum) { flag += 1; } df = gr0 * alphamin; } if (this -> iteration > maxNumOfIterations) { this -> iteration = maxNumOfIterations; } if (decrease_direction_found) { restart_flag = 0; } } void structVDSmagtMinimizer :: v_destroy () { NUMvector_free (dp, 1); NUMvector_free (pc, 1); NUMvector_free (gc, 1); NUMvector_free (g0, 1); NUMvector_free (s, 1); NUMvector_free (srst, 1); NUMvector_free (grst, 1); VDSmagtMinimizer_Parent :: v_destroy (); } void structVDSmagtMinimizer :: v_reset () { restart_flag = 1; } void structVDSmagtMinimizer :: v_setParameters (Any parameters) { if (parameters) { VDSmagtMinimizer_parameters vdspars = (VDSmagtMinimizer_parameters) parameters; lineSearchGradient = vdspars -> lineSearchGradient; lineSearchMaxNumOfIterations = vdspars -> lineSearchMaxNumOfIterations; } } VDSmagtMinimizer VDSmagtMinimizer_create (long nParameters, Daata object, double (*func) (Daata object, const double x[]), void (*dfunc) (Daata object, const double x[], double dx[])) { try { autoVDSmagtMinimizer me = Thing_new (VDSmagtMinimizer); Minimizer_init (me.peek(), nParameters, object); my dp = NUMvector (1, nParameters); my pc = NUMvector (1, nParameters); my gc = NUMvector (1, nParameters); my g0 = NUMvector (1, nParameters); my s = NUMvector (1, nParameters); my srst = NUMvector (1, nParameters); my grst = NUMvector (1, nParameters); my func = func; my dfunc = dfunc; my lineSearchGradient = 0.9; my lineSearchMaxNumOfIterations = 5; return me.transfer(); } catch (MelderError) { Melder_throw (U"VDSmagtMinimizer not created."); } } /************ class LineMinimizer *******************************/ void structLineMinimizer :: v_destroy () { NUMvector_free (ptry, 1); NUMvector_free (direction, 1); LineMinimizer_Parent :: v_destroy (); } Thing_implement (LineMinimizer, Minimizer, 0); void LineMinimizer_init (I, long nParameters, Daata object, double (*func) (Daata, const double [])) { iam (LineMinimizer); Minimizer_init (me, nParameters, object); my direction = NUMvector (1, nParameters); my ptry = NUMvector (1, nParameters); my func = func; my maxLineStep = 100; } /* End of file Minimizers.c 657*/ praat-6.0.04/dwtools/Minimizers.h000066400000000000000000000144261261542461700167210ustar00rootroot00000000000000#ifndef _Minimizers_h_ #define _Minimizers_h_ /* Minimizers.h * * Copyright (C) 1993-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header djmw 20030701 Removed non-GPL minimizations djmw 20110414 Latest modification. */ #include "Data.h" #include "Graphics.h" /*********** deferred class Minimizer **********************************/ Thing_define (Minimizer, Thing) { long nParameters; /* the number of parameters */ double *p; /* the parameters */ double minimum; /* current minimum */ double *history; /* previous minima */ double tolerance; /* stop criterium */ Daata object; /* reference to the object that uses this Minimizer */ long funcCalls; /* the number of times 'func' has been called */ long success; /* indicates whether I'm done */ long start; /* start iteration series */ long maxNumOfIterations; /* the current maximum number of iterations */ long iteration; /* the total number of iterations */ void (*after) (Minimizer me, Any aclosure); /* to be called after each iteration */ Any aclosure; Graphics gmonitor; /* graphics to monitor the minimization process */ void v_destroy () override; void v_info () override { } virtual void v_minimize () { } /* does the work */ virtual void v_reset () { } /* reset the minimizer */ virtual void v_setParameters (Any parameters) { (void) parameters; } }; void Minimizer_init (Minimizer me, long nParameters, Daata object); /* Preconditions: nParameters > 0; Postconditions: if (gmonitor) gmonitor != NULL */ void Minimizer_reset (Minimizer me, const double guess[]); /* reset the start values for the minimizer * Preconditions: * guess != NULL; * Post conditions: * p[] = guess[]; * my minimum = 1.0e30; * success = maxNumOfIterations = iteration = funcCalls = 0; * reset (me); */ void Minimizer_setAfterEachIteration (Minimizer me, int (*after) (Minimizer me, Any aclosure), Any aclosure); /* set the procedure that is executed after each iteration. */ void Minimizer_setParameters (Minimizer me, Any parameters); /* for inheritors */ void Minimizer_minimize (Minimizer me, long maxNumOfIterations, double tolerance, int monitor); /* Minimizes during maximally maxNumOfIterations. The gmonitor is initialized * before minimization and cleared afterwards. * Preconditions: * maxNumOfIterations >= 0; * tolerance > 0; * Postconditions: * if (reset) Minimizer_reset called with xopt as initial guess. * after each function call: funcCalls++ * after each iteration: iteration++ */ void Minimizer_minimizeManyTimes (Minimizer me, long numberOfTimes, long maxIterationsPerTime, double tolerance); void Minimizer_drawHistory (Minimizer me, Graphics g, long itmin, long itmax, double minimum, double maximum, int garnish); double Minimizer_getMinimum (Minimizer me); /********** deferred class LineMinimizer ************************************/ Thing_define (LineMinimizer, Minimizer) { // new data: public: /* the function to be minimized */ double (*func) (Daata object, const double p[]); double maxLineStep; /*maximum step in line search direction */ double *direction; /* search direction vector */ double *ptry; /* point in search direction */ // overridden methods: virtual void v_destroy (); // new methods: //virtual void v_linmin (double p[], double fp, double direction[], double *fret); // David, is dit correct? ja }; void LineMinimizer_init (I, long nParameters, Daata object, double (*func) (Daata object, const double p[])); /****************** class SteepestDescentMinimizer**************************/ typedef struct structSteepestDescentMinimizer_parameters { double eta, momentum; } *SteepestDescentMinimizer_parameters; Thing_define (SteepestDescentMinimizer, Minimizer) { // new data: public: double eta, momentum; double (*func) (Daata object, const double p[]); void (*dfunc) (Daata object, const double p[], double dp[]); /* calculates gradient at position p */ // overridden methods: virtual void v_minimize (); virtual void v_setParameters (Any parameters); }; SteepestDescentMinimizer SteepestDescentMinimizer_create (long nParameters, Daata object, double (*func) (Daata object, const double p[]), void (*dfunc) (Daata object, const double p[], double dp[])); /********** class VDSmagtMinimizer ********************************/ typedef struct structVDSmagtMinimizer_parameters { double lineSearchGradient; long lineSearchMaxNumOfIterations; } *VDSmagtMinimizer_parameters; Thing_define (VDSmagtMinimizer, Minimizer) { // new data: public: double (*func) (Daata object, const double p[]); void (*dfunc) (Daata object, const double p[], double dp[]); double *dp; double lineSearchGradient; long lineSearchMaxNumOfIterations; double gr0, gropt, df, alplim, alpha, dalpha, alphamin; double *pc; /* position of current point */ double *gc; /* gradient of current point */ double *g0; /* gradient at beginning of line search */ double *s; /* search direction for line search */ double *srst;/* search direction for first iteration after restart */ double *grst; /* gradient for first iteration after restart */ double fc, grc, fch, gr2s, temp, grs, beta, gcg0; double gamma, gamma_in, f0, gsq, gopt_sq; long lineSearch_iteration, flag, again, one_up, restart; long restart_flag; // overridden methods: virtual void v_destroy (); virtual void v_minimize (); virtual void v_reset (); virtual void v_setParameters (Any parameters); }; VDSmagtMinimizer VDSmagtMinimizer_create (long dimension, Daata object, double (*func) (Daata object, const double p[]), void (*dfunc) (Daata object, const double p[], double dp[])); #endif /* _Minimizer_h_ */ praat-6.0.04/dwtools/OptimalCeilingTier.cpp000066400000000000000000000031161261542461700206440ustar00rootroot00000000000000/* OptimalCeilingTier.cpp * * Copyright (C) 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "OptimalCeilingTier.h" Thing_implement (OptimalCeilingTier, RealTier, 0); autoOptimalCeilingTier OptimalCeilingTier_create (double tmin, double tmax) { try { autoOptimalCeilingTier me = Thing_new (OptimalCeilingTier); RealTier_init (me.peek(), tmin, tmax); return me; } catch (MelderError) { Melder_throw (U"OptimalCeilingTier not created."); } } void OptimalCeilingTier_draw (OptimalCeilingTier me, Graphics g, double tmin, double tmax, double ymin, double ymax, const char32 *method, int garnish) { RealTier_draw (me, g, tmin, tmax, ymin, ymax, garnish, method, U"Sound pressure (Pa)"); } autoTableOfReal OptimalCeilingTier_downto_TableOfReal (OptimalCeilingTier me) { autoTableOfReal thee = RealTier_downto_TableOfReal (me, U"Time (s)", U"Frequency (Hz)"); return thee; } /* End of file OptimalCeilingTier.cpp */ praat-6.0.04/dwtools/OptimalCeilingTier.h000066400000000000000000000026341261542461700203150ustar00rootroot00000000000000#ifndef _OptimalCeilingTier_h_ #define _OptimalCeilingTier_h_ /* OptimalCeilingTier.h * * Copyright (C) 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "IntensityTier.h" #include "TableOfReal.h" #include "Sound.h" /********** class OptimalCeilingTier **********/ Thing_define (OptimalCeilingTier, RealTier) { int v_domainQuantity () override { return MelderQuantity_TIME_SECONDS; } }; autoOptimalCeilingTier OptimalCeilingTier_create (double tmin, double tmax); void OptimalCeilingTier_draw (OptimalCeilingTier me, Graphics g, double tmin, double tmax, double ymin, double ymax, const char32 *method, int garnish); autoTableOfReal OptimalCeilingTier_downto_TableOfReal (OptimalCeilingTier me); /* End of file OptimalCeilingTier.h */ #endif praat-6.0.04/dwtools/OptimalCeilingTierEditor.cpp000066400000000000000000000037421261542461700220200ustar00rootroot00000000000000/* OptimalCeilingTierEditor.cpp * * Copyright (C) 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "OptimalCeilingTierEditor.h" #include "EditorM.h" Thing_implement (OptimalCeilingTierEditor, RealTierEditor, 0); static void menu_cb_OptimalCeilingTierHelp (EDITOR_ARGS) { EDITOR_IAM (OptimalCeilingTierEditor); Melder_help (U"OptimalCeilingTier"); } void structOptimalCeilingTierEditor :: v_createHelpMenuItems (EditorMenu menu) { OptimalCeilingTierEditor_Parent :: v_createHelpMenuItems (menu); EditorMenu_addCommand (menu, U"OptimalCeilingTier help", 0, menu_cb_OptimalCeilingTierHelp); } void structOptimalCeilingTierEditor :: v_play (double fromTime, double toTime) { if (our d_sound.data) { Sound_playPart (our d_sound.data, fromTime, toTime, theFunctionEditor_playCallback, this); } else { //OptimalCeilingTier_playPart (data, fromTime, toTime, false); } } OptimalCeilingTierEditor OptimalCeilingTierEditor_create (const char32 *title, OptimalCeilingTier octier, Sound sound, bool ownSound) { try { autoOptimalCeilingTierEditor me = Thing_new (OptimalCeilingTierEditor); RealTierEditor_init (me.peek(), title, (RealTier) octier, sound, ownSound); return me.transfer(); } catch (MelderError) { Melder_throw (U"OptimalCeilingTier window not created."); } } /* End of file OptimalCeilingTierEditor.cpp */ praat-6.0.04/dwtools/OptimalCeilingTierEditor.h000066400000000000000000000041601261542461700214600ustar00rootroot00000000000000#ifndef _AmplitudeTierEditor_h_ #define _OptimalCeilingTierEditor_h_ /* OptimalCeilingTierEditor.h * * Copyright (C) 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "RealTierEditor.h" #include "OptimalCeilingTier.h" #include "Sound.h" Thing_define (OptimalCeilingTierEditor, RealTierEditor) { void v_createHelpMenuItems (EditorMenu menu) override; void v_play (double fromTime, double toTime) override; const char32 * v_quantityText () override { return U"Frequency (Hz)"; } const char32 * v_quantityKey () override { return U"Frequency"; } const char32 * v_rightTickUnits () override { return U" Hz"; } double v_defaultYmin () override { return 4000.0; } double v_defaultYmax () override { return +6000.0; } const char32 * v_setRangeTitle () override { return U"Set frequency range..."; } const char32 * v_defaultYminText () override { return U"4000.0"; } const char32 * v_defaultYmaxText () override { return U"6000.0"; } const char32 * v_yminText () override { return U"Minimum frequency (Hz)"; } const char32 * v_ymaxText () override { return U"Maximum frequency (Hz)"; } const char32 * v_yminKey () override { return U"Minimum frequency"; } const char32 * v_ymaxKey () override { return U"Maximum frequency"; } }; OptimalCeilingTierEditor OptimalCeilingTierEditor_create (const char32 *title, OptimalCeilingTier amplitude, Sound sound, // may be null bool ownSound); /* End of file OptimalCeilingTierEditor.h */ #endif praat-6.0.04/dwtools/PCA.cpp000066400000000000000000000212661261542461700155310ustar00rootroot00000000000000/* PCA.cpp * * Principal Component Analysis * * Copyright (C) 1993-2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20000511 PCA_and_TableOfReal_to_Configuration: added centralize option. (later removed) djmw 20020327 PCA_and_TableOfReal_to_Configuration modified internals. djmw 20020418 Removed some causes for compiler warnings. djmw 20020502 modified call Eigen_and_TableOfReal_project_into. djmw 20030324 Added PCA_and_TableOfReal_getFractionVariance. djmw 20061212 Changed info to Melder_writeLine format. djmw 20071012 Added: o_CAN_WRITE_AS_ENCODING.h djmw 20071201 Melder_warning djmw 20081119 Check in TableOfReal_to_PCA if TableOfReal_areAllCellsDefined djmw 20110304 Thing_new */ #include "PCA.h" #include "NUMlapack.h" #include "NUM2.h" #include "TableOfReal_extensions.h" #include "Eigen_and_SSCP.h" #include "Eigen_and_TableOfReal.h" #include "Configuration.h" #include "oo_DESTROY.h" #include "PCA_def.h" #include "oo_COPY.h" #include "PCA_def.h" #include "oo_EQUAL.h" #include "PCA_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "PCA_def.h" #include "oo_WRITE_TEXT.h" #include "PCA_def.h" #include "oo_READ_TEXT.h" #include "PCA_def.h" #include "oo_WRITE_BINARY.h" #include "PCA_def.h" #include "oo_READ_BINARY.h" #include "PCA_def.h" #include "oo_DESCRIPTION.h" #include "PCA_def.h" Thing_implement (PCA, Eigen, 0); void structPCA :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Number of components: ", numberOfEigenvalues); MelderInfo_writeLine (U"Number of dimensions: ", dimension); MelderInfo_writeLine (U"Number of observations: ", numberOfObservations); } autoPCA PCA_create (long numberOfComponents, long dimension) { try { autoPCA me = Thing_new (PCA); Eigen_init (me.peek(), numberOfComponents, dimension); my labels = NUMvector (1, dimension); my centroid = NUMvector (1, dimension); return me; } catch (MelderError) { Melder_throw (U"PCA not created"); } } void PCA_setNumberOfObservations (PCA me, long numberOfObservations) { my numberOfObservations = numberOfObservations; } long PCA_getNumberOfObservations (PCA me) { return my numberOfObservations; } void PCA_getEqualityOfEigenvalues (PCA me, long from, long to, int conservative, double *probability, double *chisq, long *ndf) { double sum = 0, sumln = 0; *probability = 1; *ndf = 0; *chisq = 0; if ((from > 0 && to == from) || to > my numberOfEigenvalues) { return; } if (to <= from) { from = 1; to = my numberOfEigenvalues; } long i; for (i = from; i <= to; i++) { if (my eigenvalues[i] <= 0) { break; } sum += my eigenvalues[i]; sumln += log (my eigenvalues[i]); } if (sum == 0) { return; } long r = i - from; long n = my numberOfObservations - 1; if (conservative) { n -= from + (r * (2 * r + 1) + 2) / (6 * r); } *ndf = r * (r + 1) / 2 - 1; *chisq = n * (r * log (sum / r) - sumln); *probability = NUMchiSquareQ (*chisq, *ndf); } autoPCA TableOfReal_to_PCA (I) { iam (TableOfReal); try { long m = my numberOfRows, n = my numberOfColumns; if (! TableOfReal_areAllCellsDefined (me, 0, 0, 0, 0)) { Melder_throw (U"Undefined cells."); } if (m < 2) { Melder_throw (U"There is not enough data to perform a PCA.\nYour table has less than 2 rows."); } if (m < n) { Melder_warning (U"The number of rows in your table is less than the \nnumber of columns. "); } if (NUMfrobeniusnorm (m, n, my data) == 0) { Melder_throw (U"All values in your table are zero."); } autoPCA thee = Thing_new (PCA); autoNUMmatrix a (NUMmatrix_copy (my data, 1, m, 1, n), 1, 1); thy centroid = NUMvector (1, n); for (long j = 1; j <= n; j++) { double colmean = a[1][j]; for (long i = 2; i <= m; i++) { colmean += a[i][j]; } colmean /= m; for (long i = 1; i <= m; i++) { a[i][j] -= colmean; } thy centroid[j] = colmean; } Eigen_initFromSquareRoot (thee.peek(), a.peek(), m, n); thy labels = NUMvector (1, n); NUMstrings_copyElements (my columnLabels, thy labels, 1, n); PCA_setNumberOfObservations (thee.peek(), m); /* The covariance matrix C = A'A / (N-1). However, we have calculated the eigenstructure for A'A. This has no consequences for the eigenvectors, but the eigenvalues have to be divided by (N-1). */ for (long i = 1; i <= thy numberOfEigenvalues; i++) { thy eigenvalues[i] /= (m - 1); } return thee; } catch (MelderError) { Melder_throw (me, U": PCA not created."); } } autoTableOfReal PCA_and_TableOfReal_to_TableOfReal_zscores (PCA me, TableOfReal thee, long numberOfDimensions) { try { if (numberOfDimensions == 0 || numberOfDimensions > my numberOfEigenvalues) { numberOfDimensions = my numberOfEigenvalues; } autoTableOfReal him = TableOfReal_create (thy numberOfRows, numberOfDimensions); for (long i = 1; i <= thy numberOfRows; i++) { /* row */ for (long j = 1; j <= numberOfDimensions; j++) { double r = 0, sigma = sqrt (my eigenvalues[j]); for (long k = 1; k <= my dimension; k++) { // eigenvector in row, data in row r += my eigenvectors[j][k] * (thy data[i][k] - my centroid[k]) / sigma; } his data[i][j] = r; } } NUMstrings_copyElements (thy rowLabels, his rowLabels, 1, thy numberOfRows); TableOfReal_setSequentialColumnLabels (him.peek(), 0, 0, U"pc", 1, 1); return him; } catch (MelderError) { Melder_throw (U"TableOfReal (zscores) not created from PCA & TableOfReal."); } } autoConfiguration PCA_and_TableOfReal_to_Configuration (PCA me, thou, long numberOfDimensions) { try { thouart (TableOfReal); if (numberOfDimensions == 0 || numberOfDimensions > my numberOfEigenvalues) { numberOfDimensions = my numberOfEigenvalues; } autoConfiguration him = Configuration_create (thy numberOfRows, numberOfDimensions); Eigen_and_TableOfReal_project_into (me, thee, 1, thy numberOfColumns, him.peek(), 1, numberOfDimensions); NUMstrings_copyElements (thy rowLabels, his rowLabels, 1, thy numberOfRows); TableOfReal_setSequentialColumnLabels (him.peek(), 0, 0, U"pc", 1, 1); return him; } catch (MelderError) { Melder_throw (U"Configuration not created from PCA & TableOfReal."); } } autoTableOfReal PCA_and_Configuration_to_TableOfReal_reconstruct (PCA me, thou) { try { thouart (Configuration); long npc = thy numberOfColumns; if (thy numberOfColumns > my dimension) { Melder_throw (U"The dimension of the Configuration must be less than or equal to the dimension of the PCA."); } if (npc > my numberOfEigenvalues) { npc = my numberOfEigenvalues; } autoTableOfReal him = TableOfReal_create (thy numberOfRows, my dimension); NUMstrings_copyElements (my labels, his columnLabels, 1, my dimension); NUMstrings_copyElements (thy rowLabels, his rowLabels, 1, thy numberOfRows); for (long i = 1; i <= thy numberOfRows; i++) { double *hisdata = his data[i]; for (long k = 1; k <= npc; k++) { double *evec = my eigenvectors[k], pc = thy data[i][k]; for (long j = 1; j <= my dimension; j++) { hisdata[j] += pc * evec[j]; } } } return him; } catch (MelderError) { Melder_throw (U"TableOfReal not reconstructed."); } } double PCA_and_TableOfReal_getFractionVariance (PCA me, thou, long from, long to) { try { thouart (TableOfReal); double fraction = NUMundefined; if (from < 1 || from > to || to > thy numberOfColumns) { return NUMundefined; } autoSSCP s = TableOfReal_to_SSCP (thee, 0, 0, 0, 0); autoSSCP sp = Eigen_and_SSCP_project (me, s.peek()); fraction = SSCP_getFractionVariation (sp.peek(), from, to); return fraction; } catch (MelderError) { return NUMundefined; } } autoTableOfReal PCA_to_TableOfReal_reconstruct1 (PCA me, char32 *numstring) { try { long npc; autoNUMvector pc (NUMstring_to_numbers (numstring, & npc), 1); autoConfiguration c = Configuration_create (1, npc); for (long j = 1; j <= npc; j++) { c -> data [1][j] = pc[j]; } autoTableOfReal him = PCA_and_Configuration_to_TableOfReal_reconstruct (me, c.peek()); return him; } catch (MelderError) { Melder_throw (me, U" not reconstructed."); } } /* End of file PCA.cpp */ praat-6.0.04/dwtools/PCA.h000066400000000000000000000042511261542461700151710ustar00rootroot00000000000000#ifndef _PCA_h_ #define _PCA_h_ /* PCA.h * * Principal Component Analysis * * Copyright (C) 1993-2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header djmw 20110306 Latest modification. */ #include "TableOfReal.h" #include "Configuration.h" #include "Eigen.h" #include "PCA_def.h" oo_CLASS_CREATE (PCA, Eigen); autoPCA PCA_create (long numberOfComponents, long dimension); void PCA_setNumberOfObservations (PCA me, long numberOfObservations); long PCA_getNumberOfObservations (PCA me); autoPCA TableOfReal_to_PCA (I); /* Calculate PCA of M'M */ void PCA_getEqualityOfEigenvalues (PCA me, long from, long to, int conservative, double *probability, double *chisq, long *ndf); /* Morrison, Multivariate statistical methods, page 336 */ autoConfiguration PCA_and_TableOfReal_to_Configuration (PCA me, thou, long numberOfDimensions); autoTableOfReal PCA_and_TableOfReal_to_TableOfReal_zscores (PCA me, TableOfReal thee, long numberOfDimensions); double PCA_and_TableOfReal_getFractionVariance (PCA me, thou, long from, long to); /* Get fraction variance of the table projected in the pca-space. Shorthand for projecting the Covariance of the TableOfReal on the PCA-space and quering the projected Covariance for 'fraction variance'. */ autoTableOfReal PCA_and_Configuration_to_TableOfReal_reconstruct (PCA me, thou); /* Reconstruct the original TableOfReal from the PCA and the Configuration */ autoTableOfReal PCA_to_TableOfReal_reconstruct1 (PCA me, char32 *numstring); #endif /* _PCA_h_ */ praat-6.0.04/dwtools/PCA_def.h000066400000000000000000000021411261542461700160030ustar00rootroot00000000000000/* PCA_def.h * * Copyright (C) 1993-2002 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19981225, 20020813 GPL header, 20110329 latest modification */ #define ooSTRUCT PCA oo_DEFINE_CLASS (PCA, Eigen) oo_LONG (numberOfObservations) oo_STRING_VECTOR (labels, dimension) oo_DOUBLE_VECTOR (centroid, dimension) #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (PCA) #undef ooSTRUCT /* End of file PCA_def.h */ praat-6.0.04/dwtools/Pattern.cpp000066400000000000000000000063711261542461700165430ustar00rootroot00000000000000/* Pattern.cpp * * Copyright (C) 1993-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header djmw 20041203 Added _Pattern_checkElements. djmw 20071017 Melder_error

djmw 20110304 Thing_new */ #include "Pattern.h" Thing_implement (Pattern, Matrix, 2); int _Pattern_checkElements (Pattern me) { for (long i = 1; i <= my ny; i++) { for (long j = 1; j <= my nx; j++) { if (my z[i][j] < 0 || my z[i][j] > 1) { return 0; } } } return 1; } void Pattern_init (Pattern me, long ny, long nx) { my ny = ny; my nx = nx; Matrix_init (me, 1, nx, nx, 1, 1, 1, ny, ny, 1, 1); } Pattern Pattern_create (long ny, long nx) { try { autoPattern me = Thing_new (Pattern); Pattern_init (me.peek(), ny, nx); return me.transfer(); } catch (MelderError) { Melder_throw (U"Pattern not created."); } } void Pattern_normalize (Pattern me, int choice, double pmin, double pmax) { if (pmin == pmax) { (void) Matrix_getWindowExtrema (me, 1, my nx, 1, my ny, & pmin, & pmax); } if (pmin == pmax) { return; } if (choice == 1) { for (long i = 1; i <= my ny; i++) { for (long j = 1; j <= my nx; j++) { my z[i][j] = (my z[i][j] - pmin) / (pmax - pmin); } } } else { /* default choice */ for (long i = 1; i <= my ny; i++) { double sum = 0; for (long j = 1; j <= my nx; j++) { sum += (my z[i][j] -= pmin); } for (long j = 1; j <= my nx; j++) { my z[i][j] *= 1.0 / sum; } } } } void Pattern_draw (Pattern me, Graphics g, long pattern, double xmin, double xmax, double ymin, double ymax, int garnish) { Matrix_drawRows (me, g, xmin, xmax, pattern - 0.5, pattern + 0.5, ymin, ymax); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); } } Pattern Matrix_to_Pattern (Matrix me, int join) { try { if (join < 1) { join = 1; } if ( (my ny % join) != 0) { Melder_throw (U"Number of rows is not a multiple of join factor."); } autoPattern thee = Pattern_create (my ny / join, join * my nx); long r = 0, c = 1; for (long i = 1; i <= my ny; i++) { if ( (i - 1) % join == 0) { r++; c = 1; } for (long j = 1; j <= my nx; j++) { thy z[r][c++] = my z[i][j]; } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no Pattern created."); } } Matrix Pattern_to_Matrix (Pattern me) { try { autoMatrix thee = Thing_new (Matrix); my structMatrix :: v_copy (thee.peek()); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not converted to Matrix."); } } /* End of file Pattern.cpp */ praat-6.0.04/dwtools/Pattern.h000066400000000000000000000033361261542461700162060ustar00rootroot00000000000000#ifndef _Pattern_h_ #define _Pattern_h_ /* Pattern.h * * Copyright (C) 1993-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Matrix.h" Thing_define (Pattern, Matrix) { }; /* Attributes: xmin :index of first input node. xmax :last node index. nx :Number of inputs. dx :1. x1 :1. ymin :1. ymax :#patterns. dy :1. y1 :1. z[iy][ix] :the inputs. All elements in interval [0,1]. */ void Pattern_init (Pattern me, long ny, long nx); Pattern Pattern_create (long ny, long nx); void Pattern_normalize (Pattern me, int choice, double pmin, double pmax); /* choice == 1: z[i][j] = (z[i][j]-pmin) / (pmax-pmin); * choice == 2: z[i][j] *= 1.0 / sum(j=1,j=nx, z[i][j]-pmin) */ void Pattern_draw (Pattern me, Graphics g, long pattern, double xmin, double xmax, double ymin, double ymax, int garnish); Pattern Matrix_to_Pattern (Matrix me, int join); Matrix Pattern_to_Matrix (Pattern me); int _Pattern_checkElements (Pattern me); /* Return 1 if all elements are in interval [0,1] else 0. */ #endif /* _Pattern_h_ */ praat-6.0.04/dwtools/Pitch_extensions.cpp000066400000000000000000000166031261542461700204530ustar00rootroot00000000000000/* Pitch_extensions.cpp * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 1997 djmw 20030217 Latest modification djmw 20061201 Interface change: removed minimumPitch parameter from PitchTier_modifyRange. djmw 20061207 Removed PitchTier_modifyRange. */ #include "Pitch_extensions.h" void Pitch_Frame_addPitch (Pitch_Frame me, double f, double strength, int maxnCandidates) { long pos = 0; double weakest = 1e308; if (my nCandidates < maxnCandidates) { pos = ++ my nCandidates; } else { // Find weakest candidate so far (skip the unvoiced one) for (long i = 1; i <= maxnCandidates; i++) { if (my candidate[i].strength < weakest && my candidate[i].frequency > 0) { weakest = my candidate[i].strength; pos = i; } } if (strength < weakest) { pos = 0; } } if (pos > 0) { my candidate[pos].frequency = f; my candidate[pos].strength = strength; } } void Pitch_Frame_getPitch (Pitch_Frame me, double *f, double *strength) { long pos = 1; *strength = -1; for (long i = 1; i <= my nCandidates; i++) { if (my candidate[i].strength > *strength && my candidate[i].frequency > 0) { *strength = my candidate[i].strength; pos = i; } } *f = my candidate[pos].frequency; } void Pitch_Frame_resizeStrengths (Pitch_Frame me, double maxStrength, double unvoicedCriterium) { int pos = 1; double strongest = my candidate[1].strength; for (long i = 2; i <= my nCandidates; i++) { if (my candidate[i].strength > strongest) { strongest = my candidate[i].strength; pos = i; } } if (strongest != 0) { for (long i = 1; i <= my nCandidates; i++) { my candidate[i].strength *= maxStrength / strongest; } } if (maxStrength < unvoicedCriterium) { for (long i = 1; i <= my nCandidates; i++) { if (my candidate[i].frequency == 0) { pos = i; break; } } } if (pos != 1) { double tmp = my candidate[1].frequency; my candidate[1].frequency = my candidate[pos].frequency; my candidate[pos].frequency = tmp; tmp = my candidate[1].strength; my candidate[1].strength = my candidate[pos].strength; my candidate[pos].strength = tmp; } } autoPitch Pitch_scaleTime (Pitch me, double scaleFactor) { try { double dx = my dx, x1 = my x1, xmax = my xmax; if (scaleFactor != 1) { dx = my dx * scaleFactor; x1 = my xmin + 0.5 * dx; xmax = my xmin + my nx * dx; } autoPitch thee = Pitch_create (my xmin, xmax, my nx, dx, x1, my ceiling, 2); for (long i = 1; i <= my nx; i++) { double f = my frame[i].candidate[1].frequency; thy frame[i].candidate[1].strength = my frame[i].candidate[1].strength; f /= scaleFactor; if (f < my ceiling) { thy frame[i].candidate[1].frequency = f; } } return thee; } catch (MelderError) { Melder_throw (me, U": not scaled."); } } static double HertzToSpecial (double value, int pitchUnit) { return pitchUnit == kPitch_unit_HERTZ ? value : pitchUnit == kPitch_unit_HERTZ_LOGARITHMIC ? value <= 0.0 ? NUMundefined : log10 (value) : pitchUnit == kPitch_unit_MEL ? NUMhertzToMel (value) : pitchUnit == kPitch_unit_LOG_HERTZ ? value <= 0.0 ? NUMundefined : log10 (value) : pitchUnit == kPitch_unit_SEMITONES_1 ? value <= 0.0 ? NUMundefined : 12.0 * log (value / 1.0) / NUMln2 : pitchUnit == kPitch_unit_SEMITONES_100 ? value <= 0.0 ? NUMundefined : 12.0 * log (value / 100.0) / NUMln2 : pitchUnit == kPitch_unit_SEMITONES_200 ? value <= 0.0 ? NUMundefined : 12.0 * log (value / 200.0) / NUMln2 : pitchUnit == kPitch_unit_SEMITONES_440 ? value <= 0.0 ? NUMundefined : 12.0 * log (value / 440.0) / NUMln2 : pitchUnit == kPitch_unit_ERB ? NUMhertzToErb (value) : NUMundefined; } static double SpecialToHertz (double value, int pitchUnit) { return pitchUnit == kPitch_unit_HERTZ ? value : pitchUnit == kPitch_unit_HERTZ_LOGARITHMIC ? pow (10.0, value) : pitchUnit == kPitch_unit_MEL ? NUMmelToHertz (value) : pitchUnit == kPitch_unit_LOG_HERTZ ? pow (10.0, value) : pitchUnit == kPitch_unit_SEMITONES_1 ? 1.0 * exp (value * (NUMln2 / 12.0)) : pitchUnit == kPitch_unit_SEMITONES_100 ? 100.0 * exp (value * (NUMln2 / 12.0)) : pitchUnit == kPitch_unit_SEMITONES_200 ? 200.0 * exp (value * (NUMln2 / 12.0)) : pitchUnit == kPitch_unit_SEMITONES_440 ? 440.0 * exp (value * (NUMln2 / 12.0)) : pitchUnit == kPitch_unit_ERB ? NUMerbToHertz (value) : NUMundefined; } autoPitchTier PitchTier_normalizePitchRange (PitchTier me, double pitchMin_ref_Hz, double pitchMax_ref_Hz, double pitchMin_Hz, double pitchMax_Hz, int pitchUnit); autoPitchTier PitchTier_normalizePitchRange (PitchTier me, double pitchMin_ref_Hz, double pitchMax_ref_Hz, double pitchMin_Hz, double pitchMax_Hz, int pitchUnit) { try { double fminr = HertzToSpecial (pitchMin_ref_Hz, pitchUnit); double fmaxr = HertzToSpecial (pitchMax_ref_Hz, pitchUnit); double fmin = HertzToSpecial (pitchMin_Hz, pitchUnit); double fmax = HertzToSpecial (pitchMax_Hz, pitchUnit); if (fminr == NUMundefined || fmaxr == NUMundefined || fmin == NUMundefined || fmax == NUMundefined) { Melder_throw (U"The conversion of a pitch value is not defined. "); } double ranger = fmaxr - fminr, range = fmax - fmin; if (ranger < 0.01 || range < 0.01) { Melder_throw (U"Pitch range too small."); } double fmidr = fminr + ranger / 2; double factor = ranger / range; autoPitchTier thee = Data_copy (me); for (long i = 1; i <= my points -> size; i ++) { RealPoint point = (RealPoint) thy points -> item [i]; double f = HertzToSpecial (point -> value, pitchUnit); f = factor * (f - fmidr); f = SpecialToHertz (f, pitchUnit); point -> value = f; } return thee; } catch (MelderError) { Melder_throw (me, U": no PitchTier created."); } } autoPitch PitchTier_to_Pitch (PitchTier me, double dt, double pitchFloor, double pitchCeiling) { try { if (my points -> size < 1) { Melder_throw (U"The PitchTier is empty."); } if (dt <= 0) { Melder_throw (U"The time step should be a positive number."); } if (pitchFloor >= pitchCeiling) { Melder_throw (U"The pitch ceiling must be larger than the pitch floor."); } double tmin = my xmin, tmax = my xmax, t1 = my xmin + dt / 2; long nt = (long) floor ((tmax - tmin - t1) / dt); if (t1 + nt * dt < tmax) { nt++; } if (nt < 1) { Melder_throw (U"Duration is too short."); } autoPitch thee = Pitch_create (tmin, tmax, nt, dt, t1, pitchCeiling, 1); for (long i = 1; i <= nt; i++) { Pitch_Frame frame = (Pitch_Frame) & thy frame [i]; Pitch_Candidate candidate = (Pitch_Candidate) & frame -> candidate [1]; double t = t1 + (i - 1) * dt; double f = RealTier_getValueAtTime (me, t); if (f < pitchFloor || f > pitchCeiling) { f = 0; } candidate -> frequency = f; } return thee; } catch (MelderError) { Melder_throw (me, U": no Pitch created."); } } /* End of file Pitch_extensions.cpp */ praat-6.0.04/dwtools/Pitch_extensions.h000066400000000000000000000030531261542461700201130ustar00rootroot00000000000000#ifndef _Pitch_extensions_h_ #define _Pitch_extensions_h_ /* Pitch_extensions.h * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19970408 djmw 20020813 GPL header djmw 20110307 Latest modification */ #include "Pitch.h" #include "PitchTier.h" void Pitch_Frame_addPitch (Pitch_Frame me, double f, double strength, int maxnCandidates); void Pitch_Frame_getPitch (Pitch_Frame me, double *f, double *strength); void Pitch_Frame_resizeStrengths (Pitch_Frame me, double maxStrength, double unvoicedCriterium); autoPitch Pitch_scaleTime (Pitch me, double scaleFactor); /* Scale time domain and pitches: xmin' = xmin; dx' = dx * scaleFactor; x1' = xmin + 0.5 * dx'; xmax' = xmin + nx * dx'; pitch[i]' = pitch[i]/scaleFactor; */ autoPitch PitchTier_to_Pitch (PitchTier me, double dt, double pitchFloor, double pitchCeiling); #endif /* _Pitch_extensions_h_ */ praat-6.0.04/dwtools/Polygon_extensions.cpp000066400000000000000000001162721261542461700210360ustar00rootroot00000000000000/* Polygon_extensions.c * * Copyright (C) 1993-2012, 2014, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header djmw 20080122 float -> double djmw 20100407 Sound_to_Polygon, Sounds_to_Polygon_encloseds djmw 20100418 Polygon_rotate. bug: angle was in degrees now in radians */ #include "Matrix.h" #include "NUM2.h" #include "Polygon_extensions.h" #include "Vector.h" #include "DLL.h" // not for self-intesecting polygons! static double Polygon_area (Polygon me) { double area = 0; long j = my numberOfPoints; for (long i = 1; i <= my numberOfPoints; i++) { area += (my x[j] + my x[i]) * (my y[j] - my y[i]); j = i; } area *= 0.5; return fabs (area); // area my have negative sign in counter clockwise evaluation of area } void Polygon_getExtrema (Polygon me, double *xmin, double *xmax, double *ymin, double *ymax) { *xmin = my x[1]; *xmax = my x[1]; *ymin = my y[1]; *ymax = my y[1]; for (long i = 2; i <= my numberOfPoints; i++) { if (my x[i] < *xmin) { *xmin = my x[i]; } else if (my x[i] > *xmax) { *xmax = my x[i]; } if (my y[i] < *ymin) { *ymin = my y[i]; } else if (my y[i] > *ymax) { *ymax = my y[i]; } } } autoPolygon Polygon_createSimple (char32 *xystring) { try { long numberOfPoints; autoNUMvector xys (NUMstring_to_numbers (xystring, &numberOfPoints), 1); if (numberOfPoints < 6) { Melder_throw (U"There must be at least 3 points (= x,y pairs) in the Polygon"); } if (numberOfPoints % 2 != 0) { Melder_throw (U"One value is missing."); } numberOfPoints /= 2; // x,y pairs autoPolygon me = Polygon_create (numberOfPoints); for (long i = 1; i <= numberOfPoints; i++) { my x[i] = xys[2 * i - 1]; my y[i] = xys[2 * i]; if (i > 1 && my x[i] == my x[i - 1] && my y[i] == my y[i - 1]) { Melder_warning (U"Two successives vertices are equal."); } } return me; } catch (MelderError) { Melder_throw (U"Polygon not created."); } } autoPolygon Polygon_createFromRandomVertices (long numberOfVertices, double xmin, double xmax, double ymin, double ymax) { try { autoPolygon me = Polygon_create (numberOfVertices); for (long i = 1; i <= numberOfVertices; i++) { my x[i] = NUMrandomUniform (xmin, xmax); my y[i] = NUMrandomUniform (ymin, ymax); } return me; } catch (MelderError) { Melder_throw (U"Polygon not created."); } } void Polygon_translate (Polygon me, double xt, double yt) { for (long i = 1; i <= my numberOfPoints; i++) { my x[i] += xt; my y[i] += yt; } } /* rotate counterclockwise w.r.t. (xc,yc) */ void Polygon_rotate (Polygon me, double alpha, double xc, double yc) { double f = alpha * NUMpi / 180, cosa = cos (f), sina = sin (f); Polygon_translate (me, -xc, -yc); for (long i = 1; i <= my numberOfPoints; i++) { double x = my x[i]; my x[i] = cosa * my x[i] - sina * my y[i]; my y[i] = sina * x + cosa * my y[i]; } Polygon_translate (me, xc, yc); } void Polygon_scale (Polygon me, double xs, double ys) { for (long i = 1; i <= my numberOfPoints; i++) { my x[i] *= xs; my y[i] *= ys; } } void Polygon_reverseX (Polygon me) { for (long i = 1; i <= my numberOfPoints; i++) { my x[i] = -my x[i]; } } void Polygon_reverseY (Polygon me) { for (long i = 1; i <= my numberOfPoints; i++) { my y[i] = -my y[i]; } } void Polygon_Categories_draw (Polygon me, Categories thee, Graphics graphics, double xmin, double xmax, double ymin, double ymax, int garnish) { double min, max, tmp; if (my numberOfPoints != thy size) { return; } if (xmax == xmin) { NUMvector_extrema (my x, 1, my numberOfPoints, & min, & max); tmp = max - min == 0 ? 0.5 : 0.0; xmin = min - tmp; xmax = max + tmp; } if (ymax == ymin) { NUMvector_extrema (my y, 1, my numberOfPoints, & min, & max); tmp = max - min == 0 ? 0.5 : 0.0; ymin = min - tmp; ymax = max + tmp; } Graphics_setInner (graphics); Graphics_setWindow (graphics, xmin, xmax, ymin, ymax); Graphics_setTextAlignment (graphics, Graphics_CENTRE, Graphics_HALF); for (long i = 1; i <= my numberOfPoints; i++) { OrderedOfString_drawItem (thee, graphics, i, my x[i], my y[i]); } Graphics_unsetInner (graphics); if (garnish) { Graphics_drawInnerBox (graphics); Graphics_marksLeft (graphics, 2, true, true, false); if (ymin * ymax < 0.0) { Graphics_markLeft (graphics, 0.0, true, true, true, nullptr); } Graphics_marksBottom (graphics, 2, true, true, false); if (xmin * xmax < 0.0) { Graphics_markBottom (graphics, 0.0, true, true, true, nullptr); } } } static void setWindow (Polygon me, Graphics graphics, double xmin, double xmax, double ymin, double ymax) { Melder_assert (me); if (xmax <= xmin) { /* Autoscaling along x axis. */ xmax = xmin = my x [1]; for (long i = 2; i <= my numberOfPoints; i ++) { if (my x [i] < xmin) { xmin = my x [i]; } if (my x [i] > xmax) { xmax = my x [i]; } } if (xmin == xmax) { xmin -= 1.0; xmax += 1.0; } } if (ymax <= ymin) { /* Autoscaling along y axis. */ ymax = ymin = my y [1]; for (long i = 2; i <= my numberOfPoints; i ++) { if (my y [i] < ymin) { ymin = my y [i]; } if (my y [i] > ymax) { ymax = my y [i]; } } if (ymin == ymax) { ymin -= 1.0; ymax += 1.0; } } Graphics_setWindow (graphics, xmin, xmax, ymin, ymax); } void Polygon_drawMarks (Polygon me, Graphics g, double xmin, double xmax, double ymin, double ymax, double size_mm, const char32 *mark) { Graphics_setInner (g); setWindow (me, g, xmin, xmax, ymin, ymax); for (long i = 1; i <= my numberOfPoints; i++) { Graphics_mark (g, my x[i], my y[i], size_mm, mark); } Graphics_unsetInner (g); } #define CLIP_Y(y,ymin,ymax) (clip ? ((y) > (ymax) ? (ymax) : (y) < (ymin) ? (ymin) : (y)) : y) autoPolygon Sound_to_Polygon (Sound me, int channel, double tmin, double tmax, double ymin, double ymax, double level) { try { bool clip = ymin < ymax; if (channel < 1 || channel > my ny) { Melder_throw (U"Channel does not exist."); } if (tmin >= tmax) { tmin = my xmin; tmax = my xmax; } if (tmin < my xmin) { tmin = my xmin; } if (tmax > my xmax) { tmax = my xmax; } if (tmin >= my xmax || tmax < my xmin) { Melder_throw (U"Invalid domain."); } long k = 1, i1 = Sampled_xToHighIndex (me, tmin); long i2 = Sampled_xToLowIndex (me, tmax); long numberOfPoints = i2 - i1 + 1 + 2 + 2; // begin + endpoint + level autoPolygon him = Polygon_create (numberOfPoints); /* In Vector_getValueAtX the interpolation only returns defined values between the left and right edges that are calculated as left = x1 - 0.5 * dx; right = left + my nx * dx. Given a sound, for example on the domain [0,...], the value of 'left' with the above formula might not return exactly xmin but instead a very small deviation (due to the imprecise representation of real numbers in a computer). Querying for the value at xmin which is outside the interpolation domain then produces an 'undefined'. We try to avoid this with the following workaround. */ double xmin = my x1 - 0.5 * my dx; double xmax = xmin + my nx * my dx; tmin = tmin < xmin ? xmin : tmin; tmax = tmax > xmax ? xmax : tmax; // End of workaround his x[k] = tmin; his y[k++] = CLIP_Y (level, ymin, ymax); his x[k] = tmin; double y = Vector_getValueAtX (me, tmin, channel, Vector_VALUE_INTERPOLATION_LINEAR); his y[k++] = CLIP_Y (y, ymin, ymax); for (long i = i1; i <= i2; i++) { y = my z[channel][i]; his x[k] = my x1 + (i - 1) * my dx; his y[k++] = CLIP_Y (y, ymin, ymax); } his x[k] = tmax; y = Vector_getValueAtX (me, tmax, channel, Vector_VALUE_INTERPOLATION_LINEAR); his y[k++] = CLIP_Y (y, ymin, ymax); his x[k] = tmax; his y[k++] = CLIP_Y (level, ymin, ymax); return him; } catch (MelderError) { Melder_throw (me, U":no Polygon created."); } } /* Area inbetween */ autoPolygon Sounds_to_Polygon_enclosed (Sound me, Sound thee, int channel, double tmin, double tmax, double ymin, double ymax) { try { bool clip = ymin < ymax; if (my ny > 1 && thy ny > 1 && my ny != thy ny) { Melder_throw (U"The numbers of channels of the two sounds have to be equal or 1."); } long numberOfChannels = my ny > thy ny ? my ny : thy ny; if (channel < 1 || channel > numberOfChannels) { Melder_throw (U"Channel does not exist."); } // find overlap in the domains with xmin workaround as in Sound_to_Polygon double xmin1 = my x1 - 0.5 * my dx, xmin2 = thy x1 - 0.5 * thy dx ; double xmin = my xmin > thy xmin ? xmin1 : xmin2; double xmax = my xmax < thy xmax ? xmin1 + my nx * my dx : xmin2 + thy nx * thy dx; if (xmax <= xmin) { Melder_throw (U"Domains must overlap."); } if (tmin >= tmax) { tmin = xmin; tmax = xmax; } if (tmin < xmin) { tmin = xmin; } if (tmax > xmax) { tmax = xmax; } if (tmin >= xmax || tmax < xmin) { Melder_throw (U"Invalid domain."); } long k = 1; long ib1 = Sampled_xToHighIndex (me, tmin); long ie1 = Sampled_xToLowIndex (me, tmax); long n1 = ie1 - ib1 + 1; long ib2 = Sampled_xToHighIndex (thee, tmin); long ie2 = Sampled_xToLowIndex (thee, tmax); long n2 = ie2 - ib2 + 1; long numberOfPoints = n1 + n2 + 4; // me + thee + begin + endpoint + closing autoPolygon him = Polygon_create (numberOfPoints); // my starting point at tmin double y = Vector_getValueAtX (me, tmin, (my ny == 1 ? 1 : channel), Vector_VALUE_INTERPOLATION_LINEAR); his x[k] = tmin; his y[k++] = CLIP_Y (y, ymin, ymax); // my samples for (long i = ib1; i <= ie1; i++) { double t = my x1 + (i - 1) * my dx; y = my z[my ny == 1 ? 1 : channel][i]; his x[k] = t; his y[k++] = CLIP_Y (y, ymin, ymax); } // my end point at tmax y = Vector_getValueAtX (me, tmax, (my ny == 1 ? 1 : channel), Vector_VALUE_INTERPOLATION_LINEAR); his x[k] = tmax; his y[k++] = y; // thy starting point at tmax y = Vector_getValueAtX (thee, tmax, (thy ny == 1 ? 1 : channel), Vector_VALUE_INTERPOLATION_LINEAR); his x[k] = tmax; his y[k++] = y; // thy samples for (long i = ie2; i >= ib2; i--) { double t = thy x1 + (i - 1) * thy dx; y = thy z[thy ny == 1 ? 1 : channel][i]; his x[k] = t; his y[k++] = CLIP_Y (y, ymin, ymax); } // thy end point at tmin y = Vector_getValueAtX (thee, tmin, (thy ny == 1 ? 1 : channel), Vector_VALUE_INTERPOLATION_LINEAR); his x[k] = tmin; his y[k] = y; Melder_assert (k == numberOfPoints); return him; } catch (MelderError) { Melder_throw (me, U": no enclosed Polygon created."); } } #define INTERSECTION_OUTSIDE 0 #define INTERSECTION_PROPER 1 #define INTERSECTION_AT_EDGE 2 #define INTERSECTION_AT_VERTEX 3 #define INTERSECTION_COPLANAR 4 #define INTERSECTION_COPLANAR_AT_EDGE 6 #define INTERSECTION_COPLANAR_AT_VERTEX 7 // 12 is from subject 34 from clipping static int get_collinearIntersectionPoint (double x1, double x2, double x3, double x4, double *xs) { bool p3inb12 = (x1 < x3 and x3 <= x2) or (x1 > x3 and x3 >= x2); bool p4inb12 = (x1 < x4 and x4 <= x2) or (x1 > x4 and x4 >= x2); int intersection = INTERSECTION_AT_VERTEX; if (x1 < x2) { if (x3 < x4) { if (x2 < x3 || x4 < x1) { intersection = INTERSECTION_OUTSIDE; } else if (p3inb12) { // 4 can be inside or outside *xs = p4inb12 ? x4 : x2; } else if (p4inb12) { // 3 is outside *xs = x4; } else { // 3 and 4 outside 12 segment *xs = x2; intersection = INTERSECTION_AT_EDGE; } } else { // x4 < x3 if (x2 < x4 || x3 < x1) { intersection = INTERSECTION_OUTSIDE; } else if (p3inb12) { // 4 can be inside or outside *xs = x4; } else if (p4inb12) { // 3 outside *xs = x4; } else { *xs = x2; intersection = INTERSECTION_AT_EDGE; } } } else { // x2 < x1 if (x3 < x4) { if (x1 < x3 || x4 < x2) { intersection = INTERSECTION_OUTSIDE; } else if (p3inb12) { *xs = p4inb12 ? x4 : x3; } else if (p4inb12) { // 3 outside *xs = x4; } else { *xs = x2; intersection = INTERSECTION_AT_EDGE; } } else { // x4 < x3 if (x1 < x4 || x3 < x2) { intersection = INTERSECTION_OUTSIDE; } else if (p3inb12) { *xs = x3; } else if (p4inb12) { *xs = x4; } else { *xs = x3; } } } return intersection; } // Line from a to b : // (1) ab = (1-s)*a+s*b = a + s*(b-a) = a + s * b' // (2) cd = c+t*(d-c) = c + t * d' // where b' = b - a and d' = d - c. // at intersection: // (3) a + s * b' = c + t * d' // Cross (3) with d'; // cross (a, d') + s * cross (b', d') = cross (c, d') // s = cross (c - a, d') / cross (b', d') // Cross (3) with b' // cross (a, b') = cross (c, b') + t * cross (d', b') // t = cross (c - a, b') / cross (b', d') // if cross (b', b') then b' and d' are parallel // After Paul Rourke // Area of triangle a,b,c = ((bx-ax)(cy-ay) - (cx-ax)(by-ay)) / 2 #define POS(ax,ay,bx,by,cx,cy) (bx - ax) * (cy - ay) - (cx - ax) * (by-ay); // if POS(a,b,c) (> 0 ; <0, 0) then c is on (the left of; the right of; collinear with) the line segment (a,b) // Register the crossing of line a(1)b(2) with c(3)d(4), if the crossing is degenerate only register the tip. static int LineSegments_getIntersection (double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double *mua, double *mub, double eps) { // bounding box pre-selection double min12 = x1 < x2 ? x1 : x2; double max12 = x1 > x2 ? x1 : x2; double min34 = x3 < x4 ? x3 : x4; double max34 = x3 > x4 ? x3 : x4; if (max12 - min34 < -eps or max34 - min12 < -eps) { return INTERSECTION_OUTSIDE; // eps? } min12 = y1 < y2 ? y1 : y2; max12 = y1 > y2 ? y1 : y2; min34 = y3 < y4 ? y3 : y4; max34 = y3 > y4 ? y3 : y4; if (max12 - min34 < -eps or max34 - min12 < -eps) { return INTERSECTION_OUTSIDE; } double cad = (x3 - x1) * (y4 - y3) - (y3 - y1) * (x4 - x3); // cross (c - a, d') double cab = (x3 - x1) * (y2 - y1) - (y3 - y1) * (x2 - x1); // cross (c - a, b') double bd = (x2 - x1) * (y4 - y3) - (y2 - y1) * (x4 - x3); // cross (b', d') if (fabs (bd) > eps) { *mua = cad / bd; *mub = cab / bd; if (*mua <= eps or * mua > 1 + eps or * mub < eps or * mub > 1 + eps) { return INTERSECTION_OUTSIDE; } if (*mua > eps and *mua <= 1 - eps and *mub >= eps and * mub < 1 - eps) { // This occurs most of the cases (hopefully) return INTERSECTION_PROPER; } // Now eps < mua,mub <= 1+eps // and at least one of the mu's is near 1, // the other is in [eps,1] if (fabs (*mua - 1) < eps) { *mua = 1; } if (fabs (*mub - 1) < eps) { *mub = 1; } // is the intersection at an edge or at vertex if (*mua == 1) { // end of ab touches cd return *mub == 1 ? INTERSECTION_AT_VERTEX : INTERSECTION_AT_EDGE; } else { // ab crosses a vertex return INTERSECTION_AT_VERTEX; } } else { // ab and cd are parallel or coplanar if (fabs (cad) > eps and fabs (cab) > eps) { return INTERSECTION_OUTSIDE; } if (x1 == x2) { x1 = y1; x2 = y2; x3 = y3; x4 = y4; } double xs; int intersection = get_collinearIntersectionPoint (x1, x2, x3, x4, &xs); if (intersection != INTERSECTION_OUTSIDE) { *mua = fabs ( (xs - x1) / (x2 - x1)); *mub = fabs ( (xs - x3) / (x4 - x3)); intersection += INTERSECTION_COPLANAR; } return intersection; } } // Vertices: // first node has prev = 0, last node has next = 0; // entry marks the entrance of the OTHER polygon Thing_define (Vertex, Daata) { // new data: public: double x, y, alpha; DLLNode neighbour; long poly_npoints, id; int intersect, entry; bool processed; // overridden methods: virtual void v_copy (Any data_to); }; Thing_implement (Vertex, Daata, 0); void structVertex :: v_copy (thou) { thouart (Vertex); thy x = x; thy y = y; thy alpha = alpha; thy neighbour = neighbour; thy poly_npoints = poly_npoints; thy id = id; thy intersect = intersect; thy entry = entry; thy processed = processed; } Vertex Vertex_create (); Vertex Vertex_create () { try { autoVertex me = Thing_new (Vertex); return me.transfer(); } catch (MelderError) { Melder_throw (U"Vertex not created."); } } Thing_define (Vertices, DLL) { // overridden methods: protected: static int s_compare (Any data1, Any data2); virtual Data_CompareFunction v_getCompareFunction () { return s_compare; } }; Thing_implement (Vertices, DLL, 0); #define VERTEX(n) ((Vertex) ((n) -> data)) int structVertices :: s_compare (I, thou) { iam (DLLNode); thouart (DLLNode); return VERTEX (me) -> alpha < VERTEX (thee) -> alpha ? -1 : VERTEX (me) -> alpha > VERTEX (thee) -> alpha ? 1 : 0; } Vertices Vertices_create (); Vertices Vertices_create () { try { Vertices me = Thing_new (Vertices); return me; } catch (MelderError) { Melder_throw (U"Vertices not created."); } } void Vertices_addCopyBack (Vertices me, DLLNode n); void Vertices_addCopyBack (Vertices me, DLLNode n) { try { autoDLLNode nc = (DLLNode) Data_copy (n); DLL_addBack ( (DLL) me, nc.transfer()); } catch (MelderError) { Melder_throw (me, U": no copy added."); } } static bool pointsInsideInterval (double *x, long n, long istart, long iend, long *jstart, long *jend) { double xmax = x[istart], xmin = x[istart]; long imax = istart, imin = istart; long iendmod = iend > istart ? iend : iend + n; // circular for (long i = istart + 1; i <= iendmod; i++) { long index = (i - 1) % n + 1; // make it circular if (x[index] > xmax) { xmax = x[index]; imax = index; } else if (x[index] < xmin) { xmin = x[index]; imin = index; } } *jstart = imin; *jend = imax; if (x[istart] > x[iend]) { *jstart = imax; *jend = imin; } if (x[istart] == x[*jstart] and x[iend] == x[*jend]) { // if there are duplicates of the extrema *jstart = istart; *jend = iend; } return *jstart == istart and * jend == iend; } autoPolygon Polygon_circularPermutation (Polygon me, long nshift); autoPolygon Polygon_circularPermutation (Polygon me, long nshift) { try { autoPolygon thee = Data_copy (me); if (nshift != 0) { for (long i = 1; i <= my numberOfPoints; i++) { long inew = (i + nshift - 1) % my numberOfPoints + 1; thy x[inew] = my x[i]; thy y[inew] = my y[i]; } } return thee; } catch (MelderError) { Melder_throw (me, U": not circularly permuted."); } } void _Polygons_copyNonCollinearities (Polygon me, Polygon thee, long collstart, long collend); void _Polygons_copyNonCollinearities (Polygon me, Polygon thee, long collstart, long collend) { // Determine if all collinear point are within the interval [colstart,colend] long jstart, jend; bool allPointsInside = my x[collstart] != my x[collend] ? pointsInsideInterval (my x, my numberOfPoints, collstart, collend, &jstart, &jend) : pointsInsideInterval (my y, my numberOfPoints, collstart, collend, &jstart, &jend); if (not allPointsInside) { if (collstart != jstart) { // also include the extreme point at start thy numberOfPoints++; thy x[thy numberOfPoints] = my x[jstart]; thy y[thy numberOfPoints] = my y[jstart]; } if (collend != jend) { // also include the extreme point at end thy numberOfPoints++; thy x[thy numberOfPoints] = my x[jend]; thy y[thy numberOfPoints] = my y[jend]; } } thy numberOfPoints++; thy x[thy numberOfPoints] = my x[collend]; thy y[thy numberOfPoints] = my y[collend]; } #define AREA(x1,y1,x2,y2,x3,y3) (x1*(y2 - y3)+x2*(y3-y1)+x3*(y1-y2)) autoPolygon Polygon_simplify (Polygon me); autoPolygon Polygon_simplify (Polygon me) { try { autoPolygon p1 = Data_copy (me); // pass 1: remove doublets long np = 1; for (long i = 2; i <= my numberOfPoints; i++) { if (my x[i] != p1 -> x[np] || my y[i] != p1 -> y[np]) { p1 -> x[++np] = my x[i]; p1 -> y[np] = my y[i]; } } // last and first points! if (p1 -> x[np] == p1 -> x[1] && p1 -> y[np] == p1 -> y[1]) { np--; } if (np < 3) { Melder_throw (U"Not enough points left after doublet removal."); } p1 -> numberOfPoints = np; // pass 2: remove collinearities autoPolygon p = Data_copy (p1.peek()); p -> numberOfPoints = 0; // is there collinearity between the first and the last points of p1? double eps = 1e-15; double area = AREA (p1 -> x[np], p1 -> y[np], p1 -> x[1], p1 -> y[1], p1 -> x[2], p1 -> y[2]); long collend = 2; while (fabs (area) < eps && collend < np) { collend++; area = AREA (p1 -> x[collend - 2], p1 -> y[collend - 2], p1 -> x[collend - 1], p1 -> y[collend - 1], p1 -> x[collend], p1 -> y[collend]); } collend--; area = AREA (p1 -> x[np - 1], p1 -> y[np - 1], p1 -> x[np], p1 -> y[np], p1 -> x[1], p1 -> y[1]); long collstart = np - 1; while (fabs (area) < eps && collstart > collend) { collstart--; area = AREA (p1 -> x[collstart], p1 -> y[collstart], p1 -> x[collstart + 1], p1 -> y[collstart + 1], p1 -> x[collstart + 2], p1 -> y[collstart + 2]); } collstart++; if (collend - collstart + p1 -> numberOfPoints > 1) { _Polygons_copyNonCollinearities (p1.peek(), p.peek(), collstart, collend); } else { p -> numberOfPoints = 1; p -> x[1] = p1 -> x[1]; p -> y[1] = p1 -> y[1]; } bool collinearity = false; long endpos = collstart - 1; for (long i = collend + 1; i <= endpos; i++) { // start was < numberOfPoints // if i-1, i, i+1 are coplanar, remove i // area = x1*(y2 - y3)+x2*(y3-y1)+x3*(y1-y2) area = AREA (p1 -> x[i - 1], p1 -> y[i - 1], p1 -> x[i], p1 -> y[i], p1 -> x[i + 1], p1 -> y[i + 1]); if (fabs (area) < eps) { if (collinearity) { collend = i + 1; } else { // start of possibly new series collinearity = true; collstart = i - 1; collend = i + 1; } if (i != endpos) { continue; } } if (not collinearity) { p -> numberOfPoints++; p -> x[p -> numberOfPoints] = p1 -> x[i]; p -> y[p -> numberOfPoints] = p1 -> y[i]; } else { // end of series of collinearities detected _Polygons_copyNonCollinearities (p1.peek(), p.peek(), collstart, collend); collinearity = false; } } if (not collinearity and collend != endpos + 1) { // only if previous series was not collinear p -> numberOfPoints++; p -> x[p -> numberOfPoints] = p1 -> x[endpos + 1]; p -> y[p -> numberOfPoints] = p1 -> y[endpos + 1]; } if (p -> numberOfPoints < 3) { Melder_throw (U"Not enough points left after collinear points removal."); } autoPolygon thee = Data_copy (p.peek()); // return thee; } catch (MelderError) { Melder_throw (me, U": not simplified."); } } #undef AREA Vertices Polygon_to_Vertices (Polygon me, bool close); Vertices Polygon_to_Vertices (Polygon me, bool close) { try { autoVertices thee = Vertices_create (); for (long i = 1 ; i <= my numberOfPoints; i++) { autoVertex v = Vertex_create (); v -> x = my x[i]; v -> y = my y[i]; autoDLLNode n = DLLNode_create ( (Daata) v.transfer()); DLL_addBack ( (DLL) thee.peek(), n.transfer()); } Melder_assert (thy numberOfNodes == my numberOfPoints); if (close) { Vertices_addCopyBack (thee.peek(), thy front); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no Vertices created."); } } #define SKIP_INTERSECTION_NODES(n) while(VERTEX(n) -> intersect != 0) n = n -> next; void Vertices_print (Vertices me, Vertices thee); void Vertices_print (Vertices me, Vertices thee) { long ns = 0, nc = 0, nt, nt2; // MelderInfo_open(); DLLNode n = my front; MelderInfo_writeLine (U""); while (n != 0) { double x = VERTEX (n) -> x, y = VERTEX (n) -> y, alpha = VERTEX (n) -> alpha; const char32 *type = 0, *itype; if (VERTEX (n) -> intersect == 0) { type = U"S"; ns++; nt = ns; itype = U"-"; nt2 = 0; } else { type = U"I"; nt = VERTEX (n) -> id; nt2 = VERTEX (VERTEX (n) -> neighbour) -> id; itype = Melder_integer (VERTEX (n) -> intersect); } MelderInfo_write (type, nt, U" I", itype, U", (", x, U", ", y, U"), "); MelderInfo_write (alpha, U", E", VERTEX (n) -> entry, U"(", nt2, U")\n"); n = n -> next; } MelderInfo_writeLine (U""); n = thy front; while (n != 0) { double x = VERTEX (n) -> x, y = VERTEX (n) -> y, alpha = VERTEX (n) -> alpha; const char32 *type = 0, *itype; if (VERTEX (n) -> intersect == 0) { type = U"C"; nc++; nt = nc; itype = U"-"; nt2 = 0; } else { type = U"I"; nt = VERTEX (n) -> id; nt2 = VERTEX (VERTEX (n) -> neighbour) -> id; itype = Melder_integer (VERTEX (n) -> intersect); } MelderInfo_write (type, nt, U" I", itype, U", (", x, U", ", y, U"), "); MelderInfo_write (alpha, U", E", VERTEX (n) -> entry, U"(", nt2, U")\n"); n = n -> next; } // MelderInfo_close(); } void Vertices_sortIntersections (Vertices me); void Vertices_sortIntersections (Vertices me) { DLLNode ni = my front, first; bool intersections = false; while (ni != my back) { if (VERTEX (ni) -> intersect == 0) { if (intersections) { // the previous was the last of a series of intersections DLL_sortPart ( (DLL) me, first, ni -> prev); // restore myNode pointers intersections = false; } } else { if (not intersections) { first = ni; intersections = true; } } ni = ni -> next; } // we might have missed the last series of intersections if (intersections) { DLL_sortPart ( (DLL) me, first, ni -> prev); } } void Vertices_addIntersections (Vertices me, Vertices thee); void Vertices_addIntersections (Vertices me, Vertices thee) { try { double eps = 1e-15; long id = 0; if (my numberOfNodes < 4 || thy numberOfNodes < 4) { Melder_throw (U"We need at least three vertices."); } DLLNode ni = my front; // the node index in me (s) while (ni != my back) { // until penultimate double x1 = VERTEX (ni) -> x, y1 = VERTEX (ni) -> y; double x2 = VERTEX (ni -> next) -> x, y2 = VERTEX (ni -> next) -> y; DLLNode nj = thy front; // the current node index in thee (c) while (nj != thy back && VERTEX (nj) -> intersect == 0) { DLLNode njn = nj -> next; SKIP_INTERSECTION_NODES (njn) double x3 = VERTEX (nj) -> x, y3 = VERTEX (nj) -> y; double x4 = VERTEX (njn) -> x, y4 = VERTEX (njn) -> y, mua, mub; int intersection = LineSegments_getIntersection (x1, y1, x2, y2, x3, y3, x4, y4, &mua, &mub, eps); if (intersection != INTERSECTION_OUTSIDE) { id++; // 1. create the vertices autoVertex ins = Vertex_create (); ins -> x = x1 + mua * (x2 - x1); ins -> y = y1 + mua * (y2 - y1); ins -> alpha = mua; ins -> intersect = intersection; ins -> id = id; autoVertex inc = Data_copy (ins.peek()); inc -> alpha = mub; // 2. create the nodes autoDLLNode ns = DLLNode_create (0); autoDLLNode nc = DLLNode_create (0); // 3. link the neighbours + copy the links DLLNode njc = ins -> neighbour = nc.peek(); DLLNode nic = inc -> neighbour = ns.peek(); // 4. transfer the vertices to the nodes ns -> data = (Daata) ins.transfer(); nc -> data = (Daata) inc.transfer(); // 5. add the nodes to the list DLL_addAfter ( (DLL) me, ni, ns.transfer()); DLL_addAfter ( (DLL) thee, nj, nc.transfer()); // 6. set node pointer to inserted nodes ni = nic; nj = njc; } nj = nj -> next; SKIP_INTERSECTION_NODES (nj) } ni = ni -> next; } if (Melder_debug == -1) { MelderInfo_open(); Vertices_print (me, thee); } Vertices_sortIntersections (me); Vertices_sortIntersections (thee); if (Melder_debug == -1) { Vertices_print (me, thee); } } catch (MelderError) { Melder_throw (U"Intersections not calculated."); } } #define Polygon_EN 1 #define Polygon_EX 2 #define Polygon_ENEX 3 #define Polygon_EXEN 4 void Vertices_markEntryPoints (Vertices me, int firstLocation); void Vertices_markEntryPoints (Vertices me, int firstLocation) { int entry = (firstLocation == Polygon_INSIDE) ? Polygon_EX : (firstLocation == Polygon_OUTSIDE) ? Polygon_EN : Polygon_ENEX; // problematic when on boundary // my back/front can never be an intersection node for (DLLNode ni = my front -> next; ni != my back; ni = ni -> next) { if (VERTEX (ni) -> intersect == 0) { continue; } VERTEX (ni) -> entry = entry; entry = (entry == Polygon_EN) ? Polygon_EX : (entry == Polygon_EX) ? Polygon_EN : Polygon_ENEX; } } Vertices Verticeses_connectClippingPathsUnion (Vertices me, Vertices thee); Vertices Verticeses_connectClippingPathsUnion (Vertices me, Vertices thee) { try { // find my first vertex outside thee, by searching the first intersection entry DLLNode firstOutside = my front; bool firstOutsideSet = true; for (DLLNode ni = my front; ni != 0; ni = ni -> next) { if (VERTEX (ni) -> intersect == 0) { // if (firstOutsideSet) { continue; } firstOutside = ni; break; } else if (VERTEX (ni) -> entry == Polygon_EN) { break; } // We were inside else { firstOutsideSet = false; } } autoVertices him = Vertices_create (); long poly_npoints = 0; DLLNode current = firstOutside; bool inside = false, forward = true; do { if (VERTEX (current) -> intersect == 0) { Vertices_addCopyBack (him.peek(), current); poly_npoints++; } else { // intersection point // store and jump to other polygon Vertices_addCopyBack (him.peek(), current); poly_npoints++; current = VERTEX (current) -> neighbour; inside = not inside; forward = VERTEX (current) -> entry == Polygon_EX; } if (forward) { current = current -> next; if (current == 0) { current = inside ? thy front : my front; } } else { current = current -> prev; if (current == 0) { current = inside ? thy back : my back; } } } while (current != firstOutside and current != 0 and poly_npoints < my numberOfNodes); VERTEX (his front) -> poly_npoints = poly_npoints; return him.transfer(); } catch (MelderError) { Melder_throw (me, U": no clipping path."); } } //Vertices Verticeses_connectClippingPaths (Vertices me, bool use_myinterior, Vertices thee, bool use_thyinterior); static Vertices Verticeses_connectClippingPaths (Vertices me, bool /* use_myinterior */, Vertices thee, bool /* use_thyinterior */) { try { autoVertices him = Vertices_create (); DLLNode prevPoly; long poly_npoints = 0; for (DLLNode ni = my front; ni != 0; ni = ni -> next) { if ( (VERTEX (ni) -> intersect == 0) || VERTEX (ni) -> processed) { continue; } // Intersection found: start new polygon DLLNode currentPoly = his back; if (currentPoly == his front) { Vertices_addCopyBack (him.peek(), ni); poly_npoints++; prevPoly = his front; } else { Vertices_addCopyBack (him.peek(), ni); poly_npoints++; VERTEX (prevPoly) -> poly_npoints = poly_npoints; poly_npoints = 0; prevPoly = currentPoly; } DLLNode current = ni; VERTEX (current) -> processed = true; long jumps = 0; do { if (VERTEX (current) -> entry == Polygon_EN) { while ( (current = current -> next) != 0 and VERTEX (current) -> intersect == 0) { Vertices_addCopyBack (him.peek(), current); poly_npoints++; } if (current == 0) { // back of list? Goto front current = (jumps % 2 == 0) ? my front : thy front; while ( (current = current -> next) != 0 and VERTEX (current) -> intersect == 0) { Vertices_addCopyBack (him.peek(), current); poly_npoints++; } Vertices_addCopyBack (him.peek(), current); poly_npoints++; // intersection point } else if (current == ni) { break; // done } else { current = current -> prev; } } else if (VERTEX (current) -> entry == Polygon_EX) { while ( (current = current -> prev) != 0 and VERTEX (current) -> intersect == 0) { Vertices_addCopyBack (him.peek(), current); poly_npoints++; } if (current == 0) { // start of list? Goto end current = (jumps % 2 == 0) ? my back : thy back; while ( (current = current -> prev) != 0 and VERTEX (current) -> intersect == 0) { Vertices_addCopyBack (him.peek(), current); poly_npoints++; } Vertices_addCopyBack (him.peek(), current); poly_npoints++; // intersection point } else if (current == ni) { break; // done } else { current = current -> next; } } else { } VERTEX (current) -> processed = true; current = VERTEX (current) -> neighbour; jumps++; VERTEX (current) -> processed = true; } while (current != ni); // polygon closed } // last polygon: VERTEX (prevPoly) -> poly_npoints = poly_npoints; return him.transfer(); } catch (MelderError) { Melder_throw (me, U": no clipping vertices created."); } } // autoPolygon Vertices_to_Polygon (Vertices me, DLLNode *ni); autoPolygon Vertices_to_Polygon (Vertices /* me */, DLLNode *ni) { DLLNode n = *ni; try { long i = 1, nPoints = VERTEX (n) -> poly_npoints; if (nPoints == 0) { Melder_throw (U"No number info."); } autoPolygon thee = Polygon_create (nPoints); thy x[i] = VERTEX (n) -> x; thy y[i] = VERTEX (n) -> y; while ( (n = n -> next) != 0 and VERTEX (n) -> poly_npoints == 0 and i <= nPoints) { i++; thy x[i] = VERTEX (n) -> x; thy y[i] = VERTEX (n) -> y; } *ni = n; return thee; } catch (MelderError) { Melder_throw (U"Polygon not created."); } } autoCollection Vertices_to_Polygons (Vertices me); autoCollection Vertices_to_Polygons (Vertices me) { try { autoCollection thee = Collection_create (classPolygon, 10); DLLNode ni = my front; do { autoPolygon p = Vertices_to_Polygon (me, & ni); Collection_addItem (thee.peek(), p.transfer()); } while (ni != 0); return thee; } catch (MelderError) { Melder_throw (me, U": no polygon collection created."); } } autoCollection Polygons_findClippings (Polygon me, bool use_myinterior, Polygon thee, bool use_thyinterior); autoCollection Polygons_findClippings (Polygon me, bool use_myinterior, Polygon thee, bool use_thyinterior) { try { autoVertices s = Polygon_to_Vertices (me, true); // subject long ns = s -> numberOfNodes; autoVertices c = Polygon_to_Vertices (thee, true); // clip // long nc = c -> numberOfNodes; double eps = 1e-15; // phase 1: Get all intersections and add them to both lists Vertices_addIntersections (s.peek(), c.peek()); long nnewnodes = s -> numberOfNodes - ns; int firstLocation = Polygon_getLocationOfPoint (thee, my x[1], my y[1], eps); if (nnewnodes == 0) { // no crossings, either one completely inside the other or separate autoCollection apc; if (not use_myinterior and not use_thyinterior and firstLocation == Polygon_INSIDE) { autoPolygon ap = Data_copy (thee); Collection_addItem (apc.peek(), ap.transfer()); } else { autoPolygon ap = Data_copy (me); Collection_addItem (apc.peek(), ap.transfer()); } return apc; } // phase 2: Determine intersections as entry / exit points Vertices_markEntryPoints (s.peek(), firstLocation); firstLocation = Polygon_getLocationOfPoint (me, thy x[1], thy y[1], eps); Vertices_markEntryPoints (c.peek(), firstLocation); if (Melder_debug == -1) { Vertices_print (s.peek(), c.peek()); MelderInfo_close(); Melder_throw (U"Bail out of Polygons_findClippings."); } // phase 3: Determine the clipping paths // use_myinterior use_thyinterior result // true false diff me - thee // false false union // true true clip // false true diff thee - me autoVertices pgs; if (not use_myinterior and not use_thyinterior) { pgs = Verticeses_connectClippingPathsUnion (s.peek(), c.peek()); } else { pgs = Verticeses_connectClippingPaths (s.peek(), use_myinterior, c.peek(), use_thyinterior); } // phase 4: to Polygons autoCollection pols = Vertices_to_Polygons (pgs.peek()); return pols; } catch (MelderError) { Melder_throw (me, U": no union Polygon created."); } } autoCollection Polygons_clip (Polygon subject, Polygon clipper) { try { autoCollection him = Polygons_findClippings (subject, true, clipper, true); return him; } catch (MelderError) { Melder_throw (subject, U": no union created."); } } autoPolygon Polygons_union (Polygon me, Polygon thee); autoPolygon Polygons_union (Polygon me, Polygon thee) { try { autoCollection him = Polygons_findClippings (me, false, thee, false); //Melder_assert (his size == 1); autoPolygon p = (Polygon) Collection_subtractItem (him.peek(), 1); return p; } catch (MelderError) { Melder_throw (me, U": no union created."); } } #define CROSSING (my y[i] < y0) != (my y[ip1] < y0) #define AREA { a = (my x[i]-x0)*(my y[ip1]-y0) - (my x[ip1]-x0)*(my y[i]-y0); if (fabs (a) <= eps) return Polygon_EDGE; } #define RIGHT_CROSSING (a > 0) == (my y[ip1] > my y[i]) #define MODIFY_CROSSING_NUMBER { if (my y[ip1] > my y[i]) nup++; else nup--; } int Polygon_getLocationOfPoint (Polygon me, double x0, double y0, double eps); int Polygon_getLocationOfPoint (Polygon me, double x0, double y0, double eps) { if (my y[1] == y0 and my x[1] == x0) { return Polygon_VERTEX; } long nup = 0; for (long i = 1; i <= my numberOfPoints; i++) { double a; long ip1 = i < my numberOfPoints ? i + 1 : 1; if (my y[ip1] == y0) { if (my x[ip1] == x0) { return Polygon_VERTEX; } else if (my y[i] == y0 and (my x[ip1] > x0) == (my x[i] < x0)) { return Polygon_EDGE; } } if (CROSSING) { if (my x[i] >= x0) { if (my x[ip1] > x0) MODIFY_CROSSING_NUMBER else { AREA if (RIGHT_CROSSING) MODIFY_CROSSING_NUMBER } } else { if (my x[ip1] > x0) { AREA if (RIGHT_CROSSING) MODIFY_CROSSING_NUMBER } } } } return nup % 2 == 0 ? Polygon_OUTSIDE : Polygon_INSIDE; } static inline double cross (double x1, double y1, double x2, double y2, double x3, double y3) { return (x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1); } // Code adapted from http://en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Convex_hull/Monotone_chain#C autoPolygon Polygon_convexHull (Polygon me) { try { if (my numberOfPoints <= 3) { return (Polygon) Data_copy (me); } autoNUMvector x (1, my numberOfPoints), y (1, my numberOfPoints); autoNUMvector hull (1, my numberOfPoints + 2); for (long i = 1; i <= my numberOfPoints; i++) { x[i] = my x[i]; y[i] = my y[i]; } NUMsort2 (my numberOfPoints, x.peek(), y.peek()); // lower hull long n = 1; for (long i = 1; i <= my numberOfPoints; i++) { while (n > 2 && cross (x[hull[n - 2]], y[hull[n - 2]], x[hull[n - 1]], y[hull[n - 1]], x[i], y[i]) <= 0) { --n; // counter clockwise turn } hull[n++] = i; } // upper hull long t = n + 1; for (long i = my numberOfPoints - 1; i >= 1; i--) { while (n >= t && cross (x[hull[n - 2]], y[hull[n - 2]], x[hull[n - 1]], y[hull[n - 1]], x[i], y[i]) <= 0) { --n; } hull[n++] = i; } autoPolygon thee = Polygon_create (n - 1); for (long i = 1; i <= n - 1; i++) { thy x[i] = x[hull[i]]; thy y[i] = y[hull[i]]; } return thee; } catch (MelderError) { Melder_throw (me, U": no convex hull polygon created."); } } double Polygon_getAreaOfConvexHull (Polygon me) { try { autoPolygon thee = Polygon_convexHull (me); return Polygon_area (thee.peek()); } catch (MelderError) { Melder_clearError (); return NUMundefined; } } /* End of file Polygon_extensions.cpp */ praat-6.0.04/dwtools/Polygon_extensions.h000066400000000000000000000072771261542461700205070ustar00rootroot00000000000000#ifndef _Polygon_extensions_h_ #define _Polygon_extensions_h_ /* Polygon_extensions.h * * Copyright (C) 1993-2012, 2014, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 1996 djmw 20020813 GPL header djmw 20120220 Latest modification */ #include "Polygon.h" #include "Categories.h" #include "Graphics.h" #include "Sound.h" #define Polygon_INSIDE -1 #define Polygon_OUTSIDE 0 #define Polygon_BOUNDARY 1 #define Polygon_EDGE 3 #define Polygon_VERTEX 5 void Polygon_getExtrema (Polygon me, double *xmin, double *xmax, double *ymin, double *ymax); autoPolygon Polygon_createSimple (char32 *xystring); autoPolygon Polygon_createFromRandomVertices (long numberOfVertices, double xmin, double xmax, double ymin, double ymax); autoPolygon Polygon_simplify (Polygon me); void Polygon_translate (Polygon me, double xt, double yt); void Polygon_rotate (Polygon me, double alpha, double xc, double yc); void Polygon_scale (Polygon me, double xs, double ys); void Polygon_reverseX (Polygon me); void Polygon_reverseY (Polygon me); autoPolygon Polygon_circularPermutation (Polygon me, long nshift); // Is point (x,y) Inside, Outside, Boundary (Edge or Vertex) ? int Polygon_getLocationOfPoint (Polygon me, double x0, double y0, double eps); void Polygon_Categories_draw (Polygon me, Categories thee, Graphics graphics, double xmin, double xmax, double ymin, double ymax, int garnish); /* reverse axis when min > max */ void Polygon_drawMarks (Polygon me, Graphics g, double xmin, double xmax, double ymin, double ymax, double size_mm, const char32 *mark); autoPolygon Sound_to_Polygon (Sound me, int channel, double tmin, double tmax, double ymin, double ymax, double level); /* Post-conditions: If there are ns = i2 - i1 + 1 samples of the sound in the interval (tmin, tmax), the first at index i1 and the last at index i2, the Polygon will have np = 2 + ns + 2 + 1 points. i1 = Sampled_xToHighIndex (me, tmin) i2 = Sampled_xToLowIndex (me, tmax) thy x[1] = tmin thy y[1] = clip(level) thy x[2] = tmin thy y[2] = interpolated amplitude in 'channel' at tmin (or, averaged over all channels if channel = 0) thy x[3] = my x1 + (i1 - 1) * my dx thy y[3] = clip(my z[channel][i1]) (or, averaged over all channels if channel == 0) ... thy x[ns+2] = my x1 +(i2 - 1) * my dx thy y[ns+2] = clip(my z[channel][i2]) (or, averaged over all channels if channel == 0) thy x[ns+3] = tmax thy y[ns+3] = clip(interpolated amplitude in 'channel' at tmax (or, averaged over all channels if channel == 0)) thy x[ns+4] = tmax thy y[ns+4] = clip(level) thy x[ns+5] = thy x[1] (close the path) thy y[ns+5] = thy y[1] where clip(y) = y < ymin ? ymin : y > ymax ? ymax ; y; */ autoPolygon Sounds_to_Polygon_enclosed (Sound me, Sound thee, int channel, double tmin, double tmax, double ymin, double ymax); /* Area enclosed by the sounds */ autoPolygon Polygons_union (Polygon me, Polygon thee); autoCollection Polygons_clip (Polygon me, Polygon thee); autoPolygon Polygon_convexHull (Polygon me); double Polygon_getAreaOfConvexHull (Polygon me); #endif /* _Polygon_extensions_h_ */ praat-6.0.04/dwtools/Polynomial.cpp000066400000000000000000001512161261542461700172500ustar00rootroot00000000000000/* Polynomial.cpp * * Copyright (C) 1993-2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header djmw 20030619 Added SVD_compute before SVD_solve djmw 20060510 Polynomial_to_Roots: changed behaviour. All roots found are now saved. In previous version a nullptr pointer was returned. New error messages. djmw 20061021 printf expects %ld for 'long int' djmw 20071012 Added: o_CAN_WRITE_AS_ENCODING.h djmw 20071201 Melder_warning djmw 20080122 float -> double djmw 20110304 Thing_new */ #include "Polynomial.h" #include "SVD.h" #include "NUMclapack.h" #include "TableOfReal_extensions.h" #include "NUMmachar.h" #include "oo_DESTROY.h" #include "Polynomial_def.h" #include "oo_COPY.h" #include "Polynomial_def.h" #include "oo_EQUAL.h" #include "Polynomial_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Polynomial_def.h" #include "oo_WRITE_TEXT.h" #include "Polynomial_def.h" #include "oo_WRITE_BINARY.h" #include "Polynomial_def.h" #include "oo_READ_TEXT.h" #include "Polynomial_def.h" #include "oo_READ_BINARY.h" #include "Polynomial_def.h" #include "oo_DESCRIPTION.h" #include "Polynomial_def.h" #define MAX(m,n) ((m) > (n) ? (m) : (n)) #define MIN(m,n) ((m) < (n) ? (m) : (n)) /* Evaluate polynomial and derivative jointly c[1..n] -> degree n-1 !! */ static void Polynomial_evaluate2 (I, double x, double *f, double *df) { iam (Polynomial); long double p = my coefficients[my numberOfCoefficients], dp = 0, xc = x; for (long i = my numberOfCoefficients - 1; i > 0; i--) { dp = dp * xc + p; p = p * xc + my coefficients[i]; } *f = (double) p; *df = (double) dp; } /* Get value and derivative */ static void Polynomial_evaluate2_z (I, dcomplex *z, dcomplex *p, dcomplex *dp) { iam (Polynomial); long double pr = my coefficients[my numberOfCoefficients], pi = 0; long double dpr = 0, dpi = 0, x = z -> re, y = z -> im; for (long i = my numberOfCoefficients - 1; i > 0; i--) { long double tr = dpr; dpr = dpr * x - dpi * y + pr; dpi = tr * y + dpi * x + pi; tr = pr; pr = pr * x - pi * y + my coefficients[i]; pi = tr * y + pi * x; } p -> re = (double) pr; p -> im = (double) pi; dp -> re = (double) dpr; dp -> im = (double) dpi; } /* void polynomial_divide (double *u, long m, double *v, long n, double *q, double *r); Purpose: Find the quotient q(x) and the remainder r(x) polynomials that result from the division of the polynomial u(x) = u[1] + u[2]*x^1 + u[3]*x^2 + ... + u[m]*x^(m-1) by the polynomial v(x) = v[1] + v[2]*x^1 + v[3]*x^2 + ... + v[n]*x^(n-1), such that u(x) = v(x)*q(x) + r(x). The arrays u, v, q and r have to be dimensioned as u[1...m], v[1..n], q[1...m] and r[1...m], respectively. On return, the q[1..m-n] and r[1..n-1] contain the quotient and the remainder polynomial coefficients, repectively. See Knuth, The Art of Computer Programming, Volume 2: Seminumerical algorithms, Third edition, Section 4.6.1 Algorithm D (the algorithm as described has been modified to prevent overwriting of the u-polynomial). */ static void polynomial_divide (double *u, long m, double *v, long n, double *q, double *r) { // Copy u[1..m] into r[1..n] to prevent overwriting of u. // Put the q coefficients to zero for cases n > m. for (long k = 1; k <= m; k++) { r[k] = u[k]; q[k] = 0; } for (long k = m - n + 1; k > 0; k--) { /* D1 */ q[k] = r[n + k - 1] / v[n]; /* D2 with u -> r*/ for (long j = n + k - 1; j >= k; j--) { r[j] -= q[k] * v[j - k + 1]; } } } static void Polynomial_polish_realroot (I, double *x, long maxit) { iam (Polynomial); double xbest = *x, pmin = 1e308; if (! NUMfpp) { NUMmachar (); } for (long i = 1; i <= maxit; i++) { double p, dp; Polynomial_evaluate2 (me, *x, &p, &dp); double fabsp = fabs (p); if (fabsp > pmin || fabs (fabsp - pmin) < NUMfpp -> eps) { // We stop because the approximation gets worse or we cannot get closer anymore // Return previous (best) value for x. *x = xbest; return; } pmin = fabsp; xbest = *x; if (fabs (dp) == 0) { return; } double dx = p / dp; /* Newton -Raphson */ *x -= dx; } // Melder_throw (U"Maximum number of iterations exceeded."); } static void Polynomial_polish_complexroot_nr (I, dcomplex *z, long maxit) { iam (Polynomial); dcomplex zbest = *z; double pmin = 1e308; if (! NUMfpp) { NUMmachar (); } for (long i = 1; i <= maxit; i++) { dcomplex p, dp; Polynomial_evaluate2_z (me, z, &p, &dp); double fabsp = dcomplex_abs (p); if (fabsp > pmin || fabs (fabsp - pmin) < NUMfpp -> eps) { // We stop because the approximation gets worse. // Return previous (best) value for z. *z = zbest; return; } pmin = fabsp; zbest = *z; if (dcomplex_abs (dp) == 0) { return; } dcomplex dz = dcomplex_div (p , dp); /* Newton -Raphson */ *z = dcomplex_sub (*z, dz); } // Melder_throw (U"Maximum number of iterations exceeded."); } /* Symbolic evaluation of polynomial coefficients. Recurrence: P[n] = (a[n] * x + b[n]) P[n-1] + c[n] P[n-2], where P[n] is any orthogonal polynomial of degree n. P[n] is an array of coefficients p[k] representing: p[1] + p[2] x + ... p[n+1] x^n. Preconditions: degree > 1; pnm1 : polynomial of degree n - 1 pnm2 : polynomial of degree n - 2 */ static void NUMpolynomial_recurrence (double *pn, long degree, double a, double b, double c, double *pnm1, double *pnm2) { Melder_assert (degree > 1); pn[1] = b * pnm1[1] + c * pnm2[1]; for (long i = 2; i <= degree - 1; i++) { pn[i] = a * pnm1[i - 1] + b * pnm1[i] + c * pnm2[i]; } pn[degree] = a * pnm1[degree - 1] + b * pnm1[degree]; pn[degree + 1] = a * pnm1[degree]; } /* frozen[1..ma] */ static void svdcvm (double **v, long mfit, long ma, int *frozen, double *w, double **cvm) { autoNUMvector wti (1, mfit); for (long i = 1; i <= mfit; i++) { if (w[i] != 0.0) { wti[i] = 1.0 / (w[i] * w[i]); } } for (long i = 1; i <= mfit; i++) { for (long j = 1; j <= i; j++) { double sum = 0; for (long k = 1; k <= mfit; k++) { sum += v[i][k] * v[j][k] * wti[k]; } cvm[j][i] = cvm[i][j] = sum; } } for (long i = mfit + 1; i <= ma; i++) { for (long j = 1; j <= i; j++) { cvm[j][i] = cvm[i][j] = 0; } } long k = mfit; for (long j = ma; j > 0; j--) { // if (! frozen || ! frozen[i]) why i?? TODO if (! frozen || ! frozen[j]) { for (long i = 1; i <= ma; i++) { double t = cvm[i][k]; cvm[i][k] = cvm[i][j]; cvm[i][j] = t; } for (long i = 1; i <= ma; i++) { double t = cvm[k][i]; cvm[k][i] = cvm[j][i]; cvm[j][i] = t; } k--; } } } /********* FunctionTerms *********************************************/ Thing_implement (FunctionTerms, Function, 0); double structFunctionTerms :: v_evaluate (double x) { (void) x; return NUMundefined; } void structFunctionTerms :: v_evaluate_z (dcomplex *z, dcomplex *p) { (void) z; p -> re = p -> im = NUMundefined; } void structFunctionTerms :: v_evaluateTerms (double x, double terms[]) { (void) x; for (long i = 1; i <= numberOfCoefficients; i++) { terms[i] = NUMundefined; } } long structFunctionTerms :: v_getDegree () { return numberOfCoefficients - 1; } void structFunctionTerms :: v_getExtrema (double x1, double x2, double *lxmin, double *ymin, double *lxmax, double *ymax) { // David, geen aparte naam hier nodig: ??? long numberOfPoints = 1000; // Melder_warning (L"defaultGetExtrema: extrema calculated by sampling the interval"); double x = x1, dx = (x2 - x1) / (numberOfPoints - 1); *lxmin = *lxmax = x; *ymin = *ymax = v_evaluate (x); for (long i = 2; i <= numberOfPoints; i++) { x += dx; double y = v_evaluate (x); if (y > *ymax) { *ymax = y; *lxmax = x; } else if (y < *ymin) { *ymin = y; *lxmin = x; } } } void FunctionTerms_init (I, double xmin, double xmax, long numberOfCoefficients) { iam (FunctionTerms); my coefficients = NUMvector (1, numberOfCoefficients); my numberOfCoefficients = numberOfCoefficients; my xmin = xmin; my xmax = xmax; } FunctionTerms FunctionTerms_create (double xmin, double xmax, long numberOfCoefficients) { try { autoFunctionTerms me = Thing_new (FunctionTerms); FunctionTerms_init (me.peek(), xmin, xmax, numberOfCoefficients); return me.transfer(); } catch (MelderError) { Melder_throw (U"FunctionTerms not created."); } } void FunctionTerms_initFromString (I, double xmin, double xmax, const char32 *s, int allowTrailingZeros) { iam (FunctionTerms); long numberOfCoefficients; autoNUMvector numbers (NUMstring_to_numbers (s, &numberOfCoefficients), 1); if (! allowTrailingZeros) { while (numbers[numberOfCoefficients] == 0 && numberOfCoefficients > 1) { numberOfCoefficients--; } } FunctionTerms_init (me, xmin, xmax, numberOfCoefficients); NUMvector_copyElements (numbers.peek(), my coefficients, 1, numberOfCoefficients); } long FunctionTerms_getDegree (I) { iam (FunctionTerms); return my v_getDegree (); } void FunctionTerms_setDomain (I, double xmin, double xmax) { iam (FunctionTerms); my xmin = xmin; my xmax = xmax; } double FunctionTerms_evaluate (I, double x) { iam (FunctionTerms); return my v_evaluate (x); } void FunctionTerms_evaluate_z (I, dcomplex *z, dcomplex *p) { iam (FunctionTerms); my v_evaluate_z (z, p); } void FunctionTerms_evaluateTerms (I, double x, double terms[]) { iam (FunctionTerms); my v_evaluateTerms (x, terms); } void FunctionTerms_getExtrema (I, double x1, double x2, double *xmin, double *ymin, double *xmax, double *ymax) { iam (FunctionTerms); if (x2 <= x1) { x1 = my xmin; x2 = my xmax; } my v_getExtrema (x1, x2, xmin, ymin, xmax, ymax); } double FunctionTerms_getMinimum (I, double x1, double x2) { iam (FunctionTerms); double xmin, xmax, ymin, ymax; FunctionTerms_getExtrema (me, x1, x2, &xmin, &ymin, &xmax, &ymax); return ymin; } double FunctionTerms_getXOfMinimum (I, double x1, double x2) { iam (FunctionTerms); double xmin, xmax, ymin, ymax; FunctionTerms_getExtrema (me, x1, x2, &xmin, &ymin, &xmax, &ymax); return xmin; } double FunctionTerms_getMaximum (I, double x1, double x2) { iam (FunctionTerms); double xmin, xmax, ymin, ymax; FunctionTerms_getExtrema (me, x1, x2, &xmin, &ymin, &xmax, &ymax); return ymax; } double FunctionTerms_getXOfMaximum (I, double x1, double x2) { iam (FunctionTerms); double xmin, xmax, ymin, ymax; FunctionTerms_getExtrema (me, x1, x2, &xmin, &ymin, &xmax, &ymax); return xmax; } static void Graphics_polyline_clipTopBottom (Graphics g, double *x, double *y, long numberOfPoints, double ymin, double ymax) { long index = 0; if (numberOfPoints < 2) { return; } double x1 = x[0], y1 = y[0]; double xb = x1, yb = y1; for (long i = 1; i < numberOfPoints; i++) { double x2 = x[i], y2 = y[i]; if (! ( (y1 > ymax && y2 > ymax) || (y1 < ymin && y2 < ymin))) { double dxy = (x2 - x1) / (y1 - y2); double xcros_max = x1 - (ymax - y1) * dxy; double xcros_min = x1 - (ymin - y1) * dxy; if (y1 > ymax && y2 < ymax) { // Line enters from above: start new segment. Save start values. xb = x[i - 1]; yb = y[i - 1]; index = i - 1; y[i - 1] = ymax; x[i - 1] = xcros_max; } if (y1 > ymin && y2 < ymin) { // Line leaves at bottom: draw segment. Save end values and restore them // Origin of arrays for Graphics_polyline are at element 0 !!! double xe = x[i], ye = y[i]; y[i] = ymin; x[i] = xcros_min; Graphics_polyline (g, i - index + 1, x + index, y + index); x[index] = xb; y[index] = yb; x[i] = xe; y[i] = ye; } if (y1 < ymin && y2 > ymin) { // Line enters from below: start new segment. Save start values xb = x[i - 1]; yb = y[i - 1]; index = i - 1; y[i - 1] = ymin; x[i - 1] = xcros_min; } if (y1 < ymax && y2 > ymax) { // Line leaves at top: draw segment. Save and restore double xe = x[i], ye = y[i]; y[i] = ymax; x[i] = xcros_max; Graphics_polyline (g, i - index + 1, x + index, y + index); x[index] = xb; y[index] = yb; x[i] = xe; y[i] = ye; } } else { index = i; } y1 = y2; x1 = x2; } if (index < numberOfPoints - 1) { Graphics_polyline (g, numberOfPoints - index, x + index, y + index); x[index] = xb; y[index] = yb; } } void FunctionTerms_draw (I, Graphics g, double xmin, double xmax, double ymin, double ymax, int extrapolate, int garnish) { iam (FunctionTerms); long numberOfPoints = 1000; autoNUMvector y (1, numberOfPoints + 1); autoNUMvector x (1, numberOfPoints + 1); if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } double fxmin = xmin, fxmax = xmax; if (! extrapolate) { if (xmax < my xmin || xmin > my xmax) { return; } if (xmin < my xmin) { fxmin = my xmin; } if (xmax > my xmax) { fxmax = my xmax; } } if (ymax <= ymin) { double x1, x2; FunctionTerms_getExtrema (me, fxmin, fxmax, &x1, &ymin, &x2, &ymax); } Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); // Draw only the parts within [fxmin, fxmax] X [ymin, ymax]. double dx = (fxmax - fxmin) / (numberOfPoints - 1); for (long i = 1; i <= numberOfPoints; i++) { x[i] = fxmin + (i - 1.0) * dx; y[i] = FunctionTerms_evaluate (me, x[i]); } //Graphics_polyline_clipTopBottom (g, x+1, y+1, numberOfPoints, ymin, ymax); Graphics_polyline_clipTopBottom (g, &x[1], &y[1], numberOfPoints, ymin, ymax); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); } } void FunctionTerms_drawBasisFunction (I, Graphics g, long index, double xmin, double xmax, double ymin, double ymax, int extrapolate, int garnish) { iam (FunctionTerms); if (index < 1 || index > my numberOfCoefficients) { return; } autoFunctionTerms thee = (FunctionTerms) Data_copy (me); for (long i = 1; i <= my numberOfCoefficients; i++) { thy coefficients[i] = 0; } thy coefficients[index] = 1; thy numberOfCoefficients = index; FunctionTerms_draw (thee.peek(), g, xmin, xmax, ymin, ymax, extrapolate, garnish); } void FunctionTerms_setCoefficient (I, long index, double value) { iam (FunctionTerms); if (index < 1 || index > my numberOfCoefficients) { Melder_throw (U"Idex out of range [1, ", my numberOfCoefficients, U"]."); } if (index == my numberOfCoefficients && value == 0) { Melder_throw (U"You cannot remove the highest degree term."); } my coefficients[index] = value; } /********** Polynomial ***********************************************/ Thing_implement (Polynomial, FunctionTerms, 0); double structPolynomial :: v_evaluate (double x) { long double p = coefficients [numberOfCoefficients]; for (long i = numberOfCoefficients - 1; i > 0; i--) { p = p * x + coefficients [i]; } return (double) p; } void structPolynomial :: v_evaluate_z (dcomplex *z, dcomplex *p) { long double x = z -> re, y = z -> im; long double pr = coefficients [numberOfCoefficients]; long double pi = 0; for (long i = numberOfCoefficients - 1; i > 0; i--) { long double prtmp = pr; pr = pr * x - pi * y + coefficients[i]; pi = prtmp * y + pi * x; } p -> re = (double) pr; p -> im = (double) pi; } void structPolynomial :: v_evaluateTerms (double x, double terms[]) { terms[1] = 1; for (long i = 2; i <= numberOfCoefficients; i++) { terms[i] = terms[i - 1] * x; } } void structPolynomial :: v_getExtrema (double x1, double x2, double *lxmin, double *ymin, double *lxmax, double *ymax) { try { long degree = numberOfCoefficients - 1; *lxmin = x1; *ymin = v_evaluate (x1); *lxmax = x2; *ymax = v_evaluate (x2); if (*ymin > *ymax) { /* Swap */ double t = *ymin; *ymin = *ymax; *ymax = t; t = *lxmin; *lxmin = *lxmax; *lxmax = t; } if (degree < 2) { return; } autoPolynomial d = Polynomial_getDerivative (this); autoRoots r = Polynomial_to_Roots (d.peek()); for (long i = 1; i <= degree - 1; i++) { double x = (r -> v[i]).re; if (x > x1 && x < x2) { double y = v_evaluate (x); if (y > *ymax) { *ymax = y; *lxmax = x; } else if (y < *ymin) { *ymin = y; *lxmin = x; } } } } catch (MelderError) { structFunctionTerms :: v_getExtrema (x1, x2, lxmin, ymin, lxmax, ymax); Melder_clearError (); } } Polynomial Polynomial_create (double lxmin, double lxmax, long degree) { try { autoPolynomial me = Thing_new (Polynomial); FunctionTerms_init (me.peek(), lxmin, lxmax, degree + 1); return me.transfer(); } catch (MelderError) { Melder_throw (U"Polynomial not created."); } } Polynomial Polynomial_createFromString (double lxmin, double lxmax, const char32 *s) { try { autoPolynomial me = Thing_new (Polynomial); FunctionTerms_initFromString (me.peek(), lxmin, lxmax, s, 0); return me.transfer(); } catch (MelderError) { Melder_throw (U"Polynomial not created from string."); } } void Polynomial_scaleCoefficients_monic (Polynomial me) { double cn = my coefficients[my numberOfCoefficients]; if (cn == 1 || my numberOfCoefficients <= 1) { return; } for (long i = 1; i < my numberOfCoefficients; i++) { my coefficients[i] /= cn; } my coefficients[my numberOfCoefficients] = 1; } /* Transform the polynomial as if the domain were [xmin, xmax]. Some polynomials (Legendre) are defined on the domain [-1,1]. The domain for x may be extended to [xmin, xmax] by a transformation such as x' = (2 * x - (xmin + xmax)) / (xmax - xmin) -1 < x' < x. This procedure transforms x' back to x. */ Polynomial Polynomial_scaleX (Polynomial me, double xmin, double xmax) { try { Melder_assert (xmin < xmax); autoPolynomial thee = Polynomial_create (xmin, xmax, my numberOfCoefficients - 1); thy coefficients[1] = my coefficients[1]; if (my numberOfCoefficients == 1) { return thee.transfer(); } // x = a x + b // Constraints: // my xmin = a xmin + b; a = (my xmin - my xmax) / (xmin - xmax); // my xmax = a xmax + b; b = my xmin - a * xmin double a = (my xmin - my xmax) / (xmin - xmax); double b = my xmin - a * xmin; thy coefficients[2] = my coefficients[2] * a; thy coefficients[1] += my coefficients[2] * b; if (my numberOfCoefficients == 2) { return thee.transfer(); } autoNUMvector buf (1, 3 * my numberOfCoefficients); double *pn = buf.peek(); double *pnm1 = pn + my numberOfCoefficients; double *pnm2 = pnm1 + my numberOfCoefficients; // Start the recursion: P[1] = a x + b; P[0] = 1; pnm1[2] = a; pnm1[1] = b; pnm2[1] = 1; for (long n = 2; n <= my numberOfCoefficients - 1; n++) { double *t1 = pnm1, *t2 = pnm2; NUMpolynomial_recurrence (pn, n, a, b, 0, pnm1, pnm2); if (my coefficients[n + 1] != 0) { for (long j = 1; j <= n + 1; j++) { thy coefficients[j] += my coefficients[n + 1] * pn[j]; } } pnm1 = pn; pnm2 = t1; pn = t2; } return thee.transfer(); } catch (MelderError) { Melder_throw (U""); } } double Polynomial_evaluate (I, double x) { iam (Polynomial); return my v_evaluate (x); } void Polynomial_evaluate_z (Polynomial me, dcomplex *z, dcomplex *p) { my v_evaluate_z (z, p); } static void Polynomial_evaluate_z_cart (Polynomial me, double r, double phi, double *re, double *im) { double rn = 1; *re = my coefficients[1]; *im = 0; if (r == 0) { return; } for (long i = 2; i <= my numberOfCoefficients; i++) { rn *= r; double arg = (i - 1) * phi; *re += my coefficients[i] * rn * cos (arg); *im += my coefficients[i] * rn * sin (arg); } } Polynomial Polynomial_getDerivative (Polynomial me) { try { if (my numberOfCoefficients == 1) { return Polynomial_create (my xmin, my xmax, 0); } autoPolynomial thee = Polynomial_create (my xmin, my xmax, my numberOfCoefficients - 2); for (long i = 1; i <= thy numberOfCoefficients; i++) { thy coefficients[i] = i * my coefficients[i + 1]; } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no derivative created."); } } Polynomial Polynomial_getPrimitive (Polynomial me) { try { autoPolynomial thee = Polynomial_create (my xmin, my xmax, my numberOfCoefficients); for (long i = 1; i <= my numberOfCoefficients; i++) { thy coefficients[i + 1] = my coefficients[i] / i; } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no primitive created."); } } double Polynomial_getArea (Polynomial me, double xmin, double xmax) { if (xmax >= xmin) { xmin = my xmin; xmax = my xmax; } autoPolynomial p = Polynomial_getPrimitive (me); double area = FunctionTerms_evaluate (p.peek(), xmax) - FunctionTerms_evaluate (p.peek(), xmin); return area; } Polynomial Polynomials_multiply (Polynomial me, Polynomial thee) { try { long n1 = my numberOfCoefficients, n2 = thy numberOfCoefficients; if (my xmax <= thy xmin || my xmin >= thy xmax) { Melder_throw (U"Domains do not overlap."); } double xmin = my xmin > thy xmin ? my xmin : thy xmin; double xmax = my xmax < thy xmax ? my xmax : thy xmax; autoPolynomial him = Polynomial_create (xmin, xmax, n1 + n2 - 2); for (long i = 1; i <= n1; i++) { for (long j = 1; j <= n2; j++) { long k = i + j - 1; his coefficients [k] += my coefficients[i] * thy coefficients[j]; } } return him.transfer(); } catch (MelderError) { Melder_throw (U"Polynomials not multiplied."); } } void Polynomials_divide (Polynomial me, Polynomial thee, Polynomial *q, Polynomial *r) { long degree, m = my numberOfCoefficients, n = thy numberOfCoefficients; if (*q == 0 && *r == 0) { return; } autoNUMvector qc (1, m); autoNUMvector rc (1, m); autoPolynomial aq = 0, ar = 0; polynomial_divide (my coefficients, m, thy coefficients, n, qc.peek(), rc.peek()); if (*q) { degree = MAX (m - n, 0); aq.reset (Polynomial_create (my xmin, my xmax, degree)); if (degree >= 0) { NUMvector_copyElements (qc.peek(), aq -> coefficients, 1, degree + 1); } } if (*r) { degree = n - 2; if (m >= n) { degree --; } if (degree < 0) { degree = 0; } while (degree > 1 && rc[degree] == 0) { degree--; } ar.reset (Polynomial_create (my xmin, my xmax, degree)); NUMvector_copyElements (rc.peek(), ar -> coefficients, 1, degree + 1); } *q = aq.transfer(); *r = ar.transfer(); } /******** LegendreSeries ********************************************/ Thing_implement (LegendreSeries, FunctionTerms, 0); double structLegendreSeries :: v_evaluate (double x) { double p = coefficients[1]; // Transform x from domain [xmin, xmax] to domain [-1, 1] if (x < xmin || x > xmax) { return NUMundefined; } double pim1 = x = (2 * x - xmin - xmax) / (xmax - xmin); if (numberOfCoefficients > 1) { double pim2 = 1, twox = 2 * x, f2 = x, d = 1.0; p += coefficients[2] * pim1; for (long i = 3; i <= numberOfCoefficients; i++) { double f1 = d++; f2 += twox; double pi = (f2 * pim1 - f1 * pim2) / d; p += coefficients[i] * pi; pim2 = pim1; pim1 = pi; } } return p; } void structLegendreSeries :: v_evaluateTerms (double x, double terms[]) { if (x < xmin || x > xmax) { for (long i = 1; i <= numberOfCoefficients; i++) { terms[i] = NUMundefined; } return; } // Transform x from domain [xmin, xmax] to domain [-1, 1] x = (2 * x - xmin - xmax) / (xmax - xmin); terms[1] = 1; if (numberOfCoefficients > 1) { double twox = 2 * x, f2 = x, d = 1.0; terms[2] = x; for (long i = 3; i <= numberOfCoefficients; i++) { double f1 = d++; f2 += twox; terms[i] = (f2 * terms[i - 1] - f1 * terms[i - 2]) / d; } } } void structLegendreSeries :: v_getExtrema (double x1, double x2, double *lxmin, double *ymin, double *lxmax, double *ymax) { try { autoPolynomial p = LegendreSeries_to_Polynomial (this); FunctionTerms_getExtrema (p.peek(), x1, x2, lxmin, ymin, lxmax, ymax); } catch (MelderError) { structFunctionTerms :: v_getExtrema (x1, x2, lxmin, ymin, lxmax, ymax); Melder_clearError (); } } LegendreSeries LegendreSeries_create (double xmin, double xmax, long numberOfPolynomials) { try { autoLegendreSeries me = Thing_new (LegendreSeries); FunctionTerms_init (me.peek(), xmin, xmax, numberOfPolynomials); return me.transfer(); } catch (MelderError) { Melder_throw (U"LegendreSeries not created."); } } LegendreSeries LegendreSeries_createFromString (double xmin, double xmax, const char32 *s) { try { autoLegendreSeries me = Thing_new (LegendreSeries); FunctionTerms_initFromString (me.peek(), xmin, xmax, s, 0); return me.transfer(); } catch (MelderError) { Melder_throw (U"LegendreSeries not created from string."); } } LegendreSeries LegendreSeries_getDerivative (LegendreSeries me) { try { autoLegendreSeries thee = LegendreSeries_create (my xmin, my xmax, my numberOfCoefficients - 1); for (long n = 1; n <= my numberOfCoefficients - 1; n++) { // P[n]'(x) = Sum (k=0..nonNegative, (2n - 4k - 1) P[n-2k-1](x)) long n2 = n - 1; for (long k = 0; n2 >= 0; k++, n2 -= 2) { thy coefficients [n2 + 1] += (2 * n - 4 * k - 1) * my coefficients[n + 1]; } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no derivative created."); } } Polynomial LegendreSeries_to_Polynomial (LegendreSeries me) { try { double xmin = -1, xmax = 1; autoPolynomial thee = Polynomial_create (xmin, xmax, my numberOfCoefficients - 1); thy coefficients[1] = my coefficients[1]; /* * p[1] */ if (my numberOfCoefficients == 1) { return thee.transfer(); } thy coefficients[2] = my coefficients[2]; /* * p[2] */ if (my numberOfCoefficients > 2) { autoNUMvector buf (1, 3 * my numberOfCoefficients); double *pn = buf.peek(); double *pnm1 = pn + my numberOfCoefficients; double *pnm2 = pnm1 + my numberOfCoefficients; // Start the recursion: P[1] = x; P[0] = 1; pnm1[2] = 1; pnm2[1] = 1; for (long n = 2; n <= my numberOfCoefficients - 1; n++) { double a = (2 * n - 1.0) / n; double c = - (n - 1.0) / n; double *t1 = pnm1, *t2 = pnm2; NUMpolynomial_recurrence (pn, n, a, 0, c, pnm1, pnm2); if (my coefficients[n + 1] != 0) { for (long j = 1; j <= n + 1; j++) { thy coefficients[j] += my coefficients[n + 1] * pn[j]; } } pnm1 = pn; pnm2 = t1; pn = t2; } } if (my xmin != xmin || my xmax != xmax) { thee.reset (Polynomial_scaleX (thee.peek(), my xmin, my xmax)); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not converted to Polynomial."); } } /********* Roots ****************************************************/ Thing_implement (Roots, ComplexVector, 0); Roots Roots_create (long numberOfRoots) { try { autoRoots me = Thing_new (Roots); ComplexVector_init (me.peek(), 1, numberOfRoots); return me.transfer(); } catch (MelderError) { Melder_throw (U"Roots not created."); } } void Roots_fixIntoUnitCircle (Roots me) { dcomplex z10 = dcomplex_create (1, 0); for (long i = my min; i <= my max; i++) { if (dcomplex_abs (my v[i]) > 1.0) { my v[i] = dcomplex_div (z10, dcomplex_conjugate (my v[i])); } } } static void NUMdcvector_extrema_re (dcomplex v[], long lo, long hi, double *min, double *max) { *min = *max = v[lo].re; for (long i = lo + 1; i <= hi; i++) { if (v[i].re < *min) { *min = v[i].re; } else if (v[i].re > *max) { *max = v[i].re; } } } static void NUMdcvector_extrema_im (dcomplex v[], long lo, long hi, double *min, double *max) { *min = *max = v[lo].im; for (long i = lo + 1; i <= hi; i++) { if (v[i].im < *min) { *min = v[i].im; } else if (v[i].im > *max) { *max = v[i].im; } } } void Roots_draw (Roots me, Graphics g, double rmin, double rmax, double imin, double imax, const char32 *symbol, int fontSize, int garnish) { int oldFontSize = Graphics_inqFontSize (g); double eps = 1e-6; if (rmax <= rmin) { NUMdcvector_extrema_re (my v, 1, my max, &rmin, &rmax); } double denum = fabs (rmax) > fabs (rmin) ? fabs (rmax) : fabs (rmin); if (denum == 0) { denum = 1; } if (fabs ( (rmax - rmin) / denum) < eps) { rmin -= 1; rmax += 1; } if (imax <= imin) { NUMdcvector_extrema_im (my v, 1, my max, &imin, &imax); } denum = fabs (imax) > fabs (imin) ? fabs (imax) : fabs (imin); if (denum == 0) { denum = 1; } if (fabs ( (imax - imin) / denum) < eps) { imin -= 1; imax += 1; } Graphics_setInner (g); Graphics_setWindow (g, rmin, rmax, imin, imax); Graphics_setFontSize (g, fontSize); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); for (long i = 1; i <= my max; i++) { double re = my v[i].re, im = my v[i].im; if (re >= rmin && re <= rmax && im >= imin && im <= imax) { Graphics_text (g, re, im, symbol); } } Graphics_setFontSize (g, oldFontSize); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); if (rmin * rmax < 0) { Graphics_markLeft (g, 0.0, true, true, true, U"0"); } if (imin * imax < 0) { Graphics_markBottom (g, 0.0, true, true, true, U"0"); } Graphics_marksLeft (g, 2, true, true, false); Graphics_textLeft (g, true, U"Imaginary part"); Graphics_marksBottom (g, 2, true, true, false); Graphics_textBottom (g, true, U"Real part"); } } Roots Polynomial_to_Roots (Polynomial me) { try { long np1 = my numberOfCoefficients, n = np1 - 1, n2 = n * n; if (n < 1) { Melder_throw (U"Cannot find roots of a constant function."); } // Allocate storage for Hessenberg matrix (n * n) plus real and imaginary // parts of eigenvalues wr[1..n] and wi[1..n]. autoNUMvector hes (1, n2 + n + n); double *wr = &hes[n2]; double *wi = &hes[n2 + n]; // Fill the upper Hessenberg matrix (storage is Fortran) // C: [i][j] -> Fortran: (j-1)*n + i for (long i = 1; i <= n; i++) { hes[ (i - 1) *n + 1] = - (my coefficients[np1 - i] / my coefficients[np1]); if (i < n) { hes[ (i - 1) *n + 1 + i] = 1; } } // Find out the working storage needed char job = 'E', compz = 'N'; long ilo = 1, ihi = n, ldh = n, ldz = n, lwork = -1, info; double *z = 0, wt[1]; NUMlapack_dhseqr (&job, &compz, &n, &ilo, &ihi, &hes[1], &ldh, &wr[1], &wi[1], z, &ldz, wt, &lwork, &info); if (info != 0) { if (info < 0) { Melder_throw (U"Programming error. Argument ", info, U" in NUMlapack_dhseqr has illegal value."); } } lwork = (long) floor (wt[0]); autoNUMvector work (1, lwork); // Find eigenvalues. NUMlapack_dhseqr (&job, &compz, &n, &ilo, &ihi, &hes[1], &ldh, &wr[1], &wi[1], z, &ldz, &work[1], &lwork, &info); long nrootsfound = n; long ioffset = 0; if (info > 0) { // if INFO = i, NUMlapack_dhseqr failed to compute all of the eigenvalues. Elements i+1:n of // WR and WI contain those eigenvalues which have been successfully computed nrootsfound -= info; if (nrootsfound < 1) { Melder_throw (U"No roots found."); } Melder_warning (U"Calculated only ", nrootsfound, U" roots."); ioffset = info; } else if (info < 0) { Melder_throw (U"Programming error. Argument ", info, U" in NUMlapack_dhseqr has illegal value."); } autoRoots thee = Roots_create (nrootsfound); for (long i = 1; i <= nrootsfound; i++) { (thy v[i]).re = wr[ioffset + i]; (thy v[i]).im = wi[ioffset + i]; } Roots_and_Polynomial_polish (thee.peek(), me); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no roots can be calculated."); } } void Roots_sort (Roots me) { (void) me; } /* Precondition: complex roots occur in pairs (a,bi), (a,-bi) with b>0 */ void Roots_and_Polynomial_polish (Roots me, Polynomial thee) { long i = my min, maxit = 80; while (i <= my max) { double im = my v[i].im, re = my v[i].re; if (im != 0) { Polynomial_polish_complexroot_nr (thee, & my v[i], maxit); if (i < my max && im == -my v[i + 1].im && re == my v[i + 1].re) { my v[i + 1].re = my v[i].re; my v[i + 1].im = -my v[i].im; i++; } } else { Polynomial_polish_realroot (thee, & (my v[i].re), maxit); } i++; } } Polynomial Roots_to_Polynomial (Roots me) { try { (void) me; throw MelderError(); } catch (MelderError) { Melder_throw (U"Not implemented yet"); } } void Roots_setRoot (Roots me, long index, double re, double im) { if (index < my min || index > my max) { Melder_throw (U"Index must be in interval [1, ", my max, U"]."); } my v[index].re = re; my v[index].im = im; } dcomplex Roots_evaluate_z (Roots me, dcomplex z) { dcomplex result = {1, 0}; for (long i = my min; i <= my max; i++) { dcomplex t = dcomplex_sub (z, my v[i]); result = dcomplex_mul (result, t); } return result; } Spectrum Roots_to_Spectrum (Roots me, double nyquistFrequency, long numberOfFrequencies, double radius) { try { if (numberOfFrequencies < 2) { Melder_throw (U"NumberOfFrequencies must be greater or equal 2."); } autoSpectrum thee = Spectrum_create (nyquistFrequency, numberOfFrequencies); double phi = NUMpi / (numberOfFrequencies - 1); dcomplex z; for (long i = 1; i <= numberOfFrequencies; i++) { z.re = radius * cos ( (i - 1) * phi); z.im = radius * sin ( (i - 1) * phi); dcomplex s = Roots_evaluate_z (me, z); thy z[1][i] = s.re; thy z[2][i] = s.im; } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no Spectrum calculated."); } } long Roots_getNumberOfRoots (Roots me) { return my max; } dcomplex Roots_getRoot (Roots me, long index) { if (index < 1 || index > my max) { Melder_throw (U"Root index out of range."); } return my v [index]; } /* Can be speeded up by doing a FFT */ Spectrum Polynomial_to_Spectrum (Polynomial me, double nyquistFrequency, long numberOfFrequencies, double radius) { try { if (numberOfFrequencies < 2) { Melder_throw (U"NumberOfFrequencies must be greater or equal 2."); } autoSpectrum thee = Spectrum_create (nyquistFrequency, numberOfFrequencies); double phi = NUMpi / (numberOfFrequencies - 1); for (long i = 1; i <= numberOfFrequencies; i++) { double re, im; Polynomial_evaluate_z_cart (me, radius, (i - 1) * phi, &re, &im); thy z[1][i] = re; thy z[2][i] = im; } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no Spectrum calculated."); } } /****** ChebyshevSeries ******************************************/ Thing_implement (ChebyshevSeries, FunctionTerms, 0); /* p(x) = sum (k=1..numberOfCoefficients, c[k]*T[k](x')) - c[1] / 2; Numerical evaluation via Clenshaw's recurrence equation (NRC: 5.8.11) d[m+1] = d[m] = 0; d[j] = 2 x' d[j+1] - d[j+2] + c[j]; p(x) = d[0] = x' d[1] - d[2] + c[0] / 2; x' = (2 * x - xmin - xmax) / (xmax - xmin) */ double structChebyshevSeries :: v_evaluate (double x) { if (x < xmin || x > xmax) { return NUMundefined; } double d1 = 0, d2 = 0; if (numberOfCoefficients > 1) { // Transform x from domain [xmin, xmax] to domain [-1, 1] x = (2 * x - xmin - xmax) / (xmax - xmin); double x2 = 2 * x; for (long i = numberOfCoefficients; i > 1; i--) { double tmp = d1; d1 = x2 * d1 - d2 + coefficients[i]; d2 = tmp; } } return x * d1 - d2 + coefficients[1]; } /* T[n](x) = 2*x*T[n-1] - T[n-2](x) n >= 2 */ void structChebyshevSeries :: v_evaluateTerms (double x, double *terms) { if (x < xmin || x > xmax) { for (long i = 1; i <= numberOfCoefficients; i++) { terms[i] = NUMundefined; } return; } terms[1] = 1; if (numberOfCoefficients > 1) { // Transform x from domain [xmin, xmax] to domain [-1, 1] terms[2] = x = (2 * x - xmin - xmax) / (xmax - xmin); for (long i = 3; i <= numberOfCoefficients; i++) { terms[i] = 2 * x * terms[i - 1] - terms[i - 2]; } } } void structChebyshevSeries :: v_getExtrema (double x1, double x2, double *lxmin, double *ymin, double *lxmax, double *ymax) { try { autoPolynomial p = ChebyshevSeries_to_Polynomial (this); FunctionTerms_getExtrema (p.peek(), x1, x2, lxmin, ymin, lxmax, ymax); } catch (MelderError) { Melder_throw (this, U"Extrema cannot be calculated"); } } ChebyshevSeries ChebyshevSeries_create (double lxmin, double lxmax, long numberOfPolynomials) { try { autoChebyshevSeries me = Thing_new (ChebyshevSeries); FunctionTerms_init (me.peek(), lxmin, lxmax, numberOfPolynomials); return me.transfer(); } catch (MelderError) { Melder_throw (U"ChebyshevSeries not created."); } } ChebyshevSeries ChebyshevSeries_createFromString (double lxmin, double lxmax, const char32 *s) { try { autoChebyshevSeries me = Thing_new (ChebyshevSeries); FunctionTerms_initFromString (me.peek(), lxmin, lxmax, s, 0); return me.transfer(); } catch (MelderError) { Melder_throw (U"ChebyshevSeries not created from string."); }; } Polynomial ChebyshevSeries_to_Polynomial (ChebyshevSeries me) { try { double xmin = -1, xmax = 1; autoPolynomial thee = Polynomial_create (xmin, xmax, my numberOfCoefficients - 1); thy coefficients[1] = my coefficients[1] /* * p[1] */; if (my numberOfCoefficients == 1) { return thee.transfer(); } thy coefficients[2] = my coefficients[2]; if (my numberOfCoefficients > 2) { autoNUMvector buf (1, 3 * my numberOfCoefficients); double *pn = buf.peek(); double *pnm1 = pn + my numberOfCoefficients; double *pnm2 = pnm1 + my numberOfCoefficients; // Start the recursion: T[1] = x; T[0] = 1; pnm1[2] = 1; pnm2[1] = 1; double a = 2, b = 0, c = -1; for (long n = 2; n <= my numberOfCoefficients - 1; n++) { double *t1 = pnm1, *t2 = pnm2; NUMpolynomial_recurrence (pn, n, a, b, c, pnm1, pnm2); if (my coefficients[n + 1] != 0) { for (long j = 1; j <= n + 1; j++) { thy coefficients[j] += my coefficients[n + 1] * pn[j]; } } pnm1 = pn; pnm2 = t1; pn = t2; } } if (my xmin != xmin || my xmax != xmax) { thee.reset (Polynomial_scaleX (thee.peek(), my xmin, my xmax)); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U"; not converted to Polynomial."); }; } void FunctionTerms_and_RealTier_fit (I, thou, int *freeze, double tol, int ic, Covariance *c) { iam (FunctionTerms); thouart (RealTier); try { long numberOfData = thy points -> size; long numberOfParameters = my numberOfCoefficients; long numberOfFreeParameters = numberOfParameters; if (numberOfData < 2) { Melder_throw (U"Not enough data points."); } autoFunctionTerms frozen = Data_copy (me); autoNUMvector terms (1, my numberOfCoefficients); autoNUMvector p (1, numberOfParameters); autoNUMvector y_residual (1, numberOfData); autoCovariance ac = 0; if (ic) { ac.reset (Covariance_create (numberOfParameters)); } long k = 1; for (long j = 1; j <= my numberOfCoefficients; j++) { if (freeze && freeze[j]) { numberOfFreeParameters--; } else { p[k] = my coefficients[j]; k++; frozen -> coefficients[j] = 0; } } if (numberOfFreeParameters == 0) { Melder_throw (U"No free parameters left."); } autoSVD svd = SVD_create (numberOfData, numberOfFreeParameters); double sigma = RealTier_getStandardDeviation_points (thee, my xmin, my xmax); if (sigma == NUMundefined) { Melder_throw (U"Not enough data points in fit interval."); } for (long i = 1; i <= numberOfData; i++) { // Only 'residual variance' must be explained by the model // Evaluate only with the frozen parameters RealPoint point = (RealPoint) thy points -> item [i]; double x = point -> number, y = point -> value, **u = svd -> u; double y_frozen = numberOfFreeParameters == numberOfParameters ? 0 : FunctionTerms_evaluate (frozen.peek(), x); y_residual[i] = (y - y_frozen) / sigma; // Data matrix FunctionTerms_evaluateTerms (me, x, terms.peek()); k = 0; for (long j = 1; j <= my numberOfCoefficients; j++) { if (! freeze || ! freeze[j]) { k++; u[i][k] = terms[j] / sigma; } } } // SVD and evaluation of the singular values if (tol > 0) { SVD_setTolerance (svd.peek(), tol); } SVD_compute (svd.peek()); SVD_solve (svd.peek(), y_residual.peek(), p.peek()); // Put fitted values at correct position k = 1; for (long j = 1; j <= my numberOfCoefficients; j++) { if (! freeze || ! freeze[j]) { my coefficients[j] = p[k++]; } } if (ic) { svdcvm (svd -> v, numberOfFreeParameters, numberOfParameters, freeze, svd -> d, ac -> data); } *c = ac.transfer(); } catch (MelderError) { Melder_throw (me, U" & ", thee, U": no fit."); } } Polynomial RealTier_to_Polynomial (I, long degree, double tol, int ic, Covariance *cvm) { iam (RealTier); try { autoPolynomial thee = Polynomial_create (my xmin, my xmax, degree); FunctionTerms_and_RealTier_fit (thee.peek(), me, 0, tol, ic, cvm); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no Polynomial fitted."); } } LegendreSeries RealTier_to_LegendreSeries (I, long degree, double tol, int ic, Covariance *cvm) { iam (RealTier); try { autoLegendreSeries thee = LegendreSeries_create (my xmin, my xmax, degree); FunctionTerms_and_RealTier_fit (thee.peek(), me, 0, tol, ic, cvm); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no LegendreSeries fitted."); } } ChebyshevSeries RealTier_to_ChebyshevSeries (I, long degree, double tol, int ic, Covariance *cvm) { iam (RealTier); try { autoChebyshevSeries thee = ChebyshevSeries_create (my xmin, my xmax, degree); FunctionTerms_and_RealTier_fit (thee.peek(), me, 0, tol, ic, cvm); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U":no ChebyshevSeries fitted."); }; } /******* Splines *************************************************/ /* Functions for calculating an mspline and an ispline. These functions should replace the functions in NUM2.c. Before we can do that we first have to adapt the spline- dependencies in MDS.c. Formally nKnots == order + numberOfInteriorKnots + order. We forget about the multiple knots at start and end. Our point-sequece xmin < interiorKont[1] < ... < interiorKnot[n] < xmax. nKnots is now numberOfinteriorKnots + 2. */ static double NUMmspline2 (double points[], long numberOfPoints, long order, long index, double x) { long numberOfSplines = numberOfPoints + order - 2; double m[Spline_MAXIMUM_DEGREE + 2]; Melder_assert (numberOfPoints > 2 && order > 0 && index > 0); if (index > numberOfSplines) { return NUMundefined; } /* Find the range/interval where x is located. M-splines of order k have degree k-1. M-splines are zero outside interval [ knot[i], knot[i+order] ). First and last 'order' knots are equal, i.e., knot[1] = ... = knot[order] && knot[nKnots-order+1] = ... knot[nKnots]. */ long index_b = index - order + 1; index_b = MAX (index_b, 1); if (x < points[index_b]) { return 0; } long index_e = index_b + MIN (index, order); index_e = MIN (numberOfPoints, index_e); if (x > points[index_e]) { return 0; } // Calculate M[i](x|1,t) according to eq.2. for (long k = 1; k <= order; k++) { long k1 = index - order + k, k2 = k1 + 1; m[k] = 0; if (k1 > 0 && k2 <= numberOfPoints && x >= points[k1] && x < points[k2]) { m[k] = 1 / (points[k2] - points[k1]); } } // Iterate to get M[i](x|k,t) for (long k = 2; k <= order; k++) { for (long j = 1; j <= order - k + 1; j++) { long k1 = index - order + j, k2 = k1 + k; if (k2 > 1 && k1 < 1) { k1 = 1; } else if (k2 > numberOfPoints && k1 < numberOfPoints) { k2 = numberOfPoints; } if (k1 > 0 && k2 <= numberOfPoints) { double p1 = points[k1], p2 = points[k2]; m[j] = k * ( (x - p1) * m[j] + (p2 - x) * m[j + 1]) / ( (k - 1) * (p2 - p1)); } } } return m[1]; } static double NUMispline2 (double points[], long numberOfPoints, long order, long index, double x) { Melder_assert (numberOfPoints > 2 && order > 0 && index > 0); long index_b = index - order + 1; index_b = MAX (index_b, 1); if (x < points[index_b]) { return 0; } long index_e = index_b + MIN (index, order); index_e = MIN (numberOfPoints, index_e); if (x > points[index_e]) { return 1; } long j; for (j = index_e - 1; j >= index_b; j--) { if (x > points[j]) { break; } } // Equation 5 in Ramsay's article contains some errors!!! // 1. the interval selection must be 'j-k <= i <= j' instead of // 'j-k+1 <= i <= j' // 2. the summation index m starts at 'i+1' instead of 'i' double y = 0; for (long m = index + 1; m <= j + order; m++) { long km = m - order, kmp = km + order + 1; km = MAX (km, 1); kmp = MIN (kmp, numberOfPoints); y += (points[kmp] - points[km]) * NUMmspline2 (points, numberOfPoints, order + 1, m, x); } return y /= (order + 1); } Thing_implement (Spline, FunctionTerms, 0); double structSpline :: v_evaluate (double x) { (void) x; return 0; } long structSpline :: v_getDegree () { return degree; } long structSpline :: v_getOrder () { return degree + 1; } /* Precondition: FunctionTerms part inited + degree */ static void Spline_initKnotsFromString (I, long degree, const char32 *interiorKnots) { iam (Spline); if (degree > Spline_MAXIMUM_DEGREE) { Melder_throw (U"Degree must be <= 20."); } long numberOfInteriorKnots; autoNUMvector numbers (NUMstring_to_numbers (interiorKnots, &numberOfInteriorKnots), 1); if (numberOfInteriorKnots > 0) { NUMsort_d (numberOfInteriorKnots, numbers.peek()); if (numbers[1] <= my xmin || numbers[numberOfInteriorKnots] > my xmax) { Melder_throw (U"Knots must be inside domain."); } } my degree = degree; long order = Spline_getOrder (me); /* depends on spline type !! */ long n = numberOfInteriorKnots + order; if (my numberOfCoefficients != n) { Melder_throw (U"NumberOfCoefficients must equal ", n, U"."); } my numberOfKnots = numberOfInteriorKnots + 2; my knots = NUMvector (1, my numberOfKnots); for (long i = 1; i <= numberOfInteriorKnots; i++) { my knots[i + 1] = numbers[i]; } my knots[1] = my xmin; my knots[my numberOfKnots] = my xmax; } void Spline_init (I, double xmin, double xmax, long degree, long numberOfCoefficients, long numberOfKnots) { iam (Spline); if (degree > Spline_MAXIMUM_DEGREE) { Melder_throw (U"Spline_init: degree must be <= 20."); } FunctionTerms_init (me, xmin, xmax, numberOfCoefficients); my knots = NUMvector (1, numberOfKnots); my degree = degree; my numberOfKnots = numberOfKnots; my knots[1] = xmin; my knots[numberOfKnots] = xmax; } void Spline_drawKnots (I, Graphics g, double xmin, double xmax, double ymin, double ymax, int garnish) { iam (Spline); long order = Spline_getOrder (me); if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (xmax < my xmin || xmin > my xmax) { return; } if (ymax <= ymin) { double x1, x2; FunctionTerms_getExtrema (me, xmin, xmax, &x1, &ymin, &x2, &ymax); } Graphics_setWindow (g, xmin, xmax, ymin, ymax); if (my knots[1] >= xmin && my knots[1] <= xmax) { Graphics_markTop (g, my knots[1], false, true, true, ! garnish ? U"" : order == 1 ? U"t__1_" : order == 2 ? U"{t__1_, t__2_}" : Melder_cat (U"{t__1_..t__", order, U"_}") ); } for (long i = 2; i <= my numberOfKnots - 1; i++) { if (my knots[i] >= xmin && my knots[i] <= xmax) { Graphics_markTop (g, my knots[i], false, true, true, ! garnish ? U"" : Melder_cat (U"t__", i + order - 1, U"_") ); } } if (my knots[my numberOfKnots] >= xmin && my knots[my numberOfKnots] <= xmax) { long numberOfKnots = ! garnish ? 0 : my numberOfKnots + 2 * (order - 1); Graphics_markTop (g, my knots[my numberOfKnots], false, true, true, ! garnish ? U"" : order == 1 ? Melder_cat (U"t__", numberOfKnots, U"_") : order == 2 ? Melder_cat (U"{t__", numberOfKnots - 1, U"_, t__", numberOfKnots, U"_}") : Melder_cat (U"{t__", numberOfKnots - order + 1, U"_..t__", numberOfKnots, U"_}") ); } } long Spline_getOrder (I) { iam (Spline); return my v_getOrder (); } Spline Spline_scaleX (I, double xmin, double xmax) { try { iam (Spline); Melder_assert (xmin < xmax); autoSpline thee = Data_copy (me); thy xmin = xmin; thy xmax = xmax; // x = a x + b // Constraints: // my xmin = a xmin + b; a = (my xmin - my xmax) / (xmin - xmax); // my xmax = a xmax + b; b = my xmin - a * xmin double a = (xmin - xmax) / (my xmin - my xmax); double b = xmin - a * my xmin; for (long i = 1; i <= my numberOfKnots; i++) { thy knots[i] = a * my knots[i] + b; } return thee.transfer(); } catch (MelderError) { Melder_throw (U"Scaled Spline not created."); } } /********* MSplines ************************************************/ double structMSpline :: v_evaluate (double x) { if (x < xmin || x > xmax) { return 0; } double result = 0; for (long i = 1; i <= numberOfCoefficients; i++) { if (coefficients[i] != 0) result += coefficients[i] * NUMmspline2 (knots, numberOfKnots, degree + 1, i, x); } return result; } void structMSpline :: v_evaluateTerms (double x, double *terms) { if (x < xmin || x > xmax) { return; } for (long i = 1; i <= numberOfCoefficients; i++) { terms[i] = NUMmspline2 (knots, numberOfKnots, degree + 1, i, x); } } Thing_implement (MSpline, Spline, 0); MSpline MSpline_create (double xmin, double xmax, long degree, long numberOfInteriorKnots) { try { autoMSpline me = Thing_new (MSpline); long numberOfCoefficients = numberOfInteriorKnots + degree + 1; long numberOfKnots = numberOfCoefficients + degree + 1; Spline_init (me.peek(), xmin, xmax, degree, numberOfCoefficients, numberOfKnots); return me.transfer(); } catch (MelderError) { Melder_throw (U"MSpline not created."); } } MSpline MSpline_createFromStrings (double xmin, double xmax, long degree, const char32 *coef, const char32 *interiorKnots) { try { if (degree > Spline_MAXIMUM_DEGREE) { Melder_throw (U"Degree should be <= 20."); } autoMSpline me = Thing_new (MSpline); FunctionTerms_initFromString (me.peek(), xmin, xmax, coef, 1); Spline_initKnotsFromString (me.peek(), degree, interiorKnots); return me.transfer(); } catch (MelderError) { Melder_throw (U"MSpline not created from strings."); } } /******** ISplines ************************************************/ double structISpline :: v_evaluate (double x) { if (x < xmin || x > xmax) { return 0; } double result = 0; for (long i = 1; i <= numberOfCoefficients; i++) { if (coefficients[i] != 0) result += coefficients[i] * NUMispline2 (knots, numberOfKnots, degree, i, x); } return result; } void structISpline :: v_evaluateTerms (double x, double *terms) { for (long i = 1; i <= numberOfCoefficients; i++) { terms[i] = NUMispline2 (knots, numberOfKnots, degree, i, x); } } long structISpline :: v_getOrder () { return degree; } Thing_implement (ISpline, Spline, 0); ISpline ISpline_create (double xmin, double xmax, long degree, long numberOfInteriorKnots) { try { autoISpline me = Thing_new (ISpline); long numberOfCoefficients = numberOfInteriorKnots + degree; long numberOfKnots = numberOfCoefficients + degree; Spline_init (me.peek(), xmin, xmax, degree, numberOfCoefficients, numberOfKnots); return me.transfer(); } catch (MelderError) { Melder_throw (U"ISpline not created."); } } ISpline ISpline_createFromStrings (double xmin, double xmax, long degree, const char32 *coef, const char32 *interiorKnots) { try { if (degree > Spline_MAXIMUM_DEGREE) { Melder_throw (U"Degree should be <= 20."); } autoISpline me = Thing_new (ISpline); FunctionTerms_initFromString (me.peek(), xmin, xmax, coef, 1); Spline_initKnotsFromString (me.peek(), degree, interiorKnots); return me.transfer(); } catch (MelderError) { Melder_throw (U"ISpline not created from strings."); }; } /* #define RationalFunction_members Function_members \ Polynomial num, denum; #define RationalFunction_methods Function_methods class_create (RationalFunction, Function) RationalFunction RationalFunction_create (double xmin, double xmax, long degree_num, long degree_denum) { RationalFunction me = new (RationalFunction); if (! me || ! (my num = Polynomial_create (xmin, xmax, degree_num)) || ! (my denum = Polynomial_create (xmin, xmax, degree_denum))) forget (me); return me; } RationalFunction RationalFunction_createFromString (I, double xmin, double xmax, char *num, char *denum) { RationalFunction me = new (RationalFunction); long i; if (! (my num = Polynomial_createFromString (xmin, xmax, num)) || ! (my denum = Polynomial_createFromString (xmin, xmax, denum))) forget (me); if (my denum -> v[1] != 1 && my denum -> v[1] != 0) { double q0 = my denum -> v[1]; for (i=1; 1 <= my num ->numberOfCoefficients; i++) my num -> v[i] /= q0; for (i=1; 1 <= my denum ->numberOfCoefficients; i++) my denum -> v[i] /= q0; } return me; } // divide out common roots RationalFunction RationalFunction_simplify (RationalFunction me) { Roots num = nullptr, denum = nullptr; RationalFunction thee = nullptr; if (! (num = Polynomial_to_Roots (my num)) || ! (denum = Polynomial_to_Roots (my denum))) goto end; } */ #undef MAX #undef MIN /* end of file Polynomial.cpp */ praat-6.0.04/dwtools/Polynomial.h000066400000000000000000000210351261542461700167100ustar00rootroot00000000000000#ifndef _Polynomial_h_ #define _Polynomial_h_ /* Polynomial.h * * Copyright (C) 1993-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header djmw 20110306 Latest modification. */ #define FITTER_PARAMETER_FREE 0 #define FITTER_PARAMETER_FIXED 1 #include "SimpleVector.h" #include "Function.h" #include "TableOfReal.h" #include "Graphics.h" #include "Minimizers.h" #include "Spectrum.h" #include "RealTier.h" #include "SSCP.h" #define Spline_MAXIMUM_DEGREE 20 #include "Polynomial_def.h" oo_CLASS_CREATE (FunctionTerms, Function); void FunctionTerms_init (I, double xmin, double xmax, long numberOfCoefficients); void FunctionTerms_initFromString (I, double xmin, double xmax, const char32 *s, int allowTrailingZeros); FunctionTerms FunctionTerms_create (double xmin, double xmax, long numberOfCoefficients); void FunctionTerms_setDomain (I, double xmin, double xmax); void FunctionTerms_setCoefficient (I, long index, double value); double FunctionTerms_evaluate (I, double x); void FunctionTerms_evaluate_z (I, dcomplex *z, dcomplex *p); void FunctionTerms_evaluateTerms (I, double x, double terms[]); void FunctionTerms_getExtrema (I, double x1, double x2, double *xmin, double *ymin, double *xmax, double *ymax); long FunctionTerms_getDegree (I); double FunctionTerms_getMinimum (I, double x1, double x2); double FunctionTerms_getXOfMinimum (I, double x1, double x2); double FunctionTerms_getMaximum (I, double x1, double x2); double FunctionTerms_getXOfMaximum (I, double x1, double x2); /* Returns minimum and maximum function values (ymin, ymax) in interval [x1, x2] and their x-values (xmin, xmax). Precondition: [x1, x2] is a (sub)domain my xmin <= x1 < x2 <= my xmax */ void FunctionTerms_draw (I, Graphics g, double xmin, double xmax, double ymin, double ymax, int extrapolate, int garnish); /* Extrapolate only for functions whose domain is extendable and that can be extrapolated. Polynomials can be extrapolated. LegendreSeries and ChebyshevSeries cannot be extrapolated. */ void FunctionTerms_drawBasisFunction (I, Graphics g, long index, double xmin, double xmax, double ymin, double ymax, int extrapolate, int garnish); Thing_define (Polynomial, FunctionTerms) { // overridden methods: public: virtual double v_evaluate (double x); virtual void v_evaluate_z (dcomplex *z, dcomplex *p); virtual void v_evaluateTerms (double x, double terms[]); virtual void v_getExtrema (double x1, double x2, double *xmin, double *ymin, double *xmax, double *ymax); //virtual long v_getDegree (); David, is het OK dat deze niet overschreven wordt? Ja }; Polynomial Polynomial_create (double xmin, double xmax, long degree); Polynomial Polynomial_createFromString (double xmin, double xmax, const char32 *s); void Polynomial_scaleCoefficients_monic (Polynomial me); /* Make coefficent of leading term 1.0 */ Polynomial Polynomial_scaleX (Polynomial me, double xmin, double xmax); /* x' = (x-location) / scale */ void Polynomial_evaluate_z (Polynomial me, dcomplex *z, dcomplex *p); /* Evaluate at complex z = x + iy */ double Polynomial_getArea (Polynomial me, double xmin, double xmax); Polynomial Polynomial_getDerivative (Polynomial me); Polynomial Polynomial_getPrimitive (Polynomial me); void Polynomial_draw (I, Graphics g, double xmin, double xmax, double ymin, double ymax, int garnish); double Polynomial_evaluate (I, double x); void Polynomial_evaluateTerms (I, double x, double terms[]); Polynomial Polynomials_multiply (Polynomial me, Polynomial thee); void Polynomials_divide (Polynomial me, Polynomial thee, Polynomial *q, Polynomial *r); Thing_define (LegendreSeries, FunctionTerms) { // overridden methods: public: virtual double v_evaluate (double x); virtual void v_evaluateTerms (double x, double terms[]); virtual void v_getExtrema (double x1, double x2, double *xmin, double *ymin, double *xmax, double *ymax); }; LegendreSeries LegendreSeries_create (double xmin, double xmax, long numberOfPolynomials); LegendreSeries LegendreSeries_createFromString (double xmin, double xmax, const char32 *s); LegendreSeries LegendreSeries_getDerivative (LegendreSeries me); Polynomial LegendreSeries_to_Polynomial (LegendreSeries me); Thing_define (Roots, ComplexVector) { }; Roots Roots_create (long numberOfRoots); void Roots_fixIntoUnitCircle (Roots me); void Roots_sort (Roots me); /* Sort to size of real part a+bi, a-bi*/ dcomplex Roots_evaluate_z (Roots me, dcomplex z); Roots Polynomial_to_Roots_ev (Polynomial me); long Roots_getNumberOfRoots (Roots me); void Roots_draw (Roots me, Graphics g, double rmin, double rmax, double imin, double imax, const char32 *symbol, int fontSize, int garnish); dcomplex Roots_getRoot (Roots me, long index); void Roots_setRoot (Roots me, long index, double re, double im); Spectrum Roots_to_Spectrum (Roots me, double nyquistFrequency, long numberOfFrequencies, double radius); Roots Polynomial_to_Roots (Polynomial me); /* Find roots of polynomial and polish them */ void Roots_and_Polynomial_polish (Roots me, Polynomial thee); Polynomial Roots_to_Polynomial (Roots me); Polynomial TableOfReal_to_Polynomial (I, long degree, long xcol, long ycol, long scol); LegendreSeries TableOfReal_to_LegendreSeries (I, long numberOfPolynomials, long xcol, long ycol, long scol); Spectrum Polynomial_to_Spectrum (Polynomial me, double nyquistFrequency, long numberOfFrequencies, double radius); /* A ChebyshevSeries p(x) on a domain [xmin,xmax] is defined as the following linear combination of Chebyshev polynomials T[k](x') of degree k-1 and domain [-1, 1]: p(x) = sum (k=1..numberOfCoefficients, c[k]*T[k](x')) - c[1] / 2, where x' = (2 * x - xmin - xmax) / (xmax - xmin) This is equivalent to: p(x) = c[1] /2 + sum (k=2..numberOfCoefficients, c[k]*T[k](x')) */ Thing_define (ChebyshevSeries, FunctionTerms) { // overridden methods: public: virtual double v_evaluate (double x); virtual void v_evaluateTerms (double x, double terms[]); virtual void v_getExtrema (double x1, double x2, double *xmin, double *ymin, double *xmax, double *ymax); }; ChebyshevSeries ChebyshevSeries_create (double xmin, double xmax, long numberOfPolynomials); ChebyshevSeries ChebyshevSeries_createFromString (double xmin, double xmax, const char32 *s); Polynomial ChebyshevSeries_to_Polynomial (ChebyshevSeries me); oo_CLASS_CREATE (Spline, FunctionTerms); void Spline_init (I, double xmin, double xmax, long degree, long numberOfCoefficients, long numberOfKnots); long Spline_getOrder (I); void Spline_drawKnots (I, Graphics g, double xmin, double xmax, double ymin, double ymax, int garnish); Spline Spline_scaleX (I, double xmin, double xmax); /* scale domain and knots to new domain */ Thing_define (MSpline, Spline) { // overridden methods: public: virtual double v_evaluate (double x); virtual void v_evaluateTerms (double x, double terms[]); }; MSpline MSpline_create (double xmin, double xmax, long degree, long numberOfInteriorKnots); MSpline MSpline_createFromStrings (double xmin, double xmax, long degree, const char32 *coef, const char32 *interiorKnots); Thing_define (ISpline, Spline) { // overridden methods: public: virtual double v_evaluate (double x); virtual void v_evaluateTerms (double x, double terms[]); virtual long v_getOrder (); }; ISpline ISpline_create (double xmin, double xmax, long degree, long numberOfInteriorKnots); ISpline ISpline_createFromStrings (double xmin, double xmax, long degree, const char32 *coef, const char32 *interiorKnots); /****************** fit **********************************************/ void FunctionTerms_and_RealTier_fit (I, thou, int *freezeCoefficients, double tol, int ic, Covariance *c); Polynomial RealTier_to_Polynomial (I, long degree, double tol, int ic, Covariance *cvm); LegendreSeries RealTier_to_LegendreSeries (I, long degree, double tol, int ic, Covariance *cvm); ChebyshevSeries RealTier_to_ChebyshevSeries (I, long degree, double tol, int ic, Covariance *cvm); #endif /* _Polynomial_h_ */ praat-6.0.04/dwtools/Polynomial_def.h000066400000000000000000000033521261542461700175300ustar00rootroot00000000000000/* Polynomial_def.h * * Copyright (C) 1993-2002 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 1999 djmw 20020813 GPL header */ #define ooSTRUCT FunctionTerms oo_DEFINE_CLASS (FunctionTerms, Function) oo_LONG (numberOfCoefficients) oo_DOUBLE_VECTOR (coefficients, numberOfCoefficients) #if oo_DECLARING // new methods: virtual double v_evaluate (double x); virtual void v_evaluate_z (dcomplex *z, dcomplex *p); virtual void v_evaluateTerms (double x, double terms[]); virtual void v_getExtrema (double x1, double x2, double *xmin, double *ymin, double *xmax, double *ymax); virtual long v_getDegree (); #endif oo_END_CLASS (FunctionTerms) #undef ooSTRUCT #define ooSTRUCT Spline oo_DEFINE_CLASS (Spline, FunctionTerms) oo_LONG (degree) oo_LONG (numberOfKnots) oo_DOUBLE_VECTOR (knots, numberOfKnots) #if oo_DECLARING // overridden methods: virtual double v_evaluate (double x); virtual long v_getDegree (); // new methods: virtual long v_getOrder (); #endif oo_END_CLASS (Spline) #undef ooSTRUCT /* End of file Polynomial_def.h */ praat-6.0.04/dwtools/Procrustes.cpp000066400000000000000000000055471261542461700173030ustar00rootroot00000000000000/* Procrustes.cpp * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 2001 djmw 20020813 GPL header djmw 20040117 Corrected bug in classProcrustes_transform: scale (s) was not used. djmw 20050406 Renamed Procrustus Procrustes djmw 20071012 Added: o_CAN_WRITE_AS_ENCODING.h djmw 20110304 Thing_new */ #include "Procrustes.h" #include "oo_DESTROY.h" #include "Procrustes_def.h" #include "oo_COPY.h" #include "Procrustes_def.h" #include "oo_EQUAL.h" #include "Procrustes_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Procrustes_def.h" #include "oo_WRITE_TEXT.h" #include "Procrustes_def.h" #include "oo_WRITE_BINARY.h" #include "Procrustes_def.h" #include "oo_READ_TEXT.h" #include "Procrustes_def.h" #include "oo_READ_BINARY.h" #include "Procrustes_def.h" #include "oo_DESCRIPTION.h" #include "Procrustes_def.h" Thing_implement (Procrustes, AffineTransform, 0); void structProcrustes :: v_transform (double **in, long nrows, double **out) { for (long i = 1; i <= nrows; i++) { for (long j = 1; j <= n; j++) { double tmp = 0; for (long k = 1; k <= n; k++) { tmp += in[i][k] * r[k][j]; } out[i][j] = s * tmp + t[j]; } } } Any structProcrustes :: v_invert () { autoProcrustes thee = Data_copy (this); /* R is symmetric rotation matrix --> inverse is transpose! */ thy s = s == 0 ? 1 : 1 / s; for (long i = 1; i <= n; i++) { for (long j = i + 1; j <= n; j++) { thy r[i][j] = r[j][i]; thy r[j][i] = r[i][j]; } thy t[i] = 0; /* for (j = 1; j <= thy n; j++) { thy t[i] -= thy r[i][j] * t[j]; } */ for (long j = 1; j <= thy n; j++) { thy t[i] -= thy r[j][i] * t[j]; } thy t[i] *= thy s; } return thee.transfer(); } static void Procrustes_setDefaults (Procrustes me) { my s = 1; for (long i = 1; i <= my n; i++) { my t[i] = 0; my r[i][i] = 1; for (long j = i + 1; j <= my n; j++) { my r[i][j] = my r[j][i] = 0; } } } autoProcrustes Procrustes_create (long n) { try { autoProcrustes me = Thing_new (Procrustes); AffineTransform_init (me.peek(), n); Procrustes_setDefaults (me.peek()); return me; } catch (MelderError) { Melder_throw (U"Procrustes not created."); } } /* End of file Procrustes.c */ praat-6.0.04/dwtools/Procrustes.h000066400000000000000000000020671261542461700167420ustar00rootroot00000000000000#ifndef _Procrustes_h_ #define _Procrustes_h_ /* Procrustes.h * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20010926 djmw 20020813 GPL header djmw 20110306 Latest modification. */ #include "AffineTransform.h" #include "Procrustes_def.h" oo_CLASS_CREATE (Procrustes, AffineTransform); autoProcrustes Procrustes_create (long n); #endif /* _Procrustes_h_ */ praat-6.0.04/dwtools/Procrustes_def.h000066400000000000000000000021061261542461700175520ustar00rootroot00000000000000/* Procrustes_def.h * * Copyright (C) 1993-2005 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT Procrustes oo_DEFINE_CLASS (Procrustes, AffineTransform) oo_DOUBLE (s) #if oo_DECLARING // overridden methods: virtual void v_transform (double **in, long nrows, double **out); virtual Any v_invert (); #endif oo_END_CLASS (Procrustes) #undef ooSTRUCT /* End of file Procrustes_def.h */ praat-6.0.04/dwtools/Proximity.cpp000066400000000000000000000023541261542461700171270ustar00rootroot00000000000000/* Proximity.cpp * * Copyright (C) 1993-2004, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header djmw 20040309 Removed assertion 'numberOfPoints> 0' in Proximity_init */ #include "Proximity.h" #include "TableOfReal_extensions.h" Thing_implement (Proximity, TableOfReal, 0); void Proximity_init (Proximity me, long numberOfPoints) { TableOfReal_init (me, numberOfPoints, numberOfPoints); TableOfReal_setSequentialRowLabels (me, 0, 0, nullptr, 1, 1); TableOfReal_setSequentialColumnLabels (me, 0, 0, nullptr, 1, 1); } /* End of file Proximity.cpp */ praat-6.0.04/dwtools/Proximity.h000066400000000000000000000020101261542461700165610ustar00rootroot00000000000000#ifndef _Proximity_h_ #define _Proximity_h_ /* Proximity.h * * Copyright (C) 1993-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header djmw 20110306 Latest modification. */ #include "TableOfReal.h" Thing_define (Proximity, TableOfReal) { }; void Proximity_init (Proximity me, long numberOfPoints); #endif /* _Proximity_h_ */ praat-6.0.04/dwtools/Resonator.cpp000066400000000000000000000070551261542461700171020ustar00rootroot00000000000000/* Resonator.cpp * * Copyright (C) 2008-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * djmw 20081029 * djmw 20081124 +ConstantGainResonator * djmw 20110304 Thing_new */ #include "Resonator.h" Thing_implement (Filter, Daata, 0); #define SETBC(f,bw) \ double r = exp (-NUMpi * dT * bw); \ c = -(r * r); \ b = 2.0 * r * cos (2.0 * NUMpi * f * dT); void structFilter :: v_resetMemory () { p1 = p2 = 0; } void structFilter :: v_setFB (double f, double bw) { SETBC (f, bw) a = 1.0 - b - c; } double structFilter :: v_getOutput (double input) { double output = a * input + b * p1 + c * p2; p2 = p1; p1 = output; return output; } Thing_implement (Resonator, Filter, 0); void structResonator :: v_setFB (double f, double bw) { SETBC (f, bw) a = normalisation == Resonator_NORMALISATION_H0 ? (1.0 - b - c) : (1 + c) * sin (2.0 * NUMpi * f * dT); } autoResonator Resonator_create (double dT, int normalisation) { try { autoResonator me = Thing_new (Resonator); my a = 1; // all-pass my dT = dT; my normalisation = normalisation; return me; } catch (MelderError) { Melder_throw (U"Resonator not created."); } } Thing_implement (AntiResonator, Filter, 0); void structAntiResonator :: v_setFB (double f, double bw) { if (f <= 0 && bw <= 0) { a = 1; b = -2; c = 1; // all-pass except dc } else { SETBC (f, bw) a = 1 / (1.0 - b - c); // The next equations are incorporated in the getOutput function //c *= - a; b *= - a; } } /* y[n] = a * (x[n] - b * x[n-1] - c * x[n-2]) */ double structAntiResonator :: v_getOutput (double input) { double output = a * (input - b * p1 - c * p2); p2 = p1; p1 = input; return output; } Thing_implement (ConstantGainResonator, Filter, 0); void structConstantGainResonator :: v_resetMemory () { p1 = p2 = p3 = p4 = 0; } void structConstantGainResonator :: v_setFB (double f, double bw) { SETBC (f, bw) a = 1 - r; d = -r; } /* y[n] = a * (x[n] + d * x[n-2]) + b * y[n-1] + c * y[n-2] */ double structConstantGainResonator :: v_getOutput (double input) { double output = a * (input + d * p4) + b * p1 + c * p2; p2 = p1; p1 = output; p4 = p3; p3 = input; return output; } autoConstantGainResonator ConstantGainResonator_create (double dT) { try { autoConstantGainResonator me = Thing_new (ConstantGainResonator); my a = 1; // all-pass my dT = dT; return me; } catch (MelderError) { Melder_throw (U"ConstantGainResonator not created."); } } autoAntiResonator AntiResonator_create (double dT) { try { autoAntiResonator me = Thing_new (AntiResonator); my a = 1; // all-pass my dT = dT; return me; } catch (MelderError) { Melder_throw (U"AntiResonator not created."); } } void Filter_setFB (Filter me, double f, double b) { my v_setFB (f, b); } double Filter_getOutput (Filter me, double input) { return my v_getOutput (input); } void Filter_resetMemory (Filter me) { my v_resetMemory (); } /* End of file Resonator.cpp */ praat-6.0.04/dwtools/Resonator.h000066400000000000000000000040761261542461700165470ustar00rootroot00000000000000#ifndef _Resonator_h_ #define _Resonator_h_ /* Resonator.h * * Copyright (C) 2008-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * djmw 20081029 * djmw 20110306 Latest modification */ #include "Sound.h" Thing_define (Filter, Daata) { double dT; double a, b, c; double p1, p2; virtual double v_getOutput (double input); virtual void v_setFB (double f, double b); virtual void v_resetMemory (); }; Thing_define (Resonator, Filter) { int normalisation; void v_setFB (double f, double b) override; }; Thing_define (AntiResonator, Resonator) { double v_getOutput (double input) override; void v_setFB (double f, double b) override; }; Thing_define (ConstantGainResonator, Filter) { double d; double p3, p4; double v_getOutput (double input) override; void v_setFB (double f, double b) override; void v_resetMemory () override; }; #define Resonator_NORMALISATION_H0 0 #define Resonator_NORMALISATION_HMAX 1 autoResonator Resonator_create (double dT, int normalisation); autoConstantGainResonator ConstantGainResonator_create (double dT); autoAntiResonator AntiResonator_create (double dT); /* Set a,b,c normalisation == 0: H(0) = 1 -> a = 1 -b - c normalisation == 1: H(Fmax) = 1 -> a = (1 + c)sin(2*pi*F*T) */ void Filter_setFB (Filter me, double f, double b); double Filter_getOutput (Filter me, double input); void Filter_resetMemory (Filter me); #endif /* _Resonator_h_ */ praat-6.0.04/dwtools/SPINET.cpp000066400000000000000000000120321261542461700161170ustar00rootroot00000000000000/* SPINET.cpp * * Copyright (C) 1993-2012 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header djmw 20061212 Changed info to Melder_writeLine format. djmw 20071012 Added: o_CAN_WRITE_AS_ENCODING.h djmw 20080122 float -> double djmw 20110304 Thing_new */ #include "SPINET.h" #include "Sound_extensions.h" #include "NUM2.h" #include "oo_DESTROY.h" #include "SPINET_def.h" #include "oo_COPY.h" #include "SPINET_def.h" #include "oo_EQUAL.h" #include "SPINET_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "SPINET_def.h" #include "oo_WRITE_TEXT.h" #include "SPINET_def.h" #include "oo_WRITE_BINARY.h" #include "SPINET_def.h" #include "oo_READ_TEXT.h" #include "SPINET_def.h" #include "oo_READ_BINARY.h" #include "SPINET_def.h" #include "oo_DESCRIPTION.h" #include "SPINET_def.h" Thing_implement (SPINET, Sampled2, 0); void structSPINET :: v_info () { structDaata :: v_info (); double miny, maxy, mins, maxs; if (! Sampled2_getWindowExtrema_d (this, y, 1, nx, 1, ny, & miny, & maxy) || ! Sampled2_getWindowExtrema_d (this, s, 1, nx, 1, ny, & mins, & maxs)) { return; } MelderInfo_writeLine (U"Minimum power: ", miny); MelderInfo_writeLine (U"Maximum power: ", maxy); MelderInfo_writeLine (U"Minimum power rectified: ", mins); MelderInfo_writeLine (U"Maximum powerrectified: ", maxs); } autoSPINET SPINET_create (double tmin, double tmax, long nt, double dt, double t1, double minimumFrequency, double maximumFrequency, long nFilters, double excitationErbProportion, double inhibitionErbProportion) { try { autoSPINET me = Thing_new (SPINET); double minErb = NUMhertzToErb (minimumFrequency); double maxErb = NUMhertzToErb (maximumFrequency); double dErb = (maxErb - minErb) / nFilters; Sampled2_init (me.peek(), tmin, tmax, nt, dt, t1, minErb - dErb / 2.0, maxErb + dErb / 2.0, nFilters, dErb, minErb); my y = NUMmatrix (1, nFilters, 1, nt); my s = NUMmatrix (1, nFilters, 1, nt); my gamma = 4; my excitationErbProportion = excitationErbProportion; my inhibitionErbProportion = inhibitionErbProportion; return me; } catch (MelderError) { Melder_throw (U"SPINET not created."); } } void SPINET_spectralRepresentation (SPINET me, Graphics g, double fromTime, double toTime, double fromErb, double toErb, double minimum, double maximum, int enhanced, int garnish) { double **z = enhanced ? my s : my y; autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, my ymin, my ymax, my ny, my dy, my y1); for (long j = 1; j <= my ny; j++) { for (long i = 1; i <= my nx; i++) { thy z[j][i] = z[j][i]; } } Matrix_paintCells (thee.peek(), g, fromTime, toTime, fromErb, toErb, minimum, maximum); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Time (s)"); Graphics_marksBottom (g, 2, true, true, false); Graphics_textLeft (g, true, U"Frequency (ERB)"); Graphics_marksLeft (g, 2, true, true, false); Graphics_textTop (g, false, enhanced ? U"Cooperative interaction output" : U"Gammatone filterbank output"); } } void SPINET_drawSpectrum (SPINET me, Graphics g, double time, double fromErb, double toErb, double minimum, double maximum, int enhanced, int garnish) { long ifmin, ifmax, icol = Sampled2_xToLowColumn (me, time); // ppgb: don't use Sampled2_xToColumn for integer rounding double **z = enhanced ? my s : my y; if (icol < 1 || icol > my nx) { return; } if (toErb <= fromErb) { fromErb = my ymin; toErb = my ymax; } Sampled2_getWindowSamplesY (me, fromErb, toErb, &ifmin, &ifmax); autoNUMvector spec (1, my ny); for (long i = 1; i <= my ny; i++) { spec[i] = z[i][icol]; } if (maximum <= minimum) { NUMvector_extrema (spec.peek(), ifmin, ifmax, &minimum, &maximum); } if (maximum <= minimum) { minimum -= 1; maximum += 1; } for (long i = ifmin; i <= ifmax; i++) { if (spec[i] > maximum) { spec[i] = maximum; } else if (spec[i] < minimum) { spec[i] = minimum; } } Graphics_setInner (g); Graphics_setWindow (g, fromErb, toErb, minimum, maximum); Graphics_function (g, spec.peek(), ifmin, ifmax, Sampled2_rowToY (me, ifmin), Sampled2_rowToY (me, ifmax)); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Frequency (ERB)"); Graphics_marksBottom (g, 2, true, true, false); Graphics_textLeft (g, true, U"strength"); Graphics_marksLeft (g, 2, true, true, false); } } /* End of file SPINET.cpp */ praat-6.0.04/dwtools/SPINET.h000066400000000000000000000030471261542461700155720ustar00rootroot00000000000000#ifndef _SPINET_h_ #define _SPINET_h_ /* SPINET.h * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19970408 djmw 20020813 GPL header djmw 20110306 Latest modification. */ #include "Sampled2.h" #include "Graphics.h" #include "SPINET_def.h" oo_CLASS_CREATE (SPINET, Sampled2); autoSPINET SPINET_create (double tmin, double tmax, long nt, double dt, double t1, double minimumFrequency, double maximumFrequency, long nFilters, double excitationErbProportion, double inhibitionErbProportion); void SPINET_spectralRepresentation (SPINET me, Graphics g, double fromTime, double toTime, double fromErb, double toErb, double minimum, double maximum, int enhanced, int garnish); void SPINET_drawSpectrum (SPINET me, Graphics g, double time, double fromErb, double toErb, double minimum, double maximum, int enhanced, int garnish); #endif /* _SPINET_h_ */ praat-6.0.04/dwtools/SPINET_def.h000066400000000000000000000011531261542461700164040ustar00rootroot00000000000000/* SPINET_def.h */ /* David Weenink, 6 apr 1997 */ #define ooSTRUCT SPINET oo_DEFINE_CLASS (SPINET, Sampled2) oo_LONG (gamma) /* filter order */ oo_DOUBLE (excitationErbProportion) /* excitatory bandwidth proportionality factor*/ oo_DOUBLE (inhibitionErbProportion) /* inhibitatory bandwidth proportionality factor*/ oo_DOUBLE_MATRIX (y, ny, nx) /* short term average energy spectrum */ /* spectrum after on-center/off-surround and rectification */ oo_DOUBLE_MATRIX (s, ny, nx) #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (SPINET) #undef ooSTRUCT /* End of file SPINET_def.h */ praat-6.0.04/dwtools/SPINET_to_Pitch.cpp000066400000000000000000000107031261542461700177530ustar00rootroot00000000000000/* SPINET_to_Pitch.cpp * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19970408 djmw 20020813 GPL header djmw 20021106 Latest modification */ #include "SPINET_to_Pitch.h" #include "Pitch_extensions.h" #include "NUM2.h" /* from Erb-scale to log2-scale */ autoPitch SPINET_to_Pitch (SPINET me, double harmonicFallOffSlope, double ceiling, int maxnCandidates) { try { long nPointsPerOctave = 48; double fmin = NUMerbToHertz (Sampled2_rowToY (me, 1)); double fmax = NUMerbToHertz (Sampled2_rowToY (me, my ny)); double fminl2 = NUMlog2 (fmin), fmaxl2 = NUMlog2 (fmax); double points = (fmaxl2 - fminl2) * nPointsPerOctave; double dfl2 = (fmaxl2 - fminl2) / (points - 1); long nFrequencyPoints = (long) floor (points); long maxHarmonic = (long) floor (fmax / fmin); double maxStrength = 0.0, unvoicedCriterium = 0.45, maxPower = 0.0; if (nFrequencyPoints < 2) { Melder_throw (U"Frequency range too small."); } if (ceiling <= fmin) { Melder_throw (U"Ceiling is smaller than centre frequency of lowest filter."); } autoPitch thee = Pitch_create (my xmin, my xmax, my nx, my dx, my x1, ceiling, maxnCandidates); autoNUMvector power (1, my nx); autoNUMvector pitch (1, nFrequencyPoints); autoNUMvector sumspec (1, nFrequencyPoints); autoNUMvector y (1, my ny); autoNUMvector yv2 (1, my ny); autoNUMvector fl2 (1, my ny); // From ERB's to log (f) for (long i = 1; i <= my ny; i++) { double f = NUMerbToHertz (my y1 + (i - 1) * my dy); fl2[i] = NUMlog2 (f); } // Determine global maximum power in frame for (long j = 1; j <= my nx; j++) { double p = 0.0; for (long i = 1; i <= my ny; i++) { p += my s[i][j]; } if (p > maxPower) { maxPower = p; } power[j] = p; } if (maxPower == 0.0) { Melder_throw (U"No power"); } for (long j = 1; j <= my nx; j++) { Pitch_Frame pitchFrame = &thy frame[j]; pitchFrame -> intensity = power[j] / maxPower; for (long i = 1; i <= my ny; i++) { y[i] = my s[i][j]; } NUMspline (fl2.peek(), y.peek(), my ny, 1e30, 1e30, yv2.peek()); for (long k = 1; k <= nFrequencyPoints; k++) { double f = fminl2 + (k - 1) * dfl2; NUMsplint (fl2.peek(), y.peek(), yv2.peek(), my ny, f, & pitch[k]); sumspec[k] = 0.0; } // Formula (8): weighted harmonic summation. for (long m = 1; m <= maxHarmonic; m++) { double hm = 1 - harmonicFallOffSlope * NUMlog2 (m); long kb = 1 + (long) floor (nPointsPerOctave * NUMlog2 (m)); for (long k = kb; k <= nFrequencyPoints; k++) { if (pitch[k] > 0.0) { sumspec[k - kb + 1] += pitch[k] * hm; } } } // into Pitch object Pitch_Frame_init (pitchFrame, maxnCandidates); pitchFrame -> nCandidates = 0; /* !!!!! */ Pitch_Frame_addPitch (pitchFrame, 0, 0, maxnCandidates); /* unvoiced */ for (long k = 2; k <= nFrequencyPoints - 1; k++) { double y1 = sumspec[k - 1], y2 = sumspec[k], y3 = sumspec[k + 1]; if (y2 > y1 && y2 >= y3) { double denum = y1 - 2.0 * y2 + y3, tmp = y3 - 4.0 * y2; double x = dfl2 * (y1 - y3) / (2 * denum); double f = pow (2.0, fminl2 + (k - 1) * dfl2 + x); double strength = (2.0 * y1 * (4.0 * y2 + y3) - y1 * y1 - tmp * tmp) / (8.0 * denum); if (strength > maxStrength) { maxStrength = strength; } Pitch_Frame_addPitch (pitchFrame, f, strength, maxnCandidates); } } } // Scale the pitch strengths for (long j = 1; j <= my nx; j++) { double f0, localStrength; Pitch_Frame_getPitch (&thy frame[j], &f0, &localStrength); Pitch_Frame_resizeStrengths (&thy frame[j], localStrength / maxStrength, unvoicedCriterium); } return thee; } catch (MelderError) { Melder_throw (me, U": no Pitch created."); } } /* End of file SPINET_to_Pitch.cpp */ praat-6.0.04/dwtools/SPINET_to_Pitch.h000066400000000000000000000021051261542461700174150ustar00rootroot00000000000000#ifndef _SPINET_to_Pitch_h_ #define _SPINET_to_Pitch_h_ /* SPINET_to_Pitch.h * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19970408 djmw 20020813 GPL header djmw 20110307 Latest modification */ #include "SPINET.h" #include "Pitch.h" autoPitch SPINET_to_Pitch (SPINET me, double harmonicFallOffSlope, double ceiling, int maxnCandidates); #endif /* _SPINET_to_Pitch_h_ */ praat-6.0.04/dwtools/SSCP.cpp000066400000000000000000001651451261542461700157030ustar00rootroot00000000000000/* SSCP.cpp * * Copyright (C) 1993-2014, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20010614 Covariance_difference: corrected bug in calculation of trace (A B^-1) that caused chisq values to be completely unreliable. djmw 20010628 TableOfReal_to_SSCP: skip error-return when nrows < 2, just issue warning. djmw 20010906 TableOfReal_to_SSCP. djmw 20020212 +getEllipse(s)BoundingBoxCoordinates. djmw 20020313 corrected SSCP_Eigen_project. djmw 20020327 Moved SSCP_and_Eigen_project to Eigen_and_SSCP.c. djmw 20020418 Removed some causes for compiler warnings. djmw 20020430 Changed explicit calculation of SSCP to svd in TableOfReal_to_SSCP. djmw 20030703 Replaced NUMincompletebeta with gsl_sf_beta_inc. djmw 20030801 SSCPs_drawConcentrationEllipses extra label argument. djmw 20030825 Replaced gsl_sf_beta_inc with NUMincompletebeta. djmw 20031104 Added SSCP_to_CCA. djmw 20031117 Added SSCP_extractCentroid. djmw 20031127 Added Covariance_and_TableOfReal_extractDistanceQuantileRange. djmw 20040211 Better warnings in TableOfReal_to_SSCPs_byLabel for single cases. djmw 20040214 Fixed some compiler warnings. djmw 20040219 SSCP_getTraceFraction added. djmw 20040617 SSCP(s)_drawConcentrationEllipse(s) draw with reverse axes possible. (not yet supported by commands in Picture window like 'One mark bottom...' because of reversed axes)! djmw 20060202 Removed a bug in TableOfReal_to_SSCP that could crash Praat (if nrows < ncols). djmw 20060503 Covariance_getSignificanceOfMeansDifference: set probability = 0 if var_pooled = 0 and paired. djmw 20060811 Removed bug in SSCP_and_TableOfReal_to_MahalanobisDistances that caused column labels always to be copied. djmw 20061021 printf expects %ld for 'long int' djmw 20061214 Corrected possible integer overflow in ellipseScalefactor. djmw 20071012 Added: o_CAN_WRITE_AS_ENCODING.h djmw 20071016 To Melder_error djmw 20071202 Melder_warning djmw 20080122 float -> double djmw 20081119 TableOfReal_to_SSCP check if numbers are defined djmw 20090617 TableOfReal_to_SSCPs_byLabel better warnings for singular cases. djmw 20090629 +Covariances_getMultivariateCentroidDifference, Covariances_equality. djmw 20100106 +Covariance_and_TableOfReal_mahalanobis. djmw 20101019 Reduced storage Covariance. djmw 20110304 Thing_new */ #include "SSCP.h" #include "Eigen.h" #include "NUMclapack.h" #include "NUMlapack.h" #include "NUM2.h" #include "SVD.h" #include "oo_DESTROY.h" #include "SSCP_def.h" #include "oo_COPY.h" #include "SSCP_def.h" #include "oo_EQUAL.h" #include "SSCP_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "SSCP_def.h" #include "oo_WRITE_TEXT.h" #include "SSCP_def.h" #include "oo_READ_TEXT.h" #include "SSCP_def.h" #include "oo_WRITE_BINARY.h" #include "SSCP_def.h" #include "oo_READ_BINARY.h" #include "SSCP_def.h" #include "oo_DESCRIPTION.h" #include "SSCP_def.h" #undef MAX #undef MIN #define MAX(m,n) ((m) > (n) ? (m) : (n)) #define MIN(m,n) ((m) < (n) ? (m) : (n)) #define TOVEC(x) (&(x) - 1) Thing_implement (SSCP, TableOfReal, 0); void structSSCP :: v_info () { structTableOfReal :: v_info (); double zmin, zmax; NUMmatrix_extrema (data, 1, numberOfRows, 1, numberOfColumns, &zmin, &zmax); MelderInfo_writeLine (U"Minimum value: ", zmin); MelderInfo_writeLine (U"Maximum value: ", zmax); } /* Calculate scale factor by which sqrt(eigenvalue) has to be multiplied to obtain the length of an ellipse axis. */ double SSCP_getEllipseScalefactor (SSCP me, double scale, bool confidence) { long n = (long) floor (SSCP_getNumberOfObservations (me)); if (confidence) { long p = my numberOfColumns; double f; if (n - p < 1) { return -1.0; } /* D.E. Johnson (1998), Applied Multivariate methods, page 410 */ f = NUMinvFisherQ (1.0 - scale, p, n - p); scale = 2.0 * sqrt (f * p * (n - 1) / ( ((double) n) * (n - p))); } else { // very ugly, temporary hack scale *= 2.0 / (scale < 0.0 ? -1.0 : sqrt (n - 1)); } return scale; } static void getEllipseBoundingBoxCoordinates (SSCP me, double scale, int confidence, double *xmin, double *xmax, double *ymin, double *ymax) { double a, b, cs, sn, width, height; double lscale = SSCP_getEllipseScalefactor (me, scale, confidence); NUMeigencmp22 (my data[1][1], my data[1][2], my data[2][2], &a, &b, &cs, &sn); NUMgetEllipseBoundingBox (sqrt (a), sqrt (b), cs, & width, & height); *xmin = my centroid[1] - lscale * width / 2.0; *xmax = *xmin + lscale * width; *ymin = my centroid[2] - lscale * height / 2.0; *ymax = *ymin + lscale * height; } void SSCPs_getEllipsesBoundingBoxCoordinates (SSCPs me, double scale, int confidence, double *xmin, double *xmax, double *ymin, double *ymax) { *xmin = *ymin = 1e308; *xmax = *ymax = - *xmin; for (long i = 1; i <= my size; i++) { SSCP s = (SSCP) my item[i]; double xmn, xmx, ymn, ymx; getEllipseBoundingBoxCoordinates (s, scale, confidence, &xmn, &xmx, &ymn, &ymx); if (xmn < *xmin) { *xmin = xmn; } if (xmx > *xmax) { *xmax = xmx; } if (ymn < *ymin) { *ymin = ymn; } if (ymx > *ymax) { *ymax = ymx; } } } static SSCP _SSCP_extractTwoDimensions (SSCP me, long d1, long d2) { autoSSCP thee = SSCP_create (2); if (my numberOfRows == 1) { // diagonal thy data [1][1] = my data [1][d1]; thy data [2][2] = my data [1][d2]; } else { thy data [1][1] = my data [d1][d1]; thy data [2][2] = my data [d2][d2]; thy data [2][1] = thy data [1][2] = my data [d1][d2]; } thy centroid[1] = my centroid[d1]; thy centroid[2] = my centroid[d2]; thy numberOfObservations = my numberOfObservations; TableOfReal_setColumnLabel (thee.peek(), 1, my columnLabels[d1]); TableOfReal_setColumnLabel (thee.peek(), 2, my columnLabels[d2]); TableOfReal_setRowLabel (thee.peek(), 1, my columnLabels[d1]); TableOfReal_setRowLabel (thee.peek(), 2, my columnLabels[d2]); return thee.transfer(); } SSCPs SSCPs_extractTwoDimensions (SSCPs me, long d1, long d2) { try { autoSSCPs thee = SSCPs_create (); for (long i = 1; i <= my size; i++) { autoSSCP t = _SSCP_extractTwoDimensions ( (SSCP) my item[i], d1, d2); Thing_setName (t.peek(), Thing_getName ( (Thing) my item[i])); Collection_addItem (thee.peek(), t.transfer()); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": cannot extract two dimensions."); } } void SSCP_drawTwoDimensionalEllipse_inside (SSCP me, Graphics g, double scale, char32 * label, int fontSize) { try { long nsteps = 100; autoNUMvector x (0L, nsteps); autoNUMvector y (0L, nsteps); // Get principal axes and orientation for the ellipse by performing the // eigen decomposition of a symmetric 2-by-2 matrix. // Principal axes are a and b with eigenvector/orientation (cs, sn). double a, b, cs, sn; NUMeigencmp22 (my data[1][1], my data[1][2], my data[2][2], &a, &b, &cs, &sn); // 1. Take sqrt to get units of 'std_dev' a = scale * sqrt (a) / 2.0; b = scale * sqrt (b) / 2.0; x[nsteps] = x[0] = my centroid[1] + cs * a; y[nsteps] = y[0] = my centroid[2] + sn * a; double angle = 0.0; double angle_inc = NUM2pi / nsteps; for (long i = 1; i < nsteps; i++, angle += angle_inc) { double xc = a * cos (angle); double yc = b * sin (angle); double xt = xc * cs - yc * sn; y[i] = my centroid[2] + xc * sn + yc * cs; x[i] = my centroid[1] + xt; } Graphics_polyline (g, nsteps + 1, x.peek(), y.peek()); if (label) { int oldFontSize = Graphics_inqFontSize (g); Graphics_setFontSize (g, fontSize); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); Graphics_text (g, my centroid[1], my centroid[2], label); Graphics_setFontSize (g, oldFontSize); } } catch (MelderError) { Melder_clearError (); } } static void _SSCP_drawTwoDimensionalEllipse (SSCP me, Graphics g, double scale, int fontSize) { long nsteps = 100; char32 *name; autoNUMvector x (0L, nsteps); autoNUMvector y (0L, nsteps); // Get principal axes and orientation for the ellipse by performing the // eigen decomposition of a symmetric 2-by-2 matrix. // Principal axes are a and b with eigenvector/orientation (cs, sn). double a, b, cs, sn; NUMeigencmp22 (my data[1][1], my data[1][2], my data[2][2], &a, &b, &cs, &sn); // 1. Take sqrt to get units of 'std_dev' a = scale * sqrt (a) / 2.0; b = scale * sqrt (b) / 2.0; x[nsteps] = x[0] = my centroid[1] + cs * a; y[nsteps] = y[0] = my centroid[2] + sn * a; double angle = 0.0; double angle_inc = NUM2pi / nsteps; for (long i = 1; i < nsteps; i++, angle += angle_inc) { double xc = a * cos (angle); double yc = b * sin (angle); double xt = xc * cs - yc * sn; y[i] = my centroid[2] + xc * sn + yc * cs; x[i] = my centroid[1] + xt; } Graphics_polyline (g, nsteps + 1, x.peek(), y.peek()); if (fontSize > 0 && (name = Thing_getName (me))) { int oldFontSize = Graphics_inqFontSize (g); Graphics_setFontSize (g, fontSize); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); Graphics_text (g, my centroid[1], my centroid[2], name); Graphics_setFontSize (g, oldFontSize); } } SSCP SSCP_toTwoDimensions (SSCP me, double *v1, double *v2) { try { double *vec[3]; autoSSCP thee = SSCP_create (2); // Projection P of S on v1 and v2 (given matrix V' with 2 rows) is P = V'SV // P[i][j] = sum(k) sum(m) V'[i][k]*S[k][m]*V[m][j] = V'[i][k]*S[k][m]*V'[j][m] // For the new centroids cnew[i] = sum(m) V'[i][m]*c[m] vec[1] = v1; vec[2] = v2; if (my numberOfRows == 1) { // 1xn diagonal matrix for (long k = 1; k <= my numberOfColumns; k++) { thy data[1][1] += v1[k] * my data[1][k] * v1[k]; } for (long k = 1; k <= my numberOfColumns; k++) { thy data[1][2] += v1[k] * my data[1][k] * v2[k]; } for (long k = 1; k <= my numberOfColumns; k++) { thy data[2][2] += v2[k] * my data[1][k] * v2[k]; } thy data[2][1] = thy data[1][2]; } else { for (long i = 1; i <= 2; i++) { for (long j = i; j <= 2; j++) { double sum = 0; for (long k = 1; k <= my numberOfRows; k++) { for (long m = 1; m <= my numberOfRows; m++) { sum += vec[i][k] * my data[k][m] * vec[j][m]; } } thy data[j][i] = thy data[i][j] = sum; } } } // centroids for (long m = 1; m <= my numberOfColumns; m++) { thy centroid[1] += v1[m] * my centroid[m]; } for (long m = 1; m <= my numberOfColumns; m++) { thy centroid[2] += v2[m] * my centroid[m]; } thy numberOfObservations = SSCP_getNumberOfObservations (me); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": cannot extract two dimensions."); } } void SSCP_init (SSCP me, long dimension, long storage) { TableOfReal_init (me, storage, dimension); my centroid = NUMvector (1, dimension); } SSCP SSCP_create (long dimension) { try { autoSSCP me = Thing_new (SSCP); SSCP_init (me.peek(), dimension, dimension); return me.transfer(); } catch (MelderError) { Melder_throw (U"SSCP not created."); } } double SSCP_getConcentrationEllipseArea (SSCP me, double scale, bool confidence, long d1, long d2) { long p = my numberOfRows; if (d1 < 1 || d1 > p || d2 < 1 || d2 > p || d1 == d2) { Melder_throw (U"Incorrect axes."); } autoSSCP thee = _SSCP_extractTwoDimensions (me, d1, d2); scale = SSCP_getEllipseScalefactor (thee.peek(), scale, confidence); if (scale < 0.0) { Melder_throw (U"Invalid scale factor."); } double a, b, cs, sn; NUMeigencmp22 (thy data[1][1], thy data[1][2], thy data[2][2], &a, &b, &cs, &sn); // 1. Take sqrt to get units of 'std_dev' a = scale * sqrt (a) / 2.0; b = scale * sqrt (b) / 2.0; return NUMpi * a * b; } double SSCP_getFractionVariation (SSCP me, long from, long to) { long n = my numberOfRows; if (from < 1 || from > to || to > n) { return NUMundefined; } double sum = 0.0, trace = 0.0; for (long i = 1; i <= n; i++) { trace += my numberOfRows == 1 ? my data[1][i] : my data[i][i]; if (i >= from && i <= to) { sum += my numberOfRows == 1 ? my data[1][i] : my data[i][i]; } } return trace > 0.0 ? sum / trace : NUMundefined; } void SSCP_drawConcentrationEllipse (SSCP me, Graphics g, double scale, int confidence, long d1, long d2, double xmin, double xmax, double ymin, double ymax, int garnish) { long p = my numberOfColumns; if (d1 < 1 || d1 > p || d2 < 1 || d2 > p || d1 == d2) { Melder_throw (U"Incorrect axes."); } autoSSCP thee = _SSCP_extractTwoDimensions (me, d1, d2); double xmn, xmx, ymn, ymx; getEllipseBoundingBoxCoordinates (thee.peek(), scale, confidence, &xmn, &xmx, &ymn, &ymx); if (xmax == xmin) { xmin = xmn; xmax = xmx; } if (ymax == ymin) { ymin = ymn; ymax = ymx; } Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_setInner (g); scale = SSCP_getEllipseScalefactor (thee.peek(), scale, confidence); if (scale < 0) { Melder_throw (U"Invalid scale factor."); } _SSCP_drawTwoDimensionalEllipse (thee.peek(), g, scale, 0); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksLeft (g, 2, true, true, false); Graphics_marksBottom (g, 2, true, true, false); } } void SSCP_setNumberOfObservations (SSCP me, double numberOfObservations) { my numberOfObservations = numberOfObservations; } double SSCP_getNumberOfObservations (SSCP me) { return my numberOfObservations; } double SSCP_getDegreesOfFreedom (SSCP me) { return my numberOfObservations - 1; } double SSCP_getTotalVariance (SSCP me) { double trace = 0.0; for (long i = 1; i <= my numberOfColumns; i++) { trace += my numberOfRows == 1 ? my data[1][i] : my data[i][i]; } return trace; } double SSCP_getCumulativeContributionOfComponents (SSCP me, long from, long to) { double sum = NUMundefined; if (to == 0) { to = my numberOfRows; } if (from > 0 && to <= my numberOfRows && from <= to) { sum = SSCP_getTotalVariance (me); double partial = 0.0; for (long i = from; i <= to; i++) { partial += my numberOfRows == 1 ? my data[1][i] : my data[i][i]; } if (sum > 0.0) { sum = partial / sum; } } return sum; } /* For nxn matrix only ! */ void Covariance_and_PCA_generateOneVector (Covariance me, PCA thee, double *vec, double *buf) { // Generate the multi-normal vector elements N(0,sigma) for (long j = 1; j <= my numberOfColumns; j++) { buf[j] = NUMrandomGauss (0.0, sqrt (thy eigenvalues[j])); } // Rotate back for (long j = 1; j <= my numberOfColumns; j++) { vec[j] = 0.0; for (long k = 1; k <= my numberOfColumns; k++) { vec[j] += buf[k] * thy eigenvectors[k][j]; } } // Restore the centroid for (long j = 1; j <= my numberOfColumns; j++) { vec[j] += my centroid[j]; } } TableOfReal Covariance_to_TableOfReal_randomSampling (Covariance me, long numberOfData) { try { if (numberOfData <= 0) { numberOfData = (long) floor (my numberOfObservations); } autoPCA pca = SSCP_to_PCA (me); autoTableOfReal thee = TableOfReal_create (numberOfData, my numberOfColumns); autoNUMvector buf (1, my numberOfColumns); for (long i = 1; i <= numberOfData; i++) { Covariance_and_PCA_generateOneVector (me, pca.peek(), thy data[i], buf.peek()); } NUMstrings_copyElements (my columnLabels, thy columnLabels, 1, my numberOfColumns); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not random sampled."); } } SSCP TableOfReal_to_SSCP (TableOfReal me, long rowb, long rowe, long colb, long cole) { try { TableOfReal_areAllCellsDefined (me, rowb, rowe, colb, cole); if (rowb == 0 && rowe == 0) { rowb = 1; rowe = my numberOfRows; } else if (rowe < rowb || rowb < 1 || rowe > my numberOfRows) { Melder_throw (U"Invalid row number."); } if (colb == 0 && cole == 0) { colb = 1; cole = my numberOfColumns; } else if (cole < colb || colb < 1 || cole > my numberOfColumns) { Melder_throw (U"Invalid column number."); } long m = rowe - rowb + 1; /* # rows */ long n = cole - colb + 1; /* # columns */ if (m < n) Melder_warning (U"The SSCP will not have \n" "full dimensionality. This may be a problem in following analysis steps. \n" "(The number of data points was less than the number of variables.)"); autoSSCP thee = SSCP_create (n); autoNUMmatrix v (1, m, 1, n); long nvalidrows = 0; for (long i = 1; i <= m; i++) { nvalidrows++; for (long j = 1; j <= n; j++) { v[i][j] = my data[rowb + i - 1][colb + j - 1]; } } NUMcentreColumns (v.peek(), 1, m, 1, n, thy centroid); SSCP_setNumberOfObservations (thee.peek(), m); // sum of squares and cross products = T'T for (long i = 1; i <= n; i++) { for (long j = i; j <= n; j++) { double t = 0.0; for (long k = 1; k <= m; k++) { t += v[k][i] * v[k][j]; } thy data[i][j] = thy data[j][i] = t; } } for (long j = 1; j <= n; j++) { char32 *label = my columnLabels[colb + j - 1]; TableOfReal_setColumnLabel (thee.peek(), j, label); TableOfReal_setRowLabel (thee.peek(), j, label); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": SSCP not created."); } } TableOfReal SSCP_and_TableOfReal_extractDistanceQuantileRange (SSCP me, TableOfReal thee, double qlow, double qhigh) { try { autoCovariance cov = SSCP_to_Covariance (me, 1); autoTableOfReal him = Covariance_and_TableOfReal_extractDistanceQuantileRange (cov.peek(), thee, qlow, qhigh); return him.transfer(); } catch (MelderError) { Melder_throw (me, U": no distance quantile ranges created."); } } TableOfReal Covariance_and_TableOfReal_mahalanobis (Covariance me, thou, bool useTableCentroid) { try { thouart (TableOfReal); autoTableOfReal him = TableOfReal_create (thy numberOfRows, 1); autoNUMvector centroid (NUMvector_copy (my centroid, 1, thy numberOfColumns), 1); autoNUMmatrix covari (NUMmatrix_copy (my data, 1, my numberOfRows, 1, my numberOfRows), 1, 1); // Mahalanobis distance calculation. S = L.L' -> S**-1 = L**-1' . L**-1 // (x-m)'S**-1 (x-m) = (x-m)'L**-1' . L**-1. (x-m) = // (L**-1.(x-m))' . (L**-1.(x-m)) // Get inverse of covari in lower triangular part. double lndet; NUMlowerCholeskyInverse (covari.peek(), my numberOfRows, &lndet); if (useTableCentroid) { for (long icol = 1; icol <= thy numberOfColumns; icol++) { double mean = 0.0; for (long irow = 1; irow <= thy numberOfRows; irow++) { mean += thy data[irow][icol]; } centroid[icol] = mean / thy numberOfRows; } } for (long k = 1; k <= thy numberOfRows; k++) { his data[k][1] = sqrt (NUMmahalanobisDistance_chi (covari.peek(), thy data[k], centroid.peek(), my numberOfRows, my numberOfRows)); if (thy rowLabels[k]) { TableOfReal_setRowLabel (him.peek(), k, thy rowLabels[k]); } } TableOfReal_setColumnLabel (him.peek(), 1, U"d"); return him.transfer(); } catch (MelderError) { Melder_throw (me, U"no Mahalanobis distances created."); } } TableOfReal Covariance_and_TableOfReal_extractDistanceQuantileRange (Covariance me, TableOfReal thee, double qlow, double qhigh) { try { autoTableOfReal him = Covariance_and_TableOfReal_mahalanobis (me, thee, false); double low = TableOfReal_getColumnQuantile (him.peek(), 1, qlow); double high = TableOfReal_getColumnQuantile (him.peek(), 1, qhigh); // Count the number filtered. // nsel = (qhigh - qlow) * nrows is sometimes one off long nsel = 0; for (long i = 1; i <= thy numberOfRows; i++) { if (low <= his data[i][1] && his data[i][1] < high) { nsel++; } } if (nsel < 1) { Melder_throw (U"Not enough data in quantile interval."); } autoTableOfReal r = TableOfReal_create (nsel, thy numberOfColumns); NUMstrings_copyElements (thy columnLabels, r -> columnLabels, 1, thy numberOfColumns); //((r -> columnLabels = NUMstrings_copy (thy columnLabels, 1, thy numberOfColumns)) == nullptr)) goto end; long k = 0; for (long i = 1; i <= thy numberOfRows; i++) { if (low <= his data[i][1] && his data[i][1] < high) { k++; TableOfReal_copyOneRowWithLabel (thee, r.peek(), i, k); } } return r.transfer(); } catch (MelderError) { Melder_throw (U"TableOfReal with distancequantile range not created."); } } Covariance TableOfReal_to_Covariance (TableOfReal me) { try { autoSSCP sscp = TableOfReal_to_SSCP (me, 0, 0, 0, 0); autoCovariance thee = SSCP_to_Covariance (sscp.peek(), 1); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": covariances not created."); } } Correlation TableOfReal_to_Correlation (TableOfReal me) { try { autoSSCP sscp = TableOfReal_to_SSCP (me, 0, 0, 0, 0); autoCorrelation thee = SSCP_to_Correlation (sscp.peek()); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": correlations not created."); } } Correlation TableOfReal_to_Correlation_rank (TableOfReal me) { try { autoTableOfReal t = TableOfReal_rankColumns (me); autoCorrelation thee = TableOfReal_to_Correlation (t.peek()); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": rank correlations not created."); } } SSCPs TableOfReal_to_SSCPs_byLabel (TableOfReal me) { try { autoSSCPs thee = SSCPs_create (); autoTableOfReal mew = TableOfReal_sortOnlyByRowLabels (me); const char32 *label = mew -> rowLabels[1]; Melder_warningOff (); long numberOfCases = my numberOfRows, ncols = my numberOfColumns; long lastrow = 0, ngroups = 0, nsingular = 0, index = 1; for (long i = 2; i <= numberOfCases; i++) { long nrows = 0; const char32 *li = mew -> rowLabels[i]; if (Melder_cmp (li, label) != 0) { // current label different from previous one(s) nrows = i - index; lastrow = i - 1; } else if (i == numberOfCases) { // current (last) label is same as previous nrows = i - index + 1; lastrow = i; } else { // next one continue; } // We found a new group ngroups++; if (nrows > 1) { // We need at least two rows for an SSCP if (nrows < ncols) { nsingular++; } autoSSCP t = TableOfReal_to_SSCP (mew.peek(), index, lastrow, 0, 0); if (! (label = mew -> rowLabels[index])) { label = U"?"; } Thing_setName (t.peek(), label); Collection_addItem (thee.peek(), t.transfer()); } label = li; index = i; } if (lastrow != numberOfCases) { ngroups++; } Melder_warningOn (); if (nsingular > 0 || thy size != ngroups) { long notIncluded = ngroups - thy size; Melder_warning (ngroups, U" different groups detected: ", nsingular + notIncluded, U" group(s) with less rows than columns (of which ", notIncluded, U" with only one row)."); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": SSCP not created from labels."); } } PCA SSCP_to_PCA (SSCP me) { try { double **data = my data; autoNUMmatrix adata; autoPCA thee = PCA_create (my numberOfColumns, my numberOfColumns); if (my numberOfRows == 1) { // 1xn matrix -> nxn // ugly hack adata.reset (1, my numberOfColumns, 1, my numberOfColumns); for (long i = 1; i <= my numberOfColumns; i++) { data[i][i] = my data[1][i]; } data = adata.peek(); } NUMstrings_copyElements (my columnLabels, thy labels, 1, my numberOfColumns); Eigen_initFromSymmetricMatrix (thee.peek(), data, my numberOfColumns); NUMvector_copyElements (my centroid, thy centroid, 1, my numberOfColumns); PCA_setNumberOfObservations (thee.peek(), (long) floor (my numberOfObservations)); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": PCA not created."); } } void SSCP_setValue (SSCP me, long row, long col, double value) { if (col < 0 || col > my numberOfColumns) { Melder_throw (U"Illegal column number."); } if (row < 0 || row > my numberOfColumns) { Melder_throw (U"Illegal row number."); // ! yes numberOfColumns } if (row == col && value <= 0) { Melder_throw (U"Diagonal element must always be a positive number."); } if (my numberOfRows == 1) { // diagonal if (row != col) { Melder_throw (U"Row and column number must be equal for a diagonal matrix."); } my data[1][row] = value; } else { if (row != col && (fabs (value) > my data[row][row] || fabs (value) > my data[row][row])) Melder_throw (U"The off-diagonal cannot be larger than the diagonal values. Input diagonal elements first, or change this value."); my data[row][col] = my data[col][row] = value; } } void SSCP_setCentroid (SSCP me, long component, double value) { if (component < 1 || component > my numberOfColumns) { Melder_throw (U"Illegal component number."); } my centroid[component] = value; } autoCCA SSCP_to_CCA (SSCP me, long ny) { try { char upper = 'L', diag = 'N'; long info; if (ny < 1 || ny >= my numberOfRows) { Melder_throw (U"ny < 1 || ny >= my numberOfRows"); } if (my numberOfRows == 1) { Melder_throw (U"Matrix is diagonal."); } long m = my numberOfRows, nx = m - ny, xy_interchanged = nx < ny, yof = 0, xof = ny; if (xy_interchanged) { yof = ny; xof = 0; nx = ny; ny = m - nx; } autoCCA thee = Thing_new (CCA); autoNUMmatrix sxx (1, nx, 1, nx); autoNUMmatrix syy (1, ny, 1, ny); autoNUMmatrix syx (1, ny, 1, nx); // Copy Syy and Sxx into upper part of syy and sxx matrices. for (long i = 1; i <= ny; i++) { for (long j = i; j <= ny; j++) { syy[i][j] = my data[yof + i][yof + j]; } } for (long i = 1; i <= nx; i++) { for (long j = i; j <= nx; j++) { sxx[i][j] = my data[xof + i][xof + j]; } } for (long i = 1; i <= nx; i++) { for (long j = 1; j <= ny; j++) { syx[i][j] = my data[yof + i][xof + j]; } } // Cholesky decomposition: Syy = Uy'*Uy and Sxx = Ux'*Ux. // (Pretend as if colum-major storage) (void) NUMlapack_dpotf2 (&upper, &ny, &syy[1][1], &ny, &info); if (info != 0) Melder_throw (U"The leading minor of order ", info, U" is not positive definite, and the " U"factorization of Syy could not be completed."); (void) NUMlapack_dpotf2 (&upper, &nx, &sxx[1][1], &nx, &info); if (info != 0) Melder_throw (U"The leading minor of order ", info, U" is not positive definite, and the " U"factorization of Sxx could not be completed."); /* With Cholesky decomps Sxx = Ux'* Ux, Syy = Uy * Uy' Sxx**-1 = Uxi * Uxi' and Syy**-1 = Uyi * Uyi', where Uxi = Ux**-1 and Uyi = Uy**-1, the equations (1) (Syx * Sxx**-1 * Syx' - lambda Syy) y = 0 (1') (Syx' * Syy**-1 * Syx - lambda Sxx) x = 0 can be written as: (2) (Syx * Uxi * Uxi' * Syx' - lambda Uy' * Uy) y = 0 (2') (Syx' * Uyi * Uyi' * Syx - lambda Ux' * Ux) x = 0 More explicitly as: (3) (Uxi' * Syx')' * (Uxi' * Syx') - lambda Uy' * Uy) y = 0 (3') (Uyi' * Syx )' * (Uyi' * Syx ) - lambda Ux' * Ux) x = 0 They are now in the form (A'A - lambda B'B) x = 0 and both can be solved with the GSVD. However, these equations are not independent. Both have the same eigenvalues and given the eigenvectors for one, the eigenvectors for the other can be calculated. If nx >= ny use eq. (3) GSVD (Uxi' * Syx', Uy) gives lambda's and y. To get x multiply (1) from the left by Syx'*Syy**-1 (4) (Syx'*Syy**-1*Syx * Sxx**-1 - lambda ) Syx' * y = 0 Split off Sxx**-1 (5) (Syx'*Syy**-1*Syx -lambda Sxx) * Sxx**-1 * Syx' * y = 0 It follows that x = Sxx**-1 * Syx' * y = Uxi * Uxi' * Sxy * y If ny > nx use eq. (3') We switch the role of x and y. */ autoNUMmatrix a (1, nx, 1, ny); // Uxi = inverse(Ux) (void) NUMlapack_dtrti2 (&upper, &diag, &nx, &sxx[1][1], &nx, &info); if (info != 0) { Melder_throw (U"Error in inverse for Sxx."); } // Prepare Uxi' * Syx' = (Syx * Uxi)' for (long i = 1; i <= ny; i++) { for (long j = 1; j <= nx; j++) { double t = 0.0; for (long k = 1; k <= j; k++) { t += syx[i][k] * sxx[k][j]; } a[j][i] = t; } } autoGSVD gsvd = GSVD_create_d (a.peek(), nx, ny, syy.peek(), ny); autoNUMmatrix ri (NUMmatrix_copy (gsvd -> r, 1, gsvd -> numberOfColumns, 1, gsvd -> numberOfColumns), 1, 1); thy y = Eigen_create (gsvd -> numberOfColumns, gsvd -> numberOfColumns); thy x = Eigen_create (thy y -> numberOfEigenvalues, nx); // Get X=Q*R**-1 (void) NUMlapack_dtrti2 (&upper, &diag, &gsvd -> numberOfColumns, &ri[1][1], &gsvd -> numberOfColumns, &info); if (info != 0) { Melder_throw (U"Error in inverse for R."); } for (long i = 1; i <= gsvd -> numberOfColumns; i++) { double t = gsvd -> d1[i] / gsvd -> d2[i]; thy y -> eigenvalues[i] = t * t; for (long j = 1; j <= gsvd -> numberOfColumns; j++) { t = 0.0; for (long k = 1; k <= j; k++) { t += gsvd -> q[i][k] * ri[k][j]; } thy y -> eigenvectors[j][i] = t; } } NUMnormalizeRows (thy y -> eigenvectors, thy y -> numberOfEigenvalues, thy y -> numberOfEigenvalues, 1); thy numberOfCoefficients = thy y -> numberOfEigenvalues; thy numberOfObservations = (long) floor (my numberOfObservations); // x = Sxx**-1 * Syx' * y for (long i = 1; i <= thy numberOfCoefficients; i++) { double *evecy = thy y -> eigenvectors[i]; double *evecx = thy x -> eigenvectors[i]; for (long j = 1; j <= nx; j++) { double t = 0.0; for (long k = j; k <= nx; k++) { for (long l = 1; l <= nx; l++) { for (long n = 1; n <= ny; n++) { t += sxx[j][k] * sxx[l][k] * syx[n][l] * evecy[n]; } } } evecx[j] = t; } } NUMnormalizeRows (thy x -> eigenvectors, thy x -> numberOfEigenvalues, nx, 1); if (ny < nx) { autoEigen t = thy x.move(); thy x = thy y.move(); thy y = t.move(); } return thee; } catch (MelderError) { Melder_throw (me, U": CCA not created."); } } /************ SSCPs ***********************************************/ Thing_implement (SSCPs, Ordered, 0); SSCPs SSCPs_create () { try { autoSSCPs me = Thing_new (SSCPs); Ordered_init (me.peek(), classSSCP, 10); return me.transfer(); } catch (MelderError) { Melder_throw (U"SSCPs not created."); } } SSCP SSCPs_to_SSCP_pool (SSCPs me) { try { autoSSCP thee = Data_copy ( (SSCP) my item[1]); for (long k = 2; k <= my size; k++) { SSCP t = (SSCP) my item[k]; long no = (long) floor (t -> numberOfObservations); if (t -> numberOfRows != thy numberOfRows) { Melder_throw (U"Unequal dimensions (", k, U")."); } thy numberOfObservations += no; // Sum the sscp's and weigh the centroid. for (long i = 1; i <= thy numberOfRows; i++) { // if 1xn for (long j = 1; j <= thy numberOfColumns; j++) { thy data[i][j] += t -> data[i][j]; } } for (long j = 1; j <= thy numberOfRows; j++) { thy centroid[j] += no * t -> centroid[j]; } } for (long i = 1; i <= thy numberOfRows; i++) { thy centroid[i] /= thy numberOfObservations; } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not pooled."); } } void SSCPs_getHomegeneityOfCovariances_box (SSCPs me, double *probability, double *chisq, long *ndf) { *probability = 0.0; *chisq = 0.0; *ndf = 0; autoSSCP pooled = SSCPs_to_SSCP_pool (me); long p = pooled -> numberOfColumns; double ln_determinant, inv = 0.0, sum = 0.0, g = my size; for (long i = 1; i <= g; i++) { SSCP t = (SSCP) my item[i]; double ni = t -> numberOfObservations - 1.0; NUMdeterminant_cholesky (t -> data, p, &ln_determinant); // Box-test is for covariance matrices -> scale determinant. ln_determinant -= p * log (ni); sum += ni; inv += 1.0 / ni; *chisq -= ni * ln_determinant; } NUMdeterminant_cholesky (pooled -> data, p, &ln_determinant); ln_determinant -= p * log (pooled -> numberOfObservations - g); *chisq += sum * ln_determinant; *chisq *= 1.0 - (inv - 1.0 / sum) * (2.0 * p * p + 3.0 * p - 1.0) / (6.0 * (p + 1) * (g - 1.0)); *ndf = (long) floor ((g - 1.0) * p * (p + 1) / 2.0); *probability = NUMchiSquareQ (*chisq, *ndf); } SSCPs SSCPs_toTwoDimensions (SSCPs me, double *v1, double *v2) { try { autoSSCPs thee = SSCPs_create (); for (long i = 1; i <= my size; i++) { autoSSCP t = (SSCP) SSCP_toTwoDimensions ((SSCP) my item[i], v1, v2); Thing_setName (t.peek(), Thing_getName ( (Thing) my item[i])); Collection_addItem (thee.peek(), t.transfer()); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not reduced to two dimensions."); } } void SSCPs_drawConcentrationEllipses (SSCPs me, Graphics g, double scale, int confidence, const char32 *label, long d1, long d2, double xmin, double xmax, double ymin, double ymax, int fontSize, int garnish) { SSCP t = (SSCP) my item[1]; long p = t -> numberOfColumns; if (d1 < 1 || d1 > p || d2 < 1 || d2 > p || d1 == d2) { Melder_throw (U"Incorrect axes."); } autoSSCPs thee = SSCPs_extractTwoDimensions (me, d1, d2); double xmn, xmx, ymn, ymx; SSCPs_getEllipsesBoundingBoxCoordinates (thee.peek(), scale, confidence, &xmn, &xmx, &ymn, &ymx); if (xmin == xmax) { xmin = xmn; xmax = xmx; } if (ymin == ymax) { ymin = ymn; ymax = ymx; } Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_setInner (g); for (long i = 1; i <= thy size; i++) { t = (SSCP) thy item[i]; double lscale = SSCP_getEllipseScalefactor (t, scale, confidence); if (lscale < 0.0) { continue; } if (! label || Melder_cmp (label, Thing_getName (t)) == 0) { _SSCP_drawTwoDimensionalEllipse (t, g, lscale, fontSize); } } Graphics_unsetInner (g); if (garnish) { t = (SSCP) my item[1]; Graphics_drawInnerBox (g); Graphics_marksLeft (g, 2, true, true, false); Graphics_textLeft (g, true, t -> columnLabels[d2] ? t -> columnLabels[d2] : Melder_cat (U"Dimension ", d2)); Graphics_marksBottom (g, 2, true, true, false); Graphics_textBottom (g, true, t -> columnLabels[d1] ? t -> columnLabels[d1] : Melder_cat (U"Dimension ", d1)); } } TableOfReal SSCP_to_TableOfReal (SSCP me) { try { autoTableOfReal thee = Thing_new (TableOfReal); my structTableOfReal :: v_copy (thee.peek()); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not copied."); } } TableOfReal SSCP_extractCentroid (SSCP me) { try { long n = my numberOfColumns; autoTableOfReal thee = TableOfReal_create (1, n); NUMvector_copyElements (my centroid, thy data[1], 1, n); thy columnLabels = NUMstrings_copy (my columnLabels, 1, n); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": centroid not extracted."); } } Thing_implement (Covariance, SSCP, 0); Thing_implement (Correlation, SSCP, 0); Covariance Covariance_create (long dimension) { try { autoCovariance me = Thing_new (Covariance); SSCP_init (me.peek(), dimension, dimension); return me.transfer(); } catch (MelderError) { Melder_throw (U"Covariance not created."); } } Covariance Covariance_create_reduceStorage (long dimension, long storage) { try { autoCovariance me = Thing_new (Covariance); if (storage <= 0 || storage >= dimension) { storage = dimension; } SSCP_init (me.peek(), dimension, storage); return me.transfer(); } catch (MelderError) { Melder_throw (U"Reduced storage covariance not created."); } } Covariance Covariance_createSimple (char32 *covariances, char32 *centroid, long numberOfObservations) { try { long dimension, ncovars; autoNUMvector centroids (NUMstring_to_numbers (centroid, &dimension), 1); autoNUMvector covars (NUMstring_to_numbers (covariances, &ncovars), 1); long ncovars_wanted = dimension * (dimension + 1) / 2; if (ncovars != ncovars_wanted) Melder_throw (U"The number of covariance matrix elements and the number of " U"centroid elements are not in concordance. There should be d(d+1)/2 covariance values and d centroid values."); autoCovariance me = Covariance_create (dimension); // Construct the full covariance matrix from the upper-diagonal elements long rowNumber = 1; for (long inum = 1; inum <= ncovars_wanted; inum++) { long nmissing = (rowNumber - 1) * rowNumber / 2; long inumc = inum + nmissing; rowNumber = (inumc - 1) / dimension + 1; long icol = ( (inumc - 1) % dimension) + 1; my data[rowNumber][icol] = my data[icol][rowNumber] = covars[inum]; if (icol == dimension) { rowNumber++; } } // Check if a valid covariance, first check variances then covariances for (long irow = 1; irow <= dimension; irow++) { if (my data[irow][irow] <= 0) { Melder_throw (U"The variances, i.e. the diagonal matrix elements, must all be positive numbers."); } } for (long irow = 1; irow <= dimension; irow++) { for (long icol = irow + 1; icol <= dimension; icol++) { if (fabs (my data[irow][icol] / sqrt (my data[irow][irow] * my data[icol][icol])) > 1) { long nmissing = (irow - 1) * irow / 2; long inum = (irow - 1) * dimension + icol - nmissing; Melder_throw (U"The covariance in cell [", irow, U",", icol, U"], i.e. input item ", inum, U" is too large."); } } } for (long inum = 1; inum <= dimension; inum++) { my centroid[inum] = centroids[inum]; } my numberOfObservations = numberOfObservations; return me.transfer(); } catch (MelderError) { Melder_throw (U"Simple Covariance not created."); } } Correlation Correlation_create (long dimension) { try { autoCorrelation me = Thing_new (Correlation); SSCP_init (me.peek(), dimension, dimension); return me.transfer(); } catch (MelderError) { Melder_throw (U"Correlation not created."); } } Covariance SSCP_to_Covariance (SSCP me, long numberOfConstraints) { try { Melder_assert (numberOfConstraints >= 0); autoCovariance thee = Thing_new (Covariance); my structSSCP :: v_copy (thee.peek()); for (long i = 1; i <= my numberOfRows; i++) { for (long j = i; j <= my numberOfColumns; j++) { thy data[j][i] = thy data[i][j] /= (my numberOfObservations - numberOfConstraints); } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U"; Covariance not created."); } } SSCP Covariance_to_SSCP (Covariance me) { try { autoSSCP thee = Thing_new (SSCP); my structSSCP :: v_copy (thee.peek()); for (long i = 1; i <= my numberOfRows; i++) { for (long j = i; j <= my numberOfColumns; j++) { thy data[j][i] = thy data[i][j] *= (my numberOfObservations - 1); } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": SSCP not created."); } } Correlation SSCP_to_Correlation (SSCP me) { try { autoCorrelation thee = Thing_new (Correlation); my structSSCP :: v_copy (thee.peek()); for (long i = 1; i <= my numberOfRows; i++) { for (long j = i; j <= my numberOfColumns; j++) { thy data[j][i] = thy data[i][j] /= sqrt (my data[i][i] * my data[j][j]); } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": Correlation not created."); } } double SSCP_getLnDeterminant (SSCP me) { try { double ln_d; NUMdeterminant_cholesky (my data, my numberOfRows, &ln_d); return ln_d; } catch (MelderError) { return NUMundefined; } } static Covariance Covariances_pool (Covariance me, Covariance thee) { try { if (my numberOfRows != thy numberOfRows || my numberOfColumns != thy numberOfColumns) Melder_throw (U"Matrices must have equal dimensions."); autoSSCPs sscps = SSCPs_create (); autoSSCP sscp1 = Covariance_to_SSCP (me); Collection_addItem (sscps.peek(), sscp1.transfer()); autoSSCP sscp2 = Covariance_to_SSCP (thee); Collection_addItem (sscps.peek(), sscp2.transfer()); autoSSCP pool = SSCPs_to_SSCP_pool (sscps.peek()); autoCovariance him = SSCP_to_Covariance (pool.peek(), 2); return him.transfer(); } catch (MelderError) { Melder_throw (me, U"not pooled."); } } static double **productOfSquareMatrices (double **s1, double **s2, long n) { autoNUMmatrix r (1, n, 1, n); for (long i = 1; i <= n; i++) { for (long j = 1; j <= n; j++) { double sum = 0; for (long k = 1; k <= n; k++) { sum += s1[i][k] * s2[k][j]; } r[i][j] = sum; } } return r.transfer(); } static double traceOfSquaredMatrixProduct (double **s1, double **s2, long n) { // tr ((s1*s2)^2), s1, s2 are symmetric autoNUMmatrix m (productOfSquareMatrices (s1, s2, n), 1, 1); double trace2 = NUMtrace2 (m.peek(), m.peek(), n); return trace2; } double Covariance_getProbabilityAtPosition_string (Covariance me, char32 *vector) { autoNUMvector v (1, my numberOfColumns); long i = 0; for (char32 *token = Melder_firstToken (vector); token != nullptr; token = Melder_nextToken ()) { v[++i] = Melder_atof (token); if (i == my numberOfColumns) { break; } } double p = Covariance_getProbabilityAtPosition (me, v.peek()); return p; } double Covariance_getProbabilityAtPosition (Covariance me, double *x) { if (my lowerCholesky == 0) { SSCP_expandLowerCholesky (me); } double ln2pid = my numberOfColumns * log (NUM2pi); double dsq = NUMmahalanobisDistance_chi (my lowerCholesky, x, my centroid, my numberOfRows, my numberOfColumns); double lnN = - 0.5 * (ln2pid + my lnd + dsq); double p = exp (lnN); return p; } double Covariance_getMarginalProbabilityAtPosition (Covariance me, double *vector, double x) { double mu, stdev; Covariance_getMarginalDensityParameters (me, vector, &mu, &stdev); double dx = (x - mu) / stdev; double p = (NUM1_sqrt2pi / stdev) * exp (- 0.5 * dx * dx); return p; } /* Precondition ||v|| = 1 */ void Covariance_getMarginalDensityParameters (Covariance me, double *v, double *mu, double *stdev) { *stdev = *mu = 0; if (my numberOfRows == 1) { // 1xn diagonal matrix for (long m = 1; m <= my numberOfColumns; m++) { *stdev += v[m] * my data[1][m] * v[m]; } } else { for (long k = 1; k <= my numberOfRows; k++) { for (long m = 1; m <= my numberOfColumns; m++) { *stdev += v[k] * my data[k][m] * v[m]; } } } *stdev = sqrt (*stdev); for (long m = 1; m <= my numberOfColumns; m++) { *mu += v[m] * my centroid[m]; } } double Covariances_getMultivariateCentroidDifference (Covariance me, Covariance thee, int equalCovariances, double *prob, double *fisher, double *df1, double *df2) { long p = my numberOfRows, N = (long) floor (my numberOfObservations + thy numberOfObservations); long N1 = (long) floor (my numberOfObservations), n1 = N1 - 1; long N2 = (long) floor (thy numberOfObservations), n2 = N2 - 1; double dif = *prob = *fisher = NUMundefined; *df1 = p; *df2 = N - p - 1; if (*df2 < 1) { Melder_throw (U"Not enough observations (", N, U") for this test."); } if (N1 < p || N2 < p) { Melder_throw (U"At least one of the covariances has less observations than variables."); } dif = 0; for (long i = 1; i <= p; i++) { double dist = my centroid[i] - thy centroid[i]; dif += dist * dist; } dif = sqrt (dif); if (equalCovariances) { // Morrison, page 141 autoCovariance pool = Covariances_pool (me, thee); autoNUMmatrix s (NUMmatrix_copy (my data, 1, p, 1, p), 1, 1); double lndet; NUMlowerCholeskyInverse (s.peek(), p, &lndet); double mahalanobis = NUMmahalanobisDistance_chi (s.peek(), my centroid, thy centroid, p, p); double hotelling_tsq = mahalanobis * N1 * N2 / N; *fisher = hotelling_tsq * *df2 / ( (N - 2) * *df1); } else { /* Krishnamoorthy-Yu (2004): Modified Nel and Van der Merwe test Hotelling t^2 = (x1-x2)'*S^-1*(x1 -x2) follows nu*p*Fisher(p,nu-p+1)/(nu-p+1) Approximate number of degrees of freedom (their formula 7, page 164) nu = (p+p^2)/((1/n1)(tr (S1*S^-1)^2 + (tr(S1*S^-1))^2)) +(1/n2)(tr (S2*S^-1)^2 + (tr(S2*S^-1))^2))) the matrices S1 and S2 are the covariance matrices 'my data' and 'thy data' divided by N1 and N2 respectively. S is the pooled covar divided by N. */ autoNUMmatrix s1 (1, p, 1, p); autoNUMmatrix s2 (1, p, 1, p); autoNUMmatrix s (1, p, 1, p); for (long i = 1; i <= p; i++) { for (long j = 1; j <= p; j++) { s1[i][j] = my data[i][j] / my numberOfObservations; s2[i][j] = thy data[i][j] / thy numberOfObservations; s[i][j] = s1[i][j] + s2[i][j]; } } double lndet; NUMlowerCholeskyInverse (s.peek(), p, &lndet); // Krishan... formula 2, page 162 double hotelling_tsq = NUMmahalanobisDistance_chi (s.peek(), my centroid, thy centroid, p, p); autoNUMmatrix si (NUMinverseFromLowerCholesky (s.peek(), p), 1, 1); double tr_s1sisqr = traceOfSquaredMatrixProduct (s1.peek(), si.peek(), p); double tr_s1si = NUMtrace2 (s1.peek(), si.peek(), p); double tr_s2sisqr = traceOfSquaredMatrixProduct (s2.peek(), si.peek(), p); double tr_s2si = NUMtrace2 (s2.peek(), si.peek(), p); double nu = (p + p * p) / ( (tr_s1sisqr + tr_s1si * tr_s1si) / n1 + (tr_s2sisqr + tr_s2si * tr_s2si) / n2); *df2 = nu - p + 1; *fisher = hotelling_tsq * (nu - p + 1) / (nu * p); } *prob = NUMfisherQ (*fisher, *df1, *df2); return dif; } /* Schott 2001 */ void Covariances_equality (Collection me, int method, double *prob, double *chisq, double *df) { try { long nc = my size; double nsi = 0.0; *prob = *chisq = *df = NUMundefined; if (nc < 2) { Melder_throw (U"We need at least two matrices"); } long p = 1, ns = 0; for (long i = 1; i <= nc; i++) { Covariance ci = (Covariance) my item[i]; double ni = ci -> numberOfObservations - 1; if (i == 1) { p = ci -> numberOfRows; } if (ci -> numberOfRows != p) { Melder_throw (U"The dimensions of matrix ", i, U" differ from the previous one(s)."); } if (ni < p) { Melder_throw (U"The number of observations in matrix ", i, U" is less than the number of variables. "); } ns += ni; nsi += 1.0 / ni; } autoNUMmatrix s (1, p, 1, p); for (long i = 1; i <= nc; i++) { // pool Covariance ci = (Covariance) my item[i]; double sf = (ci -> numberOfObservations - 1.0) / ns; for (long j = 1; j <= p; j++) { for (long k = 1; k <= p; k++) { s[j][k] += sf * ci -> data[j][k]; } } } if (method == 1) { // bartlett (see Morrison page 297) double lnd; try { NUMdeterminant_cholesky (s.peek(), p, &lnd); } catch (MelderError) { Melder_throw (U"Pooled covariance matrix is singular."); } double m = ns * lnd; for (long i = 1; i <= nc; i++) { Covariance ci = (Covariance) my item[i]; try { NUMdeterminant_cholesky (ci -> data, p, &lnd); } catch (MelderError) { Melder_throw (U"Covariance matrix ", i, U" is singular."); } m -= (ci -> numberOfObservations - 1) * lnd; } double c1 = 1.0 - (2.0 * p * p + 3.0 * p - 1.0) / (6.0 * (p + 1) * (nc - 1)) * (nsi - 1 / ns); *df = (nc - 1.0) * p * (p + 1) / 2.0; *chisq = m * c1; } else if (method == 2) { // Schott (2001) Wald 1 // sum(i, ni/n *tr((si*s^-1)^2)- sum(i,sum(j, (ni/n)*(nj/n) *tr(si*s^-1*sj*s^-1))) = // sum(i=1..k, (ni/n -(ni/n)^2) tr((si*s^-1)^2) // - 2 * sum (i=1..k, sum(j=1..i-1, (ni/n)*(nj/n) *tr(si*s^-1*sj*s^-1))) double trace = 0; NUMlowerCholeskyInverse (s.peek(), p, nullptr); autoNUMmatrix si (NUMinverseFromLowerCholesky (s.peek(), p), 1, 1); for (long i = 1; i <= nc; i++) { Covariance ci = (Covariance) my item[i]; double ni = ci -> numberOfObservations - 1; autoNUMmatrix s1 (productOfSquareMatrices (ci -> data, si.peek(), p), 1, 1); double trace_ii = NUMtrace2 (s1.peek(), s1.peek(), p); trace += (ni / ns) * (1 - (ni / ns)) * trace_ii; for (long j = i + 1; j <= nc; j++) { Covariance cj = (Covariance) my item[j]; double nj = cj -> numberOfObservations - 1; autoNUMmatrix s2 (productOfSquareMatrices (cj -> data, si.peek(), p), 1, 1); double trace_ij = NUMtrace2 (s1.peek(), s2.peek(), p); trace -= 2.0 * (ni / ns) * (nj / ns) * trace_ij; } } *df = (nc - 1) * p * (p + 1) / 2.0; *chisq = (ns / 2.0) * trace; } else { return; } *prob = NUMchiSquareQ (*chisq, *df); } catch (MelderError) { Melder_throw (U"Equality coud not be tested."); } } void Covariance_difference (Covariance me, Covariance thee, double *prob, double *chisq, long *ndf) { long p = my numberOfRows; long numberOfObservations = (long) floor (my numberOfObservations); double ln_me, ln_thee; if (my numberOfRows != thy numberOfRows) { Melder_throw (U"Matrices must have equal dimensions."); } if (my numberOfObservations != thy numberOfObservations) { numberOfObservations = (long) floor (my numberOfObservations > thy numberOfObservations ? thy numberOfObservations : my numberOfObservations) - 1; Melder_warning (U"Covariance_difference: number of observations of matrices do not agree.\n" U" The minimum size (", numberOfObservations, U") of the two is used."); } if (numberOfObservations < 2) { Melder_throw (U"Number of observations too small."); } autoNUMmatrix linv (NUMmatrix_copy (thy data, 1, p, 1, p), 1, 1); NUMlowerCholeskyInverse (linv.peek(), p, & ln_thee); NUMdeterminant_cholesky (my data, p, &ln_me); /* We need trace (A B^-1). We have A and the inverse L^(-1) of the cholesky decomposition L^T L of B in the lower triangle + diagonal. Always: tr (A B) = tr (B A) tr (A B^-1) = tr (A (L L^T)^-1) = tr (A L^-1 (L^T)^-1) trace = sum(i=1..p, j=1..p, l=max(i,j)..p, A[i][j]Lm[l][j]Lm[l][i], where Lm = L^(-1) */ double trace = 0.0; for (long i = 1; i <= p; i++) { for (long j = 1; j <= p; j++) { long lp = MAX (j, i); for (long l = lp; l <= p; l++) { trace += my data[i][j] * linv[l][j] * linv[l][i]; } } } double l = (numberOfObservations - 1) * fabs (ln_thee - ln_me + trace - p); *chisq = l * fabs (1.0 - (2.0 * p + 1.0 - 2.0 / (p + 1)) / (numberOfObservations - 1) / 6.0); *ndf = p * (p + 1) / 2; *prob = NUMchiSquareQ (*chisq, *ndf); } static void checkOneIndex (TableOfReal me, long index) { if (index < 1 || index > my numberOfColumns) { Melder_throw (U"Index must be in interval [1, ", my numberOfColumns, U"]."); } } static void checkTwoIndices (TableOfReal me, long index1, long index2) { if (index1 < 1 || index1 > my numberOfColumns || index2 < 1 || index2 > my numberOfColumns) { Melder_throw (U"Index must be in interval [1, ", my numberOfColumns, U"]."); } if (index1 == index2) { Melder_throw (U"Indices must be different."); } } void Covariance_getSignificanceOfOneMean (Covariance me, long index, double mu, double *probability, double *t, double *ndf) { double var; *probability = *t = NUMundefined; *ndf = my numberOfObservations - 1; checkOneIndex (me, index); if ( (var = my data[index][index]) == 0.0) { return; } *t = (my centroid[index] - mu) / sqrt (var / my numberOfObservations); *probability = 2.0 * NUMstudentQ (fabs (*t), *ndf); } void Covariance_getSignificanceOfMeansDifference (Covariance me, long index1, long index2, double mu, int paired, int equalVariances, double *probability, double *t, double *ndf) { long n = (long) floor (my numberOfObservations); double df, var1, var2, var_pooled; *probability = *t = NUMundefined; *ndf = 2.0 * (n - 1); checkTwoIndices (me, index1, index2); var1 = my data[index1][index1]; var2 = my data[index2][index2]; var_pooled = var1 + var2; if (var_pooled == 0) { Melder_warning (U"The pooled variance turned out to be zero. Check your data. "); return; } if (paired) { var_pooled -= 2.0 * my data[index1][index2]; *ndf /= 2.0; } if (var_pooled == 0.0) { Melder_warning (U"The pooled variance with the paired correction turned out to be zero. "); *probability = 0.0; return; } *t = (my centroid[index1] - my centroid[index2] - mu) / sqrt (var_pooled / n); /* Return two sided probabilty. */ if (equalVariances) { *probability = 2.0 * NUMstudentQ (fabs (*t), *ndf); } else { df = (1.0 + 2.0 * var1 * var2 / (var1 * var1 + var2 * var2)) * (n - 1); *probability = NUMincompleteBeta (df / 2.0, 0.5, df / (df + (*t) * (*t))); *ndf = df; } } void Covariance_getSignificanceOfOneVariance (Covariance me, long index, double sigmasq, double *probability, double *chisq, long *ndf) { double var; *probability = *chisq = NUMundefined; *ndf = (long) floor (my numberOfObservations) - 1; checkOneIndex (me, index); if ((var = my data[index][index]) == 0.0) { return; } *chisq = *ndf; if (sigmasq != 0.0) { *chisq = *ndf * var / sigmasq; } *probability = NUMchiSquareQ (*chisq, *ndf); } void Covariance_getSignificanceOfVariancesRatio (Covariance me, long index1, long index2, double ratio, double *probability, double *f, long *ndf) { long n = (long) floor (my numberOfObservations); double var1, var2, ratio2; *ndf = n - 1; *probability = *f = NUMundefined; checkTwoIndices (me, index1, index2); var1 = my data[index1][index1]; var2 = my data[index2][index2]; if (var1 == 0.0 || var2 == 0.0) { return; } *f = ratio2 = (var1 / var2) / ratio; if (var2 > var1) { ratio2 = (var2 / var1) * ratio; } *probability = 2.0 * NUMfisherQ (ratio2, *ndf, *ndf); if (*probability > 1.0) { *probability = 2.0 - *probability; } } TableOfReal Correlation_confidenceIntervals (Correlation me, double confidenceLevel, long numberOfTests, int method) { try { long m_bonferroni = my numberOfRows * (my numberOfRows - 1) / 2; if (confidenceLevel <= 0 || confidenceLevel > 1.0) { Melder_throw (U"Confidence level must be in interval (0-1)."); } if (my numberOfObservations < 5) { Melder_throw (U"The number of observations must be greater than 4."); } if (numberOfTests < 0) { Melder_throw (U"The \"number of tests\" cannot be less than zero."); } else if (numberOfTests == 0) { numberOfTests = m_bonferroni; } if (numberOfTests > m_bonferroni) { Melder_warning (U"The \"number of tests\" exceeds the number of elements in the Correlation object."); } autoTableOfReal thee = TableOfReal_create (my numberOfRows, my numberOfRows); TableOfReal_copyLabels (me, thee.peek(), 1, 1); // Obtain large-sample conservative multiple tests and intervals by the // Bonferroni inequality and the Fisher z transformation. // Put upper value of confidence intervals in upper part and lower // values of confidence intervals in lower part of resulting table. double z = NUMinvGaussQ ( (1 - confidenceLevel) / (2.0 * numberOfTests)); double zf = z / sqrt (my numberOfObservations - 3.0); double two_n = 2.0 * my numberOfObservations; for (long i = 1; i <= my numberOfRows; i++) { for (long j = i + 1; j <= my numberOfRows; j++) { double rij = my data[i][j], rmin, rmax; if (method == 2) { // Fisher's approximation double zij = 0.5 * log ( (1 + rij) / (1 - rij)); rmax = tanh (zij + zf); rmin = tanh (zij - zf); } else if (method == 1) { // Ruben's approximation double rs = rij / sqrt (1.0 - rij * rij); double a = two_n - 3.0 - z * z; double b = rs * sqrt ( (two_n - 3.0) * (two_n - 5.0)); double c = (a - 2.0) * rs * rs - 2.0 * z * z; // Solve: a y^2 - 2b y + c = 0 // q = -0.5((-2b) + sgn(-2b) sqrt((-2b)^2 - 4ac)) // y1 = q/a; y2 = c/q; double q, d = sqrt (b * b - a * c); if (b > 0) { d = - d; } q = b - d; rmin = q / a; rmin /= sqrt (1.0 + rmin * rmin); rmax = c / q; rmax /= sqrt (1.0 + rmax * rmax); if (rmin > rmax) { double t = rmin; rmin = rmax; rmax = t; } } else { rmax = rmin = 0; } thy data[i][j] = rmax; thy data[j][i] = rmin; } thy data[i][i] = 1; } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": confidence intervals not created."); } } void SSCP_testDiagonality_bartlett (SSCP me, long numberOfContraints, double *chisq, double *probability) { *chisq = *probability = NUMundefined; autoCorrelation c = SSCP_to_Correlation (me); Correlation_testDiagonality_bartlett (c.peek(), numberOfContraints, chisq, probability); } /* Morrison, page 118 */ void Correlation_testDiagonality_bartlett (Correlation me, long numberOfContraints, double *chisq, double *probability) { *chisq = *probability = NUMundefined; if (numberOfContraints <= 0) { numberOfContraints = 1; } if (numberOfContraints > my numberOfObservations) { Melder_warning (U"Correlation_testDiagonality_bartlett: number of constraints cannot exceed the number of observations."); return; } long p = my numberOfRows; double ln_determinant; NUMdeterminant_cholesky (my data, p, &ln_determinant); *chisq = - ln_determinant * (my numberOfObservations - numberOfContraints - (2.0 * p + 5.0) / 6.0); *probability = NUMchiSquareQ (*chisq, p * (p - 1) / 2.0); } void SSCP_expand (SSCP me) { // A reduced matrix has my numberOfRows < my numberOfColumns. // After expansion: // my numberOfRows == my numberOfColumns // my storageNumberOfRows = my numberOfRows (before) // my data (after) = my expansion; // my expansion = my data (before) // No expansion for a standard matrix or if already expanded and data has not changed! if ((my expansionNumberOfRows == 0 && my numberOfRows == my numberOfColumns) || (my expansionNumberOfRows > 0 && ! my dataChanged)) { return; } if (my expansion == 0) { my expansion = NUMmatrix (1, my numberOfColumns, 1, my numberOfColumns); } for (long ir = 1; ir <= my numberOfColumns; ir++) { for (long ic = ir; ic <= my numberOfColumns; ic++) { long dij = labs (ir - ic); my expansion[ir][ic] = my expansion[ic][ir] = dij < my numberOfRows ? my data[dij + 1][ic] : 0.0; } } // Now make 'my data' point to 'my expansion' double **tmp = my data; my data = my expansion; my expansion = tmp; my expansionNumberOfRows = my numberOfRows; my numberOfRows = my numberOfColumns; // Now forget(me) is save my dataChanged = 0; } void SSCP_unExpand (SSCP me) { if (my expansionNumberOfRows == 0) { return; } NUMmatrix_free (my data, 1, 1); my data = my expansion; my expansion = nullptr; my numberOfRows = my expansionNumberOfRows; my expansionNumberOfRows = 0; my dataChanged = 0; } void SSCP_expandLowerCholesky (SSCP me) { if (! my lowerCholesky) { my lowerCholesky = NUMmatrix (1, my numberOfRows, 1, my numberOfColumns); } if (my numberOfRows == 1) { // diagonal my lnd = 0.0; for (long j = 1; j <= my numberOfColumns; j++) { my lowerCholesky[1][j] = 1.0 / sqrt (my data[1][j]); // inverse is 1/stddev my lnd += log (my data[1][j]); // diagonal elmnt is variance } } else { for (long i = 1; i <= my numberOfRows; i++) { for (long j = i; j <= my numberOfColumns; j++) { my lowerCholesky[j][i] = my lowerCholesky[i][j] = my data[i][j]; } } try { NUMlowerCholeskyInverse (my lowerCholesky, my numberOfColumns, & (my lnd)); } catch (MelderError) { // singular matrix: arrange a diagonal only inverse. my lnd = 0.0; for (long i = 1; i <= my numberOfRows; i++) { for (long j = i; j <= my numberOfColumns; j++) { my lowerCholesky[i][j] = my lowerCholesky[j][i] = i == j ? 1.0 / sqrt (my data[i][i]) : 0.0; } my lnd += log (my data[i][i]); } my lnd *= 2.0; } } } void SSCP_unExpandLowerCholesky (SSCP me) { NUMmatrix_free (my lowerCholesky, 1, 1); my lnd = 0.0; } void SSCP_expandPCA (SSCP me) { if (my pca) { forget (my pca); } my pca = SSCP_to_PCA (me); } void SSCP_unExpandPCA (SSCP me) { forget (my pca); } #undef MAX #undef MIN /* End of file SSCP.c */ praat-6.0.04/dwtools/SSCP.h000066400000000000000000000223611261542461700153400ustar00rootroot00000000000000#ifndef _SSCP_h_ #define _SSCP_h_ /* SSCP.h * * Copyright (C) 1993-2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "TableOfReal_extensions.h" #include "PCA.h" #include "CCA.h" #include "SSCP_def.h" oo_CLASS_CREATE (SSCP, TableOfReal); Thing_define (Covariance, SSCP) { }; Thing_define (Correlation, SSCP) { }; /* Ordered collection of SSCP's All SSCP's must have the same dimensions and labels. */ Thing_define (SSCPs, Ordered) { }; void SSCP_init (SSCP me, long dimension, long storage); SSCP SSCP_create (long dimension); void SSCP_drawTwoDimensionalEllipse_inside (SSCP me, Graphics g, double scale, char32 * label, int fontSize); double SSCP_getEllipseScalefactor (SSCP me, double scale, bool confidence); void SSCP_drawConcentrationEllipse (SSCP me, Graphics g, double scale, int confidence, long d1, long d2, double xmin, double xmax, double ymin, double ymax, int garnish); void SSCP_setNumberOfObservations (SSCP me, double numberOfObservations); void SSCP_setCentroid (SSCP me, long component, double value); // only SSCP & Covariance void SSCP_setValue (SSCP me, long row, long col, double value); // only SSCP & Covariance double SSCP_getNumberOfObservations (SSCP me); double SSCP_getDegreesOfFreedom (SSCP me); double SSCP_getTotalVariance (SSCP me); double SSCP_getCumulativeContributionOfComponents (SSCP me, long from, long to); double SSCP_getLnDeterminant (SSCP me); double SSCP_getConcentrationEllipseArea(SSCP me, double scale, bool confidence, long d1, long d2); double SSCP_getFractionVariation (SSCP me, long from, long to); SSCP TableOfReal_to_SSCP (TableOfReal me, long rowb, long rowe, long colb, long cole); TableOfReal SSCP_and_TableOfReal_extractDistanceQuantileRange (SSCP me, TableOfReal thee, double qlow, double qhigh); TableOfReal Covariance_and_TableOfReal_extractDistanceQuantileRange (Covariance me, TableOfReal thee, double qlow, double qhigh); /* Select from a TableOfReal the rows whose Mahalanobis distance to the centroid (from the SSCP) is in the quantile [qlow, qhigh]. */ TableOfReal Covariance_and_TableOfReal_mahalanobis (Covariance me, thou, bool useTableCentroid); /* Calculate the Mahalanobis distance: sqrt ((x-m)'S**-1 (x-m)) use the m-vector (centroid) from the covariance unless useTableColumnMeans is true. */ Covariance TableOfReal_to_Covariance (TableOfReal me); Correlation TableOfReal_to_Correlation (TableOfReal me); Correlation TableOfReal_to_Correlation_rank (TableOfReal me); TableOfReal SSCP_to_TableOfReal (SSCP me); TableOfReal SSCP_extractCentroid (SSCP me); TableOfReal Covariance_to_TableOfReal_randomSampling (Covariance me, long numberOfData); /* Generate a table with data based on the covariance matrix */ void Covariance_and_PCA_generateOneVector (Covariance me, PCA thee, double *vec, double *buf); /* A convenience function to avoid the calculation of the PCA each time we want to generate a random vector The PCA must be the result of a previous SSCP_to_PCA call ! The covariance matrix must not be singular or diagonal! Returns the random sampled vector in vec (which must be of size my numberOfColumns). Preconditions: 1. Covariance may not be in diagonal representation (1 row) 2. Dimensions of me and PCA agree 3. vec is of length my numberOfColumns 4. buf, a vector of length my numberOfColumns, is needed so the routine cannot fail */ SSCPs TableOfReal_to_SSCPs_byLabel (TableOfReal me); PCA SSCP_to_PCA (SSCP me); void SSCP_expandPCA (SSCP me); void SSCP_unExpandPCA (SSCP me); autoCCA SSCP_to_CCA (SSCP me, long ny); Covariance Covariance_create (long dimension); Covariance Covariance_createSimple (char32 *covars, char32 *centroid, long numberOfObservations); Covariance Covariance_create_reduceStorage (long dimension, long storage); /* storage 0 or >= dimension: complete matrix storage 1: only diagonal storage 2: diagonal + 1 off-diagonal [i,i+1] storage 3: diagonal + off-diagonal [i,i+1] + off-diagonal [i,i+2] .... storage dimension : complete matrix See also SSCP_expand () for usage. */ Correlation Correlation_create (long dimension); TableOfReal Correlation_confidenceIntervals (Correlation me, double confidenceLevel, long numberOfTests, int method); /* if (method == 1) Confidence intervals by Ruben's approximation if (method == 2) Obtain large-sample conservative multiple tests and intervals by the Bonferroni inequality and the Fisher z transformation. Put upper value of confidence intervals in upper matrix and lower values of confidence intervals in lower part of resulting table. Diagonal values are 1 (and represent both upper and lower c.i.). */ /* Precondition ||vector|| = 1 */ void Covariance_getMarginalDensityParameters (Covariance me, double *vector, double *mu, double *stdev); double Covariance_getMarginalProbabilityAtPosition (Covariance me, double *vector, double x); double Covariance_getProbabilityAtPosition_string (Covariance me, char32 *xpos); double Covariance_getProbabilityAtPosition (Covariance me, double *x); /* evaluate the pdf(x,mu,Sigma) at x */ Covariance SSCP_to_Covariance (SSCP me, long numberOfConstraints); SSCP Covariance_to_SSCP (Covariance me); void SSCP_testDiagonality_bartlett (SSCP me, long numberOfContraints, double *chisq, double *probability); void Correlation_testDiagonality_bartlett (Correlation me, long numberOfContraints, double *chisq, double *probability); /* Test whether matrices are diagonal matrices, Morrison, page 118 */ Correlation SSCP_to_Correlation (SSCP me); Configuration SSCP_to_Configuration (SSCP me, long numberOfDimensions); Configuration Covariance_to_Configuration (Covariance me, long numberOfDimensions); Configuration Correlation_to_Configuration (Correlation me, long numberOfDimensions); void Covariance_difference (Covariance me, Covariance thee, double *prob, double *chisq, long *ndf); void Covariance_getSignificanceOfOneMean (Covariance me, long index, double mu, double *probability, double *t, double *ndf); void Covariance_getSignificanceOfMeansDifference (Covariance me, long index1, long index2, double mu, int paired, int equalVariances, double *probability, double *t, double *ndf); void Covariance_getSignificanceOfOneVariance (Covariance me, long index, double sigmasq, double *probability, double *chisq, long *ndf); void Covariance_getSignificanceOfVariancesRatio (Covariance me, long index1, long index2, double ratio, double *probability, double *f, long *ndf); double Covariances_getMultivariateCentroidDifference (Covariance me, Covariance thee, int equalCovariances, double *prob, double *fisher, double *df1, double *df2); /* Are the centroids of me and thee different? Assumption: the two covariances are equal. (we pool me and thee, dimension p). Two sample test of Morrison (1990), page 141: T^2 = n1*n2/(n1+n2) (m1-m2)'S^-1(m1-m2) # weighted Mahalanobis distance f = T^2 * (n1+n2-p-1)/((n1+n2-2)*p) f has Fisher distribution with p and n1+n2-p-1 degrees of freedom. */ void Covariances_equality (Collection me, int method, double *prob, double *chisq, double *df); /* Equality of covariance. method = 1 : Bartlett (Morrison, 1990) method = 2 : Wald (Schott, 2001) */ SSCPs SSCPs_create (); SSCPs TableOfReal_to_SSCPs_byLabel (TableOfReal me); SSCP SSCPs_to_SSCP_sum (SSCPs me); /* Sum the sscp's and weigh each means with it's numberOfObservations. */ SSCP SSCPs_to_SSCP_pool (SSCPs me); void SSCPs_getHomegeneityOfCovariances_box (SSCPs me, double *probability, double *chisq, long *ndf); SSCP SSCP_toTwoDimensions (SSCP me, double *v1, double *v2); SSCPs SSCPs_toTwoDimensions (SSCPs me, double *v1, double *v2); SSCPs SSCPs_extractTwoDimensions (SSCPs me, long d1, long d2); /* For inheritors */ void SSCPs_drawConcentrationEllipses (SSCPs me, Graphics g, double scale, int confidence, const char32 *label, long d1, long d2, double xmin, double xmax, double ymin, double ymax, int fontSize, int garnish); void SSCPs_getEllipsesBoundingBoxCoordinates (SSCPs me, double scale, int confidence, double *xmin, double *xmax, double *ymin, double *ymax); void SSCP_expand (SSCP me); /* Expand a reduced storage SSCP. For efficiency reasons, the expanded matrix is kept in memory. Successive calls to SSCP_expand don't change anything unless Before using one of the Covariance functions defined here on a reduced matrix we first have to expand it to normal size. Covariance me = Covariance_create_reduceStorage (dimension, 1); // diagonal only ... SSCP_expand (me); PCA thee = SSCP_to_PCA (me); */ void SSCP_unExpand (SSCP me); /* Use only if the memory is really needed! */ void SSCP_expandLowerCholesky (SSCP me); // create lower square root of covariance matrix void SSCP_unExpandLowerCholesky (SSCP me); #endif /* _SSCP_h_ */ praat-6.0.04/dwtools/SSCP_def.h000066400000000000000000000030011261542461700161440ustar00rootroot00000000000000/* SSCP_def.h * * Copyright (C) 1993-2010 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT SSCP oo_DEFINE_CLASS (SSCP, TableOfReal) oo_DOUBLE (numberOfObservations) oo_DOUBLE_VECTOR (centroid, numberOfColumns) /* The following definitions are only needed when we want to use many big diagonal or almost diagonal matrices like for example in a GaussianMixture, or for efficiently calculating many times a distance like a'S^(-1)a */ #if !oo_READING && !oo_WRITING oo_LONG (expansionNumberOfRows) oo_INT (dataChanged) oo_DOUBLE_MATRIX (expansion, expansionNumberOfRows, numberOfColumns) oo_DOUBLE (lnd) oo_DOUBLE_MATRIX (lowerCholesky, numberOfColumns, numberOfColumns) oo_OBJECT (PCA, 0, pca) #endif #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (SSCP) #undef ooSTRUCT /* End of file SSCP_def.h */ praat-6.0.04/dwtools/Sampled2.cpp000066400000000000000000000124471261542461700165760ustar00rootroot00000000000000/* Sampled2.cpp * * Copyright (C) 1993-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Sampled2.h" #include "NUM2.h" #include "oo_DESTROY.h" #include "Sampled2_def.h" #include "oo_COPY.h" #include "Sampled2_def.h" #include "oo_EQUAL.h" #include "Sampled2_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Sampled2_def.h" #include "oo_WRITE_TEXT.h" #include "Sampled2_def.h" #include "oo_WRITE_BINARY.h" #include "Sampled2_def.h" #include "oo_READ_BINARY.h" #include "Sampled2_def.h" #include "oo_DESCRIPTION.h" #include "Sampled2_def.h" Thing_implement (Sampled2, Sampled, 0); void structSampled2 :: v_readText (MelderReadText text, int /*formatVersion*/) { xmin = texgetr8 (text); xmax = texgetr8 (text); nx = texgeti4 (text); dx = texgetr8 (text); x1 = texgetr8 (text); ymin = texgetr8 (text); ymax = texgetr8 (text); ny = texgeti4 (text); dy = texgetr8 (text); y1 = texgetr8 (text); if (xmin > xmax || ymin > ymax) { Melder_throw (U"xmax should be greater than xmax and ymax should be greater than ymin."); } if (nx < 1 || ny < 1) { Melder_throw (U"nx and ny should be at least 1."); } if (dx <= 0 || dy <= 0) { Melder_throw (U"dx and dy should be positive."); } } void Sampled2_init (I, double xmin, double xmax, long nx, double dx, double x1, double ymin, double ymax, long ny, double dy, double y1) { iam (Sampled2); my xmin = xmin; my xmax = xmax; my nx = nx; my dx = dx; my x1 = x1; my ymin = ymin; my ymax = ymax; my ny = ny; my dy = dy; my y1 = y1; } double Sampled2_columnToX (I, double column) { iam (Sampled2); return my x1 + (column - 1) * my dx; } double Sampled2_rowToY (I, double row) { iam (Sampled2); return my y1 + (row - 1) * my dy; } double Sampled2_xToColumn (I, double x) { iam (Sampled2); return (x - my x1) / my dx + 1; } long Sampled2_xToLowColumn (I, double x) { iam (Sampled2); return (long) floor (Sampled2_xToColumn (me, x)); } long Sampled2_xToHighColumn (I, double x) { iam (Sampled2); return (long) ceil (Sampled2_xToColumn (me, x)); } long Sampled2_xToNearestColumn (I, double x) { iam (Sampled2); return (long) floor (Sampled2_xToColumn (me, x) + 0.5); } double Sampled2_yToRow (I, double y) { iam (Sampled2); return (y - my y1) / my dy + 1; } long Sampled2_yToLowRow (I, double y) { iam (Sampled2); return (long) floor (Sampled2_yToRow (me, y)); } long Sampled2_yToHighRow (I, double y) { iam (Sampled2); return (long) ceil (Sampled2_yToRow (me, y)); } long Sampled2_yToNearestRow (I, double y) { iam (Sampled2); return (long) floor (Sampled2_yToRow (me, y) + 0.5); } long Sampled2_getWindowSamplesX (I, double xmin, double xmax, long *ixmin, long *ixmax) { iam (Sampled2); *ixmin = 1 + (long) ceil ( (xmin - my x1) / my dx); *ixmax = 1 + (long) floor ( (xmax - my x1) / my dx); if (*ixmin < 1) { *ixmin = 1; } if (*ixmax > my nx) { *ixmax = my nx; } if (*ixmin > *ixmax) { return 0; } return *ixmax - *ixmin + 1; } long Sampled2_getWindowSamplesY (I, double ymin, double ymax, long *iymin, long *iymax) { iam (Sampled2); *iymin = 1 + (long) ceil ( (ymin - my y1) / my dy); *iymax = 1 + (long) floor ( (ymax - my y1) / my dy); if (*iymin < 1) { *iymin = 1; } if (*iymax > my ny) { *iymax = my ny; } if (*iymin > *iymax) { return 0; } return *iymax - *iymin + 1; } long Sampled2_getWindowExtrema_d (I, double **z, long ixmin, long ixmax, long iymin, long iymax, double *minimum, double *maximum) { iam (Sampled2); if (ixmin == 0) { ixmin = 1; } if (ixmax == 0) { ixmax = my nx; } if (iymin == 0) { iymin = 1; } if (iymax == 0) { iymax = my ny; } if (ixmin > ixmax || iymin > iymax) { return 0; } *minimum = *maximum = z[iymin][ixmin]; for (long iy = iymin; iy <= iymax; iy ++) for (long ix = ixmin; ix <= ixmax; ix ++) { if (z[iy][ix] < *minimum) { *minimum = z[iy][ix]; } if (z[iy][ix] > *maximum) { *maximum = z[iy][ix]; } } return (ixmax - ixmin + 1) * (iymax - iymin + 1); } long Sampled2_getWindowExtrema_f (I, float **z, long ixmin, long ixmax, long iymin, long iymax, double *minimum, double *maximum) { iam (Sampled2); if (ixmin == 0) { ixmin = 1; } if (ixmax == 0) { ixmax = my nx; } if (iymin == 0) { iymin = 1; } if (iymax == 0) { iymax = my ny; } if (ixmin > ixmax || iymin > iymax) { return 0; } *minimum = *maximum = z[iymin] [ixmin]; for (long iy = iymin; iy <= iymax; iy ++) for (long ix = ixmin; ix <= ixmax; ix ++) { if (z[iy][ix] < *minimum) { *minimum = z[iy][ix]; } if (z[iy][ix] > *maximum) { *maximum = z[iy][ix]; } } return (ixmax - ixmin + 1) * (iymax - iymin + 1); } /* End of file Sampled2.cpp */ praat-6.0.04/dwtools/Sampled2.h000066400000000000000000000060771261542461700162450ustar00rootroot00000000000000#ifndef _Sampled2_h_ #define _Sampled2_h_ /* Sampled2.h * * Copyright (C) 1993-2011 David Weenink & Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Sampled.h" #include "Sampled2_def.h" oo_CLASS_CREATE (Sampled2, Sampled); void Sampled2_init (I, double xmin, double xmax, long nx, double dx, double x1, double ymin, double ymax, long ny, double dy, double y1); long Sampled2_getWindowSamplesX (I, double xmin, double xmax, long *ixmin, long *ixmax); /* Function: return the number of samples with x values in [xmin, xmax]. Put the first of these samples in ixmin. Put the last of these samples in ixmax. Postconditions: *ixmin >= 1; *ixmax <= my nx; if (result != 0) *ixmin <= *ixmax; else *ixmin > *ixmax; if (result != 0) result == *ixmax - *ixmin + 1; */ double Sampled2_columnToX (I, double column); /* Return my x1 + (column - 1) * my dx. */ double Sampled2_rowToY (I, double row); /* Return my y1 + (row - 1) * my dy. */ double Sampled2_xToColumn (I, double x); /* Return (x - xmin) / my dx + 1. */ long Sampled2_xToLowColumn (I, double x); /* Return floor (Matrix_xToColumn (me, x)). */ long Sampled2_xToHighColumn (I, double x); /* Return ceil (Matrix_xToColumn (me, x)). */ long Sampled2_xToNearestColumn (I, double x); /* Return floor (Matrix_xToColumn (me, x) + 0.5). */ double Sampled2_yToRow (I, double y); /* Return (y - ymin) / my dy + 1. */ long Sampled2_yToLowRow (I, double y); /* Return floor (Matrix_yToRow (me, y)). */ long Sampled2_yToHighRow (I, double x); /* Return ceil (Matrix_yToRow (me, y)). */ long Sampled2_yToNearestRow (I, double y); /* Return floor (Matrix_yToRow (me, y) + 0.5). */ long Sampled2_getWindowSamplesY (I, double ymin, double ymax, long *iymin, long *iymax); /**** a little bit dangerous ******/ long Sampled2_getWindowExtrema_d (I, double **z, long ixmin, long ixmax, long iymin, long iymax, double *minimum, double *maximum); long Sampled2_getWindowExtrema_f (I, float **z, long ixmin, long ixmax, long iymin, long iymax, double *minimum, double *maximum); /* Function: compute the minimum and maximum values of z over all samples inside [ixmin, ixmax] * [iymin, iymax]. Arguments: if ixmin = 0, start at first column; if ixmax = 0, end at last column (same for iymin and iymax). Return value: the number of samples inside the window. Postconditions: if result == 0, *minimum and *maximum are not changed; */ #endif /* _Sampled2_h_ */ praat-6.0.04/dwtools/Sampled2_def.h000066400000000000000000000020131261542461700170450ustar00rootroot00000000000000/* Sampled2_def.h * * Copyright (C) 1993-2013 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19970408 djmw 20020813 GPL header */ #define ooSTRUCT Sampled2 oo_DEFINE_CLASS (Sampled2, Sampled) oo_DOUBLE (ymin) oo_DOUBLE (ymax) oo_LONG (ny) oo_DOUBLE (dy) oo_DOUBLE (y1) oo_END_CLASS (Sampled2) #undef ooSTRUCT /* End of file Sampled2_def.h */ praat-6.0.04/dwtools/Sound_and_PCA.cpp000066400000000000000000000110711261542461700175140ustar00rootroot00000000000000/* Sound_and_PCA.cpp * * Copyright (C) 2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20121001 */ #include "ICA.h" #include "Sound_and_PCA.h" #include "Sound_extensions.h" #include "NUM2.h" static void checkChannelsWithinRange (long *channels, long n, long min, long max) { for (long i = 1; i <= n; i++) { if (channels[i] < min || channels[i] > max) { Melder_throw (U"Channel ", channels[i], U" is not within range [", min, U", ", max, U"]."); } } } autoPCA Sound_to_PCA_channels (Sound me, double startTime, double endTime) { try { // covariance is cross-correlation with lag time 0 autoCrossCorrelationTable thee = Sound_to_CrossCorrelationTable (me, startTime, endTime, 0); autoPCA him = SSCP_to_PCA (thee.peek()); return him; } catch (MelderError) { Melder_throw (me, U": no PCA created."); } } autoSound Sound_and_PCA_to_Sound_pc_selectedChannels (Sound me, PCA thee, long numberOfComponents, long *channels, long numberOfChannels) { try { bool channelSelection = channels != 0 && numberOfChannels > 0; if (numberOfComponents <= 0 || numberOfComponents > thy numberOfEigenvalues) { numberOfComponents = thy numberOfEigenvalues; } numberOfComponents = numberOfComponents > my ny ? my ny : numberOfComponents; if (channelSelection) { checkChannelsWithinRange (channels, numberOfChannels, 1, my ny); } autoSound him = Data_copy (me); // R['i',j] = E(i,k]*S['k',j] // use kij-variant for faster inner loop for (long k = 1; k <= thy dimension; k++) { long channel_k = channelSelection ? channels[k] : k; for (long i = 1; i <= numberOfComponents; i++) { long channel_i = channelSelection ? channels[i] : i; double ev_ik = thy eigenvectors[i][k]; for (long j = 1; j <= my nx; j++) { his z[channel_i][j] += ev_ik * my z[channel_k][j]; } } } return him; } catch (MelderError) { Melder_throw (me, U": no principal components calculated with ", thee); } } autoSound Sound_and_PCA_principalComponents (Sound me, PCA thee, long numberOfComponents) { return Sound_and_PCA_to_Sound_pc_selectedChannels (me, thee, numberOfComponents, nullptr, 0); } autoSound Sound_and_PCA_whitenSelectedChannels (Sound me, PCA thee, long numberOfComponents, long *channels, long numberOfChannels) { try { bool channelSelection = channels != 0 && numberOfChannels > 0; if (numberOfComponents <= 0 || numberOfComponents > thy numberOfEigenvalues) { numberOfComponents = thy numberOfEigenvalues; } if (channelSelection) { checkChannelsWithinRange (channels, numberOfChannels, 1, my ny); } autoNUMmatrix whiten (1, thy dimension, 1, thy dimension); // W = E D^(-1/2) E' from http://cis.legacy.ics.tkk.fi/aapo/papers/IJCNN99_tutorialweb/node26.html for (long i = 1; i <= thy dimension; i++) { for (long j = i; j <= thy dimension; j++) { double wij = 0; for (long k = 1; k <= numberOfComponents; k++) { wij += thy eigenvectors[k][i] * thy eigenvectors[k][j] / sqrt (thy eigenvalues[k]); } whiten[i][j] = whiten[j][i] = wij; } } autoSound him = Sound_create (my ny, my xmin, my xmax, my nx, my dx, my x1); for (long k = 1; k <= numberOfChannels; k++) { long channel_k = channelSelection ? channels[k] : k; for (long i = 1; i <= numberOfChannels; i++) { long channel_i = channelSelection ? channels[i] : i; double w_ik = whiten[i][k]; for (long j = 1; j <= my nx; j++) { his z[channel_i][j] += w_ik * my z[channel_k][j]; } } } return him; } catch (MelderError) { Melder_throw (U"Sound not created."); } } autoSound Sound_and_PCA_whitenChannels (Sound me, PCA thee, long numberOfComponents) { return Sound_and_PCA_whitenSelectedChannels (me, thee, numberOfComponents, nullptr, 0); } /* End of file Sound_and_PCA.cpp */ praat-6.0.04/dwtools/Sound_and_PCA.h000066400000000000000000000026411261542461700171640ustar00rootroot00000000000000#ifndef _Sound_and_PCA_h_ #define _Sound_and_PCA_h_ /* Sound_and_PCA.h * * Copyright (C) 2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20121001 */ #include "PCA.h" #include "Sound.h" autoPCA Sound_to_PCA_channels (Sound me, double startTime, double endTime); autoSound Sound_and_PCA_to_Sound_pc_selectedChannels (Sound me, PCA thee, long numberOfComponents, long *channels, long numberOfChannels); autoSound Sound_and_PCA_principalComponents (Sound me, PCA thee, long numberOfComponents); autoSound Sound_and_PCA_whitenSelectedChannels (Sound me, PCA thee, long numberOfComponents, long *channels, long numberOfChannels); autoSound Sound_and_PCA_whitenChannels (Sound me, PCA thee, long numberOfComponents); #endif /* _Sound_and_PCA_h_ */ praat-6.0.04/dwtools/Sound_and_Spectrogram_extensions.cpp000066400000000000000000000336221261542461700236640ustar00rootroot00000000000000/* Sound_and_Spectrogram_extensions.cpp * * Copyright (C) 1993-2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20010718 djmw 20020813 GPL header. djmw 20041124 Changed call to Sound_to_Spectrum. djmw 20070103 Sound interface changes djmw 20071107 Errors/warnings text changes djmw 20071202 Melder_warning */ #include "Sound_and_Spectrogram_extensions.h" #include "Sound_extensions.h" #include "Sound_and_Spectrum.h" #include "Sound_to_Pitch.h" #include "Vector.h" #include "NUM2.h" #define MIN(m,n) ((m) < (n) ? (m) : (n)) // prototypes autoSound BandFilterSpectrogram_as_Sound (BandFilterSpectrogram me, int to_dB); /* The gaussian(x) = (exp(-48*((i-(n+1)/2)/(n+1))^2)-exp(-12))/(1-exp(-12)); For power we need the area under the square of this window: Integrate (gaussian(i)^2,i=1..n) = (sqrt(Pi)*sqrt(3)*sqrt(2)*erf(2*(n-1)*sqrt(3)*sqrt(2)/(n+1))*(n+1) + 24*exp(-24)*(n-1)+ -4*sqrt(Pi)*sqrt(3)*exp(-12)*erf(2*(n-1)*sqrt(3)/(n+1))*(n+1))/ (24 * (-1+exp(-12))^2), where erf(x) = 1 - erfc(x) and n is the windowLength in samples. To compare with the rectangular window we need to divide this by the window width (n -1) x 1^2. */ static void _Spectrogram_windowCorrection (Spectrogram me, long numberOfSamples_window) { double windowFactor = 1; if (numberOfSamples_window > 1) { double e12 = exp (-12); double denum = (e12 - 1) * (e12 - 1) * 24 * (numberOfSamples_window - 1); double arg1 = 2 * NUMsqrt3 * (numberOfSamples_window - 1) / (numberOfSamples_window + 1); double arg2 = arg1 * NUMsqrt2; double p2 = NUMsqrtpi * NUMsqrt3 * NUMsqrt2 * (1 - NUMerfcc (arg2)) * (numberOfSamples_window + 1); double p1 = 4 * NUMsqrtpi * NUMsqrt3 * e12 * (1 - NUMerfcc (arg1)) * (numberOfSamples_window + 1); windowFactor = (p2 - p1 + 24 * (numberOfSamples_window - 1) * e12 * e12) / denum; } for (long i = 1; i <= my ny; i++) { for (long j = 1; j <= my nx; j++) { my z[i][j] /= windowFactor; } } } static autoSpectrum Sound_to_Spectrum_power (Sound me) { try { autoSpectrum thee = Sound_to_Spectrum (me, true); double scale = 2.0 * thy dx / (my xmax - my xmin); // factor '2' because we combine positive and negative frequencies // thy dx : width of frequency bin // my xmax - my xmin : duration of sound double *re = thy z[1], *im = thy z[2]; for (long i = 1; i <= thy nx; i++) { double power = scale * (re[i] * re[i] + im[i] * im [i]); re[i] = power; im[i] = 0; } // Correction of frequency bins at 0 Hz and nyquist: don't count for two. re[1] *= 0.5; re[thy nx] *= 0.5; return thee; } catch (MelderError) { Melder_throw (me, U": no Spectrum with spectral power created."); } } static void Sound_into_BarkSpectrogram_frame (Sound me, BarkSpectrogram thee, long frame) { autoSpectrum him = Sound_to_Spectrum_power (me); long numberOfFrequencies = his nx; autoNUMvector z (1, numberOfFrequencies); for (long ifreq = 1; ifreq <= numberOfFrequencies; ifreq++) { double fhz = his x1 + (ifreq - 1) * his dx; z[ifreq] = thy v_hertzToFrequency (fhz); } for (long i = 1; i <= thy ny; i++) { double p = 0; double z0 = thy y1 + (i - 1) * thy dy; double *pow = his z[1]; // TODO ?? for (long ifreq = 1; ifreq <= numberOfFrequencies; ifreq++) { // Sekey & Hanson filter is defined in the power domain. // We therefore multiply the power with a (and not a^2). // integral (F(z),z=0..25) = 1.58/9 double a = NUMsekeyhansonfilter_amplitude (z0, z[ifreq]); p += a * pow[ifreq] ; } thy z[i][frame] = p; } } autoBarkSpectrogram Sound_to_BarkSpectrogram (Sound me, double analysisWidth, double dt, double f1_bark, double fmax_bark, double df_bark) { try { double nyquist = 0.5 / my dx, samplingFrequency = 2 * nyquist; double windowDuration = 2 * analysisWidth; /* gaussian window */ double zmax = NUMhertzToBark2 (nyquist); double fmin_bark = 0; // Check defaults. if (f1_bark <= 0) { f1_bark = 1; } if (fmax_bark <= 0) { fmax_bark = zmax; } if (df_bark <= 0) { df_bark = 1; } fmax_bark = MIN (fmax_bark, zmax); long numberOfFilters = lround ( (fmax_bark - f1_bark) / df_bark); if (numberOfFilters <= 0) { Melder_throw (U"The combination of filter parameters is not valid."); } long numberOfFrames; double t1; Sampled_shortTermAnalysis (me, windowDuration, dt, & numberOfFrames, & t1); autoSound sframe = Sound_createSimple (1, windowDuration, samplingFrequency); autoSound window = Sound_createGaussian (windowDuration, samplingFrequency); autoBarkSpectrogram thee = BarkSpectrogram_create (my xmin, my xmax, numberOfFrames, dt, t1, fmin_bark, fmax_bark, numberOfFilters, df_bark, f1_bark); autoMelderProgress progess (U"BarkSpectrogram analysis"); for (long iframe = 1; iframe <= numberOfFrames; iframe++) { double t = Sampled_indexToX (thee.peek(), iframe); Sound_into_Sound (me, sframe.peek(), t - windowDuration / 2); Sounds_multiply (sframe.peek(), window.peek()); Sound_into_BarkSpectrogram_frame (sframe.peek(), thee.peek(), iframe); if ((iframe % 10) == 1) { Melder_progress ( (double) iframe / numberOfFrames, U"BarkSpectrogram analysis: frame ", iframe, U" from ", numberOfFrames, U"."); } } _Spectrogram_windowCorrection ((Spectrogram) thee.peek(), window -> nx); return thee; } catch (MelderError) { Melder_throw (me, U": no BarkSpectrogram created."); } } static void Sound_into_MelSpectrogram_frame (Sound me, MelSpectrogram thee, long frame) { autoSpectrum him = Sound_to_Spectrum_power (me); for (long ifilter = 1; ifilter <= thy ny; ifilter++) { double power = 0; double fc_mel = thy y1 + (ifilter - 1) * thy dy; double fc_hz = thy v_frequencyToHertz (fc_mel); double fl_hz = thy v_frequencyToHertz (fc_mel - thy dy); double fh_hz = thy v_frequencyToHertz (fc_mel + thy dy); long ifrom, ito; Sampled_getWindowSamples (him.peek(), fl_hz, fh_hz, &ifrom, &ito); for (long i = ifrom; i <= ito; i++) { // Bin with a triangular filter the power (=amplitude-squared) double f = his x1 + (i - 1) * his dx; double a = NUMtriangularfilter_amplitude (fl_hz, fc_hz, fh_hz, f); power += a * his z[1][i]; } thy z[ifilter][frame] = power; } } autoMelSpectrogram Sound_to_MelSpectrogram (Sound me, double analysisWidth, double dt, double f1_mel, double fmax_mel, double df_mel) { try { double t1, samplingFrequency = 1 / my dx, nyquist = 0.5 * samplingFrequency; double windowDuration = 2 * analysisWidth; /* gaussian window */ double fmin_mel = 0; double fbottom = NUMhertzToMel2 (100.0), fceiling = NUMhertzToMel2 (nyquist); long numberOfFrames; // Check defaults. if (fmax_mel <= 0 || fmax_mel > fceiling) { fmax_mel = fceiling; } if (fmax_mel <= f1_mel) { f1_mel = fbottom; fmax_mel = fceiling; } if (f1_mel <= 0) { f1_mel = fbottom; } if (df_mel <= 0) { df_mel = 100.0; } // Determine the number of filters. long numberOfFilters = lround ((fmax_mel - f1_mel) / df_mel); fmax_mel = f1_mel + numberOfFilters * df_mel; Sampled_shortTermAnalysis (me, windowDuration, dt, &numberOfFrames, &t1); autoSound sframe = Sound_createSimple (1, windowDuration, samplingFrequency); autoSound window = Sound_createGaussian (windowDuration, samplingFrequency); autoMelSpectrogram thee = MelSpectrogram_create (my xmin, my xmax, numberOfFrames, dt, t1, fmin_mel, fmax_mel, numberOfFilters, df_mel, f1_mel); autoMelderProgress progress (U"MelSpectrograms analysis"); for (long iframe = 1; iframe <= numberOfFrames; iframe++) { double t = Sampled_indexToX (thee.peek(), iframe); Sound_into_Sound (me, sframe.peek(), t - windowDuration / 2); Sounds_multiply (sframe.peek(), window.peek()); Sound_into_MelSpectrogram_frame (sframe.peek(), thee.peek(), iframe); if ((iframe % 10) == 1) { Melder_progress ((double) iframe / numberOfFrames, U"Frame ", iframe, U" out of ", numberOfFrames, U"."); } } _Spectrogram_windowCorrection ((Spectrogram) thee.peek(), window -> nx); return thee; } catch (MelderError) { Melder_throw (me, U": no MelSpectrogram created."); } } /* Analog formant filter response : H(f) = i f B / (f1^2 - f^2 + i f B) */ static int Sound_into_Spectrogram_frame (Sound me, Spectrogram thee, long frame, double bw) { Melder_assert (bw > 0); autoSpectrum him = Sound_to_Spectrum_power (me); for (long ifilter = 1; ifilter <= thy ny; ifilter++) { double p = 0; double fc = thy y1 + (ifilter - 1) * thy dy; double *pow = his z[1]; for (long ifreq = 1; ifreq <= his nx; ifreq++) { // H(f) = ifB / (fc^2 - f^2 + ifB) // H(f)| = fB / sqrt ((fc^2 - f^2)^2 + f^2B^2) //|H(f)|^2 = f^2B^2 / ((fc^2 - f^2)^2 + f^2B^2) // = 1 / (((fc^2 - f^2) /fB)^2 + 1) double f = his x1 + (ifreq - 1) * his dx; double a = NUMformantfilter_amplitude (fc, bw, f); p += a * pow[ifreq]; } thy z[ifilter][frame] = p; } return 1; } autoSpectrogram Sound_to_Spectrogram_pitchDependent (Sound me, double analysisWidth, double dt, double f1_hz, double fmax_hz, double df_hz, double relative_bw, double minimumPitch, double maximumPitch) { try { double floor = 80, ceiling = 600; if (minimumPitch >= maximumPitch) { minimumPitch = floor; maximumPitch = ceiling; } if (minimumPitch <= 0) { minimumPitch = floor; } if (maximumPitch <= 0) { maximumPitch = ceiling; } autoPitch thee = Sound_to_Pitch (me, dt, minimumPitch, maximumPitch); autoSpectrogram ff = Sound_and_Pitch_to_Spectrogram (me, thee.peek(), analysisWidth, dt, f1_hz, fmax_hz, df_hz, relative_bw); return ff; } catch (MelderError) { Melder_throw (me, U": no Spectrogram created."); } } autoSpectrogram Sound_and_Pitch_to_Spectrogram (Sound me, Pitch thee, double analysisWidth, double dt, double f1_hz, double fmax_hz, double df_hz, double relative_bw) { try { double t1, windowDuration = 2 * analysisWidth; /* gaussian window */ double nyquist = 0.5 / my dx, samplingFrequency = 2 * nyquist, fmin_hz = 0; long numberOfFrames, f0_undefined = 0; if (my xmin > thy xmin || my xmax > thy xmax) Melder_throw (U"The domain of the Sound is not included in the domain of the Pitch."); double f0_median = Pitch_getQuantile (thee, thy xmin, thy xmax, 0.5, kPitch_unit_HERTZ); if (f0_median == NUMundefined || f0_median == 0) { f0_median = 100; Melder_warning (U"Pitch values undefined. Bandwith fixed to 100 Hz. "); } if (f1_hz <= 0) { f1_hz = 100; } if (fmax_hz <= 0) { fmax_hz = nyquist; } if (df_hz <= 0) { df_hz = f0_median / 2; } if (relative_bw <= 0) { relative_bw = 1.1; } fmax_hz = MIN (fmax_hz, nyquist); long numberOfFilters = lround ( (fmax_hz - f1_hz) / df_hz); Sampled_shortTermAnalysis (me, windowDuration, dt, &numberOfFrames, &t1); autoSpectrogram him = Spectrogram_create (my xmin, my xmax, numberOfFrames, dt, t1, fmin_hz, fmax_hz, numberOfFilters, df_hz, f1_hz); // Temporary objects autoSound sframe = Sound_createSimple (1, windowDuration, samplingFrequency); autoSound window = Sound_createGaussian (windowDuration, samplingFrequency); autoMelderProgress progress (U"Sound & Pitch: To FormantFilter"); for (long iframe = 1; iframe <= numberOfFrames; iframe++) { double t = Sampled_indexToX (him.peek(), iframe); double b, f0 = Pitch_getValueAtTime (thee, t, kPitch_unit_HERTZ, 0); if (f0 == NUMundefined || f0 == 0) { f0_undefined++; f0 = f0_median; } b = relative_bw * f0; Sound_into_Sound (me, sframe.peek(), t - windowDuration / 2); Sounds_multiply (sframe.peek(), window.peek()); Sound_into_Spectrogram_frame (sframe.peek(), him.peek(), iframe, b); if ((iframe % 10) == 1) { Melder_progress ( (double) iframe / numberOfFrames, U"Frame ", iframe, U" out of ", numberOfFrames, U"."); } } _Spectrogram_windowCorrection (him.peek(), window -> nx); return him; } catch (MelderError) { Melder_throw (U"FormantFilter not created from Pitch & FormantFilter."); } } autoSound BandFilterSpectrogram_as_Sound (BandFilterSpectrogram me, int unit) { try { autoSound thee = Sound_create (my ny, my xmin, my xmax, my nx, my dx, my x1); for (long i = 1; i <= my ny; i++) { for (long j = 1; j <= my nx; j++) thy z[i][j] = my v_getValueAtSample (j, i, unit); } return thee; } catch (MelderError) { Melder_throw (me, U": no Sound created."); } } autoSound BandFilterSpectrograms_crossCorrelate (BandFilterSpectrogram me, BandFilterSpectrogram thee, enum kSounds_convolve_scaling scaling, enum kSounds_convolve_signalOutsideTimeDomain signalOutsideTimeDomain) { try { autoSound sme = BandFilterSpectrogram_as_Sound (me, 1) ; // to dB autoSound sthee = BandFilterSpectrogram_as_Sound (thee, 1) ; autoSound cc = Sounds_crossCorrelate (sme.peek(), sthee.peek(), scaling, signalOutsideTimeDomain); return cc; } catch (MelderError) { Melder_throw (me, U" and ", thee, U" not cross-correlated."); } } autoSound BandFilterSpectrograms_convolve (BandFilterSpectrogram me, BandFilterSpectrogram thee, enum kSounds_convolve_scaling scaling, enum kSounds_convolve_signalOutsideTimeDomain signalOutsideTimeDomain) { try { autoSound sme = BandFilterSpectrogram_as_Sound (me, 1) ; // to dB autoSound sthee = BandFilterSpectrogram_as_Sound (thee, 1) ; autoSound cc = Sounds_convolve (sme.peek(), sthee.peek(), scaling, signalOutsideTimeDomain); return cc; } catch (MelderError) { Melder_throw (me, U" and ", thee, U" not convolved."); } } /* End of file Sound_and_Spectrogram_extensions.cpp */ praat-6.0.04/dwtools/Sound_and_Spectrogram_extensions.h000066400000000000000000000045671261542461700233370ustar00rootroot00000000000000#ifndef _Sound_and_Spectrogram_extensions_h_ #define _Sound_and_Spectrogram_extensions_h_ /* Sound_and_Spectrogram_extensions.h * * Copyright (C) 2014-2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20140914 */ #include "Spectrogram_extensions.h" #include "Pitch.h" #include "Sound.h" autoBarkSpectrogram Sound_to_BarkSpectrogram (Sound me, double analysisWidth, double dt, double f1_bark, double fmax_bark, double df_bark); /* Filtering with filters on a Bark scale as defined by Andrew Sekey & Brian Hanson (1984), "Improved 1-Bark bandwidth "auditory filter", Jasa 75, 1902-1904. Although not explicitely stated the filter function is defined in the power domain. 10 log F(z) = 15.8 + 7.5(z + 0.5) - 17.5 * sqrt(1 + (z + 0.5)^2) */ autoMelSpectrogram Sound_to_MelSpectrogram (Sound me, double analysisWidth, double dt, double f1_mel, double fmax_mel, double df_mel); autoSpectrogram Sound_to_Spectrogram_pitchDependent (Sound me, double analysisWidth, double dt, double f1_hz, double fmax_hz, double df_hz, double relative_bw, double minimumPitch, double maximumPitch); autoSpectrogram Sound_and_Pitch_to_Spectrogram (Sound me, Pitch thee, double analysisWidth, double dt, double f1_hz, double fmax_hz, double df_hz, double relative_bw); autoSound BandFilterSpectrograms_crossCorrelate (BandFilterSpectrogram me, BandFilterSpectrogram thee, enum kSounds_convolve_scaling scaling, enum kSounds_convolve_signalOutsideTimeDomain signalOutsideTimeDomain); autoSound BandFilterSpectrograms_convolve (BandFilterSpectrogram me, BandFilterSpectrogram thee, enum kSounds_convolve_scaling scaling, enum kSounds_convolve_signalOutsideTimeDomain signalOutsideTimeDomain); #endif /* _Sound_and_Spectrogram_extensions_h_ */ praat-6.0.04/dwtools/Sound_extensions.cpp000066400000000000000000002314001261542461700204660ustar00rootroot00000000000000/* Sound_extensions.cpp * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20001109 Sound_scale->Vector_scale djmw 20020516 GPL header djmw 20020523 Removed Sound_read/writeWAVAudioFile djmw 20030926 Sound_changeGender djmw 20040405 Renamed: Sound_overrideSamplingFrequency djmw 20041124 Changed call to Sound_to_Spectrum & Spectrum_to_Sound. djmw 20050620 Changed Pitch_HERTZ to Pitch_UNIT_HERTZ djmw 20050628 New and extended Sound_createShepardToneComplex that corrects incorrect amplitudes of tones in complex. (amplitudes were on linear instead of log scale) djmw 20060921 Added Sound_to_IntervalTier_detectSilence djmw 20061010 Removed crashing bug in Sound_to_IntervalTier_detectSilence. djmw 20061201 Interface change: removed minimumPitch parameter from Sound_and_Pitch_changeGender. djmw 20061214 Sound_and_Pitch_changeSpeaker removed warning. djmw 20070103 Sound interface changes djmw 20070129 Warning added in changeGender_old. djmw 20071022 Possible (bug?) correction in Sound_createShepardToneComplex djmw 20071030 Sound_preEmphasis: no pre-emphasis above the Nyquist frequency. djmw 20071202 Melder_warning djmw 20080122 float -> double djmw 20080320 +Sound_fade. djmw 20080530 +Sound_localAverage pb 20090926 Correction in Sound_and_Pitch_changeGender_old djmw 20091023 Added Sound_drawIntervals djmw 20091028 Sound_drawIntervals -> Sound_drawParts + Graphics_function djmw 20091126 Sound_drawParts -> Sound_drawWheres djmw 20091211 Sound_fade: removed erroneous warning djmw 20100318 Cross-correlation, convolution and autocorrelation djmw 20100325 -Cross-correlation, convolution and autocorrelation djmw 20111227 Sound_trimSilencesAtStartAndEnd and Sound_getStartAndEndTimesOfSounding djmw 20120616 Change 0.8 to 1.25 in Sound_Point_Pitch_Duration_to_Sound */ #include #include "Formula.h" #include "Intensity_extensions.h" #include "Sound_extensions.h" #include "Sound_and_Spectrum.h" #include "Spectrum_extensions.h" #include "Sound_to_Intensity.h" #include "Sound_to_Pitch.h" #include "Vector.h" #include "Pitch_extensions.h" #include "Pitch_to_PitchTier.h" #include "Pitch_to_PointProcess.h" #include "Polygon_extensions.h" #include "TextGrid_extensions.h" #include "DurationTier.h" #include "Ltas.h" #include "Manipulation.h" #include "NUM2.h" #define MAX_T 0.02000000001 /* Maximum interval between two voice pulses (otherwise voiceless). */ static void PitchTier_modifyExcursionRange (PitchTier me, double tmin, double tmax, double multiplier, double fref_Hz) { if (fref_Hz <= 0) { return; } double fref_st = 12.0 * log (fref_Hz / 100.0) / NUMln2; for (long i = 1; i <= my points -> size; i++) { RealPoint point = (RealPoint) my points -> item [i]; double f = point -> value; if (point -> number < tmin || point -> number > tmax) { continue; } if (f > 0) { double f_st = fref_st + 12.0 * log2 (f / fref_Hz) * multiplier; point -> value = 100.0 * exp (f_st * (NUMln2 / 12.0)); } } } static void Pitch_scaleDuration (Pitch me, double multiplier) { if (multiplier != 1) { // keep xmin at the same value my dx *= multiplier; my x1 = my xmin + (my x1 - my xmin) * multiplier; my xmax = my xmin + (my xmax - my xmin) * multiplier; } } static void Pitch_scalePitch (Pitch me, double multiplier) { for (long i = 1; i <= my nx; i++) { double f = my frame[i].candidate[1].frequency; f *= multiplier; if (f < my ceiling) { my frame[i].candidate[1].frequency = f; } } } static void i1write (Sound me, FILE *f, long *nClip) { double *s = my z[1], min = -128, max = 127; *nClip = 0; for (long i = 1; i <= my nx; i++) { double sample = round (s[i] * 128); if (sample > max) { sample = max; (*nClip) ++; } else if (sample < min) { sample = min; (*nClip) ++; } binputi1 ((int) sample, f); } } static void i1read (Sound me, FILE *f) { double *s = my z[1]; for (long i = 1; i <= my nx; i++) { s[i] = bingeti1 (f) / 128.0; } } static void u1write (Sound me, FILE *f, long *nClip) { double *s = my z[1], min = 0, max = 255; *nClip = 0; for (long i = 1; i <= my nx; i++) { double sample = round ( (s[i] + 1) * 255 / 2); if (sample > max) { sample = max; (*nClip) ++; } else if (sample < min) { sample = min; (*nClip) ++; } binputu1 ((unsigned int) sample, f); } } static void u1read (Sound me, FILE *f) { double *s = my z[1]; for (long i = 1; i <= my nx; i++) { s[i] = bingetu1 (f) / 128.0 - 1.0; } } static void i2write (Sound me, FILE *f, int littleEndian, long *nClip) { double *s = my z[1], min = -32768, max = 32767; void (*put) (int16_t, FILE *) = littleEndian ? binputi2LE : binputi2; *nClip = 0; for (long i = 1; i <= my nx; i++) { double sample = round (s[i] * 32768); if (sample > max) { sample = max; (*nClip) ++; } else if (sample < min) { sample = min; (*nClip) ++; } put ((int16) sample, f); } } static void i2read (Sound me, FILE *f, int littleEndian) { double *s = my z[1]; int16_t (*get) (FILE *) = littleEndian ? bingeti2LE : bingeti2; for (long i = 1; i <= my nx; i++) { s[i] = get (f) / 32768.; } } static void u2write (Sound me, FILE *f, int littleEndian, long *nClip) { double *s = my z[1], min = 0, max = 65535; void (*put) (uint16_t, FILE *) = littleEndian ? binputu2LE : binputu2; *nClip = 0; for (long i = 1; i <= my nx; i++) { double sample = round ( (s[i] + 1) * 65535 / 2); if (sample > max) { sample = max; (*nClip) ++; } else if (sample < min) { sample = min; (*nClip) ++; } put ((uint16) sample, f); } } static void u2read (Sound me, FILE *f, int littleEndian) { double *s = my z[1]; uint16_t (*get) (FILE *) = littleEndian ? bingetu2LE : bingetu2; for (long i = 1; i <= my nx; i++) { s[i] = get (f) / 32768.0 - 1.0; } } static void i4write (Sound me, FILE *f, int littleEndian, long *nClip) { double *s = my z[1]; double min = -2147483648.0, max = 2147483647.0; void (*put) (int32_t, FILE *) = littleEndian ? binputi4LE : binputi4; *nClip = 0; for (long i = 1; i <= my nx; i++) { double sample = round (s[i] * 2147483648.0); if (sample > max) { sample = max; (*nClip) ++; } else if (sample < min) { sample = min; (*nClip) ++; } put ((int32) sample, f); } } static void i4read (Sound me, FILE *f, int littleEndian) { double *s = my z[1]; int32_t (*get) (FILE *) = littleEndian ? bingeti4LE : bingeti4; for (long i = 1; i <= my nx; i++) { s[i] = get (f) / 2147483648.; } } static void u4write (Sound me, FILE *f, int littleEndian, long *nClip) { double *s = my z[1]; double min = 0.0, max = 4294967295.0; void (*put) (uint32_t, FILE *) = littleEndian ? binputu4LE : binputu4; *nClip = 0; for (long i = 1; i <= my nx; i++) { double sample = floor (s[i] * 4294967295.0 + 0.5); if (sample > max) { sample = max; (*nClip) ++; } else if (sample < min) { sample = min; (*nClip) ++; } put ((uint32) sample, f); } } static void u4read (Sound me, FILE *f, int littleEndian) { double *s = my z[1]; int32_t (*get) (FILE *) = littleEndian ? bingeti4LE : bingeti4; for (long i = 1; i <= my nx; i++) { s[i] = get (f) / 2147483648.0 - 1.0; } } static void r4write (Sound me, FILE *f) { double *s = my z[1]; for (long i = 1; i <= my nx; i++) { binputr4 (s[i], f); } } static void r4read (Sound me, FILE *f) { double *s = my z[1]; for (long i = 1; i <= my nx; i++) { s[i] = bingetr4 (f); } } static long fileLengthBytes (FILE *f) { long begin, end, current; if ( (current = ftell (f)) < 0 || fseek (f, 0L, SEEK_SET) || (begin = ftell (f)) < 0 || fseek (f, 0L, SEEK_END) || (end = ftell (f)) < 0 || fseek (f, current, SEEK_SET)) { end = begin = 0; } return end - begin; } /* Old TIMIT sound-file format */ Sound Sound_readFromCmuAudioFile (MelderFile file) { try { int littleEndian = 1; autofile f = Melder_fopen (file, "rb"); if (bingeti2LE (f) != 6) { Melder_throw (U"Incorrect header size."); } bingeti2LE (f); short nChannels = bingeti2LE (f); if (nChannels < 1) { Melder_throw (U"Incorrect number of channels."); } if (nChannels > 1) { Melder_throw (U"File has multiple channels: cannot read."); } if (bingeti2LE (f) < 1) { Melder_throw (U"Incorrect sampling frequency."); } long nSamples = bingeti4LE (f); if (nSamples < 1) { Melder_throw (U"Incorrect number of samples."); } autoSound me = Sound_createSimple (1, nSamples / 16000., 16000); i2read (me.peek(), f, littleEndian); f.close (file); return me.transfer(); } catch (MelderError) { Melder_throw (U"Sound not read from CMU audio file ", MelderFile_messageName (file), U"."); } } Sound Sound_readFromRawFile (MelderFile file, const char *format, int nBitsCoding, int littleEndian, int unSigned, long skipNBytes, double samplingFrequency) { try { autofile f = Melder_fopen (file, "rb"); if (! format) { format = "integer"; } if (nBitsCoding <= 0) { nBitsCoding = 16; } long nBytesPerSample = (nBitsCoding + 7) / 8; if (strequ (format, "float")) { nBytesPerSample = 4; } if (nBytesPerSample == 3 || nBytesPerSample > 4) { Melder_throw (U"Number of bytes per sample should be 1, 2 or 4."); } if (skipNBytes <= 0) { skipNBytes = 0; } long nSamples = (fileLengthBytes (f) - skipNBytes) / nBytesPerSample; if (nSamples < 1) { Melder_throw (U"No samples left to read"); } autoSound me = Sound_createSimple (1, nSamples / samplingFrequency, samplingFrequency); fseek (f, skipNBytes, SEEK_SET); if (nBytesPerSample == 1 && unSigned) { u1read (me.peek(), f); } else if (nBytesPerSample == 1 && ! unSigned) { i1read (me.peek(), f); } else if (nBytesPerSample == 2 && unSigned) { u2read (me.peek(), f, littleEndian); } else if (nBytesPerSample == 2 && ! unSigned) { i2read (me.peek(), f, littleEndian); } else if (nBytesPerSample == 4 && unSigned) { u4read (me.peek(), f, littleEndian); } else if (nBytesPerSample == 4 && ! unSigned) { i4read (me.peek(), f, littleEndian); } else if (nBytesPerSample == 4 && strequ (format, "float")) { r4read (me.peek(), f); } f.close (file); return me.transfer(); } catch (MelderError) { Melder_throw (U"Sound not read from raw audio file ", MelderFile_messageName (file), U"."); } } void Sound_writeToRawFile (Sound me, MelderFile file, const char *format, int littleEndian, int nBitsCoding, int unSigned) { try { long nClip = 0; autofile f = Melder_fopen (file, "wb"); if (! format) { format = "integer"; } if (nBitsCoding <= 0) { nBitsCoding = 16; } long nBytesPerSample = (nBitsCoding + 7) / 8; if (strequ (format, "float")) { nBytesPerSample = 4; } if (nBytesPerSample == 3 || nBytesPerSample > 4) { Melder_throw (U"number of bytes per sample should be 1, 2 or 4."); } if (nBytesPerSample == 1 && unSigned) { u1write (me, f, & nClip); } else if (nBytesPerSample == 1 && ! unSigned) { i1write (me, f, & nClip); } else if (nBytesPerSample == 2 && unSigned) { u2write (me, f, littleEndian, & nClip); } else if (nBytesPerSample == 2 && ! unSigned) { i2write (me, f, littleEndian, & nClip); } else if (nBytesPerSample == 4 && unSigned) { u4write (me, f, littleEndian, & nClip); } else if (nBytesPerSample == 4 && ! unSigned) { i4write (me, f, littleEndian, & nClip); } else if (nBytesPerSample == 4 && strequ (format, "float")) { r4write (me, f); } if (nClip > 0) { Melder_warning (nClip, U" from ", my nx, U" samples have been clipped.\nAdvice: you could scale the amplitudes or save as a binary file."); } if (feof ((FILE *) f) || ferror ((FILE *) f)) { Melder_throw (U"Sound_writeToRawFile: not completed"); } f.close (file); } catch (MelderError) { Melder_throw (me, U": saving as raw file not performed."); } } struct dialogic_adpcm { char code; short last, index; short step_size[49]; short adjust[8]; }; static void dialogic_adpcm_init (struct dialogic_adpcm *adpcm) { short step_size[49] = { 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552 }; short adjust[8] = { -1, -1, -1, -1, 2, 4, 6, 8 }; adpcm -> last = 0; adpcm -> index = 0; for (long i = 0; i < 49; i++) { adpcm -> step_size[i] = step_size[i]; } for (long i = 0; i < 8; i++) { adpcm -> adjust[i] = adjust[i]; } } /* The code is adapted from: Bob Edgar (), "PC Telephony - The complete guide to designing, building and programming systems using Dialogic and Related Hardware", 272-276. */ static float dialogic_adpcm_decode (struct dialogic_adpcm *adpcm) { float scale = 32767.0 / 32768.0 / 2048.0; // nibble = B3 B2 B1 B0 (4 lower bits) // d(n) = ss(n)*B2 + ss(n)/2 *B1 + ss(n)/4*B0 + ss(n)/8 short ss = adpcm -> step_size[adpcm -> index]; short e = ss / 8; if (adpcm -> code & 0x01) { e += ss / 4; } if (adpcm -> code & 0x02) { e += ss / 2; } if (adpcm -> code & 0x04) { e += ss; } // If B3==1 then d(n) = -d(n); short diff = (adpcm -> code & 0x08) ? -e : e; // x(n) = x(n-1)+d(n) short s = adpcm -> last + diff; if (s > 2048) { s = 2048; } if (s < -2048) { s = -2048; } adpcm -> last = s; // ss(n+1) = ss(n) * 1.1*M(L(n)) via lookup table adpcm -> index += adpcm -> adjust[adpcm -> code & 0x07]; if (adpcm -> index < 0) { adpcm -> index = 0; } if (adpcm -> index > 48) { adpcm -> index = 48; } return scale * s; } autoSound Sound_readFromDialogicADPCMFile (MelderFile file, double sampleRate) { try { autofile f = Melder_fopen (file, "rb"); long filelength = MelderFile_length (file); if (filelength <= 0) { Melder_throw (U"File is empty."); } // Two samples in each byte long numberOfSamples = 2 * filelength; if (numberOfSamples <= 0) { Melder_throw (U"File too long"); } autoSound me = Sound_createSimple (1, numberOfSamples / sampleRate, sampleRate); // Read all bytes and decode struct dialogic_adpcm adpcm; dialogic_adpcm_init (& adpcm); long n = 1; for (long i = 1; i <= filelength; i++) { unsigned char sc; fread (&sc, 1, 1, f); adpcm.code = (char) ( (sc >> 4) & 0x0f); my z[1][n++] = dialogic_adpcm_decode (& adpcm); adpcm.code = (char) (sc & 0x0f); my z[1][n++] = dialogic_adpcm_decode (& adpcm); } f.close (file); return me; } catch (MelderError) { Melder_throw (U"Sound not read from Dialogic ADPCM file", MelderFile_messageName (file), U"."); } } void Sound_preEmphasis (Sound me, double preEmphasisFrequency) { if (preEmphasisFrequency >= 0.5 / my dx) { return; // above Nyquist? } double preEmphasis = exp (- 2.0 * NUMpi * preEmphasisFrequency * my dx); for (long channel = 1; channel <= my ny; channel++) { double *s = my z[channel]; for (long i = my nx; i >= 2; i--) { s[i] -= preEmphasis * s[i - 1]; } } } void Sound_deEmphasis (Sound me, double deEmphasisFrequency) { double deEmphasis = exp (- 2.0 * NUMpi * deEmphasisFrequency * my dx); for (long channel = 1; channel <= my ny; channel++) { double *s = my z[channel]; for (long i = 2; i <= my nx; i++) { s[i] += deEmphasis * s[i - 1]; } } } autoSound Sound_createGaussian (double windowDuration, double samplingFrequency) { try { autoSound me = Sound_createSimple (1, windowDuration, samplingFrequency); double *s = my z[1]; double imid = 0.5 * (my nx + 1), edge = exp (-12.0); for (long i = 1; i <= my nx; i++) { s[i] = (exp (-48.0 * (i - imid) * (i - imid) / (my nx + 1) / (my nx + 1)) - edge) / (1 - edge); } return me; } catch (MelderError) { Melder_throw (U"Sound not created from Gaussian function."); } } autoSound Sound_createHamming (double windowDuration, double samplingFrequency) { try { autoSound me = Sound_createSimple (1, windowDuration, samplingFrequency); double *s = my z[1]; double p = 2.0 * NUMpi / (my nx - 1); for (long i = 1; i <= my nx; i++) { s[i] = 0.54 - 0.46 * cos ( (i - 1) * p); } return me; } catch (MelderError) { Melder_throw (U"Sound not created from Hamming function."); }; } static autoSound Sound_create2 (double minimumTime, double maximumTime, double samplingFrequency) { return Sound_create (1, minimumTime, maximumTime, lround ( (maximumTime - minimumTime) * samplingFrequency), 1.0 / samplingFrequency, minimumTime + 0.5 / samplingFrequency); } /* Trig functions whose arguments form a linear sequence x = x1 + n.dx, for n=0,1,2,... are efficiently calculated by the following recurrence: cos(a+dx) = cos(a) - (alpha . cos(a) + beta . sin(a)) sin(a+dx) = sin(a) - (alpha . sin(a) - beta . sin(a)) where alpha and beta are precomputed coefficients alpha = 2 sin^2(dx/2) and beta = sin(dx) In this way aplha and beta do not loose significance if the increment dx is small. */ static autoSound Sound_createToneComplex (double minimumTime, double maximumTime, double samplingFrequency, double firstFrequency, long numberOfComponents, double frequencyDistance, long mistunedComponent, double mistuningFraction, int scaleAmplitudes) { try { autoSound me = Sound_create2 (minimumTime, maximumTime, samplingFrequency); for (long j = 1; j <= numberOfComponents; j++) { double fraction = j == mistunedComponent ? mistuningFraction : 0; double w = 2 * NUMpi * (firstFrequency + (j - 1 + fraction) * frequencyDistance); double delta = w * my dx; double alpha = 2 * sin (delta / 2) * sin (delta / 2); double beta = sin (delta); double sint = sin (w * my x1); double cost = cos (w * my x1); my z[1][1] += sint; for (long i = 2; i <= my nx; i++) { double costd = cost - (alpha * cost + beta * sint); double sintd = sint - (alpha * sint - beta * cost); my z[1][i] += sintd; cost = costd; sint = sintd; } } if (scaleAmplitudes) { Vector_scale (me.peek(), 0.99996948); } return me; } catch (MelderError) { Melder_throw (U"Sound not created from tone complex."); } } autoSound Sound_createSimpleToneComplex (double minimumTime, double maximumTime, double samplingFrequency, double firstFrequency, long numberOfComponents, double frequencyDistance, int scaleAmplitudes) { if (firstFrequency + (numberOfComponents - 1) * frequencyDistance > samplingFrequency / 2) { Melder_warning (U"Sound_createSimpleToneComplex: frequency of (some) components too high."); numberOfComponents = (long) floor (1.0 + (samplingFrequency / 2 - firstFrequency) / frequencyDistance); } return Sound_createToneComplex (minimumTime, maximumTime, samplingFrequency, firstFrequency, numberOfComponents, frequencyDistance, 0, 0, scaleAmplitudes); } autoSound Sound_createMistunedHarmonicComplex (double minimumTime, double maximumTime, double samplingFrequency, double firstFrequency, long numberOfComponents, long mistunedComponent, double mistuningFraction, int scaleAmplitudes) { if (firstFrequency + (numberOfComponents - 1) * firstFrequency > samplingFrequency / 2) { Melder_warning (U"Sound_createMistunedHarmonicComplex: frequency of (some) components too high."); numberOfComponents = (long) floor (1.0 + (samplingFrequency / 2 - firstFrequency) / firstFrequency); } if (mistunedComponent > numberOfComponents) { Melder_warning (U"Sound_createMistunedHarmonicComplex: mistuned component too high."); } return Sound_createToneComplex (minimumTime, maximumTime, samplingFrequency, firstFrequency, numberOfComponents, firstFrequency, mistunedComponent, mistuningFraction, scaleAmplitudes); } /* The gammachirp is a "chirp tone" with a gamma-function envelope: f(t) = t^(n-1) exp (-2 pi b t) cos (2 pi f0 t + c ln (t) + p0) = t^(n-1) exp (-2 pi b t) cos (phi(t)) Instantaneous frequency f is defined as f = d phi(t) / dt / (2 pi) and so: f = f0 + c /(2 pi t) Irino: bandwidth = (frequency * (6.23e-6 * frequency + 93.39e-3) + 28.52) */ autoSound Sound_createGammaTone (double minimumTime, double maximumTime, double samplingFrequency, long gamma, double frequency, double bandwidth, double initialPhase, double addition, int scaleAmplitudes) { try { autoSound me = Sound_create2 (minimumTime, maximumTime, samplingFrequency); for (long i = 1; i <= my nx; i++) { double t = (i - 0.5) * my dx; double f = frequency + addition / (NUM2pi * t); if (f > 0 && f < samplingFrequency / 2) my z[1][i] = pow (t, gamma - 1) * exp (- NUM2pi * bandwidth * t) * cos (NUM2pi * frequency * t + addition * log (t) + initialPhase); } if (scaleAmplitudes) { Vector_scale (me.peek(), 0.99996948); } return me; } catch (MelderError) { Melder_throw (U"Sound not created from gammatone function."); } } static void NUMgammatoneFilter4 (double *x, double *y, long n, double centre_frequency, double bandwidth, double samplingFrequency) { double a[5], b[9], dt = 1.0 / samplingFrequency, wt = NUMpi * centre_frequency * dt; double bt = 2 * NUMpi * bandwidth * dt, dt2 = dt * dt, dt4 = dt2 * dt2; Melder_assert (n > 0 && centre_frequency > 0 && bandwidth >= 0 && samplingFrequency > 0); /* The filter function is: H(z) = sum (i=0..4, a[i] z^-i) / sum (j=0..4, b[j] z^-j) Coefficients a & b according to: Slaney (1993), An efficient implementation of the Patterson-Holdsworth auditory filterbank, Apple Computer Technical Report 35, 41 pages. For the a's we have left out an overal scale factor of dt^4. This makes a[0] = 1. */ a[0] = dt4; a[1] = -4 * dt4 * cos (2 * wt) * exp (- bt); a[2] = 6 * dt4 * cos (4 * wt) * exp (-2 * bt); a[3] = -4 * dt4 * cos (6 * wt) * exp (-3 * bt); a[4] = dt4 * cos (8 * wt) * exp (-4 * bt); b[0] = 1; b[1] = -8 * cos (2 * wt) * exp (- bt); b[2] = (16 + 12 * cos (4 * wt)) * exp (-2 * bt); b[3] = (-48 * cos (2 * wt) - 8 * cos (6 * wt)) * exp (-3 * bt); b[4] = (36 + 32 * cos (4 * wt) + 2 * cos (8 * wt)) * exp (-4 * bt); b[5] = (-48 * cos (2 * wt) - 8 * cos (6 * wt)) * exp (-5 * bt); b[6] = (16 + 12 * cos (4 * wt)) * exp (-6 * bt); b[7] = -8 * cos (2 * wt) * exp (-7 * bt); b[8] = exp (-8 * bt); // Calculate gain (= Abs (H(z); f=fc) and scale a[0-4] with it. double zr = cos (2 * wt), zi = -sin (2 * wt); double dr = a[4], di = 0, tr, ti, nr, ni; for (long j = 1; j <= 4; j++) { tr = a[4 - j] + zr * dr - zi * di; ti = zi * dr + zr * di; dr = tr; di = ti; } dr = b[8]; di = 0; for (long j = 1; j <= 8; j++) { nr = b[8 - j] + zr * dr - zi * di; ni = zi * dr + zr * di; dr = nr; di = ni; } double n2 = nr * nr + ni * ni; double gr = tr * nr + ti * ni; double gi = ti * nr - tr * ni; double gain = sqrt (gr * gr + gi * gi) / n2; for (long j = 0; j <= 4; j++) { a[j] /= gain; } if (Melder_debug == -1) { Melder_casual ( U"--gammatonefilter4--\nF = ", centre_frequency, U", B = ", bandwidth, U", T = ", dt, U"\nGain = ", gain ); for (long i = 0; i <= 4; i++) { Melder_casual (U"a[", i, U"] = ", a[i]); } for (long i = 0; i <= 8; i++) { Melder_casual (U"b[", i, U"] = ", b[i]); } } /* Perform the filtering. For the first 8 samples we must do some extra work. y[1] = a[0] * x[1]; if (n > 1) { y[2] = a[0] * x[2]; y[2] += a[1] * x[1] - b[1] * y[1]; } if (n > 2) { y[2] = a[0] * x[2]; y[2] += a[2] * x[i - 2] - b[2] * y[i - 2]; } */ long n8 = n < 8 ? n : 8; for (long i = 1; i <= n8; i++) { y[i] = a[0] * x[i]; if (i > 1) { y[i] += a[1] * x[i - 1] - b[1] * y[i - 1]; } else { continue; } if (i > 2) { y[i] += a[2] * x[i - 2] - b[2] * y[i - 2]; } else { continue; } if (i > 3) { y[i] += a[3] * x[i - 3] - b[3] * y[i - 3]; } else { continue; } if (i > 4) { y[i] += a[4] * x[i - 4] - b[4] * y[i - 4]; } else { continue; } if (i > 5) { y[i] -= b[5] * y[i - 5]; } else { continue; } if (i > 6) { y[i] -= b[6] * y[i - 6]; } else { continue; } if (i > 7) { y[i] -= b[7] * y[i - 7]; } } for (long i = n8 + 1; i <= n; i++) { // y[i] = a[0] * x[i]; // y[i] += a[1] * x[i-1] + a[2] * x[i-2] + a[3] * x[i-3] + a[4] * x[i-4]; // y[i] -= b[1] * y[i-1] + b[2] * y[i-2] + b[3] * y[i-3] + b[4] * y[i-4]; // y[i] -= b[5] * y[i-5] + b[6] * y[i-6] + b[7] * y[i-7] + b[8] * y[i-8]; y[i] = a[0] * x[i] + a[1] * x[i - 1] + a[2] * x[i - 2] + a[3] * x[i - 3] + a[4] * x[i - 4] - b[1] * y[i - 1] - b[2] * y[i - 2] - b[3] * y[i - 3] - b[4] * y[i - 4] - b[5] * y[i - 5] - b[6] * y[i - 6] - b[7] * y[i - 7] - b[8] * y[i - 8]; } } autoSound Sound_filterByGammaToneFilter4 (Sound me, double centre_frequency, double bandwidth) { try { if (centre_frequency <= 0) { Melder_throw (U"Centre frequency must be positive."); } if (bandwidth < 0) { Melder_throw (U"Bandwidth must be positive."); } autoSound thee = Sound_create (my ny, my xmin, my xmax, my nx, my dx, my x1); autoNUMvector y (1, my nx); autoNUMvector x (1, my nx); double fs = 1 / my dx; for (long channel = 1; channel <= my ny; channel++) { for (long i = 1; i <= my nx; i++) { x[i] = my z[channel][i]; } NUMgammatoneFilter4 (x.peek(), y.peek(), my nx, centre_frequency, bandwidth, fs); for (long i = 1; i <= my nx; i++) { thy z[channel][i] = y[i]; } } return thee; } catch (MelderError) { Melder_throw (U"Sound not filtered by gammatone filter4."); } } /* Sound Sound_createShepardTone (double minimumTime, double maximumTime, double samplingFrequency, double baseFrequency, double frequencyShiftFraction, double maximumFrequency, double amplitudeRange) { Sound me; long i, j, nComponents = 1 + log2 (maximumFrequency / 2 / baseFrequency); double lmin = pow (10, - amplitudeRange / 10); double twoPi = 2.0 * NUMpi, f = baseFrequency * (1 + frequencyShiftFraction); if (nComponents < 2) Melder_warning (U"Sound_createShepardTone: only 1 component."); Melder_casual (U"Sound_createShepardTone: ", nComponents, U" components."); if (! (me = Sound_create2 (minimumTime, maximumTime, samplingFrequency))) return nullptr; for (j=1; j <= nComponents; j++) { double fj = f * pow (2, j-1), wj = twoPi * fj; double amplitude = lmin + (1 - lmin) * (1 - cos (twoPi * log (fj + 1) / log (maximumFrequency + 1))) / 2; for (i=1; i <= my nx; i++) { my z[1][i] += amplitude * sin (wj * (i - 0.5) * my dx); } } Vector_scale (me, 0.99996948); return me; } */ autoSound Sound_createShepardToneComplex (double minimumTime, double maximumTime, double samplingFrequency, double lowestFrequency, long numberOfComponents, double frequencyChange_st, double amplitudeRange, double octaveShiftFraction) { try { double highestFrequency = lowestFrequency * pow (2, numberOfComponents); double lmax_db = 0, lmin_db = lmax_db - fabs (amplitudeRange); if (highestFrequency > samplingFrequency / 2) { Melder_throw (U"The highest frequency you want to generate is " U"above the Nyquist frequency. Choose a larger value for \"Sampling frequency\", or lower values for " U"\"Number of components\" or \"Lowest frequency\"."); } if (octaveShiftFraction < 0 || octaveShiftFraction >= 1) { Melder_throw (U"Octave offset fraction must be greater or equal zero and smaller than one."); } double octaveTime, sweeptime; if (frequencyChange_st != 0) { octaveTime = 12 / fabs (frequencyChange_st); sweeptime = numberOfComponents * octaveTime; } else { octaveTime = sweeptime = 1e308; } autoSound me = Sound_create2 (minimumTime, maximumTime, samplingFrequency); double a = frequencyChange_st / 12; for (long i = 1; i <= numberOfComponents; i++) { double tswitch; double freqi = lowestFrequency * pow (2, i - 1 + octaveShiftFraction); double b1, b2; double phase1 = 0, phasejm1 = 0; /* The frequency is f(t) = lowestFrequency * 2^tone(t) The tone is parametrized with a straight line: tone(t) = a * t + b where a = frequencyChange_st / 12 and b depends on the component If frequencyChange_st >=0 The tone rises until highest frequency at t=tswich, then falls to lowest and starts rising again. The slope is always the same. The offsets are b1 and b2 respectively. We count octaveShiftFraction as distance from tone base else if frequencyChange_st < 0 The tone falls until the lowest frequency at t=tswich, then jumps to highest and starts falling again All tones start one octave higher as in rising case. We also count octaveShiftFraction down from this tone base. else No changes in frequency of the components. endif */ if (frequencyChange_st >= 0) { b1 = i - 1 + octaveShiftFraction; b2 = 0; tswitch = (numberOfComponents - b1) * octaveTime; } else { freqi *= 2; b1 = i - octaveShiftFraction; b2 = numberOfComponents; tswitch = b1 * octaveTime; } for (long j = 1; j <= my nx; j++) { double t = Sampled_indexToX (me.peek(), j); double tmod = fmod (t, sweeptime); double tone = tmod <= tswitch ? b1 + a * tmod : b2 + a * (tmod - tswitch); double f = lowestFrequency * pow (2, tone); /* double theta = 2 * NUMpi * log2 (f / lowestFrequency) / numberOfComponents; */ double theta = 2 * NUMpi * tone / numberOfComponents; double level = pow (10, (lmin_db + (lmax_db - lmin_db) * (1 - cos (theta)) / 2) / 20); double phasej = phasejm1 + 2 * NUMpi * f * my dx; /* Integrate 2*pi*f(t) */ if (j == 1) { phase1 = phasej; // phase1 = j == 1 ? phasej : phase1; } my z[1][j] += level * sin (phasej - phase1); // si phasejm1 = phasej; } } Vector_scale (me.peek(), 0.99996948); return me; } catch (MelderError) { Melder_throw (U"Sound not created from Shepard tone complex."); } } /* can be implemented more efficiently with sin recurrence? */ /* amplitude(f) = min + (1-min)*(1-cos(2*pi*(ln(f/f1) / ln(fn/f1)))/2 */ autoSound Sound_createShepardTone (double minimumTime, double maximumTime, double samplingFrequency, double lowestFrequency, long numberOfComponents, double frequencyChange_st, double amplitudeRange) { try { double scale = pow (2, numberOfComponents); double maximumFrequency = lowestFrequency * scale; double lmin = pow (10, - amplitudeRange / 10), twoPi = 2.0 * NUMpi; double ln2t0 = log (2) * frequencyChange_st / 12; double lnf1 = log (lowestFrequency + 1); double amplarg = twoPi / log ( (maximumFrequency + 1) / (lowestFrequency + 1)); if (lowestFrequency > samplingFrequency / 2) { Melder_throw (U"Sound_createShepardTone: lowest frequency too high."); } if (maximumFrequency > samplingFrequency / 2) { Melder_throw (U"Sound_createShepardTone: frequency of highest component too high."); } autoSound me = Sound_create2 (minimumTime, maximumTime, samplingFrequency); for (long i = 1; i <= my nx; i++) { double argt, t = (i - 0.5) * my dx, ft = lowestFrequency; if (frequencyChange_st != 0) { double expt = exp (ln2t0 * t); argt = twoPi * lowestFrequency * (expt - 1) / ln2t0; ft *= expt; } else { argt = twoPi * ft * t; } for (long j = 1; j <= numberOfComponents; j++) { while (ft >= maximumFrequency) { ft /= scale; argt /= scale; } //amplitude = lmin + (1 - lmin) * (1 - cos (twoPi * log (ft + 1) / log (maximumFrequency + 1))) / 2; double amplitude = lmin + (1 - lmin) * (1 - cos (amplarg * (log (ft + 1) - lnf1))) / 2; my z[1][i] += amplitude * sin (argt); ft *= 2; argt *= 2; } } Vector_scale (me.peek(), 0.99996948); return me; } catch (MelderError) { Melder_throw (U"Sound not created from Shepard tone."); } } autoSound Sound_createPattersonWightmanTone (double minimumTime, double maximumTime, double samplingFrequency, double baseFrequency, double frequencyShiftRatio, long numberOfComponents) { try { if ( (numberOfComponents - 1 + frequencyShiftRatio) * baseFrequency > samplingFrequency / 2) { Melder_throw (U"Frequency of one or more components too large."); } autoSound me = Sound_create2 (minimumTime, maximumTime, samplingFrequency); double w0 = NUM2pi * baseFrequency; for (long i = 1; i <= my nx; i++) { double a = 0, t = (i - 0.5) * my dx; for (long j = 1; j <= numberOfComponents; j++) { a += sin ( (j + frequencyShiftRatio) * w0 * t); } my z[1][i] = a; } Vector_scale (me.peek(), 0.99996948); return me; } catch (MelderError) { Melder_throw (U"Sound not created from Patterson Wightman tone."); } } autoSound Sound_createPlompTone (double minimumTime, double maximumTime, double samplingFrequency, double baseFrequency, double frequencyFraction, long m) { try { double w1 = NUM2pi * (1 - frequencyFraction) * baseFrequency; double w2 = NUM2pi * (1 + frequencyFraction) * baseFrequency; if (12 * (1 + frequencyFraction) * baseFrequency > samplingFrequency / 2) { Melder_throw (U"Sound_createPlompTone: frequency of one or more components too large."); } autoSound me = Sound_create2 (minimumTime, maximumTime, samplingFrequency); for (long i = 1; i <= my nx; i++) { double a = 0, t = (i - 0.5) * my dx; for (long j = 1; j <= m; j++) { a += sin (j * w1 * t); } for (long j = m + 1; j <= 12; j++) { a += sin (j * w2 * t); } my z[1][i] = a; } Vector_scale (me.peek(), 0.99996948); return me; } catch (MelderError) { Melder_throw (U"Sound not created from Plomp tone."); } } void Sounds_multiply (Sound me, Sound thee) { long n = my nx < thy nx ? my nx : thy nx; double *s1 = my z[1], *s2 = thy z[1]; for (long i = 1; i <= n; i++) { s1[i] *= s2[i]; } } double Sound_power (Sound me) { double e = 0, *amplitude = my z[1]; for (long i = 1; i <= my nx; i++) { e += amplitude[i] * amplitude[i]; } return sqrt (e) * my dx / (my xmax - my xmin); } double Sound_correlateParts (Sound me, double tx, double ty, double duration) { if (ty < tx) { double t = tx; tx = ty; ty = t; } long nbx = Sampled_xToNearestIndex (me, tx); long nby = Sampled_xToNearestIndex (me, ty); long ney = Sampled_xToNearestIndex (me, ty + duration); long increment = 0, decrement = 0; if (nbx < 1) { increment = 1 - nbx; } if (ney > my nx) { decrement = ney - my nx; } long ns = (long) floor (duration / my dx) - increment - decrement; if (ns < 1) { return 0; } double *x = & my z[1][nbx + increment - 1]; double *y = & my z[1][nby + increment - 1]; double xm = 0, ym = 0, sxx = 0, syy = 0, sxy = 0; for (long i = 1; i <= ns; i++) { xm += x[i]; ym += y[i]; } xm /= ns; ym /= ns; for (long i = 1; i <= ns; i++) { double xt = x[i] - xm, yt = y[i] - ym; sxx += xt * xt; syy += yt * yt; sxy += xt * yt; } double denum = sxx * syy; double rxy = denum > 0 ? sxy / sqrt (denum) : 0; return rxy; } void Sound_localMean (Sound me, double fromTime, double toTime, double *mean) { long n1 = Sampled_xToNearestIndex (me, fromTime); long n2 = Sampled_xToNearestIndex (me, toTime); double *s = my z[1]; *mean = 0; if (fromTime > toTime) { return; } if (n1 < 1) { n1 = 1; } if (n2 > my nx) { n2 = my nx; } for (long i = n1; i <= n2; i++) { *mean += s[i]; } *mean /= n2 - n1 + 1; } void Sound_localPeak (Sound me, double fromTime, double toTime, double ref, double *peak) { long n1 = Sampled_xToNearestIndex (me, fromTime); long n2 = Sampled_xToNearestIndex (me, toTime); double *s = my z[1]; *peak = -1e308; if (fromTime > toTime) { return; } if (n1 < 1) { n1 = 1; } if (n2 > my nx) { n2 = my nx; } for (long i = n1; i <= n2; i++) { double ds = fabs (s[i] - ref); if (ds > *peak) { *peak = ds; } } } void Sound_into_Sound (Sound me, Sound to, double startTime) { long index = Sampled_xToNearestIndex (me, startTime); for (long i = 1; i <= to -> nx; i++) { long j = index - 1 + i; to -> z[1][i] = j < 1 || j > my nx ? 0 : my z[1][j]; } } /* IntervalTier Sound_PointProcess_to_IntervalTier (Sound me, PointProcess thee, double window); IntervalTier Sound_PointProcess_to_IntervalTier (Sound me, PointProcess thee, double window) { IntervalTier him; TextInterval interval; double t1, t2, t, window2 = window / 2; long i; him = IntervalTier_create (my xmin, my xmax); if (!him) return nullptr; t1 = thy t[1] - window2; if (t1 < my xmin) t1 = my xmin; t2 = t1 + window2; if (t2 > my xmax) t2 = my xmax; interval = TextInterval_create (t1, t2, "yes"); if (!interval || ! Collection_addItem (his intervals, interval)) goto end; for (i = 2; i <= thy nt; i++) { t = thy t[i]; if (t <= t2) { long index = his points -> size; RealPoint point = his points -> item[index]; t2 = t + window2; if (t2 > my xmax) t2 = my xmax; point -> value = t2; } else { t2 = t + window2; if (t2 > my xmax) t2 = my xmax; if (! RealTier_addPoint (him, t, t2)) goto end; } } end: if (Melder_hasError()) forget (him); return him; } */ void Sound_overwritePart (Sound me, double t1, double t2, Sound thee, double t3) { if (my dx != thy dx) { Melder_throw (U"Sample rates must be equal."); } if (t1 == 0) { t1 = my xmin; } if (t2 == 0) { t2 = my xmax; } long i1 = Sampled_xToHighIndex (me, t1); long i2 = Sampled_xToLowIndex (me, t2); if (i1 > i2 || i2 > my nx || i1 < 1) Melder_throw (U"Times of part to be overwritten must be within the sound."); if (t3 == 0) { t3 = thy xmin; } long i3 = Sampled_xToHighIndex (thee, t3); long i4 = Sampled_xToLowIndex (thee, t3 + t2 - t1); if (i4 > thy nx || i3 < 1) { Melder_throw (U"Not enough samples to be copied."); } if (i4 - i3 != i2 - i1) { Melder_throw (U"Error i4 - i3 != i2 - i1."); } for (long i = i1; i <= i2; i++) { my z[1][i] = thy z[1][i - i1 + i3]; } } void Sound_filter_part_formula (Sound me, double t1, double t2, const char32 *formula, Interpreter interpreter) { try { autoSound part = Sound_extractPart (me, t1, t2, kSound_windowShape_RECTANGULAR, 1, 1); autoSpectrum spec = Sound_to_Spectrum (part.peek(), true); Matrix_formula ( (Matrix) spec.peek(), formula, interpreter, 0); autoSound filtered = Spectrum_to_Sound (spec.peek()); // Overwrite part between t1 and t2 of original with the filtered signal */ Sound_overwritePart (me, t1, t2, filtered.peek(), 0); } catch (MelderError) { Melder_throw (me, U": part not filtered by formula."); } } /* First approximation on the basis of differences in the sampled signal. The underlying analog signal still could have jumps undetected by this algorithm. We could get a better approximation by first upsampling the signal. */ autoPointProcess Sound_to_PointProcess_getJumps (Sound me, double minimumJump, double dt) { try { autoPointProcess thee = PointProcess_create (my xmin, my xmax, 10); long i = 1, dtn = (long) floor (dt / my dx); if (dtn < 1) { dtn = 1; } double *s = my z[1]; while (i < my nx) { long j = i + 1, step = 1; while (j <= i + dtn && j <= my nx) { if (fabs (s[i] - s[j]) > minimumJump) { double t = Sampled_indexToX (me, i); PointProcess_addPoint (thee.peek(), t); step = j - i + 1; break; } j++; } i += step; } return thee; } catch (MelderError) { Melder_throw (me, U": no PointProcess created."); } } /* Internal pitch representation in semitones */ autoSound Sound_and_Pitch_changeSpeaker (Sound me, Pitch him, double formantMultiplier, double pitchMultiplier, double pitchRangeMultiplier, double durationMultiplier) { try { double samplingFrequency_old = 1 / my dx; if (my xmin != his xmin || my xmax != his xmax) { Melder_throw (U"The Pitch and the Sound object must have the same start and end times."); } autoSound sound = Data_copy (me); Vector_subtractMean (sound.peek()); if (formantMultiplier != 1) { // Shift all frequencies (inclusive pitch!) */ Sound_overrideSamplingFrequency (sound.peek(), samplingFrequency_old * formantMultiplier); } autoPitch pitch = Data_copy (him); Pitch_scaleDuration (pitch.peek(), 1 / formantMultiplier); // Pitch_scalePitch (pitch.peek(), formantMultiplier); autoPointProcess pulses = Sound_Pitch_to_PointProcess_cc (sound.peek(), pitch.peek()); autoPitchTier pitchTier = Pitch_to_PitchTier (pitch.peek()); double median = Pitch_getQuantile (pitch.peek(), 0, 0, 0.5, kPitch_unit_HERTZ); if (median != 0 && median != NUMundefined) { /* Incorporate pitch shift from overriding the sampling frequency */ PitchTier_multiplyFrequencies (pitchTier.peek(), sound -> xmin, sound -> xmax, pitchMultiplier / formantMultiplier); PitchTier_modifyExcursionRange (pitchTier.peek(), sound -> xmin, sound -> xmax, pitchRangeMultiplier, median); } else if (pitchMultiplier != 1) { Melder_warning (U"Pitch has not been changed because the sound was entirely voiceless."); } autoDurationTier duration = DurationTier_create (my xmin, my xmax); RealTier_addPoint (duration.peek(), (my xmin + my xmax) / 2, formantMultiplier * durationMultiplier); autoSound thee = Sound_Point_Pitch_Duration_to_Sound (sound.peek(), pulses.peek(), pitchTier.peek(), duration.peek(), MAX_T); // Resample to the original sampling frequency if (formantMultiplier != 1) { thee = Sound_resample (thee.peek(), samplingFrequency_old, 10); } return thee; } catch (MelderError) { Melder_throw (U"Sound not created from Pitch & Sound."); } } autoSound Sound_changeSpeaker (Sound me, double pitchMin, double pitchMax, double formantMultiplier, double pitchMultiplier, double pitchRangeMultiplier, double durationMultiplier) { // > 0 try { autoPitch pitch = Sound_to_Pitch (me, 0.8 / pitchMin, pitchMin, pitchMax); autoSound thee = Sound_and_Pitch_changeSpeaker (me, pitch.peek(), formantMultiplier, pitchMultiplier, pitchRangeMultiplier, durationMultiplier); return thee; } catch (MelderError) { Melder_throw (me, U": speaker not changed."); } } autoTextGrid Sound_to_TextGrid_detectSilences (Sound me, double minPitch, double timeStep, double silenceThreshold, double minSilenceDuration, double minSoundingDuration, const char32 *silentLabel, const char32 *soundingLabel) { try { int subtractMeanPressure = 1; autoIntensity thee = Sound_to_Intensity (me, minPitch, timeStep, subtractMeanPressure); autoTextGrid him = Intensity_to_TextGrid_detectSilences (thee.peek(), silenceThreshold, minSilenceDuration, minSoundingDuration, silentLabel, soundingLabel); return him; } catch (MelderError) { Melder_throw (me, U": no TextGrid with silences created."); } } void Sound_getStartAndEndTimesOfSounding (Sound me, double minPitch, double timeStep, double silenceThreshold, double minSilenceDuration, double minSoundingDuration, double *t1, double *t2) { try { const char32 *silentLabel = U"-", *soundingLabel = U"+"; autoTextGrid dbs = Sound_to_TextGrid_detectSilences (me, minPitch, timeStep, silenceThreshold, minSilenceDuration, minSoundingDuration, silentLabel, soundingLabel); IntervalTier itier = (IntervalTier) dbs -> tiers -> item[1]; TextInterval ti = (TextInterval) itier -> intervals -> item[1]; *t1 = my xmin; if (Melder_equ (ti -> text, silentLabel)) { *t1 = ti -> xmax; } *t2 = my xmax; ti = (TextInterval) itier -> intervals -> item[itier -> intervals -> size]; if (Melder_equ (ti -> text, silentLabel)) { *t2 = ti -> xmin; } } catch (MelderError) { Melder_throw (U"Sounding times not found."); } } autoSound Sound_and_IntervalTier_cutPartsMatchingLabel (Sound me, IntervalTier thee, const char32 *match) { try { // count samples of the trimmed sound long ixmin, ixmax, numberOfSamples = 0, previous_ixmax = 0; double xmin = my xmin; // start time of output sound is start time of input sound for (long iint = 1; iint <= thy intervals -> size; iint++) { TextInterval ti = (TextInterval) thy intervals -> item[iint]; if (! Melder_equ (ti -> text, match)) { numberOfSamples += Sampled_getWindowSamples (me, ti -> xmin, ti -> xmax, &ixmin, &ixmax); // if two contiguous intervals have to be copied then the last sample of previous interval // and first sample of current interval might sometimes be equal if (ixmin == previous_ixmax) { --numberOfSamples; } previous_ixmax = ixmax; } else { // matches label if (iint == 1) { // Start time of output sound is end time of first interval xmin = ti -> xmax; } } } // Now copy the parts. The output sound starts at xmin autoSound him = Sound_create (my ny, xmin, xmin + numberOfSamples * my dx, numberOfSamples, my dx, xmin + 0.5 * my dx); numberOfSamples = 0; previous_ixmax = 0; for (long iint = 1; iint <= thy intervals -> size; iint++) { TextInterval ti = (TextInterval) thy intervals -> item[iint]; if (! Melder_equ (ti -> text, match)) { long ipos; Sampled_getWindowSamples (me, ti -> xmin, ti -> xmax, &ixmin, &ixmax); if (ixmin == previous_ixmax) { ixmin++; } previous_ixmax = ixmax; for (long ichan = 1; ichan <= my ny; ichan++) { ipos = numberOfSamples + 1; for (long i = ixmin; i <= ixmax; i++, ipos++) { his z[ichan][ipos] = my z[ichan][i]; } } numberOfSamples = --ipos; } } Melder_assert (numberOfSamples == his nx); return him; } catch (MelderError) { Melder_throw (me, U": intervals not trimmed."); } } autoSound Sound_trimSilences (Sound me, double trimDuration, bool onlyAtStartAndEnd, double minPitch, double timeStep, double silenceThreshold, double minSilenceDuration, double minSoundingDuration, autoTextGrid *p_tg, const char32 *trimLabel) { try { if (my ny > 1) { Melder_throw (U"The sound must be a mono sound."); } const char32 *silentLabel = U"silent", *soundingLabel = U"sounding"; const char32 *copyLabel = U""; autoTextGrid dbs = Sound_to_TextGrid_detectSilences (me, minPitch, timeStep, silenceThreshold, minSilenceDuration, minSoundingDuration, silentLabel, soundingLabel); autoIntervalTier itg = (IntervalTier) Data_copy ((IntervalTier) dbs -> tiers -> item[1]); IntervalTier itier = (IntervalTier) dbs -> tiers -> item[1]; for (long iint = 1; iint <= itier -> intervals -> size; iint++) { TextInterval ti = (TextInterval) itier -> intervals -> item[iint]; TextInterval ati = (TextInterval) itg -> intervals -> item[iint]; double duration = ti -> xmax - ti -> xmin; if (duration > trimDuration && Melder_equ (ti -> text, silentLabel)) { // silent const char32 * label = trimLabel; if (iint == 1) { // first is special double trim_t = ti -> xmax - trimDuration; IntervalTier_moveBoundary (itg.peek(), iint, false, trim_t); } else if (iint == itier -> intervals -> size) { // last is special double trim_t = ti -> xmin + trimDuration; IntervalTier_moveBoundary (itg.peek(), iint, true, trim_t); } else { if (onlyAtStartAndEnd) { label = ati -> text; } else { double trim_t = ti -> xmin + 0.5 * trimDuration; IntervalTier_moveBoundary (itg.peek(), iint, true, trim_t); trim_t = ti -> xmax - 0.5 * trimDuration; IntervalTier_moveBoundary (itg.peek(), iint, false, trim_t); } } TextInterval_setText (ati, label); } else { // sounding TextInterval_setText (ati, copyLabel); } } autoSound thee = Sound_and_IntervalTier_cutPartsMatchingLabel (me, itg.peek(), trimLabel); if (p_tg) { TextGrid_addTier_copy (dbs.peek(), itg.peek()); *p_tg = dbs.move(); } return thee; } catch (MelderError) { Melder_throw (me, U": silences not trimmed."); } } autoSound Sound_trimSilencesAtStartAndEnd (Sound me, double trimDuration, double minPitch, double timeStep, double silenceThreshold, double minSilenceDuration, double minSoundingDuration, double *t1, double *t2) { try { autoTextGrid tg; autoSound thee = Sound_trimSilences (me, trimDuration, true, minPitch, timeStep, silenceThreshold, minSilenceDuration, minSoundingDuration, &tg, U"trimmed"); IntervalTier trim = (IntervalTier) tg -> tiers -> item[2]; TextInterval ti1 = (TextInterval) trim -> intervals -> item[1]; *t1 = my xmin; if (Melder_equ (ti1 -> text, U"trimmed")) { *t1 = ti1 -> xmax; } TextInterval ti2 = (TextInterval) trim -> intervals -> item[trim -> intervals -> size]; *t2 = my xmax; if (Melder_equ (ti2 -> text, U"trimmed")) { *t2 = ti2 -> xmin; } return thee; } catch (MelderError) { Melder_throw (me, U": silences not trimmed."); } } /* Compatibility with old Sound(&pitch)_changeGender ***********************************/ static void PitchTier_modifyRange_old (PitchTier me, double tmin, double tmax, double factor, double fmid) { for (long i = 1; i <= my points -> size; i ++) { RealPoint point = (RealPoint) my points -> item [i]; double f = point -> value; if (point -> number < tmin || point -> number > tmax) { continue; } f = fmid + (f - fmid) * factor; point -> value = f < 0 ? 0 : f; } } static Pitch Pitch_scaleTime_old (Pitch me, double scaleFactor) { try { double dx = my dx, x1 = my x1, xmax = my xmax; if (scaleFactor != 1) { dx = my dx * scaleFactor; x1 = my xmin + 0.5 * dx; xmax = my xmin + my nx * dx; } autoPitch thee = Pitch_create (my xmin, xmax, my nx, dx, x1, my ceiling, 2); for (long i = 1; i <= my nx; i++) { double f = my frame[i].candidate[1].frequency; thy frame[i].candidate[1].strength = my frame[i].candidate[1].strength; f /= scaleFactor; if (f < my ceiling) { thy frame[i].candidate[1].frequency = f; } } return thee.transfer(); } catch (MelderError) { Melder_throw (U"Pitch not scaled."); } } autoSound Sound_and_Pitch_changeGender_old (Sound me, Pitch him, double formantRatio, double new_pitch, double pitchRangeFactor, double durationFactor) { try { double samplingFrequency_old = 1 / my dx; if (my ny > 1) { Melder_throw (U"Change Gender works only on mono sounds."); } if (my xmin != his xmin || my xmax != his xmax) { Melder_throw (U"The Pitch and the Sound object must have the same starting times and finishing times."); } if (new_pitch < 0) { Melder_throw (U"The new pitch median must not be negative."); } autoSound sound = Data_copy (me); Vector_subtractMean (sound.peek()); if (formantRatio != 1) { // Shift all frequencies (inclusive pitch!) Sound_overrideSamplingFrequency (sound.peek(), samplingFrequency_old * formantRatio); } autoPitch pitch = Pitch_scaleTime_old (him, 1 / formantRatio); autoPointProcess pulses = Sound_Pitch_to_PointProcess_cc (sound.peek(), pitch.peek()); autoPitchTier pitchTier = Pitch_to_PitchTier (pitch.peek()); double median = Pitch_getQuantile (pitch.peek(), 0, 0, 0.5, kPitch_unit_HERTZ); if (median != 0 && median != NUMundefined) { // Incorporate pitch shift from overriding the sampling frequency if (new_pitch == 0) { new_pitch = median / formantRatio; } double factor = new_pitch / median; PitchTier_multiplyFrequencies (pitchTier.peek(), sound -> xmin, sound -> xmax, factor); PitchTier_modifyRange_old (pitchTier.peek(), sound -> xmin, sound -> xmax, pitchRangeFactor, new_pitch); } else { Melder_warning (U"There were no voiced segments found."); } autoDurationTier duration = DurationTier_create (my xmin, my xmax); RealTier_addPoint (duration.peek(), (my xmin + my xmax) / 2, formantRatio * durationFactor); autoSound thee = Sound_Point_Pitch_Duration_to_Sound (sound.peek(), pulses.peek(), pitchTier.peek(), duration.peek(), 1.25 / Pitch_getMinimum (pitch.peek(), 0.0, 0.0, kPitch_unit_HERTZ, false)); // Resample to the original sampling frequency if (formantRatio != 1) { thee = Sound_resample (thee.peek(), samplingFrequency_old, 10); } return thee; } catch (MelderError) { Melder_throw (U"Sound not created from Pitch & Sound."); } } autoSound Sound_changeGender_old (Sound me, double fmin, double fmax, double formantRatio, double new_pitch, double pitchRangeFactor, double durationFactor) { try { autoPitch pitch = Sound_to_Pitch (me, 0.8 / fmin, fmin, fmax); autoSound thee = Sound_and_Pitch_changeGender_old (me, pitch.peek(), formantRatio, new_pitch, pitchRangeFactor, durationFactor); return thee; } catch (MelderError) { Melder_throw (U"Sound not created for gender change."); } } /* End of compatibility with Sound_changeGender and Sound_and_Pitch_changeGender ***********************************/ /* Draw a sound vertically, from bottom to top */ void Sound_draw_btlr (Sound me, Graphics g, double tmin, double tmax, double amin, double amax, int direction, int garnish) { double xmin, xmax, ymin, ymax; if (tmin == tmax) { tmin = my xmin; tmax = my xmax; } long itmin, itmax; Matrix_getWindowSamplesX (me, tmin, tmax, &itmin, &itmax); if (amin == amax) { Matrix_getWindowExtrema (me, itmin, itmax, 1, my ny, &amin, &amax); if (amin == amax) { amin -= 1.0; amax += 1.0; } } /* In bottom-to-top-drawing the maximum amplitude is on the left, minimum on the right */ if (direction == FROM_BOTTOM_TO_TOP) { xmin = amax; xmax = amin; ymin = tmin; ymax = tmax; } else if (direction == FROM_TOP_TO_BOTTOM) { xmin = amin; xmax = amax; ymin = tmax; ymax = tmin; } else if (direction == FROM_RIGHT_TO_LEFT) { xmin = tmax; xmax = tmin; ymin = amin; ymax = amax; } else { //if (direction == FROM_LEFT_TO_RIGHT) xmin = tmin; xmax = tmax; ymin = amin; ymax = amax; } Graphics_setWindow (g, xmin, xmax, ymin, ymax); double a1 = my z[1][itmin]; double t1 = Sampled_indexToX (me, itmin); for (long it = itmin + 1; it <= itmax; it++) { double t2 = Sampled_indexToX (me, it); double a2 = my z[1][it]; if (direction == FROM_BOTTOM_TO_TOP || direction == FROM_TOP_TO_BOTTOM) { Graphics_line (g, a1, t1, a2, t2); } else { Graphics_line (g, t1, a1, t2, a2); } a1 = a2; t1 = t2; } if (garnish) { if (direction == FROM_BOTTOM_TO_TOP) { if (amin * amax < 0.0) { Graphics_markBottom (g, 0.0, false, true, true, nullptr); } } else if (direction == FROM_TOP_TO_BOTTOM) { if (amin * amax < 0.0) { Graphics_markTop (g, 0.0, false, true, true, nullptr); } } else if (direction == FROM_RIGHT_TO_LEFT) { if (amin * amax < 0.0) { Graphics_markRight (g, 0.0, false, true, true, nullptr); } } else { //if (direction == FROM_LEFT_TO_RIGHT) if (amin * amax < 0.0) { Graphics_markLeft (g, 0.0, false, true, true, nullptr); } } Graphics_rectangle (g, xmin, xmax, ymin, ymax); } } void Sound_fade (Sound me, int channel, double t, double fadeTime, int inout, int fadeGlobal) { long numberOfSamples = (long) floor (fabs (fadeTime) / my dx); double t1 = t, t2 = t1 + fadeTime; const char32 *fade_inout = inout > 0 ? U"out" : U"in"; if (channel < 0 || channel > my ny) { Melder_throw (U"Invalid channel number."); } if (t > my xmax) { t = my xmax; if (inout <= 0) { // fade in Melder_warning (U"The start time of the fade-in is after the end time of the sound. The fade-in will not happen."); return; } } else if (t < my xmin) { t = my xmin; if (inout > 0) { // fade out Melder_warning (U"The start time of the fade-out is before the start time of the sound. The fade-out will not happen."); return; } } if (fadeTime < 0) { t1 = t + fadeTime; t2 = t; } else if (fadeTime > 0) { t1 = t; t2 = t + fadeTime; } else { Melder_warning (U"You have given a \"Fade time\" of zero seconds. The fade-", fade_inout, U"will not happen."); return; } long i0 = 0, iystart, iyend; if (channel == 0) { // all iystart = 1; iyend = my ny; } else { iystart = iyend = channel; } long istart = Sampled_xToNearestIndex (me, t1); if (istart < 1) { istart = 1; } if (istart >= my nx) { Melder_warning (U"The part to fade ", fade_inout, U" lies after the end time of the sound. The fade-", fade_inout, U" will not happen."); return; } long iend = Sampled_xToNearestIndex (me, t2); if (iend <= 1) { Melder_warning (U"The part to fade ", fade_inout, U" lies before the start time of the sound. Fade-", fade_inout, U" will be incomplete."); return; } if (iend > my nx) { iend = my nx; } if (iend - istart + 1 >= numberOfSamples) { numberOfSamples = iend - istart + 1; } else { // If the start of the fade is before xmin, arrange starting phase. // The end of the fade after xmax presents no problems (i0 = 0). if (fadeTime < 0) { i0 = numberOfSamples - (iend - istart + 1); } Melder_warning (U"The fade time is larger than the part of the sound to fade ", fade_inout, U". Fade-", fade_inout, U" will be incomplete."); } for (long ichannel = iystart; ichannel <= iyend; ichannel++) { for (long i = istart; i <= iend; i++) { double cosp = cos (NUMpi * (i0 + i - istart) / (numberOfSamples - 1)); if (inout <= 0) { cosp = -cosp; // fade-in } my z[ichannel][i] *= 0.5 * (1.0 + cosp); } if (fadeGlobal) { if (inout <= 0) { for (long i = 1; i < istart; i++) { my z[ichannel][i] = 0.0; } } else { for (long i = iend; i < my nx; i++) { my z[ichannel][i] = 0.0; } } } } } /* 1; rect 2:hamming 3: bartlet 4: welch 5: hanning 6:gaussian */ autoSound Sound_createFromWindowFunction (double windowDuration, double samplingFrequency, int windowType) { try { autoSound me = Sound_createSimple (1, windowDuration, samplingFrequency); for (long i = 1; i <= my nx; i ++) { double phase = (my x1 + (i - 1) * my dx) / windowDuration; double value; switch (windowType) { case 1: value = 1.0; break; case 2: /* Hamming */ value = 0.54 - 0.46 * cos (2.0 * NUMpi * phase); break; case 3: /* Bartlett */ value = 1.0 - fabs ( (2.0 * phase - 1.0)); break; case 4: /* Welch */ value = 1.0 - (2.0 * phase - 1.0) * (2.0 * phase - 1.0); break; case 5: /* Hanning */ value = 0.5 * (1.0 - cos (2.0 * NUMpi * phase)); break; case 6: { /* Gaussian */ double edge = exp (-12.0); phase -= 0.5; /* -0.5 .. +0.5 */ value = (exp (-48.0 * phase * phase) - edge) / (1.0 - edge); break; } break; default: value = 1.0; } my z[1][i] = value; } return me; } catch (MelderError) { Melder_throw (U"Sound not created from window function."); } } /* y[n] = sum(i=-n, i=n, x[n+mi])/(2*n+1) */ autoSound Sound_localAverage (Sound me, double averagingInterval, int windowType) { try { double windowDuration = windowType == 6 ? 2 * averagingInterval : averagingInterval; autoSound thee = Data_copy (me); autoSound window = Sound_createFromWindowFunction (windowDuration, 1 / my dx, windowType); long nswindow2 = window -> nx / 2; long nswindow2p = (window -> nx - 1) / 2; // nx is odd: one sample less in the forward direction if (nswindow2 < 1) { return thee.transfer(); } double *w = window -> z[1]; for (long k = 1; k <= thy ny; k++) { for (long i = 1; i <= my nx; i++) { double sum = 0, wsum = 0; long m = (nswindow2 + 1 - i + 1) < 1 ? 1 : (nswindow2 + 1 - i + 1); long jfrom = (i - nswindow2) < 1 ? 1 : (i - nswindow2); long jto = (i + nswindow2p) > my nx ? my nx : (i + nswindow2p); for (long j = jfrom; j <= jto; j++, m++) { sum += my z[k][j] * w[m]; wsum += w[m]; } thy z[k][i] = sum / wsum; } } return thee; } catch (MelderError) { Melder_throw (me, U": no Sound (local average) created."); } } static void _Sound_garnish (Sound me, Graphics g, double tmin, double tmax, double minimum, double maximum) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Time (s)"); Graphics_marksBottom (g, 2, true, true, false); Graphics_setWindow (g, tmin, tmax, minimum - (my ny - 1) * (maximum - minimum), maximum); Graphics_markLeft (g, minimum, true, true, false, nullptr); Graphics_markLeft (g, maximum, true, true, false, nullptr); if (minimum != 0.0 && maximum != 0.0 && (minimum > 0.0) != (maximum > 0.0)) { Graphics_markLeft (g, 0.0, true, true, true, nullptr); } if (my ny == 2) { Graphics_setWindow (g, tmin, tmax, minimum, maximum + (my ny - 1) * (maximum - minimum)); Graphics_markRight (g, minimum, true, true, false, nullptr); Graphics_markRight (g, maximum, true, true, false, nullptr); if (minimum != 0.0 && maximum != 0.0 && (minimum > 0.0) != (maximum > 0.0)) { Graphics_markRight (g, 0.0, true, true, true, nullptr); } } } static void _Sound_getWindowExtrema (Sound me, double *tmin, double *tmax, double *minimum, double *maximum, long *ixmin, long *ixmax) { if (*tmin == *tmax) { *tmin = my xmin; *tmax = my xmax; } Matrix_getWindowSamplesX (me, *tmin, *tmax, ixmin, ixmax); if (*minimum == *maximum) { Matrix_getWindowExtrema (me, *ixmin, *ixmax, 1, my ny, minimum, maximum); if (*minimum == *maximum) { *minimum -= 1.0; *maximum += 1.0; } } } /* Given sample numbers isample and isample+1, where the formula evaluates to the booleans left and right, respectively. We want to find the point in this interval where the formula switches from true to false. The x-value of the best point is approximated by a number of bisections. It is essential that the intermediate interpolated y-values are always between the values at points isample and isample+1. We cannot use a sinc-interpolation because at strong amplitude changes high-frequency oscilations may occur. (may be leave out the interpolation and just use Vector_VALUE_INTERPOLATION_LINEAR only?) */ static void Sound_findIntermediatePoint_bs (Sound me, long ichannel, long isample, bool left, bool right, const char32 *formula, Interpreter interpreter, int interpolation, long numberOfBisections, double *x, double *y) { if (left) { *x = Matrix_columnToX (me, isample); *y = my z[ichannel][isample]; } else { *x = Matrix_columnToX (me, isample + 1); *y = my z[ichannel][isample + 1]; } if ( (left && right) || (!left && !right)) { Melder_throw (U"Invalid situation."); } if (numberOfBisections < 1) { return; } long nx = 3; double dx = my dx / 2; double xleft = Matrix_columnToX (me, isample); autoSound thee = Sound_create (my ny, my xmin, my xmax, nx, dx, xleft); // my domain ! for (long channel = 1; channel <= my ny; channel++) { thy z[channel][1] = my z[channel][isample]; thy z[channel][3] = my z[channel][isample + 1]; } Formula_compile (interpreter, thee.peek(), formula, kFormula_EXPRESSION_TYPE_NUMERIC, true); // bisection to find optimal x and y long istep = 1; double xright = xleft + my dx, xmid; // !! do { xmid = (xleft + xright) / 2; for (long channel = 1; channel <= my ny; channel++) { thy z[channel][2] = Vector_getValueAtX (me, xmid, channel, interpolation); } // Only thy x1 and thy dx have changed; It seems we don't have to recompile. struct Formula_Result result; Formula_run (ichannel, 2, & result); bool current = (result.result.numericResult != 0.0); dx /= 2; if ((left && current) || (! left && ! current)) { xleft = xmid; left = current; for (long channel = 1; channel <= my ny; channel++) { thy z[channel][1] = thy z[channel][2]; } thy x1 = xleft; } else if ((left && ! current) || (!left && current)) { xright = xmid; right = current; for (long channel = 1; channel <= my ny; channel++) { thy z[channel][3] = thy z[channel][2]; } } else { // we should not even be here. break; } thy xmin = xleft - dx / 2; thy xmax = xright + dx / 2; thy dx = dx; istep ++; } while (istep < numberOfBisections); *x = xmid; *y = thy z[ichannel][2]; } void Sound_drawWhere (Sound me, Graphics g, double tmin, double tmax, double minimum, double maximum, bool garnish, const char32 *method, long numberOfBisections, const char32 *formula, Interpreter interpreter) { Formula_compile (interpreter, me, formula, kFormula_EXPRESSION_TYPE_NUMERIC, true); long ixmin, ixmax; _Sound_getWindowExtrema (me, &tmin, &tmax, &minimum, &maximum, &ixmin, &ixmax); // Set coordinates for drawing. Graphics_setInner (g); struct Formula_Result result; for (long channel = 1; channel <= my ny; channel ++) { Graphics_setWindow (g, tmin, tmax, minimum - (my ny - channel) * (maximum - minimum), maximum + (channel - 1) * (maximum - minimum)); if (str32str (method, U"bars") || str32str (method, U"Bars")) { for (long ix = ixmin; ix <= ixmax; ix ++) { Formula_run (channel, ix, & result); if (result.result.numericResult != 0.0) { double x = Sampled_indexToX (me, ix); double y = my z [channel] [ix]; double left = x - 0.5 * my dx, right = x + 0.5 * my dx; if (y > maximum) { y = maximum; } if (left < tmin) { left = tmin; } if (right > tmax) { right = tmax; } Graphics_line (g, left, y, right, y); Graphics_line (g, left, y, left, minimum); Graphics_line (g, right, y, right, minimum); } } } else if (str32str (method, U"poles") || str32str (method, U"Poles")) { for (long ix = ixmin; ix <= ixmax; ix ++) { Formula_run (channel, ix, & result); if (result.result.numericResult != 0.0) { double x = Sampled_indexToX (me, ix); double y = my z[channel][ix]; if (y > maximum) { y = maximum; } if (y < minimum) { y = minimum; } Graphics_line (g, x, 0, x, y); } } } else if (str32str (method, U"speckles") || str32str (method, U"Speckles")) { for (long ix = ixmin; ix <= ixmax; ix ++) { Formula_run (channel, ix, & result); if (result.result.numericResult != 0.0) { double x = Sampled_indexToX (me, ix); Graphics_speckle (g, x, my z [channel] [ix]); } } } else { // The default: draw as a curve. bool current = true, previous = true; long istart = ixmin; double xb = Sampled_indexToX (me, ixmin), yb = my z[channel][ixmin], xe, ye; for (long ix = ixmin; ix <= ixmax; ix++) { Formula_run (channel, ix, & result); current = (result.result.numericResult != 0.0 ); // true means draw if (previous && not current) { // leaving drawing segment if (ix != ixmin) { if (ix - istart > 1) { xe = Matrix_columnToX (me, istart); ye = my z[channel][istart]; Graphics_line (g, xb, yb, xe, ye); xb = xe; xe = Matrix_columnToX (me, ix - 1); Graphics_function (g, my z[channel], istart, ix - 1, xb, xe); xb = xe; yb = my z[channel][ix - 1]; } Sound_findIntermediatePoint_bs (me, channel, ix - 1, previous, current, formula, interpreter, Vector_VALUE_INTERPOLATION_LINEAR, numberOfBisections, &xe, &ye); Graphics_line (g, xb, yb, xe, ye); Formula_compile (interpreter, me, formula, kFormula_EXPRESSION_TYPE_NUMERIC, true); } } else if (current && not previous) { // entry drawing segment istart = ix; Sound_findIntermediatePoint_bs (me, channel, ix - 1, previous, current, formula, interpreter, Vector_VALUE_INTERPOLATION_LINEAR, numberOfBisections, &xb, &yb); xe = Sampled_indexToX (me, ix), ye = my z[channel][ix]; Graphics_line (g, xb, yb, xe, ye); xb = xe; yb = ye; Formula_compile (interpreter, me, formula, kFormula_EXPRESSION_TYPE_NUMERIC, true); } else if (previous && current && ix == ixmax) { xe = Matrix_columnToX (me, istart); ye = my z[channel][istart]; Graphics_line (g, xb, yb, xe, ye); xb = xe; xe = Matrix_columnToX (me, ix); Graphics_function (g, my z[channel], istart, ix, xb, xe); xb = xe; yb = my z[channel][ix]; } previous = current; } } } Graphics_setWindow (g, tmin, tmax, minimum, maximum); if (garnish && my ny == 2) { Graphics_line (g, tmin, 0.5 * (minimum + maximum), tmax, 0.5 * (minimum + maximum)); } Graphics_unsetInner (g); if (garnish) { _Sound_garnish (me, g, tmin, tmax, minimum, maximum); } } void Sound_paintWhere (Sound me, Graphics g, Graphics_Colour colour, double tmin, double tmax, double minimum, double maximum, double level, bool garnish, long numberOfBisections, const char32 *formula, Interpreter interpreter) { try { long ixmin, ixmax; struct Formula_Result result; Formula_compile (interpreter, me, formula, kFormula_EXPRESSION_TYPE_NUMERIC, true); _Sound_getWindowExtrema (me, &tmin, &tmax, &minimum, &maximum, &ixmin, &ixmax); Graphics_setColour (g, colour); Graphics_setInner (g); for (long channel = 1; channel <= my ny; channel++) { Graphics_setWindow (g, tmin, tmax, minimum - (my ny - channel) * (maximum - minimum), maximum + (channel - 1) * (maximum - minimum)); bool current, previous = true, fill = false; // fill only when leaving area double tmini = tmin, tmaxi = tmax, xe, ye; long ix = ixmin; do { Formula_run (channel, ix, & result); current = ( result.result.numericResult != 0.0 ); if (ix == ixmin) { previous = current; } if (previous != current) { Sound_findIntermediatePoint_bs (me, channel, ix - 1, previous, current, formula, interpreter, Vector_VALUE_INTERPOLATION_LINEAR, numberOfBisections, &xe, &ye); if (current) { // entering painting area tmini = xe; } else { //leaving painting area tmaxi = xe; fill = true; } Formula_compile (interpreter, me, formula, kFormula_EXPRESSION_TYPE_NUMERIC, true); } if (ix == ixmax && current) { tmaxi = tmax; fill = true; } if (fill) { autoPolygon him = Sound_to_Polygon (me, channel, tmini, tmaxi, minimum, maximum, level); Graphics_fillArea (g, his numberOfPoints, &his x[1], &his y[1]); fill = false; } previous = current; } while (++ix <= ixmax); } Graphics_setWindow (g, tmin, tmax, minimum, maximum); if (garnish && my ny == 2) { Graphics_line (g, tmin, 0.5 * (minimum + maximum), tmax, 0.5 * (minimum + maximum)); } Graphics_unsetInner (g); if (garnish) { _Sound_garnish (me, g, tmin, tmax, minimum, maximum); } } catch (MelderError) { Melder_clearError (); } } void Sounds_paintEnclosed (Sound me, Sound thee, Graphics g, Graphics_Colour colour, double tmin, double tmax, double minimum, double maximum, bool garnish) { try { long ixmin, ixmax, numberOfChannels = my ny > thy ny ? my ny : thy ny; double min1 = minimum, max1 = maximum, tmin1 = tmin, tmax1 = tmax; double min2 = min1, max2 = max1, tmin2 = tmin1, tmax2 = tmax1; double xmin = my xmin > thy xmin ? my xmin : thy xmin; double xmax = my xmax < thy xmax ? my xmax : thy xmax; if (xmax <= xmin) { return; } if (tmin >= tmax) { tmin = xmin; tmax = xmax; } _Sound_getWindowExtrema (thee, &tmin1, &tmax1, &min1, &max1, &ixmin, &ixmax); _Sound_getWindowExtrema (me, &tmin2, &tmax2, &min2, &max2, &ixmin, &ixmax); minimum = min1 < min2 ? min1 : min2; maximum = max1 > max2 ? max1 : max2; Graphics_setColour (g, colour); Graphics_setInner (g); for (long channel = 1; channel <= numberOfChannels; channel++) { autoPolygon him = Sounds_to_Polygon_enclosed (me, thee, channel, tmin, tmax, minimum, maximum); Graphics_setWindow (g, tmin, tmax, minimum - (numberOfChannels - channel) * (maximum - minimum), maximum + (channel - 1) * (maximum - minimum)); Graphics_fillArea (g, his numberOfPoints, &his x[1], &his y[1]); } Graphics_setWindow (g, tmin, tmax, minimum, maximum); if (garnish && (my ny == 2 || thy ny == 2)) { Graphics_line (g, tmin, 0.5 * (minimum + maximum), tmax, 0.5 * (minimum + maximum)); } Graphics_unsetInner (g); if (garnish) { _Sound_garnish (my ny == 2 ? me : thee, g, tmin, tmax, minimum, maximum); } } catch (MelderError) { Melder_clearError (); } } autoSound Sound_copyChannelRanges (Sound me, const char32 *ranges) { try { long numberOfChannels; autoNUMvector channels (NUMstring_getElementsOfRanges (ranges, my ny, & numberOfChannels, nullptr, U"channel", true), 1); autoSound thee = Sound_create (numberOfChannels, my xmin, my xmax, my nx, my dx, my x1); for (long i = 1; i <= numberOfChannels; i++) { double *from = my z[channels[i]], *to = thy z[i]; NUMvector_copyElements (from, to, 1, my nx); } return thee; } catch (MelderError) { Melder_throw (me, U": could not extract channels."); } } /* After a script by Ton Wempe */ static autoSound Sound_removeNoiseBySpectralSubtraction_mono (Sound me, Sound noise, double windowLength) { try { if (my dx != noise -> dx) { Melder_throw (U"The sound and the noise must have the same sampling frequency."); } if (noise -> ny != 1 || noise -> ny != 1) { Melder_throw (U"The number of channels in the noise and the sound should equal 1."); } double samplingFrequency = 1.0 / my dx; autoSound denoised = Sound_create (1, my xmin, my xmax, my nx, my dx, my x1); autoSound analysisWindow = Sound_createSimple (1, windowLength, samplingFrequency); long windowSamples = analysisWindow -> nx; autoSound noise_copy = (Sound) Data_copy (noise); Sound_multiplyByWindow (noise_copy.peek(), kSound_windowShape_HANNING); double bandwidth = samplingFrequency / windowSamples; autoLtas noiseLtas = Sound_to_Ltas (noise_copy.peek(), bandwidth); autoNUMvector noiseAmplitudes (1, noiseLtas -> nx); for (long i = 1; i <= noiseLtas -> nx; i++) { noiseAmplitudes[i] = pow (10.0, (noiseLtas -> z[1][i] - 94) / 20); } long stepSizeSamples = windowSamples / 4; long numberOfSteps = my nx / stepSizeSamples; for (long istep = 1; istep <= numberOfSteps; istep++) { long istart = (istep - 1) * stepSizeSamples + 1; if (istart >= my nx) { break; // finished } long nsamples = istart + windowSamples - 1 > my nx ? my nx - istart + 1 : windowSamples; for (long j = 1; j <= nsamples; j++) { analysisWindow -> z[1][j] = my z[1][istart - 1 + j]; } for (long j = nsamples + 1; j <= windowSamples; j++) { analysisWindow -> z[1][j] = 0; } autoSpectrum analysisSpectrum = Sound_to_Spectrum (analysisWindow.peek(), 0); // Suppress noise in the analysisSpectrum by subtracting the noise spectrum double *x = analysisSpectrum -> z[1], *y = analysisSpectrum -> z[2]; for (long i = 1; i <= analysisSpectrum -> nx; i++) { double amp = sqrt (x[i] * x[i] + y[i] * y[i]); double factor = 1 - 1.5 * noiseAmplitudes[i] / amp; factor = factor < 1e-6 ? 1e-6 : factor; x[i] *= factor; y[i] *= factor; } autoSound suppressed = Spectrum_to_Sound (analysisSpectrum.peek()); Sound_multiplyByWindow (suppressed.peek(), kSound_windowShape_HANNING); for (long j = 1; j <= nsamples; j++) { denoised -> z[1][istart - 1 + j] += 0.5 * suppressed -> z[1][j]; // 0.5 because of 2-fold oversampling } } return denoised; } catch (MelderError) { Melder_throw (me, U": noise not subtracted."); } } static void Sound_findNoise (Sound me, double minimumNoiseDuration, double *noiseStart, double *noiseEnd) { try { *noiseStart = NUMundefined; *noiseEnd = NUMundefined; autoIntensity intensity = Sound_to_Intensity (me, 20, 0.005, 1); double tmin = Vector_getXOfMinimum (intensity.peek(), intensity -> xmin, intensity -> xmax, 1) - minimumNoiseDuration / 2; double tmax = tmin + minimumNoiseDuration; if (tmin < my xmin) { tmin = my xmin; tmax = tmin + minimumNoiseDuration; } if (tmax > my xmax) { tmax = my xmax; tmin = tmax - minimumNoiseDuration; } if (tmin < my xmin) { Melder_throw (U"Sound too short, or window length too long."); } *noiseStart = tmin; *noiseEnd = tmax; } catch (MelderError) { Melder_throw (me, U": noise not found."); } } autoSound Sound_removeNoise (Sound me, double noiseStart, double noiseEnd, double windowLength, double minBandFilterFrequency, double maxBandFilterFrequency, double smoothing, int method) { try { autoSound filtered = Sound_filter_passHannBand (me, minBandFilterFrequency, maxBandFilterFrequency, smoothing); autoSound denoised = Sound_create (my ny, my xmin, my xmax, my nx, my dx, my x1); bool findNoise = noiseEnd <= noiseStart; double minimumNoiseDuration = 2 * windowLength; for (long ichannel = 1; ichannel <= my ny; ichannel++) { autoSound denoisedi, channeli = Sound_extractChannel (filtered.peek(), ichannel); if (findNoise) { Sound_findNoise (channeli.peek(), minimumNoiseDuration, &noiseStart, &noiseEnd); } autoSound noise = Sound_extractPart (channeli.peek(), noiseStart, noiseEnd, kSound_windowShape_RECTANGULAR, 1.0, false); if (method == 1) { // spectral subtraction denoisedi = Sound_removeNoiseBySpectralSubtraction_mono (filtered.peek(), noise.peek(), windowLength); } NUMvector_copyElements (denoisedi -> z[1], denoised -> z[ichannel], 1, my nx); } return denoised; } catch (MelderError) { Melder_throw (me, U": not denoised."); } } void Sound_playAsFrequencyShifted (Sound me, double shiftBy, double newSamplingFrequency, long precision) { try { autoSpectrum spectrum = Sound_to_Spectrum (me, 1); autoSpectrum shifted = Spectrum_shiftFrequencies (spectrum.peek(), shiftBy, newSamplingFrequency / 2, precision); autoSound thee = Spectrum_to_Sound (shifted.peek()); Sound_playPart (thee.peek(), my xmin, my xmax, nullptr, nullptr); } catch (MelderError) { Melder_throw (me, U" not played with frequencies shifted."); } } /* End of file Sound_extensions.cpp */ praat-6.0.04/dwtools/Sound_extensions.h000066400000000000000000000227751261542461700201500ustar00rootroot00000000000000#ifndef _Sound_extensions_h_ #define _Sound_extensions_h_ /* Sound_extensions.h * * Copyright (C) 1993-2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header djmw 20121023 Latest modification */ #include "Sound.h" #include "Pitch.h" #include "Collection.h" #include "PointProcess.h" #include "TextGrid.h" #include "Interpreter_decl.h" int Sound_writeToNistAudioFile (Sound me, MelderFile file); Sound Sound_readFromCmuAudioFile (MelderFile file); /* only 16 bit signed has been tested !! */ Sound Sound_readFromRawFile (MelderFile file, const char *format, int nBitsCoding, int littleEndian, int unSigned, long skipNBytes, double samplingFrequency); /* Reads a Sound from a raw file: * fileName : name of the file * format : "integer" (default) * "float" (this implies nBitsCoding=nBitsStorage=32, see below) * nBitsCoding : number of bits used in the coding (1..16) (default = 16 ) * (the storage is assumed to be a multiple of 8 bits ) * littleEndian: if littleEndian != 0 then little-endian else big-endian * unSigned : if unSigned != 0 then unsigned else signed * skipNBytes : start reading after this number of bytes (skipNBytes >= 0 ) */ autoSound Sound_readFromDialogicADPCMFile (MelderFile file, double sampleRate); /* */ void Sound_writeToRawFile (Sound me, MelderFile file, const char *format, int littleEndian, int nBitsCoding, int unSigned); void Sound_into_Sound (Sound me, Sound to, double startTime); /* precondition: my dx == to->dx (equal sampling times */ void Sound_overwritePart (Sound me, double t1, double t2, Sound thee, double t3); /* Overwrite the part between (t1,t2) in me with samples from Sound thee, starting at t3 in thee. */ void Sound_preEmphasis (Sound me, double preEmphasisFrequency); /* deEmphasis = exp(- 2 * NUMpi * deEmphasisFrequency * my dx); */ /* for (i=my nx; i >=2; i-- ) my z[1][i] -= preEmphasis * my z[1][i-1]; */ void Sound_deEmphasis (Sound me, double preEmphasisFrequency); /* for (i=2; i <= my nx; i++ ) my z[1][i] += deEmphasis * my z[1][i-1]; */ autoSound Sound_createGaussian (double windowDuration, double samplingFrequency); autoSound Sound_createHamming (double windowDuration, double samplingFrequency); autoSound Sound_createSimpleToneComplex (double minimumTime, double maximumTime, double samplingFrequency, double firstFrequency, long numberOfComponents, double frequencyDistance, int scaleAmplitudes); autoSound Sound_createMistunedHarmonicComplex (double minimumTime, double maximumTime, double samplingFrequency, double firstFrequency, long numberOfComponents, long mistunedComponent, double mistuningFraction, int scaleAmplitudes); autoSound Sound_createGammaTone (double minimumTime, double maximumTime, double samplingFrequency, long gamma, double frequency, double bandwidth, double initialPhase, double addition, int scaleAmplitudes); autoSound Sound_createShepardTone (double minimumTime, double maximumTime, double samplingFrequency, double lowestFrequency, long numberOfComponents, double frequencyChange, double amplitudeRange); autoSound Sound_createShepardToneComplex (double minimumTime, double maximumTime, double samplingFrequency, double lowestFrequency, long numberOfComponents, double frequencyChange_st, double amplitudeRange, double octaveShiftFraction); autoSound Sound_createPattersonWightmanTone (double minimumTime, double maximumTime, double samplingFrequency, double baseFrequency, double frequencyShiftRatio, long numberOfComponents); autoSound Sound_createPlompTone (double minimumTime, double maximumTime, double samplingFrequency, double baseFrequency, double frequencyFraction, long m); autoSound Sound_createFromWindowFunction (double effectiveTime, double samplingFrequency, int windowType); /* 1; rect 2:hamming 3: bartlet 4: welch 5: hanning 6:gaussian */ autoSound Sound_filterByGammaToneFilter4 (Sound me, double centre_frequency, double bandwidth); void Sounds_multiply (Sound me, Sound thee); /* precondition: my nx = thy nx */ double Sound_correlateParts (Sound me, double t1, double t2, double duration); /* Correlate part (t1, t1+duration) with (t2, t2+duration) */ void Sound_localMean (Sound me, double fromTime, double toTime, double *mean); void Sound_localPeak (Sound me, double fromTime, double toTime, double ref, double *peak); autoSound Sound_localAverage (Sound me, double averaginginterval, int windowType); /* y[n] = sum(i=-n, i=n, x[n+i])/(2*n+1) */ double Sound_power (Sound me); void Sound_scale_dB (Sound me, double level_dB); /* Scales the amplitude of a Sound to a certain dB level. The reference value is an amplitude of 1. All amplitudes are multiplied by a scale factor which is 10^(level_dB/10) / extremum, where extremum is the maximum of the absolute values the signal values. */ void Sound_fade (Sound me, int channel, double t, double fadeTime, int inout, int fadeGlobal); /* if inout <= 0 fade in with (1-cos)/2 else fade out with (1+cos)/2 channel = 0 (all), 1 (left), 2 (right). */ #define FROM_LEFT_TO_RIGHT 0 #define FROM_RIGHT_TO_LEFT 1 #define FROM_BOTTOM_TO_TOP 2 #define FROM_TOP_TO_BOTTOM 3 void Sound_draw_btlr (Sound me, Graphics g, double tmin, double tmax, double amin, double amax, int direction, int garnish); /* direction is one of the macros's FROM_LEFT_TO_RIGHT... */ void Sound_drawWhere (Sound me, Graphics g, double tmin, double tmax, double minimum, double maximum, bool garnish, const char32 *method, long numberOfBisections, const char32 *formula, Interpreter interpreter); void Sound_paintWhere (Sound me, Graphics g, Graphics_Colour colour, double tmin, double tmax, double minimum, double maximum, double level, bool garnish, long numberOfBisections, const char32 *formula, Interpreter interpreter); void Sounds_paintEnclosed (Sound me, Sound thee, Graphics g, Graphics_Colour colour, double tmin, double tmax, double minimum, double maximum, bool garnish); autoSound Sound_changeGender (Sound me, double pitchMin, double pitchMax, double pitchRatio, double formantFrequenciesRatio, double durationRatio); autoSound Sound_and_Pitch_changeGender (Sound me, Pitch him, double pitchRatio, double formantFrequenciesRatio, double durationRatio); autoSound Sound_changeGender_old (Sound me, double fmin, double fmax, double formantRatio, double new_pitch, double pitchRangeFactor, double durationFactor); autoSound Sound_and_Pitch_changeGender_old (Sound me, Pitch him, double formantRatio, double new_pitch, double pitchRangeFactor, double durationFactor); autoPointProcess Sound_to_PointProcess_getJumps (Sound me, double minimumJump, double dt); /* Marks jumps in the signal where the amplitude changes more than 'minimumJump' within time dt */ void Sound_filter_part_formula (Sound me, double t1, double t2, const char32 *formula, Interpreter interpreter); autoSound Sound_changeSpeaker (Sound me, double pitchMin, double pitchMax, double formantMultiplier, // > 0 double pitchMultiplier, // > 0 double pitchRangeMultiplier, // any number double durationMultiplier); // > 0 autoSound Sound_and_Pitch_changeSpeaker (Sound me, Pitch him, double formantMultiplier, // > 0 double pitchMultiplier, // > 0 double pitchRangeMultiplier, // any number double durationMultiplier); // > 0 /* Outphased */ autoSound Sound_changeGender_old (Sound me, double fmin, double fmax, double formantRatio, double new_pitch, double pitchRangeFactor, double durationFactor); autoTextGrid Sound_to_TextGrid_detectSilences (Sound me, double minPitch, double timeStep, double silenceThreshold, double minSilenceDuration, double minSoundingDuration, const char32 *silentLabel, const char32 *soundingLabel); void Sound_getStartAndEndTimesOfSounding (Sound me, double minPitch, double timeStep, double silenceThreshold, double minSilenceDuration, double minSoundingDuration, double *t1, double *t2); autoSound Sound_and_IntervalTier_cutPartsMatchingLabel (Sound me, IntervalTier thee, const char32 *match); /* Cut intervals that match the label from the sound. The starting time of the new sound is * (1) my xmin if the first interval is not matching * (2) the end time of the first interval if matching */ autoSound Sound_trimSilencesAtStartAndEnd (Sound me, double trimDuration, double minPitch, double timeStep, double silenceThreshold, double minSilenceDuration, double minSoundingDuration, double *t1, double *t2); autoSound Sound_trimSilences (Sound me, double trimDuration, bool onlyAtStartAndEnd, double minPitch, double timeStep, double silenceThreshold, double minSilenceDuration, double minSoundingDuration, autoTextGrid *p_tg, const char32 *trimLabel); autoSound Sound_copyChannelRanges (Sound me, const char32 *ranges); autoSound Sound_removeNoise (Sound me, double noiseStart, double noiseEnd, double windowLength, double minBandFilterFrequency, double maxBandFilterFrequency, double smoothing, int method); void Sound_playAsFrequencyShifted (Sound me, double shiftBy, double newSamplingFrequency, long precision); #endif /* _Sound_extensions_h_ */ praat-6.0.04/dwtools/Sound_to_DTW.h000066400000000000000000000021301261542461700170700ustar00rootroot00000000000000#ifndef _Sound_to_MFCC_h_ #define _Sound_to_MFCC_h_ /* Sound_to_MFCC.h * * Copyright (C) 1993-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20010410 djmw 20020813 GPL header djmw 20110307 Latest modification */ #include "MFCC.h" #include "Sound.h" MFCC Sound_to_MFCC (Sound me, long numberOfCoefficients, double analysisWidth, double dt, double f1_mel, double fmax_mel, double df_mel); #endif /* _Sound_to_MFCC_h_ */ praat-6.0.04/dwtools/Sound_to_MFCC.cpp000066400000000000000000000025161261542461700175050ustar00rootroot00000000000000/* Sound_to_MFCC.cpp * * Copyright (C) 1993-2011, 2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20010410 djmw 20020813 GPL header */ #include "Sound_to_MFCC.h" #include "Sound_and_Spectrogram_extensions.h" MFCC Sound_to_MFCC (Sound me, long numberOfCoefficients, double analysisWidth, double dt, double f1_mel, double fmax_mel, double df_mel) { try { autoMelSpectrogram mf = Sound_to_MelSpectrogram (me, analysisWidth, dt, f1_mel, fmax_mel, df_mel); autoMFCC mfcc = MelSpectrogram_to_MFCC (mf.peek(), numberOfCoefficients); return mfcc.transfer(); } catch (MelderError) { Melder_throw (me, U": no MFCC created."); } } /* End of file Sound_to_MFCC.cpp */ praat-6.0.04/dwtools/Sound_to_MFCC.h000066400000000000000000000021301261542461700171420ustar00rootroot00000000000000#ifndef _Sound_to_MFCC_h_ #define _Sound_to_MFCC_h_ /* Sound_to_MFCC.h * * Copyright (C) 1993-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20010410 djmw 20020813 GPL header djmw 20110307 Latest modification */ #include "MFCC.h" #include "Sound.h" MFCC Sound_to_MFCC (Sound me, long numberOfCoefficients, double analysisWidth, double dt, double f1_mel, double fmax_mel, double df_mel); #endif /* _Sound_to_MFCC_h_ */ praat-6.0.04/dwtools/Sound_to_Pitch2.cpp000066400000000000000000000233211261542461700201230ustar00rootroot00000000000000/* Sound_to_Pitch2.c * * Copyright (C) 1993-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header djmw 20021106 Latest modification djmw 20041124 Changed call to Sound_to_Spectrum. djmw 20070103 Sound interface changes */ #include "Sound_to_Pitch2.h" #include "Pitch_extensions.h" #include "Sound_and_Spectrum.h" #include "Sound_to_SPINET.h" #include "SPINET_to_Pitch.h" #include "NUM2.h" static int spec_enhance_SHS (double a[], long n) { if (n < 2) { return 0; } autoNUMvector posmax (1, (n + 1) / 2); long nmax = 0; if (a[1] > a[2]) { posmax[++nmax] = 1; } for (long i = 2; i <= n - 1; i++) if (a[i] > a[i - 1] && a[i] >= a[i + 1]) { posmax[++nmax] = i; } if (a[n] > a[n - 1]) { posmax[++nmax] = n; } if (nmax == 1) { for (long j = 1; j <= posmax[1] - 3; j++) { a[j] = 0; } for (long j = posmax[1] + 3; j <= n; j++) { a[j] = 0; } } else { for (long i = 2; i <= nmax; i++) { for (long j = posmax[i - 1] + 3; j <= posmax[i] - 3; j++) { a[j] = 0; } } } return 1; } static void spec_smoooth_SHS (double a[], long n) { double ai, aim1 = 0; for (long i = 1; i <= n - 1; i++) { ai = a[i]; a[i] = (aim1 + 2 * ai + a[i + 1]) / 4; aim1 = ai; } } autoPitch Sound_to_Pitch_shs (Sound me, double timeStep, double minimumPitch, double maximumFrequency, double ceiling, long maxnSubharmonics, long maxnCandidates, double compressionFactor, long nPointsPerOctave) { try { double firstTime, newSamplingFrequency = 2 * maximumFrequency; double windowDuration = 2 / minimumPitch, halfWindow = windowDuration / 2; double atans = nPointsPerOctave * NUMlog2 (65.0 / 50.0) - 1; // Number of speech samples in the downsampled signal in each frame: // 100 for windowDuration == 0.04 and newSamplingFrequency == 2500 long nx = lround (windowDuration * newSamplingFrequency); // The minimum number of points for the fft is 256. long nfft = 1; while ( (nfft *= 2) < nx || nfft <= 128) { ; } long nfft2 = nfft / 2 + 1; double frameDuration = nfft / newSamplingFrequency; double df = newSamplingFrequency / nfft; // The number of points on the octave scale double fminl2 = NUMlog2 (minimumPitch), fmaxl2 = NUMlog2 (maximumFrequency); long nFrequencyPoints = (long) floor ((fmaxl2 - fminl2) * nPointsPerOctave); double dfl2 = (fmaxl2 - fminl2) / (nFrequencyPoints - 1); autoSound sound = Sound_resample (me, newSamplingFrequency, 50); long numberOfFrames; Sampled_shortTermAnalysis (sound.peek(), windowDuration, timeStep, &numberOfFrames, &firstTime); autoSound frame = Sound_createSimple (1, frameDuration, newSamplingFrequency); autoSound hamming = Sound_createHamming (nx / newSamplingFrequency, newSamplingFrequency); autoPitch thee = Pitch_create (my xmin, my xmax, numberOfFrames, timeStep, firstTime, ceiling, maxnCandidates); autoNUMvector cc (1, numberOfFrames); autoNUMvector specAmp (1, nfft2); autoNUMvector fl2 (1, nfft2); autoNUMvector yv2 (1, nfft2); autoNUMvector arctg (1, nFrequencyPoints); autoNUMvector al2 (1, nFrequencyPoints); Melder_assert (frame->nx >= nx); Melder_assert (hamming->nx == nx); // Compute the absolute value of the globally largest amplitude w.r.t. the global mean. double globalMean, globalPeak; Sound_localMean (sound.peek(), sound -> xmin, sound -> xmax, &globalMean); Sound_localPeak (sound.peek(), sound -> xmin, sound -> xmax, globalMean, &globalPeak); /* For the cubic spline interpolation we need the frequencies on an octave scale, i.e., a log2 scale. All frequencies must be DIFFERENT, otherwise the cubic spline interpolation will give corrupt results. Because log2(f==0) is not defined, we use the heuristic: f[2]-f[1] == f[3]-f[2]. */ for (long i = 2; i <= nfft2; i++) { fl2[i] = NUMlog2 ((i - 1) * df); } fl2[1] = 2 * fl2[2] - fl2[3]; // Calculate frequencies regularly spaced on a log2-scale and // the frequency weighting function. for (long i = 1; i <= nFrequencyPoints; i++) { arctg[i] = 0.5 + atan (3.0 * (i - atans) / nPointsPerOctave) / NUMpi; } // Perform the analysis on all frames. for (long i = 1; i <= numberOfFrames; i++) { Pitch_Frame pitchFrame = &thy frame[i]; double hm = 1, f0, pitch_strength, localMean, localPeak; double tmid = Sampled_indexToX (thee.peek(), i); /* The center of this frame */ long nx_tmp = frame -> nx; // Copy a frame from the sound, apply a hamming window. Get local 'intensity' frame -> nx = nx; /*begin vies */ Sound_into_Sound (sound.peek(), frame.peek(), tmid - halfWindow); Sounds_multiply (frame.peek(), hamming.peek()); Sound_localMean (sound.peek(), tmid - 3 * halfWindow, tmid + 3 * halfWindow, &localMean); Sound_localPeak (sound.peek(), tmid - halfWindow, tmid + halfWindow, localMean, &localPeak); pitchFrame -> intensity = localPeak > globalPeak ? 1 : localPeak / globalPeak; frame -> nx = nx_tmp; /* einde vies */ // Get the Fourier spectrum. autoSpectrum spec = Sound_to_Spectrum (frame.peek(), 1); Melder_assert (spec->nx == nfft2); // From complex spectrum to amplitude spectrum. for (long j = 1; j <= nfft2; j++) { double rs = spec -> z[1][j], is = spec -> z[2][j]; specAmp[j] = sqrt (rs * rs + is * is); } // Enhance the peaks in the spectrum. spec_enhance_SHS (specAmp.peek(), nfft2); // Smooth the enhanced spectrum. spec_smoooth_SHS (specAmp.peek(), nfft2); // Go to a logarithmic scale and perform cubic spline interpolation to get // spectral values for the increased number of frequency points. NUMspline (fl2.peek(), specAmp.peek(), nfft2, 1e30, 1e30, yv2.peek()); for (long j = 1; j <= nFrequencyPoints; j++) { double f = fminl2 + (j - 1) * dfl2; NUMsplint (fl2.peek(), specAmp.peek(), yv2.peek(), nfft2, f, &al2[j]); } // Multiply by frequency selectivity of the auditory system. for (long j = 1; j <= nFrequencyPoints; j++) al2[j] = al2[j] > 0 ? al2[j] * arctg[j] : 0; // The subharmonic summation. Shift spectra in octaves and sum. Pitch_Frame_init (pitchFrame, maxnCandidates); autoNUMvector sumspec (1, nFrequencyPoints); pitchFrame -> nCandidates = 0; /* !!!!! */ for (long m = 1; m <= maxnSubharmonics + 1; m++) { long kb = 1 + (long) floor (nPointsPerOctave * NUMlog2 (m)); for (long k = kb; k <= nFrequencyPoints; k++) { sumspec[k - kb + 1] += al2[k] * hm; } hm *= compressionFactor; } // First register the voiceless candidate (always present). Pitch_Frame_addPitch (pitchFrame, 0, 0, maxnCandidates); /* Get the best local estimates for the pitch as the maxima of the subharmonic sum spectrum by parabolic interpolation on three points: The formula for a parabole with a maximum is: y(x) = a - b (x - c)^2 with a, b, c >= 0 The three points are (-x, y1), (0, y2) and (x, y3). The solution for a (the maximum) and c (the position) is: a = (2 y1 (4 y2 + y3) - y1^2 - (y3 - 4 y2)^2)/( 8 (y1 - 2 y2 + y3) c = dx (y1 - y3) / (2 (y1 - 2 y2 + y3)) (b = (2 y2 - y1 - y3) / (2 dx^2) ) */ for (long k = 2; k <= nFrequencyPoints - 1; k++) { double y1 = sumspec[k - 1], y2 = sumspec[k], y3 = sumspec[k + 1]; if (y2 > y1 && y2 >= y3) { double denum = y1 - 2 * y2 + y3, tmp = y3 - 4 * y2; double x = dfl2 * (y1 - y3) / (2 * denum); double f = pow (2, fminl2 + (k - 1) * dfl2 + x); double strength = (2 * y1 * (4 * y2 + y3) - y1 * y1 - tmp * tmp) / (8 * denum); Pitch_Frame_addPitch (pitchFrame, f, strength, maxnCandidates); } } /* Check whether f0 corresponds to an actual periodicity T = 1 / f0: correlate two signal periods of duration T, one starting at the middle of the interval and one starting T seconds before. If there is periodicity the correlation coefficient should be high. However, some sounds do not show any regularity, or very low frequency and regularity, and nevertheless have a definite pitch, e.g. Shepard sounds. */ Pitch_Frame_getPitch (pitchFrame, &f0, &pitch_strength); if (f0 > 0) { cc[i] = Sound_correlateParts (sound.peek(), tmid - 1.0 / f0, tmid, 1.0 / f0); } } // Base V/UV decision on correlation coefficients. // Resize the pitch strengths w.r.t. the cc. double vuvCriterium = 0.52; for (long i = 1; i <= numberOfFrames; i++) { Pitch_Frame_resizeStrengths (& thy frame[i], cc[i], vuvCriterium); } return thee; } catch (MelderError) { Melder_throw (me, U": no Pitch (shs) created."); } } autoPitch Sound_to_Pitch_SPINET (Sound me, double timeStep, double windowDuration, double minimumFrequencyHz, double maximumFrequencyHz, long nFilters, double ceiling, int maxnCandidates) { try { autoSPINET him = Sound_to_SPINET (me, timeStep, windowDuration, minimumFrequencyHz, maximumFrequencyHz, nFilters, 0.4, 0.6); autoPitch thee = SPINET_to_Pitch (him.peek(), 0.15, ceiling, maxnCandidates); return thee; } catch (MelderError) { Melder_throw (me, U": no Pitch (SPINET) created."); } } /* End of file Sound_to_Pitch2.cpp */ praat-6.0.04/dwtools/Sound_to_Pitch2.h000066400000000000000000000026011261542461700175660ustar00rootroot00000000000000#ifndef _Sound_to_Pitch2_h_ #define _Sound_to_Pitch2_h_ /* Sound_to_Pitch2.h * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19970410 djmw 20020813 GPL header djmw 20110307 Latest modification */ #include "Sound_extensions.h" #include "Pitch.h" autoPitch Sound_to_Pitch_shs (Sound me, double timeStep, double minimumPitch, double maximumFrequency, double ceiling, long maxnSubharmonics, long maxnCandidates, double compressionFactor, long nDivisionsPerOctave); autoPitch Sound_to_Pitch_SPINET (Sound me, double timeStep, double windowDuration, double minimumFrequencyHz, double maximumFrequencyHz, long nFilters, double ceiling, int maxnCandidates); #endif /* _Sound_to_Pitch2_h_ */ praat-6.0.04/dwtools/Sound_to_SPINET.cpp000066400000000000000000000105431261542461700177760ustar00rootroot00000000000000/* Sound_to_SPINET.cpp * * Copyright (C) 1993-2013, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020813 GPL header djmw 20070103 Sound interface changes */ #include "Sound_to_SPINET.h" #include "NUM2.h" static double fgamma (double x, long n) { double x2p1 = 1 + x * x, d = x2p1; for (long i = 2; i <= n; i++) { d *= x2p1; } return 1 / d; } /* precondition: 0 < minimumFrequencyHz < maximumFrequencyHz */ autoSPINET Sound_to_SPINET (Sound me, double timeStep, double windowDuration, double minimumFrequencyHz, double maximumFrequencyHz, long nFilters, double excitationErbProportion, double inhibitionErbProportion) { try { double firstTime, b = 1.02, samplingFrequency = 1 / my dx; if (timeStep < my dx) { timeStep = my dx; } if (maximumFrequencyHz > samplingFrequency / 2) { maximumFrequencyHz = samplingFrequency / 2; } long numberOfFrames; Sampled_shortTermAnalysis (me, windowDuration, timeStep, &numberOfFrames, &firstTime); autoSPINET thee = SPINET_create (my xmin, my xmax, numberOfFrames, timeStep, firstTime, minimumFrequencyHz, maximumFrequencyHz, nFilters, excitationErbProportion, inhibitionErbProportion); autoSound window = Sound_createGaussian (windowDuration, samplingFrequency); autoSound frame = Sound_createSimple (1, windowDuration, samplingFrequency); autoNUMvector f (1, nFilters); autoNUMvector bw (1, nFilters); autoNUMvector aex (1, nFilters); autoNUMvector ain (1, nFilters); // Cochlear filterbank: gammatone for (long i = 1; i <= nFilters; i++) { f[i] = NUMerbToHertz (thy y1 + (i - 1) * thy dy); bw[i] = 2 * NUMpi * b * (f[i] * (6.23e-6 * f[i] + 93.39e-3) + 28.52); } autoMelderProgress progress (U"SPINET analysis"); for (long i = 1; i <= nFilters; i++) { double bb = (f[i] / 1000) * exp (- f[i] / 1000); // outer & middle ear and phase locking double tgammaMax = (thy gamma - 1) / bw[i]; // Time where gammafunction envelope has maximum double gammaMaxAmplitude = pow ( (thy gamma - 1) / (NUMe * bw[i]), (thy gamma - 1)); // tgammaMax double timeCorrection = tgammaMax - windowDuration / 2; autoSound gammaTone = Sound_createGammaTone (0, 0.1, samplingFrequency, thy gamma, b, f[i], 0, 0, 0); autoSound filtered = Sounds_convolve (me, gammaTone.peek(), kSounds_convolve_scaling_SUM, kSounds_convolve_signalOutsideTimeDomain_ZERO); // To energy measure: weigh with broad-band transfer function for (long j = 1; j <= numberOfFrames; j++) { Sound_into_Sound (filtered.peek(), frame.peek(), Sampled_indexToX (thee.peek(), j) + timeCorrection); Sounds_multiply (frame.peek(), window.peek()); thy y[i][j] = Sound_power (frame.peek()) * bb / gammaMaxAmplitude; } Melder_progress ( (double) i / nFilters, U"SPINET: filter ", i, U" from ", nFilters, U"."); } // Excitatory and inhibitory area functions for (long i = 1; i <= nFilters; i++) { for (long k = 1; k <= nFilters; k++) { double fr = (f[k] - f[i]) / bw[i]; aex[i] += fgamma (fr / thy excitationErbProportion, thy gamma); ain[i] += fgamma (fr / thy inhibitionErbProportion, thy gamma); } } // On-center off-surround interactions for (long j = 1; j <= numberOfFrames; j++) for (long i = 1; i <= nFilters; i++) { double a = 0; for (long k = 1; k <= nFilters; k++) { double fr = (f[k] - f[i]) / bw[i]; double hexsq = fgamma (fr / thy excitationErbProportion, thy gamma); double hinsq = fgamma (fr / thy inhibitionErbProportion, thy gamma); a += thy y[k][j] * (hexsq / aex[i] - hinsq / ain[i]); } thy s[i][j] = a > 0 ? a : 0; } return thee; } catch (MelderError) { Melder_throw (me, U": no SPINET created."); } } /* End of file Sound_to_SPINET.cpp */ praat-6.0.04/dwtools/Sound_to_SPINET.h000066400000000000000000000022761261542461700174470ustar00rootroot00000000000000#ifndef _Sound_to_SPINET_h_ #define _Sound_to_SPINET_h_ /* Sound_to_SPINET.h * * Copyright (C) 1993-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 19970408 djmw 20020813 GPL header djmw 20110307 Latest modification */ #include "SPINET.h" #include "Sound_extensions.h" autoSPINET Sound_to_SPINET (Sound me, double timeStep, double windowDuration, double minimumFrequencyHz, double maximumFrequencyHz, long nFilters, double excitationErbProportion, double inhibitionErbProportion); #endif /* _Sound_to_SPINET_h_ */ praat-6.0.04/dwtools/Sounds_to_DTW.cpp000066400000000000000000000032711261542461700176150ustar00rootroot00000000000000/* Sounds_to_DTW.cpp * * Copyright (C) 2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20120221 */ #include "Sound_to_MFCC.h" #include "Sounds_to_DTW.h" #include "CCs_to_DTW.h" autoDTW Sounds_to_DTW (Sound me, Sound thee, double analysisWidth, double dt, double band, int slope) { try { long numberOfCoefficients = 12; double fmin_mel = 100, df_mel = 100, fmax_mel = 0.0; autoMFCC mfcc_me = Sound_to_MFCC (me, numberOfCoefficients, analysisWidth, dt, fmin_mel, fmax_mel, df_mel); autoMFCC mfcc_thee = Sound_to_MFCC (thee, numberOfCoefficients, analysisWidth, dt, fmin_mel, fmax_mel, df_mel); double wc = 1, wle = 0, wr = 0, wer = 0, dtr = 0; autoDTW him = CCs_to_DTW (mfcc_me.peek(), mfcc_thee.peek(), wc, wle, wr, wer, dtr); autoPolygon p = DTW_to_Polygon (him.peek(), band, slope); DTW_and_Polygon_findPathInside (him.peek(), p.peek(), slope, 0); return him; } catch (MelderError) { Melder_throw (me, U": no DTW created."); } } /* End of file Sounds_to_DTW.cpp */ praat-6.0.04/dwtools/Sounds_to_DTW.h000066400000000000000000000017761261542461700172720ustar00rootroot00000000000000#ifndef _Sounds_to_DTW_h_ #define _Sounds_to_DTW_h_ /* Sounds_to_DTW.h * * Copyright (C) 2012, 2014, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20120221 */ #include "DTW.h" #include "Sound.h" autoDTW Sounds_to_DTW (Sound me, Sound thee, double analysisWidth, double dt, double band, int slope); #endif /* _Sounds_to_DTW_h_ */ praat-6.0.04/dwtools/Spectrogram_extensions.cpp000066400000000000000000000551301261542461700216700ustar00rootroot00000000000000/* Spectrogram_extensions.cpp * * Copyright (C) 2014-2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20140913 */ #include "Eigen_and_Matrix.h" #include "Spectrogram_extensions.h" #include "Matrix_extensions.h" #include "NUM2.h" Thing_implement (BandFilterSpectrogram, Matrix, 2); void structBandFilterSpectrogram :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Time domain:"); MelderInfo_writeLine (U" Start time: ", xmin, U" seconds"); MelderInfo_writeLine (U" End time: ", xmax, U" seconds"); MelderInfo_writeLine (U" Total duration: ", xmax - xmin, U" seconds"); MelderInfo_writeLine (U"Time sampling:"); MelderInfo_writeLine (U" Number of time slices (frames): ", nx); MelderInfo_writeLine (U" Time step (frame distance): ", dx, U" seconds"); MelderInfo_writeLine (U" First time slice (frame centre) at: ", x1, U" seconds"); } void structBarkSpectrogram :: v_info () { structBandFilterSpectrogram :: v_info (); MelderInfo_writeLine (U"Frequency domain:"); MelderInfo_writeLine (U" Lowest frequency: ", ymin, U" ", v_getFrequencyUnit ()); MelderInfo_writeLine (U" Highest frequency: ", ymax, U" ", v_getFrequencyUnit ()); MelderInfo_writeLine (U" Total bandwidth: ", ymax - ymin, U" ", v_getFrequencyUnit ()); MelderInfo_writeLine (U"Frequency sampling:"); MelderInfo_writeLine (U" Number of frequency bands (bins): ", ny); MelderInfo_writeLine (U" Frequency step (bin width): ", dy, U" ", v_getFrequencyUnit ()); MelderInfo_writeLine (U" First frequency band around (bin centre at): ", y1, U" ", v_getFrequencyUnit ()); } void structMelSpectrogram :: v_info () { structBandFilterSpectrogram :: v_info (); MelderInfo_writeLine (U"Frequency domain:"); MelderInfo_writeLine (U" Lowest frequency: ", ymin, U" ", v_getFrequencyUnit ()); MelderInfo_writeLine (U" Highest frequency: ", ymax, U" ", v_getFrequencyUnit ()); MelderInfo_writeLine (U" Total bandwidth: ", ymax - ymin, U" ", v_getFrequencyUnit ()); MelderInfo_writeLine (U"Frequency sampling:"); MelderInfo_writeLine (U" Number of frequency bands (bins): ", ny); MelderInfo_writeLine (U" Frequency step (bin width): ", dy, U" ", v_getFrequencyUnit ()); MelderInfo_writeLine (U" First frequency band around (bin centre at): ", y1, U" ", v_getFrequencyUnit ()); } // Preconditions: 1 <= iframe <= nx; 1 <= irow <= ny double structBandFilterSpectrogram :: v_getValueAtSample (long iframe, long ifreq, int units) { double val = NUMundefined; if (units == 0) { val = z[ifreq][iframe]; } else if (z[ifreq][iframe] > 0) { val = 10 * log10 (z[ifreq][iframe] / 4e-10); // power values } return val; } Thing_implement (BarkSpectrogram, BandFilterSpectrogram, 1); // dbs = scaleFactor * log10 (value/reference); // if (dbs < floor_db) { dbs = floor_dB } autoMatrix Spectrogram_to_Matrix_dB (Spectrogram me, double reference, double scaleFactor, double floor_dB) { try { autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, my ymin, my ymax, my ny, my dy, my y1); for (long i = 1; i <= my ny; i++) { for (long j = 1; j <= my nx; j++) { double val = floor_dB; if (my z[i][j] > 0) { val = scaleFactor * log10 (my z[i][j] / reference); } else if (my z[i][j] < 0) { Melder_throw (U"Negative power in Spectrogram."); } if (val < floor_dB) { val = floor_dB; } thy z[i][j] = val; } } return thee; } catch (MelderError) { Melder_throw (U"Matrix with dB values not created."); } } static double **NUMcosinesTable (long n) { autoNUMmatrix costab (1, n, 1, n); for (long k = 1; k <= n; k++) { for (long j = 1; j <= n; j++) { costab[k][j] = cos (NUMpi * (k - 1) * (j - 0.5) / n); } } return costab.transfer(); } // x[1..n] : input // y[1..n] : output static void NUMcosineTransform (double *x, double *y, long n, double **cosinesTable) { for (long k = 1; k <= n; k++) { y[k] = 0; for (long j = 1; j <= n; j++) { y[k] += x[j] * cosinesTable[k][j]; } } } // x: input // y: output static void NUMinverseCosineTransform (double *x, double *y, long n, double **cosinesTable) { for (long j = 1; j <= n; j++) { y[j] = 0.5 * x[1] * cosinesTable[1][j]; for (long k = 2; k <= n; k++) { y[j] += x[k] * cosinesTable[k][j]; } y[j] *= 2.0 / n; } } /* Precondition: 1. CC object has been created but individual frames not yet initialized * 2. Domains and number of frames conform * Steps: * 1. transform power-spectra to dB-spectra * 2. cosine transform of dB-spectrum */ void BandFilterSpectrogram_into_CC (BandFilterSpectrogram me, CC thee, long numberOfCoefficients) { autoNUMmatrix cosinesTable (NUMcosinesTable (my ny), 1, 1); autoNUMvector x (1, my ny); autoNUMvector y (1, my ny); numberOfCoefficients = numberOfCoefficients > my ny - 1 ? my ny - 1 : numberOfCoefficients; Melder_assert (numberOfCoefficients > 0); // 20130220 new interpretation of maximumNumberOfCoefficients necessary for inverse transform for (long frame = 1; frame <= my nx; frame++) { CC_Frame ccframe = (CC_Frame) & thy frame[frame]; for (long i = 1; i <= my ny; i++) { x[i] = my v_getValueAtSample (frame, i, 1); // z[i][frame]; } NUMcosineTransform (x.peek(), y.peek(), my ny, cosinesTable.peek()); CC_Frame_init (ccframe, numberOfCoefficients); for (long i = 1; i <= numberOfCoefficients; i++) { ccframe -> c[i] = y[i + 1]; } ccframe -> c0 = y[1]; } } // Preconditions: Domains and number of frames conform // 0 <= first <= last <= my ny-1 void CC_into_BandFilterSpectrogram (CC me, BandFilterSpectrogram thee, long first, long last, bool use_c0) { long nf = my maximumNumberOfCoefficients + 1; autoNUMmatrix cosinesTable (NUMcosinesTable (nf), 1, 1); autoNUMvector x (1, nf); autoNUMvector y (1, nf); for (long frame = 1; frame <= my nx; frame++) { CC_Frame ccframe = (CC_Frame) & my frame[frame]; long iend = last < ccframe -> numberOfCoefficients ? last : ccframe -> numberOfCoefficients; x[1] = use_c0 ? ccframe -> c0 : 0; for (long i = 1; i <= my maximumNumberOfCoefficients; i++) { x[i + 1] = i < first || i > iend ? 0 : ccframe -> c[i]; } NUMinverseCosineTransform (x.peek(), y.peek(), nf, cosinesTable.peek()); for (long i = 1; i <= nf; i++) { thy z[i][frame] = BandFilterSpectrogram_DBREF * pow (10, y[i] / BandFilterSpectrogram_DBFAC); } } } autoMelSpectrogram MFCC_to_MelSpectrogram (MFCC me, long first, long last, bool c0) { try { if (first == 0 && last == 0) { // defaults first = 1; last = my maximumNumberOfCoefficients; } if (first < 1) { first = 1; } if (last > my maximumNumberOfCoefficients) { last = my maximumNumberOfCoefficients; } if (first > last) { first = 1; last = my maximumNumberOfCoefficients; } double df = (my fmax - my fmin) / (my maximumNumberOfCoefficients + 1 + 1); autoMelSpectrogram thee = MelSpectrogram_create (my xmin, my xmax, my nx, my dx, my x1, my fmin, my fmax, my maximumNumberOfCoefficients + 1, df, df); CC_into_BandFilterSpectrogram (me, thee.peek(), first, last, c0); return thee; } catch (MelderError) { Melder_throw (me, U"MelSpectrogram not created."); } } autoMFCC MelSpectrogram_to_MFCC (MelSpectrogram me, long numberOfCoefficients) { try { if (numberOfCoefficients <= 0) { numberOfCoefficients = my ny - 1; } numberOfCoefficients = numberOfCoefficients > my ny - 1 ? my ny - 1 : numberOfCoefficients; // 20130220 new interpretation of maximumNumberOfCoefficients necessary for inverse transform autoMFCC thee = MFCC_create (my xmin, my xmax, my nx, my dx, my x1, my ny - 1, my ymin, my ymax); BandFilterSpectrogram_into_CC (me, thee.peek(), numberOfCoefficients); return thee; } catch (MelderError) { Melder_throw (me, U": MFCC not created."); } } autoBarkSpectrogram BarkSpectrogram_create (double tmin, double tmax, long nt, double dt, double t1, double fmin, double fmax, long nf, double df, double f1) { try { autoBarkSpectrogram me = Thing_new (BarkSpectrogram); Matrix_init (me.peek(), tmin, tmax, nt, dt, t1, fmin, fmax, nf, df, f1); return me; } catch (MelderError) { Melder_throw (U"BarkSpectrogram not created."); } } double BandFilterSpectrogram_getFrequencyInHertz (BandFilterSpectrogram me, double f) { return my v_frequencyToHertz (f); } // xmin, xmax in hz versus bark/mel or lin void BandFilterSpectrogram_drawFrequencyScale (BandFilterSpectrogram me, Graphics g, double xmin, double xmax, double ymin, double ymax, int garnish) { if (xmin < 0 || xmax < 0 || ymin < 0 || ymax < 0) { Melder_warning (U"Frequencies must be >= 0."); return; } // scale is in hertz if (xmin >= xmax) { // autoscaling xmin = 0; xmax = my v_frequencyToHertz (my ymax); } if (ymin >= ymax) { // autoscaling ymin = my ymin; ymax = my ymax; } long n = 2000; Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); double dx = (xmax - xmin) / (n - 1); double x1 = xmin, y1 = my v_hertzToFrequency (x1); for (long i = 2; i <= n; i++) { double x2 = x1 + dx, y2 = my v_hertzToFrequency (x2); if (NUMdefined (y1) && NUMdefined (y2)) { double xo1, yo1, xo2, yo2; if (NUMclipLineWithinRectangle (x1, y1, x2, y2, xmin, ymin, xmax, ymax, &xo1, &yo1, &xo2, &yo2)) { Graphics_line (g, xo1, yo1, xo2, yo2); } } x1 = x2; y1 = y2; } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksLeft (g, 2, true, true, false); Graphics_textLeft (g, true, Melder_cat (U"Frequency (", my v_getFrequencyUnit (), U")")); Graphics_marksBottom (g, 2, true, true, false); Graphics_textBottom (g, true, U"Frequency (Hz)"); } } void BandFilterSpectrogram_paintImage (BandFilterSpectrogram me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum, int garnish) { if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } long ixmin, ixmax, iymin, iymax; (void) Matrix_getWindowSamplesX (me, xmin - 0.49999 * my dx, xmax + 0.49999 * my dx, &ixmin, &ixmax); (void) Matrix_getWindowSamplesY (me, ymin - 0.49999 * my dy, ymax + 0.49999 * my dy, &iymin, &iymax); autoMatrix thee = Spectrogram_to_Matrix_dB ((Spectrogram) me, 4e-10, 10, -100); if (maximum <= minimum) { (void) Matrix_getWindowExtrema (thee.peek(), ixmin, ixmax, iymin, iymax, &minimum, &maximum); } if (maximum <= minimum) { minimum -= 1.0; maximum += 1.0; } if (xmin >= xmax || ymin >= ymax) { return; } Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_image (g, thy z, ixmin, ixmax, Sampled_indexToX (thee.peek(), ixmin - 0.5), Sampled_indexToX (thee.peek(), ixmax + 0.5), iymin, iymax, SampledXY_indexToY (thee.peek(), iymin - 0.5), SampledXY_indexToY (thee.peek(), iymax + 0.5), minimum, maximum); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksLeft (g, 2, true, true, false); Graphics_textLeft (g, true, Melder_cat (U"Frequency (", my v_getFrequencyUnit (), U")")); Graphics_marksBottom (g, 2, true, true, false); Graphics_textBottom (g, true, U"Time (s)"); } } void BandFilterSpectrogram_drawSpectrumAtNearestTimeSlice (BandFilterSpectrogram me, Graphics g, double time, double fmin, double fmax, double dBmin, double dBmax, int garnish) { if (time < my xmin || time > my xmax) { return; } if (fmin == 0 && fmax == 0) { // autoscaling fmin = my ymin; fmax = my ymax; } if (fmax <= fmin) { fmin = my ymin; fmax = my ymax; } long icol = Matrix_xToNearestColumn (me, time); icol = icol < 1 ? 1 : (icol > my nx ? my nx : icol); autoNUMvector spectrum (1, my ny); for (long i = 1; i <= my ny; i++) { spectrum[i] = my v_getValueAtSample (icol, i, 1); // dB's } long iymin, iymax; if (Matrix_getWindowSamplesY (me, fmin, fmax, &iymin, &iymax) < 2) { // too few values return; } if (dBmin == dBmax) { // autoscaling dBmin = spectrum[iymin]; dBmax = dBmin; for (long i = iymin + 1; i <= iymax; i++) { if (spectrum[i] < dBmin) { dBmin = spectrum[i]; } else if (spectrum[i] > dBmax) { dBmax = spectrum[i]; } } if (dBmin == dBmax) { dBmin -= 1; dBmax += 1; } } Graphics_setWindow (g, fmin, fmax, dBmin, dBmax); Graphics_setInner (g); double x1 = my y1 + (iymin -1) * my dy, y1 = spectrum[iymin]; for (long i = iymin + 1; i <= iymax - 1; i++) { double x2 = my y1 + (i -1) * my dy, y2 = spectrum[i]; double xo1, yo1, xo2, yo2; if (NUMclipLineWithinRectangle (x1, y1, x2, y2, fmin, dBmin, fmax, dBmax, &xo1, &yo1, &xo2, &yo2)) { Graphics_line (g, xo1, yo1, xo2, yo2); } x1 = x2; y1 = y2; } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); Graphics_textLeft (g, true, U"Power (dB)"); Graphics_textBottom (g, true, Melder_cat (U"Frequency (", my v_getFrequencyUnit (), U")")); } } void BarkSpectrogram_drawSekeyHansonFilterFunctions (BarkSpectrogram me, Graphics g, bool xIsHertz, int fromFilter, int toFilter, double zmin, double zmax, bool yscale_dB, double ymin, double ymax, int garnish) { double xmin = zmin, xmax = zmax; if (zmin >= zmax) { zmin = my ymin; zmax = my ymax; xmin = xIsHertz ? my v_frequencyToHertz (zmin) : zmin; xmax = xIsHertz ? my v_frequencyToHertz (zmax) : zmax; } if (xIsHertz) { zmin = my v_hertzToFrequency (xmin); zmax = my v_hertzToFrequency (xmax); } if (ymin >= ymax) { ymin = yscale_dB ? -60 : 0.0; ymax = yscale_dB ? 0.0 : 1.0; } fromFilter = fromFilter <= 0 ? 1 : fromFilter; toFilter = toFilter <= 0 || toFilter > my ny ? my ny : toFilter; if (fromFilter > toFilter) { fromFilter = 1; toFilter = my ny; } long n = xIsHertz ? 1000 : 500; autoNUMvector xz (1, n), xhz (1,n), y (1, n); Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); double dz = (zmax - zmin) / (n - 1); for (long iz = 1; iz <= n; iz++) { double f = zmin + (iz - 1) * dz; xz[iz] = f; xhz[iz] = my v_frequencyToHertz (f); // just in case we need the linear scale } for (long ifilter = fromFilter; ifilter <= toFilter; ifilter++) { double zMid = Matrix_rowToY (me, ifilter); for (long iz = 1; iz <= n; iz++) { double z = xz[iz] - (zMid - 0.215); double amp = 7.0 - 7.5 * z - 17.5 * sqrt (0.196 + z * z); y[iz] = yscale_dB ? amp : pow (10.0, amp / 10.0); } // the drawing double x1 = xIsHertz ? xhz[1] : xz[1], y1 = y[1]; for (long iz = 2; iz <= n; iz++) { double x2 = xIsHertz ? xhz[iz] : xz[iz], y2 = y[iz]; if (NUMdefined (x1) && NUMdefined (x2)) { double xo1, yo1, xo2, yo2; if (NUMclipLineWithinRectangle (x1, y1, x2, y2, xmin, ymin, xmax, ymax, &xo1, &yo1, &xo2, &yo2)) { Graphics_line (g, xo1, yo1, xo2, yo2); } } x1 = x2; y1 = y2; } } Graphics_unsetInner (g); if (garnish) { double distance = yscale_dB ? 10.0 : 0.5; Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeftEvery (g, 1.0, distance, true, true, false); Graphics_textLeft (g, true, yscale_dB ? U"Amplitude (dB)" : U"Amplitude"); Graphics_textBottom (g, true, Melder_cat (U"Frequency (", xIsHertz ? U"Hz" : my v_getFrequencyUnit (), U")")); } } Thing_implement (MelSpectrogram, BandFilterSpectrogram, 2); autoMelSpectrogram MelSpectrogram_create (double tmin, double tmax, long nt, double dt, double t1, double fmin, double fmax, long nf, double df, double f1) { try { autoMelSpectrogram me = Thing_new (MelSpectrogram); Matrix_init (me.peek(), tmin, tmax, nt, dt, t1, fmin, fmax, nf, df, f1); return me; } catch (MelderError) { Melder_throw (U"MelSpectrogram not created."); } } void BandFilterSpectrogram_drawTimeSlice (I, Graphics g, double t, double fmin, double fmax, double min, double max, const char32 *xlabel, int garnish) { iam (Matrix); Matrix_drawSliceY (me, g, t, fmin, fmax, min, max); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); if (xlabel) { Graphics_textBottom (g, false, xlabel); } } } void MelSpectrogram_drawTriangularFilterFunctions (MelSpectrogram me, Graphics g, bool xIsHertz, int fromFilter, int toFilter, double zmin, double zmax, bool yscale_dB, double ymin, double ymax, int garnish) { double xmin = zmin, xmax = zmax; if (zmin >= zmax) { zmin = my ymin; zmax = my ymax; // mel xmin = xIsHertz ? my v_frequencyToHertz (zmin) : zmin; xmax = xIsHertz ? my v_frequencyToHertz (zmax) : zmax; } if (xIsHertz) { zmin = my v_hertzToFrequency (xmin); zmax = my v_hertzToFrequency (xmax); } if (ymin >= ymax) { ymin = yscale_dB ? -60.0 : 0.0; ymax = yscale_dB ? 0.0 : 1.0; } fromFilter = fromFilter <= 0 ? 1 : fromFilter; toFilter = toFilter <= 0 || toFilter > my ny ? my ny : toFilter; if (fromFilter > toFilter) { fromFilter = 1; toFilter = my ny; } long n = xIsHertz ? 1000 : 500; autoNUMvector xz (1, n), xhz (1,n), y (1, n); Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); double dz = (zmax - zmin) / (n - 1); for (long iz = 1; iz <= n; iz++) { double f = zmin + (iz - 1) * dz; xz[iz] = f; xhz[iz] = my v_frequencyToHertz (f); // just in case we need the linear scale } for (long ifilter = fromFilter; ifilter <= toFilter; ifilter++) { double zc = Matrix_rowToY (me, ifilter), zl = zc - my dy, zh = zc + my dy; double xo1, yo1, xo2, yo2; if (yscale_dB) { for (long iz = 1; iz <= n; iz++) { double z = xz[iz]; double amp = NUMtriangularfilter_amplitude (zl, zc, zh, z); y[iz] = yscale_dB ? (amp > 0.0 ? 20.0 * log10 (amp) : ymin - 10.0) : amp; } double x1 = xIsHertz ? xhz[1] : xz[1], y1 = y[1]; if (NUMdefined (y1)) { for (long iz = 1; iz <= n; iz++) { double x2 = xIsHertz ? xhz[iz] : xz[iz], y2 = y[iz]; if (NUMdefined (y2)) { if (NUMclipLineWithinRectangle (x1, y1, x2, y2, xmin, ymin, xmax, ymax, &xo1, &yo1, &xo2, &yo2)) { Graphics_line (g, xo1, yo1, xo2, yo2); } } x1 = x2; y1 = y2; } } } else { double x1 = xIsHertz ? my v_frequencyToHertz (zl) : zl; double x2 = xIsHertz ? my v_frequencyToHertz (zc) : zc; if (NUMclipLineWithinRectangle (x1, 0, x2, 1, xmin, ymin, xmax, ymax, &xo1, &yo1, &xo2, &yo2)) { Graphics_line (g, xo1, yo1, xo2, yo2); } double x3 = xIsHertz ? my v_frequencyToHertz (zh) : zh; if (NUMclipLineWithinRectangle (x2, 1, x3, 0, xmin, ymin, xmax, ymax, &xo1, &yo1, &xo2, &yo2)) { Graphics_line (g, xo1, yo1, xo2, yo2); } } } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeftEvery (g, 1.0, yscale_dB ? 10.0 : 0.5, true, true, false); Graphics_textLeft (g, true, yscale_dB ? U"Amplitude (dB)" : U"Amplitude"); Graphics_textBottom (g, true, Melder_cat (U"Frequency (", ( xIsHertz ? U"Hz" : my v_getFrequencyUnit () ), U")")); } } autoMatrix BandFilterSpectrogram_to_Matrix (BandFilterSpectrogram me, int to_dB) { try { int units = to_dB ? 1 : 0; autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, my ymin, my ymax, my ny, my dy, my y1); for (long i = 1; i <= my ny; i++) { for (long j = 1; j <= my nx; j++) { thy z[i][j] = my v_getValueAtSample (j, i, units); } } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Matrix."); } } autoBarkSpectrogram Matrix_to_BarkSpectrogram (Matrix me) { try { autoBarkSpectrogram thee = BarkSpectrogram_create (my xmin, my xmax, my nx, my dx, my x1, my ymin, my ymax, my ny, my dy, my y1); NUMmatrix_copyElements (my z, thy z, 1, my ny, 1, my nx); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to BarkSpectrogram."); } } autoMelSpectrogram Matrix_to_MelSpectrogram (Matrix me) { try { autoMelSpectrogram thee = MelSpectrogram_create (my xmin, my xmax, my nx, my dx, my x1, my ymin, my ymax, my ny, my dy, my y1); NUMmatrix_copyElements (my z, thy z, 1, my ny, 1, my nx); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to MelSpectrogram."); } } autoIntensity BandFilterSpectrogram_to_Intensity (BandFilterSpectrogram me) { try { autoIntensity thee = Intensity_create (my xmin, my xmax, my nx, my dx, my x1); for (long j = 1; j <= my nx; j++) { double p = 0; for (long i = 1; i <= my ny; i++) { p += my z[i][j]; // we add power } thy z[1][j] = BandFilterSpectrogram_DBFAC * log10 (p / BandFilterSpectrogram_DBREF); } return thee; } catch (MelderError) { Melder_throw (me, U": Intensity not created."); } } void BandFilterSpectrogram_equalizeIntensities (BandFilterSpectrogram me, double intensity_db) { for (long j = 1; j <= my nx; j++) { double p = 0; for (long i = 1; i <= my ny; i++) { p += my z[i][j]; } double delta_db = intensity_db - BandFilterSpectrogram_DBFAC * log10 (p / BandFilterSpectrogram_DBREF); double factor = pow (10, delta_db / 10); for (long i = 1; i <= my ny; i++) { my z[i][j] *= factor; } } } void BandFilterSpectrogram_and_PCA_drawComponent (BandFilterSpectrogram me, PCA thee, Graphics g, long component, double dblevel, double frequencyOffset, double scale, double tmin, double tmax, double fmin, double fmax) { if (component < 1 || component > thy numberOfEigenvalues) { Melder_throw (U"Component too large."); } // Scale Intensity autoBandFilterSpectrogram fcopy = (BandFilterSpectrogram) Data_copy (me); BandFilterSpectrogram_equalizeIntensities (fcopy.peek(), dblevel); autoMatrix mdb = Spectrogram_to_Matrix_dB ((Spectrogram) fcopy.peek(), BandFilterSpectrogram_DBREF, BandFilterSpectrogram_DBFAC, BandFilterSpectrogram_DBFLOOR); autoMatrix him = Eigen_and_Matrix_project (thee, mdb.peek(), component); for (long j = 1; j <= my nx; j++) { his z[component][j] = frequencyOffset + scale * his z[component][j]; } Matrix_drawRows (him.peek(), g, tmin, tmax, component - 0.5, component + 0.5, fmin, fmax); } /* * MelSpectrograms_to_DTW (MelSpectrogram me, MelSpectrogram thee, dtw-params); * comparison on the basis of mfcc * BarkSpectrograms_to_DTW (BarkSpectrogram me, BarkSpectrogram thee, dtw-params); * comparison on the basis of bfcc! */ /* End of file Spectrogram_extensions.cpp */ praat-6.0.04/dwtools/Spectrogram_extensions.h000066400000000000000000000130161261542461700213320ustar00rootroot00000000000000#ifndef _Spectrogram_extensions_h_ #define _Spectrogram_extensions_h_ /* Spectrogram_extensions.h * * Copyright (C) 2014, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20140913 */ #include "Intensity.h" #include "MFCC.h" #include "PCA.h" #include "Spectrogram.h" #include "Spectrum.h" #include "TableOfReal.h" #include "NUM2.h" #define HZTOBARK(x) NUMhertzToBark2(x) #define HZTOMEL(x) NUMhertzToMel2(x) #define BARKTOHZ(x) NUMbarkToHertz2(x) #define MELTOHZ(x) NUMmelToHertz2(x) #define BARKTOMEL(x) HZTOMEL(BARKTOHZ(x)) #define MELTOBARK(x) HZTOBARK(MELTOHZ(x)) #define BandFilterSpectrogram_DBREF 4e-10 #define BandFilterSpectrogram_DBFAC 10 #define BandFilterSpectrogram_DBFLOOR -100 #define BandFilterSpectrogram_HERTZ 1 #define BandFilterSpectrogram_BARK 2 #define BandFilterSpectrogram_MEL 3 Thing_define (BandFilterSpectrogram, Matrix) { void v_info () override; double v_getValueAtSample (long icol, long irow, int units) override; virtual double v_frequencyToHertz (double f) { return f; } virtual double v_hertzToFrequency (double hertz) { return hertz; } virtual const char32 *v_getFrequencyUnit () { return U"Hz"; } }; Thing_define (BarkSpectrogram, BandFilterSpectrogram) { void v_info () override; double v_frequencyToHertz (double f) override { return NUMbarkToHertz2 (f); } double v_hertzToFrequency (double hertz) override { return NUMhertzToBark2 (hertz); } const char32 *v_getFrequencyUnit () override { return U"bark"; } }; Thing_define (MelSpectrogram, BandFilterSpectrogram) { void v_info () override; double v_frequencyToHertz (double f) override { return NUMmelToHertz2 (f); } double v_hertzToFrequency (double hertz) override { return NUMhertzToMel2 (hertz); } const char32 *v_getFrequencyUnit () override { return U"mel"; } }; /* Interpretation: xmin, xmax, x1, dx, nx like Sampled. ymin, ymax lowest and highest frequencies in Barks / Mel. y1 mid of first filter (bark/mel). dy distance between filters (bark/mel). ny the number of filters. */ double BandFilterSpectrogram_getFrequencyInHertz (BandFilterSpectrogram me, double f); void BandFilterSpectrogram_equalizeIntensities (BandFilterSpectrogram me, double intensity_db); autoMatrix BandFilterSpectrogram_to_Matrix (BandFilterSpectrogram me, int to_dB); autoIntensity BandFilterSpectrogram_to_Intensity (BandFilterSpectrogram me); void BandFilterSpectrogram_drawFrequencyScale (BandFilterSpectrogram me, Graphics g, double xmin, double xmax, double ymin, double ymax, int garnish); void BandFilterSpectrogram_drawTimeSlice (I, Graphics g, double t, double fmin, double fmax, double min, double max, const char32 *xlabel, int garnish); void BarkSpectrogram_drawSekeyHansonFilterFunctions (BarkSpectrogram me, Graphics g, bool xIsHertz, int fromFilter, int toFilter, double zmin, double zmax, bool yscale_dB, double ymin, double ymax, int garnish); void BandFilterSpectrogram_drawSpectrumAtNearestTimeSlice (BandFilterSpectrogram me, Graphics g, double time, double fmin, double fmax, double dBmin, double dBmax, int garnish); void BandFilterSpectrogram_paintImage (BandFilterSpectrogram me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum, int garnish); autoBarkSpectrogram BarkSpectrogram_create (double tmin, double tmax, long nt, double dt, double t1, double fmin, double fmax, long nf, double df, double f1); autoBarkSpectrogram Matrix_to_BarkSpectrogram (Matrix me); /* Interpretation: xmin, xmax, x1, dx, nx like Sampled. ymin, ymax lowest and highest frequencies in mels. y1 mid of first filter (mels). dy distance between filters (mel). ny the number of filters. */ autoMelSpectrogram MelSpectrogram_create (double tmin, double tmax, long nt, double dt, double t1, double fmin, double fmax, long nf, double df, double f1); autoMelSpectrogram Matrix_to_MelSpectrogram (Matrix me); void MelSpectrogram_drawTriangularFilterFunctions (MelSpectrogram me, Graphics g, bool xIsHertz, int fromFilter, int toFilter, double zmin, double zmax, bool yscale_dB, double ymin, double ymax, int garnish); autoMFCC MelSpectrogram_to_MFCC (MelSpectrogram me, long numberOfCoefficients); autoMelSpectrogram MFCC_to_MelSpectrogram (MFCC me, long first, long last, bool c0); void BandFilterSpectrogram_and_PCA_drawComponent (BandFilterSpectrogram me, PCA thee, Graphics g, long component, double dblevel, double frequencyOffset, double scale, double tmin, double tmax, double fmin, double fmax); autoMatrix Spectrogram_to_Matrix_dB (Spectrogram me, double reference, double scaleFactor, double floor_dB); // dbs = scaleFactor * log10 (value/reference); // if (dbs < floor_db) { dbs = floor_dB } void BandFilterSpectrogram_into_CC (BandFilterSpectrogram me, CC thee, long numberOfCoefficients); void CC_into_BandFilterSpectrogram (CC me, BandFilterSpectrogram thee, long first, long last, bool use_c0); #endif /* _Spectrogram_extensions_h_ */ praat-6.0.04/dwtools/Spectrum_extensions.cpp000066400000000000000000000312631261542461700212050ustar00rootroot00000000000000/* Spectrum_extensions.cpp * * Copyright (C) 1993-2013 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20010718 djmw 20020813 GPL header djmw 20030929 Added a warning in Spectrum_drawPhases. djmw 20031023 New: Spectra_multiply, Spectrum_conjugate djmw 20040506 Changed warning message in Spectrum_drawPhases. djmw 20041124 Changed call to Sound_to_Spectrum. djmw 20061218 Introduction of Melder_information<12...9> djmw 20071022 phase_unwrap initialize phase = 0. djmw 20080122 float -> double djmw 20080202 Warning in Spectrum_drawPhases to wchar djmw 20080411 Removed define NUM2pi */ #include "Ltas.h" #include "Spectrum_extensions.h" #include "Sound_and_Spectrum.h" #include "NUM2.h" #define SIGN(x,s) ((s) < 0 ? -fabs (x) : fabs(x)) #define THLCON 0.5 #define THLINC 1.5 #define EXP2 12 #define PPVPHA(x,y,test) ((test) ? atan2 (-(y),-(x)) : atan2 ((y),(x))) #define PHADVT(xr,xi,yr,yi,xa) ((xa) > 0 ? ((xr)*(yr)+(xi)*(yi))/ (xa) : 0) struct tribolet_struct { double thlinc, thlcon; double ddf, dvtmn2; double *x; long nx, l, count; int reverse_sign; }; /* Perform modified Goertzel algorithm to calculate, at frequency 'freq_rad', the real and imaginary part of the spectrum and the d/df of the spectrum of x. Reference: Bonzanigo (1978), IEEE Trans. ASSP, Vol. 26. */ static void getSpectralValues (struct tribolet_struct *tbs, double freq_rad, double *xr, double *xi, double *nxr, double *nxi) { double cosf = cos (freq_rad), sinf = sin (freq_rad); double a = 2 * cosf, b, u1 = 0, u2 = u1, w1 = u1, w2 = u1; double *x = tbs -> x; long nx = tbs -> nx; for (long j = 1; j <= nx; j++) { double xj = x[j]; double u0 = xj + a * u1 - u2; double w0 = (j - 1) * xj + a * w1 - w2; u2 = u1; u1 = u0; w2 = w1; w1 = w0; } /* Bonzanigo's phase correction */ a = freq_rad * (nx - 1); u1 = cos (a); u2 = - sin (a); a = u1 - u2 * cosf; b = u2 * sinf; *xr = u1 * a - u2 * b; *xi = u2 * a + u1 * b; a = w1 - w2 * cosf; b = w2 * sinf; *nxr = u1 * a - u2 * b; *nxi = u2 * a + u1 * b; tbs -> count ++; } /* Find the closest unwrapped phase estimate from the two admissible phase values (a1 & a2). */ static int phase_check (double pv, double *phase, double thlcon) { double a0 = (*phase - pv) / NUM2pi; long k = (long) floor (a0); // ppgb: instead of truncation toward zero double a1 = pv + k * NUM2pi; double a2 = a1 + SIGN (NUM2pi, a0); double a3 = fabs (a1 - *phase); double a4 = fabs (a2 - *phase); if (a3 > thlcon && a4 > thlcon) { return 0; } *phase = a3 > a4 ? a2 : a1; return 1; } /* Phase unwrapping based on Tribolet's adaptive integration method. the unwrapped phase estimate is returned. */ static double phase_unwrap (struct tribolet_struct *tbs, double pfreq, double ppv, double pdvt, double *pphase, double *ppdvt) { double sdvt[25], sppv[25]; double freq, phase = 0, phase_inc; double delta, xr, xi, xmsq, nxr, nxi; long k, sindex[25], pindex = 1, sp = 1; sppv[sp] = ppv; sdvt[sp] = pdvt; sindex[sp] = tbs -> l + 1; goto p40; p20: /* When the routine runs out of stack space, there probably is a zero very near the unit circle that results in a jump of pi in the phase. */ if ( (sindex[sp] - pindex) <= 1) { return phase; } /* p30: Get the intermediate frequency value and compute its phase derivative and principal value. */ k = (sindex[sp] + pindex) / 2; freq = pfreq + (k - 1) * tbs -> ddf; getSpectralValues (tbs, freq, &xr, &xi, &nxr, &nxi); sindex[++sp] = k; sppv[sp] = PPVPHA (xr, xi, tbs -> reverse_sign); xmsq = xr * xr + xi * xi; sdvt[sp] = PHADVT (xr, xi, nxr, nxi, xmsq); p40: /* Evaluate the phase increment. If the phase increment, reduced by the expected linear phase increment, is greater than the specified threshold, adapt step size. */ delta = 0.5 * tbs -> ddf * (sindex[sp] - pindex); phase_inc = delta * (*ppdvt + sdvt[sp]); if (fabs (phase_inc - delta * tbs -> dvtmn2) > tbs -> thlinc) { goto p20; } phase = *pphase + phase_inc; if (! phase_check (sppv[sp], &phase, tbs -> thlcon)) { goto p20; } if (fabs (phase - *pphase) > NUMpi) { goto p20; } if (sp == 1) { return phase; } /* p10: Update previous estimate. */ pindex = sindex[sp]; *pphase = phase; *ppdvt = sdvt[sp--]; goto p40; } Matrix Spectrum_unwrap (Spectrum me) { try { struct tribolet_struct tbs; int remove_linear_part = 1; long nfft = 2; while (nfft < my nx - 1) { nfft *= 2; } nfft *= 2; if (nfft / 2 != my nx - 1) { Melder_throw (U"Dimension of Spectrum is not (power of 2 - 1)."); } autoSound x = Spectrum_to_Sound (me); autoSound nx = Data_copy (x.peek()); for (long i = 1; i <= x -> nx; i++) { nx -> z[1][i] *= (i - 1); } autoSpectrum snx = Sound_to_Spectrum (nx.peek(), 1); autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, 1, 2, 2, 1, 1); // Common variables. tbs.thlinc = THLINC; tbs.thlcon = THLCON; tbs.x = x -> z[1]; tbs.nx = x -> nx; tbs.l = (long) floor (pow (2, EXP2) + 0.1); tbs.ddf = NUM2pi / ( (tbs.l) * nfft); tbs.reverse_sign = my z[1][1] < 0; tbs.count = 0; // Reuse snx : put phase derivative (d/df) in imaginary part. tbs.dvtmn2 = 0; for (long i = 1; i <= my nx; i ++) { double xr = my z[1][i], xi = my z[2][i]; double nxr = snx -> z[1][i], nxi = snx -> z[2][i]; double xmsq = xr * xr + xi * xi; double pdvt = PHADVT (xr, xi, nxr, nxi, xmsq); thy z[1][i] = xmsq; snx -> z[2][i] = pdvt; tbs.dvtmn2 += pdvt; } tbs.dvtmn2 = (2 * tbs.dvtmn2 - snx -> z[2][1] - snx -> z[2][my nx]) / (my nx - 1); autoMelderProgress progress (U"Phase unwrapping"); double pphase = 0, phase = 0; double ppdvt = snx -> z[2][1]; thy z[2][1] = PPVPHA (my z[1][1], my z[2][1], tbs.reverse_sign); for (long i = 2; i <= my nx; i ++) { double pfreq = NUM2pi * (i - 1) / nfft; double pdvt = snx -> z[2][i]; double ppv = PPVPHA (my z[1][i], my z[2][i], tbs.reverse_sign); phase = phase_unwrap (&tbs, pfreq, ppv, pdvt, &pphase, &ppdvt); ppdvt = pdvt; thy z[2][i] = pphase = phase; Melder_progress ( (double) i / my nx, i, U" unwrapped phases from ", my nx, U"."); } long iphase = (long) floor (phase / NUMpi + 0.1); // ppgb: better than truncation toward zero if (remove_linear_part) { phase /= my nx - 1; for (long i = 2; i <= my nx; i ++) { thy z[2][i] -= phase * (i - 1); } } Melder_information (U"Number of spectral values: ", tbs.count); Melder_information (U" iphase = ", iphase); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not unwrapped."); } } void Spectrum_drawPhases (Spectrum me, Graphics g, double fmin, double fmax, double phase_min, double phase_max, int unwrap, int garnish) { autoMatrix thee; int reverse_sign = my z[1][1] < 0; if (unwrap) { thee = Spectrum_unwrap (me); } else { thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, 1.0, 2.0, 2, 1.0, 1.0); for (long i = 1; i <= my nx; i ++) { thy z[2][i] = PPVPHA (my z[1][i], my z[2][i], reverse_sign); } } Matrix_drawRows (thee.peek(), g, fmin, fmax, 1.9, 2.1, phase_min, phase_max); if (garnish) { } } Spectrum Spectra_multiply (Spectrum me, Spectrum thee) { try { if (my nx != thy nx || my x1 != thy x1 || my xmax != thy xmax || my dx != thy dx) { Melder_throw (U"Dimensions of both spectra do not conform."); } autoSpectrum him = Data_copy (me); for (long i = 1; i <= his nx; i++) { his z[1][i] = my z[1][i] * thy z[1][i] - my z[2][i] * thy z[2][i]; his z[2][i] = my z[1][i] * thy z[2][i] + my z[2][i] * thy z[1][i]; } return him.transfer(); } catch (MelderError) { Melder_throw (me, U": not multiplied."); } } void Spectrum_conjugate (Spectrum me) { for (long i = 1; i <= my nx; i++) { my z[2][i] = - my z[2][i]; } } Spectrum Spectrum_resample (Spectrum me, long numberOfFrequencies) { try { double newSamplingFrequency = (1 / my dx) * numberOfFrequencies / my nx; // resample real and imaginary part ! autoSound thee = Sound_resample ((Sound) me, newSamplingFrequency, 50); autoSpectrum him = Spectrum_create (my xmax, numberOfFrequencies); NUMmatrix_copyElements (thy z, his z, 1, 2, 1, numberOfFrequencies); return him.transfer(); } catch (MelderError) { Melder_throw (me, U": not resampled."); } } static Spectrum Spectrum_shiftFrequencies2 (Spectrum me, double shiftBy, bool changeMaximumFrequency) { try { double xmax = my xmax; long numberOfFrequencies = my nx, interpolationDepth = 50; if (changeMaximumFrequency) { xmax += shiftBy; numberOfFrequencies += (xmax - my xmax) / my dx; } autoSpectrum thee = Spectrum_create (xmax, numberOfFrequencies); // shiftBy >= 0 for (long i = 1; i <= thy nx; i++) { double thyf = thy x1 + (i - 1) * thy dx; double myf = thyf - shiftBy; if (myf >= my xmin && myf <= my xmax) { double index = Sampled_xToIndex (me, myf); thy z[1][i] = NUM_interpolate_sinc (my z[1], my nx, index, interpolationDepth); thy z[2][i] = NUM_interpolate_sinc (my z[2], my nx, index, interpolationDepth); } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not shifted."); } } Spectrum Spectrum_shiftFrequencies (Spectrum me, double shiftBy, double newMaximumFrequency, long interpolationDepth) { try { double xmax = my xmax; long numberOfFrequencies = my nx; if (newMaximumFrequency != 0) { numberOfFrequencies = (long) floor (newMaximumFrequency / my dx) + 1; xmax = newMaximumFrequency; } autoSpectrum thee = Spectrum_create (xmax, numberOfFrequencies); // shiftBy >= 0 for (long i = 1; i <= thy nx; i++) { double thyf = thy x1 + (i - 1) * thy dx; double myf = thyf - shiftBy; if (myf >= my xmin && myf <= my xmax) { double index = Sampled_xToIndex (me, myf); thy z[1][i] = NUM_interpolate_sinc (my z[1], my nx, index, interpolationDepth); thy z[2][i] = NUM_interpolate_sinc (my z[2], my nx, index, interpolationDepth); } } // Make imaginary part of first and last sample zero // so Spectrum_to_Sound uses FFT if numberOfSamples was power of 2! double amp = sqrt (thy z[1][1] * thy z[1][1] + thy z[2][1] * thy z[2][1]); thy z[1][1] = amp; thy z[2][1] = 0; amp = sqrt (thy z[1][thy nx] * thy z[1][thy nx] + thy z[2][thy nx] * thy z[2][thy nx]); thy z[1][thy nx] = amp; thy z[2][thy nx] = 0; return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not shifted."); } } Spectrum Spectrum_compressFrequencyDomain (Spectrum me, double fmax, long interpolationDepth, int freqscale, int method) { try { double fdomain = my xmax - my xmin, factor = fdomain / fmax ; //long numberOfFrequencies = 1.0 + fmax / my dx; // keep dx the same, otherwise the "duration" changes double xmax = my xmax / factor; long numberOfFrequencies = (long) floor (my nx / factor); // keep dx the same, otherwise the "duration" changes autoSpectrum thee = Spectrum_create (xmax, numberOfFrequencies); thy z[1][1] = my z[1][1]; thy z[2][1] = my z[2][1]; double df = freqscale == 1 ? factor * my dx : log10 (fdomain) / (numberOfFrequencies - 1); for (long i = 2; i <= numberOfFrequencies; i++) { double f = my xmin + (freqscale == 1 ? (i - 1) * df : pow (10.0, (i - 1) * df)); double x, y, index = (f - my x1) / my dx + 1; if (index > my nx) { break; } if (method == 1) { x = NUM_interpolate_sinc (my z[1], my nx, index, interpolationDepth); y = NUM_interpolate_sinc (my z[2], my nx, index, interpolationDepth); } else { x = NUMundefined; // ppgb: better than data from random memory y = NUMundefined; } thy z[1][i] = x; thy z[2][i] = y; } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not compressed."); } } static void Spectrum_fitTiltLine (Spectrum me, double fmin, double fmax, bool logf, double bandwidth, double *a, double *intercept, int method) { (void) me; (void) fmin; (void) fmax; (void) logf; (void) bandwidth; (void) a; (void) intercept; (void) method; try { } catch (MelderError) { Melder_throw (U"Tilt line not fitted."); } } /* End of file Spectrum_extensions.cpp */ praat-6.0.04/dwtools/Spectrum_extensions.h000066400000000000000000000037711261542461700206550ustar00rootroot00000000000000#ifndef _Spectrum_extensions_h_ #define _Spectrum_extensions_h_ /* Spectrum_extensions.h * * Copyright (C) 1993-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20010114 djmw 20020813 GPL header djmw 20121022 Latest modification */ #include "Spectrum.h" #include "Sound.h" #include "Graphics.h" Spectrum Spectrum_resample (Spectrum me, long numberOfFrequencies); Spectrum Spectrum_compressFrequencyDomain (Spectrum me, double fmax, long interpolationDepth, int freqscale, int method); Spectrum Spectrum_shiftFrequencies (Spectrum me, double shiftBy, double newMaximumFrequency, long interpolationDepth); // Shift will be plusminus dx/2 Matrix Spectrum_unwrap (Spectrum me); /* Unwrap the phases of the spectrum according to an algorithm by Tribolet as published in: Tribolet, J.M. & Quatieri, T.F. (1979), Computation of the Complex Spectrum, in: Programs for Digital Signal Processing, Digital Signal Processing Commitee (eds), IEEE Press, chapter 7.1. First row of returned matrix contains the amplitudes-squared, second row contains the unwrapped phases. */ void Spectrum_drawPhases (Spectrum me, Graphics g, double fmin, double fmax, double phase_min, double phase_max, int unwrap, int garnish); Spectrum Spectra_multiply (Spectrum me, Spectrum thee); void Spectrum_conjugate (Spectrum me); #endif /* _Spectrum_extensions_h_ */ praat-6.0.04/dwtools/SpeechSynthesizer.cpp000066400000000000000000000536761261542461700206170ustar00rootroot00000000000000/* SpeechSynthesizer.cpp * // * Copyright (C) 2011-2013, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20111214 */ #include "SpeechSynthesizer.h" #include "Strings_extensions.h" #include "translate.h" #include "oo_DESTROY.h" #include "SpeechSynthesizer_def.h" #include "oo_COPY.h" #include "SpeechSynthesizer_def.h" #include "oo_EQUAL.h" #include "SpeechSynthesizer_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "SpeechSynthesizer_def.h" #include "oo_WRITE_TEXT.h" #include "SpeechSynthesizer_def.h" #include "oo_WRITE_BINARY.h" #include "SpeechSynthesizer_def.h" #include "oo_READ_TEXT.h" #include "SpeechSynthesizer_def.h" #include "oo_READ_BINARY.h" #include "SpeechSynthesizer_def.h" #include "oo_DESCRIPTION.h" #include "SpeechSynthesizer_def.h" #define espeak_SAMPLINGFREQUENCY 22050 extern structMelderDir praatDir; extern int option_phoneme_events; Thing_implement (SpeechSynthesizerVoice, Daata, 0); SpeechSynthesizerVoice SpeechSynthesizerVoice_create (long numberOfFormants) { try { autoSpeechSynthesizerVoice me = Thing_new (SpeechSynthesizerVoice); my d_numberOfFormants = numberOfFormants; my d_freq = NUMvector (0, numberOfFormants); my d_height = NUMvector (0, my d_numberOfFormants); // 100% = 256 my d_width = NUMvector (0, my d_numberOfFormants); // 100% = 256 my d_freqadd = NUMvector (0, my d_numberOfFormants); // Hz // copies without temporary adjustments from embedded commands my d_freq2 = NUMvector (0, my d_numberOfFormants); // 100% = 256 my d_height2 = NUMvector (0, my d_numberOfFormants); // 100% = 256 my d_width2 = NUMvector (0, my d_numberOfFormants); // 100% = 256 my d_breath = NUMvector (0, my d_numberOfFormants); // amount of breath for each formant. breath[0] indicates whether any are set. my d_breathw = NUMvector (0, my d_numberOfFormants); // width of each breath formant SpeechSynthesizerVoice_setDefaults (me.peek()); return me.transfer(); } catch (MelderError) { Melder_throw (U"SpeechSynthesizerVoice not created."); } } void SpeechSynthesizerVoice_setDefaults (SpeechSynthesizerVoice me) { (void) me; } void SpeechSynthesizerVoice_initFromEspeakVoice (SpeechSynthesizerVoice me, voice_t *voice) { my d_v_name = Melder_dup (Melder_peek8to32 (voice -> v_name)); my d_phoneme_tab_ix = voice -> phoneme_tab_ix; my d_pitch_base = voice -> pitch_base; my d_pitch_range = voice -> pitch_range; my d_speedf1 = voice -> speedf1; my d_speedf2 = voice -> speedf2; my d_speedf3 = voice -> speedf3; my d_speed_percent = voice -> speed_percent; my d_flutter = voice -> flutter; my d_roughness = voice -> roughness; my d_echo_delay = voice -> echo_delay; my d_echo_amp = voice -> echo_amp; my d_n_harmonic_peaks = voice -> n_harmonic_peaks; my d_peak_shape = voice -> peak_shape; my d_voicing = voice -> voicing; my d_formant_factor = voice -> formant_factor; my d_consonant_amp = voice -> consonant_amp; my d_consonant_ampv = voice -> consonant_ampv; my d_samplingFrequency = voice -> samplerate; for (long i = 0; i < 7; i++) { my d_klattv[i] = voice -> klattv[i]; } for (long i = 0; i <= my d_numberOfFormants; i++) { my d_freq[i] = voice -> freq[i]; my d_height[i] = voice -> height[i]; my d_width[i] = voice -> width[i]; my d_freqadd[i] = voice -> freqadd[i]; my d_freq2[i] = voice -> freq2[i]; my d_height2[i] = voice -> height2[i]; my d_width2[i] = voice -> width2[i]; my d_breath[i] = voice -> breath[i]; my d_breathw[i] = voice -> breathw[i]; } } Thing_implement (SpeechSynthesizer, Daata, 0); void structSpeechSynthesizer :: v_info () { SpeechSynthesizer_Parent :: v_info (); MelderInfo_writeLine (U"Voice language: ", d_voiceLanguageName); MelderInfo_writeLine (U"Voice variant: ", d_voiceVariantName); MelderInfo_writeLine (U"Input text format: ", (d_inputTextFormat == SpeechSynthesizer_INPUT_TEXTONLY ? U"text only" : d_inputTextFormat == SpeechSynthesizer_INPUT_PHONEMESONLY ? U"phonemes only" : U"tagged text")); MelderInfo_writeLine (U"Input phoneme coding: ", (d_inputPhonemeCoding == SpeechSynthesizer_PHONEMECODINGS_KIRSHENBAUM ? U"Kirshenbaum" : U"???")); MelderInfo_writeLine (U"Sampling frequency: ", d_samplingFrequency, U" Hz"); MelderInfo_writeLine (U"Word gap: ", d_wordgap, U" s"); MelderInfo_writeLine (U"Pitch adjustment value: ", d_pitchAdjustment, U" (0-100)"); MelderInfo_writeLine (U"Speeking rate: ", d_wordsPerMinute, U" words per minute", (d_estimateWordsPerMinute ? U" (but estimated from data if possible)" : U" (fixed)")); MelderInfo_writeLine (U"Output phoneme coding: ", (d_inputPhonemeCoding == SpeechSynthesizer_PHONEMECODINGS_KIRSHENBAUM ? U"Kirshenbaum" : d_inputPhonemeCoding == SpeechSynthesizer_PHONEMECODINGS_IPA ? U"IPA" : U"???")); } static void NUMvector_extendNumberOfElements (long elementSize, void **v, long lo, long *hi, long extraDemand) { try { char *result; if (! *v) { long newhi = lo + extraDemand - 1; result = reinterpret_cast (NUMvector (elementSize, lo, newhi)); *hi = newhi; } else { long offset = lo * elementSize; for (;;) { // not very infinite: 99.999 % of the time once, 0.001 % twice result = reinterpret_cast (Melder_realloc ((char *) *v + offset, (*hi - lo + 1 + extraDemand) * elementSize)); if ((result -= offset)) break; // this will normally succeed at the first try (void) Melder_realloc_f (result + offset, 1); // ??make "sure" that the second try will succeed } (*hi) += extraDemand; memset (result + *hi * elementSize, 0, elementSize); // initialize the new elements to zeroes } *v = result; } catch (MelderError) { Melder_throw (U"Vector: size not extended."); } } static void NUMvector_supplyStorage (long elementSize, void **v, long lo, long *hi, long nfilled, long extraDemand) { long old_capacity = *hi - lo + 1, new_capacity = nfilled + extraDemand; if (new_capacity < old_capacity) return; new_capacity = new_capacity > 2 * old_capacity ? new_capacity : 2 * old_capacity; NUMvector_extendNumberOfElements (elementSize, v, lo, hi, new_capacity); } template void NUMvector_supplyStorage (T** v, long lo, long *hi, long nfilled, long extraDemand) { NUMvector_supplyStorage (sizeof (T), (void**) v, lo, hi, nfilled, extraDemand); } static int synthCallback (short *wav, int numsamples, espeak_EVENT *events) { char phoneme_name[9]; if (wav == 0) return 1; // It is essential that the SpeechSynthesizer is identified here by the user_data, // because the espeakEVENT_LIST_TERMINATED event may still be accompanied by // a piece of audio data!! SpeechSynthesizer me = (SpeechSynthesizer) (events -> user_data); while(events -> type != espeakEVENT_LIST_TERMINATED) { if (events -> type == espeakEVENT_SAMPLERATE) { my d_internalSamplingFrequency = events -> id.number; } else { //my events = Table "time type type-t t-pos length a-pos sample id uniq"; // 1 2 3 4 5 6 7 8 9 Table_appendRow (my d_events); long irow = my d_events -> rows -> size; double time = events -> audio_position * 0.001; Table_setNumericValue (my d_events, irow, 1, time); Table_setNumericValue (my d_events, irow, 2, events -> type); // Column 3 will be filled afterwards Table_setNumericValue (my d_events, irow, 4, events -> text_position); Table_setNumericValue (my d_events, irow, 5, events -> length); Table_setNumericValue (my d_events, irow, 6, events -> audio_position); Table_setNumericValue (my d_events, irow, 7, events -> sample); if (events -> type == espeakEVENT_MARK || events -> type == espeakEVENT_PLAY) { Table_setStringValue (my d_events, irow, 8, Melder_peek8to32 (events -> id.name)); } else { // Ugly hack because id.string is not 0-terminated if 8 chars long! memcpy (phoneme_name, events -> id.string, 8); phoneme_name[8] = 0; Table_setStringValue (my d_events, irow, 8, Melder_peek8to32 (phoneme_name)); } Table_setNumericValue (my d_events, irow, 9, events -> unique_identifier); } events++; } if (me != 0) { NUMvector_supplyStorage (&my d_wav, 1, &my d_wavCapacity, my d_numberOfSamples, numsamples); for (long i = 1; i <= numsamples; i++) { my d_wav[my d_numberOfSamples + i] = wav[i - 1]; } my d_numberOfSamples += numsamples; } return 0; } const char32 *SpeechSynthesizer_getVoiceLanguageCodeFromName (SpeechSynthesizer me, const char32 *voiceLanguageName) { try { (void) me; long voiceLanguageNameIndex = Strings_findString (espeakdata_voices_names, voiceLanguageName); if (voiceLanguageNameIndex == 0) { Melder_throw (U"Cannot find language \"", voiceLanguageName, U"\"."); } FileInMemory fim = (FileInMemory) espeakdata_voices -> item[voiceLanguageNameIndex]; return fim -> d_id; } catch (MelderError) { Melder_throw (U"Cannot find language code."); } } const char32 *SpeechSynthesizer_getVoiceVariantCodeFromName (SpeechSynthesizer me, const char32 *voiceVariantName) { try { (void) me; static const char32 * defaultVariantCode = U"default"; // Strings espeakdata_variants_names is one longer than the actual list of variants long voiceVariantIndex = Strings_findString (espeakdata_variants_names, voiceVariantName); if (voiceVariantIndex == 0) { Melder_throw (U"Cannot find voice variant \"", voiceVariantName, U"\"."); } // ... we have to decrease the index if (voiceVariantIndex != 1) { // 1 is default, i.e. no variant voiceVariantIndex--; // !!! FileInMemory vfim = (FileInMemory) espeakdata_variants -> item[voiceVariantIndex]; return vfim -> d_id; } else { return defaultVariantCode; // TODO what is the default? } } catch (MelderError) { Melder_throw (U"Cannot find voice variant code."); } } void SpeechSynthesizer_initSoundBuffer (SpeechSynthesizer me) { my d_wavCapacity = 2 * 22050; // 2 seconds my d_wav = NUMvector (1, my d_wavCapacity); int fsamp = espeak_Initialize (AUDIO_OUTPUT_SYNCHRONOUS, 0, nullptr, espeakINITIALIZE_PHONEME_EVENTS); // 4000 ms if (fsamp == -1) { Melder_throw (U"Internal espeak error."); } } SpeechSynthesizer SpeechSynthesizer_create (const char32 *voiceLanguageName, const char32 *voiceVariantName) { try { autoSpeechSynthesizer me = Thing_new (SpeechSynthesizer); // check the languange and voice variant (void) SpeechSynthesizer_getVoiceLanguageCodeFromName (me.peek(), voiceLanguageName); (void) SpeechSynthesizer_getVoiceVariantCodeFromName (me.peek(), voiceVariantName); my d_voiceLanguageName = Melder_dup (voiceLanguageName); my d_voiceVariantName = Melder_dup (voiceVariantName); SpeechSynthesizer_setTextInputSettings (me.peek(), SpeechSynthesizer_INPUT_TEXTONLY, SpeechSynthesizer_PHONEMECODINGS_KIRSHENBAUM); SpeechSynthesizer_setSpeechOutputSettings (me.peek(), 44100, 0.01, 50, 50, 175, true, SpeechSynthesizer_PHONEMECODINGS_IPA); SpeechSynthesizer_initSoundBuffer (me.peek()); return me.transfer(); } catch (MelderError) { Melder_throw (U"SpeechSynthesizer not created."); } } void SpeechSynthesizer_setTextInputSettings (SpeechSynthesizer me, int inputTextFormat, int inputPhonemeCoding) { my d_inputTextFormat = inputTextFormat; my d_inputPhonemeCoding = inputPhonemeCoding; } void SpeechSynthesizer_setSpeechOutputSettings (SpeechSynthesizer me, double samplingFrequency, double wordgap, long pitchAdjustment, long pitchRange, long wordsPerMinute, bool estimateWordsPerMinute, int outputPhonemeCoding) { my d_samplingFrequency = samplingFrequency; my d_wordgap = wordgap; my d_pitchAdjustment = pitchAdjustment; my d_pitchRange = pitchRange; if (wordsPerMinute <= 0) wordsPerMinute = 175; if (wordsPerMinute > 450) wordsPerMinute = 450; if (wordsPerMinute < 80) wordsPerMinute = 80; my d_wordsPerMinute = wordsPerMinute; my d_estimateWordsPerMinute = estimateWordsPerMinute; my d_outputPhonemeCoding = outputPhonemeCoding; } void SpeechSynthesizer_playText (SpeechSynthesizer me, const char32 *text) { autoSound thee= SpeechSynthesizer_to_Sound (me, text, 0, 0); Sound_playPart (thee.peek(), thy xmin, thy xmax, 0, 0); } static Sound buffer_to_Sound (int *wav, long numberOfSamples, double samplingFrequency) { try { double dx = 1.0 / samplingFrequency; double xmax = numberOfSamples * dx; autoSound thee = Sound_create (1, 0, xmax, numberOfSamples, dx, dx / 2); for (long i = 1; i <= numberOfSamples; i++) { thy z[1][i] = wav[i] / 32768.0; } return thee.transfer(); } catch (MelderError) { Melder_throw (U"Sound not created from synthesizer data."); } } static void IntervalTier_addBoundaryUnsorted (IntervalTier me, long iinterval, double time, const char32 *newLabel, bool isNewleftLabel) { if (time <= my xmin || time >= my xmax) { Melder_throw (U"Time is outside interval."); } // Find interval to split if (iinterval <= 0) { iinterval = IntervalTier_timeToLowIndex (me, time); } // Modify end time of left label TextInterval ti = (TextInterval) my intervals -> item[iinterval]; ti -> xmax = time; if (isNewleftLabel) TextInterval_setText (ti, newLabel); autoTextInterval ti_new = TextInterval_create (time, my xmax, (! isNewleftLabel ? newLabel : U"")); Sorted_addItem_unsorted (my intervals, ti_new.transfer()); } static void Table_setEventTypeString (Table me) { try { for (long i = 1; i <= my rows -> size; i++) { int type = Table_getNumericValue_Assert (me, i, 2); const char32 *label = U"0"; if (type == espeakEVENT_WORD) { label = U"word"; } else if (type == espeakEVENT_SENTENCE) { label = U"sent"; } else if (type == espeakEVENT_MARK) { label = U"mark"; } else if (type == espeakEVENT_PLAY) { label = U"play"; } else if (type == espeakEVENT_END) { label = U"s-end"; } else if (type == espeakEVENT_MSG_TERMINATED) { label = U"msg_term"; } else if (type == espeakEVENT_PHONEME) { label = U"phoneme"; } Table_setStringValue (me, i, 3, label); } } catch (MelderError) { Melder_throw (U"Event types not set."); } } static void MelderString_trimWhiteSpaceAtEnd (MelderString *me) { while (my length > 1 && (my string[my length - 1] == U' ' || my string[my length - 1] == U'\t' || my string[my length - 1] == U'\r' || my string[my length - 1] == U'\n')) { my string[my length - 1] = U'\0'; my length--; } } static TextGrid Table_to_TextGrid (Table me, const char32 *text, double xmin, double xmax) { //Table_createWithColumnNames (0, L"time type type-t t-pos length a-pos sample id uniq"); try { long length, textLength = str32len (text); long numberOfRows = my rows -> size; long timeColumnIndex = Table_getColumnIndexFromColumnLabel (me, U"time"); long typeColumnIndex = Table_getColumnIndexFromColumnLabel (me, U"type"); long tposColumnIndex = Table_getColumnIndexFromColumnLabel (me, U"t-pos"); long idColumnIndex = Table_getColumnIndexFromColumnLabel (me, U"id"); autoTextGrid thee = TextGrid_create (xmin, xmax, U"sentence clause word phoneme", U""); TextGrid_setIntervalText (thee.peek(), 1, 1, text); long p1c = 1, p1w = 1; double t1p = xmin; bool wordEnd = false; autoMelderString mark; IntervalTier itc = (IntervalTier) thy tiers -> item[2]; IntervalTier itw = (IntervalTier) thy tiers -> item[3]; IntervalTier itp = (IntervalTier) thy tiers -> item[4]; for (long i = 1; i <= numberOfRows; i++) { double time = Table_getNumericValue_Assert (me, i, timeColumnIndex); int type = Table_getNumericValue_Assert (me, i, typeColumnIndex); long pos = Table_getNumericValue_Assert (me, i, tposColumnIndex); if (type == espeakEVENT_SENTENCE) { // Only insert a new boundary, no text // text will be inserted at end sentence event if (time > xmin and time < xmax) { IntervalTier_addBoundaryUnsorted (itc, itc -> intervals -> size, time, U"", true); } p1c = pos; } else if (type == espeakEVENT_END) { // End of clause: insert new boundary, and fill left interval with text length = pos - p1c + 1; MelderString_ncopy (&mark, text + p1c - 1, length); MelderString_trimWhiteSpaceAtEnd (&mark); if (time > xmin and time < xmax) { IntervalTier_addBoundaryUnsorted (itc, itc -> intervals -> size, time, mark.string, true); } else { TextGrid_setIntervalText (thee.peek(), 2, itc -> intervals -> size, mark.string); } p1c = pos; // End of clause always signals "end of a word" if (pos <= textLength) { length = pos - p1w + 1; MelderString_ncopy (&mark, text + p1w - 1, length); MelderString_trimWhiteSpaceAtEnd (&mark); if (time > xmin and time < xmax) { IntervalTier_addBoundaryUnsorted (itw, itw -> intervals -> size, time, mark.string, true); } else { TextGrid_setIntervalText (thee.peek(), 3, itw -> intervals -> size, mark.string); } // now the next word event should not trigger setting the left interval text wordEnd = false; } } else if (type == espeakEVENT_WORD) { if (pos < p1w) continue; if (time > xmin and time < xmax) { length = pos - p1w; if (pos == textLength) length++; MelderString_ncopy (&mark, text + p1w - 1, length); MelderString_trimWhiteSpaceAtEnd (&mark); IntervalTier_addBoundaryUnsorted (itw, itw -> intervals -> size, time, (wordEnd ? mark.string : U""), true); } wordEnd = true; p1w = pos; } else if (type == espeakEVENT_PHONEME) { const char32 *id = Table_getStringValue_Assert (me, i, idColumnIndex); if (time > t1p) { // Insert new boudary and label interval with the id // TODO: Translate the id to the correct notation TextInterval ti = (TextInterval) itp -> intervals -> item[itp -> intervals -> size]; if (time > ti -> xmin and time < ti -> xmax) { IntervalTier_addBoundaryUnsorted (itp, itp -> intervals -> size, time, id, false); } } else { // Just in case the phoneme starts at xmin we only need to set interval text TextGrid_setIntervalText (thee.peek(), 4, itp -> intervals -> size, id); } t1p = time; } } Sorted_sort (itc -> intervals); Sorted_sort (itw -> intervals); Sorted_sort (itp -> intervals); return thee.transfer(); } catch (MelderError) { Melder_throw (U"TextGrid not created from Table with events."); } } static void espeakdata_SetVoiceByName (const char *name, const char *variantName) { espeak_VOICE voice_selector; memset(&voice_selector, 0, sizeof(voice_selector)); voice_selector.name = Melder_peek32to8 (Melder_cat (Melder_peek8to32 (name), U"+", Melder_peek8to32 (variantName))); // include variant name in voice stack ?? if (LoadVoice (name,1)) { LoadVoice(variantName, 2); DoVoiceChange(voice); SetVoiceStack (&voice_selector, variantName); } } autoSound SpeechSynthesizer_to_Sound (SpeechSynthesizer me, const char32 *text, autoTextGrid *tg, autoTable *events) { try { int fsamp = espeak_Initialize (AUDIO_OUTPUT_SYNCHRONOUS, 0, nullptr, // 5000ms espeakINITIALIZE_PHONEME_EVENTS|espeakINITIALIZE_PHONEME_IPA); if (fsamp == -1) Melder_throw (U"Internal espeak error."); int synth_flags = espeakCHARS_WCHAR; if (my d_inputTextFormat == SpeechSynthesizer_INPUT_TAGGEDTEXT) synth_flags |= espeakSSML; if (my d_inputTextFormat != SpeechSynthesizer_INPUT_TEXTONLY) synth_flags |= espeakPHONEMES; option_phoneme_events = espeakINITIALIZE_PHONEME_EVENTS; // extern int option_phoneme_events; if (my d_outputPhonemeCoding == SpeechSynthesizer_PHONEMECODINGS_IPA) { option_phoneme_events |= espeakINITIALIZE_PHONEME_IPA; } espeak_SetParameter (espeakRATE, my d_wordsPerMinute, 0); espeak_SetParameter (espeakPITCH, my d_pitchAdjustment, 0); espeak_SetParameter (espeakRANGE, my d_pitchRange, 0); const char32 *voiceLanguageCode = SpeechSynthesizer_getVoiceLanguageCodeFromName (me, my d_voiceLanguageName); const char32 *voiceVariantCode = SpeechSynthesizer_getVoiceVariantCodeFromName (me, my d_voiceVariantName); espeakdata_SetVoiceByName ((const char *) Melder_peek32to8 (voiceLanguageCode), (const char *) Melder_peek32to8 (voiceVariantCode)); espeak_SetParameter (espeakWORDGAP, my d_wordgap * 100, 0); // espeak wordgap is in units of 10 ms espeak_SetParameter (espeakCAPITALS, 0, 0); espeak_SetParameter (espeakPUNCTUATION, espeakPUNCT_NONE, 0); espeak_SetSynthCallback (synthCallback); my d_events = Table_createWithColumnNames (0, U"time type type-t t-pos length a-pos sample id uniq"); #ifdef _WIN32 wchar_t *textW = Melder_peek32toW (text); espeak_Synth (textW, wcslen (textW) + 1, 0, POS_CHARACTER, 0, synth_flags, nullptr, me); #else espeak_Synth (text, str32len (text) + 1, 0, POS_CHARACTER, 0, synth_flags, nullptr, me); #endif espeak_Terminate (); autoSound thee = buffer_to_Sound (my d_wav, my d_numberOfSamples, my d_internalSamplingFrequency); if (my d_samplingFrequency != my d_internalSamplingFrequency) { thee = Sound_resample (thee.peek(), my d_samplingFrequency, 50); } my d_numberOfSamples = 0; // re-use the wav-buffer if (tg) { double xmin = Table_getNumericValue_Assert (my d_events, 1, 1); if (xmin > thy xmin) xmin = thy xmin; double xmax = Table_getNumericValue_Assert (my d_events, my d_events -> rows -> size, 1); if (xmax < thy xmax) xmax = thy xmax; autoTextGrid tg1 = Table_to_TextGrid (my d_events, text, xmin, xmax); *tg = TextGrid_extractPart (tg1.peek(), thy xmin, thy xmax, 0); } if (events) { Table_setEventTypeString (my d_events); *events = my d_events; my d_events = nullptr; } forget (my d_events); return thee; } catch (MelderError) { espeak_Terminate (); Melder_throw (U"Text not played."); } } /* End of file SpeechSynthesizer.cpp */ praat-6.0.04/dwtools/SpeechSynthesizer.h000066400000000000000000000052351261542461700202500ustar00rootroot00000000000000#ifndef _SpeechSynthesizer_h_ #define _SpeechSynthesizer_h_ /* SpeechSynthesizer.h * * Copyright (C) 2011-2013 David Weenink, 2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20111214 */ #include "Sound.h" #include "TextGrid.h" #include "../external/espeak/speech.h" #include "../external/espeak/speak_lib.h" #include "../external/espeak/phoneme.h" #include "../external/espeak/synthesize.h" #include "../external/espeak/voice.h" #define SpeechSynthesizer_PHONEMECODINGS_IPA 2 #define SpeechSynthesizer_PHONEMECODINGS_KIRSHENBAUM 1 #define SpeechSynthesizer_INPUT_TEXTONLY 1 #define SpeechSynthesizer_INPUT_PHONEMESONLY 2 #define SpeechSynthesizer_INPUT_TAGGEDTEXT 3 #include "SpeechSynthesizer_def.h" oo_CLASS_CREATE (SpeechSynthesizerVoice, Daata); oo_CLASS_CREATE (SpeechSynthesizer, Daata); SpeechSynthesizerVoice SpeechSynthesizerVoice_create (long numberOfFormants); void SpeechSynthesizerVoice_setDefaults (SpeechSynthesizerVoice me); void SpeechSynthesizerVoice_initFromEspeakVoice (SpeechSynthesizerVoice me, voice_t *voice); void SpeechSynthesizer_initSoundBuffer (SpeechSynthesizer me); SpeechSynthesizer SpeechSynthesizer_create (const char32 *voiceLanguageName, const char32 *voiceVariantName); const char32 *SpeechSynthesizer_getVoiceLanguageCodeFromName (SpeechSynthesizer me, const char32 *voiceLanguageName); const char32 *SpeechSynthesizer_getVoiceVariantCodeFromName (SpeechSynthesizer me, const char32 *voiceVariantName); void SpeechSynthesizer_setTextInputSettings (SpeechSynthesizer me, int inputTextFormat, int inputPhonemeCoding); void SpeechSynthesizer_setSpeechOutputSettings (SpeechSynthesizer me, double samplingFrequency, double wordgap, long pitchAdjustment, long pitchRange, long wordsPerMinute, bool estimateWordsPerMinute, int outputPhonemeCodes); autoSound SpeechSynthesizer_to_Sound (SpeechSynthesizer me, const char32 *text, autoTextGrid *tg, autoTable *events); void SpeechSynthesizer_playText (SpeechSynthesizer me, const char32 *text); /* End of file SpeechSynthesizer.h */ #endif praat-6.0.04/dwtools/SpeechSynthesizer_and_TextGrid.cpp000066400000000000000000001110501261542461700232300ustar00rootroot00000000000000/* SpeechSynthesizer_and_TextGrid.cpp * * Copyright (C) 2011-2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20111214 */ //TODO: SpeechSynthesizer crashes on long input strings #include "DTW.h" #include "Sounds_to_DTW.h" #include "Sound_extensions.h" #include "SpeechSynthesizer_and_TextGrid.h" #include "CCs_to_DTW.h" #include "DTW_and_TextGrid.h" #include "NUMmachar.h" // prototypes static void IntervalTier_splitInterval (IntervalTier me, double time, const char32 *leftLabel, long interval, double precision); static IntervalTier IntervalTier_and_IntervalTier_cutPartsMatchingLabel (IntervalTier me, IntervalTier thee, const char32 *label, double precision); static IntervalTier IntervalTiers_patch_noBoundaries (IntervalTier me, IntervalTier thee, const char32 *patchLabel, double precision); static Table IntervalTiers_to_Table_textAlignmentment (IntervalTier target, IntervalTier source, EditCostsTable costs); autoSound SpeechSynthesizer_and_TextInterval_to_Sound (SpeechSynthesizer me, TextInterval thee, autoTextGrid *p_tg) { try { if (! thy text || thy text[0] == '\0') { Melder_throw (U"No text in TextInterval."); } autoSound him = SpeechSynthesizer_to_Sound (me, thy text, p_tg, nullptr); return him; } catch (MelderError) { Melder_throw (U"Sound not created from TextInterval."); } } autoSound SpeechSynthesizer_and_TextGrid_to_Sound (SpeechSynthesizer me, TextGrid thee, long tierNumber, long iinterval, autoTextGrid *p_tg) { try { TextGrid_checkSpecifiedTierNumberWithinRange (thee, tierNumber); IntervalTier intervalTier = (IntervalTier) thy tiers -> item [tierNumber]; if (intervalTier -> classInfo != classIntervalTier) { Melder_throw (U"Tier ", tierNumber, U" is not an interval tier."); } if (iinterval < 1 || iinterval > intervalTier -> intervals -> size) { Melder_throw (U"Interval ", iinterval, U" does not exist on tier ", tierNumber, U"."); } return SpeechSynthesizer_and_TextInterval_to_Sound (me, (TextInterval) intervalTier -> intervals -> item[iinterval], p_tg); } catch (MelderError) { Melder_throw (U"Sound not created from textGrid."); } } static double TextGrid_getStartTimeOfFirstOccurence (TextGrid thee, long tierNumber, const char32 *label) { TextGrid_checkSpecifiedTierNumberWithinRange (thee, tierNumber); IntervalTier intervalTier = (IntervalTier) thy tiers -> item [tierNumber]; if (intervalTier -> classInfo != classIntervalTier) { Melder_throw (U"Tier ", tierNumber, U" is not an interval tier."); } double start = NUMundefined; for (long iint = 1; iint <= intervalTier -> intervals -> size; iint++) { TextInterval ti = (TextInterval) intervalTier -> intervals -> item[iint]; if (Melder_cmp (ti -> text, label) == 0) { start = ti -> xmin; break; } } return start; } static double TextGrid_getEndTimeOfLastOccurence (TextGrid thee, long tierNumber, const char32 *label) { TextGrid_checkSpecifiedTierNumberWithinRange (thee, tierNumber); IntervalTier intervalTier = (IntervalTier) thy tiers -> item [tierNumber]; if (intervalTier -> classInfo != classIntervalTier) { Melder_throw (U"Tier ", tierNumber, U" is not an interval tier."); } double end = NUMundefined; for (long iint = intervalTier -> intervals -> size; iint > 0; iint--) { TextInterval ti = (TextInterval) intervalTier -> intervals -> item[iint]; if (Melder_cmp (ti -> text, label) == 0) { end = ti -> xmax; break; } } return end; } static void IntervalTier_getLabelInfo (IntervalTier me, const char32 *label, double *labelDurations, long *numberOfOccurences) { *labelDurations = 0; *numberOfOccurences = 0; for (long i = 1; i <= my intervals -> size; i++) { TextInterval ti = (TextInterval) my intervals -> item[i]; if (Melder_equ (ti -> text, label)) { *labelDurations += ti -> xmax - ti -> xmin; (*numberOfOccurences)++; } } } #define TIMES_ARE_CLOSE(x,y) (fabs((x)-(y)) < precision) void IntervalTier_splitInterval (IntervalTier me, double time, const char32 *leftLabel, long interval, double precision) { try { TextInterval ti = nullptr; long index = 0; for (long i = interval; i <= my intervals -> size; i++) { // interval > 0 ti = (TextInterval) my intervals -> item[i]; if (time < ti -> xmax + precision && time > ti -> xmin - precision) { index = i; break; } } // if index == 0 then search left intervals?? if (index == 0 || TIMES_ARE_CLOSE(time, ti -> xmin) || TIMES_ARE_CLOSE(time, ti -> xmax)) { return; } autoTextInterval newInterval = TextInterval_create (ti -> xmin, time, leftLabel); // Make start of current and begin of new interval equal ti -> xmin = time; Collection_addItem (my intervals, newInterval.transfer()); } catch (MelderError) { Melder_throw (U"Boundary not inserted."); } } static TextTier TextTier_and_IntervalTier_cutPartsMatchingLabel (TextTier me, IntervalTier thee, const char32 *label, double precision) { try { if (my xmin != thy xmin || my xmax != thy xmax) { Melder_throw (U"Domains must be equal."); } long myIndex = 1; double timeCut = 0; autoTextTier him = TextTier_create (0, my xmax - my xmin); for (long j = 1; j <= thy intervals -> size; j++) { TextInterval cut = (TextInterval) thy intervals -> item[j]; if (Melder_equ (cut -> text, label)) { timeCut += cut -> xmax - cut -> xmin; } else { while (myIndex <= my points -> size) { TextPoint tp = (TextPoint) my points -> item[myIndex]; if (tp -> number < cut -> xmin - precision) { // point is left of cut myIndex++; } else if (tp -> number < cut -> xmax + precision) { // point is in (no)cut double time = tp -> number - my xmin - timeCut; TextTier_addPoint (him.peek(), time, tp -> mark); myIndex++; } else { break; } } } } his xmax -= timeCut; return him.transfer(); } catch (MelderError) { Melder_throw (me, U": parts not cut."); } } // Cut parts from me marked by labels in thee IntervalTier IntervalTier_and_IntervalTier_cutPartsMatchingLabel (IntervalTier me, IntervalTier thee, const char32 *label, double precision) { try { if (my xmin != thy xmin || my xmax != thy xmax) { Melder_throw (U"Domains must be equal."); } autoNUMvector durations (1, my intervals -> size); for (long i = 1; i <= my intervals -> size; i++) { TextInterval ti = (TextInterval) my intervals -> item[i]; durations[i] = ti -> xmax - ti -> xmin; } long myInterval = 1; for (long j = 1; j <= thy intervals -> size; j++) { TextInterval cut = (TextInterval) thy intervals -> item[j]; if (Melder_equ (cut -> text, label)) { // trim while (myInterval <= my intervals -> size) { TextInterval ti = (TextInterval) my intervals -> item[myInterval]; if (ti -> xmin > cut -> xmin - precision && ti -> xmax < cut -> xmax + precision) { // 1. interval completely within cut durations[myInterval] = 0; myInterval++; } else if (ti -> xmin < cut -> xmin + precision && cut -> xmin < ti -> xmax + precision) { // 2. cut start is within interval if (cut -> xmax > ti -> xmax - precision) { // interval end is in cut, interval start before durations[myInterval] -= ti -> xmax - cut -> xmin; myInterval++; } else { // 3. cut completely within interval durations[myInterval] -= cut -> xmax - cut -> xmin; break; } } else if (cut -> xmax > ti -> xmin - precision && cut -> xmin < ti -> xmax + precision) { // +1+2 : cut end is within interval, cut start before durations[myInterval] -= cut -> xmax - ti -> xmin; break; } else if (ti -> xmax < cut -> xmin + precision) { myInterval++; } } } } double totalDuration = 0; for (long i = 1; i <= my intervals -> size; i++) { if (durations[i] < precision) { durations[i] = 0; } totalDuration += durations[i]; } autoIntervalTier him = IntervalTier_create (0, totalDuration); double time = 0; long hisInterval = 1; for (long i = 1; i <= my intervals -> size; i++) { if (durations[i] <= 0) continue; TextInterval ti = (TextInterval) my intervals -> item[i]; time += durations[i]; if (fabs (time - totalDuration) > precision) { IntervalTier_splitInterval (him.peek(), time, ti -> text, hisInterval, precision); hisInterval++; } else { // last interval TextInterval histi = (TextInterval) his intervals -> item[hisInterval]; TextInterval_setText (histi, ti -> text); } } return him.transfer(); } catch (MelderError) { Melder_throw (me, U": parts not cut."); } } TextGrid TextGrid_and_IntervalTier_cutPartsMatchingLabel (TextGrid me, IntervalTier thee, const char32 *label, double precision) { try { if (my xmin != thy xmin || my xmax != thy xmax) { Melder_throw (U"Domains must be equal."); } double cutDurations = 0; for (long i = 1; i <= thy intervals -> size; i++) { TextInterval cut = (TextInterval) thy intervals -> item[i]; if (Melder_equ (cut -> text, label)) { cutDurations += cut -> xmax - cut -> xmin; } } if (cutDurations <= precision) { // Nothing to patch return (TextGrid) Data_copy (me); } autoTextGrid him = TextGrid_createWithoutTiers (0, thy xmax - thy xmin - cutDurations); for (long itier = 1; itier <= my tiers -> size; itier++) { Function anyTier = (Function) my tiers -> item[itier]; if (anyTier -> classInfo == classIntervalTier) { autoIntervalTier ait = IntervalTier_and_IntervalTier_cutPartsMatchingLabel ((IntervalTier) anyTier, thee, label, precision); Collection_addItem (his tiers, ait.transfer()); } else { autoTextTier att = TextTier_and_IntervalTier_cutPartsMatchingLabel ((TextTier) anyTier, thee, label, precision); Collection_addItem (his tiers, att.transfer()); } } return him.transfer(); } catch (MelderError) { Melder_throw (me, U": no parts cut."); } } // Patch thy intervals that match patchLabel into my intervals // The resulting IntervalTier has thy xmin as starting time and thy xmax as end time IntervalTier IntervalTiers_patch_noBoundaries (IntervalTier me, IntervalTier thee, const char32 *patchLabel, double precision) { try { autoNUMvector durations (0L, my intervals -> size + 1); for (long i = 1; i <= my intervals -> size; i++) { TextInterval myti = (TextInterval) my intervals -> item[i]; durations[i] = myti -> xmax - myti -> xmin; } long myInterval = 1; double xShift = thy xmin - my xmin; for (long j = 1; j <= thy intervals -> size; j++) { TextInterval patch = (TextInterval) thy intervals -> item[j]; if (Melder_equ (patch -> text, patchLabel)) { if (j == 1) { xShift += durations[0] = patch -> xmax - patch -> xmin; } else if (j == thy intervals -> size) { durations[my intervals -> size + 1] = patch -> xmax - patch -> xmin; } else { while (myInterval <= my intervals -> size) { TextInterval ti = (TextInterval) my intervals -> item[myInterval]; double tixmin = ti -> xmin + xShift; double tixmax = ti -> xmax + xShift; if ((patch -> xmin > tixmin - precision) && (patch -> xmin < tixmax + precision)) { durations[myInterval] += patch -> xmax - patch -> xmin; break; } myInterval++; } } } else { while (myInterval <= my intervals -> size) { TextInterval ti = (TextInterval) my intervals -> item[myInterval]; double tixmax = ti -> xmax + xShift; if (tixmax < patch -> xmin + precision) { myInterval++; } else { break; } } } } autoIntervalTier him = IntervalTier_create (thy xmin, thy xmax); // first interval double time = thy xmin + durations[0]; long hisInterval = 1; if (durations[0] > 0) { IntervalTier_splitInterval (him.peek(), time , U"", hisInterval, precision); hisInterval++; } for (long i = 1; i <= my intervals -> size; i++) { TextInterval ti = (TextInterval) my intervals -> item[i]; time += durations[i]; IntervalTier_splitInterval (him.peek(), time, ti -> text, hisInterval, precision); hisInterval++; } if (durations[my intervals -> size + 1] > 0) { time += durations[my intervals -> size + 1]; IntervalTier_splitInterval (him.peek(), time , U"", hisInterval, precision); } return him.transfer(); } catch (MelderError) { Melder_throw (me, U": not patched."); } } static IntervalTier IntervalTiers_patch (IntervalTier me, IntervalTier thee, const char32 *patchLabel, double precision) { try { autoIntervalTier him = IntervalTier_create (thy xmin, thy xmax); long myInterval = 1, hisInterval = 1; double xmax = thy xmin; for (long i = 1; i <= thy intervals -> size; i++) { TextInterval myti, ti = (TextInterval) thy intervals -> item[i]; if (Melder_equ (ti -> text, patchLabel)) { bool splitInterval = false; double endtime, split = 0; if (i > 0) { while (myInterval <= my intervals -> size) { myti = (TextInterval) my intervals -> item[myInterval]; endtime = xmax + myti -> xmax - myti -> xmin; if (endtime <= ti -> xmin + precision) { xmax = endtime; IntervalTier_splitInterval (him.peek(), xmax, myti -> text, hisInterval, precision); hisInterval++; } else { if (xmax < ti -> xmin - precision) { // split interval ??? splitInterval = true; xmax = ti -> xmin; split = endtime - xmax; IntervalTier_splitInterval (him.peek(), xmax, myti -> text, hisInterval, precision); hisInterval ++; myInterval++; } break; } myInterval++; } } xmax += ti -> xmax - ti -> xmin; IntervalTier_splitInterval (him.peek(), xmax, U"", hisInterval, precision); hisInterval++; if (splitInterval) { xmax += split; IntervalTier_splitInterval (him.peek(), xmax, myti -> text, hisInterval, precision); hisInterval ++; } } else if (i == thy intervals -> size) { // copy remaining if last interval doesn't match while (myInterval <= my intervals -> size) { myti = (TextInterval) my intervals -> item[myInterval]; xmax += myti -> xmax - myti -> xmin; IntervalTier_splitInterval (him.peek(), xmax, myti -> text, hisInterval, precision); hisInterval++; myInterval++; } } } return him.transfer(); } catch (MelderError) { Melder_throw (me, U": not patched."); } } static TextTier TextTier_and_IntervalTier_patch (TextTier me, IntervalTier thee, const char32 *patchLabel, double precision) { try { long myIndex = 1; autoTextTier him = TextTier_create (thy xmin, thy xmax); double xShift = thy xmin - my xmin; for (long i = 1; i <= thy intervals -> size; i++) { TextInterval ti = (TextInterval) thy intervals -> item[i]; if (Melder_equ (ti -> text, patchLabel)) { if (i > 1) { while (myIndex <= my points -> size) { TextPoint tp = (TextPoint) my points -> item[myIndex]; double time = tp -> number + xShift; if (time < ti -> xmin + precision) { autoTextPoint atp = TextPoint_create (time, tp -> mark); Collection_addItem (his points, atp.transfer()); } else { break; } myIndex++; } } xShift += ti -> xmax - ti -> xmin; } else if (i == thy intervals -> size) { while (myIndex <= my points -> size) { TextPoint tp = (TextPoint) my points -> item[myIndex]; double time = tp -> number + xShift; if (time < ti -> xmin + precision) { autoTextPoint atp = TextPoint_create (time, tp -> mark); Collection_addItem (his points, atp.transfer()); } myIndex++; } } } return him.transfer(); } catch (MelderError) { Melder_throw (me, U": cannot patch TextTier."); } } TextGrid TextGrid_and_IntervalTier_patch (TextGrid me, IntervalTier thee, const char32 *patchLabel, double precision) { try { double patchDurations; long numberOfPatches; IntervalTier_getLabelInfo (thee, patchLabel, &patchDurations, &numberOfPatches); if (patchDurations <= 0 || my xmax - my xmin >= thy xmax - thy xmin ) { // Nothing to patch return (TextGrid) Data_copy (me); } autoTextGrid him = TextGrid_createWithoutTiers (thy xmin, thy xmax); for (long itier = 1; itier <= my tiers -> size; itier++) { Function anyTier = (Function) my tiers -> item[itier]; if (anyTier -> classInfo == classIntervalTier) { // autoIntervalTier ait = IntervalTiers_patch ((IntervalTier) anyTier, thee, patchLabel, precision); autoIntervalTier ait = IntervalTiers_patch_noBoundaries ((IntervalTier) anyTier, thee, patchLabel, precision); Collection_addItem (his tiers, ait.transfer()); } else { autoTextTier att = TextTier_and_IntervalTier_patch ((TextTier) anyTier, thee, patchLabel, precision); Collection_addItem (his tiers, att.transfer()); } } return him.transfer(); } catch (MelderError) { Melder_throw (me, U": not patched."); } } // We assume that the Sound and the SpeechSynthesizer have the same samplingFrequency // schakel waarschuwingen over stiltedetectie uit autoTextGrid SpeechSynthesizer_and_Sound_and_TextInterval_align (SpeechSynthesizer me, Sound thee, TextInterval him, double silenceThreshold, double minSilenceDuration, double minSoundingDuration) { try { if (thy xmin != his xmin || thy xmax != his xmax) { Melder_throw (U"Domains of Sound and TextGrid must be equal."); } if (fabs (1.0 / thy dx - my d_samplingFrequency) > NUMfpp -> eps) { Melder_throw (U"The sampling frequencies of the SpeechSynthesizer and the Sound must be equal."); } long numberOfTokens = Melder_countTokens (his text); if (numberOfTokens == 0) { Melder_throw (U"The interval has no text."); } // Remove silent intervals from start and end of sounds double minPitch = 200, timeStep = 0.005, precision = thy dx; double t1_thee, t2_thee; autoSound s_thee = Sound_trimSilencesAtStartAndEnd (thee, 0.0, minPitch, timeStep, silenceThreshold, minSilenceDuration, minSoundingDuration, &t1_thee, &t2_thee); double s_thee_duration = s_thee -> xmax - s_thee -> xmin; bool hasSilence_thee = fabs (t1_thee - thy xmin) > precision || fabs (t2_thee - thy xmax) > precision; if (my d_estimateWordsPerMinute) { // estimate speaking rate with the number of words per minute from the text double wordsPerMinute_rawTokens = 60.0 * numberOfTokens / s_thee_duration; // compensation for long words: 5 characters / word double wordsPerMinute_rawText = 60.0 * (str32len (his text) / 5.0) / s_thee_duration; my d_wordsPerMinute = (long) floor (0.5 * (wordsPerMinute_rawTokens + wordsPerMinute_rawText)); } autoTextGrid tg2 = 0; autoSound s2 = SpeechSynthesizer_and_TextInterval_to_Sound (me, him, &tg2); autoTextGrid silentTextGrid; /* * For the synthesizer the silence threshold has to be < -30 dB, otherwise fricatives will not * be found as sounding! This is ok since silences are almost at zero amplitudes * We also have to decrease the minimum silence and minimum sounding duration to catch, for example, * the final plosive "t" from the word "text" * */ double s2_silenceThreshold = -40, s2_minSilenceDuration = 0.05, s2_minSoundingDuration = 0.05; double t1_s2, t2_s2; autoSound s_s2 = Sound_trimSilencesAtStartAndEnd (s2.peek(), 0.0, minPitch, timeStep, s2_silenceThreshold, s2_minSilenceDuration, s2_minSoundingDuration, &t1_s2, &t2_s2); double s_s2_duration = s_s2 -> xmax - s_s2 -> xmin; bool hasSilence_s2 = fabs (t1_s2 - s2 -> xmin) > precision || fabs (t2_s2 - s2 -> xmax) > precision; if (hasSilence_s2) { silentTextGrid = TextGrid_extractPart (tg2.peek(), t1_s2, t2_s2, true); } double analysisWidth = 0.02, dt = 0.005, band = 0.0; // compare the durations of the two sounds to get an indication of the slope constraint of the DTW double slope = s_thee_duration / s_s2_duration; slope = slope > 1 ? slope : 1 / slope; int constraint = slope < 1.5 ? 4 : (slope < 2 ? 3 : (slope < 3 ? 2 : 1)); //autoMFCC m1 = Sound_to_MFCC ((hasSilence_thee ? s_thee.peek() : thee), // numberOfCoefficients, analysisWidth, dt, f1_mel, fmax_mel, df_mel); //autoMFCC m2 = Sound_to_MFCC ((hasSilence_s2 ? s_s2.peek() : s2.peek()), // numberOfCoefficients, analysisWidth, dt, f1_mel, fmax_mel, df_mel); //double wc = 1, wle = 0, wr = 0, wer = 0, dtr = 0; //int matchStart = 1, matchEnd = 1, constraint = 4; // no 1/3 1/2 2/3 //autoDTW dtw = CCs_to_DTW (m1.peek(), m2.peek(), wc, wle, wr, wer, dtr, matchStart, matchEnd, constraint); autoDTW dtw = Sounds_to_DTW ((hasSilence_thee ? s_thee.peek() : thee), (hasSilence_s2 ? s_s2.peek() : s2.peek()), analysisWidth, dt, band, constraint); autoTextGrid result = DTW_and_TextGrid_to_TextGrid (dtw.peek(), (hasSilence_s2 ? silentTextGrid.peek() : tg2.peek()), precision); if (hasSilence_thee) { if (t1_thee > thy xmin) { TextGrid_setEarlierStartTime (result.peek(), thy xmin, U"", U""); } if (t2_thee < thy xmax) { TextGrid_setLaterEndTime (result.peek(), thy xmax, U"", U""); } } return result; } catch (MelderError) { Melder_throw (U"Sound and TextInterval not aligned."); } } /* typedef struct structAlignmentOfSoundAndTextStruct { double windowLength, timeStep; // analysis double f1_mel, fmax_mel, df_mel; // MelFilter long numberOfMFCCCoefficients; // MFCC double dtw_cepstralWeight, dtw_logEnergyWeight; // MFCC -> DTW double dtw_regressionWeight, dtw_regressionlogEnergyWeight; double dtw_regressionWindowLength; double dtw_sakoeChibaBand, dtw_constraint; double silenceThreshold, minSilenceDuration, minSoundingDuration, trimDuration; // silence detection long language, voicevariant, pitchAdjustment, pitchRange, wordsPerMinute; // synthesizer bool interpretPhonemeCodes, ipa, set_wordsPerMinute; double wordgap; // synthesizer } *SpeechSynthesizer_alignmentStruct;*/ static autoTextGrid SpeechSynthesizer_and_Sound_and_TextInterval_align2 (SpeechSynthesizer me, Sound thee, TextInterval him, double silenceThreshold, double minSilenceDuration, double minSoundingDuration, double trimDuration) { try { if (thy xmin != his xmin || thy xmax != his xmax) { Melder_throw (U"Domains of Sound and TextGrid must be equal."); } if (fabs (1.0 / thy dx - my d_samplingFrequency) > NUMfpp -> eps) { Melder_throw (U"The sampling frequencies of the SpeechSynthesizer and the Sound must be equal."); } const char32 *trimLabel = U"trim"; // 1. trim the silences of the sound /* * For the synthesizer the silence threshold has to be < -30 dB, otherwise fricatives will not * be found as sounding! This is ok since silences are almost at zero amplitudes * We also have to decrease the minimum silence and minimum sounding duration to catch, for example, * the final plosive "t" from the word "text" * */ double minPitch = 200, timeStep = 0.005, precision = thy dx; autoTextGrid thee_trimmer; autoSound thee_trimmed = Sound_trimSilences (thee, trimDuration, false, minPitch, timeStep, silenceThreshold, minSilenceDuration, minSoundingDuration, &thee_trimmer, trimLabel); // 2. synthesize the sound from the TextInterval autoTextGrid tg_syn; autoSound synth = SpeechSynthesizer_and_TextInterval_to_Sound (me, him, &tg_syn); // 3. There should be no silences in the synthesized sound except at the start and finish. // Set the wordwap parameter to a small value like 0.001 s. // 4. Get DTW from the two sounds double analysisWidth = 0.02, dt = 0.005, band = 0.0; int constraint = 4; autoDTW dtw = Sounds_to_DTW (thee_trimmed.peek(), synth.peek(), analysisWidth, dt, band, constraint); // 6. Warp the synthesis TextGrid // first make domain equal, otherwsise the warper protests autoTextGrid warp = DTW_and_TextGrid_to_TextGrid (dtw.peek(), tg_syn.peek(), precision); // 7. Patch the trimmed intervals back into the warped TextGrid autoTextGrid result = TextGrid_and_IntervalTier_patch (warp.peek(), (IntervalTier) thee_trimmer -> tiers ->item[1], U"trim", 2 * thy dx); return result; } catch (MelderError) { Melder_throw (thee, U": sound and TextInterval not aligned."); } } autoTextGrid SpeechSynthesizer_and_Sound_and_IntervalTier_align (SpeechSynthesizer me, Sound thee, IntervalTier him, long istart, long iend, double silenceThreshold, double minSilenceDuration, double minSoundingDuration) { try { if (istart < 1 || iend < istart || iend > his intervals -> size) { Melder_throw (U"Not avalid interval range."); } autoCollection textgrids = Ordered_create (); TextInterval tb = (TextInterval) his intervals -> item[istart]; TextInterval te = (TextInterval) his intervals -> item[iend]; autoTextGrid result = TextGrid_create (tb -> xmin, te -> xmax, U"sentence clause word phoneme", U""); for (long iint = istart; iint <= iend; iint ++) { TextInterval ti = (TextInterval) his intervals -> item[iint]; if (ti -> text && str32len (ti -> text) > 0) { autoSound sound = Sound_extractPart (thee, ti -> xmin, ti -> xmax, kSound_windowShape_RECTANGULAR, 1, true); autoTextGrid grid = SpeechSynthesizer_and_Sound_and_TextInterval_align (me, sound.peek(), ti, silenceThreshold, minSilenceDuration, minSoundingDuration); Collection_addItem (textgrids.peek(), grid.transfer()); } } if (textgrids -> size == 0) { Melder_throw (U"Nothing could be aligned. Was your IntervalTier empty?"); } autoTextGrid aligned = TextGrids_to_TextGrid_appendContinuous (textgrids.peek(), true); return aligned; } catch (MelderError) { Melder_throw (U"No aligned TextGrid created."); } } static autoTextGrid SpeechSynthesizer_and_Sound_and_IntervalTier_align2 (SpeechSynthesizer me, Sound thee, IntervalTier him, long istart, long iend, double silenceThreshold, double minSilenceDuration, double minSoundingDuration, double trimDuration) { try { if (istart < 1 || iend < istart || iend > his intervals -> size) { Melder_throw (U"Not avalid interval range."); } autoCollection textgrids = Ordered_create (); TextInterval tb = (TextInterval) his intervals -> item[istart]; TextInterval te = (TextInterval) his intervals -> item[iend]; autoTextGrid result = TextGrid_create (tb -> xmin, te -> xmax, U"sentence clause word phoneme", U""); for (long iint = istart; iint <= iend; iint ++) { TextInterval ti = (TextInterval) his intervals -> item[iint]; if (ti -> text && str32len (ti -> text) > 0) { autoSound sound = Sound_extractPart (thee, ti -> xmin, ti -> xmax, kSound_windowShape_RECTANGULAR, 1, true); autoTextGrid grid = SpeechSynthesizer_and_Sound_and_TextInterval_align2 (me, sound.peek(), ti, silenceThreshold, minSilenceDuration, minSoundingDuration, trimDuration); Collection_addItem (textgrids.peek(), grid.transfer()); } } if (textgrids -> size == 0) { Melder_throw (U"Nothing could be aligned. Was your IntervalTier empty?"); } autoTextGrid aligned = TextGrids_to_TextGrid_appendContinuous (textgrids.peek(), true); return aligned; } catch (MelderError) { Melder_throw (U"No aligned TextGrid created."); } } autoTextGrid SpeechSynthesizer_and_Sound_and_TextGrid_align (SpeechSynthesizer me, Sound thee, TextGrid him, long tierNumber, long istart, long iend, double silenceThreshold, double minSilenceDuration, double minSoundingDuration) { try {//TODO: check not empty tier IntervalTier tier = TextGrid_checkSpecifiedTierIsIntervalTier (him, tierNumber); autoTextGrid grid = SpeechSynthesizer_and_Sound_and_IntervalTier_align (me, thee, tier, istart, iend, silenceThreshold, minSilenceDuration, minSoundingDuration); return grid; } catch (MelderError) { Melder_throw (U""); } } autoTextGrid SpeechSynthesizer_and_Sound_and_TextGrid_align2 (SpeechSynthesizer me, Sound thee, TextGrid him, long tierNumber, long istart, long iend, double silenceThreshold, double minSilenceDuration, double minSoundingDuration, double trimDuration) { try {//TODO: check not empty tier IntervalTier tier = TextGrid_checkSpecifiedTierIsIntervalTier (him, tierNumber); autoTextGrid grid = SpeechSynthesizer_and_Sound_and_IntervalTier_align2 (me, thee, tier, istart, iend, silenceThreshold, minSilenceDuration, minSoundingDuration, trimDuration); return grid; } catch (MelderError) { Melder_throw (U""); } } static Strings IntervalTier_to_Strings_withOriginData (IntervalTier me, long *from) { try { autoStrings thee = Thing_new (Strings); thy strings = NUMvector (1, my intervals -> size); for (long i = 1; i <= my intervals -> size; i++) { TextInterval ti = (TextInterval) my intervals -> item[i]; if (ti -> text != 0 && ti -> text[0] != '\0') { thy strings [++(thy numberOfStrings)] = Melder_dup (ti -> text); from[thy numberOfStrings] = i; } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no Strings created."); } } Table IntervalTiers_to_Table_textAlignmentment (IntervalTier target, IntervalTier source, EditCostsTable costs) { try { long numberOfTargetIntervals = target -> intervals -> size; long numberOfSourceIntervals = source -> intervals -> size; autoNUMvector targetOrigin (1, numberOfTargetIntervals); autoNUMvector sourceOrigin (1, numberOfSourceIntervals); autoStrings targets = IntervalTier_to_Strings_withOriginData (target, targetOrigin.peek()); autoStrings sources = IntervalTier_to_Strings_withOriginData (source, sourceOrigin.peek()); autoEditDistanceTable edit = EditDistanceTable_create (targets.peek(), sources.peek()); if (costs != 0) { EditDistanceTable_setEditCosts (edit.peek(), costs); EditDistanceTable_findPath (edit.peek(), nullptr); } long pathLength = edit -> warpingPath -> pathLength; autoTable thee = Table_createWithColumnNames (pathLength - 1, U"targetInterval targetText targetStart targetEnd sourceInterval sourceText sourceStart sourceEnd operation"); for (long i = 2; i <= pathLength; i++) { structPairOfInteger p = edit -> warpingPath -> path[i]; structPairOfInteger p1 = edit -> warpingPath -> path[i - 1]; double targetStart = NUMundefined, targetEnd = NUMundefined; double sourceStart = NUMundefined, sourceEnd = NUMundefined; const char32 * targetText = U"", *sourceText = U""; long targetInterval = p.y > 1 ? targetOrigin[p.y - 1] : 0; long sourceInterval = p.x > 1 ? sourceOrigin[p.x - 1] : 0; if (targetInterval > 0) { TextInterval ti = (TextInterval) target -> intervals -> item[targetInterval]; targetStart = ti -> xmin; targetEnd = ti -> xmax; targetText = ti -> text; } if (sourceInterval > 0) { TextInterval ti = (TextInterval) source -> intervals -> item[sourceInterval]; sourceStart = ti -> xmin; sourceEnd = ti -> xmax; sourceText = ti -> text; } long irow = i - 1; if (p.y == p1.y) { // deletion Table_setNumericValue (thee.peek(), irow, 1, 0); Table_setStringValue (thee.peek(), irow, 2, U""); Table_setNumericValue (thee.peek(), irow, 3, NUMundefined); Table_setNumericValue (thee.peek(), irow, 4, NUMundefined); Table_setNumericValue (thee.peek(), irow, 5, sourceInterval); Table_setStringValue (thee.peek(), irow, 6, sourceText); Table_setNumericValue (thee.peek(), irow, 7, sourceStart); Table_setNumericValue (thee.peek(), irow, 8, sourceEnd); Table_setStringValue (thee.peek(), irow, 9, U"d"); } else if (p.x == p1.x) { // insertion Table_setNumericValue (thee.peek(), irow, 1, targetInterval); Table_setStringValue (thee.peek(), irow, 2, targetText); Table_setNumericValue (thee.peek(), irow, 3, targetStart); Table_setNumericValue (thee.peek(), irow, 4, targetEnd); Table_setNumericValue (thee.peek(), irow, 5, 0); Table_setStringValue (thee.peek(), irow, 6, U""); Table_setNumericValue (thee.peek(), irow, 7, NUMundefined); Table_setNumericValue (thee.peek(), irow, 8, NUMundefined); Table_setStringValue (thee.peek(), irow, 9, U"i"); } else { // substitution ? Table_setNumericValue (thee.peek(), irow, 1, targetInterval); Table_setStringValue (thee.peek(), irow, 2, targetText); Table_setNumericValue (thee.peek(), irow, 3, targetStart); Table_setNumericValue (thee.peek(), irow, 4, targetEnd); Table_setNumericValue (thee.peek(), irow, 5, sourceInterval); Table_setStringValue (thee.peek(), irow, 6, sourceText); Table_setNumericValue (thee.peek(), irow, 7, sourceStart); Table_setNumericValue (thee.peek(), irow, 8, sourceEnd); Table_setStringValue (thee.peek(), irow, 9, Melder_equ (targetText, sourceText) ? U" " : U"s"); } } return thee.transfer(); } catch (MelderError) { Melder_throw (target, U" and ", source, U" not aligned."); } } Table TextGrids_to_Table_textAlignmentment (TextGrid target, long ttier, TextGrid source, long stier, EditCostsTable costs) { try { IntervalTier targetTier = TextGrid_checkSpecifiedTierIsIntervalTier (target, ttier); IntervalTier sourceTier = TextGrid_checkSpecifiedTierIsIntervalTier (source, stier); return IntervalTiers_to_Table_textAlignmentment (targetTier, sourceTier, costs); } catch (MelderError) { Melder_throw (U"No text alignment table created from TextGrids ", target, U" and ", source, U"."); } } // End of file TextGrid_and_SpeechSynthesizer.cpp praat-6.0.04/dwtools/SpeechSynthesizer_and_TextGrid.h000066400000000000000000000052301261542461700226770ustar00rootroot00000000000000#ifndef _SpeechSynthesizer_and_TextGrid_h_ #define _SpeechSynthesizer_and_TextGrid_h_ /* SpeechSynthesizer_and_TextGrid.h * * Copyright (C) 2011-2012 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20111214 */ #include "SpeechSynthesizer.h" #include "TextGrid_extensions.h" #include "EditDistanceTable.h" autoSound SpeechSynthesizer_and_TextInterval_to_Sound (SpeechSynthesizer me, TextInterval thee, autoTextGrid *tg); autoSound SpeechSynthesizer_and_TextGrid_to_Sound (SpeechSynthesizer me, TextGrid thee, long itier, long iiint, autoTextGrid *tg); autoTextGrid SpeechSynthesizer_and_Sound_and_TextInterval_align (SpeechSynthesizer me, Sound thee, TextInterval him, double silenceThreshold, double minSilenceDuration, double minSoundingDuration); autoTextGrid SpeechSynthesizer_and_Sound_and_IntervalTier_align (SpeechSynthesizer me, Sound thee, IntervalTier him, long istart, long iend, double silenceThreshold, double minSilenceDuration, double minSoundingDuration); autoTextGrid SpeechSynthesizer_and_Sound_and_TextGrid_align (SpeechSynthesizer me, Sound thee, TextGrid him, long tierNumber, long istart, long iend, double silenceThreshold, double minSilenceDuration, double minSoundingDuration); autoTextGrid SpeechSynthesizer_and_Sound_and_TextGrid_align2 (SpeechSynthesizer me, Sound thee, TextGrid him, long tierNumber, long istart, long iend, double silenceThreshold, double minSilenceDuration, double minSoundingDuration, double trimDuration); Table IntervalTiers__to_Table_textAlignmentment (IntervalTier target, IntervalTier source, EditCostsTable costs); Table TextGrids_to_Table_textAlignmentment (TextGrid target, long ttier, TextGrid source, long stier, EditCostsTable costs); /* For testing purposes only */ TextGrid TextGrid_and_IntervalTier_patch (TextGrid me, IntervalTier thee, const char32 *patchLabel, double precision); TextGrid TextGrid_and_IntervalTier_cutPartsMatchingLabel (TextGrid me, IntervalTier thee, const char32 *label, double precision); #endif // _SpeechSynthesizer_and_TextGrid_h_ praat-6.0.04/dwtools/SpeechSynthesizer_def.h000066400000000000000000000073441261542461700210710ustar00rootroot00000000000000/* SpeechSynthesizer_def.h * * Copyright (C) 2011-2012 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT SpeechSynthesizerVoice oo_DEFINE_CLASS (SpeechSynthesizerVoice, Daata) oo_STRING (d_v_name) oo_LONG (d_phoneme_tab_ix) // phoneme table number oo_LONG (d_pitch_base) // Hz oo_LONG (d_pitch_range) // Hz oo_LONG (d_speedf1) oo_LONG (d_speedf2) oo_LONG (d_speedf3) oo_DOUBLE (d_speed_percent) // adjust the WPM speed by this percentage oo_DOUBLE (d_flutter) oo_DOUBLE (d_roughness) oo_DOUBLE (d_echo_delay) oo_DOUBLE (d_echo_amp) oo_LONG (d_n_harmonic_peaks) // highest formant which is formed from adding harmonics oo_INT (d_peak_shape) // alternative shape for formant peaks (0=standard 1=squarer) oo_DOUBLE (d_voicing) // 100% = 64, level of formant-synthesized sound oo_DOUBLE (d_formant_factor) // adjust nominal formant frequencies by this because of the voice's pitch (256ths) oo_DOUBLE (d_consonant_amp) // amplitude of unvoiced consonants oo_DOUBLE (d_consonant_ampv) // amplitude of the noise component of voiced consonants oo_DOUBLE (d_samplingFrequency) oo_INT_VECTOR_FROM (d_klattv, 0, 7) // parameters used by Wavegen oo_LONG (d_numberOfFormants) oo_INT_VECTOR_FROM (d_freq, 0, d_numberOfFormants) // 100% = 256 oo_INT_VECTOR_FROM (d_height, 0, d_numberOfFormants) // 100% = 256 oo_INT_VECTOR_FROM (d_width, 0, d_numberOfFormants) // 100% = 256 oo_INT_VECTOR_FROM (d_freqadd, 0, d_numberOfFormants) // Hz // copies without temporary adjustments from embedded commands oo_INT_VECTOR_FROM (d_freq2, 0, d_numberOfFormants) // 100% = 256 oo_INT_VECTOR_FROM (d_height2, 0, d_numberOfFormants) // 100% = 256 oo_INT_VECTOR_FROM (d_width2, 0, d_numberOfFormants) // 100% = 256 oo_INT_VECTOR_FROM (d_breath, 0, d_numberOfFormants) // amount of breath for each formant. breath[0] indicates whether any are set. oo_INT_VECTOR_FROM (d_breathw, 0, d_numberOfFormants) // width of each breath formant oo_END_CLASS (SpeechSynthesizerVoice) #undef ooSTRUCT #define ooSTRUCT SpeechSynthesizer oo_DEFINE_CLASS (SpeechSynthesizer, Daata) // sythesizers language /voice oo_STRING (d_voiceLanguageName) oo_STRING (d_voiceVariantName) oo_LONG (d_wordsPerMinute) // text-only, phonemes-only, mixed oo_INT (d_inputTextFormat) // 1/: output phonemes in espeak/ notation oo_INT (d_inputPhonemeCoding) // speech output oo_DOUBLE (d_samplingFrequency) oo_DOUBLE (d_wordgap) oo_DOUBLE (d_pitchAdjustment) oo_DOUBLE (d_pitchRange) // 1/2: output phonemes in espeak/IPA notation oo_INT (d_outputPhonemeCoding) oo_BOOL (d_estimateWordsPerMinute) #if !oo_READING && !oo_WRITING // Filled by the call back oo_OBJECT(Table, 0, d_events) oo_DOUBLE (d_internalSamplingFrequency) oo_LONG (d_numberOfSamples) oo_LONG (d_wavCapacity) oo_INT_VECTOR (d_wav, d_wavCapacity) #endif #if oo_READING SpeechSynthesizer_initSoundBuffer (this); #endif #if oo_DECLARING protected: // overridden methods: virtual void v_info (); #endif oo_END_CLASS (SpeechSynthesizer) #undef ooSTRUCT /* End of file SpeechSynthesizer_def.h */ praat-6.0.04/dwtools/Strings_extensions.cpp000066400000000000000000000214061261542461700210320ustar00rootroot00000000000000/* Strings_extensions.cpp * * Copyright (C) 1993-2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20011003 djmw 20020813 GPL header djmw 20030107 Added Strings_setString djmw 20031212 Added Strings_extractPart djmw 20040301 Added Strings_createFixedLength. djmw 20040308 Corrected bug in strings_to_Strings. djmw 20040427 Strings_append added. djmw 20040629 Strings_append now accepts an Ordered of Strings. djmw 20050714 New: Strings_to_Permutation, Strings_and_Permutation_permuteStrings. djmw 20050721 Extra argument in Strings_to_Permutation. djmw 20101007 StringsIndex Stringses_to_StringsIndex (Strings me, Strings classes) djmw 20120407 + Strings_createFromCharacters djmw 20120813 -Strings_setString */ #include "Strings_extensions.h" #include "NUM2.h" autoStrings Strings_createFixedLength (long numberOfStrings) { try { if (numberOfStrings <= 0) { Melder_throw (U"The number of strings must be positive."); } autoStrings me = Thing_new (Strings); my strings = NUMvector (1, numberOfStrings); my numberOfStrings = numberOfStrings; return me; } catch (MelderError) { Melder_throw (U"Strings not created."); } } autoStrings Strings_createAsCharacters (const char32 *string) { try { autoStrings me = Thing_new (Strings); my numberOfStrings = str32len (string); my strings = NUMvector (1, my numberOfStrings); for (long i = 1; i <= my numberOfStrings; i++) { my strings[i] = Melder_dup (Melder_character (*string++)); } return me; } catch (MelderError) { Melder_throw (U"Strings from characters not created."); } } autoStrings Strings_createAsTokens (const char32 *string) { try { autoStrings me = Thing_new (Strings); my numberOfStrings = Melder_countTokens (string); my strings = NUMvector (1, my numberOfStrings); long i = 1; for (char32 *token = Melder_firstToken (string); token != 0; token = Melder_nextToken ()) { my strings[i++] = Melder_dup (token); } return me; } catch (MelderError) { Melder_throw (U"Strings from characters not created."); } } long Strings_findString (Strings me, const char32 *string) { for (long i = 1; i <= my numberOfStrings; i++) { if (Melder_equ (my strings[i], string)) { return i; } } return 0; } autoStrings Strings_append (Collection me) { try { long index = 1, numberOfStrings = 0; for (long i = 1; i <= my size; i++) { Strings s = (Strings) my item[i]; numberOfStrings += s -> numberOfStrings; } autoStrings thee = Strings_createFixedLength (numberOfStrings); for (long i = 1; i <= my size; i++) { Strings s = (Strings) my item[i]; for (long j = 1; j <= s -> numberOfStrings; j++, index++) { if (s -> strings[j] == 0) { continue; } thy strings [index] = Melder_dup (s -> strings[j]); } } return thee; } catch (MelderError) { Melder_throw (me, U": not appended."); } } autoStrings Strings_change (Strings me, const char32 *search, const char32 *replace, int maximumNumberOfReplaces, long *nmatches, long *nstringmatches, int use_regexp) { try { autoStrings thee = Thing_new (Strings); char32 **strings = strs_replace (my strings, 1, my numberOfStrings, search, replace, maximumNumberOfReplaces, nmatches, nstringmatches, use_regexp); thy numberOfStrings = my numberOfStrings; thy strings = strings; return thee; } catch (MelderError) { Melder_throw (me, U": not changed."); } } autoStrings strings_to_Strings (char32 **strings, long from, long to) { try { autoStrings thee = Strings_createFixedLength (to - from + 1); for (long i = from; i <= to; i++) { thy strings[i - from + 1] = Melder_dup (strings[i]); } return thee; } catch (MelderError) { Melder_throw (U"Strings not created."); } } autoStrings Strings_extractPart (Strings me, long from, long to) { try { if (from < 1 || to > my numberOfStrings || from > to) Melder_throw (U"Strings_extractPart: begin and end must be in interval [1, ", my numberOfStrings, U"]."); return strings_to_Strings (my strings, from, to); } catch (MelderError) { Melder_throw (me, U": no part extracted."); } } autoStrings strings_to_Strings_link (char32 **strings, long n) { try { autoStrings me = Strings_createFixedLength (n); for (long i = 1; i <= n; i++) { my strings[i] = strings[i]; } return me; } catch (MelderError) { Melder_throw (U"Strings not linked."); } } void Strings_unlink (Strings me) { for (long i = 1; i <= my numberOfStrings; i++) { my strings[i] = nullptr; } } autoPermutation Strings_to_Permutation (Strings me, int sort) { try { autoPermutation thee = Permutation_create (my numberOfStrings); if (sort != 0) { NUMindexx_s (my strings, my numberOfStrings, thy p); } return thee; } catch (MelderError) { Melder_throw (me, U": no Permutation created."); } } autoStrings Strings_and_Permutation_permuteStrings (Strings me, Permutation thee) { try { if (my numberOfStrings != thy numberOfElements) Melder_throw (U"Strings_and_Permutation_permuteStrings: " U"The number of strings and the number of elements in the Permutation must be equal."); autoStrings him = Strings_createFixedLength (my numberOfStrings); for (long i = 1; i <= thy numberOfElements; i++) { long index = thy p[i]; his strings[i] = Melder_dup (my strings[index]); } return him; } catch (MelderError) { Melder_throw (me, U": no permuted Strings created."); } } autoStringsIndex Stringses_to_StringsIndex (Strings me, Strings classes) { try { autoStringsIndex tmp = Strings_to_StringsIndex (classes); long numberOfClasses = tmp -> classes -> size; autoStringsIndex him = StringsIndex_create (my numberOfStrings); for (long i = 1; i <= numberOfClasses; i++) { SimpleString t = (SimpleString) tmp -> classes -> item[i]; autoSimpleString t2 = Data_copy (t); Collection_addItem (his classes, t2.transfer()); } for (long j = 1; j <= my numberOfStrings; j++) { long index = 0; char32 *stringsj = my strings[j]; for (long i = 1; i <= numberOfClasses; i++) { SimpleString ss = (SimpleString) his classes -> item[i]; if (Melder_cmp (stringsj, ss -> string) == 0) { index = i; break; } } his classIndex[j] = index; } return him; } catch (MelderError) { Melder_throw (me, U": no StringsIndex created."); } } autoStringsIndex Strings_to_StringsIndex (Strings me) { try { autoStringsIndex thee = StringsIndex_create (my numberOfStrings); autoPermutation sorted = Strings_to_Permutation (me, 1); long numberOfClasses = 0; char32 *strings = nullptr; for (long i = 1; i <= sorted -> numberOfElements; i++) { long index = sorted -> p[i]; char32 *stringsi = my strings[index]; if (i == 1 || Melder_cmp (strings, stringsi) != 0) { numberOfClasses++; autoSimpleString him = SimpleString_create (stringsi); Collection_addItem (thy classes, him.transfer()); strings = stringsi; } thy classIndex[index] = numberOfClasses; } return thee; } catch (MelderError) { Melder_throw (me, U": no StringsIndex created."); } } autoStrings StringsIndex_to_Strings (StringsIndex me) { try { autoStrings thee = Strings_createFixedLength (my numberOfElements); for (long i = 1; i <= thy numberOfStrings; i++) { SimpleString s = (SimpleString) my classes -> item[my classIndex[i]]; thy strings[i] = Melder_dup (s -> string); } return thee; } catch (MelderError) { Melder_throw (me, U": no Strings created."); } } autoStringsIndex Table_to_StringsIndex_column (Table me, long column) { try { if (column < 1 || column > my numberOfColumns) { Melder_throw (U"Invalid column number."); } long numberOfRows = my rows -> size; Table_numericize_Assert (me, column); autoNUMvector groupLabels (1, numberOfRows); for (long irow = 1; irow <= numberOfRows; irow++) { groupLabels[irow] = ((TableRow) my rows -> item [irow]) -> cells [column] .string; } autoStrings thee = strings_to_Strings (groupLabels.peek(), 1, numberOfRows); autoStringsIndex him = Strings_to_StringsIndex (thee.peek()); return him; } catch (MelderError) { Melder_throw (me, U"No StringsIndex created from column ", column, U"."); } } /* End of file Strings_extensions.cpp */ praat-6.0.04/dwtools/Strings_extensions.h000066400000000000000000000051231261542461700204750ustar00rootroot00000000000000#ifndef _Strings_extensions_h_ #define _Strings_extensions_h_ /* Strings_extensions.h * * Copyright (C) 1993-2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20010114 djmw 20020813 GPL header djmw 20040629 Strings_append now accepts an Ordered of Strings. djmw 20050714 Permutations djmw 20050724 Index djmw 20120813 Latest modification */ #include "Collection.h" #include "Strings_.h" #include "Permutation.h" #include "Index.h" #include "Table.h" autoStrings Strings_createFixedLength (long numberOfStrings); autoStrings Strings_createAsCharacters (const char32 *string); autoStrings Strings_createAsTokens (const char32 *string); long Strings_findString (Strings me, const char32 *string); autoStrings Strings_append (Collection me); autoStrings Strings_change (Strings me, const char32 *search, const char32 *replace, int maximumNumberOfReplaces, long *nmatches, long *nstringmatches, int use_regexp); autoStrings strings_to_Strings (char32 **strings, long from, long to); // If the Strings is only an intermediate object to achieve other goals, use the following two routines to avoid copying. autoStrings strings_to_Strings_link (char32** strings, long n); // for (i=1; i<= n; i++) my strings[i] = strings[i]; void Strings_unlink (Strings me); // for (i=1; i<= my numberOfStrings; i++) my strings[i] = NULL; autoStrings Strings_extractPart (Strings me, long start, long end); autoStringsIndex Strings_to_StringsIndex (Strings me); autoStringsIndex Stringses_to_StringsIndex (Strings me, Strings classes); /* Construct the index with strings in classes, index[i]=0 when my strings[i] doesn't occur in classes */ autoStringsIndex Table_to_StringsIndex_column (Table me, long column); autoStrings StringsIndex_to_Strings (StringsIndex me); autoPermutation Strings_to_Permutation (Strings me, int sort); autoStrings Strings_and_Permutation_permuteStrings (Strings me, Permutation thee); #endif /* _Strings_extensions_h_ */ praat-6.0.04/dwtools/TableOfReal_and_Permutation.cpp000066400000000000000000000036311261542461700224530ustar00rootroot00000000000000/* TableOfReal_and_Permutation.cpp * * Copyright (C) 2005-2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20050708 */ #include "TableOfReal_and_Permutation.h" #include "TableOfReal_extensions.h" #include "NUM2.h" TableOfReal TableOfReal_and_Permutation_permuteRows (TableOfReal me, Permutation thee) { try { if (my numberOfRows != thy numberOfElements) { Melder_throw (U"The number of rows in the table and the number of elements in the Permutation must be equal."); } autoTableOfReal him = TableOfReal_create (my numberOfRows, my numberOfColumns); for (long i = 1; i <= thy numberOfElements; i++) { TableOfReal_copyOneRowWithLabel (me, him.peek(), thy p[i], i); } for (long j = 1; j <= my numberOfColumns; j++) { TableOfReal_setColumnLabel (him.peek(), j, my columnLabels[j]); } return him.transfer(); } catch (MelderError) { Melder_throw (me, U": not permuted."); } } Permutation TableOfReal_to_Permutation_sortRowLabels (TableOfReal me) { try { autoPermutation thee = Permutation_create (my numberOfRows); NUMindexx_s (my rowLabels, my numberOfRows, thy p); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no Permutation created."); } } /* End of file TableOfReal_and_Permutation.cpp */ praat-6.0.04/dwtools/TableOfReal_and_Permutation.h000066400000000000000000000023501261542461700221150ustar00rootroot00000000000000#ifndef _TableOfReal_and_Permutation_h_ #define _TableOfReal_and_Permutation_h_ /* TableOfReal_and_Permutation.h * * Copyright (C) 2005-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20050708 djmw 20110307 Latest modification */ #include "Permutation.h" #include "TableOfReal.h" TableOfReal TableOfReal_and_Permutation_permuteRows (TableOfReal me, Permutation thee); /* Permutation (n1,n2,..nn) new his z[1] = my z[n1], his z[2] = my z[n2], ..*/ Permutation TableOfReal_to_Permutation_sortRowLabels (TableOfReal me); #endif /* _TableOfReal_and_Permutation_h_ */ praat-6.0.04/dwtools/TableOfReal_and_SVD.cpp000066400000000000000000000060331261542461700205770ustar00rootroot00000000000000/* TableOfReal_and_SVD.cpp * * Copyright (C) 1993-2012 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20021009 GPL header djmw 20031107 Added TablesOfReal_to_GSVD. djmw 20051202 Extract left/right singular vectors. */ #include "TableOfReal_and_SVD.h" #define MIN(m,n) ((m) < (n) ? (m) : (n)) TableOfReal SVD_to_TableOfReal (SVD me, long from, long to) { try { autoTableOfReal thee = TableOfReal_create (my numberOfRows, my numberOfColumns); SVD_synthesize (me, from, to, thy data); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no TableOfReal synthesized."); } } SVD TableOfReal_to_SVD (TableOfReal me) { try { autoSVD thee = SVD_create_d (my data, my numberOfRows, my numberOfColumns); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no SVD created."); } } TableOfReal SVD_extractLeftSingularVectors (SVD me) { try { long mn_min = MIN (my numberOfRows, my numberOfColumns); autoTableOfReal thee = TableOfReal_create (my numberOfRows, mn_min); NUMmatrix_copyElements (my u, thy data, 1, my numberOfRows, 1, mn_min); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": left singular vector not extracted."); } } TableOfReal SVD_extractRightSingularVectors (SVD me) { try { long mn_min = MIN (my numberOfRows, my numberOfColumns); autoTableOfReal thee = TableOfReal_create (my numberOfColumns, mn_min); NUMmatrix_copyElements (my v, thy data, 1, my numberOfColumns, 1, mn_min); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": right singular vector not extracted."); } } TableOfReal SVD_extractSingularValues (SVD me) { try { long mn_min = MIN (my numberOfRows, my numberOfColumns); autoTableOfReal thee = TableOfReal_create (1, mn_min); NUMvector_copyElements (my d, thy data[1], 1, mn_min); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": singular values not extracted."); } } GSVD TablesOfReal_to_GSVD (TableOfReal me, TableOfReal thee) { try { if (my numberOfColumns != thy numberOfColumns) { Melder_throw (U"Both tables must have the same number of columns."); } autoGSVD him = GSVD_create_d (my data, my numberOfRows, my numberOfColumns, thy data, thy numberOfRows); return him.transfer(); } catch (MelderError) { Melder_throw (U"GSVD not constructed from TablesOfReal."); } } /* End of file SVD_and_TableOfReal.cpp */ praat-6.0.04/dwtools/TableOfReal_and_SVD.h000066400000000000000000000024271261542461700202470ustar00rootroot00000000000000#ifndef _TableOfReal_and_SVD_h_ #define TableOfReal_and_SVD_h_ /* TableOfReal_and_SVD.h * * Copyright (C) 1993-2011 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20021009 GPL header djmw 20110397 Latest modification */ #include "SVD.h" #include "TableOfReal.h" SVD TableOfReal_to_SVD (TableOfReal me); GSVD TablesOfReal_to_GSVD (TableOfReal me, TableOfReal thee); TableOfReal SVD_to_TableOfReal (SVD me, long from, long to); TableOfReal SVD_extractLeftSingularVectors (SVD me); TableOfReal SVD_extractRightSingularVectors (SVD me); TableOfReal SVD_extractSingularValues (SVD me); #endif // _TableOfReal_and_SVD_h_ praat-6.0.04/dwtools/TableOfReal_extensions.cpp000066400000000000000000001576651261542461700215420ustar00rootroot00000000000000/* TableOfReal_extensions.cpp * * Copyright (C) 1993-2012, 2014, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20000202 17 typos in F1-3,L1-3 table corrected djmw 20030707 Changed TableOfReal_drawVectors interface. djmw 20031030 Added TableOfReal_appendColumns djmw 20031216 Interface change in TableOfReal_choleskyDecomposition djmw 20040108 Corrected a memory leak in TableOfReal_drawBoxPlots djmw 20040211 Modified TableOfReal_copyLabels behaviour: copy NULL-labels too. djmw 20040511 Removed TableOfReal_extractRowsByRowLabel,TableOfReal_selectColumnsWhereRow djmw 20040617 Removed column selection bug in TableOfReal_drawRowsAsHistogram djmw 20041105 Added TableOfReal_createFromVanNieropData_25females djmw 20041115 TableOfReal_drawScatterPlot: plotting a NULL-label crashed Praat. djmw 20041213 Added TableOfReal_createFromWeeninkData. djmw 20050221 TableOfReal_meansByRowLabels, extra reduce parameter. djmw 20050222 TableOfReal_drawVectors didn't draw rowlabels. djmw 20050512 TableOfReal TableOfReal_meansByRowLabels crashed if first label in sorted was NULL. djmw 20051116 TableOfReal_drawScatterPlot draw reverse permited by choosing xmin > xmax and/or ymin>ymax djmw 20060301 TableOfReal_meansByRowLabels extra medianize djmw 20060626 Extra NULL argument for ExecRE. djmw 20061021 printf expects %ld for 'long int' djmw 20070822 wchar djmw 20070902 Better error messages (object type and name feedback) djmw 20070614 updated to version 1.30 of regular expressions. djmw 20071202 Melder_warning djmw 20080122 float -> double djmw 20081119 +TableOfReal_areAllCellsDefined djmw 20090506 +setInner for _drawScatterPlotMatrix djmw 20091009 +TableOfReal_drawColumnAsDistribution djmw 20100222 Corrected a bug in TableOfReal_copyOneRowWithLabel which caused label corruption if from and to table were equal and rows were equal too. djmw 20111110 Use autostringvector djmw 20111123 Always use Melder_wcscmp */ #include #include "Graphics_extensions.h" #include "SSCP.h" #include "Matrix_extensions.h" #include "NUMclapack.h" #include "NUM2.h" #include "SVD.h" #include "Table_extensions.h" #include "TableOfReal_extensions.h" #include "TableOfReal_and_Permutation.h" #include "regularExp.h" #include "Formula.h" #define EMPTY_STRING(s) (! (s) || s[0] == '\0') #define MAX(m,n) ((m) > (n) ? (m) : (n)) #define MIN(m,n) ((m) < (n) ? (m) : (n)) #define Graphics_ARROW 1 #define Graphics_TWOWAYARROW 2 #define Graphics_LINE 3 static TableOfReal TableOfReal_and_TableOfReal_columnCorrelations (TableOfReal me, TableOfReal thee, int center, int normalize); static TableOfReal TableOfReal_and_TableOfReal_rowCorrelations (TableOfReal me, TableOfReal thee, int center, int normalize); long TableOfReal_getColumnIndexAtMaximumInRow (TableOfReal me, long rowNumber) { long columnNumber = 0; if (rowNumber > 0 && rowNumber <= my numberOfRows) { double max = my data[rowNumber][1]; columnNumber = 1; for (long icol = 2; icol <= my numberOfColumns; icol++) { if (my data[rowNumber][icol] > max) { max = my data[rowNumber][icol]; columnNumber = icol; } } } return columnNumber; } const char32 *TableOfReal_getColumnLabelAtMaximumInRow (TableOfReal me, long rowNumber) { long columnNumber = TableOfReal_getColumnIndexAtMaximumInRow (me, rowNumber); return my v_getColStr (columnNumber); } int TableOfReal_areAllCellsDefined (TableOfReal me, long rb, long re, long cb, long ce) { if (re <= rb || rb < 1 || re > my numberOfRows) { rb = 1; re = my numberOfRows; } if (ce <= cb || cb < 1 || ce > my numberOfColumns) { cb = 1; ce = my numberOfColumns; } autoNUMvector invalid_columns (1, my numberOfColumns); long numberOfInvalidRows = 0, numberOfInvalidColumns = 0; for (long i = rb; i <= re; i++) { for (long j = cb; j <= ce; j++) { long rowcount = 0; if (my data[i][j] == NUMundefined) { invalid_columns[j]++; rowcount++; } if (rowcount > 0) { numberOfInvalidRows++; } } } if (numberOfInvalidRows != 0) { for (long j = 1; j <= my numberOfColumns; j++) { if (invalid_columns[j] > 0) { numberOfInvalidColumns++; } } Melder_throw (numberOfInvalidRows == 1 ? U"One row contains invalid data." : (numberOfInvalidColumns == 1 ? U"One column contains invalid data." : U"Several rows and columns contain invalid data.")); } return numberOfInvalidRows == 0 ? 1 : 0; } void TableOfReal_copyOneRowWithLabel (TableOfReal me, TableOfReal thee, long myrow, long thyrow) { try { if (me == thee && myrow == thyrow) { return; } if (myrow < 1 || myrow > my numberOfRows || thyrow < 1 || thyrow > thy numberOfRows || my numberOfColumns != thy numberOfColumns) { Melder_throw (U"The dimensions do not fit."); } Melder_free (thy rowLabels[thyrow]); thy rowLabels[thyrow] = Melder_dup (my rowLabels[myrow]); if (my data[myrow] != thy data[thyrow]) { NUMvector_copyElements (my data[myrow], thy data[thyrow], 1, my numberOfColumns); } } catch (MelderError) { Melder_throw (me, U": row ", myrow, U" not copied to ", thee); } } int TableOfReal_hasRowLabels (TableOfReal me) { if (! my rowLabels) { return 0; } for (long i = 1; i <= my numberOfRows; i++) { if (EMPTY_STRING (my rowLabels[i])) { return 0; } } return 1; } int TableOfReal_hasColumnLabels (TableOfReal me) { if (! my columnLabels) { return 0; } for (long i = 1; i <= my numberOfColumns; i++) { if (EMPTY_STRING (my columnLabels[i])) { return 0; } } return 1; } TableOfReal TableOfReal_createIrisDataset () { double iris[150][4] = { {5.1, 3.5, 1.4, 0.2}, {4.9, 3.0, 1.4, 0.2}, {4.7, 3.2, 1.3, 0.2}, {4.6, 3.1, 1.5, 0.2}, {5.0, 3.6, 1.4, 0.2}, {5.4, 3.9, 1.7, 0.4}, {4.6, 3.4, 1.4, 0.3}, {5.0, 3.4, 1.5, 0.2}, {4.4, 2.9, 1.4, 0.2}, {4.9, 3.1, 1.5, 0.1}, {5.4, 3.7, 1.5, 0.2}, {4.8, 3.4, 1.6, 0.2}, {4.8, 3.0, 1.4, 0.1}, {4.3, 3.0, 1.1, 0.1}, {5.8, 4.0, 1.2, 0.2}, {5.7, 4.4, 1.5, 0.4}, {5.4, 3.9, 1.3, 0.4}, {5.1, 3.5, 1.4, 0.3}, {5.7, 3.8, 1.7, 0.3}, {5.1, 3.8, 1.5, 0.3}, {5.4, 3.4, 1.7, 0.2}, {5.1, 3.7, 1.5, 0.4}, {4.6, 3.6, 1.0, 0.2}, {5.1, 3.3, 1.7, 0.5}, {4.8, 3.4, 1.9, 0.2}, {5.0, 3.0, 1.6, 0.2}, {5.0, 3.4, 1.6, 0.4}, {5.2, 3.5, 1.5, 0.2}, {5.2, 3.4, 1.4, 0.2}, {4.7, 3.2, 1.6, 0.2}, {4.8, 3.1, 1.6, 0.2}, {5.4, 3.4, 1.5, 0.4}, {5.2, 4.1, 1.5, 0.1}, {5.5, 4.2, 1.4, 0.2}, {4.9, 3.1, 1.5, 0.2}, {5.0, 3.2, 1.2, 0.2}, {5.5, 3.5, 1.3, 0.2}, {4.9, 3.6, 1.4, 0.1}, {4.4, 3.0, 1.3, 0.2}, {5.1, 3.4, 1.5, 0.2}, {5.0, 3.5, 1.3, 0.3}, {4.5, 2.3, 1.3, 0.3}, {4.4, 3.2, 1.3, 0.2}, {5.0, 3.5, 1.6, 0.6}, {5.1, 3.8, 1.9, 0.4}, {4.8, 3.0, 1.4, 0.3}, {5.1, 3.8, 1.6, 0.2}, {4.6, 3.2, 1.4, 0.2}, {5.3, 3.7, 1.5, 0.2}, {5.0, 3.3, 1.4, 0.2}, {7.0, 3.2, 4.7, 1.4}, {6.4, 3.2, 4.5, 1.5}, {6.9, 3.1, 4.9, 1.5}, {5.5, 2.3, 4.0, 1.3}, {6.5, 2.8, 4.6, 1.5}, {5.7, 2.8, 4.5, 1.3}, {6.3, 3.3, 4.7, 1.6}, {4.9, 2.4, 3.3, 1.0}, {6.6, 2.9, 4.6, 1.3}, {5.2, 2.7, 3.9, 1.4}, {5.0, 2.0, 3.5, 1.0}, {5.9, 3.0, 4.2, 1.5}, {6.0, 2.2, 4.0, 1.0}, {6.1, 2.9, 4.7, 1.4}, {5.6, 2.9, 3.6, 1.3}, {6.7, 3.1, 4.4, 1.4}, {5.6, 3.0, 4.5, 1.5}, {5.8, 2.7, 4.1, 1.0}, {6.2, 2.2, 4.5, 1.5}, {5.6, 2.5, 3.9, 1.1}, {5.9, 3.2, 4.8, 1.8}, {6.1, 2.8, 4.0, 1.3}, {6.3, 2.5, 4.9, 1.5}, {6.1, 2.8, 4.7, 1.2}, {6.4, 2.9, 4.3, 1.3}, {6.6, 3.0, 4.4, 1.4}, {6.8, 2.8, 4.8, 1.4}, {6.7, 3.0, 5.0, 1.7}, {6.0, 2.9, 4.5, 1.5}, {5.7, 2.6, 3.5, 1.0}, {5.5, 2.4, 3.8, 1.1}, {5.5, 2.4, 3.7, 1.0}, {5.8, 2.7, 3.9, 1.2}, {6.0, 2.7, 5.1, 1.6}, {5.4, 3.0, 4.5, 1.5}, {6.0, 3.4, 4.5, 1.6}, {6.7, 3.1, 4.7, 1.5}, {6.3, 2.3, 4.4, 1.3}, {5.6, 3.0, 4.1, 1.3}, {5.5, 2.5, 4.0, 1.3}, {5.5, 2.6, 4.4, 1.2}, {6.1, 3.0, 4.6, 1.4}, {5.8, 2.6, 4.0, 1.2}, {5.0, 2.3, 3.3, 1.0}, {5.6, 2.7, 4.2, 1.3}, {5.7, 3.0, 4.2, 1.2}, {5.7, 2.9, 4.2, 1.3}, {6.2, 2.9, 4.3, 1.3}, {5.1, 2.5, 3.0, 1.1}, {5.7, 2.8, 4.1, 1.3}, {6.3, 3.3, 6.0, 2.5}, {5.8, 2.7, 5.1, 1.9}, {7.1, 3.0, 5.9, 2.1}, {6.3, 2.9, 5.6, 1.8}, {6.5, 3.0, 5.8, 2.2}, {7.6, 3.0, 6.6, 2.1}, {4.9, 2.5, 4.5, 1.7}, {7.3, 2.9, 6.3, 1.8}, {6.7, 2.5, 5.8, 1.8}, {7.2, 3.6, 6.1, 2.5}, {6.5, 3.2, 5.1, 2.0}, {6.4, 2.7, 5.3, 1.9}, {6.8, 3.0, 5.5, 2.1}, {5.7, 2.5, 5.0, 2.0}, {5.8, 2.8, 5.1, 2.4}, {6.4, 3.2, 5.3, 2.3}, {6.5, 3.0, 5.5, 1.8}, {7.7, 3.8, 6.7, 2.2}, {7.7, 2.6, 6.9, 2.3}, {6.0, 2.2, 5.0, 1.5}, {6.9, 3.2, 5.7, 2.3}, {5.6, 2.8, 4.9, 2.0}, {7.7, 2.8, 6.7, 2.0}, {6.3, 2.7, 4.9, 1.8}, {6.7, 3.3, 5.7, 2.1}, {7.2, 3.2, 6.0, 1.8}, {6.2, 2.8, 4.8, 1.8}, {6.1, 3.0, 4.9, 1.8}, {6.4, 2.8, 5.6, 2.1}, {7.2, 3.0, 5.8, 1.6}, {7.4, 2.8, 6.1, 1.9}, {7.9, 3.8, 6.4, 2.0}, {6.4, 2.8, 5.6, 2.2}, {6.3, 2.8, 5.1, 1.5}, {6.1, 2.6, 5.6, 1.4}, {7.7, 3.0, 6.1, 2.3}, {6.3, 3.4, 5.6, 2.4}, {6.4, 3.1, 5.5, 1.8}, {6.0, 3.0, 4.8, 1.8}, {6.9, 3.1, 5.4, 2.1}, {6.7, 3.1, 5.6, 2.4}, {6.9, 3.1, 5.1, 2.3}, {5.8, 2.7, 5.1, 1.9}, {6.8, 3.2, 5.9, 2.3}, {6.7, 3.3, 5.7, 2.5}, {6.7, 3.0, 5.2, 2.3}, {6.3, 2.5, 5.0, 1.9}, {6.5, 3.0, 5.2, 2.0}, {6.2, 3.4, 5.4, 2.3}, {5.9, 3.0, 5.1, 1.8} }; try { autoTableOfReal me = TableOfReal_create (150, 4); TableOfReal_setColumnLabel (me.peek(), 1, U"sl"); TableOfReal_setColumnLabel (me.peek(), 2, U"sw"); TableOfReal_setColumnLabel (me.peek(), 3, U"pl"); TableOfReal_setColumnLabel (me.peek(), 4, U"pw"); for (long i = 1; i <= 150; i++) { int kind = (i - 1) / 50 + 1; char32 const *label = kind == 1 ? U"1" : kind == 2 ? U"2" : U"3"; for (long j = 1; j <= 4; j++) { my data[i][j] = iris[i - 1][j - 1]; } TableOfReal_setRowLabel (me.peek(), i, label); } Thing_setName (me.peek(), U"iris"); return me.transfer(); } catch (MelderError) { Melder_throw (U"TableOfReal from iris data not created."); } } Strings TableOfReal_extractRowLabels (TableOfReal me) { try { autoStrings thee = Thing_new (Strings); if (my numberOfRows > 0) { thy strings = NUMvector (1, my numberOfRows); thy numberOfStrings = my numberOfRows; for (long i = 1; i <= my numberOfRows; i++) { const char32 *label = my rowLabels[i] ? my rowLabels[i] : U"?"; thy strings[i] = Melder_dup (label); } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": row labels not extracted."); } } Strings TableOfReal_extractColumnLabels (TableOfReal me) { try { autoStrings thee = Thing_new (Strings); if (my numberOfColumns > 0) { thy strings = NUMvector (1, my numberOfColumns); thy numberOfStrings = my numberOfColumns; for (long i = 1; i <= my numberOfColumns; i++) { char32 const *label = my columnLabels[i] ? my columnLabels[i] : U"?"; thy strings[i] = Melder_dup (label); } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": column labels not extracted."); } } TableOfReal TableOfReal_transpose (TableOfReal me) { try { autoTableOfReal thee = TableOfReal_create (my numberOfColumns, my numberOfRows); for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= my numberOfColumns; j++) { thy data[j][i] = my data[i][j]; } } NUMstrings_copyElements (my rowLabels, thy columnLabels, 1, my numberOfRows); NUMstrings_copyElements (my columnLabels, thy rowLabels, 1, my numberOfColumns); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not transposed."); } } int TableOfReal_to_Pattern_and_Categories (TableOfReal me, long fromrow, long torow, long fromcol, long tocol, Pattern *p, Categories *c) { *p = nullptr; *c = nullptr; try { long ncol = my numberOfColumns, nrow = my numberOfRows; if (fromrow == torow && fromrow == 0) { fromrow = 1; torow = nrow; } else if (fromrow > 0 && fromrow <= nrow && torow == 0) { torow = nrow; } else if (! (fromrow > 0 && torow <= nrow && fromrow <= torow)) { Melder_throw (U"Invalid row selection."); } if (fromcol == tocol && fromcol == 0) { fromcol = 1; tocol = ncol; } else if (fromcol > 0 && fromcol <= ncol && tocol == 0) { tocol = ncol; } else if (! (fromcol > 0 && tocol <= ncol && fromcol <= tocol)) { Melder_throw (U"Invalid column selection."); } nrow = torow - fromrow + 1; ncol = tocol - fromcol + 1; autoPattern ap = Pattern_create (nrow, ncol); autoCategories ac = Categories_create (); long row = 1; for (long i = fromrow; i <= torow; i++, row++) { char32 const *s = my rowLabels[i] ? my rowLabels[i] : U"?"; autoSimpleString item = SimpleString_create (s); Collection_addItem (ac.peek(), item.transfer()); long col = 1; for (long j = fromcol; j <= tocol; j++, col++) { ap -> z[row][col] = my data[i][j]; } } *p = ap.transfer(); *c = ac.transfer(); return 1; } catch (MelderError) { Melder_throw (U"Pattern and Categories not created from TableOfReal."); } } void TableOfReal_getColumnExtrema (TableOfReal me, long col, double *min, double *max) { *min = NUMundefined; *max = NUMundefined; if (col < 1 || col > my numberOfColumns) { Melder_throw (U"Invalid column number."); } *min = *max = my data[1][col]; for (long i = 2; i <= my numberOfRows; i++) { if (my data[i][col] > *max) { *max = my data[i][col]; } else if (my data[i][col] < *min) { *min = my data[i][col]; } } } void TableOfReal_drawRowsAsHistogram (TableOfReal me, Graphics g, const char32 *rows, long colb, long cole, double ymin, double ymax, double xoffsetFraction, double interbarFraction, double interbarsFraction, const char32 *greys, int garnish) { if (colb >= cole) { colb = 1; cole = my numberOfColumns; } if (colb <= cole && (colb < 1 || cole > my numberOfColumns)) { Melder_throw (U"Invalid columns"); } long nrows; autoNUMvector irows (NUMstring_to_numbers (rows, &nrows), 1); for (long i = 1; i <= nrows; i++) { long irow = (long) floor (irows[i]); if (irow < 0 || irow > my numberOfRows) { Melder_throw (U"Invalid row (", irow, U")."); } if (ymin >= ymax) { double min, max; NUMvector_extrema (my data[irow], colb, cole, &min, &max); if (i > 1) { if (min < ymin) { ymin = min; } if (max > ymax) { ymax = max; } } else { ymin = min; ymax = max; } } } long ngreys; autoNUMvector igreys (NUMstring_to_numbers (greys, &ngreys), 1); Graphics_setWindow (g, 0.0, 1.0, ymin, ymax); Graphics_setInner (g); long ncols = cole - colb + 1; double bar_width = 1.0 / (ncols * nrows + 2.0 * xoffsetFraction + (ncols - 1) * interbarsFraction + ncols * (nrows - 1) * interbarFraction); double dx = (interbarsFraction + nrows + (nrows - 1) * interbarFraction) * bar_width; for (long i = 1; i <= nrows; i++) { long irow = (long) floor (irows[i]); double xb = xoffsetFraction * bar_width + (i - 1) * (1.0 + interbarFraction) * bar_width; double x1 = xb; double grey = i <= ngreys ? igreys[i] : igreys[ngreys]; for (long j = colb; j <= cole; j++) { double x2 = x1 + bar_width; double y1 = ymin, y2 = my data[irow][j]; if (y2 > ymin) { if (y2 > ymax) { y2 = ymax; } Graphics_setGrey (g, grey); Graphics_fillRectangle (g, x1, x2, y1, y2); Graphics_setGrey (g, 0); /* Black */ Graphics_rectangle (g, x1, x2, y1, y2); } x1 += dx; } } Graphics_unsetInner (g); if (garnish) { double xb = (xoffsetFraction + 0.5 * (nrows + (nrows - 1) * interbarFraction)) * bar_width; for (long j = colb; j <= cole; j++) { if (my columnLabels[j]) { Graphics_markBottom (g, xb, false, false, false, my columnLabels[j]); } xb += dx; } Graphics_drawInnerBox (g); Graphics_marksLeft (g, 2, true, true, false); } } void TableOfReal_drawBiplot (TableOfReal me, Graphics g, double xmin, double xmax, double ymin, double ymax, double sv_splitfactor, int labelsize, int garnish) { long nr = my numberOfRows, nc = my numberOfColumns, nPoints = nr + nc; int fontsize = Graphics_inqFontSize (g); autoSVD svd = SVD_create (nr, nc); NUMmatrix_copyElements (my data, svd -> u, 1, nr, 1, nc); NUMcentreColumns (svd -> u, 1, nr, 1, nc, nullptr); SVD_compute (svd.peek()); long numberOfZeroed = SVD_zeroSmallSingularValues (svd.peek(), 0.0); long nmin = MIN (nr, nc) - numberOfZeroed; if (nmin < 2) { Melder_throw (U"There must be at least two (independent) columns in the table."); } autoNUMvector x (1, nPoints); autoNUMvector y (1, nPoints); double lambda1 = pow (svd -> d[1], sv_splitfactor); double lambda2 = pow (svd -> d[2], sv_splitfactor); for (long i = 1; i <= nr; i++) { x[i] = svd -> u[i][1] * lambda1; y[i] = svd -> u[i][2] * lambda2; } lambda1 = svd -> d[1] / lambda1; lambda2 = svd -> d[2] / lambda2; for (long i = 1; i <= nc; i++) { x[nr + i] = svd -> v[i][1] * lambda1; y[nr + i] = svd -> v[i][2] * lambda2; } if (xmax <= xmin) { NUMvector_extrema (x.peek(), 1, nPoints, &xmin, &xmax); } if (xmax <= xmin) { xmax += 1; xmin -= 1; } if (ymax <= ymin) { NUMvector_extrema (y.peek(), 1, nPoints, &ymin, &ymax); } if (ymax <= ymin) { ymax += 1.0; ymin -= 1.0; } Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_setInner (g); if (labelsize > 0) { Graphics_setFontSize (g, labelsize); } Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); for (long i = 1; i <= nPoints; i++) { char32 const *label; if (i <= nr) { label = my rowLabels[i]; if (! label) { label = U"?__r_"; } } else { label = my columnLabels[i - nr]; if (! label) { label = U"?__c_"; } } Graphics_text (g, x[i], y[i], label); } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksLeft (g, 2, true, true, false); Graphics_marksBottom (g, 2, true, true, false); } if (labelsize > 0) { Graphics_setFontSize (g, fontsize); } } void TableOfReal_drawBoxPlots (TableOfReal me, Graphics g, long rowmin, long rowmax, long colmin, long colmax, double ymin, double ymax, int garnish) { if (rowmax < rowmin || rowmax < 1) { rowmin = 1; rowmax = my numberOfRows; } if (rowmin < 1) { rowmin = 1; } if (rowmax > my numberOfRows) { rowmax = my numberOfRows; } long numberOfRows = rowmax - rowmin + 1; if (colmax < colmin || colmax < 1) { colmin = 1; colmax = my numberOfColumns; } if (colmin < 1) { colmin = 1; } if (colmax > my numberOfColumns) { colmax = my numberOfColumns; } if (ymax <= ymin) { NUMmatrix_extrema (my data, rowmin, rowmax, colmin, colmax, &ymin, &ymax); } autoNUMvector data (1, numberOfRows); Graphics_setWindow (g, colmin - 0.5, colmax + 0.5, ymin, ymax); Graphics_setInner (g); for (long j = colmin; j <= colmax; j++) { double x = j, r = 0.05, w = 0.2, t; long ndata = 0; for (long i = 1; i <= numberOfRows; i++) { if ( (t = my data[rowmin + i - 1][j]) != NUMundefined) { data[++ndata] = t; } } Graphics_boxAndWhiskerPlot (g, data.peek(), ndata, x, r, w, ymin, ymax); } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); for (long j = colmin; j <= colmax; j++) { if (my columnLabels && my columnLabels[j] && my columnLabels[j][0]) { Graphics_markBottom (g, j, false, true, false, my columnLabels [j]); } } Graphics_marksLeft (g, 2, true, true, false); } } int TableOfReal_equalLabels (TableOfReal me, TableOfReal thee, int rowLabels, int columnLabels) { Melder_assert (rowLabels || columnLabels); if (rowLabels) { if (my numberOfRows != thy numberOfRows) { return 0; } if (my rowLabels == thy rowLabels) { return 1; } for (long i = 1; i <= my numberOfRows; i++) { if (Melder_cmp (my rowLabels[i], thy rowLabels[i])) { return 0; } } } if (columnLabels) { if (my numberOfColumns != thy numberOfColumns) { return 0; } if (my columnLabels == thy columnLabels) { return 1; } for (long i = 1; i <= my numberOfColumns; i++) { if (Melder_cmp (my columnLabels[i], thy columnLabels[i]) != 0) { return 0; } } } return 1; } void TableOfReal_copyLabels (TableOfReal me, TableOfReal thee, int rowOrigin, int columnOrigin) { if (rowOrigin == 1) { if (my numberOfRows != thy numberOfRows) { Melder_throw (U"#rows1 must equal #rows2"); } NUMstrings_copyElements (my rowLabels, thy rowLabels, 1, thy numberOfRows); } else if (rowOrigin == -1) { if (my numberOfColumns != thy numberOfRows) { Melder_throw (U"#columns1 must equal #rows2."); } NUMstrings_copyElements (my columnLabels, thy rowLabels, 1, thy numberOfRows); } if (columnOrigin == 1) { if (my numberOfColumns != thy numberOfColumns) { Melder_throw (U"#columns1 must equal #columns2."); } NUMstrings_copyElements (my columnLabels, thy columnLabels, 1, thy numberOfColumns); } else if (columnOrigin == -1) { if (my numberOfRows != thy numberOfColumns) { Melder_throw (U"#rows1 must equal #columns2"); } NUMstrings_copyElements (my rowLabels, thy columnLabels, 1, thy numberOfColumns); } } void TableOfReal_labelsFromCollectionItemNames (TableOfReal me, Collection thee, int row, int column) { try { if (row) { Melder_assert (my numberOfRows == thy size); for (long i = 1; i <= my numberOfRows; i++) { const char32 *name = Thing_getName ( (Thing) thy item[i]); TableOfReal_setRowLabel (me, i, name); } } if (column) { Melder_assert (my numberOfColumns == thy size); for (long i = 1; i <= my numberOfColumns; i++) { const char32 *name = Thing_getName ( (Thing) thy item[i]); TableOfReal_setColumnLabel (me, i, name); } } } catch (MelderError) { Melder_throw (me, U": labels not changed."); } } void TableOfReal_centreColumns (TableOfReal me) { NUMcentreColumns (my data, 1, my numberOfRows, 1, my numberOfColumns, nullptr); } void TableOfReal_and_Categories_setRowLabels (TableOfReal me, Categories thee) { try { if (my numberOfRows != thy size) { Melder_throw (U"The number of items in both objects must be equal."); } /* If anything goes wrong we must leave the Table intact. We first copy the Categories, swap the labels and then delete the newly created categories. */ autoCategories c = Data_copy (thee); for (long i = 1; i <= my numberOfRows; i++) { SimpleString s = (SimpleString) c -> item[i]; char32 *t = s -> string; s -> string = my rowLabels[i]; my rowLabels[i] = t; } } catch (MelderError) { Melder_throw (me, U": row labels not set from categories."); } } void TableOfReal_centreColumns_byRowLabel (TableOfReal me) { char32 *label = my rowLabels[1]; long index = 1; for (long i = 2; i <= my numberOfRows; i++) { char32 *li = my rowLabels[i]; if (Melder_cmp (li, label) != 0) { NUMcentreColumns (my data, index, i - 1, 1, my numberOfColumns, 0); label = li; index = i; } } NUMcentreColumns (my data, index, my numberOfRows, 1, my numberOfColumns, nullptr); } double TableOfReal_getRowSum (TableOfReal me, long index) { if (index < 1 || index > my numberOfRows) { return NUMundefined; } double sum = 0.0; for (long j = 1; j <= my numberOfColumns; j++) { sum += my data[index][j]; } return sum; } double TableOfReal_getColumnSumByLabel (TableOfReal me, const char32 *label) { long index = TableOfReal_columnLabelToIndex (me, label); if (index < 1) { Melder_throw (U"There is no \"", label, U"\" column label."); } return TableOfReal_getColumnSum (me, index); } double TableOfReal_getRowSumByLabel (TableOfReal me, const char32 *label) { long index = TableOfReal_rowLabelToIndex (me, label); if (index < 1) { Melder_throw (U"There is no \"", label, U"\" row label."); } return TableOfReal_getRowSum (me, index); } double TableOfReal_getColumnSum (TableOfReal me, long index) { if (index < 1 || index > my numberOfColumns) { return NUMundefined; } double sum = 0.0; for (long i = 1; i <= my numberOfRows; i++) { sum += my data[i][index]; } return sum; } double TableOfReal_getGrandSum (TableOfReal me) { double sum = 0.0; for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= my numberOfColumns; j++) { sum += my data[i][j]; } } return sum; } void TableOfReal_centreRows (TableOfReal me) { NUMcentreRows (my data, 1, my numberOfRows, 1, my numberOfColumns); } void TableOfReal_doubleCentre (TableOfReal me) { NUMdoubleCentre (my data, 1, my numberOfRows, 1, my numberOfColumns); } void TableOfReal_normalizeColumns (TableOfReal me, double norm) { NUMnormalizeColumns (my data, my numberOfRows, my numberOfColumns, norm); } void TableOfReal_normalizeRows (TableOfReal me, double norm) { NUMnormalizeRows (my data, my numberOfRows, my numberOfColumns, norm); } void TableOfReal_standardizeColumns (TableOfReal me) { NUMstandardizeColumns (my data, 1, my numberOfRows, 1, my numberOfColumns); } void TableOfReal_standardizeRows (TableOfReal me) { NUMstandardizeRows (my data, 1, my numberOfRows, 1, my numberOfColumns); } void TableOfReal_normalizeTable (TableOfReal me, double norm) { NUMnormalize (my data, my numberOfRows, my numberOfColumns, norm); } double TableOfReal_getTableNorm (TableOfReal me) { double sumsq = 0.0; for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= my numberOfColumns; j++) { sumsq += my data[i][j] * my data[i][j]; } } return sqrt (sumsq); } int TableOfReal_checkPositive (TableOfReal me) { long negative = 0; for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= my numberOfColumns; j++) { if (my data[i][j] < 0.0) { negative ++; break; } } } return negative == 0; } /* NUMundefined ??? */ void NUMdmatrix_getColumnExtrema (double **a, long rowb, long rowe, long icol, double *min, double *max); void NUMdmatrix_getColumnExtrema (double **a, long rowb, long rowe, long icol, double *min, double *max) { *min = *max = a[rowb][icol]; for (long i = rowb + 1; i <= rowe; i++) { double t = a[i][icol]; if (t > *max) { *max = t; } else if (t < *min) { *min = t; } } } void TableOfReal_drawScatterPlotMatrix (TableOfReal me, Graphics g, long colb, long cole, double fractionWhite) { long m = my numberOfRows; if (colb == 0 && cole == 0) { colb = 1; cole = my numberOfColumns; } else if (cole < colb || colb < 1 || cole > my numberOfColumns) { return; } long n = cole - colb + 1; if (n == 1) { return; } autoNUMvector xmin (colb, cole); autoNUMvector xmax (colb, cole); for (long j = colb; j <= cole; j++) { xmin[j] = xmax[j] = my data[1][j]; } for (long i = 2; i <= m; i++) { for (long j = colb; j <= cole; j++) { if (my data[i][j] > xmax[j]) { xmax[j] = my data[i][j]; } else if (my data[i][j] < xmin[j]) { xmin[j] = my data[i][j]; } } } for (long j = colb; j <= cole; j++) { double extra = fractionWhite * fabs (xmax[j] - xmin[j]); if (extra == 0) { extra = 0.5; } xmin[j] -= extra; xmax[j] += extra; } Graphics_setWindow (g, 0.0, n, 0.0, n); Graphics_setInner (g); Graphics_line (g, 0.0, n, n, n); Graphics_line (g, 0.0, 0.0, 0.0, n); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); for (long i = 1; i <= n; i++) { long xcol, ycol = colb + i - 1; const char32 *mark; char32 label[40]; Graphics_line (g, 0.0, n - i, n, n - i); Graphics_line (g, i, n, i, 0.0); for (long j = 1; j <= n; j++) { xcol = colb + j - 1; if (i == j) { mark = my columnLabels[xcol]; if (! mark) { Melder_sprint (label,40, U"Column ", xcol); // ppgb: 20 chars is niet genoeg voor een long mark = label; } Graphics_text (g, j - 0.5, n - i + 0.5, mark); } else { for (long k = 1; k <= m; k++) { double x = j - 1 + (my data[k][xcol] - xmin[xcol]) / (xmax[xcol] - xmin[xcol]); double y = n - i + (my data[k][ycol] - xmin[ycol]) / (xmax[ycol] - xmin[ycol]); mark = EMPTY_STRING (my rowLabels[k]) ? U"+" : my rowLabels[k]; Graphics_text (g, x, y, mark); } } } } Graphics_unsetInner (g); } void TableOfReal_drawAsSquares_area (TableOfReal me, Graphics g, double zmin, double zmax, double cellSizeFactor, int randomFillOrder, int garnish) { try { cellSizeFactor = cellSizeFactor <= 0.0 ? 1.0 : cellSizeFactor; if (zmin == 0 && zmax == 0) { NUMmatrix_extrema (my data, 1, my numberOfRows, 1, my numberOfColumns, &zmin, &zmax); } double xmin = 0.0, xmax = my numberOfColumns + 1.0, ymin = 0.0, ymax = my numberOfRows + 1.0; Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_setInner (g); Graphics_matrixAsSquares (g, my data, my numberOfRows, my numberOfColumns, zmin, zmax, cellSizeFactor, randomFillOrder); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksBottomEvery (g, 1.0, 1.0, false, true, false); Graphics_marksLeftEvery (g, 1.0, 1.0, false, true, false); } } catch (MelderError) { Melder_clearError (); // drawing errors shall be ignored } } void TableOfReal_drawScatterPlot (TableOfReal me, Graphics g, long icx, long icy, long rowb, long rowe, double xmin, double xmax, double ymin, double ymax, int labelSize, int useRowLabels, const char32 *label, int garnish) { double m = my numberOfRows, n = my numberOfColumns; int fontSize = Graphics_inqFontSize (g); if (icx < 1 || icx > n || icy < 1 || icy > n) { return; } if (rowb < 1) { rowb = 1; } if (rowe > m) { rowe = (long) floor (m); } if (rowe <= rowb) { rowb = 1; rowe = (long) floor (m); } if (xmax == xmin) { NUMdmatrix_getColumnExtrema (my data, rowb, rowe, icx, & xmin, & xmax); double tmp = xmax - xmin == 0.0 ? 0.5 : 0.0; xmin -= tmp; xmax += tmp; } if (ymax == ymin) { NUMdmatrix_getColumnExtrema (my data, rowb, rowe, icy, & ymin, & ymax); double tmp = ymax - ymin == 0.0 ? 0.5 : 0.0; ymin -= tmp; ymax += tmp; } Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_setInner (g); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); Graphics_setFontSize (g, labelSize); long noLabel = 0; for (long i = rowb; i <= rowe; i++) { double x = my data[i][icx], y = my data[i][icy]; if (((xmin < xmax && x >= xmin && x <= xmax) || (xmin > xmax && x <= xmin && x >= xmax)) && ((ymin < ymax && y >= ymin && y <= ymax) || (ymin > ymax && y <= ymin && y >= ymax))) { const char32 *plotLabel = useRowLabels ? my rowLabels[i] : label; if (! NUMstring_containsPrintableCharacter (plotLabel)) { noLabel++; continue; } Graphics_text (g, x, y, plotLabel); } } Graphics_setFontSize (g, fontSize); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); if (ymin < ymax) { if (my columnLabels[icx]) { Graphics_textBottom (g, true, my columnLabels[icx]); } Graphics_marksBottom (g, 2, true, true, false); } else { if (my columnLabels[icx]) { Graphics_textTop (g, true, my columnLabels[icx]); } Graphics_marksTop (g, 2, true, true, false); } if (xmin < xmax) { if (my columnLabels[icy]) { Graphics_textLeft (g, true, my columnLabels[icy]); } Graphics_marksLeft (g, 2, true, true, false); } else { if (my columnLabels[icy]) { Graphics_textRight (g, true, my columnLabels[icy]); } Graphics_marksRight (g, 2, true, true, false); } } if (noLabel > 0) { Melder_warning (noLabel, U" from ", my numberOfRows, U" labels are " U"not visible because they are empty or they contain only spaces or non-printable characters"); } } /**************** TABLESOFREAL **************************************/ Thing_implement (TablesOfReal, Ordered, 0); void TablesOfReal_init (TablesOfReal me, ClassInfo klas) { Ordered_init (me, klas, 10); } TablesOfReal TablesOfReal_create () { try { autoTablesOfReal me = Thing_new (TablesOfReal); TablesOfReal_init (me.peek(), classTableOfReal); return me.transfer(); } catch (MelderError) { Melder_throw (U"TablesOfReal not created."); } } TableOfReal TablesOfReal_sum (TablesOfReal me) { try { if (my size <= 0) { return nullptr; } autoTableOfReal thee = Data_copy ((TableOfReal) my item[1]); for (long i = 2; i <= my size; i++) { TableOfReal him = (TableOfReal) my item[i]; if (thy numberOfRows != his numberOfRows || thy numberOfColumns != his numberOfColumns || ! TableOfReal_equalLabels (thee.peek(), him, 1, 1)) { Melder_throw (U"Dimensions or labels differ for table 1 and ", i, U"."); } for (long j = 1; j <= thy numberOfRows; j++) { for (long k = 1; k <= thy numberOfColumns; k++) { thy data[j][k] += his data[j][k]; } } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": sum not created."); } } int TablesOfReal_checkDimensions (TablesOfReal me) { if (my size < 2) { return 1; } TableOfReal t1 = (TableOfReal) my item[1]; for (long i = 2; i <= my size; i++) { TableOfReal t = (TableOfReal) my item[i]; if (t -> numberOfColumns != t1 -> numberOfColumns || t -> numberOfRows != t1 -> numberOfRows) { return 0; } } return 1; } double TableOfReal_getColumnQuantile (TableOfReal me, long col, double quantile) { try { if (col < 1 || col > my numberOfColumns) { return NUMundefined; } autoNUMvector values (1, my numberOfRows); for (long i = 1; i <= my numberOfRows; i++) { values[i] = my data[i][col]; } NUMsort_d (my numberOfRows, values.peek()); double r = NUMquantile (my numberOfRows, values.peek(), quantile); return r; } catch (MelderError) { return NUMundefined; } } static TableOfReal TableOfReal_createPolsVanNieropData (int choice, int include_levels) { try { autoTable table = Table_createFromPolsVanNieropData (); // Default: Pols 50 males, first part of the table. long nrows = 50 * 12; long ncols = include_levels ? 6 : 3; long ib = 1; if (choice == 2) { /* Van Nierop 25 females */ ib = nrows + 1; nrows = 25 * 12; } autoTableOfReal thee = TableOfReal_create (nrows, ncols); for (long i = 1; i <= nrows; i++) { TableRow row = (TableRow) table -> rows -> item[ib + i - 1]; TableOfReal_setRowLabel (thee.peek(), i, row -> cells[4].string); for (long j = 1; j <= 3; j++) { thy data[i][j] = Melder_atof (row -> cells[4 + j].string); if (include_levels) { thy data[i][3 + j] = Melder_atof (row -> cells[7 + j].string); } } } for (long j = 1; j <= 3; j++) { const char32 *label = table -> columnHeaders[4 + j].label; TableOfReal_setColumnLabel (thee.peek(), j, label); if (include_levels) { label = table -> columnHeaders[7 + j].label; TableOfReal_setColumnLabel (thee.peek(), 3 + j, label); } } return thee.transfer(); } catch (MelderError) { Melder_throw (U"TableOfReal from Pols & Van Nierop data not created."); } } TableOfReal TableOfReal_createFromPolsData_50males (int include_levels) { return TableOfReal_createPolsVanNieropData (1, include_levels); } TableOfReal TableOfReal_createFromVanNieropData_25females (int include_levels) { return TableOfReal_createPolsVanNieropData (2, include_levels); } TableOfReal TableOfReal_createFromWeeninkData (int option) { try { long nvowels = 12, ncols = 3, nrows = 10 * nvowels; autoTable table = Table_createFromWeeninkData (); long ib = option == 1 ? 1 : option == 2 ? 11 : 21; /* m f c*/ ib = (ib - 1) * nvowels + 1; autoTableOfReal thee = TableOfReal_create (nrows, ncols); for (long i = 1; i <= nrows; i++) { TableRow row = (TableRow) table -> rows -> item[ib + i - 1]; TableOfReal_setRowLabel (thee.peek(), i, row -> cells[5].string); for (long j = 1; j <= 3; j++) { thy data[i][j] = Melder_atof (row -> cells[6 + j].string); /* Skip F0 */ } } for (long j = 1; j <= 3; j++) { const char32 *label = table -> columnHeaders[6 + j].label; TableOfReal_setColumnLabel (thee.peek(), j, label); } return thee.transfer(); } catch (MelderError) { Melder_throw (U"TableOfReal from Weenink data not created."); } } TableOfReal TableOfReal_randomizeRows (TableOfReal me) { try { autoPermutation p = Permutation_create (my numberOfRows); Permutation_permuteRandomly_inline (p.peek(), 0, 0); autoTableOfReal thee = TableOfReal_and_Permutation_permuteRows (me, p.peek()); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": randomized rows not created"); } } TableOfReal TableOfReal_bootstrap (TableOfReal me) { try { autoTableOfReal thee = TableOfReal_create (my numberOfRows, my numberOfColumns); // Copy column labels. for (long i = 1; i <= my numberOfColumns; i++) { if (my columnLabels[i]) { TableOfReal_setColumnLabel (thee.peek(), i, my columnLabels[i]); } } /* Select randomly from table with replacement. Because of replacement you do not get back the original data set. A random fraction, typically 1/e (37%) are replaced by duplicates. */ for (long i = 1; i <= my numberOfRows; i++) { long p = NUMrandomInteger (1, my numberOfRows); NUMvector_copyElements (my data[p], thy data[i], 1, my numberOfColumns); if (my rowLabels[p]) { TableOfReal_setRowLabel (thee.peek(), i, my rowLabels[p]); } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": bootstrapped data not created."); } } void TableOfReal_changeRowLabels (TableOfReal me, const char32 *search, const char32 *replace, int maximumNumberOfReplaces, long *nmatches, long *nstringmatches, int use_regexp) { try { autostring32vector rowLabels (strs_replace (my rowLabels, 1, my numberOfRows, search, replace, maximumNumberOfReplaces, nmatches, nstringmatches, use_regexp), 1, my numberOfRows); NUMstrings_free (my rowLabels, 1, my numberOfRows); my rowLabels = rowLabels.transfer(); } catch (MelderError) { Melder_throw (me, U": row labels not changed."); } } void TableOfReal_changeColumnLabels (TableOfReal me, const char32 *search, const char32 *replace, int maximumNumberOfReplaces, long *nmatches, long *nstringmatches, int use_regexp) { try { autostring32vector columnLabels (strs_replace (my columnLabels, 1, my numberOfColumns, search, replace, maximumNumberOfReplaces, nmatches, nstringmatches, use_regexp), 1, my numberOfColumns); NUMstrings_free (my columnLabels, 1, my numberOfColumns); my columnLabels = columnLabels.transfer(); } catch (MelderError) { Melder_throw (me, U": column labels not changed."); } } long TableOfReal_getNumberOfLabelMatches (TableOfReal me, const char32 *search, int columnLabels, int use_regexp) { long nmatches = 0, numberOfLabels = my numberOfRows; char32 **labels = my rowLabels; regexp *compiled_regexp = nullptr; if (! search || str32len (search) == 0) { return 0; } if (columnLabels) { numberOfLabels = my numberOfColumns; labels = my columnLabels; } if (use_regexp) { compiled_regexp = CompileRE_throwable (search, 0); } for (long i = 1; i <= numberOfLabels; i++) { if (! labels[i]) { continue; } if (use_regexp) { if (ExecRE (compiled_regexp, 0, labels[i], nullptr, 0, U'\0', U'\0', 0, 0, 0)) { nmatches++; } } else if (str32equ (labels[i], search)) { nmatches++; } } if (use_regexp) { free (compiled_regexp); } return nmatches; } void TableOfReal_drawVectors (TableOfReal me, Graphics g, long colx1, long coly1, long colx2, long coly2, double xmin, double xmax, double ymin, double ymax, int vectype, int labelsize, int garnish) { long nx = my numberOfColumns, ny = my numberOfRows; int fontsize = Graphics_inqFontSize (g); if (colx1 < 1 || colx1 > nx || coly1 < 1 || coly1 > nx) { Melder_warning (U"The index in the \"From\" column(s) must be in range [1, ", nx, U"]."); return; } if (colx2 < 1 || colx2 > nx || coly2 < 1 || coly2 > nx) { Melder_warning (U"The index in the \"To\" column(s) must be in range [1, ", nx, U"]."); return; } double min, max; if (xmin >= xmax) { NUMmatrix_extrema (my data, 1, ny, colx1, colx1, &min, &max); NUMmatrix_extrema (my data, 1, ny, colx2, colx2, &xmin, &xmax); if (min < xmin) { xmin = min; } if (max > xmax) { xmax = max; } } if (ymin >= ymax) { NUMmatrix_extrema (my data, 1, ny, coly1, coly1, &min, &max); NUMmatrix_extrema (my data, 1, ny, coly2, coly2, &ymin, &ymax); if (min < ymin) { ymin = min; } if (max > ymax) { ymax = max; } } if (xmin == xmax) { if (ymin == ymax) { return; } xmin -= 0.5; xmax += 0.5; } if (ymin == ymax) { ymin -= 0.5; ymax += 0.5; } Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_setInner (g); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); if (labelsize > 0) { Graphics_setFontSize (g, labelsize); } for (long i = 1; i <= ny; i++) { double x1 = my data[i][colx1]; double y1 = my data[i][coly1]; double x2 = my data[i][colx2]; double y2 = my data[i][coly2]; const char32 *mark = EMPTY_STRING (my rowLabels[i]) ? U"" : my rowLabels[i]; if (vectype == Graphics_LINE) { Graphics_line (g, x1, y1, x2, y2); } else if (vectype == Graphics_TWOWAYARROW) { Graphics_arrow (g, x1, y1, x2, y2); Graphics_arrow (g, x2, y2, x1, y1); } else { /*if (vectype == Graphics_ARROW) */ Graphics_arrow (g, x1, y1, x2, y2); } if (labelsize > 0) { Graphics_text (g, x1, y1, mark); } } if (labelsize > 0) { Graphics_setFontSize (g, fontsize); } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksLeft (g, 2, true, true, false); Graphics_marksBottom (g, 2, true, true, false); } } void TableOfReal_drawColumnAsDistribution (TableOfReal me, Graphics g, int column, double minimum, double maximum, long nBins, double freqMin, double freqMax, int cumulative, int garnish) { if (column < 1 || column > my numberOfColumns) { return; } autoMatrix thee = TableOfReal_to_Matrix (me); Matrix_drawDistribution (thee.peek(), g, column - 0.5, column + 0.5, 0.0, 0.0, minimum, maximum, nBins, freqMin, freqMax, cumulative, garnish); if (garnish && my columnLabels[column] != 0) { Graphics_textBottom (g, true, my columnLabels[column]); } } TableOfReal TableOfReal_sortRowsByIndex (TableOfReal me, long *index, int reverse) { try { if (my rowLabels == 0) { Melder_throw (U"No labels to sort"); } double min, max; NUMvector_extrema (index, 1, my numberOfRows, &min, &max); if (min < 1 || max > my numberOfRows) { Melder_throw (U"One or more indices out of range [1, ", my numberOfRows, U"]."); } autoTableOfReal thee = TableOfReal_create (my numberOfRows, my numberOfColumns); for (long i = 1; i <= my numberOfRows; i++) { long myindex = reverse ? i : index[i]; long thyindex = reverse ? index[i] : i; const char32 *mylabel = my rowLabels[myindex]; double *mydata = my data[myindex]; double *thydata = thy data[thyindex]; // Copy the row label thy rowLabels[i] = Melder_dup (mylabel); // Copy the row values for (long j = 1; j <= my numberOfColumns; j++) { thydata[j] = mydata[j]; } } // Copy column labels. NUMstrings_copyElements (my columnLabels, thy columnLabels, 1, my numberOfColumns); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not sorted by row index."); } } long *TableOfReal_getSortedIndexFromRowLabels (TableOfReal me) { try { autoNUMvector index (1, my numberOfRows); NUMindexx_s (my rowLabels, my numberOfRows, index.peek()); return index.transfer(); } catch (MelderError) { Melder_throw (me, U": no sorted index created."); } } TableOfReal TableOfReal_sortOnlyByRowLabels (TableOfReal me) { try { autoPermutation index = TableOfReal_to_Permutation_sortRowLabels (me); autoTableOfReal thee = TableOfReal_and_Permutation_permuteRows (me, index.peek()); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not sorted by row labels."); } } static void NUMmedianizeColumns (double **a, long rb, long re, long cb, long ce) { long n = re - rb + 1; if (n < 2) { return; } autoNUMvector tmp (1, n); for (long j = cb; j <= ce; j++) { long k = 1; for (long i = rb; i <= re; i++, k++) { tmp[k] = a[i][j]; } NUMsort_d (n, tmp.peek()); double median = NUMquantile (n, tmp.peek(), 0.5); for (long i = rb; i <= re; i++) { a[i][j] = median; } } } static void NUMstatsColumns (double **a, long rb, long re, long cb, long ce, int stats) { if (stats == 0) { NUMaverageColumns (a, rb, re, cb, ce); } else { NUMmedianizeColumns (a, rb, re, cb, ce); } } TableOfReal TableOfReal_meansByRowLabels (TableOfReal me, int expand, int stats) { try { autoTableOfReal thee; autoNUMvector index (TableOfReal_getSortedIndexFromRowLabels (me), 1); autoTableOfReal sorted = TableOfReal_sortRowsByIndex (me, index.peek(), 0); long indexi = 1, indexr = 0; const char32 *label = sorted -> rowLabels[1]; for (long i = 2; i <= my numberOfRows; i++) { const char32 *li = sorted -> rowLabels[i]; if (Melder_cmp (li, label) != 0) { NUMstatsColumns (sorted -> data, indexi, i - 1, 1, my numberOfColumns, stats); if (expand == 0) { indexr++; TableOfReal_copyOneRowWithLabel (sorted.peek(), sorted.peek(), indexi, indexr); } label = li; indexi = i; } } NUMstatsColumns (sorted -> data, indexi, my numberOfRows, 1, my numberOfColumns, stats); if (expand != 0) { // Now invert the table. char32 **tmp = sorted -> rowLabels; sorted -> rowLabels = my rowLabels; thee.reset (TableOfReal_sortRowsByIndex (sorted.peek(), index.peek(), 1)); sorted -> rowLabels = tmp; } else { indexr++; TableOfReal_copyOneRowWithLabel (sorted.peek(), sorted.peek(), indexi, indexr); thee.reset (TableOfReal_create (indexr, my numberOfColumns)); for (long i = 1; i <= indexr; i++) { TableOfReal_copyOneRowWithLabel (sorted.peek(), thee.peek(), i, i); } NUMstrings_copyElements (sorted -> columnLabels, thy columnLabels, 1, my numberOfColumns); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": means by row labels not created."); } } TableOfReal TableOfReal_rankColumns (TableOfReal me) { try { autoTableOfReal thee = Data_copy (me); NUMrankColumns (thy data, 1, thy numberOfRows, 1, thy numberOfColumns); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": column ranks not created."); } } void TableOfReal_setSequentialColumnLabels (TableOfReal me, long from, long to, const char32 *precursor, long number, long increment) { if (from == 0) { from = 1; } if (to == 0) { to = my numberOfColumns; } if (from < 1 || from > my numberOfColumns || to < from || to > my numberOfColumns) { Melder_throw (U"Wrong column indices."); } NUMstrings_setSequentialNumbering (my columnLabels, from, to, precursor, number, increment, (int) 0); } void TableOfReal_setSequentialRowLabels (TableOfReal me, long from, long to, const char32 *precursor, long number, long increment) { if (from == 0) { from = 1; } if (to == 0) { to = my numberOfRows; } if (from < 1 || from > my numberOfRows || to < from || to > my numberOfRows) { Melder_throw (U"Wrong row indices."); } NUMstrings_setSequentialNumbering (my rowLabels, from, to, precursor, number, increment, (int) 0); } /* For the inheritors */ TableOfReal TableOfReal_to_TableOfReal (TableOfReal me) { try { autoTableOfReal thee = TableOfReal_create (my numberOfRows, my numberOfColumns); NUMmatrix_copyElements (my data, thy data, 1, my numberOfRows, 1, my numberOfColumns); TableOfReal_copyLabels (me, thee.peek(), 1, 1); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not copied."); } } TableOfReal TableOfReal_choleskyDecomposition (TableOfReal me, int upper, int inverse) { try { char diag = 'N'; long n = my numberOfColumns, lda = my numberOfRows, info; if (n != lda) { Melder_throw (U"The table must be a square symmetric table."); } autoTableOfReal thee = Data_copy (me); if (upper) { for (long i = 2; i <= n; i++) for (long j = 1; j < i; j++) { thy data[i][j] = 0.0; } } else { for (long i = 1; i < n; i++) for (long j = i + 1; j <= n; j++) { thy data[i][j] = 0.0; } } char uplo = upper ? 'L' : 'U'; NUMlapack_dpotf2 (&uplo, &n, &thy data[1][1], &lda, &info); if (info != 0) { Melder_throw (U"dpotf2 fails"); } if (inverse) { NUMlapack_dtrtri (&uplo, &diag, &n, &thy data[1][1], &lda, &info); if (info != 0) { Melder_throw (U"dtrtri fails"); } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": Cholesky decomposition not performed."); } } TableOfReal TableOfReal_appendColumns (TableOfReal me, TableOfReal thee) { try { long ncols = my numberOfColumns + thy numberOfColumns; long labeldiffs = 0; if (my numberOfRows != thy numberOfRows) { Melder_throw (U"Number of rows must be equal."); } /* Stricter label checking??? append only if (my rowLabels[i] == thy rowlabels[i], i=1..my numberOfRows) or (my rowLabels[i] == 'empty', i=1..my numberOfRows) or (thy rowLabels[i] == 'empty', i=1..my numberOfRows); 'empty': nullptr or \w* */ autoTableOfReal him = TableOfReal_create (my numberOfRows, ncols); NUMstrings_copyElements (my rowLabels, his rowLabels, 1, my numberOfRows); NUMstrings_copyElements (my columnLabels, his columnLabels, 1, my numberOfColumns); NUMstrings_copyElements (thy columnLabels, &his columnLabels[my numberOfColumns], 1, thy numberOfColumns); for (long i = 1; i <= my numberOfRows; i++) { if (Melder_cmp (my rowLabels[i], thy rowLabels[i]) != 0) { labeldiffs++; } NUMvector_copyElements (my data[i], his data[i], 1, my numberOfColumns); NUMvector_copyElements (thy data[i], &his data[i][my numberOfColumns], 1, thy numberOfColumns); } if (labeldiffs > 0) { Melder_warning (labeldiffs, U" row labels differed."); } return him.transfer(); } catch (MelderError) { Melder_throw (U"TableOfReal with appended columns not created."); } } TableOfReal TableOfReal_appendColumnsMany (Collection me) { try { if (my size == 0) { Melder_throw (U"No tables selected."); } TableOfReal thee = (TableOfReal) my item [1]; long nrow = thy numberOfRows; long ncol = thy numberOfColumns; for (long itab = 2; itab <= my size; itab++) { thee = (TableOfReal) my item [itab]; ncol += thy numberOfColumns; if (thy numberOfRows != nrow) { Melder_throw (U"Numbers of rows in item ", itab, U" differs from previous."); } } autoTableOfReal him = TableOfReal_create (nrow, ncol); /* Unsafe: new attributes not initialized. */ for (long irow = 1; irow <= nrow; irow++) { TableOfReal_setRowLabel (him.peek(), irow, thy rowLabels [irow]); } ncol = 0; for (long itab = 1; itab <= my size; itab++) { thee = (TableOfReal) my item [itab]; for (long icol = 1; icol <= thy numberOfColumns; icol++) { ncol++; TableOfReal_setColumnLabel (him.peek(), ncol, thy columnLabels [icol]); for (long irow = 1; irow <= nrow; irow++) { his data[irow][ncol] = thy data[irow][icol]; } } } Melder_assert (ncol == his numberOfColumns); return him.transfer(); } catch (MelderError) { Melder_throw (U"TableOfReal with appended columns not created."); } } double TableOfReal_normalityTest_BHEP (TableOfReal me, double *h, double *tnb, double *lnmu, double *lnvar) { try { long n = my numberOfRows, p = my numberOfColumns; double beta = *h > 0 ? NUMsqrt1_2 / *h : NUMsqrt1_2 * pow ( (1.0 + 2 * p) / 4, 1.0 / (p + 4)) * pow (n, 1.0 / (p + 4)); double p2 = p / 2.0; double beta2 = beta * beta, beta4 = beta2 * beta2, beta8 = beta4 * beta4; double gamma = 1 + 2 * beta2, gamma2 = gamma * gamma, gamma4 = gamma2 * gamma2; double delta = 1.0 + beta2 * (4 + 3 * beta2), delta2 = delta * delta; double prob = NUMundefined; if (*h <= 0) { *h = NUMsqrt1_2 / beta; } *tnb = *lnmu = *lnvar = NUMundefined; if (n < 2 || p < 1) { return NUMundefined; } autoCovariance thee = TableOfReal_to_Covariance (me); try { SSCP_expandLowerCholesky (thee.peek()); } catch (MelderError) { *tnb = 4 * n; } { double djk, djj, sumjk = 0.0, sumj = 0.0; double b1 = beta2 / 2.0, b2 = b1 / (1.0 + beta2); /* Heinze & Wagner (1997), page 3 We use d[j][k] = ||Y[j]-Y[k]||^2 = (Y[j]-Y[k])'S^(-1)(Y[j]-Y[k]) So d[j][k]= d[k][j] and d[j][j] = 0 */ for (long j = 1; j <= n; j++) { for (long k = 1; k < j; k++) { djk = NUMmahalanobisDistance_chi (thy lowerCholesky, my data[j], my data[k], p, p); sumjk += 2.0 * exp (-b1 * djk); // factor 2 because d[j][k] == d[k][j] } sumjk += 1; // for k == j djj = NUMmahalanobisDistance_chi (thy lowerCholesky, my data[j], thy centroid, p, p); sumj += exp (-b2 * djj); } *tnb = (1.0 / n) * sumjk - 2.0 * pow (1.0 + beta2, - p2) * sumj + n * pow (gamma, - p2); // n * } double mu = 1.0 - pow (gamma, -p2) * (1.0 + p * beta2 / gamma + p * (p + 2) * beta4 / (2.0 * gamma2)); double var = 2.0 * pow (1 + 4 * beta2, -p2) + 2.0 * pow (gamma, -p) * (1.0 + 2 * p * beta4 / gamma2 + 3 * p * (p + 2) * beta8 / (4.0 * gamma4)) - 4.0 * pow (delta, -p2) * (1.0 + 3 * p * beta4 / (2 * delta) + p * (p + 2) * beta8 / (2.0 * delta2)); double mu2 = mu * mu; *lnmu = 0.5 * log (mu2 * mu2 / (mu2 + var)); //log (sqrt (mu2 * mu2 /(mu2 + var))); *lnvar = sqrt (log ( (mu2 + var) / mu2)); prob = NUMlogNormalQ (*tnb, *lnmu, *lnvar); return prob; } catch (MelderError) { Melder_throw (me, U": cannot determine normality."); } } TableOfReal TableOfReal_and_TableOfReal_crossCorrelations (TableOfReal me, TableOfReal thee, int by_columns, int center, int normalize) { return by_columns ? TableOfReal_and_TableOfReal_columnCorrelations (me, thee, center, normalize) : TableOfReal_and_TableOfReal_rowCorrelations (me, thee, center, normalize); } TableOfReal TableOfReal_and_TableOfReal_rowCorrelations (TableOfReal me, TableOfReal thee, int center, int normalize) { try { if (my numberOfColumns != thy numberOfColumns) { Melder_throw (U"Both tables must have the same number of columns."); } autoTableOfReal him = TableOfReal_create (my numberOfRows, thy numberOfRows); autoNUMmatrix my_data (NUMmatrix_copy (my data, 1, my numberOfRows, 1, my numberOfColumns), 1, 1); autoNUMmatrix thy_data (NUMmatrix_copy (thy data, 1, thy numberOfRows, 1, thy numberOfColumns), 1, 1); if (center) { NUMcentreRows (my_data.peek(), 1, my numberOfRows, 1, my numberOfColumns); NUMcentreRows (thy_data.peek(), 1, thy numberOfRows, 1, thy numberOfColumns); } if (normalize) { NUMnormalizeRows (my_data.peek(), my numberOfRows, my numberOfColumns, 1); NUMnormalizeRows (thy_data.peek(), thy numberOfRows, thy numberOfColumns, 1); } NUMstrings_copyElements (my rowLabels, his rowLabels, 1, his numberOfRows); NUMstrings_copyElements (thy rowLabels, his columnLabels, 1, his numberOfColumns); for (long i = 1; i <= my numberOfRows; i++) { for (long k = 1; k <= thy numberOfRows; k++) { double ctmp = 0; for (long j = 1; j <= my numberOfColumns; j++) { ctmp += my_data[i][j] * thy_data[k][j]; } his data[i][k] = ctmp; } } return him.transfer(); } catch (MelderError) { Melder_throw (U"TableOfReal with row correlations not created."); } } TableOfReal TableOfReal_and_TableOfReal_columnCorrelations (TableOfReal me, TableOfReal thee, int center, int normalize) { try { if (my numberOfRows != thy numberOfRows) { Melder_throw (U"Both tables must have the same number of rows."); } autoTableOfReal him = TableOfReal_create (my numberOfColumns, thy numberOfColumns); autoNUMmatrix my_data (NUMmatrix_copy (my data, 1, my numberOfRows, 1, my numberOfColumns), 1, 1); autoNUMmatrix thy_data (NUMmatrix_copy (thy data, 1, thy numberOfRows, 1, thy numberOfColumns), 1, 1); if (center) { NUMcentreColumns (my_data.peek(), 1, my numberOfRows, 1, my numberOfColumns, nullptr); NUMcentreColumns (thy_data.peek(), 1, thy numberOfRows, 1, thy numberOfColumns, nullptr); } if (normalize) { NUMnormalizeColumns (my_data.peek(), my numberOfRows, my numberOfColumns, 1); NUMnormalizeColumns (thy_data.peek(), thy numberOfRows, thy numberOfColumns, 1); } NUMstrings_copyElements (my columnLabels, his rowLabels, 1, his numberOfRows); NUMstrings_copyElements (thy columnLabels, his columnLabels, 1, his numberOfColumns); for (long j = 1; j <= my numberOfColumns; j++) { for (long k = 1; k <= thy numberOfColumns; k++) { double ctmp = 0.0; for (long i = 1; i <= my numberOfRows; i++) { ctmp += my_data[i][j] * thy_data[i][k]; } his data[j][k] = ctmp; } } return him.transfer(); } catch (MelderError) { Melder_throw (U"TableOfReal with column correlations not created."); } } #undef EMPTY_STRING #undef MAX #undef MIN /* End of file TableOfReal_extensions.c 1869*/ praat-6.0.04/dwtools/TableOfReal_extensions.h000066400000000000000000000205161261542461700211670ustar00rootroot00000000000000#ifndef _TableOfReal_extensions_h_ #define _TableOfReal_extensions_h_ /* TableOfReal_extensions.h * * Copyright (C) 1993-2012, 2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020411 initial GPL djmw 20120914 Latest modification. */ #include "TableOfReal.h" #include "Collection.h" #include "Pattern.h" #include "Categories.h" #include "Strings_.h" #include "SSCP.h" int TableOfReal_to_Pattern_and_Categories(TableOfReal me, long fromrow, long torow, long fromcol, long tocol, Pattern *p, Categories *c); TableOfReal TableOfReal_transpose (TableOfReal me); Strings TableOfReal_extractRowLabels (TableOfReal me); Strings TableOfReal_extractColumnLabels (TableOfReal me); void TableOfReal_and_Categories_setRowLabels (TableOfReal me, Categories thee); /* !!! Set rowlabels from categories Because we need a Table-object with string-columns. */ TableOfReal TableOfReal_sortOnlyByRowLabels (TableOfReal me); long *TableOfReal_getSortedIndexFromRowLabels (TableOfReal me); TableOfReal TableOfReal_sortRowsByIndex (TableOfReal me, long *index, int reverse); /* thy data[reverse ? i : index[i]][j] = my data[reverse ? index[i] : i] */ TableOfReal TableOfReal_createIrisDataset (); int TableOfReal_areAllCellsDefined (TableOfReal me, long rb, long re, long cb, long ce); TableOfReal TableOfReal_createFromPolsData_50males (int include_levels); TableOfReal TableOfReal_createFromVanNieropData_25females (int include_levels); TableOfReal TableOfReal_createFromWeeninkData (int option); /* M W C */ void TableOfReal_getColumnExtrema (TableOfReal me, long col, double *min, double *max); long TableOfReal_getColumnIndexAtMaximumInRow (TableOfReal me, long rowNumber); const char32 *TableOfReal_getColumnLabelAtMaximumInRow (TableOfReal me, long rowNumber); void TableOfReal_drawRowsAsHistogram (TableOfReal me, Graphics g, const char32 *rows, long colb, long cole, double ymin, double ymax, double xoffsetFraction, double interbarFraction, double interbarsFraction, const char32 *greys, int garnish); void TableOfReal_drawScatterPlot (TableOfReal me, Graphics g, long icx, long icy, long rowb, long rowe, double xmin, double xmax, double ymin, double ymax, int labelSize, int useRowLabels, const char32 *label, int garnish); void TableOfReal_drawAsSquares_area (TableOfReal me, Graphics g, double zmin, double zmax, double cellSizeFactor, int randomFillOrder, int garnish); void TableOfReal_drawScatterPlotMatrix (TableOfReal me, Graphics g, long colb, long cole, double fractionWhite); void TableOfReal_drawBoxPlots (TableOfReal me, Graphics g, long rowmin, long rowmax, long colmin, long colmax, double ymin, double ymax, int garnish); void TableOfReal_drawVectors (TableOfReal me, Graphics g, long colx1, long coly1, long colx2, long coly2, double xmin, double xmax, double ymin, double ymax, int vectype, int labelsize, int garnish); void TableOfReal_drawBiplot (TableOfReal me, Graphics g, double xmin, double xmax, double ymin, double ymax, double sv_splitfactor, int labelsize, int garnish); void TableOfReal_drawColumnAsDistribution (TableOfReal me, Graphics g, int column, double minimum, double maximum, long nBins, double freqMin, double freqMax, int cumulative, int garnish); long TableOfReal_getNumberOfLabelMatches (TableOfReal me, const char32 *search, int columnLabels, int use_regexp); /* Find number of labels that match search description. */ int TableOfReal_equalLabels (TableOfReal me, TableOfReal thee, int rowLabels, int columnLabels); /* return 1 when labels are equal else 0 */ void TableOfReal_copyLabels (TableOfReal me, TableOfReal thee, int rowOrigin, int columnOrigin); /* rowOrigin == 1 copy from row rowOrigin == 0 do nothing rowOrigin == -1 copy from column columnOrigin == 1 copy from column columnOrigin == 0 do nothing columnOrigin == -1 copy from row */ void TableOfReal_labelsFromCollectionItemNames (TableOfReal me, Collection thee, int row, int column); void TableOfReal_setSequentialColumnLabels (TableOfReal me, long from, long to, const char32 *precursor, long number, long increment); void TableOfReal_setSequentialRowLabels (TableOfReal me, long from, long to, const char32 *precursor, long number, long increment); int TableOfReal_hasRowLabels (TableOfReal me); int TableOfReal_hasColumnLabels (TableOfReal me); void TableOfReal_changeRowLabels (TableOfReal me, const char32 *search, const char32 *replace, int maximumNumberOfReplaces, long *nmatches, long *nstringmatches, int use_regexp); void TableOfReal_changeColumnLabels (TableOfReal me, const char32 *search, const char32 *replace, int maximumNumberOfReplaces, long *nmatches, long *nstringmatches, int use_regexp); /* Change all row/column labels. The 'search' and 'replace' string are interpreted as regular expressions when 'use_regexp' != 0. 'maximumNumberOfReplaces' is the maximum number of replaces in EACH string in the array of strings (you can replace ALL occurrences by making this number <= 0) The totalnumber of matches found is returned in 'nmatches'. The number of strings with at least one match is returned in 'nstringmatches'. */ void TableOfReal_centreColumns (TableOfReal me); void TableOfReal_centreColumns_byRowLabel (TableOfReal me); /* PRECONDITION: Table must be sorted by row labels !! */ double TableOfReal_getColumnQuantile (TableOfReal me, long col, double quantile); double TableOfReal_getRowSumByLabel (TableOfReal me, const char32 *label); double TableOfReal_getRowSum (TableOfReal me, long index); double TableOfReal_getColumnSumByLabel (TableOfReal me, const char32 *label); double TableOfReal_getColumnSum (TableOfReal me, long index); double TableOfReal_getGrandSum (TableOfReal me); void TableOfReal_centreRows (TableOfReal me); void TableOfReal_doubleCentre (TableOfReal me); int TableOfReal_checkPositive (TableOfReal me); double TableOfReal_getTableNorm (TableOfReal me); void TableOfReal_normalizeTable (TableOfReal me, double norm); void TableOfReal_normalizeColumns (TableOfReal me, double norm); void TableOfReal_normalizeRows (TableOfReal me, double norm); void TableOfReal_standardizeColumns (TableOfReal me); void TableOfReal_standardizeRows (TableOfReal me); TableOfReal TableOfReal_rankColumns (TableOfReal me); TableOfReal TableOfReal_meansByRowLabels (TableOfReal me, int expand, int stats); /* stats == 0? averages : medians For a table with n rows and m different labels (m <= n): if (expand=1) { output has n rows, substitute each array by the average value for that row label} else output a table with m rows, the averages for the m labels. */ TableOfReal TableOfReal_bootstrap (TableOfReal me); /* Produce new table with the same number of entries, but randomly selected with replacement. */ TableOfReal TableOfReal_randomizeRows (TableOfReal me); /* Produce new table with randomized rows */ /* For the inheritors */ TableOfReal TableOfReal_to_TableOfReal (TableOfReal me); TableOfReal TableOfReal_choleskyDecomposition (TableOfReal me, int upper, int inverse); TableOfReal TableOfReal_appendColumns (TableOfReal me, TableOfReal thee); TableOfReal TableOfReal_appendColumnsMany (Collection me); void TableOfReal_copyOneRowWithLabel (TableOfReal me, TableOfReal thee, long myrow, long thyrow); double TableOfReal_normalityTest_BHEP (TableOfReal me, double *beta, double *tnb, double *lnmu, double *lnvar); TableOfReal TableOfReal_and_TableOfReal_crossCorrelations (TableOfReal me, TableOfReal thee, int by_columns, int center, int normalize); /********************* class TablesOfReal ******************************/ Thing_define (TablesOfReal, Ordered) { }; void TablesOfReal_init (TablesOfReal me, ClassInfo klas); TablesOfReal TablesOfReal_create (); TableOfReal TablesOfReal_sum (TablesOfReal me); int TablesOfReal_checkDimensions (TablesOfReal me); #endif /* _TableOfReal_extensions_h_ */ praat-6.0.04/dwtools/Table_extensions.cpp000066400000000000000000005130451261542461700204350ustar00rootroot00000000000000/* Table_extensions.cpp * * Copyright (C) 1997-2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020619 GPL header djmw 20040113 Added comment header for Peterson&Barney data. djmw 20040512 Corrected Peterson&Barney ARPABET-labeling. djmw 20041213 Added Table_createFromWeeninkData. djmw 20080125 Corrected mislabeling of vowels in the Peterson&Barney dataset according to Watrous djmw 20080508 Labeling back to original PB article. djmw 20110329 Table_get(Numeric|String)Value is now Table_get(Numeric|String)Value_Assert djmw 20131219 Improved Table_scatterPlotWithConfidenceIntervals */ /* speaker type (m|w|c), sex(m|f), id, vowel_number, vowel_label F0, F1, F2, F3 */ #include "Discriminant.h" #include "Formula.h" #include "GraphicsP.h" #include "Graphics_extensions.h" #include "Index.h" #include "Matrix_extensions.h" #include "NUM2.h" #include #include "Strings_extensions.h" #include "SSCP.h" #include "Table_extensions.h" static bool Table_selectedColumnPartIsNumeric (Table me, long column, long *selectedRows, long numberOfSelectedRows) { if (column < 1 || column > my numberOfColumns) return false; for (long irow = 1; irow <= numberOfSelectedRows; irow++) { if (! Table_isCellNumeric_ErrorFalse (me, selectedRows[irow], column)) return false; } return true; } // column and selectedRows are valid; *min & *max must be intialized static void Table_columnExtremesFromSelectedRows (Table me, long column, long *selectedRows, long numberOfSelectedRows, double *min, double *max) { double cmin = 1e308, cmax = - cmin; for (long irow = 1; irow <= numberOfSelectedRows; irow++) { double val = Table_getNumericValue_Assert (me, selectedRows[irow], column); if (val < cmin) { cmin = val; } if (val > cmax) { cmax = val; } } *min = cmin; *max = cmax; } /* The Peterson & Barney data were once (1991) obtained by me (djmw) as a compressed tar-file by anonymous ftp from ftp://linc.cis.upenn.edu/pub, However, this site appears no longer to be an anonymous ftp site. The compressed tar file contained two files: a header file 'pb.header' and a data file 'verified_pb.data'. The header file reads: "This file contains the vowel formant data reported by Gordon E. Peterson and Harold L. Barney in their classic paper, "Control methods used in a study of the vowels", JASA 24(2) 175-184, 1952. This data was supplied in printed form by Ignatius Mattingly, April, 1990. The data consists of the formant values F0, F1, F2, and F3 for each of two repetitions of ten vowels by 76 speakers (1520 utterances). The vowels were pronounced in isolated words consisting of hVd. Of the speakers, 33 were men, 28 were women and 15 were children. Dr. Mattingly reported that he obtained from G. Peterson the information that children speakers 62, 63, 65, 66, 67, 68, 73 and 76 were female. The data are organized by speaker type, speaker, and vowel into 1520 lines of 8 fields. The fields are: Speaker Type, Speaker Number, Phoneme Number, Phoneme Label, F0, F1, F2 and F3. The speaker types are type 1 (men), type 2 (women) and type 3 (children)." */ Table Table_createFromPetersonBarneyData () { long nrows = 1520, ncols = 9; const char32 *columnLabels[9] = {U"Type", U"Sex", U"Speaker", U"Vowel", U"IPA", U"F0", U"F1", U"F2", U"F3"}; const char32 *type[3] = {U"m", U"w", U"c"}; // Wrong order before 20080125 // char32 *vowel[10] = {U"iy", U"ih", U"eh", U"ae", U"aa", U"ao", U"uh", U"uw", U"ah", U"er"}; // char32 *ipa[10] = {U"i", U"\\ic", U"\\ep", U"\\ae", U"\\as", U"\\ct", U"\\hs", U"u", // U"\\vt", U"\\er\\hr"}; const char32 *vowel[10] = {U"iy", U"ih", U"eh", U"ae", U"ah", U"aa", U"ao", U"uh", U"uw", U"er"}; // Watrous IPA symbols // char32 *ipa[10] = {U"i", U"\\ic", U"e", U"\\ae", U"\\vt", U"\\as", U"o", U"\\hs", U"u", U"\\er"}; // P&B IPA symbols const char32 *ipa[10] = {U"i", U"\\ic", U"\\ef", U"\\ae", U"\\vt", U"\\as", U"\\ct", U"\\hs", U"u", U"\\er\\hr"}; const char32 *sex[2] = {U"m", U"f"}; struct pbdatum { short star; /* was there a * in front of the vowel-type? */ short f[4]; /* f0, f1, f2, f3 */ } pbdata [] = { {0, {160, 240, 2280, 2850}}, {0, {186, 280, 2400, 2790}}, {0, {203, 390, 2030, 2640}}, {0, {192, 310, 1980, 2550}}, {0, {161, 490, 1870, 2420}}, {1, {155, 570, 1700, 2600}}, {1, {140, 560, 1820, 2660}}, {0, {180, 630, 1700, 2550}}, {0, {144, 590, 1250, 2620}}, {0, {148, 620, 1300, 2530}}, {0, {148, 740, 1070, 2490}}, {0, {170, 800, 1060, 2640}}, {1, {161, 600, 970, 2280}}, {1, {158, 660, 980, 2220}}, {0, {163, 440, 1120, 2210}}, {0, {190, 400, 1070, 2280}}, {0, {160, 240, 1040, 2150}}, {0, {157, 270, 930, 2280}}, {0, {177, 370, 1520, 1670}}, {0, {164, 460, 1330, 1590}}, {0, {147, 220, 2220, 2910}}, {0, {148, 210, 2360, 3250}}, {0, {141, 410, 1890, 2680}}, {0, {139, 420, 1850, 2500}}, {0, {136, 500, 1760, 2590}}, {1, {135, 510, 1710, 2380}}, {0, {128, 690, 1610, 2560}}, {0, {131, 700, 1690, 2580}}, {1, {140, 650, 1080, 2420}}, {1, {125, 625, 1060, 2490}}, {0, {140, 650, 1040, 2450}}, {0, {136, 670, 1100, 2430}}, {0, {149, 580, 580, 2470}}, {0, {140, 560, 560, 2410}}, {0, {145, 450, 940, 1910}}, {0, {141, 410, 830, 2240}}, {0, {140, 280, 650, 3300}}, {0, {137, 260, 660, 3300}}, {0, {145, 510, 1210, 1570}}, {0, {145, 510, 1130, 1510}}, {0, {105, 250, 2180, 2680}}, {0, {111, 244, 2300, 2780}}, {0, {100, 400, 1930, 2610}}, {0, {104, 400, 1990, 2700}}, {0, {100, 550, 1810, 2500}}, {0, {95, 540, 1810, 2480}}, {0, {93, 630, 1710, 2400}}, {0, {94, 658, 1755, 2305}}, {1, {100, 600, 1200, 2320}}, {0, {105, 612, 1160, 2350}}, {0, {91, 640, 1080, 2140}}, {0, {94, 720, 1090, 2230}}, {0, {92, 550, 870, 2300}}, {0, {120, 540, 840, 2280}}, {0, {114, 460, 1150, 2290}}, {0, {114, 456, 1030, 2300}}, {0, {112, 340, 950, 2240}}, {1, {112, 326, 900, 2190}}, {0, {100, 500, 1370, 1780}}, {0, {106, 530, 1330, 1800}}, {0, {150, 300, 2240, 3400}}, {0, {156, 280, 2450, 3200}}, {1, {156, 450, 1960, 2400}}, {0, {146, 440, 2050, 2360}}, {0, {130, 570, 1780, 2410}}, {0, {150, 555, 1890, 2440}}, {0, {125, 750, 1610, 2340}}, {0, {136, 770, 1580, 2350}}, {0, {132, 660, 1200, 2330}}, {1, {150, 675, 1140, 2380}}, {0, {125, 750, 1100, 2550}}, {0, {138, 800, 1120, 2500}}, {0, {143, 540, 850, 2320}}, {0, {150, 555, 890, 2370}}, {0, {136, 460, 960, 2210}}, {0, {156, 460, 1000, 2350}}, {0, {140, 380, 950, 2050}}, {0, {148, 385, 850, 2330}}, {0, {150, 590, 1400, 1840}}, {0, {145, 555, 1430, 1730}}, {0, {140, 310, 2310, 2820}}, {0, {131, 260, 2250, 2850}}, {0, {137, 440, 2060, 2640}}, {0, {134, 430, 1880, 2450}}, {0, {140, 580, 1910, 2500}}, {0, {137, 550, 1770, 2400}}, {0, {143, 830, 1720, 2180}}, {0, {135, 750, 1690, 2320}}, {0, {136, 630, 1300, 1950}}, {0, {130, 650, 1170, 2000}}, {0, {131, 760, 1220, 2140}}, {1, {126, 720, 1260, 2020}}, {0, {136, 540, 970, 1980}}, {0, {124, 550, 880, 1950}}, {0, {133, 470, 1040, 1990}}, {0, {132, 490, 990, 1920}}, {0, {141, 380, 950, 2140}}, {0, {133, 330, 800, 2130}}, {0, {143, 560, 1510, 1800}}, {0, {136, 510, 1460, 1700}}, {0, {125, 312, 2350, 2800}}, {0, {119, 330, 2430, 2870}}, {0, {133, 420, 2000, 2660}}, {0, {125, 313, 2000, 2750}}, {0, {120, 600, 1860, 2500}}, {0, {114, 570, 1830, 2570}}, {0, {119, 676, 1670, 2540}}, {0, {125, 725, 1687, 2500}}, {1, {118, 680, 1150, 2560}}, {0, {125, 726, 1270, 2560}}, {0, {125, 740, 1100, 2680}}, {1, {113, 670, 960, 2650}}, {1, {120, 660, 1030, 2690}}, {1, {125, 720, 960, 2700}}, {0, {120, 456, 1080, 2520}}, {0, {120, 450, 1140, 2600}}, {0, {125, 313, 838, 2340}}, {0, {125, 288, 938, 2450}}, {0, {120, 503, 1305, 1775}}, {0, {120, 505, 1320, 1750}}, {0, {186, 320, 2320, 3120}}, {0, {172, 310, 2280, 3020}}, {1, {167, 470, 2000, 2660}}, {0, {170, 410, 2040, 2715}}, {1, {167, 630, 1900, 2860}}, {0, {146, 614, 1840, 2770}}, {0, {143, 740, 1800, 2450}}, {0, {162, 775, 1810, 2200}}, {1, {167, 620, 1240, 2410}}, {0, {160, 640, 1250, 2400}}, {1, {162, 650, 970, 2580}}, {0, {163, 650, 980, 2350}}, {0, {145, 430, 720, 2450}}, {0, {171, 510, 800, 2500}}, {1, {170, 460, 1120, 2150}}, {1, {170, 493, 1120, 2300}}, {0, {175, 380, 1040, 2260}}, {1, {200, 400, 1000, 2350}}, {0, {167, 570, 1300, 1750}}, {0, {157, 565, 1370, 1710}}, {1, {105, 230, 2480, 3200}}, {0, {109, 218, 2380, 3100}}, {1, {110, 320, 2200, 2680}}, {0, {103, 206, 2130, 2570}}, {1, {107, 430, 2100, 2630}}, {1, {105, 515, 1760, 2470}}, {1, {107, 514, 2060, 2600}}, {1, {106, 552, 1820, 2500}}, {0, {108, 640, 1300, 2300}}, {0, {104, 624, 1350, 2410}}, {1, {111, 714, 1170, 2420}}, {1, {97, 650, 1150, 2350}}, {1, {107, 590, 965, 2500}}, {0, {109, 578, 970, 2460}}, {0, {111, 467, 1110, 2400}}, {0, {105, 475, 1220, 2310}}, {0, {107, 270, 910, 2200}}, {0, {108, 260, 975, 2320}}, {0, {107, 460, 1400, 1790}}, {0, {103, 425, 1410, 1760}}, {0, {175, 316, 2200, 2800}}, {0, {175, 280, 2275, 2775}}, {0, {167, 450, 1820, 2475}}, {0, {167, 434, 1850, 2425}}, {0, {157, 582, 1725, 2375}}, {0, {158, 586, 1800, 2425}}, {0, {150, 600, 1750, 2375}}, {1, {145, 582, 1775, 2375}}, {1, {145, 626, 1125, 2200}}, {0, {160, 641, 1120, 2225}}, {0, {144, 708, 1054, 2420}}, {1, {150, 705, 1050, 2375}}, {0, {146, 614, 848, 2200}}, {0, {143, 600, 860, 2175}}, {0, {167, 500, 1000, 2325}}, {0, {167, 500, 1000, 2325}}, {0, {167, 334, 1150, 2200}}, {0, {183, 312, 1020, 2300}}, {0, {157, 518, 1305, 1570}}, {0, {157, 504, 1210, 1510}}, {0, {129, 260, 2260, 2820}}, {0, {125, 250, 2200, 2825}}, {0, {146, 400, 2040, 2500}}, {0, {144, 389, 2000, 2425}}, {0, {126, 500, 1870, 2500}}, {0, {125, 500, 1775, 2450}}, {0, {110, 660, 1650, 2500}}, {0, {120, 624, 1700, 2475}}, {0, {122, 650, 1220, 2550}}, {0, {120, 672, 1260, 2500}}, {0, {114, 750, 1080, 2680}}, {0, {114, 777, 1026, 2625}}, {0, {115, 580, 800, 2650}}, {0, {117, 585, 819, 2625}}, {1, {140, 480, 950, 2500}}, {0, {127, 461, 993, 2350}}, {0, {140, 280, 950, 2300}}, {0, {133, 266, 920, 2300}}, {0, {128, 500, 1340, 1700}}, {0, {133, 532, 1275, 1600}}, {0, {146, 248, 2225, 3100}}, {0, {140, 238, 2175, 3075}}, {0, {150, 405, 1925, 2550}}, {0, {138, 416, 1940, 2600}}, {1, {147, 588, 1790, 2500}}, {1, {133, 586, 1725, 2650}}, {0, {145, 725, 1700, 2425}}, {0, {127, 710, 1650, 2220}}, {1, {136, 586, 1078, 2300}}, {0, {136, 627, 1038, 2360}}, {1, {145, 725, 1046, 2325}}, {1, {131, 746, 1018, 2300}}, {0, {140, 560, 840, 2500}}, {1, {140, 560, 924, 2350}}, {0, {150, 495, 1080, 2275}}, {0, {143, 430, 1030, 2275}}, {0, {162, 290, 760, 2300}}, {0, {157, 315, 850, 2025}}, {0, {150, 511, 1561, 1876}}, {0, {138, 530, 1450, 1887}}, {0, {110, 220, 2410, 3000}}, {0, {125, 240, 2440, 3280}}, {0, {120, 450, 1880, 2450}}, {0, {118, 380, 1930, 2420}}, {0, {115, 560, 1650, 2300}}, {0, {123, 560, 1720, 2300}}, {0, {110, 680, 1720, 2330}}, {0, {133, 630, 1680, 2280}}, {1, {110, 560, 1430, 2250}}, {1, {120, 560, 1390, 2240}}, {1, {108, 800, 1330, 2260}}, {0, {110, 740, 1240, 2280}}, {1, {120, 600, 920, 2080}}, {1, {133, 580, 910, 2000}}, {0, {130, 400, 1200, 2210}}, {0, {110, 420, 1230, 2230}}, {0, {122, 300, 900, 2130}}, {0, {123, 260, 1010, 2240}}, {0, {125, 400, 1450, 1650}}, {0, {128, 360, 1410, 1640}}, {0, {142, 290, 2290, 2600}}, {0, {135, 260, 2290, 2700}}, {0, {132, 390, 1950, 2550}}, {1, {135, 400, 1900, 2450}}, {1, {124, 490, 1740, 2500}}, {1, {125, 500, 1780, 2430}}, {0, {125, 660, 1630, 2500}}, {0, {132, 670, 1630, 2380}}, {0, {140, 600, 1220, 2530}}, {0, {125, 600, 1210, 2430}}, {1, {125, 680, 1120, 2630}}, {0, {128, 670, 1100, 2700}}, {0, {127, 510, 720, 2450}}, {0, {120, 480, 710, 2540}}, {1, {133, 380, 910, 2350}}, {0, {140, 440, 1030, 2400}}, {0, {127, 350, 720, 2750}}, {0, {140, 380, 740, 2880}}, {0, {128, 430, 1370, 1610}}, {0, {135, 440, 1360, 1600}}, {0, {114, 228, 2350, 2860}}, {0, {118, 220, 2350, 2920}}, {1, {110, 407, 2070, 2500}}, {1, {112, 420, 1900, 2450}}, {0, {106, 445, 2020, 2420}}, {0, {115, 470, 2020, 2500}}, {0, {103, 721, 1680, 2400}}, {0, {109, 750, 1710, 2440}}, {1, {104, 552, 1122, 2500}}, {1, {115, 580, 1150, 2600}}, {0, {98, 686, 1078, 2570}}, {1, {103, 700, 1050, 2680}}, {0, {102, 560, 665, 2620}}, {0, {106, 550, 650, 2700}}, {0, {112, 448, 980, 2370}}, {0, {104, 410, 940, 2370}}, {0, {116, 232, 696, 2200}}, {0, {117, 222, 665, 2080}}, {0, {120, 432, 1300, 1400}}, {0, {111, 420, 1300, 1570}}, {0, {121, 230, 2100, 2850}}, {0, {118, 240, 2000, 2980}}, {0, {130, 365, 1900, 2340}}, {0, {119, 300, 2040, 2560}}, {1, {112, 440, 1980, 2310}}, {1, {120, 410, 2050, 2500}}, {1, {133, 620, 1710, 2110}}, {0, {124, 660, 1800, 2150}}, {0, {120, 660, 1000, 2380}}, {0, {110, 660, 960, 2450}}, {1, {122, 600, 830, 2250}}, {1, {119, 620, 820, 2400}}, {0, {117, 500, 620, 2250}}, {0, {106, 550, 700, 2550}}, {0, {140, 390, 730, 2180}}, {0, {130, 360, 740, 2200}}, {0, {131, 260, 720, 2100}}, {0, {132, 260, 740, 2040}}, {0, {125, 450, 1230, 1600}}, {0, {127, 460, 1300, 1650}}, {0, {150, 300, 2355, 3250}}, {0, {150, 300, 2460, 3280}}, {0, {160, 385, 2242, 2805}}, {0, {150, 407, 2250, 2780}}, {0, {140, 504, 2090, 2720}}, {0, {146, 543, 1980, 2640}}, {0, {133, 680, 1958, 2542}}, {0, {141, 708, 1840, 2535}}, {0, {150, 675, 1320, 2550}}, {0, {150, 704, 1393, 2550}}, {0, {137, 825, 1168, 2750}}, {0, {135, 840, 1210, 2680}}, {1, {143, 671, 1000, 2670}}, {1, {147, 690, 968, 2660}}, {0, {143, 443, 1273, 2430}}, {0, {153, 459, 1286, 2410}}, {0, {146, 395, 1300, 2160}}, {0, {153, 400, 1320, 2150}}, {0, {140, 532, 1500, 1890}}, {0, {146, 538, 1460, 1818}}, {0, {120, 264, 2290, 2700}}, {0, {128, 256, 2305, 2635}}, {0, {112, 380, 1880, 2440}}, {0, {115, 346, 1930, 2390}}, {0, {100, 510, 1780, 2300}}, {0, {108, 520, 1730, 2275}}, {0, {100, 630, 1770, 2350}}, {0, {105, 630, 1642, 2170}}, {0, {103, 601, 1273, 2130}}, {1, {105, 590, 1283, 2150}}, {1, {100, 750, 1150, 2440}}, {0, {95, 703, 1092, 2320}}, {0, {97, 565, 780, 2350}}, {0, {106, 584, 849, 2460}}, {0, {105, 420, 1100, 2140}}, {0, {111, 422, 1200, 2175}}, {0, {117, 315, 1080, 2260}}, {0, {125, 326, 1125, 2210}}, {0, {111, 444, 1300, 1625}}, {0, {109, 469, 1288, 1600}}, {0, {124, 210, 2100, 3090}}, {0, {130, 220, 2080, 3180}}, {0, {128, 280, 2000, 2710}}, {0, {130, 310, 1950, 2670}}, {0, {121, 470, 1910, 2580}}, {1, {129, 490, 1930, 2650}}, {0, {116, 640, 1620, 2200}}, {0, {118, 650, 1580, 2360}}, {0, {121, 610, 1100, 2230}}, {0, {126, 620, 1120, 2330}}, {1, {118, 700, 1100, 2240}}, {1, {120, 670, 1100, 2220}}, {0, {122, 460, 720, 2180}}, {0, {118, 470, 690, 2200}}, {0, {129, 320, 770, 1860}}, {1, {130, 310, 790, 1920}}, {0, {140, 210, 670, 1900}}, {0, {148, 240, 730, 1850}}, {0, {128, 390, 1320, 1550}}, {0, {124, 420, 1240, 1510}}, {0, {129, 190, 2650, 3280}}, {0, {135, 190, 2700, 3170}}, {0, {132, 370, 1750, 2700}}, {0, {130, 370, 1800, 2750}}, {1, {122, 370, 1680, 2560}}, {1, {125, 375, 1700, 2500}}, {1, {121, 550, 1570, 2600}}, {1, {120, 530, 1610, 2650}}, {1, {118, 570, 1050, 2500}}, {1, {125, 590, 1100, 2480}}, {1, {112, 640, 970, 2870}}, {1, {122, 670, 980, 2900}}, {1, {113, 560, 860, 2900}}, {0, {121, 570, 820, 2820}}, {1, {125, 350, 1000, 2500}}, {1, {130, 380, 920, 2370}}, {0, {130, 250, 1000, 2100}}, {0, {140, 210, 960, 1940}}, {0, {130, 360, 1300, 1920}}, {0, {133, 370, 1300, 1760}}, {0, {127, 250, 2180, 2660}}, {0, {131, 260, 2210, 2780}}, {0, {121, 400, 1900, 2440}}, {0, {122, 350, 1980, 2480}}, {1, {116, 560, 1670, 2310}}, {1, {124, 530, 1700, 2380}}, {0, {120, 680, 1470, 2280}}, {0, {119, 620, 1580, 2320}}, {0, {120, 620, 1100, 2390}}, {1, {125, 640, 1110, 2370}}, {1, {115, 630, 980, 2330}}, {1, {121, 670, 940, 2380}}, {0, {112, 560, 790, 2480}}, {0, {120, 610, 840, 2420}}, {0, {121, 360, 860, 2200}}, {0, {120, 400, 840, 2200}}, {0, {140, 280, 670, 2140}}, {0, {126, 250, 720, 2190}}, {0, {120, 480, 1410, 1760}}, {0, {121, 470, 1330, 1700}}, {0, {155, 280, 2400, 2910}}, {0, {150, 300, 2320, 2960}}, {1, {142, 410, 2060, 2680}}, {0, {150, 450, 2050, 2670}}, {0, {135, 540, 1900, 2530}}, {0, {135, 540, 1920, 2520}}, {0, {138, 620, 1800, 2440}}, {0, {140, 690, 1820, 2480}}, {1, {150, 630, 1200, 2600}}, {0, {140, 680, 1290, 2600}}, {0, {145, 740, 1110, 2500}}, {1, {143, 700, 1060, 2720}}, {1, {146, 600, 970, 2570}}, {0, {138, 650, 880, 2660}}, {0, {142, 430, 1130, 2440}}, {0, {143, 430, 1150, 2420}}, {0, {142, 280, 990, 2330}}, {0, {145, 290, 1000, 2300}}, {0, {150, 420, 1350, 1600}}, {0, {150, 450, 1350, 1600}}, {0, {135, 300, 2300, 2800}}, {0, {135, 350, 2240, 2760}}, {1, {136, 410, 2200, 2680}}, {1, {138, 440, 2080, 2520}}, {1, {133, 580, 1870, 2320}}, {1, {127, 520, 1900, 2400}}, {0, {130, 760, 1920, 2480}}, {0, {132, 670, 1850, 2560}}, {1, {139, 810, 1110, 2100}}, {1, {131, 770, 1150, 2100}}, {1, {141, 700, 1040, 2120}}, {0, {125, 750, 1160, 2080}}, {1, {133, 670, 920, 2240}}, {1, {142, 570, 850, 2250}}, {0, {140, 550, 970, 2200}}, {1, {141, 490, 870, 2240}}, {0, {150, 300, 600, 2300}}, {0, {148, 230, 570, 2100}}, {0, {140, 560, 1520, 2100}}, {0, {140, 540, 1570, 2050}}, {0, {125, 240, 2100, 2900}}, {0, {119, 240, 2150, 2860}}, {0, {130, 380, 1870, 2450}}, {0, {120, 430, 1710, 2350}}, {1, {119, 580, 1770, 2500}}, {1, {117, 570, 1750, 2400}}, {1, {115, 760, 1580, 2440}}, {0, {110, 715, 1500, 2300}}, {1, {124, 620, 880, 2500}}, {1, {124, 650, 1000, 2520}}, {0, {119, 710, 950, 2520}}, {1, {120, 690, 960, 2520}}, {0, {125, 460, 610, 2500}}, {0, {120, 470, 710, 2500}}, {0, {125, 390, 900, 2100}}, {0, {125, 460, 920, 2140}}, {0, {125, 250, 690, 2080}}, {0, {130, 270, 650, 2050}}, {0, {122, 540, 1280, 1720}}, {0, {118, 510, 1280, 1650}}, {0, {148, 280, 2450, 2700}}, {0, {160, 288, 2500, 2880}}, {0, {160, 400, 2080, 2530}}, {0, {153, 384, 2110, 2500}}, {1, {138, 590, 1900, 2200}}, {1, {153, 583, 1840, 2250}}, {0, {145, 680, 1850, 2400}}, {0, {140, 685, 1780, 2160}}, {0, {143, 660, 1370, 2110}}, {1, {145, 680, 1300, 2100}}, {1, {140, 760, 1260, 2120}}, {0, {135, 770, 1140, 2020}}, {0, {145, 500, 800, 1850}}, {0, {132, 600, 1000, 2000}}, {0, {157, 380, 1060, 1950}}, {0, {150, 470, 1220, 2150}}, {0, {162, 324, 800, 2220}}, {0, {139, 290, 800, 2150}}, {0, {150, 560, 1350, 1780}}, {0, {150, 600, 1470, 1820}}, {0, {110, 250, 2190, 3000}}, {0, {106, 254, 2085, 2890}}, {0, {111, 330, 1967, 2670}}, {0, {108, 430, 1940, 2590}}, {0, {116, 464, 2100, 2700}}, {0, {105, 504, 1995, 2780}}, {0, {94, 595, 1900, 2700}}, {0, {100, 670, 1860, 2500}}, {0, {96, 620, 1200, 2420}}, {0, {105, 630, 1127, 2420}}, {0, {100, 750, 1160, 2360}}, {0, {96, 740, 1155, 2330}}, {0, {101, 460, 740, 2300}}, {1, {105, 494, 789, 2420}}, {0, {113, 400, 1020, 2200}}, {0, {128, 450, 1028, 2160}}, {0, {140, 392, 1000, 2120}}, {0, {116, 350, 898, 2140}}, {0, {117, 547, 1340, 1688}}, {0, {128, 512, 1280, 1570}}, {0, {123, 246, 2185, 2730}}, {0, {133, 267, 2280, 2800}}, {0, {140, 420, 2300, 2800}}, {0, {120, 384, 2110, 2620}}, {0, {120, 480, 1920, 2540}}, {1, {112, 551, 1788, 2450}}, {0, {114, 628, 1837, 2570}}, {1, {111, 622, 1890, 2560}}, {0, {114, 628, 1254, 2470}}, {0, {114, 617, 1255, 2480}}, {1, {117, 690, 1072, 2660}}, {1, {103, 630, 1000, 2530}}, {0, {117, 510, 700, 2650}}, {0, {120, 504, 756, 2540}}, {0, {122, 465, 990, 2440}}, {0, {125, 462, 976, 2450}}, {0, {120, 324, 708, 2440}}, {0, {157, 387, 786, 2518}}, {0, {122, 488, 1468, 1712}}, {0, {118, 472, 1465, 1725}}, {0, {138, 275, 2060, 2800}}, {0, {136, 270, 2020, 2790}}, {0, {133, 349, 2030, 2760}}, {0, {136, 340, 1940, 2560}}, {1, {120, 444, 1800, 2500}}, {1, {127, 380, 1800, 2440}}, {0, {125, 688, 1600, 2300}}, {0, {122, 660, 1570, 2380}}, {1, {128, 565, 1157, 2310}}, {0, {130, 550, 1150, 2250}}, {0, {125, 712, 1024, 2250}}, {0, {125, 670, 1080, 2300}}, {0, {125, 550, 913, 2360}}, {0, {126, 550, 890, 2280}}, {0, {128, 360, 1028, 2160}}, {1, {140, 390, 1060, 2150}}, {0, {133, 294, 930, 2050}}, {0, {140, 280, 1000, 2160}}, {0, {125, 440, 1250, 1625}}, {0, {130, 480, 1160, 1520}}, {0, {125, 320, 2160, 2900}}, {0, {133, 267, 2230, 3000}}, {0, {115, 440, 1750, 2400}}, {0, {116, 390, 1780, 2450}}, {0, {117, 525, 1800, 2480}}, {0, {110, 520, 1750, 2390}}, {0, {111, 660, 1600, 2400}}, {0, {120, 720, 1680, 2430}}, {0, {117, 600, 1250, 2300}}, {1, {125, 575, 1170, 2240}}, {1, {111, 730, 1160, 2340}}, {0, {117, 860, 1280, 2470}}, {0, {114, 560, 810, 2290}}, {0, {116, 584, 840, 2280}}, {0, {130, 455, 970, 2140}}, {0, {120, 456, 1040, 2038}}, {0, {125, 350, 820, 2130}}, {0, {128, 366, 772, 2058}}, {1, {111, 450, 1420, 1870}}, {0, {118, 472, 1430, 1840}}, {0, {133, 333, 2305, 3200}}, {0, {131, 326, 2260, 3030}}, {1, {125, 375, 2188, 2750}}, {1, {133, 400, 2150, 2680}}, {1, {125, 500, 1980, 2480}}, {1, {150, 480, 1950, 2340}}, {0, {116, 640, 1710, 2450}}, {0, {123, 615, 1720, 2220}}, {0, {116, 583, 1110, 2360}}, {1, {117, 608, 1120, 2700}}, {0, {111, 777, 1170, 2600}}, {0, {114, 750, 1175, 2820}}, {1, {105, 630, 891, 2519}}, {1, {114, 572, 924, 2660}}, {0, {125, 438, 975, 2300}}, {0, {140, 420, 938, 2300}}, {0, {133, 333, 800, 2130}}, {0, {140, 320, 840, 2150}}, {0, {120, 480, 1320, 1870}}, {0, {127, 483, 1335, 1844}}, {0, {166, 267, 2300, 2940}}, {0, {156, 220, 2300, 2900}}, {0, {154, 431, 2040, 2460}}, {0, {155, 360, 2010, 2400}}, {1, {150, 565, 1950, 2500}}, {0, {180, 540, 2000, 2450}}, {1, {143, 600, 2000, 2570}}, {0, {138, 590, 1950, 2460}}, {1, {157, 630, 1140, 2200}}, {1, {186, 630, 1170, 2280}}, {1, {146, 730, 1048, 2450}}, {0, {155, 730, 1130, 2320}}, {1, {150, 600, 900, 2400}}, {1, {178, 640, 890, 2280}}, {1, {160, 448, 960, 2200}}, {0, {196, 450, 1000, 2180}}, {0, {167, 333, 835, 2170}}, {0, {198, 280, 750, 2170}}, {0, {163, 488, 1300, 1600}}, {0, {163, 490, 1380, 1620}}, {0, {120, 312, 2380, 2900}}, {0, {120, 300, 2350, 3000}}, {0, {140, 490, 2000, 2620}}, {1, {140, 490, 1960, 2600}}, {0, {125, 640, 2000, 2620}}, {0, {111, 555, 1870, 2540}}, {0, {112, 697, 1610, 2540}}, {0, {114, 684, 1634, 2510}}, {0, {115, 633, 1260, 2530}}, {1, {120, 660, 1213, 2460}}, {0, {112, 730, 1203, 2700}}, {0, {107, 752, 1125, 2620}}, {0, {108, 507, 755, 2420}}, {0, {116, 538, 816, 2450}}, {0, {114, 456, 1040, 2300}}, {0, {120, 480, 1120, 2160}}, {1, {123, 344, 960, 2150}}, {0, {125, 350, 1000, 2250}}, {0, {112, 539, 1370, 1800}}, {0, {117, 549, 1353, 1728}}, {0, {146, 292, 2500, 3150}}, {0, {133, 266, 2370, 3100}}, {0, {143, 372, 2220, 2640}}, {0, {131, 350, 2130, 2610}}, {1, {133, 574, 1840, 2260}}, {1, {133, 563, 1960, 2450}}, {0, {125, 650, 1738, 2400}}, {0, {130, 663, 1820, 2400}}, {0, {137, 600, 1370, 2180}}, {1, {125, 625, 1312, 2250}}, {0, {133, 735, 1070, 2100}}, {0, {117, 713, 1180, 2200}}, {0, {125, 625, 875, 2180}}, {1, {115, 700, 1000, 2250}}, {0, {150, 420, 1100, 2000}}, {0, {140, 420, 1120, 2100}}, {0, {125, 350, 980, 2200}}, {0, {133, 320, 918, 2100}}, {0, {143, 554, 1480, 1800}}, {0, {128, 484, 1505, 1890}}, {0, {143, 286, 2415, 2860}}, {0, {150, 300, 2415, 2860}}, {1, {140, 400, 1980, 2500}}, {1, {145, 407, 2095, 2620}}, {1, {125, 525, 1988, 2610}}, {0, {144, 553, 1935, 2530}}, {0, {133, 640, 1773, 2490}}, {0, {133, 640, 1840, 2560}}, {0, {143, 672, 1272, 2640}}, {0, {146, 658, 1241, 2560}}, {0, {130, 780, 1170, 2640}}, {0, {131, 788, 1115, 2645}}, {1, {138, 633, 891, 2500}}, {1, {150, 600, 935, 2550}}, {0, {175, 490, 1102, 2420}}, {0, {154, 492, 1077, 2306}}, {1, {160, 320, 960, 2240}}, {0, {160, 320, 960, 2290}}, {0, {143, 543, 1310, 1643}}, {0, {145, 508, 1309, 1600}}, {1, {230, 370, 2670, 3100}}, {0, {234, 390, 2760, 3060}}, {0, {234, 468, 2330, 2930}}, {0, {205, 410, 2380, 2950}}, {0, {190, 550, 2200, 2880}}, {0, {191, 570, 2100, 3040}}, {0, {200, 800, 1980, 2810}}, {0, {192, 860, 1920, 2850}}, {0, {227, 635, 1200, 3250}}, {0, {200, 700, 1200, 3100}}, {1, {210, 880, 1240, 2870}}, {0, {188, 830, 1200, 2880}}, {0, {207, 570, 830, 3300}}, {1, {200, 700, 1000, 3130}}, {0, {240, 410, 940, 3040}}, {0, {225, 450, 970, 3190}}, {0, {238, 480, 955, 2960}}, {1, {208, 395, 810, 2900}}, {0, {200, 500, 1850, 2100}}, {0, {200, 560, 1750, 2100}}, {0, {225, 270, 2760, 3550}}, {0, {240, 290, 2700, 3350}}, {0, {245, 460, 2500, 3220}}, {0, {220, 410, 2400, 3240}}, {0, {220, 620, 2300, 3200}}, {0, {210, 630, 2300, 3170}}, {0, {220, 820, 2180, 2850}}, {0, {195, 740, 2120, 3070}}, {0, {240, 800, 1300, 2900}}, {0, {225, 760, 1400, 2830}}, {0, {214, 850, 1120, 2620}}, {0, {190, 880, 1220, 2850}}, {0, {228, 460, 900, 2830}}, {1, {222, 440, 880, 2850}}, {0, {250, 500, 1040, 2750}}, {0, {245, 490, 1000, 2720}}, {0, {250, 400, 940, 2720}}, {0, {245, 410, 860, 2700}}, {0, {225, 440, 1560, 1750}}, {0, {210, 420, 1600, 1750}}, {0, {210, 290, 2700, 3020}}, {0, {215, 280, 2630, 3240}}, {1, {211, 420, 2300, 2950}}, {0, {211, 420, 2220, 2980}}, {1, {207, 640, 2120, 2900}}, {1, {221, 700, 2000, 2900}}, {0, {212, 1000, 1830, 2820}}, {0, {204, 980, 1800, 2820}}, {1, {205, 780, 1410, 2720}}, {0, {208, 710, 1450, 2750}}, {0, {205, 950, 1280, 2600}}, {0, {210, 870, 1260, 2740}}, {0, {203, 610, 900, 2710}}, {0, {210, 630, 840, 2700}}, {0, {211, 440, 1050, 2780}}, {0, {210, 420, 1050, 2740}}, {0, {222, 380, 860, 2500}}, {0, {208, 330, 750, 2740}}, {0, {208, 580, 1450, 1720}}, {0, {212, 540, 1560, 1900}}, {0, {210, 294, 2800, 3100}}, {0, {222, 270, 2880, 3160}}, {0, {202, 420, 2430, 3030}}, {0, {212, 420, 2370, 2930}}, {1, {200, 580, 2180, 2770}}, {1, {217, 540, 2160, 2770}}, {0, {200, 820, 1970, 2620}}, {0, {210, 840, 2000, 2700}}, {1, {208, 690, 1200, 2900}}, {0, {201, 666, 1206, 2900}}, {1, {200, 800, 1200, 2920}}, {1, {190, 760, 1140, 2850}}, {0, {200, 560, 760, 2800}}, {0, {207, 560, 770, 3000}}, {1, {215, 430, 1075, 2580}}, {0, {213, 430, 1000, 2700}}, {0, {220, 330, 840, 2550}}, {0, {213, 280, 850, 2500}}, {0, {205, 430, 1800, 1930}}, {0, {200, 420, 1740, 1960}}, {0, {175, 350, 2800, 3160}}, {0, {187, 338, 2870, 3300}}, {0, {200, 400, 2540, 3200}}, {0, {210, 420, 2680, 3000}}, {0, {180, 518, 2470, 3200}}, {0, {200, 600, 2400, 3150}}, {0, {171, 773, 2000, 2870}}, {0, {175, 875, 2100, 2970}}, {1, {183, 733, 1468, 2700}}, {0, {200, 740, 1280, 2900}}, {1, {178, 730, 1210, 2740}}, {1, {175, 735, 1220, 2850}}, {0, {160, 560, 960, 2850}}, {0, {192, 536, 850, 2850}}, {0, {212, 424, 1040, 2780}}, {0, {200, 520, 1060, 2670}}, {0, {190, 380, 770, 2900}}, {0, {187, 340, 750, 2780}}, {1, {177, 490, 2120, 2480}}, {0, {197, 493, 1930, 2300}}, {0, {250, 325, 2700, 3100}}, {0, {225, 310, 2750, 3225}}, {0, {214, 350, 2580, 3000}}, {0, {267, 390, 2700, 3200}}, {0, {233, 560, 2330, 2800}}, {0, {200, 520, 2500, 3000}}, {0, {171, 806, 1970, 2600}}, {0, {150, 825, 1860, 2550}}, {0, {186, 708, 1485, 2760}}, {0, {188, 676, 1500, 2590}}, {0, {200, 800, 1200, 2800}}, {1, {205, 714, 1154, 2850}}, {0, {267, 530, 800, 2780}}, {1, {180, 485, 810, 2750}}, {0, {214, 450, 1460, 2550}}, {0, {233, 467, 1400, 2450}}, {0, {225, 450, 1080, 2350}}, {0, {200, 400, 1000, 2400}}, {0, {193, 524, 1700, 2130}}, {0, {180, 507, 1800, 2380}}, {0, {200, 300, 3100, 3400}}, {1, {216, 300, 3100, 3500}}, {0, {214, 428, 2570, 3000}}, {0, {220, 440, 2640, 3080}}, {0, {210, 528, 2540, 3170}}, {1, {210, 504, 2520, 3200}}, {0, {187, 940, 2250, 2760}}, {0, {200, 820, 2200, 2920}}, {0, {204, 816, 1450, 2700}}, {1, {214, 858, 1500, 2700}}, {0, {200, 960, 1280, 3000}}, {1, {180, 1040, 1300, 3000}}, {0, {220, 520, 880, 2500}}, {0, {217, 574, 890, 2510}}, {1, {233, 466, 1330, 2750}}, {1, {233, 466, 1165, 2800}}, {0, {180, 300, 850, 2800}}, {1, {175, 350, 840, 2750}}, {0, {216, 432, 1790, 2060}}, {0, {219, 360, 1900, 2320}}, {0, {225, 337, 2700, 3300}}, {0, {233, 340, 2720, 3200}}, {0, {237, 474, 2370, 3095}}, {0, {237, 475, 2400, 3090}}, {0, {229, 526, 2360, 3090}}, {0, {233, 580, 2360, 3150}}, {1, {230, 690, 2185, 2990}}, {1, {220, 660, 2200, 3020}}, {1, {225, 675, 1551, 2923}}, {0, {233, 690, 1630, 2900}}, {0, {222, 845, 1334, 2890}}, {0, {233, 888, 1290, 2800}}, {0, {225, 631, 923, 2250}}, {0, {233, 543, 980, 2300}}, {0, {233, 537, 1360, 2920}}, {0, {240, 480, 1345, 2680}}, {0, {235, 400, 1180, 2760}}, {0, {233, 396, 1120, 2560}}, {0, {225, 450, 1640, 2250}}, {0, {233, 489, 1630, 2090}}, {0, {225, 225, 2760, 3900}}, {0, {230, 230, 2850, 3800}}, {0, {238, 429, 2560, 3200}}, {1, {230, 430, 2575, 3100}}, {0, {214, 579, 2570, 3300}}, {0, {214, 536, 2570, 3100}}, {0, {205, 823, 2220, 2870}}, {0, {200, 800, 2100, 2900}}, {0, {250, 750, 1500, 2750}}, {0, {217, 738, 1300, 2820}}, {0, {200, 840, 1300, 3100}}, {1, {206, 990, 1340, 3100}}, {0, {214, 579, 856, 2790}}, {0, {205, 545, 905, 2750}}, {1, {233, 490, 1220, 2610}}, {1, {250, 513, 1500, 2650}}, {0, {250, 400, 1250, 2500}}, {0, {225, 405, 1080, 2500}}, {0, {233, 466, 1860, 2260}}, {0, {225, 540, 1780, 2220}}, {0, {240, 290, 3000, 3840}}, {0, {250, 325, 2900, 3500}}, {0, {250, 500, 2370, 3120}}, {1, {238, 476, 2380, 3090}}, {0, {238, 760, 2380, 3205}}, {0, {233, 746, 2290, 3030}}, {0, {206, 1008, 1990, 2870}}, {0, {200, 1040, 2000, 2800}}, {0, {220, 830, 1540, 2860}}, {0, {237, 900, 1510, 2840}}, {0, {206, 970, 1343, 3018}}, {1, {236, 592, 1230, 2600}}, {0, {233, 650, 900, 2920}}, {0, {229, 687, 1060, 2780}}, {1, {233, 512, 1211, 2630}}, {0, {233, 467, 1167, 2595}}, {0, {250, 450, 875, 2750}}, {0, {233, 420, 935, 2710}}, {0, {230, 622, 1750, 2070}}, {0, {225, 652, 1710, 2043}}, {0, {255, 275, 2800, 3310}}, {0, {245, 245, 2800, 3300}}, {0, {267, 534, 2500, 3250}}, {0, {264, 528, 2640, 3370}}, {0, {238, 700, 2380, 3250}}, {0, {250, 750, 2480, 3000}}, {0, {237, 1020, 1900, 2960}}, {0, {233, 1005, 2050, 2870}}, {0, {263, 750, 1500, 2850}}, {0, {250, 850, 1400, 2750}}, {0, {258, 978, 1290, 2840}}, {0, {246, 935, 1230, 2730}}, {0, {250, 500, 750, 2750}}, {0, {243, 632, 850, 2850}}, {0, {250, 350, 1170, 2750}}, {0, {266, 450, 1000, 2800}}, {0, {256, 358, 640, 2560}}, {0, {250, 300, 750, 2500}}, {0, {260, 520, 1560, 1820}}, {0, {250, 500, 1500, 1750}}, {0, {236, 236, 2790, 3760}}, {0, {242, 242, 2770, 3800}}, {0, {222, 444, 2555, 3110}}, {0, {242, 420, 2700, 3120}}, {0, {226, 634, 2325, 2940}}, {0, {225, 608, 2475, 3100}}, {0, {210, 1010, 2060, 2900}}, {0, {200, 980, 2160, 2920}}, {0, {217, 818, 1450, 2500}}, {0, {200, 750, 1280, 2650}}, {0, {220, 820, 1200, 2640}}, {0, {210, 900, 1120, 2900}}, {0, {220, 440, 749, 2640}}, {0, {210, 567, 752, 2600}}, {1, {204, 460, 1045, 2504}}, {0, {240, 480, 1105, 2400}}, {0, {250, 420, 1000, 2500}}, {0, {275, 350, 1100, 2400}}, {0, {217, 487, 1500, 1780}}, {0, {206, 467, 1420, 1640}}, {0, {225, 360, 2920, 3400}}, {0, {233, 340, 2840, 3300}}, {0, {257, 514, 2570, 3070}}, {0, {238, 500, 2680, 3260}}, {0, {238, 650, 2495, 3090}}, {1, {216, 650, 2380, 3030}}, {0, {225, 1020, 2030, 2700}}, {0, {225, 1000, 2200, 2770}}, {0, {225, 788, 1462, 2920}}, {0, {217, 736, 1500, 2900}}, {1, {214, 987, 1330, 2830}}, {0, {214, 1009, 1415, 3080}}, {1, {226, 672, 1084, 2495}}, {0, {209, 627, 1045, 2504}}, {0, {250, 500, 1200, 2450}}, {0, {230, 460, 1150, 2880}}, {0, {267, 420, 990, 2860}}, {0, {190, 380, 893, 2920}}, {0, {246, 610, 1630, 2020}}, {0, {225, 585, 1700, 1850}}, {0, {285, 285, 2900, 3500}}, {0, {286, 310, 2900, 3400}}, {0, {297, 480, 2670, 3260}}, {1, {220, 440, 2620, 3380}}, {0, {173, 550, 2370, 3140}}, {0, {260, 520, 2340, 3040}}, {0, {167, 790, 2180, 3020}}, {0, {280, 840, 2160, 3020}}, {0, {280, 840, 1400, 2750}}, {0, {270, 760, 1330, 2950}}, {0, {252, 900, 1290, 2750}}, {1, {260, 900, 1240, 3110}}, {0, {175, 700, 1050, 2750}}, {0, {190, 720, 1080, 3030}}, {0, {286, 540, 1200, 2860}}, {0, {205, 570, 1200, 2970}}, {0, {328, 400, 980, 2630}}, {0, {290, 440, 990, 2900}}, {0, {286, 570, 2000, 2480}}, {0, {260, 510, 1850, 2350}}, {0, {170, 340, 2750, 3120}}, {0, {238, 360, 2760, 3120}}, {0, {167, 480, 2390, 2950}}, {1, {194, 520, 2450, 3000}}, {0, {220, 620, 2520, 2920}}, {0, {222, 620, 2440, 2880}}, {0, {222, 1110, 2160, 2700}}, {0, {214, 1070, 1960, 2750}}, {1, {217, 820, 1240, 2600}}, {1, {216, 860, 1300, 2670}}, {0, {150, 840, 1110, 2930}}, {0, {170, 850, 1120, 2850}}, {0, {200, 500, 700, 2930}}, {0, {212, 380, 720, 2700}}, {0, {235, 400, 940, 2820}}, {0, {214, 380, 860, 2680}}, {0, {196, 330, 760, 2870}}, {0, {188, 350, 710, 2760}}, {0, {182, 550, 1780, 2080}}, {0, {201, 600, 1750, 2000}}, {0, {200, 320, 2360, 2980}}, {0, {203, 304, 2380, 3050}}, {1, {211, 444, 2220, 2740}}, {1, {210, 420, 2090, 2780}}, {0, {200, 500, 2350, 2830}}, {0, {200, 600, 2200, 2700}}, {1, {192, 845, 1700, 2300}}, {0, {187, 860, 1724, 2530}}, {0, {200, 720, 1440, 2380}}, {0, {191, 707, 1470, 2440}}, {0, {200, 700, 1080, 2420}}, {1, {192, 767, 1150, 2590}}, {0, {200, 600, 860, 2410}}, {0, {200, 600, 900, 2400}}, {0, {210, 546, 1090, 2400}}, {0, {210, 462, 1240, 2310}}, {0, {257, 360, 930, 2260}}, {0, {220, 440, 1100, 2300}}, {0, {200, 540, 1400, 1800}}, {0, {204, 460, 1350, 1560}}, {0, {203, 406, 2600, 2945}}, {1, {200, 400, 2600, 3100}}, {0, {200, 460, 2300, 2800}}, {0, {210, 420, 2305, 2835}}, {0, {190, 570, 2100, 2720}}, {0, {207, 538, 2175, 2880}}, {0, {189, 850, 1853, 2685}}, {0, {193, 830, 1800, 2620}}, {0, {200, 720, 1500, 2560}}, {0, {200, 800, 1400, 2420}}, {0, {194, 915, 1280, 2530}}, {0, {206, 723, 1196, 2600}}, {0, {192, 575, 1073, 2490}}, {0, {200, 600, 1100, 2600}}, {0, {202, 520, 1210, 2420}}, {0, {212, 468, 1275, 2550}}, {0, {207, 370, 1000, 2470}}, {0, {205, 330, 970, 2460}}, {0, {200, 560, 1600, 1900}}, {0, {206, 514, 1540, 1955}}, {0, {240, 380, 2880, 3360}}, {0, {250, 380, 2820, 3300}}, {1, {233, 514, 2600, 2930}}, {0, {237, 473, 2660, 2970}}, {0, {223, 567, 2460, 3122}}, {0, {224, 521, 2460, 2920}}, {0, {218, 808, 2070, 2880}}, {1, {203, 678, 2420, 3080}}, {0, {200, 800, 1340, 2700}}, {1, {214, 772, 1280, 2660}}, {0, {183, 843, 1190, 2860}}, {0, {205, 740, 1160, 2780}}, {1, {222, 623, 1022, 2700}}, {0, {220, 594, 990, 2640}}, {1, {240, 480, 960, 2820}}, {0, {242, 484, 900, 2640}}, {0, {233, 370, 933, 2520}}, {0, {250, 325, 750, 2500}}, {0, {225, 450, 1680, 2050}}, {1, {233, 466, 1630, 1865}}, {0, {200, 320, 2750, 3100}}, {0, {178, 356, 2755, 3200}}, {0, {194, 388, 2622, 3050}}, {0, {194, 426, 2460, 3040}}, {0, {187, 592, 2242, 2765}}, {1, {191, 535, 2290, 2870}}, {1, {188, 750, 2060, 2770}}, {1, {162, 650, 2110, 2618}}, {0, {187, 618, 1518, 2700}}, {0, {183, 624, 1430, 2660}}, {0, {163, 766, 1180, 2340}}, {0, {167, 750, 1065, 2640}}, {1, {170, 595, 918, 2600}}, {1, {176, 630, 985, 2630}}, {0, {200, 420, 1200, 2600}}, {0, {200, 460, 1260, 2640}}, {0, {187, 375, 1124, 2685}}, {1, {188, 375, 1143, 2700}}, {0, {180, 504, 1565, 1835}}, {0, {183, 513, 1578, 1830}}, {0, {280, 357, 2800, 3360}}, {0, {275, 340, 2860, 3350}}, {0, {290, 480, 2600, 3060}}, {0, {292, 465, 2598, 3060}}, {1, {250, 700, 2350, 2980}}, {0, {240, 737, 2325, 3100}}, {0, {200, 960, 2100, 3000}}, {0, {217, 1030, 2200, 3260}}, {0, {275, 920, 1512, 2950}}, {0, {260, 910, 1688, 3050}}, {0, {275, 990, 1237, 2360}}, {0, {267, 987, 1172, 3180}}, {0, {267, 587, 1068, 3270}}, {0, {293, 560, 990, 3150}}, {1, {275, 520, 1350, 3190}}, {1, {280, 510, 1415, 3130}}, {0, {300, 420, 1045, 3060}}, {0, {300, 390, 960, 3030}}, {0, {230, 460, 1860, 2250}}, {0, {214, 504, 1820, 2290}}, {0, {200, 240, 2760, 3700}}, {0, {220, 220, 2850, 3800}}, {0, {228, 319, 2500, 3020}}, {0, {216, 324, 2500, 3010}}, {0, {220, 616, 2380, 2900}}, {0, {212, 615, 2300, 2800}}, {1, {212, 710, 2120, 2600}}, {1, {210, 690, 2250, 2680}}, {0, {221, 800, 1520, 2380}}, {0, {210, 780, 1470, 2400}}, {0, {199, 995, 1392, 2290}}, {0, {200, 1000, 1400, 2440}}, {0, {205, 656, 944, 2250}}, {0, {200, 720, 960, 2380}}, {0, {223, 335, 1049, 2470}}, {0, {210, 420, 1009, 2300}}, {0, {219, 329, 877, 2550}}, {0, {230, 340, 900, 2530}}, {0, {206, 400, 1380, 1560}}, {0, {201, 400, 1240, 1480}}, {0, {220, 286, 2800, 3550}}, {0, {241, 289, 2800, 3400}}, {0, {225, 383, 2420, 3080}}, {0, {240, 384, 2400, 3050}}, {1, {209, 418, 2430, 3110}}, {0, {230, 460, 2300, 3050}}, {0, {187, 861, 2100, 2800}}, {0, {224, 896, 2040, 3000}}, {0, {218, 654, 1160, 2800}}, {0, {230, 690, 1195, 2770}}, {0, {208, 860, 1103, 2700}}, {0, {212, 806, 1060, 2850}}, {0, {202, 606, 910, 2900}}, {0, {201, 583, 860, 2840}}, {0, {225, 340, 900, 2650}}, {0, {235, 470, 1100, 2560}}, {0, {205, 308, 1025, 2650}}, {0, {235, 329, 1151, 2560}}, {0, {213, 533, 1425, 1830}}, {0, {214, 535, 1412, 1800}}, {0, {236, 307, 2670, 3150}}, {0, {245, 340, 2700, 3250}}, {0, {231, 417, 2300, 3000}}, {1, {239, 410, 2200, 2910}}, {1, {222, 644, 2250, 3000}}, {0, {224, 670, 2300, 2880}}, {1, {224, 784, 1800, 2750}}, {1, {234, 820, 1750, 2890}}, {0, {225, 765, 1300, 2700}}, {0, {221, 730, 1390, 2790}}, {1, {225, 834, 1282, 2800}}, {0, {212, 850, 1270, 2760}}, {1, {229, 688, 1029, 2750}}, {0, {222, 670, 1040, 2640}}, {0, {251, 427, 1506, 2640}}, {0, {240, 460, 1370, 2610}}, {0, {236, 378, 1416, 2580}}, {0, {239, 380, 1430, 2610}}, {0, {230, 460, 1200, 1909}}, {0, {225, 410, 1580, 1800}}, {0, {256, 384, 2860, 3210}}, {0, {250, 375, 3000, 3400}}, {0, {230, 460, 2665, 3140}}, {0, {233, 467, 2680, 3150}}, {0, {229, 640, 2400, 2860}}, {0, {233, 630, 2530, 3030}}, {1, {233, 700, 2560, 3150}}, {1, {225, 675, 2510, 3145}}, {1, {240, 768, 1440, 2855}}, {0, {234, 794, 1447, 2920}}, {0, {227, 978, 1362, 2724}}, {0, {233, 933, 1350, 2610}}, {0, {240, 700, 1080, 2810}}, {0, {240, 720, 1090, 2840}}, {0, {243, 500, 1215, 2870}}, {0, {239, 500, 1240, 2860}}, {0, {263, 470, 1000, 2820}}, {0, {272, 378, 950, 2990}}, {0, {243, 480, 1410, 1700}}, {0, {243, 493, 1580, 1775}}, {0, {268, 320, 2900, 3200}}, {0, {263, 290, 2750, 3050}}, {1, {258, 460, 2380, 2940}}, {1, {251, 480, 2260, 2980}}, {1, {246, 640, 2220, 2900}}, {1, {250, 670, 2250, 2960}}, {0, {243, 950, 1970, 2890}}, {0, {244, 980, 1950, 2920}}, {1, {251, 750, 1280, 2760}}, {0, {258, 770, 1340, 2800}}, {1, {250, 950, 1130, 3160}}, {1, {256, 850, 1150, 2940}}, {0, {242, 530, 870, 2680}}, {0, {250, 600, 900, 2770}}, {1, {250, 600, 1225, 2500}}, {1, {264, 630, 1320, 2560}}, {0, {258, 440, 1290, 2530}}, {0, {269, 460, 1080, 2640}}, {0, {250, 600, 1500, 2000}}, {0, {254, 610, 1520, 1950}}, {0, {234, 280, 2690, 3040}}, {0, {261, 280, 2740, 2980}}, {0, {260, 470, 2500, 3400}}, {0, {262, 440, 2480, 3240}}, {0, {242, 730, 2300, 3100}}, {0, {260, 750, 2340, 3120}}, {0, {233, 860, 2070, 2880}}, {0, {240, 890, 1920, 2710}}, {0, {257, 770, 1540, 2840}}, {0, {257, 800, 1410, 2860}}, {0, {240, 790, 1250, 3080}}, {1, {241, 820, 1210, 2960}}, {0, {234, 408, 695, 3040}}, {0, {246, 420, 590, 3100}}, {0, {251, 500, 1230, 2520}}, {0, {256, 480, 1230, 2750}}, {0, {263, 419, 1050, 2850}}, {0, {278, 390, 1060, 2800}}, {0, {220, 420, 1720, 1900}}, {0, {255, 510, 1680, 1890}}, {0, {208, 270, 2820, 3450}}, {0, {225, 250, 2880, 3350}}, {0, {220, 370, 2530, 3060}}, {0, {250, 400, 2600, 3120}}, {0, {214, 640, 2360, 3020}}, {0, {219, 650, 2430, 3040}}, {0, {205, 900, 2090, 3000}}, {0, {200, 860, 2160, 2870}}, {0, {214, 750, 1540, 2800}}, {0, {214, 770, 1530, 2780}}, {0, {195, 920, 1350, 2550}}, {1, {210, 920, 1470, 2690}}, {0, {194, 720, 1110, 2420}}, {0, {200, 700, 1100, 2780}}, {0, {222, 470, 1200, 2900}}, {0, {237, 470, 1190, 2800}}, {0, {240, 380, 980, 3100}}, {0, {188, 340, 920, 3050}}, {0, {222, 530, 1670, 2050}}, {0, {200, 500, 1720, 1900}}, {0, {258, 310, 2740, 3200}}, {0, {262, 262, 2680, 3170}}, {0, {262, 450, 2310, 3020}}, {0, {263, 472, 2270, 2950}}, {1, {245, 640, 1980, 2920}}, {1, {235, 700, 2110, 2940}}, {0, {194, 810, 1860, 2620}}, {0, {234, 890, 1800, 2700}}, {1, {230, 710, 1340, 2780}}, {1, {245, 740, 1470, 2940}}, {1, {225, 830, 1020, 2650}}, {1, {219, 830, 1095, 2610}}, {0, {240, 600, 850, 2760}}, {0, {253, 455, 810, 2750}}, {0, {282, 400, 1070, 2530}}, {0, {250, 450, 1050, 2450}}, {0, {260, 290, 670, 2380}}, {0, {275, 330, 630, 2460}}, {0, {240, 500, 1630, 2040}}, {0, {243, 490, 1580, 2190}}, {0, {228, 460, 3300, 3950}}, {0, {200, 400, 3400, 3850}}, {1, {205, 600, 2550, 4000}}, {1, {205, 610, 2500, 4100}}, {1, {225, 600, 2750, 3600}}, {1, {210, 760, 2500, 3850}}, {0, {200, 1000, 2300, 3900}}, {1, {200, 800, 2500, 4050}}, {1, {200, 1000, 1750, 3550}}, {0, {223, 1110, 1690, 4040}}, {1, {205, 1220, 1560, 3650}}, {1, {200, 1300, 1800, 3450}}, {0, {219, 660, 1100, 3850}}, {1, {217, 690, 1090, 3900}}, {1, {206, 620, 1420, 3700}}, {0, {220, 620, 1410, 3520}}, {0, {233, 440, 900, 3900}}, {0, {200, 400, 650, 3800}}, {0, {210, 610, 2300, 2900}}, {0, {200, 450, 2150, 2550}}, {0, {290, 320, 3500, 4260}}, {0, {305, 350, 3400, 4100}}, {0, {322, 640, 3200, 3660}}, {0, {325, 650, 3000, 3800}}, {0, {270, 850, 2900, 3680}}, {1, {285, 700, 3120, 3750}}, {0, {256, 1130, 2560, 3500}}, {0, {285, 1140, 2000, 3560}}, {0, {310, 1130, 1740, 3670}}, {0, {300, 1000, 1800, 3450}}, {1, {265, 1170, 1500, 3440}}, {1, {283, 980, 1300, 3100}}, {1, {265, 530, 1060, 3450}}, {1, {272, 540, 1080, 3000}}, {0, {285, 560, 1440, 3500}}, {0, {294, 570, 1450, 3500}}, {0, {333, 350, 1280, 3650}}, {0, {290, 340, 1160, 2950}}, {1, {275, 560, 1740, 2460}}, {0, {302, 600, 1800, 2200}}, {0, {240, 380, 3140, 3700}}, {0, {258, 310, 3350, 3650}}, {1, {290, 580, 2760, 3400}}, {0, {250, 500, 2660, 3500}}, {1, {250, 780, 2450, 3400}}, {1, {240, 672, 2550, 3400}}, {1, {240, 660, 2900, 3370}}, {1, {215, 760, 2850, 3300}}, {0, {250, 880, 1500, 3200}}, {0, {243, 850, 1700, 3250}}, {0, {250, 940, 1380, 2400}}, {0, {276, 1200, 1500, 3160}}, {0, {250, 750, 1250, 3450}}, {0, {225, 675, 950, 3240}}, {0, {300, 610, 1500, 3300}}, {0, {275, 500, 1370, 3500}}, {0, {256, 300, 1280, 3150}}, {0, {250, 400, 1300, 3700}}, {0, {250, 500, 1540, 1700}}, {0, {242, 580, 1620, 1790}}, {0, {291, 410, 3200, 3800}}, {0, {264, 420, 3400, 3900}}, {1, {291, 580, 2900, 3820}}, {1, {280, 560, 2840, 3900}}, {1, {292, 810, 2640, 4200}}, {1, {270, 780, 2720, 4100}}, {0, {270, 1080, 2480, 3950}}, {0, {245, 1050, 2420, 4000}}, {1, {286, 970, 1600, 3950}}, {1, {250, 800, 1680, 3800}}, {1, {275, 1040, 1350, 3850}}, {0, {250, 1100, 1460, 4250}}, {1, {286, 770, 1150, 3950}}, {1, {273, 710, 1200, 3900}}, {1, {285, 680, 1420, 3800}}, {0, {278, 640, 1350, 3950}}, {0, {300, 420, 1110, 3640}}, {0, {280, 505, 1050, 3400}}, {0, {320, 640, 1940, 2820}}, {0, {265, 610, 2100, 2600}}, {0, {330, 460, 2800, 3550}}, {0, {333, 490, 2730, 3550}}, {1, {310, 560, 2500, 3450}}, {1, {310, 580, 2500, 3450}}, {1, {286, 800, 2300, 3750}}, {1, {310, 835, 2420, 3740}}, {0, {282, 950, 2150, 3650}}, {0, {310, 1000, 2150, 3700}}, {0, {293, 880, 1700, 3750}}, {0, {340, 900, 1600, 3650}}, {1, {299, 990, 1410, 3750}}, {0, {280, 1050, 1320, 3730}}, {1, {285, 770, 940, 3750}}, {1, {333, 680, 1020, 3700}}, {0, {322, 550, 1195, 3750}}, {0, {350, 550, 1340, 3500}}, {1, {316, 600, 1200, 3600}}, {0, {345, 550, 1100, 3470}}, {0, {310, 805, 1705, 2420}}, {0, {310, 710, 1700, 2400}}, {0, {210, 340, 3400, 4320}}, {0, {227, 590, 3610, 4220}}, {0, {235, 680, 3250, 4380}}, {1, {220, 440, 3000, 3790}}, {0, {212, 660, 2900, 3610}}, {1, {216, 610, 2760, 3650}}, {0, {214, 1240, 2700, 3640}}, {0, {215, 1050, 2550, 3550}}, {0, {216, 820, 1470, 3500}}, {1, {211, 970, 1410, 3200}}, {0, {218, 1090, 1380, 3050}}, {1, {212, 860, 1250, 2800}}, {0, {211, 800, 1220, 3700}}, {0, {214, 640, 1070, 3000}}, {0, {219, 660, 1360, 3700}}, {0, {214, 730, 1500, 3600}}, {0, {220, 620, 1100, 3250}}, {0, {216, 600, 1280, 3650}}, {0, {222, 670, 2130, 2360}}, {0, {205, 760, 2240, 2460}}, {0, {253, 330, 3250, 3720}}, {0, {262, 340, 3100, 3400}}, {1, {250, 500, 2500, 3640}}, {1, {278, 530, 2630, 3640}}, {1, {255, 710, 2550, 3560}}, {1, {250, 750, 2480, 3470}}, {0, {233, 1140, 2260, 3640}}, {0, {245, 1110, 2230, 3380}}, {0, {256, 770, 1540, 3500}}, {0, {257, 800, 1490, 3300}}, {0, {240, 940, 1400, 3400}}, {1, {245, 930, 1370, 3120}}, {0, {240, 530, 860, 3400}}, {0, {240, 520, 910, 3420}}, {0, {255, 510, 1250, 3320}}, {0, {260, 520, 1140, 3320}}, {0, {274, 360, 660, 3050}}, {0, {260, 310, 730, 3500}}, {0, {250, 550, 1500, 1800}}, {0, {239, 480, 1650, 1960}}, {0, {250, 300, 2950, 3600}}, {0, {270, 320, 3210, 3600}}, {0, {290, 550, 2610, 3560}}, {1, {286, 540, 2570, 3600}}, {0, {280, 700, 2500, 3580}}, {0, {263, 600, 2360, 3400}}, {0, {260, 970, 2400, 3200}}, {0, {250, 950, 2270, 3200}}, {0, {270, 780, 1650, 3350}}, {1, {250, 720, 1500, 3240}}, {1, {278, 950, 1200, 2950}}, {1, {250, 920, 1080, 2770}}, {1, {262, 790, 1050, 2900}}, {0, {250, 750, 1000, 2500}}, {0, {275, 540, 1430, 3320}}, {0, {263, 530, 1580, 3200}}, {0, {295, 420, 1500, 3010}}, {0, {260, 450, 1330, 2840}}, {0, {272, 570, 1880, 2400}}, {0, {255, 510, 1610, 1910}}, {0, {235, 280, 2820, 3400}}, {0, {244, 317, 3125, 3500}}, {0, {230, 460, 2520, 3300}}, {0, {212, 420, 2480, 3140}}, {0, {235, 657, 2300, 3300}}, {0, {232, 672, 2275, 3300}}, {0, {231, 808, 1950, 3300}}, {0, {225, 870, 2000, 3200}}, {0, {236, 706, 1410, 3200}}, {0, {211, 720, 1480, 2880}}, {1, {250, 950, 1350, 3100}}, {1, {227, 910, 1360, 2950}}, {0, {203, 700, 1120, 3070}}, {0, {230, 690, 920, 2760}}, {0, {250, 475, 1250, 3150}}, {0, {212, 460, 1210, 2750}}, {0, {244, 403, 1100, 2950}}, {0, {242, 363, 920, 2900}}, {0, {226, 452, 1580, 1810}}, {0, {232, 510, 1550, 1740}}, {0, {230, 280, 3140, 3830}}, {0, {250, 300, 3400, 3950}}, {1, {225, 450, 2700, 3650}}, {1, {250, 400, 2840, 3700}}, {0, {215, 580, 2650, 3550}}, {1, {220, 620, 2660, 3770}}, {0, {240, 910, 2370, 3160}}, {0, {233, 930, 2350, 3450}}, {0, {250, 770, 1650, 3420}}, {0, {230, 690, 1600, 3350}}, {1, {242, 970, 1450, 3260}}, {1, {225, 1010, 1650, 3150}}, {0, {232, 670, 1160, 3550}}, {0, {225, 720, 1260, 3400}}, {0, {216, 500, 1640, 3580}}, {0, {250, 450, 1440, 3500}}, {0, {290, 350, 1160, 3260}}, {0, {273, 330, 1090, 3350}}, {0, {240, 430, 1800, 2400}}, {0, {233, 470, 1840, 2400}}, {0, {275, 330, 3050, 3800}}, {0, {286, 340, 2860, 3610}}, {0, {280, 500, 2720, 3360}}, {0, {230, 600, 2750, 3550}}, {0, {245, 735, 2450, 3300}}, {0, {258, 780, 2560, 3300}}, {0, {235, 940, 2020, 2580}}, {0, {232, 1070, 2320, 2900}}, {0, {268, 860, 1530, 3100}}, {0, {256, 970, 1500, 3050}}, {1, {245, 780, 1250, 3180}}, {1, {236, 970, 970, 3120}}, {1, {258, 825, 1210, 3100}}, {1, {300, 930, 930, 2900}}, {0, {260, 490, 1460, 2860}}, {0, {286, 570, 1320, 2840}}, {0, {275, 470, 1400, 2800}}, {0, {286, 370, 1160, 2800}}, {0, {268, 510, 1660, 2100}}, {0, {250, 480, 1700, 1830}}, {0, {295, 380, 3200, 4000}}, {0, {267, 350, 3250, 3700}}, {0, {294, 380, 2960, 3800}}, {0, {300, 520, 2900, 3600}}, {0, {280, 670, 2790, 3600}}, {1, {275, 620, 2750, 3500}}, {0, {262, 1070, 2380, 3100}}, {0, {275, 1130, 2320, 3110}}, {1, {290, 700, 1730, 2960}}, {0, {270, 725, 1570, 2900}}, {0, {278, 1110, 1630, 2780}}, {0, {280, 1130, 1400, 3000}}, {1, {292, 580, 930, 2950}}, {0, {270, 540, 1070, 3000}}, {0, {300, 450, 1350, 3000}}, {0, {320, 520, 1600, 3150}}, {0, {307, 460, 1460, 3070}}, {0, {300, 400, 1700, 3000}}, {0, {300, 540, 1770, 2040}}, {0, {286, 540, 2050, 2300}}, {0, {300, 300, 3250, 3850}}, {0, {275, 275, 3280, 3800}}, {0, {286, 570, 2850, 3400}}, {0, {267, 485, 2630, 3450}}, {0, {264, 650, 2880, 3500}}, {0, {284, 570, 2900, 3600}}, {0, {260, 1300, 2280, 3130}}, {0, {260, 1300, 2160, 3300}}, {0, {275, 850, 1540, 3020}}, {0, {262, 840, 1580, 2880}}, {0, {250, 1230, 1300, 3200}}, {0, {286, 1090, 1230, 2980}}, {0, {265, 850, 850, 2920}}, {1, {285, 685, 1030, 2900}}, {0, {283, 540, 1420, 3050}}, {0, {300, 600, 1440, 2900}}, {0, {280, 390, 1340, 2830}}, {0, {284, 340, 1110, 3080}}, {0, {280, 530, 1650, 1740}}, {0, {286, 550, 1660, 1770}}, {0, {265, 370, 2950, 3400}}, {0, {290, 370, 2910, 3480}}, {0, {271, 515, 2740, 3280}}, {0, {290, 485, 2600, 3200}}, {0, {262, 630, 2520, 3150}}, {0, {272, 565, 2440, 3120}}, {0, {262, 970, 2030, 2880}}, {0, {275, 915, 2130, 2900}}, {0, {270, 810, 1600, 3230}}, {1, {280, 760, 1530, 3180}}, {1, {270, 810, 1350, 2940}}, {0, {275, 1000, 1360, 3000}}, {1, {270, 535, 970, 2960}}, {1, {275, 550, 1080, 2850}}, {1, {275, 550, 1420, 3040}}, {0, {295, 570, 1500, 3000}}, {0, {283, 510, 1700, 3020}}, {1, {278, 500, 1640, 3050}}, {0, {261, 522, 1830, 2350}}, {0, {282, 530, 1800, 2250}}, {0, {320, 350, 3240, 3760}}, {0, {344, 344, 3120, 3640}}, {0, {308, 590, 2760, 3500}}, {0, {320, 540, 2900, 3500}}, {0, {307, 830, 2750, 3650}}, {0, {308, 800, 2640, 3540}}, {0, {294, 1140, 2450, 3230}}, {0, {239, 1130, 2550, 3150}}, {0, {310, 930, 1540, 3120}}, {0, {315, 950, 1670, 3150}}, {0, {350, 1190, 1470, 3150}}, {1, {314, 1070, 1460, 2950}}, {0, {300, 910, 1200, 3180}}, {0, {330, 830, 1250, 3250}}, {0, {327, 630, 1310, 3270}}, {0, {322, 610, 1550, 3400}}, {0, {345, 520, 1250, 3460}}, {0, {334, 500, 1140, 3380}}, {0, {308, 740, 1850, 2160}}, {0, {328, 660, 1830, 2200}} }; try { autoTable me = Table_create (nrows, ncols); for (long i = 1; i <= nrows; i++) { TableRow row = (TableRow) my rows -> item[i]; int vowel_id = ( (i - 1) % 20) / 2 + 1; /* 1 - 10 */ int speaker_id = (i - 1) / 20 + 1; /* 1 - 76 */ int speaker_type, speaker_sex; if (speaker_id <= 33) { /* 33 men */ speaker_type = 0; speaker_sex = 0; } else if (speaker_id <= (33 + 28)) { /* 28 women */ speaker_type = 1; speaker_sex = 1; } else { /*15 children */ speaker_type = 2; speaker_sex = 0; if (speaker_id == 62 || speaker_id == 63 || (speaker_id >= 65 && speaker_id <= 68) || speaker_id == 73 || speaker_id == 76) { speaker_sex = 1; } } row -> cells [1]. string = Melder_dup_f (type [speaker_type]); row -> cells [2]. string = Melder_dup_f (sex [speaker_sex]); row -> cells [3]. string = Melder_dup_f (Melder_integer (speaker_id)); row -> cells [4]. string = Melder_dup_f (vowel [vowel_id - 1]); row -> cells [5]. string = Melder_dup_f (ipa [vowel_id - 1]); for (long j = 0; j <= 3; j++) { row -> cells [j + 6].string = Melder_dup_f (Melder_integer (pbdata[i - 1].f[j])); } } for (long j = 1; j <= ncols; j++) { Table_setColumnLabel (me.peek(), j, columnLabels[j - 1]); my columnHeaders [j]. numericized = false; } return me.transfer(); } catch (MelderError) { Melder_throw (U"Table not created from Peterson & Barney data."); } } Table Table_createFromPolsVanNieropData () { long nrows = 900, ncols = 10; const char32 *columnLabels[10] = {U"Sex", U"Speaker", U"Vowel", U"IPA", U"F1", U"F2", U"F3", U"L1", U"L2", U"L3"}; const char32 *vowel[12] = {U"oe", U"aa", U"oo", U"a", U"eu", U"ie", U"uu", U"ee", U"u", U"e", U"o", U"i" }; const char32 *ipa[12] = {U"u", U"a", U"o", U"\\as", U"\\o/", U"i", U"y", U"e", U"\\yc", U"\\ep", U"\\ct", U"\\ic"}; const char32 *sex[2] = {U"m", U"f"}; struct polsdatum { short f[3]; /* frequency F1, F2, F3 */ short l[3]; /* level f1, f2, f3 */ } polsdata [] = { /* 50*12 males */ /* male 1 */ {{320, 630, 2560}, {6, 13, 48}}, /* poet */ {{780, 1300, 2460}, {6, 8, 30}}, /* paat */ {{500, 940, 2420}, {3, 12, 35}}, /* poot */ {{720, 1060, 2420}, {3, 8, 27}}, /* pat */ {{430, 1580, 2260}, {2, 24, 36}}, /* peut */ {{280, 2300, 2780}, {14, 22, 27}}, /* piet */ {{320, 1680, 2140}, {6, 23, 30}}, /* puut */ {{420, 2000, 2620}, {5, 20, 23}}, /* peet */ {{420, 1540, 2380}, {4, 19, 24}}, /* put */ {{600, 1720, 2700}, {3, 17, 29}}, /* pet */ {{520, 1000, 2520}, {4, 13, 31}}, /* pot */ {{350, 2000, 2520}, {7, 19, 18}}, /* pit */ /* male 2 */ {{440, 780, 2600}, {7, 20, 35}}, {{940, 1300, 2780}, {5, 13, 26}}, {{500, 740, 2700}, {7, 11, 32}}, {{800, 1000, 2480}, {11, 11, 31}}, {{460, 1500, 2300}, {10, 20, 20}}, {{320, 2400, 3040}, {9, 28, 27}}, {{340, 1600, 2050}, {7, 30, 32}}, {{420, 2200, 2650}, {4, 10, 12}}, {{540, 1370, 2320}, {6, 23, 31}}, {{760, 1660, 2600}, {8, 13, 18}}, {{560, 800, 2800}, {5, 17, 37}}, {{430, 2030, 2660}, {7, 18, 17}}, /* male 3 */ {{280, 740, 2160}, {8, 32, 46}}, {{860, 1500, 2580}, {7, 13, 19}}, {{480, 820, 2280}, {4, 11, 33}}, {{680, 1020, 2460}, {9, 14, 25}}, {{360, 1520, 2080}, {5, 16, 21}}, {{270, 2040, 2860}, {5, 18, 18}}, {{280, 1600, 1900}, {5, 16, 21}}, {{380, 1940, 2580}, {5, 15, 17}}, {{400, 1520, 2120}, {4, 21, 24}}, {{560, 1840, 2520}, {7, 18, 22}}, {{500, 820, 2520}, {3, 11, 30}}, {{350, 2000, 2660}, {4, 15, 19}}, /* male 4 */ {{360, 820, 2220}, {6, 11, 30}}, {{840, 1300, 2280}, {9, 7, 22}}, {{500, 900, 2320}, {7, 13, 35}}, {{680, 1000, 2480}, {12, 12, 27}}, {{440, 1320, 2060}, {5, 12, 27}}, {{240, 2060, 2580}, {5, 20, 23}}, {{300, 1540, 2020}, {4, 18, 24}}, {{460, 1920, 2460}, {7, 18, 17}}, {{480, 1320, 2200}, {6, 15, 22}}, {{660, 1660, 2340}, {7, 16, 21}}, {{500, 800, 2520}, {7, 14, 34}}, {{440, 1920, 2380}, {3, 19, 18}}, /* male 5 */ {{440, 880, 2300}, {6, 22, 41}}, {{820, 1420, 2180}, {6, 7, 28}}, {{540, 960, 2460}, {4, 10, 28}}, {{780, 1040, 2620}, {8, 10, 32}}, {{540, 1540, 2160}, {2, 17, 19}}, {{300, 2300, 2900}, {5, 23, 30}}, {{360, 1860, 2200}, {2, 15, 15}}, {{520, 1960, 2400}, {4, 21, 21}}, {{560, 1440, 2280}, {2, 17, 27}}, {{700, 1720, 2300}, {7, 13, 22}}, {{600, 880, 3000}, {5, 5, 25}}, {{560, 1920, 2400}, {5, 22, 25}}, /* male 6 */ {{260, 700, 2550}, {3, 24, 45}}, {{820, 1460, 2760}, {10, 15, 27}}, {{450, 900, 2460}, {19, 20, 45}}, {{700, 1080, 2660}, {13, 22, 32}}, {{460, 1750, 2300}, {7, 32, 40}}, {{240, 2500, 3000}, {3, 33, 37}}, {{260, 2100, 2500}, {10, 37, 43}}, {{300, 2320, 2860}, {8, 26, 26}}, {{440, 1700, 2660}, {7, 27, 32}}, {{560, 2080, 2840}, {12, 15, 16}}, {{550, 900, 2740}, {7, 25, 30}}, {{340, 2340, 3000}, {8, 31, 31}}, /* male 7 */ {{280, 860, 2340}, {5, 15, 33}}, {{800, 1320, 2540}, {7, 14, 26}}, {{520, 920, 2600}, {8, 15, 33}}, {{600, 1000, 2760}, {7, 7, 25}}, {{450, 1660, 2260}, {7, 20, 24}}, {{260, 2340, 2640}, {3, 17, 20}}, {{280, 1780, 2160}, {3, 25, 29}}, {{400, 2040, 2400}, {9, 19, 21}}, {{460, 1560, 2400}, {4, 19, 22}}, {{620, 1760, 2560}, {6, 18, 25}}, {{560, 960, 2760}, {9, 16, 33}}, {{340, 2000, 2600}, {6, 14, 18}}, /* male 8 */ {{320, 880, 2200}, {6, 16, 40}}, {{800, 1160, 2600}, {6, 13, 26}}, {{560, 980, 2360}, {5, 8, 35}}, {{700, 1080, 2540}, {10, 14, 34}}, {{500, 1480, 2300}, {8, 17, 29}}, {{280, 2080, 2620}, {3, 27, 27}}, {{320, 1760, 2060}, {4, 25, 32}}, {{400, 1940, 2540}, {9, 17, 22}}, {{400, 1560, 2280}, {6, 18, 28}}, {{540, 1860, 2540}, {4, 14, 19}}, {{560, 920, 2320}, {8, 13, 32}}, {{340, 1960, 2480}, {6, 13, 17}}, /* male 9 */ {{300, 680, 2400}, {3, 19, 32}}, {{860, 1300, 2660}, {12, 18, 26}}, {{500, 940, 2500}, {3, 13, 33}}, {{700, 1120, 2620}, {9, 17, 24}}, {{500, 1500, 2280}, {3, 17, 22}}, {{300, 2380, 2960}, {2, 20, 22}}, {{300, 1760, 2160}, {1, 19, 23}}, {{480, 2100, 2580}, {4, 15, 15}}, {{500, 1580, 2400}, {5, 12, 22}}, {{640, 1700, 2620}, {3, 15, 19}}, {{560, 900, 2940}, {4, 8, 31}}, {{400, 2040, 2600}, {7, 17, 19}}, /* male 10 */ {{360, 900, 2220}, {11, 21, 46}}, {{880, 1400, 2660}, {9, 17, 29}}, {{460, 940, 2400}, {3, 13, 37}}, {{660, 1040, 2660}, {5, 5, 31}}, {{460, 1580, 2360}, {4, 22, 26}}, {{340, 2200, 2920}, {14, 30, 26}}, {{400, 1880, 2800}, {12, 19, 33}}, {{460, 2080, 2800}, {4, 18, 17}}, {{460, 1480, 2260}, {5, 27, 31}}, {{600, 1860, 2640}, {7, 18, 23}}, {{520, 860, 2880}, {2, 24, 32}}, {{460, 2100, 2800}, {6, 19, 22}}, /* male 11 */ {{320, 830, 2060}, {5, 16, 45}}, {{820, 1340, 2200}, {7, 9, 26}}, {{520, 840, 2040}, {7, 13, 31}}, {{660, 1060, 2300}, {8, 9, 28}}, {{440, 1520, 2040}, {7, 16, 22}}, {{300, 2100, 2600}, {5, 23, 30}}, {{300, 1740, 2040}, {2, 17, 19}}, {{340, 2040, 2460}, {5, 20, 24}}, {{500, 1440, 2200}, {8, 17, 21}}, {{600, 1760, 2380}, {10, 15, 19}}, {{560, 900, 2300}, {9, 10, 28}}, {{300, 1960, 2400}, {7, 22, 24}}, /* male 12 */ {{400, 860, 2700}, {7, 15, 46}}, {{940, 1520, 3040}, {10, 19, 33}}, {{580, 1040, 2960}, {5, 17, 42}}, {{860, 1280, 3000}, {8, 19, 34}}, {{480, 1600, 2620}, {7, 15, 32}}, {{300, 2500, 2880}, {3, 29, 29}}, {{300, 1670, 2350}, {3, 31, 39}}, {{480, 2220, 2640}, {7, 30, 31}}, {{380, 1600, 2540}, {4, 22, 33}}, {{630, 2140, 2880}, {7, 27, 27}}, {{640, 900, 3000}, {8, 13, 39}}, {{360, 2220, 2780}, {5, 23, 31}}, /* male 13 */ {{260, 780, 2460}, {5, 20, 44}}, {{900, 1560, 2860}, {9, 13, 26}}, {{440, 850, 2600}, {3, 17, 42}}, {{860, 1140, 2820}, {10, 12, 30}}, {{460, 1580, 2400}, {3, 19, 27}}, {{260, 2560, 3240}, {3, 28, 34}}, {{300, 1960, 2500}, {2, 31, 29}}, {{460, 2320, 2960}, {6, 25, 27}}, {{460, 1600, 2460}, {6, 22, 30}}, {{680, 2100, 2940}, {14, 19, 25}}, {{540, 800, 2740}, {7, 13, 36}}, {{380, 2500, 2980}, {7, 20, 23}}, /* male 14 */ {{340, 720, 2500}, {6, 16, 47}}, {{900, 1500, 3020}, {10, 13, 33}}, {{450, 900, 2700}, {4, 16, 42}}, {{600, 1000, 2720}, {12, 10, 31}}, {{420, 1740, 2560}, {8, 21, 25}}, {{360, 2500, 3000}, {8, 10, 13}}, {{360, 1900, 2420}, {6, 16, 12}}, {{380, 1780, 2420}, {4, 36, 18}}, {{500, 1640, 2620}, {4, 23, 29}}, {{600, 1940, 2700}, {3, 16, 19}}, {{500, 800, 2800}, {3, 10, 38}}, {{400, 2360, 2740}, {7, 13, 27}}, /* male 15 */ {{360, 780, 2320}, {5, 23, 50}}, {{860, 1420, 2420}, {8, 15, 35}}, {{440, 840, 2480}, {9, 20, 38}}, {{660, 980, 2500}, {6, 13, 33}}, {{460, 1660, 2200}, {2, 21, 31}}, {{300, 2360, 2960}, {7, 29, 27}}, {{320, 1740, 2220}, {2, 28, 30}}, {{400, 2240, 2560}, {5, 23, 24}}, {{480, 1420, 2220}, {6, 23, 37}}, {{680, 1640, 2340}, {9, 21, 28}}, {{560, 860, 2780}, {4, 15, 44}}, {{440, 2120, 2500}, {2, 22, 23}}, /* male 16 */ {{360, 760, 2300}, {7, 23, 52}}, {{660, 1000, 2500}, {9, 15, 35}}, {{500, 920, 2520}, {7, 15, 37}}, {{780, 1060, 2380}, {5, 9, 38}}, {{440, 1560, 2260}, {7, 25, 31}}, {{280, 2200, 2880}, {7, 43, 38}}, {{380, 1720, 2200}, {7, 29, 39}}, {{360, 2140, 2620}, {3, 26, 28}}, {{360, 1600, 2400}, {4, 26, 33}}, {{520, 1800, 2480}, {8, 32, 35}}, {{540, 920, 2640}, {6, 20, 44}}, {{340, 2080, 2680}, {3, 28, 27}}, /* male 17 */ {{400, 820, 2200}, {5, 15, 48}}, {{1100, 1480, 2260}, {10, 14, 30}}, {{520, 940, 2560}, {5, 15, 43}}, {{660, 940, 2820}, {11, 11, 35}}, {{500, 1720, 2400}, {5, 19, 23}}, {{360, 2300, 3260}, {11, 25, 17}}, {{360, 2100, 2420}, {10, 19, 20}}, {{440, 2360, 2860}, {6, 20, 25}}, {{500, 1760, 2600}, {6, 15, 25}}, {{660, 1840, 2620}, {7, 17, 24}}, {{540, 860, 2860}, {3, 9, 41}}, {{400, 2440, 3000}, {5, 28, 30}}, /* male 18 */ {{360, 860, 2520}, {6, 15, 35}}, {{740, 1300, 2660}, {7, 9, 22}}, {{460, 800, 2620}, {3, 20, 35}}, {{740, 1040, 2800}, {15, 13, 30}}, {{440, 1400, 2200}, {4, 21, 25}}, {{340, 2040, 2500}, {6, 18, 20}}, {{340, 1340, 2040}, {3, 15, 25}}, {{420, 1760, 2420}, {6, 18, 21}}, {{460, 1380, 2200}, {6, 20, 22}}, {{560, 1640, 2400}, {9, 13, 19}}, {{540, 920, 2520}, {9, 10, 23}}, {{400, 1800, 2400}, {8, 19, 21}}, /* male 19 */ {{320, 840, 2360}, {5, 20, 45}}, {{780, 1140, 2740}, {8, 15, 36}}, {{460, 1020, 2700}, {6, 11, 43}}, {{800, 1100, 2720}, {15, 17, 42}}, {{440, 1500, 2500}, {5, 23, 37}}, {{260, 2000, 2680}, {4, 39, 40}}, {{300, 1540, 2100}, {5, 33, 42}}, {{400, 1900, 2680}, {6, 25, 34}}, {{440, 1500, 2400}, {4, 26, 42}}, {{600, 1700, 2640}, {18, 33, 40}}, {{500, 800, 3000}, {5, 20, 47}}, {{400, 2000, 2500}, {5, 27, 37}}, /* male 20 */ {{400, 960, 2400}, {10, 16, 37}}, {{800, 1220, 2380}, {7, 13, 25}}, {{500, 1080, 2500}, {10, 14, 31}}, {{780, 1100, 2600}, {10, 11, 30}}, {{400, 1480, 2380}, {8, 20, 25}}, {{280, 2380, 2720}, {6, 23, 24}}, {{300, 1760, 2220}, {5, 14, 22}}, {{400, 2000, 2600}, {4, 20, 24}}, {{440, 1500, 2440}, {4, 15, 20}}, {{440, 1800, 2620}, {12, 18, 22}}, {{460, 860, 2600}, {12, 13, 33}}, {{400, 2040, 2640}, {3, 18, 23}}, /* male 21 */ {{300, 700, 2100}, {3, 15, 37}}, {{800, 1100, 2300}, {11, 15, 30}}, {{420, 700, 2440}, {5, 12, 33}}, {{660, 920, 2520}, {6, 9, 32}}, {{400, 1300, 2000}, {2, 22, 30}}, {{300, 1940, 2620}, {5, 25, 24}}, {{260, 1920, 2900}, {4, 21, 31}}, {{300, 1900, 2340}, {4, 20, 24}}, {{400, 1200, 2000}, {4, 20, 29}}, {{540, 1500, 2280}, {4, 15, 22}}, {{400, 740, 2580}, {3, 11, 34}}, {{300, 1900, 2380}, {2, 20, 20}}, /* male 22 */ {{400, 780, 2500}, {6, 14, 40}}, {{760, 1260, 2620}, {6, 14, 30}}, {{540, 860, 2600}, {4, 7, 34}}, {{660, 1100, 2460}, {9, 12, 30}}, {{540, 1460, 2260}, {5, 12, 20}}, {{300, 2300, 2800}, {7, 20, 17}}, {{300, 1980, 2900}, {6, 14, 32}}, {{420, 2100, 2600}, {4, 17, 21}}, {{500, 1440, 2300}, {4, 18, 26}}, {{540, 1900, 2600}, {10, 20, 22}}, {{550, 900, 3000}, {5, 11, 34}}, {{300, 2200, 2700}, {6, 14, 20}}, /* male 23 */ {{360, 900, 2140}, {3, 14, 37}}, {{800, 1250, 2650}, {12, 13, 26}}, {{520, 960, 2200}, {5, 7, 28}}, {{760, 1120, 2700}, {12, 10, 29}}, {{400, 1500, 2160}, {7, 20, 30}}, {{300, 2260, 3000}, {4, 18, 17}}, {{320, 1800, 2500}, {6, 17, 32}}, {{460, 2020, 2800}, {3, 10, 16}}, {{500, 1500, 2300}, {7, 15, 23}}, {{640, 1600, 2500}, {8, 22, 32}}, {{550, 940, 2420}, {7, 12, 40}}, {{460, 2100, 2880}, {2, 21, 24}}, /* male 24 */ {{360, 860, 2460}, {4, 15, 33}}, {{840, 1400, 2500}, {5, 8, 20}}, {{460, 900, 2520}, {1, 8, 31}}, {{620, 1020, 2770}, {7, 6, 26}}, {{410, 1460, 2360}, {2, 11, 18}}, {{270, 2140, 2580}, {2, 15, 21}}, {{300, 1870, 2300}, {1, 11, 16}}, {{360, 2000, 2520}, {2, 17, 19}}, {{400, 1520, 2400}, {2, 12, 17}}, {{600, 1600, 2580}, {3, 12, 20}}, {{500, 900, 2700}, {2, 11, 33}}, {{360, 1940, 2550}, {1, 19, 21}}, /* male 25 */ {{360, 860, 2200}, {8, 22, 46}}, {{880, 1240, 2400}, {7, 14, 25}}, {{460, 920, 3300}, {2, 11, 40}}, {{600, 1000, 2600}, {4, 7, 32}}, {{400, 1440, 2160}, {2, 31, 37}}, {{360, 2240, 2760}, {6, 23, 21}}, {{380, 1660, 2000}, {13, 16, 26}}, {{460, 2000, 2520}, {5, 23, 32}}, {{460, 1500, 2300}, {7, 17, 25}}, {{540, 1700, 2460}, {10, 22, 35}}, {{540, 1000, 2600}, {8, 13, 40}}, {{340, 2040, 2580}, {9, 27, 30}}, /* male 26 */ {{400, 800, 2500}, {6, 23, 42}}, {{960, 1300, 2640}, {9, 8, 29}}, {{460, 860, 2460}, {7, 16, 39}}, {{740, 1140, 2400}, {9, 10, 30}}, {{400, 1600, 2400}, {6, 21, 25}}, {{360, 2500, 2840}, {10, 19, 20}}, {{360, 1800, 2400}, {8, 21, 27}}, {{360, 2080, 2680}, {5, 14, 16}}, {{400, 1620, 2440}, {5, 15, 21}}, {{600, 1940, 2600}, {5, 13, 23}}, {{560, 980, 2900}, {5, 13, 32}}, {{400, 2060, 2540}, {5, 21, 21}}, /* male 27 */ {{300, 900, 2300}, {3, 15, 38}}, {{780, 1300, 2400}, {9, 18, 32}}, {{550, 1000, 2480}, {5, 10, 35}}, {{680, 1050, 2550}, {5, 10, 35}}, {{520, 1480, 2400}, {5, 16, 27}}, {{260, 2180, 2560}, {1, 30, 30}}, {{250, 1720, 2220}, {1, 26, 32}}, {{360, 2100, 2650}, {4, 31, 25}}, {{440, 1440, 2440}, {4, 21, 26}}, {{600, 1600, 2500}, {5, 15, 27}}, {{560, 950, 2700}, {3, 10, 40}}, {{360, 1900, 2600}, {3, 26, 31}}, /* male 28 */ {{280, 740, 2500}, {3, 20, 45}}, {{780, 1300, 2840}, {4, 12, 25}}, {{440, 860, 2860}, {5, 13, 41}}, {{440, 700, 3040}, {9, 10, 37}}, {{450, 1520, 2320}, {2, 25, 30}}, {{220, 2340, 2960}, {1, 35, 36}}, {{240, 1800, 2140}, {3, 36, 37}}, {{300, 2200, 2600}, {4, 28, 33}}, {{440, 1500, 2480}, {3, 26, 37}}, {{500, 1660, 2620}, {10, 30, 38}}, {{420, 700, 3000}, {4, 12, 35}}, {{300, 2140, 2760}, {6, 32, 31}}, /* male 29 */ {{340, 660, 2320}, {4, 13, 37}}, {{640, 1250, 2480}, {10, 16, 29}}, {{560, 1000, 2480}, {10, 14, 31}}, {{720, 1150, 2600}, {10, 13, 26}}, {{480, 1400, 2160}, {9, 22, 28}}, {{300, 2040, 2640}, {5, 20, 22}}, {{280, 1540, 1960}, {3, 21, 23}}, {{460, 1760, 2320}, {7, 19, 20}}, {{440, 1550, 2200}, {8, 16, 23}}, {{480, 1660, 1960}, {10, 16, 23}}, {{480, 840, 2840}, {9, 12, 28}}, {{400, 1780, 2360}, {7, 20, 23}}, /* male 30 */ {{360, 800, 2540}, {1, 11, 40}}, {{600, 1300, 2600}, {6, 8, 27}}, {{500, 860, 2440}, {2, 7, 36}}, {{750, 1140, 2640}, {4, 9, 30}}, {{460, 1400, 2340}, {1, 23, 28}}, {{340, 2300, 2620}, {2, 26, 25}}, {{300, 1540, 2300}, {5, 25, 35}}, {{440, 2000, 2540}, {1, 14, 19}}, {{440, 1360, 2360}, {1, 19, 26}}, {{620, 1840, 2560}, {3, 18, 23}}, {{520, 820, 2680}, {2, 7, 34}}, {{420, 2000, 2640}, {1, 20, 25}}, /*L2 (10) corrected 20021211 */ /* male 31 */ {{340, 740, 2240}, {5, 15, 44}}, {{820, 1200, 2250}, {5, 17, 40}}, {{440, 820, 2540}, {3, 13, 37}}, {{760, 1060, 2340}, {8, 15, 42}}, {{460, 1540, 2380}, {3, 21, 25}}, {{280, 2260, 2620}, {8, 31, 32}}, {{300, 1800, 2220}, {6, 36, 37}}, {{460, 1900, 2260}, {3, 34, 31}}, {{380, 1540, 2400}, {15, 36, 40}}, {{500, 1740, 2400}, {4, 26, 39}}, {{460, 840, 2580}, {7, 28, 35}}, {{320, 2100, 2460}, {7, 30, 27}}, /* male 32 */ {{360, 900, 2200}, {5, 18, 39}}, {{640, 1280, 2340}, {7, 15, 26}}, {{460, 920, 2360}, {7, 14, 33}}, {{720, 1200, 2580}, {11, 14, 26}}, {{420, 1520, 2260}, {6, 17, 23}}, {{400, 2000, 2560}, {5, 15, 20}}, {{380, 1700, 2100}, {6, 18, 21}}, {{440, 1740, 2420}, {4, 14, 17}}, {{500, 1520, 2440}, {5, 14, 21}}, {{580, 1540, 2460}, {5, 12, 24}}, {{580, 1020, 2700}, {9, 13, 30}}, {{460, 1720, 2400}, {7, 22, 20}}, /* male 33 */ {{400, 700, 2600}, {4, 17, 45}}, {{900, 1440, 2600}, {10, 17, 36}}, {{460, 860, 2600}, {7, 18, 45}}, {{680, 1000, 2200}, {7, 13, 39}}, {{460, 1600, 2540}, {5, 28, 37}}, {{300, 2260, 2880}, {7, 28, 26}}, {{320, 1860, 2200}, {7, 22, 28}}, {{440, 2180, 2660}, {3, 24, 28}}, {{380, 1560, 2360}, {8, 26, 33}}, {{620, 1720, 2060}, {6, 21, 28}}, {{600, 860, 2900}, {12, 18, 37}}, {{440, 2040, 2600}, {4, 26, 30}}, /* male 34 */ {{370, 900, 2230}, {3, 17, 35}}, {{700, 1200, 2580}, {12, 17, 30}}, {{500, 840, 2460}, {4, 13, 37}}, {{720, 1080, 2640}, {7, 13, 37}}, {{440, 1300, 2220}, {4, 20, 31}}, {{300, 2040, 2580}, {7, 25, 25}}, {{320, 1540, 2080}, {8, 21, 23}}, {{380, 1860, 2450}, {7, 24, 33}}, {{460, 1200, 2360}, {3, 20, 30}}, {{580, 1500, 2380}, {9, 22, 25}}, {{480, 820, 2580}, {8, 15, 32}}, {{400, 1800, 2360}, {6, 23, 26}}, /* male 35 */ {{280, 1040, 2340}, {7, 26, 41}}, {{820, 1300, 2760}, {10, 15, 32}}, {{440, 1220, 2580}, {6, 18, 29}}, {{600, 1040, 2540}, {8, 13, 27}}, {{420, 1560, 2480}, {6, 22, 26}}, {{300, 2160, 2700}, {5, 29, 30}}, {{250, 1760, 2320}, {9, 30, 38}}, {{440, 1940, 2550}, {5, 25, 28}}, {{400, 1600, 2460}, {8, 26, 29}}, {{580, 1820, 2460}, {5, 23, 30}}, {{460, 860, 2660}, {5, 21, 37}}, {{400, 2100, 2640}, {8, 27, 27}}, /* male 36 */ {{360, 740, 2160}, {2, 21, 40}}, {{660, 1260, 2540}, {10, 18, 21}}, {{500, 900, 2600}, {9, 20, 30}}, {{640, 1000, 2880}, {11, 17, 29}}, {{460, 1300, 2140}, {8, 19, 25}}, {{300, 1900, 2580}, {11, 18, 22}}, {{320, 1660, 2060}, {9, 17, 20}}, {{400, 1780, 2320}, {8, 20, 21}}, {{380, 1360, 2200}, {6, 20, 25}}, {{540, 1600, 2260}, {8, 21, 22}}, {{540, 860, 2720}, {7, 20, 32}}, {{400, 1740, 2340}, {5, 22, 23}}, /* male 37 */ {{300, 900, 2140}, {5, 21, 39}}, {{700, 1240, 2460}, {10, 18, 28}}, {{480, 960, 2140}, {4, 12, 32}}, {{640, 1120, 2480}, {9, 14, 32}}, {{460, 1520, 2160}, {4, 18, 25}}, {{320, 2120, 2600}, {10, 20, 26}}, {{320, 1800, 2200}, {8, 25, 27}}, {{320, 1920, 2460}, {8, 21, 27}}, {{480, 1460, 2260}, {5, 22, 27}}, {{600, 1600, 2480}, {7, 17, 24}}, {{500, 950, 2450}, {4, 14, 38}}, {{460, 1820, 2480}, {6, 18, 26}}, /* male 38 */ {{320, 760, 2080}, {11, 23, 41}}, {{840, 1180, 2700}, {13, 20, 37}}, {{500, 920, 2400}, {13, 17, 37}}, {{660, 1060, 2700}, {13, 17, 36}}, {{440, 1400, 2220}, {5, 32, 37}}, {{280, 2240, 2700}, {14, 29, 35}}, {{300, 1640, 2080}, {12, 31, 31}}, {{440, 2040, 2600}, {11, 19, 24}}, {{400, 1460, 2160}, {8, 32, 38}}, {{580, 1700, 1900}, {13, 26, 26}}, {{500, 840, 2920}, {10, 18, 40}}, {{360, 2060, 2440}, {7, 21, 27}}, /* male 39 */ {{320, 760, 2480}, {9, 21, 46}}, {{700, 1420, 2680}, {9, 16, 31}}, {{500, 940, 2500}, {4, 16, 41}}, {{700, 1060, 2720}, {8, 10, 38}}, {{440, 1580, 2260}, {11, 34, 39}}, {{260, 2200, 2700}, {5, 29, 32}}, {{200, 1600, 2060}, {7, 33, 34}}, {{400, 2200, 2600}, {13, 29, 31}}, {{380, 1500, 2220}, {8, 25, 37}}, {{540, 1750, 2420}, {8, 23, 32}}, {{520, 820, 2560}, {10, 19, 43}}, {{400, 1700, 2320}, {3, 38, 23}}, /* male 40 */ {{300, 680, 1920}, {7, 28, 48}}, {{740, 1200, 2550}, {8, 10, 24}}, {{420, 860, 2420}, {7, 17, 37}}, {{640, 1120, 2500}, {12, 17, 37}}, {{360, 1500, 2180}, {3, 27, 35}}, {{280, 2160, 2920}, {4, 27, 31}}, {{260, 1560, 2050}, {2, 26, 27}}, {{360, 2020, 2500}, {4, 26, 28}}, {{440, 1400, 2320}, {4, 21, 32}}, {{460, 1660, 2460}, {5, 19, 27}}, {{500, 840, 2580}, {6, 14, 35}}, {{360, 1920, 2560}, {3, 31, 31}}, /* male 41 */ {{360, 880, 2320}, {2, 12, 43}}, {{840, 1200, 2500}, {12, 17, 37}}, {{580, 1060, 2300}, {11, 10, 32}}, {{580, 1100, 2680}, {8, 12, 33}}, {{560, 1600, 2200}, {9, 22, 27}}, {{300, 2260, 2800}, {5, 25, 26}}, {{320, 1760, 2100}, {5, 23, 25}}, {{500, 2020, 2660}, {5, 17, 21}}, {{420, 1520, 2320}, {1, 20, 28}}, {{700, 1800, 2620}, {8, 17, 22}}, {{540, 860, 2720}, {7, 13, 35}}, {{420, 2080, 2600}, {4, 21, 25}}, /* male 42 */ {{420, 800, 2400}, {5, 15, 40}}, {{800, 1400, 2900}, {9, 16, 41}}, {{420, 820, 2480}, {5, 8, 40}}, {{600, 1200, 2760}, {6, 12, 34}}, {{400, 1560, 2120}, {2, 20, 31}}, {{320, 2360, 2820}, {8, 25, 27}}, {{340, 1680, 2240}, {9, 19, 35}}, {{400, 2180, 2760}, {2, 19, 20}}, {{400, 1440, 2360}, {3, 15, 26}}, {{700, 1700, 2340}, {11, 18, 29}}, {{500, 780, 2840}, {7, 14, 38}}, {{380, 2120, 2720}, {2, 21, 25}}, /* male 43 */ {{300, 760, 2020}, {3, 16, 38}}, {{740, 1200, 2360}, {8, 15, 29}}, {{460, 860, 2200}, {8, 12, 39}}, {{620, 900, 2500}, {8, 12, 27}}, {{400, 1340, 2100}, {7, 20, 31}}, {{240, 2000, 2340}, {2, 22, 28}}, {{240, 1580, 1860}, {3, 16, 24}}, {{360, 1640, 2080}, {5, 19, 26}}, {{400, 1340, 2060}, {3, 16, 28}}, {{580, 1400, 2120}, {6, 13, 24}}, {{500, 800, 2460}, {6, 6, 31}}, {{440, 1720, 2100}, {7, 19, 24}}, /* male 44 */ {{260, 800, 2400}, {3, 16, 48}}, {{780, 1300, 2700}, {6, 14, 28}}, {{480, 900, 2500}, {5, 8, 35}}, {{620, 1000, 2820}, {5, 9, 28}}, {{420, 1400, 2300}, {3, 18, 29}}, {{240, 2040, 2680}, {1, 31, 28}}, {{260, 1580, 2260}, {3, 31, 28}}, {{380, 2000, 2600}, {5, 29, 26}}, {{420, 1420, 2400}, {2, 21, 26}}, {{540, 1640, 2440}, {5, 19, 26}}, {{480, 840, 2800}, {6, 13, 32}}, {{280, 1960, 2560}, {5, 27, 28}}, /* male 45 */ {{300, 840, 3060}, {3, 10, 38}}, {{800, 1220, 2280}, {6, 10, 26}}, {{500, 920, 2120}, {6, 8, 31}}, {{700, 1020, 2600}, {3, 11, 28}}, {{400, 1260, 2020}, {6, 17, 24}}, {{260, 1960, 2440}, {1, 22, 22}}, {{300, 1480, 1940}, {2, 18, 22}}, {{440, 1880, 2380}, {6, 17, 17}}, {{320, 1400, 2140}, {5, 18, 27}}, {{500, 1560, 2300}, {7, 18, 22}}, {{540, 780, 2400}, {8, 13, 34}}, {{360, 1860, 2300}, {4, 20, 21}}, /* male 46 */ {{320, 860, 2380}, {3, 19, 41}}, {{660, 1400, 2540}, {11, 20, 27}}, {{520, 940, 2580}, {7, 11, 34}}, {{700, 1040, 2720}, {4, 8, 23}}, {{400, 1600, 2280}, {2, 27, 29}}, {{320, 2340, 3140}, {3, 33, 29}}, {{300, 1860, 2160}, {2, 25, 25}}, {{420, 2200, 2760}, {1, 17, 23}}, {{460, 2320, 3360}, {2, 33, 37}}, {{500, 2100, 2760}, {6, 23, 38}}, {{600, 920, 2700}, {8, 17, 29}}, {{420, 2200, 2740}, {3, 30, 32}}, /* male 47 */ {{360, 800, 2120}, {3, 18, 33}}, {{700, 1220, 2760}, {6, 13, 27}}, {{540, 940, 2640}, {2, 8, 33}}, {{620, 1080, 2800}, {4, 10, 33}}, {{500, 1400, 2200}, {6, 18, 25}}, {{320, 2240, 2940}, {2, 22, 27}}, {{320, 1800, 2100}, {1, 26, 27}}, {{420, 2040, 2400}, {3, 19, 24}}, {{460, 1440, 2140}, {1, 13, 25}}, {{600, 1600, 2520}, {6, 13, 27}}, {{560, 700, 2780}, {5, 11, 31}}, {{440, 1920, 2560}, {3, 22, 24}}, /* male 48 */ {{300, 760, 1900}, {3, 17, 42}}, {{800, 1260, 2740}, {7, 10, 28}}, {{460, 840, 1840}, {4, 13, 38}}, {{540, 900, 2400}, {10, 14, 28}}, {{420, 1380, 2100}, {2, 16, 29}}, {{220, 2080, 2900}, {2, 28, 21}}, {{220, 1760, 2120}, {1, 22, 25}}, {{440, 2060, 2780}, {1, 19, 21}}, {{440, 1440, 2560}, {3, 19, 31}}, {{580, 1400, 2100}, {5, 15, 22}}, {{520, 900, 2300}, {3, 10, 32}}, {{420, 1720, 2720}, {6, 22, 21}}, /* male 49 */ {{320, 1000, 2220}, {3, 24, 43}}, {{700, 1280, 2500}, {3, 13, 30}}, {{460, 1060, 2380}, {4, 13, 31}}, {{620, 1100, 2840}, {10, 18, 33}}, {{340, 1440, 2260}, {4, 21, 30}}, {{280, 2140, 2580}, {3, 31, 32}}, {{280, 1820, 2220}, {2, 36, 35}}, {{340, 2100, 2500}, {2, 29, 31}}, {{380, 1460, 2400}, {2, 26, 38}}, {{500, 1640, 2500}, {7, 27, 31}}, {{500, 960, 2720}, {4, 17, 31}}, {{420, 1960, 2700}, {1, 32, 32}}, /* male 50 */ {{340, 780, 2020}, {11, 22, 36}}, {{660, 1220, 2500}, {9, 14, 22}}, {{420, 760, 2440}, {2, 17, 33}}, {{560, 1000, 2600}, {6, 13, 25}}, {{400, 1320, 2120}, {8, 18, 21}}, {{300, 1860, 2440}, {6, 22, 22}}, {{280, 1600, 1900}, {6, 16, 19}}, {{340, 1740, 2260}, {3, 12, 17}}, {{400, 1360, 2160}, {4, 16, 22}}, {{520, 1580, 2240}, {2, 12, 16}}, {{380, 800, 2560}, {7, 11, 25}}, {{360, 1740, 2260}, {5, 14, 17}}, /* 25*12 females */ {{250, 800, 2450}, {0, 8, 45}}, /* poet */ {{950, 1500, 2650}, {5, 14, 30}}, /* paat */ {{500, 1050, 2600}, {3, 5, 38}}, /* poot */ {{720, 1100, 2950}, {8, 2, 24}}, /* pat */ {{500, 1800, 2500}, {6, 14, 30}}, /* peut */ {{280, 2500, 3100}, {0, 32, 26}}, /* piet */ {{250, 1700, 2200}, {0, 18, 21}}, /* puut */ {{500, 2350, 2750}, {2, 12, 12}}, /* peet */ {{520, 1550, 2400}, {4, 15, 27}}, /* put */ {{750, 2000, 2600}, {4, 20, 20}}, /* pet */ {{550, 900, 2800}, {6, 3, 34}}, /* pot */ {{480, 2150, 2650}, {5, 20, 22}}, /* pit */ /* female 2 */ {{300, 750, 2700}, {0, 10, 50}}, {{1100, 1500, 3000}, {6, 9, 28}}, /* djmw 20021212 L3 (was 20) */ {{520, 900, 2800}, {2, 8, 30}}, {{800, 1150, 3000}, {2, 12, 34}}, /* djmw 20021212 F3 (was 300 in Van Nierop data!)*/ {{450, 1600, 2950}, {2, 22, 31}}, {{250, 2700, 3300}, {0, 27, 31}}, {{300, 1900, 2650}, {0, 23, 33}}, {{550, 2300, 3000}, {0, 17, 22}}, {{450, 1900, 2800}, {0, 20, 32}}, {{700, 2150, 3100}, {0, 22, 30}}, {{600, 950, 2800}, {0, 10, 40}}, {{350, 2450, 2900}, {0, 27, 28}}, /* female 3 */ {{350, 800, 2700}, {0, 19, 50}}, {{1000, 1450, 2800}, {7, 7, 34}}, {{500, 1000, 2600}, {4, 11, 45}}, {{650, 1000, 2700}, {7, 1, 29}}, {{460, 1650, 2400}, {2, 21, 35}}, {{250, 2450, 2900}, {0, 30, 26}}, {{250, 1750, 2500}, {0, 22, 31}}, {{480, 2600, 3600}, {4, 22, 33}}, {{450, 1650, 2600}, {2, 16, 32}}, {{650, 2450, 2800}, {6, 19, 20}}, {{650, 1050, 2800}, {1, 10, 42}}, {{350, 2600, 3200}, {0, 24, 35}}, /* female 4 */ {{350, 750, 2500}, {1, 10, 36}}, {{1000, 1550, 2900}, {6, 14, 18}}, {{450, 950, 2450}, {2, 6, 30}}, {{800, 1100, 3200}, {6, 6, 26}}, {{450, 1900, 2400}, {3, 14, 14}}, {{250, 2450, 3050}, {0, 15, 22}}, {{300, 1900, 2350}, {0, 12, 15}}, {{450, 2250, 2850}, {3, 16, 12}}, {{430, 1700, 2650}, {2, 12, 17}}, {{600, 2250, 2950}, {4, 12, 15}}, {{600, 850, 3200}, {4, 3, 30}}, {{430, 2500, 3000}, {2, 16, 24}}, /* female 5 */ {{300, 900, 2700}, {0, 12, 42}}, {{750, 1600, 2800}, {2, 15, 24}}, {{480, 950, 2600}, {2, 13, 32}}, {{800, 1200, 2900}, {3, 13, 30}}, {{430, 1500, 2600}, {1, 20, 25}}, {{250, 2800, 3150}, { -1, 22, 32}}, {{300, 1400, 2500}, {0, 24, 28}}, {{420, 2400, 2900}, {2, 27, 27}}, {{500, 1650, 2850}, {1, 16, 25}}, {{750, 1900, 3000}, {4, 25, 30}}, {{600, 1200, 2850}, {3, 17, 23}}, {{490, 1950, 2900}, {2, 29, 28}}, /* female 6 */ {{300, 750, 2350}, {2, 8, 37}}, /* djmw 20021212 L2 (was 0) */ {{950, 1400, 2400}, {2, 12, 23}}, {{650, 1100, 2200}, {4, 8, 34}}, /* djmw 20021212 L2 (was 0) */ {{900, 1100, 2600}, {2, 6, 26}}, /* djmw 20021212 L3 (was 20) */ {{490, 1700, 2400}, {1, 18, 24}}, /* djmw 20021212 L2 (was 14) */ {{300, 2500, 2800}, {0, 16, 21}}, {{300, 1800, 2400}, {0, 10, 14}}, {{470, 2400, 2750}, {2, 17, 19}}, {{570, 1750, 2550}, {0, 17, 18}}, /* djmw 20021212 L3 (was 19) */ {{700, 1750, 2400}, {0, 10, 16}}, {{600, 1200, 2500}, {0, 18, 28}}, /* djmw 20021212 L2,3 (was 10,20) */ {{440, 2250, 2700}, {0, 17, 18}}, /* female 7 */ {{350, 850, 2600}, { -1, 16, 38}}, {{950, 1200, 2900}, {7, 9, 40}}, {{550, 1050, 2500}, {2, 6, 38}}, {{850, 1200, 2800}, { -1, 12, 39}}, {{440, 1800, 2500}, {0, 24, 30}}, {{300, 2300, 3000}, { -1, 22, 30}}, {{350, 1850, 2400}, { -1, 23, 27}}, {{460, 2400, 2900}, {1, 28, 30}}, /* djmw 20021212 L2 (was 20) */ {{490, 1650, 2700}, {1, 22, 28}}, {{650, 1700, 2750}, {2, 28, 28}}, /* djmw 20021212 L2 (was 20) */ {{450, 700, 3000}, {6, 2, 33}}, /* djmw 20021212 L2 (was 8) */ {{440, 2550, 3000}, {1, 40, 41}}, /* female 8 */ {{350, 1000, 2500}, {2, 19, 40}}, {{950, 1400, 2700}, {8, 14, 29}}, {{500, 950, 2450}, {6, 10, 34}}, {{850, 1230, 2950}, {8, 19, 42}}, {{520, 1650, 2600}, {6, 22, 28}}, {{250, 2500, 3000}, {0, 25, 30}}, {{250, 1750, 2300}, {0, 23, 29}}, {{510, 2250, 2850}, {4, 30, 24}}, {{650, 1600, 2600}, {6, 18, 26}}, {{720, 1750, 2650}, {4, 19, 27}}, {{750, 1150, 2650}, {2, 15, 37}}, {{510, 2050, 2950}, {2, 22, 23}}, /* female 9 */ {{300, 850, 2650}, {0, 14, 43}}, {{950, 1350, 2700}, {4, 6, 25}}, {{550, 900, 2700}, {5, 4, 37}}, {{930, 1300, 2800}, {0, 15, 35}}, {{550, 1500, 2400}, {0, 10, 22}}, {{280, 2450, 3000}, {0, 13, 21}}, {{300, 1650, 2400}, {0, 26, 32}}, {{530, 2400, 3000}, {0, 4, 14}}, {{600, 1600, 2000}, {0, 14, 16}}, {{850, 1950, 2800}, {1, 12, 19}}, {{750, 1050, 2900}, {2, 4, 32}}, {{550, 2300, 2800}, {1, 14, 22}}, /* female 10 */ {{350, 800, 2500}, {0, 21, 44}}, {{1100, 1450, 2900}, {5, 9, 31}}, {{400, 850, 2600}, {0, 5, 46}}, {{750, 1050, 2950}, {4, 9, 25}}, {{420, 1650, 2550}, {0, 17, 38}}, {{300, 2450, 3050}, { -1, 28, 35}}, {{280, 1850, 2500}, { -1, 20, 30}}, {{420, 2400, 2800}, {1, 25, 29}}, {{420, 1500, 2350}, {0, 22, 34}}, {{650, 1850, 2800}, {2, 28, 31}}, {{550, 800, 2800}, {4, 7, 44}}, {{420, 2350, 2750}, {2, 27, 28}}, /* female 11 */ {{300, 800, 2850}, { -1, 22, 54}}, {{1150, 1550, 2850}, {6, 9, 26}}, {{600, 1000, 2700}, {3, 9, 30}}, {{750, 1100, 2700}, {2, 10, 34}}, {{500, 1800, 2550}, {3, 17, 24}}, {{250, 2400, 3100}, {0, 27, 35}}, {{250, 2000, 3650}, {0, 30, 36}}, {{420, 2400, 2900}, {5, 28, 31}}, /* djmw 20021212 L2,3 (was 20,34) */ {{470, 1700, 2500}, {4, 26, 37}}, /* djmw 20021212 L2 (was 20) */ {{700, 1880, 2650}, {2, 21, 26}}, {{650, 900, 2650}, {5, 4, 33}}, {{490, 2250, 2650}, {3, 22, 26}}, /* female 12 */ {{300, 900, 2500}, { -1, 20, 39}}, {{950, 1500, 2700}, {3, 16, 20}}, {{450, 1000, 2650}, {2, 8, 35}}, {{600, 1050, 2800}, {4, 4, 33}}, {{420, 1650, 2500}, {1, 14, 22}}, {{250, 2300, 2850}, {0, 30, 24}}, {{300, 1800, 2300}, { -1, 21, 28}}, {{400, 2100, 2700}, {0, 29, 20}}, {{420, 1650, 2450}, {0, 17, 28}}, {{550, 1800, 2650}, {2, 19, 20}}, {{450, 1050, 2800}, {2, 10, 26}}, {{420, 1850, 2700}, {0, 27, 26}}, /* female 13 */ {{300, 850, 2800}, {0, 19, 47}}, {{1100, 1400, 2800}, {6, 10, 25}}, {{550, 900, 2900}, {2, 16, 44}}, {{700, 1050, 2750}, {4, 6, 33}}, {{490, 1700, 2500}, {0, 33, 35}}, {{300, 2500, 2950}, {0, 40, 35}}, {{300, 1900, 2450}, {0, 24, 36}}, {{500, 2500, 3000}, {4, 31, 32}}, {{460, 1450, 2500}, {6, 33, 38}}, {{700, 1700, 2700}, {1, 18, 30}}, {{500, 800, 2700}, {2, 6, 38}}, {{550, 2250, 2750}, {3, 28, 26}}, /* female 14 */ {{350, 900, 3600}, {0, 16, 44}}, {{950, 1420, 2950}, {5, 7, 26}}, {{400, 1000, 2400}, {0, 12, 36}}, {{600, 950, 2650}, {4, 7, 31}}, {{420, 1400, 2500}, {1, 21, 24}}, {{300, 2500, 2850}, {0, 26, 27}}, {{250, 1450, 2200}, {0, 29, 36}}, {{420, 1950, 2700}, {0, 20, 20}}, {{410, 1550, 2400}, {0, 20, 28}}, {{600, 1650, 2600}, {3, 9, 21}}, {{430, 880, 2950}, {2, 6, 32}}, {{410, 1950, 2250}, {0, 31, 30}}, /* female 15 */ {{350, 1000, 2350}, {0, 29, 41}}, {{850, 1100, 2800}, {2, 5, 25}}, {{600, 1000, 2800}, {2, 6, 30}}, {{850, 1400, 2600}, {1, 20, 31}}, {{470, 2000, 2550}, {2, 16, 18}}, {{250, 2650, 3250}, {0, 31, 40}}, {{300, 2000, 2400}, {0, 23, 24}}, {{430, 2400, 2900}, {1, 22, 27}}, {{460, 1900, 2500}, {2, 25, 28}}, {{650, 1900, 2900}, {2, 19, 23}}, {{600, 900, 2400}, {3, 7, 35}}, {{460, 2400, 2900}, {1, 26, 27}}, /* female 16 */ {{300, 850, 3300}, {0, 20, 52}}, {{1050, 1400, 2450}, {6, 8, 31}}, {{500, 950, 2400}, {4, 10, 44}}, {{850, 1050, 2850}, {6, 7, 37}}, {{480, 1650, 2300}, {2, 14, 32}}, {{300, 3000, 4200}, {0, 32, 36}}, {{300, 1900, 2450}, {0, 27, 37}}, {{460, 2450, 3000}, {1, 32, 30}}, {{500, 1550, 3100}, {2, 18, 40}}, {{650, 1800, 2700}, {2, 22, 32}}, {{450, 750, 2850}, {4, 2, 38}}, {{440, 2200, 2900}, {0, 30, 29}}, /* female 17 */ {{320, 850, 2500}, {0, 18, 50}}, /* djmw 20021212 L2 (was 10) */ {{1100, 1350, 2900}, {7, 9, 25}}, {{450, 900, 2600}, {2, 8, 39}}, /* djmw 20021212 L3 (was 30) */ {{800, 1200, 2800}, {2, 14, 32}}, {{480, 1800, 2500}, {2, 24, 29}}, {{300, 2600, 3000}, {0, 32, 32}}, {{300, 1900, 2400}, {0, 25, 28}}, {{460, 2300, 2900}, {2, 26, 29}}, {{480, 1800, 2650}, {2, 27, 28}}, /* djmw 20021212 L3 (was 20) */ {{650, 1850, 3000}, {4, 22, 34}}, {{550, 800, 2850}, {4, 4, 30}}, {{470, 2200, 3000}, {2, 28, 33}}, /* djmw 20021212 L2 (was 20) */ /* female 18 */ {{350, 750, 2550}, {0, 14, 48}}, /* djmw 20021212 L3 (was 40) */ {{1050, 1700, 2850}, {0, 14, 22}}, {{550, 1000, 2600}, {3, 4, 32}}, {{750, 1150, 2950}, {5, 3, 30}}, {{550, 1750, 2600}, {2, 12, 19}}, {{300, 2400, 3000}, {0, 21, 22}}, {{300, 1950, 2500}, {0, 18, 22}}, {{510, 2200, 3000}, {1, 24, 27}}, {{490, 1750, 2450}, {2, 23, 29}}, {{600, 2200, 3000}, {3, 14, 23}}, {{700, 850, 2900}, {6, 6, 38}}, {{540, 2200, 3000}, {9, 22, 22}}, /* female 19 */ {{350, 950, 2800}, {0, 24, 51}}, {{1000, 1500, 2900}, {6, 10, 26}}, {{450, 950, 2800}, {2, 16, 48}}, {{700, 1050, 3000}, {5, 5, 35}}, {{450, 1700, 2450}, {4, 23, 28}}, {{250, 2600, 3000}, {0, 28, 34}}, {{330, 1900, 2700}, {0, 30, 42}}, {{520, 2500, 2900}, {2, 28, 30}}, {{450, 1700, 2800}, {1, 24, 30}}, {{700, 1850, 3000}, {2, 23, 24}}, {{600, 900, 3150}, {2, 12, 38}}, {{490, 2400, 3100}, {2, 35, 31}}, /* female 20 */ {{300, 950, 2650}, {1, 21, 29}}, {{680, 1250, 2600}, {3, 23, 50}}, {{400, 850, 2700}, {3, 16, 44}}, {{500, 1050, 3000}, {4, 13, 42}}, {{390, 1550, 2500}, {2, 28, 35}}, {{250, 2300, 2900}, {0, 36, 38}}, {{250, 1950, 3600}, {0, 34, 45}}, {{420, 2100, 2600}, {2, 25, 34}}, {{420, 2100, 2600}, {2, 26, 34}}, {{600, 1500, 2800}, {5, 25, 36}}, {{450, 750, 2800}, {2, 11, 48}}, {{440, 2050, 2700}, {1, 27, 38}}, /* female 21 */ {{330, 750, 2900}, {1, 8, 44}}, {{1150, 1500, 2750}, {3, 8, 35}}, {{530, 950, 2850}, {0, 8, 40}}, {{850, 1050, 3000}, {5, 5, 36}}, {{500, 1700, 2700}, {0, 20, 31}}, {{300, 2600, 3100}, { -1, 23, 28}}, {{300, 1800, 2400}, {0, 22, 27}}, {{520, 2550, 3050}, {0, 22, 26}}, {{520, 1650, 2550}, {0, 20, 28}}, {{700, 1850, 2900}, {0, 16, 24}}, {{650, 1100, 2900}, { -1, 11, 36}}, {{450, 2300, 2800}, {0, 16, 17}}, /* female 22 */ {{300, 850, 2800}, {0, 15, 42}}, {{1080, 1400, 2750}, {2, 3, 21}}, {{480, 950, 2300}, {0, 6, 30}}, {{800, 1100, 2800}, {3, 3, 28}}, {{470, 1800, 2500}, {0, 12, 23}}, {{300, 2350, 2850}, { -1, 31, 31}}, {{300, 2100, 2600}, { -1, 25, 31}}, {{460, 2600, 2900}, {0, 20, 23}}, {{470, 1800, 2500}, {0, 16, 29}}, {{600, 2000, 2700}, {2, 13, 11}}, {{500, 750, 2650}, {4, 2, 24}}, {{500, 2300, 2750}, {0, 20, 22}}, /* female 23 */ {{350, 700, 2800}, {0, 10, 46}}, {{950, 1500, 2900}, {0, 19, 23}}, {{530, 980, 2850}, {0, 14, 34}}, {{750, 1100, 3000}, {4, 1, 27}}, {{520, 1800, 2450}, {2, 20, 25}}, {{300, 2550, 2950}, {0, 22, 24}}, {{300, 1950, 2450}, {0, 30, 31}}, {{500, 2300, 2800}, {0, 21, 29}}, {{550, 1700, 2750}, {0, 21, 24}}, {{650, 1850, 2700}, { -1, 16, 20}}, {{650, 980, 2650}, {1, 4, 34}}, {{500, 2400, 2800}, {4, 16, 18}}, /* female 24 */ {{300, 900, 2900}, {0, 12, 45}}, {{900, 1650, 2850}, {1, 6, 23}}, {{500, 900, 2300}, {0, 4, 39}}, {{750, 1150, 2750}, {2, 6, 27}}, {{550, 1650, 2500}, {0, 16, 24}}, {{300, 2500, 2850}, {0, 27, 34}}, {{250, 1850, 2300}, {0, 30, 26}}, {{490, 2400, 2850}, {2, 16, 18}}, {{520, 1800, 2450}, {3, 22, 23}}, {{650, 2100, 2800}, {2, 14, 13}}, {{550, 1100, 3900}, {2, 11, 32}}, {{510, 2350, 2950}, {1, 24, 23}}, /* djmw 20021212 L3 (was 33) */ /* female 25 */ {{300, 800, 3700}, {0, 13, 50}}, /* djmw 20021212 L2 (was 17) */ {{1000, 1450, 2650}, {4, 7, 24}}, {{550, 1000, 2850}, {8, 10, 43}}, {{750, 1050, 3000}, {2, 6, 33}}, {{500, 1550, 2400}, {4, 16, 25}}, {{250, 2400, 2950}, {0, 26, 24}}, {{300, 1800, 2400}, {0, 26, 26}}, {{490, 2300, 2800}, {8, 15, 20}}, {{550, 1550, 2500}, {1, 14, 25}}, {{700, 1950, 2750}, {0, 4, 13}}, {{630, 980, 2850}, {5, 7, 39}}, {{490, 2300, 2900}, {4, 17, 22}} }; try { autoTable me = Table_create (nrows, ncols); for (long i = 1; i <= nrows; i++) { TableRow row = (TableRow) my rows -> item[i]; int vowel_id = ( (i - 1) % 12) + 1; /* 1 - 12 */ int speaker_id = (i - 1) / 12 + 1; /* 1 - 75 */ int speaker_sex = speaker_id <= 50 ? 0 : 1; row -> cells [1]. string = Melder_dup_f (sex [speaker_sex]); row -> cells [2]. string = Melder_dup_f (Melder_integer (speaker_id)); row -> cells [3]. string = Melder_dup_f (vowel [vowel_id - 1]); row -> cells [4]. string = Melder_dup_f (ipa [vowel_id - 1]); for (long j = 0; j <= 2; j++) { row -> cells [j + 5]. string = Melder_dup_f (Melder_integer (polsdata[i - 1].f[j])); row -> cells [j + 8]. string = Melder_dup_f (Melder_integer (polsdata[i - 1].l[j])); } } for (long j = 1; j <= ncols; j++) { Table_setColumnLabel (me.peek(), j, columnLabels[j - 1]); my columnHeaders [j]. numericized = false; } return me.transfer(); } catch (MelderError) { Melder_throw (U"Table not created from Pols & van Nierop data."); } } Table Table_createFromWeeninkData () { long nrows = 360, ncols = 9; const char32 *columnLabels[9] = {U"Type", U"Sex", U"Speaker", U"Vowel", U"IPA", U"F0", U"F1", U"F2", U"F3"}; const char32 *type[3] = {U"m", U"w", U"c"}; /* Our order: "oe", "o", "oo", "a", "aa", "u", "eu", "uu", "ie", "i", "ee", "e" to Pols & van Nierop order */ int order[13] = { 0, 1, 5, 3, 4, 7, 9, 8, 11, 6, 12, 2, 10}; const char32 *vowel[13] = {U"", U"oe", U"aa", U"oo", U"a", U"eu", U"ie", U"uu", U"ee", U"u", U"e", U"o", U"i"}; const char32 *ipa[13] = {U"", U"u", U"a", U"o", U"\\as", U"\\o/", U"i", U"y", U"e", U"\\yc", U"\\ep", U"\\ct", U"\\ic"}; const char32 *sex[2] = {U"m", U"f"}; struct weeninkdatum { short f[4]; /* f0, f1, f2, f3 */ } weeninkdata [] = { {{182, 335, 748, 2332}}, {{170, 435, 669, 2886}}, {{164, 488, 911, 2362}}, {{170, 671, 1005, 2822}}, {{160, 787, 1372, 3313}}, {{165, 396, 1624, 2374}}, {{165, 472, 1585, 2344}}, {{180, 293, 1791, 2177}}, {{176, 314, 2149, 3215}}, {{164, 393, 2120, 2694}}, {{161, 454, 1982, 2673}}, {{165, 502, 1902, 2632}}, /* Speaker 2 */ {{161, 308, 709, 2222}}, {{155, 461, 760, 2632}}, {{148, 510, 907, 2532}}, {{153, 645, 1004, 2604}}, {{145, 758, 1244, 2658}}, {{155, 449, 1489, 2279}}, {{145, 454, 1388, 2308}}, {{162, 314, 1620, 2111}}, {{158, 303, 1984, 2835}}, {{150, 429, 1888, 2502}}, {{156, 460, 1748, 2442}}, {{150, 580, 1679, 2383}}, /* Speaker 3 */ {{124, 343, 719, 2107}}, {{124, 519, 818, 1975}}, {{125, 532, 937, 2044}}, {{126, 721, 1135, 2077}}, {{125, 850, 1328, 2299}}, {{131, 390, 1307, 2177}}, {{129, 481, 1438, 2203}}, {{127, 270, 1705, 2068}}, {{121, 275, 2081, 2882}}, {{129, 377, 2044, 2638}}, {{131, 464, 1949, 2536}}, {{124, 645, 1854, 2488}}, /* Speaker 4 */ {{119, 322, 590, 2146}}, {{110, 438, 703, 2392}}, {{106, 489, 845, 2157}}, {{120, 708, 1126, 2302}}, {{107, 818, 1333, 2312}}, {{109, 406, 1505, 2133}}, {{109, 422, 1518, 2116}}, {{115, 298, 1581, 2162}}, {{119, 268, 2189, 2950}}, {{109, 400, 2151, 2870}}, {{108, 420, 2075, 2495}}, {{108, 550, 1905, 2383}}, /* Speaker 5 */ {{132, 282, 656, 2355}}, {{118, 462, 662, 2852}}, {{117, 482, 797, 2531}}, {{115, 723, 1036, 2456}}, {{117, 732, 1356, 2562}}, {{118, 454, 1516, 2178}}, {{119, 466, 1484, 2139}}, {{129, 271, 1642, 2154}}, {{122, 255, 2390, 2787}}, {{120, 353, 2114, 2507}}, {{114, 441, 2020, 2392}}, {{122, 601, 1858, 2315}}, /* Speaker 6 */ {{155, 275, 560, 2397}}, {{141, 395, 705, 2802}}, {{149, 419, 831, 1824}}, {{142, 674, 1113, 2455}}, {{137, 696, 1262, 2778}}, {{148, 419, 1493, 2242}}, {{148, 422, 1599, 2319}}, {{157, 291, 1585, 2160}}, {{152, 281, 2324, 3124}}, {{144, 358, 2269, 2936}}, {{146, 426, 2174, 2786}}, {{140, 560, 1941, 2722}}, /* Speaker 7 */ {{165, 315, 703, 2304}}, {{138, 531, 837, 2338}}, {{130, 471, 838, 2391}}, {{135, 713, 1218, 2466}}, {{140, 807, 1478, 2390}}, {{126, 467, 1639, 2227}}, {{135, 504, 1520, 2268}}, {{151, 341, 1738, 2246}}, {{145, 302, 2255, 2887}}, {{140, 379, 2183, 2614}}, {{133, 400, 2198, 2551}}, {{137, 587, 2024, 2516}}, /* Speaker 8 */ {{179, 361, 730, 2256}}, {{168, 500, 714, 2782}}, {{165, 495, 961, 2405}}, {{162, 642, 988, 2308}}, {{156, 921, 1409, 2909}}, {{166, 451, 1482, 2657}}, {{175, 505, 1546, 2443}}, {{177, 341, 1705, 2291}}, {{176, 285, 2288, 2817}}, {{173, 364, 2126, 2907}}, {{153, 492, 2102, 2778}}, {{158, 628, 1777, 2903}}, /* Speaker 9 */ {{180, 358, 700, 2672}}, {{177, 524, 759, 2784}}, {{169, 557, 856, 2727}}, {{178, 685, 1075, 2677}}, {{168, 855, 1311, 2701}}, {{170, 499, 1496, 2725}}, {{170, 502, 1385, 2112}}, {{178, 348, 1504, 2129}}, {{176, 318, 2252, 2846}}, {{169, 422, 2186, 2816}}, {{159, 509, 1941, 2732}}, {{165, 582, 1920, 2773}}, /* Speaker 10 */ {{161, 277, 592, 2493}}, {{141, 490, 718, 2757}}, {{137, 392, 692, 2512}}, {{142, 642, 991, 2707}}, {{144, 753, 1306, 2617}}, {{140, 388, 1570, 2175}}, {{139, 357, 1675, 2105}}, {{156, 248, 1846, 2117}}, {{148, 258, 2280, 3350}}, {{149, 367, 2129, 2731}}, {{142, 357, 2163, 2624}}, {{143, 581, 1865, 2572}}, /* Speaker 11 */ {{282, 305, 842, 2366}}, {{273, 557, 986, 2677}}, {{277, 606, 1090, 2422}}, {{274, 819, 1327, 2819}}, {{277, 938, 1580, 2953}}, {{278, 503, 1826, 2518}}, {{274, 579, 1630, 2501}}, {{286, 312, 2065, 3737}}, {{282, 291, 2540, 3225}}, {{278, 506, 2270, 3040}}, {{277, 559, 2245, 2846}}, {{277, 770, 2137, 2919}}, /* Speaker 12 */ {{255, 307, 738, 2529}}, {{265, 505, 938, 2641}}, {{228, 524, 1067, 2510}}, {{233, 902, 1183, 2603}}, {{215, 841, 1504, 2712}}, {{239, 464, 1655, 2556}}, {{234, 443, 1754, 2607}}, {{245, 303, 1762, 2460}}, {{241, 277, 2439, 3407}}, {{262, 490, 2371, 3198}}, {{228, 484, 2044, 2593}}, {{234, 495, 2296, 3204}}, /* Speaker 13 */ {{298, 309, 627, 3029}}, {{267, 785, 918, 2956}}, {{259, 600, 948, 2684}}, {{257, 893, 1136, 2844}}, {{245, 1028, 1498, 2715}}, {{258, 501, 1746, 2529}}, {{265, 536, 1799, 2601}}, {{280, 282, 1391, 2520}}, {{270, 275, 2664, 3174}}, {{260, 511, 2320, 2882}}, {{255, 506, 2482, 2846}}, {{258, 783, 2027, 2606}}, /* Speaker 14 */ {{187, 327, 586, 2463}}, {{177, 520, 690, 2828}}, {{175, 540, 956, 2599}}, {{178, 596, 1023, 2750}}, {{184, 692, 1382, 2432}}, {{186, 397, 1658, 2422}}, {{175, 512, 1674, 2458}}, {{186, 291, 1737, 2236}}, {{203, 271, 2299, 3260}}, {{187, 369, 2263, 2903}}, {{182, 471, 2057, 2729}}, {{196, 593, 2122, 2779}}, /* Speaker 15 */ {{263, 448, 830, 2687}}, {{230, 570, 1010, 2614}}, {{244, 595, 1109, 2686}}, {{240, 806, 1386, 2591}}, {{239, 890, 1574, 2965}}, {{244, 482, 1900, 2710}}, {{251, 502, 1529, 2716}}, {{238, 436, 2134, 2626}}, {{254, 374, 2580, 3181}}, {{252, 494, 2323, 2989}}, {{242, 484, 2323, 3025}}, {{246, 595, 1897, 2865}}, /* Speaker 16 */ {{238, 325, 737, 2290}}, {{224, 462, 764, 2600}}, {{202, 577, 944, 2651}}, {{216, 674, 1084, 2851}}, {{210, 833, 1333, 2256}}, {{214, 427, 1708, 2346}}, {{202, 502, 1546, 2326}}, {{242, 289, 1669, 2169}}, {{232, 337, 2060, 2841}}, {{224, 416, 2217, 2769}}, {{214, 491, 1950, 2674}}, {{188, 548, 2071, 2727}}, /* Speaker 17 */ {{277, 313, 578, 2457}}, {{254, 549, 855, 2793}}, {{250, 608, 904, 2724}}, {{267, 890, 1294, 2732}}, {{263, 1047, 1578, 2848}}, {{289, 549, 1728, 2844}}, {{258, 508, 1747, 2799}}, {{284, 287, 1982, 2793}}, {{268, 268, 2873, 4075}}, {{258, 440, 2590, 3090}}, {{248, 489, 2529, 3111}}, {{261, 606, 2078, 2980}}, /* Speaker 18 */ {{330, 334, 729, 3332}}, {{247, 629, 864, 3024}}, {{234, 521, 935, 2760}}, {{264, 964, 1246, 3112}}, {{261, 1008, 1573, 2932}}, {{278, 509, 1887, 2596}}, {{243, 487, 1799, 2393}}, {{303, 306, 1781, 2415}}, {{282, 296, 2597, 3571}}, {{217, 425, 2636, 3314}}, {{250, 490, 2642, 3494}}, {{275, 787, 2326, 2992}}, /* Speaker 19 */ {{228, 322, 661, 2721}}, {{214, 589, 821, 2729}}, {{219, 457, 857, 2582}}, {{229, 801, 1260, 2911}}, {{220, 898, 1628, 2770}}, {{233, 463, 1630, 2306}}, {{225, 456, 1671, 2381}}, {{225, 283, 1779, 2211}}, {{224, 276, 2495, 3372}}, {{224, 440, 2385, 3007}}, {{216, 435, 2363, 2866}}, {{212, 637, 2130, 3029}}, /* Speaker 20 */ {{246, 324, 730, 2644}}, {{230, 636, 923, 2757}}, {{233, 534, 954, 2542}}, {{234, 820, 1256, 3064}}, {{248, 966, 1695, 2890}}, {{237, 484, 1753, 2718}}, {{240, 480, 1917, 2670}}, {{247, 291, 1981, 2701}}, {{243, 290, 2648, 3176}}, {{256, 501, 2358, 3058}}, {{238, 469, 2406, 3008}}, {{236, 693, 2128, 2991}}, /* Speaker 21 */ {{342, 353, 758, 3269}}, {{309, 627, 976, 3256}}, {{334, 663, 1017, 3075}}, {{321, 964, 1576, 3186}}, {{316, 1129, 2249, 3404}}, {{330, 650, 2336, 3284}}, {{311, 636, 2083, 3328}}, {{331, 357, 2389, 3185}}, {{332, 337, 2960, 3595}}, {{351, 586, 2833, 3595}}, {{312, 621, 2839, 3614}}, {{309, 765, 2755, 3636}}, /* Speaker 22 */ {{326, 359, 682, 2948}}, {{318, 631, 795, 3537}}, {{296, 688, 1135, 2930}}, {{285, 746, 1135, 1926}}, {{290, 1006, 2166, 3263}}, {{326, 632, 1990, 3042}}, {{285, 570, 2015, 3155}}, {{321, 324, 2025, 3104}}, {{338, 346, 3069, 3573}}, {{320, 636, 3025, 3709}}, {{306, 611, 2770, 3648}}, {{331, 893, 2639, 3566}}, /* Speaker 23 */ {{312, 414, 828, 2908}}, {{314, 609, 936, 3139}}, {{305, 659, 1201, 3015}}, {{298, 890, 1303, 3003}}, {{300, 1150, 2116, 3205}}, {{275, 537, 1968, 3032}}, {{277, 534, 1997, 3009}}, {{304, 398, 2298, 2940}}, {{302, 330, 3010, 3746}}, {{312, 547, 2965, 3673}}, {{275, 551, 2786, 3442}}, {{299, 641, 2662, 3410}}, /* Speaker 24 */ {{301, 315, 812, 3357}}, {{316, 621, 960, 3701}}, {{305, 604, 1179, 3659}}, {{331, 981, 1701, 3374}}, {{322, 954, 2010, 3291}}, {{297, 581, 2085, 3288}}, {{307, 613, 1991, 3392}}, {{322, 331, 2099, 3096}}, {{326, 326, 3235, 3935}}, {{307, 547, 2747, 3618}}, {{308, 613, 2763, 3710}}, {{315, 622, 2459, 3616}}, /* Speaker 25 */ {{360, 417, 981, 3610}}, {{354, 697, 1017, 3077}}, {{363, 741, 1302, 3381}}, {{340, 1028, 1611, 2973}}, {{337, 1122, 1930, 3068}}, {{310, 608, 2105, 3177}}, {{323, 628, 1929, 3197}}, {{378, 384, 2255, 2992}}, {{363, 363, 3235, 4069}}, {{338, 527, 2698, 3458}}, {{308, 643, 2603, 3382}}, {{326, 712, 2351, 3498}}, /* Speaker 26 */ {{375, 380, 798, 3316}}, {{371, 456, 759, 3321}}, {{324, 656, 1118, 3296}}, {{340, 1031, 1690, 3163}}, {{376, 1154, 1920, 3519}}, {{362, 604, 2162, 3603}}, {{342, 679, 2035, 3683}}, {{371, 374, 2042, 3206}}, {{349, 361, 3082, 3782}}, {{357, 499, 2899, 3934}}, {{324, 646, 2820, 3970}}, {{353, 706, 2785, 3942}}, /* Speaker 27 */ {{312, 339, 850, 4356}}, {{319, 619, 919, 3570}}, {{288, 576, 1156, 3681}}, {{301, 865, 1567, 3326}}, {{296, 914, 2090, 3113}}, {{297, 589, 2150, 3208}}, {{287, 580, 2146, 3340}}, {{303, 330, 2431, 3032}}, {{291, 313, 3090, 4039}}, {{305, 539, 3015, 3905}}, {{291, 577, 2589, 2778}}, {{307, 616, 2448, 3856}}, /* Speaker 28 */ {{353, 354, 1085, 3082}}, {{343, 617, 990, 3027}}, {{281, 822, 1180, 2931}}, {{324, 993, 1424, 2941}}, {{297, 1192, 1792, 2922}}, {{314, 444, 2170, 3044}}, {{275, 608, 1817, 2909}}, {{355, 358, 2138, 3160}}, {{321, 323, 3169, 3625}}, {{315, 499, 2831, 3465}}, {{303, 608, 2707, 3369}}, {{313, 718, 2479, 3627}}, /* Speaker 29 */ {{361, 363, 1050, 3239}}, {{365, 666, 1094, 3269}}, {{327, 830, 1289, 3145}}, {{325, 963, 1293, 3046}}, {{356, 1163, 1707, 3188}}, {{377, 580, 2191, 3234}}, {{336, 673, 2339, 3167}}, {{342, 345, 2344, 3103}}, {{341, 346, 2729, 3370}}, {{326, 541, 2568, 3297}}, {{331, 677, 2561, 3320}}, {{354, 897, 2463, 3338}}, /* Speaker 30 */ {{332, 352, 979, 2988}}, {{286, 596, 973, 2690}}, {{304, 753, 1174, 3005}}, {{290, 884, 1432, 2806}}, {{347, 1060, 2079, 2706}}, {{303, 592, 2069, 2889}}, {{299, 644, 1775, 3005}}, {{296, 329, 2082, 2791}}, {{315, 326, 2807, 3612}}, {{298, 561, 2612, 3330}}, {{281, 569, 2415, 3239}}, {{280, 709, 2460, 3314}} }; try { autoTable me = Table_create (nrows, ncols); for (long i = 1; i <= nrows; i++) { TableRow row = (TableRow) my rows -> item[i]; int speaker_id = (i - 1) / 12 + 1; /* 1 - 30 */ int vowel_id = (i - 1) % 12 + 1; /* 1 - 12 */ int index_in_data = (speaker_id - 1) * 12 + order[vowel_id] - 1; int speaker_type, speaker_sex; if (speaker_id <= 10) { /* 10 men */ speaker_type = 0; speaker_sex = 0; } else if (speaker_id <= 20) { /* 10 women */ speaker_type = 1; speaker_sex = 1; } else { /* 10 children */ speaker_type = 2; speaker_sex = 0; // Which children were m/f ? } row -> cells [1]. string = Melder_dup_f (type [speaker_type]); row -> cells [2]. string = Melder_dup_f (sex [speaker_sex]); row -> cells [3]. string = Melder_dup_f (Melder_integer (speaker_id)); row -> cells [4]. string = Melder_dup_f (vowel [vowel_id]); row -> cells [5]. string = Melder_dup_f (ipa [vowel_id]); for (long j = 0; j <= 3; j++) { row -> cells [j + 6]. string = Melder_dup_f (Melder_integer (weeninkdata[index_in_data].f[j])); } } for (long j = 1; j <= ncols; j++) { Table_setColumnLabel (me.peek(), j, columnLabels[j - 1]); my columnHeaders [j]. numericized = false; } return me.transfer(); } catch (MelderError) { Melder_throw (U"Table not created from Weenink data."); } } // Keating&Esposito (2006), Table Table_createFromEspositoData () { try { autoTable me = Table_createWithColumnNames (10, U"Language Modal Breathy"); Table_setStringValue (me.peek(), 1, 1, U"Chong");Table_setNumericValue (me.peek(), 1, 2, -1.5);Table_setNumericValue (me.peek(), 1, 3, 5); Table_setStringValue (me.peek(), 2, 1, U"Fuzhou");Table_setNumericValue (me.peek(), 2, 2, -1.5);Table_setNumericValue (me.peek(), 2, 3, 5); Table_setStringValue (me.peek(), 3, 1, U"Green Hmong");Table_setNumericValue (me.peek(), 3, 2, 3);Table_setNumericValue (me.peek(), 3, 3, 12); Table_setStringValue (me.peek(), 4, 1, U"White Hmong");Table_setNumericValue (me.peek(), 4, 2, 2);Table_setNumericValue (me.peek(), 4, 3, 11); Table_setStringValue (me.peek(), 5, 1, U"Mon");Table_setNumericValue (me.peek(), 5, 2, -1.5);Table_setNumericValue (me.peek(), 5, 3, 0); Table_setStringValue (me.peek(), 6, 1, U"SADV Zapotec");Table_setNumericValue (me.peek(), 6, 2, -6);Table_setNumericValue (me.peek(), 6, 3, -4); Table_setStringValue (me.peek(), 7, 1, U"SLQ Zapotec");Table_setNumericValue (me.peek(), 7, 2, 3.5);Table_setNumericValue (me.peek(), 7, 3, 14); Table_setStringValue (me.peek(), 8, 1, U"Tlacolula Zapotec");Table_setNumericValue (me.peek(), 8, 2, 3);Table_setNumericValue (me.peek(), 8, 3, 13); Table_setStringValue (me.peek(), 9, 1, U"Tamang");Table_setNumericValue (me.peek(), 9, 2, 1);Table_setNumericValue (me.peek(), 9, 3, 1); Table_setStringValue (me.peek(), 10, 1, U"!Xoo");Table_setNumericValue (me.peek(), 10, 2, 1);Table_setNumericValue (me.peek(), 10, 3, 14); return me.transfer(); } catch (MelderError) { Melder_throw (U"Keating-Esposito table not created."); } } Table Table_createFromGanongData () { try { autoTable me = Table_createWithColumnNames (6, U"VOT dash-tash dask-task"); Table_setNumericValue (me.peek(), 1, 1, -17.5);Table_setNumericValue (me.peek(), 1, 2, 0.98);Table_setNumericValue (me.peek(), 1, 3, 0.92); Table_setNumericValue (me.peek(), 2, 1, -7.5);Table_setNumericValue (me.peek(), 2, 2, 0.95);Table_setNumericValue (me.peek(), 2, 3, 0.83); Table_setNumericValue (me.peek(), 3, 1, -2.5);Table_setNumericValue (me.peek(), 3, 2, 0.71);Table_setNumericValue (me.peek(), 3, 3, 0.33); Table_setNumericValue (me.peek(), 4, 1, 2.5);Table_setNumericValue (me.peek(), 4, 2, 0.29);Table_setNumericValue (me.peek(), 4, 3, 0.10); Table_setNumericValue (me.peek(), 5, 1, 7.5);Table_setNumericValue (me.peek(), 5, 2, 0.12);Table_setNumericValue (me.peek(), 5, 3, 0.02); Table_setNumericValue (me.peek(), 6, 1, 17.5);Table_setNumericValue (me.peek(), 6, 2, 0.10);Table_setNumericValue (me.peek(), 6, 3, 0.02); return me.transfer(); } catch (MelderError) { Melder_throw (U"Ganong table not created."); } } static bool intervalsIntersect (double x1, double x2, double xmin, double xmax, double *xc1, double *xc2) { if (x1 > x2) { double tmp = x1; x1 = x2; x2 = tmp; } if (xmin > xmax) { double tmp = xmin; xmin = xmax; xmin = tmp; } *xc1 = x1; *xc2 = x2; if (x2 <= xmin || x1 >= xmax) { return false; } if (x1 < xmin) { *xc1 = xmin; } if (x2 > xmax) { *xc2 = xmax; } return true; } void Table_horizontalErrorBarsPlotWhere (Table me, Graphics g, long xcolumn, long ycolumn, double xmin, double xmax, double ymin, double ymax, long xci_min, long xci_max, double bar_mm, int garnish, const char32 *formula, Interpreter interpreter) { try { long nrows = my rows -> size; if (xcolumn < 1 || xcolumn > nrows || ycolumn < 1 || ycolumn > nrows || (xci_min != 0 && xci_min > nrows) || (xci_max != 0 && xci_max > nrows)) { return; } long numberOfSelectedRows = 0; autoNUMvector selectedRows (Table_findRowsMatchingCriterion (me, formula, interpreter, &numberOfSelectedRows), 1); if (ymin >= ymax) { Table_columnExtremesFromSelectedRows (me, ycolumn, selectedRows.peek(), numberOfSelectedRows, &ymin, &ymax); if (ymin >= ymax) { ymin -= 1; ymax += 1; } } double x1min, x1max; if (xmin >= xmax) { Table_columnExtremesFromSelectedRows (me, xcolumn, selectedRows.peek(), numberOfSelectedRows, &xmin, &xmax); if (xci_min > 0) { Table_columnExtremesFromSelectedRows (me, xci_min, selectedRows.peek(), numberOfSelectedRows, &x1min, &x1max); xmin -= x1max; } if (xci_max > 0) { Table_columnExtremesFromSelectedRows (me, xci_max, selectedRows.peek(), numberOfSelectedRows, &x1min, &x1max); xmax += x1max; } if (xmin >= xmax) { xmin -= 1; xmax += 1; } } Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_setInner (g); double dy = Graphics_dyMMtoWC (g, bar_mm); for (long row = 1; row <= numberOfSelectedRows; row++) { double x = Table_getNumericValue_Assert (me, selectedRows[row], xcolumn); double y = Table_getNumericValue_Assert (me, selectedRows[row], ycolumn); double dx1 = xci_min > 0 ? Table_getNumericValue_Assert (me, selectedRows[row], xci_min) : 0; double dx2 = xci_max > 0 ? Table_getNumericValue_Assert (me, selectedRows[row], xci_max) : 0; double x1 = x - dx1, x2 = x + dx2, xc1, yc1, xc2, yc2; if (x <= xmax && x >= xmin && y <= ymax && y >= ymin) { // horizontal confidence interval if (intervalsIntersect (x1, x2, xmin, xmax, &xc1, &xc2)) { Graphics_line (g, xc1, y, xc2, y); if (dy > 0 && intervalsIntersect (y - dy / 2, y + dy / 2, ymin, ymax, &yc1, &yc2)) { if (xc1 >= xmin && dx1 > 0) { Graphics_line (g, xc1, yc1, xc1, yc2); } if (xc2 <= xmax && dx2 > 0) { Graphics_line (g, xc2, yc1, xc2, yc2); } } } } } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksLeft (g, 2, true, true, false); Graphics_marksBottom (g, 2, true, true, false); } } catch (MelderError) { Melder_clearError (); } } void Table_verticalErrorBarsPlotWhere (Table me, Graphics g, long xcolumn, long ycolumn, double xmin, double xmax, double ymin, double ymax, long yci_min, long yci_max, double bar_mm, int garnish, const char32 *formula, Interpreter interpreter) { try { long nrows = my rows -> size; if (xcolumn < 1 || xcolumn > nrows || ycolumn < 1 || ycolumn > nrows || (yci_min != 0 && yci_min > nrows) || (yci_max != 0 && yci_max > nrows)) { return; } long numberOfSelectedRows = 0; autoNUMvector selectedRows (Table_findRowsMatchingCriterion (me, formula, interpreter, &numberOfSelectedRows), 1); if (xmin >= xmax) { Table_columnExtremesFromSelectedRows (me, ycolumn, selectedRows.peek(), numberOfSelectedRows, &ymin, &ymax); if (xmin >= xmax) { xmin -= 1.0; xmax += 1.0; } } double y1min, y1max; if (ymin >= ymax) { Table_columnExtremesFromSelectedRows (me, ycolumn, selectedRows.peek(), numberOfSelectedRows, &ymin, &ymax); if (yci_min > 0) { Table_columnExtremesFromSelectedRows (me, yci_min, selectedRows.peek(), numberOfSelectedRows, &y1min, &y1max); ymin -= y1max; } if (yci_max > 0) { Table_columnExtremesFromSelectedRows (me, yci_max, selectedRows.peek(), numberOfSelectedRows, &y1min, &y1max); ymax += y1max; } if (ymin >= ymax) { ymin -= 1.0; ymax += 1.0; } } Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_setInner (g); double dx = Graphics_dxMMtoWC (g, bar_mm); for (long row = 1; row <= numberOfSelectedRows; row++) { double x = Table_getNumericValue_Assert (me, selectedRows[row], xcolumn); double y = Table_getNumericValue_Assert (me, selectedRows[row], ycolumn); double dy1 = yci_min > 0 ? Table_getNumericValue_Assert (me, selectedRows[row], yci_min) : 0.0; double dy2 = yci_max > 0 ? Table_getNumericValue_Assert (me, selectedRows[row], yci_max) : 0.0; double y1 = y - dy1, y2 = y + dy2, xc1, yc1, xc2, yc2; if (x <= xmax && x >= xmin && y <= ymax && y >= ymin) { // vertical confidence interval if (intervalsIntersect (y1, y2, ymin, ymax, &yc1, &yc2)) { Graphics_line (g, x, yc1, x, yc2); if (dx > 0 && intervalsIntersect (x - dx / 2.0, x + dx / 2.0, xmin, xmax, &xc1, &xc2)) { if (yc1 >= ymin && dy1 > 0.0) { Graphics_line (g, xc1, yc1, xc2, yc1); } if (yc2 <= ymax && dy2 > 0.0) { Graphics_line (g, xc1, yc2, xc2, yc2); } } } } } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksLeft (g, 2, true, true, false); Graphics_marksBottom (g, 2, true, true, false); } } catch (MelderError) { Melder_clearError (); } } double Table_getMedianAbsoluteDeviation (Table me, long columnNumber) try { Table_checkSpecifiedColumnNumberWithinRange (me, columnNumber); Table_numericize_Assert (me, columnNumber); if (my rows -> size < 1) { return NUMundefined; } autoNUMvector data (1, my rows -> size); for (long irow = 1; irow <= my rows -> size; irow ++) { TableRow row = static_cast (my rows -> item [irow]); data[irow] = row -> cells[columnNumber].number; if (data[irow] == NUMundefined) { Melder_throw (me, U": the cell in row ", irow, U" of column \"", my columnHeaders[columnNumber].label ? my columnHeaders[columnNumber].label : Melder_integer (columnNumber), U" is undefined."); } } double mad, location; NUMmad (data.peek(), my rows -> size, &location, 1, &mad, nullptr); return mad; } catch (MelderError) { Melder_throw (me, U": cannot compute median absolute deviation of column ", columnNumber, U"."); } Table Table_getOneWayKruskalWallis (Table me, long column, long factorColumn, double *degreesOfFreedom, double *kruskalWallis, double *probability) { try { if (column < 1 || column > my numberOfColumns) { Melder_throw (U"Invalid column number."); } if (factorColumn < 1 || factorColumn > my numberOfColumns || factorColumn == column) { Melder_throw (U"Invalid group column number."); } long numberOfData = my rows -> size; Table_numericize_Assert (me, column); autoNUMvector data (1, numberOfData); autoStringsIndex levels = Table_to_StringsIndex_column (me, factorColumn); long numberOfLevels = levels -> classes -> size; if (numberOfLevels < 2) { Melder_throw (U"There must be at least two levels."); } for (long irow = 1; irow <= numberOfData; irow++) { data[irow] = ((TableRow) my rows -> item [irow]) -> cells [column] .number; } NUMsort2 (numberOfData, data.peek(), levels -> classIndex); NUMrank (numberOfData, data.peek()); // Get correctionfactor for ties // Hayes pg. 831 double c = 0.0; long jt, j = 1; while (j < numberOfData) { for (jt = j + 1; jt <= numberOfData && data[jt] == data[j]; jt++) {} double multiplicity = jt - j; if (multiplicity > 1) { c += multiplicity * (multiplicity *multiplicity - 1.0); } j = jt; } double tiesCorrection = 1.0 - c / (numberOfData * (numberOfData * numberOfData - 1.0)); autoNUMvector factorLevelSizes (1, numberOfLevels); autoNUMvector factorLevelSums (1, numberOfLevels); autoNUMvector ties (1, numberOfLevels); for (long i = 1; i <= numberOfData; i++) { long index = levels -> classIndex[i]; factorLevelSizes[index] ++; factorLevelSums[index] += data[i]; } double h = 0; for (j = 1; j <= numberOfLevels; j++) { if (factorLevelSizes[j] < 2) { SimpleString ss = (SimpleString) levels -> classes -> item[j]; Melder_throw (U"Group ", ss -> string, U" has fewer than two cases."); } h += factorLevelSums[j] * factorLevelSums[j] / factorLevelSizes[j]; // = factorLevelMeans * groupMean * factorLevelSizes } h = (12.0 / (numberOfData * (numberOfData + 1.0))) * h - 3.0 * (numberOfData + 1); h /= tiesCorrection; double dof = numberOfLevels - 1.0; if (degreesOfFreedom) { *degreesOfFreedom = dof; } if (kruskalWallis) { *kruskalWallis = h; } double p = NUMchiSquareQ (h, dof); if (probability) { *probability = p; } autoTable him = Table_createWithColumnNames (numberOfLevels, U"Group(R) Sums(R) Cases"); for (long irow = 1; irow <= numberOfLevels; irow++) { SimpleString ss = (SimpleString) levels -> classes -> item[irow]; Table_setStringValue (him.peek(), irow, 1, ss -> string); Table_setNumericValue (him.peek(), irow, 2, factorLevelSums[irow]); Table_setNumericValue (him.peek(), irow, 3, factorLevelSizes[irow]); } Table_numericize_Assert (him.peek(), 2); Table_numericize_Assert (him.peek(), 3); return him.transfer(); } catch (MelderError) { Melder_throw (me, U": no one-way Kruskal-Wallis performed."); } } // Table with Group Means Cases static void _Table_postHocTukeyHSD (Table me, double sumOfSquaresWithin, double degreesOfFreedomWithin, autoTable *meansDiff, autoTable *meansDiffProbabilities) { try { Table_numericize_Assert (me, 2); Table_numericize_Assert (me, 3); long numberOfMeans = my rows -> size; autoNUMvector means (1, numberOfMeans); autoNUMvector cases (1, numberOfMeans); autoTable meansD = Table_create (numberOfMeans - 1, numberOfMeans); for (long i = 1; i <= numberOfMeans; i++) { TableRow row = (TableRow) my rows -> item [i]; means[i] = row -> cells [2].number; cases[i] = row -> cells [3].number; } for (long i = 1; i <= numberOfMeans - 1; i++) { Table_setStringValue (meansD.peek(), i, 1, ((TableRow) my rows -> item [i]) -> cells [1].string); Table_setColumnLabel (meansD.peek(), i + 1, ((TableRow) my rows -> item [i + 1]) -> cells [1].string); } for (long irow = 1; irow <= numberOfMeans - 1; irow++) { for (long icol = irow + 1; icol <= numberOfMeans; icol++) { double dif = fabs (means[irow] - means[icol]); Table_setNumericValue (meansD.peek(), irow, icol, dif); } } autoTable meansP = (Table) Data_copy (meansD.peek()); for (long irow = 1; irow <= numberOfMeans - 1; irow++) { for (long icol = irow + 1; icol <= numberOfMeans; icol++) { // Tukey-Kramer correction for unequal sample sizes double oneOverNstar = 0.5 * (1.0 / cases[icol] + 1.0 / cases[irow]); double s = sqrt (sumOfSquaresWithin * oneOverNstar); double q = fabs (means[irow] - means[icol]) / s; double p = NUMtukeyQ (q, numberOfMeans, degreesOfFreedomWithin, 1); Table_setNumericValue (meansP.peek(), irow, icol, p); } } if (meansDiff) { *meansDiff = meansD.move(); } if (meansDiffProbabilities) { *meansDiffProbabilities = meansP.move(); } } catch (MelderError) { Melder_throw (me, U": no post-hoc performed."); } } // expect 6 columns, first text others numeric void Table_printAsAnovaTable (Table me) { autoMelderString s; int width[7] = { 0, 25, 15, 10, 15, 10, 10 }; if (my numberOfColumns < 6) return; MelderInfo_writeLine ( Melder_pad (width[1], U"Source"), U"\t", Melder_pad (width[2], U"SS"), U"\t", Melder_pad (width[3], U"Df"), U"\t", Melder_pad (width[4], U"MS"), U"\t", Melder_pad (width[5], U"F"), U"\t", Melder_pad (width[6], U"P") ); for (long icol = 2; icol <= 6; icol++) { Table_numericize_Assert (me, icol); } for (long i = 1; i <= my rows -> size; i++) { TableRow row = (TableRow) my rows -> item[i]; MelderString_copy (&s, Melder_padOrTruncate (width[1], row -> cells[1].string), U"\t"); for (long j = 2; j <= 6; j++) { double value = row -> cells[j].number; if (NUMdefined (value)) { MelderString_append (&s, Melder_pad (width[j], Melder_single (value)), j == 6 ? U"" : U"\t"); } else { MelderString_append (&s, Melder_pad (width[j], U""), j == 6 ? U"" : U"\t"); } } MelderInfo_writeLine (s.string); } } void Table_printAsMeansTable (Table me) { autoMelderString s; for (long icol = 2; icol <= my numberOfColumns; icol++) { Table_numericize_Assert (me, icol); } for (long j = 1; j <= my numberOfColumns; j++) { MelderString_append (&s, Melder_padOrTruncate (10, ! my columnHeaders[j].label ? U"" : my columnHeaders[j].label), j == my numberOfColumns ? U"" : U"\t"); } MelderInfo_writeLine (s.string); for (long i = 1; i <= my rows -> size; i++) { TableRow row = (TableRow) my rows -> item[i]; MelderString_copy (&s, Melder_padOrTruncate (10, row -> cells[1].string), U"\t"); for (long j = 2; j <= my numberOfColumns; j++) { double value = row -> cells[j].number; if (value != NUMundefined) { MelderString_append (&s, Melder_pad (10, Melder_half (value)), j == my numberOfColumns ? U"" : U"\t"); } else { MelderString_append (&s, Melder_pad (10, U""), j == my numberOfColumns ? U"" : U"\t"); } } MelderInfo_writeLine (s.string); } } autoTable Table_getOneWayAnalysisOfVarianceF (Table me, long column, long factorColumn, autoTable *means, autoTable *meansDiff, autoTable *meansDiffProbabilities) { try { if (column < 1 || column > my numberOfColumns) { Melder_throw (U"Invalid column number."); } if (factorColumn < 1 || factorColumn > my numberOfColumns || factorColumn == column) { Melder_throw (U"Invalid group column number."); } long numberOfData = my rows -> size; Table_numericize_Assert (me, column); autoNUMvector data (1, numberOfData); autoStringsIndex levels = Table_to_StringsIndex_column (me, factorColumn); // copy data from Table for (long irow = 1; irow <= numberOfData; irow++) { data[irow] = ((TableRow) my rows -> item[irow]) -> cells[column].number; } long numberOfLevels = levels -> classes -> size; if (numberOfLevels < 2) { Melder_throw (U"There must be at least two levels."); } autoNUMvector factorLevelSizes (1, numberOfLevels); autoNUMvector factorLevelMeans (1, numberOfLevels); // a, ty, c according to schem of Hayes, 10.14 pg 363 double a = 0.0, ty = 0.0; for (long i = 1; i <= numberOfData; i++) { long index = levels -> classIndex[i]; factorLevelSizes[index] ++; factorLevelMeans[index] += data[i]; a += data[i] * data[i]; ty += data[i]; } double c = 0.0; for (long j = 1; j <= numberOfLevels; j++) { if (factorLevelSizes[j] < 2) { SimpleString ss = (SimpleString) levels -> classes -> item[j]; Melder_throw (U"Level \"", ss -> string, U"\" has less then two members."); } c += factorLevelMeans[j] * factorLevelMeans[j] / factorLevelSizes[j]; // order of these two is important! factorLevelMeans[j] /= factorLevelSizes[j]; } double ss_t = a - ty * ty / numberOfData; double ss_b = c - ty * ty / numberOfData; double ss_w = a - c; double dof_w = numberOfData - numberOfLevels; double dof_b = numberOfLevels - 1; autoTable anova = Table_createWithColumnNames (3, U"Source SS Df MS F P"); long col_s = 1, col_ss = 2, col_df = 3, col_ms = 4, col_f = 5, col_p = 6; long row_b = 1, row_w = 2, row_t = 3; Table_setStringValue (anova.peek(), row_b, col_s, U"Between"); Table_setStringValue (anova.peek(), row_w, col_s, U"Within"); Table_setStringValue (anova.peek(), row_t, col_s, U"Total"); Table_setNumericValue (anova.peek(), row_b, col_ss, ss_b); Table_setNumericValue (anova.peek(), row_b, col_df, dof_b); double ms_b = ss_b / dof_b; Table_setNumericValue (anova.peek(), row_b, col_ms, ms_b); Table_setNumericValue (anova.peek(), row_w, col_ss, ss_w); Table_setNumericValue (anova.peek(), row_w, col_df, dof_w); double ms_w = ss_w / dof_w; Table_setNumericValue (anova.peek(), row_w, col_ms, ms_w); double fisherF = ms_b / ms_w; double probability = NUMfisherQ (fisherF, dof_b, dof_w); Table_setNumericValue (anova.peek(), row_b, col_f, fisherF); Table_setNumericValue (anova.peek(), row_b, col_p, probability); Table_setNumericValue (anova.peek(), row_t, col_ss, ss_t); Table_setNumericValue (anova.peek(), row_t, col_df, dof_w + dof_b); autoTable ameans = Table_createWithColumnNames (numberOfLevels, U"Group Mean Cases"); for (long irow = 1; irow <= numberOfLevels; irow++) { SimpleString name = (SimpleString) levels -> classes -> item[irow]; Table_setStringValue (ameans.peek(), irow, 1, name -> string); Table_setNumericValue (ameans.peek(), irow, 2, factorLevelMeans[irow]); Table_setNumericValue (ameans.peek(), irow, 3, factorLevelSizes[irow]); } long columns [1+1] = { 0, 2 }; // sort by column 2 Table_sortRows_Assert (ameans.peek(), columns, 1); _Table_postHocTukeyHSD (ameans.peek(), ms_w, dof_w, meansDiff, meansDiffProbabilities); if (means) { *means = ameans.move(); } return anova; } catch (MelderError) { Melder_throw (me, U": no one-way anova performed."); } } Table Table_getTwoWayAnalysisOfVarianceF (Table me, long column, long factorColumnA, long factorColumnB, Table *means, Table *levelSizes) { try { if (column < 1 || column > my numberOfColumns) { Melder_throw (U"Invalid column number."); } if (factorColumnA < 1 || factorColumnA > my numberOfColumns || factorColumnA == column) { Melder_throw (U"Invalid A group column number."); } if (factorColumnB < 1 || factorColumnB > my numberOfColumns || factorColumnB == column || factorColumnA == factorColumnB) { Melder_throw (U"Invalid B group column number."); } char32 *label_A = my columnHeaders[factorColumnA].label; char32 *label_B = my columnHeaders[factorColumnB].label; long numberOfData = my rows -> size; Table_numericize_Assert (me, column); autoNUMvector data (1, numberOfData); autoStringsIndex levelsA = Table_to_StringsIndex_column (me, factorColumnA); autoStringsIndex levelsB = Table_to_StringsIndex_column (me, factorColumnB); // copy data from Table for (long irow = 1; irow <= numberOfData; irow++) { data[irow] = ((TableRow) my rows -> item [irow]) -> cells [column] .number; } long numberOfLevelsA = levelsA -> classes -> size; long numberOfLevelsB = levelsB -> classes -> size; if (numberOfLevelsA < 2) { Melder_throw (U"There must be at least two levels in \"", label_A, U"\"."); } if (numberOfLevelsB < 2) { Melder_throw (U"There must be at least two levels in \"", label_B, U"\"."); } /* Formula's according to A. Khuri (1998), Unweighted sums of squares * in unbalanced analysis of variance, Journal of Statistical Planning * and Inference (74): 135--147. * * Model: * * y[i,j,k] = mu + alpha[i] + beta[j] + gamma[i,j] + eps[i,j,k] * i=1..r, j = 1..s, k=1..n[i,j] * * ss(alpha) = nh * s * sum(i=1..r, (ystar[i.]-ystar[..])^2) * ss(beta) = nh * r * sum(j=1..s, (ystar[.j]-ystar[..])^2) * ss(alpha,beta) = nh * sum (i=1..r, sum (j=1..s, (ymean[ij.]-ystar[i.] - ystar[.j] + ystar[..])^2)), * * where * * nh = r * s / sum (i=1..r, sum (j=1..s, 1/n[ij])), * ymean[ij.] = sum (k=1..n[ij], y[ijk]/n[ij]) * ystar[i.] = sum (j=1..s, ymean[ij.]) / s, * ystar[.j] = sum (i=1..r, ymean[ij.]) / r, * ystar[..] = sum (i=1..r, sum (j=1..s, ymean[ij.])) / (r * s) * */ autoNUMmatrix factorLevelSizes (1, numberOfLevelsA + 1, 1, numberOfLevelsB + 1); // sum + weighted sum // extra column for ystar[i.], extra row for ystar[.j] autoNUMmatrix factorLevelMeans (1, numberOfLevelsA + 1, 1, numberOfLevelsB + 1); // weighted mean + mean for (long k = 1; k <= numberOfData; k++) { long indexA = levelsA -> classIndex[k]; long indexB = levelsB -> classIndex[k]; factorLevelSizes[indexA][indexB] ++; factorLevelMeans[indexA][indexB] += data[k]; } // check for unfilled cells and calculate cell means double nh = 0; for (long i = 1; i <= numberOfLevelsA; i++) { for (long j = 1; j <= numberOfLevelsB; j++) { if (factorLevelSizes[i][j] < 1) { SimpleString li = (SimpleString) levelsA -> classes -> item[i]; SimpleString lj = (SimpleString) levelsA -> classes -> item[j]; Melder_throw (U"Level ", li, U" of ", lj, U" has no data."); } factorLevelMeans[i][j] /= factorLevelSizes[i][j]; nh += 1.0 / factorLevelSizes[i][j]; } } nh = numberOfLevelsA * numberOfLevelsB / nh; // row marginals (ystar[i.]) double mean = 0; // ystar[..] for (long i = 1; i <= numberOfLevelsA; i++) { for (long j = 1; j <= numberOfLevelsB; j++) { factorLevelMeans[i][numberOfLevelsB + 1] += factorLevelMeans[i][j]; mean += factorLevelMeans[i][j]; factorLevelSizes[i][numberOfLevelsB + 1] += factorLevelSizes[i][j]; } factorLevelMeans[i][numberOfLevelsB + 1] /= numberOfLevelsB; } mean /= numberOfLevelsA * numberOfLevelsB; factorLevelMeans[numberOfLevelsA + 1][numberOfLevelsB + 1] = mean; factorLevelSizes[numberOfLevelsA + 1][numberOfLevelsB + 1] = numberOfData; // column marginals (ystar[.j]) for (long j = 1; j <= numberOfLevelsB; j++) { for (long i = 1; i <= numberOfLevelsA; i++) { factorLevelMeans[numberOfLevelsA + 1][j] += factorLevelMeans[i][j]; factorLevelSizes[numberOfLevelsA + 1][j] += factorLevelSizes[i][j]; } factorLevelMeans[numberOfLevelsA + 1][j] /= numberOfLevelsA; } // the sums of squares double ss_T = 0; for (long k = 1; k <= numberOfData; k++) { double dif = data[k] - mean; ss_T += dif * dif; } double ss_A = 0; for (long i = 1; i <= numberOfLevelsA; i++) { double dif = factorLevelMeans[i][numberOfLevelsB + 1] - mean; ss_A += dif * dif; } ss_A *= nh * numberOfLevelsB; double ss_B = 0; for (long j = 1; j <= numberOfLevelsB; j++) { double dif = factorLevelMeans[numberOfLevelsA + 1][j] - mean; ss_B += dif * dif; } ss_B *= nh * numberOfLevelsA; double ss_AB = 0; for (long i = 1; i <= numberOfLevelsA; i++) { for (long j = 1; j <= numberOfLevelsB; j++) { double dif = factorLevelMeans[i][j] - factorLevelMeans[i][numberOfLevelsB + 1] - factorLevelMeans[numberOfLevelsA + 1][j] + mean; ss_AB += dif * dif; } } ss_AB *= nh; double ss_E = ss_T - ss_A - ss_B - ss_AB; // are there any replications? if not then the error term is the AB interaction. bool replications = true; if (factorLevelSizes[numberOfLevelsA + 1][1] == numberOfLevelsA) { replications = false; } // Construct the means Table (numberOfLevelsA+1)x(numberOfLevelsB + 1 + 1) autoTable ameans = Table_createWithoutColumnNames (numberOfLevelsA + 1, numberOfLevelsB + 1 + 1); for (long k = 2; k <= numberOfLevelsB + 1; k++) { SimpleString name = (SimpleString) levelsB -> classes -> item[k - 1]; Table_setColumnLabel (ameans.peek(), k, name -> string); } Table_setColumnLabel (ameans.peek(), numberOfLevelsB + 1 + 1, U"Mean"); for (long j = 1; j <= numberOfLevelsA; j++) { SimpleString name = (SimpleString) levelsA -> classes -> item[j]; Table_setStringValue (ameans.peek(), j, 1, name -> string); } Table_setStringValue (ameans.peek(), numberOfLevelsA + 1, 1, U"Mean"); for (long i = 1; i <= numberOfLevelsA + 1; i++) { for (long j = 1; j <= numberOfLevelsB + 1; j++) { Table_setNumericValue (ameans.peek(), i, j + 1, factorLevelMeans[i][j]); } } if (levelSizes) { autoTable asizes = (Table) Data_copy (ameans.peek()); Table_setColumnLabel (asizes.peek(), numberOfLevelsB + 1 + 1, U"Total"); Table_setStringValue (asizes.peek(), numberOfLevelsA + 1, 1, U"Total"); for (long i = 1; i <= numberOfLevelsA + 1; i++) { for (long j = 1; j <= numberOfLevelsB + 1; j++) { Table_setNumericValue (asizes.peek(), i, j + 1, factorLevelSizes[i][j]); } } *levelSizes = asizes.transfer(); } autoTable anova = Table_createWithColumnNames (replications ? 5 : 4, U"Source SS Df MS F P"); long col_s = 1, col_ss = 2, col_df = 3, col_ms = 4, col_f = 5, col_p = 6; long row_A = 1, row_B = 2, row_AB = 3, row_E = replications ? 4 : 3, row_t = replications ? 5 : 4; Table_setStringValue (anova.peek(), row_A, col_s, label_A); Table_setStringValue (anova.peek(), row_B, col_s, label_B); Table_setStringValue (anova.peek(), row_AB, col_s, Melder_cat (label_A, U" x ", label_B)); if (replications) { Table_setStringValue (anova.peek(), row_E, col_s, U"Error"); } Table_setStringValue (anova.peek(), row_t, col_s, U"Total"); double dof_A = numberOfLevelsA - 1, ms_A = ss_A / dof_A; Table_setNumericValue (anova.peek(), row_A, col_ss, ss_A); Table_setNumericValue (anova.peek(), row_A, col_df, dof_A); Table_setNumericValue (anova.peek(), row_A, col_ms, ms_A); double dof_B = numberOfLevelsB - 1, ms_B = ss_B / dof_B; Table_setNumericValue (anova.peek(), row_B, col_ss, ss_B); Table_setNumericValue (anova.peek(), row_B, col_df, dof_B); Table_setNumericValue (anova.peek(), row_B, col_ms, ms_B); double dof_AB = dof_A * dof_B , ms_AB, dof_E, ms_E; if (replications) { ms_AB = ss_AB / dof_AB; dof_E = numberOfData - dof_A - dof_B - dof_AB - 1; ms_E = ss_E / dof_E; Table_setNumericValue (anova.peek(), row_AB, col_ss, ss_AB); Table_setNumericValue (anova.peek(), row_AB, col_df, dof_AB); Table_setNumericValue (anova.peek(), row_AB, col_ms, ms_AB); } else { ss_E = ss_AB; dof_E = numberOfData - dof_A - dof_B - 1; ms_E = ss_AB / dof_E; } Table_setNumericValue (anova.peek(), row_E, col_ss, ss_E); Table_setNumericValue (anova.peek(), row_E, col_df, dof_E); Table_setNumericValue (anova.peek(), row_E, col_ms, ms_E); Table_setNumericValue (anova.peek(), row_t, col_ss, ss_T); Table_setNumericValue (anova.peek(), row_t, col_df, numberOfData - 1); // get f and p values wrt ms_E double f_A = ms_A / ms_E; double f_B = ms_B / ms_E; double p_A = NUMfisherQ (f_A, dof_A, dof_E); double p_B = NUMfisherQ (f_B, dof_B, dof_E); Table_setNumericValue (anova.peek(), row_A, col_f, f_A); Table_setNumericValue (anova.peek(), row_B, col_f, f_B); Table_setNumericValue (anova.peek(), row_A, col_p, p_A); Table_setNumericValue (anova.peek(), row_B, col_p, p_B); if (replications) { double f_AB = ms_AB / ms_E; double p_AB = NUMfisherQ (f_AB, dof_AB, dof_E); Table_setNumericValue (anova.peek(), row_AB, col_f, f_AB); Table_setNumericValue (anova.peek(), row_AB, col_p, p_AB); } if (means) { *means = ameans.transfer(); } return anova.transfer(); } catch (MelderError) { Melder_throw (me, U": two-way anova not created."); } } void Table_normalProbabilityPlot (Table me, Graphics g, long column, long numberOfQuantiles, double numberOfSigmas, int labelSize, const char32 *label, int garnish) { try { if (column < 1 || column > my numberOfColumns) return; Table_numericize_Assert (me, column); long numberOfData = my rows -> size; autoNUMvector data (1, numberOfData); for (long irow = 1; irow <= numberOfData; irow++) { data[irow] = ((TableRow) my rows -> item [irow]) -> cells [column] . number; } double mean, var; NUMvector_avevar (data.peek(), numberOfData, &mean, &var); double xmin = 100, xmax = -xmin, ymin = 1e308, ymax = -ymin, stdev = sqrt (var / (numberOfData - 1)); if (numberOfSigmas != 0) { xmin = -numberOfSigmas; xmax = numberOfSigmas; ymin = mean - numberOfSigmas * stdev; ymax = mean + numberOfSigmas * stdev; } NUMsort_d (numberOfData, data.peek()); numberOfQuantiles = numberOfData < numberOfQuantiles ? numberOfData : numberOfQuantiles; autoTableOfReal thee = TableOfReal_create (numberOfQuantiles, 2); TableOfReal_setColumnLabel (thee.peek(), 1, U"Normal distribution quantiles"); TableOfReal_setColumnLabel (thee.peek(), 2, my columnHeaders[column].label); double un = pow (0.5, 1.0 / numberOfQuantiles); for (long irow = 1; irow <= numberOfQuantiles; irow++) { double ui = irow == 1 ? 1.0 - un : (irow == numberOfQuantiles ? un : (irow - 0.3175) / (numberOfQuantiles + 0.365)); double q = NUMquantile (numberOfData, data.peek(), ui); double zq = - NUMinvGaussQ (ui); thy data[irow][1] = zq; // along x thy data[irow][2] = q; // along y if (numberOfSigmas == 0) { xmin = zq < xmin ? zq : xmin; xmax = zq > xmax ? zq : xmax; ymin = q < ymin ? q : ymin; ymax = q > ymax ? q : ymax; } } TableOfReal_drawScatterPlot (thee.peek(), g, 1, 2, 1, numberOfQuantiles, xmin, xmax, ymin, ymax, labelSize, 0, label, garnish); Graphics_setInner (g); Graphics_setLineType (g, Graphics_DOTTED); Graphics_line (g, xmin, ymin, xmax, ymax); Graphics_setLineType (g, Graphics_DRAWN); Graphics_unsetInner (g); } catch (MelderError) { Melder_clearError (); // drawing errors shall be ignored } } void Table_quantileQuantilePlot_betweenLevels (Table me, Graphics g, long dataColumn, long factorColumn, const char32 *xlevel, const char32 *ylevel, long numberOfQuantiles, double xmin, double xmax, double ymin, double ymax, int labelSize, const char32 *plotLabel, int garnish) { try { if (dataColumn < 1 || dataColumn > my numberOfColumns || factorColumn < 1 || factorColumn > my numberOfColumns) return; Table_numericize_Assert (me, dataColumn); long numberOfData = my rows -> size; autoNUMvector xdata (1, numberOfData); autoNUMvector ydata (1, numberOfData); long xnumberOfData = 0, ynumberOfData = 0; for (long irow = 1; irow <= numberOfData; irow++) { char32 *label = ((TableRow) my rows -> item [irow]) -> cells [factorColumn] . string; double val = ((TableRow) my rows -> item [irow]) -> cells [dataColumn] . number; if (Melder_equ (label, xlevel)) { xdata[++xnumberOfData] = val; } else if (Melder_equ (label, ylevel)) { ydata[++ynumberOfData] = val; } } if (xmin == xmax) { NUMvector_extrema (xdata.peek(), 1, xnumberOfData, &xmin, &xmax); if (xmin == xmax) { xmin -= 1.0; xmax += 1.0; } } if (ymin == ymax) { NUMvector_extrema (ydata.peek(), 1, ynumberOfData, &ymin, &ymax); if (ymin == ymax) { ymin -= 1.0; ymax += 1.0; } } Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_setInner (g); Graphics_quantileQuantilePlot (g, numberOfQuantiles, xdata.peek(), xnumberOfData, ydata.peek(), ynumberOfData, xmin, xmax, ymin, ymax, labelSize, plotLabel); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, Melder_cat (my columnHeaders [dataColumn].label, U" (", xlevel, U")")); Graphics_marksBottom (g, 2, true, true, false); Graphics_textLeft (g, true, Melder_cat (my columnHeaders [dataColumn].label, U" (", ylevel, U")")); Graphics_marksLeft (g, 2, true, true, false); } } catch (MelderError) { Melder_clearError (); // drawing errors shall be ignored } } void Table_quantileQuantilePlot (Table me, Graphics g, long xcolumn, long ycolumn, long numberOfQuantiles, double xmin, double xmax, double ymin, double ymax, int labelSize, const char32 *plotLabel, int garnish) { try { if (xcolumn < 1 || xcolumn > my numberOfColumns || ycolumn < 1 || ycolumn > my numberOfColumns) return; Table_numericize_Assert (me, xcolumn); Table_numericize_Assert (me, ycolumn); long numberOfData = my rows -> size; autoNUMvector xdata (1, numberOfData); autoNUMvector ydata (1, numberOfData); for (long irow = 1; irow <= numberOfData; irow++) { xdata[irow] = ((TableRow) my rows -> item [irow]) -> cells [xcolumn] . number; ydata[irow] = ((TableRow) my rows -> item [irow]) -> cells [ycolumn] . number; } if (xmin == xmax) { NUMvector_extrema (xdata.peek(), 1, numberOfData, &xmin, &xmax); if (xmin == xmax) { xmin -= 1.0; xmax += 1.0; } } if (ymin == ymax) { NUMvector_extrema (ydata.peek(), 1, numberOfData, &ymin, &ymax); if (ymin == ymax) { ymin -= 1.0; ymax += 1.0; } } Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_setInner (g); Graphics_quantileQuantilePlot (g, numberOfQuantiles, xdata.peek(), numberOfData, ydata.peek(), numberOfData, xmin, xmax, ymin, ymax, labelSize, plotLabel); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); if (my columnHeaders [xcolumn].label) { Graphics_textBottom (g, true, my columnHeaders [xcolumn].label); } Graphics_marksBottom (g, 2, true, true, false); if (my columnHeaders [ycolumn].label) { Graphics_textLeft (g, true, my columnHeaders [ycolumn].label); } Graphics_marksLeft (g, 2, true, true, false); } } catch (MelderError) { Melder_clearError (); // drawing errors shall be ignored } } void Table_boxPlots (Table me, Graphics g, long dataColumn, long factorColumn, double ymin, double ymax, int garnish) { try { if (dataColumn < 1 || dataColumn > my numberOfColumns || factorColumn < 1 || factorColumn > my numberOfColumns) return; Table_numericize_Assert (me, dataColumn); long numberOfData = my rows -> size; autoStringsIndex si = Table_to_StringsIndex_column (me, factorColumn); long numberOfLevels = si -> classes -> size; if (ymin == ymax) { ymax = Table_getMaximum (me, dataColumn); ymin = Table_getMinimum (me, dataColumn); if (ymax == ymin) { ymax += 1.0; ymin -= 1.0; } } Graphics_setWindow (g, 1.0 - 0.5, numberOfLevels + 0.5, ymin, ymax); Graphics_setInner (g); autoNUMvector data (1, numberOfData); for (long ilevel = 1; ilevel <= numberOfLevels; ilevel++) { long numberOfDataInLevel = 0; for (long k = 1; k <= numberOfData; k++) { if (si -> classIndex[k] == ilevel) { data[++numberOfDataInLevel] = Table_getNumericValue_Assert (me, k, dataColumn); } } Graphics_boxAndWhiskerPlot (g, data.peek(), numberOfDataInLevel, ilevel, 0.2, 0.35, ymin, ymax); } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); for (long ilevel = 1; ilevel <= numberOfLevels; ilevel++) { SimpleString ss = (SimpleString) si -> classes -> item[ilevel]; Graphics_markBottom (g, ilevel, false, true, false, ss -> string); } Graphics_marksLeft (g, 2, true, true, false); } } catch (MelderError) { Melder_clearError (); // drawing errors shall be ignored } } void Table_boxPlotsWhere (Table me, Graphics g, char32 *dataColumns_string, long factorColumn, double ymin, double ymax, int garnish, const char32 *formula, Interpreter interpreter) { try { long numberOfSelectedColumns; autoNUMvector dataColumns (Table_getColumnIndicesFromColumnLabelString (me, dataColumns_string, &numberOfSelectedColumns), 1); if (factorColumn < 1 || factorColumn > my numberOfColumns) { return; } Formula_compile (interpreter, me, formula, kFormula_EXPRESSION_TYPE_UNKNOWN, true); long numberOfData = my rows -> size; autoStringsIndex si = Table_to_StringsIndex_column (me, factorColumn); long numberOfLevels = si -> classes -> size; if (ymin == ymax) { ymin = 1e308, ymax = -ymin; for (long icol = 1; icol <= numberOfSelectedColumns; icol++) { double ymaxi = Table_getMaximum (me, dataColumns[icol]); double ymini = Table_getMinimum (me, dataColumns[icol]); ymax = ymaxi > ymax ? ymaxi : ymax; ymin = ymini < ymin ? ymini : ymin; } if (ymax == ymin) { ymax += 1.0; ymin -= 1.0; } } Graphics_setWindow (g, 1.0 - 0.5, numberOfLevels + 0.5, ymin, ymax); Graphics_setInner (g); double boxWidth = 4.0, spaceBetweenBoxesInGroup = 1.0, barWidth = boxWidth / 3.0; double spaceBetweenGroupsdiv2 = 3.0 / 2.0; double widthUnit = 1.0 / (numberOfSelectedColumns * boxWidth + (numberOfSelectedColumns - 1) * spaceBetweenBoxesInGroup + spaceBetweenGroupsdiv2 + spaceBetweenGroupsdiv2); autoNUMvector data (1, numberOfData); for (long ilevel = 1; ilevel <= numberOfLevels; ilevel++) { double xlevel = ilevel; for (long icol = 1; icol <= numberOfSelectedColumns; icol++) { long numberOfDataInLevelColumn = 0; for (long irow = 1; irow <= numberOfData; irow++) { if (si -> classIndex[irow] == ilevel) { struct Formula_Result result; Formula_run (irow, dataColumns[icol], & result); if (result.result.numericResult != 0.0) { data[++numberOfDataInLevelColumn] = Table_getNumericValue_Assert (me, irow, dataColumns[icol]); } } } if (numberOfDataInLevelColumn > 0) { // determine position double xc = xlevel - 0.5 + (spaceBetweenGroupsdiv2 + (icol - 1) * (boxWidth + spaceBetweenBoxesInGroup) + boxWidth / 2) * widthUnit; Graphics_boxAndWhiskerPlot (g, data.peek(), numberOfDataInLevelColumn, xc, 0.5 * barWidth * widthUnit , 0.5 * boxWidth * widthUnit, ymin, ymax); } } } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); for (long ilevel = 1; ilevel <= numberOfLevels; ilevel++) { SimpleString ss = (SimpleString) si -> classes -> item[ilevel]; Graphics_markBottom (g, ilevel, false, true, false, ss -> string); } Graphics_marksLeft (g, 2, true, true, false); } } catch (MelderError) { Melder_clearError (); // drawing errors shall be ignored } } void Table_distributionPlotWhere (Table me, Graphics g, long dataColumn, double minimum, double maximum, long nBins, double freqMin, double freqMax, int garnish, const char32 *formula, Interpreter interpreter) { try { if (dataColumn < 1 || dataColumn > my numberOfColumns) return; Formula_compile (interpreter, me, formula, kFormula_EXPRESSION_TYPE_UNKNOWN, true); Table_numericize_Assert (me, dataColumn); long n = my rows -> size, mrow = 0; autoMatrix thee = Matrix_create (1, 1, 1, 1, 1, 0, n + 1, n, 1, 1); for (long irow = 1; irow <= n; irow++) { struct Formula_Result result; Formula_run (irow, dataColumn, & result); if (result.result.numericResult != 0.0) { thy z[1][++mrow] = Table_getNumericValue_Assert (me, irow, dataColumn); } } Matrix_drawDistribution (thee.peek(), g, 0, 1, 0.5, mrow+0.5, minimum, maximum, nBins, freqMin, freqMax, 0, garnish); } catch (MelderError) { Melder_clearError (); // drawing errors shall be ignored } } static Strings itemizeColourString (const char32 *colourString) { // remove all spaces within { } so each {1,2,3} can be itemized long nmatches_sub = 0; const char32 *searchRE = U"\\{\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*\\}"; regexp *compiledRE = CompileRE_throwable (searchRE, 0); autoMelderString colour; MelderString_append (&colour, str_replace_regexp (colourString, compiledRE, U"{\\1,\\2,\\3}", 0, &nmatches_sub)); autoStrings thee = Strings_createAsTokens (colour.string); return thee.transfer(); } static Graphics_Colour Strings_colourToValue (Strings me, long index) { if (index < 0 || index > my numberOfStrings) { return Graphics_GREY; } Graphics_Colour colourValue; char32 *p = my strings[index]; while (*p == U' ' || *p == U'\t') p ++; *p = (char32) tolower ((int) *p); char32 first = *p; if (first == U'{') { colourValue.red = Melder_atof (++ p); p = (char32 *) str32chr (p, U','); if (! p) return Graphics_GREY; colourValue.green = Melder_atof (++ p); p = (char32 *) str32chr (p, U','); if (! p) return Graphics_GREY; colourValue.blue = Melder_atof (++ p); } else { *p = (char32) tolower ((int) *p); if (str32equ (p, U"black")) colourValue = Graphics_BLACK; else if (str32equ (p, U"white")) colourValue = Graphics_WHITE; else if (str32equ (p, U"red")) colourValue = Graphics_RED; else if (str32equ (p, U"green")) colourValue = Graphics_GREEN; else if (str32equ (p, U"blue")) colourValue = Graphics_BLUE; else if (str32equ (p, U"yellow")) colourValue = Graphics_YELLOW; else if (str32equ (p, U"cyan")) colourValue = Graphics_CYAN; else if (str32equ (p, U"magenta")) colourValue = Graphics_MAGENTA; else if (str32equ (p, U"maroon")) colourValue = Graphics_MAROON; else if (str32equ (p, U"lime")) colourValue = Graphics_LIME; else if (str32equ (p, U"navy")) colourValue = Graphics_NAVY; else if (str32equ (p, U"teal")) colourValue = Graphics_TEAL; else if (str32equ (p, U"purple")) colourValue = Graphics_PURPLE; else if (str32equ (p, U"olive")) colourValue = Graphics_OLIVE; else if (str32equ (p, U"pink")) colourValue = Graphics_PINK; else if (str32equ (p, U"silver")) colourValue = Graphics_SILVER; else if (str32equ (p, U"grey")) colourValue = Graphics_GREY; else { double grey = Melder_atof (p); grey = grey < 0 ? 0 : (grey > 1 ? 1 : grey); colourValue.red = colourValue.green = colourValue.blue = grey; } } return colourValue; } long Table_getNumberOfRowsWhere (Table me, const char32 *formula, Interpreter interpreter) { long numberOfRows = 0; Formula_compile (interpreter, me, formula, kFormula_EXPRESSION_TYPE_UNKNOWN, true); for (long irow = 1; irow <= my rows -> size; irow ++) { struct Formula_Result result; Formula_run (irow, 1, & result); if (result.result.numericResult != 0.0) { numberOfRows++; } } return numberOfRows; } long *Table_findRowsMatchingCriterion (Table me, const char32 *formula, Interpreter interpreter, long *numberOfMatches) { try { *numberOfMatches = Table_getNumberOfRowsWhere (me, formula, interpreter); if (*numberOfMatches < 1) { Melder_throw (U"No rows selected."); } Formula_compile (interpreter, me, formula, kFormula_EXPRESSION_TYPE_UNKNOWN, true); // again? autoNUMvector selectedRows (1, *numberOfMatches); long n = 0; for (long irow =1; irow <= my rows -> size; irow++) { struct Formula_Result result; Formula_run (irow, 1, & result); if (result.result.numericResult != 0.0) { selectedRows[++n] = irow; } } Melder_assert (n == *numberOfMatches); return selectedRows.transfer(); } catch (MelderError) { Melder_throw (me, U": cannot find matches."); } } void Table_barPlotWhere (Table me, Graphics g, const char32 *columnLabels, double ymin, double ymax, const char32 *factorColumn, double xoffsetFraction, double interbarFraction, double interbarsFraction, const char32 *colours, double angle, int garnish, const char32 *formula, Interpreter interpreter) { try { long numberOfColumns, numberOfRowMatches = 0; autoNUMvector columnIndex (Table_getColumnIndicesFromColumnLabelString (me, columnLabels, &numberOfColumns), 1); long labelIndex = Table_findColumnIndexFromColumnLabel (me, factorColumn); autoStrings colour = itemizeColourString (colours);// removes all spaces within { } so each {} can be parsed as 1 item autoNUMvector selectedRows (Table_findRowsMatchingCriterion (me, formula, interpreter, &numberOfRowMatches), 1); if (ymax <= ymin) { // autoscaling ymin = 1e308; ymax= - ymin; for (long icol = 1; icol <= numberOfColumns; icol++) { double cmin, cmax; Table_columnExtremesFromSelectedRows (me, columnIndex[icol], selectedRows.peek(), numberOfRowMatches, &cmin, &cmax); if (cmin < ymin) { ymin = cmin; } if (cmax > ymax) { ymax = cmax; } } ymin = ymin > 0 ? 0 : ymin; ymax = ymax < 0 ? 0 : ymax; } Graphics_setInner (g); Graphics_setWindow (g, 0, 1, ymin, ymax); long numberOfGroups = numberOfRowMatches; long groupSize = numberOfColumns; double bar_width = 1 / (numberOfGroups * groupSize + 2 * xoffsetFraction + (numberOfGroups - 1) * interbarsFraction + numberOfGroups * (groupSize - 1) * interbarFraction); double dx = (interbarsFraction + groupSize + (groupSize - 1) * interbarFraction) * bar_width; for (long icol = 1; icol <= groupSize; icol++) { double xb = xoffsetFraction * bar_width + (icol - 1) * (1 + interbarFraction) * bar_width; double x1 = xb; Graphics_Colour color = Strings_colourToValue (colour.peek(), icol); for (long irow = 1; irow <= numberOfRowMatches; irow++) { double x2 = x1 + bar_width; double y2 = Table_getNumericValue_Assert (me, selectedRows[irow], columnIndex[icol]); y2 = y2 > ymax ? ymax : (y2 < ymin ? ymin : y2); double y1 = ymin < 0 ? 0 : ymin; Graphics_setColour (g, color); Graphics_fillRectangle (g, x1, x2, y1, y2); Graphics_setGrey (g, 0); /* Black */ Graphics_rectangle (g, x1, x2, y1, y2); x1 += dx; } } //Graphics_unsetInner (g); if (garnish) { if (labelIndex > 0) { double y = ymin, xb = (xoffsetFraction + 0.5 * (groupSize + (groupSize - 1) * interbarFraction)) * bar_width; double lineSpacing = Graphics_dyMMtoWC (g, 1.5 * Graphics_inqFontSize (g) * 25.4 / 72); int currentFontSize = Graphics_inqFontSize (g); Graphics_setTextRotation (g, angle); if (angle < 0) { y -= 0.3*lineSpacing; xb -= 0.5 * bar_width; Graphics_setFontSize (g, currentFontSize - (currentFontSize > 12 ? 2 : 1)); Graphics_setTextAlignment (g, Graphics_LEFT, Graphics_TOP); } else if (angle > 0) { y -= 0.3*lineSpacing; xb += 0.5 * bar_width; Graphics_setFontSize (g, currentFontSize - (currentFontSize > 12 ? 2 : 1)); Graphics_setTextAlignment (g, Graphics_RIGHT, Graphics_TOP); } else { Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_TOP); } for (long irow = 1; irow <= numberOfGroups; irow++) { const char32 *label = Table_getStringValue_Assert (me, selectedRows[irow], labelIndex); if (label) { //Graphics_markBottom (g, xb, false, false, false, label); Graphics_text (g, xb, ymin - g -> vertTick, label); // was y } xb += dx; } Graphics_setFontSize (g, currentFontSize); Graphics_setTextRotation (g, 0); } } Graphics_unsetInner (g); if (garnish) { if (ymin * ymax < 0) { Graphics_markLeft (g, 0.0, true, true, true, nullptr); } Graphics_drawInnerBox (g); Graphics_marksLeft (g, 2, true, true, false); } } catch (MelderError) { Melder_clearError (); // drawing errors shall be ignored } } static int Graphics_getConnectingLine (Graphics g, const char32 *text1, double x1, double y1, const char32 *text2, double x2, double y2, double *x3, double *y3, double *x4, double *y4) { int drawLine = 0; double width1 = Graphics_textWidth (g, text1), width2 = Graphics_textWidth (g, text2); double h = Graphics_dyMMtoWC (g, 1.5 * Graphics_inqFontSize (g) * 25.4 / 72) / 1.5; double xi[3], yi[3], xleft = x1 < x2 ? x1 : x2, xright = x2 > x1 ? x2 : x1; int numberOfIntersections = NUMgetIntersectionsWithRectangle (x1, y1, x2, y2, xleft - width1 / 2.0, y1 - h/2, xleft + width1 / 2.0, y1 + h/2, xi, yi); if (numberOfIntersections == 1) { *x3 = xi[1]; *y3 = yi[1]; numberOfIntersections = NUMgetIntersectionsWithRectangle (x1, y1, x2, y2, xright - width2 / 2.0, y2 - h/2, xright + width2 / 2.0, y2 + h/2, xi, yi); if (numberOfIntersections == 1) { *x4 = xi[1]; *y4 = yi[1]; drawLine = 1; } } return drawLine; } // take the xcolumn as labels if non-numeric column else as numbers and arrange distances accordingly. void Table_lineGraphWhere (Table me, Graphics g, long xcolumn, double xmin, double xmax, long ycolumn, double ymin, double ymax, const char32 *symbol, double angle, int garnish, const char32 *formula, Interpreter interpreter) { try { if (ycolumn < 1 || ycolumn > my numberOfColumns) return; long numberOfSelectedRows = 0; autoNUMvector selectedRows (Table_findRowsMatchingCriterion (me, formula, interpreter, &numberOfSelectedRows), 1); if (ymax <= ymin) { // autoscaling Table_columnExtremesFromSelectedRows (me, ycolumn, selectedRows.peek(), numberOfSelectedRows, &ymin, &ymax); } // the following also catches xcolumn = 0 ! bool xIsNumeric = Table_selectedColumnPartIsNumeric (me, xcolumn, selectedRows.peek(), numberOfSelectedRows); if (xmin >= xmax) { if (xIsNumeric) { Table_columnExtremesFromSelectedRows (me, xcolumn, selectedRows.peek(), numberOfSelectedRows, &xmin, &xmax); } else { xmin = 0; xmax = numberOfSelectedRows + 1; } } Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); double x1, y1; double lineSpacing = Graphics_dyMMtoWC (g, 1.5 * Graphics_inqFontSize (g) * 25.4 / 72.0); //double symbolHeight = lineSpacing / 1.5; for (long i = 1; i <= numberOfSelectedRows; i++) { double y2 = Table_getNumericValue_Assert (me, selectedRows[i], ycolumn); double x2 = xIsNumeric ? Table_getNumericValue_Assert (me, selectedRows[i], xcolumn) : i; //double symbolWidth = 0; if (x2 >= xmin && (x2 <= xmax || x1 < xmax)) { if (symbol && y2 >= ymin && y2 <= ymax && x2 <= xmax) { Graphics_text (g, x2, y2, symbol); //symbolWidth = Graphics_textWidth (g, symbol); } if (i > 1) { double x3, y3, x4, y4, xo1, yo1, xo2, yo2; if (Graphics_getConnectingLine (g, symbol, x1, y1, symbol, x2, y2, &x3, &y3, &x4, &y4) && NUMclipLineWithinRectangle (x3, y3, x4, y4, xmin, ymin, xmax, ymax, &xo1, &yo1, &xo2, &yo2)) { Graphics_line (g, xo1, yo1, xo2, yo2); } } } else { x2 = x2 < xmin ? xmin : xmax; } x1 = x2; y1 = y2; } if (garnish && ! xIsNumeric && xcolumn > 0) { double y = ymin, dx = 0; int currentFontSize = Graphics_inqFontSize (g); Graphics_setTextRotation (g, angle); if (angle < 0) { y -= 0.3*lineSpacing; dx = -0.5; Graphics_setFontSize (g, currentFontSize - (currentFontSize > 12 ? 2 : 1)); Graphics_setTextAlignment (g, Graphics_LEFT, Graphics_TOP); } else if (angle > 0) { y -= 0.3*lineSpacing; dx = 0.5; Graphics_setFontSize (g, currentFontSize - (currentFontSize > 12 ? 2 : 1)); Graphics_setTextAlignment (g, Graphics_RIGHT, Graphics_TOP); } else { Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_TOP); } for (long i = 1; i <= numberOfSelectedRows; i++) { double x2 = i; if (x2 >= xmin && x2 <= xmax) { const char32 *label = Table_getStringValue_Assert (me, selectedRows[i], xcolumn); if (label) { //Graphics_markBottom (g, xb, false, false, false, label); Graphics_text (g, x2 + dx, ymin - g -> vertTick, label); // was y } } } Graphics_setFontSize (g, currentFontSize); Graphics_setTextRotation (g, 0); } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksLeft (g, 2, true, true, false); if (xIsNumeric) { Graphics_marksBottom (g, 2, true, true, false); } } } catch (MelderError) { Melder_clearError (); // drawing errors shall be ignored } } void Table_lagPlotWhere (Table me, Graphics g, long column, long lag, double xmin, double xmax, const char32 *symbol, int labelSize, int garnish, const char32 *formula, Interpreter interpreter) { try { if (column < 1 || column > my rows -> size) { return; } long numberOfSelectedRows = 0; autoNUMvector selectedRows (Table_findRowsMatchingCriterion (me, formula, interpreter, &numberOfSelectedRows), 1); if (xmax <= xmin) { // autoscaling Table_columnExtremesFromSelectedRows (me, column, selectedRows.peek(), numberOfSelectedRows, &xmin, &xmax); } autoNUMvector x (1, numberOfSelectedRows); for (long i = 1; i <= numberOfSelectedRows; i++) { x[i] = Table_getNumericValue_Assert (me, selectedRows[i], column); } Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, xmin, xmax); Graphics_lagPlot (g, x.peek(), numberOfSelectedRows, xmin, xmax, lag, labelSize, symbol); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); if (my columnHeaders [column]. label) { Graphics_textLeft (g, true, my columnHeaders[column].label); Graphics_textBottom (g, true, Melder_cat (my columnHeaders[column].label, U" (lag = ", lag, U")")); } } } catch (MelderError) { Melder_clearError (); // drawing errors shall be ignored } } Table Table_extractRowsWhere (Table me, const char32 *formula, Interpreter interpreter) { try { Formula_compile (interpreter, me, formula, kFormula_EXPRESSION_TYPE_UNKNOWN, true); autoTable thee = Table_create (0, my numberOfColumns); for (long icol = 1; icol <= my numberOfColumns; icol ++) { autostring32 newLabel = Melder_dup (my columnHeaders [icol]. label); thy columnHeaders [icol]. label = newLabel.transfer(); } for (long irow = 1; irow <= my rows -> size; irow ++) { struct Formula_Result result; Formula_run (irow, 1, & result); if (result.result.numericResult != 0.0) { TableRow row = static_cast (my rows -> item [irow]); autoTableRow newRow = Data_copy (row); Collection_addItem (thy rows, newRow.transfer()); } } if (thy rows -> size == 0) { Melder_warning (U"No row matches criterion."); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no Table could be extracted."); } } static TableOfReal Table_to_TableOfRealWhere (Table me, const char32 *columnLabels, const char32 *factorColumn, const char32 *formula, Interpreter interpreter) { try { long numberOfColumns, numberOfSelectedRows = 0; long factorColIndex = Table_findColumnIndexFromColumnLabel (me, factorColumn); autoNUMvector columnIndex (Table_getColumnIndicesFromColumnLabelString (me, columnLabels, &numberOfColumns), 1); autoNUMvector selectedRows (Table_findRowsMatchingCriterion (me, formula, interpreter, &numberOfSelectedRows), 1); autoTableOfReal thee = TableOfReal_create (numberOfSelectedRows, numberOfColumns); for (long i = 1; i <= numberOfSelectedRows; i++) { for (long icol = 1; icol <= numberOfColumns; icol++) { double value = Table_getNumericValue_Assert (me, selectedRows[i], columnIndex[icol]); thy data[i][icol] = value; } if (factorColIndex > 0) { // if no factorColumn given labels may be empty const char32 *label = Table_getStringValue_Assert (me, selectedRows[i], factorColIndex); TableOfReal_setRowLabel (thee.peek(), i, label); } } for (long icol = 1; icol <= numberOfColumns; icol++) { TableOfReal_setColumnLabel (thee.peek(), icol, my columnHeaders [columnIndex[icol]].label); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U"No TableOfReal created from Table."); } } static SSCPs Table_to_SSCPsWhere (Table me, const char32 *columnLabels, const char32 *factorColumn, const char32 *formula, Interpreter interpreter) { try { autoTableOfReal thee = Table_to_TableOfRealWhere (me, columnLabels, factorColumn, formula, interpreter); autoSSCPs him = TableOfReal_to_SSCPs_byLabel (thee.peek()); return him.transfer(); } catch (MelderError) { Melder_throw (me, U"No Discriminant created from Table."); } } static long SSCPs_findIndexOfGroupLabel (SSCPs me, const char32 *label) { for (long i = 1; i <= my size; i++) { if (Melder_cmp (Thing_getName ((SSCP) my item[i]), label) == 0) { return i; } } return 0; } static Table Table_and_SSCPs_extractMahalanobisWhere (Table me, SSCPs thee, double numberOfSigmas, int which_Melder_NUMBER, const char32 *factorColumn, const char32 *formula, Interpreter interpreter) { try { SSCP sscp = (SSCP) thy item[1]; long numberOfColumns = sscp -> numberOfColumns, numberOfSelectedRows = 0; long factorColIndex = Table_findColumnIndexFromColumnLabel (me, factorColumn); // can be absent autoNUMvector columnIndex (1, numberOfColumns); autoNUMvector vector (1, numberOfColumns); autoNUMvector selectedRows (Table_findRowsMatchingCriterion (me, formula, interpreter, &numberOfSelectedRows), 1); for (long icol = 1; icol <= numberOfColumns; icol++) { columnIndex[icol] = Table_getColumnIndexFromColumnLabel (me, sscp -> columnLabels[icol]); // throw if not present } long numberOfGroups = thy size; autoTable him = Table_create (0, my numberOfColumns); for (long icol = 1; icol <= my numberOfColumns; icol ++) { autostring32 newLabel = Melder_dup (my columnHeaders[icol].label); his columnHeaders[icol].label = newLabel.transfer(); } autoOrdered covs = Ordered_create (); for (long igroup = 1; igroup <= numberOfGroups; igroup++) { autoCovariance cov = SSCP_to_Covariance ((SSCP) thy item[igroup], 1); SSCP_expandLowerCholesky (cov.peek()); Collection_addItem (covs.peek(), cov.transfer()); } for (long i = 1; i <= numberOfSelectedRows; i++) { long irow = selectedRows[i]; long igroup = 1; // if factorColIndex == 0 we don't need labels if (factorColIndex > 0) { const char32 *label = Table_getStringValue_Assert (me, irow, factorColIndex); igroup = SSCPs_findIndexOfGroupLabel (thee, label); if (igroup == 0) { Melder_throw (U"The label \"", label, U"\" in row ", irow, U" is not valid in this context."); } } Covariance covi = (Covariance) covs -> item[igroup]; for (long icol = 1; icol <= numberOfColumns; icol++) { vector[icol] = Table_getNumericValue_Assert (me, irow, columnIndex[icol]); } double dm2 = NUMmahalanobisDistance_chi (covi -> lowerCholesky, vector.peek(), covi -> centroid, numberOfColumns, numberOfColumns); if (Melder_numberMatchesCriterion (sqrt (dm2), which_Melder_NUMBER, numberOfSigmas)) { TableRow row = static_cast (my rows -> item [irow]); autoTableRow newRow = Data_copy (row); Collection_addItem (his rows, newRow.transfer()); } } return him.transfer(); } catch (MelderError) { Melder_throw (me, U"Table (mahalanobis) not extracted."); } } Table Table_extractMahalanobisWhere(Table me, const char32 *columnLabels, const char32 *factorColumn, double numberOfSigmas, int which_Melder_NUMBER, const char32 *formula, Interpreter interpreter) { try { autoSSCPs thee = Table_to_SSCPsWhere (me, columnLabels, factorColumn, formula, interpreter); autoTable him = Table_and_SSCPs_extractMahalanobisWhere (me, thee.peek(), numberOfSigmas, which_Melder_NUMBER, factorColumn, formula, interpreter); return him.transfer(); } catch (MelderError) { Melder_throw (me, U"Table not extracted."); } } void Table_drawEllipsesWhere (Table me, Graphics g, long xcolumn, long ycolumn, long factorColumn, double xmin, double xmax, double ymin, double ymax, double numberOfSigmas, long labelSize, int garnish, const char32 *formula, Interpreter interpreter) { try { long numberOfSelectedRows = 0; autoNUMvector selectedRows (Table_findRowsMatchingCriterion (me, formula, interpreter, &numberOfSelectedRows), 1); autoTableOfReal thee = TableOfReal_create (numberOfSelectedRows, 2); for (long i = 1; i <= numberOfSelectedRows; i++) { double x = Table_getNumericValue_Assert (me, selectedRows[i], xcolumn); double y = Table_getNumericValue_Assert (me, selectedRows[i], ycolumn); const char32 *label = Table_getStringValue_Assert (me, selectedRows[i], factorColumn); thy data[i][1] = x; thy data[i][2] = y; TableOfReal_setRowLabel (thee.peek(), i, label); } autoSSCPs him = TableOfReal_to_SSCPs_byLabel (thee.peek()); int confidence = 0; if (ymax == ymin) { // autoscaling SSCPs_getEllipsesBoundingBoxCoordinates (him.peek(), numberOfSigmas, confidence, &xmin, &xmax, &ymin, &ymax); } Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_setInner (g); for (long i = 1; i <= his size; i++) { SSCP sscpi = (SSCP) his item[i]; double scalei = SSCP_getEllipseScalefactor (sscpi, numberOfSigmas, confidence); if (scalei > 0) { SSCP_drawTwoDimensionalEllipse_inside (sscpi, g, scalei, Thing_getName (sscpi), labelSize); } } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); if (my columnHeaders [xcolumn]. label) { Graphics_textBottom (g, true, my columnHeaders[xcolumn].label); } if (my columnHeaders [ycolumn]. label) { Graphics_textLeft (g, true, my columnHeaders[ycolumn].label); } } } catch (MelderError) { Melder_clearError (); // drawing errors shall be ignored } } Table Table_extractColumnRanges (Table me, char32 *ranges) { try { long numberOfSelectedColumns, numberOfRows = my rows -> size; autoNUMvector columnRanges (NUMstring_getElementsOfRanges (ranges, my numberOfColumns, & numberOfSelectedColumns, nullptr, U"columnn number", true), 1); autoTable thee = Table_createWithoutColumnNames (numberOfRows, numberOfSelectedColumns); for (long icol = 1; icol <= numberOfSelectedColumns; icol++) { Table_setColumnLabel (thee.peek(), icol, my v_getColStr (columnRanges[icol])); } for (long irow = 1; irow <= numberOfRows; irow++) { //TableRow row = (TableRow) thy rows -> item[irow]; for (long icol = 1; icol <= numberOfSelectedColumns; icol++) { const char32 *value = Table_getStringValue_Assert (me, irow, columnRanges[icol]); Table_setStringValue (thee.peek(), irow, icol, value); } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no column range extracted."); } } /* End of file Table_extensions.cpp */ praat-6.0.04/dwtools/Table_extensions.h000066400000000000000000000121071261542461700200730ustar00rootroot00000000000000#ifndef _Table_extensions_h_ #define _Table_extensions_h_ /* Table_extensions.h * * Copyright (C) 1993-2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020411 initial GPL djmw 20131220 Latest modification. */ #include "TableOfReal.h" #include "Collection.h" #include "Pattern.h" #include "Categories.h" #include "Strings_.h" #include "SSCP.h" #include "Table.h" long Table_getNumberOfRowsWhere (Table me, const char32 *formula, Interpreter interpreter); long *Table_findRowsMatchingCriterion (Table me, const char32 *formula, Interpreter interpreter, long *numberOfMatches); Table Table_createFromPetersonBarneyData (); Table Table_createFromPolsVanNieropData (); Table Table_createFromWeeninkData (); Table Table_createFromEspositoData (); Table Table_createFromGanongData (); double Table_getMedianAbsoluteDeviation (Table me, long columnNumber); // Two one-way tests for normal and non-normally distributed data, respectively. autoTable Table_getOneWayAnalysisOfVarianceF (Table me, long column, long groupColumn, autoTable *means, autoTable *meansDiff, autoTable *meansDiffProbabilities); Table Table_getOneWayKruskalWallis (Table me, long column, long groupColumn, double *degreesOfFreedom, double *kruskalWallis, double *probability); Table Table_getTwoWayAnalysisOfVarianceF (Table me, long column, long groupColumnA, long groupColumnB, Table *means, Table *factorLevelSizes); void Table_verticalErrorBarsPlotWhere (Table me, Graphics g, long xcolumn, long ycolumn, double xmin, double xmax, double ymin, double ymax, long yci_min, long yci_max, double bar_mm, int garnish, const char32 *formula, Interpreter interpreter); void Table_horizontalErrorBarsPlotWhere (Table me, Graphics g, long xcolumn, long ycolumn, double xmin, double xmax, double ymin, double ymax, long xci_min, long xci_max, double bar_mm, int garnish, const char32 *formula, Interpreter interpreter); void Table_normalProbabilityPlot (Table me, Graphics g, long column, long numberOfQuantiles, double numberOfSigmas, int labelSize, const char32 *label, int garnish); void Table_quantileQuantilePlot (Table me, Graphics g, long xcolumn, long ycolumn, long numberOfQuantiles, double xmin, double xmax, double ymin, double ymax, int labelSize, const char32 *label, int garnish); void Table_quantileQuantilePlot_betweenLevels (Table me, Graphics g, long dataColumn, long factorColumn, const char32 *xlevel, const char32 *ylevel, long numberOfQuantiles, double xmin, double xmax, double ymin, double ymax, int labelSize, const char32 *label, int garnish); void Table_boxPlots (Table me, Graphics g, long dataColumn, long factorColumn, double ymin, double ymax, int garnish); void Table_boxPlotsWhere (Table me, Graphics g, char32 *dataColumns_string, long factorColumn, double ymin, double ymax, int garnish, const char32 *formula, Interpreter interpreter); Table Table_extractRowsWhere (Table me, const char32 *formula, Interpreter interpreter); Table Table_extractColumnRanges (Table me, char32 *ranges); Table Table_extractMahalanobisWhere (Table me, const char32 *columnLabels, const char32 *factorColumn, double numberOfSigmas, int which_Melder_NUMBER, const char32 *formula, Interpreter interpreter); void Table_distributionPlotWhere (Table me, Graphics g, long dataColumn, double minimum, double maximum, long nBins, double freqMin, double freqMax, int garnish, const char32 *formula, Interpreter interpreter); void Table_barPlotWhere (Table me, Graphics g, const char32 *columnLabels, double ymin, double ymax, const char32 *labelColumn, double xoffsetFraction, double interbarFraction, double interbarsFraction, const char32 *colours, double angle, int garnish, const char32 *formula, Interpreter interpreter); void Table_lineGraphWhere (Table me, Graphics g, long xcolumn, double xmin, double xmax, long ycolumn, double ymin, double ymax, const char32 *symbol, double angle, int garnish, const char32 *formula, Interpreter interpreter); void Table_lagPlotWhere (Table me, Graphics g, long column, long lag, double xmin, double xmax, const char32 *symbol, int labelSize, int garnish, const char32 *formula, Interpreter interpreter); void Table_drawEllipsesWhere (Table me, Graphics g, long xcolumn, long ycolumn, long labelcolumn, double xmin, double xmax, double ymin, double ymax, double numberOfSigmas, long labelSize, int garnish, const char32 *formula, Interpreter interpreter); void Table_printAsAnovaTable (Table me); void Table_printAsMeansTable (Table me); #endif // _Table_extensions_h_ praat-6.0.04/dwtools/TextGrid_extensions.cpp000066400000000000000000000677531261542461700211520ustar00rootroot00000000000000/* TextGrid_extensions.cpp * * Copyright (C) 1993-2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020702 GPL header djmw 20020702 +TextGrid_extendTime djmw 20051215 Corrected a bug in TextGrid_readFromTIMITLabelFile that caused a crash when the first number in a file was not 0 (in that case an empty interval was added as the first element in the tier). djmw 20060517 Added (TextTier|IntervalTier|TextGrid)_changeLabels. djmw 20060712 TextGrid_readFromTIMITLabelFile: don't set first boundary to zero for .wrd files. djmw 20060921 Added IntervalTier_cutIntervalOnLabelMatch, IntervalTier_cutIntervals_minimumDuration djmw 20061113 Reassign item in list after a deletion. djmw 20061116 Added IntervalTier_cutInterval to correct a bug in IntervalTier_removeBoundary... djmw 20071008 Removed two unused variables. djmw 20071202 Melder_warning */ #include #include "TextGrid_extensions.h" #include "NUM2.h" struct TIMIT_key { const char *timitLabel, *ipaLabel; } TIMIT_toIpaTable[] = { {"", ""}, /* Vowels */ {"iy", "i"}, /* beet: bcl b IY tcl t */ {"ih", "\\ic"}, /* bit: bcl b IH tcl t */ {"eh", "\\ep"}, /* bet: bcl b EH tcl t */ {"ey", "e"}, /* bait: bcl b EY tcl t */ {"ae", "\\ae"}, /* bat: bcl b AE tcl t */ {"aa", "\\as"}, /* bott: bcl b AA tcl t */ {"aw", "a\\hs"}, /* bout: bcl b AW tcl t */ {"ay", "a\\ic"}, /* bite: bcl b AY tcl t */ {"ah", "\\vt"}, /* but: bcl b AH tcl t */ {"ao", "\\ct"}, /* bought: bcl b AO tcl t */ {"oy", "\\ct\\ic"}, /* boy: bcl b OY */ {"ow", "o"}, /* boat: bcl b OW tcl t */ {"uh", "\\hs"}, /* book: bcl b UH tcl t */ {"uw", "u"}, /* boot: bcl b UW tcl t */ /* fronted allophone of uw (alveolair contexts) */ {"ux", "\\u\""}, /* toot: tcl t UX tcl t */ {"er", "\\er\\hr"}, /* bird: bcl b ER dcl d */ {"ax", "\\sw"}, /* about: AX bcl b aw tcl t */ {"ix", "\\i-"}, /* debit: dcl d eh bcl b IX tcl t */ {"axr", "\\sr"}, /* butter: bcl ah dx AXR */ /* devoiced schwa, very short */ {"ax-h", "\\sw\\ov"}, /* suspect: s AX-H s pcl p eh kcl k tcl t */ /* Semivowels and glides */ {"l", "l"}, /* lay: L ey */ {"r", "r"}, /* ray: R ey */ {"w", "w"}, /* way: w ey */ {"y", "j"}, /* yacht: Y aa tcl t */ {"hh", "h" }, /* hay: HH ey*/ /* voiced allophone of h */ {"hv", "\\hh"}, /* ahead: ax HV eh dcl d */ {"el", "l\\|v"}, /* bottle: bcl b aa tcl t EL */ /* Nasals */ {"m", "m"}, /* mom: M aa M */ {"n", "n"}, /* noon: N uw N*/ {"ng", "\\ng"}, /* sing: s ih NG */ {"em", "m\\|v"}, /* bottom: b aa tcl t EM */ {"en", "n\\|v"}, /* button: b ah q EN */ {"eng", "\\ng\\|v"}, /* washington: w aa sh ENG tcl t ax n */ /* nasal flap */ {"nx", "n^\\fh"}, /* winner: wih NX axr */ /* Fricatives */ {"s", "s"}, /* sea: S iy */ {"sh", "\\sh"}, /* she: SH iy */ {"z", "z"}, /* zone: Z ow n */ {"zh", "\\zh"}, /* azure: ae ZH er */ {"f", "f"}, /* fin: F ih n */ {"th", "\\te"}, /* thin: TH ih n */ {"v", "v"}, /* van: v ae n */ {"dh", "\\dh"}, /* then: DH en */ /* Affricates */ {"jh", "d\\zh"}, /* joke: DCL JH ow kcl k */ {"ch", "t\\sh"}, /* choke TCL CH ow kcl k */ /* Stops */ {"b", "b"}, /* bee: BCL B iy */ {"d", "d"}, /* day: DCL D ey */ {"g", "g"}, /* gay: GCL G ey */ {"p", "p"}, /* pea: PCL P iy */ {"t", "t"}, /* tea: TCL T iy */ {"k", "k"}, /* key: KCL K iy */ /* 20140315: Added silences before the burst */ {"bcl", ""}, {"dcl", ""}, {"gcl", ""}, {"pcl", ""}, {"tcl", ""}, {"kcl", ""}, /* flap */ {"dx", "\\fh"}, /* muddy: m ah DX iy & dirty: dcl d er DX iy */ /* glottal stop */ {"q", "?"}, /* Others */ {"pau", ""}, /* pause */ {"epi", ""}, /* epenthetic silence */ {"h#", ""}, /* marks start and end piece of sentence */ /* the following markers only occur in the dictionary */ {"1", "1"}, /* primary stress marker */ {"2", "2"} /* secondary stress marker */ }; #define TIMIT_NLABELS (sizeof TIMIT_toIpaTable / sizeof TIMIT_toIpaTable[1] - 1) static const char *TIMIT_DELIMITER = "h#"; static const char *timitLabelToIpaLabel (const char timitLabel[]) { for (unsigned int i = 1; i <= TIMIT_NLABELS; i++) if (!strcmp (TIMIT_toIpaTable[i].timitLabel, timitLabel)) { return TIMIT_toIpaTable[i].ipaLabel; } return timitLabel; } static int isTimitPhoneticLabel (const char label[]) { for (unsigned int i = 1; i <= TIMIT_NLABELS; i++) if (! strcmp (TIMIT_toIpaTable[i].timitLabel, label)) { return 1; } return 0; } static int isTimitWord (const char label[]) { const char *p = label; for (; *p; p++) if (isupper (*p) && *p != '\'') { return 0; } return 1; } Any TextGrid_TIMITLabelFileRecognizer (int nread, const char *header, MelderFile file) { char hkruis[3] = "h#", label1[512], label2[512]; int length, phnFile = 0; long it[5]; if (nread < 12 || sscanf (header, "%ld%ld%s%n\n", &it[1], &it[2], label1, &length) != 3 || it[1] < 0 || it[2] <= it[1] || sscanf (&header[length], "%ld%ld%s\n", &it[3], &it[4], label2) != 3 || // 20120512 djmw removed the extra "it[3] < it[2]" check, because otherwise train/dr7/mdlm0/si1864.wrd cannot be read it[4] <= it[3]) { return 0; } if (! strcmp (label1, hkruis)) { if (isTimitPhoneticLabel (label2)) { phnFile = 1; } else if (! isTimitWord (label2)) { return 0; } } else if (! isTimitWord (label1) || ! isTimitWord (label2)) { return 0; } return TextGrid_readFromTIMITLabelFile (file, phnFile); } static void IntervalTier_add (IntervalTier me, double xmin, double xmax, const char32 *label) { long i = IntervalTier_timeToIndex (me, xmin); // xmin is in interval i if (i < 1) { Melder_throw (U"Index too low."); } autoTextInterval newti = TextInterval_create (xmin, xmax, label); TextInterval interval = (TextInterval) my intervals -> item[i]; double xmaxi = interval -> xmax; if (xmax > xmaxi) { Melder_throw (U"Don't know what to do"); // Don't know what to do } if (xmin == interval -> xmin) { if (xmax == interval -> xmax) { // interval already present TextInterval_setText (interval, label); return; } // split interval interval -> xmin = xmax; Collection_addItem (my intervals, newti.transfer()); return; } interval -> xmax = xmin; Collection_addItem (my intervals, newti.transfer()); // extra interval when xmax's are not the same if (xmax < xmaxi) { autoTextInterval newti2 = TextInterval_create (xmax, xmaxi, interval -> text); Collection_addItem (my intervals, newti2.transfer()); } } TextGrid TextGrid_readFromTIMITLabelFile (MelderFile file, int phnFile) { try { double dt = 1.0 / 16000; /* 1 / (TIMIT samplingFrequency) */ double xmax = dt; autofile f = Melder_fopen (file, "r"); // Ending time will only be known after all labels have been read. // We start with a sufficiently long duration (one hour) and correct this later. autoTextGrid me = TextGrid_create (0.0, 3600.0, U"wrd", 0); IntervalTier timit = (IntervalTier) my tiers -> item[1]; long linesRead = 0; char line[200], label[200]; while (fgets (line, 199, f)) { long it1, it2; linesRead++; if (sscanf (line, "%ld%ld%s", &it1, &it2, label) != 3) { Melder_throw (U"Incorrect number of items."); } if (it1 < 0 || it2 <= it1) { Melder_throw (U"Incorrect time at line ", linesRead); } xmax = it2 * dt; double xmin = it1 * dt; long ni = timit -> intervals -> size - 1; if (ni < 1) { ni = 1; // Some files do not start with a first line "0 h#". // Instead they start with " h#", where number1 > 0. // We override number1 with 0. */ if (xmin > 0.0 && phnFile) { xmin = 0.0; } } TextInterval interval = (TextInterval) timit -> intervals -> item[ni]; if (xmin < interval -> xmax && linesRead > 1) { xmin = interval -> xmax; Melder_warning (U"File \"", MelderFile_messageName (file), U"\": Start time set to previous end " U"time for label at line ", linesRead, U"."); } // standard: new TextInterval const char *labelstring = (strncmp (label, "h#", 2) ? label : TIMIT_DELIMITER); IntervalTier_add (timit, xmin, xmax, Melder_peek8to32 (labelstring)); } // Now correct the end times, based on last read interval. // (end time was set to large value!) if (timit -> intervals -> size < 2) { Melder_throw (U"Empty TextGrid"); } Collection_removeItem (timit -> intervals, timit -> intervals -> size); TextInterval interval = (TextInterval) timit -> intervals -> item[timit -> intervals -> size]; timit -> xmax = interval -> xmax; my xmax = xmax; if (phnFile) { // Create tier 2 with IPA symbols autoIntervalTier ipa = Data_copy (timit); Thing_setName (ipa.peek(), U"ipa"); // First change the data in ipa for (long i = 1; i <= ipa -> intervals -> size; i++) { interval = (TextInterval) timit -> intervals -> item[i]; TextInterval_setText ((TextInterval) ipa -> intervals -> item[i], Melder_peek8to32 (timitLabelToIpaLabel (Melder_peek32to8 (interval -> text)))); } Collection_addItem (my tiers, ipa.transfer()); // Then: add to collection Thing_setName (timit, U"phn"); // rename wrd } f.close (file); return me.transfer(); } catch (MelderError) { Melder_throw (U"TextGrid not read from file ", file, U"."); } } TextGrid TextGrids_merge (TextGrid me, TextGrid thee) { try { int at_end = 0, at_start = 1; autoTextGrid g1 = Data_copy (me); autoTextGrid g2 = Data_copy (thee); // The new TextGrid will have the domain // [min(g1->xmin, g2->xmin), max(g1->xmax, g2->xmax)] double extra_time_end = fabs (g2 -> xmax - g1 -> xmax); double extra_time_start = fabs (g2 -> xmin - g1 -> xmin); if (g1 -> xmin > g2 -> xmin) { TextGrid_extendTime (g1.peek(), extra_time_start, at_start); } if (g1 -> xmax < g2 -> xmax) { TextGrid_extendTime (g1.peek(), extra_time_end, at_end); } if (g2 -> xmin > g1 -> xmin) { TextGrid_extendTime (g2.peek(), extra_time_start, at_start); } if (g2 -> xmax < g1 -> xmax) { TextGrid_extendTime (g2.peek(), extra_time_end, at_end); } for (long i = 1; i <= g2 -> tiers -> size; i++) { autoFunction tier = Data_copy ( (Function) g2 -> tiers -> item [i]); Collection_addItem (g1 -> tiers, tier.transfer()); } return g1.transfer(); } catch (MelderError) { Melder_throw (me, U" & ", thee, U": not merged."); } } void IntervalTier_setLaterEndTime (IntervalTier me, double xmax, const char32 *mark) { try { if (xmax <= my xmax) return; // nothing to be done TextInterval ti = (TextInterval) my intervals -> item[my intervals -> size]; Melder_assert (xmax > ti -> xmax); if (mark) { autoTextInterval interval = TextInterval_create (ti -> xmax, xmax, mark); Collection_addItem (my intervals, interval.transfer()); } else { // extend last interval ti -> xmax = xmax; } my xmax = xmax; } catch (MelderError) { Melder_throw (U"Larger end time of IntervalTier not set."); } } void IntervalTier_setEarlierStartTime (IntervalTier me, double xmin, const char32 *mark) { try { if (xmin >= my xmin) return; // nothing to be done TextInterval ti = (TextInterval) my intervals -> item[1]; Melder_assert (xmin < ti -> xmin); if (mark) { autoTextInterval interval = TextInterval_create (xmin, ti -> xmin, mark); Collection_addItem (my intervals, interval.transfer()); } else { // extend first interval ti -> xmin = xmin; } my xmin = xmin; } catch (MelderError) { Melder_throw (U"Earlier start time of IntervalTier not set."); } } void IntervalTier_moveBoundary (IntervalTier me, long iint, bool atStart, double newTime) { try { if (iint < 1 or iint > my intervals -> size) { Melder_throw (U"Interval out of range."); } if ((iint == 1 && atStart) or ((iint == my intervals -> size && not atStart))) { Melder_throw (U"Cannot change the domain."); } TextInterval interval = (TextInterval) my intervals -> item[iint]; if (atStart) { TextInterval pinterval = (TextInterval) my intervals -> item[iint-1]; if (newTime <= pinterval -> xmin) { Melder_throw (U"Cannot move past the start of previous interval."); } pinterval -> xmax = interval -> xmin = newTime; } else { TextInterval ninterval = (TextInterval) my intervals -> item[iint+1]; if (newTime >= ninterval -> xmax) { Melder_throw (U"Cannot move past the end of next interval."); } ninterval -> xmin = interval -> xmax = newTime; } } catch (MelderError) { Melder_throw (me, U": boundary not moved."); } } void TextTier_setLaterEndTime (TextTier me, double xmax, const char32 *mark) { try { if (xmax <= my xmax) return; // nothing to be done if (mark) { autoTextPoint textpoint = TextPoint_create (my xmax, mark); Collection_addItem (my points, textpoint.transfer()); } my xmax = xmax; } catch (MelderError) { Melder_throw (U"Larger end time of TextTier not set."); } } void TextTier_setEarlierStartTime (TextTier me, double xmin, const char32 *mark) { try { if (xmin >= my xmin) return; // nothing to be done if (mark) { autoTextPoint textpoint = TextPoint_create (my xmin, mark); Collection_addItem (my points, textpoint.transfer()); } my xmin = xmin; } catch (MelderError) { Melder_throw (U"Earlier start time of TextTier not set."); } } void TextGrid_setEarlierStartTime (TextGrid me, double xmin, const char32 *imark, const char32 *pmark) { try { if (xmin >= my xmin) { return; } for (long tierNumber = 1 ; tierNumber <= my tiers -> size; tierNumber++) { Function tier = (Function) my tiers -> item [tierNumber]; if (tier -> classInfo == classIntervalTier) { IntervalTier_setEarlierStartTime ((IntervalTier) tier, xmin, imark); } else { TextTier_setEarlierStartTime ((TextTier) tier, xmin, pmark); } } my xmin = xmin; } catch (MelderError) { Melder_throw (U"Earlier start time of TextGrid not set."); } } void TextGrid_setLaterEndTime (TextGrid me, double xmax, const char32 *imark, const char32 *pmark) { try { if (xmax <= my xmax) return; for (long tierNumber =1 ; tierNumber <= my tiers -> size; tierNumber++) { Function tier = (Function) my tiers -> item [tierNumber]; if (tier -> classInfo == classIntervalTier) { IntervalTier_setLaterEndTime ((IntervalTier) tier, xmax, imark); } else { TextTier_setLaterEndTime ((TextTier) tier, xmax, pmark); } } my xmax = xmax; } catch (MelderError) { Melder_throw (U"Larger end time of TextGrid not set."); } } void TextGrid_extendTime (TextGrid me, double extra_time, int position) { autoTextGrid thee = 0; try { double xmax = my xmax, xmin = my xmin; int at_end = position == 0; if (extra_time == 0) { return; } extra_time = fabs (extra_time); // Just in case... thee.reset (Data_copy (me)); if (at_end) { xmax += extra_time; } else { xmin -= extra_time; } for (long i = 1; i <= my tiers -> size; i++) { Function anyTier = (Function) my tiers -> item [i]; double tmin = anyTier -> xmin, tmax = anyTier -> xmax; if (at_end) { anyTier -> xmax = xmax; tmin = tmax; tmax = xmax; } else { anyTier -> xmin = xmin; tmax = tmin; tmin = xmin; } if (anyTier -> classInfo == classIntervalTier) { IntervalTier tier = (IntervalTier) anyTier; autoTextInterval interval = TextInterval_create (tmin, tmax, U""); Collection_addItem (tier -> intervals, interval.transfer()); } } my xmin = xmin; my xmax = xmax; } catch (MelderError) { Melder_throw (me, U": time not extended."); } } void TextGrid_setTierName (TextGrid me, long itier, const char32 *newName) { try { long ntiers = my tiers -> size; if (itier < 1 || itier > ntiers) Melder_throw (U"Tier number (", itier, U") should not be " U"larger than the number of tiers (", ntiers, U")."); Thing_setName ( (Thing) my tiers -> item [itier], newName); } catch (MelderError) { Melder_throw (me, U": tier name not set."); } } static void IntervalTier_cutInterval (IntervalTier me, long index, int extend_option) { long size_pre = my intervals -> size; /* There always must be at least one interval */ if (size_pre == 1 || index > size_pre || index < 1) { return; } TextInterval ti = (TextInterval) my intervals -> item[index]; double xmin = ti -> xmin; double xmax = ti -> xmax; Collection_removeItem (my intervals, index); if (index == 1) { // Change xmin of the new first interval. ti = (TextInterval) my intervals -> item[index]; ti -> xmin = xmin; } else if (index == size_pre) { // Change xmax of the new last interval. ti = (TextInterval) my intervals -> item[my intervals -> size]; ti -> xmax = xmax; } else { if (extend_option == 0) { // extend earlier interval to the right ti = (TextInterval) my intervals -> item[index - 1]; ti -> xmax = xmax; } else { // extend next interval to the left ti = (TextInterval) my intervals -> item[index]; ti -> xmin = xmin; } } } void IntervalTier_removeBoundariesBetweenIdenticallyLabeledIntervals (IntervalTier me, const char32 *label) { try { for (long iint = my intervals -> size; iint > 1; iint--) { TextInterval ti = (TextInterval) my intervals -> item[iint]; if (Melder_equ (ti -> text, label)) { TextInterval tim1 = (TextInterval) my intervals -> item[iint - 1]; if (Melder_equ (tim1 -> text, label)) { Melder_free (tim1 -> text); IntervalTier_removeLeftBoundary (me, iint); } } } } catch (MelderError) { Melder_throw (me, U": boundaries not removed."); } } void IntervalTier_cutIntervals_minimumDuration (IntervalTier me, const char32 *label, double minimumDuration) { long i = 1; while (i <= my intervals -> size) { TextInterval ti = (TextInterval) my intervals -> item[i]; if ( (! label || (ti -> text && str32equ (ti -> text, label))) && ti -> xmax - ti -> xmin < minimumDuration) { IntervalTier_cutInterval (me, i, 0); } else { i++; } } } void IntervalTier_cutIntervalsOnLabelMatch (IntervalTier me, const char32 *label) { long i = 1; while (i < my intervals -> size) { TextInterval ti = (TextInterval) my intervals -> item[i]; TextInterval tip1 = (TextInterval) my intervals -> item[i + 1]; if ( (! label || (ti -> text && str32equ (ti -> text, label))) && (Melder_cmp (ti -> text, tip1 -> text) == 0)) { IntervalTier_cutInterval (me, i, 1); } else { i++; } } } void IntervalTier_changeLabels (I, long from, long to, const char32 *search, const char32 *replace, int use_regexp, long *nmatches, long *nstringmatches) { iam (IntervalTier); try { if (from == 0) { from = 1; } if (to == 0) { to = my intervals -> size; } if (from > to || from < 1 || to > my intervals -> size) { Melder_throw (U"Incorrect specification of where to act."); } if (use_regexp && str32len (search) == 0) { Melder_throw (U"The regex search string cannot be empty.\nYou may search for an empty string with the expression \"^$\""); } long nlabels = to - from + 1; autoNUMvector labels (1, nlabels); for (long i = from; i <= to; i++) { TextInterval interval = (TextInterval) my intervals -> item[i]; labels[i - from + 1] = interval -> text; // Shallow copy. } autostring32vector newlabels (strs_replace (labels.peek(), 1, nlabels, search, replace, 0, nmatches, nstringmatches, use_regexp), 1, nlabels); for (long i = from; i <= to; i++) { TextInterval interval = (TextInterval) my intervals -> item[i]; Melder_free (interval -> text); interval -> text = newlabels[i - from + 1]; // Transfer of ownership. newlabels[i - from + 1] = nullptr; } } catch (MelderError) { Melder_throw (me, U": labels not changed."); } } void TextTier_changeLabels (I, long from, long to, const char32 *search, const char32 *replace, int use_regexp, long *nmatches, long *nstringmatches) { iam (TextTier); try { if (from == 0) { from = 1; } if (to == 0) { to = my points -> size; } if (from > to || from < 1 || to > my points -> size) { Melder_throw (U"Incorrect specification of where to act."); } if (use_regexp && str32len (search) == 0) { Melder_throw (U"The regex search string cannot be empty.\nYou may search for an empty string with the expression \"^$\""); } long nmarks = to - from + 1; autoNUMvector marks (1, nmarks); for (long i = from; i <= to; i++) { TextPoint point = (TextPoint) my points -> item[i]; marks[i - from + 1] = point -> mark; // Shallow copy. } autostring32vector newmarks (strs_replace (marks.peek(), 1, nmarks, search, replace, 0, nmatches, nstringmatches, use_regexp), 1, nmarks); for (long i = from; i <= to; i++) { TextPoint point = (TextPoint) my points -> item[i]; Melder_free (point -> mark); point -> mark = newmarks[i - from + 1]; // Transfer of ownership. newmarks[i - from + 1] = 0; } } catch (MelderError) { Melder_throw (me, U": no labels changed."); } } void TextGrid_changeLabels (TextGrid me, int tier, long from, long to, const char32 *search, const char32 *replace, int use_regexp, long *nmatches, long *nstringmatches) { try { long ntiers = my tiers -> size; if (tier < 1 || tier > ntiers) { Melder_throw (U"The tier number (", tier, U") should not be larger than the number of tiers (", ntiers, U")."); } if (use_regexp && str32len (search) == 0) { Melder_throw (U"The regex search string cannot be empty.\nYou may search for an empty string with the expression \"^$\""); } Daata anyTier = (Daata) my tiers -> item [tier]; if (anyTier -> classInfo == classIntervalTier) { IntervalTier_changeLabels (anyTier, from, to, search, replace, use_regexp, nmatches, nstringmatches); } else { TextTier_changeLabels (anyTier, from, to, search, replace, use_regexp, nmatches, nstringmatches); } } catch (MelderError) { Melder_throw (me, U": labels not changed."); } } static void IntervalTier_checkStartAndEndTime (IntervalTier me) { TextInterval ti = (TextInterval) my intervals -> item[1]; if (my xmin != ti -> xmin) { Melder_throw (me, U": start time of first interval doesn't match start time of the tier."); } ti = (TextInterval) my intervals -> item[my intervals -> size]; if (my xmax != ti -> xmax) { Melder_throw (me, U": end time of last interval doesn't match end time of the tier."); } } // Precondition: if (preserveTimes) { my xmax <= thy xmin } // Postcondition: my xmin preserved void IntervalTiers_append_inline (IntervalTier me, IntervalTier thee, bool preserveTimes) { try { IntervalTier_checkStartAndEndTime (me); // start/end time of first/last interval should match with tier IntervalTier_checkStartAndEndTime (thee); double xmax_previous = my xmax, time_shift = my xmax - thy xmin; if (preserveTimes && my xmax < thy xmin) { autoTextInterval connection = TextInterval_create (my xmax, thy xmin, U""); xmax_previous = thy xmin; Collection_addItem (my intervals, connection.transfer()); } for (long iint = 1; iint <= thy intervals -> size; iint++) { autoTextInterval ti = (TextInterval) Data_copy ((Daata) thy intervals -> item[iint]); if (preserveTimes) { Collection_addItem (my intervals, ti.transfer()); } else { /* the interval could be so short that if we test ti -> xmin < ti->xmax it might be true * but after assigning ti->xmin = xmax_previous and ti->xmax += time_shift the test * ti -> xmin < ti->xmax might be false! * We want to make sure xmin and xmax are not register variables and therefore force double64 * by using volatile variables. */ volatile double xmin = xmax_previous; volatile double xmax = ti -> xmax + time_shift; if (xmin < xmax) { ti -> xmin = xmin; ti -> xmax = xmax; Collection_addItem (my intervals, ti.transfer()); xmax_previous = xmax; } // else don't include interval } } my xmax = preserveTimes ? thy xmax : xmax_previous; } catch (MelderError) { Melder_throw (U"IntervalTiers not appended."); } } // Precondition: if (preserveTimes) { my xmax <= thy xmin } void TextTiers_append_inline (TextTier me, TextTier thee, bool preserveTimes) { try { for (long iint = 1; iint <= thy points -> size; iint++) { autoTextPoint tp = (TextPoint) Data_copy ((Daata) thy points -> item[iint]); if (not preserveTimes) { tp -> number += my xmax - thy xmin; } Collection_addItem (my points, tp.transfer()); } my xmax = preserveTimes ? thy xmax : my xmax + (thy xmax - thy xmin); } catch (MelderError) { Melder_throw (U"TextTiers not appended."); } } static void TextGrid_checkStartAndEndTimesOfTiers (TextGrid me) { for (long itier = 1; itier <= my tiers -> size; itier++) { Function tier = (Function) my tiers -> item[itier]; if (tier -> xmin != my xmin) { Melder_throw (me, U": the start time of tier ", itier, U" does not match the start time of its TextGrid."); } else if (tier -> xmax != my xmax) { Melder_throw (me, U": the end time of tier ", itier, U" does not match the end time of its TextGrid."); } } } void TextGrids_append_inline (TextGrid me, TextGrid thee, bool preserveTimes) { try { if (my tiers -> size != thy tiers -> size) { Melder_throw (U"The number of tiers must be equal."); } if (preserveTimes && thy xmin < my xmax) { Melder_throw (U"The start time of the second TextGrid can't be earlier than the end time of the first one if you want to preserve times."); } TextGrid_checkStartAndEndTimesOfTiers (me); // all tiers must have the same start/end time as textgrid TextGrid_checkStartAndEndTimesOfTiers (thee); // last intervals must have the same end time double xmax = preserveTimes ? thy xmax : my xmax + (thy xmax - thy xmin); for (long itier = 1; itier <= my tiers -> size; itier++) { Function myTier = my tier (itier), thyTier = thy tier (itier); if (myTier -> classInfo == classIntervalTier && thyTier -> classInfo == classIntervalTier) { IntervalTier myIntervalTier = static_cast (myTier); IntervalTier thyIntervalTier = static_cast (thyTier); IntervalTiers_append_inline (myIntervalTier, thyIntervalTier, preserveTimes); // make sure last interval has correct end time TextInterval lastInterval = myIntervalTier -> interval (myIntervalTier -> numberOfIntervals()); lastInterval -> xmax = xmax; Melder_assert (lastInterval -> xmax > lastInterval -> xmin); } else if (myTier -> classInfo == classTextTier && thyTier -> classInfo == classTextTier) { TextTier myTextTier = static_cast (myTier); TextTier thyTextTier = static_cast (thyTier); TextTiers_append_inline (myTextTier, thyTextTier, preserveTimes); myTextTier -> xmax = xmax; } else { Melder_throw (U"Tier ", itier, U" in the second TextGrid is of a different type " "than tier ", itier, U" in the first TextGrid."); } } my xmax = xmax; } catch (MelderError) { Melder_throw (U"TextGrids not appended."); } } TextGrid TextGrids_to_TextGrid_appendContinuous (Collection me, bool preserveTimes) { try { autoTextGrid thee = Data_copy ((TextGrid) my item[1]); for (long igrid = 2; igrid <= my size; igrid++) { TextGrids_append_inline (thee.peek(), (TextGrid) my item[igrid], preserveTimes); } if (! preserveTimes) { Function_shiftXBy (thee.peek(), -thy xmin); } return thee.transfer(); } catch (MelderError) { Melder_throw (U"No aligned TextGrid created from Collection."); } } /* End of file TextGrid_extensions.cpp */ praat-6.0.04/dwtools/TextGrid_extensions.h000066400000000000000000000125451261542461700206040ustar00rootroot00000000000000#ifndef _TextGrid_extensions_h_ #define _TextGrid_extensions_h_ /* TextGrid_extensions.h * * Copyright (C) 1993-2012 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020516 GPL header djmw 20120418 Latest modification */ #include "TextGrid.h" TextGrid TextGrid_readFromTIMITLabelFile (MelderFile file, int phnFile); /* Read TIMIT label file with the following structure: samplenumber1 samplenumber2 label1 samplenumber3 samplenumber4 label2 ... samplenumber2n-1 samplenumber2n labeln The first tier of TextGrid will contain the TIMIT labels. If phnFile != 0, the second tier will contain the translation of the TIMIT labels into IPA labels. For the translation from sample number to time a default sampling frequency of 16000 Hz is assumed. */ Any TextGrid_TIMITLabelFileRecognizer (int nread, const char *header, MelderFile file); /* There are two types of TIMIT label files. One with phonetic labels, these files have '.phn' as file extension. The other contains word labels and has '.wrd' as extension. Since these extensions are only valid on the CDROM we can not use them for filetype recognition. Both TIMIT label files do not have a self-describing format. For filetype recognition we make use of the fact that both files are text files and always have three items on each line: two numbers followed by a string. The numbers increase in a monotone way. The recognizer only checks the first two lines and it tests whether 0 <= number[1] < number[2] <= number[3] < number[4] (A number of .wrd files do not obey the monotonocity constraint for number[4] and number[5] !) The decision whether it is a .phn or .wrd file is: .phn if string[1] == 'h#' AND string[2] is a TIMIT phonetic label .wrd if (string[1] == 'h#' AND string[2] is a valid word) OR string[1] and string[2] are both valid words. A valid word is a string with contains the lowercase characters [a-z] and [']. */ TextGrid TextGrids_merge (TextGrid grid1, TextGrid grid2); /* Merge two textGrids. The new domain will be: [min(grid1->xmin, grid2->xmin), max(grid1->xmax, grid2->xmax)]. This implies that for the resulting TextGrid each interval tier will have one or two extra intervals if the domains of the two TextGrids are not equal, */ void TextGrid_extendTime (TextGrid me, double delta_time, int position); /* Extend the begin-time (delta_time<0) or end-time (delta_time>0). For Point-tiers only the domain will be extended. Interval tiers will have a new (empty) interval at the start or the end. */ void TextGrid_setTierName (TextGrid me, long itier, const char32 *newName); void TextTier_changeLabels (I, long from, long to, const char32 *search, const char32 *replace, int use_regexp, long *nmatches, long *nstringmatches); void IntervalTier_changeLabels (I, long from, long to, const char32 *search, const char32 *replace, int use_regexp, long *nmatches, long *nstringmatches); void IntervalTier_removeBoundariesBetweenIdenticallyLabeledIntervals (IntervalTier me, const char32 *label); void IntervalTier_cutIntervalsOnLabelMatch (IntervalTier me, const char32 *label); void IntervalTier_cutIntervals_minimumDuration (IntervalTier me, const char32 *label, double minimumDuration); void TextGrid_changeLabels (TextGrid me, int tier, long from, long to, const char32 *search, const char32 *replace, int use_regexp, long *nmatches, long *nstringmatches); /* Set the start/end time to a smaller/larger value. * If mark is NULL, only times are changed * If mark != NULL mark the previous start/end time * For a TextTier this involves adding a point with the marker * For an IntervalTier this involves adding a new interval */ void IntervalTier_setLaterEndTime (IntervalTier me, double xmax, const char32 *mark); void IntervalTier_setEarlierStartTime (IntervalTier me, double xmin, const char32 *mark); void IntervalTier_moveBoundary (IntervalTier me, long interval, bool atStart, double newTime); void TextTier_setLaterEndTime (TextTier me, double xmax, const char32 *mark); void TextTier_setEarlierStartTime (TextTier me, double xmin, const char32 *mark); void TextGrid_setEarlierStartTime (TextGrid me, double xmin, const char32 *imark, const char32 *pmark); void TextGrid_setLaterEndTime (TextGrid me, double xmax, const char32 *imark, const char32 *pmark); // Precondition: if (preserveTimes) { my xmax <= thy xmin } // Postcondition: my xmin preserved void IntervalTiers_append_inline (IntervalTier me, IntervalTier thee, bool preserveTimes); void TextTiers_append_inline (TextTier me, TextTier thee, bool preserveTimes); void TextGrids_append_inline (TextGrid me, TextGrid thee, bool preserveTimes); // Postcondition: TextGrid TextGrids_to_TextGrid_appendContinuous (Collection me, bool preserveTimes); #endif /* _TextGrid_extensions_h_ */ praat-6.0.04/dwtools/VowelEditor.cpp000066400000000000000000001647251261542461700174010ustar00rootroot00000000000000/* VowelEditor.cpp * * Copyright (C) 2008-2013, 2015 David Weenink, 2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20080202, 20080330 djmw 20090114 FormantTier_to_FormantGrid. djmw 20090613 Extract KlattGrid djmw 20110329 Table_get(Numeric|String)Value is now Table_get(Numeric|String)Value_Assert djmw 20110331 Corrected a typo */ /* trajectory --> path ???? The main part of the VowelEditor is a drawing area. In this drawing area a cursor can be moved around by a mouse. The position of the cursor is related to the F1 and F2 frequencies. On_mouse_down the position of the cursor is sampled (Not a fixed intervals!). This results in a series of (x,y) values that will be transformed to (F1,F2) values in Hertz The corresponding sound wil be made audible until the mouse is released. Graphics area is F1-F2 plane. Origin top-right with log(F2) horizontal and log(F1) vertical). Axis orientation from topright: F1 down, F2 to the left. F1, F2 are always evaluated to Hz; In the Graphics part, the Graphics_window (0, 1, 0, 1), i.e. origin is bottom-left. log(fmin) -> 1; log(fmax)-> 0 Transformations XY <=> F1F2: VowelEditor_getXYFromF1F2(...) and VowelEditor_getF1F2FromXY(...) For x direction F2 from right to left 1 = a * log(f2min) +b 0 = a * log(f2max) +b x' = a (log(f2)-log(f2max)) 1 = a * log(f1min) +b 0 = a * log(f1max) +b y' = a (log(f1)-log(f1max)) TO DO: The third and higher formant frequencies can also be set indirectly by defining them as functions on the f1,f2 plane (for example, by an object of type Matrix). Make sound-follows-mouse real time! */ #include "FormantGrid.h" #include "KlattGrid.h" #include "../external/portaudio/portaudio.h" #include "praat.h" #include "PitchTier_to_PointProcess.h" #include "PitchTier_to_Sound.h" #include "PointProcess_and_Sound.h" #include "Polygon.h" #include "TableOfReal_extensions.h" #include "Table_extensions.h" #include "VowelEditor.h" #include "machine.h" #include "Preferences.h" #include "EditorM.h" #include #if defined (macintosh) #include #elif defined (linux) #include #include #endif Thing_implement (VowelEditor, Editor, 0); // Male, Female, Child speaker #define VG_SPEAKER_M 0 #define VG_SPEAKER_F 1 #define VG_SPEAKER_C 2 // STATUS_INFO >=Gui_LABEL_HEIGHT !! #define STATUS_INFO (1.5*Gui_LABEL_HEIGHT) #define MARGIN_RIGHT 10 #define MARGIN_LEFT 50 #define MARGIN_TOP 50 #define MARGIN_BOTTOM (60+STATUS_INFO) #define BUFFER_SIZE_SEC 4 #define SAMPLING_FREQUENCY 44100 #define STATUSINFO_STARTINTR0 U"Start (F1,F2,F0) = (" #define STATUSINFO_ENDINTR0 U"End (F1,F2,F0) = (" #define STATUSINFO_ENDING U")" #define MICROSECPRECISION(x) (round((x)*1000000)/1000000) // To prevent the generation of inaudible short Sounds we set a minimum duration #define MINIMUM_SOUND_DURATION 0.01 // maximum number of marks #define VowelEditor_MAXIMUM_MARKERS 30 // prototypes: button callbacks static void gui_button_cb_publish (I, GuiButtonEvent event); static void gui_button_cb_play (I, GuiButtonEvent event); static void gui_drawingarea_cb_resize (I, GuiDrawingAreaResizeEvent event); static void gui_drawingarea_cb_click (I, GuiDrawingAreaClickEvent event); static void gui_button_cb_reverse (I, GuiButtonEvent event); static void gui_drawingarea_cb_expose (I, GuiDrawingAreaExposeEvent event); // prototypes: helpers static double getRealFromTextWidget (GuiText me); static double getCoordinate (double fmin, double fmax, double f); static double getF0 (structVowelEditor_F0 *f0p, double time); static void checkF1F2 (VowelEditor me, double *f1, double *f2); static void checkF0 (structVowelEditor_F0 *f0p, double *f0); static void checkXY (double *x, double *y); static void Sound_fadeIn (Sound me, double duration, int fromFirstNonZeroSample); static void Sound_fadeOut (Sound me, double duration); static void PitchTier_newDuration (PitchTier me, structVowelEditor_F0 *f0p, double newDuration); static void FormantTier_newDuration (FormantTier me, double newDuration); static void FormantTier_drawF1F2Trajectory (FormantTier me, Graphics g, double f1min, double f1max, double f2min, double f2max, double markTraceEvery, double width); static autoFormantGrid FormantTier_to_FormantGrid (FormantTier me); static autoPitchTier VowelEditor_to_PitchTier (VowelEditor me, double duration); static void VowelEditor_updateF0Info (VowelEditor me); static void VowelEditor_updateExtendDuration (VowelEditor me); static double VowelEditor_updateDurationInfo (VowelEditor me); static void VowelEditor_Vowel_updateTiers (VowelEditor me, Vowel thee, double time, double x, double y); static void VowelEditor_Vowel_addData (VowelEditor me, Vowel thee, double time, double f1, double f2, double f0); static void VowelEditor_getXYFromF1F2 (VowelEditor me, double f1, double f2, double *x, double *y); static void VowelEditor_getF1F2FromXY (VowelEditor me, double x, double y, double *f1, double *f2); static void VowelEditor_updateVowel (VowelEditor me); static autoSound VowelEditor_createTarget (VowelEditor me); static void VowelEditor_Vowel_reverseFormantTier (VowelEditor me); static void VowelEditor_shiftF1F2 (VowelEditor me, double f1_st, double f2_st); static void VowelEditor_setMarks (VowelEditor me, int marksDataset, int speakerType, int fontSize); static void VowelEditor_setF3F4 (VowelEditor me, double f3, double b3, double f4, double b4); static void VowelEditor_getF3F4 (VowelEditor me, double f1, double f2, double *f3, double *b3, double *f4, double *b4); static void VowelEditor_getVowelMarksFromTableFile (VowelEditor me, MelderFile file); static void VowelEditor_createTableFromVowelMarksInPreferences (VowelEditor me); static void Table_addColumn_size (Table me, int size); static double Matrix_getValue (Matrix me, double x, double y); static void VowelEditor_drawBackground (VowelEditor me, Graphics g); static void createPersistentVowelMarks (); static void copyVowelMarksInPreferences_volatile (Table me); static autoVowel Vowel_create (double duration); static autoVowel Vowel_create_twoFormantSchwa (double duration); static void Vowel_newDuration (Vowel me, structVowelEditor_F0 *f0p, double newDuration); static autoSound Vowel_to_Sound_pulses (Vowel me, double samplingFrequency, double adaptFactor, double adaptTime, long interpolationDepth); // forward declarations end static struct structVowelEditor_F0 f0default = { 140.0, 0.0, 40.0, 2000.0, SAMPLING_FREQUENCY, 1, 0.0, 2000 }; static struct structVowelEditor_F1F2Grid griddefault = { 200, 500, 0, 1, 0, 1, 0.5 }; #include "oo_DESTROY.h" #include "Vowel_def.h" #include "oo_COPY.h" #include "Vowel_def.h" #include "oo_EQUAL.h" #include "Vowel_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Vowel_def.h" #include "oo_WRITE_TEXT.h" #include "Vowel_def.h" #include "oo_READ_TEXT.h" #include "Vowel_def.h" #include "oo_WRITE_BINARY.h" #include "Vowel_def.h" #include "oo_READ_BINARY.h" #include "Vowel_def.h" #include "oo_DESCRIPTION.h" #include "Vowel_def.h" // Preferences structs struct markInfo { double f1, f2; int size; char32 vowel [Preferences_STRING_BUFFER_SIZE]; }; static struct { int shellWidth, shellHeight; bool soundFollowsMouse; double f1min, f1max, f2min, f2max; double f3, b3, f4, b4; double markTraceEvery, extendDuration; int frequencyScale; int axisOrientation; int speakerType, marksDataset, numberOfMarks, marksFontSize; char32 mark[VowelEditor_MAXIMUM_MARKERS][Preferences_STRING_BUFFER_SIZE]; } prefs; Thing_implement (Vowel, Function, 0); static autoVowel Vowel_create (double duration) { try { autoVowel me = Thing_new (Vowel); Function_init (me.get(), 0.0, duration); my ft = FormantTier_create (0.0, duration); my pt = PitchTier_create (0.0, duration); return me; } catch (MelderError) { Melder_throw (U"Vowel not created."); } } static autoVowel Vowel_create_twoFormantSchwa (double duration) { try { autoVowel me = Vowel_create (duration); autoFormantPoint fp = FormantPoint_create (0.0); fp -> formant [0] = 500.0; fp -> bandwidth[0] = 50.0; fp -> formant [1] = 1500.0; fp -> bandwidth[1] = 150.0; fp -> numberOfFormants = 2; Collection_addItem (my ft -> points, fp.transfer()); RealTier_addPoint (my pt.get(), 0.0, 140.0); fp = FormantPoint_create (duration); fp -> formant [0] = 500.0; fp -> bandwidth[0] = 50.0; fp -> formant [1] = 1500.0; fp -> bandwidth[1] = 150.0; fp -> numberOfFormants = 2; Collection_addItem (my ft -> points, fp.transfer()); RealTier_addPoint (my pt.get(), duration, 140.0); return me; } catch (MelderError) { Melder_throw (U"Schwa Vowel not created"); } } static autoSound Vowel_to_Sound_pulses (Vowel me, double samplingFrequency, double adaptFactor, double adaptTime, long interpolationDepth) { try { autoPointProcess pp = PitchTier_to_PointProcess (my pt.get()); autoSound thee = PointProcess_to_Sound_pulseTrain (pp.peek(), samplingFrequency, adaptFactor, adaptTime, interpolationDepth); Sound_FormantTier_filter_inline (thee.peek(), my ft.get()); return thee; } catch (MelderError) { Melder_throw (me, U": Sound with pulses not created."); } } static autoFormantGrid FormantTier_to_FormantGrid (FormantTier me) { try { long numberOfFormants = FormantTier_getMaxNumFormants (me); autoFormantGrid thee = FormantGrid_createEmpty (my xmin, my xmax, numberOfFormants); for (long ipoint = 1; ipoint <= my points -> size; ipoint++) { FormantPoint fp = (FormantPoint) my points -> item[ipoint]; double t = fp -> time; for (long iformant = 1; iformant <= fp -> numberOfFormants; iformant++) { FormantGrid_addFormantPoint (thee.peek(), iformant, t, fp -> formant[iformant - 1]); FormantGrid_addBandwidthPoint (thee.peek(), iformant, t, fp -> bandwidth[iformant - 1]); } } return thee; } catch (MelderError) { Melder_throw (me, U": no FormantGrod created."); } } static void VowelEditor_getXYFromF1F2 (VowelEditor me, double f1, double f2, double *x, double *y) { *x = log (f2 / my f2max) / log (my f2min / my f2max); *y = log (f1 / my f1max) / log (my f1min / my f1max); } //Graphics_DCtoWC ???? static void VowelEditor_getF1F2FromXY (VowelEditor me, double x, double y, double *f1, double *f2) { *f2 = my f2min * pow (my f2max / my f2min, 1.0 - x); *f1 = my f1min * pow (my f1max / my f1min, 1.0 - y); } #define REPRESENTNUMBER(x,i) (((x) == NUMundefined) ? U" undef" : Melder_pad (6, Melder_fixed (x, 1))) static void appendF1F2F0 (MelderString *statusInfo, const char32 *intro, double f1, double f2, double f0, const char32 *ending) { MelderString_append (statusInfo, intro, REPRESENTNUMBER (f1, 1), U", ", REPRESENTNUMBER (f2, 2), U", ", REPRESENTNUMBER (f0, 3), ending); } static double getRealFromTextWidget (GuiText me) { double value = NUMundefined; char32 *dirty = GuiText_getString (me); try { Interpreter_numericExpression (nullptr, dirty, & value); } catch (MelderError) { Melder_clearError (); value = NUMundefined; } Melder_free (dirty); return value; } static void VowelEditor_updateF0Info (VowelEditor me) { double f0 = getRealFromTextWidget (my f0TextField); checkF0 (&my f0, &f0); GuiText_setString (my f0TextField, Melder_double (f0)); my f0.start = f0; double slopeOctPerSec = getRealFromTextWidget (my f0SlopeTextField); if (! NUMdefined (slopeOctPerSec)) { slopeOctPerSec = f0default.slopeOctPerSec; } my f0.slopeOctPerSec = slopeOctPerSec; GuiText_setString (my f0SlopeTextField, Melder_double (my f0.slopeOctPerSec)); } static void VowelEditor_updateExtendDuration (VowelEditor me) { double extend = getRealFromTextWidget (my extendTextField); if (! NUMdefined (extend) || extend <= MINIMUM_SOUND_DURATION || extend > my maximumDuration) { extend = MINIMUM_SOUND_DURATION; } GuiText_setString (my extendTextField, Melder_double (extend)); my extendDuration = prefs.extendDuration = extend; } static double VowelEditor_updateDurationInfo (VowelEditor me) { double duration = getRealFromTextWidget (my durationTextField); if (! NUMdefined (duration) || duration < MINIMUM_SOUND_DURATION) { duration = MINIMUM_SOUND_DURATION; } GuiText_setString (my durationTextField, Melder_double (MICROSECPRECISION (duration))); return duration; } static void Sound_fadeIn (Sound me, double duration, int fromFirstNonZeroSample) { long istart = 1, numberOfSamples = (long) floor (duration / my dx); // ppgb: waarom afronden naar beneden? if (numberOfSamples < 2) { return; } if (fromFirstNonZeroSample != 0) { // If the first part of the sound is very low level we put sample values to zero and // start windowing from the position where the amplitude is above the minimum level. // WARNING: this part is special for the artificial vowels because // 1. They have no offset // 2. They are already scaled to a maximum amplitude of 0.99 // 3. For 16 bit precision double zmin = 0.5 / pow (2.0, 16.0); while (fabs (my z[1][istart]) < zmin && istart < my nx) { my z[1][istart] = 0.0; // To make sure istart++; } } if (numberOfSamples > my nx - istart + 1) { numberOfSamples = my nx - istart + 1; } for (long i = 1; i <= numberOfSamples; i++) { double phase = NUMpi * (i - 1) / (numberOfSamples - 1); my z[1][istart + i - 1] *= 0.5 * (1.0 - cos (phase)); } } static void Sound_fadeOut (Sound me, double duration) { long istart, numberOfSamples = (long) floor (duration / my dx); if (numberOfSamples < 2) { return; } if (numberOfSamples > my nx) { numberOfSamples = my nx; } istart = my nx - numberOfSamples; // only one channel for (long i = 1; i <= numberOfSamples; i++) { double phase = NUMpi * (i - 1) / (numberOfSamples - 1); my z[1][istart + i] *= 0.5 * (1.0 + cos (phase)); } } static double getF0 (structVowelEditor_F0 *f0p, double time) { double f0 = f0p -> start * pow (2.0, f0p -> slopeOctPerSec * time); if (f0 < f0p -> minimum) { f0 = f0p -> minimum; } else if (f0 > f0p -> maximum) { f0 = f0p -> maximum; } return f0; } static void VowelEditor_Vowel_reverseFormantTier (VowelEditor me) { FormantTier ft = my vowel -> ft.get(); double duration = ft -> xmax; long np = ft -> points -> size, np_2 = np / 2; for (long i = 1; i <= np_2; i++) { FormantPoint fpt = (FormantPoint) ft -> points -> item[i]; ft -> points -> item[i] = ft -> points -> item[np - i + 1]; ft -> points -> item[np - i + 1] = fpt; fpt = (FormantPoint) ft -> points -> item[i]; fpt -> time = duration - fpt -> time; fpt = (FormantPoint) ft -> points -> item[np - i + 1]; fpt -> time = duration - fpt -> time; } if (np % 2 == 1) { FormantPoint fpt = (FormantPoint) ft -> points -> item[np_2 + 1]; fpt -> time = duration - fpt -> time; } } static void VowelEditor_shiftF1F2 (VowelEditor me, double f1_st, double f2_st) { FormantTier ft = my vowel -> ft.get(); for (long i = 1; i <= ft -> points -> size; i++) { FormantPoint fp = (FormantPoint) ft -> points -> item[i]; double f1 = fp -> formant[0], f2 = fp -> formant[1]; f1 *= pow (2, f1_st / 12); if (f1 < my f1min) { f1 = my f1min; } if (f1 > my f1max) { f1 = my f1max; } fp -> formant[0] = f1; fp -> bandwidth[0] = f1 / 10; f2 *= pow (2, f2_st / 12); if (f2 < my f2min) { f2 = my f2min; } if (f2 > my f2max) { f2 = my f2max; } fp -> formant[1] = f2; fp -> bandwidth[1] = f2 / 10; double f3, b3, f4, b4; VowelEditor_getF3F4 (me, f1, f2, &f3, &b3, &f4, &b4); fp -> formant[2] = f3; fp -> bandwidth[2] = b3; fp -> formant[3] = f4; fp -> bandwidth[3] = b4; } } static void Vowel_newDuration (Vowel me, structVowelEditor_F0 *f0p, double newDuration) { if (newDuration != my xmax) { double multiplier = newDuration / my xmax; FormantTier_newDuration (my ft.get(), newDuration); my xmax *= multiplier; } PitchTier_newDuration (my pt.get(), f0p, newDuration); // always update } static void FormantTier_newDuration (FormantTier me, double newDuration) { if (newDuration != my xmax) { double multiplier = newDuration / my xmax; for (long i = 1; i <= my points -> size; i++) { FormantPoint fp = (FormantPoint) my points -> item[i]; fp -> time *= multiplier; } my xmax *= multiplier; } } static void PitchTier_newDuration (PitchTier me, structVowelEditor_F0 *f0p, double newDuration) { // Always update; GuiObject text might have changed double multiplier = newDuration / my xmax; for (long i = 1; i <= my points -> size; i++) { RealPoint pp = (RealPoint) my points -> item[i]; pp -> number *= multiplier; pp -> value = getF0 (f0p, pp -> number); } my xmax *= multiplier; } static void VowelEditor_updateVowel (VowelEditor me) { double newDuration = VowelEditor_updateDurationInfo (me); // Get new duration from TextWidget VowelEditor_updateF0Info (me); // Get new pitch and slope values from TextWidgets Vowel_newDuration (my vowel.get(), & my f0, newDuration); } static double getCoordinate (double fmin, double fmax, double f) { return log (f / fmax) / log (fmin / fmax); } #define GETX(x) (getCoordinate (f2min, f2max, x)) #define GETY(y) (getCoordinate (f1min, f1max, y)) // Our FormantTiers always have a FormantPoint at t=xmin and t=xmax; static void FormantTier_drawF1F2Trajectory (FormantTier me, Graphics g, double f1min, double f1max, double f2min, double f2max, double markTraceEvery, double width) { int it, imark = 1, glt = Graphics_inqLineType (g); double glw = Graphics_inqLineWidth (g), x1, x1p, y1, y1p, t1; Graphics_Colour colour = Graphics_inqColour (g); long nfp = my points -> size; trace (U"number of points ", nfp); FormantPoint fp = (FormantPoint) my points -> item[1]; FormantPoint fpn = (FormantPoint) my points -> item[nfp]; double tm, markLength = 0.01; Graphics_setInner (g); Graphics_setWindow (g, 0.0, 1.0, 0.0, 1.0); Graphics_setLineType (g, Graphics_DRAWN); // Too short too hear ? if ( (my xmax - my xmin) < 0.005) { Graphics_setColour (g, Graphics_RED); } x1p = x1 = GETX (fp->formant[1]); y1p = y1 = GETY (fp->formant[0]); t1 = fp->time; for (it = 2; it <= nfp; it++) { fp = (FormantPoint) my points -> item[it]; double x2 = GETX (fp->formant[1]), y2 = GETY (fp->formant[0]), t2 = fp->time; Graphics_setLineWidth (g, 3); if (x1 == x2 && y1 == y2) { x1 = x1p; y1 = y1p; } else { Graphics_line (g, x1, y1, x2, y2); } while (markTraceEvery > 0 && (tm = markTraceEvery * imark) < t2) { // line orthogonal to y = (y1/x1)*x is y = -(x1/y1)*x double fraction = (tm - t1) / (t2 - t1); double dx = x2 - x1, dy = y2 - y1; double xm = x1 + fraction * dx, ym = y1 + fraction * dy; double d = sqrt (dx * dx + dy * dy); if (d > 0.0) { double xl1 = dy * markLength / d, xl2 = - xl1; double yl1 = dx * markLength / d, yl2 = - yl1; if (dx * dy > 0) { xl1 = -fabs (xl1); yl1 = fabs (yl1); xl2 = fabs (xl1); yl2 = -fabs (yl1); } else if (dx * dy < 0) { xl1 = -fabs (xl1); yl1 = -fabs (yl1); xl2 = fabs (xl1); yl2 = fabs (yl1); } Graphics_setLineWidth (g, 1); trace (xm, U" ", ym, U" ", xl1, U" ", xl2, U" ", yl1, U" ", yl2); Graphics_line (g, xm + xl1, ym + yl1, xm + xl2, ym + yl2); } imark++; } x1p = x1; y1p = y1; x1 = x2; y1 = y2; t1 = t2; } // Arrow at end { double gas = Graphics_inqArrowSize (g), arrowSize = 1.0; double size = 10.0 * arrowSize * Graphics_getResolution (g) / 75.0 / width, size2 = size * size; Graphics_setArrowSize (g, arrowSize); it = 1; while (it <= (nfp - 1)) { fp = (FormantPoint) my points -> item[nfp - it]; double dx = GETX (fpn->formant[1]) - GETX (fp->formant[1]); double dy = GETY (fpn->formant[0]) - GETY (fp->formant[0]); double d2 = dx * dx + dy * dy; if (d2 > size2) { break; } it++; } Graphics_arrow (g, GETX (fp->formant[1]), GETY (fp->formant[0]), GETX (fpn->formant[1]), GETY (fpn->formant[0])); Graphics_setArrowSize (g, gas); } Graphics_unsetInner (g); Graphics_setColour (g, colour); Graphics_setLineType (g, glt); Graphics_setLineWidth (g, glw); } #undef GETX #undef GETY void VowelEditor_prefs () { Preferences_addInt (U"VowelEditor.shellWidth", &prefs.shellWidth, 500); Preferences_addInt (U"VowelEditor.shellHeight", &prefs.shellHeight, 500); Preferences_addBool (U"VowelEditor.soundFollowsMouse", &prefs.soundFollowsMouse, true); Preferences_addDouble (U"VowelEditor.f1min", &prefs.f1min, 200.0); Preferences_addDouble (U"VowelEditor.f1max", &prefs.f1max, 1200.0); Preferences_addDouble (U"VowelEditor.f2min", &prefs.f2min, 500.0); Preferences_addDouble (U"VowelEditor.f2max", &prefs.f2max, 3500.0); Preferences_addDouble (U"VowelEditor.f3", &prefs.f3, 2500.0); Preferences_addDouble (U"VowelEditor.b3", &prefs.b3, 250.0); Preferences_addDouble (U"VowelEditor.f4", &prefs.f4, 3500.0); Preferences_addDouble (U"VowelEditor.b4", &prefs.b4, 350.0); Preferences_addDouble (U"VowelEditor.markTraceEvery", &prefs.markTraceEvery, 0.05); Preferences_addDouble (U"VowelEditor.extendDuration", &prefs.extendDuration, 0.05); Preferences_addInt (U"VowelEditor.frequencyScale", &prefs.frequencyScale, 0); Preferences_addInt (U"VowelEditor.axisOrientation", &prefs.axisOrientation, 0); Preferences_addInt (U"VowelEditor.speakerType", &prefs.speakerType, 1); Preferences_addInt (U"VowelEditor.marksDataset", &prefs.marksDataset, 2); Preferences_addInt (U"VowelEditor.marksFontsize", &prefs.marksFontSize, 14); createPersistentVowelMarks (); } static void copyVowelMarksInPreferences_volatile (Table me) { long numberOfRows = prefs.numberOfMarks = my rows -> size; if (numberOfRows > 0) { long col_vowel = Table_getColumnIndexFromColumnLabel (me, U"Vowel"); long col_f1 = Table_getColumnIndexFromColumnLabel (me, U"F1"); long col_f2 = Table_getColumnIndexFromColumnLabel (me, U"F2"); long col_size = Table_getColumnIndexFromColumnLabel (me, U"Size"); autoMelderString mark; for (long i = 1; i <= VowelEditor_MAXIMUM_MARKERS; i++) { if (i <= numberOfRows) { MelderString_copy (&mark, Table_getStringValue_Assert (me, i, col_vowel), U"\t", Table_getStringValue_Assert (me, i, col_f1), U"\t", Table_getStringValue_Assert (me, i, col_f2), U"\t", Table_getStringValue_Assert (me, i, col_size)); long length = str32len (mark.string); if (length > Preferences_STRING_BUFFER_SIZE) Melder_throw (U"Preference mark", i, U"too many characters"); str32cpy (prefs.mark[i-1], mark.string); } else { str32cpy (prefs.mark[i-1], U"x"); } } // The following code removes the superfluous mark preferences, // *if* we had access to the thePreferences set (but we don't) // autoMelderString markID; // for (long i = VowelEditor_MAXIMUM_MARKERS; i > numberOfRows; i--) { // MelderString_copy (&markID, U"VowelEditor.mark", (i < 10 ? U"0" : U""), i); // long index = SortedSetOfString_lookUp (thePreferences, markID.string); // Collection_removeItem (thePreferences, index); // } } } static void createPersistentVowelMarks () { // Deadlock: // This function is executed before the preferences are read from file and before we know how // many vowel marks the user wants. // However, to succesfully read the preferences from file we need the names of the preferences otherwise // they will not be assigned a value. // We therefore create fake names first and later fill them with data. long numberOfMarks = VowelEditor_MAXIMUM_MARKERS; Preferences_addInt (U"VowelEditor.numberOfMarks", &prefs.numberOfMarks, numberOfMarks); for (long i = 1; i <= numberOfMarks; i++) { Preferences_addString (Melder_cat (U"VowelEditor.mark", (i < 10 ? U"0" : U""), i), & prefs.mark[i-1][0], U"x"); } } void VowelEditor_createTableFromVowelMarksInPreferences (VowelEditor me) { long numberOfRows = VowelEditor_MAXIMUM_MARKERS; try { autoTable newMarks = Table_createWithColumnNames (0, U"Vowel F1 F2 Size"); long nmarksFound = 0; for (long i = 1; i <= numberOfRows; i++) { long numberOfTokens; autoMelderTokens rowi (prefs.mark[i-1], &numberOfTokens); if (numberOfTokens < 4) { // we are done break; } Table_appendRow (newMarks.peek()); for (long j = 1; j <= 4; j++) { Table_setStringValue (newMarks.peek(), i, j, rowi[j]); } nmarksFound++; } if (nmarksFound == 0) { my speakerType = prefs.speakerType = 1; my marksDataset = prefs.marksDataset = 1; VowelEditor_setMarks (me, my marksDataset, my speakerType, prefs.marksFontSize); } else { my marks = newMarks.move(); } } catch (MelderError) { Melder_throw (U"Cannot create Table from preferences. Default marks set."); my speakerType = prefs.speakerType = 1; my marksDataset = prefs.marksDataset = 1; VowelEditor_setMarks (me, my marksDataset, my speakerType, prefs.marksFontSize); } } static void Table_addColumn_size (Table me, int size) { long col_size = Table_findColumnIndexFromColumnLabel (me, U"Size"); if (col_size == 0) { Table_appendColumn (me, U"Size"); for (long i = 1; i <= my rows -> size; i++) { Table_setNumericValue (me, i, my numberOfColumns, size); } } } static void VowelEditor_setMarks (VowelEditor me, int marksDataset, int speakerType, int fontSize) { autoTable te; const char32 *Type[4] = { U"", U"m", U"w", U"c" }; const char32 *Sex[3] = { U"", U"m", U"f"}; if (marksDataset == 1) { // American-English autoTable thee = Table_createFromPetersonBarneyData (); te.reset (Table_extractRowsWhereColumn_string (thee.peek(), 1, kMelder_string_EQUAL_TO, Type[speakerType])); } else if (marksDataset == 2) { // Dutch if (speakerType == 1 || speakerType == 2) { // male + female from Pols van Nierop autoTable thee = Table_createFromPolsVanNieropData (); te.reset (Table_extractRowsWhereColumn_string (thee.peek(), 1, kMelder_string_EQUAL_TO, Sex[speakerType])); } else { autoTable thee = Table_createFromWeeninkData (); te.reset (Table_extractRowsWhereColumn_string (thee.peek(), 1, kMelder_string_EQUAL_TO, Type[speakerType])); } } else if (marksDataset == 3) { // None my marks.reset(); return; } else { // Leave as is return; } autoTable newMarks = Table_collapseRows (te.peek(), U"IPA", U"", U"F1 F2", U"", U"", U""); long col_ipa = Table_findColumnIndexFromColumnLabel (newMarks.peek(), U"IPA"); Table_setColumnLabel (newMarks.get(), col_ipa, U"Vowel"); Table_addColumn_size (newMarks.get(), fontSize); my marks = newMarks.move(); copyVowelMarksInPreferences_volatile (my marks.get()); } static void VowelEditor_getVowelMarksFromTableFile (VowelEditor me, MelderFile file) { try { autoDaata data = Data_readFromFile (file); if (! Thing_isa (data.get(), classTable)) { Melder_throw (U"\"", MelderFile_name (file), U"\" is not a Table file"); } autoTable newMarks = (Table) data.transfer(); // check if columns Vowel F1 & F2 are present Table_getColumnIndexFromColumnLabel (newMarks.get(), U"Vowel"); Table_getColumnIndexFromColumnLabel (newMarks.get(), U"F1"); Table_getColumnIndexFromColumnLabel (newMarks.get(), U"F2"); Table_addColumn_size (newMarks.peek(), prefs.marksFontSize); my marks = newMarks.move(); my marksDataset = prefs.marksDataset = 9999; copyVowelMarksInPreferences_volatile (my marks.get()); // our marks preferences are dynamic, save each time } catch (MelderError) { Melder_throw (U"Vowel marks from Table not shown."); } } static void VowelEditor_setF3F4 (VowelEditor me, double f3, double b3, double f4, double b4) { double xmin = my f2min, xmax = my f2max, dx = my f2max - my f2min, x1 = dx / 2; double dy = my f1max - my f1min, y1 = dy / 2; if (my f3 == 0) { my f3 = Matrix_create (xmin, xmax, 1, dx, x1, my f1min, my f1max, 1, dy, y1); } if (my b3 == 0) { my b3 = Matrix_create (xmin, xmax, 1, dx, x1, my f1min, my f1max, 1, dy, y1); } if (my f4 == 0) { my f4 = Matrix_create (xmin, xmax, 1, dx, x1, my f1min, my f1max, 1, dy, y1); } if (my b4 == 0) { my b4 = Matrix_create (xmin, xmax, 1, dx, x1, my f1min, my f1max, 1, dy, y1); } my f3 -> z[1][1] = f3; my b3 -> z[1][1] = b3; my f4 -> z[1][1] = f4; my b4 -> z[1][1] = b4; } static double Matrix_getValue (Matrix me, double x, double y) { (void) x; (void) y; return my z[1][1]; } static void VowelEditor_getF3F4 (VowelEditor me, double f1, double f2, double *f3, double *b3, double *f4, double *b4) { *f3 = Matrix_getValue (my f3.get(), f2, f1); *b3 = Matrix_getValue (my b3.get(), f2, f1); *f4 = Matrix_getValue (my f4.get(), f2, f1); *b4 = Matrix_getValue (my b4.get(), f2, f1); } static void VowelEditor_drawBackground (VowelEditor me, Graphics g) { double x1, y1, x2, y2, f1, f2; Graphics_setInner (g); Graphics_setWindow (g, 0.0, 1.0, 0.0, 1.0); Graphics_setGrey (g, 0.0); Graphics_setLineType (g, Graphics_DRAWN); Graphics_setLineWidth (g, 2.0); Graphics_rectangle (g, 0.0, 1.0, 0.0, 1.0); Graphics_setLineWidth (g, 1.0); Graphics_setGrey (g, 0.5); int fontSize = Graphics_inqFontSize (g); // draw the marks if (my marks) { long col_vowel = Table_getColumnIndexFromColumnLabel (my marks.get(), U"Vowel"); long col_f1 = Table_getColumnIndexFromColumnLabel (my marks.get(), U"F1"); long col_f2 = Table_getColumnIndexFromColumnLabel (my marks.get(), U"F2"); long col_fs = Table_findColumnIndexFromColumnLabel (my marks.get(), U"Size"); for (long i = 1; i <= my marks -> rows -> size; i++) { const char32 *label = Table_getStringValue_Assert (my marks.get(), i, col_vowel); f1 = Table_getNumericValue_Assert (my marks.get(), i, col_f1); f2 = Table_getNumericValue_Assert (my marks.get(), i, col_f2); if (f1 >= my f1min && f1 <= my f1max && f2 >= my f2min && f2 <= my f2max) { VowelEditor_getXYFromF1F2 (me, f1, f2, &x1, &y1); int size = prefs.marksFontSize; if (col_fs != 0) { size = (int) floor (Table_getNumericValue_Assert (my marks.get(), i, col_fs)); } Graphics_setFontSize (g, size); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); Graphics_text (g, x1, y1, label); } } } Graphics_setFontSize (g, fontSize); // Draw the line F1=F2 // VowelEditor_getXYFromF1F2 (me, my f2min, my f2min, &x1, &y1); if (y1 >= 0.0 && y1 <= 1.0) { VowelEditor_getXYFromF1F2 (me, my f1max, my f1max, &x2, &y2); if (x2 >= 0.0 && x2 <= 1.0) { autoPolygon p = Polygon_create (3); p -> x[1] = x1; p -> y[1] = y1; p -> x[2] = x2; p -> y[2] = y2; p -> x[3] = 1; p -> y[3] = 0; Graphics_fillArea (g, p -> numberOfPoints, & p -> x[1], & p -> y[1]); // Polygon_paint does not work because of use of Graphics_setInner. Graphics_line (g, x1, y1, x2, y2); } } // Draw the grid if (my grid.df1 < (my f1max - my f1min)) { // Horizontal lines long iline = (my f1min + my grid.df1) / my grid.df1; // FIXME: if truncating down is deliberate, then do `floor` Graphics_setGrey (g, 0.5); Graphics_setLineType (g, Graphics_DOTTED); while ( (f1 = iline * my grid.df1) < my f1max) { if (f1 > my f1min) { VowelEditor_getXYFromF1F2 (me, f1, my f2min, &x1, &y1); VowelEditor_getXYFromF1F2 (me, f1, my f2max, &x2, &y2); Graphics_line (g, x1, y1, x2, y2); } iline++; } Graphics_setLineType (g, Graphics_DRAWN); Graphics_setGrey (g, 0.0); // black } if (my grid.df2 < (my f2max - my f2min)) { long iline = (my f2min + my grid.df2) / my grid.df2; // FIXME: if truncating down is deliberate, then do `floor` Graphics_setGrey (g, 0.5); Graphics_setLineType (g, Graphics_DOTTED); while ( (f2 = iline * my grid.df2) < my f2max) { // vert line if (f2 > my f2min) { VowelEditor_getXYFromF1F2 (me, my f1min, f2, &x1, &y1); VowelEditor_getXYFromF1F2 (me, my f1max, f2, &x2, &y2); Graphics_line (g, x1, y1, x2, y2); } iline++; } Graphics_setLineType (g, Graphics_DRAWN); Graphics_setGrey (g, 0.0); // black } Graphics_unsetInner (g); Graphics_setGrey (g, 0.0); // black Graphics_markLeft (g, 0.0, false, true, false, Melder_double (my f1max)); Graphics_markLeft (g, 1.0, false, true, false, Melder_double (my f1min)); Graphics_markTop (g, 0.0, false, true, false, Melder_double (my f2max)); Graphics_markTop (g, 1.0, false, true, false, Melder_double (my f2min)); } typedef struct { long some_check_value; long istart; float *z; } *paVowelData; /* This routine will be called by the PortAudio engine when audio is needed. ** It may called at interrupt level on some machines so don't do anything ** that could mess up the system like calling malloc() or free(). */ static int paCallback (const void* /*inputBuffer*/, void* outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* /*timeInfo*/, PaStreamCallbackFlags /*statusFlags*/, I) { iam (paVowelData); float* out = (float*) outputBuffer; for (unsigned int i = 0; i < framesPerBuffer; i++) { *out++ = my z[my istart + i]; /* left */ *out++ = my z[my istart + i]; /* right */ } my istart += framesPerBuffer; return 0; } /********** MENU METHODS **********/ static void menu_cb_help (EDITOR_ARGS) { EDITOR_IAM (VowelEditor); (void) me; Melder_help (U"VowelEditor"); } static void menu_cb_prefs (EDITOR_ARGS) { EDITOR_IAM (VowelEditor); EDITOR_FORM (U"Preferences", 0); BOOLEAN (U"Sound-follows-mouse", true) EDITOR_OK SET_INTEGER (U"Sound-follows-mouse", prefs.soundFollowsMouse) EDITOR_DO my frequencyScale = prefs.frequencyScale; my axisOrientation = prefs.axisOrientation; my soundFollowsMouse = prefs.soundFollowsMouse = GET_INTEGER (U"Sound-follows-mouse"); Graphics_updateWs (my g); EDITOR_END } static void menu_cb_ranges_f1f2 (EDITOR_ARGS) { EDITOR_IAM (VowelEditor); EDITOR_FORM (U"F1 (vert) and F2 (hor) view ranges", 0); POSITIVE (U"left F1 range (Hz)", U"200.0") POSITIVE (U"right F1 range (Hz)", U"1000.0") POSITIVE (U"left F2 range (Hz)", U"500.0") POSITIVE (U"right F2 range (Hz)", U"2500.0") EDITOR_OK SET_REAL (U"left F1 range", prefs.f1min) SET_REAL (U"right F1 range", prefs.f1max) SET_REAL (U"left F2 range", prefs.f2min) SET_REAL (U"right F2 range", prefs.f2max) EDITOR_DO my frequencyScale = prefs.frequencyScale; my axisOrientation = prefs.axisOrientation; my f1min = prefs.f1min = GET_REAL (U"left F1 range"); my f1max = prefs.f1max = GET_REAL (U"right F1 range"); my f2min = prefs.f2min = GET_REAL (U"left F2 range"); my f2max = prefs.f2max = GET_REAL (U"right F2 range"); Graphics_updateWs (my g); EDITOR_END } static void menu_cb_publishSound (EDITOR_ARGS) { EDITOR_IAM (VowelEditor); autoSound publish = VowelEditor_createTarget (me); Editor_broadcastPublication (me, publish.transfer()); } static void menu_cb_extract_FormantGrid (EDITOR_ARGS) { EDITOR_IAM (VowelEditor); VowelEditor_updateVowel (me); autoFormantGrid publish = FormantTier_to_FormantGrid (my vowel -> ft.get()); Editor_broadcastPublication (me, publish.transfer()); } static void menu_cb_extract_KlattGrid (EDITOR_ARGS) { EDITOR_IAM (VowelEditor); VowelEditor_updateVowel (me); autoFormantGrid fg = FormantTier_to_FormantGrid (my vowel -> ft.get()); autoKlattGrid publish = KlattGrid_create (fg -> xmin, fg -> xmax, fg -> formants -> size, 0, 0, 0, 0, 0, 0); KlattGrid_addVoicingAmplitudePoint (publish.peek(), fg -> xmin, 90.0); KlattGrid_replacePitchTier (publish.peek(), my vowel -> pt.get()); KlattGrid_replaceFormantGrid (publish.peek(), KlattGrid_ORAL_FORMANTS, fg.peek()); Editor_broadcastPublication (me, publish.transfer()); } static void menu_cb_extract_PitchTier (EDITOR_ARGS) { EDITOR_IAM (VowelEditor); VowelEditor_updateVowel (me); autoPitchTier publish = Data_copy (my vowel -> pt.get()); Editor_broadcastPublication (me, publish.transfer()); } static void menu_cb_drawTrajectory (EDITOR_ARGS) { EDITOR_IAM (VowelEditor); EDITOR_FORM (U"Draw trajectory", 0) my v_form_pictureWindow (cmd); BOOLEAN (U"Garnish", 1) EDITOR_OK my v_ok_pictureWindow (cmd); EDITOR_DO int garnish = GET_INTEGER (U"Garnish"); my v_do_pictureWindow (cmd); Editor_openPraatPicture (me); if (garnish) { VowelEditor_drawBackground (me, my pictureGraphics); } FormantTier_drawF1F2Trajectory (my vowel -> ft.get(), my pictureGraphics, my f1min, my f1max, my f2min, my f2max, my markTraceEvery, my width); Editor_closePraatPicture (me); EDITOR_END } static void menu_cb_showOneVowelMark (EDITOR_ARGS) { EDITOR_IAM (VowelEditor); EDITOR_FORM (U"Show one vowel mark", 0); POSITIVE (U"F1 (Hz)", U"300.0") POSITIVE (U"F2 (Hz)", U"600.0") WORD (U"Mark", U"u") EDITOR_OK EDITOR_DO double f1 = GET_REAL (U"F1"); double f2 = GET_REAL (U"F2"); char32 *label = GET_STRING (U"Mark"); if (f1 >= my f1min && f1 <= my f1max && f2 >= my f2min && f2 <= my f2max) { long irow = 1; if (! my marks) { my marks = Table_createWithColumnNames (1, U"IPA F1 F2 Colour"); } else { Table_appendRow (my marks.get()); } irow = my marks -> rows -> size; Table_setStringValue (my marks.get(), irow, 1, label); Table_setNumericValue (my marks.get(), irow, 2, f1); Table_setNumericValue (my marks.get(), irow, 3, f2); Graphics_updateWs (my g); } EDITOR_END } static void menu_cb_showVowelMarks (EDITOR_ARGS) { EDITOR_IAM (VowelEditor); EDITOR_FORM (U"Show vowel marks", 0); LABEL (U"note", U"") OPTIONMENU (U"Data set", 1) OPTION (U"American English") OPTION (U"Dutch") OPTION (U"None") OPTIONMENU (U"Speaker", 1) OPTION (U"Man") OPTION (U"Woman") OPTION (U"Child") NATURAL (U"Font size (points)", U"14") EDITOR_OK if (my marksDataset == 9999) SET_STRING (U"note", U"(Warning: current vowel marks are not from one of these data sets.)") SET_INTEGER (U"Data set", my marksDataset); SET_INTEGER (U"Speaker", my speakerType); SET_INTEGER (U"Font size", my marksFontSize); EDITOR_DO my marksDataset = prefs.marksDataset = GET_INTEGER (U"Data set"); my speakerType = prefs.speakerType = GET_INTEGER (U"Speaker"); my marksFontSize = prefs.marksFontSize = GET_INTEGER (U"Font size"); VowelEditor_setMarks (me, my marksDataset, my speakerType, my marksFontSize); Graphics_updateWs (my g); EDITOR_END } static void menu_cb_showVowelMarksFromTableFile (EDITOR_ARGS) { EDITOR_IAM (VowelEditor); EDITOR_FORM_READ (U"VowelEditor: Show vowel marks from Table file", U"VowelEditor: Show vowel marks from Table file..."); EDITOR_DO_READ VowelEditor_getVowelMarksFromTableFile (me, file); Graphics_updateWs (my g); EDITOR_END } static void menu_cb_setF0 (EDITOR_ARGS) { EDITOR_IAM (VowelEditor); EDITOR_FORM (U"Set F0", 0); POSITIVE (U"Start F0 (Hz)", U"150.0") REAL (U"Slope (oct/s)", U"0.0") EDITOR_OK EDITOR_DO double f0 = GET_REAL (U"Start F0"); checkF0 (&my f0, &f0); my f0.start = f0; my f0.slopeOctPerSec = GET_REAL (U"Slope"); GuiText_setString (my f0TextField, Melder_double (my f0.start)); GuiText_setString (my f0SlopeTextField, Melder_double (my f0.slopeOctPerSec)); EDITOR_END } static void menu_cb_setF3F4 (EDITOR_ARGS) { EDITOR_IAM (VowelEditor); EDITOR_FORM (U"Set F3 & F4", 0); POSITIVE (U"F3 (Hz)", U"2500.0") POSITIVE (U"B3 (Hz)", U"250.0") POSITIVE (U"F4 (Hz)", U"3500.0") POSITIVE (U"B4 (Hz)", U"350.0") EDITOR_OK EDITOR_DO double f3 = GET_REAL (U"F3"), b3 = GET_REAL (U"B3"); double f4 = GET_REAL (U"F4"), b4 = GET_REAL (U"B4"); if (f3 >= f4) { Melder_throw (U"F4 must be larger than F3."); } VowelEditor_setF3F4 (me, f3, b3, f4, b4); EDITOR_END } static void menu_cb_reverseTrajectory (EDITOR_ARGS) { EDITOR_IAM (VowelEditor); VowelEditor_Vowel_reverseFormantTier (me); Graphics_updateWs (my g); } static void VowelEditor_Vowel_addData (VowelEditor me, Vowel thee, double time, double f1, double f2, double f0) { autoFormantPoint fp = FormantPoint_create (time); double f3, b3, f4, b4; fp -> formant[0] = f1; fp -> bandwidth[0] = f1 / 10; fp -> formant[1] = f2; fp -> bandwidth[1] = f2 / 10; VowelEditor_getF3F4 (me, f1, f2, &f3, &b3, &f4, &b4); fp -> formant[2] = f3; fp -> bandwidth[2] = b3; fp -> formant[3] = f4; fp -> bandwidth[3] = b4; fp -> numberOfFormants = 4; Collection_addItem (thy ft -> points, fp.transfer()); RealTier_addPoint (thy pt.get(), time, f0); } static void checkF1F2 (VowelEditor me, double *f1, double *f2) { if (*f1 < my f1min) { *f1 = my f1min; } if (*f1 > my f1max) { *f1 = my f1max; } if (*f2 < my f2min) { *f2 = my f2min; } if (*f2 > my f2max) { *f1 = my f2max; } } static void checkF0 (structVowelEditor_F0 *f0p, double *f0) { if (! NUMdefined (*f0)) { *f0 = f0p -> start; } if (*f0 > f0p -> maximum) { *f0 = f0p -> maximum; } if (*f0 < f0p -> minimum) { *f0 = f0p -> minimum; } } static void checkXY (double *x, double *y) { if (*x < 0.0) { *x = 0.0; } else if (*x > 1.0) { *x = 1.0; } if (*y < 0.0) { *y = 0.0; } else if (*y > 1.0) { *y = 1.0; } } static void menu_cb_newTrajectory (EDITOR_ARGS) { EDITOR_IAM (VowelEditor); EDITOR_FORM (U"New Trajectory", 0); POSITIVE (U"Start F1 (Hz)", U"700.0") POSITIVE (U"Start F2 (Hz)", U"1200.0") POSITIVE (U"End F1 (Hz)", U"350.0") POSITIVE (U"End F2 (Hz)", U"800.0") POSITIVE (U"Duration (s)", U"0.25") EDITOR_OK EDITOR_DO double duration = GET_REAL (U"Duration"); autoVowel newVowel = Vowel_create (duration); double time = 0.0; double f0 = getF0 (&my f0, time); double f1 = GET_REAL (U"Start F1"); double f2 = GET_REAL (U"Start F2"); checkF1F2 (me, &f1, &f2); VowelEditor_Vowel_addData (me, newVowel.peek(), time, f1, f2, f0); time = duration; f0 = getF0 (&my f0, time); f1 = GET_REAL (U"End F1"); f2 = GET_REAL (U"End F2"); checkF1F2 (me, &f1, &f2); VowelEditor_Vowel_addData (me, newVowel.peek(), time, f1, f2, f0); GuiText_setString (my durationTextField, Melder_double (MICROSECPRECISION (duration))); my vowel = newVowel.move(); Graphics_updateWs (my g); EDITOR_END } static void menu_cb_extendTrajectory (EDITOR_ARGS) { EDITOR_IAM (VowelEditor); EDITOR_FORM (U"Extend Trajectory", 0); POSITIVE (U"To F1 (Hz)", U"500.0") POSITIVE (U"To F2 (Hz)", U"1500.0") POSITIVE (U"Extra duration (s)", U"0.1") EDITOR_OK EDITOR_DO Vowel thee = my vowel.get(); double newDuration = thy xmax + GET_REAL (U"Extra duration"); double f0 = getF0 (&my f0, newDuration); double f1 = GET_REAL (U"To F1"); double f2 = GET_REAL (U"To F2"); thy xmax = thy pt -> xmax = thy ft -> xmax = newDuration; checkF1F2 (me, &f1, &f2); VowelEditor_Vowel_addData (me, thee, newDuration, f1, f2, f0); GuiText_setString (my durationTextField, Melder_double (MICROSECPRECISION (newDuration))); Graphics_updateWs (my g); EDITOR_END } static void menu_cb_modifyTrajectoryDuration (EDITOR_ARGS) { EDITOR_IAM (VowelEditor); EDITOR_FORM (U"Modify duration", 0); POSITIVE (U"New duration (s)", U"0.5") EDITOR_OK EDITOR_DO GuiText_setString (my durationTextField, Melder_double (MICROSECPRECISION (GET_REAL (U"New duration")))); EDITOR_END } static void menu_cb_shiftTrajectory (EDITOR_ARGS) { EDITOR_IAM (VowelEditor); EDITOR_FORM (U"Shift trajectory", 0); REAL (U"F1 (semitones)", U"0.5") REAL (U"F2 (semitones)", U"0.5") EDITOR_OK EDITOR_DO VowelEditor_shiftF1F2 (me, GET_REAL (U"F1"), GET_REAL (U"F2")); Graphics_updateWs (my g); EDITOR_END } static void menu_cb_showTrajectoryTimeMarksEvery (EDITOR_ARGS) { EDITOR_IAM (VowelEditor); EDITOR_FORM (U"Show trajectory time marks every", 0); REAL (U"Distance (s)", U"0.05") EDITOR_OK SET_REAL (U"Distance", my markTraceEvery) EDITOR_DO my markTraceEvery = GET_REAL (U"Distance"); if (my markTraceEvery < 0) { my markTraceEvery = 0; } Graphics_updateWs (my g); EDITOR_END } /********** BUTTON METHODS **********/ static void gui_button_cb_play (I, GuiButtonEvent /*event*/) { iam (VowelEditor); autoSound thee = VowelEditor_createTarget (me); Sound_play (thee.peek(), nullptr, nullptr); Graphics_updateWs (my g); } static void gui_button_cb_publish (I, GuiButtonEvent /*event*/) { iam (VowelEditor); autoSound publish = VowelEditor_createTarget (me); Editor_broadcastPublication (me, publish.transfer()); } static void gui_button_cb_reverse (I, GuiButtonEvent event) { (void) event; iam (VowelEditor); VowelEditor_Vowel_reverseFormantTier (me); struct structGuiButtonEvent play_event = { 0 }; gui_button_cb_play (me, &play_event); } /* Main drawing routine: it's been called after every call to Graphics_updateWs (g) */ static void gui_drawingarea_cb_expose (I, GuiDrawingAreaExposeEvent /*event*/) { iam (VowelEditor); Melder_assert (me); Melder_assert (my vowel); double ts = my vowel -> xmin, te = my vowel -> xmax; FormantTier ft = my vowel -> ft.get(); Melder_assert (ft); static MelderString statusInfo { 0 }; if (! my g) { return; // could be the case in the very beginning } Graphics_clearWs (my g); appendF1F2F0 (&statusInfo, STATUSINFO_STARTINTR0, FormantTier_getValueAtTime (ft, 1, ts), FormantTier_getValueAtTime (ft, 2, ts), getF0 (&my f0, ts), STATUSINFO_ENDING); GuiLabel_setText (my startInfo, statusInfo.string); MelderString_empty (&statusInfo); appendF1F2F0 (&statusInfo, STATUSINFO_ENDINTR0, FormantTier_getValueAtTime (ft, 1, te), FormantTier_getValueAtTime (ft, 2, te), getF0 (&my f0, te), STATUSINFO_ENDING); GuiLabel_setText (my endInfo, statusInfo.string); MelderString_empty (&statusInfo); Graphics_setGrey (my g, 0.9); Graphics_fillRectangle (my g, 0.0, 1.0, 0.0, 1.0); Graphics_setInner (my g); Graphics_setWindow (my g, 0.0, 1.0, 0.0, 1.0); Graphics_setGrey (my g, 1.0); Graphics_fillRectangle (my g, 0.0, 1.0, 0.0, 1.0); Graphics_unsetInner (my g); Graphics_setGrey (my g, 0.0); VowelEditor_drawBackground (me, my g); Melder_assert (me); Melder_assert (my vowel); Melder_assert (my vowel -> ft); FormantTier_drawF1F2Trajectory (my vowel -> ft.get(), my g, my f1min, my f1max, my f2min, my f2max, my markTraceEvery, my width); } static void gui_drawingarea_cb_resize (I, GuiDrawingAreaResizeEvent event) { iam (VowelEditor); Melder_assert (me); if (! my g) { return; // could be the case in the very beginning } Graphics_setWsViewport (my g, 0.0, event -> width, 0.0, event -> height); my width = event -> width; my height = event -> height; Graphics_setWsWindow (my g, 0.0, my width, 0.0, my height); Graphics_setViewport (my g, 0.0, my width, 0.0, my height); Graphics_updateWs (my g); /* Save the current shell size as the user's preference for a new VowelEditor. */ prefs.shellWidth = GuiShell_getShellWidth (my d_windowForm); prefs.shellHeight = GuiShell_getShellHeight (my d_windowForm); } static void VowelEditor_Vowel_updateTiers (VowelEditor me, Vowel thee, double time, double x, double y) { if (time > thy xmax) { thy xmax = time; thy ft -> xmax = time; thy pt -> xmax = time; } double f0 = getF0 (& my f0, time), f1, f2; autoFormantPoint point = FormantPoint_create (time); VowelEditor_getF1F2FromXY (me, x, y, &f1, &f2); double f3, b3, f4, b4; VowelEditor_getF3F4 (me, f1, f2, &f3, &b3, &f4, &b4); point -> formant[0] = f1; point -> bandwidth[0] = f1 / 10; point -> formant[1] = f2; point -> bandwidth[1] = f2 / 10; point -> formant[2] = f3; point -> bandwidth[2] = b3; point -> formant[3] = f4; point -> bandwidth[3] = b4; point -> numberOfFormants = 4; Collection_addItem (thy ft -> points, point.transfer()); RealTier_addPoint (thy pt.get(), time, f0); } // shift key always extends what already is. // Special case : !soundFollowsMouse. The first click just defines the vowel's first f1f2-position, static void gui_drawingarea_cb_click (I, GuiDrawingAreaClickEvent event) { iam (VowelEditor); Vowel thee = nullptr; autoVowel athee; double x, y, xb, yb, tb, t, dt = 0.0; double t0 = Melder_clock (); long iskipped = 0; struct structGuiButtonEvent gb_event = { 0 }; Graphics_setInner (my g); Graphics_getMouseLocation (my g, & x, & y); checkXY (&x, &y); if (event -> shiftKeyPressed) { VowelEditor_updateExtendDuration (me); (my shiftKeyPressed) ++; thee = my vowel.get(); dt = thy xmax + my extendDuration; t = 0.0 + dt; VowelEditor_Vowel_updateTiers (me, thee, t, x, y); GuiText_setString (my durationTextField, Melder_double (t)); if (! my soundFollowsMouse) { goto end; } } else { t = 0.0; my shiftKeyPressed = 0; athee = Vowel_create (MINIMUM_SOUND_DURATION); thee = athee.peek(); VowelEditor_Vowel_updateTiers (me, thee, t, x, y); GuiText_setString (my durationTextField, Melder_double (t)); if (! my soundFollowsMouse) { VowelEditor_Vowel_updateTiers (me, thee, MINIMUM_SOUND_DURATION, x, y); goto end; } } Graphics_xorOn (my g, Graphics_BLUE); while (Graphics_mouseStillDown (my g)) { xb = x, yb = y, tb = t; t = Melder_clock () - t0 + dt; // Get relative time in seconds from the clock Graphics_getMouseLocation (my g, & x, & y); checkXY (&x, &y); // If the new point equals the previous one: no tier update if (xb == x && yb == y) { iskipped++; continue; } // Add previous point only if at least one previous event was skipped... if (iskipped > 0) { VowelEditor_Vowel_updateTiers (me, thee, tb, xb, yb); } iskipped = 0; Graphics_line (my g, xb, yb, x, y); VowelEditor_Vowel_updateTiers (me, thee, t, x, y); GuiText_setString (my durationTextField, Melder_double (MICROSECPRECISION (t))); } t = Melder_clock () - t0; // To prevent ultra short clicks we set a minimum of 0.01 s duration if (t < MINIMUM_SOUND_DURATION) { t = MINIMUM_SOUND_DURATION; } t += dt; GuiText_setString (my durationTextField, Melder_double (MICROSECPRECISION (t))); VowelEditor_Vowel_updateTiers (me, thee, t, x, y); Graphics_xorOff (my g); end: Graphics_unsetInner (my g); if (! my shiftKeyPressed) { my vowel = athee.move(); } Melder_assert (! athee); gui_button_cb_play (me, & gb_event); } static void gui_drawingarea_cb_key (I, GuiDrawingAreaKeyEvent event) { iam (VowelEditor); (void) me; (void) event; } static void cb_publish (Editor /*editor*/, void* /*closure*/, Daata publish) { try { praat_new (publish, U""); praat_updateSelection (); } catch (MelderError) { Melder_flushError (); } } static void updateWidgets (I) { iam (VowelEditor); (void) me; } void structVowelEditor :: v_destroy () { forget (g); VowelEditor_Parent :: v_destroy (); } void structVowelEditor :: v_createMenus () { VowelEditor_Parent :: v_createMenus (); Editor_addMenu (this, U"View", 0); Editor_addCommand (this, U"File", U"Preferences...", 0, menu_cb_prefs); Editor_addCommand (this, U"File", U"-- publish data --", 0, nullptr); Editor_addCommand (this, U"File", U"Publish Sound", 0, menu_cb_publishSound); Editor_addCommand (this, U"File", U"Extract KlattGrid", 0, menu_cb_extract_KlattGrid); Editor_addCommand (this, U"File", U"Extract FormantGrid", 0, menu_cb_extract_FormantGrid); Editor_addCommand (this, U"File", U"Extract PitchTier", 0, menu_cb_extract_PitchTier); Editor_addCommand (this, U"File", U"-- drawing --", 0, nullptr); Editor_addCommand (this, U"File", U"Draw trajectory...", 0, menu_cb_drawTrajectory); Editor_addCommand (this, U"File", U"-- scripting --", 0, nullptr); Editor_addCommand (this, U"Edit", U"-- f0 --", 0, nullptr); Editor_addCommand (this, U"Edit", U"Set F0...", 0, menu_cb_setF0); Editor_addCommand (this, U"Edit", U"Set F3 & F4...", 0, menu_cb_setF3F4); Editor_addCommand (this, U"Edit", U"-- trajectory commands --", 0, nullptr); Editor_addCommand (this, U"Edit", U"Reverse trajectory", 0, menu_cb_reverseTrajectory); Editor_addCommand (this, U"Edit", U"Modify trajectory duration...", 0, menu_cb_modifyTrajectoryDuration); Editor_addCommand (this, U"Edit", U"New trajectory...", 0, menu_cb_newTrajectory); Editor_addCommand (this, U"Edit", U"Extend trajectory...", 0, menu_cb_extendTrajectory); Editor_addCommand (this, U"Edit", U"Shift trajectory...", 0, menu_cb_shiftTrajectory); Editor_addCommand (this, U"View", U"F1 & F2 range...", 0, menu_cb_ranges_f1f2); Editor_addCommand (this, U"View", U"--show vowel marks--", 0, nullptr); Editor_addCommand (this, U"View", U"Show one vowel mark...", Editor_HIDDEN, menu_cb_showOneVowelMark); Editor_addCommand (this, U"View", U"Show vowel marks...", Editor_HIDDEN, menu_cb_showVowelMarks); Editor_addCommand (this, U"View", U"Show vowel marks from fixed set...", 0, menu_cb_showVowelMarks); Editor_addCommand (this, U"View", U"Show vowel marks from Table file...", 0, menu_cb_showVowelMarksFromTableFile); Editor_addCommand (this, U"View", U"--show trajectory time marks--", 0, nullptr); Editor_addCommand (this, U"View", U"Show trajectory time marks every...", 0, menu_cb_showTrajectoryTimeMarksEvery); } void structVowelEditor :: v_createHelpMenuItems (EditorMenu menu) { VowelEditor_Parent :: v_createHelpMenuItems (menu); EditorMenu_addCommand (menu, U"VowelEditor help", '?', menu_cb_help); } void structVowelEditor :: v_createChildren () { double button_width = 90, text_width = 95, status_info_width = 290; double left, right, top, bottom, bottom_widgets_top, bottom_widgets_bottom, bottom_widgets_halfway; // Three buttons on a row: Play, Reverse, Publish left = 10; right = left + button_width; bottom_widgets_top = top = -MARGIN_BOTTOM + 10; bottom_widgets_bottom = bottom = -STATUS_INFO; playButton = GuiButton_createShown (d_windowForm, left, right, top, bottom, U"Play", gui_button_cb_play, this, 0); left = right + 10; right = left + button_width; reverseButton = GuiButton_createShown (d_windowForm, left, right, top, bottom, U"Reverse", gui_button_cb_reverse, this, 0); left = right + 10; right = left + button_width; publishButton = GuiButton_createShown (d_windowForm, left, right, top, bottom, U"Publish", gui_button_cb_publish, this, 0); // Four Text widgets with the label on top: Duration, Extend, F0, Slope // Make the F0 slope button 10 wider to accomodate the text // We wil not use a callback from a Text widget. It will get called multiple times during the editing // of the text. Better to have all editing done and then query the widget for its value! left = right + 10; right = left + text_width; bottom_widgets_halfway = bottom = (top + bottom) / 2; top = bottom_widgets_top; GuiLabel_createShown (d_windowForm, left, right, top , bottom, U"Duration (s):", 0); top = bottom; bottom = bottom_widgets_bottom; durationTextField = GuiText_createShown (d_windowForm, left, right, top, bottom, 0); left = right + 10; right = left + text_width; top = bottom_widgets_top; bottom = bottom_widgets_halfway; GuiLabel_createShown (d_windowForm, left, right, top, bottom, U"Extend (s):", 0); top = bottom; bottom = bottom_widgets_bottom; extendTextField = GuiText_createShown (d_windowForm, left, right, top, bottom, 0); left = right + 10; right = left + text_width; top = bottom_widgets_top; bottom = bottom_widgets_halfway; GuiLabel_createShown (d_windowForm, left, right, top, bottom, U"Start F0 (Hz):", 0); top = bottom; bottom = bottom_widgets_bottom; f0TextField = GuiText_createShown (d_windowForm, left, right, top, bottom, 0); left = right + 10; right = left + text_width + 10; top = bottom_widgets_top; bottom = bottom_widgets_halfway; GuiLabel_createShown (d_windowForm, left, right, top, bottom, U"F0 slope (oct/s):", 0); top = bottom; bottom = bottom_widgets_bottom; f0SlopeTextField = GuiText_createShown (d_windowForm, left, right, top, bottom, 0); // The status startInfo and endInfo widget at the bottom: bottom = - (STATUS_INFO - Gui_LABEL_HEIGHT) / 2; top = bottom - Gui_LABEL_HEIGHT; left = MARGIN_LEFT; right = left + status_info_width; startInfo = GuiLabel_createShown (d_windowForm, left, right, top, bottom, U"", 0); left = right; right = left + status_info_width; endInfo = GuiLabel_createShown (d_windowForm, left, right, top, bottom, U"", 0); /***** Create drawing area. *****/ // Approximately square because for our defaults: f1min=200, f1max=1000 and f2min = 500, f2mx = 2500, // log distances are equal (log (1000/200) == log (2500/500) ). //drawingArea = GuiDrawingArea_createShown (d_windowForm, 0, 0, Machine_getMenuBarHeight (), -MARGIN_BOTTOM, // gui_drawingarea_cb_expose, gui_drawingarea_cb_click, gui_drawingarea_cb_key, gui_drawingarea_cb_resize, this, 0); drawingArea = GuiDrawingArea_createShown (d_windowForm, 0, 0, Machine_getMenuBarHeight (), -MARGIN_BOTTOM, gui_drawingarea_cb_expose, gui_drawingarea_cb_click, nullptr, gui_drawingarea_cb_resize, this, 0); width = GuiControl_getWidth (drawingArea); height = GuiControl_getHeight (drawingArea); } static autoSound VowelEditor_createTarget (VowelEditor me) { try { VowelEditor_updateVowel (me); // update pitch and duration autoSound thee = Vowel_to_Sound_pulses (my vowel.get(), 44100.0, 0.7, 0.05, 30); Vector_scale (thee.peek(), 0.99); Sound_fadeIn (thee.peek(), 0.005, 1); Sound_fadeOut (thee.peek(), 0.005); return thee; } catch (MelderError) { Melder_throw (U"Target Sound not created."); } } autoVowelEditor VowelEditor_create (const char32 *title, Daata data) { try { trace (U"enter"); autoVowelEditor me = Thing_new (VowelEditor); Melder_assert (me.peek()); Editor_init (me.peek(), 0, 0, prefs.shellWidth, prefs.shellHeight, title, data); #if motif Melder_assert (XtWindow (my drawingArea -> d_widget)); #endif my g = Graphics_create_xmdrawingarea (my drawingArea); Melder_assert (my g); Graphics_setFontSize (my g, 12); Editor_setPublicationCallback (me.peek(), cb_publish, nullptr); my f1min = prefs.f1min; my f1max = prefs.f1max; my f2min = prefs.f2min; my f2max = prefs.f2max; my frequencyScale = prefs.frequencyScale; my axisOrientation = prefs.axisOrientation; my speakerType = prefs.speakerType; my marksDataset = prefs.marksDataset; my marksFontSize = prefs.marksFontSize; my soundFollowsMouse = prefs.soundFollowsMouse; if (my marksDataset > 3) { // TODO variable?? VowelEditor_createTableFromVowelMarksInPreferences (me.peek()); } else { VowelEditor_setMarks (me.peek(), my marksDataset, my speakerType, 14); } VowelEditor_setF3F4 (me.peek(), prefs.f3, prefs.b3, prefs.f4, prefs.b4); my maximumDuration = BUFFER_SIZE_SEC; my extendDuration = prefs.extendDuration; if (my data) { my vowel = Data_copy (static_cast (data)); } else { my vowel = Vowel_create_twoFormantSchwa (0.2); } my markTraceEvery = prefs.markTraceEvery; my f0 = f0default; GuiText_setString (my f0TextField, Melder_double (my f0.start)); GuiText_setString (my f0SlopeTextField, Melder_double (my f0.slopeOctPerSec)); GuiText_setString (my durationTextField, U"0.2"); // Source has been created GuiText_setString (my extendTextField, Melder_double (my extendDuration)); my grid = griddefault; { // This exdents because it's a hack: struct structGuiDrawingAreaResizeEvent event = { my drawingArea, 0 }; event. width = GuiControl_getWidth (my drawingArea); event. height = GuiControl_getHeight (my drawingArea); gui_drawingarea_cb_resize (me.peek(), & event); } //struct structGuiDrawingAreaResizeEvent event = { 0 }; //event.widget = my drawingArea; //gui_drawingarea_cb_resize (me, & event); updateWidgets (me.peek()); trace (U"exit"); return me; } catch (MelderError) { Melder_throw (U"VowelEditor not created."); } } /* End of file VowelEditor.cpp */ praat-6.0.04/dwtools/VowelEditor.h000066400000000000000000000050141261542461700170270ustar00rootroot00000000000000#ifndef _VowelEditor_h_ #define _VowelEditor_h_ /* VowelEditor.h * * Copyright (C) 2008-2011, 2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20070130 First djmw 20110306 Latest modification. */ #include "FormantTier.h" #include "PitchTier.h" #include "TableOfReal.h" #include "Editor.h" #include "Vowel_def.h" oo_CLASS_CREATE (Vowel, Function); struct structVowelEditor_F0 { double start; double slopeOctPerSec; double minimum, maximum; double samplingFrequency, adaptFactor, adaptTime; long interpolationDepth; }; struct structVowelEditor_F1F2Grid { double df1, df2; int text_left, text_right, text_bottom, text_top; double grey; }; Thing_define (VowelEditor, Editor) { int soundFollowsMouse, shiftKeyPressed; double f1min, f1max, f2min, f2max; // domain of graphics F1-F2 area autoMatrix f3, b3, f4, b4; int frequencyScale; // 0: lin, 1: log, 2: bark, 3: mel int axisOrientation; // 0: origin topright + f1 down + f2 to left, 0: origin lb + f1 right +f2 up int marksDataset, speakerType; // 1 = male, 2 = female, 3 = child int marksFontSize; Graphics g; // the drawing short width, height; // size of drawing area in pixels autoTable marks; // Vowel, F1, F2, Colour... autoVowel vowel; double markTraceEvery; structVowelEditor_F0 f0; double maximumDuration, extendDuration; GuiDrawingArea drawingArea; GuiButton playButton, reverseButton, publishButton; GuiText f0TextField, f0SlopeTextField, durationTextField, extendTextField; GuiLabel startInfo, endInfo; structVowelEditor_F1F2Grid grid; void v_destroy () override; bool v_scriptable () override { return false; } void v_createChildren () override; void v_createMenus () override; void v_createHelpMenuItems (EditorMenu menu) override; }; autoVowelEditor VowelEditor_create (const char32 *title, Daata data); void VowelEditor_prefs (); #endif /* _VowelEditor_h_ */ praat-6.0.04/dwtools/Vowel_def.h000066400000000000000000000017261261542461700165040ustar00rootroot00000000000000/* Vowel_def.h * * Copyright (C) 2011,2015 David Weenink & Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT Vowel oo_DEFINE_CLASS (Vowel, Function) oo_AUTO_OBJECT (PitchTier, 0, pt) oo_AUTO_OBJECT (FormantTier, 0, ft) oo_END_CLASS (Vowel) #undef ooSTRUCT /* End of file Vowel_def.h */ praat-6.0.04/dwtools/manual_BSS.cpp000066400000000000000000000560771261542461700171220ustar00rootroot00000000000000/* manual_BSS.cpp * * Copyright (C) 2010-2014, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20101227 Initial version */ #include "ManPagesM.h" void manual_BSS (ManPages me); void manual_BSS (ManPages me) { MAN_BEGIN (U"CrossCorrelationTable", U"djmw", 20110105) INTRO (U"One of the types of objects in Praat. A CrossCorrelationTable represents the cross-correlations between " "a number of signals. Cell [%i,%j] of a CrossCorrelationTable contains the cross-correlation between the %i-th " "and the %j-th signal. For example, the CrossCorrelationTable of an %n-channel sound is a %n\\xx%n table where " "the number in cell [%i,%j] is the cross-correlation of channel %i with channel %j (for a particular lag time %\\ta).") NORMAL (U"A CrossCorrelationTable has a square matrix whose cells contain the cross-correlations between " "the signals and a centroid vector with the average value of each signal.") ENTRY (U"Remarks") NORMAL (U"Sometimes in the statistical literature, the cross-correlation between signals is also called " "\"covariance\". However, the only thing a @@Covariance@ has in common with a CrossCorrelationTable is that " "both are symmetric matrices. The differences between a CrossCorrelationTable and a Covariance are:") TAG (U"1. a Covariance matrix is always positive-definite; for a cross-correlation table this is only guaranteed if " "the lag time %\\ta = 0.") TAG (U"2. The elements %%c__ij_% in a Covariance always satisfy |%%c__ij_%/\\Vr(%%c__ii_%\\.c%%c__jj_%)| \\<_ 1; this is " "generally not the case for cross-correlations.") MAN_END MAN_BEGIN (U"CrossCorrelationTables", U"djmw", 20101227) INTRO (U"One of the types of objects in Praat. A CrossCorrelationTables represents a collection of @@CrossCorrelationTable@ objects.") MAN_END MAN_BEGIN (U"CrossCorrelationTables: Create test set...", U"djmw", 20110212) INTRO (U"Create a collection of @@CrossCorrelationTable@s that are all derived from different diagonal matrices by the same transformation matrix.") ENTRY (U"Settings") SCRIPT (5.4, Manual_SETTINGS_WINDOW_HEIGHT (4), U"" Manual_DRAW_SETTINGS_WINDOW ("CrossCorrelationTables: Create test set", 4) Manual_DRAW_SETTINGS_WINDOW_FIELD ("Matrix dimension", "5") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Number of matrices", "20") Manual_DRAW_SETTINGS_WINDOW_BOOLEAN("First is positive-definite",1) Manual_DRAW_SETTINGS_WINDOW_FIELD ("Sigma", "0.02") ) TAG (U"##Matrix dimension") DEFINITION (U"determines the size of the square matrix with cross-correlations.") TAG (U"##Number of matrices") DEFINITION (U"determines the number of matrices that have to be generated.") TAG (U"##First is positive-definite") DEFINITION (U"guarantees that the first matrix of the series is positive definite.") TAG (U"##Sigma") DEFINITION (U"the standard deviation of the noise that is added to each transformation matrix element. A value " "of zero makes all the cross-correlation matrices jointly diagonalizable. A value greater than zero " "makes each transformation matrix a little different and the collection not jointly " "diagonalizable anymore.") ENTRY (U"Algorithm") NORMAL (U"All the CrossCorrelationTable matrices are generated as #V\\'p\\.c#D__%k_\\.c #V, where #D__%k_ is a diagonal matrix " "with entries randomly choosen from the [-1,1] interval. The matrix #V is a \"random\" orthogonal matrix " "obtained from the singular value decomposition of a matrix #M = #U\\.c#D\\.c#V\\'p, where the cells of the " "matrix #M are random Gaussian numbers with mean 0 and standard deviation 1.") NORMAL (U"If the first matrix has to be positive definite, the numbers on the diagonal of #D__1_ are randomly " "chosen from the [0.1,1] interval.") MAN_END MAN_BEGIN (U"Sound: To CrossCorrelationTable...", U"djmw", 20110212) INTRO (U"A command that creates a @@CrossCorrelationTable@ form every selected @@Sound@ object.") ENTRY (U"Settings") SCRIPT (5.4, Manual_SETTINGS_WINDOW_HEIGHT (2), U"" Manual_DRAW_SETTINGS_WINDOW ("Sound: To CrossCorrelationTable", 2) Manual_DRAW_SETTINGS_WINDOW_RANGE("Time range", "0.0", "10.0") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Lag time", "0.0") ) TAG (U"##Time range (s)#,") DEFINITION (U"determines the time range over which the table is calculated.") TAG (U"##Lag time (s)#,") DEFINITION (U"determines the lag time.") ENTRY (U"Algorithm") NORMAL (U"The cross-correlation between channel %i and channel %j for lag time \\ta is defined as the " "discretized #integral") FORMULA (U"cross-corr (%c__%i_, %c__%j_) [%\\ta] \\=3 \\su__%t_ %c__%i_[%t] %c__%j_[%t+%\\ta] %%\\Det%,") NORMAL (U"where %t and %t+%\\ta are discrete times and %%\\Det% is the @@sampling period@. ") MAN_END MAN_BEGIN (U"Sound: To Covariance (channels)...", U"djmw", 20120303) INTRO (U"Detemines the @@Covariance|covariances@ between the channels of a selected @Sound.") NORMAL (U"The covariance of a sound is determined by calculating the @@CrossCorrelationTable@ of a multichannel sound for a lag time equal to zero.") MAN_END MAN_BEGIN (U"Sound: To Sound (blind source separation)...", U"djmw", 20151030) INTRO (U"Analyze the selected multi-channel sound into its independent components by an iterative method.") NORMAL (U"The @@blind source separation@ method to find the independent components tries to simultaneously diagonalize a number of " "@@CrossCorrelationTable@s that are calculated from the multi-channel sound at different lag times.") ENTRY (U"Settings") SCRIPT (5.4, Manual_SETTINGS_WINDOW_HEIGHT (6), U"" Manual_DRAW_SETTINGS_WINDOW ("Sound: To Sound (blind source separation)", 6) Manual_DRAW_SETTINGS_WINDOW_RANGE("Time range (s)", "0.0", "10.0") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Number of cross-correlations", "20") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Lag times", "0.002") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Maximum number of iterations", "100") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Tolerance", "0.001") Manual_DRAW_SETTINGS_WINDOW_OPTIONMENU("Diagonalization method", "ffdiag") ) TAG (U"##Time range (s)") DEFINITION (U"defines the time range over which the ##CrossCorrelationTable#s of the sound will be calculated.") TAG (U"##Number of cross-correlations") DEFINITION (U"defines the number of ##CrossCorrelationTable#s to be calculated.") TAG (U"##Lag times") DEFINITION (U"defines the lag time %\\ta__0_ for the ##CrossCorrelationTable#s. These tables " "are calculated at lag times %\\ta__k_=(%k - 1)%\\ta__0_, where %k runs from 1 to %%numberOfCrosscorrelations%.") TAG (U"##Maximum number of iterations") DEFINITION (U"defines a stopping criterion for the iteration. The iteration will stops when this number is reached.") TAG (U"##Tolerance") DEFINITION (U"defines another stopping criterion that depends on the method used.") TAG (U"##Diagonalization method") DEFINITION (U"defines the method to determine the independent components.") ENTRY (U"Algorithm") NORMAL (U"This method tries to decompose the sound according to the %%instantaneous% mixing model") FORMULA (U"#Y=#A\\.c#X.") NORMAL (U"In this model #Y is a matrix with the selected multi-channel sound, #A is a so-called " "%%mixing matrix% and #X is a matrix with the independent components. " "Essentially the model says that each channel in the multi-channel sound is a linear combination of the " "independent sound components in #X. " "If we would know the mixing matrix #A we could easily solve the model above for #X by standard means. " "However, if we don't know #A and we don't know #X, the decomposition of #Y is underdetermined. This means there " "are an infinite number of possible combinations of #A and #X that result in the same #Y. ") NORMAL (U"One approach to solve the equation above is to make assumptions about the statistical properties " "of the components in the matrix #X: it turns out that a sufficient assumption is to assume that the " "components in #X at each time instant are %%statistically independent%. This is not an unrealistic " "assumption in many cases, although in practice it need not be exactly the case. Another assumption is " "that the mixing matrix is constant, which means that the mixing conditions did not change during the recoding of the sound." ) NORMAL (U"The theory says that statistically independent signals are not correlated (although the reverse " "is not always true: signals that are not correlated don't have to be statistically independent). " "The methods implemented here all follow this lead as follows. If we calculate the @@CrossCorrelationTable@ " "for the left and the right side signals of the equation above, then, " "for the multi-channel sound #Y this will result in a cross-correlation matrix #C. For the right side we " "obtain #A\\.c#D\\.c#A\\'p, where #D is a diagonal matrix because all the cross-correlations between " "different independent components are zero by definition. This results in the following identity: ") FORMULA (U"#C(\\ta)=#A\\.c#D(\\ta)\\.c#A\\'p, for all values of the lag time \\ta.") NORMAL (U"This equation says that, given the model, the cross-correlation matrix can be diagonalized for " "all values of the lag time %%by the same transformation matrix% #A.") NORMAL (U"If we calculate the cross-correlation matrices for a number of different lag times, say 20, we " "then have to obtain the matrix #A that diagonalizes them all. Unfortunately there is no closed form solution " "that diagonalizes more than two matrices at the same time and we have to resort to iterative " "algorithms for joint diagonalization. ") NORMAL (U"Two of these algorithms are the ##qdiag# method as described in @@Vollgraf & Obermayer (2006)@ " "and the ##ffdiag# method as described in @@Ziehe et al. (2004)@. ") NORMAL (U"Unfortunately the convergence criteria of these two algorithms cannot easily be compared as " "the criterion for the ##ffdiag# algorithm is the relative change of the square root of the sum of the " "squared off-diagonal " "elements of the transformed cross-correlation matrices and the criterion for ##qdiag# is the largest " "change in the eigenvectors norm during an iteration.") ENTRY (U"Example") NORMAL (U"We start by creating a speech synthesizer that need to create two sounds. We will mix the two sounds and finally our blind source separation software will try to undo our mixing by extracting the two original sounds as well as possible from the two mixtures.") CODE(U"synth = Create SpeechSynthesizer: \"English\", \"default\"") CODE(U"s1 = To Sound: \"This is some text\", \"no\"") NORMAL (U"The first speech sound was created from the text \"This is some text\" at a speed of 175 words per minute.") CODE(U"selectObject: synth") CODE(U"Set speech output settings: 44100, 0.01, 80, 50, 145, \"no\", \"IPA\"") CODE(U"s2 = To Sound.: \"Abracadabra, abra\", \"no\"") NORMAL (U"The second sound \"Abracadabra, abra\" was synthesized at 145 words per minute with a somewhat larger pitch excursion (80) than the previous sound (50).") CODE(U"plusObject: s1") CODE(U"stereo = Combine to stereo") NORMAL (U"We combine the two separate sounds into one stereo sound because our blind source separation works on multichannel sounds only.") CODE(U"mm = Create simple MixingMatrix: \"mm\", 2, 2, \"1.0 2.0 2.0 1.0\"") NORMAL (U"A two by two MixingMatrix is created.") CODE(U"plusObject: stereo") CODE(U"Mix") NORMAL (U"The last command, Mix, creates a new two-channel sound where each channel is a linear mixture of the two " "channels in the stereo sound, i.e. channel 1 is the sum of s1 and s2 with mixture strengths of 1 and 2, respectively. " "The second channel is also the sum of s1 and s2 but now with mixture strengths 2 and 1, respectively.") CODE (U"To Sound (blind source separation): 0.1, 1, 20, 0.0002, 100, 0.001, \"ffdiag\"") NORMAL (U"The two channels in the new sound that results from this command contain a reasonable approximation of " "the two originating sounds.") NORMAL (U"In the top panel the two speech sounds \"This is some text\" and \"abracadabra, abra\". " "The middle panel shows the two mixed sounds while the lower panel shows the two sounds after unmixing.") SCRIPT (6, 6, U" " "syn = Create SpeechSynthesizer: \"English\", \"default\"\n" "s1 = To Sound: \"This is some text\", \"no\"\n" "selectObject: syn\n" "Set speech output settings: 44100, 0.01, 80, 50, 145, \"no\", \"IPA\"\n" "s2 = To Sound: \"abracadabra, abra\", \"no\"\n" "plusObject: s1\n" "stereo = Combine to stereo\n" "Select inner viewport: 1, 6, 0.1, 1.9\n" "Draw: 0, 0, 0, 0, \"no\", \"Curve\"\n" "Draw inner box\n" "mm = Create simple MixingMatrix: \"mm\", 2, 2, \"1.0 2.0 2.0 1.0\"\n" "plusObject: stereo\n" "mixed = Mix\n" "Select inner viewport: 1, 6, 2.1, 3.9\n" "Draw: 0, 0, 0, 0, \"no\", \"Curve\"\n" "Draw inner box\n" "unmixed = To Sound (bss): 0.1, 1, 20, 0.00021, 100, 0.001, \"ffdiag\"\n" "Select inner viewport: 1, 6, 4.1, 5.9\n" "Draw: 0, 0, 0, 0, \"no\", \"Curve\"\n" "Draw inner box\n" "removeObject: unmixed, syn, stereo, s1, s2, mixed, mm\n" ) NORMAL (U"The first two panels will not change between different sessions of praat. The last panel, which shows " "the result of the blind source separation, i.e. unmixing, will not always be the same because of two things. In the first place the unmixing always starts with an initialisation with random values of the parameters that " "we have to determine for the blind source separation. Therefore the iteration sequence will never be the same and the final outcomes might differ. In the second place, as was explained in the @@blind source separation@ manual, the unmixing is only " "unique up to a scale factor and a permutation. Therefore the channels in the unmixed sound do not necessarily correspond to the corresponding channel in our \"original\" stereo sound.") NORMAL (U"The complete script:") CODE (U"syn = Create SpeechSynthesizer: \"English\", \"default\"") CODE (U"s1 = To Sound: \"This is some text\", \"no\"") CODE (U"selectObject: syn") CODE (U"Set speech output settings: 44100, 0.01, 80, 50, 145, \"no\", \"IPA\"") CODE (U"s2 = To Sound: \"abracadabra, abra\", \"no\"") CODE (U"plusObject: s1") CODE (U"stereo = Combine to stereo") CODE (U"Select inner viewport: 1, 6, 0.1, 1.9") CODE (U"Draw: 0, 0, 0, 0, \"no\", \"Curve\"") CODE (U"Draw inner box") CODE (U"mm = Create simple MixingMatrix: \"mm\", 2, 2, \"1.0 2.0 2.0 1.0\"") CODE (U"plusObject: stereo") CODE (U"mixed = Mix") CODE (U"Select inner viewport: 1, 6, 2.1, 3.9") CODE (U"Draw: 0, 0, 0, 0, \"no\", \"Curve\"") CODE (U"Draw inner box") CODE (U"unmixed = To Sound (bss): 0.1, 1, 20, 0.00021, 100, 0.001, \"ffdiag\"") CODE (U"Select inner viewport: 1, 6, 4.1, 5.9") CODE (U"Draw: 0, 0, 0, 0, \"no\", \"Curve\"") CODE (U"Draw inner box") CODE (U"removeObject: unmixed, syn, stereo, s1, s2, mixed, mm") MAN_END MAN_BEGIN (U"Sound: To Sound (whiten channels)...", U"djmw", 20120303) INTRO (U"Transforms the channels of the selected @Sound linearly to make them white, i.e. the new channels will be uncorrelated and their variances equal unity.") ENTRY (U"Settings") TAG (U"##Variance fraction to keep#,") DEFINITION (U"determines, indirectly, how many channels the final sound will have.") ENTRY (U"Algorithm") NORMAL (U"We start by determining the @@Sound: To Covariance (channels)...|covariance@ of the selected sound. " "Next a @@Principal component analysis|principal component analysis@ determines the eigenvalues and eigenvectors of the covariance matrix. The settings of the variance fraction to keep determines how many eigenvalues and eigenvectors we use for the whitening. This number, %p, will also be equal to the number of channels of the resulting whitened sound.") NORMAL (U"In mathematical terms. For an %n-channel sound, if #E is the matrix with the eigenvectors and #D=diag (%d__1_, %d__2_,..., %d__n_) is the diagonal matrix with the " "eigenvalues of the covariance matrix, then the whitening matrix is #W = #E#D^^-1/2^#E\\'p, where #D^^-1/2^=diag (%d__1_^^-1/2^, ..., %d__p_^^-1/2^, 0, ..., 0). Only the %p most important eigenvalues have been retained, where %p was determined as the smallest integer for which (%d__1_+%d__2_+...%d__%p_)/(%d__1_+%d__2_+ ... + %d__%n_) >= %%varianceFractionToKeep%.") NORMAL (U"The resulting sound samples of the whitened sound, %w__%ij_, are then calculated from the samples of the " "original sound, %s__%kj_, as %w__%ij_ = \\Si__%k_ W__%ik_ %s__%kj_, where 1 \\<_ %i \\<_%p, 1 \\<_ %j \\<_ numberOfSamples and 1 \\<_ %k \\<_ %n.") MAN_END MAN_BEGIN (U"blind source separation", U"djmw", 20120907) INTRO (U"Blind source separation (BSS) is a technique for estimating individual source components from their mixtures " "at multiple sensors. It is called %blind because we don't use any other information besides the mixtures. ") NORMAL (U"For example, imagine a room with a number of persons present and a number of microphones for recording. " "When one or more persons are speaking at the same time, each microphone registers a different %mixture of individual speaker's audio signals. It is the task of BSS to untangle these mixtures into their sources, i.e. the individual speaker's audio signals. " "In general, this is a difficult problem because of several complicating factors. ") LIST_ITEM (U"\\bu Different locations of speakers and microphones in the room: the individual speaker's audio signals do not reach all microphones at the same time. ") LIST_ITEM (U"\\bu Room acoustics: the signal that reaches a microphone is composed of the signal that %directly travels to the microphone and parts that come from room reverberations and echos. ") LIST_ITEM (U"\\bu Varying distances to microphones: one or more speakers might be moving. This makes the mixing time dependent.") NORMAL (U"If the number of sensors is %larger than the number of sources we speak of an %overdetermined problem. If the number of sensors and the number of sources are %equal we speak of a %determined problem. The more difficult problem is the %underdetermined one where the number of sensors is %less than the number of sources.") ENTRY (U"Typology of mixtures") NORMAL (U"In general two different types of mixtures are considered in the literature: %%instantaneous " "mixtures% and %%convolutive mixtures%. ") TAG (U"%%Instantaneous mixtures%") DEFINITION (U"where the mixing is instantaneous, corresponds to the model #Y=#A\\.c#X. In this model #Y is a matrix with the recorded microphone sounds, #A is a so-called " "%%mixing matrix% and #X is a matrix with the independent source signals. " "Essentially the model says that the signal that each microphone records is a (possibly different) linear combination of the %same source signals. " "If we would know the mixing matrix #A we could easily solve the model above for #X by standard means. " "However, in general we don't know #A and #X and there are an infinite number of possible decompositions for #Y. The problem is however solvable by making some (mild) assumptions about #A and #X. ") TAG (U"%%Convolutive mixtures%") DEFINITION (U"are mixtures where the mixing is of convolutive nature, i.e. the model is ") FORMULA (U"%%y__i_ (n)% = \\Si__%j_^^%d^\\Si__%\\ta_^^M__%ij_-1^ %%h__ij_(\\ta)x__j_(n-\\ta) + N__i_(n)%, for %i=1..m.") DEFINITION (U"Here %%y__i_ (n) is the %n-th sample of the %i-th microphone signal, %m is the number of microphones, %%h__ij_(\\ta)% is the multi-input multi-output linear filter with the source-microphone impulse responses that characterize the propagation of the sound in the room and %%N__i_% is a noise source. This model is typically much harder to solve than the previous one because of the %%h__ij_(\\ta)% filter term that can have thousands of coefficients. For example, the typical @@reverberation time@ of a room is approximately 0.3 s which corresponds to 2400 samples, i.e. filter coefficients, for an 8 kHz sampled sound.") ENTRY (U"Solving the blind source separation for instantaneous mixtures") NORMAL (U"Various techniques exist for solving the blind source separation problem for %instantaneous mixtures. Very popular ones make make use of second order statistics (SOS) by trying to " "simultaneously diagonalize a large number of cross-correlation matrices. Other techniques like independent component analysis use higher order statistics (HOS) to find the independent components, i.e. the sources.") NORMAL (U"Given the decomposition problem #Y=#A\\.c#X, we can see that the solution is determined " "only upto a permutation and a scaling of the components. This is called the %%indeterminancy " "problem% of BSS. This can be seen as follows: given a permutation matrix #P, i.e. a matrix which " "contains only zeros except for one 1 in every row and column, and a diagonal scaling matrix #D, any " "scaling and permutation of the independent components #X__%n_=(#D\\.c#P)\\.c#X can be compensated " "by the reversed scaling of the mixing matrix #A__%n_=#A\\.c(#D\\.c#P)^^-1^ because #A\\.c(#D\\.c#P)^^-1^\\.c(#D\\.c#P)\\.c#X = #A\\.c#X = #Y. ") ENTRY (U"Solving the blind source separation for convolutive mixtures") NORMAL (U"Solutions for %convolutive mixture problems are much harder to achieve. " "One normally starts by transforming the problem to the frequency domain where the " "convolution is turned into a multiplication. The problem then translates into a separate " "%%instantaneous% mixing problem for %%each% frequency in the frequency domain. It is here that " "the indeterminacy problem hits us because it is not clear beforehand how to combine the " "independent components of each frequency bin.") MAN_END MAN_BEGIN (U"reverberation time", U"djmw", 20110107) NORMAL (U"Reverberation is the persistence of sound in a room after the sound source has silenced. ") NORMAL (U"The %%reverberation time% is normally defined as the time required for the persistence of a direct sound " "to decay by 60 dB after the direct sound has silenced. Sometimes this dB level is indicated with a subscript " "and the reverberation time is given by the symbol %T__60_. " "The reverberation time depends mainly on a room's volume and area and on the absorption at the walls. Generally absorption is frequency dependent and therefore the reverberation time of a room varies with frequency. ") MAN_END MAN_BEGIN (U"Vollgraf & Obermayer (2006)", U"djmw", 20110105) NORMAL (U"Roland Vollgraf & Klaus Obermayer (2006): \"Quadratic optimization for simultaneous matrix " "diagonalization.\" %%IEEE Transactions On Signal Processing% #54: 3270\\--3278.") MAN_END MAN_BEGIN (U"Ziehe et al. (2004)", U"djmw", 20110105) NORMAL (U"Andreas Ziehe, Pavel Laskov, Guido Nolte & Klaus-Robert M\\u\"ller (2004): \"A fast algorithm for joint " "diagonalization with non-orthogonal transformations and its application to blind source separation\", " "%%Journal of Machine Learning Research% #5: 777\\--800.") MAN_END } /* End of file manual_BSS.cpp */ praat-6.0.04/dwtools/manual_DataModeler.cpp000066400000000000000000000066161261542461700206460ustar00rootroot00000000000000/* manual_DataModeler.cpp * * Copyright (C) 2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20101009 Initial version */ #include "ManPagesM.h" void manual_DataModeler (ManPages me); void manual_DataModeler (ManPages me) { MAN_BEGIN (U"FormantModeler: Get residual sum of squares...", U"djmw", 20140421) INTRO (U"Get the residual sum of squares for a formant in the selected FormantModeler.") NORMAL (U"The residual sum of squares, RSS, is defined as follows") FORMULA (U"RSS = \\su__i=1_^^n^ (%f__%i_ - %F__%i_)^^2^,") NORMAL (U"where %f__%i_ is the frequency value of the %i-ith data point, %F__%i_ is the frequency at the i-data point as estimated by the model and %n is the number of data points.") MAN_END MAN_BEGIN (U"Formants: Extract smoothest part (constrained)...", U"djmw", 20140424) NORMAL (U"Extracts the best matching part from the slected @@formant|Formant@s.") ENTRY (U"Settings") TAG (U"##Minimum F1 (Hz)") DEFINITION (U"suppresses models whose average first formant frequency, %f1, is below %%minimumF1% by a factor sqrt (%minimumF1 - %f1 + 1). You can use this constraint to disfavour models with a low average first formant. Sometimes due to the generally high frequency of the /a/ a lower harmonic of the fundamental frequency is taken as a candidate for the first formant. You can suppress these models with this constraint.") TAG (U"##Maximum F1 (Hz)") DEFINITION (U"suppresses models whose average first formant frequency, %f1, is above %%maximumF1% by a factor sqrt (%f1 - %%maximumF1% + 1).You can use this constraint to disfavour models in which the first formant is missing. ") TAG (U"##Minimum F2 (Hz)") DEFINITION (U"suppresses models whose average second formant frequency, %f2, is below %%minimumF2% by a factor sqrt (%minimumF2 - %f2 + 1). This constraint might be used for high front vowels that normally have a large distance between the first and second formant. ") TAG (U"##Maximum F2 (Hz)") DEFINITION (U"suppresses models whose average second formant frequency, %f2, is above %%maximumF2% by a factor sqrt (%f2 - %%maximumF2% + 1). This factor is sometimes necessary to suppress models for high back vowels where the second formant is \"missing\", i.e. where the third formant is playing the role of the second. ") TAG (U"##Minimum F3 (Hz)") DEFINITION (U"suppress models whose average third formant frequency, %%f3%, is below %%minimumF3% by a factor sqrt (%%minimumF3% - %%f3% + 1). This constraint might sometimes be usefull to suppress low lying third formants that can occur for /a/-like vowels.") MAN_END MAN_BEGIN (U"Buse (1973)", U"djmw", 20140328) NORMAL (U"A. Buse (1973): \"Goodness of fit in generalized least squares estimation.\", %%The American Statistician% #27: 106\\--108.") MAN_END } /* End of file manual_HMM.cpp */ praat-6.0.04/dwtools/manual_HMM.cpp000066400000000000000000000644621261542461700171110ustar00rootroot00000000000000/* manual_HMM.cpp * * Copyright (C) 2011-2014, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20101009 Initial version */ #include "ManPagesM.h" void manual_HMM (ManPages me); void manual_HMM (ManPages me) { MAN_BEGIN (U"expectation-maximization", U"djmw", 20111130) NORMAL (U"Expectation-maximization (EM) is an iterative method used to find maximum " "likelihood estimates of parameters in probabilistic models, where the model depends on " "unobserved, also called %%latent%, variables. EM alternates between performing an expectation (E) step, " "which computes an expectation of the likelihood by including the latent variables as if they " "were observed, and a maximization (M) step, which computes the maximum likelihood " "estimates of the parameters by maximizing the expected likelihood found in the E step. The " "parameters found on the M step are then used to start another E step, and the process is " "repeated until some criterion is satisfied. EM is frequently used for data clustering like for example in " "@@TableOfReal: To GaussianMixture...|Gaussian mixtures@ or in the @@HMM & HMMObservationSequences: Learn...|Baum-Welch training@ of a Hidden Markov Model.") MAN_END MAN_BEGIN (U"GaussianMixture", U"djmw", 20101026) INTRO (U"A Gaussian mixture is a probability density function (p.d.f.). It is a combination of several Gaussian densities.") NORMAL (U"The GaussianMixture's p.d.f. is defined as the weighted sum of %K multivariate Gaussian p.d.f's:") FORMULA (U"pdf(x) = \\Si__%%i%=1_^^%K^ p__%i_ %N(%x;\\mu__%i_,\\Si__%i_),") NORMAL (U"where each %N(%x;\\mu__%i_,\\Si__%i_) is a multivariate p.d.f. with mean \\mu__%i_ and covariance matrix \\Si__%i_. The coefficients %p__%i_ sum to 1. ") NORMAL (U"For an introduction to Gaussian mixtures see for example @@Bishop (2006)@.") MAN_END MAN_BEGIN (U"GaussianMixture: Draw concentration ellipses...", U"djmw", 20101101) INTRO (U"Draws the concentration ellipse for each component in the @@GaussianMixture@. ") NORMAL (U"The principal component plane will be determined from @@GaussianMixture: To PCA@.") NORMAL (U"You might also use another @PCA and to combine it with a GaussianMixture for drawing (@@GaussianMixture & PCA: Draw concentration ellipses...@).") ENTRY (U"Settings") TAG (U"##Number of sigmas") DEFINITION (U"determines the @@concentration ellipse|data coverage@.") TAG (U"##Principal component plane") DEFINITION (U"determines whether the principal component plane is used or not for drawing.") MAN_END MAN_BEGIN (U"GaussianMixture: Get probability at position", U"djmw",20101103) INTRO (U"Evaluate the pdf of the @@GaussianMixture@ at the given position.") MAN_END MAN_BEGIN (U"GaussianMixture & PCA: Draw concentration ellipses...", U"djmw", 20101101) INTRO (U"Draws the concentration ellipse for each component in the @@GaussianMixture@ in the plane spanned by the selected @PCA.") ENTRY (U"Settings") TAG (U"##Number of sigmas") DEFINITION (U"determines the @@concentration ellipse|data coverage@.") MAN_END MAN_BEGIN (U"GaussianMixture: Draw marginal pdf...", U"djmw", 20101122) INTRO (U"A command to draw the marginal p.d.f. (probability density function) of the selected @GaussianMixture.") NORMAL (U"A marginal distribution is the projection of the (multivariate) p.d.f. on one dimension or direction. " "This direction may also be externally defined by selecting a @PCA and a GaussianMixture together.") MAN_END MAN_BEGIN (U"GaussianMixture: Split component...", U"djmw", 20101122) INTRO (U"Splits one component of the selected @GaussianMixture into two components.") NORMAL (U"The selected component is split based on a @PCA analysis of its covariance matrix. The new means are situated " "around the old components mean, 1\\si apart in the first principal components direction, and the new covariances are " "constructed with information from the old covariance matrix. ") NORMAL (U"The details of the algorith are described in @@Zhang et al. (2003)@.") MAN_END MAN_BEGIN (U"GaussianMixture: To PCA", U"djmw", 20101030) INTRO (U"Creates a @PCA from the selected @GaussianMixture.") NORMAL (U"The PCA is calculated from the @@GaussianMixture: To Covariance (total)|total covariance matrix@ of the GaussianMixture.") MAN_END MAN_BEGIN (U"GaussianMixture & PCA: To Matrix (density)...", U"djmw", 20101101) INTRO (U"Represent the @@GaussianMixture@ p.d.f. on the plane spanned by @@PCA@. This makes it possible to draw " "the p.d.f. as grey values with one of the special @@Matrix@ image drawing methods.") NORMAL (U"For each cell in the matrix of dimension %%numberOfRows% \\xx %%numberOfColumns%, the p.d.f. will be evaluated.") MAN_END MAN_BEGIN (U"GaussianMixture: To Covariance (between)", U"djmw", 20101030) INTRO (U"The covariance between the centers of the components of the @@GaussianMixture@ is calculated; " "each center is weighted according to its mixing probability.") MAN_END MAN_BEGIN (U"GaussianMixture: To Covariance (within)", U"djmw", 20101120) INTRO (U"The covariances of the components of the @@GaussianMixture@ are pooled.") MAN_END MAN_BEGIN (U"GaussianMixture: To Covariance (total)", U"djmw", 20101030) INTRO (U"The sum of the @@GaussianMixture: To Covariance (within)|within@ and @@GaussianMixture: To Covariance (between)|between@ covariances of the @@GaussianMixture@ is calculated.") MAN_END MAN_BEGIN (U"GaussianMixture: To TableOfReal (random sampling)...", U"djmw", 20101030) INTRO (U"The selected @@GaussianMixture@ is used as a generator of data.") ENTRY (U"Setting") TAG (U"##Number of data points") DEFINITION (U"determines how many random data point have to be generated.") ENTRY (U"Algorithm") NORMAL (U"For each data point to be generated:") NORMAL (U"1. A random number decides to which component in the mixture the data point will belong.") NORMAL (U"2. According to the procedure described in @@Covariance: To TableOfReal (random sampling)...@, one " "data point will be generated.") MAN_END MAN_BEGIN (U"TableOfReal: To GaussianMixture...", U"djmw", 20150930) INTRO (U"Creates a @@GaussianMixture@ from the selected @@TableOfReal@ by an @@expectation-maximization|" "expectation-maximization@ procedure.") ENTRY (U"Settings") TAG (U"##Number of components") DEFINITION (U"defines the number of Gaussians in the mixture.") TAG (U"##Tolerance of minimizer") DEFINITION (U"defines when to stop optimizing. If the relative difference between the likelihoods at two successive " "iteration steps differs by less then the tolerance we stop, i.e. when |(%L(%i-1)-%L(%i))/%L(%i)| < %%tolerance%. ") TAG (U"##Maximum number of iterations") DEFINITION (U"defines another stopping criterion. The EM iteration will stop when either the tolerance " "is reached or the maximum number of iterations. If zero is chosen, no iteration will be performed and the " "GaussianMixture will be initialized with the initial guess.") TAG (U"##Stability coefficient lambda") DEFINITION (U"defines the fraction of the total covariance that will be added to the each of the mixture " "covariance matrices during the EM iteration. This may prevent one or more of these matrices to become singular.") TAG (U"##Covariance matrices are") DEFINITION (U"defines whether the complete covariance matrices in the mixture have to be calculated or only the diagonal.") TAG (U"##Criterion based on") DEFINITION (U"defines how the @@GaussianMixture & TableOfReal: Get likelihood value...|likelihood of the data given the model is calculated@.") ENTRY (U"Expectation\\--Maximization Algorithm") NORMAL (U"The Expectation\\--Maximization (EM) algorithm is an iterative procedure to maximize the likelihood of the data given a model. For a " "GaussianMixture, the parameters in the model are the centers and the covariances of all components in the mixture " "and their mixing probabilities.") NORMAL (U"The number of parameters depends on the number of components in the mixture and the dimension of the data. " "For a full covariance matrix we have to find %dimension%(%dimension%+1)/2 matrix elements and another " " %dimension vector elements for its center. This makes the total number of parameters that have to be estimated " "for a mixture with ##Number of components# components equal to " "%numberOfComponents \\.c %dimension%(%dimension%+3)/2 + %numberOfComponents.") NORMAL (U"For diagonal covariance matrices the number of parameters reduces considerably.") NORMAL (U"The EM iteration has to start with a sensible initial guess for all the parameters. For the initial guess, " "we derive our centers from positions on the 1-\\si ellipse in the plane spanned by the first two principal " "components. We then make all covariance matrices equal to a scaled down version of the total covariance matrix " "where the scaling factor depends on the number of components and the quotient of the between and within variance. " "Initialy all mixing probabilities will be chosen equal.") NORMAL (U"How to proceed from the initial guess with the EM to find the optimal values for all the parameters " "in the Gaussian mixture is explained in great detail by @@Bishop (2006)@.") MAN_END #define GaussianMixture_OPTION_MENU_CRITERIA \ OPTIONMENU (U"Criterion based on", 1) \ OPTION (U"Maximum likelihood") \ OPTION (U"Minimum message length") \ OPTION (U"Bayes information") \ OPTION (U"Akaike information") \ OPTION (U"Akaike corrected") \ OPTION (U"Complete-data ML") MAN_BEGIN (U"GaussianMixture & TableOfReal: Get likelihood value...", U"djmw", 20101125) INTRO (U"Calculates how well the @GaussianMixture model fits the data according to a criterion.") ENTRY (U"Settings") TAG (U"##Maximum likelihood") FORMULA (U"ML = \\Si__%i=1..%n_ log (\\Si__%m=1..%k_ \\al__%k_ %p__%%ik%_)") TAG (U"##Minimum message length") FORMULA (U"DL = ML - 0.5(N\\.c\\Si__%m=1..%k_ log(%n\\al__%m_/12) -%k\\.clog(%n/12) -%k(%N+1))") TAG (U"##Bayes information") FORMULA (U"BIC = 2\\.cML - k\\.cN\\.clog(n)") TAG (U"##Akaike information") FORMULA (U"AIC = 2(ML - k\\.cN) ") TAG (U"##Akaike corrected") FORMULA (U"AICc = 2(ML - k\\.cN\\.cn/(n-k\\.cN-1))") TAG (U"##Complete-data ML") FORMULA (U"\\Si__%i=1..%n_\\Si__%m=1..%k_ \\ga__%%im%_ log (\\ga__%%im%_)") NORMAL (U"In the formulas above %n is the number of data points, %k is the number of mixture components, %N is the " "number of parameters in one component, i.e. %d + %d(%d+1)/2 for a full covariance matrix of " "dimension %d with means. The \\al__%k_ are the mixing probabilities, the %p__%%ik%_ are the probabilities for the %i-th data vector in the %k-th component. The \\ga__%%ik%_ are defined as ") FORMULA (U"\\ga__%%im%_= \\al__%m_\\.c%p__%%im%_ /(\\Si__%j=1..%k_ \\al__%j_\\.c%p__%%ij%_).") MAN_END MAN_BEGIN (U"GaussianMixture & TableOfReal: Improve likelihood...", U"djmw", 20111130) INTRO (U"Try to improve the likelihood of the parameters in the @@GaussianMixture@ by an @@expectation-maximization@ algorithm.") ENTRY (U"Settings & EM Algorithm") NORMAL (U"As decribed in @@TableOfReal: To GaussianMixture...@.") MAN_END MAN_BEGIN (U"GaussianMixture & TableOfReal: To Correlation (columns)", U"djmw", 20101111) INTRO (U"Create a @Correlation matrix from the selected @TableOfReal and the @GaussianMixture.") NORMAL (U"We start by calculating the ClassificationTable @@GaussianMixture & TableOfReal: To ClassificationTable|from " "the data and the GaussianMixture@.") NORMAL (U"Nex we calculate correlations between the %%columns% of the ClassificationTable: cell [%i,%j] of the " "correlation matrix will then contain the value:") FORMULA (U"%p[%i] \\.c %p[%j] / (||%p[%i]||\\.c ||%p[%j]||), ") NORMAL (U"where %p[%i] is the data in the %i-th column of the classification table and ||%p[%i]|| is its Euclidean norm. " "The index %i runs from 1 to the number of components in the mixture.") NORMAL (U"Because all the elements in a column are positive numbers, i.e. probabilities, all correlations will be positive numbers too.") MAN_END MAN_BEGIN (U"GaussianMixture & TableOfReal: To ClassificationTable", U"djmw", 20101122) INTRO (U"Create a @ClassificationTable from the selected @TableOfReal and the @GaussianMixture.") NORMAL (U"The classification table is a matrix with the same number of rows as the selected #TableOfReal " "object. The number of columns equals the number of components in the mixture. " "Cell [%i,%j] of the classification table contains the probability " "that the data in row %i of the TableOfReal belongs to component %j of the mixture.") MAN_END MAN_BEGIN (U"GaussianMixture & TableOfReal: To GaussianMixture (CEMM)...", U"djmw", 20101120) INTRO (U"Find the best @@GaussianMixture@ from the data according to a iterative component-wise optimization algorithm by which components may be deleted.") ENTRY (U"Settings") TAG (U"##Minimum number of components") DEFINITION (U"defines the minimum number of components that have to survive the minimization process. If a value of zero is chosen all components will survive and no deletions will take place.") TAG (U"##Tolerance of minimizer") DEFINITION (U"defines when to stop optimizing. If the relative difference between the likelihoods at two successive " "iteration steps differs by less then the tolerance we stop, i.e. when |(%L(%i-1)-%L(%i))/%L(%i)| < %%tolerance%. ") TAG (U"##Maximum number of iterations") DEFINITION (U"defines another stop criterion. Iteration stops whenever the number of iterations reaches this value.") TAG (U"##Stability coefficient lambda") DEFINITION (U"defines the fraction of the totat covariance that is added to the covariance of each component to " "prevent these matrices from becoming singular.") TAG (U"##Criterion based on") DEFINITION (U"defines whether the function to be optimized is the log likelihood or the related miminum description length.") ENTRY (U"Algorithm") NORMAL (U"The component-wise optimization algorithm is described in @@Figueiredo & Jain (2002)@ where the function to be optimized " "is the minimum description length defined as:") FORMULA (U"%L(\\te,%Y) = %N/2 \\Si__%m=1_^^%k^ ln(%n\\al__%k_/12) + %k/2 ln(%n/12) + %k(%N+1)/2 - ln %p(%Y|\\te),") NORMAL (U"where %k is the number of components, %N is the number of parameters of one component, " "i.e. %d+%d(%d+1)/2 for a full covariance matrix of dimension %d with means and %d+%d for a diagonal " "matrix with means; %n is the number of data vectors. The term ln %p(%Y|\\te) is the log likelihood of the data " "given the model.") NORMAL (U"For the optimization we either optimize the complete function %L(\\te,%Y) or only the likelihood ln %p(%Y|\\te) term.") MAN_END MAN_BEGIN (U"GaussianMixture & TableOfReal: To TableOfReal (BHEP normality tests)...", U"djmw", 20101113) INTRO (U"Tests the data in the @TableOfReal that belong to the components of the @GaussianMixture for normality " "according to an adapted version of the @@BHEP multivariate normality test@.") ENTRY (U"Setting") TAG (U"##Beta") DEFINITION (U"determines the smoothing parameter of the data. If %beta equals zero the smoothing is determined " "automatically for each component of the mixture separately as: ") FORMULA (U"%beta = 1/(\\Vr2) (2%p+1)^^1/(%p+4)^ n^^1/(%p+4)^,") NORMAL (U"where %n is the effective number of elements in the component and %p the dimension of the data.") MAN_END MAN_BEGIN (U"TableOfReal: To GaussianMixture (row labels)...", U"djmw", 20101101) INTRO (U"Creates a @@GaussianMixture@ from the selected @TableOfReal. The number of mixture components is determined by the number of different row labels.") ENTRY (U"Setting") TAG (U"##Covariance matrices are") DEFINITION (U"defines whether the complete covariance matrices in the mixture have to be calculated or only the diagonal.") MAN_END MAN_BEGIN (U"HMMObservationSequence", U"djmw", 20140117) INTRO (U"An HMMObservationSequence models a sequence of observations. The observation sequence can be generated " "by the @HMM or it can be used to train a model.") MAN_END MAN_BEGIN (U"HMMStateSequence", U"djmw", 20101010) INTRO (U"An HMMStateSequence models the sequence of states that an @HMM has traversed.") MAN_END MAN_BEGIN (U"HMM", U"djmw", 20130410) INTRO (U"A HMM is a Hidden Markov Model. Markov models are often used to model observation sequences. " "The fundamental assumption in a markov model is that the probability of an observation (event) can only " "depend on the previous observation. " "A HMM can be visualised as a graph with a number of %%states%. If states are connected they have line connecting them. The following picture shows a HMM with two states, labeled \"Rainy\" and \"Sunny\". Each state can emit three symbols (these are not visible in the graph). ") SCRIPT (5, 5, U"Create simple HMM: \"wheather\", \"no\", \"Rainy Sunny\", \"Walk Shop Clean\"\n" "Draw: \"no\"\n" "Remove\n") INTRO (U"For an introduction into HMM's see @@Rabiner (1989)@.") MAN_END MAN_BEGIN (U"HMM: Create simple HMM...", U"djmw", 20101009) INTRO (U"Creates a @@HMM|Hidden Markov Model@ from given states and observation symbols.") ENTRY (U"Settings") TAG (U"##Name") DEFINITION (U"determines the name (for the list of objects).") TAG (U"##States") DEFINITION (U"determines the number of and the names of the states.") TAG (U"##Symbols") DEFINITION (U"determines the number and the names of the observation symbols.") NORMAL (U"You can define a (not hidden) Markov model by leaving either the States or the Symbols field empty.") NORMAL (U"The model is initialised with equal probabilities for all the transitions and emissions.") MAN_END MAN_BEGIN (U"HMM: Extract transition probabilities", U"djmw", 20101020) INTRO (U"Extract the transition probabilities of the selected @@HMM@ as a @@TableOfReal@.") NORMAL (U"The row label shows the %%from% state and the column label the %%to% state, therefore the cell element " "in row %i and column %j shows the probability of making a transition from state %i to state %j.") MAN_END MAN_BEGIN (U"HMM: Extract emission probabilities", U"djmw", 20101020) INTRO (U"Extract the emission probabilities of the selected @@HMM@ as a @@TableOfReal@.") NORMAL (U"The row label shows the %%from% state and the column label the %%to% symbol, therefore the cell element " "in row %i and column %j shows the probability of emitting symbol %j from state %i.") MAN_END MAN_BEGIN (U"HMM & HMM: Get cross-entropy...", U"djmw", 20101017) INTRO (U"Calculates the cross-entropy between the two selected @@HMM@ models based on observation sequences.") ENTRY (U"Settings") TAG (U"##Observation length") DEFINITION (U"defines the number of observations that have to generated.") TAG (U"##Symmetric") DEFINITION (U"defines whether the symmetric formula is used in the calculation.") ENTRY (U"Algorithm") NORMAL (U"The cross-entropy is a measure of the distance between two models \\la__1_ and \\la__2_. It is defined as") FORMULA (U"%D(\\la__1_,\\la__2_) = 1/%N (log %p(%O__2_|\\la__1_) - log %p(%O__2_|\\la__2_)),") NORMAL (U"where %O__2_ is an observation sequence of length %N generated by model \\la__2_.") NORMAL (U"The symmetrized version is:") FORMULA (U"%D__%s_(\\la__1_,\\la__2_) = (%D(\\la__1_,\\la__2_) + %D(\\la__2_,\\la__1_))/2.") MAN_END MAN_BEGIN (U"HMM & HMMObservationSequence: Get cross-entropy", U"djmw", 20101017) INTRO (U"Calculates the cross-entropy between the selected @@HMM@ model and the @@HMMObservationSequence@.") NORMAL (U"The cross-entropy is a useful upper bound for the entropy of a model. An approximation to the cross-entropy for a model on a observation sequence %O of length %N is: ") FORMULA (U"%H(%O) = -1/%N log %p(%O),") NORMAL (U"where %p(%O) is the probability of the observation sequence given the model.") MAN_END MAN_BEGIN (U"HMM & HMM & HMMObservationSequence: Get cross-entropy", U"djmw", 20101017) INTRO (U"Get the (symmetric) cross-entropy for the two selected @HMM models and an observation sequence.") NORMAL (U"See @@HMM & HMM: Get cross-entropy...@.") MAN_END MAN_BEGIN (U"HMM: To HMMObservationSequence...", U"djmw", 20101010) INTRO (U"Use the selected @HMM as a generator for an observation sequence.") ENTRY (U"Settings") TAG (U"##Start state") DEFINITION (U"defines the state in which the HMM starts. If a zero is given the start state is randomly chosen according to the start probabilities.") TAG (U"##Number of observations") DEFINITION (U"defines the number of observations to generate. For models of %%finite% duration such as left-to-right models, the HMM generator may stop before this number is reached.") MAN_END MAN_BEGIN (U"HMM: Get transition probability...", U"djmw", 20101010) INTRO (U"For the selected @HMM get the probability to make a transition from one state to the other.") MAN_END MAN_BEGIN (U"HMM: Get emission probability...", U"djmw", 20101010) INTRO (U"For the selected @HMM get the probability that in a given state a particular symbol will be emitted.") MAN_END MAN_BEGIN (U"HMM: Get start probability...", U"djmw", 20101010) INTRO (U"For the selected @HMM get the probabilities that the model will start in a particular state.") MAN_END MAN_BEGIN (U"HMM: Get p (time, state)...", U"djmw", 20101010) INTRO (U"For the selected @HMM get the probability that after a given number of time steps the HMM will be in " "a particular state.") MAN_END MAN_BEGIN (U"HMM: Get p (time, state, symbol)...", U"djmw", 20101010) INTRO (U"For the selected @HMM get the probability that after a given number of time steps the HMM will be in " "a particular state and emits a certain symbol.") NORMAL (U"This probability is the product of the %%probability being in particular state at that time (index)% and the %%probability of emitting a certain symbol in that state%.") MAN_END MAN_BEGIN (U"HMM: Get probability staying in state...", U"djmw", 20101010) INTRO (U"For the selected @HMM get the probability that it stays exactly the given number of times in that state.") NORMAL (U"This probability is %\\al__%%ii%_^^numberOfTimes-1^(1 - %\\al__%%ii%_),\n" "where \\al__%%ii%_ is the probability of staying in state %i.") MAN_END MAN_BEGIN (U"HMM: Get expected duration in state...", U"djmw", 20101010) INTRO (U"For the selected @HMM get the number of time units that the system is expected to stay in that state.") MAN_END MAN_BEGIN (U"HMM & HMMStateSequence: Get probability", U"djmw", 20101010) INTRO (U"Get the natural logarithm of the probability that the selected @@HMMStateSequence|state sequence@ was generated by the selected @HMM.") MAN_END MAN_BEGIN (U"HMM & HMMObservationSequence: Get probability", U"djmw", 20101010) INTRO (U"Get the natural logarithm of the probability that the selected @@HMMObservationSequence|state sequence@ was generated by the selected @HMM.") ENTRY (U"Algorithm") NORMAL (U"Viterbi") MAN_END MAN_BEGIN (U"HMM: Set transition probabilities...", U"djmw", 20101010) INTRO (U"Sets the probabilities for making a transition from one state to all other states.") ENTRY (U"Settings") TAG (U"##Probabilities") DEFINITION (U"the list of transition probabilities from the given state. " "The values given will be scaled as probabilities. A zero is used to mark a transition that will never occur. ") ENTRY (U"Examples") NORMAL (U"For a three state model the input \"1 3 7\" will result in the same probabilities as the input \"0.1 0.3 0.7\".") MAN_END MAN_BEGIN (U"HMM: Set emission probabilities...", U"djmw", 20101010) INTRO (U"Sets the probabilities for emitting the symbols from the state.") NORMAL (U"The values given will be scaled as probabilities. ") ENTRY (U"Examples") NORMAL (U"For an HMM with four symbols the input \"1 3 3 3\" will result in the same probabilities as the input \"0.1 0.3 0.3 0.3\".") MAN_END MAN_BEGIN (U"HMM: Set start probabilities...", U"djmw", 20101010) INTRO (U"Sets the probabilities that the model starts in the particular states.") NORMAL (U"The values given will be scaled as probabilities. ") MAN_END MAN_BEGIN (U"HMM & HMMObservationSequence: To TableOfReal (bigrams)...", U"djmw", 20101019) INTRO (U"Get a table with bigrams and marginals form the selected @HMMObservationSequence and the @HMM.") NORMAL (U"The entry at row %i and column %j shows how often the %j-th symbol follows the %i-th symbol in the observation sequence.") ENTRY (U"Remark") NORMAL (U"The row and colum marginals for the first and the last element in the obsevation sequence will not be equal because there is no transition to the first and no transition from the last one.") MAN_END MAN_BEGIN (U"HMMObservationSequence: To TableOfReal (bigrams)...", U"djmw", 20101019) INTRO (U"Get a table with bigrams form the selected @HMMObservationSequence.") NORMAL (U"See also @@HMM & HMMObservationSequence: To TableOfReal (bigrams)...@.") MAN_END MAN_BEGIN (U"HMM & HMMObservationSequences: Learn...", U"djmw", 20111130) INTRO (U"Train the transition and emission probabilities of the @HMM from the observations.") ENTRY (U"Algorithm") NORMAL (U"The Baum-Welch @@expectation-maximization@ procedure. It uses the forward and backward procedures to (re)estimate the parameters until convergence is reached.") MAN_END MAN_BEGIN (U"Bishop (2006)", U"djmw", 20101026) NORMAL (U"C.M. Bishop (2006): %%Pattern recognition and machine learning%. Springer.") MAN_END MAN_BEGIN (U"Figueiredo & Jain (2002)", U"djmw", 20101229) NORMAL (U"Mario A.T. Figueiredo & Anil K. Jain (2002): \"Unsupervised learning of finite mixture models.\" " "%%IEEE Transactions on Pattern Analysis and Machine Intelligence% ##24(3)#: 381\\--396.") MAN_END MAN_BEGIN (U"Rabiner (1989)", U"djmw", 20101017) NORMAL (U"L.R. Rabiner (1989): \"A tutorial on Hidden Markov Models and selected applications in speech recognition.\" %%Proceedings of the IEEE% #77: 257\\--286.") MAN_END MAN_BEGIN (U"Tenreiro (2009)", U"djmw", 20101113) NORMAL (U"C. Tenreiro (2009): \"On the choice of the smoothing parameter for the BHEP goodness-of-fit test.\" " "%%Computational Statistics and Data Analysis% #53: 1038\\--1053.") MAN_END MAN_BEGIN (U"Zhang et al. (2003)", U"djmw", 20101122) NORMAL (U"Zhihua Zhang & Chibiao Chen & Jian Sun & Kap Luk Chan (2003): \"EM algorithms for Gaussian mixtures with " "split-and-merge operation.\" %%Pattern Recognition% #36: 1973\\--1983.") MAN_END } /* End of file manual_HMM.cpp */ praat-6.0.04/dwtools/manual_KlattGrid.cpp000066400000000000000000000314551261542461700203510ustar00rootroot00000000000000/* manual_KlattGrid.cpp * * Copyright (C) 2009-2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ManPagesM.h" void manual_KlattGrid (ManPages me); void manual_KlattGrid (ManPages me) { MAN_BEGIN (U"KlattGrid", U"djmw", 20140117) INTRO (U"A KlattGrid represents the source-filter model as a function of time. It consists of a number of tiers that model aspects of the source and the filter, and the interaction between source and filter. The KlattGrid implements a superset of the speech synthesizer described in figure 14 in the @@Klatt & Klatt (1990)@ article.") NORMAL (U"The following drawing represents a cascade synthesizer with six oral formants, one nasal formant, " "one nasal antiformant, one tracheal formant, one tracheal antiformant and six frication formants. ") SCRIPT (7.0, 6.5, U"Create KlattGrid: \"kg\", 0, 1, 6, 1, 1, 6, 1, 1, 1\n" "Draw synthesizer: \"Cascade\"\n" "Remove\n") NORMAL (U"In the next picture a parallel synthesizer branch is used instead of the cascade one.") SCRIPT (7.0, 6.5, U"Create KlattGrid: \"kg\", 0, 1, 6, 1, 1, 6, 1, 1, 1\n" "Draw synthesizer... Parallel\n" "Remove\n") NORMAL (U"All parameters in the synthesizer are represented by separate tiers.") ENTRY (U"The source") NORMAL (U"The source is modelled by the following tiers:") TAG (U"##Pitch") DEFINITION (U"models fundamental frequency (in Hertz).") TAG (U"##Flutter") DEFINITION (U"models a kind of \"random\" variation of the pitch (with a number between zero and one). ") TAG (U"##Voicing amplitude") DEFINITION (U"models the maximum amplitude of the glottal flow (in dB SPL).") TAG (U"##Open phase") DEFINITION (U"models the open phase of the glottis (with a number between zero and one). If the tier is empty a default of 0.7 " "will be used.") TAG (U"##Power1#, ##Power2#") DEFINITION (U"model the form of the glottal flow function flow(%t)=%t^^%%power1%^-%t^^%%power2%^ for 0\\<_ t \\<_ 1. " "To make glottal closure possible, %power2 has to be larger than %power1. If the power1 tier is empty, a default " "value of 3 will be used. If the power2 tier is empty, a default of 4 will be used.") TAG (U"##Collision phase") DEFINITION (U"models the last part of the flow function with an exponential decay function instead of a polynomial one. " "More information about #Power1, #Power2, ##Open phase# and ##Collision phase# can be found in the @@PointProcess: To Sound (phonation)...@ manual.") TAG (U"##Spectral tilt") DEFINITION (U"models the extra number of dB the voicing spectrum should be down at 3000 Hertz.") TAG (U"##Aspiration amplitude") DEFINITION (U"models the (maximum) amplitude of the noise generated at the glottis (in dB SPL). ") TAG (U"##Breathiness amplitude") DEFINITION (U"models the maximum breathiness noise amplitude during the open phase of the glottis (in dB SPL). " "The amplitude of the breathiness noise is modulated by the glottal flow.") TAG (U"##Double pulsing") DEFINITION (U"models diplophonia (by a fraction between zero and one). Whenever this parameter is greater than zero, " "alternate pulses are modified. A pulse is modified with this %%single% parameter in %%two% ways: it is %%delayed " "in time% and its amplitude is %%attenuated%. If the double pulsing value is a maximum and equals one, the time of " "closure of the first peak coincides with the opening time of the second one. ") ENTRY (U"The vocal tract filter") NORMAL (U"The filter is modelled by a number of @@FormantGrid@'s. For parallel synthesis the formant grids that normally " "only contain formant frequency and formant bandwidth tiers, have been extended with amplitude tiers. Amplitudes values are in dB. The following formant grids can be used:") TAG (U"##Oral formants") DEFINITION (U"represent the \"standard\" oral resonances of the vocal tract. ") TAG (U"##Nasal formants") DEFINITION (U"model resonances in the nasal tract. Because the form of the nasal tract does not vary much during the course of an utterance, nasal formants tend to be constant. ") TAG (U"##Nasal antiformants") DEFINITION (U"model dips in the spectrum caused by leakage to the nasal tract.") ENTRY (U"Interaction between source and filter") NORMAL (U"The interaction between source and filter is modeled by two formant grids.") TAG (U"##Tracheal formants") DEFINITION (U"model one aspect of the coupling of the trachea with the vocal tract transfer function, namely, by the " "introduction of extra formants (and antiformants) that sometimes distort vowel spectra to a varying degrees. " "According to @@Klatt & Klatt (1990)@, the other effect being increased losses at glottal termination which primarily affect first-formant bandwidths.") TAG (U"##Tracheal antiformants") DEFINITION (U"model dips in the spectrum caused by the trachea.") TAG (U"##Delta formants") DEFINITION (U"The values in this grid model the number of hertz that the oral formants and/or bandwidths change during the open phase " "of the glottis. @@Klatt & Klatt (1990)@ distinguish four types of source-filter interactions: an F1 ripple in the " "source waveform, a non-linear interaction between the first formant and the fundamental frequency, a truncation of " "the first formant and tracheal formants and antiformants. ") ENTRY (U"The frication section") NORMAL (U"The frication section is modeled with a frication formant grid, with formant frequencies, bandwidths and (separate) " "amplitudes (dB), a frication by-pass tier (dB) and an amplitude tier (dB SPL) that governs the frication noise source.") ENTRY (U"A minimal synthesizer") NORMAL (U"The following script produces a minimal voiced sound. The first line creates the standard KlattGrid." "The next two lines define a pitch point, in Hz, and the voicing amplitude, in dB. The last line " "creates the sound.") CODE (U"Create KlattGrid: \"kg\", 0, 1, 6, 1, 1, 6, 1, 1, 1") CODE (U"Add pitch point: 0.5, 100") CODE (U"Add voicing amplitude point: 0.5, 90") CODE (U"To Sound") NORMAL (U"The following script will produce raw frication noise. Because we do not specify formant amplitudes, " "we turn off the formants in the parallel section.") CODE (U"Create KlattGrid: \"kg\", 0, 1, 6, 1, 1, 6, 1, 1, 1") CODE (U"Add frication amplitude point: 0.5 ,80") CODE (U"Add frication bypass point: 0.5, 0") CODE (U"To Sound (special): 0, 0, 44100, \"yes\", \"no\", \"yes\", \"yes\", \"yes\", \"yes\",") CODE (U"... \"Powers in tiers\", \"yes\", \"yes\", \"yes\",") CODE (U"... \"Cascade\", 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, \"yes\"") ENTRY (U"Changes") NORMAL (U"In praat versions before 5.1.05 the values for the %%oral / nasal / tracheal formant amplitudes% and" " %%frication bypass amplitude% had to be given in dB SPL; " " now they are in real dB's, i.e." " 0 dB means no change in amplitude. You can calculate new values from old values as:\n" "new_value = old_value + 20*log10(2e-5). This means that you have to subtract approximately 94 dB from the old values.") MAN_END MAN_BEGIN (U"Create KlattGrid...", U"djmw", 20081224) INTRO (U"A command to create a multitier @@KlattGrid@ speech synthesizer.") MAN_END #define PhonationGrid_to_Sound_COMMON_PARAMETERS_HELP \ TAG (U"##Sampling frequency (Hz)") \ DEFINITION (U"the @@sampling frequency@ of the resulting sound.") \ TAG (U"##Voicing") \ DEFINITION (U"switches voicing on or off.") \ TAG (U"##Flutter") \ DEFINITION (U"switches the flutter tier on or off. This will, of course, only have effect if at least one flutter point has been defined in the flutter tier.") \ TAG (U"##Double pulsing") \ DEFINITION (U"switches the double pulsing tier on or off.") \ TAG (U"##Collision phase") \ DEFINITION (U"switches the collision phase tier on or off.") \ TAG (U"##Spectral tilt") \ DEFINITION (U"switches the spectral tilt tier on or off.") \ TAG (U"##Flow function") \ DEFINITION (U"determines which flow function will be used. The flow function is determined by two parameters, %%power1% and %%power2% as %%flow(t)=x^^power1^-x^^power2^%. " \ "If the option \"Powers in tier\" is chosen the power1 and power2 tiers will be used for the values of %%power1% and %%power2%. The other choices switch the two tiers off and instead fixed values will be used for %%power1% and %%power2%.") \ TAG (U"##Flow derivative") \ DEFINITION (U"determines whether the flow or the flow derivative is used for phonation. ") \ TAG (U"##Aspiration") \ DEFINITION (U"determines whether aspiration is included in the synthesis.") \ TAG (U"##Breathiness") \ DEFINITION (U"determines whether breathiness is included in the synthesis.") MAN_BEGIN (U"KlattGrid: To Sound (phonation)...", U"djmw", 20090122) INTRO (U"A command to synthesize a Sound from the selected @@KlattGrid@.") ENTRY (U"Settings") PhonationGrid_to_Sound_COMMON_PARAMETERS_HELP MAN_END MAN_BEGIN (U"KlattGrid: Play special...", U"djmw", 20090421) INTRO (U"A command to play part of a @@KlattGrid@.") ENTRY (U"Settings") TAG (U"##Time range (s)") DEFINITION (U"determines the part of the sound's domain that you want to hear. If both argument equal zero the complete sound is played. ") TAG (U"##Sampling frequency (Hz)") DEFINITION (U"determines the @@sampling frequency@ of the resulting sound.") TAG (U"##Scale peak") DEFINITION (U"determines whether the peak value of the sound will be set to 0.99. In this way the sound will always play well.") PhonationGrid_to_Sound_COMMON_PARAMETERS_HELP TAG (U"##Model") DEFINITION (U"switches on either the cascade or the parallel section of the synthesizer.") TAG (U"##Oral formant range#, ##Nasal formant range# ...") DEFINITION (U"selects the formants to use in the synthesis. Choosing the end of a range smaller than the start of the range switches off the formants. ") TAG (U"##Frication bypass") DEFINITION (U"switches the frication bypass of the frication section on or off. " "The complete frication section can be turned off by also switching off the frication formants.") MAN_END MAN_BEGIN (U"KlattGrid: To Sound (special)...", U"djmw", 20090415) INTRO (U"A command to synthesize a Sound from the selected @@KlattGrid@.") ENTRY (U"Settings") TAG (U"##Time range (s)") DEFINITION (U"determines the part of the domain that you want to save as a sound. If both argument equal zero the complete sound is created. ") TAG (U"##Sampling frequency (Hz)") DEFINITION (U"determines the @@sampling frequency@ of the resulting sound.") TAG (U"##Scale peak") DEFINITION (U"determines whether the peak value of the sound will be set to 0.99. In this way the sound will always play well and can be saved to a file with minimal loss of resolution.") PhonationGrid_to_Sound_COMMON_PARAMETERS_HELP TAG (U"##Model") DEFINITION (U"switches on either the cascade or the parallel section of the synthesizer.") TAG (U"##Oral formant range#, ##Nasal formant range# ...") DEFINITION (U"selects the formants to use in the synthesis. Choosing the end of a range smaller than the start of the range switches off the formants. ") TAG (U"##Frication bypass") DEFINITION (U"switches the frication bypass of the frication section on or off. " "The complete frication section can be turned off by also switching off the frication formants.") MAN_END MAN_BEGIN (U"KlattGrid: Extract oral formant grid (open phases)...", U"djmw", 20090421) INTRO (U"Extracts the oral formant grid as used in the synthesis, i.e. the resulting grid contains the informantion from the oral formant grid and the delta formant grid combined during the open phase of the glottis. ") MAN_END MAN_BEGIN (U"Sound: To KlattGrid (simple)...", U"djmw", 20090415) INTRO (U"Create a @@KlattGrid@ from a @@Sound@.") ENTRY (U"Algorithm") NORMAL (U"Oral formants are determined by the @@Sound: To Formant (burg)...@ method and transformed to a @@FormantGrid@. " "Pitch is determined by the @@Sound: To Pitch...@ method and transformed to a @@PitchTier@. " "With @@Sound: To Intensity...@ we determine intensity and convert it to an @@IntensityTier@.") NORMAL (U"Next a KlattGrid is created whose time domain conforms to the sound. Its pitch tier, normal formant grid " "and its voicing amplitude are replaced by the results from the analyses.") MAN_END MAN_BEGIN (U"Sound & KlattGrid: Filter by vocal tract...", U"djmw", 20090108) INTRO (U"Filters the selected sound with the vocal tract part of the selected @@KlattGrid@. During this filtering the delta formants and bandwidths are %%not% used. ") MAN_END } /* End of file manual_KlattGrid.cpp */ praat-6.0.04/dwtools/manual_MDS.cpp000066400000000000000000003063171261542461700171110ustar00rootroot00000000000000/* manual_MDS.cpp * * Copyright (C) 1993-2014, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020422 GPL + removed "C syntax" part of manpage djmw 20030317 Latest modification. djmw 20030825 Spelling corrections. djmw 20040118 Procrustes modifications. djmw 20040214 Removed last link to @praat program@. djmw 20040407 Change Arguments -> Settings. djmw 20040513 Spelling. djmw 20070108 Latest modification. */ #include "ManPagesM.h" #include "MDS.h" static void drawLetterRConfigurationExample (Graphics g) { autoConfiguration me = Configuration_createLetterRExample (1); Graphics_setWindow (g, -6, 4, -7, 5); Configuration_draw (me.peek(), g, 1, 2, -6, 4, -7, 5, 0, 1, U"", 1); } static void drawLetterRConfigurationExample2 (Graphics g) { autoConfiguration me = Configuration_createLetterRExample (2); Configuration_draw (me.peek(), g, 1, 2, -0.8, 1.2, -0.8, 0.7, 0, 1, U"", 1); } static void drawLetterRShepard (Graphics g) { autoDissimilarity d = Dissimilarity_createLetterRExample (32.5); autoConfiguration c = Configuration_createLetterRExample (2); Dissimilarity_Configuration_drawShepardDiagram (d.peek(), c.peek(), g, 0, 200, 0, 2.2, 1, U"+", 1); } static void drawLetterRRegression (Graphics g) { autoDissimilarity d = Dissimilarity_createLetterRExample (32.5); autoConfiguration c = Configuration_createLetterRExample (2); Dissimilarity_Configuration_drawMonotoneRegression (d.peek(), c.peek(), g, MDS_PRIMARY_APPROACH, 0, 200, 0, 2.2, 1, U"+", 1); } static void drawCarrollWishConfigurationExample (Graphics g) { autoConfiguration me = Configuration_createCarrollWishExample (); Graphics_setWindow (g, -2, 2, -2, 2); Configuration_draw (me.peek(), g, 1, 2, -2, 2, -2, 2, 0, 1, U"", 1); } static void drawCarrollWishSalienceExample (Graphics g) { autoSalience me = Salience_createCarrollWishExample (); Salience_draw (me.peek(), g, 1, 2, 1); } static void drawMsplineExample (Graphics g) { drawSplines (g, 0, 1, 0, 10, 1, 3, U"0.3 0.5 0.6", 1); } static void drawIsplineExample (Graphics g) { drawSplines (g, 0, 1, 0, 1.5, 2, 3, U"0.3 0.5 0.6", 1); } void manual_MDS_init (ManPages me); void manual_MDS_init (ManPages me) { MAN_BEGIN (U"CANDECOMP", U"djmw", 19971201) ENTRY (U"An algorithm to solve the INDSCAL problem.") NORMAL (U"In the analysis of the INDSCAL three-way data matrix (%numberOfPoints " "\\xx %numberOfDimensions \\xx %numberOfSources) we seek to minimize the " "function: ") FORMULA (U"%f(%X, %W__1_,..., %W__%numberOfSources_) = " "\\su__%i=1..%numberOfSources_ | %S__%i_ \\-- %X%W__%i_%X\\'p |^2") NORMAL (U"where %S__%i_ is a known symmetric %numberOfPoints \\xx %numberOfPoints " "matrix with scalar products of distances for source %i, %X is the unknown configuration " "%numberOfPoints \\xx %numberOfDimensions matrix, %X\\'p its transpose, and, %W__%i_ is " "the diagonal %numberOfDimensions \\xx %numberOfDimensions weight matrix for source %i. The function " "above has no analytical solution for %X and the %W__%i_. It can be solved, however, " "by an iterative procedure which Carroll & Chang have christened CANDECOMP " "(CANonical DECOMPosition). This method minimizes, instead of the function " "given above, the following function:") LIST_ITEM (U"%g(%X, %Y, %W__1_,..., %W__%numberOfSources_) = \\su__%i=1..%numberOfSources_ " "| %S__%i_ \\-- %X%W__%i_%Y\\'p |^2") NORMAL (U"where %X and %Y are both %numberOfPoints \\xx %numberOfDimensions configuration matrices.") NORMAL (U"The algorithm proceeds as follows:") NORMAL (U"1. Initialize the $W matrices and the configuration matrix %X. This can for example be " "done according to a procedure given in @@Young, Takane & Lewyckyj (1978)@.") NORMAL (U"2. An alternating least squares minimization process is started as described that " "sequentially updates %Y, %X an %W (@@Carroll & Chang (1970)@):") LIST_ITEM (U"2.1. Solve for a new %Y given %X and the %W__%i_") LIST_ITEM (U"2.2. Solve for a new %X given the %W__%i_ and the new %Y.") LIST_ITEM (U"2.3. Solve for the %W__%i_ given the new %X and %Y.") NORMAL (U"Evaluate the goodness-of-fit criterion and either repeat the minimization sequence " "(2.1\\--2.3) or continue.") NORMAL (U"3. Done: make %Y equal to %X and solve a last time for the %W__%i_.") NORMAL (U"Note: during the minimization the following constraints are effective:") LIST_ITEM (U"The configuration must be centered.") LIST_ITEM (U"The sum of squared coordinates in the configuration space is one for " "each dimension, i.e., the configuration always has unit variance in each dimension.") MAN_END MAN_BEGIN (U"Configuration", U"djmw", 20101102) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"An object of type Configuration represents the positions of a number " "of labelled points in a multidimensional space.") ENTRY (U"How to create a Configuration") NORMAL (U"From the New menu:") LIST_ITEM (U" \\bu @@Create Configuration...") NORMAL (U"By multidimensional scaling:") LIST_ITEM (U" \\bu @@Dissimilarity: To Configuration (monotone mds)...") LIST_ITEM (U" \\bu @@Dissimilarity: To Configuration (i-spline mds)...") LIST_ITEM (U" \\bu @@Dissimilarity: To Configuration (interval mds)...") LIST_ITEM (U" \\bu @@Dissimilarity: To Configuration (ratio mds)...") LIST_ITEM (U" \\bu @@Dissimilarity: To Configuration (absolute mds)...") NORMAL (U"By multidimensional scaling with weights (@@Dissimilarity & Weight: To Configuration...@):") LIST_ITEM (U" \\bu ##Dissimilarity & Weight: To Configuration (monotone mds)...") LIST_ITEM (U" \\bu ##Dissimilarity & Weight: To Configuration (i-spline mds)...") LIST_ITEM (U" \\bu ##Dissimilarity & Weight: To Configuration (interval mds)...") LIST_ITEM (U" \\bu ##Dissimilarity & Weight: To Configuration (ratio mds)...") LIST_ITEM (U" \\bu ##Dissimilarity & Weight: To Configuration (absolute mds)...") NORMAL (U"By multidimensional scaling with a start Configuration:") LIST_ITEM (U" \\bu @@Dissimilarity & Configuration: To Configuration (monotone mds)...") LIST_ITEM (U" \\bu @@Dissimilarity & Configuration: To Configuration (i-spline mds)...") LIST_ITEM (U" \\bu @@Dissimilarity & Configuration: To Configuration (interval mds)...") LIST_ITEM (U" \\bu @@Dissimilarity & Configuration: To Configuration (ratio mds)...") LIST_ITEM (U" \\bu @@Dissimilarity & Configuration: To Configuration (absolute mds)...") NORMAL (U"By transforming an existing Configuration:") LIST_ITEM (U" \\bu @@Configuration: To Configuration (varimax)...") LIST_ITEM (U" \\bu @@Configuration & AffineTransform: To Configuration") LIST_ITEM (U" \\bu @@Configuration & Procrustes: To Configuration") NORMAL (U"From @@Principal component analysis@:") LIST_ITEM (U" \\bu @@TableOfReal: To Configuration (pca)...") LIST_ITEM (U" \\bu @@PCA & TableOfReal: To Configuration...") NORMAL (U"From @@Discriminant analysis@:") LIST_ITEM (U"@@TableOfReal: To Configuration (lda)...") LIST_ITEM (U" \\bu @@Discriminant & TableOfReal: To Configuration...") ENTRY (U"How to draw a Configuration") LIST_ITEM (U"\\bu @@Configuration: Draw...") LIST_ITEM (U"\\bu ##Configuration: Draw as numbers...") LIST_ITEM (U"\\bu ##Configuration: Draw as squares...") ENTRY (U"How to modify a Configuration") LIST_ITEM (U"\\bu @@Configuration: Randomize") LIST_ITEM (U"\\bu @@Configuration: Rotate (pc)@ (to principal directions)") LIST_ITEM (U"\\bu @@Configuration: Rotate...@ (in a plane around the origin)") LIST_ITEM (U"\\bu @@Configuration: Invert dimension...") LIST_ITEM (U"\\bu @@Configuration: Normalize...") ENTRY (U"Inside a Configuration") NORMAL (U"With @Inspect you will see the following attributes:") TAG (U"%numberOfRows") DEFINITION (U"the number of points (%numberOfPoints\\>_1).") TAG (U"%numberOfColumns") DEFINITION (U"the dimension of the space (%numberOfDimensions\\>_1).") TAG (U"%rowLabels") DEFINITION (U"the names associated with the points.") TAG (U"%columnLabels") DEFINITION (U"the names for the dimensions.") TAG (U"%data [1..%numberOfPoints][1..%numberOfDimensions]") DEFINITION (U"the coordinates of the points.") TAG (U"%metric") DEFINITION (U"determines the way distances between points are measured. In general " "the distance between points #x__%i_ and #x__%j_ is:") FORMULA (U"%d__%ij_ = " "(\\su__%k=1..%numberOfDimensions_ %w__%k_ |%x__%ik_ \\-- " "%x__%jk_|^^%metric^)^^1/%metric^") DEFINITION (U"For Euclidean distances %metric is 2.") TAG (U"%w [1..%numberOfDimensions]") DEFINITION (U"weight given to each dimension in the distance calculation.") MAN_END MAN_BEGIN (U"Configuration: Centralize", U"djmw", 19980413) INTRO (U"Makes the centre of the selected @Configuration equal to the origin.") NORMAL (U"") MAN_END MAN_BEGIN (U"Configuration: Draw...", U"djmw", 20040407) INTRO (U"Draws a projection of the selected @Configuration on a coordinate plane.") ENTRY (U"Settings") TAG (U"##X-coordinate#, ##Y-coordinate#") DEFINITION (U"control the dimensions that will show in the plot.") TAG (U"##xmin#, ##xmax#; ##ymin#, ##ymax#") DEFINITION (U"range for horizontal and vertical axes, respectively.") TAG (U"##Garnish") DEFINITION (U"when on, draws a bounding box with decoration.") MAN_END MAN_BEGIN (U"Configuration: Invert dimension...", U"djmw", 20040407) INTRO (U"Inverts one dimension of a @Configuration.") NORMAL (U"Setting") TAG (U"##Dimension") DEFINITION (U"the dimensions that has to be inverted.") ENTRY (U"Behaviour") NORMAL (U"For all points %i=1..%numberOfPoints: if %j == %dimension then %x__%ij_ " "= \\--%x__%ij_.") MAN_END MAN_BEGIN (U"Configuration: Normalize...", U"djmw", 20040407) INTRO (U"Normalizes the selected @Configuration.") ENTRY (U"Settings") TAG (U"##Sum of squares# (standard value: 0.0)") DEFINITION (U"The desired value for the variance.") TAG (U"##Each dimension separately") DEFINITION (U"When on, the sum of squares in each dimension (column) will be scaled to %sumOfSquares " "When off, the sum of squares of all the matrix elements will equal %sumOfSquares.") NORMAL (U"With the default value (0.0) for %sumOfSquares, and %eachDimensionSeparately chosen, " "an INDSCAL-like normalization is applied: the sum of squares for each column is scaled to " "equal 1.0. When %eachDimensionSeparately is off, a Kruskal-like normalization is applied: " "the sum of squares of the whole matrix is scaled equal to %numberOfRows.") ENTRY (U"Behaviour") NORMAL (U"Before the normalization will be applied, however, we first translate the centre of the " "configuration to the origin by subtracting the mean for each dimension. " "The sum of squares than equals variance.") MAN_END MAN_BEGIN (U"Configuration: Randomize", U"djmw", 19971201) INTRO (U"Changes all coordinates of the points #%x__%i_ in the @Configuration according to:") LIST_ITEM (U"%x__%ij_ = randomUniform (-1, 1)") MAN_END MAN_BEGIN (U"Configuration: Rotate...", U"djmw", 20100303) INTRO (U"Rotates the @Configuration in a plane around the origin.") NORMAL (U"Settings") TAG (U"##Dimension 1#, ##Dimension 2#") DEFINITION (U"the dimensions that span the plane. The order of dimension 1 and dimension 2 is not important: " "the lowest number always determines the first dimension.") TAG (U"##Angle") DEFINITION (U"the counter-clockwise rotation angle in degrees.") MAN_END MAN_BEGIN (U"Configuration: Rotate (pc)", U"djmw", 19971201) INTRO (U"Rotates the @Configuration to principal directions. The principal directions " "correspond to the principal components.") MAN_END MAN_BEGIN (U"Configuration: To Configuration (procrustes)", U"djmw", 19971219) INTRO (U"A command that transforms the second selected @Configuration object " "to match the first selected Configuration object as closely as possible." "This problem of fitting one configuration (testee) to another (target) " "as closely as possible is called the Procrustes problem. We use a " "special @@Procrustes transform@ algorithm that does not " "mutilate or distort the testee configuration.") NORMAL (U"Both Configuration objects must have the same dimensions.") MAN_END MAN_BEGIN (U"Configuration: To Configuration (varimax)...", U"djmw", 20040407) INTRO (U"A command that rotates the selected @Configuration object to a new " "Configuration object whose coordinates have maximum %squared variance. ") ENTRY (U"Settings") TAG (U"##Normalize rows") DEFINITION (U"when selected, the distances of all points to the origin will " "be made equal before iteration starts. We remember these scale factors " "and restore the original distances after the iteration process has " "stopped.") TAG (U"##Quartimax") DEFINITION (U"when selected, the sum of fourth powers, normalized or raw, " "will be maximized. ") TAG (U"##Maximum number of iterations") DEFINITION (U"sets a limit to the number of iterations. One iteration consists " "of %numberOfDimensions\\.c (%numberOfDimensions\\--1)/2 planar rotations " "of all pairs of dimensions.") TAG (U"##Tolerance") DEFINITION (U"also determines when the iteration stops. This happens if " "|%v__%i_\\--%v__%i+1_| < %tolerance \\.c %v__%i_, where %v__%i_ is the " "squared variance for the %i^^th^ iteration.") NORMAL (U"The iteration process stops when either the %%maximum number of " "iterations% is reached or the %tolerance criterion is met, which ever " "one is first.") ENTRY (U"Algorithm") NORMAL (U"The Varimax rotation procedure was first proposed by @@Kaiser " "(1958)@. Given a %numberOfPoints \\xx %numberOfDimensions configuration " "#A, the procedure tries to find an orthonormal rotation matrix #T such " "that the sum of variances of the columns of #B*#B is a maximum, where #B " "= #A#T and * is the element wise (Hadamard) product of matrices. A direct " "solution for the optimal #T is not available, except for the case when " "%numberOfDimensions equals two. Kaiser suggested an iterative " "algorithm based on planar rotations, i.e., alternate rotations of all " "pairs of columns of #A.") NORMAL (U"However, this procedure is not without problems: the varimax function " "may have stationary points that are not even local maxima. We have " "incorporated an algorithm of @@Ten Berge (1995)@ " "that prevents this unpleasant situation from happening.") MAN_END MAN_BEGIN (U"Configuration: To Distance", U"djmw", 19971207) INTRO (U"A command that computes a @Distance object for each selected " "@Configuration.") ENTRY (U"Algorithm") NORMAL (U"The distance %d__%ij_ between objects %i and %j is calculated as:") FORMULA (U"%d__%ij_ = %d__%ji_ = (\\su__%k=1..%numberOfDimensions_ |%x__%ik_ " "\\-- %x__%jk_|^2)^^1/2^") MAN_END MAN_BEGIN (U"Configuration: To Similarity (cc)", U"djmw", 19980130) INTRO (U"A command that create one @Similarity object from the selected " "@Configuration objects.") NORMAL (U"In the Similarity object entry %s__%ij_ equals the @@congruence " "coefficient@ for the %i-th and %j-th selected Configuration object.") NORMAL (U"All Configuration objects must have the same number of points and " "the same dimensions.") MAN_END MAN_BEGIN (U"Configuration & AffineTransform: To Configuration", U"djmw", 20011008) INTRO (U"A command that transforms the selected @Configuration to a new " "Configuration object according to the specifications in the selected " "@AffineTransform object.") MAN_END MAN_BEGIN (U"Configuration & Procrustes: To Configuration", U"djmw", 20011008) INTRO (U"A command that transforms the selected @Configuration to a new " "Configuration object according to the specifications in the selected " "@Procrustes object.") MAN_END MAN_BEGIN (U"Configurations: To AffineTransform (congruence)...", U"djmw", 20040407) INTRO (U"A command that creates an @AffineTransform object from two selected " "@Configuration objects.") NORMAL (U"We calculate the affine transform that transforms the second " "selected Configuration object to match the first selected Configuration " "object as closely as possible. " "The degree of proportionality is the congruence between corresponding " "dimensions.") ENTRY (U"Settings") TAG (U"##Maximum number of iterations") DEFINITION (U"sets a limit to the number of iterations.") TAG (U"##Tolerance") DEFINITION (U"also determines when the iteration stops. This happens if " "|%f(#T__%i_)\\--%f(#T__%i+1_)| < %tolerance \\.c %f(#T__%i_), where " "%f(#T__%i_) is the sum of the congruences for the %i^^th^ " "iteration (see below).") NORMAL (U"The iteration process stops when either the %%maximum number of " "iterations% is reached or the %tolerance criterion is met, which ever " "one is first.") ENTRY (U"Algorithm") NORMAL (U"Sometimes the criterion used in a @@Procrustes transform@ is too " "restrictive for comparing two configurations. This criterion is only " "zero when the positions in the rotated configuration (#A#T) equal the " "positions in the other configuration (#B). @@Brokken (1983)@ proposed an " "algorithm to maximize instead the sum of congruences between " "corresponding dimensions of #AT and #B. " "Specifically he proposed to maximize") FORMULA (U"%f(#T) = \\su__%i=1..%numberOfDimensions_ #t\\'p__%i_#A\\'p#b__%i_ /" " ((#t\\'p__%i_#A\\'p#A#t__%i_)^^1/2^(#b\\'p__%i_#b__%i_)^^1/2^),") NORMAL (U"where #t\\'p__%i_ and #b\\'p__%i_ are the %i^^th^ column of #T and " "#B, respectively. A direct solution for #T is not available, it can only " "be obtained by an iterative procedure. The implemented algorithm is from " "@@Kiers & Groenen (1996)@ and shows excellent convergence properties.") MAN_END MAN_BEGIN (U"Configuration & Configuration: To Procrustes...", U"djmw", 20011008) INTRO (U"A command that creates a @Procrustes object from two selected " "@Configuration objects.") ENTRY (U"Setting") TAG (U"##Orthogonal transform") DEFINITION (U"determines whether or not a translation and a scaling are allowed in the transform.") NORMAL (U"We calculate the @@Procrustes transform@ that transforms the second " "selected Configuration object to match the first selected Configuration " "object as closely as possible.") MAN_END MAN_BEGIN (U"Confusion: To Dissimilarity...", U"djmw", 20040407) INTRO (U"A command that creates a @Dissimilarity from every selected " "@Confusion.") ENTRY (U"Settings") TAG (U"##Normalize") DEFINITION (U"when on, normalize rows by dividing each row element by the row " "sum. In this way you correct for unequal stimulus numbers.") TAG (U"##No symmetrization#, #Average, #Houtgast") DEFINITION (U"determine the symmetrization procedure. See " "@@Confusion: To Similarity...") TAG (U"##Maximum dissimilarity") DEFINITION (U"determines the maximum dissimilarity possible. When the default " "value, 0.0, is chosen, %maximumDissimilarity " "is calculated as the maximum element in the Similarity object.") ENTRY (U"Algorithm") NORMAL (U"We first transform the Confusion to a Similarity. See " "@@Confusion: To Similarity...") NORMAL (U"To obtain dissimilarities from similarities we \"reverse\" the " "latter:") FORMULA (U"%%dissimilarity__%ij_ = %maximumDissimilarity \\-- %similarity__%ij_") MAN_END MAN_BEGIN (U"Confusion: To Dissimilarity (pdf)...", U"djmw", 20040407) INTRO (U"A command that creates a @Dissimilarity from every selected " "@Confusion.") ENTRY (U"Settings") TAG (U"##Symmetrize first") DEFINITION (U"when on, the confusion matrix is symmetrized before we calculate " "dissimilarities.") TAG (U"##Maximum dissimilarity (units of sigma)") DEFINITION (U"specifies the dissimilarity from confusion matrix elements that " "are zero.") ENTRY (U"Algorithm") TAG (U"1. Normalize rows by dividing each row element by the row sum (optional).") TAG (U"2. Symmetrize the matrix by averaging %f__%ij_ and %f__%ji_.") TAG (U"3. Transformation of the confusion measure which is a sort of " "%similarity measure to the %dissimilarity measure.") NORMAL (U"Similarity and dissimilarity have an inverse relationship: the " "greater the similarity, the smaller the dissimilarity and vice versa. " "Both have a monotonic relationship with distance. " "The most simple way to transform the similarities %f__%ij_ into " "dissimilarities is:") FORMULA (U"%dissimilarity__%ij_ = %maximumSimilarity \\-- %similarity__%ij_") NORMAL (U"For ordinal analyses like Kruskal this transformation is fine because " "only order relations are important in this analysis. However, for " "metrical analyses like INDSCAL this is not optimal. " "In INDSCAL, distance is a linear function of dissimilarity. This means " "that, with the transformation " "above, you ultimately fit an INDSCAL model in which the distance " "between object %i and %j will be linearly related to the confusion " "between %i and %j.") NORMAL (U"For the relation between confusion and dissimilarity, the model " "implemented here, makes the assumption that the amount of confusion " "between objects %i and %j is related to the amount that their " "probability density functions, pdf's, overlap. Because we do not know " "these pdf's we make the assumption that both are normal, have equal " "%sigma and are one-dimensional. The parameter to be determined is the " "distance between the centres of both pdf's. " "According to formula 26.2.23 in @@Abramowitz & Stegun (1970)@, for each " "fraction %f__%ij_, we have to find an %x that solves:") FORMULA (U"%f__%ij_ = 1 / \\Vr(2%\\pi) \\in__%x_^^\\oo^ e^^-%t\\.c%t/2^ %dt") NORMAL (U"This %x will be used as the dissimilarity between %i and %j. The " "relation between %x and %f__%ij_ is monotonic. This means that the " "results for a Kruskal analysis will not change much. For INDSCAL, in " "general, you will note a significantly better fit.") MAN_END MAN_BEGIN (U"Confusion: To Similarity...", U"djmw", 20040407) INTRO (U"A command that creates a @Similarity from every selected @Confusion.") ENTRY (U"Settings") TAG (U"##Normalize") DEFINITION (U"when on, normalize rows by dividing each row element by the row " "sum. In this way you correct for unequal stimulus numbers.") TAG (U"##No symmetrization#, #Average, #Houtgast") DEFINITION (U"determine the symmetrization procedure.") ENTRY (U"Algorithm") NORMAL (U"The %Average procedure averages:") FORMULA (U"%similarity__%ij_= %similarity__%ji_ = (%confusion__%ij_ + " "%confusion__%ji_) / 2") NORMAL (U"The %Houtgast procedure as described in the paper by @@Klein, Plomp " "& Pols (1970)@, expresses similarity between stimuli %i and %j by the " "number of times that stimulus %i and %j have " "resulted in the same response, summated over all response categories.") NORMAL (U"We use the following formula to calculate the %Houtgast " "dissimilarities:") FORMULA (U"%similarity__%ij_ = \\su__%k=1..%numberOfColumns_ min " "(%confusion__%ik_, %confusion__%jk_)") NORMAL (U"which is equivalent to the formula in the Klein et al. paper:") FORMULA (U"%similarity__%ij_ = \\su__%k=1..%numberOfColumns_ (%confusion__%ik_ " "+ %confusion__%jk_ \\-- |%confusion__%ik_ \\-- %confusion__%jk_|)") MAN_END MAN_BEGIN (U"congruence coefficient", U"djmw", 20040407) INTRO (U"The %%congruence coefficient% is a measure of similarity between two " "@@Configuration@s.") NORMAL (U"The congruence coefficient %c(#X, #Y) for the configurations #X and " "#Y is defined as:") FORMULA (U"%c(%X, %Y) = \\su__%i<%j_ %w__%ij_ %d__%ij_(#X) %d__%ij_(#Y) / " "([\\su__%i<%j_ %w__%ij_ %d^2__%ij_(#X)]^^1/2^ [\\su__%i<%j_ %w__%ij_ " "%d^2__%ij_(#Y)]^^1/2^),") NORMAL (U"where %d__%ij_(#X) is the distance between the points %i and %j in " "configuration #X and %w__%ij_ are nonnegative weights (default: %w__%ij_" " = 1).") NORMAL (U"Since distances are nonnegative, the congruence coefficient has a " "value between 0 and 1.") NORMAL (U"The %%congruence coefficient% is a better measure of the similarity " "between configurations than the %%correlation coefficient% of the " "distances. @@Borg & Groenen (1997)@ give a simple example where things " "go wrong with correlation coefficients: two configurations #X and #Y with three points each, have " "distances %d__12_(#X) = 1, %d__13_(#X) = 2, %d__23_(#X) = 3 and " "%d__12_(#Y) = 2, %d__13_(#Y) = 3, %d__23_(#Y) = 4. " "These distances have a correlation coefficient of 1. " "However, in #X the three points lie on a straight line and in #Y the " "points form a triangle. This unwanted situation occurs because " "in the calculation of the correlation coefficient the mean is subtracted " "from the distances and the resulting values are no longer distances " "(they may become negative). In calculating the correlation " "between the distances we should not subtract the mean. " "In fact, the congruence coefficient is exactly this correlation " "coefficient calculated with respect to the origin and " "not with respect to the centroid position (the \"mean\").") NORMAL (U"For further information on how well one number can assess the " "similarity between two configurations see @@Borg & Groenen (1997)@ " "section 19.7.") MAN_END MAN_BEGIN (U"ContingencyTable", U"djmw", 19971216) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"In a two-way contingency table, cell %f__%ij_ contains the frequency " "with which row category %i co-occurs with column category %j. " "Necessarily, all %f__%ij_ \\>_ 0.") ENTRY (U"Commands") NORMAL (U"Creation") LIST_ITEM (U"\\bu ##TableOfReal: To ##ContingencyTable") NORMAL (U"Query") LIST_ITEM (U"\\bu ##ContingencyTable: Get chi squared probability") LIST_ITEM (U"\\bu ##ContingencyTable: Get Cramer's statistic") LIST_ITEM (U"\\bu ##ContingencyTable: Get contingency coefficient") NORMAL (U"Analysis") LIST_ITEM (U"\\bu @@ContingencyTable: To Configuration (ca)...") MAN_END MAN_BEGIN (U"ContingencyTable: To Configuration (ca)...", U"djmw", 20040407) INTRO (U"A command that creates a @Configuration object from the selected " "@ContingencyTable object by means of @@Correspondence analysis@.") ENTRY (U"Settings") TAG (U"##Number of dimensions") DEFINITION (U"The dimensionality of the Configuration.") TAG (U"##Scaling of the final configuration") DEFINITION (U"determines whether row points are in the centre of gravity of " "column points, or, column points are in the centre of gravity of row " "points, or, whether roes and columns are treated symmetrically.") ENTRY (U"Algorithm") NORMAL (U"1. We start with the following transformation of the entries " "%f__%ij_:") FORMULA (U"%h__%ij_ = %f__%ij_ / \\Vr (%f__%i+_%f__+%j_) - \\Vr " "(%f__%i+_%f__+%j_) / %N,") NORMAL (U"where %h__%ij_ is the entry for a cell in the matrix #H with " "transformed data, %f__%i+_ " "is the total count for row %i, %f__+%j_ is the total count for column %j " "and %N is the grand total. " "This can be written in matrix form as:") FORMULA (U"#H = #R^^\\--1/2^#F#C^^\\--1/2^ \\-- #R^^1/2^#uu\\'p#C^^1/2^ / %N,") NORMAL (U"where #R and #C are diagonal matrices with the row and column totals, " "respectively and #u a column vector with all elements equal to 1. ") NORMAL (U"2. Next the singular value decomposition of matrix #H is performed:") FORMULA (U"#H = #K #\\La #L\\'p,") NORMAL (U"where #K\\'p#K = #I, #L\\'p#L = #I, and #\\La is a diagonal matrix " "with singular values.") NORMAL (U"3. Now the row (#X) and column points (#Y) can be determined. " "Three normalizations are possible:") TAG (U"\\bu Scale row points in the centre of gravity of column points") DEFINITION (U"#X = \\Vr%N #R^^\\--1/2^#K#\\La") DEFINITION (U"#Y = \\Vr%N #C^^\\--1/2^#U") TAG (U"\\bu Scale column points in the centre of gravity of row points") DEFINITION (U"#X = \\Vr%N #R^^\\--1/2^#K") DEFINITION (U"#Y = \\Vr%N #C^^\\--1/2^#L#\\La") TAG (U"\\bu Treat row points and column points symmetrically") DEFINITION (U"#X = \\Vr%N #R^^\\--1/2^#K#\\La^^\\--1/2^") DEFINITION (U"#Y = \\Vr%N #C^^\\--1/2^#L\\La^^\\--1/2^") NORMAL (U"For more details see @@Gifi (1990)@, chapter 8.") MAN_END MAN_BEGIN (U"Correspondence analysis", U"djmw", 19971216) INTRO (U"Correspondence analysis provides a method for representing data in " "an Euclidean space so that the results can be visually examined for " "structure. For data in a typical two-way @ContingencyTable both the row " "variables and the column variables are represented in the same space. " "This means that one can examine relations not only among row " "or column variables but also between row and column variables.") NORMAL (U"In correspondence analysis the data matrix is first transformed by " "dividing each cell by the square root of the corresponding row and column " "totals. " "The transformed matrix is then decomposed with singular value " "decomposition resulting in the singular values (which in this case are " "canonical correlations) and a set of row vectors and column vectors. " "Next the row and column vectors are rescaled with the original total " "frequencies to obtain optimal scores. " "These optimal scores are weighted by the square root of the singular " "values and become the coordinates of the points in the @Configuration.") NORMAL (U"Examples can be found in the books by @@Weller & Romney (1990)@ and " "@@Gifi (1990)@.") MAN_END MAN_BEGIN (U"Create Configuration...", U"djmw", 19980413) INTRO (U"A command to create a @Configuration with the specified number of " "points and number of dimensions. The location of the points will be " "determined by the formula (see @@Formulas@ for more " "information about possible formulas).") MAN_END MAN_BEGIN (U"Create INDSCAL Carroll & Wish example...", U"djmw", 19971201) INTRO (U"Creates eight @Dissimilarity objects that bear names \"1\" ... \"8\".") NORMAL (U"These objects contain the interpoint distances for a twodimensional " "3\\xx3 @Configuration of points, labelled A, B, C, ... I. " "All Dissimilarity objects are based on the following underlying configuration.") PICTURE (4.0, 4.0, drawCarrollWishConfigurationExample) NORMAL (U"The eight sources weigh this configuration in the following manner:") PICTURE (4.0, 4.0, drawCarrollWishSalienceExample) NORMAL (U"For each source, the distances were subjected to the transformation: ") FORMULA (U"%dissimilarity__%ij_ = %distance__%ij_ + %noiseRange \\.c #u, ") NORMAL (U"where #u is a uniform random variable between 0 and 1.") NORMAL (U"Now you can do the following for example:") TAG (U"Select all the Dissimilarity objects and choose @@Dissimilarity: To Distance...|" "To Distance...@.") DEFINITION (U"Uncheck scale (add \"additive constant\").") TAG (U"Select all the Distance objects and choose @@Distance: To Configuration (indscal)...|" "To Configuration (indscal)...@.") DEFINITION (U"and an @@INDSCAL analysis@ will be performed. In order to reproduce the saliences, " "you have to uncheck the \"Normalize scalar products\" option.") NORMAL (U"This example was adapted from @@Carroll & Wish (1974)@.") MAN_END MAN_BEGIN (U"Create letter R example...", U"djmw", 19971201) INTRO (U"Creates a @Dissimilarity object that bears the name %R. The " "dissimilarities in this object were chosen to be a monotone " "transformation of the distances between the 32 two-dimensional points " "that make up the capital letter #R.") PICTURE (4.0, 4.0, drawLetterRConfigurationExample) NORMAL (U"All 32 \\.c (32-1)/2 interpoint distances were subjected to the " "transformation: ") FORMULA (U"%dissimilarity__%ij_^ = %distance__%ij_^2 + 5 + %noiseRange \\.c #u, ") NORMAL (U"where #u is a uniform random variable between 0 and 1.") NORMAL (U"This example was chosen from @@Green, Carmone & Smith (1989)@.") MAN_END MAN_BEGIN (U"disparities", U"djmw", 19980111) INTRO (U"The numbers %d\\'p__%ij_ that result from applying an admissible " "transformation %f on the dissimilarities %\\de__%ij_, i.e., %d\\'p__%ij_ " "= %f (%\\de__%ij_). Disparities have the same dimension as distances. " "Other names for disparities are %%pseudo distances% and %%target " "distances%.") MAN_END MAN_BEGIN (U"Dissimilarity", U"djmw", 20010327) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"It represents a one-way table with " "dissimilarities between \"objects\".") ENTRY (U"Creating a Dissimilarity from data in a text file") NORMAL (U"Suppose you have three objects A, B and C. " "In one way or another, you have acquired the following (symmetric) " "dissimilarities: %\\de__%AB_ = 2 (= %\\de__%BA_) , %\\de__%AC_ = 1 " "(= %\\de__%CA_), and %\\de__%BC_ = 1.4 (= %\\de__CB_), where %\\de__%AB_" " represents the dissimilarity between object A and object B.") NORMAL (U"You can create a simple text file like the following:") CODE (U"\"ooTextFile\" ! The line by which Praat can recognize your file") CODE (U"\"Dissimilarity\" ! The line that tells Praat about the contents") CODE (U"3 \"A\" \"B\" \"C\" ! Number of columns, and column labels") CODE (U"3 ! Number of rows") CODE (U"\"A\" 0 2 1 ! Row label (A), A-B value, A-C value") CODE (U"\"B\" 2 0 1.4 ! Row label (B), B-A value, B-C value") CODE (U"\"C\" 1 1.4 0 ! Row label (C), C-A value, C-B value") NORMAL (U"Notice that:") LIST_ITEM (U"\\bu the row and column labels are identical.") LIST_ITEM (U"\\bu the matrix elements on the diagonal are zero.") LIST_ITEM (U"\\bu the matrix is symmetrical.") NORMAL (U"This text file can be read with the @@Read from file...@ command. " "Since a Dissimilarity object has the data structure of a square " "symmetrical TableOfReal, you could also start from an appropriate " "@TableOfReal object and cast it to a Dissimilarity object.") ENTRY (U"Commands") NORMAL (U"Creation") LIST_ITEM (U"\\bu @@Confusion: To Dissimilarity...") NORMAL (U"Drawing") LIST_ITEM (U"\\bu ##Draw as numbers...") LIST_ITEM (U"\\bu ##Draw as squares...") NORMAL (U"Query") LIST_ITEM (U"\\bu ##Get column mean (index)...") LIST_ITEM (U"\\bu ##Get column mean (label)...") LIST_ITEM (U"\\bu ##Get column stdev (index)...") LIST_ITEM (U"\\bu ##Get column stdev (label)...") LIST_ITEM (U"\\bu @@Dissimilarity: Get additive constant") NORMAL (U"Modification") LIST_ITEM (U"\\bu @@Formula...") LIST_ITEM (U"\\bu ##Set value...") LIST_ITEM (U"\\bu ##Remove column (index)...") LIST_ITEM (U"\\bu ##Insert column (index)...") LIST_ITEM (U"\\bu ##Set row label (index)...") LIST_ITEM (U"\\bu ##Set row label (label)...") LIST_ITEM (U"\\bu ##Set column label (index)...") LIST_ITEM (U"\\bu ##Set column label (label)...") NORMAL (U"Multidimensional scaling analysis") LIST_ITEM (U"\\bu @@Dissimilarity: To Configuration (monotone mds)...") LIST_ITEM (U"\\bu @@Dissimilarity: To Configuration (i-spline mds)...") LIST_ITEM (U"\\bu @@Dissimilarity: To Configuration (interval mds)...") LIST_ITEM (U"\\bu @@Dissimilarity: To Configuration (ratio mds)...") LIST_ITEM (U"\\bu @@Dissimilarity: To Configuration (absolute mds)...") LIST_ITEM (U"\\bu @@Dissimilarity: To Configuration (kruskal)...") LIST_ITEM (U"Transformations") LIST_ITEM (U"\\bu @@Dissimilarity: To Distance...") LIST_ITEM (U"\\bu @@Dissimilarity: To Weight") MAN_END MAN_BEGIN (U"Dissimilarity: Get additive constant", U"djmw", 19971201) INTRO (U"A command that calculates the \"additive constant\" from the selected @Dissimilarity.") NORMAL (U"Distances %d__%ij_ will be obtained from dissimilarities %\\de__%ij_ according to:") FORMULA (U" %distance__%ij_ = %dissimilarity__%ij_ + %additiveConstant") NORMAL (U"We use a procedure by @@Cailliez (1983)@ to solve the \"additive constant problem\", i.e. " "find the smallest %additiveConstant such that all %distance__%ij_ in the above equation " " have a Euclidean representation.") MAN_END MAN_BEGIN (U"Dissimilarity: To Configuration (absolute mds)...", U"djmw", 19980105) INTRO (U"A command that creates a @Configuration object from a @Dissimilarity object.") NORMAL (U"The @disparities %d\\'p__%ij_ will be obtained from dissimilarities %\\de__%ij_ according to:") FORMULA (U"%d\\'p__%ij_ = %\\de__%ij_") MAN_END MAN_BEGIN (U"Dissimilarity: To Configuration (interval mds)...", U"djmw", 19980105) INTRO (U"A command that creates a @Configuration object from a @Dissimilarity object.") NORMAL (U"The @disparities %d\\'p__%ij_ will be obtained from dissimilarities %\\de__%ij_ according to:") FORMULA (U"%d\\'p__%ij_ = %a + %b \\.c %\\de__%ij_") MAN_END MAN_BEGIN (U"Dissimilarity: To Configuration (i-spline mds)...", U"djmw", 20040407) INTRO (U"A command that creates a @Configuration object from a @Dissimilarity object.") NORMAL (U"Dissimilarities %\\de__%ij_ and @disparities %d\\'p__%ij_ will be related by a @spline function:") FORMULA (U"%d\\'p__%ij_ = \\su__%k=1..(%%numberOfInteriorKnots%+%order)_ spline__%k_ (%knots, %order, %\\de__%ij_),") NORMAL (U"where spline__%k_ (\\.c) is the value of the %k^^th^ I-spline of order %order and knot sequence " "%knot evaluated at %\\de__%ij_.") ENTRY (U"Settings") TAG (U"##Number of dimensions") DEFINITION (U"determines the dimensionality of the configuration.") TAG (U"##Number of interior knots") DEFINITION (U"determines the number of segment boundaries. Each interior knot " "is the boundary between two segments. The splines in each segment will " "be joined as continuously as possible.") TAG (U"##Order of I-spline") DEFINITION (U"The order of the polynomial basis of the I-spline.") NORMAL (U"Finding the optimal Configuration involves a minimization process:") TAG (U"##Tolerance") DEFINITION (U"When successive values for the stress differ by less than " "#Tolerance, the minimization process stops.") TAG (U"##Maximum number of iterations") DEFINITION (U"Minimization stops after this number of iterations has been " "reached.") TAG (U"##Number of repetitions") DEFINITION (U"If chosen larger than 1, the minimization process will be " "repeated, each time with another random start configuration. " "The configuration that results in minimum stress, will be saved.") ENTRY (U"Hints") NORMAL (U"If %numberOfInteriorKnots is zero, polynomial regression will be " "performed. Therefore , the combination %numberOfInteriorKnots = 0 and " "%order = 1 also gives interval " "scaling (in fact, it is the implementation in this program).") NORMAL (U"In the limit when %order = 0 and %numberOfInteriorKnots = " "%numberOfDissimilarities, monotone regression is performed.") MAN_END MAN_BEGIN (U"Dissimilarity: To Configuration (kruskal)...", U"djmw", 20040407) INTRO (U"A command that creates a @Configuration object from a @Dissimilarity " "object.") ENTRY (U"Settings") TAG (U"##Number of dimensions# (standard value: 2)") DEFINITION (U"The dimensionality of the Configuration.") TAG (U"##Distance metric% (standard value: 2, i.e. Euclidean)") DEFINITION (U"the general distance between points #x__%i_ and #x__%j_ (%i,%j " "= 1..%numberOfPoints) is:") DEFINITION (U"(\\su__%k=1..%numberOfDimensions_ |%x__%ik_ \\--%x__%jk_|" "^^%metric^)^^1/%metric^") TAG (U"##Sort distances") DEFINITION (U"determines the handling of ties in the data. When off, whenever " "two or more dissimilarities are equal we do not care whether the fitted " "distances are equal or not. " "Consequently, no constraints are imposed on the fitted distances. " "When on, however, we impose the constaint that the fitted distances be " "equal whenever the dissimilarities are equal.") NORMAL (U"For the calculation of stress:") TAG (U"##Formula1 (default)") // ?? FORMULA (U"%stress = \\Vr(\\su(%distance__%k_ \\-- %fittedDistance__%k_)^2 / " "\\su %distance__%k_^2)") TAG (U"##Formula2") FORMULA (U"%stress = \\Vr(\\su(%distance__%k_ \\-- %fittedDistance__%k_)^2 / " "\\su (%distance__%k_ \\-- %averageDistance)^2)") DEFINITION (U"Note that values of stress 2 are generally more than double those " "of stress 1 for the same degree of fit.") NORMAL (U"Finding the optimal Configuration involves a minimization process:") TAG (U"##Tolerance") DEFINITION (U"When successive values for the stress differ less than %Tolerance " "the minimization process stops.") TAG (U"##Maximum number of iterations") DEFINITION (U"Minimization stops after this number of iterations has been " "reached.") TAG (U"##Number of repetitions") DEFINITION (U"When chosen larger than 1, the minimalization process will be " "repeated, each time with another random start configuration. " "The configuration that results in minimum stress will be saved.") ENTRY (U"Precautions") NORMAL (U"When there are few objects it is impossible to recover many " "dimensions. A rough rule of thumb is that there should be at least twice " "as many number of observations, i.e. the %numberOfPoints \\.c " "(%numberOfPoints - 1) / 2 (dis)similarities, than parameters " "to be estimated, i.e. the %numberOfPoints \\.c %numberOfDimensions " "position coordinates. A practical guide is:") LIST_ITEM (U"for %numberOfDimensions = 1 you need \\>_ 5 objects") LIST_ITEM (U"for %numberOfDimensions = 2 you need \\>_ 9 objects") LIST_ITEM (U"for %numberOfDimensions = 3 you need \\>_ 13 objects") NORMAL (U"There is no feasible way to be certain that you have found the " "true global minimum. However, by using a great number of different " "random starting configurations to scale the same data it is often " "possible to obtain practical certainty. " "Although the procedure for obtaining an initial configuration is based " "on a %linear relation between distance and (dis)similarity, it gives a " "very good approximation of the optimal #Configuration and " "the #Minimizer practically always finds the global minimum from it " "(I guess...). A way to find out is to try the %numberOfRepetitions " "parameter which gives you the possibility to fit many times and each " "time start with another random initial configuration.") ENTRY (U"Algorithm") LIST_ITEM (U"1. The Dissimilarity object is converted to a Distance object in " "the same way as in @@Dissimilarity: To Distance...@.)") LIST_ITEM (U"2. From the Distance object an initial Configuration is found by " "first transforming the Distance object to a matrix with scalar products " "of distances and subsequently solving for the first %numberOfDimensions " "eigenvectors of this matrix.") LIST_ITEM (U"3. A minimalization algorithm is started that tries to minimize a " "function. In this function:") LIST_ITEM (U"\\bu 3.1 We normalize the current Configuration from the minimizer") LIST_ITEM (U"\\bu 3.2 Calculate a new Distance object from the configuration") LIST_ITEM (U"\\bu 3.3 Do a monotone regression of this Distance on the " "Dissimilarity. This results in a new Distance object.") LIST_ITEM (U"\\bu 3.4 Calculate stress from this Distance and the Distance " "obtained from Dissimilarity.") NORMAL (U"The optimization process is ccontrolledby a conjugate gradient " "minimization algorithm that tries to minimize the %stress function. " "In @@Kruskal (1964)@, a steepest descent " "algorithm is used wwhichis less efficient. ") MAN_END MAN_BEGIN (U"Dissimilarity: To Configuration (monotone mds)...", U"djmw", 20040407) INTRO (U"A command that creates a @Configuration object from a @Dissimilarity " "object.") NORMAL (U"Dissimilarities %\\de__%ij_ and @disparities %d\\'p__%ij_ are " "related by:") FORMULA (U"%d\\'p__%ij_ \\<_ %d\\'p__%kl_ if %\\de__%ij_ \\<_ %\\de__%kl_") ENTRY (U"Settings") TAG (U"##Number of dimensions") DEFINITION (U"determines the number of dimensions of the configuration.") TAG (U"##Primary or secondary approach to ties") DEFINITION (U"When dissimilarities are equal, i.e., %\\de__%ij_ = %\\de__%kl_, " "the primary approach imposes no conditions on the corresponding " "@disparities %d\\'p__%ij_ and %d\\'p__%kl_, while the %secondary " "approach demands that also %d\\'p__%ij_ = %d\\'p__%kl_.") NORMAL (U"Finding the optimal Configuration involves a minimization process:") TAG (U"##Tolerance") DEFINITION (U"When successive values for the stress differ less than %Tolerance " "the minimization process stops.") TAG (U"##Maximum number of iterations") DEFINITION (U"Minimization stops after this number of iterations has been reached.") TAG (U"##Number of repetitions") DEFINITION (U"When chosen larger than 1, the minimalization process will be " "repeated, each time with another random start configuration. " "The configuration that results in minimum stress will be saved.") MAN_END MAN_BEGIN (U"Dissimilarity: To Configuration (ratio mds)...", U"djmw", 19980105) INTRO (U"A command that creates a @Configuration object from a @Dissimilarity " "object.") NORMAL (U"The @disparities %d\\'p__%ij_ will be obtained from dissimilarities " "%\\de__%ij_ according to:") FORMULA (U"%d\\'p__%ij_ = %b \\.c %\\de__%ij_") MAN_END MAN_BEGIN (U"Dissimilarity: To Distance...", U"djmw", 20040407) INTRO (U"A command that creates a @Distance object from a selected " "@Dissimilarity object.") ENTRY (U"Settings") TAG (U"##Scale") DEFINITION (U"when on, the @@Dissimilarity: Get additive constant|" "additiveConstant@ is determined, when off the %additiveConstant = 0.") NORMAL (U"dissimilarities are transformed to distances according to:") FORMULA (U" %distance__%ij_ = %dissimilarity__%ij_ + %additiveConstant.") MAN_END MAN_BEGIN (U"Dissimilarity: To Weight", U"djmw", 19980108) INTRO (U"Creates an object of type @Weight for each selected @Dissimilarity " "object.") NORMAL (U"The values in the weight matrix will be:") LIST_ITEM (U"%w__%ii_ = 0") LIST_ITEM (U"%w__%ij_ = 1 if %\\de__%ij_ > 0") MAN_END MAN_BEGIN (U"Dissimilarity & Configuration: Draw regression (absolute mds)...", U"djmw", 20040407) INTRO (U"Draws a scatterplot of the dissimilarities %\\de__%ij_ from the " "selected @Dissimilarity object versus @disparities %d\\'p__%ij_ obtained " "from the \"regression\" of distances %d__%ij_ " "from @Configuration on the dissimilarities %\\de__%ij_.") FORMULA (U"%d\\'p__%ij_ = %\\de__%ij_") ENTRY (U"Settings") TAG (U"##Minimum proximity#, ##Maximum proximity#") DEFINITION (U"minimum and maximum values for the proximities (horizontal axis).") TAG (U"##Minimum distance#, ##Maximum distance#") DEFINITION (U"minimum and maximum values for the distances (vertical axis).") TAG (U"##Mark size (mm)#, ##Mark string#") DEFINITION (U"size and kind of the marks in the plot.") TAG (U"##Garnish") DEFINITION (U"when on, draws a bounding box with decoration.") MAN_END MAN_BEGIN (U"Dissimilarity & Configuration: Draw regression (interval mds)...", U"djmw", 20040407) INTRO (U"Draws a scatterplot of the dissimilarities %\\de__%ij_ from the " "selected @Dissimilarity versus @disparities %d\\'p__%ij_ obtained " "from the regression of distances %d__%ij_ " "from @Configuration on the dissimilarities %\\de__%ij_.") FORMULA (U"%d\\'p__%ij_ = %a + %b \\.c %\\de__%ij_,") NORMAL (U"where the values of %a and %b are determined by regression.") ENTRY (U"Settings") TAG (U"##Minimum proximity#, ##Maximum proximity#") DEFINITION (U"minimum and maximum values for the proximities (horizontal axis).") TAG (U"##Minimum distance#, ##Maximum distance#") DEFINITION (U"minimum and maximum values for the distances (vertical axis).") TAG (U"##Mark size (mm)#, ##Mark string#") DEFINITION (U"size and kind of the marks in the plot.") TAG (U"##Garnish") DEFINITION (U"when on, draws a bounding box with decoration.") MAN_END MAN_BEGIN (U"Dissimilarity & Configuration: Draw regression (i-spline mds)...", U"djmw", 20040407) INTRO (U"Draws a scatterplot of the dissimilarities %\\de__%ij_ from the " "selected @Dissimilarity versus @disparities %d\\'p__%ij_ obtained " "from the regression of distances %d__%ij_ from @Configuration on the " "@spline transformed dissimilarities %\\de__%ij_.") ENTRY (U"Settings") TAG (U"##Number of interior knots") DEFINITION (U"determines the number of segments.") TAG (U"##Order of I-spline") DEFINITION (U"The order of the polynomial basis of the I-spline.") TAG (U"##Minimum proximity#, ##Maximum proximity#") DEFINITION (U"minimum and maximum values for the proximities (horizontal axis).") TAG (U"##Minimum distance#, ##Maximum distance#") DEFINITION (U"minimum and maximum values for the distances (vertical axis).") TAG (U"##Mark size (mm)#, ##Mark string#") DEFINITION (U"size and kind of the marks in the plot.") TAG (U"##Garnish") DEFINITION (U"when on, draws a bounding box with decoration.") MAN_END MAN_BEGIN (U"Dissimilarity & Configuration: Draw regression (monotone mds)...", U"djmw", 20040407) INTRO (U"Draws a scatterplot of the dissimilarities %\\de__%ij_ from the " "selected @Dissimilarity versus @disparities %d\\'p__%ij_ obtained " "from the monotone regression of distances %d__%ij_ " "from @Configuration on the dissimilarities %\\de__%ij_.") ENTRY (U"Settings") TAG (U"##Primary or secondary approach to ties") DEFINITION (U"When dissimilarities are equal, i.e., %\\de__%ij_ = %\\de__%kl_ " "the primary approach imposes no conditions on the corresponding distances " "%d__%ij_ and %d__%kl_, while the %secondary approach demands that also " "%d__%ij_ = %d__%kl_.") TAG (U"##Minimum proximity#, ##Maximum proximity#") DEFINITION (U"minimum and maximum values for the proximities (horizontal axis).") TAG (U"##Minimum distance#, ##Maximum distance#") DEFINITION (U"minimum and maximum values for the distances (vertical axis).") TAG (U"##Mark size (mm)#, ##Mark string#") DEFINITION (U"size and kind of the marks in the plot.") TAG (U"##Garnish") DEFINITION (U"when on, draws a bounding box with decoration.") MAN_END MAN_BEGIN (U"Dissimilarity & Configuration: Draw regression (ratio mds)...", U"djmw", 20040407) INTRO (U"Draws a scatterplot of the dissimilarities %\\de__%ij_ from the " "selected @Dissimilarity versus @disparities %d\\'p__%ij_ obtained " "from the \"regression\" of distances %d__%ij_ " "from @Configuration on the dissimilarities %\\de__%ij_.") FORMULA (U"%d\\'p__%ij_ = %b \\.c %\\de__%ij_,") NORMAL (U"where the value of %b is determined by regression.") ENTRY (U"Settings") TAG (U"##Minimum proximity#, ##Maximum proximity#") DEFINITION (U"minimum and maximum values for the proximities (horizontal axis).") TAG (U"##Minimum distance#, ##Maximum distance#") DEFINITION (U"minimum and maximum values for the distances (vertical axis).") TAG (U"##Mark size (mm)#, ##Mark string#") DEFINITION (U"size and kind of the marks in the plot.") TAG (U"##Garnish") DEFINITION (U"when on, draws a bounding box with decoration.") MAN_END MAN_BEGIN (U"Dissimilarity & Configuration: Draw Shepard diagram...", U"djmw", 20040407) INTRO (U"Draws the Shepard diagram. This is a scatterplot of the " "dissimilarities from the @Dissimilarity object versus distances (as " "calculated from the @Configuration).") ENTRY (U"Settings") TAG (U"##Minimum proximity#, ##Maximum proximity#") DEFINITION (U"minimum and maximum values for the proximities (horizontal axis).") TAG (U"##Minimum distance#, ##Maximum distance#") DEFINITION (U"minimum and maximum values for the distances (vertical axis).") TAG (U"##Mark size (mm)#, ##Mark string#") DEFINITION (U"size and kind of the marks in the plot.") TAG (U"##Garnish") DEFINITION (U"when on, draws a bounding box with decoration.") MAN_END MAN_BEGIN (U"Dissimilarity & Configuration: Get stress (absolute mds)...", U"djmw", 19980119) INTRO (U"A command to obtain the @stress value for the selected @Dissimilarity " "and @Configuration object.") ENTRY (U"Behaviour") NORMAL (U"Stress formula's are #dependent of the scale of the Configuration: " "you will get #another stress value if you had pre-multiplied the " "selected Configuration with any number greater than zero.") MAN_END MAN_BEGIN (U"Dissimilarity & Configuration: Get stress (interval mds)...", U"djmw", 19980119) INTRO (U"A command to obtain the @stress value for the selected @Dissimilarity " "and @Configuration object.") ENTRY (U"Behaviour") NORMAL (U"We use stress formula's that are independent of the scale of the " "Configuration: you would have got the same stress value if you had " "pre-multiplied the selected Configuration with any number greater " "than zero.") MAN_END MAN_BEGIN (U"Dissimilarity & Configuration: Get stress (i-spline mds)...", U"djmw", 19980119) INTRO (U"A command to obtain the @stress value for the selected @Dissimilarity " "and @Configuration object.") ENTRY (U"Behaviour") NORMAL (U"We use stress formula's that are independent of the scale " "of the Configuration: you would have got the same stress value if " "you had pre-multiplied the selected Configuration with any number " "greater than zero.") MAN_END MAN_BEGIN (U"Dissimilarity & Configuration: Get stress (monotone mds)...", U"djmw", 19980119) INTRO (U"A command to obtain the @stress value for the selected @Dissimilarity " "and @Configuration object.") ENTRY (U"Behaviour") NORMAL (U"We use stress formula's that are independent of the scale " "of the Configuration: you would have got the same stress value if " "you had pre-multiplied the selected Configuration with any number " "greater than zero.") MAN_END MAN_BEGIN (U"Dissimilarity & Configuration: Get stress (ratio mds)...", U"djmw", 19980119) INTRO (U"A command to obtain the @stress value for the selected @Dissimilarity " "and @Configuration object.") ENTRY (U"Behaviour") NORMAL (U"We use stress formula's that are independent of the scale " "of the Configuration: you would have got the same stress value if " "you had pre-multiplied the selected Configuration with any number " "greater than zero.") MAN_END MAN_BEGIN (U"Dissimilarity & Configuration: To Configuration (absolute mds)...", U"djmw", 19980119) INTRO (U"A command that creates a @Configuration object from a @Dissimilarity " "object. The selected Configuration object serves as a starting " "configuration for the minimization process.") MAN_END MAN_BEGIN (U"Dissimilarity & Configuration: To Configuration (interval mds)...", U"djmw", 19980119) INTRO (U"A command that creates a @Configuration object from a @Dissimilarity " "object. The selected Configuration object serves as a starting " "configuration for the minimization process.") MAN_END MAN_BEGIN (U"Dissimilarity & Configuration: To Configuration (i-spline mds)...", U"djmw", 19980119) INTRO (U"A command that creates a @Configuration object from a @Dissimilarity " "object. The selected Configuration object serves as a starting " "configuration for the minimization process.") MAN_END MAN_BEGIN (U"Dissimilarity & Configuration: To Configuration (kruskal)...", U"djmw", 19971201) INTRO (U"A command to fit an optimal @Configuration for the selected " "@Dissimilarity object. The selected @Configuration will be used as the " "starting configuration in the kruskal analysis.") MAN_END MAN_BEGIN (U"Dissimilarity & Configuration: To Configuration (monotone mds)...", U"djmw", 19980119) INTRO (U"A command that creates a @Configuration object from a @Dissimilarity " "object. The selected Configuration object serves as a starting " "configuration for the minimization process.") MAN_END MAN_BEGIN (U"Dissimilarity & Configuration: To Configuration (ratio mds)...", U"djmw", 19980119) INTRO (U"A command that creates a @Configuration object from a @Dissimilarity " "object. The selected Configuration object serves as a starting " "configuration for the minimization process.") MAN_END MAN_BEGIN (U"Dissimilarity & Configuration & Weight: Get stress...", U"djmw", 20040407) INTRO (U"A command that calculates the @stress between distances %d__%ij_ " "derived from the selected @Configuration object and @disparities " "%d\\'p__%ij_ derived from the selected @Dissimilarity object. " "With the selected @Weight object the evaluation of the influence " "of each dissimilarity on stress can be influenced.") ENTRY (U"Settings") LIST_ITEM (U"%%Normalized stress%, %%Kruskal's stress-1%, %%Kruskal's " "stress-2% or %Raw stress%") ENTRY (U"Behaviour") NORMAL (U"Except for %absolute %mds, we us stress formula's that are " "independent of the scale of the Configuration (see @stress): you would " "have got the same stress value if you had pre-multiplied the selected " "Configuration with any number greater than zero.") MAN_END MAN_BEGIN (U"Dissimilarity & Configuration & Weight: To Configuration...", U"djmw", 20040407) INTRO (U"A command that creates a @Configuration object from a @Dissimilarity " "object. With the selected @Weight object the influence of each " "dissimilarity on @stress can be influenced. The selected Configuration " "object serves as a starting configuration for the minimization process.") ENTRY (U"Settings") LIST_ITEM (U"\\bu @@Dissimilarity: To Configuration (monotone mds)...") LIST_ITEM (U"\\bu @@Dissimilarity: To Configuration (i-spline mds)...") LIST_ITEM (U"\\bu @@Dissimilarity: To Configuration (interval mds)...") LIST_ITEM (U"\\bu @@Dissimilarity: To Configuration (ratio mds)...") LIST_ITEM (U"\\bu @@Dissimilarity: To Configuration (absolute mds)...") MAN_END MAN_BEGIN (U"Dissimilarity & Weight: To Configuration...", U"djmw", 20040407) INTRO (U"A command that creates a @Configuration object from a @Dissimilarity " "object. With the selected @Weight object the influence of each " "dissimilarity on @stress can be influenced.") ENTRY (U"Settings") NORMAL (U"May be different and depend on the representation function, i.e. " "the scale of measurement.") LIST_ITEM (U"\\bu @@Dissimilarity: To Configuration (monotone mds)...") LIST_ITEM (U"\\bu @@Dissimilarity: To Configuration (i-spline mds)...") LIST_ITEM (U"\\bu @@Dissimilarity: To Configuration (interval mds)...") LIST_ITEM (U"\\bu @@Dissimilarity: To Configuration (ratio mds)...") LIST_ITEM (U"\\bu @@Dissimilarity: To Configuration (absolute mds)...") MAN_END MAN_BEGIN (U"Dissimilarity & Weight: To Configuration...", U"djmw", 20040407) INTRO (U"A command that creates a @Configuration object from a @Dissimilarity " "object. With the selected @Weight object the influence of each " "dissimilarity on @stress can be influenced.") ENTRY (U"Settings") NORMAL (U"May be different and depend on the representation function, i.e. the scale of measurement.") LIST_ITEM (U"\\bu @@Dissimilarity: To Configuration (monotone mds)...") LIST_ITEM (U"\\bu @@Dissimilarity: To Configuration (i-spline mds)...") LIST_ITEM (U"\\bu @@Dissimilarity: To Configuration (interval mds)...") LIST_ITEM (U"\\bu @@Dissimilarity: To Configuration (ratio mds)...") LIST_ITEM (U"\\bu @@Dissimilarity: To Configuration (absolute mds)...") MAN_END MAN_BEGIN (U"Distance", U"djmw", 19971124) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"An object of type Distance represents distances between objects in a metrical space.") NORMAL (U"Creation") LIST_ITEM (U"\\bu @@Confusion: To Dissimilarity (pdf)...") LIST_ITEM (U"\\bu @@Dissimilarity: To Distance...") MAN_END MAN_BEGIN (U"Distance: To Configuration (indscal)...", U"djmw", 19971124) INTRO (U"Perform an @@INDSCAL analysis@ on the selected object(s) of type @Distance that " "results in a @Configuration and a @Salience object.") MAN_END MAN_BEGIN (U"Distance: To Configuration (ytl)...", U"djmw", 19971124) INTRO (U"A command that creates one @Configuration and one @Salience object " "from a collection of one or more @Distance objects.") NORMAL (U"This Configuration and Salience object normally serve as starting points " "for an @@individual difference scaling@ such as an @@INDSCAL analysis@.") NORMAL (U"The algorithm is ddescribedin @@Young, Takane & Lewyckyj (1978)@.") MAN_END MAN_BEGIN (U"Distance: To ScalarProduct...", U"djmw", 20040407) INTRO (U"A command that creates a @ScalarProduct for each selected @Distance.") ENTRY (U"Setting") TAG (U"##Make sum of squares equal 1.0") DEFINITION (U"when selected, the elements in the resulting matrix part will be scaled such that " "the sum of all the squared elements in the matrix equals 1.0.") ENTRY (U"Algorithm") NORMAL (U"ScalarProduct entries %b__%ij_ are created from distances %d__%ij_ bij double centering " "the matrix with elements \\--1/2 %d__%ij_^2, i.e.,") FORMULA (U"%b__%ij_= \\--1/2(%d__%ij_^2 \\-- %d__%\\.cj_^2 \\-- %d__%i\\.c_^2 + %d__%\\.c\\.c_^2),") NORMAL (U"where the dot (\\.c) means averaging over that dimension.") MAN_END MAN_BEGIN (U"Distance & Configuration: Draw scatter diagram...", U"djmw", 19971201) MAN_END MAN_BEGIN (U"Distance & Configuration: Get VAF...", U"djmw", 19971201) INTRO (U"Calculates the \"%%variance accounted for%\" from the selected collection of @Distance objects and the " "selected @Configuration. The optimal @Salience necessary for the calculation " "will be inferred from the selected Distance and Configuration objects.") MAN_END MAN_BEGIN (U"Distance & Configuration: To Configuration (indscal)...", U"djmw", 19971201) INTRO (U"Performs an @@INDSCAL analysis@ on the selected objects of type @Distance and calculates " "a @Configuration from them. Uses the selected Configuration object as the initial Configuration in " "the iteration process.") MAN_END MAN_BEGIN (U"Distance & Configuration & Salience: Get VAF...", U"djmw", 19971201) INTRO (U"Calculates the \"variance accounted for\" from the selected collection " "of @Distance objects, the " "selected @Configuration and the selected #Salience.") MAN_END MAN_BEGIN (U"Distance & Configuration & Salience: To Configuration " "(indscal)...", U"djmw", 19971201) INTRO (U"A command that creates a new @Configuration from the selected " "collection of @Distance objects, the selected @Configuration and the " "selected #Salience. The selected Configuration and Salience " "serve as start values for the @@INDSCAL analysis@.") MAN_END MAN_BEGIN (U"individual difference scaling", U"djmw", 19970502) INTRO (U"The purpose of individual difference scaling is to represent objects, " "whose dissimilarities are given, as points in a metrical space. " "The distances in the space should be in accordance with the " "dissimilarities as well as is possible. Besides the configuration a " "@Salience matrix is calculated.") NORMAL (U"The basic Euclidean model is:") LIST_ITEM (U"%\\de__%ijk_ \\~~ (\\su__%s=1..%r_ %w__%ks_(%x__%is_ \\-- " "%x__%js_)^2)^^1/2^") NORMAL (U"Here \\de__%ijk_ is the (known) dissimilarity between %objects %i and " "%j, as measured on %data %source %k. The %x's are the %coordinates of " "the objects in an %r-dimensional space and the %w's are weights or " "saliences. Because straight minimization of the expression above " "is difficult, one applies transformations on this expression. " "Squaring both sides gives the model:") LIST_ITEM (U"%\\de^2__%ijk_ \\~~ \\su__%s=1..%r_ %w__%ks_(%x__%is_ \\-- " "%x__%js_)^2") NORMAL (U"and the corresponding least squares loss function:") LIST_ITEM (U"\\su__%k=1..%numberOfSources_ \\su__%i=1..%numberOfPoints_ " "\\su__%j=1..%numberOfPoints_ (%\\de^2__%ijk_ \\-- %d^2__%ijk_)^2") NORMAL (U"This loss function is minimized in the (ratio scale option of the) " "#ALSCAL program of @@Takane, Young & de Leeuw (1976)@.") NORMAL (U"The transformation used by @@Carroll & Chang (1970)@ in the INDSCAL " "model, transforms the data from each source into scalar products " "of vectors. For the dissimilarities:") LIST_ITEM (U"%\\be__%ijk_ = \\--{ %\\de^2__%ijk_ \\-- %\\de^2__%i.%k_ \\-- " "%\\de^2__.%jk_ + %\\de^2__..%k_ } / 2,") NORMAL (U"where dots replacing indices indicate averaging over the range of " "that index. In the same way for the distances:") LIST_ITEM (U"%z__%ijk_ = \\--{ %d^2__%ijk_ \\-- %d^2__%i.%k_ \\-- %d" "^2__%.%jk_ + %d^2__%..%k_ } / 2.") LIST_ITEM (U"%\\be__%ijk_ \\~~ %z__%ijk_ = \\su__%s=1..%numberOfDimensions_ " "%w__%ks_ %x__%is_ %x__%js_") NORMAL (U"Translated into matrix algebra, the equation above translates to:") LIST_ITEM (U"%B__%k_ \\~~ %Z__%k_ = %X %W__%k_ %X\\'p,") NORMAL (U"where %X is a %numberOfPoints \\xx %numberOfDimensions configuration " "matrix, %W__%k_, a non-negative %numberOfDimensions \\xx " "%numberOfDimensions matrix with weights, and %B__%k_ " "the %k^^th^ slab of %\\be__%ijk_.") NORMAL (U"This translates to the following INDSCAL loss function:") FORMULA (U"%f(%X, %W__1_,..., %W__%numberOfSources_) = " "\\su__%k=1..%numberOfSources_ | %B__%k_ \\-- %X%W__%k_%X\\'p |^2") NORMAL (U"") MAN_END MAN_BEGIN (U"INDSCAL analysis", U"djmw", 20120306) INTRO (U"A method for @@individual difference scaling@ analysis in P\\s{RAAT}.") NORMAL (U"An INDSCAL analysis can be performed on objects of type Distance.") NORMAL (U"If you start with @Dissimilarity objects you first have to transform " "them to Distance objects.") LIST_ITEM (U"\\bu @@Dissimilarity: To Distance...@") NORMAL (U"If you start with a @Confusion you can use:") LIST_ITEM (U"\\bu @@Confusion: To Dissimilarity (pdf)...@") ENTRY (U"Examples") LIST_ITEM (U"\\bu @@Distance: To Configuration (indscal)...@") DEFINITION (U"Perform an INDSCAL analysis on one or more objects of type " "@Distance to calculate a @Configuration.") LIST_ITEM (U"\\bu @@Distance & Configuration: To Configuration (indscal)...@") DEFINITION (U"Perform an INDSCAL analysis on one or more objects of type " "@Distance to calculate a @Configuration. Use the selected Configuration " "object as the initial Configuration in the iteration process.") ENTRY (U"Algorithm") NORMAL (U"The function to be minimized in INDSCAL is the following:") FORMULA (U"%f(%X, %W__1_,..., %W__%numberOfSources_) = " "\\su__%i=1..%numberOfSources_ |%S__%i_ \\-- %XW__%i_%X\\'p|^2") NORMAL (U"where %X an unknown %numberOfPoints x %numberOfDimensions " "configuration matrix, the %W__%i_ are %numberOfSources unknown " "diagonal %numberOfDimensions x %numberOfDimensions matrices with weights, " "often called saliences, and the %S__%i_ are known symmetric " "matrices with scalar products of dimension %numberOfPoints x " "%numberOfPoints.") NORMAL (U"In the absence of an algorithm that minimizes %f, @@Carroll & " "Chang (1970)@ resorted to the @CANDECOMP algorithm, which instead of the " "function given above minimizes the following function:") FORMULA (U"%g(%X, %Y, %W__1_,..., %W__%numberOfSources_) = " "\\su__%i=1..%numberOfSources_ |%S__%i_ \\-- %XW__%i_%Y\\'p|^2.") NORMAL (U"Carroll & Chang claimed that for most practical circumstances %X " "and %Y converge to matrices that will be columnwise proportional. " "However, INDSCAL does not only require symmetry of the solution, " "but also non-negativity of the weights. Both these aspects cannot be " "guaranteed with the CANDECOMP algorithm.") NORMAL (U"@@Ten Berge, Kiers & Krijnen (1993)@ describe an algorithm that " "automatically satisfies symmetry because it solves %f directly, and, " "also, can guarantee non-negativity of the weights. " "This algorithm proceeds as follows:") NORMAL (U"Let #%x__%h_ be the %h-th column of %X. We then write the function %f above as:") FORMULA (U"%f(#%x__%h_, %w__1%h_, ..., %w__%numberOfSources %h_) = \\su__%i=1.." "%numberOfSources_ |%S__%ih_ \\-- #%x__%h_%w__%ih_#%x\\'p__%h_|^2,") NORMAL (U"with %S__%ih_ defined as:") FORMULA (U"%S__%ih_ = (%S__%i_ - \\su__%j\\=/%h, %j=1..%numberOfDimensions_ " "#%x__%j_%w__%ij_#%x\\'p__%j_).") NORMAL (U"Without loss of generality we may require that") FORMULA (U"#%x\\'p__%h_#%x__%h_ = 1") NORMAL (U"Minimizing %f over #%x__%h_ is equivalent to minimizing") FORMULA (U"\\su__%i=1..%numberOfSources_ |%S__%ih_|^2 \\-- 2tr \\su " "%S__%ih_#%x__%h_%w__%ih_#%x\\'p__%h_ + \\su %w^2__%ih_") NORMAL (U"This amounts to maximizing") FORMULA (U"%g(#%x__%h_) = #%x\\'p__%h_(\\su %w__%ih_%S__%ih_)#%x__%h_") NORMAL (U"subject to #%x\\'p__%h_#%x__%h_ = 1. The solution for #%x__%h_ is " "the dominant eigenvector of (\\su %w__%ih_%S__%ih_), " "which can be determined with the power method (see @@Golub & van Loan " "(1996)@). The optimal value " "for the %w__%ih_, given that all other parameters are fixed:") FORMULA (U"%w__%ih_ = #%x\\'p__%h_%S__%ih_#%x__%h_") NORMAL (U"In an alternating least squares procedure we may update columns of " "%X and the diagonals of the %W matrices in any sensible order.") MAN_END MAN_BEGIN (U"Kruskal analysis", U"djmw", 19971201) INTRO (U"One of the @@MDS models@ in P\\s{RAAT}.") NORMAL (U"You can perform a Kruskal-type multidimensional scaling only on " "objects of type @Dissimilarity. Objects of other types first have to " "be converted to objects of Dissimilarity type.") ENTRY (U"Example") NORMAL (U"Convert a @Dissimilarity object into a @Configuration object.") LIST_ITEM (U"\\bu @@Dissimilarity: To Configuration (monotone mds)...@") DEFINITION (U"choose appropriate parameters") LIST_ITEM (U"\\bu @@Dissimilarity & Configuration: Get stress (monotone mds)...@") DEFINITION (U"choose stress-1 to obtain the value for the @stress according " "to Kruskal.") ENTRY (U"How to get started") NORMAL (U"You can create an example @Dissimilarity object with the @@Create " "letter R example...@ button which you can find under the " "##Multidimensional scaling# option in the #New menu.") MAN_END MAN_BEGIN (U"MDS models", U"djmw", 20101109) INTRO (U"Multidimensional scaling (MDS) models are defined by specifying " "how given @Dissimilarity data, %\\de__%ij_, are " "mapped into distances of an %m-dimensional MDS @Configuration %#X. " "The mapping is specified by a %%representation function%, %f : " "%\\de__%ij_ \\-> %d__%ij_(#X), which specifies how " "dissimilarities should be related to the distances. The MDS analysis " "tries to find the configuration (in a given dimensionality) whose " "distances satisfy %f as closely as possible. " "This closeness is quantified by a badness-of-fit measure which is often " "called @stress.") ENTRY (U"Representation functions") NORMAL (U"In the application of MDS we try to find a configuration #X such that " "the following relations are satisfied as well as possible:") FORMULA (U"%f(%\\de__%ij_) \\~~ %d__%ij_(#X)") NORMAL (U"The numbers that result from applying %f on %\\de__%ij_ are sometimes " "called @disparities %d\\'p__%ij_. In most applications of MDS, besides " "the configuration #X, also the function %f is not " "completely specified, i.e., the exact parameters of %f are unknown and " "must also be estimated during the analysis. If no particular %f can be " "derived from a theoretical model, one often restricts %f to a particular " "class of functions on the basis of the scale level of the dissimilarity " "data. If the disparities are related to the proximities by a specific " "parametric function we speak of %metric MDS otherwise we speak of " "%ordinal or %%non-metric% MDS.") LIST_ITEM (U"\\bu %absolute mds: %d\\'p__%ij_ = \\de__%ij_") DEFINITION (U"No parameters need to be estimated.") LIST_ITEM (U"\\bu %ratio mds: %d\\'p__%ij_ = %b \\.c \\de__%ij_,") DEFINITION (U"where the value of %b can be estimated by a linear regression of " "%d__%ij_ on %\\de__%ij_.") LIST_ITEM (U"\\bu %interval mds: %d\\'p__%ij_ = %a + %b \\.c %\\de__%ij_,") DEFINITION (U"where the values of %a and %b can be estimated by a linear " "regression of %d__%ij_ on %\\de__%ij_.") LIST_ITEM (U"\\bu %i-spline mds: %d\\'p__%ij_ = %i-spline(%\\de__%ij_),") DEFINITION (U"where %i-spline(\\.c) is a smooth monotonically increasing " "@spline curve. The conceptual idea is that it is not possible to map " "all dissimilarities into disparities by one simple function.") LIST_ITEM (U"\\bu %monotone mds: %d\\'p__%ij_ = %monotone(\\de__%ij_),") DEFINITION (U"where %monotone(\\.c) is restricted to be a monotonic function " "that preserves the order of the dissimilarities:") FORMULA (U"if %\\de__%ij_ < %\\de__%kl_, then %d__%ij_(#X) < %d__%kl_(#X)") DEFINITION (U"If %\\de__%ij_ = %\\de__%kl_ and no particular constraint is involved for %d__%ij_(#X) " "and %d__%kl_(#X) this is referred to as the %%primary approach% to ties. The %%secondary " "approach% to ties requires that if %\\de__%ij_ = %\\de__%kl_, then also %d__%ij_(#X) = %d__%kl_(#X).") NORMAL (U"More information on all aspects of multidimensional scaling can be found in: " "@@Borg & Groenen (1997)@ and @@Ramsay (1988)@.") NORMAL (U"The most important object types used in Praat for MDS and the conversions between these types are " "shown in the following figure.") PICTURE (6, 6, drawMDSClassRelations) MAN_END MAN_BEGIN (U"Measurement levels", U"djmw", 20151014) INTRO (U"According to the measurement theory of @@Stevens (1951)@, there are four measurement levels, namely " "#Nominal, #Ordinal, #Interval and #Ratio. In the light of multidimensional scaling, the first " "two levels, Nominal and Ordinal, are often called %non-%metric. The last two are %metric.") MAN_END MAN_BEGIN (U"Multidimensional scaling", U"djmw", 20140117) INTRO (U"This tutorial describes how you can use P\\s{RAAT} to " "perform ##M#ulti ##D#imensional ##S#caling (MDS) analysis.") NORMAL (U"MDS helps us to represent %dissimilarities between objects as " "%distances in a %%Euclidean space%. In effect, the more dissimilar two " "objects are, the larger the distance between the objects in the Euclidean " "space should be. The data types in P\\s{RAAT} that " "incorporate these notions are @Dissimilarity, @Distance and " "@Configuration.") NORMAL (U"In essence, an MDS-analysis is performed when you select a " "Dissimilarity object and choose one of the ##To Configuration (xxx)...# " "commands to obtain a Configuration object. In the above, method (xxx) " "represents on of the possible @@MDS models|multidimensional scaling " "models@.") ENTRY (U"MDS-analysis") NORMAL (U"Let us first create a Dissimilarity object. You can for example " "@@Dissimilarity|create a Dissimilarity object from a file@. Here we " "will the use the Dissimilarity object from @@Create letter R example...|" "the letter R example@. We have chosen the default value (32.5) for the " "(uniform) noise range. Note that this may result in substantial " "distortions between the dissimilarities and the distances.") NORMAL (U"Now you can do the following, for example:") NORMAL (U"Select the Dissimilarity and choose @@Dissimilarity: To Configuration " "(monotone mds)...|To Configuration (monotone mds)...@, and you perform " "a @@Kruskal analysis|kruskal@-like multidimensional scaling which " "results in a new " "Configuration object. (This Configuration could subsequently be used as " "the starting Configuration for a new MDS-analysis!).") NORMAL (U"Select the Configuration and choose @@Configuration: Draw...|Draw...@ " "and the following picture might result.") PICTURE (4.0, 4.0, drawLetterRConfigurationExample2) NORMAL (U"The following script summarizes:") CODE (U"dissimilarity = Create letter R example: 32.5") CODE (U"configuration = To Configuration (monotone mds): 2, \"Primary approach\", 0.00001, 50, 1") CODE (U"Draw: 1, 2, -0.8, 1.2, -0.8, 0.7, \"yes\"") ENTRY (U"Obtaining the stress value") NORMAL (U"Select the Dissimilarity and the Configuration together and query for " "the @stress value with: " "@@Dissimilarity & Configuration: Get stress (monotone mds)...|" "Get stress (monotone mds)...@. ") NORMAL (U"The following script summarizes:") CODE (U"selectObject: dissimilarity, configuration") CODE (U"Get stress (monotone mds): \"Primary approach\", \"Kruskals's " "stress-1\"") ENTRY (U"The Shepard diagram") NORMAL (U"Select the Dissimilarity and the Configuration together to " "@@Dissimilarity & Configuration: Draw Shepard diagram...|" "draw the Shepard diagram@.") PICTURE (4.0, 4.0, drawLetterRShepard) NORMAL (U"The following script summarizes:") CODE (U"selectObject: dissimilarity, configuration") CODE (U"Draw Shepard diagram: 0, 200, 0, 2.2, 1, \"+\", \"yes\"") ENTRY (U"The (monotone) regression") NORMAL (U"Select the Dissimilarity and the Configuration together to " "@@Dissimilarity & Configuration: Draw regression (monotone mds)...|" "draw the monotone regression@ of distances on dissimilarities.") PICTURE (4.0, 4.0, drawLetterRRegression) NORMAL (U"The following script summarizes:") CODE (U"selectObject: dissimilarity, configuration") CODE (U"Draw monotone regresion: \"Primary approach\", 0, 200, 0, 2.2, 1, \"+\", \"yes\"") NORMAL (U"When you enter %noiseRange = 0 in the form for the letter #R, perfect " "reconstruction is possible. The Shepard diagram then will show " "a perfectly smooth monotonically increasing function.") ENTRY (U"Weighing the dissimilarities") NORMAL (U"When you can't have equal confidence in all the number in the " "Dissimilarity object, you can give different weights to these numbers by " "associating a @Weight object with the Dissimilarity object. " "An easy way to do this is to select the Dissimilarity object and first " "choose @@Dissimilarity: To Weight|To Weight@. Then you might change the " "individual weights in the Weight object with the @@TableOfReal: Set " "value...| Set value...@ command (remember: make %w__%ij_ = %w__%ji_).") NORMAL (U"The following script summarizes:") CODE (U"selectObject: dissimilarity") CODE (U"weight = To Weight") CODE (U"! Change [i][j] and [j][i] cells in the Weight object") CODE (U"Set value: i, j, val") CODE (U"Set value: j, i, val") CODE (U"...") CODE (U"! now we can do a weighed analysis.") CODE (U"selectObject: dissimilarity, weight") CODE (U"To Configuration (monotone mds): 2, \"Primary approach\", 0.00001, 50, 1)") NORMAL (U"You can also query the @stress values with three objects selected. " "The following script summarizes:") CODE (U"selectObject: dissimilarity, weight, configuration") CODE (U"Get stress (monotone mds): \"Primary approach\", \"Kruskals's stress-1\"") ENTRY (U"Using a start Configuration") NORMAL (U"You could also use a Configuration object as a starting " "configuration in the minimization process. " "Let's assume that you are not satisfied with the stress value from the " "Configuration object that you obtained in the previous analysis. " "You can than use this Configuration object as a " "starting point for further analysis:") NORMAL (U"The following script summarizes:") CODE (U"selectObject: dissimilarity, configuration, weight") CODE (U"To Configuration (monotone mds): 2, \"Primary approach\", 0.00001, 50, 1") ENTRY (U"Multiple Dissimilarity's (INDSCAL)") NORMAL (U"When you have multiple Dissimilarity objects you can also perform " "@@individual difference scaling@ (often called @@INDSCAL analysis@). ") NORMAL (U"As an example we can use an @@Create INDSCAL Carroll & Wish " "example...| example taken from Carrol & Wish@. " "Because INDSCAL only works on metrical data, we cannot use Dissimilarity " "objects directly. We have to transform them first @@Dissimilarity: To " "Distance...|to Distance@ objects.") NORMAL (U"This type of analysis on multiple objects results in two new objects: " "a Configuration and a @Salience.") MAN_END MAN_BEGIN (U"Procrustes", U"djmw", 20010927) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"An object of type Procrustes represents the special @@AffineTransform|" "affine transform@ that consists of a " "combination of a translation, a shape preserving transformation and a scaling (this scaling is often called %dilation). " "Because the transformation has to be shape preserving, only a combination of a rotation and a reflection is allowed. " "A configuration matrix #%X is transformed in the following way to a new configuration matrix #%Y: ") FORMULA (U"#%Y = %s #%X #%T+ #1#%t',") NORMAL (U"where %s is the scaling factor, #%T is the shape preserving transformation matrix, #%t is the translation vector, " "and #1 is the vector with only ones as its elements.") NORMAL (U"For more information about the Procrustes transform and its algorithm " "see chapter 19 in @@Borg & Groenen (1997)@.") MAN_END MAN_BEGIN (U"Procrustes transform", U"djmw", 19980119) INTRO (U"A transformation that only uses a combination of a translation, " "a scaling and a rigid transformation to transform one Configuration such that it " "matches as closely as possible another Configuration. ") NORMAL (U"We speak of %%orthogonal Procrustes transform% when only the rigid " "transformation is allowed but no scaling or translation.") NORMAL (U"For more information about the Procrustes transform and its algorithm " "see chapter 19 in @@Borg & Groenen (1997)@.") MAN_END MAN_BEGIN (U"Proximity", U"djmw", 19961008) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"An object of type #Proximity represents proximities between objects.") ENTRY (U"Inside a Proximity") NORMAL (U"With @Inspect you will see the following attributes:") TAG (U"%numberOfRows, %numberOfColumns") DEFINITION (U"the number of objects (%numberOfRows and %numberOfColumns are " "equal and \\>_1).") TAG (U"%rowLabels, %columnLabels") DEFINITION (U"the names associated with the objects (%rowLabels and " "%columnLabels are equal.") TAG (U"%data [1..%numberOfRows][1..%numberOfColumns]") DEFINITION (U"the proximities between the objects.") MAN_END MAN_BEGIN (U"Salience", U"djmw", 19980112) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"Elements %s__%ij_ in the " "Salience matrix represent the importance of dimension %j (in the " "@Configuration) for data source %i.") ENTRY (U"Commands") NORMAL (U"Creation, as a by-product of:") LIST_ITEM (U"\\bu @@Distance: To Configuration (indscal)...") LIST_ITEM (U"\\bu @@Distance: To Configuration (ytl)...") MAN_END MAN_BEGIN (U"ScalarProduct", U"djmw", 19980125) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"An object of type ScalarProduct represents scalar products %b__%ij_ " "between objects %i and %j in a metrical space.") FORMULA (U"%b__%ij_ = \\su__%k=1..%numberOfDimensions_ %x__%ik_%x__%jk_,") NORMAL (U"where %x__%ik_ and %x__%jk_ are the coordinates of the %k-th " "dimension of points %i and %j, respectively. From this definition one " "can see that scalar products, in contrast to distances, " "do change when the origin is shifted.") NORMAL (U"Creation") LIST_ITEM (U"\\bu @@Distance: To ScalarProduct...@") MAN_END MAN_BEGIN (U"Similarity", U"djmw", 19961008) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"An object of type Similarity represent a one-way " "table of similarities between \"objects\".") ENTRY (U"Commands") NORMAL (U"Creation") LIST_ITEM (U"\\bu @@Confusion: To Similarity...") NORMAL (U"Drawing") LIST_ITEM (U"\\bu ##Draw as numbers...") LIST_ITEM (U"\\bu ##Draw as squares...") NORMAL (U"Query") LIST_ITEM (U"\\bu ##Get column mean (index)...") LIST_ITEM (U"\\bu ##Get column mean (label)...") LIST_ITEM (U"\\bu ##Get column stdev (index)...") LIST_ITEM (U"\\bu ##Get column stdev (label)...") NORMAL (U"Modification") LIST_ITEM (U"\\bu ##Formula...") LIST_ITEM (U"\\bu ##Remove column (index)...") LIST_ITEM (U"\\bu ##Insert column (index)...") LIST_ITEM (U"\\bu ##Set row label (index)...") LIST_ITEM (U"\\bu ##Set row label (label)...") LIST_ITEM (U"\\bu ##Set column label (index)...") LIST_ITEM (U"\\bu ##Set column label (label)...") NORMAL (U"Analysis") LIST_ITEM (U"\\bu @@Similarity: To Dissimilarity...") MAN_END MAN_BEGIN (U"Similarity: To Dissimilarity...", U"djmw", 20040407) INTRO (U"A command that creates a @Dissimilarity from every selected " "@Similarity.") ENTRY (U"Setting") TAG (U"##Maximum dissimilarity") DEFINITION (U"determines the maximum dissimilarity possible. When the default " "value, 0.0, is chchosen%maximumDissimilarity " "is calculated as the maximum element in the Similarity object.") ENTRY (U"Algorithm") NORMAL (U"To obtain dissimilarities we 'reverse' similarities:") FORMULA (U"%%dissimilarity__%ij_ = %maximumDissimilarity \\-- %similarity__%ij_") NORMAL (U"In this way the order of dissimilarities is the reverse of the order " "of the similarities.") MAN_END MAN_BEGIN (U"smacof", U"djmw", 19980119) INTRO (U"Scaling by Majorizing a Complicated Function, the iterative algorithm " "to find an optimal Configuration.") LIST_ITEM (U"1. Initialize") LIST_ITEM (U" 1.a. Get initial Configuration #Z") LIST_ITEM (U" 1.b. Set stress %\\si__%n_^^[0]^ to a very large value.") LIST_ITEM (U" 1.c. Set iteration counter %k = 0") LIST_ITEM (U"2. Increase iteration counter by one: %k = %k + 1") LIST_ITEM (U"3. Calculate distances %d__%ij_(#Z).") LIST_ITEM (U"4. Transform dissimilarities %\\de__%ij_ into disparities " "%d\\'p__%ij_.") LIST_ITEM (U"5. Standardize the disparities so that %\\et__%d\\'p_^2 = " "%n(%n\\--1)/2.") LIST_ITEM (U"6. Compute the Guttman transform #X^^[%k]^ of #Z.") LIST_ITEM (U"7. Compute new distances %d__%ij_(#X^^[%k]^).") LIST_ITEM (U"8. Compute normalized stress %\\si__%n_ (#d\\'p, #X^^[%k]^)") LIST_ITEM (U"9. If |%\\si__%n_^^[%k]^ \\-- %\\si__%n_^^[%k\\--1]^| / %\\si__%n_" "^^[%k\\--1]^ < %\\ep or %k > %maximumNumberOfIterations, then stop") LIST_ITEM (U"10. Set #Z = #X^^[%k]^, and go to 2.") NORMAL (U"This algorithm goes back to @@De Leeuw (1977)@.") MAN_END MAN_BEGIN (U"spline", U"djmw", 20121101) INTRO (U"A spline function %f is a piecewise polynomial function defined on " "an interval [%x__%min_, %x__%max_] " "with specified continuity constraints, i.e., when the interval [%x__%min_," " %x__%max_] is subdivided by points %\\xi__%i_ such that %x__%min_ = " "%\\xi__%1_ < ... < %\\xi__%q_ = %%x__%max_, then within each subinterval " "[%\\xi__%j_, %\\xi__%j+1_) the function is a polynomial %P__%j_ of " "specified degree %k.") NORMAL (U"A %%knot sequence% %t = {%t__1_, ..., %t__%n+%k_}, where %n is the " "number of free parameters that specify the spline function, is derived " "from the %\\xi__%i_ by placing knots at the boundary values %\\xi__%i_ " "according to the order of continuity at that boundary. The most common " "continuity characteristics imposed on %f request that for adjacent " "polynomials the derivatives up to order %k\\--2 match. For example, " "the knot sequence of a spline of order %k for a partition of [%x__%min_," " %%x__%max_] into three intervals (%q = 4) will be %t__1_ = ... = " "%t__%k_ = %x__%min_ (=%\\xi__1_), %t__%k+1_ = %\\xi__2_, %t__%k+2_ = " "%\\xi__3_ , %t__%k+3_ = ... = %t__%k+%k+2_ = %x__%max_ (= %\\xi__4_). " "This is called a %simple knot sequence, because all interior knots are " "simple. The number of free parameters %n for this case obeys a simple " "formula:") FORMULA (U"%n = %numberOfInteriorKnots + %order.") NORMAL (U"With suitable basis functions, for example, the M-spline family " "%M__%i_(%x|%k, %t), %i=1..%n, we can write any spline %f in the form:") FORMULA (U"%f = \\su__%i=1..%n_ %a__%i_%M__%i_,") NORMAL (U"where the %M__%i_ are defined by the following recursive formula's:") FORMULA (U"%M__%i_(%x|1,%t) = 1 / (%t__%i+1_ \\-- %t__%i_), %t__%i_ " "\\<_ %x < %t__%i+1_, 0 otherwise") FORMULA (U"%M__%i_(%x|%k,%t) = %k [(%x\\--%t__%i_)%M__%i_(%x|%k\\--1,%t) + " "(%t__%i+%k_\\--%x)%M__%i+1_(%x|%k\\--1,%t)] / " "((%k\\--1)(%t__%i+%k_\\--%t__%i_))") NORMAL (U"These %M__%i_ are localized because %M__%i_(%x|%k,%t) > 0 only when " "%t__%i_ \\<_ %x < %t__%i+%k_ and zero otherwise. Also, we have \\in" " M__%i_(%x)%dx = 1. Because of this localization a change in coefficient " "%a__%i_ will only effect %f within this interval.") NORMAL (U"The following picture shows an M-spline of order 3 on the interval " "[0, 1], with three interior knots at 0.3, 0.5 and 0.6.") PICTURE (5.0, 5.0, drawMsplineExample) NORMAL (U"Because the M-splines are nonnegative, %monotone splines% can be " "derived from them by %integration:") FORMULA (U"%I__%i_(%x|%k,%t) = \\in__%xmin_^%x %M__%i_(%u|%k,%t) %du") NORMAL (U"Because each %M__%i_(%x|%k, %t) is a piecewise polynomial of degree" " %k\\--1, each %I__%i_ will be of degree %k. Now we can write:") FORMULA (U"%f = \\su__%i=1..%n_ %b__%i_%I__%i_(%x|%k,%t)") NORMAL (U"We can use an M-spline of order %k+1 with a simple knot sequence %t, " "for which %t__%j_ \\<_ x < %t__%j+1_, to put " "the I-spline of order %k into a more convenient form:") FORMULA (U"%I__%i_(%x|%k,%t) = 0, %i > %j") FORMULA (U"%I__%i_(%x|%k,%t) = \\su__%m=%i+1..%j_ (%t__%m+%k+1_\\--" "%t__%m_)%M__%m_(%x|%k+1,%t)/(%k+1), %j\\--%k \\<_ %i \\<_ %j") FORMULA (U"%I__%i_(%x|%k,%t) = 1, %i < %j\\--%k") NORMAL (U"The following figure shows the I-splines that were derived from " "the M-splines above.") PICTURE (5.0, 5.0, drawIsplineExample) NORMAL (U"These spline formula's were taken from @@Ramsay (1988)@ and the " "errors in his I-spline formulas were corrected.") MAN_END MAN_BEGIN (U"stress", U"djmw", 19980108) INTRO (U"A badness-of-fit measure for the entire MDS representation.") NORMAL (U"Several measures exist.") ENTRY (U"Raw stress") FORMULA (U"%\\si__%r_ (#d\\'p, #X) = \\su__%i<%j_ %w__%ij_(%d\\'p__%ij_ \\-- " "%d__%ij_(#X))^2") FORMULA (U"= \\su__%i<%j_ %w__%ij_%d\\'p__%ij_^2 + \\su__%i<%j_ " "%w__%ij_%d__%ij_^2(#X) \\-- " "2 \\su__%i<%j_ %w__%ij_%d\\'p__%ij_%d__%ij_(#X)") FORMULA (U"= %\\et__%d\\'p_^2 + %\\et^2(#X) \\-- 2%\\ro(#d\\'p, #X)") NORMAL (U"where the %d\\'p__%ij_ are the @disparities that are the result " "from the transformation of the dissimilarities, i.e., %f(%\\de__%ij_). " "Raw stress can be misleading because it is dependent on the normalization " "of the disparities. The following measure tries to circumvent this " "inconvenience.") ENTRY (U"Normalized stress") FORMULA (U"%\\si__%n_ = \\si__%r_ / %\\et__%d\\'p_^2") NORMAL (U"This is the stress function that we minimize by iterative " "majorization. It goes back to @@De Leeuw (1977)@.") ENTRY (U"Kruskal's stress-1") FORMULA (U"%\\si__1_ = \\Vr (\\su__%i<%j_ %w__%ij_(%d\\'p__%ij_ \\-- " "%d__%ij_(#X))^2 / \\su__%i<%j_ %w__%ij_%d__%ij_^2(#X))^^1/2^") NORMAL (U"In this measure, which is due to @@Kruskal (1964)@, stress is " "expressed in relation to the size of #X.") ENTRY (U"Kruskal's stress-2") FORMULA (U"%\\si__2_ = \\Vr (\\su__%i<%j_ %w__%ij_(%d\\'p__%ij_ \\-- " "%d__%ij_(#X))^2 / \\su__%i<%j_ %w__%ij_(%d__%ij_(#X) - " "%averageDistance)^2)^^1/2^.") NORMAL (U"In general, this measure results in a stress value that is " "approximately twice the value for stress-1.") ENTRY (U"Relation between %\\si__1_ and %\\si__n_") NORMAL (U"When we have calculated %\\si__%n_ for Configuration #X, " "disparities #d\\'p and Weight #W we cannot " "directly use #X, #d\\'p and #W to calculate %\\si__1_ because the " "scale of #X is not necessarily optimal " "for %\\si__1_. We allow therefore a scale factor %b > 0 and " "try to calculate %\\si__1_ (#d\\'p, %b #X). We minimize the resulting " "expression for %b and substitute " "the result back into the formula for stress, i.e.,") FORMULA (U"%\\si__1_^2 (#d\\'p, %b #X) = (%\\et__%d\\'p_^2 + %b^2 %\\et^2(#X) " "\\-- 2 %b %\\ro(#d\\'p, #X)) / %b^2 %\\et^2(#X)") FORMULA (U"d%\\si__1_^2 (%b) / d%b == 0, gives") FORMULA (U"%b = %\\et__%d\\'p_^2 / %\\ro") FORMULA (U"%\\si__1_^2 = (1 - %\\ro^2 / (%\\et__%d\\'p_^2\\.c%\\et^2(#X)))") NORMAL (U"This means that %\\si__1_ = \\Vr %\\si__%n_.") ENTRY (U"Relation between %\\si__2_ and %\\si__n_") NORMAL (U"We can do the same trick as before for %\\si__2_:") FORMULA (U"%\\si__2_^2 (#d\\'p, %b #X) = (%\\et__%d\\'p_^2 + %b^2 %\\et^2(#X) " "\\-- 2 %b %\\ro(#d\\'p, #X)) / " "(%b^2 \\su__%i<%j_ %w__%ij_(%d__%ij_(#X) - %averageDistance)^2)") NORMAL (U"From which we derive:") FORMULA (U"%\\si__2_ = \\Vr ((%\\et__%d\\'p_^2 \\.c %\\et^2(#X) - " "%\\ro^2(#d\\'p, #X)) / (%\\et__%d\\'p_^2 \\.c \\su__%i<%j_ " "%w__%ij_(%d__%ij_(#X) - %averageDistance)^2))") MAN_END MAN_BEGIN (U"TableOfReal: Centre columns", U"djmw", 19980422) INTRO (U"A command that centres the columns in the selected @TableOfReal " "objects.") ENTRY (U"Algorithm") NORMAL (U"The new values in the table, %x\\'p__%ij_, will be:") FORMULA (U"%x\\'p__%ij_ = %x__%ij_ \\-- %x__\\.c%j_,") NORMAL (U"where") FORMULA (U"%x__\\.c%j_ = \\su__%i=1..%numberOfRows_ %x__%ij_ / %numberOfRows,") NORMAL (U"the average of column %j.") MAN_END MAN_BEGIN (U"TableOfReal: Centre rows", U"djmw", 19980422) INTRO (U"A command that centres the rows in the selected @TableOfReal objects.") ENTRY (U"Algorithm") NORMAL (U"The new values in the table, %x\\'p__%ij_, will be:") FORMULA (U"%x\\'p__%ij_ = %x__%ij_ \\-- %x__%i\\.c_,") NORMAL (U"where") FORMULA (U"%x__%i\\.c_ = \\su__%j=1..%numberOfColumns_ %x__%ij_ / " "%numberOfColumns,") NORMAL (U"the average of row %i.") MAN_END MAN_BEGIN (U"TableOfReal: Get table norm", U"djmw", 19980422) INTRO (U"A command that returns the norm of the selected @TableOfReal object.") ENTRY (U"Algorithm") NORMAL (U"Returns: sqrt (\\su__%i=1..%numberOfRows_ \\su__%j=1..%numberOfColumns" "_ %x__%ij_^2).") MAN_END MAN_BEGIN (U"TableOfReal: Normalize columns...", U"djmw", 19980422) INTRO (U"A command that normalizes the columns in the selected @TableOfReal " "objects.") ENTRY (U"Setting") TAG (U"##Norm") DEFINITION (U"determines the sum of the squared elements in each column after " "normalization.") ENTRY (U"Algorithm") NORMAL (U"All elements %x__%ij_ in each column %j=1..%numberOfColumns will be " "multiplied by sqrt (%norm / \\su__%i=1..%numberOfRows_ %x__%ij_^2).") MAN_END MAN_BEGIN (U"TableOfReal: Normalize rows...", U"djmw", 19980422) INTRO (U"A command that normalizes the rows in the selected @TableOfReal " "objects.") ENTRY (U"Setting") TAG (U"##Norm") DEFINITION (U"determines the sum of the squared elements in each row after " "normalization.") ENTRY (U"Algorithm") NORMAL (U"All elements %x__%ij_ in each row %i=1..%numberOfRows will be " "multiplied by sqrt (%norm / \\su__%j=1..%numberOfColumns_ %x__%ij_^2).") MAN_END MAN_BEGIN (U"TableOfReal: Normalize table...", U"djmw", 19980422) INTRO (U"A command that normalizes the elements in the selected @TableOfReal " "objects.") ENTRY (U"Setting") TAG (U"##Norm") DEFINITION (U"determines the sum of the squared elements after normalization.") ENTRY (U"Algorithm") NORMAL (U"All elements %x__%ij_ will be multiplied by " "sqrt (%norm / \\su__%i=1..%numberOfRows_ \\su__%j=1..%numberOfColumns_" " %x__%ij_^2.") MAN_END MAN_BEGIN (U"Weight", U"djmw", 19980108) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"An object of type Weight represents a matrix " "with weights %w__%ij_.") NORMAL (U"An object of type Weight selected together with an onject of type" " @Dissimilarity can be used to make distinctions in the importance of the" " contribution of each individual dissimilarity %\\de__%ij_ to " "@stress and therefore to the final configuration. Weights can be " "used for instance to code for missing values, i.e., take %w__%ij_ = 0 if " "dissimilarity %\\de__%ij_ is missing and %w__%ij_ = 1 if %\\de__%ij_ is" " known.") ENTRY (U"Commands") NORMAL (U"Creation") LIST_ITEM (U"\\bu @@Dissimilarity: To Weight") NORMAL (U"Analysis") NORMAL (U"See @@Dissimilarity & Weight: To Configuration...@ for help on the " "following analysis items: ") LIST_ITEM (U"\\bu ##Dissimilarity & Weight: To Configuration (monotone mds)...") LIST_ITEM (U"\\bu ##Dissimilarity & Weight: To Configuration (i-spline mds)...") LIST_ITEM (U"\\bu ##Dissimilarity & Weight: To Configuration (interval mds)...") LIST_ITEM (U"\\bu ##Dissimilarity & Weight: To Configuration (ratio mds)...") LIST_ITEM (U"\\bu ##Dissimilarity & Weight: To Configuration (absolute mds)...") NORMAL (U"Query") NORMAL (U"See @@Dissimilarity & Configuration & Weight: Get stress...@ for help " "on the following query items: ") LIST_ITEM (U"\\bu ##Dissimilarity & Configuration & Weight: Get stress " "(monotone mds)...") LIST_ITEM (U"\\bu ##Dissimilarity & Configuration & Weight: Get stress " "(i-spline mds)...") LIST_ITEM (U"\\bu ##Dissimilarity & Configuration & Weight: Get stress " "(interval mds)...") LIST_ITEM (U"\\bu ##Dissimilarity & Configuration & Weight: Get stress " "(ratio mds)...") LIST_ITEM (U"\\bu ##Dissimilarity & Configuration & Weight: Get stress " "(absolute mds)...") MAN_END /************ references ***********************************************/ MAN_BEGIN (U"Abramowitz & Stegun (1970)", U"djmw", 19971201) NORMAL (U"M. Abramowitz & I. Stegun (1970): %%Handbook of mathematical " "functions%. New York: Dover Publications.") MAN_END MAN_BEGIN (U"Borg & Groenen (1997)", U"djmw", 19971219) NORMAL (U"I. Borg & P. Groenen (1997): %%Modern multidimensional scaling: " "theory and applications%. Springer.") MAN_END MAN_BEGIN (U"Brokken (1983)", U"djmw", 19980406) NORMAL (U" F.B. Brokken (1983): \"Orthogonal Procrustes rotation maximizing " "congruence.\" %Psychometrika #48: 343\\--352.") MAN_END MAN_BEGIN (U"Cailliez (1983)", U"djmw", 19971201) NORMAL (U" F. Cailliez (1983): \"The analytical solution of the additive " "constant problem.\" %Psychometrika #48, 305-308.") MAN_END MAN_BEGIN (U"Carroll & Chang (1970)", U"djmw", 19971201) NORMAL (U"J.D. Carroll & J.-J. Chang, (1970): \"Analysis of Individual " "Differences in Multidimensional scaling via an N-way generalization of " "\"Eckart-Young\" Decomposition.\" %Psychometrika #35: 283\\--319.") MAN_END MAN_BEGIN (U"Carroll & Wish (1974)", U"djmw", 19971201) NORMAL (U"J.D. Carroll & M. Wish, (1974): \"Models and methods for three-way " "multidimensional scaling.\" In D.H. Krantz, R.C. Atkinson, R.D. Luce & " "P. Suppes (eds.): %%Contemporary developments in mathematical psychology: " "Vol. 2 Measurement, psychophysics, and neural " "information processing%, 283\\--319. New York: Academic Press.") MAN_END MAN_BEGIN (U"De Leeuw (1977)", U"djmw", 19971201) NORMAL (U"J. de Leeuw (1977): \"Applications of convex analysis to " "multidimensional scaling.\" In J.R. Barra, F. Brodeau, G. Romier & " "B. van Cutsem (eds.): %%Recent developments in statistics%. Amsterdam: " "North-Holland. 133\\--145.") MAN_END MAN_BEGIN (U"De Leeuw & Pruzansky (1978)", U"djmw", 19971201) NORMAL (U"J. de Leeuw & S. Pruzansky (1978): \"A new computational method to " "fit the weighted Euclidean distance model.\" %Psychometrika #43: 479\\--490.") MAN_END MAN_BEGIN (U"Gifi (1990)", U"djmw", 19971207) NORMAL (U"A. Gifi (1990): %%Nonlinear multivariate analysis%. John Wiley & " "Sons Ltd., reprint 1996.") MAN_END MAN_BEGIN (U"Golub & van Loan (1996)", U"djmw", 19971207) NORMAL (U"G. Golub & C. van Loan (1996): %%Matrix computations%. Third edition. " "London: The Johns Hopkins University Press.") // ?? MAN_END MAN_BEGIN (U"Green, Carmone & Smith (1989)", U"djmw", 19971201) NORMAL (U"P. Green, F. Carmone, S. Smith (1989): " "%%Multidimensional scaling: concepts and applications%. Section 3. Allyn and Bacon.") MAN_END MAN_BEGIN (U"Kaiser (1958)", U"djmw", 19980404) NORMAL (U" H.F. Kaiser (1958): \"The varimax criterion for analytic rotation " "in factor analysis.\" %Psychometrika #23: 187\\--200.") MAN_END MAN_BEGIN (U"Kiers & Groenen (1996)", U"djmw", 19971219) NORMAL (U"H.A.L. Kiers & P. Groenen (1996): \"A monotonically convergent " "algorithm for orthogonal congruence rotation.\" %Psychometrika #61: " "375\\--389.") MAN_END MAN_BEGIN (U"Klein, Plomp & Pols (1970)", U"djmw", 19971201) NORMAL (U" W. Klein, R. Plomp, & L.C.W. Pols (1970): \"Vowel Spectra, " "Vowel Spaces, and Vowel Identification.\" %%Journal of the Acoustical Society of America% #48: 999\\--1009.") MAN_END MAN_BEGIN (U"Kruskal (1964)", U"djmw", 19971201) NORMAL (U"J.B. Kruskal (1964): \"Nonmetric multidimensional scaling: a " "numerical method.\" %Psychometrika #29: 115\\--129.") MAN_END MAN_BEGIN (U"Ramsay (1988)", U"djmw", 19980106) NORMAL (U"J.O. Ramsay (1988): \"Monotone regression splines in action.\" " "%%Statistical Science% #3: 425\\--461.") MAN_END MAN_BEGIN (U"Stevens (1951)", U"djmw", 19971201) NORMAL (U"S.S. Stevens (1951): \"Mathematics, measurement, and psychophysics.\" " "In S.S. Stevens (ed.): %%Handbook of experimental psychology%. New York: " "Wiley.") MAN_END MAN_BEGIN (U"Takane, Young & de Leeuw (1976)", U"djmw", 19971201) NORMAL (U"Y. Takane, F. Young, J. de Leeuw (1976): \"Non-metric individual " "differences multidimensional scaling: an alternating least squares method " "with optimal scaling features.\" %Psychometrika #42: 7\\--67.") MAN_END MAN_BEGIN (U"Ten Berge (1995)", U"djmw", 19980404) NORMAL (U"J.M.F. ten Berge (1995): \"Suppressing permutations or rigid planar " "rotations: a remedy against nonoptimal varimax rotations.\" " "%Psychometrika #60, 437\\--446.") MAN_END MAN_BEGIN (U"Ten Berge, Kiers & Krijnen (1993)", U"djmw", 19971207) NORMAL (U"J.M.F. ten Berge, H.A.L. Kiers & W.P. Krijnen (1993): \"Computational " "solutions for the problem of negative saliences and nonsymmetry in " "INDSCAL.\" %%Journal of Classification% #10: 115\\--124.") MAN_END MAN_BEGIN (U"Torgerson (1958)", U"djmw", 19971201) NORMAL (U"W.S. Torgerson (1958): %%Theory and methods of scaling%. New York: Wiley.") MAN_END MAN_BEGIN (U"Young, Takane & Lewyckyj (1978)", U"djmw", 19971201) NORMAL (U"F.W. Young, Y. Takane & R. Lewyckyj (1978): " "\"Three notes on ALSCAL.\" %Psychometrika #43: 433\\--435.") MAN_END MAN_BEGIN (U"Weller & Romney (1990)", U"djmw", 19971216) NORMAL (U"S.C. Weller & A.K. Romney (1990): %%Metric Scaling: " "correspondence analysis%. Sage University Paper Series on Quantitative " "Applications in the Social Sciences 07-075. Newbury Park, CA: Sage.") MAN_END } /* End of file manual_MDS.cpp */ praat-6.0.04/dwtools/manual_Permutation.cpp000066400000000000000000000560041261542461700207700ustar00rootroot00000000000000/* manual_Permutation.cpp * * Copyright (C) 2005-2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* 20050709 djmw */ #include "ManPagesM.h" void manual_Permutation_init (ManPages me); void manual_Permutation_init (ManPages me) { MAN_BEGIN (U"Permutation", U"djmw", 20050721) INTRO (U"One of the @@types of objects@ in Praat. A Permutation object with %n elements consists of some ordering of " "the numbers 1,2...%n.") ENTRY (U"Interpretation") NORMAL (U"A permutation like for example (2,3,5,4,1) is an %arrangement of the five objects 1, 2, 3, 4, and 5. " "It tells us that the second object is in the first position, the third object is in the second position, " "the fifth object in the third position and so on.") NORMAL (U"If we combine a Permutation together with an other object, like a Strings for example, we may force a " "new arrangement of the strings, according to the specification in the Permutation (see @@Strings & Permutation: Permute strings@)." ) ENTRY (U"Commands") NORMAL (U"Creation:") LIST_ITEM (U"\\bu @@Create Permutation...@") NORMAL (U"Query:") LIST_ITEM (U"\\bu ##Get number of elements#") LIST_ITEM (U"\\bu @@Permutation: Get value...|Get value...@") LIST_ITEM (U"\\bu @@Permutation: Get index...|Get index...@") NORMAL (U"Modification:") LIST_ITEM (U"\\bu @@Permutation: Sort|Sort@") LIST_ITEM (U"\\bu @@Permutation: Swap blocks...|Swap blocks...@") LIST_ITEM (U"\\bu @@Permutation: Swap positions...|Swap positions...@") LIST_ITEM (U"\\bu @@Permutation: Swap numbers...|Swap numbers...@") LIST_ITEM (U"\\bu @@Permutation: Swap one from range...|Swap one from range...@") NORMAL (U"Permutations:") LIST_ITEM (U"\\bu @@Permutation: Permute randomly...|Permute randomly...@") LIST_ITEM (U"\\bu @@Permutation: Permute randomly (blocks)...|Permute randomly (blocks)...@") LIST_ITEM (U"\\bu @@Permutation: Interleave...|Interleave...@") LIST_ITEM (U"\\bu @@Permutation: Rotate...|Rotate...@") LIST_ITEM (U"\\bu @@Permutation: Reverse...|Reverse...@") LIST_ITEM (U"\\bu @@Permutation: Invert|Invert@") NORMAL (U"Successive permutations:") LIST_ITEM (U"\\bu @@Permutations: Multiply|Multiply@") ENTRY (U"Usage") LIST_ITEM (U"@@Strings & Permutation: Permute strings@ to rearrange the strings in a Strings object.") LIST_ITEM (U"@@TableOfReal & Permutation: Permute rows@ to rearrange the rows in a TableOfReal object.") MAN_END MAN_BEGIN (U"Create Permutation...", U"djmw", 20050709) INTRO (U"A command to create a @Permutation of the numbers 1,2, ..., %numberOfElements.") ENTRY (U"Settings") TAG (U"##Name") DEFINITION (U"the name of the new permutation.") TAG (U"##Number of elements%") DEFINITION (U"the number of elements in the permutation.") TAG (U"##Identity permutation") DEFINITION (U"determines whether the permution will be a randomly chosen one, or the @@identity permutation@.") MAN_END MAN_BEGIN (U"identity permutation", U"djmw", 20050713) INTRO (U"The identity permutation is (1,2,3,...,%numberOfElements), i.e. the numbers 1 to " "%numberOfElements in their natural order. ") MAN_END MAN_BEGIN (U"Permutation: Get value...", U"djmw", 20050709) INTRO (U"Get the value at the index position.") ENTRY (U"Example") NORMAL (U"The query for the value at index 3 for the permutation (3,2,4,5,1) gives 4.") MAN_END MAN_BEGIN (U"Permutation: Get index...", U"djmw", 20050714) INTRO (U"Get the index position of the value. ") ENTRY (U"Example") NORMAL (U"The query for the index of value 3 for the permutation (3,2,4,5,1) gives 1.") MAN_END MAN_BEGIN (U"Permutation: Reverse...", U"djmw", 20110105) INTRO (U"Reverse the elements in the given range.") ENTRY (U"Setting") TAG (U"##Index range#") DEFINITION (U"defines the range of indices that will be reversed.") ENTRY (U"Examples") NORMAL (U"1. With ##Index range# = [0,0], the permutation (1,2,3,4,5) is turned into (5,4,3,2,1). ") NORMAL (U"2. With ##Index range# = [3,0], the permutation (1,2,3,4,5) is turned into (1,2,5,4,3). ") MAN_END MAN_BEGIN (U"Permutation: Swap one from range...", U"djmw", 20110105) INTRO (U"An element at an index, randomly chosen from a range, will be permuted with an element at a prescribed index position.") ENTRY (U"Settings") TAG (U"##Index range#") DEFINITION (U"defines the range of indices from which one will be randomly chosen.") TAG (U"##Index#") DEFINITION (U"defines the special index position whose element will be interchanged with the one chosen from the range.") TAG (U"##Forbid same") DEFINITION (U"when %on, forbids the randomly chosen position and the index position to be the same. " "This switch is only of relevance when the chosen range happens to overlap the index position.") ENTRY (U"Examples") NORMAL (U"With ##Index range# = [0,0], ##Index# = 3, ##Forbid same# is %off and (1,2,3,4,5) as the starting permutation, the outcome might be one of " "the five permutations (3,2,1,4,5), (1,3,2,4,5), (1,2,3,4,5), (1,2,4,3,5), (1,2,5,4,3). If ##Forbid same# were chosen as %on, the " "(1,2,3,4,5) permutation is forbidden and the outcome could only be one of the four remaining permutations.") MAN_END MAN_BEGIN (U"Permutation: Permute randomly...", U"djmw", 20111123) INTRO (U"Generates a new @@Permutation@ by randomly permuting a range of elements in the selected Permutation object.") ENTRY (U"Setting") TAG (U"##Index range#") DEFINITION (U"defines the range of elements that will be permuted. The elements outside this range will be kept intact.") ENTRY (U"Example") NORMAL (U"If we start with the permutation (4,6,3,1,5,2,7) and a chosen ##Index range# that runs from 3 to 6, a new permutation will be generated as follows:") LIST_ITEM (U"1. A new permutation of the same dimension as the selected one will be created. ") LIST_ITEM (U"2. Because the index range starts at 3, the first two elements of the selected permutation will be copied " "to the first two locations in the newly created permutation. The new permutation is now (4,6,.,.,.,.,.), where a " "dot (.) means that the element is unspecified.") LIST_ITEM (U"3. The elements 3 to 6 of the selected permutation, i.e. the numbers (3,1,5,2) will be randomly permuted. " "There are 24 possible permutations of these 4 numbers. Say the outcome happens to be (5,1,3,2). The new permutation is now (4,6,5,1,3,2,.).") LIST_ITEM (U"4. The remaining element (7) is copied to the new permutation. Finally, this results " "in the new permutation being (4,6,5,1,3,2,7).") MAN_END MAN_BEGIN (U"Permutation: Permute randomly (blocks)...", U"djmw", 20110105) INTRO (U"Generates a new @Permutation by randomly permuting blocks of size %blocksize.") ENTRY (U"Settings") TAG (U"##Index range#") DEFINITION (U"the range of elements whose blocks will be permuted.") TAG (U"##Block size#") DEFINITION (U"the size of the blocks that will be permuted. There must fit an integer number of blocks " "in the chosen range.") TAG (U"##Permute within blocks#") DEFINITION (U"when %on, the elements in each block are also randomly permuted.") TAG (U"##No doublets#") DEFINITION (U"guarantees that the first element in each block does not equal the last element of the previous block modulo " "the block size. E.g. the numbers 3, 6, 9 are all equal modulo 3. " "This parameter only has effect when ##Permute within blocks# is %on.") ENTRY (U"Examples") NORMAL (U"1. With ##Index range# = [0,0], ##Block size# = 3 and ##Permute within blocks# is %off, the permutation ((1,2,3),(4,5,6),(7,8,9)) " "is turned into one of six possible permutations, for example into ((4,5,6),(7,8,9),(1,2,3)). (The option ##No doublets# will be ignored and the parentheses are only there to indicate the blocks.)") NORMAL (U"2. With ##Index range# = [0,0], ##Block size# = 3, ##Permute within blocks# is %on and ##No doublets# is %off, " "the permutation ((1,2,3),(4,5,6),(7,8,9)) might turn into ((5,4,6),(9,8,7),(3,1,2)).") NORMAL (U"3. With the same options as 2 but ##No doublets# is %on, the previously given outcome is forbidden because " "the last element of the first block (6) and the first element of the next block (9) are equal modulo 3 (the " "blocksize). A valid outcome might then be ((5,4,6),(8,9,7),(3,1,2)).") MAN_END MAN_BEGIN (U"Permutation: Swap blocks...", U"djmw", 20110105) INTRO (U"A command to swap the contents of two index ranges in the selected @Permutation.") ENTRY (U"Settings") TAG (U"##From index#, ##To index#") DEFINITION (U"the two starting positions from where elements are to be swapped. The blocks may overlap.") TAG (U"##Block size#") DEFINITION (U"determines the number of pairs to swap. ") ENTRY (U"Behaviour") NORMAL (U"If the ##Block size# equals one, only the elements at the ##From index# and ##To index# position are swapped. If blocksize is greater than one, the two elements at ##From index#+1 and ##To index#+1 will be swapped too. This goes on until the last two elements in each block have been swapped.") ENTRY (U"Examples") NORMAL (U"1. Swap two blocks: with ##From index# = 1, ##To index# = 4, and ##Block size# = 2, the permutation (1,2,3,4,5) is turned into (4,5,3,1,2).") NORMAL (U"2. Swap two elements: with ##From index# = 1, ##To index# = 4, and ##Block size# = 1, the permutation (1,2,3,4,5) is turned into (4,2,3,1,5).") NORMAL (U"3. Swap two overlapping blocks: with ##From index# = 1, ##To index# = 3, and ##Block size# = 3, the permutation (1,2,3,4,5) is turned into " "(3,4,5,2,1).") MAN_END MAN_BEGIN (U"Permutation: Swap positions...", U"djmw", 20110105) INTRO (U"Swaps the contents at two indices in the selected @@Permutation@.") ENTRY (U"Settings") TAG (U"##First index#, ##Second index#") DEFINITION (U"the two indices from where elements have to be swapped. The order of these indices is not important.") ENTRY (U"Example") NORMAL (U"With ##First index# = 1 and ##Second index# = 3, the permutation (1,3,4,2,5) is turned into (4,3,1,2,5).") MAN_END MAN_BEGIN (U"Permutation: Swap numbers...", U"djmw", 20110105) INTRO (U"Swaps two numbers in the selected @@Permutation@.") ENTRY (U"Settings") TAG (U"##First number#, ##Second number#") DEFINITION (U"the two numbers that have to be swapped. The order of these numbers is not important.") ENTRY (U"Example") NORMAL (U"With ##First number# = 1 and ##Second number# = 3, the permutation (1,3,4,2,5) is turned into (3,1,4,2,5).") MAN_END MAN_BEGIN (U"Permutation: Interleave...", U"djmw", 20110105) INTRO (U"Generates a new @Permutation by interleaving elements from successive blocks. ") NORMAL (U"We always start with the first element in the first block. When the offset is zero, the next element will be the first " "element of the second block, then the first element of the third block. After the first element of the last block, we start again " "with the second elements in each block. And so on. (In card playing, with two blocks of 26 cards each, this is called a faro " "shuffle and eight successive faro shuffles will return the deck to precisely the order in which you began.)") NORMAL (U"If the offset differs from zero and equals 1 for example, we start with the first element in the first block, then the " "second element in the second block, the third element in the third block and so on. When the last element of a block is reached " "and the number of blocks is not exhausted the next element will be the first from the next block. When the last block is reached, " "we start the same cycle again with the next lower element in the first block (which by the way need not be the second element, " "see also example 4).") ENTRY (U"Settings") TAG (U"##Index range#") DEFINITION (U"the range of elements that will be permuted.") TAG (U"##Block size#") DEFINITION (U"the size of a block. An integer number of blocks must fit " "in the chosen ##Index range#.") TAG (U"##Offset#") DEFINITION (U"determines the relative positions of selected elements in successive blocks.") ENTRY (U"Examples") NORMAL (U"1. With ##Index range# = [0,0], ##Block size# = 3, and ##Offset# = 0, the permutation ((1,2,3),(4,5,6),(7,8,9)) is turned into (1,4,7,2,5,8,3,6,9).") NORMAL (U"2. With ##Index range# = [0,0], ##Block size# = 3, and ##Offset# = 1, the permutation ((1,2,3),(4,5,6),(7,8,9)) is turned into (1,5,9,2,6,7,3,4,8).") NORMAL (U"3. With ##Index range# = [0,0], ##Block size# = 3, and ##Offset# = 2, the permutation ((1,2,3),(4,5,6),(7,8,9)) is turned into (1,6,8,2,4,9,3,5,7).") NORMAL (U"4. With ##Index range# = [0,0], ##Block size# = 4, and ##Offset# = 1, the permutation ((1,2,3,4),(5,6,7,8)) is turned into (1,6,3,8,2,7,4,5).") MAN_END MAN_BEGIN (U"lexicographic permutation order", U"djmw", 20140131) INTRO (U"We can order the %n numbers 1, 2, 3,..., n in %n! different ways. Each of these n! orderings represents a different permutation of " "the numbers 1, 2, 3,..., n. For example, if %n equals 3 we have 6 (=3\\.c2\\.c1) possible orderings: (1,2,3), (1,3,2), (2,1,3), (2,3,1), (3,1,2) and (3,2,1). " "The %%lexicographic permutation order% starts from the identity permutation (1,2,..., n). By successively swapping only two numbers one " "obtains all possible permutations. The last permutation in lexicographic order will be the permutation with all numbers in reversed order, " "i.e. (n,n-1,...,2,1). The example given above has all 6 permutations in lexicographic permutation order.") MAN_END MAN_BEGIN (U"Permutation: Next", U"djmw", 20140131) INTRO (U"Get the next @@Permutation|permutation@ in @@lexicographic permutation order@. ") NORMAL (U"The next permutation is obtained from the selected permutation " "by swapping values %%at only two positions%. Starting with the identity permutation and " "repeatedly applying this function will iterate through all possible permutations. If no further permutation " "is available, i.e. the selected permutation is at the lexicographic end position (n, n-1, ..., 3, 2, 1), the current permutation will not change anymore. ") ENTRY (U"Examples") NORMAL (U"If we start with (1,2,3,4) successively applying ##Next# will generate the following sequence (1,2,4,3), (1,3,2,4), (1,3,4,2), (1,4,2,3), (1,4,3,2), etc.") MAN_END MAN_BEGIN (U"Permutation: Previous", U"djmw", 20140131) NORMAL (U"Get the previous @@Permutation|permutation@ in @@lexicographic permutation order@. The previous permutation is obtained " "from the selected permutation by swapping values %%at only two positions%. If no further permutation " "is available, i.e. the current permutation is at the lexicographic start position (1, 2, 3, ..., n-1, n), the current permutation will not change anymore. ") NORMAL (U"The ##Previous# operation follows the opposite order of @@Permutation: Next@.") MAN_END MAN_BEGIN (U"Permutation: Rotate...", U"djmw", 20110105) INTRO (U"A circular shift of all elements within the given range.") ENTRY (U"Settings") TAG (U"##Index range#") DEFINITION (U"the range of elements that will be circularly permuted.") // ambiguous; are these the positions or the numbers? TAG (U"##Step size#") DEFINITION (U"define how many positions each element will be shifted.") ENTRY (U"Examples") NORMAL (U"1. With ##Step size# = 2 and ##Index range# = [1,5], the permutation (1,2,3,4,5) is turned into (4,5,1,2,3). ") NORMAL (U"2. With ##Step size# = 2 and ##Index range# = [2,5], the permutation ((1),(2,3,4,5)) is turned into ((1),(4,5,2,3))") NORMAL (U"3. With ##Step size# = -1 and ##Index range# = [0,0], the permutation (1,2,3,4,5) is turned into (2,3,4,5,1).") MAN_END MAN_BEGIN (U"Permutation: Invert", U"djmw", 20050709) INTRO (U"Generates the inverse of the selected @Permutation.") ENTRY (U"Example") NORMAL (U"If the permutation is (1,5,3,2,4) the inverse will be (1,4,3,5,2). If we @@Permutations: Multiply|multiply@ these two permutations the result will be the identity permutation (1,2,3,4,5).") MAN_END MAN_BEGIN (U"Permutations: Multiply", U"djmw", 20050717) INTRO (U"Apply the selected @@Permutation@s one after the other. ") NORMAL (U"Permutations are %not commutative, i.e. applying permutation %p__1_ after %p__2_ might not give the same outcome as applying " "%p__2_ after %p__1_.") MAN_END MAN_BEGIN (U"Permutation: Sort", U"djmw", 20050709) INTRO (U"Sorts the elements ascending, i.e. set the selected @@Permutation@ to the @@identity permutation@.") MAN_END MAN_BEGIN (U"TableOfReal & Permutation: Permute rows", U"djmw", 20050709) INTRO (U"Generate a new @TableOfReal with a row ordering determined by the @Permutation.") ENTRY (U"Example") NORMAL (U"If the selected TableOfReal has 5 rows and the permutation is (5,4,3,2,1) the first row of the new TableOfReal equals the fifth row of the selected, the second row of new equals the fourth row of the selected and so on.") MAN_END MAN_BEGIN (U"Strings & Permutation: Permute strings", U"djmw", 20140130) INTRO (U"Generate a new @Strings with a strings ordering determined by the @Permutation.") NORMAL (U"The number of strings in the #Strings and the number of elements in the #Permutation have to be equal.") ENTRY (U"Examples") NORMAL (U"1. If the selected Strings has the 4 strings ordered as \"heed\", \"hid\", \"hood\", \"hud\", and the permutation is " "(4,3,2,1), the new Strings has the ordering \"hud\", \"hood\", \"hid\", \"heed\".") NORMAL (U"2. In the example that is discussed in the @@ExperimentMFC|listening experiment@ section, we have four stimuli \"heed.wav\", " "\"hid.wav\", \"hood.wav\", \"hud.wav\" that we want to present three times to each subject with a " "randomization strategy, i.e. stimuli presented in blocks of four, randomized, and no two successive stimuli equal. " "This type of randomization can easily be accomplished with a Permutation object and a Strings." ) LIST_ITEM (U"1. Fill the Strings object with 12 strings, i.e. three repetitions of the four stimuli. ") LIST_ITEM (U"2. Create a Permutation object with 12 elements and perform ##@@Permutation: Permute randomly (blocks)...|Permute randomly (blocks):@ 0, 0, 4, \"yes\", \"yes\"#. We randomly permute blocks of size 4 and permute randomly within these blocks and make sure that on the transition from on block to the other no two stimuli are equal. (Of course, the random permutation of the blocks makes no difference here since all the blocks have the same content.)") LIST_ITEM (U"3. Select the Strings and the Permutation together and choose ##Permute strings#. " "Now the new Strings will contain the new ordering of the stimuli.") MAN_END MAN_BEGIN (U"Strings: To Permutation...", U"djmw", 20050721) INTRO (U"Generates a @Permutation with the same number of elements as the @Strings.") ENTRY (U"Setting") TAG (U"##Sort") DEFINITION (U"determines whether the Permutation will have an element ordering that can be used to sort the Strings alphabetically.") ENTRY (U"Example") NORMAL (U"If \"Sort\" is %on, and the selected Strings contains 4 strings ordered as \"hud\", \"hid\", \"hood\", " "\"heed\", the generated Permutation will be (4,2,3,1). If you now select the String and the Permutation " "together and choose @@Strings & Permutation: Permute strings|Permute strings@, the new Strings will have " "the strings ordered alphabetically as \"heed\", \"hid\", \"hood\", \"hud\". " "You can also sort the Strings alphabetically descending, by first @@Permutation: Reverse...|reversing@ " "the elements in the Permutation before you select the Permutation and the Strings together. ") MAN_END MAN_BEGIN (U"Index", U"djmw", 20050725) INTRO (U"One of the @@Types of objects|types of objects@ in the P\\s{RAAT} program.") MAN_END MAN_BEGIN (U"Strings: To Index", U"djmw", 20050721) INTRO (U"Generates an @Index from the selected @Strings.") ENTRY (U"Example") NORMAL (U"We start from the following #Strings:") CODE (U"6 (number of strings)") CODE (U"\"hallo\"") CODE (U"\"dag allemaal\"") CODE (U"\"hallo\"") CODE (U"\"tot morgen\"") CODE (U"\"hallo\"") CODE (U"\"tot morgen\"") NORMAL (U"This will give us the following #Index:") CODE (U"1 (number of columns) \"\" (no column name)") CODE (U"\"dag allemaal\"") CODE (U"\"hallo\"") CODE (U"\"tot morgen\"") CODE (U"6 (number of elements)") CODE (U"2") CODE (U"1") CODE (U"2") CODE (U"3") CODE (U"2") CODE (U"3") MAN_END MAN_BEGIN (U"Index: To Permutation...", U"djmw", 20050725) INTRO (U"Generates a @Permutation from the selected @Index by randomly permuting blocks of equivalent elements.") NORMAL (U"Suppose your data consists of groups of equivalent elements and the number of elements in the groups are not equal. You want to make random ordering of your data such that the elements in a group stay together. The following example shows you how.") ENTRY (U"Setting") TAG (U"##Permute within classes") DEFINITION (U"determines whether the elements within a class will be randomly permuted.") ENTRY (U"Example") NORMAL (U"Suppose your data, for example a @Strings, consists of groups of equivalent elements and the number of elements in the groups are not equal. You want to make a random ordering of your data such that the elements in a group stay together. The following example shows you how.") NORMAL (U"We start from the following Strings:") CODE (U"6 (number of strings)") CODE (U"\"hallo\"") CODE (U"\"dag allemaal\"") CODE (U"\"hallo\"") CODE (U"\"tot morgen\"") CODE (U"\"hallo\"") CODE (U"\"tot morgen\"") NORMAL (U"We choose @@Strings: To Index|To Index@ which will give us the following #Index:") CODE (U"1 (number of columns) \"\" (no column name)") CODE (U"\"dag allemaal\"") CODE (U"\"hallo\"") CODE (U"\"tot morgen\"") CODE (U"6 (number of elements)") CODE (U"2") CODE (U"1") CODE (U"2") CODE (U"3") CODE (U"2") CODE (U"3") NORMAL (U"We choose ##To Permutation# and with ##Permute within classes# %off, this might generate the permutation (2,4,6,1,3,5).") NORMAL (U"Selecting the Permutation and the Strings together and choosing @@Strings & Permutation: " "Permute strings|Permute strings@ will generate the following Strings:") CODE (U"\"dag allemaal\"") CODE (U"\"tot morgen\"") CODE (U"\"tot morgen\"") CODE (U"\"hallo\"") CODE (U"\"hallo\"") CODE (U"\"hallo\"") NORMAL (U"We see that the permutation always keeps identical strings together.") MAN_END MAN_BEGIN (U"Index: Extract part...", U"djmw", 20050725) INTRO (U"Creates a new @Index by copying a part of selected Index.") ENTRY (U"Example") NORMAL (U"Given the following Index:") CODE (U"1 (number of columns) \"\" (no column name)") CODE (U"\"dag allemaal\"") CODE (U"\"hallo\"") CODE (U"\"tot morgen\"") CODE (U"6 (number of elements)") CODE (U"2") CODE (U"1") CODE (U"2") CODE (U"3") CODE (U"2") CODE (U"3") NORMAL (U"The command ##Extract part... 1 2# gives you the new Index:") CODE (U"1 (number of columns) \"\" (no column name)") CODE (U"\"dag allemaal\"") CODE (U"\"hallo\"") CODE (U"\"tot morgen\"") CODE (U"6 (number of elements)") CODE (U"2") CODE (U"1") NORMAL (U"Note that all classes stay intact and may have zero references like for example the \"tot morgen\" class. ") MAN_END } /* End of file manual_Permutation.cpp */ praat-6.0.04/dwtools/manual_dwtools.cpp000066400000000000000000010532401261542461700201540ustar00rootroot00000000000000/* manual_dwtools.cpp * * Copyright (C) 1993-2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020313 GPL djmw 20130620 Latest modification */ #include "ManPagesM.h" #include "Sound_extensions.h" #include "TableOfReal_extensions.h" #include "Table_extensions.h" #include "Configuration.h" #include "Discriminant.h" static TableOfReal getStandardizedLogFrequencyPolsData (int includeLevels) { autoTableOfReal me = TableOfReal_createFromPolsData_50males (includeLevels); for (long i = 1; i <= my numberOfRows; i++) { for (long j = 1; j <= 3; j++) { my data[i][j] = log10 (my data[i][j]); } } TableOfReal_standardizeColumns (me.peek()); TableOfReal_setColumnLabel (me.peek(), 1, U"standardized log (%F__1_)"); TableOfReal_setColumnLabel (me.peek(), 2, U"standardized log (%F__2_)"); TableOfReal_setColumnLabel (me.peek(), 3, U"standardized log (%F__3_)"); if (includeLevels) { TableOfReal_setColumnLabel (me.peek(), 4, U"standardized %L__1_"); TableOfReal_setColumnLabel (me.peek(), 5, U"standardized %L__1_"); TableOfReal_setColumnLabel (me.peek(), 6, U"standardized %L__3_"); } return me.transfer(); } static void drawPolsF1F2_log (Graphics g) { autoTableOfReal me = getStandardizedLogFrequencyPolsData (0); Graphics_setWindow (g, -2.9, 2.9, -2.9, 2.9); TableOfReal_drawScatterPlot (me.peek(), g, 1, 2, 0, 0, -2.9, 2.9, -2.9, 2.9, 10, 1, U"+", 1); } static void drawPolsF1F2ConcentrationEllipses (Graphics g) { autoTableOfReal me = getStandardizedLogFrequencyPolsData (0); autoDiscriminant d = TableOfReal_to_Discriminant (me.peek()); Discriminant_drawConcentrationEllipses (d.peek(), g, 1, 0, nullptr, 0, 1, 2, -2.9, 2.9, -2.9, 2.9, 12, 1); } static void drawPolsDiscriminantConfiguration (Graphics g) { autoTableOfReal me = getStandardizedLogFrequencyPolsData (0); autoDiscriminant d = TableOfReal_to_Discriminant (me.peek()); autoConfiguration c = Discriminant_and_TableOfReal_to_Configuration (d.peek(), me.peek(), 2); Configuration_draw (c.peek(), g, 1, 2, -2.9, 2.9, -2.9, 2.9, 0, 1, U"", 1); } static void drawBoxPlot (Graphics g) { double q25 = 25, q50 = 50, q75 = 60, mean = 45; double hspread = q75 - q25, r = 0.05, w = 0.2; double lowerInnerFence = q25 - 1.5 * hspread; double upperInnerFence = q75 + 1.5 * hspread; double upperOuterFence = q75 + 3.0 * hspread; double lowerWhisker = lowerInnerFence + 0.1 * hspread; double upperWhisker = upperInnerFence - 0.5 * hspread; double ymin = lowerWhisker - 0.1 * hspread, ymax = q75 + 4 * hspread; double x = 0, dx = 0.01, xar = x + 0.7, xtl = xar + dx; double xal1 = x + r + dx, xal2 = x + w + r, y; Graphics_setWindow (g, -1, 2, ymin, ymax); Graphics_setInner (g); Graphics_setTextAlignment (g, Graphics_LEFT, Graphics_HALF); Graphics_line (g, x - r, lowerWhisker, x + r, lowerWhisker); Graphics_line (g, x, lowerWhisker, x, q25); Graphics_line (g, x - w, q25, x + w, q25); Graphics_line (g, x - w, q50, x + w, q50); Graphics_line (g, x - w, q75, x + w, q75); Graphics_line (g, x - w, q25, x - w, q75); Graphics_line (g, x + w, q25, x + w, q75); Graphics_line (g, x, q75, x, upperWhisker); Graphics_line (g, x - r, upperWhisker, x + r, upperWhisker); y = q75 + 2.5 * hspread; Graphics_text (g, x, y, U"*"); Graphics_arrow (g, xar, y, xal1, y); Graphics_text (g, xtl, y, U"outlier > %%upperInnerFence%"); y = q75 + 3.5 * hspread; Graphics_text (g, x, y, U"o"); Graphics_arrow (g, xar, y, xal1, y); Graphics_text (g, xtl, y, U"outlier > %%upperOuterFence%"); y = upperOuterFence; Graphics_setLineType (g, Graphics_DOTTED); Graphics_line (g, -xtl, y, xtl, y); Graphics_text (g, xtl, y, U"%%upperOuterFence%"); y = upperInnerFence; Graphics_line (g, -xtl, y, xtl, y); Graphics_text (g, xtl, y, U"%%upperInnerFence%"); Graphics_line (g, x - w, mean, x + w, mean); Graphics_setLineType (g, Graphics_DRAWN); y = upperWhisker; Graphics_arrow (g, xar, y, xal2, y); Graphics_text (g, xtl, y, U"%%upperWhisker%"); y = lowerWhisker; Graphics_arrow (g, xar, y, xal2, y); Graphics_text (g, xtl, y, U"%%lowerWhisker%"); y = q75; Graphics_arrow (g, xar, y, xal2, y); Graphics_text (g, xtl, y, U"%%q75%"); y = q25; Graphics_arrow (g, xar, y, xal2, y); Graphics_text (g, xtl, y, U"%%q25%"); y = q50; Graphics_arrow (g, xar, y, xal2, y); Graphics_text (g, xtl, y, U"%%q50%"); y = mean; Graphics_arrow (g, xar, y, xal2, y); Graphics_text (g, xtl, y, U"%%mean%"); Graphics_unsetInner (g); } static void drawPartionedMatrix (Graphics g) { double min = 0, max = 10, x1, x2, y1, y2; Graphics_setWindow (g, min, max, min, max); x1 = 0; x2 = max; y1 = y2 = 7; Graphics_setLineType (g, Graphics_DOTTED); Graphics_line (g, x1, y1, x2, y2); x1 = x2 = 3; y1 = 0; y2 = max; Graphics_line (g, x1, y1, x2, y2); Graphics_setLineType (g, Graphics_DRAWN); x1 = 1.5; y1 = 7+3/2; Graphics_setFontSize (g, 14); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); Graphics_text (g, x1, y1, U"##S__yy_#"); x1 = 3 + 7/2; Graphics_text (g, x1, y1, U"##S__yx_#"); y1 = 7/2; Graphics_text (g, x1, y1, U"##S__xx_#"); x1 = 1.5; Graphics_text (g, x1, y1, U"##S__xy_#"); } void manual_dwtools_init (ManPages me); void manual_dwtools_init (ManPages me) { MAN_BEGIN (U"AffineTransform", U"djmw", 20010927) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"An affine transform is a combination of a linear transformation #%A " "and a translation #%t that transforms a vector #%x to a new vector #%y " "in the following way:") FORMULA (U"#%y = #%A x + #%t") MAN_END MAN_BEGIN (U"AffineTransform: Invert", U"djmw", 20011008) INTRO (U"Get the inverse of the selected @AffineTransform object.") NORMAL (U"The inverse from") FORMULA (U"#%y = #%A x + #%t") NORMAL (U"is:") FORMULA (U"#%x = #%A^^-1^ - #%A^^-1^#%t.") MAN_END MAN_BEGIN (U"band filtering in the frequency domain", U"djmw", 20010404) INTRO (U"We describe how band filtering in the frequency domain is performed.") NORMAL (U"We start with a @Sound and end with a filter bank representation of " "this sound. We assume a standard analysis context: a sound divided into " "frames according to a certain %%window length% and %%time step%. We will " "simulate a filterbank with %N filters.") NORMAL (U"The algorithm for each sound frame proceeds in the following way:") LIST_ITEM (U"1. Apply a Gaussian window to the sound frame.") LIST_ITEM (U"2. Convert the windowed frame into a @Spectrum object.") LIST_ITEM (U"3. Convert the spectral amplitudes to %energy values by squaring " "the real and imaginary parts and multiplying by %df, the frequency " "distance between two successive frequency points in the spectrum. " "Since the Spectrum object only contains positive frequencies, " "we have to multiply all energy values, except the first and the last " "frequency, by another factor of 2 to compensate for negative frequencies.") LIST_ITEM (U"4. For each of the %N filters in the filter bank: determine the " "inner product of its filter function with the energies as determined in " "the previous step. The result of each inner product is the energy in the " "corresponding filter.") LIST_ITEM (U"5. Convert the energies in each filter to power by dividing by " "the %%window length%.") LIST_ITEM (U"6. Correct the power, due to the windowing of the frame, by dividing " "by the integral of the %squared windowing function.") LIST_ITEM (U"7. Convert all power values to %dB's according to 10 * log10 " "(%power / 4 10^^-10^).") MAN_END MAN_BEGIN (U"Bonferroni correction", U"djmw", 20011107) NORMAL (U"In general, if we have %k independent significance tests " "at the %\\al level, the probability %p that we will get no significant " "differences in all these tests is simply the product of the individual " "probabilities: (1 - %\\al)^^%k^. " "For example, with %\\al = 0.05 and %k = 10 we get %p = 0.95^^10^ = 0.60. " "This means, however, we now have a 40\\% chance that one of these 10 " "tests will turn out significant, despite each individual test only being " "at the 5\\% level. " "In order to guarantee that the overall significance test is still at the " "%\\al level, we have to adapt the significance level %\\al\\'p of the " "individual test. ") NORMAL (U"This results in the following relation between the overall and the " "individual significance level:") FORMULA (U"(1 - %\\al\\'p)^^%k%^ = 1 - %\\al.") NORMAL (U"This equation can easily be solved for %\\al\\'p:") FORMULA (U"%\\al\\'p = 1 - (1-%\\al)^^1/%k^,") NORMAL (U"which for small %\\al reduces to:") FORMULA (U"%\\al\\'p = %\\al / %k") NORMAL (U"This is a very simple recipe: If you want an overall significance " "level %\\al and you perform %k individual tests, simply divide %\\al " "by %k to obtain the significance level for the individual tests.") MAN_END MAN_BEGIN (U"box plot", U"djmw", 20111010) INTRO (U"A box plot provides a simple graphical summary of data. These plots " "originate from the work of @@Tukey (1977)@.") ENTRY (U"Definitions") NORMAL (U"The following figure shows an annotated box plot.") PICTURE (5.0, 5.0, drawBoxPlot) NORMAL (U"To understand the box plot we need the following definitions:") LIST_ITEM (U"%%q25% = lower quartile, 25\\% of the data lie below this value") LIST_ITEM (U"%%q50% = median, 50\\% of the data lie below this value") LIST_ITEM (U"%%q75% = upper quartile, 25\\% of the data lie above this value") NORMAL (U"The following definitions all depend on these quantiles:") LIST_ITEM (U"%%hspread% = |%%q75% \\-- %%q25%| (50\\% interval)") LIST_ITEM (U"%%lowerOuterFence% = %%q25% \\-- 3.0 * %%hspread% (not in figure)") LIST_ITEM (U"%%lowerInnerFence% = %%q25% \\-- 1.5 * %%hspread% (not in figure)") LIST_ITEM (U"%%upperInnerFence% = %%q75% + 1.5 * %%hspread%") LIST_ITEM (U"%%upperOuterFence% = %%q75% + 3.0 * %%hspread%") LIST_ITEM (U"%%lowerWhisker% = smallest data value larger then %%lowerInnerFence%") LIST_ITEM (U"%%upperWhisker% = largest data value smaller then %%upperInnerFence%") NORMAL (U"The box plot is a summary of the data in which:") LIST_ITEM (U"\\bu the horizontal lines of the rectangle correspond to " " %%q25%, %%q50% and %%q75%, respectively.") LIST_ITEM (U"\\bu the dotted line corresponds to the mean.") LIST_ITEM (U"\\bu the outliers outside the %%outerFences% are drawn with an 'o'.") LIST_ITEM (U"\\bu the outliers in the intervals (%%lowerOuterFence%, %%lowerInnerFence%) " "and (%%upperInnerFence%, %%upperOuterFence%) are drawn with an '*'.") LIST_ITEM (U"\\bu the whisker lines outside the rectangle connect %%q25% with %%lowerWhisker%, and, " "%%q75% with %%upperWhisker%, respectively. With no outliers present, the " "whiskers mark minimum and/or maximum of the data.") MAN_END MAN_BEGIN (U"BarkFilter", U"djmw", 20141023) INTRO (U"A #deprecated @@types of objects|type of object@ in P\\s{RAAT}. It is replaced by @@BarkSpectrogram@.") NORMAL (U"An object of type BarkFilter represents an acoustic time-frequency " "representation of a sound: the power spectral density %P(%z, %t), expressed " "in dB's as 10*log10(power/4e-10)). In the now preferred BarkSpectrogram the power is represented instead of its dB value." "It is sampled into a number of points around equally spaced times %t__%i_ " "and frequencies %z__%j_ (on a Bark scale).") ENTRY (U"Inside a BarkFilter") NORMAL (U"With @Inspect you will see that this type contains the same attributes a @Matrix object.") MAN_END MAN_BEGIN (U"BarkSpectrogram", U"djmw", 20141023) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"An object of type BarkSpectrogram represents an acoustic time-frequency " "representation of a sound: the power spectral density %P(%z, %t). " "It is sampled into a number of points around equally spaced times %t__%i_ " "and frequencies %z__%j_ (on a Bark scale).") NORMAL (U" The bark to hertz transformation is defined as:") FORMULA (U"hertz = 650.0 * sinh (bark / 7.0),") NORMAL (U"while its inverse is defined as:") FORMULA (U"bark = 7.0 * log (hertz/650 + sqrt (1 + (hertz/650)^^2^).") ENTRY (U"Inside a BarkSpectrogram") NORMAL (U"With @Inspect you will see that this type contains the same attributes a @Matrix object.") MAN_END MAN_BEGIN (U"BarkSpectrogram: Draw Sekey-Hanson auditory filters...", U"djmw", 20141023) INTRO (U"A command to draw the auditory filters defined in @@Sekey & Hanson (1984)@.") MAN_END MAN_BEGIN (U"BarkSpectrogram: Paint image...", U"djmw", 20141023) INTRO (U"A command to draw the selected @BarkSpectrogram into the @@Picture window@ in shades of grey.") MAN_END MAN_BEGIN (U"bootstrap", U"djmw", 20141101) INTRO (U"The bootstrap data set is a random sample of size %n " "drawn %%with% replacement from the sample (%x__1_,...%x__n_). This " "means that the bootstrap data set consists of members of the original " "data set, some appearing zero times, some appearing once, some appearing " "twice, etc.") NORMAL (U"More information can be found in @@Efron & Tibshirani (1993)@.") MAN_END MAN_BEGIN (U"canonical variate", U"djmw", 20060328) NORMAL (U"A ##canonical variate# is a new variable (variate) formed by making a linear combination of two " "or more variates (variables) from a data set. " "A linear combination of variables is the same as a weighted sum of variables. " "Because we can in infinitely many ways choose combinations of weights between variables in a data set, " "there are also infinitely many canonical variates possible. ") NORMAL (U"In general additional constraints must be satisfied by the weights to get a meaningful canonical variate. " "For example, in @@Canonical correlation analysis|canonical correlation analyis@ a data set is split up into two parts, a %%dependent% and an %%independent% part. " "In both parts we can form a canonical variate and we choose weights that maximize the correlation between these canonical variates " "(there is an @@TableOfReal: To CCA...|algorithm@ that calculates these weights).") MAN_END MAN_BEGIN (U"Categories", U"djmw", 19960918) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"An object of type Categories represents an ordered collection of categories. Each " "category is a simple text string.") ENTRY (U"Categories commands") NORMAL (U"Creation:") LIST_ITEM (U"\\bu ##Create an empty Categories#") LIST_ITEM (U"\\bu @@FFNet & Pattern: To Categories...@") NORMAL (U"Viewing and editing:") LIST_ITEM (U"\\bu @CategoriesEditor") NORMAL (U"Analysis:") LIST_ITEM (U"\\bu @@Categories: To Confusion@") LIST_ITEM (U"\\bu @@Categories: Difference@") NORMAL (U"Synthesis") LIST_ITEM (U"\\bu @@Categories: Append@") LIST_ITEM (U"\\bu ##Categories: Permute...#") LIST_ITEM (U"\\bu ##Categories: To unique Categories#") ENTRY (U"Inside a Categories") NORMAL (U"With @Inspect you will see the following attributes:") TAG (U"%size") DEFINITION (U"the number of simple categories.") TAG (U"%item[]") DEFINITION (U"the categories. Each category is an object of type #SimpleString.") MAN_END MAN_BEGIN (U"Categories: Difference", U"djmw", 19960918) INTRO (U"A command to compute the difference between two selected @Categories objects.") ENTRY (U"Behaviour") NORMAL (U"Each element in the first object is compared with the corresponding " "object in the second object according to its compare method. " "The number of different %categories will be shown in the @@Info window@.") MAN_END MAN_BEGIN (U"Categories: To Confusion", U"djmw", 19960918) INTRO (U"A command to compute the @Confusion matrix from two selected " "@Categories objects.") ENTRY (U"Algorithm") NORMAL (U"A confusion matrix is constructed from both #Categories objects in " "the following way: The first Categories object is considered the stimulus " "Categories and its unique (sorted) categories " "form the row indices of the confusion matrix, the unique (sorted) " "categories of the second object form the column indices of this matrix.") NORMAL (U"Next, each element in the first #Categories object is compared with " "the corresponding object in the second object and the element in the " "confusion matrix addressed by this pair is incremented by 1.") MAN_END MAN_BEGIN (U"Categories: Append", U"djmw", 19960918) INTRO (U"You can choose this command after selecting 2 objects of type @Categories. " "A new object is created that contains the second object appended after the first.") MAN_END MAN_BEGIN (U"Categories: Edit", U"djmw", 19960918) INTRO (U"You can choose this command after selecting one #Categories. " "A @CategoriesEditor will appear on the screen, with the selected #Categories in it.") MAN_END MAN_BEGIN (U"CategoriesEditor", U"djmw", 19960918) ENTRY (U"An editor for manipulating @Categories.") NORMAL (U"To make a selection, use the left mouse button.") NORMAL (U"The Ctrl key extends a selection (discontinuously).") NORMAL (U"The Shift key extends a selection contiguously.") MAN_END MAN_BEGIN (U"CC", U"djmw", 20010219) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"Any object that represents cepstral coefficients as a function of " "time.") MAN_END MAN_BEGIN (U"CC: Get value in frame...", U"djmw", 20140926) INTRO (U"Get the cepstral coefficient value at a specified position in a specified frame.") MAN_END MAN_BEGIN (U"CC: Get c0 value in frame...", U"djmw", 20140926) INTRO (U"Get the zeroth cepstral coefficient value in the specified frame. For a @MFCC object this value relates to energy.") MAN_END MAN_BEGIN (U"CCA", U"djmw", 20020323) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}. ") NORMAL (U"An object of type CCA represents the @@Canonical correlation " "analysis@ of two multivariate datasets.") ENTRY (U"Commands") NORMAL (U"Creation:") LIST_ITEM (U"\\bu @@TableOfReal: To CCA...@") MAN_END MAN_BEGIN (U"CCA: Get zero correlation probability...", U"djmw", 20040407) INTRO (U"Get the probability that for the selected @CCA object the chosen " "canonical correlation coefficient is different from zero.") ENTRY (U"Setting") TAG (U"##Index") DEFINITION (U"is the index of the canonical correlation coefficient that " "you want to test.") ENTRY (U"Algorithm") NORMAL (U"Wilks' statistic: the probability that coefficient \\ro__%index_ " "differs from zero is ") FORMULA (U" %probability = chiSquareQ (\\ci^2, %ndf),") NORMAL (U"where the %%number of degrees of freedom% parameter equals") FORMULA (U"%ndf = (%n__y_ - %index +1)(%n__x_ - %index +1)") NORMAL (U"and the chi-squared parameter is") FORMULA (U"\\ci^2 = \\--(%numberOfObservations - (%n__y_ + %n__x_ +3)/2) " "log (\\La__%index_),") NORMAL (U"In the formulas above the variables %n__y_ and %n__x_ are the " "dimensions of the dependent and the independent data sets whose " "canonical correlations have been " "obtained, and Wilks' lambda is:") FORMULA (U"\\La__index_ = \\Pi__%i=%index..min(%ny,%nx)_ (1 \\-- \\ro__%i_^^2^)") MAN_END MAN_BEGIN (U"CCA & Correlation: To TableOfReal (loadings)", U"djmw", 20020525) INTRO (U"Determine from the selected @CCA and @Correlation objects the correlations " "of the canonical variables with the original variables. These correlations are " "called %%canonical factor loadings%, or also %%structure correlation " "coefficients%.") MAN_END MAN_BEGIN (U"CCA & Correlation: Get variance fraction...", U"djmw", 20060323) INTRO (U"Determine from the selected @CCA and @Correlation objects the fraction of the variance " "explained by the selected @@canonical variate@ range.") ENTRY (U"Settings") TAG (U"##%X or Y") DEFINITION (U"determines whether you select the dependent (y) or the independent (x) set.") TAG (U"##Canonical variate range") DEFINITION (U"determines the canonical variates (or canonical variables).") ENTRY (U"Remarks") NORMAL (U"1. In general the variance fractions for a particular canonical variate in the " "dependent and in the independent set are not the same.") NORMAL (U"2. In general, the variance fractions for all canonical variates do not sum to 1.") ENTRY (U"Algorithm") NORMAL (U"The formula's can be found on page 170 of @@Cooley & Lohnes (1971)@.") NORMAL (U"For example, the fraction of the variance explained by the %i^^th^ canonical " "variable in the dependent set is:") FORMULA (U"%%fractionVariance% = ((#y__i_\\'p #R__yy_\\'p #R__yy_ #y__i_) / (#y__i_\\'p #R__yy_ #y__i_)) / %n__%y_,") NORMAL (U"where #y__%i_ is the eigenvector for dependent canonical variable %i and #R__%%yy%_ is the correlation matrix for the %n__%y_ variables in the dependent set.") MAN_END MAN_BEGIN (U"CCA & Correlation: Get redundancy (sl)...", U"djmw", 20060323) INTRO (U"Determine from the selected @CCA and @Correlation objects the Stewart-Love redundancy for the " "selected canonical variates.") NORMAL (U"The Stewart-Love redundancy for a single @@canonical variate@ is the fraction of variance explained by the selected " "canonical variate in a set times the fraction of shared variance between the corresponding canonical variates in the two sets.") NORMAL (U"The Stewart-Love redundancy for a canonical variate range is the sum of the individual redundancies.") ENTRY (U"Settings") TAG (U"##X or Y") DEFINITION (U"determines whether you select the dependent (y) or the independent (x) set.") TAG (U"##Canonical variate range") DEFINITION (U"determines the canonical variates (or canonical variables).") ENTRY (U"Algorithm") NORMAL (U"The formula's can be found on page 170 of @@Cooley & Lohnes (1971)@.") NORMAL (U"For example, the redundancy of the dependent set (y) given the independent set (x) for the %i^^%%th%^ canonical " "variate can be expressed as:") FORMULA (U"%R__%i_(y) = %%varianceFraction%__%i_(y) * \\ro__%i_^2, ") NORMAL (U"where %%varianceFraction%__%i_(y) is the @@CCA & Correlation: Get variance fraction...|variance fraction@ explained " "by the %i^^%%th%^ canonical variate of the dependent set, and \\ro__%i_ is the %i^^%%th%^ canonical correlation coefficient.") NORMAL (U"The redundancy for the selected canonical variate in the dependent set shows what " "fraction of the variance in the %%dependent% set is already \"explained\" by " "the variance in the %%independent% set, i.e. this fraction could be considered as redundant.") NORMAL (U"In the same way we can measure the redundancy of the independent (x) set giving the dependent set (y).") ENTRY (U"Remark") NORMAL (U"In general %R__%i_(y) \\=/ %R__%i_(x).") MAN_END MAN_BEGIN (U"CCA & TableOfReal: To TableOfReal (loadings)", U"djmw", 20020525) INTRO (U"Determine from the selected @CCA and @TableOfReal objects the correlations " "of the canonical variables with the original variables. These correlations are " "called %%canonical factor loadings%, or also %%structure correlation " "coefficients%.") MAN_END MAN_BEGIN (U"CCA & TableOfReal: To TableOfReal (scores)...", U"djmw", 20040407) INTRO (U"Determines the scores on the dependent and the independent canonical " "variates from the selected @CCA and @TableOfReal objects.") ENTRY (U"Settings") TAG (U"##Number of canonical correlations") DEFINITION (U"determines the dimension, i.e., the number of elements of the resulting " "canonical score vectors. The newly created table will have twice this number of " "columns because we have calculated score vectors for the dependent and the " "independent variates.") ENTRY (U"Behaviour") NORMAL (U"The scores on the dependent set are determined as #T__%y_ #Y, where " "#T__%y_ is the dependent part in the table and #Y is a matrix with " "%numberOfCanonicalCorrelations eigenvectors for the dependent variate.") NORMAL (U"The scores for the independent variates are then determined in an analogous " "way as #T__%x_ #X.") NORMAL (U"The scores for the dependent data will be in the lower numbered columns, " "the scores for the independent part will be in the higher numbered columns of " "the newly created object.") MAN_END MAN_BEGIN (U"Canonical correlation analysis", U"djmw", 20140509) INTRO (U"This tutorial will show you how to perform canonical correlation " "analysis with P\\s{RAAT}.") ENTRY (U"1. Objective of canonical correlation analysis") NORMAL (U"In canonical correlation analysis we try to find the correlations between " "two data sets. One data set is called the %dependent set, the other the " "%independent set. In P\\s{RAAT} these two sets must reside into one " "@TableOfReal object. The lower numbered columns of this table will then be " "interpreted as the dependent part, the rest of the columns as the " "independent part. " "The dimension of, i.e., the number of columns in, the dependent part may not " "exceed the dimension of the independent part.") NORMAL (U"As an example, we will use the dataset from @@Pols et al. (1973)@ " "with the frequencies and levels of the first three formants from the 12 " "Dutch monophthongal vowels as spoken in /h_t/ context by 50 male speakers. " "We will try to find the canonical correlation between formant frequencies " "(the %dependent part) and levels (the %independent part). " "The dimension of both groups of variates is 3. " "In the introduction of the " "@@discriminant analysis@ tutorial you can find how to get these data, " "how to take the logarithm of the formant frequency values and how to " "standardize them. The following script summarizes:") CODE (U"pols50m = Create TableOfReal (Pols 1973): \"yes\"") CODE (U"Formula: \"if col < 4 then log10 (self) else self endif\"") CODE (U"Standardize columns") NORMAL (U"Before we start with the %canonical correlation analysis we will first have " "a look at the %Pearson correlations of this table and " "calculate the @Correlation matrix. It is given by:") CODE (U" F1 F2 F3 L1 L2 L3") CODE (U"F1 1 -0.338 0.191 0.384 -0.505 -0.014") CODE (U"F2 -0.338 1 0.190 -0.106 0.526 -0.568") CODE (U"F3 0.191 0.190 1 0.113 -0.038 0.019") CODE (U"L1 0.384 -0.106 0.113 1 -0.038 0.085") CODE (U"L2 -0.505 0.526 -0.038 -0.038 1 0.128") CODE (U"L3 -0.014 -0.568 0.019 0.085 0.128 1") NORMAL (U"The following script summarizes:") CODE (U"selectObject: pols50m") CODE (U"To Correlation") CODE (U"Draw as numbers: 1, 0, \"decimal\", 3") NORMAL (U"The correlation matrix shows that high correlations exist between some " "formant frequencies and some levels. For example, the correlation " "coefficient between F2 and L2 equals 0.526.") NORMAL (U"In a canonical correlation analysis of the dataset above, we try " "to find the linear " "combination %u__1_ of %F__1_, %F__2_ and %F__3_ that correlates maximally " "with the linear combination %v__1_ of %L__1_, %L__2_ and %L__3_. " "When we have found these %u__1_ and %v__1_ we next try to find a new " "combination %u__2_ of the formant frequencies and a new combination " "%v__2_ of the levels that have maximum correlation. These %u__2_ and " "%v__2_ must be uncorrelated with %u__1_ and %v__1_. " "When we express the above with formulas we have:") FORMULA (U"%u__1_ = %y__11_%F__1_+%y__12_%F__2_ + %y__13_%F__3_") FORMULA (U"%v__1_ = %x__11_%L__1_+%x__12_%L__2_ + %x__13_%L__3_") FORMULA (U"\\ro(%u__1_, %v__1_) = maximum, \\ro(%u__2_, %v__2_) = submaximum, ") FORMULA (U"\\ro(%u__2_, %u__1_) = \\ro (%u__2_, %v__1_) = \\ro (%v__2_, %v__1_) " "= \\ro (%v__2_, %u__1_) = 0,") NORMAL (U"where the \\ro(%u__i_, %v__i_) are the correlations between the " "@@canonical variate@s %u__i_ and %v__i_ and the %y__%ij_'s and %x__%ij_'s are" " the ##canonical coefficients# for the dependent and the independent " "variates, respectively.") ENTRY (U"2. How to perform a canonical correlation analysis") NORMAL (U"Select the TableOfReal and choose from the dynamic menu the option " "@@TableOfReal: To CCA...|To CCA...@. This command is available in the " "\"Multivariate statistics\" action button. We fill out the form and supply " "3 for %%Dimension of dependent variate%. The resulting CCA object will bear " "the same name as the TableOfReal object. The following script summarizes:") CODE (U"selectObject: pols50m") CODE (U"cca = To CCA: 3") ENTRY (U"3. How to get the canonical correlation coefficients") NORMAL (U"You can get the canonical correlation coefficients by queries of the CCA " "object. You will find that the three canonical correlation coefficients, " "\\ro(%u__1_, %v__1_), \\ro(%u__2_, %v__2_) and \\ro(%u__3_, %v__3_) are " " approximately 0.86, 0.53 and 0.07, respectively. " "The following script summarizes:") CODE (U"cc1 = Get correlation: 1") CODE (U"cc2 = Get correlation: 2") CODE (U"cc3 = Get correlation: 3") CODE (U"writeInfoLine: \"cc1 = \", cc1, \", cc2 = \", cc2, \", cc3 = \", cc3") ENTRY (U"4. How to obtain canonical scores") NORMAL (U"Canonical #scores, also named @@canonical variate@s, are the linear combinations:") FORMULA (U"%u__%i_ = %y__%i1_%F__1_+%y__%i2_%F__2_ + %y__%i3_%F__3_, and,") FORMULA (U"%v__%i_ = %x__%i1_%L__1_+%x__%i2_%L__2_ + %x__%i3_%L__3_,") NORMAL (U"where the index %i runs from 1 to the number of correlation coefficients.") NORMAL (U"You can get the canonical scores by selecting a CCA object together with " "the TableOfReal object and choose " "@@CCA & TableOfReal: To TableOfReal (scores)...|To TableOfReal (scores)...@") NORMAL (U"When we now calculate the ##Correlation# matrix of these canonical variates we " "get the following table:") CODE (U" u1 u2 u3 v1 v2 v3") CODE (U"u1 1 . . 0.860 . .") CODE (U"u2 . 1 . . 0.531 .") CODE (U"u3 . . 1 . . 0.070") CODE (U"v1 0.860 . . 1 . .") CODE (U"v2 . 0.1 . . 1 .") CODE (U"v3 . . 0.070 . . 1") NORMAL (U"The scores with a dot are zero to numerical precision. In this table the " "only correlations that differ from zero are the canonical correlations. " "The following script summarizes:") CODE (U"selectObject: cca, pols50m") CODE (U"To TableOfReal (scores): 3)") CODE (U"To Correlation") CODE (U"Draw as numbers if: 1, 0, \"decimal\", 2, \"abs(self) > 1e-14") ENTRY (U"5. How to predict one dataset from the other") NORMAL (U"@@CCA & TableOfReal: Predict...@") NORMAL (U"Additional information can be found in @@Weenink (2003)@.") MAN_END MAN_BEGIN (U"CCA & TableOfReal: Predict...", U"djmw", 20020503) INTRO (U"") MAN_END MAN_BEGIN (U"Chebyshev polynomials", U"djmw", 19990620) INTRO (U"The Chebyshev polynomials %T__%n_(%x) of degree %n are special orthogonal polynomial functions " "defined on the domain [-1, 1].") NORMAL (U"Orthogonality:") FORMULA (U"__-1_\\in^^1^ %W(%x) %T__%i_(%x) %T__%j_(%x) %dx = \\de__%ij_") FORMULA (U"%W(%x) = (1 \\-- %x^^2^)^^\\--1/2^ (-1 < x < 1)") NORMAL (U"They obey certain recurrence relations:") FORMULA (U"%T__%n_(%x) = 2 %x %T__%n-1_(%x) \\-- %T__%n-2_(%x)") FORMULA (U"%T__0_(%x) = 1") FORMULA (U"%T__1_(%x) = %x") MAN_END MAN_BEGIN (U"ChebyshevSeries", U"djmw", 19990620) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"An object of type ChebyshevSeries represents a linear combination of @@Chebyshev polynomials@ " "%T__%k_(%x).") FORMULA (U"ChebyshevSeries (%x) = \\Si__%k=1..%numberOfCoefficients_ %c__%k_ %T__%k_(%x)") MAN_END MAN_BEGIN (U"ChebyshevSeries: To Polynomial", U"djmw", 19990620) INTRO (U"A command to transform the selected @ChebyshevSeries object into a @@Polynomial@ object.") NORMAL (U"We find polynomial coefficients %c__%k_ such that") FORMULA (U"\\Si__%k=1..%numberOfCoefficients_ %c__%k_ %x^^%k^ = \\Si__%k=1.." "%numberOfCoefficients_ %l__%k_ %T__%k_(%x)") NORMAL (U"We use the recurrence relation for @@Chebyshev polynomials@ to calculate these coefficients.") MAN_END MAN_BEGIN (U"ClassificationTable: To Confusion...", U"djmw", 20141030) INTRO (U"A command to create a @Confusion object from the selected @ClassificationTable object.") ENTRY (U"Settings") TAG (U"##Only class labels#") DEFINITION (U"defines whether the class labels from the ClassificationTable object will be used not only as response labels but also as stimulus labels. If checked the resulting Confusion will always have equal stimulus and response labels. If not checked the stimulus labels will be determined from the row labels of the ClassificationTable object. ") ENTRY (U"Behaviour") NORMAL (U"In obtaining a Confusion object from a ClassificationTable we explicitly use its row labels as stimulus labels.") MAN_END MAN_BEGIN (U"ClassificationTable", U"djmw", 19990525) INTRO (U"One of the @@types of objects@ in Praat.") NORMAL (U"An object of type ClassificationTable represents the result of a classification experiment. " "The numbers in a row show how well a particular input matches the classes represented by the " "column labels. The higher the number the better the match.") MAN_END MAN_BEGIN (U"concentration ellipse", U"djmw", 20071113) INTRO (U"The percentage of bivariate normally distributed data covered by an ellipse " "whose axes have a length of %numberOfSigmas\\.c\\si can be obtained by integration of the p.d.f. " "over an elliptical area. This results in the following equation as can be " "verified from equation 26.3.21 in @@Abramowitz & Stegun (1970)@:") FORMULA (U"%percentage = (1 - exp (-%numberOfSigmas^^2^/2))\\.c 100\\% ,") NORMAL (U"where the %numberOfSigmas is the radius of the \"ellipse\":") FORMULA (U"(%x/%\\si__x_)^2 + (%y/%\\si__y_)^2 = %numberOfSigmas^2.") NORMAL (U"The %numberOfSigmas = 1 ellipse covers 39.3\\% , " "the %numberOfSigmas = 2 ellipse covers 86.5\\% and " "the %numberOfSigmas = 3 ellipse covers 98.9\\% of the data.") NORMAL (U"From the formula above we can show that if we want to cover %p percent of the data, we have to " "chose %numberOfSigmas as:") FORMULA (U"%numberOfSigmas = \\Vr(-2 ln(1-%p/100)).") NORMAL (U"For covering 95\\% of the data we calculate %numberOfSigmas = 2.45.") MAN_END MAN_BEGIN (U"confidence interval", U"djmw", 20011105) INTRO (U"The confidence interval gives an estimated range of values which " "is likely to include an unknown population parameter. " "The estimated range is calculated from a given set of observations.") ENTRY (U"Examples") NORMAL (U"At the \\al level of significance a two sided confidence interval " "for the true mean \\mu for normally distributed data with mean %%mean% and " "known standard deviation %\\si can be constructed as:") FORMULA (U"%%mean% - %z__\\al/2_ \\si / \\Vr%N \\<_ \\mu \\<_ " "%%mean% + %z__\\al/2_ \\si / \\Vr%N,") NORMAL (U"where %z__\\al/2_ = invGaussQ (\\al/2) and %N is the number of observations.") NORMAL (U"If the standard deviation is %not known, we have to estimate its value (%s) " "from the data and the formula above becomes:") FORMULA (U"%%mean% - %t__%%\\al/2;N%_ %s / \\Vr%N \\<_ \\mu \\<_ " "%%mean% + %t__%%\\al/2;N%_ %s / \\Vr%N,") NORMAL (U"where %t__%%\\al/2;N%_ = invStudentQ (%\\al/2, %N-1).") NORMAL (U"For %\\al=0.05 and %N=20 we get %z__0.025_=1.96 and %t__0.025;20_=2.039. " "This shows that when we have to estimate the standard deviation from the data, " "the confidence interval is wider than when the standard deviation is known " "beforehand.") MAN_END MAN_BEGIN (U"confidence level", U"djmw", 20011105) NORMAL (U"The confidence level is the probability value 1-\\al associated " "with a @@confidence interval@, where \\al is the level of significance. " "It can also be expressed as a percentage 100(1-\\al)\\% and is than " "sometimes called the %%confidence coefficient%.") MAN_END MAN_BEGIN (U"Confusion", U"djmw", 20110517) INTRO (U"One of the @@types of objects@ in Praat.") NORMAL (U"An object of type Confusions represents a confusion matrix, with " "stimuli as row labels and responses as column labels. The entry at " "position [%i][%j] represents the number of times response %j " "was given to the stimulus %i.") ENTRY (U"Creating a Confusion from data in a text file") NORMAL (U"Suppose you have two objects A and B. " "In one way or another, you have acquired the following " "confusions: %\\de__%AA_ = 6, %\\de__%AB_ = 2 , %\\de__%BA_ = 1, " "and %\\de__%BB_ = 7.") NORMAL (U"You can create a simple text file like the following:") CODE (U"\"ooTextFile\" ! to make Praat recognize your file") CODE (U"\"Confusion\" ! The line that tells Praat about the contents") CODE (U"2 \"A\" \"B\" ! Number of columns, and column labels") CODE (U"2 ! Number of rows") CODE (U"\"A\" 6 2 ! Row label A, A-A value, A-B value") CODE (U"\"B\" 1 7 ! Row label B, B-A value, B-B value") NORMAL (U"This text file can be read with the @@Read from file...@ command. ") ENTRY (U"Commands") NORMAL (U"Creation:") LIST_ITEM (U"\\bu @@Categories: To Confusion") LIST_ITEM (U"\\bu @@Create simple Confusion...") NORMAL (U"Drawing") LIST_ITEM (U"\\bu ##Draw as numbers...") LIST_ITEM (U"\\bu ##Draw as squares...") NORMAL (U"Query") LIST_ITEM (U"\\bu @@Confusion: Get fraction correct|Get fraction correct") LIST_ITEM (U"\\bu @@Confusion: Get stimulus sum...") LIST_ITEM (U"\\bu @@Confusion: Get response sum...") LIST_ITEM (U"\\bu ##Get grand sum") NORMAL (U"Modification") LIST_ITEM (U"\\bu ##Formula...") LIST_ITEM (U"\\bu @@Confusion: Increase...") NORMAL (U"Grouping") LIST_ITEM (U"\\bu @@Confusion: Group stimuli...@") LIST_ITEM (U"\\bu @@Confusion: Group responses...@") NORMAL (U"Analysis:") LIST_ITEM (U"\\bu @@Confusion: To Similarity...@") LIST_ITEM (U"\\bu @@Confusion: To Dissimilarity (pdf)...@") ENTRY (U"Inside a Confusion") NORMAL (U"With @Inspect you will see the following attributes:") TAG (U"%numberOfRows") DEFINITION (U"the number of stimuli.") TAG (U"%numberOfColumns") DEFINITION (U"the number of responses.") TAG (U"%rowLabels") DEFINITION (U"the names of the stimuli.") TAG (U"columnLabels") DEFINITION (U"the names of the responses.") MAN_END MAN_BEGIN (U"Create simple Confusion...", U"djmw", 20140117) INTRO (U"Creates a square @@Confusion|confusion matrix@ with equal stimulus labels and response labels.") ENTRY (U"Example") NORMAL (U"The command ##Create simple Confusion: \"simple\", \"u i a\"# results in the following Confusion:") CODE (U" u i a ! The response labels") CODE (U"u 0 0 0 ! Responses on stimulus u,") CODE (U"i 0 0 0 ! Responses on stimulus i") CODE (U"a 0 0 0 ! Responses on stimulus a") MAN_END MAN_BEGIN (U"Confusion: Increase...", U"djmw", 20140117) INTRO (U"Increases the contents of the corresponding cell in the selected @@Confusion@ by one.") ENTRY (U"Settings") TAG (U"##Stimulus# and ##Response#") DEFINITION (U"define the cell whose value will be increased by one.") ENTRY (U"Example") NORMAL (U"Given the following Confusion:") CODE (U" u i a ! The response labels") CODE (U" u 6 2 1 ! Responses on stimulus u,") CODE (U" i 3 4 2 ! Responses on stimulus i") CODE (U" a 1 4 4 ! Responses on stimulus a") NORMAL (U"The command ##Increase: \"u\", \"i\"# results in:") CODE (U" u i a ! The responses") CODE (U" u 6 3 1 ! Responses on stimulus u,") CODE (U" i 3 4 2 ! Responses on stimulus i") CODE (U" a 1 4 4 ! Responses on stimulus a") MAN_END MAN_BEGIN (U"Confusion: Group...", U"djmw", 20140117) INTRO (U"Groups a number of stimuli and responses into one new category.") ENTRY (U"Settings") TAG (U"##Stimuli & Responses") DEFINITION (U"defines the labels that will be grouped.") TAG (U"##New label") DEFINITION (U"defines the new label for the grouped labels.") TAG (U"##New label position") DEFINITION (U"the row/column number for the new group label.") ENTRY (U"Example") NORMAL (U"Given the following selected Confusion:") CODE (U" u i a ! The response labels") CODE (U" u 6 2 1 ! Responses on stimulus u,") CODE (U" i 3 4 2 ! Responses on stimulus i") CODE (U" a 1 4 4 ! Responses on stimulus a") NORMAL (U"After the command ##Group stimuli: \"u i\", \"high\", 0#, the new Confusion will be:") CODE (U" high a ! The new response labels") CODE (U" high 15 3 ! Responses on group %%high%") CODE (U" a 5 4 ! Responses on stimulus a") NORMAL (U"Instead after the command ##Group stimuli: \"u i\", \"high\", 2#, the new Confusion will be:") CODE (U" a high ! The new response labels") CODE (U" a 4 5 ! Responses on stimulus a") CODE (U" high 3 15 ! Responses on group %%high%") MAN_END MAN_BEGIN (U"Confusion: Group stimuli...", U"djmw", 20140117) INTRO (U"Groups a number of stimuli into one new category.") ENTRY (U"Settings") TAG (U"##Stimuli") DEFINITION (U"defines the stimuli that will be grouped.") TAG (U"##New label") DEFINITION (U"defines the new label for the grouped stimuli.") TAG (U"##New label position") DEFINITION (U"the row number for the new group label.") ENTRY (U"Example") NORMAL (U"Given the following selected Confusion:") CODE (U" u i a ! The response labels") CODE (U" u 6 2 1 ! Responses on stimulus u,") CODE (U" i 3 4 2 ! Responses on stimulus i") CODE (U" a 1 4 4 ! Responses on stimulus a") NORMAL (U"After the command ##Group stimuli: \"u i\", \"high\", 1#, the new Confusion will be:") CODE (U" u i a ! The response labels") CODE (U" high 9 6 3 ! Responses on stimulus group %%high%,") CODE (U" a 1 4 4 ! Responses on stimulus a") MAN_END MAN_BEGIN (U"Confusion: Group responses...", U"djmw", 20140117) INTRO (U"Groups a number of responses into one new category.") ENTRY (U"Settings") TAG (U"##Responses") DEFINITION (U"defines the responses that will be grouped.") TAG (U"##New label") DEFINITION (U"defines the new label for the grouped responses.") TAG (U"##New label position") DEFINITION (U"the column number for the new group label.") ENTRY (U"Example") NORMAL (U"Given the following selected Confusion:") CODE (U" u i a ! The response labels") CODE (U" u 6 2 1 ! Responses on stimulus u,") CODE (U" i 3 4 2 ! Responses on stimulus i") CODE (U" a 1 4 4 ! Responses on stimulus a") NORMAL (U"After the command ##Group responses: \"a i\", \"front\", 1#, the new Confusion will be:") CODE (U" front i ! The new response labels") CODE (U" u 7 2 ! Responses on stimulus u,") CODE (U" i 5 4 ! Responses on stimulus i") CODE (U" a 5 4 ! Responses on stimulus a") MAN_END MAN_BEGIN (U"Confusion: Get stimulus sum...", U"djmw", 20140117) INTRO (U"Returns the number of responses for the chosen stimulus (the sum of all the numbers in the row with this stimulus label). ") ENTRY (U"Example") NORMAL (U"Given the following selected Confusion:") CODE (U" u i a ! The response labels") CODE (U" u 6 2 1 ! Responses on stimulus u,") CODE (U" i 3 4 2 ! Responses on stimulus i") CODE (U" a 1 4 4 ! Responses on stimulus a") NORMAL (U"The command ##Get stimulus sum: \"a\"# will return the number 9.") MAN_END MAN_BEGIN (U"Confusion: Get response sum...", U"djmw", 20140117) INTRO (U"Returns the number of times the chosen response was given (the sum of all the numbers in the column with this response label).") ENTRY (U"Example") NORMAL (U"Given the following selected Confusion:") CODE (U" u i a ! The response labelss") CODE (U" u 6 2 1 ! Responses on stimulus u,") CODE (U" i 3 4 2 ! Responses on stimulus i") CODE (U" a 1 4 4 ! Responses on stimulus a") NORMAL (U"The command ##Get response sum: \"a\"# will return the number 7.") MAN_END MAN_BEGIN (U"Confusion: Condense...", U"djmw", 20130410) INTRO (U"Groups row and column labels of the selected @Confusion object in " "order to reduce its dimension. ") ENTRY (U"Settings") TAG (U"##Search") DEFINITION (U"the pattern to match.") TAG (U"##Replace") DEFINITION (U"the pattern that replaces the match(es).") TAG (U"##Replace limit") DEFINITION (U"limits the maximum number of times that a match/replace cycle " "may occur within each label.") TAG (U"##Search and replace are") DEFINITION (U"defines whether the search and replace strings are taken " "literally or as a @@Regular expressions|regular expression@.") ENTRY (U"Behaviour") NORMAL (U"First all row and column labels are changed according to the search " "and replace specification. Next all rows or columns that have the same " "labels are summed. ") MAN_END MAN_BEGIN (U"Confusion: Get fraction correct", U"djmw", 20000225) INTRO (U"A @@query@ to ask the selected @Confusion matrix for the fraction of " "correct classifications.") NORMAL (U"The \"fraction correct\" is defined as the quotient of the number " "of correct classifications and the sum of the entries in the matrix.") NORMAL (U"Correct classifications have identical row and column labels.") MAN_END MAN_BEGIN (U"Confusion & ClassificationTable: Increase confusion count", U"djmw", 201411101) INTRO (U"Increases the contents of cell(s) in the selected @@Confusion@. The cells to increase are determined by the selected " "@ClassificationTable.") ENTRY (U"Behaviour") NORMAL (U"For each row in the ClassificationTable object the contents of one cell in the Confusion we be increased by one. " "This cell is determined as follows: we start by finding the label of the column wich the largest number in it. " "This label is defined as the ##response label#. We use the corresponding row label as the ##stimulus label#. The content " "of the cell in the Confusion object whose row and column are labeled with ##stimulus label# and ##response label#, " "respectively, is increased by one.") MAN_END MAN_BEGIN (U"Confusion: To TableOfReal (marginals)", U"djmw", 20011031) INTRO (U"A new @TableOfReal object is created from the selected @Confusion " "object with one extra row and column. ") NORMAL (U"The first element of the extra row will contain the sum of the " "confusions in the the first %column, the first element of the extra " "column will contain the sum of the confusions in the the first %row, " "etc... The bottom-right element will contain the sum of all confusions.") MAN_END MAN_BEGIN (U"Correlation", U"djmw", 19990105) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"An object of type Correlation represents the correlation coefficients " "of a multivariate data set.") MAN_END MAN_BEGIN (U"Correlation: Confidence intervals...", U"djmw", 20040407) INTRO (U"Calculates @@confidence interval@s for the correlation coefficients " "from the selected @Correlation object(s) and saves these intervals in a " "new @TableOfReal object.") ENTRY (U"Settings") TAG (U"##Confidence level") DEFINITION (U"the @@confidence level@ you want for the confidence intervals.") TAG (U"##Number of tests") DEFINITION (U"determines the @@Bonferroni correction@ for the significance " "level. If the default value (zero) is chosen, it will be set equal " "to the number of correlations involved (a matrix of dimension %n " "has %n\\.c(%n-1)/2 correlations).") TAG (U"##Approximation") DEFINITION (U"defines the approximation that will be used to calculate the " "confidence intervals. It is either Fisher's z transformation or Ruben's " "transformation. According to @@Boomsma (1977)@, Ruben's approximation is " "more accurate than Fisher's.") ENTRY (U"Algorithm") NORMAL (U"We obtain intervals by the large-sample conservative multiple tests " "with Bonferroni inequality and the Fisher or Ruben transformation. " "We put the upper values of the confidence intervals in the upper " "triangular part of the matrix and the lower values of the confidence " "intervals in lower triangular part of the resulting TableOfReal object.") NORMAL (U"In %%Fisher's approximation%, for each element %r__%ij_ of the " "correlation matrix the confidence interval is:") FORMULA (U"#[ tanh (%z__%ij_ - %z__%\\al\\'p_ / \\Vr(%N - 3)) , " "tanh (%z__%ij_ + %z__%\\al\\'p_ / \\Vr(%N - 3)) #],") NORMAL (U"where %z__%ij_ is the Fisher z-transform of the correlation %r__%ij_:") FORMULA (U"%z__%ij_ = 1/2 ln ((1 + %r__%ij_) / (1 - %r__%ij_)), ") NORMAL (U"%z__%\\al\\'p_ the Bonferroni corrected %z-value " "%z__%\\al/(2\\.c%numberOfTests)_, ") FORMULA (U"%\\al = 1 - %confidenceLevel,") NORMAL (U"and %N the number of observations that the correlation matrix is " "based on.") NORMAL (U"In %%Ruben's approximation% the confidence interval for element %r__%ij_ " "is:") FORMULA (U"#[ %x__1_ / \\Vr(1 - %x__1_^2), %x__2_ / \\Vr(1 - %x__2_^2) #]") NORMAL (U"in which %x__1_ and %x__2_ are the smallest and the largest root from") FORMULA (U"%a %x^^2^ + %b %x + %c = 0, with") FORMULA (U"%a = 2%N - 3 - %z__%\\al\\'p_^^2^") FORMULA (U"%b = - 2 %r\\'p \\Vr((2%N - 3)(2%N - 5))") FORMULA (U"%c = (2%N - 5 - %z__%\\al\\'p_^^2^) %r\\'p^^2^ - 2%z__%\\al\\'p_^^2^, and") FORMULA (U"%r\\'p = %r__%ij_ / \\Vr(1 - %r__%ij_^2),") MAN_END MAN_BEGIN (U"Covariance", U"djmw", 19990105) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"An object of type Covariance represents the sums of squares and cross " "products of a multivariate data set divided by the number of observations.") NORMAL (U"An object of type Covariance contains the same attributes as an object of " "type @SSCP.") NORMAL (U"Since an object of type Covariance contains the mean values (the " "centroids), the covariances as well as the number of observations it has " "all the information necessary to be the subject of all kinds of statistical " "tests on means and variances.") MAN_END MAN_BEGIN (U"Create simple Covariance...", U"djmw", 20101125) INTRO (U"Create a @@Covariance@ matrix with its centroid.") ENTRY (U"Settings") TAG (U"##Covariances") DEFINITION (U"define the covariances. Because a covariance matrix is a symmetric matrix, only the upper triangular " "part of the matrix has to be input (row-wise). If your covariance matrix is " "of dimension %d, your input needs %d(%d+1)/2 elements. The first %d input elements are the elements of the first " "row of the covariance matrix, the next %d-1 input elements are for the second row, then %d-2 for the third row, etc.") TAG (U"##Centroid") DEFINITION (U"defines the centroid. ") TAG (U"##Number of observations") DEFINITION (U"defines the number of observations. ") MAN_END MAN_BEGIN (U"Covariance: Set value...", U"djmw", 20101124) INTRO (U"Input @@Covariance@ matrix cell values.") ENTRY (U"Constraints on input values") TAG (U"A covariance matrix is a %%symmetric% matrix: values input at cell [%i,%j] will be automatically input at " "cell [%j,%i] too.") TAG (U"All values on the diagonal must be positive numbers.") TAG (U"The absolute value of an off-diagonal element at cell [%i,%j] must be smaller than the corresponding diagonal " "elements at cells [%i,%i] and [%j,%j].") MAN_END MAN_BEGIN (U"Covariance: Difference", U"djmw", 20090624) INTRO (U"You can choose this command after selecting two objects of type @Covariance. ") NORMAL (U"We test the hypothesis that the samples that gave rise to the two " "covariance matrices #%M__1_ and #%M__2_, have equal covariances. " "The test statistic is %L\\'p which is distributed as " "a \\ci^2 variate with %p(%p+1)/2 degrees of freedom.") FORMULA (U"%L\\'p = %L \\.c (1 \\-- (2%p + 1 \\-- 2 / (%p + 1)) / (6 \\.c ( %N \\-- 1))),") NORMAL (U"where, ") FORMULA (U"%L = (%N \\-- 1) \\.c (ln determinant (#%M__1_) \\-- ln determinant " "(#%M__2_)) + trace (#%M__2_ \\.c #%M__1_^^\\--1^) \\-- %p), ") NORMAL (U"%p is dimension of covariance matrix and " "%N is the number of observations underlying the covariance matrix. ") NORMAL (U"For more details on this test, see e.g. page 292 of @@Morrison (1990)@.") MAN_END MAN_BEGIN (U"Covariance: Get significance of one mean...", U"djmw", 20040407) INTRO (U"Gets the level of significance for one mean from the selected " "@Covariance object being different from a hypothesized mean.") ENTRY (U"Settings") TAG (U"##Index") DEFINITION (U"the position of the element in the means vector (centroid) that " "you want to test. ") TAG (U"##Value") DEFINITION (U"the hypothesized mean %\\mu (see below).") ENTRY (U"Behaviour") NORMAL (U"This is the standard test on means when the variance is unknown. " "The test statistic is") FORMULA (U"%t = (%mean - %\\mu) \\Vr%(N / %s^2),") NORMAL (U"which has the Student %t distribution with %ndf = %N-1 degrees of freedom.") NORMAL (U"In the formulas above, %mean is the element of the mean vector at " "position %index, %\\mu is the hypothesized mean, " "%N is the number of observations, %s^2 " "is the variance at position [%index][%index] in the covariance matrix.") NORMAL (U"The returned probability %p is the %%two-sided% probability") FORMULA (U"%p = 2 * studentQ (%t, %ndf)") NORMAL (U"A low probability %p means that the difference is significant.") MAN_END MAN_BEGIN (U"Covariance: Get fraction variance...", U"djmw", 20040407) INTRO (U"A command to ask the selected @Covariance object for the fraction " "of the total variance that is accounted for by the selected dimension(s).") ENTRY (U"Settings") TAG (U"##From dimension#, ##To dimension#") DEFINITION (U"define the range of components. By choosing both numbers equal, " "you get the fraction of the variance \"explained\" by that dimension.") ENTRY (U"Details") NORMAL (U"The total variance is the sum of the diagonal elements of the covariance " "matrix #C, i.e., its trace. " "The fraction is defined as:") FORMULA (U"\\Si__%i=%from..%to_ %%C__ii_% / \\Si__%i=1..%numberOfRows_ %%C__ii_%") MAN_END MAN_BEGIN (U"Covariance: Get significance of means difference...", U"djmw", 20040407) INTRO (U"Gets the level of significance for the %difference of two means " "from the selected @Covariance object being different from a hypothesized " "value.") ENTRY (U"Settings") TAG (U"##Index1#, ##Index2#") DEFINITION (U"the positions of the two elements of the means vector whose " "difference is compared to the hypothesized difference.") TAG (U"##Value") DEFINITION (U"the hypothesized difference (%\\mu).") TAG (U"##Paired samples") DEFINITION (U"determines whether we treat the two means as being dependent. ") TAG (U"##Equal variances") DEFINITION (U"determines whether the distribution of the difference of the means " "is a Student t-distribution (see below).") ENTRY (U"Behaviour") NORMAL (U"This is Student's t-test for the significance of a difference of means. " "The test statistic is:") FORMULA (U"%t = (%mean__1_ - %mean__2_ - %\\mu) \\Vr (%N / %s^2) with %ndf " "degrees of freedom.") NORMAL (U"In the formula above %mean__1_ and %mean__2_ are the elements of the " "means vector, %\\mu is the hypothesized difference and %N is the number of " "observations. The value that we use for the (combined) variance %s^2 is:") FORMULA (U"%s^2 = %var__1_ + %var__2_ - 2 * %covar__12_,") NORMAL (U"when the samples are %paired, and ") FORMULA (U"%s^2 = %var__1_ + %var__2_ ") NORMAL (U"when they are not.") NORMAL (U"The %var__1_ and %var__2_ are the variance components for " "%mean__1_ and %mean__2_, respectively, and %covar__12_ is their covariance." " When we have %%paired samples% we assume that the two variances are " "not independent and their covariance is subtracted, otherwise their " "covariance is not taken into account. Degrees of freedom parameter %ndf " "usually equals 2(%N-1). ") NORMAL (U"If the two variances are significantly different, the statistic %t " "above is only %approximately distributed as Student's %t with " "degrees of freedom equal to:") FORMULA (U"%ndf = (%N-1) \\.c (%var__1_ + %var__2_)^2 / (%var__1_^2 + " "%var__2_^2).") NORMAL (U"The returned probability %p will be the %%two-sided% probability") FORMULA (U"%p = 2 * studentQ (%t, %ndf)") NORMAL (U"A low probability %p means that the difference is significant.") MAN_END MAN_BEGIN (U"Covariance: Get significance of one variance...", U"djmw", 20040407) INTRO (U"Gets the probability for one variance from the selected " "@Covariance object being different from a hypothesized variance.") ENTRY (U"Settings") TAG (U"##Index") DEFINITION (U"the position of the variance element.") TAG (U"##Hypothesized variance") DEFINITION (U"the hypothesized variance %\\si^2") ENTRY (U"Behaviour") NORMAL (U"The test statistic") FORMULA (U"%\\ci^2 = (%N-1)%s^2 / %\\si^2,") NORMAL (U"is distributed as a chi-squared variate with %ndf = %N-1 degrees of freedom.") NORMAL (U"The returned probability %p will be ") FORMULA (U"%p = chiSquareQ (%\\ci^2, %ndf)") MAN_END MAN_BEGIN (U"Covariance: Get significance of variance ratio...", U"djmw", 20040407) INTRO (U"Gets the probability for the ratio of two variances " "from the selected @Covariance object being different from a hypothesized " "ratio.") ENTRY (U"Settings") TAG (U"##Index1#, ##Index2#") DEFINITION (U"determine the variances.") TAG (U"##Hypothesized ratio") DEFINITION (U"the hypothesized ratio %F.") ENTRY (U"Behaviour") NORMAL (U"The test statistic") FORMULA (U"%f = %s__1_^2 / %s__2_^2 / %ratio") NORMAL (U"is distributed as Fisher's F distribution with %ndf__1_ = %N-1 and " "%ndf__2_ = %N-1 degrees of freedom for the numerator and denominator terms, " "respectively.") NORMAL (U"The returned probability %p will be the %%two-sided% probability") FORMULA (U"%p = 2 * fisherQ (%f, %ndf__1_, %ndf__2_)") NORMAL (U"If %s__2_^2 > %s__1_^2 we use 1/%f to determine the probability.") MAN_END MAN_BEGIN (U"Covariances: Report multivariate mean difference...", U"djmw", 20090627) INTRO (U"Reports the probability that the two multivariate means of the selected @@Covariance@s are equal.") ENTRY (U"Settings") TAG (U"##Covariances are equal") DEFINITION (U"determines whether the test is performed as if the two covariance matrices are equal or not.") ENTRY (U"Algorithm") NORMAL (U"For equal covariance matrices the test is via Hotelling's T^^2^ as described in @@Morrison (1990)|Morrison (1990,@ page 141). " "The test statistic is %F = (%N__1_+%N__2_-%p-1)/((%N__1_+%N__2_-2)%p)\\.c T^^2^, with %p and %N__1_+%N__2_-%p-1 degrees of freedom.") NORMAL (U"If the covariance matrices are not equal, we apply a correction on the number of degrees of freedom as " "proposed by @@Krishnamoorthy & Yu (2004)@. The test statistic in this case is %F = (\\nu-%p+1)/(%p\\nu)\\.c T^^2^, " "with %p and \\nu degrees of freedom. Here \\nu is a corrected number of degrees of freedom. ") NORMAL (U"(The test for unequal covariances simplifies to Welch's approximate solution for the univariate t-test with unequal variances.) ") MAN_END MAN_BEGIN (U"Covariances: Report equality", U"djmw", 20090701) INTRO (U"Reports the probability that the selected @@Covariance@ matrices are equal.") NORMAL (U"We use the Bartlett test and the Wald test. According to @@Schott (2001)@, " "both tests are overly sensitive to violations of normality.") MAN_END MAN_BEGIN (U"Covariance: To TableOfReal (random sampling)...", U"djmw", 20101101) INTRO (U"Generate a @TableOfReal object by random sampling from a multi-variate " "normal distribution whose @Covariance matrix is the selected object.") ENTRY (U"Setting") TAG (U"##Number of data points") DEFINITION (U"determines the number of data points that will be generated. Each " "data point occupies one row in the generated table.") ENTRY (U"Algorithm") NORMAL (U"The algorithm proceeds as follows:") LIST_ITEM (U"1. Diagonalize the covariance matrix: calculate the eigenvalues $v__%i_ and " "eigenvectors %#e__%i_ of the %m \\xx %m Covariance matrix. " "In general there will also be %m of these. Let #%E be the %m \\xx %m matrix " "with eigenvector %#e__%j_ in column %j (%j=1..%m).") LIST_ITEM (U"2. Generate a vector #x whose elements %x__%k_ equal %x__%k_ = " "randomGauss (0, \\Vr (%v__%k_)). " "Each %x__%k_ is a random deviate drawn from a Gaussian distribution with " "mean zero and standard deviation equal to the square root of the corresponding " "eigenvalue %v__%k_.") LIST_ITEM (U"3. Rotate back: calculate the vector #y = #%E #x, obtained by multiplying the vector " "#x with the matrix #%E.") LIST_ITEM (U"4. Add the centroid to #y and copy the elements of #y to the corresponding row of " "the TableOfReal object.") LIST_ITEM (U"5. Repeat steps 2, 3 and 4 until the desired number of data points " "has been reached.") LIST_ITEM (U"6. Copy the column labels from the Covariance object to the " "TableOfReal object.") NORMAL (U"In case the covariance matrix is diagonal, the algorithm is much simpler: we can skip " "the first and third step.") MAN_END MAN_BEGIN (U"Covariance & TableOfReal: Extract quantile range...", U"djmw", 20040225) INTRO (U"Extract those rows from the selected @TableOfReal object whose Mahalanobis " "distance, with respect to the selected @Covariance object, are within the " "quantile range.") MAN_END MAN_BEGIN (U"Covariance & TableOfReal: To TableOfReal (mahalanobis)...", U"djmw", 20140509) INTRO (U"Calculate Mahalanobis distance for the selected @TableOfReal with respect to the " "selected @Covariance object.") ENTRY (U"Setting") TAG (U"##Use table centroid") DEFINITION (U"Use the mean vector calculated from the columns in the selected TableOfReal instead of the means in the selected Covariance.") ENTRY (U"Explanation") NORMAL (U"The Mahalanobis distance is defined as") FORMULA (U"%d = \\Vr((#%x - #mean)\\'p #S^^-1^ (#%x - #mean)),") NORMAL (U"where #%x is a vector, #mean is the average and #S is the covariance matrix. ") NORMAL (U"It is the multivariate form of the distance measured in units of standard deviation.") ENTRY (U"Example") NORMAL (U"Count the number of items that are within 1, 2, 3, 4 and 5 standard deviations from the mean.") NORMAL (U"We first create a table with only one column and 10000 rows and fill it with numbers drawn from " "a normal distribution with mean zero and standard deviation one. Its covariance matrix, of course, is " "one dimensional. We next create a table with Mahalanobis distances.") CODE (U"n = 100000") CODE (U"t0 = Create TableOfReal: \"table\", n, 1") CODE (U"Formula: \"randomGauss(0,1)\"") CODE (U"c = To Covariance") CODE (U"selectObject: c, t0") CODE (U"ts = To TableOfReal (mahalanobis): \"no\"") CODE (U"") CODE (U"for nsigma to 5") CODE1 (U" selectObject: ts") CODE1 (U" extraction = Extract rows where: \"self < nsigma\"") CODE1 (U" nr = Get number of rows") CODE1 (U" nrp = nr / n * 100") CODE1 (U" expect = (1 - 2 * gaussQ (nsigma)) * 100") CODE1 (U" writeInfoLine: nsigma, \"-sigma: \", nrp, \"%, \", expect, \"%\"") CODE1 (U" removeObject: extraction") CODE (U"endfor") MAN_END MAN_BEGIN (U"Create ChebyshevSeries...", U"djmw", 20040407) INTRO (U"A command to create a @ChebyshevSeries from a list of coefficients.") ENTRY (U"Settings") TAG (U"##Xmin# and ##Xmax#") DEFINITION (U"define the domain of the polynomials.") TAG (U"%Coefficients") DEFINITION (U"define the coefficients of each @@Chebyshev polynomials|Chebyshev polynomial@. " "The coefficient of the polynomial with the highest degree comes last.") MAN_END MAN_BEGIN (U"Create ISpline...", U"djmw", 20040407) INTRO (U"A command to create an @ISpline from a list of coefficients.") ENTRY (U"Settings") TAG (U"##Xmin# and ##Xmax#") DEFINITION (U"define the domain of the polynomial @spline.") TAG (U"%Degree") DEFINITION (U"defines the degree of the polynomial @spline.") TAG (U"%Coefficients") DEFINITION (U"define the coefficients of the basis polynomials.") TAG (U"%%Interior knots") DEFINITION (U"define the positions in the domain where continuity conditions are defined.") ENTRY (U"Behaviour") NORMAL (U"The number of coefficients and the number of interior knots must satisfy " "the following relation:") FORMULA (U"%numberOfCoefficients = %numberOfInteriorKnots + %degree") NORMAL (U"") MAN_END MAN_BEGIN (U"Create MSpline...", U"djmw", 20040407) INTRO (U"A command to create an @MSpline from a list of coefficients.") ENTRY (U"Settings") TAG (U"##Xmin# and ##Xmax#") DEFINITION (U"define the domain of the polynomial @spline.") TAG (U"##Degree") DEFINITION (U"defines the degree of the polynomial @spline.") TAG (U"##Coefficients") DEFINITION (U"define the coefficients of the basis polynomials.") TAG (U"##Interior knots") DEFINITION (U"define the positions in the domain where continuity conditions are defined.") ENTRY (U"Behaviour") NORMAL (U"The number of coefficients and the number of interior knots must satisfy " "the following relation:") FORMULA (U"%numberOfCoefficients = %numberOfInteriorKnots + %degree + 1") NORMAL (U"") MAN_END MAN_BEGIN (U"Create Polynomial...", U"djmw", 20040407) INTRO (U"A command to create an @Polynomial from a list of coefficients.") ENTRY (U"Settings") TAG (U"##Xmin# and ##Xmax#") DEFINITION (U"define the domain of the polynomial.") TAG (U"##Degree") DEFINITION (U"defines the degree of the basis polynomials.") TAG (U"##Coefficients") DEFINITION (U"define the coefficients of the polynomial. The coefficient of the " "highest power of %x comes last.") MAN_END MAN_BEGIN (U"Create LegendreSeries...", U"djmw", 20040407) INTRO (U"A command to create a @LegendreSeries from a list of coefficients.") ENTRY (U"Settings") TAG (U"##Xmin# and ##Xmax#") DEFINITION (U"define the domain of the polynomials.") TAG (U"##Coefficients") DEFINITION (U"define the coefficients of each @@Legendre polynomials|Legendre polynomial@. " "The coefficient of the polynomial with the highest degree comes last.") MAN_END MAN_BEGIN (U"Create Sound from gammatone...", U"djmw", 20100517) INTRO (U"A command to create a @Sound as a @@gammatone@.") ENTRY (U"Settings") TAG (U"##Name") DEFINITION (U"the name of the resulting Sound object.") TAG (U"##Minimum time (s)# and ##Maximum time (s)#") DEFINITION (U"the start and end time of the resulting Sound.") TAG (U"##Sampling frequency (Hz)") DEFINITION (U"the @@sampling frequency@ of the resulting Sound.") TAG (U"##Gamma") DEFINITION (U"determines the exponent of the polynomial.") TAG (U"##Frequency (Hz)# and ##Bandwidth (Hz)#") DEFINITION (U"determine the frequency and damping of the cosine wave in the gammatone.") TAG (U"##Initial phase (radians)") DEFINITION (U"the initial phase of the cosine wave.") TAG (U"##Addition factor# (standard value: 0)") DEFINITION (U"determines the degree of asymmetry in the spectrum of the gammatone. " "The zero default value gives a gammatone. A value unequal to zero results in a " "so called %gammachirp. A negative value is used in auditory filter modeling to " "guarantee the usual direction of filter asymmetry, which corresponds to an upward " "glide in instantaneous frequency.") TAG (U"##Scale amplitudes") DEFINITION (U"determines whether the amplitudes will be scaled to fit in the range (-1, 1).") ENTRY (U"Purpose") NORMAL (U"to create a Sound according to the following formula:") FORMULA (U"%t^^%\\ga\\--1^ e^^\\--2%\\pi\\.c%bandwidth\\.c%t^ " "cos (2%%\\pi\\.cfrequency\\.ct% + %additionFactor\\.cln(%t) + %initialPhase),") NORMAL (U"The %gammachirp function has a monotonically frequency-modulated carrier (the chirp) with " "instantaneous frequency ") FORMULA (U"%instantaneousFrequency(%t) = %frequency + %additionFactor / (2\\.c\\pi\\.c%t)") NORMAL (U"and an envelope that is a gamma distribution function. It is a theoretically optimum " "auditory filter, in the sense that it leads to minimal uncertainty in the joint time and " "scale representation of auditory signal analysis.") NORMAL (U"For faithful modelling of the inner ear, " "@@Irino & Patterson (1997)@ conclude that a value of approximately 1.5 * ERB (%frequency) " "is appropriate for %bandwidth. " "ERB stands for @@equivalent rectangular bandwidth@. Their formula for ERB is:") FORMULA (U"ERB(%f) = 6.23 10^^\\--6^ %f^2 + 93.39 10^^\\--3^ %f + 28.52.") NORMAL (U"To avoid @aliasing in the chirp sound, a sound is only generated during times where the " "instantaneous frequency is greater than zero and smaller than the @@Nyquist frequency@.") MAN_END MAN_BEGIN (U"Create Sound from Shepard tone...", U"djmw", 20140117) INTRO (U"One of the commands that create a @Sound.") ENTRY (U"Settings") TAG (U"##Name") DEFINITION (U"the name of the resulting Sound object.") TAG (U"##Minimum time (s)# and ##Maximum time (s)") DEFINITION (U"the start and end time of the resulting Sound.") TAG (U"##Sampling frequency (Hz)") DEFINITION (U"the @@sampling frequency@ of the resulting Sound.") TAG (U"##Lowest frequency (Hz)") DEFINITION (U"the frequency of the lowest component in the tone complex.") TAG (U"##Number of components") DEFINITION (U"the number of frequency components in the tone complex.") TAG (U"##Frequency change (semitones/s)") DEFINITION (U"determines how many semitones the frequency of each component will change in one second. " "The number of seconds needed to change one octave will then be 12 divided by ##Frequency change#. " "You can make rising, falling and monotonous tone complexes by chosing a positive, negative or zero value.") TAG (U"##Amplitude range% (dB)") DEFINITION (U"determines the relative size in decibels of the maximum and the minimum amplitude of the components in a tone complex. These relative amplitudes will then be 10^^\\--%amplitudeRange/20^. ") TAG (U"##Octave shift fraction (0-1)") DEFINITION (U"shifts all frequency components by this fraction at the start. You will probably only need this " "if you want to generate static tone complexes as the example script below shows.") ENTRY (U"Purpose") NORMAL (U"To create a Sound that is a continuous variant of the sound sequences " "used by @@Shepard (1964)@ in his " "experiment about the circularity in judgments of relative pitch.") NORMAL (U"The tone consists of many sinusoidal components whose frequencies " "might increase exponentially in time. " "All frequencies are always at successive intervals of an octave and sounded simultaneously. " "Thus the frequency of each component above the lowest is at each moment in time exactly twice " "the frequency of the one just below. The amplitudes are large for the components of intermediate " "frequency only, and tapered off gradually to subthreshold levels for the components at the " "highest and lowest extremes of frequency.") NORMAL (U"For a rising tone complex, the Sound is generated according to the following specification:") FORMULA (U"%s(%t) = \\su__%i=1..%numberOfComponents_ %A__%i_(%t) sin (arg__%i_(%t)), where") FORMULA (U"arg__%i_(%t) = \\in 2%\\pi f__%i_(%\\ta) %d\\ta , and") FORMULA (U"f__%i_(%t) = %lowestFrequency \\.c 2^^(%i \\-- 1 + octaveShiftFraction + %t/(12/%frequencyChange_st)^, with") FORMULA (U"%A__%i_(%t) = 10^^((%L__min_ + (%L__max_ \\-- %L__min_) (1 \\-- cos 2%\\pi%\\te__%i_(%t)) / 2) / 20)^, where,") FORMULA (U"%L__max_ = 0, %L__min_ = 10^^\\--%amplitudeRange/20^, and,") FORMULA (U"%\\te__%i_(%t) = 2\\pi log2 (%f(%t) / %lowestFrequency) / %numberOfComponents.") NORMAL (U"The maximum frequency that can be reached during a sweep by any single tone is:") FORMULA (U"%maximumFrequency = %lowestFrequency\\.c2^^%numberOfComponents^.") NORMAL (U"A component that reaches the maximum frequency falls instantaneously to the lowest frequency and then starts rising again.") NORMAL (U"The absolute @@sound pressure level@ of the resulting sound will not be set, it is only guaranteed that the peak value " "is just below 1. You can always scale the intensity with the ##Scale Intensity...# command.") ENTRY (U"Example") NORMAL (U"The following script generates 12 static Shepard tone complexes, 1 semitone 'apart', " "with a cosine window to temper the abrupt start and finish.") CODE (U"fadeTime = 0.010") CODE (U"for i to 12") CODE1 (U"fraction = (i-1)/12") CODE1 (U"Create Sound from Shepard tone: \"s\" + string\\$ (i), 0, 0.1, 22050, 4.863, 10, 0, 34, fraction") CODE1 (U"Fade in: 0, 0, fadeTime, \"no\"") CODE1 (U"Fade out: 0, 0.1, -fadeTime, \"no\"") CODE (U"endfor") MAN_END MAN_BEGIN (U"Create formant table (Peterson & Barney 1952)", U"djmw", 20080509) INTRO (U"A command to create a @Table object filled with the " "fundamental frequency and the first three formant frequency values from 10 " "American-English monophthongal vowels as spoken in a /h_d/ context by 76 speakers " "(33 men, 28 women and 15 children). Every vowel was pronounced twice, so that there are " "1520 recorded vowels in total.") ENTRY (U"Table layout") NORMAL (U"The created table will contain 9 columns:") TAG (U"Column 1, labelled as %Type") DEFINITION (U"speaker type: \"m\", \"w\" or \"c\" (for %man, %women or %child).") TAG (U"Column 2, labelled as %Sex") DEFINITION (U"speaker sex: either \"m\" or \"f\" (for %male or %female).") TAG (U"Column 3, labelled as %Speaker") DEFINITION (U"speaker id: a number from 1 to 76.") TAG (U"Column 4, labelled as %Vowel") DEFINITION (U"the vowel name. The following list gives the vowel in a %h_d context word " "together with its representation in this column: (%heed, iy), (%hid, ih), " "(%head, eh), (%had, ae), (%hod, aa), (%hawed, ao), (%hood, uh), (%%who'd%, uw), " "(%hud, ah), (%heard, er).") TAG (U"Column 5, labelled as %IPA") DEFINITION (U"the IPA notation for the vowels as defined in @@Peterson & Barney (1952)@. ") TAG (U"Column 6, labelled as %F0") DEFINITION (U"the fundamental frequency in Hertz.") TAG (U"Column 7, 8 and 9, labelled as %F1, %F2 and %F3") DEFINITION (U"the frequencies in Hertz of the first three formants.") ENTRY (U"Remarks") NORMAL (U"We originally downloaded the data from the University of Pennsylvania FTP site, " "where they were reportedly based on a printed version supplied by Ignatius Mattingly. ") NORMAL (U"About the IPA notation. We used the original notation from the Peterson & Barney article. " "The notation in @@Watrous (1991)@ differs for three vowels: Watrous uses /e, o, \\er/ where Peterson & Barney use /\\ef, \\ct, \\er\\hr/.") NORMAL (U"More details about these data and how they were measured can be found in the articles" "@@Watrous (1991)@ and in @@Peterson & Barney (1952)@.") MAN_END MAN_BEGIN (U"Create formant table (Pols & Van Nierop 1973)", U"djmw", 20020620) INTRO (U"A command to create a @Table object filled with the frequencies and the levels " "of the first three formants from the 12 Dutch monophthong " "vowels as spoken in /h_t/ context by 50 male and 25 female speakers.") ENTRY (U"Table layout") NORMAL (U"The created table will contain 10 columns") TAG (U"Column 1, labeled as %Sex") DEFINITION (U"speaker sex: Either \"m\" or \"f\" (for %male or %female).") TAG (U"Column 2, labeled as %Speaker") DEFINITION (U"speaker id: a number from 1 to 75.") TAG (U"Column 3, labeled as %Vowel") DEFINITION (U"the vowel name. The following list gives the vowel in p_t context word " "together with its representation in this column: (%poet, oe), (%paat, aa), " "(%poot, oo), (%pat, a), (%peut, eu), (%piet, ie), (%puut, uu), (%peet, ee), " "(%put, u), (%pet, e), (%pot, o), (%pit, i).") TAG (U"Column 4, labeled as %IPA") DEFINITION (U"the IPA-notation for the vowels") TAG (U"Column 5, 6 and 7, labeled as %F1, %F2 and %F3") DEFINITION (U"the frequencies in Hertz of the first three formants.") TAG (U"Column 8, 9 and 10, labeled as %L1, %L2 and %L3") DEFINITION (U"the levels in decibel below overall SPL of the first three formants.") NORMAL (U"More details about these data and how they were measured can be found " "in @@Pols et al. (1973)@ and @@Van Nierop et al. (1973)@.") MAN_END MAN_BEGIN (U"Create formant table (Weenink 1985)", U"djmw", 20041217) INTRO (U"A command to create a @Table object filled with the " "fundamental frequency and the first three formant frequency values from 12 " "Dutch monophthongal vowels as spoken in isolation by 30 speakers " "(10 men, 10 women and 10 children). Every vowel was pronounced only once, so that there are " "360 recorded vowels in total. A reduced form, with only the formant frequecy values, is also available " "as a @@Create TableOfReal (Weenink 1985)...|TableOfReal@.") ENTRY (U"Table layout") NORMAL (U"The created table will contain 9 columns:") TAG (U"Column 1, labelled as %Type") DEFINITION (U"speaker type: \"m\", \"w\" or \"c\" (for %man, %women or %child).") TAG (U"Column 2, labelled as %Sex") DEFINITION (U"speaker sex: either \"m\" or \"f\" (for %male or %female).") TAG (U"Column 3, labelled as %Speaker") DEFINITION (U"speaker id: a number from 1 to 76.") TAG (U"Column 4, labelled as %Vowel") DEFINITION (U"the vowel name. The following list gives the vowel in Dutch p_t context words " "together with its representation in this column: (%poet, oe), (%paat, aa), " "(%poot, oo), (%pat, a), (%peut, eu), (%piet, ie), (%puut, uu), (%peet, ee), " "(%put, u), (%pet, e), (%pot, o), (%pit, i).") TAG (U"Column 5, labelled as %IPA") DEFINITION (U"the IPA notation for the vowels.") TAG (U"Column 6, labelled as %F0") DEFINITION (U"the fundamental frequency in Hertz.") TAG (U"Column 7, 8 and 9, labelled as %F1, %F2 and %F3") DEFINITION (U"the frequencies in Hertz of the first three formants. ") NORMAL (U"The formant frequency values have been determined by means of LPC analysis with a " "varying prediction order. See @@Weenink (1985)@.") MAN_END MAN_BEGIN (U"Create TableOfReal (Pols 1973)...", U"djmw", 19990426) INTRO (U"A command to create a @TableOfReal filled with the first three formant " "frequency values and (optionally) the levels from the 12 Dutch monophthongal " "vowels as spoken in /h_t/ context by 50 male speakers.") NORMAL (U"The first three columns will contain the frequencies in Hz, the next three columns " "the levels in decibels below the overall SPL of the measured vowel segment. Each row will " "be labelled with its corresponding vowel symbol.") NORMAL (U"More details about these data and how they were measured can be found in the paper of " "@@Pols et al. (1973)@.") MAN_END MAN_BEGIN (U"Create TableOfReal (Van Nierop 1973)...", U"djmw", 20041217) INTRO (U"A command to create a @TableOfReal filled with the first three formant " "frequency values and (optionally) the levels from the 12 Dutch monophthongal " "vowels as spoken in /h_t/ context by 25 female speakers.") NORMAL (U"The first three columns will contain the frequencies in Hz, the next three columns " "the levels in decibels below the overall SPL of the measured vowel segment. Each row will " "be labelled with its corresponding vowel symbol.") NORMAL (U"More details about these data and how they were measured can be found in the paper of " "@@Van Nierop et al. (1973)@.") MAN_END MAN_BEGIN (U"Create TableOfReal (Weenink 1985)...", U"djmw", 19990426) INTRO (U"A command to create a @TableOfReal filled with the first three formant " "frequency values from the 12 Dutch monophthongal " "vowels as spoken in isolation by either 10 men or 10 women or 10 children.") NORMAL (U"The three columns will contain the formant frequencies in Hz. Each row will " "be labelled with its corresponding vowel symbol.") NORMAL (U"More details about these data and how they were measured can be found in the paper of " "@@Weenink (1985)@.") MAN_END MAN_BEGIN (U"Discriminant", U"djmw", 19981103) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"An object of type Discriminant represents the discriminant structure of a multivariate " "data set with several groups. This discriminant structure consists of a number of orthogonal " "directions in space, along which maximum separability of the groups can occur.") ENTRY (U"Commands") NORMAL (U"Creation:") LIST_ITEM (U"\\bu @@Discriminant analysis@ tutorial") LIST_ITEM (U"\\bu @@TableOfReal: To Discriminant@") NORMAL (U"Drawing") LIST_ITEM (U"\\bu Draw eigenvalues...") LIST_ITEM (U"\\bu Draw eigenvector...") LIST_ITEM (U"\\bu @@Discriminant: Draw sigma ellipses...|Draw sigma ellipses...@") MAN_END MAN_BEGIN (U"Discriminant analysis", U"djmw", 20150902) INTRO (U"This tutorial will show you how to perform discriminant analysis with P\\s{RAAT}") NORMAL (U"As an example, we will use the dataset from @@Pols et al. (1973)@ " "with the frequencies and levels of the first three formants from the 12 " "Dutch monophthongal vowels as spoken in /h_t/ context by 50 male speakers. " "This data set has been incorporated into " "Praat and can be called into play with the @@Create TableOfReal " "(Pols 1973)...@ command that can be found in the \"New / " "TableOfReal\" menu.") NORMAL (U"In the list of objects a new TableOfReal object will appear with 6 " "columns and 600 rows " "(50 speakers \\xx 12 vowels). The first three columns contain " "the formant frequencies in Hz, the last three columns contain the levels " "of the first three formants " "given in decibels below the overall sound pressure level of the measured " "vowel segment. Each row is labelled with a vowel label.") NORMAL (U"Pols et al. use logarithms of frequency values, we will too. Because " "the measurement units in the first three columns are in Hz and in the last " "three columns in dB, it is probably better to standardize the columns. " "The following script summarizes our achievements up till now:") CODE (U"table = Create TableOfReal (Pols 1973): \"yes\"") CODE (U"Formula: \"if col < 4 then log10 (self) else self fi\"") CODE (U"Standardize columns") CODE (U"\\# change the column labels too, for nice plot labels.") CODE (U"Set column label (index): 1, \"standardized log (\\% F\\_ \\_ 1\\_ )\"") CODE (U"Set column label (index): 2, \"standardized log (\\% F\\_ \\_ 2\\_ )\"") CODE (U"Set column label (index): 3, \"standardized log (\\% F\\_ \\_ 3\\_ )\"") CODE (U"Set column label (index): 4, \"standardized \\% L\\_ \\_ 1\\_ \"") CODE (U"Set column label (index): 5, \"standardized \\% L\\_ \\_ 2\\_ \"") CODE (U"Set column label (index): 6, \"standardized \\% L\\_ \\_ 3\\_ \"") NORMAL (U"To get an indication of what these data look like, we make a scatter " "plot of the " "first standardized log-formant-frequency against the second standardized " "log-formant-frequency. With the next script fragment you can reproduce the " "following picture.") CODE (U"Viewport: 0, 5, 0, 5") CODE (U"selectObject: table") CODE (U"Draw scatter plot: 1, 2, 0, 0, -2.9, 2.9, -2.9, 2.9, 10, \"yes\", \"+\", \"yes\"") PICTURE (5, 5, drawPolsF1F2_log) NORMAL (U"Apart from a difference in scale this plot is the same as fig. 3 in the " "Pols et al. article.") ENTRY (U"1. How to perform a discriminant analysis") NORMAL (U"Select the TableOfReal and choose from the dynamic menu the option " "@@TableOfReal: To Discriminant|To Discriminant@. This command is available " "in the \"Multivariate statistics\" action button. The resulting Discriminant " "object will bear the same name as the TableOfReal object. The following " "script summarizes:") CODE (U"selectObject: table") CODE (U"discrimimant = To Discriminant") ENTRY (U"2. How to project data on the discriminant space") NORMAL (U"You select a TableOfReal and a Discriminant object together and choose: " "@@Discriminant & TableOfReal: To Configuration...|To Configuration...@. " "One of the options of the newly created Configuration object is to draw it. " "The following picture shows how the data look in the plane spanned by the " "first two dimensions of this Configuration. The directions in this " "configuration are the eigenvectors from the Discriminant.") PICTURE (5, 5, drawPolsDiscriminantConfiguration) NORMAL (U"The following script summarizes:") CODE (U"selectObject: table, discriminant") CODE (U"To Configuration: 0") CODE (U"Viewport: 0, 5, 0, 5") CODE (U"Draw: 1, 2, -2.9, 2.9, -2.9, 2.9, 12, \"yes\", \"+\", \"yes\"") NORMAL (U"If you are only interested in this projection, there also is a short cut " "without an intermediate Discriminant object: " "select the TableOfReal object and choose @@TableOfReal: To Configuration " "(lda)...|To Configuration (lda)...@.") ENTRY (U"3. How to draw concentration ellipses") NORMAL (U"Select the Discriminant object and choose @@Discriminant: Draw sigma " "ellipses...|Draw sigma ellipses...@. In the form you can fill out the " "coverage of the ellipse by way of the %%Number of sigmas% parameter. " "You can also select the projection " "plane. The next figure shows the 1-%\\si concentration ellipses in the " "standardized log %F__1_ vs log %F__2_ plane. When the data are multinormally distributed, " "a 1-%\\si ellipse will cover approximately 39.3\\% of the data. " "The following code summarizes:") CODE (U"selectObject: discriminant") CODE (U"Draw sigma ellipses: 1.0, \"no\", 1, 2, -2.9, 2.9, -2.9, 2.9, 12, \"yes\"") PICTURE (5, 5, drawPolsF1F2ConcentrationEllipses) ENTRY (U"4. How to classify") NORMAL (U"Select together the Discriminant object (the classifier), and " "a TableOfReal object (the data to be classified). Next you choose " "@@Discriminant & TableOfReal: To ClassificationTable...|To " "ClassificationTable@. " "Normally you will enable the option %%Pool covariance matrices% and " "the pooled covariance matrix will be used for classification.") NORMAL (U"The ClassificationTable can be converted to a @Confusion object " "and its fraction correct can be queried with: " "@@Confusion: Get fraction correct@.") NORMAL (U"In general you would separate your data into two independent sets, " "\\s{TRAIN} and \\s{TEST}. You would use \\s{TRAIN} to train the " "discriminant classifier and \\s{TEST} to test how well it classifies. " "Several possibilities for splitting a dataset into two sets exist. " "We mention the @@jackknife@ (\"leave-one-out\") and the " "@@bootstrap@ methods (\"resampling\").") ENTRY (U"5.1 Jacknife classification") NORMAL (U"The following script summarizes #jackknife classification of the dataset:") CODE (U"selectObject: table") CODE (U"numberOfRows = Get number of rows") CODE (U"for irow to numberOfRows") CODE (U" selectObject: table") CODE (U" rowi = Extract rows where: \"row = irow\"") CODE (U" selectObject: table") CODE (U" rest = Extract rows where: \"row <> irow\"") CODE (U" discriminant = To Discriminant") CODE (U" plusObject: rowi") CODE (U" classification = To ClassificationTable: \"yes\", \"yes\"") CODE (U" if irow = 1") CODE (U" confusion = To Confusion: \"yes\"") CODE (U" else") CODE (U" plusObject: confusion") CODE (U" Increase confusion count") CODE (U" endif") CODE (U" removeObject: rowi, rest, discriminant, classification") CODE (U"endfor") CODE (U"selectObject: confusion") CODE (U"fractionCorrect = Get fraction correct") CODE (U"appendInfoLine: fractionCorrect, \" (= fraction correct, jackknifed \", numberOfRows, \" times).\"") CODE (U"removeObject: confusion") ENTRY (U"5.2 Bootstrap classification") NORMAL (U"The following script summarizes bootstrap classification.") CODE (U"fractionCorrect = 0") CODE (U"for i to numberOfBootstraps") CODE (U" selectObject: table") CODE (U" resampled = To TableOfReal (bootstrap)") CODE (U" discriminant = To Discriminant") CODE (U" plusObject: resampled") CODE (U" classification = To ClassificationTable: \"yes\", \"yes\"") CODE (U" confusion = To Confusion: \"yes\"") CODE (U" fc = Get fraction correct") CODE (U" fractionCorrect += fc") CODE (U" removeObject: resampled, discriminant, classification, confusion") CODE (U"endfor") CODE (U"fractionCorrect /= numberOfBootstraps") CODE (U"appendInfoLine: fractionCorrect, \" (= fraction correct, bootstrapped \", numberOfBootstraps, \" times).\"") MAN_END MAN_BEGIN (U"Discriminant: Draw sigma ellipses...", U"djmw", 20040407) INTRO (U"A command to draw for each group from the selected @Discriminant an ellipse " "that covers part of the multivariate data.") ENTRY (U"Settings") TAG (U"##Number of sigmas") DEFINITION (U"determines the @@concentration ellipse|data coverage@.") TAG (U"##Discriminant plane") DEFINITION (U"When on, the selected %X and %Y-dimension will refer to the eigenvectors " "of the discriminant space, and, consequently, the projection of the hyper ellipsoid " "onto the space spanned by these eigenvectors will be drawn. When off, the selected " "%X and Y-dimension will refer to the original dimensions.") TAG (U"##Xmin#, ##Xmax#, ##Ymin#, ##Ymax#") DEFINITION (U"determine the limits of the drawing area.") TAG (U"##Label size") DEFINITION (U"determines the size of the labels at the centre of the ellipse. No " "labels will be drawn when a value less than or equal to zero is chosen.") MAN_END MAN_BEGIN (U"Discriminant: Extract within-group SSCP...", U"djmw", 20020314) INTRO (U"Extract the @SSCP for group %%index% from the selected @Discriminant " "object.") MAN_END MAN_BEGIN (U"Discriminant: Extract pooled within-groups SSCP", U"djmw", 20020314) INTRO (U"Extract the pooled within-group @SSCP from the selected @Discriminant " "object.") MAN_END MAN_BEGIN (U"Discriminant: Get partial discrimination probability...", U"djmw", 19981102) INTRO (U"A command to test the selected @Discriminant for the significance of " "discrimination afforded by the remaining %n\\--%k eigenvectors after the acceptance of " "the first %k eigenvectors.") ENTRY (U"Details") NORMAL (U"The test statistic is:") FORMULA (U"%\\ci^2 = \\--(%degreesOfFreedom\\--(%numberOfGroups+%dimension)/2) ln \\La\\'p, where") FORMULA (U"%degreesOfFreedom = (%dimension\\--%k)(%numberOfGroups\\--%k\\--1), and, ") FORMULA (U"\\La\\'p = \\Pi__%j=%k+1..%numberOfEigenvalues_ 1 / (1 + %%eigenvalue[j]%)") MAN_END MAN_BEGIN (U"Discriminant: Get contribution of component...", U"djmw", 19981106) INTRO (U"A command to ask the selected @Discriminant for the contribution of the %j^^th^ " "discriminant function (component) to the total variance.") ENTRY (U"Details") NORMAL (U"The contribution is defined as:") FORMULA (U"%%eigenvalue[j]% / \\Si__%i=1..%numberOfEigenvalues_ %%eigenvalue[i]%") MAN_END MAN_BEGIN (U"Discriminant: Get Wilks' lambda...", U"djmw", 20040407) INTRO (U"A command to ask the selected @Discriminant for the value of Wilks' lamda (a " "multivariate measure of group differences over several variables).") ENTRY (U"Settings") TAG (U"##From") DEFINITION (U"the first eigenvalue number from which the value for lambda has to be calculated.") ENTRY (U"Details") NORMAL (U"Wilks' lambda is defined as:") FORMULA (U"%\\La = \\Pi__%i=%from..%numberOfEigenvalues_ 1 / (1 + %eigenvalue[%i])") NORMAL (U"Because lambda is a kind of %inverse measure, values of lambda which are near zero " "denote high discrimination between groups.") MAN_END MAN_BEGIN (U"Discriminant: Get concentration ellipse area...", U"djmw", 20040407) INTRO (U"A command to query the @Discriminant object for the area of the concentration " "ellipse of one of its groups.") ENTRY (U"Settings") TAG (U"##Number of sigmas") DEFINITION (U"determines the @@concentration ellipse|data coverage@.") TAG (U"##Discriminant plane") DEFINITION (U"When on, the selected %X and %Y-dimension will refer to the eigenvectors " "of the discriminant space, and, consequently, the area of the projection of the hyper ellipsoid " "onto the space spanned by these eigenvectors will be calculated. When off, the selected " "%X and Y-dimension will refer to the original dimensions.") ENTRY (U"Algorithm") NORMAL (U"See @@SSCP: Get sigma ellipse area...") MAN_END MAN_BEGIN (U"Discriminant: Get confidence ellipse area...", U"djmw", 20040407) INTRO (U"A command to query the @Discriminant object for the area of the confidence " "ellipse of one of its groups.") ENTRY (U"Settings") TAG (U"##Discriminant plane") DEFINITION (U"When on, the selected %X and %Y-dimension will refer to the eigenvectors " "of the discriminant space, and, consequently, the area of the projection of the hyper ellipsoid " "onto the space spanned by these eigenvectors will be calculated. When off, the selected " "%X and Y-dimension will refer to the original dimensions.") ENTRY (U"Algorithm") NORMAL (U"See @@SSCP: Get confidence ellipse area...") MAN_END MAN_BEGIN (U"Discriminant & Pattern: To Categories...", U"djmw", 20040422) INTRO (U"A command to use the selected @Discriminant to classify each pattern from the " "selected @Pattern into a category.") NORMAL (U"Arguments as in @@Discriminant & TableOfReal: To ClassificationTable...@.") MAN_END MAN_BEGIN (U"Discriminant & SSCP: Project", U"djmw", 20020313) INTRO (U"A command to project the selected @SSCP object on the eigenspace " "defined by the selected @Discriminant object.") NORMAL (U"Further details can be found in @@Eigen & SSCP: Project@") MAN_END MAN_BEGIN (U"Discriminant & TableOfReal: To ClassificationTable...", U"djmw", 20040407) INTRO (U"A command to use the selected @Discriminant to classify each row from the " "selected @TableOfReal. The newly created @ClassificationTable will then contain the posterior " "probabilities of group membership.") ENTRY (U"Settings") TAG (U"##Pool covariance matrices") DEFINITION (U"when on, all group covariance matrices are pooled and distances will be determined " "on the basis of only this pooled covariance matrix (see below).") ENTRY (U"Details") NORMAL (U"The posterior probabilities of group membership %p__%j_ for a vector #x are defined as:") FORMULA (U"%p__%j_ = %p(%j\\| #%x) = exp (\\--%d__%j_^^2^(#%x) / 2) / " "\\su__%k=1..%numberOfGroups_ exp (\\--%d__%k_^^2^(#%x) / 2),") NORMAL (U"where %d__%i_^^2^ is the generalized squared distance function:") FORMULA (U"%d__%i_^^2^(#%x) = ((#%x\\--#%\\mu__%i_)\\'p #\\Si__%i_^^-1^ (#%x\\--#%\\mu__%i_) + " "ln determinant (#\\Si__%i_)) / 2 \\-- ln %aprioriProbability__%i_") NORMAL (U"that depends on the individual covariance matrix #\\Si__%i_ and the mean " "#%\\mu__%i_ for group %i.") NORMAL (U"When the covariances matrices are %pooled, the squared distance function can be reduced to:") FORMULA (U"%d__%i_^^2^(#%x) = ((#%x\\--#%\\mu__%i_)\\'p #\\Si^^-1^ (#%x\\--#%\\mu__%i_) " "\\-- ln %aprioriProbability__%i_,") NORMAL (U"and #\\Si is now the pooled covariance matrix.") NORMAL (U"The a priori probabilities normally will have values that are related to the number of " "%training vectors %n__%i_ in each group:") FORMULA (U"%aprioriProbability__%i_ = %n__%i_ / \\Si__%k=1..%numberOfGroups_ %n__%k_") MAN_END MAN_BEGIN (U"Discriminant & TableOfReal: To Configuration...", U"djmw", 20040407) INTRO (U"A command to project each row in the selected @TableOfReal onto " "a space spanned by the eigenvectors of the selected @Discriminant. ") ENTRY (U"Settings") TAG (U"##Number of dimensions") DEFINITION (U"specifies the number of eigenvectors taken into account, i.e., determines " "the dimension of the resulting @Configuration. When the default value (0) is " "given the resulting Configuration will have the maximum dimension as allowed by " "the number of eigenvectors in the selected Discriminant.") ENTRY (U"Precondition") NORMAL (U"The number of columns in the TableOfReal must equal the dimension of the " "eigenvectors in the Discriminant.") NORMAL (U"See also @@Eigen & TableOfReal: Project...@.") MAN_END MAN_BEGIN (U"Discriminant & TableOfReal: To TableOfReal (mahalanobis)...", U"djmw", 20140509) INTRO (U"Calculate Mahalanobis distances for the selected @TableOfReal with respect to one group in the " "selected @Discriminant object.") ENTRY (U"Settings") TAG (U"##Group label") DEFINITION (U"defines which group mean to use for the distance calculation.") TAG (U"##Pool covariance matrices") DEFINITION (U"when on use a pooled covariance matrix instead of the group covariance matrix.") ENTRY (U"Algorithm") NORMAL (U"See @@Covariance & TableOfReal: To TableOfReal (mahalanobis)...@.") ENTRY (U"Example") NORMAL (U"Calculate the number of datapoints that are within the one-sigma elipses of two different groups, i.e. " "the number of data points that are in the overlapping area. ") NORMAL (U"Suppose the group labels are \\o/ and \\yc.") CODE (U"pols50m = Create TableOfReal (Pols 1973): \"no\"") CODE (U"Formula: \"log10(self)\"") CODE (U"discriminant = To Discriminant") CODE (U"selectObject: pols50m, discriminant") CODE (U"t1 = To TableOfReal (mahalanobis): \"\\bso/\", \"no\"") CODE (U"selectObject: pols50m, discriminant") CODE (U"t2 = To TableOfReal (mahalanobis): \"\\bsyc\", \"no\"") NORMAL (U"Now we count when both the t1 and t2 values are smaller than 1 (sigma):") CODE (U"Copy: \"tr\"") CODE (U"Formula: \"Object_'t1'[] < 1 and Object_'t2'[] < 1\"") CODE (U"Extract rows where column: 1, \"equal to\", 1") CODE (U"no = Get number of rows\"") MAN_END MAN_BEGIN (U"DTW", U"djmw", 20110603) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"An object of type DTW represents the dynamic time warp structure of " "two objects.") ENTRY (U"Commands") NORMAL (U"Creation:") LIST_ITEM (U"\\bu @@CC: To DTW...@ (from 2 objects with cepstral coefficients)") LIST_ITEM (U"\\bu ##Spectrogram: To DTW...# (from 2 Spectrogram objects)") NORMAL (U"Query:") LIST_ITEM (U"\\bu @@DTW: Get y time from x time...@") LIST_ITEM (U"\\bu @@DTW: Get x time from y time...@") MAN_END MAN_BEGIN (U"DTW: Draw warp (x)...", U"djmw", 20071204) INTRO (U"Draws the warp given a time on the \"x-direction\"") MAN_END MAN_BEGIN (U"DTW: Find path (band & slope)...", U"djmw", 20120223) INTRO (U"Finds the optimal path for the selected @DTW that lies within the union of the sakoe-chiba band and local slope limits.") ENTRY (U"Settings") TAG (U"##Sakoe-Chiba band (s)#,") DEFINITION (U"The maximum distance from the start/end of the sound where a path may start/finish.") TAG (U"##Slope constraint#,") DEFINITION (U"determines the maximum and minimum local slopes in the optimal path. For example, the constraint " "1/3 < slope < 3 forces the path locally after having taken three steps in the same direction direction to take the next step in the other direction, or after having taken two steps in the same direction to take the next step in the diagonal direction. At the same time the global consequences of the \"1/3 < slope < 3\" constraint mandates that the durations of the two domains do not differ by more than a factor of three. ") NORMAL (U"For more information see the article of @@Sakoe & Chiba (1978)@.") MAN_END MAN_BEGIN (U"DTW: Get maximum consecutive steps...", U"djmw", 20050307) INTRO (U"Get the maximum number of consecutive steps in the chosen direction along the optimal path from the selected @DTW.") MAN_END MAN_BEGIN (U"DTW: Get distance (weighted)", U"djmw", 20100628) INTRO (U"Queries the selected @DTW object for the weighted distance along the minimum path.") ENTRY (U"Algorithm") NORMAL (U"If the distance matrix has %%nx% cells along the %%x%-direction, %%ny% cells along the %%y%-direction and the " "sum of the distances along the minimum path is %%S%, the weighted distance is given by %%S%/(%nx+%ny). ") MAN_END MAN_BEGIN (U"DTW: Get time along path...", U"djmw", 20110603) INTRO (U"Queries the selected @DTW object for the time along the minimal path " "given the time along the \"%x-direction\". This command is deprecated, the new commands for querying are " "@@DTW: Get y time from x time...@ and @@DTW: Get x time from y time...@.") ENTRY (U"Setting") TAG (U"##Time (s)") DEFINITION (U"the time along the %x-direction.") ENTRY (U"Behaviour") NORMAL (U"When the %input time is in the interval [%xmin, %xmax], the %returned " "time will be in the interval [%ymin, %ymax], where [%xmin, %xmax] and " "[%ymin, %ymax] are the domains of the two \"objects\" from which the " "DTW-object was constructed." "For all other input times we assume that the two object are aligned.") NORMAL (U"We like to have a \"continuous\" interpretation of time for the quantized times in the %x and " "%y direction; we make the path piecewise linear. There are two special cases:") NORMAL (U"1. The local path is horizontal. We calculate the %y-time from the line that connects the " "lower-left position of the leftmost horizontal time block to the upper-right position of the " "rightmost horizontal time block.") NORMAL (U"2. The local path is vertical. We calculate the %y-time from the line that connects the " "lower-left position of the bottommost vertical time block to the upper-right position of the " "topmost horizontal time block.") MAN_END MAN_BEGIN (U"DTW: Get y time from x time...", U"djmw", 20110603) INTRO (U"Queries the selected @DTW object for the time along the %y-direction " "given the time along the \"%x-direction\". ") ENTRY (U"Setting") TAG (U"##Time (s)") DEFINITION (U"the time along the %x-direction.") ENTRY (U"Behaviour") NORMAL (U"When the %input time is in the interval [%xmin, %xmax], the %returned " "time will be in the interval [%ymin, %ymax], where [%xmin, %xmax] and " "[%ymin, %ymax] are the domains of the two \"objects\" from which the " "DTW-object was constructed." "For input times outside the domain we assume that the two object were aligned.") NORMAL (U"We like to have a \"continuous\" interpretation of time for the quantized times in the %x and " "%y direction; we make the path a piecewise linear monotonically increasing function. " "There are special cases:") NORMAL (U"1. The local path is in the %x-direction only. We calculate the %y-time from the line " "that connects the lower-left position of the begin cell of this path to the " "upper-right position of the last cell.") NORMAL (U"2. The local path is in the x-direction only. We calculate the %y-time from the line " "that connects the lower-left position of lowest cell to the upper-right position of the " "highest cell.") NORMAL (U"3. A cell is both part of a path in the %x- and the %y-direction. " "We then calculate the intersection point of the paths in the %x- and the %y-directions. " "The %y-times in this cell are now calculated from the two line segments that originate " "from this intersection point.") MAN_END MAN_BEGIN (U"DTW: Get x time from y time...", U"djmw", 20110603) INTRO (U"Queries the selected @DTW object for the time along the %x-direction " "given the time along the \"%y-direction\". ") ENTRY (U"Setting") TAG (U"##Time (s)") DEFINITION (U"the time along the %y-direction.") ENTRY (U"Behaviour") NORMAL (U"The behaviour is like @@DTW: Get y time from x time...@") MAN_END MAN_BEGIN (U"DTW: Swap axes", U"djmw", 20050306) INTRO (U"Swap the x and y-axes of the selected @DTW.") MAN_END MAN_BEGIN (U"DTW: To Polygon...", U"djmw", 20120223) INTRO (U"A command to convert for a selected @DTW the Sakoe-Chiba band and the local slope constraint " "to a @Polygon object. The polygon will show the boundaries of the search domain for the optimal path.") MAN_END MAN_BEGIN (U"DTW & TextGrid: To TextGrid (warp times)", U"djmw", 20110603) INTRO (U"Create a new TextGrid from the selected @DTW and @TextGrid by warping the " "times from the selected TextGrid to the newly created TextGrid.") ENTRY (U"Algorithm") NORMAL (U"First we check whether the y-domain of the DTW and the domain of the TextGrid are " "equal. If they are, a new TextGrid is created by copying the selected one. " "We then change its domain and make it equal to the x-domain of the DTW. " "Then for each tier we change the domain and @@DTW: Get x time from y time...|calculate new times@ by using the path.") MAN_END MAN_BEGIN (U"DTW & Sounds: Draw...", U"djmw", 20071204) INTRO (U"Draws the distances, the path and the sounds for the selected @DTW and the two selected @@Sound|Sounds@.") MAN_END MAN_BEGIN (U"DTW & Sounds: Draw warp (x)...", U"djmw", 20071204) INTRO (U"Draws the warp given a time on the \"x-direction\" for the selected @DTW and the two selected @@Sound|Sounds@.") MAN_END MAN_BEGIN (U"Create empty EditCostsTable...", U"djmw", 20120524) INTRO (U"Creates an empty @@EditCostsTable@.") ENTRY (U"Settings") TAG (U"##Name#") DEFINITION (U"the name of the resulting EditCostsTable object.") TAG (U"##Number of target symbols#") DEFINITION (U"the number of different symbols in the target symbol set that you want to give special edit cost values in the EditCostTable. " "The number you specify may be smaller than the actual target symbol set size because the EditCostTable has an entry for target symbols " "that fall in a %%rest% category. If you don't want to treat any target symbol is a special way you may set this value to 0.") TAG (U"##Number of source symbols#") DEFINITION (U"the number of different symbols in the source symbol set that you want to give special edit cost values in the EditCostTable. " "The number you specify may be smaller than the actual source symbol set size because the EditCostTable has an entry for source symbols " "that fall in a %rest% category. If you don't want to treat any source symbol is a special way you may set this value 0.") MAN_END MAN_BEGIN (U"EditCostsTable", U"djmw", 20140509) INTRO (U"One of the @@types of objects@ in Praat.") NORMAL (U"The EditCostsTable determines the %%string edit costs%, i.e. the costs involved in changing one string of " "symbols (the %%source%) into another one (the %%target%). " "String edit costs are generally divided into %%insertion%, %%deletion% and %%substitution% costs. " "The latter terms refer to the operations that may be performed on a source string to transform it to a target " "string. For example, to change the source string \"execution\" to the target string \"intention\" we would need " "one insertion (i), one deletion (d) and three substitutions (s) as the following figure shows.") SCRIPT (4, 1.0, U"target = Create Strings as characters: \"intention\"\n" "source = Create Strings as characters: \"execution\"\n" "selectObject: source, target\n" "edt = To EditDistanceTable\n" "Draw edit operations\n" "removeObject: edt, target, source\n") NORMAL (U"The figure above was produced with default values for the costs, i.e. the insertion and deletion costs were 1.0 while the " "substitution cost was 2.0. The actual edit distance between the target and source strings is calculated by the @@EditDistanceTable@ " "which uses an EditCostsTable to access the specific string edit costs. The figure above was produced by the following commands:") CODE (U"target = Create Strings as characters: \"intention\"") CODE (U"source = Create Strings as characters: \"execution\"") CODE (U"plusObject: target") CODE (U"edt = To EditDistanceTable") CODE (U"Draw edit operations") NORMAL (U"The default EditCostsTable which is in every new EditDistanceTable object has only two rows and two columns, " "where the cells in this EditCostsTable have the following interpretation:\n") TAG (U"Cell [1][2]:") DEFINITION (U"defines the cost for the insertion of a target symbol in the source string. The default insertion cost is 1.0.") TAG (U"Cell [2][1]:") DEFINITION (U"defines the cost of the deletion of a source symbol. The default value is 1.0.") TAG (U"Cell [1][1]:") DEFINITION (U"defines the cost of substituting a target symbol for a source symbol where the target and source symbols don't match. The default substitution cost is 2.0.") TAG (U"Cell [2][2]:") DEFINITION (U"defines the cost of substituting a target symbol for a source symbol where the target and source symbols do match. The deault value is 0.0.") ENTRY (U"How to create a non-default EditCostsTable") NORMAL (U"In general we can define a table for %%numberOfTargets% target symbols and %%numberOfSources% source symbols. These numbers " "do not necessarily have to be equal to the number of different symbols that may occur in the target and source strings. They only represent the number of symbols that you like to give special edit costs. " "The EditCostTable will provide one extra dimension to accommodate target symbol insertion costs and source symbol deletion costs and another extra dimension to represent other target and source symbols that don't have separate entries and can therefore be treated as one group. " "The actual dimension of the table will therefore be (%%numberOfTargets% + 2) \\xx (%%numberOfSources% + 2). This is what the cells in the non-default table mean: ") LIST_ITEM (U"\\bu The upper matrix part of dimension %%numberOfTargets% \\xx %%numberOfSources% will show at cell [%i][%j] the costs " "of substituting the %i-th target symbol for the %j-th source symbol.") LIST_ITEM (U"\\bu The first %%numberOfSources% values in row (%%numberOfTargets% + 1) represent the costs of substituting one of the target " "symbols from the target %%rest% category for the source symbol in the corresponding column. The target rest category is the group of " "targets that do not belong to the %%numberOfTargets% targets represented in the upper part of the matrix.") LIST_ITEM (U"\\bu The first %%numberOfTargets% values in the column (%%numberOfSources% + 1) represent the costs of substituting the target " "symbol in the corresponding row for one of the source symbols from the source %%rest% category. The source rest category is the group " "of source symbols that do not belong to the %%numberOfSources% source symbols represented in the upper part of the matrix.") LIST_ITEM (U"\\bu The first %%numberOfSources% cells in the last row represent the deletion cost of the corresponding source symbols.") LIST_ITEM (U"\\bu The first %%numberOfTargets% cells in the last column represent the insertion costs of the corresponding target symbols.") LIST_ITEM (U"\\bu Finally the four numbers in the cells at the bottom-right corner have an interpretation analogous to the four numbers in " "the basic EditCostTable we discussed above (but now for the %%rest% symbols).") ENTRY (U"Example") NORMAL (U"If we extend the basic table with one extra target and one extra source symbol, then the EditCostTable will " "be a 3 by 3 table. The numbers in the following table have been chosen to be distinctive and therefore probably " "will not correspond to any practical situation.") CODE (U" s ") CODE (U"t 1.1 1.2 1.3") CODE (U" 1.4 1.5 1.6") CODE (U" 1.7 1.8 0.0") NORMAL (U"By issuing the following series of commands this particular table can be created:") CODE (U"Create empty EditCostsTable: \"editCosts\", 1, 1") CODE (U"Set target symbol (index): 1, \"t\"") CODE (U"Set source symbol (index): 1, \"s\"") CODE (U"Set insertion costs: \"t\", 1.3") CODE (U"Set deletion costs: \"s\", 1.7") CODE (U"Set substitution costs: \"t\", \"s\", 1.1") CODE (U"Set substitution costs: \"\", \"s\", 1.4") CODE (U"Set substitution costs: \"t\", \"\", 1.2") CODE (U"Set costs (others): 1.6, 1.8, 0, 1.5") NORMAL (U"In the first line we create the (empty) table, we name it %%editCosts% and it creates space for one target " "and one source symbol. The next line defines the target symbol which becomes the label of the first row of the table. " "Line 3 defines the source symbol which will become the label of the first column of the table. " "We next define the insertion and deletion costs, they fill cells [1][3] and [3][1], respectively. " "Cell [1][1] is filled by the command in line 6. The command in line 7 fills cell [2][1] which defines the cost " "of substituting any target symbol unequal to \"t\" for \"s\". The next line fills cell [1][2] which defines " "the substitution costs of \"t\" for any source symbol unequal to \"s\". " "Finally, the command in the last line defines the little 2\\xx2 matrix at the bottom-right that " "is analogous to the default cost matrix explained above. Therefore cell [2][2] defines the cost of substituting a " "target symbol unequal to \"t\" for a source symbol unequal to \"s\" where the target and source symbols don't match, while cell [3][3] " "defines the costs when they do match. " "Cell [3][2] defines the cost of the deletion of a source symbol unequal \"s\", while cell [2][3] defines the cost " "for the insertion of a target symbol unequal \"t\" in the source string. ") ENTRY (U"How to use a special EditCostsTable") NORMAL (U"After creating the special EditCostsTable you select it together with the EditDistanceTable and issue the command @@EditDistanceTable & EditCostsTable: Set new edit costs|Set new edit costs@. The EditDistanceTable will then find the minimum edit distance based on the new cost values.") MAN_END MAN_BEGIN (U"EditDistanceTable", U"djmw", 20140509) INTRO (U"One of the @@types of objects@ in Praat.") NORMAL (U"An EditDistanceTable shows the accumulated distances between a target string and a source string. " "For example, the accumulated distances between the target string \"intention\" and the source string " "\"execution\" can be expressed by the following EditDistanceTable:") SCRIPT (5, 3.5, U"target = Create Strings as characters: \"intention\"\n" "source = Create Strings as characters: \"execution\"\n" "selectObject: source, target\n" "edt = To EditDistanceTable\n" "Draw: \"decimal\", 1, 0\n" "removeObject: edt, target, source\n") NORMAL (U"This figure was created by issuing the following commands:") CODE (U"target = Create Strings as characters: \"intention\"") CODE (U"source = Create Strings as characters: \"execution\"") CODE (U"plusObject: target") CODE (U"edt = To EditDistanceTable") CODE (U"Draw: \"decimal\", 1, 0") NORMAL (U"The target string is always displayed vertically while the source string is displayed horizontally and the origin is at the bottom-left corner of the table. " "Each cell of this table, dist[%i, %j], contains the accumulated distance between the first %i characters of the target and the first %j characters of the source. The cells on the path through this table which have the " "minimum accumulated cost are shown with boxes around them. Below we will explain how this path is calculated.") NORMAL (U"The local directional steps in this path show which %%edit operations% we have to perform on the source string symbols to obtain the target string symbols. " "Three edit operations exist: (1) %%insertion% of a target symbol in the source string. This happens each time we take a step in the vertical direction along the path. (2) %%deletion% of a symbol in the source string. This happens each time we take a step in horizontal direction along the path. (3) %%substitution% of a source symbol by a target symbol happens at each diagonal step along the path.") NORMAL (U"If we trace the path from its start at the origin to its end, we see that it first moves up, indicating the insertion of an \"i\" symbol in the source string. " "In the next step which is in the diagonal direction, the \"n\" target is substituted for the \"e\" source symbol. Next follows another substitution, \"t\" for \"x\". " "The next diagonal step substitutes \"e\" for an identical \"e\". This step is followed by a horizontal step in which the source symbol \"c\" is deleted. " "The next diagonal step substitutes an \"n\" for a \"u\". The path now continues in the diagonal direction until the end point and only identical substitutions occur in the last part. The following figure shows these operations more explicitly.") SCRIPT (4, 1.5, U"target = Create Strings as characters: \"intention\"\n" "source = Create Strings as characters: \"execution\"\n" "plusObject: target\n" "edt = To EditDistanceTable\n" "Draw edit operations\n" "removeObject: edt, target, source\n") NORMAL (U"The value of the accumulated costs in a cell of the table is computed by taking the minimum of the accumulated distances from three possible paths that end in the current cell, i.e. the paths that come from the %%left%, from the %%diagonal% and from %%below%.") CODE (U"dist[i,j] = min (d__left_, d__diag_, d__below_), ") NORMAL (U"where ") CODE (U" d__left _ = dist[i-1,j] + insertionCost(target[i])") CODE (U" d__diag _ = dist[i-1,j-1] + substitutionCost(source[j],target[i])") CODE (U" d__below_ = dist[i,j-1] + deletionCost(source[j])") NORMAL (U"Since the calculation is recursive we start at the origin. After calculating the accumulative distances for each cell in the table as based on the algorithm above, the cell at the top-right position will contain the accumulated edit distance. " "This distance happens to be 8 for the given example. The value 8 results from using the target-indepent value of 1.0 for the insertion cost, the source-independent value of 1.0 for the deletion costs and a constant value of 2.0 for the substitution costs. " "If target and source symbol happen to be equal no costs are assigned, or, equivalently the substitution costs are zero if target and source symbol match. If you want more control over these costs you can create an @@EditCostsTable@ and specify your special costs and then @@EditDistanceTable & EditCostsTable: Set new edit costs|set the new edit costs@.") NORMAL (U"If during the calculations we also keep track of which of the three cells resulted in the local minimum accumulated distance, we can use this directional " "information to backtrack from the cell at the top-right position to the cell at the bottom-right position and obtain the minimum path.") MAN_END MAN_BEGIN (U"EditDistanceTable & EditCostsTable: Set new edit costs", U"djmw", 20120522) INTRO (U"A command available in the dynamic menu if an @@EditDistanceTable@ and an @@EditCostsTable@ are chosen together.") NORMAL (U"New accumulated cost values will be calculated and a new path based on these values will be calculated.") MAN_END MAN_BEGIN (U"Eigen", U"djmw", 19981102) INTRO (U"One of the @@types of objects@ in Praat.") NORMAL (U"An object of type Eigen represents the eigen structure of " "a matrix whose eigenvalues and eigenvectors are real.") ENTRY (U"Inside an Eigen") NORMAL (U"With @Inspect you will see the following attributes:") TAG (U"%numberOfEigenvalues") DEFINITION (U"the number of eigenvalues and eigenvectors") TAG (U"%dimension") DEFINITION (U"the dimension of an eigenvector.") TAG (U"%eigenvalues[1..%numberOfEigenvalues]") DEFINITION (U"the real eigenvalues.") TAG (U"%eigenvectors[1..%numberOfEigenvalues][1..%dimension]") DEFINITION (U"the real eigenvectors, stored by row.") MAN_END MAN_BEGIN (U"Eigen: Draw eigenvalues...", U"djmw", 20040407) INTRO (U"A command to draw the eigenvalues of the selected @Eigen object(s).") ENTRY (U"Settings") TAG (U"##Fraction of eigenvalues summed") DEFINITION (U"defines whether or not fractions are plotted. Fractions %f__%i_ " "will be calculated for each number %e__%i_ by dividing this number by the sum of all " "numbers %e__%j_: %f__%i_ = %e__%i_ / \\su__%j=1..%numberOfEigenvalues_ %e__%j_.") TAG (U"##Cumulative") DEFINITION (U"defines whether or not cumulative values are plotted. Cumulative " "values %c__%i_ will be calculated for each number %e__%i_ by summing the first %i " "numbers %e__%j_: %c__%i_ = \\su__%j=1..%i_ %e__%j_).") NORMAL (U"A @@Scree plot|scree@ plot can be obtained if both %%Fraction of eigenvalues summed% " "and %%Cumulative% are unchecked.") MAN_END MAN_BEGIN (U"Eigen: Draw eigenvector...", U"djmw", 20040407) INTRO (U"A command to draw an eigenvector from the selected @Eigen.") ENTRY (U"Settings") TAG (U"##Eigenvector number") DEFINITION (U"determines the eigenvector to be drawn.") TAG (U"%Component %loadings") DEFINITION (U"when on, the eigenvector is multiplied with the square root of the corresponding " "eigenvalue. (For @@PCA@-analysis this means that you will draw the so called " "%%component loading vector%. You will be able to compare " "quantitatively the elements in different component loading vectors because " "the %i-th element in the %j-th component loading vector gives the covariance between the %i-th " "original variable and the %j-th principal component.)") TAG (U"##Element rang%") DEFINITION (U"determine the first and last element of the vector that must be drawn.") TAG (U"##Minimum# and ##Maximum#") DEFINITION (U"determine the lower and upper bounds of the plot (choosing #Maximum smaller than #Minimum " "will draw the %%inverted% eigenvector). ") TAG (U"##Mark size#, ##Mark string#") DEFINITION (U"determine size and type of the marks that will be drawn.") TAG (U"##Garnish") DEFINITION (U"determines whether a bounding box and margins will be drawn.") MAN_END MAN_BEGIN (U"Eigen: Get contribution of component...", U"djmw", 19981109) INTRO (U"A command to ask the selected @Eigen for the contribution of the %j^^th^ " "eigenvalue to the total sum of eigenvalues.") ENTRY (U"Details") NORMAL (U"The contribution is defined as:") FORMULA (U"%%eigenvalue[j]% / \\Si__%i=1..%numberOfEigenvalues_ %%eigenvalue[i]%") MAN_END MAN_BEGIN (U"Eigen: Get cumulative contribution of components...", U"djmw", 19981109) INTRO (U"A command to ask the selected @Eigen for the contribution of the sum of the " "eigenvalues[%from..%to] to the total sum of eigenvalues.") ENTRY (U"Details") NORMAL (U"The contribution is defined as:") FORMULA (U"\\Si__%i=%from..%to_ %%eigenvalue[i]% / \\Si__%i=1..%numberOfEigenvalues_ %%eigenvalue[i]%") MAN_END MAN_BEGIN (U"Eigen: Get eigenvalue...", U"djmw", 20040225) INTRO (U"A command to query the selected @Eigen for the %i^^th^ " "eigenvalue.") MAN_END MAN_BEGIN (U"Eigen: Get eigenvector element...", U"djmw", 20040225) INTRO (U"A command to query the selected @Eigen for the %j^^th^ element of the " "%i^^th^ eigenvector.") MAN_END MAN_BEGIN (U"Eigen & Matrix: Project...", U"djmw", 20040407) INTRO (U"A command to project the columns of the @Matrix object onto the " "eigenspace of the @Eigen object.") ENTRY (U"Setting") TAG (U"##Number of dimensions") DEFINITION (U"defines the dimension, i.e., the number of rows, of the " "resulting object.") ENTRY (U"Algorithm") NORMAL (U"Project each column of the Matrix on the coordinate " "system given by the eigenvectors of the Eigen object. This can be done " "as follows:") FORMULA (U"%y__%ji_ = \\Si__%k=1..%numberOfColums_ %e__jk_ %x__%ki_, where") NORMAL (U"%y__%ji_ is the %j-th element of the %i-th column of the resulting " "(matrix) object, %e__%jk_ is the %k-th element of the %j-th eigenvector " "and, %x__%ki_ is the %k-th element of the %i-th column of the selected " "matrix object.") MAN_END MAN_BEGIN (U"Eigen & SSCP: Project", U"djmw", 20020328) INTRO (U"A command to project the @SSCP object onto the eigenspace of " "the @Eigen object.") ENTRY (U"Behaviour") NORMAL (U"Transform the SSCP object as if it was calculated in a coordinate " "system given by the eigenvectors of the Eigen object. This can be done " "as follows:") FORMULA (U"#%S__%t_ = #%E\\'p #%S #%E, where") NORMAL (U"where #%E\\'p is the transpose of the matrix with eigenvectors #%E, " "#%S is the square matrix with sums of squares and crossproducts, and " "#%S__%t_ the newly created square matrix. The dimension of #%S__%t_ may " "be smaller than the dimension of #%S.") MAN_END MAN_BEGIN (U"Eigen & TableOfReal: Project...", U"djmw", 20040407) INTRO (U"A command to project the rows of the @TableOfReal object onto the " "eigenspace of the @Eigen object.") ENTRY (U"Setting") TAG (U"##Number of dimensions") DEFINITION (U"defines the number of dimensions, i.e., the number of columns, of the " "resulting object.") ENTRY (U"Algorithm") NORMAL (U"Project each row of the TableOfReal on the coordinate " "system given by the eigenvectors of the Eigen object. This can be done " "as follows:") FORMULA (U"%y__%ij_ = \\Si__%k=1..%numberOfColums_ %e__jk_ %x__%ik_, where") NORMAL (U"%e__%jk_ is the %k-th element of the %j-th eigenvector, %x__%ik_ is " "the %k-th element of the %i-th row and %y__%ij_ is the %j-th element at " "the %i-th row of the matrix part of the resulting object.") MAN_END MAN_BEGIN (U"equivalent rectangular bandwidth", U"djmw", 19980713) INTRO (U"The %%equivalent rectangular bandwidth% (ERB) of a filter is defined " "as the width of a rectangular filter whose height equals the peak gain of " "the filter and which passes the same total power as the filter (given a flat " "spectrum input such as white noise or an impulse).") MAN_END MAN_BEGIN (U"Excitations", U"djmw", 19960918) INTRO (U"A collection of objects of type @Excitation. " "You can create an #Excitations by selecting one or more #Excitation's and " "selecting ##To Excitations#. You can add one or more #Excitation's to an " "#Excitations by selecting one #Excitations and one or more " "#Excitation's and selecting ##Add to Excitations# (the #Excitation's will " "be removed from the list of objects).") MAN_END MAN_BEGIN (U"Excitations: Append", U"djmw", 19960918) INTRO (U"You can choose this command after selecting two objects of type @Excitations. ") NORMAL (U"A new object is created that contains the second object appended after the first.") MAN_END MAN_BEGIN (U"Excitations: To Pattern...", U"djmw", 19960918) INTRO (U"A command to convert every selected @Excitations to a @Pattern object.") ENTRY (U"Setting") TAG (U"##Join") DEFINITION (U"the number of subsequent @Excitation objects to combine into one row of @Pattern. " "E.g. if an #Excitation has length 26 and %join = 2 then each row of #Pattern " "contains 52 elements. The number of rows in #Pattern will be %%my size% / 2. " "In the conversion process the elements of an #Excitation will be divided by 100.0 in order " "to guarantee that all patterns have values between 0 and 1.") MAN_END MAN_BEGIN (U"FilterBank: Draw filter functions...", U"djmw", 20030901) INTRO (U"") MAN_END MAN_BEGIN (U"FilterBank: Draw frequency scales...", U"djmw", 20030901) MAN_END MAN_BEGIN (U"FilterBank: Get frequency in Hertz...", U"djmw", 20030901) INTRO (U"A @query to the selected FilterBank object.") ENTRY (U"Return value") NORMAL (U"a frequency value in Hertz.") MAN_END MAN_BEGIN (U"FilterBank: Get frequency in Bark...", U"djmw", 20030901) MAN_END MAN_BEGIN (U"FilterBank: Get frequency in mel...", U"djmw", 20030901) MAN_END MAN_BEGIN (U"FormantFilter", U"djmw", 20141022) INTRO (U"A #deprecated @@types of objects|type of object@ in P\\s{RAAT}. It is replaced by @@Spectrogram@.") NORMAL (U"An object of type FormantFilter represents an acoustic time-frequency " "representation of a sound: the power spectral density %P(%f, %t), expressed " "in dB as 10*log10(power/4e-10)). In the now preferred Spectrogram the power is represented instead of its dB value. " "It is sampled into a number of points around equally spaced times %t__%i_ " "and frequencies %f__%j_ (on a linear frequency scale).") ENTRY (U"Inside a FormantFilter") NORMAL (U"With @Inspect you will see that this type contains the same " "attributes a @Matrix.") MAN_END MAN_BEGIN (U"gammatone", U"djmw", 20100517) INTRO (U"A gammatone is the product of a rising polynomial, a decaying exponential function, and a " "cosine wave.") NORMAL (U"It can be described with the following formula:") FORMULA (U"gammaTone (%t) = %a %t^^%\\ga\\--1^ e^^\\--2%\\pi\\.c%bandwidth\\.c%t^ " "cos (2%%\\pi\\.cfrequency\\.ct% + %initialPhase),") NORMAL (U"where %\\ga determines the order of the gammatone.") NORMAL (U"The gammatone function has a monotone carrier (the tone) with an " "envelope that is a gamma distribution function. The amplitude spectrum is essentially " "symmetric on a linear frequency scale. This function is used in some time-domain " "auditory models to simulate the spectral analysis performed by the basilar membrane. " "It was popularized in auditory modeling by @@Johannesma (1972)@. @@Flanagan (1960)@ " "already used it to model basilar membrane motion.") MAN_END MAN_BEGIN (U"generalized singular value decomposition", U"djmw", 19981007) INTRO (U"For %m > %n, the %%generalized singular value decomposition% (gsvd) of an %m \\xx %n matrix #%A and " "a %p \\xx %n matrix #%B is given by the pair of factorizations") FORMULA (U"#%A = #%U #%\\Si__1_ [#%0, #%R] #%Q\\'p and #%B = #%V #%\\Si__2_ [#%0, #%R] #%Q\\'p") NORMAL (U"The matrices in these factorizations have the following properties:") TAG (U"\\bu #%U [%m \\xx %m], #%V [%p \\xx %p] and #%Q [%n \\xx %n]") DEFINITION (U" are orthogonal matrices. In the reconstruction formula's above we maximally need " "only the first %n columns of matrices #%U and #%V (when %m and/or %p are greater than %n).") TAG (U"\\bu #%R [%r \\xx %r],") DEFINITION (U"is an upper triangular nonsingular matrix. %r is the rank of [#%A\\'p, #%B\\'p]\\'p " "and %r \\<_ %n. The matrix [#%0, #%R] is %r \\xx %n and its first %n \\xx (%n \\-- %r) part " "is a zero matrix.") TAG (U"\\bu #%\\Si__1_ [%m \\xx %r] and #%\\Si__2_ [%p \\xx %r]") DEFINITION (U"are real, nonnegative and \"diagonal\".") NORMAL (U"In practice, the matrices #%\\Si__1_ and #%\\Si__2_ are never used. Instead a shorter " "representation with numbers %\\al__%i_ and %\\be__%i_ is used. These numbers obey " "0 \\<_ \\al__%i_ \\<_ 1 and \\al__%i_^^2^ + \\be__%i_^^2^ = 1. The following relations exist:") FORMULA (U"#%\\Si__1_\\'p #%\\Si__1_ + #%\\Si__2_\\'p #%\\Si__2_ = #%I, ") FORMULA (U"#%\\Si__1_\\'p #%\\Si__1_ = #diag (%\\al__1_^^2^, ..., %\\al__%r_^^2^), and, ") FORMULA (U"#%\\Si__2_\\'p #%\\Si__2_ = #diag (%\\be__1_^^2^, ..., %\\be__%r_^^2^).") NORMAL (U"The ratios \\al__%i_ / \\be__%i_ are called the %%generalized singular values% of the " "pair #%A, #%B. Let %l be the rank of #%B and %k + %l (= %r) the rank of [#%A\\'p, #%B\\'p]\\'p. " "Then the first %k generalized singular values are infinite and the remaining %l are finite. " "(When %#B is of full rank then, of course, %k = 0).") ENTRY (U"Special cases") NORMAL (U"\\bu If #%B is a square nonsingular matrix, the gsvd of #%A and #%B is equivalent to the " "singular value decomposition of #%A #%B^^\\--1^.") NORMAL (U"\\bu The generalized eigenvalues and eigenvectors of #%A\\'p #%A - %\\la #%B\\'p #%B " "can be expressed in terms of the gsvd. The columns of the matrix #%X, constructed as") CODE (U"X = Q*( I 0 )") CODE (U" ( 0 inv(R) ),") NORMAL (U"form the eigenvectors. The important eigenvectors, of course, correspond " "to the positions where the %l eigenvalues are not infinite.") MAN_END MAN_BEGIN (U"invFisherQ", U"djmw", 20000525) INTRO (U"$$invFisherQ$ (%q, %df1, %df2) returns the value %f for which " "$$@fisherQ (%f, %df1, %df2) = %q.") MAN_END MAN_BEGIN (U"fisherQ", U"djmw", 20000525) INTRO (U"$$fisherQ$ (%f, %df1, %df2) returns the area under Fisher's F-distribution " "from %f to +\\oo.") MAN_END MAN_BEGIN (U"ISpline", U"djmw", 19990627) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}. ") NORMAL (U"An object of type ISpline represents a linear combination of basis " "i@spline functions. Each basis %ispline is a monotonically increasing " "polynomial function of degree %p.") FORMULA (U"ISpline (%x) = \\Si__%k=1..%numberOfCoefficients_ %c__%k_ %ispline__%k_(%x)") MAN_END MAN_BEGIN (U"jackknife", U"djmw", 20141101) INTRO (U"A technique for estimating the bias and standard deviation of an estimate.") NORMAL (U"Suppose we have a sample #%x = (%x__1_, %x__2_,...%x__n_) and wish to estimate " "the bias and standard error of an estimator \\Te. The jackknife " "focuses on the samples that leave out one observation at a time: " "the %i-th jackknife sample consists of the data with the %i-th observation " "removed.") MAN_END MAN_BEGIN (U"Kirshenbaum phonetic encoding", U"djmw", 20120413) INTRO (U"The Kirshenbaum phonetic encoding represents International Phonetic Alphabet symbols using ascii characters. See: http://www.kirshenbaum.net/IPA/ascii-ipa.pdf. The @@espeak@ speech synthesizer on which our synthesizer is based accepts this encoding as text input. ") MAN_END MAN_BEGIN (U"Legendre polynomials", U"djmw", 19990620) INTRO (U"The Legendre polynomials %P__%n_(%x) of degree %n are special " "orthogonal polynomial functions defined on the domain [-1, 1].") NORMAL (U"Orthogonality:") FORMULA (U"__-1_\\in^^1^ %W(%x) %P__%i_(%x) %P__%j_(%x) %dx = \\de__%ij_") FORMULA (U"%W(%x) = 1 (-1 < x < 1)") NORMAL (U"They obey certain recurrence relations:") FORMULA (U"%n %P__%n_(%x) = (2%n \\-- 1) %x %P__%n-1_(%x) \\-- (%n \\-- 1) %P__%n-2_(%x)") FORMULA (U"%P__0_(%x) = 1") FORMULA (U"%P__1_(%x) = %x") NORMAL (U"We may %change the domain of these polynomials to [%xmin, %xmax] by " "using the following transformation:") FORMULA (U"%x\\'p = (2%x \\-- (%xmax + %xmin)) / (%xmax - %xmin).") NORMAL (U"We subsequently use %P__%k_(%x\\'p) instead of %P__%k_(%x).") MAN_END MAN_BEGIN (U"LegendreSeries", U"djmw", 19990620) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"An object of type LegendreSeries represents a linear combination of @@Legendre polynomials@ " "%P__%k_(%x).") FORMULA (U"LegendreSeries (%x) = \\Si__%k=1..%numberOfCoefficients_ %c__%k_ %P__%k_(%x)") MAN_END MAN_BEGIN (U"LegendreSeries: To Polynomial", U"djmw", 19990620) INTRO (U"A command to transform the selected @LegendreSeries object into a @@Polynomial@ object.") NORMAL (U"We find polynomial coefficients %c__%k_ such that") FORMULA (U"\\Si__%k=1..%numberOfCoefficients_ %c__%k_ %x^^%k^ = " "\\Si__%k=1..%numberOfCoefficients_ %l__%k_ %P__%k_(%x)") NORMAL (U"We use the recurrence relation for @@Legendre polynomials@ to calculate these coefficients.") MAN_END MAN_BEGIN (U"Matrix: Draw distribution...", U"djmw", 20041110) INTRO (U"A command to draw the distribution histogram of the values in the selected part of a @Matrix.") ENTRY (U"Settings") TAG (U"##Horizontal range#, ##Vertical range#") DEFINITION (U"determine the part of the matrix whose distribution will be drawn.") TAG (U"##Minimum value#, ##Maximum value#") DEFINITION (U"determine the range of values that will be considered in the distribution. " "To treat all bin widths equally, the range will include the %%Minimum value% and exclude the " "%%Maximum value% (see below).") TAG (U"##Number of bins") DEFINITION (U"determines the number of bars in the distribution histogram.") TAG (U"##Minimum frequency#, ##Maximum frequency#") DEFINITION (U"determine the limits of the vertical axis.") ENTRY (U"Algorithm") NORMAL (U"For a particular matrix element %z, the histogram bin number %%i% that will be incremented obeys the following relation:") FORMULA (U"%%lowerBinBorder%__%i_ \\<_ %z < %%lowerBinBorder%__%i_+ %%binWidth%,") NORMAL (U"where") FORMULA (U"%%binWidth% = (%%maximumValue% - %%minimumValue%)/%%numberOfBins%,") NORMAL (U"and") FORMULA (U"%%lowerBinBorder%__%i_ = %%minimumValue% + (%i - 1)\\.c%%binWidth%.") NORMAL (U"In this way all bins will be based on exactly the same width, as each binning interval includes its lower border " "and excludes its upper border " "(i.e., each interval is closed to the left and open to the right). ") MAN_END MAN_BEGIN (U"Matrix: Solve equation...", U"djmw", 19961006) INTRO (U"Solve the general matrix equation #A #x = #b for #x.") NORMAL (U"The matrix #A can be any general %m \\xx %n matrix, #b is a %m-dimensional " "and #x a %n-dimensional vector. The @Matrix contains #A as its first %n columns " "and #b as its last column. The %n-dimensional solution is returned as a #Matrix " "with %n columns.") NORMAL (U"When the number of equations (%m) is %greater than the number of unknowns (%n) the " "algorithm gives the best least-squares solution. If on the contrary you " "have %fewer equations than unknowns the solution will not be unique.") ENTRY (U"Method") NORMAL (U"Singular value decomposition with backsubstitution. " "Zero will be substituted for eigenvalues smaller than %tolerance \\.c " "%%maximum_eigenvalue% (when the user-supplied %tolerance equals 0.0 a " "value of 2.2 \\.c 10^^-16^ \\.c %%number_of_unknowns% " "will be used as %tolerance).") NORMAL (U"See for more details: @@Golub & van Loan (1996)@ chapters 2 and 3.") MAN_END MAN_BEGIN (U"MelFilter", U"djmw", 20141022) INTRO (U"A #deprecated @@types of objects|type of object@ in P\\s{RAAT}. It is replaced by the @@MelSpectrogram@.") NORMAL (U"An object of type MelFilter represents an acoustic time-frequency " "representation of a sound: the power spectral density %P(%f, %t), " "expressed in dB's. " "It is sampled into a number of points around equally spaced times %t__%i_ " "and frequencies %f__%j_ (on a Mel frequency scale).") NORMAL (U"The frequency in mels is:") FORMULA (U"mels = 2595 * log10 (1 + hertz / 700),") NORMAL (U"and its inverse is:") FORMULA (U"hertz = 700 * (10.0^^mel / 2595.0^ - 1).") MAN_END MAN_BEGIN (U"MelSpectrogram", U"djmw", 20141209) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"An object of type MelSpectrogram represents an acoustic time-frequency " "representation of a sound: the power spectral density %P(%f, %t)." "It is sampled into a number of points around equally spaced times %t__%i_ " "and frequencies %f__%j_ (on a Mel frequency scale).") NORMAL (U"The mel frequency scale is defined as:") FORMULA (U"mel = 2595 * log10 (1 + hertz / 700),") NORMAL (U"and its inverse is:") FORMULA (U"hertz = 700 * (10.0^^mel / 2595.0^ - 1).") ENTRY (U"Inside a MelSpectrogram") NORMAL (U"With @Inspect you will see that this type contains the same " "attributes a @Matrix.") MAN_END MAN_BEGIN (U"MelSpectrogram: Paint image...", U"djmw", 20141023) INTRO (U"A command to draw the selected @MelSpectrogram into the @@Picture window@ in shades of grey.") MAN_END MAN_BEGIN (U"MelSpectrogram: To MFCC...", U"djmw", 20141023) INTRO (U"A command to create a @MFCC object from each selected @MelSpectrogram " "object.") NORMAL (U"Mel frequency cepstral coefficients %c__%k_ in each frame of the MFCC object result from the output of a Discrete Cosine " "Transform on spectral values %P__%j_ in the corresponding frame of the MelSpectrogram. The following formula " "shows the relation between the values in each frame:") FORMULA (U"%c__%k-1_ = \\Si__%j=1_^^%N^ %P__%j_ cos (\\pi(%k-1)(%j-0.5)/%N)),") NORMAL (U"where %N represents the number of spectral values and %P__%j_ the power in dB " "of the %j^^%th^ spectral value (%k runs from 1 to %N).") NORMAL (U"This transformation was first used by @@Davis & Mermelstein (1980)@.") MAN_END MAN_BEGIN (U"MFCC: To TableOfReal...", U"djmw", 20120504) INTRO (U"Convert the selected @@MFCC@ object to a @@TableOfReal@ object. Each MFCC frame results " "in one row in the TableOfReal. If the \"Include energy\" option is chosen, the zeroth MFCC " "coefficient will be saved in the first column.") MAN_END MAN_BEGIN (U"MSpline", U"djmw", 19990627) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}. ") NORMAL (U"An object of type MSpline represents a linear combination of basis " "m@spline functions. Each basis %mspline is a positive polynomial function " "of degree %p.") FORMULA (U"MSpline (%x) = \\Si__%k=1..%numberOfCoefficients_ %c__%k_ %mspline__%k_(%x)") MAN_END MAN_BEGIN (U"Pattern", U"djmw", 20041201) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") INTRO (U"An object of type Pattern represents a sequence of patterns that can serve as " "inputs for a neural net. All elements in a Pattern have to be in the interval [0,1].") ENTRY (U"Pattern commands") NORMAL (U"Creation:") LIST_ITEM (U"\\bu ##Create Pattern with zeroes...#") LIST_ITEM (U"\\bu @@TableOfReal: To Pattern and Categories...@") NORMAL (U"Synthesis:") LIST_ITEM (U"\\bu @@FFNet & Pattern: To Categories...@") LIST_ITEM (U"\\bu @@Pattern & Categories: To FFNet...@") ENTRY (U"Inside a Pattern") NORMAL (U"With @Inspect you will see that this type contains the same " "attributes as a @Matrix.") MAN_END MAN_BEGIN (U"PCA", U"djmw", 19990323) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}. " "See the @@Principal component analysis@ tutorial.") NORMAL (U"An object of type PCA represents the principal components analysis " "of a multivariate dataset.") ENTRY (U"Commands") NORMAL (U"Creation:") LIST_ITEM (U"\\bu @@Principal component analysis@ tutorial") LIST_ITEM (U"\\bu @@TableOfReal: To PCA@") ENTRY (U"Inside a PCA") NORMAL (U"With @Inspect you will see that this type contains the same " "attributes as an @Eigen with the following extras:") TAG (U"%numberOfObservations") DEFINITION (U"the number of observations in the multivariate dataset that originated the PCA, " "usually equal to the dataset's number of rows.") TAG (U"%labels[1..%dimension]") DEFINITION (U"the label that corresponds to each dimension.") TAG (U"%centroid") DEFINITION (U"the centroids of the originating multivariate data set.") MAN_END MAN_BEGIN (U"PCA: Get fraction variance accounted for...", U"djmw", 19990106) INTRO (U"A command to query the selected @PCA for the fraction %%variance " "accounted for% by the selected components.") ENTRY (U"Setting") TAG (U"##Principal component range") DEFINITION (U"defines the range of the principal components. If you choose both numbers equal, " "you get the fraction of the \"variance\" explained by that one component.") ENTRY (U"Details") NORMAL (U"The contribution is defined as:") FORMULA (U"\\Si__%i=%from..%to_ %%eigenvalue[i]% / \\Si__%i=1..%numberOfEigenvalues_ %%eigenvalue[i]%") MAN_END MAN_BEGIN (U"PCA: Get eigenvalue...", U"djmw", 20040225) INTRO (U"A command to query the selected @PCA for the %i^^th^ " "eigenvalue.") MAN_END MAN_BEGIN (U"PCA: Get eigenvector element...", U"djmw", 20040225) INTRO (U"A command to query the selected @PCA for the %j^^th^ element of the " "%i^^th^ eigenvector.") MAN_END MAN_BEGIN (U"PCA: Get equality of eigenvalues...", U"djmw", 19981102) INTRO (U"A command to get the probability that some of the eigenvalues of the " "selected @PCA object are equal. A low probability means that it is not " "very likely that that these numbers are equal.") NORMAL (U"We test the hypothesis %H__0_: %\\la__%from_ = ... = %\\la__%to_ " "that %r (= %to\\--%from+1) of the eigenvalues \\la of the covariance " "matrix are equal. The remaining eigenvalues are unrestricted as to their " "values and multiplicities. The alternative hypothesis to %H__0_ is that " "some of the eigenvalues in the set are distinct.") ENTRY (U"Settings") TAG (U"##Eigenvalue range") DEFINITION (U"define the range of eigenvalues to be tested for equality.") TAG (U"##Conservative test") DEFINITION (U"when on, a more conservative estimate for %n is chosen (see below).") ENTRY (U"Details") NORMAL (U"The test statistic is:") FORMULA (U"\\ci^2 = \\--%n \\Si__%j=%from..%to_ ln %eigenvalue[%j] + %n %r " "ln (\\Si__%j=%from..%to_ %eigenvalue[%j] / %r),") NORMAL (U"with %r(%r+1)/2 \\--1 degrees of freedom. Here %n = %totalNumberOfCases \\-- 1.") NORMAL (U"A special case occurs when the variation in the last %r dimensions is spherical. In a " "slightly more conservative test we may replace %n by %n\\--%from\\--(2%r^2+%r+2)/6%r.") NORMAL (U"Also see @@Morrison (1990)@, page 336.") MAN_END MAN_BEGIN (U"PCA: Get number of components (VAF)...", U"djmw", 19990111) INTRO (U"A command to ask the selected @PCA for the minimum number of " "components that are necessary " "to explain the given fraction %%variance accounted for%.") ENTRY (U"Setting") TAG (U"##Variance accounted for (fraction)") DEFINITION (U"the fraction variance accounted for that must be explained.") MAN_END MAN_BEGIN (U"PCA: To TableOfReal (reconstruct 1)...", U"djmw", 20030108) INTRO (U"A command to reconstruct a single data item. The result is stored as " "a @TableOfReal with only one row.") ENTRY (U"Settings") TAG (U"##Coefficients") DEFINITION (U"the weight for the eigenvectors.") NORMAL (U"The algorithm is explained in @@PCA & Configuration: To TableOfReal " "(reconstruct)@.") MAN_END MAN_BEGIN (U"PCA & Configuration: To TableOfReal (reconstruct)", U"djmw", 20030108) INTRO (U"A command to reconstruct a @TableOfReal from the selected @Configuration" " and @PCA.") NORMAL (U"The TableOfReal is reconstructed from the eigenvectors of the PCA and " "elements of the Configuration are the weight factors: ") FORMULA (U"%#t__%i_ = \\Si__%k_ %c__%ik_ #%e__%k_,") NORMAL (U"where %#t__%i_ is the %i-th row in the resulting TableOfReal object, %c__%ik_ is " "the element at row %i and column %k in the Configuration object and #%e__%k_ " "the %k-th eigenvector from the PCA object.") MAN_END MAN_BEGIN (U"PCA & PCA: Get angle between pc1-pc2 planes", U"djmw", 20041028) INTRO (U"A command to calculate the angle between two planes. Each plane is spanned by the first " "two eigenvectors from the corresponding @@PCA@.") ENTRY (U"Algorithm") NORMAL (U"The algorithm is described in section 12.4.3 of @@Golub & van Loan (1996)@:") NORMAL (U"First we form the projection of one set of eigenvectors on the other set. " "This results in a 2\\xx2 matrix #C:") FORMULA (U"#C = #E__1_\\'p #E__2_,") NORMAL (U"where #E__1_ and #E__2_ are 2\\xx%%dimension% and %%dimension%\\xx2 matrices " "that contain the first two eigenvectors of the PCA's, respectively.") NORMAL (U"Next, we compute the @@singular value decomposition@ of #C:") FORMULA (U"#C = #U #\\Si #V\\'p") NORMAL (U"Now the cosine of the angle between the two planes is given by \\si__2_ and " "the angle in degrees is therefore:") FORMULA (U"arccos (\\si__2_)\\.c180/\\pi") MAN_END MAN_BEGIN (U"PCA & PCA: To Procrustes...", U"djmw", 20041028) INTRO (U"A command to calculate a @Procrustes from the two selected @@PCA@'s.") NORMAL (U"Determines the orthogonal @@Procrustes transform@.") NORMAL (U"Algorithm 12.4.1 in @@Golub & van Loan (1996)@.") MAN_END MAN_BEGIN (U"PCA & TableOfReal: To Configuration...", U"djmw", 19990111) INTRO (U"A command to construct a @Configuration from the selected @TableOfReal" " and @PCA.") ENTRY (U"Setting") TAG (U"##Number of dimensions") DEFINITION (U"determines the number of dimensions of the resulting Configuration.") ENTRY (U"Algorithm") NORMAL (U"The TableOfReal is projected on the eigenspace of the PCA, i.e., " "each row of the TableOfReal is treated as a vector, and the inner product " "with the eigenvectors of the PCA determine its coordinates in the Configuration.") NORMAL (U"Because the algorithm performs a projection, the resulting Configuration will " "##only be centered#, i.e., its centroid will be at ##0#, if the data in the " "TableOfReal object are centered too. ") NORMAL (U"See also @@Eigen & TableOfReal: Project...@.") MAN_END MAN_BEGIN (U"PCA & TableOfReal: To TableOfReal (z-scores)...", U"djmw", 20120510) INTRO (U"A command to construct a @TableOfReal with z-scores from the selected @TableOfReal" " and @PCA.") ENTRY (U"Setting") TAG (U"##Number of dimensions") DEFINITION (U"determines the number of dimensions of the resulting Configuration.") ENTRY (U"Algorithm") NORMAL (U"The values %d__%ij_ in the new TableOfReal are calculated as") FORMULA (U"%d__%ij_ = ##eigenvector#__j_\\.c ##z#__%i_,") NORMAL (U"which is the inproduct of the %j-th eigenvector and the z-score vector ##z#__%i_ of the %i-th row whose elements %z__%ij_ are defined as") FORMULA (U"%z__%ij_ = (data__%ij_ - mean__%j_) / sqrt (eigenvalue__%j_),") NORMAL (U"in which data__%ij_ is the data value at row %i and column %j of the selected TableOfReal and mean__%j_ is the " "%j-th centroid value of the PCA. The square root of the %j-th eigenvalue is the standard deviation in " " the %j-th principal direction.") MAN_END MAN_BEGIN (U"PCA & TableOfReal: Get fraction variance...", U"djmw", 20040324) INTRO (U"A command to query the selected @PCA and @TableOfReal object for the explained " "fraction of the variance if the TableOfReal object were projected onto the PCA space.") ENTRY (U"Algorithm") LIST_ITEM (U"1. The TableOfReal is @@TableOfReal: To Covariance|converted@ to a " "Covariance object.") LIST_ITEM (U"2. The Covariance object is @@PCA & Covariance: Project|projected@ on " "the PCA eigenspace and the newly obtained projected Covariance object is " "@@Covariance: Get fraction variance...|queried@ for the fraction variance.") MAN_END MAN_BEGIN (U"PitchTier: To Pitch...", U"djmw", 20061128) INTRO (U"Synthesizes a new @Pitch from the selected @PitchTier.") MAN_END MAN_BEGIN (U"Polygon: Rotate...", U"djmw", 20100418) INTRO (U"Rotates the selected @@Polygon@ counterclockwise with respect to the given coordinates.") MAN_END MAN_BEGIN (U"Create simple Polygon...", U"djmw", 20140117) INTRO (U"Creates a @@Polygon@ from user supplied x/y pairs.") ENTRY (U"Settings") TAG (U"##Name") DEFINITION (U"defines the name of the resulting Polygon.") TAG (U"##Vertices as X-Y pairs#,") DEFINITION (U"defines the x-y values of the vertices of the Polygon. The Polygon will be automatically closed, i.e., the first and the last point will be connected.") ENTRY (U"Example") NORMAL (U"The command ##Create simple Polygon: \"p\", \"0.0 0.0 0.0 1.0 1.0 0.0\"# defines a Polygon with three points. In the figure the three points are indicated with open circles while the Polygon is drawn as a closed figure.") SCRIPT (4,4, U"Create simple Polygon: \"p\", \"0.0 0.0 0.0 1.0 1.0 0.0\"\n" "Draw circles: 0, 1, 0, 1, 3\n" "Draw closed: 0, 1, 0, 1\n" "Remove\n") MAN_END MAN_BEGIN (U"Polygon: Get location of point...", U"djmw", 20120220) INTRO (U"Determines whether a given point is on the ##I#nside, the ##O#utside, on an ##E#dge or on a ##V#ertex of the selected Polygon.") ENTRY (U"Algorithm") NORMAL (U"We determine how often a horizontal line extending from the point crosses the polygon. If the number of crossings is even, the point is on the outside, else on the inside. Special care is taken to be able to detect if a point is on the boundary of the polygon. The used algorithm is from @@Hormann & Agathos (2001)@") MAN_END MAN_BEGIN (U"Polygon: Simplify", U"djmw", 20140509) INTRO (U"Removes collinear vertices from a @@Polygon@.") ENTRY (U"Example") SCRIPT (4, 4, U"p1 = Create simple Polygon: \"p\", \"0.0 0.0 0.0 1.0 0.5 0.5 1.0 0.0 0.5 0 0 -0.5 0 -0.25\"\n" "Draw closed: 0, 0, 0, 0\n" "Colour: \"Red\"\n" "Draw circles: 0, 0, 0, 0, 3\n" "p2 = Simplify\n" "Colour: \"Black\"\n" "Paint circles: 0, 0, 0, 0, 1.5\n" "removeObject: p1, p2\n" ) NORMAL (U"Given the Polygon with the seven vertices indicated by the red open circles, the Simplify action results in the Polygon with four vertices indicated by the filled black circles.") MAN_END MAN_BEGIN (U"Polygon: Translate...", U"djmw", 20100418) INTRO (U"Translates the selected @@Polygon@ over the given vector.") NORMAL (U"Given the old coordinates (x__i_, y__i_) and the translation (x__t_,y__t_), the new coordinates are:") FORMULA (U"x__i_\\'p = x__i_ + x__t_") FORMULA (U"y__i_\\'p = y__i_ + y__t_") MAN_END MAN_BEGIN (U"Polynomial", U"djmw", 19990608) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"An object of type " "Polynomial represents a polynomial function on a domain.") NORMAL (U"A polynomial of degree %n is defined as:") FORMULA (U"%p(%x) = %c__1_ + %c__2_ %x + %c__3_ %x^^2^ + ... c__%n+1_ %x^^%n^.") NORMAL (U"The real numbers %c__%k_ are called the polynomial %coefficients.") ENTRY (U"Commands") NORMAL (U"Creation") LIST_ITEM (U"\\bu @@Create Polynomial...@ (in the ##New menu#)") LIST_ITEM (U"\\bu @@LPC: To Polynomial (slice)...@ (from prediction coefficients)") LIST_ITEM (U"\\bu @@LegendreSeries: To Polynomial@") LIST_ITEM (U"\\bu @@ChebyshevSeries: To Polynomial@") NORMAL (U"Drawing") LIST_ITEM (U"\\bu ##Draw...#") NORMAL (U"Queries") LIST_ITEM (U"\\bu @@Polynomial: Get function value...|Get function value...@: get %p(%x)") LIST_ITEM (U"\\bu ##Get coefficient value...#: get %c__%i_") LIST_ITEM (U"\\bu @@Polynomial: Get minimum...|Get minimum...@: minimum of %p(%x) on an interval") LIST_ITEM (U"\\bu @@Polynomial: Get x of minimum...|Get x of minimum...@") LIST_ITEM (U"\\bu @@Polynomial: Get maximum...|Get maximum...@: maximum of %p(%x) on an interval") LIST_ITEM (U"\\bu @@Polynomial: Get x of maximum...|Get x of maximum...@") LIST_ITEM (U"\\bu @@Polynomial: Get area...|Get area...@") NORMAL (U"Modification") LIST_ITEM (U"\\bu ##Set domain...#: new domain") LIST_ITEM (U"\\bu ##Set coefficient value...#: change one coefficient") NORMAL (U"Conversion") LIST_ITEM (U"\\bu @@Polynomial: To Spectrum...|To Spectrum...@ (evaluation over unit-circle)") LIST_ITEM (U"\\bu @@Polynomial: To Polynomial (derivative)|To Polynomial (derivative)@") LIST_ITEM (U"\\bu @@Polynomial: To Polynomial (primitive)|To Polynomial (primitive)@") LIST_ITEM (U"\\bu @@Polynomial: To Roots|To Roots@: roots of polynomial") MAN_END MAN_BEGIN (U"Polynomial: Get area...", U"djmw", 19990610) INTRO (U"A command to compute the area below the selected @Polynomial object.") ENTRY (U"Settings") TAG (U"##Xmin#, ##Xmax#") DEFINITION (U"define the interval.") NORMAL (U"The area is defined as __%xmin_\\in^^xmax^ %p(%x) %dx.") MAN_END MAN_BEGIN (U"Polynomial: Get function value...", U"djmw", 19990610) INTRO (U"A command to compute %p(%x) for the selected @Polynomial object.") MAN_END MAN_BEGIN (U"Polynomial: Get maximum...", U"djmw", 19990610) INTRO (U"A command to compute, on a specified interval, the maximum value of the selected " "@Polynomial object.") MAN_END MAN_BEGIN (U"Polynomial: Get x of maximum...", U"djmw", 19990610) INTRO (U"A command to compute, on a specified interval, the location of the maximum of the " "selected @Polynomial object.") MAN_END MAN_BEGIN (U"Polynomial: Get minimum...", U"djmw", 19990610) INTRO (U"A command to compute, on a specified interval, the minimum value of the selected " "@Polynomial object.") MAN_END MAN_BEGIN (U"Polynomial: Get x of minimum...", U"djmw", 19990610) INTRO (U"A command to compute, on a specified interval, the location of the minimum of the " "selected @Polynomial object.") MAN_END MAN_BEGIN (U"Polynomials: Multiply", U"djmw", 19990616) INTRO (U"A command to multiply two @@Polynomial|polynomials@ with each other.") NORMAL (U"The result of multiplying 1 + 2 %x and 2 \\-- %x^2 will be the polynomial:") FORMULA (U"2 + 4 %x \\-- %x^2 \\-- 2 %x^3.") MAN_END MAN_BEGIN (U"Polynomial: To Polynomial (derivative)", U"djmw", 19990610) INTRO (U"A command to compute the derivative of the selected @Polynomial object.") MAN_END MAN_BEGIN (U"Polynomial: To Polynomial (primitive)", U"djmw", 19990610) INTRO (U"A command to compute the primitive of the selected @Polynomial object.") MAN_END MAN_BEGIN (U"Polynomial: Scale x...", U"djmw", 19990610) INTRO (U"A command to transform the selected @Polynomial object to a new domain.") TAG (U"##Xmin# and ##Xmax#") DEFINITION (U"define the new domain.") ENTRY (U"Behaviour") NORMAL (U"The polynomial is transformed from domain [%x__min_, %x__max_] to " "domain [%Xmin, %Xmax] in such a way that its form stays the same. " "This is accomplished by first calculating:") FORMULA (U"%f(%x\\'p) = \\Si__%k=1..%numberOfCoefficients_ %c__%k_ %x\\'p^^%k^, where") FORMULA (U"%x\\'p = %a %x + %b,") NORMAL (U"and then collecting terms of equal degree. The %a and %b are defined as") FORMULA (U"%a = (%x__min_ \\-- %x__max_) / (%Xmin \\-- %Xmax)") FORMULA (U"%b = %x__min_ \\-- %a %Xmin") MAN_END MAN_BEGIN (U"Polynomial: To Roots", U"djmw", 19990608) INTRO (U"A command to compute the @@Roots|roots@ of the selected @Polynomial objects.") ENTRY (U"Algorithm") NORMAL (U"The roots are found from the polished eigenvalues of a special companion matrix. " "For further explanation on these methods see @@Press et al. (1992)@.") MAN_END MAN_BEGIN (U"Polynomial: To Spectrum...", U"djmw", 19990616) INTRO (U"A command to compute the @@Spectrum|spectrum@ of the selected @Polynomial objects.") ENTRY (U"Settings") TAG (U"##Nyquist frequency (Hz)") DEFINITION (U"defines the highest frequency in the spectrum. The lowest frequency of the spectrum " "will be 0 Hz.") TAG (U"##Number of frequencies") DEFINITION (U"defines the number of frequencies in the spectrum.") ENTRY (U"Algorithm") NORMAL (U"We calculate the spectrum by evaluating the polynomial at regularly spaced points %z__%k_ " "on the upper half of a circle with radius %r = 1 in the complex plane. The upperhalf of the " "unit circle, where %k\\.c%\\fi is in the interval [0, %\\pi], will be mapped to frequencies " "[0, @@Nyquist frequency@] in the spectrum. ") NORMAL (U"The complex values %z__%k_ (%k=1..%numberOfFrequencies) are defined as:") FORMULA (U"%z__%k_ = %r e^^%i %k %\\fi^, where,") FORMULA (U"%\\fi = \\pi / (%numberOfFrequencies \\-- 1) and %r = 1.") MAN_END MAN_BEGIN (U"Principal component analysis", U"djmw", 20120510) INTRO (U"This tutorial describes how you can perform principal component " "analysis with P\\s{RAAT}.") NORMAL (U"Principal component analysis (PCA) involves a mathematical procedure " "that transforms a number of (possibly) correlated variables into a " "(smaller) number of uncorrelated variables called %%principal " "components%. The first principal component accounts for as much of the " "variability in the data as possible, and each succeeding component " "accounts for as much of the remaining variability as possible.") ENTRY (U"1. Objectives of principal component analysis") LIST_ITEM (U"\\bu To discover or to reduce the dimensionality of the data set.") LIST_ITEM (U"\\bu To identify new meaningful underlying variables.") ENTRY (U"2. How to start") NORMAL (U"We assume that the multi-dimensional data have been collected in a @TableOfReal data matrix, " "in which the rows are associated with the cases and the columns with the variables.") NORMAL (U"Traditionally, principal component analysis is performed on the " "symmetric @@Covariance|Covariance@ matrix or on the symmetric @@correlation|Correlation@ matrix. " "These matrices can be calculated from the data matrix. " "The covariance matrix contains scaled @@SSCP|sums of squares and cross products@. " "A correlation matrix is like a covariance matrix but first the variables, i.e. the columns, have been standardized. " "We will have to standardize the data first if the variances of " "variables differ much, or if the units of measurement of the " "variables differ. You can standardize the data in the TableOfReal by choosing @@TableOfReal: Standardize columns|Standardize columns@.") NORMAL (U"To perform the analysis, we select the TabelOfReal data matrix in the list of objects and choose " "@@TableOfReal: To PCA|To PCA@. This results in a new PCA object in the " "list of objects.") NORMAL (U"We can now make a @@Scree plot|scree@ plot of the eigenvalues, @@Eigen: Draw " "eigenvalues...|Draw eigenvalues...@ " "to get an indication of the importance of each eigenvalue. The exact " "contribution of each eigenvalue (or a range of eigenvalues) to the " "\"explained variance\" can also be queried: " "@@PCA: Get fraction variance accounted for...|Get fraction variance " "accounted for...@. You might also check for the equality of a " "number of eigenvalues: @@PCA: Get equality of eigenvalues...|Get equality " "of eigenvalues...@.") ENTRY (U"3. Determining the number of components") NORMAL (U"There are two methods to help you to choose the number of components. " "Both methods are based on relations between the eigenvalues.") LIST_ITEM (U"\\bu Plot the eigenvalues, @@Eigen: Draw eigenvalues...|" "Draw eigenvalues...@. If the points on the graph tend to level out (show an \"elbow\"), " "these eigenvalues are usually close enough to zero that they can be " "ignored.") LIST_ITEM (U"\\bu Limit the number of components to that number that accounts for a certain fraction of the total variance. For example, if you are satisfied with 95% of the total variance explained then use the number you get by the query ##Get number of components (VAF)... 0.95#.") ENTRY (U"4. Getting the principal components") NORMAL (U"Principal components are obtained by projecting the multivariate " "datavectors on the space spanned by the eigenvectors. This can be done " "in two ways:") LIST_ITEM (U"1. Directly from the TableOfReal without first forming a " "@PCA object: " "@@TableOfReal: To Configuration (pca)...|To Configuration (pca)...@. " "You can then draw the Configuration or display its numbers. ") LIST_ITEM (U"2. Select a PCA and a TableOfReal object together and choose " "@@PCA & TableOfReal: To Configuration...|To Configuration...@. " "In this way you project the TableOfReal onto the PCA's eigenspace.") ENTRY (U"5. Mathematical background on principal component analysis") NORMAL (U"The mathematical technique used in PCA is called eigen analysis: " "we solve for the eigenvalues and eigenvectors of a square symmetric " "matrix with sums of squares and cross products. " "The eigenvector associated with the largest eigenvalue has the same " "direction as the first principal component. The eigenvector associated " "with the second largest eigenvalue determines the direction of the second " "principal component. " "The sum of the eigenvalues equals the trace of the square matrix and the " "maximum number of eigenvectors equals the number of rows (or columns) of " "this matrix.") ENTRY (U"6. Algorithms") NORMAL (U"If our starting point happens to be a symmetric matrix like the covariance matrix, " "we solve for the eigenvalue and eigenvectors " "by first performing a Householder reduction to tridiagonal form, followed" " by the QL algorithm with implicit shifts.") NORMAL (U"If, conversely, our starting point is the data matrix #%A , " "we do not have to form explicitly the matrix with sums of squares and " "cross products, #%A\\'p#%A. Instead, we proceed by a numerically more " "stable method, and form the @@singular value decomposition@ of #%A, " "#%U #%\\Si #%V\\'p. The matrix #%V then contains the eigenvectors, " "and the squared diagonal elements of #%\\Si contain the eigenvalues.") MAN_END MAN_BEGIN (U"PCA & Covariance: Project", U"djmw", 20040225) INTRO (U"A command to project the @Covariance object onto the eigenspace of " "the @PCA object. ") NORMAL (U"Further details can be found in @@Eigen & SSCP: Project@.") MAN_END MAN_BEGIN (U"PCA & SSCP: Project", U"djmw", 20040225) INTRO (U"A command to project the @SSCP object onto the eigenspace of " "the @PCA object. ") NORMAL (U"Further details can be found in @@Eigen & SSCP: Project@.") MAN_END MAN_BEGIN (U"Regular expressions", U"djmw", 20010706) INTRO (U"This tutorial describes the %syntax of regular expressions in P\\s{RAAT} ") ENTRY (U"Introduction") NORMAL (U"A %%regular expression% is a text string that describes a %set " "of strings. Regular expressions (regex) are useful as a way to search " "for patterns in text strings and, optionally, replace them by another " "pattern.") NORMAL (U"Some regex match only one string, i.e., the set they describe has " "only one member. For example, the regex \"ab\" matches the string \"ab\" " "and no others. Other regex match more than one string, i.e., the set " "they describe has more than one member. For example, the regex \"a*\" " "matches the string made up of any number (including zero) of \"a\"s. " "As you can see, some characters match themselves (such as \"a\" and " "\"b\") and these characters are called %ordinary characters. The " "characters that don't match themselves, such as \"*\", are called " "%special characters or %meta characters. Many special characters are only " "special characters in the %search regex and are ordinary characters in " "the substitution regex. ") NORMAL (U"You can read the rest of this tutorial sequentially with the help of " "the \"<1\" and \">1\" buttons.") LIST_ITEM (U"1. @@Regular expressions 1. Special characters|Special characters@ " "(\\bs \\^ \\$ { } [ ] ( ) . + ? \\| - &)") LIST_ITEM (U"2. @@Regular expressions 2. Quantifiers|Quantifiers@ " "(how often do we match).") LIST_ITEM (U"3. @@Regular expressions 3. Anchors|Anchors@ (where do we match)") LIST_ITEM (U"4. @@Regular expressions 4. Special constructs with parenthesis|" "Special constructs with parenthesis@ (grouping constructs)") LIST_ITEM (U"5. @@Regular expressions 5. Special control characters|" "Special control characters@ (difficult-to-type characters like \\bsn)") LIST_ITEM (U"6. @@Regular expressions 6. Convenience escape sequences|" "Convenience escape sequences@ " "(\\bsd \\bsD \\bsl \\bsL \\bss \\bsS \\bsw \\bsW \\bsB)") LIST_ITEM (U"7. @@Regular expressions 7. Octal and hexadecimal escapes|" "Octal and hexadecimal escapes@ (things like \\bs053 or \\bsX2B)") LIST_ITEM (U"8. @@Regular expressions 8. Substitution special characters|" "Substitution special characters@ (\\bs1..\\bs9 \\bsU \\bsu \\bsL \\bsl &)") NORMAL (U"More in depth coverage of regular expressions can be found in " "@@Friedl (1997)@.") MAN_END MAN_BEGIN (U"Regular expressions 1. Special characters", U"djmw", 20010718) INTRO (U"The following characters are the %meta characters that give special " "meaning to the regular expression search syntax:") TAG (U"#\\bs# the backslash %escape character.") DEFINITION (U"The backslash gives special meaning to the character " "following it. For example, the combination \"\\bsn\" stands for the " "%newline, one of the @@Regular expressions 5. Special control characters" "|control characters@. The combination \"\\bsw\" stands for a \"word\" " "character, one of the @@Regular expressions 6. Convenience escape " "sequences|" "convenience escape sequences@ while \"\\bs1\" is one of the @@Regular " "expressions 8. Substitution special characters|substitution special " "characters@.") LIST_ITEM1 (U"Example: The regex \"aa\\bsn\" tries to match two consecutive " "\"a\"s at the end of a line, inclusive the newline character itself.") LIST_ITEM1 (U"Example: \"a\\bs+\" matches \"a+\" and not a series of one or " "\"a\"s.") TAG (U"##\\^ # the caret is the start of line @@Regular expressions 3. " "Anchors|anchor@ or the negate symbol.") LIST_ITEM1 (U"Example: \"\\^ a\" matches \"a\" at the start of a line.") LIST_ITEM1 (U"Example: \"[\\^ 0-9]\" matches any non digit.") TAG (U"##\\$ # the dollar is the end of line @@Regular expressions 3. " "Anchors|anchor@.") LIST_ITEM1 (U"Example: \"b\\$ \" matches a \"b\" at the end of a line.") LIST_ITEM1 (U"Example: \"\\^ b\\$ \" matches the empty line.") TAG (U"##{ }# the open and close curly bracket are used as range @@Regular " "expressions 2. Quantifiers|quantifiers@.") LIST_ITEM1 (U"Example: \"a{2,3}\" matches \"aa\" or \"aaa\".") TAG (U"##[ ]# the open and close square bracket define a character class to " "match a %single character.") DEFINITION (U"The \"\\^ \" as the first character following the \"[\" negates " "and the match is for the characters %not listed. " "The \"-\" denotes a range of characters. Inside a \"[ ]\" character " "class construction most special characters are interpreted as ordinary " "characters. ") LIST_ITEM1 (U"Example: \"[d-f]\" is the same as \"[def]\" and matches \"d\", " "\"e\" or \"f\".") LIST_ITEM1 (U"Example: \"[a-z]\" matches any lowercase characters in the " "alfabet.") LIST_ITEM1 (U"Example: \"[\\^ 0-9]\" matches any character that is not a digit.") LIST_ITEM1 (U"Example: A search for \"[][()?<>$^.*?^]\" in the string " "\"[]()?<>$^.*?^\" followed by a replace string \"r\" has the result " "\"rrrrrrrrrrrrr\". Here the search string is %one character class and " "all the meta characters are interpreted as ordinary characters without " "the need to escape them.") TAG (U"##( )# the open and close parenthesis are used for grouping " "characters (or other regex).") DEFINITION (U"The groups can be referenced in " "both the search and the @@Regular expressions 8. Substitution special " "characters|substitution@ phase. There also exist some @@Regular " "expressions 4. Special constructs with parenthesis|special constructs " "with parenthesis@.") LIST_ITEM1 (U"Example: \"(ab)\\bs1\" matches \"abab\".") TAG (U"##.# the dot matches any character except the newline.") LIST_ITEM1 (U"Example: \".a\" matches two consecutive characters where " "the last one is \"a\".") LIST_ITEM1 (U"Example: \".*\\bs.txt\\$ \" matches all strings that end in " "\".txt\".") TAG (U"##*# the star is the match-zero-or-more @@Regular expressions 2. " "Quantifiers|quantifier@.") LIST_ITEM1 (U"Example: \"\\^ .*\\$ \" matches an entire line. ") TAG (U"##+# the plus is the match-one-or-more quantifier.") TAG (U"##?# the question mark is the match-zero-or-one " "quantifier. The question mark is also used in " "@@Regular expressions 4. Special constructs with parenthesis|special " "constructs with parenthesis@ and in @@Regular expressions 2. " "Quantifiers|changing match behaviour@.") TAG (U"##\\| # the vertical pipe separates a series of alternatives.") LIST_ITEM1 (U"Example: \"(a|b|c)a\" matches \"aa\" or \"ba\" or \"ca\".") TAG (U"##< ># the smaller and greater signs are @@Regular expressions 3. " "Anchors|anchors@ that specify a left or right word boundary.") TAG (U"##-# the minus indicates a range in a character class (when it is " "not at the first position after the \"[\" opening bracket or the last " "position before the \"]\" closing bracket.") LIST_ITEM1 (U"Example: \"[A-Z]\" matches any uppercase character.") LIST_ITEM1 (U"Example: \"[A-Z-]\" or \"[-A-Z]\" match any uppercase character " "or \"-\".") TAG (U"##&# the and is the \"substitute complete match\" symbol.") MAN_END MAN_BEGIN (U"Regular expressions 2. Quantifiers", U"djmw", 20010708) INTRO (U"Quantifiers specify how often the preceding @@Regular expressions|" "regular expression@ should match.") TAG (U"##*# Try to match the preceding regular expression zero or more times.") LIST_ITEM1 (U"Example: \"(ab)c*\" matches \"ab\" followed by zero or more " "\"c\"s, i.e., \"ab\", \"abc\", \"abcc\", \"abccc\" ...") TAG (U"##+# Try to match the preceding regular expression one or more times.") LIST_ITEM1 (U"Example: \"(ab)c+\" matches \"ab\" followed by one or more " "\"c\"s, i.e., \"abc\", \"abcc\", \"abccc\" ...") TAG (U"##{%m, %n}# Try to match the preceding regular expression between %m " "and %n times.") DEFINITION (U"If you leave %m out, it is assumed to be zero. If you leave " "%n out it is assumed to be infinity. I.e., \"{,%n}\" matches from %zero " "to %n times, \"{%m,}\" matches a minimum of %m times, \"{,}\" matches " "the same as \"*\" and \"{n}\" is shorthand for \"{n, n\"} and matches " "exactly %n times.") LIST_ITEM1 (U"Example: \"(ab){1,2}\" matches \"ab\" and \"abab\".") TAG (U"##?# Try to match zero or one time.") ENTRY (U"Changing match behaviour") NORMAL (U"Default the quantifiers above try to match as much as possible, they " "are %greedy. " "You can change greedy behaviour to %lazy behaviour by adding an " "extra \"?\" after the quantifier.") LIST_ITEM1 (U"Example: In the string \"cabddde\", the search \"abd{1,2}\" " "matches \"abdd\", while the search for \"abd{1,2}?\" matches \"abd\".") LIST_ITEM1 (U"Example: In the string \"cabddde\", the search \"abd+\" " "matches \"abddd\", while the search for \"abd+?\" matches \"abd\".") MAN_END MAN_BEGIN (U"Regular expressions 3. Anchors", U"djmw", 20010708) INTRO (U"Anchors let you specify a very specific position within the search " "text.") TAG (U"##\\^ # Try to match the (following) regex at the beginning of a line.") LIST_ITEM1 (U"Example: \"\\^ ab\" matches \"ab\" only at the beginning of a " "line and not, for example, in the line \"cab\".") TAG (U"##\\$ # Try to match the (following) regex at the end of a line.") TAG (U"##<# Try to match the regex at the %start of a word.") DEFINITION (U"The character class that defines a %word can be found at the " "@@Regular expressions 6. Convenience escape sequences|convenience escape " "sequences@ page.") TAG (U"##># Try to match the regex at the %end of a word.") TAG (U"##\\bsB# Not a word boundary") DEFINITION (U"") MAN_END MAN_BEGIN (U"Regular expressions 4. Special constructs with parenthesis", U"djmw", 20010710) INTRO (U"Some special constructs exist with parenthesis. ") TAG (U"##(?:#%regex#)# is a grouping-only construct.") DEFINITION (U"They exist merely for efficiency reasons and facilitate grouping.") TAG (U"##(?=#%regex#)# is a positive look-ahead.") DEFINITION (U"A match of the regular expression contained in the positive " "look-ahead construct is attempted. If the match succeeds, control is " "passed to the regex following this construct and the text consumed by " "this look-ahead construct is first unmatched. ") TAG (U"##(?!#%regex#)# is a negative look-ahead.") DEFINITION (U"Functions like a positive look-ahead, only the " "%regex must %not match.") LIST_ITEM (U"Example: \"abc(?!.*abc.*)\" searches for the %last " "occurrence of \"abc\" in a string.") TAG (U"##(?i#%regex#)# is a case insensitive regex.") TAG (U"##(?I#%regex#)# is a case sensitive regex.") DEFINITION (U"Default a regex is case sensitive. ") LIST_ITEM1 (U"Example: \"(?iaa)\" matches \"aa\", \"aA\", \"Aa\" and \"AA\".") TAG (U"##(?n#%regex#)# matches newlines.") TAG (U"##(?N#%regex#)# doesn't match newlines.") NORMAL (U"All the constructs above do not capture text and cannot be " "referenced, i.e., the parenthesis are not counted. However, you " "can make them capture text by surrounding them with %ordinary " "parenthesis.") MAN_END MAN_BEGIN (U"Regular expressions 5. Special control characters", U"djmw", 20010708) INTRO (U"Special control characters in a @@Regular expressions|regular " "expression@ specify characters that are difficult to type.") TAG (U"#\\bsa alert (bell).") TAG (U"#\\bsb backspace.") TAG (U"#\\bse ASCII escape character.") TAG (U"#\\bsf form feed (new page).") TAG (U"#\\bsn newline.") TAG (U"#\\bsr carriage return.") LIST_ITEM1 (U"Example : a search for \"\\bsr\\bsn\" followed by a replace " "\"\\bsr\" changes Windows text files to Macintosh text files.") LIST_ITEM1 (U"Example : a search for \"\\bsr\" followed by a replace " "\"\\bsn\" changes Macintosh text files to Unix text files.") LIST_ITEM1 (U"Example : a search for \"\\bsr\\bsn\" followed by a replace " "\"\\bsn\" changes Windows text files to Unix text files.") TAG (U"#\\bst horizontal tab.") TAG (U"#\\bsv vertical tab.") MAN_END MAN_BEGIN (U"Regular expressions 6. Convenience escape sequences", U"djmw", 20010708) INTRO (U"Convenience escape sequences in a @@Regular expressions|regular " "expression@ present a shorthand for some character classes.") TAG (U"#\\bsd matches a digit: [0-9].") LIST_ITEM1 (U"Example: \"-?\\bsd+\" matches any integer.") TAG (U"#\\bsD %not a digit: [\\^ 0-9].") TAG (U"#\\bsl a letter: [a-zA-Z].") TAG (U"#\\bsL %not a letter: [\\^ a-zA-Z].") TAG (U"#\\bss whitespace: [ \\bst\\bsn\\bsr\\bsf\\bsv].") TAG (U"#\\bsS %not whitespace: [\\^ \\bst\\bsn\\bsr\\bsf\\bsv].") TAG (U"#\\bsw \"word\" character: [a-zA-Z0-9\\_ ].") LIST_ITEM1 (U"Example: \"\\bsw+\" matches a \"word\", i.e., a string of one " "or more characters that may consist of letters, digits and underscores.") TAG (U"#\\bsW %not a \"word\" character: [\\^ a-zA-Z0-9\\_ ].") TAG (U"#\\bsB any character that is %not a word-delimiter.") MAN_END MAN_BEGIN (U"Regular expressions 7. Octal and hexadecimal escapes", U"djmw", 20010709) INTRO (U"An octal number can be represented by the octal escape \"\\bs0\" " "and maximally three digits from the digit class [0-7]. " "The octal number should not exceed \\bs0377. ") NORMAL (U"A hexadecimal number can be represented by the octal escape " "\"\\bsx\" or \"\\bsX\"and maximally two characters from the class " "[0-9A-F]. The maximum hexadecimal number should not exceed \\bsxFF. ") LIST_ITEM1 (U"Example: \\bs053 and \\bsX2B both specify the \"+\" character.") MAN_END MAN_BEGIN (U"Regular expressions 8. Substitution special characters", U"djmw", 20010708) INTRO (U"The substitution string is mostly interpreted as ordinary text except " "for the @@Regular expressions 5. Special control characters|" "special control characters@, the @@Regular expressions 7. Octal and " "hexadecimal escapes|octal and hexadecimal escapes@ and the following " "character combinations:") TAG (U"#\\bs1 ... #\\bs9 are backreferences at sub-expressions 1 ... 9 in the match.") DEFINITION (U"Any of the first nine sub-expressions of the match string can " "be inserted into the replacement string by inserting a `\\bs' followed " "by a digit from 1 to 9 that represents the string matched by a " "parenthesized expression within the regular expression. The numbering " "is left to right.") LIST_ITEM1 (U"Example: A search for \"(a)(b)\" in the string \"abc\", " "followed by a replace \"\\bs2\\bs1\" results in \"bac\".") TAG (U"#& reference at entire match.") DEFINITION (U"The entire string that was matched by the search operation will " "be substituted.") LIST_ITEM1 (U"Example: a search for \".\" in the string \"abcd\" followed by " "the replace \"&&\" doubles every character in the result " "\"aabbccdd\".") TAG (U"#\\bsU #\\bsu to uppercase.") DEFINITION (U"The text inserted by \"&\" or \"\\bs1\" ... \"\\bs9\" is " "converted to %uppercase (\"\\bsu\" only changes the %first character to " "uppercase).") LIST_ITEM1 (U"Example: A search for \"(aa)\" in the string \"aabb\", " "followed by a replace \"\\bsU\\bs1bc\" results in the string \"AAbcbb\".") TAG (U"#\\bsL #\\bsl to lowercase.") DEFINITION (U"The text inserted by \"&\" or \"\\bs1\" ... \"\\bs9\" is " "converted to %lowercase (\"\\bsl\" only changes the %first character to " "lowercase).") LIST_ITEM1 (U"Example: A search for \"(AA)\" with a replace \"\\bsl\\bs1bc\" " "in the string \"AAbb\" results in the string \"aAbcbb\".") MAN_END MAN_BEGIN (U"Roots", U"djmw", 19990608) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"An object of type Roots " "represents the (complex) roots of a @@Polynomial|polynomial@ function.") ENTRY (U"Commands") NORMAL (U"Creation") LIST_ITEM (U"\\bu @@Polynomial: To Roots@") NORMAL (U"Drawing") LIST_ITEM (U"\\bu ##Draw...# (in the complex plane)") NORMAL (U"Queries") LIST_ITEM (U"\\bu ##Get root...#: get complex root") LIST_ITEM (U"\\bu ##Get real part of root...#") LIST_ITEM (U"\\bu ##Get imaginary part of root...#") MAN_END MAN_BEGIN (U"Scree plot", U"djmw", 20040331) NORMAL (U"A scree plot shows the sorted eigenvalues, from large to " "small, as a function of the eigenvalue index.") MAN_END MAN_BEGIN (U"singular value decomposition", U"djmw", 20120510) INTRO (U"The %%singular value decomposition% (SVD) is a matrix factorization algorithm.") NORMAL (U"For %m > %n, the singular value decomposition of a real %m \\xx %n matrix #A is the " "factorization") FORMULA (U"#A = #U #\\Si #V\\'p,") NORMAL (U"The matrices in this factorization have the following properties:") TAG (U"#U [%m \\xx %n] and #V [%n \\xx %n]") DEFINITION (U"are orthogonal matrices. The columns #u__%i_ of #U =[#u__1_, ..., #u__%n_] " "are the %%left singular vectors%, and the columns #v__%i_ of #V [#v__1_, ..., #v__%n_] " "are the %%right singular vectors%.") TAG (U"#\\Si [%n \\xx %n] = diag (%\\si__1_, ..., %\\si__%n_)") DEFINITION (U"is a real, nonnegative, and diagonal matrix. Its diagonal contains the so called " "%%singular values% %\\si__%i_, where %\\si__1_ \\>_ ... \\>_ %\\si__%n_ \\>_ 0.") NORMAL (U"If %m < %n, the decomposition results in #U [%m \\xx %m] and #V [%n \\xx %m].") MAN_END MAN_BEGIN (U"Sound & Pitch: Change speaker...", U"djmw", 20070722) INTRO (U"A command to create a new Sound object with manipulated characteristics " "from the selected @Sound and @Pitch.") NORMAL (U"With this command you can have finer grained control over the " "pitch than with the @@Sound: Change speaker...@ command. " "Accurate pitch measurement determines the quality of the " "@@overlap-add@ synthesis." ) ENTRY (U"Settings") NORMAL (U"The settings are described in @@Sound: Change speaker...@. ") MAN_END MAN_BEGIN (U"Sound & Pitch: Change gender...", U"djmw", 20070722) /* INTRO (U"Deprecated: use @@Sound & Pitch: Change speaker...@") */ NORMAL (U"A command to create a new Sound object with manipulated characteristics " "from the selected @Sound and @Pitch.") NORMAL (U"With this command you can have finer grained control over the " "pitch than with the @@Sound: Change gender...@ command. " "Accurate pitch measurement determines the quality of the " "@@overlap-add@ synthesis." ) ENTRY (U"Settings") NORMAL (U"The settings are described in @@Sound: Change gender...@. ") MAN_END MAN_BEGIN (U"Sound: Change gender...", U"djmw", 20030205) /* INTRO (U"Deprecated: use @@Sound: Change speaker...@") */ NORMAL (U"A command to create a new @Sound with manipulated characteristics.") ENTRY (U"Settings") NORMAL (U"The quality of the @@overlap-add|manipulation@ depends on the pitch measurement.") NORMAL (U"The arguments that control the pitch measurement are:") TAG (U"##Minimum pitch (Hz)# (standard value: 75 Hz)") DEFINITION (U"pitch candidates below this frequency will not be considered.") TAG (U"##%Maximum pitch (Hz)# (standard value: 600 Hz)") DEFINITION (U"pitch candidates above this frequency will be ignored.") NORMAL (U"The arguments that control the manipulation are:") TAG (U"##Formant shift ratio") DEFINITION (U"determines the frequencies of the formants in the newly created " "Sound. If this ratio equals 1 no frequency shift will occur and " "the formant frequencies will not change. A ratio of 1.1 will change " "a male voice to a voice with approximate female formant characteristics. " "A ratio of 1/1.1 will change a female voice to a voice with approximate male formant " "characteristics.") TAG (U"##New pitch median (Hz)# (standard value: 0.0 Hz, i.e. same as original)") DEFINITION (U"determines what the median pitch of the new Sound will be. " "The pitch values in the newly created Sound will be calculated from the pitch " "values in the selected Sound by multiplying them by a factor " "%%newPitchMedian / oldPitchMedian%. This factor equals 1.0 if the default " "value for the new pitch median (0.0) is chosen. ") TAG (U"##Pitch range factor# (standard value: 1.0)") DEFINITION (U"determines an %extra% scaling of the new pitch values around the %new% " "pitch median. A factor of 1.0 means that no additional pitch modification will occur " "(except the obvious one described above). A factor of 0.0 monotonizes the new " "sound to the new pitch median.") TAG (U"##Duration factor# (standard value: 1.0)") DEFINITION (U"The factor with which the sound will be lengthened. The default is 1.0. " "If you take a value less than 1.0, the resulting sound will be shorter than " "the original. A value larger than 3.0 will not work.") NORMAL (U"If you want more control over the synthesis you can supply your own " "Pitch object and use the @@Sound & Pitch: Change gender...@ command. ") ENTRY (U"Algorithm") NORMAL (U"The shifting of frequencies is done via manipulation of the sampling frequency. " "Pitch and duration changes are generated with @@overlap-add@ synthesis.") NORMAL (U"The new pitch values are calculated in a two step process. We first multiply all " "the pitches with the factor %%newPitchMedian / oldPitchMedian% according to:") FORMULA (U"%newPitch = %pitch * %newPitchMedian / %oldPitchMedian.") NORMAL (U"It follows that if the %newPitchMedian equals the %oldPitchMedian no " "change in pitch values will occur in the first step.") NORMAL (U"Subsequently, the pitch range scale factor determines the final pitch values " "in the following linear manner:") FORMULA (U"%finalPitch = %newPitchMedian + (%newPitch \\-- %newPitchMedian) * %pitchRangeScaleFactor") NORMAL (U"Hence, it follows that no further scaling occurs if %pitchRangeScaleFactor " "equals 1.0.") MAN_END MAN_BEGIN (U"Sound: Change speaker...", U"djmw", 20080515) INTRO (U"A command to create a new @Sound with manipulated characteristics.") ENTRY (U"Settings") NORMAL (U"The quality of the @@overlap-add|manipulation@ depends on the pitch measurement.") NORMAL (U"The arguments that control the pitch measurement are:") TAG (U"##Pitch floor (Hz)# (standard value: 75 Hz)") DEFINITION (U"pitch candidates below this frequency will not be considered.") TAG (U"##Pitch ceiling (Hz)# (standard value: 600 Hz)") DEFINITION (U"pitch candidates above this frequency will be ignored.") NORMAL (U"The arguments that control the manipulation are:") TAG (U"##Multiply formants by") DEFINITION (U"determines the formant frequencies of the newly created sound. " "The formant frequency of the new sound will equal the formant frequencies of the selected sound multiplied by this number. " "If this number equals 1, formant frequencies will not change. A number of 1.1 will change " "a male voice to a voice with approximate female formant characteristics. " "A ratio of 1/1.1 will change a female voice to a voice with approximate male formant " "characteristics.") TAG (U"##Multiply pitch by") DEFINITION (U"determines what the pitch of the new Sound will be. " "The pitch values of the new sound will equal the pitch values of the selected sound multiplied by this number. A value of 1.8 will approximately change a male's pitch to a female's pitch.") TAG (U"##Multiply pitch range by# (standard value: 1.0)") DEFINITION (U"determines the pitch range of the newly created sound. " "A factor of 1.0 means that no additional pitch modification will occur " "(except the obvious one described above). A factor of 0.0 monotonizes the new " "sound to the new pitch median. A negative number inverses the pitch range with respect to the median.") TAG (U"##Multiply duration by# (standard value: 1.0)") DEFINITION (U"determines how to modify the duration of the newly created sound. " "A value of 1.0 means that the new sound will have the same duration as the selected sound. " "A value less than 1.0 will result in a shortened new sound. A value larger than 2.5 will not work.") NORMAL (U"If you want more control over the synthesis you can supply your own " "Pitch object and use the @@Sound & Pitch: Change speaker...@ command. ") ENTRY (U"Algorithm") NORMAL (U"The shifting of formant frequencies is done via manipulation of the sampling frequency. " "To multiply all formants by a factor of 1.10 (i.e. raising them by 10 percent), a sampling " "frequency of 44100 Hz is first raised to 48510 Hz (without changing " "the samples). After this, the sound is lengthened by a factor of 1.10 " "and the pitch is lowered by a factor of 1.10, so that the original " "duration and pitch are restored. After this, the sound is resampled " "to 44100 Hz (by sinc interpolation)." "Pitch and duration changes are generated with @@overlap-add@ synthesis.") MAN_END MAN_BEGIN (U"Sound: Remove noise...", U"djmw", 20121122) INTRO (U"A command to suppress noise in the selected @Sound.") ENTRY (U"Settings") SCRIPT (5.4, Manual_SETTINGS_WINDOW_HEIGHT (5), U"" Manual_DRAW_SETTINGS_WINDOW ("Sound: Remove noise...", 5) Manual_DRAW_SETTINGS_WINDOW_RANGE(U"Noise time range (s)", U"0.0", U"0.0") Manual_DRAW_SETTINGS_WINDOW_FIELD(U"Window length (s)", U"0.025") Manual_DRAW_SETTINGS_WINDOW_RANGE(U"Filter frequency range (Hz)", U"80.0", U"10000.0") Manual_DRAW_SETTINGS_WINDOW_FIELD(U"Smoothing (Hz)", U"40.0") Manual_DRAW_SETTINGS_WINDOW_OPTIONMENU(U"Noise reduction method", U"Spectral subtraction") ) TAG (U"##Noise time range (s)") DEFINITION (U"the start and end time of a noise part in the sound whose characteristics will be used in the denoising. " "If the end time is chosen before the start time, the noise fragment will be chosen automatically around a position " "where the intensity is minimal. For good noise suppression it is important that the noise fragment's duration is chosen " "several times the length of the window.") TAG (U"##Window length (s)") DEFINITION (U"denoising takes place in (overlapping) windows of this length.") TAG (U"##Filter frequency range (Hz)") DEFINITION (U"before denoising the sound will be @@Sound: Filter (pass Hann band)...|band-pass filtered@. ") TAG (U"##Noise reduction method") DEFINITION (U"The method of %%spectral subtraction% was defined in @@Boll (1979)@. The variant implemented is modeled " "after a script by Ton Wempe.") MAN_END MAN_BEGIN (U"Sound: Draw where...", U"djmw", 20140509) INTRO (U"A command to draw only those parts of a @Sound where a condition holds.") ENTRY (U"Settings") SCRIPT (5.4, Manual_SETTINGS_WINDOW_HEIGHT (5), U"" Manual_DRAW_SETTINGS_WINDOW ("Sound: Draw where...", 5) Manual_DRAW_SETTINGS_WINDOW_RANGE("Time range (s)", "0.0", "0.0 (=all)") Manual_DRAW_SETTINGS_WINDOW_RANGE ("Vertical range", "0.0", "0.0 (=all)") Manual_DRAW_SETTINGS_WINDOW_BOOLEAN("Garnish", 1) Manual_DRAW_SETTINGS_WINDOW_OPTIONMENU("Drawing method", "Curve") Manual_DRAW_SETTINGS_WINDOW_TEXT ("Draw only those parts where the following condition holds", "x < xmin + (xmax - xmin) / 2; first half") ) TAG (U"##Time range (s)") DEFINITION (U"selects the time domain for the drawing.") TAG (U"##Vertical range") DEFINITION (U"defines the vertical limits; larger amplitudes will be clipped.") TAG (U"##Draw only those parts where the following condition holds#") DEFINITION (U"determines the part of the sound that will be drawn. All parts where the formula evaluates to true will be drawn. " "This formula may ##not# contain references to the sampling of the sound, i.e. don't use 'col', 'x1', 'dx' and 'ncol' in it.") ENTRY (U"Example 1") NORMAL (U"The following script draws all amplitudes larger than one in red.") CODE (U"Create Sound from formula: \"s\", \"Mono\", 0, 1, 2000, \"1.8*sin(2*pi*5*x)+randomGauss(0,0.1)\"") CODE (U"Colour: \"Red\"") CODE (U"Draw where: 0, 0, -2, 2, \"no\", \"Curve\", \"abs(self)>1\"") CODE (U"Colour: \"Black\"") CODE (U"Draw where: 0, 0, -2, 2, \"yes\", \"Curve\", \"not (abs(self)>1)\"") SCRIPT (8, 3, U"Create Sound from formula: \"s\", \"Mono\", 0, 1, 2000, \"1.8*sin(2*pi*5*x)+randomGauss(0,0.1)\"\n" "Colour: \"Red\"\n" "Draw where: 0, 0, -2, 2, \"no\", \"Curve\", \"abs(self)>1\"\n" "Colour: \"Black\"\n" "Draw where: 0, 0, -2, 2, \"yes\", \"Curve\", \"not (abs(self)>1)\"\n" "Remove\n" ) ENTRY (U"Example 2") NORMAL (U"Draw the second half of a sound:") CODE (U"Draw where: 0, 0, -1, 1, \"no\", \"Curve\", \"x > xmin + (xmax - xmin) / 2\"") ENTRY (U"Example 3") NORMAL (U"Draw only positive amplitudes:") CODE (U"Draw where: 0, 0, -1, 1, \"no\", \"Curve\", \"self>0\"") ENTRY (U"Example 4") NORMAL (U"Draw parts where pitch is larger than 300 Hz in red:") CODE (U"s = selected (\"Sound\")") CODE (U"p = To Pitch: 0, 75, 600") CODE (U"pt = Down to PitchTier\"") CODE (U"selectObject: s") CODE (U"Colour: \"Red\"") CODE (U"Draw where: 0, 0, -1, 1, \"yes\", \"Curve\", \"Object_'pt'(x) > 300\"") CODE (U"Colour: \"Black\"") CODE (U"Draw where: 0, 0, -1, 1, \"yes\", \"Curve\", \"not (Object_'pt'(x) > 300)\"") MAN_END MAN_BEGIN (U"Sound: Fade in...", U"djmw", 20140117) INTRO (U"A command to gradually increase the amplitude of a selected @Sound.") ENTRY (U"Settings") TAG (U"##Channel") DEFINITION (U"determines whether you want to fade all channels or only a selected channel.") TAG (U"##Time (s)") DEFINITION (U"determines where the fade-in will take place. If %time is earlier than the start time of the sound, the start time of the sound wil be used.") TAG (U"##Fade time (s)") DEFINITION (U"determines the start point and the endpoint of the fade-in with respect to the %time argument. Depending on the sign of %%fadeTime%, %time is either the start or the end position of the fade-in. If %%fadeTime% is positive, fade-in will take place between %%time% and %%time+fadeTime%. If %%fadeTime% is negative, fade-in wil take place between %%time+fadeTime% and %time.") TAG (U"##Silent from start") DEFINITION (U"when on, makes the sound silent before the fade-in starts. " "When off, the sound before the fade-in starts will not be changed. ") ENTRY (U"Algorithm") NORMAL (U"Multiplication with the first half period of a (1-cos(x))/2 function. ") ENTRY (U"Cross-fading two sounds") NORMAL (U"The following script cross-fades two sounds s1 and s2 at time 1 second and leaves the result in s2.") CODE1 (U"crossFTime = 0.5") CODE1 (U"t = 1") CODE1 (U"Create Sound from formula: \"s1\", 1, 0, 2, 44100, \"sin(2*pi*500*x)\"") CODE1 (U"Fade out: 0, t-crossFTime/2, crossFTime, \"yes\"") CODE1 (U"Create Sound from formula: \"s2\", 1, 0, 2, 44100, \"sin(2*pi*1000*x)\"") CODE1 (U"Fade in.: 0, t-crossFTime/2, crossFTime, \"yes\"") CODE1 (U"Formula: \"self+Sound_s1[]\"") MAN_END MAN_BEGIN (U"Sound: Fade out...", U"djmw", 20121010) INTRO (U"A command to gradually decrease the amplitude of a selected @Sound.") ENTRY (U"Settings") TAG (U"##Channel") DEFINITION (U"determines whether you want to fade all channels or only a selected channel.") TAG (U"##Time (s)") DEFINITION (U"determines where the fade-out will take place. If %time is later than the end time of the sound, the end time of the sound wil be used.") TAG (U"##Fade time (s)") DEFINITION (U"determines the start point and the endpoint of the fade-out with respect to the %time argument. Depending on the sign of %%fadeTime%, %time is either the start or the end position of the fade-out. If %%fadeTime% is positive, fade-out will take place between %%time% and %%time+fadeTime%. If %%fadeTime% is negative, fade-out wil take place between %%time+fadeTime% and %time.") TAG (U"##Silent to end") DEFINITION (U"Make the sound silent after the fade-out finishes. ") ENTRY (U"Algorithm") NORMAL (U"Multiplication with the first half period of a (1+cos(%%x%))/2 function.") MAN_END MAN_BEGIN (U"Sound: Filter (gammatone)...", U"djmw", 19980712) INTRO (U"A command to filter a Sound by a fourth order gammatone bandpass filter.") ENTRY (U"Settings") TAG (U"##Centre frequency (Hz)#, ##Bandwidth (Hz)#") DEFINITION (U"determine the passband of the filter.") ENTRY (U"Algorithm") NORMAL (U"The impulse response of the filter is a 4-th order @@gammatone@. This " "filter is implemented as a simple 8-th order recursive digital filter with " "4 zeros and 8 poles (these 8 poles consist of one conjugate pole pair to the " "4-th power). In the Z-domain its formula is: ") FORMULA (U"%#H (%z) = (1 + \\su__%i=1..4_ %a__%i_%z^^%\\--i^) / " "(1 + \\su__%j=1..8_ %b__%j_%z^^%\\--j^)") NORMAL (U"The derivation of the filter coefficients %a__%i_ and %b__%j_ is " "according to @@Slaney (1993)@. " "The gain of the filter is scaled to unity at the centre frequency.") MAN_END MAN_BEGIN (U"Sound: Play as frequency shifted...", U"djmw", 20140106) INTRO (U"Plays the selected @Sound with all frequencies shifted by the same amount. This trick can be used to make " "audible those sounds that are normally not audible at all by human beings, like for example ultrasounds or infrasounds.") ENTRY (U"Settings") TAG (U"##Shift by (Hz)") DEFINITION (U"the amount by which frequencies are shifted. A positive number shifts frequencies up, a negative number " "shifts frequencies down. ") ENTRY (U"##Example") NORMAL (U"Rodents produce sounds with frequencies far outside the human audible range. Some meaningfull sqeeks of these animals " "are present in the frequency range from 54 kHz up to sometimes 100kHz. By choosing a shift value of -54000 Hz and a sampling " "frequency of 44100 Hz, all frequencies between 54000 Hz and (54000+22050=) 76050 Hz will be shifted down by 54000 Hz. The " "rodents frequencies in the interval from 54000 Hz to 76050 Hz will theredore be mapped to the frequency interval between 0 and 22050 Hz. ") MAN_END MAN_BEGIN (U"Sound: To BarkSpectrogram...", U"djmw", 20141023) INTRO (U"A command that creates a @BarkSpectrogram object from every selected " "@Sound object by @@band filtering in the frequency domain@ with a " "bank of filters.") NORMAL (U"The auditory filter functions used are defined as:") FORMULA (U"10 log %#H(%z) = 7 - 7.5 * (%z__%c_ - %z - 0.215) - 17.5 * \\Vr " "(0.196 + (%z__%c_ - %z - 0.215)^2)") NORMAL (U"where %z__%c_ is the central (resonance) frequency of the filter in Bark. " "The bandwidths of these filters are constant and equal 1 Bark. ") NORMAL (U"The auditory filters are defined in @@Sekey & Hanson (1984)@. You can draw these filters from " "a BarkSpectrogram object by selecting @@BarkSpectrogram: Draw Sekey-Hanson auditory filters...@.") MAN_END MAN_BEGIN (U"Sound: To FormantFilter...", U"djmw", 20141024) INTRO (U"A #deprecated command that creates a @FormantFilter object from every selected @Sound object by " "@@band filtering in the frequency domain@ with a bank of filters whose bandwidths depend on the pitch of the signal.") NORMAL (U"The analysis proceeds in two steps:") LIST_ITEM (U"1. We perform a pitch analysis (see @@Sound: To Pitch...@ for details).") LIST_ITEM (U"2. We perform a filter bank analysis on a linear frequency scale. The bandwidth of the filters depends on " "the measured pitch (see @@Sound & Pitch: To Spectrogram...@ for details).") MAN_END MAN_BEGIN (U"Sound: To Spectrogram (pitch-dependent)...", U"djmw", 20141024) INTRO (U"A command that creates a @Spectrogram object from every selected " "@Sound object by @@band filtering in the frequency domain@ with a " "bank of formant filters whose bandwidths vary with the local pitch of the signal.") NORMAL (U"The analysis proceeds in two steps:") LIST_ITEM (U"1. We perform a pitch analysis (see @@Sound: To Pitch...@ for details).") LIST_ITEM (U"2. We perform a filter bank analysis on a linear frequency scale. " "The bandwidth of the filters depends on the measured pitch (see @@Sound & Pitch: To Spectrogram...@ for details).") MAN_END MAN_BEGIN (U"Sound: Paint where...", U"djmw", 20140509) INTRO (U"A command to paint only those parts of a @Sound where a condition holds. The painted area is the area " "between the Sound and a horizontal line at a certain level.") ENTRY (U"Settings") SCRIPT (5.4, Manual_SETTINGS_WINDOW_HEIGHT (6), U"" Manual_DRAW_SETTINGS_WINDOW ("Sound: Paint where...", 6) Manual_DRAW_SETTINGS_WINDOW_FIELD ("Colour (0-1, name, {r,g,b})", "0.5") Manual_DRAW_SETTINGS_WINDOW_RANGE("Time range (s)", "0.0", "0.0 (=all)") Manual_DRAW_SETTINGS_WINDOW_RANGE ("Vertical range", "0.0", "0.0 (=all)") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Fill from level", "0") Manual_DRAW_SETTINGS_WINDOW_BOOLEAN("Garnish", 1) Manual_DRAW_SETTINGS_WINDOW_TEXT ("Paint only those parts where the following condition holds", "1; always") ) TAG (U"##Colour") DEFINITION (U"defines the @@Colour|colour@ of the paint.") TAG (U"##Time range (s)") DEFINITION (U"selects the time domain for the drawing.") TAG (U"##Vertical range") DEFINITION (U"defines the vertical limits; larger amplitudes will be clipped.") TAG (U"##Fill from level") DEFINITION (U"defines the level of the horizontal line. ") TAG (U"##Formula") DEFINITION (U"determines the part of the sound that will be painted. All parts where the formula evaluates to true will be painted. " "This formula may ##not# contain references to the sampling of the sound, i.e. don't use 'col', 'x1', 'dx' and 'ncol' in it.") ENTRY (U"Example 1") NORMAL (U"The following script paints the area under a sine curve in red and the area above in green." "For the first paint the horizontal line is at y=-1, for the second paint the line is at y=+1. " "The formula always evaluates to true.") CODE (U"s = Create Sound from formula: \"s\", 1, 0, 1, 10000, \"0.5*sin(2*pi*5*x)\"") CODE (U"Paint where: \"Red\", 0, 0, -1, 1, -1, \"yes\", \"1\"") CODE (U"Paint where: \"Green\", 0, 0, -1, 1, 1, \"no\", \"1\"") SCRIPT (8, 5, U"s = Create Sound from formula: \"s\", 1, 0, 1, 10000, \"0.5*sin(2*pi*5*x)\"\n" "Paint where: \"Red\", 0, 0, -1, 1, -1, \"no\", \"1\"\n" "Paint where: \"Green\", 0, 0, -1, 1, 1, \"yes\", \"1\"\n" "Remove\n") ENTRY (U"Example 2") NORMAL (U"The following script paints the area below zero in red and the area above in green." "The horizontal line is now always at y=0 and we use the formula to differentiate the areas.") CODE (U"s = Create Sound from formula: \"s\", 1, 0, 1, 10000, \"0.5*sin(2*pi*5*x)\"") CODE (U"Paint where: \"Red\", 0, 0, -1, 1, 0, \"no\", \"self>0\"") CODE (U"Paint where: \"Green\", 0, 0, -1, 1, 0, \"yes\", \"self<0\"") SCRIPT (8, 5, U"s = Create Sound from formula: \"s\", 1, 0, 1, 10000, \"0.5*sin(2*pi*5*x)\"\n" "Paint where: \"Red\", 0, 0, -1, 1, 0, \"no\", \"self<0\"\n" "Paint where: \"Green\", 0, 0, -1, 1, 0, \"yes\", \"self>0\"\n" "removeObject: s\n") ENTRY (U"Example 3") NORMAL (U"To give an indication that the area under a 1/x curve between the points %a and %b and the area " "between %c and %d are equal if %b/%a = %d/%c. For example, for %a=1, %b=2, %c=4 and %d=8: ") CODE (U"Create Sound from formula: \"1dx\", \"Mono\", 0, 20, 100, \"1/x\"") CODE (U"Draw: 0, 20, 0, 1.5, \"yes\", \"Curve\"") CODE (U"Paint where: \"Grey\", 0, 20, 0, 1.5, 0, \"yes\", \"(x >= 1 and x <2) or (x>=4 and x<8)\"") CODE (U"One mark bottom: 1, \"yes\", \"yes\", \"no\", \"\"") CODE (U"One mark bottom: 2, \"yes\", \"yes\", \"no\", \"\"") CODE (U"One mark bottom: 4, \"yes\", \"yes\", \"no\", \"\"") CODE (U"One mark bottom: 8, \"yes\", \"yes\", \"no\", \"\"") SCRIPT (8, 5, U"s = Create Sound from formula: \"1dx\", \"Mono\", 0, 20, 100, \"1/x\"\n" "Draw: 0, 20, 0, 1.5, \"yes\", \"Curve\"\n" "Paint where: \"Grey\", 0, 20, 0, 1.5, 0, \"yes\", \"(x >= 1 and x <2) or (x>=4 and x<8)\"\n" "One mark bottom: 1, \"yes\", \"yes\", \"no\", \"\"\n" "One mark bottom: 2, \"yes\", \"yes\", \"no\", \"\"\n" "One mark bottom: 4, \"yes\", \"yes\", \"no\", \"\"\n" "One mark bottom: 8, \"yes\", \"yes\", \"no\", \"\"\n" "removeObject: s\n") MAN_END MAN_BEGIN (U"Sounds: Paint enclosed...", U"djmw", 20140509) INTRO (U"Paints the area between the two selected @@Sound@s. ") ENTRY (U"Settings") SCRIPT (5.4, Manual_SETTINGS_WINDOW_HEIGHT (4), U"" Manual_DRAW_SETTINGS_WINDOW ("Sounds: Paint enclosed", 4) Manual_DRAW_SETTINGS_WINDOW_FIELD ("Colour (0-1, name, {r,g,b})", "0.5") Manual_DRAW_SETTINGS_WINDOW_RANGE("Time range (s)", "0.0", "0.0 (=all)") Manual_DRAW_SETTINGS_WINDOW_RANGE ("Vertical range", "0.0", "0.0 (=all)") Manual_DRAW_SETTINGS_WINDOW_BOOLEAN("Garnish", 1) ) TAG (U"##Colour") DEFINITION (U"defines the @@Colour|colour@ of the paint.") TAG (U"##Time range (s)") DEFINITION (U"selects the time domain for the drawing.") TAG (U"##Vertical range") DEFINITION (U"defines the vertical limits, larger amplitudes will be clipped.") ENTRY (U"Example") NORMAL (U"The following script paints the area enclosed between a sine tone of 5 Hz and the straight line %y = %x/2.") CODE (U"s1 = Create Sound from formula: \"sine\", \"Mono\", 0, 1, 10000, \"1/2 * sin(2*pi*5*x)\"") CODE (U"s2 = Create Sound from formula: \"line\", \"Mono\", 0, 1, 10000, \"x / 2\"") CODE (U"plusObject (s1)") CODE (U"Paint enclosed: \"Grey\", 0, 0, -1, 1, \"yes\"") SCRIPT ( 4, 2, U"s1 = Create Sound from formula: \"sine\", \"Mono\", 0, 1, 10000, \"1/2 * sin(2*pi*5*x)\"\n" "s2 = Create Sound from formula: \"line\", \"Mono\", 0, 1, 10000, \"x / 2\"\n" "selectObject: s1, s2\n" "Paint enclosed: \"Grey\", 0, 0, -1, 1, \"yes\"\n" "removeObject: s1, s2\n") MAN_END MAN_BEGIN (U"Sound: To Polygon...", U"djmw", 20140509) INTRO (U"A command that creates a @@Polygon@ from a selected @@Sound@, where the Polygon's " " points are defined by the (%time, %amplitude) pairs of the sound. ") ENTRY (U"Settings") TAG (U"##Channel") DEFINITION (U"defines which channel of the sound is used.") TAG (U"##Time range (s)") DEFINITION (U"defines the part of the sound whose (%time, %amplitude) pairs have to be included.") TAG (U"##Vertical range") DEFINITION (U"defines the vertical limits, larger amplitudes will be clipped.") TAG (U"##Connection y-value") DEFINITION (U"defines the y-value of the first and last point of the Polygon. This gives the opportunity to " " draw a closed Polygon with the horizontal connection line at any position you like. ") ENTRY (U"Example") NORMAL (U"The following script paints the area under a sound curve in red and the area above in green.") CODE (U"s = Create Sound from formula: \"s\", 1, 0, 1, 10000, \"0.5*sin(2*pi*5*x)\"") CODE (U"\\# Connection y-value is at amplitude -1: area under the curve.") CODE (U"p1 = To Polygon: 1, 0, 0, -1, 1, -1") CODE (U"Paint: \"{1,0,0}\", 0, 0, -1, 1") CODE (U"selectObject: s") CODE (U"\\# Connection y-value is now at amplitude 1: area above the curve.") CODE (U"p2 = To Polygon: 1, 0, 0, -1, 1, 1") CODE (U"Paint: \"{0,1,0}\", 0, 0, -1, 1") SCRIPT (4.5, 2, U"s = Create Sound from formula: \"s\", 1, 0, 1, 10000, \"0.5*sin(2*pi*5*x)\"\n" "p1 = To Polygon: 1, 0, 0, -1, 1, -1\n" "Paint: \"{1,0,0}\", 0, 0, -1, 1\n" "selectObject: s\n" "p2 = To Polygon: 1, 0, 0, -1, 1, 1\n" "Paint: \"{0,1,0}\", 0, 0, -1, 1\n" "removeObject: p2, p1, s\n" ) MAN_END #define xxx_to_TextGrid_detectSilences_COMMON_PARAMETERS_HELP \ TAG (U"##Silence threshold (dB)") \ DEFINITION (U"determines the maximum silence intensity value in dB with respect to the maximum " \ "intensity. For example, if %imax is the maximum intensity in dB then the maximum silence " \ "intensity is calculated as %%imax - silenceThreshold%; intervals with an intensity smaller " \ "than this value are considered as silent intervals.") \ TAG (U"##Minimum silent interval duration (s)") \ DEFINITION (U"determines the minimum duration for an interval to be considered as silent. " \ "If you don't want the closure for a plosive to count as silent then use a large enough value.") \ TAG (U"##Minimum sounding interval duration (s)") \ DEFINITION (U"determines the minimum duration for an interval to be ##not# considered as silent. " \ "This offers the possibility to filter out small intense bursts of relatively short duration.") \ TAG (U"##Silent interval label") \ DEFINITION (U"determines the label for a silent interval in the TextGrid.") \ TAG (U"##Sounding interval label") \ DEFINITION (U"determines the label for a sounding interval in the TextGrid.") MAN_BEGIN (U"Sound: To TextGrid (silences)...", U"djmw", 20061205) INTRO (U"A command that creates a @TextGrid in which the silent and sounding intervals of the selected @Sound are marked.") ENTRY (U"Settings") xxx_to_TextGrid_detectSilences_COMMON_PARAMETERS_HELP ENTRY (U"Algorithm") NORMAL (U"First the intensity is determined according to the @@Sound: To Intensity...@ command. " "Next the silent and sounding intervas are determined as in the @@Intensity: To TextGrid (silences)...@ command.") MAN_END MAN_BEGIN (U"Intensity: To TextGrid (silences)...", U"djmw", 20061201) INTRO (U"A command that creates a @TextGrid in which the silent and sounding intervals of the selected @Intensity are marked.") ENTRY (U"Settings") xxx_to_TextGrid_detectSilences_COMMON_PARAMETERS_HELP ENTRY (U"Algorithm") NORMAL (U"First the intensity contour is evaluated and the intervals above and below the silence threshold are marked as " "%sounding and %silent. " "We then remove sounding intervals with a duration smaller than the %%Minimum sounding interval duration%. " "This step is followed by joining the neighbouring silent intervals that resulted because of this removal. " "Finally we remove silent intervals with a duration smaller than the %%Minimum silent interval duration%. " "This is followed by joining the neighbouring sounding intervals that resulted because of this removal.") NORMAL (U"Experience showed that first removing short intensity bursts instead of short silences gave better results than doing it the other way around.") ENTRY (U"Important") NORMAL (U"The effectiveness of the %%Minimum silent interval duration% and %%Minimum sounding interval duration% " "depends on the effective analysis window duration that was used to determine the intensity contour. " "For example, if you have chosen 100 Hz for the \"Minimum pitch\" parameter in the @@Sound: To Intensity...@ analysis, " "the effective analysis window duration was 32 ms. Don't expect to find sounding " "or silent intervals with a duration smaller than this effective analysis window duration.") MAN_END MAN_BEGIN (U"Sound: Trim silences...", U"djmw", 20120323) INTRO (U"A command that creates from the selected @Sound a new sound in which all silence durations are not longer than a specified value.") ENTRY (U"Settings") TAG (U"%%Trim duration (s)%,") DEFINITION (U"specifies the maximum allowed silence duration.") TAG (U"%%Minimum pitch (Hz)%, and, %Time step (s)%,") DEFINITION (U"determine how we measure the intensities on which the determination of silent intervals is based. See @@Sound: To Intensity...@ for more info.") TAG (U"%%Silence threshold (dB)%, %%Minimum silent interval duration (s)%, and %%Minimum sounding interval duration%,") DEFINITION (U"determine how the silent intervals will be determined. See @@Intensity: To TextGrid (silences)...@ for more info.") TAG (U"%%Save trimming info as TextGrid%,") DEFINITION (U"determines if a TextGrid with trimming information will also be created. The TextGrid will have one tier where interval of the %%originating% sound that were trimmed have been labeled. ") TAG (U"%%Trim label%,") DEFINITION (U"determines the label that the trimmed intervals in the TextGrid will get.") MAN_END MAN_BEGIN (U"Sound & Pitch: To Spectrogram...", U"djmw", 20141024) INTRO (U"A command that creates a @Spectrogram object from the selected " "@Sound and @Pitch objects by @@band filtering in the frequency domain@ with a " "bank of filters whose bandwidths depend on the local pitch.") NORMAL (U"The filter functions used are:") FORMULA (U"%#H(%f, %F__0_) = 1 / (((%f__%c_^^2^ - %f^2) /%f\\.c%B(%F__0_)))^2 + 1),") NORMAL (U"where %f__%c_ is the central (resonance) frequency of the filter. " "%B(%F__0_) is the bandwidth in Hz and determined as") FORMULA (U"%B(%F__0_) = %relativeBandwidth\\.c%F__0_, ") NORMAL (U"where %F__0_ is the fundamental frequency as determined from the Pitch " "object. Whenever the value of %F__0_ is undefined, a value of 100 Hz is taken.") MAN_END MAN_BEGIN (U"Sound: To MelFilter...", U"djmw", 20141022) INTRO (U"A deprecated command. Use @@Sound: To MelSpectrogram...@ instead.") MAN_END MAN_BEGIN (U"Sound: To MelSpectrogram...", U"djmw", 20141022) INTRO (U"A command that creates a @MelSpectrogram object from every selected " "@Sound object by @@band filtering in the frequency domain@ with a " "set of triangular filters.") NORMAL (U"The filter functions used are all triangular in shape on a %mel " "frequency scale. Each filter function depends on three parameters, the " "lower frequency %f__%l_, the central frequency %f__%c_ and the higher " "frequency %f__%h_. " "On a %mel scale, the distances %f__%c_-%f__%l_ and %f__%h_-%f__%c_ " "are equal for each filter. The filter function is as follows:" ) FORMULA (U"%#H(%f) = 0 for %f \\<_ %f__%l_ and %f \\>_ %f__%h_") FORMULA (U"%#H(%f) = (%f - %f__%l_) / (%f__%c_ - %f__%l_) for %f__%l_ \\<_ %f \\<_ %f__%c_") FORMULA (U"%#H(%f) = (%f__%h_ - %f) / (%f__%h_ - %f__%c_) for %f__%c_ \\<_ %f \\<_ %f__%h_") NORMAL (U"In general the number of filter values stored in each frame of the MelSpectrogram is an order of magnitude smaller than the number of sound samples in the corresponding analysis frame.") MAN_END MAN_BEGIN (U"Sound: To Pitch (shs)...", U"djmw", 19970402) INTRO (U"A command that creates a @Pitch object from every selected @Sound object.") ENTRY (U"Purpose") NORMAL (U"to perform a pitch analysis based on a spectral compression model. " "The concept of this model is that each spectral component not only activates " "those elements of the central pitch processor that are most sensitive to the " "component's frequency, but also elements that have a lower harmonic " "relation with this component. Therefore, when a specific element of the " "central pitch processor is most sensitive at a frequency %f__0_, it receives " "contributions from spectral components in the " "signal at integral multiples of %f__0_.") ENTRY (U"Algorithm") NORMAL (U"The spectral compression consists of the summation of a sequence of " "harmonically compressed spectra. " "The abscissa of these spectra is compressed by an integral factor, the rank " "of the compression. The maximum of the resulting sum spectrum is the " "estimate of the pitch. Details of the algorithm can be " "found in @@Hermes (1988)@") ENTRY (U"Settings") TAG (U"##Time step (s)# (standard value: 0.01 s)") DEFINITION (U"the measurement interval (frame duration), in seconds.") TAG (U"##Minimum pitch (Hz)# (standard value: 50 Hz)") DEFINITION (U"candidates below this frequency will not be recruited. This parameter " "determines the length of the analysis window.") TAG (U"##Max. number of candidates# (standard value: 15)") DEFINITION (U"The maximum number of candidates that will be recruited.") TAG (U"##Maximum frequency (Hz)# (standard value: 1250 Hz)") DEFINITION (U"higher frequencies will not be considered.") TAG (U"##Max. number of subharmonics# (standard value: 15)") DEFINITION (U"the maximum number of harmonics that add up to the pitch.") TAG (U"##Compression factor# (standard value: 0.84)") DEFINITION (U"the factor by which successive compressed spectra are multiplied before the summation.") TAG (U"##Number of points per octave# (standard value: 48)") DEFINITION (U"determines the sampling of the logarithmic frequency scale.") TAG (U"##Ceiling (Hz)# (standard value: 500 Hz)") DEFINITION (U"candidates above this frequency will be ignored.") MAN_END MAN_BEGIN (U"Spectra: Multiply", U"djmw", 20100318) INTRO (U"Returns a new Spectrum object that is the product of the two selected " "@Spectrum objects.") MAN_END MAN_BEGIN (U"Spectrum: Conjugate", U"djmw", 20031023) INTRO (U"Reverses the sign of the complex part of the selected @Spectrum object(s).") NORMAL (U"For real signals, conjugation in the spectral domain amounts to time-inversion in the time domain.") MAN_END MAN_BEGIN (U"Spectrum: Shift frequencies...", U"djmw", 20121028) INTRO (U"Creates a new @Spectrum by shifting all frequencies of the selected Spectrum upwards or downwards.") ENTRY (U"Settings") TAG (U"##Shift by (Hz)") DEFINITION (U"a positive value shifts the spectrum towards higher frequencies, a negative value shifts the spectrum " "towards lower frequencies.") TAG (U"##New maximum frequency (Hz)") DEFINITION (U"the maximum frequency in the new Spectrum.") TAG (U"##Precision") DEFINITION (U"the number of neighbouring frequency points that are used in the calculation of the new frequency points. " "The precision relates linearly to the amount of computing time needed to get the new shifted spectrum.") MAN_END MAN_BEGIN (U"SpeechSynthesizer", U"djmw", 20120413) INTRO (U"The SpeechSynthesizer is one of the @@types of objects@ in Praat. It creates a speech sound from text. The actual text-to-speech synthesis is performed by the @@Espeak@ speech synthsizer and therefore our SpeechSynthsizer is merely an interface to Espeak.") ENTRY (U"Commands") NORMAL (U"Creation:") LIST_ITEM (U"\\bu @@Create SpeechSynthesizer...@") NORMAL (U"Playing:") LIST_ITEM (U"\\bu @@SpeechSynthesizer: Play text...|Play text...@") LIST_ITEM (U"\\bu @@SpeechSynthesizer: To Sound...|To Sound...@") NORMAL (U"Modification:") LIST_ITEM (U"\\bu @@SpeechSynthesizer: Set text input settings...|Set text input settings...@") LIST_ITEM (U"\\bu @@SpeechSynthesizer: Set speech output settings...|Set speech output settings...@") MAN_END MAN_BEGIN (U"Create SpeechSynthesizer...", U"djmw", 20120221) INTRO (U"Creates the @@Espeak@ speech synthesizer.") ENTRY (U"Settings") TAG (U"##Language#") DEFINITION (U"determines the language of the synthesizer.") TAG (U"##Voice variant#") DEFINITION (U"determines which voice type the synthesizer uses (male, female or whispered voices).") MAN_END MAN_BEGIN (U"SpeechSynthesizer: Play text...", U"djmw", 20120413) INTRO (U"The selected @@SpeechSynthesizer@ plays a text") ENTRY (U"Settings") TAG (U"##Text#") DEFINITION (U"is the text to be played. Text within [[ ]] is treated as phonemes codes in @@Kirshenbaum phonetic encoding@. For example, besides a text like \"This is text\", you might also input \"This [[Iz]] text\".") MAN_END MAN_BEGIN (U"SpeechSynthesizer: To Sound...", U"djmw", 20120414) INTRO (U"The selected @@SpeechSynthesizer@ converts a text to the corresponding speech sound.") ENTRY (U"Settings") TAG (U"##Text#") DEFINITION (U"is the text to be played. Text within [[ ]] is treated as phonemes codes in @@Kirshenbaum phonetic encoding@. For example, besides a text like \"This is text\", you might also input \"This [[Iz]] text\".") TAG (U"##Create TextGrid with annotations#") DEFINITION (U"determines whether, besides the sound, a TextGrid with multiple-tier annotations will appear.") MAN_END MAN_BEGIN (U"SpeechSynthesizer: Set text input settings...", U"djmw", 20120414) INTRO (U"A command available in the ##Modify# menu when you select a @@SpeechSynthesizer@.") ENTRY (U"Settings") TAG (U"##Input text format is#") DEFINITION (U"determines how the input text will be synthesized.") TAG (U"##Input phoneme codes are#") DEFINITION (U"") MAN_END MAN_BEGIN (U"SpeechSynthesizer: Set speech output settings...", U"djmw", 20120414) INTRO (U"A command available in the ##Modify# menu when you select a @@SpeechSynthesizer@.") ENTRY (U"Settings") TAG (U"##Sampling frequency#") DEFINITION (U"determines how the sampling frequency of the sound.") TAG (U"##Gap between words#") DEFINITION (U"determines the amount of silence between words.") TAG (U"##Pitch adjustment#") DEFINITION (U"") TAG (U"##Pitch range#") DEFINITION (U"") TAG (U"##Words per minute#") DEFINITION (U"determines the speaking rate in words per minute.") TAG (U"##estimate words per minute from data#") DEFINITION (U"") TAG (U"##Output phoneme codes are#") MAN_END MAN_BEGIN (U"SSCP", U"djmw", 19981103) INTRO (U"One of the @@types of objects@ in P\\s{RAAT}.") NORMAL (U"An object of type SSCP represents the sums of squares and cross products of " "a multivariate data set.") NORMAL (U"Besides the matrix part, an object of type SSCP also contains a " "vector with centroids.") ENTRY (U"Inside a SSCP") NORMAL (U"With @Inspect you will see that this type contains the same " "attributes as a @TableOfReal with the following extras:") TAG (U"%numberOfObservations") TAG (U"%centroid") MAN_END MAN_BEGIN (U"SSCP: Draw sigma ellipse...", U"djmw", 19990222) INTRO (U"A command to draw for the selected @SSCP an ellipse that " "covers a part of the multivariate data.") ENTRY (U"Setting") TAG (U"##Number of sigmas") DEFINITION (U"determines the @@concentration ellipse|data coverage@.") MAN_END MAN_BEGIN (U"SSCP: Get sigma ellipse area...", U"djmw", 20000525) INTRO (U"A command to query the selected @SSCP object for the area of a " "sigma ellipse.") ENTRY (U"Algorithm") NORMAL (U"The algorithm proceeds as follows:") LIST_ITEM (U"1. The four array elements in the SSCP-matrix that correspond to the chosen dimensions " "are copied into a two-dimensional matrix #%S (symmetric of course).") LIST_ITEM (U"2. The eigenvalues of #%S are determined, call them %s__1_ and %s__2_.") LIST_ITEM (U"3. The lengths %l__%i_ of the axes of the ellipse can be obtained as the " "square root of the %s__i_ multiplied by a scale factor: %l__%i_ = %scaleFactor \\.c " "\\Vr (%s__%i_ ), " "where %scaleFactor = %numberOfSigmas / \\Vr(%numberOfObservations \\-- 1).") LIST_ITEM (U"4. The area of the ellipse will be %\\pi\\.c%l__1_\\.c%l__2_.") MAN_END MAN_BEGIN (U"SSCP: Get confidence ellipse area...", U"djmw", 20000525) INTRO (U"A command to query the selected @SSCP object for the area of a " "confidence ellipse.") ENTRY (U"Algorithm") NORMAL (U"The algorithm proceeds as follows:") LIST_ITEM (U"1. The four array elements in the SSCP-matrix that correspond to the chosen dimensions " "are copied into a two-dimensional matrix #%S (symmetric of course).") LIST_ITEM (U"2. The eigenvalues of #%S are determined, call them %s__1_ and %s__2_.") LIST_ITEM (U"3. The lengths %l__1_ and %l__2_ of the two axes of the ellipse can be obtained as " "(see for example @@Johnson (1998)@, page 410): ") FORMULA (U" %l__%i_ = %scaleFactor \\.c \\Vr (%s__%i_ ),") LIST_ITEM (U" where") FORMULA (U"%scaleFactor = \\Vr (%f \\.c %p \\.c (%n \\-- 1) / (%n \\.c (%n \\-- %p))),") LIST_ITEM (U" in which %f = $$@@invFisherQ@$ (1 \\-- %confidenceLevel, %p, %n \\-- %p), " "where %p is the numberOfRows from the SSCP object and %n the %numberOfObservations.") LIST_ITEM (U"4. The area of the ellipse will be %\\pi\\.c%l__1_\\.c%l__2_.") MAN_END MAN_BEGIN (U"SSCP: Get diagonality (bartlett)...", U"djmw", 20011111) INTRO (U"Tests the hypothesis that the selected @SSCP matrix object is " "diagonal.") ENTRY (U"Setting") TAG (U"##Number of constraints") DEFINITION (U"modifies the number of independent observations. " "The default value is 1.") ENTRY (U"Algorithm") NORMAL (U"The test statistic is |#R|^^N/2^, the N/2-th power of the determinant" " of the correlation matrix. @@Bartlett (1954)@ developed the following " "approximation to the limiting distribution:") FORMULA (U"\\ci^2 = -(%N - %numberOfConstraints - (2%p + 5) /6) ln |#R|") NORMAL (U"In the formula's above, %p is the dimension of the correlation " "matrix, %N-%numberOfConstraints is the number of independent " "observations. Normally %numberOfConstraints would " "equal 1, however, if the matrix has been computed in some other way, " "e.g., from within-group sums of squares and cross-products of %k " "independent groups, %numberOfConstraints would equal %k.") NORMAL (U"We return the probability %\\al as ") FORMULA (U"%\\al = chiSquareQ (\\ci^2 , %p(%p-1)/2).") NORMAL (U"A very low %\\al indicates that it is very improbable that the " "matrix is diagonal.") MAN_END MAN_BEGIN (U"SSCP: Get fraction variation...", U"djmw", 20040210) INTRO (U"A command to ask the selected @SSCP object for the fraction " "of the total variation that is accounted for by the selected dimension(s).") NORMAL (U"Further details can be found in @@Covariance: Get fraction variance...@.") MAN_END MAN_BEGIN (U"SSCP: To CCA...", U"djmw", 20031103) INTRO (U"A command that creates a @@CCA|canonical correlation@ object from the " "selected @SSCP object.") ENTRY (U"Setting") TAG (U"##Dimension of dependent variate (ny)") DEFINITION (U"defines a partition of the square %n x %n SSCP matrix S into the parts S__yy_ of " "dimension %ny x %ny, S__xx_ of dimension %nx x %nx, and the parts " "S__xy_ and S__yx_ of dimensions %nx x %ny and %ny x %nx, respectively.") ENTRY (U"Algorithm") NORMAL (U"The partition for the square SSCP-matrix is as follows:") PICTURE (2.0, 2.0, drawPartionedMatrix) NORMAL (U"The canonical correlation equations we have to solve are:") FORMULA (U"(1) (#S__%yx_ #S__%xx_^^-1^ #S__%yx_\\'p -\\la #S__%yy_)#y = #0") FORMULA (U"(2) (#S__%yx_\\'p #S__%yy_^^-1^ #S__%yx_ -\\la #S__%xx_)#x = #0") NORMAL (U"where #S__%yy_ [%ny \\xx %ny] and #S__%xx_ [%nx \\xx %nx] are " "symmetric, positive definite matrices belonging to the dependent and the " "independent variables, respectively. ") NORMAL (U"These two equations are not independent and we will show that both " "equations have the same eigenvalues and that the eigenvectors #x for " "equation (2) can be obtained from the eigenvectors #y of equation (1).") NORMAL (U"We can solve equation (1) in several ways, however, the numerically " "stablest algorithm is probably by performing first a Cholesky decomposition " "of #S__xx_ and #S__yy_, followed by a @@generalized singular value " "decomposition@. The algorithm goes as follows:") NORMAL (U"The Cholesky decompositions (\"square roots\") of #S__yy_ and #S__xx_ are:") FORMULA (U"#S__yy_ = #U\\'p #U and #S__xx_ = #H\\'p #H,") NORMAL (U"where #U and H are upper triangular matrices. From these decompositions, " "the inverse for #S__xx_^^-1^ is easily computed. Let #K be the inverse of #H, " "then we can write: ") FORMULA (U"#S__xx_^^-1^ = #K #K\\'p.") NORMAL (U"We next substitute in equation (1) and rewrite as:") FORMULA (U"((#K\\'p#S__yx_\\'p)\\'p (#K\\'p#S__yx_\\'p) - \\la #U\\'p #U)#x = 0") NORMAL (U"This equation can be solved for eigenvalues and eigenvectors by the " "generalized singular value decomposition because it is of the form " "#A\\'p#A -\\la #B\\'p#B.") NORMAL (U"Now, given the solution for equation (1) we can find the solution " "for equation (2) by first multiplying (1) from the left with " "#S__yx_\\'p#S__yy_^^-1^, resulting in:") FORMULA (U"(#S__yx_\\'p#S__yy_^^-1^#S__yx_#S__xx_^^-1^#S__yx_\\'p -\\la #S__yx_\\'p) #y = 0") NORMAL (U"Now we split of the term #S__xx_^^-1^#S__yx_\\'p and obtain:") FORMULA (U"(#S__yx_\\'p#S__yy_^^-1^#S__yx_ - \\la #S__xx_) #S__xx_^^-1^#S__yx_\\'p #y = 0") NORMAL (U"This equation is like equation (2) and it has therefore the same eigenvalues " "and eigenvectors. (We also proved this fact in the algorithmic section of " "@@TableOfReal: To CCA...@.)") NORMAL (U"The eigenvectors #x is now") FORMULA (U"#x = #S__xx_^^-1^#S__yx_\\'p #y.") MAN_END MAN_BEGIN (U"SSCP: To Covariance...", U"djmw", 20090624) INTRO (U"A command that creates a @Covariance object from each selected @SSCP object.") ENTRY (U"Setting") TAG (U"##Number of constraints") DEFINITION (U"determines the factor by which each entry in the " "SSCP-matrix is scaled to obtain the Covariance matrix.") ENTRY (U"Details") NORMAL (U"The relation between the numbers %c__%ij_ in the covariance matrix and the numbers %s__%ij_ in " "the originating SSCP matrix is:") FORMULA (U"%c__%ij_ = %s__%ij_ / (%numberOfObservations - %numberOfConstraints)") NORMAL (U"Normally %numberOfConstraints will equal 1. However, when the SSCP was the " "result of summing %g SSCP objects, as is, for example, the case when you obtained the total " "within-groups SSCP from pooling the individual group SSCP's, %numberOfConstraints will equal the number of pooled SSCP's, %g.") MAN_END MAN_BEGIN (U"SSCP & TableOfReal: Extract quantile range...", U"djmw", 20040225) INTRO (U"Extract those rows from the selected @TableOfReal object whose Mahalanobis " "distance, with respect to the selected @SSCP object, are within the " "quantile range.") MAN_END MAN_BEGIN (U"T-test", U"djmw", 20020117) INTRO (U"A test on the mean of a normal variate when the variance is unknown.") NORMAL (U"In Praat, the t-test is used to query a @Covariance object and:") LIST_ITEM (U"1. get the significance of one mean. See @@Covariance: Get " "significance of one mean...@.") LIST_ITEM (U"2. get the significance of the %difference between two means. " "See @@Covariance: Get significance of means difference...@.") NORMAL (U"You should use a t-test when you want to test a hypothesis about " "the mean of one column in a @TableOfReal object, or, if you want to test " "a hypothesis about the difference between the means of two columns in " "this object.") NORMAL (U"You can perform these t-tests in Praat by first transforming the " "TableOfReal object into a Covariance object (see @@TableOfReal: To " "Covariance@) and then choosing the appropriate query method on the " "latter object.") MAN_END MAN_BEGIN (U"BHEP multivariate normality test", U"djmw", 20101124) INTRO (U"The Baringhaus–Henze–Epps–Pulley multivariate normality test.") NORMAL (U"According to @@Henze & Wagner (1997)@ the test has:") LIST_ITEM (U"\\bu affine invariance,") LIST_ITEM (U"\\bu consistency against each fixed nonnormal alternative distribution,") LIST_ITEM (U"\\bu asymptotic power against contiguous alternatives of order \\Vr (%n),") LIST_ITEM (U"\\bu feasibility for any dimension and any sample size.") NORMAL (U"The test depends on a smoothing parameter %%h% that can be chosen in various ways:") NORMAL (U"@@Henze & Wagner (1997)@ recommend %h = 1.41, while") NORMAL (U"@@Tenreiro (2009)@ recommends %h__%%s% _= 0.448 + 0.026\\.c%d for short tailed alternatives and " " %h__%%l%_ = 0.928 + 0.049\\.c%d for long tailed alternatives.") MAN_END MAN_BEGIN (U"Table: Normal probability plot...", U"djmw", 20130619) NORMAL (U"In a normal probability plot, the data in the selected column of the @Table are plotted " "against a normal distribution in such a way that the points should form approximately a straight line. " "Departures from a straight line indicate departures from normality.") ENTRY (U"Settings") TAG (U"##Number of quantiles#") DEFINITION (U"the number of quantile points, %n, in the plot. From this number %n, the quantile points are " "determined as follows: the last quantile point is %q__%n_ = 0.5^^1/%n^ and the first quantile point is " "%q__1_=1\\--%q__%n_. The intermediate quantile points %q__%i_ are determined according to " "%q__%i_=(%i \\-- 0.3175)/(%n + 0.365), where %i runs from 2 to %n\\--1.") TAG (U"##Number of sigmas#") DEFINITION (U"determines the horizontal and vertical drawing ranges in units of standard deviations. ") MAN_END MAN_BEGIN (U"Table: Quantile-quantile plot...", U"djmw", 20130619) NORMAL (U"In a quantile-quantile plot the quantiles of the data in the first selected column of the @Table are plotted against " "the quantiles of the data in the second selected column. If the two sets come from a population with the " "same distribution, the points should fall approximately along the reference line.") MAN_END MAN_BEGIN (U"Table: Bar plot where...", U"djmw", 20140509) INTRO (U"Draws a bar plot from data in one or more columns of the selected @Table. In a bar plot the horizontal axis has nominal values (labels). ") ENTRY (U"Settings") SCRIPT (6, Manual_SETTINGS_WINDOW_HEIGHT (10), U"" Manual_DRAW_SETTINGS_WINDOW ("Table: Bar plot where", 10) Manual_DRAW_SETTINGS_WINDOW_FIELD ("Vertical column(s)", "") Manual_DRAW_SETTINGS_WINDOW_RANGE("Vertical range", "0.0", "0.0 (=autoscaling)") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Column with labels", "") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Distance of first bar from border", "1.0") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Distance between bar groups", "1.0") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Distance between bars within group", "0.0") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Colours (0-1, name, {r,g,b})", "Grey") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Label text angle (degrees)", "0.0") Manual_DRAW_SETTINGS_WINDOW_BOOLEAN("Garnish", 1) Manual_DRAW_SETTINGS_WINDOW_TEXT("Formula:", "row>1 and row < 10") ) TAG (U"##Vertical column(s)") DEFINITION (U"you list the table columns that you want to represent in the bar plot. The number of selected columns is the group size.") TAG (U"##Vertical range") DEFINITION (U"determine the lower and upper limit of the display.") TAG (U"##Column with labels") DEFINITION (U"determines the column whose labels will be put at the bottom of the plot.") TAG (U"##Distance of first bar from border") DEFINITION (U"determines how far the first (and last) bar wil be positioned from the borders (in units of the width of one bar).") TAG (U"##Distance between bar groups") DEFINITION (U"determines how far groups of bars are from each other. ") TAG (U"##Distance between bars within group") DEFINITION (U"determines the distance between the bars within each group.") TAG (U"##Colours") DEFINITION (U"determines the colours of the bars in a group.") TAG (U"##Label text angle (degrees)") DEFINITION (U"determines the angle of the labels written below the plot. If you have very long label texts you can prevent the label texts from overlapping.") TAG (U"##Formula:") DEFINITION (U"can be used to supply an expression to select only those rows for plotting where the expression evaluates to %%true%. A 1 value always evaluates to %%true%.") ENTRY (U"Examples") NORMAL (U"@@Keating & Esposito (2006)@ present a bar plot in their fig. 3 from which we estimate the following data table") CODE (U"Language Modal Breathy") CODE (U"Chong -1.5 5") CODE (U"Fuzhou 2 10") CODE (U"Green Hmong 3 12") CODE (U"White Hmong 2 11") CODE (U"Mon -1.5 0") CODE (U"SADV Zapotec -6 -4") CODE (U"SLQ Zapotec 3.5 14") CODE (U"Tlacolula Zapotec 3 13") CODE (U"Tamang 1 1") CODE (U"!Xoo 1 14") NORMAL (U"Given that we have these data in a Table with the three columns labeled \"Language\", \"Modal\" and \"Breathy\", " "respectively, we can first try to reproduce their figure 3 (a bar plot with both Modal and Breathy columns displayed) ") NORMAL (U"As you can see the labels in the first column are very long texts and they will surely overlap if " "plotted at the bottom of a plot. We therefore use a value of 15 degrees for the \"Label text angle\" " "parameter. This " "will make the label texts nonoverlapping. We cannot make this angle much larger because then the label texts will run out of " "the viewport. ") NORMAL (U"Sometimes you need to plot only a part of the Table and for the selection of this part, the \"Formula\" field can be " "used. Since we only have a small table we put a \"1\" in this field which always evaluates to true. In effect, all the rows will be selected. The following script line will produce the picture below.") CODE (U"Bar plot where: \"Modal Breathy\", -10, 20, \"Language\", 1.0, 1.0, 0.0, \"0.9 0.5\", 15.0, \"yes\", \"1\"") SCRIPT (5, 3, U"h1h2 = Create H1H2 table (Esposito 2006)\n" "Font size: 10\n" "Bar plot where: \"Modal Breathy\", -10, 20, \"Language\", 1.0, 1.0, 0.0, \"0.9 0.5\", 15.0, \"yes\", \"1\"\n" "removeObject: h1h2\n") NORMAL (U"The essentials of the bart plot in their paper are perfectly reproduced in the figure above. If you want the bars within a group to be placed somewhat more apart say 0.2 (times the bar width) you can set the \"Distance between bars in a group\" to a value of 0.2:") CODE (U"Bar plot where: \"Modal Breathy\", -10, 20, \"Language\", 1.0, 1.0, 0.2, \"0.9 0.5\", 15.0, \"yes\", \"1\"") SCRIPT (5, 3, U"h1h2 = Create H1H2 table (Esposito 2006)\n" "Font size: 10\n" "Bar plot where: \"Modal Breathy\", -10, 20, \"Language\", 1.0, 1.0, 0.2, \"0.9 0.5\", 15.0, \"yes\", \"1\"\n" "removeObject: h1h2\n") NORMAL (U"Of course we can also work with colours and we can add vertical marks as the following sriptlet shows") CODE (U"Bar plot where: \"Modal Breathy\", -10, 20, \"Language\", 1.0, 1.0, 0.0, \"Green Red\", 15.0, \"yes\", \"1\"") CODE (U"Marks left every: 1, 5, 1, 1, 1") CODE (U"Text left: 1, \"H__1_-H__2_ (dB)\"") SCRIPT (5, 3, U"h1h2 = Create H1H2 table (Esposito 2006)\n" "Font size: 10\n" "Bar plot where: \"Modal Breathy\", -10, 20, \"Language\", 1.0, 1.0, 0.0, \"Green Red\", 15.0, \"yes\", \"1\"\n" "Marks left every: 1, 5, 1, 1, 1\n" "Text left: 1, \"H__1_-H__2_ (dB)\"\n" "removeObject: h1h2\n") MAN_END MAN_BEGIN (U"Table: Box plots where...", U"djmw", 20140509) INTRO (U"A command to draw @@box plot@s from the data in a column of the selected @Table object.") ENTRY (U"Example") NORMAL (U"To draw separate box plots for the male, female and children F0 for the @@Peterson & Barney (1952)@ data: ") CODE (U"Create formant table (Peterson & Barney 1952)") CODE (U"Box plots where: \"F0\", \"Type\", 70, 400, \"1\"") CODE (U"Text left: \"yes\", \"F0 (Hz)\"") SCRIPT (5,3, U"pb = Create formant table (Peterson & Barney 1952)\n" "Box plots where: \"F0\", \"Type\", 70, 400, \"yes\", \"1\"\n" "Text left: \"yes\", \"F0 (Hz)\"\n" "removeObject: pb\n" ) MAN_END MAN_BEGIN (U"Table: Line graph where...", U"djmw", 20140509) INTRO (U"Draws a line graph from the data in a column of the selected @Table. In a line plot the horizontal axis can have a nominal scale or a numeric scale. The data point are connected by line segments.") ENTRY (U"Settings") SCRIPT (7, Manual_SETTINGS_WINDOW_HEIGHT (8), U"" Manual_DRAW_SETTINGS_WINDOW ("Table: Line graph where", 8) Manual_DRAW_SETTINGS_WINDOW_FIELD ("Vertical column", "") Manual_DRAW_SETTINGS_WINDOW_RANGE ("Vertical range", "0.0", "0.0 (=autoscaling)") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Horizontal column", "") Manual_DRAW_SETTINGS_WINDOW_RANGE ("Horizontal range", "0.0", "0.0 (=autoscaling)") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Text", "+") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Label text angle (degrees)", "0.0") Manual_DRAW_SETTINGS_WINDOW_BOOLEAN("Garnish", 1) Manual_DRAW_SETTINGS_WINDOW_TEXT("Formula:", "1; (=everything)") ) TAG (U"##Vertical column") DEFINITION (U"The column whose data points you want to plot.") TAG (U"##Vertical range") DEFINITION (U"determine the lower and upper limits of the plot.") TAG (U"##Horizontal column") DEFINITION (U"determines the horizontal scale. If you leave it empty, or, if the (selected part of the) selected column contains nominal values, i.e. the values are not numeric but text, the horizontal " "distance between the data points will be constant (i.e. 1) and the nominal values (texts) will be put as labels at the bottom of the horizontal axis. " "On the other hand, if this column contains only numerical values, the horizontal position of the data points will be determined by the values in this column.") TAG (U"##Horizontal range") DEFINITION (U"determines the left and right limit of the plot.") TAG (U"##Text") DEFINITION (U"The text to put at the position of the data point in the plot.") TAG (U"##Label text angle (degrees)") DEFINITION (U"determines the angle of the labels written %%below% the plot. If you have very long label texts in the \"Horizontal column\", you can prevent the label texts from overlapping. This only has effect for a horizontal column with nominal values.") TAG (U"##Formula") DEFINITION (U"can be used to supply an expression to select only those rows for plotting where the expression evaluates to %%true%. A 1 value always evaluates to %%true%.") ENTRY (U"Examples") NORMAL (U"The following table was estimated from fig. 3 in @@Ganong (1980)@ and represents the fraction /d/ responses as a function of a " "voice onset time (VOT) continuum. The second column shows the responses in a word - nonword continuum, while the third column shows " "the responses to a nonword - word continuum.") CODE (U"VOT dash-tash dask-task") CODE (U"-17.5 0.98 0.92") CODE (U" -7.5 0.95 0.83") CODE (U" -2.5 0.71 0.33") CODE (U" 2.5 0.29 0.10") CODE (U" 7.5 0.12 0.02") CODE (U" 17.5 0.10 0.02") NORMAL (U"We can reproduce fig. 3 from Ganong (1980) with the following script, where we labeled the word - nonword curve with \"wn\" and the nonword - word curve with \"nw\". We deselect \"Garnish\" because we want to put special marks at the bottom.") CODE (U"Dotted line\n") CODE (U"Line graph where: \"dash-tash\", 0, 1, \"VOT\", -20, 20, \"wn\", 0, 0, \"1\"") CODE (U"Dashed line\n") CODE (U"Line graph where: \"dask-task\", 0, 1, \"VOT\", -20, 20, \"nw\", 0, 0, \"1\"") CODE (U"Draw inner box") CODE (U"One mark bottom: 2.5, 0, 1, 0, \"+2.5\"") CODE (U"One mark bottom: -2.5, 1, 1, 0, \"\"") CODE (U"One mark bottom: -7.5,1, 1, 0, \"\"") CODE (U"One mark bottom: 7.5, 0, 1, 0, \"+7.5\"") CODE (U"One mark bottom: 2.5, 0, 0, 0, \"+2.5\"") CODE (U"One mark bottom: -20, 0, 0, 0, \"Short VOT\"") CODE (U"One mark bottom: 20, 0, 0, 0, \"Long VOT\"") CODE (U"Text bottom: 1, \"VOT (ms)\"") CODE (U"Marks left every: 1, 0.2, 1, 1, 0") CODE (U"Text left: 1, \"Prop. of voiced responses\"") SCRIPT (5,3, U"ganong = Create Table (Ganong 1980)\n" "Dotted line\n" "Line graph where: \"dash-tash\", 0, 1, \"VOT\", -20, 20, \"wn\", 0, 0, \"1\"\n" "Dashed line\n" "Line graph where: \"dask-task\", 0, 1, \"VOT\", -20, 20, \"nw\", 0, 0, \"1\"\n" "Draw inner box\n" "One mark bottom: 2.5, 0, 1, 0, \"+2.5\"\n" "One mark bottom: -2.5, 1, 1, 0, \"\"\n" "One mark bottom: -7.5,1, 1, 0, \"\"\n" "One mark bottom: 7.5, 0, 1, 0, \"+7.5\"\n" "One mark bottom: 2.5, 0, 0, 0, \"+2.5\"\n" "One mark bottom: -20, 0, 0, 0, \"Short VOT\"\n" "One mark bottom: 20, 0, 0, 0, \"Long VOT\"\n" "Text bottom: 1, \"VOT (ms)\"\n" "Marks left every: 1, 0.2, 1, 1, 0\n" "Text left: 1, \"Prop. of voiced responses\"\n" "removeObject: ganong\n" ) NORMAL (U"As an example of what happens if you don't supply an argument for the \"Horizontal column\" we will use the same table as for the previous plot. However the resulting plot may not be as meaningful (note that the horizontal nominal scale makes all points equidistant in the horizontal direction.)") CODE (U"Dotted line\")\n") CODE (U"Line graph where: \"dash-tash\", 0, 1, \"\", 0, 0, \"wn\", 0, 1, \"1\"") CODE (U"One mark bottom: 1, 0, 1, 0, \"Short VOT\"") SCRIPT (5,3, U"ganong = Create Table (Ganong 1980)\n" "Dotted line\n" "Line graph where: \"dash-tash\", 0, 1, \"\", 0, 0, \"wn\", 0, 1, \"1\"\n" "One mark bottom: 1, 0, 1, 0, \"Short VOT\"\n" "removeObject: ganong\n" ) MAN_END MAN_BEGIN (U"Table: Horizontal error bars plot where...", U"djmw", 20131220) INTRO (U"Draws horizontal lines that represent the error intervals of a data column from the selected @@Table@.") NORMAL (U"This command behaves analogous to @@Table: Vertical error bars plot where...@.") MAN_END MAN_BEGIN (U"Table: Horizontal error bars plot...", U"djmw", 20131220) INTRO (U"Draws horizontal lines that represent the error intervals of a data column from the selected @@Table@.") NORMAL (U"This command behaves analogous to @@Table: Vertical error bars plot where...@.") MAN_END MAN_BEGIN (U"Table: Vertical error bars plot...", U"djmw", 20131223) INTRO (U"Draws vertical lines that represent the error intervals of a data column from the selected @@Table@.") NORMAL (U"For more info see @@Table: Vertical error bars plot where...@") MAN_END MAN_BEGIN (U"Table: Vertical error bars plot where...", U"djmw", 20131223) INTRO (U"Draws vertical lines that represent the error intervals of a data column from the selected @@Table@.") ENTRY (U"Settings") SCRIPT (6, Manual_SETTINGS_WINDOW_HEIGHT (9), U"" Manual_DRAW_SETTINGS_WINDOW ("Table: Vertical confidence intervals plot where", 9) Manual_DRAW_SETTINGS_WINDOW_FIELD ("Horizontal column", "") Manual_DRAW_SETTINGS_WINDOW_RANGE ("Horizontal range", "0.0", "0.0 (=autoscaling)") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Vertical column", "") Manual_DRAW_SETTINGS_WINDOW_RANGE ("Vertical range", "0.0", "0.0 (=autoscaling)") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Lower error value column", "") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Upper error value column", "") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Bar size (mm)", "1.0") Manual_DRAW_SETTINGS_WINDOW_BOOLEAN("Garnish", 1) Manual_DRAW_SETTINGS_WINDOW_TEXT("Formula", "1; (=everything)") ) TAG (U"##Horizontal column") DEFINITION (U"determines the data along the horizontal axis.") TAG (U"##Horizontal range") DEFINITION (U"determines the lower and upper limits of the plot.") TAG (U"##Vertical column") DEFINITION (U"determines the data along the horizontal axis.") TAG (U"##Vertical range") DEFINITION (U"determines the lower and upper limits of the plot.") TAG (U"##Lower error value column, Upper error value column") DEFINITION (U"determine the size of the vertical lines that will be drawn. These lines are drawn between the points (%x,%y-%low) and (%x, %y+%up), " "where %x and %y are the values from the %%horizontal column% and the %%vertical column%, respectively, and, %low and %up are the corresponding values " "in the %%lower error value column% and the %%upper error value column%, respectively. If either of these column names is not given the corresponding values (%low and/or %up) will taken as zero. This makes it possible to draw one-sided and two-sided error bars. If your " "errors are symmetric around the y-position, your table only needs one column and you can supply the name of this column in both fields.") TAG (U"##Bar size (mm)") DEFINITION (U"determines the width of the horizontal bars or whishers at the lower an postion of the drawn line. ") TAG (U"##Garnish") DEFINITION (U"determines whether or not some decoration is drawn.") TAG (U"##Formula") DEFINITION (U"can be used to supply an expression to select only those rows for plotting where the expression evaluates to %%true%. A 1 value always evaluates to %%true%.") MAN_END MAN_BEGIN (U"Table: Get median absolute deviation...", U"djmw", 20120405) INTRO (U"Get the median absolute deviation (MAD) of the column in the selected @@Table@ (adjusted by a scale factor).") ENTRY (U"Algorithm") NORMAL (U"From the %n numbers %x__1_, %x__2_, ..., %x__%n_ in the selected column we first calculate the @@quantile algorithm|median@ " "value %x__median_. Next we calculate the %n absolute deviations from this median: %d__1_, %d__2_, ..., %d__%n_, " "where %d__%j_=|%x__%j_ - %x__median_|. " "Then we calculate the MAD value, which is the median of the %n values %d__1_, %d__2_, ..., %d__%n_. Finally we multiply the MAD " "value by the scale factor 1.4826. This last multiplication makes the result comparable with the value of the standard deviation if " "the %x values are normally distributed.") MAN_END MAN_BEGIN (U"Table: Report one-way anova...", U"djmw", 20120617) INTRO (U"Performs a one-way analysis of variance on the data in one column of a selected @@Table@ and reports the fixed-effects anova table results in the info window.") ENTRY (U"Settings") TAG (U"##Column with data#") DEFINITION (U"the label of the column who's data will be analyzed.") TAG (U"##Factor") DEFINITION (U"the label of the column with the names of the levels.") TAG (U"##Table with means") DEFINITION (U"if checked, a Table with the mean values of the levels will be created.") TAG (U"##Table with differences between means") DEFINITION (U"if checked, a Table with the differences between the mean values of the levels will be created.") TAG (U"##Table with Tukey's post-hoc test") DEFINITION (U"if checked, a Table with Tukey's HSD tests will be created. Each value in this Table measures the probability that the corresponding difference between the level means happened by chance. The test compares all possible level means and is based on the studentized range distribution.") MAN_END MAN_BEGIN (U"Table: Report two-way anova...", U"djmw", 20140117) INTRO (U"Performs a two-way analysis of variance on the data in one column of a selected %%fully factorial% @@Table@ and reports the fixed-effects anova table in the info window. ") ENTRY (U"Settings") TAG (U"##Column with data#") DEFINITION (U"the label of the column who's data will be analyzed.") TAG (U"##First factor") DEFINITION (U"the label of the column with the names of the levels for the first factor.") TAG (U"##Second factor") DEFINITION (U"the label of the column with the names of the levels for the second factor.") TAG (U"##Table with means") DEFINITION (U"if checked, a Table with the mean values of all the levels will be created.") ENTRY (U"Example") NORMAL (U"Suppose you want to check if fundamental frequency depends on the type of vowel and speaker type. We will use the " "@@Create formant table (Peterson & Barney 1952)|Peterson & Barney@ vowel data set to illustrate this. " "The following script will first create the data set and then produce the two-way anova report." ) CODE (U"Create formant table (Peterson & Barney 1952)") CODE (U"Report two-way anova: \"F0\", \"Vowel\", \"Type\"") NORMAL (U"This will produce the following anova table in the info window:") CODE (U"Two-way analysis of \"F0\" by \"Vowel\" and \"Type\".") CODE (U"") CODE (U" Source SS Df MS F P") CODE (U" Vowel 73719.4 9 8191.05 7.62537 5.25258e-11") CODE (U" Type 4.18943e+06 2 2.09471e+06 1950.05 0") CODE (U"Vowel x Type 6714.34 18 373.019 0.347258 0.994969") CODE (U" Error 1.60053e+06 1490 1074.18") CODE (U" Total 5.87039e+06 1519") NORMAL (U"The analysis shows that F0 strongly depends on the vowel and also on the speaker type and, luckily, we do not have any " "interaction between the vowel and the speaker type. Besides the anova table there is also shown a table with the mean F0 " "values for each Vowel-Type combination which looks like:") CODE (U" c m w Mean") CODE (U" aa 258 124 212 198") CODE (U" ae 248 125 208 194") CODE (U" ah 263 129 223 205") CODE (U" ao 259 127 217 201") CODE (U" eh 259 128 220 202") CODE (U" er 264 133 219 205") CODE (U" ih 270 136 232 213") CODE (U" iy 270 136 231 212") CODE (U" uh 273 136 234 214") CODE (U" uw 278 139 235 218") CODE (U" Mean 264 131 223 206") NORMAL (U"The first column of this table shows the vowel codes while the first row shows the speaker types (child, man, women). " "The last row and the last column of the table shows the averages for the factors Type and Vowel, respectively. The actual " "data are unbalanced because we have 300, 660 and 560 replications per column respectively (for each speaker we have two replcations of the data).") ENTRY (U"Algorithm") NORMAL (U"The formula's to handle unbalanced designs come from @@Khuri (1998)@.") MAN_END MAN_BEGIN (U"Table: Report one-way Kruskal-Wallis...", U"djmw", 20120617) INTRO (U"Performs a one-way Kruskal-Wallis analysis on the data in one column of a selected @@Table@ and reports the results in the info window. This test is sometimes refered to as a one-way analysis of variance for %%non-normally distributed% data.") ENTRY (U"Settings") TAG (U"##Column with data#") DEFINITION (U"the label of the column who's data will be analyzed.") TAG (U"##Factor") DEFINITION (U"the label of the column with the names of the levels.") ENTRY (U"Algorithm") NORMAL (U"The analysis is done on the ranked data and consists of the following steps:") LIST_ITEM (U"1. Rank all the %N data points together, i.e. rank the data from 1 to %N.") LIST_ITEM (U"2. The test statistic is:") FORMULA (U"%K = (12 / (%N(%N+1)) \\Si__%i=1_^^%g^ %n__%i_ (meanRank__%i_)^^2^ - 3(%N+1),") DEFINITION (U"where %g is the number of levels, %n__%i_ the number of data in %i-th level and meanRank__%i_ " "the average rank of the %i-th level.") LIST_ITEM (U"3. The %p value is %%approximated by the \\ci^^2^ (%K, %g - 1) distribution.") MAN_END MAN_BEGIN (U"TableOfReal: Report multivariate normality (BHEP)...", U"djmw", 20090701) INTRO (U"Report about multivariate normality according to the @@BHEP multivariate normality test@.") ENTRY (U"Settings") TAG (U"##Smoothing parameter") DEFINITION (U"determines the smoothing parameter %h.") MAN_END MAN_BEGIN (U"TableOfReal: Change row labels...", U"djmw", 20010822) INTRO (U"Changes the row labels of the selected @TableOfReal object according " "to the specification in the search and replace fields.") NORMAL (U"Both search and replace fields may contain @@regular expressions|" "Regular expressions@. The ##Replace limit# parameter limits the number of " "replaces that may occur within each label.") MAN_END MAN_BEGIN (U"TableOfReal: Change column labels...", U"djmw", 20010822) INTRO (U"Changes the column labels of the selected @TableOfReal object according " "to the specification in the search and replace fields.") NORMAL (U"Both search and replace fields may contain @@regular expressions|" "Regular expressions@. The %%Replace limit% parameter limits the number of " "replaces that may occur within each label.") MAN_END MAN_BEGIN (U"TableOfReal: Draw biplot...", U"djmw", 20020603) INTRO (U"A command to draw a biplot for each column in the selected " "@TableOfReal object.") ENTRY (U"Settings") TAG (U"##Xmin#, ##Xmax#, ##Ymin#, ##Ymax#") DEFINITION (U"determine the drawing boundaries.") TAG (U"##Split factor") DEFINITION (U"determines the weighing of the row and column structure " "(see below).") ENTRY (U"Behaviour") LIST_ITEM (U"1. Get the @@singular value decomposition@ #U #\\Si #V\\'p of the " "table.") LIST_ITEM (U"2. Calculate weighing factors %\\la for row and columns") FORMULA (U"%\\la__r,1_ = %\\si__1_^^%splitFactor^") FORMULA (U"%\\la__c,1_ = %\\si__1_^^1-%splitFactor^") FORMULA (U"%\\la__r,2_ = %\\si__2_^^%splitFactor^") FORMULA (U"%\\la__c,2_ = %\\si__2_^^1-%splitFactor^") DEFINITION (U"where %\\si__1_ and %\\si__2_ are the first and the second singular values") LIST_ITEM (U"3. For the rows (%i from 1..%numberOfRows) form:") FORMULA (U"%xr__%i_ = %U__%i1_ %\\la__%r,1_") FORMULA (U"%yr__%i_ = %U__%i2_ %\\la__%r,2_") LIST_ITEM (U"4. For the columns (%i from 1..%numberOfColumns) form:") FORMULA (U"%xc__%i_ = %V__%i1_ %\\la__%c,1_") FORMULA (U"%yc__%i_ = %V__%i2_ %\\la__%c,2_") LIST_ITEM (U"5. Plot the points (%xr__%i_, yr__%i_) and (%xc__%i_, yc__%i_) in the " "same figure with the corresponding row and column labels.") MAN_END MAN_BEGIN (U"TableOfReal: Draw box plots...", U"djmw", 20000523) INTRO (U"A command to draw a @@box plot@ for each column in the selected " "@TableOfReal object.") ENTRY (U"Settings") TAG (U"##From row#, ##To row#, ##From column#, ##To column#") DEFINITION (U"determine the part of the table that you want to analyse.") TAG (U"%Ymin and %Ymax") DEFINITION (U"determine the drawing boundaries.") MAN_END MAN_BEGIN (U"TableOfReal: Draw rows as histogram...", U"djmw", 20030619) INTRO (U"A command to draw a histogram from the rows in the selected " "@TableOfReal object.") NORMAL (U"The histogram will consist of %groups of bars. The number of groups will " "be determined by the number of selected columns from the table, while the " "number of bars within each group will be determined from the number of " "selected rows.") ENTRY (U"Settings") TAG (U"##Row numbers# and ##Column range#") DEFINITION (U"determine the part of the table that you want to draw. " "The column range determines the number of bars that you want to draw for " "each row selected by the %%Row numbers% argument.") TAG (U"##Ymin# and ##Ymax#") DEFINITION (U"the drawing boundaries.") NORMAL (U"The following arguments are all relative to the width of a bar " "in the histogram. ") TAG (U"##Horizontal offset") DEFINITION (U"the offset from the left and right margin.") TAG (U"##Distance between bar groups") DEFINITION (U"the distance between each group, i.e., the distance " "between the right side of the last bar in a group to the left side of " "the first bar in the next group.") TAG (U"##Distance between bars") DEFINITION (U"the distance between the bars in a group.") TAG (U"##Grey values") DEFINITION (U"the grey values of the bars in a group.") ENTRY (U"Bar positioning") NORMAL (U"If you want to put the labels yourself you will need the following information.") NORMAL (U"The width of a bar is determined as follows:") FORMULA (U"%width = 1 / (%nc \\.c %nr + 2 \\.c %hoffset + (%nc - 1)\\.c %intergroup +" "%nc\\.c(%nr -1)\\.c %interbar),") NORMAL (U"where %nc is the number of columns (groups) to draw, %nr is the number of " "rows to draw (the number of bars within a group), %hoffset is the horizontal " "offset, %intergroup the distance between each group and %interbar " "the distance between the bars within a group.") NORMAL (U"The spacing between the bars drawn from a row:") FORMULA (U"%dx = (%intergroup + %nr + (%nr -1) \\.c %interbar) *% width") NORMAL (U"The first bar for the %k-th row starts at:") FORMULA (U"%x1 = %hoffset \\.c %width + (%k - 1) \\.c (1 + %interbar) \\.c %width") MAN_END MAN_BEGIN (U"TableOfReal: Select columns where row...", U"djmw", 20140117) INTRO (U"Copy columns from the selected @TableOfReal object to a new " "TableOfReal object.") ENTRY (U"Settings") TAG (U"##Columns") DEFINITION (U"defines the indices of the columns to be selected. Ranges can be " "defined with a colon \":\". Columns will be selected in the specified " "order.") TAG (U"##Row condition") DEFINITION (U"specifies a condition for the selection of rows. If the " "condition evaluates as %true for a particular row, the selected elements " "in this row will be copied. See @@Matrix: Formula...@ for the kind of " "expressions that can be used here.") ENTRY (U"Examples") CODE (U"Select columns where row: \"1 2 3\", \"1\"") CODE (U"Select columns where row: \"1 : 3\", \"1\"") NORMAL (U"Two alternative expressions to copy the first three columns to a new table " "with the same number of rows.") CODE (U"Select columns where row: \"3 : 1\", \"1\"") NORMAL (U"Copy the first three columns to a new table with the same number of " "rows. The new table will have the 3 columns reversed.") CODE (U"Select columns where row: \"1:6 9:11\", \"self[row,8]>0\"") NORMAL (U"Copy the first six columns and columns 9, 10, and 11 to a new table. " "Copy only elements from rows where the element in column 8 is greater " "than zero.") MAN_END MAN_BEGIN (U"TableOfReal: Standardize columns", U"djmw", 19990428) INTRO (U"Standardizes each column of the selected @TableOfReal.") NORMAL (U"The entries %x__%ij_ in the TableOfReal will change to:") FORMULA (U"(%x__%ij_ \\-- %\\mu__%j_) / %\\si__%j_, ") NORMAL (U"where %\\mu__%j_ and %\\si__%j_ are the mean and the standard deviation as calculated " "from the %j^^th^ column, respectively. After standardization all column means will equal zero " "and all column standard deviations will equal one.") MAN_END MAN_BEGIN (U"TableOfReal: To Configuration (lda)...", U"djmw", 19981103) INTRO (U"Calculates a @Configuration based on the @Discriminant scores obtained " "from the selected @TableOfReal. Row labels in the table indicate group membership.") ENTRY (U"Setting") TAG (U"##Number of dimensions") DEFINITION (U"determines the number of dimensions of the resulting Configuration.") ENTRY (U"Algorithm") NORMAL (U"First we calculate the Discriminant from the data in the TableOfReal. " "See @@TableOfReal: To Discriminant@ for details.") NORMAL (U"The eigenvectors of the Discriminant determine the directions that " "the data in the TableOfReal will be projected unto.") MAN_END MAN_BEGIN (U"TableOfReal: To Configuration (pca)...", U"djmw", 19980909) INTRO (U"Calculates a @Configuration based on the principal components from the " "selected @TableOfReal.") ENTRY (U"Setting") TAG (U"##Number of dimensions") DEFINITION (U"determines the number of dimensions of the resulting Configuration.") ENTRY (U"Algorithm") NORMAL (U"We form principal components without explicitly calculating the covariance matrix " "#C = #M\\'p\\.c#M, where #M is the matrix part of the TableOfReal. ") LIST_ITEM (U"1. Make the singular value decomposition of #M. This results in " "#M = #U\\.c#d\\.c#V\\'p.") LIST_ITEM (U"2. Sort singular values #d and corresponding row vectors in #V (descending).") LIST_ITEM (U"3. The principalComponent__%ij_ = \\su__%k=1..%numberOfColumns_ %M__%ik_ \\.c %V__%jk_.") ENTRY (U"Remark") NORMAL (U"The resulting configuration is unique up to reflections along the new principal directions.") MAN_END MAN_BEGIN (U"TableOfReal: To Correlation", U"djmw", 20020105) INTRO (U"A command that creates a (%Pearson) @Correlation object from every " "selected @TableOfReal object. The correlations are calculated between " "columns.") ENTRY (U"Algorithm") NORMAL (U"The linear correlation coefficient %r__%ij_ (also called the %%product" " moment correlation coefficient% or %%Pearson's correlation coefficient%) " " between the elements of columns %i and %j is calculated as:") FORMULA (U"%r__%ij_ = \\Si__%k_ (%x__%ki_ - %mean__%i_)(%x__%kj_ - %mean__%j_)/" "(\\Vr (\\Si__%k_(%x__%ki_ - %mean__%i_)^2) \\Vr (\\Si__%k_(%x__%kj_ -" " %mean__%j_)^2)),") NORMAL (U"where %x__%mn_ is the element %m in column %n, and %mean__%n_ " "is the mean of column %n.") MAN_END MAN_BEGIN (U"TableOfReal: To Correlation (rank)", U"djmw", 20020105) INTRO (U"A command that creates a (%%Spearman rank-order%) @Correlation object " "from every selected @TableOfReal object. The correlations are calculated " "between columns.") ENTRY (U"Algorithm") NORMAL (U"The Spearman rank-order correlation coefficient %r__%ij_ between " "the elements of columns %i and %j is calculated as the linear correlation" " of the ranks:") FORMULA (U"%r__%ij_ = \\Si__%k_ (%R__%ki_ - %Rmean__%i_) " "(%R__%kj_ - %Rmean__%j_) / (\\Vr (\\Si__%k_(%R__%ki_ - %Rmean__%i_)^2) " "\\Vr (\\Si__%k_(%R__%kj_ - %Rmean__%j_)^2)),") NORMAL (U"where %R__%mn_ is the rank of element %m in column %n, " "and %Rmean__%n_ is the mean of the ranks in column %n.") MAN_END MAN_BEGIN (U"TableOfReal: To Covariance", U"djmw", 20020117) INTRO (U"A command that creates a @Covariance object from every " "selected @TableOfReal object. The covariances are calculated between " "columns.") ENTRY (U"Algorithm") NORMAL (U"The covariance coefficients %s__%ij_ " " between the elements of columns %i and %j are defined as:") FORMULA (U"%s__%ij_ = \\Si__%k_ (%x__%ki_ - %mean__%i_)(%x__%kj_ - %mean__%j_)/" "(%numberOfObservations - %numberOfConstraints),") NORMAL (U"where %x__%ki_ is the element %k in column %i, %mean__%i_ " "is the mean of column %i, %numberOfObservations equals the number of rows in " "the table, and %numberOfConstraints equals 1.") NORMAL (U"The actual calculation goes as follows") LIST_ITEM (U"1. Centralize each column (subtract the mean).") LIST_ITEM (U"2. Get its @@singular value decomposition@ #U #\\Si #V\\'p.") LIST_ITEM (U"3. Form #S = #V #\\Si #V\\'p.") LIST_ITEM (U"4. Divide all elements in #S by (%numberOfObservations - 1).") MAN_END MAN_BEGIN (U"TableOfReal: To Discriminant", U"djmw", 19990104) INTRO (U"A command that creates a @Discriminant object from every selected " "@TableOfReal object. Row labels in the table indicate group membership.") ENTRY (U"Algorithm") NORMAL (U"We solve for directions #x that are eigenvectors of the generalized " "eigenvalue equation:") FORMULA (U"#%B #x - %\\la #%W #x = 0,") NORMAL (U"where #%B and #%W are the between-groups and the within-groups sums of " "squares and cross-products matrices, respectively. Both #%B and #%W are symmetric " "matrices. Standard formula show that both matrices can also " "be written as a matrix product. The formula above then transforms to:") FORMULA (U"#%B__1_\\'p#%B__1_ #x - %\\la #%W__1_\\'p#%W__1_ #x = 0") NORMAL (U"The equation can be solved with the @@generalized singular value decomposition@. " "This procedure is numerically very stable and can even cope with cases when both " "matrices are singular.") NORMAL (U"The a priori probabilities in the Discriminant will be calculated from the number of " "%training vectors %n__%i_ in each group:") FORMULA (U"%aprioriProbability__%i_ = %n__%i_ / \\Si__%k=1..%numberOfGroups_ %n__%k_") MAN_END MAN_BEGIN (U"TableOfReal: To PCA", U"djmw", 19980106) INTRO (U"A command that creates a @PCA object from every selected " "@TableOfReal object.") MAN_END MAN_BEGIN (U"TableOfReal: To SSCP...", U"djmw", 19990218) INTRO (U"Calculates Sums of Squares and Cross Products (@SSCP) from the selected @TableOfReal.") ENTRY (U"Algorithm") NORMAL (U"The sums of squares and cross products %s__%ij_ " " between the elements of columns %i and %j are calculated as:") FORMULA (U"%s__%ij_ = \\Si__%k_ (%x__%ki_ - %mean__%i_)(%x__%kj_ - %mean__%j_),") NORMAL (U"where %x__%mn_ is the element %m in column %n and %mean__%n_ " "is the mean of column %n.") MAN_END MAN_BEGIN (U"TableOfReal: To Pattern and Categories...", U"djmw", 20040429) INTRO (U"Extracts a @Pattern and a @Categories from the selected @TableOfReal.") NORMAL (U"The selected rows and columns are copied into the Pattern and " "the corresponding row labels are copied into a Categories. ") MAN_END MAN_BEGIN (U"TableOfReal: To CCA...", U"djmw", 20020424) INTRO (U"A command that creates a @CCA object from the selected " "@TableOfReal object.") ENTRY (U"Settings") TAG (U"%%Dimension of dependent variate (ny)") DEFINITION (U"defines the partition of the table into the two parts whose " "correlations will be determined. The first %ny columns must be the " "dependent part, the rest of the columns will be interpreted as the " "independent part (%nx columns). In general %nx must be larger than or " "equal to %ny.") ENTRY (U"Behaviour") NORMAL (U"Calculates canonical correlations between the %dependent and the " "%independent parts of the table. The corresponding " "canonical coefficients are also determined.") ENTRY (U"Algorithm") NORMAL (U"The canonical correlation equations for two data sets #T__%y_ " "[%n \\xx %p] and #T__%x_ [n \\xx %q] are:") FORMULA (U"(1) (#S__%yx_ #S__%xx_^^-1^ #S__%yx_\\'p -\\la #S__%yy_)#y = #0") FORMULA (U"(2) (#S__%yx_\\'p #S__%yy_^^-1^ #S__%yx_ -\\la #S__%xx_)#x = #0") NORMAL (U"where #S__%yy_ [%p \\xx %p] and #S__%xx_ [%q \\xx %q] are the " "covariance matrices of data sets #T__%y_ and #T__%x_, respectively, " "#S__%yx_ [%p \\xx %q] is the matrix of covariances between data sets " "#T__%y_ and #T__%x_, and the vectors #y and #x are the %%canonical " "weights% or the %%canonical function coefficients% for the dependent and " "the independent data, respectively. " "In terms of the (dependent) data set #T__%y_ and the (independent) data set " "#T__%x_, these covariances can be written as:") FORMULA (U"#S__%yy_ = #T__%y_\\'p #T__%y_, #S__%yx_ = #T__%y_\\'p #T__%x_ and " "#S__%xx_ = #T__%x_\\'p #T__%x_.") NORMAL (U"The following @@singular value decomposition@s ") FORMULA (U"#T__%y_ = #U__%y_ #D__%y_ #V__%y_\\'p and #T__%x_ = #U__%x_ #D__%x_ " "#V__%x_\\'p ") NORMAL (U"transform equation (1) above into:") FORMULA (U"(3) (#V__%y_ #D__%y_ #U__%y_\\'p#U__%x_ #U__%x_\\'p #U__%y_ #D__%y_ " "#V__%y_\\'p - \\la #V__%y_ #D__%y_ #D__%y_ #V__%y_\\'p)#y = 0 ") NORMAL (U"where we used the fact that:") FORMULA (U"#S__%xx_^^-1^ = #V__%x_ #D__%x_^^-2^ #V__%x_\\'p.") NORMAL (U"Equation (3) can be simplified by multiplication from the left by " "#D__%y_^^-1^ #V__%y_' to:") FORMULA (U" (4) ((#U__%x_\\'p #U__%y_)\\'p (#U__%x_\\'p #U__%y_) - \\la #I)#D__%y_ " "#V__%y_\\'p #y = #0") NORMAL (U"This equation can, finally, be solved by a substitution of the s.v.d " "of #U__%x_\\'p #U__%y_ = #U #D #V\\'p into (4). This results in") FORMULA (U"(5) (#D^^2^ - \\la #I) #V\\'p #D__%y_ #V__%y_\\'p #y = #0") NORMAL (U"In an analogous way we can reduce eigenequation (2) to:") FORMULA (U"(6) (#D^^2^ - \\la #I) #U\\'p #D__%x_ #V__%x_\\'p #x = #0") NORMAL (U"From (5) and (6) we deduce that the eigenvalues in both equations " "are equal to the squared singular values of the product matrix " "#U__%x_\\'p#U__%y_. " "These singular values are also called %%canonical " "correlation coefficients%. The eigenvectors #y and #x can be obtained " "from the columns of the following matrices #Y and #X:") FORMULA (U"#Y = #V__%y_ #D__%y_^^-1^ #V") FORMULA (U"#X = #V__%x_ #D__%x_^^-1^ #U") NORMAL (U"For example, when the vector #y equals the first column of #Y and " "the vector #x equals " "the first column of #X, then the vectors #u = #T__%y_#y and #v = #T__%x_#x " "are the linear combinations from #T__%y_ and #T__%x_ that have maximum " "correlation. Their correlation coefficient equals the first canonical " "correlation coefficient.") MAN_END MAN_BEGIN (U"TableOfReal: To TableOfReal (means by row labels)...", U"djmw", 20140117) INTRO (U"A command that appears in the ##Multivariate statistics# menu if you select a @@TableOfReal@. " "It calculates the multivariate means for the different row labels from the selected TableOfReal.") ENTRY (U"Setting") TAG (U"##Expand") DEFINITION (U"when %off, then for a table with %n rows and %m different labels (%m\\<_%n), the resulting table will have %m rows. " "When %on, the dimensions of the resulting table will be the same as the originating, and corresponding means substituded " "in each row.") ENTRY (U"Example") NORMAL (U"The following commands") CODE (U"@@Create TableOfReal (Pols 1973)...|Create TableOfReal (Pols 1973)@: \"no\"") CODE (U"To TableOfReal (means by row labels): 0") NORMAL (U"will result in a new TableOfReal that has 12 rows. Each row will contain the mean F1, F2 and F3 values for a particular vowel. These means " " were obtained from 50 representations of that vowel.") NORMAL (U"If we had chosen the %expansion:") CODE (U"To TableOfReal (means by row labels): \"yes\"") NORMAL (U"the resulting TableOfReal would have had 600 rows. This representation comes in handy when, for example, you have to calculate deviations from the mean.") MAN_END MAN_BEGIN (U"TextGrid: Extend time...", U"djmw", 20020702) INTRO (U"Extends the domain of the selected @TextGrid object.") ENTRY (U"Settings") TAG (U"##Extend domain by") DEFINITION (U"defines the amount of time by which the domain will be extended.") TAG (U"##At") DEFINITION (U"defines whether starting times or finishing times will be " "modified.") ENTRY (U"Behaviour") NORMAL (U"We add an extra (empty) interval into each %%interval tier%. " "This is necessary to keep original intervals intact. According to the " "value of the second argument, the new interval will be added at the " "beginning or at the end of the tier.") NORMAL (U"For %%point tiers% only the domain will be changed.") MAN_END MAN_BEGIN (U"TIMIT acoustic-phonetic speech corpus", U"djmw", 19970320) INTRO (U"A large American-English speech corpus that resulted from the joint efforts " "of several American research sites.") NORMAL (U"The TIMIT corpus contains a total of 6300 sentences, 10 sentences spoken by " "630 speakers selected from 8 major dialect regions of the USA. 70\\% of " "the speakers are male, 30\\% are female.") NORMAL (U"The text corpus design was done by the Massachusetts Institute of " "Technology (MIT), Stanford Research Institute and Texas Instruments (TI). " "The speech was recorded at TI, transcribed at MIT, and has been maintained, " "verified and prepared for CDROM production by the American National Institute " "of Standards and Technology (NIST) (@@Lamel et al. (1986)@).") MAN_END MAN_BEGIN (U"VowelEditor", U"djmw", 20111124) INTRO (U"An Editor for generating vowel-like @@sound|Sound@s from mouse movements.") ENTRY (U"How to get a sound") NORMAL (U"With the mouse button down, you can move the mouse cursor around in the plane " "spanned by the first two formants. While you move the cursor around, the positions you trace will be " "indicated by blue dots. After you release the mouse button, the color of the trajectory will change " "to black. Next you will hear the vowel-like sound whose " "first two formants follow this trajectory. (The small bars on the trajectory are time markers. With " "default settings, time markers are at 50 milliseconds apart and they may give you an indication of the speed by which you traversed the trajectory.)") ENTRY (U"The interface") NORMAL (U"In the lower part of the editor a number of buttons and fields are displayed.") TAG (U"##Play") DEFINITION (U"will play the trajectory.") TAG (U"##Reverse") DEFINITION (U"will reverse the trajectory and play it.") TAG (U"##Publish") DEFINITION (U"will publish the sound in the list of objects.") TAG (U"##Duration (s)") DEFINITION (U"allows to modify the duration of the current trajectory. ") TAG (U"##Extend (s)") DEFINITION (U"determines the duration of the straight line trajectory that connects the endpoint of the current trajectory with the startpoint of a new trajectory. You may extend the current trajectory by starting a new trajectory with the shift button pressed. After you finished the new trajectory, three trajectories will be appended: the current one, the straight line one and the new one.") TAG (U"##Start F0 (Hz)") DEFINITION (U"determines the fundamental frequency at the start of the trajectory.") TAG (U"##F0 slope (oct/s)") DEFINITION (U"determines how many octaves the pitch will changes during the course of the trajectory.") NORMAL (U"The bottom line in the Editor displays the first and second formant frequency and the fundamental frequency at the start point and the endpoint of the trajectory.") ENTRY (U"Edit menu") TAG (U"##Set F0...") DEFINITION (U"Set pitch and slope.") TAG (U"##Set F3 & F4...") DEFINITION (U"Set the frequencies and bandwidths for the third and fourth formant.") TAG (U"##Reverse trajectory") DEFINITION (U"Reverses the trajectory (like editor button).") // ?? TAG (U"##Modify trajectory duration...") DEFINITION (U"Modifies trajectory duration (like editor field).") // ?? TAG (U"##New trajectory...") DEFINITION (U"Set startpoint, endpoint and duration of a new trajectory.") TAG (U"##Extend trajectory...") DEFINITION (U"Extend current trajectory to...") TAG (U"##Shift trajectory...") DEFINITION (U"Shift current trajectory.") ENTRY (U"View menu") TAG (U"##F1 & F2 range...#") DEFINITION (U"Modify the horizontal and vertical scales.") TAG (U"##Show vowel marks from fixed set...#") DEFINITION (U"Show the vowel marks in the editor from a fixed set of vowel inventories.") TAG (U"##Show vowel marks from Table file...#") DEFINITION (U"Put your own marks in the editor. The Table needs to have at least three mandatory columns " "labeled \"Vowel\", \"F1\" and \"F2\" and " "one optional column labeled \"Size\". The Vowel column contains the vowel marker labels, the F1 and " "F2 columns have the first and second formant frequencies in Hertz. The optional Size column contains " "the font size of the vowel markers.") TAG (U"##Show trajectory time markers every...") DEFINITION (U"Shows time markers as small bars orthogonal to the trajectory. ") ENTRY (U"Publishing") TAG (U"##Publish Sound") TAG (U"##Extract FormantTier") TAG (U"##Extract PitchTier") DEFINITION (U"Publish the Sound, the PitchTier and the FormantTier from the trajectory.") TAG (U"##Draw trajectory...") DEFINITION (U"Draws the trajectory in the picture window") MAN_END MAN_BEGIN (U"VowelEditor: Show vowel marks from Table file...", U"djmw", 20111124) INTRO (U"A command in the @@VowelEditor@ that lets you set your own vowel marks. ") ENTRY (U"Layout of the Table") NORMAL (U"The Table needs at least three mandatory columns labeled \"Vowel\", \"F1\" and \"F2\" and " "one optional column labeled \"Size\". The Vowel column contains the vowel marker labels, the F1 and " "F2 columns have the first and second formant frequencies in Hertz. The optional Size column contains " "the font size of the vowel markers.") MAN_END /********************** GSL ********************************************/ MAN_BEGIN (U"incompleteBeta", U"djmw", 20071024) TAG (U"##incompleteBeta (%a, %b, %x)") DEFINITION (U"I__x_(%a,%b) = 1/beta(%a,%b)\\in__0_^%x %t^^%a-1^(1-%t)^^%b-1^ dt,") NORMAL (U"for 0 \\<_ %x \\<_ 1 and %a and %b and %a+%b not equal to a negative integer.") //double incompleteBeta (double a, double b, double x); //Pre: 0<= x <= 1; a> 0, b>0 //Def: $I_x(a,b)=B_x(a,b)/B(a,b)=1/B(a,b) \int_0^x t^{a-1}(1-t)^{b-1)dt$ //Limiting values: $I_0(a,b)=0 I_1(a,b)=1$ //Symmetry: $I_x(a,b) = 1 - I_{1-x}(b,a)$ MAN_END MAN_BEGIN (U"incompleteGammaP", U"djmw", 20071024) TAG (U"##incompleteGammaP (%a, %x)") DEFINITION (U"incompleteGammaP = 1/\\Ga(%a)\\in__0_^%x e^^-%t^%t^^%a-1^ dt,") NORMAL (U"For %x\\>_ 0 and %a not a negative integer.") MAN_END MAN_BEGIN (U"lnBeta", U"djmw", 20071024) TAG (U"##lnBeta (%a, %b)") DEFINITION (U"Computes the logarithm of the #beta function, subject to %a and %b and %a+%b not being negative integers.") MAN_END /********************* References **************************************/ MAN_BEGIN (U"Bai & Demmel (1993)", U"djmw", 19981007) NORMAL (U"Z. Bai & J. Demmel (1993): \"Computing the generalized singular value " "decomposition.\" %%SIAM J. Sci. Comput.% #14: 1464\\--1486.") MAN_END MAN_BEGIN (U"Bartlett (1954)", U"djmw", 20011111) NORMAL (U"M.S. Bartlett (1954): \"A note on multiplying factors for various " "chi-squared approximations.\", %%Joural of the Royal Statistical Society, " "Series B% #16: 296\\--298") MAN_END MAN_BEGIN (U"Boll (1979)", U"djmw", 20121021) NORMAL (U"S.F. Boll (1979): \"Suppression of acoustic noise in speech using spectral subtraction.\"" "%%IEEE Transactions on ASSP% #27: 113\\--120.") MAN_END MAN_BEGIN (U"Boomsma (1977)", U"djmw", 20020524) NORMAL (U"A. Boomsma (1977): \"Comparing approximations of confidence intervals " "for the product-moment correlation coefficient.\" %%Statistica Neerlandica% " "#31: 179-186.") MAN_END MAN_BEGIN (U"Cooley & Lohnes (1971)", U"djmw", 20060322) NORMAL (U"W.W. Colley & P.R. Lohnes (1971): %%Multivariate data analysis%. " "John Wiley & Sons.") MAN_END MAN_BEGIN (U"Davis & Mermelstein (1980)", U"djmw", 20010419) NORMAL (U"S.B. Davis & P. Mermelstein (1980), \"Comparison of parametric " "representations for monosyllabic word recognition in continuously " "spoken sentences.\" " "%%IEEE Transactions on ASSP% #28: 357\\--366.") MAN_END MAN_BEGIN (U"Efron & Tibshirani (1993)", U"djmw", 20031103) NORMAL (U"B. Efron & R.J. Tibshirani (1993): %%An introduction " "to the bootstrap%. Chapman & Hall.") MAN_END MAN_BEGIN (U"Espeak", U"djmw", 20111217) NORMAL (U"Jonathan Duddington's Espeak speech synthesizer, available via http://espeak.sourceforge.net/") MAN_END MAN_BEGIN (U"Flanagan (1960)", U"djmw", 19980713) NORMAL (U"J.L. Flanagan (1960): \"Models for approximating basilar membrane " "displacement.\" %%Bell System Technical Journal% #39: 1163\\--1191.") MAN_END MAN_BEGIN (U"Friedl (1997)", U"djmw", 20010710) NORMAL (U"J.E.F. Friedl (1997): %%Mastering Regular Expressions%. " "O'Reilly & Associates.") MAN_END MAN_BEGIN (U"Ganong (1980)", U"djmw", 20130622) NORMAL (U"W.F. Ganong III (1980): \"Phonetic categorization in auditory word perception.\" %%Journal of Experimental Psychology: Human Perception and Performance% #6: 110\\--125.") MAN_END MAN_BEGIN (U"Greiner & Hormann (1998)", U"djmw", 20110617) NORMAL (U"G. Greiner & K. Hormann (1998): \"Efficient clipping of arbitrary polygons.\" %%ACM Transactions on Graphics% #17: 71\\--83.") MAN_END MAN_BEGIN (U"Heath et al. (1986)", U"djmw", 19981007) NORMAL (U"M.T. Heath, J.A. Laub, C.C. Paige & R.C. Ward (1986): \"Computing the " "singular value decomposition of a product of two matrices.\" " "%%SIAM J. Sci. Statist. Comput.% #7: 1147\\--1159.") MAN_END MAN_BEGIN (U"Hermes (1988)", U"djmw", 19980123) NORMAL (U"D.J. Hermes (1988): \"Measurement of pitch by subharmonic " "summation.\" %%Journal of the Acoustical Society of America% #83: 257\\--264.") MAN_END MAN_BEGIN (U"Henze & Wagner (1997)", U"djmw", 20090630) NORMAL (U"N. Henze & T. Wagner (1997): \"A new npproach to the BHEP Tests for Multivariate Normality.\" " "%%Journal of Multivariate Analysis% #62: 1\\--23.") MAN_END MAN_BEGIN (U"Hormann & Agathos (2001)", U"djmw", 20110617) NORMAL (U"K. Hormann & A. Agathos (2001): \"The point in polygon problem for arbitrary polygons.\" " "%%Computational Geometry% #20: 131\\--144.") MAN_END MAN_BEGIN (U"Irino & Patterson (1997)", U"djmw", 20100517) NORMAL (U"T. Irino & R.D. Patterson (1997): \"A time-domain, level-dependent " "auditory filter: The gammachirp.\" %%Journal of the Acoustical Society of America% #101: 412\\--419.") MAN_END MAN_BEGIN (U"Johannesma (1972)", U"djmw", 19980123) NORMAL (U"P.I.M. Johannesma (1972): \"The pre-response stimulus ensemble of " "neurons in the cochlear nucleus.\" In %%Symposium on Hearing Theory% " "(IPO, Eindhoven, Holland), 58\\--69.") MAN_END MAN_BEGIN (U"Johnson (1998)", U"djmw", 20000525) NORMAL (U"D.E. Johnson (1998): %%Applied Multivariate methods%.") MAN_END MAN_BEGIN (U"Keating & Esposito (2006)", U"djmw", 20130620) NORMAL (U"P.A. Keating & C. Esposito (2006): \"Linguistic voice quality.\" %%UCLA Working Papers in Phonetics% #105: 85\\--91.") MAN_END MAN_BEGIN (U"Khuri (1998)", U"djmw", 20120702) NORMAL (U"A. Khuri (1998): \"Unweighted sums of squares in unbalanced analysis of variance.\", %%Journal of Statistical Planning " "and Inference% #74: 135\\--147.") MAN_END MAN_BEGIN (U"Kim & Kim (2006)", U"djmw", 20110617) NORMAL (U"D.H. Kim & M.-J. Kim (2006): \"An extension of polygon clipping to resolve degenerate cases.\" %%Computer-Aided Design & Applications% #3: 447\\--456.") MAN_END MAN_BEGIN (U"Krishnamoorthy & Yu (2004)", U"djmw", 20090813) NORMAL (U"K. Krishnamoortht & J. Yu (2004): \"Modified Nel and Van der Merwe test for multivariate " "Behrens-Fisher problem.\" %%Statistics & Probability Letters% #66: 161\\--169.") MAN_END MAN_BEGIN (U"Lamel et al. (1986)", U"djmw", 19980123) NORMAL (U"L.F. Lamel, R.H. Kassel & S. Sennef (1986): \"Speech Database " "Development: Design and Analysis of the Acoustic-Phonetic Corpus.\" " "%%Proc. DARPA Speech Recognition Workshop%, Report No. SAIC-86/1546, " "100\\--119.") MAN_END MAN_BEGIN (U"Morrison (1990)", U"djmw", 19980123) NORMAL (U"D.F. Morrison (1990): %%Multivariate Statistical Methods%. " "New York: McGraw-Hill.") MAN_END MAN_BEGIN (U"Peterson & Barney (1952)", U"djmw", 20020620) NORMAL (U"G.E. Peterson & H.L. Barney (1952): \"Control methods used in a study " "of the vowels.\" %%Journal of the Acoustical Society of America% #24: 175\\--184") MAN_END MAN_BEGIN (U"Pols et al. (1973)", U"djmw", 19990426) NORMAL (U"L.C.W. Pols, H.R.C. Tromp & R. Plomp (1973): " "\"Frequency analysis of Dutch vowels from 50 male speakers.\" " "%%Journal of the Acoustical Society of America% #53: 1093\\--1101.") MAN_END MAN_BEGIN (U"Press et al. (1992)", U"djmw", 19980114) NORMAL (U"W.H. Press, S.A. Teukolsky, W.T. Vetterling & B.P. Flannery (1992): " "%%Numerical recipes in C: The art of scientific computing%. " "Second Edition. Cambridge University Press.") MAN_END MAN_BEGIN (U"Sakoe & Chiba (1978)", U"djmw", 20050302) NORMAL (U"H. Sakoe & S. Chiba (1978): \"Dynamic programming algorithm optimization for spoken word recognition.\" " "%%Transactions on ASSP% #26: 43\\--49.") MAN_END MAN_BEGIN (U"Sekey & Hanson (1984)", U"djmw", 20050302) NORMAL (U"A. Sekey & B.A. Hanson (1984): \"Improved 1-Bark bandwidth auditory filter.\" " "%%Journal of the Acoustical Society of America% #75: 1902\\--1904.") MAN_END MAN_BEGIN (U"Schott (2001)", U"djmw", 20090629) NORMAL (U"J. R. Schott (2001): \"Some tests for the equality of covariance matrices.\" " "%%Journal of Statistical Planning and Inference% #94: 25\\-–36.") MAN_END MAN_BEGIN (U"Shepard (1964)", U"djmw", 19980114) NORMAL (U"R.N. Shepard (1964): \"Circularity in judgments of relative pitch.\" " "%%Journal of the Acoustical Society of America% #36: 2346\\--2353.") MAN_END MAN_BEGIN (U"Slaney (1993)", U"djmw", 19980712) NORMAL (U"M. Slaney (1993): \"An efficient implementation of the " "Patterson-Holdsworth auditory filterbank.\" " "%%Apple Computer Technical Report% #35, 41 pages.") MAN_END MAN_BEGIN (U"Tribolet et al. (1979)", U"djmw", 20010114) NORMAL (U"J.M. Tribolet & T.F. Quatieri (1979): \"Computation of the Complex " "Cepstrum.\" In %%Programs for Digital Signal Processing%, " "Digital Signal Processing Committee (eds.), IEEE Press.") MAN_END MAN_BEGIN (U"Tukey (1977)", U"djmw", 20000524) NORMAL (U"J.W. Tukey (1977): %%Exploratory data analysis%. Reading, MA: Addison-Wesley.") MAN_END MAN_BEGIN (U"Van Nierop et al. (1973)", U"djmw", 20020620) NORMAL (U"D.J.P.J. Van Nierop, L.C.W. Pols & R. Plomp (1973): \"Frequency " "analysis of Dutch vowels from 25 female speakers.\" %%Acustica% #29: 110\\--118") MAN_END MAN_BEGIN (U"Weenink (1985)", U"djmw", 20111010) NORMAL (U"D.J.M. Weenink (1985), \"Formant analysis of Dutch vowels from 10 children\", " "%%Proceedings of the Institute of Phonetic Sciences of the " "University of Amsterdam% #9, 45\\--52.") MAN_END MAN_BEGIN (U"Watrous (1991)", U"djmw", 20080125) NORMAL (U"R.L. Watrous (1991): \"Current status of Peterson-Barney vowel formant data.\" " "%%Journal of the Acoustical Society of America% #89: 2459\\--2460.") MAN_END MAN_BEGIN (U"Weenink (1999)", U"djmw", 20041217) NORMAL (U"D.J.M. Weenink (1999): \"Accurate algorithms for performing " "principal component analysis and discriminant analysis.\" " "%%Proceedings of the Institute of Phonetic Sciences of the " "University of Amsterdam% #23: 77\\--89.") MAN_END MAN_BEGIN (U"Weenink (2003)", U"djmw", 20040225) NORMAL (U"D.J.M. Weenink (2003): \"Canonical correlation analysis.\" " "%%Proceedings of the Institute of Phonetic Sciences of the " "University of Amsterdam% #25: 81\\--99.") MAN_END } /* End of file manual_dwtools.cpp */ praat-6.0.04/dwtools/praat_BSS_init.cpp000066400000000000000000000606051261542461700177670ustar00rootroot00000000000000/* praat_BSS_init.c * * Copyright (C) 2010-2014, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20101003 djmw 20110101 Latest modification */ #include "praat.h" #include "EEG_extensions.h" #include "ICA.h" #include "Sound_and_PCA.h" #undef iam #define iam iam_LOOP void praat_SSCP_as_TableOfReal_init (ClassInfo klas); void praat_TableOfReal_init (ClassInfo klas); void praat_TableOfReal_init3 (ClassInfo klas); /******************** EEG ********************************************/ FORM (EEG_to_CrossCorrelationTable, U"EEG: To CrossCorrelationTable", U"EEG: To CrossCorrelationTable...") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"10.0") REAL (U"Lag step (s)", U"0.05") TEXTFIELD (U"Channel ranges", U"1:64") LABEL (U"", U"To supply rising or falling ranges, use e.g. 2:6 or 5:3.") OK DO double startTime = GET_REAL (U"left Time range"), endTime = GET_REAL (U"right Time range"); double lagTime = GET_REAL (U"Lag step"); const char32 *channelRanges = GET_STRING (U"Channel ranges"); LOOP { iam (EEG); autoCrossCorrelationTable cct = EEG_to_CrossCorrelationTable (me, startTime, endTime, lagTime, channelRanges); praat_new (cct.move(), my name, U"_", (long) floor (lagTime*1000)); // lagTime to ms ppgb: geeft afrondingsfouten; waarom niet round? } END FORM (EEG_to_Covariance, U"EEG: To Covariance", U"EEG: To Covariance...") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"10.0") TEXTFIELD (U"Channel ranges", U"1:64") LABEL (U"", U"To supply rising or falling ranges, use e.g. 2:6 or 5:3.") OK DO double startTime = GET_REAL (U"left Time range"), endTime = GET_REAL (U"right Time range"); const char32 *channelRanges = GET_STRING (U"Channel ranges"); LOOP { iam (EEG); autoCovariance cov = EEG_to_Covariance (me, startTime, endTime, channelRanges); praat_new (cov.move(), my name); } END FORM (EEG_to_CrossCorrelationTables, U"EEG: To CrossCorrelationTables", U"EEG: To CrossCorrelationTables...") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"10.0") POSITIVE (U"Lag step (s)", U"0.02") NATURAL (U"Number of cross-correlations", U"40") LABEL (U"", U"To supply rising or falling ranges, use e.g. 2:6 or 5:3.") TEXTFIELD (U"Channel ranges", U"1:64") OK DO LOOP { iam (EEG); autoCrossCorrelationTables thee = EEG_to_CrossCorrelationTables (me, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"Lag step"), GET_INTEGER (U"Number of cross-correlations"), GET_STRING (U"Channel ranges")); praat_new (thee.move(), my name); } END FORM (EEG_to_EEG_bss, U"EEG: To EEG (bss)", U"EEG: To EEG (bss)...") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"10.0") NATURAL (U"Number of cross-correlations", U"40") POSITIVE (U"Lag step (s)", U"0.002") LABEL (U"", U"To supply rising or falling ranges, use e.g. 2:6 or 5:3.") TEXTFIELD (U"Channel ranges", U"1:64") LABEL (U"", U"Pre-whitening parameters") OPTIONMENU (U"Whitening method", 1) OPTION (U"No whitening") OPTION (U"Covariance") OPTION (U"Correlation") LABEL (U"", U"Iteration parameters") NATURAL (U"Maximum number of iterations", U"100") POSITIVE (U"Tolerance", U"0.001") OPTIONMENU (U"Diagonalization method", 2) OPTION (U"qdiag") OPTION (U"ffdiag") OK DO int whiteningMethod = GET_INTEGER (U"Whitening method") - 1; LOOP { iam (EEG); autoEEG thee = EEG_to_EEG_bss (me, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_INTEGER (U"Number of cross-correlations"), GET_REAL (U"Lag step"), GET_STRING (U"Channel ranges"), whiteningMethod, GET_INTEGER (U"Diagonalization method"), GET_INTEGER (U"Maximum number of iterations"), GET_REAL (U"Tolerance")); praat_new (thee.move(), my name, U"_bss"); } END FORM (EEG_to_PCA, U"EEG: To PCA", U"EEG: To PCA...") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"10.0") TEXTFIELD (U"Channel ranges", U"1:64") LABEL (U"", U"To supply rising or falling ranges, use e.g. 2:6 or 5:3.") OPTIONMENU (U"Use", 1) OPTION (U"Covariance") OPTION (U"Correlation") OK DO double startTime = GET_REAL (U"left Time range"), endTime = GET_REAL (U"right Time range"); const char32 *channelRanges = GET_STRING (U"Channel ranges"); bool useCorrelation = GET_INTEGER (U"Use") == 2; LOOP { iam (EEG); autoPCA pca = EEG_to_PCA (me, startTime, endTime, channelRanges, useCorrelation); praat_new (pca.move(), my name); } END FORM (EEG_and_PCA_to_EEG_principalComponents, U"EEG & PCA: To EEG (principal components)", U"EEG & PCA: To EEG (principal components)...") INTEGER (U"Number of components", U"0 (=all)") OK DO EEG me = FIRST (EEG); PCA thee = FIRST (PCA); autoEEG him = EEG_and_PCA_to_EEG_principalComponents (me, thee, GET_INTEGER (U"Number of components")); praat_new (him.move(), my name, U"_pc"); END FORM (EEG_and_PCA_to_EEG_whiten, U"EEG & PCA: To EEG (whiten)", U"EEG & PCA: To EEG (whiten)...") INTEGER (U"Number of components", U"0 (=all)") OK DO EEG me = FIRST (EEG); PCA thee = FIRST (PCA); autoEEG him = EEG_and_PCA_to_EEG_whiten (me, thee, GET_INTEGER (U"Number of components")); praat_new (him.move(), my name, U"_white"); END FORM (EEG_to_Sound_modulated, U"EEG: To Sound (modulated)", 0) POSITIVE (U"Start frequency (Hz)", U"100.0") POSITIVE (U"Channel bandwidth (Hz)", U"100.0") TEXTFIELD (U"Channel ranges", U"1:64") LABEL (U"", U"To supply rising or falling ranges, use e.g. 2:6 or 5:3.") OK DO LOOP { iam (EEG); autoSound thee = EEG_to_Sound_modulated (me, GET_REAL (U"Start frequency"), GET_REAL (U"Channel bandwidth"), GET_STRING (U"Channel ranges")); praat_new (thee.move(), my name); } END FORM (EEG_to_Sound_frequencyShifted, U"EEG: To Sound (frequency shifted)", 0) NATURAL (U"Channel", U"1") POSITIVE (U"Frequency shift (Hz)", U"100.0") POSITIVE (U"Sampling frequecy (Hz)", U"11025.0") REAL (U"Maximum amplitude", U"0.99") OK DO long channel = GET_INTEGER (U"Channel"); LOOP { iam (EEG); autoSound thee = EEG_to_Sound_frequencyShifted (me, channel, GET_REAL (U"Frequency shift"), GET_REAL (U"Sampling frequecy"), GET_REAL (U"Maximum amplitude")); praat_new (thee.move(), my name, U"_ch", channel); } END /********************** CrossCorrelationTable(s) ******************/ FORM (CrossCorrelationTables_createTestSet, U"CrossCorrelationTables: Create test set", U"CrossCorrelationTables: Create test set...") WORD (U"Name", U"5x5") NATURAL (U"Matrix dimension", U"5") NATURAL (U"Number of matrices", U"20") BOOLEAN (U"First is positive definite", 1) REAL (U"Sigma", U"0.02") OK DO autoCrossCorrelationTables thee = CrossCorrelationTables_createTestSet (GET_INTEGER (U"Matrix dimension"), GET_INTEGER (U"Number of matrices"), GET_INTEGER (U"First is positive definite"), GET_REAL (U"Sigma")); praat_new (thee.move(), GET_STRING (U"Name")); END FORM (CrossCorrelationTable_createSimple, U"Create simple CrossCorrelationTable", 0) WORD (U"Name", U"ct") SENTENCE (U"Cross correlations", U"1.0 0.0 1.0") SENTENCE (U"Centroid", U"0.0 0.0") NATURAL (U"Number of samples", U"100") OK DO autoCrossCorrelationTable thee = CrossCorrelationTable_createSimple (GET_STRING (U"Cross correlations"), GET_STRING (U"Centroid"), GET_INTEGER (U"Number of samples")); praat_new (thee.move(), GET_STRING (U"Name")); END FORM (MixingMatrix_createSimple, U"Create simple MixingMatrix", 0) WORD (U"Name", U"mm") NATURAL (U"Number of channels", U"2") NATURAL (U"Number of components", U"2") SENTENCE (U"Mixing coefficients", U"1.0 1.0 1.0 1.0") OK DO autoMixingMatrix thee = MixingMatrix_createSimple (GET_INTEGER (U"Number of channels"), GET_INTEGER (U"Number of components"), GET_STRING (U"Mixing coefficients")); praat_new (thee.move(), GET_STRING (U"Name")); END DIRECT (CrossCorrelationTable_help) Melder_help (U"CrossCorrelationTable"); END FORM (Sound_and_PCA_principalComponents, U"Sound & PCA: To Sound (principal components)", 0) NATURAL (U"Number of components", U"10") OK DO Sound me = FIRST (Sound); PCA thee = FIRST (PCA); autoSound him = Sound_and_PCA_principalComponents (me, thee, GET_INTEGER (U"Number of components")); praat_new (him.move(), my name, U"_pc"); END FORM (Sound_and_PCA_whitenChannels, U"Sound & PCA: To Sound (white channels)", 0) NATURAL (U"Number of components", U"10") OK DO Sound me = FIRST (Sound); PCA thee = FIRST (PCA); autoSound him = Sound_and_PCA_whitenChannels (me, thee, GET_INTEGER (U"Number of components")); praat_new (him.move(), my name, U"_white"); END DIRECT (CrossCorrelationTable_to_CrossCorrelationTables) autoCrossCorrelationTables thee = CrossCorrelationTables_create (); long nrows = 0, ncols = 0, nselected = 0; LOOP { iam (CrossCorrelationTable); nselected++; if (nselected == 1) { nrows = my numberOfRows; ncols = my numberOfColumns; } if (my numberOfRows != nrows || my numberOfColumns != ncols) { Melder_throw (U"Dimensions of table ", IOBJECT, U" differs from the rest."); } autoCrossCorrelationTable myc = Data_copy (me); Collection_addItem (thee.peek(), myc.transfer()); } praat_new (thee.move(), U"ct_", nselected); END FORM (Sound_to_Covariance_channels, U"Sound: To Covariance (channels)", U"Sound: To Covariance (channels)...") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"10.0") OK DO LOOP { iam (Sound); autoCovariance thee = Sound_to_Covariance_channels (me, GET_REAL (U"left Time range"), GET_REAL (U"right Time range")); praat_new (thee.move(), my name); } END FORM (Sound_to_CrossCorrelationTable, U"Sound: To CrossCorrelationTable", U"Sound: To CrossCorrelationTable...") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"10.0") REAL (U"Lag step (s)", U"0.0") OK DO double lagTime = fabs (GET_REAL (U"Lag step")); LOOP { iam (Sound); autoCrossCorrelationTable thee = Sound_to_CrossCorrelationTable (me, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), lagTime); praat_new (thee.move(), my name); } END FORM (Sounds_to_CrossCorrelationTable_combined, U"Sound: To CrossCorrelationTable (combined)", 0) REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"10.0") REAL (U"Lag step (s)", U"0.0") OK DO Sound s1 = nullptr, s2 = nullptr; LOOP { iam (Sound); (s1 ? s2 : s1) = me; } Melder_assert (s1 && s2); autoCrossCorrelationTable thee = Sounds_to_CrossCorrelationTable_combined (s1, s2, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"Lag step")); praat_new (thee.move(), s1 -> name, U"_", s2 -> name, U"_cc"); END DIRECT (CrossCorrelationTables_help) Melder_help (U"CrossCorrelationTables"); END FORM (CrossCorrelationTables_getDiagonalityMeasure, U"CrossCorrelationTables: Get diagonality measure", U"CrossCorrelationTables: Get diagonality measure...") NATURAL (U"First table", U"1") NATURAL (U"Last table", U"100") OK DO LOOP { iam (CrossCorrelationTables); double dm = CrossCorrelationTables_getDiagonalityMeasure (me, 0, GET_INTEGER (U"First table"), GET_INTEGER (U"Last table")); Melder_information (dm, U" (= average sum of squared off-diagonal elements)"); } END FORM (CrossCorrelationTables_extractCrossCorrelationTable, U"CrossCorrelationTables: Extract one CrossCorrelationTable", 0) NATURAL (U"Index", U"1") OK DO long index = GET_INTEGER (U"Index"); LOOP { iam (CrossCorrelationTables); if (index > my size) { Melder_throw (U"Index too large."); } autoCrossCorrelationTable thee = Data_copy ( (CrossCorrelationTable) my item[index]); praat_new (thee.move(), Thing_getName (me), U"_", index); } END FORM (CrossCorrelationTables_to_Diagonalizer, U"CrossCorrelationTables: To Diagonalizer", 0) NATURAL (U"Maximum number of iterations", U"100") POSITIVE (U"Tolerance", U"0.001") OPTIONMENU (U"Diagonalization method", 2) OPTION (U"qdiag") OPTION (U"ffdiag") OK DO LOOP { iam (CrossCorrelationTables); autoDiagonalizer thee = CrossCorrelationTables_to_Diagonalizer (me, GET_INTEGER (U"Maximum number of iterations"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Diagonalization method")); praat_new (thee.move(), my name); } END FORM (Diagonalizer_and_CrossCorrelationTables_improveDiagonality, U"Diagonalizer & CrossCorrelationTables: Improve diagonality", 0) NATURAL (U"Maximum number of iterations", U"100") POSITIVE (U"Tolerance", U"0.001") OPTIONMENU (U"Diagonalization method", 2) OPTION (U"qdiag") OPTION (U"ffdiag") OK DO Diagonalizer d = FIRST (Diagonalizer); CrossCorrelationTables ccts = FIRST (CrossCorrelationTables); Diagonalizer_and_CrossCorrelationTables_improveDiagonality (d, ccts, GET_INTEGER (U"Maximum number of iterations"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Diagonalization method")); END FORM (CrossCorrelationTables_and_Diagonalizer_getDiagonalityMeasure, U"CrossCorrelationTables & Diagonalizer: Get diagonality measure", 0) NATURAL (U"First table", U"1") NATURAL (U"Last table", U"100") OK DO CrossCorrelationTables ccts = FIRST (CrossCorrelationTables); Diagonalizer d = FIRST (Diagonalizer); double dm = CrossCorrelationTables_and_Diagonalizer_getDiagonalityMeasure (ccts, d, 0, GET_INTEGER (U"First table"), GET_INTEGER (U"Last table")); Melder_information (dm, U" (= average sum of squared off-diagonal elements)"); END DIRECT (CrossCorrelationTable_and_Diagonalizer_diagonalize) CrossCorrelationTable cct = FIRST (CrossCorrelationTable); Diagonalizer d = FIRST (Diagonalizer); autoCrossCorrelationTable thee = CrossCorrelationTable_and_Diagonalizer_diagonalize (cct, d); praat_new (thee.move(), cct -> name, U"_", d -> name); END DIRECT (CrossCorrelationTables_and_Diagonalizer_diagonalize) CrossCorrelationTables ccts = FIRST (CrossCorrelationTables); Diagonalizer d = FIRST (Diagonalizer); autoCrossCorrelationTables thee = CrossCorrelationTables_and_Diagonalizer_diagonalize (ccts, d); praat_new (thee.move(), ccts->name, U"_", d->name); END FORM (CrossCorrelationTables_and_MixingMatrix_improveUnmixing, U"", 0) LABEL (U"", U"Iteration parameters") NATURAL (U"Maximum number of iterations", U"100") POSITIVE (U"Tolerance", U"0.001") OPTIONMENU (U"Diagonalization method", 2) OPTION (U"qdiag") OPTION (U"ffdiag") OK DO MixingMatrix mm = FIRST (MixingMatrix); CrossCorrelationTables ccts = FIRST (CrossCorrelationTables); MixingMatrix_and_CrossCorrelationTables_improveUnmixing (mm, ccts, GET_INTEGER (U"Maximum number of iterations"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Diagonalization method")); END DIRECT (Diagonalizer_to_MixingMatrix) LOOP { iam (Diagonalizer); autoMixingMatrix thee = Diagonalizer_to_MixingMatrix (me); praat_new (thee.move(), my name); } END FORM (Sound_to_MixingMatrix, U"Sound: To MixingMatrix", 0) REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"10.0") NATURAL (U"Number of cross-correlations", U"40") POSITIVE (U"Lag step (s)", U"0.002") LABEL (U"", U"Iteration parameters") NATURAL (U"Maximum number of iterations", U"100") POSITIVE (U"Tolerance", U"0.001") OPTIONMENU (U"Diagonalization method", 2) OPTION (U"qdiag") OPTION (U"ffdiag") OK DO LOOP { iam (Sound); autoMixingMatrix thee = Sound_to_MixingMatrix (me, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_INTEGER (U"Number of cross-correlations"), GET_REAL (U"Lag step"), GET_INTEGER (U"Maximum number of iterations"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Diagonalization method")); praat_new (thee.move(), my name); } END FORM (Sound_to_CrossCorrelationTables, U"Sound: To CrossCorrelationTables", 0) REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"10.0") NATURAL (U"Number of cross-correlations", U"40") POSITIVE (U"Lag step (s)", U"0.002") OK DO LOOP { iam (Sound); autoCrossCorrelationTables thee = Sound_to_CrossCorrelationTables (me, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"Lag step"), GET_INTEGER (U"Number of cross-correlations")); praat_new (thee.move(), my name); } END FORM (Sound_to_Sound_bss, U"Sound: To Sound (blind source separation)", U"Sound: To Sound (blind source separation)...") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"10.0") NATURAL (U"Number of cross-correlations", U"40") POSITIVE (U"Lag step (s)", U"0.002") LABEL (U"", U"Iteration parameters") NATURAL (U"Maximum number of iterations", U"100") POSITIVE (U"Tolerance", U"0.001") OPTIONMENU (U"Diagonalization method", 2) OPTION (U"qdiag") OPTION (U"ffdiag") OK DO LOOP { iam (Sound); autoSound thee = Sound_to_Sound_BSS (me, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_INTEGER (U"Number of cross-correlations"), GET_REAL (U"Lag step"), GET_INTEGER (U"Maximum number of iterations"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Diagonalization method")); praat_new (thee.move(), my name, U"_bss"); } END FORM (Sound_to_Sound_whiteChannels, U"Sound: To Sound (white channels)", U"Sound: To Sound (white channels)...") POSITIVE (U"Variance fraction to keep", U"0.99") OK DO double varianceFraction = GET_REAL (U"Variance fraction to keep"); if (varianceFraction > 1) varianceFraction = 1; long permille = (long) floor (varianceFraction * 1000.0); LOOP { iam (Sound); autoSound thee = Sound_whitenChannels (me, varianceFraction); praat_new (thee.move(), my name, U"_", permille); } END DIRECT (Sound_and_MixingMatrix_mix) Sound s = FIRST (Sound); MixingMatrix mm = FIRST (MixingMatrix); autoSound thee = Sound_and_MixingMatrix_mix (s, mm); praat_new (thee.move(), Thing_getName (s), U"_mixed"); END DIRECT (Sound_and_MixingMatrix_unmix) Sound s = FIRST (Sound); MixingMatrix mm = FIRST (MixingMatrix); autoSound thee = Sound_and_MixingMatrix_unmix (s, mm); praat_new (thee.move(), Thing_getName (s), U"_unmixed"); END DIRECT (TableOfReal_to_MixingMatrix) LOOP { iam (TableOfReal); autoMixingMatrix thee = TableOfReal_to_MixingMatrix (me); praat_new (thee.move(), my name); } END FORM (TableOfReal_and_TableOfReal_crossCorrelations, U"TableOfReal & TableOfReal: Cross-correlations", 0) OPTIONMENU (U"Correlations between", 1) OPTION (U"Rows") OPTION (U"Columns") BOOLEAN (U"Center", 0) BOOLEAN (U"Normalize", 0) OK DO TableOfReal t1 = nullptr, t2 = nullptr; LOOP { iam (TableOfReal); (t1 ? t2 : t1) = me; } Melder_assert (t1 && t2); int by_columns = GET_INTEGER (U"Correlations between") - 1; autoTableOfReal thee = TableOfReal_and_TableOfReal_crossCorrelations (t1, t2, by_columns, GET_INTEGER (U"Center"), GET_INTEGER (U"Normalize")); praat_new (thee.move(), ( by_columns ? U"by_columns" : U"by_rows" )); END void praat_TableOfReal_init3 (ClassInfo klas) { praat_TableOfReal_init (klas); praat_addAction1 (klas, 2, U"To TableOfReal (cross-correlations)...", 0, 0, DO_TableOfReal_and_TableOfReal_crossCorrelations); } void praat_BSS_init (); void praat_BSS_init () { Thing_recognizeClassesByName (classDiagonalizer, classMixingMatrix, classCrossCorrelationTable, classCrossCorrelationTables, nullptr); praat_addMenuCommand (U"Objects", U"New", U"Create simple CrossCorrelationTable...", U"Create simple Covariance...", praat_HIDDEN + praat_DEPTH_1, DO_CrossCorrelationTable_createSimple); praat_addMenuCommand (U"Objects", U"New", U"Create test CrossCorrelationTables...", U"Create simple CrossCorrelationTable...", praat_HIDDEN + praat_DEPTH_1, DO_CrossCorrelationTables_createTestSet); praat_addMenuCommand (U"Objects", U"New", U"Create simple MixingMatrix...", U"Create test CrossCorrelationTables...", praat_HIDDEN + praat_DEPTH_1, DO_MixingMatrix_createSimple); praat_addAction1 (classCrossCorrelationTable, 0, U"CrossCorrelationTable help", 0, 0, DO_CrossCorrelationTable_help); praat_SSCP_as_TableOfReal_init (classCrossCorrelationTable); praat_addAction1 (classCrossCorrelationTable, 0, U"To CrossCorrelationTables", 0, 0, DO_CrossCorrelationTable_to_CrossCorrelationTables); praat_addAction1 (classCrossCorrelationTables, 0, U"CrossCorrelationTables help", 0, 0, DO_CrossCorrelationTables_help); praat_addAction1 (classCrossCorrelationTables, 1, U"Extract CrossCorrelationTable...", 0, 0, DO_CrossCorrelationTables_extractCrossCorrelationTable); praat_addAction1 (classCrossCorrelationTables, 1, U"Get diagonality measure...", 0, 0, DO_CrossCorrelationTables_getDiagonalityMeasure); praat_addAction1 (classCrossCorrelationTables, 0, U"To Diagonalizer...", 0, 0, DO_CrossCorrelationTables_to_Diagonalizer); praat_TableOfReal_init3 (classDiagonalizer); praat_addAction1 (classDiagonalizer, 0, U"To MixingMatrix", 0, 0, DO_Diagonalizer_to_MixingMatrix); praat_addAction1 (classEEG, 0, U"To Sound (mc modulated)...", U"To ERPTier...", praat_HIDDEN, DO_EEG_to_Sound_modulated); praat_addAction1 (classEEG, 0, U"To Sound (frequency shifted)...", U"To ERPTier...", 0, DO_EEG_to_Sound_frequencyShifted); praat_addAction1 (classEEG, 0, U"To PCA...", U"To ERPTier...", 0, DO_EEG_to_PCA); praat_addAction1 (classEEG, 0, U"To CrossCorrelationTable...", U"To PCA...", praat_HIDDEN, DO_EEG_to_CrossCorrelationTable); praat_addAction1 (classEEG, 0, U"To CrossCorrelationTables...", U"To PCA...", praat_HIDDEN, DO_EEG_to_CrossCorrelationTables); praat_addAction1 (classEEG, 0, U"To Covariance...", U"To CrossCorrelationTable...", praat_HIDDEN, DO_EEG_to_Covariance); praat_addAction1 (classEEG, 0, U"To EEG (bss)...", U"To CrossCorrelationTable...", praat_HIDDEN, DO_EEG_to_EEG_bss); praat_addAction2 (classEEG, 1, classPCA, 1, U"To EEG (principal components)...", 0, 0, DO_EEG_and_PCA_to_EEG_principalComponents); praat_addAction2 (classEEG, 1, classPCA, 1, U"To EEG (whiten)...", 0, 0, DO_EEG_and_PCA_to_EEG_whiten); praat_TableOfReal_init3 (classMixingMatrix); praat_addAction1 (classSound, 0, U"To MixingMatrix...", U"Resample...", praat_HIDDEN + praat_DEPTH_1, DO_Sound_to_MixingMatrix); praat_addAction1 (classSound, 0, U"To CrossCorrelationTable...", U"Resample...", 1, DO_Sound_to_CrossCorrelationTable); praat_addAction1 (classSound, 0, U"To Covariance (channels)...", U"Resample...", praat_HIDDEN + praat_DEPTH_1, DO_Sound_to_Covariance_channels); praat_addAction1 (classSound, 0, U"To CrossCorrelationTables...", U"Resample...", praat_HIDDEN + praat_DEPTH_1, DO_Sound_to_CrossCorrelationTables); praat_addAction1 (classSound, 0, U"To Sound (bss)...", U"Resample...", 1, DO_Sound_to_Sound_bss); praat_addAction1 (classSound, 0, U"To Sound (white channels)...", U"Resample...", 1, DO_Sound_to_Sound_whiteChannels); praat_addAction1 (classSound, 2, U"To CrossCorrelationTable (combined)...", U"Cross-correlate...", 1, DO_Sounds_to_CrossCorrelationTable_combined); praat_addAction1 (classTableOfReal, 0, U"To MixingMatrix", U"To Configuration", praat_HIDDEN, DO_TableOfReal_to_MixingMatrix); praat_addAction2 (classSound, 1, classMixingMatrix, 1, U"Mix", 0, 0, DO_Sound_and_MixingMatrix_mix); praat_addAction2 (classSound, 1, classMixingMatrix, 1, U"Unmix", 0, 0, DO_Sound_and_MixingMatrix_unmix); praat_addAction2 (classSound, 1, classPCA, 1, U"To Sound (white channels)...", 0 , 0, DO_Sound_and_PCA_whitenChannels); praat_addAction2 (classSound, 1, classPCA, 1, U"To Sound (principal components)...", 0 , 0, DO_Sound_and_PCA_principalComponents); praat_addAction2 (classCrossCorrelationTable, 1, classDiagonalizer, 1, U"Diagonalize", 0 , 0, DO_CrossCorrelationTable_and_Diagonalizer_diagonalize); praat_addAction2 (classCrossCorrelationTables, 1, classDiagonalizer, 1, U"Get diagonality measure...", 0 , 0, DO_CrossCorrelationTables_and_Diagonalizer_getDiagonalityMeasure); praat_addAction2 (classCrossCorrelationTables, 1, classDiagonalizer, 1, U"Diagonalize", 0 , 0, DO_CrossCorrelationTables_and_Diagonalizer_diagonalize); praat_addAction2 (classCrossCorrelationTables, 1, classDiagonalizer, 1, U"Improve diagonality...", 0 , 0, DO_Diagonalizer_and_CrossCorrelationTables_improveDiagonality); praat_addAction2 (classCrossCorrelationTables, 1, classMixingMatrix, 1, U"Improve unmixing...", 0 , 0, DO_CrossCorrelationTables_and_MixingMatrix_improveUnmixing); INCLUDE_MANPAGES (manual_BSS) } /* End of file praat_BSS_init.c */ praat-6.0.04/dwtools/praat_DataModeler_init.cpp000066400000000000000000001657771261542461700215410ustar00rootroot00000000000000/* praat_DataModeler_init.cpp * * Copyright (C) 2014 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "praatP.h" #include "DataModeler.h" #include "Formant_extensions.h" #include "OptimalCeilingTierEditor.h" #include "Pitch.h" #include "Table_extensions.h" #include #undef iam #define iam iam_LOOP /* DataModeler */ FORM (DataModeler_createSimple, U"Create simple DataModeler", 0) WORD (U"Name", U"dm") REAL (U"left X range", U"0.0") REAL (U"right X range", U"1.0") NATURAL (U"Number of data points", U"20") SENTENCE (U"Parameters", U"0.0 1.0 1.0") POSITIVE (U"Gaussian noise stdev", U"0.2") OPTIONMENU (U"Basis functions", 2) OPTION (U"Polynomial") OPTION (U"Legendre") OK DO autoDataModeler thee = DataModeler_createSimple (GET_REAL (U"left X range"), GET_REAL (U"right X range"), GET_INTEGER (U"Number of data points"), GET_STRING (U"Parameters"), GET_REAL (U"Gaussian noise stdev"), GET_INTEGER (U"Basis functions") - 1); praat_new (thee.move(), GET_STRING (U"Name")); END FORM (DataModeler_speckle, U"DataModeler: Speckle", 0) REAL (U"left X range", U"0.0") REAL (U"right X range", U"0.0") REAL (U"left Y range", U"0.0") REAL (U"right Y range", U"0.0") BOOLEAN (U"Draw error bars", 1) REAL (U"Bar width (mm)", U"1.0") REAL (U"Horizontal offset (mm)", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; long order = 6; LOOP { iam (DataModeler); DataModeler_speckle (me, GRAPHICS, GET_REAL (U"left X range"), GET_REAL (U"right X range"), GET_REAL (U"left Y range"), GET_REAL (U"right Y range"), 0, order + 1, GET_INTEGER (U"Draw error bars"), GET_REAL (U"Bar width"), GET_REAL (U"Horizontal offset"), GET_INTEGER (U"Garnish")); } END FORM (DataModeler_drawEstimatedTrack, U"DataModeler: Draw estimated track", 0) REAL (U"left X range", U"0.0") REAL (U"right X range", U"0.0") REAL (U"left Y range", U"0.0") REAL (U"right Y range", U"0.0") INTEGER (U"Order of polynomials for estimation", U"3") REAL (U"Horizontal offset (mm)", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; long order = GET_INTEGER (U"Order of polynomials for estimation"); REQUIRE (order >= 0, U"The order must be greater than or equal to zero.") LOOP { iam (DataModeler); DataModeler_drawTrack (me, GRAPHICS, GET_REAL (U"left X range"), GET_REAL (U"right X range"), GET_REAL (U"left Y range"), GET_REAL (U"right Y range"), 1, order + 1, GET_REAL (U"Horizontal offset"), GET_INTEGER (U"Garnish")); } END DIRECT (DataModeler_getNumberOfParameters) LOOP { iam (DataModeler); Melder_information (my numberOfParameters, U" (= number of parameters)"); } END DIRECT (DataModeler_getNumberOfFixedParameters) LOOP { iam (DataModeler); Melder_information (DataModeler_getNumberOfFixedParameters (me), U" (= number of parameters)"); } END FORM (DataModeler_getParameterValue, U"DataModeler: Get parameter value", 0) NATURAL (U"Parameter number", U"1") OK DO long iparameter = GET_INTEGER (U"Parameter number"); LOOP { iam (DataModeler); double parameter = DataModeler_getParameterValue (me, iparameter); Melder_information (parameter, U" (= parameter[", iparameter, U"])"); } END FORM (DataModeler_getParameterStatus, U"DataModeler: Get parameter status", 0) NATURAL (U"Parameter number", U"1") OK DO long iparameter = GET_INTEGER (U"Parameter number"); LOOP { iam (DataModeler); int status = DataModeler_getParameterStatus (me, iparameter); Melder_information (status == DataModeler_PARAMETER_FREE ? U"Free" : (status == DataModeler_PARAMETER_FIXED ? U"Fixed" : U"Undefined"), U" (= parameter[", iparameter, U"])"); } END FORM (DataModeler_getParameterStandardDeviation, U"DataModeler: Get parameter standard deviation", 0) NATURAL (U"Parameter number", U"1") OK DO long iparameter = GET_INTEGER (U"Parameter number"); LOOP { iam (DataModeler); double sigma = DataModeler_getParameterStandardDeviation (me, iparameter); Melder_information (sigma, U" (= parameter[", iparameter, U"])"); } END FORM (DataModeler_getVarianceOfParameters, U"DataModeler: Get variance of parameters", 0) INTEGER (U"left Parameter range", U"0") INTEGER (U"right Parameter range", U"0") OK DO long nofp; LOOP { iam (DataModeler); double var = DataModeler_getVarianceOfParameters (me, GET_INTEGER (U"left Parameter range"), GET_INTEGER (U"right Parameter range"), &nofp); Melder_information (var, U" (for ", nofp, U" free parameters)"); } END DIRECT (DataModeler_getNumberOfDataPoints) LOOP { iam (DataModeler); Melder_information (my numberOfDataPoints, U" (= number of data points)"); } END DIRECT (DataModeler_getNumberOfInvalidDataPoints) LOOP { iam (DataModeler); Melder_information (DataModeler_getNumberOfInvalidDataPoints (me), U" (= number of invalid data points)"); } END FORM (DataModeler_getModelValueAtX, U"DataModeler: Get model value at x", 0) REAL (U"X", U"0.1") OK DO LOOP { iam (DataModeler); double y = DataModeler_getModelValueAtX (me, GET_REAL (U"X")); Melder_informationReal (y, nullptr); } END DIRECT (DataModeler_getResidualSumOfSquares) LOOP { long n; iam (DataModeler); double rss = DataModeler_getResidualSumOfSquares (me, &n); Melder_information (rss, U" (for ", n, U" datapoints)"); } END DIRECT (DataModeler_getStandardDeviation) LOOP { iam (DataModeler); double sigma = DataModeler_estimateSigmaY (me); Melder_information (sigma); } END FORM (DataModeler_getDataPointValue, U"DataModeler: Get data point value", 0) NATURAL (U"Index", U"1") OK DO long index = GET_INTEGER (U"Index"); LOOP { iam (DataModeler); double value = DataModeler_getDataPointValue (me, index); Melder_information (value, U" (= value at point ", index, U")"); } END FORM (DataModeler_getDataPointSigma, U"DataModeler: Get data point sigma", 0) NATURAL (U"Index", U"1") OK DO long index = GET_INTEGER (U"Index"); LOOP { iam (DataModeler); double sigma = DataModeler_getDataPointSigma (me, index); Melder_information (sigma, U" (= sigma at point ", index, U")"); } END FORM (DataModeler_getDataPointStatus, U"DataModeler: Get data point status", 0) NATURAL (U"Index", U"1") OK DO LOOP { iam (DataModeler); int status = DataModeler_getDataPointStatus (me, GET_INTEGER (U"Index")); Melder_information (status == DataModeler_DATA_INVALID ? U"Invalid" : U"Valid"); } END DIRECT (DataModeler_getCoefficientOfDetermination) LOOP { iam (DataModeler); double rSquared = DataModeler_getCoefficientOfDetermination (me, nullptr, nullptr); Melder_informationReal (rSquared, U" (= R^2)"); } END FORM (DataModeler_reportChiSquared, U"DataModeler: Report chi squared", 0) OPTIONMENU (U"Weigh data", 2) OPTION (U"Equally") OPTION (U"Sigma") OPTION (U"Relative") OPTION (U"Sqrt sigma") OK DO LOOP { iam (DataModeler); int useSigmaY = GET_INTEGER (U"Weigh data") - 1; MelderInfo_open (); MelderInfo_writeLine (U"Chi squared test:"); MelderInfo_writeLine (useSigmaY == DataModeler_DATA_WEIGH_EQUAL ? U"Standard deviation is estimated from the data." : useSigmaY == DataModeler_DATA_WEIGH_SIGMA ? U"Sigmas are used as estimate for local standard deviations." : useSigmaY == DataModeler_DATA_WEIGH_RELATIVE ? U"1/Q's are used as estimate for local standard deviations." : U"Sqrt sigmas are used as estimate for local standard deviations."); double ndf, probability, chisq = DataModeler_getChiSquaredQ (me, useSigmaY, &probability, &ndf); MelderInfo_writeLine (U"Chi squared = ", chisq); MelderInfo_writeLine (U"Probability = ", probability); MelderInfo_writeLine (U"Number of degrees of freedom = ", ndf); MelderInfo_close (); } END DIRECT (DataModeler_getDegreesOfFreedom) LOOP { iam (DataModeler); double dof = DataModeler_getDegreesOfFreedom (me); Melder_informationReal (dof, U" (= degrees of freedom)"); } END FORM (DataModeler_setDataWeighing, U"DataModeler: Set data weighing", 0) OPTIONMENU (U"Weigh data", 1) OPTION (U"Equally") OPTION (U"Sigma") OPTION (U"Relative") OPTION (U"Sqrt sigma") OK DO LOOP { iam (DataModeler); DataModeler_setDataWeighing (me, GET_INTEGER (U"Weigh data") - 1); } END FORM (DataModeler_setTolerance, U"DataModeler: Set tolerance", 0) REAL (U"Tolerance", U"1e-5") OK DO LOOP { iam (DataModeler); DataModeler_setTolerance (me, GET_REAL (U"Tolerance")); } END FORM (DataModeler_setParameterValue, U"DataModeler: Set parameter value", 0) NATURAL (U"Parameter number", U"1") REAL (U"Value", U"0.0") OPTIONMENU (U"Status", 1) OPTION (U"Free") OPTION (U"Fixed") OK DO LOOP { iam (DataModeler); DataModeler_setParameterValue (me, GET_INTEGER (U"Parameter number"), GET_REAL (U"Value"), GET_INTEGER (U"Status") - 1); } END FORM (DataModeler_setParameterFree, U"DataModeler: Set parameter free", 0) INTEGER (U"left Parameter range", U"0") INTEGER (U"right Parameter range", U"0") OK DO LOOP { iam (DataModeler); DataModeler_setParametersFree (me, GET_INTEGER (U"left Parameter range"), GET_INTEGER (U"right Parameter range")); } END FORM (DataModeler_setParameterValuesToZero, U"DataModeler: Set parameter values to zero", 0) REAL (U"Number of sigmas", U"1.0") OK DO LOOP { iam (DataModeler); DataModeler_setParameterValuesToZero (me, GET_REAL (U"Number of sigmas")); } END FORM (DataModeler_setDataPointStatus, U"DataModeler: Set data point status", 0) NATURAL (U"Index", U"1") OPTIONMENU (U"Status", 1) OPTION (U"Valid") OPTION (U"Invalid") OK DO int menustatus = GET_INTEGER (U"Status"); int status = menustatus == 2 ? DataModeler_DATA_INVALID : DataModeler_DATA_VALID; LOOP { iam (DataModeler); DataModeler_setDataPointStatus (me, GET_INTEGER (U"Index"), status); } END FORM (DataModeler_setDataPointValue, U"DataModeler: Set data point value", 0) NATURAL (U"Index", U"1") REAL (U"Value", U"0.0") OK DO LOOP { iam (DataModeler); DataModeler_setDataPointValue (me, GET_INTEGER (U"Index"), GET_REAL (U"Value")); } END FORM (DataModeler_setDataPointSigma, U"DataModeler: Set data point sigma", 0) NATURAL (U"Index", U"1") REAL (U"Sigma", U"10.0") OK DO LOOP { iam (DataModeler); DataModeler_setDataPointSigma (me, GET_INTEGER (U"Index"), GET_REAL (U"Sigma")); } END DIRECT (DataModeler_fitModel) LOOP { iam (DataModeler); DataModeler_fit (me); } END DIRECT (DataModeler_to_Covariance_parameters) LOOP { iam (DataModeler); autoCovariance thee = DataModeler_to_Covariance_parameters (me); praat_new (thee.move(), my name); } END FORM (DataModeler_to_Table_zscores, U"DataModeler: To Table (z-scores)", 0) BOOLEAN (U"Use sigmas on y-values", 1) OK DO LOOP { iam (DataModeler); autoTable thee = DataModeler_to_Table_zscores (me, GET_INTEGER (U"Use sigmas on y-values")); praat_new (thee.move(), my name, U"_z"); } END FORM (Formant_to_FormantModeler, U"Formant: To FormantModeler", 0) //double tmin, double tmax, long numberOfFormants, long numberOfParametersPerTrack REAL (U"left Start time", U"0.0") REAL (U"right End time", U"0.1") NATURAL (U"Number of formants", U"3") INTEGER (U"Order of polynomials", U"3") OPTIONMENU (U"Weigh data", 2) OPTION (U"Equally") OPTION (U"Bandwidth") OPTION (U"Bandwidth / frequency") OPTION (U"Sqrt bandwidth") OK DO long order = GET_INTEGER (U"Order of polynomials"); REQUIRE (order >= 0, U"The order must be greater than or equal to zero.") LOOP { iam (Formant); autoFormantModeler thee = Formant_to_FormantModeler (me, GET_REAL (U"left Start time"), GET_REAL (U"right End time"), GET_INTEGER (U"Number of formants"), order + 1, GET_INTEGER (U"Weigh data") - 1); praat_new (thee.move(), my name, U"_o", order); } END FORM (Formants_extractSmoothestPart, U"Formants: Extract smoothest part", U"Formants: Extract smoothest part") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") NATURAL (U"Number of formant tracks", U"4") INTEGER (U"Order of polynomials", U"3") LABEL (U"", U"Use bandwidths to model the formant tracks:") OPTIONMENU (U"Weigh data", 2) OPTION (U"Equally") OPTION (U"Bandwidth") OPTION (U"Bandwidth / frequency") OPTION (U"Sqrt bandwidth") LABEL (U"", U"Zero parameter values whose range include zero:") REAL (U"Number of sigmas", U"1.0") REAL (U"Parameter variance power", U"1.5") OK DO autoCollection set = praat_getSelectedObjects (); double tmin = GET_REAL (U"left Time range"), tmax = GET_REAL (U"right Time range"); long index = Formants_getSmoothestInInterval (set.peek(), tmin, tmax, GET_INTEGER (U"Number of formant tracks"), GET_INTEGER (U"Order of polynomials") + 1, GET_INTEGER (U"Weigh data") - 1, 0, GET_REAL (U"Number of sigmas"), GET_REAL (U"Parameter variance power"), 1, 1, 1, 1, 1); // next code is necessary to get the Formant at postion index selected and to get its name long iselected = 0; Formant him = nullptr; LOOP { iselected ++; if (iselected == index) { him = static_cast (OBJECT); } } Melder_assert (him); autoFormant thee = Formant_extractPart (him, tmin, tmax); praat_new (thee.move(), his name, U"_part"); END FORM (Formants_extractSmoothestPart_constrained, U"Formants: Extract smoothest part (constrained)", U"Formants: Extract smoothest part (constrained)...") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") NATURAL (U"Number of formant tracks", U"4") INTEGER (U"Order of polynomials", U"3") LABEL (U"", U"Use bandwidths to model the formant tracks:") OPTIONMENU (U"Weigh data", 2) OPTION (U"Equally") OPTION (U"Bandwidth") OPTION (U"Bandwidth / frequency") OPTION (U"Sqrt bandwidth") LABEL (U"", U"Zero parameter values whose range include zero:") REAL (U"Number of sigmas", U"1.0") REAL (U"Parameter variance power", U"1.5") LABEL (U"", U"The constraints on the formants:") REAL (U"Minimum F1 (Hz)", U"100.0") REAL (U"Maximum F1 (Hz)", U"1200.0") REAL (U"Minimum F2 (Hz)", U"0.0") POSITIVE (U"Maximum F2 (Hz)", U"5000.0") POSITIVE (U"Minimum F3 (Hz)", U"1500.0") OK DO autoCollection set = praat_getSelectedObjects (); double tmin = GET_REAL (U"left Time range"), tmax = GET_REAL (U"right Time range"); long index = Formants_getSmoothestInInterval (set.peek(), tmin, tmax, GET_INTEGER (U"Number of formant tracks"), GET_INTEGER (U"Order of polynomials") + 1, GET_INTEGER (U"Weigh data") - 1, 1, GET_REAL (U"Number of sigmas"), GET_REAL (U"Parameter variance power"), GET_REAL (U"Minimum F1"), GET_REAL (U"Maximum F1"), GET_REAL (U"Minimum F2"), GET_REAL (U"Maximum F2"), GET_REAL (U"Minimum F3")); // next code is necessary to get the Formant at postion index selected and to get its name long iselected = 0; Formant him = nullptr; LOOP { iselected ++; if (iselected == index) { him = static_cast (OBJECT); } } Melder_assert (him); autoFormant thee = Formant_extractPart (him, tmin, tmax); praat_new (thee.move(), his name, U"_part"); END /********************** FormantModeler ******************************/ FORM (FormantModeler_drawEstimatedTracks, U"FormantModeler: Draw estimated tracks", 0) REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") REAL (U"Maximum frequency (Hz)", U"5500.0") NATURAL (U"left Formant range", U"1") NATURAL (U"right Formant range", U"3") INTEGER (U"Order of polynomials for estimation", U"3") REAL (U"Horizontal offset (mm)", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; long order = GET_INTEGER (U"Order of polynomials for estimation"); REQUIRE (order >= 0, U"The order must be greater than or equal to zero.") LOOP { iam (FormantModeler); FormantModeler_drawTracks (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"Maximum frequency"), GET_INTEGER (U"left Formant range"), GET_INTEGER (U"right Formant range"), 1, order + 1, GET_REAL (U"Horizontal offset"), GET_INTEGER (U"Garnish")); } END FORM (FormantModeler_drawTracks, U"FormantModeler: Draw tracks", 0) REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") REAL (U"Maximum frequency (Hz)", U"5500.0") NATURAL (U"left Formant range", U"1") NATURAL (U"right Formant range", U"3") REAL (U"Horizontal offset (mm)", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; long order = 6; LOOP { iam (FormantModeler); FormantModeler_drawTracks (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"Maximum frequency"), GET_INTEGER (U"left Formant range"), GET_INTEGER (U"right Formant range"), 0, order + 1, GET_REAL (U"Horizontal offset"), GET_INTEGER (U"Garnish")); } END FORM (FormantModeler_speckle, U"FormantModeler: Speckle", 0) REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") REAL (U"Maximum frequency (Hz)", U"5500.0") NATURAL (U"left Formant range", U"1") NATURAL (U"right Formant range", U"3") BOOLEAN (U"Draw error bars", 1) REAL (U"Bar width (mm)", U"1.0") REAL (U"Horizontal offset (mm)", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; long order = 6; LOOP { iam (FormantModeler); FormantModeler_speckle (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"Maximum frequency"), GET_INTEGER (U"left Formant range"), GET_INTEGER (U"right Formant range"), 0, order + 1, GET_INTEGER (U"Draw error bars"), GET_REAL (U"Bar width"), GET_REAL (U"Horizontal offset"), GET_INTEGER (U"Garnish")); } END FORM (FormantModeler_drawOutliersMarked, U"FormantModeler: Draw outliers marked", 0) REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") REAL (U"Maximum frequency (Hz)", U"5500.0") NATURAL (U"left Formant range", U"1") NATURAL (U"right Formant range", U"3") POSITIVE (U"Number of sigmas", U"3.0") OPTIONMENU (U"Weigh data", 2) OPTION (U"Equally") OPTION (U"Bandwidth") OPTION (U"Bandwidth / frequency") OPTION (U"Sqrt bandwidth") WORD (U"Mark", U"o") NATURAL (U"Mark font size", U"12") REAL (U"Horizontal offset (mm)", U"0.0") BOOLEAN (U"Garnish", 0) OK DO autoPraatPicture picture; LOOP { iam (FormantModeler); FormantModeler_drawOutliersMarked (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"Maximum frequency"), GET_INTEGER (U"left Formant range"), GET_INTEGER (U"right Formant range"), GET_REAL (U"Number of sigmas"), GET_INTEGER (U"Weigh data") - 1, GET_STRING (U"Mark"), GET_INTEGER (U"Mark font size"), GET_REAL (U"Horizontal offset"), GET_INTEGER (U"Garnish")); } END FORM (FormantModeler_drawVariancesOfShiftedTracks, U"FormantModeler: Draw variances of shifted tracks", 0) REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range", U"0.0") REAL (U"left Variance range", U"0.0") REAL (U"right Variance range", U"0.0") OPTIONMENU (U"Shift tracks", 1) OPTION (U"No") OPTION (U"Up") OPTION (U"Down") NATURAL (U"left Formant range", U"1") NATURAL (U"right Formant range", U"4") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (FormantModeler); FormantModeler_drawVariancesOfShiftedTracks (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Variance range"), GET_REAL (U"right Variance range"), GET_INTEGER (U"Shift tracks"), GET_INTEGER (U"left Formant range"), GET_INTEGER (U"right Formant range"), GET_INTEGER (U"Garnish")); } END FORM (FormantModeler_drawCumulativeChiScores, U"FormantModeler: Draw cumulative chi scores", 0) REAL (U"left Time range", U"0.0") REAL (U"right Time range", U"0.0") REAL (U"left Chisq range", U"0.0") REAL (U"right Chisq range", U"0.0") OPTIONMENU (U"Weigh data", 2) OPTION (U"Equally") OPTION (U"Bandwidth") OPTION (U"Bandwidth / frequency") OPTION (U"Sqrt bandwidth") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (FormantModeler); FormantModeler_drawCumulativeChiScores (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Chisq range"), GET_REAL (U"right Chisq range"), GET_INTEGER (U"Weigh data"), GET_INTEGER (U"Garnish")); } END FORM (FormantModeler_normalProbabilityPlot, U"FormantModeler: Normal probability plot", 0) NATURAL (U"Formant number", U"1") OPTIONMENU (U"Weigh data", 2) OPTION (U"Equally") OPTION (U"Bandwidth") OPTION (U"Bandwidth / frequency") OPTION (U"Sqrt bandwidth") NATURAL (U"Number of quantiles", U"100") REAL (U"Number of sigmas", U"0.0") NATURAL (U"Label size", U"12") WORD (U"Label", U"+") BOOLEAN (U"Garnish", 1); OK DO autoPraatPicture picture; LOOP { iam (FormantModeler); FormantModeler_normalProbabilityPlot (me, GRAPHICS, GET_INTEGER (U"Formant number"), GET_INTEGER (U"Weigh data") - 1, GET_INTEGER (U"Number of quantiles"), GET_REAL (U"Number of sigmas"), GET_INTEGER (U"Label size"), GET_STRING (U"Label"), GET_INTEGER (U"Garnish")); } END FORM (FormantModeler_drawBasisFunction, U"FormantModeler: Draw basis function", 0) REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") REAL (U"left Amplitude range (Hz)", U"0.0") REAL (U"right Amplitude range (Hz)", U"5500.0") //long iterm, bool scaled, long numberOfPoints, int garnish NATURAL (U"Formant number", U"1") NATURAL (U"Basis function", U"2") BOOLEAN (U"Scale function with parameter value", 0) NATURAL (U"Number of points", U"200") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (FormantModeler); FormantModeler_drawBasisFunction (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range"),GET_INTEGER (U"Formant number"), GET_INTEGER (U"Basis function"), GET_INTEGER (U"Scale function with parameter value"), GET_INTEGER (U"Number of points"), GET_INTEGER (U"Garnish")); } END FORM (FormantModeler_getModelValueAtTime, U"", 0) NATURAL (U"Formant number", U"1") REAL (U"Time (s)", U"0.1") OK DO LOOP { iam (FormantModeler); double y = FormantModeler_getModelValueAtTime (me, GET_INTEGER (U"Formant number"), GET_REAL (U"Time")); Melder_informationReal (y, U"Hertz"); } END FORM (FormantModeler_getDataPointValue, U"FormantModeler: Get data point value", 0) NATURAL (U"Formant number", U"1") NATURAL (U"Index", U"1") OK DO long iformant = GET_INTEGER (U"Formant number"); long index = GET_INTEGER (U"Index"); LOOP { iam (FormantModeler); double value = FormantModeler_getDataPointValue (me, iformant, index); Melder_information (value, U" (= value of point ", index, U" in track F", iformant, U")"); } END FORM (FormantModeler_getDataPointSigma, U"FormantModeler: Get data point sigma", 0) NATURAL (U"Formant number", U"1") NATURAL (U"Index", U"1") OK DO long iformant = GET_INTEGER (U"Formant number"); long index = GET_INTEGER (U"Index"); LOOP { iam (FormantModeler); double value = FormantModeler_getDataPointSigma (me, iformant, index); Melder_information (value, U" (= sigma of point ", index, U" in track F", iformant, U")"); } END FORM (FormantModeler_getDataPointStatus, U"FormantModeler: Get data point status", 0) NATURAL (U"Formant number", U"1") NATURAL (U"Index", U"1") OK DO long iformant = GET_INTEGER (U"Formant number"); long index = GET_INTEGER (U"Index"); LOOP { iam (FormantModeler); int status = FormantModeler_getDataPointStatus (me, iformant, index); Melder_information (status == DataModeler_DATA_INVALID ? U"Invalid" : U"Valid"); } END DIRECT (FormantModeler_getNumberOfTracks) LOOP { iam (FormantModeler); long nop = FormantModeler_getNumberOfTracks (me); Melder_information (nop, U" (= number of formants)"); } END FORM (FormantModeler_getNumberOfParameters, U"FormantModeler: Get number of parameters", 0) NATURAL (U"Formant number", U"1") OK DO long iformant = GET_INTEGER (U"Formant number"); LOOP { iam (FormantModeler); long nop = FormantModeler_getNumberOfParameters (me, iformant); Melder_information (nop, U" (= number of parameters for F", iformant, U")"); } END FORM (FormantModeler_getNumberOfFixedParameters, U"FormantModeler: Get number of fixed parameters", 0) NATURAL (U"Formant number", U"1") OK DO long iformant = GET_INTEGER (U"Formant number"); LOOP { iam (FormantModeler); long nop = FormantModeler_getNumberOfFixedParameters (me, iformant); Melder_information (nop, U" (= number of fixed parameters for F", iformant, U")"); } END DIRECT (FormantModeler_getNumberOfDataPoints) LOOP { iam (FormantModeler); long numberOfDataPoints = FormantModeler_getNumberOfDataPoints (me); Melder_information (numberOfDataPoints); } END FORM (FormantModeler_getNumberOfInvalidDataPoints, U"FormantModeler: Get number of invalid data points", 0) NATURAL (U"Formant number", U"1") OK DO long iformant = GET_INTEGER (U"Formant number"); LOOP { iam (FormantModeler); long numberOfInvalidDataPoints = FormantModeler_getNumberOfInvalidDataPoints (me, iformant); Melder_information (numberOfInvalidDataPoints, U" (= number of invalid data points for F", iformant, U")"); } END FORM (FormantModeler_getParameterValue, U"FormantModeler: Get parameter value", 0) NATURAL (U"Formant number", U"1") NATURAL (U"Parameter number", U"1") OK DO long iformant = GET_INTEGER (U"Formant number"), iparameter = GET_INTEGER (U"Parameter number"); LOOP { iam (FormantModeler); double parameter = FormantModeler_getParameterValue (me, iformant, iparameter); Melder_information (parameter, U" (= parameter[", iparameter, U"] for F", iformant, U")"); } END FORM (FormantModeler_getParameterStatus, U"FormantModeler: Get parameter status", 0) NATURAL (U"Formant number", U"1") NATURAL (U"Parameter number", U"1") OK DO long iformant = GET_INTEGER (U"Formant number"), iparameter = GET_INTEGER (U"Parameter number"); LOOP { iam (FormantModeler); int status = FormantModeler_getParameterStatus (me, iformant, iparameter); Melder_information (status == DataModeler_PARAMETER_FREE ? U"Free" : (status == DataModeler_PARAMETER_FIXED ? U"Fixed" : U"Undefined"), U" (= parameter[", iparameter, U"] for F", iformant, U")"); } END FORM (FormantModeler_getParameterStandardDeviation, U"FormantModeler: Get parameter standard deviatio", 0) NATURAL (U"Formant number", U"1") NATURAL (U"Parameter number", U"1") OK DO long iformant = GET_INTEGER (U"Formant number"), iparameter = GET_INTEGER (U"Parameter number"); LOOP { iam (FormantModeler); double sigma = FormantModeler_getParameterStandardDeviation (me, iformant, iparameter); Melder_information (sigma, U" (= parameter[", iparameter, U"] for F", iformant, U")"); } END FORM (FormantModeler_getVarianceOfParameters, U"FormantModeler: Get variance of parameters", 0) INTEGER (U"left Formant range", U"0") INTEGER (U"right Formant range", U"0") INTEGER (U"left Parameter range", U"0") INTEGER (U"right Parameter range", U"0") OK DO long nofp; LOOP { iam (FormantModeler); double var = FormantModeler_getVarianceOfParameters (me, GET_INTEGER (U"left Formant range"), GET_INTEGER (U"right Formant range"), GET_INTEGER (U"left Parameter range"), GET_INTEGER (U"right Parameter range"), &nofp); Melder_information (var, U" (for ", nofp, U" free parameters.)"); } END FORM (FormantModeler_getCoefficientOfDetermination, U"FormantModeler: Get coefficient of determination", 0) INTEGER (U"left Formant range", U"0") INTEGER (U"right Formant range", U"0") OK DO LOOP { iam (FormantModeler); double rSquared = FormantModeler_getCoefficientOfDetermination (me, GET_INTEGER (U"left Formant range"), GET_INTEGER (U"right Formant range")); Melder_informationReal (rSquared, U" (= R^2)"); } END FORM (FormantModeler_getResidualSumOfSquares, U"FormantModeler: Get residual sum of squares", U"FormantModeler: Get residual sum of squares...") NATURAL (U"Formant number", U"1") OK DO long n, iformant = GET_INTEGER (U"Formant number"); LOOP { iam (FormantModeler); double rss = FormantModeler_getResidualSumOfSquares (me, iformant, &n); Melder_information (rss, U" Hz^2, (= RSS of F", iformant, U")"); } END FORM (FormantModeler_getStandardDeviation, U"FormantModeler: Get formant standard deviation", 0) NATURAL (U"Formant number", U"1") OK DO long iformant = GET_INTEGER (U"Formant number"); LOOP { iam (FormantModeler); double sigma = FormantModeler_getStandardDeviation (me, iformant); Melder_information (sigma, U" Hz (= std. dev. of F", iformant, U")"); } END FORM (FormantModeler_reportChiSquared, U"FormantModeler: Report chi squared", 0) OPTIONMENU (U"Weigh data", 2) OPTION (U"Equally") OPTION (U"Bandwidth") OPTION (U"Bandwidth / frequency") OPTION (U"Sqrt bandwidth") OK DO LOOP { iam (FormantModeler); long numberOfFormants = my trackmodelers -> size; int useSigmaY = GET_INTEGER (U"Weigh data") - 1; double chisq = 0, ndf = 0, probability; MelderInfo_open (); MelderInfo_writeLine (U"Chi squared tests for individual models of each of ", numberOfFormants, U" formant track:"); MelderInfo_writeLine (useSigmaY == DataModeler_DATA_WEIGH_EQUAL ? U"Standard deviation is estimated from the data." : useSigmaY == DataModeler_DATA_WEIGH_SIGMA ? U"\tBandwidths are used as estimate for local standard deviations." : useSigmaY == DataModeler_DATA_WEIGH_RELATIVE ? U"\t1/Q's are used as estimate for local standard deviations." : U"\tSqrt bandwidths are used as estimate for local standard deviations."); for (long iformant = 1; iformant <= numberOfFormants; iformant++) { chisq = FormantModeler_getChiSquaredQ (me, iformant, iformant, useSigmaY, &probability, &ndf); MelderInfo_writeLine (U"Formant track ", iformant, U":"); MelderInfo_writeLine (U"\tChi squared (F", iformant, U") = ", chisq); MelderInfo_writeLine (U"\tProbability (F", iformant, U") = ", probability); MelderInfo_writeLine (U"\tNumber of degrees of freedom (F", iformant, U") = ", ndf); } chisq = FormantModeler_getChiSquaredQ (me, 1, numberOfFormants, useSigmaY, &probability, &ndf); MelderInfo_writeLine (U"Chi squared test for the complete model with ", numberOfFormants, U" formants:"); MelderInfo_writeLine (U"\tChi squared = ", chisq); MelderInfo_writeLine (U"\tProbability = ", probability); MelderInfo_writeLine (U"\tNumber of degrees of freedom = ", ndf); MelderInfo_close (); } END FORM (FormantModeler_getDegreesOfFreedom, U"FormantModeler: Get degrees of freedom", 0) NATURAL (U"Formant number", U"1") OK DO long iformant = GET_INTEGER (U"Formant number"); LOOP { iam (FormantModeler); double sigma = FormantModeler_getDegreesOfFreedom (me, iformant); Melder_information (sigma, U" (= degrees of freedom of F", iformant, U")"); } END FORM (FormantModeler_getSmoothnessValue, U"FormantModeler: Get smoothness value", 0) INTEGER (U"left Formant range", U"0") INTEGER (U"right Formant range", U"0") INTEGER (U"Order of polynomials", U"3") REAL (U"Parameter variance power", U"1.5") OK DO LOOP { iam (FormantModeler); double smoothness = FormantModeler_getSmoothnessValue (me, GET_INTEGER (U"left Formant range"), GET_INTEGER (U"right Formant range"), GET_INTEGER (U"Order of polynomials"), GET_REAL (U"Parameter variance power")); Melder_information (smoothness, U" (= smoothness)"); } END FORM (FormantModeler_getAverageDistanceBetweenTracks, U"FormantModeler: Get average distance between tracks", 0) NATURAL (U"Track 1", U"2") NATURAL (U"Track 2", U"3") OPTIONMENU (U"Type of data", 1) OPTION (U"Data points") OPTION (U"Modeled") OK DO long track1 = GET_INTEGER (U"Track 1"), track2 = GET_INTEGER (U"Track 2"); LOOP { iam (FormantModeler); double distance = FormantModeler_getAverageDistanceBetweenTracks (me, track1, track2, GET_INTEGER (U"Type of data") - 1); Melder_information (distance, U" (= average |F", track1, U" - F", track2, U"|)"); } END FORM (FormantModeler_getFormantsConstraintsFactor, U"FormantModeler: Get formants constraints factor", 0) REAL (U"Minimum F1 (Hz)", U"100.0") REAL (U"Maximum F1 (Hz)", U"1200.0") REAL (U"Minimum F2 (Hz)", U"0.0") POSITIVE (U"Maximum F2 (Hz)", U"5000.0") POSITIVE (U"Minimum F3 (Hz)", U"1500.0") OK DO LOOP { iam (FormantModeler); double fc = FormantModeler_getFormantsConstraintsFactor (me, GET_REAL (U"Minimum F1"), GET_REAL (U"Maximum F1"), GET_REAL (U"Minimum F2"), GET_REAL (U"Maximum F2"), GET_REAL (U"Minimum F3")); Melder_information (fc, U" (= formants constraints factor)"); } END FORM (FormantModeler_setDataWeighing, U"FormantModeler: Set data weighing", 0) INTEGER (U"left Formant range", U"0") INTEGER (U"right Formant range", U"0") OPTIONMENU (U"Weigh data", 2) OPTION (U"Equally") OPTION (U"Bandwidth") OPTION (U"Bandwidth / frequency") OPTION (U"Sqrt bandwidth") OK DO LOOP { iam (FormantModeler); FormantModeler_setDataWeighing (me, GET_INTEGER (U"left Formant range"), GET_INTEGER (U"right Formant range"), GET_INTEGER (U"Weigh data") - 1); } END FORM (FormantModeler_setTolerance, U"FormantModeler: Set tolerance", 0) REAL (U"Tolerance", U"1e-5") OK DO LOOP { iam (FormantModeler); FormantModeler_setTolerance (me, GET_REAL (U"Tolerance")); } END FORM (FormantModeler_setParameterValueFixed, U"FormantModeler: Set parameter value fixed", 0) NATURAL (U"Formant number", U"1") NATURAL (U"Parameter number", U"1") REAL (U"Value", U"0.0") OK DO LOOP { iam (FormantModeler); FormantModeler_setParameterValueFixed (me, GET_INTEGER (U"Formant number"), GET_INTEGER (U"Parameter number"), GET_REAL (U"Value")); } END FORM (FormantModeler_setParameterFree, U"FormantModeler: Set parameter free", 0) INTEGER (U"left Formant range", U"0") INTEGER (U"right Formant range", U"0") INTEGER (U"left Parameter range", U"0") INTEGER (U"right Parameter range", U"0") OK DO LOOP { iam (FormantModeler); FormantModeler_setParametersFree (me, GET_INTEGER (U"left Formant range"), GET_INTEGER (U"right Formant range"), GET_INTEGER (U"left Parameter range"), GET_INTEGER (U"right Parameter range")); } END FORM (FormantModeler_setParameterValuesToZero, U"FormantModeler: Set parameter values to zero", 0) INTEGER (U"left Formant range", U"0") INTEGER (U"right Formant range", U"0") REAL (U"Number of sigmas", U"1.0") OK DO LOOP { iam (FormantModeler); FormantModeler_setParameterValuesToZero (me, GET_INTEGER (U"left Formant range"), GET_INTEGER (U"right Formant range"), GET_REAL (U"Number of sigmas")); } END FORM (FormantModeler_setDataPointValue, U"FormantModeler: Set data point value", 0) NATURAL (U"Formant index", U"1") NATURAL (U"Data index", U"1") REAL (U"Value", U"1.0") OK DO LOOP { iam (FormantModeler); FormantModeler_setDataPointValue (me, GET_INTEGER (U"Formant index"), GET_INTEGER (U"Data index"), GET_REAL (U"Value")); } END FORM (FormantModeler_setDataPointSigma, U"FormantModeler: Set data point sigma", 0) NATURAL (U"Formant index", U"1") NATURAL (U"Data index", U"1") REAL (U"Sigma", U"10.0") OK DO LOOP { iam (FormantModeler); FormantModeler_setDataPointSigma (me, GET_INTEGER (U"Formant index"), GET_INTEGER (U"Data index"), GET_REAL (U"Sigma")); } END FORM (FormantModeler_setDataPointStatus, U"FormantModeler: Set data point status", 0) NATURAL (U"Formant index", U"1") NATURAL (U"Data index", U"1") OPTIONMENU (U"Status", 1) OPTION (U"Valid") OPTION (U"Invalid") OK DO int menustatus = GET_INTEGER (U"Status"); int status = menustatus == 2 ? DataModeler_DATA_INVALID : DataModeler_DATA_VALID; LOOP { iam (FormantModeler); FormantModeler_setDataPointStatus (me, GET_INTEGER (U"Formant index"), GET_INTEGER (U"Data index"), status); } END DIRECT (FormantModeler_fitModel) LOOP { iam (FormantModeler); FormantModeler_fit (me); } END FORM (FormantModeler_to_Covariance_parameters, U"", 0) NATURAL (U"Formant number", U"1") OK DO long iformant = GET_INTEGER (U"Formant number"); LOOP { iam (FormantModeler); autoCovariance thee = FormantModeler_to_Covariance_parameters (me, iformant); praat_new (thee.move(), my name, U"_", iformant); } END FORM (FormantModeler_extractDataModeler, U"FormantModeler: Extract DataModeler", 0) NATURAL (U"Formant number", U"1") OK DO long iformant = GET_INTEGER (U"Formant number"); LOOP { iam (FormantModeler); autoDataModeler thee = FormantModeler_extractDataModeler (me, iformant); praat_new (thee.move(), my name, U"_", iformant); } END FORM (FormantModeler_to_Table_zscores, U"", 0) BOOLEAN (U"Bandwidths as standard deviation", 1) OK DO LOOP { iam (FormantModeler); autoTable thee = FormantModeler_to_Table_zscores (me, GET_INTEGER (U"Bandwidths as standard deviation")); praat_new (thee.move(), my name, U"_z"); } END FORM (FormantModeler_processOutliers, U"", 0) POSITIVE (U"Number of sigmas", U"3.0") BOOLEAN (U"Bandwidths as standard deviation", 1) OK DO LOOP { iam (FormantModeler); autoFormantModeler thee = FormantModeler_processOutliers (me, GET_REAL (U"Number of sigmas"), GET_INTEGER (U"Bandwidths as standard deviation")); praat_new (thee.move(), my name, U"_outliers"); } END DIRECT (OptimalCeilingTier_edit) if (theCurrentPraatApplication -> batch) Melder_throw (U"Cannot view or edit an OptimalCeilingTier from batch."); Sound sound = nullptr; LOOP { if (CLASS == classSound) { sound = (Sound) OBJECT; // may stay nullptr } } LOOP if (CLASS == classOptimalCeilingTier) { iam (OptimalCeilingTier); autoOptimalCeilingTierEditor editor = OptimalCeilingTierEditor_create (ID_AND_FULL_NAME, me, sound, true); praat_installEditor (editor.transfer(), IOBJECT); } END /*************************** PitchModeler *************************************/ FORM (Pitch_to_PitchModeler, U"Pitch: To PitchModeler", 0) REAL (U"left Start time (s)", U"0.0") REAL (U"right End time (s)", U"0.1") INTEGER (U"Order of polynomials", U"2") OK DO LOOP { iam (Pitch); autoPitchModeler thee = Pitch_to_PitchModeler (me, GET_REAL (U"left Start time"), GET_REAL (U"right End time"), GET_INTEGER (U"Order of polynomials") + 1); praat_new (thee.move(), my name); } END FORM (PitchModeler_draw, U"PitchModeler: Draw", 0) REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") REAL (U"left Frequency range (Hz)", U"0.0") REAL (U"right Frequency range (Hz)", U"500.0") INTEGER (U"Order of polynomial for estimation", U"2") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (PitchModeler); PitchModeler_draw (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Frequency range"), GET_REAL (U"right Frequency range"), GET_INTEGER (U"Order of polynomial for estimation") + 1, GET_INTEGER (U"Garnish")); } END FORM (Sound_getOptimalFormantCeiling, U"Sound: Get optimal formant ceiling", 0) REAL (U"left Time range (s)", U"0.1") REAL (U"right Time range (s)", U"0.15") POSITIVE (U"Window length (s)", U"0.015") POSITIVE (U"Time step (s)", U"0.0025") POSITIVE (U"left Maximum frequency range (Hz)", U"4500.0") POSITIVE (U"right Maximum frequency range (Hz)", U"6500.0") NATURAL (U"Number of frequency steps", U"11") POSITIVE (U"Pre-emphasis from (Hz)", U"50.0") NATURAL (U"Number of formant tracks in model", U"4") INTEGER (U"Order of polynomials", U"3") OPTIONMENU (U"Weigh data", 2) OPTION (U"Equally") OPTION (U"Bandwidth") OPTION (U"Bandwidth / frequency") OPTION (U"Sqrt bandwidth") LABEL (U"", U"Make parameters that include zero in their confidence region zero") REAL (U"Number of sigmas", U"1.0") REAL (U"Parameter variance power", U"1.5") OK DO LOOP { iam (Sound); double ceiling = Sound_getOptimalFormantCeiling (me, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"Window length"), GET_REAL (U"Time step"), GET_REAL (U"left Maximum frequency range"), GET_REAL (U"right Maximum frequency range"), GET_INTEGER (U"Number of frequency steps"), GET_REAL (U"Pre-emphasis from"), GET_INTEGER (U"Number of formant tracks in model"), GET_INTEGER (U"Order of polynomials") + 1, GET_INTEGER (U"Weigh data") - 1, GET_REAL (U"Number of sigmas"), GET_REAL (U"Parameter variance power")); Melder_informationReal (ceiling, U" Hz"); } END FORM (Sound_to_Formant_interval, U"Sound: To Formant (interval)", 0) REAL (U"left Time range (s)", U"0.1") REAL (U"right Time range (s)", U"0.15") POSITIVE (U"Window length (s)", U"0.015") POSITIVE (U"Time step (s)", U"0.0025") POSITIVE (U"left Maximum frequency range (Hz)", U"4500.0") POSITIVE (U"right Maximum frequency range (Hz)", U"6500.0") NATURAL (U"Number of frequency steps", U"11") POSITIVE (U"Pre-emphasis from (Hz)", U"50.0") NATURAL (U"Number of formant tracks in model", U"4") INTEGER (U"Order of polynomials", U"3") OPTIONMENU (U"Weigh data", 2) OPTION (U"Equally") OPTION (U"Bandwidth") OPTION (U"Bandwidth / frequency") OPTION (U"Sqrt bandwidth") LABEL (U"", U"Make parameters that include zero in their confidence region zero") REAL (U"Number of sigmas", U"1.0") REAL (U"Parameter variance power", U"1.5") OK DO LOOP { iam (Sound); double ceiling; autoFormant formant = Sound_to_Formant_interval (me, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"Window length"), GET_REAL (U"Time step"), GET_REAL (U"left Maximum frequency range"), GET_REAL (U"right Maximum frequency range"), GET_INTEGER (U"Number of frequency steps"), GET_REAL (U"Pre-emphasis from"), GET_INTEGER (U"Number of formant tracks in model"), GET_INTEGER (U"Order of polynomials") + 1, GET_INTEGER (U"Weigh data") - 1, GET_REAL (U"Number of sigmas"), GET_REAL (U"Parameter variance power"), 0, 1, 1, 1, 1, 1, &ceiling); praat_new (formant.move(), my name, U"_", Melder_fixed (ceiling, 0)); } END FORM (Sound_to_Formant_interval_constrained, U"Sound: To Formant (interval, constrained)", 0) REAL (U"left Time range (s)", U"0.1") REAL (U"right Time range (s)", U"0.15") POSITIVE (U"Window length (s)", U"0.015") POSITIVE (U"Time step (s)", U"0.0025") POSITIVE (U"left Maximum frequency range (Hz)", U"4500.0") POSITIVE (U"right Maximum frequency range (Hz)", U"6500.0") NATURAL (U"Number of frequency steps", U"11") POSITIVE (U"Pre-emphasis from (Hz)", U"50.0") NATURAL (U"Number of formant tracks in model", U"4") INTEGER (U"Order of polynomials", U"3") OPTIONMENU (U"Weigh data", 2) OPTION (U"Equally") OPTION (U"Bandwidth") OPTION (U"Bandwidth / frequency") OPTION (U"Sqrt bandwidth") LABEL (U"", U"Make parameters that include zero in their confidence region zero") REAL (U"Number of sigmas", U"1.0") REAL (U"Parameter variance power", U"1.5") LABEL (U"", U"Formant frequency constraints") REAL (U"Minimum F1 (Hz)", U"100.0") REAL (U"Maximum F1 (Hz)", U"1200.0") REAL (U"Minimum F2 (Hz)", U"0.0") POSITIVE (U"Maximum F2 (Hz)", U"5000.0") POSITIVE (U"Minimum F3 (Hz)", U"1000.0") OK DO LOOP { iam (Sound); double ceiling; autoFormant formant = Sound_to_Formant_interval (me, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"Window length"), GET_REAL (U"Time step"), GET_REAL (U"left Maximum frequency range"), GET_REAL (U"right Maximum frequency range"), GET_INTEGER (U"Number of frequency steps"), GET_REAL (U"Pre-emphasis from"), GET_INTEGER (U"Number of formant tracks in model"), GET_INTEGER (U"Order of polynomials") + 1, GET_INTEGER (U"Weigh data") - 1, GET_REAL (U"Number of sigmas"), GET_REAL (U"Parameter variance power"), 1, GET_REAL (U"Minimum F1"), GET_REAL (U"Maximum F1"), GET_REAL (U"Minimum F2"), GET_REAL (U"Maximum F2"), GET_REAL (U"Minimum F3"), &ceiling); praat_new (formant.move(), my name, U"_", Melder_fixed (ceiling, 0)); } END FORM (Sound_to_Formant_interval_constrained_robust, U"Sound: To Formant (interval, constrained, robust)", 0) REAL (U"left Time range (s)", U"0.1") REAL (U"right Time range (s)", U"0.15") POSITIVE (U"Window length (s)", U"0.015") POSITIVE (U"Time step (s)", U"0.0025") POSITIVE (U"left Maximum frequency range (Hz)", U"4500.0") POSITIVE (U"right Maximum frequency range (Hz)", U"6500.0") NATURAL (U"Number of frequency steps", U"11") POSITIVE (U"Pre-emphasis from (Hz)", U"50.0") NATURAL (U"Number of formant tracks in model", U"4") INTEGER (U"Order of polynomials", U"3") OPTIONMENU (U"Weigh data", 2) OPTION (U"Equally") OPTION (U"Bandwidth") OPTION (U"Bandwidth / frequency") OPTION (U"Sqrt bandwidth") LABEL (U"", U"Make parameters that include zero in their confidence region zero") REAL (U"Number of sigmas", U"1.0") REAL (U"Parameter variance power", U"1.5") LABEL (U"", U"Formant frequency constraints") REAL (U"Minimum F1 (Hz)", U"100.0") REAL (U"Maximum F1 (Hz)", U"1200.0") REAL (U"Minimum F2 (Hz)", U"0.0") POSITIVE (U"Maximum F2 (Hz)", U"5000.0") POSITIVE (U"Minimum F3 (Hz)", U"1000.0") OK DO LOOP { iam (Sound); double ceiling; autoFormant formant = Sound_to_Formant_interval_robust (me, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"Window length"), GET_REAL (U"Time step"), GET_REAL (U"left Maximum frequency range"), GET_REAL (U"right Maximum frequency range"), GET_INTEGER (U"Number of frequency steps"), GET_REAL (U"Pre-emphasis from"), GET_INTEGER (U"Number of formant tracks in model"), GET_INTEGER (U"Order of polynomials") + 1, GET_INTEGER (U"Weigh data") - 1, GET_REAL (U"Number of sigmas"), GET_REAL (U"Parameter variance power"), 1, GET_REAL (U"Minimum F1"), GET_REAL (U"Maximum F1"), GET_REAL (U"Minimum F2"), GET_REAL (U"Maximum F2"), GET_REAL (U"Minimum F3"), &ceiling); praat_new (formant.move(), my name, U"_", Melder_fixed (ceiling, 0)); } END FORM (Sound_to_OptimalCeilingTier, U"", 0) POSITIVE (U"Window length (s)", U"0.015") POSITIVE (U"Time step (s)", U"0.0025") POSITIVE (U"left Maximum frequency range (Hz)", U"4500.0") POSITIVE (U"right Maximum frequency range (Hz)", U"6500.0") NATURAL (U"Number of frequency steps", U"11") POSITIVE (U"Pre-emphasis from (Hz)", U"50.0") REAL (U"Formant smoothing window (s)", U"0.05") NATURAL (U"Number of formant tracks in model", U"4") INTEGER (U"Order of polynomials", U"2") OPTIONMENU (U"Weigh data", 2) OPTION (U"Equally") OPTION (U"Bandwidth") OPTION (U"Bandwidth / frequency") OPTION (U"Sqrt bandwidth") LABEL (U"", U"Make parameters that include zero in their confidence region zero") REAL (U"Number of sigmas", U"1.0") REAL (U"Parameter variance power", U"1.5") OK DO LOOP { iam (Sound); autoOptimalCeilingTier octier = Sound_to_OptimalCeilingTier (me, GET_REAL (U"Window length"), GET_REAL (U"Time step"), GET_REAL (U"left Maximum frequency range"), GET_REAL (U"right Maximum frequency range"), GET_INTEGER (U"Number of frequency steps"), GET_REAL (U"Pre-emphasis from"), GET_REAL (U"Formant smoothing window"), GET_INTEGER (U"Number of formant tracks in model"), GET_INTEGER (U"Order of polynomials") + 1, GET_INTEGER (U"Weigh data") - 1, GET_REAL (U"Number of sigmas"), GET_REAL (U"Parameter variance power")); praat_new (octier.move(), my name); } END FORM (Table_to_DataModeler, U"", 0) REAL (U"left X range", U"0.0") REAL (U"right X range", U"0.0 (=auto)") WORD (U"Column with X data", U"") WORD (U"Column with Y data", U"") WORD (U"Column with sigmas", U"") OPTIONMENU (U"Model functions", 1) OPTION (U"Legendre polynomials") INTEGER (U"Maximum order", U"3") OK DO LOOP { iam (Table); long xcolumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Column with X data")); long ycolumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Column with Y data")); long scolumn = Table_findColumnIndexFromColumnLabel (me, GET_STRING (U"Column with sigmas")); autoDataModeler thee = Table_to_DataModeler (me, GET_REAL (U"left X range"), GET_REAL (U"right X range"), xcolumn, ycolumn, scolumn, GET_INTEGER (U"Maximum order") + 1, GET_INTEGER (U"Model functions")); praat_new (thee.move(), my name); } END void praat_DataModeler_init (); void praat_DataModeler_init () { Thing_recognizeClassesByName (classDataModeler, classFormantModeler, classOptimalCeilingTier, classOptimalCeilingTierEditor, classPitchModeler, nullptr); praat_addMenuCommand (U"Objects", U"New", U"Create simple DataModeler...", U"Create ISpline...", praat_HIDDEN + praat_DEPTH_1, DO_DataModeler_createSimple); praat_addAction1 (classDataModeler, 0, U"Speckle...", 0, 0, DO_DataModeler_speckle); praat_addAction1 (classDataModeler, 0, U"Draw estimated track...", 0, 0, DO_DataModeler_drawEstimatedTrack); praat_addAction1 (classDataModeler, 1, U"Query -", 0, 0, 0); praat_addAction1 (classDataModeler, 0, U"Get number of parameters", 0, 1, DO_DataModeler_getNumberOfParameters); praat_addAction1 (classDataModeler, 0, U"Get number of fixed parameters", 0, 1, DO_DataModeler_getNumberOfFixedParameters); praat_addAction1 (classDataModeler, 0, U"Get parameter value...", 0, 1, DO_DataModeler_getParameterValue); praat_addAction1 (classDataModeler, 0, U"Get parameter status...", 0, 1, DO_DataModeler_getParameterStatus); praat_addAction1 (classDataModeler, 0, U"Get parameter standard deviation...", 0, 1, DO_DataModeler_getParameterStandardDeviation); praat_addAction1 (classDataModeler, 0, U"Get variance of parameters...", 0, 1, DO_DataModeler_getVarianceOfParameters); praat_addAction1 (classDataModeler, 1, U"-- get data points info --", 0, 1, 0); praat_addAction1 (classDataModeler, 0, U"Get model value at x...", 0, 1, DO_DataModeler_getModelValueAtX); praat_addAction1 (classDataModeler, 0, U"Get number of data points", 0, 1, DO_DataModeler_getNumberOfDataPoints); praat_addAction1 (classDataModeler, 0, U"Get number of invalid data points", 0, 1, DO_DataModeler_getNumberOfInvalidDataPoints); praat_addAction1 (classDataModeler, 0, U"Get data point value...", 0, 1, DO_DataModeler_getDataPointValue); praat_addAction1 (classDataModeler, 0, U"Get data point sigma...", 0, 1, DO_DataModeler_getDataPointSigma); praat_addAction1 (classDataModeler, 0, U"Get data point status...", 0, 1, DO_DataModeler_getDataPointStatus); praat_addAction1 (classDataModeler, 1, U"-- get statistics info --", 0, 1, 0); praat_addAction1 (classDataModeler, 0, U"Get residual sum of squares", 0, 1, DO_DataModeler_getResidualSumOfSquares); praat_addAction1 (classDataModeler, 0, U"Get data standard deviation", 0, 1, DO_DataModeler_getStandardDeviation); praat_addAction1 (classDataModeler, 0, U"Get coefficient of determination", 0, 1, DO_DataModeler_getCoefficientOfDetermination); praat_addAction1 (classDataModeler, 0, U"Report chi squared...", 0, 1, DO_DataModeler_reportChiSquared); praat_addAction1 (classDataModeler, 0, U"Get degrees of freedom", 0, 1, DO_DataModeler_getDegreesOfFreedom); praat_addAction1 (classDataModeler, 1, U"Modify -", 0, 0, 0); praat_addAction1 (classDataModeler, 0, U"Set data weighing...", 0, 1, DO_DataModeler_setDataWeighing); praat_addAction1 (classDataModeler, 0, U"Set tolerance...", 0, 1, DO_DataModeler_setTolerance); praat_addAction1 (classDataModeler, 1, U"-- set parameter values --", 0, 1, 0); praat_addAction1 (classDataModeler, 0, U"Set parameter value...", 0, 1, DO_DataModeler_setParameterValue); praat_addAction1 (classDataModeler, 0, U"Set parameter free...", 0, 1, DO_DataModeler_setParameterFree); praat_addAction1 (classDataModeler, 0, U"Set parameter values to zero...", 0, 1, DO_DataModeler_setParameterValuesToZero); praat_addAction1 (classDataModeler, 1, U"-- set data values --", 0, 1, 0); praat_addAction1 (classDataModeler, 0, U"Set data point status...", 0, 1, DO_DataModeler_setDataPointStatus); praat_addAction1 (classDataModeler, 0, U"Set data point value...", 0, 1, DO_DataModeler_setDataPointValue); praat_addAction1 (classDataModeler, 0, U"Set data point sigma...", 0, 1, DO_DataModeler_setDataPointSigma); praat_addAction1 (classDataModeler, 0, U"Fit model", 0, 0, DO_DataModeler_fitModel); praat_addAction1 (classDataModeler, 0, U"To Covariance (parameters)...", 0, 0, DO_DataModeler_to_Covariance_parameters); praat_addAction1 (classDataModeler, 0, U"To Table (z-scores)...", 0, 0, DO_DataModeler_to_Table_zscores); praat_addAction1 (classFormant, 0, U"To FormantModeler...", U"To LPC...", praat_HIDDEN, DO_Formant_to_FormantModeler); praat_addAction1 (classFormant, 0, U"Extract smoothest part...", 0, praat_HIDDEN, DO_Formants_extractSmoothestPart); praat_addAction1 (classFormant, 0, U"Extract smoothest part (constrained)...", 0, praat_HIDDEN, DO_Formants_extractSmoothestPart_constrained); praat_addAction1 (classFormantModeler, 0, U"Draw -", 0, 0, 0); praat_addAction1 (classFormantModeler, 0, U"Speckle...", 0, 1, DO_FormantModeler_speckle); praat_addAction1 (classFormantModeler, 0, U"Draw tracks...", 0, 1, DO_FormantModeler_drawTracks); praat_addAction1 (classFormantModeler, 0, U"Draw estimated tracks...", 0, 1, DO_FormantModeler_drawEstimatedTracks); praat_addAction1 (classFormantModeler, 0, U"Draw variances of shifted tracks...", 0, 1, DO_FormantModeler_drawVariancesOfShiftedTracks); praat_addAction1 (classFormantModeler, 0, U"Draw outliers marked...", 0, 1, DO_FormantModeler_drawOutliersMarked); praat_addAction1 (classFormantModeler, 0, U"Draw cumulative chisq scores...", 0, 1, DO_FormantModeler_drawCumulativeChiScores); praat_addAction1 (classFormantModeler, 0, U"Normal probability plot...", 0, 1, DO_FormantModeler_normalProbabilityPlot); praat_addAction1 (classFormantModeler, 0, U"Draw basis function...", 0, 1, DO_FormantModeler_drawBasisFunction); praat_addAction1 (classFormantModeler, 1, U"Query -", 0, 0, 0); praat_addAction1 (classFormantModeler, 0, U"Get number of tracks", 0, 1, DO_FormantModeler_getNumberOfTracks); praat_addAction1 (classFormantModeler, 1, U"-- get parameter info --", 0, 1, 0); praat_addAction1 (classFormantModeler, 0, U"Get number of parameters...", 0, 1, DO_FormantModeler_getNumberOfParameters); praat_addAction1 (classFormantModeler, 0, U"Get number of fixed parameters...", 0, 1, DO_FormantModeler_getNumberOfFixedParameters); praat_addAction1 (classFormantModeler, 0, U"Get parameter value...", 0, 1, DO_FormantModeler_getParameterValue); praat_addAction1 (classFormantModeler, 0, U"Get parameter status...", 0, 1, DO_FormantModeler_getParameterStatus); praat_addAction1 (classFormantModeler, 0, U"Get parameter standard deviation...", 0, 1, DO_FormantModeler_getParameterStandardDeviation); praat_addAction1 (classFormantModeler, 0, U"Get variance of parameters...", 0, 1, DO_FormantModeler_getVarianceOfParameters); praat_addAction1 (classFormantModeler, 1, U"-- get data points info --", 0, 1, 0); praat_addAction1 (classFormantModeler, 0, U"Get number of data points", 0, 1, DO_FormantModeler_getNumberOfDataPoints); praat_addAction1 (classFormantModeler, 0, U"Get number of invalid data points...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_FormantModeler_getNumberOfInvalidDataPoints); praat_addAction1 (classFormantModeler, 0, U"Get model value at time...", 0, 1, DO_FormantModeler_getModelValueAtTime); praat_addAction1 (classFormantModeler, 0, U"Get data point value...", 0, 1, DO_FormantModeler_getDataPointValue); praat_addAction1 (classFormantModeler, 0, U"Get data point sigma...", 0, 1, DO_FormantModeler_getDataPointSigma); praat_addAction1 (classFormantModeler, 0, U"Get data point status...", 0, 1, DO_FormantModeler_getDataPointStatus); praat_addAction1 (classFormantModeler, 1, U"-- get statistics info --", 0, 1, 0); praat_addAction1 (classFormantModeler, 0, U"Get residual sum of squares...", 0, 1, DO_FormantModeler_getResidualSumOfSquares); praat_addAction1 (classFormantModeler, 0, U"Get formant standard deviation...", 0, 1, DO_FormantModeler_getStandardDeviation); praat_addAction1 (classFormantModeler, 0, U"Get coefficient of determination...", 0, 1, DO_FormantModeler_getCoefficientOfDetermination); praat_addAction1 (classFormantModeler, 0, U"Report chi squared...", 0, 1, DO_FormantModeler_reportChiSquared); praat_addAction1 (classFormantModeler, 0, U"Get degrees of freedom...", 0, 1, DO_FormantModeler_getDegreesOfFreedom); praat_addAction1 (classFormantModeler, 0, U"Get smoothness value...", 0, 1, DO_FormantModeler_getSmoothnessValue); praat_addAction1 (classFormantModeler, 0, U"Get average distance between tracks...", 0, 1, DO_FormantModeler_getAverageDistanceBetweenTracks); praat_addAction1 (classFormantModeler, 0, U"Get formants constraints factor...", 0, 1, DO_FormantModeler_getFormantsConstraintsFactor); praat_addAction1 (classFormantModeler, 1, U"Modify -", 0, 0, 0); praat_addAction1 (classFormantModeler, 0, U"Set data weighing...", 0, 1, DO_FormantModeler_setDataWeighing); praat_addAction1 (classFormantModeler, 0, U"Set tolerance...", 0, 1, DO_FormantModeler_setTolerance); praat_addAction1 (classFormantModeler, 1, U"-- set parameter values --", 0, 1, 0); praat_addAction1 (classFormantModeler, 0, U"Set parameter value fixed...", 0, 1, DO_FormantModeler_setParameterValueFixed); praat_addAction1 (classFormantModeler, 0, U"Set parameter free...", 0, 1, DO_FormantModeler_setParameterFree); praat_addAction1 (classFormantModeler, 0, U"Set parameter values to zero...", 0, 1, DO_FormantModeler_setParameterValuesToZero); praat_addAction1 (classFormantModeler, 1, U"-- set data points --", 0, 1, 0); praat_addAction1 (classFormantModeler, 0, U"Set data point value...", 0, 1, DO_FormantModeler_setDataPointValue); praat_addAction1 (classFormantModeler, 0, U"Set data point sigma...", 0, 1, DO_FormantModeler_setDataPointSigma); praat_addAction1 (classFormantModeler, 0, U"Set data point status...", 0, 1, DO_FormantModeler_setDataPointStatus); praat_addAction1 (classFormantModeler, 0, U"Fit model", 0, 0, DO_FormantModeler_fitModel); praat_addAction1 (classFormantModeler, 0, U"To Covariance (parameters)...", 0, 0, DO_FormantModeler_to_Covariance_parameters); praat_addAction1 (classFormantModeler, 0, U"To Table (z-scores)...", 0, 0, DO_FormantModeler_to_Table_zscores); praat_addAction1 (classFormantModeler, 0, U"To FormantModeler (process outliers)...", 0, 0, DO_FormantModeler_processOutliers); praat_addAction1 (classFormantModeler, 0, U"Extract DataModeler...", 0, 0, DO_FormantModeler_extractDataModeler); praat_addAction1 (classOptimalCeilingTier, 1, U"View & Edit", 0, praat_ATTRACTIVE, DO_OptimalCeilingTier_edit); praat_addAction1 (classPitch, 0, U"To PitchModeler...", U"To PointProcess", praat_HIDDEN, DO_Pitch_to_PitchModeler); praat_addAction1 (classPitchModeler, 0, U"Draw...", 0, 0, DO_PitchModeler_draw); praat_addAction1 (classSound, 0, U"Get optimal formant ceiling...", U"Get intensity (dB)", praat_DEPTH_1 | praat_HIDDEN, DO_Sound_getOptimalFormantCeiling); praat_addAction1 (classSound, 0, U"To Formant (interval)...", U"To Formant (robust)...", praat_DEPTH_2 | praat_HIDDEN, DO_Sound_to_Formant_interval); praat_addAction1 (classSound, 0, U"To Formant (interval, constrained)...", U"To Formant (interval)...", praat_DEPTH_2 | praat_HIDDEN, DO_Sound_to_Formant_interval_constrained); praat_addAction1 (classSound, 0, U"To OptimalCeilingTier...", U"To Formant (interval, constrained)...", praat_DEPTH_2 | praat_HIDDEN, DO_Sound_to_OptimalCeilingTier); praat_addAction1 (classSound, 0, U"To Formant (interval, constrained, robust)...", U"To Formant (interval, constrained)...", praat_DEPTH_2 | praat_HIDDEN, DO_Sound_to_Formant_interval_constrained_robust); praat_addAction1 (classTable, 0, U"To DataModeler...", U"To logistic regression...", praat_DEPTH_1 + praat_HIDDEN, DO_Table_to_DataModeler); } /* End of file praat_DataModeler_init.cpp */ praat-6.0.04/dwtools/praat_David_init.cpp000066400000000000000000012524261261542461700203740ustar00rootroot00000000000000/* praat_David_init.cpp * * Copyright (C) 1993-2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20030701 Added Strings_setString. djmw 20031020 Changed Matrix_solveEquation. djmw 20031023 Added Spectra_multiply, Spectrum_conjugate and modified interface for CCA_and_TableOfReal_scores. djmw 20031030 Added TableOfReal_appendColumns. djmw 20031107 Added TablesOfReal_to_GSVD. djmw 20040303 Latest modification djmw 20040305 Added hints for PCA. djmw 20040323 Added hint for Discriminant. djmw 20040324 Added PCA_and_TableOfReal_getFractionVariance. djmw 20040331 Modified Eigen_drawEigenvalues interface. djmw 20040406 Extensive checks for creation of Sounds. djmw 20040414 Forms texts. djmw 20040523 Discriminant_and_TableOfReal_to_ClassificationTable: give new object a name. djmw 20040623 Added ClassificationTable_to_Strings_maximumProbability. djmw 20040704 BarkFilter... in Thing_recognizeClassesByName. djmw 20041020 MelderFile -> structMelderFile. djmw 20041105 TableOfReal_createFromVanNieropData_25females. djmw 20041108 FormantFilter_drawSpectrum bug correted (wrong field name). djmw 20050308 Find path (slopes), Find path (band)... and others. djmw 20050404 TableOfReal_appendColumns -> TableOfReal_appendColumnsMany djmw 20050406 Procrustus -> Prorustes djmw 20050407 MelFilter_drawFilterFunctions error in field names crashed praat djmw 20050706 Eigen_getSumOfEigenvalues djmw 20051012 Robust LPC analysis test djmw 20051116 TableOfReal_drawScatterPlot horizontal and vertical axes indices must be positive numbers djmw SVD extract lef/right singular vectors djmw 20060111 TextGrid: Extend time moved from depth 1 to depth 2. djmw 20060308 Thing_recognizeClassesByName: StringsIndex, CCA djmw 20070206 Sound_changeGender: pitch range factor must be >= 0 djmw 20070304 Latest modification. djmw 20070903 Melder_new<1...> djmw 20071011 REQUIRE requires U"". djmw 20071202 Melder_warning djmw 20080521 Confusion_drawAsnumbers djmw 20090109 KlattGrid formulas for formant djmw 20090708 KlattTable <-> Table djmw 20090822 Thing_recognizeClassesByName: added classCepstrum, classIndex, classKlattTable djmw 20090914 Excitation to Excitations crashed because of nullptr reference djmw 20090927 TableOfReal_drawRow(s)asHistogram djmw 20091023 Sound_draw_selectedIntervals djmw 20091230 Covariance_and_TableOfReal_mahalanobis djmw 20100212 Standardize on Window length djmw 20100511 Categories_getNumberOfCategories djmw 20120813 Latest modification. */ #include "praat.h" #include "NUM2.h" #include "NUMlapack.h" #include "NUMmachar.h" #include "Activation.h" #include "Categories.h" #include "CategoriesEditor.h" #include "ClassificationTable.h" #include "Collection_extensions.h" #include "ComplexSpectrogram.h" #include "Confusion.h" #include "Discriminant.h" #include "EditDistanceTable.h" #include "Editor.h" #include "EditDistanceTable.h" #include "Eigen_and_Matrix.h" #include "Eigen_and_Procrustes.h" #include "Eigen_and_SSCP.h" #include "Eigen_and_TableOfReal.h" #include "Excitations.h" #include "espeakdata_FileInMemory.h" #include "FileInMemory.h" #include "FilterBank.h" #include "Formula.h" #include "FormantGridEditor.h" #include "DataModeler.h" #include "FormantGrid_extensions.h" #include "Intensity_extensions.h" #include "IntensityTierEditor.h" #include "Matrix_Categories.h" #include "Matrix_extensions.h" #include "LongSound_extensions.h" #include "KlattGridEditors.h" #include "KlattTable.h" #include "Ltas_extensions.h" #include "Minimizers.h" #include "Pattern.h" #include "PCA.h" #include "PitchTierEditor.h" #include "Polygon_extensions.h" #include "Polynomial.h" #include "Sound_extensions.h" #include "Sounds_to_DTW.h" #include "Spectrum_extensions.h" #include "Spectrogram.h" #include "SpeechSynthesizer.h" #include "SpeechSynthesizer_and_TextGrid.h" #include "SSCP.h" #include "Strings_extensions.h" #include "SVD.h" #include "Table_extensions.h" #include "TableOfReal_and_Permutation.h" #include "TextGrid_extensions.h" #include "Categories_and_Strings.h" #include "CCA_and_Correlation.h" #include "Cepstrum_and_Spectrum.h" #include "CCs_to_DTW.h" #include "Discriminant_Pattern_Categories.h" #include "DTW_and_TextGrid.h" #include "Permutation_and_Index.h" #include "Pitch_extensions.h" #include "Sound_and_Spectrogram_extensions.h" #include "Sound_to_Pitch2.h" #include "Sound_to_SPINET.h" #include "TableOfReal_and_SVD.h" #include "VowelEditor.h" #undef iam #define iam iam_LOOP static const char32 *QUERY_BUTTON = U"Query -"; static const char32 *DRAW_BUTTON = U"Draw -"; static const char32 *MODIFY_BUTTON = U"Modify -"; static const char32 *EXTRACT_BUTTON = U"Extract -"; void praat_TimeFunction_query_init (ClassInfo klas); void praat_TimeFrameSampled_query_init (ClassInfo klas); void praat_TableOfReal_init (ClassInfo klas); void praat_TableOfReal_init2 (ClassInfo klas); void praat_SSCP_as_TableOfReal_init (ClassInfo klas); void praat_CC_init (ClassInfo klas); void DTW_constraints_addCommonFields (UiForm dia); void DTW_constraints_getCommonFields (UiForm dia, int *begin, int *end, int *slope); void praat_BandFilterSpectrogram_query_init (ClassInfo klas); int praat_Fon_formula (UiForm dia, Interpreter interpreter); void praat_EditDistanceTable_as_TableOfReal_init (ClassInfo klas); #undef INCLUDE_DTW_SLOPES /********************** Activation *******************************************/ FORM (Activation_formula, U"Activation: Formula", 0) LABEL (U"label", U"for col := 1 to ncol do { self [row, col] := `formula' ; x := x + dx } y := y + dy }}") TEXTFIELD (U"formula", U"self") OK DO praat_Fon_formula (dia, interpreter); END DIRECT (Activation_to_Matrix) LOOP { iam (Activation); autoMatrix thee = Activation_to_Matrix (me); praat_new (thee.move(), my name); } END /********************** BandFilterSpectrogram *******************************************/ FORM (BandFilterSpectrogram_drawFrequencyScale, U"", U"") REAL (U"left Horizontal frequency range (Hz)", U"0.0") REAL (U"right Horizontal frequency range (Hz)", U"0.0") REAL (U"left Vertical frequency range (mel)", U"0.0") REAL (U"right Vertical frequency range (mel)", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (BandFilterSpectrogram); BandFilterSpectrogram_drawFrequencyScale (me, GRAPHICS, GET_REAL (U"left Horizontal frequency range"), GET_REAL (U"right Horizontal frequency range"), GET_REAL (U"left Vertical frequency range"), GET_REAL (U"right Vertical frequency range"), GET_INTEGER (U"Garnish")); } END /********************** BarkFilter *******************************************/ DIRECT (BarkFilter_help) Melder_help (U"BarkFilter"); END DIRECT (BarkSpectrogram_help) Melder_help (U"BarkSpectrogram"); END FORM (BarkFilter_drawSpectrum, U"BarkFilter: Draw spectrum (slice)", U"FilterBank: Draw spectrum (slice)...") POSITIVE (U"Time (s)", U"0.1") REAL (U"left Frequency range (Bark)", U"0.0") REAL (U"right Frequency range (Bark)", U"0.0") REAL (U"left Amplitude range (dB)", U"0.0") REAL (U"right Amplitude range (dB)", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (BarkFilter); FilterBank_drawTimeSlice (me, GRAPHICS, GET_REAL (U"Time"), GET_REAL (U"left Frequency range"), GET_REAL (U"right Frequency range"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range"), U"Barks", GET_INTEGER (U"Garnish")); } END FORM (BarkFilter_drawSekeyHansonFilterFunctions, U"BarkFilter: Draw filter functions", U"FilterBank: Draw filter functions...") INTEGER (U"left Filter range", U"0") INTEGER (U"right Filter range", U"0") RADIO (U"Frequency scale", 1) RADIOBUTTON (U"Hertz") RADIOBUTTON (U"Bark") RADIOBUTTON (U"mel") REAL (U"left Frequency range", U"0.0") REAL (U"right Frequency range", U"0.0") BOOLEAN (U"Amplitude scale in dB", 1) REAL (U"left Amplitude range", U"0.0") REAL (U"right Amplitude range", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (BarkFilter); BarkFilter_drawSekeyHansonFilterFunctions (me, GRAPHICS, GET_INTEGER (U"Frequency scale"), GET_INTEGER (U"left Filter range"), GET_INTEGER (U"right Filter range"), GET_REAL (U"left Frequency range"), GET_REAL (U"right Frequency range"), GET_INTEGER (U"Amplitude scale in dB"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range"), GET_INTEGER (U"Garnish")); } END FORM (BarkSpectrogram_drawSekeyHansonAuditoryFilters, U"BarkSpectrogram: Draw Sekey-Hanson auditory filters", U"BarkSpectrogram: Draw Sekey-Hanson auditory filters...") INTEGER (U"left Filter range", U"0") INTEGER (U"right Filter range", U"0") RADIO (U"Frequency scale", 2) RADIOBUTTON (U"Hertz") RADIOBUTTON (U"Bark") REAL (U"left Frequency range", U"0.0") REAL (U"right Frequency range", U"0.0") BOOLEAN (U"Amplitude scale in dB", 1) REAL (U"left Amplitude range", U"0.0") REAL (U"right Amplitude range", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (BarkSpectrogram); bool xIsHertz = GET_INTEGER (U"Frequency scale") == 1; BarkSpectrogram_drawSekeyHansonFilterFunctions (me, GRAPHICS, xIsHertz, GET_INTEGER (U"left Filter range"), GET_INTEGER (U"right Filter range"), GET_REAL (U"left Frequency range"), GET_REAL (U"right Frequency range"), GET_INTEGER (U"Amplitude scale in dB"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range"), GET_INTEGER (U"Garnish")); } END FORM (BarkFilter_paint, U"FilterBank: Paint", 0) REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") REAL (U"left Frequency range (bark)", U"0.0") REAL (U"right Frequency range (bark)", U"0.0") REAL (U"left Amplitude range", U"0.0") REAL (U"right Amplitude range", U"0.0") BOOLEAN (U"Garnish", 0) OK DO autoPraatPicture picture; LOOP { iam (Matrix); FilterBank_paint ((FilterBank) me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Frequency range"), GET_REAL (U"right Frequency range"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range"), GET_INTEGER (U"Garnish")); } END DIRECT (BarkFilter_to_BarkSpectrogram) LOOP { iam (BarkFilter); praat_new (BarkFilter_to_BarkSpectrogram (me), my name); } END DIRECT (MelFilter_to_MelSpectrogram) LOOP { iam (MelFilter); praat_new (MelFilter_to_MelSpectrogram (me), my name); } END DIRECT (FormantFilter_to_Spectrogram) LOOP { iam (FormantFilter); praat_new (FormantFilter_to_Spectrogram (me), my name); } END /********************** Categories ****************************************/ FORM (Categories_append, U"Categories: Append 1 category", U"Categories: Append 1 category...") SENTENCE (U"Category", U"") OK DO LOOP { iam (Categories); OrderedOfString_append (me, GET_STRING (U"Category")); } END DIRECT (Categories_edit) if (theCurrentPraatApplication -> batch) { Melder_throw (U"Cannot edit a Categories from batch."); } else { LOOP { iam (Categories); praat_installEditor (CategoriesEditor_create ( my name, me), IOBJECT); } } END DIRECT (Categories_getNumberOfCategories) LOOP { iam (Categories); Melder_information (my size, U" categories"); } END DIRECT (Categories_getNumberOfDifferences) Categories c1 = nullptr, c2 = nullptr; LOOP { iam (Categories); (c1 ? c2 : c1) = me; } Melder_assert (c1 && c2); long numberOfDifferences = OrderedOfString_getNumberOfDifferences (c1, c2); if (numberOfDifferences < 0) { Melder_information (U"-1 (undefined: number of elements differ!)"); } else { Melder_information (numberOfDifferences, U" differences"); } END DIRECT (Categories_getFractionDifferent) Categories c1 = nullptr, c2 = nullptr; LOOP { iam (Categories); (c1 ? c2 : c1) = me; } Melder_assert (c1 && c2); Melder_information (OrderedOfString_getFractionDifferent (c1, c2)); END DIRECT (Categories_difference) Categories c1 = nullptr, c2 = nullptr; LOOP { iam (Categories); (c1 ? c2 : c1) = me; } Melder_assert (c1 && c2); long n; double fraction; OrderedOfString_difference (c1, c2, &n, &fraction); Melder_information (n, U" differences"); END DIRECT (Categories_selectUniqueItems) LOOP { iam (Categories); autoCategories thee = Categories_selectUniqueItems (me, 1); praat_new (thee.move(), my name, U"_uniq"); } END DIRECT (Categories_to_Confusion) Categories c1 = nullptr, c2 = nullptr; LOOP { iam (Categories); (c1 ? c2 : c1) = me; } Melder_assert (c1 && c2); autoConfusion thee = Categories_to_Confusion (c1, c2); praat_new (thee.move(), Thing_getName (c1), U"_", Thing_getName (c2)); END DIRECT (Categories_to_Strings) LOOP { iam (Categories); autoStrings thee = Categories_to_Strings (me); praat_new (thee.move(), my name); } END DIRECT (Categories_join) Categories c1 = nullptr, c2 = nullptr; LOOP { iam (Categories); (c1 ? c2 : c1) = me; } Melder_assert (c1 && c2); autoOrderedOfString thee = OrderedOfString_joinItems (c1, c2); praat_new (thee.move()); END DIRECT (Categories_permuteItems) LOOP { iam (Collection); autoCollection thee = Collection_permuteItems (me); // thee will be of class Categories! praat_new (thee.move(), my name, U"_perm"); } END /***************** CC ****************************************/ FORM (CC_getNumberOfCoefficients, U"Get number of coefficients", 0) NATURAL (U"Frame number", U"1") OK DO LOOP { iam (CC); long numberOfCoefficients = CC_getNumberOfCoefficients (me, GET_INTEGER (U"Frame number")); Melder_information (numberOfCoefficients); } END FORM (CC_getValue, U"CC: Get value", U"CC: Get value...") REAL (U"Time (s)", U"0.1") NATURAL (U"Index", U"1") OK DO LOOP { iam (CC); // ?? generic Melder_informationReal (CC_getValue (me, GET_REAL (U"Time"), GET_INTEGER (U"Index")), 0); } END FORM (CC_getValueInFrame, U"CC: Get value in frame", U"CC: Get value in frame...") NATURAL (U"Frame number", U"1") NATURAL (U"Index", U"1") OK DO LOOP { iam (CC); // ?? generic Melder_informationReal (CC_getValueInFrame (me, GET_INTEGER (U"Frame number"), GET_INTEGER (U"Index")), 0); } END FORM (CC_getC0ValueInFrame, U"CC: Get c0 value in frame", U"CC: Get c0 value in frame...") NATURAL (U"Frame number", U"1") OK DO LOOP { iam (CC); // ?? generic Melder_informationReal (CC_getC0ValueInFrame (me, GET_INTEGER (U"Frame number")), 0); } END FORM (CC_paint, U"CC: Paint", U"CC: Paint...") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") INTEGER (U"From coefficient", U"0") INTEGER (U"To coefficient", U"0") REAL (U"Minimum", U"0.0") REAL (U"Maximum", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (CC); CC_paint (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_INTEGER (U"From coefficient"), GET_INTEGER (U"To coefficient"), GET_REAL (U"Minimum"), GET_REAL (U"Maximum"), GET_INTEGER (U"Garnish")); } END FORM (CC_drawC0, U"CC: Draw c0", U"CC: Draw c0...") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") REAL (U"left Amplitude range", U"0.0") REAL (U"right Amplitude range", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (CC); CC_drawC0 (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range"), GET_INTEGER (U"Garnish")); } END FORM (CCs_to_DTW, U"CC: To DTW", U"CC: To DTW...") LABEL (U"", U"Distance between cepstral coefficients") REAL (U"Cepstral weight", U"1.0") REAL (U"Log energy weight", U"0.0") REAL (U"Regression weight", U"0.0") REAL (U"Regression weight log energy", U"0.0") REAL (U"Regression coefficients window (s)", U"0.056") DTW_constraints_addCommonFields (dia); OK DO CC c1 = nullptr, c2 = nullptr; LOOP { iam (CC); (c1 ? c2 : c1) = me; } Melder_assert (c1 && c2); int begin, end, slope; DTW_constraints_getCommonFields (dia, &begin, &end, &slope); autoDTW thee = CCs_to_DTW (c1, c2, GET_REAL (U"Cepstral weight"), GET_REAL (U"Log energy weight"), GET_REAL (U"Regression weight"), GET_REAL (U"Regression weight log energy"), GET_REAL (U"Regression coefficients window")); DTW_findPath (thee.get(), begin, end, slope); praat_new (thee.move(), U""); END DIRECT (CC_to_Matrix) LOOP { iam (CC); autoMatrix thee = CC_to_Matrix (me); praat_new (thee.move(), my name); } END /******************* class CCA ********************************/ FORM (CCA_drawEigenvector, U"CCA: Draw eigenvector", U"Eigen: Draw eigenvector...") OPTIONMENU (U"X or Y", 1) OPTION (U"y") OPTION (U"x") INTEGER (U"Eigenvector number", U"1") LABEL (U"", U"Multiply by eigenvalue?") BOOLEAN (U"Component loadings", 0) LABEL (U"", U"Select part of the eigenvector:") INTEGER (U"left Element range", U"0") INTEGER (U"right Element range", U"0") REAL (U"left Amplitude range", U"-1.0") REAL (U"right Amplitude range", U"1.0") POSITIVE (U"Mark size (mm)", U"1.0") SENTENCE (U"Mark string (+xo.)", U"+") BOOLEAN (U"Connect points", 1) BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (CCA); CCA_drawEigenvector (me, GRAPHICS, GET_INTEGER (U"X or Y"), GET_INTEGER (U"Eigenvector number"), GET_INTEGER (U"left Element range"), GET_INTEGER (U"right Element range"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range"), GET_INTEGER (U"Component loadings"), GET_REAL (U"Mark size"), GET_STRING (U"Mark string"), GET_INTEGER (U"Connect points"), GET_INTEGER (U"Garnish")); } END DIRECT (CCA_getNumberOfCorrelations) LOOP { iam (CCA); Melder_information (my numberOfCoefficients); } END FORM (CCA_getCorrelationCoefficient, U"CCA: Get canonical correlation coefficient", U"CCA: Get canonical correlation coefficient") NATURAL (U"Coefficient number", U"1") OK DO LOOP { iam (CCA); Melder_information (CCA_getCorrelationCoefficient (me, GET_INTEGER (U"Coefficient number"))); } END FORM (CCA_getEigenvectorElement, U"CCA: Get eigenvector element", U"Eigen: Get eigenvector element...") OPTIONMENU (U"X or Y", 1) OPTION (U"y") OPTION (U"x") NATURAL (U"Eigenvector number", U"1") NATURAL (U"Element number", U"1") OK DO LOOP { iam (CCA); Melder_information (CCA_getEigenvectorElement (me, GET_INTEGER (U"X or Y"), GET_INTEGER (U"Eigenvector number"), GET_INTEGER (U"Element number"))); } END FORM (CCA_getZeroCorrelationProbability, U"CCA: Get zero correlation probability", U"CCA: Get zero correlation probability...") NATURAL (U"Coefficient number", U"1") OK DO LOOP { iam (CCA); double p, chisq; long ndf; CCA_getZeroCorrelationProbability (me, GET_INTEGER (U"Coefficient number"), &chisq, &ndf, &p); Melder_information (p, U" (=probability for chisq = ", chisq, U" and ndf = ", ndf, U")"); } END DIRECT (CCA_and_Correlation_factorLoadings) CCA me = FIRST (CCA); Correlation thee = FIRST (Correlation); autoTableOfReal result = CCA_and_Correlation_factorLoadings (me, thee); praat_new (result.move(), Thing_getName (me), U"_loadings"); END FORM (CCA_and_Correlation_getVarianceFraction, U"CCA & Correlation: Get variance fraction", U"CCA & Correlation: Get variance fraction...") LABEL (U"", U"Get the fraction of variance from the data in set...") OPTIONMENU (U"X or Y", 1) OPTION (U"y") OPTION (U"x") LABEL (U"", U"extracted by...") NATURAL (U"left Canonical variate range", U"1") NATURAL (U"right Canonical variate range", U"1") OK DO CCA me = FIRST (CCA); Correlation thee = FIRST (Correlation); int x_or_y = GET_INTEGER (U"X or Y"); int cv_from = GET_INTEGER (U"left Canonical variate range"); int cv_to = GET_INTEGER (U"right Canonical variate range"); Melder_information (CCA_and_Correlation_getVarianceFraction (me, thee, x_or_y, cv_from, cv_to), U" (fraction variance from ", (x_or_y == 1 ? U"y" : U"x"), U", extracted by canonical variates ", cv_from, U" to ", cv_to, U")"); END FORM (CCA_and_Correlation_getRedundancy_sl, U"CCA & Correlation: Get Stewart-Love redundancy", U"CCA & Correlation: Get redundancy (sl)...") LABEL (U"", U"Get the redundancy of the data in set...") OPTIONMENU (U"X or Y", 1) OPTION (U"y") OPTION (U"x") LABEL (U"", U"extracted by...") NATURAL (U"left Canonical variate range", U"1") NATURAL (U"right Canonical variate range", U"1") LABEL (U"", U"...given the availability of the data in the other set.") OK DO CCA me = FIRST (CCA); Correlation thee = FIRST (Correlation); int x_or_y = GET_INTEGER (U"X or Y"); int cv_from = GET_INTEGER (U"left Canonical variate range"); int cv_to = GET_INTEGER (U"right Canonical variate range"); Melder_information (CCA_and_Correlation_getRedundancy_sl (me, thee, x_or_y, cv_from, cv_to), U" (redundancy from ", (x_or_y == 1 ? U"y" : U"x"), U" extracted by canonical variates ", cv_from, U" to ", cv_to, U")"); END DIRECT (CCA_and_TableOfReal_factorLoadings) CCA me = FIRST (CCA); TableOfReal thee = FIRST (TableOfReal); autoTableOfReal result = CCA_and_TableOfReal_factorLoadings (me, thee); praat_new (result.move(), Thing_getName (me), U"_loadings"); END FORM (CCA_and_TableOfReal_scores, U"CCA & TableOfReal: To TableOfReal (scores)", U"CCA & TableOfReal: To TableOfReal (scores)...") INTEGER (U"Number of canonical correlations", U"0 (=all)") OK DO CCA me = FIRST (CCA); TableOfReal thee = FIRST (TableOfReal); autoTableOfReal result = CCA_and_TableOfReal_scores (me, thee, GET_INTEGER (U"Number of canonical correlations")); praat_new (result.move(), Thing_getName (me), U"_scores"); END FORM (CCA_and_TableOfReal_predict, U"CCA & TableOfReal: Predict", U"CCA & TableOfReal: Predict...") LABEL (U"", U"The data set from which to predict starts at...") INTEGER (U"Column number", U"1") OK DO CCA me = FIRST (CCA); TableOfReal thee = FIRST (TableOfReal); autoTableOfReal result = CCA_and_TableOfReal_predict (me, thee, GET_INTEGER (U"Column number")); praat_new (result.move(), thy name, U"_", my name); END /***************** ChebyshevSeries ****************************************/ DIRECT (ChebyshevSeries_help) Melder_help (U"ChebyshevSeries"); END FORM (ChebyshevSeries_create, U"Create ChebyshevSeries", U"Create ChebyshevSeries...") WORD (U"Name", U"cs") LABEL (U"", U"Domain") REAL (U"Xmin", U"-1") REAL (U"Xmax", U"1") LABEL (U"", U"ChebyshevSeries(x) = c[1] T[0](x) + c[2] T[1](x) + ... c[n+1] T[n](x)") LABEL (U"", U"T[k] is a Chebyshev polynomial of degree k") SENTENCE (U"Coefficients (c[k])", U"0 0 1.0") OK DO double xmin = GET_REAL (U"Xmin"), xmax = GET_REAL (U"Xmax"); REQUIRE (xmin < xmax, U"Xmin must be smaller than Xmax.") autoChebyshevSeries me = ChebyshevSeries_createFromString (xmin, xmax, GET_STRING (U"Coefficients")); praat_new (me.move(), GET_STRING (U"Name")); END DIRECT (ChebyshevSeries_to_Polynomial) LOOP { iam (ChebyshevSeries); autoPolynomial thee = ChebyshevSeries_to_Polynomial (me); praat_new (thee.move(), my name); } END /***************** ClassificationTable ****************************************/ DIRECT (ClassificationTable_help) Melder_help (U"ClassificationTable"); END FORM (ClassificationTable_getClassIndexAtMaximumInRow, U"ClassificationTable: Get class index at maximum in row", 0) NATURAL (U"Row number", U"1") OK DO LOOP { iam (ClassificationTable); long klasIndex = TableOfReal_getColumnIndexAtMaximumInRow (me, GET_INTEGER (U"Row number")); Melder_information (klasIndex); } END FORM (ClassificationTable_getClassLabelAtMaximumInRow, U"ClassificationTable: Get class label at maximum in row", 0) NATURAL (U"Row number", U"1") OK DO LOOP { iam (ClassificationTable); const char32 *klasLabel = TableOfReal_getColumnLabelAtMaximumInRow (me, GET_INTEGER (U"Row number")); Melder_information (klasLabel); } END // deprecated 2014 DIRECT (ClassificationTable_to_Confusion_old) LOOP { iam (ClassificationTable); autoConfusion thee = ClassificationTable_to_Confusion (me, false); praat_new (thee.move(), my name); } END FORM (ClassificationTable_to_Confusion, U"ClassificationTable: To Confusion", U"ClassificationTable: To Confusion...") BOOLEAN (U"Only class labels", true) OK DO LOOP { iam (ClassificationTable); autoConfusion thee = ClassificationTable_to_Confusion (me, GET_INTEGER (U"Only class labels")); praat_new (thee.move(), my name); } END DIRECT (ClassificationTable_to_Correlation_columns) LOOP { iam (ClassificationTable); autoCorrelation thee = ClassificationTable_to_Correlation_columns (me); praat_new (thee.move(), my name, U"_col"); } END DIRECT (ClassificationTable_to_Strings_maximumProbability) LOOP { iam (ClassificationTable); autoStrings thee = ClassificationTable_to_Strings_maximumProbability (me); praat_new (thee.move(), my name); } END /********************** Confusion *******************************************/ DIRECT (Confusion_help) Melder_help (U"Confusion"); END FORM (Confusion_createSimple, U"Create simple Confusion", U"Create simple Confusion...") WORD (U"Name", U"simple") SENTENCE (U"Labels", U"u i a") OK DO autoConfusion thee = Confusion_createSimple (GET_STRING (U"Labels")); praat_new (thee.move(), GET_STRING (U"Name")); END FORM (Confusion_increase, U"Confusion: Increase", U"Confusion: Increase...") WORD (U"Stimulus", U"u") WORD (U"Response", U"i") OK DO LOOP { iam (Confusion); Confusion_increase (me, GET_STRING (U"Stimulus"), GET_STRING (U"Response")); praat_dataChanged (me); } END FORM (Confusion_getValue, U"Confusion: Get value", 0) WORD (U"Stimulus", U"u") WORD (U"Response", U"i") OK DO char32 *stim = GET_STRING (U"Stimulus"); char32 *resp = GET_STRING (U"Response"); LOOP { iam (Confusion); Melder_information (Confusion_getValue (me, stim, resp), U" ( [\"", stim, U"\", \"", resp, U"\"] )"); } END FORM (Confusion_getResponseSum, U"Confusion: Get response sum", U"Confusion: Get response sum...") WORD (U"Response", U"u") OK DO LOOP { iam (TableOfReal); Melder_information (TableOfReal_getColumnSumByLabel (me, GET_STRING (U"Response"))); } END FORM (Confusion_getStimulusSum, U"Confusion: Get stimulus sum", U"Confusion: Get stimulus sum...") WORD (U"Stimulus", U"u") OK DO LOOP { iam (TableOfReal); Melder_information (TableOfReal_getRowSumByLabel (me, GET_STRING (U"Stimulus"))); } END DIRECT (Confusion_to_TableOfReal_marginals) LOOP { iam (Confusion); autoTableOfReal thee = Confusion_to_TableOfReal_marginals (me); praat_new (thee.move(), my name); } END DIRECT (Confusion_difference) Confusion c1 = nullptr, c2 = nullptr; LOOP { iam (Confusion); (c1 ? c2 : c1) = me; } Melder_assert (c1 && c2); autoMatrix thee = Confusion_difference (c1, c2); praat_new (thee.move(), U"diffs"); END FORM (Confusion_condense, U"Confusion: Condense", U"Confusion: Condense...") SENTENCE (U"Search", U"^(u|i)$") SENTENCE (U"Replace", U"high") INTEGER (U"Replace limit", U"0 (=unlimited)") RADIO (U"Search and replace are", 2) RADIOBUTTON (U"Literals") RADIOBUTTON (U"Regular Expressions") OK DO LOOP { iam (Confusion); autoConfusion thee = Confusion_condense (me, GET_STRING (U"Search"), GET_STRING (U"Replace"), GET_INTEGER (U"Replace limit"), GET_INTEGER (U"Search and replace are") - 1); praat_new (thee.move(), my name, U"_cnd"); } END FORM (Confusion_group, U"Confusion: Group stimuli & responses", U"Confusion: Group...") SENTENCE (U"Stimuli & Responses", U"u i") SENTENCE (U"New label", U"high") INTEGER (U"New label position", U"0 (=at start)") OK DO const char32 *newlabel = GET_STRING (U"New label"); LOOP { iam (Confusion); autoConfusion thee = Confusion_group (me, GET_STRING (U"Stimuli & Responses"), newlabel, GET_INTEGER (U"New label position")); praat_new (thee.move(), my name, U"_sr", newlabel); } END FORM (Confusion_groupStimuli, U"Confusion: Group stimuli", U"Confusion: Group stimuli...") SENTENCE (U"Stimuli", U"u i") SENTENCE (U"New label", U"high") INTEGER (U"New label position", U"0") OK DO const char32 *newlabel = GET_STRING (U"New label"); LOOP { iam (Confusion); autoConfusion thee = Confusion_groupStimuli (me, GET_STRING (U"Stimuli"), newlabel, GET_INTEGER (U"New label position")); praat_new (thee.move(), my name, U"_s", newlabel); } END FORM (Confusion_groupResponses, U"Confusion: Group responses", U"Confusion: Group responses...") SENTENCE (U"Responses", U"a i") SENTENCE (U"New label", U"front") INTEGER (U"New label position", U"0") OK DO const char32 *newlabel = GET_STRING (U"New label"); LOOP { iam (Confusion); autoConfusion thee = Confusion_groupResponses (me, GET_STRING (U"Responses"), newlabel, GET_INTEGER (U"New label position")); praat_new (thee.move(), my name, U"_s", newlabel); } END FORM (Confusion_drawAsNumbers, U"", U"") BOOLEAN (U"Draw marginals", 1) RADIO (U"Format", 3) RADIOBUTTON (U"decimal") RADIOBUTTON (U"exponential") RADIOBUTTON (U"free") RADIOBUTTON (U"rational") NATURAL (U"Precision", U"5") OK DO autoPraatPicture picture; LOOP { iam (Confusion); Confusion_drawAsNumbers (me, GRAPHICS, GET_INTEGER (U"Draw marginals"), GET_INTEGER (U"Format"), GET_INTEGER (U"Precision")); } END DIRECT (Confusion_getFractionCorrect) LOOP { iam (Confusion); double f; long n; Confusion_getFractionCorrect (me, &f, &n); Melder_information (f, U" (fraction correct)"); } END DIRECT (Confusion_and_ClassificationTable_increase) Confusion me = FIRST (Confusion); ClassificationTable thee = FIRST (ClassificationTable); Confusion_and_ClassificationTable_increase (me, thee); END /******************* Confusion & Matrix *************************************/ FORM (Confusion_Matrix_draw, U"Confusion & Matrix: Draw confusions with arrows", 0) INTEGER (U"Category position", U"0 (=all)") REAL (U"Lower level (%)", U"0") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") BOOLEAN (U"Garnish", 1) OK DO long categoryPosition = GET_INTEGER (U"Category position"); REQUIRE (categoryPosition >= 0, U"Category position must be >= 0") Confusion conf = FIRST (Confusion); Matrix mat = FIRST (Matrix); Confusion_Matrix_draw (conf, mat, GRAPHICS, categoryPosition, GET_REAL (U"Lower level"), GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Garnish")); END /**********************ComplexSpectrogram *******************************************/ DIRECT (ComplexSpectrogram_help) Melder_help (U"ComplexSpectrogram_help"); END FORM (ComplexSpectrogram_to_Sound, U"ComplexSpectrogram: To Sound", 0) POSITIVE (U"Duration factor", U"1.0") OK DO LOOP { iam (ComplexSpectrogram); autoSound thee = ComplexSpectrogram_to_Sound (me, GET_REAL (U"Duration factor")); praat_new (thee.move(), my name); } END DIRECT (ComplexSpectrogram_to_Spectrogram) LOOP { iam (ComplexSpectrogram); autoSpectrogram thee = ComplexSpectrogram_to_Spectrogram (me); praat_new (thee.move(), my name); } END FORM (ComplexSpectrogram_to_Spectrum, U"ComplexSpectrogram: To Spectrum (slice)", 0) REAL (U"Time (s)", U"0.0") OK DO LOOP { iam (ComplexSpectrogram); autoSpectrum thee = ComplexSpectrogram_to_Spectrum (me, GET_REAL (U"Time")); praat_new (thee.move(), my name); } END /**********************Correlation *******************************************/ DIRECT (Correlation_help) Melder_help (U"Correlation"); END FORM (Correlation_confidenceIntervals, U"Correlation: Confidence intervals...", U"Correlation: Confidence intervals...") POSITIVE (U"Confidence level (0-1)", U"0.95") INTEGER (U"Number of tests (Bonferroni correction)", U"0") RADIO (U"Approximation", 1) RADIOBUTTON (U"Ruben") RADIOBUTTON (U"Fisher") OK DO double cl = GET_REAL (U"Confidence level"); long numberOfTests = GET_INTEGER (U"Number of tests"); LOOP { iam (Correlation); autoTableOfReal thee = Correlation_confidenceIntervals (me, cl, numberOfTests, GET_INTEGER (U"Approximation")); praat_new (thee.move(), U"conf_intervals"); } END FORM (Correlation_testDiagonality_bartlett, U"Correlation: Get diagonality (bartlett)", U"SSCP: Get diagonality (bartlett)...") NATURAL (U"Number of contraints", U"1") OK DO long nc = GET_INTEGER (U"Number of contraints"); LOOP { iam (Correlation); double chisq, p; Correlation_testDiagonality_bartlett (me, nc, &chisq, &p); Melder_information (p, U" (=probability, based on chisq = ", chisq, U"and ndf = ", my numberOfRows * (my numberOfRows - 1) / 2, U")"); } END DIRECT (Correlation_to_PCA) LOOP { iam (Correlation); autoPCA thee = SSCP_to_PCA (me); praat_new (thee.move(), my name); } END /**********************Covariance *******************************************/ DIRECT (Covariance_help) Melder_help (U"Covariance"); END FORM (Covariance_createSimple, U"Create simple Covariance", U"Create simple Covariance...") WORD (U"Name", U"c") SENTENCE (U"Covariances", U"1.0 0.0 1.0") SENTENCE (U"Centroid", U"0.0 0.0") NATURAL (U"Number of observations", U"100") OK DO autoCovariance me = Covariance_createSimple (GET_STRING (U"Covariances"), GET_STRING (U"Centroid"), GET_INTEGER (U"Number of observations")); praat_new (me.move(), GET_STRING (U"Name")); END FORM (Covariance_getProbabilityAtPosition, U"Covariance: Get probability at position", 0) SENTENCE (U"Position", U"10.0 20.0") OK DO char32 *position = GET_STRING (U"Position"); LOOP { iam (Covariance); double p = Covariance_getProbabilityAtPosition_string (me, position); Melder_information (p, U" (= probability at position ", position, U")"); } END FORM (Covariance_getSignificanceOfOneMean, U"Covariance: Get significance of one mean", U"Covariance: Get significance of one mean...") LABEL (U"", U"Get probability that the mean with") NATURAL (U"Index", U"1") LABEL (U"", U"differs from") REAL (U"Value", U"0.0") LABEL (U"", U"(Null hypothesis: the observed difference is due to chance.)") OK DO LOOP { iam (Covariance); double p, t, ndf; Covariance_getSignificanceOfOneMean (me, GET_INTEGER (U"Index"), GET_REAL (U"Value"), &p, &t, &ndf); Melder_information (p, U" (=probability, based on t = ", t, U" and ndf = ", ndf); } END FORM (Covariance_getSignificanceOfMeansDifference, U"Covariance: Get significance of means difference", U"Covariance: Get significance of means difference...") LABEL (U"", U"Get probability that the difference between means") NATURAL (U"Index1", U"1") NATURAL (U"Index2", U"2") LABEL (U"", U"differs from") REAL (U"Value", U"0.0") LABEL (U"", U"when the means are") BOOLEAN (U"Paired", 1) LABEL (U"", U"and have") BOOLEAN (U"Equal variances", 1) OK DO LOOP { iam (Covariance); double p, t, ndf; Covariance_getSignificanceOfMeansDifference (me, GET_INTEGER (U"Index1"), GET_INTEGER (U"Index2"), GET_REAL (U"Value"), GET_INTEGER (U"Paired"), GET_INTEGER (U"Equal variances"), &p, &t, &ndf); Melder_information (p, U" (=probability, based on t = ", t, U"and ndf = ", ndf, U")"); } END FORM (Covariance_getSignificanceOfOneVariance, U"Covariance: Get significance of one variance", U"Covariance: Get significance of one variance...") LABEL (U"", U"Get probability that the variance with") NATURAL (U"Index", U"1") LABEL (U"", U"differs from") REAL (U"Value", U"0.0") LABEL (U"", U"(Null hypothesis: the observed difference is due to chance.)") OK DO LOOP { iam (Covariance); double p, chisq; long ndf; Covariance_getSignificanceOfOneVariance (me, GET_INTEGER (U"Index"), GET_REAL (U"Value"), &p, &chisq , &ndf); Melder_information (p, U" (=probability, based on chisq = ", chisq, U"and ndf = ", ndf); } END FORM (Covariance_getSignificanceOfVariancesRatio, U"Covariance: Get significance of variances ratio", U"Covariance: Get significance of variances ratio...") NATURAL (U"Index1", U"1") NATURAL (U"Index2", U"2") REAL (U"Hypothesized ratio", U"1.0") OK DO LOOP { iam (Covariance); double p, f; long ndf; Covariance_getSignificanceOfVariancesRatio (me, GET_INTEGER (U"Index1"), GET_INTEGER (U"Index2"), GET_REAL (U"Hypothesized ratio"), &p, &f , &ndf); Melder_information (p, U" (=probability, based on F = ", f, U"and ndf1 = ", ndf, U" and ndf2 = ", ndf); } END FORM (Covariance_getFractionVariance, U"Covariance: Get fraction variance", U"Covariance: Get fraction variance...") NATURAL (U"From dimension", U"1") NATURAL (U"To dimension", U"1") OK DO LOOP { iam (Covariance); Melder_information (SSCP_getFractionVariation (me, GET_INTEGER (U"From dimension"), GET_INTEGER (U"To dimension"))); } END FORM (Covariances_reportMultivariateMeanDifference, U"Covariances: Report multivariate mean difference", U"Covariances: Report multivariate mean difference...") BOOLEAN (U"Covariances are equal", true) OK DO Covariance c1 = nullptr, c2 = nullptr; LOOP { iam (Covariance); (c1 ? c2 : c1) = me; } Melder_assert (c1 && c2); double prob, fisher, df1, df2, difference; bool equalCovariances = GET_INTEGER (U"Covariances are equal"); MelderInfo_open (); difference = Covariances_getMultivariateCentroidDifference (c1, c2, equalCovariances, &prob, &fisher, &df1, &df2); MelderInfo_writeLine (U"Under the assumption that the two covariances are", (equalCovariances ? U" " : U" not "), U"equal:"); MelderInfo_writeLine (U"Difference between multivariate means = ", difference); MelderInfo_writeLine (U"Fisher's F = ", fisher); MelderInfo_writeLine (U"Significance from zero = ", prob); MelderInfo_writeLine (U"Degrees of freedom = ", df1, U", ", df2); MelderInfo_writeLine (U"(Number of observations = ", c1->numberOfObservations, U", ", c2->numberOfObservations); MelderInfo_writeLine (U"Dimension of covariance matrices = ", c1-> numberOfRows, U")"); MelderInfo_close (); END FORM (Covariance_to_TableOfReal_randomSampling, U"Covariance: To TableOfReal (random sampling)", U"Covariance: To TableOfReal (random sampling)...") INTEGER (U"Number of data points", U"0") OK DO LOOP { iam (Covariance); autoTableOfReal thee = Covariance_to_TableOfReal_randomSampling (me, GET_INTEGER (U"Number of data points")); praat_new (thee.move(), my name); } END DIRECT (Covariances_reportEquality) autoCollection set = praat_getSelectedObjects (); MelderInfo_open (); double p, chisq, df; Covariances_equality (set.peek(), 1, &p, &chisq, &df); MelderInfo_writeLine (U"Difference between covariance matrices:"); MelderInfo_writeLine (U"Significance of difference (bartlett) = ", p); MelderInfo_writeLine (U"Chi-squared = ", chisq); MelderInfo_writeLine (U"Degrees of freedom = ", df); Covariances_equality (set.peek(), 2, &p, &chisq, &df); MelderInfo_writeLine (U"Significance of difference (wald) = ", p); MelderInfo_writeLine (U"Chi-squared = ", chisq); MelderInfo_writeLine (U"Degrees of freedom = ", df); MelderInfo_close (); END DIRECT (Covariance_to_Correlation) LOOP { iam (Covariance); autoCorrelation thee = SSCP_to_Correlation (me); praat_new (thee.move(), my name); } END DIRECT (Covariance_to_PCA) LOOP { iam (Covariance); autoPCA thee = SSCP_to_PCA (me); praat_new (thee.move(), my name); } END FORM (Covariance_and_TableOfReal_mahalanobis, U"Covariance & TableOfReal: To TableOfReal (mahalanobis)", U"Covariance & TableOfReal: To TableOfReal (mahalanobis)...") BOOLEAN (U"Centroid from table", 0) OK DO Covariance me = FIRST (Covariance); TableOfReal thee = FIRST (TableOfReal); praat_new (Covariance_and_TableOfReal_mahalanobis (me, thee, GET_INTEGER (U"Centroid from table")), U"mahalanobis"); END /********************** Discriminant **********************************/ DIRECT (Discriminant_help) Melder_help (U"Discriminant"); END DIRECT (Discriminant_setGroupLabels) Discriminant me = FIRST (Discriminant); Strings ss = FIRST (Strings); Discriminant_setGroupLabels (me, ss); praat_dataChanged (me); END FORM (Discriminant_and_Pattern_to_Categories, U"Discriminant & Pattern: To Categories", U"Discriminant & Pattern: To Categories...") BOOLEAN (U"Pool covariance matrices", 1) BOOLEAN (U"Use apriori probabilities", 1) OK DO Discriminant me = FIRST (Discriminant); Pattern pat = FIRST (Pattern); autoCategories thee = Discriminant_and_Pattern_to_Categories (me, pat, GET_INTEGER (U"Pool covariance matrices"), GET_INTEGER (U"Use apriori probabilities")); praat_new (thee.move(), my name, U"_", pat->name); END FORM (Discriminant_and_TableOfReal_to_Configuration, U"Discriminant & TableOfReal: To Configuration", U"Discriminant & TableOfReal: To Configuration...") INTEGER (U"Number of dimensions", U"0") OK DO long dimension = GET_INTEGER (U"Number of dimensions"); REQUIRE (dimension >= 0, U"Number of dimensions must be greater equal zero.") Discriminant me = FIRST (Discriminant); TableOfReal tr = FIRST_GENERIC (TableOfReal); autoConfiguration thee = Discriminant_and_TableOfReal_to_Configuration (me, tr, dimension); praat_new (thee.move(), my name, U"_", tr->name); END DIRECT (hint_Discriminant_and_TableOfReal_to_ClassificationTable) Melder_information (U"You can use the Discriminant as a classifier by \nselecting a Discriminant and a TableOfReal object together."); END FORM (Discriminant_and_TableOfReal_to_ClassificationTable, U"Discriminant & TableOfReal: To ClassificationTable", U"Discriminant & TableOfReal: To ClassificationTable...") BOOLEAN (U"Pool covariance matrices", 1) BOOLEAN (U"Use apriori probabilities", 1) OK DO Discriminant me = FIRST (Discriminant); TableOfReal tr = FIRST_GENERIC (TableOfReal); autoClassificationTable thee = Discriminant_and_TableOfReal_to_ClassificationTable (me, tr, GET_INTEGER (U"Pool covariance matrices"), GET_INTEGER (U"Use apriori probabilities")); praat_new (thee.move(), my name, U"_", tr->name); END FORM (Discriminant_and_TableOfReal_mahalanobis, U"Discriminant & TableOfReal: To TableOfReal (mahalanobis)", U"Discriminant & TableOfReal: To TableOfReal (mahalanobis)...") SENTENCE (U"Group label", U"") BOOLEAN (U"Pool covariance matrices", 0) OK DO Discriminant me = FIRST (Discriminant); TableOfReal tr = FIRST (TableOfReal); long group = Discriminant_groupLabelToIndex (me, GET_STRING (U"Group label")); REQUIRE (group > 0, U"Group label does not exist.") autoTableOfReal thee = Discriminant_and_TableOfReal_mahalanobis (me, tr, group, GET_INTEGER (U"Pool covariance matrices")); praat_new (thee.move(), U"mahalanobis"); END FORM (Discriminant_getWilksLambda, U"Discriminant: Get Wilks' lambda", U"Discriminant: Get Wilks' lambda...") LABEL (U"", U"Product (i=from..numberOfEigenvalues, 1 / (1 + eigenvalue[i]))") INTEGER (U"From", U"1") OK DO long from = GET_INTEGER (U"From"); REQUIRE (from >= 1, U"Number must be greater than or equal to one.") LOOP { iam (Discriminant); Melder_information (Discriminant_getWilksLambda (me, from)); } END FORM (Discriminant_getCumulativeContributionOfComponents, U"Discriminant: Get cumulative contribution of components", U"Eigen: Get cumulative contribution of components...") NATURAL (U"From component", U"1") NATURAL (U"To component", U"1") OK DO LOOP { iam (Discriminant); Melder_information (Eigen_getCumulativeContributionOfComponents (me, GET_INTEGER (U"From component"), GET_INTEGER (U"To component"))); } END FORM (Discriminant_getPartialDiscriminationProbability, U"Discriminant: Get partial discrimination probability", U"Discriminant: Get partial discrimination probability...") INTEGER (U"Number of dimensions", U"1") OK DO long n = GET_INTEGER (U"Number of dimensions"); REQUIRE (n >= 0, U"Number of dimensions must be greater than or equal to zero.") LOOP { iam (Discriminant); double p, chisq; long ndf; Discriminant_getPartialDiscriminationProbability (me, n, &p, &chisq, &ndf); Melder_information (p, U" (=probability, based on chisq = ", chisq, U"and ndf = ", ndf, U")"); } END DIRECT (Discriminant_getHomegeneityOfCovariances_box) LOOP { iam (Discriminant); double chisq, p; long ndf; SSCPs_getHomegeneityOfCovariances_box ( (SSCPs) my groups, &p, &chisq, &ndf); Melder_information (p, U" (=probability, based on chisq = ", chisq, U"and ndf = ", ndf, U")"); } END DIRECT (Discriminant_reportEqualityOfCovariances_wald) MelderInfo_open (); LOOP { iam (Discriminant); double chisq, prob, df; Covariances_equality ( (Collection) my groups, 2, &prob, &chisq, &df); MelderInfo_writeLine (U"Wald test for equality of covariance matrices:"); MelderInfo_writeLine (U"Chi squared: ", chisq); MelderInfo_writeLine (U"Significance: ", prob); MelderInfo_writeLine (U"Degrees of freedom: ", df); MelderInfo_writeLine (U"Number of matrices: ", my groups -> size); } MelderInfo_close (); END FORM (Discriminant_getConcentrationEllipseArea, U"Discriminant: Get concentration ellipse area", U"Discriminant: Get concentration ellipse area...") SENTENCE (U"Group label", U"") POSITIVE (U"Number of sigmas", U"1.0") BOOLEAN (U"Discriminant plane", 1) INTEGER (U"X-dimension", U"1") INTEGER (U"Y-dimension", U"2") OK DO LOOP { iam (Discriminant); long group = Discriminant_groupLabelToIndex (me, GET_STRING (U"Group label")); REQUIRE (group > 0, U"Group label does not exist.") Melder_information (Discriminant_getConcentrationEllipseArea (me, group, GET_REAL (U"Number of sigmas"), 0, GET_INTEGER (U"Discriminant plane"), GET_INTEGER (U"X-dimension"), GET_INTEGER (U"Y-dimension"))); } END FORM (Discriminant_getConfidenceEllipseArea, U"Discriminant: Get confidence ellipse area", U"Discriminant: Get confidence ellipse area...") SENTENCE (U"Group label", U"") POSITIVE (U"Confidence level (0-1)", U"0.95") BOOLEAN (U"Discriminant plane", 1) INTEGER (U"X-dimension", U"1") INTEGER (U"Y-dimension", U"2") OK DO LOOP { iam (Discriminant); long group = Discriminant_groupLabelToIndex (me, GET_STRING (U"Group label")); REQUIRE (group > 0, U"Group label does not exist.") Melder_information (Discriminant_getConcentrationEllipseArea (me, group, GET_REAL (U"Confidence level"), 1, GET_INTEGER (U"Discriminant plane"), GET_INTEGER (U"X-dimension"), GET_INTEGER (U"Y-dimension"))); } END FORM (Discriminant_getLnDeterminant_group, U"Discriminant: Get determinant (group)", U"Discriminant: Get determinant (group)...") SENTENCE (U"Group label", U"") OK DO LOOP { iam (Discriminant); long group = Discriminant_groupLabelToIndex (me, GET_STRING (U"Group label")); REQUIRE (group > 0, U"Group label does not exist.") Melder_information (Discriminant_getLnDeterminant_group (me, group)); } END DIRECT (Discriminant_getLnDeterminant_total) LOOP { iam (Discriminant); Melder_information (Discriminant_getLnDeterminant_total (me)); } END FORM (Discriminant_invertEigenvector, U"Discriminant: Invert eigenvector", 0) NATURAL (U"Index of eigenvector", U"1") OK DO LOOP { iam (Discriminant); Eigen_invertEigenvector (me, GET_INTEGER (U"Index of eigenvector")); praat_dataChanged (me); } END FORM (Discriminant_drawSigmaEllipses, U"Discriminant: Draw sigma ellipses", U"Discriminant: Draw sigma ellipses...") POSITIVE (U"Number of sigmas", U"1.0") BOOLEAN (U"Discriminant plane", 1) INTEGER (U"X-dimension", U"1") INTEGER (U"Y-dimension", U"2") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") INTEGER (U"Label size", U"12") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (Discriminant); Discriminant_drawConcentrationEllipses (me, GRAPHICS, GET_REAL (U"Number of sigmas"), 0, 0, GET_INTEGER (U"Discriminant plane"), GET_INTEGER (U"X-dimension"), GET_INTEGER (U"Y-dimension"), GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Label size"), GET_INTEGER (U"Garnish")); } END FORM (Discriminant_drawOneSigmaEllipse, U"Discriminant: Draw one sigma ellipse", U"Discriminant: Draw one sigma ellipse...") SENTENCE (U"Label", U"") POSITIVE (U"Number of sigmas", U"1.0") BOOLEAN (U"Discriminant plane", 1) INTEGER (U"X-dimension", U"1") INTEGER (U"Y-dimension", U"2") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") INTEGER (U"Label size", U"12") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (Discriminant); Discriminant_drawConcentrationEllipses (me, GRAPHICS, GET_REAL (U"Number of sigmas"), 0, GET_STRING (U"Label"), GET_INTEGER (U"Discriminant plane"), GET_INTEGER (U"X-dimension"), GET_INTEGER (U"Y-dimension"), GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Label size"), GET_INTEGER (U"Garnish")); } END FORM (Discriminant_drawConfidenceEllipses, U"Discriminant: Draw confidence ellipses", 0) POSITIVE (U"Confidence level (0-1)", U"0.95") BOOLEAN (U"Discriminant plane", 1) INTEGER (U"X-dimension", U"1") INTEGER (U"Y-dimension", U"2") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") INTEGER (U"Label size", U"12") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (Discriminant); Discriminant_drawConcentrationEllipses (me, GRAPHICS, GET_REAL (U"Confidence level"), 1, nullptr, GET_INTEGER (U"Discriminant plane"), GET_INTEGER (U"X-dimension"), GET_INTEGER (U"Y-dimension"), GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Label size"), GET_INTEGER (U"Garnish")); } END FORM (Discriminant_drawOneConfidenceEllipse, U"Discriminant: Draw one confidence ellipse", 0) SENTENCE (U"Label", U"") POSITIVE (U"Confidence level (0-1)", U"0.95") BOOLEAN (U"Discriminant plane", 1) INTEGER (U"X-dimension", U"1") INTEGER (U"Y-dimension", U"2") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") INTEGER (U"Label size", U"12") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (Discriminant); Discriminant_drawConcentrationEllipses (me, GRAPHICS, GET_REAL (U"Confidence level"), 1, GET_STRING (U"Label"), GET_INTEGER (U"Discriminant plane"), GET_INTEGER (U"X-dimension"), GET_INTEGER (U"Y-dimension"), GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Label size"), GET_INTEGER (U"Garnish")); } END DIRECT (Discriminant_extractBetweenGroupsSSCP) LOOP { iam (Discriminant); autoSSCP thee = Discriminant_extractBetweenGroupsSSCP (me); praat_new (thee.move()); } END DIRECT (Discriminant_extractGroupCentroids) LOOP { iam (Discriminant); autoTableOfReal thee = Discriminant_extractGroupCentroids (me); praat_new (thee.move(), U"centroids"); } END DIRECT (Discriminant_extractGroupStandardDeviations) LOOP { iam (Discriminant); autoTableOfReal thee = Discriminant_extractGroupStandardDeviations (me); praat_new (thee.move(), U"group_stddevs"); } END DIRECT (Discriminant_extractGroupLabels) LOOP { iam (Discriminant); autoStrings thee = Discriminant_extractGroupLabels (me); praat_new (thee.move(), U"group_labels"); } END DIRECT (Discriminant_extractPooledWithinGroupsSSCP) LOOP { iam (Discriminant); autoSSCP thee = Discriminant_extractPooledWithinGroupsSSCP (me); praat_new (thee.move(), U"pooled_within"); } END FORM (Discriminant_extractWithinGroupSSCP, U"Discriminant: Extract within-group SSCP", U"Discriminant: Extract within-group SSCP...") NATURAL (U"Group index", U"1") OK DO long index = GET_INTEGER (U"Group index"); LOOP { iam (Discriminant); autoSSCP thee = Discriminant_extractWithinGroupSSCP (me, index); praat_new (thee.move(), my name, U"_g", index); } END DIRECT (Discriminant_getNumberOfFunctions) LOOP { iam (Discriminant); Melder_information (Discriminant_getNumberOfFunctions (me)); } END DIRECT (Discriminant_getDimensionOfFunctions) LOOP { iam (Discriminant); Melder_information (Eigen_getDimensionOfComponents (me)); } END DIRECT (Discriminant_getNumberOfGroups) LOOP { iam (Discriminant); Melder_information (Discriminant_getNumberOfGroups (me)); } END FORM (Discriminant_getNumberOfObservations, U"Discriminant: Get number of observations", U"Discriminant: Get number of observations...") INTEGER (U"Group", U"0 (=total)") OK DO LOOP { iam (Discriminant); Melder_information (Discriminant_getNumberOfObservations (me, GET_INTEGER (U"Group"))); } END /********************** DTW *******************************************/ FORM (DTW_and_Polygon_findPathInside, U"DTW & Polygon: Find path inside", 0) RADIO (U"Slope constraint", 1) RADIOBUTTON (U"no restriction") RADIOBUTTON (U"1/3 < slope < 3") RADIOBUTTON (U"1/2 < slope < 2") RADIOBUTTON (U"2/3 < slope < 3/2") OK DO int localSlope = GET_INTEGER (U"Slope constraint"); DTW me = FIRST (DTW); Polygon thee = FIRST (Polygon); DTW_and_Polygon_findPathInside (me, thee, localSlope, 0); END FORM (DTW_and_Polygon_to_Matrix_cummulativeDistances, U"DTW & Polygon: To Matrix (cumm. distances)", 0) RADIO (U"Slope constraint", 1) RADIOBUTTON (U"no restriction") RADIOBUTTON (U"1/3 < slope < 3") RADIOBUTTON (U"1/2 < slope < 2") RADIOBUTTON (U"2/3 < slope < 3/2") OK DO int localSlope = GET_INTEGER (U"Slope constraint"); DTW me = FIRST (DTW); Polygon thee = FIRST (Polygon); autoMatrix him = DTW_and_Polygon_to_Matrix_cummulativeDistances (me, thee, localSlope); praat_new (him.move(), my name, U"_", localSlope); END FORM (DTW_and_Sounds_draw, U"DTW & Sounds: Draw", U"DTW & Sounds: Draw...") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") BOOLEAN (U"Garnish", 1) OK DO Sound s1 = nullptr, s2 = nullptr; DTW dtw = nullptr; LOOP { iam (Daata); if (CLASS == classSound) { (s1 ? s2 : s1) = (Sound) me; } else if (CLASS == classDTW) { dtw = (DTW) me; } } Melder_assert (s1 && s2 && dtw); autoPraatPicture picture; DTW_and_Sounds_draw (dtw, s2, s1, GRAPHICS, GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Garnish")); END FORM (DTW_and_Sounds_drawWarpX, U"DTW & Sounds: Draw warp (x)", U"DTW & Sounds: Draw warp (x)...") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") REAL (U"Time (s)", U"0.1") BOOLEAN (U"Garnish", 1) OK DO Sound s1 = nullptr, s2 = nullptr; LOOP { iam (Sound); (s1 ? s2 : s1) = me; } Melder_assert (s1 && s2); DTW dtw = FIRST (DTW); autoPraatPicture picture; DTW_and_Sounds_drawWarpX (dtw, s2, s1, GRAPHICS, GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_REAL (U"Time"), GET_INTEGER (U"Garnish")); END void DTW_constraints_addCommonFields (UiForm dia) { Any radio; LABEL (U"", U"Boundary conditions") BOOLEAN (U"Match begin positions", 0) BOOLEAN (U"Match end positions", 0) RADIO (U"Slope constraint", 1) RADIOBUTTON (U"no restriction") RADIOBUTTON (U"1/3 < slope < 3") RADIOBUTTON (U"1/2 < slope < 2") RADIOBUTTON (U"2/3 < slope < 3/2") } void DTW_constraints_getCommonFields (UiForm dia, int *begin, int *end, int *slope) { *begin = GET_INTEGER (U"Match begin positions"); *end = GET_INTEGER (U"Match end positions"); *slope = GET_INTEGER (U"Slope constraint"); } DIRECT (DTW_help) Melder_help (U"DTW"); END FORM (DTW_drawPath, U"DTW: Draw path", 0) REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") BOOLEAN (U"Garnish", 0); OK DO autoPraatPicture picture; LOOP { iam (DTW); DTW_drawPath (me, GRAPHICS, GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Garnish")); } END FORM (DTW_drawDistancesAlongPath, U"DTW: Draw distances along path", 0) REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") BOOLEAN (U"Garnish", 0); OK DO autoPraatPicture picture; LOOP { iam (DTW); DTW_drawDistancesAlongPath (me, GRAPHICS, GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Garnish")); } END FORM (DTW_paintDistances, U"DTW: Paint distances", 0) REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") REAL (U"Minimum", U"0.0") REAL (U"Maximum", U"0.0") BOOLEAN (U"Garnish", 0); OK DO autoPraatPicture picture; LOOP { iam (DTW); DTW_paintDistances (me, GRAPHICS, GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_REAL (U"Minimum"), GET_REAL (U"Maximum"), GET_INTEGER (U"Garnish")); } END FORM (DTW_drawWarpX, U"DTW: Draw warp (x)", U"DTW: Draw warp (x)...") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") REAL (U"Time (s)", U"0.1") BOOLEAN (U"Garnish", 0); OK DO autoPraatPicture picture; LOOP { iam (DTW); DTW_drawWarpX (me, GRAPHICS, GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_REAL (U"Time"), GET_INTEGER (U"Garnish")); } END DIRECT (DTW_getStartTimeX) LOOP { iam (DTW); Melder_information (my xmin, U" s (= start time along x)"); } END DIRECT (DTW_getEndTimeX) LOOP { iam (DTW); Melder_information (my xmax, U" s (= end time along x)"); } END DIRECT (DTW_getTotalDurationX) LOOP { iam (DTW); Melder_information (my xmax - my xmin, U" s (= total duration along x)"); } END DIRECT (DTW_getStartTimeY) LOOP { iam (DTW); Melder_information (my ymin, U" s (= start time along y)"); } END DIRECT (DTW_getEndTimeY) LOOP { iam (DTW); Melder_information (my ymax, U" s (= end time along y)"); } END DIRECT (DTW_getTotalDurationY) LOOP { iam (DTW); Melder_information (my ymax - my ymin, U" s (= total duration along y)"); } END DIRECT (DTW_getNumberOfFramesX) LOOP { iam (DTW); Melder_information (my nx, U" (= number of frames along x)"); } END DIRECT (DTW_getTimeStepX) LOOP { iam (DTW); Melder_information (my dx, U" s (= time step along x)"); } END FORM (DTW_getTimeFromFrameNumberX, U"DTW: Get time from frame number (x)", 0) NATURAL (U"Frame number (x)", U"1") OK DO long column = GET_INTEGER (U"Frame number"); LOOP { iam (DTW); Melder_information (Matrix_columnToX (me, column), U" s (= y time at x frame ", column, U")"); } END FORM (DTW_getFrameNumberFromTimeX, U"DTW: Get frame number from time (x)", 0) REAL (U"Time along x (s)", U"0.1") OK DO double time = GET_REAL (U"Time along x"); LOOP { iam (DTW); if (time < my xmin || time > my xmax) { Melder_throw (me, U"Time outside x domain."); } long iframe = lround (Matrix_xToColumn (me, time)); Melder_information (iframe, U" (= x frame at y time ", time, U")"); } END DIRECT (DTW_getNumberOfFramesY) LOOP { iam (DTW); Melder_information (my ny, U" (= number of frames along y)"); } END DIRECT (DTW_getTimeStepY) LOOP { iam (DTW); Melder_information (my dy, U" s (= time step along y)"); } END FORM (DTW_getTimeFromFrameNumberY, U"DTW: Get time from frame number (y)", 0) NATURAL (U"Frame number (y)", U"1") OK DO long row = GET_INTEGER (U"Frame number"); LOOP { iam (DTW); Melder_information (Matrix_rowToY (me, row), U" s (= x time at y frame ", row, U")"); } END FORM (DTW_getFrameNumberFromTimeY, U"DTW: Get frame number from time (y)", 0) REAL (U"Time along y (s)", U"0.1") OK DO double time = GET_REAL (U"Time along y"); LOOP { iam (DTW); if (time < my ymin || time > my ymax) { Melder_throw (me, U"Time outside y domain."); } long iframe = lround (Matrix_yToRow (me, time)); Melder_information (iframe, U" (= y frame at x time ", time, U")"); } END FORM (DTW_getPathY, U"DTW: Get time along path", U"DTW: Get time along path...") REAL (U"Time (s)", U"0.0") OK DO LOOP { iam (DTW); Melder_information (DTW_getPathY (me, GET_REAL (U"Time"))); } END FORM (DTW_getYTimeFromXTime, U"DTW: Get y time from x time", U"DTW: Get y time from x time...") REAL (U"Time at x (s)", U"0.0") OK DO double time = GET_REAL (U"Time at x"); LOOP { iam (DTW); Melder_information (DTW_getYTimeFromXTime (me, time), U" s (= y time at z time ", time, U")"); } END FORM (DTW_getXTimeFromYTime, U"DTW: Get x time from y time", U"DTW: Get x time from y time...") REAL (U"Time at y (s)", U"0.0") OK DO double time = GET_REAL (U"Time at y"); LOOP { iam (DTW); Melder_information (DTW_getXTimeFromYTime (me, time), U" s (= x time at y time ", time, U")"); } END FORM (DTW_getMaximumConsecutiveSteps, U"DTW: Get maximum consecutive steps", U"DTW: Get maximum consecutive steps...") OPTIONMENU (U"Direction", 1) OPTION (U"X") OPTION (U"Y") OPTION (U"Diagonaal") OK DO int direction[] = {DTW_START, DTW_X, DTW_Y, DTW_XANDY}; const char32 *string[] = {U"", U"x", U"y", U"diagonal"}; int d = GET_INTEGER (U"Direction"); LOOP { iam (DTW); Melder_information (DTW_getMaximumConsecutiveSteps (me, direction[d]), U" (= maximum number of consecutive steps in ", string[d], U" direction)"); } END DIRECT (DTW_getWeightedDistance) LOOP { iam (DTW); Melder_information (my weightedDistance); } END FORM (DTW_getDistanceValue, U"DTW: Get distance value", 0) REAL (U"Time at x (s)", U"0.1") REAL (U"Time at y (s)", U"0.1") OK DO double xtime = GET_REAL (U"Time at x"); double ytime = GET_REAL (U"Time at y"); double dist; LOOP { iam (DTW); if (xtime < my xmin || xtime > my xmax || ytime < my ymin || ytime > my ymax) { dist = NUMundefined; } else { long irow = Matrix_yToNearestRow (me, ytime); long icol = Matrix_xToNearestColumn (me, xtime); dist = my z[irow][icol]; } Melder_information (dist, U" (= distance at (", xtime, U", ", ytime, U"))"); } END DIRECT (DTW_getMinimumDistance) LOOP { iam (DTW); double minimum = NUMundefined, maximum = NUMundefined; Matrix_getWindowExtrema (me, 0, 0, 0, 0, & minimum, & maximum); Melder_informationReal (minimum, 0); } END DIRECT (DTW_getMaximumDistance) LOOP { iam (DTW); double minimum = NUMundefined, maximum = NUMundefined; Matrix_getWindowExtrema (me, 0, 0, 0, 0, & minimum, & maximum); Melder_informationReal (maximum, 0); } END FORM (DTW_formulaDistances, U"DTW: Formula (distances)", 0) LABEL (U"label", U"y := y1; for row := 1 to nrow do { x := x1; " "for col := 1 to ncol do { self [row, col] := `formula' ; x := x + dx } y := y + dy }") TEXTFIELD (U"formula", U"self") OK DO LOOP { iam (DTW); autoMatrix cp = DTW_to_Matrix_distances (me); try { Matrix_formula (reinterpret_cast (me), GET_STRING (U"formula"), interpreter, 0); double minimum, maximum; Matrix_getWindowExtrema (me, 0, 0, 0, 0, & minimum, & maximum); if (minimum < 0) { DTW_and_Matrix_replace (me, cp.peek()); // restore original Melder_throw (U"Execution of the formula has made some distance(s) negative which is not allowed."); } praat_dataChanged (me); } catch (MelderError) { praat_dataChanged (me); throw; } } END FORM (DTW_setDistanceValue, U"DTW: Set distance value", 0) REAL (U"Time at x (s)", U"0.1") REAL (U"Time at y (s)", U"0.1") REAL (U"New value", U"0.0") OK DO double xtime = GET_REAL (U"Time at x"); double ytime = GET_REAL (U"Time at y"); double val = GET_REAL (U"New value"); if (val < 0) { Melder_throw (U"Distances cannot be negative."); } LOOP { iam (DTW); if (xtime < my xmin || xtime > my xmax) { Melder_throw (U"Time at x outside domain."); } if (ytime < my ymin || ytime > my ymax) { Melder_throw (U"Time at y outside domain."); } long irow = Matrix_yToNearestRow (me, ytime); long icol = Matrix_xToNearestColumn (me, xtime); my z[irow][icol] = GET_REAL (U"New value"); praat_dataChanged (me); } END FORM (DTW_findPath, U"DTW: Find path", 0) DTW_constraints_addCommonFields (dia); OK DO int begin, end, slope; DTW_constraints_getCommonFields (dia, &begin, &end, &slope); LOOP { iam (DTW); DTW_findPath (me, begin, end, slope); } END FORM (DTW_findPath_bandAndSlope, U"DTW: find path (band & slope)", 0) REAL (U"Sakoe-Chiba band (s)", U"0.05") RADIO (U"Slope constraint", 1) RADIOBUTTON (U"no restriction") RADIOBUTTON (U"1/3 < slope < 3") RADIOBUTTON (U"1/2 < slope < 2") RADIOBUTTON (U"2/3 < slope < 3/2") OK DO double band = GET_REAL (U"Sakoe-Chiba band"); int slope = GET_INTEGER (U"Slope constraint"); LOOP { iam (DTW); DTW_findPath_bandAndSlope (me, band, slope, 0); } END FORM (DTW_to_Matrix_cummulativeDistances, U"DTW: To Matrix", 0) REAL (U"Sakoe-Chiba band (s)", U"0.05") RADIO (U"Slope constraint", 1) RADIOBUTTON (U"no restriction") RADIOBUTTON (U"1/3 < slope < 3") RADIOBUTTON (U"1/2 < slope < 2") RADIOBUTTON (U"2/3 < slope < 3/2") OK DO double band = GET_REAL (U"Sakoe-Chiba band"); int slope = GET_INTEGER (U"Slope constraint"); LOOP { iam (DTW); autoMatrix thee = DTW_to_Matrix_cummulativeDistances (me, band, slope); praat_new (thee.move(), my name, U"_cd"); } END FORM (DTW_to_Polygon, U"DTW: To Polygon...", 0) REAL (U"Sakoe-Chiba band (s)", U"0.1") RADIO (U"Slope constraint", 1) RADIOBUTTON (U"no restriction") RADIOBUTTON (U"1/3 < slope < 3") RADIOBUTTON (U"1/2 < slope < 2") RADIOBUTTON (U"2/3 < slope < 3/2") OK DO double band = GET_REAL (U"Sakoe-Chiba band"); int slope = GET_INTEGER (U"Slope constraint"); LOOP { iam (DTW); autoPolygon thee = DTW_to_Polygon (me, band, slope); praat_new (thee.move(), my name); } END DIRECT (DTW_to_Matrix_distances) LOOP { iam (DTW); autoMatrix thee = DTW_to_Matrix_distances (me); praat_new (thee.move(), my name); } END DIRECT (DTW_swapAxes) LOOP { iam (DTW); autoDTW thee = DTW_swapAxes (me); praat_new (thee.move(), my name, U"_axesSwapped"); } END DIRECT (DTW_and_Matrix_replace) DTW me = FIRST (DTW); Matrix m = FIRST (Matrix); DTW_and_Matrix_replace (me, m); praat_dataChanged (me); END DIRECT (DTW_and_TextGrid_to_TextGrid) DTW me = FIRST (DTW); TextGrid tg = FIRST (TextGrid); autoTextGrid thee = DTW_and_TextGrid_to_TextGrid (me, tg, 0); praat_new (thee.move(), tg -> name, U"_", my name); END DIRECT (DTW_and_IntervalTier_to_Table) DTW me = FIRST (DTW); IntervalTier ti = FIRST (IntervalTier); autoTable thee = DTW_and_IntervalTier_to_Table (me, ti, 1.0/44100); praat_new (thee.move(), my name); END /******************** EditDistanceTable & EditCostsTable ********************************************/ DIRECT (EditDistanceTable_help) Melder_help (U"EditDistanceTable"); END DIRECT (EditDistanceTable_to_TableOfReal_directions) LOOP { iam (EditDistanceTable); autoTableOfReal thee = EditDistanceTable_to_TableOfReal_directions (me); praat_new (thee.move(), my name); } END DIRECT (EditDistanceTable_setEditCosts) EditDistanceTable me = FIRST (EditDistanceTable); EditCostsTable thee = FIRST(EditCostsTable); EditDistanceTable_setEditCosts (me, thee); END FORM (EditDistanceTable_setDefaultCosts, U"", 0) REAL (U"Insertion costs", U"1.0") REAL (U"Deletion costs", U"1.0") REAL (U"Substitution costs", U"2.0") OK DO double insertionCosts = GET_REAL (U"Insertion costs"); if (insertionCosts < 0) { Melder_throw (U"Insertion costs cannot be negative."); } double deletionCosts = GET_REAL (U"Deletion costs"); if (deletionCosts < 0) { Melder_throw (U"Deletion costs cannot be negative."); } double substitutionCosts = GET_REAL (U"Substitution costs"); if (substitutionCosts < 0) { Melder_throw (U"Substitution costs cannot be negative."); } LOOP { iam (EditDistanceTable); EditDistanceTable_setDefaultCosts (me, insertionCosts, deletionCosts, substitutionCosts); } END FORM (EditDistanceTable_draw, U"EditDistanceTable_draw", 0) RADIO (U"Format", 3) RADIOBUTTON (U"decimal") RADIOBUTTON (U"exponential") RADIOBUTTON (U"free") RADIOBUTTON (U"rational") NATURAL (U"Precision", U"1") REAL (U"Rotate source labels by (degrees)", U"0.0") OK DO autoPraatPicture picture; LOOP { iam (EditDistanceTable); EditDistanceTable_draw (me, GRAPHICS, GET_INTEGER (U"Format"), GET_INTEGER (U"Precision"), GET_REAL (U"Rotate source labels by")); } END DIRECT (EditDistanceTable_drawEditOperations) autoPraatPicture picture; LOOP { iam(EditDistanceTable); EditDistanceTable_drawEditOperations (me, GRAPHICS); } END DIRECT (EditCostsTable_help) Melder_help (U"EditCostsTable"); END FORM (EditCostsTable_getTargetIndex, U"EditCostsTable: Get target index", 0) SENTENCE (U"Target", U"") OK DO LOOP { iam (EditCostsTable); Melder_informationReal (EditCostsTable_getTargetIndex (me, GET_STRING (U"Target")), nullptr); } END FORM (EditCostsTable_getSourceIndex, U"EditCostsTable: Get source index", 0) SENTENCE (U"Source", U"") OK DO LOOP { iam (EditCostsTable); Melder_informationReal (EditCostsTable_getSourceIndex (me, GET_STRING (U"Source")), nullptr); } END FORM (EditCostsTable_getInsertionCost, U"EditCostsTable: Get insertion cost", 0) SENTENCE (U"Target", U"") OK DO LOOP { iam (EditCostsTable); Melder_informationReal (EditCostsTable_getInsertionCost (me, GET_STRING (U"Target")), nullptr); } END FORM (EditCostsTable_getDeletionCost, U"EditCostsTable: Get deletion cost", 0) SENTENCE (U"Source", U"") OK DO LOOP { iam (EditCostsTable); Melder_informationReal (EditCostsTable_getDeletionCost (me, GET_STRING (U"Source")), nullptr); } END FORM (EditCostsTable_getSubstitutionCost, U"EditCostsTable: Get substitution cost", 0) SENTENCE (U"Target", U"") SENTENCE (U"Source", U"") OK DO LOOP { iam (EditCostsTable); Melder_informationReal (EditCostsTable_getSubstitutionCost (me, GET_STRING (U"Target"), GET_STRING (U"Source")), nullptr); } END FORM (EditCostsTable_getOthersCost, U"EditCostsTable: Get cost (others)", 0) RADIO (U"Others cost type", 1) RADIOBUTTON (U"Insertion") RADIOBUTTON (U"Deletion") RADIOBUTTON (U"Equality") RADIOBUTTON (U"Inequality") OK DO LOOP { iam (EditCostsTable); Melder_informationReal (EditCostsTable_getOthersCost (me, GET_INTEGER (U"Others cost type")), nullptr); } END FORM (EditCostsTable_setTargetSymbol_index, U"EditCostsTable: Set target symbol (index)", 0) NATURAL (U"Index", U"1") SENTENCE (U"Target", U"a") OK DO LOOP { iam (TableOfReal); TableOfReal_setRowLabel (me, GET_INTEGER (U"Index"), GET_STRING (U"Target")); } END FORM (EditCostsTable_setSourceSymbol_index, U"EditCostsTable: Set source symbol (index)", 0) NATURAL (U"Index", U"1") SENTENCE (U"Source", U"a") OK DO LOOP { iam (TableOfReal); TableOfReal_setColumnLabel (me, GET_INTEGER (U"Index"), GET_STRING (U"Source")); } END FORM (EditCostsTable_setInsertionCosts, U"EditCostsTable: Set insertion costs", 0) SENTENCE (U"Targets", U"") REAL (U"Cost", U"2.0") OK DO LOOP { iam (EditCostsTable); EditCostsTable_setInsertionCosts (me, GET_STRING (U"Targets"), GET_REAL (U"Cost")); } END FORM (EditCostsTable_setDeletionCosts, U"EditCostsTable: Set deletion costs", 0) SENTENCE (U"Sources", U"") REAL (U"Cost", U"2.0") OK DO LOOP { iam (EditCostsTable); EditCostsTable_setDeletionCosts (me, GET_STRING (U"Sources"), GET_REAL (U"Cost")); } END FORM (EditCostsTable_setSubstitutionCosts, U"EditCostsTable: Set substitution costs", 0) SENTENCE (U"Targets", U"a i u") SENTENCE (U"Sources", U"a i u") REAL (U"Cost", U"2.0") OK DO LOOP { iam (EditCostsTable); EditCostsTable_setSubstitutionCosts (me, GET_STRING (U"Targets"), GET_STRING (U"Sources"), GET_REAL (U"Cost")); } END FORM (EditCostsTable_setOthersCosts, U"EditCostsTable: Set costs (others)", 0) LABEL (U"", U"Others costs") REAL (U"Insertion", U"1.0") REAL (U"Deletion", U"1.0") LABEL (U"", U"Substitution costs") REAL (U"Equality", U"0.0") REAL (U"Inequality", U"2.0") OK DO LOOP { iam (EditCostsTable); EditCostsTable_setOthersCosts (me, GET_REAL (U"Insertion"), GET_REAL (U"Deletion"), GET_REAL (U"Equality"), GET_REAL (U"Inequality")); } END DIRECT (EditCostsTable_to_TableOfReal) LOOP { iam (EditCostsTable); autoTableOfReal thee = EditCostsTable_to_TableOfReal (me); praat_new (thee.move(), my name); } END FORM (EditCostsTable_createEmpty, U"Create empty EditCostsTable", U"Create empty EditCostsTable...") SENTENCE (U"Name", U"editCosts") INTEGER (U"Number of target symbols", U"0") INTEGER (U"Number of source symbols", U"0") OK DO long numberOfTargetSymbols = GET_INTEGER (U"Number of target symbols"); numberOfTargetSymbols = numberOfTargetSymbols < 0 ? 0 : numberOfTargetSymbols; long numberOfSourceSymbols = GET_INTEGER (U"Number of source symbols"); numberOfSourceSymbols = numberOfSourceSymbols < 0 ? 0 : numberOfSourceSymbols; autoEditCostsTable thee = EditCostsTable_create (numberOfTargetSymbols, numberOfSourceSymbols); praat_new (thee.move(), GET_STRING (U"Name")); END /******************** Eigen ********************************************/ DIRECT (Eigen_drawEigenvalues_scree) Melder_warning (U"The command \"Draw eigenvalues (scree)...\" has been " "removed.\n To get a scree plot use \"Draw eigenvalues...\" with the " "arguments\n 'Fraction of eigenvalues summed' and 'Cumulative' unchecked."); END FORM (Eigen_drawEigenvalues, U"Eigen: Draw eigenvalues", U"Eigen: Draw eigenvalues...") INTEGER (U"left Eigenvalue range", U"0") INTEGER (U"right Eigenvalue range", U"0") REAL (U"left Amplitude range", U"0.0") REAL (U"right Amplitude range", U"0.0") BOOLEAN (U"Fraction of eigenvalues summed", 0) BOOLEAN (U"Cumulative", 0) POSITIVE (U"Mark size (mm)", U"1.0") SENTENCE (U"Mark string (+xo.)", U"+") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (Eigen); Eigen_drawEigenvalues (me, GRAPHICS, GET_INTEGER (U"left Eigenvalue range"), GET_INTEGER (U"right Eigenvalue range"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range"), GET_INTEGER (U"Fraction of eigenvalues summed"), GET_INTEGER (U"Cumulative"), GET_REAL (U"Mark size"), GET_STRING (U"Mark string"), GET_INTEGER (U"Garnish")); } END FORM (Eigen_drawEigenvector, U"Eigen: Draw eigenvector", U"Eigen: Draw eigenvector...") INTEGER (U"Eigenvector number", U"1") BOOLEAN (U"Component loadings", 0) INTEGER (U"left Element range", U"0") INTEGER (U"right Element range", U"0") REAL (U"left Amplitude range", U"-1.0") REAL (U"right Amplitude range", U"1.0") POSITIVE (U"Mark size (mm)", U"1.0") SENTENCE (U"Mark string (+xo.)", U"+") BOOLEAN (U"Connect points", 1) BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (Eigen); Eigen_drawEigenvector (me, GRAPHICS, GET_INTEGER (U"Eigenvector number"), GET_INTEGER (U"left Element range"), GET_INTEGER (U"right Element range"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range"), GET_INTEGER (U"Component loadings"), GET_REAL (U"Mark size"), GET_STRING (U"Mark string"), GET_INTEGER (U"Connect points"), 0, GET_INTEGER (U"Garnish")); } END DIRECT (Eigen_getNumberOfEigenvalues) LOOP { iam (Eigen); Melder_information (my numberOfEigenvalues); } END DIRECT (Eigen_getDimension) LOOP { iam (Eigen); Melder_information (my dimension); } END FORM (Eigen_getEigenvalue, U"Eigen: Get eigenvalue", U"Eigen: Get eigenvalue...") NATURAL (U"Eigenvalue number", U"1") OK DO LOOP { iam (Eigen); long number = GET_INTEGER (U"Eigenvalue number"); if (number > my numberOfEigenvalues) { Melder_throw (U"Eigenvalue number must be smaller than ", my numberOfEigenvalues + 1); } Melder_information (my eigenvalues[number]); } END FORM (Eigen_getSumOfEigenvalues, U"Eigen:Get sum of eigenvalues", U"Eigen: Get sum of eigenvalues...") INTEGER (U"left Eigenvalue range", U"0") INTEGER (U"right Eigenvalue range", U"0") OK DO LOOP { iam (Eigen); Melder_information (Eigen_getSumOfEigenvalues (me, GET_INTEGER (U"left Eigenvalue range"), GET_INTEGER (U"right Eigenvalue range"))); } END FORM (Eigen_getEigenvectorElement, U"Eigen: Get eigenvector element", U"Eigen: Get eigenvector element...") NATURAL (U"Eigenvector number", U"1") NATURAL (U"Element number", U"1") OK DO LOOP { iam (Eigen); Melder_information (Eigen_getEigenvectorElement (me, GET_INTEGER (U"Eigenvector number"), GET_INTEGER (U"Element number"))); } END DIRECT (Eigens_alignEigenvectors) autoCollection set = praat_getSelectedObjects (); Eigens_alignEigenvectors (set.peek()); END FORM (Eigen_and_Matrix_project, U"Eigen & Matrix: Project", U"Eigen & Matrix: Project...") INTEGER (U"Number of dimensions", U"0") OK DO Eigen me = FIRST_GENERIC (Eigen); Matrix thee = FIRST_GENERIC (Matrix); autoMatrix him = Eigen_and_Matrix_project (me, thee, GET_INTEGER (U"Number of dimensions")); praat_new (him.move(), my name, U"_", thy name); END DIRECT (Eigen_and_SSCP_project) Eigen me = FIRST_GENERIC (Eigen); SSCP cp = FIRST (SSCP); autoSSCP thee = Eigen_and_SSCP_project (me, cp); praat_new (thee.move(), my name, U"_", cp->name); END DIRECT (Eigen_and_Covariance_project) Eigen me = FIRST_GENERIC (Eigen); Covariance cv = FIRST (Covariance); autoCovariance thee = Eigen_and_Covariance_project (me, cv); praat_new (thee.move(), my name, U"_", cv->name); END /******************** Index ********************************************/ DIRECT (Index_help) Melder_help (U"Index"); END DIRECT (Index_getNumberOfClasses) LOOP { iam (Index); Melder_information (my classes -> size); } END FORM (StringsIndex_getClassLabel, U"StringsIndex: Get class label", U"StringsIndex: Get class label...") NATURAL (U"Class index", U"1") OK DO long klas = GET_INTEGER (U"Class index"); LOOP { iam (StringsIndex); long numberOfClasses = my classes -> size; if (klas > numberOfClasses) { Melder_throw (U"Index must be less than or equal ", numberOfClasses, U"."); } SimpleString ss = (SimpleString) my classes -> item[klas]; Melder_information (ss -> string); } END FORM (StringsIndex_getLabel, U"StringsIndex: Get label", U"StringsIndex: Get label...") NATURAL (U"Element index", U"1") OK DO long index = GET_INTEGER (U"Element index"); LOOP { iam (StringsIndex); if (index > my numberOfElements) { Melder_throw (U"Index must be less than or equal ", my numberOfElements, U"."); } long klas = my classIndex[index]; SimpleString ss = (SimpleString) my classes -> item [klas]; Melder_information (ss -> string); } END FORM (Index_getIndex, U"Index: Get index", U"Index: Get index...") NATURAL (U"Element index", U"1") OK DO long index = GET_INTEGER (U"Element index"); LOOP { iam (Index); if (index > my numberOfElements) { Melder_throw (U"Index must be less than or equal ", my numberOfElements, U"."); } Melder_information (my classIndex[index]); } END FORM (StringsIndex_getClassIndex, U"StringsIndex: Get class index", U"StringsIndex: Get class index...") WORD (U"Class label", U"label") OK DO char32 *klasLabel = GET_STRING (U"Class label"); LOOP { iam (StringsIndex); long index = StringsIndex_getClass (me, klasLabel); Melder_information (index); } END FORM (Index_extractPart, U"Index: Extract part", U"Index: Extract part...") INTEGER (U"left Range", U"0") INTEGER (U"right Range", U"0") OK DO LOOP { iam (Index); autoIndex thee = Index_extractPart (me, GET_INTEGER (U"left Range"), GET_INTEGER (U"right Range")); praat_new (thee.move(), Thing_getName (me), U"_part"); } END FORM (Index_to_Permutation, U"Index: To Permutation", U"Index: To Permutation...") BOOLEAN (U"Permute within classes", 1) OK DO LOOP { iam (Index); autoPermutation thee = Index_to_Permutation_permuteRandomly (me, GET_INTEGER (U"Permute within classes")); praat_new (thee.move(), my name); } END DIRECT (StringsIndex_to_Strings) LOOP { iam (StringsIndex); autoStrings thee = StringsIndex_to_Strings (me); praat_new (thee.move(), my name); } END /******************** Excitation ********************************************/ DIRECT (Excitation_to_Excitations) autoExcitations e = Excitations_create (100); LOOP { iam (Excitation); autoExcitation thee = Data_copy (me); Collection_addItem (e.peek(), thee.transfer()); } praat_new (e.move(), U"appended"); END /******************** Excitations ********************************************/ FORM (Excitations_formula, U"Excitations: Formula", 0) LABEL (U"label", U"for all objects in Excitations do { for col := 1 to ncol do { self [col] := `formula' ; x := x + dx } }") TEXTFIELD (U"formula", U"self") OK DO LOOP { iam (Excitations); for (long j = 1; j <= my size; j++) { Matrix_formula ( (Matrix) my item[j], GET_STRING (U"formula"), interpreter, 0); } praat_dataChanged (me); } END DIRECT (Excitations_addItem) Excitations e = FIRST (Excitations); WHERE_DOWN (SELECTED && CLASS == classExcitation) { iam (Excitation); autoExcitation thee = Data_copy (me); Collection_addItem (e, thee.transfer()); } END FORM (Excitations_getItem, U"Excitations: Get item", 0) NATURAL (U"Item number", U"1") OK DO LOOP { iam (Excitations); autoExcitation thee = Excitations_getItem (me, GET_INTEGER (U"Item number")); praat_new (thee.move(), my name, U"_item"); } END DIRECT (Excitations_append) Excitations e1 = 0, e2 = 0; LOOP { iam (Excitations); (e1 ? e2 : e1) = me; } Melder_assert (e1 && e2); autoCollection result = Collections_merge (e1, e2); praat_new (result.move(), U"appended"); END FORM (Excitations_to_Pattern, U"Excitations: To Pattern", 0) NATURAL (U"Join", U"1") OK DO LOOP { iam (Excitations); autoPattern thee = Excitations_to_Pattern (me, GET_INTEGER (U"Join")); praat_new (thee.move(), my name); } END DIRECT (Excitations_to_TableOfReal) LOOP { iam (Excitations); autoTableOfReal thee = Excitations_to_TableOfReal (me); praat_new (thee.move(), my name); } END /************************* FileInMemory ***********************************/ FORM_READ2 (FileInMemory_create, U"Create file in memory", 0, true) { autoFileInMemory me = FileInMemory_create (file); praat_new (me.move(), MelderFile_name (file)); END2 } FORM (FileInMemory_setId, U"FileInMemory: Set id", 0) SENTENCE (U"New id", U"New id") OK DO LOOP { iam (FileInMemory); FileInMemory_setId (me, GET_STRING (U"New id")); praat_dataChanged (me); } END FORM (FileInMemory_showAsCode, U"FileInMemory: Show as code", 0) WORD (U"Name", U"example") INTEGER (U"Number of bytes per line", U"20") OK DO const char32 *name = GET_STRING (U"Name"); LOOP { iam (FileInMemory); MelderInfo_open (); FileInMemory_showAsCode (me, name, GET_INTEGER (U"Number of bytes per line")); MelderInfo_close (); } END /************************* FilesInMemory ***********************************/ FORM (FilesInMemory_createFromDirectoryContents, U"Create files in memory from directory contents", 0) SENTENCE (U"Name", U"list") LABEL (U"", U"Directory:") TEXTFIELD (U"Directory", U"/home/david/praat/src/espeak-work/espeak-1.46.13/espeak-data") WORD (U"Only files that match pattern", U"*.txt") OK DO autoFilesInMemory me = FilesInMemory_createFromDirectoryContents (GET_STRING (U"Directory"), GET_STRING (U"Only files that match pattern")); praat_new (me.move(), GET_STRING (U"Name")); END FORM (FilesInMemory_createCopyFromFilesInMemory, U"", 0) OPTIONMENU (U"Espeakdata", 5) OPTION (U"phons") OPTION (U"dicts") OPTION (U"voices") OPTION (U"variants") OPTION (U"voices_names") OPTION (U"variants_names") OK DO long choice = GET_INTEGER (U"Espeakdata"); if (choice == 1) { autoFilesInMemory f = (FilesInMemory) Data_copy (espeakdata_phons); praat_new (f.move(), U"espeakdata_phons"); } else if (choice == 2) { autoFilesInMemory f = (FilesInMemory) Data_copy (espeakdata_dicts); praat_new (f.move(), U"espeakdata_dicts"); } else if (choice == 3) { autoFilesInMemory f = (FilesInMemory) Data_copy (espeakdata_voices); praat_new (f.move(), U"espeakdata_voices"); } else if (choice == 4) { autoFilesInMemory f = (FilesInMemory) Data_copy (espeakdata_variants); praat_new (f.move(), U"espeakdata_variants"); } else if (choice == 5) { autoStrings s = (Strings) Data_copy (espeakdata_voices_names); praat_new (s.move(), U"espeakdata_voices_names"); } else if (choice == 6) { autoStrings s = (Strings) Data_copy (espeakdata_variants_names); praat_new (s.move(), U"espeakdata_variants_names"); } END FORM (FilesInMemory_showAsCode, U"FilesInMemory: Show as code", 0) WORD (U"Name", U"example") INTEGER (U"Number of bytes per line", U"20") OK DO LOOP { iam (FilesInMemory); MelderInfo_open (); FilesInMemory_showAsCode (me, GET_STRING (U"Name"), GET_INTEGER (U"Number of bytes per line")); MelderInfo_close (); } END FORM (FilesInMemory_showOneFileAsCode, U"FilesInMemory: Show one file as code", 0) NATURAL (U"Index", U"1") WORD (U"Name", U"example") INTEGER (U"Number of bytes per line", U"20") OK DO LOOP { iam (FilesInMemory); MelderInfo_open (); FilesInMemory_showOneFileAsCode (me, GET_INTEGER (U"Index"), GET_STRING (U"Name"), GET_INTEGER (U"Number of bytes per line")); MelderInfo_close (); } END DIRECT (FileInMemory_to_FilesInMemory) autoFilesInMemory thee = FilesInMemory_create (); LOOP { iam (FileInMemory); FileInMemory him = Data_copy (me); Collection_addItem (thee.peek(), him); } praat_new (thee.move(), U"files"); END DIRECT (FilesInMemory_addItems) FilesInMemory thee = FIRST (FilesInMemory); LOOP { iam (Daata); if (CLASS == classFileInMemory) { FileInMemory t1 = (FileInMemory) Data_copy (me); Collection_addItem (thee, t1); } } END DIRECT (FilesInMemory_merge) FilesInMemory f1 = nullptr, f2 = nullptr; LOOP { iam (FilesInMemory); (f1 ? f2 : f1) = me; } Melder_assert (f1 != 0 && f2 != 0); autoFilesInMemory fim = (FilesInMemory) Collections_merge (f1, f2); praat_new (fim.move(), f1 -> name, U"_", f2 -> name); END DIRECT (FilesInMemory_to_Strings_id) LOOP { iam (FilesInMemory); autoStrings thee = FilesInMemory_to_Strings_id (me); praat_new (thee.move(), my name); } END /************************* FilterBank ***********************************/ FORM (FilterBank_drawFilters, U"FilterBank: Draw filters", 0) REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") REAL (U"left Frequency range", U"0.0") REAL (U"right Frequency range", U"0.0") REAL (U"left Amplitude range", U"0.0") REAL (U"right Amplitude range", U"0.0") OK DO autoPraatPicture picture; LOOP { iam (Matrix); Matrix_drawRows (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Frequency range"), GET_REAL (U"right Frequency range"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range")); } END FORM (FilterBank_drawOneContour, U"FilterBank: Draw one contour", 0) REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") REAL (U"left Frequency range", U"0.0") REAL (U"right Frequency range", U"0.0") REAL (U"Height (dB)", U"40.0") OK DO autoPraatPicture picture; LOOP { iam (Matrix); Matrix_drawOneContour (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Frequency range"), GET_REAL (U"right Frequency range"), GET_REAL (U"Height")); } END FORM (FilterBank_drawContours, U"FilterBank: Draw contours", 0) REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") REAL (U"left Frequency range", U"0.0") REAL (U"right Frequency range", U"0.0") REAL (U"left Amplitude range", U"0.0") REAL (U"right Amplitude range", U"0.0") OK DO autoPraatPicture picture; LOOP { iam (Matrix); Matrix_drawContours (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Frequency range"), GET_REAL (U"right Frequency range"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range")); } END FORM (FilterBank_drawFrequencyScales, U"FilterBank: Draw frequency scales", U"FilterBank: Draw frequency scales...") RADIO (U"Horizontal frequency scale", 1) RADIOBUTTON (U"Hertz") RADIOBUTTON (U"Bark") RADIOBUTTON (U"mel") REAL (U"left Horizontal frequency range", U"0.0") REAL (U"right Horizontal frequency range", U"0.0") RADIO (U"Vertical frequency scale", 1) RADIOBUTTON (U"Hertz") RADIOBUTTON (U"Bark") RADIOBUTTON (U"mel") REAL (U"left Vertical frequency range", U"0.0") REAL (U"right Vertical frequency range", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (FilterBank); FilterBank_drawFrequencyScales (me, GRAPHICS, GET_INTEGER (U"Horizontal frequency scale"), GET_REAL (U"left Horizontal frequency range"), GET_REAL (U"right Horizontal frequency range"), GET_INTEGER (U"Vertical frequency scale"), GET_REAL (U"left Vertical frequency range"), GET_REAL (U"right Vertical frequency range"), GET_INTEGER (U"Garnish")); } END FORM (MelSpectrogram_paintImage, U"MelSpectrogram: Paint image", U"MelSpectrogram: Paint image...") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") REAL (U"left Frequency range (mel)", U"0.0") REAL (U"right Frequency range (mel)", U"0.0") REAL (U"left Amplitude range (dB)", U"0.0") REAL (U"right Amplitude range (dB)", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (MelSpectrogram); BandFilterSpectrogram_paintImage (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Frequency range"), GET_REAL (U"right Frequency range"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range"), GET_INTEGER (U"Garnish")); } END FORM (BarkSpectrogram_paintImage, U"BarkSpectrogram: Paint image", U"BarkSpectrogram: Paint image...") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") REAL (U"left Frequency range (bark)", U"0.0") REAL (U"right Frequency range (bark)", U"0.0") REAL (U"left Amplitude range (dB)", U"0.0") REAL (U"right Amplitude range (dB)", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (BarkSpectrogram); BandFilterSpectrogram_paintImage (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Frequency range"), GET_REAL (U"right Frequency range"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range"), GET_INTEGER (U"Garnish")); } END FORM (FilterBank_paintImage, U"FilterBank: Paint image", 0) REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") REAL (U"left Frequency range", U"0.0") REAL (U"right Frequency range", U"0.0") REAL (U"left Amplitude range", U"0.0") REAL (U"right Amplitude range", U"0.0") OK DO autoPraatPicture picture; LOOP { iam (Matrix); Matrix_paintImage (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Frequency range"), GET_REAL (U"right Frequency range"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range")); } END FORM (FilterBank_paintContours, U"FilterBank: Paint contours", 0) REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") REAL (U"left Frequency range", U"0.0") REAL (U"right Frequency range", U"0.0") REAL (U"left Amplitude range", U"0.0") REAL (U"right Amplitude range", U"0.0") OK DO autoPraatPicture picture; LOOP { iam (Matrix); Matrix_paintContours (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Frequency range"), GET_REAL (U"right Frequency range"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range")); } END FORM (FilterBank_paintCells, U"FilterBank: Paint cells", 0) REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") REAL (U"left Frequency range", U"0.0") REAL (U"right Frequency range", U"0.0") REAL (U"left Amplitude range", U"0.0") REAL (U"right Amplitude range", U"0.0") OK DO autoPraatPicture picture; LOOP { iam (Matrix); Matrix_paintCells (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Frequency range"), GET_REAL (U"right Frequency range"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range")); } END FORM (FilterBank_paintSurface, U"FilterBank: Paint surface", 0) REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") REAL (U"left Frequency range", U"0.0") REAL (U"right Frequency range", U"0.0") REAL (U"left Amplitude range", U"0.0") REAL (U"right Amplitude range", U"0.0") OK DO autoPraatPicture picture; LOOP { iam (Matrix); Matrix_paintSurface (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Frequency range"), GET_REAL (U"right Frequency range"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range"), 30, 45); } END FORM (FilterBank_getFrequencyInHertz, U"FilterBank: Get frequency in Hertz", U"FilterBank: Get frequency in Hertz...") REAL (U"Frequency", U"10.0") RADIO (U"Unit", 2) RADIOBUTTON (U"Hertz") RADIOBUTTON (U"Bark") RADIOBUTTON (U"mel") OK DO LOOP { iam (FilterBank); double f = FilterBank_getFrequencyInHertz (me, GET_REAL (U"Frequency"), GET_INTEGER (U"Unit")); Melder_informationReal (f, U"Hertz"); } END FORM (FilterBank_getFrequencyInBark, U"FilterBank: Get frequency in Bark", U"FilterBank: Get frequency in Bark...") REAL (U"Frequency", U"93.17") RADIO (U"Unit", 1) RADIOBUTTON (U"Hertz") RADIOBUTTON (U"Bark") RADIOBUTTON (U"mel") OK DO LOOP { iam (FilterBank); double f = FilterBank_getFrequencyInBark (me, GET_REAL (U"Frequency"), GET_INTEGER (U"Unit")); Melder_informationReal (f, U"Bark"); } END FORM (FilterBank_getFrequencyInMel, U"FilterBank: Get frequency in mel", U"FilterBank: Get frequency in mel...") REAL (U"Frequency", U"1000.0") RADIO (U"Unit", 1) RADIOBUTTON (U"Hertz") RADIOBUTTON (U"Bark") RADIOBUTTON (U"mel") OK DO LOOP { iam (FilterBank); double f = FilterBank_getFrequencyInMel (me, GET_REAL (U"Frequency"), GET_INTEGER (U"Unit")); Melder_informationReal (f, U"mel"); } END FORM (FilterBank_equalizeIntensities, U"FilterBank: Equalize intensities", nullptr) REAL (U"Intensity (dB)", U"80.0") OK DO LOOP { iam (FilterBank); FilterBank_equalizeIntensities (me, GET_REAL (U"Intensity")); praat_dataChanged (me); } END FORM (BandFilterSpectrogram_equalizeIntensities, U"BandFilterSpectrogram: Equalize intensities", nullptr) REAL (U"Intensity (dB)", U"80.0") OK DO LOOP { iam (BandFilterSpectrogram); BandFilterSpectrogram_equalizeIntensities (me, GET_REAL (U"Intensity")); praat_dataChanged (me); } END DIRECT (FilterBank_to_Matrix) LOOP { iam (FilterBank); autoMatrix thee = FilterBank_to_Matrix (me); praat_new (thee.move(), my name); } END FORM (BandFilterSpectrogram_to_Matrix, U"BandFilterSpectrogram: To Matrix", nullptr) BOOLEAN (U"Convert to dB values", 1) OK DO LOOP { iam (BandFilterSpectrogram); autoMatrix thee = BandFilterSpectrogram_to_Matrix (me, GET_INTEGER (U"Convert to dB values")); praat_new (thee.move(), my name); } END FORM (FilterBanks_crossCorrelate, U"FilterBanks: Cross-correlate", nullptr) RADIO_ENUM (U"Amplitude scaling", kSounds_convolve_scaling, DEFAULT) RADIO_ENUM (U"Signal outside time domain is...", kSounds_convolve_signalOutsideTimeDomain, DEFAULT) OK DO FilterBank f1 = nullptr, f2 = nullptr; LOOP { iam (FilterBank); (f1 ? f2 : f1) = me; } Melder_assert (f1 && f2); autoSound result = FilterBanks_crossCorrelate (f1, f2, GET_ENUM (kSounds_convolve_scaling, U"Amplitude scaling"), GET_ENUM (kSounds_convolve_signalOutsideTimeDomain, U"Signal outside time domain is...")); praat_new (result.move(), f1 -> name, U"_", f2 -> name); END FORM (BandFilterSpectrograms_crossCorrelate, U"BandFilterSpectrograms: Cross-correlate", nullptr) RADIO_ENUM (U"Amplitude scaling", kSounds_convolve_scaling, DEFAULT) RADIO_ENUM (U"Signal outside time domain is...", kSounds_convolve_signalOutsideTimeDomain, DEFAULT) OK DO BandFilterSpectrogram f1 = nullptr, f2 = nullptr; LOOP { iam (BandFilterSpectrogram); (f1 ? f2 : f1) = me; } Melder_assert (f1 && f2); autoSound result = BandFilterSpectrograms_crossCorrelate (f1, f2, GET_ENUM (kSounds_convolve_scaling, U"Amplitude scaling"), GET_ENUM (kSounds_convolve_signalOutsideTimeDomain, U"Signal outside time domain is...")); praat_new (result.move(), f1 -> name, U"_", f2 -> name); END FORM (FilterBanks_convolve, U"FilterBanks: Convolve", nullptr) RADIO_ENUM (U"Amplitude scaling", kSounds_convolve_scaling, DEFAULT) RADIO_ENUM (U"Signal outside time domain is...", kSounds_convolve_signalOutsideTimeDomain, DEFAULT) OK DO FilterBank f1 = nullptr, f2 = nullptr; LOOP { iam (FilterBank); (f1 ? f2 : f1) = me; } Melder_assert (f1 && f2); autoSound result = FilterBanks_convolve (f1, f2, GET_ENUM (kSounds_convolve_scaling, U"Amplitude scaling"), GET_ENUM (kSounds_convolve_signalOutsideTimeDomain, U"Signal outside time domain is...")); praat_new (result.move(), f1 -> name, U"_", f2 -> name); END FORM (BandFilterSpectrograms_convolve, U"BandFilterSpectrograms: Convolve", nullptr) RADIO_ENUM (U"Amplitude scaling", kSounds_convolve_scaling, DEFAULT) RADIO_ENUM (U"Signal outside time domain is...", kSounds_convolve_signalOutsideTimeDomain, DEFAULT) OK DO BandFilterSpectrogram f1 = nullptr, f2 = nullptr; LOOP { iam (BandFilterSpectrogram); (f1 ? f2 : f1) = me; } Melder_assert (f1 && f2); autoSound result = BandFilterSpectrograms_convolve (f1, f2, GET_ENUM (kSounds_convolve_scaling, U"Amplitude scaling"), GET_ENUM (kSounds_convolve_signalOutsideTimeDomain, U"Signal outside time domain is...")); praat_new (result.move(), f1 -> name, U"_", f2 -> name); END DIRECT (FilterBank_to_Intensity) LOOP { iam (FilterBank); autoIntensity thee = FilterBank_to_Intensity (me); praat_new (thee.move(), my name); } END DIRECT (BandFilterSpectrogram_to_Intensity) LOOP { iam (BandFilterSpectrogram); autoIntensity thee = BandFilterSpectrogram_to_Intensity (me); praat_new (thee.move(), my name); } END /*********** FormantFilter *******************************************/ DIRECT (FormantFilter_help) Melder_help (U"FormantFilter"); END FORM (FormantFilter_drawFilterFunctions, U"FormantFilter: Draw filter functions", U"FilterBank: Draw filter functions...") INTEGER (U"left Filter range", U"0") INTEGER (U"right Filter range", U"0") POSITIVE (U"Bandwidth (Hz)", U"100.0") RADIO (U"Frequency scale", 1) RADIOBUTTON (U"Hertz") RADIOBUTTON (U"Bark") RADIOBUTTON (U"mel") REAL (U"left Frequency range", U"0.0") REAL (U"right Frequency range", U"0.0") BOOLEAN (U"Amplitude scale in dB", 1) REAL (U"left Amplitude range", U"0.0") REAL (U"right Amplitude range", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (FormantFilter); FormantFilter_drawFilterFunctions (me, GRAPHICS, GET_REAL (U"Bandwidth"), GET_INTEGER (U"Frequency scale"), GET_INTEGER (U"left Filter range"), GET_INTEGER (U"right Filter range"), GET_REAL (U"left Frequency range"), GET_REAL (U"right Frequency range"), GET_INTEGER (U"Amplitude scale in dB"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range"), GET_INTEGER (U"Garnish")); } END FORM (FormantFilter_drawSpectrum, U"FormantFilter: Draw spectrum (slice)", U"FilterBank: Draw spectrum (slice)...") POSITIVE (U"Time (s)", U"0.1") REAL (U"left Frequency range (Hz)", U"0.0") REAL (U"right Frequency range (Hz)", U"0.0") REAL (U"left Amplitude range (dB)", U"0.0") REAL (U"right Amplitude range (dB)", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (FilterBank); FilterBank_drawTimeSlice (me, GRAPHICS, GET_REAL (U"Time"), GET_REAL (U"left Frequency range"), GET_REAL (U"right Frequency range"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range"), U"Hz", GET_INTEGER (U"Garnish")); } END /****************** FormantGrid *********************************/ FORM (old_FormantGrid_draw, U"FormantGrid: Draw", 0) REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0 (=all)") REAL (U"left Frequency range (Hz)", U"0.0") REAL (U"right Frequency range (Hz)", U"0.0 (=auto)") BOOLEAN (U"Bandwidths", false) BOOLEAN (U"Garnish", true) OK DO autoPraatPicture picture; LOOP { iam (FormantGrid); FormantGrid_draw (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Frequency range"), GET_REAL (U"right Frequency range"), GET_INTEGER (U"Bandwidths"), GET_INTEGER (U"Garnish"), U"lines and speckles"); } END FORM (FormantGrid_draw, U"FormantGrid: Draw", 0) REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0 (=all)") REAL (U"left Frequency range (Hz)", U"0.0") REAL (U"right Frequency range (Hz)", U"0.0 (=auto)") BOOLEAN (U"Bandwidths", false) BOOLEAN (U"Garnish", true) LABEL (U"", U"") OPTIONMENU (U"Drawing method", 1) OPTION (U"lines") OPTION (U"speckles") OPTION (U"lines and speckles") OK DO_ALTERNATIVE (old_FormantGrid_draw) autoPraatPicture picture; LOOP { iam (FormantGrid); FormantGrid_draw (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Frequency range"), GET_REAL (U"right Frequency range"), GET_INTEGER (U"Bandwidths"), GET_INTEGER (U"Garnish"), GET_STRING (U"Drawing method")); } END /****************** FunctionTerms *********************************/ FORM (FunctionTerms_draw, U"FunctionTerms: Draw", 0) REAL (U"Xmin", U"0.0") REAL (U"Xmax", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") BOOLEAN (U"Extrapolate", 0) BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (FunctionTerms); FunctionTerms_draw (me, GRAPHICS, GET_REAL (U"Xmin"), GET_REAL (U"Xmax"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Extrapolate"), GET_INTEGER (U"Garnish")); } END FORM (FunctionTerms_drawBasisFunction, U"FunctionTerms: Draw basis function", 0) NATURAL (U"Index", U"1") REAL (U"Xmin", U"0.0") REAL (U"Xmax", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") BOOLEAN (U"Extrapolate", 0) BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (FunctionTerms); FunctionTerms_drawBasisFunction (me, GRAPHICS, GET_INTEGER (U"Index"), GET_REAL (U"Xmin"), GET_REAL (U"Xmax"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Extrapolate"), GET_INTEGER (U"Garnish")); } END FORM (FunctionTerms_evaluate, U"FunctionTerms: Evaluate", 0) REAL (U"X", U"0.0") OK DO LOOP { iam (FunctionTerms); Melder_information (FunctionTerms_evaluate (me, GET_REAL (U"X"))); } END DIRECT (FunctionTerms_getNumberOfCoefficients) LOOP { iam (FunctionTerms); Melder_information (my numberOfCoefficients); } END FORM (FunctionTerms_getCoefficient, U"FunctionTerms: Get coefficient", 0) LABEL (U"", U"p(x) = c[1] + c[2] x + ... c[n+1] x^n") NATURAL (U"Index", U"1") OK DO long index = GET_INTEGER (U"Index"); LOOP { iam (FunctionTerms); if (index > my numberOfCoefficients) { Melder_throw (U"Index too large."); } Melder_information (my coefficients[index]); } END DIRECT (FunctionTerms_getDegree) LOOP { iam (FunctionTerms); Melder_information (FunctionTerms_getDegree (me)); } END FORM (FunctionTerms_getMaximum, U"FunctionTerms: Get maximum", U"Polynomial: Get maximum...") LABEL (U"", U"Interval") REAL (U"Xmin", U"0.0") REAL (U"Xmax", U"0.0") OK DO LOOP { iam (FunctionTerms); double x = FunctionTerms_getMaximum (me, GET_REAL (U"Xmin"), GET_REAL (U"Xmax")); Melder_information (x); } END FORM (FunctionTerms_getMinimum, U"FunctionTerms: Get minimum", U"Polynomial: Get minimum...") LABEL (U"", U"Interval") REAL (U"Xmin", U"0.0") REAL (U"Xmax", U"0.0") OK DO LOOP { iam (FunctionTerms); double x = FunctionTerms_getMinimum (me, GET_REAL (U"Xmin"), GET_REAL (U"Xmax")); Melder_information (x); } END FORM (FunctionTerms_getXOfMaximum, U"FunctionTerms: Get x of maximum", U"Polynomial: Get x of maximum...") LABEL (U"", U"Interval") REAL (U"Xmin", U"0.0") REAL (U"Xmax", U"0.0") OK DO LOOP { iam (FunctionTerms); double x = FunctionTerms_getXOfMaximum (me, GET_REAL (U"Xmin"), GET_REAL (U"Xmax")); Melder_information (x); } END FORM (FunctionTerms_getXOfMinimum, U"FunctionTerms: Get x of minimum", U"Polynomial: Get x of minimum...") LABEL (U"", U"Interval") REAL (U"Xmin", U"0.0") REAL (U"Xmax", U"0.0") OK DO LOOP { iam (FunctionTerms); double x = FunctionTerms_getXOfMinimum (me, GET_REAL (U"Xmin"), GET_REAL (U"Xmax")); Melder_information (x); } END FORM (FunctionTerms_setCoefficient, U"FunctionTerms: Set coefficient", 0) LABEL (U"", U"p(x) = c[1]F[0] + c[2]F[1] + ... c[n+1]F[n]") LABEL (U"", U"F[k] is of degree k") NATURAL (U"Index", U"1") REAL (U"Value", U"0.0") OK DO LOOP { iam (FunctionTerms); FunctionTerms_setCoefficient (me, GET_INTEGER (U"Index"), GET_REAL (U"Value")); } END FORM (FunctionTerms_setDomain, U"FunctionTerms: Set domain", 0) REAL (U"Xmin", U"0.0") REAL (U"Xmax", U"2.0") OK DO double xmin = GET_REAL (U"Xmin"), xmax = GET_REAL (U"Xmax"); LOOP { iam (FunctionTerms); if (xmax <= xmin) { Melder_throw (U"Xmax should be larger than Xmin."); } FunctionTerms_setDomain (me, xmin, xmax); } END /***************** Intensity ***************************************************/ FORM (Intensity_to_TextGrid_detectSilences, U"Intensity: To TextGrid (silences)", U"Intensity: To TextGrid (silences)...") REAL (U"Silence threshold (dB)", U"-25.0") POSITIVE (U"Minimum silent interval duration (s)", U"0.1") POSITIVE (U"Minimum sounding interval duration (s)", U"0.05") WORD (U"Silent interval label", U"silent") WORD (U"Sounding interval label", U"sounding") OK DO LOOP { iam (Intensity); autoTextGrid thee = Intensity_to_TextGrid_detectSilences (me, GET_REAL (U"Silence threshold"), GET_REAL (U"Minimum silent interval duration"), GET_REAL (U"Minimum sounding interval duration"), GET_STRING (U"Silent interval label"), GET_STRING (U"Sounding interval label")); praat_new (thee.move(), my name); } END /***************** IntensityTier ***************************************************/ FORM (IntensityTier_to_TextGrid_detectSilences, U"IntensityTier: To TextGrid (silences)", U"Intensity: To TextGrid (silences)...") REAL (U"Silence threshold (dB)", U"-25.0") POSITIVE (U"Minimum silent interval duration (s)", U"0.1") POSITIVE (U"Minimum sounding interval duration (s)", U"0.05") WORD (U"Silent interval label", U"silent") WORD (U"Sounding interval label", U"sounding") POSITIVE (U"Time step (s)", U"0.001") OK DO LOOP { iam (IntensityTier); autoTextGrid thee = IntensityTier_to_TextGrid_detectSilences (me, GET_REAL (U"Time step"), GET_REAL (U"Silence threshold"), GET_REAL (U"Minimum silent interval duration"), GET_REAL (U"Minimum sounding interval duration"), GET_STRING (U"Silent interval label"), GET_STRING (U"Sounding interval label")); praat_new (thee.move(), my name); } END FORM (IntensityTier_to_Intensity, U"", 0) POSITIVE (U"Time step (s)", U"0.001") OK DO LOOP { iam (IntensityTier); autoIntensity thee = IntensityTier_to_Intensity (me, GET_REAL (U"Time step")); praat_new (thee.move(), my name); } END /***************** ISpline ***************************************************/ DIRECT (ISpline_help) Melder_help (U"ISpline"); END FORM (ISpline_create, U"Create ISpline", U"Create ISpline...") WORD (U"Name", U"ispline") LABEL (U"", U"Domain") REAL (U"Xmin", U"0") REAL (U"Xmax", U"1") LABEL (U"", U"ISpline(x) = c[1] I[1](x) + c[2] I[1](x) + ... c[n] I[n](x)") LABEL (U"", U"all I[k] are polynomials of degree \"Degree\"") LABEL (U"", U"Relation: numberOfCoefficients == numberOfInteriorKnots + degree") INTEGER (U"Degree", U"3") SENTENCE (U"Coefficients (c[k])", U"1.2 2.0 1.2 1.2 3.0 0.0") SENTENCE (U"Interior knots" , U"0.3 0.5 0.6") OK DO double xmin = GET_REAL (U"Xmin"), xmax = GET_REAL (U"Xmax"); long degree = GET_INTEGER (U"Degree"); if (xmax <= xmin) { Melder_throw (U"Xmin should be smaller than Xmax."); } autoISpline me = ISpline_createFromStrings (xmin, xmax, degree, GET_STRING (U"Coefficients"), GET_STRING (U"Interior knots")); praat_new (me.move(), GET_STRING (U"Name")); END /******************* KlattTable *********************************/ DIRECT (KlattTable_help) Melder_help (U"KlattTable"); END DIRECT (KlattTable_createExample) autoKlattTable thee = KlattTable_createExample (); praat_new (thee.transfer(), U"example"); END FORM (KlattTable_to_Sound, U"KlattTable: To Sound", U"KlattTable: To Sound...") POSITIVE (U"Sampling frequency", U"16000") RADIO (U"Synthesis model", 1) RADIOBUTTON (U"Cascade") RADIOBUTTON (U"Parallel") NATURAL (U"Number of formants", U"5") POSITIVE (U"Frame duration (s)", U"0.005") REAL (U"Flutter percentage (%)", U"0.0") // ppgb: foutgevoelig OPTIONMENU (U"Voicing source", 1) OPTION (U"Impulsive") OPTION (U"Natural") OPTIONMENU (U"Output type", 1) OPTION (U"Sound") OPTION (U"Voicing") OPTION (U"Aspiration") OPTION (U"Frication") OPTION (U"Cascade-glottal-output") OPTION (U"Parallel-glottal-output") OPTION (U"Bypass-output") OPTION (U"All-excitations") OK DO double flutter = GET_REAL (U"Flutter percentage"); int outputType = GET_INTEGER (U"Output type") - 1; if (flutter < 0.0 || flutter > 100.0) { Melder_throw (U"Flutter should be between 0 and 100%."); } LOOP { iam (KlattTable); autoSound thee = KlattTable_to_Sound (me, GET_REAL (U"Sampling frequency"), GET_INTEGER (U"Synthesis model"), GET_INTEGER (U"Number of formants"), GET_REAL (U"Frame duration"), GET_INTEGER (U"Voicing source"), GET_REAL (U"Flutter percentage"), outputType); praat_new (thee.transfer(), my name); } END FORM (KlattTable_to_KlattGrid, U"KlattTable: To KlattGrid", 0) POSITIVE (U"Frame duration (s)", U"0.002") OK DO LOOP { iam (KlattTable); praat_new (KlattTable_to_KlattGrid (me, GET_REAL (U"Frame duration")).transfer(), my name); } END DIRECT (KlattTable_to_Table) LOOP { iam (KlattTable); autoTable thee = KlattTable_to_Table (me); praat_new (thee.transfer(), my name); } END DIRECT (Table_to_KlattTable) LOOP { iam (Table); autoKlattTable thee = Table_to_KlattTable (me); praat_new (thee.transfer(), my name); } END FORM (Table_getMedianAbsoluteDeviation, U"Table: Get median absolute deviation", U"Table: Get median absolute deviation...") SENTENCE (U"Column label", U"") OK DO LOOP { iam (Table); long icol = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Column label")); double mad = Table_getMedianAbsoluteDeviation (me, icol); Melder_information (mad); } END static void print_means (Table me); static void print_means (Table me) { Table_numericize_Assert (me, 2); Table_numericize_Assert (me, 3); if (my numberOfColumns < 3) { MelderInfo_writeLine (U"Table does not have the right format."); return; } MelderInfo_writeLine ( Melder_padOrTruncate (15, my columnHeaders[1].label), U"\t", Melder_padOrTruncate (15, my columnHeaders[2].label), U"\t", Melder_padOrTruncate (15, my columnHeaders[3].label)); for (long irow = 1; irow <= my rows -> size; irow++) { TableRow row = (TableRow) my rows -> item [irow]; MelderInfo_writeLine ( Melder_padOrTruncate (15, row -> cells[1].string), U"\t", Melder_padOrTruncate (15, Melder_double (row -> cells[2].number)), U"\t", Melder_padOrTruncate (15, Melder_double (row -> cells[3].number))); } } FORM (Table_getNumberOfRowsWhere, U"", 0) LABEL (U"", U"Count only rows where the following condition holds:") TEXTFIELD (U"Formula", U"1; self$[\"gender\"]=\"M\"") OK DO LOOP { iam (Table); long numberOfRows = Table_getNumberOfRowsWhere (me, GET_STRING (U"Formula"), interpreter); Melder_information (numberOfRows); } END FORM (Table_reportOneWayAnova, U"Table: Report one-way anova", U"Table: Report one-way anova...") SENTENCE (U"Column with data", U"F0") SENTENCE (U"Factor", U"Vowel") BOOLEAN (U"Table with means", 0); BOOLEAN (U"Table with differences between means", 0) BOOLEAN (U"Table with Tukey's post-hoc HSD test", 0) OK DO char32 *factor = GET_STRING (U"Factor"); char32 *dataLabel = GET_STRING (U"Column with data"); bool getMeans = GET_INTEGER (U"Table with means"); bool getMeansDiff = GET_INTEGER (U"Table with differences between means"); bool getMeansDiffProbabilities = GET_INTEGER (U"Table with Tukey's post-hoc HSD test"); LOOP { iam (Table); long factorColumn = Table_getColumnIndexFromColumnLabel (me, factor); long dataColumn = Table_getColumnIndexFromColumnLabel (me, dataLabel); autoTable means, meansDiff, meansDiffProbabilities; autoTable anova = Table_getOneWayAnalysisOfVarianceF (me, dataColumn, factorColumn, &means, &meansDiff, & meansDiffProbabilities); MelderInfo_open (); MelderInfo_writeLine (U"One-way analysis of \"", dataLabel, U"\" by \"", factor, U"\".\n"); Table_printAsAnovaTable (anova.peek()); MelderInfo_writeLine (U"\nMeans:\n"); print_means (means.peek()); MelderInfo_close (); if (getMeans) { praat_new (means.transfer(), my name, U"_groupMeans"); } if (getMeansDiff) { praat_new (meansDiff.transfer(), my name, U"_meansDiff"); } if (getMeansDiffProbabilities) { praat_new (meansDiffProbabilities.transfer(), my name, U"_meansDiffP"); } } END FORM (Table_reportTwoWayAnova, U"Table: Report two-way anova", U"Table: Report two-way anova...") SENTENCE (U"Column with data", U"Data") SENTENCE (U"First factor", U"A") SENTENCE (U"Second factor", U"B") BOOLEAN (U"Table with means", 0); OK DO char32 *factorA = GET_STRING (U"First factor"); char32 *factorB = GET_STRING (U"Second factor"); char32 *dataLabel = GET_STRING (U"Column with data"); bool getMeans = GET_INTEGER (U"Table with means"); LOOP { iam (Table); long factorColumnA = Table_getColumnIndexFromColumnLabel (me, factorA); long factorColumnB = Table_getColumnIndexFromColumnLabel (me, factorB); long dataColumn = Table_getColumnIndexFromColumnLabel (me, dataLabel); Table tmeans = 0, tsizes = 0; autoTable anova = Table_getTwoWayAnalysisOfVarianceF (me, dataColumn, factorColumnA, factorColumnB, &tmeans, &tsizes); autoTable means = tmeans, sizes = tsizes; MelderInfo_open (); MelderInfo_writeLine (U"Two-way analysis of \"", dataLabel, U"\" by \"", factorA, U"\" and \"", factorB, U".\n"); Table_printAsAnovaTable (anova.peek()); MelderInfo_writeLine (U"\nMeans:\n"); Table_printAsMeansTable (means.peek()); MelderInfo_writeLine (U"\nCell sizes:\n"); Table_printAsMeansTable (sizes.peek()); MelderInfo_close (); if (getMeans) { praat_new (means.transfer(), my name, U"_groupMeans"); } } END FORM (Table_reportOneWayKruskalWallis, U"Table: Report one-way Kruskal-Wallis", U"Table: Report one-way Kruskal-Wallis...") SENTENCE (U"Column with data", U"Data") SENTENCE (U"Factor", U"Group") OK DO char32 *factor = GET_STRING (U"Factor"); char32 *dataLabel = GET_STRING (U"Column with data"); LOOP { iam (Table); long factorColumn = Table_getColumnIndexFromColumnLabel (me, factor); long dataColumn = Table_getColumnIndexFromColumnLabel (me, dataLabel); double degreesOfFreedom, kruskalWallis, probability; autoTable thee = Table_getOneWayKruskalWallis (me, dataColumn, factorColumn, °reesOfFreedom, &kruskalWallis, &probability); MelderInfo_open (); MelderInfo_writeLine (U"One-way Kruskal-Wallis of \"", dataLabel, U"\" by \"", factor, U"\".\n"); MelderInfo_writeLine (U"Chi squared: ", kruskalWallis); MelderInfo_writeLine (U"Degrees of freedom: ", degreesOfFreedom); MelderInfo_writeLine (U"Probability: ", probability); MelderInfo_writeLine (U"\nMeans:\n"); print_means (thee.peek()); MelderInfo_close (); //praat_new (thee.transfer(), my name, U"_groupMeans"); } END FORM (Table_to_StringsIndex_column, U"Table: To StringsIndex (column)", 0) SENTENCE (U"Column label", U"") OK DO char32 *columnLabel = GET_STRING (U"Column label"); LOOP { iam (Table); long icol = Table_getColumnIndexFromColumnLabel (me, columnLabel); autoStringsIndex thee = Table_to_StringsIndex_column (me, icol); praat_new (thee.transfer(), my name, U"_", columnLabel); } END /******************* LegendreSeries *********************************/ FORM (LegendreSeries_create, U"Create LegendreSeries", U"Create LegendreSeries...") WORD (U"Name", U"ls") LABEL (U"", U"Domain") REAL (U"Xmin", U"-1") REAL (U"Xmax", U"1") LABEL (U"", U"LegendreSeries(x) = c[1] P[0](x) + c[2] P[1](x) + ... c[n+1] P[n](x)") LABEL (U"", U"P[k] is a Legendre polynomial of degree k") SENTENCE (U"Coefficients", U"0 0 1.0") OK DO double xmin = GET_REAL (U"Xmin"), xmax = GET_REAL (U"Xmax"); if (xmin >= xmax) { Melder_throw (U"Xmin must be smaller than Xmax."); } praat_new (LegendreSeries_createFromString (xmin, xmax, GET_STRING (U"Coefficients")), GET_STRING (U"Name")); END DIRECT (LegendreSeries_help) Melder_help (U"LegendreSeries"); END DIRECT (LegendreSeries_to_Polynomial) LOOP { iam (LegendreSeries); praat_new (LegendreSeries_to_Polynomial (me), my name); } END /********************* LongSound **************************************/ FORM_READ2 (LongSounds_appendToExistingSoundFile, U"LongSound: Append to existing sound file", 0, false) { autoCollection set = praat_getSelectedObjects (); LongSounds_appendToExistingSoundFile (set.peek(), file); END2 } FORM_WRITE (LongSounds_writeToStereoAiffFile, U"LongSound: Save as AIFF file", 0, U"aiff") LongSound s1 = 0, s2 = 0; LOOP { iam (LongSound); (s1 ? s2 : s1) = me; } Melder_assert (s1 != 0 && s2 != 0); LongSounds_writeToStereoAudioFile16 (s1, s2, Melder_AIFF, file); END FORM_WRITE (LongSounds_writeToStereoAifcFile, U"LongSound: Save as AIFC file", 0, U"aifc") LongSound s1 = 0, s2 = 0; LOOP { iam (LongSound); (s1 ? s2 : s1) = me; } Melder_assert (s1 != 0 && s2 != 0); LongSounds_writeToStereoAudioFile16 (s1, s2, Melder_AIFC, file); END FORM_WRITE (LongSounds_writeToStereoWavFile, U"LongSound: Save as WAV file", 0, U"wav") LongSound s1 = 0, s2 = 0; LOOP { iam (LongSound); (s1 ? s2 : s1) = me; } Melder_assert (s1 != 0 && s2 != 0); LongSounds_writeToStereoAudioFile16 (s1, s2, Melder_WAV, file); END FORM_WRITE (LongSounds_writeToStereoNextSunFile, U"LongSound: Save as NeXT/Sun file", 0, U"au") LongSound s1 = 0, s2 = 0; LOOP { iam (LongSound); (s1 ? s2 : s1) = me; } Melder_assert (s1 != 0 && s2 != 0); LongSounds_writeToStereoAudioFile16 (s1, s2, Melder_NEXT_SUN, file); END FORM_WRITE (LongSounds_writeToStereoNistFile, U"LongSound: Save as NIST file", 0, U"nist") LongSound s1 = 0, s2 = 0; LOOP { iam (LongSound); (s1 ? s2 : s1) = me; } Melder_assert (s1 != 0 && s2 != 0); LongSounds_writeToStereoAudioFile16 (s1, s2, Melder_NIST, file); END /******************* Matrix **************************************************/ FORM (Matrix_drawAsSquares, U"Matrix: Draw as squares", U"Matrix: Draw as squares...") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (Matrix); Matrix_drawAsSquares (me, GRAPHICS, GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Garnish")); } END FORM (Matrix_drawDistribution, U"Matrix: Draw distribution", U"Matrix: Draw distribution...") LABEL (U"", U"Selection of (part of) Matrix") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") LABEL (U"", U"Selection of Matrix values") REAL (U"Minimum value", U"0.0") REAL (U"Maximum value", U"0.0") LABEL (U"", U"Display of the distribution") NATURAL (U"Number of bins", U"10") REAL (U"Minimum frequency", U"0.0") REAL (U"Maximum frequency", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (Matrix); Matrix_drawDistribution (me, GRAPHICS, GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_REAL (U"Minimum value"), GET_REAL (U"Maximum value"), GET_INTEGER (U"Number of bins"), GET_REAL (U"Minimum frequency"), GET_REAL (U"Maximum frequency"), 0, GET_INTEGER (U"Garnish")); } END FORM (Matrix_drawCumulativeDistribution, U"Matrix: Draw cumulative distribution", U"") LABEL (U"", U"Selection of (part of) Matrix") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") LABEL (U"", U"Selection of Matrix values") REAL (U"Minimum value", U"0.0") REAL (U"Maximum value", U"0.0") LABEL (U"", U"Display of the distribution") NATURAL (U"Number of bins", U"10") REAL (U"Minimum", U"0.0") REAL (U"Maximum", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (Matrix); Matrix_drawDistribution (me, GRAPHICS, GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_REAL (U"Minimum value"), GET_REAL (U"Maximum value"), GET_INTEGER (U"Number of bins"), GET_REAL (U"Minimum"), GET_REAL (U"Maximum"), 1, GET_INTEGER (U"Garnish")); } END FORM (Matrix_getMean, U"Matrix: Get mean", 0) REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") OK DO Matrix me = FIRST_ANY (Matrix); double mean = Matrix_getMean (me, GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range")); Melder_informationReal (mean, nullptr); END FORM (Matrix_getStandardDeviation, U"Matrix: Get standard deviation", 0) REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") OK DO Matrix me = FIRST_ANY (Matrix); double stdev = Matrix_getStandardDeviation (me, GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range")); Melder_informationReal (stdev, nullptr); END FORM (Matrix_scale, U"Matrix: Scale", 0) LABEL (U"", U"self[row, col] := self[row, col] / `Scale factor'") RADIO (U"Scale factor", 1) RADIOBUTTON (U"Extremum in matrix") RADIOBUTTON (U"Extremum in each row") RADIOBUTTON (U"Extremum in each column") OK DO int scale = GET_INTEGER (U"Scale factor"); if (scale < 1 || scale > 3) { Melder_throw (U"Scale must be in (1,3) interval."); } autoPraatPicture picture; LOOP { iam (Matrix); Matrix_scale (me, scale); praat_dataChanged (me); } END DIRECT (Matrix_transpose) LOOP { iam (Matrix); autoMatrix thee = Matrix_transpose (me); praat_new (thee.transfer(), my name, U"_transposed"); } END FORM (Matrix_solveEquation, U"Matrix: Solve equation", U"Matrix: Solve equation...") REAL (U"Tolerance", U"1.19e-7") OK DO LOOP { iam (Matrix); autoMatrix thee = Matrix_solveEquation (me, GET_REAL (U"Tolerance")); praat_new (thee.transfer(), Thing_getName (me), U"_solution"); } END DIRECT (Matrix_Categories_to_TableOfReal) Matrix me = FIRST (Matrix); Categories cat = FIRST (Categories); autoTableOfReal thee = Matrix_and_Categories_to_TableOfReal (me, cat); praat_new (thee.transfer(), my name, U"_", cat->name); END FORM (Matrix_scatterPlot, U"Matrix: Scatter plot", 0) NATURAL (U"Column for X-axis", U"1") NATURAL (U"Column for Y-axis", U"2") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") POSITIVE (U"Mark size (mm)", U"1.0") SENTENCE (U"Mark string (+xo.)", U"+") BOOLEAN (U"Garnish", 1) OK DO long x = GET_INTEGER (U"Column for X-axis"); long y = GET_INTEGER (U"Column for Y-axis"); if (x == 0 || y == 0) { Melder_throw (U"X and Y component must differ from 0."); } LOOP { iam (Matrix); Matrix_scatterPlot (me, GRAPHICS, x, y, GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_REAL (U"Mark size"), GET_STRING (U"Mark string"), GET_INTEGER (U"Garnish")); } END DIRECT (Matrix_to_Activation) LOOP { iam (Matrix); autoActivation thee = Matrix_to_Activation (me); praat_new (thee.transfer(), my name); } END FORM (Matrices_to_DTW, U"Matrices: To DTW", U"Matrix: To DTW...") LABEL (U"", U"Distance between cepstral coefficients") REAL (U"Distance metric", U"2.0") DTW_constraints_addCommonFields (dia); OK DO int begin, end, slope; DTW_constraints_getCommonFields (dia, &begin, &end, &slope); Matrix m1 = 0, m2 = 0; LOOP { iam (Matrix); (m1 ? m2 : m1) = me; } Melder_assert (m1 && m2); autoDTW thee = Matrices_to_DTW (m1, m2, begin, end, slope, GET_REAL (U"Distance metric")); praat_new (thee.transfer(), m1->name, U"_", m2->name); END FORM (Matrix_to_Pattern, U"Matrix: To Pattern", 0) NATURAL (U"Join", U"1") OK DO LOOP { iam (Matrix); praat_new (Matrix_to_Pattern (me, GET_INTEGER (U"Join")), my name); } END /**** Filterbank (deprecated) *******/ DIRECT (FilterBank_getHighestFrequency) LOOP { iam (FilterBank); Melder_information (my ymax, U" ", my v_getFrequencyUnit ()); } END DIRECT (FilterBank_getLowestFrequency) LOOP { iam (FilterBank); Melder_information (my ymin, U" ", my v_getFrequencyUnit ()); } END DIRECT (FilterBank_getNumberOfFrequencies) LOOP { iam (FilterBank); Melder_information (my ny); } END DIRECT (FilterBank_getFrequencyDistance) LOOP { iam (FilterBank); Melder_information (my dy, U" ", my v_getFrequencyUnit ()); } END FORM (FilterBank_getXofColumn, U"Get time of column", 0) NATURAL (U"Column number", U"1") OK DO LOOP { iam (FilterBank); Melder_information (Matrix_columnToX (me, GET_INTEGER (U"Column number"))); } END FORM (FilterBank_getFrequencyOfRow, U"Get frequency of row", 0) NATURAL (U"Row number", U"1") OK DO LOOP { iam (FilterBank); Melder_information (Matrix_rowToY (me, GET_INTEGER (U"Row number")), U" ", my v_getFrequencyUnit ()); } END FORM (FilterBank_getValueInCell, U"Get value in cell", 0) POSITIVE (U"Time (s)", U"0.5") POSITIVE (U"Frequency", U"1") OK DO double t = GET_REAL (U"Time"); double f = GET_REAL (U"Frequency"); LOOP { iam (FilterBank); if (f < my ymin || f > my ymax) { Melder_throw (U"Frequency out of range."); } if (t < my xmin || t > my xmax) { Melder_throw (U"Time out of range."); } long col = Matrix_xToNearestColumn (me, t); if (col < 1) { col = 1; } if (col > my nx) { col = my nx; } long row = Matrix_yToNearestRow (me, f); if (row < 1) { row = 1; } if (row > my ny) { row = my ny; } double ta = Matrix_columnToX (me, col); double fa = Matrix_rowToY (me, row); Melder_information (my z[row][col], U" (delta t: ", ta - t, U" f: ", fa - f, U")"); } END /***** MATRIXFT *************/ DIRECT (BandFilterSpectrogram_getHighestFrequency) LOOP { iam (BandFilterSpectrogram); Melder_information (my ymax, U" ", my v_getFrequencyUnit ()); } END DIRECT (BandFilterSpectrogram_getLowestFrequency) LOOP { iam (BandFilterSpectrogram); Melder_information (my ymin, U" ", my v_getFrequencyUnit ()); } END DIRECT (BandFilterSpectrogram_getNumberOfFrequencies) LOOP { iam (BandFilterSpectrogram); Melder_information (my ny); } END DIRECT (BandFilterSpectrogram_getFrequencyDistance) LOOP { iam (BandFilterSpectrogram); Melder_information (my dy, U" ", my v_getFrequencyUnit ()); } END FORM (BandFilterSpectrogram_getFrequencyOfRow, U"Get frequency of row", 0) NATURAL (U"Row number", U"1") OK DO LOOP { iam (BandFilterSpectrogram); Melder_information (Matrix_rowToY (me, GET_INTEGER (U"Row number")), U" ", my v_getFrequencyUnit ()); } END FORM (BandFilterSpectrogram_getXofColumn, U"Get time of column", 0) NATURAL (U"Column number", U"1") OK DO LOOP { iam (BandFilterSpectrogram); Melder_information (Matrix_columnToX (me, GET_INTEGER (U"Column number"))); } END FORM (BandFilterSpectrogram_getValueInCell, U"Get value in cell", 0) POSITIVE (U"Time (s)", U"0.5") POSITIVE (U"Frequency", U"1") OK DO double t = GET_REAL (U"Time"); double f = GET_REAL (U"Frequency"); LOOP { iam (BandFilterSpectrogram); if (f < my ymin || f > my ymax) { Melder_throw (U"Frequency out of range."); } if (t < my xmin || t > my xmax) { Melder_throw (U"Time out of range."); } long col = Matrix_xToNearestColumn (me, t); if (col < 1) { col = 1; } if (col > my nx) { col = my nx; } long row = Matrix_yToNearestRow (me, f); if (row < 1) { row = 1; } if (row > my ny) { row = my ny; } double ta = Matrix_columnToX (me, col); double fa = Matrix_rowToY (me, row); Melder_information (Melder_single (my z[row][col]), U" (delta t: ", ta - t, U" f: ", fa - f, U")"); } END /**************** MelFilter *******************************************/ DIRECT (MelFilter_help) Melder_help (U"MelFilter"); END DIRECT (MelSpectrogram_help) Melder_help (U"MelSpectrogram"); END FORM (MelFilter_drawFilterFunctions, U"MelFilter: Draw filter functions", U"FilterBank: Draw filter functions...") INTEGER (U"left Filter range", U"0") INTEGER (U"right Filter range", U"0") RADIO (U"Frequency scale", 1) RADIOBUTTON (U"Hertz") RADIOBUTTON (U"Bark") RADIOBUTTON (U"Mel") REAL (U"left Frequency range", U"0.0") REAL (U"right Frequency range", U"0.0") BOOLEAN (U"Amplitude scale in dB", 0) REAL (U"left Amplitude range", U"0.0") REAL (U"right Amplitude range", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (MelFilter); MelFilter_drawFilterFunctions (me, GRAPHICS, GET_INTEGER (U"Frequency scale"), GET_INTEGER (U"left Filter range"), GET_INTEGER (U"right Filter range"), GET_REAL (U"left Frequency range"), GET_REAL (U"right Frequency range"), GET_INTEGER (U"Amplitude scale in dB"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range"), GET_INTEGER (U"Garnish")); } END FORM (MelSpectrogram_drawTriangularFilterFunctions, U"MelSpectrogram: Draw triangulat filter functions", U"MelSpectrogram: Draw filter functions...") INTEGER (U"left Filter range", U"0") INTEGER (U"right Filter range", U"0") RADIO (U"Frequency scale", 1) RADIOBUTTON (U"Mel") RADIOBUTTON (U"Hertz") REAL (U"left Frequency range", U"0.0") REAL (U"right Frequency range", U"0.0") BOOLEAN (U"Amplitude scale in dB", 0) REAL (U"left Amplitude range", U"0.0") REAL (U"right Amplitude range", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (MelSpectrogram); MelSpectrogram_drawTriangularFilterFunctions (me, GRAPHICS, GET_INTEGER (U"Frequency scale") - 1, GET_INTEGER (U"left Filter range"), GET_INTEGER (U"right Filter range"), GET_REAL (U"left Frequency range"), GET_REAL (U"right Frequency range"), GET_INTEGER (U"Amplitude scale in dB"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range"), GET_INTEGER (U"Garnish")); } END FORM (MelFilter_drawSpectrum, U"MelFilter: Draw spectrum (slice)", U"FilterBank: Draw spectrum (slice)...") POSITIVE (U"Time (s)", U"0.1") REAL (U"left Frequency range (mel)", U"0.0") REAL (U"right Frequency range (mel)", U"0.0") REAL (U"left Amplitude range (dB)", U"0.0") REAL (U"right Amplitude range (dB)", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (FilterBank); FilterBank_drawTimeSlice (me, GRAPHICS, GET_REAL (U"Time"), GET_REAL (U"left Frequency range"), GET_REAL (U"right Frequency range"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range"), U"Mels", GET_INTEGER (U"Garnish")); } END FORM (MelSpectrogram_drawSpectrumAtNearestTimeSlice, U"MelSpectrogram: Draw spectrum at nearest time slice", U"BandFilterSpectrogram: Draw spectrum at nearest time slice...") REAL (U"Time (s)", U"0.1") REAL (U"left Frequency range (mel)", U"0.0") REAL (U"right Frequency range (mel)", U"0.0") REAL (U"left Amplitude range (dB)", U"0.0") REAL (U"right Amplitude range (dB)", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (MelSpectrogram); BandFilterSpectrogram_drawSpectrumAtNearestTimeSlice (me, GRAPHICS, GET_REAL (U"Time"), GET_REAL (U"left Frequency range"), GET_REAL (U"right Frequency range"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range"), GET_INTEGER (U"Garnish")); } END FORM (BarkSpectrogram_drawSpectrumAtNearestTimeSlice, U"BarkSpectrogram: Draw spectrum at nearest time slice", U"BandFilterSpectrogram: Draw spectrum at nearest time slice...") REAL (U"Time (s)", U"0.1") REAL (U"left Frequency range (bark)", U"0.0") REAL (U"right Frequency range (bark)", U"0.0") REAL (U"left Amplitude range (dB)", U"0.0") REAL (U"right Amplitude range (dB)", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (MelSpectrogram); BandFilterSpectrogram_drawSpectrumAtNearestTimeSlice (me, GRAPHICS, GET_REAL (U"Time"), GET_REAL (U"left Frequency range"), GET_REAL (U"right Frequency range"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range"), GET_INTEGER (U"Garnish")); } END FORM (MelFilter_paint, U"FilterBank: Paint", 0) REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") REAL (U"left Frequency range (mel)", U"0.0") REAL (U"right Frequency range (mel)", U"0.0") REAL (U"left Amplitude range", U"0.0") REAL (U"right Amplitude range", U"0.0") BOOLEAN (U"Garnish", 0) OK DO autoPraatPicture picture; LOOP { iam (Matrix); FilterBank_paint ((FilterBank) me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Frequency range"), GET_REAL (U"right Frequency range"), GET_REAL (U"left Amplitude range"), GET_REAL (U"right Amplitude range"), GET_INTEGER (U"Garnish")); } END FORM (MelFilter_to_MFCC, U"MelFilter: To MFCC", U"MelSpectrogram: To MFCC...") NATURAL (U"Number of coefficients", U"12") OK DO LOOP { iam (MelFilter); praat_new (MelFilter_to_MFCC (me, GET_INTEGER (U"Number of coefficients")), my name); } END FORM (MelSpectrogram_to_MFCC, U"MelSpectrogram: To MFCC", U"MelSpectrogram: To MFCC...") NATURAL (U"Number of coefficients", U"12") OK DO LOOP { iam (MelSpectrogram); autoMFCC thee = MelSpectrogram_to_MFCC (me, GET_INTEGER (U"Number of coefficients")); praat_new (thee.transfer(), my name); } END /**************** Ltas *******************************************/ #include "UnicodeData.h" FORM (Ltas_reportSpectralTilt, U"Ltas: Report spectral tilt", 0) POSITIVE (U"left Frequency range (Hz)", U"100.0") POSITIVE (U"right Frequency range (Hz)", U"5000.0") OPTIONMENU (U"Frequency scale", 1) OPTION (U"Linear") OPTION (U"Logarithmic") OPTIONMENU (U"Fit method", 2) OPTION (U"Least squares") OPTION (U"Robust") OK DO bool logScale = GET_INTEGER (U"Frequency scale") == 2; LOOP { iam (Ltas); double a, b; Ltas_fitTiltLine (me, GET_REAL (U"left Frequency range"), GET_REAL (U"right Frequency range"), logScale, GET_INTEGER (U"Fit method"), &a, &b); MelderInfo_open (); MelderInfo_writeLine (U"Spectral model: amplitude_dB(frequency_Hz) " UNITEXT_ALMOST_EQUAL_TO " ", logScale ? U"offset + slope * log (frequency_Hz)" : U"offset + slope * frequency_Hz"); MelderInfo_writeLine (U"Slope: ", a, logScale ? U" dB/decade" : U" dB/Hz"); MelderInfo_writeLine (U"Offset: ", b, U" dB"); MelderInfo_close (); } END /**************** MFCC *******************************************/ DIRECT (MFCC_help) Melder_help (U"MFCC"); END FORM (MFCC_to_MelFilter, U"MFCC: To MelFilter", 0) INTEGER (U"From coefficient", U"0") INTEGER (U"To coefficient", U"0") OK DO LOOP { iam (MFCC); praat_new (MFCC_to_MelFilter (me, GET_INTEGER (U"From coefficient"), GET_INTEGER (U"To coefficient")), my name); } END FORM (MFCC_to_MelSpectrogram, U"MFCC: MelSpectrogram", U"MFCC: To MelSpectrogram...") INTEGER (U"From coefficient", U"0") INTEGER (U"To coefficient", U"0") BOOLEAN (U"Include constant term", 1) OK DO LOOP { iam (MFCC); autoMelSpectrogram thee = MFCC_to_MelSpectrogram (me, GET_INTEGER (U"From coefficient"), GET_INTEGER (U"To coefficient"), GET_INTEGER (U"Include constant term")); praat_new (thee.transfer(), my name); } END FORM (MFCC_to_TableOfReal, U"MFCC: To TableOfReal", U"MFCC: To TableOfReal...") BOOLEAN (U"Include energy", 0) OK DO LOOP { iam (MFCC); praat_new (MFCC_to_TableOfReal (me, GET_INTEGER (U"Include energy")), my name); } END FORM (MFCC_to_Matrix_features, U"MFCC: To Matrix (features)", U"") POSITIVE (U"Window length (s)", U"0.025") BOOLEAN (U"Include energy", 0) OK DO LOOP { iam (MFCC); praat_new (MFCC_to_Matrix_features (me, GET_REAL (U"Window length"), GET_INTEGER (U"Include energy")), my name); } END FORM (MFCCs_crossCorrelate, U"MFCC & MFCC: Cross-correlate", 0) RADIO_ENUM (U"Amplitude scaling", kSounds_convolve_scaling, DEFAULT) RADIO_ENUM (U"Signal outside time domain is...", kSounds_convolve_signalOutsideTimeDomain, DEFAULT) OK DO MFCC m1 = 0, m2 = 0; LOOP { iam (MFCC); (m1 ? m2 : m1) = me; } Melder_assert (m1 && m2); praat_new (MFCCs_crossCorrelate (m1, m2, GET_ENUM (kSounds_convolve_scaling, U"Amplitude scaling"), GET_ENUM (kSounds_convolve_signalOutsideTimeDomain, U"Signal outside time domain is...")), m1 -> name, U"_", m2 -> name); END FORM (MFCCs_convolve, U"MFCC & MFCC: Convolve", 0) RADIO_ENUM (U"Amplitude scaling", kSounds_convolve_scaling, DEFAULT) RADIO_ENUM (U"Signal outside time domain is...", kSounds_convolve_signalOutsideTimeDomain, DEFAULT) OK DO MFCC m1 = 0, m2 = 0; LOOP { iam (MFCC); (m1 ? m2 : m1) = me; } Melder_assert (m1 && m2); praat_new (MFCCs_convolve (m1, m2, GET_ENUM (kSounds_convolve_scaling, U"Amplitude scaling"), GET_ENUM (kSounds_convolve_signalOutsideTimeDomain, U"Signal outside time domain is...")), m1 -> name, U"_", m2 -> name); END DIRECT (MFCC_to_Sound) LOOP { iam (MFCC); praat_new (MFCC_to_Sound (me), my name); } END /**************** MSpline *******************************************/ FORM (MSpline_create, U"Create MSpline", U"Create MSpline...") WORD (U"Name", U"mspline") LABEL (U"", U"Domain") REAL (U"Xmin", U"0") REAL (U"Xmax", U"1") LABEL (U"", U"MSpline(x) = c[1] M[1](x) + c[2] M[1](x) + ... c[n] M[n](x)") LABEL (U"", U"all M[k] are polynomials of degree \"Degree\"") LABEL (U"", U"Relation: numberOfCoefficients == numberOfInteriorKnots + degree + 1") INTEGER (U"Degree", U"2") SENTENCE (U"Coefficients (c[k])", U"1.2 2.0 1.2 1.2 3.0 0.0") SENTENCE (U"Interior knots" , U"0.3 0.5 0.6") OK DO double xmin = GET_REAL (U"Xmin"), xmax = GET_REAL (U"Xmax"); long degree = GET_INTEGER (U"Degree"); if (xmin >= xmax) { Melder_throw (U"Xmin must be smaller than Xmax."); } praat_new (MSpline_createFromStrings (xmin, xmax, degree, GET_STRING (U"Coefficients"), GET_STRING (U"Interior knots")), GET_STRING (U"Name")); END DIRECT (MSpline_help) Melder_help (U"MSpline"); END /********************** Pattern *******************************************/ DIRECT (Pattern_and_Categories_to_Discriminant) Pattern me = FIRST (Pattern); Categories cat = FIRST (Categories); autoDiscriminant thee = Pattern_and_Categories_to_Discriminant (me, cat); praat_new (thee.transfer(), my name, U"_", cat -> name); END FORM (Pattern_draw, U"Pattern: Draw", 0) NATURAL (U"Pattern number", U"1") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (Pattern); Pattern_draw (me, GRAPHICS, GET_INTEGER (U"Pattern number"), GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Garnish")); } END FORM (Pattern_formula, U"Pattern: Formula", 0) LABEL (U"label", U" y := 1; for row := 1 to nrow do { x := 1; " "for col := 1 to ncol do { self [row, col] := `formula' ; x := x + 1 } " "y := y + 1 }}") TEXTFIELD (U"formula", U"self") OK DO praat_Fon_formula (dia, interpreter); END FORM (Pattern_setValue, U"Pattern: Set value", U"Pattern: Set value...") NATURAL (U"Row number", U"1") NATURAL (U"Column number", U"1") REAL (U"New value", U"0.0") OK DO LOOP { iam (Pattern); long row = GET_INTEGER (U"Row number"), column = GET_INTEGER (U"Column number"); if (row > my ny) { Melder_throw (U"Row number must not be greater than number of rows."); } if (column > my nx) { Melder_throw (U"Column number must not be greater than number of columns."); } my z [row] [column] = GET_REAL (U"New value"); praat_dataChanged (me); } END DIRECT (Pattern_to_Matrix) LOOP { iam (Pattern); praat_new (Pattern_to_Matrix (me), my name); } END /******************* PCA ******************************/ DIRECT (PCA_help) Melder_help (U"PCA"); END DIRECT (hint_PCA_and_TableOfReal_to_Configuration) Melder_information (U"You can get principal components by selecting a PCA and a TableOfReal\n" "together and choosing \"To Configuration...\"."); END DIRECT (hint_PCA_and_Covariance_Project) Melder_information (U"You can get a new Covariance object rotated to the directions of the direction vectors\n" " in the PCA object by selecting a PCA and a Covariance object together."); END DIRECT (hint_PCA_and_Configuration_to_TableOfReal_reconstruct) Melder_information (U"You can reconstruct the original TableOfReal as well as possible from\n" " the principal components in the Configuration and the direction vectors in the PCA object."); END FORM (PCA_and_TableOfReal_getFractionVariance, U"PCA & TableOfReal: Get fraction variance", U"PCA & TableOfReal: Get fraction variance...") NATURAL (U"left Principal component range", U"1") NATURAL (U"right Principal component range", U"1") OK DO PCA me = FIRST (PCA); TableOfReal tab = FIRST (TableOfReal); Melder_information (PCA_and_TableOfReal_getFractionVariance (me, tab, GET_INTEGER (U"left Principal component range"), GET_INTEGER (U"right Principal component range"))); END DIRECT (PCA_and_Configuration_to_TableOfReal_reconstruct) PCA me = FIRST (PCA); Configuration conf = FIRST (Configuration); autoTableOfReal thee = PCA_and_Configuration_to_TableOfReal_reconstruct (me, conf); praat_new (thee.transfer(), my name, U"_", conf->name); END FORM (PCA_and_TableOfReal_to_Configuration, U"PCA & TableOfReal: To Configuration", U"PCA & TableOfReal: To Configuration...") INTEGER (U"Number of dimensions", U"0 (=all)") OK DO long dimension = GET_INTEGER (U"Number of dimensions"); if (dimension < 0) { Melder_throw (U"Number of dimensions must be greater equal zero."); } PCA me = FIRST (PCA); TableOfReal tab = FIRST_GENERIC (TableOfReal); autoConfiguration thee = PCA_and_TableOfReal_to_Configuration (me, tab, dimension); praat_new (thee.transfer(), my name, U"_", tab->name); END FORM (PCA_and_TableOfReal_to_TableOfReal_zscores, U"PCA & TableOfReal: To TableOfReal (z-scores)", U"PCA & TableOfReal: To TableOfReal (z-scores)...") INTEGER (U"Number of dimensions", U"0 (=all)") OK DO long dimension = GET_INTEGER (U"Number of dimensions"); if (dimension < 0) { Melder_throw (U"Number of dimensions must be greater than or equal to zero."); } PCA me = FIRST (PCA); TableOfReal thee = FIRST_GENERIC (TableOfReal); autoTableOfReal him = PCA_and_TableOfReal_to_TableOfReal_zscores (me, thee, dimension); praat_new (him.transfer(), my name, U"_", thy name, U"_zscores"); END FORM (PCA_getCentroidElement, U"PCA: Get centroid element...", 0) NATURAL (U"Number", U"1") OK DO long number = GET_INTEGER (U"Number"); LOOP { iam (PCA); if (number > my dimension) { Melder_throw (U"Number may not be larger than ", my dimension, U"."); } Melder_information (my centroid[number], U" (element ", number, U")"); } END FORM (PCA_getEqualityOfEigenvalues, U"PCA: Get equality of eigenvalues", U"PCA: Get equality of eigenvalues...") INTEGER (U"left Eigenvalue range", U"0") INTEGER (U"right Eigenvalue range", U"0") BOOLEAN (U"Conservative test", 0) OK DO LOOP { iam (PCA); long ndf; double p, chisq; PCA_getEqualityOfEigenvalues (me, GET_INTEGER (U"left Eigenvalue range"), GET_INTEGER (U"right Eigenvalue range"), GET_INTEGER (U"Conservative test"), &p, &chisq, &ndf); Melder_information (p, U" (=probability, based on chisq = ", chisq, U"and ndf = ", ndf); } END FORM (PCA_getNumberOfComponentsVAF, U"PCA: Get number of components (VAF)", U"PCA: Get number of components (VAF)...") POSITIVE (U"Variance fraction (0-1)", U"0.95") OK DO double f = GET_REAL (U"Variance fraction"); LOOP { iam (Eigen); if (f <= 0 || f > 1) { Melder_throw (U"The variance fraction must be in interval (0-1)."); } Melder_information (Eigen_getDimensionOfFraction (me, f)); } END FORM (PCA_getFractionVAF, U"PCA: Get fraction variance accounted for", U"PCA: Get fraction variance accounted for...") NATURAL (U"left Principal component range", U"1") NATURAL (U"right Principal component range", U"1") OK DO long from = GET_INTEGER (U"left Principal component range"); long to = GET_INTEGER (U"right Principal component range"); if (from > to) { Melder_throw (U"The second component must be greater than or equal to the first component."); } LOOP { iam (Eigen); if (from > to) { Melder_throw (U"The second component must be greater than or equal to the first component."); } Melder_information (Eigen_getCumulativeContributionOfComponents (me, from, to)); } END FORM (PCA_invertEigenvector, U"PCA: Invert eigenvector", 0) NATURAL (U"Eigenvector number", U"1") OK DO LOOP { iam (Eigen); Eigen_invertEigenvector (me, GET_INTEGER (U"Eigenvector number")); praat_dataChanged (me); } END FORM (PCA_to_TableOfReal_reconstruct1, U"PCA: To TableOfReal (reconstruct)", U"PCA: To TableOfReal (reconstruct 1)...") SENTENCE (U"Coefficients", U"1.0 1.0") OK DO LOOP { iam (PCA); autoTableOfReal thee = PCA_to_TableOfReal_reconstruct1 (me, GET_STRING (U"Coefficients")); praat_new (thee.transfer(), my name, U"_reconstructed"); } END FORM (PCAs_to_Procrustes, U"PCA & PCA: To Procrustes", U"PCA & PCA: To Procrustes...") NATURAL (U"left Eigenvector range", U"1") NATURAL (U"right Eigenvector range", U"2") OK DO long from = GET_INTEGER (U"left Eigenvector range"); long to = GET_INTEGER (U"right Eigenvector range"); PCA p1 = 0, p2 = 0; LOOP { iam (PCA); (p1 ? p2 : p1) = me; } Melder_assert (p1 && p2); autoProcrustes thee = Eigens_to_Procrustes (p1, p2, from, to); praat_new (thee.transfer(), Thing_getName (p1), U"_", Thing_getName (p2)); END DIRECT (PCAs_getAngleBetweenPc1Pc2Plane_degrees) PCA p1 = 0, p2 = 0; LOOP { iam (PCA); (p1 ? p2 : p1) = me; } Melder_assert (p1 && p2); Melder_information (Eigens_getAngleBetweenEigenplanes_degrees (p1, p2), U" degrees (=angle of intersection between the two pc1-pc2 eigenplanes)"); END /******************* Permutation **************************************/ DIRECT (Permutation_help) Melder_help (U"Permutation"); END FORM (Permutation_create, U"Create Permutation", U"Create Permutation...") WORD (U"Name", U"p") NATURAL (U"Number of elements", U"10") BOOLEAN (U"Identity Permutation", 1) OK DO Permutation p = Permutation_create (GET_INTEGER (U"Number of elements")); int identity = GET_INTEGER (U"Identity Permutation"); if (! identity) { Permutation_permuteRandomly_inline (p, 0, 0); } praat_new (p, GET_STRING (U"Name")); END DIRECT (Permutation_getNumberOfElements) LOOP { iam (Permutation); Melder_information (my numberOfElements); } END FORM (Permutation_getValueAtIndex, U"Permutation: Get value", U"Permutation: Get value...") NATURAL (U"Index", U"1") OK DO long index = GET_INTEGER (U"Index"); LOOP { iam (Permutation); Melder_information (Permutation_getValueAtIndex (me, index), U" (value, at index = ", index, U")"); } END FORM (Permutation_getIndexAtValue, U"Permutation: Get index", U"Permutation: Get index...") NATURAL (U"Value", U"1") OK DO long value = GET_INTEGER (U"Value"); LOOP { iam (Permutation); Melder_information (Permutation_getIndexAtValue (me, value), U" (index, at value = ", value, U")"); } END DIRECT (Permutation_sort) LOOP { iam (Permutation); Permutation_sort (me); praat_dataChanged (me); } END FORM (Permutation_swapBlocks, U"Permutation: Swap blocks", U"Permutation: Swap blocks...") NATURAL (U"From index", U"1") NATURAL (U"To index", U"2") NATURAL (U"Block size", U"1") OK DO LOOP { iam (Permutation); Permutation_swapBlocks (me, GET_INTEGER (U"From index"), GET_INTEGER (U"To index"), GET_INTEGER (U"Block size")); praat_dataChanged (me); } END FORM (Permutation_swapPositions, U"Permutation: Swap positions", U"Permutation: Swap positions...") NATURAL (U"First index", U"1") NATURAL (U"Second index", U"2") OK DO LOOP { iam (Permutation); Permutation_swapPositions (me, GET_INTEGER (U"First index"), GET_INTEGER (U"Second index")); praat_dataChanged (me); } END FORM (Permutation_swapNumbers, U"Permutation: Swap numbers", U"Permutation: Swap numbers...") NATURAL (U"First number", U"1") NATURAL (U"Second number", U"2") OK DO LOOP { iam (Permutation); Permutation_swapNumbers (me, GET_INTEGER (U"First number"), GET_INTEGER (U"Second number")); praat_dataChanged (me); } END FORM (Permutation_swapOneFromRange, U"Permutation: Swap one from range", U"Permutation: Swap one from range...") LABEL (U"", U"A randomly chosen element from ") INTEGER (U"left Index range", U"0") INTEGER (U"right Index range", U"0") LABEL (U"", U"is swapped with the element at") NATURAL (U"Index", U"1") BOOLEAN (U"Forbid same", 1) OK DO LOOP { iam (Permutation); Permutation_swapOneFromRange (me, GET_INTEGER (U"left Index range"), GET_INTEGER (U"right Index range"), GET_INTEGER (U"Index"), GET_INTEGER (U"Forbid same")); praat_dataChanged (me); } END FORM (Permutation_permuteRandomly, U"Permutation: Permute randomly", U"Permutation: Permute randomly...") INTEGER (U"left Index range", U"0") INTEGER (U"right Index range", U"0") OK DO LOOP { iam (Permutation); praat_new (Permutation_permuteRandomly (me, GET_INTEGER (U"left Index range"), GET_INTEGER (U"right Index range")), Thing_getName (me), U"_rdm"); } END FORM (Permutation_rotate, U"Permutation: Rotate", U"Permutation: Rotate...") INTEGER (U"left Index range", U"0") INTEGER (U"right Index range", U"0") INTEGER (U"Step size", U"1") OK DO long step = GET_INTEGER (U"Step size"); LOOP { iam (Permutation); praat_new (Permutation_rotate (me, GET_INTEGER (U"left Index range"), GET_INTEGER (U"right Index range"), step), Thing_getName (me), U"_rot", step); } END FORM (Permutation_reverse, U"Permutation: Reverse", U"Permutation: Reverse...") INTEGER (U"left Index range", U"0") INTEGER (U"right Index range", U"0") OK DO LOOP { iam (Permutation); praat_new (Permutation_reverse (me, GET_INTEGER (U"left Index range"), GET_INTEGER (U"right Index range")), Thing_getName (me), U"_rev"); } END FORM (Permutation_permuteBlocksRandomly, U"Permutation: Permute blocks randomly", U"Permutation: Permute randomly (blocks)...") INTEGER (U"left Index range", U"0") INTEGER (U"right Index range", U"0") NATURAL (U"Block size", U"12") BOOLEAN (U"Permute within blocks", 1) BOOLEAN (U"No doublets", 0) OK DO long blocksize = GET_INTEGER (U"Block size"); LOOP { iam (Permutation); praat_new (Permutation_permuteBlocksRandomly (me, GET_INTEGER (U"left Index range"), GET_INTEGER (U"right Index range"), blocksize, GET_INTEGER (U"Permute within blocks"), GET_INTEGER (U"No doublets")), Thing_getName (me), U"_pbr", blocksize); } END FORM (Permutation_interleave, U"Permutation: Interleave", U"Permutation: Interleave...") INTEGER (U"left Index range", U"0") INTEGER (U"right Index range", U"0") NATURAL (U"Block size", U"12") INTEGER (U"Offset", U"0") OK DO LOOP { iam (Permutation); praat_new (Permutation_interleave (me, GET_INTEGER (U"left Index range"), GET_INTEGER (U"right Index range"), GET_INTEGER (U"Block size"), GET_INTEGER (U"Offset")), Thing_getName (me), U"_itl"); } END DIRECT (Permutation_invert) LOOP { iam (Permutation); praat_new (Permutation_invert (me), Thing_getName (me), U"_inv"); } END DIRECT (Permutations_multiply) autoCollection set = praat_getSelectedObjects (); praat_new (Permutations_multiply (set.peek()), U"mul_", set -> size); END DIRECT (Permutations_next) LOOP { iam (Permutation); Permutation_next_inline (me); praat_dataChanged (me); } END DIRECT (Permutations_previous) LOOP { iam (Permutation); Permutation_previous_inline (me); praat_dataChanged (me); } END FORM (Pitches_to_DTW, U"Pitches: To DTW", U"Pitches: To DTW...") REAL (U"Voiced-unvoiced costs", U"24.0") REAL (U"Time costs weight", U"10.0") DTW_constraints_addCommonFields (dia); OK DO int begin, end, slope; DTW_constraints_getCommonFields (dia, &begin, &end, &slope); Pitch p1 = 0, p2 = 0; LOOP { iam (Pitch); (p1 ? p2 : p1) = me; } Melder_assert (p1 && p2); autoDTW thee = Pitches_to_DTW (p1, p2, GET_REAL (U"Voiced-unvoiced costs"), GET_REAL (U"Time costs weight"), begin, end, slope); praat_new (thee.transfer(), U"dtw_", Thing_getName (p1), U"_", Thing_getName (p2)); END FORM (PitchTier_to_Pitch, U"PitchTier: To Pitch", U"PitchTier: To Pitch...") POSITIVE (U"Step size", U"0.02") POSITIVE (U"Pitch floor", U"60.0") POSITIVE (U"Pitch ceiling", U"400.0") OK DO LOOP { iam (PitchTier); autoPitch thee = PitchTier_to_Pitch (me, GET_REAL (U"Step size"), GET_REAL (U"Pitch floor"), GET_REAL (U"Pitch ceiling")); praat_new (thee.transfer(), my name); } END /******************* Polygon & Categories *************************************/ FORM (Polygon_createSimple, U"Create simple Polygon", U"Create simple Polygon...") WORD (U"Name", U"p") SENTENCE (U"Vertices as X-Y pairs", U"0.0 0.0 0.0 1.0 1.0 0.0") OK DO autoPolygon thee = Polygon_createSimple (GET_STRING (U"Vertices as X-Y pairs")); praat_new (thee.transfer(), GET_STRING (U"Name")); END FORM (Polygon_createFromRandomVertices, U"", 0) WORD (U"Name", U"p") NATURAL (U"Number of vertices", U"10") REAL (U"left X range", U"0.0") REAL (U"right X range", U"1.0") REAL (U"left Y range", U"0.0") REAL (U"right Y range", U"1.0") OK DO autoPolygon thee = Polygon_createFromRandomVertices (GET_INTEGER (U"Number of vertices"), GET_REAL (U"left X range"), GET_REAL (U"right X range"), GET_REAL (U"left Y range"), GET_REAL (U"right Y range")); praat_new (thee.transfer(), GET_STRING (U"Name")); END DIRECT (Polygon_getNumberOfPoints) LOOP { iam (Polygon); Melder_information (my numberOfPoints); } END FORM (Polygon_getPointX, U"Polygon: Get point (x)", 0) NATURAL (U"Point number", U"1") OK DO long point = GET_INTEGER (U"Point number"); LOOP { iam (Polygon); if (point > my numberOfPoints) { Melder_throw (U"Point cannot be larger than ", my numberOfPoints, U"."); } Melder_information (my x[point]); } END FORM (Polygon_getPointY, U"Polygon: Get point (y)", 0) NATURAL (U"Point number", U"1") OK DO long point = GET_INTEGER (U"Point number"); LOOP { iam (Polygon); if (point > my numberOfPoints) { Melder_throw (U"Vertex cannot be larger than ", my numberOfPoints, U"."); } Melder_information (my y[point]); } END FORM (Polygon_getLocationOfPoint, U"Get location of point", U"Polygon: Get location of point...") LABEL (U"", U"Point is (I)n, (O)ut, (E)dge or (V)ertex?") REAL (U"X", U"0.0") REAL (U"Y", U"0.0") REAL (U"Precision", U"1.64e-15") OK DO double eps = GET_REAL (U"Precision"); REQUIRE (eps >= 0, U"The precision cannot be negative.") LOOP { iam (Polygon); int loc = Polygon_getLocationOfPoint (me, GET_REAL (U"X"), GET_REAL (U"Y"), eps); Melder_information (loc == Polygon_INSIDE ? U"I" : loc == Polygon_OUTSIDE ? U"O" : loc == Polygon_EDGE ? U"E" : U"V"); } END DIRECT (Polygon_getAreaOfConvexHull) LOOP { iam (Polygon); Melder_informationReal (Polygon_getAreaOfConvexHull (me), nullptr); } END FORM (Polygon_circularPermutation, U"Polygon: Circular permutation", 0) INTEGER (U"Shift", U"1") OK DO long shift = GET_INTEGER (U"Shift"); LOOP { iam (Polygon); autoPolygon thee = Polygon_circularPermutation (me, shift); praat_new (thee.transfer(), my name, U"_", shift); } END DIRECT (Polygon_simplify) LOOP { iam (Polygon); autoPolygon thee = Polygon_simplify (me); praat_new (thee.transfer(), my name, U"_s"); } END DIRECT (Polygon_convexHull) LOOP { iam (Polygon); autoPolygon thee = Polygon_convexHull (me); praat_new (thee.transfer(), my name, U"_hull"); } END FORM (Polygon_translate, U"Polygon: Translate", U"Polygon: Translate...") REAL (U"X", U"0.0") REAL (U"Y", U"0.0") OK DO LOOP { iam (Polygon); Polygon_translate (me, GET_REAL (U"X"), GET_REAL (U"Y")); praat_dataChanged (me); } END FORM (Polygon_rotate, U"Polygon: Rotate", U"Polygon: Rotate...") LABEL (U"", U"Rotate counterclockwise over the") REAL (U"Angle (degrees)", U"0.0") LABEL (U"", U"With respect to the point") REAL (U"X", U"0.0") REAL (U"Y", U"0.0") OK DO LOOP { iam (Polygon); Polygon_rotate (me, GET_REAL (U"Angle"), GET_REAL (U"X"), GET_REAL (U"Y")); praat_dataChanged (me); } END FORM (Polygon_scale, U"Polygon: Scale polygon", 0) REAL (U"X", U"0.0") REAL (U"Y", U"0.0") OK DO LOOP { iam (Polygon); Polygon_scale (me, GET_REAL (U"X"), GET_REAL (U"Y")); praat_dataChanged (me); } END FORM (Polygon_Categories_draw, U"Polygon & Categories: Draw", 0) REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") BOOLEAN (U"Garnish", 1) OK DO Polygon me = FIRST (Polygon); Categories cat = FIRST (Categories); Polygon_Categories_draw (me, cat, GRAPHICS, GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Garnish")); END DIRECT (Polygon_reverseX) LOOP { iam (Polygon); Polygon_reverseX (me); praat_dataChanged (me); } END DIRECT (Polygon_reverseY) LOOP { iam (Polygon); Polygon_reverseY (me); praat_dataChanged (me); } END /***************** Polynomial *******************/ DIRECT (Polynomial_help) Melder_help (U"Polynomial"); END FORM (Polynomial_create, U"Create Polynomial", U"Create Polynomial...") WORD (U"Name", U"p") LABEL (U"", U"Domain of polynomial") REAL (U"Xmin", U"-3") REAL (U"Xmax", U"4") LABEL (U"", U"p(x) = c[1] + c[2] x + ... c[n+1] x^n") SENTENCE (U"Coefficients", U"2.0 -1.0 -2.0 1.0") OK DO double xmin = GET_REAL (U"Xmin"), xmax = GET_REAL (U"Xmax"); if (xmin >= xmax) { Melder_throw (U"Xmin must be smaller than Xmax."); } praat_new (Polynomial_createFromString (xmin, xmax, GET_STRING (U"Coefficients")), GET_STRING (U"Name")); END FORM (Polynomial_getArea, U"Polynomial: Get area", U"Polynomial: Get area...") LABEL (U"", U"Interval") REAL (U"Xmin", U"0.0") REAL (U"Xmax", U"0.0") OK DO LOOP { iam (Polynomial); double area = Polynomial_getArea (me, GET_REAL (U"Xmin"), GET_REAL (U"Xmax")); Melder_information (area); } END DIRECT (Polynomial_getDerivative) LOOP { iam (Polynomial); praat_new (Polynomial_getDerivative (me), my name, U"_derivative"); } END DIRECT (Polynomial_getPrimitive) LOOP { iam (Polynomial); praat_new (Polynomial_getPrimitive (me), my name, U"_primitive"); } END FORM (Polynomial_scaleX, U"Polynomial: Scale x", U"Polynomial: Scale x...") LABEL (U"", U"New domain") REAL (U"Xmin", U"-1.0") REAL (U"Xmax", U"1.0") OK DO double xmin = GET_REAL (U"Xmin"), xmax = GET_REAL (U"Xmax"); if (xmin >= xmax) { Melder_throw (U"Xmin must be smaller than Xmax."); } LOOP { iam (Polynomial); praat_new (Polynomial_scaleX (me, xmin, xmax), my name, U"_scaleX"); } END DIRECT (Polynomial_scaleCoefficients_monic) LOOP { iam (Polynomial); Polynomial_scaleCoefficients_monic (me); praat_dataChanged (me); } END DIRECT (Polynomial_to_Roots) LOOP { iam (Polynomial); praat_new (Polynomial_to_Roots (me), my name); } END FORM (Polynomial_evaluate_z, U"Polynomial: Get value (complex)", U"Polynomial: Get value (complex)...") REAL (U"Real part", U"0.0") REAL (U"Imaginary part", U"0.0") OK DO dcomplex p, z = dcomplex_create (GET_REAL (U"Real part"), GET_REAL (U"Imaginary part")); LOOP { iam (Polynomial); Polynomial_evaluate_z (me, &z, &p); Melder_information (p.re, U" + ", p.im, U" i"); } END FORM (Polynomial_to_Spectrum, U"Polynomial: To Spectrum", U"Polynomial: To Spectrum...") POSITIVE (U"Nyquist frequency (Hz)", U"5000.0") NATURAL (U"Number of frequencies (>1)", U"1025") OK DO long n = GET_INTEGER (U"Number of frequencies"); LOOP { iam (Polynomial); praat_new (Polynomial_to_Spectrum (me, GET_REAL (U"Nyquist frequency"), n, 1.0), my name); } END DIRECT (Polynomials_multiply) Polynomial p1 = 0, p2 = 0; LOOP { iam (Polynomial); (p1 ? p2 : p1) = me; } Melder_assert (p1 && p2); praat_new (Polynomials_multiply (p1, p2), Thing_getName (p1), U"_x_", Thing_getName (p2)); END FORM (Polynomials_divide, U"Polynomials: Divide", U"Polynomials: Divide...") BOOLEAN (U"Want quotient", 1) BOOLEAN (U"Want remainder", 1) OK DO /* With gcc (GCC) 3.2.2 20030217 (Red Hat Linux 8.0 3.2.2-2) The following line initiates pq = nullptr and I don't know why Polynomial p1 = nullptr, p2 = nullptr, pq, pr; */ bool wantq = GET_INTEGER (U"Want quotient"); bool wantr = GET_INTEGER (U"Want remainder"); if (! wantq && ! wantr) { Melder_throw (U"Either \'Want quotient\' or \'Want remainder\' should be chosen"); } Polynomial p1 = 0, p2 = 0; LOOP { iam (Polynomial); (p1 ? p2 : p1) = me; } Melder_assert (p1 && p2); Polynomial q, r; if (! wantq) { q = 0; } if (! wantr) { r = 0; } Polynomials_divide (p1, p2, &q, &r); autoPolynomial aq = q, ar = r; if (wantq) { praat_new (aq.transfer(), Thing_getName (p1), U"_q"); } if (wantr) { praat_new (ar.transfer(), Thing_getName (p1), U"_r"); } END /********************* Roots ******************************/ DIRECT (Roots_help) Melder_help (U"Roots"); END FORM (Roots_draw, U"Roots: Draw", 0) REAL (U"Minimum of real axis", U"0.0") REAL (U"Maximum of real axis", U"0.0") REAL (U"Minimum of imaginary axis", U"0.0") REAL (U"Maximum of imaginary axis", U"0.0") SENTENCE (U"Mark string (+x0...)", U"o") NATURAL (U"Mark size", U"12") BOOLEAN (U"Garnish", 0) OK DO autoPraatPicture picture; LOOP { iam (Roots); Roots_draw (me, GRAPHICS, GET_REAL (U"Minimum of real axis"), GET_REAL (U"Maximum of real axis"), GET_REAL (U"Minimum of imaginary axis"), GET_REAL (U"Maximum of imaginary axis"), GET_STRING (U"Mark string"), GET_INTEGER (U"Mark size"), GET_INTEGER (U"Garnish")); } END DIRECT (Roots_getNumberOfRoots) LOOP { iam (Roots); Melder_information (Roots_getNumberOfRoots (me)); } END FORM (Roots_getRoot, U"Roots: Get root", 0) NATURAL (U"Root number", U"1") OK DO LOOP { iam (Roots); dcomplex z = Roots_getRoot (me, GET_INTEGER (U"Root number")); Melder_information (z.re, (z.im < 0 ? U" - " : U" + "), fabs (z.im), U" i"); // ppgb: waarom hier de absolute waarde maar beneden niet? } END FORM (Roots_getRealPartOfRoot, U"Roots: Get real part", 0) NATURAL (U"Root number", U"1") OK DO LOOP { iam (Roots); dcomplex z = Roots_getRoot (me, GET_INTEGER (U"Root number")); Melder_information (z.re); } END FORM (Roots_getImaginaryPartOfRoot, U"Roots: Get imaginary part", 0) NATURAL (U"Root number", U"1") OK DO LOOP { iam (Roots); dcomplex z = Roots_getRoot (me, GET_INTEGER (U"Root number")); Melder_information (z.im); // ppgb: waarom hier de imaginaire waarde zelf, maar boven de absolute waarde daarvan? } END FORM (Roots_setRoot, U"Roots: Set root", 0) NATURAL (U"Root number", U"1") REAL (U"Real part", U"1.0/sqrt(2)") REAL (U"Imaginary part", U"1.0/sqrt(2)") OK DO LOOP { iam (Roots); Roots_setRoot (me, GET_INTEGER (U"Root number"), GET_REAL (U"Real part"), GET_REAL (U"Imaginary part")); praat_dataChanged (me); } END FORM (Roots_to_Spectrum, U"Roots: To Spectrum", U"Roots: To Spectrum...") POSITIVE (U"Nyquist frequency (Hz)", U"5000.0") NATURAL (U"Number of frequencies (>1)", U"1025") OK DO long n = GET_INTEGER (U"Number of frequencies"); LOOP { iam (Roots); praat_new (Roots_to_Spectrum (me, GET_REAL (U"Nyquist frequency"), n, 1.0), my name); } END DIRECT (Roots_and_Polynomial_polish) Roots me = FIRST (Roots); Polynomial pol = FIRST (Polynomial); Roots_and_Polynomial_polish (me, pol); praat_dataChanged (me); END /*****************************************************************************/ DIRECT (Praat_ReportFloatingPointProperties) if (! NUMfpp) { NUMmachar (); } MelderInfo_open (); MelderInfo_writeLine (U"Double precision floating point properties of this machine,"); MelderInfo_writeLine (U"as calculated by algorithms from the Binary Linear Algebra System (BLAS)"); MelderInfo_writeLine (U"Radix: ", NUMfpp -> base); MelderInfo_writeLine (U"Number of digits in mantissa: ", NUMfpp -> t); MelderInfo_writeLine (U"Smallest exponent before (gradual) underflow (expmin): ", NUMfpp -> emin); MelderInfo_writeLine (U"Largest exponent before overflow (expmax): ", NUMfpp -> emax); MelderInfo_writeLine (U"Does rounding occur in addition: ", (NUMfpp -> rnd == 1 ? U"yes" : U"no")); MelderInfo_writeLine (U"Quantization step (d): ", NUMfpp -> prec); MelderInfo_writeLine (U"Quantization error (eps = d/2): ", NUMfpp -> eps); MelderInfo_writeLine (U"Underflow threshold (= radix ^ (expmin - 1)): ", NUMfpp -> rmin); MelderInfo_writeLine (U"Safe minimum (such that its inverse does not overflow): ", NUMfpp -> sfmin); MelderInfo_writeLine (U"Overflow threshold (= (1 - eps) * radix ^ expmax): ", NUMfpp -> rmax); MelderInfo_close (); END /* #ifdef HAVE_PULSEAUDIO void pulseAudioServer_report (); DIRECT (Praat_ReportSoundServerProperties) pulseAudioServer_report (); END #endif */ FORM (Praat_getTukeyQ, U"Get TukeyQ", 0) REAL (U"Critical value", U"2.0") NATURAL (U"Number of means", U"3") POSITIVE (U"Degrees of freedom", U"10.0") NATURAL (U"Number of rows", U"1") OK DO double q = GET_REAL (U"Critical value"); REQUIRE (q > 0 , U"Critical value must be > 0.") double val = NUMtukeyQ (q, GET_INTEGER (U"Number of means"), GET_REAL (U"Degrees of freedom"), GET_INTEGER (U"Number of rows") ); Melder_informationReal (val, nullptr); END FORM (Praat_getInvTukeyQ, U"Get invTukeyQ", 0) REAL (U"Probability", U"0.05") NATURAL (U"Number of means", U"3") POSITIVE (U"Degrees of freedom", U"10.0") NATURAL (U"Number of rows", U"1") OK DO double p = GET_REAL (U"Probability"); REQUIRE (p >= 0 && p <= 1, U"Probability must be in (0,1).") double val = NUMinvTukeyQ (p, GET_INTEGER (U"Number of means"), GET_REAL (U"Degrees of freedom"), GET_INTEGER (U"Number of rows")); Melder_informationReal (val, nullptr); END /******************** Sound ****************************************/ static void Sound_create_addCommonFields (UiForm dia, const char32 *endTime) { REAL (U"Starting time (s)", U"0.0") REAL (U"Finishing time (s)", endTime) POSITIVE (U"Sampling frequency (Hz)", U"44100.0") } static void Sound_create_checkCommonFields (UiForm dia, double *startingTime, double *finishingTime, double *samplingFrequency) { double numberOfSamples_real; *startingTime = GET_REAL (U"Starting time"); *finishingTime = GET_REAL (U"Finishing time"); *samplingFrequency = GET_REAL (U"Sampling frequency"); numberOfSamples_real = round ( (*finishingTime - *startingTime) * *samplingFrequency); if (*finishingTime <= *startingTime) { if (*finishingTime == *startingTime) { Melder_throw (U"A Sound cannot have a duration of zero."); } else { Melder_throw (U"A Sound cannot have a duration less than zero."); } if (*startingTime == 0.0) { Melder_throw (U"Please set the finishing time to something greater than 0 seconds."); } else { Melder_throw (U"Please lower the starting time or raise the finishing time."); } } if (*samplingFrequency <= 0.0) Melder_throw (U"A Sound cannot have a negative sampling frequency.\n" U"Please set the sampling frequency to something greater than zero, e.g. 44100 Hz."); if (numberOfSamples_real < 1.0) { Melder_appendError (U"A Sound cannot have zero samples.\n"); if (*startingTime == 0.0) { Melder_throw (U"Please raise the finishing time."); } else { Melder_throw (U"Please lower the starting time or raise the finishing time."); } } if (numberOfSamples_real > LONG_MAX) { // ppgb: kan niet in een 64-bit-omgeving Melder_throw (U"A Sound cannot have ", Melder_bigInteger ((long) numberOfSamples_real), U" samples; the maximum is ", Melder_bigInteger (LONG_MAX), U" samples.\n"); #if 0 if (*startingTime == 0.0) { Melder_throw (U"Please lower the finishing time or the sampling frequency."); } else { Melder_throw (U"Please raise the starting time, lower the finishing time, or lower the sampling frequency."); } #endif } } FORM (Sound_and_Pitch_to_FormantFilter, U"Sound & Pitch: To FormantFilter", U"Sound & Pitch: To Spectrogram...") POSITIVE (U"Analysis window duration (s)", U"0.015") POSITIVE (U"Time step (s)", U"0.005") LABEL (U"", U"Filter bank parameters") POSITIVE (U"Position of first filter (Hz)", U"100.0") POSITIVE (U"Distance between filters (Hz)", U"50.0") REAL (U"Maximum frequency", U"0"); POSITIVE (U"Relative bandwidth", U"1.1") OK DO Sound me = FIRST (Sound); Pitch p = FIRST (Pitch); praat_new (Sound_and_Pitch_to_FormantFilter (me, p, GET_REAL (U"Analysis window duration"), GET_REAL (U"Time step"), GET_REAL (U"Position of first filter"), GET_REAL (U"Maximum frequency"), GET_REAL (U"Distance between filters"), GET_REAL (U"Relative bandwidth")), my name, U"_", p->name); END FORM (Sound_and_Pitch_to_Spectrogram, U"Sound & Pitch: To Spectrogram", U"Sound & Pitch: To Spectrogram...") POSITIVE (U"Analysis window duration (s)", U"0.015") POSITIVE (U"Time step (s)", U"0.005") LABEL (U"", U"Filter bank parameters") POSITIVE (U"Position of first filter (Hz)", U"100.0") POSITIVE (U"Distance between filters (Hz)", U"50.0") REAL (U"Maximum frequency", U"0"); POSITIVE (U"Relative bandwidth", U"1.1") OK DO Sound me = FIRST (Sound); Pitch thee = FIRST (Pitch); autoSpectrogram him = Sound_and_Pitch_to_Spectrogram (me, thee, GET_REAL (U"Analysis window duration"), GET_REAL (U"Time step"), GET_REAL (U"Position of first filter"), GET_REAL (U"Maximum frequency"), GET_REAL (U"Distance between filters"), GET_REAL (U"Relative bandwidth")); praat_new (him.transfer(), my name, U"_", thy name); END FORM (Sound_and_Pitch_changeGender, U"Sound & Pitch: Change gender", U"Sound & Pitch: Change gender...") POSITIVE (U"Formant shift ratio", U"1.2") REAL (U"New pitch median (Hz)", U"0.0 (=no change)") POSITIVE (U"Pitch range factor", U"1.0 (=no change)") POSITIVE (U"Duration factor", U"1.0") OK DO Sound me = FIRST (Sound); Pitch p = FIRST (Pitch); autoSound thee = Sound_and_Pitch_changeGender_old (me, p, GET_REAL (U"Formant shift ratio"), GET_REAL (U"New pitch median"), GET_REAL (U"Pitch range factor"), GET_REAL (U"Duration factor")); praat_new (thee.transfer(), my name, U"_", p->name); END FORM (Sound_and_Pitch_changeSpeaker, U"Sound & Pitch: Change speaker", U"Sound & Pitch: Change speaker...") POSITIVE (U"Multiply formants by", U"1.1 (male->female)") POSITIVE (U"Multiply pitch by", U"1.8 (male->female") REAL (U"Multiply pitch range by", U"1.0 (=no change)") POSITIVE (U"Multiply duration", U"1.0") OK DO Sound me = FIRST (Sound); Pitch p = FIRST (Pitch); autoSound thee = Sound_and_Pitch_changeSpeaker (me, p, GET_REAL (U"Multiply formants by"), GET_REAL (U"Multiply pitch by"), GET_REAL (U"Multiply pitch range by"), GET_REAL (U"Multiply duration")); praat_new (thee.transfer(), my name, U"_", p -> name); END FORM (Sound_and_IntervalTier_cutPartsMatchingLabel, U"Sound & IntervalTier: Cut parts matching label", 0) SENTENCE (U"Label", U"cut") OK DO const char32 *label = GET_STRING (U"Label"); Sound me = FIRST (Sound); IntervalTier thee = FIRST (IntervalTier); autoSound him = Sound_and_IntervalTier_cutPartsMatchingLabel (me, thee, label); praat_new (him.transfer(), my name, U"_cut"); END FORM (Sound_createFromGammaTone, U"Create a gammatone", U"Create Sound from gammatone...") WORD (U"Name", U"gammatone") Sound_create_addCommonFields (dia, U"0.1"); INTEGER (U"Gamma", U"4") POSITIVE (U"Frequency (Hz)", U"1000.0") REAL (U"Bandwidth (Hz)", U"150.0") REAL (U"Initial phase (radians)", U"0.0") REAL (U"Addition factor", U"0.0") BOOLEAN (U"Scale amplitudes", 1) OK DO double startingTime, finishingTime, samplingFrequency; long gamma = GET_INTEGER (U"Gamma"); double bandwidth = GET_REAL (U"Bandwidth"); double f = GET_REAL (U"Frequency"); Sound_create_checkCommonFields (dia, &startingTime, &finishingTime, &samplingFrequency); if (f >= samplingFrequency / 2) Melder_throw (U"Frequency cannot be larger than half the sampling frequency.\n" U"Please use a frequency smaller than ", samplingFrequency / 2); if (gamma < 0) { Melder_throw (U"Gamma cannot be negative.\nPlease use a positive or zero gamma."); } if (bandwidth < 0) { Melder_throw (U"Bandwidth cannot be negative.\nPlease use a positive or zero bandwidth."); } autoSound sound = Sound_createGammaTone (startingTime, finishingTime, samplingFrequency, gamma, f, bandwidth, GET_REAL (U"Initial phase"), GET_REAL (U"Addition factor"), GET_INTEGER (U"Scale amplitudes")); //Sound_create_check (sound.peek(), startingTime, finishingTime, samplingFrequency);//TODO praat_new (sound.transfer(), GET_STRING (U"Name")); END FORM (Sound_createFromShepardTone, U"Create a Shepard tone", U"Create Sound from Shepard tone...") WORD (U"Name", U"shepardTone") Sound_create_addCommonFields (dia, U"1.0"); POSITIVE (U"Lowest frequency (Hz)", U"4.863") NATURAL (U"Number of components", U"10") REAL (U"Frequency change (semitones/s)", U"4.0") REAL (U"Amplitude range (dB)", U"30.0") REAL (U"Octave shift fraction ([0,1))", U"0.0") OK DO double startingTime, finishingTime, samplingFrequency; double amplitudeRange = GET_REAL (U"Amplitude range"); double octaveShiftFraction = GET_REAL (U"Octave shift fraction"); Sound_create_checkCommonFields (dia, &startingTime, &finishingTime, &samplingFrequency); if (amplitudeRange < 0) { Melder_throw (U"Amplitude range cannot be negative.\nPlease use a positive or zero amplitude range."); } autoSound sound = Sound_createShepardToneComplex (startingTime, finishingTime, samplingFrequency, GET_REAL (U"Lowest frequency"), GET_INTEGER (U"Number of components"), GET_REAL (U"Frequency change"), GET_REAL (U"Amplitude range"), octaveShiftFraction); // Sound_create_check (sound, startingTime, finishingTime, samplingFrequency); //TODO praat_new (sound.transfer(), GET_STRING (U"Name")); END FORM (Sound_drawWhere, U"Sound: Draw where", U"Sound: Draw where...") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range", U"0.0 (= all)") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0 (= auto)") BOOLEAN (U"Garnish", 1) LABEL (U"", U"") OPTIONMENU (U"Drawing method", 1) OPTION (U"Curve") OPTION (U"Bars") OPTION (U"Poles") OPTION (U"Speckles") LABEL (U"", U"Draw only those parts where the following condition holds:") TEXTFIELD (U"Formula", U"x < xmin + (xmax - xmin) / 2; first half") OK DO long numberOfBisections = 10; autoPraatPicture picture; LOOP { iam (Sound); Sound_drawWhere (me, GRAPHICS, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Garnish"), GET_STRING (U"Drawing method"), numberOfBisections, GET_STRING (U"Formula"), interpreter); } END FORM (Sound_playOneChannel, U"Sound: Play one channel", 0) NATURAL (U"Channel", U"1") OK DO long ichannel = GET_INTEGER (U"Channel"); LOOP { iam (Sound); if (ichannel > my ny) { Melder_throw (me, U": there is no channel ", ichannel, U". Sound has only ", my ny, U" channel", (my ny > 1 ? U"s." : U".")); } autoSound thee = Sound_extractChannel (me, ichannel); Sound_play (thee.peek(), 0, 0); } END FORM (Sound_playAsFrequencyShifted, U"Sound: Play as frequency shifted", U"Sound: Play as frequency shifted...") REAL (U"Shift by (Hz)", U"1000.0") POSITIVE (U"New sampling frequency (Hz)", U"44100.0") NATURAL (U"Precision (samples)", U"50") OK DO double shiftBy = GET_REAL (U"Shift by"); double newSamplingFrequency = GET_REAL (U"New sampling frequency"); long precision = GET_INTEGER (U"Precision"); LOOP { iam (Sound); Sound_playAsFrequencyShifted (me, shiftBy, newSamplingFrequency, precision); } END FORM (Sounds_to_DTW, U"Sounds: To DTW", 0) POSITIVE (U"Window length (s)", U"0.015") POSITIVE (U"Time step (s)", U"0.005") LABEL (U"", U"") REAL (U"Sakoe-Chiba band (s)", U"0.1") RADIO (U"Slope constraint", 1) RADIOBUTTON (U"no restriction") RADIOBUTTON (U"1/3 < slope < 3") RADIOBUTTON (U"1/2 < slope < 2") RADIOBUTTON (U"2/3 < slope < 3/2") OK DO double analysisWidth = GET_REAL (U"Window length"); double dt = GET_REAL (U"Time step"); double band = GET_REAL (U"Sakoe-Chiba band"); int slope = GET_INTEGER (U"Slope constraint"); Sound s1 = 0, s2 = 0; LOOP { iam (Sound); (s1 ? s2 : s1) = me; } Melder_assert (s1 && s2); autoDTW thee = Sounds_to_DTW (s1, s2, analysisWidth, dt, band, slope); praat_new (thee.transfer(), s1 -> name, U"_", s2 -> name); END FORM (Sound_to_TextGrid_detectSilences, U"Sound: To TextGrid (silences)", U"Sound: To TextGrid (silences)...") LABEL (U"", U"Parameters for the intensity analysis") POSITIVE (U"Minimum pitch (Hz)", U"100") REAL (U"Time step (s)", U"0.0 (= auto)") LABEL (U"", U"Silent intervals detection") REAL (U"Silence threshold (dB)", U"-25.0") POSITIVE (U"Minimum silent interval duration (s)", U"0.1") POSITIVE (U"Minimum sounding interval duration (s)", U"0.1") WORD (U"Silent interval label", U"silent") WORD (U"Sounding interval label", U"sounding") OK DO LOOP { iam (Sound); autoTextGrid thee = Sound_to_TextGrid_detectSilences (me, GET_REAL (U"Minimum pitch"), GET_REAL (U"Time step"), GET_REAL (U"Silence threshold"), GET_REAL (U"Minimum silent interval duration"), GET_REAL (U"Minimum sounding interval duration"), GET_STRING (U"Silent interval label"), GET_STRING (U"Sounding interval label")); praat_new (thee.transfer(), my name); } END FORM (Sound_copyChannelRanges, U"Sound: Copy channel ranges", 0) LABEL (U"", U"Create a new Sound from the following channels:") TEXTFIELD (U"Ranges", U"1:64") LABEL (U"", U"To supply rising or falling ranges, use e.g. 2:6 or 5:3.") OK DO LOOP { iam (Sound); autoSound thee = Sound_copyChannelRanges (me, GET_STRING (U"Ranges")); praat_new (thee.transfer(), my name, U"_channels"); } END FORM (Sound_trimSilences, U"Sound: Trim silences", U"Sound: Trim silences...") REAL (U"Trim duration (s)", U"0.08") BOOLEAN (U"Only at start and end", 1); LABEL (U"", U"Parameters for the intensity analysis") POSITIVE (U"Minimum pitch (Hz)", U"100") REAL (U"Time step (s)", U"0.0 (= auto)") LABEL (U"", U"Silent intervals detection") REAL (U"Silence threshold (dB)", U"-35.0") POSITIVE (U"Minimum silent interval duration (s)", U"0.1") POSITIVE (U"Minimum sounding interval duration (s)", U"0.05") BOOLEAN (U"Save trimming info as TextGrid", 0) WORD (U"Trim label", U"trimmed") OK DO double trimDuration = GET_REAL (U"Trim duration"); if (trimDuration < 0) { trimDuration = 0; } bool onlyAtStartAndEnd = GET_INTEGER (U"Only at start and end"); double minPitch = GET_REAL (U"Minimum pitch"); double timeStep = GET_REAL (U"Time step"); double silenceThreshold = GET_REAL (U"Silence threshold"); double minSilenceDuration = GET_REAL (U"Minimum silent interval duration"); double minSoundingDuration = GET_REAL (U"Minimum sounding interval duration"); bool saveTextGrid = GET_INTEGER (U"Save trimming info as TextGrid"); const char32 *trimlabel = GET_STRING (U"Trim label"); LOOP { iam (Sound); autoTextGrid tg; autoSound thee = Sound_trimSilences (me, trimDuration, onlyAtStartAndEnd, minPitch, timeStep, silenceThreshold, minSilenceDuration, minSoundingDuration, ( saveTextGrid ? &tg : nullptr ), trimlabel); if (saveTextGrid) { praat_new (tg.transfer(), my name, U"_trimmed"); } praat_new (thee.transfer(), my name, U"_trimmed"); } END // deprecated FORM (Sound_to_BarkFilter, U"Sound: To BarkFilter", U"Sound: To BarkSpectrogram...") POSITIVE (U"Window length (s)", U"0.015") POSITIVE (U"Time step (s)", U"0.005") LABEL (U"", U"Filter bank parameters") POSITIVE (U"Position of first filter (bark)", U"1.0") POSITIVE (U"Distance between filters (bark)", U"1.0") REAL (U"Maximum frequency (bark)", U"0"); OK DO LOOP { iam (Sound); praat_new (Sound_to_BarkFilter (me, GET_REAL (U"Window length"), GET_REAL (U"Time step"), GET_REAL (U"Position of first filter"), GET_REAL (U"Maximum frequency"), GET_REAL (U"Distance between filters")), my name); } END FORM (Sound_to_BarkSpectrogram, U"Sound: To BarkSpectrogram", U"Sound: To BarkSpectrogram...") POSITIVE (U"Window length (s)", U"0.015") POSITIVE (U"Time step (s)", U"0.005") LABEL (U"", U"Filter bank parameters") POSITIVE (U"Position of first filter (bark)", U"1.0") POSITIVE (U"Distance between filters (bark)", U"1.0") REAL (U"Maximum frequency (bark)", U"0"); OK DO LOOP { iam (Sound); autoBarkSpectrogram thee = Sound_to_BarkSpectrogram (me, GET_REAL (U"Window length"), GET_REAL (U"Time step"), GET_REAL (U"Position of first filter"), GET_REAL (U"Maximum frequency"), GET_REAL (U"Distance between filters")); praat_new (thee.transfer(), my name); } END // deprecated FORM (Sound_to_FormantFilter, U"Sound: To FormantFilter", U"Sound: To FormantFilter...") POSITIVE (U"Window length (s)", U"0.015") POSITIVE (U"Time step (s)", U"0.005") LABEL (U"", U"Filter bank parameters") POSITIVE (U"Position of first filter (Hz)", U"100.0") POSITIVE (U"Distance between filters (Hz)", U"50.0") REAL (U"Maximum frequency", U"0"); POSITIVE (U"Relative bandwidth", U"1.1") LABEL (U"", U"Pitch analysis") REAL (U"Minimum pitch (Hz)", U"75.0") REAL (U"Maximum pitch (Hz)", U"600.0") OK DO LOOP { iam (Sound); praat_new (Sound_to_FormantFilter (me, GET_REAL (U"Window length"), GET_REAL (U"Time step"), GET_REAL (U"Position of first filter"), GET_REAL (U"Maximum frequency"), GET_REAL (U"Distance between filters"), GET_REAL (U"Relative bandwidth"), GET_REAL (U"Minimum pitch"), GET_REAL (U"Maximum pitch")), my name); } END FORM (Sound_to_Spectrogram_pitchDependent, U"Sound: To Spectrogram (pitch-dependent)", U"Sound: To Spectrogram (pitch-dependent)...") POSITIVE (U"Window length (s)", U"0.015") POSITIVE (U"Time step (s)", U"0.005") LABEL (U"", U"Filter bank parameters") POSITIVE (U"Position of first filter (Hz)", U"100.0") POSITIVE (U"Distance between filters (Hz)", U"50.0") REAL (U"Maximum frequency", U"0"); POSITIVE (U"Relative bandwidth", U"1.1") LABEL (U"", U"Pitch analysis") REAL (U"Minimum pitch (Hz)", U"75.0") REAL (U"Maximum pitch (Hz)", U"600.0") OK DO LOOP { iam (Sound); autoSpectrogram thee = Sound_to_Spectrogram_pitchDependent (me, GET_REAL (U"Window length"), GET_REAL (U"Time step"), GET_REAL (U"Position of first filter"), GET_REAL (U"Maximum frequency"), GET_REAL (U"Distance between filters"), GET_REAL (U"Relative bandwidth"), GET_REAL (U"Minimum pitch"), GET_REAL (U"Maximum pitch")); praat_new (thee.transfer(), my name); } END // deprecated FORM (Sound_to_MelFilter, U"Sound: To MelFilter", U"Sound: To MelFilter...") POSITIVE (U"Window length (s)", U"0.015") POSITIVE (U"Time step (s)", U"0.005") LABEL (U"", U"Filter bank parameters") POSITIVE (U"Position of first filter (mel)", U"100.0") POSITIVE (U"Distance between filters (mel)", U"100.0") REAL (U"Maximum frequency (mel)", U"0.0"); OK DO LOOP { iam (Sound); autoMelFilter thee = Sound_to_MelFilter (me, GET_REAL (U"Window length"), GET_REAL (U"Time step"), GET_REAL (U"Position of first filter"), GET_REAL (U"Maximum frequency"), GET_REAL (U"Distance between filters")); praat_new (thee.transfer(), my name); } END FORM (Sound_to_MelSpectrogram, U"Sound: To MelSpectrogram", U"Sound: To MelSpectrogram...") POSITIVE (U"Window length (s)", U"0.015") POSITIVE (U"Time step (s)", U"0.005") LABEL (U"", U"Filter bank parameters") POSITIVE (U"Position of first filter (mel)", U"100.0") POSITIVE (U"Distance between filters (mel)", U"100.0") REAL (U"Maximum frequency (mel)", U"0.0"); OK DO LOOP { iam (Sound); autoMelSpectrogram thee = Sound_to_MelSpectrogram (me, GET_REAL (U"Window length"), GET_REAL (U"Time step"), GET_REAL (U"Position of first filter"), GET_REAL (U"Maximum frequency"), GET_REAL (U"Distance between filters")); praat_new (thee.transfer(), my name); } END FORM (Sound_to_ComplexSpectrogram, U"Sound: To ComplexSpectrogram", 0) POSITIVE (U"Window length (s)", U"0.015") POSITIVE (U"Time step", U"0.005") OK DO LOOP { iam (Sound); autoComplexSpectrogram thee = Sound_to_ComplexSpectrogram (me, GET_REAL (U"Window length"), GET_REAL (U"Time step")); praat_new (thee.transfer(), my name); } END FORM (Sound_to_Pitch_shs, U"Sound: To Pitch (shs)", U"Sound: To Pitch (shs)...") POSITIVE (U"Time step (s)", U"0.01") POSITIVE (U"Minimum pitch (Hz)", U"50.0") NATURAL (U"Max. number of candidates (Hz)", U"15") LABEL (U"", U"Algorithm parameters") POSITIVE (U"Maximum frequency component (Hz)", U"1250.0") NATURAL (U"Max. number of subharmonics", U"15") POSITIVE (U"Compression factor (<=1)", U"0.84") POSITIVE (U"Ceiling (Hz)", U"600.0") NATURAL (U"Number of points per octave", U"48"); OK DO double minimumPitch = GET_REAL (U"Minimum pitch"); double fmax = GET_REAL (U"Maximum frequency component"); double ceiling = GET_REAL (U"Ceiling"); if (minimumPitch >= ceiling) { Melder_throw (U"Minimum pitch should be smaller than ceiling."); } if (ceiling >= fmax) { Melder_throw (U"Maximum frequency must be greater than or equal to ceiling."); } LOOP { iam (Sound); autoPitch thee = Sound_to_Pitch_shs (me, GET_REAL (U"Time step"), minimumPitch, fmax, ceiling, GET_INTEGER (U"Max. number of subharmonics"), GET_INTEGER (U"Max. number of candidates"), GET_REAL (U"Compression factor"), GET_INTEGER (U"Number of points per octave")); praat_new (thee.transfer(), my name); } END FORM (Sound_fadeIn, U"Sound: Fade in", U"Sound: Fade in...") CHANNEL (U"Channel (number, 0 = (all))", U"1") REAL (U"Time (s)", U"-10000.0") REAL (U"Fade time (s)", U"0.005") BOOLEAN (U"Silent from start", 0) OK DO long channel = GET_INTEGER (U"Channel"); LOOP { iam (Sound); Sound_fade (me, channel, GET_REAL (U"Time"), GET_REAL (U"Fade time"), -1, GET_INTEGER (U"Silent from start")); praat_dataChanged (me); } END FORM (Sound_fadeOut, U"Sound: Fade out", U"Sound: Fade out...") CHANNEL (U"Channel (number, 0 = (all))", U"1") REAL (U"Time (s)", U"10000.0") REAL (U"Fade time (s)", U"-0.005") BOOLEAN (U"Silent to end", 0) OK DO long channel = GET_INTEGER (U"Channel"); LOOP { iam (Sound); Sound_fade (me, channel, GET_REAL (U"Time"), GET_REAL (U"Fade time"), 1, GET_INTEGER (U"Silent to end")); praat_dataChanged (me); } END FORM (Sound_to_KlattGrid_simple, U"Sound: To KlattGrid (simple)", U"Sound: To KlattGrid (simple)...") POSITIVE (U"Time step (s)", U"0.005") LABEL (U"", U"Formant determination") NATURAL (U"Max. number of formants", U"5") POSITIVE (U"Maximum formant (Hz)", U"5500 (=adult female)") POSITIVE (U"Window length (s)", U"0.025") POSITIVE (U"Pre-emphasis from (Hz)", U"50.0") LABEL (U"", U"Pitch determination") POSITIVE (U"Pitch floor (Hz)", U"60.0") POSITIVE (U"Pitch ceiling (Hz)", U"600.0") LABEL (U"", U"Intensity determination") POSITIVE (U"Minimum pitch (Hz)", U"100.0") BOOLEAN (U"Subtract mean", 1) OK DO LOOP { iam (Sound); praat_new (Sound_to_KlattGrid_simple (me, GET_REAL (U"Time step"), GET_INTEGER (U"Max. number of formants"), GET_REAL (U"Maximum formant"), GET_REAL (U"Window length"), GET_REAL (U"Pre-emphasis from"), GET_REAL (U"Pitch floor"), GET_REAL (U"Pitch ceiling"), GET_REAL (U"Minimum pitch"), GET_INTEGER (U"Subtract mean")).transfer(), my name); } END FORM (Sound_to_Pitch_SPINET, U"Sound: To SPINET", U"Sound: To SPINET...") POSITIVE (U"Time step (s)", U"0.005") POSITIVE (U"Window length (s)", U"0.040") LABEL (U"", U"Gammatone filter bank") POSITIVE (U"Minimum filter frequency (Hz)", U"70.0") POSITIVE (U"Maximum filter frequency (Hz)", U"5000.0") NATURAL (U"Number of filters", U"250"); POSITIVE (U"Ceiling (Hz)", U"500.0") NATURAL (U"Max. number of candidates", U"15") OK DO double fmin = GET_REAL (U"Minimum filter frequency"); double fmax = GET_REAL (U"Maximum filter frequency"); if (fmax <= fmin) { Melder_throw (U"Maximum frequency must be larger than minimum frequency."); } LOOP { iam (Sound); autoPitch thee = Sound_to_Pitch_SPINET (me, GET_REAL (U"Time step"), GET_REAL (U"Window length"), fmin, fmax, GET_INTEGER (U"Number of filters"), GET_REAL (U"Ceiling"), GET_INTEGER (U"Max. number of candidates")); praat_new (thee.transfer(), my name); } END FORM (Sound_to_Polygon, U"Sound: To Polygon", U"Sound: To Polygon...") CHANNEL (U"Channel (number, Left, or Right)", U"1") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") REAL (U"Connection y-value", U"0.0") OK DO long channel = GET_INTEGER (U"Channel"); LOOP { iam (Sound); if (channel > my ny) { channel = 1; } autoPolygon thee = Sound_to_Polygon (me, channel, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_REAL (U"Connection y-value")); praat_new (thee.transfer(), my name); } END FORM (Sounds_to_Polygon_enclosed, U"Sounds: To Polygon (enclosed)", U"Sounds: To Polygon (enclosed)...") CHANNEL (U"Channel (number, Left, or Right)", U"1") OPTION (U"Left") OPTION (U"Right") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") OK DO long channel = GET_INTEGER (U"Channel"); Sound s1 = nullptr, s2 = nullptr; LOOP { iam (Sound); (s1 ? s2 : s1) = me; } Melder_assert (s1 && s2); autoPolygon thee = Sounds_to_Polygon_enclosed (s1, s2, channel, GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range")); praat_new (thee.transfer(), s1->name, U"_", s2->name); END FORM (Sound_filterByGammaToneFilter4, U"Sound: Filter (gammatone)", U"Sound: Filter (gammatone)...") POSITIVE (U"Centre frequency (Hz)", U"1000.0") POSITIVE (U"Bandwidth (Hz)", U"150.0") OK DO LOOP { iam (Sound); autoSound thee = Sound_filterByGammaToneFilter4 (me, GET_REAL (U"Centre frequency"), GET_REAL (U"Bandwidth")); praat_new (thee.transfer(), my name, U"_filtered"); } END FORM (Sound_removeNoise, U"Sound: Remove noise", U"Sound: Remove noise...") REAL (U"left Noise time range (s)", U"0.0") REAL (U"right Noise time range (s)", U"0.0") POSITIVE (U"Window length (s)", U"0.025") LABEL (U"", U"Filter") REAL (U"left Filter frequency range (Hz)", U"80.0") REAL (U"right Filter frequency range (Hz)", U"10000.0") POSITIVE (U"Smoothing (Hz)", U"40.0") OPTIONMENU (U"Noise reduction method", 1) OPTION (U"Spectral subtraction") OK DO LOOP { iam (Sound); autoSound thee = Sound_removeNoise (me, GET_REAL (U"left Noise time range"), GET_REAL (U"right Noise time range"), GET_REAL (U"Window length"), GET_REAL (U"left Filter frequency range"), GET_REAL (U"right Filter frequency range"), GET_REAL (U"Smoothing"), GET_INTEGER (U"Noise reduction method")); praat_new (thee.transfer(), my name, U"_denoised"); } END FORM (Sound_changeSpeaker, U"Sound: Change speaker", U"Sound: Change speaker...") LABEL (U"", U"Pitch measurement parameters") POSITIVE (U"Pitch floor (Hz)", U"75.0") POSITIVE (U"Pitch ceiling (Hz)", U"600.0") LABEL (U"", U"Modification parameters") POSITIVE (U"Multiply formants by", U"1.2") POSITIVE (U"Multiply pitch by", U"1.0") REAL (U"Multiply pitch range by", U"1.0 (=no change)") POSITIVE (U"Multiply duration by", U"1.0") OK DO double minimumPitch = GET_REAL (U"Pitch floor"); double maximumPitch = GET_REAL (U"Pitch ceiling"); if (minimumPitch >= maximumPitch) { Melder_throw (U"Maximum pitch should be greater than minimum pitch."); } LOOP { iam (Sound); autoSound thee = Sound_changeSpeaker (me, minimumPitch, maximumPitch, GET_REAL (U"Multiply formants by"), GET_REAL (U"Multiply pitch by"), GET_REAL (U"Multiply pitch range by"), GET_REAL (U"Multiply duration by")); praat_new (thee.transfer(), my name, U"_changeSpeaker"); } END FORM (Sound_changeGender, U"Sound: Change gender", U"Sound: Change gender...") LABEL (U"", U"Pitch measurement parameters") POSITIVE (U"Pitch floor (Hz)", U"75.0") POSITIVE (U"Pitch ceiling (Hz)", U"600.0") LABEL (U"", U"Modification parameters") POSITIVE (U"Formant shift ratio", U"1.2") REAL (U"New pitch median (Hz)", U"0.0 (=no change)") REAL (U"Pitch range factor", U"1.0 (=no change)") POSITIVE (U"Duration factor", U"1.0") OK DO double minimumPitch = GET_REAL (U"Pitch floor"); double maximumPitch = GET_REAL (U"Pitch ceiling"); double pitchrf = GET_REAL (U"Pitch range factor"); if (minimumPitch >= maximumPitch) { Melder_throw (U"Maximum pitch should be greater than minimum pitch."); } if (pitchrf < 0) { Melder_throw (U"Pitch range factor may not be negative"); } LOOP { iam (Sound); autoSound thee = Sound_changeGender_old (me, minimumPitch, maximumPitch, GET_REAL (U"Formant shift ratio"), GET_REAL (U"New pitch median"), pitchrf, GET_REAL (U"Duration factor")); praat_new (thee.transfer(), my name, U"_changeGender"); } END FORM (Sound_paintWhere, U"Sound paint where", U"Sound: Paint where...") COLOUR (U"Colour (0-1, name, or {r,g,b})", U"0.5") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") REAL (U"Fill from level", U"0.0") BOOLEAN (U"Garnish", 1) LABEL (U"", U"Paint only those parts where the following condition holds:") TEXTFIELD (U"Formula", U"1; always") OK DO long numberOfBisections = 10; autoPraatPicture picture; LOOP { iam (Sound); Sound_paintWhere (me, GRAPHICS, GET_COLOUR (U"Colour"), GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_REAL (U"Fill from level"), GET_INTEGER (U"Garnish"), numberOfBisections, GET_STRING (U"Formula"), interpreter); } END FORM (Sounds_paintEnclosed, U"Sounds paint enclosed", U"Sounds: Paint enclosed...") COLOUR (U"Colour (0-1, name, or {r,g,b})", U"0.5") REAL (U"left Time range (s)", U"0.0") REAL (U"right Time range (s)", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") BOOLEAN (U"Garnish", 1) OK DO Sound s1 = 0, s2 = 0; LOOP { iam (Sound); (s1 ? s2 : s1) = me; } Melder_assert (s1 && s2); autoPraatPicture picture; Sounds_paintEnclosed (s1, s2, GRAPHICS, GET_COLOUR (U"Colour"), GET_REAL (U"left Time range"), GET_REAL (U"right Time range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Garnish")); END FORM_READ2 (Sound_readFromRawFileLE, U"Read Sound from raw Little Endian file", 0, true) { autoSound thee = Sound_readFromRawFile (file, nullptr, 16, 1, 0, 0, 16000); praat_new (thee.transfer(), MelderFile_name (file)); END2 } FORM_READ2 (Sound_readFromRawFileBE, U"Read Sound from raw 16-bit Little Endian file", 0, true) { autoSound thee = Sound_readFromRawFile (file, nullptr, 16, 0, 0, 0, 16000); praat_new (thee.transfer(), MelderFile_name (file)); END2 } FORM_READ2 (KlattTable_readFromRawTextFile, U"KlattTable_readFromRawTextFile", 0, true) { autoKlattTable thee = KlattTable_readFromRawTextFile (file); praat_new (thee.transfer(), MelderFile_name (file)); END2 } /************ Spectrograms *********************************************/ FORM (Spectrograms_to_DTW, U"Spectrograms: To DTW", 0) DTW_constraints_addCommonFields (dia); OK DO int begin, end, slope; DTW_constraints_getCommonFields (dia, &begin, &end, &slope); Spectrogram s1 = 0, s2 = 0; LOOP { iam (Spectrogram); (s1 ? s2 : s1) = me; } Melder_assert (s1 && s2); autoDTW thee = Spectrograms_to_DTW (s1, s2, begin, end, slope, 1); praat_new (thee.transfer(), s1->name, U"_", s2->name); END /**************** Spectrum *******************************************/ FORM (Spectrum_drawPhases, U"Spectrum: Draw phases", U"Spectrum: Draw phases...") REAL (U"From frequency (Hz)", U"0.0") REAL (U"To frequency (Hz)", U"0.0") REAL (U"Minimum phase (dB/Hz)", U"0.0 (= auto)") REAL (U"Maximum phase (dB/Hz)", U"0.0 (= auto)") BOOLEAN (U"Unwrap", 1) BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (Spectrum); Spectrum_drawPhases (me, GRAPHICS, GET_REAL (U"From frequency"), GET_REAL (U"To frequency"), GET_REAL (U"Minimum phase"), GET_REAL (U"Maximum phase"), GET_INTEGER (U"Unwrap"), GET_INTEGER (U"Garnish")); } END FORM (Spectrum_setRealValueInBin, U"Spectrum: Set real value in bin", 0) NATURAL (U"Bin number", U"100") REAL (U"Value", U"0.0") OK DO long binNumber = GET_INTEGER (U"Bin number"); LOOP { iam (Spectrum); if (binNumber > my nx) Melder_throw (U"Bin number must not exceed number of bins."); my z[1][binNumber]= GET_REAL (U"Value"); } END FORM (Spectrum_setImaginaryValueInBin, U"Spectrum: Set imaginary value in bin", 0) NATURAL (U"Bin number", U"100") REAL (U"Value", U"0.0") OK DO long binNumber = GET_INTEGER (U"Bin number"); LOOP { iam (Spectrum); if (binNumber > my nx) Melder_throw (U"Bin number must not exceed number of bins."); my z[2][binNumber]= GET_REAL (U"Value"); } END DIRECT (Spectrum_conjugate) LOOP { iam (Spectrum); Spectrum_conjugate (me); praat_dataChanged (me); } END FORM (Spectrum_shiftFrequencies, U"Spectrum: Shift frequencies", U"Spectrum: Shift frequencies...") REAL (U"Shift by (Hz)", U"1000.0") POSITIVE (U"New maximum frequency (Hz)", U"22050") NATURAL (U"Precision", U"50") OK DO double shiftBy = GET_REAL (U"Shift by"); double newMaximumFrequency = GET_REAL (U"New maximum frequency"); long precision = GET_INTEGER (U"Precision"); LOOP { iam (Spectrum); autoSpectrum thee = Spectrum_shiftFrequencies (me, shiftBy, newMaximumFrequency, precision); praat_new (thee.transfer(), my name, (shiftBy < 0 ? U"_m" : U"_"), (long) floor (shiftBy)); } END DIRECT (Spectra_multiply) Spectrum s1 = 0, s2 = 0; LOOP { iam (Spectrum); (s1 ? s2 : s1) = me; } Melder_assert (s1 && s2); praat_new (Spectra_multiply (s1, s2), Thing_getName (s1), U"_x_", Thing_getName (s2)); END FORM (Spectrum_resample, U"Spectrum: Resample", 0) NATURAL (U"New number of frequencies", U"256") OK DO long numberOfFrequencies = GET_INTEGER (U"New number of frequencies"); LOOP { iam (Spectrum); autoSpectrum thee = Spectrum_resample (me, numberOfFrequencies); praat_new (thee.transfer(), my name, U"_", numberOfFrequencies); } END FORM (Spectrum_compressFrequencyDomain, U"Spectrum: Compress frequency domain", 0) POSITIVE (U"Maximum frequency (Hz)", U"5000.0") INTEGER (U"Interpolation depth", U"50") RADIO (U"Interpolation scale", 1) RADIOBUTTON (U"Linear") RADIOBUTTON (U"Logarithmic") OK DO double maximumFrequency = GET_REAL (U"Maximum frequency"); long interpolationDepth = GET_INTEGER (U"Interpolation depth"); int freqScale = GET_INTEGER (U"Interpolation scale"); LOOP { iam (Spectrum); autoSpectrum thee = Spectrum_compressFrequencyDomain (me, maximumFrequency, interpolationDepth, freqScale, 1); praat_new (thee.transfer(), my name, U"_", (long) floor (maximumFrequency)); } END DIRECT (Spectrum_unwrap) LOOP { iam (Spectrum); praat_new (Spectrum_unwrap (me), my name); } END DIRECT (Spectrum_to_PowerCepstrum) LOOP { iam (Spectrum); autoPowerCepstrum thee = Spectrum_to_PowerCepstrum (me); praat_new (thee.transfer(), my name); } END DIRECT (Spectrum_to_Cepstrum) LOOP { iam (Spectrum); autoCepstrum thee = Spectrum_to_Cepstrum (me); praat_new (thee.transfer(), my name); } END /************* SpeechSynthesizer *************************************************/ DIRECT (SpeechSynthesizer_help) Melder_help (U"SpeechSynthesizer"); END FORM (SpeechSynthesizer_create, U"Create SpeechSynthesizer", U"Create SpeechSynthesizer...") long prefVoice = Strings_findString (espeakdata_voices_names, U"English"); if (prefVoice == 0) { prefVoice = 1; } LIST (U"Language", espeakdata_voices_names -> numberOfStrings, (const char32 **) espeakdata_voices_names -> strings, prefVoice) long prefVariant = Strings_findString (espeakdata_variants_names, U"default"); LIST (U"Voice variant", espeakdata_variants_names -> numberOfStrings, (const char32 **) espeakdata_variants_names -> strings, prefVariant) OK DO long voiceIndex = GET_INTEGER (U"Language"); long variantIndex = GET_INTEGER (U"Voice variant"); // default is not in the list! autoSpeechSynthesizer me = SpeechSynthesizer_create (espeakdata_voices_names -> strings[voiceIndex], espeakdata_variants_names -> strings[variantIndex]); praat_new (me.transfer(), espeakdata_voices_names -> strings[voiceIndex], U"_", espeakdata_variants_names -> strings[variantIndex]); END FORM (SpeechSynthesizer_playText, U"SpeechSynthesizer: Play text", U"SpeechSynthesizer: Play text...") TEXTFIELD (U"Text", U"This is some text.") OK DO const char32 *text = GET_STRING (U"Text"); LOOP { iam (SpeechSynthesizer); SpeechSynthesizer_playText (me, text); } END FORM (SpeechSynthesizer_to_Sound, U"SpeechSynthesizer: To Sound", U"SpeechSynthesizer: To Sound...") TEXTFIELD (U"Text", U"This is some text.") BOOLEAN (U"Create TextGrid with annotations", 0); OK DO const char32 *text = GET_STRING (U"Text"); bool createTextGrid = GET_INTEGER (U"Create TextGrid with annotations"); LOOP { iam (SpeechSynthesizer); autoTextGrid tg; autoTable t; autoSound thee = SpeechSynthesizer_to_Sound (me, text, (createTextGrid ? &tg : nullptr), (Melder_debug == -2 ? &t : nullptr)); praat_new (thee.transfer(), my name); if (createTextGrid) { praat_new (tg.transfer(), my name); } if (Melder_debug == -2) { praat_new (t.transfer(), my name); } } END DIRECT (SpeechSynthesizer_getVoiceName) LOOP { iam (SpeechSynthesizer); Melder_information (my d_voiceLanguageName); } END DIRECT (SpeechSynthesizer_getVoiceVariant) LOOP { iam (SpeechSynthesizer); Melder_information (my d_voiceVariantName); } END FORM (SpeechSynthesizer_setTextInputSettings, U"SpeechSynthesizer: Set text input settings", U"SpeechSynthesizer: Set text input settings...") OPTIONMENU (U"Input text format is", 1) OPTION (U"Text only") OPTION (U"Phoneme codes only") OPTION (U"Mixed with tags") OPTIONMENU (U"Input phoneme codes are", 1) OPTION (U"Kirshenbaum_espeak") OK DO int inputTextFormat = GET_INTEGER (U"Input text format is"); int inputPhonemeCoding = SpeechSynthesizer_PHONEMECODINGS_KIRSHENBAUM; // LOOP { iam (SpeechSynthesizer); SpeechSynthesizer_setTextInputSettings (me, inputTextFormat, inputPhonemeCoding); } END FORM (SpeechSynthesizer_setSpeechOutputSettings, U"SpeechSynthesizer: Set speech output settings", U"SpeechSynthesizer: Set speech output settings...") POSITIVE (U"Sampling frequency (Hz)", U"44100") REAL (U"Gap between words (s)", U"0.01") INTEGER (U"Pitch adjustment (0-99)", U"50") INTEGER (U"Pitch range (0-99)", U"50"); NATURAL (U"Words per minute (80-450)", U"175"); BOOLEAN (U"Estimate rate from data", 1); OPTIONMENU (U"Output phoneme codes are", 2) OPTION (U"Kirshenbaum_espeak") OPTION (U"IPA") OK DO double samplingFrequency = GET_REAL (U"Sampling frequency"); double wordgap = GET_REAL (U"Gap between words"); if (wordgap < 0) wordgap = 0; long pitchAdjustment = GET_INTEGER (U"Pitch adjustment"); // ppgb: waarom was dit een double? if (pitchAdjustment < 0) pitchAdjustment = 0; if (pitchAdjustment > 99) pitchAdjustment = 99; long pitchRange = GET_INTEGER (U"Pitch range"); // ppgb: waarom was dit een double? if (pitchRange < 0) pitchRange = 0; if (pitchRange > 99) pitchRange = 99; long wordsPerMinute = GET_INTEGER (U"Words per minute"); // ppgb: waarom was dit een double? bool estimateWordsPerMinute = GET_INTEGER (U"Estimate rate from data"); int outputPhonemeCodes = GET_INTEGER (U"Output phoneme codes are"); LOOP { iam (SpeechSynthesizer); SpeechSynthesizer_setSpeechOutputSettings (me, samplingFrequency, wordgap, pitchAdjustment, pitchRange, wordsPerMinute, estimateWordsPerMinute, outputPhonemeCodes); } END /************* SpeechSynthesizer and TextGrid ************************/ FORM (SpeechSynthesizer_and_TextGrid_to_Sound, U"SpeechSynthesizer & TextGrid: To Sound", 0) NATURAL (U"Tier number", U"1") NATURAL (U"Interval number", U"1") BOOLEAN (U"Create TextGrid with annotations", 0); OK DO bool createAnnotations = GET_INTEGER (U"Create TextGrid with annotations"); SpeechSynthesizer me = FIRST (SpeechSynthesizer); TextGrid thee = FIRST (TextGrid); autoTextGrid annotations; autoSound him = SpeechSynthesizer_and_TextGrid_to_Sound (me, thee, GET_INTEGER (U"Tier number"), GET_INTEGER (U"Interval number"), ( createAnnotations ? & annotations : nullptr )); praat_new (him.transfer(), my name); if (createAnnotations) { praat_new (annotations.transfer(), my name); } END FORM (SpeechSynthesizer_and_Sound_and_TextGrid_align, U"SpeechSynthesizer & Sound & TextGrid: To TextGrid (align)", 0) NATURAL (U"Tier number", U"1") NATURAL (U"From interval number", U"1") NATURAL (U"To interval number", U"1") REAL (U"Silence threshold (dB)", U"-35.0") POSITIVE (U"Minimum silent interval duration (s)", U"0.1") POSITIVE (U"Minimum sounding interval duration (s)", U"0.1") OK DO double silenceThreshold = GET_REAL (U"Silence threshold"); double minSilenceDuration = GET_REAL (U"Minimum silent interval duration"); double minSoundingDuration = GET_REAL (U"Minimum sounding interval duration"); SpeechSynthesizer synth = FIRST (SpeechSynthesizer); Sound s = FIRST (Sound); TextGrid tg = FIRST (TextGrid); autoTextGrid thee = SpeechSynthesizer_and_Sound_and_TextGrid_align (synth, s, tg, GET_INTEGER (U"Tier number"), GET_INTEGER (U"From interval number"), GET_INTEGER (U"To interval number"), silenceThreshold, minSilenceDuration, minSoundingDuration); praat_new (thee.transfer(), s -> name, U"_aligned"); END FORM (SpeechSynthesizer_and_Sound_and_TextGrid_align2, U"SpeechSynthesizer & Sound & TextGrid: To TextGrid (align, trim)", 0) NATURAL (U"Tier number", U"1") NATURAL (U"From interval number", U"1") NATURAL (U"To interval number", U"1") REAL (U"Silence threshold (dB)", U"-35.0") POSITIVE (U"Minimum silent interval duration (s)", U"0.1") POSITIVE (U"Minimum sounding interval duration (s)", U"0.1") REAL (U"Silence trim duration (s)", U"0.08") OK DO double silenceThreshold = GET_REAL (U"Silence threshold"); double minSilenceDuration = GET_REAL (U"Minimum silent interval duration"); double minSoundingDuration = GET_REAL (U"Minimum sounding interval duration"); double trimDuration = GET_REAL (U"Silence trim duration"); if (trimDuration < 0) { trimDuration = 0; } SpeechSynthesizer synth = FIRST (SpeechSynthesizer); Sound s = FIRST (Sound); TextGrid tg = FIRST (TextGrid); autoTextGrid thee = SpeechSynthesizer_and_Sound_and_TextGrid_align2 (synth, s, tg, GET_INTEGER (U"Tier number"), GET_INTEGER (U"From interval number"), GET_INTEGER (U"To interval number"), silenceThreshold, minSilenceDuration, minSoundingDuration, trimDuration); praat_new (thee.transfer(), s -> name, U"_aligned"); END /************* Spline *************************************************/ FORM (Spline_drawKnots, U"Spline: Draw knots", 0) REAL (U"Xmin", U"0.0") REAL (U"Xmax", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") BOOLEAN (U"Garnish", 1) OK DO LOOP { iam (Spline); Spline_drawKnots (me, GRAPHICS, GET_REAL (U"Xmin"), GET_REAL (U"Xmax"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Garnish")); } END DIRECT (Spline_getOrder) LOOP { iam (Spline); Melder_information (Spline_getOrder (me)); } END FORM (Spline_scaleX, U"Spline: Scale x", U"Spline: Scale x...") LABEL (U"", U"New domain") REAL (U"Xmin", U"-1.0") REAL (U"Xmax", U"1.0") OK DO double xmin = GET_REAL (U"Xmin"), xmax = GET_REAL (U"Xmax"); if (xmin >= xmax) { Melder_throw (U"Xmin must be smaller than Xmax."); } LOOP { iam (Spline); praat_new (Spline_scaleX (me, xmin, xmax), my name, U"_scaleX"); } END /************ SSCP ***************************************************/ DIRECT (SSCP_help) Melder_help (U"SSCP"); END FORM (SSCP_drawConfidenceEllipse, U"SSCP: Draw confidence ellipse", 0) POSITIVE (U"Confidence level", U"0.95") NATURAL (U"Index for X-axis", U"1") NATURAL (U"Index for Y-axis", U"2") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (SSCP); SSCP_drawConcentrationEllipse (me, GRAPHICS, GET_REAL (U"Confidence level"), 1, GET_INTEGER (U"Index for X-axis"), GET_INTEGER (U"Index for Y-axis"), GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Garnish")); } END FORM (SSCP_drawSigmaEllipse, U"SSCP: Draw sigma ellipse", U"SSCP: Draw sigma ellipse...") POSITIVE (U"Number of sigmas", U"1.0") NATURAL (U"Index for X-axis", U"1") NATURAL (U"Index for Y-axis", U"2") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (SSCP); SSCP_drawConcentrationEllipse (me, GRAPHICS, GET_REAL (U"Number of sigmas"), 0, GET_INTEGER (U"Index for X-axis"), GET_INTEGER (U"Index for Y-axis"), GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Garnish")); } END DIRECT (SSCP_extractCentroid) LOOP { iam (SSCP); praat_new (SSCP_extractCentroid (me), my name, U"_centroid"); } END FORM (SSCP_getConfidenceEllipseArea, U"SSCP: Get confidence ellipse area", U"SSCP: Get confidence ellipse area...") POSITIVE (U"Confidence level", U"0.95") NATURAL (U"Index for X-axis", U"1") NATURAL (U"Index for Y-axis", U"2") OK DO double conf = GET_REAL (U"Confidence level"); long d1 = GET_INTEGER (U"Index for X-axis"); long d2 = GET_INTEGER (U"Index for Y-axis"); LOOP { iam (SSCP); Melder_information (SSCP_getConcentrationEllipseArea (me, conf, 1, d1, d2)); } END FORM (SSCP_getFractionVariation, U"SSCP: Get fraction variation", U"SSCP: Get fraction variation...") NATURAL (U"From dimension", U"1") NATURAL (U"To dimension", U"1") OK DO LOOP { iam (SSCP); Melder_information (SSCP_getFractionVariation (me, GET_INTEGER (U"From dimension"), GET_INTEGER (U"To dimension"))); } END FORM (SSCP_getConcentrationEllipseArea, U"SSCP: Get sigma ellipse area", U"SSCP: Get sigma ellipse area...") POSITIVE (U"Number of sigmas", U"1.0") NATURAL (U"Index for X-axis", U"1") NATURAL (U"Index for Y-axis", U"2") OK DO double nsigmas = GET_REAL (U"Number of sigmas"); long d1 = GET_INTEGER (U"Index for X-axis"); long d2 = GET_INTEGER (U"Index for Y-axis"); LOOP { iam (SSCP); Melder_information (SSCP_getConcentrationEllipseArea (me, nsigmas, 0, d1, d2)); } END DIRECT (SSCP_getDegreesOfFreedom) LOOP { iam (SSCP); Melder_information (SSCP_getDegreesOfFreedom (me)); } END DIRECT (SSCP_getNumberOfObservations) LOOP { iam (SSCP); Melder_information ((long) floor (my numberOfObservations)); // ppgb: blijf ik raar vinden } END DIRECT (SSCP_getTotalVariance) LOOP { iam (SSCP); Melder_information (SSCP_getTotalVariance (me)); } END FORM (SSCP_getCentroidElement, U"SSCP: Get centroid element", U"SSCP: Get centroid element") NATURAL (U"Number", U"1") OK DO long number = GET_INTEGER (U"Number"); LOOP { iam (SSCP); if (number < 1 || number > my numberOfColumns) { Melder_throw (U"\"Number\" must be smaller than ", my numberOfColumns + 1, U"."); } Melder_information (my centroid[number]); } END DIRECT (SSCP_getLnDeterminant) LOOP { iam (SSCP); Melder_information (SSCP_getLnDeterminant (me)); } END FORM (SSCP_testDiagonality_bartlett, U"SSCP: Get diagonality (bartlett)", U"SSCP: Get diagonality (bartlett)...") NATURAL (U"Number of contraints", U"1") OK DO double chisq, p; long nc = GET_INTEGER (U"Number of contraints"); LOOP { iam (SSCP); SSCP_testDiagonality_bartlett (me, nc, &chisq, &p); Melder_information (p, U" (=probability for chisq = ", chisq, U" and ndf = ", my numberOfRows * (my numberOfRows - 1) / 2, U")"); } END DIRECT (SSCP_to_Correlation) LOOP { iam (SSCP); praat_new (SSCP_to_Correlation (me), U""); } END FORM (SSCP_to_Covariance, U"SSCP: To Covariance", U"SSCP: To Covariance...") NATURAL (U"Number of constraints", U"1") OK DO long noc = GET_INTEGER (U"Number of constraints"); LOOP { iam (SSCP); praat_new (SSCP_to_Covariance (me, noc), U""); } END DIRECT (SSCP_to_PCA) LOOP { iam (SSCP); praat_new (SSCP_to_PCA (me), U""); } END /******************* Strings ****************************/ DIRECT (Strings_createFromEspeakVoices) praat_new (nullptr, U"voices"); // TODO ?? END FORM (Strings_createAsCharacters, U"Strings: Create as characters", 0) SENTENCE (U"Text", U"intention") OK DO autoStrings thee = Strings_createAsCharacters (GET_STRING (U"Text")); praat_new (thee.transfer(), U""); END FORM (Strings_createAsTokens, U"Strings: Create as tokens", 0) SENTENCE (U"Text", U"There are seven tokens in this text") OK DO autoStrings thee = Strings_createAsTokens (GET_STRING (U"Text")); praat_new (thee.transfer(), U""); END DIRECT (Strings_append) autoCollection set = praat_getSelectedObjects (); autoStrings thee = Strings_append (set.transfer()); praat_new (thee.transfer(), U"appended"); END DIRECT (Strings_to_Categories) LOOP { iam (Strings); autoCategories thee = Strings_to_Categories (me); praat_new (thee.transfer(), U""); } END FORM (Strings_change, U"Strings: Change", U"Strings: Change") SENTENCE (U"Search", U"a") SENTENCE (U"Replace", U"a") INTEGER (U"Replace limit", U"0 (=unlimited)") RADIO (U"Search and replace are:", 1) RADIOBUTTON (U"Literals") RADIOBUTTON (U"Regular Expressions") OK DO long nmatches, nstringmatches; LOOP { iam (Strings); autoStrings thee = Strings_change (me, GET_STRING (U"Search"), GET_STRING (U"Replace"), GET_INTEGER (U"Replace limit"), &nmatches, &nstringmatches, GET_INTEGER (U"Search and replace are") - 1); praat_new (thee.transfer(), 0); } END FORM (Strings_extractPart, U"Strings: Extract part", U"") NATURAL (U"From index", U"1") NATURAL (U"To index", U"1") OK DO LOOP { iam (Strings); autoStrings thee = Strings_extractPart (me, GET_INTEGER (U"From index"), GET_INTEGER (U"To index")); praat_new (thee.transfer(), my name, U"_part"); } END DIRECT (Strings_to_EditDistanceTable) Strings s1 = nullptr, s2 = nullptr; LOOP { iam(Strings); (s1 ? s2 : s1) = me; } Melder_assert (s1 && s2); autoEditDistanceTable table = EditDistanceTable_create (s1, s2); praat_new (table.transfer(), s1 -> name, U"_", s2 -> name); END FORM (Strings_to_Permutation, U"Strings: To Permutation", U"Strings: To Permutation...") BOOLEAN (U"Sort", 1) OK DO LOOP { iam (Strings); autoPermutation thee = Strings_to_Permutation (me, GET_INTEGER (U"Sort")); praat_new (thee.transfer(), my name); } END DIRECT (Strings_and_Permutation_permuteStrings) Strings me = FIRST (Strings); Permutation p = FIRST (Permutation); autoStrings thee = Strings_and_Permutation_permuteStrings (me, p); praat_new (thee.transfer(), my name, U"_", p->name); END FORM (SVD_to_TableOfReal, U"SVD: To TableOfReal", U"SVD: To TableOfReal...") NATURAL (U"First component", U"1") INTEGER (U"Last component", U"0 (=all)") OK DO LOOP { iam (SVD); autoTableOfReal thee = SVD_to_TableOfReal (me, GET_INTEGER (U"First component"), GET_INTEGER (U"Last component")); praat_new (thee.transfer(), my name); } END DIRECT (SVD_extractLeftSingularVectors) LOOP { iam (SVD); autoTableOfReal thee = SVD_extractLeftSingularVectors (me); praat_new (thee.transfer(), my name, U"_lsv"); } END DIRECT (SVD_extractRightSingularVectors) LOOP { iam (SVD); autoTableOfReal thee = SVD_extractRightSingularVectors (me); praat_new (thee.transfer(), my name, U"_rsv"); } END DIRECT (SVD_extractSingularValues) LOOP { iam (SVD); autoTableOfReal thee = SVD_extractSingularValues (me); praat_new (thee.transfer(), my name, U"_sv"); } END /******************* Table ****************************/ DIRECT (Table_createFromPetersonBarneyData) praat_new (Table_createFromPetersonBarneyData (), U"pb"); END DIRECT (Table_createFromPolsVanNieropData) praat_new (Table_createFromPolsVanNieropData (), U"pvn"); END DIRECT (Table_createFromWeeninkData) praat_new (Table_createFromWeeninkData (), U"m10w10c10"); END FORM (Table_scatterPlotWhere, U"Table: Scatter plot where", 0) WORD (U"Horizontal column", U"") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0 (= auto)") WORD (U"Vertical column", U"") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0 (= auto)") WORD (U"Column with marks", U"") NATURAL (U"Font size", U"12") BOOLEAN (U"Garnish", 1) LABEL (U"", U"Use only data from rows where the following condition holds:") TEXTFIELD (U"Formula", U"1; self$[\"gender\"]=\"male\"") OK DO autoPraatPicture picture; LOOP { iam (Table); long xcolumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Horizontal column")); long ycolumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Vertical column")); long markColumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Column with marks")); autoTable thee = Table_extractRowsWhere (me, GET_STRING (U"Formula"), interpreter); Table_scatterPlot (thee.peek(), GRAPHICS, xcolumn, ycolumn, GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), markColumn, GET_INTEGER (U"Font size"), GET_INTEGER (U"Garnish")); } END FORM (Table_scatterPlotMarkWhere, U"Scatter plot where (marks)", 0) WORD (U"Horizontal column", U"") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0 (= auto)") WORD (U"Vertical column", U"") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0 (= auto)") POSITIVE (U"Mark size (mm)", U"1.0") BOOLEAN (U"Garnish", 1) SENTENCE (U"Mark string (+xo.)", U"+") LABEL (U"", U"Use only data from rows where the following condition holds:") TEXTFIELD (U"Formula", U"1; self$[\"gender\"]=\"male\"") OK DO autoPraatPicture picture; LOOP { iam (Table); long xcolumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Horizontal column")); long ycolumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Vertical column")); autoTable thee = Table_extractRowsWhere (me, GET_STRING (U"Formula"), interpreter); Table_scatterPlot_mark (thee.peek(), GRAPHICS, xcolumn, ycolumn, GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_REAL (U"Mark size"), GET_STRING (U"Mark string"), GET_INTEGER (U"Garnish")); } END FORM (Table_barPlotWhere, U"Table: Bar plot where", U"Table: Bar plot where...") SENTENCE (U"Vertical column(s)", U"") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0 (= auto)") SENTENCE (U"Column with labels", U"") LABEL (U"", U"Distances are in units of 'bar width'") REAL (U"Distance of first bar from border", U"1.0") REAL (U"Distance between bar groups", U"1.0") REAL (U"Distance between bars within group", U"0.0") SENTENCE (U"Colours", U"Grey") REAL (U"Label text angle (degrees)", U"0.0"); BOOLEAN (U"Garnish", 1) LABEL (U"", U"Use only data from rows where the following condition holds:") TEXTFIELD (U"Formula", U"row >= 1 and row <= 8") OK DO autoPraatPicture picture; LOOP { iam (Table); Table_barPlotWhere (me, GRAPHICS, GET_STRING (U"Vertical column"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_STRING (U"Column with labels"), GET_REAL (U"Distance of first bar from border"), GET_REAL (U"Distance between bars within group"), GET_REAL (U"Distance between bar groups"), GET_STRING (U"Colours"),GET_REAL (U"Label text angle"), GET_INTEGER (U"Garnish"), GET_STRING (U"Formula"), interpreter); } END FORM (Table_LineGraphWhere, U"Table: Line graph where", U"Table: Line graph where...") SENTENCE (U"Vertical column", U"") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0 (= auto)") SENTENCE (U"Horizonal column", U"") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0 (= auto)") WORD (U"Text", U"+") REAL (U"Label text angle (degrees)", U"0.0"); BOOLEAN (U"Garnish", 1) LABEL (U"", U"Use only data from rows where the following condition holds:") TEXTFIELD (U"Formula", U"1; (= everything)") OK DO autoPraatPicture picture; LOOP { iam (Table); long ycolumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Vertical column")); long xcolumn = Table_findColumnIndexFromColumnLabel (me, GET_STRING (U"Horizonal column")); Table_lineGraphWhere (me, GRAPHICS, xcolumn, GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), ycolumn, GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_STRING (U"Text"), GET_REAL (U"Label text angle"), GET_INTEGER (U"Garnish"), GET_STRING (U"Formula"), interpreter); } END FORM (Table_boxPlots, U"Table: Box plots", 0) WORD (U"Data columns", U"") WORD (U"Factor column", U"") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") BOOLEAN (U"Garnish", 1); OK DO autoPraatPicture picture; double ymin = GET_REAL (U"left Vertical range"); double ymax = GET_REAL (U"right Vertical range"); int garnish = GET_INTEGER (U"Garnish"); LOOP { iam (Table); long factorColumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Factor column")); Table_boxPlotsWhere (me, GRAPHICS, GET_STRING (U"Data columns"), factorColumn, ymin, ymax, garnish, U"1", interpreter); } END FORM (Table_boxPlotsWhere, U"Table: Box plots where", U"Table: Box plots where...") SENTENCE (U"Data columns", U"") WORD (U"Factor column", U"") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") BOOLEAN (U"Garnish", 1); LABEL (U"", U"Use only data in rows where the following condition holds:") TEXTFIELD (U"Formula", U"1; self$[\"gender\"]=\"male\"") OK DO autoPraatPicture picture; double ymin = GET_REAL (U"left Vertical range"); double ymax = GET_REAL (U"right Vertical range"); int garnish = GET_INTEGER (U"Garnish"); char32 *dataColumns = GET_STRING (U"Data columns"); LOOP { iam (Table); long factorColumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Factor column")); Table_boxPlotsWhere (me, GRAPHICS, dataColumns, factorColumn, ymin, ymax, garnish, GET_STRING (U"Formula"), interpreter); } END FORM (Table_drawEllipseWhere, U"Draw ellipse (standard deviation)", 0) WORD (U"Horizontal column", U"") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0 (= auto)") WORD (U"Vertical column", U"") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0 (= auto)") POSITIVE (U"Number of sigmas", U"2.0") BOOLEAN (U"Garnish", 1) LABEL (U"", U"Use only data in rows where the following condition holds:") TEXTFIELD (U"Formula", U"1; self$[\"gender\"]=\"male\"") OK DO autoPraatPicture picture; LOOP { iam (Table); long xcolumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Horizontal column")); long ycolumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Vertical column")); autoTable thee = Table_extractRowsWhere (me, GET_STRING (U"Formula"), interpreter); Table_drawEllipse_e (thee.peek(), GRAPHICS, xcolumn, ycolumn, GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_REAL (U"Number of sigmas"), GET_INTEGER (U"Garnish")); } END FORM (Table_drawEllipses, U"Table: Draw ellipses", 0) WORD (U"Horizontal column", U"F2") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0 (= auto)") WORD (U"Vertical column", U"F1") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0 (= auto)") WORD (U"Factor column", U"Vowel") POSITIVE (U"Number of sigmas", U"1.0") NATURAL (U"Font size", U"12") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (Table); long xcolumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Horizontal column")); long ycolumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Vertical column")); long factorcolumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Factor column")); Table_drawEllipsesWhere (me, GRAPHICS, xcolumn, ycolumn, factorcolumn, GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_REAL (U"Number of sigmas"), GET_INTEGER (U"Font size"), GET_INTEGER (U"Garnish"), U"1", interpreter); } END FORM (Table_drawEllipsesWhere, U"Table: Draw ellipses where", 0) WORD (U"Horizontal column", U"F2") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0 (= auto)") WORD (U"Vertical column", U"F1") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0 (= auto)") WORD (U"Factor column", U"Vowel") POSITIVE (U"Number of sigmas", U"1.0") NATURAL (U"Font size", U"12") BOOLEAN (U"Garnish", 1) LABEL (U"", U"Use only data in rows where the following condition holds:") TEXTFIELD (U"Formula", U"1; self$[\"gender\"]=\"male\"") OK DO autoPraatPicture picture; LOOP { iam (Table); long xcolumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Horizontal column")); long ycolumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Vertical column")); long factorcolumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Factor column")); Table_drawEllipsesWhere (me, GRAPHICS, xcolumn, ycolumn, factorcolumn, GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_REAL (U"Number of sigmas"), GET_INTEGER (U"Font size"), GET_INTEGER (U"Garnish"), GET_STRING (U"Formula"), interpreter); } END FORM (Table_normalProbabilityPlot, U"Table: Normal probability plot", U"Table: Normal probability plot...") WORD (U"Column", U"") NATURAL (U"Number of quantiles", U"100") REAL (U"Number of sigmas", U"0.0") NATURAL (U"Label size", U"12") WORD (U"Label", U"+") BOOLEAN (U"Garnish", 1); OK DO autoPraatPicture picture; LOOP { iam (Table); long column = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Column")); Table_normalProbabilityPlot (me, GRAPHICS, column, GET_INTEGER (U"Number of quantiles"), GET_REAL (U"Number of sigmas"), GET_INTEGER (U"Label size"), GET_STRING (U"Label"), GET_INTEGER (U"Garnish")); } END FORM (Table_normalProbabilityPlotWhere, U"Table: Normal probability plot where", U"Table: Normal probability plot...") WORD (U"Column", U"") NATURAL (U"Number of quantiles", U"100") REAL (U"Number of sigmas", U"0.0") NATURAL (U"Label size", U"12") WORD (U"Label", U"+") BOOLEAN (U"Garnish", 1); LABEL (U"", U"Use only data in rows where the following condition holds:") TEXTFIELD (U"Formula", U"1; self$[\"gender\"]=\"male\"") OK DO autoPraatPicture picture; LOOP { iam (Table); long column = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Column")); autoTable thee = Table_extractRowsWhere (me, GET_STRING (U"Formula"), interpreter); Table_normalProbabilityPlot (thee.peek(), GRAPHICS, column, GET_INTEGER (U"Number of quantiles"), GET_REAL (U"Number of sigmas"), GET_INTEGER (U"Label size"), GET_STRING (U"Label"), GET_INTEGER (U"Garnish")); } END FORM (Table_quantileQuantilePlot, U"Table: Quantile-quantile plot", U"Table: Quantile-quantile plot...") WORD (U"Horizontal axis column", U"") WORD (U"Vertical axis column", U"") NATURAL (U"Number of quantiles", U"100") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") NATURAL (U"Label size", U"12") WORD (U"Label", U"+") BOOLEAN (U"Garnish", 1); OK DO autoPraatPicture picture; LOOP { iam (Table); long xcolumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Horizontal axis column")); long ycolumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Vertical axis column")); Table_quantileQuantilePlot (me, GRAPHICS, xcolumn, ycolumn, GET_INTEGER (U"Number of quantiles"), GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Label size"), GET_STRING (U"Label"), GET_INTEGER (U"Garnish")); } END FORM (Table_quantileQuantilePlot_betweenLevels, U"Table: Quantile-quantile plot (between levels)", U"Table: Quantile-quantile plot...") WORD (U"Data column", U"") WORD (U"Factor column", U"") WORD (U"Horizontal factor level", U"") WORD (U"Vertical factor level", U"") NATURAL (U"Number of quantiles", U"100") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") NATURAL (U"Label size", U"12") WORD (U"Label", U"+") BOOLEAN (U"Garnish", 1); OK DO autoPraatPicture picture; LOOP { iam (Table); long dataColumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Data column")); long factorColumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Factor column")); char32 *xLevel = GET_STRING (U"Horizontal factor level"); char32 *yLevel = GET_STRING (U"Vertical factor level"); Table_quantileQuantilePlot_betweenLevels (me, GRAPHICS, dataColumn, factorColumn, xLevel, yLevel, GET_INTEGER (U"Number of quantiles"), GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Label size"), GET_STRING (U"Label"), GET_INTEGER (U"Garnish")); } END FORM (Table_lagPlot, U"Table: lag plot",0) WORD (U"Data column", U"errors") NATURAL (U"Lag", U"1") REAL (U"left Horizontal and vertical range", U"0.0") REAL (U"right Horizontal and vertical range", U"0.0") NATURAL (U"Label size", U"12") WORD (U"Label", U"+") BOOLEAN (U"Garnish", 1); OK DO autoPraatPicture picture; LOOP { iam (Table); long dataColumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Data column")); Table_lagPlotWhere (me, GRAPHICS, dataColumn, GET_INTEGER (U"Lag"), GET_REAL (U"left Horizontal and vertical range"), GET_REAL (U"right Horizontal and vertical range"), GET_STRING (U"Label"), GET_INTEGER (U"Label size"), GET_INTEGER (U"Garnish"), U"1", interpreter); } END FORM (Table_lagPlotWhere, U"Table: lag plot where",0) WORD (U"Data column", U"errors") NATURAL (U"Lag", U"1") REAL (U"left Horizontal and vertical range", U"0.0") REAL (U"right Horizontal and vertical range", U"0.0") NATURAL (U"Label size", U"12") WORD (U"Label", U"+") BOOLEAN (U"Garnish", 1); LABEL (U"", U"Use only data in rows where the following condition holds:") TEXTFIELD (U"Formula", U"1; self$[\"gender\"]=\"male\"") OK DO autoPraatPicture picture; LOOP { iam (Table); long dataColumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Data column")); Table_lagPlotWhere (me, GRAPHICS, dataColumn, GET_INTEGER (U"Lag"), GET_REAL (U"left Horizontal and vertical range"), GET_REAL (U"right Horizontal and vertical range"), GET_STRING (U"Label"), GET_INTEGER (U"Label size"), GET_INTEGER (U"Garnish"), GET_STRING (U"Formula"), interpreter); } END FORM (Table_distributionPlot, U"Table: Distribution plot", 0) WORD (U"Data column", U"data") REAL (U"Minimum value", U"0.0") REAL (U"Maximum value", U"0.0") LABEL (U"", U"Display of the distribution") NATURAL (U"Number of bins", U"10") REAL (U"Minimum frequency", U"0.0") REAL (U"Maximum frequency", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (Table); long dataColumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Data column")); Table_distributionPlotWhere (me, GRAPHICS, dataColumn, GET_REAL (U"Minimum value"), GET_REAL (U"Maximum value"), GET_INTEGER (U"Number of bins"), GET_REAL (U"Minimum frequency"), GET_REAL (U"Maximum frequency"), GET_INTEGER (U"Garnish"), U"1", interpreter); } END FORM (Table_distributionPlotWhere, U"Table: Distribution plot where", 0) WORD (U"Data column", U"data") REAL (U"Minimum value", U"0.0") REAL (U"Maximum value", U"0.0") LABEL (U"", U"Display of the distribution") NATURAL (U"Number of bins", U"10") REAL (U"Minimum frequency", U"0.0") REAL (U"Maximum frequency", U"0.0") BOOLEAN (U"Garnish", 1) LABEL (U"", U"Use only data in rows where the following condition holds:") TEXTFIELD (U"Formula", U"1; self$[\"gender\"]=\"male\"") OK DO autoPraatPicture picture; LOOP { iam (Table); long dataColumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Data column")); Table_distributionPlotWhere (me, GRAPHICS, dataColumn, GET_REAL (U"Minimum value"), GET_REAL (U"Maximum value"), GET_INTEGER (U"Number of bins"), GET_REAL (U"Minimum frequency"), GET_REAL (U"Maximum frequency"), GET_INTEGER (U"Garnish"), GET_STRING (U"Formula"), interpreter); } END FORM (Table_horizontalErrorBarsPlot, U"Table: Horizontal error bars plot", U"Table: Horizontal error bars plot...") WORD (U"Horizontal column", U"x") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") WORD (U"Vertical column", U"y") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") WORD (U"Lower error value column", U"") WORD (U"Upper error value column", U"") REAL (U"Bar size (mm)", U"1.0") BOOLEAN (U"Garnish", 1); OK DO autoPraatPicture picture; LOOP { iam (Table); long xcolumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Horizontal column")); long ycolumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Vertical column")); long xl = Table_findColumnIndexFromColumnLabel (me, GET_STRING (U"Lower error value column")); long xu = Table_findColumnIndexFromColumnLabel (me, GET_STRING (U"Upper error value column")); Table_horizontalErrorBarsPlotWhere (me, GRAPHICS, xcolumn, ycolumn, GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), xl, xu, GET_REAL (U"Bar size"), GET_INTEGER (U"Garnish"), U"1", interpreter); } END FORM (Table_horizontalErrorBarsPlotWhere, U"Table: Horizontal error bars plot where", U"Table: Horizontal error bars plot where...") WORD (U"Horizontal column", U"") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") WORD (U"Vertical column", U"") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") WORD (U"Lower error value column", U"") WORD (U"Upper error value column", U"") REAL (U"Bar size (mm)", U"1.0") BOOLEAN (U"Garnish", 1); LABEL (U"", U"Use only data in rows where the following condition holds:") TEXTFIELD (U"Formula", U"1; self$[\"gender\"]=\"male\"") OK DO autoPraatPicture picture; LOOP { iam (Table); long xcolumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Horizontal column")); long ycolumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Vertical column")); long xl = Table_findColumnIndexFromColumnLabel (me, GET_STRING (U"Lower error value column")); long xu = Table_findColumnIndexFromColumnLabel (me, GET_STRING (U"Upper error value column")); Table_horizontalErrorBarsPlotWhere (me, GRAPHICS, xcolumn, ycolumn, GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), xl, xu, GET_REAL (U"Bar size"), GET_INTEGER (U"Garnish"), GET_STRING (U"Formula"), interpreter); } END FORM (Table_verticalErrorBarsPlot, U"Table: Vertical error bars plot", U"Table: Vertical error bars plot...") WORD (U"Horizontal column", U"") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") WORD (U"Vertical column", U"") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") WORD (U"Lower error value column", U"") WORD (U"Upper error value column", U"") REAL (U"Bar size (mm)", U"1.0") BOOLEAN (U"Garnish", 1); OK DO autoPraatPicture picture; LOOP { iam (Table); long xcolumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Horizontal column")); long ycolumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Vertical column")); long yl = Table_findColumnIndexFromColumnLabel (me, GET_STRING (U"Lower error value column")); long yu = Table_findColumnIndexFromColumnLabel (me, GET_STRING (U"Upper error value column")); Table_verticalErrorBarsPlotWhere (me, GRAPHICS, xcolumn, ycolumn, GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), yl, yu, GET_REAL (U"Bar size"), GET_INTEGER (U"Garnish"), U"1", interpreter); } END FORM (Table_verticalErrorBarsPlotWhere, U"Table: Vertical error bars plot where", U"Table: Vertical error bars plot where...") WORD (U"Horizontal column", U"") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") WORD (U"Vertical column", U"") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") WORD (U"Lower error value column", U"") WORD (U"Upper error value column", U"") REAL (U"Bar size (mm)", U"1.0") BOOLEAN (U"Garnish", 1); LABEL (U"", U"Use only data in rows where the following condition holds:") TEXTFIELD (U"Formula", U"1; self$[\"gender\"]=\"male\"") OK DO autoPraatPicture picture; LOOP { iam (Table); long xcolumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Horizontal column")); long ycolumn = Table_getColumnIndexFromColumnLabel (me, GET_STRING (U"Vertical column")); long yl = Table_findColumnIndexFromColumnLabel (me, GET_STRING (U"Lower error value column")); long yu = Table_findColumnIndexFromColumnLabel (me, GET_STRING (U"Upper error value column")); Table_verticalErrorBarsPlotWhere (me, GRAPHICS, xcolumn, ycolumn, GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), yl, yu, GET_REAL (U"Bar size"), GET_INTEGER (U"Garnish"), GET_STRING (U"Formula"), interpreter); } END FORM (Table_extractRowsWhere, U"Table: Extract rows where", 0) LABEL (U"", U"Extract rows where the following condition holds:") TEXTFIELD (U"Formula", U"1; self$[\"gender\"]=\"male\"") OK DO LOOP { iam (Table); autoTable thee = Table_extractRowsWhere (me, GET_STRING (U"Formula"), interpreter); praat_new (thee.transfer(), my name, U"_formula"); } END FORM (Table_extractRowsMahalanobisWhere, U"Table: Extract rows where (mahalanobis)", 0) SENTENCE (U"Extract all rows where columns...", U"") RADIO_ENUM (U"...have a mahalanobis distance...", kMelder_number, GREATER_THAN) REAL (U"...the number", U"2.0") WORD (U"Factor column", U"") LABEL (U"", U"Process only rows where the following condition holds:") TEXTFIELD (U"Formula", U"1; self$[\"gender\"]=\"male\"") OK DO double numberOfSigmas = GET_REAL (U"...the number"); LOOP { iam (Table); autoTable thee = Table_extractMahalanobisWhere(me, GET_STRING (U"Extract all rows where columns..."), GET_STRING (U"Factor column"), numberOfSigmas, GET_ENUM (kMelder_number, U"...have a mahalanobis distance..."), GET_STRING (U"Formula"), interpreter); praat_new (thee.transfer(), my name, U"_mahalanobis"); } END FORM (Table_extractColumnRanges, U"Table: Extract column ranges", 0) LABEL (U"", U"Create a new Table from the following columns:") TEXTFIELD (U"Ranges", U"1 2") LABEL (U"", U"To supply rising or falling ranges, use e.g. 2:6 or 5:3.") OK DO LOOP { iam (Table); autoTable thee = Table_extractColumnRanges (me, GET_STRING (U"Ranges")); praat_new (thee.transfer(), my name, U"_columns"); } END /******************* TableOfReal ****************************/ DIRECT (New_CreateIrisDataset) praat_new (TableOfReal_createIrisDataset (), U""); END FORM (TableOfReal_reportMultivariateNormality, U"TableOfReal: Report multivariate normality (BHEP)", U"TableOfReal: Report multivariate normality (BHEP)...") REAL (U"Smoothing parameter", U"0.0") OK DO double h = GET_REAL (U"Smoothing parameter"); MelderInfo_open (); LOOP { iam (TableOfReal); double tnb, lnmu, lnvar; double prob = TableOfReal_normalityTest_BHEP (me, &h, &tnb, &lnmu, &lnvar); MelderInfo_open (); MelderInfo_writeLine (U"Baringhaus–Henze–Epps–Pulley normality test:"); MelderInfo_writeLine (U"Significance of normality: ", prob); MelderInfo_writeLine (U"BHEP statistic: ", tnb); MelderInfo_writeLine (U"Lognormal mean: ", lnmu); MelderInfo_writeLine (U"Lognormal variance: ", lnvar); MelderInfo_writeLine (U"Smoothing: ", h); MelderInfo_writeLine (U"Sample size: ", my numberOfRows); MelderInfo_writeLine (U"Number of variables: ", my numberOfColumns); } MelderInfo_close (); END DIRECT (TableOfReal_and_Permutation_permuteRows) TableOfReal me = FIRST (TableOfReal); Permutation p = FIRST (Permutation); praat_new (TableOfReal_and_Permutation_permuteRows (me, p), my name, U"_", p->name); END DIRECT (TableOfReal_to_Permutation_sortRowlabels) LOOP { iam (TableOfReal); praat_new (TableOfReal_to_Permutation_sortRowLabels (me), my name); } END DIRECT (TableOfReal_appendColumns) autoCollection set = praat_getSelectedObjects (); praat_new (TableOfReal_appendColumnsMany (set.peek()), U"columns_appended"); END FORM (TableOfReal_createFromPolsData_50males, U"Create TableOfReal (Pols 1973)", U"Create TableOfReal (Pols 1973)...") BOOLEAN (U"Include formant levels", 0) OK DO praat_new (TableOfReal_createFromPolsData_50males (GET_INTEGER (U"Include formant levels")), U"pols_50males"); END DIRECT (Table_createFromEspositoData) praat_new (Table_createFromEspositoData (), U"h1_h2"); END DIRECT (Table_createFromGanongData) praat_new (Table_createFromGanongData (), U"ganong"); END FORM (TableOfReal_createFromVanNieropData_25females, U"Create TableOfReal (Van Nierop 1973)...", U"Create TableOfReal (Van Nierop 1973)...") BOOLEAN (U"Include formant levels", 0) OK DO praat_new (TableOfReal_createFromVanNieropData_25females (GET_INTEGER (U"Include formant levels")), U"vannierop_25females"); END FORM (TableOfReal_createFromWeeninkData, U"Create TableOfReal (Weenink 1985)...", U"Create TableOfReal (Weenink 1985)...") RADIO (U"Speakers group", 1) RADIOBUTTON (U"Men") RADIOBUTTON (U"Women") RADIOBUTTON (U"Children") OK DO int type = GET_INTEGER (U"Speakers group"); praat_new (TableOfReal_createFromWeeninkData (type), (type == 1 ? U"m10" : type == 2 ? U"w10" : U"c10")); END FORM (TableOfReal_drawScatterPlot, U"TableOfReal: Draw scatter plot", U"TableOfReal: Draw scatter plot...") LABEL (U"", U"Select the part of the table") NATURAL (U"Horizontal axis column number", U"1") NATURAL (U"Vertical axis column number", U"2") INTEGER (U"left Row number range", U"0") INTEGER (U"right Row number range", U"0") LABEL (U"", U"Select the drawing area limits") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") NATURAL (U"Label size", U"12") BOOLEAN (U"Use row labels", 0) WORD (U"Label", U"+") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (TableOfReal); TableOfReal_drawScatterPlot (me, GRAPHICS, GET_INTEGER (U"Horizontal axis column number"), GET_INTEGER (U"Vertical axis column number"), GET_INTEGER (U"left Row number range"), GET_INTEGER (U"right Row number range"), GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Label size"), GET_INTEGER (U"Use row labels"), GET_STRING (U"Label"), GET_INTEGER (U"Garnish")); } END FORM (TableOfReal_drawScatterPlotMatrix, U"TableOfReal: Draw scatter plots matrix", 0) INTEGER (U"From column", U"0") INTEGER (U"To column", U"0") POSITIVE (U"Fraction white", U"0.1") OK DO autoPraatPicture picture; LOOP { iam (TableOfReal); TableOfReal_drawScatterPlotMatrix (me, GRAPHICS, GET_INTEGER (U"From column"), GET_INTEGER (U"To column"), GET_REAL (U"Fraction white")); } END FORM (TableOfReal_drawBiplot, U"TableOfReal: Draw biplot", U"TableOfReal: Draw biplot...") LABEL (U"", U"") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") REAL (U"Split factor", U"0.5") INTEGER (U"Label size", U"10") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (TableOfReal); TableOfReal_drawBiplot (me, GRAPHICS, GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_REAL (U"Split factor"), GET_INTEGER (U"Label size"), GET_INTEGER (U"Garnish")); } END FORM (TableOfReal_drawVectors, U"Draw vectors", U"TableOfReal: Draw vectors...") LABEL (U"", U"From (x1, y1) to (x2, y2)") NATURAL (U"left From columns (x1, y1)", U"1") NATURAL (U"right From columns (x1, y1)", U"2") NATURAL (U"left To columns (x2, y2)", U"3") NATURAL (U"right To columns (x2, y2)", U"4") LABEL (U"", U"Select the drawing area") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") RADIO (U"Vector type", 1) RADIOBUTTON (U"Arrow") RADIOBUTTON (U"Double arrow") RADIOBUTTON (U"Line") INTEGER (U"Label size", U"10") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (TableOfReal); TableOfReal_drawVectors (me, GRAPHICS, GET_INTEGER (U"left From columns"), GET_INTEGER (U"right From columns"), GET_INTEGER (U"left To columns"), GET_INTEGER (U"right To columns"), GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Vector type"), GET_INTEGER (U"Label size"), GET_INTEGER (U"Garnish")); } END FORM (TableOfReal_drawRowAsHistogram, U"Draw row as histogram", U"TableOfReal: Draw rows as histogram...") LABEL (U"", U"Select from the table") WORD (U"Row number", U"1") INTEGER (U"left Column range", U"0") INTEGER (U"right Column range", U"0") LABEL (U"", U"Vertical drawing range") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") LABEL (U"", U"Offset and distance in units of 'bar width'") REAL (U"Horizontal offset", U"0.5") REAL (U"Distance between bars", U"1.0") WORD (U"Grey value (1=white)", U"0.7") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (TableOfReal); TableOfReal_drawRowsAsHistogram (me, GRAPHICS, GET_STRING (U"Row number"), GET_INTEGER (U"left Column range"), GET_INTEGER (U"right Column range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_REAL (U"Horizontal offset"), 0, GET_REAL (U"Distance between bars"), GET_STRING (U"Grey value"), GET_INTEGER (U"Garnish")); } END FORM (TableOfReal_drawRowsAsHistogram, U"Draw rows as histogram", U"TableOfReal: Draw rows as histogram...") LABEL (U"", U"Select from the table") SENTENCE (U"Row numbers", U"1 2") INTEGER (U"left Column range", U"0") INTEGER (U"right Column range", U"0") LABEL (U"", U"Vertical drawing range") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") LABEL (U"", U"Offset and distance in units of 'bar width'") REAL (U"Horizontal offset", U"1.0") REAL (U"Distance between bar groups", U"1.0") REAL (U"Distance between bars", U"0.0") SENTENCE (U"Grey values (1=white)", U"1 1") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (TableOfReal); TableOfReal_drawRowsAsHistogram (me, GRAPHICS, GET_STRING (U"Row numbers"), GET_INTEGER (U"left Column range"), GET_INTEGER (U"right Column range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_REAL (U"Horizontal offset"), GET_REAL (U"Distance between bars"), GET_REAL (U"Distance between bar groups"), GET_STRING (U"Grey values"), GET_INTEGER (U"Garnish")); } END FORM (TableOfReal_drawBoxPlots, U"TableOfReal: Draw box plots", U"TableOfReal: Draw box plots...") INTEGER (U"From row", U"0") INTEGER (U"To row", U"0") INTEGER (U"From column", U"0") INTEGER (U"To column", U"0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (TableOfReal); TableOfReal_drawBoxPlots (me, GRAPHICS, GET_INTEGER (U"From row"), GET_INTEGER (U"To row"), GET_INTEGER (U"From column"), GET_INTEGER (U"To column"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Garnish")); } END FORM (TableOfReal_drawColumnAsDistribution, U"TableOfReal: Draw column as distribution", U"TableOfReal: Draw column as distribution...") NATURAL (U"Column number", U"1") REAL (U"left Value range", U"0.0") REAL (U"right Value range", U"0.0") REAL (U"left Frequency range", U"0.0") REAL (U"right frequency range", U"0.0") NATURAL (U"Number of bins", U"10") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (TableOfReal); TableOfReal_drawColumnAsDistribution (me, GRAPHICS, GET_INTEGER (U"Column number"), GET_REAL (U"left Value range"), GET_REAL (U"right Value range"), GET_INTEGER (U"Number of bins"), GET_REAL (U"left Frequency range"), GET_REAL (U"right frequency range"), 0, GET_INTEGER (U"Garnish")); } END FORM (TableOfReal_to_Configuration_lda, U"TableOfReal: To Configuration (lda)", U"TableOfReal: To Configuration (lda)...") INTEGER (U"Number of dimensions", U"0 (= all)") OK DO long dimension = GET_INTEGER (U"Number of dimensions"); if (dimension < 0) { Melder_throw (U"Number of dimensions must be greater equal zero."); } LOOP { iam (TableOfReal); autoConfiguration thee = TableOfReal_to_Configuration_lda (me, dimension); praat_new (thee.transfer(), my name, U"_lda"); } END FORM (TableOfReal_to_CCA, U"TableOfReal: To CCA", U"TableOfReal: To CCA...") NATURAL (U"Dimension of dependent variate", U"2") OK DO LOOP { iam (TableOfReal); autoCCA thee = TableOfReal_to_CCA (me, GET_INTEGER (U"Dimension of dependent variate")); praat_new (thee.transfer(), my name); } END FORM (TableOfReal_to_Configuration_pca, U"TableOfReal: To Configuration (pca)", U"TableOfReal: To Configuration (pca)...") NATURAL (U"Number of dimensions", U"2") OK DO LOOP { iam (TableOfReal); autoConfiguration thee = TableOfReal_to_Configuration_pca (me, GET_INTEGER (U"Number of dimensions")); praat_new (thee.transfer(), my name, U"_pca"); } END DIRECT (TableOfReal_to_Discriminant) LOOP { iam (TableOfReal); autoDiscriminant thee = TableOfReal_to_Discriminant (me); praat_new (thee.transfer(), my name); } END DIRECT (TableOfReal_to_PCA) LOOP { iam (TableOfReal); autoPCA thee = TableOfReal_to_PCA (me); praat_new (thee.transfer(), my name); } END FORM (TableOfReal_to_SSCP, U"TableOfReal: To SSCP", U"TableOfReal: To SSCP...") INTEGER (U"Begin row", U"0") INTEGER (U"End row", U"0") INTEGER (U"Begin column", U"0") INTEGER (U"End column", U"0") OK DO LOOP { iam (TableOfReal); praat_new (TableOfReal_to_SSCP (me, GET_INTEGER (U"Begin row"), GET_INTEGER (U"End row"), GET_INTEGER (U"Begin column"), GET_INTEGER (U"End column")), my name); } END /* For the inheritors */ DIRECT (TableOfReal_to_TableOfReal) LOOP { iam (TableOfReal); praat_new (TableOfReal_to_TableOfReal (me), my name); } END DIRECT (TableOfReal_to_Correlation) LOOP { iam (TableOfReal); praat_new (TableOfReal_to_Correlation (me), my name); } END DIRECT (TableOfReal_to_Correlation_rank) LOOP { iam (TableOfReal); praat_new (TableOfReal_to_Correlation_rank (me), my name); } END DIRECT (TableOfReal_to_Covariance) LOOP { iam (TableOfReal); praat_new (TableOfReal_to_Covariance (me), my name); } END DIRECT (TableOfReal_to_SVD) LOOP { iam (TableOfReal); praat_new (TableOfReal_to_SVD (me), my name); } END DIRECT (TablesOfReal_to_Eigen_gsvd) TableOfReal t1 = 0, t2 = 0; LOOP { iam (TableOfReal); (t1 ? t2 : t1) = me; } Melder_assert (t1 && t2); autoEigen thee = TablesOfReal_to_Eigen_gsvd (t1, t2); praat_new (thee.transfer(), U""); END FORM (TableOfReal_and_TableOfReal_crossCorrelations, U"TableOfReal & TableOfReal: Cross-correlations", 0) OPTIONMENU (U"Correlations between", 1) OPTION (U"Rows") OPTION (U"Columns") BOOLEAN (U"Center", 0) BOOLEAN (U"Normalize", 0) OK DO int by_columns = GET_INTEGER (U"Correlations between") - 1; TableOfReal t1 = 0, t2 = 0; LOOP { iam (TableOfReal); (t1 ? t2 : t1) = me; } Melder_assert (t1 && t2); praat_new (TableOfReal_and_TableOfReal_crossCorrelations (t1, t2, by_columns, GET_INTEGER (U"Center"), GET_INTEGER (U"Normalize")), (by_columns ? U"by_columns" : U"by_rows"), U"cc"); END DIRECT (TablesOfReal_to_GSVD) TableOfReal t1 = 0, t2 = 0; LOOP { iam (TableOfReal); (t1 ? t2 : t1) = me; } Melder_assert (t1 && t2); praat_new (TablesOfReal_to_GSVD (t1, t2), U""); END FORM (TableOfReal_choleskyDecomposition, U"TableOfReal: Cholesky decomposition", 0) BOOLEAN (U"Upper (else L)", 0) BOOLEAN (U"Inverse", 0) OK DO LOOP { iam (TableOfReal); praat_new (TableOfReal_choleskyDecomposition (me, GET_INTEGER (U"Upper"), GET_INTEGER (U"Inverse")), my name); } END FORM (TableOfReal_to_Pattern_and_Categories, U"TableOfReal: To Pattern and Categories", U"TableOfReal: To Pattern and Categories...") INTEGER (U"left Row range", U"0") INTEGER (U"right Row range", U"0 (=all)") INTEGER (U"left Column range", U"0") INTEGER (U"right Column range", U"0 (=all)") OK DO LOOP { iam (TableOfReal); Pattern p = 0; Categories c = 0; TableOfReal_to_Pattern_and_Categories (me, GET_INTEGER (U"left Row range"), GET_INTEGER (U"right Row range"), GET_INTEGER (U"left Column range"), GET_INTEGER (U"right Column range"), &p, &c); autoPattern ap = p; autoCategories ac = c; praat_new (ap.transfer(), Thing_getName (me)); praat_new (ac.transfer(), Thing_getName (me)); } END FORM (TableOfReal_getColumnSum, U"TableOfReal: Get column sum", U"") INTEGER (U"Column", U"1") OK DO LOOP { iam (TableOfReal); Melder_information (TableOfReal_getColumnSum (me, GET_INTEGER (U"Column"))); } END FORM (TableOfReal_getRowSum, U"TableOfReal: Get row sum", U"") INTEGER (U"Row", U"1") OK DO LOOP { iam (TableOfReal); Melder_information (TableOfReal_getRowSum (me, GET_INTEGER (U"Row"))); } END DIRECT (TableOfReal_getGrandSum) LOOP { iam (TableOfReal); Melder_information (TableOfReal_getGrandSum (me)); } END FORM (TableOfReal_meansByRowLabels, U"TableOfReal: Means by row labels", U"TableOfReal: To TableOfReal (means by row labels)...") BOOLEAN (U"Expand", 0) OK DO LOOP { iam (TableOfReal); praat_new (TableOfReal_meansByRowLabels (me, GET_INTEGER (U"Expand"), 0), NAME, U"_byrowlabels"); } END FORM (TableOfReal_mediansByRowLabels, U"TableOfReal: Medians by row labels", U"TableOfReal: To TableOfReal (medians by row labels)...") BOOLEAN (U"Expand", 0) OK DO LOOP { iam (TableOfReal); praat_new (TableOfReal_meansByRowLabels (me, GET_INTEGER (U"Expand"), 1), Thing_getName (me), U"_byrowlabels"); } END /***** TableOfReal and FilterBank *****/ FORM (TextGrid_extendTime, U"TextGrid: Extend time", U"TextGrid: Extend time...") LABEL (U"", U"") POSITIVE (U"Extend domain by (s)", U"1.0") RADIO (U"At", 1) RADIOBUTTON (U"End") RADIOBUTTON (U"Start") OK DO LOOP { iam (TextGrid); TextGrid_extendTime (me, GET_REAL (U"Extend domain by"), GET_INTEGER (U"At") - 1); praat_dataChanged (me); } END FORM (TextGrid_replaceIntervalTexts, U"TextGrid: Replace interval text", U"TextGrid: Replace interval text...") LABEL (U"", U"") NATURAL (U"Tier number", U"1") INTEGER (U"left Interval range", U"0") INTEGER (U"right Interval range", U"0") SENTENCE (U"Search", U"a") SENTENCE (U"Replace", U"a") RADIO (U"Search and replace strings are:", 1) RADIOBUTTON (U"Literals") RADIOBUTTON (U"Regular Expressions") OK DO long from = GET_INTEGER (U"left Interval range"); long to = GET_INTEGER (U"right Interval range"); int isregexp = GET_INTEGER (U"Search and replace strings are") - 1; char32 *search = GET_STRING (U"Search"); LOOP { iam (TextGrid); long nmatches, nstringmatches; TextGrid_changeLabels (me, GET_INTEGER (U"Tier number"), from, to, search, GET_STRING (U"Replace"), isregexp, &nmatches, &nstringmatches); praat_dataChanged (me); } END FORM (TextGrid_replacePointTexts, U"TextGrid: Replace point text", U"TextGrid: Replace point text...") LABEL (U"", U"") NATURAL (U"Tier number", U"1") INTEGER (U"left Interval range", U"0") INTEGER (U"right Interval range", U"0") SENTENCE (U"Search", U"a") SENTENCE (U"Replace", U"a") RADIO (U"Search and replace strings are:", 1) RADIOBUTTON (U"Literals") RADIOBUTTON (U"Regular Expressions") OK DO long from = GET_INTEGER (U"left Interval range"); long to = GET_INTEGER (U"right Interval range"); LOOP { iam (TextGrid); long nmatches, nstringmatches; TextGrid_changeLabels (me, GET_INTEGER (U"Tier number"), from, to, GET_STRING (U"Search"), GET_STRING (U"Replace"), GET_INTEGER (U"Search and replace strings are") - 1, &nmatches, &nstringmatches); praat_dataChanged (me); } END FORM (TextGrids_to_Table_textAlignmentment, U"TextGrids: To Table (text alignment)", 0) NATURAL (U"Target tier", U"1") NATURAL (U"Source tier", U"1") OK DO TextGrid tg1 = 0, tg2 = 0; LOOP { iam (TextGrid); (tg1 ? tg2 : tg1) = me; } Melder_assert (tg1 && tg2); praat_new (TextGrids_to_Table_textAlignmentment (tg1, GET_INTEGER (U"Target tier"), tg2, GET_INTEGER (U"Source tier"), 0), tg1 -> name, U"_", tg2 -> name); END FORM (TextGrids_and_EditCostsTable_to_Table_textAlignmentment, U"TextGrids & EditCostsTable: To Table(text alignmentment)", 0) NATURAL (U"Target tier", U"1") NATURAL (U"Source tier", U"1") OK DO TextGrid tg1 = 0, tg2 = 0; EditCostsTable ect = 0; LOOP { if (CLASS == classTextGrid) { (tg1 ? tg2 : tg1) = (TextGrid) OBJECT; } else { ect = (EditCostsTable) OBJECT; } } Melder_assert (tg1 && tg2 && ect); praat_new (TextGrids_to_Table_textAlignmentment (tg1, GET_INTEGER (U"Target tier"), tg2, GET_INTEGER (U"Source tier"), ect), tg1 -> name, U"_", tg2 -> name); END FORM (TextGrid_setTierName, U"TextGrid: Set tier name", U"TextGrid: Set tier name...") NATURAL (U"Tier number:", U"1") SENTENCE (U"Name", U""); OK DO LOOP { iam (TextGrid); TextGrid_setTierName (me, GET_INTEGER (U"Tier number"), GET_STRING (U"Name")); praat_dataChanged (me); } END DIRECT (VowelEditor_create) if (theCurrentPraatApplication -> batch) { Melder_throw (U"Cannot edit from batch."); } autoVowelEditor vowelEditor = VowelEditor_create (U"VowelEditor", nullptr); vowelEditor.transfer(); // user becomes the owner END static Any cmuAudioFileRecognizer (int nread, const char *header, MelderFile fs) { return nread < 12 || header [0] != 6 || header [1] != 0 ? nullptr : Sound_readFromCmuAudioFile (fs); } void praat_CC_init (ClassInfo klas) { praat_addAction1 (klas, 1, U"Paint...", 0, 1, DO_CC_paint); praat_addAction1 (klas, 1, U"Draw...", 0, 1, DO_CC_drawC0); praat_addAction1 (klas, 1, QUERY_BUTTON, 0, 0, 0); praat_TimeFrameSampled_query_init (klas); praat_addAction1 (klas, 1, U"Get number of coefficients...", 0, 1, DO_CC_getNumberOfCoefficients); praat_addAction1 (klas, 1, U"Get value in frame...", 0, 1, DO_CC_getValueInFrame); praat_addAction1 (klas, 1, U"Get c0 value in frame...", 0, 1, DO_CC_getC0ValueInFrame); praat_addAction1 (klas, 1, U"Get value...", 0, praat_HIDDEN + praat_DEPTH_1, DO_CC_getValue); praat_addAction1 (klas, 0, U"To Matrix", 0, 0, DO_CC_to_Matrix); praat_addAction1 (klas, 2, U"To DTW...", 0, 0, DO_CCs_to_DTW); } static void praat_Eigen_Matrix_project (ClassInfo klase, ClassInfo klasm); // deprecated 2014 static void praat_Eigen_Matrix_project (ClassInfo klase, ClassInfo klasm) { praat_addAction2 (klase, 1, klasm, 1, U"Project...", 0, praat_HIDDEN, DO_Eigen_and_Matrix_project); } static void praat_Eigen_Spectrogram_project (ClassInfo klase, ClassInfo klasm); static void praat_Eigen_Spectrogram_project (ClassInfo klase, ClassInfo klasm) { praat_addAction2 (klase, 1, klasm, 1, U"Project...", 0, 0, DO_Eigen_and_Matrix_project); } static void praat_Eigen_query_init (ClassInfo klas) { praat_addAction1 (klas, 1, U"Get eigenvalue...", 0, 1, DO_Eigen_getEigenvalue); praat_addAction1 (klas, 1, U"Get sum of eigenvalues...", 0, 1, DO_Eigen_getSumOfEigenvalues); praat_addAction1 (klas, 1, U"Get number of eigenvectors", 0, 1, DO_Eigen_getNumberOfEigenvalues); praat_addAction1 (klas, 1, U"Get eigenvector dimension", 0, 1, DO_Eigen_getDimension); praat_addAction1 (klas, 1, U"Get eigenvector element...", 0, 1, DO_Eigen_getEigenvectorElement); } static void praat_Eigen_draw_init (ClassInfo klas) { praat_addAction1 (klas, 0, U"Draw eigenvalues...", 0, 1, DO_Eigen_drawEigenvalues); praat_addAction1 (klas, 0, U"Draw eigenvalues (scree)...", 0, praat_DEPTH_1 | praat_HIDDEN, DO_Eigen_drawEigenvalues_scree); praat_addAction1 (klas, 0, U"Draw eigenvector...", 0, 1, DO_Eigen_drawEigenvector); } static void praat_Index_init (ClassInfo klas) { praat_addAction1 (klas, 1, U"Get number of classes", 0, 0, DO_Index_getNumberOfClasses); praat_addAction1 (klas, 1, U"To Permutation...", 0, 0, DO_Index_to_Permutation); praat_addAction1 (klas, 1, U"Extract part...", 0, 0, DO_Index_extractPart); } static void praat_BandFilterSpectrogram_draw_init (ClassInfo klas); static void praat_BandFilterSpectrogram_draw_init (ClassInfo klas) { praat_addAction1 (klas, 0, DRAW_BUTTON, 0, 0, 0); // praat_addAction1 (klas, 0, U"Paint image...", 0, praat_DEPTH_1, DO_BandFilterSpectrogram_paintImage); // praat_addAction1 (klas, 0, U"Draw filters...", 0, 1, DO_FilterBank_drawFilters); // praat_addAction1 (klas, 0, U"Draw one contour...", 0, 1, DO_FilterBank_drawOneContour); // praat_addAction1 (klas, 0, U"Draw contours...", 0, 1, DO_FilterBank_drawContours); // praat_addAction1 (klas, 0, U"Paint contours...", 0, 1, DO_FilterBank_paintContours); // praat_addAction1 (klas, 0, U"Paint cells...", 0, 1, DO_FilterBank_paintCells); // praat_addAction1 (klas, 0, U"Paint surface...", 0, 1, DO_FilterBank_paintSurface); praat_addAction1 (klas, 0, U"-- frequency scales --", 0, 1, 0); praat_addAction1 (klas, 0, U"Draw frequency scale...", 0, 1, DO_BandFilterSpectrogram_drawFrequencyScale); } void praat_Matrixft_query_init (ClassInfo klas); void praat_Matrixft_query_init (ClassInfo klas) { praat_TimeFrameSampled_query_init (klas); praat_addAction1 (klas, 1, U"Get time from column...", 0, praat_DEPTH_1, DO_BandFilterSpectrogram_getXofColumn); praat_addAction1 (klas, 1, U"-- frequencies --", 0, praat_DEPTH_1, 0); praat_addAction1 (klas, 1, U"Get lowest frequency", 0, praat_DEPTH_1, DO_BandFilterSpectrogram_getLowestFrequency); praat_addAction1 (klas, 1, U"Get highest frequency", 0, praat_DEPTH_1, DO_BandFilterSpectrogram_getHighestFrequency); praat_addAction1 (klas, 1, U"Get number of frequencies", 0, praat_DEPTH_1, DO_BandFilterSpectrogram_getNumberOfFrequencies); praat_addAction1 (klas, 1, U"Get frequency distance", 0, praat_DEPTH_1, DO_BandFilterSpectrogram_getFrequencyDistance); praat_addAction1 (klas, 1, U"Get frequency from row...", 0, praat_DEPTH_1, DO_BandFilterSpectrogram_getFrequencyOfRow); praat_addAction1 (klas, 1, U"-- get value --", 0, praat_DEPTH_1, 0); praat_addAction1 (klas, 1, U"Get value in cell...", 0, praat_DEPTH_1, DO_BandFilterSpectrogram_getValueInCell); } void praat_Matrixtype_query_init (ClassInfo klas); void praat_Matrixtype_query_init (ClassInfo klas) { praat_TimeFrameSampled_query_init (klas); praat_addAction1 (klas, 1, U"Get time from column...", 0, praat_DEPTH_1, DO_FilterBank_getXofColumn); praat_addAction1 (klas, 1, U"-- frequencies --", 0, praat_DEPTH_1, 0); praat_addAction1 (klas, 1, U"Get lowest frequency", 0, praat_DEPTH_1, DO_FilterBank_getLowestFrequency); praat_addAction1 (klas, 1, U"Get highest frequency", 0, praat_DEPTH_1, DO_FilterBank_getHighestFrequency); praat_addAction1 (klas, 1, U"Get number of frequencies", 0, praat_DEPTH_1, DO_FilterBank_getNumberOfFrequencies); praat_addAction1 (klas, 1, U"Get frequency distance", 0, praat_DEPTH_1, DO_FilterBank_getFrequencyDistance); praat_addAction1 (klas, 1, U"Get frequency from row...", 0, praat_DEPTH_1, DO_FilterBank_getFrequencyOfRow); praat_addAction1 (klas, 1, U"-- get value --", 0, praat_DEPTH_1, 0); praat_addAction1 (klas, 1, U"Get value in cell...", 0, praat_DEPTH_1, DO_FilterBank_getValueInCell); } static void praat_FilterBank_query_init (ClassInfo klas); static void praat_FilterBank_query_init (ClassInfo klas) { praat_addAction1 (klas, 0, QUERY_BUTTON, 0, 0, 0); praat_Matrixtype_query_init (klas); praat_addAction1 (klas, 0, U"-- frequency scales --", 0, praat_DEPTH_1, 0); praat_addAction1 (klas, 1, U"Get frequency in Hertz...", 0, praat_DEPTH_1, DO_FilterBank_getFrequencyInHertz); praat_addAction1 (klas, 1, U"Get frequency in Bark...", 0, praat_DEPTH_1, DO_FilterBank_getFrequencyInBark); praat_addAction1 (klas, 1, U"Get frequency in mel...", 0, praat_DEPTH_1, DO_FilterBank_getFrequencyInMel); } static void praat_FilterBank_modify_init (ClassInfo klas); static void praat_FilterBank_modify_init (ClassInfo klas) { // praat_addAction1 (klas, 0, MODIFY_BUTTON, 0, 0, 0); praat_addAction1 (klas, 0, U"Equalize intensities...", 0, praat_DEPTH_1, DO_FilterBank_equalizeIntensities); } static void praat_FilterBank_draw_init (ClassInfo klas); static void praat_FilterBank_draw_init (ClassInfo klas) { // praat_addAction1 (klas, 0, DRAW_BUTTON, 0, 0, 0); praat_addAction1 (klas, 0, U"Draw filters...", 0, praat_DEPTH_1, DO_FilterBank_drawFilters); praat_addAction1 (klas, 0, U"Draw one contour...", 0, praat_DEPTH_1, DO_FilterBank_drawOneContour); praat_addAction1 (klas, 0, U"Draw contours...", 0, praat_DEPTH_1, DO_FilterBank_drawContours); praat_addAction1 (klas, 0, U"Paint image...", 0, praat_DEPTH_1, DO_FilterBank_paintImage); praat_addAction1 (klas, 0, U"Paint contours...", 0, praat_DEPTH_1, DO_FilterBank_paintContours); praat_addAction1 (klas, 0, U"Paint cells...", 0, praat_DEPTH_1, DO_FilterBank_paintCells); praat_addAction1 (klas, 0, U"Paint surface...", 0, praat_DEPTH_1, DO_FilterBank_paintSurface); praat_addAction1 (klas, 0, U"-- frequency scales --", 0, praat_DEPTH_1, 0); praat_addAction1 (klas, 0, U"Draw frequency scales...", 0, praat_DEPTH_1, DO_FilterBank_drawFrequencyScales); } static void praat_FilterBank_all_init (ClassInfo klas); static void praat_FilterBank_all_init (ClassInfo klas) { praat_FilterBank_draw_init (klas); praat_FilterBank_query_init (klas); praat_FilterBank_modify_init (klas); praat_addAction1 (klas, 0, U"To Intensity", 0, praat_HIDDEN, DO_FilterBank_to_Intensity); praat_addAction1 (klas, 0, U"To Matrix", 0, praat_HIDDEN, DO_FilterBank_to_Matrix); praat_addAction1 (klas, 2, U"Cross-correlate...", 0, praat_HIDDEN, DO_FilterBanks_crossCorrelate); praat_addAction1 (klas, 2, U"Convolve...", 0, praat_HIDDEN, DO_FilterBanks_convolve); } static void praat_FunctionTerms_init (ClassInfo klas) { praat_addAction1 (klas, 0, DRAW_BUTTON, 0, 0, 0); praat_addAction1 (klas, 0, U"Draw...", 0, 1, DO_FunctionTerms_draw); praat_addAction1 (klas, 0, U"Draw basis function...", 0, 1, DO_FunctionTerms_drawBasisFunction); praat_addAction1 (klas, 0, QUERY_BUTTON, 0, 0, 0); praat_addAction1 (klas, 1, U"Get number of coefficients", 0, 1, DO_FunctionTerms_getNumberOfCoefficients); praat_addAction1 (klas, 1, U"Get coefficient...", 0, 1, DO_FunctionTerms_getCoefficient); praat_addAction1 (klas, 1, U"Get degree", 0, 1, DO_FunctionTerms_getDegree); praat_addAction1 (klas, 0, U"-- function specifics --", 0, 1, 0); praat_addAction1 (klas, 1, U"Get value...", 0, 1, DO_FunctionTerms_evaluate); praat_addAction1 (klas, 1, U"Get minimum...", 0, 1, DO_FunctionTerms_getMinimum); praat_addAction1 (klas, 1, U"Get x of minimum...", 0, 1, DO_FunctionTerms_getXOfMinimum); praat_addAction1 (klas, 1, U"Get maximum...", 0, 1, DO_FunctionTerms_getMaximum); praat_addAction1 (klas, 1, U"Get x of maximum...", 0, 1, DO_FunctionTerms_getXOfMaximum); praat_addAction1 (klas, 0, U"Modify -", 0, 0, 0); praat_addAction1 (klas, 1, U"Set domain...", 0, 1, DO_FunctionTerms_setDomain); praat_addAction1 (klas, 1, U"Set coefficient...", 0, 1, DO_FunctionTerms_setCoefficient); praat_addAction1 (klas, 0, U"Analyse", 0, 0, 0); } /* Query buttons for frame-based frequency x time subclasses of matrix. */ void praat_BandFilterSpectrogram_query_init (ClassInfo klas) { praat_TimeFrameSampled_query_init (klas); praat_addAction1 (klas, 1, U"Get time from column...", 0, 1, DO_BandFilterSpectrogram_getXofColumn); praat_addAction1 (klas, 1, U"-- frequencies --", 0, 1, 0); praat_addAction1 (klas, 1, U"Get lowest frequency", 0, 1, DO_BandFilterSpectrogram_getLowestFrequency); praat_addAction1 (klas, 1, U"Get highest frequency", 0, 1, DO_BandFilterSpectrogram_getHighestFrequency); praat_addAction1 (klas, 1, U"Get number of frequencies", 0, 1, DO_BandFilterSpectrogram_getNumberOfFrequencies); praat_addAction1 (klas, 1, U"Get frequency distance", 0, 1, DO_BandFilterSpectrogram_getFrequencyDistance); praat_addAction1 (klas, 1, U"Get frequency from row...", 0, 1, DO_BandFilterSpectrogram_getFrequencyOfRow); praat_addAction1 (klas, 1, U"-- get value --", 0, 1, 0); praat_addAction1 (klas, 1, U"Get value in cell...", 0, 1, DO_BandFilterSpectrogram_getValueInCell); } static void praat_Spline_init (ClassInfo klas) { praat_FunctionTerms_init (klas); praat_addAction1 (klas, 0, U"Draw knots...", U"Draw basis function...", 1, DO_Spline_drawKnots); praat_addAction1 (klas, 1, U"Get order", U"Get degree", 1, DO_Spline_getOrder); praat_addAction1 (klas, 1, U"Scale x...", U"Analyse", 0, DO_Spline_scaleX); } static void praat_SSCP_query_init (ClassInfo klas) { praat_addAction1 (klas, 1, U"-- statistics --", U"Get value...", 1, 0); praat_addAction1 (klas, 1, U"Get number of observations", U"-- statistics --", 1, DO_SSCP_getNumberOfObservations); praat_addAction1 (klas, 1, U"Get degrees of freedom", U"Get number of observations", 1, DO_SSCP_getDegreesOfFreedom); praat_addAction1 (klas, 1, U"Get centroid element...", U"Get degrees of freedom", 1, DO_SSCP_getCentroidElement); praat_addAction1 (klas, 1, U"Get ln(determinant)", U"Get centroid element...", 1, DO_SSCP_getLnDeterminant); } static void praat_SSCP_extract_init (ClassInfo klas) { praat_addAction1 (klas, 1, U"Extract centroid", EXTRACT_BUTTON, 1, DO_SSCP_extractCentroid); } FORM (SSCP_setValue, U"Covariance: Set value", U"Covariance: Set value...") NATURAL (U"Row number", U"1") NATURAL (U"Column number", U"1") REAL (U"New value", U"1.0") OK DO LOOP { iam (SSCP); SSCP_setValue (me, GET_INTEGER (U"Row number"), GET_INTEGER (U"Column number"), GET_REAL (U"New value")); } END FORM (SSCP_setCentroid, U"", 0) NATURAL (U"Element number", U"1") REAL (U"New value", U"1.0") OK DO LOOP { iam (SSCP); SSCP_setCentroid (me, GET_INTEGER (U"Element number"), GET_REAL (U"New value")); } END void praat_SSCP_as_TableOfReal_init (ClassInfo klas) { praat_TableOfReal_init (klas); praat_removeAction (klas, nullptr, nullptr, U"Set value..."); praat_addAction1 (klas, 1, U"Set centroid...", U"Formula...", 1, DO_SSCP_setCentroid); praat_addAction1 (klas, 1, U"Set value...", U"Formula...", 1, DO_SSCP_setValue); praat_addAction1 (klas, 0, U"To TableOfReal", U"To Matrix", 1, DO_TableOfReal_to_TableOfReal); } void praat_TableOfReal_init2 (ClassInfo klas) { praat_TableOfReal_init (klas); praat_addAction1 (klas, 0, U"To TableOfReal", U"To Matrix", 1, DO_TableOfReal_to_TableOfReal); } void praat_EditDistanceTable_as_TableOfReal_init (ClassInfo klas) { praat_TableOfReal_init (klas); praat_addAction1 (klas, 0, U"Set default costs...", U"Formula...", 1, DO_EditDistanceTable_setDefaultCosts); praat_removeAction (klas, nullptr, nullptr, U"Draw as numbers..."); praat_addAction1 (klas, 0, U"Draw...", U"Draw -", 1, DO_EditDistanceTable_draw); praat_addAction1 (klas, 0, U"Draw edit operations", U"Draw...", 1, DO_EditDistanceTable_drawEditOperations); praat_removeAction (klas, nullptr, nullptr, U"Draw as numbers if..."); praat_removeAction (klas, nullptr, nullptr, U"Draw as squares..."); praat_removeAction (klas, nullptr, nullptr, U"Draw vertical lines..."); praat_removeAction (klas, nullptr, nullptr, U"Draw horizontal lines..."); praat_removeAction (klas, nullptr, nullptr, U"Draw left and right lines..."); praat_removeAction (klas, nullptr, nullptr, U"Draw top and bottom lines..."); praat_removeAction (klas, nullptr, nullptr, U"-- draw lines --"); } void praat_uvafon_David_init (); void praat_uvafon_David_init () { Data_recognizeFileType (TextGrid_TIMITLabelFileRecognizer); Data_recognizeFileType (cmuAudioFileRecognizer); Thing_recognizeClassesByName (classActivation, classBarkFilter, classBarkSpectrogram, classCategories, classCepstrum, classCCA, classChebyshevSeries, classClassificationTable, classComplexSpectrogram, classConfusion, classCorrelation, classCovariance, classDiscriminant, classDTW, classEigen, classExcitations, classEditCostsTable, classEditDistanceTable, classFileInMemory, classFilesInMemory, classFormantFilter, classIndex, classKlattTable, classPermutation, classISpline, classLegendreSeries, classMelFilter, classMelSpectrogram, classMSpline, classPattern, classPCA, classPolynomial, classRoots, classSimpleString, classStringsIndex, classSpeechSynthesizer, classSPINET, classSSCP, classSVD, nullptr); VowelEditor_prefs (); espeakdata_praat_init (); praat_addMenuCommand (U"Objects", U"Technical", U"Report floating point properties", U"Report integer properties", 0, DO_Praat_ReportFloatingPointProperties); praat_addMenuCommand (U"Objects", U"Goodies", U"Get TukeyQ...", 0, praat_HIDDEN, DO_Praat_getTukeyQ); praat_addMenuCommand (U"Objects", U"Goodies", U"Get invTukeyQ...", 0, praat_HIDDEN, DO_Praat_getInvTukeyQ); praat_addMenuCommand (U"Objects", U"New", U"Create Strings from espeak voices", U"Create Strings as directory list...", praat_DEPTH_1 + praat_HIDDEN, DO_Strings_createFromEspeakVoices); praat_addMenuCommand (U"Objects", U"New", U"Create iris data set", U"Create TableOfReal...", 1, DO_New_CreateIrisDataset); praat_addMenuCommand (U"Objects", U"New", U"Create Permutation...", 0, 0, DO_Permutation_create); praat_addMenuCommand (U"Objects", U"New", U"Polynomial", 0, 0, 0); praat_addMenuCommand (U"Objects", U"New", U"Create Polynomial...", 0, 1, DO_Polynomial_create); praat_addMenuCommand (U"Objects", U"New", U"Create LegendreSeries...", 0, 1, DO_LegendreSeries_create); praat_addMenuCommand (U"Objects", U"New", U"Create ChebyshevSeries...", 0, 1, DO_ChebyshevSeries_create); praat_addMenuCommand (U"Objects", U"New", U"Create MSpline...", 0, 1, DO_MSpline_create); praat_addMenuCommand (U"Objects", U"New", U"Create ISpline...", 0, 1, DO_ISpline_create); praat_addMenuCommand (U"Objects", U"New", U"Create Sound from gammatone...", U"Create Sound from tone complex...", 1, DO_Sound_createFromGammaTone); praat_addMenuCommand (U"Objects", U"New", U"Create Sound from gamma-tone...", U"Create Sound from tone complex...", praat_DEPTH_1 | praat_HIDDEN, DO_Sound_createFromGammaTone); praat_addMenuCommand (U"Objects", U"New", U"Create Sound from Shepard tone...", U"Create Sound from gammatone...", 1, DO_Sound_createFromShepardTone); praat_addMenuCommand (U"Objects", U"New", U"Create Sound from VowelEditor...", U"Create Sound from Shepard tone...", praat_DEPTH_1, DO_VowelEditor_create); praat_addMenuCommand (U"Objects", U"New", U"Create SpeechSynthesizer...", U"Create Sound from VowelEditor...", praat_DEPTH_1, DO_SpeechSynthesizer_create); praat_addMenuCommand (U"Objects", U"New", U"Create formant table (Pols & Van Nierop 1973)", U"Create Table...", 1, DO_Table_createFromPolsVanNieropData); praat_addMenuCommand (U"Objects", U"New", U"Create formant table (Peterson & Barney 1952)", U"Create Table...", 1, DO_Table_createFromPetersonBarneyData); praat_addMenuCommand (U"Objects", U"New", U"Create formant table (Weenink 1985)", U"Create formant table (Peterson & Barney 1952)", 1, DO_Table_createFromWeeninkData); praat_addMenuCommand (U"Objects", U"New", U"Create H1H2 table (Esposito 2006)", U"Create formant table (Weenink 1985)", praat_DEPTH_1+ praat_HIDDEN, DO_Table_createFromEspositoData); praat_addMenuCommand (U"Objects", U"New", U"Create Table (Ganong 1980)", U"Create H1H2 table (Esposito 2006)", praat_DEPTH_1+ praat_HIDDEN, DO_Table_createFromGanongData); praat_addMenuCommand (U"Objects", U"New", U"Create TableOfReal (Pols 1973)...", U"Create TableOfReal...", 1, DO_TableOfReal_createFromPolsData_50males); praat_addMenuCommand (U"Objects", U"New", U"Create TableOfReal (Van Nierop 1973)...", U"Create TableOfReal (Pols 1973)...", 1, DO_TableOfReal_createFromVanNieropData_25females); praat_addMenuCommand (U"Objects", U"New", U"Create TableOfReal (Weenink 1985)...", U"Create TableOfReal (Van Nierop 1973)...", 1, DO_TableOfReal_createFromWeeninkData); praat_addMenuCommand (U"Objects", U"New", U"Create simple Confusion...", U"Create TableOfReal (Weenink 1985)...", 1, DO_Confusion_createSimple); praat_addMenuCommand (U"Objects", U"New", U"Create simple Covariance...", U"Create simple Confusion...", 1, DO_Covariance_createSimple); praat_addMenuCommand (U"Objects", U"New", U"Create empty EditCostsTable...", U"Create simple Covariance...", 1, DO_EditCostsTable_createEmpty); praat_addMenuCommand (U"Objects", U"New", U"Create KlattTable example", U"Create TableOfReal (Weenink 1985)...", praat_DEPTH_1 + praat_HIDDEN, DO_KlattTable_createExample); praat_addMenuCommand (U"Objects", U"New", U"Create Strings as characters...", U"Create TextGrid...", praat_HIDDEN, DO_Strings_createAsCharacters); praat_addMenuCommand (U"Objects", U"New", U"Create Strings as tokens...", U"Create TextGrid...", praat_HIDDEN, DO_Strings_createAsTokens); praat_addMenuCommand (U"Objects", U"New", U"Create simple Polygon...", 0, praat_HIDDEN, DO_Polygon_createSimple); praat_addMenuCommand (U"Objects", U"New", U"Create Polygon (random vertices)...", 0, praat_HIDDEN, DO_Polygon_createFromRandomVertices); praat_addMenuCommand (U"Objects", U"New", U"FilesInMemory", 0, praat_HIDDEN, 0); praat_addMenuCommand (U"Objects", U"New", U"Create FileInMemory...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_FileInMemory_create); praat_addMenuCommand (U"Objects", U"New", U"Create copy from FilesInMemory...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_FilesInMemory_createCopyFromFilesInMemory); praat_addMenuCommand (U"Objects", U"New", U"Create FilesInMemory from directory contents...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_FilesInMemory_createFromDirectoryContents); praat_addMenuCommand (U"Objects", U"Open", U"Read Sound from raw 16-bit Little Endian file...", U"Read from special sound file", 1, DO_Sound_readFromRawFileLE); praat_addMenuCommand (U"Objects", U"Open", U"Read Sound from raw 16-bit Big Endian file...", U"Read Sound from raw 16-bit Little Endian file...", 1, DO_Sound_readFromRawFileBE); praat_addMenuCommand (U"Objects", U"Open", U"Read KlattTable from raw text file...", U"Read Matrix from raw text file...", praat_HIDDEN, DO_KlattTable_readFromRawTextFile); praat_addAction1 (classActivation, 0, U"Modify", 0, 0, 0); praat_addAction1 (classActivation, 0, U"Formula...", 0, 0, DO_Activation_formula); praat_addAction1 (classActivation, 0, U"Hack", 0, 0, 0); praat_addAction1 (classActivation, 0, U"To Matrix", 0, 0, DO_Activation_to_Matrix); praat_addAction2 (classActivation, 1, classCategories, 1, U"To TableOfReal", 0, 0, DO_Matrix_Categories_to_TableOfReal); praat_addAction1 (classBarkFilter, 0, U"BarkFilter help", 0, 0, DO_BarkFilter_help); praat_FilterBank_all_init (classBarkFilter); // deprecated 2014 praat_addAction1 (classBarkFilter, 0, U"Draw spectrum (slice)...", U"Draw filters...", praat_DEPTH_1, DO_BarkFilter_drawSpectrum); // deprecated 2014 praat_addAction1 (classBarkFilter, 1, U"Draw filter functions...", U"Draw filters...", praat_DEPTH_1, DO_BarkFilter_drawSekeyHansonFilterFunctions); // deprecated 2014 praat_addAction1 (classBarkFilter, 0, U"Paint...", U"Draw filters...", praat_DEPTH_1, DO_BarkFilter_paint); // deprecated 2014 praat_addAction1 (classBarkFilter, 0, U"To BarkSpectrogram", 0, 0, DO_BarkFilter_to_BarkSpectrogram); praat_addAction1 (classBarkSpectrogram, 0, U"BarkSpectrogram help", 0, 0, DO_BarkSpectrogram_help); praat_BandFilterSpectrogram_draw_init (classBarkSpectrogram); praat_addAction1 (classBarkSpectrogram, 0, U"Paint image...", 0, 1, DO_BarkSpectrogram_paintImage); praat_addAction1 (classBarkSpectrogram, 0, U"Draw Sekey-Hanson auditory filters...", 0, 1, DO_BarkSpectrogram_drawSekeyHansonAuditoryFilters); praat_addAction1 (classBarkSpectrogram, 0, U"Draw spectrum at nearest time slice...", 0, 1, DO_BarkSpectrogram_drawSpectrumAtNearestTimeSlice); praat_addAction1 (classBarkSpectrogram, 0, QUERY_BUTTON, 0, 0, 0); praat_BandFilterSpectrogram_query_init (classBarkSpectrogram); praat_addAction1 (classBarkSpectrogram, 0, U"Equalize intensities...", 0, 0, DO_BandFilterSpectrogram_equalizeIntensities); praat_addAction1 (classBarkSpectrogram, 0, U"To Intensity", 0, 0, DO_BandFilterSpectrogram_to_Intensity); praat_addAction1 (classBarkSpectrogram, 0, U"To Matrix...", 0, 0, DO_BandFilterSpectrogram_to_Matrix); praat_addAction1 (classBarkSpectrogram, 2, U"Cross-correlate...", 0, 0, DO_BandFilterSpectrograms_crossCorrelate); praat_addAction1 (classBarkSpectrogram, 2, U"Convolve...", 0, 0, DO_BandFilterSpectrograms_convolve); praat_addAction1 (classCategories, 0, U"Edit", 0, 0, DO_Categories_edit); praat_addAction1 (classCategories, 0, QUERY_BUTTON, 0, 0, 0); praat_addAction1 (classCategories, 1, U"Get number of categories", QUERY_BUTTON, 1, DO_Categories_getNumberOfCategories); praat_addAction1 (classCategories, 2, U"Get difference", QUERY_BUTTON, praat_HIDDEN | praat_DEPTH_1, DO_Categories_difference); praat_addAction1 (classCategories, 2, U"Get number of differences", QUERY_BUTTON, 1, DO_Categories_getNumberOfDifferences); praat_addAction1 (classCategories, 2, U"Get fraction different", QUERY_BUTTON, 1, DO_Categories_getFractionDifferent); praat_addAction1 (classCategories, 0, MODIFY_BUTTON, 0, 0, 0); praat_addAction1 (classCategories, 1, U"Append 1 category...", MODIFY_BUTTON, 1, DO_Categories_append); praat_addAction1 (classCategories, 0, U"Extract", 0, 0, 0); praat_addAction1 (classCategories, 0, U"To unique Categories", 0, 0, DO_Categories_selectUniqueItems); praat_addAction1 (classCategories, 0, U"Analyse", 0, 0, 0); praat_addAction1 (classCategories, 2, U"To Confusion", 0, 0, DO_Categories_to_Confusion); praat_addAction1 (classCategories, 0, U"Synthesize", 0, 0, 0); praat_addAction1 (classCategories, 2, U"Join", 0, 0, DO_Categories_join); praat_addAction1 (classCategories, 0, U"Permute items", 0, 0, DO_Categories_permuteItems); praat_addAction1 (classCategories, 0, U"To Strings", 0, 0, DO_Categories_to_Strings); praat_addAction1 (classChebyshevSeries, 0, U"ChebyshevSeries help", 0, 0, DO_ChebyshevSeries_help); praat_FunctionTerms_init (classChebyshevSeries); praat_addAction1 (classChebyshevSeries, 0, U"To Polynomial", U"Analyse", 0, DO_ChebyshevSeries_to_Polynomial); praat_addAction1 (classCCA, 1, U"Draw eigenvector...", 0, 0, DO_CCA_drawEigenvector); praat_addAction1 (classCCA, 1, U"Get number of correlations", 0, 0, DO_CCA_getNumberOfCorrelations); praat_addAction1 (classCCA, 1, U"Get correlation...", 0, 0, DO_CCA_getCorrelationCoefficient); praat_addAction1 (classCCA, 1, U"Get eigenvector element...", 0, 0, DO_CCA_getEigenvectorElement); praat_addAction1 (classCCA, 1, U"Get zero correlation probability...", 0, 0, DO_CCA_getZeroCorrelationProbability); praat_addAction2 (classCCA, 1, classTableOfReal, 1, U"To TableOfReal (scores)...", 0, 0, DO_CCA_and_TableOfReal_scores); praat_addAction2 (classCCA, 1, classTableOfReal, 1, U"To TableOfReal (loadings)", 0, 0, DO_CCA_and_TableOfReal_factorLoadings); praat_addAction2 (classCCA, 1, classTableOfReal, 1, U"Predict...", 0, 0, DO_CCA_and_TableOfReal_predict); praat_addAction2 (classCCA, 1, classCorrelation, 1, U"To TableOfReal (loadings)", 0, 0, DO_CCA_and_Correlation_factorLoadings); praat_addAction2 (classCCA, 1, classCorrelation, 1, U"Get variance fraction...", 0, 0, DO_CCA_and_Correlation_getVarianceFraction); praat_addAction2 (classCCA, 1, classCorrelation, 1, U"Get redundancy (sl)...", 0, 0, DO_CCA_and_Correlation_getRedundancy_sl); praat_addAction1 (classComplexSpectrogram, 0, U"ComplexSpectrogram help", 0, 0, DO_ComplexSpectrogram_help); praat_addAction1 (classComplexSpectrogram, 0, DRAW_BUTTON, 0, 0, 0); praat_addAction1 (classComplexSpectrogram, 0, U"To Sound...", 0, 0, DO_ComplexSpectrogram_to_Sound); praat_addAction1 (classComplexSpectrogram, 0, U"Down to Spectrogram", 0, 0, DO_ComplexSpectrogram_to_Spectrogram); praat_addAction1 (classComplexSpectrogram, 0, U"To Spectrum (slice)...", 0, 0, DO_ComplexSpectrogram_to_Spectrum); //praat_addAction1 (classComplexSpectrogram, 0, U"Paint...", 0, 1, DO_Spectrogram_paint); praat_addAction1 (classConfusion, 0, U"Confusion help", 0, 0, DO_Confusion_help); praat_TableOfReal_init2 (classConfusion); praat_removeAction (classConfusion, nullptr, nullptr, U"Draw as numbers..."); praat_removeAction (classConfusion, nullptr, nullptr, U"Sort by label..."); praat_removeAction (classConfusion, nullptr, nullptr, U"Sort by column..."); praat_addAction1 (classConfusion, 0, U"Draw as numbers...", U"Draw -", 1, DO_Confusion_drawAsNumbers); praat_addAction1 (classConfusion, 1, U"Get value (labels)...", U"Get value...", 1, DO_Confusion_getValue); praat_addAction1 (classConfusion, 0, U"-- confusion statistics --", U"Get value (labels)...", 1, 0); praat_addAction1 (classConfusion, 1, U"Get fraction correct", U"-- confusion statistics --", 1, DO_Confusion_getFractionCorrect); praat_addAction1 (classConfusion, 1, U"Get stimulus sum...", U"Get fraction correct", 1, DO_Confusion_getStimulusSum); praat_addAction1 (classConfusion, 1, U"Get row sum...", U"Get fraction correct", praat_DEPTH_1 | praat_HIDDEN, DO_TableOfReal_getRowSum); praat_addAction1 (classConfusion, 1, U"Get response sum...", U"Get stimulus sum...", 1, DO_Confusion_getResponseSum); praat_addAction1 (classConfusion, 1, U"Get column sum...", U"Get row sum...", praat_DEPTH_1 | praat_HIDDEN, DO_TableOfReal_getColumnSum); praat_addAction1 (classConfusion, 1, U"Get grand sum", U"Get response sum...", 1, DO_TableOfReal_getGrandSum); praat_addAction1 (classConfusion, 0, U"Increase...", U"Formula...", 1, DO_Confusion_increase); praat_addAction1 (classConfusion, 0, U"To TableOfReal (marginals)", U"To TableOfReal", 0, DO_Confusion_to_TableOfReal_marginals); praat_addAction1 (classConfusion, 0, U"Analyse", 0, 0, 0); praat_addAction1 (classConfusion, 0, U"Condense...", 0, praat_HIDDEN, DO_Confusion_condense); praat_addAction1 (classConfusion, 0, U"Group...", 0, 0, DO_Confusion_group); praat_addAction1 (classConfusion, 0, U"Group stimuli...", 0, 0, DO_Confusion_groupStimuli); praat_addAction1 (classConfusion, 0, U"Group responses...", 0, 0, DO_Confusion_groupResponses); praat_addAction1 (classConfusion, 2, U"To difference matrix", 0, 0, DO_Confusion_difference); praat_addAction2 (classConfusion, 1, classClassificationTable, 1, U"Increase confusion count", 0, 0, DO_Confusion_and_ClassificationTable_increase); praat_addAction2 (classConfusion, 1, classMatrix, 1, U"Draw", 0, 0, 0); praat_addAction2 (classConfusion, 1, classMatrix, 1, U"Draw confusion...", 0, 0, DO_Confusion_Matrix_draw); praat_addAction1 (classCovariance, 0, U"Covariance help", 0, 0, DO_Covariance_help); praat_SSCP_as_TableOfReal_init (classCovariance); praat_SSCP_query_init (classCovariance); praat_SSCP_extract_init (classCovariance); praat_addAction1 (classCovariance, 1, U"Get probability at position...", U"Get value...", 1, DO_Covariance_getProbabilityAtPosition); praat_addAction1 (classCovariance, 1, U"Get diagonality (bartlett)...", U"Get ln(determinant)", 1, DO_SSCP_testDiagonality_bartlett); praat_addAction1 (classCovariance, 1, U"Get significance of one mean...", U"Get diagonality (bartlett)...", 1, DO_Covariance_getSignificanceOfOneMean); praat_addAction1 (classCovariance, 1, U"Get significance of means difference...", U"Get significance of one mean...", 1, DO_Covariance_getSignificanceOfMeansDifference); praat_addAction1 (classCovariance, 1, U"Get significance of one variance...", U"Get significance of means difference...", 1, DO_Covariance_getSignificanceOfOneVariance); praat_addAction1 (classCovariance, 1, U"Get significance of variances ratio...", U"Get significance of one variance...", 1, DO_Covariance_getSignificanceOfVariancesRatio); praat_addAction1 (classCovariance, 1, U"Get fraction variance...", U"Get significance of variances ratio...", 1, DO_Covariance_getFractionVariance); praat_addAction1 (classCovariance, 2, U"Report multivariate mean difference...", U"Get fraction variance...", 1, DO_Covariances_reportMultivariateMeanDifference); praat_addAction1 (classCovariance, 2, U"Difference", U"Report multivariate mean difference...", praat_DEPTH_1 | praat_HIDDEN, DO_Covariances_reportEquality); praat_addAction1 (classCovariance, 0, U"Report equality of covariances", U"Report multivariate mean difference...", praat_DEPTH_1 | praat_HIDDEN, DO_Covariances_reportEquality); praat_addAction1 (classCovariance, 0, U"To TableOfReal (random sampling)...", 0, 0, DO_Covariance_to_TableOfReal_randomSampling); praat_addAction1 (classCovariance, 0, U"To Correlation", 0, 0, DO_Covariance_to_Correlation); praat_addAction1 (classCovariance, 0, U"To PCA", 0, 0, DO_Covariance_to_PCA); praat_addAction2 (classCovariance, 1, classTableOfReal, 1, U"To TableOfReal (mahalanobis)...", 0, 0, DO_Covariance_and_TableOfReal_mahalanobis); praat_addAction1 (classClassificationTable, 0, U"ClassificationTable help", 0, 0, DO_ClassificationTable_help); praat_TableOfReal_init (classClassificationTable); praat_addAction1 (classClassificationTable, 0, U"Get class index at maximum in row...", U"Get column index...", 1, DO_ClassificationTable_getClassIndexAtMaximumInRow); praat_addAction1 (classClassificationTable, 0, U"Get class label at maximum in row...", U"Get class index at maximum in row...", 1, DO_ClassificationTable_getClassLabelAtMaximumInRow); praat_addAction1 (classClassificationTable, 0, U"To Confusion", 0, praat_HIDDEN, DO_ClassificationTable_to_Confusion_old); // deprecated 2014 praat_addAction1 (classClassificationTable, 0, U"To Confusion...", 0, 0, DO_ClassificationTable_to_Confusion); praat_addAction1 (classClassificationTable, 0, U"To Correlation (columns)", 0, 0, DO_ClassificationTable_to_Correlation_columns); praat_addAction1 (classClassificationTable, 0, U"To Strings (max. prob.)", 0, 0, DO_ClassificationTable_to_Strings_maximumProbability); praat_addAction1 (classCorrelation, 0, U"Correlation help", 0, 0, DO_Correlation_help); praat_TableOfReal_init2 (classCorrelation); praat_SSCP_query_init (classCorrelation); praat_SSCP_extract_init (classCorrelation); praat_addAction1 (classCorrelation, 1, U"Get diagonality (bartlett)...", U"Get ln(determinant)", 1, DO_Correlation_testDiagonality_bartlett); praat_addAction1 (classCorrelation, 0, U"Confidence intervals...", 0, 0, DO_Correlation_confidenceIntervals); praat_addAction1 (classCorrelation, 0, U"To PCA", 0, 0, DO_Correlation_to_PCA); praat_addAction1 (classDiscriminant, 0, U"Discriminant help", 0, 0, DO_Discriminant_help); praat_addAction1 (classDiscriminant, 0, DRAW_BUTTON, 0, 0, 0); praat_Eigen_draw_init (classDiscriminant); praat_addAction1 (classDiscriminant, 0, U"-- sscps --", 0, 1, 0); praat_addAction1 (classDiscriminant, 0, U"Draw sigma ellipses...", 0, 1, DO_Discriminant_drawSigmaEllipses); praat_addAction1 (classDiscriminant, 0, U"Draw one sigma ellipse...", 0, 1, DO_Discriminant_drawOneSigmaEllipse); praat_addAction1 (classDiscriminant, 0, U"Draw confidence ellipses...", 0, 1, DO_Discriminant_drawConfidenceEllipses); praat_addAction1 (classDiscriminant, 1, QUERY_BUTTON, 0, 0, 0); praat_addAction1 (classDiscriminant, 1, U"-- eigen structure --", 0, 1, 0); praat_Eigen_query_init (classDiscriminant); praat_addAction1 (classDiscriminant, 1, U"-- discriminant --", 0, 1, 0); praat_addAction1 (classDiscriminant, 1, U"Get number of functions", 0, 1, DO_Discriminant_getNumberOfFunctions); praat_addAction1 (classDiscriminant, 1, U"Get dimension of functions", 0, 1, DO_Discriminant_getDimensionOfFunctions); praat_addAction1 (classDiscriminant, 1, U"Get number of groups", 0, 1, DO_Discriminant_getNumberOfGroups); praat_addAction1 (classDiscriminant, 1, U"Get number of observations...", 0, 1, DO_Discriminant_getNumberOfObservations); praat_addAction1 (classDiscriminant, 1, U"-- tests --", 0, 1, 0); praat_addAction1 (classDiscriminant, 1, U"Get Wilks lambda...", 0, 1, DO_Discriminant_getWilksLambda); praat_addAction1 (classDiscriminant, 1, U"Get cumulative contribution of components...", 0, 1, DO_Discriminant_getCumulativeContributionOfComponents); praat_addAction1 (classDiscriminant, 1, U"Get partial discrimination probability...", 0, 1, DO_Discriminant_getPartialDiscriminationProbability); praat_addAction1 (classDiscriminant, 1, U"Get homogeneity of covariances (box)", 0, praat_DEPTH_1 | praat_HIDDEN, DO_Discriminant_getHomegeneityOfCovariances_box); praat_addAction1 (classDiscriminant, 1, U"Report equality of covariance matrices", 0, 1, DO_Discriminant_reportEqualityOfCovariances_wald); praat_addAction1 (classDiscriminant, 1, U"-- ellipses --", 0, 1, 0); praat_addAction1 (classDiscriminant, 1, U"Get sigma ellipse area...", 0, 1, DO_Discriminant_getConcentrationEllipseArea); praat_addAction1 (classDiscriminant, 1, U"Get confidence ellipse area...", 0, 1, DO_Discriminant_getConfidenceEllipseArea); praat_addAction1 (classDiscriminant, 1, U"Get ln(determinant_group)...", 0, 1, DO_Discriminant_getLnDeterminant_group); praat_addAction1 (classDiscriminant, 1, U"Get ln(determinant_total)", 0, 1, DO_Discriminant_getLnDeterminant_total); praat_addAction1 (classDiscriminant, 0, MODIFY_BUTTON, 0, 0, 0); praat_addAction1 (classDiscriminant, 1, U"Invert eigenvector...", 0, 1, DO_Discriminant_invertEigenvector); praat_addAction1 (classDiscriminant, 0, U"Align eigenvectors", 0, 1, DO_Eigens_alignEigenvectors); praat_addAction1 (classDiscriminant, 0, EXTRACT_BUTTON, 0, 0, 0); praat_addAction1 (classDiscriminant, 1, U"Extract pooled within-groups SSCP", 0, 1, DO_Discriminant_extractPooledWithinGroupsSSCP); praat_addAction1 (classDiscriminant, 1, U"Extract within-group SSCP...", 0, 1, DO_Discriminant_extractWithinGroupSSCP); praat_addAction1 (classDiscriminant, 1, U"Extract between-groups SSCP", 0, 1, DO_Discriminant_extractBetweenGroupsSSCP); praat_addAction1 (classDiscriminant, 1, U"Extract group centroids", 0, 1, DO_Discriminant_extractGroupCentroids); praat_addAction1 (classDiscriminant, 1, U"Extract group standard deviations", 0, 1, DO_Discriminant_extractGroupStandardDeviations); praat_addAction1 (classDiscriminant, 1, U"Extract group labels", 0, 1, DO_Discriminant_extractGroupLabels); praat_addAction1 (classDiscriminant , 0, U"& TableOfReal: To ClassificationTable?", 0, 0, DO_hint_Discriminant_and_TableOfReal_to_ClassificationTable); /* praat_addAction1 (classDiscriminant, 1, U"Extract coefficients...", 0, 1, DO_Discriminant_extractCoefficients);*/ praat_Eigen_Spectrogram_project (classDiscriminant, classSpectrogram); praat_Eigen_Spectrogram_project (classDiscriminant, classBarkSpectrogram); praat_Eigen_Spectrogram_project (classDiscriminant, classMelSpectrogram); praat_Eigen_Matrix_project (classDiscriminant, classFormantFilter); // deprecated 2014 praat_Eigen_Matrix_project (classDiscriminant, classBarkFilter); // deprecated 2014 praat_Eigen_Matrix_project (classDiscriminant, classMelFilter); // deprecated 2014 praat_addAction2 (classDiscriminant, 1, classPattern, 1, U"To Categories...", 0, 0, DO_Discriminant_and_Pattern_to_Categories); praat_addAction2 (classDiscriminant, 1, classSSCP, 1, U"Project", 0, 0, DO_Eigen_and_SSCP_project); praat_addAction2 (classDiscriminant, 1, classStrings, 1, U"Modify Discriminant", 0, 0, 0); praat_addAction2 (classDiscriminant, 1, classStrings, 1, U"Set group labels", 0, 0, DO_Discriminant_setGroupLabels); praat_addAction2 (classDiscriminant, 1, classTableOfReal, 1, U"To Configuration...", 0, 0, DO_Discriminant_and_TableOfReal_to_Configuration); praat_addAction2 (classDiscriminant, 1, classTableOfReal, 1, U"To ClassificationTable...", 0, 0, DO_Discriminant_and_TableOfReal_to_ClassificationTable); praat_addAction2 (classDiscriminant, 1, classTableOfReal, 1, U"To TableOfReal (mahalanobis)...", 0, 0, DO_Discriminant_and_TableOfReal_mahalanobis); praat_addAction1 (classDTW, 0, U"DTW help", 0, 0, DO_DTW_help); praat_addAction1 (classDTW, 0, DRAW_BUTTON, 0, 0, 0); praat_addAction1 (classDTW, 0, U"Draw path...", 0, 1, DO_DTW_drawPath); praat_addAction1 (classDTW, 0, U"Paint distances...", 0, 1, DO_DTW_paintDistances); praat_addAction1 (classDTW, 0, U"Draw warp (x)...", 0, 1, DO_DTW_drawWarpX); praat_addAction1 (classDTW, 0, QUERY_BUTTON, 0, 0, 0); praat_addAction1 (classDTW, 1, U"Query time domains", 0, 1, 0); praat_addAction1 (classDTW, 1, U"Get start time (x)", 0, 2, DO_DTW_getStartTimeX); praat_addAction1 (classDTW, 1, U"Get end time (x)", 0, 2, DO_DTW_getEndTimeX); praat_addAction1 (classDTW, 1, U"Get total duration (x)", 0, 2, DO_DTW_getTotalDurationX); praat_addAction1 (classDTW, 1, U"-- time domain x from y separator --", 0, 2, 0); praat_addAction1 (classDTW, 1, U"Get start time (y)", 0, 2, DO_DTW_getStartTimeY); praat_addAction1 (classDTW, 1, U"Get end time (y)", 0, 2, DO_DTW_getEndTimeY); praat_addAction1 (classDTW, 1, U"Get total duration (y)", 0, 2, DO_DTW_getTotalDurationY); praat_addAction1 (classDTW, 1, U"Query time samplings", 0, 1, 0); praat_addAction1 (classDTW, 1, U"Get number of frames (x)", 0, 2, DO_DTW_getNumberOfFramesX); praat_addAction1 (classDTW, 1, U"Get time step (x)", 0, 2, DO_DTW_getTimeStepX); praat_addAction1 (classDTW, 1, U"Get time from frame number (x)...", 0, 2, DO_DTW_getTimeFromFrameNumberX); praat_addAction1 (classDTW, 1, U"Get frame number from time (x)...", 0, 2, DO_DTW_getFrameNumberFromTimeX); praat_addAction1 (classDTW, 1, U"-- time sampling x from y separator --", 0, 2, 0); praat_addAction1 (classDTW, 1, U"Get number of frames (y)", 0, 2, DO_DTW_getNumberOfFramesY); praat_addAction1 (classDTW, 1, U"Get time step (y)", 0, 2, DO_DTW_getTimeStepY); praat_addAction1 (classDTW, 1, U"Get time from frame number (y)...", 0, 2, DO_DTW_getTimeFromFrameNumberY); praat_addAction1 (classDTW, 1, U"Get frame number from time (y)...", 0, 2, DO_DTW_getFrameNumberFromTimeY); praat_addAction1 (classDTW, 1, U"Get y time from x time...", 0, 1, DO_DTW_getYTimeFromXTime); praat_addAction1 (classDTW, 1, U"Get x time from y time...", 0, 1, DO_DTW_getXTimeFromYTime); praat_addAction1 (classDTW, 1, U"Get y time...", 0, praat_HIDDEN + praat_DEPTH_1, DO_DTW_getYTimeFromXTime); praat_addAction1 (classDTW, 1, U"Get x time...", 0, praat_HIDDEN + praat_DEPTH_1, DO_DTW_getXTimeFromYTime); praat_addAction1 (classDTW, 1, U"Get maximum consecutive steps...", 0, 1, DO_DTW_getMaximumConsecutiveSteps); praat_addAction1 (classDTW, 1, U"Get time along path...", 0, praat_DEPTH_1 | praat_HIDDEN, DO_DTW_getPathY); praat_addAction1 (classDTW, 1, U"-- distance queries --", 0, 1, 0); praat_addAction1 (classDTW, 1, U"Get distance value...", 0, 1, DO_DTW_getDistanceValue); praat_addAction1 (classDTW, 1, U"Get minimum distance", 0, 1, DO_DTW_getMinimumDistance); praat_addAction1 (classDTW, 1, U"Get maximum distance", 0, 1, DO_DTW_getMaximumDistance); praat_addAction1 (classDTW, 1, U"Get distance (weighted)", 0, 1, DO_DTW_getWeightedDistance); praat_addAction1 (classDTW, 0, MODIFY_BUTTON, 0, 0, 0); praat_addAction1 (classDTW, 0, U"Formula (distances)...", 0, 1, DO_DTW_formulaDistances); praat_addAction1 (classDTW, 0, U"Set distance value...", 0, 1, DO_DTW_setDistanceValue); praat_addAction1 (classDTW, 0, U"Analyse", 0, 0, 0); praat_addAction1 (classDTW, 0, U"Find path...", 0, praat_HIDDEN, DO_DTW_findPath); praat_addAction1 (classDTW, 0, U"Find path (band & slope)...", 0, 0, DO_DTW_findPath_bandAndSlope); praat_addAction1 (classDTW, 0, U"To Polygon...", 0, 1, DO_DTW_to_Polygon); praat_addAction1 (classDTW, 0, U"To Matrix (distances)", 0, 0, DO_DTW_to_Matrix_distances); praat_addAction1 (classDTW, 0, U"To Matrix (cumm. distances)...", 0, 0, DO_DTW_to_Matrix_cummulativeDistances); praat_addAction1 (classDTW, 0, U"Swap axes", 0, 0, DO_DTW_swapAxes); praat_addAction2 (classDTW, 1, classMatrix, 1, U"Replace matrix", 0, 0, DO_DTW_and_Matrix_replace); praat_addAction2 (classDTW, 1, classTextGrid, 1, U"To TextGrid (warp times)", 0, 0, DO_DTW_and_TextGrid_to_TextGrid); praat_addAction2 (classDTW, 1, classIntervalTier, 1, U"To Table (distances)", 0, 0, DO_DTW_and_IntervalTier_to_Table); praat_addAction2 (classDTW, 1, classPolygon, 1, U"Find path inside...", 0, 0, DO_DTW_and_Polygon_findPathInside); praat_addAction2 (classDTW, 1, classPolygon, 1, U"To Matrix (cumm. distances)...", 0, 0, DO_DTW_and_Polygon_to_Matrix_cummulativeDistances); praat_addAction2 (classDTW, 1, classSound, 2, U"Draw...", 0, 0, DO_DTW_and_Sounds_draw); praat_addAction2 (classDTW, 1, classSound, 2, U"Draw warp (x)...", 0, 0, DO_DTW_and_Sounds_drawWarpX); praat_addAction1 (classEditDistanceTable, 1, U"EditDistanceTable help", 0, 0, DO_EditDistanceTable_help); praat_EditDistanceTable_as_TableOfReal_init (classEditDistanceTable); praat_addAction1 (classEditDistanceTable, 1, U"To TableOfReal (directions)...", 0, praat_HIDDEN, DO_EditDistanceTable_to_TableOfReal_directions); praat_addAction2 (classEditDistanceTable, 1, classEditCostsTable, 1, U"Set new edit costs", 0, 0, DO_EditDistanceTable_setEditCosts); praat_addAction1 (classEditCostsTable, 1, U"EditCostsTable help", 0, 0, DO_EditCostsTable_help); praat_addAction1 (classEditCostsTable, 0, QUERY_BUTTON, 0, 0, 0); praat_addAction1 (classEditCostsTable, 1, U"Get target index...", 0, 1, DO_EditCostsTable_getTargetIndex); praat_addAction1 (classEditCostsTable, 1, U"Get source index...", 0, 1, DO_EditCostsTable_getSourceIndex); praat_addAction1 (classEditCostsTable, 1, U"Get insertion cost...", 0, 1, DO_EditCostsTable_getInsertionCost); praat_addAction1 (classEditCostsTable, 1, U"Get deletion cost...", 0, 1, DO_EditCostsTable_getDeletionCost); praat_addAction1 (classEditCostsTable, 1, U"Get substitution cost...", 0, 1, DO_EditCostsTable_getSubstitutionCost); praat_addAction1 (classEditCostsTable, 1, U"Get cost (others)...", 0, 1, DO_EditCostsTable_getOthersCost); praat_addAction1 (classEditCostsTable, 0, MODIFY_BUTTON, 0, 0, 0); praat_addAction1 (classEditCostsTable, 1, U"Set target symbol (index)...", 0, 1, DO_EditCostsTable_setTargetSymbol_index); praat_addAction1 (classEditCostsTable, 1, U"Set source symbol (index)...", 0, 1, DO_EditCostsTable_setSourceSymbol_index); praat_addAction1 (classEditCostsTable, 1, U"Set insertion costs...", 0, 1, DO_EditCostsTable_setInsertionCosts); praat_addAction1 (classEditCostsTable, 1, U"Set deletion costs...", 0, 1, DO_EditCostsTable_setDeletionCosts); praat_addAction1 (classEditCostsTable, 1, U"Set substitution costs...", 0, 1, DO_EditCostsTable_setSubstitutionCosts); praat_addAction1 (classEditCostsTable, 1, U"Set costs (others)...", 0, 1, DO_EditCostsTable_setOthersCosts); praat_addAction1 (classEditCostsTable, 1, U"To TableOfReal", 0, 0, DO_EditCostsTable_to_TableOfReal); praat_Index_init (classStringsIndex); praat_addAction1 (classIndex, 0, U"Index help", 0, 0, DO_Index_help); praat_addAction1 (classStringsIndex, 1, U"Get class label...", 0, 0, DO_StringsIndex_getClassLabel); praat_addAction1 (classStringsIndex, 1, U"Get class index...", 0, 0, DO_StringsIndex_getClassIndex); praat_addAction1 (classStringsIndex, 1, U"Get label...", 0, 0, DO_StringsIndex_getLabel); praat_addAction1 (classIndex, 1, U"Get index...", 0, 0, DO_Index_getIndex); praat_addAction1 (classStringsIndex, 1, U"To Strings", 0, 0, DO_StringsIndex_to_Strings); praat_addAction1 (classExcitation, 0, U"Synthesize", U"To Formant...", 0, 0); praat_addAction1 (classExcitation, 0, U"To Excitations", U"Synthesize", 0, DO_Excitation_to_Excitations); praat_addAction1 (classExcitations, 0, U"Modify", 0, 0, 0); praat_addAction1 (classExcitations, 0, U"Formula...", 0, 0, DO_Excitations_formula); praat_addAction1 (classExcitations, 0, U"Extract", 0, 0, 0); praat_addAction1 (classExcitations, 0, U"Extract Excitation...", 0, 0, DO_Excitations_getItem); praat_addAction1 (classExcitations, 0, U"Synthesize", 0, 0, 0); praat_addAction1 (classExcitations, 0, U"Append", 0, 0, DO_Excitations_append); praat_addAction1 (classExcitations, 0, U"Convert", 0, 0, 0); praat_addAction1 (classExcitations, 0, U"To Pattern...", 0, 0, DO_Excitations_to_Pattern); praat_addAction1 (classExcitations, 0, U"To TableOfReal", 0, 0, DO_Excitations_to_TableOfReal); praat_addAction2 (classExcitations, 1, classExcitation, 0, U"Add to Excitations", 0, 0, DO_Excitations_addItem); praat_addAction1 (classFileInMemory, 1, U"Show as code...", 0, 0, DO_FileInMemory_showAsCode); praat_addAction1 (classFileInMemory, 1, U"Set id...", 0, 0, DO_FileInMemory_setId); praat_addAction1 (classFileInMemory, 0, U"To FilesInMemory", 0, 0, DO_FileInMemory_to_FilesInMemory); praat_addAction1 (classFilesInMemory, 1, U"Show as code...", 0, 0, DO_FilesInMemory_showAsCode); praat_addAction1 (classFilesInMemory, 1, U"Show one file as code...", 0, 0, DO_FilesInMemory_showOneFileAsCode); praat_addAction1 (classFilesInMemory, 0, U"Merge", 0, 0, DO_FilesInMemory_merge); praat_addAction1 (classFilesInMemory, 0, U"To Strings (id)", 0, 0, DO_FilesInMemory_to_Strings_id); praat_addAction2 (classFilesInMemory, 1, classFileInMemory, 0, U"Add items to Collection", 0, 0, DO_FilesInMemory_addItems); praat_addAction1 (classFormantFilter, 0, U"FormantFilter help", 0, 0, DO_FormantFilter_help); praat_FilterBank_all_init (classFormantFilter); praat_addAction1 (classFormantFilter, 0, U"Draw spectrum (slice)...", U"Draw filters...", praat_DEPTH_1 + praat_HIDDEN, DO_FormantFilter_drawSpectrum); praat_addAction1 (classFormantFilter, 0, U"Draw filter functions...", U"Draw filters...", praat_DEPTH_1 + praat_HIDDEN, DO_FormantFilter_drawFilterFunctions); praat_addAction1 (classFormantFilter, 0, U"To Spectrogram", 0, 0, DO_FormantFilter_to_Spectrogram); praat_addAction1 (classFormantGrid, 0, U"Draw...", U"Edit", praat_DEPTH_1 + praat_HIDDEN, DO_FormantGrid_draw); praat_addAction1 (classIntensity, 0, U"To TextGrid (silences)...", U"To IntensityTier (valleys)", 0, DO_Intensity_to_TextGrid_detectSilences); praat_addAction1 (classIntensityTier, 0, U"To TextGrid (silences)...", 0, 0, DO_IntensityTier_to_TextGrid_detectSilences); praat_addAction1 (classIntensityTier, 0, U"To Intensity...", 0, praat_HIDDEN, DO_IntensityTier_to_Intensity); praat_addAction1 (classISpline, 0, U"ISpline help", 0, 0, DO_ISpline_help); praat_Spline_init (classISpline); praat_addAction1 (classKlattTable, 0, U"KlattTable help", 0, 0, DO_KlattTable_help); praat_addAction1 (classKlattTable, 0, U"To Sound...", 0, 0, DO_KlattTable_to_Sound); praat_addAction1 (classKlattTable, 0, U"To KlattGrid...", 0, 0, DO_KlattTable_to_KlattGrid); praat_addAction1 (classKlattTable, 0, U"To Table", 0, 0, DO_KlattTable_to_Table); praat_addAction1 (classLegendreSeries, 0, U"LegendreSeries help", 0, 0, DO_LegendreSeries_help); praat_FunctionTerms_init (classLegendreSeries); praat_addAction1 (classLegendreSeries, 0, U"To Polynomial", U"Analyse", 0, DO_LegendreSeries_to_Polynomial); praat_addAction1 (classLongSound, 0, U"Append to existing sound file...", 0, 0, DO_LongSounds_appendToExistingSoundFile); praat_addAction1 (classSound, 0, U"Append to existing sound file...", 0, 0, DO_LongSounds_appendToExistingSoundFile); praat_addAction2 (classLongSound, 0, classSound, 0, U"Append to existing sound file...", 0, 0, DO_LongSounds_appendToExistingSoundFile); praat_addAction1 (classLongSound, 2, U"Save as stereo AIFF file...", U"Save as NIST file...", 1, DO_LongSounds_writeToStereoAiffFile); praat_addAction1 (classLongSound, 2, U"Write to stereo AIFF file...", U"Write to NIST file...", praat_HIDDEN + praat_DEPTH_1, DO_LongSounds_writeToStereoAiffFile); praat_addAction1 (classLongSound, 2, U"Save as stereo AIFC file...", U"Save as stereo AIFF file...", 1, DO_LongSounds_writeToStereoAifcFile); praat_addAction1 (classLongSound, 2, U"Write to stereo AIFC file...", U"Write to stereo AIFF file...", praat_HIDDEN + praat_DEPTH_1, DO_LongSounds_writeToStereoAifcFile); praat_addAction1 (classLongSound, 2, U"Save as stereo WAV file...", U"Save as stereo AIFC file...", 1, DO_LongSounds_writeToStereoWavFile); praat_addAction1 (classLongSound, 2, U"Write to stereo WAV file...", U"Write to stereo AIFC file...", praat_HIDDEN + praat_DEPTH_1, DO_LongSounds_writeToStereoWavFile); praat_addAction1 (classLongSound, 2, U"Save as stereo NeXt/Sun file...", U"Save as stereo WAV file...", 1, DO_LongSounds_writeToStereoNextSunFile); praat_addAction1 (classLongSound, 2, U"Write to stereo NeXt/Sun file...", U"Write to stereo WAV file...", praat_HIDDEN + praat_DEPTH_1, DO_LongSounds_writeToStereoNextSunFile); praat_addAction1 (classLongSound, 2, U"Save as stereo NIST file...", U"Save as stereo NeXt/Sun file...", 1, DO_LongSounds_writeToStereoNistFile); praat_addAction1 (classLongSound, 2, U"Write to stereo NIST file...", U"Write to stereo NeXt/Sun file...", praat_HIDDEN + praat_DEPTH_1, DO_LongSounds_writeToStereoNistFile); praat_addAction1 (classLtas, 0, U"Report spectral tilt...", U"Get slope...", 1, DO_Ltas_reportSpectralTilt); praat_addAction1 (classMatrix, 0, U"Scatter plot...", U"Paint cells...", 1, DO_Matrix_scatterPlot); praat_addAction1 (classMatrix, 0, U"Draw as squares...", U"Scatter plot...", 1, DO_Matrix_drawAsSquares); praat_addAction1 (classMatrix, 0, U"Draw distribution...", U"Draw as squares...", 1, DO_Matrix_drawDistribution); praat_addAction1 (classMatrix, 0, U"Draw cumulative distribution...", U"Draw distribution...", 1, DO_Matrix_drawCumulativeDistribution); praat_addAction1 (classMatrix, 0, U"Get mean...", U"Get sum", 1, DO_Matrix_getMean); praat_addAction1 (classMatrix, 0, U"Get standard deviation...", U"Get mean...", 1, DO_Matrix_getStandardDeviation); praat_addAction1 (classMatrix, 0, U"Transpose", U"Synthesize", 0, DO_Matrix_transpose); praat_addAction1 (classMatrix, 0, U"Solve equation...", U"Analyse", 0, DO_Matrix_solveEquation); praat_addAction1 (classMatrix, 0, U"To Pattern...", U"To VocalTract", 1, DO_Matrix_to_Pattern); praat_addAction1 (classMatrix, 0, U"To Activation", U"To Pattern...", 1, DO_Matrix_to_Activation); praat_addAction1 (classMatrix, 2, U"To DTW...", U"To ParamCurve", 1, DO_Matrices_to_DTW); praat_addAction2 (classMatrix, 1, classCategories, 1, U"To TableOfReal", 0, 0, DO_Matrix_Categories_to_TableOfReal); praat_addAction1 (classMelSpectrogram, 0, U"MelSpectrogram help", 0, 0, DO_MelSpectrogram_help); praat_BandFilterSpectrogram_draw_init (classMelSpectrogram); praat_addAction1 (classMelSpectrogram, 0, U"Paint image...", 0, 1, DO_MelSpectrogram_paintImage); praat_addAction1 (classMelSpectrogram, 0, U"Draw triangular filter functions...", 0, 1, DO_MelSpectrogram_drawTriangularFilterFunctions); praat_addAction1 (classMelSpectrogram, 0, U"Draw spectrum at nearest time slice...", 0, 1, DO_MelSpectrogram_drawSpectrumAtNearestTimeSlice); praat_addAction1 (classMelSpectrogram, 0, QUERY_BUTTON, 0, 0, 0); praat_BandFilterSpectrogram_query_init (classMelSpectrogram); praat_addAction1 (classMelSpectrogram, 0, U"Equalize intensities...", 0, 0, DO_BandFilterSpectrogram_equalizeIntensities); praat_addAction1 (classMelSpectrogram, 0, U"To MFCC...", 0, 0, DO_MelSpectrogram_to_MFCC); praat_addAction1 (classMelSpectrogram, 0, U"To Intensity", 0, 0, DO_BandFilterSpectrogram_to_Intensity); praat_addAction1 (classMelSpectrogram, 0, U"To Matrix...", 0, 0, DO_BandFilterSpectrogram_to_Matrix); praat_addAction1 (classMelSpectrogram, 2, U"Cross-correlate...", 0, 0, DO_BandFilterSpectrograms_crossCorrelate); praat_addAction1 (classMelSpectrogram, 2, U"Convolve...", 0, 0, DO_BandFilterSpectrograms_convolve); praat_addAction1 (classMelFilter, 0, U"MelFilter help", 0, 0, DO_MelFilter_help); // deprecated 2014 praat_FilterBank_all_init (classMelFilter); // deprecated 2014 praat_addAction1 (classMelFilter, 0, U"Draw spectrum (slice)...", U"Draw filters...", praat_DEPTH_1 + praat_HIDDEN, DO_MelFilter_drawSpectrum); // deprecated 2014 praat_addAction1 (classMelFilter, 0, U"Draw filter functions...", U"Draw filters...", praat_DEPTH_1 + praat_HIDDEN, DO_MelFilter_drawFilterFunctions); // deprecated 2014 praat_addAction1 (classMelFilter, 0, U"Paint...", U"Draw filter functions...", praat_DEPTH_1 + praat_HIDDEN, DO_MelFilter_paint); // deprecated 2014 praat_addAction1 (classMelFilter, 0, U"To MFCC...", 0, praat_HIDDEN, DO_MelFilter_to_MFCC); // deprecated 2014 praat_addAction1 (classMelFilter, 0, U"To MelSpectrogram", 0, 0, DO_MelFilter_to_MelSpectrogram); praat_addAction1 (classMFCC, 0, U"MFCC help", 0, 0, DO_MFCC_help); praat_CC_init (classMFCC); praat_addAction1 (classMFCC, 0, U"To MelFilter...", 0, praat_HIDDEN, DO_MFCC_to_MelFilter); praat_addAction1 (classMFCC, 0, U"To MelSpectrogram...", 0, 0, DO_MFCC_to_MelSpectrogram); praat_addAction1 (classMFCC, 0, U"To TableOfReal...", 0, 0, DO_MFCC_to_TableOfReal); praat_addAction1 (classMFCC, 0, U"To Matrix (features)...", 0, praat_HIDDEN, DO_MFCC_to_Matrix_features); praat_addAction1 (classMFCC, 0, U"To Sound", 0, praat_HIDDEN, DO_MFCC_to_Sound); praat_addAction1 (classMFCC, 2, U"Cross-correlate...", 0, 0, DO_MFCCs_crossCorrelate); praat_addAction1 (classMFCC, 2, U"Convolve...", 0, 0, DO_MFCCs_convolve); praat_addAction1 (classMSpline, 0, U"MSpline help", 0, 0, DO_MSpline_help); praat_Spline_init (classMSpline); praat_addAction1 (classPattern, 0, U"Draw", 0, 0, 0); praat_addAction1 (classPattern, 0, U"Draw...", 0, 0, DO_Pattern_draw); praat_addAction1 (classPattern, 0, MODIFY_BUTTON, 0, 0, 0); praat_addAction1 (classPattern, 0, U"Formula...", 0, 1, DO_Pattern_formula); praat_addAction1 (classPattern, 0, U"Set value...", 0, 1, DO_Pattern_setValue); praat_addAction1 (classPattern, 0, U"To Matrix", 0, 0, DO_Pattern_to_Matrix); praat_addAction2 (classPattern, 1, classCategories, 1, U"To TableOfReal", 0, 0, DO_Matrix_Categories_to_TableOfReal); praat_addAction2 (classPattern, 1, classCategories, 1, U"To Discriminant", 0, 0, DO_Pattern_and_Categories_to_Discriminant); praat_addAction1 (classPCA, 0, U"PCA help", 0, 0, DO_PCA_help); praat_addAction1 (classPCA, 0, DRAW_BUTTON, 0, 0, 0); praat_Eigen_draw_init (classPCA); praat_addAction1 (classPCA, 0, QUERY_BUTTON, 0, 0, 0); praat_Eigen_query_init (classPCA); praat_addAction1 (classPCA, 1, U"-- pca --", 0, 1, 0); praat_addAction1 (classPCA, 1, U"Get centroid element...", 0, 1, DO_PCA_getCentroidElement); praat_addAction1 (classPCA, 1, U"Get equality of eigenvalues...", 0, 1, DO_PCA_getEqualityOfEigenvalues); praat_addAction1 (classPCA, 1, U"Get fraction variance accounted for...", 0, 1, DO_PCA_getFractionVAF); praat_addAction1 (classPCA, 1, U"Get number of components (VAF)...", 0, 1, DO_PCA_getNumberOfComponentsVAF); praat_addAction1 (classPCA, 2, U"Get angle between pc1-pc2 planes", 0, 1, DO_PCAs_getAngleBetweenPc1Pc2Plane_degrees); praat_addAction1 (classPCA, 0, MODIFY_BUTTON, 0, 0, 0); praat_addAction1 (classPCA, 1, U"Invert eigenvector...", 0, 1, DO_PCA_invertEigenvector); praat_addAction1 (classPCA, 0, U"Align eigenvectors", 0, 1, DO_Eigens_alignEigenvectors); praat_addAction1 (classPCA, 2, U"To Procrustes...", 0, 0, DO_PCAs_to_Procrustes); praat_addAction1 (classPCA, 0, U"To TableOfReal (reconstruct 1)...", 0, 0, DO_PCA_to_TableOfReal_reconstruct1); praat_addAction1 (classPCA, 0, U"& TableOfReal: To Configuration?", 0, 0, DO_hint_PCA_and_TableOfReal_to_Configuration); praat_addAction1 (classPCA, 0, U"& Configuration (reconstruct)?", 0, 0, DO_hint_PCA_and_Configuration_to_TableOfReal_reconstruct); praat_addAction1 (classPCA, 0, U"& Covariance: Project?", 0, 0, DO_hint_PCA_and_Covariance_Project); praat_addAction2 (classPCA, 1, classConfiguration, 1, U"To TableOfReal (reconstruct)", 0, 0, DO_PCA_and_Configuration_to_TableOfReal_reconstruct); praat_addAction2 (classPCA, 1, classSSCP, 1, U"Project", 0, 0, DO_Eigen_and_SSCP_project); praat_addAction2 (classPCA, 1, classTableOfReal, 1, U"To Configuration...", 0, 0, DO_PCA_and_TableOfReal_to_Configuration); praat_addAction2 (classPCA, 1, classTableOfReal, 1, U"To TableOfReal (z-scores)...", 0, 0, DO_PCA_and_TableOfReal_to_TableOfReal_zscores); praat_addAction2 (classPCA, 1, classTableOfReal, 1, U"Get fraction variance...", 0, 0, DO_PCA_and_TableOfReal_getFractionVariance); praat_addAction2 (classPCA, 1, classCovariance, 1, U"Project", 0, 0, DO_Eigen_and_Covariance_project); praat_Eigen_Spectrogram_project (classPCA, classSpectrogram); praat_Eigen_Spectrogram_project (classPCA, classBarkSpectrogram); praat_Eigen_Spectrogram_project (classPCA, classMelSpectrogram); praat_Eigen_Matrix_project (classPCA, classFormantFilter); // deprecated 2014 praat_Eigen_Matrix_project (classPCA, classBarkFilter); // deprecated 2014 praat_Eigen_Matrix_project (classPCA, classMelFilter); // deprecated 2014 praat_addAction1 (classPermutation, 0, U"Permutation help", 0, 0, DO_Permutation_help); praat_addAction1 (classPermutation, 0, QUERY_BUTTON, 0, 0, 0); praat_addAction1 (classPermutation, 1, U"Get number of elements", 0, 1, DO_Permutation_getNumberOfElements); praat_addAction1 (classPermutation, 1, U"Get value...", 0, 1, DO_Permutation_getValueAtIndex); praat_addAction1 (classPermutation, 1, U"Get index...", 0, 1, DO_Permutation_getIndexAtValue); praat_addAction1 (classPermutation, 0, MODIFY_BUTTON, 0, 0, 0); praat_addAction1 (classPermutation, 1, U"Sort", 0, 1, DO_Permutation_sort); praat_addAction1 (classPermutation, 1, U"Swap blocks...", 0, 1, DO_Permutation_swapBlocks); praat_addAction1 (classPermutation, 1, U"Swap numbers...", 0, 1, DO_Permutation_swapNumbers); praat_addAction1 (classPermutation, 1, U"Swap positions...", 0, 1, DO_Permutation_swapPositions); praat_addAction1 (classPermutation, 1, U"Swap one from range...", 0, 1, DO_Permutation_swapOneFromRange); praat_addAction1 (classPermutation, 0, U"-- sequential permutations --", 0, 1, 0); praat_addAction1 (classPermutation, 0, U"Next", 0, 1, DO_Permutations_next); praat_addAction1 (classPermutation, 0, U"Previous", 0, 1, DO_Permutations_previous); praat_addAction1 (classPermutation, 1, U"Permute randomly...", 0, 0, DO_Permutation_permuteRandomly); praat_addAction1 (classPermutation, 1, U"Permute randomly (blocks)...", 0, 0, DO_Permutation_permuteBlocksRandomly); praat_addAction1 (classPermutation, 1, U"Interleave...", 0, 0, DO_Permutation_interleave); praat_addAction1 (classPermutation, 1, U"Rotate...", 0, 0, DO_Permutation_rotate); praat_addAction1 (classPermutation, 1, U"Reverse...", 0, 0, DO_Permutation_reverse); praat_addAction1 (classPermutation, 1, U"Invert", 0, 0, DO_Permutation_invert); praat_addAction1 (classPermutation, 0, U"Multiply", 0, 0, DO_Permutations_multiply); praat_addAction1 (classPitch, 2, U"To DTW...", U"To PointProcess", praat_HIDDEN, DO_Pitches_to_DTW); praat_addAction1 (classPitchTier, 0, U"To Pitch...", U"To Sound (sine)...", 1, DO_PitchTier_to_Pitch); praat_addAction1 (classPolygon, 0, QUERY_BUTTON, U"Paint circles...", 0, 0); praat_addAction1 (classPolygon, 0, U"Get number of points", QUERY_BUTTON, 1, DO_Polygon_getNumberOfPoints); praat_addAction1 (classPolygon, 0, U"Get point (x)...", U"Get number of points", 1, DO_Polygon_getPointX); praat_addAction1 (classPolygon, 0, U"Get point (y)...", U"Get point (x)...", 1, DO_Polygon_getPointY); praat_addAction1 (classPolygon, 0, U"-- other queries --", U"Get point (y)...", 1, 0); praat_addAction1 (classPolygon, 0, U"Get location of point...", U"-- other queries --", 1, DO_Polygon_getLocationOfPoint); praat_addAction1 (classPolygon, 0, U"Get area of convex hull...", U"Get location of point...", praat_DEPTH_1 + praat_HIDDEN, DO_Polygon_getAreaOfConvexHull); praat_addAction1 (classPolygon, 0, U"Translate...", MODIFY_BUTTON, 1, DO_Polygon_translate); praat_addAction1 (classPolygon, 0, U"Rotate...", U"Translate...", 1, DO_Polygon_rotate); praat_addAction1 (classPolygon, 0, U"Scale...", U"Rotate...", 1, DO_Polygon_scale); praat_addAction1 (classPolygon, 0, U"Reverse X", U"Scale...", 1, DO_Polygon_reverseX); praat_addAction1 (classPolygon, 0, U"Reverse Y", U"Reverse X", 1, DO_Polygon_reverseY); praat_addAction1 (classPolygon, 0, U"Simplify", 0, praat_HIDDEN, DO_Polygon_simplify); praat_addAction1 (classPolygon, 0, U"Convex hull", 0, 0, DO_Polygon_convexHull); praat_addAction1 (classPolygon, 0, U"Circular permutation...", 0, praat_HIDDEN, DO_Polygon_circularPermutation); praat_addAction2 (classPolygon, 1, classCategories, 1, U"Draw...", 0, 0, DO_Polygon_Categories_draw); praat_addAction1 (classPolynomial, 0, U"Polynomial help", 0, 0, DO_Polynomial_help); praat_FunctionTerms_init (classPolynomial); praat_addAction1 (classPolynomial, 0, U"-- area --", U"Get x of maximum...", 1, 0); praat_addAction1 (classPolynomial, 1, U"Get area...", U"-- area --", 1, DO_Polynomial_getArea); praat_addAction1 (classPolynomial, 0, U"-- monic --", U"Set coefficient...", 1, 0); praat_addAction1 (classPolynomial, 0, U"Scale coefficients (monic)", U"-- monic --", 1, DO_Polynomial_scaleCoefficients_monic); praat_addAction1 (classPolynomial, 1, U"Get value (complex)...", U"Get value...", 1, DO_Polynomial_evaluate_z); praat_addAction1 (classPolynomial, 0, U"To Spectrum...", U"Analyse", 0, DO_Polynomial_to_Spectrum); praat_addAction1 (classPolynomial, 0, U"To Roots", 0, 0, DO_Polynomial_to_Roots); praat_addAction1 (classPolynomial, 0, U"To Polynomial (derivative)", 0, 0, DO_Polynomial_getDerivative); praat_addAction1 (classPolynomial, 0, U"To Polynomial (primitive)", 0, 0, DO_Polynomial_getPrimitive); praat_addAction1 (classPolynomial, 0, U"Scale x...", 0, 0, DO_Polynomial_scaleX); praat_addAction1 (classPolynomial, 2, U"Multiply", 0, 0, DO_Polynomials_multiply); praat_addAction1 (classPolynomial, 2, U"Divide...", 0, 0, DO_Polynomials_divide); praat_addAction1 (classRoots, 1, U"Roots help", 0, 0, DO_Roots_help); praat_addAction1 (classRoots, 1, U"Draw...", 0, 0, DO_Roots_draw); praat_addAction1 (classRoots, 1, QUERY_BUTTON, 0, 0, 0); praat_addAction1 (classRoots, 1, U"Get number of roots", 0, 1, DO_Roots_getNumberOfRoots); praat_addAction1 (classRoots, 1, U"-- roots --", 0, 1, 0); praat_addAction1 (classRoots, 1, U"Get root...", 0, 1, DO_Roots_getRoot); praat_addAction1 (classRoots, 1, U"Get real part of root...", 0, 1, DO_Roots_getRealPartOfRoot); praat_addAction1 (classRoots, 1, U"Get imaginary part of root...", 0, 1, DO_Roots_getImaginaryPartOfRoot); praat_addAction1 (classRoots, 1, MODIFY_BUTTON, 0, 0, 0); praat_addAction1 (classRoots, 1, U"Set root...", 0, 1, DO_Roots_setRoot); praat_addAction1 (classRoots, 0, U"Analyse", 0, 0, 0); praat_addAction1 (classRoots, 0, U"To Spectrum...", 0, 0, DO_Roots_to_Spectrum); praat_addAction2 (classRoots, 1, classPolynomial, 1, U"Polish roots", 0, 0, DO_Roots_and_Polynomial_polish); praat_addAction1 (classSound, 0, U"To TextGrid (silences)...", U"To IntervalTier", 1, DO_Sound_to_TextGrid_detectSilences); praat_addAction1 (classSound, 0, U"Play one channel...", U"Play", praat_HIDDEN, DO_Sound_playOneChannel); praat_addAction1 (classSound, 0, U"Play as frequency shifted...", U"Play", praat_HIDDEN, DO_Sound_playAsFrequencyShifted); praat_addAction1 (classSound, 0, U"Draw where...", U"Draw...", 1, DO_Sound_drawWhere); // praat_addAction1 (classSound, 0, U"Paint where...", U"Draw where...", praat_DEPTH_1 | praat_HIDDEN, DO_Sound_paintWhere); praat_addAction1 (classSound, 0, U"Paint where...", U"Draw where...", 1, DO_Sound_paintWhere); // praat_addAction1 (classSound, 2, U"Paint enclosed...", U"Paint where...", praat_DEPTH_1 | praat_HIDDEN, DO_Sounds_paintEnclosed); praat_addAction1 (classSound, 2, U"Paint enclosed...", U"Paint where...", 1, DO_Sounds_paintEnclosed); praat_addAction1 (classSound, 0, U"To Pitch (shs)...", U"To Pitch (cc)...", 1, DO_Sound_to_Pitch_shs); praat_addAction1 (classSound, 0, U"Fade in...", U"Multiply by window...", praat_HIDDEN + praat_DEPTH_1, DO_Sound_fadeIn); praat_addAction1 (classSound, 0, U"Fade out...", U"Fade in...", praat_HIDDEN + praat_DEPTH_1, DO_Sound_fadeOut); praat_addAction1 (classSound, 0, U"To Pitch (SPINET)...", U"To Pitch (cc)...", 1, DO_Sound_to_Pitch_SPINET); praat_addAction1 (classSound, 0, U"To FormantFilter...", U"To Cochleagram (edb)...", praat_HIDDEN + praat_DEPTH_1, DO_Sound_to_FormantFilter); praat_addAction1 (classSound, 0, U"To Spectrogram (pitch-dependent)...", U"To Cochleagram (edb)...", 1, DO_Sound_to_Spectrogram_pitchDependent); praat_addAction1 (classSound, 0, U"To BarkFilter...", U"To FormantFilter...", praat_HIDDEN + praat_DEPTH_1, DO_Sound_to_BarkFilter); // deprecated 2014 praat_addAction1 (classSound, 0, U"To BarkSpectrogram...", U"To FormantFilter...", praat_DEPTH_1, DO_Sound_to_BarkSpectrogram); praat_addAction1 (classSound, 0, U"To MelFilter...", U"To BarkFilter...", praat_HIDDEN + praat_DEPTH_1, DO_Sound_to_MelFilter); // deprecated 2014 praat_addAction1 (classSound, 0, U"To MelSpectrogram...", U"To BarkSpectrogram...", praat_DEPTH_1, DO_Sound_to_MelSpectrogram); praat_addAction1 (classSound, 0, U"To ComplexSpectrogram...", U"To MelSpectrogram...", praat_DEPTH_1 + praat_HIDDEN, DO_Sound_to_ComplexSpectrogram); praat_addAction1 (classSound, 0, U"To Polygon...", U"Down to Matrix", praat_DEPTH_1 | praat_HIDDEN, DO_Sound_to_Polygon); praat_addAction1 (classSound, 2, U"To Polygon (enclosed)...", U"Cross-correlate...", praat_DEPTH_1 | praat_HIDDEN, DO_Sounds_to_Polygon_enclosed); praat_addAction1 (classSound, 2, U"To DTW...", U"Cross-correlate...", praat_DEPTH_1, DO_Sounds_to_DTW); praat_addAction1 (classSound, 1, U"Filter (gammatone)...", U"Filter (de-emphasis)...", 1, DO_Sound_filterByGammaToneFilter4); praat_addAction1 (classSound, 0, U"Remove noise...", U"Filter (formula)...", 1, DO_Sound_removeNoise); praat_addAction1 (classSound, 0, U"Change gender...", U"Deepen band modulation...", 1, DO_Sound_changeGender); praat_addAction1 (classSound, 0, U"Change speaker...", U"Deepen band modulation...", praat_DEPTH_1 | praat_HIDDEN, DO_Sound_changeSpeaker); praat_addAction1 (classSound, 0, U"Copy channel ranges...", U"Extract all channels", praat_DEPTH_1 | praat_HIDDEN, DO_Sound_copyChannelRanges); praat_addAction1 (classSound, 0, U"Trim silences...", U"Resample...", praat_DEPTH_1 | praat_HIDDEN, DO_Sound_trimSilences); praat_addAction1 (classSound, 0, U"To KlattGrid (simple)...", U"To Manipulation...", 1, DO_Sound_to_KlattGrid_simple); praat_addAction2 (classSound, 1, classPitch, 1, U"To FormantFilter...", 0, praat_HIDDEN, DO_Sound_and_Pitch_to_FormantFilter); praat_addAction2 (classSound, 1, classPitch, 1, U"To Spectrogram (pitch-dependent)...", 0, 0, DO_Sound_and_Pitch_to_Spectrogram); praat_addAction2 (classSound, 1, classPitch, 1, U"Change gender...", 0, 0, DO_Sound_and_Pitch_changeGender); praat_addAction2 (classSound, 1, classPitch, 1, U"Change speaker...", 0, praat_HIDDEN, DO_Sound_and_Pitch_changeSpeaker); praat_addAction2 (classSound, 1, classIntervalTier, 1, U"Cut parts matching label...", 0, 0, DO_Sound_and_IntervalTier_cutPartsMatchingLabel); praat_addAction1 (classSpectrogram, 2, U"To DTW...", U"To Spectrum (slice)...", 0, DO_Spectrograms_to_DTW); praat_addAction1 (classSpectrum, 0, U"Draw phases...", U"Draw (log freq)...", praat_DEPTH_1 | praat_HIDDEN, DO_Spectrum_drawPhases); praat_addAction1 (classSpectrum, 0, U"Set real value in bin...", U"Formula...", praat_HIDDEN | praat_DEPTH_1, DO_Spectrum_setRealValueInBin); praat_addAction1 (classSpectrum, 0, U"Set imaginary value in bin...", U"Formula...", praat_HIDDEN | praat_DEPTH_1, DO_Spectrum_setImaginaryValueInBin); praat_addAction1 (classSpectrum, 0, U"Conjugate", U"Formula...", praat_HIDDEN | praat_DEPTH_1, DO_Spectrum_conjugate); praat_addAction1 (classSpectrum, 2, U"Multiply", U"To Sound (fft)", praat_HIDDEN, DO_Spectra_multiply); praat_addAction1 (classSpectrum, 0, U"To Matrix (unwrap)", U"To Matrix", praat_HIDDEN, DO_Spectrum_unwrap); praat_addAction1 (classSpectrum, 0, U"Shift frequencies...", U"To Matrix", praat_HIDDEN, DO_Spectrum_shiftFrequencies); praat_addAction1 (classSpectrum, 0, U"Compress frequency domain...", U"Shift frequencies...", praat_HIDDEN, DO_Spectrum_compressFrequencyDomain); praat_addAction1 (classSpectrum, 0, U"Resample...", U"Compress frequency domain...", praat_HIDDEN, DO_Spectrum_resample); praat_addAction1 (classSpectrum, 0, U"To Cepstrum", U"To Spectrogram", 1, DO_Spectrum_to_Cepstrum); praat_addAction1 (classSpectrum, 0, U"To PowerCepstrum", U"To Cepstrum", 1, DO_Spectrum_to_PowerCepstrum); praat_addAction1 (classSpeechSynthesizer, 0, U"SpeechSynthesizer help", 0, 0, DO_SpeechSynthesizer_help); praat_addAction1 (classSpeechSynthesizer, 0, U"Play text...", 0, 0, DO_SpeechSynthesizer_playText); praat_addAction1 (classSpeechSynthesizer, 0, U"To Sound...", 0, 0, DO_SpeechSynthesizer_to_Sound); praat_addAction1 (classSpeechSynthesizer, 0, QUERY_BUTTON, 0, 0, 0); praat_addAction1 (classSpeechSynthesizer, 1, U"Get voice name", 0, 1, DO_SpeechSynthesizer_getVoiceName); praat_addAction1 (classSpeechSynthesizer, 1, U"Get voice variant", 0, 1, DO_SpeechSynthesizer_getVoiceVariant); praat_addAction1 (classSpeechSynthesizer, 0, MODIFY_BUTTON, 0, 0, 0); praat_addAction1 (classSpeechSynthesizer, 0, U"Set text input settings...", 0, 1, DO_SpeechSynthesizer_setTextInputSettings); praat_addAction1 (classSpeechSynthesizer, 0, U"Set speech output settings...", 0, 1, DO_SpeechSynthesizer_setSpeechOutputSettings); praat_addAction2 (classSpeechSynthesizer, 1, classTextGrid, 1, U"To Sound...", 0, 0, DO_SpeechSynthesizer_and_TextGrid_to_Sound); praat_addAction3 (classSpeechSynthesizer, 1, classSound, 1, classTextGrid, 1, U"To TextGrid (align)...", 0, 0, DO_SpeechSynthesizer_and_Sound_and_TextGrid_align); praat_addAction3 (classSpeechSynthesizer, 1, classSound, 1, classTextGrid, 1, U"To TextGrid (align,trim)...", 0, 0, DO_SpeechSynthesizer_and_Sound_and_TextGrid_align2); praat_addAction1 (classSSCP, 0, U"SSCP help", 0, 0, DO_SSCP_help); praat_TableOfReal_init2 (classSSCP); praat_removeAction (classSSCP, nullptr, nullptr, U"Append"); praat_addAction1 (classSSCP, 0, U"Draw sigma ellipse...", DRAW_BUTTON, 1, DO_SSCP_drawSigmaEllipse); praat_addAction1 (classSSCP, 0, U"Draw confidence ellipse...", DRAW_BUTTON, 1, DO_SSCP_drawConfidenceEllipse); praat_SSCP_query_init (classSSCP); praat_addAction1 (classSSCP, 1, U"Get diagonality (bartlett)...", U"Get ln(determinant)", 1, DO_SSCP_testDiagonality_bartlett); praat_addAction1 (classSSCP, 1, U"Get total variance", U"Get diagonality (bartlett)...", 1, DO_SSCP_getTotalVariance); praat_addAction1 (classSSCP, 1, U"Get sigma ellipse area...", U"Get total variance", 1, DO_SSCP_getConcentrationEllipseArea); praat_addAction1 (classSSCP, 1, U"Get confidence ellipse area...", U"Get sigma ellipse area...", 1, DO_SSCP_getConfidenceEllipseArea); praat_addAction1 (classSSCP, 1, U"Get fraction variation...", U"Get confidence ellipse area...", 1, DO_SSCP_getFractionVariation); praat_SSCP_extract_init (classSSCP); praat_addAction1 (classSSCP, 0, U"To PCA", 0, 0, DO_SSCP_to_PCA); praat_addAction1 (classSSCP, 0, U"To Correlation", 0, 0, DO_SSCP_to_Correlation); praat_addAction1 (classSSCP, 0, U"To Covariance...", 0, 0, DO_SSCP_to_Covariance); praat_addAction1 (classStrings, 0, U"To Categories", 0, 0, DO_Strings_to_Categories); praat_addAction1 (classStrings, 0, U"Append", 0, 0, DO_Strings_append); praat_addAction1 (classStrings, 0, U"Change...", U"Replace all...", praat_HIDDEN, DO_Strings_change); praat_addAction1 (classStrings, 0, U"Extract part...", U"Replace all...", 0, DO_Strings_extractPart); praat_addAction1 (classStrings, 0, U"To Permutation...", U"To Distributions", 0, DO_Strings_to_Permutation); praat_addAction1 (classStrings, 2, U"To EditDistanceTable", U"To Distributions", 0, DO_Strings_to_EditDistanceTable); praat_addAction1 (classSVD, 0, U"To TableOfReal...", 0, 0, DO_SVD_to_TableOfReal); praat_addAction1 (classSVD, 0, U"Extract left singular vectors", 0, 0, DO_SVD_extractLeftSingularVectors); praat_addAction1 (classSVD, 0, U"Extract right singular vectors", 0, 0, DO_SVD_extractRightSingularVectors); praat_addAction1 (classSVD, 0, U"Extract singular values", 0, 0, DO_SVD_extractSingularValues); praat_addAction1 (classTable, 0, U"Draw ellipses...", U"Draw ellipse (standard deviation)...", praat_DEPTH_1, DO_Table_drawEllipses); praat_addAction1 (classTable, 0, U"Box plots...", U"Draw ellipses...", praat_DEPTH_1 | praat_HIDDEN, DO_Table_boxPlots); praat_addAction1 (classTable, 0, U"Normal probability plot...", U"Box plots...", praat_DEPTH_1 | praat_HIDDEN, DO_Table_normalProbabilityPlot); praat_addAction1 (classTable, 0, U"Quantile-quantile plot...", U"Normal probability plot...", praat_DEPTH_1 | praat_HIDDEN, DO_Table_quantileQuantilePlot); praat_addAction1 (classTable, 0, U"Quantile-quantile plot (between levels)...", U"Quantile-quantile plot...", praat_DEPTH_1 | praat_HIDDEN, DO_Table_quantileQuantilePlot_betweenLevels); praat_addAction1 (classTable, 0, U"Lag plot...", U"Quantile-quantile plot (between levels)...", praat_DEPTH_1 | praat_HIDDEN, DO_Table_lagPlot); praat_addAction1 (classTable, 0, U"Horizontal error bars plot...", U"Scatter plot (mark)...", praat_DEPTH_1, DO_Table_horizontalErrorBarsPlot); praat_addAction1 (classTable, 0, U"Vertical error bars plot...", U"Scatter plot (mark)...", praat_DEPTH_1, DO_Table_verticalErrorBarsPlot); praat_addAction1 (classTable, 0, U"Distribution plot...", U"Quantile-quantile plot...", praat_DEPTH_1 | praat_HIDDEN, DO_Table_distributionPlot); praat_addAction1 (classTable, 1, U"Draw where", U"Lag plot...", 1 , 0); praat_addAction1 (classTable, 0, U"Scatter plot where...", U"Draw where", 2, DO_Table_scatterPlotWhere); praat_addAction1 (classTable, 0, U"Scatter plot where (mark)...", U"Scatter plot where...", 2, DO_Table_scatterPlotMarkWhere); praat_addAction1 (classTable, 0, U"Horizontal error bars plot where...", U"Scatter plot where (mark)...", praat_DEPTH_2, DO_Table_horizontalErrorBarsPlotWhere); praat_addAction1 (classTable, 0, U"Vertical error bars plot where...", U"Scatter plot where (mark)...", praat_DEPTH_2, DO_Table_verticalErrorBarsPlotWhere); praat_addAction1 (classTable, 0, U"Distribution plot where...", U"Scatter plot where (mark)...", 2, DO_Table_distributionPlotWhere); praat_addAction1 (classTable, 0, U"Draw ellipse where (standard deviation)...", U"Distribution plot where...", 2, DO_Table_drawEllipseWhere); praat_addAction1 (classTable, 0, U"Box plots where...", U"Draw ellipse where (standard deviation)...", 2, DO_Table_boxPlotsWhere); praat_addAction1 (classTable, 0, U"Normal probability plot where...", U"Box plots where...", 2, DO_Table_normalProbabilityPlotWhere); praat_addAction1 (classTable, 0, U"Bar plot where...", U"Normal probability plot where...", 2, DO_Table_barPlotWhere); praat_addAction1 (classTable, 0, U"Line graph where...", U"Bar plot where...", 2, DO_Table_LineGraphWhere); praat_addAction1 (classTable, 0, U"Lag plot where...", U"Line graph where...", 2, DO_Table_lagPlotWhere); praat_addAction1 (classTable, 0, U"Draw ellipses where...", U"Lag plot where...", 2, DO_Table_drawEllipsesWhere); praat_addAction1 (classTable, 1, U"Get number of rows where...", U"Get number of rows", praat_DEPTH_1 | praat_HIDDEN, DO_Table_getNumberOfRowsWhere); praat_addAction1 (classTable, 1, U"Report one-way anova...", U"Report group difference (Wilcoxon rank sum)...", praat_DEPTH_1 | praat_HIDDEN, DO_Table_reportOneWayAnova); praat_addAction1 (classTable, 1, U"Report one-way Kruskal-Wallis...", U"Report one-way anova...", praat_DEPTH_1 | praat_HIDDEN, DO_Table_reportOneWayKruskalWallis); praat_addAction1 (classTable, 1, U"Report two-way anova...", U"Report one-way Kruskal-Wallis...", praat_DEPTH_1 | praat_HIDDEN, DO_Table_reportTwoWayAnova); praat_addAction1 (classTable, 0, U"Extract rows where...", U"Extract rows where column (text)...", praat_DEPTH_1, DO_Table_extractRowsWhere); praat_addAction1 (classTable, 0, U"Extract rows where (mahalanobis)...", U"Extract rows where...", praat_DEPTH_1| praat_HIDDEN, DO_Table_extractRowsMahalanobisWhere); praat_addAction1 (classTable, 0, U"-- Extract columns ----", U"Extract rows where (mahalanobis)...", praat_DEPTH_1| praat_HIDDEN, 0); praat_addAction1 (classTable, 0, U"Extract column ranges...", U"-- Extract columns ----", praat_DEPTH_1| praat_HIDDEN, DO_Table_extractColumnRanges); praat_addAction1 (classTable, 0, U"To KlattTable", 0, praat_HIDDEN, DO_Table_to_KlattTable); praat_addAction1 (classTable, 1, U"Get median absolute deviation...", U"Get standard deviation...", 1, DO_Table_getMedianAbsoluteDeviation); praat_addAction1 (classTable, 0, U"To StringsIndex (column)...", 0, praat_HIDDEN, DO_Table_to_StringsIndex_column); praat_addAction1 (classTableOfReal, 1, U"Report multivariate normality...", U"Get column stdev (label)...", praat_DEPTH_1 | praat_HIDDEN, DO_TableOfReal_reportMultivariateNormality); praat_addAction1 (classTableOfReal, 0, U"Append columns", U"Append", 1, DO_TableOfReal_appendColumns); praat_addAction1 (classTableOfReal, 0, U"Multivariate statistics -", 0, 0, 0); praat_addAction1 (classTableOfReal, 0, U"To Discriminant", 0, 1, DO_TableOfReal_to_Discriminant); praat_addAction1 (classTableOfReal, 0, U"To PCA", 0, 1, DO_TableOfReal_to_PCA); praat_addAction1 (classTableOfReal, 0, U"To SSCP...", 0, 1, DO_TableOfReal_to_SSCP); praat_addAction1 (classTableOfReal, 0, U"To Covariance", 0, 1, DO_TableOfReal_to_Covariance); praat_addAction1 (classTableOfReal, 0, U"To Correlation", 0, 1, DO_TableOfReal_to_Correlation); praat_addAction1 (classTableOfReal, 0, U"To Correlation (rank)", 0, 1, DO_TableOfReal_to_Correlation_rank); praat_addAction1 (classTableOfReal, 0, U"To CCA...", 0, 1, DO_TableOfReal_to_CCA); praat_addAction1 (classTableOfReal, 0, U"To TableOfReal (means by row labels)...", 0, 1, DO_TableOfReal_meansByRowLabels); praat_addAction1 (classTableOfReal, 0, U"To TableOfReal (medians by row labels)...", 0, 1, DO_TableOfReal_mediansByRowLabels); praat_addAction1 (classTableOfReal, 0, U"-- configurations --", 0, 1, 0); praat_addAction1 (classTableOfReal, 0, U"To Configuration (pca)...", 0, 1, DO_TableOfReal_to_Configuration_pca); praat_addAction1 (classTableOfReal, 0, U"To Configuration (lda)...", 0, 1, DO_TableOfReal_to_Configuration_lda); praat_addAction1 (classTableOfReal, 2, U"-- between tables --", U"To Configuration (lda)...", 1, 0); praat_addAction1 (classTableOfReal, 2, U"To TableOfReal (cross-correlations)...", 0, praat_HIDDEN + praat_DEPTH_1, DO_TableOfReal_and_TableOfReal_crossCorrelations); praat_addAction1 (classTableOfReal, 1, U"To Pattern and Categories...", U"To Matrix", 1, DO_TableOfReal_to_Pattern_and_Categories); praat_addAction1 (classTableOfReal, 1, U"Split into Pattern and Categories...", U"To Pattern and Categories...", praat_DEPTH_1 | praat_HIDDEN, DO_TableOfReal_to_Pattern_and_Categories); praat_addAction1 (classTableOfReal, 0, U"To Permutation (sort row labels)", U"To Matrix", 1, DO_TableOfReal_to_Permutation_sortRowlabels); praat_addAction1 (classTableOfReal, 1, U"To SVD", 0, praat_HIDDEN, DO_TableOfReal_to_SVD); praat_addAction1 (classTableOfReal, 2, U"To GSVD", 0, praat_HIDDEN, DO_TablesOfReal_to_GSVD); praat_addAction1 (classTableOfReal, 2, U"To Eigen (gsvd)", 0, praat_HIDDEN, DO_TablesOfReal_to_Eigen_gsvd); praat_addAction1 (classTableOfReal, 0, U"To TableOfReal (cholesky)...", 0, praat_HIDDEN, DO_TableOfReal_choleskyDecomposition); praat_addAction1 (classTableOfReal, 0, U"-- scatter plots --", U"Draw top and bottom lines...", 1, 0); praat_addAction1 (classTableOfReal, 0, U"Draw scatter plot...", U"-- scatter plots --", 1, DO_TableOfReal_drawScatterPlot); praat_addAction1 (classTableOfReal, 0, U"Draw scatter plot matrix...", U"Draw scatter plot...", 1, DO_TableOfReal_drawScatterPlotMatrix); praat_addAction1 (classTableOfReal, 0, U"Draw box plots...", U"Draw scatter plot matrix...", 1, DO_TableOfReal_drawBoxPlots); praat_addAction1 (classTableOfReal, 0, U"Draw biplot...", U"Draw box plots...", 1, DO_TableOfReal_drawBiplot); praat_addAction1 (classTableOfReal, 0, U"Draw vectors...", U"Draw box plots...", praat_DEPTH_1 | praat_HIDDEN, DO_TableOfReal_drawVectors); praat_addAction1 (classTableOfReal, 1, U"Draw row as histogram...", U"Draw biplot...", praat_DEPTH_1 | praat_HIDDEN, DO_TableOfReal_drawRowAsHistogram); praat_addAction1 (classTableOfReal, 1, U"Draw rows as histogram...", U"Draw row as histogram...", praat_DEPTH_1 | praat_HIDDEN, DO_TableOfReal_drawRowsAsHistogram); praat_addAction1 (classTableOfReal, 1, U"Draw column as distribution...", U"Draw rows as histogram...", praat_DEPTH_1, DO_TableOfReal_drawColumnAsDistribution); praat_addAction2 (classStrings, 1, classPermutation, 1, U"Permute strings", 0, 0, DO_Strings_and_Permutation_permuteStrings); praat_addAction2 (classTableOfReal, 1, classPermutation, 1, U"Permute rows", 0, 0, DO_TableOfReal_and_Permutation_permuteRows); praat_addAction1 (classTextGrid, 0, U"Extend time...", U"Scale times...", 2, DO_TextGrid_extendTime); praat_addAction1 (classTextGrid, 1, U"Set tier name...", U"Remove tier...", 1, DO_TextGrid_setTierName); praat_addAction1 (classTextGrid, 0, U"Replace interval text...", U"Set interval text...", 2, DO_TextGrid_replaceIntervalTexts); praat_addAction1 (classTextGrid, 0, U"Replace point text...", U"Set point text...", 2, DO_TextGrid_replacePointTexts); praat_addAction1 (classTextGrid, 2, U"To Table (text alignment)...", U"Extract part...", 0, DO_TextGrids_to_Table_textAlignmentment); praat_addAction2 (classTextGrid, 2, classEditCostsTable, 1, U"To Table (text alignment)...", 0, 0, DO_TextGrids_and_EditCostsTable_to_Table_textAlignmentment); INCLUDE_MANPAGES (manual_dwtools_init) INCLUDE_MANPAGES (manual_Permutation_init) INCLUDE_LIBRARY (praat_uvafon_MDS_init) INCLUDE_LIBRARY (praat_KlattGrid_init) INCLUDE_LIBRARY (praat_HMM_init) INCLUDE_LIBRARY (praat_BSS_init) } /* End of file praat_David.cpp */ praat-6.0.04/dwtools/praat_HMM_init.cpp000066400000000000000000001123761261542461700177640ustar00rootroot00000000000000/* praat_HMM_init.cpp * * Copyright (C) 2010-2011, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20101003 */ #include "praat.h" #include "GaussianMixture.h" #include "HMM.h" #include "Strings_extensions.h" #include "TableOfReal.h" #undef iam #define iam iam_LOOP //#undef praat_HIDDEN //#define praat_HIDDEN 0 #define GaussianMixture_OPTION_MENU_CRITERIA \ OPTIONMENU (U"Criterion based on", 1) \ OPTION (U"Likelihood") \ OPTION (U"Message length") \ OPTION (U"Bayes information") \ OPTION (U"Akaike information") \ OPTION (U"Akaike corrected") \ OPTION (U"Complete-data ML") Correlation GaussianMixture_and_TableOfReal_to_Correlation2 (GaussianMixture me, thou); DIRECT (GaussianMixture_help) Melder_help (U"GaussianMixture"); END FORM (GaussianMixture_drawConcentrationEllipses, U"GaussianMixture: Draw concentration ellipses", U"GaussianMixture: Draw concentration ellipses...") POSITIVE (U"Number of sigmas", U"1.0") BOOLEAN (U"Principal component plane", 1) INTEGER (U"X-dimension", U"1") INTEGER (U"Y-dimension", U"2") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") INTEGER (U"Label size", U"12") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (GaussianMixture); GaussianMixture_drawConcentrationEllipses (me, GRAPHICS, GET_REAL (U"Number of sigmas"), 0, 0, GET_INTEGER (U"Principal component plane"), GET_INTEGER (U"X-dimension"), GET_INTEGER (U"Y-dimension"), GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Label size"), GET_INTEGER (U"Garnish")); } END FORM (GaussianMixture_and_PCA_drawConcentrationEllipses, U"GaussianMixture & PCA: Draw concentration ellipses", U"GaussianMixture & PCA: Draw concentration ellipses...") POSITIVE (U"Number of sigmas", U"1.0") INTEGER (U"X-dimension", U"1") INTEGER (U"Y-dimension", U"2") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") INTEGER (U"Label size", U"12") BOOLEAN (U"Garnish", 1) OK DO GaussianMixture me = FIRST (GaussianMixture); PCA pca = FIRST (PCA); GaussianMixture_and_PCA_drawConcentrationEllipses (me, pca, GRAPHICS, GET_REAL (U"Number of sigmas"), 0, nullptr, GET_INTEGER (U"X-dimension"), GET_INTEGER (U"Y-dimension"), GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Label size"), GET_INTEGER (U"Garnish")); END FORM (GaussianMixture_drawMarginalPdf, U"GaussianMixture: Draw marginal pdf", U"GaussianMixture: Draw marginal pdf...") INTEGER (U"X-dimension", U"1") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") NATURAL (U"Number of points", U"500") INTEGER (U"Number of bins", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (GaussianMixture); GaussianMixture_drawMarginalPdf (me, GRAPHICS, GET_INTEGER (U"X-dimension"), GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Number of points"), GET_INTEGER (U"Number of bins"), GET_INTEGER (U"Garnish")); } END DIRECT (GaussianMixture_getNumberOfComponents) LOOP { iam (GaussianMixture); Melder_information (my numberOfComponents, U" (= number of components)"); } END DIRECT (GaussianMixture_getDimensionOfComponent) LOOP { iam (GaussianMixture); Melder_information (my dimension, U" (= dimension of component)"); } END FORM (GaussianMixture_getProbabilityAtPosition, U"GaussianMixture: Get probability at position", 0) SENTENCE (U"Position", U"100.0 300.0") OK DO const char32 *position = GET_STRING (U"Position"); LOOP { iam (GaussianMixture); double p = GaussianMixture_getProbabilityAtPosition_string (me, position); Melder_information (p, U" (= probability at position ", position); } END FORM (GaussianMixture_splitComponent, U"GaussianMixture: Split component", U"GaussianMixture: Split component...") NATURAL (U"Component", U"1") OK DO LOOP { iam (GaussianMixture); GaussianMixture_splitComponent (me, GET_INTEGER (U"Component")); } END FORM (GaussianMixture_and_PCA_drawMarginalPdf, U"GaussianMixture & PCA: Draw pdf function", U"GaussianMixture: Draw marginal pdf...") INTEGER (U"X-dimension", U"1") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") NATURAL (U"Number of points", U"500") INTEGER (U"Number of bins", U"0.0") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; GaussianMixture me = FIRST (GaussianMixture); PCA pca = FIRST (PCA); GaussianMixture_and_PCA_drawMarginalPdf (me, pca, GRAPHICS, GET_INTEGER (U"X-dimension"), GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Number of points"), GET_INTEGER (U"Number of bins"), GET_INTEGER (U"Garnish")); END FORM (GaussianMixture_and_PCA_to_Matrix_density, U"GaussianMixture & PCA: To Matrix density", U"GaussianMixture & PCA: To Matrix (density)...") INTEGER (U"X-dimension", U"1") INTEGER (U"Y-dimension", U"2") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") NATURAL (U"Number of columns", U"100") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") NATURAL (U"Number of rows", U"100") OK DO GaussianMixture me = FIRST (GaussianMixture); PCA pca = FIRST (PCA); autoMatrix thee = GaussianMixture_and_PCA_to_Matrix_density (me, pca, GET_INTEGER (U"X-dimension"), GET_INTEGER (U"Y-dimension"), GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_INTEGER (U"Number of columns"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Number of rows")); praat_new (thee.transfer(), my name, U"_", pca->name); END FORM (GaussianMixture_extractComponent, U"GaussianMixture: Extract component", 0) NATURAL (U"Component", U"1") OK DO long component = GET_INTEGER (U"Component"); LOOP { iam (GaussianMixture); autoCovariance thee = GaussianMixture_extractComponent (me, component); praat_new (thee.transfer(), my name, U"_", thy name); } END DIRECT (GaussianMixture_extractCentroids) LOOP { iam (GaussianMixture); autoTableOfReal thee = GaussianMixture_extractCentroids (me); praat_new (thee.transfer(), my name); } END DIRECT (GaussianMixture_extractMixingProbabilities) LOOP { iam (GaussianMixture); autoTableOfReal thee = GaussianMixture_extractMixingProbabilities (me); praat_new (thee.transfer(), my name); } END DIRECT (GaussianMixture_to_PCA) LOOP { iam (GaussianMixture); autoPCA thee = GaussianMixture_to_PCA (me); praat_new (thee.transfer(), my name); } END FORM (GaussianMixture_to_TableOfReal_randomSampling, U"GaussianMixture: To TableOfReal (random sampling)", U"GaussianMixture: To TableOfReal (random sampling)...") NATURAL (U"Number of data points", U"100") OK DO long numberOfpoints = GET_INTEGER (U"Number of data points"); LOOP { iam (GaussianMixture); autoTableOfReal thee = GaussianMixture_to_TableOfReal_randomSampling (me, numberOfpoints); praat_new (thee.transfer(), my name); } END DIRECT (GaussianMixture_to_Covariance_between) LOOP { iam (GaussianMixture); autoCovariance thee = GaussianMixture_to_Covariance_between (me); praat_new (thee.transfer(), my name, U"_b"); } END DIRECT (GaussianMixture_to_Covariance_within) LOOP { iam (GaussianMixture); autoCovariance thee = GaussianMixture_to_Covariance_within (me); praat_new (thee.transfer(), my name, U"_w"); } END DIRECT (GaussianMixture_to_Covariance_total) LOOP { iam (GaussianMixture); autoCovariance thee = GaussianMixture_to_Covariance_total (me); praat_new (thee.transfer(), my name, U"_t"); } END FORM (GaussianMixture_and_TableOfReal_getLikelihoodValue, U"GaussianMixture & TableOfReal: Get likelihood value", U"GaussianMixture & TableOfReal: Get likelihood value...") GaussianMixture_OPTION_MENU_CRITERIA OK DO GaussianMixture me = FIRST (GaussianMixture); TableOfReal thee = FIRST (TableOfReal); int criterion = GET_INTEGER (U"Criterion based on") - 1; const char32 *criterionText = GaussianMixture_criterionText (criterion); double lnpdn = GaussianMixture_and_TableOfReal_getLikelihoodValue (me, thee, criterion); Melder_information (lnpdn / thy numberOfRows, U" (= ", criterionText, U", n = ", thy numberOfRows, U")"); END DIRECT (HMM_help) Melder_help (U"HMM"); END FORM (HMM_create, U"Create HMM", U"") WORD (U"Name", U"hmm") BOOLEAN (U"Left to right model", 0) NATURAL (U"Number of states", U"3") NATURAL (U"Number of observations", U"3") OK DO autoHMM thee = HMM_create (GET_INTEGER (U"Left to right model"), GET_INTEGER (U"Number of states"), GET_INTEGER (U"Number of observations")); praat_new (thee.transfer(), GET_STRING (U"Name")); END FORM (HMM_createSimple, U"HMM: Create simple", U"HMM: Create simple HMM...") WORD (U"Name", U"weather") BOOLEAN (U"Left to right model", 0) SENTENCE (U"States", U"Rainy Sunny") SENTENCE (U"Observations", U"Walk Shop Clean") OK DO autoHMM thee = HMM_createSimple (GET_INTEGER (U"Left to right model"), GET_STRING (U"States"), GET_STRING (U"Observations")); praat_new (thee.transfer(), GET_STRING (U"Name")); END FORM (HMM_createContinuousModel, U"HMM: Create continuous model", 0) WORD (U"Name", U"cm") BOOLEAN (U"Left to right model", 0) NATURAL (U"Number of states", U"3") NATURAL (U"Number of symbols", U"10") LABEL (U"", U"For the Gaussian mixtures:") NATURAL (U"Number of components", U"3") NATURAL (U"Dimension of component", U"39") OPTIONMENU (U"Covariance matrices are", 1) OPTION (U"Complete") OPTION (U"Diagonal") OK DO long componentStorage = GET_INTEGER (U"Covariance matrices are") - 1; long dimension = GET_INTEGER (U"Dimension of component"); REQUIRE (componentStorage >= 0 && componentStorage <= dimension, U"Not a valid covariance matrix type") autoHMM thee = HMM_createContinuousModel (GET_INTEGER (U"Left to right model"), GET_INTEGER (U"Number of states"), GET_INTEGER (U"Number of symbols"), GET_INTEGER (U"Number of components"), dimension, componentStorage); praat_new (thee.transfer(), GET_STRING (U"Name")); END FORM (HMMObservationSequence_to_HMM, U"HMMObservationSequence: To HMM", 0) LABEL (U"", U"(0 states gives a non-hidden model) ") INTEGER (U"Number of states", U"2") BOOLEAN (U"Left to right model", 0) OK DO long numberOfStates = GET_INTEGER (U"Number of states"); LOOP { iam (HMMObservationSequence); autoHMM thee = HMM_createFromHMMObservationSequence (me, numberOfStates, GET_INTEGER (U"Left to right model")); praat_new (thee.transfer(), my name, U"_", numberOfStates); } END FORM (HMM_draw, U"HMM: Draw", 0) BOOLEAN (U"Garnish", 0) OK DO autoPraatPicture picture; LOOP { iam (HMM); HMM_draw (me, GRAPHICS, GET_INTEGER (U"Garnish")); } END FORM (HMM_and_HMMStateSequence_drawTrellis, U"HMM & Strings: Draw trellis", 0) BOOLEAN (U"Connect", 1); BOOLEAN (U"Garnish", 1); OK DO autoPraatPicture picture; HMM me = FIRST (HMM); HMMStateSequence hmm_ss = FIRST (HMMStateSequence); HMM_and_HMMStateSequence_drawTrellis (me, hmm_ss, GRAPHICS, GET_INTEGER (U"Connect"), GET_INTEGER (U"Garnish")); END DIRECT (HMM_drawForwardProbabilitiesIllustration) autoPraatPicture picture; HMM_drawForwardProbabilitiesIllustration (GRAPHICS, true); END DIRECT (HMM_drawBackwardProbabilitiesIllustration) autoPraatPicture picture; HMM_drawBackwardProbabilitiesIllustration (GRAPHICS, true); END DIRECT (HMM_drawForwardAndBackwardProbabilitiesIllustration) autoPraatPicture picture; HMM_drawForwardAndBackwardProbabilitiesIllustration (GRAPHICS, true); END FORM (HMM_getTransitionProbability, U"HMM: Get transition probability", U"HMM: Get transition probability...") NATURAL (U"From state number", U"1") NATURAL (U"To state number", U"1") OK DO LOOP { iam (HMM); long s1 = GET_INTEGER (U"From state number"), s2 = GET_INTEGER (U"To state number"); REQUIRE (s1 <= my numberOfStates && s2 <= my numberOfStates, U"State number(s) too high.") Melder_information (my transitionProbs[s1][s2], U" : [ ", s1, U", ", s2, U" ]"); } END FORM (HMM_getEmissionProbability, U"HMM: Get emission probability", U"HMM: Get emission probability...") NATURAL (U"From state number", U"1") NATURAL (U"To symbol number", U"1") OK DO LOOP { iam (HMM); long s1 = GET_INTEGER (U"From state number"), s2 = GET_INTEGER (U"To symbol number"); REQUIRE (s1 <= my numberOfStates, U"State number too high.") REQUIRE (s2 <= my numberOfObservationSymbols, U"Symbol number too high.") Melder_information (my emissionProbs[s1][s2], U" : [ ", s1, U", ", s2, U" ]"); } END FORM (HMM_getStartProbability, U"HMM: Get start probability", U"HMM: Get start probability...") NATURAL (U"State number", U"1") OK DO LOOP { iam (HMM); long s1 = GET_INTEGER (U"State number"); REQUIRE (s1 <= my numberOfStates, U"State number too high.") Melder_information (my transitionProbs[0][s1], U" : [ ", s1, U" ]"); } END FORM (HMM_getProbabilityAtTimeBeingInState, U"HMM: Get probability of being in state at time", U"HMM: Get p (time, state)...") NATURAL (U"Time index", U"10") NATURAL (U"State number", U"1") OK DO long istate = GET_INTEGER (U"State number"); long itime = GET_INTEGER (U"Time index"); LOOP { iam (HMM); double lnp = HMM_getProbabilityAtTimeBeingInState (me, itime, istate); Melder_information (lnp, U" (=ln(p), p = ", Melder_naturalLogarithm (lnp), U") Being in state ", istate, U" at time ", itime); } END FORM (HMM_getProbabilityAtTimeBeingInStateEmittingSymbol, U"HMM: get probability being at time in state emitting symbol", U"HMM: Get p (time, state, symbol)...") NATURAL (U"Time index", U"10") NATURAL (U"State number", U"1") NATURAL (U"Symbol number", U"1") OK DO long istate = GET_INTEGER (U"State number"); long itime = GET_INTEGER (U"Time index"); long isymbol = GET_INTEGER (U"Symbol number"); LOOP { iam (HMM); double lnp = HMM_getProbabilityAtTimeBeingInStateEmittingSymbol (me, itime, istate, isymbol); Melder_information (lnp, U" (=ln(p), p = ", Melder_naturalLogarithm (lnp), U") Being in state ", istate, U" emitting symbol ", isymbol, U" at time ", itime); } END FORM (HMM_getProbabilityOfStayingInState, U"HMM: Get probability of staying in state", U"HMM: Get probability staying in state...") NATURAL (U"State number", U"1") NATURAL (U"Number of times", U"2") OK DO LOOP { iam (HMM); Melder_informationReal (HMM_getProbabilityOfStayingInState (me, GET_INTEGER (U"State number"), GET_INTEGER (U"Number of times")), 0); } END FORM (HMM_getExpectedValueOfDurationInState, U"HMM: Get expected value of duration in state", U"HMM: Get expected duration in state...") NATURAL (U"State number", U"1") OK DO LOOP { iam (HMM); Melder_informationReal (HMM_getExpectedValueOfDurationInState (me, GET_INTEGER (U"State number")), U" time units"); } END FORM (HMM_getSymbolLabel, U"HMM: Get symbol label", 0) NATURAL (U"Symbol number", U"1") OK DO long is = GET_INTEGER (U"Symbol number"); LOOP { iam (HMM); REQUIRE (is <= my numberOfObservationSymbols, U"Symbol number too high.") HMMObservation s = (HMMObservation) my observationSymbols -> item[is]; Melder_information (s -> label); } END FORM (HMM_getStateLabel, U"HMM: Get state label", 0) NATURAL (U"State number", U"1") OK DO long is = GET_INTEGER (U"State number"); LOOP { iam (HMM); REQUIRE (is <= my numberOfStates, U"State number too high.") HMMState s = (HMMState) my states -> item[is]; Melder_information (s -> label); } END FORM (HMM_and_HMM_getCrossEntropy, U"HMM & HMM: Get cross-entropy...", U"HMM & HMM: Get cross-entropy...") NATURAL (U"Observation length", U"2000") BOOLEAN (U"Symmetric", 1) OK DO long n = GET_INTEGER (U"Observation length"); int sym = GET_INTEGER (U"Symmetric"); HMM m1 = 0, m2 = 0; LOOP { iam (HMM); (m1 ? m2 : m1) = me; } Melder_assert (m1 && m2); double ce = HMM_and_HMM_getCrossEntropy (m1, m2, n, sym); Melder_information (ce, U" (=", (sym ? U"symmetric " : U""), U" cross-entropy between models for observation length = ", n, U")"); END DIRECT (HMM_and_HMM_and_HMMObservationSequence_getCrossEntropy) HMM m1 = 0, m2 = 0; HMMObservationSequence hmm_os = 0; LOOP { if (CLASS == classHMMObservationSequence) { hmm_os = (HMMObservationSequence) OBJECT; } else { (m1 ? m2 : m1) = (HMM) OBJECT; } } Melder_assert (m1 && m2 && hmm_os); double ce = HMM_and_HMM_and_HMMObservationSequence_getCrossEntropy (m1, m2, hmm_os); Melder_information (ce, U" (=symmetric cross-entropy between models)"); END FORM (HMM_to_HMMObservationSequence, U"HMM: To HMMObservationSequence (generate observations)", U"HMM: To HMMObservationSequence...") INTEGER (U"Start state", U"0") NATURAL (U"Number of observations", U"20") OK DO LOOP { iam (HMM); autoHMMObservationSequence thee = HMM_to_HMMObservationSequence (me, GET_INTEGER (U"Start state"), GET_INTEGER (U"Number of observations")); praat_new (thee.transfer(), my name); } END DIRECT (HMM_and_HMMStateSequence_getProbability) HMM me = FIRST (HMM); HMMStateSequence hmm_ss = FIRST (HMMStateSequence); double lnp = HMM_and_HMMStateSequence_getProbability (me, hmm_ss); Melder_information (lnp, U" (=ln(p), p = ", Melder_naturalLogarithm (lnp), U")"); END DIRECT (HMM_and_HMMObservationSequence_getProbability) HMM me = FIRST (HMM); HMMObservationSequence hmm_os = FIRST (HMMObservationSequence); double lnp = HMM_and_HMMObservationSequence_getProbability (me, hmm_os); Melder_information (lnp, U" (=ln(p), p = ", Melder_naturalLogarithm (lnp), U")"); END DIRECT (HMM_and_HMMObservationSequence_getCrossEntropy) HMM me = FIRST (HMM); HMMObservationSequence hmm_os = FIRST (HMMObservationSequence); double ce = HMM_and_HMMObservationSequence_getCrossEntropy (me, hmm_os); Melder_information (ce, U" (= cross-entropy)"); END DIRECT (HMM_and_HMMObservationSequence_getPerplexity) HMM me = FIRST (HMM); HMMObservationSequence hmm_os = FIRST (HMMObservationSequence); double py = HMM_and_HMMObservationSequence_getPerplexity (me, hmm_os); Melder_information (py, U" (= perplexity)"); END DIRECT (HMM_and_HMMObservationSequence_to_HMMStateSequence) HMM me = FIRST (HMM); HMMObservationSequence thee = FIRST (HMMObservationSequence); autoHMMStateSequence him = HMM_and_HMMObservationSequence_to_HMMStateSequence (me, thee); praat_new (him.transfer(), my name, U"_", thy name, U"_states"); END FORM (HMM_and_HMMObservationSequence_learn, U"HMM & HMMObservationSequence: Learn", U"HMM & HMMObservationSequences: Learn...") POSITIVE (U"Relative precision in log(p)", U"0.001") REAL (U"Minimum probability", U"0.00000000001") BOOLEAN (U"Learning history in Info window", 0) OK DO double minProb = GET_REAL (U"Minimum probability"); REQUIRE (minProb >= 0 && minProb < 1, U"A probabilty must be >= 0 and < 1!") autoHMMObservationSequences hmm_oss = HMMObservationSequences_create (); HMM hmm = 0; Collection_dontOwnItems (hmm_oss.peek()); LOOP { iam (Daata); if (CLASS == classHMMObservationSequence) { Collection_addItem (hmm_oss.peek(), me); } else { hmm = (HMM) me; } } HMM_and_HMMObservationSequences_learn (hmm, hmm_oss.peek(), GET_REAL (U"Relative precision in log"), minProb, GET_INTEGER (U"Learning history in Info window")); END FORM (HMM_setTransitionProbabilities, U"HMM: Set transition probabilities", U"HMM: Set transition probabilities...") NATURAL (U"State number", U"1") SENTENCE (U"Probabilities", U"0.1 0.9") OK DO LOOP { iam (HMM); HMM_setTransitionProbabilities (me, GET_INTEGER (U"State number"), GET_STRING (U"Probabilities")); } END FORM (HMM_setEmissionProbabilities, U"HMM: Set emission probabilities", U"HMM: Set emission probabilities...") NATURAL (U"State number", U"1") SENTENCE (U"Probabilities", U"0.1 0.7 0.2") OK DO LOOP { iam (HMM); HMM_setEmissionProbabilities (me, GET_INTEGER (U"State number"), GET_STRING (U"Probabilities")); } END FORM (HMM_setStartProbabilities, U"HMM: Set start probabilities", U"HMM: Set start probabilities...") SENTENCE (U"Probabilities", U"0.1 0.9") OK DO LOOP { iam (HMM); HMM_setStartProbabilities (me, GET_STRING (U"Probabilities")); } END DIRECT (HMM_extractTransitionProbabilities) LOOP { iam (HMM); autoTableOfReal thee = HMM_extractTransitionProbabilities (me); praat_new (thee.transfer(), my name, U"_t"); } END DIRECT (HMM_extractEmissionProbabilities) LOOP { iam (HMM); autoTableOfReal thee = HMM_extractEmissionProbabilities (me); praat_new (thee.transfer(), my name, U"_e"); } END FORM (HMMObservationSequence_to_TableOfReal, U"HMMObservationSequence: To TableOfReal ", U"HMMObservationSequence: To TableOfReal (bigrams)...") BOOLEAN (U"As probabilities", 1) OK DO LOOP { iam (HMMObservationSequence); autoTableOfReal thee = HMMObservationSequence_to_TableOfReal_transitions (me, GET_INTEGER (U"As probabilities")); praat_new (thee.transfer(), my name); } END FORM (HMM_and_HMMObservationSequence_to_TableOfReal, U"HMM & HMMObservationSequence: To TableOfReal", U"HMM & HMMObservationSequence: To TableOfReal (bigrams)...") BOOLEAN (U"As probabilities", 1) OK DO HMM me = FIRST (HMM); HMMObservationSequence hmm_os = FIRST (HMMObservationSequence); autoTableOfReal thee = HMM_and_HMMObservationSequence_to_TableOfReal_transitions (me, hmm_os,GET_INTEGER (U"As probabilities")); praat_new (thee.transfer(), hmm_os -> name, U"_m"); END FORM (HMM_and_HMMStateSequence_to_TableOfReal, U"HMM & HMMStateSequence: To TableOfReal", 0) BOOLEAN (U"As probabilities", 1) OK DO HMM me = FIRST (HMM); HMMStateSequence hmm_ss = FIRST (HMMStateSequence); autoTableOfReal thee = HMM_and_HMMStateSequence_to_TableOfReal_transitions (me, hmm_ss, GET_INTEGER (U"As probabilities")); praat_new (thee.transfer(), Thing_getName (hmm_ss), U"_m"); END FORM (HMMStateSequence_to_TableOfReal, U"HMMStateSequence: To TableOfReal", 0) BOOLEAN (U"As probabilities", 1) OK DO LOOP { iam (HMMStateSequence); autoTableOfReal thee = Strings_to_TableOfReal_transitions (me, GET_INTEGER (U"As probabilities")); praat_new (thee.transfer(), my name); } END DIRECT (HMMObservationSequence_to_Strings) LOOP { iam (HMMObservationSequence); autoStrings thee = HMMObservationSequence_to_Strings (me); praat_new (thee.transfer(), my name); } END DIRECT (Strings_to_HMMObservationSequence) LOOP { iam (Strings); autoHMMObservationSequence thee = Strings_to_HMMObservationSequence (me); praat_new (thee.transfer(), my name); } END DIRECT (HMMStateSequence_to_Strings) LOOP { iam (HMMStateSequence); autoStrings thee = HMMStateSequence_to_Strings (me); praat_new (thee.transfer(), my name); } END FORM (TableOfReal_to_GaussianMixture_fromRowlabels, U"TableOfReal: To GaussianMixture from row labels", U"TableOfReal: To GaussianMixture (row labels)...") OPTIONMENU (U"Covariance matrices are", 1) OPTION (U"Complete") OPTION (U"Diagonal") OK DO long storage = GET_INTEGER (U"Covariance matrices are") - 1; LOOP { iam (TableOfReal); autoGaussianMixture thee = TableOfReal_to_GaussianMixture_fromRowLabels (me, storage); praat_new (thee.transfer(), my name); } END FORM (TableOfReal_to_GaussianMixture, U"TableOfReal: To GaussianMixture (no labels)", U"TableOfReal: To GaussianMixture...") NATURAL (U"Number of components", U"2") POSITIVE (U"Tolerance of minimizer", U"0.001") INTEGER (U"Maximum number of iterations", U"200") REAL (U"Stability coefficient lambda", U"0.001") OPTIONMENU (U"Covariance matrices are", 1) OPTION (U"Complete") OPTION (U"Diagonal") GaussianMixture_OPTION_MENU_CRITERIA OK DO int criterion = GET_INTEGER (U"Criterion based on") - 1; double lambda = GET_REAL (U"Stability coefficient lambda"); REQUIRE (lambda >= 0 && lambda < 1, U"Lambda must be in interval [0,1).") long storage = GET_INTEGER (U"Covariance matrices are") - 1; LOOP { iam (TableOfReal); autoGaussianMixture thee = TableOfReal_to_GaussianMixture (me, GET_INTEGER (U"Number of components"), GET_REAL (U"Tolerance of minimizer"), GET_INTEGER (U"Maximum number of iterations"), lambda, storage, criterion); praat_new (thee.transfer(), my name); } END FORM (GaussianMixture_and_TableOfReal_improveLikelihood, U"GaussianMixture & TableOfReal: Improve likelihood", U"GaussianMixture & TableOfReal: Improve likelihood...") POSITIVE (U"Tolerance of minimizer", U"0.001") NATURAL (U"Maximum number of iterations", U"200") REAL (U"Stability coefficient lambda", U"0.001") GaussianMixture_OPTION_MENU_CRITERIA OK DO long criterion = GET_INTEGER (U"Criterion based on") - 1; double lambda = GET_REAL (U"Stability coefficient lambda"); GaussianMixture me = FIRST (GaussianMixture); TableOfReal thee = FIRST (TableOfReal); REQUIRE (lambda >= 0 && lambda < 1, U"Lambda must be in interval [0,1).") REQUIRE (thy numberOfColumns == my dimension, U"The number of columns and the dimension of the model do not agree."); REQUIRE (my numberOfComponents < thy numberOfRows / 2, U"Not enough data points.") GaussianMixture_and_TableOfReal_improveLikelihood (me, thee, GET_REAL (U"Tolerance of minimizer"), GET_INTEGER (U"Maximum number of iterations"), lambda, criterion); END FORM (GaussianMixture_and_TableOfReal_to_GaussianMixture_CEMM, U"GaussianMixture & TableOfReal: To GaussianMixture (CEMM)", U"GaussianMixture & TableOfReal: To GaussianMixture (CEMM)...") INTEGER (U"Minimum number of components", U"1") POSITIVE (U"Tolerance of minimizer", U"0.001") NATURAL (U"Maximum number of iterations", U"200") REAL (U"Stability coefficient lambda", U"0.001") GaussianMixture_OPTION_MENU_CRITERIA OK DO double lambda = GET_REAL (U"Stability coefficient lambda"); int criterion = GET_INTEGER (U"Criterion based on") - 1; GaussianMixture me = FIRST (GaussianMixture); TableOfReal thee = FIRST (TableOfReal); REQUIRE (lambda >= 0 && lambda < 1, U"Lambda must be in interval [0,1).") REQUIRE (thy numberOfColumns == my dimension, U"The number of columns and the dimension of the model do not agree."); REQUIRE (my numberOfComponents < thy numberOfRows / 2, U"Not enough data points.") autoGaussianMixture him = GaussianMixture_and_TableOfReal_to_GaussianMixture_CEMM (me, thee, GET_INTEGER (U"Minimum number of components"), GET_REAL (U"Tolerance of minimizer"), GET_INTEGER (U"Maximum number of iterations"), lambda, criterion); praat_new (him.transfer(), my name); END DIRECT (GaussianMixture_and_TableOfReal_to_ClassificationTable) GaussianMixture me = FIRST (GaussianMixture); TableOfReal thee = FIRST (TableOfReal); autoClassificationTable him = GaussianMixture_and_TableOfReal_to_ClassificationTable (me, thee); praat_new (him.transfer(), my name, U"_", thy name); END DIRECT (GaussianMixture_and_TableOfReal_to_Correlation) GaussianMixture me = FIRST (GaussianMixture); TableOfReal thee = FIRST (TableOfReal); autoCorrelation him = GaussianMixture_and_TableOfReal_to_Correlation (me, thee); praat_new (him.transfer(), my name, U"_", thy name); END FORM (GaussianMixture_and_TableOfReal_to_TableOfReal_BHEPNormalityTests, U"GaussianMixture & TableOfReal: To TableOfReal BHEP normality tests", U"GaussianMixture & TableOfReal: To TableOfReal (BHEP normality tests)...") REAL (U"Smoothing parameter", U"1.41") OK DO GaussianMixture me = FIRST (GaussianMixture); TableOfReal thee = FIRST (TableOfReal); double h = GET_REAL (U"Smoothing parameter"); autoTableOfReal him = GaussianMixture_and_TableOfReal_to_TableOfReal_BHEPNormalityTests (me, thee, h); praat_new (him.transfer(), my name, U"_", thy name); END void praat_HMM_init (); void praat_HMM_init () { Thing_recognizeClassesByName (classHMM, classHMMState, classHMMObservation, classHMMObservationSequence, classHMMStateSequence, classGaussianMixture, nullptr); praat_addMenuCommand (U"Objects", U"New", U"Markov models", 0, praat_HIDDEN, 0); praat_addMenuCommand (U"Objects", U"New", U"Create HMM...", 0, praat_HIDDEN + praat_DEPTH_1, DO_HMM_create); praat_addMenuCommand (U"Objects", U"New", U"Create simple HMM...", 0, praat_HIDDEN + praat_DEPTH_1, DO_HMM_createSimple); praat_addMenuCommand (U"Objects", U"New", U"Create continuous HMM...", 0, praat_HIDDEN + praat_DEPTH_1, DO_HMM_createContinuousModel); praat_addMenuCommand (U"Objects", U"New", U"--drawings--", 0, praat_HIDDEN + praat_DEPTH_1, 0); praat_addMenuCommand (U"Objects", U"New", U"Draw forward probabilities illustration", 0, praat_HIDDEN + praat_DEPTH_1, DO_HMM_drawForwardProbabilitiesIllustration); praat_addMenuCommand (U"Objects", U"New", U"Draw backward probabilities illustration", 0, praat_HIDDEN + praat_DEPTH_1, DO_HMM_drawBackwardProbabilitiesIllustration); praat_addMenuCommand (U"Objects", U"New", U"Draw forward and backward probabilities illustration", 0, praat_HIDDEN + praat_DEPTH_1, DO_HMM_drawForwardAndBackwardProbabilitiesIllustration); praat_addAction1 (classGaussianMixture, 0, U"GaussianMixture help", 0, 0, DO_GaussianMixture_help); praat_addAction1 (classGaussianMixture, 0, U"Draw concentration ellipses...", 0, 0, DO_GaussianMixture_drawConcentrationEllipses); praat_addAction1 (classGaussianMixture, 0, U"Draw marginal pdf...", 0, 0, DO_GaussianMixture_drawMarginalPdf); praat_addAction1 (classGaussianMixture, 0, U"Query -", 0, 0, 0); praat_addAction1 (classGaussianMixture, 1, U"Get number of components", 0, 1, DO_GaussianMixture_getNumberOfComponents); praat_addAction1 (classGaussianMixture, 1, U"Get dimension of component", 0, 1, DO_GaussianMixture_getDimensionOfComponent); praat_addAction1 (classGaussianMixture, 1, U"Get probability at position...", 0, 1, DO_GaussianMixture_getProbabilityAtPosition); praat_addAction1 (classGaussianMixture, 0, U"Modify -", 0, 0, 0); praat_addAction1 (classGaussianMixture, 1, U"Split component...", 0, 1, DO_GaussianMixture_splitComponent); praat_addAction1 (classGaussianMixture, 0, U"Extract -", 0, 0, 0); praat_addAction1 (classGaussianMixture, 0, U"Extract mixing probabilities", 0, 1, DO_GaussianMixture_extractMixingProbabilities); praat_addAction1 (classGaussianMixture, 0, U"Extract component...", 0, 1, DO_GaussianMixture_extractComponent); praat_addAction1 (classGaussianMixture, 0, U"Extract centroids", 0, 1, DO_GaussianMixture_extractCentroids); praat_addAction1 (classGaussianMixture, 0, U"To Covariance (between)", 0, 0, DO_GaussianMixture_to_Covariance_between); praat_addAction1 (classGaussianMixture, 0, U"To Covariance (within)", 0, 0, DO_GaussianMixture_to_Covariance_within); praat_addAction1 (classGaussianMixture, 0, U"To Covariance (total)", 0, 0, DO_GaussianMixture_to_Covariance_total); praat_addAction1 (classGaussianMixture, 0, U"To PCA", 0, 0, DO_GaussianMixture_to_PCA); praat_addAction1 (classGaussianMixture, 0, U"To TableOfReal (random sampling)...", 0, 0, DO_GaussianMixture_to_TableOfReal_randomSampling); praat_addAction2 (classGaussianMixture, 1, classTableOfReal, 1, U"Get likelihood value...", 0, 0, DO_GaussianMixture_and_TableOfReal_getLikelihoodValue); praat_addAction2 (classGaussianMixture, 1, classTableOfReal, 1, U"Improve likelihood...", 0, 0, DO_GaussianMixture_and_TableOfReal_improveLikelihood); praat_addAction2 (classGaussianMixture, 1, classTableOfReal, 1, U"To GaussianMixture (CEMM)...", 0, 0, DO_GaussianMixture_and_TableOfReal_to_GaussianMixture_CEMM); praat_addAction2 (classGaussianMixture, 1, classTableOfReal, 1, U"To ClassificationTable", 0, 0, DO_GaussianMixture_and_TableOfReal_to_ClassificationTable); praat_addAction2 (classGaussianMixture, 1, classTableOfReal, 1, U"To Correlation", 0, 0, DO_GaussianMixture_and_TableOfReal_to_Correlation); praat_addAction2 (classGaussianMixture, 1, classTableOfReal, 1, U"To TableOfReal (BHEP normality tests)...", 0, 0, DO_GaussianMixture_and_TableOfReal_to_TableOfReal_BHEPNormalityTests); praat_addAction2 (classGaussianMixture, 1, classPCA, 1, U"Draw concentration ellipses...", 0, 0, DO_GaussianMixture_and_PCA_drawConcentrationEllipses); praat_addAction2 (classGaussianMixture, 1, classPCA, 1, U"Draw marginal pdf...", 0, 0, DO_GaussianMixture_and_PCA_drawMarginalPdf); praat_addAction2 (classGaussianMixture, 1, classPCA, 1, U"To Matrix (density)...", 0, 0, DO_GaussianMixture_and_PCA_to_Matrix_density); praat_addAction1 (classHMM, 0, U"HMM help ", 0, 0, DO_HMM_help); praat_addAction1 (classHMM, 0, U"Draw...", 0, 0, DO_HMM_draw); praat_addAction1 (classHMM, 0, U"Query -", 0, 0, 0); praat_addAction1 (classHMM, 1, U"Get transition probability...", 0, 1, DO_HMM_getTransitionProbability); praat_addAction1 (classHMM, 1, U"Get emission probability...", 0, 1, DO_HMM_getEmissionProbability); praat_addAction1 (classHMM, 1, U"Get start probability...", 0, 1, DO_HMM_getStartProbability); praat_addAction1 (classHMM, 1, U"Get p (time, state)...", 0, 1, DO_HMM_getProbabilityAtTimeBeingInState); praat_addAction1 (classHMM, 1, U"Get p (time, state, symbol)...", 0, 1, DO_HMM_getProbabilityAtTimeBeingInStateEmittingSymbol); praat_addAction1 (classHMM, 1, U"Get probability staying in state...", 0, 1, DO_HMM_getProbabilityOfStayingInState); praat_addAction1 (classHMM, 1, U"Get expected duration in state...", 0, 1, DO_HMM_getExpectedValueOfDurationInState); praat_addAction1 (classHMM, 1, U"---- states / symbols -----", 0, 1, 0); praat_addAction1 (classHMM, 1, U"Get state label...", 0, 1, DO_HMM_getStateLabel); praat_addAction1 (classHMM, 1, U"Get symbol label...", 0, 1, DO_HMM_getSymbolLabel); praat_addAction1 (classHMM, 0, U"--- multiple HMMs ----", 0, 1, 0); praat_addAction1 (classHMM, 2, U"Get cross-entropy...", 0, 1, DO_HMM_and_HMM_getCrossEntropy); praat_addAction1 (classHMM, 0, U"Modify -", 0, 0, 0); praat_addAction1 (classHMM, 1, U"Set transition probabilities...", 0, 1, DO_HMM_setTransitionProbabilities); praat_addAction1 (classHMM, 1, U"Set emission probabilities...", 0, 1, DO_HMM_setEmissionProbabilities); praat_addAction1 (classHMM, 1, U"Set start probabilities...", 0, 1, DO_HMM_setStartProbabilities); praat_addAction1 (classHMM, 0, U"Extract -", 0, 0, 0); praat_addAction1 (classHMM, 0, U"Extract transition probabilities", 0, 1, DO_HMM_extractTransitionProbabilities); praat_addAction1 (classHMM, 0, U"Extract emission probabilities", 0, 1, DO_HMM_extractEmissionProbabilities); praat_addAction1 (classHMM, 0, U"To HMMObservationSequence...", 0, 0, DO_HMM_to_HMMObservationSequence); praat_addAction2 (classHMM, 1, classHMMStateSequence, 1, U"Draw trellis...", 0, 0, DO_HMM_and_HMMStateSequence_drawTrellis); praat_addAction2 (classHMM, 1, classHMMStateSequence, 1, U"Get probability", 0, 0, DO_HMM_and_HMMStateSequence_getProbability); praat_addAction2 (classHMM, 1, classHMMStateSequence, 1, U"To TableOfReal (bigrams)...", 0, 0, DO_HMM_and_HMMStateSequence_to_TableOfReal); praat_addAction2 (classHMM, 1, classHMMObservationSequence, 1, U"Get probability", 0, 0, DO_HMM_and_HMMObservationSequence_getProbability); praat_addAction2 (classHMM, 1, classHMMObservationSequence, 1, U"Get cross-entropy", 0, 0, DO_HMM_and_HMMObservationSequence_getCrossEntropy); praat_addAction2 (classHMM, 1, classHMMObservationSequence, 1, U"Get perplexity", 0, 0, DO_HMM_and_HMMObservationSequence_getPerplexity); praat_addAction2 (classHMM, 1, classHMMObservationSequence, 1, U"To HMMStateSequence", 0, 0, DO_HMM_and_HMMObservationSequence_to_HMMStateSequence); praat_addAction2 (classHMM, 2, classHMMObservationSequence, 1, U"Get cross-entropy", 0, 0, DO_HMM_and_HMM_and_HMMObservationSequence_getCrossEntropy); praat_addAction2 (classHMM, 1, classHMMObservationSequence, 1, U"To TableOfReal (bigrams)...", 0, 0, DO_HMM_and_HMMObservationSequence_to_TableOfReal); praat_addAction2 (classHMM, 1, classHMMObservationSequence, 0, U"Learn...", 0, 0, DO_HMM_and_HMMObservationSequence_learn); praat_addAction1 (classHMMObservationSequence, 0, U"To TableOfReal (bigrams)...", 0, 0, DO_HMMObservationSequence_to_TableOfReal); praat_addAction1 (classHMMObservationSequence, 0, U"To Strings", 0, 0, DO_HMMObservationSequence_to_Strings); praat_addAction1 (classHMMStateSequence, 0, U"To TableOfReal (bigrams)...", 0, 0, DO_HMMStateSequence_to_TableOfReal); praat_addAction1 (classHMMStateSequence, 0, U"To Strings", 0, 0, DO_HMMStateSequence_to_Strings); praat_addAction1 (classHMMObservationSequence, 0, U"To HMM...", 0, 1, DO_HMMObservationSequence_to_HMM); praat_addAction1 (classStrings, 0, U"To HMMObservationSequence", 0, praat_HIDDEN, DO_Strings_to_HMMObservationSequence); praat_addAction1 (classTableOfReal, 0, U"To GaussianMixture (row labels)...", U"To Covariance", praat_HIDDEN + praat_DEPTH_1, DO_TableOfReal_to_GaussianMixture_fromRowlabels); praat_addAction1 (classTableOfReal, 0, U"To GaussianMixture...", U"To Covariance", praat_HIDDEN + praat_DEPTH_1, DO_TableOfReal_to_GaussianMixture); INCLUDE_MANPAGES (manual_HMM) } /* End of file praat_HMM_init.cpp */ praat-6.0.04/dwtools/praat_KlattGrid_init.cpp000066400000000000000000002027151261542461700212250ustar00rootroot00000000000000/* praat_KlattGrid_init.cpp * * Copyright (C) 2009-2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20090420 */ #include "praat.h" #include "IntensityTierEditor.h" #include "KlattGridEditors.h" #include "KlattTable.h" #undef iam #define iam iam_LOOP /******************* KlattGrid *********************************/ static const char32 *formant_names[] = { U"", U"oral ", U"nasal ", U"frication ", U"tracheal ", U"nasal anti", U"tracheal anti", U"delta "}; static void KlattGrid_4formants_addCommonField (UiForm dia) { Any radio; OPTIONMENU (U"Formant type", 1) OPTION (U"Normal formant") OPTION (U"Nasal formant") OPTION (U"Frication formant") OPTION (U"Tracheal formant") } static void KlattGrid_6formants_addCommonField (UiForm dia) { Any radio; OPTIONMENU (U"Formant type", 1) OPTION (U"Normal formant") OPTION (U"Nasal formant") OPTION (U"Frication formant") OPTION (U"Tracheal formant") OPTION (U"Nasal antiformant") OPTION (U"Tracheal antiformant") // OPTION (U"Delta formant") } static void KlattGrid_7formants_addCommonField (UiForm dia) { Any radio; OPTIONMENU (U"Formant type", 1) OPTION (U"Normal formant") OPTION (U"Nasal formant") OPTION (U"Frication formant") OPTION (U"Tracheal formant") OPTION (U"Nasal antiformant") OPTION (U"Tracheal antiformant") OPTION (U"Delta formant") } static void KlattGrid_PhonationGridPlayOptions_addCommonFields (UiForm dia) { Any radio; //LABEL (U"", U"Phonation options") BOOLEAN (U"Voicing", 1) BOOLEAN (U"Flutter", 1) BOOLEAN (U"Double pulsing", 1) BOOLEAN (U"Collision phase", 1) BOOLEAN (U"Spectral tilt", 1) OPTIONMENU (U"Flow function", 1) OPTION (U"Powers in tiers") OPTION (U"t^2-t^3") OPTION (U"t^3-t^4") BOOLEAN (U"Flow derivative", 1) BOOLEAN (U"Aspiration", 1) BOOLEAN (U"Breathiness", 1) } static void KlattGrid_PhonationGridPlayOptions_getCommonFields (UiForm dia, KlattGrid thee) { PhonationGridPlayOptions pp = thy phonation -> options.get(); pp -> voicing = GET_INTEGER (U"Voicing"); pp -> flutter = GET_INTEGER (U"Flutter"); pp -> doublePulsing = GET_INTEGER (U"Double pulsing"); pp -> collisionPhase = GET_INTEGER (U"Collision phase"); pp -> spectralTilt = GET_INTEGER (U"Spectral tilt"); pp -> flowFunction = GET_INTEGER (U"Flow function"); pp -> flowDerivative = GET_INTEGER (U"Flow derivative"); pp -> aspiration = GET_INTEGER (U"Aspiration"); pp -> breathiness = GET_INTEGER (U"Breathiness"); } static void KlattGrid_PlayOptions_addCommonFields (UiForm dia, int sound) { Any radio; //LABEL (U"", U"Time domain") REAL (U"left Time range (s)", U"0") REAL (U"right Time range (s)", U"0") if (sound) POSITIVE (U"Sampling frequency (Hz)", U"44100") BOOLEAN (U"Scale peak", 1) KlattGrid_PhonationGridPlayOptions_addCommonFields (dia); OPTIONMENU (U"Filter options", 1) OPTION (U"Cascade") OPTION (U"Parallel") INTEGER (U"left Oral formant range", U"1") INTEGER (U"right Oral formant range", U"5") INTEGER (U"left Nasal formant range", U"1") INTEGER (U"right Nasal formant range", U"1") INTEGER (U"left Nasal antiformant range", U"1") INTEGER (U"right Nasal antiformant range", U"1") //LABEL (U"", U"Coupling options") INTEGER (U"left Tracheal formant range", U"1") INTEGER (U"right Tracheal formant range", U"1") INTEGER (U"left Tracheal antiformant range", U"1") INTEGER (U"right Tracheal antiformant range", U"1") INTEGER (U"left Delta formant range", U"1") INTEGER (U"right Delta formant range", U"1") INTEGER (U"left Delta bandwidth range", U"1") INTEGER (U"right Delta bandwidth range", U"1") //LABEL (U"", U"Frication options") INTEGER (U"left Frication formant range", U"1") INTEGER (U"right Frication formant range", U"6") BOOLEAN (U"Frication bypass", 1) } static void KlattGrid_PlayOptions_getCommonFields (UiForm dia, int sound, KlattGrid thee) { KlattGrid_setDefaultPlayOptions (thee); KlattGridPlayOptions pk = thy options.get(); pk -> scalePeak = GET_INTEGER (U"Scale peak"); pk -> xmin = GET_REAL (U"left Time range"); pk -> xmax = GET_REAL (U"right Time range"); if (sound) { pk -> samplingFrequency = GET_REAL (U"Sampling frequency"); } pk -> scalePeak = GET_INTEGER (U"Scale peak"); KlattGrid_PhonationGridPlayOptions_getCommonFields (dia, thee); VocalTractGridPlayOptions pv = thy vocalTract -> options.get(); pv -> filterModel = GET_INTEGER (U"Filter options") == 1 ? KlattGrid_FILTER_CASCADE : KlattGrid_FILTER_PARALLEL; pv -> startOralFormant = GET_INTEGER (U"left Oral formant range"); pv -> endOralFormant = GET_INTEGER (U"right Oral formant range"); pv -> startNasalFormant = GET_INTEGER (U"left Nasal formant range"); pv -> endNasalFormant = GET_INTEGER (U"right Nasal formant range"); pv -> startNasalAntiFormant = GET_INTEGER (U"left Nasal antiformant range"); pv -> endNasalAntiFormant = GET_INTEGER (U"right Nasal antiformant range"); CouplingGridPlayOptions pc = thy coupling -> options.get(); pc -> startTrachealFormant = GET_INTEGER (U"left Tracheal formant range"); pc -> endTrachealFormant = GET_INTEGER (U"right Tracheal formant range"); pc -> startTrachealAntiFormant = GET_INTEGER (U"left Tracheal antiformant range"); pc -> endTrachealAntiFormant = GET_INTEGER (U"right Tracheal antiformant range"); pc -> startDeltaFormant = GET_INTEGER (U"left Delta formant range"); pc -> endDeltaFormant = GET_INTEGER (U"right Delta formant range"); pc -> startDeltaBandwidth = GET_INTEGER (U"left Delta bandwidth range"); pc -> endDeltaFormant = GET_INTEGER (U"right Delta bandwidth range"); FricationGridPlayOptions pf = thy frication -> options.get(); pf -> startFricationFormant = GET_INTEGER (U"left Frication formant range"); pf -> endFricationFormant = GET_INTEGER (U"right Frication formant range"); pf -> bypass = GET_INTEGER (U"Frication bypass"); } DIRECT (KlattGrid_createExample) praat_new (KlattGrid_createExample().transfer(), U"example"); END FORM (KlattGrid_create, U"Create KlattGrid", U"Create KlattGrid...") WORD (U"Name", U"kg") REAL (U"Start time (s)", U"0.0") REAL (U"End time (s)", U"1.0") INTEGER (U"Number of oral formants", U"6") INTEGER (U"Number of nasal formants", U"1") INTEGER (U"Number of nasal antiformants", U"1") INTEGER (U"Number of frication formants", U"6") LABEL (U"", U"Coupling between source and filter") INTEGER (U"Number of tracheal formants", U"1") INTEGER (U"Number of tracheal antiformants", U"1") INTEGER (U"Number of delta formants", U"1") OK DO double tmin = GET_REAL (U"Start time"); double tmax = GET_REAL (U"End time"); REQUIRE (tmin < tmax, U"The start time must lie before the end time.") long numberOfOralFormants = GET_INTEGER (U"Number of oral formants"); long numberOfNasalFormants = GET_INTEGER (U"Number of nasal formants"); long numberOfNasalAntiFormants = GET_INTEGER (U"Number of nasal antiformants"); long numberOfTrachealFormants = GET_INTEGER (U"Number of tracheal formants"); long numberOfTrachealAntiFormants = GET_INTEGER (U"Number of tracheal antiformants"); long numberOfFricationFormants = GET_INTEGER (U"Number of frication formants"); long numberOfDeltaFormants = GET_INTEGER (U"Number of delta formants"); REQUIRE (numberOfOralFormants >= 0 && numberOfNasalFormants >= 0 && numberOfNasalAntiFormants >= 0 && numberOfTrachealFormants >= 0 && numberOfTrachealAntiFormants >= 0 && numberOfFricationFormants >= 0 && numberOfDeltaFormants >= 0, U"The number of (..) formants cannot be negative!") praat_new (KlattGrid_create (tmin, tmax, numberOfOralFormants, numberOfNasalFormants, numberOfNasalAntiFormants, numberOfTrachealFormants, numberOfTrachealAntiFormants, numberOfFricationFormants, numberOfDeltaFormants).transfer(), GET_STRING (U"Name")); END #define KlattGrid_INSTALL_TIER_EDITOR(Name) \ DIRECT (KlattGrid_edit##Name##Tier) \ if (theCurrentPraatApplication -> batch) { Melder_throw (U"Cannot edit a KlattGrid from batch."); } \ LOOP {\ iam (KlattGrid); \ auto##KlattGrid_##Name##TierEditor editor = KlattGrid_##Name##TierEditor_create (ID_AND_FULL_NAME, me); \ praat_installEditor (editor.transfer(), IOBJECT); \ }\ END KlattGrid_INSTALL_TIER_EDITOR (Pitch) KlattGrid_INSTALL_TIER_EDITOR (VoicingAmplitude) KlattGrid_INSTALL_TIER_EDITOR (Flutter) KlattGrid_INSTALL_TIER_EDITOR (Power1) KlattGrid_INSTALL_TIER_EDITOR (Power2) KlattGrid_INSTALL_TIER_EDITOR (OpenPhase) KlattGrid_INSTALL_TIER_EDITOR (CollisionPhase) KlattGrid_INSTALL_TIER_EDITOR (DoublePulsing) KlattGrid_INSTALL_TIER_EDITOR (AspirationAmplitude) KlattGrid_INSTALL_TIER_EDITOR (BreathinessAmplitude) KlattGrid_INSTALL_TIER_EDITOR (SpectralTilt) KlattGrid_INSTALL_TIER_EDITOR (FricationBypass) KlattGrid_INSTALL_TIER_EDITOR (FricationAmplitude) #undef KlattGrid_INSTALL_TIER_EDITOR #define KlattGRID_EDIT_FORMANTGRID(Name,formantType) \ DIRECT (KlattGrid_edit##Name##FormantGrid) \ if (theCurrentPraatApplication -> batch) { Melder_throw (U"Cannot edit a KlattGrid from batch."); } \ LOOP {\ iam (KlattGrid); \ const char32 *id_and_name = Melder_cat (ID, U". ", formant_names[formantType], U"formant grid"); \ autoKlattGrid_FormantGridEditor editor = KlattGrid_FormantGridEditor_create (id_and_name, me, formantType); \ praat_installEditor (editor.transfer(), IOBJECT); \ } \ END KlattGRID_EDIT_FORMANTGRID (Oral, KlattGrid_ORAL_FORMANTS) KlattGRID_EDIT_FORMANTGRID (Nasal, KlattGrid_NASAL_FORMANTS) KlattGRID_EDIT_FORMANTGRID (Tracheal, KlattGrid_TRACHEAL_FORMANTS) KlattGRID_EDIT_FORMANTGRID (NasalAnti, KlattGrid_NASAL_ANTIFORMANTS) KlattGRID_EDIT_FORMANTGRID (TrachealAnti, KlattGrid_TRACHEAL_ANTIFORMANTS) KlattGRID_EDIT_FORMANTGRID (Delta, KlattGrid_DELTA_FORMANTS) KlattGRID_EDIT_FORMANTGRID (Frication, KlattGrid_FRICATION_FORMANTS) #undef KlattGRID_EDIT_FORMANTGRID #define KlattGrid_EDIT_FORMANT_AMPLITUDE_TIER(Name,name,formantType) \ FORM (KlattGrid_edit##Name##FormantAmplitudeTier, U"KlattGrid: View & Edit " #name "formant amplitude tier", 0) \ NATURAL (U"Formant number", U"1") \ OK \ DO \ long formantNumber = GET_INTEGER (U"Formant number"); \ if (theCurrentPraatApplication -> batch) { Melder_throw (U"Cannot edit a KlattGrid from batch."); } \ LOOP { \ iam (KlattGrid); \ Ordered *amp = KlattGrid_getAddressOfAmplitudes (me, formantType); \ if (! amp) Melder_throw (U"Unknown formant type"); \ if (formantNumber > (*amp) -> size) Melder_throw (U"Formant number does not exist."); \ const char32 *id_and_name = Melder_cat (ID, U". ", formant_names[formantType], U"formant amplitude tier"); \ autoKlattGrid_DecibelTierEditor editor = KlattGrid_DecibelTierEditor_create (id_and_name, me, (RealTier) (*amp)->item[formantNumber]); \ praat_installEditor (editor.transfer(), IOBJECT); \ } \ END KlattGrid_EDIT_FORMANT_AMPLITUDE_TIER (Oral, oral, KlattGrid_ORAL_FORMANTS) KlattGrid_EDIT_FORMANT_AMPLITUDE_TIER (Nasal, nasal, KlattGrid_NASAL_FORMANTS) KlattGrid_EDIT_FORMANT_AMPLITUDE_TIER (Tracheal, tracheal, KlattGrid_TRACHEAL_FORMANTS) KlattGrid_EDIT_FORMANT_AMPLITUDE_TIER (Frication, frication, KlattGrid_FRICATION_FORMANTS) #undef KlattGrid_EDIT_FORMANT_AMPLITUDE_TIER #define KlattGrid_PHONATION_GET_ADD_REMOVE_EXTRACT_REPLACE(Name,name,unit,default,require, requiremessage,newname,tiertype) \ FORM(KlattGrid_get##Name##AtTime, U"KlattGrid: Get " #name " at time", 0) \ REAL (U"Time", U"0.5") \ OK \ DO \ LOOP { iam (KlattGrid); \ Melder_informationReal (KlattGrid_get##Name##AtTime (me, GET_REAL (U"Time")), unit); \ }\ END \ FORM (KlattGrid_add##Name##Point, U"KlattGrid: Add " #name " point", 0) \ REAL (U"Time (s)", U"0.5") \ REAL (U"Value" unit, default) \ OK \ DO \ double value = GET_REAL (U"Value"); \ REQUIRE (require, requiremessage) \ LOOP { iam (KlattGrid); \ KlattGrid_add##Name##Point (me, GET_REAL (U"Time"), value); \ praat_dataChanged (me); \ } \ END \ FORM (KlattGrid_remove##Name##Points, U"Remove " #name " points", 0) \ REAL (U"From time (s)", U"0.3")\ REAL (U"To time (s)", U"0.7") \ OK \ DO \ LOOP { iam (KlattGrid); \ KlattGrid_remove##Name##Points (me, GET_REAL (U"From time"), GET_REAL (U"To time")); \ praat_dataChanged (me);\ } \ END \ DIRECT (KlattGrid_extract##Name##Tier) \ LOOP { iam (KlattGrid); \ praat_new (KlattGrid_extract##Name##Tier (me).transfer(), newname); \ } \ END \ DIRECT (KlattGrid_replace##Name##Tier) \ KlattGrid me = FIRST(KlattGrid); \ tiertype thee = FIRST(tiertype); \ KlattGrid_replace##Name##Tier (me, thee); \ praat_dataChanged (me);\ END // 55 DO_KlattGrid... functions KlattGrid_PHONATION_GET_ADD_REMOVE_EXTRACT_REPLACE (Pitch, pitch, U" (Hz)", (U"100.0"), (value >= 0), (U"Pitch must be greater equal zero."), U"f0", PitchTier) KlattGrid_PHONATION_GET_ADD_REMOVE_EXTRACT_REPLACE (VoicingAmplitude, voicing amplitude, U" (dB SPL)", U"90.0", (1), U"", U"voicing", IntensityTier) KlattGrid_PHONATION_GET_ADD_REMOVE_EXTRACT_REPLACE (Flutter, flutter, U" (0..1)", (U"0.0"), (value >= 0 && value <= 1), (U"Flutter must be in [0,1]."), U"flutter", RealTier) KlattGrid_PHONATION_GET_ADD_REMOVE_EXTRACT_REPLACE (Power1, power1, U"", U"3", (value > 0), U"Power1 needs to be positive.", U"power1", RealTier) KlattGrid_PHONATION_GET_ADD_REMOVE_EXTRACT_REPLACE (Power2, power2, U"", U"4", (value > 0), U"Power2 needs to be positive.", U"power2", RealTier) KlattGrid_PHONATION_GET_ADD_REMOVE_EXTRACT_REPLACE (OpenPhase, open phase, U"", U"0.7", (value >= 0 && value <= 1), U"Open phase must be greater than zero and smaller equal one.", U"openPhase", RealTier) KlattGrid_PHONATION_GET_ADD_REMOVE_EXTRACT_REPLACE (CollisionPhase, collision phase, U"", U"0.03", (value >= 0 && value < 1), U"Collision phase must be greater equal zero and smaller than one.", U"collisionPhase", RealTier) KlattGrid_PHONATION_GET_ADD_REMOVE_EXTRACT_REPLACE (DoublePulsing, double pulsing, U" (0..1)", U"0.0", (value >= 0 && value <= 1), U"Double pulsing must be greater equal zero and smaller equal one.", U"doublePulsing", RealTier) KlattGrid_PHONATION_GET_ADD_REMOVE_EXTRACT_REPLACE (SpectralTilt, spectral tilt, U" (dB)", U"0.0", (value >= 0), U"Spectral tilt must be greater equal zero.", U"spectralTilt", IntensityTier) KlattGrid_PHONATION_GET_ADD_REMOVE_EXTRACT_REPLACE (AspirationAmplitude, aspiration amplitude, U" (dB SPL)", U"0.0", (1), U"", U"aspiration", IntensityTier) KlattGrid_PHONATION_GET_ADD_REMOVE_EXTRACT_REPLACE (BreathinessAmplitude, breathiness amplitude, U" (dB SPL)", U"30.0", (1), U"", U"breathiness", IntensityTier) KlattGrid_PHONATION_GET_ADD_REMOVE_EXTRACT_REPLACE (FricationAmplitude, frication amplitude, U" (dB SPL)", U"30.0", (1), U"", U"frication", IntensityTier) KlattGrid_PHONATION_GET_ADD_REMOVE_EXTRACT_REPLACE (FricationBypass, frication bypass, U" (dB)", U"30.0", (1), U"", U"bypass", IntensityTier) #undef KlattGrid_PHONATION_GET_ADD_REMOVE_EXTRACT_REPLACE #define KlattGrid_FORMULA_FORMANT_FBA_VALUE(Name,namef,ForBs,forbs,textfield,formantType,label) \ FORM (KlattGrid_formula##Name##Formant##ForBs, U"KlattGrid: Formula (" #namef "ormant " #forbs ")", U"Formant: Formula (" #forbs ")...") \ LABEL (U"", U"row is formant number, col is point number:\nfor row from 1 to nrow do for col from 1 to ncol do " #ForBs " (row, col) :=") \ LABEL (U"", label) \ TEXTFIELD (U"formula", textfield) \ OK \ DO \ LOOP { iam (KlattGrid); \ KlattGrid_formula_##forbs (me, formantType, GET_STRING (U"formula"), interpreter); \ praat_dataChanged (me); \ } \ END #define KlattGrid_ADD_FBA_VALUE(Name,namef,Form,FBA,fba,formantType,default,unit,require,requiremessage) \ FORM (KlattGrid_add##Name##Formant##FBA##Point, U"KlattGrid: Add " #namef "ormant " #fba " point", 0) \ NATURAL (U"Formant number", U"1") \ REAL (U"Time (s)", U"0.5") \ REAL (U"Value " #unit, default) \ OK \ DO \ double value = GET_REAL (U"Value"); \ REQUIRE (require, requiremessage) \ LOOP { iam (KlattGrid); \ KlattGrid_add##Form##Point (me, formantType, GET_INTEGER (U"Formant number"), GET_REAL (U"Time"), value); \ praat_dataChanged (me); \ } \ END #define KlattGrid_REMOVE_FBA_VALUE(Name,namef,Form,FBA,fba,formantType) \ FORM (KlattGrid_remove##Name##Formant##FBA##Points, U"KlattGrid: Remove " #namef "ormant " #fba " points", 0) \ NATURAL (U"Formant number", U"1") \ REAL (U"From time (s)", U"0.3")\ REAL (U"To time (s)", U"0.7") \ OK \ DO \ LOOP { iam (KlattGrid); \ KlattGrid_remove##Form##Points (me, formantType, GET_INTEGER (U"Formant number"), GET_REAL (U"From time"), GET_REAL (U"To time")); \ praat_dataChanged (me);\ } \ END #define KlattGrid_ADD_FORMANT(Name,namef,formantType) \ FORM (KlattGrid_add##Name##Formant, U"KlattGrid: Add " #namef "ormant", 0) \ INTEGER (U"Position", U"0 (=at end)") \ OK \ DO \ LOOP { iam (KlattGrid); \ KlattGrid_addFormant (me, formantType, GET_INTEGER (U"Position")); \ praat_dataChanged (me); \ } \ END #define KlattGrid_REMOVE_FORMANT(Name,namef,formantType) \ FORM (KlattGrid_remove##Name##Formant, U"KlattGrid: Remove " #namef "ormant", 0) \ INTEGER (U"Position", U"0 (=do nothing)") \ OK \ DO \ LOOP { iam (KlattGrid); \ KlattGrid_removeFormant (me, formantType, GET_INTEGER (U"Position")); \ praat_dataChanged (me); \ } \ END #define KlattGrid_ADD_FORMANT_FREQUENCYANDBANDWIDTHTIERS(Name,namef,formantType) \ FORM (KlattGrid_add##Name##FormantFrequencyAndBandwidthTiers, U"KlattGrid: Add " #namef "ormant", 0) \ INTEGER (U"Position", U"0 (=at end)") \ OK \ DO \ LOOP { iam (KlattGrid); \ KlattGrid_addFormantFrequencyAndBandwidthTiers (me, formantType, GET_INTEGER (U"Position")); \ praat_dataChanged (me); \ } \ END #define KlattGrid_REMOVE_FORMANT_FREQUENCYANDBANDWIDTHTIERS(Name,namef,formantType) \ FORM (KlattGrid_remove##Name##FormantFrequencyAndBandwidthTiers, U"KlattGrid: Remove " #namef "ormant", 0) \ INTEGER (U"Position", U"0 (=do nothing)") \ OK \ DO \ LOOP { iam (KlattGrid); \ KlattGrid_removeFormantFrequencyAndBandwidthTiers (me, formantType, GET_INTEGER (U"Position")); \ praat_dataChanged (me); \ } \ END #define KlattGrid_ADD_FORMANT_AMPLITUDETIER(Name,namef,formantType) \ FORM (KlattGrid_add##Name##FormantAmplitudeTier, U"KlattGrid: Add " #namef "ormant amplitude tier", 0) \ INTEGER (U"Position", U"0 (=at end)") \ OK \ DO \ LOOP { iam (KlattGrid); \ KlattGrid_addFormantAmplitudeTier (me, formantType, GET_INTEGER (U"Position")); \ praat_dataChanged (me); \ } \ END #define KlattGrid_REMOVE_FORMANT_AMPLITUDETIER(Name,namef,formantType) \ FORM (KlattGrid_remove##Name##FormantAmplitudeTier, U"KlattGrid: Remove " #namef "ormant amplitude tier", 0) \ INTEGER (U"Position", U"0 (=do nothing)") \ OK \ DO \ LOOP { iam (KlattGrid); \ KlattGrid_removeFormant (me, formantType, GET_INTEGER (U"Position")); \ praat_dataChanged (me); \ } \ END #define KlattGrid_FORMULA_ADD_REMOVE_FBA(Name,namef,formantType) \ KlattGrid_FORMULA_FORMANT_FBA_VALUE (Name, namef, Frequencies, frequencies, U"if row = 2 then self + 200 else self fi", formantType, U" ") \ KlattGrid_FORMULA_FORMANT_FBA_VALUE (Name, namef, Bandwidths, bandwidths, U"self / 10 ; 10% of frequency", formantType, U"Warning: self is formant frequency.") \ KlattGrid_ADD_FBA_VALUE (Name, namef, Formant, Frequency, frequency, formantType, U"500.0", (Hz), (value>0), U"Frequency must be greater than zero.") \ KlattGrid_ADD_FBA_VALUE (Name, namef, Bandwidth, Bandwidth, bandwidth, formantType, U"50.0", (Hz), (value>0), U"Bandwidth must be greater than zero.") \ KlattGrid_ADD_FBA_VALUE (Name, namef, Amplitude, Amplitude, amplitude, formantType, U"0.0", (dB), (NUMdefined(value)), U"Amplitude must be defined.") \ KlattGrid_REMOVE_FBA_VALUE (Name, namef, Formant, Frequency, frequency, formantType) \ KlattGrid_REMOVE_FBA_VALUE (Name, namef, Bandwidth, Bandwidth, bandwidth, formantType) \ KlattGrid_REMOVE_FBA_VALUE (Name, namef, Amplitude, Amplitude, amplitude, formantType) \ KlattGrid_ADD_FORMANT(Name,namef,formantType) \ KlattGrid_ADD_FORMANT_FREQUENCYANDBANDWIDTHTIERS(Name,namef,formantType) \ KlattGrid_REMOVE_FORMANT_FREQUENCYANDBANDWIDTHTIERS(Name,namef,formantType) \ KlattGrid_REMOVE_FORMANT_AMPLITUDETIER(Name,namef,formantType) \ KlattGrid_REMOVE_FORMANT(Name,namef,formantType) \ KlattGrid_ADD_FORMANT_AMPLITUDETIER(Name,namef,formantType) #define KlattGrid_FORMULA_ADD_REMOVE_FB(Name,namef,formantType) \ KlattGrid_FORMULA_FORMANT_FBA_VALUE (Name, namef, Frequencies, frequencies, U"if row = 2 then self + 200 else self fi",formantType, U" ") \ KlattGrid_FORMULA_FORMANT_FBA_VALUE (Name, namef, Bandwidths, bandwidths, U"self / 10 ; 10% of frequency",formantType, U"Warning: self is formant frequency.") \ KlattGrid_ADD_FBA_VALUE (Name, namef, Formant,Frequency, frequency, formantType, U"500.0", (Hz), (value>0), U"Frequency must be greater than zero.") \ KlattGrid_ADD_FBA_VALUE (Name, namef, Bandwidth, Bandwidth, bandwidth, formantType, U"50.0", (Hz), (value>0), U"Bandwidth must be greater than zero.") \ KlattGrid_REMOVE_FBA_VALUE (Name, namef, Formant, Frequency, frequency, formantType) \ KlattGrid_REMOVE_FBA_VALUE (Name, namef, Bandwidth, Bandwidth, bandwidth, formantType) \ KlattGrid_ADD_FORMANT(Name,namef,formantType) \ KlattGrid_ADD_FORMANT_FREQUENCYANDBANDWIDTHTIERS(Name,namef,formantType) \ KlattGrid_REMOVE_FORMANT_FREQUENCYANDBANDWIDTHTIERS(Name,namef,formantType) \ KlattGrid_REMOVE_FORMANT(Name,namef,formantType) #define KlattGrid_FORMULA_ADD_REMOVE_FB_DELTA(Name,namef,formantType) \ KlattGrid_FORMULA_FORMANT_FBA_VALUE (Name, namef, Frequencies, frequencies, U"if row = 2 then self + 200 else self fi",formantType, U" ") \ KlattGrid_FORMULA_FORMANT_FBA_VALUE (Name, namef, Bandwidths, bandwidths, U"self / 10 ; 10% of frequency",formantType, U"Warning: self is formant frequency.") \ KlattGrid_ADD_FBA_VALUE (Name, namef, Formant,Frequency, frequency, formantType, U"-100.0", (Hz), (value!=NUMundefined), U"Frequency must be defined.") \ KlattGrid_ADD_FBA_VALUE (Name, namef, Bandwidth, Bandwidth, bandwidth, formantType, U"-50.0", (Hz), (value!=NUMundefined), U"Bandwidth must be defined.") \ KlattGrid_REMOVE_FBA_VALUE (Name, namef, Formant, Frequency, frequency, formantType) \ KlattGrid_REMOVE_FBA_VALUE (Name, namef, Bandwidth, Bandwidth, bandwidth, formantType) \ KlattGrid_ADD_FORMANT_FREQUENCYANDBANDWIDTHTIERS(Name,namef,formantType) \ KlattGrid_REMOVE_FORMANT_FREQUENCYANDBANDWIDTHTIERS(Name,namef,formantType) \ KlattGrid_ADD_FORMANT(Name,namef,formantType) \ KlattGrid_REMOVE_FORMANT(Name,namef,formantType) KlattGrid_FORMULA_ADD_REMOVE_FBA (Oral, oral f, KlattGrid_ORAL_FORMANTS) KlattGrid_FORMULA_ADD_REMOVE_FBA (Nasal, nasal f, KlattGrid_NASAL_FORMANTS) KlattGrid_FORMULA_ADD_REMOVE_FB (NasalAnti, nasal antif, KlattGrid_NASAL_ANTIFORMANTS) KlattGrid_FORMULA_ADD_REMOVE_FB_DELTA (Delta, delta f, KlattGrid_DELTA_FORMANTS) KlattGrid_FORMULA_ADD_REMOVE_FBA (Tracheal, tracheal f, KlattGrid_TRACHEAL_FORMANTS) KlattGrid_FORMULA_ADD_REMOVE_FB (TrachealAnti, tracheal antif, KlattGrid_TRACHEAL_ANTIFORMANTS) KlattGrid_FORMULA_ADD_REMOVE_FBA (Frication, frication f, KlattGrid_FRICATION_FORMANTS) #undef KlattGrid_FORMULA_ADD_REMOVE_FB #undef KlattGrid_FORMULA_ADD_REMOVE #undef KlattGrid_ADD_FORMANT_AND_BANDWDTH_TIER #undef KlattGrid_REMOVE_FBA_VALUE #undef KlattGrid_ADD_FBA_VALUE #undef KlattGrid_FORMULA_FORMANT_FB_VALUE DIRECT (KlattGrid_extractPointProcess_glottalClosures) LOOP { iam (KlattGrid); praat_new (KlattGrid_extractPointProcess_glottalClosures (me).transfer(), my name); } END FORM (KlattGrid_formula_frequencies, U"KlattGrid: Formula (frequencies)", U"Formant: Formula (frequencies)...") KlattGrid_6formants_addCommonField (dia); LABEL (U"", U"row is formant number, col is point number: for row from 1 to nrow do for col from 1 to ncol do F (row, col) :=") TEXTFIELD (U"formula", U"if row = 2 then self + 200 else self fi") OK DO int formantType = GET_INTEGER (U"Formant type"); LOOP { iam (KlattGrid); KlattGrid_formula_frequencies (me, formantType, GET_STRING (U"formula"), interpreter); praat_dataChanged (me); } END FORM (KlattGrid_formula_bandwidths, U"KlattGrid: Formula (bandwidths)", U"Formant: Formula (bandwidths)...") KlattGrid_6formants_addCommonField (dia); LABEL (U"", U"row is formant number, col is point number: for row from 1 to nrow do for col from 1 to ncol do F (row, col) :=") TEXTFIELD (U"formula", U"if row = 2 then self + 200 else self fi") OK DO int formantType = GET_INTEGER (U"Formant type"); LOOP { iam (KlattGrid); KlattGrid_formula_bandwidths (me, formantType, GET_STRING (U"formula"), interpreter); praat_dataChanged (me); } END #define KlattGrid_FORMANT_GET_FB_VALUE(Name,name,ForB,forb,FormB,formantType) \ FORM (KlattGrid_get##Name##Formant##ForB##AtTime, U"KlattGrid: Get " #name " " #forb " at time", 0) \ NATURAL (U"Formant number", U"1") \ REAL (U"Time (s)", U"0.5") \ OK \ DO \ LOOP { iam (KlattGrid); \ Melder_informationReal (KlattGrid_get##FormB##AtTime (me, formantType, GET_INTEGER (U"Formant number"), GET_REAL (U"Time")), U" (Hz)"); \ } \ END #define KlattGrid_FORMANT_GET_A_VALUE(Name,name,formantType) \ FORM (KlattGrid_get##Name##FormantAmplitudeAtTime, U"KlattGrid: Get " #name " formant amplitude at time", 0) \ NATURAL (U"Formant number", U"1") \ REAL (U"Time (s)", U"0.5") \ OK \ DO \ LOOP { iam (KlattGrid); \ Melder_informationReal (KlattGrid_getAmplitudeAtTime (me, formantType, GET_INTEGER (U"Formant number"), GET_REAL (U"Time")), U" (dB)"); \ } \ END #define KlattGrid_FORMANT_GET_FB_VALUES(Name,name,formantType) \ KlattGrid_FORMANT_GET_FB_VALUE(Name,name,Frequency,frequency,Formant,formantType) \ KlattGrid_FORMANT_GET_FB_VALUE(Name,name,Bandwidth,bandwidth,Bandwidth,formantType) KlattGrid_FORMANT_GET_FB_VALUES (Oral, oral, KlattGrid_ORAL_FORMANTS) KlattGrid_FORMANT_GET_A_VALUE (Oral, oral, KlattGrid_ORAL_FORMANTS) KlattGrid_FORMANT_GET_FB_VALUES (Nasal, nasal, KlattGrid_NASAL_FORMANTS) KlattGrid_FORMANT_GET_A_VALUE (Nasal, nasal, KlattGrid_NASAL_FORMANTS) KlattGrid_FORMANT_GET_FB_VALUES (NasalAnti, nasal anti, KlattGrid_NASAL_ANTIFORMANTS) KlattGrid_FORMANT_GET_FB_VALUES (Tracheal, tracheal f, KlattGrid_TRACHEAL_FORMANTS) KlattGrid_FORMANT_GET_A_VALUE (Tracheal, tracheal f, KlattGrid_TRACHEAL_FORMANTS) KlattGrid_FORMANT_GET_FB_VALUES (Delta, delta f, KlattGrid_DELTA_FORMANTS) KlattGrid_FORMANT_GET_FB_VALUES (TrachealAnti, tracheal antif, KlattGrid_TRACHEAL_ANTIFORMANTS) KlattGrid_FORMANT_GET_FB_VALUES (Frication, frication, KlattGrid_FRICATION_FORMANTS) KlattGrid_FORMANT_GET_A_VALUE (Frication, frication, KlattGrid_FRICATION_FORMANTS) #undef KlattGrid_FORMANT_GET_FB_VALUES #undef KlattGrid_FORMANT_GET_A_VALUE #define KlattGrid_EXTRACT_FORMANT_GRID(Name,gridType) \ DIRECT (KlattGrid_extract##Name##FormantGrid) \ LOOP { iam (KlattGrid); \ praat_new (KlattGrid_extractFormantGrid (me, gridType).transfer(), formant_names[gridType]); \ } \ END #define KlattGrid_EXTRACT_FORMANT_AMPLITUDE(Name,name,formantType) \ FORM (KlattGrid_extract##Name##FormantAmplitudeTier, U"KlattGrid: Extract " #name " formant amplitude tier", 0) \ NATURAL (U"Formant number", U"1") \ OK \ DO \ LOOP { iam (KlattGrid); \ praat_new (KlattGrid_extractAmplitudeTier (me, formantType, GET_INTEGER (U"Formant number")).transfer(), formant_names[formantType]); \ } \ END KlattGrid_EXTRACT_FORMANT_GRID (Oral, KlattGrid_ORAL_FORMANTS) KlattGrid_EXTRACT_FORMANT_AMPLITUDE (Oral, oral, KlattGrid_ORAL_FORMANTS) KlattGrid_EXTRACT_FORMANT_GRID (Nasal, KlattGrid_NASAL_FORMANTS) KlattGrid_EXTRACT_FORMANT_AMPLITUDE (Nasal, nasal, KlattGrid_NASAL_FORMANTS) KlattGrid_EXTRACT_FORMANT_GRID (Frication, KlattGrid_FRICATION_FORMANTS) KlattGrid_EXTRACT_FORMANT_AMPLITUDE (Frication, frication, KlattGrid_FRICATION_FORMANTS) KlattGrid_EXTRACT_FORMANT_GRID (Tracheal, KlattGrid_TRACHEAL_FORMANTS) KlattGrid_EXTRACT_FORMANT_AMPLITUDE (Tracheal, tracheal, KlattGrid_TRACHEAL_FORMANTS) KlattGrid_EXTRACT_FORMANT_GRID (NasalAnti, KlattGrid_NASAL_ANTIFORMANTS) KlattGrid_EXTRACT_FORMANT_GRID (TrachealAnti, KlattGrid_TRACHEAL_ANTIFORMANTS) KlattGrid_EXTRACT_FORMANT_GRID (Delta, KlattGrid_DELTA_FORMANTS) #undef KlattGrid_EXTRACT_FORMANTGRID #define KlattGrid_REPLACE_FORMANT_GRID(Name,formantType) \ DIRECT (KlattGrid_replace##Name##FormantGrid) \ KlattGrid me = FIRST (KlattGrid); \ FormantGrid thee = FIRST (FormantGrid); \ KlattGrid_replaceFormantGrid (me, formantType, thee); \ praat_dataChanged (me); \ END #define KlattGrid_REPLACE_FORMANT_AMPLITUDE(Name,name,formantType) \ FORM (KlattGrid_replace##Name##FormantAmplitudeTier, U"KlattGrid: Replace " #name " formant amplitude tier", 0) \ NATURAL (U"Formant number", U"1") \ OK \ DO \ KlattGrid me = FIRST (KlattGrid); \ IntensityTier thee = FIRST (IntensityTier); \ KlattGrid_replaceAmplitudeTier (me, formantType, GET_INTEGER (U"Formant number"), thee); \ praat_dataChanged (me); \ END KlattGrid_REPLACE_FORMANT_GRID (Oral, KlattGrid_ORAL_FORMANTS) KlattGrid_REPLACE_FORMANT_AMPLITUDE (Oral, oral, KlattGrid_ORAL_FORMANTS) KlattGrid_REPLACE_FORMANT_GRID (Nasal, KlattGrid_NASAL_FORMANTS) KlattGrid_REPLACE_FORMANT_AMPLITUDE (Nasal, nasal, KlattGrid_NASAL_FORMANTS) KlattGrid_REPLACE_FORMANT_GRID (NasalAnti, KlattGrid_NASAL_ANTIFORMANTS) KlattGrid_REPLACE_FORMANT_GRID (Tracheal, KlattGrid_TRACHEAL_FORMANTS) KlattGrid_REPLACE_FORMANT_AMPLITUDE (Tracheal, tracheal, KlattGrid_TRACHEAL_FORMANTS) KlattGrid_REPLACE_FORMANT_GRID (TrachealAnti, KlattGrid_TRACHEAL_ANTIFORMANTS) KlattGrid_REPLACE_FORMANT_GRID (Delta, KlattGrid_DELTA_FORMANTS) KlattGrid_REPLACE_FORMANT_GRID (Frication, KlattGrid_FRICATION_FORMANTS) KlattGrid_REPLACE_FORMANT_AMPLITUDE (Frication, frication, KlattGrid_FRICATION_FORMANTS) #undef KlattGrid_REPLACE_FORMANT_AMPLITUDE #undef KlattGrid_REPLACE_FORMANTGRID #define KlattGrid_FORMANT_GET_ADD_REMOVE(Name,name,unit,default,require,requiremessage) \ FORM (KlattGrid_get##Name##AtTime, U"KlattGrid: Get " #name " at time", 0) \ KlattGrid_6formants_addCommonField (dia); \ NATURAL (U"Formant number", U"1") \ REAL (U"Time (s)", U"0.5") \ OK \ DO \ int formantType = GET_INTEGER (U"Formant type"); \ LOOP { iam (KlattGrid); \ Melder_informationReal (KlattGrid_get##Name##AtTime (me, formantType, GET_INTEGER (U"Formant number"), GET_REAL (U"Time")), U" (Hz)"); \ } \ END \ FORM (KlattGrid_getDelta##Name##AtTime, U"KlattGrid: Get delta " #name " at time", 0) \ NATURAL (U"Formant number", U"1") \ REAL (U"Time (s)", U"0.5") \ OK \ DO \ LOOP { iam (KlattGrid); \ Melder_informationReal (KlattGrid_getDelta##Name##AtTime (me, GET_INTEGER (U"Formant number"), GET_REAL (U"Time")), U" (Hz)"); \ } \ END \ FORM (KlattGrid_add##Name##Point, U"KlattGrid: Add " #name " point", 0) \ KlattGrid_6formants_addCommonField (dia); \ NATURAL (U"Formant number", U"1") \ REAL (U"Time (s)", U"0.5") \ REAL (U"Value" unit, default) \ OK \ DO \ int formantType = GET_INTEGER (U"Formant type"); \ double value = GET_REAL (U"Value"); \ REQUIRE (require, requiremessage) \ LOOP { iam (KlattGrid); \ KlattGrid_add##Name##Point (me, formantType, GET_INTEGER (U"Formant number"), GET_REAL (U"Time"), value); \ praat_dataChanged (me); \ } \ END \ FORM (KlattGrid_addDelta##Name##Point, U"KlattGrid: Add delta " #name " point", 0) \ NATURAL (U"Formant number", U"1") \ REAL (U"Time (s)", U"0.5") \ REAL (U"Value" unit, default) \ OK \ DO \ double value = GET_REAL (U"Value"); \ REQUIRE (require, requiremessage) \ LOOP { iam (KlattGrid); \ KlattGrid_addDelta##Name##Point (me, GET_INTEGER (U"Formant number"), GET_REAL (U"Time"), value); \ praat_dataChanged (me); \ } \ END \ FORM (KlattGrid_remove##Name##Points, U"Remove " #name " points", 0) \ KlattGrid_6formants_addCommonField (dia); \ NATURAL (U"Formant number", U"1") \ REAL (U"From time (s)", U"0.3")\ REAL (U"To time (s)", U"0.7") \ OK \ DO \ int formantType = GET_INTEGER (U"Formant type"); \ LOOP { iam (KlattGrid); \ KlattGrid_remove##Name##Points (me, formantType, GET_INTEGER (U"Formant number"), GET_REAL (U"From time"), GET_REAL (U"To time")); \ praat_dataChanged (me);\ } \ END \ FORM (KlattGrid_removeDelta##Name##Points, U"Remove delta " #name " points", 0) \ NATURAL (U"Formant number", U"1") \ REAL (U"From time (s)", U"0.3")\ REAL (U"To time (s)", U"0.7") \ OK \ DO \ LOOP { iam (KlattGrid); \ KlattGrid_removeDelta##Name##Points (me, GET_INTEGER (U"Formant number"), GET_REAL (U"From time"), GET_REAL (U"To time")); \ praat_dataChanged (me);\ } \ END KlattGrid_FORMANT_GET_ADD_REMOVE (Formant, formant, U" (Hz)", U"500.0", (value > 0), U"Frequency must be greater than zero.") KlattGrid_FORMANT_GET_ADD_REMOVE (Bandwidth, bandwidth, U" (Hz)", U"50.0", (value > 0), U"Bandwidth must be greater than zero.") #undef KlattGrid_FORMANT_GET_ADD_REMOVE FORM (KlattGrid_addFormantAndBandwidthTier, U"", 0) KlattGrid_7formants_addCommonField (dia); INTEGER (U"Position", U"0 (=at end)") OK DO long gridType = GET_INTEGER (U"Formant type"); LOOP { iam (KlattGrid); KlattGrid_addFormantFrequencyAndBandwidthTiers (me, gridType, GET_INTEGER (U"Position")); praat_dataChanged (me); } END FORM (KlattGrid_extractFormantGrid, U"KlattGrid: Extract formant grid", 0) KlattGrid_6formants_addCommonField (dia); OK DO long gridType = GET_INTEGER (U"Formant type"); LOOP { iam (KlattGrid); praat_new (KlattGrid_extractFormantGrid (me, gridType).transfer(), formant_names[gridType]); } END FORM (KlattGrid_replaceFormantGrid, U"KlattGrid: Replace formant grid", 0) KlattGrid_6formants_addCommonField (dia); OK DO KlattGrid me = FIRST (KlattGrid); FormantGrid thee = FIRST (FormantGrid); KlattGrid_replaceFormantGrid (me, GET_INTEGER (U"Formant type"), thee); praat_dataChanged (OBJECT); END FORM (KlattGrid_getAmplitudeAtTime, U"KlattGrid: Get amplitude at time", 0) \ KlattGrid_4formants_addCommonField (dia); NATURAL (U"Formant number", U"1") REAL (U"Time (s)", U"0.5") OK DO int formantType = GET_INTEGER (U"Formant type"); LOOP { iam (KlattGrid); Melder_informationReal (KlattGrid_getAmplitudeAtTime (me, formantType, GET_INTEGER (U"Formant number"), GET_REAL (U"Time")), U" (dB)"); } END FORM (KlattGrid_addAmplitudePoint, U"KlattGrid: Add amplitude point", 0) KlattGrid_4formants_addCommonField (dia); NATURAL (U"Formant number", U"1") REAL (U"Time (s)", U"0.5") REAL (U"Value (Hz)", U"80.0") OK DO int formantType = GET_INTEGER (U"Formant type"); double value = GET_REAL (U"Value"); LOOP { iam (KlattGrid); KlattGrid_addAmplitudePoint (me, formantType, GET_INTEGER (U"Formant number"), GET_REAL (U"Time"), value); praat_dataChanged (me); } END FORM (KlattGrid_removeAmplitudePoints, U"Remove amplitude points", 0) \ KlattGrid_4formants_addCommonField (dia); NATURAL (U"Formant number", U"1") REAL (U"From time (s)", U"0.3") REAL (U"To time (s)", U"0.7") OK DO int formantType = GET_INTEGER (U"Formant type"); LOOP { iam (KlattGrid); KlattGrid_removeAmplitudePoints (me, formantType, GET_INTEGER (U"Formant number"), GET_REAL (U"From time"), GET_REAL (U"To time")); praat_dataChanged (me); } END FORM (KlattGrid_extractAmplitudeTier, U"", 0) KlattGrid_4formants_addCommonField (dia); NATURAL (U"Formant number", U"1") OK DO int formantType = GET_INTEGER (U"Formant type"); LOOP { iam (KlattGrid); praat_new (KlattGrid_extractAmplitudeTier (me, formantType, GET_INTEGER (U"Formant number")).transfer(), formant_names[formantType]); } END FORM (KlattGrid_replaceAmplitudeTier, U"KlattGrid: Replace amplitude tier", 0) KlattGrid_4formants_addCommonField (dia); NATURAL (U"Formant number", U"1") OK DO int formantType = GET_INTEGER (U"Formant type"); KlattGrid me = FIRST (KlattGrid); IntensityTier thee = FIRST (IntensityTier); KlattGrid_replaceAmplitudeTier (me, formantType, GET_INTEGER (U"Formant number"), thee); praat_dataChanged (me); END FORM (KlattGrid_to_Sound_special, U"KlattGrid: To Sound (special)", U"KlattGrid: To Sound (special)...") KlattGrid_PlayOptions_addCommonFields (dia, 1); OK DO LOOP { iam (KlattGrid); KlattGrid_setDefaultPlayOptions (me); KlattGrid_PlayOptions_getCommonFields (dia, 1, me); praat_new (KlattGrid_to_Sound (me).transfer(), my name); } END DIRECT (KlattGrid_to_Sound) LOOP { iam (KlattGrid); KlattGrid_setDefaultPlayOptions (me); praat_new (KlattGrid_to_Sound (me).transfer(), my name); } END FORM (KlattGrid_playSpecial, U"KlattGrid: Play special", U"KlattGrid: Play special...") KlattGrid_PlayOptions_addCommonFields (dia, 0); OK DO LOOP { iam (KlattGrid); KlattGrid_setDefaultPlayOptions (me); KlattGrid_PlayOptions_getCommonFields (dia, 0, me); KlattGrid_playSpecial (me); } END FORM (KlattGrid_to_Sound_phonation, U"KlattGrid: To Sound (phonation)", U"KlattGrid: To Sound (phonation)...") POSITIVE (U"Sampling frequency (Hz)", U"44100") KlattGrid_PhonationGridPlayOptions_addCommonFields (dia); OK DO LOOP { iam (KlattGrid); KlattGrid_PhonationGridPlayOptions_getCommonFields (dia, me); my options -> samplingFrequency = GET_REAL (U"Sampling frequency"); praat_new (KlattGrid_to_Sound_phonation (me).transfer(), my name, U"_phonation"); } END DIRECT (KlattGrid_help) Melder_help (U"KlattGrid"); END DIRECT (KlattGrid_play) LOOP { iam (KlattGrid); KlattGrid_play (me); } END FORM (KlattGrid_draw, U"KlattGrid: Draw", 0) RADIO (U"Synthesis model", 1) RADIOBUTTON (U"Cascade") RADIOBUTTON (U"Parallel") OK DO autoPraatPicture picture; LOOP { iam (KlattGrid); KlattGrid_draw (me, GRAPHICS, GET_INTEGER (U"Synthesis model") - 1); } END FORM (KlattGrid_drawVocalTract, U"KlattGrid: Draw vocal tract", 0) RADIO (U"Synthesis model", 1) RADIOBUTTON (U"Cascade") RADIOBUTTON (U"Parallel") BOOLEAN (U"Include tracheal formants", 1); OK DO autoPraatPicture picture; LOOP { iam (KlattGrid); KlattGrid_drawVocalTract (me, GRAPHICS, GET_INTEGER (U"Synthesis model") - 1, GET_INTEGER (U"Include tracheal formants")); } END DIRECT (KlattGrid_drawPhonation) autoPraatPicture picture; LOOP { iam (KlattGrid); PhonationGrid_draw (my phonation.get(), GRAPHICS); } END DIRECT (KlattGrid_drawFrication) autoPraatPicture picture; LOOP { iam (KlattGrid); FricationGrid_draw (my frication.get(), GRAPHICS); } END FORM (KlattGrid_to_oralFormantGrid_openPhases, U"KlattGrid: Extract oral formant grid (open phases)", U"KlattGrid: Extract oral formant grid (open phases)...") REAL (U"Fade fraction (0..0.5)", U"0.1") OK DO double fadeFraction = GET_REAL (U"Fade fraction"); REQUIRE (fadeFraction < 0.5, U"Fade fraction has to be smaller than 0.5.") LOOP { iam (KlattGrid); praat_new (KlattGrid_to_oralFormantGrid_openPhases (me, fadeFraction).transfer(), U"corrected"); } END FORM (Sound_KlattGrid_filterByVocalTract, U"Sound & KlattGrid: Filter by vocal tract", U"Sound & KlattGrid: Filter by vocal tract...") RADIO (U"Vocal tract filter model", 1) RADIOBUTTON (U"Cascade") RADIOBUTTON (U"Parallel") OK DO Sound me = FIRST (Sound); KlattGrid thee = FIRST (KlattGrid); int filterModel = GET_INTEGER (U"Vocal tract filter model") - 1; praat_new (Sound_KlattGrid_filterByVocalTract (me, thee, filterModel).transfer(), my name, U"_", thy name); END void praat_KlattGrid_init (); void praat_KlattGrid_init () { Thing_recognizeClassesByName (classKlattGrid, nullptr); praat_addMenuCommand (U"Objects", U"New", U"Acoustic synthesis (Klatt)", 0, 0, 0); praat_addMenuCommand (U"Objects", U"New", U"KlattGrid help", 0, 1, DO_KlattGrid_help); praat_addMenuCommand (U"Objects", U"New", U"-- the synthesizer grid --", 0, 1, 0); praat_addMenuCommand (U"Objects", U"New", U"Create KlattGrid...", 0, 1, DO_KlattGrid_create); praat_addMenuCommand (U"Objects", U"New", U"Create KlattGrid example", 0, praat_DEPTH_1 + praat_HIDDEN, DO_KlattGrid_createExample); /* Edit oral/nasal/tracheal/frication/delta formant grid Edit nasal/tracheal antiformant grid Get oral/nasal/tracheal/frication/delta formant at time... Get nasal/tracheal antiformant at time... Get oral/nasal/tracheal/frication/delta formant bandwidth at time... Get nasal/tracheal antiformant bandwidth at time... Get oral/nasal/tracheal/frication formant amplitude at time... Formula (oral/nasal/tracheal/frication/delta formant frequencies)... Formula (nasal/tracheal antiformant frequencies)... Formula (oral/nasal/tracheal/frication/delta formant bandwidths)... Formula (nasal/tracheal antiformant bandwidths)... Add oral/nasal/tracheal/frication/delta formant point... Add nasal/tracheal antiformant point... Add oral/nasal/tracheal/frication/delta formant bandwidth point... Add nasal/tracheal antiformant bandwidth point... Add oral/nasal/tracheal/frication formant amplitude point... Remove oral/nasal/tracheal/frication/delta formant points... Remove nasal/tracheal antiformant points... Remove oral/nasal/tracheal/frication/delta bandwidth points... Remove nasal/tracheal antiformant bandwidth points... Remove oral/nasal/tracheal/frication formant amplitude points... Extract oral/nasal/tracheal/frication/delta formant grid Extract nasal/tracheal antiformant grid Replace oral/nasal/tracheal/frication/delta formant grid Replace nasal/tracheal antiformant grid Add oral/nasal/tracheal/frication/delta formant and bandwidth tier Add nasal/tracheal antiformant and bandwidth tier #define KlattGrid_ORAL_FORMANTS 1 #define KlattGrid_NASAL_FORMANTS 2 #define KlattGrid_FRICATION_FORMANTS 3 #define KlattGrid_TRACHEAL_FORMANTS 4 #define KlattGrid_NASAL_ANTIFORMANTS 5 #define KlattGrid_TRACHEAL_ANTIFORMANTS 6 #define KlattGrid_DELTA_FORMANTS 7 */ praat_addAction1 (classKlattGrid, 0, U"KlattGrid help", 0, 0, DO_KlattGrid_help); praat_addAction1 (classKlattGrid, 0, U"Edit phonation -", 0, 0, 0); praat_addAction1 (classKlattGrid, 0, U"Edit pitch tier", 0, 1, DO_KlattGrid_editPitchTier); praat_addAction1 (classKlattGrid, 0, U"Edit voicing amplitude tier", 0, 1, DO_KlattGrid_editVoicingAmplitudeTier); praat_addAction1 (classKlattGrid, 0, U"Edit flutter tier", 0, 1, DO_KlattGrid_editFlutterTier); praat_addAction1 (classKlattGrid, 0, U"Edit power1 tier", 0, 1, DO_KlattGrid_editPower1Tier); praat_addAction1 (classKlattGrid, 0, U"Edit power2 tier", 0, 1, DO_KlattGrid_editPower2Tier); praat_addAction1 (classKlattGrid, 0, U"Edit open phase tier", 0, 1, DO_KlattGrid_editOpenPhaseTier); praat_addAction1 (classKlattGrid, 0, U"Edit collision phase tier", 0, 1, DO_KlattGrid_editCollisionPhaseTier); praat_addAction1 (classKlattGrid, 0, U"Edit double pulsing tier", 0, 1, DO_KlattGrid_editDoublePulsingTier); praat_addAction1 (classKlattGrid, 0, U"Edit spectral tilt tier", 0, 1, DO_KlattGrid_editSpectralTiltTier); praat_addAction1 (classKlattGrid, 0, U"Edit aspiration amplitude tier", 0, 1, DO_KlattGrid_editAspirationAmplitudeTier); praat_addAction1 (classKlattGrid, 0, U"Edit breathiness amplitude tier", 0, 1, DO_KlattGrid_editBreathinessAmplitudeTier); praat_addAction1 (classKlattGrid, 0, U"Edit filters -", 0, 0, 0); praat_addAction1 (classKlattGrid, 0, U"Edit oral formant grid", 0, 1, DO_KlattGrid_editOralFormantGrid); praat_addAction1 (classKlattGrid, 0, U"Edit nasal formant grid", 0, 1, DO_KlattGrid_editNasalFormantGrid); praat_addAction1 (classKlattGrid, 0, U"Edit nasal antiformant grid", 0, 1, DO_KlattGrid_editNasalAntiFormantGrid); praat_addAction1 (classKlattGrid, 0, U"Edit oral formant amplitude tier...", 0, 1, DO_KlattGrid_editOralFormantAmplitudeTier); praat_addAction1 (classKlattGrid, 0, U"Edit nasal formant amplitude tier...", 0, 1, DO_KlattGrid_editNasalFormantAmplitudeTier); praat_addAction1 (classKlattGrid, 0, U"-- edit delta formant grid --", 0, 1, 0); praat_addAction1 (classKlattGrid, 0, U"Edit delta formant grid", 0, 1, DO_KlattGrid_editDeltaFormantGrid); praat_addAction1 (classKlattGrid, 0, U"Edit tracheal formant grid", 0, 1, DO_KlattGrid_editTrachealFormantGrid); praat_addAction1 (classKlattGrid, 0, U"Edit tracheal antiformant grid", 0, 1, DO_KlattGrid_editTrachealAntiFormantGrid); praat_addAction1 (classKlattGrid, 0, U"Edit tracheal formant amplitude tier...", 0, 1, DO_KlattGrid_editTrachealFormantAmplitudeTier); praat_addAction1 (classKlattGrid, 0, U"-- edit frication tiers --", 0, 1, 0); praat_addAction1 (classKlattGrid, 1, U"Edit frication amplitude tier", 0, 1, DO_KlattGrid_editFricationAmplitudeTier); praat_addAction1 (classKlattGrid, 0, U"Edit frication formant grid", 0, 1, DO_KlattGrid_editFricationFormantGrid); praat_addAction1 (classKlattGrid, 0, U"Edit frication formant amplitude tier...", 0, 1, DO_KlattGrid_editFricationFormantAmplitudeTier); praat_addAction1 (classKlattGrid, 0, U"Edit frication bypass tier", 0, 1, DO_KlattGrid_editFricationBypassTier); praat_addAction1 (classKlattGrid, 1, U"Edit frication amplitude tier", 0, 1, DO_KlattGrid_editFricationAmplitudeTier); praat_addAction1 (classKlattGrid, 0, U"Play", 0, 0, DO_KlattGrid_play); praat_addAction1 (classKlattGrid, 0, U"Play special...", 0, 0, DO_KlattGrid_playSpecial); praat_addAction1 (classKlattGrid, 0, U"To Sound", 0, 0, DO_KlattGrid_to_Sound); praat_addAction1 (classKlattGrid, 0, U"To Sound (special)...", 0, 0, DO_KlattGrid_to_Sound_special); praat_addAction1 (classKlattGrid, 0, U"To Sound (phonation)...", 0, 0, DO_KlattGrid_to_Sound_phonation); praat_addAction1 (classKlattGrid, 0, U"Draw -", 0, 0, 0); praat_addAction1 (classKlattGrid, 0, U"Draw synthesizer...", 0, 1, DO_KlattGrid_draw); praat_addAction1 (classKlattGrid, 0, U"Draw vocal tract...", 0, 1, DO_KlattGrid_drawVocalTract); praat_addAction1 (classKlattGrid, 0, U"Draw phonation", 0, 1, DO_KlattGrid_drawPhonation); praat_addAction1 (classKlattGrid, 0, U"Draw frication", 0, 1, DO_KlattGrid_drawFrication); praat_addAction1 (classKlattGrid, 0, U"Query phonation -", 0, 0, 0); praat_addAction1 (classKlattGrid, 1, U"Get pitch at time...", 0, 1, DO_KlattGrid_getPitchAtTime); praat_addAction1 (classKlattGrid, 1, U"Get voicing amplitude at time...", 0, 1, DO_KlattGrid_getVoicingAmplitudeAtTime); praat_addAction1 (classKlattGrid, 1, U"Get flutter at time...", 0, 1, DO_KlattGrid_getFlutterAtTime); praat_addAction1 (classKlattGrid, 1, U"Get power1 at time...", 0, 1, DO_KlattGrid_getPower1AtTime); praat_addAction1 (classKlattGrid, 1, U"Get power2 at time...", 0, 1, DO_KlattGrid_getPower2AtTime); praat_addAction1 (classKlattGrid, 1, U"Get open phase at time...", 0, 1, DO_KlattGrid_getOpenPhaseAtTime); praat_addAction1 (classKlattGrid, 1, U"Get collision phase at time...", 0, 1, DO_KlattGrid_getCollisionPhaseAtTime); praat_addAction1 (classKlattGrid, 1, U"Get double pulsing at time...", 0, 1, DO_KlattGrid_getDoublePulsingAtTime); praat_addAction1 (classKlattGrid, 1, U"Get spectral tilt at time...", 0, 1, DO_KlattGrid_getSpectralTiltAtTime); praat_addAction1 (classKlattGrid, 1, U"Get aspiration amplitude at time...", 0, 1, DO_KlattGrid_getAspirationAmplitudeAtTime); praat_addAction1 (classKlattGrid, 1, U"Get breathiness amplitude at time...", 0, 1, DO_KlattGrid_getBreathinessAmplitudeAtTime); praat_addAction1 (classKlattGrid, 0, U"Query filters -", 0, 0, 0); praat_addAction1 (classKlattGrid, 1, U"Get formant at time...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_KlattGrid_getFormantAtTime); praat_addAction1 (classKlattGrid, 1, U"Get bandwidth at time...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_KlattGrid_getBandwidthAtTime); praat_addAction1 (classKlattGrid, 1, U"Get amplitude at time...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_KlattGrid_getAmplitudeAtTime); praat_addAction1 (classKlattGrid, 1, U"Get delta formant at time...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_KlattGrid_getDeltaFormantAtTime); praat_addAction1 (classKlattGrid, 1, U"Get delta bandwidth at time...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_KlattGrid_getDeltaBandwidthAtTime); #define KlattGRID_GET_FORMANT_FB_VALUES_ACTION(Name, formantname) \ praat_addAction1 (classKlattGrid, 1, U"Get " #formantname " frequency at time...", 0, 1, DO_KlattGrid_get##Name##FormantFrequencyAtTime); \ praat_addAction1 (classKlattGrid, 1, U"Get " #formantname " bandwidth at time...", 0, 1, DO_KlattGrid_get##Name##FormantBandwidthAtTime); #define KlattGRID_GET_FORMANT_A_VALUES_ACTION(Name,formantname) \ praat_addAction1 (classKlattGrid, 1, U"Get " #formantname " amplitude at time...", 0, 1, DO_KlattGrid_get##Name##FormantAmplitudeAtTime); \ KlattGRID_GET_FORMANT_FB_VALUES_ACTION (Oral, oral formant) KlattGRID_GET_FORMANT_A_VALUES_ACTION (Oral, oral formant) KlattGRID_GET_FORMANT_FB_VALUES_ACTION (Nasal, nasal formant) KlattGRID_GET_FORMANT_A_VALUES_ACTION (Nasal, nasal formant) KlattGRID_GET_FORMANT_FB_VALUES_ACTION (NasalAnti, nasal antiformant) praat_addAction1 (classKlattGrid, 1, U"-- query delta characteristics", 0, 1, 0); KlattGRID_GET_FORMANT_FB_VALUES_ACTION (Delta, delta formant) KlattGRID_GET_FORMANT_FB_VALUES_ACTION (Tracheal, tracheal formant) KlattGRID_GET_FORMANT_A_VALUES_ACTION (Tracheal, tracheal formant) KlattGRID_GET_FORMANT_FB_VALUES_ACTION (TrachealAnti, tracheal antiformant) praat_addAction1 (classKlattGrid, 1, U"-- query frication characteristics", 0, 1, 0); KlattGRID_GET_FORMANT_FB_VALUES_ACTION (Frication, frication formant) KlattGRID_GET_FORMANT_A_VALUES_ACTION (Frication, frication formant) #undef KlattGRID_GET_FORMANT_A_VALUES_ACTION #undef KlattGRID_GET_FORMANT_A_VALUES_ACTION praat_addAction1 (classKlattGrid, 1, U"Get frication bypass at time...", 0, 1, DO_KlattGrid_getFricationBypassAtTime); praat_addAction1 (classKlattGrid, 1, U"Get frication amplitude at time...", 0, 1, DO_KlattGrid_getFricationAmplitudeAtTime); praat_addAction1 (classKlattGrid, 0, U"Modify phonation -", 0, 0, 0); praat_addAction1 (classKlattGrid, 0, U"Add pitch point...", 0, 1, DO_KlattGrid_addPitchPoint); praat_addAction1 (classKlattGrid, 0, U"Add voicing amplitude point...", 0, 1, DO_KlattGrid_addVoicingAmplitudePoint); praat_addAction1 (classKlattGrid, 0, U"Add flutter point...", 0, 1, DO_KlattGrid_addFlutterPoint); praat_addAction1 (classKlattGrid, 0, U"Add power1 point...", 0, 1, DO_KlattGrid_addPower1Point); praat_addAction1 (classKlattGrid, 0, U"Add power2 point...", 0, 1, DO_KlattGrid_addPower2Point); praat_addAction1 (classKlattGrid, 0, U"Add open phase point...", 0, 1, DO_KlattGrid_addOpenPhasePoint); praat_addAction1 (classKlattGrid, 0, U"Add collision phase point...", 0, 1, DO_KlattGrid_addCollisionPhasePoint); praat_addAction1 (classKlattGrid, 0, U"Add double pulsing point...", 0, 1, DO_KlattGrid_addDoublePulsingPoint); praat_addAction1 (classKlattGrid, 0, U"Add spectral tilt point...", 0, 1, DO_KlattGrid_addSpectralTiltPoint); praat_addAction1 (classKlattGrid, 0, U"Add aspiration amplitude point...", 0, 1, DO_KlattGrid_addAspirationAmplitudePoint); praat_addAction1 (classKlattGrid, 0, U"Add breathiness amplitude point...", 0, 1, DO_KlattGrid_addBreathinessAmplitudePoint); #define KlattGrid_REMOVE_POINTS_ACTION(Name,name) \ praat_addAction1 (classKlattGrid, 0, U"Remove " #name " points between...", 0, praat_DEPTH_1+praat_HIDDEN, DO_KlattGrid_remove##Name##Points); \ praat_addAction1 (classKlattGrid, 0, U"Remove " #name " points...", 0, 1, DO_KlattGrid_remove##Name##Points); KlattGrid_REMOVE_POINTS_ACTION (Pitch, pitch) KlattGrid_REMOVE_POINTS_ACTION (VoicingAmplitude, voicing amplitude) KlattGrid_REMOVE_POINTS_ACTION (Flutter, flutter) KlattGrid_REMOVE_POINTS_ACTION (Power1, power1) KlattGrid_REMOVE_POINTS_ACTION (Power2, power2) KlattGrid_REMOVE_POINTS_ACTION (OpenPhase, open phase) KlattGrid_REMOVE_POINTS_ACTION (CollisionPhase, collision phase) KlattGrid_REMOVE_POINTS_ACTION (DoublePulsing, double pulsing) KlattGrid_REMOVE_POINTS_ACTION (SpectralTilt, spectral tilt) KlattGrid_REMOVE_POINTS_ACTION (AspirationAmplitude, aspiration amplitude) KlattGrid_REMOVE_POINTS_ACTION (BreathinessAmplitude, breathiness amplitude) praat_addAction1 (classKlattGrid, 0, U"Modify vocal tract -", 0, 0, 0); #define KlattGrid_MODIFY_ACTIONS_FBA(Name,formantname) \ praat_addAction1 (classKlattGrid, 0, U"Formula (" #formantname " frequencies)...", 0, 1, DO_KlattGrid_formula##Name##FormantFrequencies); \ praat_addAction1 (classKlattGrid, 0, U"Formula (" #formantname " bandwidths)...", 0, 1, DO_KlattGrid_formula##Name##FormantBandwidths); \ praat_addAction1 (classKlattGrid, 0, U"Add " #formantname " frequency point...", 0, 1, DO_KlattGrid_add##Name##FormantFrequencyPoint); \ praat_addAction1 (classKlattGrid, 0, U"Add " #formantname " bandwidth point...", 0, 1, DO_KlattGrid_add##Name##FormantBandwidthPoint); \ praat_addAction1 (classKlattGrid, 0, U"Add " #formantname " amplitude point...", 0, 1, DO_KlattGrid_add##Name##FormantAmplitudePoint); \ praat_addAction1 (classKlattGrid, 0, U"Remove " #formantname " frequency points...", 0, 1, DO_KlattGrid_remove##Name##FormantFrequencyPoints); \ praat_addAction1 (classKlattGrid, 0, U"Remove " #formantname " bandwidth points...", 0, 1, DO_KlattGrid_remove##Name##FormantBandwidthPoints); \ praat_addAction1 (classKlattGrid, 0, U"Remove " #formantname " amplitude points...", 0, 1, DO_KlattGrid_remove##Name##FormantAmplitudePoints); \ praat_addAction1 (classKlattGrid, 0, U"Add " #formantname " frequency and bandwidth tiers...", 0, 1, DO_KlattGrid_add##Name##FormantFrequencyAndBandwidthTiers); \ praat_addAction1 (classKlattGrid, 0, U"Remove " #formantname " frequency and bandwidth tiers...", 0, 1, DO_KlattGrid_remove##Name##FormantFrequencyAndBandwidthTiers); \ praat_addAction1 (classKlattGrid, 0, U"Add " #formantname " amplitude tier...", 0, 1, DO_KlattGrid_add##Name##FormantAmplitudeTier); \ praat_addAction1 (classKlattGrid, 0, U"Remove " #formantname " amplitude tier...", 0, 1, DO_KlattGrid_remove##Name##FormantAmplitudeTier); \ praat_addAction1 (classKlattGrid, 0, U"Add " #formantname "...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_KlattGrid_add##Name##Formant); \ praat_addAction1 (classKlattGrid, 0, U"Remove " #formantname "...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_KlattGrid_remove##Name##Formant); #define KlattGrid_MODIFY_ACTIONS_FB(Name,formantname) \ praat_addAction1 (classKlattGrid, 0, U"Formula (" #formantname " frequencies)...", 0, 1, DO_KlattGrid_formula##Name##FormantFrequencies); \ praat_addAction1 (classKlattGrid, 0, U"Formula (" #formantname " bandwidths)...", 0, 1, DO_KlattGrid_formula##Name##FormantBandwidths); \ praat_addAction1 (classKlattGrid, 0, U"Add " #formantname " frequency point...", 0, 1, DO_KlattGrid_add##Name##FormantFrequencyPoint); \ praat_addAction1 (classKlattGrid, 0, U"Add " #formantname " bandwidth point...", 0, 1, DO_KlattGrid_add##Name##FormantBandwidthPoint); \ praat_addAction1 (classKlattGrid, 0, U"Remove " #formantname " frequency points...", 0, 1, DO_KlattGrid_remove##Name##FormantFrequencyPoints); \ praat_addAction1 (classKlattGrid, 0, U"Remove " #formantname " bandwidth points...", 0, 1, DO_KlattGrid_remove##Name##FormantBandwidthPoints); \ praat_addAction1 (classKlattGrid, 0, U"Add " #formantname " frequency and bandwidth tiers...", 0, 1, DO_KlattGrid_add##Name##FormantFrequencyAndBandwidthTiers); \ praat_addAction1 (classKlattGrid, 0, U"Remove " #formantname " frequency and bandwidth tiers...", 0, 1, DO_KlattGrid_remove##Name##FormantFrequencyAndBandwidthTiers); \ praat_addAction1 (classKlattGrid, 0, U"Add " #formantname "...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_KlattGrid_add##Name##Formant); \ praat_addAction1 (classKlattGrid, 0, U"Remove " #formantname "...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_KlattGrid_remove##Name##Formant); KlattGrid_MODIFY_ACTIONS_FBA (Oral, oral formant) praat_addAction1 (classKlattGrid, 0, U"-- oral modify separator --", 0, 1, 0); KlattGrid_MODIFY_ACTIONS_FBA (Nasal, nasal formant) praat_addAction1 (classKlattGrid, 0, U"-- nasal modify separator --", 0, 1, 0); KlattGrid_MODIFY_ACTIONS_FB (NasalAnti, nasal antiformant) praat_addAction1 (classKlattGrid, 0, U"Formula (frequencies)...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_KlattGrid_formula_frequencies); praat_addAction1 (classKlattGrid, 0, U"Formula (bandwidths)...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_KlattGrid_formula_bandwidths); praat_addAction1 (classKlattGrid, 0, U"Add formant point...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_KlattGrid_addFormantPoint); praat_addAction1 (classKlattGrid, 0, U"Add bandwidth point...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_KlattGrid_addBandwidthPoint); praat_addAction1 (classKlattGrid, 0, U"Add amplitude point...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_KlattGrid_addAmplitudePoint); praat_addAction1 (classKlattGrid, 0, U"Remove formant points between...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_KlattGrid_removeFormantPoints); praat_addAction1 (classKlattGrid, 0, U"Remove bandwidth points between...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_KlattGrid_removeBandwidthPoints); praat_addAction1 (classKlattGrid, 0, U"Remove amplitude points between...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_KlattGrid_removeAmplitudePoints); praat_addAction1 (classKlattGrid, 0, U"Modify coupling - ", 0, 0, 0); KlattGrid_MODIFY_ACTIONS_FB (Delta, delta formant) praat_addAction1 (classKlattGrid, 0, U"-- delta modify separator --", 0, 1, 0); KlattGrid_MODIFY_ACTIONS_FBA (Tracheal, tracheal formant) praat_addAction1 (classKlattGrid, 0, U"-- nasal modify separator --", 0, 1, 0); KlattGrid_MODIFY_ACTIONS_FB (TrachealAnti, tracheal antiformant) praat_addAction1 (classKlattGrid, 0, U"Add delta formant point...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_KlattGrid_addDeltaFormantPoint); praat_addAction1 (classKlattGrid, 0, U"Add delta bandwidth point...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_KlattGrid_addDeltaBandwidthPoint); praat_addAction1 (classKlattGrid, 0, U"Remove delta formant points between...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_KlattGrid_removeDeltaFormantPoints); praat_addAction1 (classKlattGrid, 0, U"Remove delta bandwidth points between...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_KlattGrid_removeDeltaBandwidthPoints); praat_addAction1 (classKlattGrid, 0, U"Modify frication -", 0, 0, 0); KlattGrid_MODIFY_ACTIONS_FBA (Frication, frication formant) praat_addAction1 (classKlattGrid, 0, U"-- frication modify separator --", 0, 1, 0); praat_addAction1 (classKlattGrid, 0, U"Add frication bypass point...", 0, 1, DO_KlattGrid_addFricationBypassPoint); praat_addAction1 (classKlattGrid, 0, U"Add frication amplitude point...", 0, 1, DO_KlattGrid_addFricationAmplitudePoint); KlattGrid_REMOVE_POINTS_ACTION (FricationBypass, frication bypass) KlattGrid_REMOVE_POINTS_ACTION (FricationAmplitude, frication amplitude) praat_addAction1 (classKlattGrid, 0, U"Add formant and bandwidth tier...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_KlattGrid_addFormantAndBandwidthTier); #undef KlattGrid_REMOVE_POINTS_ACTION #undef KlattGrid_MODIFY_ACTION_FB #undef KlattGrid_MODIFY_ACTION_FBA praat_addAction1 (classKlattGrid, 0, U"Extract phonation -", 0, 0, 0); praat_addAction1 (classKlattGrid, 0, U"Extract pitch tier", 0, 1, DO_KlattGrid_extractPitchTier); praat_addAction1 (classKlattGrid, 0, U"Extract voicing amplitude tier", 0, 1, DO_KlattGrid_extractVoicingAmplitudeTier); praat_addAction1 (classKlattGrid, 0, U"Extract flutter tier", 0, 1, DO_KlattGrid_extractFlutterTier); praat_addAction1 (classKlattGrid, 0, U"Extract power1 tier", 0, 1, DO_KlattGrid_extractPower1Tier); praat_addAction1 (classKlattGrid, 0, U"Extract power2 tier", 0, 1, DO_KlattGrid_extractPower2Tier); praat_addAction1 (classKlattGrid, 0, U"Extract open phase tier", 0, 1, DO_KlattGrid_extractOpenPhaseTier); praat_addAction1 (classKlattGrid, 0, U"Extract collision phase tier", 0, 1, DO_KlattGrid_extractCollisionPhaseTier); praat_addAction1 (classKlattGrid, 0, U"Extract double pulsing tier", 0, 1, DO_KlattGrid_extractDoublePulsingTier); praat_addAction1 (classKlattGrid, 0, U"Extract spectral tilt tier", 0, 1, DO_KlattGrid_extractSpectralTiltTier); praat_addAction1 (classKlattGrid, 0, U"Extract aspiration amplitude tier", 0, 1, DO_KlattGrid_extractAspirationAmplitudeTier); praat_addAction1 (classKlattGrid, 0, U"Extract breathiness amplitude tier", 0, 1, DO_KlattGrid_extractBreathinessAmplitudeTier); praat_addAction1 (classKlattGrid, 0, U"-- extract glottal events--", 0, 1, 0); praat_addAction1 (classKlattGrid, 0, U"Extract PointProcess (glottal closures)", 0, 1, DO_KlattGrid_extractPointProcess_glottalClosures); #define KlattGRID_EXTRACT_FORMANT_GRID_ACTION(Name,namef) \ praat_addAction1 (classKlattGrid, 0, U"Extract " #namef "ormant grid", 0, 1, DO_KlattGrid_extract##Name##FormantGrid); #define KlattGRID_EXTRACT_FORMANT_AMPLITUDE_ACTION(Name,name) \ praat_addAction1 (classKlattGrid, 0, U"Extract " #name " formant amplitude tier...", 0, 1, DO_KlattGrid_extract##Name##FormantAmplitudeTier); praat_addAction1 (classKlattGrid, 0, U"Extract filters -", 0, 0, 0); praat_addAction1 (classKlattGrid, 0, U"Extract formant grid...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_KlattGrid_extractFormantGrid); // deprecated KlattGRID_EXTRACT_FORMANT_GRID_ACTION (Oral, oral f) praat_addAction1 (classKlattGrid, 0, U"Extract amplitude tier...", 0, praat_DEPTH_1 + praat_HIDDEN, DO_KlattGrid_extractAmplitudeTier); // deprecated praat_addAction1 (classKlattGrid, 0, U"Extract formant grid (open phases)...", 0, praat_HIDDEN + praat_DEPTH_1, DO_KlattGrid_to_oralFormantGrid_openPhases); praat_addAction1 (classKlattGrid, 0, U"Extract oral formant grid (open phases)...", 0, 1, DO_KlattGrid_to_oralFormantGrid_openPhases); KlattGRID_EXTRACT_FORMANT_AMPLITUDE_ACTION (Oral, oral) KlattGRID_EXTRACT_FORMANT_GRID_ACTION (Nasal, nasal f) KlattGRID_EXTRACT_FORMANT_AMPLITUDE_ACTION (Nasal, nasal) KlattGRID_EXTRACT_FORMANT_GRID_ACTION (NasalAnti, nasal antif) praat_addAction1 (classKlattGrid, 0, U"-- extract delta characteristics", 0, 1, 0); praat_addAction1 (classKlattGrid, 0, U"Extract delta formant grid", 0, 1, DO_KlattGrid_extractDeltaFormantGrid); KlattGRID_EXTRACT_FORMANT_GRID_ACTION (Tracheal, tracheal f) KlattGRID_EXTRACT_FORMANT_AMPLITUDE_ACTION (Tracheal, tracheal) KlattGRID_EXTRACT_FORMANT_GRID_ACTION (TrachealAnti, tracheal antif) praat_addAction1 (classKlattGrid, 0, U"-- extract frication characteristics", 0, 1, 0); KlattGRID_EXTRACT_FORMANT_GRID_ACTION (Frication, frication f) KlattGRID_EXTRACT_FORMANT_AMPLITUDE_ACTION (Frication, frication) praat_addAction1 (classKlattGrid, 0, U"Extract frication bypass tier", 0, 1, DO_KlattGrid_extractFricationBypassTier); praat_addAction1 (classKlattGrid, 0, U"Extract frication amplitude tier", 0, 1, DO_KlattGrid_extractFricationAmplitudeTier); #undef KlattGRID_EXTRACT_FORMANT_AMPLITUDE_ACTION #undef KlattGRID_EXTRACT_FORMANT_GRID_ACTION praat_addAction2 (classKlattGrid, 1, classPitchTier, 1, U"Replace pitch tier", 0, 1, DO_KlattGrid_replacePitchTier); praat_addAction2 (classKlattGrid, 1, classRealTier, 1, U"Replace flutter tier", 0, 1, DO_KlattGrid_replaceFlutterTier); praat_addAction2 (classKlattGrid, 1, classRealTier, 1, U"Replace power1 tier", 0, 1, DO_KlattGrid_replacePower1Tier); praat_addAction2 (classKlattGrid, 1, classRealTier, 1, U"Replace power2 tier", 0, 1, DO_KlattGrid_replacePower2Tier); praat_addAction2 (classKlattGrid, 1, classRealTier, 1, U"Replace open phase tier", 0, 1, DO_KlattGrid_replaceOpenPhaseTier); praat_addAction2 (classKlattGrid, 1, classRealTier, 1, U"Replace collision phase tier", 0, 1, DO_KlattGrid_replaceCollisionPhaseTier); praat_addAction2 (classKlattGrid, 1, classRealTier, 1, U"Replace double pulsing tier", 0, 1, DO_KlattGrid_replaceDoublePulsingTier); praat_addAction2 (classKlattGrid, 1, classIntensityTier, 1, U"-- replace formant amplitudes --", 0, 1, 0); #define KlattGrid_REPLACE_FORMANTGRID_ACTION(Name,namef) \ praat_addAction2 (classKlattGrid, 1, classFormantGrid, 1, U"Replace " #namef "ormant grid", 0, 1, DO_KlattGrid_replace##Name##FormantGrid); #define KlattGrid_REPLACE_FORMANT_AMPLITUDE_ACTION(Name,namef) \ praat_addAction2 (classKlattGrid, 1, classIntensityTier, 1, U"Replace " #namef "ormant amplitude tier...", 0, 1, DO_KlattGrid_replace##Name##FormantAmplitudeTier); KlattGrid_REPLACE_FORMANTGRID_ACTION (Oral, oral f) KlattGrid_REPLACE_FORMANTGRID_ACTION (Nasal, nasal f) KlattGrid_REPLACE_FORMANTGRID_ACTION (NasalAnti, nasal antif) praat_addAction2 (classKlattGrid, 1, classFormantGrid, 1, U"-- replace coupling --", 0, 1, 0); KlattGrid_REPLACE_FORMANTGRID_ACTION (Tracheal, tracheal f) KlattGrid_REPLACE_FORMANTGRID_ACTION (TrachealAnti, tracheal antif) KlattGrid_REPLACE_FORMANTGRID_ACTION (Delta, delta f) praat_addAction2 (classKlattGrid, 1, classFormantGrid, 1, U"-- replace frication --", 0, 1, 0); KlattGrid_REPLACE_FORMANTGRID_ACTION (Frication, frication f) praat_addAction2 (classKlattGrid, 1, classFormantGrid, 1, U"Replace formant grid...", 0, praat_HIDDEN + praat_DEPTH_1, DO_KlattGrid_replaceFormantGrid); praat_addAction2 (classKlattGrid, 1, classIntensityTier, 1, U"Replace voicing amplitude tier", 0, 1, DO_KlattGrid_replaceVoicingAmplitudeTier); praat_addAction2 (classKlattGrid, 1, classIntensityTier, 1, U"Replace spectral tilt tier", 0, 1, DO_KlattGrid_replaceSpectralTiltTier); praat_addAction2 (classKlattGrid, 1, classIntensityTier, 1, U"Replace aspiration amplitude tier", 0, 1, DO_KlattGrid_replaceAspirationAmplitudeTier); praat_addAction2 (classKlattGrid, 1, classIntensityTier, 1, U"Replace breathiness amplitude tier", 0, 1, DO_KlattGrid_replaceBreathinessAmplitudeTier); praat_addAction2 (classKlattGrid, 1, classIntensityTier, 1, U"Replace amplitude tier...", 0, praat_HIDDEN + praat_DEPTH_1, DO_KlattGrid_replaceAmplitudeTier); KlattGrid_REPLACE_FORMANT_AMPLITUDE_ACTION (Oral, oral f) KlattGrid_REPLACE_FORMANT_AMPLITUDE_ACTION (Nasal, nasal f) KlattGrid_REPLACE_FORMANT_AMPLITUDE_ACTION (Tracheal, tracheal f) KlattGrid_REPLACE_FORMANT_AMPLITUDE_ACTION (Frication, frication f) praat_addAction2 (classKlattGrid, 1, classIntensityTier, 1, U"Replace frication amplitude tier", 0, 1, DO_KlattGrid_replaceFricationAmplitudeTier); praat_addAction2 (classKlattGrid, 1, classIntensityTier, 1, U"Replace frication bypass tier", 0, 1, DO_KlattGrid_replaceFricationBypassTier); #undef KlattGrid_REPLACE_FORMANT_AMPLITUDE_ACTION #undef KlattGrid_REPLACE_FORMANTGRID_ACTION praat_addAction2 (classKlattGrid, 1, classSound, 1, U"Filter by vocal tract...", 0, 1, DO_Sound_KlattGrid_filterByVocalTract); INCLUDE_MANPAGES (manual_KlattGrid) } /* End of file praat_KlattGrid_init.cpp */ praat-6.0.04/dwtools/praat_MDS_init.cpp000066400000000000000000002277151261542461700177720ustar00rootroot00000000000000/* praat_MDS_init.cpp * * Copyright (C) 1992-2012, 2015 David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* djmw 20020408 GPL djmw 20020408 Added MDS-tutorial djmw 20020603 Changes due to TableOfReal dynamic menu changes. djmw 20040415 Forms texts. djmw 20040513 More forms text changes djmw 20041027 Orhogonal transform parameter for Configurations_to_Procrustes djmw 20050406 classProcrustus -> classProcrustes. djmw 20050426 Removed "Procrustus.h" djmw 20050630 Better name of Procrustes object after Configurations_to_Procrustes. djmw 20061218 Introduction of Melder_information<12...9> djmw 20070902 Melder_new<1...> djmw 20071011 REQUIRE requires U"". djmw 20090818 Thing_recognizeClassesByName: added classAffineTransform, classScalarProduct, classWeight */ #include #include "NUM2.h" #include "praat.h" #include "MDS.h" #include "ContingencyTable.h" #include "TableOfReal_extensions.h" #include "Configuration_and_Procrustes.h" #include "Configuration_AffineTransform.h" #include "Confusion.h" #include "Formula.h" void praat_TableOfReal_init (ClassInfo klas); void praat_TableOfReal_init2 (ClassInfo klas); static const char32 *QUERY_BUTTON = U"Query -"; static const char32 *DRAW_BUTTON = U"Draw -"; static const char32 *ANALYSE_BUTTON = U"Analyse -"; static const char32 *CONFIGURATION_BUTTON = U"To Configuration -"; /* Tests */ /* Sort row 1 ascending and store in row 3 Sort row 1 and move row 2 along and store in rows 4 and 5 respectively Make an index for row 1 and store in row 6 */ static void TabelOfReal_testSorting (I, long rowtoindex) { iam (TableOfReal); try { long nc = my numberOfColumns; autoNUMvector index (1, nc); if (my numberOfRows < 6) { Melder_throw (U"TabelOfReal_sort2: we want at least 6 rows!!"); } if (rowtoindex < 1 || rowtoindex > 2) { Melder_throw (U"TabelOfReal_sort2: rowtoindex <= 2"); } // Copy 1->3 and sort 3 inplace NUMvector_copyElements (my data[1], my data[3], 1, nc); NUMsort_d (nc, my data[3]); // Copy 1->4 and 2->5, sort 4+5 in parallel NUMvector_copyElements (my data[1], my data[4], 1, nc); NUMvector_copyElements (my data[2], my data[5], 1, nc); NUMsort2 (nc, my data[4], my data[5]); NUMindexx (my data[rowtoindex], nc, index.peek()); for (long i = 1; i <= nc; i++) { my data[6][i] = index[i]; } } catch (MelderError) { Melder_throw (me, U": sorting test not ok."); } } #undef iam #define iam iam_LOOP FORM (TabelOfReal_testSorting, U"TabelOfReal: Sort and index", U"") NATURAL (U"Row to index", U"1") OK DO LOOP { iam (TableOfReal); TabelOfReal_testSorting (me, GET_INTEGER (U"Row to index")); } END /************************* examples ***************************************/ FORM (Dissimilarity_createLetterRExample, U"Create letter R example", U"Create letter R example...") LABEL (U"", U"For the monotone transformation on the distances") REAL (U"Noise range", U"32.5") OK DO praat_new (Dissimilarity_createLetterRExample (GET_REAL (U"Noise range")), U""); END FORM (INDSCAL_createCarrollWishExample, U"Create INDSCAL Carroll & Wish example...", U"Create INDSCAL Carroll & Wish example...") REAL (U"Noise standard deviation", U"0.0") OK DO praat_new (INDSCAL_createCarrollWishExample (GET_REAL (U"Noise standard deviation")), U""); END FORM (Configuration_create, U"Create Configuration", U"Create Configuration...") WORD (U"Name", U"uniform") NATURAL (U"Number of points", U"10") NATURAL (U"Number of dimensions", U"2") LABEL (U"", U"Formula:") TEXTFIELD (U"formula", U"randomUniform(-1.5, 1.5)") OK DO autoConfiguration me = Configuration_create (GET_INTEGER (U"Number of points"), GET_INTEGER (U"Number of dimensions")); TableOfReal_formula (me.peek(), GET_STRING (U"formula"), interpreter, 0); praat_new (me.transfer(), GET_STRING (U"Name")); END FORM (drawSplines, U"Draw splines", U"spline") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"1.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"20.0") RADIO (U"Spline type", 1) RADIOBUTTON (U"M-spline") RADIOBUTTON (U"I-spline") INTEGER (U"Order", U"3") SENTENCE (U"Interior knots", U"0.3 0.5 0.6") BOOLEAN (U"Garnish", 1) OK DO double xmin = GET_REAL (U"left Horizontal range"), xmax = GET_REAL (U"right Horizontal range"); double ymin = GET_REAL (U"left Vertical range"), ymax = GET_REAL (U"right Vertical range"); if (xmax <= xmin or ymax <= ymin) { Melder_throw (U"Required: xmin < xmax and ymin < ymax."); } autoPraatPicture picture; drawSplines (GRAPHICS, xmin, xmax, ymin, ymax, GET_INTEGER (U"Spline type"), GET_INTEGER (U"Order"), GET_STRING (U"Interior knots"), GET_INTEGER (U"Garnish")); END DIRECT (drawMDSClassRelations) autoPraatPicture picture; drawMDSClassRelations (GRAPHICS); END /***************** AffineTransform ***************************************/ DIRECT (AffineTransform_help) Melder_help (U"AffineTransform"); END DIRECT (AffineTransform_invert) LOOP { iam (AffineTransform); praat_new ( (AffineTransform) AffineTransform_invert (me), NAME, U"_inv"); } END FORM (AffineTransform_getTransformationElement, U"AffineTransform: Get transformation element", U"Procrustes") NATURAL (U"Row number", U"1") NATURAL (U"Column number", U"1") OK DO long row = GET_INTEGER (U"Row number"); long column = GET_INTEGER (U"Column number"); LOOP { iam (AffineTransform); if (row > my n) { Melder_throw (U"Row number must not exceed number of rows."); } if (column > my n) { Melder_throw (U"Column number must not exceed number of columns."); } Melder_information (my r [row] [column]); } END FORM (AffineTransform_getTranslationElement, U"AffineTransform: Get translation element", U"Procrustes") NATURAL (U"Index", U"1") OK DO long number = GET_INTEGER (U"Index"); LOOP { iam (AffineTransform); if (number > my n) { Melder_throw (U"Index must not exceed number of elements."); } Melder_information (my t [number]); } END DIRECT (AffineTransform_extractMatrix) LOOP { iam (AffineTransform); autoTableOfReal thee = AffineTransform_extractMatrix (me); praat_new (thee.transfer(), my name); } END DIRECT (AffineTransform_extractTranslationVector) LOOP { iam (AffineTransform); autoTableOfReal thee = AffineTransform_extractTranslationVector (me); praat_new (thee.transfer(), my name); } END /***************** Configuration ***************************************/ DIRECT (Configuration_help) Melder_help (U"Configuration"); END static void Configuration_draw_addCommonFields (UiForm dia) { NATURAL (U"Horizontal dimension", U"1") NATURAL (U"Vertical dimension", U"2") REAL (U"left Horizontal range", U"0.0") REAL (U"right Horizontal range", U"0.0") REAL (U"left Vertical range", U"0.0") REAL (U"right Vertical range", U"0.0") } FORM (Configuration_draw, U"Configuration: Draw", U"Configuration: Draw...") Configuration_draw_addCommonFields (dia); NATURAL (U"Label size", U"12") BOOLEAN (U"Use row labels", 0) WORD (U"Label", U"+") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (Configuration); Configuration_draw (me, GRAPHICS, GET_INTEGER (U"Horizontal dimension"), GET_INTEGER (U"Vertical dimension"), GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Label size"), GET_INTEGER (U"Use row labels"), GET_STRING (U"Label"), GET_INTEGER (U"Garnish")); } END FORM (Configuration_drawSigmaEllipses, U"Configuration: Draw sigma ellipses", U"Configuration: Draw sigma ellipses...") POSITIVE (U"Number of sigmas", U"1.0") Configuration_draw_addCommonFields (dia); INTEGER (U"Label size", U"12") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (Configuration); Configuration_drawConcentrationEllipses (me, GRAPHICS, GET_REAL (U"Number of sigmas"), 0, 0, GET_INTEGER (U"Horizontal dimension"), GET_INTEGER (U"Vertical dimension"), GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Label size"), GET_INTEGER (U"Garnish")); } END FORM (Configuration_drawOneSigmaEllipse, U"Configuration: Draw one sigma ellipse", U"Configuration: Draw sigma ellipses...") SENTENCE (U"Label", U"") POSITIVE (U"Number of sigmas", U"1.0") Configuration_draw_addCommonFields (dia); INTEGER (U"Label size", U"12") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (Configuration); Configuration_drawConcentrationEllipses (me, GRAPHICS, GET_REAL (U"Number of sigmas"), 0, GET_STRING (U"Label"), GET_INTEGER (U"Horizontal dimension"), GET_INTEGER (U"Vertical dimension"), GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Label size"), GET_INTEGER (U"Garnish")); } END FORM (Configuration_drawConfidenceEllipses, U"Configuration: Draw confidence ellipses", 0) POSITIVE (U"Confidence level (0-1)", U"0.95") Configuration_draw_addCommonFields (dia); INTEGER (U"Label size", U"12") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (Configuration); Configuration_drawConcentrationEllipses (me, GRAPHICS, GET_REAL (U"Confidence level"), 1, 0, GET_INTEGER (U"Horizontal dimension"), GET_INTEGER (U"Vertical dimension"), GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Label size"), GET_INTEGER (U"Garnish")); } END FORM (Configuration_drawOneConfidenceEllipse, U"Configuration: Draw one confidence ellipse", 0) SENTENCE (U"Label", U"") POSITIVE (U"Confidence level (0-1)", U"0.95") Configuration_draw_addCommonFields (dia); INTEGER (U"Label size", U"12") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; LOOP { iam (Configuration); Configuration_drawConcentrationEllipses (me, GRAPHICS, GET_REAL (U"Confidence level"), 1, GET_STRING (U"Label"), GET_INTEGER (U"Horizontal dimension"), GET_INTEGER (U"Vertical dimension"), GET_REAL (U"left Horizontal range"), GET_REAL (U"right Horizontal range"), GET_REAL (U"left Vertical range"), GET_REAL (U"right Vertical range"), GET_INTEGER (U"Label size"), GET_INTEGER (U"Garnish")); } END DIRECT (Configuration_randomize) LOOP { iam (Configuration); Configuration_randomize (me); } END FORM (Configuration_normalize, U"Configuration: Normalize", U"Configuration: Normalize...") REAL (U"Sum of squares", U"0.0") LABEL (U"", U"On (INDSCAL), Off (Kruskal)") BOOLEAN (U"Each dimension separately", 1) OK DO LOOP { iam (Configuration); Configuration_normalize (me, GET_REAL (U"Sum of squares"), GET_INTEGER (U"Each dimension separately")); } END DIRECT (Configuration_centralize) LOOP { iam (Configuration); TableOfReal_centreColumns (me); } END FORM (Configuration_rotate, U"Configuration: Rotate", U"Configuration: Rotate...") NATURAL (U"Dimension 1", U"1") NATURAL (U"Dimension 2", U"2") REAL (U"Angle (degrees)", U"60.0") OK DO LOOP { iam (Configuration); Configuration_rotate (me, GET_INTEGER (U"Dimension 1"), GET_INTEGER (U"Dimension 2"), GET_REAL (U"Angle")); } END DIRECT (Configuration_rotateToPrincipalDirections) LOOP { iam (Configuration); Configuration_rotateToPrincipalDirections (me); } END FORM (Configuration_invertDimension, U"Configuration: Invert dimension", U"Configuration: Invert dimension...") NATURAL (U"Dimension", U"1") OK DO LOOP { iam (Configuration); Configuration_invertDimension (me, GET_INTEGER (U"Dimension")); } END DIRECT (Configuration_to_Distance) LOOP { iam (Configuration); praat_new (Configuration_to_Distance (me), my name); } END FORM (Configuration_varimax, U"Configuration: To Configuration (varimax)", U"Configuration: To Configuration (varimax)...") BOOLEAN (U"Normalize rows", 1) BOOLEAN (U"Quartimax", 0) NATURAL (U"Maximum number of iterations", U"50") POSITIVE (U"Tolerance", U"1e-6") OK DO LOOP { iam (Configuration); autoConfiguration thee = Configuration_varimax (me, GET_INTEGER (U"Normalize rows"), GET_INTEGER (U"Quartimax"), GET_INTEGER (U"Maximum number of iterations"), GET_REAL (U"Tolerance")); praat_new (thee.transfer(), my name, U"_varimax"); } END DIRECT (Configurations_to_Similarity_cc) autoConfigurations set = (Configurations) praat_getSelectedObjects (); praat_new (Configurations_to_Similarity_cc (set.peek(), 0), U"congruence"); END FORM (Configurations_to_Procrustes, U"Configuration & Configuration: To Procrustes", U"Configuration & Configuration: To Procrustes...") BOOLEAN (U"Orthogonal transform", 0) OK DO Configuration c1 = 0, c2 = 0; LOOP { iam (Configuration); (c1 ? c2 : c1) = me; } Melder_assert (c1 && c2); autoProcrustes thee = Configurations_to_Procrustes (c1, c2, GET_INTEGER (U"Orthogonal transform")); praat_new (thee.transfer(), Thing_getName (c2), U"_to_", Thing_getName (c1)); END FORM (Configurations_to_AffineTransform_congruence, U"Configurations: To AffineTransform (congruence)", U"Configurations: To AffineTransform (congruence)...") NATURAL (U"Maximum number of iterations", U"50") POSITIVE (U"Tolerance", U"1e-6") OK DO Configuration c1 = 0, c2 = 0; LOOP { iam (Configuration); (c1 ? c2 : c1) = me; } Melder_assert (c1 && c2); autoAffineTransform thee = Configurations_to_AffineTransform_congruence (c1, c2, GET_INTEGER (U"Maximum number of iterations"), GET_REAL (U"Tolerance")); praat_new (thee.transfer(), c1 -> name, U"_", c2 -> name); END DIRECT (Configuration_Weight_to_Similarity_cc) autoConfigurations thee = Configurations_create (); Collection_dontOwnItems (thee.peek()); Weight w = 0; LOOP { iam (Daata); if (CLASS == classConfiguration) { Collection_addItem (thee.peek(), me); } else if (CLASS == classWeight) { w = (Weight) me; } } Melder_assert (thy size > 0 && w); praat_new (Configurations_to_Similarity_cc (thee.peek(), w), U"congruence"); END DIRECT (Configuration_and_AffineTransform_to_Configuration) Configuration me = FIRST (Configuration); AffineTransform at = FIRST_GENERIC (AffineTransform); autoConfiguration thee = Configuration_and_AffineTransform_to_Configuration (me, at); praat_new (thee.transfer(), my name, U"_", at -> name); END /*************** Confusion *********************************/ FORM (Confusion_to_Dissimilarity_pdf, U"Confusion: To Dissimilarity (pdf)", U"Confusion: To Dissimilarity (pdf)...") POSITIVE (U"Minimum confusion level", U"0.5") OK DO LOOP { iam (Confusion); praat_new (Confusion_to_Dissimilarity_pdf (me, GET_REAL (U"Minimum confusion level")), my name, U"_pdf"); } END FORM (Confusion_to_Similarity, U"Confusion: To Similarity", U"Confusion: To Similarity...") BOOLEAN (U"Normalize", 1) RADIO (U"Symmetrization", 1) RADIOBUTTON (U"No symmetrization") RADIOBUTTON (U"Average (s[i][j] = (c[i][j]+c[j][i])/2)") RADIOBUTTON (U"Houtgast (s[i][j]= sum (min(c[i][k],c[j][k])))") OK DO LOOP { iam (Confusion); praat_new (Confusion_to_Similarity (me, GET_INTEGER (U"Normalize"), GET_INTEGER (U"Symmetrization")), my name); } END DIRECT (Confusions_sum) autoConfusions me = (Confusions) praat_getSelectedObjects (); praat_new (Confusions_sum (me.peek()), U"sum"); END DIRECT (Confusion_to_ContingencyTable) LOOP { iam (Confusion); autoContingencyTable thee = Confusion_to_ContingencyTable (me); praat_new (thee.transfer(), my name); } END /*************** ContingencyTable *********************************/ FORM (ContingencyTable_to_Configuration_ca, U"ContingencyTable: To Configuration (ca)", U"ContingencyTable: To Configuration (ca)...") NATURAL (U"Number of dimensions", U"2") RADIO (U"Scaling of final configuration", 3) RADIOBUTTON (U"Row points in centre of gravity of column points") RADIOBUTTON (U"Column points in centre of gravity of row points") RADIOBUTTON (U"Row points and column points symmetric") OK DO LOOP { iam (ContingencyTable); praat_new (ContingencyTable_to_Configuration_ca (me, GET_INTEGER (U"Number of dimensions"), GET_INTEGER (U"Scaling of final configuration")), my name); } END DIRECT (ContingencyTable_chisqProbability) LOOP { iam (ContingencyTable); Melder_information (ContingencyTable_chisqProbability (me)); } END DIRECT (ContingencyTable_cramersStatistic) LOOP { iam (ContingencyTable); Melder_information (ContingencyTable_cramersStatistic (me)); } END DIRECT (ContingencyTable_contingencyCoefficient) LOOP { iam (ContingencyTable); Melder_information (ContingencyTable_contingencyCoefficient (me)); } END /************************* Correlation ***********************************/ FORM (Correlation_to_Configuration, U"Correlation: To Configuration", 0) NATURAL (U"Number of dimensions", U"2") OK DO LOOP { iam (Correlation); praat_new (Correlation_to_Configuration (me, GET_INTEGER (U"Number of dimensions")), my name); } END /************************* Similarity ***************************************/ DIRECT (Similarity_help) Melder_help (U"Similarity"); END FORM (Similarity_to_Dissimilarity, U"Similarity: To Dissimilarity", U"Similarity: To Dissimilarity...") REAL (U"Maximum dissimilarity", U"0.0 (=from data)") OK DO LOOP { iam (Similarity); praat_new (Similarity_to_Dissimilarity (me, GET_REAL (U"Maximum dissimilarity")), my name); } END /**************** Dissimilarity ***************************************/ static void Dissimilarity_to_Configuration_addCommonFields (UiForm dia) { LABEL (U"", U"Minimization parameters") REAL (U"Tolerance", U"1e-5") NATURAL (U"Maximum number of iterations", U"50 (= each repetition)") NATURAL (U"Number of repetitions", U"1") } static void Dissimilarity_and_Configuration_getStress_addCommonFields (UiForm dia, void *radio) { RADIO (U"Stress measure", 1) RADIOBUTTON (U"Normalized") RADIOBUTTON (U"Kruskal's stress-1") RADIOBUTTON (U"Kruskal's stress-2") RADIOBUTTON (U"Raw") } static void Dissimilarity_Configuration_drawDiagram_addCommonFields (UiForm dia) { REAL (U"left Proximity range", U"0.0") REAL (U"right Proximity range", U"0.0") REAL (U"left Distance range", U"0.0") REAL (U"right Distance range", U"0.0") POSITIVE (U"Mark size (mm)", U"1.0") SENTENCE (U"Mark string (+xo.)", U"+") BOOLEAN (U"Garnish", 1) } DIRECT (Dissimilarity_help) Melder_help (U"Dissimilarity"); END DIRECT (Dissimilarity_getAdditiveConstant) LOOP { iam (Dissimilarity); double c = Dissimilarity_getAdditiveConstant (me); Melder_information (c); } END FORM (Dissimilarity_Configuration_kruskal, U"Dissimilarity & Configuration: To Configuration (kruskal)", U"Dissimilarity & Configuration: To Configuration (kruskal)...") RADIO (U"Handling of ties", 1) RADIOBUTTON (U"Primary approach") RADIOBUTTON (U"Secondary approach") RADIO (U"Stress calculation", 1) RADIOBUTTON (U"Formula1") RADIOBUTTON (U"Formula2") Dissimilarity_to_Configuration_addCommonFields (dia); OK DO Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); praat_new (Dissimilarity_Configuration_kruskal (me, c, GET_INTEGER (U"Handling of ties"), GET_INTEGER (U"Stress calculation"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Maximum number of iterations"), GET_INTEGER (U"Number of repetitions")), my name, U"_kruskal"); END FORM (Dissimilarity_Configuration_absolute_mds, U"Dissimilarity & Configuration: To Configuration (absolute mds)", U"Dissimilarity & Configuration: To Configuration (absolute mds)...") Dissimilarity_to_Configuration_addCommonFields (dia); OK DO Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); int showProgress = 1; praat_new (Dissimilarity_Configuration_Weight_absolute_mds (me, c, 0, GET_REAL (U"Tolerance"), GET_INTEGER (U"Maximum number of iterations"), GET_INTEGER (U"Number of repetitions"), showProgress), my name, U"_absolute"); END FORM (Dissimilarity_Configuration_ratio_mds, U"Dissimilarity & Configuration: To Configuration (ratio mds)", U"Dissimilarity & Configuration: To Configuration (ratio mds)...") Dissimilarity_to_Configuration_addCommonFields (dia); OK DO Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); int showProgress = 1; praat_new (Dissimilarity_Configuration_Weight_ratio_mds (me, c, 0, GET_REAL (U"Tolerance"), GET_INTEGER (U"Maximum number of iterations"), GET_INTEGER (U"Number of repetitions"), showProgress), my name, U"_ratio"); END FORM (Dissimilarity_Configuration_interval_mds, U"Dissimilarity & Configuration: To Configuration (interval mds)", U"Dissimilarity & Configuration: To Configuration (interval mds)...") Dissimilarity_to_Configuration_addCommonFields (dia); OK DO Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); int showProgress = 1; praat_new (Dissimilarity_Configuration_Weight_interval_mds (me, c, 0, GET_REAL (U"Tolerance"), GET_INTEGER (U"Maximum number of iterations"), GET_INTEGER (U"Number of repetitions"), showProgress), my name, U"_interval"); END FORM (Dissimilarity_Configuration_monotone_mds, U"Dissimilarity & Configuration: To Configuration (monotone mds)", U"Dissimilarity & Configuration: To Configuration (monotone mds)...") RADIO (U"Handling of ties", 1) RADIOBUTTON (U"Primary approach") RADIOBUTTON (U"Secondary approach") Dissimilarity_to_Configuration_addCommonFields (dia); OK DO Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); int showProgress = 1; praat_new (Dissimilarity_Configuration_Weight_monotone_mds (me, c, 0, GET_INTEGER (U"Handling of ties"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Maximum number of iterations"), GET_INTEGER (U"Number of repetitions"), showProgress), my name, U"_monotone"); END FORM (Dissimilarity_Configuration_ispline_mds, U"Dissimilarity & Configuration: To Configuration (i-spline mds)", U"Dissimilarity & Configuration: To Configuration (i-spline mds)...") LABEL (U"", U"Spline smoothing") INTEGER (U"Number of interior knots", U"1") INTEGER (U"Order of I-spline", U"1") Dissimilarity_to_Configuration_addCommonFields (dia); OK DO Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); int showProgress = 1; praat_new (Dissimilarity_Configuration_Weight_ispline_mds (me, c, 0, GET_INTEGER (U"Number of interior knots"), GET_INTEGER (U"Order of I-spline"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Maximum number of iterations"), GET_INTEGER (U"Number of repetitions"), showProgress), my name, U"_ispline"); END FORM (Dissimilarity_Configuration_Weight_absolute_mds, U"Dissimilarity & Configuration & Weight: To Configuration (absolute mds)", U"Dissimilarity & Configuration & Weight: To Configuration...") Dissimilarity_to_Configuration_addCommonFields (dia); OK DO Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); Weight w = FIRST (Weight); int showProgress = 1; praat_new (Dissimilarity_Configuration_Weight_absolute_mds (me, c, w, GET_REAL (U"Tolerance"), GET_INTEGER (U"Maximum number of iterations"), GET_INTEGER (U"Number of repetitions"), showProgress), my name, U"_w_absolute"); END FORM (Dissimilarity_Configuration_Weight_ratio_mds, U"Dissimilarity & Configuration & Weight: To Configuration (ratio mds)", U"Dissimilarity & Configuration & Weight: To Configuration...") Dissimilarity_to_Configuration_addCommonFields (dia); OK DO Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); Weight w = FIRST (Weight); int showProgress = 1; praat_new (Dissimilarity_Configuration_Weight_ratio_mds (me, c, w, GET_REAL (U"Tolerance"), GET_INTEGER (U"Maximum number of iterations"), GET_INTEGER (U"Number of repetitions"), showProgress), my name, U"_w_ratio"); END FORM (Dissimilarity_Configuration_Weight_interval_mds, U"Dissimilarity & Configuration & Weight: To Configuration (interval mds)", U"Dissimilarity & Configuration & Weight: To Configuration...") Dissimilarity_to_Configuration_addCommonFields (dia); OK DO Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); Weight w = FIRST (Weight); int showProgress = 1; praat_new (Dissimilarity_Configuration_Weight_interval_mds (me, c, w, GET_REAL (U"Tolerance"), GET_INTEGER (U"Maximum number of iterations"), GET_INTEGER (U"Number of repetitions"), showProgress), my name, U"_w_interval"); END FORM (Dissimilarity_Configuration_Weight_monotone_mds, U"Dissimilarity & Configuration & Weight: To Configuration (monotone mds)", U"Dissimilarity & Configuration & Weight: To Configuration...") RADIO (U"Handling of ties", 1) RADIOBUTTON (U"Primary approach") RADIOBUTTON (U"Secondary approach") Dissimilarity_to_Configuration_addCommonFields (dia); OK DO Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); Weight w = FIRST (Weight); int showProgress = 1; praat_new (Dissimilarity_Configuration_Weight_monotone_mds (me, c, w, GET_INTEGER (U"Handling of ties"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Maximum number of iterations"), GET_INTEGER (U"Number of repetitions"), showProgress), my name, U"_sw_monotone"); END FORM (Dissimilarity_Configuration_Weight_ispline_mds, U"Dissimilarity & Configuration & Weight: To Configuration (i-spline mds)", U"Dissimilarity & Configuration & Weight: To Configuration...") LABEL (U"", U"Spline smoothing") INTEGER (U"Number of interior knots", U"1") INTEGER (U"Order of I-spline", U"1") Dissimilarity_to_Configuration_addCommonFields (dia); OK DO Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); Weight w = FIRST (Weight); int showProgress = 1; praat_new (Dissimilarity_Configuration_Weight_ispline_mds (me, c, w, GET_INTEGER (U"Number of interior knots"), GET_INTEGER (U"Order of I-spline"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Maximum number of iterations"), GET_INTEGER (U"Number of repetitions"), showProgress), my name, U"_sw_ispline"); END FORM (Dissimilarity_Configuration_getStress, U"Dissimilarity & Configuration: Get stress", U"Dissimilarity & Configuration: get stress") RADIO (U"Handling of ties", 1) RADIOBUTTON (U"Primary approach") RADIOBUTTON (U"Secondary approach") RADIO (U"Stress calculation", 1) RADIOBUTTON (U"Formula1") RADIOBUTTON (U"Formula2") OK DO Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); Melder_information (Dissimilarity_Configuration_getStress (me, c, GET_INTEGER (U"Handling of ties"), GET_INTEGER (U"Stress calculation"))); END FORM (Dissimilarity_Configuration_absolute_stress, U"Dissimilarity & Configuration: Get stress (absolute mds)", U"Dissimilarity & Configuration: Get stress (absolute mds)...") Dissimilarity_and_Configuration_getStress_addCommonFields (dia, radio); OK DO Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); Melder_information (Dissimilarity_Configuration_Weight_absolute_stress (me, c, 0, GET_INTEGER (U"Stress measure"))); END FORM (Dissimilarity_Configuration_ratio_stress, U"Dissimilarity & Configuration: Get stress (ratio mds)", U"Dissimilarity & Configuration: Get stress (ratio mds)...") Dissimilarity_and_Configuration_getStress_addCommonFields (dia, radio); OK DO Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); Melder_information (Dissimilarity_Configuration_Weight_ratio_stress (me, c, 0, GET_INTEGER (U"Stress measure"))); END FORM (Dissimilarity_Configuration_interval_stress, U"Dissimilarity & Configuration: Get stress (interval mds)", U"Dissimilarity & Configuration: Get stress (interval mds)...") Dissimilarity_and_Configuration_getStress_addCommonFields (dia, radio); OK DO Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); Melder_information (Dissimilarity_Configuration_Weight_interval_stress (me, c, 0, GET_INTEGER (U"Stress measure"))); END FORM (Dissimilarity_Configuration_monotone_stress, U"Dissimilarity & Configuration: Get stress (monotone mds)", U"Dissimilarity & Configuration: Get stress (monotone mds)...") RADIO (U"Handling of ties", 1) RADIOBUTTON (U"Primary approach") RADIOBUTTON (U"Secondary approach") Dissimilarity_and_Configuration_getStress_addCommonFields (dia, radio); OK DO Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); Melder_information (Dissimilarity_Configuration_Weight_monotone_stress (me, c, 0, GET_INTEGER (U"Handling of ties"), GET_INTEGER (U"Stress measure"))); END FORM (Dissimilarity_Configuration_ispline_stress, U"Dissimilarity & Configuration: Get stress (i-spline mds)", U"Dissimilarity & Configuration: Get stress (i-spline mds)...") INTEGER (U"Number of interior knots", U"1") INTEGER (U"Order of I-spline", U"3") Dissimilarity_and_Configuration_getStress_addCommonFields (dia, radio); OK DO Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); Melder_information (Dissimilarity_Configuration_Weight_ispline_stress (me, c, 0, GET_INTEGER (U"Number of interior knots"), GET_INTEGER (U"Order of I-spline"), GET_INTEGER (U"Stress measure"))); END FORM (Dissimilarity_Configuration_Weight_absolute_stress, U"Dissimilarity & Configuration & Weight: Get stress (absolute mds)", U"Dissimilarity & Configuration & Weight: Get stress (absolute mds)...") Dissimilarity_and_Configuration_getStress_addCommonFields (dia, radio); OK DO Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); Weight w = FIRST (Weight); Melder_information (Dissimilarity_Configuration_Weight_absolute_stress (me, c, w, GET_INTEGER (U"Stress measure"))); END FORM (Dissimilarity_Configuration_Weight_ratio_stress, U"Dissimilarity & Configuration & Weight: Get stress (ratio mds)", U"Dissimilarity & Configuration & Weight: Get stress (ratio mds)...") Dissimilarity_and_Configuration_getStress_addCommonFields (dia, radio); OK DO Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); Weight w = FIRST (Weight); Melder_information (Dissimilarity_Configuration_Weight_ratio_stress (me, c, w, GET_INTEGER (U"Stress measure"))); END FORM (Dissimilarity_Configuration_Weight_interval_stress, U"Dissimilarity & Configuration & Weight: Get stress (interval mds)", U"Dissimilarity & Configuration & Weight: Get stress (interval mds)...") Dissimilarity_and_Configuration_getStress_addCommonFields (dia, radio); OK DO Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); Weight w = FIRST (Weight); Melder_information (Dissimilarity_Configuration_Weight_interval_stress (me, c, w, GET_INTEGER (U"Stress measure"))); END FORM (Dissimilarity_Configuration_Weight_monotone_stress, U"Dissimilarity & Configuration & Weight: Get stress (monotone mds)", U"Dissimilarity & Configuration & Weight: Get stress (monotone mds)...") RADIO (U"Handling of ties", 1) RADIOBUTTON (U"Primary approach)") RADIOBUTTON (U"Secondary approach") Dissimilarity_and_Configuration_getStress_addCommonFields (dia, radio); OK DO Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); Weight w = FIRST (Weight); Melder_information (Dissimilarity_Configuration_Weight_monotone_stress (me, c, w, GET_INTEGER (U"Handling of ties"), GET_INTEGER (U"Stress measure"))); END FORM (Dissimilarity_Configuration_Weight_ispline_stress, U"Dissimilarity & Configuration & Weight: Get stress (i-spline mds)", U"Dissimilarity & Configuration & Weight: Get stress (i-spline mds)...") INTEGER (U"Number of interior knots", U"1") INTEGER (U"Order of I-spline", U"3") Dissimilarity_and_Configuration_getStress_addCommonFields (dia, radio); OK DO Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); Weight w = FIRST (Weight); Melder_information (Dissimilarity_Configuration_Weight_ispline_stress (me, c, w, GET_INTEGER (U"Number of interior knots"), GET_INTEGER (U"Order of I-spline"), GET_INTEGER (U"Stress measure"))); END FORM (Dissimilarity_Configuration_drawShepardDiagram, U"Dissimilarity & Configuration: Draw Shepard diagram", U"Dissimilarity & Configuration: Draw Shepard diagram...") Dissimilarity_Configuration_drawDiagram_addCommonFields (dia); OK DO autoPraatPicture picture; Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); Dissimilarity_Configuration_drawShepardDiagram (me, c, GRAPHICS, GET_REAL (U"left Proximity range"), GET_REAL (U"right Proximity range"), GET_REAL (U"left Distance range"), GET_REAL (U"right Distance range"), GET_REAL (U"Mark size"), GET_STRING (U"Mark string"), GET_INTEGER (U"Garnish")); END FORM (Dissimilarity_Configuration_drawAbsoluteRegression, U"Dissimilarity & Configuration: Draw regression (absolute mds)", U"Dissimilarity & Configuration: Draw regression (absolute mds)...") Dissimilarity_Configuration_drawDiagram_addCommonFields (dia); OK DO autoPraatPicture picture; Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); Dissimilarity_Configuration_Weight_drawAbsoluteRegression (me, c, 0, GRAPHICS, GET_REAL (U"left Proximity range"), GET_REAL (U"right Proximity range"), GET_REAL (U"left Distance range"), GET_REAL (U"right Distance range"), GET_REAL (U"Mark size"), GET_STRING (U"Mark string"), GET_INTEGER (U"Garnish")); END FORM (Dissimilarity_Configuration_drawRatioRegression, U"Dissimilarity & Configuration: Draw regression (ratio mds)", U"Dissimilarity & Configuration: Draw regression (ratio mds)...") Dissimilarity_Configuration_drawDiagram_addCommonFields (dia); OK DO autoPraatPicture picture; Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); Dissimilarity_Configuration_Weight_drawRatioRegression (me, c, 0, GRAPHICS, GET_REAL (U"left Proximity range"), GET_REAL (U"right Proximity range"), GET_REAL (U"left Distance range"), GET_REAL (U"right Distance range"), GET_REAL (U"Mark size"), GET_STRING (U"Mark string"), GET_INTEGER (U"Garnish")); END FORM (Dissimilarity_Configuration_drawIntervalRegression, U"Dissimilarity & Configuration: Draw regression (interval mds)", U"Dissimilarity & Configuration: Draw regression (interval mds)...") Dissimilarity_Configuration_drawDiagram_addCommonFields (dia); OK DO autoPraatPicture picture; Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); Dissimilarity_Configuration_Weight_drawIntervalRegression (me, c, 0, GRAPHICS, GET_REAL (U"left Proximity range"), GET_REAL (U"right Proximity range"), GET_REAL (U"left Distance range"), GET_REAL (U"right Distance range"), GET_REAL (U"Mark size"), GET_STRING (U"Mark string"), GET_INTEGER (U"Garnish")); END FORM (Dissimilarity_Configuration_drawMonotoneRegression, U"Dissimilarity & Configuration: Draw regression (monotone mds)", U"Dissimilarity & Configuration: Draw regression (monotone mds)...") RADIO (U"Handling of ties", 1) RADIOBUTTON (U"Primary approach)") RADIOBUTTON (U"Secondary approach") Dissimilarity_Configuration_drawDiagram_addCommonFields (dia); OK DO autoPraatPicture picture; Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); Dissimilarity_Configuration_Weight_drawMonotoneRegression (me, c, 0, GRAPHICS, GET_INTEGER (U"Handling of ties"), GET_REAL (U"left Proximity range"), GET_REAL (U"right Proximity range"), GET_REAL (U"left Distance range"), GET_REAL (U"right Distance range"), GET_REAL (U"Mark size"), GET_STRING (U"Mark string"), GET_INTEGER (U"Garnish")); END FORM (Dissimilarity_Configuration_drawISplineRegression, U"Dissimilarity & Configuration: Draw regression (i-spline mds)", U"Dissimilarity & Configuration: Draw regression (i-spline mds)...") INTEGER (U"Number of interior knots", U"1") INTEGER (U"Order of I-spline", U"3") Dissimilarity_Configuration_drawDiagram_addCommonFields (dia); OK DO autoPraatPicture picture; Dissimilarity me = FIRST (Dissimilarity); Configuration c = FIRST (Configuration); Dissimilarity_Configuration_Weight_drawISplineRegression (me, c, 0, GRAPHICS, GET_INTEGER (U"Number of interior knots"), GET_INTEGER (U"Order of I-spline"), GET_REAL (U"left Proximity range"), GET_REAL (U"right Proximity range"), GET_REAL (U"left Distance range"), GET_REAL (U"right Distance range"), GET_REAL (U"Mark size"), GET_STRING (U"Mark string"), GET_INTEGER (U"Garnish")); END FORM (Dissimilarity_kruskal, U"Dissimilarity: To Configuration (kruskal)", U"Dissimilarity: To Configuration (kruskal)...") LABEL (U"", U"Configuration") NATURAL (U"Number of dimensions", U"2") NATURAL (U"Distance metric", U"2 (=Euclidean)") RADIO (U"Handling of ties", 1) RADIOBUTTON (U"Primary approach") RADIOBUTTON (U"Secondary approach") RADIO (U"Stress calculation", 1) RADIOBUTTON (U"Formula1") RADIOBUTTON (U"Formula2") Dissimilarity_to_Configuration_addCommonFields (dia); OK DO LOOP { iam (Dissimilarity); praat_new (Dissimilarity_kruskal (me, GET_INTEGER (U"Number of dimensions"), GET_INTEGER (U"Distance metric"), GET_INTEGER (U"Handling of ties"), GET_INTEGER (U"Stress calculation"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Maximum number of iterations"), GET_INTEGER (U"Number of repetitions")), my name); } END FORM (Dissimilarity_absolute_mds, U"Dissimilarity: To Configuration (absolute mds)", U"Dissimilarity: To Configuration (absolute mds)...") LABEL (U"", U"Configuration") NATURAL (U"Number of dimensions", U"2") Dissimilarity_to_Configuration_addCommonFields (dia); OK DO LOOP { iam (Dissimilarity); int showProgress = 1; praat_new (Dissimilarity_Weight_absolute_mds (me, nullptr, GET_INTEGER (U"Number of dimensions"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Maximum number of iterations"), GET_INTEGER (U"Number of repetitions"), showProgress), my name, U"_absolute"); } END FORM (Dissimilarity_ratio_mds, U"Dissimilarity: To Configuration (ratio mds)", U"Dissimilarity: To Configuration (ratio mds)...") LABEL (U"", U"Configuration") NATURAL (U"Number of dimensions", U"2") Dissimilarity_to_Configuration_addCommonFields (dia); OK DO LOOP { iam (Dissimilarity); int showProgress = 1; praat_new (Dissimilarity_Weight_ratio_mds (me, 0, GET_INTEGER (U"Number of dimensions"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Maximum number of iterations"), GET_INTEGER (U"Number of repetitions"), showProgress), my name, U"_ratio"); } END FORM (Dissimilarity_interval_mds, U"Dissimilarity: To Configuration (interval mds)", U"Dissimilarity: To Configuration (interval mds)...") LABEL (U"", U"Configuration") NATURAL (U"Number of dimensions", U"2") Dissimilarity_to_Configuration_addCommonFields (dia); OK DO LOOP { iam (Dissimilarity); int showProgress = 1; praat_new (Dissimilarity_Weight_interval_mds (me, 0, GET_INTEGER (U"Number of dimensions"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Maximum number of iterations"), GET_INTEGER (U"Number of repetitions"), showProgress), my name, U"_interval"); } END FORM (Dissimilarity_monotone_mds, U"Dissimilarity: To Configuration (monotone mds)", U"Dissimilarity: To Configuration (monotone mds)...") LABEL (U"", U"Configuration") NATURAL (U"Number of dimensions", U"2") RADIO (U"Handling of ties", 1) RADIOBUTTON (U"Primary approach") RADIOBUTTON (U"Secondary approach") Dissimilarity_to_Configuration_addCommonFields (dia); OK DO LOOP { iam (Dissimilarity); int showProgress = 1; praat_new (Dissimilarity_Weight_monotone_mds (me, 0, GET_INTEGER (U"Number of dimensions"), GET_INTEGER (U"Handling of ties"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Maximum number of iterations"), GET_INTEGER (U"Number of repetitions"), showProgress), my name, U"_monotone"); } END FORM (Dissimilarity_ispline_mds, U"Dissimilarity: To Configuration (i-spline mds)", U"Dissimilarity: To Configuration (i-spline mds)...") LABEL (U"", U"Configuration") NATURAL (U"Number of dimensions", U"2") LABEL (U"", U"Spline smoothing") INTEGER (U"Number of interior knots", U"1") INTEGER (U"Order of I-spline", U"1") Dissimilarity_to_Configuration_addCommonFields (dia); OK DO long niknots = GET_INTEGER (U"Number of interior knots"); long order = GET_INTEGER (U"Order of I-spline"); if (not (order > 0 || niknots > 0)) { Melder_throw (U"Order-zero spline must at least have 1 interior knot."); } LOOP { iam (Dissimilarity); int showProgress = 1; praat_new (Dissimilarity_Weight_ispline_mds (me, 0, GET_INTEGER (U"Number of dimensions"), niknots, order, GET_REAL (U"Tolerance"), GET_INTEGER (U"Maximum number of iterations"), GET_INTEGER (U"Number of repetitions"), showProgress), my name, U"_ispline"); } END FORM (Dissimilarity_Weight_ispline_mds, U"Dissimilarity & Weight: To Configuration (i-spline mds)", U"Dissimilarity & Weight: To Configuration (i-spline mds)...") LABEL (U"", U"Configuration") NATURAL (U"Number of dimensions", U"2") LABEL (U"", U"Spline smoothing") INTEGER (U"Number of interior knots", U"1") INTEGER (U"Order of I-spline", U"1") Dissimilarity_to_Configuration_addCommonFields (dia); OK DO Dissimilarity me = FIRST (Dissimilarity); Weight w = FIRST (Weight); int showProgress = 1; long niknots = GET_INTEGER (U"Number of interior knots"); long order = GET_INTEGER (U"Order of I-spline"); if (not (order > 0 || niknots > 0)) { Melder_throw (U"Order-zero spline must at least have 1 interior knot."); } praat_new (Dissimilarity_Weight_ispline_mds (me, w, GET_INTEGER (U"Number of dimensions"), niknots, order, GET_REAL (U"Tolerance"), GET_INTEGER (U"Maximum number of iterations"), GET_INTEGER (U"Number of repetitions"), showProgress), my name, U"_ispline"); END FORM (Dissimilarity_Weight_absolute_mds, U"Dissimilarity & Weight: To Configuration (absolute mds)", U"Dissimilarity & Weight: To Configuration (absolute mds)...") LABEL (U"", U"Configuration") NATURAL (U"Number of dimensions", U"2") Dissimilarity_to_Configuration_addCommonFields (dia); OK DO Dissimilarity me = FIRST (Dissimilarity); Weight w = FIRST (Weight); int showProgress = 1; praat_new (Dissimilarity_Weight_absolute_mds (me, w, GET_INTEGER (U"Number of dimensions"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Maximum number of iterations"), GET_INTEGER (U"Number of repetitions"), showProgress), my name, U"_absolute"); END FORM (Dissimilarity_Weight_ratio_mds, U"Dissimilarity & Weight: To Configuration (ratio mds)", U"Dissimilarity & Weight: To Configuration (ratio mds)...") LABEL (U"", U"Configuration") NATURAL (U"Number of dimensions", U"2") Dissimilarity_to_Configuration_addCommonFields (dia); OK DO Dissimilarity me = FIRST (Dissimilarity); Weight w = FIRST (Weight); int showProgress = 1; praat_new (Dissimilarity_Weight_ratio_mds (me, w, GET_INTEGER (U"Number of dimensions"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Maximum number of iterations"), GET_INTEGER (U"Number of repetitions"), showProgress), my name, U"_absolute"); END FORM (Dissimilarity_Weight_interval_mds, U"Dissimilarity & Weight: To Configuration (interval mds)", U"Dissimilarity & Weight: To Configuration (interval mds)...") LABEL (U"", U"Configuration") NATURAL (U"Number of dimensions", U"2") Dissimilarity_to_Configuration_addCommonFields (dia); OK DO Dissimilarity me = FIRST (Dissimilarity); Weight w = FIRST (Weight); int showProgress = 1; praat_new (Dissimilarity_Weight_interval_mds (me, w, GET_INTEGER (U"Number of dimensions"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Maximum number of iterations"), GET_INTEGER (U"Number of repetitions"), showProgress), my name, U"_absolute"); END FORM (Dissimilarity_Weight_monotone_mds, U"Dissimilarity & Weight: To Configuration (monotone mds)", U"Dissimilarity & Weight: To Configuration (monotone mds)...") LABEL (U"", U"Configuration") NATURAL (U"Number of dimensions", U"2") RADIO (U"Handling of ties", 1) RADIOBUTTON (U"Primary approach") RADIOBUTTON (U"Secondary approach") Dissimilarity_to_Configuration_addCommonFields (dia); OK DO Dissimilarity me = FIRST (Dissimilarity); Weight w = FIRST (Weight); int showProgress = 1; praat_new (Dissimilarity_Weight_monotone_mds (me, w, GET_INTEGER (U"Number of dimensions"), GET_INTEGER (U"Handling of ties"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Maximum number of iterations"), GET_INTEGER (U"Number of repetitions"), showProgress), my name, U"_monotone"); END FORM (Dissimilarity_to_Distance, U"Dissimilarity: To Distance", U"Dissimilarity: To Distance...") BOOLEAN (U"Scale (additive constant)", 1) OK DO LOOP { iam (Dissimilarity); praat_new (Dissimilarity_to_Distance (me, GET_INTEGER (U"Scale")), my name); } END DIRECT (Dissimilarity_to_Weight) LOOP { iam (Dissimilarity); praat_new (Dissimilarity_to_Weight (me), my name); } END /************************* Distance(s) ***************************************/ FORM (Distance_to_ScalarProduct, U"Distance: To ScalarProduct", U"Distance: To ScalarProduct...") BOOLEAN (U"Make sum of squares equal 1.0", 1) OK DO LOOP { iam (Distance); praat_new (Distance_to_ScalarProduct (me, GET_INTEGER (U"Make sum of squares equal 1.0")), my name); } END DIRECT (Distance_to_Dissimilarity) LOOP { iam (Distance); praat_new (Distance_to_Dissimilarity (me), my name); } END FORM (Distances_indscal, U"Distance: To Configuration (indscal)", U"Distance: To Configuration (indscal)...") NATURAL (U"Number of dimensions", U"2") BOOLEAN (U"Normalize scalar products", 1) LABEL (U"", U"Minimization parameters") REAL (U"Tolerance", U"1e-5") NATURAL (U"Maximum number of iterations", U"100 (= each repetition)") NATURAL (U"Number of repetitions", U"1") OK DO autoDistances me = (Distances) praat_getSelectedObjects (); autoConfiguration ac; autoSalience as; Distances_indscal (me.peek(), GET_INTEGER (U"Number of dimensions"), GET_INTEGER (U"Normalize scalar products"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Maximum number of iterations"), GET_INTEGER (U"Number of repetitions"), 1, &ac, &as); praat_new (ac.transfer(), U"indscal"); praat_new (as.transfer(), U"indscal"); END FORM (Distance_and_Configuration_drawScatterDiagram, U"Distance & Configuration: Draw scatter diagram", U"Distance & Configuration: Draw scatter diagram...") REAL (U"Minimum x-distance", U"0.0") REAL (U"Maximum x-distance", U"0.0") REAL (U"Minimum y-distance", U"0.0") REAL (U"Maximum y-distance", U"0.0") POSITIVE (U"Mark size (mm)", U"1.0") SENTENCE (U"Mark string (+xo.)", U"+") BOOLEAN (U"Garnish", 1) OK DO autoPraatPicture picture; Distance me = FIRST (Distance); Configuration c = FIRST (Configuration); Distance_and_Configuration_drawScatterDiagram (me, c, GRAPHICS, GET_REAL (U"Minimum x-distance"), GET_REAL (U"Maximum x-distance"), GET_REAL (U"Minimum y-distance"), GET_REAL (U"Maximum y-distance"), GET_REAL (U"Mark size"), GET_STRING (U"Mark string"), GET_INTEGER (U"Garnish")); END FORM (Distance_Configuration_indscal, U"Distance & Configuration: To Configuration (indscal)", U"Distance & Configuration: To Configuration (indscal)...") BOOLEAN (U"Normalize scalar products", 1) LABEL (U"", U"Minimization parameters") REAL (U"Tolerance", U"1e-5") NATURAL (U"Maximum number of iterations", U"100 (= each repetition)") OK DO autoDistances thee = Distances_create (); Collection_dontOwnItems (thee.peek()); Configuration c = 0; LOOP { iam (Daata); if (CLASS == classDistance) { Collection_addItem (thee.peek(), me); } else if (CLASS == classConfiguration) { c = (Configuration) me; } } Melder_assert (thy size > 0 && c); autoConfiguration ac; autoSalience as; Distances_Configuration_indscal (thee.peek(), c, GET_INTEGER (U"Normalize scalar products"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Maximum number of iterations"), 1, &ac, &as); praat_new (ac.transfer(), U"indscal"); praat_new (as.transfer(), U"indscal"); END FORM (Distance_Configuration_vaf, U"Distance & Configuration: Get VAF", U"Distance & Configuration: Get VAF...") BOOLEAN (U"Normalize scalar products", 1) OK DO autoDistances thee = Distances_create (); Collection_dontOwnItems (thee.peek()); Configuration c = 0; LOOP { iam (Daata); if (CLASS == classDistance) { Collection_addItem (thee.peek(), me); } else if (CLASS == classConfiguration) { c = (Configuration) me; } } Melder_assert (thy size > 0 && c); double vaf; Distances_Configuration_vaf (thee.peek(), c, GET_INTEGER (U"Normalize scalar products"), &vaf); Melder_information (vaf); END FORM (Distance_Configuration_Salience_vaf, U"Distance & Configuration & Salience: Get VAF", U"Distance & Configuration & Salience: Get VAF...") BOOLEAN (U"Normalize scalar products", 1) OK DO autoDistances thee = Distances_create (); Collection_dontOwnItems (thee.peek()); Configuration c = 0; Salience s = 0; LOOP { iam (Daata); if (CLASS == classDistance) { Collection_addItem (thee.peek(), me); } else if (CLASS == classConfiguration) { c = (Configuration) me; } else if (CLASS == classSalience) { s = (Salience) me; } } Melder_assert (thy size > 0 && c && s); double vaf; Distances_Configuration_Salience_vaf (thee.peek(), c, s, GET_INTEGER (U"Normalize scalar products"), &vaf); Melder_information (vaf); END FORM (Dissimilarity_Configuration_Salience_vaf, U"Dissimilarity & Configuration & Salience: Get VAF", U"Dissimilarity & Configuration & Salience: Get VAF...") RADIO (U"Handling of ties", 1) RADIOBUTTON (U"Primary approach") RADIOBUTTON (U"Secondary approach") BOOLEAN (U"Normalize scalar products", 1) OK DO autoDissimilarities thee = Dissimilarities_create (); Collection_dontOwnItems (thee.peek()); Configuration c = 0; Salience s = 0; LOOP { iam (Daata); if (CLASS == classDissimilarity) { Collection_addItem (thee.peek(), me); } else if (CLASS == classConfiguration) { c = (Configuration) me; } else if (CLASS == classSalience) { s = (Salience) me; } } Melder_assert (thy size > 0 && c && s); double vaf; Dissimilarities_Configuration_Salience_vaf (thee.peek(), c, s, GET_INTEGER (U"Handling of ties"), GET_INTEGER (U"Normalize scalar products"), &vaf); Melder_information (vaf); END FORM (Distance_Configuration_Salience_indscal, U"Distance & Configuration & Salience: To Configuration (indscal)", U"Distance & Configuration & Salience: To Configuration (indscal)...") BOOLEAN (U"Normalize scalar products", 1) LABEL (U"", U"Minimization parameters") REAL (U"Tolerance", U"1e-5") NATURAL (U"Maximum number of iterations", U"100") OK DO autoDistances thee = Distances_create (); Collection_dontOwnItems (thee.peek()); Configuration c = 0; Salience s = 0; LOOP { iam (Daata); if (CLASS == classDistance) { Collection_addItem (thee.peek(), me); } else if (CLASS == classConfiguration) { c = (Configuration) me; } else if (CLASS == classSalience) { s = (Salience) me; } } Melder_assert (thy size > 0 && c && s); double vaf; autoConfiguration ac; autoSalience as; Distances_Configuration_Salience_indscal (thee.peek(), c, s, GET_INTEGER (U"Normalize scalar products"), GET_REAL (U"Tolerance"), GET_INTEGER (U"Maximum number of iterations"), 1, &ac, &as, &vaf); praat_new (ac.transfer(), U"indscal"); praat_new (as.transfer(), U"indscal"); END FORM (Distances_to_Configuration_ytl, U"Distance: To Configuration (ytl)", U"Distance: To Configuration (ytl)...") NATURAL (U"Number of dimensions", U"2") BOOLEAN (U"Normalize scalar products", 1) BOOLEAN (U"Salience object", 0) OK DO autoDistances me = (Distances) praat_getSelectedObjects (); autoConfiguration ac; autoSalience as; Distances_to_Configuration_ytl (me.peek(), GET_INTEGER (U"Number of dimensions"), GET_INTEGER (U"Normalize scalar products"), &ac, &as); praat_new (ac.transfer(), U"ytl"); if (GET_INTEGER (U"Salience object")) { praat_new (as.transfer(), U"ytl"); } END FORM (Dissimilarity_Distance_monotoneRegression, U"Dissimilarity & Distance: Monotone regression", 0) RADIO (U"Handling of ties", 1) RADIOBUTTON (U"Primary approach") RADIOBUTTON (U"Secondary approach") OK DO Dissimilarity me = FIRST (Dissimilarity); Distance d = FIRST (Distance); praat_new (Dissimilarity_Distance_monotoneRegression (me, d, GET_INTEGER (U"Handling of ties")), my name); END FORM (Distance_Dissimilarity_drawShepardDiagram, U"Distance & Dissimilarity: Draw Shepard diagram", U"") REAL (U"Minimum dissimilarity", U"0.0") REAL (U"Maximum dissimilarity", U"0.0") REAL (U"left Distance range", U"0.0") REAL (U"right Distance range", U"0.0") POSITIVE (U"Mark size (mm)", U"1.0") SENTENCE (U"Mark string (+xo.)", U"+") BOOLEAN (U"Garnish", 1) OK DO Dissimilarity me = FIRST (Dissimilarity); Distance d = FIRST (Distance); Proximity_Distance_drawScatterDiagram (me, d, GRAPHICS, GET_REAL (U"Minimum dissimilarity"), GET_REAL (U"Maximum dissimilarity"), GET_REAL (U"left Distance range"), GET_REAL (U"right Distance range"), GET_REAL (U"Mark size"), GET_STRING (U"Mark string"), GET_INTEGER (U"Garnish")); END DIRECT (MDS_help) Melder_help (U"Multidimensional scaling"); END /************************* Salience ***************************************/ FORM (Salience_draw, U"Salience: Draw", 0) NATURAL (U"Horizontal dimension", U"1") NATURAL (U"Vertical dimension", U"2") BOOLEAN (U"Garnish", 1) OK DO LOOP { iam (Salience); Salience_draw (me, GRAPHICS, GET_INTEGER (U"Horizontal dimension"), GET_INTEGER (U"Vertical dimension"), GET_INTEGER (U"Garnish")); } END /************************* COVARIANCE & CONFIGURATION ********************/ FORM (Covariance_to_Configuration, U"Covariance: To Configuration", 0) NATURAL (U"Number of dimensions", U"2") OK DO LOOP { iam (Covariance); praat_new (Covariance_to_Configuration (me, GET_INTEGER (U"Number of dimensions")), my name); } END /********* Procrustes ***************************/ DIRECT (Procrustes_help) Melder_help (U"Procrustes"); END DIRECT (Procrustes_getScale) LOOP { iam (Procrustes); Melder_information (my s); } END /********* Casts from & to TableOfReal ***************************/ DIRECT (TableOfReal_to_Dissimilarity) LOOP { iam (TableOfReal); praat_new (TableOfReal_to_Dissimilarity (me), my name); } END DIRECT (TableOfReal_to_Similarity) LOOP { iam (TableOfReal); praat_new (TableOfReal_to_Similarity (me), my name); } END DIRECT (TableOfReal_to_Distance) LOOP { iam (TableOfReal); praat_new (TableOfReal_to_Distance (me), my name); } END DIRECT (TableOfReal_to_Salience) LOOP { iam (TableOfReal); praat_new (TableOfReal_to_Salience (me), my name); } END DIRECT (TableOfReal_to_Weight) LOOP { iam (TableOfReal); praat_new (TableOfReal_to_Weight (me), my name); } END DIRECT (TableOfReal_to_ScalarProduct) LOOP { iam (TableOfReal); praat_new (TableOfReal_to_ScalarProduct (me), my name); } END DIRECT (TableOfReal_to_Configuration) LOOP { iam (TableOfReal); autoConfiguration thee = TableOfReal_to_Configuration (me); praat_new (thee.transfer(), my name); } END DIRECT (TableOfReal_to_ContingencyTable) LOOP { iam (TableOfReal); autoContingencyTable thee = TableOfReal_to_ContingencyTable (me); praat_new (thee.transfer(), my name); } END /********************** TableOfReal ***************************************/ DIRECT (TableOfReal_getTableNorm) LOOP { iam (TableOfReal); Melder_information (TableOfReal_getTableNorm (me)); } END FORM (TableOfReal_normalizeTable, U"TableOfReal: Normalize table", U"TableOfReal: Normalize table...") POSITIVE (U"Norm", U"1.0") OK DO LOOP { iam (TableOfReal); TableOfReal_normalizeTable (me, GET_REAL (U"Norm")); } END FORM (TableOfReal_normalizeRows, U"TableOfReal: Normalize rows", U"TableOfReal: Normalize rows...") POSITIVE (U"Norm", U"1.0") OK DO LOOP { iam (TableOfReal); TableOfReal_normalizeRows (me, GET_REAL (U"Norm")); } END FORM (TableOfReal_normalizeColumns, U"TableOfReal: Normalize columns", U"TableOfReal: Normalize columns...") POSITIVE (U"Norm", U"1.0") OK DO LOOP { iam (TableOfReal); TableOfReal_normalizeColumns (me, GET_REAL (U"Norm")); } END DIRECT (TableOfReal_centreRows) LOOP { iam (TableOfReal); TableOfReal_centreRows (me); } END DIRECT (TableOfReal_centreColumns) LOOP { iam (TableOfReal); TableOfReal_centreColumns (me); } END DIRECT (TableOfReal_doubleCentre) LOOP { iam (TableOfReal); TableOfReal_doubleCentre (me); } END DIRECT (TableOfReal_standardizeRows) LOOP { iam (TableOfReal); TableOfReal_standardizeRows (me); } END DIRECT (TableOfReal_standardizeColumns) LOOP { iam (TableOfReal); TableOfReal_standardizeColumns (me); } END DIRECT (TableOfReal_to_Confusion) LOOP { iam (TableOfReal); autoConfusion thee = TableOfReal_to_Confusion (me); praat_new (thee.transfer(), my name); } END static void praat_AffineTransform_init (ClassInfo klas) { praat_addAction1 (klas, 0, QUERY_BUTTON, 0, 0, 0); praat_addAction1 (klas, 1, U"Get transformation element...", QUERY_BUTTON, 1, DO_AffineTransform_getTransformationElement); praat_addAction1 (klas, 1, U"Get translation element...", QUERY_BUTTON, 1, DO_AffineTransform_getTranslationElement); praat_addAction1 (klas, 0, U"Invert", 0, 0, DO_AffineTransform_invert); } static void praat_Configuration_and_AffineTransform_init (ClassInfo transform) { praat_addAction2 (classConfiguration, 1, transform, 1, U"To Configuration", 0, 0, DO_Configuration_and_AffineTransform_to_Configuration); } void praat_TableOfReal_extras (ClassInfo klas); void praat_TableOfReal_extras (ClassInfo klas) { praat_addAction1 (klas, 1, U"-- get additional --", U"Get value...", 1, 0); praat_addAction1 (klas, 1, U"Get table norm", U"-- get additional --", 1, DO_TableOfReal_getTableNorm); praat_addAction1 (klas, 1, U"-- set additional --", U"Set column label (label)...", 1, 0); praat_addAction1 (klas, 1, U"Normalize rows...", U"-- set additional --", 1, DO_TableOfReal_normalizeRows); praat_addAction1 (klas, 1, U"Normalize columns...", U"Normalize rows...", 1, DO_TableOfReal_normalizeColumns); praat_addAction1 (klas, 1, U"Normalize table...", U"Normalize columns...", 1, DO_TableOfReal_normalizeTable); praat_addAction1 (klas, 1, U"Standardize rows", U"Normalize table...", 1, DO_TableOfReal_standardizeRows); praat_addAction1 (klas, 1, U"Standardize columns", U"Standardize rows", 1, DO_TableOfReal_standardizeColumns); praat_addAction1 (klas, 1, U"Test sorting...", U"Standardize columns", praat_DEPTH_1 + praat_HIDDEN, DO_TabelOfReal_testSorting); } void praat_uvafon_MDS_init (); void praat_uvafon_MDS_init () { Thing_recognizeClassesByName (classAffineTransform, classProcrustes, classContingencyTable, classDissimilarity, classSimilarity, classConfiguration, classDistance, classSalience, classScalarProduct, classWeight, nullptr); Thing_recognizeClassByOtherName (classProcrustes, U"Procrustus"); praat_addMenuCommand (U"Objects", U"New", U"Multidimensional scaling", 0, 0, 0); praat_addMenuCommand (U"Objects", U"New", U"MDS tutorial", 0, 1, DO_MDS_help); praat_addMenuCommand (U"Objects", U"New", U"-- MDS --", 0, 1, 0); praat_addMenuCommand (U"Objects", U"New", U"Create letter R example...", 0, 1, DO_Dissimilarity_createLetterRExample); praat_addMenuCommand (U"Objects", U"New", U"Create INDSCAL Carroll Wish example...", 0, 1, DO_INDSCAL_createCarrollWishExample); praat_addMenuCommand (U"Objects", U"New", U"Create Configuration...", 0, 1, DO_Configuration_create); praat_addMenuCommand (U"Objects", U"New", U"Draw splines...", 0, 1, DO_drawSplines); praat_addMenuCommand (U"Objects", U"New", U"Draw MDS class relations", 0, 1, DO_drawMDSClassRelations); /****** 1 class ********************************************************/ praat_addAction1 (classAffineTransform, 0, U"AffineTransform help", 0, 0, DO_AffineTransform_help); praat_AffineTransform_init (classAffineTransform); praat_addAction1 (classConfiguration, 0, U"Configuration help", 0, 0, DO_Configuration_help); praat_TableOfReal_init2 (classConfiguration); praat_TableOfReal_extras (classConfiguration); (void) praat_removeAction (classConfiguration, nullptr, nullptr, U"Insert column (index)..."); (void) praat_removeAction (classConfiguration, nullptr, nullptr, U"Remove column (index)..."); (void) praat_removeAction (classConfiguration, nullptr, nullptr, U"Append"); praat_addAction1 (classConfiguration, 0, U"Draw...", DRAW_BUTTON, 1, DO_Configuration_draw); praat_addAction1 (classConfiguration, 0, U"Draw sigma ellipses...", U"Draw...", 1, DO_Configuration_drawSigmaEllipses); praat_addAction1 (classConfiguration, 0, U"Draw one sigma ellipse...", U"Draw...", 1, DO_Configuration_drawOneSigmaEllipse); praat_addAction1 (classConfiguration, 0, U"Draw confidence ellipses...", U"Draw sigma ellipses...", 1, DO_Configuration_drawConfidenceEllipses); praat_addAction1 (classConfiguration, 0, U"Draw one confidence ellipse...", U"Draw sigma ellipses...", 1, DO_Configuration_drawOneConfidenceEllipse); praat_addAction1 (classConfiguration, 0, U"Randomize", U"Normalize table...", 1, DO_Configuration_randomize); praat_addAction1 (classConfiguration, 0, U"Normalize...", U"Randomize", 1, DO_Configuration_normalize); praat_addAction1 (classConfiguration, 0, U"Centralize", U"Randomize", 1, DO_Configuration_centralize); praat_addAction1 (classConfiguration, 1, U"-- set rotations & reflections --", U"Centralize", 1, 0); praat_addAction1 (classConfiguration, 0, U"Rotate...", U"-- set rotations & reflections --", 1, DO_Configuration_rotate); praat_addAction1 (classConfiguration, 0, U"Rotate (pc)", U"Rotate...", 1, DO_Configuration_rotateToPrincipalDirections); praat_addAction1 (classConfiguration, 0, U"Invert dimension...", U"Rotate (pc)", 1, DO_Configuration_invertDimension); praat_addAction1 (classConfiguration, 0, U"Analyse", 0, 0, 0); praat_addAction1 (classConfiguration, 0, U"To Distance", 0, 0, DO_Configuration_to_Distance); praat_addAction1 (classConfiguration, 0, U"To Configuration (varimax)...", 0, 0, DO_Configuration_varimax); praat_addAction1 (classConfiguration, 0, U"To Similarity (cc)", 0, 0, DO_Configurations_to_Similarity_cc); praat_addAction1 (classConfiguration, 0, U"Match configurations -", 0, 0, 0); praat_addAction1 (classConfiguration, 2, U"To Procrustes...", 0, 1, DO_Configurations_to_Procrustes); praat_addAction1 (classConfiguration, 2, U"To AffineTransform (congruence)...", 0, 1, DO_Configurations_to_AffineTransform_congruence); praat_addAction1 (classConfusion, 0, U"To ContingencyTable", U"To Matrix", 0, DO_Confusion_to_ContingencyTable); praat_addAction1 (classConfusion, 0, U"To Proximity -", U"Analyse", 0, 0); praat_addAction1 (classConfusion, 0, U"To Dissimilarity (pdf)...", U"To Proximity -", 1, DO_Confusion_to_Dissimilarity_pdf); praat_addAction1 (classConfusion, 0, U"To Similarity...", U"To Proximity -", 1, DO_Confusion_to_Similarity); praat_addAction1 (classConfusion, 0, U"Sum", U"Synthesize -", 1, DO_Confusions_sum); praat_TableOfReal_init2 (classContingencyTable); praat_addAction1 (classContingencyTable, 1, U"-- statistics --", U"Get value...", 1, 0); praat_addAction1 (classContingencyTable, 1, U"Get chi squared probability", U"-- statistics --", 1, DO_ContingencyTable_chisqProbability); praat_addAction1 (classContingencyTable, 1, U"Get Cramer's statistic", U"Get chi squared probability", 1, DO_ContingencyTable_cramersStatistic); praat_addAction1 (classContingencyTable, 1, U"Get contingency coefficient", U"Get Cramer's statistic", 1, DO_ContingencyTable_contingencyCoefficient); praat_addAction1 (classContingencyTable, 0, U"Analyse", 0, 0, 0); praat_addAction1 (classContingencyTable, 1, U"To Configuration (ca)...", 0, 0, DO_ContingencyTable_to_Configuration_ca); praat_addAction1 (classCorrelation, 0, U"To Configuration...", 0, 0, DO_Correlation_to_Configuration); praat_addAction1 (classDissimilarity, 0, U"Dissimilarity help", 0, 0, DO_Dissimilarity_help); praat_TableOfReal_init2 (classDissimilarity); praat_TableOfReal_extras (classDissimilarity); praat_addAction1 (classDissimilarity, 0, U"Get additive constant", U"Get table norm", 1, DO_Dissimilarity_getAdditiveConstant); praat_addAction1 (classDissimilarity, 0, CONFIGURATION_BUTTON, 0, 0, 0); praat_addAction1 (classDissimilarity, 1, U"To Configuration (monotone mds)...", 0, 1, DO_Dissimilarity_monotone_mds); praat_addAction1 (classDissimilarity, 1, U"To Configuration (i-spline mds)...", 0, 1, DO_Dissimilarity_ispline_mds); praat_addAction1 (classDissimilarity, 1, U"To Configuration (interval mds)...", 0, 1, DO_Dissimilarity_interval_mds); praat_addAction1 (classDissimilarity, 1, U"To Configuration (ratio mds)...", 0, 1, DO_Dissimilarity_ratio_mds); praat_addAction1 (classDissimilarity, 1, U"To Configuration (absolute mds)...", 0, 1, DO_Dissimilarity_absolute_mds); praat_addAction1 (classDissimilarity, 1, U"To Configuration (kruskal)...", 0, 1, DO_Dissimilarity_kruskal); praat_addAction1 (classDissimilarity, 0, U"To Distance...", 0, 0, DO_Dissimilarity_to_Distance); praat_addAction1 (classDissimilarity, 0, U"To Weight", 0, 0, DO_Dissimilarity_to_Weight); praat_addAction1 (classCovariance, 0, U"To Configuration...", 0, 0, DO_Covariance_to_Configuration); praat_TableOfReal_init2 (classDistance); praat_TableOfReal_extras (classDistance); praat_addAction1 (classDistance, 0, U"Analyse -", 0, 0, 0); praat_addAction1 (classDistance, 0, CONFIGURATION_BUTTON, 0, 0, 0); praat_addAction1 (classDistance, 0, U"To Configuration (indscal)...", 0, 1, DO_Distances_indscal); praat_addAction1 (classDistance, 0, U"-- linear scaling --", 0, 1, 0); praat_addAction1 (classDistance, 0, U"To Configuration (ytl)...", 0, 1, DO_Distances_to_Configuration_ytl); praat_addAction1 (classDistance, 0, U"To Dissimilarity", 0, 0, DO_Distance_to_Dissimilarity); praat_addAction1 (classDistance, 0, U"To ScalarProduct...", 0, 0, DO_Distance_to_ScalarProduct); praat_addAction1 (classProcrustes, 0, U"Procrustes help", 0, 0, DO_Procrustes_help); praat_AffineTransform_init (classProcrustes); praat_addAction1 (classProcrustes, 1, U"Get scale", QUERY_BUTTON, 1, DO_Procrustes_getScale); praat_addAction1 (classProcrustes, 0, U"Extract transformation matrix", 0, 0, DO_AffineTransform_extractMatrix); praat_addAction1 (classProcrustes, 0, U"Extract translation vector", 0, 0, DO_AffineTransform_extractTranslationVector); praat_TableOfReal_init2 (classSalience); praat_TableOfReal_extras (classSalience); praat_addAction1 (classSalience, 0, U"Draw...", DRAW_BUTTON, 1, DO_Salience_draw); praat_addAction1 (classSimilarity, 0, U"Similarity help", 0, 0, DO_Similarity_help); praat_TableOfReal_init2 (classSimilarity); praat_TableOfReal_extras (classSimilarity); praat_addAction1 (classSimilarity, 0, U"Analyse -", 0, 0, 0); praat_addAction1 (classSimilarity, 0, U"To Dissimilarity...", 0, 0, DO_Similarity_to_Dissimilarity); praat_TableOfReal_init2 (classScalarProduct); praat_TableOfReal_extras (classScalarProduct); praat_TableOfReal_extras (classTableOfReal); praat_addAction1 (classTableOfReal, 1, U"Centre rows", U"Normalize table...", 1, DO_TableOfReal_centreRows); praat_addAction1 (classTableOfReal, 1, U"Centre columns", U"Centre rows", 1, DO_TableOfReal_centreColumns); praat_addAction1 (classTableOfReal, 1, U"Double centre", U"Centre columns", 1, DO_TableOfReal_doubleCentre); praat_addAction1 (classTableOfReal, 0, U"Cast -", 0, 0, 0); praat_addAction1 (classTableOfReal, 0, U"To Confusion", 0, 1, DO_TableOfReal_to_Confusion); praat_addAction1 (classTableOfReal, 0, U"To Dissimilarity", 0, 1, DO_TableOfReal_to_Dissimilarity); praat_addAction1 (classTableOfReal, 0, U"To Similarity", 0, 1, DO_TableOfReal_to_Similarity); praat_addAction1 (classTableOfReal, 0, U"To Distance", 0, 1, DO_TableOfReal_to_Distance); praat_addAction1 (classTableOfReal, 0, U"To Salience", 0, 1, DO_TableOfReal_to_Salience); praat_addAction1 (classTableOfReal, 0, U"To Weight", 0, 1, DO_TableOfReal_to_Weight); praat_addAction1 (classTableOfReal, 0, U"To ScalarProduct", 0, 1, DO_TableOfReal_to_ScalarProduct); praat_addAction1 (classTableOfReal, 0, U"To Configuration", 0, 1, DO_TableOfReal_to_Configuration); praat_addAction1 (classTableOfReal, 0, U"To ContingencyTable", 0, 1, DO_TableOfReal_to_ContingencyTable); praat_TableOfReal_init2 (classWeight); /****** 2 classes ********************************************************/ praat_Configuration_and_AffineTransform_init (classAffineTransform); praat_Configuration_and_AffineTransform_init (classProcrustes); praat_addAction2 (classConfiguration, 0, classWeight, 1, U"Analyse", 0, 0, 0); praat_addAction2 (classConfiguration, 0, classWeight, 1, U"To Similarity (cc)", 0, 0, DO_Configuration_Weight_to_Similarity_cc); praat_addAction2 (classDissimilarity, 1, classWeight, 1, ANALYSE_BUTTON, 0, 0, 0); praat_addAction2 (classDissimilarity, 1, classWeight, 1, U"To Configuration (monotone mds)...", 0, 1, DO_Dissimilarity_Weight_monotone_mds); praat_addAction2 (classDissimilarity, 1, classWeight, 1, U"To Configuration (i-spline mds)...", 0, 1, DO_Dissimilarity_Weight_ispline_mds); praat_addAction2 (classDissimilarity, 1, classWeight, 1, U"To Configuration (interval mds)...", 0, 1, DO_Dissimilarity_Weight_interval_mds); praat_addAction2 (classDissimilarity, 1, classWeight, 1, U"To Configuration (ratio mds)...", 0, 1, DO_Dissimilarity_Weight_ratio_mds); praat_addAction2 (classDissimilarity, 1, classWeight, 1, U"To Configuration (absolute mds)...", 0, 1, DO_Dissimilarity_Weight_absolute_mds); praat_addAction2 (classDissimilarity, 1, classConfiguration, 1, DRAW_BUTTON, 0, 0, 0); praat_addAction2 (classDissimilarity, 1, classConfiguration, 1, U"Draw Shepard diagram...", 0, 1, DO_Dissimilarity_Configuration_drawShepardDiagram); praat_addAction2 (classDissimilarity, 1, classConfiguration, 1, U"-- draw regressions --", 0, 1, 0); praat_addAction2 (classDissimilarity, 1, classConfiguration, 1, U"Draw monotone regression...", 0, 1, DO_Dissimilarity_Configuration_drawMonotoneRegression); praat_addAction2 (classDissimilarity, 1, classConfiguration, 1, U"Draw i-spline regression...", 0, 1, DO_Dissimilarity_Configuration_drawISplineRegression); praat_addAction2 (classDissimilarity, 1, classConfiguration, 1, U"Draw interval regression...", 0, 1, DO_Dissimilarity_Configuration_drawIntervalRegression); praat_addAction2 (classDissimilarity, 1, classConfiguration, 1, U"Draw ratio regression...", 0, 1, DO_Dissimilarity_Configuration_drawRatioRegression); praat_addAction2 (classDissimilarity, 1, classConfiguration, 1, U"Draw absolute regression...", 0, 1, DO_Dissimilarity_Configuration_drawAbsoluteRegression); praat_addAction2 (classDissimilarity, 1, classConfiguration, 1, QUERY_BUTTON, 0, 0, 0); praat_addAction2 (classDissimilarity, 1, classConfiguration, 1, U"Get stress...", 0, 1, DO_Dissimilarity_Configuration_getStress); praat_addAction2 (classDissimilarity, 1, classConfiguration, 1, U"Get stress (monotone mds)...", 0, 1, DO_Dissimilarity_Configuration_monotone_stress); praat_addAction2 (classDissimilarity, 1, classConfiguration, 1, U"Get stress (i-spline mds)...", 0, 1, DO_Dissimilarity_Configuration_ispline_stress); praat_addAction2 (classDissimilarity, 1, classConfiguration, 1, U"Get stress (interval mds)...", 0, 1, DO_Dissimilarity_Configuration_interval_stress); praat_addAction2 (classDissimilarity, 1, classConfiguration, 1, U"Get stress (ratio mds)...", 0, 1, DO_Dissimilarity_Configuration_ratio_stress); praat_addAction2 (classDissimilarity, 1, classConfiguration, 1, U"Get stress (absolute mds)...", 0, 1, DO_Dissimilarity_Configuration_absolute_stress); praat_addAction2 (classDissimilarity, 1, classConfiguration, 1, ANALYSE_BUTTON, 0, 0, 0); praat_addAction2 (classDissimilarity, 1, classConfiguration, 1, U"To Configuration (monotone mds)...", 0, 1, DO_Dissimilarity_Configuration_monotone_mds); praat_addAction2 (classDissimilarity, 1, classConfiguration, 1, U"To Configuration (i-spline mds)...", 0, 1, DO_Dissimilarity_Configuration_ispline_mds); praat_addAction2 (classDissimilarity, 1, classConfiguration, 1, U"To Configuration (interval mds)...", 0, 1, DO_Dissimilarity_Configuration_interval_mds); praat_addAction2 (classDissimilarity, 1, classConfiguration, 1, U"To Configuration (ratio mds)...", 0, 1, DO_Dissimilarity_Configuration_ratio_mds); praat_addAction2 (classDissimilarity, 1, classConfiguration, 1, U"To Configuration (absolute mds)...", 0, 1, DO_Dissimilarity_Configuration_absolute_mds); praat_addAction2 (classDissimilarity, 1, classConfiguration, 1, U"To Configuration (kruskal)...", 0, 1, DO_Dissimilarity_Configuration_kruskal); praat_addAction2 (classDistance, 1, classConfiguration, 1, DRAW_BUTTON, 0, 0, 0); praat_addAction2 (classDistance, 1, classConfiguration, 1, U"Draw scatter diagram...", 0, 0, DO_Distance_and_Configuration_drawScatterDiagram); praat_addAction2 (classDistance, 1, classConfiguration, 1, QUERY_BUTTON, 0, 0, 0); praat_addAction2 (classDistance, 0, classConfiguration, 1, U"Get VAF...", 0, 0, DO_Distance_Configuration_vaf); praat_addAction2 (classDistance, 1, classConfiguration, 1, ANALYSE_BUTTON, 0, 0, 0); praat_addAction2 (classDistance, 0, classConfiguration, 1, U"To Configuration (indscal)...", 0, 1, DO_Distance_Configuration_indscal); praat_addAction2 (classDistance, 1, classDissimilarity, 1, U"Draw Shepard diagram...", 0, 0, DO_Distance_Dissimilarity_drawShepardDiagram); praat_addAction2 (classDissimilarity, 1, classDistance, 1, U"Monotone regression...", 0, 0, DO_Dissimilarity_Distance_monotoneRegression); /****** 3 classes ********************************************************/ praat_addAction3 (classDissimilarity, 0, classConfiguration, 1, classSalience, 1, QUERY_BUTTON, 0, 0, 0); praat_addAction3 (classDissimilarity, 0, classConfiguration, 1, classSalience, 1, U"Get VAF...", 0, 1, DO_Dissimilarity_Configuration_Salience_vaf); praat_addAction3 (classDissimilarity, 1, classConfiguration, 1, classWeight, 1, QUERY_BUTTON, 0, 0, 0); praat_addAction3 (classDissimilarity, 1, classConfiguration, 1, classWeight, 1, U"Get stress (monotone mds)...", 0, 1, DO_Dissimilarity_Configuration_Weight_monotone_stress); praat_addAction3 (classDissimilarity, 1, classConfiguration, 1, classWeight, 1, U"Get stress (i-spline mds)...", 0, 1, DO_Dissimilarity_Configuration_Weight_ispline_stress); praat_addAction3 (classDissimilarity, 1, classConfiguration, 1, classWeight, 1, U"Get stress (interval mds)...", 0, 1, DO_Dissimilarity_Configuration_Weight_interval_stress); praat_addAction3 (classDissimilarity, 1, classConfiguration, 1, classWeight, 1, U"Get stress (ratio mds)...", 0, 1, DO_Dissimilarity_Configuration_Weight_ratio_stress); praat_addAction3 (classDissimilarity, 1, classConfiguration, 1, classWeight, 1, U"Get stress (absolute mds)...", 0, 1, DO_Dissimilarity_Configuration_Weight_absolute_stress); praat_addAction3 (classDissimilarity, 1, classConfiguration, 1, classWeight, 1, ANALYSE_BUTTON, 0, 0, 0); praat_addAction3 (classDissimilarity, 1, classConfiguration, 1, classWeight, 1, U"To Configuration (monotone mds)...", 0, 1, DO_Dissimilarity_Configuration_Weight_monotone_mds); praat_addAction3 (classDissimilarity, 1, classConfiguration, 1, classWeight, 1, U"To Configuration (i-spline mds)...", 0, 1, DO_Dissimilarity_Configuration_Weight_ispline_mds); praat_addAction3 (classDissimilarity, 1, classConfiguration, 1, classWeight, 1, U"To Configuration (interval mds)...", 0, 1, DO_Dissimilarity_Configuration_Weight_interval_mds); praat_addAction3 (classDissimilarity, 1, classConfiguration, 1, classWeight, 1, U"To Configuration (ratio mds)...", 0, 1, DO_Dissimilarity_Configuration_Weight_ratio_mds); praat_addAction3 (classDissimilarity, 1, classConfiguration, 1, classWeight, 1, U"To Configuration (absolute mds)...", 0, 1, DO_Dissimilarity_Configuration_Weight_absolute_mds); praat_addAction3 (classDistance, 0, classConfiguration, 1, classSalience, 1, QUERY_BUTTON, 0, 0, 0); praat_addAction3 (classDistance, 0, classConfiguration, 1, classSalience, 1, U"Get VAF...", 0, 1, DO_Distance_Configuration_Salience_vaf); praat_addAction3 (classDistance, 0, classConfiguration, 1, classSalience, 1, U"Analyse", 0, 0, 0); praat_addAction3 (classDistance, 0, classConfiguration, 1, classSalience, 1, U"To Configuration (indscal)...", 0, 0, DO_Distance_Configuration_Salience_indscal); INCLUDE_MANPAGES (manual_MDS_init) } /* End of file praat_MDS_init.c 1775*/ praat-6.0.04/external/000077500000000000000000000000001261542461700145425ustar00rootroot00000000000000praat-6.0.04/external/espeak/000077500000000000000000000000001261542461700160125ustar00rootroot00000000000000praat-6.0.04/external/espeak/Makefile000066400000000000000000000013561261542461700174570ustar00rootroot00000000000000# makefile for libespeak include ../../makefile.defs CPPFLAGS = -I ../../num -I ../../kar -I ../../stat -I ../../sys -I ../../dwsys OBJECTS = compiledict.o dictionary.o intonation.o klatt.o \ numbers.o phonemelist.o readclause.o setlengths.o \ sonic.o speak_lib.o synthdata.o synthesize.o \ synth_mbrola.o tr_languages.o translate.o voices.o wavegen.o \ espeakdata_phons.o espeakdata_dicts.o espeakdata_voices.o espeakdata_variants.o \ espeakdata_FileInMemory.o .PHONY: all clean all: libespeak.a clean: $(RM) $(OBJECTS) $(RM) libespeak.a libespeak.a: $(OBJECTS) touch libespeak.a rm libespeak.a $(AR) cq libespeak.a $(OBJECTS) $(RANLIB) libespeak.a $(OBJECTS): *.h ../../num/NUM.h ../../kar/*.h ../../sys/*.h ../../stat/*.h praat-6.0.04/external/espeak/READ_ME.TXT000066400000000000000000000143231261542461700175120ustar00rootroot00000000000000READ_ME.TXT djmw 20120130 Espeak Version 1.46 The Espeak program and its library use the espeak-data directory as a supply for the data the synthesizer needs. The synthesizer needs the location of this directory to work correctly. The synthesizer's version and the espeak-data version have to match. This is not exceptable in Praat since we don't want these potential mismatches between the internal version of the synthesizer and the external espeak-data directory to occur at all. We have therefore "removed" espeak's dependency on the external espeak-data directory and we have moved all the data to memory. This means that some of the espeak code had to be modified a little bit to accomplish this. ***** Step 1: Use the (private) script "espeakdata_to_code.praat to 1. copy the necessary files from the current espeak distribution to the espeak-work/espeak directory 2. copy files espeakdata_FileInMemory.cpp, espeakdata_FileInMemory.h and Makefile from espeak-work to /espeak-work/espeak 3. Create the files - espeakdata_phons.cpp // phondata, phonindex, phontab, intonations - espeakdata_dicts.cpp // all **_dict files - espeakdata_voices.cpp // all voices in voices/ and subdirs except voices/mb and voices/!v - espeakdata_variants.cpp // all files in voices/!v 4. remove the __cdecl from compiledict.cpp and voices.cpp ***** Step 2 Modify some espeak files >> Adapt speech.h ******* #include "espeakdata_FileInMemory.h" #undef INCLUDE_MBROLA #undef PLATFORM_POSIX #undef PLATFORM_WINDOWS #undef USE_NANOSLEEP #define DATA_FROM_SOURCECODE_FILES #ifdef _WIN32 wchar_t * Melder_peekUtf8ToWcs (const char *string); const uint16_t * Melder_peekWcsToUtf16 (const wchar_t *string); #endif >> voices.cpp : voice_t *LoadVoice(const char *vname, int control) #ifdef DATA_FROM_SOURCECODE_FILES long numberOfBytes; const char * data; if (tone_only) { data = espeakdata_get_voiceVariant (vname, &numberOfBytes); } else { language_type = "en"; data = espeakdata_get_voice (vname, &numberOfBytes); language_type = vname; } if (data == 0) { language_type = "en"; // default data = espeakdata_get_voice ("en/en", &numberOfBytes); } #else ... endif #ifdef DATA_FROM_SOURCECODE_FILES long index = 1; const char *start = data; while (start = espeakdata_get_voicedata (start, numberOfBytes, buf, sizeof(buf), &index)) { #else while((f_voice != NULL) && (fgets_strip(buf,sizeof(buf),f_voice) != NULL)) { #endif >> synthdata : int LoadPhData() #ifdef DATA_FROM_SOURCECODE_FILES long llength; phoneme_tab_data = (unsigned char *) FilesInMemory_getData (espeakdata_phons, L"phontab", &llength); phoneme_index = (USHORT *) FilesInMemory_getData (espeakdata_phons, L"phonindex", &llength); phondata_ptr = (char *) FilesInMemory_getData (espeakdata_phons, L"phondata", &llength); tunes = (TUNE *) FilesInMemory_getData (espeakdata_phons, L"intonations", &llength); length = llength; #else if((phoneme_tab_data = (unsigned char *)ReadPhFile((void *)(phoneme_tab_data),"phontab",NULL)) == NULL) return(-1); if((phoneme_index = (USHORT *)ReadPhFile((void *)(phoneme_index),"phonindex",NULL)) == NULL) return(-1); if((phondata_ptr = ReadPhFile((void *)(phondata_ptr),"phondata",NULL)) == NULL) return(-1); if((tunes = (TUNE *)ReadPhFile((void *)(tunes),"intonations",&length)) == NULL) return(-1); #endif void FreePhData(void) {//================== #ifndef DATA_FROM_SOURCECODE_FILES Free(phoneme_tab_data); Free(phoneme_index); Free(phondata_ptr); Free(tunes); #endif phoneme_tab_data=NULL; phoneme_index=NULL; phondata_ptr=NULL; tunes=NULL; } >> speak_lib.cpp #ifdef DATA_FROM_SOURCECODE_FILES static void init_path(const char *path) { (void) path; } #else static void init_path(const char *path) {//==================================== #ifdef PLATFORM_WINDOWS near line 464: sleep is not a WIN64 function, but luckily we don't need it. // sleep(1) >> dictionary.cpp #ifdef DATA_FROM_SOURCECODE_FILES int LoadDictionary(Translator *tr, const char *name, int no_error) { strcpy (dictionary_name, name); // currently loaded dictionary name strcpy (tr -> dictionary_name, name); // Load a pronunciation data file into memory // bytes 0-3: offset to rules data // bytes 4-7: number of hash table entries if(tr -> data_dictlist != NULL) { Free (tr -> data_dictlist); tr -> data_dictlist = NULL; } unsigned int size; tr -> data_dictlist = (char *) espeakdata_get_dict_data (name, &size); if (tr -> data_dictlist == 0) { return 1; } int *pw = reinterpret_cast (tr -> data_dictlist); int length = Reverse4Bytes (pw[1]); // was int really written with 4 bytes? if (size <= (N_HASH_DICT + sizeof(int)*2)) { Melder_error_ (L"Empty _dict: ", Melder_utf8ToWcs(name), L"_dict."); return(2); } if((Reverse4Bytes(pw[0]) != N_HASH_DICT) || (length <= 0) || (length > 0x8000000)) { Melder_error_ (L"Bad data in dict: ", Melder_utf8ToWcs(name), L" ", Melder_integer (Reverse4Bytes(pw[0])), L" ", Melder_integer (length)); return (2); } tr -> data_dictrules = &(tr->data_dictlist[length]); // set up indices into data_dictrules InitGroups(tr); if (tr -> groups1[0] == NULL) { Melder_error_ (L"Error in ", Melder_peekUtf8ToWcs (name), L"_rules, no default rule group."); } // set up hash table for data_dictlist char *p = &(tr -> data_dictlist[8]); for (int hash = 0; hash < N_HASH_DICT; hash++) { tr -> dict_hashtab[hash] = p; while ((length = *p) != 0) { p += length; } p++; // skip over the zero which terminates the list for this hash value } return (0); } // end of LoadDictionary #else int LoadDictionary_old(Translator *tr, const char *name, int no_error) ************ klatt.cpp *************** replace the gen_noise with the corrected version: static double gen_noise(double noisedummy) // repaired ppgb 20111223 { long temp; static double nlast = 0.0; temp = (long) getrandom (-8191, 8191); kt_globals.nrand = (long) temp; double noise = kt_globals.nrand + (0.75 * nlast); nlast = noise; return(noise); } ??? template T *align_address (T *p) { union { T* ptr; size_t integer; }; const size_t bit_mask = ~(_align_to - 1); ptr = p; Melder_assert (sizeof (size_t) == sizeof (void *)); integer &= bit_mask; return ptr; } praat-6.0.04/external/espeak/StdAfx.h000066400000000000000000000001071261542461700173520ustar00rootroot00000000000000// This is a dummy file. // A file of this name is needed on Windows praat-6.0.04/external/espeak/compiledict.cpp000066400000000000000000001200261261542461700210130ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2005 to 2010 by Jonathan Duddington * * email: jonsd@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write see: * * . * ***************************************************************************/ #include "StdAfx.h" #include #include #include #include #include #include "speak_lib.h" #include "speech.h" #include "phoneme.h" #include "synthesize.h" #include "translate.h" extern void Write4Bytes(FILE *f, int value); int HashDictionary(const char *string); static FILE *f_log = NULL; extern char *dir_dictionary; extern char word_phonemes[N_WORD_PHONEMES]; // a word translated into phoneme codes static int linenum; static int error_count; static int text_mode = 0; static int debug_flag = 0; static int error_need_dictionary = 0; static int hash_counts[N_HASH_DICT]; static char *hash_chains[N_HASH_DICT]; static char letterGroupsDefined[N_LETTER_GROUPS]; MNEM_TAB mnem_rules[] = { {"unpr", 0x01}, {"w_alt2", 0x12}, {"w_alt3", 0x13}, {"w_alt", 0x11}, // note: put longer names before their sub-strings {"p_alt2", 0x22}, {"p_alt3", 0x23}, {"p_alt", 0x21}, {NULL, -1} }; MNEM_TAB mnem_flags[] = { // these in the first group put a value in bits0-3 of dictionary_flags {"$1", 0x41}, // stress on 1st syllable {"$2", 0x42}, // stress on 2nd syllable {"$3", 0x43}, {"$4", 0x44}, {"$5", 0x45}, {"$6", 0x46}, {"$7", 0x47}, {"$u", 0x48}, // reduce to unstressed {"$u1", 0x49}, {"$u2", 0x4a}, {"$u3", 0x4b}, {"$u+", 0x4c}, // reduce to unstressed, but stress at end of clause {"$u1+", 0x4d}, {"$u2+", 0x4e}, {"$u3+", 0x4f}, // these set the corresponding numbered bit if dictionary_flags {"$pause", 8}, /* ensure pause before this word */ {"$only", 9}, /* only match on this word without suffix */ {"$onlys", 10}, /* only match with none, or with 's' suffix */ {"$strend", 11}, /* full stress if at end of clause */ {"$strend2", 12}, /* full stress if at end of clause, or only followed by unstressed */ {"$unstressend",13}, /* reduce stress at end of clause */ {"$atend", 14}, /* use this pronunciation if at end of clause */ {"$atstart", 15}, // use this pronunciation at start of clause {"$abbrev", 17}, /* use this pronuciation rather than split into letters */ {"$stem", 18}, // must have a suffix // language specific {"$double", 19}, // IT double the initial consonant of next word {"$alt", 20}, // use alternative pronunciation {"$alt1", 20}, // synonym for $alt {"$alt2", 21}, {"$alt3", 22}, {"$combine", 23}, // Combine with the next word {"$dot", 24}, // ignore '.' after this word (abbreviation) {"$hasdot", 25}, // use this pronunciation if there is a dot after the word {"$max3", 27}, // limit to 3 repetitions {"$brk", 28}, // a shorter $pause {"$text", 29}, // word translates to replcement text, not phonemes // flags in dictionary word 2 {"$verbf", 0x20}, /* verb follows */ {"$verbsf", 0x21}, /* verb follows, allow -s suffix */ {"$nounf", 0x22}, /* noun follows */ {"$pastf", 0x23}, /* past tense follows */ {"$verb", 0x24}, /* use this pronunciation when its a verb */ {"$noun", 0x25}, /* use this pronunciation when its a noun */ {"$past", 0x26}, /* use this pronunciation when its past tense */ {"$verbextend",0x28}, /* extend influence of 'verb follows' */ {"$capital", 0x29}, /* use this pronunciation if initial letter is upper case */ {"$allcaps", 0x2a}, /* use this pronunciation if initial letter is upper case */ {"$accent", 0x2b}, // character name is base-character name + accent name {"$sentence",0x2d}, // only if this clause is a sentence (i.e. terminator is {. ? !} not {, ; :} // doesn't set dictionary_flags {"$?", 100}, // conditional rule, followed by byte giving the condition number {"$textmode", 200}, {"$phonememode", 201}, {NULL, -1} }; #define LEN_GROUP_NAME 12 typedef struct { char name[LEN_GROUP_NAME+1]; unsigned int start; unsigned int length; int group3_ix; } RGROUP; int isspace2(unsigned int c) {//========================= // can't use isspace() because on Windows, isspace(0xe1) gives TRUE ! int c2; if(((c2 = (c & 0xff)) == 0) || (c > ' ')) return(0); return(1); } static FILE *fopen_log(const char *fname,const char *access) {//================================================== // performs fopen, but produces error message to f_log if it fails FILE *f; if((f = fopen(fname,access)) == NULL) { if(f_log != NULL) fprintf(f_log,"Can't access (%s) file '%s'\n",access,fname); } return(f); } const char *LookupMnemName(MNEM_TAB *table, const int value) //========================================================== /* Lookup a mnemonic string in a table, return its name */ { while(table->mnem != NULL) { if(table->value==value) return(table->mnem); table++; } return(""); /* not found */ } /* end of LookupMnemValue */ char *print_dictionary_flags(unsigned int *flags) {//============================================== static char buf[20]; sprintf(buf,"%s 0x%x/%x",LookupMnemName(mnem_flags,(flags[0] & 0xf)+0x40), flags[0], flags[1]); return(buf); } char *DecodeRule(const char *group_chars, int group_length, char *rule, int control) {//================================================================================= /* Convert compiled match template to ascii */ unsigned char rb; unsigned char c; char *p; int ix; int match_type; int finished=0; int value; int linenum=0; int flags; int suffix_char; int condition_num=0; int at_start = 0; const char *name; char buf[60]; char buf_pre[60]; char suffix[20]; static char output[60]; static char symbols[] = {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', '&','%','+','#','S','D','Z','A','L','!',' ','@','?','J','N','K','V','?','T','X','?','W'}; static char symbols_lg[] = {'A','B','C','H','F','G','Y'}; match_type = 0; buf_pre[0] = 0; for(ix=0; ix> 8)) suffix_char = 'P'; sprintf(suffix,"%c%d",suffix_char,rule[2] & 0x7f); rule += 3; for(ix=0;ix<9;ix++) { if(flags & 1) sprintf(&suffix[strlen(suffix)],"%c",flag_chars[ix]); flags = (flags >> 1); } strcpy(p,suffix); p += strlen(suffix); c = ' '; } else if(rb == RULE_LETTERGP) { c = symbols_lg[*rule++ - 'A']; } else if(rb == RULE_LETTERGP2) { value = *rule++ - 'A'; p[0] = 'L'; p[1] = (value / 10) + '0'; c = (value % 10) + '0'; if(match_type == RULE_PRE) { p[0] = c; c = 'L'; } p+=2; } else if(rb <= RULE_LAST_RULE) c = symbols[rb]; else if(rb == RULE_SPACE) c = '_'; else c = rb; *p++ = c; } *p = 0; p = output; if(linenum > 0) { sprintf(p,"%5d:\t",linenum); p += 7; } if(condition_num > 0) { sprintf(p,"?%d ",condition_num); p = &p[strlen(p)]; } if(((ix = strlen(buf_pre)) > 0) || at_start) { if(at_start) *p++ = '_'; while(--ix >= 0) *p++ = buf_pre[ix]; *p++ = ')'; *p++ = ' '; } *p = 0; strcat(p,buf); ix = strlen(output); while(ix < 8) output[ix++]=' '; output[ix]=0; return(output); } /* end of DecodeRule */ static int compile_line(char *linebuf, char *dict_line, int *hash) {//=============================================================== // Compile a line in the language_list file unsigned char c; char *p; char *word; char *phonetic; unsigned int ix; int step; unsigned int n_flag_codes = 0; int flagnum; int flag_offset; int length; int multiple_words = 0; int multiple_numeric_hyphen = 0; char *multiple_string = NULL; char *multiple_string_end = NULL; int len_word; int len_phonetic; int text_not_phonemes; // this word specifies replacement text, not phonemes unsigned int wc; int all_upper_case; char *mnemptr; unsigned char flag_codes[100]; char encoded_ph[200]; unsigned char bad_phoneme[4]; static char nullstring[] = {0}; text_not_phonemes = 0; phonetic = word = nullstring; p = linebuf; // while(isspace2(*p)) p++; #ifdef deleted if(*p == '$') { if(memcmp(p,"$textmode",9) == 0) { text_mode = 1; return(0); } if(memcmp(p,"$phonememode",12) == 0) { text_mode = 0; return(0); } } #endif step = 0; c = 0; while(c != '\n') { c = *p; if((c == '?') && (step==0)) { // conditional rule, allow only if the numbered condition is set for the voice flag_offset = 100; p++; if(*p == '!') { // allow only if the numbered condition is NOT set flag_offset = 132; p++; } ix = 0; if(isdigit(*p)) { ix += (*p-'0'); p++; } if(isdigit(*p)) { ix = ix*10 + (*p-'0'); p++; } flag_codes[n_flag_codes++] = ix + flag_offset; c = *p; } if((c == '$') && isalnum(p[1])) { /* read keyword parameter */ mnemptr = p; while(!isspace2(c = *p)) p++; *p = 0; flagnum = LookupMnem(mnem_flags,mnemptr); if(flagnum > 0) { if(flagnum == 200) { text_mode = 1; } else if(flagnum == 201) { text_mode = 0; } else if(flagnum == BITNUM_FLAG_TEXTMODE) { text_not_phonemes = 1; } else { flag_codes[n_flag_codes++] = flagnum; } } else { fprintf(f_log,"%5d: Unknown keyword: %s\n",linenum,mnemptr); error_count++; } } if((c == '/') && (p[1] == '/') && (multiple_words==0)) { c = '\n'; /* "//" treat comment as end of line */ } switch(step) { case 0: if(c == '(') { multiple_words = 1; word = p+1; step = 1; } else if(!isspace2(c)) { word = p; step = 1; } break; case 1: if((c == '-') && multiple_words) { if(isdigit(word[0])) { multiple_numeric_hyphen = 1; } // else // ??? { flag_codes[n_flag_codes++] = BITNUM_FLAG_HYPHENATED; } c = ' '; } if(isspace2(c)) { p[0] = 0; /* terminate english word */ if(multiple_words) { multiple_string = multiple_string_end = p+1; step = 2; } else { step = 3; } } else if(c == ')') { if(multiple_words) { p[0] = 0; multiple_words = 0; step = 3; } else if(word[0] != '_') { fprintf(f_log, "%5d: Missing '('\n", linenum); error_count++; step = 3; } } break; case 2: if(isspace2(c)) { multiple_words++; } else if(c == ')') { p[0] = ' '; // terminate extra string multiple_string_end = p+1; step = 3; } break; case 3: if(!isspace2(c)) { phonetic = p; step = 4; } break; case 4: if(isspace2(c)) { p[0] = 0; /* terminate phonetic */ step = 5; } break; case 5: break; } p++; } if(word[0] == 0) { return(0); /* blank line */ } if(text_mode) text_not_phonemes = 1; if(text_not_phonemes) { if(word[0] == '_') { // This is a special word, used by eSpeak. Translate this into phonemes now strcat(phonetic, " "); // need a space to indicate word-boundary // PROBLEM vowel reductions are not applied to the translated phonemes // condition rules are not applied TranslateWord(translator,phonetic,0,NULL); text_not_phonemes = 0; strncpy0(encoded_ph, word_phonemes, N_WORD_BYTES-4); if((word_phonemes[0] == 0) && (error_need_dictionary < 3)) { // the dictionary was not loaded, we need a second attempt error_need_dictionary++; fprintf(f_log,"%5d: Need to compile dictionary again\n",linenum); } { //char decoded_phonemes[128]; //DecodePhonemes(word_phonemes,decoded_phonemes); //printf("Translator %x %s [%s] [%s]\n",translator->translator_name,word,phonetic,decoded_phonemes); } } else { // this is replacement text, so don't encode as phonemes. Restrict the length of the replacement word strncpy0(encoded_ph,phonetic,N_WORD_BYTES-4); } } else { EncodePhonemes(phonetic,encoded_ph,bad_phoneme); if(strchr(encoded_ph,phonSWITCH) != 0) { flag_codes[n_flag_codes++] = BITNUM_FLAG_ONLY_S; // don't match on suffixes (except 's') when switching languages } // check for errors in the phonemes codes if(bad_phoneme[0] != 0) { // unrecognised phoneme, report error fprintf(f_log,"%5d: Bad phoneme [%c] (0x%x) in: %s %s\n",linenum,bad_phoneme[0],bad_phoneme[0],word,phonetic); error_count++; } } if(text_not_phonemes != translator->langopts.textmode) { flag_codes[n_flag_codes++] = BITNUM_FLAG_TEXTMODE; } if(sscanf(word,"U+%x",&wc) == 1) { // Character code ix = utf8_out(wc, word); word[ix] = 0; } else if(word[0] != '_') { // convert to lower case, and note if the word is all-capitals int c2; all_upper_case = 1; p = word; for(p=word;;) { // this assumes that the lower case char is the same length as the upper case char // OK, except for Turkish "I", but use towlower() rather than towlower2() ix = utf8_in(&c2,p); if(c2 == 0) break; if(iswupper(c2)) { utf8_out(towlower(c2),p); } else { all_upper_case = 0; } p += ix; } if(all_upper_case) { flag_codes[n_flag_codes++] = BITNUM_FLAG_ALLCAPS; } } len_word = strlen(word); if(translator->transpose_min > 0) { len_word = TransposeAlphabet(translator, word); } *hash = HashDictionary(word); len_phonetic = strlen(encoded_ph); dict_line[1] = len_word; // bit 6 indicates whether the word has been compressed len_word &= 0x3f; memcpy(&dict_line[2],word,len_word); if(len_phonetic == 0) { // no phonemes specified. set bit 7 dict_line[1] |= 0x80; length = len_word + 2; } else { length = len_word + len_phonetic + 3; strcpy(&dict_line[(len_word)+2],encoded_ph); } for(ix=0; ix 0)) { if(multiple_words > 10) { fprintf(f_log,"%5d: Two many parts in a multi-word entry: %d\n",linenum,multiple_words); error_count++; } else { dict_line[length++] = 80 + multiple_words; ix = multiple_string_end - multiple_string; if(multiple_numeric_hyphen) { dict_line[length++] = ' '; // ??? } memcpy(&dict_line[length],multiple_string,ix); length += ix; } } dict_line[0] = length; return(length); } /* end of compile_line */ static void compile_dictlist_start(void) {//===================================== // initialise dictionary list int ix; char *p; char *p2; for(ix=0; ix= '0') && (c <= '9')) return(c - '0'); if((c >= 'a') && (c <= 'f')) return(c - 'a' + 10); if((c >= 'A') && (c <= 'F')) return(c - 'A' + 10); return(-1); } static void copy_rule_string(char *string, int &state) {//=================================================== // state 0: conditional, 1=pre, 2=match, 3=post, 4=phonemes static char *outbuf[5] = {rule_cond, rule_pre, rule_match, rule_post, rule_phonemes}; static int next_state[5] = {2,2,4,4,4}; char *output; char *p; int ix; int len; char c; int c2, c3; int sxflags; int value; int literal; int hexdigit_input = 0; MNEM_TAB *mr; if(string[0] == 0) return; output = outbuf[state]; if(state==4) { // append to any previous phoneme string, i.e. allow spaces in the phoneme string len = strlen(rule_phonemes); if(len > 0) rule_phonemes[len++] = ' '; output = &rule_phonemes[len]; } sxflags = 0x808000; // to ensure non-zero bytes for(p=string,ix=0;;) { literal = 0; c = *p++; if((c == '0') && (p[0] == 'x') && (isHexDigit(p[1]) >= 0) && (isHexDigit(p[2]) >= 0)) { hexdigit_input = 1; c = p[1]; p+= 2; } if(c == '\\') { c = *p++; // treat next character literally //#ifdef deleted if((c >= '0') && (c <= '3') && (p[0] >= '0') && (p[0] <= '7') && (p[1] >= '0') && (p[1] <= '7')) { // character code given by 3 digit octal value; c = (c-'0')*64 + (p[0]-'0')*8 + (p[1]-'0'); p += 2; } //endif literal = 1; } if(hexdigit_input) { if(((c2 = isHexDigit(c)) >= 0) && ((c3 = isHexDigit(p[0])) >= 0)) { c = c2 * 16 + c3; literal = 1; p++; } else { hexdigit_input = 0; } } if((state==1) || (state==3)) { // replace special characters (note: 'E' is reserved for a replaced silent 'e') if(literal == 0) { static const char lettergp_letters[9] = {LETTERGP_A,LETTERGP_B,LETTERGP_C,0,0,LETTERGP_F,LETTERGP_G,LETTERGP_H,LETTERGP_Y}; switch(c) { case '_': c = RULE_SPACE; break; case 'Y': c = 'I'; // drop through to next case case 'A': // vowel case 'B': case 'C': case 'H': case 'F': case 'G': if(state == 1) { // pre-rule, put the number before the RULE_LETTERGP; output[ix++] = lettergp_letters[c-'A'] + 'A'; c = RULE_LETTERGP; } else { output[ix++] = RULE_LETTERGP; c = lettergp_letters[c-'A'] + 'A'; } break; case 'D': c = RULE_DIGIT; break; case 'K': c = RULE_NOTVOWEL; break; case 'N': c = RULE_NO_SUFFIX; break; case 'V': c = RULE_IFVERB; break; case 'Z': c = RULE_NONALPHA; break; case '+': c = RULE_INC_SCORE; break; case '@': c = RULE_SYLLABLE; break; case '&': c = RULE_STRESSED; break; case '%': c = RULE_DOUBLE; break; case '#': c = RULE_DEL_FWD; break; case '!': c = RULE_CAPITAL; break; case 'T': output[ix++] = RULE_DOLLAR; c = 0x11; break; case 'W': c = RULE_SPELLING; break; case 'X': c = RULE_NOVOWELS; break; case 'J': c = RULE_SKIPCHARS; break; case 'L': // expect two digits c = *p++ - '0'; value = *p++ - '0'; c = c * 10 + value; if((value < 0) || (value > 9)) { c = 0; fprintf(f_log,"%5d: Expected 2 digits after 'L'\n",linenum); error_count++; } else if((c <= 0) || (c >= N_LETTER_GROUPS) || (letterGroupsDefined[(int)c] == 0)) { fprintf(f_log,"%5d: Letter group L%.2d not defined\n",linenum,c); error_count++; } c += 'A'; if(state == 1) { // pre-rule, put the group number before the RULE_LETTERGP command output[ix++] = c; c = RULE_LETTERGP2; } else { output[ix++] = RULE_LETTERGP2; } break; case '$': output[ix++] = RULE_DOLLAR; c = 0; mr = mnem_rules; while(mr->mnem != NULL) { len = strlen(mr->mnem); if(memcmp(p, mr->mnem, len) == 0) { c = mr->value; p += len; break; } mr++; } if(c == 0) { fprintf(f_log,"%5d: $ command not recognized\n",linenum); error_count++; } break; case 'P': sxflags |= SUFX_P; // Prefix, now drop through to Suffix case 'S': output[ix++] = RULE_ENDING; value = 0; while(!isspace2(c = *p++) && (c != 0)) { switch(c) { case 'e': sxflags |= SUFX_E; break; case 'i': sxflags |= SUFX_I; break; case 'p': // obsolete, replaced by 'P' above sxflags |= SUFX_P; break; case 'v': sxflags |= SUFX_V; break; case 'd': sxflags |= SUFX_D; break; case 'f': sxflags |= SUFX_F; break; case 'q': sxflags |= SUFX_Q; break; case 't': sxflags |= SUFX_T; break; case 'b': sxflags |= SUFX_B; break; case 'a': sxflags |= SUFX_A; break; default: if(isdigit(c)) value = (value*10) + (c - '0'); break; } } p--; output[ix++] = sxflags >> 16; output[ix++] = sxflags >> 8; c = value | 0x80; break; } } } output[ix++] = c; if(c == 0) break; } state = next_state[state]; } // end of copy_rule_string static char *compile_rule(char *input) {//=================================== int ix; unsigned char c; int wc; char *p; char *prule; int len; int len_name; int start; int state=2; int finish=0; char buf[80]; char output[150]; unsigned char bad_phoneme[4]; buf[0]=0; rule_cond[0]=0; rule_pre[0]=0; rule_post[0]=0; rule_match[0]=0; rule_phonemes[0]=0; p = buf; for(ix=0; finish==0; ix++) { c = input[ix]; switch(c = input[ix]) { case ')': // end of prefix section *p = 0; state = 1; copy_rule_string(buf,state); p = buf; break; case '(': // start of suffix section *p = 0; state = 2; copy_rule_string(buf,state); state = 3; p = buf; if(input[ix+1] == ' ') { fprintf(f_log,"%5d: Syntax error. Space after (\n",linenum); error_count++; } break; case '\n': // end of line case '\r': case 0: // end of line *p = 0; copy_rule_string(buf,state); finish=1; break; case '\t': // end of section section case ' ': *p = 0; copy_rule_string(buf,state); p = buf; break; case '?': if(state==2) state=0; else *p++ = c; break; default: *p++ = c; break; } } if(strcmp(rule_match,"$group")==0) strcpy(rule_match,group_name); if(rule_match[0]==0) { if(rule_post[0] != 0) { fprintf(f_log,"%5d: Syntax error\n",linenum); error_count++; } return(NULL); } EncodePhonemes(rule_phonemes,buf,bad_phoneme); if(bad_phoneme[0] != 0) { fprintf(f_log,"%5d: Bad phoneme [%c] in %s\n",linenum,bad_phoneme[0],input); error_count++; } strcpy(output,buf); len = strlen(buf)+1; len_name = strlen(group_name); if((len_name > 0) && (memcmp(rule_match,group_name,len_name) != 0)) { utf8_in(&wc,rule_match); if((group_name[0] == '9') && IsDigit(wc)) { // numeric group, rule_match starts with a digit, so OK } else { fprintf(f_log,"%5d: Wrong initial letters '%s' for group '%s'\n",linenum,rule_match,group_name); error_count++; } } strcpy(&output[len],rule_match); len += strlen(rule_match); if(debug_flag) { output[len] = RULE_LINENUM; output[len+1] = (linenum % 255) + 1; output[len+2] = (linenum / 255) + 1; len+=3; } if(rule_cond[0] != 0) { ix = -1; if(rule_cond[0] == '!') { // allow the rule only if the condition number is NOT set for the voice ix = atoi(&rule_cond[1]) + 32; } else { // allow the rule only if the condition number is set for the voice ix = atoi(rule_cond); } if((ix > 0) && (ix < 255)) { output[len++] = RULE_CONDITION; output[len++] = ix; } else { fprintf(f_log,"%5d: bad condition number ?%d\n",linenum,ix); error_count++; } } if(rule_pre[0] != 0) { start = 0; if(rule_pre[0] == RULE_SPACE) { // omit '_' at the beginning of the pre-string and imply it by using RULE_PRE_ATSTART c = RULE_PRE_ATSTART; start = 1; } else { c = RULE_PRE; } output[len++] = c; // output PRE string in reverse order for(ix = strlen(rule_pre)-1; ix>=start; ix--) output[len++] = rule_pre[ix]; } if(rule_post[0] != 0) { sprintf(&output[len],"%c%s",RULE_POST,rule_post); len += (strlen(rule_post)+1); } output[len++]=0; prule = (char *)malloc(len); memcpy(prule,output,len); return(prule); } // end of compile_rule int string_sorter(char **a, char **b) {//=========================================== char *pa, *pb; int ix; if((ix = strcmp(pa = *a,pb = *b)) != 0) return(ix); pa += (strlen(pa)+1); pb += (strlen(pb)+1); return(strcmp(pa,pb)); } /* end of string_sorter */ static int rgroup_sorter(RGROUP *a, RGROUP *b) {//=================================================== // Sort long names before short names int ix; ix = strlen(b->name) - strlen(a->name); if(ix != 0) return(ix); ix = strcmp(a->name,b->name); if(ix != 0) return(ix); return(a->start-b->start); } #ifdef OUTPUT_FORMAT static void print_rule_group(FILE *f_out, int n_rules, char **rules, char *name) {//============================================================================= int rule; int ix; unsigned char c; int len1; int len2; int spaces; char *p; char *pout; int condition; char buf[80]; char suffix[12]; static unsigned char symbols[] = {'@','&','%','+','#','$','D','Z','A','B','C','F'}; fprintf(f_out,"\n$group %s\n",name); for(rule=0; rule 0) { sprintf(buf,"?%d ",condition); spaces -= strlen(buf); fprintf(f_out,"%s",buf); } if(rule_pre[0] != 0) { p = buf; for(ix=strlen(rule_pre)-1;ix>=0;ix--) *p++ = rule_pre[ix]; sprintf(p,") "); spaces -= strlen(buf); for(ix=0; ix 30) printf("Group %s %c %d\n",name,ix,nextchar_count[ix]); } #endif } // end of output_rule_group static int compile_lettergroup(char *input, FILE *f_out) {//===================================================== char *p; char *p_start; int group; int ix; int n_items; int length; int max_length = 0; #define N_LETTERGP_ITEMS 200 char *items[N_LETTERGP_ITEMS]; char item_length[N_LETTERGP_ITEMS]; p = input; if(!isdigit(p[0]) || !isdigit(p[1])) { fprintf(f_log,"%5d: Expected 2 digits after '.L'\n",linenum); error_count++; return(1); } group = atoi(&p[0]); if(group >= N_LETTER_GROUPS) { fprintf(f_log,"%5d: lettergroup out of range (01-%.2d)\n",linenum,N_LETTER_GROUPS-1); error_count++; return(1); } while(!isspace2(*p)) p++; fputc(RULE_GROUP_START,f_out); fputc(RULE_LETTERGP2,f_out); fputc(group + 'A', f_out); if(letterGroupsDefined[group] != 0) { fprintf(f_log,"%5d: lettergroup L%.2d is already defined\n",linenum,group); error_count++; } letterGroupsDefined[group] = 1; n_items = 0; while(n_items < N_LETTERGP_ITEMS) { while(isspace2(*p)) p++; if(*p == 0) break; items[n_items] = p_start = p; while((*p & 0xff) > ' ') { p++; } *p++ = 0; length = p - p_start; if(length > max_length) max_length = length; item_length[n_items++] = length; } // write out the items, longest first while(max_length > 1) { for(ix=0; ix < n_items; ix++) { if(item_length[ix] == max_length) { fwrite(items[ix],1,max_length,f_out); } } max_length--; } fputc(RULE_GROUP_END,f_out); return(0); } static int compile_dictrules(FILE *f_in, FILE *f_out, char *fname_temp) {//==================================================================== char *prule; unsigned char *p; int ix; int c; int gp; FILE *f_temp; int n_rules=0; int count=0; int different; int wc; const char *prev_rgroup_name; unsigned int char_code; int compile_mode=0; char *buf; char buf1[500]; char *rules[N_RULES]; int n_rgroups = 0; int n_groups3 = 0; RGROUP rgroup[N_RULE_GROUP2]; linenum = 0; group_name[0] = 0; if((f_temp = fopen_log(fname_temp,"wb")) == NULL) return(1); for(;;) { linenum++; buf = fgets(buf1,sizeof(buf1),f_in); if(buf != NULL) { if((p = (unsigned char *)strstr(buf,"//")) != NULL) *p = 0; if(buf[0] == '\r') buf++; // ignore extra \r in \r\n } if((buf == NULL) || (buf[0] == '.')) { // next .group or end of file, write out the previous group if(n_rules > 0) { strcpy(rgroup[n_rgroups].name,group_name); rgroup[n_rgroups].group3_ix = group3_ix; rgroup[n_rgroups].start = ftell(f_temp); output_rule_group(f_temp,n_rules,rules,group_name); rgroup[n_rgroups].length = ftell(f_temp) - rgroup[n_rgroups].start; n_rgroups++; count += n_rules; } n_rules = 0; if(compile_mode == 2) { // end of the character replacements section fwrite(&n_rules,1,4,f_out); // write a zero word to terminate the replacemenmt list compile_mode = 0; } if(buf == NULL) break; // end of file if(memcmp(buf,".L",2)==0) { compile_lettergroup(&buf[2], f_out); continue; } if(memcmp(buf,".replace",8)==0) { compile_mode = 2; fputc(RULE_GROUP_START,f_out); fputc(RULE_REPLACEMENTS,f_out); // advance to next word boundary while((ftell(f_out) & 3) != 0) fputc(0,f_out); } if(memcmp(buf,".group",6)==0) { compile_mode = 1; p = (unsigned char *)&buf[6]; while((p[0]==' ') || (p[0]=='\t')) p++; // Note: Windows isspace(0xe1) gives TRUE ! ix = 0; while((*p > ' ') && (ix < LEN_GROUP_NAME)) group_name[ix++] = *p++; group_name[ix]=0; group3_ix = 0; if(sscanf(group_name,"0x%x",&char_code)==1) { // group character is given as a character code (max 16 bits) p = (unsigned char *)group_name; if(char_code > 0x100) { *p++ = (char_code >> 8); } *p++ = char_code; *p = 0; } else { if(translator->letter_bits_offset > 0) { utf8_in(&wc, group_name); if(((ix = (wc - translator->letter_bits_offset)) >= 0) && (ix < 128)) { group3_ix = ix+1; // not zero } } } if((group3_ix == 0) && (strlen(group_name) > 2)) { if(utf8_in(&c,group_name) < 2) { fprintf(f_log,"%5d: Group name longer than 2 bytes (UTF8)",linenum); error_count++; } group_name[2] = 0; } } continue; } switch(compile_mode) { case 1: // .group prule = compile_rule(buf); if((prule != NULL) && (n_rules < N_RULES)) { rules[n_rules++] = prule; } break; case 2: // .replace { int replace1; int replace2; char *p; p = buf; replace1 = 0; replace2 = 0; while(isspace2(*p)) p++; ix = 0; while((unsigned char)(*p) > 0x20) // not space or zero-byte { p += utf8_in(&c,p); replace1 += (c << ix); ix += 16; } while(isspace2(*p)) p++; ix = 0; while((unsigned char)(*p) > 0x20) { p += utf8_in(&c,p); replace2 += (c << ix); ix += 16; } if(replace1 != 0) { Write4Bytes(f_out,replace1); // write as little-endian Write4Bytes(f_out,replace2); // if big-endian, reverse the bytes in LoadDictionary() } } break; } } fclose(f_temp); qsort((void *)rgroup,n_rgroups,sizeof(rgroup[0]),(int (*)(const void *,const void *))rgroup_sorter); if((f_temp = fopen(fname_temp,"rb"))==NULL) return(2); prev_rgroup_name = "\n"; for(gp = 0; gp < n_rgroups; gp++) { fseek(f_temp,rgroup[gp].start,SEEK_SET); if((different = strcmp(rgroup[gp].name, prev_rgroup_name)) != 0) { // not the same as the previous group if(gp > 0) fputc(RULE_GROUP_END,f_out); fputc(RULE_GROUP_START,f_out); if(rgroup[gp].group3_ix != 0) { n_groups3++; fputc(1,f_out); fputc(rgroup[gp].group3_ix, f_out); } else { fprintf(f_out, "%s", prev_rgroup_name = rgroup[gp].name); } fputc(0,f_out); } for(ix=rgroup[gp].length; ix>0; ix--) { c = fgetc(f_temp); fputc(c,f_out); } if(different) { } } fputc(RULE_GROUP_END,f_out); fputc(0,f_out); fclose(f_temp); remove(fname_temp); fprintf(f_log,"\t%d rules, %d groups (%d)\n\n",count,n_rgroups,n_groups3); return(0); } // end of compile_dictrules int CompileDictionary(const char *dsource, const char *dict_name, FILE *log, char *fname_err, int flags) {//===================================================================================================== // fname: space to write the filename in case of error // flags: bit 0: include source line number information, for debug purposes. FILE *f_in; FILE *f_out; int offset_rules=0; int value; char fname_in[sizeof(path_home)+45]; char fname_out[sizeof(path_home)+15]; char fname_temp[sizeof(path_home)+15]; char path[sizeof(path_home)+40]; // path_dsource+20 error_count = 0; error_need_dictionary = 0; memset(letterGroupsDefined,0,sizeof(letterGroupsDefined)); debug_flag = flags & 1; if(dsource == NULL) dsource = ""; f_log = log; //f_log = fopen("log2.txt","w"); if(f_log == NULL) f_log = stderr; // try with and without '.txt' extension sprintf(path,"%s%s_",dsource,dict_name); sprintf(fname_in,"%srules.txt",path); if((f_in = fopen(fname_in,"r")) == NULL) { sprintf(fname_in,"%srules",path); if((f_in = fopen_log(fname_in,"r")) == NULL) { if(fname_err) strcpy(fname_err,fname_in); return(-1); } } sprintf(fname_out,"%s%c%s_dict",path_home,PATHSEP,dict_name); if((f_out = fopen_log(fname_out,"wb+")) == NULL) { if(fname_err) strcpy(fname_err,fname_in); return(-1); } sprintf(fname_temp,"%s%ctemp",path_home,PATHSEP); value = N_HASH_DICT; Write4Bytes(f_out,value); Write4Bytes(f_out,offset_rules); compile_dictlist_start(); fprintf(f_log,"Using phonemetable: '%s'\n",phoneme_tab_list[phoneme_tab_number].name); compile_dictlist_file(path,"roots"); if(translator->langopts.listx) { compile_dictlist_file(path,"list"); compile_dictlist_file(path,"listx"); } else { compile_dictlist_file(path,"listx"); compile_dictlist_file(path,"list"); } compile_dictlist_file(path,"extra"); compile_dictlist_end(f_out); offset_rules = ftell(f_out); fprintf(f_log,"Compiling: '%s'\n",fname_in); compile_dictrules(f_in,f_out,fname_temp); fclose(f_in); fseek(f_out,4,SEEK_SET); Write4Bytes(f_out,offset_rules); fclose(f_out); LoadDictionary(translator, dict_name, 0); return(error_count); } // end of compile_dictionary praat-6.0.04/external/espeak/debug.h000066400000000000000000000010231261542461700172450ustar00rootroot00000000000000#ifndef DEBUG_H #define DEBUG_H //#define DEBUG_ENABLED #ifdef DEBUG_ENABLED #define ENTER(text) debug_enter(text) #define SHOW(format,...) debug_show(format,__VA_ARGS__); #define SHOW_TIME(text) debug_time(text); extern void debug_enter(const char* text); extern void debug_show(const char* format,...); extern void debug_time(const char* text); #else #ifdef NO_VARIADIC_MACROS #define SHOW(format) // VC6 doesn't allow "..." #else #define SHOW(format,...) #endif #define SHOW_TIME(text) #define ENTER(text) #endif #endif praat-6.0.04/external/espeak/dictionary.cpp000066400000000000000000002535621261542461700207000ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2005 to 2011 by Jonathan Duddington * * email: jonsd@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write see: * * . * ***************************************************************************/ #include "StdAfx.h" #include #include #include #include #include #include #include "speak_lib.h" #include "speech.h" #include "phoneme.h" #include "synthesize.h" #include "translate.h" int dictionary_skipwords; char dictionary_name[40]; extern char *print_dictionary_flags(unsigned int *flags); extern char *DecodeRule(const char *group_chars, int group_length, char *rule, int control); // accented characters which indicate (in some languages) the start of a separate syllable //static const unsigned short diereses_list[7] = {L'ä',L'ë',L'ï',L'ö',L'ü',L'ÿ',0}; static const unsigned short diereses_list[7] = {0xe4,0xeb,0xef,0xf6,0xfc,0xff,0}; // convert characters to an approximate 7 bit ascii equivalent // used for checking for vowels (up to 0x259=schwa) #define N_REMOVE_ACCENT 0x25e static unsigned char remove_accent[N_REMOVE_ACCENT] = { 'a','a','a','a','a','a','a','c','e','e','e','e','i','i','i','i', // 0c0 'd','n','o','o','o','o','o', 0, 'o','u','u','u','u','y','t','s', // 0d0 'a','a','a','a','a','a','a','c','e','e','e','e','i','i','i','i', // 0e0 'd','n','o','o','o','o','o', 0 ,'o','u','u','u','u','y','t','y', // 0f0 'a','a','a','a','a','a','c','c','c','c','c','c','c','c','d','d', // 100 'd','d','e','e','e','e','e','e','e','e','e','e','g','g','g','g', // 110 'g','g','g','g','h','h','h','h','i','i','i','i','i','i','i','i', // 120 'i','i','i','i','j','j','k','k','k','l','l','l','l','l','l','l', // 130 'l','l','l','n','n','n','n','n','n','n','n','n','o','o','o','o', // 140 'o','o','o','o','r','r','r','r','r','r','s','s','s','s','s','s', // 150 's','s','t','t','t','t','t','t','u','u','u','u','u','u','u','u', // 160 'u','u','u','u','w','w','y','y','y','z','z','z','z','z','z','s', // 170 'b','b','b','b', 0, 0, 'o','c','c','d','d','d','d','d','e','e', // 180 'e','f','f','g','g','h','i','i','k','k','l','l','m','n','n','o', // 190 'o','o','o','o','p','p','y', 0, 0, 's','s','t','t','t','t','u', // 1a0 'u','u','v','y','y','z','z','z','z','z','z','z', 0, 0, 0, 'w', // 1b0 't','t','t','k','d','d','d','l','l','l','n','n','n','a','a','i', // 1c0 'i','o','o','u','u','u','u','u','u','u','u','u','u','e','a','a', // 1d0 'a','a','a','a','g','g','g','g','k','k','o','o','o','o','z','z', // 1e0 'j','d','d','d','g','g','w','w','n','n','a','a','a','a','o','o', // 1f0 'a','a','a','a','e','e','e','e','i','i','i','i','o','o','o','o', // 200 'r','r','r','r','u','u','u','u','s','s','t','t','y','y','h','h', // 210 'n','d','o','o','z','z','a','a','e','e','o','o','o','o','o','o', // 220 'o','o','y','y','l','n','t','j','d','q','a','c','c','l','t','s', // 230 'z', 0, 0, 'b','u','v','e','e','j','j','q','q','r','r','y','y', // 240 'a','a','a','b','o','c','d','d','e','e','e','e','e','e' }; void strncpy0(char *to,const char *from, int size) {//=============================================== // strcpy with limit, ensures a zero terminator strncpy(to,from,size); to[size-1] = 0; } int Reverse4Bytes(int word) {//======================== // reverse the order of bytes from little-endian to big-endian #ifdef ARCH_BIG int ix; int word2 = 0; for(ix=0; ix<=24; ix+=8) { word2 = word2 << 8; word2 |= (word >> ix) & 0xff; } return(word2); #else return(word); #endif } int LookupMnem(MNEM_TAB *table, const char *string) {//================================================ while(table->mnem != NULL) { if(strcmp(string,table->mnem)==0) return(table->value); table++; } return(table->value); } //============================================================================================= // Read pronunciation rules and pronunciation lookup dictionary // //============================================================================================= static void InitGroups(Translator *tr) {//=================================== /* Called after dictionary 1 is loaded, to set up table of entry points for translation rule chains for single-letters and two-letter combinations */ int ix; char *p; char *p_name; unsigned int *pw; unsigned char c, c2; int len; tr->n_groups2 = 0; for(ix=0; ix<256; ix++) { tr->groups1[ix]=NULL; tr->groups2_count[ix]=0; tr->groups2_start[ix]=255; // indicates "not set" } memset(tr->letterGroups,0,sizeof(tr->letterGroups)); memset(tr->groups3,0,sizeof(tr->groups3)); p = tr->data_dictrules; while(*p != 0) { if(*p != RULE_GROUP_START) { fprintf(stderr,"Bad rules data in '%s_dict' at 0x%x\n",dictionary_name,(unsigned int)(p - tr->data_dictrules)); break; } p++; if(p[0] == RULE_REPLACEMENTS) { // pw = (unsigned int *)(((long64)p+4) & ~3); // advance to next word boundary pw = (unsigned int *) align_address <4, char> (p+4); // advance to next word boundary tr->langopts.replace_chars = pw; while(pw[0] != 0) { pw += 2; // find the end of the replacement list, each entry is 2 words. } p = (char *)(pw+1); #ifdef ARCH_BIG pw = (unsigned int *)(tr->langopts.replace_chars); while(*pw != 0) { *pw = Reverse4Bytes(*pw); pw++; *pw = Reverse4Bytes(*pw); pw++; } #endif continue; } if(p[0] == RULE_LETTERGP2) { ix = p[1] - 'A'; p += 2; if((ix >= 0) && (ix < N_LETTER_GROUPS)) { tr->letterGroups[ix] = p; } } else { len = strlen(p); p_name = p; c = p_name[0]; c2 = p_name[1]; p += (len+1); if(len == 1) { tr->groups1[c] = p; } else if(len == 0) { tr->groups1[0] = p; } else if(c == 1) { // index by offset from letter base tr->groups3[c2 - 1] = p; } else { if(tr->groups2_start[c] == 255) tr->groups2_start[c] = tr->n_groups2; tr->groups2_count[c]++; tr->groups2[tr->n_groups2] = p; tr->groups2_name[tr->n_groups2++] = (c + (c2 << 8)); } } // skip over all the rules in this group while(*p != RULE_GROUP_END) { p += (strlen(p) + 1); } p++; } } // end of InitGroups #ifdef DATA_FROM_SOURCECODE_FILES int LoadDictionary(Translator *tr, const char *name, int no_error) { strcpy (dictionary_name, name); // currently loaded dictionary name strcpy (tr -> dictionary_name, name); // Load a pronunciation data file into memory // bytes 0-3: offset to rules data // bytes 4-7: number of hash table entries if(tr -> data_dictlist != NULL) { Free (tr -> data_dictlist); tr -> data_dictlist = NULL; } unsigned int size; tr -> data_dictlist = (char *) espeakdata_get_dict_data (name, &size); if (tr -> data_dictlist == 0) { return 1; } int *pw = reinterpret_cast (tr -> data_dictlist); int length = Reverse4Bytes (pw[1]); // was int really written with 4 bytes? if (size <= (N_HASH_DICT + sizeof(int)*2)) { Melder_appendError (U"Empty _dict: ", Melder_peek8to32(name), U"_dict."); return(2); } if((Reverse4Bytes(pw[0]) != N_HASH_DICT) || (length <= 0) || (length > 0x8000000)) { Melder_appendError (U"Bad data in dict: ", Melder_peek8to32(name), U" ", Reverse4Bytes(pw[0]), U" ", length); return (2); } tr -> data_dictrules = &(tr->data_dictlist[length]); // set up indices into data_dictrules InitGroups(tr); if (tr -> groups1[0] == NULL) { Melder_appendError (U"Error in ", Melder_peek8to32(name), U"_rules, no default rule group."); } // set up hash table for data_dictlist char *p = &(tr -> data_dictlist[8]); for (int hash = 0; hash < N_HASH_DICT; hash++) { tr -> dict_hashtab[hash] = p; while ((length = *p) != 0) { p += length; } p++; // skip over the zero which terminates the list for this hash value } return (0); } // end of LoadDictionary #else int LoadDictionary(Translator *tr, const char *name, int no_error) {//=============================================================== int hash; char *p; int *pw; int length; FILE *f; unsigned int size; char fname[sizeof(path_home)+20]; strcpy(dictionary_name,name); // currently loaded dictionary name strcpy(tr->dictionary_name, name); // Load a pronunciation data file into memory // bytes 0-3: offset to rules data // bytes 4-7: number of hash table entries sprintf(fname,"%s%c%s_dict",path_home,PATHSEP,name); size = GetFileLength(fname); if(tr->data_dictlist != NULL) { Free(tr->data_dictlist); tr->data_dictlist = NULL; } f = fopen(fname,"rb"); if((f == NULL) || (size <= 0)) { if(no_error == 0) { fprintf(stderr,"Can't read dictionary file: '%s'\n",fname); } return(1); } tr->data_dictlist = Alloc(size); size = fread(tr->data_dictlist,1,size,f); fclose(f); pw = (int *)(tr->data_dictlist); length = Reverse4Bytes(pw[1]); if(size <= (N_HASH_DICT + sizeof(int)*2)) { fprintf(stderr,"Empty _dict file: '%s\n",fname); return(2); } if((Reverse4Bytes(pw[0]) != N_HASH_DICT) || (length <= 0) || (length > 0x8000000)) { fprintf(stderr,"Bad data: '%s' (%x length=%x)\n",fname,Reverse4Bytes(pw[0]),length); return(2); } tr->data_dictrules = &(tr->data_dictlist[length]); // set up indices into data_dictrules InitGroups(tr); if(tr->groups1[0] == NULL) { fprintf(stderr,"Error in %s_rules, no default rule group\n",name); } // set up hash table for data_dictlist p = &(tr->data_dictlist[8]); for(hash=0; hashdict_hashtab[hash] = p; while((length = *p) != 0) { p += length; } p++; // skip over the zero which terminates the list for this hash value } return(0); } // end of LoadDictionary #endif int HashDictionary(const char *string) //==================================== /* Generate a hash code from the specified string This is used to access the dictionary_2 word-lookup dictionary */ { int c; int chars=0; int hash=0; while((c = (*string++ & 0xff)) != 0) { hash = hash * 8 + c; hash = (hash & 0x3ff) ^ (hash >> 8); /* exclusive or */ chars++; } return((hash+chars) & 0x3ff); // a 10 bit hash code } // end of HashDictionary //============================================================================================= // Translate between internal representation of phonemes and a mnemonic form for display // //============================================================================================= const char *EncodePhonemes(const char *p, char *outptr, unsigned char *bad_phoneme) /***************************************************************************/ /* Translate a phoneme string from ascii mnemonics to internal phoneme numbers, from 'p' up to next blank . Returns advanced 'p' outptr contains encoded phonemes, unrecognized phoneme stops the encoding bad_phoneme must point to char array of length 2 of more */ { int ix; unsigned char c; int count; /* num. of matching characters */ int max; /* highest num. of matching found so far */ int max_ph; /* corresponding phoneme with highest matching */ int consumed; unsigned int mnemonic_word; if(bad_phoneme != NULL) bad_phoneme[0] = 0; // skip initial blanks while(isspace(*p)) { p++; } while(((c = *p) != 0) && !isspace(c)) { consumed = 0; switch(c) { case '|': // used to separate phoneme mnemonics if needed, to prevent characters being treated // as a multi-letter mnemonic if((c = p[1]) == '|') { // treat double || as a word-break symbol, drop through // to the default case with c = '|' } else { p++; break; } default: // lookup the phoneme mnemonic, find the phoneme with the highest number of // matching characters max= -1; max_ph= 0; for(ix=1; ixtype == phINVALID) continue; // this phoneme is not defined for this language count = 0; mnemonic_word = phoneme_tab[ix]->mnemonic; while(((c = p[count]) > ' ') && (count < 4) && (c == ((mnemonic_word >> (count*8)) & 0xff))) count++; if((count > max) && ((count == 4) || (((mnemonic_word >> (count*8)) & 0xff)==0))) { max = count; max_ph = phoneme_tab[ix]->code; } } if(max_ph == 0) { // not recognised, report and ignore if(bad_phoneme != NULL) { bad_phoneme[0] = *p; bad_phoneme[1] = 0; } *outptr++ = 0; return(p+1); } if(max <= 0) max = 1; p += (consumed + max); *outptr++ = (char)(max_ph); if(max_ph == phonSWITCH) { // Switch Language: this phoneme is followed by a text string char *p_lang = outptr; while(!isspace(c = *p) && (c != 0)) { p++; *outptr++ = tolower(c); } *outptr = 0; if(c == 0) { if(strcmp(p_lang,"en")==0) { *p_lang = 0; // don't need "en", it's assumed by default return(p); } } else { *outptr++ = '|'; // more phonemes follow, terminate language string with separator } } break; } } /* terminate the encoded string */ *outptr = 0; return(p); } // end of EncodePhonemes void DecodePhonemes(const char *inptr, char *outptr) //================================================== // Translate from internal phoneme codes into phoneme mnemonics { unsigned char phcode; unsigned char c; unsigned int mnem; PHONEME_TAB *ph; static const char *stress_chars = "==,,'* "; sprintf(outptr,"* "); while((phcode = *inptr++) > 0) { if(phcode == 255) continue; /* indicates unrecognised phoneme */ if((ph = phoneme_tab[phcode]) == NULL) continue; if((ph->type == phSTRESS) && (ph->std_length <= 4) && (ph->program == 0)) { if(ph->std_length > 1) *outptr++ = stress_chars[ph->std_length]; } else { mnem = ph->mnemonic; while((c = (mnem & 0xff)) != 0) { *outptr++ = c; mnem = mnem >> 8; } if(phcode == phonSWITCH) { while(isalpha(*inptr)) { *outptr++ = *inptr++; } } } } *outptr = 0; /* string terminator */ } // end of DecodePhonemes // using Kirschenbaum to IPA translation, ascii 0x20 to 0x7f unsigned short ipa1[96] = { 0x20,0x21,0x22,0x2b0,0x24,0x25,0x0e6,0x2c8,0x28,0x27e,0x2a,0x2b,0x2cc,0x2d,0x2e,0x2f, 0x252,0x31,0x32,0x25c,0x34,0x35,0x36,0x37,0x275,0x39,0x2d0,0x2b2,0x3c,0x3d,0x3e,0x294, 0x259,0x251,0x3b2,0xe7,0xf0,0x25b,0x46,0x262,0x127,0x26a,0x25f,0x4b,0x29f,0x271,0x14b,0x254, 0x3a6,0x263,0x280,0x283,0x3b8,0x28a,0x28c,0x153,0x3c7,0xf8,0x292,0x32a,0x5c,0x5d,0x5e,0x5f, 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x261,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f, 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x303,0x7f }; char *WritePhMnemonic(char *phon_out, PHONEME_TAB *ph, PHONEME_LIST *plist, int use_ipa) {//===================================================================================== int c; int mnem; int len; int first; int ix = 0; char *p; unsigned int ipa_control=0; // first byte of ipa string may control the phoneme name interpretation. 0x20 = ignore this phoneme PHONEME_DATA phdata; if(ph->code == phonEND_WORD) { // ignore phon_out[0] = 0; return(phon_out); } if(ph->code == phonSWITCH) { // the tone_ph field contains a phoneme table number p = phoneme_tab_list[plist->tone_ph].name; sprintf(phon_out, "(%s)", p); return(phon_out + strlen(phon_out)); } if(use_ipa) { // has an ipa name been defined for this phoneme ? phdata.ipa_string[0] = 0; if(plist == NULL) { InterpretPhoneme2(ph->code, &phdata); } else { InterpretPhoneme(NULL, 0, plist, &phdata, NULL); } len = strlen(phdata.ipa_string); if(len > 0) { if((ipa_control = phdata.ipa_string[0]) > 0x20) { strcpy(&phon_out[ix], phdata.ipa_string); ix += len; } if(ipa_control >= 0x20) { phon_out = &phon_out[ix]; *phon_out = 0; return(phon_out); // 0x20 = ignore phoneme } } } first = 1; for(mnem = ph->mnemonic; (c = mnem & 0xff) != 0; mnem = mnem >> 8) { if((c == '/') && (option_phoneme_variants==0)) break; // discard phoneme variant indicator if(use_ipa) { // convert from ascii to ipa if(first && (c == '_')) break; // don't show pause phonemes if((c == '#') && (ph->type == phVOWEL)) break; // # is subscript-h, but only for consonants // ignore digits after the first character if(!first && isdigit(c)) continue; if((c >= 0x20) && (c < 128)) c = ipa1[c-0x20]; ix += utf8_out(c, &phon_out[ix]); } else { phon_out[ix++]= c; } first = 0; } phon_out = &phon_out[ix]; *phon_out = 0; return(phon_out); } // end of WritePhMnemonic void GetTranslatedPhonemeString(char *phon_out, int n_phon_out, int use_ipa) {//========================================================================= /* Can be called after a clause has been translated into phonemes, in order to display the clause in phoneme mnemonic form. */ int ix; unsigned int len; unsigned int max_len; int phon_out_ix=0; int stress; unsigned int c; char *buf; char phon_buf[30]; PHONEME_LIST *plist; static const char *stress_chars = "==,,''"; if(phon_out != NULL) { for(ix=1; ix<(n_phoneme_list-2); ix++) { buf = phon_buf; plist = &phoneme_list[ix]; if(plist->newword) *buf++ = ' '; if(plist->synthflags & SFLAG_SYLLABLE) { if((stress = plist->stresslevel) > 1) { c = 0; if(stress > 5) stress = 5; if(use_ipa) { c = 0x2cc; // ipa, secondary stress if(stress > 3) c = 0x02c8; // ipa, primary stress } else { c = stress_chars[stress]; } if(c != 0) { buf += utf8_out(c, buf); } } } buf = WritePhMnemonic(buf, plist->ph, plist, use_ipa); if(plist->ph->code != phonSWITCH) { if(plist->synthflags & SFLAG_LENGTHEN) { buf = WritePhMnemonic(buf, phoneme_tab[phonLENGTHEN], NULL, use_ipa); } if((plist->synthflags & SFLAG_SYLLABLE) && (plist->type != phVOWEL)) { // syllablic consonant buf = WritePhMnemonic(buf, phoneme_tab[phonSYLLABIC], NULL, use_ipa); } if(plist->tone_ph > 0) { buf = WritePhMnemonic(buf, phoneme_tab[plist->tone_ph], NULL, use_ipa); } } len = buf - phon_buf; max_len = (n_phon_out - phon_out_ix - 5); // allow for " ..." and zero byte terminator if(len > max_len) { strcpy(&phon_buf[max_len], " ..."); len = max_len + 4; } phon_buf[len] = 0; strcpy(&phon_out[phon_out_ix], phon_buf); phon_out_ix += len; if(len > max_len) { break; } } phon_out[phon_out_ix] = 0; } } // end of GetTranslatedPhonemeString //============================================================================================= // Is a word Unpronouncable - and so should be spoken as individual letters // //============================================================================================= static int IsLetterGroup(Translator *tr, char *word, int group, int pre) {//===================================================================== // match the word against a list of utf-8 strings char *p; char *w; int len=0; p = tr->letterGroups[group]; if(p == NULL) return(0); while(*p != RULE_GROUP_END) { if(pre) { len = strlen(p); w = word - len + 1; } else { w = word; } while(*p == *w) { w++; p++; } if(*p == 0) { if(pre) return(len); return(w-word); // matched a complete string } while(*p++ != 0); // skip to end of string } return(0); } static int IsLetter(Translator *tr, int letter, int group) {//======================================================= int letter2; if(tr->letter_groups[group] != NULL) { if(wcschr(tr->letter_groups[group],letter)) return(1); return(0); } if(group > 7) return(0); if(tr->letter_bits_offset > 0) { if(((letter2 = (letter - tr->letter_bits_offset)) > 0) && (letter2 < 0x100)) letter = letter2; else return(0); } else { if((letter >= 0xc0) && (letter < N_REMOVE_ACCENT)) return(tr->letter_bits[remove_accent[letter-0xc0]] & (1L << group)); } if((letter >= 0) && (letter < 0x100)) return(tr->letter_bits[letter] & (1L << group)); return(0); } int IsVowel(Translator *tr, int letter) {//==================================== return(IsLetter(tr, letter, LETTERGP_VOWEL2)); } static int Unpronouncable2(Translator *tr, char *word) {//=================================================== int c; int end_flags; char ph_buf[N_WORD_PHONEMES]; ph_buf[0] = 0; c = word[-1]; word[-1] = ' '; // ensure there is a space before the "word" end_flags = TranslateRules(tr, word, ph_buf, sizeof(ph_buf), NULL, FLAG_UNPRON_TEST, NULL); word[-1] = c; if((end_flags == 0) || (end_flags & SUFX_UNPRON)) return(1); return(0); } int Unpronouncable(Translator *tr, char *word, int posn) {//===================================================== /* Determines whether a word in 'unpronouncable', i.e. whether it should be spoken as individual letters. This function may be language specific. This is a generic version. */ int c; int c1=0; int vowel_posn=9; int index; int count; utf8_in(&c,word); if((tr->letter_bits_offset > 0) && (c < 0x241)) { // Latin characters for a language with a non-latin alphabet return(0); // so we can re-translate the word as English } if(tr->langopts.param[LOPT_UNPRONOUNCABLE] == 1) return(0); if(((c = *word) == ' ') || (c == 0) || (c == '\'')) return(0); index = 0; count = 0; for(;;) { index += utf8_in(&c,&word[index]); if((c==0) || (c==' ')) break; if((c=='\'') && ((count > 1) || (posn > 0))) break; // "tv'" but not "l'" if(count==0) c1 = c; count++; if(IsVowel(tr, c)) { vowel_posn = count; // position of the first vowel break; } if((c != '\'') && !iswalpha(c)) return(0); } if((vowel_posn > 2) && (tr->langopts.param[LOPT_UNPRONOUNCABLE] == 2)) { // Lookup unpronounable rules in *_rules return(Unpronouncable2(tr, word)); } if(c1 == tr->langopts.param[LOPT_UNPRONOUNCABLE]) vowel_posn--; // disregard this as the initial letter when counting if(vowel_posn > (tr->langopts.max_initial_consonants+1)) return(1); // no vowel, or no vowel in first few letters return(0); } /* end of Unpronounceable */ //============================================================================================= // Determine the stress pattern of a word // //============================================================================================= static int GetVowelStress(Translator *tr, unsigned char *phonemes, signed char *vowel_stress, int &vowel_count, int &stressed_syllable, int control) {//================================================================================================================================================= // control = 1, set stress to 1 for forced unstressed vowels unsigned char phcode; PHONEME_TAB *ph; unsigned char *ph_out = phonemes; int count = 1; int max_stress = -1; int ix; int j; int stress = -1; int primary_posn = 0; vowel_stress[0] = 1; while(((phcode = *phonemes++) != 0) && (count < (N_WORD_PHONEMES/2)-1)) { if((ph = phoneme_tab[phcode]) == NULL) continue; if((ph->type == phSTRESS) && (ph->program == 0)) { /* stress marker, use this for the following vowel */ if(phcode == phonSTRESS_PREV) { /* primary stress on preceeding vowel */ j = count - 1; while((j > 0) && (stressed_syllable == 0) && (vowel_stress[j] < 4)) { if((vowel_stress[j] != 0) && (vowel_stress[j] != 1)) { // don't promote a phoneme which must be unstressed vowel_stress[j] = 4; if(max_stress < 4) { max_stress = 4; primary_posn = j; } /* reduce any preceding primary stress markers */ for(ix=1; ixstd_length < 4) || (stressed_syllable == 0)) { stress = ph->std_length; if(stress > max_stress) max_stress = stress; } } continue; } if((ph->type == phVOWEL) && !(ph->phflags & phNONSYLLABIC)) { vowel_stress[count] = (char)stress; if((stress >= 4) && (stress >= max_stress)) { primary_posn = count; max_stress = stress; } if((stress < 0) && (control & 1) && (ph->phflags & phUNSTRESSED)) vowel_stress[count] = 1; /* weak vowel, must be unstressed */ count++; stress = -1; } else if(phcode == phonSYLLABIC) { // previous consonant phoneme is syllablic vowel_stress[count] = (char)stress; if((stress == 0) && (control & 1)) vowel_stress[count++] = 1; // syllabic consonant, usually unstressed } *ph_out++ = phcode; } vowel_stress[count] = 1; *ph_out = 0; /* has the position of the primary stress been specified by $1, $2, etc? */ if(stressed_syllable > 0) { if(stressed_syllable >= count) stressed_syllable = count-1; // the final syllable vowel_stress[stressed_syllable] = 4; max_stress = 4; primary_posn = stressed_syllable; } if(max_stress == 5) { // priority stress, replaces any other primary stress marker for(ix=1; ixlangopts.stress_flags & 0x20000) vowel_stress[ix] = 1; else vowel_stress[ix] = 3; } if(vowel_stress[ix] == 5) { vowel_stress[ix] = 4; primary_posn = ix; } } max_stress = 4; } stressed_syllable = primary_posn; vowel_count = count; return(max_stress); } // end of GetVowelStress static char stress_phonemes[] = {phonSTRESS_D, phonSTRESS_U, phonSTRESS_2, phonSTRESS_3, phonSTRESS_P, phonSTRESS_P2, phonSTRESS_TONIC}; void ChangeWordStress(Translator *tr, char *word, int new_stress) {//============================================================== int ix; unsigned char *p; int max_stress; int vowel_count; // num of vowels + 1 int stressed_syllable=0; // position of stressed syllable unsigned char phonetic[N_WORD_PHONEMES]; signed char vowel_stress[N_WORD_PHONEMES/2]; strcpy((char *)phonetic,word); max_stress = GetVowelStress(tr, phonetic, vowel_stress, vowel_count, stressed_syllable, 0); if(new_stress >= 4) { // promote to primary stress for(ix=1; ix= max_stress) { vowel_stress[ix] = new_stress; break; } } } else { // remove primary stress for(ix=1; ix new_stress) // >= allows for diminished stress (=1) vowel_stress[ix] = new_stress; } } // write out phonemes ix = 1; p = phonetic; while(*p != 0) { if((phoneme_tab[*p]->type == phVOWEL) && !(phoneme_tab[*p]->phflags & phNONSYLLABIC)) { if((vowel_stress[ix] == 0) || (vowel_stress[ix] > 1)) *word++ = stress_phonemes[(unsigned char)vowel_stress[ix]]; ix++; } *word++ = *p++; } *word = 0; } // end of ChangeWordStress void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags, int tonic, int control) {//===================================================================================================== /* Guess stress pattern of word. This is language specific 'output' is used for input and output 'dictionary_flags' has bits 0-3 position of stressed vowel (if > 0) or unstressed (if == 7) or syllables 1 and 2 (if == 6) bits 8... dictionary flags If 'tonic' is set (>= 0), replace highest stress by this value. control: bit 0 This is an individual symbol, not a word */ unsigned char phcode; unsigned char *p; PHONEME_TAB *ph; int stress; int max_stress; int vowel_count; // num of vowels + 1 int ix; int v; int v_stress; int stressed_syllable; // position of stressed syllable int max_stress_posn; int unstressed_word = 0; char *max_output; int final_ph; int final_ph2; int mnem; int mnem2; int post_tonic; // currently not used int opt_length; int done; int stressflags; int dflags = 0; int first_primary; signed char vowel_stress[N_WORD_PHONEMES/2]; char syllable_weight[N_WORD_PHONEMES/2]; char vowel_length[N_WORD_PHONEMES/2]; unsigned char phonetic[N_WORD_PHONEMES]; static char consonant_types[16] = {0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0}; /* stress numbers STRESS_BASE + 0 diminished, unstressed within a word 1 unstressed, weak 2 3 secondary stress 4 main stress */ stressflags = tr->langopts.stress_flags; if(dictionary_flags != NULL) dflags = dictionary_flags[0]; /* copy input string into internal buffer */ for(ix=0; ix= n_phoneme_tab) phonetic[ix] = phonSCHWA; if(phonetic[ix] == 0) break; } if(ix == 0) return; final_ph = phonetic[ix-1]; final_ph2 = phonetic[ix-2]; max_output = output + (N_WORD_PHONEMES-3); /* check for overrun */ // any stress position marked in the xx_list dictionary ? stressed_syllable = dflags & 0x7; if(dflags & 0x8) { // this indicates a word without a primary stress stressed_syllable = dflags & 0x3; unstressed_word = 1; } max_stress = GetVowelStress(tr, phonetic, vowel_stress, vowel_count, stressed_syllable, 1); if((max_stress < 0) && dictionary_flags) { if((tr->langopts.stress_flags & 1) && (vowel_count == 2)) { // lang=fr: don't stress monosyllables except at end-of-clause vowel_stress[1] = 0; dictionary_flags[0] |= FLAG_STRESS_END2; } max_stress = 0; } // heavy or light syllables ix = 1; for(p = phonetic; *p != 0; p++) { if((phoneme_tab[p[0]]->type == phVOWEL) && !(phoneme_tab[p[0]]->phflags & phNONSYLLABIC)) { int weight = 0; int lengthened = 0; if(phoneme_tab[p[1]]->code == phonLENGTHEN) lengthened = 1; if(lengthened || (phoneme_tab[p[0]]->phflags & phLONG)) { // long vowel, increase syllable weight weight++; } vowel_length[ix] = weight; if(lengthened) p++; // advance over phonLENGTHEN if(consonant_types[phoneme_tab[p[1]]->type] && ((phoneme_tab[p[2]]->type != phVOWEL) || (phoneme_tab[p[1]]->phflags & phLONG))) { // followed by two consonants, a long consonant, or consonant and end-of-word weight++; } syllable_weight[ix] = weight; ix++; } } switch(tr->langopts.stress_rule) { case 8: // stress on first syllable, unless it is a light syllable followed by a heavy syllable if((syllable_weight[1] > 0) || (syllable_weight[2] == 0)) break; // else drop through to case 1 case 1: // stress on second syllable if((stressed_syllable == 0) && (vowel_count > 2)) { stressed_syllable = 2; if(max_stress == 0) { vowel_stress[stressed_syllable] = 4; } max_stress = 4; } break; case 10: // penultimate, but final if only 1 or 2 syllables if(stressed_syllable == 0) { if(vowel_count < 4) { vowel_stress[vowel_count - 1] = 4; max_stress = 4; break; } } // drop through to next case case 2: // a language with stress on penultimate vowel if(stressed_syllable == 0) { /* no explicit stress - stress the penultimate vowel */ max_stress = 4; if(vowel_count > 2) { stressed_syllable = vowel_count - 2; if(stressflags & 0x300) { // LANG=Spanish, stress on last vowel if the word ends in a consonant other than 'n' or 's' if(phoneme_tab[final_ph]->type != phVOWEL) { if(stressflags & 0x100) { stressed_syllable = vowel_count - 1; } else { mnem = phoneme_tab[final_ph]->mnemonic; mnem2 = phoneme_tab[final_ph2]->mnemonic; if((mnem == 's') && (phoneme_tab[final_ph2]->type == phNASAL)) { // -ns stress remains on penultimate syllable } else if(((phoneme_tab[final_ph]->type != phNASAL) && (mnem != 's')) || (phoneme_tab[final_ph2]->type != phVOWEL)) { stressed_syllable = vowel_count - 1; } } } } if(stressflags & 0x80000) { // stress on last syllable if it has a long vowel, but previous syllable has a short vowel if(vowel_length[vowel_count - 1] > vowel_length[vowel_count - 2]) { stressed_syllable = vowel_count - 1; } } if((vowel_stress[stressed_syllable] == 0) || (vowel_stress[stressed_syllable] == 1)) { // but this vowel is explicitly marked as unstressed if(stressed_syllable > 1) stressed_syllable--; else stressed_syllable++; } } else { stressed_syllable = 1; } // only set the stress if it's not already marked explicitly if(vowel_stress[stressed_syllable] < 0) { // don't stress if next and prev syllables are stressed if((vowel_stress[stressed_syllable-1] < 4) || (vowel_stress[stressed_syllable+1] < 4)) vowel_stress[stressed_syllable] = max_stress; } } break; case 3: // stress on last vowel if(stressed_syllable == 0) { /* no explicit stress - stress the final vowel */ stressed_syllable = vowel_count - 1; while(stressed_syllable > 0) { // find the last vowel which is not unstressed if(vowel_stress[stressed_syllable] < 0) { vowel_stress[stressed_syllable] = 4; break; } else stressed_syllable--; } max_stress = 4; } break; case 4: // stress on antipenultimate vowel if(stressed_syllable == 0) { stressed_syllable = vowel_count - 3; if(stressed_syllable < 1) stressed_syllable = 1; if(max_stress == 0) { vowel_stress[stressed_syllable] = 4; } max_stress = 4; } break; case 5: // LANG=Russian if(stressed_syllable == 0) { /* no explicit stress - guess the stress from the number of syllables */ static char guess_ru[16] = {0,0,1,1,2,3,3,4,5,6,7,7,8,9,10,11}; static char guess_ru_v[16] = {0,0,1,1,2,2,3,3,4,5,6,7,7,8,9,10}; // for final phoneme is a vowel static char guess_ru_t[16] = {0,0,1,2,3,3,3,4,5,6,7,7,7,8,9,10}; // for final phoneme is an unvoiced stop stressed_syllable = vowel_count - 3; if(vowel_count < 16) { if(phoneme_tab[final_ph]->type == phVOWEL) stressed_syllable = guess_ru_v[vowel_count]; else if(phoneme_tab[final_ph]->type == phSTOP) stressed_syllable = guess_ru_t[vowel_count]; else stressed_syllable = guess_ru[vowel_count]; } vowel_stress[stressed_syllable] = 4; max_stress = 4; } break; case 6: // LANG=hi stress on the last heaviest syllable if(stressed_syllable == 0) { int wt; int max_weight = -1; // int prev_stressed; // find the heaviest syllable, excluding the final syllable for(ix = 1; ix < (vowel_count-1); ix++) { if(vowel_stress[ix] < 0) { if((wt = syllable_weight[ix]) >= max_weight) { max_weight = wt; // prev_stressed = stressed_syllable; stressed_syllable = ix; } } } if((syllable_weight[vowel_count-1] == 2) && (max_weight< 2)) { // the only double=heavy syllable is the final syllable, so stress this stressed_syllable = vowel_count-1; } else if(max_weight <= 0) { // all syllables, exclusing the last, are light. Stress the first syllable stressed_syllable = 1; } vowel_stress[stressed_syllable] = 4; max_stress = 4; } break; case 7: // LANG=tr, the last syllable for any vowel marked explicitly as unstressed if(stressed_syllable == 0) { stressed_syllable = vowel_count - 1; for(ix=1; ix < vowel_count; ix++) { if(vowel_stress[ix] == 1) { stressed_syllable = ix-1; break; } } vowel_stress[stressed_syllable] = 4; max_stress = 4; } break; case 9: // mark all as stressed for(ix=1; ix 2) && (vowel_stress[2] >= 4)) { vowel_stress[1] = 3; } } done = 0; first_primary = 0; for(v=1; v 1) && (stressflags & 0x40) && (syllable_weight[v]==0) && (syllable_weight[v+1]>0)) { // don't put secondary stress on a light syllable which is followed by a heavy syllable continue; } // should start with secondary stress on the first syllable, or should it count back from // the primary stress and put secondary stress on alternate syllables? vowel_stress[v] = (char)stress; done =1; stress = 3; /* use secondary stress for remaining syllables */ } } if(vowel_stress[v] >= 4) { if(first_primary == 0) first_primary = v; else if(stressflags & S_FIRST_PRIMARY) { // reduce primary stresses after the first to secondary vowel_stress[v] = 3; } } } if((unstressed_word) && (tonic < 0)) { if(vowel_count <= 2) tonic = tr->langopts.unstressed_wd1; /* monosyllable - unstressed */ else tonic = tr->langopts.unstressed_wd2; /* more than one syllable, used secondary stress as the main stress */ } max_stress = 0; max_stress_posn = 0; for(v=1; v= max_stress) { max_stress = vowel_stress[v]; max_stress_posn = v; } } if(tonic >= 0) { /* find position of highest stress, and replace it by 'tonic' */ /* don't disturb an explicitly set stress by 'unstress-at-end' flag */ if((tonic > max_stress) || (max_stress <= 4)) vowel_stress[max_stress_posn] = (char)tonic; max_stress = tonic; } /* produce output phoneme string */ p = phonetic; v = 1; if(!(control & 1) && ((ph = phoneme_tab[*p]) != NULL)) { if(ph->type == phSTRESS) ph = phoneme_tab[p[1]]; #ifdef deleted int gap = tr->langopts.word_gap & 0x700; if((gap) && (vowel_stress[1] >= 4) && (prev_stress >= 4)) { /* two primary stresses together, insert a short pause */ *output++ = pause_phonemes[gap >> 8]; } else #endif if((tr->langopts.vowel_pause & 0x30) && (ph->type == phVOWEL)) { // word starts with a vowel if((tr->langopts.vowel_pause & 0x20) && (vowel_stress[1] >= 4)) { *output++ = phonPAUSE_NOLINK; // not to be replaced by link } else { *output++ = phonPAUSE_VSHORT; // break, but no pause } } } p = phonetic; post_tonic = 0; while(((phcode = *p++) != 0) && (output < max_output)) { if((ph = phoneme_tab[phcode]) == NULL) continue; // if(ph->type == phSTRESS) // continue; if(ph->type == phPAUSE) { tr->prev_last_stress = 0; } else if(((ph->type == phVOWEL) && !(ph->phflags & phNONSYLLABIC)) || (*p == phonSYLLABIC)) { // a vowel, or a consonant followed by a syllabic consonant marker v_stress = vowel_stress[v]; tr->prev_last_stress = v_stress; if(vowel_stress[v-1] >= max_stress) post_tonic = 1; if(v_stress <= 1) { if((v > 1) && (max_stress >= 2) && (stressflags & 4) && (v == (vowel_count-1))) { // option: mark unstressed final syllable as diminished v_stress = 0; } else if((stressflags & 2) || (v == 1) || (v == (vowel_count-1))) { // first or last syllable, or option 'don't set diminished stress' v_stress = 1; } else if((v == (vowel_count-2)) && (vowel_stress[vowel_count-1] <= 1)) { // penultimate syllable, followed by an unstressed final syllable v_stress = 1; } else { // unstressed syllable within a word if((vowel_stress[v-1] < 0) || ((stressflags & 0x10000) == 0)) { v_stress = 0; /* change to 0 (diminished stress) */ vowel_stress[v] = v_stress; } } } if((v_stress == 0) || (v_stress > 1)) *output++ = stress_phonemes[v_stress]; // mark stress of all vowels except 1 (unstressed) if(vowel_stress[v] > max_stress) { max_stress = vowel_stress[v]; } if((*p == phonLENGTHEN) && ((opt_length = tr->langopts.param[LOPT_IT_LENGTHEN]) & 1)) { // remove lengthen indicator from non-stressed syllables int shorten=0; if(opt_length & 0x10) { // only allow lengthen indicator on the highest stress syllable in the word if(v != max_stress_posn) shorten = 1; } else if(v_stress < 4) { // only allow lengthen indicator if stress >= 4. shorten = 1; } if(shorten) p++; } if((v_stress >= 4) && (tr->langopts.param[LOPT_IT_LENGTHEN] == 2)) { // LANG=Italian, lengthen penultimate stressed vowels, unless followed by 2 consonants if((v == (vowel_count - 2)) && (syllable_weight[v] == 0)) { *output++ = phcode; phcode = phonLENGTHEN; } } v++; } if(phcode != 1) *output++ = phcode; } *output++ = 0; return; } /* end of SetWordStress */ //============================================================================================= // Look up a word in the pronunciation rules // //============================================================================================= void AppendPhonemes(Translator *tr, char *string, int size, const char *ph) {//======================================================================== /* Add new phoneme string "ph" to "string" Keeps count of the number of vowel phonemes in the word, and whether these can be stressed syllables. These values can be used in translation rules */ const char *p; unsigned char c; int unstress_mark; int length; length = strlen(ph) + strlen(string); if(length >= size) { return; } /* any stressable vowel ? */ unstress_mark = 0; p = ph; while((c = *p++) != 0) { if(c >= n_phoneme_tab) continue; if(phoneme_tab[c]->type == phSTRESS) { if(phoneme_tab[c]->std_length < 4) unstress_mark = 1; } else { if(phoneme_tab[c]->type == phVOWEL) { if(((phoneme_tab[c]->phflags & phUNSTRESSED) == 0) && (unstress_mark == 0)) { tr->word_stressed_count++; } unstress_mark = 0; tr->word_vowel_count++; } } } if(string != NULL) strcat(string,ph); } /* end of AppendPhonemes */ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_length, char *rule, MatchRecord *match_out, int word_flags, int dict_flags) {//======================================================================================================================================================== /* Checks a specified word against dictionary rules. Returns with phoneme code string, or NULL if no match found. word (indirect) points to current character group within the input word This is advanced by this procedure as characters are consumed group: the initial characters used to choose the rules group rule: address of dictionary rule data for this character group match_out: returns best points score word_flags: indicates whether this is a retranslation after a suffix has been removed */ unsigned char rb; // current instuction from rule unsigned char letter; // current letter from input word, single byte int letter_w; // current letter, wide character int letter_xbytes; // number of extra bytes of multibyte character (num bytes - 1) unsigned char last_letter; char *pre_ptr; char *post_ptr; /* pointer to first character after group */ char *rule_start; /* start of current match template */ char *p; int ix; int match_type; /* left, right, or consume */ int failed; int unpron_ignore; int consumed; /* number of letters consumed from input */ int syllable_count; int vowel; int letter_group; int distance_right; int distance_left; int lg_pts; int n_bytes; int add_points; int command; int check_atstart; MatchRecord match; static MatchRecord best; int total_consumed; /* letters consumed for best match */ unsigned char condition_num; char *common_phonemes; /* common to a group of entries */ char *group_chars; char word_buf[N_WORD_BYTES]; group_chars = *word; if(rule == NULL) { match_out->points = 0; (*word)++; return; } total_consumed = 0; common_phonemes = NULL; match_type = 0; best.points = 0; best.phonemes = ""; best.end_type = 0; best.del_fwd = NULL; /* search through dictionary rules */ while(rule[0] != RULE_GROUP_END) { unpron_ignore = word_flags & FLAG_UNPRON_TEST; match_type=0; consumed = 0; letter = 0; distance_right= -6; /* used to reduce points for matches further away the current letter */ distance_left= -2; check_atstart = 0; match.points = 1; match.end_type = 0; match.del_fwd = NULL; pre_ptr = *word; post_ptr = *word + group_length; /* work through next rule until end, or until no-match proved */ rule_start = rule; failed = 0; while(!failed) { rb = *rule++; if(rb <= RULE_LINENUM) { switch(rb) { case 0: // no phoneme string for this rule, use previous common rule if(common_phonemes != NULL) { match.phonemes = common_phonemes; while(((rb = *match.phonemes++) != 0) && (rb != RULE_PHONEMES)) { if(rb == RULE_CONDITION) match.phonemes++; // skip over condition number if(rb == RULE_LINENUM) match.phonemes += 2; // skip over line number } } else { match.phonemes = ""; } rule--; // so we are still pointing at the 0 failed=2; // matched OK break; case RULE_PRE_ATSTART: // pre rule with implied 'start of word' check_atstart = 1; unpron_ignore = 0; match_type = RULE_PRE; break; case RULE_PRE: match_type = RULE_PRE; if(word_flags & FLAG_UNPRON_TEST) { // checking the start of the word for unpronouncable character sequences, only // consider rules which explicitly match the start of a word // Note: Those rules now use RULE_PRE_ATSTART failed = 1; } break; case RULE_POST: match_type = RULE_POST; break; case RULE_PHONEMES: match.phonemes = rule; failed=2; // matched OK break; case RULE_PH_COMMON: common_phonemes = rule; break; case RULE_CONDITION: /* conditional rule, next byte gives condition number */ condition_num = *rule++; if(condition_num >= 32) { // allow the rule only if the condition number is NOT set if((tr->dict_condition & (1L << (condition_num-32))) != 0) failed = 1; } else { // allow the rule only if the condition number is set if((tr->dict_condition & (1L << condition_num)) == 0) failed = 1; } if(!failed) match.points++; // add one point for a matched conditional rule break; case RULE_LINENUM: rule+=2; break; } continue; } add_points = 0; switch(match_type) { case 0: /* match and consume this letter */ last_letter = letter; letter = *post_ptr++; if((letter == rb) || ((letter==(unsigned char)REPLACED_E) && (rb=='e'))) { if((letter & 0xc0) != 0x80) add_points = 21; // don't add point for non-initial UTF-8 bytes consumed++; } else failed = 1; break; case RULE_POST: /* continue moving fowards */ distance_right += 6; if(distance_right > 18) distance_right = 19; last_letter = letter; letter_xbytes = utf8_in(&letter_w,post_ptr)-1; letter = *post_ptr++; switch(rb) { case RULE_LETTERGP: letter_group = *rule++ - 'A'; if(IsLetter(tr, letter_w, letter_group)) { lg_pts = 20; if(letter_group==2) lg_pts = 19; // fewer points for C, general consonant add_points = (lg_pts-distance_right); post_ptr += letter_xbytes; } else failed = 1; break; case RULE_LETTERGP2: // match against a list of utf-8 strings letter_group = *rule++ - 'A'; if((n_bytes = IsLetterGroup(tr, post_ptr-1,letter_group,0)) >0) { add_points = (20-distance_right); post_ptr += (n_bytes-1); } else failed =1; break; case RULE_NOTVOWEL: if(IsLetter(tr, letter_w, 0) || ((letter_w == ' ') && (word_flags & FLAG_SUFFIX_VOWEL))) { failed = 1; } else { add_points = (20-distance_right); post_ptr += letter_xbytes; } break; case RULE_DIGIT: if(IsDigit(letter_w)) { add_points = (20-distance_right); post_ptr += letter_xbytes; } else if(tr->langopts.tone_numbers) { // also match if there is no digit add_points = (20-distance_right); post_ptr--; } else failed = 1; break; case RULE_NONALPHA: if(!iswalpha(letter_w)) { add_points = (21-distance_right); post_ptr += letter_xbytes; } else failed = 1; break; case RULE_DOUBLE: if(letter == last_letter) add_points = (21-distance_right); else failed = 1; break; case RULE_DOLLAR: command = *rule++; if(command == 0x01) { match.end_type = SUFX_UNPRON; // $unpron } else if((command & 0xf0) == 0x10) { // $w_alt if(dict_flags & (1 << (BITNUM_FLAG_ALT + (command & 0xf)))) add_points = 23; else failed = 1; } else if((command & 0xf0) == 0x20) { // $p_alt // make a copy of the word up to the post-match characters ix = *word - word_start + consumed + group_length + 1; memcpy(word_buf, word_start-1, ix); word_buf[ix] = ' '; word_buf[ix+1] = 0; if(LookupFlags(tr, &word_buf[1]) & (1 << (BITNUM_FLAG_ALT + (command & 0xf)))) add_points = 23; else failed = 1; } break; case '-': if((letter == '-') || ((letter == ' ') && (word_flags & FLAG_HYPHEN_AFTER))) { add_points = (22-distance_right); // one point more than match against space } else failed = 1; break; case RULE_SYLLABLE: { /* more than specified number of vowel letters to the right */ char *p = post_ptr + letter_xbytes; int vowel_count=0; syllable_count = 1; while(*rule == RULE_SYLLABLE) { rule++; syllable_count+=1; /* number of syllables to match */ } vowel = 0; while(letter_w != RULE_SPACE) { if((vowel==0) && IsLetter(tr, letter_w,LETTERGP_VOWEL2)) { // this is counting vowels which are separated by non-vowel letters vowel_count++; } vowel = IsLetter(tr, letter_w,LETTERGP_VOWEL2); p += utf8_in(&letter_w,p); } if(syllable_count <= vowel_count) add_points = (18+syllable_count-distance_right); else failed = 1; } break; case RULE_NOVOWELS: { char *p = post_ptr + letter_xbytes; while(letter_w != RULE_SPACE) { if(IsLetter(tr, letter_w,LETTERGP_VOWEL2)) { failed = 1; break; } p += utf8_in(&letter_w,p); } if(!failed) add_points = (19-distance_right); } break; case RULE_SKIPCHARS: { // Used for lang=Tamil, used to match on the next word after an unknown word ending // only look until the end of the word (including the end-of-word marker) // Jx means 'skip characters until x', where 'x' may be '_' for 'end of word' char *p = post_ptr + letter_xbytes; char *p2 = p; int rule_w; // skip characters until this utf8_in(&rule_w,rule); while((letter_w != rule_w) && (letter_w != RULE_SPACE)) { p2 = p; p += utf8_in(&letter_w,p); } if(letter_w == rule_w) { post_ptr = p2; } } break; case RULE_INC_SCORE: add_points = 20; // force an increase in points break; case RULE_DEL_FWD: // find the next 'e' in the word and replace by 'E' for(p = *word + group_length; p < post_ptr; p++) { if(*p == 'e') { match.del_fwd = p; break; } } break; case RULE_ENDING: { int end_type; // next 3 bytes are a (non-zero) ending type. 2 bytes of flags + suffix length end_type = (rule[0] << 16) + ((rule[1] & 0x7f) << 8) + (rule[2] & 0x7f); if((tr->word_vowel_count == 0) && !(end_type & SUFX_P) && (tr->langopts.param[LOPT_SUFFIX] & 1)) failed = 1; // don't match a suffix rule if there are no previous syllables (needed for lang=tr). else { match.end_type = end_type; rule += 3; } } break; case RULE_NO_SUFFIX: if(word_flags & FLAG_SUFFIX_REMOVED) failed = 1; // a suffix has been removed else add_points = 1; break; default: if(letter == rb) { if((letter & 0xc0) != 0x80) { // not for non-initial UTF-8 bytes add_points = (21-distance_right); } } else failed = 1; break; } break; case RULE_PRE: /* match backwards from start of current group */ distance_left += 2; if(distance_left > 18) distance_left = 19; last_letter = *pre_ptr; pre_ptr--; letter_xbytes = utf8_in2(&letter_w,pre_ptr,1)-1; letter = *pre_ptr; switch(rb) { case RULE_LETTERGP: letter_group = *rule++ - 'A'; if(IsLetter(tr, letter_w,letter_group)) { lg_pts = 20; if(letter_group==2) lg_pts = 19; // fewer points for C, general consonant add_points = (lg_pts-distance_left); pre_ptr -= letter_xbytes; } else failed = 1; break; case RULE_LETTERGP2: // match against a list of utf-8 strings letter_group = *rule++ - 'A'; if((n_bytes = IsLetterGroup(tr, pre_ptr,letter_group,1)) >0) { add_points = (20-distance_right); pre_ptr -= (n_bytes-1); } else failed =1; break; case RULE_NOTVOWEL: if(!IsLetter(tr, letter_w,0)) { add_points = (20-distance_left); pre_ptr -= letter_xbytes; } else failed = 1; break; case RULE_DOUBLE: if(letter == last_letter) add_points = (21-distance_left); else failed = 1; break; case RULE_DIGIT: if(IsDigit(letter_w)) { add_points = (21-distance_left); pre_ptr -= letter_xbytes; } else failed = 1; break; case RULE_NONALPHA: if(!iswalpha(letter_w)) { add_points = (21-distance_right); pre_ptr -= letter_xbytes; } else failed = 1; break; case RULE_SYLLABLE: /* more than specified number of vowels to the left */ syllable_count = 1; while(*rule == RULE_SYLLABLE) { rule++; syllable_count++; /* number of syllables to match */ } if(syllable_count <= tr->word_vowel_count) add_points = (18+syllable_count-distance_left); else failed = 1; break; case RULE_STRESSED: if(tr->word_stressed_count > 0) add_points = 19; else failed = 1; break; case RULE_NOVOWELS: { char *p = pre_ptr - letter_xbytes - 1; while(letter_w != RULE_SPACE) { if(IsLetter(tr, letter_w,LETTERGP_VOWEL2)) { failed = 1; break; } p -= utf8_in2(&letter_w,p,1); } if(!failed) add_points = 3; } break; case RULE_IFVERB: if(tr->expect_verb) add_points = 1; else failed = 1; break; case RULE_CAPITAL: if(word_flags & FLAG_FIRST_UPPER) add_points = 1; else failed = 1; break; case '.': // dot in pre- section, match on any dot before this point in the word for(p=pre_ptr; *p != ' '; p--) { if(*p == '.') { add_points = 50; break; } } if(*p == ' ') failed = 1; break; case '-': if((letter == '-') || ((letter == ' ') && (word_flags & FLAG_HYPHEN))) { add_points = (22-distance_right); // one point more than match against space } else failed = 1; break; default: if(letter == rb) { if(letter == RULE_SPACE) add_points = 4; else { if((letter & 0xc0) != 0x80) { // not for non-initial UTF-8 bytes add_points = (21-distance_left); } } } else failed = 1; break; } break; } if(failed == 0) match.points += add_points; } if((failed == 2) && (unpron_ignore == 0)) { // do we also need to check for 'start of word' ? if((check_atstart==0) || (pre_ptr[-1] == ' ')) { if(check_atstart) match.points += 4; /* matched OK, is this better than the last best match ? */ if(match.points >= best.points) { memcpy(&best,&match,sizeof(match)); total_consumed = consumed; } if((option_phonemes == 2) && (match.points > 0) && ((word_flags & FLAG_NO_TRACE) == 0)) { // show each rule that matches, and it's points score int pts; char decoded_phonemes[80]; pts = match.points; if(group_length > 1) pts += 35; // to account for an extra letter matching DecodePhonemes(match.phonemes,decoded_phonemes); fprintf(f_trans,"%3d\t%s [%s]\n",pts,DecodeRule(group_chars, group_length, rule_start, word_flags), decoded_phonemes); } } } /* skip phoneme string to reach start of next template */ while(*rule++ != 0); } if((option_phonemes == 2) && ((word_flags & FLAG_NO_TRACE)==0)) { if(group_length <= 1) fprintf(f_trans,"\n"); } /* advance input data pointer */ total_consumed += group_length; if(total_consumed == 0) total_consumed = 1; /* always advance over 1st letter */ *word += total_consumed; if(best.points == 0) best.phonemes = ""; memcpy(match_out,&best,sizeof(MatchRecord)); } /* end of MatchRule */ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, char *end_phonemes, int word_flags, unsigned int *dict_flags) {//===================================================================================================================================== /* Translate a word bounded by space characters Append the result to 'phonemes' and any standard prefix/suffix in 'end_phonemes' */ unsigned char c, c2; unsigned int c12; int wc=0; int wc_bytes; char *p2; /* copy of p for use in double letter chain match */ int found; int g; /* group chain number */ int g1; /* first group for this letter */ int n; int letter; int any_alpha=0; int ix; unsigned int digit_count=0; char *p; int dict_flags0=0; MatchRecord match1; MatchRecord match2; char ph_buf[40]; char word_copy[N_WORD_BYTES]; static const char str_pause[2] = {phonPAUSE_NOLINK,0}; if(tr->data_dictrules == NULL) return(0); if(dict_flags != NULL) dict_flags0 = dict_flags[0]; for(ix=0; ix<(N_WORD_BYTES-1);) { c = p_start[ix]; word_copy[ix++] = c; if(c == 0) break; } word_copy[ix] = 0; if((option_phonemes == 2) && ((word_flags & FLAG_NO_TRACE)==0)) { char wordbuf[120]; unsigned int ix; for(ix=0; ((c = p_start[ix]) != ' ') && (c != 0) && (ix < (sizeof(wordbuf)-1)); ix++) { wordbuf[ix] = c; } wordbuf[ix] = 0; if(word_flags & FLAG_UNPRON_TEST) fprintf(f_trans,"Unpronouncable? '%s'\n",wordbuf); else fprintf(f_trans,"Translate '%s'\n",wordbuf); } p = p_start; tr->word_vowel_count = 0; tr->word_stressed_count = 0; if(end_phonemes != NULL) end_phonemes[0] = 0; while(((c = *p) != ' ') && (c != 0)) { wc_bytes = utf8_in(&wc,p); if(IsAlpha(wc)) any_alpha++; n = tr->groups2_count[c]; if(IsDigit(wc) && ((tr->langopts.tone_numbers == 0) || !any_alpha)) { // lookup the number in *_list not *_rules char string[8]; char buf[40]; string[0] = '_'; memcpy(&string[1],p,wc_bytes); string[1+wc_bytes] = 0; Lookup(tr, string,buf); if(++digit_count >= 2) { strcat(buf,str_pause); digit_count=0; } AppendPhonemes(tr,phonemes,ph_size,buf); p += wc_bytes; continue; } else { digit_count = 0; found = 0; if(((ix = wc - tr->letter_bits_offset) >= 0) && (ix < 128)) { if(tr->groups3[ix] != NULL) { MatchRule(tr, &p, p_start, wc_bytes, tr->groups3[ix], &match1, word_flags, dict_flags0); found = 1; } } if(!found && (n > 0)) { /* there are some 2 byte chains for this initial letter */ c2 = p[1]; c12 = c + (c2 << 8); /* 2 characters */ g1 = tr->groups2_start[c]; for(g=g1; g < (g1+n); g++) { if(tr->groups2_name[g] == c12) { found = 1; p2 = p; MatchRule(tr, &p2, p_start, 2, tr->groups2[g], &match2, word_flags, dict_flags0); if(match2.points > 0) match2.points += 35; /* to acount for 2 letters matching */ /* now see whether single letter chain gives a better match ? */ MatchRule(tr, &p, p_start, 1, tr->groups1[c], &match1, word_flags, dict_flags0); if(match2.points >= match1.points) { // use match from the 2-letter group memcpy(&match1,&match2,sizeof(MatchRecord)); p = p2; } } } } if(!found) { /* alphabetic, single letter chain */ if(tr->groups1[c] != NULL) MatchRule(tr, &p, p_start, 1, tr->groups1[c], &match1, word_flags, dict_flags0); else { // no group for this letter, use default group MatchRule(tr, &p, p_start, 0, tr->groups1[0], &match1, word_flags, dict_flags0); if((match1.points == 0) && ((option_sayas & 0x10) == 0)) { n = utf8_in(&letter,p-1)-1; if(tr->letter_bits_offset > 0) { // not a Latin alphabet, switch to the default Latin alphabet language if((letter <= 0x241) && iswalpha(letter)) { sprintf(phonemes,"%c%s",phonSWITCH,tr->langopts.ascii_language); return(0); } } #ifdef deleted // can't switch to a tone language, because the tone-phoneme numbers are not valid for the original language if((letter >= 0x4e00) && (letter < 0xa000) && (tr->langopts.ideographs != 1)) { // Chinese ideogram sprintf(phonemes,"%czh",phonSWITCH); return(0); } #endif // is it a bracket ? if(letter == 0xe000+'(') { if(pre_pause < tr->langopts.param2[LOPT_BRACKET_PAUSE]) pre_pause = tr->langopts.param2[LOPT_BRACKET_PAUSE]; // a bracket, aleady spoken by AnnouncePunctuation() } if(IsBracket(letter)) { if(pre_pause < tr->langopts.param[LOPT_BRACKET_PAUSE]) pre_pause = tr->langopts.param[LOPT_BRACKET_PAUSE]; } // no match, try removing the accent and re-translating the word if((letter >= 0xc0) && (letter < N_REMOVE_ACCENT) && ((ix = remove_accent[letter-0xc0]) != 0)) { // within range of the remove_accent table if((p[-2] != ' ') || (p[n] != ' ')) { // not the only letter in the word p2 = p-1; p[-1] = ix; while((p[0] = p[n]) != ' ') p++; while(n-- > 0) *p++ = ' '; // replacement character must be no longer than original if(tr->langopts.param[LOPT_DIERESES] && (lookupwchar(diereses_list,letter) > 0)) { // vowel with dieresis, replace and continue from this point p = p2; continue; } phonemes[0] = 0; // delete any phonemes which have been produced so far p = p_start; tr->word_vowel_count = 0; tr->word_stressed_count = 0; continue; // start again at the beginning of the word } } else if((letter >= 0x3200) && (letter < 0xa700) && (end_phonemes != NULL)) { // ideograms // outside the range of the accent table, speak the unknown symbol sound Lookup(tr, "_??", ph_buf); match1.phonemes = ph_buf; match1.points = 1; p += (wc_bytes-1); } } } if(match1.points == 0) { if((wc >= 0x300) && (wc <= 0x36f)) { // combining accent inside a word, ignore } else if(IsAlpha(wc)) { if((any_alpha > 1) || (p[wc_bytes-1] > ' ')) { // an unrecognised character in a word, abort and then spell the word phonemes[0] = 0; if(dict_flags != NULL) dict_flags[0] |= FLAG_SPELLWORD; break; } } else { LookupLetter(tr, wc, -1, ph_buf, 0); if(ph_buf[0]) { match1.phonemes = ph_buf; match1.points = 1; } } p += (wc_bytes-1); } else { tr->phonemes_repeat_count = 0; } } } if(match1.phonemes == NULL) match1.phonemes = ""; if(match1.points > 0) { if(word_flags & FLAG_UNPRON_TEST) return(match1.end_type | 1); if((match1.phonemes[0] == phonSWITCH) && ((word_flags & FLAG_DONT_SWITCH_TRANSLATOR)==0)) { // an instruction to switch language, return immediately so we can re-translate strcpy(phonemes,match1.phonemes); return(0); } match1.end_type &= ~SUFX_UNPRON; if((match1.end_type != 0) && (end_phonemes != NULL)) { /* a standard ending has been found, re-translate the word without it */ if((match1.end_type & SUFX_P) && (word_flags & FLAG_NO_PREFIX)) { // ignore the match on a prefix } else { if((match1.end_type & SUFX_P) && ((match1.end_type & 0x7f) == 0)) { // no prefix length specified match1.end_type |= p - p_start; } strcpy(end_phonemes,match1.phonemes); memcpy(p_start,word_copy,strlen(word_copy)); return(match1.end_type); } } if(match1.del_fwd != NULL) *match1.del_fwd = REPLACED_E; AppendPhonemes(tr,phonemes,ph_size,match1.phonemes); } } // any language specific changes ? ApplySpecialAttribute(tr,phonemes,dict_flags0); memcpy(p_start,word_copy,strlen(word_copy)); return(0); } /* end of TranslateRules */ void ApplySpecialAttribute2(Translator *tr, char *phonemes, int dict_flags) {//======================================================================== // apply after the translation is complete int ix; int len; char *p; len = strlen(phonemes); if(tr->langopts.param[LOPT_ALT] & 2) { for(ix=0; ix<(len-1); ix++) { if(phonemes[ix] == phonSTRESS_P) { p = &phonemes[ix+1]; if((dict_flags & FLAG_ALT2_TRANS) != 0) { if(*p == PhonemeCode('E')) *p = PhonemeCode('e'); if(*p == PhonemeCode('O')) *p = PhonemeCode('o'); } else { if(*p == PhonemeCode('e')) *p = PhonemeCode('E'); if(*p == PhonemeCode('o')) *p = PhonemeCode('O'); } break; } } } } // end of ApplySpecialAttribute2 void ApplySpecialAttribute(Translator *tr, char *phonemes, int dict_flags) {//======================================================================= // Amend the translated phonemes according to an attribute which is specific for the language. int len; char *p_end; if((dict_flags & (FLAG_ALT_TRANS | FLAG_ALT2_TRANS)) == 0) return; len = strlen(phonemes); p_end = &phonemes[len-1]; switch(tr->translator_name) { #ifdef deleted // this is now done in de_rules case L('d','e'): if(p_end[0] == PhonemeCode2('i',':')) { // words ends in ['i:], change to [=I@] p_end[-1] = phonSTRESS_PREV; p_end[0] = PhonemeCode('I'); p_end[1] = phonSCHWA; p_end[2] = 0; } break; #endif case L('r','o'): if(p_end[0] == PhonemeCode('j')) { // word end in [j], change to ['i] p_end[0] = phonSTRESS_P; p_end[1] = PhonemeCode('i'); p_end[2] = 0; } break; } } // end of ApplySpecialAttribute //============================================================================================= // Look up a word in the pronunciation dictionary list // - exceptions which override the usual pronunciation rules, or which give a word // special properties, such as pronounce as unstressed //============================================================================================= int TransposeAlphabet(Translator *tr, char *text) {//============================================== // transpose cyrillic alphabet (for example) into ascii (single byte) character codes // return: number of bytes, bit 6: 1=used compression int c; int c2; int ix; int offset; int min; int max; char *p = text; char *p2 = text; int all_alpha=1; int bits; int acc; int pairs_start; const short *pairs_list; offset = tr->transpose_min - 1; min = tr->transpose_min; max = tr->transpose_max; pairs_start = max - min + 2; do { p += utf8_in(&c,p); if((c >= min) && (c <= max)) { *p2++ = c - offset; } else if(c != 0) { p2 += utf8_out(c,p2); all_alpha=0; } } while (c != 0); *p2 = 0; if(all_alpha) { // compress to 6 bits per character acc=0; bits=0; p = text; p2 = text; while((c = *p++) != 0) { if((pairs_list = tr->frequent_pairs) != NULL) { c2 = c + (*p << 8); for(ix=0; c2 >= pairs_list[ix]; ix++) { if(c2 == pairs_list[ix]) { // found an encoding for a 2-character pair c = ix + pairs_start; // 2-character codes start after the single letter codes p++; break; } } } acc = (acc << 6) + (c & 0x3f); bits += 6; if(bits >= 8) { bits -= 8; *p2++ = (acc >> bits); } } if(bits > 0) { *p2++ = (acc << (8-bits)); } *p2 = 0; return((p2 - text) | 0x40); // bit 6 indicates compressed characters } return(p2 - text); } // end of TransposeAlphabet static const char *LookupDict2(Translator *tr, const char *word, const char *word2, char *phonetic, unsigned int *flags, int end_flags, WORD_TAB *wtab) //===================================================================================== /* Find an entry in the word_dict file for a specified word. Returns NULL if no match, else returns 'word_end' word zero terminated word to match word2 pointer to next word(s) in the input text (terminated by space) flags: returns dictionary flags which are associated with a matched word end_flags: indicates whether this is a retranslation after removing a suffix */ { char *p; char *next; int hash; int phoneme_len; int wlen; unsigned char flag; unsigned int dictionary_flags; unsigned int dictionary_flags2; int condition_failed=0; int n_chars; int no_phonemes; int skipwords; int ix; const char *word_end; const char *word1; int wflags = 0; // int wflags2; char word_buf[N_WORD_BYTES+1]; if(wtab != NULL) { wflags = wtab->flags; } word1 = word; if(tr->transpose_min > 0) { strncpy0(word_buf,word, N_WORD_BYTES); wlen = TransposeAlphabet(tr, word_buf); word = word_buf; } else { wlen = strlen(word); } hash = HashDictionary(word); p = tr->dict_hashtab[hash]; if(p == NULL) { if(flags != NULL) *flags = 0; return(0); } // Find the first entry in the list for this hash value which matches. // This corresponds to the last matching entry in the *_list file. while(*p != 0) { next = p + p[0]; if(((p[1] & 0x7f) != wlen) || (memcmp(word,&p[2],wlen & 0x3f) != 0)) { // bit 6 of wlen indicates whether the word has been compressed; so we need to match on this also. p = next; continue; } /* found matching entry. Decode the phonetic string */ word_end = word2; dictionary_flags = 0; dictionary_flags2 = 0; no_phonemes = p[1] & 0x80; p += ((p[1] & 0x3f) + 2); if(no_phonemes) { phonetic[0] = 0; phoneme_len = 0; } else { strcpy(phonetic,p); phoneme_len = strlen(p); p += (phoneme_len + 1); } while(p < next) { // examine the flags which follow the phoneme string flag = *p++; if(flag >= 100) { // conditional rule if(flag >= 132) { // fail if this condition is set if((tr->dict_condition & (1 << (flag-132))) != 0) condition_failed = 1; } else { // allow only if this condition is set if((tr->dict_condition & (1 << (flag-100))) == 0) condition_failed = 1; } } else if(flag > 80) { // flags 81 to 90 match more than one word // This comes after the other flags n_chars = next - p; skipwords = flag - 80; // don't use the contraction if any of the words are emphasized // or has an embedded command, such as MARK if(wtab != NULL) { for(ix=0; ix <= skipwords; ix++) { if(wtab[ix].flags & FLAG_EMPHASIZED2) // if(((wflags2 = wtab[ix].flags) & FLAG_EMPHASIZED2) || ((ix > 0) && (wflags2 & FLAG_EMBEDDED))) { condition_failed = 1; } } } if(memcmp(word2,p,n_chars) != 0) condition_failed = 1; if(condition_failed) { p = next; break; } dictionary_flags |= FLAG_SKIPWORDS; dictionary_skipwords = skipwords; p = next; word_end = word2 + n_chars; } else if(flag > 64) { // stressed syllable information, put in bits 0-3 dictionary_flags = (dictionary_flags & ~0xf) | (flag & 0xf); if((flag & 0xc) == 0xc) dictionary_flags |= FLAG_STRESS_END; } else if(flag >= 32) { dictionary_flags2 |= (1L << (flag-32)); } else { dictionary_flags |= (1L << flag); } } if(condition_failed) { condition_failed=0; continue; } if((end_flags & FLAG_SUFX)==0) { // no suffix has been removed if(dictionary_flags & FLAG_STEM) continue; // this word must have a suffix } if((end_flags & SUFX_P) && (dictionary_flags & (FLAG_ONLY | FLAG_ONLY_S))) continue; // $only or $onlys, don't match if a prefix has been removed if(end_flags & FLAG_SUFX) { // a suffix was removed from the word if(dictionary_flags & FLAG_ONLY) continue; // no match if any suffix if((dictionary_flags & FLAG_ONLY_S) && ((end_flags & FLAG_SUFX_S)==0)) { // only a 's' suffix allowed, but the suffix wasn't 's' continue; } } if(dictionary_flags2 & FLAG_HYPHENATED) { if(!(wflags & FLAG_HYPHEN_AFTER)) { continue; } } if(dictionary_flags2 & FLAG_CAPITAL) { if(!(wflags & FLAG_FIRST_UPPER)) { continue; } } if(dictionary_flags2 & FLAG_ALLCAPS) { if(!(wflags & FLAG_ALL_UPPER)) { continue; } } if(dictionary_flags & FLAG_NEEDS_DOT) { if(!(wflags & FLAG_HAS_DOT)) continue; } if((dictionary_flags & FLAG_ATEND) && (word_end < tr->clause_end)) { // only use this pronunciation if it's the last word of the clause continue; } if((dictionary_flags & FLAG_ATSTART) && !(wtab->flags & FLAG_FIRST_WORD)) { // only use this pronunciation if it's the first word of a clause continue; } if((dictionary_flags2 & FLAG_SENTENCE) && !(tr->clause_terminator & CLAUSE_BIT_SENTENCE)) { // only uis this clause is a sentence , i.e. terminator is {. ? !} not {, : :} continue; } if(dictionary_flags2 & FLAG_VERB) { // this is a verb-form pronunciation if(tr->expect_verb || (tr->expect_verb_s && (end_flags & FLAG_SUFX_S))) { // OK, we are expecting a verb } else { /* don't use the 'verb' pronunciation unless we are expecting a verb */ continue; } } if(dictionary_flags2 & FLAG_PAST) { if(!tr->expect_past) { /* don't use the 'past' pronunciation unless we are expecting past tense */ continue; } } if(dictionary_flags2 & FLAG_NOUN) { if((!tr->expect_noun) || (end_flags & SUFX_V)) { /* don't use the 'noun' pronunciation unless we are expecting a noun */ continue; } } if(dictionary_flags & FLAG_ALT2_TRANS) { // language specific if((tr->translator_name == L('h','u')) && !(tr->prev_dict_flags & FLAG_ALT_TRANS)) continue; } if(flags != NULL) { flags[0] = dictionary_flags | FLAG_FOUND_ATTRIBUTES; flags[1] = dictionary_flags2; } if(phoneme_len == 0) { if(option_phonemes == 2) { fprintf(f_trans,"Flags: %s %s\n",word1,print_dictionary_flags(flags)); } return(0); // no phoneme translation found here, only flags. So use rules } if(flags != NULL) flags[0] |= FLAG_FOUND; // this flag indicates word was found in dictionary if(option_phonemes == 2) { char ph_decoded[N_WORD_PHONEMES]; int textmode; DecodePhonemes(phonetic,ph_decoded); if((dictionary_flags & FLAG_TEXTMODE) == 0) textmode = 0; else textmode = 1; if(textmode == translator->langopts.textmode) { // only show this line if the word translates to phonemes, not replacement text if((dictionary_skipwords) && (wtab != NULL)) { // matched more than one word // (check for wtab prevents showing RULE_SPELLING byte when speaking individual letters) memcpy(word_buf,word2,word_end-word2); word_buf[word_end-word2-1] = 0; fprintf(f_trans,"Found: '%s %s",word1,word_buf); } else { fprintf(f_trans,"Found: '%s",word1); } fprintf(f_trans,"' [%s] %s\n",ph_decoded,print_dictionary_flags(flags)); } } return(word_end); } return(0); } // end of LookupDict2 int LookupDictList(Translator *tr, char **wordptr, char *ph_out, unsigned int *flags, int end_flags, WORD_TAB *wtab) //================================================================================================================== /* Lookup a specified word in the word dictionary. Returns phonetic data in 'phonetic' and bits in 'flags' end_flags: indicates if a suffix has been removed */ { int length; const char *found; const char *word1; const char *word2; unsigned char c; int nbytes; int len; char word[N_WORD_BYTES]; static char word_replacement[N_WORD_BYTES]; length = 0; word2 = word1 = *wordptr; while((word2[nbytes = utf8_nbytes(word2)]==' ') && (word2[nbytes+1]=='.')) { // look for an abbreviation of the form a.b.c // try removing the spaces between the dots and looking for a match memcpy(&word[length],word2,nbytes); length += nbytes; word[length++] = '.'; word2 += nbytes+3; } if(length > 0) { // found an abbreviation containing dots nbytes = 0; while(((c = word2[nbytes]) != 0) && (c != ' ')) { nbytes++; } memcpy(&word[length],word2,nbytes); word[length+nbytes] = 0; found = LookupDict2(tr, word, word2, ph_out, flags, end_flags, wtab); if(found) { // set the skip words flag flags[0] |= FLAG_SKIPWORDS; dictionary_skipwords = length; return(1); } } for(length=0; length<(N_WORD_BYTES-1); length++) { if(((c = *word1++)==0) || (c == ' ')) break; if((c=='.') && (length > 0) && (isdigit(word[length-1]))) break; // needed for lang=hu, eg. "december 2.-ig" word[length] = c; } word[length] = 0; found = LookupDict2(tr, word, word1, ph_out, flags, end_flags, wtab); if(flags[0] & FLAG_MAX3) { if(strcmp(ph_out, tr->phonemes_repeat) == 0) { tr->phonemes_repeat_count++; if(tr->phonemes_repeat_count > 3) { ph_out[0] = 0; } } else { strncpy0(tr->phonemes_repeat, ph_out, sizeof(tr->phonemes_repeat)); tr->phonemes_repeat_count = 1; } } else { tr->phonemes_repeat_count = 0; } if((found == 0) && (flags[1] & FLAG_ACCENT)) { int letter; word2 = word; if(*word2 == '_') word2++; len = utf8_in(&letter, word2); LookupAccentedLetter(tr,letter, ph_out); found = word2 + len; } if(found == 0) { ph_out[0] = 0; // try modifications to find a recognised word if((end_flags & FLAG_SUFX_E_ADDED) && (word[length-1] == 'e')) { // try removing an 'e' which has been added by RemoveEnding word[length-1] = 0; found = LookupDict2(tr, word, word1, ph_out, flags, end_flags, wtab); } else if((end_flags & SUFX_D) && (word[length-1] == word[length-2])) { // try removing a double letter word[length-1] = 0; found = LookupDict2(tr, word, word1, ph_out, flags, end_flags, wtab); } } if(found) { // if textmode is the default, then words which have phonemes are marked. if(tr->langopts.textmode) *flags ^= FLAG_TEXTMODE; if(*flags & FLAG_TEXTMODE) { // the word translates to replacement text, not to phonemes if(end_flags & FLAG_ALLOW_TEXTMODE) { // only use replacement text if this is the original word, not if a prefix or suffix has been removed word_replacement[0] = 0; word_replacement[1] = ' '; sprintf(&word_replacement[2],"%s ",ph_out); // replacement word, preceded by zerochar and space word1 = *wordptr; *wordptr = &word_replacement[2]; if(option_phonemes == 2) { len = found - word1; memcpy(word,word1,len); // include multiple matching words word[len] = 0; fprintf(f_trans,"Replace: %s %s\n",word,*wordptr); } } else { // flags[0] &= ~FLAG_SKIPWORDS; // check lang=hu január 21.-ig (error: suffix repeated ??) } ph_out[0] = 0; return(0); } return(1); } ph_out[0] = 0; return(0); } // end of LookupDictList int Lookup(Translator *tr, const char *word, char *ph_out) {//=================================================== unsigned int flags[2]; flags[0] = flags[1] = 0; char *word1 = (char *)word; return(LookupDictList(tr, &word1, ph_out, flags, 0, NULL)); } int LookupFlags(Translator *tr, const char *word) {//============================================== char buf[100]; static unsigned int flags[2]; flags[0] = flags[1] = 0; char *word1 = (char *)word; LookupDictList(tr, &word1, buf, flags, 0, NULL); return(flags[0]); } int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy) {//======================================================================== /* Removes a standard suffix from a word, once it has been indicated by the dictionary rules. end_type: bits 0-6 number of letters bits 8-14 suffix flags word_copy: make a copy of the original word This routine is language specific. In English it deals with reversing y->i and e-dropping that were done when the suffix was added to the original word. */ int i; char *word_end; int len_ending; int end_flags; const char *p; int len; static char ending[12]; // these lists are language specific, but are only relevent if the 'e' suffix flag is used static const char *add_e_exceptions[] = { "ion", NULL }; static const char *add_e_additions[] = { // "c", "rs", "ir", "ur", "ath", "ns", "lu", NULL }; "c", "rs", "ir", "ur", "ath", "ns", "u", NULL }; for(word_end = word; *word_end != ' '; word_end++) { /* replace discarded 'e's */ if(*word_end == REPLACED_E) *word_end = 'e'; } i = word_end - word; memcpy(word_copy,word,i); word_copy[i] = 0; // look for multibyte characters to increase the number of bytes to remove for(len_ending = i = (end_type & 0x3f); i>0 ;i--) // num.of characters of the suffix { word_end--; while((*word_end & 0xc0) == 0x80) { word_end--; // for multibyte characters len_ending++; } } // remove bytes from the end of the word and replace them by spaces for(i=0; itranslator_name == L('n','l')) { if(((word_end[0] & 0x80) == 0) && ((word_end[-1] & 0x80) == 0) && IsVowel(tr, word_end[-1]) && IsLetter(tr, word_end[0], LETTERGP_C) && !IsVowel(tr, word_end[-2])) { //double the vowel before the (ascii) final consonant word_end[1] = word_end[0]; word_end[0] = word_end[-1]; word_end[2] = ' '; } } else if(tr->translator_name == L('e','n')) { // add 'e' to end of stem if(IsLetter(tr, word_end[-1],LETTERGP_VOWEL2) && IsLetter(tr, word_end[0],1)) { // vowel(incl.'y') + hard.consonant for(i=0; (p = add_e_exceptions[i]) != NULL; i++) { len = strlen(p); if(memcmp(p,&word_end[1-len],len)==0) { break; } } if(p == NULL) end_flags |= FLAG_SUFX_E_ADDED; // no exception found } else { for(i=0; (p = add_e_additions[i]) != NULL; i++) { len = strlen(p); if(memcmp(p,&word_end[1-len],len)==0) { end_flags |= FLAG_SUFX_E_ADDED; break; } } } } else if(tr->langopts.suffix_add_e != 0) { end_flags |= FLAG_SUFX_E_ADDED; } if(end_flags & FLAG_SUFX_E_ADDED) { utf8_out(tr->langopts.suffix_add_e, &word_end[1]); if(option_phonemes == 2) { fprintf(f_trans,"add e\n"); } } } if((end_type & SUFX_V) && (tr->expect_verb==0)) tr->expect_verb = 1; // this suffix indicates the verb pronunciation if((strcmp(ending,"s")==0) || (strcmp(ending,"es")==0)) end_flags |= FLAG_SUFX_S; // if(strcmp(ending,"'s")==0) if(ending[0] == '\'') end_flags &= ~FLAG_SUFX; // don't consider 's as an added suffix return(end_flags); } /* end of RemoveEnding */ praat-6.0.04/external/espeak/espeak_command.h000066400000000000000000000074361261542461700211430ustar00rootroot00000000000000#ifndef ESPEAK_COMMAND_H #define ESPEAK_COMMAND_H #ifndef PLATFORM_WINDOWS #include #endif #include "speak_lib.h" enum t_espeak_type { ET_TEXT, ET_MARK, ET_KEY, ET_CHAR, ET_PARAMETER, ET_PUNCTUATION_LIST, ET_VOICE_NAME, ET_VOICE_SPEC, ET_TERMINATED_MSG }; typedef struct { unsigned int unique_identifier; void* text; size_t size; unsigned int position; espeak_POSITION_TYPE position_type; unsigned int end_position; unsigned int flags; void* user_data; } t_espeak_text; typedef struct { unsigned int unique_identifier; void* text; size_t size; const char* index_mark; unsigned int end_position; unsigned int flags; void* user_data; } t_espeak_mark; typedef struct { unsigned int unique_identifier; void* user_data; wchar_t character; } t_espeak_character; typedef struct { unsigned int unique_identifier; void* user_data; const char* key_name; } t_espeak_key; typedef struct { unsigned int unique_identifier; void* user_data; } t_espeak_terminated_msg; typedef struct { espeak_PARAMETER parameter; int value; int relative; } t_espeak_parameter; enum t_command_state { CS_UNDEFINED, // The command has just been created CS_PENDING, // stored in the fifo CS_PROCESSED // processed }; typedef struct { enum t_espeak_type type; t_command_state state; union command { t_espeak_text my_text; t_espeak_mark my_mark; t_espeak_key my_key; t_espeak_character my_char; t_espeak_parameter my_param; const wchar_t* my_punctuation_list; const char *my_voice_name; espeak_VOICE my_voice_spec; t_espeak_terminated_msg my_terminated_msg; } u; } t_espeak_command; t_espeak_command* create_espeak_text(const void *text, size_t size, unsigned int position, espeak_POSITION_TYPE position_type, unsigned int end_position, unsigned int flags, void* user_data); t_espeak_command* create_espeak_mark(const void *text, size_t size, const char *index_mark, unsigned int end_position, unsigned int flags, void* user_data); t_espeak_command* create_espeak_terminated_msg(unsigned int unique_identifier, void* user_data); t_espeak_command* create_espeak_key(const char *key_name, void *user_data); t_espeak_command* create_espeak_char(wchar_t character, void *user_data); t_espeak_command* create_espeak_parameter(espeak_PARAMETER parameter, int value, int relative); t_espeak_command* create_espeak_punctuation_list(const wchar_t *punctlist); t_espeak_command* create_espeak_voice_name(const char *name); t_espeak_command* create_espeak_voice_spec(espeak_VOICE *voice_spec); void process_espeak_command( t_espeak_command* the_command); int delete_espeak_command( t_espeak_command* the_command); void display_espeak_command(t_espeak_command* the_command); espeak_ERROR sync_espeak_Synth(unsigned int unique_identifier, const void *text, size_t size, unsigned int position, espeak_POSITION_TYPE position_type, unsigned int end_position, unsigned int flags, void* user_data); espeak_ERROR sync_espeak_Synth_Mark(unsigned int unique_identifier, const void *text, size_t size, const char *index_mark, unsigned int end_position, unsigned int flags, void* user_data); void sync_espeak_Key(const char *key); void sync_espeak_Char(wchar_t character); void sync_espeak_SetPunctuationList(const wchar_t *punctlist); void sync_espeak_SetParameter(espeak_PARAMETER parameter, int value, int relative); int sync_espeak_SetVoiceByName(const char *name); int sync_espeak_SetVoiceByProperties(espeak_VOICE *voice_selector); espeak_ERROR SetVoiceByName(const char *name); espeak_ERROR SetVoiceByProperties(espeak_VOICE *voice_selector); void SetParameter(int parameter, int value, int relative); int sync_espeak_terminated_msg(unsigned int unique_identifier, void* user_data); //> #endif praat-6.0.04/external/espeak/espeakdata_FileInMemory.cpp000066400000000000000000000147201261542461700232430ustar00rootroot00000000000000/* espeakdata_FileInMemory.c * * Copyright (C) David Weenink 2012 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ // The glue between Praat and espeak #include "speech.h" #include FilesInMemory espeakdata_variants; FilesInMemory espeakdata_dicts; FilesInMemory espeakdata_phons; FilesInMemory espeakdata_voices; Strings espeakdata_voices_names; Strings espeakdata_voices_names_short; Strings espeakdata_variants_names; static void FilesInMemory_and_Strings_changeIds (FilesInMemory me, Strings thee) { try { if (my size != thy numberOfStrings) return; // do nothing for (long i = 1; i <= my size; i++) { FileInMemory_setId ((FileInMemory) my item[i], thy strings[i]); } } catch (MelderError) { Melder_throw (me, U"Ids not changed."); } } static Strings espeak_voices_sort () { try { autoTable names = espeakdata_voices_to_Table (espeakdata_voices); autoStrings fullnames = espeakdata_voices_getNames (names.peek(), 2); FilesInMemory_and_Strings_changeIds (espeakdata_voices, fullnames.peek()); espeakdata_voices -> d_sortKey = 1; // sort id's Sorted_sort (espeakdata_voices); Table_sortRows_string (names.peek(), U"name"); //They hopefully sort the same way autoStrings neworder = espeakdata_voices_getNames (names.peek(), 2); autoStrings names_short = espeakdata_voices_getNames (names.peek(), 1); FilesInMemory_and_Strings_changeIds (espeakdata_voices, names_short.peek()); return neworder.transfer(); } catch (MelderError) { Melder_throw (U"Espeak voices not sorted."); } } static Strings Strings_insertAndExpand (Strings me, long position, const char32 *newstring) { try { if (position == 0) position = my numberOfStrings + 1; Melder_assert (position >= 1); Melder_assert (position <= my numberOfStrings + 1); autoStrings thee = Thing_new (Strings); thy strings = NUMvector (1, my numberOfStrings + 1); for (long i = 1, from = 1; i <= my numberOfStrings + 1; i++, from++) { const char32 *to_copy = my strings[from]; if (i == position) { to_copy = newstring; from--; } thy strings[i] = Melder_dup (to_copy); } thy numberOfStrings = my numberOfStrings + 1; return thee.transfer(); } catch (MelderError) { Melder_throw (me, U" not expanded."); } } void espeakdata_praat_init () { try { espeakdata_variants = create_espeakdata_variants (); autoStrings vnames = FilesInMemory_to_Strings_id (espeakdata_variants); espeakdata_variants_names = Strings_insertAndExpand (vnames.peek(), 1, U"default"); espeakdata_dicts = create_espeakdata_dicts (); espeakdata_phons = create_espeakdata_phons (); espeakdata_voices = create_espeakdata_voices (); espeakdata_voices_names = espeak_voices_sort (); autoTable names_table = espeakdata_voices_to_Table (espeakdata_voices); } catch (MelderError) { Melder_throw (U"Espeakdata initialization not performed."); } } #define ESPEAK_ISSPACE(c) (c == ' ' || c == '\t' || c == '\r' || c == '\n') // imitates fgets_strip for file in memory const char * espeakdata_get_voicedata (const char *data, long ndata, char *buf, long nbuf, long *index) { if (ndata <= 0 || nbuf <= 0 || *index >= ndata) { return 0; } long i = 0; while (i < nbuf && *index < ndata && ((buf[i] = data[i]) != '\n')) { i++; (*index)++; } (*index)++; // ppgb 20151020 fix long idata = i + 1; buf[i] = '\0'; while (--i >= 0 && ESPEAK_ISSPACE (buf[i])) { buf[i] = 0; } char *p = strstr (buf, "//"); if (p != 0) { *p = 0; } return &data[idata]; } Table espeakdata_voices_to_Table (FilesInMemory me) { try { autoTable thee = Table_createWithColumnNames (my size, U"id name"); for (long ifile = 1; ifile <= my size; ifile++) { FileInMemory fim = (FileInMemory) my item[ifile]; Table_setStringValue (thee.peek(), ifile, 1, fim -> d_id); const char *p = strstr (fim -> d_data, "name"); if (p == NULL) continue; // copy the name part to the following new line char buf[40], *bufp = buf; long len = 0; while ((*bufp++ = *p++) != '\n' && len < 39) { len++; } // remove trailing white space *bufp = 0; while (ESPEAK_ISSPACE (buf[len]) && len > 0) { buf[len] = 0; len--; } // skip leading white space bufp = & buf[4]; while (ESPEAK_ISSPACE (*bufp)) { *bufp++; } Table_setStringValue (thee.peek(), ifile, 2, Melder_peek8to32 (bufp)); TableRow row = static_cast (thy rows -> item [ifile]); wint_t c0 = row -> cells [2]. string[0]; row -> cells [2]. string[0] = towupper (c0); } return thee.transfer(); } catch (MelderError) { Melder_throw (U"Espeakdata: voice table not initialized."); } } Strings espeakdata_voices_getNames (Table me, long column) { try { if (column < 0 || column > 2) { Melder_throw (U"Illegal columnn."); } autoStrings thee = Thing_new (Strings); thy strings = NUMvector (1, my rows -> size); thy numberOfStrings = 0; for (long irow = 1; irow <= my rows -> size; irow++) { thy strings[irow] = Melder_dup (Table_getStringValue_Assert (me, irow, column)); thy numberOfStrings++; } return thee.transfer(); } catch (MelderError) { Melder_throw (U"Espeakdata: voices not initialized."); } } char * espeakdata_get_dict_data (const char *name, unsigned int *size) { long lsize; char *data = FilesInMemory_getCopyOfData (espeakdata_dicts, Melder_peek8to32 (name), &lsize); *size = (unsigned int) lsize; return data; } const char * espeakdata_get_voice (const char *vname, long *numberOfBytes) { return FilesInMemory_getData (espeakdata_voices, Melder_peek8to32 (vname), numberOfBytes); } const char * espeakdata_get_voiceVariant (const char *vname, long *numberOfBytes) { char *plus = strstr ((char *) vname, "+"); // prototype says: strstr (const char *, const char *) const char *name = plus != NULL ? ++plus : vname; return FilesInMemory_getData (espeakdata_variants, Melder_peek8to32 (name), numberOfBytes);; } /* End of file espeakdata_FileInMemory.cpp */ praat-6.0.04/external/espeak/espeakdata_FileInMemory.h000066400000000000000000000034321261542461700227060ustar00rootroot00000000000000#ifndef _espeakdata_FileInMemory_h_ #define _espeakdata_FileInMemory_h_ /* espeakdata_FileInMemory.h * Copyright (C) David Weenink 2012 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "FileInMemory.h" #include "Table.h" extern FilesInMemory espeakdata_phons; extern FilesInMemory espeakdata_dicts; extern FilesInMemory espeakdata_voices; extern FilesInMemory espeakdata_variants; FilesInMemory create_espeakdata_phons (); FilesInMemory create_espeakdata_dicts (); FilesInMemory create_espeakdata_voices (); FilesInMemory create_espeakdata_variants (); extern Strings espeakdata_voices_names; extern Strings espeakdata_variants_names; void espeakdata_praat_init (); const char * espeakdata_get_voicedata (const char *data, long ndata, char *buf, long nbuf, long *index); Table espeakdata_voices_to_Table (FilesInMemory me); Strings espeakdata_voices_getNames (Table me, long column); // mask the char / char32 char * espeakdata_get_dict_data (const char *name, unsigned int *size); const char * espeakdata_get_voice (const char *vname, long *numberOfBytes); const char * espeakdata_get_voiceVariant (const char *vname, long *numberOfBytes); #endif praat-6.0.04/external/espeak/espeakdata_dicts.cpp000066400000000000000000210771201261542461700220200ustar00rootroot00000000000000/* File espeakdata_dicts.cpp was generated on Sun Nov 4 17:43:38 2012 from all espeak-data/*_dict files: */ #include "espeakdata_FileInMemory.h" #include "Collection.h" #include "FileInMemory.h" #include "melder.h" FilesInMemory create_espeakdata_dicts () { try { autoFilesInMemory me = FilesInMemory_create (); static unsigned char espeakdata_dicts1_data[81298] = { 0, 4, 0, 0, 213, 80, 0, 0, 14, 69, 80, 245, 9, 85, 48, 47, 117, 91, 37, 111, 89, 0, 0, 0, 0, 0, 0, 10, 198, 88, 243, 210, 44, 243, 64, 66, 9, 9, 198, 80, 244, 142, 4, 67, 192, 66, 24, 74, 44, 243, 134, 101, 69, 5, 73, 66, 137, 20, 49, 110, 50, 83, 6, 123, 47, 113, 34, 80, 37, 0, 23, 65, 4, 35, 15, 49, 35, 48, 6, 112, 55, 35, 0, 81, 99, 97, 112, 112, 101, 108, 108, 97, 32, 0, 18, 71, 32, 81, 76, 80, 83, 65, 48, 107, 116, 55, 47, 13, 65, 35, 55, 0, 10, 199, 5, 69, 18, 4, 180, 201, 20, 66, 9, 198, 80, 241, 82, 36, 83, 128, 66, 0, 20, 72, 88, 243, 210, 56, 83, 69, 57, 48, 83, 117, 34, 50, 116, 65, 13, 50, 89, 0, 6, 195, 92, 19, 148, 8, 0, 11, 68, 88, 19, 142, 20, 83, 35, 50, 13, 0, 13, 68, 61, 1, 78, 16, 110, 48, 10, 108, 50, 47, 0, 12, 4, 1, 19, 39, 20, 35, 89, 13, 47, 0, 72, 10, 67, 80, 243, 153, 47, 120, 50, 37, 0, 0, 6, 65, 8, 71, 116, 0, 0, 10, 198, 92, 19, 142, 20, 84, 128, 65, 8, 6, 195, 76, 16, 131, 17, 0, 6, 195, 89, 48, 64, 17, 14, 67, 52, 82, 128, 65, 13, 57, 111, 83, 34, 120, 0, 24, 0, 0, 6, 65, 12, 89, 116, 0, 0, 0, 17, 10, 2, 18, 195, 188, 14, 8, 9, 12, 4, 5, 21, 100, 101, 0, 10, 13, 4, 95, 8, 1, 3, 49, 6, 115, 34, 110, 50, 0, 0, 0, 13, 69, 56, 81, 197, 21, 32, 50, 13, 136, 116, 34, 0, 10, 69, 32, 85, 201, 81, 64, 21, 0, 10, 6, 65, 16, 72, 116, 0, 0, 0, 0, 11, 68, 88, 144, 203, 76, 84, 37, 49, 89, 0, 0, 5, 65, 20, 116, 0, 0, 12, 201, 16, 85, 82, 77, 68, 129, 4, 193, 5, 66, 15, 70, 92, 18, 204, 60, 241, 128, 84, 115, 49, 55, 117, 83, 0, 0, 10, 67, 64, 243, 132, 48, 135, 50, 47, 0, 17, 4, 95, 48, 67, 15, 107, 6, 110, 50, 13, 34, 47, 89, 47, 13, 0, 0, 26, 73, 52, 244, 133, 48, 85, 1, 64, 20, 139, 65, 110, 34, 13, 55, 4, 108, 47, 35, 48, 6, 35, 34, 49, 0, 0, 8, 197, 60, 244, 140, 20, 112, 66, 14, 69, 36, 225, 129, 52, 80, 13, 50, 83, 115, 65, 13, 0, 22, 73, 48, 19, 135, 20, 226, 15, 88, 83, 128, 55, 35, 68, 13, 50, 107, 117, 83, 13, 50, 0, 6, 65, 24, 108, 83, 0, 0, 6, 195, 76, 21, 75, 17, 0, 0, 0, 8, 197, 28, 83, 129, 16, 80, 66, 21, 10, 13, 1, 20, 20, 8, 195, 169, 195, 188, 19, 65, 35, 47, 6, 37, 12, 111, 89, 0, 14, 69, 8, 83, 129, 16, 80, 71, 13, 50, 115, 72, 37, 0, 15, 69, 52, 243, 129, 12, 240, 65, 110, 50, 6, 115, 49, 40, 0, 6, 65, 28, 136, 116, 0, 0, 0, 8, 195, 44, 19, 128, 72, 11, 32, 18, 71, 12, 243, 5, 76, 33, 82, 28, 49, 117, 55, 89, 71, 112, 34, 136, 0, 0, 19, 72, 80, 84, 130, 48, 19, 131, 32, 80, 47, 13, 34, 71, 55, 115, 50, 91, 0, 0, 6, 65, 32, 107, 115, 0, 0, 13, 70, 24, 192, 85, 8, 84, 148, 21, 102, 114, 0, 10, 0, 8, 67, 48, 244, 132, 21, 0, 10, 0, 15, 70, 60, 211, 69, 44, 81, 82, 110, 65, 13, 49, 116, 34, 0, 10, 198, 36, 229, 21, 77, 49, 78, 8, 32, 10, 1, 35, 50, 110, 65, 13, 34, 0, 27, 0, 10, 69, 28, 21, 19, 9, 144, 21, 0, 10, 5, 65, 36, 37, 0, 6, 195, 5, 66, 214, 17, 0, 13, 6, 4, 195, 169, 10, 195, 160, 21, 102, 114, 0, 10, 13, 1, 37, 48, 13, 34, 89, 6, 108, 50, 47, 0, 27, 0, 14, 1, 38, 23, 35, 65, 48, 112, 34, 89, 35, 50, 47, 0, 0, 0, 18, 70, 77, 68, 153, 17, 35, 211, 89, 47, 34, 123, 47, 10, 34, 110, 89, 0, 16, 69, 20, 180, 197, 48, 96, 2, 112, 49, 89, 6, 112, 55, 83, 0, 6, 65, 40, 57, 116, 0, 0, 16, 70, 44, 21, 137, 4, 20, 128, 49, 35, 84, 37, 6, 115, 34, 0, 0, 8, 67, 76, 148, 128, 21, 0, 10, 10, 67, 12, 20, 140, 49, 115, 34, 114, 0, 9, 1, 42, 89, 47, 112, 34, 0, 27, 0, 20, 72, 52, 84, 133, 28, 80, 137, 20, 64, 65, 116, 34, 13, 136, 13, 71, 37, 47, 0, 16, 70, 4, 50, 197, 72, 208, 78, 35, 49, 13, 34, 65, 35, 50, 0, 10, 1, 43, 48, 55, 6, 111, 89, 0, 27, 0, 6, 65, 44, 49, 115, 0, 0, 0, 12, 71, 28, 83, 148, 48, 83, 65, 56, 21, 0, 10, 9, 1, 46, 48, 111, 50, 47, 0, 27, 0, 12, 68, 80, 19, 137, 4, 47, 35, 50, 57, 35, 0, 10, 1, 47, 89, 47, 34, 116, 48, 0, 27, 0, 14, 69, 17, 84, 214, 21, 32, 72, 111, 89, 83, 112, 34, 0, 6, 65, 48, 112, 55, 0, 0, 0, 12, 67, 52, 85, 128, 65, 13, 83, 34, 120, 0, 24, 0, 0, 6, 65, 52, 108, 65, 0, 0, 24, 11, 22, 5, 18, 1, 6, 7, 5, 12, 5, 195, 171, 83, 112, 34, 35, 83, 136, 13, 55, 116, 13, 0, 9, 198, 60, 244, 140, 20, 81, 128, 66, 0, 17, 70, 12, 128, 82, 37, 51, 65, 49, 35, 34, 6, 109, 89, 65, 35, 0, 0, 22, 72, 65, 35, 205, 21, 66, 5, 85, 48, 48, 34, 40, 65, 6, 116, 47, 37, 38, 111, 89, 0, 21, 72, 52, 20, 135, 5, 33, 84, 32, 16, 65, 35, 34, 136, 35, 34, 6, 116, 47, 35, 0, 0, 8, 197, 64, 20, 139, 36, 80, 65, 14, 69, 80, 19, 139, 92, 16, 47, 35, 68, 49, 58, 35, 0, 11, 5, 95, 48, 1, 14, 4, 11, 108, 50, 0, 6, 65, 56, 108, 50, 0, 0, 9, 198, 60, 225, 5, 73, 118, 76, 67, 0, 10, 199, 4, 19, 135, 4, 19, 132, 20, 66, 0, 21, 72, 44, 243, 15, 77, 49, 78, 76, 80, 49, 110, 55, 13, 89, 6, 134, 50, 89, 13, 0, 0, 9, 198, 60, 225, 5, 73, 113, 71, 67, 9, 197, 16, 16, 82, 60, 208, 8, 32, 5, 65, 60, 117, 0, 0, 17, 70, 21, 113, 78, 81, 114, 76, 116, 84, 13, 50, 47, 84, 13, 55, 0, 6, 194, 61, 0, 72, 12, 15, 70, 48, 82, 80, 60, 193, 20, 55, 122, 48, 110, 55, 47, 0, 13, 1, 61, 10, 136, 13, 55, 6, 123, 49, 10, 0, 27, 0, 12, 71, 16, 243, 129, 48, 68, 207, 56, 21, 0, 10, 16, 70, 12, 128, 82, 48, 83, 133, 91, 115, 55, 6, 37, 12, 50, 0, 0, 12, 68, 61, 32, 65, 48, 117, 34, 6, 115, 55, 0, 20, 72, 36, 224, 71, 56, 83, 73, 56, 112, 13, 50, 35, 136, 50, 116, 65, 13, 68, 0, 0, 7, 1, 64, 71, 123, 9, 0, 6, 65, 64, 48, 116, 0, 0, 16, 70, 4, 227, 129, 48, 85, 0, 35, 50, 35, 55, 6, 108, 47, 0, 0, 0, 0, 6, 65, 68, 49, 118, 0, 0, 16, 70, 32, 244, 193, 56, 224, 64, 107, 40, 89, 6, 35, 50, 35, 0, 0, 10, 199, 5, 52, 197, 77, 51, 210, 20, 67, 12, 199, 28, 85, 143, 48, 115, 9, 44, 66, 8, 32, 0, 0, 8, 197, 60, 209, 197, 20, 96, 66, 0, 8, 67, 80, 129, 79, 47, 119, 0, 11, 70, 12, 128, 82, 48, 84, 192, 21, 0, 10, 0, 15, 6, 1, 14, 4, 18, 195, 169, 6, 35, 50, 72, 34, 123, 0, 0, 0, 17, 70, 28, 85, 197, 48, 198, 83, 136, 116, 84, 13, 55, 55, 123, 89, 0, 6, 65, 76, 108, 89, 0, 0, 19, 71, 77, 0, 71, 32, 85, 20, 36, 89, 48, 2, 35, 81, 108, 47, 2, 37, 0, 0, 11, 136, 20, 21, 14, 9, 19, 9, 195, 171, 66, 18, 71, 44, 147, 66, 21, 35, 5, 100, 49, 37, 65, 71, 13, 34, 55, 37, 0, 17, 70, 16, 160, 75, 5, 37, 1, 75, 35, 49, 6, 35, 34, 47, 35, 0, 0, 0, 6, 65, 80, 47, 116, 0, 0, 17, 70, 48, 20, 193, 28, 225, 64, 55, 35, 89, 6, 35, 50, 57, 13, 0, 16, 70, 4, 33, 21, 48, 192, 72, 35, 71, 72, 6, 40, 55, 35, 0, 0, 0, 7, 196, 88, 243, 20, 20, 65, 0, 9, 198, 60, 225, 197, 92, 83, 147, 65, 5, 193, 84, 72, 32, 14, 69, 76, 19, 132, 72, 16, 89, 35, 50, 72, 34, 35, 0, 9, 198, 52, 20, 148, 36, 83, 147, 66, 15, 69, 84, 112, 78, 16, 16, 40, 81, 6, 35, 50, 72, 35, 0, 0, 14, 70, 64, 85, 71, 20, 245, 0, 48, 111, 12, 90, 120, 0, 0, 0, 22, 72, 76, 244, 200, 4, 225, 213, 88, 80, 89, 110, 91, 35, 68, 81, 6, 40, 12, 84, 108, 0, 0, 24, 73, 48, 19, 66, 61, 33, 200, 36, 226, 64, 55, 35, 65, 71, 110, 34, 81, 6, 37, 12, 50, 37, 0, 6, 65, 88, 83, 116, 0, 0, 9, 66, 5, 48, 4, 35, 89, 0, 8, 0, 0, 9, 68, 52, 16, 133, 48, 21, 0, 10, 11, 200, 12, 243, 147, 80, 19, 148, 36, 16, 66, 0, 13, 69, 64, 85, 9, 80, 80, 48, 13, 47, 37, 47, 0, 14, 69, 64, 85, 18, 85, 48, 48, 116, 47, 34, 111, 89, 0, 12, 1, 92, 47, 34, 118, 89, 47, 34, 116, 48, 0, 6, 65, 92, 84, 116, 0, 0, 16, 70, 56, 85, 10, 36, 84, 192, 50, 108, 12, 37, 80, 37, 89, 0, 16, 70, 36, 66, 76, 48, 84, 192, 37, 72, 6, 109, 55, 13, 89, 0, 0, 11, 67, 64, 244, 148, 48, 110, 34, 47, 0, 65, 24, 73, 29, 35, 194, 48, 84, 147, 16, 19, 0, 136, 34, 110, 71, 55, 13, 34, 89, 72, 6, 35, 55, 0, 0, 12, 68, 44, 17, 133, 20, 49, 35, 83, 6, 116, 0, 0, 7, 65, 96, 108, 49, 89, 0, 0, 17, 70, 64, 19, 5, 72, 211, 192, 48, 35, 55, 6, 112, 34, 65, 40, 0, 0, 16, 70, 56, 85, 10, 36, 84, 197, 50, 108, 37, 80, 37, 89, 13, 0, 0, 12, 68, 49, 80, 193, 76, 55, 40, 49, 35, 89, 0, 0, 17, 70, 76, 243, 132, 20, 225, 83, 89, 110, 50, 72, 13, 50, 108, 89, 0, 5, 65, 100, 123, 0, 0, 11, 67, 4, 211, 211, 6, 115, 65, 110, 89, 0, 9, 67, 80, 134, 83, 47, 123, 89, 0, 17, 70, 56, 21, 1, 76, 128, 64, 50, 2, 35, 47, 6, 35, 91, 35, 0, 0, 10, 199, 48, 85, 137, 80, 146, 213, 76, 66, 12, 71, 72, 240, 133, 73, 68, 207, 56, 21, 0, 10, 28, 67, 48, 244, 192, 55, 110, 89, 10, 6, 35, 50, 75, 13, 55, 37, 12, 88, 0, 81, 97, 110, 103, 101, 108, 101, 115, 32, 0, 10, 67, 8, 197, 77, 71, 55, 40, 65, 0, 0, 10, 69, 44, 83, 22, 36, 224, 21, 0, 10, 7, 65, 104, 88, 108, 72, 0, 0, 16, 70, 56, 148, 150, 4, 224, 64, 50, 13, 34, 84, 115, 50, 35, 0, 16, 70, 28, 20, 129, 28, 84, 192, 81, 13, 34, 115, 75, 13, 89, 0, 9, 67, 21, 84, 143, 128, 34, 40, 0, 17, 70, 76, 16, 146, 36, 224, 64, 89, 35, 71, 34, 6, 37, 50, 35, 0, 0, 19, 71, 88, 84, 132, 21, 32, 65, 56, 83, 113, 34, 72, 13, 34, 10, 115, 50, 0, 0, 11, 68, 64, 147, 143, 80, 48, 37, 50, 40, 0, 9, 198, 60, 225, 197, 48, 243, 198, 65, 19, 72, 29, 32, 72, 4, 212, 212, 4, 64, 136, 34, 115, 65, 89, 47, 35, 47, 0, 0, 14, 69, 44, 244, 1, 5, 32, 49, 110, 48, 10, 115, 34, 0, 0, 0, 18, 71, 72, 147, 80, 20, 194, 78, 28, 34, 109, 65, 48, 13, 55, 13, 68, 0, 0, 0, 8, 197, 76, 81, 5, 73, 64, 8, 0, 14, 70, 21, 66, 69, 56, 225, 64, 108, 47, 37, 13, 50, 0, 0, 0, 13, 68, 61, 32, 76, 20, 117, 34, 6, 115, 55, 13, 0, 0, 14, 69, 16, 19, 5, 56, 80, 72, 35, 55, 6, 116, 50, 0, 10, 69, 12, 192, 73, 72, 80, 21, 0, 10, 0, 18, 70, 52, 20, 148, 36, 226, 64, 65, 35, 34, 47, 6, 37, 12, 50, 37, 0, 17, 70, 88, 149, 129, 48, 66, 64, 84, 37, 84, 6, 35, 55, 72, 37, 0, 0, 0, 16, 70, 40, 84, 197, 8, 83, 0, 57, 116, 89, 13, 71, 112, 55, 0, 0, 0, 17, 70, 40, 19, 148, 92, 18, 192, 57, 35, 50, 47, 58, 6, 35, 49, 0, 16, 70, 16, 17, 5, 48, 146, 192, 72, 115, 72, 13, 55, 109, 49, 0, 17, 66, 5, 80, 120, 15, 48, 6, 113, 34, 0, 81, 112, 97, 105, 114, 32, 0, 10, 199, 16, 85, 82, 77, 64, 65, 56, 66, 0, 7, 196, 76, 19, 146, 8, 17, 0, 8, 197, 60, 225, 213, 57, 48, 65, 14, 69, 56, 19, 69, 57, 48, 50, 115, 65, 13, 50, 89, 0, 8, 197, 20, 180, 205, 4, 224, 65, 13, 69, 17, 83, 142, 21, 48, 72, 111, 50, 13, 89, 0, 0, 9, 198, 60, 225, 197, 52, 18, 192, 65, 0, 10, 1, 126, 47, 109, 55, 72, 13, 0, 27, 0, 0, 0, 11, 70, 12, 130, 67, 4, 115, 192, 21, 0, 10, 0, 0, 12, 68, 21, 33, 197, 72, 112, 34, 81, 13, 34, 0, 0, 0, 0, 15, 70, 92, 243, 19, 20, 193, 89, 58, 40, 55, 89, 55, 37, 0, 0, 0, 18, 70, 20, 193, 15, 72, 17, 15, 112, 55, 72, 110, 34, 6, 115, 72, 120, 0, 0, 15, 70, 16, 145, 134, 85, 84, 192, 72, 13, 83, 118, 12, 89, 0, 15, 70, 85, 68, 133, 12, 133, 0, 118, 47, 34, 112, 136, 47, 0, 0, 0, 14, 7, 3, 18, 195, 168, 3, 8, 5, 49, 34, 108, 91, 0, 0, 8, 197, 92, 16, 82, 60, 208, 8, 0, 9, 198, 76, 82, 212, 61, 33, 64, 66, 9, 198, 16, 242, 212, 61, 33, 64, 66, 14, 70, 72, 83, 133, 81, 65, 64, 34, 13, 50, 108, 47, 0, 0, 0, 11, 200, 88, 243, 19, 92, 19, 135, 21, 32, 65, 0, 0, 21, 66, 16, 16, 72, 35, 15, 84, 6, 37, 50, 76, 37, 0, 81, 118, 105, 110, 99, 105, 32, 0, 11, 70, 20, 20, 212, 28, 21, 5, 21, 0, 10, 0, 0, 14, 69, 88, 244, 137, 28, 80, 83, 117, 34, 13, 136, 13, 0, 16, 69, 76, 145, 83, 80, 16, 89, 37, 38, 6, 108, 89, 47, 35, 0, 14, 69, 29, 32, 78, 28, 80, 136, 34, 115, 50, 89, 37, 0, 14, 69, 20, 196, 193, 8, 80, 112, 55, 89, 13, 71, 37, 0, 0, 0, 7, 195, 16, 21, 0, 72, 11, 0, 7, 196, 44, 243, 148, 20, 65, 23, 72, 53, 5, 77, 4, 192, 78, 28, 16, 65, 48, 40, 12, 65, 35, 55, 6, 35, 68, 81, 35, 0, 8, 67, 48, 17, 25, 21, 0, 10, 0, 14, 69, 16, 80, 143, 72, 16, 72, 13, 71, 117, 34, 35, 0, 0, 17, 70, 32, 16, 129, 45, 82, 192, 107, 6, 35, 71, 35, 49, 111, 49, 0, 0, 18, 7, 4, 1, 14, 9, 195, 171, 12, 72, 6, 115, 50, 37, 12, 13, 55, 0, 0, 22, 72, 88, 84, 147, 36, 225, 1, 8, 16, 83, 113, 34, 89, 10, 13, 50, 72, 115, 71, 35, 0, 11, 200, 52, 148, 194, 73, 82, 75, 80, 80, 66, 12, 68, 88, 243, 22, 60, 84, 110, 55, 84, 40, 0, 0, 0, 15, 70, 44, 194, 77, 20, 145, 0, 49, 55, 109, 65, 123, 47, 0, 0, 0, 0, 0, 16, 70, 64, 144, 193, 77, 51, 192, 48, 37, 49, 6, 35, 89, 40, 0, 11, 70, 52, 20, 135, 5, 33, 84, 21, 0, 10, 0, 0, 16, 7, 19, 195, 169, 1, 14, 3, 5, 89, 2, 116, 133, 50, 89, 0, 0, 16, 70, 80, 84, 207, 85, 37, 83, 47, 13, 89, 120, 34, 111, 89, 0, 0, 0, 13, 67, 52, 228, 128, 65, 109, 50, 6, 116, 34, 0, 24, 0, 9, 68, 60, 113, 5, 56, 21, 0, 10, 0, 9, 198, 77, 64, 67, 12, 21, 15, 66, 0, 17, 70, 48, 20, 193, 73, 84, 192, 55, 115, 89, 13, 34, 2, 111, 89, 0, 15, 70, 13, 84, 211, 60, 228, 192, 49, 35, 89, 13, 50, 89, 0, 13, 66, 17, 32, 72, 6, 110, 49, 47, 13, 34, 0, 24, 16, 66, 9, 96, 71, 123, 83, 6, 117, 34, 71, 116, 55, 47, 0, 24, 0, 0, 12, 200, 36, 229, 5, 20, 225, 5, 20, 192, 66, 8, 13, 68, 40, 244, 213, 4, 57, 6, 117, 91, 37, 35, 0, 12, 68, 45, 34, 71, 20, 49, 34, 37, 136, 13, 0, 0, 12, 69, 76, 50, 15, 61, 32, 89, 49, 117, 34, 0, 0, 17, 70, 52, 244, 212, 21, 37, 0, 65, 6, 110, 89, 47, 13, 34, 47, 0, 0, 0, 11, 67, 8, 85, 1, 71, 116, 47, 35, 0, 9, 13, 68, 44, 83, 137, 4, 49, 37, 12, 50, 37, 35, 0, 0, 0, 9, 198, 65, 34, 77, 5, 65, 64, 66, 0, 0, 8, 196, 60, 225, 5, 72, 72, 12, 0, 13, 69, 24, 245, 82, 36, 80, 83, 40, 34, 6, 37, 0, 0, 0, 17, 71, 81, 34, 67, 32, 20, 132, 80, 47, 34, 37, 136, 115, 34, 47, 0, 0, 16, 70, 76, 83, 133, 44, 19, 0, 89, 116, 50, 13, 49, 35, 55, 0, 0, 14, 69, 28, 195, 210, 36, 16, 81, 55, 131, 34, 37, 35, 0, 12, 201, 4, 208, 78, 104, 147, 84, 61, 66, 64, 68, 0, 0, 11, 70, 88, 144, 212, 61, 34, 65, 21, 0, 10, 0, 11, 200, 60, 225, 197, 92, 83, 147, 16, 80, 67, 0, 0, 0, 9, 198, 84, 226, 70, 61, 35, 69, 67, 0, 7, 196, 76, 241, 1, 80, 8, 7, 196, 60, 209, 1, 80, 8, 0, 0, 0, 6, 195, 4, 224, 192, 17, 0, 12, 68, 29, 34, 69, 28, 81, 34, 37, 12, 81, 0, 0, 0, 10, 198, 56, 241, 212, 4, 228, 192, 8, 32, 0, 17, 70, 48, 243, 132, 20, 228, 197, 55, 110, 50, 72, 13, 50, 89, 13, 0, 11, 67, 8, 80, 64, 71, 37, 12, 57, 35, 0, 0, 0, 0, 0, 6, 195, 16, 145, 64, 72, 0, 10, 67, 105, 83, 21, 88, 40, 55, 40, 0, 0, 14, 69, 72, 243, 132, 21, 32, 34, 110, 50, 72, 13, 34, 0, 14, 69, 17, 83, 131, 4, 224, 72, 35, 68, 49, 14, 50, 0, 12, 69, 8, 245, 87, 21, 32, 71, 120, 13, 34, 0, 0, 0, 19, 71, 28, 83, 4, 20, 194, 75, 20, 136, 112, 55, 72, 13, 55, 13, 49, 13, 0, 0, 10, 67, 73, 81, 1, 34, 40, 72, 35, 0, 0, 14, 69, 49, 82, 68, 61, 0, 55, 127, 47, 10, 110, 48, 0, 10, 69, 72, 240, 133, 73, 64, 21, 0, 10, 15, 69, 8, 84, 212, 21, 32, 71, 6, 108, 89, 47, 13, 34, 0, 0, 12, 201, 60, 244, 133, 20, 226, 207, 53, 53, 5, 66, 19, 8, 5, 6, 5, 19, 9, 195, 171, 18, 37, 83, 6, 116, 89, 37, 13, 34, 0, 17, 8, 3, 9, 20, 18, 15, 195, 170, 14, 89, 13, 47, 34, 40, 50, 0, 15, 66, 16, 80, 72, 13, 15, 55, 35, 0, 72, 81, 108, 97, 32, 8, 66, 16, 80, 72, 13, 0, 9, 16, 70, 28, 243, 149, 8, 145, 64, 81, 13, 50, 40, 12, 71, 37, 0, 0, 0, 12, 68, 32, 147, 4, 20, 107, 37, 55, 72, 13, 0, 0, 8, 195, 32, 16, 82, 72, 9, 32, 16, 69, 76, 243, 1, 56, 176, 89, 2, 117, 55, 35, 68, 49, 0, 8, 16, 7, 11, 1, 14, 1, 195, 164, 14, 49, 115, 50, 115, 35, 50, 0, 0, 0, 18, 71, 64, 148, 143, 84, 85, 20, 20, 48, 13, 34, 40, 12, 6, 108, 47, 0, 20, 71, 4, 112, 77, 20, 211, 143, 56, 35, 136, 35, 65, 6, 108, 65, 50, 110, 50, 0, 0, 13, 68, 92, 83, 1, 24, 84, 112, 55, 10, 35, 83, 0, 9, 68, 9, 34, 65, 56, 21, 0, 10, 12, 4, 95, 4, 16, 20, 6, 48, 111, 50, 47, 0, 0, 0, 5, 194, 9, 144, 72, 16, 66, 17, 80, 72, 13, 15, 47, 125, 0, 81, 116, 111, 105, 116, 32, 19, 66, 17, 80, 72, 13, 15, 48, 34, 6, 116, 0, 81, 112, 114, 101, 101, 122, 32, 18, 66, 17, 80, 72, 13, 15, 48, 55, 125, 0, 81, 112, 108, 111, 111, 121, 32, 23, 66, 17, 80, 72, 40, 15, 48, 55, 13, 89, 6, 37, 0, 81, 112, 108, 101, 115, 115, 105, 115, 32, 24, 66, 17, 80, 72, 40, 15, 48, 37, 89, 6, 115, 50, 37, 0, 81, 112, 105, 115, 97, 110, 105, 101, 32, 5, 194, 17, 80, 72, 0, 10, 199, 80, 83, 141, 36, 228, 212, 20, 66, 0, 13, 68, 32, 19, 12, 60, 107, 6, 109, 55, 4, 120, 0, 11, 200, 20, 65, 76, 4, 112, 129, 72, 80, 67, 15, 7, 5, 21, 7, 195, 168, 14, 5, 118, 90, 6, 108, 50, 0, 0, 10, 67, 40, 80, 78, 90, 133, 50, 0, 41, 0, 0, 8, 67, 56, 82, 76, 21, 0, 10, 0, 12, 68, 80, 19, 135, 4, 47, 35, 68, 81, 35, 0, 8, 196, 80, 83, 147, 100, 66, 8, 7, 196, 56, 17, 1, 80, 8, 0, 8, 197, 24, 195, 210, 37, 48, 65, 19, 70, 4, 229, 15, 56, 149, 83, 35, 50, 47, 6, 117, 50, 37, 57, 111, 89, 0, 0, 6, 194, 4, 192, 8, 32, 17, 70, 40, 240, 67, 32, 147, 64, 57, 40, 58, 6, 115, 136, 13, 65, 0, 0, 0, 12, 68, 49, 82, 193, 76, 55, 40, 49, 35, 89, 0, 12, 68, 29, 33, 84, 4, 81, 34, 116, 47, 35, 0, 13, 4, 95, 20, 12, 4, 47, 6, 109, 55, 72, 13, 0, 0, 10, 69, 92, 21, 19, 60, 224, 21, 0, 10, 14, 69, 37, 48, 66, 20, 192, 37, 89, 13, 71, 112, 55, 0, 0, 9, 198, 4, 196, 133, 20, 68, 192, 66, 0, 16, 67, 20, 228, 192, 108, 50, 89, 117, 83, 117, 34, 47, 89, 0, 24, 0, 12, 68, 88, 83, 132, 4, 84, 108, 50, 72, 35, 0, 9, 68, 12, 242, 5, 56, 21, 0, 10, 0, 13, 69, 12, 131, 208, 36, 224, 91, 2, 110, 48, 133, 0, 0, 17, 70, 60, 213, 18, 20, 229, 0, 110, 65, 47, 34, 6, 108, 50, 47, 0, 22, 66, 21, 64, 108, 47, 89, 6, 108, 47, 13, 34, 35, 0, 81, 99, 101, 116, 101, 114, 97, 32, 9, 198, 4, 194, 66, 4, 208, 64, 67, 0, 0, 9, 198, 92, 16, 82, 32, 81, 78, 8, 16, 70, 85, 2, 78, 29, 67, 206, 35, 48, 37, 68, 47, 13, 50, 0, 0, 0, 17, 70, 52, 242, 1, 52, 209, 68, 65, 40, 107, 6, 35, 65, 13, 47, 0, 0, 0, 12, 137, 1, 7, 20, 5, 18, 23, 5, 195, 171, 67, 0, 0, 16, 70, 8, 147, 208, 76, 145, 64, 71, 37, 6, 110, 48, 89, 37, 0, 16, 70, 52, 243, 148, 4, 117, 64, 65, 110, 50, 47, 13, 49, 118, 0, 0, 0, 0, 0, 9, 198, 60, 244, 151, 4, 18, 64, 65, 0, 0, 9, 198, 72, 243, 132, 20, 83, 0, 66, 9, 68, 48, 245, 73, 76, 55, 126, 0, 0, 8, 197, 60, 244, 139, 60, 208, 66, 14, 69, 20, 97, 129, 80, 16, 108, 83, 6, 115, 47, 35, 0, 0, 0, 10, 67, 52, 241, 84, 65, 40, 47, 0, 32, 0, 9, 198, 88, 243, 210, 92, 16, 82, 66, 13, 68, 76, 243, 143, 64, 89, 110, 50, 10, 110, 48, 0, 11, 200, 60, 225, 197, 72, 145, 70, 36, 80, 65, 0, 16, 70, 24, 85, 1, 44, 16, 83, 83, 108, 47, 35, 49, 115, 89, 0, 13, 69, 76, 128, 82, 60, 224, 91, 112, 34, 14, 50, 0, 10, 69, 8, 244, 212, 60, 224, 21, 0, 10, 0, 11, 70, 92, 147, 12, 36, 19, 64, 21, 0, 10, 0, 0, 24, 72, 16, 84, 207, 56, 64, 78, 45, 48, 72, 108, 89, 19, 110, 50, 72, 35, 68, 49, 89, 0, 8, 32, 16, 70, 20, 147, 147, 80, 82, 78, 121, 50, 89, 47, 121, 12, 50, 0, 20, 9, 23, 1, 12, 12, 15, 14, 9, 195, 171, 84, 35, 55, 6, 117, 50, 37, 13, 0, 0, 14, 69, 8, 84, 212, 21, 48, 71, 108, 89, 47, 13, 89, 0, 23, 73, 12, 192, 78, 92, 147, 12, 36, 19, 64, 49, 55, 113, 50, 58, 6, 37, 55, 37, 13, 65, 0, 0, 10, 67, 52, 241, 83, 65, 40, 89, 0, 32, 15, 70, 44, 128, 89, 100, 19, 64, 49, 35, 57, 6, 35, 65, 0, 18, 5, 19, 13, 19, 39, 5, 108, 89, 10, 108, 65, 10, 6, 108, 89, 13, 0, 0, 0, 0, 11, 68, 8, 245, 8, 4, 71, 117, 47, 35, 0, 0, 14, 6, 14, 1, 21, 4, 195, 169, 50, 110, 72, 6, 116, 0, 0, 0, 16, 71, 76, 50, 18, 20, 147, 133, 72, 91, 34, 121, 50, 13, 34, 0, 0, 12, 68, 80, 19, 135, 60, 47, 35, 68, 136, 40, 0, 12, 68, 12, 147, 132, 100, 89, 109, 50, 72, 37, 0, 9, 68, 4, 115, 133, 76, 21, 0, 10, 12, 68, 44, 243, 135, 60, 49, 110, 68, 81, 40, 0, 0, 0, 17, 70, 56, 85, 19, 61, 113, 76, 50, 108, 47, 89, 117, 84, 112, 55, 0, 11, 70, 12, 128, 85, 12, 84, 128, 21, 0, 10, 0, 18, 71, 9, 82, 84, 21, 1, 82, 16, 71, 127, 47, 13, 48, 113, 34, 47, 0, 23, 10, 13, 1, 3, 5, 4, 15, 14, 9, 195, 171, 65, 35, 89, 13, 72, 6, 117, 50, 37, 13, 0, 24, 10, 2, 1, 2, 9, 12, 15, 14, 9, 195, 171, 71, 35, 71, 37, 55, 6, 117, 50, 37, 38, 13, 0, 0, 11, 68, 4, 195, 1, 32, 2, 35, 55, 115, 0, 18, 7, 9, 20, 1, 12, 9, 195, 171, 37, 47, 6, 115, 55, 37, 38, 13, 0, 22, 72, 4, 97, 193, 56, 148, 212, 4, 224, 35, 83, 81, 6, 35, 50, 37, 89, 47, 35, 50, 0, 0, 18, 70, 12, 20, 193, 56, 245, 129, 49, 35, 89, 35, 50, 6, 117, 84, 35, 0, 0, 0, 0, 11, 68, 32, 19, 143, 84, 107, 115, 50, 120, 0, 0, 18, 70, 76, 241, 15, 20, 225, 5, 89, 6, 117, 72, 4, 40, 50, 72, 13, 0, 0, 17, 70, 52, 20, 140, 20, 225, 64, 65, 35, 34, 55, 6, 116, 12, 50, 0, 21, 9, 1, 2, 9, 13, 195, 169, 12, 5, 7, 35, 71, 37, 50, 6, 116, 55, 108, 136, 0, 0, 17, 67, 36, 228, 208, 109, 50, 89, 48, 108, 49, 47, 6, 128, 34, 0, 24, 0, 13, 68, 88, 84, 129, 24, 83, 112, 34, 10, 35, 83, 0, 12, 68, 88, 19, 129, 24, 83, 35, 50, 35, 83, 0, 15, 70, 76, 50, 15, 20, 208, 78, 89, 49, 40, 65, 35, 50, 0, 0, 14, 69, 64, 19, 1, 92, 16, 48, 13, 55, 115, 84, 35, 0, 16, 69, 21, 52, 5, 4, 176, 37, 12, 38, 89, 48, 37, 12, 49, 0, 7, 195, 16, 149, 0, 72, 32, 0, 0, 19, 71, 76, 181, 76, 16, 83, 1, 76, 89, 49, 111, 55, 72, 13, 55, 35, 89, 0, 20, 71, 56, 20, 193, 72, 83, 133, 72, 50, 35, 89, 35, 34, 6, 116, 50, 13, 34, 0, 16, 70, 48, 148, 19, 80, 145, 75, 55, 109, 48, 89, 47, 37, 49, 0, 15, 70, 12, 129, 67, 44, 84, 147, 76, 108, 49, 13, 34, 89, 0, 15, 70, 53, 144, 149, 72, 114, 0, 65, 123, 71, 111, 34, 136, 0, 0, 13, 68, 52, 19, 1, 56, 65, 35, 55, 6, 35, 50, 0, 0, 14, 69, 52, 17, 1, 52, 80, 65, 35, 72, 6, 115, 65, 0, 13, 69, 52, 20, 148, 32, 16, 65, 35, 34, 47, 35, 0, 13, 69, 8, 84, 148, 32, 16, 71, 112, 34, 47, 35, 0, 0, 6, 195, 20, 243, 133, 66, 10, 67, 8, 83, 133, 71, 116, 50, 13, 0, 0, 0, 11, 200, 44, 192, 65, 77, 96, 75, 36, 80, 66, 15, 6, 10, 21, 14, 195, 173, 14, 136, 40, 50, 6, 37, 50, 0, 0, 10, 67, 41, 80, 78, 136, 58, 35, 50, 0, 16, 70, 28, 83, 210, 28, 147, 129, 75, 131, 75, 6, 37, 50, 35, 0, 17, 70, 16, 19, 137, 20, 195, 5, 72, 35, 50, 37, 38, 6, 112, 55, 0, 0, 11, 67, 105, 83, 65, 88, 40, 12, 65, 35, 0, 16, 70, 48, 21, 5, 28, 19, 128, 55, 115, 47, 13, 136, 35, 50, 0, 11, 70, 12, 194, 70, 80, 243, 128, 21, 0, 10, 0, 16, 70, 72, 145, 83, 48, 147, 135, 34, 37, 12, 89, 55, 37, 68, 0, 7, 195, 16, 19, 128, 8, 32, 20, 71, 52, 85, 21, 76, 19, 5, 52, 65, 13, 47, 6, 118, 89, 35, 55, 108, 65, 0, 19, 71, 64, 146, 197, 80, 33, 82, 28, 48, 13, 49, 108, 47, 71, 112, 34, 136, 0, 0, 0, 9, 198, 4, 100, 137, 12, 19, 129, 67, 0, 10, 67, 88, 84, 129, 84, 116, 34, 35, 0, 11, 70, 77, 65, 80, 32, 83, 128, 21, 0, 10, 0, 10, 67, 88, 84, 128, 83, 6, 113, 34, 0, 10, 199, 16, 85, 82, 28, 16, 78, 76, 65, 0, 16, 73, 52, 17, 1, 52, 242, 83, 20, 195, 5, 21, 102, 114, 0, 10, 0, 13, 69, 80, 129, 82, 60, 224, 47, 34, 6, 110, 50, 0, 10, 69, 48, 147, 9, 4, 224, 21, 0, 10, 0, 17, 70, 56, 146, 211, 92, 84, 132, 50, 109, 49, 89, 84, 113, 34, 47, 0, 15, 70, 88, 149, 137, 21, 36, 192, 84, 13, 84, 13, 57, 116, 0, 0, 0, 10, 67, 88, 84, 135, 83, 112, 34, 136, 0, 9, 68, 32, 83, 5, 56, 21, 0, 10, 0, 14, 69, 52, 244, 139, 20, 192, 65, 110, 34, 49, 13, 55, 0, 0, 0, 0, 19, 72, 12, 132, 137, 77, 66, 65, 4, 224, 49, 34, 109, 89, 47, 37, 115, 50, 0, 0, 23, 73, 8, 83, 1, 56, 116, 137, 44, 84, 128, 71, 13, 55, 35, 68, 34, 13, 49, 4, 109, 34, 0, 0, 0, 0, 0, 14, 69, 77, 80, 137, 21, 64, 89, 111, 71, 6, 37, 47, 0, 9, 198, 4, 193, 193, 4, 225, 5, 66, 0, 6, 194, 8, 240, 72, 12, 0, 18, 71, 13, 33, 83, 12, 83, 132, 60, 49, 34, 13, 91, 108, 50, 72, 40, 0, 23, 73, 72, 16, 200, 52, 19, 137, 56, 241, 134, 34, 35, 136, 65, 6, 35, 50, 37, 50, 110, 83, 0, 19, 71, 16, 83, 133, 52, 20, 139, 20, 72, 116, 50, 13, 65, 35, 34, 49, 13, 0, 18, 71, 8, 241, 75, 5, 33, 83, 80, 71, 40, 49, 35, 34, 108, 89, 47, 0, 0, 0, 16, 69, 36, 225, 21, 56, 16, 37, 50, 72, 6, 40, 12, 50, 35, 0, 15, 6, 13, 15, 18, 14, 195, 169, 65, 110, 34, 50, 6, 123, 0, 14, 69, 52, 243, 137, 12, 16, 65, 110, 50, 37, 49, 35, 0, 15, 69, 32, 83, 5, 56, 16, 107, 37, 55, 6, 116, 50, 35, 0, 13, 69, 8, 85, 19, 36, 80, 71, 108, 47, 89, 37, 0, 0, 0, 0, 0, 15, 69, 80, 245, 1, 48, 80, 47, 40, 47, 6, 115, 55, 13, 0, 14, 69, 56, 17, 5, 48, 80, 50, 115, 72, 116, 55, 13, 0, 18, 70, 52, 16, 193, 72, 243, 137, 65, 35, 49, 35, 34, 6, 117, 50, 37, 0, 21, 73, 12, 132, 137, 77, 67, 198, 24, 83, 0, 49, 34, 13, 89, 47, 110, 83, 13, 55, 0, 17, 69, 4, 209, 76, 36, 16, 35, 65, 6, 37, 12, 55, 37, 57, 35, 0, 14, 69, 28, 17, 1, 72, 16, 136, 13, 72, 115, 34, 35, 0, 0, 0, 17, 3, 226, 133, 148, 47, 58, 4, 116, 72, 6, 113, 34, 72, 13, 89, 0, 0, 13, 68, 72, 243, 133, 48, 34, 40, 50, 6, 112, 55, 0, 0, 18, 70, 40, 18, 207, 52, 147, 129, 57, 35, 49, 40, 65, 6, 37, 50, 35, 0, 0, 9, 198, 20, 180, 212, 20, 83, 128, 65, 16, 70, 45, 84, 149, 52, 19, 128, 49, 40, 34, 40, 65, 35, 50, 0, 0, 16, 70, 21, 33, 197, 72, 147, 135, 112, 34, 81, 13, 34, 13, 68, 0, 0, 12, 68, 16, 20, 133, 52, 72, 35, 34, 13, 65, 0, 14, 70, 12, 147, 147, 5, 85, 0, 89, 13, 50, 89, 117, 0, 11, 3, 226, 133, 147, 72, 113, 34, 72, 13, 0, 0, 15, 69, 36, 229, 5, 57, 48, 13, 50, 47, 6, 108, 50, 89, 0, 14, 69, 20, 193, 5, 73, 48, 112, 55, 72, 13, 34, 89, 0, 14, 73, 77, 4, 137, 56, 116, 212, 20, 83, 128, 21, 0, 10, 0, 10, 198, 60, 100, 203, 60, 243, 128, 66, 8, 9, 198, 88, 147, 10, 60, 83, 128, 66, 13, 70, 5, 98, 71, 56, 243, 128, 21, 102, 114, 0, 10, 0, 0, 9, 68, 20, 197, 137, 76, 21, 0, 10, 0, 19, 70, 5, 3, 212, 20, 244, 197, 35, 48, 110, 47, 37, 38, 6, 117, 89, 13, 0, 14, 69, 52, 245, 84, 60, 224, 65, 40, 47, 6, 110, 50, 0, 0, 9, 198, 8, 244, 203, 4, 20, 192, 66, 11, 70, 8, 80, 84, 48, 84, 192, 21, 0, 10, 16, 70, 52, 84, 211, 36, 20, 192, 65, 13, 89, 37, 57, 35, 89, 0, 15, 70, 8, 244, 12, 4, 20, 192, 71, 117, 48, 55, 115, 89, 0, 0, 10, 67, 4, 128, 64, 115, 107, 26, 115, 0, 19, 71, 52, 21, 82, 37, 66, 85, 76, 65, 110, 34, 6, 37, 91, 57, 111, 89, 0, 0, 9, 68, 92, 83, 132, 100, 21, 0, 10, 10, 3, 95, 49, 15, 10, 6, 116, 34, 0, 0, 0, 10, 3, 95, 49, 1, 10, 6, 116, 50, 0, 0, 14, 71, 8, 245, 82, 28, 83, 201, 76, 21, 102, 114, 0, 10, 9, 3, 226, 130, 172, 128, 34, 40, 0, 0, 19, 8, 22, 15, 195, 171, 12, 5, 14, 20, 83, 117, 13, 55, 10, 108, 50, 47, 0, 0, 0, 17, 70, 56, 244, 141, 4, 193, 64, 50, 110, 34, 65, 6, 115, 55, 13, 0, 0, 0, 24, 67, 64, 144, 203, 48, 4, 37, 49, 15, 13, 50, 15, 48, 6, 123, 0, 82, 110, 32, 112, 97, 121, 32, 10, 3, 95, 50, 15, 47, 58, 6, 116, 0, 0, 0, 9, 66, 20, 176, 112, 49, 0, 72, 32, 0, 0, 10, 67, 88, 84, 147, 83, 113, 34, 89, 0, 12, 68, 28, 83, 133, 72, 136, 116, 50, 13, 34, 0, 13, 68, 5, 51, 207, 44, 2, 35, 89, 10, 117, 49, 0, 0, 15, 69, 76, 19, 1, 52, 144, 89, 35, 55, 6, 115, 65, 37, 0, 7, 195, 32, 85, 0, 72, 32, 16, 69, 17, 99, 210, 4, 176, 72, 14, 84, 6, 131, 90, 35, 49, 0, 0, 16, 70, 81, 32, 71, 36, 82, 192, 47, 34, 35, 136, 6, 37, 49, 0, 17, 70, 9, 33, 89, 4, 226, 64, 71, 34, 37, 57, 6, 115, 50, 37, 0, 16, 70, 65, 33, 83, 80, 146, 192, 48, 34, 108, 89, 47, 37, 49, 0, 24, 74, 64, 245, 3, 32, 81, 147, 81, 35, 207, 52, 48, 110, 76, 109, 83, 89, 47, 34, 6, 117, 65, 0, 0, 11, 199, 60, 225, 5, 73, 113, 82, 64, 67, 36, 10, 199, 28, 84, 136, 5, 33, 21, 76, 66, 0, 9, 68, 40, 243, 133, 76, 21, 0, 10, 10, 3, 95, 51, 15, 72, 6, 113, 34, 0, 0, 15, 69, 76, 243, 149, 72, 80, 89, 110, 50, 10, 118, 34, 13, 0, 0, 6, 194, 37, 48, 72, 32, 0, 12, 71, 92, 147, 66, 48, 81, 15, 56, 21, 0, 10, 0, 20, 72, 5, 36, 143, 28, 19, 147, 36, 80, 35, 34, 40, 136, 6, 35, 50, 89, 37, 0, 12, 68, 76, 245, 8, 60, 89, 40, 12, 47, 40, 0, 9, 67, 41, 83, 135, 57, 40, 68, 0, 0, 0, 0, 9, 198, 32, 84, 139, 84, 193, 83, 65, 17, 70, 44, 19, 1, 24, 243, 135, 49, 35, 55, 35, 83, 6, 110, 68, 0, 0, 0, 0, 20, 9, 6, 18, 1, 14, 195, 167, 15, 9, 19, 83, 34, 133, 50, 89, 58, 6, 115, 0, 0, 6, 195, 16, 148, 192, 72, 14, 71, 12, 129, 86, 72, 243, 5, 80, 21, 102, 114, 0, 10, 0, 0, 15, 70, 56, 245, 83, 20, 64, 69, 50, 120, 89, 13, 72, 115, 0, 0, 16, 70, 80, 84, 85, 36, 192, 64, 47, 13, 49, 37, 12, 55, 35, 0, 16, 70, 44, 19, 9, 20, 96, 64, 49, 35, 55, 6, 37, 83, 35, 0, 17, 70, 56, 21, 1, 76, 160, 64, 50, 2, 35, 47, 6, 35, 91, 35, 0, 18, 70, 52, 21, 8, 36, 20, 192, 65, 35, 47, 6, 37, 12, 57, 35, 89, 0, 9, 198, 8, 84, 141, 84, 64, 64, 66, 0, 19, 71, 65, 33, 84, 61, 34, 85, 76, 48, 34, 13, 47, 117, 34, 37, 111, 89, 0, 0, 20, 72, 29, 34, 69, 44, 83, 1, 56, 64, 136, 34, 37, 49, 13, 55, 35, 50, 47, 0, 0, 9, 197, 60, 244, 150, 4, 192, 66, 36, 10, 69, 56, 83, 19, 60, 224, 21, 0, 10, 0, 25, 74, 76, 225, 69, 84, 32, 76, 20, 97, 133, 44, 89, 50, 119, 71, 35, 55, 10, 37, 83, 4, 108, 49, 0, 10, 67, 8, 85, 197, 71, 116, 84, 13, 0, 17, 70, 76, 81, 129, 56, 160, 64, 89, 13, 83, 6, 35, 50, 57, 35, 0, 14, 4, 95, 13, 3, 14, 65, 6, 35, 49, 34, 110, 50, 0, 0, 20, 71, 28, 192, 68, 36, 21, 15, 72, 136, 55, 35, 72, 37, 6, 115, 47, 110, 34, 0, 0, 15, 70, 72, 145, 75, 21, 37, 0, 34, 37, 49, 13, 34, 47, 0, 0, 0, 0, 20, 71, 52, 20, 203, 21, 34, 78, 28, 65, 35, 89, 49, 6, 116, 34, 13, 68, 0, 9, 15, 69, 32, 20, 132, 61, 0, 107, 35, 34, 47, 19, 110, 48, 0, 16, 6, 11, 1, 195, 175, 18, 15, 49, 35, 10, 6, 37, 34, 40, 0, 0, 12, 68, 64, 20, 139, 20, 48, 35, 34, 49, 13, 0, 14, 70, 8, 83, 142, 21, 69, 0, 71, 108, 50, 13, 47, 0, 0, 17, 70, 76, 147, 129, 28, 241, 197, 89, 13, 50, 13, 136, 117, 136, 13, 0, 25, 73, 28, 241, 1, 48, 208, 71, 80, 145, 192, 136, 110, 47, 10, 35, 55, 65, 6, 35, 136, 47, 13, 136, 0, 10, 69, 77, 69, 65, 73, 64, 21, 0, 10, 14, 69, 29, 84, 212, 5, 96, 81, 40, 89, 47, 35, 83, 0, 0, 9, 198, 52, 20, 211, 4, 193, 64, 66, 15, 70, 12, 81, 9, 48, 193, 64, 89, 13, 72, 109, 55, 13, 0, 14, 70, 64, 244, 147, 12, 129, 64, 48, 110, 34, 91, 13, 0, 15, 70, 21, 53, 5, 48, 193, 64, 2, 37, 89, 47, 112, 55, 0, 0, 0, 7, 196, 76, 244, 1, 76, 66, 13, 68, 16, 149, 129, 56, 72, 37, 84, 6, 35, 50, 0, 9, 198, 4, 197, 5, 52, 149, 0, 67, 12, 5, 10, 15, 19, 195, 169, 21, 101, 115, 0, 10, 0, 18, 70, 36, 228, 207, 52, 226, 65, 13, 50, 89, 110, 65, 50, 37, 57, 35, 0, 16, 69, 32, 83, 5, 56, 80, 107, 37, 12, 55, 6, 37, 12, 50, 0, 0, 0, 20, 71, 92, 83, 9, 77, 112, 65, 72, 84, 6, 112, 55, 14, 89, 84, 115, 34, 0, 8, 11, 70, 56, 144, 200, 60, 192, 83, 21, 0, 10, 18, 71, 76, 147, 135, 5, 3, 197, 72, 89, 37, 68, 81, 35, 48, 40, 34, 0, 0, 21, 72, 88, 243, 210, 52, 19, 9, 28, 80, 83, 117, 34, 65, 6, 115, 55, 13, 136, 13, 0, 12, 68, 88, 84, 130, 100, 83, 13, 34, 71, 123, 0, 11, 68, 60, 244, 140, 20, 117, 34, 55, 13, 0, 27, 13, 19, 20, 15, 3, 11, 5, 14, 19, 20, 18, 195, 182, 13, 89, 47, 110, 49, 13, 50, 89, 47, 34, 117, 65, 0, 11, 68, 24, 20, 129, 60, 83, 115, 34, 117, 0, 12, 68, 12, 84, 133, 76, 89, 116, 34, 13, 89, 0, 12, 3, 95, 55, 15, 89, 6, 116, 84, 13, 50, 0, 0, 19, 70, 77, 80, 149, 72, 34, 65, 89, 111, 71, 6, 111, 34, 71, 37, 57, 35, 0, 12, 201, 32, 243, 198, 76, 16, 75, 48, 146, 192, 66, 0, 9, 198, 60, 224, 146, 84, 146, 192, 65, 0, 12, 71, 77, 83, 142, 101, 50, 68, 20, 21, 0, 10, 0, 11, 68, 4, 68, 137, 20, 115, 72, 34, 37, 0, 24, 73, 64, 130, 76, 4, 65, 76, 64, 130, 65, 83, 13, 55, 13, 72, 6, 112, 55, 83, 37, 38, 35, 0, 17, 6, 95, 18, 15, 13, 1, 14, 34, 40, 65, 6, 123, 50, 89, 13, 0, 0, 0, 0, 10, 199, 4, 113, 210, 21, 52, 201, 20, 66, 9, 198, 32, 84, 131, 84, 193, 83, 65, 0, 16, 70, 12, 132, 137, 76, 160, 78, 49, 34, 109, 89, 57, 35, 50, 0, 0, 0, 7, 194, 20, 224, 72, 8, 32, 0, 10, 199, 16, 148, 204, 20, 180, 201, 20, 66, 13, 3, 95, 51, 88, 6, 72, 112, 34, 47, 109, 136, 0, 0, 21, 9, 8, 5, 12, 12, 15, 195, 175, 19, 5, 107, 108, 55, 40, 58, 6, 37, 12, 88, 0, 13, 3, 95, 48, 67, 6, 107, 110, 50, 13, 34, 47, 0, 0, 8, 197, 60, 228, 129, 4, 64, 65, 27, 69, 29, 32, 65, 24, 96, 136, 34, 115, 83, 15, 34, 13, 50, 6, 108, 47, 0, 81, 114, 101, 105, 110, 101, 116, 32, 13, 69, 12, 86, 76, 60, 224, 89, 13, 55, 110, 50, 0, 0, 14, 70, 77, 68, 129, 85, 52, 192, 89, 47, 34, 129, 89, 0, 0, 19, 71, 52, 145, 23, 36, 229, 5, 72, 65, 109, 72, 84, 13, 50, 47, 13, 34, 0, 0, 13, 72, 92, 20, 200, 36, 225, 212, 60, 224, 21, 0, 10, 11, 3, 95, 57, 15, 50, 116, 136, 13, 50, 0, 0, 14, 69, 76, 19, 85, 20, 192, 89, 115, 65, 118, 13, 55, 0, 0, 17, 70, 29, 35, 206, 17, 148, 192, 136, 34, 131, 50, 47, 10, 123, 89, 0, 9, 198, 21, 32, 83, 53, 84, 192, 66, 0, 10, 199, 28, 84, 148, 73, 82, 68, 4, 66, 0, 9, 68, 12, 20, 143, 48, 21, 0, 10, 0, 0, 14, 70, 76, 50, 21, 81, 65, 64, 89, 49, 111, 47, 13, 0, 14, 70, 4, 227, 133, 81, 65, 64, 35, 50, 6, 108, 47, 0, 0, 0, 0, 0, 16, 70, 88, 84, 135, 21, 65, 64, 83, 13, 34, 136, 116, 47, 13, 0, 16, 70, 69, 82, 74, 61, 65, 64, 49, 37, 136, 6, 110, 47, 108, 0, 15, 3, 95, 49, 57, 6, 50, 116, 136, 13, 50, 47, 37, 50, 0, 0, 13, 3, 95, 49, 56, 10, 6, 35, 136, 47, 37, 50, 0, 0, 0, 14, 69, 57, 83, 69, 72, 144, 50, 111, 65, 13, 34, 37, 0, 13, 69, 20, 224, 207, 72, 80, 133, 68, 49, 131, 34, 0, 15, 69, 52, 18, 149, 8, 16, 65, 35, 57, 6, 40, 71, 35, 0, 0, 0, 0, 20, 72, 88, 84, 140, 4, 225, 211, 80, 80, 83, 13, 34, 55, 35, 68, 89, 47, 13, 0, 8, 196, 4, 117, 5, 72, 72, 12, 0, 15, 69, 4, 97, 193, 56, 80, 35, 83, 81, 6, 115, 50, 13, 0, 8, 197, 80, 246, 79, 80, 16, 66, 11, 3, 226, 136, 146, 65, 37, 50, 111, 89, 0, 0, 6, 194, 33, 144, 72, 32, 11, 70, 29, 33, 71, 61, 38, 64, 21, 0, 10, 11, 3, 95, 49, 49, 10, 6, 112, 55, 83, 0, 0, 10, 3, 95, 49, 48, 6, 47, 37, 50, 0, 0, 11, 200, 12, 19, 142, 20, 195, 15, 56, 144, 67, 13, 3, 95, 49, 51, 6, 72, 112, 34, 47, 37, 50, 0, 0, 13, 3, 95, 49, 50, 6, 47, 58, 6, 115, 55, 83, 0, 0, 13, 3, 95, 49, 53, 6, 83, 123, 83, 47, 37, 50, 0, 0, 9, 67, 40, 242, 12, 57, 117, 55, 0, 13, 3, 95, 49, 52, 6, 83, 116, 34, 47, 37, 50, 0, 0, 15, 3, 95, 49, 55, 6, 89, 116, 84, 13, 50, 47, 37, 50, 0, 0, 17, 70, 72, 81, 5, 16, 83, 5, 34, 116, 72, 13, 72, 116, 55, 13, 0, 13, 3, 95, 49, 54, 6, 89, 108, 89, 47, 37, 50, 0, 0, 0, 9, 198, 52, 84, 131, 20, 65, 83, 66, 15, 3, 95, 55, 88, 6, 89, 116, 84, 13, 50, 47, 109, 136, 0, 0, 12, 68, 76, 245, 133, 72, 89, 117, 83, 112, 34, 0, 11, 68, 12, 132, 137, 76, 49, 34, 109, 89, 0, 0, 0, 9, 198, 60, 224, 133, 29, 34, 80, 65, 0, 0, 0, 0, 16, 70, 89, 32, 80, 73, 148, 192, 83, 34, 115, 48, 34, 123, 89, 0, 0, 18, 71, 77, 65, 80, 32, 19, 149, 76, 89, 47, 13, 83, 115, 50, 111, 89, 0, 0, 0, 0, 17, 70, 76, 243, 66, 21, 33, 64, 89, 6, 110, 65, 71, 13, 34, 13, 0, 16, 70, 69, 82, 88, 61, 65, 64, 49, 37, 136, 6, 110, 47, 108, 0, 0, 20, 8, 3, 5, 19, 1, 18, 195, 169, 1, 89, 13, 89, 13, 34, 37, 12, 57, 35, 0, 0, 0, 0, 9, 198, 45, 83, 20, 85, 33, 64, 66, 0, 0, 22, 72, 48, 148, 197, 57, 50, 65, 5, 64, 55, 13, 89, 134, 50, 89, 37, 38, 6, 115, 47, 0, 0, 16, 70, 52, 148, 212, 21, 34, 69, 65, 13, 89, 47, 116, 34, 37, 0, 9, 198, 24, 16, 212, 61, 69, 77, 66, 15, 69, 84, 197, 78, 16, 144, 40, 55, 6, 40, 50, 72, 37, 0, 0, 17, 70, 64, 20, 16, 21, 33, 76, 48, 35, 48, 13, 34, 6, 112, 55, 0, 0, 17, 70, 60, 225, 5, 73, 34, 71, 110, 50, 13, 34, 6, 109, 136, 0, 36, 10, 199, 4, 19, 135, 21, 50, 69, 56, 8, 0, 12, 68, 24, 244, 148, 20, 83, 110, 34, 47, 13, 0, 24, 68, 12, 20, 144, 20, 49, 35, 34, 48, 108, 15, 72, 37, 12, 108, 65, 0, 81, 100, 105, 101, 109, 32, 7, 196, 40, 244, 137, 76, 65, 9, 68, 32, 83, 146, 100, 21, 0, 10, 0, 15, 69, 56, 17, 193, 56, 16, 50, 35, 81, 6, 115, 50, 35, 0, 0, 9, 198, 60, 225, 197, 49, 146, 192, 65, 17, 70, 44, 20, 9, 81, 65, 76, 49, 35, 48, 6, 109, 47, 13, 55, 0, 20, 9, 13, 1, 20, 20, 8, 5, 195, 188, 19, 65, 35, 47, 6, 37, 12, 111, 89, 0, 16, 7, 7, 5, 14, 195, 168, 22, 5, 90, 13, 50, 108, 12, 84, 0, 0, 14, 3, 95, 50, 88, 6, 47, 58, 109, 50, 47, 109, 136, 0, 0, 9, 68, 16, 21, 137, 16, 21, 0, 10, 17, 67, 65, 33, 83, 48, 34, 13, 89, 13, 72, 6, 108, 50, 47, 0, 24, 0, 0, 0, 0, 26, 12, 11, 14, 1, 16, 19, 5, 11, 195, 170, 18, 5, 12, 49, 50, 35, 48, 89, 13, 49, 113, 34, 13, 55, 0, 10, 3, 95, 56, 15, 10, 6, 35, 136, 0, 0, 14, 69, 48, 242, 193, 5, 48, 55, 110, 49, 10, 115, 89, 0, 9, 197, 4, 225, 5, 73, 48, 8, 32, 0, 0, 0, 0, 0, 0, 16, 70, 25, 32, 78, 12, 242, 83, 83, 34, 35, 50, 91, 58, 35, 0, 0, 14, 68, 37, 53, 90, 84, 37, 89, 6, 40, 12, 88, 40, 0, 13, 3, 95, 63, 63, 89, 13, 65, 71, 6, 117, 55, 0, 0, 19, 8, 9, 18, 15, 14, 9, 5, 195, 171, 37, 34, 40, 50, 6, 37, 12, 13, 0, 14, 69, 36, 225, 9, 20, 224, 109, 50, 72, 37, 50, 0, 36, 9, 67, 28, 81, 78, 136, 116, 50, 0, 17, 70, 4, 97, 193, 4, 228, 197, 35, 83, 81, 6, 115, 50, 89, 13, 0, 20, 8, 1, 12, 7, 5, 18, 9, 195, 171, 35, 55, 136, 6, 116, 34, 116, 12, 14, 0, 0, 11, 70, 13, 147, 148, 32, 144, 64, 21, 0, 10, 0, 8, 67, 28, 81, 64, 136, 116, 0, 18, 71, 12, 132, 137, 77, 66, 65, 56, 49, 34, 109, 89, 47, 37, 35, 50, 0, 20, 71, 48, 17, 25, 9, 32, 78, 16, 55, 123, 72, 37, 71, 34, 6, 35, 50, 47, 0, 13, 3, 95, 52, 88, 6, 83, 116, 34, 47, 109, 136, 0, 0, 0, 16, 69, 88, 84, 132, 21, 32, 83, 6, 112, 34, 72, 13, 34, 0, 8, 10, 69, 21, 35, 133, 77, 64, 21, 0, 10, 20, 70, 104, 147, 66, 4, 37, 197, 88, 109, 12, 65, 71, 6, 35, 71, 10, 58, 108, 0, 0, 15, 70, 77, 86, 133, 81, 65, 64, 89, 40, 88, 6, 108, 47, 0, 10, 67, 60, 193, 193, 110, 55, 81, 35, 0, 15, 70, 52, 83, 1, 56, 145, 64, 65, 13, 55, 115, 50, 37, 0, 0, 0, 0, 14, 69, 72, 82, 197, 57, 64, 34, 116, 49, 13, 50, 47, 0, 8, 67, 40, 240, 78, 21, 0, 10, 10, 69, 32, 19, 76, 21, 64, 21, 0, 10, 0, 25, 74, 64, 81, 1, 48, 81, 5, 53, 2, 78, 28, 48, 13, 72, 115, 55, 13, 72, 108, 65, 48, 13, 68, 0, 5, 194, 56, 16, 72, 8, 66, 48, 80, 55, 13, 0, 9, 17, 70, 64, 244, 148, 84, 112, 76, 48, 110, 34, 47, 118, 136, 35, 55, 0, 0, 10, 199, 60, 244, 147, 81, 35, 207, 52, 66, 13, 3, 95, 53, 88, 6, 83, 123, 83, 47, 109, 136, 0, 0, 13, 68, 76, 241, 18, 4, 89, 117, 72, 34, 6, 115, 0, 7, 196, 76, 241, 18, 4, 8, 9, 68, 72, 245, 133, 72, 21, 0, 10, 0, 16, 73, 8, 245, 82, 28, 83, 201, 76, 145, 64, 21, 102, 114, 0, 10, 12, 69, 64, 145, 82, 72, 80, 48, 6, 116, 34, 0, 14, 69, 21, 35, 69, 48, 240, 112, 34, 65, 13, 55, 117, 0, 0, 25, 74, 76, 19, 135, 20, 209, 69, 57, 50, 193, 64, 89, 35, 50, 136, 13, 65, 116, 50, 89, 49, 35, 48, 0, 0, 17, 71, 76, 86, 67, 32, 83, 12, 20, 89, 123, 91, 6, 112, 55, 13, 0, 0, 0, 8, 197, 60, 244, 147, 20, 80, 66, 0, 6, 194, 41, 144, 72, 32, 9, 198, 16, 241, 66, 4, 18, 64, 66, 0, 20, 71, 72, 245, 5, 72, 83, 132, 20, 34, 40, 47, 6, 116, 34, 13, 50, 72, 13, 0, 13, 3, 95, 54, 88, 6, 89, 108, 89, 47, 109, 136, 0, 0, 23, 73, 60, 33, 82, 4, 211, 69, 72, 112, 85, 117, 71, 13, 34, 6, 35, 65, 13, 34, 81, 129, 0, 0, 24, 73, 16, 244, 212, 60, 161, 87, 76, 178, 64, 72, 110, 89, 47, 110, 57, 6, 108, 84, 89, 49, 37, 0, 22, 73, 28, 244, 132, 60, 228, 194, 4, 18, 64, 81, 131, 34, 72, 13, 50, 89, 71, 6, 122, 0, 0, 16, 70, 44, 133, 77, 4, 195, 192, 49, 40, 65, 6, 115, 55, 40, 0, 17, 7, 2, 15, 7, 15, 20, 195, 161, 71, 110, 81, 110, 47, 6, 115, 0, 0, 19, 71, 16, 85, 82, 20, 229, 25, 16, 72, 118, 13, 34, 13, 50, 47, 123, 47, 0, 18, 71, 8, 85, 8, 48, 82, 5, 52, 71, 108, 47, 10, 55, 37, 108, 65, 0, 0, 13, 70, 52, 243, 147, 36, 85, 82, 21, 102, 114, 0, 10, 21, 72, 32, 84, 146, 101, 49, 78, 37, 48, 107, 112, 34, 6, 123, 89, 13, 50, 13, 89, 0, 17, 70, 32, 20, 148, 77, 65, 82, 107, 35, 34, 47, 89, 47, 112, 34, 0, 0, 14, 69, 73, 84, 208, 21, 48, 34, 111, 89, 48, 13, 89, 0, 8, 197, 5, 52, 18, 37, 48, 66, 0, 9, 67, 40, 241, 89, 75, 120, 37, 0, 0, 0, 0, 17, 70, 81, 51, 197, 56, 19, 73, 47, 89, 40, 50, 6, 115, 65, 37, 0, 17, 70, 52, 19, 8, 21, 32, 133, 65, 35, 55, 6, 112, 34, 71, 13, 0, 0, 16, 70, 16, 146, 215, 20, 196, 192, 72, 109, 49, 84, 13, 55, 89, 0, 17, 70, 76, 17, 193, 72, 144, 64, 89, 35, 136, 35, 34, 6, 37, 35, 0, 11, 70, 40, 84, 211, 36, 48, 64, 21, 0, 10, 18, 70, 28, 19, 9, 48, 80, 64, 136, 35, 55, 13, 55, 6, 37, 12, 35, 0, 0, 0, 0, 10, 69, 17, 84, 212, 36, 224, 21, 0, 10, 0, 0, 20, 71, 5, 48, 70, 77, 64, 78, 16, 35, 89, 10, 35, 83, 89, 47, 35, 50, 47, 0, 8, 195, 40, 245, 64, 72, 9, 32, 9, 67, 52, 21, 68, 65, 131, 72, 0, 13, 3, 95, 56, 88, 6, 47, 35, 136, 47, 109, 136, 0, 0, 0, 20, 8, 1, 12, 2, 1, 14, 9, 195, 171, 35, 55, 71, 6, 115, 50, 116, 12, 14, 0, 0, 0, 0, 21, 73, 72, 144, 200, 5, 33, 19, 8, 16, 73, 34, 37, 76, 13, 72, 89, 71, 6, 122, 0, 0, 23, 73, 44, 19, 69, 72, 17, 5, 72, 145, 64, 49, 35, 65, 13, 34, 115, 72, 13, 34, 6, 37, 0, 0, 13, 70, 12, 128, 82, 48, 145, 64, 76, 115, 55, 37, 0, 0, 15, 3, 95, 57, 88, 6, 50, 116, 136, 13, 50, 47, 109, 136, 0, 0, 0, 13, 69, 12, 241, 206, 4, 48, 49, 110, 67, 35, 49, 0, 6, 195, 52, 85, 0, 72, 0, 0, 15, 70, 64, 130, 76, 48, 148, 19, 83, 109, 55, 13, 48, 89, 0, 20, 71, 44, 193, 79, 64, 21, 18, 4, 49, 55, 119, 12, 48, 6, 115, 47, 34, 35, 0, 0, 19, 72, 4, 229, 15, 36, 225, 84, 80, 80, 35, 50, 47, 40, 50, 6, 108, 47, 0, 0, 14, 69, 12, 20, 9, 80, 16, 49, 35, 48, 37, 47, 35, 0, 13, 69, 4, 209, 76, 20, 80, 35, 65, 13, 55, 116, 0, 20, 8, 2, 15, 12, 9, 22, 9, 195, 171, 71, 40, 55, 6, 109, 84, 37, 12, 13, 0, 0, 9, 198, 52, 19, 5, 4, 114, 64, 67, 15, 70, 76, 50, 15, 49, 70, 128, 89, 49, 131, 55, 47, 89, 0, 12, 3, 95, 63, 65, 55, 6, 108, 47, 13, 34, 0, 0, 23, 73, 76, 197, 73, 80, 85, 197, 56, 16, 82, 89, 55, 127, 47, 10, 116, 84, 13, 50, 115, 34, 0, 10, 199, 60, 227, 205, 92, 243, 132, 20, 67, 19, 71, 76, 80, 129, 77, 66, 65, 56, 89, 13, 71, 35, 89, 47, 37, 35, 50, 0, 0, 17, 70, 44, 19, 69, 72, 241, 78, 49, 35, 65, 13, 34, 6, 40, 50, 0, 0, 0, 0, 0, 0, 18, 70, 77, 84, 137, 56, 19, 69, 89, 118, 34, 37, 50, 6, 115, 65, 13, 0, 0, 10, 3, 19, 39, 14, 89, 13, 50, 0, 72, 0, 5, 194, 36, 224, 72, 10, 3, 226, 153, 175, 49, 34, 127, 89, 0, 0, 0, 9, 68, 72, 240, 137, 56, 21, 0, 10, 9, 3, 226, 153, 173, 65, 110, 55, 0, 0, 0, 17, 70, 44, 21, 5, 80, 84, 128, 49, 35, 47, 6, 116, 47, 13, 34, 0, 0, 10, 199, 76, 48, 82, 48, 21, 20, 36, 66, 14, 4, 95, 15, 7, 15, 117, 136, 117, 50, 4, 112, 49, 0, 0, 0, 15, 69, 52, 20, 148, 36, 224, 65, 6, 115, 34, 47, 13, 50, 0, 10, 69, 8, 83, 147, 60, 224, 21, 0, 10, 8, 197, 8, 20, 211, 60, 224, 66, 0, 15, 70, 64, 85, 15, 61, 36, 192, 48, 13, 47, 117, 34, 89, 0, 15, 70, 48, 245, 66, 76, 84, 128, 55, 120, 48, 91, 13, 34, 0, 15, 70, 8, 244, 132, 20, 21, 88, 71, 110, 34, 72, 6, 120, 0, 0, 20, 71, 28, 84, 141, 60, 193, 78, 20, 75, 109, 12, 65, 13, 55, 6, 37, 12, 50, 0, 15, 70, 24, 84, 146, 20, 148, 129, 83, 13, 34, 113, 34, 13, 0, 0, 0, 17, 70, 77, 65, 82, 92, 83, 147, 89, 47, 112, 34, 84, 13, 50, 89, 0, 10, 198, 52, 148, 194, 73, 82, 75, 66, 36, 21, 73, 20, 225, 197, 48, 36, 133, 12, 133, 0, 108, 68, 13, 55, 71, 34, 112, 136, 47, 0, 0, 0, 18, 70, 64, 192, 83, 20, 229, 1, 48, 55, 35, 89, 6, 108, 50, 47, 35, 0, 10, 199, 36, 225, 197, 88, 243, 7, 20, 67, 0, 19, 8, 13, 1, 2, 1, 12, 195, 170, 12, 65, 35, 71, 35, 55, 6, 112, 55, 0, 0, 0, 0, 13, 6, 18, 5, 14, 195, 169, 5, 34, 13, 50, 123, 0, 17, 70, 52, 21, 8, 36, 193, 1, 65, 35, 47, 6, 109, 55, 72, 35, 0, 21, 67, 77, 84, 20, 89, 40, 48, 34, 108, 50, 47, 108, 50, 72, 6, 108, 50, 47, 0, 24, 0, 33, 68, 52, 241, 21, 76, 65, 4, 117, 72, 111, 89, 15, 117, 48, 13, 34, 6, 35, 50, 72, 37, 0, 81, 111, 112, 101, 114, 97, 110, 100, 105, 32, 0, 8, 197, 60, 212, 133, 16, 80, 66, 13, 69, 60, 85, 86, 72, 80, 111, 12, 84, 34, 13, 0, 15, 69, 56, 21, 21, 72, 80, 50, 35, 47, 6, 118, 34, 13, 0, 0, 0, 11, 199, 60, 225, 5, 73, 51, 197, 44, 67, 36, 10, 199, 16, 85, 82, 45, 37, 73, 76, 66, 20, 71, 52, 19, 148, 61, 96, 78, 36, 65, 35, 50, 47, 110, 84, 6, 115, 50, 37, 0, 13, 67, 28, 83, 140, 136, 13, 50, 13, 34, 115, 55, 0, 0, 9, 198, 52, 20, 211, 4, 19, 0, 66, 21, 72, 12, 20, 16, 84, 48, 201, 56, 240, 49, 35, 48, 40, 76, 6, 37, 12, 50, 40, 0, 22, 68, 80, 128, 66, 4, 47, 35, 71, 6, 115, 15, 50, 76, 40, 0, 81, 110, 99, 104, 117, 32, 13, 72, 8, 243, 142, 36, 85, 129, 48, 80, 21, 0, 10, 0, 16, 69, 12, 20, 201, 56, 240, 49, 35, 89, 6, 37, 12, 50, 120, 0, 14, 69, 48, 83, 206, 36, 80, 55, 37, 6, 117, 50, 37, 0, 0, 9, 198, 88, 243, 8, 20, 145, 0, 65, 0, 22, 73, 77, 112, 78, 28, 84, 147, 92, 16, 82, 89, 58, 35, 68, 13, 34, 89, 58, 115, 34, 0, 23, 67, 65, 35, 192, 48, 34, 117, 15, 83, 6, 110, 34, 65, 35, 0, 81, 102, 111, 114, 109, 97, 32, 19, 71, 8, 244, 212, 4, 19, 132, 20, 71, 6, 117, 89, 47, 115, 50, 72, 13, 0, 7, 195, 4, 19, 128, 72, 12, 20, 71, 64, 83, 9, 56, 64, 66, 4, 48, 112, 55, 13, 50, 72, 6, 115, 71, 35, 0, 0, 22, 72, 20, 193, 77, 20, 229, 1, 48, 80, 108, 55, 13, 65, 108, 50, 47, 6, 115, 55, 13, 0, 0, 13, 69, 16, 85, 82, 73, 144, 72, 128, 34, 34, 123, 0, 16, 67, 65, 35, 198, 48, 34, 40, 83, 6, 108, 89, 13, 34, 0, 24, 0, 21, 9, 13, 9, 12, 9, 20, 195, 170, 18, 5, 65, 109, 55, 13, 47, 6, 113, 34, 13, 0, 8, 3, 195, 161, 19, 35, 89, 0, 11, 70, 52, 21, 82, 20, 83, 128, 21, 0, 10, 9, 198, 40, 244, 132, 4, 19, 128, 66, 11, 70, 12, 19, 69, 72, 243, 128, 21, 0, 10, 14, 4, 95, 48, 77, 50, 65, 109, 55, 57, 6, 40, 50, 0, 0, 15, 4, 95, 48, 77, 51, 65, 109, 55, 57, 6, 35, 34, 47, 0, 0, 11, 68, 52, 20, 137, 20, 65, 115, 34, 37, 0, 0, 15, 4, 95, 48, 77, 49, 6, 72, 6, 127, 89, 13, 50, 47, 0, 0, 17, 70, 24, 147, 5, 52, 243, 128, 83, 6, 37, 55, 13, 65, 110, 50, 0, 16, 4, 95, 2, 18, 22, 49, 6, 110, 34, 47, 116, 49, 13, 50, 0, 0, 9, 198, 92, 19, 8, 4, 195, 1, 66, 0, 0, 0, 15, 70, 52, 83, 9, 77, 48, 64, 65, 13, 55, 109, 89, 35, 0, 14, 70, 24, 148, 195, 32, 84, 128, 83, 37, 91, 13, 34, 0, 11, 70, 8, 83, 3, 32, 84, 128, 21, 0, 10, 0, 18, 70, 76, 83, 129, 80, 244, 133, 89, 13, 50, 35, 47, 6, 117, 34, 13, 0, 14, 71, 13, 35, 201, 77, 48, 78, 80, 21, 102, 114, 0, 10, 0, 10, 67, 52, 20, 129, 65, 115, 34, 35, 0, 0, 9, 198, 45, 112, 78, 77, 82, 83, 66, 17, 70, 44, 21, 19, 92, 147, 139, 49, 35, 47, 89, 84, 13, 50, 49, 0, 13, 69, 72, 85, 9, 20, 96, 34, 13, 47, 37, 83, 0, 0, 9, 198, 20, 83, 139, 20, 84, 128, 65, 16, 70, 16, 17, 211, 80, 84, 128, 72, 35, 136, 89, 47, 112, 34, 0, 0, 19, 71, 8, 84, 206, 20, 65, 78, 20, 71, 13, 89, 50, 116, 72, 13, 50, 13, 0, 10, 199, 9, 34, 84, 80, 19, 138, 20, 66, 0, 0, 16, 70, 88, 84, 146, 21, 113, 71, 83, 112, 34, 13, 84, 112, 136, 0, 0, 11, 70, 28, 147, 2, 21, 37, 0, 21, 0, 10, 0, 18, 71, 64, 243, 137, 21, 1, 82, 76, 48, 117, 50, 37, 48, 112, 34, 89, 0, 0, 0, 0, 9, 198, 60, 244, 147, 21, 49, 64, 66, 0, 10, 67, 24, 244, 148, 83, 110, 34, 47, 0, 8, 67, 29, 86, 64, 21, 0, 10, 18, 71, 8, 241, 68, 5, 1, 83, 80, 71, 40, 72, 35, 48, 108, 89, 47, 0, 0, 21, 72, 8, 17, 5, 56, 131, 210, 77, 64, 71, 115, 72, 13, 50, 107, 110, 34, 89, 47, 0, 0, 8, 197, 40, 84, 193, 40, 16, 66, 10, 69, 8, 241, 73, 56, 112, 21, 0, 10, 0, 0, 0, 12, 68, 8, 244, 137, 76, 71, 110, 34, 13, 89, 0, 0, 21, 73, 88, 241, 76, 20, 229, 8, 20, 145, 0, 83, 40, 55, 13, 50, 47, 107, 123, 47, 0, 15, 70, 72, 243, 201, 64, 84, 147, 34, 125, 48, 113, 34, 89, 0, 8, 197, 44, 147, 79, 56, 240, 66, 13, 69, 76, 20, 16, 32, 240, 89, 35, 48, 83, 40, 0, 14, 69, 12, 80, 201, 48, 80, 89, 13, 89, 37, 12, 55, 0, 0, 6, 194, 53, 144, 72, 32, 0, 9, 198, 77, 66, 76, 77, 118, 69, 65, 20, 71, 76, 19, 136, 20, 68, 137, 56, 89, 35, 50, 107, 6, 116, 72, 34, 13, 50, 0, 0, 22, 72, 12, 132, 137, 77, 66, 65, 56, 16, 49, 34, 13, 89, 47, 37, 57, 6, 115, 50, 35, 0, 0, 16, 70, 56, 81, 197, 72, 147, 135, 50, 13, 136, 116, 34, 13, 68, 0, 16, 70, 8, 85, 197, 72, 147, 135, 71, 13, 84, 116, 34, 109, 68, 0, 18, 70, 88, 84, 213, 88, 149, 83, 84, 13, 89, 40, 12, 84, 37, 111, 89, 0, 0, 0, 17, 71, 76, 50, 5, 21, 1, 82, 76, 89, 49, 116, 48, 13, 34, 89, 0, 0, 19, 72, 52, 19, 13, 21, 48, 149, 73, 144, 65, 115, 65, 89, 71, 13, 34, 37, 0, 0, 15, 69, 29, 32, 84, 37, 48, 136, 34, 6, 115, 47, 13, 89, 0, 14, 69, 4, 226, 77, 85, 48, 35, 50, 37, 65, 40, 89, 0, 0, 6, 194, 60, 96, 72, 8, 16, 70, 8, 16, 137, 48, 243, 128, 71, 35, 71, 37, 55, 110, 50, 0, 0, 20, 71, 92, 81, 199, 21, 113, 78, 76, 84, 112, 136, 13, 84, 6, 108, 12, 50, 89, 0, 17, 70, 52, 17, 5, 48, 83, 133, 65, 35, 72, 13, 55, 6, 116, 50, 0, 17, 70, 52, 17, 5, 48, 83, 133, 65, 35, 72, 13, 55, 6, 116, 50, 0, 12, 71, 5, 35, 83, 81, 35, 206, 28, 21, 0, 10, 0, 0, 0, 11, 70, 72, 22, 77, 60, 225, 0, 21, 0, 10, 12, 70, 77, 4, 137, 56, 116, 192, 21, 0, 41, 10, 0, 16, 70, 28, 83, 133, 72, 193, 73, 136, 116, 50, 13, 34, 55, 123, 0, 20, 71, 56, 81, 133, 73, 66, 84, 36, 50, 108, 83, 13, 34, 47, 6, 37, 47, 37, 0, 0, 0, 9, 198, 88, 244, 133, 56, 64, 71, 67, 24, 73, 5, 34, 83, 80, 245, 5, 48, 84, 192, 35, 34, 37, 89, 47, 6, 117, 47, 13, 55, 108, 89, 0, 19, 70, 76, 19, 148, 36, 17, 207, 89, 35, 50, 47, 37, 38, 6, 115, 81, 40, 0, 0, 18, 70, 60, 225, 1, 56, 180, 192, 6, 110, 50, 72, 35, 68, 49, 89, 0, 8, 0, 11, 70, 88, 84, 143, 56, 144, 193, 21, 0, 10, 0, 11, 67, 52, 145, 193, 65, 6, 37, 136, 35, 0, 17, 7, 3, 18, 15, 14, 10, 195, 169, 49, 34, 110, 50, 57, 6, 116, 0, 0, 0, 13, 202, 44, 83, 142, 37, 53, 129, 5, 33, 9, 28, 65, 15, 70, 40, 21, 207, 61, 33, 0, 57, 115, 84, 117, 34, 47, 0, 16, 70, 8, 244, 135, 20, 225, 64, 71, 110, 34, 136, 13, 50, 13, 0, 0, 10, 67, 52, 17, 192, 65, 35, 136, 0, 32, 0, 8, 67, 52, 20, 153, 21, 0, 10, 0, 0, 15, 70, 28, 84, 136, 5, 33, 0, 136, 112, 34, 35, 34, 47, 0, 0, 14, 70, 72, 82, 78, 21, 69, 5, 34, 13, 50, 108, 47, 0, 19, 70, 16, 244, 143, 80, 129, 65, 72, 110, 34, 13, 47, 6, 37, 12, 57, 35, 0, 0, 21, 72, 28, 80, 146, 60, 177, 78, 21, 32, 136, 13, 71, 34, 117, 49, 13, 50, 13, 34, 0, 0, 13, 69, 80, 84, 193, 4, 208, 47, 13, 89, 115, 65, 0, 0, 0, 16, 70, 4, 229, 8, 60, 226, 69, 35, 50, 47, 6, 117, 50, 37, 0, 12, 5, 16, 5, 18, 195, 186, 48, 13, 34, 40, 0, 0, 8, 67, 52, 146, 197, 21, 0, 10, 0, 9, 197, 60, 225, 5, 84, 112, 65, 9, 22, 73, 56, 19, 1, 80, 145, 200, 20, 145, 0, 50, 115, 55, 6, 115, 47, 13, 136, 123, 47, 0, 10, 69, 32, 148, 16, 36, 80, 21, 0, 10, 0, 0, 10, 199, 88, 243, 210, 48, 83, 148, 20, 65, 11, 70, 88, 148, 135, 36, 226, 65, 21, 0, 10, 19, 71, 40, 244, 197, 64, 130, 78, 4, 57, 117, 89, 13, 83, 6, 37, 50, 35, 0, 17, 71, 8, 194, 71, 56, 21, 76, 80, 71, 55, 109, 136, 50, 120, 47, 0, 13, 6, 18, 8, 195, 180, 14, 5, 21, 102, 114, 0, 10, 0, 22, 72, 45, 83, 147, 52, 21, 9, 28, 80, 49, 111, 50, 89, 65, 6, 115, 47, 13, 136, 13, 0, 0, 21, 73, 25, 32, 78, 76, 50, 8, 60, 82, 192, 83, 34, 133, 50, 89, 107, 6, 40, 49, 0, 0, 12, 4, 95, 3, 9, 18, 49, 6, 35, 48, 37, 0, 0, 0, 20, 72, 76, 179, 204, 48, 145, 78, 21, 48, 89, 49, 110, 55, 37, 50, 4, 108, 89, 0, 16, 70, 12, 132, 153, 76, 193, 82, 49, 34, 121, 89, 55, 13, 34, 0, 13, 68, 52, 33, 75, 36, 65, 71, 108, 12, 49, 37, 0, 0, 13, 69, 56, 20, 211, 5, 80, 50, 35, 89, 6, 120, 0, 14, 69, 8, 82, 197, 73, 48, 71, 116, 49, 13, 34, 89, 0, 0, 6, 195, 36, 34, 83, 65, 0, 21, 71, 81, 32, 80, 21, 50, 85, 52, 47, 34, 35, 48, 6, 116, 89, 37, 12, 111, 65, 0, 0, 7, 196, 60, 227, 73, 56, 65, 0, 0, 9, 198, 36, 226, 204, 84, 148, 192, 66, 16, 70, 28, 83, 133, 76, 148, 192, 136, 116, 50, 13, 89, 13, 89, 0, 16, 70, 76, 80, 213, 56, 64, 64, 89, 13, 49, 40, 50, 72, 35, 0, 0, 19, 71, 12, 132, 137, 77, 66, 78, 20, 49, 34, 13, 89, 47, 6, 37, 12, 50, 0, 0, 0, 23, 73, 17, 34, 78, 44, 80, 146, 60, 84, 128, 72, 34, 109, 50, 49, 13, 71, 34, 40, 12, 34, 0, 0, 16, 70, 24, 195, 210, 36, 64, 64, 83, 55, 110, 34, 37, 72, 35, 0, 0, 13, 4, 95, 19, 20, 11, 89, 47, 34, 6, 116, 48, 0, 0, 20, 72, 48, 145, 70, 16, 84, 208, 20, 192, 55, 37, 83, 72, 13, 89, 48, 112, 55, 0, 0, 9, 198, 80, 245, 19, 36, 83, 147, 66, 20, 73, 52, 245, 73, 48, 193, 80, 84, 229, 0, 65, 40, 55, 37, 48, 111, 50, 47, 0, 12, 4, 95, 1, 3, 21, 35, 49, 6, 118, 47, 0, 0, 18, 70, 37, 50, 193, 72, 147, 212, 37, 89, 49, 6, 35, 34, 37, 110, 47, 0, 0, 12, 201, 4, 117, 5, 73, 53, 5, 88, 243, 210, 68, 17, 70, 17, 85, 133, 56, 17, 197, 72, 118, 84, 13, 50, 115, 136, 13, 0, 0, 0, 8, 197, 88, 19, 132, 5, 64, 65, 7, 195, 76, 19, 0, 72, 32, 0, 17, 70, 16, 17, 207, 72, 65, 64, 72, 35, 136, 10, 110, 34, 72, 13, 0, 0, 0, 0, 13, 69, 32, 81, 76, 8, 240, 107, 116, 55, 71, 117, 0, 15, 69, 60, 32, 68, 40, 16, 117, 71, 6, 35, 47, 57, 35, 0, 18, 70, 48, 83, 206, 5, 33, 15, 55, 119, 12, 50, 6, 35, 34, 72, 40, 0, 0, 0, 18, 71, 12, 132, 137, 77, 66, 78, 4, 49, 34, 13, 89, 47, 37, 50, 35, 0, 13, 4, 95, 18, 14, 7, 6, 115, 50, 71, 112, 55, 0, 0, 16, 70, 60, 101, 5, 92, 83, 0, 110, 83, 47, 13, 84, 112, 55, 0, 9, 198, 32, 241, 86, 20, 83, 0, 8, 0, 13, 69, 28, 84, 148, 36, 80, 81, 109, 12, 47, 37, 0, 0, 17, 70, 9, 84, 149, 56, 66, 64, 71, 40, 34, 6, 40, 50, 72, 37, 0, 0, 20, 71, 4, 229, 8, 60, 226, 85, 76, 35, 50, 47, 6, 117, 50, 37, 38, 111, 89, 0, 21, 67, 33, 69, 16, 107, 115, 47, 116, 47, 116, 48, 6, 116, 10, 0, 81, 58, 47, 47, 32, 0, 0, 0, 17, 70, 92, 147, 8, 20, 195, 64, 84, 13, 55, 107, 112, 55, 14, 65, 0, 0, 19, 71, 44, 243, 80, 84, 196, 201, 20, 49, 110, 65, 48, 6, 111, 55, 89, 37, 0, 0, 0, 14, 69, 32, 83, 1, 5, 48, 107, 116, 55, 6, 115, 89, 0, 0, 0, 0, 0, 8, 197, 32, 84, 141, 60, 224, 65, 0, 17, 70, 36, 227, 133, 77, 65, 76, 109, 50, 50, 108, 89, 47, 13, 55, 0, 0, 9, 67, 21, 32, 64, 116, 34, 35, 0, 9, 67, 72, 19, 12, 34, 115, 55, 0, 15, 6, 7, 18, 15, 22, 195, 169, 136, 34, 40, 84, 6, 116, 0, 0, 16, 7, 5, 12, 19, 1, 2, 195, 169, 112, 55, 89, 13, 71, 37, 0, 0, 0, 15, 70, 60, 81, 9, 65, 84, 192, 117, 72, 37, 48, 111, 89, 0, 15, 70, 8, 20, 130, 5, 32, 64, 71, 115, 71, 13, 34, 35, 0, 0, 19, 71, 52, 20, 148, 32, 147, 149, 76, 65, 35, 34, 47, 6, 37, 50, 111, 89, 0, 0, 9, 68, 52, 144, 77, 36, 21, 0, 10, 0, 0, 17, 70, 28, 195, 194, 4, 193, 64, 136, 55, 117, 71, 6, 115, 55, 13, 0, 17, 4, 95, 1, 3, 50, 72, 6, 111, 71, 13, 55, 35, 49, 118, 47, 0, 0, 0, 0, 24, 73, 64, 21, 18, 36, 245, 9, 76, 209, 64, 48, 35, 47, 34, 37, 40, 47, 6, 109, 89, 65, 13, 0, 13, 69, 8, 243, 65, 5, 64, 71, 117, 65, 115, 47, 0, 0, 16, 70, 88, 84, 132, 21, 33, 64, 83, 112, 34, 72, 13, 34, 13, 0, 9, 198, 24, 18, 212, 85, 33, 64, 66, 0, 0, 11, 68, 8, 82, 68, 20, 71, 123, 72, 13, 0, 8, 196, 41, 83, 12, 20, 72, 32, 11, 70, 52, 144, 200, 4, 83, 0, 21, 0, 10, 0, 0, 16, 70, 52, 245, 15, 73, 38, 64, 65, 117, 47, 13, 34, 34, 123, 0, 0, 17, 71, 72, 80, 133, 48, 193, 69, 72, 34, 13, 71, 13, 55, 116, 34, 0, 0, 16, 70, 44, 244, 147, 92, 83, 0, 49, 110, 34, 89, 84, 13, 55, 0, 0, 13, 69, 28, 19, 132, 32, 144, 81, 35, 50, 72, 37, 0, 0, 0, 0, 17, 70, 76, 243, 143, 56, 65, 82, 89, 110, 50, 10, 110, 50, 13, 34, 0, 19, 72, 48, 18, 78, 29, 48, 149, 72, 112, 55, 123, 50, 89, 71, 111, 34, 136, 0, 0, 14, 69, 52, 20, 129, 37, 48, 65, 35, 34, 6, 108, 12, 0, 0, 0, 16, 71, 84, 149, 4, 4, 114, 78, 28, 127, 72, 115, 136, 13, 68, 0, 18, 70, 4, 193, 197, 32, 83, 5, 35, 55, 136, 13, 107, 4, 116, 55, 13, 0, 13, 70, 76, 244, 130, 60, 227, 133, 21, 102, 114, 0, 10, 0, 0, 0, 0, 0, 12, 68, 92, 147, 80, 100, 58, 109, 65, 48, 37, 0, 11, 68, 72, 85, 8, 4, 34, 116, 47, 35, 0, 15, 70, 52, 16, 199, 36, 195, 0, 65, 13, 81, 57, 37, 55, 0, 0, 14, 69, 37, 52, 129, 20, 192, 109, 89, 34, 121, 12, 55, 0, 0, 15, 70, 28, 243, 79, 73, 32, 64, 136, 13, 65, 110, 34, 35, 0, 16, 70, 76, 145, 205, 84, 225, 0, 89, 37, 81, 65, 40, 50, 47, 0, 17, 70, 48, 80, 78, 17, 32, 64, 55, 37, 6, 35, 50, 72, 34, 35, 0, 0, 10, 199, 4, 195, 5, 72, 113, 78, 20, 67, 0, 11, 68, 88, 84, 146, 20, 83, 113, 34, 13, 0, 13, 72, 52, 16, 203, 36, 229, 15, 76, 128, 21, 0, 10, 11, 68, 80, 242, 201, 60, 47, 117, 49, 119, 0, 0, 14, 69, 8, 84, 215, 36, 192, 71, 108, 89, 84, 13, 55, 0, 8, 2, 195, 151, 65, 115, 55, 0, 0, 10, 66, 77, 64, 89, 13, 50, 47, 0, 24, 0, 0, 9, 68, 41, 83, 9, 4, 21, 0, 10, 0, 0, 0, 19, 71, 33, 83, 12, 21, 49, 76, 24, 107, 111, 55, 13, 89, 112, 55, 83, 0, 32, 0, 12, 68, 88, 84, 147, 20, 83, 113, 34, 89, 13, 0, 12, 68, 20, 226, 71, 20, 116, 50, 109, 136, 13, 0, 14, 68, 56, 19, 205, 36, 50, 35, 10, 6, 117, 65, 37, 0, 0, 12, 2, 194, 167, 35, 83, 72, 116, 55, 13, 68, 0, 0, 17, 70, 88, 18, 193, 57, 65, 64, 83, 2, 35, 49, 35, 50, 47, 13, 0, 10, 66, 76, 80, 108, 89, 13, 0, 41, 9, 6, 194, 60, 208, 72, 12, 13, 2, 194, 164, 65, 111, 50, 47, 116, 49, 13, 50, 0, 0, 10, 198, 60, 225, 5, 84, 113, 5, 65, 9, 8, 2, 194, 165, 57, 108, 50, 0, 0, 13, 68, 60, 225, 69, 72, 110, 50, 10, 116, 34, 0, 9, 12, 68, 8, 82, 193, 24, 71, 112, 49, 35, 83, 0, 16, 3, 5, 46, 1, 9, 108, 50, 10, 6, 35, 50, 72, 13, 34, 0, 0, 12, 69, 52, 81, 71, 20, 80, 65, 116, 136, 116, 0, 13, 69, 44, 230, 83, 56, 16, 50, 123, 89, 50, 35, 0, 9, 2, 194, 163, 48, 131, 50, 47, 0, 0, 0, 12, 201, 77, 113, 84, 80, 84, 138, 60, 83, 0, 67, 18, 71, 5, 52, 197, 8, 194, 69, 24, 35, 89, 13, 71, 55, 6, 37, 83, 0, 19, 70, 49, 80, 210, 21, 66, 65, 55, 40, 49, 34, 6, 37, 12, 91, 57, 35, 0, 20, 71, 8, 20, 131, 20, 195, 206, 4, 71, 35, 34, 89, 13, 55, 6, 117, 50, 35, 0, 0, 12, 68, 88, 84, 148, 20, 83, 112, 34, 47, 13, 0, 12, 68, 80, 84, 149, 28, 47, 14, 34, 111, 136, 0, 7, 196, 64, 20, 148, 20, 65, 17, 7, 3, 12, 9, 3, 8, 195, 169, 49, 55, 37, 91, 6, 123, 12, 0, 0, 0, 15, 70, 24, 84, 146, 5, 34, 64, 83, 13, 34, 115, 34, 37, 0, 5, 130, 195, 164, 43, 0, 19, 71, 16, 21, 201, 17, 53, 5, 72, 72, 115, 84, 13, 47, 89, 47, 112, 34, 0, 20, 71, 81, 32, 70, 4, 193, 193, 72, 47, 34, 35, 83, 6, 35, 55, 81, 35, 34, 0, 0, 21, 72, 64, 85, 18, 60, 225, 76, 48, 16, 48, 116, 47, 34, 40, 50, 6, 112, 55, 35, 0, 15, 7, 6, 15, 21, 3, 8, 195, 169, 83, 40, 91, 6, 116, 0, 12, 68, 12, 80, 201, 48, 89, 108, 89, 13, 55, 0, 9, 68, 56, 145, 197, 48, 21, 0, 10, 0, 0, 18, 70, 76, 192, 80, 5, 35, 64, 89, 55, 35, 48, 10, 35, 34, 14, 65, 0, 25, 2, 195, 160, 35, 15, 55, 35, 15, 49, 6, 35, 34, 47, 0, 82, 108, 97, 32, 99, 97, 114, 116, 101, 32, 6, 130, 195, 160, 43, 14, 0, 13, 2, 194, 169, 49, 40, 48, 6, 37, 34, 112, 136, 0, 5, 130, 195, 161, 43, 0, 18, 70, 32, 245, 1, 29, 65, 82, 107, 110, 47, 10, 35, 136, 47, 13, 34, 0, 18, 70, 16, 85, 133, 57, 65, 82, 72, 6, 116, 84, 13, 50, 47, 13, 34, 0, 13, 2, 194, 182, 48, 35, 34, 35, 136, 34, 115, 83, 0, 0, 5, 130, 195, 175, 43, 0, 5, 130, 195, 172, 43, 0, 9, 67, 88, 144, 64, 84, 37, 35, 0, 10, 2, 194, 181, 65, 37, 49, 34, 40, 0, 5, 130, 195, 173, 43, 0, 12, 68, 8, 82, 197, 72, 71, 116, 49, 13, 34, 0, 10, 68, 12, 128, 82, 48, 91, 115, 55, 0, 18, 72, 76, 86, 67, 32, 83, 12, 21, 48, 89, 123, 91, 6, 112, 55, 88, 0, 5, 130, 195, 170, 43, 0, 5, 130, 195, 171, 43, 0, 10, 2, 194, 176, 136, 34, 115, 72, 13, 0, 5, 130, 195, 168, 43, 0, 17, 2, 194, 177, 48, 55, 111, 89, 10, 110, 83, 65, 37, 50, 111, 89, 0, 5, 130, 195, 169, 43, 0, 13, 2, 194, 190, 72, 34, 37, 49, 58, 35, 34, 47, 0, 5, 130, 195, 182, 43, 0, 10, 69, 32, 245, 193, 72, 64, 21, 0, 10, 8, 197, 20, 195, 73, 20, 224, 66, 10, 69, 16, 20, 151, 36, 224, 21, 0, 10, 13, 2, 195, 183, 136, 13, 72, 116, 55, 72, 128, 34, 0, 0, 16, 70, 56, 241, 197, 20, 228, 192, 50, 110, 136, 10, 116, 50, 89, 0, 15, 70, 72, 80, 133, 44, 176, 64, 34, 13, 71, 108, 49, 35, 0, 11, 2, 194, 188, 13, 49, 58, 35, 34, 47, 0, 5, 130, 195, 180, 43, 0, 28, 67, 56, 145, 64, 50, 4, 37, 15, 84, 4, 115, 34, 15, 50, 6, 37, 0, 82, 119, 97, 97, 114, 32, 110, 105, 101, 32, 7, 195, 56, 145, 64, 13, 40, 11, 2, 194, 189, 13, 107, 35, 55, 84, 13, 0, 0, 11, 200, 76, 81, 5, 73, 65, 9, 20, 224, 67, 13, 4, 95, 3, 5, 4, 89, 13, 72, 109, 55, 35, 0, 5, 130, 195, 178, 43, 0, 13, 70, 28, 241, 66, 8, 83, 19, 21, 100, 101, 0, 10, 5, 130, 195, 179, 43, 0, 16, 70, 5, 97, 82, 76, 145, 64, 35, 84, 6, 112, 34, 89, 37, 0, 16, 70, 88, 148, 193, 28, 145, 64, 83, 37, 89, 6, 115, 136, 37, 0, 15, 70, 52, 20, 133, 48, 145, 64, 65, 35, 34, 13, 55, 37, 0, 0, 18, 4, 95, 12, 9, 7, 72, 6, 111, 71, 13, 55, 55, 108, 47, 13, 34, 0, 0, 9, 68, 12, 192, 82, 44, 21, 0, 10, 17, 70, 76, 19, 22, 4, 67, 210, 89, 35, 55, 84, 35, 72, 131, 34, 0, 0, 21, 67, 80, 83, 0, 47, 112, 55, 15, 35, 84, 6, 37, 84, 0, 81, 97, 118, 105, 118, 32, 0, 14, 70, 88, 243, 210, 28, 81, 64, 83, 117, 34, 136, 116, 0, 8, 66, 80, 80, 47, 13, 0, 32, 15, 70, 12, 241, 84, 104, 81, 64, 49, 40, 47, 89, 6, 116, 0, 21, 73, 40, 81, 134, 72, 86, 83, 8, 16, 73, 75, 108, 83, 34, 37, 89, 71, 6, 122, 0, 5, 130, 195, 188, 43, 0, 5, 130, 195, 189, 43, 0, 8, 196, 33, 83, 12, 20, 72, 32, 9, 68, 72, 241, 197, 72, 21, 0, 10, 13, 68, 48, 80, 78, 4, 55, 37, 6, 115, 50, 35, 0, 5, 130, 195, 186, 43, 0, 21, 73, 72, 83, 129, 37, 52, 193, 56, 49, 64, 34, 108, 50, 13, 89, 6, 133, 50, 89, 0, 8, 197, 60, 225, 197, 4, 112, 65, 14, 69, 32, 145, 82, 76, 240, 107, 37, 12, 34, 89, 110, 0, 15, 69, 12, 194, 86, 36, 16, 49, 55, 109, 84, 37, 57, 35, 0, 10, 69, 28, 83, 210, 28, 80, 21, 0, 10, 12, 69, 9, 32, 72, 4, 208, 71, 34, 115, 65, 0, 14, 69, 56, 147, 133, 88, 80, 50, 109, 50, 13, 83, 37, 0, 5, 130, 195, 187, 43, 0, 15, 70, 85, 37, 71, 84, 22, 64, 40, 34, 40, 81, 58, 121, 0, 0, 5, 130, 195, 185, 43, 0, 7, 196, 92, 18, 201, 76, 65, 12, 68, 12, 130, 78, 4, 91, 6, 37, 50, 35, 0, 0, 14, 69, 40, 19, 137, 56, 80, 75, 13, 50, 37, 12, 50, 0, 13, 69, 8, 85, 10, 36, 80, 71, 108, 37, 80, 37, 0, 15, 69, 4, 192, 83, 44, 16, 35, 55, 6, 35, 89, 49, 35, 0, 0, 9, 198, 72, 147, 139, 36, 226, 192, 66, 0, 18, 71, 17, 80, 130, 20, 194, 197, 56, 72, 111, 71, 13, 55, 49, 108, 50, 0, 0, 0, 16, 69, 21, 131, 196, 85, 48, 108, 49, 89, 6, 117, 72, 111, 89, 0, 0, 0, 18, 70, 60, 179, 1, 32, 243, 65, 120, 49, 55, 13, 107, 6, 120, 65, 35, 0, 0, 0, 18, 70, 64, 147, 143, 44, 178, 79, 48, 37, 50, 6, 110, 49, 37, 38, 40, 0, 0, 0, 0, 12, 68, 92, 21, 23, 60, 84, 35, 47, 84, 117, 0, 10, 67, 4, 36, 193, 35, 71, 89, 35, 0, 0, 9, 4, 95, 35, 4, 5, 72, 13, 0, 0, 0, 11, 67, 60, 228, 192, 135, 50, 89, 0, 72, 32, 0, 12, 68, 52, 245, 15, 72, 65, 117, 47, 13, 34, 0, 19, 72, 8, 18, 78, 76, 179, 15, 60, 96, 71, 123, 50, 89, 49, 55, 117, 83, 0, 0, 17, 70, 72, 85, 15, 72, 145, 75, 34, 13, 47, 40, 34, 6, 37, 49, 0, 25, 73, 52, 83, 79, 72, 16, 137, 48, 144, 64, 65, 108, 65, 110, 34, 35, 71, 6, 37, 55, 37, 57, 35, 0, 0, 10, 66, 81, 96, 47, 116, 83, 116, 10, 0, 0, 7, 195, 76, 245, 64, 72, 32, 0, 10, 67, 49, 83, 21, 55, 40, 55, 40, 0, 9, 68, 40, 147, 77, 100, 21, 0, 10, 0, 14, 69, 73, 84, 5, 73, 64, 34, 40, 48, 13, 34, 47, 0, 0, 9, 198, 88, 243, 19, 64, 241, 68, 65, 0, 7, 195, 92, 245, 64, 72, 32, 0, 9, 198, 60, 225, 197, 72, 145, 70, 65, 12, 68, 20, 97, 83, 20, 116, 83, 13, 89, 13, 0, 0, 20, 73, 32, 19, 132, 80, 84, 148, 40, 145, 64, 107, 35, 50, 47, 113, 34, 80, 37, 0, 11, 69, 88, 147, 204, 21, 64, 21, 0, 41, 10, 13, 69, 12, 17, 83, 5, 32, 89, 37, 88, 13, 34, 0, 0, 17, 70, 76, 147, 135, 20, 227, 212, 89, 109, 50, 136, 13, 50, 110, 47, 0, 9, 198, 56, 17, 5, 56, 177, 64, 65, 0, 0, 20, 9, 22, 18, 15, 5, 195, 171, 18, 9, 7, 83, 34, 40, 12, 13, 34, 13, 136, 0, 7, 196, 60, 228, 149, 76, 65, 12, 68, 32, 241, 82, 4, 107, 40, 34, 6, 115, 0, 14, 68, 16, 144, 78, 4, 72, 37, 57, 6, 115, 50, 35, 0, 0, 8, 197, 32, 241, 75, 60, 208, 8, 0, 0, 6, 195, 92, 21, 0, 8, 0, 20, 72, 64, 146, 193, 56, 145, 78, 36, 80, 48, 37, 49, 35, 50, 6, 37, 50, 37, 0, 13, 68, 4, 224, 76, 20, 35, 50, 6, 115, 55, 13, 0, 13, 68, 20, 192, 78, 4, 37, 55, 6, 115, 50, 35, 0, 0, 14, 69, 88, 84, 151, 20, 112, 83, 113, 34, 84, 112, 136, 0, 16, 70, 8, 16, 133, 48, 16, 83, 71, 35, 71, 13, 55, 115, 89, 0, 12, 69, 52, 84, 129, 4, 144, 65, 13, 34, 122, 0, 0, 23, 66, 77, 144, 89, 4, 123, 15, 35, 50, 15, 89, 6, 123, 0, 82, 97, 97, 110, 32, 115, 121, 32, 6, 194, 77, 144, 72, 32, 15, 70, 65, 33, 83, 48, 86, 64, 48, 34, 108, 89, 55, 37, 0, 0, 18, 71, 72, 17, 5, 52, 86, 69, 72, 34, 115, 72, 13, 65, 123, 13, 34, 0, 6, 2, 95, 1, 115, 0, 0, 9, 198, 88, 243, 210, 44, 81, 82, 65, 19, 72, 88, 84, 133, 17, 82, 70, 36, 80, 83, 116, 34, 13, 72, 127, 83, 37, 0, 11, 200, 77, 113, 76, 48, 83, 132, 4, 208, 67, 0, 23, 73, 28, 83, 5, 72, 83, 132, 32, 82, 68, 136, 13, 55, 116, 34, 13, 50, 47, 107, 123, 47, 0, 0, 0, 18, 71, 8, 244, 132, 20, 115, 197, 16, 71, 131, 34, 72, 13, 136, 40, 47, 0, 27, 12, 13, 5, 19, 15, 16, 15, 20, 1, 13, 9, 195, 171, 65, 108, 89, 40, 48, 40, 47, 6, 115, 65, 37, 13, 0, 0, 0, 13, 69, 8, 86, 69, 73, 48, 71, 123, 13, 34, 89, 0, 0, 9, 198, 60, 225, 197, 17, 83, 4, 65, 17, 70, 76, 84, 207, 80, 131, 192, 89, 13, 89, 6, 40, 12, 47, 40, 0, 0, 0, 0, 12, 68, 64, 21, 15, 76, 48, 115, 47, 110, 89, 0, 0, 9, 3, 7, 39, 14, 136, 109, 50, 0, 0, 9, 198, 60, 244, 130, 60, 244, 132, 66, 0, 19, 71, 20, 194, 83, 4, 33, 84, 32, 37, 55, 6, 37, 89, 35, 71, 108, 47, 0, 11, 67, 45, 112, 64, 49, 58, 35, 0, 72, 9, 0, 7, 196, 60, 227, 65, 28, 65, 0, 14, 69, 32, 241, 87, 20, 192, 107, 40, 84, 6, 112, 55, 0, 0, 21, 9, 22, 5, 18, 7, 5, 12, 5, 195, 171, 83, 113, 34, 136, 13, 55, 4, 116, 13, 0, 16, 70, 56, 20, 208, 21, 36, 192, 50, 35, 89, 48, 112, 34, 89, 0, 0, 19, 71, 80, 147, 79, 80, 129, 85, 76, 47, 13, 65, 6, 117, 47, 37, 111, 89, 0, 14, 71, 8, 240, 195, 4, 48, 201, 60, 21, 105, 116, 0, 10, 0, 0, 13, 69, 24, 145, 213, 85, 32, 83, 13, 136, 118, 34, 0, 6, 2, 95, 21, 118, 0, 0, 17, 70, 64, 83, 143, 72, 83, 148, 48, 108, 50, 117, 34, 108, 50, 47, 0, 17, 70, 44, 243, 139, 5, 113, 64, 49, 110, 50, 49, 6, 115, 84, 13, 0, 31, 76, 72, 149, 137, 21, 36, 207, 56, 65, 82, 20, 225, 0, 34, 13, 83, 37, 12, 34, 89, 110, 50, 13, 34, 10, 6, 108, 50, 47, 0, 0, 18, 70, 4, 48, 80, 84, 192, 207, 35, 49, 35, 48, 6, 40, 55, 49, 120, 0, 0, 0, 9, 198, 88, 243, 16, 84, 229, 5, 65, 0, 0, 9, 198, 32, 84, 139, 48, 16, 83, 65, 19, 70, 8, 80, 84, 72, 150, 0, 71, 37, 38, 6, 115, 47, 34, 13, 49, 89, 0, 12, 67, 9, 2, 192, 71, 13, 48, 112, 34, 49, 0, 0, 16, 70, 80, 241, 82, 20, 177, 78, 47, 40, 34, 116, 49, 13, 50, 0, 30, 76, 80, 129, 83, 76, 19, 15, 56, 144, 197, 57, 49, 64, 47, 108, 89, 35, 55, 117, 50, 37, 89, 6, 108, 12, 50, 89, 13, 0, 0, 15, 69, 64, 20, 129, 80, 80, 48, 35, 34, 6, 115, 47, 13, 0, 12, 69, 32, 242, 193, 4, 144, 107, 110, 49, 122, 0, 0, 17, 70, 16, 80, 149, 77, 54, 64, 72, 13, 71, 40, 89, 6, 37, 12, 0, 0, 0, 10, 135, 20, 5, 18, 4, 5, 195, 171, 66, 10, 68, 60, 244, 146, 100, 117, 34, 123, 0, 11, 2, 95, 34, 107, 115, 55, 23, 115, 50, 0, 0, 14, 69, 52, 147, 149, 80, 80, 65, 13, 50, 118, 47, 13, 0, 14, 69, 4, 98, 197, 72, 80, 35, 83, 49, 116, 34, 13, 0, 13, 69, 101, 99, 206, 56, 80, 37, 84, 6, 110, 50, 0, 13, 69, 64, 131, 197, 8, 80, 83, 37, 12, 71, 37, 0, 13, 69, 60, 229, 15, 56, 112, 110, 50, 47, 110, 68, 0, 24, 73, 88, 19, 146, 33, 147, 147, 16, 244, 144, 83, 35, 50, 34, 6, 123, 50, 89, 72, 110, 34, 48, 0, 0, 9, 66, 89, 80, 21, 102, 114, 0, 10, 0, 8, 195, 44, 243, 128, 72, 11, 32, 17, 70, 16, 19, 65, 76, 181, 83, 72, 13, 65, 35, 89, 49, 111, 89, 0, 8, 2, 95, 39, 47, 37, 49, 0, 0, 21, 72, 76, 19, 69, 48, 85, 201, 56, 112, 89, 115, 65, 13, 55, 4, 116, 84, 13, 68, 0, 20, 72, 64, 242, 78, 76, 85, 20, 36, 16, 48, 124, 50, 89, 6, 108, 47, 37, 35, 0, 20, 72, 52, 20, 135, 84, 84, 137, 80, 80, 65, 115, 81, 13, 34, 6, 37, 12, 47, 0, 0, 0, 15, 70, 77, 65, 80, 32, 19, 128, 89, 47, 116, 83, 35, 50, 0, 8, 67, 40, 19, 133, 21, 0, 10, 16, 70, 4, 68, 137, 4, 19, 128, 115, 72, 34, 37, 57, 35, 50, 0, 0, 6, 195, 88, 19, 128, 72, 0, 17, 70, 36, 115, 143, 72, 81, 82, 37, 136, 50, 117, 34, 6, 116, 34, 0, 6, 195, 37, 50, 83, 65, 16, 4, 95, 3, 1, 16, 107, 6, 117, 83, 55, 108, 47, 13, 34, 0, 0, 14, 69, 80, 19, 135, 5, 48, 47, 35, 68, 81, 35, 89, 0, 13, 69, 88, 84, 151, 21, 144, 83, 13, 34, 84, 123, 0, 27, 69, 9, 81, 78, 61, 48, 71, 58, 108, 50, 110, 89, 10, 6, 121, 34, 108, 89, 0, 81, 97, 105, 114, 101, 115, 32, 13, 2, 95, 41, 34, 112, 136, 89, 107, 35, 49, 37, 0, 0, 16, 70, 48, 147, 80, 61, 3, 192, 55, 13, 65, 48, 117, 48, 117, 0, 16, 70, 12, 19, 5, 16, 243, 128, 49, 35, 55, 37, 72, 110, 50, 0, 13, 2, 95, 40, 55, 109, 68, 89, 107, 35, 49, 37, 0, 0, 10, 67, 64, 84, 128, 48, 13, 34, 0, 9, 6, 195, 88, 148, 128, 72, 7, 195, 92, 244, 132, 72, 32, 0, 16, 70, 80, 83, 5, 52, 19, 142, 47, 116, 55, 13, 65, 35, 50, 0, 0, 24, 73, 64, 19, 132, 20, 211, 206, 37, 83, 64, 48, 35, 50, 72, 13, 65, 6, 117, 50, 37, 111, 65, 0, 15, 2, 95, 45, 49, 110, 48, 13, 55, 47, 116, 49, 13, 50, 0, 0, 10, 67, 32, 84, 133, 107, 116, 34, 13, 0, 10, 67, 48, 85, 137, 55, 116, 83, 37, 0, 9, 2, 95, 44, 49, 110, 65, 35, 0, 0, 19, 71, 12, 19, 69, 52, 33, 82, 80, 49, 35, 65, 13, 65, 71, 6, 113, 34, 0, 9, 67, 16, 84, 128, 72, 13, 34, 0, 9, 2, 95, 51, 6, 72, 34, 37, 0, 0, 12, 68, 80, 133, 76, 4, 47, 40, 12, 55, 35, 0, 12, 68, 76, 18, 78, 80, 89, 109, 50, 47, 0, 72, 9, 2, 95, 50, 6, 47, 58, 116, 0, 0, 13, 69, 44, 243, 65, 4, 224, 49, 110, 65, 115, 50, 0, 8, 197, 52, 147, 1, 4, 224, 66, 9, 2, 95, 49, 10, 6, 116, 50, 0, 0, 10, 67, 88, 149, 129, 84, 37, 84, 35, 0, 16, 70, 41, 84, 9, 80, 84, 128, 57, 40, 48, 37, 47, 13, 34, 0, 9, 2, 95, 48, 6, 50, 111, 55, 0, 0, 18, 71, 28, 85, 129, 48, 193, 78, 20, 136, 13, 83, 35, 55, 13, 50, 13, 0, 10, 2, 95, 55, 6, 89, 116, 84, 13, 0, 0, 21, 72, 8, 19, 135, 48, 17, 5, 76, 160, 71, 35, 68, 81, 55, 35, 72, 6, 108, 91, 0, 9, 2, 95, 54, 6, 89, 108, 89, 0, 0, 14, 69, 52, 84, 140, 61, 64, 65, 112, 34, 55, 6, 117, 0, 9, 2, 95, 53, 6, 83, 123, 83, 0, 0, 15, 70, 20, 97, 133, 57, 49, 64, 108, 83, 13, 50, 89, 13, 0, 17, 70, 52, 20, 140, 37, 49, 64, 65, 35, 34, 55, 6, 37, 12, 89, 0, 24, 11, 7, 5, 20, 19, 195, 169, 13, 1, 14, 195, 169, 136, 108, 47, 89, 6, 116, 65, 35, 50, 37, 0, 10, 2, 95, 52, 6, 83, 37, 12, 34, 0, 0, 13, 2, 95, 59, 49, 110, 65, 35, 48, 111, 50, 47, 0, 0, 15, 70, 40, 245, 66, 21, 37, 0, 57, 40, 71, 6, 113, 34, 0, 14, 2, 95, 58, 72, 111, 71, 13, 55, 48, 111, 50, 47, 0, 0, 13, 69, 52, 147, 149, 85, 64, 65, 13, 50, 118, 47, 0, 10, 2, 95, 57, 6, 50, 116, 136, 13, 0, 0, 10, 2, 95, 56, 10, 6, 35, 136, 47, 0, 0, 15, 70, 12, 147, 12, 36, 84, 147, 89, 109, 55, 57, 6, 116, 0, 15, 70, 12, 83, 12, 36, 84, 147, 89, 109, 55, 57, 6, 116, 0, 16, 70, 88, 147, 12, 36, 84, 147, 84, 109, 55, 37, 13, 34, 89, 0, 14, 2, 95, 63, 83, 34, 115, 136, 47, 116, 49, 13, 50, 0, 0, 14, 2, 95, 62, 136, 34, 117, 47, 13, 34, 23, 35, 89, 0, 0, 14, 69, 76, 19, 15, 52, 240, 89, 115, 55, 13, 65, 117, 0, 14, 69, 52, 148, 137, 4, 208, 65, 109, 34, 37, 13, 65, 0, 15, 69, 28, 64, 78, 76, 176, 81, 14, 72, 35, 50, 89, 49, 0, 0, 14, 2, 95, 60, 49, 55, 123, 50, 13, 34, 23, 35, 89, 0, 0, 18, 71, 9, 34, 69, 92, 83, 69, 76, 71, 34, 37, 84, 13, 65, 108, 89, 0, 0, 21, 72, 88, 84, 139, 20, 84, 132, 60, 208, 83, 13, 34, 49, 116, 34, 47, 10, 110, 65, 0, 9, 198, 88, 243, 210, 16, 21, 0, 8, 18, 8, 5, 19, 5, 7, 9, 195, 171, 12, 37, 89, 6, 116, 136, 37, 12, 0, 21, 72, 20, 211, 65, 72, 83, 148, 36, 16, 108, 65, 35, 34, 6, 134, 50, 91, 57, 35, 0, 0, 15, 69, 76, 19, 21, 80, 80, 89, 35, 55, 6, 118, 47, 13, 0, 14, 69, 48, 81, 193, 80, 80, 55, 13, 136, 115, 47, 13, 0, 15, 69, 16, 82, 193, 16, 80, 72, 108, 49, 6, 115, 72, 13, 0, 16, 69, 76, 244, 8, 36, 16, 89, 40, 83, 6, 37, 12, 57, 35, 0, 17, 70, 76, 19, 4, 4, 226, 1, 89, 35, 55, 72, 6, 35, 50, 35, 0, 0, 0, 17, 70, 17, 82, 84, 77, 113, 83, 72, 127, 47, 89, 84, 6, 108, 89, 0, 0, 21, 72, 16, 148, 12, 60, 208, 83, 36, 80, 72, 13, 48, 55, 117, 65, 35, 89, 6, 37, 0, 9, 68, 13, 148, 137, 48, 21, 0, 10, 0, 14, 69, 52, 20, 137, 85, 48, 65, 115, 34, 37, 111, 89, 0, 13, 69, 48, 85, 201, 21, 48, 55, 13, 84, 37, 89, 0, 0, 9, 198, 52, 148, 203, 36, 83, 128, 66, 15, 70, 12, 132, 137, 77, 67, 192, 49, 34, 109, 89, 47, 40, 0, 0, 0, 11, 68, 52, 16, 200, 60, 65, 35, 76, 120, 0, 16, 70, 12, 132, 137, 77, 67, 198, 49, 34, 109, 89, 47, 110, 83, 0, 0, 18, 70, 73, 147, 69, 48, 20, 153, 34, 123, 65, 13, 55, 35, 34, 6, 123, 0, 15, 70, 52, 144, 200, 20, 195, 5, 65, 37, 91, 6, 112, 55, 0, 18, 70, 12, 20, 143, 48, 147, 129, 49, 35, 34, 40, 55, 6, 37, 50, 35, 0, 0, 16, 70, 4, 195, 5, 29, 35, 192, 35, 55, 6, 108, 81, 34, 40, 0, 17, 70, 8, 244, 143, 16, 147, 128, 71, 110, 34, 40, 72, 6, 37, 50, 0, 16, 4, 194, 182, 194, 182, 48, 35, 34, 35, 136, 34, 115, 84, 13, 0, 0, 0, 11, 70, 88, 147, 131, 20, 229, 0, 21, 0, 10, 12, 5, 18, 5, 14, 195, 169, 34, 13, 50, 123, 0, 12, 68, 40, 244, 197, 24, 57, 117, 89, 13, 83, 0, 0, 15, 204, 92, 81, 82, 88, 243, 210, 77, 1, 76, 48, 147, 135, 65, 9, 198, 12, 243, 134, 21, 69, 9, 66, 10, 69, 28, 244, 132, 60, 224, 21, 0, 10, 0, 12, 137, 15, 14, 22, 5, 18, 13, 15, 195, 171, 65, 15, 70, 56, 146, 204, 4, 20, 192, 50, 37, 49, 55, 115, 89, 0, 0, 19, 71, 4, 229, 23, 21, 36, 5, 56, 35, 50, 47, 84, 112, 34, 48, 13, 50, 0, 0, 6, 195, 76, 243, 211, 72, 6, 195, 76, 243, 211, 8, 18, 8, 7, 1, 2, 18, 9, 195, 171, 12, 136, 115, 71, 34, 37, 13, 55, 0, 11, 5, 95, 35, 19, 20, 5, 89, 47, 13, 0, 0, 10, 69, 9, 84, 148, 60, 224, 21, 0, 10, 10, 69, 4, 193, 146, 20, 64, 21, 0, 10, 17, 70, 44, 147, 147, 32, 20, 193, 49, 37, 50, 91, 6, 115, 89, 35, 0, 0, 9, 198, 4, 229, 1, 72, 84, 192, 66, 15, 70, 76, 84, 150, 4, 20, 192, 89, 13, 34, 83, 115, 89, 0, 22, 73, 52, 243, 210, 72, 81, 83, 9, 84, 135, 65, 40, 34, 6, 116, 89, 71, 111, 34, 136, 0, 0, 0, 11, 70, 72, 144, 200, 5, 33, 0, 21, 0, 10, 12, 4, 95, 4, 15, 20, 48, 6, 111, 50, 47, 0, 0, 14, 69, 80, 245, 4, 5, 64, 47, 110, 72, 35, 47, 0, 8, 0, 9, 198, 60, 226, 213, 56, 65, 64, 65, 6, 195, 36, 65, 69, 66, 17, 70, 100, 243, 1, 56, 65, 64, 57, 40, 55, 6, 35, 50, 72, 13, 0, 10, 67, 4, 64, 77, 35, 72, 35, 65, 0, 0, 17, 71, 64, 192, 65, 76, 160, 65, 64, 48, 55, 115, 89, 57, 115, 48, 0, 18, 2, 95, 91, 55, 109, 68, 89, 15, 71, 55, 110, 49, 107, 35, 49, 37, 0, 0, 7, 196, 88, 84, 141, 100, 66, 11, 68, 32, 82, 203, 20, 107, 112, 49, 13, 0, 0, 17, 70, 64, 147, 143, 80, 17, 197, 48, 37, 50, 40, 47, 6, 115, 90, 0, 13, 69, 72, 82, 78, 21, 64, 34, 13, 50, 108, 47, 0, 15, 69, 52, 246, 129, 73, 64, 65, 117, 47, 89, 35, 34, 47, 0, 0, 17, 70, 45, 112, 90, 84, 197, 64, 49, 58, 35, 88, 6, 40, 55, 40, 0, 0, 9, 67, 32, 82, 192, 107, 112, 49, 0, 8, 2, 95, 95, 55, 123, 50, 0, 0, 9, 68, 40, 19, 69, 76, 21, 0, 10, 0, 22, 73, 88, 84, 146, 20, 112, 65, 56, 65, 64, 83, 112, 34, 13, 136, 6, 115, 50, 72, 13, 0, 15, 69, 76, 240, 133, 72, 80, 89, 6, 117, 71, 13, 34, 13, 0, 8, 197, 56, 19, 65, 80, 80, 66, 13, 69, 81, 37, 68, 36, 80, 47, 34, 40, 72, 37, 0, 9, 198, 12, 243, 146, 4, 66, 69, 66, 18, 2, 95, 93, 34, 112, 136, 89, 15, 71, 55, 110, 49, 107, 35, 49, 37, 0, 0, 16, 70, 45, 34, 84, 36, 82, 192, 49, 34, 109, 47, 6, 37, 49, 0, 8, 67, 28, 243, 201, 136, 124, 0, 18, 70, 4, 194, 15, 21, 113, 76, 35, 55, 107, 40, 84, 6, 112, 55, 0, 8, 0, 10, 199, 8, 20, 146, 36, 176, 68, 20, 67, 6, 195, 24, 18, 192, 17, 0, 12, 201, 92, 16, 82, 76, 182, 78, 48, 146, 197, 66, 13, 68, 20, 194, 84, 20, 37, 55, 6, 37, 12, 47, 0, 0, 8, 197, 81, 84, 139, 100, 80, 66, 0, 15, 70, 49, 146, 215, 4, 18, 192, 55, 123, 49, 84, 115, 49, 0, 9, 198, 28, 245, 68, 36, 226, 64, 66, 0, 12, 201, 36, 229, 5, 57, 50, 84, 20, 149, 0, 68, 18, 71, 28, 16, 78, 16, 85, 197, 28, 136, 115, 50, 72, 13, 84, 112, 136, 0, 0, 22, 72, 76, 241, 197, 56, 16, 77, 16, 80, 89, 6, 117, 136, 13, 50, 4, 115, 65, 72, 13, 0, 10, 67, 40, 16, 207, 57, 35, 49, 40, 0, 0, 12, 201, 92, 16, 82, 76, 182, 78, 48, 146, 192, 66, 6, 195, 37, 48, 142, 17, 0, 0, 20, 9, 195, 170, 18, 5, 14, 19, 20, 5, 18, 113, 34, 13, 50, 89, 47, 13, 34, 0, 0, 22, 72, 61, 32, 78, 40, 84, 5, 73, 48, 117, 34, 6, 35, 50, 57, 13, 48, 113, 34, 89, 0, 0, 0, 26, 74, 16, 85, 84, 21, 35, 206, 60, 210, 85, 52, 72, 128, 47, 13, 34, 117, 50, 6, 117, 65, 37, 111, 65, 0, 14, 4, 95, 7, 18, 22, 136, 34, 35, 83, 6, 109, 89, 0, 0, 9, 67, 20, 180, 192, 108, 49, 89, 0, 0, 0, 0, 16, 70, 36, 226, 193, 80, 128, 64, 37, 68, 49, 6, 115, 47, 35, 0, 9, 198, 24, 147, 129, 48, 148, 192, 67, 0, 0, 9, 68, 48, 85, 201, 76, 21, 0, 10, 12, 68, 36, 36, 197, 56, 37, 71, 89, 13, 50, 0, 0, 0, 0, 0, 13, 67, 20, 67, 83, 123, 13, 50, 72, 110, 65, 89, 0, 0, 0, 16, 70, 80, 85, 146, 20, 65, 64, 47, 13, 83, 34, 116, 72, 13, 0, 0, 9, 195, 92, 147, 0, 72, 11, 9, 32, 18, 2, 95, 123, 55, 109, 68, 89, 15, 49, 34, 111, 55, 107, 35, 49, 37, 0, 16, 4, 95, 4, 9, 1, 72, 6, 116, 55, 47, 116, 49, 13, 50, 0, 0, 7, 196, 4, 226, 77, 4, 65, 0, 15, 69, 9, 37, 87, 21, 32, 71, 34, 40, 58, 6, 113, 34, 0, 0, 16, 70, 77, 69, 75, 72, 17, 192, 89, 47, 118, 49, 34, 35, 136, 0, 15, 70, 77, 86, 129, 56, 225, 64, 89, 40, 88, 6, 115, 50, 0, 11, 70, 12, 20, 140, 100, 193, 64, 21, 0, 10, 0, 19, 71, 32, 148, 143, 76, 162, 77, 4, 107, 37, 34, 40, 91, 6, 37, 65, 35, 0, 0, 0, 23, 73, 48, 16, 149, 76, 50, 1, 28, 225, 64, 55, 35, 71, 111, 89, 49, 6, 35, 136, 50, 37, 0, 15, 69, 21, 81, 197, 56, 80, 57, 40, 75, 6, 37, 12, 50, 0, 18, 2, 95, 125, 34, 112, 136, 89, 15, 49, 34, 111, 55, 107, 35, 49, 37, 0, 0, 12, 2, 95, 124, 35, 83, 89, 47, 34, 116, 48, 0, 0, 0, 11, 200, 92, 83, 148, 4, 181, 9, 20, 176, 65, 0, 8, 197, 60, 225, 9, 56, 112, 65, 10, 69, 76, 244, 8, 36, 80, 21, 0, 10, 0, 11, 70, 64, 21, 18, 36, 50, 192, 21, 0, 10, 0, 0, 11, 70, 9, 35, 207, 44, 198, 78, 21, 0, 10, 0, 0, 0, 17, 71, 52, 245, 15, 73, 66, 137, 20, 65, 117, 47, 13, 34, 49, 37, 0, 12, 71, 48, 240, 203, 21, 32, 137, 20, 21, 0, 10, 0, 0, 13, 69, 92, 21, 23, 61, 80, 84, 35, 47, 84, 120, 0, 0, 17, 70, 12, 16, 133, 72, 225, 84, 49, 35, 71, 13, 34, 50, 6, 123, 0, 0, 18, 71, 16, 82, 210, 20, 194, 78, 28, 72, 108, 49, 34, 116, 55, 13, 68, 0, 0, 13, 70, 76, 50, 13, 36, 69, 0, 91, 65, 37, 47, 0, 0, 0, 18, 70, 52, 19, 132, 20, 192, 64, 65, 35, 50, 72, 6, 108, 12, 55, 35, 0, 0, 0, 0, 0, 17, 70, 52, 21, 20, 21, 84, 192, 65, 35, 47, 6, 37, 12, 111, 89, 0, 0, 17, 70, 44, 244, 9, 21, 33, 71, 49, 40, 48, 6, 37, 34, 112, 136, 0, 19, 8, 22, 9, 195, 171, 20, 14, 1, 13, 84, 57, 6, 108, 47, 50, 35, 65, 0, 12, 71, 52, 83, 2, 61, 84, 142, 20, 21, 0, 10, 0, 0, 14, 69, 88, 243, 21, 37, 64, 83, 110, 55, 10, 127, 47, 0, 13, 69, 32, 82, 77, 5, 64, 107, 121, 65, 35, 47, 0, 0, 16, 70, 93, 148, 199, 21, 33, 64, 84, 123, 89, 136, 116, 34, 13, 0, 0, 0, 0, 10, 69, 88, 144, 212, 61, 32, 21, 0, 10, 14, 73, 76, 128, 75, 21, 52, 5, 5, 33, 64, 21, 0, 10, 0, 13, 70, 72, 244, 211, 61, 85, 192, 34, 13, 89, 120, 0, 9, 198, 52, 144, 200, 36, 83, 0, 66, 0, 10, 199, 92, 81, 82, 44, 194, 78, 44, 66, 10, 199, 60, 225, 197, 92, 243, 206, 76, 65, 0, 11, 200, 60, 225, 5, 73, 118, 83, 21, 32, 67, 15, 70, 48, 145, 83, 8, 85, 0, 55, 37, 89, 71, 108, 47, 0, 13, 68, 20, 210, 76, 20, 108, 65, 6, 37, 12, 55, 0, 0, 15, 69, 32, 21, 129, 56, 16, 107, 35, 84, 6, 35, 50, 35, 0, 0, 0, 16, 70, 73, 82, 203, 21, 34, 71, 34, 111, 49, 13, 34, 13, 136, 0, 0, 11, 200, 4, 19, 147, 80, 16, 78, 16, 80, 66, 0, 15, 69, 52, 245, 15, 72, 80, 65, 117, 47, 6, 117, 34, 13, 0, 9, 197, 16, 16, 82, 56, 16, 8, 32, 14, 69, 76, 50, 1, 48, 176, 89, 49, 6, 35, 55, 49, 0, 0, 0, 16, 70, 72, 245, 20, 20, 225, 83, 34, 110, 47, 13, 50, 108, 89, 0, 13, 71, 32, 243, 199, 20, 65, 76, 20, 107, 117, 136, 0, 18, 71, 17, 35, 207, 53, 53, 5, 72, 72, 34, 117, 65, 89, 47, 112, 34, 0, 10, 199, 52, 17, 196, 4, 193, 78, 4, 67, 0, 11, 68, 16, 18, 83, 100, 72, 123, 88, 37, 0, 0, 10, 67, 5, 51, 198, 35, 89, 110, 83, 0, 0, 18, 70, 12, 243, 5, 57, 51, 192, 49, 40, 55, 6, 108, 12, 50, 89, 120, 0, 0, 13, 70, 21, 52, 18, 21, 52, 207, 21, 105, 116, 0, 10, 18, 70, 8, 195, 205, 21, 37, 83, 71, 55, 40, 65, 6, 116, 34, 111, 89, 0, 0, 0, 17, 70, 76, 177, 80, 76, 83, 5, 89, 49, 108, 48, 89, 13, 55, 13, 0, 11, 70, 44, 83, 148, 84, 50, 217, 21, 0, 10, 0, 25, 73, 52, 81, 137, 77, 67, 198, 20, 193, 83, 65, 108, 83, 37, 89, 47, 6, 117, 83, 13, 55, 13, 89, 0, 0, 0, 0, 0, 0, 7, 195, 17, 84, 192, 8, 32, 0, 0, 0, 11, 70, 76, 147, 129, 81, 32, 64, 21, 0, 10, 17, 70, 41, 80, 78, 37, 64, 64, 57, 40, 35, 50, 6, 37, 47, 35, 0, 0, 19, 71, 84, 149, 5, 72, 16, 82, 16, 127, 47, 13, 34, 10, 6, 115, 34, 47, 0, 14, 67, 4, 69, 128, 35, 47, 83, 40, 49, 6, 115, 47, 0, 0, 0, 13, 69, 48, 81, 193, 5, 64, 55, 13, 136, 115, 47, 0, 16, 70, 8, 83, 12, 21, 101, 69, 71, 112, 55, 84, 57, 40, 12, 0, 0, 0, 21, 71, 36, 225, 215, 5, 101, 77, 4, 37, 68, 81, 58, 35, 84, 6, 40, 12, 65, 35, 0, 0, 0, 8, 197, 92, 21, 20, 21, 32, 8, 0, 9, 198, 5, 53, 1, 73, 65, 64, 66, 0, 0, 10, 67, 89, 33, 75, 83, 34, 112, 49, 0, 0, 9, 198, 92, 81, 82, 28, 19, 13, 66, 12, 69, 80, 241, 71, 20, 80, 47, 40, 136, 116, 0, 14, 69, 48, 144, 137, 16, 240, 55, 13, 71, 37, 72, 40, 0, 0, 16, 70, 88, 16, 82, 92, 83, 0, 83, 115, 34, 84, 6, 112, 55, 0, 0, 10, 199, 84, 149, 5, 72, 208, 84, 20, 67, 14, 67, 44, 20, 20, 49, 35, 48, 47, 6, 123, 50, 0, 24, 0, 20, 72, 61, 85, 5, 56, 145, 75, 92, 16, 120, 47, 13, 50, 6, 37, 49, 58, 35, 0, 0, 14, 69, 88, 84, 147, 80, 80, 83, 112, 34, 89, 47, 13, 0, 17, 70, 56, 80, 146, 5, 50, 193, 50, 13, 71, 34, 35, 89, 49, 35, 0, 0, 0, 0, 17, 70, 56, 81, 197, 77, 65, 82, 50, 116, 136, 13, 89, 47, 112, 34, 0, 20, 72, 24, 147, 9, 65, 1, 78, 76, 80, 83, 13, 55, 13, 48, 108, 50, 89, 13, 0, 13, 68, 76, 245, 197, 48, 89, 117, 84, 6, 112, 55, 0, 21, 72, 25, 32, 83, 21, 32, 149, 72, 112, 83, 34, 123, 88, 13, 34, 71, 111, 34, 136, 0, 0, 0, 0, 0, 12, 68, 72, 81, 201, 20, 34, 13, 90, 37, 12, 0, 17, 70, 52, 147, 137, 77, 65, 82, 65, 13, 50, 109, 89, 47, 13, 34, 0, 21, 72, 65, 149, 8, 4, 115, 210, 5, 48, 48, 37, 47, 6, 115, 136, 117, 34, 35, 89, 0, 0, 8, 197, 61, 3, 1, 5, 48, 66, 0, 17, 70, 88, 84, 147, 24, 83, 4, 83, 112, 34, 89, 83, 112, 55, 47, 0, 0, 24, 73, 8, 85, 12, 20, 129, 77, 77, 65, 82, 71, 108, 47, 55, 37, 12, 108, 65, 89, 47, 112, 34, 0, 0, 9, 68, 92, 22, 78, 20, 21, 0, 10, 0, 14, 69, 8, 85, 197, 56, 64, 71, 116, 84, 13, 50, 47, 0, 14, 69, 12, 20, 141, 20, 224, 49, 35, 34, 65, 108, 50, 0, 0, 15, 70, 92, 147, 12, 20, 228, 192, 84, 109, 55, 13, 50, 89, 0, 18, 70, 40, 84, 133, 52, 144, 64, 57, 2, 116, 34, 13, 65, 6, 37, 35, 0, 0, 0, 13, 68, 20, 194, 90, 20, 37, 55, 6, 37, 12, 88, 0, 0, 8, 195, 28, 16, 78, 72, 9, 32, 14, 69, 36, 225, 210, 36, 64, 37, 68, 81, 34, 13, 72, 0, 0, 10, 67, 4, 193, 197, 35, 55, 136, 13, 0, 11, 70, 77, 65, 86, 20, 228, 192, 21, 0, 10, 11, 70, 12, 243, 12, 36, 228, 192, 21, 0, 10, 0, 6, 195, 92, 145, 64, 8, 7, 195, 80, 241, 64, 72, 32, 18, 71, 76, 50, 1, 48, 181, 217, 44, 89, 49, 35, 55, 49, 84, 123, 49, 0, 12, 71, 28, 84, 141, 37, 53, 15, 56, 21, 0, 10, 0, 19, 72, 92, 83, 12, 36, 225, 212, 60, 224, 58, 108, 55, 37, 68, 47, 13, 50, 0, 0, 0, 0, 6, 195, 32, 241, 64, 8, 0, 0, 16, 69, 88, 18, 193, 57, 64, 83, 2, 35, 49, 6, 35, 50, 47, 0, 10, 67, 4, 209, 78, 115, 65, 108, 50, 0, 10, 69, 5, 37, 8, 85, 32, 21, 0, 10, 0, 0, 0, 0, 9, 198, 4, 195, 73, 76, 178, 69, 67, 13, 69, 16, 84, 137, 12, 176, 72, 108, 34, 37, 49, 0, 0, 0, 9, 67, 105, 147, 0, 89, 123, 55, 0, 0, 0, 15, 69, 76, 243, 143, 72, 80, 89, 40, 50, 6, 117, 34, 13, 0, 17, 70, 29, 32, 70, 24, 149, 9, 81, 34, 35, 83, 6, 37, 47, 37, 0, 13, 70, 72, 245, 83, 76, 80, 85, 34, 13, 89, 120, 0, 16, 69, 76, 245, 197, 80, 240, 89, 40, 58, 6, 108, 12, 47, 40, 0, 16, 69, 52, 20, 21, 80, 240, 65, 35, 48, 6, 40, 12, 47, 40, 0, 15, 69, 44, 19, 129, 16, 16, 49, 35, 50, 35, 72, 2, 35, 0, 0, 0, 18, 70, 65, 35, 198, 21, 65, 83, 48, 34, 110, 83, 13, 47, 6, 108, 89, 0, 18, 71, 64, 245, 16, 61, 84, 146, 36, 48, 110, 47, 48, 40, 34, 6, 37, 0, 20, 71, 36, 212, 18, 60, 212, 20, 84, 37, 65, 48, 34, 6, 110, 65, 48, 47, 40, 0, 10, 199, 24, 147, 129, 48, 148, 212, 20, 67, 18, 70, 4, 192, 133, 73, 69, 83, 35, 55, 71, 6, 112, 34, 47, 111, 89, 0, 0, 11, 70, 29, 83, 12, 37, 97, 82, 21, 0, 10, 0, 10, 69, 8, 20, 139, 49, 144, 21, 0, 10, 0, 21, 72, 9, 33, 68, 20, 226, 193, 53, 0, 71, 34, 116, 72, 13, 50, 49, 35, 65, 48, 0, 14, 70, 4, 36, 129, 32, 19, 64, 115, 71, 34, 35, 65, 0, 0, 20, 71, 44, 245, 9, 48, 163, 206, 76, 49, 110, 47, 13, 55, 57, 6, 135, 50, 89, 0, 7, 195, 32, 243, 64, 72, 32, 9, 67, 44, 147, 64, 21, 0, 41, 10, 0, 12, 68, 32, 22, 68, 56, 107, 122, 72, 13, 50, 0, 17, 70, 8, 83, 138, 4, 210, 78, 71, 108, 50, 75, 13, 65, 13, 50, 0, 21, 72, 5, 32, 200, 36, 209, 68, 21, 48, 35, 34, 136, 37, 65, 6, 116, 72, 108, 89, 0, 0, 10, 69, 72, 131, 196, 21, 48, 21, 0, 10, 8, 197, 48, 17, 146, 5, 48, 66, 0, 12, 201, 81, 32, 80, 77, 85, 84, 40, 145, 83, 66, 12, 67, 4, 195, 205, 35, 55, 10, 6, 110, 65, 0, 11, 67, 36, 196, 197, 6, 37, 55, 88, 13, 0, 15, 70, 48, 84, 207, 80, 131, 192, 55, 13, 89, 40, 47, 40, 0, 0, 18, 71, 88, 243, 19, 12, 129, 78, 44, 83, 110, 55, 89, 49, 108, 68, 49, 0, 0, 0, 10, 69, 92, 147, 19, 60, 224, 21, 0, 10, 0, 15, 70, 61, 81, 19, 32, 84, 128, 120, 47, 89, 107, 112, 34, 0, 17, 70, 12, 80, 201, 48, 144, 64, 89, 13, 89, 37, 12, 55, 37, 35, 0, 0, 17, 71, 12, 128, 82, 52, 18, 78, 20, 91, 115, 65, 6, 123, 12, 50, 0, 0, 11, 68, 28, 86, 69, 72, 136, 123, 13, 34, 0, 0, 10, 69, 61, 129, 143, 72, 64, 21, 0, 10, 0, 16, 70, 32, 21, 133, 56, 112, 64, 107, 115, 83, 13, 68, 136, 35, 0, 0, 12, 71, 92, 147, 12, 37, 53, 15, 56, 21, 0, 10, 12, 71, 77, 65, 86, 20, 228, 207, 56, 21, 0, 10, 0, 0, 0, 14, 70, 52, 21, 20, 32, 81, 64, 65, 35, 47, 6, 116, 0, 0, 0, 18, 8, 2, 195, 170, 18, 5, 20, 25, 4, 71, 113, 34, 13, 47, 123, 47, 0, 14, 68, 32, 244, 197, 4, 107, 40, 89, 6, 37, 12, 35, 0, 0, 15, 69, 92, 83, 5, 21, 32, 84, 112, 55, 10, 6, 116, 34, 0, 0, 0, 20, 71, 88, 19, 141, 20, 193, 87, 20, 83, 35, 50, 65, 13, 55, 6, 116, 84, 13, 0, 11, 70, 16, 83, 9, 48, 18, 0, 21, 0, 10, 0, 11, 200, 56, 147, 77, 21, 35, 69, 21, 32, 65, 22, 72, 52, 17, 1, 28, 20, 203, 5, 32, 65, 35, 72, 35, 136, 6, 35, 89, 49, 35, 34, 0, 0, 16, 69, 32, 84, 133, 72, 240, 107, 108, 34, 6, 108, 12, 34, 40, 0, 17, 69, 4, 64, 71, 36, 240, 35, 72, 6, 115, 75, 37, 38, 2, 120, 0, 6, 195, 92, 16, 82, 8, 14, 69, 16, 83, 9, 48, 16, 72, 13, 55, 109, 55, 35, 0, 14, 69, 21, 84, 143, 64, 16, 128, 34, 6, 117, 48, 35, 0, 0, 0, 0, 13, 68, 16, 246, 69, 56, 72, 131, 57, 6, 108, 50, 0, 18, 72, 12, 132, 137, 77, 65, 76, 48, 80, 49, 34, 13, 89, 47, 112, 55, 0, 0, 13, 69, 76, 129, 73, 48, 16, 91, 37, 12, 55, 35, 0, 15, 69, 48, 245, 73, 76, 80, 55, 40, 58, 6, 37, 12, 88, 0, 14, 69, 5, 66, 5, 56, 80, 35, 47, 6, 116, 50, 13, 0, 0, 0, 0, 21, 72, 13, 34, 77, 64, 83, 5, 56, 80, 49, 34, 13, 65, 48, 13, 55, 37, 12, 50, 0, 20, 72, 12, 19, 79, 84, 99, 1, 28, 80, 49, 35, 65, 40, 83, 55, 6, 115, 90, 0, 0, 6, 97, 97, 0, 4, 110, 2, 98, 105, 100, 3, 2, 115, 50, 0, 110, 2, 103, 114, 101, 110, 115, 101, 110, 0, 110, 2, 103, 114, 121, 112, 101, 110, 100, 0, 110, 2, 104, 97, 110, 103, 105, 103, 0, 110, 2, 104, 97, 110, 107, 0, 110, 2, 104, 111, 117, 100, 101, 110, 0, 110, 2, 108, 111, 107, 0, 110, 2, 109, 101, 108, 100, 98, 97, 0, 110, 2, 112, 97, 115, 98, 97, 0, 110, 2, 115, 105, 101, 110, 0, 110, 2, 115, 112, 114, 101, 101, 107, 0, 110, 2, 115, 116, 17, 65, 17, 65, 17, 67, 0, 110, 2, 116, 97, 115, 98, 0, 110, 2, 118, 97, 97, 114, 0, 110, 2, 118, 97, 108, 108, 17, 65, 17, 67, 0, 110, 2, 118, 101, 103, 98, 97, 0, 110, 2, 118, 117, 108, 108, 101, 110, 100, 0, 110, 2, 119, 101, 115, 105, 103, 0, 110, 2, 119, 121, 115, 101, 110, 100, 101, 32, 118, 111, 111, 114, 110, 0, 110, 2, 101, 101, 110, 3, 2, 115, 50, 19, 0, 110, 116, 114, 101, 107, 108, 105, 107, 3, 2, 115, 50, 47, 34, 112, 49, 55, 13, 49, 0, 110, 100, 111, 101, 110, 108, 105, 107, 3, 2, 115, 50, 72, 40, 50, 55, 13, 49, 0, 110, 110, 101, 101, 109, 108, 105, 107, 3, 2, 115, 50, 116, 65, 55, 13, 49, 0, 109, 2, 98, 111, 114, 115, 3, 2, 115, 65, 0, 110, 2, 115, 105, 101, 110, 32, 24, 3, 6, 115, 50, 0, 4, 110, 119, 101, 110, 2, 32, 3, 6, 115, 50, 84, 108, 50, 0, 110, 119, 101, 110, 2, 100, 0, 110, 115, 116, 101, 114, 107, 3, 6, 115, 50, 89, 47, 112, 34, 49, 0, 110, 103, 101, 8, 2, 21, 14, 128, 132, 133, 3, 6, 115, 50, 136, 13, 0, 110, 103, 101, 101, 2, 12, 3, 6, 115, 50, 136, 116, 0, 110, 115, 2, 32, 3, 6, 133, 50, 89, 0, 110, 115, 101, 2, 32, 3, 6, 133, 50, 89, 13, 0, 3, 115, 0, 114, 100, 8, 2, 114, 3, 115, 34, 47, 0, 114, 100, 8, 2, 111, 3, 115, 34, 47, 10, 0, 4, 110, 2, 103, 3, 115, 50, 0, 110, 2, 108, 111, 107, 32, 24, 0, 110, 2, 115, 112, 114, 101, 101, 107, 32, 24, 0, 110, 2, 115, 116, 17, 65, 17, 65, 17, 67, 32, 24, 0, 110, 2, 116, 114, 101, 107, 32, 24, 0, 110, 2, 118, 97, 108, 108, 101, 114, 0, 4, 110, 2, 115, 107, 111, 117, 3, 115, 50, 6, 0, 110, 2, 118, 97, 110, 107, 0, 4, 110, 100, 2, 114, 111, 107, 3, 115, 50, 47, 10, 0, 110, 100, 2, 114, 117, 115, 0, 110, 116, 101, 108, 8, 3, 115, 50, 47, 112, 55, 0, 110, 100, 101, 108, 101, 3, 115, 50, 72, 116, 55, 13, 10, 0, 110, 115, 116, 101, 2, 108, 108, 101, 114, 105, 103, 3, 115, 50, 89, 47, 6, 112, 0, 110, 110, 101, 109, 2, 17, 65, 3, 115, 50, 116, 65, 0, 105, 3, 122, 0, 4, 110, 2, 100, 106, 105, 101, 3, 122, 68, 0, 110, 2, 116, 106, 105, 101, 0, 4, 100, 106, 105, 101, 3, 122, 80, 37, 0, 116, 106, 105, 101, 0, 7, 6, 97, 110, 0, 4, 1, 17, 67, 2, 107, 101, 101, 114, 3, 2, 35, 50, 0, 8, 2, 17, 65, 0, 8, 2, 101, 109, 105, 101, 0, 110, 8, 2, 97, 21, 0, 97, 116, 111, 2, 109, 105, 101, 3, 2, 35, 50, 2, 35, 47, 2, 40, 0, 97, 116, 111, 109, 105, 101, 115, 3, 2, 35, 50, 2, 35, 47, 117, 65, 2, 37, 89, 0, 111, 2, 114, 101, 107, 17, 67, 3, 2, 35, 50, 2, 40, 0, 111, 109, 97, 2, 108, 105, 101, 3, 2, 35, 50, 2, 40, 65, 2, 35, 0, 111, 109, 97, 108, 105, 101, 115, 3, 2, 35, 50, 2, 40, 65, 115, 55, 37, 89, 0, 101, 107, 2, 100, 111, 116, 3, 2, 35, 50, 2, 108, 49, 0, 101, 2, 109, 111, 3, 2, 35, 50, 13, 0, 116, 105, 8, 2, 17, 67, 14, 128, 132, 132, 3, 2, 35, 50, 47, 2, 37, 0, 116, 114, 97, 2, 115, 105, 101, 116, 3, 2, 35, 50, 47, 34, 2, 35, 0, 116, 101, 2, 110, 110, 17, 65, 3, 2, 35, 50, 47, 108, 0, 101, 116, 116, 101, 1, 17, 67, 2, 32, 3, 2, 35, 50, 108, 47, 0, 2, 103, 105, 110, 97, 3, 2, 35, 68, 0, 103, 101, 2, 108, 105, 101, 114, 3, 2, 35, 68, 13, 0, 103, 111, 114, 97, 3, 2, 35, 68, 81, 131, 34, 2, 35, 0, 103, 111, 108, 2, 101, 3, 2, 133, 68, 136, 2, 40, 55, 0, 103, 108, 8, 2, 17, 65, 3, 2, 133, 68, 136, 55, 2, 0, 97, 8, 2, 17, 67, 3, 4, 35, 50, 35, 0, 1, 103, 2, 32, 3, 21, 0, 111, 2, 114, 97, 107, 3, 35, 50, 2, 40, 0, 116, 114, 111, 111, 112, 1, 21, 3, 35, 50, 47, 34, 6, 117, 48, 0, 116, 114, 111, 112, 101, 1, 21, 2, 32, 3, 35, 50, 47, 34, 6, 117, 48, 13, 0, 116, 114, 111, 112, 105, 101, 1, 21, 3, 35, 50, 47, 34, 6, 117, 48, 37, 0, 116, 114, 111, 112, 105, 101, 1, 21, 2, 32, 24, 3, 35, 50, 47, 34, 40, 48, 6, 37, 0, 115, 106, 111, 118, 105, 3, 35, 50, 91, 7, 117, 83, 13, 0, 103, 108, 101, 101, 114, 3, 35, 68, 55, 116, 34, 0, 4, 2, 100, 106, 105, 101, 12, 3, 121, 68, 0, 2, 116, 106, 105, 101, 0, 4, 115, 1, 100, 3, 133, 50, 89, 0, 115, 1, 104, 0, 115, 1, 107, 0, 115, 1, 108, 0, 115, 1, 114, 102, 0, 115, 1, 114, 107, 0, 103, 111, 108, 97, 3, 133, 68, 136, 6, 117, 55, 35, 0, 7, 6, 98, 97, 0, 4, 2, 108, 97, 110, 115, 3, 71, 2, 35, 0, 2, 108, 100, 97, 100, 105, 103, 0, 2, 108, 106, 97, 97, 114, 0, 2, 108, 107, 111, 110, 0, 2, 108, 108, 111, 110, 0, 2, 110, 97, 108, 17, 65, 0, 2, 110, 105, 101, 114, 0, 2, 114, 101, 116, 25, 0, 2, 114, 111, 110, 0, 2, 115, 105, 101, 108, 105, 0, 2, 116, 105, 107, 0, 8, 2, 115, 97, 0, 114, 2, 98, 17, 65, 3, 71, 2, 35, 34, 0, 116, 97, 108, 2, 106, 111, 110, 3, 71, 2, 35, 47, 2, 35, 55, 0, 116, 116, 101, 2, 114, 121, 3, 71, 2, 35, 47, 13, 0, 107, 97, 116, 101, 2, 108, 3, 71, 2, 35, 49, 13, 47, 112, 0, 107, 116, 101, 2, 114, 105, 3, 71, 2, 35, 49, 47, 116, 0, 110, 100, 2, 105, 101, 116, 3, 71, 2, 35, 50, 72, 0, 4, 108, 97, 107, 108, 97, 118, 97, 3, 71, 2, 35, 55, 2, 35, 49, 55, 115, 84, 2, 35, 0, 108, 97, 107, 108, 97, 119, 97, 0, 108, 97, 110, 2, 115, 101, 101, 114, 3, 71, 2, 35, 55, 2, 35, 50, 0, 108, 108, 101, 114, 2, 105, 110, 17, 65, 3, 71, 2, 35, 55, 13, 34, 0, 108, 106, 117, 3, 71, 2, 35, 55, 57, 118, 0, 108, 104, 111, 114, 3, 71, 2, 35, 55, 107, 117, 34, 0, 108, 108, 101, 2, 116, 3, 71, 2, 35, 55, 108, 0, 108, 108, 97, 100, 101, 3, 71, 2, 35, 55, 115, 72, 13, 0, 106, 111, 110, 101, 2, 116, 3, 71, 2, 35, 57, 2, 40, 50, 108, 0, 109, 8, 2, 98, 111, 101, 115, 3, 71, 2, 35, 65, 0, 4, 110, 2, 107, 101, 116, 3, 71, 2, 35, 68, 0, 110, 2, 107, 105, 101, 114, 0, 110, 2, 107, 114, 111, 116, 0, 115, 105, 2, 108, 105, 115, 107, 3, 71, 2, 35, 89, 13, 0, 115, 111, 116, 104, 111, 3, 71, 2, 35, 89, 40, 47, 2, 40, 0, 115, 116, 105, 108, 108, 101, 3, 71, 2, 35, 89, 47, 37, 12, 55, 0, 104, 97, 109, 97, 3, 71, 2, 35, 107, 115, 65, 2, 35, 0, 110, 100, 2, 17, 65, 108, 105, 101, 114, 3, 71, 4, 35, 50, 72, 0, 108, 108, 111, 2, 116, 3, 71, 4, 35, 55, 110, 0, 1, 21, 2, 114, 101, 110, 3, 71, 6, 115, 0, 97, 114, 108, 105, 107, 1, 21, 3, 71, 6, 115, 34, 55, 13, 49, 0, 116, 101, 8, 3, 71, 7, 115, 47, 13, 0, 107, 108, 101, 105, 3, 71, 13, 49, 55, 123, 0, 103, 97, 115, 105, 101, 3, 71, 13, 136, 115, 89, 37, 0, 2, 114, 105, 116, 111, 110, 3, 71, 35, 0, 114, 111, 2, 109, 101, 116, 101, 114, 3, 71, 35, 34, 2, 40, 0, 114, 97, 2, 107, 3, 71, 35, 34, 6, 35, 0, 114, 111, 107, 3, 71, 35, 34, 7, 110, 49, 10, 0, 100, 2, 114, 3, 71, 35, 47, 0, 100, 8, 2, 17, 65, 3, 71, 35, 47, 10, 0, 107, 8, 2, 111, 3, 71, 35, 49, 10, 0, 110, 100, 2, 17, 65, 3, 71, 35, 50, 47, 0, 110, 100, 2, 101, 3, 71, 35, 50, 72, 0, 108, 108, 2, 101, 116, 106, 105, 101, 12, 3, 71, 35, 55, 0, 108, 115, 101, 109, 3, 71, 35, 55, 89, 13, 65, 0, 115, 116, 105, 111, 110, 3, 71, 35, 89, 47, 37, 110, 50, 0, 107, 101, 110, 3, 71, 115, 49, 13, 50, 0, 114, 98, 101, 114, 116, 111, 110, 3, 71, 115, 71, 13, 34, 47, 2, 110, 50, 0, 98, 97, 3, 71, 115, 71, 35, 0, 98, 97, 2, 116, 106, 105, 101, 3, 71, 115, 71, 121, 0, 115, 105, 2, 115, 3, 71, 115, 89, 13, 0, 100, 106, 105, 101, 3, 71, 121, 80, 37, 0, 7, 6, 98, 101, 0, 115, 101, 114, 105, 110, 103, 3, 8, 71, 13, 89, 116, 34, 13, 68, 0, 110, 8, 2, 17, 67, 105, 101, 110, 3, 71, 2, 108, 50, 0, 110, 8, 2, 103, 97, 3, 71, 2, 108, 68, 0, 114, 2, 108, 121, 110, 3, 71, 2, 112, 34, 0, 110, 101, 2, 100, 121, 3, 71, 2, 116, 50, 13, 0, 1, 17, 67, 2, 114, 115, 105, 101, 3, 71, 6, 113, 0, 101, 114, 1, 21, 2, 32, 3, 71, 6, 116, 34, 0, 4, 114, 105, 110, 103, 3, 71, 6, 116, 34, 13, 68, 0, 114, 105, 110, 103, 1, 98, 111, 114, 107, 115, 0, 116, 101, 114, 3, 71, 6, 116, 47, 13, 34, 0, 101, 108, 100, 105, 103, 1, 21, 3, 71, 6, 116, 55, 72, 13, 136, 0, 107, 101, 114, 8, 2, 17, 67, 21, 3, 71, 7, 116, 49, 13, 34, 0, 4, 1, 21, 2, 17, 67, 3, 71, 13, 0, 1, 98, 17, 65, 17, 67, 2, 108, 0, 1, 117, 106, 2, 108, 108, 17, 65, 0, 2, 100, 114, 21, 0, 2, 119, 101, 103, 105, 110, 103, 0, 8, 2, 17, 67, 121, 0, 8, 2, 21, 14, 128, 132, 130, 0, 8, 2, 32, 0, 2, 97, 109, 112, 3, 71, 13, 19, 0, 114, 2, 115, 101, 114, 107, 3, 71, 13, 34, 0, 4, 114, 105, 110, 103, 1, 17, 67, 3, 71, 13, 34, 13, 68, 0, 114, 105, 110, 103, 1, 111, 0, 107, 101, 110, 3, 71, 13, 49, 108, 50, 0, 110, 100, 101, 1, 98, 10, 3, 71, 13, 50, 72, 13, 0, 100, 119, 2, 21, 3, 71, 13, 72, 58, 0, 100, 101, 2, 17, 67, 102, 3, 71, 13, 72, 112, 0, 100, 101, 108, 105, 110, 103, 3, 71, 13, 72, 116, 55, 13, 68, 0, 119, 121, 115, 1, 21, 3, 71, 13, 84, 123, 89, 0, 115, 116, 101, 2, 107, 3, 71, 13, 89, 47, 112, 0, 115, 105, 103, 2, 116, 105, 103, 3, 71, 13, 89, 109, 136, 0, 104, 101, 112, 3, 71, 13, 107, 108, 48, 0, 103, 101, 114, 2, 17, 65, 3, 71, 13, 136, 116, 34, 0, 4, 2, 17, 67, 11, 12, 3, 71, 108, 0, 100, 2, 116, 0, 100, 106, 105, 101, 3, 71, 108, 12, 37, 80, 37, 0, 4, 100, 1, 21, 2, 32, 3, 71, 108, 47, 0, 100, 2, 17, 67, 0, 100, 2, 114, 97, 110, 100, 0, 100, 2, 119, 97, 114, 109, 0, 100, 2, 119, 111, 111, 114, 100, 0, 116, 108, 101, 104, 101, 2, 109, 3, 71, 108, 47, 55, 2, 37, 2, 108, 0, 100, 119, 2, 105, 101, 103, 3, 71, 108, 47, 84, 0, 110, 100, 101, 3, 71, 108, 50, 72, 13, 0, 110, 103, 101, 108, 3, 71, 108, 68, 13, 55, 0, 115, 115, 105, 101, 3, 71, 108, 89, 37, 0, 115, 116, 101, 2, 32, 3, 71, 108, 89, 47, 13, 0, 1, 101, 114, 2, 108, 25, 12, 3, 71, 112, 0, 114, 8, 2, 17, 67, 3, 71, 112, 34, 0, 114, 107, 101, 8, 3, 71, 112, 34, 49, 13, 0, 114, 103, 101, 3, 71, 112, 34, 81, 13, 0, 114, 103, 3, 71, 112, 34, 136, 0, 4, 107, 2, 32, 3, 71, 112, 49, 0, 107, 2, 100, 0, 107, 2, 102, 0, 107, 2, 104, 0, 107, 2, 109, 0, 107, 2, 115, 0, 107, 107, 2, 12, 0, 4, 1, 114, 2, 108, 25, 3, 71, 112, 55, 0, 108, 1, 17, 67, 2, 32, 0, 108, 8, 2, 17, 67, 0, 108, 108, 2, 12, 0, 4, 1, 110, 111, 115, 2, 115, 105, 101, 3, 71, 116, 0, 2, 100, 101, 32, 0, 101, 2, 12, 0, 4, 101, 114, 1, 97, 17, 67, 11, 3, 71, 116, 34, 0, 101, 114, 1, 101, 105, 100, 100, 101, 116, 0, 101, 114, 1, 115, 121, 0, 114, 101, 2, 32, 3, 71, 116, 34, 13, 0, 114, 105, 110, 103, 1, 116, 110, 111, 3, 71, 116, 34, 13, 68, 0, 116, 101, 2, 32, 3, 71, 116, 47, 13, 0, 116, 101, 115, 1, 97, 105, 100, 2, 21, 3, 71, 116, 47, 13, 89, 0, 116, 105, 101, 115, 3, 71, 116, 47, 37, 89, 0, 4, 107, 101, 114, 1, 21, 2, 32, 3, 71, 116, 49, 13, 34, 0, 107, 101, 114, 1, 21, 2, 116, 106, 105, 101, 0, 107, 101, 114, 2, 17, 67, 21, 0, 107, 101, 114, 2, 17, 65, 17, 65, 3, 71, 116, 49, 13, 34, 10, 0, 4, 110, 101, 1, 21, 2, 32, 3, 71, 116, 50, 13, 0, 110, 101, 2, 114, 0, 110, 105, 2, 103, 0, 100, 101, 2, 115, 116, 114, 3, 71, 116, 72, 13, 0, 100, 101, 108, 3, 71, 116, 72, 13, 55, 0, 100, 101, 118, 3, 71, 116, 72, 13, 83, 0, 100, 101, 115, 2, 32, 3, 71, 116, 72, 13, 89, 0, 4, 119, 101, 2, 107, 110, 105, 101, 3, 71, 116, 84, 13, 0, 119, 101, 2, 108, 105, 112, 0, 119, 101, 2, 114, 97, 115, 105, 101, 0, 119, 101, 2, 114, 105, 103, 0, 119, 101, 110, 100, 101, 3, 71, 116, 84, 13, 50, 72, 13, 0, 119, 105, 110, 103, 3, 71, 116, 84, 13, 68, 0, 4, 115, 2, 105, 101, 32, 3, 71, 116, 89, 0, 115, 2, 105, 101, 115, 32, 0, 115, 101, 109, 3, 71, 116, 89, 13, 65, 0, 115, 105, 103, 3, 71, 116, 89, 13, 136, 0, 97, 117, 3, 71, 120, 0, 105, 2, 12, 3, 71, 123, 0, 105, 103, 101, 3, 71, 123, 12, 90, 0, 117, 2, 17, 67, 3, 71, 128, 0, 117, 101, 108, 3, 71, 128, 13, 55, 0, 7, 6, 100, 101, 0, 1, 21, 2, 114, 111, 115, 105, 101, 3, 47, 10, 2, 116, 0, 4, 2, 109, 111, 111, 110, 3, 72, 2, 37, 0, 2, 112, 114, 101, 115, 115, 0, 111, 100, 111, 2, 114, 97, 110, 116, 3, 72, 2, 37, 2, 40, 72, 2, 40, 0, 116, 97, 105, 2, 108, 108, 101, 101, 114, 3, 72, 2, 37, 12, 47, 2, 123, 0, 109, 111, 110, 101, 3, 72, 2, 37, 65, 117, 50, 13, 0, 4, 2, 107, 108, 105, 110, 17, 65, 3, 72, 2, 108, 0, 2, 109, 111, 17, 67, 114, 0, 2, 112, 117, 116, 97, 0, 2, 115, 107, 117, 110, 0, 116, 111, 2, 110, 17, 65, 3, 72, 2, 108, 47, 2, 40, 0, 110, 8, 2, 100, 114, 105, 3, 72, 2, 108, 50, 0, 108, 105, 8, 2, 107, 97, 3, 72, 2, 108, 55, 2, 37, 0, 108, 105, 107, 97, 2, 116, 101, 115, 115, 3, 72, 2, 108, 55, 2, 37, 49, 2, 35, 0, 98, 105, 2, 116, 101, 3, 72, 2, 108, 71, 2, 37, 0, 4, 98, 117, 2, 116, 97, 3, 72, 2, 108, 71, 2, 118, 0, 98, 117, 2, 116, 101, 21, 0, 115, 8, 2, 112, 111, 3, 72, 2, 108, 89, 0, 114, 8, 2, 100, 117, 105, 17, 67, 3, 72, 2, 112, 34, 0, 108, 112, 104, 105, 110, 105, 117, 109, 3, 72, 2, 112, 55, 83, 37, 50, 37, 38, 111, 65, 0, 4, 2, 102, 108, 97, 115, 105, 3, 72, 2, 116, 0, 2, 104, 105, 100, 114, 0, 2, 107, 114, 105, 109, 105, 110, 97, 0, 2, 115, 116, 114, 117, 107, 116, 0, 101, 2, 109, 111, 101, 100, 105, 103, 0, 115, 116, 97, 98, 105, 108, 105, 8, 2, 115, 3, 72, 2, 116, 89, 47, 2, 35, 71, 2, 37, 55, 2, 37, 0, 115, 101, 109, 98, 101, 114, 3, 72, 2, 116, 89, 108, 65, 71, 13, 34, 0, 4, 117, 114, 2, 100, 114, 101, 110, 107, 3, 72, 2, 118, 13, 34, 0, 117, 114, 2, 100, 114, 105, 110, 103, 21, 0, 117, 114, 2, 103, 114, 111, 110, 100, 0, 117, 114, 2, 108, 101, 101, 102, 0, 117, 114, 2, 108, 111, 112, 21, 0, 117, 114, 2, 108, 117, 103, 116, 0, 117, 114, 2, 115, 105, 103, 116, 0, 117, 114, 2, 116, 114, 97, 112, 116, 0, 117, 114, 2, 119, 101, 101, 17, 67, 0, 117, 114, 2, 119, 105, 110, 116, 101, 114, 0, 117, 114, 2, 97, 97, 114, 3, 72, 2, 118, 13, 34, 10, 0, 117, 114, 115, 112, 101, 107, 3, 72, 2, 118, 13, 34, 89, 48, 108, 49, 0, 4, 117, 114, 2, 98, 111, 3, 72, 2, 128, 34, 0, 117, 114, 2, 100, 97, 103, 0, 117, 114, 2, 112, 114, 105, 101, 109, 0, 117, 114, 2, 114, 101, 105, 115, 0, 117, 114, 2, 115, 107, 121, 110, 17, 65, 0, 117, 114, 2, 115, 107, 121, 110, 100, 101, 0, 117, 114, 2, 115, 111, 101, 107, 0, 117, 114, 2, 119, 97, 97, 105, 100, 0, 2, 103, 114, 97, 100, 17, 65, 3, 72, 4, 116, 0, 116, 97, 105, 108, 3, 72, 6, 37, 12, 47, 123, 55, 0, 110, 105, 109, 8, 3, 72, 7, 108, 50, 13, 65, 0, 110, 107, 101, 110, 2, 100, 3, 72, 7, 108, 68, 49, 13, 50, 0, 4, 1, 10, 2, 110, 101, 32, 3, 72, 13, 0, 1, 21, 2, 107, 111, 110, 116, 114, 97, 107, 0, 1, 21, 2, 109, 101, 110, 116, 0, 2, 98, 17, 65, 0, 2, 107, 97, 97, 110, 0, 2, 107, 97, 110, 101, 0, 2, 107, 114, 101, 0, 2, 108, 97, 97, 110, 0, 114, 100, 1, 21, 2, 32, 3, 72, 13, 34, 47, 0, 112, 97, 114, 116, 101, 2, 109, 101, 110, 116, 3, 72, 13, 48, 2, 35, 34, 47, 13, 0, 112, 111, 115, 105, 116, 111, 3, 72, 13, 48, 117, 89, 37, 47, 40, 0, 107, 97, 110, 116, 2, 32, 3, 72, 13, 49, 35, 50, 47, 0, 110, 105, 115, 1, 10, 3, 72, 13, 50, 13, 89, 0, 110, 100, 1, 21, 2, 115, 116, 101, 3, 72, 13, 50, 47, 0, 110, 100, 1, 21, 2, 101, 114, 3, 72, 13, 50, 72, 0, 108, 101, 8, 2, 103, 17, 65, 3, 72, 13, 55, 13, 0, 108, 101, 1, 110, 117, 107, 2, 25, 3, 72, 13, 55, 108, 0, 108, 105, 2, 114, 105, 117, 109, 3, 72, 13, 55, 109, 0, 4, 108, 111, 111, 115, 3, 72, 13, 55, 117, 89, 0, 108, 111, 115, 0, 98, 97, 2, 116, 116, 101, 101, 114, 3, 72, 13, 71, 2, 35, 0, 98, 117, 117, 116, 3, 72, 13, 71, 118, 47, 0, 119, 101, 2, 116, 25, 3, 72, 13, 84, 108, 0, 112, 111, 116, 2, 32, 3, 72, 108, 48, 2, 40, 0, 107, 97, 100, 101, 2, 115, 3, 72, 108, 49, 6, 115, 72, 13, 0, 107, 97, 100, 101, 2, 110, 3, 72, 108, 49, 35, 72, 6, 108, 0, 110, 116, 101, 1, 21, 2, 21, 3, 72, 108, 50, 47, 13, 0, 110, 107, 3, 72, 108, 68, 49, 0, 115, 105, 98, 101, 108, 3, 72, 108, 89, 37, 71, 112, 55, 0, 114, 109, 1, 17, 67, 21, 2, 25, 3, 72, 112, 34, 14, 65, 0, 114, 103, 101, 8, 3, 72, 112, 34, 136, 13, 0, 4, 114, 100, 101, 1, 101, 101, 119, 116, 3, 72, 113, 34, 72, 13, 0, 114, 100, 101, 8, 2, 25, 0, 8, 2, 107, 108, 97, 115, 115, 3, 72, 116, 0, 4, 108, 101, 1, 114, 101, 100, 110, 111, 2, 21, 3, 72, 116, 55, 13, 10, 0, 108, 101, 1, 114, 111, 111, 118, 2, 21, 0, 7, 6, 101, 101, 0, 114, 98, 105, 101, 100, 119, 3, 2, 116, 34, 71, 2, 37, 47, 84, 0, 114, 119, 8, 3, 2, 116, 34, 84, 0, 4, 110, 2, 100, 114, 97, 103, 21, 3, 2, 116, 50, 0, 110, 2, 109, 97, 108, 105, 103, 0, 110, 2, 112, 97, 114, 105, 103, 0, 110, 2, 118, 111, 114, 109, 0, 110, 8, 2, 115, 116, 101, 109, 109, 0, 110, 8, 2, 115, 121, 0, 110, 8, 2, 116, 111, 110, 0, 110, 8, 2, 118, 111, 117, 100, 21, 0, 4, 114, 1, 21, 2, 24, 3, 6, 116, 34, 0, 114, 1, 107, 105, 0, 114, 1, 108, 111, 17, 65, 0, 114, 1, 109, 109, 0, 114, 1, 109, 114, 0, 114, 1, 115, 107, 0, 114, 1, 115, 115, 0, 114, 1, 117, 0, 114, 100, 104, 101, 105, 100, 1, 21, 3, 6, 116, 34, 47, 107, 123, 47, 0, 108, 1, 117, 3, 6, 116, 55, 0, 3, 116, 0, 2, 117, 117, 3, 116, 10, 0, 110, 2, 17, 67, 106, 105, 101, 3, 116, 12, 37, 68, 0, 4, 114, 1, 102, 115, 3, 116, 34, 0, 114, 1, 104, 0, 114, 1, 107, 21, 0, 114, 1, 107, 115, 0, 114, 1, 108, 17, 65, 17, 65, 0, 114, 1, 108, 17, 67, 17, 65, 17, 65, 0, 114, 1, 108, 17, 67, 21, 0, 114, 1, 108, 101, 103, 0, 114, 1, 108, 103, 0, 114, 1, 108, 107, 0, 114, 1, 108, 110, 0, 114, 1, 108, 114, 0, 114, 1, 108, 115, 0, 114, 1, 109, 17, 67, 0, 114, 1, 112, 101, 0, 114, 1, 115, 17, 67, 0, 114, 1, 116, 110, 171, 195, 105, 114, 111, 0, 114, 1, 118, 17, 65, 17, 65, 0, 114, 1, 118, 17, 67, 0, 114, 1, 118, 101, 17, 67, 0, 114, 1, 119, 0, 114, 98, 105, 101, 100, 2, 17, 65, 3, 116, 34, 71, 6, 37, 72, 0, 4, 100, 106, 105, 101, 3, 116, 37, 80, 37, 0, 116, 106, 105, 101, 0, 117, 3, 119, 12, 0, 117, 101, 3, 119, 12, 13, 0, 7, 6, 101, 110, 0, 101, 109, 109, 101, 108, 3, 2, 37, 50, 112, 65, 13, 55, 0, 4, 1, 17, 67, 17, 65, 17, 67, 2, 115, 105, 101, 101, 17, 67, 3, 2, 108, 50, 0, 1, 17, 67, 17, 65, 17, 67, 2, 115, 105, 195, 171, 17, 67, 0, 8, 2, 116, 111, 112, 116, 105, 101, 0, 101, 114, 2, 103, 105, 3, 2, 108, 50, 13, 34, 0, 116, 111, 101, 115, 105, 97, 3, 2, 108, 50, 47, 2, 40, 89, 2, 37, 35, 0, 107, 101, 108, 2, 118, 111, 117, 100, 105, 3, 2, 108, 50, 49, 13, 55, 0, 115, 105, 107, 108, 111, 112, 101, 3, 2, 108, 50, 89, 2, 37, 49, 55, 2, 40, 48, 13, 0, 105, 103, 8, 2, 109, 97, 3, 2, 108, 50, 109, 136, 0, 111, 114, 109, 8, 2, 17, 65, 3, 2, 116, 50, 110, 34, 65, 0, 116, 114, 101, 112, 114, 101, 2, 110, 101, 3, 2, 133, 50, 47, 34, 13, 48, 34, 13, 0, 4, 116, 1, 17, 67, 21, 2, 25, 3, 6, 108, 50, 47, 0, 116, 1, 17, 67, 21, 2, 101, 32, 0, 115, 105, 101, 1, 17, 67, 2, 25, 3, 6, 108, 50, 89, 37, 0, 115, 105, 101, 115, 1, 17, 67, 3, 6, 108, 50, 89, 37, 89, 0, 105, 8, 2, 103, 3, 6, 116, 50, 13, 0, 8, 107, 2, 100, 104, 3, 8, 108, 50, 0, 4, 115, 105, 101, 109, 2, 32, 3, 10, 2, 108, 50, 89, 37, 65, 0, 115, 105, 101, 109, 2, 101, 32, 0, 115, 101, 109, 98, 108, 101, 3, 10, 2, 133, 50, 89, 133, 65, 71, 114, 0, 4, 1, 10, 2, 17, 67, 32, 3, 13, 50, 0, 1, 10, 2, 32, 0, 1, 10, 2, 100, 101, 17, 67, 32, 0, 1, 10, 2, 100, 101, 32, 0, 1, 17, 67, 10, 2, 98, 17, 65, 114, 103, 0, 1, 100, 114, 111, 111, 98, 2, 115, 0, 1, 102, 21, 2, 105, 115, 0, 1, 103, 110, 2, 100, 0, 1, 105, 111, 111, 2, 115, 0, 1, 107, 17, 67, 97, 118, 2, 17, 67, 0, 1, 107, 21, 2, 115, 107, 97, 112, 0, 1, 109, 2, 105, 115, 0, 105, 101, 114, 1, 17, 67, 3, 13, 50, 6, 37, 12, 34, 0, 121, 1, 17, 67, 21, 2, 32, 3, 13, 50, 6, 123, 0, 4, 101, 1, 107, 10, 2, 32, 3, 13, 50, 13, 0, 101, 1, 115, 10, 2, 32, 0, 4, 115, 1, 108, 17, 65, 17, 65, 2, 32, 3, 13, 50, 89, 0, 115, 1, 108, 101, 118, 2, 32, 0, 115, 1, 108, 108, 117, 118, 2, 32, 0, 115, 1, 112, 112, 111, 17, 67, 0, 115, 119, 97, 97, 114, 1, 21, 2, 100, 105, 103, 3, 13, 50, 89, 84, 6, 115, 34, 0, 104, 101, 105, 100, 1, 17, 67, 3, 13, 50, 107, 123, 47, 0, 97, 97, 114, 1, 17, 67, 3, 13, 50, 115, 34, 0, 97, 114, 101, 1, 17, 67, 2, 32, 3, 13, 50, 115, 34, 13, 0, 99, 101, 2, 25, 12, 3, 21, 0, 116, 106, 105, 101, 1, 107, 10, 3, 37, 68, 80, 37, 0, 116, 106, 105, 101, 1, 114, 112, 3, 108, 12, 37, 68, 49, 2, 37, 0, 115, 1, 108, 2, 32, 3, 108, 12, 50, 89, 0, 115, 101, 1, 108, 2, 32, 3, 108, 12, 50, 89, 13, 0, 116, 106, 105, 101, 2, 12, 3, 108, 37, 68, 80, 37, 0, 4, 1, 107, 115, 2, 100, 3, 108, 50, 0, 1, 112, 17, 67, 21, 2, 32, 0, 1, 112, 105, 101, 114, 98, 0, 1, 116, 111, 112, 2, 17, 67, 0, 110, 1, 112, 17, 67, 21, 2, 101, 0, 4, 116, 1, 110, 101, 2, 12, 12, 3, 108, 50, 47, 0, 116, 1, 114, 112, 2, 12, 12, 0, 116, 1, 115, 21, 2, 114, 17, 65, 0, 106, 105, 110, 3, 108, 50, 57, 13, 50, 0, 100, 101, 108, 2, 32, 3, 108, 50, 72, 13, 55, 0, 115, 1, 112, 17, 67, 2, 12, 3, 108, 50, 89, 0, 115, 101, 1, 112, 17, 67, 2, 108, 101, 32, 3, 108, 50, 89, 116, 0, 4, 1, 10, 2, 107, 32, 3, 108, 68, 0, 103, 1, 10, 2, 32, 0, 103, 101, 2, 108, 3, 108, 68, 13, 0, 107, 101, 108, 8, 3, 108, 68, 49, 13, 55, 0, 111, 114, 109, 8, 3, 116, 50, 6, 110, 34, 13, 10, 65, 0, 101, 1, 107, 115, 2, 32, 3, 116, 50, 13, 0, 101, 114, 115, 3, 116, 50, 13, 34, 89, 0, 4, 115, 1, 109, 2, 12, 12, 3, 134, 50, 89, 0, 115, 1, 114, 103, 0, 115, 1, 119, 0, 115, 105, 101, 1, 109, 2, 25, 3, 134, 50, 89, 2, 37, 0, 7, 6, 103, 101, 0, 103, 101, 101, 1, 21, 3, 8, 136, 13, 136, 116, 0, 1, 17, 67, 2, 32, 3, 81, 13, 0, 114, 1, 114, 117, 98, 3, 81, 13, 34, 0, 110, 114, 101, 3, 90, 6, 133, 50, 34, 13, 0, 110, 105, 101, 2, 32, 3, 90, 13, 50, 37, 12, 0, 111, 8, 2, 115, 3, 136, 2, 37, 2, 40, 0, 114, 8, 2, 109, 97, 3, 136, 2, 112, 34, 0, 114, 117, 2, 98, 121, 110, 3, 136, 2, 116, 34, 2, 111, 0, 110, 101, 2, 97, 108, 111, 3, 136, 2, 116, 50, 2, 37, 0, 101, 115, 2, 100, 114, 105, 102, 116, 105, 3, 136, 2, 116, 89, 0, 109, 109, 101, 114, 3, 136, 6, 108, 65, 13, 34, 0, 1, 105, 110, 2, 114, 105, 3, 136, 6, 116, 0, 119, 101, 2, 32, 3, 136, 6, 116, 84, 13, 0, 4, 119, 101, 110, 100, 1, 21, 2, 32, 3, 136, 6, 116, 84, 13, 50, 47, 0, 119, 101, 110, 100, 1, 21, 2, 115, 116, 101, 0, 119, 101, 110, 100, 101, 1, 21, 2, 32, 3, 136, 6, 116, 84, 13, 50, 72, 13, 0, 115, 101, 2, 32, 3, 136, 6, 116, 89, 13, 0, 4, 3, 136, 13, 0, 8, 2, 21, 14, 128, 132, 130, 0, 8, 2, 111, 115, 115, 14, 128, 132, 130, 0, 107, 108, 101, 100, 101, 3, 136, 13, 49, 55, 116, 72, 13, 0, 110, 101, 2, 114, 17, 65, 3, 136, 13, 50, 13, 0, 110, 97, 100, 2, 101, 116, 106, 105, 101, 3, 136, 13, 50, 115, 72, 0, 110, 97, 100, 101, 3, 136, 13, 50, 115, 72, 13, 0, 110, 101, 2, 114, 105, 101, 25, 3, 136, 13, 50, 116, 0, 108, 121, 107, 101, 110, 105, 8, 2, 115, 3, 136, 13, 55, 6, 123, 49, 13, 50, 13, 0, 109, 101, 108, 2, 100, 3, 136, 13, 65, 112, 55, 0, 98, 101, 100, 101, 8, 3, 136, 13, 71, 116, 72, 13, 0, 118, 101, 115, 2, 32, 3, 136, 13, 83, 108, 89, 0, 119, 101, 108, 2, 119, 3, 136, 13, 84, 6, 112, 55, 0, 4, 119, 101, 108, 2, 100, 3, 136, 13, 84, 112, 55, 0, 119, 101, 108, 2, 102, 0, 119, 101, 101, 114, 3, 136, 13, 84, 116, 34, 0, 119, 101, 110, 115, 1, 17, 67, 21, 3, 136, 13, 84, 134, 50, 89, 0, 115, 101, 108, 2, 32, 3, 136, 13, 89, 112, 55, 0, 115, 101, 108, 108, 101, 2, 32, 3, 136, 13, 89, 112, 55, 13, 0, 115, 101, 108, 115, 3, 136, 13, 89, 112, 55, 89, 0, 103, 101, 119, 101, 110, 115, 3, 136, 13, 136, 116, 84, 13, 50, 89, 0, 4, 1, 17, 65, 2, 116, 106, 105, 101, 3, 136, 37, 0, 2, 111, 103, 114, 97, 0, 2, 111, 108, 111, 0, 2, 111, 109, 101, 0, 110, 115, 8, 2, 17, 67, 3, 136, 108, 12, 50, 89, 0, 109, 115, 3, 136, 108, 65, 89, 0, 115, 112, 101, 2, 32, 3, 136, 108, 89, 48, 13, 0, 115, 112, 101, 115, 2, 32, 3, 136, 108, 89, 48, 13, 89, 0, 4, 2, 107, 32, 3, 136, 112, 0, 2, 107, 103, 0, 2, 107, 104, 0, 2, 107, 107, 0, 2, 107, 115, 107, 101, 101, 114, 0, 2, 107, 116, 0, 8, 2, 114, 17, 67, 0, 114, 102, 1, 17, 67, 3, 136, 112, 34, 83, 0, 114, 119, 101, 1, 17, 67, 2, 32, 3, 136, 112, 34, 84, 13, 0, 107, 119, 2, 111, 114, 100, 3, 136, 112, 49, 84, 0, 108, 100, 3, 136, 112, 55, 47, 0, 108, 100, 2, 105, 110, 17, 67, 3, 136, 112, 55, 47, 10, 0, 108, 100, 2, 105, 110, 103, 3, 136, 112, 55, 72, 0, 4, 108, 100, 101, 2, 25, 3, 136, 112, 55, 72, 13, 0, 108, 100, 105, 0, 108, 100, 106, 105, 101, 3, 136, 112, 55, 80, 37, 0, 4, 1, 107, 114, 101, 119, 2, 119, 101, 114, 3, 136, 116, 0, 101, 2, 12, 0, 195, 171, 114, 2, 32, 3, 136, 116, 13, 34, 0, 110, 101, 2, 32, 3, 136, 116, 50, 13, 0, 110, 105, 116, 2, 105, 101, 17, 67, 3, 136, 116, 50, 13, 47, 0, 110, 117, 115, 3, 136, 116, 50, 111, 89, 0, 108, 101, 1, 25, 2, 32, 3, 136, 116, 55, 13, 0, 108, 101, 114, 8, 3, 136, 116, 55, 13, 34, 0, 4, 119, 101, 114, 1, 103, 97, 108, 115, 3, 136, 116, 84, 13, 34, 0, 119, 101, 114, 1, 116, 101, 119, 0, 119, 101, 114, 2, 32, 0, 119, 101, 114, 115, 2, 32, 3, 136, 116, 84, 13, 34, 89, 0, 119, 101, 110, 115, 2, 103, 3, 136, 116, 84, 13, 50, 89, 0, 119, 101, 108, 3, 136, 116, 84, 13, 55, 0, 119, 105, 110, 103, 3, 136, 116, 84, 13, 68, 0, 105, 2, 12, 3, 136, 123, 0, 117, 2, 17, 67, 3, 136, 128, 0, 7, 6, 104, 101, 0, 2, 98, 114, 101, 3, 107, 2, 37, 0, 116, 101, 114, 111, 2, 21, 21, 14, 128, 132, 134, 3, 107, 2, 108, 47, 14, 34, 2, 40, 0, 107, 8, 2, 116, 97, 3, 107, 2, 108, 49, 0, 114, 8, 2, 21, 14, 128, 132, 131, 3, 107, 2, 112, 34, 0, 114, 97, 108, 2, 100, 105, 101, 107, 3, 107, 2, 112, 34, 2, 35, 55, 0, 114, 2, 101, 110, 105, 3, 107, 2, 112, 34, 19, 0, 114, 97, 108, 2, 100, 3, 107, 2, 112, 34, 35, 55, 0, 114, 116, 111, 103, 2, 105, 110, 3, 107, 2, 112, 34, 47, 2, 110, 136, 0, 114, 109, 97, 102, 114, 111, 2, 100, 105, 3, 107, 2, 112, 34, 65, 2, 35, 83, 34, 2, 40, 0, 114, 109, 101, 2, 108, 121, 110, 3, 107, 2, 112, 34, 65, 13, 0, 114, 98, 101, 114, 103, 2, 105, 3, 107, 2, 112, 34, 71, 2, 112, 34, 136, 0, 114, 98, 101, 114, 103, 2, 115, 97, 21, 3, 107, 2, 112, 34, 71, 112, 34, 136, 0, 114, 105, 110, 110, 101, 114, 3, 107, 2, 112, 34, 109, 50, 13, 34, 0, 108, 2, 100, 105, 110, 3, 107, 2, 112, 55, 0, 108, 105, 2, 107, 111, 112, 3, 107, 2, 112, 55, 2, 37, 0, 108, 100, 2, 104, 97, 102, 116, 3, 107, 2, 112, 55, 47, 0, 2, 114, 111, 195, 175, 101, 3, 107, 2, 116, 0, 114, 111, 2, 195, 175, 101, 110, 3, 107, 2, 116, 34, 2, 40, 58, 0, 101, 116, 2, 104, 111, 111, 102, 100, 105, 3, 107, 2, 116, 47, 0, 4, 114, 8, 2, 98, 101, 17, 67, 14, 128, 132, 131, 3, 107, 6, 112, 34, 0, 114, 8, 2, 118, 101, 114, 14, 128, 132, 131, 0, 114, 100, 101, 114, 3, 107, 6, 112, 34, 72, 13, 34, 0, 108, 100, 101, 8, 3, 107, 6, 112, 55, 72, 13, 0, 114, 8, 2, 119, 97, 97, 3, 107, 7, 112, 34, 0, 4, 114, 2, 101, 107, 115, 97, 109, 17, 65, 3, 107, 7, 112, 34, 10, 0, 114, 8, 2, 117, 105, 116, 0, 1, 21, 2, 110, 25, 3, 107, 108, 0, 120, 2, 17, 67, 3, 107, 108, 49, 89, 0, 107, 115, 101, 2, 17, 67, 3, 107, 108, 49, 89, 13, 0, 109, 2, 17, 67, 3, 107, 108, 65, 0, 4, 2, 103, 3, 107, 112, 0, 2, 114, 114, 105, 101, 0, 4, 114, 2, 98, 101, 114, 103, 3, 107, 112, 34, 0, 114, 2, 107, 111, 109, 115, 0, 114, 8, 2, 109, 97, 110, 25, 0, 114, 8, 114, 111, 111, 2, 17, 67, 0, 114, 2, 101, 118, 97, 3, 107, 112, 34, 19, 0, 114, 116, 122, 111, 103, 3, 107, 112, 34, 47, 89, 110, 136, 0, 114, 116, 111, 103, 3, 107, 112, 34, 47, 110, 136, 0, 114, 102, 115, 3, 107, 112, 34, 83, 89, 0, 114, 115, 101, 110, 3, 107, 112, 34, 89, 13, 50, 0, 108, 3, 107, 112, 55, 0, 2, 108, 105, 3, 107, 116, 0, 114, 2, 101, 25, 3, 107, 116, 34, 0, 4, 114, 101, 2, 114, 101, 103, 3, 107, 116, 34, 13, 0, 114, 101, 2, 119, 0, 114, 101, 8, 2, 108, 0, 101, 114, 101, 110, 2, 103, 114, 97, 99, 3, 107, 116, 34, 13, 50, 0, 101, 114, 115, 101, 114, 3, 107, 116, 34, 89, 13, 34, 0, 108, 101, 8, 2, 25, 3, 107, 116, 55, 13, 0, 109, 101, 108, 3, 107, 116, 65, 13, 55, 0, 100, 101, 1, 10, 2, 32, 3, 107, 116, 72, 13, 0, 105, 100, 2, 32, 14, 128, 128, 132, 3, 107, 123, 47, 0, 105, 100, 101, 2, 17, 67, 3, 107, 123, 72, 13, 0, 7, 6, 105, 110, 0, 4, 105, 115, 105, 2, 17, 65, 3, 2, 37, 50, 2, 37, 91, 2, 37, 0, 105, 115, 105, 2, 101, 17, 65, 0, 2, 102, 111, 114, 109, 101, 14, 128, 132, 130, 3, 6, 109, 50, 0, 8, 2, 97, 17, 67, 101, 109, 14, 128, 132, 130, 3, 6, 109, 50, 10, 0, 103, 8, 2, 21, 3, 6, 109, 50, 136, 0, 103, 101, 8, 2, 21, 14, 128, 132, 132, 3, 6, 109, 50, 136, 13, 0, 4, 103, 101, 2, 119, 105, 110, 103, 3, 6, 109, 50, 136, 116, 0, 103, 101, 101, 8, 2, 12, 0, 8, 2, 115, 116, 117, 100, 101, 14, 128, 132, 130, 3, 7, 109, 50, 0, 8, 2, 101, 110, 116, 3, 7, 109, 50, 10, 0, 4, 1, 17, 67, 2, 97, 115, 101, 109, 3, 10, 13, 50, 0, 1, 102, 108, 101, 115, 2, 17, 67, 21, 0, 103, 97, 110, 103, 3, 10, 109, 50, 136, 35, 68, 0, 4, 1, 21, 2, 103, 114, 121, 112, 3, 13, 50, 0, 2, 100, 105, 101, 110, 0, 2, 100, 111, 101, 110, 97, 0, 2, 101, 101, 110, 0, 2, 102, 101, 107, 0, 2, 104, 97, 108, 105, 103, 0, 2, 104, 101, 101, 109, 115, 0, 2, 104, 101, 103, 116, 101, 110, 0, 2, 107, 101, 110, 110, 0, 2, 115, 107, 105, 107, 0, 2, 115, 107, 114, 105, 112, 0, 2, 115, 112, 101, 107, 0, 2, 115, 116, 97, 110, 0, 2, 116, 105, 101, 109, 0, 2, 119, 101, 114, 107, 105, 110, 103, 17, 67, 17, 67, 0, 8, 2, 101, 114, 17, 67, 0, 105, 115, 105, 101, 3, 13, 50, 6, 37, 89, 2, 37, 0, 116, 117, 195, 175, 3, 13, 50, 47, 2, 40, 12, 37, 0, 116, 101, 2, 103, 114, 101, 3, 13, 50, 47, 13, 0, 4, 116, 101, 114, 2, 110, 97, 115, 105, 111, 3, 13, 50, 47, 13, 34, 0, 116, 101, 114, 2, 110, 101, 114, 105, 110, 0, 116, 101, 114, 2, 110, 105, 25, 0, 116, 105, 109, 105, 2, 100, 17, 65, 3, 13, 50, 47, 13, 65, 13, 0, 116, 114, 105, 103, 2, 101, 21, 3, 13, 50, 47, 34, 2, 37, 136, 0, 116, 114, 111, 8, 2, 17, 67, 3, 13, 50, 47, 34, 2, 40, 0, 116, 114, 105, 103, 101, 3, 13, 50, 47, 34, 37, 136, 13, 0, 116, 101, 103, 2, 114, 105, 3, 13, 50, 47, 112, 136, 0, 100, 105, 2, 97, 21, 3, 13, 50, 72, 2, 37, 0, 100, 111, 110, 101, 2, 115, 105, 3, 13, 50, 72, 2, 40, 50, 37, 12, 0, 100, 101, 114, 8, 2, 17, 67, 3, 13, 50, 72, 13, 34, 0, 4, 100, 105, 118, 105, 3, 13, 50, 72, 13, 84, 13, 0, 100, 105, 119, 105, 0, 100, 105, 115, 2, 107, 114, 3, 13, 50, 72, 13, 89, 0, 102, 97, 110, 2, 116, 105, 3, 13, 50, 83, 2, 35, 50, 0, 102, 111, 114, 2, 109, 97, 3, 13, 50, 83, 2, 110, 34, 0, 118, 97, 108, 105, 100, 101, 3, 13, 50, 84, 2, 35, 55, 37, 72, 13, 0, 118, 101, 115, 116, 2, 101, 101, 114, 3, 13, 50, 84, 2, 108, 89, 47, 0, 118, 101, 115, 116, 101, 2, 114, 21, 3, 13, 50, 84, 2, 108, 89, 47, 116, 0, 115, 105, 2, 100, 101, 110, 116, 3, 13, 50, 89, 13, 0, 115, 101, 107, 2, 117, 3, 13, 50, 89, 13, 49, 0, 115, 116, 105, 2, 116, 117, 3, 13, 50, 89, 47, 13, 0, 115, 116, 114, 117, 107, 116, 3, 13, 50, 89, 47, 34, 2, 111, 49, 47, 0, 115, 116, 114, 117, 107, 115, 3, 13, 50, 89, 47, 34, 6, 111, 49, 89, 0, 110, 101, 109, 101, 110, 3, 13, 50, 116, 65, 13, 50, 0, 110, 117, 101, 110, 100, 111, 3, 13, 50, 118, 12, 6, 108, 50, 72, 120, 0, 103, 114, 121, 112, 101, 110, 3, 13, 50, 136, 34, 123, 48, 13, 50, 0, 103, 1, 10, 2, 32, 3, 13, 68, 0, 103, 101, 1, 17, 67, 21, 2, 32, 3, 13, 68, 13, 0, 4, 100, 106, 105, 101, 3, 109, 37, 68, 80, 37, 0, 116, 106, 105, 101, 0, 8, 2, 97, 21, 14, 128, 132, 130, 3, 109, 50, 0, 8, 2, 111, 101, 3, 109, 50, 10, 0, 98, 101, 8, 2, 108, 17, 67, 3, 109, 50, 71, 2, 112, 0, 100, 119, 105, 110, 103, 3, 109, 50, 72, 58, 13, 68, 0, 100, 101, 108, 8, 2, 17, 67, 3, 109, 50, 72, 112, 55, 0, 115, 101, 107, 2, 17, 65, 3, 109, 50, 89, 108, 49, 10, 0, 103, 2, 115, 3, 109, 68, 0, 7, 6, 107, 97, 0, 116, 97, 8, 3, 4, 49, 35, 47, 35, 0, 4, 1, 21, 2, 110, 111, 110, 3, 49, 2, 35, 0, 2, 106, 97, 107, 0, 2, 109, 97, 115, 0, 2, 110, 97, 108, 101, 0, 2, 112, 97, 17, 67, 101, 17, 67, 0, 2, 114, 111, 115, 0, 2, 115, 97, 114, 109, 0, 2, 115, 116, 114, 111, 108, 0, 2, 115, 116, 121, 0, 2, 116, 97, 114, 115, 105, 0, 8, 2, 100, 21, 0, 8, 2, 108, 17, 65, 110, 17, 67, 0, 8, 2, 114, 105, 101, 110, 0, 8, 2, 115, 116, 97, 0, 8, 2, 115, 116, 101, 21, 0, 8, 2, 116, 111, 0, 8, 2, 116, 114, 0, 4, 114, 2, 100, 111, 101, 115, 3, 49, 2, 35, 34, 0, 114, 2, 110, 117, 102, 102, 101, 108, 0, 114, 2, 116, 111, 110, 0, 114, 2, 119, 97, 116, 115, 0, 114, 2, 119, 101, 105, 0, 114, 2, 119, 121, 0, 114, 8, 2, 98, 0, 114, 8, 2, 118, 101, 0, 4, 114, 97, 2, 98, 121, 110, 3, 49, 2, 35, 34, 2, 35, 0, 114, 97, 2, 107, 111, 101, 108, 0, 114, 97, 109, 101, 108, 3, 49, 2, 35, 34, 2, 35, 65, 112, 55, 0, 114, 105, 107, 97, 2, 116, 117, 3, 49, 2, 35, 34, 2, 37, 49, 2, 35, 0, 114, 97, 2, 118, 97, 3, 49, 2, 35, 34, 13, 0, 114, 116, 101, 116, 115, 3, 49, 2, 35, 34, 47, 108, 47, 89, 0, 114, 110, 97, 2, 118, 97, 108, 3, 49, 2, 35, 34, 50, 2, 35, 0, 114, 109, 111, 115, 121, 110, 3, 49, 2, 35, 34, 65, 2, 40, 89, 123, 50, 0, 114, 109, 101, 2, 110, 97, 97, 100, 106, 3, 49, 2, 35, 34, 65, 13, 0, 114, 97, 116, 101, 3, 49, 2, 35, 34, 115, 47, 2, 37, 0, 4, 116, 101, 2, 100, 114, 3, 49, 2, 35, 47, 13, 0, 116, 101, 2, 103, 17, 65, 0, 116, 97, 108, 111, 2, 103, 17, 65, 3, 49, 2, 35, 47, 35, 55, 2, 40, 0, 116, 107, 105, 2, 115, 17, 65, 3, 49, 2, 35, 47, 49, 13, 0, 112, 2, 116, 101, 105, 110, 3, 49, 2, 35, 48, 0, 112, 97, 2, 115, 105, 116, 101, 105, 116, 3, 49, 2, 35, 48, 2, 35, 0, 112, 105, 2, 116, 97, 3, 49, 2, 35, 48, 2, 37, 0, 112, 101, 2, 108, 97, 21, 3, 49, 2, 35, 48, 13, 0, 112, 101, 114, 2, 106, 111, 108, 3, 49, 2, 35, 48, 13, 34, 0, 112, 115, 117, 108, 101, 3, 49, 2, 35, 48, 89, 118, 55, 13, 0, 112, 111, 8, 2, 17, 67, 3, 49, 2, 35, 48, 110, 0, 112, 101, 2, 108, 3, 49, 2, 35, 48, 112, 0, 4, 110, 2, 116, 105, 101, 110, 3, 49, 2, 35, 50, 0, 110, 8, 2, 116, 111, 21, 0, 4, 110, 100, 105, 2, 100, 17, 65, 3, 49, 2, 35, 50, 2, 37, 0, 110, 110, 105, 2, 98, 97, 0, 110, 115, 101, 2, 108, 108, 101, 3, 49, 2, 35, 50, 89, 13, 0, 4, 110, 111, 2, 32, 3, 49, 2, 35, 50, 117, 0, 110, 111, 8, 2, 118, 97, 97, 114, 0, 4, 108, 2, 98, 97, 115, 3, 49, 2, 35, 55, 0, 108, 2, 107, 111, 101, 110, 0, 108, 105, 2, 98, 3, 49, 2, 35, 55, 37, 0, 108, 101, 110, 100, 101, 114, 3, 49, 2, 35, 55, 108, 50, 72, 13, 34, 0, 109, 111, 101, 2, 102, 108, 3, 49, 2, 35, 65, 2, 40, 0, 109, 111, 101, 102, 108, 97, 103, 101, 3, 49, 2, 35, 65, 2, 40, 83, 55, 115, 90, 0, 109, 101, 114, 97, 100, 101, 3, 49, 2, 35, 65, 13, 34, 115, 72, 13, 0, 98, 97, 114, 101, 2, 116, 3, 49, 2, 35, 71, 2, 35, 34, 108, 0, 98, 105, 110, 101, 2, 116, 3, 49, 2, 35, 71, 2, 37, 50, 108, 0, 102, 101, 2, 195, 175, 3, 49, 2, 35, 83, 2, 37, 0, 102, 101, 2, 116, 101, 3, 49, 2, 35, 83, 13, 0, 115, 116, 97, 2, 110, 106, 101, 116, 3, 49, 2, 35, 89, 47, 2, 35, 0, 115, 107, 101, 2, 110, 97, 100, 101, 3, 49, 2, 35, 89, 49, 13, 0, 115, 115, 101, 2, 116, 3, 49, 2, 35, 89, 108, 0, 115, 101, 114, 110, 101, 3, 49, 2, 35, 89, 112, 34, 50, 13, 0, 116, 106, 105, 101, 2, 112, 105, 101, 3, 49, 2, 121, 80, 2, 37, 0, 110, 102, 101, 114, 2, 102, 111, 101, 108, 3, 49, 2, 133, 50, 83, 13, 34, 0, 116, 101, 103, 111, 114, 105, 101, 115, 3, 49, 4, 35, 47, 13, 136, 6, 117, 34, 37, 89, 0, 116, 101, 103, 111, 114, 105, 101, 3, 49, 4, 35, 47, 13, 136, 40, 34, 6, 37, 0, 97, 1, 17, 65, 21, 2, 116, 3, 49, 6, 115, 0, 116, 101, 1, 21, 2, 32, 3, 49, 6, 115, 47, 13, 0, 110, 101, 114, 1, 17, 65, 21, 2, 32, 3, 49, 6, 115, 50, 13, 34, 0, 4, 114, 2, 98, 101, 3, 49, 35, 34, 0, 114, 2, 118, 101, 110, 0, 114, 2, 118, 101, 114, 0, 116, 101, 103, 111, 114, 2, 105, 115, 17, 65, 3, 49, 35, 47, 13, 136, 40, 34, 0, 110, 116, 2, 111, 110, 100, 101, 114, 3, 49, 35, 50, 47, 10, 0, 110, 115, 101, 2, 108, 25, 3, 49, 35, 50, 89, 13, 0, 108, 97, 104, 97, 114, 105, 3, 49, 35, 55, 35, 107, 6, 115, 34, 37, 0, 4, 108, 109, 101, 101, 114, 3, 49, 35, 55, 65, 6, 116, 34, 0, 108, 109, 101, 114, 2, 17, 65, 0, 108, 119, 101, 114, 3, 49, 35, 55, 84, 13, 34, 10, 0, 109, 101, 114, 2, 97, 116, 106, 105, 101, 3, 49, 35, 65, 13, 34, 0, 109, 101, 114, 97, 97, 3, 49, 35, 65, 13, 34, 6, 115, 0, 109, 101, 114, 97, 3, 49, 35, 65, 13, 34, 35, 0, 98, 101, 108, 106, 111, 117, 3, 49, 35, 71, 13, 55, 57, 6, 120, 0, 100, 2, 109, 105, 117, 109, 3, 49, 35, 72, 0, 115, 116, 101, 114, 2, 111, 108, 105, 101, 3, 49, 35, 89, 47, 13, 34, 10, 0, 2, 100, 101, 114, 3, 49, 115, 0, 116, 101, 108, 1, 25, 3, 49, 115, 47, 13, 55, 0, 107, 101, 2, 17, 67, 3, 49, 115, 49, 13, 0, 4, 109, 101, 114, 3, 49, 115, 65, 13, 34, 0, 109, 101, 114, 2, 17, 67, 0, 98, 101, 108, 3, 49, 115, 71, 13, 55, 0, 110, 102, 101, 114, 3, 49, 133, 50, 83, 13, 34, 10, 0, 7, 6, 107, 111, 0, 4, 2, 107, 101, 116, 25, 3, 49, 2, 40, 0, 2, 107, 111, 110, 0, 2, 108, 111, 109, 0, 2, 108, 111, 110, 105, 0, 2, 109, 101, 100, 105, 0, 2, 109, 101, 116, 101, 0, 2, 114, 97, 0, 2, 114, 105, 110, 116, 0, 2, 114, 114, 117, 112, 0, 2, 195, 182, 0, 8, 2, 109, 105, 101, 107, 0, 8, 2, 109, 109, 111, 0, 8, 2, 112, 105, 101, 21, 0, 101, 2, 106, 97, 119, 101, 108, 0, 101, 2, 112, 108, 101, 116, 0, 101, 2, 112, 111, 110, 0, 101, 2, 114, 17, 65, 0, 114, 114, 101, 107, 3, 49, 2, 40, 34, 108, 49, 0, 114, 101, 110, 2, 116, 3, 49, 2, 40, 34, 108, 50, 0, 117, 107, 97, 2, 115, 105, 195, 171, 3, 49, 2, 40, 49, 115, 0, 110, 110, 101, 107, 3, 49, 2, 40, 50, 108, 49, 0, 101, 108, 2, 98, 108, 111, 101, 3, 49, 2, 40, 55, 0, 108, 108, 101, 2, 107, 116, 17, 65, 3, 49, 2, 40, 55, 2, 108, 0, 108, 108, 101, 2, 107, 116, 101, 25, 3, 49, 2, 40, 55, 108, 0, 108, 108, 101, 107, 2, 115, 3, 49, 2, 40, 55, 108, 49, 0, 108, 111, 2, 115, 25, 3, 49, 2, 40, 55, 110, 0, 108, 111, 110, 110, 101, 3, 49, 2, 40, 55, 110, 50, 13, 0, 108, 108, 101, 103, 97, 3, 49, 2, 40, 55, 116, 136, 2, 35, 0, 109, 101, 100, 105, 2, 97, 110, 116, 3, 49, 2, 40, 65, 2, 37, 72, 2, 37, 0, 109, 109, 97, 110, 100, 111, 3, 49, 2, 40, 65, 35, 50, 72, 40, 0, 109, 109, 105, 115, 115, 105, 101, 3, 49, 2, 40, 65, 37, 89, 2, 37, 0, 109, 97, 116, 105, 2, 25, 3, 49, 2, 40, 65, 115, 47, 2, 37, 0, 101, 118, 101, 114, 2, 116, 3, 49, 2, 40, 83, 112, 34, 0, 4, 114, 2, 115, 101, 116, 3, 49, 2, 110, 34, 0, 114, 8, 2, 100, 17, 65, 0, 114, 114, 101, 107, 116, 105, 101, 119, 101, 3, 49, 2, 110, 34, 2, 108, 49, 47, 37, 84, 13, 0, 114, 114, 105, 103, 2, 101, 3, 49, 2, 110, 34, 13, 136, 0, 4, 114, 116, 2, 115, 105, 103, 116, 105, 103, 3, 49, 2, 110, 34, 47, 0, 114, 116, 2, 115, 116, 111, 110, 100, 0, 114, 112, 111, 2, 114, 97, 97, 108, 3, 49, 2, 110, 34, 48, 13, 0, 112, 117, 2, 108, 17, 65, 3, 49, 2, 110, 48, 2, 118, 0, 107, 107, 101, 8, 2, 17, 67, 3, 49, 2, 110, 49, 13, 0, 110, 8, 2, 17, 67, 21, 14, 128, 132, 131, 3, 49, 2, 110, 50, 0, 110, 116, 114, 97, 2, 100, 105, 107, 115, 3, 49, 2, 110, 50, 47, 34, 2, 35, 0, 110, 116, 114, 97, 115, 101, 112, 3, 49, 2, 110, 50, 47, 34, 2, 35, 89, 108, 48, 0, 110, 116, 114, 111, 118, 101, 114, 2, 115, 3, 49, 2, 110, 50, 47, 34, 2, 40, 84, 112, 34, 0, 110, 116, 114, 97, 112, 2, 115, 105, 101, 3, 49, 2, 110, 50, 47, 34, 35, 48, 0, 110, 116, 114, 97, 107, 8, 3, 49, 2, 110, 50, 47, 34, 35, 49, 0, 110, 116, 114, 97, 115, 8, 3, 49, 2, 110, 50, 47, 34, 35, 89, 0, 110, 116, 97, 107, 2, 17, 65, 3, 49, 2, 110, 50, 47, 35, 49, 10, 0, 110, 100, 101, 110, 2, 115, 101, 3, 49, 2, 110, 50, 72, 2, 108, 50, 0, 110, 102, 101, 114, 2, 101, 3, 49, 2, 110, 50, 83, 13, 34, 0, 110, 102, 101, 114, 101, 110, 3, 49, 2, 110, 50, 83, 13, 34, 108, 50, 0, 4, 110, 115, 117, 108, 2, 17, 65, 3, 49, 2, 110, 50, 89, 2, 111, 55, 0, 110, 115, 117, 108, 2, 116, 97, 110, 116, 0, 110, 115, 101, 110, 2, 116, 114, 105, 101, 3, 49, 2, 110, 50, 89, 7, 108, 50, 0, 110, 115, 101, 2, 107, 119, 101, 110, 3, 49, 2, 110, 50, 89, 13, 0, 110, 115, 101, 114, 116, 105, 110, 97, 3, 49, 2, 110, 50, 89, 13, 34, 47, 37, 50, 2, 35, 0, 110, 115, 101, 114, 118, 3, 49, 2, 110, 50, 89, 13, 34, 84, 0, 110, 115, 101, 110, 2, 116, 114, 3, 49, 2, 110, 50, 89, 13, 50, 0, 110, 115, 105, 100, 101, 2, 114, 17, 65, 3, 49, 2, 110, 50, 89, 13, 72, 13, 0, 110, 115, 105, 115, 116, 3, 49, 2, 110, 50, 89, 13, 89, 47, 0, 110, 115, 116, 105, 2, 116, 117, 115, 105, 3, 49, 2, 110, 50, 89, 47, 13, 0, 110, 115, 116, 97, 98, 101, 108, 3, 49, 2, 110, 50, 89, 47, 115, 71, 13, 55, 0, 110, 115, 101, 112, 2, 17, 65, 3, 49, 2, 110, 50, 89, 108, 48, 10, 0, 4, 108, 2, 106, 97, 110, 3, 49, 2, 110, 55, 0, 108, 2, 119, 121, 110, 0, 4, 109, 2, 112, 108, 17, 65, 3, 49, 2, 110, 65, 0, 109, 2, 112, 111, 115, 105, 115, 105, 101, 0, 109, 109, 97, 110, 2, 100, 17, 65, 3, 49, 2, 110, 65, 2, 35, 50, 0, 109, 109, 101, 114, 2, 115, 105, 3, 49, 2, 110, 65, 2, 112, 34, 0, 109, 109, 117, 2, 110, 97, 3, 49, 2, 110, 65, 2, 118, 0, 109, 105, 2, 116, 101, 101, 3, 49, 2, 110, 65, 13, 0, 109, 109, 101, 110, 2, 116, 97, 3, 49, 2, 110, 65, 13, 50, 0, 109, 109, 105, 115, 115, 97, 114, 105, 2, 97, 3, 49, 2, 110, 65, 13, 89, 2, 35, 34, 2, 37, 0, 109, 112, 97, 110, 2, 106, 105, 101, 3, 49, 2, 110, 65, 48, 2, 35, 50, 0, 109, 112, 114, 111, 2, 109, 105, 101, 3, 49, 2, 110, 65, 48, 34, 2, 40, 0, 109, 107, 111, 109, 109, 101, 114, 3, 49, 2, 110, 65, 49, 110, 65, 13, 34, 0, 109, 98, 101, 114, 115, 3, 49, 2, 110, 65, 71, 113, 34, 89, 0, 109, 98, 117, 105, 115, 3, 49, 2, 110, 65, 71, 127, 89, 0, 110, 103, 2, 111, 116, 111, 109, 105, 101, 3, 49, 2, 110, 68, 81, 0, 4, 115, 2, 109, 101, 116, 3, 49, 2, 110, 89, 0, 115, 2, 116, 117, 0, 115, 109, 111, 2, 112, 111, 108, 105, 3, 49, 2, 110, 89, 65, 2, 40, 0, 115, 109, 101, 2, 116, 105, 101, 107, 3, 49, 2, 110, 89, 65, 13, 0, 107, 97, 2, 195, 175, 3, 49, 2, 117, 49, 2, 35, 0, 110, 105, 110, 103, 2, 105, 110, 3, 49, 2, 117, 50, 13, 68, 0, 100, 101, 2, 114, 105, 110, 103, 3, 49, 2, 117, 72, 116, 0, 117, 2, 115, 97, 21, 3, 49, 2, 120, 0, 108, 111, 2, 115, 115, 97, 3, 49, 4, 110, 55, 40, 0, 110, 103, 111, 2, 25, 3, 49, 4, 110, 68, 81, 40, 0, 110, 8, 2, 100, 105, 103, 3, 49, 6, 110, 50, 0, 110, 116, 114, 97, 8, 2, 25, 14, 128, 132, 134, 3, 49, 6, 110, 50, 47, 34, 35, 0, 108, 108, 101, 103, 101, 115, 2, 32, 3, 49, 6, 110, 55, 37, 75, 13, 89, 0, 101, 2, 114, 101, 110, 100, 3, 49, 40, 0, 101, 195, 171, 108, 3, 49, 40, 12, 55, 0, 112, 2, 111, 3, 49, 110, 48, 19, 0, 110, 2, 115, 117, 108, 3, 49, 110, 50, 0, 110, 110, 101, 107, 116, 101, 101, 114, 3, 49, 110, 50, 108, 49, 47, 6, 116, 34, 0, 108, 111, 110, 101, 108, 3, 49, 110, 55, 13, 50, 6, 112, 55, 0, 108, 108, 101, 103, 101, 3, 49, 110, 55, 37, 75, 0, 110, 107, 101, 108, 3, 49, 110, 68, 49, 13, 55, 0, 110, 107, 97, 8, 2, 25, 3, 49, 110, 68, 49, 35, 0, 115, 2, 116, 101, 114, 109, 3, 49, 110, 89, 0, 115, 116, 101, 3, 49, 110, 89, 47, 13, 0, 98, 114, 97, 3, 49, 117, 71, 34, 35, 0, 7, 6, 109, 97, 0, 110, 117, 2, 115, 107, 3, 4, 65, 35, 50, 118, 0, 4, 2, 103, 105, 115, 116, 101, 114, 3, 65, 2, 35, 0, 2, 103, 114, 105, 101, 116, 0, 2, 104, 17, 65, 0, 2, 107, 97, 115, 115, 97, 114, 0, 2, 107, 105, 101, 116, 105, 101, 0, 2, 107, 114, 105, 101, 108, 0, 2, 116, 101, 115, 105, 115, 0, 2, 116, 114, 0, 8, 2, 100, 0, 8, 2, 114, 17, 65, 0, 2, 114, 105, 116, 122, 3, 65, 2, 35, 6, 0, 114, 2, 115, 106, 101, 3, 65, 2, 35, 34, 0, 114, 105, 111, 2, 110, 101, 116, 3, 65, 2, 35, 34, 2, 37, 2, 40, 0, 114, 105, 101, 1, 21, 2, 32, 3, 65, 2, 35, 34, 6, 37, 0, 114, 105, 2, 116, 105, 101, 109, 3, 65, 2, 35, 34, 13, 0, 114, 105, 110, 101, 2, 25, 3, 65, 2, 35, 34, 37, 50, 13, 0, 114, 109, 111, 2, 115, 101, 116, 3, 65, 2, 35, 34, 65, 2, 40, 0, 114, 109, 101, 108, 97, 100, 101, 3, 65, 2, 35, 34, 65, 13, 55, 115, 72, 13, 0, 114, 103, 97, 2, 114, 105, 3, 65, 2, 35, 34, 136, 2, 35, 0, 116, 101, 114, 105, 2, 17, 65, 21, 3, 65, 2, 35, 47, 2, 116, 34, 2, 37, 0, 116, 101, 2, 109, 97, 116, 105, 3, 65, 2, 35, 47, 13, 0, 116, 101, 114, 105, 101, 2, 12, 3, 65, 2, 35, 47, 116, 34, 2, 37, 0, 107, 97, 2, 112, 97, 97, 110, 3, 65, 2, 35, 49, 2, 35, 0, 99, 97, 100, 97, 109, 105, 97, 3, 65, 2, 35, 49, 2, 35, 72, 115, 65, 2, 37, 38, 2, 35, 0, 99, 104, 105, 97, 118, 101, 3, 65, 2, 35, 49, 2, 37, 2, 35, 84, 108, 0, 107, 115, 105, 2, 109, 97, 21, 3, 65, 2, 35, 49, 89, 2, 37, 0, 107, 97, 98, 101, 114, 3, 65, 2, 35, 49, 115, 71, 13, 34, 0, 4, 110, 2, 100, 97, 3, 65, 2, 35, 50, 0, 110, 2, 104, 97, 102, 116, 0, 110, 2, 109, 111, 101, 0, 110, 2, 115, 106, 101, 116, 0, 110, 105, 2, 107, 117, 3, 65, 2, 35, 50, 2, 37, 0, 110, 105, 112, 117, 3, 65, 2, 35, 50, 2, 37, 48, 2, 118, 0, 4, 110, 101, 2, 119, 97, 108, 101, 3, 65, 2, 35, 50, 13, 0, 110, 110, 101, 2, 107, 121, 110, 0, 110, 106, 105, 2, 102, 105, 101, 3, 65, 2, 35, 50, 57, 13, 0, 110, 100, 111, 2, 108, 105, 101, 110, 3, 65, 2, 35, 50, 72, 2, 40, 0, 110, 101, 2, 108, 3, 65, 2, 35, 50, 112, 0, 108, 2, 103, 97, 115, 3, 65, 2, 35, 55, 0, 108, 97, 2, 103, 105, 101, 116, 3, 65, 2, 35, 55, 2, 35, 0, 108, 116, 101, 8, 2, 115, 17, 65, 3, 65, 2, 35, 55, 47, 116, 0, 109, 2, 112, 111, 101, 114, 3, 65, 2, 35, 65, 0, 115, 111, 2, 99, 104, 105, 115, 3, 65, 2, 35, 89, 2, 40, 0, 99, 101, 100, 111, 2, 110, 17, 65, 3, 65, 2, 35, 89, 13, 72, 117, 0, 115, 116, 101, 107, 116, 111, 2, 109, 3, 65, 2, 35, 89, 47, 108, 49, 47, 2, 40, 0, 115, 107, 101, 114, 2, 97, 100, 101, 3, 65, 2, 35, 89, 49, 13, 34, 0, 115, 107, 97, 114, 97, 3, 65, 2, 35, 89, 49, 115, 34, 2, 35, 0, 115, 106, 105, 2, 110, 97, 21, 3, 65, 2, 35, 91, 2, 37, 0, 103, 2, 110, 17, 65, 21, 3, 65, 2, 35, 136, 0, 103, 97, 2, 115, 121, 110, 3, 65, 2, 35, 136, 2, 35, 0, 103, 105, 115, 2, 116, 114, 97, 3, 65, 2, 35, 136, 2, 37, 89, 0, 103, 97, 2, 108, 105, 101, 3, 65, 2, 35, 136, 35, 0, 110, 105, 97, 2, 107, 3, 65, 2, 115, 50, 2, 37, 38, 2, 35, 0, 106, 101, 115, 116, 117, 3, 65, 2, 115, 57, 13, 89, 47, 2, 118, 0, 106, 101, 115, 116, 101, 105, 116, 108, 105, 3, 65, 2, 115, 57, 13, 89, 47, 123, 47, 55, 13, 0, 100, 101, 2, 108, 105, 101, 3, 65, 2, 115, 72, 13, 0, 121, 111, 110, 110, 97, 105, 115, 101, 3, 65, 2, 123, 57, 2, 40, 50, 123, 12, 88, 0, 116, 105, 103, 1, 21, 3, 65, 6, 115, 47, 13, 136, 0, 116, 105, 101, 115, 3, 65, 6, 115, 47, 37, 89, 0, 110, 105, 101, 114, 3, 65, 13, 50, 37, 12, 34, 0, 115, 106, 105, 101, 110, 3, 65, 13, 91, 37, 50, 0, 114, 97, 116, 2, 111, 110, 3, 65, 35, 34, 2, 35, 47, 0, 114, 97, 116, 104, 111, 110, 3, 65, 35, 34, 2, 35, 47, 2, 110, 50, 10, 0, 114, 109, 101, 114, 3, 65, 35, 34, 65, 13, 34, 10, 0, 107, 105, 101, 1, 21, 2, 115, 105, 101, 3, 65, 35, 49, 6, 37, 0, 107, 114, 97, 110, 107, 97, 1, 21, 3, 65, 35, 49, 34, 6, 35, 50, 49, 35, 0, 110, 105, 102, 101, 115, 3, 65, 35, 50, 37, 83, 108, 89, 0, 108, 1, 10, 2, 32, 14, 128, 128, 131, 3, 65, 35, 55, 0, 108, 97, 114, 105, 97, 3, 65, 35, 55, 6, 115, 34, 37, 35, 0, 108, 108, 101, 115, 2, 32, 3, 65, 35, 55, 13, 89, 0, 108, 118, 97, 2, 25, 3, 65, 35, 55, 83, 2, 35, 0, 110, 103, 111, 8, 3, 65, 35, 68, 81, 2, 40, 0, 115, 107, 101, 114, 3, 65, 35, 89, 49, 13, 34, 0, 2, 116, 114, 105, 107, 25, 3, 65, 115, 0, 110, 105, 2, 97, 107, 25, 3, 65, 115, 50, 2, 37, 0, 2, 98, 105, 101, 107, 3, 89, 0, 7, 6, 109, 101, 0, 116, 101, 2, 111, 3, 65, 2, 37, 47, 2, 37, 0, 116, 101, 111, 2, 114, 105, 101, 116, 3, 65, 2, 37, 47, 2, 37, 2, 40, 0, 116, 97, 8, 2, 17, 67, 3, 65, 2, 108, 47, 2, 35, 0, 110, 2, 116, 97, 115, 105, 101, 3, 65, 2, 108, 50, 0, 110, 111, 112, 111, 117, 2, 115, 97, 3, 65, 2, 108, 50, 2, 40, 48, 2, 120, 0, 110, 117, 101, 2, 116, 3, 65, 2, 108, 50, 2, 118, 12, 38, 108, 0, 110, 116, 97, 108, 105, 2, 116, 101, 105, 116, 3, 65, 2, 108, 50, 47, 2, 35, 55, 2, 37, 0, 110, 115, 116, 114, 117, 3, 65, 2, 108, 50, 89, 47, 34, 2, 118, 0, 4, 108, 97, 110, 99, 104, 3, 65, 2, 108, 55, 2, 35, 68, 49, 0, 108, 97, 110, 107, 0, 4, 108, 97, 110, 99, 104, 111, 108, 105, 101, 2, 32, 24, 3, 65, 2, 108, 55, 2, 35, 68, 49, 2, 117, 55, 37, 0, 108, 97, 110, 107, 111, 108, 105, 101, 2, 32, 24, 0, 108, 111, 100, 105, 8, 2, 101, 117, 3, 65, 2, 108, 55, 2, 40, 72, 2, 37, 0, 109, 2, 98, 114, 97, 3, 65, 2, 108, 65, 0, 109, 111, 2, 114, 17, 65, 3, 65, 2, 108, 65, 2, 40, 0, 109, 111, 114, 97, 2, 98, 105, 108, 105, 3, 65, 2, 108, 65, 2, 110, 34, 2, 35, 0, 109, 111, 2, 114, 105, 17, 65, 3, 65, 2, 108, 65, 117, 0, 100, 105, 2, 116, 17, 65, 3, 65, 2, 108, 72, 2, 37, 0, 100, 105, 116, 101, 2, 114, 114, 101, 3, 65, 2, 108, 72, 2, 37, 47, 13, 0, 100, 105, 115, 105, 2, 110, 97, 21, 3, 65, 2, 108, 72, 13, 89, 2, 37, 0, 4, 101, 2, 100, 111, 195, 171, 3, 65, 2, 116, 0, 101, 2, 119, 97, 114, 0, 101, 114, 2, 118, 111, 117, 100, 105, 103, 3, 65, 2, 116, 34, 0, 101, 114, 100, 101, 114, 2, 106, 97, 114, 3, 65, 2, 116, 34, 72, 13, 34, 0, 4, 100, 101, 2, 100, 111, 195, 171, 3, 65, 2, 116, 72, 13, 0, 100, 101, 2, 112, 108, 105, 103, 0, 100, 101, 8, 2, 108, 121, 0, 101, 115, 116, 101, 114, 101, 3, 65, 2, 116, 89, 47, 13, 34, 108, 0, 110, 116, 106, 105, 101, 3, 65, 6, 108, 37, 68, 80, 37, 0, 110, 116, 3, 65, 6, 108, 50, 47, 0, 108, 111, 8, 2, 100, 114, 3, 65, 6, 108, 55, 40, 0, 110, 105, 110, 103, 3, 65, 6, 116, 50, 13, 68, 0, 100, 101, 8, 2, 21, 14, 128, 132, 132, 3, 65, 6, 116, 72, 13, 0, 101, 103, 101, 8, 2, 21, 14, 128, 132, 133, 3, 65, 6, 116, 136, 13, 0, 4, 2, 106, 117, 102, 3, 65, 13, 0, 2, 108, 97, 97, 116, 115, 0, 2, 114, 105, 101, 116, 101, 0, 2, 116, 111, 100, 0, 8, 2, 100, 117, 17, 67, 0, 114, 105, 110, 111, 3, 65, 13, 34, 37, 50, 2, 40, 0, 116, 97, 108, 101, 3, 65, 13, 47, 6, 115, 55, 13, 0, 116, 111, 100, 101, 3, 65, 13, 47, 6, 117, 72, 13, 0, 116, 97, 97, 2, 17, 67, 3, 65, 13, 47, 115, 0, 107, 97, 97, 114, 3, 65, 13, 49, 6, 115, 34, 0, 107, 97, 97, 114, 103, 101, 3, 65, 13, 49, 6, 115, 34, 136, 13, 0, 110, 101, 101, 114, 3, 65, 13, 50, 6, 116, 34, 0, 110, 101, 114, 101, 3, 65, 13, 50, 6, 116, 34, 13, 0, 108, 111, 100, 105, 101, 115, 8, 3, 65, 13, 55, 6, 117, 72, 37, 89, 0, 100, 97, 108, 2, 106, 111, 110, 3, 65, 13, 72, 2, 35, 55, 0, 100, 105, 115, 121, 110, 101, 3, 65, 13, 72, 13, 89, 123, 50, 13, 0, 100, 97, 108, 106, 101, 3, 65, 13, 72, 35, 55, 57, 13, 0, 118, 114, 111, 117, 3, 65, 13, 83, 34, 6, 120, 0, 103, 97, 110, 105, 101, 115, 3, 65, 13, 136, 6, 115, 50, 37, 89, 0, 2, 100, 105, 117, 109, 3, 65, 37, 12, 0, 100, 105, 97, 3, 65, 37, 12, 72, 37, 12, 57, 35, 4, 0, 2, 114, 114, 105, 101, 3, 65, 108, 0, 116, 101, 101, 110, 3, 65, 108, 47, 10, 6, 116, 50, 0, 116, 111, 100, 105, 115, 3, 65, 108, 47, 40, 72, 6, 109, 89, 0, 110, 105, 110, 103, 2, 105, 116, 105, 115, 3, 65, 108, 50, 13, 68, 136, 0, 110, 116, 101, 101, 2, 17, 67, 3, 65, 108, 50, 47, 6, 116, 0, 110, 116, 101, 114, 105, 110, 103, 3, 65, 108, 50, 47, 6, 116, 34, 13, 68, 0, 110, 116, 101, 108, 101, 2, 25, 3, 65, 108, 50, 47, 6, 116, 55, 13, 0, 108, 111, 100, 105, 101, 8, 3, 65, 108, 55, 40, 72, 6, 37, 0, 110, 103, 2, 115, 101, 108, 3, 65, 108, 68, 0, 4, 115, 1, 102, 101, 104, 2, 32, 3, 65, 108, 89, 0, 115, 1, 108, 101, 102, 97, 116, 2, 32, 0, 115, 1, 115, 17, 65, 17, 65, 2, 32, 0, 115, 1, 115, 17, 67, 2, 32, 0, 115, 1, 121, 110, 115, 2, 32, 0, 115, 8, 2, 97, 97, 110, 3, 65, 108, 89, 10, 0, 4, 114, 107, 1, 101, 116, 3, 65, 112, 34, 49, 0, 114, 107, 2, 32, 0, 114, 107, 101, 2, 32, 3, 65, 112, 34, 49, 13, 0, 2, 116, 114, 117, 109, 3, 65, 116, 0, 114, 101, 1, 17, 67, 21, 2, 32, 3, 65, 116, 12, 34, 13, 0, 116, 101, 108, 8, 3, 65, 116, 47, 13, 55, 0, 7, 6, 109, 105, 0, 2, 110, 101, 117, 114, 3, 65, 2, 37, 0, 114, 97, 107, 117, 2, 108, 101, 117, 115, 3, 65, 2, 37, 34, 2, 35, 49, 2, 118, 0, 107, 114, 111, 98, 101, 3, 65, 2, 37, 49, 34, 117, 71, 13, 0, 110, 105, 2, 109, 97, 21, 3, 65, 2, 37, 50, 2, 37, 0, 97, 97, 117, 3, 65, 2, 37, 129, 12, 0, 110, 97, 103, 3, 65, 6, 109, 50, 35, 136, 0, 100, 100, 97, 103, 101, 116, 101, 3, 65, 6, 109, 72, 35, 136, 10, 116, 47, 13, 0, 115, 2, 108, 105, 107, 3, 65, 6, 109, 89, 0, 4, 2, 109, 105, 101, 107, 3, 65, 13, 0, 2, 109, 111, 115, 97, 0, 2, 115, 115, 105, 101, 108, 0, 114, 97, 107, 101, 108, 3, 65, 13, 34, 115, 49, 13, 55, 0, 110, 97, 114, 101, 2, 116, 3, 65, 13, 50, 2, 35, 34, 108, 0, 110, 105, 115, 116, 101, 114, 115, 3, 65, 13, 50, 6, 109, 89, 47, 13, 34, 89, 0, 110, 117, 2, 115, 107, 117, 3, 65, 13, 50, 13, 0, 4, 110, 100, 101, 114, 2, 106, 97, 114, 3, 65, 13, 50, 13, 34, 0, 110, 101, 114, 2, 17, 65, 0, 110, 105, 115, 116, 101, 114, 105, 3, 65, 13, 50, 13, 89, 47, 2, 116, 34, 2, 37, 0, 110, 105, 115, 116, 101, 2, 114, 105, 101, 25, 3, 65, 13, 50, 13, 89, 47, 116, 0, 108, 2, 106, 17, 65, 3, 65, 13, 55, 0, 108, 105, 116, 3, 65, 13, 55, 13, 47, 0, 108, 105, 101, 117, 3, 65, 13, 55, 57, 118, 0, 108, 108, 101, 2, 110, 110, 105, 17, 65, 3, 65, 13, 55, 108, 0, 100, 100, 101, 108, 2, 106, 97, 114, 105, 3, 65, 13, 72, 13, 55, 0, 4, 115, 2, 103, 105, 115, 3, 65, 13, 89, 0, 115, 2, 103, 117, 110, 0, 115, 2, 104, 97, 0, 115, 2, 108, 0, 115, 2, 110, 111, 101, 103, 0, 115, 2, 112, 108, 97, 97, 115, 0, 115, 2, 114, 97, 98, 101, 108, 0, 115, 2, 114, 101, 107, 101, 110, 0, 115, 2, 116, 105, 101, 107, 0, 115, 2, 116, 114, 111, 111, 115, 0, 115, 2, 118, 111, 114, 109, 0, 115, 8, 2, 105, 110, 14, 128, 132, 131, 0, 115, 8, 2, 109, 0, 115, 101, 2, 114, 97, 0, 115, 116, 101, 114, 2, 105, 101, 117, 115, 3, 65, 13, 89, 47, 116, 34, 0, 115, 107, 101, 2, 110, 3, 65, 13, 89, 49, 108, 0, 2, 115, 115, 105, 101, 3, 65, 37, 0, 107, 114, 2, 111, 3, 65, 37, 49, 34, 0, 100, 100, 101, 2, 108, 3, 65, 109, 72, 13, 0, 100, 100, 101, 108, 108, 105, 2, 107, 3, 65, 109, 72, 13, 55, 13, 0, 4, 115, 2, 108, 97, 109, 112, 3, 65, 109, 89, 0, 115, 2, 108, 111, 111, 112, 0, 115, 2, 111, 0, 7, 6, 109, 111, 0, 4, 2, 112, 97, 110, 105, 3, 65, 2, 40, 0, 101, 2, 114, 97, 115, 0, 116, 111, 114, 2, 105, 101, 3, 65, 2, 40, 47, 117, 34, 0, 4, 108, 101, 115, 2, 25, 3, 65, 2, 40, 55, 108, 89, 0, 108, 101, 115, 2, 116, 101, 32, 0, 100, 101, 114, 110, 3, 65, 2, 40, 72, 112, 34, 14, 50, 0, 104, 97, 109, 109, 101, 100, 2, 97, 3, 65, 2, 40, 107, 2, 35, 65, 13, 72, 0, 4, 2, 100, 117, 108, 17, 65, 3, 65, 2, 110, 0, 2, 115, 107, 101, 101, 0, 4, 114, 2, 102, 111, 115, 101, 3, 65, 2, 110, 34, 0, 114, 8, 2, 17, 67, 21, 0, 114, 102, 2, 111, 116, 111, 109, 105, 101, 3, 65, 2, 110, 34, 83, 0, 122, 122, 97, 114, 101, 108, 108, 97, 3, 65, 2, 110, 47, 89, 2, 35, 34, 112, 55, 2, 35, 0, 110, 2, 116, 101, 117, 114, 3, 65, 2, 110, 50, 0, 110, 105, 116, 2, 101, 3, 65, 2, 110, 50, 2, 37, 47, 0, 110, 117, 2, 109, 101, 110, 116, 3, 65, 2, 110, 50, 2, 118, 0, 110, 101, 2, 116, 195, 170, 114, 3, 65, 2, 110, 50, 13, 0, 110, 100, 101, 114, 2, 17, 65, 3, 65, 2, 110, 50, 72, 116, 34, 0, 108, 101, 115, 2, 116, 17, 65, 3, 65, 2, 110, 55, 13, 89, 0, 110, 8, 2, 103, 111, 21, 3, 65, 2, 110, 68, 0, 100, 101, 2, 108, 108, 101, 21, 3, 65, 2, 110, 72, 13, 0, 100, 101, 114, 97, 2, 116, 17, 65, 3, 65, 2, 110, 72, 13, 34, 2, 35, 0, 100, 101, 114, 97, 2, 116, 111, 114, 25, 3, 65, 2, 110, 72, 13, 34, 115, 0, 2, 110, 97, 114, 103, 3, 65, 2, 117, 0, 116, 105, 101, 2, 17, 67, 3, 65, 2, 117, 47, 37, 0, 110, 97, 114, 103, 105, 101, 2, 32, 24, 3, 65, 2, 117, 50, 2, 35, 34, 136, 37, 0, 110, 111, 2, 103, 97, 3, 65, 2, 117, 50, 2, 117, 0, 110, 111, 112, 111, 2, 108, 105, 3, 65, 2, 117, 50, 2, 117, 48, 2, 40, 0, 100, 101, 2, 108, 3, 65, 2, 117, 72, 112, 0, 115, 97, 2, 195, 175, 101, 107, 3, 65, 2, 117, 89, 2, 35, 0, 115, 97, 109, 2, 98, 105, 101, 107, 3, 65, 2, 117, 89, 2, 35, 65, 0, 101, 105, 116, 101, 3, 65, 6, 126, 47, 13, 0, 100, 101, 8, 3, 65, 7, 117, 72, 13, 0, 101, 100, 115, 119, 105, 108, 108, 105, 103, 3, 65, 40, 47, 89, 84, 6, 109, 55, 13, 136, 0, 114, 114, 8, 2, 105, 3, 65, 110, 34, 0, 114, 115, 8, 2, 21, 3, 65, 110, 34, 89, 0, 110, 110, 105, 107, 101, 3, 65, 110, 50, 13, 49, 13, 0, 110, 105, 116, 111, 114, 2, 25, 3, 65, 110, 50, 37, 47, 110, 34, 0, 2, 98, 105, 101, 108, 3, 65, 117, 6, 0, 116, 111, 114, 3, 65, 117, 47, 13, 34, 0, 7, 6, 111, 110, 0, 4, 2, 114, 101, 103, 118, 12, 12, 3, 2, 110, 50, 0, 2, 116, 111, 101, 0, 2, 116, 117, 103, 116, 105, 103, 0, 2, 116, 119, 121, 102, 101, 108, 0, 8, 2, 21, 14, 128, 132, 130, 0, 8, 2, 116, 97, 97, 108, 0, 8, 2, 116, 97, 107, 116, 0, 8, 2, 116, 97, 115, 98, 97, 0, 8, 2, 116, 111, 111, 17, 67, 17, 67, 0, 8, 2, 116, 121, 100, 0, 8, 2, 119, 101, 115, 101, 110, 0, 116, 2, 100, 21, 0, 111, 109, 2, 115, 116, 111, 111, 116, 3, 2, 110, 50, 2, 110, 65, 0, 4, 97, 102, 8, 2, 115, 107, 101, 105, 17, 67, 3, 2, 110, 50, 10, 2, 35, 83, 0, 97, 102, 8, 2, 119, 101, 110, 100, 0, 4, 100, 101, 114, 2, 98, 114, 101, 3, 2, 110, 50, 13, 34, 0, 100, 101, 114, 2, 98, 114, 111, 107, 101, 0, 100, 101, 114, 2, 100, 97, 110, 105, 103, 0, 100, 101, 114, 2, 100, 114, 117, 107, 0, 100, 101, 114, 2, 100, 117, 105, 109, 0, 100, 101, 114, 2, 104, 97, 110, 100, 101, 0, 100, 101, 114, 2, 104, 101, 119, 0, 100, 101, 114, 2, 104, 111, 114, 0, 100, 101, 114, 2, 104, 111, 117, 0, 100, 101, 114, 2, 108, 101, 103, 0, 100, 101, 114, 2, 109, 121, 110, 0, 100, 101, 114, 2, 110, 101, 0, 100, 101, 114, 2, 115, 107, 114, 121, 17, 67, 0, 100, 101, 114, 2, 115, 111, 101, 107, 101, 110, 0, 100, 101, 114, 2, 115, 116, 101, 117, 0, 100, 101, 114, 2, 115, 116, 114, 101, 0, 100, 101, 114, 2, 116, 101, 107, 101, 110, 0, 100, 101, 114, 2, 116, 114, 111, 117, 0, 100, 101, 114, 2, 118, 97, 110, 103, 0, 100, 101, 114, 2, 118, 105, 110, 0, 100, 101, 114, 2, 118, 114, 97, 0, 100, 101, 114, 2, 119, 101, 114, 112, 105, 110, 103, 0, 100, 101, 114, 2, 119, 111, 114, 112, 0, 100, 101, 114, 8, 2, 115, 107, 17, 65, 0, 100, 101, 114, 111, 110, 115, 105, 101, 3, 2, 110, 50, 13, 34, 19, 135, 50, 89, 37, 0, 100, 101, 114, 115, 116, 101, 98, 111, 3, 2, 110, 50, 13, 34, 89, 47, 13, 71, 117, 0, 116, 8, 2, 21, 14, 128, 132, 131, 3, 2, 110, 50, 47, 0, 116, 101, 109, 2, 98, 97, 3, 2, 110, 50, 47, 108, 65, 0, 116, 101, 108, 8, 3, 2, 110, 50, 47, 112, 55, 0, 116, 101, 114, 105, 110, 103, 3, 2, 110, 50, 47, 116, 34, 13, 68, 0, 100, 101, 117, 114, 3, 2, 110, 50, 72, 2, 118, 13, 34, 0, 118, 111, 111, 114, 2, 115, 3, 2, 110, 50, 83, 2, 117, 34, 0, 4, 119, 101, 101, 114, 8, 2, 108, 3, 2, 110, 50, 84, 2, 116, 34, 0, 119, 101, 101, 114, 8, 2, 115, 112, 114, 0, 119, 101, 101, 114, 8, 2, 115, 116, 97, 97, 110, 0, 104, 101, 105, 108, 2, 115, 112, 101, 108, 3, 2, 110, 50, 107, 2, 123, 55, 0, 104, 101, 105, 108, 2, 105, 103, 3, 2, 110, 50, 107, 6, 123, 55, 0, 103, 101, 101, 115, 8, 3, 2, 110, 50, 136, 2, 116, 89, 0, 103, 101, 108, 2, 100, 105, 103, 3, 2, 110, 50, 136, 112, 55, 0, 103, 114, 101, 115, 1, 107, 3, 2, 110, 68, 136, 34, 108, 89, 0, 4, 2, 115, 107, 117, 108, 100, 32, 24, 3, 6, 110, 50, 0, 8, 2, 119, 17, 65, 115, 0, 100, 101, 114, 103, 101, 8, 2, 21, 14, 128, 132, 135, 3, 6, 110, 50, 13, 34, 136, 13, 0, 105, 101, 115, 1, 21, 3, 6, 117, 50, 37, 89, 0, 4, 100, 101, 114, 2, 115, 101, 107, 114, 3, 7, 110, 50, 13, 34, 0, 100, 101, 114, 2, 119, 121, 115, 17, 67, 21, 0, 100, 101, 114, 8, 2, 101, 110, 17, 67, 3, 7, 110, 50, 13, 34, 10, 0, 104, 101, 105, 108, 3, 7, 110, 50, 107, 123, 55, 0, 121, 1, 21, 2, 32, 3, 21, 0, 111, 111, 109, 3, 40, 50, 6, 117, 65, 0, 111, 109, 101, 3, 40, 50, 6, 117, 65, 13, 0, 111, 109, 105, 101, 115, 3, 40, 50, 6, 117, 65, 37, 89, 0, 111, 109, 105, 101, 3, 40, 50, 40, 65, 6, 37, 0, 4, 2, 100, 105, 101, 114, 3, 110, 50, 0, 2, 108, 97, 110, 103, 115, 0, 2, 115, 105, 110, 32, 24, 0, 2, 116, 117, 103, 0, 8, 2, 102, 105, 107, 115, 0, 8, 2, 107, 97, 110, 116, 0, 8, 2, 107, 111, 115, 116, 101, 0, 8, 2, 107, 114, 117, 105, 100, 0, 8, 2, 108, 117, 115, 0, 8, 2, 112, 97, 97, 114, 0, 8, 2, 116, 117, 105, 17, 67, 0, 8, 2, 117, 105, 116, 103, 101, 21, 12, 12, 14, 128, 132, 130, 3, 110, 50, 10, 0, 117, 105, 116, 8, 2, 21, 14, 128, 132, 133, 3, 110, 50, 10, 127, 47, 0, 4, 100, 101, 114, 3, 110, 50, 13, 34, 0, 100, 101, 114, 2, 104, 111, 117, 100, 25, 0, 100, 101, 114, 2, 104, 111, 117, 100, 101, 32, 0, 100, 101, 114, 2, 115, 107, 101, 105, 100, 32, 24, 0, 100, 101, 114, 119, 121, 115, 101, 114, 2, 97, 3, 110, 50, 13, 34, 84, 6, 123, 89, 13, 34, 10, 0, 114, 101, 103, 2, 25, 3, 110, 50, 34, 112, 136, 0, 110, 105, 101, 8, 3, 110, 50, 37, 0, 116, 101, 118, 114, 101, 100, 101, 3, 110, 50, 47, 13, 83, 34, 6, 116, 72, 13, 0, 116, 101, 101, 110, 115, 101, 103, 3, 110, 50, 47, 116, 50, 89, 6, 112, 136, 0, 119, 101, 101, 114, 8, 3, 110, 50, 84, 116, 34, 0, 4, 103, 101, 2, 100, 105, 101, 114, 116, 3, 110, 50, 136, 13, 0, 103, 101, 8, 2, 21, 14, 128, 132, 132, 0, 103, 101, 114, 105, 101, 102, 108, 105, 2, 107, 3, 110, 50, 136, 13, 34, 6, 37, 83, 55, 13, 0, 103, 101, 108, 111, 111, 102, 108, 105, 8, 2, 107, 3, 110, 50, 136, 13, 55, 6, 117, 83, 55, 13, 0, 103, 101, 109, 97, 107, 108, 105, 2, 107, 3, 110, 50, 136, 13, 65, 6, 35, 49, 55, 13, 0, 105, 107, 115, 3, 117, 50, 13, 49, 89, 0, 4, 105, 101, 1, 108, 111, 107, 3, 117, 50, 37, 0, 105, 101, 1, 109, 101, 114, 101, 115, 2, 25, 0, 105, 101, 115, 1, 112, 21, 3, 117, 50, 37, 89, 0, 117, 115, 8, 3, 117, 50, 111, 89, 0, 4, 100, 106, 105, 101, 3, 124, 68, 80, 37, 0, 116, 106, 105, 101, 0, 4, 115, 1, 98, 3, 135, 50, 89, 0, 115, 1, 100, 0, 115, 1, 103, 0, 115, 1, 114, 102, 0, 4, 103, 101, 1, 21, 2, 108, 117, 107, 21, 3, 135, 68, 136, 13, 0, 103, 101, 2, 108, 117, 107, 32, 0, 103, 101, 2, 108, 117, 107, 107, 101, 32, 0, 103, 101, 2, 108, 117, 107, 107, 105, 101, 0, 103, 101, 2, 108, 117, 107, 115, 0, 103, 101, 118, 97, 2, 108, 3, 135, 68, 136, 13, 83, 35, 0, 7, 6, 111, 111, 0, 4, 114, 2, 98, 108, 121, 119, 3, 2, 117, 34, 0, 114, 2, 98, 114, 117, 103, 0, 114, 2, 100, 105, 110, 107, 0, 114, 2, 100, 111, 110, 100, 101, 114, 0, 114, 2, 100, 114, 97, 97, 103, 0, 114, 2, 103, 97, 110, 107, 0, 114, 2, 104, 101, 101, 114, 115, 0, 114, 2, 107, 111, 111, 109, 0, 114, 2, 108, 97, 97, 105, 100, 0, 114, 2, 108, 97, 109, 115, 0, 114, 2, 109, 101, 101, 115, 116, 101, 114, 0, 114, 2, 114, 101, 101, 100, 0, 114, 2, 114, 111, 109, 112, 101, 108, 0, 114, 2, 115, 105, 103, 116, 0, 114, 2, 115, 107, 114, 121, 0, 114, 2, 115, 112, 114, 111, 110, 107, 0, 114, 2, 115, 116, 117, 114, 0, 114, 2, 116, 114, 0, 114, 2, 116, 117, 105, 103, 0, 114, 8, 2, 100, 97, 103, 0, 114, 8, 2, 100, 101, 110, 107, 0, 114, 8, 2, 100, 111, 101, 110, 0, 114, 8, 2, 100, 114, 121, 17, 67, 0, 114, 8, 2, 103, 114, 111, 101, 105, 0, 114, 8, 2, 104, 97, 97, 115, 0, 114, 8, 2, 104, 111, 111, 102, 115, 0, 114, 8, 2, 112, 101, 105, 110, 115, 0, 114, 8, 2, 115, 107, 97, 100, 117, 0, 114, 8, 2, 115, 107, 97, 116, 0, 114, 8, 2, 115, 116, 101, 108, 112, 0, 114, 8, 2, 115, 116, 114, 111, 109, 105, 0, 114, 8, 2, 118, 108, 101, 117, 101, 108, 0, 114, 8, 2, 118, 108, 111, 101, 100, 105, 103, 0, 114, 8, 2, 119, 0, 4, 114, 2, 101, 101, 110, 3, 2, 117, 34, 10, 0, 114, 2, 101, 101, 110, 103, 101, 0, 114, 2, 101, 101, 110, 115, 21, 0, 114, 2, 101, 101, 116, 0, 114, 2, 101, 105, 115, 0, 114, 101, 114, 102, 108, 105, 107, 3, 2, 117, 34, 10, 112, 34, 83, 55, 13, 49, 0, 114, 100, 119, 97, 114, 115, 8, 3, 2, 117, 34, 72, 58, 35, 34, 89, 0, 114, 100, 101, 8, 2, 107, 3, 2, 117, 34, 72, 112, 0, 114, 115, 116, 117, 117, 114, 115, 8, 3, 2, 117, 34, 89, 47, 118, 12, 34, 89, 0, 114, 115, 97, 97, 107, 108, 105, 107, 3, 2, 117, 34, 89, 115, 49, 55, 13, 49, 0, 114, 114, 101, 2, 100, 17, 65, 3, 2, 117, 34, 116, 0, 116, 2, 109, 111, 101, 100, 105, 103, 3, 2, 117, 47, 0, 4, 103, 2, 108, 111, 112, 3, 2, 117, 136, 0, 103, 2, 108, 117, 105, 107, 0, 114, 2, 101, 101, 110, 21, 21, 3, 4, 117, 34, 10, 0, 114, 2, 119, 105, 103, 3, 6, 117, 34, 0, 112, 103, 101, 8, 2, 21, 14, 128, 132, 133, 3, 6, 117, 48, 136, 13, 0, 3, 117, 0, 4, 114, 2, 115, 105, 103, 116, 121, 100, 3, 117, 34, 0, 114, 2, 116, 114, 101, 107, 0, 114, 8, 2, 116, 114, 111, 109, 0, 114, 8, 2, 104, 97, 110, 100, 21, 3, 117, 34, 6, 0, 114, 107, 111, 101, 112, 101, 108, 3, 117, 34, 49, 6, 40, 48, 13, 55, 0, 114, 108, 101, 100, 101, 8, 3, 117, 34, 55, 6, 116, 72, 13, 0, 114, 108, 101, 2, 119, 17, 65, 110, 3, 117, 34, 55, 7, 116, 0, 114, 108, 101, 2, 108, 25, 3, 117, 34, 55, 112, 0, 114, 98, 111, 100, 105, 103, 3, 117, 34, 71, 6, 117, 72, 13, 136, 0, 114, 98, 108, 117, 102, 3, 117, 34, 71, 55, 6, 111, 83, 0, 114, 100, 114, 101, 119, 101, 3, 117, 34, 72, 34, 6, 116, 84, 13, 0, 109, 98, 108, 105, 107, 108, 105, 107, 3, 117, 65, 71, 55, 6, 109, 49, 55, 13, 49, 0, 4, 105, 3, 125, 0, 121, 0, 4, 110, 100, 106, 105, 101, 3, 125, 68, 49, 37, 0, 110, 116, 106, 105, 101, 0, 4, 100, 106, 105, 101, 3, 125, 80, 37, 0, 116, 106, 105, 101, 0, 7, 6, 111, 112, 0, 4, 2, 104, 111, 117, 100, 101, 3, 2, 110, 48, 0, 2, 108, 101, 116, 116, 0, 2, 110, 117, 117, 116, 0, 2, 114, 111, 101, 114, 105, 103, 0, 2, 114, 117, 105, 101, 110, 0, 2, 115, 105, 101, 110, 98, 0, 2, 115, 105, 111, 110, 101, 21, 0, 2, 115, 116, 97, 110, 100, 105, 103, 0, 2, 119, 105, 110, 100, 101, 0, 8, 2, 114, 101, 103, 0, 8, 2, 115, 121, 0, 8, 2, 118, 97, 108, 108, 0, 8, 2, 118, 108, 105, 101, 195, 171, 0, 112, 111, 114, 2, 116, 117, 3, 2, 110, 48, 2, 110, 34, 0, 112, 101, 114, 2, 118, 108, 97, 107, 107, 105, 3, 2, 110, 48, 13, 34, 0, 112, 111, 110, 2, 17, 65, 3, 2, 110, 48, 13, 50, 0, 112, 111, 115, 2, 105, 115, 105, 101, 3, 2, 110, 48, 13, 88, 0, 116, 105, 2, 109, 17, 65, 3, 2, 110, 48, 47, 2, 37, 0, 109, 101, 114, 107, 108, 105, 8, 2, 107, 3, 2, 110, 48, 65, 112, 34, 49, 55, 13, 0, 115, 101, 116, 108, 105, 107, 3, 2, 110, 48, 89, 108, 47, 55, 13, 49, 0, 115, 105, 103, 116, 101, 108, 105, 8, 2, 107, 3, 2, 110, 48, 89, 109, 136, 47, 13, 55, 13, 0, 101, 114, 8, 2, 17, 65, 3, 2, 117, 48, 13, 34, 0, 101, 114, 97, 115, 105, 101, 3, 2, 117, 48, 13, 34, 115, 89, 37, 0, 101, 110, 2, 98, 3, 2, 117, 48, 13, 50, 0, 8, 2, 21, 14, 128, 132, 130, 3, 6, 110, 48, 0, 103, 101, 8, 2, 21, 14, 128, 132, 132, 3, 6, 110, 48, 136, 13, 0, 103, 101, 101, 2, 12, 3, 6, 110, 48, 136, 116, 0, 1, 17, 67, 10, 2, 105, 103, 3, 6, 117, 48, 0, 101, 101, 110, 1, 25, 3, 10, 2, 110, 48, 10, 116, 50, 0, 97, 97, 116, 3, 40, 48, 6, 115, 47, 0, 4, 97, 116, 105, 101, 115, 3, 40, 48, 6, 115, 47, 37, 89, 0, 97, 116, 105, 101, 115, 0, 97, 116, 105, 101, 3, 40, 48, 35, 47, 6, 37, 0, 2, 111, 102, 102, 101, 114, 3, 110, 48, 0, 112, 101, 114, 3, 110, 48, 13, 34, 0, 116, 101, 108, 3, 110, 48, 47, 112, 55, 0, 115, 112, 114, 97, 97, 107, 3, 110, 48, 89, 48, 34, 115, 49, 0, 105, 110, 105, 101, 3, 117, 48, 6, 37, 50, 37, 0, 4, 101, 2, 108, 3, 117, 48, 13, 0, 101, 8, 2, 25, 0, 101, 8, 2, 114, 105, 103, 0, 101, 114, 97, 2, 25, 3, 117, 48, 13, 34, 2, 35, 0, 101, 110, 2, 12, 3, 117, 48, 13, 50, 0, 105, 117, 109, 3, 117, 48, 37, 111, 65, 0, 117, 8, 2, 115, 3, 117, 48, 111, 0, 7, 6, 112, 97, 0, 114, 97, 2, 17, 67, 3, 4, 48, 35, 34, 35, 0, 4, 2, 103, 111, 100, 17, 65, 3, 48, 2, 35, 0, 2, 110, 101, 108, 101, 0, 2, 110, 105, 101, 107, 0, 2, 112, 105, 101, 114, 0, 2, 112, 105, 114, 117, 115, 0, 2, 115, 105, 102, 105, 0, 2, 115, 116, 101, 108, 0, 2, 116, 114, 17, 65, 0, 8, 2, 107, 107, 97, 0, 8, 2, 115, 116, 101, 105, 0, 8, 2, 115, 116, 111, 0, 8, 2, 116, 17, 65, 0, 112, 2, 98, 114, 111, 101, 107, 17, 65, 17, 67, 0, 114, 8, 2, 17, 67, 17, 65, 3, 48, 2, 35, 34, 0, 114, 111, 2, 100, 105, 3, 48, 2, 35, 34, 2, 40, 0, 114, 116, 105, 2, 115, 97, 3, 48, 2, 35, 34, 47, 2, 37, 0, 114, 116, 105, 2, 116, 117, 3, 48, 2, 35, 34, 47, 13, 0, 114, 108, 101, 2, 109, 101, 110, 116, 3, 48, 2, 35, 34, 55, 13, 0, 114, 109, 101, 2, 115, 97, 97, 110, 3, 48, 2, 35, 34, 65, 13, 0, 116, 105, 101, 2, 25, 24, 3, 48, 2, 35, 47, 6, 37, 0, 116, 114, 105, 2, 21, 3, 48, 2, 35, 47, 34, 2, 37, 0, 116, 114, 105, 97, 114, 2, 103, 97, 3, 48, 2, 35, 47, 34, 2, 37, 2, 35, 34, 0, 116, 114, 111, 2, 108, 108, 101, 3, 48, 2, 35, 47, 34, 2, 40, 0, 116, 195, 169, 3, 48, 2, 35, 47, 116, 0, 112, 97, 106, 97, 3, 48, 2, 35, 48, 6, 115, 37, 35, 0, 4, 112, 101, 2, 103, 97, 97, 105, 3, 48, 2, 35, 48, 13, 0, 112, 112, 101, 2, 114, 121, 0, 112, 97, 119, 101, 114, 3, 48, 2, 35, 48, 115, 84, 13, 34, 0, 107, 105, 115, 116, 97, 110, 3, 48, 2, 35, 49, 2, 37, 89, 47, 35, 50, 0, 107, 107, 101, 2, 116, 3, 48, 2, 35, 49, 108, 0, 4, 110, 8, 2, 100, 111, 3, 48, 2, 35, 50, 0, 110, 8, 2, 116, 111, 0, 110, 111, 2, 114, 97, 109, 3, 48, 2, 35, 50, 2, 40, 0, 110, 100, 101, 2, 109, 105, 101, 3, 48, 2, 35, 50, 72, 116, 0, 108, 2, 109, 105, 101, 116, 3, 48, 2, 35, 55, 0, 108, 101, 2, 115, 116, 17, 65, 3, 48, 2, 35, 55, 13, 0, 108, 105, 110, 2, 100, 114, 111, 3, 48, 2, 35, 55, 13, 50, 0, 108, 101, 2, 116, 3, 48, 2, 35, 55, 108, 0, 109, 2, 17, 67, 3, 48, 2, 35, 65, 0, 109, 112, 101, 114, 2, 108, 3, 48, 2, 35, 65, 48, 13, 34, 0, 4, 118, 105, 108, 2, 106, 111, 101, 3, 48, 2, 35, 84, 13, 55, 0, 119, 105, 108, 2, 106, 111, 101, 0, 115, 2, 111, 112, 3, 48, 2, 35, 89, 0, 115, 115, 97, 2, 115, 105, 101, 114, 3, 48, 2, 35, 89, 2, 35, 0, 115, 116, 111, 8, 2, 114, 17, 65, 21, 3, 48, 2, 35, 89, 47, 2, 40, 0, 115, 101, 2, 108, 108, 97, 3, 48, 2, 35, 89, 112, 0, 116, 105, 101, 115, 1, 21, 3, 48, 6, 115, 47, 37, 89, 0, 100, 100, 97, 8, 2, 17, 67, 17, 65, 3, 48, 7, 35, 72, 35, 0, 2, 116, 97, 116, 3, 48, 13, 0, 114, 97, 100, 101, 2, 25, 3, 48, 13, 34, 115, 72, 13, 0, 110, 97, 100, 111, 3, 48, 13, 50, 115, 72, 120, 12, 0, 106, 97, 109, 97, 3, 48, 13, 75, 115, 65, 2, 35, 0, 114, 107, 97, 2, 98, 97, 97, 100, 106, 3, 48, 35, 34, 49, 2, 35, 0, 114, 107, 101, 2, 114, 97, 97, 100, 3, 48, 35, 34, 49, 13, 0, 107, 2, 17, 65, 3, 48, 35, 49, 19, 0, 110, 8, 2, 103, 101, 17, 67, 3, 48, 35, 50, 0, 110, 97, 109, 97, 3, 48, 35, 50, 13, 65, 35, 0, 110, 116, 115, 101, 114, 3, 48, 35, 50, 47, 89, 13, 34, 0, 108, 106, 97, 8, 2, 25, 3, 48, 35, 55, 57, 7, 35, 0, 109, 2, 112, 97, 3, 48, 35, 65, 0, 110, 107, 114, 101, 97, 3, 48, 35, 68, 49, 34, 2, 37, 2, 35, 0, 110, 103, 97, 3, 48, 35, 68, 81, 35, 0, 115, 8, 2, 17, 65, 17, 65, 3, 48, 35, 89, 0, 97, 114, 108, 8, 3, 48, 113, 34, 114, 0, 116, 105, 111, 3, 48, 115, 47, 37, 38, 40, 0, 7, 6, 112, 101, 0, 2, 110, 97, 108, 105, 3, 48, 2, 108, 0, 114, 105, 2, 115, 17, 67, 17, 65, 3, 48, 2, 108, 34, 13, 0, 114, 105, 102, 101, 2, 114, 17, 65, 21, 3, 48, 2, 108, 34, 13, 83, 13, 0, 110, 2, 100, 117, 108, 101, 3, 48, 2, 108, 50, 0, 110, 101, 2, 116, 114, 17, 65, 3, 48, 2, 108, 50, 13, 0, 110, 105, 115, 105, 2, 108, 108, 105, 3, 48, 2, 108, 50, 13, 89, 13, 0, 110, 115, 105, 2, 111, 101, 110, 3, 48, 2, 108, 50, 91, 2, 37, 0, 108, 105, 8, 2, 107, 97, 3, 48, 2, 108, 55, 2, 37, 0, 108, 111, 116, 111, 110, 3, 48, 2, 108, 55, 13, 47, 110, 50, 0, 100, 8, 2, 111, 102, 3, 48, 2, 108, 72, 0, 100, 97, 8, 2, 103, 3, 48, 2, 108, 72, 2, 35, 0, 100, 105, 8, 3, 48, 2, 108, 72, 2, 37, 0, 114, 2, 115, 101, 101, 108, 3, 48, 2, 112, 34, 0, 114, 108, 101, 2, 109, 111, 101, 3, 48, 2, 112, 34, 55, 13, 0, 114, 115, 111, 2, 110, 101, 101, 108, 3, 48, 2, 112, 34, 89, 2, 40, 0, 114, 103, 111, 108, 97, 3, 48, 2, 112, 34, 136, 117, 55, 2, 35, 0, 4, 108, 101, 2, 116, 111, 110, 3, 48, 2, 112, 55, 13, 0, 108, 101, 2, 116, 111, 110, 0, 114, 105, 2, 111, 3, 48, 2, 116, 34, 2, 37, 0, 114, 100, 101, 8, 3, 48, 6, 113, 34, 72, 13, 0, 4, 1, 17, 67, 21, 2, 100, 97, 3, 48, 13, 0, 2, 110, 97, 114, 105, 101, 0, 2, 114, 114, 111, 110, 0, 2, 116, 105, 101, 116, 101, 114, 0, 2, 116, 105, 115, 105, 0, 2, 116, 117, 110, 105, 97, 0, 8, 2, 100, 17, 65, 0, 4, 114, 2, 107, 117, 115, 115, 105, 101, 3, 48, 13, 34, 0, 114, 2, 115, 101, 112, 115, 105, 0, 114, 2, 115, 111, 0, 4, 114, 101, 1, 109, 97, 107, 115, 2, 32, 3, 48, 13, 34, 13, 0, 114, 101, 1, 112, 2, 32, 0, 114, 101, 1, 121, 114, 2, 32, 0, 114, 109, 105, 116, 3, 48, 13, 34, 65, 6, 109, 47, 0, 4, 114, 100, 101, 1, 101, 112, 2, 32, 3, 48, 13, 34, 72, 13, 0, 114, 100, 101, 1, 109, 101, 116, 2, 32, 0, 114, 100, 101, 1, 112, 105, 110, 115, 2, 32, 0, 114, 100, 101, 1, 114, 117, 112, 2, 32, 0, 114, 100, 101, 1, 115, 97, 114, 2, 32, 0, 114, 102, 101, 107, 3, 48, 13, 34, 83, 108, 49, 0, 114, 118, 101, 114, 116, 3, 48, 13, 34, 83, 112, 34, 47, 0, 114, 118, 101, 114, 115, 3, 48, 13, 34, 83, 112, 34, 89, 0, 114, 115, 101, 110, 116, 3, 48, 13, 34, 89, 108, 50, 47, 0, 114, 115, 101, 110, 116, 97, 1, 21, 2, 115, 105, 3, 48, 13, 34, 89, 108, 50, 47, 115, 0, 116, 114, 111, 108, 2, 101, 117, 109, 3, 48, 13, 47, 34, 117, 55, 0, 110, 101, 2, 32, 3, 48, 13, 50, 13, 0, 108, 105, 110, 103, 1, 114, 2, 32, 3, 48, 13, 55, 13, 68, 0, 114, 105, 112, 97, 2, 116, 3, 48, 108, 34, 37, 48, 35, 7, 0, 116, 114, 111, 108, 3, 48, 108, 47, 34, 13, 55, 10, 0, 100, 111, 8, 2, 109, 3, 48, 108, 72, 2, 40, 0, 115, 1, 114, 101, 100, 110, 117, 114, 3, 48, 108, 89, 0, 114, 107, 101, 1, 21, 2, 32, 3, 48, 112, 34, 49, 13, 0, 114, 107, 101, 114, 1, 21, 2, 25, 3, 48, 112, 34, 49, 13, 34, 0, 114, 107, 105, 110, 103, 1, 21, 3, 48, 112, 34, 49, 13, 68, 0, 114, 109, 97, 110, 101, 110, 3, 48, 112, 34, 65, 35, 50, 6, 108, 50, 0, 114, 115, 2, 111, 109, 3, 48, 112, 34, 89, 10, 0, 114, 115, 107, 101, 3, 48, 112, 34, 89, 49, 13, 0, 114, 1, 121, 114, 2, 100, 3, 48, 113, 34, 0, 114, 100, 8, 2, 114, 3, 48, 113, 34, 47, 0, 4, 114, 100, 101, 1, 21, 2, 32, 3, 48, 113, 34, 72, 13, 0, 114, 100, 101, 2, 107, 97, 114, 0, 8, 2, 116, 114, 17, 65, 32, 3, 48, 116, 0, 114, 101, 1, 21, 2, 32, 3, 48, 116, 34, 13, 0, 7, 6, 112, 114, 0, 111, 116, 101, 115, 116, 3, 4, 48, 34, 110, 47, 13, 89, 47, 0, 111, 112, 97, 103, 3, 4, 48, 34, 110, 48, 35, 136, 0, 97, 107, 8, 2, 116, 121, 107, 3, 48, 34, 2, 35, 49, 0, 97, 107, 116, 105, 2, 115, 121, 110, 3, 48, 34, 2, 35, 49, 47, 2, 37, 0, 105, 2, 109, 97, 97, 116, 3, 48, 34, 2, 37, 0, 101, 116, 111, 114, 105, 3, 48, 34, 2, 37, 47, 2, 117, 34, 2, 37, 0, 101, 116, 111, 114, 105, 97, 2, 110, 3, 48, 34, 2, 37, 47, 2, 117, 34, 2, 37, 6, 115, 0, 101, 116, 111, 114, 105, 97, 2, 32, 3, 48, 34, 2, 37, 47, 6, 117, 34, 37, 35, 0, 101, 109, 105, 195, 168, 114, 101, 3, 48, 34, 2, 37, 65, 57, 113, 34, 0, 105, 118, 2, 97, 21, 3, 48, 34, 2, 37, 83, 0, 105, 101, 115, 116, 101, 114, 101, 2, 25, 3, 48, 34, 2, 37, 89, 47, 13, 34, 108, 0, 4, 111, 2, 17, 67, 17, 65, 3, 48, 34, 2, 40, 0, 111, 2, 98, 108, 17, 65, 0, 111, 2, 103, 114, 97, 109, 0, 111, 116, 101, 115, 2, 116, 101, 32, 24, 3, 48, 34, 2, 40, 47, 108, 89, 0, 111, 106, 101, 107, 3, 48, 34, 2, 40, 57, 108, 49, 0, 111, 100, 117, 107, 2, 17, 65, 3, 48, 34, 2, 40, 72, 111, 49, 10, 0, 111, 102, 101, 115, 115, 105, 111, 2, 110, 3, 48, 34, 2, 40, 83, 2, 108, 91, 2, 37, 2, 40, 0, 111, 118, 105, 116, 97, 3, 48, 34, 2, 40, 84, 37, 47, 2, 35, 0, 111, 115, 101, 115, 3, 48, 34, 2, 40, 89, 108, 89, 0, 111, 103, 114, 97, 109, 109, 101, 2, 114, 105, 110, 103, 3, 48, 34, 2, 40, 136, 34, 2, 35, 65, 116, 0, 101, 112, 97, 2, 114, 97, 3, 48, 34, 2, 108, 48, 13, 0, 101, 115, 116, 105, 103, 101, 3, 48, 34, 2, 108, 89, 47, 37, 12, 90, 0, 101, 115, 98, 105, 116, 101, 114, 105, 2, 97, 3, 48, 34, 2, 108, 89, 71, 13, 47, 2, 116, 34, 2, 37, 0, 101, 103, 2, 110, 97, 110, 17, 67, 3, 48, 34, 2, 108, 136, 0, 111, 112, 111, 115, 105, 3, 48, 34, 2, 110, 48, 13, 88, 37, 0, 111, 107, 117, 2, 114, 17, 65, 3, 48, 34, 2, 110, 49, 2, 118, 0, 111, 108, 101, 116, 97, 114, 105, 2, 97, 3, 48, 34, 2, 110, 55, 13, 47, 2, 35, 34, 2, 37, 0, 111, 109, 117, 108, 103, 2, 101, 3, 48, 34, 2, 110, 65, 2, 111, 55, 136, 0, 111, 109, 101, 110, 97, 100, 101, 3, 48, 34, 2, 110, 65, 13, 50, 115, 72, 13, 0, 111, 109, 105, 115, 107, 117, 3, 48, 34, 2, 110, 65, 13, 89, 49, 118, 0, 111, 98, 108, 101, 2, 109, 97, 116, 105, 3, 48, 34, 2, 110, 71, 55, 13, 0, 111, 102, 105, 116, 2, 101, 3, 48, 34, 2, 110, 83, 13, 47, 0, 111, 115, 101, 2, 100, 117, 114, 101, 3, 48, 34, 2, 110, 89, 13, 0, 111, 115, 116, 105, 2, 116, 117, 3, 48, 34, 2, 110, 89, 47, 13, 0, 101, 100, 105, 2, 107, 97, 110, 116, 3, 48, 34, 2, 116, 72, 13, 0, 111, 2, 103, 114, 101, 115, 115, 3, 48, 34, 2, 117, 0, 111, 116, 101, 2, 195, 175, 3, 48, 34, 2, 117, 47, 13, 0, 111, 106, 101, 107, 2, 116, 105, 101, 108, 3, 48, 34, 2, 117, 57, 2, 108, 49, 0, 111, 118, 105, 2, 97, 110, 100, 3, 48, 34, 2, 117, 84, 2, 37, 0, 111, 115, 97, 2, 195, 175, 101, 3, 48, 34, 2, 117, 89, 115, 0, 111, 103, 101, 115, 116, 101, 114, 2, 111, 3, 48, 34, 2, 117, 136, 2, 108, 89, 47, 13, 34, 0, 101, 2, 110, 97, 116, 97, 3, 48, 34, 4, 116, 0, 4, 101, 2, 108, 117, 100, 3, 48, 34, 13, 0, 101, 2, 109, 105, 101, 114, 0, 101, 2, 115, 17, 65, 0, 101, 116, 101, 110, 2, 115, 105, 3, 48, 34, 13, 47, 134, 50, 0, 105, 110, 115, 105, 2, 112, 17, 65, 3, 48, 34, 13, 50, 89, 13, 0, 105, 110, 115, 105, 112, 101, 2, 25, 3, 48, 34, 13, 50, 89, 37, 48, 13, 0, 105, 110, 115, 101, 2, 115, 3, 48, 34, 13, 50, 89, 108, 0, 105, 110, 115, 101, 115, 1, 21, 2, 32, 3, 48, 34, 13, 50, 89, 108, 89, 0, 105, 109, 105, 2, 116, 3, 48, 34, 13, 65, 13, 0, 4, 101, 115, 101, 2, 100, 101, 110, 116, 3, 48, 34, 13, 89, 13, 0, 105, 115, 111, 2, 110, 105, 101, 114, 0, 101, 115, 105, 100, 101, 110, 2, 17, 67, 3, 48, 34, 13, 89, 13, 72, 108, 50, 0, 101, 115, 116, 97, 2, 115, 105, 101, 3, 48, 34, 13, 89, 47, 115, 0, 101, 115, 116, 101, 2, 114, 101, 110, 100, 3, 48, 34, 13, 89, 47, 116, 0, 101, 115, 116, 101, 101, 114, 3, 48, 34, 13, 89, 47, 116, 34, 0, 101, 115, 101, 110, 116, 1, 21, 3, 48, 34, 13, 89, 108, 50, 47, 0, 101, 116, 111, 114, 105, 97, 2, 17, 67, 3, 48, 34, 37, 47, 6, 117, 34, 37, 35, 0, 101, 102, 101, 107, 3, 48, 34, 37, 83, 108, 49, 0, 111, 116, 101, 115, 3, 48, 34, 40, 47, 6, 108, 89, 0, 111, 109, 105, 110, 101, 110, 3, 48, 34, 110, 65, 37, 50, 6, 108, 50, 0, 111, 110, 107, 101, 114, 2, 116, 106, 105, 3, 48, 34, 110, 68, 49, 10, 112, 34, 0, 111, 102, 101, 115, 105, 101, 3, 48, 34, 110, 83, 13, 89, 6, 37, 0, 4, 101, 2, 104, 105, 115, 116, 111, 3, 48, 34, 116, 0, 101, 2, 115, 101, 32, 0, 101, 100, 105, 107, 101, 114, 3, 48, 34, 116, 72, 13, 49, 13, 34, 0, 111, 116, 2, 111, 110, 12, 3, 48, 34, 117, 47, 0, 111, 116, 111, 2, 17, 67, 3, 48, 34, 117, 47, 40, 0, 111, 107, 105, 101, 3, 48, 34, 117, 49, 2, 37, 0, 111, 115, 97, 3, 48, 34, 117, 89, 2, 35, 0, 111, 115, 101, 1, 21, 2, 32, 3, 48, 34, 117, 89, 13, 0, 7, 6, 114, 101, 0, 2, 97, 103, 101, 114, 101, 110, 3, 34, 2, 37, 0, 97, 2, 17, 67, 3, 34, 2, 37, 2, 35, 0, 104, 97, 98, 105, 108, 105, 116, 3, 34, 2, 37, 2, 35, 71, 2, 37, 55, 2, 37, 47, 0, 2, 195, 188, 3, 34, 2, 37, 10, 0, 97, 2, 107, 115, 3, 34, 2, 37, 35, 0, 102, 108, 101, 107, 2, 17, 67, 3, 34, 2, 37, 83, 55, 108, 49, 0, 116, 114, 111, 8, 2, 21, 14, 128, 132, 133, 3, 34, 2, 108, 47, 34, 2, 40, 0, 112, 2, 116, 105, 101, 108, 3, 34, 2, 108, 48, 0, 112, 101, 114, 116, 111, 105, 114, 101, 3, 34, 2, 108, 48, 13, 34, 47, 58, 115, 34, 0, 112, 117, 2, 116, 3, 34, 2, 108, 48, 118, 0, 100, 105, 103, 8, 2, 17, 65, 3, 34, 2, 108, 72, 2, 37, 136, 0, 102, 101, 114, 2, 97, 3, 34, 2, 108, 83, 13, 34, 0, 119, 111, 108, 2, 117, 3, 34, 2, 108, 84, 2, 111, 55, 0, 115, 111, 2, 110, 17, 65, 3, 34, 2, 108, 89, 2, 40, 0, 115, 111, 2, 108, 117, 115, 105, 101, 3, 34, 2, 108, 89, 2, 110, 0, 115, 116, 97, 117, 114, 3, 34, 2, 108, 89, 47, 2, 40, 34, 0, 115, 116, 101, 8, 2, 114, 101, 110, 100, 3, 34, 2, 108, 89, 47, 116, 0, 103, 105, 109, 101, 110, 2, 116, 97, 21, 3, 34, 2, 108, 136, 2, 37, 65, 2, 108, 50, 0, 103, 117, 2, 108, 17, 65, 3, 34, 2, 108, 136, 2, 118, 0, 103, 2, 104, 111, 101, 107, 105, 103, 3, 34, 2, 112, 136, 0, 2, 112, 114, 111, 100, 117, 3, 34, 2, 116, 0, 112, 101, 114, 2, 107, 117, 115, 3, 34, 2, 116, 48, 13, 34, 0, 108, 105, 195, 171, 102, 3, 34, 2, 116, 55, 2, 37, 108, 83, 0, 100, 101, 2, 114, 121, 3, 34, 2, 116, 72, 13, 0, 101, 108, 1, 17, 65, 10, 2, 32, 3, 34, 6, 116, 55, 0, 108, 101, 1, 10, 2, 32, 3, 34, 6, 116, 55, 13, 0, 4, 1, 17, 67, 2, 103, 97, 116, 3, 34, 13, 0, 2, 98, 101, 108, 0, 2, 100, 97, 107, 17, 67, 0, 2, 102, 114, 101, 105, 110, 0, 2, 103, 101, 101, 114, 0, 2, 103, 114, 101, 115, 25, 0, 2, 103, 114, 111, 101, 112, 0, 2, 107, 114, 117, 0, 2, 108, 105, 101, 107, 0, 2, 110, 17, 65, 0, 2, 112, 108, 105, 101, 107, 0, 2, 115, 101, 110, 115, 17, 65, 0, 2, 115, 101, 115, 115, 105, 101, 0, 2, 115, 112, 111, 110, 0, 2, 116, 111, 0, 8, 2, 108, 97, 0, 8, 2, 115, 112, 121, 116, 0, 8, 2, 115, 116, 97, 110, 116, 0, 116, 105, 2, 114, 101, 3, 34, 13, 47, 13, 0, 112, 117, 98, 108, 105, 2, 107, 3, 34, 13, 48, 2, 111, 71, 55, 2, 37, 0, 112, 117, 98, 108, 105, 101, 107, 3, 34, 13, 48, 2, 111, 71, 55, 37, 49, 0, 4, 107, 108, 97, 2, 109, 17, 65, 3, 34, 13, 49, 55, 35, 0, 107, 108, 97, 2, 109, 101, 101, 114, 0, 107, 108, 97, 109, 101, 3, 34, 13, 49, 55, 115, 65, 13, 0, 110, 101, 1, 111, 3, 34, 13, 50, 13, 0, 110, 111, 110, 115, 3, 34, 13, 50, 135, 50, 89, 0, 4, 108, 101, 2, 103, 17, 65, 3, 34, 13, 55, 13, 0, 108, 101, 2, 118, 97, 110, 0, 108, 105, 2, 103, 105, 0, 108, 97, 115, 101, 3, 34, 13, 55, 115, 89, 13, 0, 100, 101, 110, 2, 17, 65, 17, 67, 17, 65, 3, 34, 13, 72, 13, 50, 6, 0, 100, 101, 110, 101, 101, 114, 3, 34, 13, 72, 13, 50, 6, 116, 34, 0, 102, 111, 114, 2, 109, 3, 34, 13, 83, 2, 110, 34, 0, 102, 101, 114, 101, 110, 2, 100, 17, 65, 3, 34, 13, 83, 13, 34, 108, 50, 0, 119, 111, 108, 119, 101, 114, 3, 34, 13, 84, 6, 110, 55, 84, 13, 34, 0, 115, 101, 114, 119, 101, 3, 34, 13, 88, 6, 112, 34, 84, 13, 0, 4, 115, 105, 2, 100, 101, 110, 3, 34, 13, 89, 13, 0, 115, 105, 2, 116, 17, 65, 0, 115, 101, 114, 2, 118, 3, 34, 13, 89, 13, 34, 0, 115, 112, 101, 107, 2, 116, 101, 101, 114, 3, 34, 13, 89, 48, 2, 108, 49, 0, 115, 112, 101, 107, 3, 34, 13, 89, 48, 108, 49, 0, 115, 101, 112, 3, 34, 13, 89, 108, 48, 0, 115, 101, 115, 2, 32, 3, 34, 13, 89, 108, 89, 0, 115, 117, 108, 2, 116, 17, 65, 3, 34, 13, 89, 111, 55, 6, 0, 103, 105, 109, 101, 2, 32, 3, 34, 13, 90, 37, 12, 65, 0, 103, 2, 105, 115, 116, 3, 34, 13, 136, 0, 4, 103, 105, 2, 109, 101, 110, 116, 3, 34, 13, 136, 13, 0, 103, 105, 2, 115, 115, 101, 117, 17, 67, 0, 103, 108, 101, 2, 109, 101, 110, 116, 3, 34, 13, 136, 55, 13, 0, 103, 101, 114, 2, 17, 65, 3, 34, 13, 136, 116, 34, 0, 4, 1, 17, 67, 2, 110, 32, 3, 34, 108, 0, 1, 17, 67, 2, 110, 110, 101, 32, 0, 1, 101, 100, 114, 101, 112, 2, 110, 0, 116, 105, 110, 97, 3, 34, 108, 47, 37, 50, 35, 0, 112, 101, 116, 3, 34, 108, 48, 13, 47, 0, 107, 111, 114, 100, 3, 34, 108, 49, 2, 110, 34, 47, 0, 99, 99, 101, 3, 34, 108, 49, 37, 0, 109, 2, 32, 3, 34, 108, 65, 0, 103, 103, 97, 101, 3, 34, 108, 81, 123, 0, 103, 3, 34, 112, 136, 0, 103, 118, 101, 114, 100, 105, 103, 3, 34, 112, 136, 83, 6, 112, 34, 72, 13, 136, 0, 114, 105, 110, 103, 1, 10, 2, 32, 3, 34, 116, 34, 13, 68, 0, 107, 101, 2, 110, 17, 65, 3, 34, 116, 49, 13, 0, 4, 100, 101, 1, 115, 3, 34, 116, 72, 13, 0, 100, 101, 8, 2, 17, 67, 0, 100, 101, 108, 8, 3, 34, 116, 72, 13, 55, 0, 7, 6, 115, 101, 0, 110, 105, 111, 114, 2, 105, 116, 101, 105, 3, 89, 2, 37, 12, 50, 2, 37, 2, 110, 34, 0, 4, 114, 101, 2, 109, 111, 110, 105, 3, 89, 2, 108, 34, 13, 0, 114, 101, 2, 110, 97, 100, 101, 0, 114, 111, 116, 111, 2, 110, 105, 3, 89, 2, 108, 34, 13, 47, 2, 40, 0, 107, 117, 2, 108, 3, 89, 2, 108, 49, 2, 118, 0, 107, 119, 101, 2, 115, 116, 114, 17, 65, 3, 89, 2, 108, 49, 58, 13, 0, 107, 115, 2, 116, 97, 110, 116, 3, 89, 2, 108, 49, 89, 0, 107, 115, 116, 101, 2, 116, 3, 89, 2, 108, 49, 89, 47, 108, 0, 4, 110, 2, 115, 111, 114, 105, 101, 3, 89, 2, 108, 50, 0, 110, 2, 115, 117, 117, 114, 0, 110, 8, 2, 116, 114, 97, 21, 0, 110, 116, 105, 2, 109, 101, 110, 116, 3, 89, 2, 108, 50, 47, 2, 37, 0, 108, 105, 2, 98, 97, 3, 89, 2, 108, 55, 2, 37, 0, 109, 105, 2, 110, 97, 3, 89, 2, 108, 65, 2, 37, 0, 2, 108, 108, 105, 110, 3, 89, 2, 112, 6, 0, 108, 108, 111, 2, 102, 97, 3, 89, 2, 112, 55, 13, 0, 108, 100, 101, 114, 2, 121, 3, 89, 2, 112, 55, 72, 13, 34, 0, 108, 102, 2, 115, 116, 97, 110, 3, 89, 2, 112, 55, 83, 0, 108, 97, 2, 107, 97, 110, 116, 3, 89, 2, 116, 55, 13, 0, 105, 2, 115, 111, 101, 110, 3, 89, 2, 123, 0, 108, 1, 21, 2, 119, 105, 103, 3, 89, 6, 112, 55, 0, 108, 108, 105, 103, 1, 21, 3, 89, 6, 112, 55, 13, 136, 0, 108, 101, 1, 10, 2, 32, 3, 89, 6, 116, 55, 13, 0, 110, 105, 111, 114, 8, 3, 89, 7, 37, 12, 50, 37, 13, 34, 0, 107, 111, 1, 21, 2, 110, 111, 21, 3, 89, 10, 2, 108, 49, 2, 40, 0, 4, 2, 32, 3, 89, 13, 0, 2, 100, 117, 107, 0, 2, 107, 111, 0, 2, 107, 117, 0, 2, 114, 111, 101, 116, 0, 8, 2, 100, 101, 110, 116, 0, 8, 2, 100, 111, 111, 115, 0, 8, 2, 107, 114, 101, 0, 8, 2, 110, 105, 21, 0, 8, 2, 114, 105, 110, 103, 0, 8, 32, 2, 32, 0, 4, 114, 2, 115, 97, 110, 116, 3, 89, 13, 34, 0, 114, 2, 118, 101, 116, 0, 114, 8, 2, 101, 21, 0, 107, 114, 101, 2, 116, 97, 3, 89, 13, 49, 34, 13, 0, 107, 114, 101, 116, 97, 114, 105, 2, 17, 65, 3, 89, 13, 49, 34, 13, 47, 2, 35, 34, 2, 37, 0, 108, 101, 1, 111, 110, 2, 32, 3, 89, 13, 55, 13, 0, 108, 101, 107, 2, 17, 67, 17, 65, 3, 89, 13, 55, 108, 49, 0, 108, 111, 110, 8, 2, 115, 17, 67, 3, 89, 13, 55, 135, 50, 0, 109, 101, 8, 2, 17, 67, 116, 3, 89, 13, 65, 108, 0, 100, 97, 110, 8, 3, 89, 13, 72, 35, 50, 0, 100, 101, 2, 114, 105, 110, 103, 3, 89, 13, 72, 116, 0, 100, 101, 101, 114, 3, 89, 13, 72, 116, 34, 0, 107, 115, 1, 21, 2, 32, 3, 89, 108, 49, 89, 0, 110, 116, 101, 114, 3, 89, 108, 50, 47, 13, 34, 0, 110, 100, 105, 110, 103, 2, 32, 3, 89, 108, 50, 72, 13, 68, 0, 4, 109, 105, 8, 2, 17, 67, 3, 89, 108, 65, 37, 0, 109, 105, 8, 2, 32, 0, 115, 2, 117, 117, 114, 3, 89, 108, 89, 10, 0, 4, 1, 100, 101, 111, 108, 98, 2, 108, 3, 89, 112, 0, 1, 101, 105, 115, 105, 108, 111, 112, 2, 108, 25, 0, 1, 101, 108, 108, 105, 97, 114, 98, 2, 108, 0, 1, 103, 110, 105, 110, 117, 101, 104, 2, 108, 25, 0, 1, 109, 97, 97, 103, 103, 105, 108, 2, 108, 25, 0, 1, 109, 97, 116, 115, 2, 108, 0, 2, 103, 103, 17, 65, 0, 108, 108, 101, 2, 116, 106, 105, 101, 3, 89, 112, 55, 37, 0, 1, 17, 67, 21, 2, 114, 101, 32, 3, 89, 116, 0, 116, 101, 2, 110, 101, 32, 3, 89, 116, 47, 13, 0, 116, 101, 108, 2, 25, 3, 89, 116, 47, 13, 55, 0, 107, 101, 114, 3, 89, 116, 49, 13, 34, 0, 110, 105, 110, 103, 3, 89, 116, 50, 13, 68, 0, 110, 117, 8, 2, 17, 67, 17, 67, 3, 89, 116, 50, 118, 0, 109, 101, 108, 2, 21, 3, 89, 116, 65, 13, 55, 0, 98, 114, 97, 8, 3, 89, 116, 71, 34, 35, 0, 100, 101, 8, 3, 89, 116, 72, 13, 0, 7, 6, 115, 116, 0, 105, 101, 115, 1, 21, 3, 8, 89, 47, 2, 37, 89, 0, 101, 109, 112, 101, 114, 97, 109, 101, 1, 21, 3, 89, 10, 47, 108, 65, 48, 14, 34, 2, 35, 65, 108, 0, 4, 97, 2, 116, 117, 116, 17, 65, 3, 89, 47, 2, 35, 0, 97, 8, 2, 98, 105, 21, 0, 97, 110, 2, 100, 97, 3, 89, 47, 2, 35, 50, 0, 4, 97, 110, 100, 2, 104, 111, 117, 100, 101, 3, 89, 47, 2, 35, 50, 47, 0, 97, 110, 100, 2, 118, 97, 115, 116, 105, 0, 97, 110, 100, 101, 114, 100, 2, 21, 3, 89, 47, 2, 35, 50, 72, 13, 34, 47, 0, 97, 108, 97, 103, 2, 17, 67, 105, 101, 116, 3, 89, 47, 2, 35, 55, 2, 35, 136, 0, 105, 101, 2, 98, 101, 117, 3, 89, 47, 2, 37, 0, 105, 108, 101, 2, 116, 3, 89, 47, 2, 37, 55, 108, 0, 101, 8, 2, 114, 105, 3, 89, 47, 2, 108, 0, 101, 108, 108, 101, 110, 2, 98, 111, 115, 3, 89, 47, 2, 112, 55, 13, 65, 0, 101, 114, 101, 111, 2, 116, 105, 3, 89, 47, 2, 116, 34, 2, 37, 2, 40, 0, 101, 114, 111, 2, 195, 175, 101, 100, 3, 89, 47, 2, 116, 34, 2, 40, 38, 0, 117, 2, 100, 101, 3, 89, 47, 2, 118, 0, 117, 100, 101, 110, 2, 116, 3, 89, 47, 2, 118, 72, 108, 50, 0, 111, 117, 116, 2, 109, 111, 101, 100, 105, 3, 89, 47, 2, 120, 47, 0, 105, 101, 107, 1, 26, 21, 3, 89, 47, 6, 37, 49, 0, 101, 1, 21, 2, 108, 108, 101, 110, 3, 89, 47, 6, 112, 0, 101, 114, 114, 101, 116, 106, 105, 101, 3, 89, 47, 6, 112, 34, 37, 80, 37, 0, 97, 116, 105, 101, 115, 3, 89, 47, 6, 115, 47, 37, 89, 0, 121, 102, 103, 101, 2, 21, 14, 128, 132, 134, 3, 89, 47, 6, 123, 83, 136, 13, 0, 97, 97, 116, 8, 2, 115, 3, 89, 47, 7, 115, 47, 0, 4, 101, 1, 17, 67, 21, 2, 109, 97, 110, 3, 89, 47, 13, 0, 101, 1, 21, 2, 108, 121, 25, 0, 101, 1, 32, 15, 0, 101, 1, 114, 170, 195, 2, 32, 14, 128, 128, 131, 0, 101, 2, 108, 97, 97, 110, 0, 101, 2, 108, 97, 110, 100, 0, 101, 2, 108, 108, 97, 115, 105, 101, 0, 101, 2, 109, 97, 97, 116, 0, 101, 2, 109, 97, 114, 107, 0, 101, 8, 2, 102, 97, 97, 110, 0, 105, 2, 112, 117, 108, 17, 65, 0, 101, 114, 114, 101, 105, 3, 89, 47, 13, 34, 6, 123, 0, 101, 110, 101, 1, 105, 114, 104, 99, 2, 32, 3, 89, 47, 13, 50, 13, 0, 4, 101, 108, 1, 21, 2, 105, 17, 67, 3, 89, 47, 13, 55, 0, 101, 108, 1, 21, 2, 111, 0, 101, 108, 1, 110, 117, 107, 2, 100, 0, 101, 108, 1, 111, 112, 97, 0, 101, 108, 1, 114, 111, 119, 0, 101, 108, 8, 101, 110, 0, 105, 108, 2, 115, 119, 121, 0, 101, 108, 105, 107, 1, 21, 3, 89, 47, 13, 55, 13, 49, 0, 105, 109, 117, 2, 108, 17, 65, 3, 89, 47, 13, 65, 2, 118, 0, 114, 97, 116, 101, 103, 105, 101, 3, 89, 47, 34, 2, 35, 47, 13, 136, 37, 0, 114, 97, 116, 101, 103, 105, 101, 115, 3, 89, 47, 34, 2, 35, 47, 116, 136, 37, 89, 0, 114, 97, 98, 2, 111, 116, 111, 109, 105, 3, 89, 47, 34, 2, 35, 71, 0, 114, 97, 102, 2, 114, 101, 103, 116, 101, 3, 89, 47, 34, 2, 35, 83, 0, 114, 117, 107, 116, 2, 117, 3, 89, 47, 34, 2, 111, 49, 47, 0, 114, 117, 107, 116, 117, 2, 114, 101, 114, 17, 65, 110, 3, 89, 47, 34, 2, 111, 49, 47, 2, 118, 0, 114, 105, 103, 2, 110, 105, 101, 110, 3, 89, 47, 34, 13, 136, 0, 4, 114, 97, 110, 100, 2, 111, 3, 89, 47, 34, 35, 50, 47, 10, 0, 114, 97, 110, 100, 8, 2, 101, 114, 17, 67, 0, 114, 101, 115, 2, 32, 3, 89, 47, 34, 108, 89, 0, 114, 97, 97, 116, 1, 21, 2, 32, 14, 129, 128, 134, 3, 89, 47, 34, 115, 47, 0, 114, 101, 107, 101, 3, 89, 47, 34, 116, 49, 13, 0, 97, 112, 8, 2, 17, 65, 3, 89, 47, 35, 48, 10, 0, 97, 109, 105, 110, 97, 3, 89, 47, 35, 65, 2, 37, 50, 2, 35, 0, 101, 2, 109, 3, 89, 47, 108, 0, 101, 110, 2, 115, 105, 108, 3, 89, 47, 108, 50, 0, 101, 109, 112, 101, 108, 3, 89, 47, 108, 65, 48, 13, 55, 0, 111, 114, 109, 3, 89, 47, 110, 34, 14, 65, 0, 111, 107, 2, 17, 65, 3, 89, 47, 110, 49, 19, 0, 111, 102, 2, 111, 3, 89, 47, 110, 83, 19, 0, 4, 101, 1, 100, 110, 2, 114, 3, 89, 47, 112, 0, 101, 1, 101, 101, 115, 2, 114, 0, 101, 1, 101, 105, 112, 101, 115, 2, 114, 0, 101, 1, 101, 105, 115, 105, 118, 2, 114, 0, 101, 1, 101, 114, 17, 65, 109, 2, 114, 0, 101, 1, 101, 119, 101, 115, 2, 114, 0, 101, 1, 103, 114, 101, 119, 100, 2, 114, 0, 101, 1, 107, 99, 111, 114, 2, 114, 0, 101, 1, 108, 97, 97, 119, 100, 2, 114, 0, 101, 1, 108, 101, 17, 67, 11, 2, 114, 0, 101, 1, 108, 111, 111, 112, 2, 114, 0, 101, 1, 109, 97, 97, 115, 2, 108, 108, 101, 110, 0, 101, 1, 109, 108, 105, 102, 2, 114, 0, 101, 1, 110, 101, 101, 116, 2, 108, 108, 101, 110, 0, 101, 1, 112, 111, 112, 2, 114, 0, 101, 1, 114, 101, 112, 117, 115, 2, 114, 0, 101, 1, 116, 101, 17, 67, 2, 114, 25, 0, 101, 1, 116, 110, 101, 114, 112, 2, 114, 0, 101, 2, 108, 0, 4, 101, 114, 1, 103, 101, 119, 2, 119, 101, 3, 89, 47, 112, 34, 0, 101, 114, 2, 45, 104, 111, 116, 101, 108, 0, 101, 114, 2, 104, 111, 116, 101, 108, 0, 101, 114, 2, 119, 101, 110, 100, 0, 101, 114, 8, 0, 101, 114, 114, 101, 3, 89, 47, 112, 34, 13, 0, 101, 114, 107, 2, 32, 3, 89, 47, 112, 34, 49, 0, 101, 114, 107, 116, 1, 21, 3, 89, 47, 112, 34, 49, 47, 0, 101, 114, 102, 2, 25, 3, 89, 47, 112, 34, 83, 0, 101, 114, 119, 101, 110, 115, 2, 21, 3, 89, 47, 112, 34, 84, 13, 50, 89, 10, 0, 101, 108, 101, 1, 10, 2, 102, 111, 3, 89, 47, 112, 55, 13, 0, 4, 101, 114, 1, 107, 105, 119, 107, 3, 89, 47, 113, 34, 0, 101, 114, 1, 107, 111, 98, 2, 116, 0, 101, 114, 1, 107, 114, 97, 118, 2, 116, 106, 105, 101, 0, 101, 114, 1, 112, 97, 97, 107, 115, 2, 116, 106, 105, 101, 0, 97, 2, 100, 105, 111, 110, 3, 89, 47, 115, 0, 97, 112, 101, 108, 3, 89, 47, 115, 48, 13, 55, 0, 101, 2, 107, 101, 32, 3, 89, 47, 116, 0, 101, 107, 101, 2, 108, 105, 103, 3, 89, 47, 116, 49, 13, 0, 101, 107, 101, 114, 1, 17, 67, 3, 89, 47, 116, 49, 13, 34, 0, 101, 110, 101, 2, 32, 3, 89, 47, 116, 50, 13, 0, 101, 108, 101, 2, 32, 3, 89, 47, 116, 55, 13, 0, 101, 108, 101, 114, 3, 89, 47, 116, 55, 13, 34, 0, 4, 101, 100, 101, 2, 17, 67, 3, 89, 47, 116, 72, 13, 0, 101, 100, 101, 2, 32, 0, 101, 100, 105, 110, 103, 3, 89, 47, 116, 72, 13, 68, 0, 101, 119, 101, 108, 3, 89, 47, 116, 84, 13, 55, 0, 111, 116, 101, 110, 101, 3, 89, 47, 117, 47, 13, 50, 13, 0, 111, 107, 2, 101, 3, 89, 47, 117, 49, 0, 7, 6, 116, 101, 0, 109, 112, 101, 114, 97, 3, 4, 47, 108, 65, 48, 14, 34, 2, 35, 0, 2, 111, 17, 67, 3, 47, 2, 37, 2, 0, 97, 2, 116, 114, 97, 3, 47, 2, 37, 2, 35, 0, 97, 116, 101, 114, 3, 47, 2, 37, 115, 47, 13, 34, 0, 114, 97, 2, 112, 17, 65, 3, 47, 2, 108, 34, 2, 35, 0, 114, 97, 1, 111, 2, 112, 17, 65, 3, 47, 2, 108, 34, 2, 35, 6, 0, 114, 114, 111, 114, 2, 105, 115, 3, 47, 2, 108, 34, 2, 40, 34, 0, 4, 107, 115, 2, 116, 105, 101, 108, 3, 47, 2, 108, 49, 89, 0, 107, 115, 8, 2, 116, 117, 0, 4, 110, 2, 111, 116, 111, 109, 105, 101, 3, 47, 2, 108, 50, 0, 110, 2, 116, 97, 107, 101, 108, 0, 110, 2, 116, 111, 111, 110, 0, 110, 100, 101, 110, 115, 3, 47, 2, 108, 50, 72, 134, 50, 89, 0, 115, 111, 117, 2, 114, 105, 101, 3, 47, 2, 108, 89, 2, 40, 0, 4, 114, 2, 109, 105, 101, 116, 3, 47, 2, 112, 34, 0, 114, 2, 109, 121, 110, 0, 114, 8, 2, 115, 0, 114, 97, 97, 114, 100, 101, 8, 3, 47, 2, 112, 34, 19, 115, 34, 72, 13, 0, 114, 112, 101, 110, 2, 116, 121, 110, 3, 47, 2, 112, 34, 48, 13, 50, 0, 114, 109, 105, 2, 110, 97, 21, 3, 47, 2, 112, 34, 65, 2, 37, 0, 108, 101, 8, 2, 17, 67, 3, 47, 2, 112, 55, 13, 0, 4, 101, 110, 2, 115, 116, 114, 121, 100, 3, 47, 2, 116, 50, 0, 101, 110, 2, 119, 111, 111, 114, 0, 101, 110, 2, 111, 111, 114, 103, 101, 115, 3, 47, 2, 116, 50, 10, 0, 101, 110, 115, 2, 119, 111, 111, 114, 3, 47, 2, 116, 50, 89, 0, 4, 1, 17, 67, 21, 2, 114, 103, 101, 110, 100, 3, 47, 6, 112, 0, 2, 114, 103, 101, 110, 100, 0, 114, 110, 2, 101, 32, 3, 47, 6, 112, 34, 50, 0, 114, 110, 2, 25, 3, 47, 6, 113, 34, 14, 50, 0, 4, 1, 97, 17, 67, 2, 114, 105, 110, 103, 3, 47, 6, 116, 0, 1, 107, 2, 114, 105, 110, 103, 0, 4, 114, 101, 110, 100, 101, 1, 101, 112, 2, 32, 3, 47, 6, 116, 34, 13, 50, 72, 13, 0, 114, 101, 110, 100, 101, 1, 105, 2, 32, 0, 114, 101, 110, 100, 101, 1, 107, 101, 2, 32, 0, 114, 101, 110, 100, 101, 1, 108, 117, 2, 32, 0, 114, 101, 110, 100, 101, 1, 114, 101, 118, 2, 32, 0, 114, 101, 110, 100, 101, 1, 115, 97, 2, 32, 0, 108, 101, 1, 21, 2, 32, 3, 47, 6, 116, 55, 13, 0, 115, 101, 2, 32, 3, 47, 6, 116, 89, 13, 0, 115, 101, 115, 2, 32, 3, 47, 6, 116, 89, 13, 89, 0, 4, 117, 114, 1, 17, 65, 3, 47, 6, 128, 34, 0, 117, 114, 1, 107, 0, 101, 110, 2, 97, 114, 103, 117, 3, 47, 7, 116, 50, 0, 4, 1, 17, 65, 2, 108, 105, 110, 103, 3, 47, 13, 0, 1, 17, 65, 10, 2, 108, 112, 0, 1, 17, 65, 17, 67, 2, 108, 101, 110, 100, 0, 1, 17, 65, 21, 2, 103, 101, 17, 67, 0, 1, 17, 67, 21, 2, 17, 67, 0, 1, 17, 67, 21, 2, 109, 97, 114, 107, 0, 1, 21, 2, 111, 112, 0, 1, 97, 119, 2, 114, 105, 110, 103, 0, 1, 101, 105, 110, 2, 109, 105, 110, 0, 2, 32, 0, 2, 97, 97, 0, 2, 100, 111, 109, 0, 2, 111, 110, 100, 101, 114, 0, 2, 111, 111, 0, 2, 114, 114, 17, 65, 0, 8, 2, 98, 111, 119, 101, 0, 8, 2, 110, 111, 0, 8, 2, 119, 101, 0, 4, 114, 1, 10, 2, 116, 17, 65, 21, 3, 47, 13, 34, 0, 114, 1, 21, 2, 116, 121, 100, 0, 114, 1, 97, 119, 2, 116, 0, 114, 8, 2, 108, 0, 114, 8, 2, 110, 17, 65, 0, 114, 8, 2, 119, 0, 114, 105, 101, 1, 110, 3, 47, 13, 34, 6, 37, 0, 114, 117, 103, 103, 101, 101, 2, 12, 3, 47, 13, 34, 6, 111, 136, 116, 0, 4, 114, 100, 1, 10, 2, 32, 3, 47, 13, 34, 47, 0, 114, 116, 1, 10, 2, 114, 0, 114, 116, 106, 105, 101, 1, 10, 3, 47, 13, 34, 49, 37, 0, 114, 109, 101, 115, 1, 10, 3, 47, 13, 34, 65, 108, 89, 0, 114, 101, 103, 8, 3, 47, 13, 34, 112, 136, 0, 107, 111, 114, 3, 47, 13, 49, 110, 34, 0, 107, 101, 114, 101, 8, 3, 47, 13, 49, 116, 34, 13, 0, 4, 110, 1, 21, 2, 98, 97, 99, 104, 3, 47, 13, 50, 0, 110, 1, 21, 2, 100, 101, 114, 119, 121, 25, 0, 110, 105, 115, 3, 47, 13, 50, 109, 89, 0, 110, 97, 97, 114, 3, 47, 13, 50, 115, 34, 0, 4, 108, 1, 10, 2, 32, 3, 47, 13, 55, 0, 108, 1, 21, 2, 111, 0, 108, 1, 117, 101, 108, 115, 0, 108, 116, 106, 105, 101, 3, 47, 13, 55, 49, 37, 0, 108, 115, 1, 10, 2, 32, 3, 47, 13, 55, 89, 0, 108, 101, 117, 114, 3, 47, 13, 55, 128, 34, 0, 118, 111, 114, 101, 3, 47, 13, 83, 6, 117, 34, 13, 0, 118, 101, 114, 8, 2, 21, 3, 47, 13, 83, 13, 34, 0, 115, 97, 109, 101, 3, 47, 13, 89, 115, 65, 13, 0, 103, 101, 8, 2, 17, 67, 17, 65, 3, 47, 13, 136, 13, 0, 114, 117, 103, 8, 2, 14, 128, 132, 133, 3, 47, 14, 34, 6, 111, 136, 0, 114, 117, 103, 103, 101, 8, 2, 21, 14, 128, 132, 135, 3, 47, 14, 34, 6, 111, 136, 13, 0, 1, 17, 67, 2, 116, 106, 105, 101, 3, 47, 37, 0, 2, 107, 107, 105, 101, 12, 3, 47, 108, 0, 114, 114, 105, 195, 171, 114, 3, 47, 108, 34, 37, 13, 34, 0, 107, 115, 2, 12, 3, 47, 108, 49, 89, 0, 110, 2, 100, 101, 114, 3, 47, 108, 50, 0, 110, 110, 105, 115, 3, 47, 108, 50, 13, 89, 0, 110, 116, 2, 32, 3, 47, 108, 50, 47, 0, 110, 116, 101, 2, 32, 3, 47, 108, 50, 47, 13, 0, 109, 112, 111, 2, 32, 3, 47, 108, 65, 48, 2, 40, 0, 109, 112, 101, 114, 3, 47, 108, 65, 48, 13, 34, 0, 109, 112, 101, 108, 3, 47, 108, 65, 48, 13, 55, 0, 4, 1, 17, 67, 21, 2, 103, 110, 3, 47, 112, 0, 1, 17, 67, 21, 2, 107, 32, 0, 1, 17, 67, 21, 2, 108, 98, 111, 114, 100, 0, 1, 17, 67, 21, 2, 108, 108, 0, 1, 17, 67, 21, 2, 110, 107, 0, 2, 108, 0, 114, 109, 1, 21, 2, 32, 3, 47, 112, 34, 13, 65, 0, 114, 114, 97, 2, 99, 3, 47, 112, 34, 35, 0, 114, 116, 1, 10, 3, 47, 112, 34, 47, 0, 114, 109, 101, 1, 21, 2, 32, 3, 47, 112, 34, 65, 13, 0, 114, 116, 105, 8, 2, 17, 65, 25, 3, 47, 112, 34, 91, 57, 0, 108, 1, 101, 103, 2, 32, 3, 47, 112, 55, 0, 4, 108, 101, 1, 21, 2, 102, 111, 3, 47, 112, 55, 13, 0, 108, 101, 1, 21, 2, 103, 114, 97, 0, 108, 101, 107, 115, 3, 47, 112, 55, 108, 49, 89, 0, 4, 114, 116, 1, 115, 10, 2, 97, 97, 110, 3, 47, 113, 34, 47, 0, 114, 116, 1, 115, 10, 2, 101, 32, 0, 4, 1, 21, 2, 102, 105, 101, 32, 3, 47, 116, 0, 1, 21, 2, 108, 101, 114, 0, 1, 110, 105, 115, 2, 116, 105, 0, 1, 110, 121, 109, 2, 114, 105, 110, 103, 0, 1, 115, 2, 107, 105, 110, 103, 0, 4, 114, 105, 110, 103, 1, 115, 101, 108, 111, 109, 3, 47, 116, 34, 13, 68, 0, 114, 105, 110, 103, 8, 0, 4, 107, 1, 21, 2, 101, 110, 3, 47, 116, 49, 0, 107, 1, 112, 97, 2, 17, 65, 0, 107, 101, 110, 2, 17, 65, 3, 47, 116, 49, 13, 50, 0, 108, 101, 114, 8, 3, 47, 116, 55, 13, 34, 0, 119, 101, 2, 32, 3, 47, 116, 84, 13, 0, 119, 101, 110, 115, 8, 3, 47, 116, 84, 13, 50, 89, 0, 115, 105, 2, 115, 3, 47, 116, 89, 13, 0, 105, 107, 101, 110, 3, 47, 123, 49, 13, 50, 0, 7, 6, 116, 114, 0, 101, 107, 101, 110, 3, 47, 10, 34, 116, 49, 13, 50, 0, 97, 2, 106, 101, 107, 3, 47, 34, 2, 35, 0, 97, 112, 2, 115, 111, 101, 3, 47, 34, 2, 35, 48, 0, 97, 107, 8, 2, 116, 97, 3, 47, 34, 2, 35, 49, 0, 4, 97, 110, 115, 8, 2, 21, 14, 128, 132, 133, 3, 47, 34, 2, 35, 50, 89, 0, 97, 110, 115, 8, 2, 97, 107, 115, 105, 101, 0, 97, 110, 115, 101, 110, 100, 101, 110, 116, 2, 17, 65, 3, 47, 34, 2, 35, 50, 89, 2, 108, 50, 72, 2, 108, 50, 47, 0, 97, 110, 115, 105, 116, 111, 3, 47, 34, 2, 35, 50, 89, 37, 47, 2, 40, 0, 97, 110, 115, 112, 97, 2, 114, 97, 110, 116, 3, 47, 34, 2, 35, 50, 89, 48, 13, 0, 97, 110, 115, 112, 111, 114, 116, 3, 47, 34, 2, 35, 50, 89, 48, 110, 34, 47, 0, 97, 110, 115, 105, 115, 116, 111, 114, 3, 47, 34, 2, 35, 50, 89, 109, 89, 47, 13, 34, 0, 97, 100, 105, 2, 115, 105, 3, 47, 34, 2, 35, 72, 37, 0, 97, 103, 2, 101, 100, 3, 47, 34, 2, 35, 136, 0, 105, 2, 111, 109, 102, 3, 47, 34, 2, 37, 0, 105, 111, 109, 102, 2, 97, 110, 116, 3, 47, 34, 2, 37, 2, 110, 65, 83, 0, 4, 111, 2, 116, 115, 101, 101, 114, 3, 47, 34, 2, 110, 0, 111, 2, 116, 115, 101, 114, 105, 110, 103, 0, 4, 111, 109, 8, 2, 98, 3, 47, 34, 2, 110, 65, 0, 111, 109, 8, 2, 112, 101, 116, 0, 111, 103, 108, 111, 2, 100, 105, 101, 3, 47, 34, 2, 110, 136, 55, 2, 40, 0, 117, 2, 115, 116, 101, 101, 3, 47, 34, 2, 111, 0, 97, 103, 101, 2, 111, 116, 111, 109, 105, 3, 47, 34, 2, 115, 136, 2, 37, 0, 105, 115, 101, 1, 21, 2, 32, 3, 47, 34, 6, 37, 89, 13, 0, 105, 115, 101, 115, 1, 21, 2, 32, 3, 47, 34, 6, 37, 89, 13, 89, 0, 101, 101, 114, 1, 21, 3, 47, 34, 6, 116, 34, 0, 111, 117, 115, 115, 101, 97, 117, 3, 47, 34, 7, 40, 12, 89, 120, 0, 105, 8, 2, 98, 117, 3, 47, 34, 13, 0, 105, 108, 2, 106, 111, 101, 110, 3, 47, 34, 13, 55, 0, 105, 98, 117, 8, 2, 110, 97, 3, 47, 34, 13, 71, 2, 118, 0, 97, 112, 2, 111, 114, 114, 3, 47, 34, 35, 48, 10, 0, 97, 119, 2, 97, 3, 47, 34, 35, 84, 6, 0, 105, 111, 2, 32, 3, 47, 34, 37, 12, 40, 0, 101, 102, 2, 97, 102, 115, 3, 47, 34, 108, 83, 10, 0, 105, 118, 105, 97, 3, 47, 34, 109, 84, 37, 57, 2, 35, 0, 101, 2, 107, 3, 47, 34, 112, 0, 101, 107, 107, 101, 114, 3, 47, 34, 112, 49, 13, 34, 0, 97, 110, 115, 8, 2, 100, 97, 110, 115, 3, 47, 34, 115, 50, 89, 0, 101, 101, 114, 1, 21, 2, 17, 65, 3, 47, 34, 116, 34, 0, 101, 100, 105, 110, 103, 1, 10, 3, 47, 34, 116, 72, 13, 68, 0, 4, 117, 2, 112, 114, 111, 106, 101, 107, 3, 47, 34, 118, 0, 117, 2, 115, 112, 105, 101, 195, 171, 0, 117, 107, 2, 97, 97, 116, 115, 3, 47, 34, 118, 49, 0, 101, 110, 115, 2, 32, 3, 47, 34, 134, 50, 89, 0, 7, 6, 117, 105, 0, 116, 2, 100, 97, 103, 101, 110, 3, 2, 127, 0, 4, 116, 2, 98, 117, 110, 100, 3, 2, 127, 47, 0, 116, 2, 100, 114, 117, 107, 0, 116, 2, 104, 117, 105, 115, 105, 103, 0, 116, 2, 109, 117, 110, 116, 101, 110, 0, 116, 2, 115, 108, 117, 105, 116, 101, 110, 0, 116, 2, 115, 112, 97, 116, 116, 0, 116, 2, 115, 116, 101, 107, 101, 110, 0, 116, 2, 118, 111, 101, 114, 98, 97, 0, 116, 2, 118, 111, 101, 114, 105, 103, 0, 116, 2, 119, 105, 115, 98, 97, 0, 116, 2, 101, 101, 110, 3, 2, 127, 47, 10, 0, 116, 101, 101, 110, 2, 108, 111, 112, 3, 2, 127, 47, 10, 2, 116, 50, 0, 116, 109, 101, 2, 107, 97, 97, 114, 3, 2, 127, 47, 65, 13, 0, 116, 115, 116, 97, 97, 110, 2, 17, 67, 3, 2, 127, 47, 89, 47, 115, 50, 0, 116, 115, 112, 114, 101, 101, 107, 108, 3, 2, 127, 47, 89, 48, 34, 116, 49, 55, 0, 116, 115, 112, 97, 116, 108, 105, 107, 3, 2, 127, 47, 89, 48, 35, 47, 55, 13, 49, 0, 116, 115, 108, 117, 105, 116, 108, 105, 107, 3, 2, 127, 47, 89, 55, 127, 47, 55, 13, 49, 0, 116, 115, 111, 110, 100, 101, 114, 108, 105, 2, 107, 3, 2, 127, 47, 89, 110, 50, 13, 34, 55, 13, 0, 116, 101, 105, 110, 100, 101, 108, 105, 3, 2, 127, 47, 123, 50, 72, 13, 55, 13, 0, 116, 8, 2, 21, 14, 128, 132, 131, 3, 6, 127, 47, 0, 116, 103, 101, 8, 2, 21, 14, 128, 132, 133, 3, 6, 127, 47, 136, 13, 0, 116, 103, 101, 101, 2, 12, 3, 6, 127, 47, 136, 116, 0, 4, 3, 127, 0, 2, 116, 106, 105, 101, 0, 101, 2, 17, 67, 3, 127, 13, 0, 4, 116, 2, 100, 114, 117, 107, 32, 24, 3, 127, 47, 0, 116, 2, 100, 114, 117, 107, 107, 105, 110, 103, 32, 0, 116, 2, 100, 114, 117, 107, 107, 105, 110, 103, 115, 0, 116, 2, 101, 101, 110, 108, 111, 111, 112, 3, 127, 47, 10, 0, 116, 101, 114, 3, 127, 47, 13, 34, 0, 116, 105, 110, 103, 3, 127, 47, 13, 68, 0, 116, 107, 101, 2, 110, 3, 127, 47, 49, 108, 0, 116, 115, 116, 97, 97, 110, 2, 114, 3, 127, 47, 89, 47, 115, 50, 0, 116, 103, 101, 119, 101, 114, 3, 127, 47, 136, 2, 116, 84, 13, 34, 0, 116, 103, 101, 119, 101, 114, 112, 3, 127, 47, 136, 13, 84, 112, 34, 48, 0, 116, 103, 101, 119, 101, 114, 107, 3, 127, 47, 136, 13, 84, 112, 34, 49, 0, 7, 6, 118, 101, 0, 4, 1, 21, 2, 32, 3, 21, 0, 115, 1, 17, 65, 2, 32, 0, 116, 101, 2, 114, 97, 3, 83, 2, 108, 47, 13, 0, 114, 116, 105, 2, 107, 97, 3, 83, 2, 112, 34, 47, 2, 37, 0, 4, 101, 108, 2, 100, 117, 105, 100, 3, 83, 2, 116, 55, 0, 101, 108, 2, 106, 97, 114, 0, 101, 108, 2, 115, 21, 21, 0, 114, 2, 107, 121, 107, 101, 114, 3, 83, 6, 113, 34, 0, 114, 103, 101, 115, 111, 103, 8, 3, 83, 6, 113, 34, 38, 136, 13, 89, 110, 136, 0, 114, 101, 110, 100, 2, 32, 3, 83, 6, 116, 34, 13, 50, 47, 0, 114, 101, 110, 100, 101, 3, 83, 6, 116, 34, 13, 50, 72, 13, 0, 114, 105, 110, 103, 3, 83, 6, 116, 34, 13, 68, 0, 108, 101, 3, 83, 6, 116, 55, 13, 0, 114, 115, 102, 8, 3, 83, 7, 112, 34, 89, 83, 0, 114, 2, 115, 112, 114, 105, 110, 103, 3, 83, 7, 113, 34, 0, 4, 114, 3, 83, 13, 34, 0, 114, 2, 102, 108, 101, 110, 17, 67, 0, 114, 2, 102, 114, 105, 115, 0, 114, 2, 118, 101, 108, 17, 65, 0, 114, 8, 2, 21, 14, 128, 132, 131, 0, 114, 97, 110, 116, 2, 119, 3, 83, 13, 34, 2, 35, 50, 47, 0, 114, 111, 110, 103, 101, 8, 2, 21, 14, 128, 132, 135, 3, 83, 13, 34, 6, 131, 68, 136, 13, 0, 4, 114, 97, 110, 116, 2, 119, 111, 111, 114, 100, 32, 3, 83, 13, 34, 10, 35, 50, 47, 0, 114, 97, 110, 116, 2, 119, 111, 111, 114, 100, 101, 32, 24, 0, 114, 101, 114, 2, 105, 110, 103, 3, 83, 13, 34, 10, 116, 34, 0, 114, 116, 101, 2, 108, 3, 83, 13, 34, 47, 112, 0, 114, 116, 101, 114, 2, 17, 65, 3, 83, 13, 34, 47, 116, 34, 0, 114, 108, 97, 110, 103, 115, 2, 97, 3, 83, 13, 34, 55, 6, 35, 68, 89, 0, 114, 98, 101, 116, 101, 3, 83, 13, 34, 71, 6, 116, 47, 13, 0, 114, 98, 121, 3, 83, 13, 34, 71, 123, 0, 4, 114, 102, 2, 105, 3, 83, 13, 34, 83, 0, 114, 102, 2, 114, 111, 109, 0, 114, 102, 8, 2, 108, 111, 117, 0, 114, 102, 8, 2, 111, 0, 114, 118, 101, 114, 115, 105, 110, 103, 3, 83, 13, 34, 83, 6, 112, 34, 89, 13, 68, 0, 114, 102, 121, 110, 3, 83, 13, 34, 83, 6, 123, 50, 0, 114, 115, 116, 101, 114, 1, 21, 2, 107, 3, 83, 13, 34, 89, 47, 112, 34, 0, 114, 111, 110, 100, 101, 114, 115, 116, 101, 2, 108, 3, 83, 13, 34, 110, 50, 13, 34, 89, 47, 6, 112, 0, 114, 103, 101, 116, 101, 3, 83, 13, 34, 136, 6, 116, 47, 13, 0, 114, 103, 101, 119, 101, 8, 3, 83, 13, 34, 136, 116, 84, 13, 0, 4, 110, 2, 100, 117, 115, 105, 101, 3, 83, 13, 50, 0, 110, 2, 121, 110, 0, 2, 115, 116, 3, 83, 108, 0, 116, 8, 2, 17, 65, 3, 83, 108, 47, 10, 0, 2, 108, 3, 83, 112, 0, 114, 2, 103, 101, 115, 105, 103, 3, 83, 112, 34, 0, 4, 114, 102, 3, 83, 112, 34, 83, 0, 114, 102, 2, 21, 0, 114, 119, 101, 2, 32, 3, 83, 112, 34, 84, 13, 0, 114, 119, 101, 114, 2, 32, 3, 83, 112, 34, 84, 13, 34, 0, 114, 119, 101, 114, 121, 3, 83, 112, 34, 84, 13, 34, 2, 123, 0, 114, 119, 101, 114, 115, 3, 83, 112, 34, 84, 13, 34, 89, 0, 4, 114, 115, 1, 21, 2, 32, 3, 83, 112, 34, 89, 0, 114, 115, 1, 21, 2, 101, 32, 0, 114, 115, 2, 100, 0, 114, 115, 2, 107, 117, 110, 115, 0, 114, 115, 2, 114, 0, 114, 115, 2, 118, 0, 114, 115, 8, 2, 98, 0, 114, 115, 101, 1, 17, 67, 2, 32, 3, 83, 112, 34, 89, 13, 0, 108, 100, 2, 17, 67, 3, 83, 112, 55, 47, 0, 4, 108, 100, 2, 101, 107, 115, 3, 83, 112, 55, 47, 10, 0, 108, 100, 2, 111, 0, 4, 103, 2, 101, 101, 110, 3, 83, 112, 136, 10, 0, 103, 2, 111, 0, 4, 114, 1, 17, 67, 21, 2, 32, 3, 83, 113, 34, 0, 114, 2, 114, 101, 105, 107, 0, 114, 2, 115, 105, 101, 32, 0, 114, 2, 115, 105, 101, 115, 32, 0, 114, 108, 97, 110, 103, 115, 8, 3, 83, 113, 34, 55, 35, 68, 89, 0, 4, 114, 115, 2, 107, 97, 108, 17, 67, 3, 83, 113, 34, 89, 0, 114, 115, 2, 112, 97, 110, 111, 114, 0, 114, 115, 2, 97, 108, 98, 117, 109, 3, 83, 113, 34, 89, 10, 0, 114, 115, 101, 2, 98, 3, 83, 113, 34, 89, 13, 0, 114, 103, 101, 2, 115, 116, 114, 101, 107, 3, 83, 113, 34, 136, 13, 0, 4, 114, 101, 2, 32, 3, 83, 116, 34, 13, 0, 114, 101, 2, 98, 0, 114, 101, 2, 100, 111, 0, 114, 101, 2, 104, 0, 114, 101, 2, 107, 0, 114, 101, 2, 109, 0, 114, 101, 2, 115, 116, 111, 0, 114, 101, 2, 118, 0, 4, 116, 111, 8, 2, 114, 101, 103, 3, 83, 116, 47, 2, 40, 0, 116, 111, 8, 2, 115, 116, 101, 109, 0, 116, 101, 2, 29, 3, 83, 116, 47, 13, 0, 116, 101, 114, 2, 25, 3, 83, 116, 47, 13, 34, 0, 108, 1, 21, 2, 17, 65, 3, 83, 116, 55, 0, 110, 2, 115, 116, 101, 114, 3, 83, 134, 50, 0, 114, 105, 102, 105, 2, 21, 3, 84, 2, 108, 34, 2, 37, 83, 2, 37, 0, 110, 2, 100, 101, 116, 116, 97, 3, 84, 2, 108, 50, 0, 4, 114, 2, 98, 97, 97, 108, 3, 84, 2, 112, 34, 0, 114, 2, 98, 97, 108, 17, 65, 0, 114, 115, 105, 102, 105, 2, 17, 67, 3, 84, 2, 112, 34, 89, 2, 37, 83, 2, 37, 0, 114, 115, 101, 1, 17, 65, 25, 2, 32, 3, 84, 6, 112, 34, 89, 13, 0, 114, 97, 110, 100, 97, 3, 84, 13, 34, 35, 50, 72, 35, 0, 114, 98, 101, 110, 97, 3, 84, 13, 34, 71, 116, 50, 2, 35, 0, 110, 101, 2, 115, 105, 17, 65, 3, 84, 13, 50, 37, 12, 0, 114, 1, 111, 114, 116, 2, 25, 3, 84, 112, 34, 0, 2, 110, 117, 115, 3, 84, 116, 0, 7, 6, 118, 111, 0, 114, 2, 32, 3, 21, 0, 4, 2, 107, 97, 3, 83, 2, 40, 0, 8, 2, 109, 101, 0, 2, 108, 17, 67, 3, 83, 2, 110, 0, 4, 108, 2, 98, 114, 105, 110, 103, 3, 83, 2, 110, 55, 0, 108, 2, 103, 114, 111, 101, 105, 0, 108, 2, 107, 111, 109, 101, 0, 108, 2, 101, 105, 110, 100, 105, 103, 3, 83, 2, 110, 55, 10, 0, 108, 108, 101, 2, 100, 105, 103, 3, 83, 2, 110, 55, 116, 0, 4, 111, 114, 2, 107, 111, 109, 98, 97, 3, 83, 2, 117, 34, 0, 111, 114, 2, 115, 105, 101, 0, 111, 114, 2, 115, 112, 111, 101, 100, 105, 0, 111, 114, 8, 2, 100, 101, 108, 105, 103, 0, 111, 114, 8, 2, 107, 111, 109, 17, 65, 0, 4, 111, 114, 2, 97, 102, 103, 97, 97, 110, 3, 83, 2, 117, 34, 10, 0, 111, 114, 116, 2, 100, 117, 114, 101, 110, 0, 111, 114, 116, 2, 118, 21, 21, 3, 83, 2, 117, 34, 47, 0, 111, 114, 119, 97, 97, 114, 100, 101, 2, 32, 3, 83, 2, 117, 34, 84, 115, 34, 72, 13, 0, 111, 114, 115, 116, 101, 100, 101, 108, 105, 2, 107, 3, 83, 2, 117, 34, 89, 47, 116, 72, 13, 55, 13, 0, 111, 114, 115, 107, 114, 105, 102, 116, 101, 108, 105, 2, 107, 3, 83, 2, 117, 34, 89, 49, 34, 109, 83, 47, 13, 55, 13, 0, 111, 103, 2, 100, 121, 3, 83, 2, 117, 136, 0, 101, 114, 105, 103, 1, 21, 3, 83, 6, 40, 34, 13, 136, 0, 108, 111, 112, 3, 83, 6, 110, 55, 10, 110, 48, 0, 114, 101, 110, 3, 83, 6, 117, 34, 13, 50, 0, 111, 114, 98, 101, 8, 2, 21, 14, 128, 132, 134, 3, 83, 6, 117, 34, 71, 13, 0, 111, 114, 103, 101, 8, 2, 21, 14, 128, 132, 134, 3, 83, 6, 117, 34, 136, 13, 0, 108, 2, 109, 97, 103, 3, 83, 7, 110, 55, 0, 4, 2, 108, 108, 17, 65, 32, 3, 83, 110, 0, 2, 108, 108, 101, 114, 0, 114, 109, 3, 83, 110, 34, 13, 65, 0, 114, 115, 116, 105, 2, 110, 3, 83, 110, 34, 89, 47, 6, 109, 0, 4, 108, 2, 98, 3, 83, 110, 55, 0, 108, 2, 103, 0, 108, 2, 104, 111, 117, 32, 0, 108, 2, 109, 97, 97, 110, 0, 108, 2, 109, 97, 110, 101, 0, 108, 2, 112, 114, 111, 112, 0, 108, 2, 114, 0, 108, 2, 115, 105, 17, 67, 0, 108, 2, 115, 116, 101, 32, 0, 108, 2, 115, 116, 111, 0, 108, 8, 2, 115, 107, 0, 108, 108, 101, 115, 2, 32, 3, 83, 110, 55, 13, 89, 0, 108, 116, 121, 100, 115, 3, 83, 110, 55, 47, 123, 47, 89, 0, 108, 107, 3, 83, 110, 55, 49, 0, 108, 107, 101, 3, 83, 110, 55, 49, 13, 0, 108, 119, 97, 115, 115, 101, 3, 83, 110, 55, 84, 6, 35, 89, 13, 0, 108, 108, 2, 101, 110, 103, 116, 101, 3, 83, 110, 55, 108, 0, 4, 111, 114, 2, 115, 107, 3, 83, 117, 34, 0, 111, 114, 2, 116, 114, 97, 112, 0, 111, 114, 2, 116, 114, 101, 107, 0, 111, 114, 8, 2, 98, 101, 101, 12, 0, 111, 114, 2, 17, 65, 3, 83, 117, 34, 10, 0, 111, 114, 117, 105, 116, 8, 3, 83, 117, 34, 10, 6, 127, 47, 0, 111, 114, 98, 97, 114, 3, 83, 117, 34, 71, 6, 115, 34, 0, 111, 114, 119, 97, 97, 114, 100, 101, 2, 32, 24, 3, 83, 117, 34, 84, 115, 34, 72, 13, 0, 111, 114, 115, 112, 101, 2, 108, 25, 3, 83, 117, 34, 89, 48, 6, 112, 0, 111, 114, 117, 105, 116, 2, 115, 116, 114, 101, 119, 3, 83, 117, 34, 127, 47, 6, 0, 108, 117, 109, 101, 3, 84, 2, 110, 55, 118, 65, 13, 0, 100, 107, 97, 3, 84, 110, 47, 49, 35, 0, 7, 6, 119, 101, 0, 8, 2, 108, 108, 21, 21, 3, 84, 2, 112, 0, 114, 107, 2, 115, 116, 101, 108, 108, 105, 3, 84, 2, 112, 34, 49, 0, 4, 108, 2, 115, 107, 97, 112, 101, 3, 84, 2, 112, 55, 0, 108, 2, 115, 112, 114, 101, 107, 101, 110, 0, 108, 2, 119, 105, 108, 0, 108, 8, 2, 114, 0, 108, 8, 2, 118, 0, 108, 8, 2, 101, 100, 101, 108, 3, 84, 2, 112, 55, 10, 0, 108, 98, 101, 104, 97, 97, 103, 108, 105, 107, 3, 84, 2, 112, 55, 71, 13, 107, 115, 136, 55, 13, 49, 0, 101, 2, 109, 111, 101, 100, 105, 3, 84, 2, 116, 0, 4, 101, 114, 2, 98, 97, 114, 115, 116, 3, 84, 2, 116, 34, 0, 101, 114, 2, 104, 111, 117, 0, 101, 114, 2, 107, 97, 97, 116, 115, 0, 101, 114, 2, 108, 101, 103, 0, 101, 114, 2, 108, 195, 170, 0, 101, 114, 2, 115, 116, 97, 97, 110, 0, 101, 114, 2, 115, 116, 114, 101, 119, 0, 101, 116, 2, 103, 105, 101, 114, 105, 103, 3, 84, 2, 116, 47, 0, 100, 101, 114, 2, 118, 97, 3, 84, 2, 116, 72, 13, 34, 0, 107, 107, 101, 110, 100, 1, 21, 3, 84, 6, 108, 49, 13, 50, 47, 0, 107, 107, 101, 110, 100, 101, 1, 21, 3, 84, 6, 108, 49, 13, 50, 72, 13, 0, 110, 100, 105, 103, 1, 21, 3, 84, 6, 108, 50, 72, 13, 136, 0, 103, 103, 101, 8, 2, 17, 67, 21, 14, 128, 132, 133, 3, 84, 6, 112, 136, 13, 0, 115, 105, 103, 104, 101, 105, 100, 1, 21, 3, 84, 6, 116, 89, 13, 136, 123, 47, 0, 114, 1, 17, 65, 2, 17, 65, 17, 65, 3, 84, 13, 34, 0, 110, 101, 1, 10, 2, 32, 3, 84, 13, 50, 13, 0, 110, 115, 1, 101, 110, 3, 84, 13, 50, 89, 0, 1, 17, 67, 21, 2, 116, 25, 3, 84, 108, 0, 4, 100, 1, 21, 2, 115, 116, 114, 3, 84, 108, 47, 0, 100, 1, 115, 2, 17, 67, 0, 100, 121, 119, 101, 114, 3, 84, 108, 47, 123, 84, 13, 34, 0, 110, 8, 2, 97, 17, 67, 3, 84, 108, 50, 19, 0, 98, 8, 3, 84, 108, 71, 0, 100, 100, 1, 115, 2, 21, 3, 84, 108, 72, 0, 114, 112, 3, 84, 112, 34, 48, 0, 114, 107, 1, 116, 3, 84, 112, 34, 49, 0, 114, 119, 101, 108, 3, 84, 112, 34, 84, 13, 55, 0, 108, 2, 118, 97, 97, 114, 116, 3, 84, 112, 55, 0, 108, 102, 2, 32, 3, 84, 112, 55, 83, 0, 4, 103, 1, 21, 2, 32, 3, 84, 112, 136, 0, 103, 1, 114, 111, 111, 112, 115, 0, 103, 1, 25, 2, 111, 3, 84, 112, 136, 10, 0, 101, 114, 1, 115, 17, 65, 2, 32, 3, 84, 116, 34, 0, 101, 114, 8, 2, 115, 112, 3, 84, 116, 34, 6, 0, 114, 101, 1, 101, 103, 3, 84, 116, 34, 13, 0, 114, 105, 110, 103, 1, 17, 67, 21, 2, 32, 3, 84, 116, 34, 13, 68, 0, 116, 101, 110, 2, 17, 67, 3, 84, 116, 47, 13, 50, 0, 107, 101, 8, 2, 17, 67, 3, 84, 116, 49, 13, 0, 101, 115, 1, 21, 2, 32, 3, 84, 116, 89, 0, 105, 102, 101, 2, 108, 3, 84, 123, 83, 13, 0, 110, 115, 1, 115, 101, 101, 102, 3, 84, 134, 50, 89, 0, 7, 6, 97, 0, 4, 1, 17, 67, 2, 17, 67, 115, 105, 101, 114, 3, 2, 35, 0, 1, 17, 67, 2, 114, 105, 110, 97, 0, 1, 17, 67, 2, 116, 101, 114, 105, 110, 103, 0, 1, 17, 67, 11, 2, 32, 0, 1, 17, 67, 17, 65, 2, 32, 0, 1, 17, 67, 21, 2, 116, 105, 101, 102, 0, 1, 17, 67, 21, 2, 116, 105, 101, 119, 101, 0, 1, 21, 2, 17, 67, 105, 115, 97, 115, 105, 101, 0, 1, 21, 2, 17, 67, 105, 115, 101, 101, 114, 0, 1, 21, 2, 17, 67, 105, 115, 101, 114, 105, 110, 103, 0, 1, 98, 10, 2, 32, 0, 1, 100, 2, 103, 111, 103, 103, 101, 110, 0, 1, 100, 10, 2, 32, 0, 1, 105, 2, 32, 0, 1, 105, 2, 116, 105, 101, 17, 67, 0, 1, 106, 2, 112, 97, 110, 0, 1, 109, 21, 2, 116, 105, 101, 107, 0, 1, 109, 114, 10, 2, 32, 0, 1, 114, 10, 2, 32, 0, 1, 116, 10, 2, 32, 24, 0, 2, 17, 67, 17, 65, 17, 65, 0, 2, 17, 67, 121, 0, 2, 102, 102, 108, 105, 107, 0, 2, 103, 105, 116, 17, 65, 0, 2, 103, 111, 110, 105, 101, 0, 2, 103, 117, 114, 107, 105, 101, 0, 2, 107, 107, 111, 111, 114, 100, 0, 2, 108, 97, 114, 109, 0, 2, 108, 105, 115, 109, 101, 0, 2, 108, 105, 116, 101, 105, 116, 0, 2, 109, 101, 110, 116, 0, 2, 114, 105, 115, 116, 111, 107, 114, 0, 2, 115, 105, 101, 108, 0, 2, 115, 112, 101, 114, 115, 105, 101, 0, 2, 116, 111, 109, 17, 65, 0, 8, 2, 98, 17, 67, 0, 8, 2, 102, 102, 17, 65, 0, 8, 2, 107, 117, 0, 8, 2, 107, 119, 97, 116, 0, 8, 2, 108, 17, 65, 0, 8, 2, 108, 108, 111, 111, 105, 0, 8, 2, 108, 108, 117, 0, 8, 2, 112, 17, 67, 0, 8, 2, 112, 111, 0, 8, 2, 115, 116, 114, 17, 65, 0, 8, 107, 2, 110, 17, 65, 0, 102, 2, 118, 97, 108, 108, 105, 103, 0, 4, 114, 1, 25, 2, 112, 117, 105, 115, 3, 2, 35, 34, 0, 114, 2, 103, 97, 195, 175, 0, 114, 2, 109, 111, 101, 100, 105, 103, 0, 114, 2, 115, 101, 101, 110, 0, 114, 2, 116, 105, 107, 101, 108, 0, 114, 8, 2, 103, 105, 0, 114, 8, 2, 111, 109, 0, 114, 97, 2, 98, 105, 101, 114, 3, 2, 35, 34, 2, 35, 0, 114, 97, 98, 101, 2, 115, 107, 3, 2, 35, 34, 2, 35, 71, 108, 0, 114, 101, 2, 111, 108, 17, 65, 3, 2, 35, 34, 2, 37, 0, 114, 114, 111, 2, 103, 3, 2, 35, 34, 2, 40, 0, 114, 121, 1, 108, 101, 107, 107, 111, 109, 115, 21, 21, 21, 3, 2, 35, 34, 2, 123, 0, 114, 114, 101, 2, 115, 116, 17, 65, 3, 2, 35, 34, 13, 0, 4, 114, 109, 2, 108, 97, 115, 116, 3, 2, 35, 34, 14, 65, 0, 114, 109, 2, 115, 97, 108, 105, 103, 0, 114, 116, 105, 107, 117, 3, 2, 35, 34, 47, 2, 37, 49, 2, 118, 0, 114, 116, 101, 2, 102, 97, 107, 3, 2, 35, 34, 47, 13, 0, 114, 116, 105, 108, 108, 101, 2, 114, 105, 101, 3, 2, 35, 34, 47, 13, 55, 13, 0, 114, 116, 101, 8, 2, 114, 105, 3, 2, 35, 34, 47, 116, 0, 114, 115, 101, 2, 110, 97, 3, 2, 35, 34, 89, 13, 0, 114, 114, 101, 115, 2, 32, 3, 2, 35, 34, 108, 89, 0, 114, 97, 2, 98, 105, 3, 2, 35, 34, 115, 0, 114, 101, 110, 97, 2, 25, 12, 3, 2, 35, 34, 116, 50, 2, 35, 0, 114, 103, 2, 108, 105, 115, 116, 3, 2, 35, 34, 136, 0, 114, 103, 105, 116, 101, 107, 3, 2, 35, 34, 136, 2, 37, 47, 108, 49, 0, 114, 103, 101, 2, 116, 105, 112, 3, 2, 35, 34, 136, 13, 0, 114, 103, 101, 110, 2, 116, 17, 65, 3, 2, 35, 34, 136, 13, 50, 0, 4, 100, 2, 118, 105, 101, 115, 3, 2, 35, 47, 0, 116, 2, 108, 97, 110, 116, 0, 116, 2, 108, 101, 0, 116, 116, 101, 115, 116, 2, 17, 65, 3, 2, 35, 47, 2, 108, 89, 47, 0, 116, 111, 114, 105, 101, 115, 1, 21, 3, 2, 35, 47, 6, 117, 34, 37, 89, 0, 4, 116, 101, 1, 115, 2, 108, 3, 2, 35, 47, 13, 0, 116, 104, 101, 1, 17, 67, 2, 114, 105, 110, 97, 0, 116, 114, 111, 2, 102, 105, 101, 3, 2, 35, 47, 34, 2, 40, 0, 116, 116, 114, 105, 98, 2, 117, 3, 2, 35, 47, 34, 13, 71, 0, 116, 108, 101, 2, 116, 105, 101, 107, 3, 2, 35, 47, 55, 13, 0, 100, 109, 105, 2, 114, 3, 2, 35, 47, 65, 2, 37, 0, 116, 109, 111, 2, 115, 102, 101, 3, 2, 35, 47, 65, 2, 110, 0, 100, 109, 105, 110, 105, 3, 2, 35, 47, 65, 13, 50, 13, 0, 100, 109, 105, 2, 115, 115, 105, 101, 3, 2, 35, 47, 65, 37, 0, 116, 101, 108, 2, 106, 101, 101, 3, 2, 35, 47, 114, 0, 112, 111, 2, 107, 114, 105, 101, 17, 67, 3, 2, 35, 48, 2, 40, 0, 112, 111, 107, 97, 2, 108, 3, 2, 35, 48, 2, 110, 49, 2, 35, 0, 112, 111, 108, 111, 103, 2, 17, 65, 3, 2, 35, 48, 2, 110, 55, 2, 40, 136, 0, 112, 112, 101, 2, 108, 108, 17, 65, 3, 2, 35, 48, 13, 0, 112, 112, 97, 114, 2, 17, 65, 3, 2, 35, 48, 13, 34, 0, 112, 112, 101, 108, 8, 2, 107, 111, 21, 3, 2, 35, 48, 13, 55, 0, 112, 111, 115, 116, 111, 2, 108, 105, 101, 3, 2, 35, 48, 13, 89, 47, 117, 0, 112, 112, 114, 111, 112, 114, 105, 2, 17, 65, 3, 2, 35, 48, 34, 2, 117, 48, 34, 2, 37, 0, 112, 97, 114, 116, 3, 2, 35, 48, 35, 34, 47, 0, 112, 112, 108, 105, 2, 107, 97, 110, 116, 3, 2, 35, 48, 55, 2, 37, 0, 98, 115, 111, 2, 108, 117, 3, 2, 35, 48, 89, 2, 40, 0, 98, 115, 101, 2, 115, 3, 2, 35, 48, 89, 108, 0, 112, 112, 101, 110, 2, 100, 105, 17, 67, 3, 2, 35, 48, 108, 50, 0, 107, 2, 115, 121, 110, 3, 2, 35, 49, 0, 107, 111, 2, 17, 67, 105, 101, 116, 3, 2, 35, 49, 2, 40, 0, 107, 107, 111, 109, 109, 111, 2, 100, 3, 2, 35, 49, 2, 110, 65, 13, 0, 107, 107, 117, 2, 114, 97, 3, 2, 35, 49, 2, 118, 0, 107, 97, 2, 100, 101, 21, 3, 2, 35, 49, 13, 0, 107, 107, 101, 100, 105, 3, 2, 35, 49, 13, 72, 109, 0, 107, 114, 111, 2, 98, 97, 3, 2, 35, 49, 34, 2, 40, 0, 107, 116, 117, 97, 114, 105, 2, 17, 65, 3, 2, 35, 49, 47, 2, 118, 2, 35, 34, 2, 37, 0, 107, 119, 97, 114, 101, 2, 108, 3, 2, 35, 49, 58, 2, 35, 34, 112, 0, 107, 119, 97, 109, 97, 2, 114, 121, 110, 3, 2, 35, 49, 58, 2, 35, 65, 2, 35, 0, 107, 97, 2, 115, 105, 97, 3, 2, 35, 49, 115, 0, 110, 111, 2, 110, 105, 21, 3, 2, 35, 50, 2, 40, 0, 110, 116, 101, 114, 105, 110, 103, 3, 2, 35, 50, 47, 116, 34, 13, 68, 0, 4, 108, 2, 98, 97, 115, 116, 101, 114, 3, 2, 35, 55, 0, 108, 2, 98, 105, 110, 111, 0, 108, 2, 106, 97, 110, 100, 101, 114, 0, 108, 8, 2, 119, 101, 0, 108, 117, 2, 109, 105, 110, 105, 117, 109, 3, 2, 35, 55, 2, 40, 0, 108, 101, 120, 2, 97, 3, 2, 35, 55, 2, 108, 49, 88, 0, 108, 101, 107, 115, 97, 110, 100, 2, 114, 121, 3, 2, 35, 55, 2, 108, 49, 89, 2, 35, 50, 72, 0, 4, 108, 105, 8, 17, 67, 2, 102, 111, 114, 110, 105, 3, 2, 35, 55, 13, 0, 108, 108, 101, 2, 109, 105, 110, 116, 0, 108, 108, 101, 114, 2, 103, 105, 101, 32, 24, 3, 2, 35, 55, 13, 34, 0, 108, 8, 2, 101, 119, 105, 103, 3, 2, 35, 55, 38, 0, 108, 107, 111, 104, 111, 108, 2, 105, 101, 25, 3, 2, 35, 55, 49, 2, 40, 107, 117, 55, 0, 108, 109, 97, 2, 110, 97, 107, 3, 2, 35, 55, 65, 2, 35, 0, 108, 102, 97, 98, 101, 2, 116, 17, 65, 3, 2, 35, 55, 83, 2, 35, 71, 116, 0, 108, 108, 101, 114, 2, 103, 105, 101, 3, 2, 35, 55, 112, 34, 0, 108, 108, 101, 2, 110, 17, 65, 3, 2, 35, 55, 116, 0, 108, 108, 101, 101, 110, 3, 2, 35, 55, 116, 50, 0, 108, 99, 104, 101, 2, 109, 105, 3, 2, 35, 55, 136, 2, 116, 0, 108, 103, 101, 2, 114, 121, 110, 3, 2, 35, 55, 136, 13, 0, 4, 109, 8, 2, 17, 65, 3, 2, 35, 65, 0, 109, 8, 2, 110, 17, 65, 0, 109, 97, 114, 117, 108, 97, 3, 2, 35, 65, 2, 35, 34, 40, 55, 2, 35, 0, 109, 97, 115, 111, 110, 101, 3, 2, 35, 65, 2, 35, 89, 117, 50, 13, 0, 109, 117, 2, 17, 67, 17, 65, 3, 2, 35, 65, 2, 118, 0, 109, 112, 105, 2, 111, 101, 110, 3, 2, 35, 65, 48, 2, 37, 0, 109, 98, 97, 115, 115, 2, 97, 100, 101, 3, 2, 35, 65, 71, 2, 35, 89, 0, 109, 98, 97, 115, 115, 97, 2, 100, 101, 117, 3, 2, 35, 65, 71, 2, 35, 89, 2, 35, 0, 109, 98, 117, 2, 108, 3, 2, 35, 65, 71, 2, 118, 0, 109, 101, 114, 2, 105, 107, 3, 2, 35, 65, 116, 34, 0, 109, 109, 111, 2, 110, 105, 17, 65, 3, 2, 35, 65, 117, 0, 98, 111, 8, 2, 17, 67, 3, 2, 35, 71, 110, 0, 4, 98, 101, 108, 1, 116, 3, 2, 35, 71, 112, 55, 0, 98, 101, 108, 108, 1, 116, 0, 100, 111, 108, 101, 115, 115, 101, 110, 3, 2, 35, 72, 2, 117, 55, 13, 89, 108, 50, 0, 100, 114, 101, 110, 97, 2, 108, 105, 3, 2, 35, 72, 34, 13, 50, 2, 35, 0, 100, 114, 101, 2, 25, 3, 2, 35, 72, 34, 108, 0, 103, 97, 2, 112, 97, 110, 116, 3, 2, 35, 81, 2, 35, 0, 4, 102, 2, 103, 117, 110, 115, 116, 105, 103, 3, 2, 35, 83, 0, 102, 2, 104, 97, 110, 107, 0, 102, 2, 115, 105, 103, 116, 101, 0, 102, 2, 115, 107, 117, 119, 0, 102, 2, 115, 121, 100, 105, 103, 0, 102, 2, 119, 97, 103, 116, 101, 110, 0, 102, 8, 2, 107, 101, 114, 105, 103, 0, 102, 8, 2, 107, 111, 109, 115, 116, 105, 103, 0, 102, 102, 111, 2, 100, 105, 108, 3, 2, 35, 83, 2, 40, 0, 118, 111, 107, 97, 100, 101, 3, 2, 35, 83, 2, 40, 49, 115, 72, 13, 0, 118, 111, 107, 97, 100, 111, 3, 2, 35, 83, 2, 40, 49, 115, 72, 40, 0, 102, 114, 105, 107, 2, 97, 97, 110, 3, 2, 35, 83, 34, 2, 37, 49, 0, 102, 114, 105, 107, 97, 110, 101, 2, 25, 3, 2, 35, 83, 34, 2, 37, 49, 115, 50, 13, 0, 4, 102, 114, 111, 2, 100, 105, 116, 3, 2, 35, 83, 34, 2, 40, 0, 112, 104, 114, 111, 2, 100, 105, 116, 0, 102, 102, 114, 111, 2, 110, 116, 3, 2, 35, 83, 34, 2, 110, 0, 102, 119, 101, 115, 105, 103, 3, 2, 35, 83, 84, 116, 89, 13, 136, 0, 102, 115, 116, 111, 111, 116, 108, 3, 2, 35, 83, 89, 47, 117, 47, 55, 0, 102, 115, 111, 110, 100, 101, 114, 108, 3, 2, 35, 83, 89, 110, 50, 13, 34, 55, 0, 102, 103, 114, 121, 115, 108, 105, 107, 3, 2, 35, 83, 136, 34, 123, 89, 55, 13, 49, 0, 118, 111, 110, 116, 117, 2, 114, 105, 101, 114, 3, 2, 35, 84, 2, 110, 50, 47, 2, 118, 0, 115, 8, 2, 107, 101, 3, 2, 35, 89, 0, 115, 115, 117, 2, 114, 97, 110, 3, 2, 35, 89, 2, 111, 0, 115, 115, 111, 115, 105, 2, 17, 65, 3, 2, 35, 89, 2, 117, 91, 2, 37, 0, 115, 115, 101, 2, 103, 97, 97, 105, 3, 2, 35, 89, 13, 0, 115, 115, 105, 115, 116, 3, 2, 35, 89, 13, 89, 47, 0, 115, 112, 105, 8, 2, 114, 17, 65, 3, 2, 35, 89, 48, 2, 37, 0, 115, 112, 101, 107, 3, 2, 35, 89, 48, 108, 49, 0, 115, 107, 105, 116, 101, 8, 3, 2, 35, 89, 49, 37, 47, 13, 0, 115, 107, 97, 114, 105, 3, 2, 35, 89, 49, 115, 34, 2, 37, 0, 115, 98, 101, 115, 8, 3, 2, 35, 89, 71, 108, 89, 0, 115, 115, 101, 2, 115, 115, 111, 114, 3, 2, 35, 89, 108, 0, 115, 115, 105, 115, 1, 114, 2, 25, 3, 2, 35, 89, 109, 89, 0, 103, 111, 110, 105, 101, 2, 32, 24, 3, 2, 35, 136, 2, 40, 50, 37, 0, 103, 116, 101, 2, 108, 111, 115, 105, 103, 3, 2, 35, 136, 47, 13, 0, 4, 103, 116, 101, 114, 2, 98, 97, 107, 3, 2, 35, 136, 47, 13, 34, 0, 103, 116, 101, 114, 2, 100, 111, 103, 116, 0, 103, 116, 101, 114, 2, 108, 111, 115, 105, 103, 0, 103, 116, 101, 114, 2, 109, 105, 100, 100, 97, 0, 103, 116, 101, 114, 2, 115, 116, 97, 108, 108, 0, 103, 116, 101, 114, 2, 118, 111, 108, 103, 0, 103, 116, 101, 114, 2, 111, 111, 114, 3, 2, 35, 136, 47, 13, 34, 10, 0, 103, 116, 101, 114, 101, 101, 110, 2, 118, 111, 108, 103, 3, 2, 35, 136, 47, 13, 34, 10, 2, 116, 50, 0, 103, 116, 101, 114, 2, 117, 105, 116, 3, 2, 35, 136, 47, 13, 34, 19, 0, 103, 101, 110, 116, 3, 2, 35, 136, 108, 50, 47, 0, 103, 101, 110, 100, 97, 3, 2, 35, 136, 108, 50, 72, 2, 35, 0, 103, 101, 2, 114, 101, 110, 100, 3, 2, 35, 136, 116, 0, 117, 103, 117, 115, 116, 117, 115, 3, 2, 110, 136, 111, 89, 47, 111, 89, 0, 2, 112, 111, 108, 105, 116, 105, 3, 2, 115, 0, 117, 115, 116, 114, 97, 3, 2, 117, 89, 47, 34, 115, 0, 195, 171, 2, 114, 111, 98, 105, 3, 2, 121, 0, 118, 111, 110, 2, 116, 3, 4, 35, 84, 110, 50, 0, 108, 103, 101, 109, 101, 101, 110, 3, 6, 35, 55, 136, 13, 65, 4, 116, 50, 0, 102, 8, 2, 21, 14, 128, 132, 130, 3, 6, 35, 83, 0, 102, 103, 101, 8, 2, 21, 14, 128, 132, 132, 3, 6, 35, 83, 136, 13, 0, 102, 103, 101, 101, 2, 12, 3, 6, 35, 83, 136, 116, 0, 103, 116, 101, 114, 103, 101, 8, 2, 21, 14, 128, 132, 135, 3, 6, 35, 136, 47, 13, 34, 136, 13, 0, 103, 116, 105, 103, 1, 10, 3, 6, 35, 136, 47, 13, 136, 0, 4, 1, 105, 2, 116, 105, 101, 115, 3, 6, 115, 0, 2, 114, 105, 17, 65, 0, 8, 17, 67, 2, 17, 67, 105, 101, 32, 0, 116, 111, 114, 1, 21, 2, 25, 3, 6, 115, 47, 110, 34, 0, 98, 101, 108, 1, 116, 107, 101, 112, 115, 3, 6, 115, 71, 13, 55, 0, 98, 105, 101, 1, 17, 67, 3, 6, 115, 71, 37, 0, 100, 8, 17, 67, 114, 97, 2, 17, 65, 3, 6, 115, 72, 0, 100, 105, 103, 1, 21, 3, 6, 115, 72, 13, 136, 0, 100, 105, 101, 115, 1, 17, 67, 17, 65, 3, 6, 115, 72, 37, 89, 0, 115, 105, 101, 1, 17, 67, 3, 6, 115, 89, 37, 0, 103, 116, 101, 114, 8, 2, 101, 110, 3, 7, 35, 136, 47, 13, 34, 10, 0, 116, 116, 97, 99, 104, 195, 169, 3, 10, 2, 35, 47, 2, 35, 91, 116, 0, 4, 99, 107, 2, 32, 3, 21, 0, 121, 2, 32, 0, 121, 115, 2, 32, 0, 4, 105, 110, 101, 2, 32, 3, 21, 102, 114, 0, 105, 114, 101, 1, 21, 2, 32, 0, 4, 1, 17, 67, 2, 120, 17, 65, 12, 3, 35, 0, 1, 107, 10, 2, 32, 0, 1, 116, 115, 2, 116, 105, 115, 116, 0, 2, 17, 67, 0, 8, 2, 98, 98, 97, 0, 2, 100, 114, 101, 115, 3, 35, 6, 0, 114, 121, 1, 108, 101, 17, 67, 3, 35, 34, 6, 123, 0, 114, 109, 101, 115, 8, 3, 35, 34, 19, 65, 13, 89, 0, 100, 8, 112, 2, 17, 65, 3, 35, 47, 0, 116, 116, 101, 110, 2, 17, 67, 3, 35, 47, 6, 108, 50, 0, 116, 111, 114, 101, 1, 21, 2, 32, 3, 35, 47, 6, 117, 34, 13, 0, 116, 116, 101, 110, 2, 100, 3, 35, 47, 13, 50, 0, 112, 112, 8, 2, 17, 65, 3, 35, 48, 0, 112, 112, 195, 168, 108, 3, 35, 48, 6, 112, 55, 0, 4, 112, 1, 17, 67, 2, 111, 111, 114, 3, 35, 48, 10, 0, 112, 1, 17, 67, 2, 111, 114, 101, 32, 0, 108, 105, 8, 2, 107, 114, 17, 65, 3, 35, 55, 2, 37, 0, 108, 111, 195, 171, 3, 35, 55, 6, 40, 13, 0, 108, 111, 111, 103, 3, 35, 55, 6, 117, 136, 0, 108, 111, 103, 105, 101, 115, 3, 35, 55, 6, 117, 136, 37, 89, 0, 108, 108, 101, 8, 2, 17, 67, 3, 35, 55, 13, 0, 108, 111, 109, 8, 2, 21, 3, 35, 55, 19, 110, 65, 0, 108, 111, 103, 105, 101, 3, 35, 55, 40, 136, 6, 37, 0, 108, 107, 111, 104, 111, 108, 3, 35, 55, 49, 2, 40, 2, 110, 55, 0, 108, 109, 101, 2, 108, 101, 3, 35, 55, 65, 13, 0, 108, 102, 97, 98, 101, 2, 116, 25, 3, 35, 55, 83, 35, 71, 108, 0, 109, 97, 110, 100, 101, 108, 3, 35, 65, 6, 35, 50, 72, 13, 55, 0, 109, 112, 101, 114, 8, 3, 35, 65, 48, 13, 34, 0, 100, 106, 117, 110, 107, 3, 35, 72, 57, 6, 111, 68, 49, 0, 115, 1, 17, 67, 21, 2, 32, 3, 35, 89, 0, 103, 116, 8, 2, 117, 117, 114, 3, 35, 136, 47, 0, 103, 116, 101, 114, 110, 97, 3, 35, 136, 47, 13, 34, 50, 6, 115, 0, 4, 3, 115, 0, 1, 17, 67, 2, 17, 67, 105, 97, 32, 0, 1, 109, 97, 116, 2, 116, 105, 101, 107, 0, 1, 114, 98, 17, 67, 2, 32, 0, 1, 114, 100, 10, 2, 32, 0, 1, 114, 118, 10, 2, 32, 0, 1, 119, 2, 116, 101, 114, 105, 110, 103, 0, 2, 17, 67, 17, 65, 0, 2, 17, 67, 105, 101, 0, 2, 104, 108, 101, 32, 0, 8, 2, 115, 105, 195, 171, 0, 101, 0, 104, 2, 17, 67, 0, 114, 101, 1, 17, 67, 2, 17, 67, 17, 65, 3, 115, 34, 13, 0, 114, 101, 110, 100, 115, 3, 115, 34, 13, 50, 47, 89, 10, 0, 114, 101, 97, 3, 115, 34, 37, 35, 0, 116, 114, 105, 117, 109, 3, 115, 47, 34, 37, 111, 65, 0, 108, 105, 97, 3, 115, 55, 2, 37, 2, 35, 0, 100, 101, 109, 8, 3, 115, 72, 13, 65, 0, 100, 105, 117, 1, 17, 67, 2, 25, 3, 115, 72, 37, 111, 0, 102, 101, 108, 1, 17, 67, 2, 21, 3, 115, 83, 13, 55, 0, 102, 114, 105, 107, 97, 3, 115, 83, 34, 37, 49, 35, 0, 4, 115, 105, 101, 1, 21, 21, 21, 21, 3, 115, 89, 2, 37, 0, 115, 105, 101, 1, 108, 112, 0, 115, 105, 101, 1, 112, 115, 21, 0, 115, 101, 109, 3, 115, 89, 13, 65, 0, 4, 115, 105, 101, 1, 17, 67, 11, 17, 67, 3, 115, 89, 37, 0, 115, 105, 101, 1, 98, 117, 111, 0, 115, 105, 101, 1, 108, 103, 0, 115, 105, 101, 1, 109, 114, 111, 102, 21, 0, 115, 105, 101, 1, 116, 115, 17, 65, 17, 65, 0, 115, 105, 101, 1, 116, 115, 17, 67, 0, 103, 105, 101, 1, 17, 67, 3, 115, 136, 37, 0, 117, 1, 25, 3, 120, 0, 4, 2, 100, 106, 105, 101, 3, 121, 0, 105, 0, 116, 106, 105, 101, 3, 121, 80, 37, 0, 101, 110, 2, 116, 106, 105, 101, 3, 122, 68, 0, 100, 106, 105, 101, 3, 122, 80, 37, 0, 117, 3, 129, 0, 117, 101, 114, 3, 129, 13, 34, 0, 7, 6, 98, 0, 2, 98, 3, 0, 117, 114, 121, 1, 21, 2, 32, 3, 21, 0, 2, 32, 24, 3, 48, 0, 4, 3, 71, 0, 2, 101, 101, 110, 116, 106, 105, 101, 12, 12, 0, 4, 105, 2, 115, 97, 114, 3, 71, 2, 37, 0, 105, 2, 122, 97, 0, 105, 8, 2, 103, 97, 0, 105, 115, 97, 110, 2, 116, 121, 110, 3, 71, 2, 37, 89, 2, 35, 50, 0, 4, 111, 2, 98, 111, 116, 105, 101, 3, 71, 2, 40, 0, 111, 2, 104, 97, 97, 105, 0, 111, 2, 104, 101, 0, 111, 101, 2, 100, 100, 104, 105, 0, 111, 101, 2, 116, 115, 101, 101, 114, 0, 4, 111, 101, 114, 2, 103, 111, 110, 100, 3, 71, 2, 40, 34, 0, 111, 101, 114, 2, 105, 110, 0, 111, 101, 107, 101, 2, 116, 25, 3, 71, 2, 40, 49, 108, 0, 117, 108, 2, 103, 97, 3, 71, 2, 40, 55, 0, 117, 108, 108, 101, 2, 116, 105, 110, 3, 71, 2, 40, 55, 13, 0, 111, 114, 8, 2, 100, 17, 65, 21, 3, 71, 2, 110, 34, 0, 111, 107, 109, 97, 2, 107, 105, 101, 114, 3, 71, 2, 110, 49, 65, 2, 35, 0, 111, 110, 115, 109, 97, 114, 97, 3, 71, 2, 110, 50, 89, 65, 115, 34, 2, 35, 0, 111, 98, 98, 101, 2, 106, 3, 71, 2, 110, 71, 13, 0, 117, 114, 2, 108, 101, 115, 107, 3, 71, 2, 111, 34, 0, 117, 102, 102, 101, 2, 116, 3, 71, 2, 111, 83, 108, 0, 111, 2, 116, 97, 110, 105, 101, 3, 71, 2, 117, 0, 111, 116, 97, 2, 110, 105, 101, 32, 24, 3, 71, 2, 117, 47, 2, 35, 0, 111, 111, 115, 2, 97, 97, 114, 100, 105, 103, 3, 71, 2, 117, 89, 10, 0, 117, 114, 2, 111, 107, 114, 97, 3, 71, 2, 118, 34, 0, 117, 114, 111, 3, 71, 2, 118, 34, 117, 0, 4, 121, 2, 107, 111, 109, 21, 3, 71, 2, 123, 0, 121, 2, 118, 111, 111, 114, 98, 0, 121, 2, 101, 101, 110, 3, 71, 2, 123, 10, 0, 121, 100, 101, 114, 2, 17, 67, 21, 3, 71, 2, 123, 72, 13, 34, 0, 121, 119, 111, 111, 114, 100, 101, 108, 105, 3, 71, 2, 123, 84, 117, 34, 72, 13, 55, 13, 0, 121, 103, 101, 2, 108, 111, 119, 105, 3, 71, 2, 123, 136, 13, 0, 121, 8, 2, 116, 101, 108, 14, 128, 132, 130, 3, 71, 6, 123, 0, 121, 103, 101, 8, 2, 21, 14, 128, 132, 132, 3, 71, 6, 123, 136, 13, 0, 117, 105, 116, 101, 110, 2, 103, 101, 3, 71, 6, 127, 47, 13, 50, 0, 111, 101, 112, 101, 110, 115, 3, 71, 7, 40, 48, 134, 50, 89, 0, 111, 119, 101, 8, 3, 71, 7, 117, 84, 13, 0, 98, 101, 2, 114, 114, 3, 71, 13, 0, 105, 107, 105, 110, 105, 3, 71, 13, 49, 37, 50, 37, 0, 105, 108, 2, 106, 3, 71, 13, 55, 0, 105, 98, 108, 105, 2, 111, 17, 67, 3, 71, 13, 71, 55, 2, 37, 12, 2, 0, 114, 97, 118, 2, 17, 65, 3, 71, 34, 2, 35, 84, 0, 114, 97, 115, 105, 2, 108, 105, 3, 71, 34, 2, 35, 89, 109, 0, 114, 111, 2, 115, 106, 117, 3, 71, 34, 2, 110, 0, 114, 111, 2, 109, 105, 3, 71, 34, 2, 117, 0, 114, 117, 2, 116, 97, 3, 71, 34, 2, 118, 0, 114, 105, 101, 119, 101, 8, 2, 17, 67, 3, 71, 34, 7, 37, 84, 13, 0, 114, 105, 108, 2, 106, 97, 110, 116, 3, 71, 34, 13, 55, 0, 114, 101, 100, 97, 8, 3, 71, 34, 13, 72, 115, 0, 114, 97, 110, 100, 2, 114, 3, 71, 34, 35, 50, 47, 0, 114, 97, 110, 100, 2, 97, 3, 71, 34, 35, 50, 47, 10, 0, 114, 97, 110, 100, 2, 111, 3, 71, 34, 35, 50, 47, 19, 0, 114, 111, 110, 2, 17, 65, 21, 3, 71, 34, 110, 50, 10, 0, 114, 97, 105, 108, 108, 101, 3, 71, 34, 123, 12, 55, 10, 0, 114, 101, 105, 100, 101, 108, 3, 71, 34, 123, 72, 13, 55, 0, 111, 101, 114, 101, 3, 71, 40, 12, 34, 13, 0, 111, 117, 108, 101, 118, 97, 114, 100, 3, 71, 40, 55, 13, 84, 35, 34, 72, 0, 4, 108, 97, 2, 116, 97, 110, 116, 3, 71, 55, 2, 35, 0, 108, 97, 8, 2, 109, 101, 0, 108, 111, 101, 2, 100, 100, 111, 114, 115, 21, 3, 71, 55, 2, 40, 0, 4, 108, 111, 101, 100, 2, 115, 107, 101, 110, 100, 105, 103, 3, 71, 55, 2, 40, 47, 0, 108, 111, 101, 100, 2, 115, 116, 111, 108, 0, 4, 108, 111, 8, 2, 107, 107, 97, 3, 71, 55, 2, 110, 0, 108, 111, 8, 2, 107, 107, 101, 101, 114, 0, 108, 111, 110, 2, 100, 105, 110, 101, 3, 71, 55, 2, 110, 50, 0, 108, 121, 2, 109, 111, 101, 100, 3, 71, 55, 2, 123, 0, 108, 97, 100, 2, 17, 65, 3, 71, 55, 35, 47, 10, 0, 108, 105, 107, 8, 2, 17, 65, 3, 71, 55, 109, 49, 10, 0, 108, 111, 109, 2, 97, 107, 107, 101, 114, 3, 71, 55, 110, 65, 10, 0, 105, 100, 8, 3, 71, 109, 47, 10, 0, 105, 110, 110, 101, 3, 71, 109, 50, 13, 0, 105, 108, 108, 105, 2, 107, 3, 71, 109, 55, 13, 0, 105, 100, 100, 3, 71, 109, 72, 0, 111, 114, 100, 101, 2, 114, 3, 71, 110, 34, 72, 13, 0, 111, 107, 2, 111, 111, 105, 3, 71, 110, 49, 10, 0, 111, 110, 100, 101, 2, 17, 67, 3, 71, 110, 50, 72, 13, 0, 111, 109, 2, 17, 65, 17, 65, 3, 71, 110, 65, 10, 0, 111, 110, 103, 111, 8, 3, 71, 110, 68, 81, 40, 0, 111, 115, 99, 104, 2, 32, 3, 71, 110, 89, 0, 111, 115, 2, 17, 65, 21, 3, 71, 110, 89, 19, 0, 4, 111, 2, 103, 114, 111, 110, 100, 3, 71, 117, 0, 111, 2, 115, 107, 114, 105, 102, 0, 111, 2, 118, 0, 111, 8, 2, 107, 108, 101, 0, 111, 116, 97, 8, 2, 110, 105, 17, 67, 17, 65, 3, 71, 117, 47, 7, 115, 0, 111, 109, 97, 97, 110, 115, 3, 71, 117, 65, 115, 50, 89, 0, 111, 119, 101, 110, 3, 71, 117, 84, 13, 50, 6, 0, 121, 98, 101, 108, 3, 71, 123, 71, 13, 55, 0, 117, 105, 116, 101, 3, 71, 127, 47, 13, 0, 4, 117, 105, 116, 101, 110, 2, 115, 116, 101, 3, 71, 127, 47, 13, 50, 0, 117, 105, 116, 101, 110, 2, 116, 0, 117, 105, 116, 101, 110, 3, 71, 127, 47, 13, 50, 6, 0, 7, 6, 99, 0, 2, 99, 3, 0, 4, 101, 2, 32, 3, 21, 0, 101, 108, 1, 21, 2, 32, 0, 104, 97, 116, 0, 108, 101, 1, 21, 2, 32, 0, 121, 2, 32, 0, 4, 3, 49, 0, 104, 2, 108, 0, 104, 2, 114, 111, 0, 107, 0, 104, 97, 2, 114, 105, 115, 109, 97, 3, 49, 2, 35, 0, 97, 108, 2, 118, 17, 65, 3, 49, 2, 35, 55, 0, 97, 108, 97, 109, 97, 114, 105, 3, 49, 2, 35, 55, 2, 35, 65, 115, 34, 2, 37, 0, 104, 111, 114, 101, 2, 111, 103, 114, 97, 3, 49, 2, 110, 34, 2, 37, 0, 111, 108, 111, 109, 98, 105, 2, 97, 21, 3, 49, 2, 110, 55, 2, 110, 65, 71, 2, 37, 0, 104, 111, 108, 101, 115, 116, 101, 114, 111, 108, 3, 49, 2, 110, 55, 108, 89, 47, 14, 34, 2, 110, 55, 0, 108, 105, 99, 104, 195, 169, 3, 49, 55, 2, 37, 91, 116, 0, 111, 114, 110, 101, 2, 108, 105, 3, 49, 110, 34, 50, 7, 116, 0, 104, 111, 108, 101, 114, 97, 3, 49, 117, 55, 13, 34, 35, 10, 0, 111, 107, 101, 3, 49, 120, 49, 0, 104, 101, 100, 100, 97, 114, 3, 76, 108, 72, 13, 34, 0, 4, 2, 101, 3, 89, 0, 2, 105, 0, 2, 121, 0, 101, 110, 2, 116, 97, 117, 114, 17, 65, 3, 89, 2, 108, 50, 0, 105, 1, 21, 2, 32, 3, 89, 6, 37, 0, 121, 2, 114, 105, 108, 108, 105, 101, 3, 89, 13, 0, 105, 8, 2, 112, 114, 17, 65, 3, 89, 37, 0, 104, 97, 108, 101, 116, 3, 91, 2, 35, 55, 123, 0, 104, 105, 110, 2, 101, 3, 91, 2, 37, 50, 0, 104, 97, 117, 2, 17, 67, 3, 91, 2, 120, 0, 104, 105, 114, 117, 114, 103, 2, 105, 101, 32, 24, 3, 91, 13, 34, 2, 111, 34, 136, 0, 104, 105, 114, 117, 114, 103, 3, 91, 13, 34, 111, 34, 136, 0, 4, 104, 3, 136, 0, 104, 8, 0, 104, 101, 109, 105, 107, 97, 2, 108, 105, 3, 136, 2, 116, 65, 2, 37, 49, 115, 0, 7, 6, 100, 0, 4, 1, 21, 2, 116, 3, 0, 4, 2, 32, 100, 24, 3, 0, 2, 100, 3, 0, 4, 103, 101, 1, 21, 2, 32, 3, 21, 0, 103, 101, 2, 32, 0, 4, 1, 21, 2, 17, 67, 3, 47, 0, 1, 21, 2, 101, 116, 101, 17, 67, 32, 0, 1, 21, 2, 114, 97, 97, 109, 0, 1, 21, 2, 114, 111, 111, 115, 0, 1, 21, 2, 114, 111, 115, 101, 32, 0, 1, 21, 2, 114, 111, 115, 105, 101, 0, 1, 21, 2, 114, 117, 105, 109, 0, 1, 101, 111, 2, 114, 0, 1, 110, 21, 2, 101, 116, 101, 32, 0, 1, 110, 97, 104, 2, 114, 0, 1, 110, 97, 115, 2, 114, 0, 1, 110, 105, 119, 2, 114, 0, 1, 110, 111, 104, 2, 17, 67, 0, 1, 111, 111, 2, 114, 0, 2, 32, 0, 2, 114, 105, 101, 109, 32, 0, 4, 1, 17, 65, 2, 97, 103, 116, 105, 103, 3, 47, 10, 0, 1, 21, 2, 101, 105, 101, 110, 0, 1, 21, 2, 101, 105, 110, 100, 101, 32, 0, 1, 21, 2, 101, 105, 115, 0, 1, 21, 2, 105, 110, 104, 111, 117, 0, 1, 110, 21, 2, 117, 105, 116, 0, 1, 111, 111, 2, 17, 65, 3, 47, 19, 0, 119, 101, 115, 1, 21, 3, 47, 84, 6, 108, 89, 0, 119, 105, 108, 108, 105, 103, 1, 21, 3, 47, 84, 6, 109, 55, 13, 136, 0, 119, 101, 115, 101, 1, 21, 3, 47, 84, 116, 89, 13, 0, 115, 1, 21, 2, 32, 3, 47, 89, 0, 4, 3, 72, 0, 1, 21, 2, 114, 0, 1, 101, 111, 116, 2, 114, 0, 1, 111, 111, 114, 97, 107, 0, 1, 112, 2, 17, 67, 0, 1, 114, 101, 118, 2, 17, 67, 0, 100, 0, 100, 1, 21, 0, 100, 104, 0, 105, 2, 110, 97, 109, 105, 101, 3, 72, 2, 37, 0, 105, 97, 2, 17, 67, 3, 72, 2, 37, 2, 35, 0, 105, 97, 107, 111, 2, 110, 105, 101, 3, 72, 2, 37, 2, 35, 49, 2, 40, 0, 105, 114, 101, 107, 3, 72, 2, 37, 34, 108, 49, 0, 4, 105, 110, 97, 2, 109, 105, 101, 107, 3, 72, 2, 37, 50, 2, 35, 0, 105, 110, 97, 2, 109, 105, 101, 116, 0, 105, 110, 97, 2, 115, 116, 105, 101, 0, 105, 110, 111, 2, 115, 111, 117, 3, 72, 2, 37, 50, 2, 40, 0, 105, 101, 110, 115, 2, 119, 105, 108, 108, 105, 3, 72, 2, 37, 50, 89, 0, 105, 97, 107, 101, 110, 3, 72, 2, 37, 115, 49, 13, 50, 0, 105, 103, 105, 2, 116, 97, 3, 72, 2, 37, 136, 2, 37, 0, 117, 2, 101, 116, 3, 72, 2, 40, 12, 58, 0, 111, 101, 108, 2, 116, 114, 101, 102, 3, 72, 2, 40, 55, 0, 117, 118, 101, 116, 3, 72, 2, 40, 84, 123, 12, 0, 111, 101, 97, 110, 101, 3, 72, 2, 40, 115, 50, 13, 0, 111, 2, 115, 115, 105, 101, 114, 3, 72, 2, 110, 0, 111, 108, 2, 102, 121, 110, 3, 72, 2, 110, 55, 0, 111, 108, 111, 2, 109, 105, 101, 116, 3, 72, 2, 110, 55, 13, 0, 111, 109, 105, 110, 2, 17, 65, 3, 72, 2, 110, 65, 2, 37, 50, 0, 111, 109, 105, 110, 105, 2, 107, 97, 3, 72, 2, 110, 65, 2, 37, 50, 2, 37, 0, 97, 97, 114, 111, 112, 2, 118, 3, 72, 2, 115, 34, 2, 110, 48, 0, 97, 97, 114, 101, 110, 2, 116, 101, 3, 72, 2, 115, 34, 13, 50, 0, 97, 97, 100, 2, 119, 101, 114, 107, 3, 72, 2, 115, 47, 0, 111, 112, 97, 2, 109, 105, 3, 72, 2, 117, 48, 2, 35, 0, 97, 110, 116, 1, 21, 3, 72, 6, 35, 50, 47, 0, 97, 103, 1, 110, 97, 97, 2, 116, 105, 103, 3, 72, 6, 35, 136, 0, 97, 110, 105, 2, 103, 104, 3, 72, 6, 115, 50, 13, 0, 97, 109, 101, 115, 8, 3, 72, 6, 115, 65, 13, 89, 0, 111, 109, 105, 110, 101, 101, 2, 32, 3, 72, 6, 117, 65, 13, 50, 37, 0, 111, 100, 101, 8, 3, 72, 6, 117, 72, 13, 0, 4, 105, 2, 110, 101, 101, 3, 72, 13, 0, 105, 2, 112, 108, 111, 109, 97, 0, 105, 2, 115, 115, 105, 0, 105, 2, 118, 105, 115, 105, 101, 0, 105, 114, 105, 103, 2, 101, 3, 72, 13, 34, 13, 136, 0, 100, 101, 114, 100, 1, 21, 2, 32, 3, 72, 13, 34, 47, 0, 105, 112, 108, 111, 2, 109, 97, 116, 3, 72, 13, 48, 55, 2, 40, 0, 105, 107, 2, 118, 101, 108, 108, 3, 72, 13, 49, 0, 105, 110, 97, 1, 110, 97, 107, 115, 3, 72, 13, 50, 6, 115, 0, 105, 108, 101, 109, 109, 97, 3, 72, 13, 55, 108, 65, 35, 0, 105, 109, 101, 110, 2, 115, 105, 3, 72, 13, 65, 108, 50, 0, 105, 110, 103, 97, 97, 110, 3, 72, 13, 68, 81, 115, 50, 0, 105, 118, 105, 100, 101, 2, 110, 100, 3, 72, 13, 84, 13, 72, 108, 0, 4, 105, 115, 2, 107, 111, 101, 114, 115, 3, 72, 13, 89, 0, 105, 115, 2, 108, 111, 106, 97, 0, 105, 115, 2, 112, 117, 0, 105, 115, 8, 2, 105, 110, 14, 128, 132, 131, 0, 105, 115, 8, 2, 107, 114, 101, 0, 105, 115, 8, 2, 107, 117, 115, 115, 17, 65, 0, 105, 115, 8, 2, 111, 14, 128, 132, 131, 0, 105, 115, 8, 2, 116, 0, 105, 115, 115, 105, 112, 101, 108, 2, 105, 110, 3, 72, 13, 89, 2, 37, 48, 13, 55, 0, 105, 115, 115, 105, 112, 108, 105, 110, 101, 2, 25, 3, 72, 13, 89, 13, 48, 55, 37, 50, 13, 0, 105, 115, 116, 114, 111, 2, 102, 105, 101, 3, 72, 13, 89, 47, 34, 2, 40, 0, 105, 115, 116, 114, 105, 2, 98, 117, 3, 72, 13, 89, 47, 34, 13, 0, 105, 115, 107, 114, 101, 2, 115, 3, 72, 13, 89, 49, 34, 108, 0, 105, 103, 101, 114, 115, 3, 72, 13, 136, 13, 34, 89, 0, 105, 103, 116, 101, 114, 101, 2, 25, 3, 72, 13, 136, 47, 13, 34, 108, 0, 114, 111, 101, 102, 2, 103, 101, 101, 115, 3, 72, 34, 2, 40, 83, 0, 114, 117, 107, 107, 101, 8, 2, 114, 121, 3, 72, 34, 2, 111, 49, 13, 0, 114, 97, 109, 97, 2, 116, 117, 114, 103, 3, 72, 34, 2, 115, 65, 2, 35, 0, 114, 97, 2, 115, 116, 105, 101, 3, 72, 34, 35, 0, 114, 105, 108, 2, 17, 65, 3, 72, 34, 109, 55, 0, 114, 97, 8, 2, 115, 116, 3, 72, 34, 115, 0, 105, 101, 112, 101, 114, 2, 21, 3, 72, 37, 48, 13, 34, 0, 117, 2, 112, 108, 105, 17, 67, 3, 72, 40, 0, 4, 119, 1, 101, 103, 3, 72, 58, 0, 119, 1, 109, 0, 119, 1, 121, 98, 114, 101, 118, 0, 119, 2, 101, 114, 103, 0, 119, 101, 108, 109, 2, 32, 3, 72, 58, 112, 55, 14, 65, 0, 105, 2, 103, 25, 3, 72, 109, 0, 105, 115, 116, 101, 108, 3, 72, 109, 89, 47, 13, 55, 0, 111, 107, 116, 111, 114, 2, 25, 3, 72, 110, 49, 47, 13, 34, 0, 111, 107, 117, 3, 72, 110, 49, 118, 0, 111, 108, 2, 111, 115, 3, 72, 110, 55, 0, 111, 109, 8, 2, 17, 65, 17, 67, 17, 67, 3, 72, 110, 65, 0, 111, 110, 103, 97, 3, 72, 110, 68, 81, 35, 0, 97, 116, 101, 1, 105, 100, 110, 97, 107, 2, 17, 67, 3, 72, 115, 47, 13, 0, 97, 110, 105, 195, 171, 108, 3, 72, 115, 50, 37, 13, 55, 0, 111, 115, 105, 2, 115, 3, 72, 117, 89, 13, 0, 106, 8, 3, 75, 0, 106, 3, 80, 0, 106, 105, 101, 3, 80, 37, 0, 7, 6, 101, 0, 1, 105, 111, 111, 2, 110, 116, 106, 105, 101, 3, 0, 4, 2, 102, 101, 115, 105, 3, 2, 37, 0, 2, 109, 111, 115, 105, 0, 8, 2, 108, 108, 105, 112, 25, 0, 8, 108, 101, 105, 115, 2, 116, 106, 105, 101, 0, 108, 101, 107, 2, 116, 114, 111, 100, 101, 3, 2, 37, 55, 2, 108, 49, 0, 108, 101, 107, 116, 114, 3, 2, 37, 55, 108, 49, 47, 34, 0, 102, 102, 101, 107, 2, 25, 3, 2, 37, 83, 108, 49, 0, 118, 2, 101, 110, 116, 117, 101, 3, 2, 37, 84, 0, 118, 97, 108, 2, 117, 3, 2, 37, 84, 2, 35, 55, 0, 115, 115, 101, 110, 2, 115, 105, 3, 2, 37, 89, 108, 50, 0, 4, 1, 108, 108, 101, 116, 110, 105, 2, 107, 3, 2, 108, 0, 2, 107, 111, 110, 111, 21, 0, 8, 2, 107, 115, 0, 8, 2, 109, 105, 0, 116, 105, 2, 107, 101, 116, 3, 2, 108, 47, 2, 37, 0, 116, 105, 107, 101, 116, 116, 101, 2, 114, 17, 65, 3, 2, 108, 47, 2, 37, 49, 2, 108, 47, 116, 0, 4, 112, 105, 2, 100, 101, 17, 67, 3, 2, 108, 48, 2, 37, 0, 112, 105, 8, 2, 17, 67, 0, 112, 111, 117, 2, 108, 101, 116, 3, 2, 108, 48, 2, 40, 0, 107, 117, 2, 109, 101, 110, 105, 101, 3, 2, 108, 49, 2, 118, 0, 107, 119, 105, 2, 108, 105, 98, 114, 105, 3, 2, 108, 49, 58, 2, 37, 0, 120, 1, 108, 97, 2, 97, 110, 100, 3, 2, 108, 49, 88, 0, 107, 115, 97, 109, 105, 110, 2, 17, 65, 3, 2, 108, 49, 89, 2, 35, 65, 2, 37, 50, 0, 107, 115, 101, 2, 108, 108, 101, 110, 17, 67, 3, 2, 108, 49, 89, 13, 0, 107, 115, 101, 103, 101, 2, 17, 67, 17, 65, 3, 2, 108, 49, 89, 13, 136, 116, 0, 107, 115, 116, 114, 111, 2, 118, 101, 114, 3, 2, 108, 49, 89, 47, 34, 2, 40, 0, 107, 115, 116, 114, 101, 2, 109, 105, 115, 3, 2, 108, 49, 89, 47, 34, 13, 0, 107, 115, 116, 101, 114, 110, 8, 3, 2, 108, 49, 89, 47, 112, 34, 14, 50, 0, 107, 115, 112, 108, 105, 2, 115, 105, 101, 116, 3, 2, 108, 49, 89, 48, 55, 13, 0, 4, 108, 101, 2, 103, 97, 110, 17, 67, 3, 2, 108, 55, 13, 0, 108, 101, 2, 103, 105, 101, 0, 108, 101, 109, 101, 110, 116, 3, 2, 108, 55, 13, 65, 108, 50, 47, 0, 4, 109, 2, 112, 105, 114, 3, 2, 108, 65, 0, 109, 8, 2, 98, 108, 101, 0, 109, 102, 105, 2, 115, 101, 101, 109, 3, 2, 108, 65, 83, 2, 37, 0, 119, 111, 2, 108, 117, 115, 105, 3, 2, 108, 84, 2, 110, 0, 115, 8, 2, 107, 97, 114, 112, 3, 2, 108, 89, 0, 115, 105, 1, 100, 21, 2, 109, 97, 3, 2, 108, 89, 2, 37, 0, 115, 116, 114, 111, 2, 103, 101, 3, 2, 108, 89, 47, 34, 2, 40, 0, 115, 116, 101, 8, 2, 116, 3, 2, 108, 89, 47, 116, 0, 115, 107, 97, 2, 112, 97, 100, 101, 3, 2, 108, 89, 49, 13, 0, 115, 107, 97, 100, 101, 114, 3, 2, 108, 89, 49, 115, 72, 13, 34, 0, 114, 107, 101, 2, 110, 12, 3, 2, 112, 34, 49, 108, 0, 4, 2, 107, 108, 105, 112, 25, 3, 2, 116, 0, 8, 2, 103, 105, 112, 116, 0, 8, 2, 114, 111, 115, 105, 101, 0, 114, 101, 2, 107, 115, 105, 17, 65, 3, 2, 116, 34, 108, 0, 109, 97, 108, 106, 101, 3, 2, 116, 65, 35, 55, 57, 13, 0, 119, 101, 8, 2, 114, 101, 100, 3, 2, 116, 84, 13, 0, 119, 101, 119, 105, 103, 2, 116, 105, 103, 3, 2, 116, 84, 13, 84, 109, 136, 0, 119, 105, 103, 2, 100, 117, 3, 2, 116, 84, 13, 136, 0, 115, 111, 116, 101, 2, 114, 105, 101, 3, 2, 116, 89, 2, 40, 47, 116, 0, 103, 111, 115, 101, 110, 116, 114, 105, 101, 3, 2, 116, 136, 2, 40, 89, 108, 50, 47, 34, 37, 0, 103, 97, 8, 2, 108, 3, 2, 116, 136, 115, 0, 105, 101, 110, 97, 97, 114, 100, 105, 103, 3, 2, 123, 13, 50, 115, 34, 72, 13, 136, 0, 117, 2, 102, 111, 114, 105, 101, 3, 2, 128, 0, 117, 114, 111, 8, 2, 112, 101, 3, 2, 128, 34, 2, 117, 0, 117, 102, 111, 2, 114, 105, 101, 32, 24, 3, 2, 128, 83, 2, 117, 0, 118, 97, 110, 103, 8, 3, 4, 116, 83, 35, 68, 136, 0, 8, 17, 67, 2, 111, 110, 32, 3, 6, 37, 0, 4, 1, 17, 67, 2, 115, 107, 32, 12, 12, 3, 6, 108, 0, 1, 17, 67, 2, 115, 107, 101, 32, 12, 12, 0, 1, 17, 67, 21, 2, 115, 107, 101, 114, 32, 0, 1, 114, 97, 2, 115, 115, 101, 32, 0, 100, 106, 105, 101, 3, 6, 108, 12, 37, 80, 37, 0, 107, 116, 111, 109, 105, 101, 1, 17, 67, 3, 6, 108, 49, 47, 40, 65, 37, 0, 1, 115, 21, 2, 108, 102, 100, 101, 3, 6, 112, 0, 4, 1, 100, 21, 2, 115, 101, 32, 12, 3, 6, 116, 0, 1, 112, 2, 114, 105, 110, 103, 0, 1, 112, 101, 111, 114, 2, 114, 105, 110, 103, 0, 4, 114, 1, 102, 102, 111, 116, 115, 2, 17, 65, 3, 6, 116, 34, 0, 114, 1, 110, 105, 2, 17, 65, 0, 114, 105, 110, 103, 1, 117, 3, 6, 116, 34, 13, 68, 0, 116, 101, 110, 115, 8, 3, 6, 116, 47, 13, 50, 89, 0, 108, 101, 1, 117, 17, 67, 2, 25, 12, 3, 6, 116, 55, 13, 0, 105, 1, 114, 2, 115, 101, 110, 3, 6, 123, 0, 105, 107, 101, 8, 3, 6, 123, 49, 13, 0, 105, 110, 1, 21, 2, 100, 105, 103, 3, 6, 123, 50, 0, 108, 119, 101, 114, 115, 1, 17, 67, 3, 7, 112, 55, 84, 13, 34, 89, 0, 1, 17, 67, 2, 110, 100, 104, 3, 8, 13, 0, 107, 111, 110, 1, 10, 2, 111, 21, 3, 10, 2, 108, 49, 2, 40, 50, 0, 105, 1, 17, 67, 21, 2, 108, 97, 110, 100, 3, 10, 4, 123, 0, 105, 1, 21, 2, 115, 101, 110, 3, 10, 6, 123, 0, 114, 116, 115, 1, 21, 2, 32, 3, 10, 112, 34, 47, 89, 0, 114, 107, 101, 1, 100, 108, 117, 107, 115, 3, 10, 112, 34, 49, 108, 0, 114, 103, 8, 114, 101, 108, 108, 97, 3, 10, 112, 34, 136, 0, 116, 101, 114, 1, 114, 101, 105, 109, 3, 10, 116, 47, 13, 34, 0, 4, 1, 10, 2, 32, 3, 13, 0, 1, 10, 2, 108, 17, 67, 32, 0, 1, 10, 2, 108, 32, 0, 1, 10, 2, 109, 32, 0, 1, 10, 2, 114, 32, 0, 1, 17, 67, 2, 104, 0, 1, 17, 67, 2, 107, 97, 109, 112, 12, 0, 1, 17, 67, 2, 107, 97, 110, 116, 12, 0, 1, 17, 67, 2, 108, 116, 106, 105, 101, 0, 1, 17, 67, 2, 109, 97, 97, 116, 0, 1, 17, 67, 2, 109, 97, 110, 0, 1, 17, 67, 2, 109, 97, 114, 105, 101, 0, 1, 17, 67, 2, 112, 97, 100, 0, 1, 17, 67, 2, 112, 97, 110, 0, 1, 17, 67, 2, 116, 111, 101, 32, 0, 1, 17, 67, 2, 118, 0, 1, 17, 67, 2, 119, 97, 97, 114, 0, 1, 17, 67, 2, 119, 105, 110, 107, 101, 108, 0, 1, 17, 67, 10, 2, 103, 97, 110, 103, 101, 114, 0, 1, 17, 67, 10, 2, 108, 114, 17, 65, 0, 1, 17, 67, 10, 2, 115, 107, 21, 0, 1, 17, 67, 11, 2, 17, 67, 0, 1, 17, 67, 17, 65, 2, 108, 104, 0, 1, 17, 67, 17, 65, 17, 67, 2, 17, 67, 17, 67, 0, 1, 17, 67, 17, 65, 17, 67, 2, 114, 114, 0, 1, 17, 67, 21, 2, 98, 111, 0, 1, 17, 67, 21, 2, 98, 117, 0, 1, 17, 67, 21, 2, 98, 121, 0, 1, 17, 67, 21, 2, 100, 105, 101, 110, 0, 1, 17, 67, 21, 2, 103, 101, 17, 67, 21, 0, 1, 17, 67, 21, 2, 103, 114, 111, 101, 112, 0, 1, 17, 67, 21, 2, 106, 0, 1, 17, 67, 21, 2, 107, 111, 100, 101, 25, 0, 1, 17, 67, 21, 2, 107, 111, 109, 21, 0, 1, 17, 67, 21, 2, 109, 97, 97, 108, 32, 0, 1, 17, 67, 21, 2, 109, 97, 108, 101, 32, 0, 1, 17, 67, 21, 2, 114, 101, 101, 107, 25, 0, 1, 17, 67, 21, 2, 114, 101, 195, 171, 0, 1, 17, 67, 21, 2, 114, 104, 0, 1, 17, 67, 21, 2, 116, 97, 97, 108, 0, 1, 17, 67, 21, 2, 119, 97, 32, 0, 1, 17, 67, 21, 2, 119, 97, 101, 110, 0, 1, 17, 67, 101, 111, 17, 67, 2, 17, 67, 12, 0, 1, 17, 67, 105, 117, 2, 25, 12, 0, 1, 17, 67, 117, 101, 25, 2, 108, 17, 67, 21, 0, 1, 21, 2, 115, 112, 101, 108, 32, 0, 1, 25, 2, 112, 111, 111, 114, 116, 0, 1, 98, 10, 2, 115, 21, 0, 1, 98, 17, 65, 2, 119, 97, 0, 1, 100, 10, 2, 114, 21, 12, 12, 0, 1, 100, 17, 67, 2, 116, 114, 0, 1, 100, 21, 2, 98, 108, 0, 1, 100, 21, 2, 107, 108, 97, 115, 0, 1, 100, 21, 2, 107, 114, 0, 1, 100, 21, 2, 115, 21, 0, 1, 100, 97, 114, 114, 111, 111, 118, 2, 17, 67, 0, 1, 100, 100, 17, 65, 2, 108, 101, 32, 0, 1, 100, 100, 105, 109, 2, 21, 0, 1, 100, 102, 101, 105, 108, 2, 17, 67, 0, 1, 100, 103, 117, 101, 114, 118, 2, 17, 67, 0, 1, 100, 108, 97, 97, 110, 2, 17, 67, 0, 1, 100, 108, 101, 101, 119, 2, 119, 17, 65, 0, 1, 100, 108, 101, 112, 115, 2, 17, 67, 0, 1, 100, 108, 105, 119, 0, 1, 100, 108, 105, 119, 2, 107, 17, 65, 0, 1, 100, 110, 2, 108, 105, 110, 103, 0, 1, 100, 110, 17, 65, 2, 108, 17, 67, 0, 1, 100, 110, 97, 17, 67, 2, 17, 67, 0, 1, 100, 110, 97, 97, 109, 2, 108, 17, 65, 0, 1, 100, 110, 101, 105, 114, 118, 2, 17, 67, 0, 1, 100, 110, 105, 108, 98, 2, 17, 67, 21, 0, 1, 100, 110, 105, 108, 98, 2, 108, 105, 110, 103, 0, 1, 100, 110, 111, 17, 67, 2, 17, 67, 17, 65, 0, 1, 100, 110, 117, 107, 2, 21, 0, 1, 100, 111, 107, 2, 17, 67, 0, 1, 100, 114, 111, 111, 110, 2, 17, 67, 0, 1, 100, 121, 2, 108, 0, 1, 102, 108, 105, 107, 115, 2, 114, 0, 1, 102, 121, 115, 2, 114, 0, 1, 103, 110, 97, 108, 115, 2, 17, 67, 0, 1, 103, 110, 105, 17, 67, 2, 108, 17, 65, 0, 1, 103, 110, 105, 17, 67, 2, 108, 17, 67, 21, 0, 1, 103, 110, 105, 110, 101, 107, 2, 21, 0, 1, 105, 97, 97, 2, 17, 67, 0, 1, 105, 101, 0, 1, 105, 111, 111, 2, 17, 67, 0, 1, 107, 21, 2, 108, 100, 101, 32, 0, 1, 107, 21, 2, 114, 97, 97, 100, 0, 1, 107, 97, 108, 98, 2, 114, 0, 1, 107, 101, 111, 2, 17, 67, 0, 1, 107, 110, 2, 108, 17, 67, 0, 1, 107, 110, 17, 65, 2, 114, 21, 0, 1, 107, 110, 105, 119, 2, 108, 0, 1, 107, 111, 112, 115, 2, 17, 67, 0, 1, 107, 114, 101, 119, 2, 114, 115, 0, 1, 107, 114, 105, 115, 2, 108, 0, 1, 108, 2, 109, 111, 101, 110, 0, 1, 108, 97, 104, 2, 114, 17, 67, 21, 0, 1, 108, 97, 109, 2, 100, 121, 0, 1, 108, 97, 114, 101, 110, 105, 109, 2, 17, 67, 0, 1, 108, 101, 119, 117, 106, 2, 17, 67, 0, 1, 108, 105, 101, 114, 116, 2, 114, 17, 67, 0, 1, 108, 108, 105, 119, 2, 17, 67, 0, 1, 108, 111, 114, 116, 2, 17, 67, 21, 0, 1, 109, 2, 108, 101, 110, 100, 0, 1, 109, 2, 108, 105, 110, 103, 0, 1, 109, 97, 115, 0, 1, 109, 97, 115, 21, 2, 110, 115, 32, 0, 1, 109, 101, 110, 21, 2, 110, 115, 32, 0, 1, 109, 108, 101, 17, 67, 2, 116, 25, 0, 1, 109, 111, 107, 21, 2, 110, 115, 32, 0, 1, 109, 111, 115, 2, 114, 0, 1, 109, 114, 2, 114, 116, 106, 105, 101, 0, 1, 110, 97, 17, 67, 17, 67, 2, 17, 67, 17, 65, 0, 1, 110, 101, 105, 17, 67, 2, 114, 17, 67, 21, 0, 1, 110, 110, 17, 65, 17, 67, 2, 17, 67, 17, 65, 0, 1, 110, 110, 97, 112, 2, 17, 67, 0, 1, 110, 117, 101, 2, 114, 21, 0, 1, 112, 2, 116, 97, 108, 106, 101, 0, 1, 112, 2, 116, 97, 108, 106, 101, 0, 1, 112, 17, 65, 2, 108, 105, 110, 103, 0, 1, 112, 17, 65, 17, 67, 2, 114, 107, 17, 67, 0, 1, 112, 17, 67, 17, 65, 17, 67, 2, 114, 108, 0, 1, 112, 21, 2, 108, 104, 0, 1, 112, 21, 2, 114, 116, 106, 105, 101, 0, 1, 112, 105, 104, 2, 114, 0, 1, 112, 109, 2, 108, 100, 101, 32, 0, 1, 112, 109, 21, 2, 108, 17, 67, 21, 0, 1, 112, 109, 111, 107, 2, 116, 21, 0, 1, 112, 112, 2, 17, 67, 21, 12, 0, 1, 112, 114, 2, 114, 17, 67, 17, 67, 0, 1, 112, 114, 101, 119, 2, 114, 115, 17, 65, 0, 1, 112, 114, 117, 112, 2, 114, 0, 1, 112, 115, 2, 100, 0, 1, 112, 115, 2, 108, 111, 110, 107, 0, 1, 114, 101, 100, 101, 111, 103, 2, 21, 0, 1, 114, 101, 105, 17, 67, 29, 2, 21, 0, 1, 114, 114, 111, 2, 108, 0, 1, 115, 10, 2, 108, 21, 0, 1, 115, 25, 2, 110, 97, 0, 1, 115, 100, 110, 97, 104, 101, 100, 2, 17, 67, 21, 0, 1, 115, 101, 105, 2, 98, 0, 1, 115, 101, 105, 2, 102, 0, 1, 115, 105, 101, 2, 98, 101, 0, 1, 115, 105, 101, 2, 115, 116, 0, 1, 115, 107, 21, 2, 109, 17, 67, 0, 1, 115, 107, 117, 117, 108, 0, 1, 115, 111, 107, 114, 97, 110, 2, 17, 67, 0, 1, 115, 111, 108, 2, 115, 0, 1, 115, 111, 114, 2, 17, 67, 17, 65, 0, 1, 115, 117, 101, 114, 2, 21, 0, 1, 115, 117, 111, 112, 2, 17, 67, 0, 1, 116, 10, 2, 114, 21, 0, 1, 116, 17, 65, 10, 2, 98, 17, 65, 21, 0, 1, 117, 111, 2, 17, 67, 0, 1, 118, 2, 110, 110, 111, 21, 12, 0, 1, 119, 2, 108, 105, 110, 103, 0, 1, 119, 10, 2, 102, 0, 1, 119, 17, 65, 2, 98, 17, 65, 0, 1, 119, 97, 2, 17, 67, 21, 0, 1, 119, 101, 107, 115, 2, 17, 67, 0, 1, 119, 101, 108, 2, 110, 115, 0, 1, 119, 108, 97, 104, 2, 25, 0, 1, 119, 108, 111, 17, 67, 2, 17, 67, 0, 1, 119, 114, 2, 115, 0, 1, 119, 117, 101, 17, 67, 2, 108, 0, 1, 119, 121, 2, 114, 17, 65, 0, 1, 119, 121, 116, 115, 2, 17, 67, 0, 1, 121, 17, 67, 2, 17, 67, 12, 0, 1, 121, 17, 67, 2, 17, 67, 17, 67, 0, 2, 17, 67, 111, 117, 120, 0, 2, 110, 97, 114, 101, 115, 32, 0, 8, 100, 97, 2, 108, 17, 67, 0, 8, 100, 105, 101, 109, 2, 17, 67, 0, 8, 100, 110, 101, 101, 2, 17, 67, 17, 65, 0, 8, 108, 101, 105, 115, 2, 21, 0, 8, 112, 111, 2, 110, 0, 8, 112, 115, 97, 114, 2, 114, 0, 8, 115, 110, 101, 109, 0, 8, 115, 110, 101, 109, 2, 107, 0, 8, 119, 101, 2, 12, 12, 0, 4, 1, 17, 67, 2, 114, 106, 3, 13, 6, 0, 1, 114, 112, 114, 101, 116, 110, 105, 2, 116, 17, 65, 0, 4, 1, 17, 67, 2, 117, 105, 116, 3, 13, 10, 0, 1, 17, 67, 10, 2, 117, 117, 0, 1, 17, 67, 21, 2, 97, 17, 67, 17, 67, 0, 1, 17, 67, 21, 2, 111, 111, 114, 0, 1, 100, 110, 111, 104, 2, 21, 0, 1, 110, 105, 101, 116, 110, 111, 102, 2, 17, 67, 0, 1, 117, 111, 2, 97, 0, 4, 114, 1, 17, 67, 21, 2, 116, 121, 100, 3, 13, 34, 0, 114, 1, 102, 102, 2, 21, 0, 114, 1, 105, 17, 65, 2, 17, 65, 0, 114, 1, 105, 101, 108, 2, 115, 0, 114, 105, 101, 1, 110, 2, 32, 3, 13, 34, 6, 37, 0, 4, 114, 101, 115, 1, 17, 67, 3, 13, 34, 6, 108, 89, 0, 114, 101, 115, 115, 1, 17, 67, 0, 114, 105, 1, 110, 117, 101, 2, 110, 3, 13, 34, 6, 109, 0, 114, 1, 112, 111, 108, 2, 17, 65, 3, 13, 34, 10, 0, 114, 101, 1, 10, 2, 32, 3, 13, 34, 13, 0, 114, 101, 115, 1, 116, 97, 108, 3, 13, 34, 13, 89, 0, 4, 114, 115, 1, 10, 2, 32, 3, 13, 34, 89, 0, 114, 115, 1, 112, 108, 101, 104, 2, 32, 0, 114, 115, 1, 112, 114, 101, 119, 2, 32, 0, 114, 115, 1, 112, 114, 111, 100, 2, 32, 0, 114, 115, 1, 119, 101, 105, 2, 116, 101, 114, 0, 114, 115, 121, 100, 115, 1, 17, 67, 3, 13, 34, 89, 123, 47, 89, 0, 114, 101, 1, 115, 110, 97, 100, 21, 2, 25, 3, 13, 34, 108, 0, 114, 105, 103, 1, 25, 10, 3, 13, 34, 109, 136, 0, 4, 114, 105, 103, 101, 1, 17, 65, 17, 65, 3, 13, 34, 109, 136, 13, 0, 114, 105, 103, 101, 1, 25, 10, 0, 4, 114, 101, 105, 1, 10, 2, 32, 3, 13, 34, 123, 0, 114, 121, 1, 21, 2, 32, 12, 0, 114, 121, 1, 21, 2, 101, 32, 0, 107, 101, 1, 110, 2, 32, 3, 13, 49, 13, 0, 108, 1, 102, 102, 2, 21, 3, 13, 55, 0, 108, 97, 103, 116, 105, 103, 3, 13, 55, 6, 35, 136, 47, 13, 136, 0, 108, 1, 103, 110, 97, 109, 2, 17, 65, 3, 13, 55, 10, 0, 108, 101, 1, 10, 2, 32, 3, 13, 55, 13, 0, 108, 105, 107, 1, 10, 2, 105, 110, 103, 3, 13, 55, 13, 49, 0, 108, 105, 107, 104, 101, 105, 100, 1, 10, 3, 13, 55, 13, 49, 123, 47, 0, 108, 105, 103, 97, 1, 21, 2, 32, 3, 13, 55, 37, 136, 35, 0, 108, 97, 97, 114, 3, 13, 55, 115, 34, 0, 108, 111, 111, 115, 1, 17, 67, 3, 13, 55, 117, 89, 0, 108, 111, 115, 101, 1, 17, 67, 3, 13, 55, 117, 89, 13, 0, 100, 101, 114, 109, 1, 17, 67, 21, 3, 13, 72, 112, 34, 14, 65, 10, 0, 100, 97, 110, 115, 1, 17, 67, 21, 3, 13, 72, 133, 50, 89, 0, 119, 101, 114, 107, 1, 17, 67, 21, 3, 13, 84, 112, 34, 49, 0, 119, 121, 1, 17, 67, 2, 17, 67, 3, 13, 84, 123, 0, 4, 115, 1, 17, 67, 17, 65, 17, 65, 17, 67, 29, 2, 32, 3, 13, 89, 0, 115, 1, 17, 67, 17, 65, 29, 2, 32, 0, 115, 1, 100, 17, 65, 17, 65, 17, 65, 17, 67, 29, 2, 32, 0, 115, 1, 100, 17, 67, 10, 2, 32, 0, 115, 1, 105, 17, 65, 17, 65, 2, 32, 0, 115, 1, 107, 2, 32, 0, 4, 115, 115, 1, 17, 67, 21, 2, 32, 3, 21, 0, 120, 2, 12, 0, 121, 2, 32, 0, 4, 1, 17, 67, 101, 111, 17, 67, 2, 116, 106, 105, 101, 3, 37, 0, 1, 110, 110, 97, 112, 2, 116, 106, 105, 101, 0, 116, 106, 105, 101, 1, 10, 2, 12, 3, 37, 80, 37, 0, 116, 106, 105, 101, 115, 1, 110, 110, 3, 37, 80, 37, 89, 0, 4, 1, 17, 67, 2, 107, 115, 12, 12, 3, 108, 0, 1, 17, 67, 2, 107, 116, 21, 12, 12, 0, 1, 17, 67, 2, 109, 109, 12, 12, 0, 1, 17, 67, 11, 2, 116, 116, 12, 0, 1, 17, 67, 17, 65, 17, 67, 2, 17, 67, 11, 0, 1, 100, 2, 102, 105, 0, 1, 100, 101, 114, 112, 2, 115, 116, 105, 0, 1, 106, 2, 107, 0, 1, 107, 21, 2, 116, 116, 21, 12, 0, 1, 108, 10, 2, 109, 32, 0, 1, 114, 2, 100, 105, 103, 101, 114, 105, 110, 103, 0, 2, 17, 67, 0, 8, 119, 2, 115, 107, 117, 115, 0, 1, 100, 2, 109, 111, 110, 115, 3, 108, 2, 0, 1, 17, 67, 2, 104, 108, 101, 32, 12, 3, 108, 12, 0, 116, 106, 105, 101, 115, 1, 110, 17, 67, 3, 108, 37, 80, 37, 89, 0, 112, 105, 108, 101, 112, 8, 3, 108, 48, 13, 55, 6, 108, 48, 0, 112, 115, 1, 17, 67, 21, 2, 12, 3, 108, 48, 89, 0, 120, 105, 107, 1, 109, 3, 108, 49, 89, 2, 37, 49, 0, 120, 97, 115, 1, 116, 3, 108, 49, 89, 13, 89, 0, 107, 115, 116, 97, 115, 101, 3, 108, 49, 89, 47, 6, 115, 89, 13, 0, 107, 115, 116, 101, 114, 8, 2, 25, 3, 108, 49, 89, 47, 13, 34, 0, 107, 115, 116, 114, 97, 2, 25, 3, 108, 49, 89, 47, 34, 35, 0, 118, 111, 108, 117, 115, 3, 108, 84, 110, 55, 6, 118, 89, 0, 4, 1, 17, 67, 2, 107, 3, 112, 0, 1, 17, 67, 2, 107, 107, 21, 12, 0, 1, 17, 67, 11, 2, 103, 103, 0, 1, 17, 67, 17, 65, 17, 67, 2, 103, 103, 0, 1, 17, 67, 21, 2, 103, 100, 12, 0, 1, 17, 67, 21, 2, 108, 107, 32, 12, 0, 1, 17, 67, 21, 2, 108, 107, 101, 32, 0, 1, 100, 21, 2, 114, 110, 115, 116, 12, 12, 0, 1, 100, 100, 108, 2, 108, 103, 17, 65, 17, 67, 0, 1, 107, 115, 21, 2, 108, 0, 1, 108, 108, 2, 108, 25, 0, 1, 109, 21, 2, 108, 100, 0, 1, 110, 107, 2, 108, 0, 1, 112, 115, 17, 67, 2, 108, 100, 0, 1, 112, 115, 17, 67, 2, 108, 115, 0, 1, 112, 115, 101, 103, 2, 108, 100, 0, 1, 112, 115, 117, 111, 107, 115, 2, 108, 32, 0, 1, 112, 115, 121, 108, 98, 2, 108, 25, 0, 1, 115, 17, 67, 2, 108, 102, 0, 1, 115, 17, 67, 2, 108, 108, 101, 32, 0, 1, 115, 107, 110, 111, 114, 116, 2, 108, 0, 1, 115, 114, 101, 105, 101, 2, 108, 0, 1, 116, 17, 65, 17, 67, 2, 103, 110, 0, 1, 118, 101, 17, 67, 2, 103, 25, 0, 1, 119, 17, 65, 17, 67, 2, 114, 107, 17, 65, 0, 1, 119, 17, 65, 17, 67, 2, 114, 107, 25, 0, 1, 119, 21, 2, 108, 115, 121, 110, 0, 1, 119, 108, 111, 98, 2, 114, 107, 32, 0, 2, 103, 25, 0, 2, 108, 25, 0, 2, 114, 0, 4, 114, 8, 2, 98, 3, 112, 34, 6, 0, 114, 8, 2, 118, 0, 114, 112, 1, 17, 67, 21, 2, 32, 3, 112, 34, 48, 0, 114, 112, 101, 1, 17, 67, 21, 2, 32, 3, 112, 34, 48, 13, 0, 114, 112, 105, 101, 1, 17, 67, 21, 2, 32, 3, 112, 34, 48, 37, 0, 4, 114, 107, 101, 1, 109, 2, 110, 100, 3, 112, 34, 49, 13, 0, 114, 107, 101, 1, 112, 2, 110, 100, 0, 114, 107, 101, 1, 119, 2, 110, 100, 0, 114, 100, 101, 8, 2, 17, 67, 3, 112, 34, 72, 13, 0, 114, 102, 1, 17, 67, 21, 2, 32, 3, 112, 34, 83, 0, 114, 119, 101, 1, 17, 67, 21, 2, 32, 3, 112, 34, 84, 13, 0, 4, 114, 115, 1, 112, 102, 2, 32, 3, 112, 34, 89, 0, 114, 115, 1, 112, 103, 2, 32, 0, 114, 115, 1, 112, 107, 2, 32, 0, 114, 115, 1, 112, 108, 2, 32, 0, 114, 115, 1, 112, 110, 2, 32, 0, 114, 115, 1, 112, 114, 2, 32, 0, 108, 112, 101, 8, 3, 112, 55, 48, 13, 0, 4, 114, 115, 1, 107, 103, 3, 113, 34, 89, 0, 114, 115, 1, 107, 116, 0, 114, 115, 1, 112, 117, 111, 108, 98, 0, 4, 3, 116, 0, 1, 17, 67, 2, 107, 17, 65, 12, 0, 1, 100, 17, 67, 17, 65, 2, 108, 101, 32, 0, 1, 100, 100, 17, 67, 2, 108, 101, 32, 0, 1, 100, 101, 111, 116, 2, 108, 105, 110, 103, 0, 1, 100, 110, 105, 2, 108, 105, 110, 103, 0, 1, 100, 115, 17, 67, 2, 108, 101, 32, 0, 1, 108, 108, 2, 115, 101, 114, 0, 1, 116, 105, 17, 67, 2, 114, 105, 110, 103, 0, 1, 116, 110, 171, 195, 105, 2, 114, 21, 110, 0, 1, 119, 21, 2, 103, 101, 110, 100, 101, 0, 1, 119, 114, 2, 115, 101, 32, 0, 2, 17, 67, 17, 65, 0, 8, 100, 110, 101, 101, 2, 108, 105, 103, 0, 195, 171, 0, 114, 101, 1, 119, 115, 2, 32, 3, 116, 12, 34, 13, 0, 4, 114, 101, 1, 108, 21, 2, 32, 3, 116, 34, 13, 0, 114, 101, 8, 0, 108, 108, 101, 110, 100, 101, 8, 3, 116, 55, 6, 108, 50, 72, 13, 0, 108, 108, 101, 110, 100, 105, 103, 8, 3, 116, 55, 6, 108, 50, 72, 13, 136, 0, 108, 97, 97, 114, 1, 100, 114, 111, 111, 3, 116, 55, 115, 34, 0, 109, 97, 1, 17, 67, 2, 32, 3, 116, 65, 35, 0, 100, 101, 1, 17, 67, 2, 32, 3, 116, 72, 13, 0, 100, 101, 108, 8, 3, 116, 72, 13, 55, 0, 100, 101, 115, 1, 17, 67, 2, 32, 3, 116, 72, 13, 89, 0, 119, 101, 108, 1, 17, 67, 2, 17, 65, 3, 116, 84, 13, 55, 0, 119, 105, 103, 104, 101, 105, 2, 100, 3, 116, 84, 13, 136, 4, 123, 0, 4, 105, 3, 123, 0, 121, 0, 105, 101, 114, 3, 123, 13, 34, 0, 105, 110, 100, 2, 101, 107, 115, 3, 123, 50, 47, 10, 0, 117, 3, 128, 0, 117, 101, 1, 17, 67, 3, 128, 13, 0, 117, 110, 116, 106, 105, 101, 3, 128, 37, 68, 80, 37, 0, 7, 6, 102, 0, 2, 102, 3, 0, 4, 105, 101, 108, 100, 3, 21, 0, 105, 116, 122, 8, 0, 117, 108, 1, 21, 2, 32, 0, 3, 83, 0, 4, 97, 2, 98, 114, 105, 101, 107, 3, 83, 2, 35, 0, 97, 2, 110, 97, 116, 105, 0, 97, 2, 116, 97, 21, 0, 97, 114, 105, 2, 115, 101, 195, 171, 114, 3, 83, 2, 35, 34, 2, 37, 0, 97, 114, 109, 97, 2, 115, 101, 117, 116, 3, 83, 2, 35, 34, 65, 2, 35, 0, 97, 116, 2, 115, 111, 101, 110, 3, 83, 2, 35, 47, 0, 97, 107, 2, 116, 111, 114, 101, 3, 83, 2, 35, 49, 0, 97, 107, 117, 108, 2, 116, 101, 105, 116, 3, 83, 2, 35, 49, 2, 111, 55, 0, 97, 107, 116, 117, 2, 114, 101, 114, 105, 3, 83, 2, 35, 49, 47, 2, 118, 0, 4, 97, 110, 2, 102, 97, 114, 101, 3, 83, 2, 35, 50, 0, 97, 110, 8, 2, 116, 111, 0, 97, 110, 116, 97, 2, 115, 17, 65, 3, 83, 2, 35, 50, 47, 2, 35, 0, 97, 109, 105, 2, 108, 105, 17, 65, 3, 83, 2, 35, 65, 37, 0, 97, 98, 114, 105, 2, 17, 67, 17, 65, 3, 83, 2, 35, 71, 34, 2, 37, 0, 97, 115, 105, 108, 105, 3, 83, 2, 35, 89, 13, 55, 2, 37, 0, 97, 115, 101, 2, 116, 25, 3, 83, 2, 35, 89, 108, 0, 97, 115, 97, 100, 101, 3, 83, 2, 35, 89, 115, 72, 13, 0, 4, 105, 2, 115, 97, 110, 116, 3, 83, 2, 37, 0, 105, 8, 2, 110, 97, 21, 0, 105, 97, 115, 107, 111, 3, 83, 2, 37, 35, 89, 49, 2, 40, 0, 111, 114, 101, 2, 108, 3, 83, 2, 40, 34, 112, 0, 111, 110, 101, 2, 116, 105, 101, 3, 83, 2, 40, 50, 116, 0, 101, 2, 109, 105, 110, 17, 65, 3, 83, 2, 108, 0, 101, 114, 111, 2, 109, 111, 3, 83, 2, 108, 34, 2, 40, 0, 101, 100, 101, 2, 114, 97, 3, 83, 2, 108, 72, 13, 0, 101, 115, 115, 111, 114, 2, 97, 21, 3, 83, 2, 108, 89, 13, 34, 0, 111, 2, 115, 115, 105, 101, 108, 3, 83, 2, 110, 0, 111, 114, 8, 2, 17, 67, 21, 3, 83, 2, 110, 34, 0, 111, 114, 109, 97, 2, 108, 105, 101, 110, 3, 83, 2, 110, 34, 65, 2, 35, 0, 111, 114, 109, 105, 2, 100, 97, 3, 83, 2, 110, 34, 65, 2, 37, 0, 111, 114, 109, 117, 2, 108, 105, 101, 114, 3, 83, 2, 110, 34, 65, 2, 118, 0, 111, 110, 2, 116, 101, 105, 110, 3, 83, 2, 110, 50, 0, 111, 110, 100, 117, 101, 3, 83, 2, 110, 50, 72, 118, 0, 111, 115, 2, 102, 97, 3, 83, 2, 110, 89, 0, 117, 110, 103, 2, 101, 3, 83, 2, 111, 68, 136, 0, 101, 8, 2, 116, 97, 21, 3, 83, 2, 116, 0, 111, 116, 111, 2, 115, 116, 97, 3, 83, 2, 117, 47, 2, 40, 0, 111, 116, 111, 103, 101, 2, 110, 105, 101, 3, 83, 2, 117, 47, 2, 40, 136, 116, 0, 111, 110, 101, 2, 116, 105, 101, 107, 3, 83, 2, 117, 50, 13, 0, 117, 8, 2, 116, 105, 3, 83, 2, 118, 0, 117, 115, 105, 2, 108, 108, 17, 65, 3, 83, 2, 118, 89, 13, 0, 121, 110, 103, 101, 2, 118, 111, 101, 108, 105, 3, 83, 2, 123, 50, 136, 13, 0, 111, 114, 8, 2, 115, 101, 32, 3, 83, 6, 110, 34, 0, 111, 110, 105, 101, 115, 1, 21, 3, 83, 6, 117, 50, 37, 89, 0, 4, 105, 2, 115, 105, 101, 107, 3, 83, 13, 0, 105, 2, 115, 107, 17, 65, 0, 101, 114, 2, 119, 101, 101, 108, 3, 83, 13, 34, 0, 101, 110, 111, 109, 2, 101, 3, 83, 13, 50, 2, 110, 65, 0, 101, 110, 111, 109, 101, 110, 2, 17, 65, 21, 3, 83, 13, 50, 2, 110, 65, 13, 50, 0, 4, 101, 108, 1, 21, 2, 101, 110, 100, 3, 83, 13, 55, 0, 101, 108, 1, 21, 2, 105, 110, 103, 0, 105, 108, 105, 2, 112, 112, 17, 65, 3, 83, 13, 55, 13, 0, 105, 108, 105, 115, 116, 121, 110, 3, 83, 13, 55, 13, 89, 47, 6, 123, 50, 0, 105, 108, 108, 101, 2, 116, 3, 83, 13, 55, 108, 0, 101, 115, 115, 111, 114, 101, 2, 32, 3, 83, 13, 89, 117, 34, 13, 0, 114, 97, 2, 103, 105, 101, 108, 3, 83, 34, 2, 35, 0, 4, 114, 97, 110, 2, 17, 67, 105, 110, 97, 3, 83, 34, 2, 35, 50, 0, 114, 97, 110, 8, 2, 17, 67, 105, 115, 17, 67, 17, 65, 0, 114, 97, 110, 103, 105, 2, 112, 97, 110, 105, 3, 83, 34, 2, 35, 68, 2, 37, 0, 114, 101, 2, 107, 119, 101, 110, 3, 83, 34, 2, 37, 0, 114, 111, 110, 116, 2, 17, 65, 21, 3, 83, 34, 2, 110, 50, 47, 0, 114, 117, 2, 115, 116, 114, 3, 83, 34, 2, 111, 0, 114, 105, 107, 107, 97, 100, 101, 2, 108, 3, 83, 34, 13, 49, 13, 72, 112, 0, 114, 101, 117, 100, 3, 83, 34, 124, 72, 0, 97, 2, 108, 97, 110, 107, 115, 3, 83, 35, 0, 105, 110, 101, 1, 114, 111, 109, 2, 21, 3, 83, 37, 50, 13, 10, 0, 4, 111, 110, 105, 101, 1, 21, 3, 83, 40, 50, 6, 37, 0, 111, 110, 105, 101, 1, 21, 2, 115, 21, 21, 0, 4, 108, 97, 2, 103, 114, 97, 110, 116, 3, 83, 55, 2, 35, 0, 108, 97, 2, 109, 105, 0, 108, 97, 109, 98, 111, 2, 106, 97, 110, 116, 3, 83, 55, 2, 35, 65, 71, 2, 40, 0, 108, 111, 2, 114, 101, 3, 83, 55, 2, 40, 0, 108, 101, 98, 2, 111, 116, 111, 109, 105, 101, 3, 83, 55, 2, 108, 71, 0, 108, 111, 114, 105, 2, 115, 115, 17, 65, 3, 83, 55, 2, 117, 34, 13, 0, 108, 117, 2, 119, 101, 3, 83, 55, 2, 118, 0, 108, 105, 107, 116, 8, 2, 101, 114, 17, 65, 3, 83, 55, 13, 49, 47, 0, 101, 115, 115, 111, 114, 3, 83, 108, 89, 13, 34, 0, 111, 107, 8, 2, 111, 3, 83, 110, 49, 10, 0, 117, 110, 103, 117, 115, 3, 83, 111, 68, 81, 111, 89, 10, 0, 101, 98, 114, 117, 97, 114, 105, 101, 3, 83, 116, 71, 34, 118, 4, 115, 34, 37, 0, 111, 2, 116, 111, 103, 114, 97, 3, 83, 117, 0, 111, 116, 111, 3, 83, 117, 47, 40, 0, 111, 108, 105, 111, 3, 83, 117, 55, 37, 10, 40, 0, 101, 105, 116, 101, 3, 83, 123, 47, 13, 0, 121, 110, 103, 101, 2, 17, 67, 3, 83, 123, 50, 136, 13, 0, 7, 6, 103, 0, 2, 103, 3, 0, 4, 104, 116, 3, 21, 0, 110, 1, 21, 2, 32, 0, 110, 111, 110, 1, 21, 2, 32, 3, 21, 102, 114, 0, 104, 2, 32, 3, 49, 0, 104, 8, 3, 81, 0, 104, 105, 2, 116, 97, 3, 81, 2, 37, 0, 117, 105, 108, 108, 111, 116, 105, 110, 101, 3, 81, 2, 37, 55, 2, 40, 47, 37, 50, 0, 111, 2, 114, 105, 108, 108, 97, 3, 81, 2, 40, 0, 117, 101, 114, 114, 105, 108, 108, 97, 3, 81, 13, 34, 6, 109, 55, 35, 0, 97, 114, 97, 103, 101, 3, 81, 13, 34, 6, 115, 75, 0, 108, 105, 115, 101, 2, 114, 105, 101, 110, 3, 81, 55, 13, 89, 13, 0, 97, 108, 97, 2, 32, 3, 81, 115, 55, 2, 35, 0, 111, 117, 114, 109, 101, 116, 3, 81, 117, 34, 65, 123, 12, 0, 3, 136, 0, 4, 97, 2, 108, 17, 65, 17, 67, 3, 136, 2, 35, 0, 97, 2, 114, 105, 101, 112, 0, 97, 114, 2, 110, 3, 136, 2, 35, 34, 0, 97, 114, 121, 101, 1, 17, 67, 21, 3, 136, 2, 35, 34, 6, 123, 13, 0, 97, 114, 110, 105, 2, 115, 111, 101, 110, 3, 136, 2, 35, 34, 50, 2, 37, 0, 97, 108, 2, 106, 111, 101, 110, 3, 136, 2, 35, 55, 0, 97, 108, 97, 2, 115, 105, 3, 136, 2, 35, 55, 115, 0, 111, 101, 100, 2, 103, 117, 110, 115, 116, 3, 136, 2, 40, 47, 0, 111, 101, 100, 101, 114, 2, 116, 105, 101, 3, 136, 2, 40, 72, 13, 34, 0, 111, 101, 119, 101, 114, 8, 3, 136, 2, 40, 84, 13, 34, 0, 111, 114, 2, 100, 121, 110, 3, 136, 2, 110, 34, 0, 4, 111, 100, 2, 115, 97, 108, 105, 103, 3, 136, 2, 110, 47, 0, 111, 100, 2, 118, 114, 0, 4, 111, 100, 115, 2, 100, 105, 101, 110, 115, 116, 105, 103, 3, 136, 2, 110, 47, 89, 0, 111, 100, 115, 2, 108, 97, 115, 116, 101, 114, 0, 111, 100, 100, 101, 2, 108, 111, 3, 136, 2, 110, 72, 13, 0, 117, 116, 116, 117, 2, 114, 97, 3, 136, 2, 111, 47, 2, 111, 0, 111, 2, 100, 105, 110, 3, 136, 2, 117, 0, 97, 117, 116, 101, 110, 103, 3, 136, 2, 129, 47, 108, 68, 0, 111, 195, 171, 1, 17, 65, 3, 136, 6, 40, 13, 0, 97, 109, 105, 101, 115, 3, 136, 6, 115, 65, 37, 89, 0, 111, 111, 103, 1, 17, 65, 2, 32, 3, 136, 6, 117, 136, 0, 111, 103, 105, 101, 115, 1, 17, 65, 3, 136, 6, 117, 136, 37, 89, 0, 97, 115, 8, 2, 17, 65, 3, 136, 7, 35, 89, 10, 0, 103, 101, 1, 21, 2, 32, 3, 136, 13, 0, 105, 109, 2, 110, 97, 25, 3, 136, 13, 65, 0, 105, 109, 110, 97, 2, 115, 105, 17, 65, 3, 136, 13, 65, 50, 115, 0, 4, 114, 97, 2, 102, 105, 101, 107, 3, 136, 34, 2, 35, 0, 114, 97, 2, 102, 105, 101, 116, 0, 114, 97, 2, 110, 105, 101, 116, 0, 114, 97, 2, 115, 105, 101, 117, 0, 114, 97, 8, 2, 118, 17, 65, 0, 114, 97, 110, 100, 105, 2, 111, 3, 136, 34, 2, 35, 50, 72, 2, 37, 0, 114, 97, 109, 97, 2, 100, 111, 101, 3, 136, 34, 2, 35, 65, 2, 35, 0, 114, 97, 109, 109, 97, 2, 116, 105, 107, 3, 136, 34, 2, 35, 65, 35, 0, 114, 97, 100, 101, 2, 114, 105, 110, 103, 3, 136, 34, 2, 35, 72, 116, 0, 114, 111, 110, 100, 119, 101, 116, 108, 105, 107, 3, 136, 34, 2, 110, 50, 47, 84, 108, 47, 55, 13, 49, 0, 114, 97, 97, 100, 8, 2, 116, 3, 136, 34, 2, 115, 0, 4, 114, 97, 97, 100, 8, 2, 110, 101, 103, 101, 3, 136, 34, 2, 115, 47, 0, 114, 97, 97, 100, 8, 2, 118, 121, 102, 0, 114, 97, 97, 100, 8, 2, 101, 3, 136, 34, 2, 115, 47, 10, 0, 114, 97, 97, 100, 115, 101, 8, 2, 115, 3, 136, 34, 2, 115, 47, 89, 108, 0, 114, 1, 97, 17, 67, 117, 111, 2, 111, 111, 116, 106, 105, 101, 3, 136, 34, 6, 0, 4, 114, 97, 8, 2, 110, 97, 3, 136, 34, 13, 0, 114, 105, 2, 102, 102, 105, 101, 114, 0, 114, 105, 8, 2, 109, 17, 65, 0, 114, 97, 115, 8, 2, 17, 65, 3, 136, 34, 35, 89, 10, 0, 114, 105, 101, 107, 119, 97, 3, 136, 34, 37, 49, 58, 35, 0, 114, 111, 110, 100, 119, 101, 2, 116, 25, 3, 136, 34, 110, 50, 47, 84, 108, 0, 114, 111, 110, 100, 119, 101, 116, 2, 97, 3, 136, 34, 110, 50, 47, 84, 108, 47, 10, 0, 114, 97, 8, 2, 115, 105, 101, 3, 136, 34, 115, 0, 114, 97, 100, 101, 2, 17, 67, 3, 136, 34, 115, 72, 13, 0, 114, 111, 116, 101, 114, 101, 3, 136, 34, 117, 47, 13, 34, 13, 0, 4, 114, 111, 110, 100, 1, 114, 101, 116, 103, 97, 2, 105, 3, 136, 34, 131, 50, 47, 10, 0, 114, 111, 110, 100, 2, 111, 0, 97, 116, 8, 2, 111, 3, 136, 35, 47, 10, 0, 97, 109, 105, 101, 2, 32, 3, 136, 35, 65, 6, 37, 0, 111, 103, 105, 101, 1, 17, 65, 2, 32, 3, 136, 40, 136, 6, 37, 0, 108, 101, 116, 115, 101, 114, 3, 136, 55, 7, 108, 47, 89, 13, 34, 0, 108, 97, 110, 115, 3, 136, 55, 35, 50, 89, 0, 4, 108, 97, 115, 2, 97, 3, 136, 55, 35, 89, 10, 0, 108, 97, 115, 2, 111, 0, 105, 102, 8, 2, 17, 65, 3, 136, 109, 83, 10, 0, 111, 109, 97, 103, 2, 116, 105, 103, 3, 136, 110, 65, 10, 2, 35, 136, 0, 117, 115, 2, 111, 111, 105, 3, 136, 111, 89, 10, 0, 97, 100, 101, 8, 3, 136, 115, 72, 13, 0, 4, 97, 115, 2, 101, 114, 105, 103, 3, 136, 115, 89, 0, 97, 115, 2, 105, 101, 0, 97, 115, 2, 105, 103, 0, 195, 169, 115, 101, 108, 3, 136, 116, 89, 13, 55, 0, 4, 111, 117, 100, 2, 97, 21, 3, 136, 120, 47, 10, 0, 111, 117, 100, 2, 111, 0, 104, 101, 105, 100, 1, 21, 3, 136, 123, 47, 0, 4, 97, 110, 115, 1, 21, 3, 136, 133, 50, 89, 0, 97, 110, 115, 2, 17, 67, 0, 7, 6, 104, 0, 4, 1, 17, 65, 21, 2, 32, 3, 0, 2, 104, 3, 0, 108, 101, 1, 17, 65, 2, 32, 3, 8, 105, 108, 0, 3, 107, 0, 97, 114, 2, 112, 111, 101, 110, 3, 107, 2, 35, 34, 0, 4, 97, 114, 100, 2, 17, 67, 21, 3, 107, 2, 35, 34, 47, 0, 97, 114, 116, 2, 114, 111, 101, 114, 0, 97, 114, 116, 2, 115, 116, 111, 103, 116, 101, 32, 0, 97, 114, 108, 101, 2, 107, 121, 110, 3, 107, 2, 35, 34, 55, 13, 0, 97, 114, 109, 111, 2, 110, 105, 101, 3, 107, 2, 35, 34, 65, 2, 40, 0, 4, 97, 108, 2, 115, 115, 116, 97, 114, 3, 107, 2, 35, 55, 0, 97, 108, 2, 118, 101, 21, 0, 97, 108, 102, 2, 118, 105, 101, 114, 0, 97, 108, 102, 2, 118, 121, 102, 0, 97, 108, 111, 2, 103, 101, 3, 107, 2, 35, 55, 2, 40, 0, 97, 108, 108, 101, 108, 117, 106, 97, 3, 107, 2, 35, 55, 13, 55, 118, 57, 2, 35, 0, 4, 97, 108, 102, 2, 100, 114, 105, 101, 3, 107, 2, 35, 55, 83, 0, 97, 108, 102, 2, 107, 114, 111, 21, 0, 97, 108, 102, 2, 110, 101, 103, 101, 0, 97, 108, 102, 2, 115, 101, 119, 101, 0, 97, 108, 102, 2, 116, 105, 101, 110, 0, 97, 108, 102, 2, 116, 119, 97, 97, 108, 102, 0, 97, 108, 102, 2, 116, 119, 101, 101, 0, 4, 97, 108, 102, 2, 101, 101, 110, 3, 107, 2, 35, 55, 83, 10, 0, 97, 108, 102, 2, 101, 108, 102, 0, 97, 108, 102, 8, 2, 97, 103, 25, 0, 97, 108, 102, 115, 101, 2, 115, 3, 107, 2, 35, 55, 83, 89, 108, 0, 4, 105, 2, 115, 116, 111, 3, 107, 2, 37, 0, 105, 8, 2, 98, 105, 115, 0, 105, 101, 114, 110, 97, 2, 109, 97, 97, 108, 3, 107, 2, 37, 12, 34, 50, 115, 0, 105, 195, 171, 114, 2, 97, 114, 103, 105, 101, 3, 107, 2, 37, 13, 34, 0, 105, 195, 171, 114, 97, 114, 2, 103, 105, 101, 32, 24, 3, 107, 2, 37, 13, 34, 2, 35, 34, 0, 105, 195, 171, 114, 111, 2, 103, 108, 105, 101, 3, 107, 2, 37, 13, 34, 2, 40, 0, 105, 112, 2, 110, 111, 17, 67, 17, 65, 3, 107, 2, 37, 48, 0, 105, 112, 101, 114, 2, 98, 111, 3, 107, 2, 37, 48, 13, 34, 0, 105, 97, 2, 115, 105, 110, 116, 3, 107, 2, 37, 57, 2, 35, 0, 105, 115, 116, 114, 105, 2, 111, 110, 3, 107, 2, 37, 89, 47, 34, 2, 37, 0, 105, 195, 171, 110, 97, 3, 107, 2, 37, 116, 12, 50, 35, 0, 105, 103, 105, 195, 171, 2, 110, 17, 65, 3, 107, 2, 37, 136, 2, 37, 116, 0, 111, 116, 101, 2, 108, 3, 107, 2, 40, 47, 112, 0, 111, 101, 118, 101, 2, 114, 3, 107, 2, 40, 83, 112, 0, 111, 101, 118, 101, 101, 108, 104, 2, 101, 3, 107, 2, 40, 83, 116, 55, 107, 0, 111, 2, 110, 110, 101, 117, 114, 3, 107, 2, 110, 0, 4, 111, 114, 2, 108, 111, 115, 3, 107, 2, 110, 34, 0, 111, 114, 2, 109, 111, 0, 111, 114, 114, 105, 2, 98, 17, 65, 3, 107, 2, 110, 34, 2, 37, 0, 111, 110, 103, 2, 97, 3, 107, 2, 110, 68, 136, 0, 111, 114, 105, 115, 111, 110, 2, 116, 97, 3, 107, 2, 117, 34, 2, 37, 89, 2, 110, 50, 0, 4, 111, 111, 103, 2, 100, 114, 97, 3, 107, 2, 117, 136, 0, 111, 111, 103, 2, 109, 111, 101, 100, 105, 103, 0, 117, 2, 109, 101, 117, 114, 3, 107, 2, 118, 0, 117, 105, 115, 2, 104, 111, 117, 100, 32, 3, 107, 2, 127, 89, 0, 97, 114, 116, 105, 103, 1, 21, 3, 107, 6, 35, 34, 47, 13, 136, 0, 97, 108, 1, 17, 67, 21, 2, 115, 17, 65, 3, 107, 6, 35, 55, 0, 97, 108, 102, 8, 2, 103, 101, 14, 128, 132, 132, 3, 107, 6, 35, 55, 83, 0, 105, 110, 107, 101, 2, 112, 105, 110, 107, 3, 107, 13, 68, 49, 13, 0, 4, 97, 114, 100, 2, 104, 101, 105, 100, 3, 107, 35, 34, 47, 0, 97, 114, 100, 2, 108, 111, 0, 97, 114, 100, 2, 115, 116, 101, 0, 97, 114, 116, 2, 115, 116, 111, 103, 116, 101, 32, 24, 0, 97, 114, 100, 103, 101, 2, 17, 67, 3, 107, 35, 34, 47, 136, 13, 0, 97, 114, 109, 111, 110, 105, 101, 115, 3, 107, 35, 34, 65, 6, 117, 50, 37, 89, 0, 97, 114, 100, 101, 3, 107, 35, 34, 72, 13, 0, 97, 110, 100, 2, 111, 3, 107, 35, 50, 47, 19, 0, 105, 116, 108, 101, 114, 3, 107, 37, 47, 55, 13, 34, 0, 105, 112, 111, 8, 2, 21, 14, 128, 132, 132, 3, 107, 37, 48, 40, 0, 105, 110, 2, 100, 111, 101, 3, 107, 37, 50, 0, 105, 109, 110, 101, 3, 107, 37, 65, 50, 13, 0, 105, 115, 116, 101, 114, 2, 105, 3, 107, 37, 89, 47, 6, 116, 34, 0, 105, 115, 116, 101, 114, 2, 101, 3, 107, 37, 89, 47, 13, 34, 0, 111, 101, 110, 100, 101, 114, 3, 107, 40, 50, 13, 34, 0, 111, 102, 2, 17, 65, 3, 107, 110, 83, 10, 0, 97, 2, 119, 101, 3, 107, 115, 0, 97, 112, 101, 114, 3, 107, 115, 48, 13, 34, 0, 97, 110, 101, 8, 2, 17, 67, 3, 107, 115, 50, 13, 0, 97, 109, 101, 114, 3, 107, 115, 65, 13, 34, 0, 111, 98, 111, 8, 3, 107, 117, 71, 40, 0, 111, 102, 2, 105, 101, 3, 107, 117, 83, 0, 7, 6, 105, 0, 4, 1, 17, 67, 2, 195, 171, 115, 116, 97, 3, 2, 37, 0, 1, 104, 2, 100, 114, 17, 65, 0, 1, 112, 115, 2, 111, 101, 110, 0, 1, 120, 97, 116, 2, 21, 0, 1, 180, 195, 2, 25, 0, 2, 114, 111, 110, 105, 101, 0, 2, 118, 111, 111, 114, 0, 8, 2, 107, 111, 0, 8, 2, 109, 109, 117, 0, 8, 2, 114, 114, 0, 195, 171, 116, 101, 105, 116, 3, 2, 37, 13, 47, 6, 123, 47, 0, 114, 97, 8, 2, 17, 67, 3, 2, 37, 34, 35, 0, 116, 97, 108, 105, 2, 97, 3, 2, 37, 47, 2, 35, 55, 2, 37, 0, 101, 116, 101, 114, 109, 97, 2, 103, 3, 2, 37, 47, 13, 34, 65, 2, 35, 0, 112, 101, 2, 107, 111, 110, 3, 2, 37, 48, 13, 0, 108, 108, 117, 109, 105, 2, 110, 17, 65, 3, 2, 37, 55, 2, 40, 65, 2, 37, 0, 108, 108, 117, 2, 115, 116, 114, 17, 65, 3, 2, 37, 55, 2, 111, 0, 108, 108, 117, 2, 115, 105, 3, 2, 37, 55, 118, 0, 109, 112, 97, 108, 97, 3, 2, 37, 65, 48, 115, 55, 35, 0, 98, 101, 114, 2, 105, 21, 3, 2, 37, 71, 116, 34, 0, 100, 8, 2, 17, 65, 3, 2, 37, 72, 0, 4, 100, 101, 2, 97, 3, 2, 37, 72, 2, 37, 0, 100, 101, 2, 195, 171, 0, 100, 105, 8, 2, 111, 0, 115, 108, 97, 109, 8, 2, 105, 3, 2, 37, 89, 55, 2, 35, 65, 0, 101, 115, 101, 8, 2, 17, 67, 3, 4, 37, 89, 13, 0, 101, 1, 114, 116, 2, 32, 24, 3, 6, 37, 0, 116, 105, 115, 1, 17, 67, 21, 2, 32, 3, 6, 37, 47, 13, 89, 0, 4, 101, 107, 1, 110, 21, 2, 32, 3, 6, 37, 49, 0, 101, 107, 1, 110, 21, 2, 101, 32, 0, 101, 107, 1, 114, 116, 21, 2, 32, 0, 101, 107, 1, 114, 116, 21, 2, 101, 25, 0, 101, 107, 1, 116, 21, 2, 32, 0, 101, 107, 1, 116, 21, 2, 101, 32, 0, 101, 102, 1, 115, 115, 2, 32, 3, 6, 37, 83, 0, 4, 101, 119, 101, 1, 115, 110, 2, 25, 3, 6, 37, 84, 13, 0, 101, 119, 101, 1, 115, 115, 2, 32, 0, 115, 105, 101, 1, 17, 67, 3, 6, 37, 89, 37, 0, 1, 17, 67, 114, 97, 110, 2, 115, 115, 117, 115, 3, 6, 109, 0, 109, 109, 101, 114, 8, 2, 21, 14, 128, 132, 133, 3, 6, 109, 65, 13, 34, 10, 0, 4, 115, 1, 17, 67, 17, 65, 2, 32, 3, 6, 109, 89, 0, 115, 1, 109, 101, 111, 108, 98, 0, 115, 1, 114, 97, 116, 105, 108, 2, 12, 0, 115, 116, 101, 1, 17, 67, 17, 65, 2, 32, 3, 6, 109, 89, 47, 13, 0, 115, 116, 105, 101, 115, 1, 17, 67, 21, 3, 6, 109, 89, 47, 37, 89, 0, 4, 115, 107, 1, 17, 67, 2, 32, 3, 6, 109, 89, 49, 0, 115, 107, 1, 17, 67, 2, 101, 32, 0, 115, 109, 101, 1, 21, 2, 25, 3, 6, 109, 89, 65, 13, 0, 107, 97, 1, 21, 2, 32, 3, 8, 2, 37, 49, 2, 35, 0, 115, 1, 114, 97, 21, 2, 25, 3, 8, 13, 89, 0, 4, 1, 17, 67, 2, 103, 3, 13, 0, 1, 102, 101, 100, 2, 110, 0, 1, 109, 2, 110, 105, 115, 116, 101, 114, 0, 1, 115, 105, 114, 107, 2, 25, 0, 2, 110, 110, 101, 101, 109, 98, 97, 0, 2, 116, 105, 101, 102, 0, 2, 116, 105, 101, 119, 0, 8, 109, 101, 2, 114, 0, 103, 101, 114, 1, 10, 2, 32, 14, 128, 128, 130, 3, 13, 34, 0, 103, 101, 114, 115, 1, 10, 2, 32, 14, 128, 128, 131, 3, 13, 34, 89, 0, 107, 101, 1, 10, 2, 32, 14, 128, 128, 131, 3, 13, 49, 13, 0, 107, 101, 114, 1, 108, 10, 2, 17, 67, 3, 13, 49, 13, 34, 0, 107, 101, 110, 100, 1, 17, 67, 10, 3, 13, 49, 13, 50, 47, 0, 107, 101, 110, 100, 101, 1, 17, 67, 10, 3, 13, 49, 13, 50, 72, 13, 0, 107, 105, 110, 103, 1, 17, 67, 3, 13, 49, 13, 68, 0, 110, 2, 116, 117, 115, 115, 101, 110, 3, 13, 50, 0, 110, 116, 101, 110, 2, 115, 3, 13, 50, 47, 108, 50, 0, 110, 115, 117, 114, 103, 101, 110, 2, 17, 67, 3, 13, 50, 89, 2, 111, 34, 136, 108, 50, 0, 110, 103, 101, 110, 105, 101, 117, 114, 3, 13, 50, 136, 13, 50, 6, 118, 13, 34, 0, 109, 109, 105, 8, 2, 103, 114, 17, 65, 3, 13, 65, 13, 0, 4, 109, 112, 111, 2, 115, 97, 110, 116, 3, 13, 65, 48, 2, 40, 0, 109, 112, 111, 2, 116, 101, 0, 109, 112, 101, 114, 97, 2, 116, 17, 65, 21, 3, 13, 65, 48, 2, 108, 34, 2, 35, 0, 109, 98, 101, 2, 115, 3, 13, 65, 71, 13, 0, 4, 115, 1, 98, 117, 112, 2, 32, 3, 13, 89, 0, 115, 1, 108, 105, 117, 118, 0, 115, 1, 108, 111, 112, 2, 32, 0, 115, 1, 109, 17, 65, 17, 65, 2, 32, 0, 115, 1, 110, 101, 2, 25, 0, 4, 115, 1, 110, 102, 2, 17, 65, 3, 13, 89, 10, 0, 115, 1, 110, 110, 2, 17, 65, 0, 115, 114, 97, 101, 2, 108, 105, 21, 3, 13, 89, 34, 2, 121, 0, 115, 114, 97, 101, 2, 108, 105, 3, 13, 89, 34, 122, 0, 103, 101, 114, 1, 17, 67, 21, 2, 17, 67, 17, 65, 3, 13, 136, 13, 34, 0, 103, 101, 110, 100, 1, 17, 67, 21, 2, 32, 3, 13, 136, 13, 50, 47, 0, 103, 101, 110, 100, 101, 1, 17, 67, 21, 3, 13, 136, 13, 50, 72, 13, 0, 103, 105, 110, 103, 1, 17, 67, 3, 13, 136, 13, 68, 0, 103, 104, 101, 105, 2, 100, 3, 13, 136, 123, 0, 4, 99, 1, 21, 2, 32, 3, 21, 0, 108, 101, 115, 2, 32, 0, 116, 121, 2, 32, 24, 0, 195, 169, 3, 26, 37, 0, 4, 3, 37, 0, 1, 21, 2, 115, 101, 114, 105, 110, 103, 0, 1, 104, 2, 100, 114, 111, 0, 1, 115, 112, 2, 103, 17, 65, 0, 2, 17, 67, 17, 65, 0, 8, 116, 110, 97, 2, 17, 67, 0, 101, 0, 101, 1, 103, 2, 114, 105, 103, 0, 101, 1, 104, 2, 114, 100, 105, 101, 0, 101, 1, 107, 2, 114, 97, 110, 17, 67, 0, 101, 1, 107, 2, 114, 105, 101, 0, 101, 1, 107, 2, 114, 116, 115, 0, 101, 1, 107, 115, 2, 114, 105, 103, 0, 101, 1, 112, 2, 114, 101, 119, 0, 101, 1, 112, 2, 114, 105, 110, 103, 0, 101, 1, 119, 2, 114, 111, 111, 107, 0, 101, 2, 117, 117, 0, 195, 171, 110, 3, 37, 6, 108, 50, 0, 97, 116, 101, 114, 1, 17, 67, 3, 37, 6, 115, 47, 13, 34, 0, 97, 116, 114, 105, 101, 115, 1, 17, 67, 3, 37, 6, 115, 47, 34, 37, 89, 0, 97, 110, 97, 3, 37, 6, 115, 50, 35, 0, 97, 97, 108, 2, 32, 25, 3, 37, 6, 115, 55, 0, 97, 108, 101, 2, 32, 3, 37, 6, 115, 55, 13, 0, 101, 101, 2, 17, 67, 3, 37, 6, 116, 0, 195, 171, 114, 2, 17, 65, 3, 37, 6, 116, 34, 0, 195, 171, 108, 101, 3, 37, 6, 116, 55, 13, 0, 101, 117, 115, 3, 37, 6, 128, 89, 0, 101, 1, 17, 67, 2, 114, 3, 37, 12, 0, 101, 195, 171, 2, 25, 3, 37, 12, 13, 0, 114, 105, 8, 2, 115, 3, 37, 34, 13, 0, 114, 114, 105, 116, 101, 114, 2, 21, 3, 37, 34, 13, 47, 6, 116, 34, 0, 114, 111, 110, 105, 101, 2, 32, 24, 3, 37, 34, 40, 50, 6, 37, 0, 97, 116, 114, 105, 101, 1, 17, 67, 3, 37, 35, 47, 34, 6, 37, 0, 116, 101, 105, 116, 1, 21, 3, 37, 47, 6, 123, 47, 0, 116, 101, 109, 3, 37, 47, 108, 65, 0, 4, 101, 107, 1, 110, 107, 21, 2, 32, 3, 37, 49, 0, 101, 107, 1, 116, 105, 114, 107, 0, 109, 112, 105, 8, 2, 16, 3, 37, 65, 48, 37, 0, 103, 8, 2, 108, 111, 3, 37, 81, 0, 4, 118, 101, 101, 114, 1, 17, 67, 3, 37, 83, 6, 116, 34, 0, 118, 101, 114, 1, 17, 67, 2, 17, 65, 0, 115, 101, 101, 114, 1, 21, 3, 37, 89, 6, 116, 34, 0, 115, 101, 114, 101, 110, 1, 21, 2, 100, 3, 37, 89, 6, 116, 34, 13, 50, 0, 115, 101, 117, 114, 1, 21, 3, 37, 89, 6, 128, 34, 0, 115, 105, 101, 1, 17, 67, 21, 21, 21, 3, 37, 89, 37, 0, 115, 105, 101, 117, 115, 1, 17, 67, 3, 37, 89, 37, 6, 128, 89, 0, 115, 108, 97, 109, 8, 3, 37, 89, 55, 35, 65, 0, 103, 101, 114, 105, 110, 103, 1, 21, 3, 37, 136, 6, 116, 34, 13, 68, 0, 4, 1, 29, 2, 103, 25, 12, 3, 109, 0, 1, 115, 2, 103, 17, 67, 0, 1, 119, 115, 2, 103, 0, 2, 17, 67, 0, 4, 100, 106, 105, 101, 3, 109, 37, 80, 37, 0, 116, 106, 105, 101, 0, 116, 1, 119, 2, 17, 65, 3, 109, 47, 0, 115, 1, 109, 101, 17, 67, 21, 2, 32, 3, 109, 89, 0, 115, 112, 101, 108, 1, 17, 67, 3, 109, 89, 48, 13, 55, 0, 103, 101, 1, 10, 2, 32, 3, 109, 136, 13, 0, 103, 101, 115, 1, 10, 2, 32, 3, 109, 136, 13, 89, 0, 195, 171, 3, 116, 12, 14, 0, 101, 117, 3, 119, 0, 106, 2, 17, 67, 3, 123, 0, 7, 6, 106, 0, 2, 106, 3, 0, 4, 97, 99, 107, 8, 3, 21, 0, 101, 97, 110, 0, 101, 101, 112, 0, 111, 104, 110, 0, 4, 3, 57, 0, 8, 2, 97, 110, 116, 106, 105, 101, 25, 12, 12, 0, 97, 8, 2, 17, 67, 111, 98, 17, 65, 3, 57, 2, 35, 0, 97, 112, 111, 2, 110, 3, 57, 2, 35, 48, 110, 0, 4, 97, 99, 97, 114, 97, 110, 100, 97, 3, 57, 2, 35, 49, 2, 35, 34, 6, 35, 50, 72, 35, 0, 97, 107, 97, 114, 97, 110, 100, 97, 0, 97, 107, 111, 112, 101, 119, 101, 114, 3, 57, 2, 35, 49, 2, 110, 48, 116, 84, 13, 34, 10, 0, 97, 110, 8, 2, 17, 67, 21, 3, 57, 2, 35, 50, 0, 97, 108, 111, 101, 2, 115, 105, 101, 3, 57, 2, 35, 55, 2, 40, 0, 97, 115, 2, 109, 121, 110, 3, 57, 2, 35, 89, 0, 117, 2, 114, 105, 100, 3, 57, 2, 40, 0, 111, 101, 114, 2, 110, 97, 3, 57, 2, 40, 34, 0, 117, 114, 105, 115, 2, 100, 105, 107, 3, 57, 2, 40, 34, 13, 89, 0, 111, 104, 97, 2, 110, 3, 57, 2, 40, 107, 35, 0, 111, 114, 100, 97, 8, 2, 110, 105, 17, 65, 3, 57, 2, 110, 34, 72, 115, 0, 97, 107, 111, 98, 2, 114, 101, 103, 111, 112, 3, 57, 2, 115, 49, 2, 110, 48, 0, 117, 2, 119, 101, 3, 57, 2, 118, 0, 117, 119, 101, 2, 108, 105, 101, 114, 3, 57, 2, 118, 84, 13, 0, 117, 119, 101, 108, 101, 3, 57, 2, 118, 84, 116, 55, 13, 0, 117, 110, 103, 105, 8, 2, 97, 3, 57, 4, 40, 68, 2, 37, 0, 97, 103, 8, 2, 17, 65, 3, 57, 7, 35, 136, 10, 0, 101, 114, 117, 115, 97, 108, 101, 109, 3, 57, 13, 34, 118, 89, 2, 35, 55, 2, 108, 65, 0, 101, 110, 101, 119, 101, 114, 3, 57, 13, 50, 116, 84, 13, 34, 0, 97, 8, 2, 110, 110, 17, 65, 12, 3, 57, 35, 0, 97, 110, 8, 2, 115, 17, 65, 110, 25, 3, 57, 35, 50, 0, 97, 110, 117, 97, 114, 105, 101, 3, 57, 35, 50, 118, 4, 115, 34, 37, 0, 97, 103, 117, 97, 114, 3, 57, 35, 81, 58, 35, 34, 0, 101, 115, 117, 115, 3, 57, 37, 12, 89, 111, 89, 0, 117, 110, 105, 101, 3, 57, 40, 50, 37, 0, 117, 108, 105, 101, 3, 57, 40, 55, 37, 0, 111, 110, 103, 2, 101, 116, 106, 105, 101, 3, 57, 110, 68, 0, 111, 110, 103, 101, 3, 57, 110, 68, 13, 0, 97, 2, 98, 114, 111, 101, 114, 3, 57, 115, 0, 4, 97, 103, 2, 101, 110, 100, 3, 57, 115, 136, 0, 97, 103, 2, 101, 114, 0, 97, 103, 2, 105, 110, 103, 0, 101, 108, 108, 105, 101, 3, 75, 6, 108, 55, 37, 0, 111, 117, 108, 101, 3, 75, 40, 12, 55, 0, 97, 122, 122, 3, 75, 113, 88, 0, 7, 6, 107, 0, 2, 107, 3, 0, 107, 108, 101, 114, 101, 3, 8, 49, 55, 6, 116, 34, 13, 0, 3, 49, 0, 97, 114, 97, 107, 116, 101, 114, 3, 49, 2, 35, 34, 35, 49, 47, 13, 34, 0, 4, 105, 2, 110, 101, 116, 105, 101, 3, 49, 2, 37, 0, 105, 8, 2, 116, 97, 0, 105, 97, 97, 116, 3, 49, 2, 37, 38, 115, 47, 0, 105, 107, 111, 101, 2, 106, 111, 101, 3, 49, 2, 37, 49, 40, 12, 0, 105, 108, 105, 109, 97, 110, 100, 106, 97, 114, 111, 3, 49, 2, 37, 55, 13, 65, 2, 35, 50, 75, 115, 34, 40, 0, 101, 110, 2, 109, 101, 114, 107, 101, 110, 3, 49, 2, 108, 50, 0, 117, 108, 105, 110, 3, 49, 2, 111, 55, 2, 37, 50, 0, 101, 114, 97, 2, 109, 105, 101, 107, 3, 49, 2, 112, 34, 2, 35, 0, 101, 108, 107, 105, 101, 2, 119, 121, 110, 3, 49, 2, 112, 55, 49, 2, 37, 0, 101, 108, 110, 101, 114, 2, 105, 110, 3, 49, 2, 112, 55, 50, 13, 34, 0, 4, 117, 2, 98, 97, 21, 3, 49, 2, 118, 0, 117, 2, 98, 105, 101, 107, 0, 101, 105, 115, 101, 114, 2, 105, 110, 3, 49, 2, 123, 88, 13, 34, 0, 117, 110, 100, 105, 1, 21, 2, 103, 3, 49, 6, 111, 50, 72, 13, 0, 117, 115, 1, 105, 3, 49, 6, 111, 89, 0, 101, 114, 1, 114, 101, 100, 101, 119, 2, 17, 65, 3, 49, 6, 116, 34, 0, 101, 117, 114, 105, 103, 1, 21, 3, 49, 6, 128, 34, 13, 136, 0, 101, 117, 115, 101, 8, 3, 49, 7, 128, 89, 13, 0, 4, 101, 114, 1, 21, 2, 116, 106, 105, 101, 3, 49, 13, 34, 0, 107, 101, 114, 2, 17, 65, 0, 101, 114, 101, 110, 100, 1, 110, 2, 32, 3, 49, 13, 34, 13, 50, 47, 0, 101, 114, 101, 110, 100, 101, 1, 110, 2, 32, 3, 49, 13, 34, 13, 50, 72, 13, 0, 101, 114, 107, 101, 114, 115, 1, 107, 105, 108, 102, 3, 49, 13, 34, 49, 113, 34, 89, 0, 4, 101, 108, 101, 110, 100, 2, 32, 3, 49, 13, 55, 13, 50, 47, 0, 107, 101, 108, 101, 110, 100, 2, 32, 0, 4, 101, 108, 101, 110, 100, 101, 2, 32, 3, 49, 13, 55, 13, 50, 72, 13, 0, 107, 101, 108, 101, 110, 100, 101, 2, 32, 0, 4, 101, 108, 105, 110, 103, 3, 49, 13, 55, 13, 68, 0, 107, 101, 108, 105, 110, 103, 0, 114, 97, 2, 119, 97, 116, 3, 49, 34, 2, 35, 0, 4, 114, 101, 8, 2, 111, 3, 49, 34, 2, 37, 0, 114, 105, 2, 111, 101, 108, 0, 114, 101, 2, 100, 105, 116, 3, 49, 34, 2, 108, 0, 114, 111, 107, 111, 100, 105, 2, 108, 3, 49, 34, 2, 110, 49, 13, 72, 109, 0, 114, 117, 103, 101, 114, 3, 49, 34, 6, 128, 13, 34, 0, 114, 97, 103, 8, 2, 17, 65, 3, 49, 34, 7, 35, 136, 10, 0, 4, 114, 101, 2, 100, 105, 101, 116, 3, 49, 34, 13, 0, 114, 101, 8, 2, 112, 101, 21, 0, 114, 105, 2, 115, 97, 110, 116, 0, 114, 105, 116, 2, 17, 65, 3, 49, 34, 13, 47, 0, 114, 101, 109, 101, 2, 116, 97, 114, 116, 3, 49, 34, 13, 65, 13, 0, 114, 105, 109, 105, 2, 110, 17, 65, 3, 49, 34, 13, 65, 13, 6, 0, 114, 105, 115, 116, 97, 2, 108, 3, 49, 34, 13, 89, 47, 35, 0, 114, 105, 116, 105, 101, 115, 3, 49, 34, 37, 47, 37, 89, 0, 114, 105, 101, 107, 101, 116, 3, 49, 34, 37, 49, 13, 47, 0, 114, 105, 101, 107, 101, 116, 119, 3, 49, 34, 37, 49, 13, 47, 84, 0, 114, 105, 101, 119, 101, 2, 108, 3, 49, 34, 37, 84, 13, 0, 114, 97, 2, 103, 105, 101, 3, 49, 34, 115, 0, 97, 109, 101, 108, 101, 8, 3, 49, 35, 65, 6, 116, 55, 13, 0, 105, 108, 111, 8, 3, 49, 37, 55, 2, 40, 0, 105, 101, 115, 101, 114, 2, 21, 3, 49, 37, 89, 13, 34, 0, 110, 105, 112, 2, 17, 65, 3, 49, 50, 109, 48, 19, 0, 110, 101, 114, 115, 2, 32, 3, 49, 50, 112, 34, 89, 0, 4, 108, 97, 2, 115, 115, 105, 101, 107, 3, 49, 55, 2, 35, 0, 108, 97, 2, 118, 105, 101, 114, 0, 108, 97, 114, 105, 110, 101, 2, 116, 3, 49, 55, 2, 35, 34, 2, 37, 50, 108, 0, 108, 97, 110, 100, 101, 2, 115, 116, 105, 3, 49, 55, 2, 35, 50, 72, 13, 0, 4, 108, 97, 119, 101, 114, 2, 98, 111, 101, 114, 3, 49, 55, 2, 115, 84, 13, 34, 0, 108, 97, 119, 101, 114, 2, 100, 114, 0, 108, 97, 119, 101, 114, 2, 104, 101, 101, 114, 0, 108, 97, 119, 101, 114, 2, 106, 97, 115, 0, 108, 97, 119, 101, 114, 2, 110, 101, 103, 101, 0, 108, 97, 119, 101, 114, 2, 115, 101, 119, 0, 108, 97, 119, 101, 114, 2, 116, 0, 108, 97, 119, 101, 114, 2, 118, 0, 108, 97, 119, 101, 114, 2, 97, 3, 49, 55, 2, 115, 84, 13, 34, 10, 0, 108, 97, 119, 101, 114, 115, 101, 115, 3, 49, 55, 2, 115, 84, 13, 34, 89, 108, 89, 0, 108, 111, 117, 2, 115, 117, 108, 101, 3, 49, 55, 2, 120, 0, 108, 101, 105, 110, 2, 115, 105, 101, 108, 105, 3, 49, 55, 2, 123, 50, 0, 108, 101, 105, 110, 115, 101, 2, 114, 105, 103, 3, 49, 55, 2, 123, 50, 89, 116, 0, 4, 108, 105, 2, 109, 97, 97, 116, 3, 49, 55, 13, 0, 108, 105, 2, 110, 105, 101, 107, 0, 108, 97, 8, 2, 115, 17, 65, 21, 21, 3, 49, 55, 35, 0, 108, 105, 2, 109, 111, 112, 3, 49, 55, 109, 0, 108, 105, 112, 2, 17, 65, 3, 49, 55, 109, 48, 10, 0, 108, 105, 109, 1, 103, 114, 101, 98, 2, 17, 65, 3, 49, 55, 109, 65, 10, 0, 108, 97, 2, 107, 111, 117, 115, 3, 49, 55, 115, 0, 108, 97, 97, 114, 98, 108, 121, 107, 108, 105, 107, 3, 49, 55, 115, 34, 71, 55, 6, 123, 49, 55, 13, 49, 0, 4, 108, 97, 119, 101, 114, 3, 49, 55, 115, 84, 13, 34, 0, 108, 97, 119, 101, 114, 2, 118, 101, 108, 100, 0, 108, 97, 118, 101, 115, 105, 109, 98, 101, 108, 3, 49, 55, 115, 84, 13, 89, 13, 65, 71, 13, 55, 0, 108, 101, 114, 101, 3, 49, 55, 116, 34, 13, 0, 108, 101, 117, 114, 2, 101, 102, 102, 101, 107, 3, 49, 55, 128, 34, 0, 108, 101, 117, 114, 101, 3, 49, 55, 128, 34, 13, 0, 119, 8, 3, 49, 58, 0, 4, 119, 97, 2, 100, 114, 97, 3, 49, 58, 2, 35, 0, 119, 97, 2, 116, 114, 121, 110, 0, 119, 97, 114, 8, 2, 116, 17, 65, 3, 49, 58, 2, 35, 34, 0, 119, 97, 114, 97, 110, 2, 116, 3, 49, 58, 2, 35, 34, 13, 50, 0, 119, 97, 114, 116, 101, 2, 116, 3, 49, 58, 2, 35, 34, 47, 108, 0, 119, 97, 108, 105, 2, 17, 67, 21, 3, 49, 58, 2, 35, 55, 2, 37, 0, 119, 97, 97, 100, 2, 97, 97, 114, 100, 105, 3, 49, 58, 2, 115, 47, 10, 0, 119, 105, 2, 116, 97, 110, 115, 3, 49, 58, 13, 0, 119, 105, 110, 116, 101, 2, 116, 3, 49, 58, 13, 50, 47, 108, 0, 119, 97, 114, 116, 2, 101, 101, 117, 3, 49, 58, 35, 34, 47, 10, 0, 119, 97, 114, 116, 101, 105, 110, 100, 8, 3, 49, 58, 35, 34, 47, 10, 123, 50, 47, 0, 119, 97, 114, 116, 101, 108, 3, 49, 58, 35, 34, 47, 13, 55, 10, 0, 119, 101, 108, 97, 3, 49, 58, 108, 12, 55, 35, 0, 119, 105, 107, 8, 2, 17, 65, 3, 49, 58, 109, 49, 10, 0, 101, 2, 110, 110, 17, 65, 25, 3, 49, 108, 0, 117, 114, 119, 101, 3, 49, 111, 34, 84, 13, 0, 101, 114, 1, 21, 2, 115, 105, 101, 32, 3, 49, 112, 34, 0, 101, 114, 107, 2, 32, 3, 49, 112, 34, 49, 0, 101, 114, 107, 101, 2, 32, 3, 49, 112, 34, 49, 13, 0, 101, 114, 107, 101, 114, 3, 49, 112, 34, 49, 13, 34, 0, 101, 114, 107, 105, 101, 2, 25, 3, 49, 112, 34, 49, 37, 0, 101, 108, 110, 101, 114, 3, 49, 112, 55, 50, 13, 34, 0, 4, 101, 114, 115, 1, 108, 101, 116, 116, 111, 98, 3, 49, 113, 34, 89, 0, 101, 114, 115, 1, 115, 101, 101, 102, 0, 101, 116, 101, 2, 108, 3, 49, 116, 47, 13, 0, 101, 105, 115, 101, 114, 3, 49, 123, 88, 13, 34, 0, 7, 6, 108, 0, 2, 108, 3, 0, 111, 107, 111, 109, 111, 3, 4, 55, 40, 49, 40, 65, 40, 6, 0, 4, 97, 110, 100, 8, 2, 32, 114, 111, 118, 101, 114, 3, 21, 0, 101, 1, 17, 67, 2, 32, 0, 101, 115, 115, 1, 21, 2, 32, 0, 108, 1, 21, 2, 32, 24, 0, 3, 55, 0, 4, 97, 2, 116, 101, 110, 116, 3, 55, 2, 35, 0, 97, 8, 2, 107, 111, 110, 0, 97, 116, 114, 105, 110, 101, 3, 55, 2, 35, 47, 34, 37, 50, 13, 0, 97, 112, 97, 114, 2, 111, 116, 111, 109, 105, 3, 55, 2, 35, 48, 2, 35, 34, 0, 97, 112, 101, 108, 2, 32, 3, 55, 2, 35, 48, 6, 112, 55, 0, 97, 112, 101, 2, 108, 25, 3, 55, 2, 35, 48, 112, 0, 97, 110, 8, 2, 115, 17, 65, 3, 55, 2, 35, 50, 0, 97, 110, 111, 2, 108, 105, 101, 110, 3, 55, 2, 35, 50, 2, 40, 0, 97, 110, 100, 101, 2, 114, 121, 3, 55, 2, 35, 50, 72, 13, 0, 97, 109, 2, 108, 101, 110, 3, 55, 2, 35, 65, 0, 97, 109, 112, 101, 2, 116, 3, 55, 2, 35, 65, 48, 108, 0, 4, 97, 110, 103, 2, 119, 101, 114, 112, 3, 55, 2, 35, 68, 0, 97, 110, 103, 8, 2, 100, 21, 21, 0, 97, 110, 107, 2, 109, 111, 101, 3, 55, 2, 35, 68, 49, 0, 97, 98, 105, 2, 114, 105, 110, 116, 3, 55, 2, 35, 71, 13, 0, 97, 98, 111, 114, 97, 116, 111, 114, 3, 55, 2, 35, 71, 14, 34, 2, 35, 47, 6, 117, 34, 0, 97, 118, 101, 110, 116, 101, 108, 3, 55, 2, 35, 83, 108, 50, 47, 13, 55, 0, 97, 103, 117, 110, 101, 3, 55, 2, 35, 136, 118, 50, 13, 0, 105, 2, 107, 119, 105, 100, 3, 55, 2, 37, 0, 4, 105, 116, 2, 111, 116, 111, 109, 105, 101, 3, 55, 2, 37, 47, 0, 105, 116, 8, 2, 111, 103, 114, 97, 102, 0, 105, 116, 111, 8, 2, 17, 67, 3, 55, 2, 37, 47, 2, 40, 0, 105, 110, 103, 117, 2, 105, 3, 55, 2, 37, 68, 81, 58, 0, 105, 101, 102, 2, 116, 97, 108, 108, 3, 55, 2, 37, 83, 0, 4, 111, 2, 106, 97, 3, 55, 2, 40, 0, 111, 2, 107, 97, 108, 17, 65, 0, 117, 112, 105, 110, 101, 3, 55, 2, 40, 48, 37, 50, 13, 0, 111, 98, 111, 116, 111, 2, 109, 105, 101, 3, 55, 2, 40, 71, 2, 110, 47, 2, 40, 0, 111, 115, 105, 101, 115, 8, 3, 55, 2, 40, 89, 6, 37, 89, 0, 117, 115, 101, 114, 110, 3, 55, 2, 40, 89, 113, 34, 13, 50, 0, 101, 103, 105, 2, 111, 101, 110, 3, 55, 2, 108, 136, 2, 37, 0, 111, 109, 2, 98, 97, 114, 100, 17, 65, 3, 55, 2, 110, 65, 0, 111, 98, 111, 108, 97, 3, 55, 2, 110, 71, 131, 55, 35, 0, 111, 115, 98, 97, 110, 100, 105, 2, 103, 3, 55, 2, 110, 89, 71, 35, 50, 72, 13, 0, 117, 2, 109, 105, 101, 114, 3, 55, 2, 111, 0, 117, 107, 115, 97, 2, 108, 105, 103, 3, 55, 2, 111, 49, 89, 6, 115, 0, 101, 100, 101, 2, 107, 97, 110, 116, 3, 55, 2, 116, 72, 13, 0, 101, 118, 105, 2, 97, 116, 97, 110, 3, 55, 2, 116, 84, 2, 37, 0, 111, 117, 2, 114, 105, 101, 114, 3, 55, 2, 120, 0, 4, 121, 107, 2, 109, 111, 101, 100, 3, 55, 2, 123, 49, 0, 121, 107, 2, 110, 97, 109, 0, 117, 105, 116, 101, 2, 110, 97, 110, 116, 3, 55, 2, 127, 47, 13, 0, 117, 105, 100, 2, 114, 117, 103, 116, 3, 55, 2, 127, 72, 0, 111, 115, 103, 101, 8, 2, 21, 14, 128, 132, 133, 3, 55, 6, 110, 89, 136, 13, 0, 117, 115, 116, 105, 1, 21, 2, 103, 3, 55, 6, 111, 89, 47, 13, 0, 101, 101, 114, 1, 105, 17, 67, 3, 55, 6, 116, 34, 0, 101, 114, 105, 110, 103, 2, 32, 3, 55, 6, 116, 34, 13, 68, 0, 117, 103, 8, 2, 17, 67, 3, 55, 7, 111, 136, 0, 4, 101, 1, 108, 2, 32, 3, 55, 13, 0, 101, 1, 108, 21, 2, 115, 17, 67, 21, 0, 105, 2, 107, 101, 117, 114, 0, 105, 2, 114, 105, 101, 107, 0, 105, 2, 116, 117, 114, 103, 105, 101, 0, 105, 8, 2, 109, 105, 0, 105, 116, 101, 114, 2, 17, 65, 3, 55, 13, 47, 13, 34, 0, 105, 116, 101, 114, 97, 2, 116, 3, 55, 13, 47, 13, 34, 2, 35, 0, 105, 107, 1, 10, 2, 32, 14, 128, 128, 131, 3, 55, 13, 49, 0, 4, 105, 107, 101, 1, 10, 2, 17, 67, 21, 3, 55, 13, 49, 13, 0, 105, 107, 101, 1, 10, 2, 32, 14, 128, 128, 132, 0, 105, 107, 107, 101, 2, 119, 97, 0, 105, 107, 101, 114, 1, 10, 2, 32, 14, 128, 128, 133, 3, 55, 13, 49, 13, 34, 0, 105, 107, 101, 115, 1, 10, 2, 32, 14, 128, 128, 133, 3, 55, 13, 49, 13, 89, 0, 105, 107, 115, 116, 101, 1, 10, 2, 32, 14, 128, 128, 134, 3, 55, 13, 49, 89, 47, 13, 0, 105, 110, 105, 2, 97, 97, 108, 3, 55, 13, 50, 2, 37, 0, 105, 110, 111, 2, 108, 101, 117, 109, 3, 55, 13, 50, 117, 0, 105, 109, 111, 117, 115, 105, 110, 101, 3, 55, 13, 65, 2, 40, 88, 37, 12, 50, 0, 105, 98, 101, 2, 114, 17, 65, 3, 55, 13, 71, 13, 0, 105, 98, 101, 8, 2, 114, 105, 21, 3, 55, 13, 71, 116, 0, 101, 118, 8, 2, 105, 3, 55, 13, 83, 0, 101, 119, 101, 114, 107, 1, 17, 65, 3, 55, 13, 84, 112, 34, 49, 0, 105, 115, 101, 110, 115, 105, 2, 101, 101, 114, 3, 55, 13, 89, 2, 108, 50, 89, 2, 37, 0, 105, 115, 101, 110, 115, 105, 101, 3, 55, 13, 89, 108, 12, 50, 89, 2, 37, 0, 105, 103, 2, 104, 111, 111, 102, 100, 3, 55, 13, 136, 0, 105, 103, 101, 110, 3, 55, 13, 136, 6, 108, 50, 0, 101, 103, 101, 110, 2, 100, 97, 3, 55, 13, 136, 13, 50, 0, 101, 103, 101, 110, 100, 101, 3, 55, 13, 136, 108, 50, 72, 13, 0, 105, 103, 103, 97, 97, 109, 108, 105, 107, 3, 55, 13, 136, 115, 65, 55, 13, 49, 0, 109, 1, 10, 2, 25, 3, 55, 14, 65, 0, 97, 110, 103, 101, 8, 2, 17, 67, 17, 65, 3, 55, 35, 68, 13, 0, 97, 102, 2, 97, 97, 114, 3, 55, 35, 83, 0, 4, 105, 2, 103, 97, 32, 3, 55, 37, 0, 105, 8, 2, 103, 97, 17, 67, 0, 105, 101, 102, 100, 101, 115, 3, 55, 37, 83, 72, 13, 89, 0, 101, 110, 100, 101, 8, 3, 55, 108, 50, 72, 13, 0, 4, 101, 115, 1, 17, 67, 21, 2, 25, 3, 55, 108, 89, 0, 101, 115, 1, 101, 105, 2, 32, 0, 101, 115, 115, 101, 1, 17, 67, 21, 2, 32, 3, 55, 108, 89, 13, 0, 105, 8, 2, 103, 3, 55, 109, 0, 105, 110, 107, 101, 114, 3, 55, 109, 68, 49, 13, 34, 0, 117, 115, 2, 111, 3, 55, 111, 89, 10, 0, 117, 103, 2, 17, 65, 3, 55, 111, 136, 19, 0, 101, 2, 107, 107, 101, 114, 3, 55, 112, 0, 97, 112, 97, 8, 2, 25, 3, 55, 115, 48, 35, 0, 101, 112, 101, 2, 108, 108, 3, 55, 116, 48, 13, 0, 101, 110, 105, 110, 103, 3, 55, 116, 50, 13, 68, 0, 101, 108, 105, 2, 107, 3, 55, 116, 55, 13, 0, 4, 101, 100, 101, 1, 10, 2, 32, 14, 128, 128, 132, 3, 55, 116, 72, 13, 0, 101, 100, 101, 1, 114, 101, 118, 2, 25, 0, 101, 100, 101, 2, 17, 67, 0, 101, 100, 105, 110, 103, 2, 32, 3, 55, 116, 72, 13, 68, 0, 101, 119, 101, 2, 25, 3, 55, 116, 84, 13, 0, 101, 119, 101, 2, 116, 106, 105, 101, 3, 55, 116, 84, 37, 0, 111, 114, 101, 8, 2, 17, 67, 21, 3, 55, 117, 34, 13, 0, 117, 2, 107, 119, 97, 114, 116, 3, 55, 118, 0, 117, 116, 104, 101, 114, 3, 55, 118, 47, 13, 34, 0, 101, 117, 101, 110, 2, 116, 106, 105, 101, 3, 55, 128, 37, 68, 0, 4, 97, 109, 102, 101, 114, 3, 55, 133, 65, 83, 13, 34, 0, 97, 110, 102, 101, 114, 0, 7, 6, 109, 0, 2, 109, 3, 0, 110, 1, 21, 2, 32, 3, 21, 0, 3, 65, 0, 117, 115, 105, 101, 107, 3, 65, 2, 111, 89, 37, 49, 0, 117, 115, 107, 97, 100, 101, 108, 3, 65, 2, 111, 89, 49, 2, 35, 72, 112, 55, 0, 117, 115, 107, 101, 2, 116, 105, 101, 114, 3, 65, 2, 111, 89, 49, 13, 0, 117, 115, 107, 101, 108, 2, 106, 97, 97, 116, 3, 65, 2, 111, 89, 49, 13, 55, 0, 117, 115, 101, 117, 109, 3, 65, 2, 118, 89, 128, 65, 0, 109, 101, 1, 17, 65, 17, 67, 2, 17, 67, 3, 65, 13, 0, 109, 101, 1, 17, 65, 17, 67, 2, 116, 106, 105, 101, 3, 65, 37, 0, 112, 101, 108, 1, 21, 2, 17, 65, 3, 65, 48, 13, 55, 0, 117, 114, 109, 101, 108, 3, 65, 111, 34, 65, 13, 55, 0, 117, 115, 105, 2, 17, 67, 3, 65, 118, 89, 37, 6, 0, 121, 109, 101, 114, 3, 65, 123, 65, 13, 34, 0, 195, 180, 114, 101, 2, 21, 3, 65, 131, 34, 13, 0, 7, 6, 110, 0, 4, 2, 32, 110, 3, 0, 2, 110, 3, 0, 97, 2, 116, 97, 108, 3, 4, 50, 35, 6, 0, 4, 3, 50, 0, 1, 10, 2, 103, 97, 116, 0, 1, 97, 97, 2, 103, 97, 115, 0, 1, 101, 2, 103, 111, 101, 17, 67, 0, 1, 101, 101, 2, 103, 0, 1, 101, 111, 2, 103, 0, 1, 101, 119, 2, 103, 21, 12, 12, 0, 1, 105, 101, 2, 103, 0, 1, 105, 112, 115, 2, 103, 101, 0, 1, 105, 117, 17, 67, 2, 103, 0, 1, 111, 111, 2, 103, 0, 1, 117, 101, 2, 103, 0, 1, 121, 2, 103, 0, 1, 171, 195, 2, 103, 0, 2, 32, 110, 32, 0, 8, 2, 17, 65, 17, 65, 0, 4, 97, 1, 21, 2, 108, 105, 115, 3, 50, 2, 35, 0, 97, 2, 116, 117, 117, 114, 0, 97, 2, 118, 114, 97, 110, 116, 0, 97, 8, 2, 114, 107, 0, 97, 2, 195, 175, 3, 50, 2, 35, 10, 0, 97, 2, 195, 175, 3, 50, 2, 35, 19, 0, 97, 114, 101, 115, 2, 32, 3, 50, 2, 35, 34, 6, 108, 89, 0, 97, 116, 117, 114, 101, 2, 108, 25, 3, 50, 2, 35, 47, 2, 118, 34, 112, 0, 97, 112, 111, 108, 101, 2, 111, 110, 116, 3, 50, 2, 35, 48, 2, 117, 55, 2, 37, 0, 97, 112, 111, 2, 108, 101, 111, 110, 3, 50, 2, 35, 48, 117, 0, 97, 109, 97, 107, 119, 97, 3, 50, 2, 35, 65, 35, 49, 58, 2, 35, 0, 97, 109, 105, 2, 98, 105, 3, 50, 2, 35, 65, 109, 0, 97, 118, 105, 103, 3, 50, 2, 35, 84, 2, 37, 136, 0, 97, 115, 105, 111, 2, 110, 97, 3, 50, 2, 35, 91, 2, 37, 2, 40, 0, 101, 2, 97, 110, 100, 101, 114, 17, 67, 97, 3, 50, 2, 37, 0, 101, 111, 2, 108, 105, 3, 50, 2, 37, 2, 40, 0, 4, 105, 107, 111, 2, 116, 105, 3, 50, 2, 37, 49, 2, 40, 0, 105, 107, 111, 2, 116, 105, 101, 110, 0, 111, 116, 2, 101, 114, 105, 110, 103, 3, 50, 2, 40, 47, 0, 111, 116, 117, 108, 101, 2, 25, 3, 50, 2, 40, 47, 118, 55, 13, 0, 111, 118, 101, 108, 108, 101, 3, 50, 2, 40, 83, 112, 55, 13, 0, 101, 107, 116, 97, 2, 114, 105, 101, 110, 3, 50, 2, 108, 49, 47, 2, 35, 0, 111, 2, 115, 116, 97, 108, 103, 105, 101, 3, 50, 2, 110, 0, 111, 114, 2, 109, 97, 21, 3, 50, 2, 110, 34, 0, 111, 107, 116, 117, 114, 110, 101, 3, 50, 2, 110, 49, 47, 111, 34, 50, 13, 0, 111, 110, 99, 104, 97, 2, 108, 97, 3, 50, 2, 110, 50, 91, 2, 35, 0, 111, 109, 105, 2, 110, 17, 65, 3, 50, 2, 110, 65, 2, 37, 0, 111, 109, 109, 101, 114, 2, 101, 101, 110, 3, 50, 2, 110, 65, 13, 34, 19, 0, 111, 115, 116, 97, 108, 2, 103, 105, 101, 32, 24, 3, 50, 2, 110, 89, 47, 2, 35, 55, 0, 101, 114, 2, 118, 101, 117, 3, 50, 2, 112, 34, 0, 4, 97, 2, 98, 117, 114, 105, 103, 3, 50, 2, 115, 0, 97, 2, 98, 121, 103, 101, 0, 97, 8, 2, 98, 121, 21, 0, 97, 8, 2, 100, 101, 108, 105, 103, 0, 97, 8, 2, 108, 97, 116, 105, 103, 0, 97, 8, 2, 115, 112, 101, 117, 114, 0, 97, 2, 121, 119, 101, 114, 105, 103, 3, 50, 2, 115, 10, 0, 97, 97, 114, 115, 116, 105, 103, 116, 101, 3, 50, 2, 115, 34, 89, 47, 109, 136, 47, 13, 0, 97, 98, 121, 104, 2, 101, 3, 50, 2, 115, 71, 123, 107, 0, 4, 101, 101, 114, 2, 100, 114, 117, 107, 107, 3, 50, 2, 116, 34, 0, 101, 101, 114, 2, 104, 97, 108, 101, 110, 100, 0, 101, 103, 101, 114, 2, 105, 110, 3, 50, 2, 116, 136, 13, 34, 0, 111, 2, 109, 97, 100, 3, 50, 2, 117, 0, 111, 111, 114, 100, 2, 111, 111, 115, 3, 50, 2, 117, 34, 47, 10, 0, 4, 111, 111, 100, 2, 108, 111, 116, 116, 105, 3, 50, 2, 117, 47, 0, 111, 111, 100, 2, 115, 97, 97, 107, 0, 111, 116, 97, 114, 105, 2, 17, 65, 3, 50, 2, 117, 47, 2, 35, 34, 2, 37, 38, 0, 111, 98, 101, 108, 8, 3, 50, 2, 117, 71, 112, 55, 0, 111, 118, 101, 109, 98, 101, 114, 3, 50, 2, 117, 83, 108, 65, 71, 13, 34, 0, 117, 97, 110, 2, 115, 101, 101, 114, 3, 50, 2, 118, 2, 35, 50, 0, 117, 97, 110, 115, 101, 2, 114, 105, 110, 103, 3, 50, 2, 118, 2, 35, 50, 89, 116, 0, 117, 97, 110, 115, 101, 2, 25, 3, 50, 2, 118, 35, 50, 89, 13, 0, 117, 119, 101, 114, 2, 119, 101, 116, 3, 50, 2, 118, 84, 13, 34, 0, 117, 117, 115, 2, 107, 105, 101, 114, 105, 103, 3, 50, 2, 118, 89, 0, 101, 117, 2, 116, 114, 3, 50, 2, 128, 0, 101, 117, 114, 111, 2, 17, 67, 17, 65, 3, 50, 2, 128, 34, 117, 0, 97, 8, 2, 17, 67, 32, 3, 50, 6, 35, 0, 97, 103, 8, 2, 17, 67, 3, 50, 6, 35, 136, 0, 97, 8, 3, 50, 6, 115, 0, 97, 103, 8, 2, 114, 97, 97, 100, 3, 50, 6, 115, 136, 0, 97, 103, 101, 8, 2, 21, 14, 128, 132, 132, 3, 50, 6, 115, 136, 13, 0, 101, 108, 101, 1, 10, 2, 32, 3, 50, 6, 116, 55, 13, 0, 101, 101, 115, 1, 21, 2, 32, 3, 50, 6, 116, 89, 0, 101, 115, 101, 2, 32, 3, 50, 6, 116, 89, 13, 0, 4, 121, 1, 114, 101, 17, 67, 21, 2, 32, 3, 50, 6, 123, 0, 121, 1, 114, 101, 17, 67, 21, 2, 101, 0, 97, 8, 2, 115, 107, 101, 101, 114, 3, 50, 7, 115, 0, 101, 101, 114, 103, 101, 8, 2, 17, 67, 21, 14, 128, 132, 134, 3, 50, 7, 116, 34, 136, 13, 0, 101, 2, 103, 111, 115, 105, 101, 3, 50, 13, 0, 110, 105, 110, 103, 3, 50, 13, 68, 0, 110, 101, 115, 1, 97, 104, 3, 50, 13, 89, 0, 4, 97, 1, 21, 2, 32, 3, 50, 35, 0, 97, 8, 2, 114, 17, 67, 0, 97, 8, 2, 116, 17, 67, 0, 97, 115, 116, 101, 114, 2, 103, 3, 50, 35, 89, 47, 13, 34, 0, 4, 97, 103, 2, 97, 100, 100, 101, 114, 3, 50, 35, 136, 10, 0, 97, 103, 2, 117, 105, 108, 0, 97, 103, 8, 2, 97, 97, 112, 0, 97, 103, 8, 2, 97, 112, 17, 65, 0, 105, 116, 114, 111, 3, 50, 37, 47, 34, 2, 40, 0, 116, 101, 114, 101, 2, 115, 115, 3, 50, 47, 34, 13, 6, 0, 101, 116, 2, 119, 101, 114, 107, 3, 50, 108, 47, 0, 101, 116, 116, 111, 8, 3, 50, 108, 47, 2, 40, 0, 4, 101, 116, 2, 97, 103, 116, 105, 103, 3, 50, 108, 47, 10, 0, 101, 116, 8, 2, 111, 0, 4, 101, 115, 1, 17, 67, 21, 2, 32, 3, 50, 108, 89, 0, 101, 115, 1, 101, 121, 98, 0, 101, 115, 1, 115, 2, 25, 0, 101, 115, 1, 121, 98, 0, 101, 115, 8, 2, 101, 105, 3, 50, 108, 89, 10, 0, 105, 2, 103, 103, 105, 101, 3, 50, 109, 0, 111, 103, 97, 108, 3, 50, 110, 136, 35, 55, 0, 101, 107, 2, 111, 109, 3, 50, 112, 49, 10, 0, 4, 97, 1, 114, 2, 32, 3, 50, 115, 0, 97, 2, 98, 111, 111, 116, 115, 0, 97, 2, 116, 114, 105, 117, 109, 0, 97, 2, 116, 114, 111, 115, 25, 0, 97, 2, 118, 114, 97, 0, 97, 8, 2, 103, 108, 111, 101, 0, 97, 8, 2, 115, 112, 101, 117, 114, 32, 24, 0, 97, 8, 2, 116, 114, 101, 107, 25, 0, 97, 1, 10, 2, 119, 101, 3, 50, 115, 2, 0, 97, 122, 105, 3, 50, 115, 47, 89, 37, 0, 97, 109, 101, 115, 3, 50, 115, 65, 13, 89, 0, 97, 100, 114, 117, 107, 108, 105, 107, 3, 50, 115, 72, 34, 6, 111, 49, 55, 13, 49, 0, 101, 116, 101, 108, 3, 50, 116, 47, 13, 55, 0, 111, 111, 100, 2, 115, 97, 97, 107, 32, 24, 3, 50, 117, 47, 0, 111, 116, 101, 2, 98, 3, 50, 117, 47, 13, 0, 121, 108, 111, 110, 3, 50, 122, 55, 110, 50, 0, 101, 117, 116, 101, 3, 50, 128, 47, 13, 0, 103, 101, 101, 115, 3, 50, 136, 116, 89, 0, 4, 2, 32, 103, 3, 68, 0, 2, 99, 0, 2, 107, 0, 2, 113, 0, 2, 116, 106, 105, 101, 0, 2, 120, 0, 103, 0, 103, 101, 114, 1, 17, 65, 17, 67, 3, 68, 13, 34, 0, 103, 101, 115, 1, 21, 2, 32, 3, 68, 13, 89, 0, 103, 117, 110, 105, 8, 3, 68, 81, 40, 12, 50, 37, 0, 4, 103, 1, 21, 2, 105, 116, 105, 115, 32, 3, 68, 136, 0, 103, 2, 101, 101, 82, 0, 103, 2, 101, 110, 116, 0, 7, 6, 111, 0, 4, 1, 17, 67, 2, 17, 67, 17, 65, 17, 65, 3, 2, 40, 0, 1, 17, 67, 2, 17, 67, 121, 0, 1, 17, 67, 10, 2, 32, 24, 0, 1, 107, 105, 115, 105, 114, 0, 2, 108, 105, 101, 110, 0, 97, 115, 101, 3, 2, 40, 10, 115, 89, 13, 0, 8, 105, 100, 117, 17, 65, 3, 2, 40, 12, 0, 114, 97, 110, 103, 2, 111, 101, 116, 3, 2, 40, 34, 2, 35, 68, 10, 0, 107, 114, 97, 116, 2, 105, 115, 17, 65, 3, 2, 40, 49, 34, 2, 35, 47, 0, 4, 2, 114, 97, 107, 101, 108, 3, 2, 110, 0, 2, 115, 111, 111, 110, 0, 8, 2, 109, 97, 114, 109, 0, 4, 114, 8, 2, 103, 97, 3, 2, 110, 34, 0, 114, 8, 2, 107, 97, 0, 4, 114, 116, 2, 111, 103, 114, 97, 3, 2, 110, 34, 47, 0, 114, 116, 2, 111, 108, 111, 0, 114, 116, 2, 111, 109, 101, 116, 114, 0, 114, 116, 2, 111, 115, 107, 111, 0, 114, 116, 111, 8, 2, 21, 3, 2, 110, 34, 47, 2, 40, 0, 114, 107, 101, 115, 3, 2, 110, 34, 49, 108, 89, 0, 114, 100, 111, 2, 110, 110, 97, 110, 3, 2, 110, 34, 72, 13, 0, 114, 100, 101, 110, 116, 8, 3, 2, 110, 34, 72, 108, 50, 47, 0, 114, 103, 97, 110, 105, 2, 115, 17, 65, 3, 2, 110, 34, 136, 2, 35, 50, 37, 0, 114, 103, 105, 2, 100, 101, 3, 2, 110, 34, 136, 13, 0, 98, 8, 2, 115, 3, 2, 110, 48, 0, 98, 115, 101, 114, 2, 118, 101, 101, 114, 3, 2, 110, 48, 89, 2, 112, 34, 0, 98, 115, 116, 105, 2, 110, 97, 3, 2, 110, 48, 89, 47, 13, 0, 107, 8, 2, 116, 17, 65, 3, 2, 110, 49, 0, 107, 107, 101, 114, 2, 110, 101, 117, 116, 3, 2, 110, 49, 13, 34, 0, 4, 109, 2, 108, 121, 3, 2, 110, 65, 0, 109, 2, 114, 105, 110, 103, 0, 109, 2, 115, 101, 105, 108, 0, 109, 2, 115, 105, 103, 0, 109, 2, 115, 119, 101, 114, 17, 67, 0, 109, 2, 118, 97, 116, 116, 0, 109, 2, 119, 101, 110, 116, 101, 108, 105, 0, 109, 8, 2, 103, 111, 114, 100, 0, 109, 8, 2, 104, 0, 109, 8, 2, 107, 108, 101, 109, 0, 109, 8, 2, 108, 97, 97, 103, 0, 109, 8, 2, 109, 117, 117, 114, 0, 109, 8, 2, 114, 97, 97, 109, 0, 109, 8, 2, 115, 105, 114, 107, 101, 108, 0, 109, 8, 2, 115, 107, 101, 112, 0, 109, 8, 2, 115, 107, 114, 0, 109, 8, 2, 115, 108, 117, 105, 101, 114, 0, 109, 8, 2, 115, 108, 117, 105, 116, 0, 109, 8, 2, 115, 116, 114, 101, 100, 101, 0, 109, 8, 2, 119, 97, 108, 0, 109, 8, 2, 119, 101, 108, 17, 67, 0, 109, 101, 108, 101, 2, 116, 3, 2, 110, 65, 13, 55, 108, 0, 109, 108, 105, 8, 2, 103, 103, 3, 2, 110, 65, 55, 109, 0, 109, 118, 101, 114, 8, 3, 2, 110, 65, 83, 112, 34, 0, 109, 115, 116, 97, 110, 100, 105, 103, 104, 3, 2, 110, 65, 89, 47, 35, 50, 72, 13, 136, 0, 109, 115, 107, 97, 110, 115, 8, 3, 2, 110, 65, 89, 49, 35, 50, 89, 0, 109, 115, 105, 110, 103, 101, 108, 3, 2, 110, 65, 89, 109, 68, 13, 55, 0, 109, 103, 101, 119, 105, 110, 103, 3, 2, 110, 65, 136, 116, 84, 13, 68, 0, 102, 102, 105, 115, 105, 3, 2, 110, 83, 2, 37, 91, 2, 37, 38, 0, 102, 102, 105, 2, 115, 105, 101, 114, 3, 2, 110, 83, 13, 0, 118, 117, 3, 2, 110, 84, 2, 118, 0, 115, 8, 2, 109, 111, 17, 67, 3, 2, 110, 89, 0, 115, 115, 105, 108, 108, 2, 101, 3, 2, 110, 89, 13, 55, 0, 115, 115, 105, 108, 108, 101, 2, 17, 67, 17, 65, 3, 2, 110, 89, 13, 55, 116, 0, 4, 1, 17, 67, 2, 17, 67, 105, 101, 101, 3, 2, 117, 0, 2, 108, 105, 109, 0, 2, 108, 121, 17, 67, 0, 2, 112, 97, 97, 108, 0, 2, 112, 97, 108, 101, 0, 8, 2, 118, 97, 21, 0, 114, 105, 195, 171, 110, 116, 2, 21, 3, 2, 117, 34, 2, 37, 57, 2, 108, 50, 47, 0, 114, 97, 110, 106, 101, 3, 2, 117, 34, 35, 50, 57, 13, 0, 114, 101, 110, 116, 2, 25, 3, 2, 117, 34, 108, 50, 47, 0, 116, 111, 109, 105, 101, 1, 21, 2, 32, 24, 3, 2, 117, 47, 2, 40, 65, 6, 37, 0, 116, 111, 109, 105, 101, 1, 21, 2, 195, 171, 3, 2, 117, 47, 2, 40, 65, 6, 37, 12, 0, 107, 97, 112, 105, 3, 2, 117, 49, 115, 48, 2, 37, 0, 108, 101, 2, 97, 110, 100, 101, 114, 3, 2, 117, 55, 2, 37, 0, 108, 121, 109, 2, 112, 3, 2, 117, 55, 109, 65, 0, 109, 105, 8, 2, 115, 115, 105, 101, 3, 2, 117, 65, 37, 0, 109, 101, 103, 97, 3, 2, 117, 65, 116, 136, 35, 0, 118, 97, 114, 105, 2, 111, 116, 111, 109, 105, 3, 2, 117, 84, 2, 115, 34, 2, 37, 0, 119, 101, 114, 2, 115, 112, 101, 108, 105, 103, 3, 2, 117, 84, 13, 34, 0, 115, 101, 2, 97, 3, 2, 117, 91, 2, 37, 0, 117, 116, 2, 111, 107, 114, 97, 3, 2, 120, 47, 0, 117, 100, 101, 114, 2, 119, 101, 116, 3, 2, 120, 72, 13, 34, 0, 1, 114, 117, 98, 2, 32, 3, 4, 117, 0, 117, 120, 3, 6, 40, 0, 109, 103, 101, 8, 2, 21, 14, 128, 132, 132, 3, 6, 110, 65, 136, 13, 0, 109, 103, 101, 101, 2, 12, 3, 6, 110, 65, 136, 116, 0, 1, 98, 114, 2, 32, 3, 6, 117, 0, 114, 105, 117, 3, 6, 117, 34, 37, 111, 0, 116, 105, 101, 115, 1, 21, 3, 6, 117, 47, 37, 89, 0, 103, 105, 103, 1, 17, 67, 3, 10, 117, 136, 13, 136, 0, 4, 39, 8, 2, 17, 67, 3, 21, 0, 121, 1, 17, 67, 0, 105, 114, 1, 25, 2, 32, 3, 21, 102, 114, 0, 4, 1, 114, 107, 105, 109, 3, 40, 0, 2, 116, 101, 114, 97, 112, 0, 101, 0, 101, 1, 104, 2, 114, 0, 101, 1, 107, 2, 114, 0, 101, 1, 116, 2, 114, 17, 65, 0, 101, 1, 119, 2, 114, 0, 101, 8, 2, 114, 0, 1, 108, 105, 102, 2, 21, 3, 40, 2, 0, 4, 101, 2, 114, 3, 40, 12, 0, 101, 2, 195, 171, 0, 195, 171, 3, 40, 12, 13, 0, 101, 116, 101, 108, 1, 17, 67, 3, 40, 47, 13, 55, 0, 116, 114, 111, 111, 112, 3, 40, 47, 34, 6, 117, 48, 0, 116, 114, 111, 112, 101, 3, 40, 47, 34, 6, 117, 48, 13, 0, 116, 114, 111, 112, 105, 101, 115, 3, 40, 47, 34, 6, 117, 48, 37, 89, 0, 116, 114, 111, 112, 105, 101, 3, 40, 47, 34, 40, 48, 6, 37, 0, 101, 107, 101, 1, 116, 2, 110, 3, 40, 49, 2, 108, 0, 4, 107, 114, 97, 97, 116, 3, 40, 49, 34, 6, 115, 47, 0, 107, 114, 97, 116, 2, 17, 65, 0, 107, 114, 97, 115, 105, 101, 3, 40, 49, 34, 35, 89, 6, 37, 0, 4, 108, 105, 101, 107, 1, 25, 3, 40, 55, 6, 37, 49, 0, 108, 105, 101, 107, 2, 101, 32, 0, 108, 105, 101, 107, 105, 103, 3, 40, 55, 6, 37, 49, 13, 136, 0, 108, 111, 195, 171, 3, 40, 55, 6, 40, 13, 0, 108, 111, 111, 103, 3, 40, 55, 6, 117, 136, 0, 108, 111, 103, 105, 101, 115, 3, 40, 55, 6, 117, 136, 37, 89, 0, 108, 111, 103, 105, 101, 3, 40, 55, 40, 136, 6, 37, 0, 108, 111, 103, 105, 101, 2, 115, 116, 3, 40, 55, 40, 136, 7, 37, 0, 109, 101, 116, 114, 105, 101, 115, 3, 40, 65, 6, 116, 47, 34, 37, 89, 0, 109, 101, 116, 114, 105, 101, 3, 40, 65, 116, 47, 34, 6, 37, 0, 100, 105, 101, 107, 3, 40, 72, 6, 37, 49, 0, 102, 105, 101, 108, 3, 40, 83, 6, 37, 55, 0, 102, 111, 111, 110, 3, 40, 83, 6, 117, 50, 0, 102, 111, 110, 101, 3, 40, 83, 6, 117, 50, 13, 0, 102, 111, 98, 105, 101, 115, 3, 40, 83, 6, 117, 71, 37, 89, 0, 101, 102, 101, 110, 3, 40, 83, 13, 50, 0, 102, 105, 108, 105, 101, 3, 40, 83, 37, 55, 6, 37, 0, 102, 111, 98, 105, 101, 3, 40, 83, 117, 71, 6, 37, 0, 101, 119, 101, 114, 8, 3, 40, 84, 13, 34, 0, 115, 111, 111, 102, 3, 40, 89, 6, 117, 83, 0, 115, 111, 102, 105, 101, 115, 3, 40, 89, 6, 117, 83, 37, 89, 0, 115, 111, 119, 101, 3, 40, 89, 6, 117, 84, 13, 0, 115, 111, 102, 105, 101, 3, 40, 89, 40, 83, 6, 37, 0, 115, 107, 111, 111, 112, 3, 40, 89, 49, 6, 117, 48, 0, 115, 107, 111, 112, 101, 3, 40, 89, 49, 6, 117, 48, 13, 0, 115, 107, 111, 112, 105, 101, 115, 3, 40, 89, 49, 6, 117, 48, 37, 89, 0, 103, 114, 97, 97, 102, 3, 40, 136, 34, 6, 115, 83, 0, 103, 114, 97, 102, 105, 101, 115, 3, 40, 136, 34, 6, 115, 83, 37, 89, 0, 103, 114, 97, 119, 101, 3, 40, 136, 34, 6, 115, 84, 13, 0, 103, 114, 97, 102, 105, 101, 3, 40, 136, 34, 35, 83, 6, 37, 0, 4, 1, 119, 2, 114, 115, 116, 101, 108, 3, 110, 0, 2, 17, 67, 0, 114, 100, 101, 8, 3, 110, 34, 72, 13, 0, 107, 107, 101, 108, 1, 17, 67, 3, 110, 49, 13, 55, 0, 4, 109, 2, 104, 97, 3, 110, 65, 0, 109, 8, 2, 107, 114, 105, 110, 103, 14, 128, 132, 130, 0, 109, 1, 98, 2, 111, 3, 110, 65, 10, 0, 4, 109, 107, 101, 101, 114, 3, 110, 65, 49, 116, 34, 0, 109, 107, 101, 114, 8, 2, 17, 65, 0, 109, 103, 101, 119, 101, 2, 32, 3, 110, 65, 136, 6, 116, 84, 13, 0, 115, 115, 101, 119, 97, 2, 17, 67, 3, 110, 89, 13, 84, 115, 0, 103, 103, 101, 110, 100, 2, 21, 3, 110, 136, 13, 50, 47, 10, 0, 103, 103, 101, 110, 100, 101, 2, 32, 3, 110, 136, 13, 50, 72, 13, 0, 4, 3, 117, 0, 1, 17, 67, 2, 17, 67, 105, 101, 0, 1, 17, 67, 2, 100, 105, 117, 109, 0, 1, 17, 67, 2, 108, 105, 97, 0, 1, 98, 2, 17, 67, 17, 65, 17, 65, 0, 1, 98, 2, 108, 121, 17, 67, 0, 1, 115, 10, 2, 32, 0, 2, 17, 67, 17, 65, 0, 114, 105, 101, 3, 117, 34, 37, 0, 107, 101, 114, 8, 3, 117, 49, 13, 34, 0, 119, 101, 114, 2, 21, 3, 117, 84, 13, 34, 0, 4, 117, 3, 120, 0, 117, 119, 2, 25, 0, 117, 116, 111, 8, 2, 21, 14, 128, 132, 132, 3, 120, 47, 40, 0, 4, 105, 3, 124, 0, 121, 0, 4, 100, 106, 105, 101, 3, 124, 80, 37, 0, 116, 106, 105, 101, 0, 101, 105, 3, 126, 0, 101, 110, 116, 106, 105, 101, 3, 126, 68, 80, 37, 0, 4, 101, 100, 106, 105, 101, 3, 126, 80, 37, 0, 101, 116, 106, 105, 101, 0, 4, 1, 114, 103, 2, 110, 100, 3, 131, 0, 1, 119, 2, 114, 115, 0, 7, 6, 112, 0, 2, 112, 3, 0, 111, 114, 8, 2, 17, 67, 3, 2, 48, 110, 34, 0, 111, 112, 117, 3, 4, 48, 110, 48, 118, 0, 3, 48, 0, 4, 105, 2, 107, 97, 110, 116, 3, 48, 2, 37, 0, 105, 8, 2, 108, 97, 0, 105, 111, 2, 110, 105, 101, 114, 3, 48, 2, 37, 2, 40, 0, 105, 114, 97, 2, 109, 105, 3, 48, 2, 37, 34, 2, 35, 0, 105, 101, 116, 101, 114, 8, 2, 115, 17, 65, 21, 3, 48, 2, 37, 47, 13, 34, 0, 105, 111, 2, 110, 3, 48, 2, 37, 57, 110, 0, 4, 111, 2, 108, 101, 109, 105, 101, 3, 48, 2, 40, 0, 111, 2, 108, 105, 101, 112, 0, 111, 195, 171, 115, 105, 101, 3, 48, 2, 40, 12, 13, 88, 37, 0, 111, 195, 171, 2, 116, 17, 65, 3, 48, 2, 40, 12, 116, 0, 111, 116, 101, 110, 8, 2, 17, 67, 3, 48, 2, 40, 47, 108, 50, 0, 111, 108, 105, 115, 105, 2, 101, 101, 114, 3, 48, 2, 40, 55, 2, 37, 89, 2, 37, 0, 111, 108, 105, 115, 105, 195, 171, 3, 48, 2, 40, 55, 2, 37, 89, 2, 37, 116, 0, 111, 108, 105, 116, 105, 101, 115, 3, 48, 2, 40, 55, 37, 47, 2, 37, 89, 0, 111, 108, 105, 115, 105, 101, 3, 48, 2, 40, 55, 37, 89, 2, 37, 0, 111, 109, 101, 108, 111, 3, 48, 2, 40, 65, 116, 55, 2, 40, 0, 111, 115, 105, 115, 105, 101, 3, 48, 2, 40, 88, 37, 89, 2, 37, 0, 111, 114, 116, 117, 2, 103, 101, 3, 48, 2, 110, 34, 47, 2, 118, 0, 112, 111, 114, 116, 101, 1, 97, 114, 2, 114, 17, 65, 3, 48, 2, 110, 34, 47, 116, 0, 111, 114, 115, 101, 2, 108, 101, 105, 110, 3, 48, 2, 110, 34, 89, 13, 0, 111, 116, 2, 115, 105, 101, 114, 3, 48, 2, 110, 47, 0, 111, 110, 8, 2, 100, 111, 107, 3, 48, 2, 110, 50, 0, 4, 111, 108, 2, 102, 121, 110, 3, 48, 2, 110, 55, 0, 111, 108, 2, 118, 121, 0, 111, 108, 105, 195, 171, 115, 116, 101, 2, 114, 3, 48, 2, 110, 55, 2, 37, 38, 108, 89, 47, 13, 0, 4, 111, 108, 101, 2, 109, 105, 101, 107, 3, 48, 2, 110, 55, 13, 0, 111, 108, 105, 2, 116, 17, 65, 17, 65, 17, 67, 0, 111, 115, 116, 8, 2, 117, 3, 48, 2, 110, 89, 47, 0, 117, 110, 116, 101, 110, 101, 114, 3, 48, 2, 111, 50, 47, 13, 50, 116, 34, 0, 117, 98, 2, 108, 105, 3, 48, 2, 111, 71, 0, 111, 114, 2, 105, 101, 3, 48, 2, 117, 34, 0, 111, 114, 105, 2, 101, 117, 115, 3, 48, 2, 117, 34, 2, 37, 0, 111, 116, 101, 110, 2, 115, 105, 97, 3, 48, 2, 117, 47, 2, 108, 50, 0, 111, 108, 105, 8, 2, 17, 67, 3, 48, 2, 117, 55, 2, 37, 0, 117, 2, 112, 105, 108, 3, 48, 2, 118, 0, 117, 114, 105, 2, 116, 101, 105, 110, 3, 48, 2, 118, 34, 13, 0, 111, 115, 116, 8, 2, 25, 3, 48, 6, 120, 89, 47, 20, 0, 111, 115, 2, 97, 100, 118, 101, 114, 116, 3, 48, 7, 110, 89, 10, 0, 111, 108, 105, 115, 8, 2, 25, 3, 48, 7, 117, 55, 13, 89, 0, 105, 2, 115, 116, 111, 3, 48, 13, 0, 105, 107, 107, 101, 2, 119, 121, 110, 3, 48, 13, 49, 13, 0, 115, 97, 108, 109, 105, 115, 3, 48, 13, 89, 2, 35, 55, 13, 65, 109, 89, 0, 115, 97, 108, 109, 8, 3, 48, 13, 89, 35, 55, 13, 65, 0, 105, 103, 2, 109, 101, 17, 65, 3, 48, 13, 136, 0, 105, 122, 122, 97, 3, 48, 37, 47, 89, 35, 0, 111, 2, 108, 105, 101, 115, 109, 97, 110, 3, 48, 40, 0, 4, 108, 97, 2, 102, 111, 110, 3, 48, 55, 2, 35, 0, 108, 97, 2, 115, 116, 105, 101, 107, 0, 108, 97, 8, 2, 107, 107, 97, 0, 108, 97, 8, 2, 116, 97, 0, 108, 97, 110, 101, 2, 116, 17, 65, 3, 48, 55, 2, 35, 50, 13, 6, 0, 108, 97, 110, 116, 2, 97, 97, 114, 100, 105, 3, 48, 55, 2, 35, 50, 47, 10, 0, 108, 97, 110, 101, 116, 101, 3, 48, 55, 2, 35, 50, 116, 47, 13, 0, 108, 97, 103, 105, 2, 97, 3, 48, 55, 2, 35, 136, 2, 37, 0, 108, 101, 105, 2, 100, 111, 111, 105, 3, 48, 55, 2, 123, 0, 108, 105, 103, 116, 105, 103, 1, 21, 3, 48, 55, 6, 109, 136, 47, 13, 136, 0, 108, 101, 115, 105, 101, 114, 3, 48, 55, 13, 89, 6, 37, 12, 34, 0, 108, 105, 103, 3, 48, 55, 109, 136, 0, 108, 101, 2, 107, 3, 48, 55, 112, 0, 108, 97, 116, 105, 110, 117, 109, 2, 17, 65, 3, 48, 55, 115, 47, 37, 50, 111, 65, 10, 0, 115, 105, 103, 101, 8, 101, 105, 110, 3, 48, 89, 13, 136, 13, 0, 4, 111, 114, 2, 115, 105, 101, 3, 48, 110, 34, 0, 111, 114, 2, 115, 116, 111, 107, 0, 111, 116, 2, 121, 115, 116, 101, 114, 3, 48, 110, 47, 10, 0, 111, 102, 2, 97, 100, 100, 3, 48, 110, 83, 10, 0, 111, 115, 8, 2, 97, 3, 48, 110, 89, 0, 195, 170, 114, 101, 2, 17, 67, 3, 48, 113, 34, 13, 0, 111, 108, 105, 111, 3, 48, 117, 55, 119, 0, 104, 2, 32, 3, 83, 0, 104, 105, 2, 108, 105, 112, 112, 17, 65, 32, 3, 83, 13, 0, 104, 105, 2, 108, 105, 112, 3, 83, 109, 0, 115, 2, 105, 103, 17, 65, 3, 89, 0, 115, 105, 103, 101, 2, 100, 101, 108, 105, 101, 3, 89, 2, 37, 136, 13, 0, 115, 101, 117, 100, 111, 3, 89, 128, 72, 2, 40, 0, 7, 6, 113, 0, 2, 113, 3, 0, 117, 3, 21, 0, 3, 49, 58, 0, 117, 105, 120, 2, 111, 116, 105, 101, 3, 49, 58, 2, 37, 49, 89, 0, 7, 6, 114, 0, 2, 114, 3, 0, 4, 108, 2, 32, 3, 21, 0, 108, 115, 2, 32, 0, 3, 34, 0, 4, 97, 2, 98, 98, 121, 110, 3, 34, 2, 35, 0, 97, 2, 110, 116, 115, 111, 101, 110, 0, 97, 2, 112, 105, 101, 114, 0, 97, 8, 2, 112, 112, 111, 114, 116, 0, 97, 109, 2, 112, 111, 107, 107, 101, 114, 3, 34, 2, 35, 65, 0, 4, 97, 109, 112, 2, 115, 97, 108, 105, 103, 3, 34, 2, 35, 65, 48, 0, 97, 109, 112, 2, 115, 112, 111, 101, 100, 21, 0, 97, 110, 8, 2, 103, 101, 101, 114, 3, 34, 2, 35, 68, 0, 97, 102, 102, 105, 110, 97, 100, 101, 2, 114, 3, 34, 2, 35, 83, 2, 37, 50, 2, 35, 72, 13, 0, 105, 8, 2, 111, 3, 34, 2, 37, 0, 111, 2, 106, 97, 3, 34, 2, 40, 0, 111, 101, 116, 105, 110, 101, 3, 34, 2, 40, 47, 37, 50, 13, 0, 111, 117, 108, 101, 116, 116, 101, 3, 34, 2, 40, 55, 108, 47, 0, 111, 109, 97, 110, 3, 34, 2, 40, 65, 35, 50, 0, 111, 101, 109, 101, 2, 110, 105, 195, 171, 3, 34, 2, 40, 65, 37, 12, 0, 111, 110, 2, 100, 97, 119, 101, 108, 3, 34, 2, 110, 50, 0, 111, 110, 100, 2, 98, 111, 114, 115, 116, 3, 34, 2, 110, 50, 47, 0, 111, 110, 100, 111, 109, 2, 116, 97, 108, 105, 3, 34, 2, 110, 50, 47, 2, 110, 65, 0, 4, 117, 2, 98, 114, 105, 101, 107, 3, 34, 2, 111, 0, 117, 2, 109, 111, 101, 114, 0, 117, 109, 97, 2, 116, 105, 101, 107, 3, 34, 2, 111, 65, 13, 0, 97, 100, 105, 2, 111, 108, 111, 21, 3, 34, 2, 115, 72, 2, 37, 0, 111, 111, 115, 2, 107, 108, 101, 117, 114, 105, 3, 34, 2, 117, 89, 0, 117, 2, 195, 175, 110, 3, 34, 2, 118, 10, 0, 111, 111, 100, 101, 8, 3, 34, 6, 117, 72, 13, 0, 117, 103, 8, 2, 17, 65, 21, 3, 34, 7, 111, 136, 10, 0, 97, 2, 110, 111, 110, 107, 101, 108, 3, 34, 13, 0, 105, 116, 117, 2, 17, 65, 3, 34, 13, 47, 2, 118, 0, 105, 110, 110, 101, 2, 119, 3, 34, 13, 50, 13, 0, 4, 105, 110, 103, 1, 10, 2, 32, 3, 34, 13, 68, 0, 114, 105, 110, 103, 0, 105, 118, 105, 101, 114, 3, 34, 13, 83, 37, 12, 34, 0, 105, 115, 2, 107, 97, 110, 116, 3, 34, 13, 89, 0, 110, 1, 21, 2, 25, 3, 34, 14, 50, 0, 109, 1, 10, 2, 25, 3, 34, 14, 65, 0, 97, 107, 101, 2, 116, 3, 34, 35, 49, 6, 108, 0, 4, 8, 2, 32, 15, 15, 15, 3, 34, 35, 50, 47, 0, 8, 2, 32, 15, 15, 46, 0, 8, 2, 32, 15, 46, 0, 97, 110, 100, 8, 2, 17, 65, 21, 3, 34, 35, 50, 47, 10, 0, 4, 97, 100, 105, 107, 97, 2, 108, 101, 3, 34, 35, 72, 37, 49, 6, 115, 0, 97, 100, 105, 107, 97, 97, 0, 97, 100, 105, 107, 97, 2, 108, 105, 3, 34, 35, 72, 37, 49, 35, 0, 97, 115, 115, 101, 3, 34, 35, 89, 13, 0, 105, 101, 116, 101, 3, 34, 37, 47, 13, 0, 117, 2, 100, 111, 108, 17, 67, 3, 34, 40, 0, 111, 101, 114, 115, 101, 108, 3, 34, 40, 34, 89, 13, 55, 0, 105, 8, 2, 103, 3, 34, 109, 0, 105, 116, 109, 101, 3, 34, 109, 47, 65, 13, 0, 105, 110, 107, 104, 2, 97, 108, 115, 3, 34, 109, 68, 49, 0, 105, 98, 98, 101, 2, 116, 106, 3, 34, 109, 71, 2, 37, 0, 111, 110, 100, 2, 114, 3, 34, 110, 50, 47, 0, 111, 110, 100, 111, 109, 3, 34, 110, 50, 47, 10, 2, 110, 65, 0, 111, 108, 8, 2, 17, 65, 3, 34, 110, 55, 19, 0, 117, 103, 98, 121, 3, 34, 111, 81, 71, 37, 0, 117, 115, 112, 101, 114, 2, 17, 67, 3, 34, 111, 89, 48, 13, 34, 0, 97, 97, 100, 2, 17, 65, 3, 34, 115, 47, 10, 0, 97, 100, 105, 111, 3, 34, 115, 72, 119, 12, 10, 0, 97, 99, 104, 101, 108, 3, 34, 115, 136, 13, 55, 0, 111, 98, 111, 116, 2, 17, 65, 3, 34, 117, 71, 110, 47, 10, 0, 8, 2, 32, 3, 112, 34, 0, 7, 6, 115, 0, 2, 115, 3, 0, 4, 104, 2, 32, 3, 21, 0, 104, 105, 114, 101, 2, 32, 0, 4, 3, 89, 0, 1, 21, 2, 32, 14, 128, 192, 129, 0, 1, 21, 2, 106, 97, 115, 0, 1, 21, 2, 106, 111, 101, 114, 110, 0, 1, 21, 2, 106, 111, 110, 17, 67, 0, 1, 21, 21, 21, 2, 32, 14, 128, 128, 129, 0, 1, 105, 2, 32, 0, 1, 111, 2, 32, 0, 1, 117, 2, 32, 0, 2, 99, 104, 97, 111, 115, 0, 2, 99, 104, 101, 109, 105, 0, 2, 106, 97, 97, 112, 0, 2, 106, 97, 103, 0, 4, 97, 2, 114, 111, 110, 103, 3, 89, 2, 35, 0, 97, 2, 116, 105, 114, 0, 97, 2, 116, 117, 114, 110, 117, 0, 4, 97, 114, 2, 107, 17, 65, 3, 89, 2, 35, 34, 0, 97, 114, 8, 2, 100, 0, 97, 114, 97, 2, 115, 101, 3, 89, 2, 35, 34, 2, 35, 0, 97, 114, 107, 111, 2, 102, 97, 3, 89, 2, 35, 34, 49, 2, 40, 0, 4, 97, 110, 2, 17, 65, 116, 17, 65, 17, 67, 3, 89, 2, 35, 50, 0, 97, 110, 8, 2, 100, 97, 0, 4, 97, 108, 2, 109, 97, 110, 100, 101, 114, 3, 89, 2, 35, 55, 0, 97, 108, 2, 112, 101, 116, 101, 114, 0, 97, 108, 97, 2, 109, 97, 110, 100, 101, 114, 3, 89, 2, 35, 55, 2, 35, 0, 97, 108, 111, 2, 110, 3, 89, 2, 35, 55, 110, 0, 97, 109, 8, 2, 98, 3, 89, 2, 35, 65, 0, 97, 109, 97, 114, 105, 2, 116, 97, 3, 89, 2, 35, 65, 2, 35, 34, 2, 37, 0, 97, 110, 103, 101, 114, 101, 2, 25, 3, 89, 2, 35, 68, 13, 34, 108, 0, 97, 98, 111, 116, 2, 17, 65, 3, 89, 2, 35, 71, 2, 40, 47, 0, 97, 102, 97, 114, 105, 3, 89, 2, 35, 83, 115, 34, 2, 37, 0, 97, 118, 2, 97, 110, 110, 17, 65, 3, 89, 2, 35, 84, 0, 97, 103, 2, 109, 111, 101, 3, 89, 2, 35, 136, 0, 97, 103, 104, 101, 98, 98, 101, 2, 110, 3, 89, 2, 35, 136, 107, 108, 71, 13, 0, 105, 8, 2, 107, 108, 111, 3, 89, 2, 37, 0, 105, 112, 114, 101, 2, 25, 3, 89, 2, 37, 48, 34, 108, 0, 105, 101, 108, 107, 117, 110, 1, 21, 2, 100, 105, 103, 3, 89, 2, 37, 55, 49, 4, 111, 50, 0, 4, 111, 2, 110, 97, 116, 17, 65, 3, 89, 2, 40, 0, 111, 2, 112, 114, 97, 0, 111, 117, 2, 102, 102, 108, 101, 117, 0, 117, 2, 115, 97, 17, 67, 0, 117, 8, 2, 109, 101, 114, 105, 0, 111, 101, 116, 2, 115, 97, 112, 112, 105, 3, 89, 2, 40, 47, 0, 111, 110, 110, 101, 2, 116, 3, 89, 2, 40, 50, 108, 0, 111, 109, 97, 8, 2, 108, 105, 17, 65, 3, 89, 2, 40, 65, 115, 0, 111, 101, 100, 97, 8, 2, 110, 3, 89, 2, 40, 72, 35, 0, 111, 101, 119, 101, 2, 110, 105, 101, 114, 3, 89, 2, 40, 84, 13, 0, 111, 115, 97, 2, 116, 105, 3, 89, 2, 40, 89, 115, 0, 4, 111, 2, 108, 105, 100, 3, 89, 2, 110, 0, 111, 2, 108, 105, 101, 100, 0, 4, 111, 108, 2, 100, 121, 3, 89, 2, 110, 55, 0, 111, 108, 8, 2, 100, 97, 0, 117, 2, 109, 109, 105, 101, 114, 3, 89, 2, 111, 0, 117, 114, 114, 111, 2, 103, 97, 3, 89, 2, 111, 34, 2, 40, 0, 4, 117, 98, 2, 115, 116, 97, 110, 115, 105, 101, 3, 89, 2, 111, 48, 0, 117, 98, 2, 116, 105, 0, 117, 107, 115, 101, 115, 3, 89, 2, 111, 49, 89, 108, 89, 0, 117, 108, 116, 97, 110, 97, 3, 89, 2, 111, 55, 47, 115, 50, 2, 35, 0, 4, 117, 98, 2, 108, 105, 3, 89, 2, 111, 71, 0, 117, 98, 2, 115, 105, 100, 17, 65, 0, 117, 98, 2, 115, 107, 114, 105, 112, 0, 117, 98, 108, 105, 2, 109, 17, 65, 3, 89, 2, 111, 71, 55, 2, 37, 0, 117, 98, 108, 105, 109, 105, 2, 110, 97, 3, 89, 2, 111, 71, 55, 2, 37, 65, 2, 37, 0, 117, 98, 115, 116, 105, 2, 116, 117, 3, 89, 2, 111, 71, 89, 47, 13, 0, 117, 103, 103, 101, 115, 3, 89, 2, 111, 136, 108, 89, 0, 97, 2, 116, 97, 110, 105, 101, 3, 89, 2, 115, 0, 97, 109, 101, 8, 2, 104, 17, 65, 21, 3, 89, 2, 115, 65, 13, 0, 99, 101, 110, 97, 114, 105, 111, 3, 89, 2, 116, 50, 115, 34, 2, 37, 38, 2, 117, 0, 117, 105, 100, 2, 45, 97, 102, 114, 105, 107, 3, 89, 2, 127, 47, 0, 117, 105, 100, 2, 111, 111, 115, 3, 89, 2, 127, 47, 10, 0, 105, 110, 111, 2, 110, 105, 101, 109, 3, 89, 4, 37, 50, 2, 40, 0, 117, 112, 101, 114, 105, 110, 116, 101, 110, 100, 101, 110, 116, 3, 89, 4, 40, 48, 34, 13, 50, 47, 2, 108, 50, 72, 108, 50, 47, 0, 4, 111, 100, 111, 109, 2, 105, 101, 116, 3, 89, 4, 117, 72, 110, 65, 0, 111, 100, 111, 109, 2, 105, 101, 116, 0, 105, 116, 114, 117, 115, 3, 89, 6, 37, 47, 34, 2, 111, 89, 10, 0, 105, 101, 102, 1, 21, 2, 32, 3, 89, 6, 37, 83, 0, 105, 101, 119, 101, 1, 21, 2, 32, 3, 89, 6, 37, 84, 13, 0, 105, 101, 119, 101, 114, 1, 21, 2, 32, 3, 89, 6, 37, 84, 13, 34, 0, 105, 2, 110, 110, 105, 103, 3, 89, 6, 109, 0, 117, 103, 1, 21, 2, 116, 105, 103, 3, 89, 6, 111, 136, 0, 101, 108, 102, 2, 32, 3, 89, 6, 112, 55, 83, 0, 97, 97, 109, 8, 2, 14, 128, 132, 132, 3, 89, 6, 115, 65, 0, 97, 109, 101, 8, 2, 21, 14, 128, 132, 132, 3, 89, 6, 115, 65, 13, 0, 101, 114, 105, 110, 103, 1, 21, 3, 89, 6, 116, 34, 13, 68, 0, 101, 119, 101, 1, 25, 2, 17, 67, 3, 89, 6, 116, 84, 13, 0, 111, 110, 2, 111, 109, 3, 89, 7, 110, 50, 10, 0, 117, 112, 101, 114, 2, 17, 65, 3, 89, 7, 118, 48, 13, 34, 10, 0, 101, 119, 101, 1, 21, 2, 119, 105, 103, 3, 89, 10, 116, 84, 13, 0, 4, 105, 2, 108, 108, 97, 98, 17, 65, 3, 89, 13, 0, 105, 2, 108, 108, 97, 98, 17, 65, 0, 105, 2, 110, 97, 112, 25, 0, 105, 2, 112, 105, 101, 114, 0, 105, 2, 116, 114, 111, 101, 110, 0, 105, 2, 118, 105, 101, 108, 0, 105, 8, 2, 110, 111, 17, 67, 0, 105, 114, 101, 110, 101, 3, 89, 13, 34, 116, 50, 13, 0, 105, 116, 114, 111, 110, 101, 108, 108, 97, 3, 89, 13, 47, 34, 2, 40, 50, 112, 55, 2, 35, 0, 101, 112, 116, 101, 109, 98, 101, 114, 3, 89, 13, 48, 47, 108, 65, 71, 13, 34, 0, 4, 105, 110, 2, 106, 97, 3, 89, 13, 50, 0, 105, 110, 2, 116, 97, 107, 17, 67, 0, 105, 110, 8, 2, 100, 114, 111, 0, 105, 110, 116, 101, 116, 105, 101, 115, 3, 89, 13, 50, 47, 116, 47, 37, 89, 0, 105, 110, 105, 115, 116, 2, 17, 65, 114, 3, 89, 13, 50, 109, 89, 47, 0, 105, 108, 105, 107, 111, 111, 110, 3, 89, 13, 55, 2, 37, 49, 117, 50, 10, 0, 105, 108, 104, 111, 101, 2, 17, 65, 3, 89, 13, 55, 2, 40, 58, 0, 105, 108, 105, 2, 110, 100, 3, 89, 13, 55, 109, 0, 97, 108, 97, 114, 105, 115, 3, 89, 13, 55, 115, 34, 13, 89, 0, 4, 105, 109, 8, 2, 98, 17, 65, 3, 89, 13, 65, 0, 105, 109, 112, 2, 116, 111, 0, 105, 109, 109, 101, 2, 116, 114, 105, 101, 32, 24, 3, 89, 13, 65, 13, 0, 105, 109, 112, 111, 2, 115, 105, 17, 65, 3, 89, 13, 65, 48, 117, 0, 105, 109, 98, 105, 2, 111, 17, 67, 3, 89, 13, 65, 71, 2, 37, 0, 105, 109, 98, 111, 2, 108, 105, 101, 107, 3, 89, 13, 65, 71, 2, 40, 0, 105, 109, 109, 101, 2, 116, 114, 105, 101, 3, 89, 13, 65, 116, 0, 4, 101, 115, 1, 21, 2, 32, 3, 89, 13, 89, 0, 105, 115, 2, 116, 121, 110, 0, 105, 115, 116, 2, 101, 3, 89, 13, 89, 47, 0, 105, 115, 116, 101, 2, 109, 97, 116, 3, 89, 13, 89, 47, 13, 0, 105, 103, 2, 97, 21, 3, 89, 13, 136, 0, 105, 103, 97, 114, 101, 2, 116, 3, 89, 13, 136, 2, 35, 34, 108, 0, 97, 8, 2, 102, 102, 3, 89, 35, 7, 0, 97, 110, 100, 2, 97, 100, 100, 101, 114, 3, 89, 35, 50, 47, 10, 0, 97, 108, 118, 111, 2, 25, 3, 89, 35, 55, 84, 2, 40, 0, 97, 104, 97, 114, 97, 3, 89, 35, 107, 6, 115, 34, 35, 0, 105, 2, 107, 108, 105, 101, 3, 89, 37, 0, 105, 112, 97, 108, 101, 1, 21, 3, 89, 37, 48, 6, 115, 55, 13, 0, 105, 101, 107, 101, 8, 3, 89, 37, 49, 13, 0, 105, 107, 108, 117, 2, 115, 3, 89, 37, 49, 55, 111, 0, 111, 110, 97, 110, 116, 3, 89, 40, 50, 6, 35, 50, 47, 0, 112, 97, 2, 115, 105, 101, 101, 114, 3, 89, 48, 2, 35, 0, 112, 97, 114, 8, 2, 116, 97, 21, 3, 89, 48, 2, 35, 34, 0, 4, 112, 97, 110, 2, 100, 97, 98, 3, 89, 48, 2, 35, 50, 0, 112, 97, 110, 2, 106, 17, 65, 17, 65, 0, 112, 97, 110, 2, 115, 112, 101, 107, 0, 112, 97, 115, 2, 109, 111, 100, 3, 89, 48, 2, 35, 89, 0, 4, 112, 105, 2, 110, 97, 21, 3, 89, 48, 2, 37, 0, 112, 105, 8, 2, 114, 97, 0, 112, 105, 110, 101, 2, 116, 3, 89, 48, 2, 37, 50, 108, 0, 112, 101, 107, 2, 116, 97, 107, 101, 108, 3, 89, 48, 2, 108, 49, 0, 112, 101, 107, 117, 2, 108, 17, 65, 3, 89, 48, 2, 108, 49, 2, 118, 0, 112, 101, 115, 8, 2, 109, 97, 3, 89, 48, 2, 108, 89, 0, 112, 101, 115, 105, 2, 102, 3, 89, 48, 2, 108, 89, 2, 109, 0, 112, 101, 115, 105, 2, 97, 3, 89, 48, 2, 108, 91, 2, 37, 0, 112, 111, 110, 8, 2, 116, 97, 3, 89, 48, 2, 110, 50, 0, 112, 111, 114, 116, 8, 2, 21, 21, 21, 3, 89, 48, 7, 110, 34, 47, 10, 0, 112, 101, 114, 1, 21, 2, 97, 3, 89, 48, 13, 34, 6, 0, 112, 105, 116, 115, 2, 118, 111, 110, 3, 89, 48, 13, 47, 89, 0, 112, 101, 115, 101, 2, 114, 121, 3, 89, 48, 13, 89, 13, 0, 112, 114, 101, 101, 107, 119, 111, 111, 114, 100, 101, 108, 105, 3, 89, 48, 34, 2, 116, 49, 84, 117, 34, 72, 13, 55, 13, 0, 112, 114, 105, 110, 103, 98, 111, 2, 107, 3, 89, 48, 34, 7, 109, 68, 71, 110, 0, 112, 114, 111, 107, 101, 3, 89, 48, 34, 117, 49, 13, 0, 112, 97, 114, 116, 101, 108, 3, 89, 48, 35, 34, 47, 13, 55, 0, 112, 97, 116, 8, 2, 97, 3, 89, 48, 35, 47, 10, 0, 112, 111, 101, 100, 8, 2, 21, 3, 89, 48, 40, 47, 0, 112, 111, 101, 100, 2, 105, 103, 3, 89, 48, 40, 72, 0, 112, 101, 114, 1, 107, 101, 2, 105, 109, 3, 89, 48, 108, 34, 0, 112, 101, 115, 105, 97, 108, 105, 115, 3, 89, 48, 108, 91, 35, 55, 6, 109, 89, 0, 112, 101, 115, 105, 97, 108, 105, 115, 2, 17, 65, 3, 89, 48, 108, 91, 37, 35, 55, 37, 89, 0, 4, 112, 101, 108, 1, 17, 65, 17, 65, 2, 100, 3, 89, 48, 112, 55, 0, 112, 101, 108, 1, 17, 67, 2, 32, 0, 112, 101, 108, 1, 101, 2, 32, 0, 112, 101, 108, 8, 17, 65, 110, 2, 32, 0, 112, 101, 108, 97, 103, 116, 105, 103, 3, 89, 48, 112, 55, 6, 35, 136, 47, 13, 136, 0, 112, 101, 110, 101, 2, 32, 3, 89, 48, 116, 50, 13, 0, 112, 101, 108, 101, 1, 10, 2, 32, 3, 89, 48, 116, 55, 13, 0, 107, 97, 2, 118, 111, 116, 3, 89, 49, 2, 35, 0, 107, 97, 114, 8, 2, 17, 67, 3, 89, 49, 2, 35, 34, 0, 107, 97, 107, 101, 114, 2, 105, 110, 103, 3, 89, 49, 2, 35, 49, 116, 34, 0, 107, 97, 110, 2, 100, 97, 3, 89, 49, 2, 35, 50, 0, 107, 97, 110, 100, 101, 2, 114, 105, 110, 103, 3, 89, 49, 2, 35, 50, 72, 116, 0, 107, 105, 115, 111, 102, 114, 2, 101, 3, 89, 49, 2, 37, 89, 2, 40, 83, 34, 0, 107, 101, 2, 100, 117, 108, 101, 3, 89, 49, 2, 108, 0, 107, 111, 112, 112, 101, 108, 2, 109, 97, 97, 3, 89, 49, 2, 110, 48, 13, 55, 0, 107, 101, 114, 2, 109, 117, 116, 115, 3, 89, 49, 2, 112, 34, 0, 107, 101, 114, 112, 105, 2, 111, 101, 110, 3, 89, 49, 2, 112, 34, 48, 2, 37, 0, 107, 111, 2, 108, 105, 101, 114, 3, 89, 49, 2, 117, 0, 107, 121, 110, 2, 104, 101, 105, 3, 89, 49, 2, 123, 50, 0, 107, 97, 112, 108, 105, 107, 1, 21, 3, 89, 49, 6, 35, 48, 55, 13, 49, 0, 107, 121, 110, 108, 105, 107, 1, 21, 3, 89, 49, 6, 123, 50, 55, 13, 49, 0, 107, 111, 107, 8, 2, 17, 65, 14, 128, 132, 132, 3, 89, 49, 7, 110, 49, 10, 0, 107, 101, 2, 100, 111, 110, 107, 3, 89, 49, 13, 0, 107, 105, 108, 100, 101, 114, 2, 121, 3, 89, 49, 13, 55, 72, 13, 34, 0, 107, 101, 108, 101, 8, 2, 116, 3, 89, 49, 13, 55, 108, 0, 107, 114, 97, 112, 110, 101, 2, 108, 3, 89, 49, 34, 2, 35, 48, 50, 112, 0, 107, 114, 105, 102, 2, 17, 65, 3, 89, 49, 34, 109, 83, 10, 0, 107, 97, 114, 114, 101, 108, 3, 89, 49, 35, 34, 13, 55, 0, 107, 97, 112, 112, 121, 8, 17, 67, 17, 65, 17, 65, 17, 67, 3, 89, 49, 35, 48, 6, 123, 0, 4, 107, 97, 112, 1, 21, 2, 105, 110, 21, 3, 89, 49, 35, 48, 10, 0, 107, 97, 112, 1, 21, 2, 111, 0, 107, 108, 101, 2, 114, 111, 115, 101, 3, 89, 49, 55, 13, 0, 107, 117, 108, 100, 2, 101, 114, 107, 101, 110, 3, 89, 49, 111, 55, 47, 10, 0, 107, 101, 114, 112, 3, 89, 49, 112, 34, 48, 0, 107, 97, 100, 101, 3, 89, 49, 115, 72, 13, 0, 107, 97, 100, 117, 3, 89, 49, 115, 72, 118, 0, 107, 101, 109, 101, 114, 3, 89, 49, 116, 65, 13, 34, 0, 107, 111, 111, 110, 103, 101, 2, 17, 67, 3, 89, 49, 117, 50, 136, 13, 0, 107, 111, 108, 101, 3, 89, 49, 117, 55, 13, 0, 110, 101, 108, 8, 2, 17, 65, 3, 89, 50, 7, 112, 55, 10, 0, 110, 101, 108, 2, 32, 3, 89, 50, 112, 55, 0, 110, 97, 112, 101, 114, 2, 105, 110, 103, 3, 89, 50, 115, 48, 13, 34, 0, 108, 97, 2, 118, 105, 110, 3, 89, 55, 2, 35, 0, 108, 97, 103, 8, 3, 89, 55, 7, 35, 136, 10, 0, 108, 97, 103, 2, 111, 102, 102, 3, 89, 55, 35, 136, 10, 0, 108, 111, 112, 2, 101, 109, 109, 101, 114, 3, 89, 55, 110, 48, 10, 0, 108, 97, 2, 119, 101, 3, 89, 55, 115, 0, 4, 106, 1, 21, 2, 97, 17, 67, 17, 65, 3, 89, 57, 0, 106, 1, 21, 2, 97, 97, 114, 0, 4, 119, 2, 101, 114, 109, 3, 89, 58, 0, 119, 8, 0, 119, 97, 2, 104, 105, 108, 105, 3, 89, 58, 2, 35, 0, 119, 97, 114, 116, 2, 103, 97, 108, 3, 89, 58, 2, 35, 34, 47, 0, 4, 119, 97, 97, 114, 2, 108, 121, 119, 3, 89, 58, 2, 115, 34, 0, 119, 97, 97, 114, 2, 109, 111, 101, 100, 0, 119, 97, 109, 8, 2, 17, 65, 21, 3, 89, 58, 35, 65, 10, 0, 117, 105, 116, 101, 3, 89, 58, 37, 47, 13, 0, 119, 101, 110, 100, 101, 108, 3, 89, 58, 108, 50, 72, 13, 55, 0, 119, 101, 109, 1, 21, 2, 32, 3, 89, 58, 108, 65, 0, 119, 101, 109, 8, 2, 17, 65, 3, 89, 58, 108, 65, 10, 0, 119, 105, 116, 115, 101, 114, 3, 89, 58, 109, 47, 89, 13, 34, 0, 119, 101, 101, 112, 3, 89, 58, 116, 48, 0, 119, 101, 112, 101, 3, 89, 58, 116, 48, 13, 0, 109, 97, 2, 114, 97, 103, 3, 89, 65, 2, 35, 0, 109, 101, 108, 116, 3, 89, 65, 112, 55, 47, 0, 119, 97, 103, 2, 25, 3, 89, 84, 35, 136, 0, 119, 101, 114, 107, 1, 21, 3, 89, 84, 112, 34, 49, 0, 119, 101, 101, 1, 21, 2, 32, 3, 89, 84, 116, 0, 105, 108, 105, 107, 111, 2, 110, 3, 89, 109, 55, 2, 37, 49, 2, 110, 0, 105, 108, 119, 101, 114, 3, 89, 109, 55, 84, 13, 34, 0, 105, 116, 117, 97, 115, 105, 101, 3, 89, 109, 76, 40, 6, 115, 89, 37, 0, 111, 2, 110, 110, 101, 116, 106, 105, 101, 12, 12, 3, 89, 110, 0, 111, 110, 2, 103, 21, 3, 89, 110, 50, 0, 117, 98, 8, 2, 97, 3, 89, 111, 71, 10, 0, 97, 107, 101, 3, 89, 115, 49, 13, 0, 97, 109, 101, 110, 2, 12, 3, 89, 115, 65, 13, 50, 0, 97, 109, 101, 108, 2, 17, 67, 3, 89, 115, 65, 13, 55, 0, 97, 97, 109, 103, 101, 101, 3, 89, 115, 65, 136, 116, 0, 101, 119, 101, 2, 116, 106, 105, 101, 3, 89, 116, 84, 37, 0, 111, 2, 118, 3, 89, 117, 0, 111, 105, 101, 8, 3, 89, 117, 19, 37, 0, 111, 118, 101, 114, 114, 101, 3, 89, 117, 83, 6, 112, 34, 13, 0, 111, 115, 105, 97, 108, 2, 105, 3, 89, 117, 91, 37, 35, 55, 6, 0, 111, 115, 105, 111, 2, 45, 3, 89, 117, 91, 119, 12, 0, 97, 117, 110, 97, 3, 89, 131, 50, 35, 0, 4, 1, 17, 67, 2, 105, 101, 101, 17, 67, 3, 91, 0, 1, 17, 67, 2, 105, 195, 171, 108, 101, 0, 2, 105, 195, 171, 110, 0, 99, 104, 0, 104, 8, 0, 106, 0, 106, 97, 2, 109, 97, 3, 91, 2, 35, 0, 106, 97, 114, 2, 109, 97, 110, 116, 3, 91, 2, 35, 34, 0, 106, 97, 109, 112, 97, 110, 106, 101, 3, 91, 2, 35, 65, 48, 35, 50, 57, 13, 0, 106, 97, 109, 112, 111, 101, 3, 91, 2, 35, 65, 48, 40, 12, 0, 106, 111, 107, 111, 108, 97, 100, 101, 3, 91, 2, 110, 49, 13, 55, 115, 72, 13, 0, 106, 105, 109, 112, 97, 110, 2, 115, 101, 101, 3, 91, 13, 65, 48, 2, 35, 50, 0, 105, 1, 21, 2, 111, 3, 91, 37, 0, 105, 97, 97, 108, 3, 91, 37, 6, 115, 55, 0, 105, 97, 108, 101, 3, 91, 37, 6, 115, 55, 13, 0, 99, 104, 117, 8, 2, 17, 67, 3, 91, 40, 0, 106, 101, 114, 114, 105, 101, 3, 91, 108, 34, 37, 0, 105, 111, 1, 21, 2, 110, 101, 3, 91, 119, 6, 0, 7, 6, 116, 0, 4, 2, 32, 100, 24, 3, 0, 2, 116, 3, 0, 4, 99, 104, 1, 17, 65, 3, 21, 0, 104, 1, 21, 2, 32, 24, 0, 104, 8, 0, 104, 121, 1, 21, 2, 32, 0, 105, 111, 110, 1, 21, 2, 32, 0, 105, 111, 110, 115, 1, 21, 2, 32, 0, 108, 101, 1, 21, 2, 32, 0, 106, 105, 101, 1, 101, 114, 3, 37, 80, 37, 0, 4, 3, 47, 0, 1, 17, 67, 21, 2, 101, 110, 121, 0, 1, 21, 2, 101, 109, 97, 25, 12, 12, 0, 1, 97, 97, 114, 116, 115, 2, 106, 0, 104, 1, 21, 2, 17, 67, 0, 104, 8, 2, 21, 21, 0, 4, 97, 1, 21, 2, 108, 105, 115, 3, 47, 2, 35, 0, 97, 2, 98, 108, 101, 116, 0, 97, 2, 114, 105, 101, 102, 0, 97, 2, 114, 105, 101, 119, 101, 0, 97, 8, 2, 109, 98, 0, 97, 114, 8, 2, 116, 97, 21, 3, 47, 2, 35, 34, 0, 97, 114, 101, 110, 2, 116, 97, 3, 47, 2, 35, 34, 13, 50, 0, 97, 116, 111, 101, 2, 195, 171, 3, 47, 2, 35, 47, 2, 40, 0, 97, 112, 105, 115, 115, 101, 2, 114, 105, 3, 47, 2, 35, 48, 13, 89, 13, 0, 97, 107, 115, 105, 100, 101, 114, 2, 109, 3, 47, 2, 35, 49, 89, 2, 37, 72, 2, 112, 34, 0, 97, 110, 122, 97, 2, 110, 105, 3, 47, 2, 35, 50, 88, 115, 0, 97, 108, 101, 110, 2, 116, 106, 105, 101, 3, 47, 2, 35, 55, 108, 37, 68, 0, 97, 108, 101, 110, 116, 3, 47, 2, 35, 55, 108, 50, 47, 0, 97, 109, 97, 114, 105, 115, 107, 3, 47, 2, 35, 65, 2, 35, 34, 109, 89, 49, 0, 97, 109, 101, 108, 101, 2, 116, 106, 3, 47, 2, 35, 65, 13, 55, 108, 37, 0, 97, 109, 98, 111, 101, 2, 114, 121, 110, 3, 47, 2, 35, 65, 71, 2, 40, 0, 97, 109, 97, 2, 116, 105, 101, 3, 47, 2, 35, 65, 115, 0, 97, 98, 101, 114, 2, 110, 97, 107, 101, 108, 3, 47, 2, 35, 71, 13, 34, 0, 97, 98, 97, 107, 3, 47, 2, 35, 71, 35, 49, 0, 97, 98, 108, 111, 2, 16, 3, 47, 2, 35, 71, 55, 117, 0, 97, 102, 101, 2, 114, 101, 3, 47, 2, 35, 83, 13, 0, 97, 118, 101, 114, 2, 110, 105, 101, 114, 3, 47, 2, 35, 83, 13, 34, 0, 97, 118, 101, 114, 110, 101, 3, 47, 2, 35, 83, 112, 34, 50, 13, 0, 4, 105, 2, 112, 101, 114, 17, 65, 3, 47, 2, 37, 0, 105, 2, 114, 97, 0, 105, 101, 114, 108, 97, 110, 2, 116, 121, 3, 47, 2, 37, 12, 34, 55, 2, 35, 50, 0, 105, 114, 97, 2, 110, 110, 105, 101, 3, 47, 2, 37, 34, 2, 35, 0, 105, 110, 101, 110, 8, 2, 116, 97, 21, 3, 47, 2, 37, 50, 2, 108, 50, 0, 105, 98, 101, 116, 8, 3, 47, 2, 37, 71, 108, 47, 0, 105, 97, 114, 97, 3, 47, 2, 37, 115, 34, 35, 0, 4, 111, 101, 2, 107, 111, 109, 101, 3, 47, 2, 40, 0, 111, 101, 2, 107, 111, 109, 115, 116, 105, 0, 111, 101, 2, 108, 97, 97, 116, 98, 97, 0, 111, 101, 2, 114, 105, 115, 116, 101, 21, 0, 111, 101, 114, 2, 110, 3, 47, 2, 40, 34, 0, 111, 101, 114, 101, 107, 101, 110, 2, 98, 3, 47, 2, 40, 34, 6, 116, 49, 13, 50, 0, 111, 101, 114, 101, 105, 107, 101, 3, 47, 2, 40, 34, 123, 49, 13, 0, 4, 111, 112, 8, 2, 97, 97, 115, 3, 47, 2, 40, 48, 0, 111, 112, 8, 2, 97, 115, 101, 0, 111, 101, 112, 97, 115, 108, 105, 107, 3, 47, 2, 40, 48, 35, 89, 55, 13, 49, 0, 111, 110, 101, 101, 108, 3, 47, 2, 40, 50, 116, 55, 0, 111, 110, 101, 108, 101, 3, 47, 2, 40, 50, 116, 55, 13, 0, 111, 101, 103, 97, 110, 107, 3, 47, 2, 40, 136, 6, 35, 68, 49, 0, 111, 101, 103, 101, 101, 102, 3, 47, 2, 40, 136, 116, 83, 0, 111, 101, 103, 101, 119, 101, 110, 2, 100, 3, 47, 2, 40, 136, 116, 84, 13, 50, 0, 111, 114, 8, 2, 110, 121, 110, 3, 47, 2, 110, 34, 0, 111, 107, 2, 116, 111, 107, 107, 3, 47, 2, 110, 49, 0, 111, 107, 107, 101, 2, 108, 111, 3, 47, 2, 110, 49, 13, 0, 111, 109, 98, 111, 108, 97, 3, 47, 2, 110, 65, 71, 117, 55, 2, 35, 0, 111, 115, 8, 2, 107, 97, 3, 47, 2, 110, 89, 0, 111, 8, 2, 110, 97, 3, 47, 2, 117, 0, 4, 111, 112, 8, 2, 111, 103, 114, 97, 3, 47, 2, 117, 48, 0, 111, 112, 8, 2, 111, 108, 111, 0, 117, 98, 101, 114, 107, 117, 108, 111, 115, 101, 3, 47, 2, 118, 71, 13, 34, 49, 2, 118, 55, 117, 89, 13, 0, 97, 105, 119, 97, 2, 110, 3, 47, 2, 121, 58, 35, 0, 121, 100, 2, 114, 111, 119, 3, 47, 2, 123, 47, 0, 111, 105, 2, 108, 101, 116, 3, 47, 2, 124, 0, 117, 105, 110, 2, 105, 101, 114, 3, 47, 2, 127, 50, 0, 1, 114, 101, 118, 100, 97, 2, 101, 3, 47, 6, 0, 105, 101, 102, 1, 21, 2, 32, 3, 47, 6, 37, 83, 0, 4, 105, 101, 119, 101, 1, 21, 2, 32, 3, 47, 6, 37, 84, 13, 0, 105, 101, 119, 101, 1, 21, 2, 114, 32, 0, 111, 101, 8, 2, 119, 101, 110, 25, 14, 128, 132, 131, 3, 47, 6, 40, 0, 111, 101, 103, 101, 8, 2, 21, 14, 128, 132, 133, 3, 47, 6, 40, 136, 13, 0, 111, 101, 103, 101, 2, 119, 105, 110, 103, 3, 47, 6, 40, 136, 116, 0, 97, 108, 105, 103, 1, 21, 3, 47, 6, 115, 55, 13, 136, 0, 111, 114, 105, 115, 1, 21, 2, 32, 3, 47, 6, 117, 34, 13, 89, 0, 117, 117, 114, 3, 47, 6, 118, 34, 0, 121, 1, 21, 2, 100, 105, 103, 3, 47, 6, 123, 0, 117, 105, 103, 108, 105, 107, 3, 47, 6, 127, 136, 55, 13, 49, 0, 97, 110, 100, 101, 8, 2, 17, 67, 21, 3, 47, 7, 35, 50, 72, 13, 0, 111, 112, 8, 2, 17, 65, 3, 47, 7, 110, 48, 10, 0, 117, 114, 98, 111, 8, 2, 25, 3, 47, 7, 111, 34, 71, 117, 10, 0, 104, 101, 117, 8, 3, 47, 7, 128, 0, 116, 101, 108, 3, 47, 13, 55, 0, 105, 110, 107, 2, 116, 105, 110, 107, 3, 47, 13, 68, 49, 0, 4, 97, 110, 100, 2, 111, 3, 47, 35, 50, 47, 10, 0, 97, 110, 100, 8, 2, 97, 0, 105, 116, 101, 108, 3, 47, 37, 47, 13, 55, 0, 105, 115, 115, 117, 101, 3, 47, 37, 91, 2, 40, 0, 111, 101, 114, 101, 2, 32, 3, 47, 40, 12, 34, 13, 0, 111, 101, 110, 101, 109, 101, 110, 3, 47, 40, 50, 6, 116, 65, 13, 50, 0, 4, 106, 1, 21, 2, 97, 3, 47, 57, 0, 106, 1, 105, 117, 0, 106, 111, 101, 114, 110, 97, 108, 105, 1, 21, 3, 47, 57, 2, 40, 34, 50, 2, 35, 55, 13, 0, 119, 101, 101, 100, 2, 25, 3, 47, 58, 37, 12, 72, 0, 119, 105, 115, 2, 17, 65, 3, 47, 58, 109, 89, 10, 0, 119, 101, 101, 100, 2, 114, 97, 3, 47, 58, 116, 72, 0, 119, 121, 102, 101, 2, 108, 3, 47, 58, 123, 83, 13, 0, 111, 103, 1, 103, 114, 111, 98, 3, 47, 110, 136, 10, 0, 117, 114, 108, 105, 110, 103, 116, 111, 110, 3, 47, 111, 12, 55, 2, 37, 68, 47, 13, 50, 0, 117, 115, 115, 101, 110, 3, 47, 111, 89, 13, 50, 0, 117, 103, 2, 17, 65, 3, 47, 111, 136, 10, 0, 4, 117, 117, 114, 1, 105, 116, 114, 97, 112, 3, 47, 118, 12, 34, 0, 117, 117, 114, 1, 115, 0, 121, 100, 2, 114, 3, 47, 123, 47, 0, 97, 110, 116, 8, 2, 101, 3, 47, 133, 50, 47, 0, 97, 110, 116, 101, 115, 3, 47, 133, 50, 47, 13, 89, 0, 4, 106, 3, 76, 0, 106, 8, 2, 105, 101, 0, 106, 101, 2, 108, 108, 105, 115, 3, 76, 2, 108, 0, 106, 97, 110, 107, 1, 21, 3, 76, 35, 68, 49, 0, 106, 101, 108, 108, 111, 3, 76, 108, 55, 40, 0, 106, 2, 105, 101, 3, 80, 0, 106, 105, 101, 1, 105, 117, 3, 80, 37, 0, 105, 97, 2, 32, 3, 91, 57, 35, 0, 7, 6, 117, 0, 103, 97, 110, 2, 100, 101, 3, 2, 40, 81, 2, 35, 50, 0, 1, 109, 2, 115, 107, 105, 101, 116, 3, 2, 111, 0, 108, 116, 105, 2, 109, 97, 3, 2, 111, 55, 47, 2, 37, 0, 8, 2, 114, 97, 3, 2, 118, 0, 114, 105, 110, 101, 3, 2, 118, 34, 37, 50, 13, 0, 114, 105, 101, 110, 119, 101, 103, 3, 2, 118, 34, 37, 50, 84, 112, 136, 10, 0, 114, 101, 8, 2, 116, 3, 2, 118, 34, 116, 0, 116, 111, 2, 112, 105, 17, 65, 3, 2, 118, 47, 117, 0, 110, 105, 118, 101, 114, 115, 2, 17, 65, 21, 3, 2, 118, 50, 2, 37, 84, 2, 112, 34, 89, 0, 115, 8, 98, 2, 17, 65, 3, 7, 111, 89, 10, 0, 2, 104, 108, 101, 32, 3, 40, 12, 0, 2, 17, 67, 3, 111, 0, 4, 3, 118, 0, 2, 17, 67, 17, 65, 0, 117, 0, 114, 101, 8, 2, 17, 67, 3, 118, 12, 34, 13, 0, 114, 105, 110, 101, 101, 114, 3, 118, 34, 37, 50, 6, 116, 34, 0, 119, 1, 110, 3, 118, 84, 0, 4, 119, 101, 1, 110, 2, 17, 67, 3, 118, 84, 13, 0, 119, 101, 1, 114, 17, 67, 2, 17, 67, 0, 119, 101, 108, 105, 107, 1, 17, 67, 3, 118, 84, 13, 55, 13, 49, 0, 121, 3, 127, 0, 110, 116, 106, 105, 101, 1, 17, 67, 3, 127, 68, 80, 37, 0, 116, 106, 105, 101, 3, 127, 80, 37, 0, 7, 6, 118, 0, 2, 118, 3, 0, 105, 108, 108, 101, 3, 21, 0, 3, 83, 0, 97, 2, 108, 108, 101, 105, 3, 83, 2, 35, 0, 97, 116, 105, 2, 107, 97, 97, 110, 3, 83, 2, 35, 47, 2, 37, 0, 97, 107, 97, 2, 116, 117, 114, 101, 3, 83, 2, 35, 49, 13, 0, 97, 110, 8, 2, 21, 3, 83, 2, 35, 50, 0, 97, 110, 115, 101, 108, 102, 2, 115, 112, 114, 3, 83, 2, 35, 50, 89, 2, 112, 55, 83, 0, 105, 2, 111, 3, 83, 2, 37, 0, 105, 111, 2, 108, 101, 116, 25, 3, 83, 2, 37, 2, 40, 0, 105, 101, 114, 2, 107, 97, 110, 116, 105, 103, 3, 83, 2, 37, 12, 34, 0, 105, 116, 114, 105, 2, 111, 101, 108, 3, 83, 2, 37, 47, 34, 2, 37, 0, 4, 117, 108, 2, 107, 97, 3, 83, 2, 111, 55, 0, 117, 108, 8, 2, 103, 97, 97, 116, 0, 121, 2, 97, 110, 100, 105, 103, 3, 83, 2, 123, 0, 97, 108, 108, 105, 103, 3, 83, 6, 35, 55, 13, 136, 0, 97, 115, 103, 101, 8, 2, 21, 14, 128, 132, 133, 3, 83, 6, 35, 89, 136, 13, 0, 105, 115, 101, 2, 25, 3, 83, 6, 37, 89, 37, 0, 117, 108, 100, 105, 103, 3, 83, 6, 111, 55, 72, 13, 136, 0, 97, 97, 114, 100, 105, 103, 1, 21, 3, 83, 6, 115, 34, 72, 13, 136, 0, 97, 107, 97, 110, 115, 105, 101, 3, 83, 13, 49, 35, 50, 89, 37, 0, 4, 105, 115, 1, 25, 2, 105, 101, 114, 3, 83, 13, 89, 0, 105, 115, 1, 101, 105, 21, 2, 32, 0, 105, 115, 101, 110, 2, 116, 101, 3, 83, 13, 89, 13, 50, 0, 105, 115, 105, 116, 101, 3, 83, 13, 89, 37, 47, 13, 0, 114, 101, 100, 101, 2, 108, 105, 101, 119, 3, 83, 34, 2, 116, 72, 13, 0, 114, 101, 101, 115, 97, 97, 110, 2, 106, 97, 3, 83, 34, 2, 116, 89, 19, 2, 115, 50, 0, 4, 114, 121, 2, 109, 101, 115, 115, 101, 108, 3, 83, 34, 2, 123, 0, 114, 121, 2, 109, 111, 101, 100, 0, 114, 121, 2, 112, 111, 115, 116, 105, 0, 114, 121, 2, 119, 105, 108, 0, 114, 105, 101, 110, 100, 105, 2, 110, 3, 83, 34, 37, 50, 72, 6, 109, 0, 114, 111, 116, 2, 101, 105, 101, 114, 3, 83, 34, 110, 47, 10, 0, 114, 101, 101, 109, 100, 101, 3, 83, 34, 116, 65, 72, 13, 0, 114, 101, 100, 101, 3, 83, 34, 116, 72, 13, 0, 114, 121, 103, 101, 119, 105, 103, 3, 83, 34, 123, 136, 6, 116, 84, 13, 136, 0, 97, 2, 100, 111, 101, 107, 3, 83, 35, 0, 97, 116, 8, 2, 17, 65, 21, 3, 83, 35, 47, 10, 0, 97, 107, 2, 117, 110, 105, 101, 3, 83, 35, 49, 10, 0, 97, 110, 103, 8, 2, 21, 3, 83, 35, 68, 0, 97, 110, 103, 101, 110, 3, 83, 35, 68, 13, 50, 0, 97, 110, 107, 108, 105, 107, 8, 3, 83, 35, 68, 49, 55, 13, 49, 0, 97, 115, 115, 116, 101, 2, 108, 3, 83, 35, 89, 47, 112, 0, 105, 115, 1, 100, 97, 2, 101, 21, 3, 83, 37, 89, 6, 0, 108, 105, 101, 195, 171, 2, 110, 105, 101, 114, 3, 83, 55, 2, 37, 13, 0, 108, 97, 109, 2, 111, 111, 3, 83, 55, 35, 65, 10, 0, 108, 97, 2, 17, 67, 17, 65, 17, 65, 3, 83, 55, 115, 0, 105, 115, 2, 17, 65, 3, 83, 109, 89, 0, 195, 169, 114, 3, 83, 113, 34, 0, 4, 97, 97, 114, 100, 105, 103, 1, 114, 101, 118, 3, 83, 115, 34, 72, 13, 136, 0, 97, 97, 114, 100, 105, 103, 1, 116, 105, 117, 0, 97, 116, 101, 2, 17, 67, 3, 83, 115, 47, 13, 0, 1, 21, 2, 97, 108, 101, 110, 116, 3, 84, 0, 97, 2, 107, 117, 3, 84, 2, 35, 0, 97, 114, 105, 2, 17, 65, 3, 84, 2, 35, 34, 2, 37, 0, 97, 108, 117, 116, 97, 3, 84, 2, 35, 55, 118, 47, 2, 35, 0, 97, 115, 101, 108, 105, 110, 101, 3, 84, 2, 35, 89, 13, 55, 37, 50, 0, 97, 103, 105, 110, 2, 17, 65, 21, 3, 84, 2, 35, 136, 2, 37, 50, 0, 4, 105, 2, 98, 114, 17, 65, 3, 84, 2, 37, 0, 105, 2, 99, 116, 111, 21, 0, 105, 8, 2, 114, 97, 0, 105, 116, 97, 2, 109, 105, 3, 84, 2, 37, 47, 2, 35, 0, 105, 115, 105, 2, 111, 101, 110, 3, 84, 2, 37, 89, 2, 37, 0, 105, 115, 2, 117, 17, 65, 3, 84, 2, 37, 90, 0, 105, 8, 2, 114, 105, 3, 84, 13, 0, 105, 114, 116, 117, 3, 84, 13, 34, 76, 2, 118, 0, 97, 103, 105, 110, 97, 3, 84, 35, 136, 37, 50, 35, 0, 105, 114, 117, 2, 25, 3, 84, 37, 34, 111, 0, 105, 116, 114, 111, 8, 2, 32, 3, 84, 37, 47, 34, 2, 40, 0, 105, 107, 105, 110, 103, 3, 84, 37, 49, 37, 68, 0, 105, 100, 101, 111, 3, 84, 37, 72, 119, 0, 4, 105, 115, 1, 17, 65, 2, 97, 115, 105, 101, 3, 84, 37, 89, 0, 105, 115, 2, 105, 101, 0, 105, 115, 2, 117, 109, 0, 105, 115, 1, 17, 65, 2, 101, 21, 3, 84, 37, 89, 6, 0, 105, 195, 171, 116, 110, 97, 2, 109, 101, 3, 84, 57, 2, 108, 47, 50, 2, 35, 0, 105, 108, 108, 97, 3, 84, 109, 55, 35, 0, 7, 6, 119, 0, 2, 119, 3, 0, 4, 1, 21, 2, 17, 67, 32, 3, 21, 0, 1, 21, 2, 32, 24, 0, 104, 0, 110, 0, 111, 111, 100, 2, 12, 0, 111, 114, 116, 104, 0, 115, 1, 21, 2, 32, 24, 0, 4, 1, 100, 3, 58, 0, 1, 104, 103, 0, 1, 107, 0, 1, 115, 0, 1, 115, 2, 97, 114, 116, 0, 1, 115, 2, 101, 101, 114, 100, 101, 114, 0, 1, 115, 21, 2, 97, 108, 107, 32, 0, 1, 115, 101, 98, 2, 97, 97, 114, 100, 101, 0, 1, 115, 101, 105, 2, 97, 97, 110, 0, 1, 115, 114, 101, 2, 101, 101, 114, 32, 0, 1, 116, 0, 97, 103, 103, 97, 1, 107, 3, 58, 35, 136, 35, 0, 97, 114, 101, 1, 115, 101, 98, 3, 58, 115, 34, 13, 0, 121, 102, 101, 108, 1, 116, 21, 3, 58, 123, 83, 13, 55, 0, 4, 3, 84, 0, 1, 17, 67, 2, 101, 101, 114, 100, 101, 114, 0, 1, 17, 67, 2, 105, 116, 32, 0, 1, 17, 67, 2, 195, 170, 114, 101, 108, 100, 0, 1, 17, 67, 17, 65, 2, 97, 97, 105, 101, 114, 0, 1, 17, 67, 21, 2, 97, 97, 114, 100, 101, 32, 0, 1, 17, 67, 21, 2, 97, 114, 109, 0, 1, 17, 67, 21, 2, 101, 114, 107, 0, 1, 17, 67, 21, 2, 101, 195, 171, 0, 1, 17, 67, 21, 2, 105, 101, 108, 0, 1, 17, 67, 21, 2, 111, 17, 67, 25, 0, 1, 17, 67, 21, 2, 111, 111, 17, 67, 0, 1, 17, 67, 21, 2, 117, 114, 109, 0, 1, 17, 67, 21, 2, 121, 100, 0, 1, 17, 67, 111, 111, 0, 1, 21, 2, 97, 101, 110, 0, 1, 100, 17, 65, 17, 65, 0, 1, 100, 21, 2, 97, 97, 114, 0, 1, 100, 97, 0, 1, 100, 110, 0, 1, 100, 111, 17, 67, 0, 1, 100, 121, 0, 1, 107, 2, 17, 65, 110, 100, 0, 1, 107, 2, 101, 114, 17, 67, 0, 1, 107, 2, 111, 17, 65, 0, 1, 107, 21, 2, 97, 108, 109, 0, 1, 115, 2, 97, 116, 101, 114, 0, 1, 115, 2, 101, 101, 107, 0, 1, 115, 2, 105, 108, 0, 1, 115, 2, 111, 101, 100, 101, 0, 1, 115, 2, 111, 101, 108, 105, 110, 103, 0, 1, 115, 2, 111, 117, 0, 1, 115, 2, 114, 0, 1, 115, 2, 121, 102, 0, 1, 115, 10, 2, 101, 101, 102, 115, 0, 1, 115, 17, 65, 17, 65, 2, 101, 110, 107, 0, 1, 115, 21, 2, 17, 65, 110, 32, 0, 1, 115, 21, 2, 17, 65, 110, 100, 0, 1, 115, 21, 2, 97, 97, 110, 0, 1, 115, 21, 2, 97, 108, 0, 1, 115, 21, 2, 97, 110, 103, 32, 0, 1, 115, 21, 2, 97, 110, 103, 101, 32, 0, 1, 115, 21, 2, 101, 110, 110, 0, 1, 115, 97, 97, 108, 112, 2, 101, 114, 17, 67, 0, 1, 115, 97, 118, 0, 1, 115, 105, 101, 108, 118, 0, 1, 115, 105, 109, 0, 1, 115, 107, 108, 111, 118, 0, 1, 115, 107, 121, 108, 2, 97, 97, 17, 67, 0, 1, 115, 110, 101, 0, 1, 115, 111, 108, 0, 1, 115, 114, 101, 0, 1, 116, 2, 97, 97, 114, 0, 1, 116, 2, 97, 116, 0, 1, 116, 17, 65, 11, 0, 1, 116, 21, 2, 97, 110, 100, 0, 1, 116, 21, 2, 105, 101, 0, 1, 116, 21, 2, 121, 0, 1, 116, 101, 111, 0, 1, 116, 105, 0, 1, 116, 110, 2, 17, 65, 0, 1, 116, 114, 97, 119, 115, 0, 1, 116, 117, 17, 67, 0, 1, 116, 117, 111, 0, 2, 101, 115, 101, 32, 0, 2, 121, 115, 0, 97, 116, 2, 119, 111, 110, 100, 3, 84, 2, 35, 47, 0, 4, 97, 110, 2, 115, 116, 97, 108, 116, 3, 84, 2, 35, 50, 0, 97, 110, 2, 116, 114, 111, 117, 105, 103, 0, 97, 110, 111, 114, 100, 101, 108, 105, 2, 107, 3, 84, 2, 35, 50, 10, 110, 34, 72, 13, 55, 13, 0, 97, 108, 2, 107, 117, 114, 101, 3, 84, 2, 35, 55, 0, 97, 110, 107, 101, 108, 2, 109, 111, 101, 100, 3, 84, 2, 35, 68, 49, 13, 55, 0, 111, 101, 2, 115, 116, 121, 110, 3, 84, 2, 40, 0, 111, 108, 2, 118, 105, 110, 3, 84, 2, 110, 55, 0, 97, 97, 114, 2, 110, 101, 101, 109, 98, 97, 3, 84, 2, 115, 34, 0, 121, 115, 103, 101, 2, 114, 105, 103, 3, 84, 2, 123, 89, 136, 116, 0, 195, 170, 114, 101, 108, 100, 8, 2, 21, 14, 128, 132, 134, 3, 84, 6, 113, 34, 13, 55, 47, 10, 0, 97, 97, 114, 100, 105, 103, 1, 10, 3, 84, 6, 115, 34, 72, 13, 136, 0, 97, 110, 8, 2, 17, 65, 14, 128, 132, 131, 3, 84, 7, 35, 50, 10, 0, 105, 108, 108, 101, 2, 109, 105, 3, 84, 13, 55, 13, 0, 105, 108, 104, 101, 108, 2, 109, 105, 3, 84, 13, 55, 107, 2, 112, 55, 0, 105, 110, 107, 101, 2, 108, 105, 101, 114, 3, 84, 13, 68, 49, 13, 55, 0, 105, 115, 112, 101, 108, 2, 116, 117, 3, 84, 13, 89, 48, 13, 55, 0, 114, 101, 101, 100, 2, 97, 97, 114, 100, 105, 103, 3, 84, 34, 2, 116, 47, 10, 0, 114, 101, 101, 100, 2, 97, 3, 84, 34, 116, 47, 10, 0, 4, 97, 97, 114, 100, 101, 101, 114, 3, 84, 35, 34, 72, 6, 116, 34, 0, 97, 97, 114, 100, 101, 114, 2, 21, 0, 97, 110, 103, 101, 2, 100, 114, 97, 103, 3, 84, 35, 50, 136, 13, 0, 97, 115, 1, 115, 21, 2, 25, 3, 84, 35, 89, 0, 97, 115, 97, 103, 2, 116, 105, 103, 3, 84, 35, 89, 10, 4, 35, 136, 0, 97, 103, 1, 17, 67, 2, 25, 3, 84, 35, 136, 0, 105, 107, 105, 110, 103, 3, 84, 37, 49, 37, 68, 0, 111, 114, 99, 101, 115, 116, 101, 114, 3, 84, 40, 89, 47, 13, 34, 0, 101, 100, 2, 114, 101, 110, 3, 84, 108, 47, 0, 101, 114, 115, 116, 101, 1, 21, 2, 32, 3, 84, 109, 34, 89, 47, 13, 0, 4, 105, 110, 100, 8, 2, 97, 3, 84, 109, 50, 47, 10, 0, 105, 110, 100, 8, 2, 111, 0, 105, 108, 107, 101, 114, 3, 84, 109, 55, 49, 13, 34, 0, 105, 110, 107, 101, 108, 1, 17, 67, 3, 84, 109, 68, 49, 13, 55, 0, 105, 103, 8, 3, 84, 109, 136, 0, 111, 108, 8, 2, 17, 65, 3, 84, 110, 55, 10, 0, 111, 108, 107, 101, 3, 84, 110, 55, 49, 13, 0, 195, 170, 114, 101, 108, 2, 100, 106, 105, 101, 3, 84, 113, 34, 13, 55, 0, 195, 170, 114, 101, 108, 100, 119, 3, 84, 113, 34, 13, 55, 47, 84, 0, 195, 170, 114, 101, 108, 100, 101, 2, 32, 3, 84, 113, 34, 13, 55, 72, 13, 0, 4, 97, 1, 21, 2, 32, 24, 3, 84, 115, 0, 97, 2, 115, 112, 111, 114, 101, 0, 97, 2, 118, 111, 108, 0, 97, 2, 118, 114, 97, 103, 0, 97, 8, 2, 98, 111, 0, 97, 8, 2, 119, 121, 0, 97, 97, 114, 1, 107, 3, 84, 115, 34, 0, 4, 97, 114, 101, 1, 107, 21, 3, 84, 115, 34, 13, 0, 97, 114, 101, 1, 115, 21, 0, 97, 114, 101, 1, 116, 2, 25, 0, 97, 97, 114, 116, 115, 1, 17, 67, 3, 84, 115, 34, 47, 89, 0, 97, 116, 101, 114, 1, 107, 21, 3, 84, 115, 47, 13, 34, 0, 97, 112, 101, 110, 3, 84, 115, 48, 13, 50, 0, 111, 111, 114, 100, 2, 97, 3, 84, 117, 34, 47, 10, 0, 111, 111, 114, 100, 101, 3, 84, 117, 34, 72, 13, 0, 111, 110, 105, 110, 103, 1, 17, 67, 21, 3, 84, 117, 50, 13, 68, 0, 111, 111, 110, 103, 101, 119, 101, 115, 3, 84, 117, 50, 136, 13, 84, 108, 89, 0, 121, 107, 1, 115, 10, 3, 84, 123, 49, 0, 121, 110, 107, 101, 108, 2, 100, 101, 114, 3, 84, 123, 50, 49, 112, 55, 0, 101, 110, 115, 1, 107, 117, 108, 3, 84, 134, 50, 89, 0, 7, 6, 120, 0, 2, 120, 3, 0, 104, 111, 115, 97, 3, 49, 7, 131, 89, 35, 0, 3, 49, 89, 0, 101, 110, 2, 111, 3, 88, 2, 108, 50, 0, 7, 6, 121, 0, 1, 112, 112, 97, 107, 115, 2, 32, 3, 2, 123, 0, 1, 17, 67, 11, 2, 32, 3, 21, 0, 111, 114, 107, 3, 57, 6, 131, 49, 0, 3, 123, 0, 115, 116, 101, 114, 114, 101, 2, 108, 105, 110, 3, 123, 89, 47, 13, 34, 116, 0, 7, 6, 122, 0, 2, 122, 3, 0, 3, 88, 0, 97, 109, 98, 101, 115, 105, 3, 88, 2, 35, 65, 71, 116, 89, 2, 37, 0, 101, 98, 114, 97, 3, 88, 116, 71, 34, 35, 0, 1, 116, 3, 89, 0, 7, 6, 206, 0, 4, 172, 3, 6, 35, 55, 83, 35, 10, 0, 177, 0, 4, 173, 3, 6, 108, 48, 89, 37, 55, 110, 50, 10, 0, 181, 0, 191, 3, 6, 110, 65, 37, 49, 34, 110, 50, 10, 0, 4, 174, 3, 6, 116, 47, 35, 10, 0, 183, 0, 4, 175, 3, 37, 6, 117, 47, 35, 10, 0, 185, 0, 186, 3, 49, 6, 35, 48, 35, 10, 0, 190, 3, 49, 89, 6, 37, 10, 0, 189, 3, 50, 6, 118, 12, 10, 0, 187, 3, 55, 6, 35, 65, 71, 72, 35, 10, 0, 188, 3, 65, 6, 118, 12, 10, 0, 178, 3, 71, 6, 116, 47, 35, 10, 0, 180, 3, 72, 6, 112, 55, 47, 35, 10, 0, 179, 3, 81, 6, 35, 65, 35, 10, 0, 184, 3, 87, 6, 116, 47, 35, 10, 0, 182, 3, 88, 6, 116, 47, 35, 10, 0, 7, 6, 207, 0, 4, 133, 3, 6, 40, 48, 89, 37, 55, 110, 50, 10, 0, 141, 0, 140, 3, 6, 110, 65, 37, 49, 34, 110, 50, 10, 0, 129, 3, 34, 6, 117, 10, 0, 132, 3, 47, 6, 129, 10, 0, 128, 3, 48, 6, 37, 10, 0, 136, 3, 48, 89, 6, 37, 10, 0, 134, 3, 83, 6, 37, 10, 0, 4, 130, 3, 89, 6, 37, 81, 65, 35, 10, 0, 131, 0, 135, 3, 101, 6, 37, 10, 0, 4, 137, 3, 117, 65, 6, 116, 136, 35, 10, 0, 142, 0, 7, 6, 0, 33, 1, 19, 3, 0, 195, 175, 108, 108, 117, 2, 115, 116, 3, 2, 37, 55, 2, 111, 0, 39, 116, 106, 105, 101, 1, 21, 3, 2, 37, 80, 37, 0, 195, 175, 115, 111, 108, 3, 2, 37, 89, 2, 40, 55, 0, 195, 175, 2, 110, 17, 67, 3, 6, 109, 0, 195, 169, 107, 1, 25, 2, 32, 3, 6, 112, 49, 0, 195, 170, 114, 2, 32, 3, 7, 113, 34, 0, 195, 170, 114, 101, 2, 32, 3, 7, 113, 34, 13, 0, 195, 161, 1, 17, 67, 2, 17, 67, 17, 65, 3, 7, 115, 0, 33, 3, 9, 123, 47, 34, 40, 48, 9, 0, 4, 45, 1, 32, 17, 65, 2, 32, 15, 3, 10, 0, 45, 1, 32, 17, 67, 2, 32, 15, 0, 4, 195, 171, 2, 116, 101, 105, 116, 3, 13, 0, 195, 175, 2, 110, 115, 112, 0, 195, 175, 2, 110, 116, 0, 201, 153, 0, 195, 175, 110, 107, 97, 114, 110, 2, 17, 65, 3, 13, 68, 49, 2, 35, 34, 50, 0, 195, 177, 3, 21, 101, 115, 0, 195, 161, 1, 25, 2, 17, 67, 25, 3, 26, 35, 0, 195, 161, 108, 108, 101, 2, 25, 3, 26, 35, 55, 13, 0, 195, 179, 195, 169, 3, 26, 40, 0, 195, 169, 1, 25, 2, 17, 67, 25, 3, 26, 108, 0, 195, 179, 1, 25, 2, 17, 67, 25, 3, 26, 110, 0, 195, 186, 1, 25, 2, 17, 67, 25, 3, 26, 111, 0, 195, 169, 107, 2, 32, 3, 26, 112, 49, 0, 195, 161, 195, 161, 3, 26, 115, 0, 195, 169, 195, 169, 3, 26, 116, 0, 195, 179, 195, 179, 3, 26, 117, 0, 195, 179, 195, 186, 3, 26, 120, 0, 195, 189, 3, 26, 123, 0, 195, 179, 195, 179, 105, 3, 26, 125, 0, 195, 169, 195, 186, 3, 26, 128, 0, 195, 175, 103, 110, 111, 114, 101, 101, 114, 3, 37, 136, 50, 40, 34, 6, 116, 34, 0, 45, 8, 32, 2, 32, 15, 3, 65, 37, 50, 111, 89, 0, 36, 3, 72, 110, 55, 13, 34, 0, 39, 115, 1, 21, 2, 14, 128, 128, 130, 3, 89, 0, 195, 168, 8, 17, 67, 2, 32, 3, 108, 0, 195, 187, 101, 3, 111, 12, 13, 0, 195, 171, 1, 101, 103, 2, 114, 102, 3, 112, 0, 195, 170, 2, 114, 3, 113, 0, 195, 170, 101, 114, 1, 108, 3, 113, 13, 34, 0, 195, 170, 114, 1, 107, 115, 2, 12, 3, 113, 34, 0, 195, 170, 114, 101, 1, 98, 2, 32, 3, 113, 34, 13, 0, 195, 170, 3, 130, 0, 195, 180, 3, 131, 0, 195, 174, 101, 3, 132, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts1 = FileInMemory_createWithData (81297, reinterpret_cast (&espeakdata_dicts1_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/af_dict", U"af"); Collection_addItem (me.peek(), espeakdata_dicts1.transfer()); static unsigned char espeakdata_dicts2_data[1351] = { 0, 4, 0, 0, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 201, 148, 0, 3, 109, 0, 7, 6, 201, 155, 0, 3, 108, 0, 7, 6, 97, 0, 3, 35, 0, 7, 6, 98, 0, 3, 71, 0, 7, 6, 99, 0, 3, 49, 0, 4, 2, 101, 3, 89, 0, 2, 105, 0, 7, 6, 100, 0, 3, 72, 0, 119, 3, 75, 0, 119, 2, 105, 3, 77, 0, 7, 6, 101, 0, 3, 36, 0, 7, 6, 102, 0, 3, 83, 0, 7, 6, 103, 0, 121, 3, 72, 94, 0, 3, 81, 0, 7, 6, 104, 0, 4, 2, 105, 3, 99, 0, 121, 0, 119, 2, 105, 3, 99, 58, 0, 3, 107, 0, 7, 6, 105, 0, 3, 37, 0, 7, 6, 106, 0, 3, 75, 0, 7, 6, 107, 0, 3, 49, 0, 121, 3, 78, 0, 7, 6, 108, 0, 3, 55, 0, 7, 6, 109, 0, 3, 65, 0, 7, 6, 110, 0, 3, 50, 0, 4, 103, 2, 105, 3, 67, 0, 106, 0, 119, 2, 105, 0, 4, 110, 121, 2, 105, 3, 67, 12, 0, 121, 2, 105, 0, 2, 107, 3, 68, 0, 103, 3, 68, 12, 0, 119, 3, 68, 12, 58, 0, 7, 6, 111, 0, 3, 39, 0, 7, 6, 112, 0, 3, 48, 0, 7, 6, 113, 0, 3, 49, 0, 117, 3, 49, 58, 0, 7, 6, 114, 0, 3, 51, 0, 7, 6, 115, 0, 3, 89, 0, 7, 6, 116, 0, 3, 47, 0, 2, 105, 3, 47, 99, 0, 7, 6, 117, 0, 3, 40, 0, 7, 6, 118, 0, 3, 84, 0, 7, 6, 119, 0, 3, 58, 0, 7, 6, 120, 0, 3, 49, 89, 0, 8, 3, 88, 0, 7, 6, 121, 0, 1, 25, 2, 25, 3, 37, 0, 3, 57, 0, 7, 6, 122, 0, 3, 88, 0, 7, 6, 0, 36, 3, 72, 109, 55, 35, 51, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts2 = FileInMemory_createWithData (1350, reinterpret_cast (&espeakdata_dicts2_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/ak_dict", U"ak"); Collection_addItem (me.peek(), espeakdata_dicts2.transfer()); static unsigned char espeakdata_dicts3_data[3335] = { 0, 4, 0, 0, 149, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 1, 37, 48, 13, 34, 89, 6, 13, 50, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 4, 16, 20, 10, 50, 6, 13, 110, 108, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 3, 225, 141, 164, 72, 6, 108, 34, 108, 82, 108, 89, 13, 34, 13, 88, 0, 0, 20, 3, 225, 141, 167, 110, 6, 108, 57, 35, 112, 36, 65, 108, 55, 108, 49, 108, 47, 0, 0, 0, 0, 0, 18, 3, 225, 141, 163, 50, 6, 13, 110, 13, 55, 35, 89, 13, 34, 13, 88, 0, 0, 18, 3, 225, 141, 162, 19, 6, 35, 34, 35, 47, 108, 50, 13, 110, 108, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 51, 88, 89, 35, 55, 6, 35, 89, 35, 0, 0, 11, 3, 95, 48, 67, 65, 6, 13, 47, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 49, 48, 6, 19, 35, 89, 89, 108, 34, 0, 0, 0, 17, 3, 95, 49, 50, 6, 19, 35, 89, 34, 35, 6, 40, 55, 13, 47, 0, 0, 0, 0, 0, 0, 0, 10, 3, 95, 55, 88, 89, 13, 71, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 49, 88, 19, 35, 89, 34, 6, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 95, 50, 88, 107, 35, 57, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 52, 88, 19, 35, 34, 71, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 53, 88, 107, 35, 65, 89, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 54, 88, 89, 37, 55, 89, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 56, 88, 89, 13, 65, 6, 35, 50, 57, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 57, 88, 88, 13, 110, 6, 13, 50, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 48, 77, 50, 65, 6, 37, 55, 108, 39, 50, 0, 0, 14, 4, 95, 48, 77, 51, 71, 6, 37, 55, 108, 39, 50, 0, 0, 0, 11, 4, 95, 48, 77, 49, 91, 6, 37, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 2, 95, 51, 89, 6, 39, 89, 47, 0, 0, 11, 2, 95, 50, 107, 6, 40, 55, 13, 47, 0, 0, 10, 2, 95, 49, 6, 19, 35, 50, 72, 0, 0, 10, 2, 95, 48, 88, 6, 36, 34, 39, 0, 0, 11, 2, 95, 55, 89, 6, 13, 71, 35, 47, 0, 0, 13, 2, 95, 54, 89, 6, 108, 72, 12, 108, 89, 47, 0, 0, 13, 2, 95, 53, 6, 19, 35, 65, 65, 108, 89, 47, 0, 0, 11, 2, 95, 52, 6, 19, 35, 34, 35, 47, 0, 0, 0, 0, 11, 2, 95, 57, 88, 6, 13, 110, 13, 67, 0, 0, 12, 2, 95, 56, 89, 6, 108, 65, 108, 50, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 225, 136, 0, 173, 1, 21, 2, 32, 3, 34, 0, 168, 3, 34, 13, 0, 171, 3, 34, 35, 0, 172, 3, 34, 36, 0, 170, 3, 34, 37, 0, 174, 3, 34, 39, 0, 169, 3, 34, 40, 0, 175, 3, 34, 58, 35, 0, 173, 3, 34, 108, 0, 141, 1, 21, 2, 32, 3, 55, 0, 136, 3, 55, 13, 0, 139, 3, 55, 35, 0, 140, 3, 55, 36, 0, 138, 3, 55, 37, 0, 142, 3, 55, 39, 0, 137, 3, 55, 40, 0, 143, 3, 55, 40, 35, 0, 141, 3, 55, 108, 0, 157, 1, 21, 2, 32, 3, 65, 0, 152, 3, 65, 13, 0, 155, 3, 65, 35, 0, 156, 3, 65, 36, 0, 154, 3, 65, 37, 0, 158, 3, 65, 39, 0, 153, 3, 65, 40, 0, 159, 3, 65, 58, 35, 0, 157, 3, 65, 108, 0, 4, 165, 1, 21, 2, 32, 3, 89, 0, 181, 1, 21, 2, 32, 0, 4, 160, 3, 89, 13, 0, 176, 0, 4, 163, 3, 89, 35, 0, 179, 0, 4, 164, 3, 89, 36, 0, 180, 0, 4, 162, 3, 89, 37, 0, 178, 0, 4, 166, 3, 89, 39, 0, 182, 0, 4, 161, 3, 89, 40, 0, 177, 0, 4, 167, 3, 89, 58, 35, 0, 183, 0, 4, 165, 3, 89, 108, 0, 181, 0, 189, 1, 21, 2, 32, 3, 91, 0, 184, 3, 91, 13, 0, 187, 3, 91, 35, 0, 188, 3, 91, 36, 0, 186, 3, 91, 37, 0, 190, 3, 91, 39, 0, 185, 3, 91, 40, 0, 191, 3, 91, 58, 35, 0, 189, 3, 91, 108, 0, 4, 133, 1, 21, 2, 32, 3, 101, 0, 149, 1, 21, 2, 32, 0, 4, 128, 3, 107, 35, 0, 131, 0, 144, 0, 147, 0, 4, 132, 3, 107, 36, 0, 148, 0, 4, 130, 3, 107, 37, 0, 146, 0, 4, 134, 3, 107, 39, 0, 150, 0, 4, 129, 3, 107, 40, 0, 145, 0, 151, 3, 107, 58, 35, 0, 4, 133, 3, 107, 108, 0, 149, 0, 7, 6, 225, 137, 0, 181, 1, 21, 2, 32, 3, 47, 0, 176, 3, 47, 13, 0, 179, 3, 47, 35, 0, 180, 3, 47, 36, 0, 178, 3, 47, 37, 0, 182, 3, 47, 39, 0, 177, 3, 47, 40, 0, 183, 3, 47, 58, 35, 0, 181, 3, 47, 108, 0, 165, 1, 21, 2, 32, 3, 71, 0, 160, 3, 71, 13, 0, 163, 3, 71, 35, 0, 164, 3, 71, 36, 0, 162, 3, 71, 37, 0, 166, 3, 71, 39, 0, 161, 3, 71, 40, 0, 167, 3, 71, 58, 35, 0, 165, 3, 71, 108, 0, 189, 1, 21, 2, 32, 3, 76, 0, 184, 3, 76, 13, 0, 187, 3, 76, 35, 0, 188, 3, 76, 36, 0, 186, 3, 76, 37, 0, 190, 3, 76, 39, 0, 185, 3, 76, 40, 0, 191, 3, 76, 58, 35, 0, 189, 3, 76, 108, 0, 173, 1, 21, 2, 32, 3, 84, 0, 168, 3, 84, 13, 0, 171, 3, 84, 35, 0, 172, 3, 84, 36, 0, 170, 3, 84, 37, 0, 174, 3, 84, 39, 0, 169, 3, 84, 40, 0, 175, 3, 84, 58, 35, 0, 173, 3, 84, 108, 0, 133, 1, 21, 2, 32, 3, 112, 0, 128, 3, 112, 13, 0, 131, 3, 112, 35, 0, 132, 3, 112, 36, 0, 130, 3, 112, 37, 0, 134, 3, 112, 39, 0, 129, 3, 112, 40, 0, 141, 1, 21, 2, 32, 3, 112, 58, 0, 136, 3, 112, 58, 13, 0, 139, 3, 112, 58, 35, 0, 140, 3, 112, 58, 36, 0, 138, 3, 112, 58, 37, 0, 141, 3, 112, 58, 108, 0, 133, 3, 112, 108, 0, 7, 6, 225, 138, 0, 167, 3, 19, 13, 0, 4, 160, 3, 19, 35, 0, 163, 0, 164, 3, 19, 36, 0, 162, 3, 19, 37, 0, 166, 3, 19, 39, 0, 161, 3, 19, 40, 0, 165, 3, 19, 108, 0, 173, 1, 21, 2, 32, 3, 49, 0, 168, 3, 49, 13, 0, 171, 3, 49, 35, 0, 172, 3, 49, 36, 0, 170, 3, 49, 37, 0, 174, 3, 49, 39, 0, 169, 3, 49, 40, 0, 181, 1, 21, 2, 32, 3, 49, 58, 0, 176, 3, 49, 58, 13, 0, 179, 3, 49, 58, 35, 0, 180, 3, 49, 58, 36, 0, 178, 3, 49, 58, 37, 0, 181, 3, 49, 58, 108, 0, 173, 3, 49, 108, 0, 149, 1, 21, 2, 32, 3, 50, 0, 144, 3, 50, 13, 0, 147, 3, 50, 35, 0, 148, 3, 50, 36, 0, 146, 3, 50, 37, 0, 150, 3, 50, 39, 0, 145, 3, 50, 40, 0, 151, 3, 50, 58, 35, 0, 149, 3, 50, 108, 0, 157, 1, 21, 2, 32, 3, 67, 0, 152, 3, 67, 13, 0, 155, 3, 67, 35, 0, 156, 3, 67, 36, 0, 154, 3, 67, 37, 0, 158, 3, 67, 39, 0, 153, 3, 67, 40, 0, 159, 3, 67, 58, 35, 0, 157, 3, 67, 108, 0, 4, 133, 1, 21, 2, 32, 3, 101, 0, 189, 1, 21, 2, 32, 0, 184, 3, 107, 13, 0, 4, 128, 3, 107, 35, 0, 131, 0, 187, 0, 4, 132, 3, 107, 36, 0, 188, 0, 4, 130, 3, 107, 37, 0, 186, 0, 4, 134, 3, 107, 39, 0, 190, 0, 4, 129, 3, 107, 40, 0, 185, 0, 141, 1, 21, 2, 32, 3, 107, 58, 0, 136, 3, 107, 58, 13, 0, 139, 3, 107, 58, 35, 0, 140, 3, 107, 58, 36, 0, 138, 3, 107, 58, 37, 0, 141, 3, 107, 58, 108, 0, 4, 133, 3, 107, 108, 0, 189, 0, 7, 6, 225, 139, 0, 4, 144, 3, 19, 35, 0, 147, 0, 148, 3, 19, 36, 0, 146, 3, 19, 37, 0, 150, 3, 19, 39, 0, 145, 3, 19, 40, 0, 149, 3, 19, 108, 0, 173, 1, 21, 2, 32, 3, 57, 0, 168, 3, 57, 13, 0, 171, 3, 57, 35, 0, 172, 3, 57, 36, 0, 170, 3, 57, 37, 0, 174, 3, 57, 39, 0, 169, 3, 57, 40, 0, 173, 3, 57, 108, 0, 141, 1, 21, 2, 32, 3, 58, 0, 136, 3, 58, 13, 0, 139, 3, 58, 35, 0, 140, 3, 58, 36, 0, 138, 3, 58, 37, 0, 142, 3, 58, 39, 0, 137, 3, 58, 40, 0, 141, 3, 58, 108, 0, 181, 1, 21, 2, 32, 3, 72, 0, 176, 3, 72, 13, 0, 179, 3, 72, 35, 0, 180, 3, 72, 36, 0, 178, 3, 72, 37, 0, 182, 3, 72, 39, 0, 177, 3, 72, 40, 0, 183, 3, 72, 58, 35, 0, 189, 1, 21, 2, 32, 3, 72, 72, 0, 184, 3, 72, 72, 13, 0, 187, 3, 72, 72, 35, 0, 188, 3, 72, 72, 36, 0, 186, 3, 72, 72, 37, 0, 190, 3, 72, 72, 39, 0, 185, 3, 72, 72, 40, 0, 191, 3, 72, 72, 58, 35, 0, 189, 3, 72, 72, 108, 0, 181, 3, 72, 108, 0, 157, 1, 21, 2, 32, 3, 88, 0, 152, 3, 88, 13, 0, 155, 3, 88, 35, 0, 156, 3, 88, 36, 0, 154, 3, 88, 37, 0, 158, 3, 88, 39, 0, 153, 3, 88, 40, 0, 159, 3, 88, 58, 35, 0, 157, 3, 88, 108, 0, 165, 1, 21, 2, 32, 3, 90, 0, 160, 3, 90, 13, 0, 163, 3, 90, 35, 0, 164, 3, 90, 36, 0, 162, 3, 90, 37, 0, 166, 3, 90, 39, 0, 161, 3, 90, 40, 0, 167, 3, 90, 58, 35, 0, 165, 3, 90, 108, 0, 133, 1, 21, 2, 32, 3, 107, 58, 0, 128, 3, 107, 58, 13, 0, 131, 3, 107, 58, 35, 0, 132, 3, 107, 58, 36, 0, 130, 3, 107, 58, 37, 0, 133, 3, 107, 58, 108, 0, 7, 6, 225, 140, 0, 189, 1, 21, 2, 32, 3, 47, 89, 0, 184, 3, 47, 89, 13, 0, 187, 3, 47, 89, 35, 0, 188, 3, 47, 89, 36, 0, 186, 3, 47, 89, 37, 0, 190, 3, 47, 89, 39, 0, 185, 3, 47, 89, 40, 0, 191, 3, 47, 89, 58, 35, 0, 189, 3, 47, 89, 108, 0, 157, 1, 21, 2, 32, 3, 68, 0, 152, 3, 68, 13, 0, 155, 3, 68, 35, 0, 156, 3, 68, 36, 0, 154, 3, 68, 37, 0, 158, 3, 68, 39, 0, 153, 3, 68, 40, 0, 157, 3, 68, 108, 0, 133, 1, 21, 2, 32, 3, 75, 0, 128, 3, 75, 13, 0, 131, 3, 75, 35, 0, 132, 3, 75, 36, 0, 130, 3, 75, 37, 0, 134, 3, 75, 39, 0, 129, 3, 75, 40, 0, 135, 3, 75, 58, 35, 0, 133, 3, 75, 108, 0, 141, 1, 21, 2, 32, 3, 81, 0, 136, 3, 81, 13, 0, 139, 3, 81, 35, 0, 140, 3, 81, 36, 0, 138, 3, 81, 37, 0, 142, 3, 81, 39, 0, 137, 3, 81, 40, 0, 149, 1, 21, 2, 32, 3, 81, 58, 0, 144, 3, 81, 58, 13, 0, 147, 3, 81, 58, 35, 0, 148, 3, 81, 58, 36, 0, 146, 3, 81, 58, 37, 0, 149, 3, 81, 58, 108, 0, 141, 3, 81, 108, 0, 181, 1, 21, 2, 32, 3, 109, 0, 176, 3, 109, 13, 0, 179, 3, 109, 35, 0, 180, 3, 109, 36, 0, 178, 3, 109, 37, 0, 182, 3, 109, 39, 0, 177, 3, 109, 40, 0, 183, 3, 109, 58, 35, 0, 181, 3, 109, 108, 0, 165, 1, 21, 2, 32, 3, 110, 0, 160, 3, 110, 13, 0, 163, 3, 110, 35, 0, 164, 3, 110, 36, 0, 162, 3, 110, 37, 0, 166, 3, 110, 39, 0, 161, 3, 110, 40, 0, 167, 3, 110, 58, 35, 0, 165, 3, 110, 108, 0, 173, 1, 21, 2, 32, 3, 111, 0, 168, 3, 111, 13, 0, 171, 3, 111, 35, 0, 172, 3, 111, 36, 0, 170, 3, 111, 37, 0, 174, 3, 111, 39, 0, 169, 3, 111, 40, 0, 175, 3, 111, 58, 35, 0, 173, 3, 111, 108, 0, 7, 6, 225, 141, 0, 152, 3, 34, 57, 13, 0, 133, 1, 21, 2, 32, 3, 47, 89, 0, 128, 3, 47, 89, 13, 0, 131, 3, 47, 89, 35, 0, 132, 3, 47, 89, 36, 0, 130, 3, 47, 89, 37, 0, 134, 3, 47, 89, 39, 0, 129, 3, 47, 89, 40, 0, 133, 3, 47, 89, 108, 0, 149, 1, 21, 2, 32, 3, 48, 0, 144, 3, 48, 13, 0, 147, 3, 48, 35, 0, 148, 3, 48, 36, 0, 146, 3, 48, 37, 0, 150, 3, 48, 39, 0, 145, 3, 48, 40, 0, 151, 3, 48, 58, 35, 0, 149, 3, 48, 108, 0, 153, 3, 65, 57, 13, 0, 141, 1, 21, 2, 32, 3, 83, 0, 136, 3, 83, 13, 0, 139, 3, 83, 35, 0, 140, 3, 83, 36, 0, 138, 3, 83, 37, 0, 142, 3, 83, 39, 0, 137, 3, 83, 40, 0, 154, 3, 83, 57, 13, 0, 143, 3, 83, 58, 35, 0, 141, 3, 83, 108, 0, 7, 6, 0, 36, 3, 72, 39, 55, 35, 34, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts3 = FileInMemory_createWithData (3334, reinterpret_cast (&espeakdata_dicts3_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/am_dict", U"am"); Collection_addItem (me.peek(), espeakdata_dicts3.transfer()); static unsigned char espeakdata_dicts4_data[1813] = { 0, 4, 0, 0, 15, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 8, 71, 36, 0, 0, 0, 0, 0, 6, 65, 12, 75, 36, 0, 0, 0, 0, 0, 6, 65, 16, 72, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 24, 83, 36, 0, 0, 0, 0, 0, 6, 65, 28, 79, 36, 0, 0, 0, 0, 0, 6, 65, 32, 107, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 40, 90, 36, 0, 0, 0, 0, 0, 6, 65, 44, 49, 35, 0, 0, 0, 0, 0, 6, 65, 48, 36, 55, 0, 0, 0, 0, 0, 6, 65, 52, 36, 65, 0, 0, 0, 0, 0, 6, 65, 56, 36, 50, 0, 0, 0, 6, 195, 76, 150, 128, 76, 0, 0, 4, 193, 60, 76, 0, 0, 0, 0, 6, 65, 64, 48, 36, 0, 0, 0, 0, 0, 6, 65, 68, 81, 36, 0, 0, 0, 0, 0, 6, 65, 72, 36, 51, 0, 0, 0, 0, 0, 6, 65, 76, 89, 36, 0, 0, 0, 0, 0, 6, 65, 80, 47, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 88, 84, 36, 0, 0, 0, 0, 0, 12, 65, 92, 72, 40, 71, 109, 55, 84, 6, 109, 0, 0, 0, 0, 0, 6, 65, 96, 101, 36, 0, 0, 0, 0, 0, 6, 65, 100, 57, 36, 0, 0, 0, 0, 0, 6, 65, 104, 88, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 132, 19, 201, 153, 14, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 132, 13, 201, 153, 14, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 4, 95, 4, 16, 20, 10, 84, 37, 51, 81, 4, 112, 55, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 19, 201, 153, 14, 9, 14, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 60, 227, 1, 72, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 51, 88, 39, 47, 6, 40, 88, 0, 0, 10, 3, 95, 48, 67, 57, 6, 112, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 55, 88, 57, 36, 47, 65, 6, 37, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 3, 95, 49, 88, 6, 39, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 50, 88, 37, 57, 37, 51, 65, 6, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 76, 150, 137, 56, 76, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 52, 88, 81, 6, 13, 51, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 53, 88, 127, 55, 55, 6, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 54, 88, 35, 55, 47, 65, 6, 13, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 13, 201, 153, 14, 9, 13, 76, 0, 0, 0, 0, 0, 0, 13, 3, 95, 56, 88, 89, 127, 99, 89, 6, 127, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 57, 88, 72, 39, 101, 89, 6, 35, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 48, 77, 50, 65, 37, 55, 57, 6, 39, 50, 0, 0, 15, 4, 95, 48, 77, 51, 65, 37, 55, 57, 6, 35, 51, 72, 0, 0, 0, 11, 4, 95, 48, 77, 49, 65, 6, 37, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 8, 150, 137, 52, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 60, 229, 78, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 196, 159, 100, 36, 0, 7, 2, 195, 167, 76, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 197, 159, 91, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 136, 15, 14, 12, 1, 18, 196, 177, 14, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 2, 95, 15, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 2, 95, 51, 6, 112, 76, 0, 0, 9, 2, 95, 50, 37, 80, 6, 37, 0, 0, 9, 2, 95, 49, 71, 6, 37, 51, 0, 0, 11, 2, 95, 48, 89, 13, 83, 6, 13, 51, 0, 0, 11, 2, 95, 55, 57, 36, 72, 72, 6, 37, 0, 0, 10, 2, 95, 54, 35, 55, 47, 6, 13, 0, 0, 9, 2, 95, 53, 71, 6, 36, 91, 0, 0, 10, 2, 95, 52, 72, 6, 125, 51, 72, 0, 0, 0, 0, 12, 2, 95, 57, 72, 39, 81, 81, 6, 40, 88, 0, 0, 12, 2, 95, 56, 89, 127, 99, 80, 6, 37, 88, 0, 0, 0, 0, 0, 0, 6, 195, 8, 150, 128, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 167, 0, 3, 76, 0, 7, 6, 195, 182, 0, 3, 125, 0, 7, 6, 195, 188, 0, 3, 112, 0, 7, 6, 196, 159, 0, 3, 100, 0, 7, 6, 196, 177, 0, 3, 13, 0, 7, 6, 197, 159, 0, 3, 91, 0, 7, 6, 201, 153, 0, 3, 127, 0, 7, 6, 97, 0, 3, 35, 0, 7, 6, 98, 0, 3, 71, 0, 7, 6, 99, 0, 3, 75, 0, 7, 6, 100, 0, 3, 72, 0, 7, 6, 101, 0, 3, 36, 0, 7, 6, 102, 0, 3, 83, 0, 7, 6, 103, 0, 3, 79, 0, 7, 6, 104, 0, 3, 107, 0, 7, 6, 105, 0, 3, 37, 0, 7, 6, 106, 0, 3, 90, 0, 7, 6, 107, 0, 3, 80, 0, 2, 25, 3, 99, 0, 7, 6, 108, 0, 3, 55, 0, 7, 6, 109, 0, 3, 65, 0, 7, 6, 110, 0, 3, 50, 0, 7, 6, 111, 0, 3, 39, 0, 7, 6, 112, 0, 3, 48, 0, 7, 6, 113, 0, 3, 81, 0, 7, 6, 114, 0, 1, 17, 65, 2, 17, 65, 3, 16, 0, 3, 51, 0, 7, 6, 115, 0, 3, 89, 0, 7, 6, 116, 0, 3, 47, 0, 7, 6, 117, 0, 3, 40, 0, 7, 6, 118, 0, 3, 84, 0, 7, 6, 119, 0, 3, 58, 0, 7, 6, 120, 0, 3, 101, 0, 7, 6, 121, 0, 3, 57, 0, 7, 6, 122, 0, 3, 88, 0, 7, 6, 0, 195, 164, 3, 127, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts4 = FileInMemory_createWithData (1812, reinterpret_cast (&espeakdata_dicts4_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/az_dict", U"az"); Collection_addItem (me.peek(), espeakdata_dicts4.transfer()); static unsigned char espeakdata_dicts5_data[26955] = { 0, 4, 0, 0, 170, 99, 0, 0, 8, 197, 64, 20, 144, 245, 48, 66, 8, 197, 55, 166, 81, 81, 48, 66, 8, 197, 50, 226, 80, 81, 48, 67, 8, 197, 47, 52, 209, 173, 48, 66, 0, 9, 198, 88, 148, 147, 60, 195, 196, 67, 9, 198, 87, 163, 107, 60, 195, 196, 68, 9, 198, 25, 50, 77, 60, 195, 196, 68, 9, 198, 168, 139, 211, 60, 195, 196, 68, 0, 8, 197, 52, 20, 203, 5, 0, 66, 0, 6, 195, 79, 128, 72, 66, 7, 196, 175, 99, 137, 52, 67, 0, 7, 196, 74, 49, 84, 68, 66, 7, 196, 67, 97, 139, 76, 66, 7, 196, 65, 27, 137, 12, 65, 8, 197, 66, 148, 58, 5, 48, 67, 7, 196, 8, 244, 212, 100, 66, 0, 5, 193, 4, 72, 23, 8, 197, 149, 18, 75, 5, 48, 67, 6, 195, 75, 160, 74, 66, 12, 201, 68, 17, 73, 60, 68, 65, 52, 245, 115, 70, 6, 195, 48, 98, 250, 65, 9, 198, 47, 161, 73, 60, 195, 196, 68, 9, 198, 17, 16, 85, 60, 195, 196, 67, 0, 17, 66, 5, 0, 35, 48, 35, 34, 47, 35, 65, 6, 36, 50, 47, 0, 24, 6, 195, 5, 0, 89, 66, 0, 6, 195, 148, 204, 192, 66, 10, 199, 197, 36, 6, 45, 63, 65, 76, 68, 0, 7, 196, 73, 67, 37, 56, 66, 7, 196, 20, 115, 227, 56, 66, 7, 196, 212, 81, 170, 48, 67, 0, 6, 65, 8, 71, 13, 0, 8, 197, 64, 193, 130, 24, 160, 66, 0, 9, 198, 77, 27, 210, 67, 212, 192, 66, 9, 198, 73, 52, 65, 76, 97, 0, 66, 9, 198, 197, 36, 201, 77, 68, 192, 67, 9, 198, 24, 50, 237, 37, 4, 192, 67, 0, 0, 11, 200, 84, 148, 248, 5, 51, 204, 60, 64, 69, 0, 7, 65, 12, 84, 13, 0, 14, 4, 193, 12, 23, 8, 197, 77, 18, 66, 60, 160, 66, 8, 197, 73, 94, 207, 36, 80, 67, 6, 195, 67, 211, 202, 66, 6, 195, 244, 99, 0, 66, 8, 197, 10, 188, 2, 232, 80, 67, 0, 9, 198, 73, 52, 73, 88, 236, 64, 66, 6, 195, 67, 100, 47, 66, 9, 198, 52, 193, 139, 60, 222, 192, 67, 9, 198, 44, 243, 80, 61, 36, 192, 66, 9, 198, 14, 52, 147, 24, 204, 64, 67, 0, 0, 6, 195, 14, 251, 177, 67, 0, 12, 65, 16, 81, 39, 72, 6, 37, 50, 35, 0, 25, 9, 198, 47, 19, 193, 67, 160, 83, 69, 8, 197, 22, 196, 209, 199, 176, 67, 8, 197, 168, 36, 65, 87, 48, 67, 0, 6, 195, 74, 170, 87, 66, 9, 198, 64, 17, 73, 100, 21, 128, 67, 0, 6, 195, 73, 179, 64, 72, 9, 198, 16, 20, 147, 216, 227, 205, 67, 0, 17, 4, 95, 100, 112, 116, 10, 117, 38, 6, 35, 64, 39, 10, 37, 15, 0, 6, 195, 75, 9, 237, 67, 7, 196, 20, 146, 229, 76, 66, 7, 196, 173, 114, 115, 236, 68, 0, 6, 65, 20, 72, 13, 0, 8, 197, 25, 99, 204, 61, 48, 67, 0, 9, 198, 77, 18, 80, 76, 149, 128, 66, 0, 9, 198, 188, 99, 79, 17, 16, 85, 68, 0, 7, 196, 74, 210, 219, 52, 66, 6, 195, 69, 64, 177, 66, 0, 4, 193, 24, 72, 9, 198, 32, 20, 207, 99, 2, 75, 66, 8, 197, 19, 3, 215, 36, 80, 67, 0, 9, 198, 73, 15, 19, 60, 222, 192, 67, 9, 198, 53, 67, 133, 105, 66, 192, 66, 9, 198, 140, 50, 193, 20, 114, 96, 65, 6, 195, 47, 138, 7, 66, 0, 6, 195, 79, 133, 8, 66, 0, 7, 196, 75, 22, 6, 92, 66, 6, 195, 75, 19, 197, 66, 12, 201, 64, 243, 9, 76, 99, 73, 17, 27, 211, 69, 0, 6, 65, 28, 90, 13, 0, 8, 197, 52, 105, 78, 60, 192, 67, 6, 195, 22, 180, 238, 66, 0, 6, 195, 24, 180, 111, 66, 0, 0, 0, 7, 195, 45, 16, 74, 72, 23, 6, 65, 32, 88, 13, 0, 8, 197, 45, 68, 82, 189, 48, 66, 9, 198, 45, 22, 196, 157, 16, 83, 67, 8, 197, 44, 243, 85, 245, 48, 66, 8, 197, 20, 98, 239, 5, 48, 67, 0, 9, 198, 72, 19, 79, 72, 59, 64, 67, 9, 198, 64, 244, 240, 92, 155, 64, 68, 6, 195, 4, 81, 147, 66, 0, 10, 199, 67, 100, 198, 45, 63, 65, 76, 68, 6, 195, 176, 107, 192, 67, 6, 195, 147, 97, 64, 66, 0, 11, 1, 35, 72, 6, 37, 38, 36, 95, 0, 27, 6, 195, 91, 161, 109, 66, 6, 195, 36, 81, 173, 67, 6, 195, 11, 19, 205, 66, 0, 5, 193, 36, 72, 8, 8, 197, 69, 77, 213, 60, 32, 67, 8, 197, 66, 145, 68, 159, 208, 65, 9, 198, 24, 179, 6, 45, 50, 75, 67, 9, 198, 20, 241, 13, 5, 50, 75, 67, 8, 197, 16, 197, 16, 25, 112, 66, 0, 13, 1, 37, 48, 34, 39, 117, 6, 36, 50, 47, 0, 27, 9, 198, 64, 243, 6, 13, 177, 64, 67, 6, 195, 44, 157, 83, 66, 0, 16, 67, 73, 52, 64, 89, 47, 34, 6, 35, 50, 37, 117, 35, 0, 24, 6, 1, 38, 21, 0, 10, 6, 195, 60, 140, 192, 66, 6, 195, 46, 252, 192, 66, 6, 195, 18, 220, 192, 66, 0, 6, 195, 129, 102, 209, 66, 7, 196, 197, 62, 228, 76, 67, 0, 6, 65, 40, 37, 0, 72, 8, 197, 160, 61, 140, 60, 64, 67, 6, 195, 4, 90, 82, 66, 0, 6, 195, 77, 18, 115, 66, 9, 198, 66, 148, 198, 45, 36, 192, 66, 6, 195, 44, 22, 115, 66, 0, 15, 1, 42, 88, 84, 36, 88, 72, 6, 37, 76, 49, 35, 0, 27, 0, 8, 196, 67, 208, 69, 36, 72, 23, 9, 1, 43, 48, 55, 40, 89, 0, 27, 9, 198, 84, 244, 221, 60, 163, 0, 66, 6, 195, 77, 18, 125, 66, 9, 198, 65, 62, 207, 22, 180, 238, 68, 0, 6, 65, 44, 49, 13, 0, 8, 197, 88, 207, 79, 86, 224, 67, 8, 197, 73, 60, 56, 37, 32, 67, 8, 197, 16, 194, 87, 239, 16, 67, 8, 197, 16, 16, 186, 23, 16, 67, 0, 4, 129, 45, 8, 9, 198, 52, 22, 113, 224, 148, 128, 68, 9, 198, 44, 20, 11, 60, 222, 192, 67, 9, 198, 189, 50, 68, 236, 242, 128, 68, 0, 6, 195, 221, 3, 204, 66, 6, 195, 157, 16, 68, 66, 0, 8, 196, 35, 160, 69, 36, 72, 23, 21, 1, 47, 50, 35, 49, 64, 6, 39, 50, 36, 50, 35, 15, 76, 36, 34, 47, 4, 35, 0, 7, 196, 165, 15, 83, 236, 67, 7, 196, 68, 17, 73, 188, 67, 6, 195, 60, 34, 61, 66, 7, 196, 54, 226, 115, 236, 68, 7, 196, 52, 100, 198, 244, 67, 6, 195, 5, 82, 89, 66, 0, 6, 65, 48, 55, 13, 0, 8, 197, 69, 178, 248, 37, 32, 67, 6, 195, 31, 2, 86, 66, 8, 197, 188, 177, 147, 119, 208, 67, 0, 9, 198, 24, 193, 139, 79, 97, 64, 67, 6, 195, 18, 219, 211, 66, 9, 198, 8, 241, 15, 72, 201, 192, 67, 0, 10, 199, 66, 209, 179, 76, 243, 15, 16, 69, 10, 199, 52, 100, 198, 244, 243, 15, 16, 69, 9, 198, 24, 66, 80, 78, 3, 177, 66, 0, 0, 6, 65, 52, 65, 13, 0, 8, 197, 11, 161, 140, 25, 80, 67, 8, 197, 5, 68, 144, 81, 96, 65, 0, 6, 195, 91, 163, 111, 66, 6, 195, 64, 241, 147, 66, 0, 9, 198, 91, 99, 143, 17, 16, 85, 67, 9, 198, 76, 148, 15, 17, 16, 85, 67, 9, 198, 65, 91, 87, 17, 16, 85, 66, 9, 198, 66, 209, 143, 17, 16, 85, 68, 9, 198, 48, 148, 207, 17, 16, 85, 67, 9, 198, 47, 164, 207, 17, 16, 85, 67, 9, 198, 25, 51, 143, 17, 16, 85, 67, 0, 7, 196, 83, 97, 193, 40, 67, 7, 196, 55, 0, 71, 236, 67, 0, 6, 65, 56, 50, 13, 0, 8, 197, 72, 19, 79, 80, 176, 67, 8, 197, 52, 18, 14, 36, 176, 66, 8, 197, 8, 241, 15, 54, 224, 67, 0, 6, 195, 176, 243, 123, 67, 6, 195, 46, 244, 243, 66, 0, 0, 6, 195, 244, 146, 0, 66, 0, 8, 197, 85, 180, 147, 108, 176, 66, 9, 198, 64, 197, 19, 177, 16, 83, 67, 8, 197, 32, 96, 200, 24, 176, 66, 9, 198, 232, 148, 147, 177, 16, 83, 68, 0, 16, 1, 61, 36, 15, 34, 6, 35, 84, 50, 39, 15, 50, 4, 35, 0, 9, 198, 68, 18, 13, 37, 38, 204, 65, 0, 0, 7, 196, 97, 65, 20, 56, 66, 9, 198, 73, 54, 203, 51, 130, 82, 67, 7, 196, 72, 98, 233, 76, 66, 6, 195, 75, 160, 85, 66, 7, 196, 67, 102, 9, 76, 65, 7, 196, 44, 245, 70, 196, 67, 7, 196, 236, 100, 201, 44, 67, 9, 198, 24, 81, 140, 12, 18, 146, 65, 6, 195, 23, 186, 153, 66, 0, 11, 1, 64, 49, 55, 6, 39, 65, 71, 35, 0, 6, 65, 64, 48, 13, 0, 6, 195, 76, 153, 78, 66, 9, 198, 60, 47, 79, 76, 243, 123, 69, 8, 197, 10, 242, 209, 81, 48, 66, 0, 10, 198, 64, 243, 70, 28, 85, 0, 72, 23, 6, 195, 92, 153, 83, 66, 6, 195, 54, 193, 147, 66, 6, 195, 28, 157, 83, 66, 0, 9, 198, 64, 243, 9, 17, 16, 85, 67, 10, 199, 189, 50, 80, 240, 100, 201, 44, 69, 0, 6, 195, 91, 161, 141, 66, 9, 198, 74, 48, 224, 56, 245, 110, 68, 7, 196, 145, 89, 76, 196, 67, 7, 196, 36, 131, 211, 224, 67, 0, 6, 65, 68, 34, 13, 0, 8, 197, 84, 243, 11, 51, 208, 66, 8, 197, 73, 69, 76, 119, 208, 66, 9, 198, 64, 98, 210, 36, 209, 147, 67, 0, 13, 202, 73, 179, 211, 25, 129, 146, 76, 60, 9, 44, 67, 6, 195, 66, 227, 211, 66, 0, 6, 195, 222, 132, 192, 66, 0, 7, 196, 88, 22, 73, 100, 66, 7, 196, 20, 105, 74, 48, 66, 0, 7, 65, 72, 89, 13, 0, 14, 4, 193, 72, 23, 6, 195, 79, 137, 78, 66, 8, 197, 47, 160, 77, 24, 192, 67, 0, 9, 198, 172, 49, 133, 80, 180, 192, 67, 0, 0, 6, 195, 75, 0, 83, 66, 7, 196, 67, 176, 193, 32, 66, 7, 196, 60, 35, 15, 16, 66, 6, 195, 12, 20, 173, 66, 0, 6, 65, 76, 47, 13, 0, 8, 197, 91, 179, 70, 51, 16, 67, 8, 197, 80, 94, 142, 36, 176, 65, 8, 197, 79, 192, 148, 103, 48, 67, 8, 197, 68, 19, 65, 34, 240, 67, 8, 197, 47, 19, 213, 184, 208, 67, 8, 197, 44, 21, 24, 80, 176, 65, 0, 9, 198, 67, 100, 201, 212, 64, 72, 68, 6, 195, 53, 72, 211, 66, 9, 198, 55, 50, 83, 247, 17, 0, 66, 9, 198, 22, 113, 133, 192, 146, 192, 66, 0, 6, 195, 73, 49, 128, 72, 0, 7, 196, 66, 147, 15, 52, 66, 7, 196, 44, 241, 212, 88, 66, 0, 5, 193, 80, 72, 23, 8, 197, 12, 100, 246, 19, 48, 67, 0, 9, 198, 73, 62, 198, 61, 34, 248, 68, 0, 9, 198, 128, 165, 198, 67, 109, 69, 68, 9, 198, 77, 22, 194, 227, 109, 69, 68, 0, 7, 196, 95, 21, 250, 196, 65, 6, 195, 85, 77, 145, 66, 11, 200, 73, 58, 80, 76, 243, 73, 95, 16, 68, 7, 196, 73, 51, 201, 44, 66, 7, 196, 212, 83, 205, 236, 67, 7, 196, 9, 67, 29, 204, 66, 0, 6, 65, 84, 83, 13, 0, 9, 198, 74, 84, 201, 73, 50, 75, 67, 9, 198, 47, 53, 198, 72, 156, 251, 69, 9, 198, 24, 180, 147, 238, 67, 147, 67, 0, 9, 198, 75, 162, 207, 84, 17, 0, 67, 9, 198, 64, 20, 209, 39, 165, 128, 67, 0, 10, 199, 84, 244, 253, 25, 15, 83, 236, 69, 9, 198, 84, 244, 207, 17, 16, 85, 67, 9, 198, 79, 179, 79, 17, 16, 85, 67, 9, 198, 20, 99, 79, 17, 16, 85, 67, 0, 9, 198, 77, 18, 66, 82, 67, 0, 67, 0, 6, 65, 88, 101, 13, 0, 6, 195, 34, 99, 202, 66, 0, 9, 198, 80, 194, 88, 56, 146, 192, 65, 9, 198, 76, 111, 70, 76, 146, 192, 68, 9, 198, 65, 16, 83, 192, 146, 192, 65, 0, 10, 199, 20, 99, 21, 199, 162, 84, 52, 67, 0, 7, 196, 80, 128, 134, 44, 66, 11, 200, 77, 18, 66, 4, 74, 78, 36, 176, 66, 11, 200, 73, 60, 3, 25, 36, 206, 36, 176, 65, 7, 196, 220, 53, 143, 32, 66, 7, 196, 44, 244, 204, 204, 66, 6, 195, 34, 99, 197, 66, 0, 30, 1, 92, 39, 71, 34, 6, 35, 47, 50, 35, 15, 50, 35, 49, 64, 6, 39, 50, 36, 50, 35, 15, 76, 36, 34, 47, 4, 35, 0, 6, 65, 92, 117, 13, 0, 8, 197, 76, 240, 143, 18, 240, 67, 8, 197, 216, 208, 143, 36, 80, 67, 12, 201, 68, 17, 73, 61, 49, 150, 56, 146, 192, 69, 12, 201, 65, 34, 86, 224, 20, 207, 48, 241, 0, 69, 8, 197, 64, 145, 147, 25, 48, 67, 8, 197, 64, 20, 139, 168, 192, 66, 8, 197, 140, 142, 142, 36, 176, 65, 8, 197, 140, 78, 206, 36, 176, 65, 8, 197, 44, 19, 66, 81, 16, 66, 8, 197, 19, 98, 14, 36, 176, 66, 8, 197, 8, 18, 179, 25, 48, 67, 8, 197, 4, 87, 229, 57, 48, 67, 0, 9, 198, 77, 27, 210, 67, 212, 252, 67, 9, 198, 44, 20, 207, 48, 146, 192, 67, 6, 195, 15, 1, 151, 66, 0, 12, 1, 94, 49, 39, 55, 6, 37, 71, 49, 35, 0, 0, 6, 195, 78, 146, 61, 66, 0, 14, 4, 95, 49, 77, 49, 99, 37, 55, 6, 35, 72, 35, 0, 6, 65, 96, 76, 13, 0, 8, 197, 76, 96, 134, 103, 192, 67, 8, 197, 69, 70, 67, 25, 48, 66, 6, 195, 55, 62, 150, 66, 8, 197, 44, 22, 109, 61, 48, 67, 6, 195, 8, 31, 0, 66, 0, 10, 198, 36, 131, 70, 28, 85, 0, 72, 23, 20, 4, 95, 49, 77, 50, 36, 72, 6, 37, 50, 15, 65, 37, 55, 37, 6, 39, 50, 0, 9, 198, 91, 99, 137, 45, 223, 64, 67, 9, 198, 72, 16, 143, 77, 223, 64, 67, 9, 198, 47, 19, 198, 45, 27, 192, 68, 9, 198, 17, 27, 197, 60, 219, 192, 67, 0, 21, 4, 95, 49, 77, 51, 36, 72, 6, 37, 50, 15, 65, 37, 55, 37, 6, 35, 34, 72, 0, 10, 199, 48, 109, 82, 24, 185, 78, 76, 68, 0, 7, 196, 91, 181, 42, 52, 67, 7, 196, 84, 146, 9, 44, 66, 7, 196, 76, 97, 6, 48, 66, 7, 196, 74, 81, 73, 204, 67, 7, 196, 64, 240, 143, 40, 66, 7, 196, 197, 37, 12, 196, 67, 0, 6, 65, 100, 91, 13, 0, 12, 201, 47, 53, 251, 76, 208, 74, 73, 63, 64, 66, 8, 197, 13, 178, 19, 244, 64, 66, 8, 197, 9, 67, 5, 60, 64, 66, 0, 6, 195, 18, 99, 211, 66, 0, 0, 7, 196, 61, 49, 39, 244, 65, 7, 196, 244, 145, 49, 180, 68, 0, 7, 65, 104, 91, 47, 13, 0, 8, 197, 21, 16, 68, 80, 224, 66, 8, 197, 212, 83, 204, 24, 160, 67, 8, 197, 189, 63, 15, 54, 240, 68, 0, 9, 198, 44, 48, 69, 68, 20, 192, 66, 9, 198, 20, 100, 15, 32, 148, 192, 66, 0, 7, 195, 73, 180, 128, 72, 23, 6, 195, 60, 35, 112, 66, 0, 7, 196, 30, 144, 134, 92, 66, 7, 196, 12, 19, 80, 240, 66, 0, 13, 65, 108, 6, 36, 34, 81, 4, 39, 55, 35, 65, 0, 8, 197, 92, 99, 15, 86, 240, 67, 8, 197, 88, 241, 65, 148, 160, 67, 8, 197, 76, 99, 6, 87, 48, 67, 8, 197, 176, 24, 14, 36, 176, 66, 8, 197, 57, 66, 204, 27, 16, 67, 8, 197, 36, 220, 14, 36, 176, 65, 0, 9, 198, 73, 62, 47, 156, 97, 64, 68, 9, 198, 72, 99, 112, 56, 146, 192, 65, 9, 198, 48, 145, 38, 56, 146, 192, 65, 0, 10, 199, 58, 115, 194, 60, 64, 101, 100, 69, 0, 7, 196, 91, 1, 70, 44, 66, 9, 198, 220, 217, 13, 9, 67, 0, 67, 7, 196, 44, 96, 129, 64, 66, 0, 8, 197, 84, 195, 211, 39, 176, 67, 9, 198, 73, 64, 146, 77, 16, 83, 66, 9, 198, 73, 52, 91, 12, 226, 75, 66, 8, 197, 44, 19, 123, 79, 48, 67, 0, 0, 0, 7, 196, 73, 180, 165, 12, 66, 7, 196, 75, 11, 15, 72, 67, 0, 13, 65, 116, 6, 36, 34, 65, 4, 35, 64, 13, 49, 0, 8, 197, 160, 35, 210, 212, 80, 67, 8, 197, 34, 188, 231, 24, 80, 68, 0, 6, 195, 67, 101, 111, 66, 6, 195, 36, 211, 211, 66, 0, 6, 1, 118, 21, 0, 10, 10, 199, 47, 49, 79, 55, 18, 84, 52, 67, 0, 11, 200, 64, 243, 20, 68, 18, 16, 4, 80, 68, 7, 196, 20, 243, 107, 196, 67, 7, 196, 17, 240, 198, 96, 66, 0, 6, 1, 120, 21, 0, 10, 8, 197, 68, 148, 206, 36, 176, 66, 9, 198, 44, 59, 211, 37, 49, 147, 67, 0, 9, 198, 88, 100, 211, 68, 146, 192, 66, 9, 198, 76, 146, 195, 192, 146, 192, 65, 9, 198, 45, 180, 69, 30, 210, 96, 65, 0, 6, 195, 79, 143, 64, 66, 10, 199, 161, 4, 102, 24, 83, 137, 44, 66, 6, 195, 140, 146, 192, 66, 9, 198, 5, 3, 211, 24, 242, 0, 68, 0, 9, 198, 47, 52, 209, 4, 32, 82, 67, 7, 196, 196, 149, 201, 180, 68, 0, 8, 197, 88, 18, 133, 80, 176, 66, 12, 201, 73, 182, 20, 13, 36, 195, 192, 146, 192, 66, 9, 198, 24, 193, 139, 79, 99, 123, 68, 0, 7, 195, 44, 20, 207, 72, 23, 9, 198, 88, 148, 56, 62, 83, 64, 68, 9, 198, 72, 177, 144, 76, 146, 192, 66, 9, 198, 52, 100, 207, 20, 146, 192, 67, 0, 6, 195, 79, 15, 64, 66, 9, 198, 52, 17, 5, 188, 242, 0, 67, 0, 9, 198, 79, 99, 6, 40, 37, 18, 67, 0, 8, 197, 79, 99, 80, 25, 48, 66, 8, 197, 56, 148, 209, 5, 48, 66, 6, 195, 53, 77, 206, 66, 0, 9, 198, 24, 193, 139, 79, 99, 128, 67, 0, 0, 6, 195, 224, 149, 13, 65, 7, 196, 44, 21, 101, 56, 66, 6, 195, 22, 200, 197, 66, 0, 8, 197, 85, 16, 72, 119, 208, 66, 0, 9, 198, 77, 16, 77, 64, 204, 64, 66, 9, 198, 68, 147, 76, 128, 236, 64, 65, 6, 195, 6, 83, 111, 67, 0, 6, 195, 66, 241, 140, 66, 6, 195, 188, 156, 192, 67, 0, 7, 196, 245, 62, 6, 20, 67, 7, 196, 52, 155, 58, 20, 67, 7, 196, 55, 162, 212, 96, 66, 7, 196, 20, 98, 233, 76, 66, 0, 8, 197, 80, 210, 82, 108, 192, 65, 8, 197, 67, 100, 236, 60, 192, 67, 8, 197, 66, 52, 147, 216, 224, 66, 8, 197, 161, 77, 135, 4, 160, 68, 8, 197, 44, 20, 9, 148, 192, 67, 8, 197, 23, 177, 130, 24, 160, 67, 0, 6, 195, 98, 113, 139, 66, 9, 198, 95, 18, 195, 4, 164, 128, 66, 9, 198, 60, 81, 139, 60, 204, 192, 68, 6, 195, 24, 193, 139, 66, 0, 0, 8, 196, 61, 50, 219, 52, 72, 23, 7, 196, 72, 148, 232, 28, 66, 7, 196, 12, 89, 198, 92, 66, 7, 196, 9, 179, 53, 96, 66, 0, 16, 67, 9, 67, 0, 71, 40, 55, 36, 84, 4, 35, 34, 47, 0, 24, 8, 197, 72, 20, 209, 5, 0, 66, 8, 197, 45, 28, 79, 51, 16, 67, 6, 195, 47, 131, 202, 66, 8, 197, 37, 36, 15, 51, 16, 67, 8, 197, 20, 144, 68, 206, 208, 68, 8, 197, 16, 18, 15, 51, 16, 67, 8, 197, 11, 1, 149, 37, 32, 67, 8, 197, 4, 77, 142, 60, 208, 67, 0, 6, 195, 95, 18, 75, 66, 9, 198, 89, 67, 111, 60, 145, 64, 68, 6, 195, 164, 220, 211, 66, 9, 198, 55, 195, 196, 48, 97, 64, 67, 9, 198, 19, 49, 79, 48, 158, 192, 68, 6, 195, 168, 188, 211, 66, 0, 10, 199, 76, 100, 142, 60, 68, 91, 20, 67, 6, 195, 66, 240, 124, 67, 6, 195, 61, 153, 128, 66, 9, 198, 52, 146, 246, 72, 190, 0, 67, 0, 7, 195, 72, 193, 133, 72, 23, 7, 196, 61, 48, 198, 72, 66, 7, 196, 46, 251, 73, 128, 66, 7, 196, 212, 95, 79, 20, 67, 0, 5, 193, 144, 72, 23, 8, 197, 85, 18, 72, 119, 208, 66, 8, 197, 79, 209, 129, 23, 208, 68, 8, 197, 64, 243, 9, 55, 176, 67, 8, 197, 52, 17, 1, 35, 16, 67, 8, 197, 10, 209, 65, 91, 16, 67, 0, 6, 195, 233, 54, 203, 66, 0, 6, 195, 25, 51, 192, 65, 10, 199, 52, 20, 140, 61, 32, 198, 76, 67, 0, 0, 8, 197, 93, 181, 83, 24, 112, 66, 8, 197, 48, 109, 195, 108, 80, 67, 8, 197, 17, 180, 77, 24, 112, 66, 0, 0, 8, 197, 77, 18, 88, 51, 0, 66, 6, 195, 236, 32, 80, 66, 0, 6, 195, 73, 176, 189, 66, 7, 196, 67, 189, 228, 48, 67, 6, 195, 52, 97, 109, 66, 7, 196, 45, 25, 129, 40, 66, 0, 0, 10, 66, 17, 16, 81, 34, 35, 47, 0, 24, 9, 198, 88, 17, 71, 185, 178, 192, 67, 6, 195, 55, 213, 11, 66, 6, 195, 34, 241, 111, 66, 6, 195, 5, 96, 83, 66, 0, 6, 195, 25, 59, 128, 66, 0, 7, 196, 18, 144, 134, 92, 66, 7, 196, 8, 243, 9, 20, 66, 0, 8, 197, 76, 96, 83, 70, 208, 67, 8, 197, 68, 18, 11, 61, 144, 66, 0, 0, 6, 195, 92, 155, 192, 66, 0, 5, 194, 159, 0, 66, 7, 196, 145, 156, 6, 92, 65, 7, 196, 52, 104, 206, 28, 66, 0, 5, 193, 160, 72, 11, 8, 197, 88, 145, 81, 189, 48, 66, 8, 197, 66, 49, 9, 5, 48, 67, 8, 197, 44, 244, 204, 25, 48, 66, 6, 195, 188, 29, 206, 67, 9, 198, 4, 128, 148, 96, 226, 75, 65, 0, 20, 4, 95, 50, 77, 50, 72, 84, 6, 35, 15, 65, 37, 55, 37, 6, 39, 50, 35, 0, 9, 198, 40, 241, 79, 87, 211, 64, 67, 6, 195, 20, 97, 151, 66, 0, 21, 4, 95, 50, 77, 51, 72, 84, 6, 35, 15, 65, 37, 55, 37, 6, 35, 34, 72, 35, 0, 10, 199, 88, 99, 79, 16, 195, 194, 196, 68, 0, 7, 195, 8, 98, 0, 72, 23, 7, 196, 61, 49, 70, 48, 66, 0, 11, 200, 45, 67, 133, 81, 17, 71, 38, 0, 65, 8, 197, 44, 19, 66, 80, 128, 66, 0, 9, 198, 36, 212, 6, 22, 244, 128, 67, 0, 0, 7, 196, 96, 99, 9, 44, 66, 7, 196, 80, 211, 137, 44, 66, 9, 198, 67, 212, 213, 24, 163, 0, 66, 7, 196, 46, 50, 221, 244, 66, 0, 4, 193, 168, 72, 9, 198, 73, 14, 205, 5, 113, 147, 67, 8, 197, 44, 243, 51, 38, 208, 68, 8, 197, 44, 20, 9, 148, 224, 67, 8, 197, 20, 149, 83, 204, 64, 66, 8, 197, 169, 113, 139, 70, 208, 67, 8, 197, 12, 99, 9, 46, 240, 67, 8, 197, 7, 179, 200, 60, 192, 68, 0, 0, 6, 195, 66, 236, 192, 66, 0, 6, 195, 67, 96, 237, 66, 7, 196, 49, 177, 198, 92, 66, 7, 196, 20, 155, 79, 16, 67, 7, 196, 18, 49, 15, 48, 66, 7, 196, 10, 182, 73, 100, 66, 0, 8, 197, 91, 166, 12, 108, 176, 66, 8, 197, 73, 51, 205, 5, 96, 66, 8, 197, 68, 18, 11, 51, 48, 66, 0, 9, 198, 48, 98, 147, 194, 244, 192, 65, 9, 198, 46, 208, 66, 181, 178, 192, 68, 0, 9, 198, 53, 66, 9, 46, 113, 133, 68, 10, 199, 40, 241, 103, 60, 95, 79, 20, 69, 0, 11, 200, 84, 244, 207, 52, 20, 251, 38, 208, 70, 7, 196, 64, 102, 75, 240, 66, 7, 196, 11, 209, 70, 40, 66, 0, 8, 197, 54, 226, 122, 23, 176, 68, 8, 197, 44, 148, 58, 37, 32, 67, 6, 195, 192, 150, 58, 66, 8, 197, 20, 243, 113, 39, 48, 68, 0, 6, 194, 20, 16, 72, 11, 6, 195, 55, 211, 115, 66, 0, 10, 199, 72, 98, 72, 52, 243, 15, 16, 68, 6, 195, 64, 244, 248, 66, 10, 199, 45, 18, 77, 196, 243, 15, 16, 68, 10, 199, 24, 66, 80, 76, 243, 15, 16, 68, 0, 7, 196, 140, 47, 49, 76, 67, 7, 196, 44, 20, 201, 204, 67, 0, 6, 195, 149, 15, 0, 66, 9, 198, 148, 180, 137, 20, 147, 211, 68, 9, 198, 73, 1, 139, 82, 51, 147, 67, 9, 198, 189, 50, 87, 36, 179, 51, 68, 0, 0, 6, 195, 64, 244, 252, 66, 6, 195, 52, 105, 76, 66, 0, 9, 198, 98, 113, 139, 61, 128, 82, 68, 7, 196, 216, 131, 194, 236, 67, 6, 195, 60, 33, 141, 66, 7, 196, 53, 68, 139, 180, 66, 7, 196, 54, 100, 84, 20, 66, 0, 8, 197, 76, 98, 210, 78, 224, 66, 6, 195, 52, 105, 78, 66, 8, 197, 52, 21, 167, 36, 176, 67, 8, 197, 37, 36, 251, 36, 176, 67, 0, 0, 10, 199, 73, 50, 80, 192, 82, 111, 76, 68, 6, 195, 60, 47, 64, 66, 0, 7, 196, 92, 155, 201, 20, 67, 7, 196, 91, 164, 20, 56, 66, 7, 196, 88, 18, 27, 68, 66, 7, 196, 73, 241, 198, 76, 66, 7, 196, 73, 176, 198, 76, 66, 9, 198, 46, 233, 193, 77, 128, 82, 68, 7, 196, 44, 20, 219, 68, 66, 7, 196, 7, 188, 230, 76, 68, 0, 8, 197, 96, 150, 56, 24, 160, 67, 8, 197, 90, 210, 85, 5, 48, 67, 8, 197, 84, 244, 248, 140, 224, 67, 8, 197, 65, 68, 73, 148, 224, 67, 8, 197, 9, 67, 4, 81, 16, 66, 0, 6, 195, 64, 244, 243, 66, 6, 195, 60, 33, 147, 66, 9, 198, 54, 180, 137, 53, 67, 64, 65, 0, 7, 195, 13, 22, 200, 72, 23, 0, 7, 196, 73, 68, 251, 192, 67, 7, 196, 44, 62, 165, 48, 66, 7, 196, 212, 83, 227, 32, 67, 6, 195, 4, 117, 17, 66, 0, 8, 197, 84, 244, 149, 5, 48, 66, 8, 197, 66, 149, 70, 45, 48, 66, 8, 197, 24, 180, 144, 237, 48, 66, 8, 197, 9, 241, 71, 25, 48, 66, 0, 6, 195, 52, 243, 35, 66, 6, 195, 50, 113, 151, 66, 9, 198, 17, 16, 85, 60, 219, 192, 67, 6, 195, 170, 49, 147, 67, 0, 6, 195, 60, 35, 200, 66, 0, 11, 200, 52, 109, 203, 60, 208, 177, 5, 48, 69, 7, 196, 47, 164, 20, 32, 66, 0, 8, 197, 68, 18, 11, 60, 192, 66, 6, 195, 60, 35, 202, 66, 0, 6, 195, 105, 74, 87, 66, 6, 195, 70, 106, 23, 66, 9, 198, 53, 66, 9, 46, 244, 192, 67, 9, 198, 17, 16, 77, 61, 92, 192, 67, 9, 198, 5, 92, 73, 76, 100, 192, 68, 9, 198, 153, 63, 73, 76, 100, 192, 68, 0, 10, 199, 52, 18, 146, 79, 211, 27, 44, 67, 6, 195, 46, 147, 204, 66, 0, 7, 196, 74, 81, 239, 76, 66, 9, 198, 67, 100, 201, 213, 65, 122, 68, 11, 200, 64, 243, 9, 76, 244, 197, 24, 192, 68, 7, 196, 67, 177, 65, 88, 66, 7, 196, 44, 242, 6, 48, 66, 0, 8, 197, 96, 20, 17, 4, 128, 66, 8, 197, 55, 30, 237, 60, 64, 68, 8, 197, 44, 243, 22, 60, 128, 66, 8, 197, 16, 20, 147, 216, 192, 66, 0, 10, 66, 13, 96, 84, 107, 39, 47, 0, 24, 9, 198, 17, 180, 76, 60, 35, 204, 67, 0, 7, 195, 32, 17, 64, 72, 23, 10, 199, 72, 49, 147, 60, 67, 6, 20, 67, 6, 195, 67, 100, 236, 65, 10, 199, 22, 209, 139, 60, 67, 6, 20, 68, 0, 7, 196, 65, 18, 83, 176, 65, 7, 196, 67, 178, 79, 20, 67, 7, 196, 47, 98, 198, 76, 66, 0, 8, 197, 67, 4, 137, 207, 176, 68, 8, 197, 44, 62, 147, 239, 48, 67, 8, 197, 32, 99, 70, 55, 176, 67, 6, 195, 15, 4, 238, 66, 0, 9, 198, 79, 131, 196, 68, 21, 64, 67, 9, 198, 65, 16, 79, 76, 101, 192, 67, 9, 198, 56, 146, 235, 12, 101, 192, 65, 9, 198, 53, 180, 83, 12, 101, 192, 66, 9, 198, 48, 97, 79, 88, 241, 64, 67, 9, 198, 25, 2, 68, 68, 21, 64, 67, 9, 198, 153, 51, 196, 68, 21, 64, 67, 0, 6, 195, 86, 226, 72, 66, 9, 198, 47, 52, 209, 5, 60, 61, 68, 0, 7, 196, 87, 3, 205, 192, 67, 7, 196, 81, 16, 68, 188, 67, 7, 196, 74, 84, 212, 76, 66, 7, 196, 11, 161, 84, 44, 66, 7, 196, 180, 37, 13, 196, 67, 0, 8, 197, 55, 18, 71, 81, 0, 67, 8, 197, 180, 32, 83, 217, 32, 67, 0, 9, 198, 68, 18, 16, 48, 241, 64, 66, 0, 6, 195, 24, 82, 64, 65, 10, 199, 72, 96, 251, 60, 146, 19, 176, 68, 0, 7, 195, 13, 42, 69, 72, 23, 6, 195, 96, 21, 25, 66, 7, 196, 216, 131, 122, 196, 67, 11, 200, 64, 243, 20, 66, 244, 137, 207, 176, 70, 6, 195, 22, 224, 85, 66, 7, 196, 16, 244, 231, 188, 67, 0, 8, 197, 72, 20, 252, 36, 176, 67, 8, 197, 52, 244, 248, 24, 80, 67, 6, 195, 9, 73, 78, 66, 0, 6, 194, 144, 80, 72, 23, 9, 198, 72, 197, 7, 8, 22, 64, 66, 0, 9, 198, 47, 61, 209, 92, 149, 13, 66, 10, 199, 13, 178, 16, 38, 83, 137, 44, 66, 10, 199, 15, 179, 184, 60, 91, 201, 44, 67, 0, 9, 198, 85, 27, 203, 52, 29, 206, 67, 9, 198, 68, 17, 73, 61, 128, 82, 68, 7, 196, 161, 33, 146, 236, 67, 7, 196, 55, 161, 58, 196, 67, 7, 196, 12, 100, 233, 92, 66, 0, 8, 197, 89, 27, 240, 36, 176, 65, 8, 197, 64, 243, 112, 36, 176, 67, 8, 197, 64, 241, 66, 36, 48, 65, 9, 198, 48, 98, 139, 226, 52, 147, 67, 0, 9, 198, 64, 97, 65, 16, 241, 0, 67, 6, 195, 45, 44, 51, 66, 0, 9, 198, 68, 18, 11, 68, 22, 0, 65, 10, 199, 45, 22, 245, 36, 131, 9, 12, 67, 0, 7, 196, 67, 162, 198, 76, 66, 0, 8, 197, 54, 49, 112, 25, 112, 67, 8, 197, 46, 49, 112, 25, 112, 65, 8, 197, 44, 20, 139, 25, 48, 66, 0, 9, 198, 221, 0, 69, 28, 152, 0, 65, 6, 195, 64, 17, 51, 66, 0, 6, 195, 55, 219, 64, 66, 0, 7, 196, 79, 211, 79, 32, 66, 7, 196, 67, 17, 42, 56, 66, 7, 196, 52, 20, 246, 72, 66, 7, 196, 47, 99, 73, 20, 66, 0, 8, 197, 86, 254, 137, 61, 48, 68, 8, 197, 164, 133, 12, 149, 48, 67, 8, 197, 66, 145, 77, 25, 48, 66, 8, 197, 35, 162, 38, 5, 48, 67, 12, 201, 24, 193, 139, 79, 99, 115, 77, 223, 64, 69, 8, 197, 20, 144, 77, 189, 48, 67, 8, 197, 8, 242, 139, 61, 48, 66, 0, 5, 194, 10, 144, 72, 9, 198, 24, 193, 139, 79, 97, 240, 68, 9, 198, 189, 61, 144, 60, 195, 196, 68, 0, 9, 198, 97, 66, 212, 56, 85, 17, 67, 10, 199, 73, 177, 17, 4, 113, 111, 196, 66, 6, 195, 73, 76, 68, 66, 6, 195, 11, 172, 192, 66, 0, 7, 196, 167, 83, 3, 236, 67, 7, 196, 64, 242, 9, 12, 65, 11, 200, 24, 180, 139, 81, 18, 9, 189, 48, 68, 11, 200, 153, 51, 211, 70, 244, 144, 245, 48, 68, 0, 8, 197, 77, 18, 66, 80, 224, 66, 8, 197, 65, 18, 72, 70, 176, 65, 0, 9, 198, 84, 244, 207, 74, 84, 192, 67, 9, 198, 80, 226, 67, 236, 208, 68, 68, 9, 198, 65, 64, 187, 76, 100, 192, 67, 9, 198, 52, 146, 246, 9, 68, 128, 67, 0, 0, 7, 196, 84, 18, 147, 204, 66, 6, 195, 150, 50, 0, 66, 7, 196, 48, 97, 9, 204, 67, 11, 200, 47, 52, 209, 4, 17, 77, 242, 208, 69, 7, 196, 44, 248, 196, 192, 67, 7, 196, 20, 240, 137, 12, 65, 7, 196, 4, 34, 1, 92, 66, 0, 8, 197, 21, 73, 16, 164, 224, 67, 8, 197, 20, 53, 2, 60, 160, 66, 0, 9, 198, 129, 100, 203, 49, 64, 128, 66, 9, 198, 77, 18, 87, 12, 100, 192, 66, 13, 202, 76, 99, 6, 84, 244, 207, 5, 14, 129, 76, 71, 6, 195, 23, 90, 87, 66, 9, 198, 19, 211, 215, 12, 100, 192, 67, 6, 195, 9, 70, 115, 66, 9, 198, 233, 0, 69, 28, 146, 192, 67, 0, 10, 199, 84, 244, 207, 5, 14, 129, 76, 69, 6, 195, 20, 106, 136, 66, 0, 6, 195, 86, 226, 109, 67, 7, 196, 81, 96, 71, 244, 67, 7, 196, 73, 51, 198, 28, 66, 7, 196, 66, 249, 76, 204, 67, 7, 196, 44, 243, 6, 28, 66, 7, 196, 32, 20, 245, 68, 66, 0, 8, 197, 66, 115, 6, 46, 240, 67, 0, 6, 195, 48, 147, 115, 66, 9, 198, 43, 179, 196, 48, 149, 64, 67, 0, 10, 199, 75, 185, 219, 16, 206, 207, 20, 69, 0, 7, 196, 86, 244, 207, 52, 66, 7, 196, 77, 18, 79, 20, 66, 6, 195, 67, 131, 49, 66, 7, 196, 55, 162, 201, 32, 66, 6, 195, 32, 20, 61, 66, 7, 196, 9, 66, 198, 76, 66, 7, 196, 7, 121, 14, 72, 67, 7, 196, 5, 34, 198, 76, 66, 7, 196, 232, 208, 68, 188, 67, 0, 12, 201, 47, 17, 141, 5, 51, 196, 68, 21, 64, 69, 0, 6, 195, 145, 1, 131, 66, 6, 195, 197, 91, 211, 66, 0, 0, 7, 196, 67, 97, 41, 72, 66, 7, 196, 64, 97, 111, 76, 66, 7, 196, 54, 241, 122, 196, 67, 0, 8, 197, 74, 170, 3, 108, 80, 67, 9, 198, 66, 148, 147, 69, 64, 239, 67, 8, 197, 65, 25, 142, 80, 176, 66, 8, 197, 17, 16, 69, 24, 112, 66, 8, 197, 8, 19, 66, 80, 176, 66, 0, 9, 198, 88, 145, 118, 48, 241, 0, 67, 9, 198, 85, 68, 100, 20, 114, 96, 65, 9, 198, 15, 14, 207, 48, 241, 0, 68, 0, 6, 195, 61, 33, 140, 66, 0, 6, 195, 47, 132, 253, 66, 0, 9, 198, 87, 163, 65, 92, 96, 211, 67, 8, 197, 74, 51, 112, 36, 176, 65, 0, 11, 66, 25, 48, 36, 47, 6, 35, 91, 0, 24, 6, 195, 67, 100, 243, 66, 6, 195, 11, 48, 179, 66, 0, 10, 199, 72, 98, 233, 149, 18, 65, 76, 69, 10, 199, 67, 99, 6, 149, 18, 65, 76, 69, 9, 198, 4, 223, 83, 37, 39, 125, 68, 0, 7, 196, 91, 197, 17, 16, 66, 9, 198, 8, 144, 140, 36, 245, 110, 68, 0, 8, 197, 17, 16, 69, 25, 112, 66, 0, 9, 198, 65, 34, 86, 60, 195, 196, 67, 9, 198, 52, 146, 246, 86, 227, 64, 67, 9, 198, 20, 98, 59, 77, 223, 64, 67, 0, 6, 195, 81, 15, 64, 66, 10, 199, 46, 209, 138, 20, 244, 139, 224, 68, 10, 199, 21, 16, 77, 5, 53, 17, 16, 67, 0, 11, 200, 73, 1, 151, 38, 210, 72, 189, 48, 69, 7, 196, 69, 179, 70, 28, 66, 6, 195, 55, 213, 113, 66, 0, 8, 197, 64, 197, 3, 25, 112, 66, 8, 197, 47, 160, 179, 5, 48, 67, 8, 197, 24, 180, 144, 245, 48, 66, 8, 197, 20, 148, 139, 189, 48, 66, 8, 197, 23, 178, 67, 5, 48, 67, 0, 9, 198, 76, 101, 142, 60, 195, 196, 67, 6, 195, 64, 148, 59, 66, 6, 195, 31, 161, 51, 66, 0, 10, 66, 8, 192, 71, 55, 39, 49, 0, 24, 6, 195, 145, 11, 77, 66, 6, 195, 10, 182, 209, 66, 0, 0, 0, 8, 197, 73, 180, 17, 80, 64, 66, 8, 197, 45, 68, 73, 60, 128, 67, 0, 9, 198, 72, 19, 108, 205, 61, 140, 68, 9, 198, 20, 101, 201, 8, 99, 0, 67, 9, 198, 18, 52, 144, 5, 15, 0, 67, 0, 6, 195, 96, 25, 76, 66, 9, 198, 44, 243, 80, 48, 98, 211, 66, 6, 195, 232, 76, 192, 66, 0, 7, 196, 77, 18, 83, 204, 66, 7, 196, 61, 82, 87, 236, 67, 9, 198, 44, 243, 80, 48, 98, 210, 66, 7, 196, 196, 82, 106, 20, 67, 7, 196, 180, 44, 79, 72, 67, 0, 8, 197, 93, 180, 67, 80, 192, 66, 0, 9, 198, 88, 19, 70, 48, 108, 192, 68, 6, 195, 164, 114, 77, 66, 9, 198, 56, 150, 65, 21, 180, 64, 67, 9, 198, 47, 52, 209, 5, 36, 192, 66, 9, 198, 20, 144, 80, 4, 140, 192, 68, 9, 198, 9, 180, 72, 224, 148, 128, 67, 0, 6, 195, 72, 209, 128, 72, 6, 195, 75, 186, 136, 66, 10, 199, 68, 18, 14, 60, 67, 6, 20, 67, 0, 7, 196, 150, 52, 155, 52, 67, 6, 195, 60, 40, 203, 65, 7, 196, 47, 162, 70, 72, 65, 7, 196, 25, 11, 143, 16, 67, 7, 196, 13, 180, 54, 72, 66, 6, 195, 11, 176, 187, 66, 0, 8, 197, 84, 18, 15, 55, 176, 67, 8, 197, 52, 97, 109, 119, 48, 67, 8, 197, 16, 18, 15, 55, 176, 67, 8, 197, 4, 208, 83, 119, 208, 67, 0, 8, 197, 204, 32, 89, 38, 0, 65, 0, 6, 195, 16, 19, 112, 66, 0, 7, 196, 91, 211, 210, 188, 67, 7, 196, 76, 99, 6, 92, 66, 7, 196, 47, 169, 3, 180, 67, 6, 195, 20, 98, 239, 66, 7, 196, 11, 160, 66, 188, 67, 0, 6, 195, 52, 100, 238, 66, 8, 197, 52, 21, 129, 19, 48, 67, 0, 6, 194, 32, 16, 72, 23, 9, 198, 8, 241, 73, 19, 161, 64, 67, 0, 7, 195, 65, 18, 64, 72, 23, 9, 198, 84, 206, 9, 20, 148, 139, 67, 10, 199, 79, 98, 139, 4, 81, 201, 128, 65, 10, 199, 23, 179, 65, 76, 243, 15, 16, 68, 10, 199, 22, 217, 187, 4, 81, 201, 128, 67, 10, 199, 9, 65, 75, 4, 81, 201, 128, 65, 0, 7, 196, 73, 67, 81, 172, 65, 7, 196, 37, 146, 65, 72, 67, 7, 196, 32, 16, 143, 40, 66, 7, 196, 20, 96, 137, 76, 65, 11, 200, 19, 14, 237, 37, 34, 77, 81, 32, 68, 7, 196, 11, 98, 193, 76, 66, 0, 9, 198, 91, 209, 143, 17, 16, 85, 68, 9, 198, 67, 211, 143, 17, 16, 85, 67, 8, 197, 181, 98, 77, 36, 176, 67, 0, 9, 198, 141, 62, 228, 20, 114, 96, 66, 0, 9, 198, 84, 16, 145, 36, 176, 83, 67, 0, 11, 200, 88, 148, 15, 91, 49, 81, 36, 176, 68, 11, 200, 65, 18, 67, 109, 17, 240, 36, 176, 66, 6, 195, 224, 144, 83, 67, 9, 198, 48, 100, 142, 37, 129, 138, 67, 7, 196, 47, 179, 210, 196, 67, 7, 196, 21, 66, 193, 76, 66, 0, 8, 197, 9, 67, 83, 24, 112, 66, 0, 12, 201, 64, 243, 20, 84, 16, 145, 36, 176, 83, 69, 9, 198, 52, 227, 199, 37, 49, 140, 65, 9, 198, 12, 100, 147, 156, 242, 128, 67, 0, 7, 195, 45, 179, 64, 72, 23, 6, 195, 61, 43, 128, 66, 9, 198, 47, 53, 240, 77, 16, 83, 67, 6, 195, 10, 203, 64, 66, 0, 7, 195, 13, 178, 0, 72, 23, 7, 196, 78, 147, 157, 244, 66, 7, 196, 72, 20, 219, 68, 66, 7, 196, 21, 65, 84, 44, 66, 0, 8, 197, 72, 49, 147, 25, 112, 66, 8, 197, 64, 245, 131, 5, 48, 66, 9, 198, 64, 20, 17, 36, 176, 89, 65, 8, 197, 54, 240, 82, 79, 192, 67, 8, 197, 20, 155, 70, 45, 48, 67, 6, 195, 20, 98, 250, 65, 8, 197, 4, 130, 77, 81, 48, 65, 0, 6, 195, 20, 98, 253, 66, 0, 0, 6, 195, 196, 124, 59, 67, 7, 196, 4, 40, 212, 76, 65, 0, 8, 197, 44, 243, 80, 61, 48, 66, 8, 197, 21, 177, 197, 25, 112, 66, 0, 6, 195, 47, 17, 237, 66, 0, 9, 198, 67, 98, 212, 23, 2, 75, 66, 10, 199, 48, 98, 231, 60, 83, 227, 32, 69, 9, 198, 17, 16, 77, 5, 50, 75, 67, 10, 199, 9, 66, 205, 24, 162, 219, 68, 65, 0, 0, 8, 197, 145, 18, 207, 54, 240, 67, 6, 195, 140, 177, 138, 66, 0, 5, 194, 144, 160, 65, 9, 198, 79, 179, 79, 74, 84, 192, 67, 9, 198, 47, 52, 198, 45, 36, 192, 66, 6, 195, 26, 84, 0, 66, 9, 198, 212, 95, 65, 32, 81, 140, 68, 0, 6, 195, 70, 108, 64, 66, 6, 195, 244, 99, 204, 67, 6, 195, 25, 95, 0, 66, 10, 199, 12, 99, 15, 72, 148, 6, 20, 68, 0, 6, 195, 72, 98, 51, 66, 7, 196, 52, 97, 5, 188, 66, 0, 8, 197, 64, 100, 205, 24, 128, 66, 8, 197, 64, 20, 147, 246, 208, 67, 8, 197, 55, 51, 204, 60, 64, 67, 6, 195, 43, 190, 150, 66, 8, 197, 32, 243, 204, 60, 64, 67, 9, 198, 13, 179, 14, 60, 195, 205, 67, 0, 9, 198, 73, 62, 198, 61, 50, 80, 68, 6, 195, 47, 163, 113, 66, 0, 9, 198, 8, 144, 140, 36, 243, 111, 68, 0, 7, 196, 91, 181, 207, 16, 66, 7, 196, 60, 211, 6, 76, 66, 7, 196, 52, 243, 6, 92, 66, 6, 195, 47, 162, 123, 67, 7, 196, 46, 213, 212, 56, 66, 7, 196, 34, 107, 73, 128, 65, 0, 8, 197, 79, 179, 79, 87, 208, 67, 8, 197, 148, 163, 184, 37, 32, 67, 8, 197, 65, 25, 184, 37, 32, 67, 8, 197, 53, 68, 134, 51, 16, 67, 0, 6, 195, 91, 179, 241, 67, 9, 198, 141, 28, 68, 61, 34, 248, 68, 9, 198, 18, 208, 239, 61, 34, 248, 68, 0, 9, 198, 20, 155, 70, 45, 50, 75, 68, 0, 7, 196, 84, 100, 201, 100, 66, 7, 196, 76, 251, 70, 76, 67, 7, 196, 25, 100, 198, 28, 66, 7, 196, 9, 16, 77, 196, 66, 7, 196, 4, 81, 144, 76, 66, 0, 8, 197, 52, 97, 1, 87, 48, 67, 8, 197, 45, 179, 139, 119, 208, 66, 0, 9, 198, 9, 67, 6, 15, 161, 64, 67, 0, 10, 199, 164, 184, 205, 4, 81, 201, 128, 66, 6, 195, 66, 254, 192, 66, 6, 195, 46, 148, 240, 66, 0, 9, 198, 92, 146, 204, 61, 36, 238, 67, 7, 196, 87, 211, 65, 76, 66, 7, 196, 81, 166, 209, 8, 66, 7, 196, 75, 20, 198, 32, 66, 7, 196, 52, 18, 4, 180, 66, 6, 195, 46, 148, 243, 66, 6, 195, 47, 160, 83, 66, 0, 12, 3, 226, 132, 150, 50, 6, 39, 65, 36, 34, 0, 0, 0, 9, 198, 20, 96, 134, 48, 243, 123, 68, 0, 9, 198, 221, 114, 79, 48, 241, 0, 68, 7, 196, 64, 153, 68, 244, 67, 7, 196, 61, 50, 207, 72, 66, 7, 196, 44, 99, 6, 100, 66, 7, 196, 232, 243, 65, 76, 67, 7, 196, 4, 83, 124, 180, 67, 0, 8, 197, 80, 226, 75, 80, 208, 65, 8, 197, 72, 222, 129, 16, 80, 66, 8, 197, 68, 18, 4, 216, 208, 66, 8, 197, 37, 36, 253, 36, 176, 67, 9, 198, 8, 98, 9, 73, 60, 0, 67, 8, 197, 232, 158, 196, 232, 80, 68, 0, 9, 198, 64, 243, 9, 92, 18, 128, 67, 0, 10, 199, 52, 243, 9, 76, 60, 9, 44, 66, 0, 7, 196, 88, 20, 219, 68, 66, 7, 196, 68, 18, 53, 20, 66, 7, 196, 45, 67, 70, 92, 66, 7, 196, 44, 243, 6, 76, 66, 7, 196, 46, 52, 104, 76, 66, 7, 196, 44, 148, 6, 28, 66, 7, 196, 44, 22, 77, 240, 66, 7, 196, 10, 212, 129, 52, 66, 0, 8, 197, 68, 18, 16, 37, 48, 65, 8, 197, 189, 242, 83, 25, 48, 68, 0, 9, 198, 84, 100, 147, 36, 59, 64, 67, 6, 195, 61, 52, 61, 66, 0, 9, 198, 68, 18, 146, 108, 49, 147, 67, 9, 198, 67, 98, 193, 31, 2, 75, 66, 9, 198, 24, 193, 139, 77, 18, 75, 67, 0, 7, 196, 99, 180, 198, 28, 66, 7, 196, 84, 197, 9, 20, 66, 9, 198, 67, 100, 201, 212, 49, 146, 68, 7, 196, 196, 59, 73, 20, 67, 0, 8, 197, 65, 18, 67, 25, 48, 66, 8, 197, 20, 101, 70, 45, 48, 66, 8, 197, 4, 74, 68, 5, 48, 67, 0, 6, 195, 90, 210, 85, 66, 6, 195, 173, 55, 125, 66, 0, 0, 7, 196, 197, 94, 139, 76, 66, 0, 6, 131, 226, 128, 166, 8, 8, 197, 53, 68, 165, 56, 64, 66, 0, 9, 198, 75, 17, 73, 44, 20, 192, 67, 9, 198, 46, 241, 73, 20, 20, 192, 67, 9, 198, 197, 49, 140, 24, 180, 192, 67, 0, 8, 197, 86, 235, 211, 217, 0, 67, 10, 199, 73, 59, 15, 60, 47, 79, 76, 69, 6, 195, 224, 148, 192, 65, 6, 195, 15, 161, 140, 66, 0, 7, 196, 88, 18, 131, 188, 66, 7, 196, 68, 18, 53, 40, 66, 7, 196, 60, 36, 134, 16, 66, 7, 196, 47, 160, 179, 184, 67, 7, 196, 4, 44, 193, 76, 67, 0, 12, 201, 221, 114, 109, 20, 99, 108, 68, 20, 192, 70, 12, 201, 47, 52, 209, 5, 10, 67, 68, 20, 192, 68, 8, 197, 12, 100, 246, 14, 208, 67, 0, 9, 198, 79, 176, 80, 24, 52, 192, 67, 9, 198, 67, 100, 144, 24, 180, 192, 66, 9, 198, 20, 97, 48, 236, 20, 192, 68, 0, 10, 199, 68, 18, 11, 6, 3, 137, 44, 66, 10, 199, 52, 17, 9, 73, 52, 65, 76, 67, 6, 195, 8, 98, 60, 66, 0, 6, 195, 26, 83, 51, 67, 7, 196, 25, 2, 68, 204, 67, 0, 8, 197, 72, 99, 32, 59, 16, 65, 8, 197, 47, 19, 210, 183, 48, 68, 0, 5, 194, 163, 48, 66, 0, 7, 195, 66, 145, 64, 72, 23, 9, 198, 220, 36, 147, 15, 2, 75, 65, 10, 199, 45, 190, 73, 44, 241, 212, 88, 68, 0, 11, 200, 77, 244, 76, 124, 71, 195, 25, 128, 68, 7, 196, 75, 17, 71, 240, 66, 7, 196, 177, 62, 15, 20, 67, 0, 8, 197, 75, 186, 147, 119, 208, 67, 8, 197, 48, 100, 248, 37, 32, 67, 0, 6, 195, 54, 241, 45, 66, 0, 7, 195, 61, 32, 240, 72, 23, 0, 8, 196, 72, 52, 91, 88, 72, 23, 7, 196, 68, 148, 212, 180, 67, 6, 195, 64, 150, 167, 66, 9, 198, 52, 146, 207, 48, 241, 0, 67, 6, 195, 54, 241, 47, 66, 0, 0, 12, 201, 65, 180, 198, 100, 100, 147, 15, 2, 75, 67, 9, 198, 65, 16, 70, 32, 146, 192, 67, 9, 198, 53, 22, 210, 56, 146, 192, 66, 9, 198, 47, 164, 194, 140, 230, 64, 66, 6, 195, 19, 188, 0, 66, 9, 198, 212, 193, 138, 8, 243, 0, 65, 0, 0, 6, 195, 60, 197, 11, 66, 9, 198, 52, 148, 207, 48, 241, 0, 67, 6, 195, 47, 161, 111, 66, 7, 196, 32, 20, 1, 72, 66, 6, 195, 9, 68, 243, 66, 7, 196, 8, 99, 15, 76, 66, 0, 9, 198, 88, 145, 118, 17, 16, 85, 67, 12, 201, 77, 180, 15, 108, 70, 204, 56, 146, 192, 67, 9, 198, 76, 99, 6, 17, 16, 85, 67, 6, 195, 164, 249, 78, 67, 12, 201, 65, 25, 143, 108, 70, 204, 56, 146, 192, 67, 12, 201, 24, 113, 141, 25, 33, 152, 56, 146, 192, 67, 8, 197, 188, 67, 15, 86, 224, 67, 0, 9, 198, 86, 197, 18, 56, 146, 192, 65, 9, 198, 77, 21, 7, 192, 146, 192, 65, 9, 198, 73, 181, 24, 192, 146, 192, 68, 9, 198, 64, 243, 9, 76, 146, 192, 67, 9, 198, 52, 17, 1, 35, 30, 192, 68, 9, 198, 44, 243, 119, 52, 243, 0, 67, 0, 7, 195, 88, 99, 64, 72, 23, 0, 11, 200, 77, 18, 91, 17, 179, 14, 36, 176, 66, 7, 196, 72, 187, 197, 180, 66, 7, 196, 64, 242, 29, 244, 66, 7, 196, 52, 18, 20, 76, 66, 7, 196, 7, 210, 82, 76, 66, 0, 8, 197, 72, 18, 131, 189, 48, 66, 12, 201, 64, 100, 207, 108, 70, 204, 56, 146, 192, 67, 8, 197, 144, 154, 147, 25, 48, 68, 8, 197, 44, 148, 27, 165, 112, 65, 8, 197, 47, 17, 146, 47, 128, 67, 8, 197, 44, 99, 6, 67, 192, 67, 0, 9, 198, 52, 97, 45, 60, 219, 192, 68, 9, 198, 8, 22, 137, 96, 179, 192, 65, 0, 0, 7, 196, 52, 25, 69, 244, 67, 7, 196, 47, 212, 198, 28, 66, 7, 196, 28, 104, 211, 196, 67, 7, 196, 23, 49, 212, 188, 67, 0, 8, 197, 74, 83, 133, 233, 48, 66, 8, 197, 66, 51, 153, 25, 48, 66, 8, 197, 64, 20, 147, 25, 48, 66, 8, 197, 31, 195, 210, 47, 128, 67, 8, 197, 7, 179, 210, 149, 48, 68, 0, 9, 198, 66, 241, 73, 101, 11, 192, 67, 0, 6, 195, 128, 137, 252, 67, 9, 198, 74, 144, 155, 68, 226, 75, 65, 9, 198, 72, 99, 18, 108, 49, 147, 67, 9, 198, 64, 19, 70, 76, 226, 75, 65, 0, 11, 200, 73, 51, 205, 5, 51, 210, 47, 128, 68, 7, 196, 67, 96, 227, 44, 65, 11, 200, 52, 17, 14, 37, 51, 210, 47, 128, 68, 0, 8, 197, 216, 188, 5, 216, 192, 67, 9, 198, 44, 243, 66, 4, 170, 17, 67, 8, 197, 44, 22, 75, 154, 208, 67, 8, 197, 46, 211, 194, 70, 240, 67, 8, 197, 233, 98, 123, 24, 160, 68, 8, 197, 5, 3, 196, 24, 160, 67, 0, 9, 198, 20, 146, 211, 61, 92, 192, 67, 9, 198, 20, 99, 6, 16, 20, 192, 67, 0, 10, 199, 73, 178, 195, 233, 63, 47, 76, 68, 9, 198, 45, 223, 85, 37, 145, 139, 65, 10, 199, 20, 100, 134, 76, 240, 143, 40, 68, 0, 7, 196, 72, 197, 4, 4, 66, 7, 196, 164, 244, 165, 76, 67, 11, 200, 68, 17, 73, 61, 34, 68, 144, 192, 69, 7, 196, 67, 165, 198, 48, 66, 7, 196, 47, 164, 198, 48, 66, 7, 196, 36, 212, 1, 72, 66, 7, 196, 8, 16, 148, 196, 67, 0, 8, 197, 44, 21, 2, 60, 160, 67, 8, 197, 44, 20, 147, 216, 224, 66, 9, 198, 36, 132, 27, 48, 179, 205, 67, 12, 201, 9, 241, 71, 25, 62, 54, 24, 180, 192, 69, 8, 197, 8, 98, 2, 216, 160, 66, 0, 9, 198, 76, 99, 6, 64, 20, 192, 67, 9, 198, 44, 244, 141, 206, 100, 192, 67, 9, 198, 24, 180, 144, 204, 20, 192, 67, 9, 198, 9, 27, 160, 57, 60, 64, 67, 0, 10, 199, 160, 52, 65, 73, 60, 9, 44, 68, 0, 7, 196, 79, 101, 70, 40, 66, 7, 196, 73, 61, 134, 28, 66, 0, 9, 198, 84, 99, 5, 55, 166, 109, 65, 9, 198, 73, 180, 134, 50, 3, 177, 66, 8, 197, 73, 68, 240, 119, 208, 67, 8, 197, 72, 191, 80, 39, 48, 67, 8, 197, 64, 20, 129, 31, 176, 67, 8, 197, 145, 3, 204, 27, 48, 68, 9, 198, 52, 21, 186, 4, 81, 193, 68, 8, 197, 44, 20, 9, 103, 48, 67, 12, 201, 24, 193, 139, 79, 97, 79, 8, 144, 192, 68, 8, 197, 20, 96, 137, 79, 208, 65, 0, 7, 195, 176, 17, 193, 72, 23, 0, 9, 198, 74, 84, 207, 72, 190, 0, 67, 9, 198, 64, 243, 9, 76, 146, 239, 68, 0, 6, 195, 54, 242, 123, 67, 6, 195, 18, 222, 0, 66, 7, 196, 232, 76, 230, 76, 67, 0, 8, 197, 88, 97, 6, 55, 48, 67, 8, 197, 86, 249, 72, 119, 208, 67, 8, 197, 31, 49, 12, 119, 208, 66, 8, 197, 19, 163, 137, 35, 48, 67, 0, 9, 198, 74, 49, 79, 48, 97, 64, 67, 6, 195, 54, 240, 85, 66, 0, 6, 195, 220, 179, 204, 66, 6, 195, 61, 36, 240, 66, 9, 198, 244, 177, 146, 77, 27, 211, 67, 9, 198, 212, 89, 219, 69, 49, 135, 68, 0, 8, 196, 67, 100, 201, 12, 72, 23, 7, 196, 44, 18, 6, 196, 67, 7, 196, 15, 180, 198, 64, 66, 7, 196, 4, 43, 207, 72, 67, 0, 9, 197, 144, 209, 146, 76, 240, 72, 23, 8, 197, 68, 18, 17, 36, 48, 65, 8, 197, 64, 241, 86, 60, 80, 66, 8, 197, 49, 73, 19, 36, 176, 67, 8, 197, 13, 180, 67, 24, 112, 66, 8, 197, 8, 149, 83, 24, 176, 66, 0, 7, 195, 66, 145, 73, 72, 23, 9, 198, 108, 70, 204, 56, 146, 192, 65, 9, 198, 85, 26, 215, 39, 62, 192, 68, 9, 198, 72, 209, 153, 56, 146, 192, 66, 0, 10, 199, 64, 243, 20, 60, 47, 79, 76, 69, 9, 198, 52, 20, 147, 60, 92, 211, 67, 6, 195, 47, 169, 76, 66, 0, 6, 195, 90, 208, 83, 66, 7, 196, 73, 66, 205, 188, 66, 7, 196, 75, 177, 239, 76, 66, 11, 200, 64, 241, 84, 96, 20, 147, 108, 176, 65, 7, 196, 44, 245, 203, 232, 65, 0, 9, 198, 76, 99, 6, 76, 148, 0, 67, 8, 197, 216, 219, 211, 36, 176, 67, 12, 201, 216, 142, 54, 36, 141, 69, 37, 49, 140, 69, 8, 197, 52, 20, 251, 36, 176, 67, 8, 197, 13, 180, 83, 24, 112, 66, 0, 0, 10, 199, 81, 36, 61, 24, 83, 137, 44, 65, 6, 195, 149, 107, 192, 66, 10, 199, 69, 65, 79, 20, 240, 137, 12, 67, 0, 11, 200, 73, 180, 12, 24, 220, 14, 36, 176, 66, 7, 196, 24, 51, 148, 88, 66, 0, 12, 201, 61, 35, 79, 108, 70, 204, 56, 146, 192, 67, 8, 197, 45, 16, 69, 25, 112, 66, 0, 6, 195, 74, 208, 77, 66, 9, 198, 9, 18, 68, 4, 95, 0, 67, 0, 6, 195, 130, 147, 64, 66, 9, 198, 73, 178, 77, 192, 226, 75, 66, 9, 198, 21, 177, 197, 60, 36, 111, 67, 0, 7, 196, 64, 148, 134, 92, 66, 6, 195, 61, 49, 151, 66, 7, 196, 47, 96, 82, 188, 67, 0, 8, 197, 91, 211, 210, 47, 128, 67, 6, 195, 64, 148, 186, 65, 8, 197, 197, 36, 241, 45, 48, 66, 0, 12, 201, 72, 97, 77, 61, 177, 27, 48, 226, 75, 67, 9, 198, 64, 243, 20, 73, 179, 128, 67, 9, 198, 20, 149, 84, 33, 223, 64, 67, 0, 15, 3, 95, 51, 88, 47, 34, 6, 37, 72, 36, 89, 36, 47, 0, 9, 198, 65, 18, 125, 37, 49, 147, 68, 10, 199, 65, 16, 80, 70, 99, 148, 44, 67, 9, 198, 66, 179, 210, 76, 226, 75, 65, 9, 198, 13, 22, 210, 76, 226, 75, 66, 9, 198, 180, 179, 214, 60, 194, 75, 68, 0, 13, 3, 95, 48, 67, 89, 47, 6, 39, 47, 37, 50, 0, 7, 196, 68, 18, 2, 244, 66, 7, 196, 60, 47, 79, 76, 67, 7, 196, 140, 212, 9, 204, 67, 7, 196, 46, 118, 6, 16, 66, 7, 196, 16, 240, 140, 192, 66, 7, 196, 16, 145, 47, 76, 66, 0, 8, 197, 54, 214, 20, 18, 240, 67, 8, 197, 32, 16, 145, 154, 240, 67, 0, 0, 6, 195, 167, 116, 64, 66, 0, 7, 196, 69, 77, 213, 184, 67, 6, 195, 54, 246, 115, 66, 7, 196, 12, 100, 251, 188, 67, 7, 196, 12, 99, 20, 68, 66, 7, 196, 8, 245, 134, 52, 66, 0, 0, 0, 0, 10, 3, 95, 49, 67, 89, 47, 6, 39, 0, 6, 195, 54, 241, 135, 66, 11, 200, 47, 19, 213, 25, 36, 201, 14, 208, 69, 7, 196, 10, 195, 20, 44, 66, 0, 0, 6, 195, 24, 204, 0, 66, 9, 198, 20, 124, 19, 108, 195, 112, 65, 9, 198, 16, 18, 56, 219, 81, 64, 68, 0, 10, 199, 67, 171, 79, 16, 146, 27, 52, 65, 0, 7, 196, 52, 18, 15, 48, 66, 7, 196, 180, 16, 129, 100, 67, 0, 0, 6, 194, 20, 240, 72, 23, 20, 3, 95, 49, 57, 72, 4, 36, 84, 36, 47, 50, 6, 35, 72, 36, 89, 36, 47, 0, 9, 198, 36, 133, 13, 69, 65, 64, 67, 9, 198, 24, 194, 80, 220, 145, 64, 68, 9, 198, 16, 18, 15, 60, 35, 112, 68, 0, 19, 3, 95, 49, 56, 4, 39, 89, 36, 65, 50, 6, 35, 72, 36, 89, 36, 47, 0, 9, 198, 76, 99, 6, 72, 190, 0, 67, 10, 199, 73, 1, 140, 24, 243, 15, 16, 68, 9, 198, 65, 26, 211, 36, 187, 211, 67, 0, 13, 3, 95, 50, 67, 72, 84, 6, 36, 89, 47, 35, 0, 7, 196, 189, 52, 107, 72, 66, 0, 9, 198, 67, 100, 207, 76, 148, 0, 67, 8, 197, 64, 241, 111, 36, 176, 65, 8, 197, 66, 51, 167, 36, 176, 67, 0, 6, 195, 20, 248, 209, 65, 0, 6, 195, 20, 248, 208, 66, 0, 7, 196, 88, 18, 131, 236, 66, 7, 196, 72, 145, 36, 48, 66, 6, 195, 45, 68, 51, 66, 7, 196, 47, 164, 198, 96, 66, 7, 196, 189, 52, 107, 76, 66, 0, 0, 18, 3, 95, 49, 49, 36, 72, 4, 37, 50, 6, 35, 72, 36, 89, 36, 47, 0, 9, 198, 65, 25, 174, 56, 146, 192, 65, 6, 195, 61, 61, 81, 66, 0, 12, 3, 95, 49, 48, 72, 6, 36, 89, 36, 47, 0, 6, 195, 77, 74, 12, 66, 9, 198, 47, 160, 68, 116, 242, 0, 67, 6, 195, 26, 83, 128, 66, 8, 197, 19, 3, 211, 37, 0, 67, 10, 199, 168, 81, 143, 72, 145, 36, 48, 69, 0, 13, 3, 95, 51, 67, 47, 34, 6, 37, 89, 47, 35, 0, 17, 3, 95, 49, 51, 47, 34, 37, 50, 6, 35, 72, 36, 89, 36, 47, 0, 7, 196, 68, 18, 5, 244, 66, 7, 196, 52, 17, 36, 76, 66, 6, 195, 10, 209, 147, 66, 0, 17, 3, 95, 49, 50, 72, 84, 35, 50, 6, 35, 72, 36, 89, 36, 47, 0, 8, 197, 17, 68, 66, 25, 48, 66, 0, 17, 3, 95, 49, 53, 48, 36, 47, 50, 6, 35, 72, 36, 89, 36, 47, 0, 0, 21, 3, 95, 49, 52, 76, 4, 36, 47, 37, 34, 37, 50, 6, 35, 72, 36, 89, 36, 47, 0, 8, 197, 51, 19, 211, 37, 0, 67, 6, 195, 24, 223, 0, 66, 10, 199, 215, 3, 143, 196, 59, 73, 20, 70, 0, 20, 3, 95, 49, 55, 89, 4, 36, 72, 36, 65, 50, 6, 35, 72, 36, 89, 36, 47, 0, 7, 196, 67, 101, 198, 72, 66, 12, 201, 66, 148, 139, 205, 94, 240, 92, 152, 0, 68, 7, 196, 55, 161, 49, 180, 67, 6, 195, 30, 177, 147, 66, 0, 18, 3, 95, 49, 54, 91, 36, 89, 47, 50, 6, 35, 72, 36, 89, 36, 47, 0, 8, 197, 77, 180, 78, 179, 128, 67, 8, 197, 66, 144, 209, 5, 48, 66, 9, 198, 24, 83, 143, 96, 204, 0, 67, 8, 197, 4, 213, 12, 25, 48, 67, 0, 6, 194, 36, 128, 72, 23, 9, 198, 52, 100, 246, 56, 243, 64, 67, 0, 17, 3, 95, 55, 88, 89, 36, 72, 36, 65, 72, 36, 89, 6, 36, 47, 0, 10, 199, 47, 31, 70, 28, 148, 157, 244, 69, 9, 198, 19, 14, 237, 37, 49, 147, 69, 0, 7, 196, 166, 129, 1, 76, 67, 6, 195, 52, 17, 47, 66, 7, 196, 48, 241, 9, 44, 66, 7, 196, 5, 36, 60, 196, 67, 0, 8, 197, 21, 180, 117, 140, 128, 67, 0, 0, 0, 7, 196, 44, 240, 173, 76, 66, 6, 195, 188, 184, 195, 66, 0, 8, 197, 89, 67, 9, 18, 240, 67, 9, 198, 88, 243, 6, 73, 62, 241, 68, 8, 197, 52, 20, 251, 38, 208, 68, 8, 197, 45, 16, 88, 60, 192, 66, 0, 0, 0, 7, 196, 67, 100, 147, 244, 66, 0, 8, 197, 56, 146, 207, 79, 16, 67, 0, 9, 198, 89, 27, 248, 219, 81, 64, 68, 9, 198, 79, 131, 56, 219, 81, 64, 68, 6, 195, 170, 83, 113, 67, 0, 9, 198, 32, 20, 27, 69, 54, 203, 65, 0, 6, 195, 91, 211, 115, 66, 7, 196, 79, 99, 66, 204, 66, 7, 196, 17, 244, 84, 44, 66, 0, 9, 198, 99, 179, 143, 16, 193, 133, 67, 8, 197, 79, 179, 73, 23, 208, 67, 8, 197, 76, 97, 12, 37, 128, 66, 8, 197, 75, 195, 205, 5, 96, 67, 6, 195, 216, 219, 210, 66, 8, 197, 4, 90, 100, 51, 16, 68, 0, 5, 194, 52, 16, 72, 11, 66, 48, 48, 55, 4, 36, 84, 35, 0, 24, 6, 195, 177, 34, 69, 66, 6, 195, 47, 49, 125, 66, 0, 10, 199, 85, 16, 72, 24, 243, 15, 16, 68, 10, 199, 24, 208, 145, 36, 243, 15, 16, 68, 0, 11, 200, 53, 67, 19, 36, 219, 137, 207, 176, 70, 7, 196, 16, 18, 165, 56, 66, 7, 196, 4, 74, 77, 188, 67, 0, 8, 197, 222, 52, 73, 80, 208, 66, 8, 197, 65, 18, 74, 60, 208, 66, 8, 197, 55, 163, 109, 4, 80, 67, 0, 6, 194, 180, 16, 72, 23, 9, 198, 55, 17, 123, 49, 178, 192, 67, 0, 9, 198, 4, 67, 15, 55, 176, 83, 68, 0, 6, 195, 84, 244, 243, 66, 11, 200, 72, 198, 206, 96, 241, 12, 24, 80, 67, 7, 196, 68, 21, 129, 76, 66, 6, 195, 64, 148, 243, 66, 6, 195, 47, 62, 0, 66, 6, 195, 232, 100, 147, 66, 0, 8, 197, 88, 144, 145, 36, 80, 66, 8, 197, 67, 160, 86, 60, 80, 67, 0, 6, 195, 52, 244, 253, 66, 0, 15, 3, 95, 50, 88, 72, 84, 6, 35, 72, 36, 89, 36, 47, 0, 9, 198, 8, 146, 250, 11, 48, 83, 68, 0, 7, 196, 88, 207, 73, 20, 66, 7, 196, 88, 18, 58, 76, 66, 6, 195, 84, 18, 47, 66, 7, 196, 74, 217, 100, 76, 67, 6, 195, 164, 129, 151, 66, 7, 196, 60, 220, 201, 52, 67, 7, 196, 47, 210, 69, 244, 67, 7, 196, 32, 54, 232, 92, 66, 7, 196, 15, 179, 84, 76, 66, 0, 8, 197, 91, 195, 205, 189, 48, 67, 8, 197, 77, 180, 68, 5, 144, 66, 8, 197, 52, 98, 51, 25, 48, 67, 8, 197, 52, 19, 122, 25, 112, 67, 8, 197, 44, 195, 200, 25, 48, 66, 0, 9, 198, 44, 243, 66, 4, 163, 128, 66, 0, 6, 195, 216, 219, 192, 66, 9, 198, 167, 83, 31, 92, 156, 251, 70, 6, 195, 232, 107, 64, 67, 9, 198, 5, 3, 204, 60, 65, 147, 68, 0, 7, 196, 96, 144, 148, 44, 66, 7, 196, 67, 21, 198, 76, 66, 7, 196, 25, 36, 198, 76, 66, 7, 196, 9, 245, 70, 76, 66, 0, 9, 198, 72, 99, 32, 56, 85, 17, 67, 8, 197, 52, 20, 145, 5, 80, 66, 8, 197, 25, 50, 75, 25, 48, 67, 8, 197, 8, 97, 239, 25, 112, 67, 8, 197, 8, 97, 12, 25, 112, 66, 8, 197, 153, 62, 46, 61, 48, 68, 0, 9, 198, 44, 243, 44, 169, 67, 64, 66, 9, 198, 7, 179, 197, 69, 67, 64, 68, 0, 6, 195, 45, 67, 124, 66, 6, 195, 191, 52, 128, 66, 0, 11, 200, 88, 147, 75, 60, 208, 177, 5, 48, 68, 7, 196, 84, 244, 132, 192, 66, 7, 196, 76, 101, 83, 236, 66, 11, 200, 73, 68, 59, 84, 244, 149, 5, 48, 68, 7, 196, 220, 195, 137, 44, 66, 7, 196, 68, 18, 13, 236, 66, 7, 196, 64, 100, 246, 48, 66, 7, 196, 55, 163, 197, 236, 67, 0, 8, 197, 64, 22, 75, 80, 192, 66, 8, 197, 64, 20, 1, 18, 208, 67, 0, 9, 198, 84, 98, 140, 25, 60, 192, 67, 9, 198, 72, 147, 84, 140, 228, 192, 67, 5, 194, 158, 208, 66, 9, 198, 53, 68, 65, 84, 100, 192, 67, 9, 198, 20, 144, 251, 74, 244, 192, 67, 9, 198, 168, 45, 130, 25, 60, 192, 68, 0, 10, 199, 52, 104, 206, 88, 243, 9, 44, 68, 10, 199, 47, 49, 12, 60, 222, 193, 76, 68, 0, 7, 196, 64, 102, 1, 76, 66, 7, 196, 52, 20, 148, 68, 66, 7, 196, 47, 52, 212, 68, 66, 0, 8, 197, 73, 15, 126, 55, 0, 66, 8, 197, 68, 17, 73, 46, 208, 67, 8, 197, 64, 145, 13, 24, 160, 66, 8, 197, 64, 20, 147, 24, 192, 66, 8, 197, 44, 20, 17, 36, 128, 66, 0, 0, 18, 3, 95, 52, 88, 76, 36, 47, 37, 34, 6, 37, 72, 36, 89, 36, 47, 0, 10, 199, 44, 243, 73, 75, 162, 65, 76, 69, 0, 7, 196, 74, 229, 6, 76, 67, 7, 196, 52, 18, 165, 64, 66, 7, 196, 47, 164, 207, 84, 66, 6, 195, 15, 177, 131, 66, 0, 8, 197, 165, 83, 6, 45, 32, 66, 9, 198, 9, 16, 83, 157, 129, 133, 67, 0, 9, 198, 87, 51, 196, 68, 21, 64, 67, 9, 198, 45, 22, 210, 76, 101, 192, 66, 0, 0, 7, 196, 48, 240, 148, 76, 66, 7, 196, 21, 246, 70, 44, 66, 0, 8, 197, 72, 149, 110, 37, 32, 65, 8, 197, 48, 149, 198, 55, 176, 67, 8, 197, 8, 198, 213, 119, 208, 66, 0, 9, 198, 65, 180, 117, 30, 149, 192, 67, 9, 198, 67, 98, 72, 88, 241, 64, 67, 9, 198, 44, 148, 140, 244, 241, 64, 67, 0, 15, 3, 95, 53, 88, 48, 36, 47, 72, 36, 89, 6, 36, 47, 0, 9, 198, 64, 243, 9, 16, 195, 211, 67, 10, 199, 64, 241, 82, 24, 186, 101, 68, 65, 0, 7, 196, 84, 17, 15, 76, 66, 11, 200, 68, 18, 3, 24, 164, 17, 5, 96, 67, 7, 196, 67, 100, 198, 196, 67, 7, 196, 52, 22, 129, 8, 66, 7, 196, 47, 160, 84, 48, 67, 7, 196, 212, 163, 137, 44, 66, 0, 9, 197, 12, 209, 146, 76, 240, 72, 23, 8, 197, 96, 149, 76, 36, 176, 66, 8, 197, 87, 49, 147, 36, 176, 67, 8, 197, 77, 16, 68, 36, 176, 66, 8, 197, 64, 241, 73, 80, 208, 65, 9, 198, 66, 254, 19, 36, 181, 13, 66, 8, 197, 53, 182, 48, 36, 176, 67, 8, 197, 48, 241, 56, 24, 80, 67, 0, 0, 6, 195, 5, 1, 140, 66, 0, 7, 196, 60, 46, 211, 204, 65, 0, 9, 197, 20, 241, 70, 76, 240, 72, 23, 8, 197, 49, 241, 79, 24, 80, 67, 6, 195, 45, 69, 122, 65, 8, 197, 8, 97, 12, 36, 176, 66, 0, 9, 198, 152, 147, 205, 60, 81, 140, 69, 0, 16, 3, 95, 54, 88, 91, 36, 89, 47, 72, 36, 89, 6, 36, 47, 0, 6, 195, 8, 240, 72, 66, 0, 7, 196, 88, 18, 163, 32, 66, 6, 195, 79, 178, 123, 67, 11, 200, 73, 189, 194, 73, 48, 240, 36, 176, 66, 11, 200, 60, 38, 134, 73, 48, 240, 36, 176, 66, 7, 196, 56, 246, 134, 72, 66, 9, 198, 47, 52, 209, 5, 65, 122, 67, 6, 195, 47, 49, 151, 66, 7, 196, 5, 93, 142, 76, 66, 0, 9, 198, 47, 48, 240, 92, 156, 237, 69, 8, 197, 232, 100, 165, 57, 48, 67, 8, 197, 4, 90, 82, 5, 48, 67, 0, 9, 198, 88, 207, 79, 87, 211, 64, 67, 9, 198, 55, 51, 196, 68, 19, 64, 67, 9, 198, 141, 28, 68, 60, 195, 196, 68, 9, 198, 8, 242, 5, 80, 75, 192, 67, 0, 6, 195, 22, 243, 192, 66, 6, 195, 91, 219, 64, 66, 6, 195, 81, 27, 192, 66, 0, 7, 196, 77, 244, 66, 188, 66, 6, 195, 11, 209, 151, 66, 6, 195, 173, 70, 123, 67, 0, 8, 197, 46, 52, 113, 25, 48, 67, 0, 6, 195, 51, 17, 173, 67, 0, 0, 7, 196, 73, 51, 194, 244, 66, 7, 196, 60, 33, 139, 76, 66, 7, 196, 48, 110, 58, 20, 67, 11, 200, 7, 179, 211, 70, 244, 144, 245, 48, 69, 0, 8, 197, 73, 254, 81, 36, 128, 66, 8, 197, 169, 52, 73, 60, 192, 67, 0, 9, 198, 73, 180, 87, 24, 35, 204, 67, 9, 198, 67, 97, 139, 148, 228, 192, 67, 6, 195, 46, 58, 145, 66, 9, 198, 44, 48, 69, 70, 244, 192, 66, 9, 198, 20, 96, 159, 148, 228, 192, 67, 9, 198, 153, 62, 61, 78, 148, 192, 68, 0, 6, 195, 160, 176, 64, 65, 9, 198, 44, 48, 69, 70, 226, 115, 68, 0, 7, 196, 68, 22, 6, 48, 66, 7, 196, 48, 149, 240, 32, 66, 7, 196, 47, 53, 84, 32, 66, 7, 196, 44, 240, 148, 68, 66, 0, 6, 195, 47, 61, 74, 66, 8, 197, 197, 49, 132, 70, 208, 67, 6, 195, 8, 241, 110, 66, 0, 5, 194, 53, 64, 72, 6, 195, 66, 144, 237, 66, 9, 198, 56, 249, 81, 37, 68, 128, 66, 9, 198, 15, 180, 207, 48, 100, 192, 67, 0, 16, 3, 95, 56, 88, 39, 89, 36, 65, 72, 36, 89, 6, 36, 47, 0, 0, 6, 195, 144, 179, 51, 66, 7, 196, 36, 188, 207, 52, 67, 0, 8, 197, 79, 131, 15, 55, 176, 67, 8, 197, 68, 18, 14, 61, 32, 66, 8, 197, 67, 203, 18, 187, 16, 68, 8, 197, 8, 25, 76, 119, 48, 67, 0, 9, 198, 67, 160, 68, 68, 21, 64, 67, 9, 198, 52, 20, 139, 232, 17, 64, 67, 9, 198, 32, 54, 206, 76, 97, 192, 66, 9, 198, 16, 99, 196, 68, 21, 64, 67, 0, 0, 8, 196, 36, 132, 15, 20, 72, 23, 7, 196, 55, 4, 207, 48, 66, 7, 196, 28, 20, 141, 196, 66, 7, 196, 8, 204, 197, 196, 66, 6, 195, 4, 131, 211, 66, 0, 12, 201, 84, 244, 236, 233, 51, 196, 68, 21, 64, 69, 8, 197, 67, 164, 206, 119, 208, 66, 8, 197, 12, 100, 246, 55, 176, 67, 8, 197, 5, 43, 210, 119, 208, 67, 8, 197, 172, 48, 77, 235, 16, 68, 0, 5, 194, 36, 208, 72, 7, 195, 145, 42, 69, 72, 23, 9, 198, 97, 65, 197, 192, 101, 192, 67, 9, 198, 74, 129, 39, 180, 97, 192, 68, 9, 198, 60, 36, 65, 32, 101, 192, 67, 0, 17, 3, 95, 57, 88, 72, 36, 84, 36, 47, 72, 36, 89, 6, 36, 47, 0, 0, 9, 198, 47, 52, 209, 5, 95, 82, 67, 6, 195, 47, 164, 243, 66, 0, 8, 197, 22, 126, 240, 36, 176, 66, 0, 9, 198, 84, 207, 37, 20, 114, 96, 65, 9, 198, 64, 145, 133, 25, 41, 76, 68, 9, 198, 14, 180, 129, 20, 114, 96, 65, 0, 9, 198, 20, 148, 12, 60, 208, 83, 67, 0, 7, 196, 67, 212, 201, 236, 67, 7, 196, 5, 14, 129, 76, 67, 0, 8, 197, 72, 201, 253, 24, 80, 67, 8, 197, 64, 195, 218, 4, 80, 66, 9, 198, 44, 20, 139, 4, 87, 125, 67, 8, 197, 18, 145, 125, 24, 80, 67, 0, 0, 6, 195, 79, 191, 64, 66, 0, 7, 196, 92, 145, 47, 196, 65, 7, 196, 85, 68, 68, 204, 66, 7, 196, 79, 179, 113, 180, 67, 6, 195, 74, 82, 239, 66, 7, 196, 161, 68, 246, 56, 67, 7, 196, 53, 69, 76, 204, 66, 7, 196, 45, 68, 66, 188, 66, 7, 196, 17, 25, 157, 244, 66, 0, 8, 197, 91, 210, 72, 205, 48, 67, 8, 197, 77, 18, 84, 53, 80, 66, 8, 197, 165, 36, 253, 189, 48, 67, 8, 197, 20, 100, 20, 149, 48, 67, 8, 197, 11, 177, 139, 25, 48, 67, 0, 6, 195, 46, 58, 153, 66, 9, 198, 153, 51, 205, 60, 43, 128, 68, 0, 6, 195, 164, 139, 128, 66, 0, 6, 195, 149, 1, 147, 66, 6, 195, 64, 156, 251, 67, 7, 196, 44, 21, 155, 68, 66, 6, 195, 10, 208, 239, 66, 0, 8, 197, 75, 18, 231, 25, 112, 65, 8, 197, 72, 98, 229, 57, 48, 66, 8, 197, 64, 241, 76, 25, 112, 66, 9, 198, 52, 146, 47, 79, 100, 0, 67, 8, 197, 47, 52, 148, 49, 48, 66, 8, 197, 20, 100, 144, 61, 48, 66, 8, 197, 8, 148, 141, 81, 48, 66, 8, 197, 5, 36, 60, 189, 48, 67, 0, 6, 195, 68, 17, 122, 65, 9, 198, 64, 243, 20, 87, 27, 64, 68, 9, 198, 66, 226, 68, 68, 147, 64, 67, 0, 6, 195, 144, 178, 83, 65, 9, 198, 52, 17, 40, 76, 245, 115, 68, 6, 195, 10, 226, 115, 67, 6, 195, 10, 210, 243, 66, 0, 6, 195, 20, 145, 136, 66, 0, 8, 196, 13, 180, 86, 80, 72, 23, 7, 196, 166, 132, 175, 72, 67, 7, 196, 164, 140, 239, 72, 67, 6, 195, 67, 160, 69, 66, 7, 196, 46, 52, 137, 44, 66, 6, 195, 180, 37, 13, 66, 0, 8, 197, 148, 194, 82, 54, 240, 67, 8, 197, 67, 160, 66, 24, 192, 67, 8, 197, 44, 243, 39, 60, 128, 67, 6, 195, 30, 193, 138, 66, 0, 6, 195, 8, 98, 243, 66, 0, 6, 195, 164, 140, 192, 66, 0, 7, 196, 88, 240, 143, 76, 66, 11, 200, 73, 51, 205, 5, 51, 204, 60, 64, 68, 11, 200, 160, 61, 144, 5, 51, 204, 60, 64, 69, 0, 8, 197, 84, 97, 123, 10, 208, 65, 8, 197, 70, 241, 70, 54, 240, 67, 8, 197, 44, 242, 60, 60, 64, 65, 8, 197, 20, 146, 1, 40, 224, 66, 0, 9, 198, 160, 35, 210, 44, 204, 192, 67, 9, 198, 44, 226, 68, 224, 148, 128, 67, 0, 0, 7, 196, 92, 145, 47, 244, 67, 7, 196, 195, 210, 65, 100, 68, 0, 6, 195, 72, 107, 210, 66, 8, 197, 64, 241, 82, 51, 48, 66, 9, 198, 20, 19, 65, 32, 198, 203, 67, 0, 6, 195, 52, 19, 115, 66, 9, 198, 24, 130, 75, 156, 97, 64, 68, 6, 195, 10, 210, 239, 66, 0, 10, 199, 88, 207, 103, 60, 95, 79, 20, 69, 0, 7, 196, 83, 99, 15, 16, 67, 7, 196, 77, 68, 203, 180, 66, 7, 196, 72, 191, 70, 92, 66, 12, 201, 67, 98, 72, 212, 84, 147, 15, 2, 75, 67, 0, 8, 197, 164, 114, 82, 119, 208, 67, 8, 197, 64, 243, 20, 79, 48, 67, 9, 198, 52, 148, 139, 196, 198, 203, 67, 8, 197, 44, 241, 207, 23, 176, 67, 8, 197, 20, 157, 228, 57, 32, 67, 0, 5, 194, 48, 144, 72, 9, 198, 49, 67, 143, 88, 241, 64, 67, 9, 198, 18, 113, 133, 157, 177, 64, 68, 9, 198, 12, 100, 246, 88, 241, 64, 67, 6, 195, 10, 212, 243, 66, 0, 10, 199, 10, 180, 251, 36, 243, 15, 16, 69, 0, 26, 4, 104, 116, 116, 112, 36, 57, 76, 47, 37, 12, 47, 37, 12, 6, 48, 37, 12, 10, 0, 81, 58, 47, 47, 32, 7, 196, 61, 51, 9, 12, 65, 6, 195, 46, 192, 113, 67, 6, 195, 31, 192, 85, 66, 0, 8, 197, 68, 18, 12, 60, 208, 66, 8, 197, 44, 19, 89, 36, 176, 66, 8, 197, 25, 2, 72, 60, 80, 67, 0, 9, 198, 128, 213, 17, 49, 66, 192, 67, 9, 198, 95, 194, 193, 20, 114, 96, 65, 6, 195, 164, 142, 195, 66, 9, 198, 45, 22, 195, 56, 146, 192, 66, 9, 198, 21, 22, 195, 56, 146, 192, 66, 6, 195, 8, 100, 243, 66, 0, 6, 195, 52, 18, 128, 72, 0, 7, 196, 79, 181, 201, 236, 67, 0, 8, 197, 77, 16, 85, 36, 176, 66, 8, 197, 73, 65, 71, 80, 176, 66, 8, 197, 68, 20, 147, 24, 112, 66, 8, 197, 67, 98, 1, 36, 176, 67, 8, 197, 157, 113, 131, 108, 80, 67, 0, 9, 198, 77, 16, 77, 12, 18, 128, 66, 9, 198, 52, 98, 15, 32, 242, 128, 67, 9, 198, 19, 98, 5, 60, 46, 192, 67, 6, 195, 10, 225, 147, 66, 0, 9, 198, 52, 146, 246, 17, 16, 85, 67, 6, 195, 36, 132, 236, 65, 10, 199, 9, 179, 4, 232, 245, 79, 8, 68, 0, 7, 196, 52, 21, 8, 236, 65, 6, 195, 19, 14, 237, 67, 0, 8, 197, 73, 64, 134, 45, 48, 66, 8, 197, 164, 92, 68, 61, 48, 65, 9, 198, 144, 33, 133, 164, 226, 75, 66, 8, 197, 44, 243, 111, 23, 192, 67, 9, 198, 20, 144, 66, 25, 50, 75, 68, 6, 195, 173, 179, 0, 66, 0, 15, 4, 95, 48, 77, 50, 65, 37, 55, 37, 6, 39, 50, 35, 0, 5, 194, 179, 128, 66, 9, 198, 44, 97, 6, 48, 43, 192, 65, 6, 195, 8, 241, 151, 66, 0, 16, 4, 95, 48, 77, 51, 65, 37, 55, 37, 6, 35, 34, 72, 35, 0, 10, 199, 168, 81, 143, 79, 179, 113, 180, 70, 0, 8, 196, 64, 244, 169, 20, 72, 23, 7, 196, 99, 166, 65, 84, 66, 0, 14, 4, 95, 48, 77, 49, 99, 6, 37, 55, 35, 72, 37, 0, 8, 197, 73, 178, 204, 25, 48, 66, 8, 197, 164, 142, 195, 5, 48, 67, 6, 195, 61, 59, 0, 65, 8, 197, 140, 179, 205, 25, 112, 65, 9, 198, 25, 11, 134, 65, 50, 75, 68, 8, 197, 4, 93, 75, 5, 48, 67, 0, 9, 198, 72, 98, 210, 5, 11, 128, 67, 6, 195, 68, 18, 179, 66, 9, 198, 46, 209, 91, 69, 179, 64, 67, 0, 9, 198, 75, 185, 207, 23, 211, 197, 69, 6, 195, 74, 220, 192, 66, 6, 195, 10, 220, 192, 66, 0, 9, 198, 91, 210, 72, 206, 83, 0, 68, 7, 196, 9, 66, 210, 240, 66, 0, 8, 197, 75, 19, 204, 60, 64, 67, 8, 197, 64, 99, 9, 46, 240, 67, 8, 197, 44, 25, 76, 60, 64, 67, 0, 9, 198, 88, 244, 240, 76, 244, 192, 67, 9, 198, 65, 180, 198, 64, 148, 128, 67, 0, 9, 198, 73, 62, 198, 61, 91, 141, 68, 10, 199, 66, 145, 82, 150, 164, 198, 48, 66, 0, 8, 196, 144, 180, 65, 40, 72, 23, 7, 196, 85, 68, 78, 240, 66, 11, 200, 52, 146, 246, 8, 147, 204, 60, 64, 69, 7, 196, 45, 68, 100, 32, 66, 7, 196, 36, 132, 9, 76, 65, 7, 196, 11, 162, 83, 204, 67, 0, 9, 198, 52, 146, 47, 73, 124, 0, 67, 9, 198, 45, 79, 148, 32, 197, 11, 67, 8, 197, 24, 179, 204, 60, 64, 67, 6, 195, 10, 219, 210, 66, 0, 9, 198, 95, 4, 212, 68, 156, 192, 68, 6, 195, 222, 67, 147, 66, 6, 195, 225, 50, 75, 66, 9, 198, 54, 242, 85, 25, 36, 192, 67, 0, 10, 199, 145, 4, 91, 73, 51, 137, 44, 65, 0, 7, 196, 73, 68, 201, 192, 67, 7, 196, 24, 180, 165, 32, 66, 7, 196, 232, 43, 70, 76, 67, 0, 8, 197, 92, 100, 6, 51, 16, 67, 9, 198, 84, 16, 145, 36, 187, 211, 67, 9, 198, 220, 80, 69, 28, 152, 0, 65, 8, 197, 44, 243, 80, 5, 32, 66, 9, 198, 16, 147, 100, 73, 50, 75, 67, 8, 197, 5, 66, 215, 39, 48, 68, 0, 6, 195, 160, 49, 135, 66, 6, 195, 47, 176, 239, 66, 0, 9, 198, 57, 242, 189, 45, 139, 241, 66, 0, 7, 196, 140, 212, 198, 28, 66, 7, 196, 47, 211, 137, 32, 66, 7, 196, 20, 99, 21, 196, 66, 0, 6, 195, 68, 25, 74, 66, 8, 197, 66, 149, 73, 45, 32, 66, 8, 197, 52, 240, 137, 87, 48, 65, 9, 198, 44, 194, 77, 5, 50, 75, 67, 8, 197, 8, 20, 147, 39, 48, 67, 0, 5, 194, 52, 144, 72, 0, 9, 198, 20, 149, 123, 193, 114, 109, 69, 10, 199, 4, 77, 130, 36, 243, 15, 16, 69, 0, 7, 196, 88, 148, 233, 92, 66, 11, 200, 73, 51, 205, 188, 240, 134, 79, 48, 69, 6, 195, 67, 160, 85, 66, 7, 196, 192, 150, 58, 196, 66, 7, 196, 9, 68, 75, 188, 66, 0, 0, 9, 198, 72, 19, 84, 68, 18, 128, 67, 6, 195, 66, 152, 211, 66, 9, 198, 60, 33, 140, 37, 34, 192, 67, 0, 10, 199, 72, 191, 79, 73, 51, 205, 236, 68, 10, 199, 64, 241, 80, 37, 35, 137, 44, 65, 0, 7, 196, 48, 244, 137, 204, 67, 0, 8, 197, 66, 208, 77, 80, 80, 67, 8, 197, 44, 17, 118, 168, 176, 67, 9, 198, 193, 53, 18, 36, 20, 147, 68, 0, 9, 198, 88, 244, 198, 48, 158, 192, 68, 9, 198, 64, 100, 207, 8, 242, 128, 67, 0, 10, 199, 99, 208, 129, 20, 123, 155, 44, 68, 10, 199, 20, 99, 115, 73, 52, 111, 76, 67, 0, 11, 200, 33, 176, 143, 76, 101, 142, 36, 176, 68, 7, 196, 175, 209, 70, 204, 68, 0, 8, 197, 20, 144, 66, 25, 48, 67, 8, 197, 12, 22, 112, 25, 112, 65, 0, 0, 9, 198, 66, 52, 206, 61, 99, 197, 67, 10, 199, 44, 16, 145, 36, 243, 6, 76, 68, 0, 6, 195, 84, 159, 69, 66, 11, 200, 67, 101, 75, 60, 210, 83, 25, 48, 68, 12, 201, 48, 147, 115, 4, 80, 69, 28, 152, 0, 67, 9, 198, 33, 176, 143, 48, 98, 250, 67, 0, 8, 197, 77, 16, 80, 25, 112, 66, 9, 198, 216, 84, 147, 15, 2, 75, 65, 8, 197, 65, 16, 82, 25, 112, 66, 8, 197, 44, 16, 177, 25, 48, 67, 8, 197, 9, 18, 75, 25, 48, 66, 0, 9, 198, 95, 177, 141, 204, 155, 64, 69, 0, 10, 199, 197, 33, 139, 76, 149, 201, 20, 68, 6, 195, 196, 20, 192, 66, 0, 9, 198, 216, 83, 197, 192, 93, 142, 68, 11, 200, 68, 17, 73, 60, 16, 179, 5, 48, 70, 0, 6, 195, 160, 61, 142, 66, 8, 197, 47, 178, 240, 24, 128, 67, 0, 9, 198, 64, 243, 6, 16, 20, 192, 67, 9, 198, 64, 20, 209, 36, 244, 192, 67, 9, 198, 47, 52, 144, 24, 180, 192, 66, 0, 0, 7, 196, 77, 68, 78, 240, 66, 7, 196, 61, 48, 137, 12, 65, 7, 196, 180, 219, 193, 88, 67, 0, 8, 197, 77, 18, 80, 140, 224, 66, 8, 197, 52, 17, 71, 80, 224, 66, 6, 195, 46, 208, 74, 66, 8, 197, 20, 240, 187, 54, 240, 65, 0, 9, 198, 44, 243, 80, 48, 244, 192, 66, 9, 198, 44, 243, 66, 196, 20, 192, 67, 0, 6, 195, 12, 98, 60, 66, 0, 7, 196, 87, 211, 109, 196, 67, 7, 196, 86, 249, 82, 76, 66, 7, 196, 20, 241, 39, 244, 65, 6, 195, 212, 18, 189, 67, 0, 9, 198, 64, 193, 141, 192, 226, 75, 65, 8, 197, 66, 51, 139, 79, 48, 66, 9, 198, 224, 242, 9, 92, 156, 251, 70, 9, 198, 160, 89, 207, 48, 226, 75, 68, 8, 197, 52, 148, 137, 207, 176, 68, 8, 197, 47, 50, 212, 69, 32, 66, 8, 197, 24, 180, 144, 165, 32, 66, 8, 197, 9, 243, 6, 79, 16, 67, 0, 9, 198, 52, 227, 196, 61, 131, 48, 67, 0, 0, 7, 195, 56, 146, 0, 72, 23, 7, 196, 66, 145, 39, 244, 65, 7, 196, 67, 160, 85, 196, 67, 7, 196, 36, 129, 39, 244, 65, 7, 196, 33, 176, 134, 92, 66, 0, 8, 197, 77, 16, 84, 51, 176, 65, 8, 197, 76, 105, 78, 81, 32, 65, 8, 197, 161, 68, 144, 25, 96, 67, 8, 197, 12, 18, 6, 51, 16, 67, 6, 195, 189, 80, 82, 66, 0, 5, 194, 72, 16, 72, 5, 194, 56, 144, 72, 6, 195, 4, 32, 83, 66, 0, 10, 199, 67, 100, 144, 236, 148, 198, 76, 68, 12, 201, 47, 164, 207, 86, 195, 205, 8, 18, 142, 69, 9, 198, 20, 147, 79, 61, 61, 69, 68, 0, 7, 196, 46, 144, 193, 76, 66, 7, 196, 44, 243, 73, 44, 66, 7, 196, 8, 18, 45, 76, 66, 0, 8, 197, 148, 35, 15, 36, 80, 67, 0, 6, 194, 184, 144, 72, 23, 6, 194, 172, 240, 72, 23, 9, 198, 81, 41, 66, 5, 146, 96, 66, 9, 198, 145, 18, 207, 76, 146, 192, 67, 0, 0, 7, 196, 75, 176, 134, 32, 66, 7, 196, 67, 212, 233, 76, 66, 7, 196, 45, 77, 145, 76, 66, 7, 196, 47, 170, 212, 48, 67, 7, 196, 29, 68, 100, 48, 66, 7, 196, 25, 81, 139, 76, 66, 0, 8, 197, 76, 101, 142, 36, 176, 66, 8, 197, 64, 243, 49, 60, 208, 67, 8, 197, 66, 217, 142, 36, 176, 65, 12, 201, 188, 100, 147, 24, 130, 79, 48, 241, 0, 70, 0, 9, 198, 64, 20, 207, 48, 241, 0, 67, 9, 198, 10, 218, 15, 48, 241, 0, 68, 0, 10, 199, 89, 64, 143, 73, 51, 137, 44, 67, 0, 6, 195, 52, 18, 189, 66, 7, 196, 44, 243, 24, 188, 66, 7, 196, 47, 176, 83, 196, 67, 0, 8, 197, 104, 145, 12, 25, 112, 66, 8, 197, 73, 77, 132, 5, 48, 67, 8, 197, 44, 62, 147, 25, 48, 66, 0, 0, 10, 199, 20, 99, 9, 44, 20, 198, 72, 68, 0, 7, 196, 164, 140, 221, 244, 67, 7, 196, 47, 160, 137, 20, 66, 6, 195, 20, 147, 197, 66, 0, 9, 198, 73, 3, 6, 76, 226, 75, 66, 8, 197, 52, 101, 240, 5, 48, 67, 9, 198, 52, 105, 85, 36, 130, 75, 68, 9, 198, 44, 243, 6, 72, 226, 75, 67, 9, 198, 36, 213, 14, 37, 49, 147, 68, 0, 0, 10, 199, 73, 64, 251, 192, 148, 198, 76, 69, 6, 195, 47, 193, 152, 66, 10, 199, 169, 34, 207, 32, 148, 198, 76, 68, 0, 12, 201, 65, 180, 117, 36, 132, 207, 96, 226, 75, 67, 7, 196, 64, 241, 70, 52, 66, 7, 196, 67, 177, 6, 48, 66, 7, 196, 140, 47, 111, 76, 67, 7, 196, 45, 79, 148, 32, 66, 7, 196, 16, 213, 41, 92, 66, 7, 196, 8, 244, 165, 56, 66, 7, 196, 189, 50, 68, 192, 67, 0, 8, 197, 87, 162, 82, 24, 160, 67, 12, 201, 80, 196, 209, 4, 210, 75, 217, 34, 248, 69, 0, 0, 0, 6, 195, 74, 241, 109, 66, 7, 196, 5, 60, 37, 76, 67, 0, 8, 197, 68, 18, 5, 24, 192, 66, 8, 197, 67, 98, 72, 212, 192, 67, 8, 197, 47, 165, 73, 60, 192, 67, 8, 197, 16, 243, 15, 18, 240, 67, 0, 9, 198, 65, 34, 86, 224, 20, 192, 67, 9, 198, 48, 98, 211, 244, 20, 192, 67, 9, 198, 47, 53, 76, 36, 180, 192, 66, 9, 198, 44, 243, 80, 189, 220, 192, 67, 6, 195, 24, 130, 75, 66, 6, 195, 9, 250, 75, 66, 0, 10, 199, 73, 179, 73, 100, 204, 9, 44, 66, 9, 198, 45, 66, 212, 69, 66, 0, 67, 0, 7, 196, 32, 17, 39, 244, 65, 0, 12, 201, 68, 17, 73, 61, 49, 140, 25, 92, 192, 70, 9, 198, 64, 243, 65, 34, 242, 75, 66, 8, 197, 66, 242, 233, 5, 32, 67, 0, 38, 3, 95, 194, 171, 55, 38, 4, 35, 84, 35, 15, 72, 84, 4, 39, 37, 50, 35, 15, 47, 34, 37, 4, 13, 81, 35, 55, 50, 35, 15, 89, 49, 6, 39, 71, 35, 0, 0, 10, 199, 52, 21, 141, 81, 19, 20, 44, 67, 0, 12, 201, 96, 100, 252, 37, 177, 27, 48, 226, 75, 68, 7, 196, 66, 144, 198, 72, 66, 7, 196, 55, 62, 15, 48, 67, 7, 196, 28, 144, 198, 92, 66, 11, 200, 168, 81, 143, 76, 99, 6, 87, 48, 70, 7, 196, 188, 20, 207, 52, 67, 0, 24, 3, 95, 194, 166, 48, 34, 36, 49, 4, 13, 89, 50, 35, 47, 35, 15, 76, 36, 34, 47, 6, 35, 0, 12, 201, 48, 148, 251, 5, 53, 54, 12, 97, 64, 70, 8, 197, 28, 145, 12, 119, 208, 66, 6, 195, 23, 17, 46, 66, 0, 9, 198, 73, 59, 15, 60, 35, 112, 68, 0, 0, 6, 195, 78, 196, 177, 66, 6, 195, 52, 17, 253, 66, 7, 196, 48, 145, 14, 196, 66, 7, 196, 47, 57, 75, 76, 66, 0, 8, 197, 75, 30, 19, 36, 176, 67, 0, 9, 198, 66, 209, 153, 56, 146, 192, 65, 9, 198, 20, 148, 144, 189, 46, 192, 67, 0, 9, 198, 65, 50, 87, 24, 54, 197, 67, 9, 198, 67, 168, 205, 193, 55, 125, 68, 8, 197, 20, 53, 24, 51, 0, 66, 9, 198, 169, 113, 129, 20, 223, 45, 69, 10, 199, 8, 146, 195, 4, 84, 65, 76, 67, 0, 7, 196, 77, 67, 20, 52, 66, 7, 196, 67, 96, 137, 12, 65, 7, 196, 25, 34, 253, 76, 66, 7, 196, 8, 148, 35, 56, 66, 6, 195, 4, 33, 109, 66, 0, 12, 201, 65, 34, 86, 62, 251, 73, 76, 146, 192, 70, 9, 198, 52, 109, 197, 60, 34, 67, 67, 8, 197, 44, 253, 208, 4, 80, 67, 8, 197, 44, 20, 24, 80, 176, 66, 12, 201, 20, 243, 79, 81, 4, 102, 37, 49, 140, 68, 8, 197, 18, 49, 78, 36, 176, 66, 8, 197, 212, 94, 54, 212, 80, 68, 0, 15, 66, 73, 48, 89, 47, 39, 47, 6, 37, 50, 49, 37, 0, 24, 9, 198, 96, 148, 147, 56, 146, 192, 66, 9, 198, 172, 17, 70, 52, 146, 192, 68, 0, 10, 199, 161, 13, 139, 225, 43, 201, 44, 67, 0, 9, 198, 60, 194, 68, 61, 90, 78, 68, 11, 200, 24, 180, 139, 81, 18, 39, 60, 80, 68, 7, 196, 13, 180, 83, 224, 66, 7, 196, 189, 60, 201, 52, 67, 0, 8, 197, 164, 180, 253, 5, 48, 67, 9, 198, 54, 249, 76, 37, 49, 147, 68, 8, 197, 22, 196, 253, 5, 48, 67, 8, 197, 5, 49, 146, 149, 48, 67, 0, 9, 198, 99, 179, 143, 32, 99, 64, 67, 6, 195, 141, 81, 147, 66, 6, 195, 20, 144, 239, 66, 0, 0, 7, 196, 220, 197, 70, 28, 66, 7, 196, 145, 55, 233, 48, 67, 12, 201, 52, 227, 196, 61, 177, 27, 48, 226, 75, 67, 7, 196, 54, 49, 70, 28, 66, 7, 196, 52, 101, 239, 196, 67, 7, 196, 54, 241, 139, 192, 67, 0, 9, 198, 74, 80, 174, 37, 49, 147, 68, 8, 197, 44, 244, 147, 81, 16, 66, 8, 197, 16, 102, 70, 85, 48, 66, 0, 0, 6, 195, 87, 3, 204, 66, 6, 195, 156, 100, 128, 66, 0, 7, 196, 67, 96, 143, 40, 66, 7, 196, 66, 145, 70, 48, 66, 7, 196, 52, 241, 70, 52, 66, 6, 195, 44, 101, 109, 66, 7, 196, 44, 17, 70, 52, 66, 6, 195, 168, 135, 125, 66, 7, 196, 8, 17, 70, 52, 66, 0, 8, 197, 64, 243, 46, 24, 160, 67, 8, 197, 60, 36, 147, 164, 192, 66, 8, 197, 20, 101, 201, 54, 208, 67, 8, 197, 16, 99, 204, 60, 64, 67, 0, 9, 198, 16, 244, 144, 60, 92, 64, 67, 0, 9, 198, 13, 67, 133, 236, 188, 69, 65, 6, 195, 154, 244, 128, 66, 0, 7, 196, 52, 241, 70, 48, 66, 0, 8, 197, 87, 163, 65, 220, 224, 67, 0, 9, 198, 46, 208, 77, 9, 68, 64, 67, 6, 195, 4, 164, 111, 66, 0, 10, 199, 52, 20, 209, 39, 165, 129, 76, 68, 10, 199, 189, 50, 66, 36, 244, 201, 44, 69, 0, 7, 196, 88, 19, 84, 76, 66, 7, 196, 86, 245, 122, 204, 67, 7, 196, 221, 84, 212, 236, 65, 9, 198, 67, 100, 212, 11, 187, 210, 68, 7, 196, 64, 19, 84, 44, 66, 7, 196, 64, 17, 70, 28, 66, 0, 9, 198, 67, 100, 198, 74, 83, 147, 67, 8, 197, 44, 240, 85, 119, 208, 67, 0, 6, 195, 14, 209, 135, 66, 0, 10, 199, 23, 82, 139, 4, 81, 201, 128, 65, 10, 199, 8, 20, 139, 25, 48, 143, 48, 65, 0, 7, 196, 79, 2, 20, 88, 66, 7, 196, 149, 16, 83, 244, 67, 7, 196, 244, 156, 19, 240, 68, 12, 201, 24, 113, 146, 24, 83, 73, 96, 226, 75, 67, 7, 196, 9, 70, 77, 192, 66, 0, 12, 201, 73, 14, 205, 5, 51, 200, 60, 145, 64, 69, 8, 197, 55, 52, 176, 119, 208, 67, 6, 195, 37, 160, 86, 66, 9, 198, 19, 161, 123, 60, 34, 123, 69, 0, 9, 198, 45, 66, 204, 156, 241, 64, 67, 0, 10, 199, 92, 155, 231, 60, 95, 79, 20, 70, 10, 199, 44, 20, 1, 92, 148, 198, 76, 68, 0, 7, 196, 61, 48, 143, 40, 66, 7, 196, 32, 21, 163, 72, 66, 0, 8, 197, 65, 26, 211, 36, 176, 66, 8, 197, 55, 6, 70, 168, 176, 67, 9, 198, 189, 50, 80, 5, 32, 83, 68, 0, 0, 7, 195, 65, 178, 192, 72, 23, 0, 0, 8, 197, 77, 68, 19, 24, 112, 66, 8, 197, 73, 180, 54, 212, 80, 67, 8, 197, 64, 100, 147, 36, 176, 66, 9, 198, 24, 178, 9, 73, 60, 23, 67, 0, 9, 198, 54, 98, 15, 48, 98, 128, 67, 0, 6, 195, 90, 107, 192, 66, 0, 7, 196, 64, 243, 39, 196, 67, 7, 196, 64, 96, 198, 92, 66, 7, 196, 160, 209, 165, 48, 67, 7, 196, 32, 101, 147, 196, 66, 7, 196, 16, 241, 70, 28, 66, 7, 196, 8, 241, 70, 28, 66, 0, 0, 38, 3, 95, 194, 187, 116, 4, 35, 89, 50, 35, 15, 72, 84, 4, 39, 37, 50, 35, 15, 47, 34, 37, 4, 13, 81, 35, 55, 50, 35, 15, 89, 49, 6, 39, 71, 35, 0, 0, 6, 195, 98, 187, 64, 66, 10, 199, 72, 52, 91, 89, 137, 198, 44, 67, 6, 195, 74, 107, 192, 66, 0, 7, 195, 66, 146, 0, 72, 23, 6, 195, 15, 188, 237, 67, 0, 8, 197, 88, 145, 81, 5, 48, 66, 8, 197, 72, 186, 237, 25, 112, 67, 6, 195, 52, 29, 206, 66, 0, 5, 194, 72, 96, 72, 9, 198, 88, 145, 118, 66, 51, 128, 67, 0, 10, 199, 88, 99, 9, 60, 68, 65, 84, 68, 10, 199, 68, 17, 73, 60, 68, 65, 84, 68, 10, 199, 47, 161, 73, 60, 68, 65, 84, 68, 10, 199, 44, 20, 9, 77, 72, 206, 76, 68, 10, 199, 17, 22, 205, 60, 244, 245, 20, 68, 0, 7, 196, 85, 65, 1, 72, 66, 7, 196, 72, 19, 84, 68, 66, 11, 200, 52, 100, 198, 244, 241, 17, 5, 80, 69, 7, 196, 47, 52, 246, 48, 66, 11, 200, 37, 36, 253, 36, 241, 17, 5, 80, 69, 7, 196, 13, 180, 72, 224, 66, 11, 200, 8, 144, 140, 36, 241, 17, 5, 80, 68, 0, 6, 195, 68, 149, 250, 65, 12, 201, 67, 97, 139, 76, 241, 79, 18, 127, 64, 68, 8, 197, 11, 101, 14, 196, 64, 65, 8, 197, 8, 147, 204, 60, 64, 67, 0, 9, 198, 76, 98, 232, 84, 100, 128, 67, 9, 198, 197, 62, 213, 24, 164, 128, 67, 6, 195, 19, 177, 111, 66, 9, 198, 233, 98, 80, 26, 49, 0, 68, 0, 10, 199, 64, 243, 20, 36, 82, 79, 76, 69, 9, 198, 19, 181, 14, 20, 149, 13, 66, 0, 7, 196, 99, 1, 6, 48, 66, 7, 196, 79, 179, 9, 44, 66, 7, 196, 72, 97, 70, 84, 66, 9, 198, 68, 17, 70, 76, 99, 0, 67, 9, 198, 64, 244, 140, 25, 2, 82, 67, 7, 196, 54, 241, 65, 76, 66, 7, 196, 45, 64, 251, 76, 66, 7, 196, 46, 244, 243, 236, 67, 7, 196, 21, 180, 77, 204, 66, 7, 196, 19, 177, 6, 84, 66, 7, 196, 154, 241, 58, 20, 67, 0, 8, 197, 86, 227, 204, 60, 64, 67, 8, 197, 66, 145, 76, 60, 64, 66, 8, 197, 20, 96, 134, 140, 224, 67, 8, 197, 180, 179, 214, 60, 192, 67, 6, 195, 180, 155, 210, 67, 0, 9, 198, 24, 180, 147, 70, 180, 192, 66, 0, 9, 198, 217, 51, 73, 73, 54, 209, 65, 6, 195, 175, 209, 64, 66, 0, 7, 196, 53, 66, 6, 40, 66, 7, 196, 47, 160, 143, 48, 66, 7, 196, 44, 17, 70, 76, 66, 7, 196, 172, 59, 111, 16, 67, 0, 6, 195, 72, 111, 0, 66, 8, 197, 66, 52, 147, 187, 16, 67, 8, 197, 140, 36, 65, 23, 208, 67, 8, 197, 45, 68, 139, 81, 32, 66, 8, 197, 22, 226, 71, 189, 32, 67, 0, 9, 198, 65, 180, 67, 192, 101, 192, 67, 6, 195, 66, 195, 51, 66, 0, 10, 199, 72, 184, 197, 4, 81, 201, 128, 65, 0, 7, 196, 91, 161, 84, 236, 65, 12, 201, 52, 242, 1, 40, 176, 69, 28, 152, 0, 66, 7, 196, 44, 20, 147, 244, 66, 0, 8, 197, 77, 27, 210, 87, 176, 66, 8, 197, 76, 243, 59, 189, 32, 67, 8, 197, 73, 69, 73, 45, 32, 66, 9, 198, 72, 100, 147, 71, 18, 75, 65, 9, 198, 44, 243, 70, 20, 155, 211, 68, 8, 197, 44, 243, 2, 5, 32, 66, 8, 197, 24, 208, 145, 39, 48, 67, 0, 6, 194, 56, 240, 72, 23, 0, 0, 0, 6, 195, 66, 57, 78, 66, 8, 197, 64, 99, 19, 24, 176, 66, 8, 197, 34, 110, 176, 36, 176, 66, 8, 197, 189, 50, 80, 60, 80, 67, 0, 6, 195, 55, 17, 123, 66, 9, 198, 183, 163, 65, 20, 114, 96, 66, 0, 0, 7, 196, 164, 62, 239, 72, 67, 7, 196, 66, 149, 163, 72, 66, 6, 195, 46, 209, 141, 66, 7, 196, 15, 162, 111, 76, 67, 7, 196, 8, 144, 187, 204, 67, 0, 8, 197, 67, 100, 176, 36, 176, 67, 16, 205, 61, 49, 152, 25, 36, 195, 192, 245, 118, 57, 57, 198, 92, 70, 8, 197, 52, 148, 147, 36, 176, 66, 8, 197, 55, 18, 77, 80, 208, 65, 8, 197, 52, 105, 76, 36, 176, 67, 8, 197, 168, 62, 137, 80, 208, 66, 8, 197, 172, 62, 137, 80, 208, 66, 0, 0, 9, 198, 76, 101, 142, 36, 181, 13, 65, 10, 199, 64, 193, 139, 72, 145, 35, 72, 67, 0, 7, 196, 165, 114, 101, 48, 67, 0, 6, 195, 84, 148, 238, 66, 8, 197, 73, 67, 21, 5, 48, 66, 8, 197, 67, 162, 83, 25, 48, 67, 9, 198, 16, 100, 165, 66, 113, 151, 66, 8, 197, 13, 16, 66, 25, 112, 66, 8, 197, 153, 59, 17, 5, 48, 67, 0, 9, 198, 73, 4, 113, 77, 223, 64, 66, 6, 195, 66, 177, 147, 66, 0, 0, 8, 196, 52, 97, 197, 80, 72, 23, 11, 200, 88, 145, 118, 73, 67, 21, 5, 48, 68, 7, 196, 74, 129, 198, 92, 66, 7, 196, 72, 19, 84, 56, 66, 6, 195, 68, 149, 241, 66, 7, 196, 32, 20, 140, 204, 66, 0, 8, 197, 73, 176, 145, 5, 48, 66, 9, 198, 73, 64, 147, 217, 2, 75, 67, 9, 198, 65, 18, 89, 24, 193, 151, 67, 0, 14, 66, 64, 192, 48, 55, 39, 91, 47, 6, 35, 47, 0, 24, 6, 195, 79, 90, 87, 66, 9, 198, 5, 36, 209, 4, 75, 192, 67, 0, 0, 7, 196, 45, 68, 73, 236, 67, 7, 196, 31, 164, 201, 236, 67, 11, 200, 24, 193, 139, 79, 97, 17, 5, 80, 68, 7, 196, 172, 62, 134, 48, 67, 0, 8, 197, 60, 34, 88, 4, 160, 67, 8, 197, 47, 210, 85, 24, 160, 67, 0, 9, 198, 92, 149, 123, 10, 52, 192, 65, 9, 198, 86, 181, 12, 76, 100, 192, 67, 9, 198, 64, 19, 85, 48, 100, 192, 66, 9, 198, 47, 52, 209, 6, 212, 192, 67, 6, 195, 8, 146, 51, 66, 0, 6, 195, 18, 61, 88, 66, 0, 11, 200, 66, 145, 80, 4, 130, 83, 24, 192, 66, 7, 196, 55, 62, 35, 56, 67, 7, 196, 7, 190, 35, 56, 68, 0, 8, 197, 67, 213, 198, 140, 224, 67, 8, 197, 58, 193, 65, 80, 224, 65, 8, 197, 32, 20, 147, 60, 160, 66, 9, 198, 34, 188, 248, 216, 98, 211, 69, 8, 197, 19, 161, 123, 60, 32, 67, 8, 197, 212, 83, 197, 24, 192, 67, 8, 197, 8, 19, 194, 4, 32, 67, 0, 9, 198, 197, 52, 73, 18, 244, 192, 67, 6, 195, 4, 47, 83, 66, 0, 10, 199, 73, 176, 233, 55, 3, 137, 44, 66, 0, 7, 196, 74, 129, 61, 196, 67, 7, 196, 60, 37, 143, 20, 66, 7, 196, 140, 142, 134, 76, 67, 7, 196, 11, 169, 198, 92, 65, 0, 6, 195, 57, 251, 210, 66, 8, 197, 52, 98, 44, 233, 0, 67, 8, 197, 46, 224, 193, 79, 176, 65, 8, 197, 17, 18, 77, 119, 208, 66, 9, 198, 212, 163, 137, 44, 198, 203, 67, 8, 197, 8, 99, 39, 141, 32, 67, 0, 9, 198, 72, 214, 209, 20, 97, 192, 66, 9, 198, 53, 16, 72, 156, 101, 192, 65, 9, 198, 140, 225, 68, 68, 21, 64, 66, 9, 198, 46, 210, 68, 68, 21, 64, 67, 9, 198, 13, 177, 12, 236, 241, 64, 67, 0, 10, 199, 17, 16, 83, 37, 38, 9, 128, 65, 0, 7, 196, 52, 97, 70, 92, 66, 7, 196, 18, 61, 105, 32, 67, 0, 6, 195, 84, 29, 206, 66, 8, 197, 36, 212, 20, 49, 32, 66, 8, 197, 4, 36, 151, 25, 32, 66, 0, 5, 194, 72, 144, 72, 9, 198, 72, 180, 73, 64, 101, 192, 66, 9, 198, 64, 148, 207, 52, 101, 192, 65, 6, 195, 67, 169, 175, 67, 9, 198, 16, 16, 182, 12, 101, 192, 65, 9, 198, 13, 16, 71, 180, 101, 192, 67, 0, 6, 195, 149, 53, 12, 66, 9, 198, 197, 62, 228, 92, 156, 237, 70, 0, 7, 196, 88, 243, 79, 76, 66, 7, 196, 88, 147, 73, 44, 66, 7, 196, 84, 20, 148, 48, 66, 7, 196, 221, 3, 227, 56, 67, 6, 195, 165, 53, 25, 66, 7, 196, 61, 50, 9, 12, 65, 0, 8, 197, 64, 22, 109, 108, 176, 67, 0, 9, 198, 84, 242, 187, 15, 178, 192, 65, 0, 10, 199, 67, 195, 211, 25, 99, 137, 44, 68, 0, 11, 200, 65, 180, 117, 53, 182, 48, 36, 176, 69, 7, 196, 67, 212, 236, 180, 67, 6, 195, 50, 197, 13, 66, 7, 196, 44, 20, 137, 236, 67, 0, 8, 197, 84, 197, 61, 36, 80, 67, 8, 197, 52, 101, 140, 24, 208, 66, 8, 197, 45, 68, 89, 80, 208, 66, 8, 197, 47, 160, 77, 86, 224, 67, 0, 6, 195, 47, 209, 115, 66, 6, 195, 37, 161, 151, 66, 0, 6, 195, 79, 203, 192, 66, 9, 198, 73, 67, 21, 4, 210, 69, 67, 10, 199, 68, 17, 73, 179, 53, 251, 76, 69, 10, 199, 64, 20, 209, 39, 165, 129, 76, 68, 6, 195, 47, 219, 64, 66, 0, 7, 196, 64, 98, 211, 196, 66, 7, 196, 212, 94, 1, 20, 67, 0, 8, 197, 65, 67, 139, 79, 192, 66, 8, 197, 56, 144, 198, 51, 192, 67, 8, 197, 52, 21, 73, 61, 48, 67, 8, 197, 25, 2, 83, 25, 48, 67, 0, 6, 195, 44, 246, 47, 66, 9, 198, 46, 227, 196, 68, 19, 64, 67, 9, 198, 193, 51, 205, 60, 195, 196, 68, 0, 6, 195, 87, 27, 64, 66, 10, 199, 54, 242, 85, 25, 41, 78, 76, 68, 0, 11, 200, 80, 226, 67, 237, 34, 83, 25, 48, 69, 11, 200, 73, 1, 151, 38, 210, 83, 25, 48, 69, 6, 195, 46, 226, 77, 66, 0, 8, 197, 88, 18, 163, 41, 80, 66, 9, 198, 52, 20, 139, 232, 198, 203, 67, 8, 197, 24, 194, 75, 75, 192, 67, 8, 197, 20, 144, 82, 47, 128, 67, 0, 9, 198, 36, 36, 73, 100, 147, 64, 67, 0, 6, 195, 46, 214, 208, 66, 0, 7, 196, 76, 99, 70, 48, 66, 7, 196, 64, 241, 54, 52, 66, 7, 196, 67, 171, 70, 48, 67, 7, 196, 64, 20, 20, 68, 66, 6, 195, 55, 23, 125, 66, 0, 0, 9, 198, 68, 146, 207, 100, 100, 192, 67, 9, 198, 141, 28, 68, 61, 92, 192, 68, 9, 198, 44, 25, 80, 80, 196, 192, 67, 0, 0, 7, 196, 96, 100, 9, 44, 66, 7, 196, 148, 180, 201, 44, 66, 7, 196, 47, 53, 251, 76, 66, 6, 195, 46, 214, 213, 66, 7, 196, 8, 98, 193, 72, 66, 7, 196, 153, 59, 35, 12, 67, 0, 8, 197, 45, 18, 82, 148, 192, 66, 0, 9, 198, 72, 19, 79, 48, 100, 192, 67, 9, 198, 60, 211, 137, 9, 68, 128, 65, 9, 198, 52, 146, 246, 128, 137, 252, 69, 6, 195, 19, 171, 211, 66, 0, 6, 195, 98, 182, 204, 66, 10, 199, 75, 180, 201, 84, 146, 193, 76, 68, 10, 199, 72, 98, 212, 56, 83, 205, 236, 68, 10, 199, 67, 99, 73, 100, 204, 9, 44, 66, 9, 198, 44, 243, 15, 21, 21, 13, 67, 10, 199, 44, 243, 6, 45, 114, 115, 236, 69, 10, 199, 24, 180, 151, 193, 52, 73, 44, 67, 0, 7, 196, 67, 2, 238, 236, 65, 6, 195, 144, 82, 61, 66, 6, 195, 44, 243, 113, 66, 0, 9, 198, 77, 27, 210, 67, 171, 211, 67, 6, 195, 44, 100, 186, 65, 0, 9, 198, 60, 211, 196, 68, 21, 64, 67, 9, 198, 52, 105, 76, 60, 145, 64, 68, 9, 198, 8, 147, 196, 68, 21, 64, 67, 0, 10, 199, 44, 226, 68, 60, 240, 141, 192, 68, 6, 195, 188, 241, 64, 66, 0, 7, 196, 64, 146, 198, 76, 66, 7, 196, 197, 62, 198, 72, 67, 7, 196, 10, 208, 82, 76, 66, 0, 9, 198, 85, 67, 139, 92, 156, 251, 68, 8, 197, 79, 180, 48, 79, 16, 67, 8, 197, 64, 241, 78, 61, 32, 66, 8, 197, 67, 162, 198, 79, 16, 67, 8, 197, 67, 160, 69, 177, 32, 67, 12, 201, 48, 98, 210, 36, 179, 196, 68, 21, 64, 68, 8, 197, 9, 179, 4, 235, 16, 65, 0, 5, 194, 76, 144, 72, 5, 194, 80, 112, 72, 6, 194, 64, 240, 72, 23, 9, 198, 5, 36, 251, 60, 145, 64, 68, 0, 9, 198, 22, 209, 139, 227, 109, 69, 69, 0, 7, 196, 81, 140, 9, 44, 67, 7, 196, 149, 2, 87, 236, 67, 7, 196, 165, 94, 193, 76, 67, 7, 196, 66, 50, 193, 76, 66, 6, 195, 67, 165, 237, 66, 7, 196, 47, 53, 251, 56, 66, 0, 8, 197, 85, 179, 133, 108, 176, 66, 8, 197, 77, 245, 76, 24, 176, 66, 8, 197, 77, 180, 77, 108, 176, 66, 8, 197, 65, 18, 75, 140, 80, 66, 8, 197, 66, 126, 240, 36, 176, 66, 9, 198, 44, 193, 144, 76, 243, 111, 67, 8, 197, 180, 81, 150, 36, 80, 67, 0, 0, 6, 195, 87, 14, 192, 66, 0, 7, 196, 66, 107, 137, 204, 68, 7, 196, 53, 177, 105, 92, 66, 6, 195, 47, 209, 141, 66, 11, 200, 13, 177, 12, 27, 81, 125, 60, 80, 69, 7, 196, 212, 94, 15, 40, 67, 7, 196, 8, 99, 44, 244, 67, 0, 26, 3, 95, 208, 142, 39, 71, 34, 4, 35, 47, 36, 50, 15, 40, 72, 37, 84, 6, 37, 47, 36, 55, 36, 50, 0, 7, 2, 95, 3, 84, 13, 0, 12, 201, 99, 179, 143, 11, 212, 129, 20, 114, 96, 67, 8, 197, 47, 49, 131, 108, 80, 67, 9, 198, 21, 64, 140, 36, 176, 83, 67, 0, 28, 3, 95, 209, 151, 39, 71, 34, 4, 35, 47, 36, 50, 15, 84, 13, 48, 34, 39, 89, 6, 37, 47, 36, 55, 36, 50, 0, 0, 6, 2, 95, 1, 35, 0, 10, 199, 52, 97, 79, 20, 240, 137, 12, 67, 6, 195, 190, 211, 196, 67, 0, 6, 2, 95, 6, 36, 0, 11, 200, 72, 49, 147, 157, 180, 83, 24, 112, 68, 6, 195, 166, 162, 61, 67, 7, 196, 56, 243, 65, 20, 66, 7, 196, 10, 242, 198, 76, 66, 0, 8, 197, 89, 64, 166, 25, 112, 67, 6, 195, 87, 17, 146, 66, 8, 197, 60, 37, 131, 5, 48, 66, 0, 12, 3, 95, 209, 147, 83, 55, 39, 34, 37, 50, 0, 7, 2, 95, 4, 81, 13, 0, 9, 198, 72, 147, 80, 76, 243, 64, 66, 6, 195, 46, 210, 239, 66, 9, 198, 19, 17, 139, 60, 195, 196, 68, 9, 198, 168, 81, 143, 86, 227, 64, 68, 6, 195, 8, 145, 115, 66, 0, 6, 195, 149, 27, 192, 66, 6, 195, 144, 195, 196, 66, 6, 195, 55, 31, 64, 66, 0, 8, 196, 73, 13, 147, 36, 72, 23, 7, 196, 79, 99, 6, 40, 66, 7, 196, 72, 20, 20, 56, 66, 0, 14, 2, 95, 10, 6, 37, 49, 34, 4, 35, 47, 49, 39, 0, 8, 197, 87, 178, 66, 61, 48, 65, 8, 197, 67, 98, 212, 217, 16, 67, 8, 197, 65, 16, 89, 25, 112, 66, 8, 197, 67, 160, 80, 25, 48, 67, 8, 197, 44, 24, 21, 25, 48, 67, 8, 197, 180, 19, 113, 81, 48, 68, 0, 6, 2, 95, 9, 37, 0, 9, 198, 88, 245, 77, 233, 155, 64, 65, 9, 198, 84, 146, 9, 60, 195, 196, 68, 9, 198, 244, 226, 83, 60, 195, 196, 68, 0, 6, 195, 11, 2, 49, 66, 0, 0, 7, 196, 75, 17, 118, 52, 66, 7, 196, 45, 64, 137, 44, 66, 0, 8, 197, 76, 99, 204, 60, 64, 67, 0, 9, 198, 45, 44, 15, 84, 240, 128, 67, 9, 198, 20, 99, 9, 76, 99, 0, 65, 0, 6, 195, 144, 76, 192, 66, 6, 195, 168, 140, 192, 66, 0, 7, 2, 95, 18, 89, 13, 0, 11, 200, 96, 100, 195, 109, 20, 213, 198, 208, 68, 7, 196, 66, 147, 73, 236, 67, 7, 196, 5, 81, 139, 76, 66, 0, 8, 197, 52, 245, 137, 46, 240, 67, 0, 9, 198, 25, 34, 201, 52, 244, 128, 67, 9, 198, 20, 148, 252, 4, 208, 128, 67, 0, 10, 199, 84, 193, 132, 52, 20, 201, 44, 67, 10, 199, 64, 241, 80, 245, 70, 9, 44, 65, 9, 198, 20, 98, 15, 23, 219, 211, 68, 0, 7, 196, 79, 180, 201, 64, 66, 7, 196, 44, 194, 82, 232, 65, 7, 196, 24, 195, 65, 32, 66, 0, 9, 198, 73, 180, 87, 24, 49, 133, 67, 0, 6, 2, 95, 20, 40, 0, 9, 198, 5, 3, 210, 79, 101, 64, 67, 0, 10, 199, 88, 193, 130, 60, 137, 143, 20, 68, 10, 199, 72, 49, 147, 60, 82, 79, 20, 68, 0, 7, 196, 92, 146, 204, 204, 66, 6, 195, 28, 100, 243, 66, 7, 196, 11, 2, 15, 48, 66, 0, 8, 197, 68, 17, 73, 81, 32, 65, 6, 195, 19, 179, 202, 66, 0, 9, 198, 52, 97, 1, 91, 181, 192, 67, 0, 6, 195, 55, 162, 64, 72, 9, 198, 76, 101, 142, 177, 16, 83, 67, 9, 198, 72, 49, 147, 48, 243, 123, 67, 9, 198, 140, 164, 205, 61, 50, 67, 65, 0, 7, 196, 74, 226, 75, 204, 67, 7, 196, 15, 160, 250, 196, 65, 7, 196, 5, 37, 109, 76, 66, 7, 196, 180, 146, 58, 196, 68, 0, 8, 197, 44, 243, 15, 36, 80, 67, 8, 197, 25, 129, 141, 36, 176, 67, 0, 9, 198, 73, 62, 1, 20, 114, 96, 65, 9, 198, 64, 246, 129, 20, 114, 96, 65, 9, 198, 53, 69, 101, 20, 114, 96, 65, 9, 198, 33, 176, 143, 8, 243, 0, 67, 9, 198, 31, 180, 195, 192, 146, 192, 65, 0, 0, 13, 2, 95, 34, 49, 35, 84, 6, 37, 76, 49, 37, 0, 7, 196, 87, 99, 147, 204, 66, 6, 195, 51, 194, 75, 66, 7, 196, 16, 96, 196, 240, 66, 7, 196, 14, 222, 201, 188, 68, 6, 195, 8, 25, 83, 66, 6, 195, 10, 242, 251, 66, 9, 198, 5, 36, 246, 48, 241, 0, 67, 0, 16, 2, 95, 33, 40, 72, 37, 84, 6, 37, 47, 36, 55, 36, 50, 0, 8, 197, 73, 244, 83, 80, 176, 66, 12, 201, 66, 145, 89, 25, 36, 195, 192, 146, 192, 66, 9, 198, 66, 244, 207, 17, 16, 85, 67, 8, 197, 49, 73, 16, 232, 176, 65, 0, 9, 198, 86, 196, 147, 236, 158, 192, 68, 6, 195, 164, 191, 69, 66, 9, 198, 44, 149, 99, 20, 114, 96, 65, 0, 14, 2, 95, 39, 35, 48, 39, 89, 47, 34, 6, 39, 83, 0, 10, 199, 74, 48, 224, 56, 245, 79, 8, 68, 10, 199, 72, 99, 6, 45, 114, 115, 236, 69, 6, 195, 50, 203, 64, 66, 10, 199, 21, 180, 117, 20, 240, 137, 12, 67, 6, 195, 10, 251, 192, 66, 0, 15, 2, 95, 38, 35, 65, 48, 36, 34, 89, 6, 35, 50, 47, 0, 6, 195, 56, 150, 111, 66, 7, 196, 11, 160, 148, 56, 66, 0, 8, 197, 73, 67, 37, 145, 48, 67, 8, 197, 74, 226, 75, 5, 48, 67, 8, 197, 67, 100, 198, 73, 48, 66, 8, 197, 67, 160, 89, 81, 48, 67, 0, 6, 195, 140, 133, 17, 66, 9, 198, 45, 22, 196, 60, 143, 64, 67, 0, 6, 195, 46, 107, 64, 66, 0, 7, 196, 96, 147, 89, 240, 66, 11, 200, 47, 52, 209, 5, 80, 68, 61, 48, 68, 7, 196, 25, 145, 140, 204, 67, 7, 196, 16, 235, 143, 96, 66, 0, 18, 2, 95, 41, 116, 4, 35, 89, 50, 35, 15, 89, 49, 6, 39, 71, 35, 0, 8, 197, 89, 16, 66, 165, 112, 66, 0, 18, 2, 95, 40, 55, 38, 6, 35, 84, 35, 15, 89, 49, 6, 39, 71, 35, 0, 9, 198, 87, 212, 141, 4, 127, 64, 67, 9, 198, 24, 180, 147, 236, 159, 64, 68, 9, 198, 5, 36, 246, 56, 243, 64, 67, 0, 0, 11, 2, 95, 46, 47, 6, 39, 76, 49, 35, 0, 7, 196, 92, 146, 204, 224, 66, 7, 196, 88, 244, 198, 48, 66, 6, 195, 75, 206, 0, 66, 7, 196, 70, 181, 17, 72, 66, 7, 196, 52, 101, 148, 68, 66, 0, 10, 2, 95, 45, 47, 37, 34, 4, 36, 0, 8, 197, 160, 189, 140, 60, 64, 67, 8, 197, 8, 20, 134, 40, 224, 66, 0, 14, 2, 95, 44, 88, 35, 48, 36, 47, 6, 35, 57, 35, 0, 9, 198, 48, 98, 210, 36, 188, 192, 67, 9, 198, 5, 52, 73, 9, 68, 192, 67, 9, 198, 188, 67, 15, 84, 240, 128, 67, 0, 9, 2, 95, 51, 47, 34, 6, 37, 0, 6, 195, 34, 188, 192, 66, 6, 195, 30, 220, 192, 66, 10, 199, 17, 27, 197, 88, 244, 198, 48, 67, 0, 9, 2, 95, 50, 72, 84, 6, 36, 0, 7, 196, 64, 100, 147, 184, 66, 9, 198, 45, 16, 82, 59, 130, 82, 67, 7, 196, 46, 242, 66, 180, 67, 7, 196, 32, 19, 65, 88, 66, 7, 196, 24, 208, 74, 48, 66, 7, 196, 8, 241, 212, 68, 66, 0, 10, 2, 95, 49, 36, 72, 50, 6, 39, 0, 8, 197, 81, 99, 194, 60, 192, 67, 8, 197, 64, 148, 139, 80, 224, 66, 8, 197, 8, 20, 147, 80, 224, 66, 0, 10, 2, 95, 48, 50, 6, 40, 64, 35, 0, 6, 195, 64, 99, 49, 66, 9, 198, 44, 25, 81, 32, 148, 128, 65, 0, 11, 2, 95, 55, 89, 6, 36, 72, 36, 65, 0, 9, 198, 73, 99, 227, 73, 50, 75, 67, 6, 195, 55, 171, 48, 67, 0, 10, 2, 95, 54, 91, 6, 36, 89, 47, 0, 7, 196, 76, 147, 80, 188, 66, 7, 196, 72, 19, 70, 92, 66, 7, 196, 66, 52, 198, 28, 66, 7, 196, 197, 62, 195, 180, 67, 7, 196, 172, 59, 230, 76, 67, 0, 9, 2, 95, 53, 48, 6, 36, 47, 0, 9, 198, 76, 96, 83, 216, 49, 133, 68, 8, 197, 68, 18, 4, 159, 208, 65, 8, 197, 64, 243, 9, 19, 48, 67, 8, 197, 21, 179, 4, 81, 128, 66, 0, 12, 2, 95, 52, 76, 6, 36, 47, 37, 34, 37, 0, 0, 23, 2, 95, 59, 47, 4, 39, 76, 49, 35, 15, 37, 15, 88, 35, 48, 36, 47, 6, 35, 57, 35, 0, 10, 199, 61, 89, 76, 52, 243, 15, 16, 68, 0, 15, 2, 95, 58, 72, 84, 40, 36, 47, 6, 39, 76, 37, 36, 0, 11, 200, 28, 99, 6, 32, 240, 134, 79, 48, 69, 0, 11, 2, 95, 57, 72, 6, 36, 84, 36, 47, 0, 8, 197, 66, 149, 123, 189, 32, 67, 8, 197, 67, 2, 87, 187, 16, 68, 8, 197, 66, 242, 75, 119, 208, 67, 8, 197, 44, 243, 80, 165, 32, 66, 8, 197, 14, 49, 15, 55, 176, 67, 0, 10, 2, 95, 56, 6, 39, 89, 36, 65, 0, 6, 195, 8, 22, 129, 66, 0, 18, 2, 95, 63, 84, 13, 48, 34, 39, 89, 6, 37, 47, 36, 55, 36, 50, 0, 10, 199, 52, 193, 139, 60, 137, 143, 20, 68, 10, 199, 8, 22, 73, 8, 242, 20, 44, 68, 0, 16, 2, 95, 62, 48, 39, 15, 81, 39, 55, 38, 6, 35, 65, 39, 0, 7, 196, 164, 228, 201, 236, 67, 6, 195, 67, 192, 83, 66, 7, 196, 176, 18, 9, 204, 68, 7, 196, 44, 243, 65, 76, 66, 7, 196, 44, 241, 70, 196, 67, 9, 198, 36, 81, 143, 48, 241, 0, 68, 7, 196, 20, 243, 65, 76, 66, 0, 6, 195, 78, 197, 0, 66, 8, 197, 65, 18, 72, 144, 176, 65, 8, 197, 47, 98, 207, 22, 224, 67, 8, 197, 17, 16, 66, 24, 112, 66, 8, 197, 180, 187, 79, 36, 80, 68, 0, 14, 2, 95, 60, 48, 39, 15, 65, 6, 35, 55, 49, 39, 0, 6, 195, 79, 188, 0, 66, 9, 198, 32, 99, 48, 97, 66, 192, 67, 0, 10, 199, 44, 243, 80, 192, 82, 84, 52, 66, 6, 195, 23, 30, 128, 65, 0, 11, 200, 24, 193, 139, 79, 100, 54, 212, 80, 69, 0, 9, 198, 95, 18, 207, 17, 16, 85, 67, 9, 198, 73, 124, 15, 17, 16, 85, 67, 9, 198, 73, 60, 15, 17, 16, 85, 67, 9, 198, 64, 100, 147, 37, 114, 69, 67, 0, 0, 6, 195, 212, 187, 64, 66, 0, 7, 196, 148, 165, 84, 56, 66, 6, 195, 72, 149, 115, 66, 7, 196, 52, 146, 246, 8, 66, 7, 196, 49, 67, 113, 180, 67, 7, 196, 48, 100, 198, 28, 66, 7, 196, 46, 52, 157, 244, 66, 7, 196, 5, 51, 6, 76, 66, 7, 196, 175, 209, 93, 244, 67, 0, 8, 197, 165, 36, 6, 45, 48, 66, 8, 197, 46, 163, 147, 25, 48, 66, 8, 197, 5, 36, 6, 45, 48, 66, 0, 0, 10, 199, 77, 16, 80, 24, 131, 201, 20, 68, 6, 195, 148, 43, 192, 66, 6, 195, 144, 75, 192, 66, 6, 195, 48, 97, 48, 66, 9, 198, 44, 20, 134, 76, 245, 115, 68, 0, 7, 196, 67, 9, 68, 204, 67, 0, 8, 197, 72, 191, 66, 81, 48, 66, 0, 11, 66, 80, 192, 40, 55, 37, 117, 35, 0, 24, 9, 198, 19, 179, 111, 61, 91, 128, 68, 0, 9, 4, 95, 226, 128, 161, 21, 0, 10, 6, 195, 4, 64, 64, 66, 0, 9, 4, 95, 226, 128, 160, 21, 0, 10, 7, 196, 80, 226, 119, 56, 67, 7, 196, 64, 241, 66, 244, 66, 7, 196, 52, 244, 198, 48, 66, 7, 196, 44, 244, 198, 48, 66, 7, 196, 44, 19, 73, 204, 67, 6, 195, 46, 107, 123, 67, 9, 198, 25, 2, 83, 68, 21, 174, 68, 7, 196, 20, 100, 175, 76, 66, 0, 8, 197, 74, 83, 137, 60, 192, 67, 0, 18, 4, 95, 226, 128, 166, 65, 50, 39, 81, 39, 47, 6, 39, 76, 37, 36, 0, 9, 198, 81, 4, 102, 37, 49, 140, 66, 9, 198, 66, 145, 73, 44, 20, 192, 67, 9, 198, 20, 99, 108, 68, 20, 192, 67, 9, 198, 8, 102, 65, 52, 99, 0, 67, 6, 195, 234, 241, 253, 67, 9, 198, 189, 50, 83, 177, 44, 64, 68, 0, 10, 199, 161, 34, 248, 61, 35, 137, 44, 66, 10, 199, 36, 132, 17, 152, 148, 198, 48, 66, 6, 195, 233, 156, 64, 66, 0, 7, 196, 76, 244, 198, 52, 66, 7, 196, 64, 100, 198, 48, 66, 6, 195, 47, 97, 135, 66, 7, 196, 44, 19, 204, 196, 67, 6, 195, 5, 34, 251, 66, 0, 8, 197, 88, 147, 73, 46, 208, 67, 8, 197, 64, 241, 77, 60, 192, 66, 8, 197, 55, 178, 69, 38, 240, 68, 12, 201, 13, 177, 12, 25, 98, 69, 68, 20, 192, 68, 0, 9, 198, 68, 18, 3, 68, 20, 192, 66, 13, 202, 64, 241, 80, 164, 84, 134, 20, 20, 198, 48, 65, 9, 198, 197, 91, 147, 68, 20, 192, 67, 0, 6, 195, 96, 98, 72, 66, 0, 7, 196, 65, 179, 40, 28, 66, 7, 196, 52, 146, 246, 56, 66, 7, 196, 52, 100, 198, 28, 66, 7, 196, 8, 99, 79, 48, 66, 7, 196, 232, 16, 137, 128, 66, 0, 8, 197, 147, 97, 120, 37, 32, 68, 8, 197, 52, 146, 246, 87, 48, 67, 8, 197, 188, 20, 236, 75, 16, 68, 0, 0, 7, 195, 74, 145, 64, 72, 23, 29, 2, 95, 91, 55, 38, 4, 35, 84, 35, 15, 49, 84, 35, 72, 34, 4, 35, 47, 50, 35, 15, 89, 49, 6, 39, 71, 35, 0, 9, 198, 72, 149, 110, 37, 50, 75, 68, 6, 195, 173, 114, 72, 66, 0, 6, 195, 87, 160, 115, 67, 11, 200, 10, 209, 147, 52, 18, 146, 79, 208, 66, 0, 18, 4, 95, 226, 128, 147, 49, 4, 13, 89, 39, 15, 47, 37, 34, 6, 36, 0, 9, 198, 52, 20, 140, 227, 109, 69, 68, 8, 197, 21, 64, 140, 119, 208, 66, 8, 197, 175, 100, 147, 37, 96, 67, 8, 197, 153, 51, 194, 81, 32, 67, 0, 13, 202, 65, 34, 86, 61, 82, 72, 36, 243, 15, 16, 70, 0, 18, 2, 95, 95, 72, 4, 39, 55, 50, 35, 15, 76, 36, 34, 47, 6, 35, 0, 10, 199, 164, 228, 196, 192, 243, 15, 16, 68, 0, 6, 195, 130, 81, 47, 67, 6, 195, 34, 210, 67, 65, 0, 29, 2, 95, 93, 116, 4, 35, 89, 50, 35, 15, 49, 84, 35, 72, 34, 4, 35, 47, 50, 35, 15, 89, 49, 6, 39, 71, 35, 0, 8, 197, 8, 249, 78, 36, 176, 67, 0, 9, 198, 78, 146, 3, 192, 146, 192, 65, 0, 9, 198, 77, 244, 75, 60, 18, 0, 67, 6, 195, 150, 54, 64, 66, 6, 195, 160, 86, 196, 66, 9, 198, 8, 148, 148, 49, 80, 83, 67, 0, 19, 4, 95, 226, 128, 148, 72, 4, 13, 55, 81, 39, 15, 47, 37, 34, 6, 36, 0, 9, 198, 91, 99, 143, 48, 241, 0, 67, 7, 196, 64, 100, 18, 196, 66, 7, 196, 60, 36, 73, 12, 65, 7, 196, 60, 36, 65, 76, 66, 7, 196, 32, 21, 186, 196, 67, 9, 198, 9, 180, 72, 204, 241, 0, 67, 0, 8, 197, 65, 18, 72, 36, 48, 65, 8, 197, 66, 148, 147, 36, 112, 66, 8, 197, 8, 99, 19, 108, 176, 66, 8, 197, 4, 36, 148, 68, 80, 66, 0, 9, 2, 95, 96, 81, 34, 35, 83, 0, 9, 198, 77, 68, 205, 188, 146, 192, 65, 9, 198, 23, 130, 82, 56, 146, 192, 65, 0, 10, 199, 72, 191, 79, 73, 51, 137, 44, 65, 10, 199, 65, 16, 66, 108, 193, 58, 196, 66, 10, 199, 46, 148, 15, 73, 51, 137, 44, 65, 6, 195, 47, 219, 192, 66, 0, 6, 195, 88, 16, 187, 66, 7, 196, 64, 243, 80, 204, 66, 6, 195, 145, 101, 19, 66, 0, 8, 197, 85, 68, 75, 25, 48, 66, 8, 197, 67, 178, 82, 47, 128, 67, 8, 197, 153, 51, 210, 79, 128, 67, 0, 6, 195, 97, 64, 237, 66, 6, 195, 64, 102, 45, 66, 6, 195, 55, 166, 109, 66, 6, 195, 17, 72, 217, 66, 0, 10, 199, 73, 1, 139, 79, 100, 139, 224, 67, 9, 198, 64, 100, 6, 48, 226, 75, 67, 10, 199, 24, 193, 139, 79, 100, 139, 224, 68, 9, 198, 23, 48, 66, 244, 226, 75, 66, 0, 7, 196, 48, 146, 221, 244, 66, 7, 196, 44, 20, 198, 76, 66, 7, 196, 10, 196, 157, 244, 66, 0, 8, 197, 73, 58, 76, 25, 112, 66, 8, 197, 72, 193, 144, 25, 112, 66, 8, 197, 68, 18, 19, 213, 16, 66, 8, 197, 8, 241, 1, 149, 144, 67, 8, 197, 188, 98, 197, 61, 48, 67, 0, 6, 194, 96, 96, 72, 23, 9, 198, 68, 17, 73, 61, 111, 64, 68, 9, 198, 47, 52, 246, 49, 223, 64, 67, 0, 10, 199, 161, 68, 209, 180, 148, 198, 76, 69, 0, 7, 196, 84, 100, 147, 204, 66, 7, 196, 47, 49, 41, 72, 66, 7, 196, 44, 147, 73, 204, 67, 6, 195, 4, 74, 23, 66, 0, 12, 201, 64, 241, 84, 65, 25, 137, 76, 99, 0, 65, 8, 197, 18, 54, 65, 148, 160, 67, 9, 198, 153, 51, 205, 205, 55, 125, 68, 0, 6, 195, 14, 241, 109, 66, 9, 198, 5, 36, 246, 144, 52, 192, 67, 0, 6, 195, 67, 188, 192, 66, 9, 198, 52, 244, 207, 77, 18, 115, 68, 9, 198, 44, 243, 66, 196, 98, 51, 68, 0, 7, 196, 89, 179, 2, 176, 65, 7, 196, 175, 96, 129, 76, 67, 0, 8, 197, 68, 18, 2, 60, 160, 66, 8, 197, 10, 241, 123, 60, 192, 67, 0, 9, 198, 20, 100, 147, 184, 20, 192, 67, 9, 198, 9, 253, 139, 68, 20, 192, 67, 9, 198, 233, 98, 83, 24, 180, 192, 67, 0, 6, 195, 86, 191, 0, 66, 10, 199, 72, 198, 206, 96, 240, 145, 188, 67, 0, 7, 196, 66, 52, 198, 92, 66, 0, 8, 197, 77, 180, 66, 81, 96, 66, 8, 197, 46, 48, 198, 75, 16, 67, 0, 6, 195, 148, 182, 205, 66, 0, 32, 2, 95, 123, 55, 38, 4, 35, 84, 35, 15, 84, 13, 55, 50, 39, 4, 39, 71, 34, 35, 88, 50, 35, 15, 89, 49, 6, 39, 71, 35, 0, 9, 198, 36, 132, 207, 96, 226, 75, 65, 0, 7, 196, 78, 153, 7, 244, 67, 6, 195, 67, 52, 243, 66, 7, 196, 224, 98, 212, 56, 67, 9, 198, 55, 162, 198, 79, 17, 0, 65, 0, 8, 197, 47, 160, 66, 199, 176, 68, 8, 197, 20, 243, 79, 87, 48, 67, 0, 6, 195, 233, 44, 0, 66, 0, 6, 195, 46, 240, 80, 66, 6, 195, 184, 146, 192, 66, 0, 14, 2, 95, 126, 84, 13, 55, 50, 6, 37, 76, 49, 35, 0, 11, 200, 24, 193, 139, 79, 108, 71, 195, 176, 70, 9, 198, 233, 97, 143, 48, 241, 0, 68, 0, 32, 2, 95, 125, 116, 4, 35, 89, 50, 35, 15, 84, 13, 55, 50, 39, 4, 39, 71, 34, 35, 88, 50, 35, 15, 89, 49, 6, 39, 71, 35, 0, 8, 197, 88, 243, 59, 36, 176, 67, 0, 23, 2, 95, 124, 84, 36, 34, 47, 37, 49, 4, 35, 55, 50, 35, 15, 76, 36, 34, 47, 6, 35, 0, 6, 195, 84, 197, 61, 66, 6, 195, 75, 7, 125, 66, 9, 198, 67, 171, 73, 76, 146, 192, 68, 9, 198, 54, 189, 134, 32, 146, 192, 68, 9, 198, 32, 16, 166, 37, 49, 140, 66, 12, 201, 24, 193, 139, 79, 96, 68, 164, 64, 83, 70, 0, 6, 195, 80, 94, 128, 65, 10, 199, 77, 18, 84, 54, 164, 65, 76, 68, 0, 8, 196, 66, 196, 65, 40, 72, 23, 7, 196, 66, 116, 65, 76, 66, 6, 195, 61, 113, 147, 66, 7, 196, 52, 147, 111, 72, 66, 7, 196, 52, 19, 84, 48, 66, 7, 196, 44, 17, 111, 72, 66, 0, 11, 5, 95, 48, 97, 110, 100, 10, 2, 37, 0, 0, 9, 198, 64, 100, 147, 56, 146, 192, 66, 9, 198, 145, 10, 88, 56, 146, 192, 65, 9, 198, 20, 198, 199, 56, 146, 192, 66, 0, 10, 199, 72, 147, 80, 60, 130, 84, 52, 66, 9, 198, 67, 98, 248, 74, 242, 75, 66, 9, 198, 64, 244, 140, 25, 35, 39, 67, 10, 199, 34, 147, 15, 73, 51, 137, 44, 65, 0, 7, 196, 81, 36, 6, 88, 66, 7, 196, 148, 229, 221, 244, 66, 11, 200, 68, 20, 147, 192, 145, 131, 108, 80, 69, 7, 196, 48, 100, 198, 92, 66, 7, 196, 47, 212, 134, 76, 66, 7, 196, 44, 19, 91, 100, 66, 7, 196, 22, 148, 157, 244, 66, 7, 196, 9, 23, 232, 76, 66, 7, 196, 11, 172, 198, 76, 67, 0, 11, 200, 72, 209, 147, 44, 17, 71, 38, 0, 65, 8, 197, 75, 186, 147, 81, 48, 67, 12, 201, 68, 16, 143, 76, 245, 143, 48, 146, 192, 69, 12, 201, 64, 241, 80, 60, 194, 231, 56, 146, 192, 65, 0, 8, 197, 142, 49, 71, 38, 0, 65, 9, 198, 32, 19, 73, 73, 179, 0, 65, 0, 9, 198, 65, 177, 80, 108, 86, 203, 67, 9, 198, 65, 25, 134, 20, 226, 75, 65, 0, 7, 196, 61, 84, 134, 76, 66, 6, 195, 51, 218, 19, 66, 7, 196, 47, 161, 113, 180, 67, 7, 196, 16, 194, 68, 188, 66, 0, 11, 200, 66, 144, 209, 6, 81, 71, 38, 0, 66, 8, 197, 53, 68, 139, 25, 48, 66, 0, 9, 198, 88, 99, 9, 61, 34, 248, 68, 0, 10, 199, 88, 98, 211, 60, 68, 65, 84, 67, 0, 7, 196, 47, 209, 163, 76, 67, 7, 196, 36, 212, 61, 76, 66, 7, 196, 16, 96, 233, 44, 66, 11, 200, 189, 50, 69, 25, 10, 82, 189, 48, 69, 0, 8, 197, 61, 51, 204, 60, 64, 67, 8, 197, 246, 241, 20, 148, 224, 66, 6, 195, 144, 83, 202, 66, 8, 197, 46, 196, 198, 40, 192, 66, 8, 197, 5, 3, 15, 52, 32, 66, 0, 9, 198, 72, 99, 70, 20, 99, 0, 67, 13, 202, 68, 17, 73, 61, 49, 140, 24, 68, 65, 84, 70, 5, 194, 214, 208, 66, 0, 9, 198, 78, 146, 133, 124, 226, 115, 68, 0, 7, 196, 148, 225, 70, 52, 66, 7, 196, 73, 180, 134, 20, 66, 7, 196, 74, 84, 73, 44, 66, 6, 195, 66, 209, 135, 66, 7, 196, 48, 99, 84, 68, 66, 6, 195, 46, 247, 115, 66, 7, 196, 8, 97, 84, 196, 67, 0, 8, 197, 65, 18, 66, 60, 160, 66, 6, 195, 44, 248, 202, 66, 8, 197, 153, 51, 196, 60, 192, 67, 0, 0, 9, 198, 95, 161, 170, 96, 226, 75, 65, 10, 199, 73, 98, 72, 52, 20, 201, 44, 67, 0, 7, 196, 76, 99, 247, 84, 67, 7, 196, 64, 20, 147, 240, 66, 7, 196, 36, 82, 79, 52, 67, 11, 200, 20, 155, 70, 45, 51, 204, 60, 64, 69, 0, 8, 197, 44, 243, 15, 87, 48, 67, 6, 195, 44, 248, 206, 66, 0, 0, 10, 199, 73, 177, 12, 24, 80, 193, 96, 66, 9, 198, 72, 98, 212, 56, 91, 211, 67, 10, 199, 19, 100, 141, 4, 164, 147, 244, 65, 6, 195, 182, 53, 128, 66, 0, 7, 196, 77, 28, 79, 52, 66, 7, 196, 48, 144, 187, 180, 67, 6, 195, 236, 128, 87, 66, 0, 9, 198, 65, 33, 131, 23, 50, 77, 67, 6, 195, 55, 48, 86, 66, 8, 197, 46, 249, 81, 39, 48, 68, 0, 0, 6, 195, 164, 62, 192, 66, 10, 199, 20, 146, 6, 48, 211, 211, 244, 68, 9, 198, 8, 100, 243, 156, 242, 0, 68, 0, 7, 196, 73, 64, 240, 240, 67, 6, 195, 67, 210, 67, 65, 7, 196, 66, 196, 73, 12, 65, 7, 196, 66, 244, 137, 204, 67, 6, 195, 48, 101, 123, 66, 0, 9, 197, 73, 4, 96, 52, 240, 72, 23, 8, 197, 246, 82, 204, 108, 176, 67, 8, 197, 45, 179, 147, 24, 112, 66, 8, 197, 45, 18, 83, 36, 176, 66, 8, 197, 20, 144, 85, 184, 208, 67, 6, 195, 8, 21, 238, 66, 6, 195, 190, 240, 82, 67, 0, 9, 198, 64, 243, 20, 45, 22, 196, 67, 6, 195, 64, 97, 109, 66, 9, 198, 21, 177, 197, 60, 222, 192, 67, 9, 198, 22, 209, 139, 60, 222, 192, 68, 0, 6, 195, 32, 101, 124, 66, 0, 6, 195, 164, 85, 19, 66, 7, 196, 67, 213, 201, 204, 67, 7, 196, 52, 100, 201, 72, 66, 7, 196, 44, 21, 70, 32, 66, 7, 196, 44, 17, 81, 184, 66, 9, 198, 44, 17, 65, 73, 61, 142, 67, 11, 200, 36, 130, 212, 73, 61, 67, 24, 80, 68, 11, 200, 25, 36, 198, 73, 61, 67, 24, 80, 68, 6, 195, 18, 213, 115, 66, 0, 8, 197, 99, 202, 204, 108, 176, 67, 8, 197, 73, 58, 77, 24, 112, 66, 0, 9, 198, 52, 241, 70, 48, 158, 192, 68, 6, 195, 25, 41, 21, 66, 9, 198, 22, 144, 143, 73, 178, 192, 67, 0, 6, 195, 67, 195, 196, 66, 6, 195, 46, 251, 64, 66, 0, 7, 196, 96, 100, 198, 92, 66, 7, 196, 84, 99, 197, 180, 67, 7, 196, 86, 213, 198, 76, 66, 7, 196, 67, 197, 6, 76, 67, 7, 196, 52, 19, 84, 76, 66, 0, 11, 200, 64, 241, 54, 52, 17, 71, 38, 0, 66, 12, 201, 52, 18, 141, 80, 225, 71, 185, 178, 192, 68, 12, 201, 168, 81, 143, 20, 148, 144, 48, 98, 128, 69, 8, 197, 5, 11, 17, 37, 80, 67, 8, 197, 153, 51, 205, 5, 48, 67, 0, 9, 198, 20, 99, 60, 37, 67, 64, 66, 0, 6, 195, 67, 204, 88, 66, 0, 7, 195, 98, 146, 0, 72, 23, 7, 196, 75, 28, 201, 52, 67, 11, 200, 52, 244, 207, 92, 146, 204, 25, 48, 68, 7, 196, 55, 52, 221, 244, 66, 0, 8, 197, 76, 99, 123, 81, 48, 67, 8, 197, 74, 49, 75, 37, 144, 66, 8, 197, 67, 97, 84, 45, 48, 66, 8, 197, 45, 68, 12, 25, 48, 66, 8, 197, 32, 241, 17, 5, 80, 66, 8, 197, 5, 113, 147, 187, 0, 68, 8, 197, 4, 90, 82, 189, 48, 67, 0, 5, 194, 104, 96, 72, 9, 198, 88, 99, 9, 61, 61, 144, 68, 6, 195, 46, 119, 125, 66, 0, 7, 195, 74, 150, 148, 72, 23, 9, 198, 45, 22, 210, 79, 134, 211, 67, 0, 7, 195, 176, 243, 15, 72, 23, 11, 200, 72, 98, 72, 52, 241, 17, 5, 80, 68, 7, 196, 20, 100, 187, 76, 66, 0, 0, 9, 198, 17, 16, 71, 22, 252, 64, 65, 0, 6, 195, 5, 51, 204, 66, 0, 8, 196, 36, 128, 219, 56, 72, 23, 6, 195, 221, 4, 111, 66, 7, 196, 220, 193, 65, 76, 66, 7, 196, 74, 241, 91, 44, 66, 7, 196, 74, 189, 213, 204, 67, 7, 196, 164, 186, 134, 52, 67, 7, 196, 67, 182, 6, 52, 66, 0, 8, 197, 66, 148, 147, 60, 160, 66, 8, 197, 64, 20, 209, 80, 192, 66, 8, 197, 204, 179, 204, 60, 64, 67, 6, 195, 181, 54, 206, 66, 0, 9, 198, 76, 100, 6, 17, 211, 200, 67, 9, 198, 64, 243, 20, 18, 52, 128, 67, 6, 195, 64, 242, 61, 66, 6, 195, 55, 30, 237, 67, 9, 198, 36, 188, 207, 74, 84, 128, 68, 6, 195, 236, 76, 0, 66, 9, 198, 20, 19, 65, 72, 188, 64, 67, 0, 0, 7, 196, 55, 5, 6, 76, 67, 7, 196, 48, 149, 198, 40, 66, 11, 200, 48, 98, 210, 36, 179, 204, 60, 64, 68, 7, 196, 28, 19, 66, 204, 66, 0, 8, 197, 44, 19, 123, 39, 176, 68, 8, 197, 9, 26, 243, 39, 176, 68, 9, 198, 154, 249, 69, 28, 152, 0, 66, 0, 9, 198, 212, 83, 207, 79, 81, 64, 68, 0, 0, 7, 196, 86, 227, 247, 84, 67, 6, 195, 148, 212, 51, 66, 7, 196, 47, 196, 9, 96, 66, 7, 196, 47, 193, 9, 32, 66, 11, 200, 5, 37, 109, 76, 240, 134, 79, 48, 69, 0, 6, 195, 69, 178, 230, 66, 8, 197, 166, 181, 201, 207, 176, 69, 8, 197, 68, 18, 13, 5, 96, 66, 8, 197, 45, 43, 143, 87, 48, 67, 0, 6, 195, 44, 21, 25, 66, 0, 6, 195, 75, 16, 80, 66, 6, 195, 46, 238, 192, 66, 0, 6, 195, 87, 179, 111, 66, 7, 196, 36, 82, 79, 76, 67, 0, 8, 197, 73, 180, 66, 24, 112, 66, 8, 197, 67, 96, 140, 24, 208, 66, 8, 197, 44, 148, 240, 36, 176, 65, 8, 197, 13, 178, 22, 60, 80, 66, 0, 9, 198, 9, 180, 251, 86, 50, 128, 65, 0, 6, 195, 99, 208, 80, 66, 0, 7, 196, 74, 227, 205, 236, 67, 7, 196, 52, 97, 73, 44, 66, 6, 195, 54, 177, 147, 66, 7, 196, 33, 67, 20, 52, 66, 7, 196, 20, 240, 74, 192, 67, 6, 195, 12, 17, 51, 66, 7, 196, 5, 113, 147, 204, 67, 0, 9, 197, 13, 180, 41, 44, 144, 72, 23, 8, 197, 88, 145, 81, 36, 80, 66, 8, 197, 86, 240, 83, 36, 176, 67, 9, 198, 77, 18, 75, 60, 199, 125, 67, 8, 197, 72, 21, 81, 36, 80, 66, 8, 197, 52, 97, 73, 80, 208, 65, 6, 195, 196, 85, 18, 66, 0, 6, 195, 164, 193, 149, 66, 9, 198, 64, 18, 58, 49, 178, 192, 67, 0, 10, 199, 65, 16, 68, 52, 20, 201, 44, 67, 10, 199, 52, 193, 139, 204, 17, 79, 40, 68, 9, 198, 44, 243, 73, 72, 156, 251, 69, 0, 7, 196, 67, 172, 201, 52, 67, 6, 195, 66, 209, 147, 66, 7, 196, 44, 204, 241, 16, 66, 7, 196, 44, 20, 212, 56, 66, 0, 8, 197, 52, 148, 139, 25, 48, 66, 9, 198, 44, 25, 69, 28, 152, 0, 65, 8, 197, 44, 17, 65, 37, 80, 67, 8, 197, 21, 64, 140, 25, 48, 66, 8, 197, 22, 225, 165, 57, 48, 67, 0, 9, 198, 24, 194, 72, 37, 67, 64, 66, 6, 195, 4, 213, 17, 66, 0, 6, 195, 148, 59, 192, 66, 6, 195, 72, 20, 252, 66, 6, 195, 214, 51, 128, 66, 0, 7, 196, 72, 20, 21, 240, 66, 9, 198, 52, 105, 76, 81, 17, 0, 67, 9, 198, 19, 179, 111, 61, 83, 194, 68, 0, 6, 195, 164, 74, 82, 66, 8, 197, 20, 148, 144, 81, 48, 66, 0, 10, 66, 96, 192, 76, 55, 36, 50, 0, 24, 6, 195, 164, 59, 217, 66, 0, 0, 7, 196, 73, 55, 250, 20, 66, 11, 200, 73, 1, 139, 79, 97, 17, 5, 80, 67, 7, 196, 45, 68, 148, 68, 66, 0, 9, 198, 79, 58, 71, 37, 39, 125, 68, 8, 197, 68, 144, 143, 50, 112, 67, 8, 197, 9, 67, 123, 188, 64, 67, 0, 9, 198, 44, 243, 112, 22, 244, 192, 67, 0, 7, 195, 4, 208, 64, 72, 23, 10, 199, 72, 97, 77, 37, 131, 137, 44, 65, 10, 199, 32, 243, 211, 25, 99, 137, 44, 68, 0, 7, 196, 246, 83, 27, 44, 67, 7, 196, 56, 253, 246, 16, 67, 7, 196, 30, 241, 122, 52, 66, 0, 8, 197, 99, 163, 197, 24, 160, 67, 6, 195, 79, 100, 238, 66, 8, 197, 66, 148, 147, 60, 192, 66, 8, 197, 32, 195, 197, 24, 160, 66, 8, 197, 169, 20, 212, 60, 128, 67, 0, 9, 198, 72, 98, 210, 148, 228, 192, 66, 9, 198, 36, 210, 68, 70, 244, 192, 67, 9, 198, 24, 210, 68, 70, 244, 192, 67, 0, 14, 67, 16, 241, 64, 81, 39, 72, 6, 37, 50, 35, 0, 24, 6, 195, 5, 56, 200, 66, 0, 6, 195, 150, 51, 147, 66, 7, 196, 58, 192, 84, 76, 65, 6, 195, 44, 18, 47, 66, 7, 196, 13, 178, 36, 44, 65, 0, 6, 195, 16, 241, 70, 65, 8, 197, 164, 191, 69, 119, 208, 67, 8, 197, 16, 244, 147, 195, 16, 65, 0, 0, 7, 195, 64, 241, 64, 72, 23, 9, 198, 47, 52, 148, 50, 83, 147, 67, 0, 6, 195, 76, 145, 47, 66, 7, 196, 149, 27, 70, 28, 67, 0, 8, 197, 64, 20, 137, 189, 32, 67, 6, 195, 5, 56, 210, 66, 0, 9, 198, 91, 176, 137, 92, 145, 64, 67, 9, 198, 48, 148, 147, 224, 17, 64, 67, 9, 198, 25, 33, 183, 12, 101, 192, 66, 9, 198, 9, 22, 211, 12, 97, 192, 66, 0, 9, 198, 61, 82, 87, 36, 242, 0, 68, 9, 198, 197, 84, 65, 32, 53, 11, 65, 6, 195, 21, 65, 140, 66, 0, 7, 196, 77, 26, 229, 76, 66, 0, 8, 197, 96, 98, 209, 108, 176, 66, 8, 197, 73, 177, 108, 140, 80, 67, 8, 197, 73, 67, 21, 36, 80, 66, 8, 197, 24, 212, 60, 36, 176, 67, 0, 9, 198, 72, 19, 79, 76, 98, 192, 67, 9, 198, 12, 99, 8, 24, 53, 12, 67, 0, 0, 7, 196, 52, 100, 207, 88, 66, 7, 196, 46, 145, 73, 76, 65, 12, 201, 197, 36, 209, 80, 220, 37, 68, 149, 13, 68, 9, 198, 20, 99, 65, 16, 241, 0, 67, 0, 8, 197, 73, 59, 39, 24, 80, 67, 8, 197, 29, 179, 19, 108, 176, 66, 8, 197, 16, 241, 112, 36, 176, 67, 0, 6, 195, 4, 80, 89, 66, 0, 9, 198, 68, 21, 129, 76, 198, 203, 67, 6, 195, 34, 211, 196, 66, 0, 7, 196, 96, 17, 91, 68, 66, 7, 196, 45, 246, 6, 44, 66, 6, 195, 44, 20, 47, 66, 7, 196, 197, 62, 201, 244, 68, 6, 195, 21, 65, 147, 66, 7, 196, 11, 212, 148, 44, 66, 0, 8, 197, 52, 97, 38, 5, 48, 67, 8, 197, 45, 180, 141, 25, 48, 66, 0, 6, 195, 233, 44, 45, 67, 0, 10, 199, 80, 196, 209, 4, 128, 212, 44, 67, 9, 198, 64, 148, 147, 60, 193, 147, 67, 0, 7, 196, 148, 34, 70, 76, 67, 11, 200, 68, 17, 73, 60, 20, 58, 5, 48, 70, 7, 196, 53, 67, 133, 240, 66, 7, 196, 45, 190, 70, 28, 66, 0, 9, 198, 77, 21, 2, 4, 85, 17, 67, 8, 197, 197, 60, 5, 189, 48, 67, 8, 197, 9, 22, 205, 11, 160, 65, 0, 9, 198, 68, 18, 18, 78, 147, 0, 66, 6, 195, 18, 211, 217, 66, 9, 198, 152, 147, 205, 61, 63, 64, 69, 0, 6, 195, 67, 213, 124, 66, 6, 195, 24, 178, 80, 66, 0, 8, 196, 73, 15, 70, 20, 72, 23, 6, 195, 86, 50, 243, 66, 7, 196, 141, 74, 65, 76, 68, 9, 198, 9, 179, 4, 232, 245, 110, 68, 0, 0, 9, 198, 64, 244, 147, 82, 52, 192, 67, 5, 194, 226, 208, 66, 9, 198, 44, 62, 147, 242, 244, 192, 67, 9, 198, 20, 100, 41, 74, 244, 192, 67, 0, 6, 195, 91, 28, 64, 66, 6, 195, 67, 204, 192, 66, 10, 199, 145, 145, 146, 76, 60, 9, 44, 66, 0, 7, 196, 36, 132, 73, 12, 65, 7, 196, 18, 220, 9, 44, 65, 7, 196, 13, 67, 11, 188, 66, 7, 196, 212, 83, 198, 52, 67, 0, 0, 6, 195, 98, 214, 205, 66, 9, 198, 84, 145, 20, 70, 244, 192, 67, 6, 195, 72, 178, 125, 66, 9, 198, 68, 18, 23, 12, 100, 192, 66, 9, 198, 44, 243, 73, 76, 100, 192, 67, 9, 198, 20, 98, 210, 77, 28, 64, 66, 9, 198, 8, 147, 205, 37, 124, 64, 68, 0, 10, 199, 86, 214, 73, 84, 146, 193, 76, 68, 9, 198, 75, 176, 134, 32, 198, 203, 67, 10, 199, 52, 20, 198, 52, 20, 201, 44, 68, 0, 7, 196, 84, 150, 70, 44, 66, 7, 196, 77, 180, 232, 28, 66, 6, 195, 216, 35, 211, 66, 0, 8, 197, 47, 53, 227, 19, 176, 65, 0, 9, 198, 47, 49, 136, 152, 241, 64, 68, 9, 198, 44, 148, 134, 48, 101, 192, 65, 9, 198, 16, 243, 6, 52, 101, 192, 67, 0, 0, 7, 196, 54, 246, 70, 76, 66, 7, 196, 44, 20, 207, 20, 66, 7, 196, 197, 37, 12, 76, 66, 11, 200, 24, 193, 139, 79, 99, 79, 79, 208, 69, 0, 6, 195, 87, 57, 78, 66, 8, 197, 48, 97, 9, 207, 176, 68, 8, 197, 44, 244, 177, 81, 32, 65, 0, 6, 195, 66, 224, 85, 66, 9, 198, 47, 160, 77, 8, 243, 0, 67, 9, 198, 153, 51, 200, 152, 241, 64, 68, 0, 6, 195, 67, 217, 76, 66, 9, 198, 189, 50, 85, 68, 146, 0, 67, 0, 7, 196, 141, 49, 139, 72, 66, 0, 8, 197, 36, 67, 48, 36, 176, 67, 8, 197, 32, 60, 39, 60, 80, 67, 9, 198, 28, 157, 83, 58, 118, 197, 68, 0, 6, 195, 75, 23, 125, 66, 0, 9, 198, 73, 64, 140, 36, 208, 83, 67, 0, 9, 198, 67, 100, 207, 43, 177, 138, 68, 9, 198, 52, 227, 196, 60, 35, 202, 67, 9, 198, 237, 117, 187, 92, 241, 0, 67, 9, 198, 23, 1, 118, 48, 241, 0, 67, 0, 9, 198, 92, 99, 20, 48, 242, 69, 68, 9, 198, 66, 146, 9, 20, 149, 13, 66, 8, 197, 25, 144, 85, 60, 80, 67, 0, 6, 195, 44, 18, 89, 66, 0, 9, 198, 67, 101, 82, 109, 242, 0, 67, 0, 7, 196, 72, 20, 29, 244, 66, 7, 196, 66, 52, 157, 244, 66, 7, 196, 66, 244, 198, 204, 67, 6, 195, 66, 98, 111, 67, 7, 196, 61, 54, 6, 76, 66, 11, 200, 13, 177, 12, 24, 83, 194, 36, 48, 67, 6, 195, 11, 165, 19, 66, 0, 6, 18, 66, 208, 181, 0, 209, 144, 0, 208, 184, 0, 209, 157, 0, 7, 6, 18, 67, 209, 128, 0, 208, 187, 0, 208, 188, 0, 208, 189, 0, 7, 6, 18, 68, 208, 180, 208, 183, 0, 208, 180, 208, 182, 0, 208, 177, 0, 208, 178, 0, 208, 179, 0, 208, 180, 0, 208, 183, 0, 208, 182, 0, 7, 6, 18, 69, 208, 191, 0, 209, 132, 0, 208, 186, 0, 209, 130, 0, 209, 129, 0, 209, 134, 0, 209, 136, 0, 209, 137, 0, 209, 135, 0, 209, 133, 0, 7, 6, 1, 17, 0, 209, 128, 1, 21, 2, 32, 3, 6, 35, 34, 0, 209, 130, 208, 181, 208, 187, 208, 181, 208, 189, 1, 21, 2, 32, 3, 6, 35, 47, 36, 55, 36, 50, 0, 209, 130, 208, 181, 208, 187, 209, 129, 209, 130, 208, 178, 208, 190, 1, 21, 2, 32, 3, 6, 35, 47, 36, 55, 89, 47, 84, 39, 0, 208, 186, 1, 21, 2, 32, 3, 6, 35, 49, 0, 208, 189, 208, 184, 208, 181, 1, 21, 2, 32, 3, 6, 35, 50, 37, 36, 0, 208, 189, 209, 129, 208, 186, 208, 184, 1, 21, 2, 32, 3, 6, 35, 50, 89, 49, 37, 0, 208, 187, 208, 181, 208, 189, 1, 21, 2, 32, 3, 6, 35, 55, 36, 50, 0, 208, 187, 208, 184, 209, 137, 208, 181, 1, 21, 2, 32, 3, 6, 35, 55, 37, 91, 47, 36, 0, 208, 187, 208, 189, 209, 143, 1, 21, 2, 32, 3, 6, 35, 55, 50, 38, 35, 0, 209, 135, 1, 21, 2, 32, 3, 6, 35, 76, 0, 208, 178, 208, 184, 209, 137, 208, 181, 1, 21, 2, 32, 3, 6, 35, 84, 37, 91, 47, 36, 0, 208, 182, 1, 21, 2, 32, 3, 6, 35, 90, 0, 209, 134, 208, 184, 209, 143, 1, 21, 2, 32, 3, 6, 35, 117, 37, 35, 0, 4, 3, 35, 0, 1, 21, 2, 32, 14, 128, 128, 129, 0, 209, 128, 208, 184, 209, 143, 1, 21, 2, 32, 3, 35, 34, 37, 35, 0, 7, 6, 1, 18, 0, 3, 71, 0, 2, 17, 71, 3, 71, 38, 0, 7, 6, 1, 19, 0, 3, 84, 0, 2, 17, 71, 3, 84, 38, 0, 7, 6, 1, 20, 0, 3, 81, 0, 2, 17, 71, 3, 122, 0, 7, 6, 1, 21, 0, 3, 72, 0, 208, 182, 3, 75, 0, 2, 17, 71, 3, 116, 0, 208, 183, 3, 118, 0, 208, 183, 2, 17, 71, 3, 118, 38, 0, 7, 6, 1, 22, 0, 208, 181, 208, 189, 1, 21, 2, 32, 3, 6, 36, 36, 50, 0, 208, 189, 208, 184, 208, 181, 1, 21, 2, 32, 3, 6, 36, 50, 37, 36, 0, 208, 189, 209, 130, 1, 21, 2, 32, 3, 6, 36, 50, 47, 0, 208, 185, 209, 129, 208, 186, 208, 184, 1, 21, 2, 32, 3, 6, 36, 57, 89, 49, 37, 0, 208, 177, 208, 181, 208, 189, 1, 21, 2, 32, 3, 6, 36, 71, 36, 50, 0, 208, 178, 208, 181, 208, 189, 1, 21, 2, 32, 3, 6, 36, 84, 36, 50, 0, 3, 36, 0, 7, 6, 1, 23, 0, 3, 90, 0, 7, 6, 1, 24, 0, 3, 88, 0, 2, 17, 71, 3, 94, 0, 7, 6, 1, 25, 0, 4, 1, 130, 209, 190, 208, 2, 209, 143, 32, 3, 6, 37, 0, 1, 186, 208, 2, 208, 189, 209, 143, 32, 0, 209, 130, 1, 21, 2, 32, 3, 6, 37, 47, 0, 209, 130, 208, 181, 208, 187, 1, 21, 2, 32, 3, 6, 37, 47, 36, 55, 0, 209, 130, 208, 181, 208, 187, 208, 181, 208, 189, 1, 21, 2, 32, 3, 6, 37, 47, 36, 55, 36, 50, 0, 208, 180, 208, 177, 208, 176, 1, 21, 2, 32, 3, 6, 37, 47, 71, 35, 0, 208, 186, 208, 176, 208, 178, 1, 21, 2, 32, 3, 6, 37, 49, 35, 84, 0, 208, 189, 209, 129, 208, 186, 208, 184, 1, 21, 2, 32, 3, 6, 37, 50, 89, 49, 37, 0, 208, 187, 208, 181, 208, 189, 1, 21, 2, 32, 3, 6, 37, 55, 36, 50, 0, 208, 187, 208, 184, 209, 137, 208, 181, 1, 21, 2, 32, 3, 6, 37, 55, 37, 91, 47, 36, 0, 208, 188, 208, 176, 1, 21, 2, 32, 3, 6, 37, 65, 35, 0, 209, 135, 208, 181, 209, 129, 208, 186, 208, 184, 1, 21, 2, 32, 3, 6, 37, 76, 36, 89, 49, 37, 0, 208, 178, 1, 21, 2, 32, 3, 6, 37, 84, 0, 208, 178, 208, 181, 208, 189, 1, 21, 2, 32, 3, 6, 37, 84, 36, 50, 0, 208, 183, 209, 138, 208, 188, 1, 21, 2, 32, 3, 6, 37, 88, 13, 65, 0, 209, 129, 209, 130, 1, 21, 2, 32, 3, 6, 37, 89, 47, 0, 3, 37, 0, 2, 32, 24, 3, 37, 12, 0, 7, 6, 1, 26, 0, 3, 57, 0, 7, 6, 1, 27, 0, 3, 49, 0, 2, 17, 71, 3, 49, 38, 0, 208, 190, 1, 21, 2, 32, 14, 128, 128, 130, 3, 49, 39, 0, 7, 6, 1, 28, 0, 4, 2, 17, 71, 3, 55, 0, 2, 18, 66, 0, 2, 209, 140, 18, 66, 3, 61, 0, 3, 64, 0, 7, 6, 1, 29, 0, 3, 65, 0, 2, 17, 71, 3, 65, 38, 0, 7, 6, 1, 30, 0, 3, 50, 0, 208, 189, 3, 50, 12, 0, 2, 17, 71, 3, 67, 0, 7, 6, 1, 31, 0, 209, 128, 208, 184, 209, 131, 208, 188, 1, 21, 2, 32, 3, 6, 39, 34, 37, 40, 65, 0, 208, 186, 1, 21, 2, 32, 3, 6, 39, 49, 0, 208, 178, 208, 181, 208, 189, 1, 21, 2, 32, 3, 6, 39, 84, 36, 50, 0, 208, 178, 208, 184, 209, 137, 208, 181, 1, 21, 2, 32, 3, 6, 39, 84, 37, 91, 47, 36, 0, 208, 178, 208, 189, 208, 184, 208, 186, 1, 21, 2, 32, 3, 6, 39, 84, 50, 37, 49, 0, 208, 183, 208, 181, 208, 189, 2, 32, 3, 6, 39, 88, 36, 50, 0, 3, 39, 0, 208, 178, 208, 176, 2, 209, 130, 32, 3, 39, 84, 6, 35, 0, 208, 178, 208, 184, 2, 209, 130, 32, 3, 39, 84, 6, 37, 0, 7, 6, 1, 32, 0, 3, 48, 0, 2, 17, 71, 3, 48, 38, 0, 7, 6, 1, 33, 0, 3, 34, 0, 2, 17, 71, 3, 34, 38, 0, 7, 6, 1, 34, 0, 3, 89, 0, 2, 17, 71, 3, 95, 0, 7, 6, 1, 35, 0, 3, 47, 0, 209, 130, 3, 47, 12, 0, 208, 176, 1, 21, 2, 32, 14, 128, 128, 130, 3, 47, 35, 0, 208, 181, 1, 21, 2, 32, 14, 128, 128, 130, 3, 47, 36, 0, 2, 17, 71, 3, 115, 0, 7, 6, 1, 36, 0, 3, 40, 0, 7, 6, 1, 37, 0, 3, 83, 0, 2, 17, 71, 3, 83, 38, 0, 7, 6, 1, 38, 0, 4, 2, 17, 71, 3, 99, 0, 2, 208, 184, 0, 3, 101, 0, 7, 6, 1, 39, 0, 3, 117, 0, 2, 17, 71, 3, 117, 38, 0, 7, 6, 1, 40, 0, 208, 190, 1, 21, 2, 32, 3, 8, 76, 39, 0, 3, 76, 0, 7, 6, 1, 41, 0, 3, 91, 0, 7, 6, 1, 42, 0, 3, 91, 47, 0, 2, 17, 71, 3, 91, 115, 0, 7, 6, 1, 43, 0, 3, 13, 0, 209, 130, 1, 21, 2, 32, 14, 128, 128, 130, 3, 13, 47, 0, 7, 6, 1, 45, 0, 1, 17, 67, 3, 0, 3, 57, 0, 7, 6, 1, 47, 0, 1, 17, 67, 3, 40, 0, 3, 57, 40, 0, 7, 6, 1, 48, 0, 208, 189, 208, 184, 208, 181, 1, 21, 2, 32, 3, 6, 57, 35, 50, 37, 36, 0, 4, 1, 17, 67, 3, 35, 0, 1, 17, 67, 21, 2, 32, 14, 128, 192, 129, 0, 209, 130, 1, 17, 67, 21, 2, 32, 14, 128, 192, 130, 3, 35, 47, 0, 4, 3, 57, 35, 0, 1, 21, 2, 32, 14, 128, 192, 129, 0, 209, 130, 1, 21, 2, 32, 14, 128, 192, 130, 3, 57, 35, 47, 0, 7, 6, 0, 209, 144, 3, 7, 36, 0, 209, 157, 3, 7, 37, 0, 204, 128, 3, 8, 0, 36, 3, 72, 6, 39, 64, 35, 34, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts5 = FileInMemory_createWithData (26954, reinterpret_cast (&espeakdata_dicts5_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/bg_dict", U"bg"); Collection_addItem (me.peek(), espeakdata_dicts5.transfer()); static unsigned char espeakdata_dicts6_data[2830] = { 0, 4, 0, 0, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 20, 0, 0, 32, 15, 0, 0, 48, 0, 0, 0, 33, 15, 0, 0, 49, 0, 0, 0, 34, 15, 0, 0, 50, 0, 0, 0, 35, 15, 0, 0, 51, 0, 0, 0, 36, 15, 0, 0, 52, 0, 0, 0, 37, 15, 0, 0, 53, 0, 0, 0, 38, 15, 0, 0, 54, 0, 0, 0, 39, 15, 0, 0, 55, 0, 0, 0, 40, 15, 0, 0, 56, 0, 0, 0, 41, 15, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 6, 1, 65, 0, 4, 1, 21, 2, 32, 3, 49, 0, 2, 17, 66, 0, 3, 49, 35, 0, 7, 6, 1, 66, 0, 4, 1, 21, 2, 32, 3, 146, 0, 2, 17, 66, 0, 3, 146, 35, 0, 7, 6, 1, 67, 0, 4, 1, 21, 2, 32, 3, 81, 0, 2, 17, 66, 0, 3, 81, 35, 0, 7, 6, 1, 68, 0, 4, 1, 21, 2, 32, 3, 147, 0, 2, 17, 66, 0, 3, 147, 35, 0, 7, 6, 1, 69, 0, 4, 1, 21, 2, 32, 3, 68, 0, 2, 17, 66, 0, 3, 68, 35, 0, 7, 6, 1, 70, 0, 4, 1, 21, 2, 32, 3, 80, 0, 2, 17, 66, 0, 3, 80, 35, 0, 7, 6, 1, 71, 0, 4, 1, 21, 2, 32, 3, 144, 0, 2, 17, 66, 0, 3, 144, 35, 0, 7, 6, 1, 72, 0, 4, 1, 21, 2, 32, 3, 79, 0, 2, 17, 66, 0, 3, 79, 35, 0, 7, 6, 1, 74, 0, 4, 1, 21, 2, 32, 3, 67, 0, 2, 17, 66, 0, 3, 67, 35, 0, 7, 6, 1, 75, 0, 4, 1, 21, 2, 32, 3, 140, 0, 2, 17, 66, 0, 3, 140, 35, 0, 7, 6, 1, 76, 0, 4, 1, 21, 2, 32, 3, 142, 0, 2, 17, 66, 0, 3, 142, 35, 0, 7, 6, 1, 77, 0, 4, 1, 21, 2, 32, 3, 141, 0, 2, 17, 66, 0, 3, 141, 35, 0, 7, 6, 1, 78, 0, 4, 1, 21, 2, 32, 3, 143, 0, 2, 17, 66, 0, 3, 143, 35, 0, 7, 6, 1, 79, 0, 4, 1, 21, 2, 32, 3, 66, 0, 2, 17, 66, 0, 3, 66, 35, 0, 7, 6, 1, 80, 0, 4, 1, 21, 2, 32, 3, 47, 0, 2, 17, 66, 0, 3, 47, 35, 0, 7, 6, 1, 81, 0, 4, 1, 21, 2, 32, 3, 138, 0, 2, 17, 66, 0, 3, 138, 35, 0, 7, 6, 1, 82, 0, 4, 1, 21, 2, 32, 3, 72, 0, 2, 17, 66, 0, 3, 72, 35, 0, 7, 6, 1, 83, 0, 4, 1, 21, 2, 32, 3, 139, 0, 2, 17, 66, 0, 3, 139, 35, 0, 7, 6, 1, 84, 0, 4, 1, 21, 2, 32, 3, 50, 0, 2, 17, 66, 0, 3, 50, 35, 0, 7, 6, 1, 85, 0, 4, 1, 21, 2, 32, 3, 48, 0, 2, 17, 66, 0, 3, 48, 35, 0, 7, 6, 1, 86, 0, 4, 1, 21, 2, 32, 3, 136, 0, 2, 17, 66, 0, 3, 136, 35, 0, 7, 6, 1, 87, 0, 4, 1, 21, 2, 32, 3, 71, 0, 2, 17, 66, 0, 3, 71, 35, 0, 7, 6, 1, 88, 0, 4, 1, 21, 2, 32, 3, 137, 0, 2, 17, 66, 0, 3, 137, 35, 0, 7, 6, 1, 89, 0, 4, 1, 21, 2, 32, 3, 65, 0, 2, 17, 66, 0, 3, 65, 35, 0, 7, 6, 1, 90, 0, 4, 1, 21, 2, 32, 3, 149, 0, 2, 17, 66, 0, 3, 149, 35, 0, 7, 6, 1, 91, 0, 4, 1, 21, 2, 32, 3, 151, 0, 2, 17, 66, 0, 3, 151, 35, 0, 7, 6, 1, 92, 0, 4, 1, 21, 2, 32, 3, 150, 0, 2, 17, 66, 0, 3, 150, 35, 0, 7, 6, 1, 93, 0, 4, 1, 21, 2, 32, 3, 152, 0, 2, 17, 66, 0, 3, 152, 35, 0, 7, 6, 1, 94, 0, 4, 1, 21, 2, 32, 3, 58, 0, 2, 17, 66, 0, 3, 58, 35, 0, 7, 6, 1, 95, 0, 4, 1, 21, 2, 32, 3, 90, 0, 2, 17, 66, 0, 3, 90, 35, 0, 7, 6, 1, 96, 0, 4, 1, 21, 2, 32, 3, 88, 0, 2, 17, 66, 0, 3, 88, 35, 0, 7, 6, 1, 97, 0, 4, 1, 21, 2, 32, 3, 19, 0, 2, 17, 66, 0, 3, 19, 35, 0, 7, 6, 1, 98, 0, 4, 1, 21, 2, 32, 3, 57, 0, 2, 17, 66, 0, 3, 57, 35, 0, 7, 6, 1, 99, 0, 4, 1, 21, 2, 32, 3, 34, 0, 2, 17, 66, 0, 3, 34, 35, 0, 7, 6, 1, 100, 0, 4, 1, 21, 2, 32, 3, 55, 0, 2, 17, 66, 0, 3, 55, 35, 0, 7, 6, 1, 101, 0, 4, 1, 21, 2, 32, 3, 91, 0, 2, 17, 66, 0, 3, 91, 35, 0, 7, 6, 1, 102, 0, 4, 1, 21, 2, 32, 3, 93, 0, 2, 17, 66, 0, 3, 93, 35, 0, 7, 6, 1, 103, 0, 4, 1, 21, 2, 32, 3, 89, 0, 2, 17, 66, 0, 3, 89, 35, 0, 7, 6, 1, 104, 0, 4, 1, 21, 2, 32, 3, 108, 0, 2, 17, 66, 0, 3, 108, 35, 0, 7, 6, 1, 105, 0, 4, 1, 21, 2, 32, 3, 19, 0, 2, 17, 66, 0, 3, 19, 35, 0, 7, 6, 1, 106, 0, 4, 1, 21, 2, 32, 3, 49, 93, 0, 2, 17, 66, 0, 3, 49, 93, 35, 0, 7, 6, 224, 189, 0, 186, 3, 36, 0, 178, 3, 37, 0, 188, 3, 39, 0, 180, 3, 40, 0, 182, 3, 44, 0, 183, 3, 44, 12, 0, 184, 3, 45, 0, 185, 3, 45, 12, 0, 179, 3, 112, 0, 187, 3, 114, 0, 177, 3, 118, 0, 189, 3, 119, 0, 181, 3, 123, 0, 7, 6, 224, 190, 0, 4, 176, 1, 21, 2, 32, 3, 19, 0, 176, 2, 17, 66, 0, 184, 1, 21, 2, 32, 0, 184, 2, 17, 66, 0, 4, 176, 3, 19, 35, 0, 184, 0, 4, 178, 1, 21, 2, 32, 3, 34, 0, 178, 2, 17, 66, 0, 178, 3, 34, 35, 0, 4, 159, 1, 21, 2, 32, 3, 47, 0, 159, 2, 17, 66, 0, 159, 3, 47, 35, 0, 4, 164, 1, 21, 2, 32, 3, 48, 0, 164, 2, 17, 66, 0, 164, 3, 48, 35, 0, 4, 144, 1, 21, 2, 32, 3, 49, 0, 144, 2, 17, 66, 0, 144, 3, 49, 35, 0, 4, 185, 1, 21, 2, 32, 3, 49, 93, 0, 185, 2, 17, 66, 0, 185, 3, 49, 93, 35, 0, 4, 163, 1, 21, 2, 32, 3, 50, 0, 163, 2, 17, 66, 0, 163, 3, 50, 35, 0, 4, 179, 1, 21, 2, 32, 3, 55, 0, 179, 2, 17, 66, 0, 179, 3, 55, 35, 0, 4, 177, 1, 21, 2, 32, 3, 57, 0, 177, 2, 17, 66, 0, 177, 3, 57, 35, 0, 4, 173, 1, 21, 2, 32, 3, 58, 0, 173, 2, 17, 66, 0, 173, 3, 58, 35, 0, 4, 168, 1, 21, 2, 32, 3, 65, 0, 168, 2, 17, 66, 0, 168, 3, 65, 35, 0, 4, 158, 1, 21, 2, 32, 3, 66, 0, 158, 2, 17, 66, 0, 158, 3, 66, 35, 0, 4, 153, 1, 21, 2, 32, 3, 67, 0, 153, 2, 17, 66, 0, 153, 3, 67, 35, 0, 4, 148, 1, 21, 2, 32, 3, 68, 0, 148, 2, 17, 66, 0, 148, 3, 68, 35, 0, 4, 166, 1, 21, 2, 32, 3, 71, 0, 166, 2, 17, 66, 0, 166, 3, 71, 35, 0, 4, 161, 1, 21, 2, 32, 3, 72, 0, 161, 2, 17, 66, 0, 161, 3, 72, 35, 0, 4, 151, 1, 21, 2, 32, 3, 79, 0, 151, 2, 17, 66, 0, 151, 3, 79, 35, 0, 4, 149, 1, 21, 2, 32, 3, 80, 0, 149, 2, 17, 66, 0, 149, 3, 80, 35, 0, 4, 146, 1, 21, 2, 32, 3, 81, 0, 146, 2, 17, 66, 0, 146, 3, 81, 35, 0, 4, 175, 1, 21, 2, 32, 3, 88, 0, 175, 2, 17, 66, 0, 175, 3, 88, 35, 0, 4, 182, 1, 21, 2, 32, 3, 89, 0, 182, 2, 17, 66, 0, 182, 3, 89, 35, 0, 4, 174, 1, 21, 2, 32, 3, 90, 0, 174, 2, 17, 66, 0, 174, 3, 90, 35, 0, 4, 180, 1, 21, 2, 32, 3, 91, 0, 180, 2, 17, 66, 0, 180, 3, 91, 35, 0, 4, 181, 1, 21, 2, 32, 3, 93, 0, 181, 2, 17, 66, 0, 181, 3, 93, 35, 0, 4, 183, 1, 21, 2, 32, 3, 108, 0, 183, 2, 17, 66, 0, 183, 3, 108, 35, 0, 4, 165, 1, 21, 2, 32, 3, 136, 0, 165, 2, 17, 66, 0, 165, 3, 136, 35, 0, 4, 167, 1, 21, 2, 32, 3, 137, 0, 167, 2, 17, 66, 0, 167, 3, 137, 35, 0, 4, 160, 1, 21, 2, 32, 3, 138, 0, 160, 2, 17, 66, 0, 160, 3, 138, 35, 0, 4, 162, 1, 21, 2, 32, 3, 139, 0, 162, 2, 17, 66, 0, 162, 3, 139, 35, 0, 4, 154, 1, 21, 2, 32, 3, 140, 0, 154, 2, 17, 66, 0, 154, 3, 140, 35, 0, 4, 156, 1, 21, 2, 32, 3, 141, 0, 156, 2, 17, 66, 0, 156, 3, 141, 35, 0, 4, 155, 1, 21, 2, 32, 3, 142, 0, 155, 2, 17, 66, 0, 155, 3, 142, 35, 0, 4, 157, 1, 21, 2, 32, 3, 143, 0, 157, 2, 17, 66, 0, 157, 3, 143, 35, 0, 4, 150, 1, 21, 2, 32, 3, 144, 0, 150, 2, 17, 66, 0, 150, 3, 144, 35, 0, 4, 145, 1, 21, 2, 32, 3, 146, 0, 145, 2, 17, 66, 0, 145, 3, 146, 35, 0, 147, 1, 21, 2, 32, 3, 147, 0, 147, 3, 147, 35, 0, 4, 169, 1, 21, 2, 32, 3, 149, 0, 169, 2, 17, 66, 0, 169, 3, 149, 35, 0, 4, 171, 1, 21, 2, 32, 3, 150, 0, 171, 2, 17, 66, 0, 171, 3, 150, 35, 0, 4, 170, 1, 21, 2, 32, 3, 151, 0, 170, 2, 17, 66, 0, 170, 3, 151, 35, 0, 4, 172, 1, 21, 2, 32, 3, 152, 0, 172, 2, 17, 66, 0, 172, 3, 152, 35, 0, 7, 6, 0, 36, 3, 72, 39, 55, 35, 34, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts6 = FileInMemory_createWithData (2829, reinterpret_cast (&espeakdata_dicts6_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/bo_dict", U"bo"); Collection_addItem (me.peek(), espeakdata_dicts6.transfer()); static unsigned char espeakdata_dicts7_data[4178] = { 0, 4, 0, 0, 46, 12, 0, 0, 0, 0, 0, 0, 0, 6, 65, 4, 35, 0, 14, 5, 193, 4, 72, 28, 0, 0, 0, 0, 6, 65, 8, 71, 36, 0, 0, 0, 6, 195, 4, 208, 128, 28, 0, 0, 6, 65, 12, 89, 36, 0, 0, 0, 13, 4, 95, 8, 1, 3, 49, 35, 69, 6, 110, 50, 0, 0, 0, 6, 65, 16, 72, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 65, 24, 109, 83, 124, 0, 0, 0, 0, 0, 6, 65, 28, 79, 36, 0, 9, 134, 19, 5, 18, 195, 160, 19, 76, 0, 0, 0, 0, 6, 65, 32, 35, 49, 0, 0, 0, 0, 14, 1, 35, 49, 111, 57, 97, 37, 50, 6, 109, 47, 0, 27, 0, 6, 65, 36, 37, 0, 14, 5, 193, 36, 72, 8, 0, 15, 1, 37, 48, 13, 51, 89, 13, 50, 47, 6, 35, 77, 13, 0, 0, 18, 1, 38, 9, 9, 6, 37, 38, 15, 9, 124, 68, 55, 6, 109, 88, 124, 0, 0, 0, 8, 65, 40, 96, 110, 47, 124, 0, 0, 0, 9, 67, 21, 68, 192, 36, 123, 0, 76, 14, 1, 42, 35, 89, 47, 36, 16, 6, 37, 89, 49, 0, 27, 0, 9, 1, 43, 65, 16, 36, 89, 0, 27, 0, 6, 65, 44, 49, 36, 0, 0, 9, 1, 45, 65, 6, 109, 67, 89, 0, 0, 0, 9, 1, 47, 71, 35, 16, 51, 35, 0, 0, 7, 65, 48, 109, 55, 124, 0, 0, 0, 0, 0, 7, 65, 52, 109, 65, 124, 0, 0, 0, 0, 0, 7, 65, 56, 109, 50, 124, 0, 0, 0, 0, 0, 6, 65, 60, 39, 0, 14, 5, 193, 60, 72, 8, 0, 11, 1, 61, 37, 100, 58, 6, 35, 55, 0, 27, 0, 0, 0, 6, 65, 64, 48, 36, 0, 11, 1, 64, 35, 16, 51, 6, 39, 82, 35, 0, 0, 0, 0, 0, 6, 65, 68, 49, 40, 0, 0, 0, 6, 195, 84, 224, 64, 72, 0, 0, 8, 65, 72, 109, 51, 52, 13, 0, 0, 0, 0, 0, 8, 65, 76, 109, 89, 89, 13, 0, 0, 0, 0, 0, 6, 65, 80, 47, 36, 0, 0, 0, 0, 0, 0, 11, 4, 19, 195, 179, 14, 89, 39, 50, 0, 76, 0, 0, 0, 13, 65, 88, 6, 85, 36, 15, 71, 6, 117, 97, 124, 0, 0, 0, 0, 10, 135, 19, 5, 18, 195, 173, 5, 13, 76, 0, 14, 65, 92, 6, 85, 36, 15, 72, 6, 39, 71, 55, 13, 0, 0, 0, 16, 1, 94, 89, 37, 51, 49, 40, 65, 83, 55, 6, 109, 49, 89, 0, 0, 0, 7, 65, 96, 37, 49, 89, 0, 0, 0, 11, 4, 19, 195, 179, 3, 89, 39, 49, 0, 76, 0, 10, 135, 19, 5, 18, 195, 173, 5, 21, 76, 0, 12, 65, 100, 6, 37, 15, 81, 69, 109, 100, 124, 0, 0, 0, 0, 0, 8, 65, 104, 88, 36, 47, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 84, 225, 83, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 16, 80, 72, 0, 0, 0, 6, 195, 16, 83, 0, 72, 0, 0, 0, 12, 4, 95, 4, 16, 20, 10, 49, 39, 65, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 4, 192, 72, 28, 0, 0, 13, 4, 95, 20, 12, 4, 47, 6, 37, 55, 72, 36, 0, 0, 0, 0, 6, 195, 84, 228, 192, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 32, 21, 137, 4, 76, 0, 0, 7, 66, 32, 16, 35, 0, 76, 0, 6, 195, 25, 82, 64, 76, 0, 0, 0, 0, 0, 0, 0, 0, 9, 67, 32, 19, 128, 35, 50, 0, 76, 0, 0, 8, 197, 32, 21, 137, 21, 48, 76, 0, 0, 0, 0, 8, 197, 76, 84, 137, 21, 48, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 32, 21, 137, 21, 80, 76, 0, 0, 0, 0, 0, 0, 0, 7, 196, 24, 244, 133, 56, 76, 0, 0, 0, 0, 0, 0, 0, 11, 3, 226, 130, 172, 6, 109, 58, 16, 111, 0, 0, 0, 0, 0, 0, 0, 0, 7, 66, 32, 80, 109, 0, 76, 0, 0, 8, 133, 6, 195, 179, 18, 1, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 76, 84, 133, 52, 76, 0, 0, 6, 194, 20, 192, 72, 28, 5, 194, 20, 192, 72, 0, 9, 67, 32, 20, 192, 35, 89, 0, 76, 10, 3, 95, 50, 48, 85, 6, 37, 50, 0, 0, 7, 196, 76, 84, 129, 56, 76, 0, 0, 0, 0, 0, 0, 14, 4, 95, 13, 3, 14, 65, 35, 49, 69, 6, 110, 50, 0, 0, 19, 3, 197, 128, 12, 109, 55, 124, 4, 90, 13, 65, 37, 50, 6, 35, 86, 124, 0, 0, 0, 0, 0, 0, 7, 196, 76, 84, 137, 4, 76, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 24, 244, 133, 76, 76, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 76, 84, 133, 84, 76, 0, 0, 6, 194, 20, 224, 72, 28, 0, 13, 3, 95, 51, 88, 47, 69, 6, 109, 50, 47, 124, 0, 0, 12, 3, 95, 48, 67, 89, 6, 109, 50, 47, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 49, 67, 89, 6, 109, 50, 47, 0, 0, 0, 0, 0, 0, 0, 5, 194, 48, 16, 72, 12, 3, 95, 49, 57, 72, 37, 50, 6, 39, 40, 0, 0, 13, 3, 95, 49, 56, 72, 37, 82, 6, 40, 57, 47, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 49, 49, 6, 110, 50, 88, 13, 0, 0, 10, 3, 95, 49, 48, 72, 6, 36, 58, 0, 0, 13, 3, 95, 49, 51, 47, 69, 6, 109, 72, 88, 13, 0, 0, 12, 3, 95, 49, 50, 72, 6, 39, 72, 88, 13, 0, 0, 12, 3, 95, 49, 53, 49, 6, 37, 50, 88, 13, 0, 0, 14, 3, 95, 49, 52, 49, 124, 47, 6, 39, 51, 88, 13, 0, 0, 12, 3, 95, 49, 55, 72, 37, 89, 6, 109, 47, 0, 0, 12, 3, 95, 49, 54, 89, 6, 109, 72, 88, 13, 0, 0, 0, 14, 3, 95, 55, 88, 89, 13, 47, 6, 35, 50, 47, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 53, 67, 89, 37, 50, 89, 6, 109, 50, 123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 32, 21, 137, 20, 208, 76, 0, 0, 0, 0, 0, 0, 12, 3, 95, 50, 88, 85, 4, 37, 50, 47, 37, 0, 0, 14, 3, 95, 55, 67, 89, 4, 36, 123, 6, 109, 50, 123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 32, 21, 137, 20, 224, 76, 0, 0, 0, 13, 3, 95, 63, 63, 89, 6, 37, 65, 71, 110, 55, 0, 0, 8, 197, 76, 84, 137, 20, 224, 76, 0, 0, 15, 3, 95, 52, 88, 49, 58, 124, 69, 6, 35, 50, 47, 124, 0, 0, 15, 3, 95, 57, 67, 50, 4, 110, 40, 89, 6, 109, 50, 123, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 53, 88, 89, 37, 50, 49, 58, 6, 35, 50, 47, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 54, 88, 89, 13, 57, 97, 6, 35, 50, 47, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 56, 88, 85, 40, 57, 47, 6, 35, 50, 47, 124, 0, 0, 0, 0, 0, 6, 195, 24, 245, 64, 76, 0, 0, 0, 0, 14, 3, 95, 57, 88, 50, 111, 69, 6, 35, 50, 47, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 15, 7, 15, 49, 39, 55, 6, 37, 47, 35, 0, 0, 7, 196, 20, 229, 18, 20, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 4, 95, 48, 77, 50, 65, 37, 61, 6, 39, 50, 13, 89, 0, 0, 0, 0, 11, 4, 95, 48, 77, 49, 65, 6, 37, 55, 0, 0, 13, 4, 95, 2, 18, 22, 71, 69, 6, 36, 82, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 4, 12, 194, 183, 12, 109, 55, 124, 4, 90, 13, 65, 37, 50, 6, 35, 86, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 66, 48, 192, 6, 109, 37, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 64, 83, 0, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 3, 195, 169, 19, 36, 89, 0, 76, 19, 4, 95, 3, 9, 18, 89, 37, 51, 49, 40, 65, 83, 55, 6, 109, 49, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 19, 20, 11, 71, 6, 35, 16, 51, 35, 0, 0, 0, 13, 4, 95, 1, 3, 21, 35, 100, 6, 40, 86, 39, 0, 0, 20, 3, 95, 194, 171, 6, 39, 71, 69, 13, 15, 49, 111, 65, 6, 109, 47, 13, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 18, 14, 7, 35, 50, 6, 37, 98, 39, 0, 0, 23, 3, 95, 194, 161, 35, 82, 69, 6, 37, 51, 35, 86, 65, 37, 69, 35, 87, 57, 6, 110, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 19, 5, 18, 195, 160, 76, 0, 0, 0, 0, 0, 0, 6, 195, 21, 32, 64, 76, 0, 0, 0, 8, 133, 19, 5, 18, 195, 169, 76, 7, 195, 64, 83, 19, 72, 28, 0, 0, 0, 0, 20, 4, 95, 1, 3, 50, 72, 6, 110, 71, 55, 36, 15, 35, 100, 6, 40, 86, 39, 0, 0, 0, 0, 6, 195, 21, 33, 78, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 3, 95, 194, 191, 35, 82, 69, 6, 37, 51, 37, 50, 47, 109, 16, 51, 4, 39, 100, 35, 87, 57, 6, 110, 50, 0, 0, 0, 0, 0, 6, 195, 21, 33, 83, 76, 21, 3, 95, 194, 187, 47, 6, 35, 50, 49, 124, 15, 49, 111, 65, 6, 109, 47, 13, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 6, 195, 179, 18, 5, 13, 76, 0, 0, 0, 6, 195, 16, 83, 19, 72, 0, 0, 0, 13, 2, 194, 167, 124, 48, 124, 69, 47, 6, 35, 47, 0, 0, 0, 0, 0, 12, 2, 194, 163, 55, 55, 37, 40, 69, 13, 89, 0, 0, 0, 0, 0, 16, 2, 195, 167, 89, 36, 4, 47, 69, 13, 50, 49, 35, 86, 124, 0, 0, 0, 0, 0, 0, 0, 14, 2, 194, 169, 49, 39, 48, 37, 16, 51, 6, 117, 47, 0, 0, 14, 2, 194, 182, 48, 124, 69, 6, 35, 100, 69, 124, 83, 0, 0, 0, 0, 9, 134, 6, 195, 179, 18, 5, 21, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 4, 95, 3, 5, 4, 47, 69, 109, 50, 49, 6, 35, 86, 35, 0, 0, 0, 0, 8, 2, 195, 177, 109, 67, 13, 0, 16, 4, 95, 12, 9, 7, 55, 37, 100, 35, 86, 6, 40, 69, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 67, 32, 83, 64, 109, 65, 0, 76, 6, 195, 76, 243, 64, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 67, 32, 85, 64, 109, 58, 0, 76, 6, 195, 76, 245, 64, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 2, 95, 1, 35, 0, 0, 0, 0, 0, 0, 0, 0, 6, 2, 95, 9, 37, 0, 0, 0, 6, 2, 95, 15, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 2, 95, 34, 49, 111, 65, 6, 109, 47, 13, 89, 0, 0, 23, 2, 95, 33, 89, 6, 37, 81, 50, 13, 15, 72, 124, 72, 65, 37, 69, 124, 89, 57, 6, 39, 0, 0, 0, 15, 2, 95, 39, 124, 48, 6, 110, 89, 47, 69, 6, 111, 83, 0, 0, 0, 0, 0, 0, 13, 4, 95, 3, 1, 16, 65, 6, 35, 98, 40, 89, 0, 0, 23, 2, 95, 41, 47, 6, 35, 50, 49, 124, 15, 48, 124, 69, 6, 109, 50, 47, 13, 88, 37, 89, 0, 0, 22, 2, 95, 40, 6, 39, 71, 69, 13, 15, 48, 124, 69, 6, 109, 50, 47, 13, 88, 37, 89, 0, 0, 7, 195, 64, 84, 128, 72, 28, 10, 2, 95, 47, 71, 35, 16, 51, 35, 0, 0, 8, 2, 95, 46, 48, 40, 50, 0, 0, 0, 9, 2, 95, 44, 49, 39, 65, 35, 0, 0, 10, 2, 95, 51, 47, 69, 6, 36, 89, 0, 0, 9, 2, 95, 50, 72, 6, 110, 89, 0, 0, 7, 2, 95, 49, 6, 40, 0, 0, 10, 2, 95, 48, 88, 6, 36, 69, 111, 0, 0, 9, 2, 95, 55, 89, 6, 109, 47, 0, 0, 9, 2, 95, 54, 89, 6, 37, 89, 0, 0, 10, 2, 95, 53, 89, 6, 37, 68, 49, 0, 20, 4, 95, 4, 1, 3, 72, 6, 110, 71, 55, 36, 15, 35, 100, 6, 40, 86, 39, 0, 0, 12, 2, 95, 52, 49, 58, 6, 35, 47, 69, 13, 0, 0, 15, 2, 95, 59, 48, 4, 40, 50, 37, 49, 6, 39, 65, 35, 0, 0, 15, 2, 95, 58, 72, 6, 39, 89, 15, 48, 6, 40, 50, 89, 0, 0, 9, 2, 95, 57, 50, 6, 39, 58, 0, 0, 10, 2, 95, 56, 85, 6, 40, 57, 47, 0, 0, 26, 2, 95, 63, 89, 6, 37, 81, 50, 13, 15, 72, 37, 50, 47, 13, 51, 52, 111, 100, 124, 89, 57, 6, 39, 0, 0, 15, 2, 95, 62, 65, 124, 96, 6, 39, 15, 9, 9, 49, 13, 0, 0, 0, 15, 2, 95, 60, 65, 13, 50, 6, 39, 15, 9, 9, 49, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 95, 4, 15, 20, 48, 6, 40, 50, 47, 0, 0, 0, 0, 22, 2, 95, 91, 6, 39, 71, 69, 13, 15, 49, 55, 124, 58, 86, 6, 35, 47, 4, 39, 16, 0, 0, 0, 0, 7, 66, 88, 144, 84, 37, 0, 0, 18, 2, 95, 95, 71, 6, 35, 51, 52, 124, 15, 82, 6, 35, 57, 97, 124, 0, 0, 0, 23, 2, 95, 93, 47, 6, 35, 50, 49, 124, 15, 49, 55, 124, 58, 86, 6, 35, 47, 4, 39, 16, 0, 0, 21, 2, 95, 92, 71, 6, 35, 16, 51, 35, 37, 65, 71, 109, 51, 47, 6, 37, 86, 35, 0, 0, 0, 0, 0, 19, 2, 95, 96, 124, 49, 89, 6, 109, 50, 47, 4, 111, 82, 6, 109, 69, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 7, 18, 22, 81, 69, 6, 35, 82, 36, 0, 0, 0, 0, 0, 0, 6, 195, 48, 84, 192, 72, 0, 0, 0, 0, 0, 0, 0, 0, 17, 2, 95, 123, 6, 39, 71, 69, 13, 15, 49, 55, 6, 35, 58, 89, 0, 16, 4, 95, 4, 9, 1, 72, 57, 6, 109, 69, 36, 89, 37, 89, 0, 0, 10, 4, 95, 35, 57, 96, 47, 35, 71, 0, 0, 0, 0, 0, 0, 18, 2, 95, 125, 47, 6, 35, 50, 49, 124, 15, 49, 55, 6, 35, 58, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 84, 224, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 35, 51, 50, 13, 89, 48, 6, 35, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 195, 169, 18, 5, 13, 76, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 195, 169, 18, 5, 21, 76, 0, 0, 0, 0, 0, 0, 0, 6, 195, 20, 196, 192, 72, 0, 0, 0, 0, 7, 195, 4, 196, 192, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 18, 66, 102, 0, 104, 0, 108, 0, 114, 0, 115, 0, 118, 0, 119, 0, 121, 0, 122, 0, 7, 6, 18, 67, 104, 0, 108, 0, 114, 0, 115, 0, 118, 0, 119, 0, 121, 0, 122, 0, 7, 6, 18, 68, 102, 0, 104, 0, 114, 0, 115, 0, 118, 0, 119, 0, 121, 0, 122, 0, 7, 6, 18, 69, 195, 173, 0, 195, 169, 0, 195, 168, 0, 105, 0, 101, 0, 7, 6, 18, 70, 112, 0, 116, 0, 107, 0, 102, 0, 115, 0, 7, 6, 18, 74, 98, 0, 100, 0, 103, 0, 109, 0, 118, 0, 108, 0, 110, 0, 100, 0, 122, 0, 114, 0, 113, 0, 7, 6, 18, 75, 97, 0, 101, 0, 111, 0, 7, 6, 18, 76, 105, 0, 117, 0, 7, 6, 18, 86, 112, 0, 98, 0, 116, 0, 100, 0, 107, 0, 103, 0, 7, 6, 18, 87, 102, 0, 118, 0, 115, 0, 122, 0, 7, 6, 18, 88, 109, 0, 110, 0, 7, 6, 18, 89, 108, 108, 0, 108, 0, 7, 6, 18, 90, 114, 0, 7, 6, 195, 167, 0, 3, 89, 0, 7, 6, 97, 0, 101, 3, 4, 35, 125, 0, 3, 35, 0, 109, 98, 2, 32, 17, 65, 3, 35, 65, 0, 7, 6, 98, 0, 2, 32, 3, 48, 0, 3, 71, 0, 4, 1, 17, 65, 2, 17, 65, 3, 82, 0, 1, 18, 67, 2, 17, 65, 0, 1, 32, 17, 65, 2, 17, 65, 0, 1, 32, 18, 67, 2, 17, 65, 0, 7, 6, 99, 0, 3, 49, 0, 2, 18, 69, 3, 89, 0, 7, 6, 100, 0, 2, 32, 3, 47, 0, 118, 3, 71, 71, 0, 3, 72, 0, 106, 3, 77, 0, 4, 1, 17, 65, 2, 17, 65, 3, 86, 0, 1, 18, 68, 2, 17, 65, 0, 1, 32, 17, 65, 2, 17, 65, 0, 1, 32, 18, 68, 2, 17, 65, 0, 7, 6, 101, 0, 2, 110, 116, 32, 3, 36, 0, 3, 109, 0, 97, 3, 125, 4, 35, 0, 111, 3, 125, 4, 39, 0, 7, 6, 102, 0, 3, 83, 0, 7, 6, 103, 0, 2, 32, 3, 49, 0, 117, 105, 3, 77, 37, 0, 4, 3, 81, 0, 117, 2, 18, 69, 0, 2, 18, 69, 3, 96, 0, 4, 1, 17, 65, 2, 17, 65, 3, 100, 0, 1, 17, 65, 2, 114, 17, 65, 0, 1, 18, 66, 2, 17, 65, 0, 1, 32, 17, 65, 2, 17, 65, 0, 1, 32, 18, 66, 2, 17, 65, 0, 7, 6, 104, 0, 3, 0, 105, 1, 45, 2, 32, 3, 6, 37, 0, 111, 1, 45, 2, 32, 3, 6, 111, 0, 7, 6, 105, 0, 4, 3, 37, 0, 1, 188, 195, 103, 2, 25, 0, 1, 188, 195, 113, 2, 25, 0, 2, 97, 32, 0, 2, 117, 0, 4, 1, 17, 65, 2, 25, 12, 3, 57, 0, 2, 17, 65, 0, 103, 1, 17, 65, 2, 32, 3, 78, 0, 120, 1, 17, 65, 3, 97, 0, 7, 6, 106, 0, 3, 96, 0, 7, 6, 107, 0, 3, 49, 0, 7, 6, 108, 0, 4, 3, 55, 0, 39, 8, 2, 14, 128, 132, 130, 0, 97, 1, 45, 2, 32, 3, 55, 124, 0, 108, 3, 61, 0, 7, 6, 109, 0, 4, 3, 65, 0, 39, 8, 2, 14, 128, 132, 130, 0, 112, 2, 25, 0, 7, 6, 110, 0, 4, 2, 32, 3, 8, 50, 0, 116, 2, 32, 0, 4, 3, 50, 0, 1, 101, 2, 32, 0, 1, 105, 2, 32, 0, 39, 8, 2, 14, 128, 132, 130, 0, 116, 2, 25, 0, 4, 1, 21, 2, 98, 3, 65, 0, 1, 21, 2, 118, 0, 1, 98, 2, 21, 0, 1, 118, 2, 21, 0, 121, 3, 67, 0, 4, 2, 99, 25, 3, 68, 0, 103, 0, 7, 6, 111, 0, 114, 2, 32, 3, 6, 39, 16, 0, 3, 39, 0, 117, 3, 110, 58, 0, 7, 6, 112, 0, 3, 48, 0, 2, 116, 3, 48, 12, 0, 7, 6, 113, 0, 4, 3, 49, 0, 117, 2, 18, 69, 0, 195, 188, 3, 49, 58, 0, 117, 105, 3, 49, 58, 37, 0, 7, 6, 114, 0, 2, 32, 3, 8, 0, 4, 8, 3, 16, 51, 0, 114, 0, 4, 3, 51, 0, 1, 108, 2, 17, 65, 0, 1, 109, 2, 17, 65, 0, 1, 110, 2, 17, 65, 0, 1, 115, 2, 17, 65, 0, 4, 1, 17, 65, 2, 17, 65, 3, 69, 0, 1, 17, 67, 2, 17, 65, 0, 2, 116, 0, 7, 6, 115, 0, 1, 17, 65, 2, 17, 65, 3, 88, 0, 4, 3, 89, 0, 1, 21, 2, 32, 14, 128, 128, 129, 0, 39, 8, 2, 14, 128, 132, 130, 0, 115, 0, 101, 1, 45, 2, 32, 3, 89, 13, 0, 7, 6, 116, 0, 4, 3, 47, 0, 39, 8, 2, 14, 128, 132, 130, 0, 109, 3, 65, 65, 0, 122, 3, 72, 88, 0, 4, 103, 2, 18, 69, 3, 77, 0, 106, 0, 4, 106, 2, 32, 3, 78, 0, 120, 0, 7, 6, 117, 0, 4, 3, 40, 0, 2, 105, 0, 117, 3, 40, 58, 0, 4, 1, 17, 65, 2, 25, 3, 58, 0, 2, 17, 65, 0, 7, 6, 118, 0, 3, 82, 0, 8, 3, 85, 0, 7, 6, 119, 0, 3, 58, 0, 7, 6, 120, 0, 4, 3, 49, 89, 0, 8, 17, 65, 2, 18, 70, 0, 8, 17, 65, 3, 81, 88, 0, 4, 1, 25, 3, 97, 0, 1, 105, 17, 65, 0, 1, 117, 17, 65, 0, 7, 6, 121, 0, 3, 37, 0, 2, 17, 65, 3, 57, 0, 7, 6, 122, 0, 3, 88, 0, 7, 6, 0, 195, 160, 3, 7, 35, 0, 195, 169, 3, 7, 36, 0, 195, 173, 3, 7, 37, 0, 195, 179, 3, 7, 39, 0, 195, 186, 3, 7, 40, 0, 195, 168, 3, 7, 109, 0, 195, 178, 3, 7, 110, 0, 195, 175, 3, 37, 0, 195, 188, 3, 40, 0, 197, 128, 3, 55, 0, 195, 188, 1, 103, 3, 58, 0, 195, 177, 3, 67, 0, 36, 3, 72, 39, 55, 124, 16, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts7 = FileInMemory_createWithData (4177, reinterpret_cast (&espeakdata_dicts7_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/ca_dict", U"ca"); Collection_addItem (me.peek(), espeakdata_dicts7.transfer()); static unsigned char espeakdata_dicts8_data[7615] = { 0, 4, 0, 0, 70, 17, 0, 0, 0, 0, 0, 0, 6, 195, 41, 49, 77, 72, 0, 6, 65, 4, 124, 0, 14, 6, 193, 4, 72, 28, 8, 0, 0, 6, 195, 12, 16, 128, 17, 9, 134, 2, 196, 155, 8, 5, 13, 8, 0, 0, 6, 65, 8, 71, 123, 0, 0, 0, 0, 0, 6, 65, 12, 117, 123, 0, 0, 0, 13, 4, 95, 8, 1, 3, 107, 6, 124, 76, 36, 49, 0, 0, 0, 6, 65, 16, 72, 123, 0, 0, 7, 132, 196, 141, 19, 18, 17, 0, 0, 0, 5, 65, 20, 123, 0, 0, 0, 6, 195, 41, 50, 64, 72, 0, 0, 14, 69, 4, 229, 15, 56, 144, 35, 50, 47, 39, 50, 37, 0, 6, 65, 24, 36, 83, 0, 0, 0, 0, 6, 195, 41, 51, 69, 72, 0, 6, 65, 28, 81, 123, 0, 0, 6, 195, 29, 0, 64, 17, 0, 11, 67, 64, 117, 80, 48, 131, 75, 35, 48, 0, 0, 0, 6, 65, 32, 107, 124, 0, 0, 14, 1, 33, 84, 37, 81, 133, 37, 76, 67, 121, 49, 0, 27, 0, 0, 10, 1, 35, 81, 133, 121, 90, 36, 49, 0, 0, 6, 65, 36, 121, 0, 14, 5, 193, 36, 72, 28, 0, 5, 194, 37, 0, 17, 13, 1, 37, 48, 51, 39, 117, 36, 50, 47, 39, 0, 27, 0, 12, 1, 38, 35, 65, 48, 44, 89, 36, 50, 47, 0, 0, 0, 7, 132, 12, 5, 196, 141, 8, 6, 65, 40, 57, 123, 0, 0, 0, 15, 1, 42, 107, 84, 57, 36, 88, 79, 37, 76, 49, 35, 0, 27, 15, 1, 42, 107, 84, 57, 36, 88, 79, 37, 76, 49, 35, 0, 27, 0, 9, 1, 43, 48, 55, 40, 89, 0, 27, 0, 7, 65, 44, 49, 124, 0, 14, 4, 193, 44, 28, 0, 6, 195, 45, 0, 64, 17, 0, 10, 1, 46, 47, 36, 76, 49, 35, 0, 27, 0, 10, 1, 47, 55, 39, 65, 36, 50, 39, 0, 0, 6, 65, 48, 36, 55, 0, 0, 0, 0, 7, 196, 88, 81, 12, 20, 8, 0, 6, 65, 52, 36, 65, 0, 0, 6, 195, 53, 0, 64, 17, 0, 9, 134, 2, 21, 4, 5, 197, 161, 72, 0, 0, 11, 136, 3, 8, 20, 196, 155, 10, 195, 173, 76, 8, 197, 9, 81, 5, 52, 80, 72, 6, 65, 56, 36, 50, 0, 0, 0, 0, 0, 6, 65, 60, 125, 0, 14, 6, 193, 60, 72, 8, 23, 0, 10, 1, 61, 51, 39, 84, 50, 39, 0, 27, 0, 0, 10, 67, 76, 150, 133, 89, 35, 57, 88, 0, 0, 11, 1, 64, 88, 35, 84, 37, 50, 124, 76, 0, 6, 65, 64, 48, 123, 0, 0, 0, 6, 195, 20, 81, 192, 17, 0, 0, 7, 65, 68, 49, 84, 123, 0, 0, 0, 0, 7, 132, 13, 196, 155, 12, 76, 0, 6, 65, 72, 36, 51, 0, 0, 0, 0, 0, 7, 65, 76, 36, 89, 0, 14, 7, 65, 76, 89, 10, 0, 8, 10, 133, 16, 197, 153, 5, 4, 72, 8, 23, 0, 0, 0, 6, 195, 76, 144, 197, 8, 0, 6, 65, 80, 47, 123, 0, 0, 0, 6, 195, 4, 226, 64, 8, 0, 11, 67, 84, 226, 69, 40, 50, 37, 57, 36, 0, 6, 195, 52, 86, 137, 8, 0, 0, 7, 66, 85, 0, 35, 48, 0, 8, 133, 4, 195, 173, 11, 25, 8, 0, 0, 0, 12, 69, 12, 128, 78, 28, 80, 76, 131, 50, 75, 0, 7, 65, 88, 84, 123, 0, 14, 8, 197, 12, 128, 197, 80, 80, 76, 7, 65, 88, 84, 10, 0, 28, 0, 0, 0, 14, 4, 95, 49, 77, 52, 71, 6, 37, 55, 37, 125, 50, 0, 0, 11, 1, 92, 71, 36, 49, 89, 55, 36, 91, 0, 11, 65, 92, 72, 84, 6, 39, 57, 84, 123, 0, 0, 0, 11, 1, 94, 88, 72, 133, 121, 91, 49, 35, 0, 0, 0, 13, 4, 95, 49, 77, 49, 80, 6, 37, 89, 121, 117, 0, 7, 65, 96, 37, 49, 89, 0, 0, 14, 4, 95, 49, 77, 50, 65, 6, 37, 55, 37, 125, 50, 0, 0, 16, 4, 95, 49, 77, 51, 65, 6, 37, 55, 37, 35, 51, 72, 35, 0, 0, 0, 9, 67, 16, 245, 206, 72, 127, 50, 0, 11, 65, 100, 37, 48, 89, 37, 55, 39, 50, 0, 0, 0, 0, 0, 8, 65, 104, 88, 36, 47, 0, 14, 7, 65, 104, 89, 10, 0, 28, 0, 0, 6, 195, 5, 65, 0, 17, 0, 11, 68, 5, 48, 201, 36, 35, 89, 49, 37, 0, 0, 0, 15, 70, 84, 229, 9, 80, 193, 68, 35, 50, 47, 37, 47, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 57, 52, 128, 17, 0, 0, 0, 0, 19, 71, 8, 19, 9, 77, 66, 75, 4, 71, 35, 55, 37, 89, 47, 37, 49, 35, 0, 9, 1, 126, 47, 37, 55, 72, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 196, 65, 35, 212, 36, 72, 8, 0, 0, 0, 6, 195, 13, 33, 0, 17, 0, 0, 0, 0, 8, 133, 196, 141, 19, 19, 18, 17, 0, 0, 0, 7, 132, 3, 15, 197, 190, 8, 0, 6, 195, 93, 34, 64, 17, 0, 0, 0, 0, 6, 195, 17, 2, 64, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 72, 196, 128, 17, 6, 195, 56, 68, 128, 17, 6, 195, 8, 196, 128, 17, 0, 0, 0, 0, 6, 195, 73, 52, 192, 17, 0, 0, 0, 0, 0, 6, 195, 41, 51, 213, 72, 0, 0, 0, 0, 0, 0, 0, 6, 195, 84, 102, 128, 17, 0, 0, 14, 67, 16, 51, 0, 72, 36, 117, 37, 55, 37, 47, 44, 0, 0, 0, 0, 0, 0, 9, 198, 56, 20, 18, 61, 66, 64, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 72, 192, 192, 17, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 85, 97, 128, 17, 0, 6, 195, 9, 81, 5, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 4, 16, 20, 9, 76, 124, 51, 49, 35, 10, 0, 0, 0, 5, 194, 9, 144, 72, 5, 194, 9, 144, 72, 0, 0, 6, 195, 9, 81, 21, 72, 0, 6, 195, 9, 147, 0, 72, 0, 0, 0, 0, 0, 7, 66, 12, 128, 101, 124, 0, 0, 0, 13, 4, 95, 20, 12, 4, 80, 6, 37, 55, 72, 35, 0, 10, 3, 95, 35, 57, 47, 6, 35, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 61, 165, 128, 17, 0, 0, 0, 0, 16, 70, 21, 128, 200, 4, 225, 197, 37, 49, 89, 76, 131, 50, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 69, 76, 52, 143, 48, 192, 89, 49, 34, 125, 55, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 56, 80, 143, 72, 8, 0, 0, 6, 195, 45, 35, 205, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 67, 57, 83, 64, 50, 35, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 60, 52, 128, 17, 0, 0, 13, 69, 12, 19, 131, 20, 192, 49, 36, 50, 89, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 66, 12, 208, 117, 36, 50, 47, 37, 65, 36, 47, 44, 0, 6, 195, 8, 86, 133, 8, 0, 0, 0, 0, 0, 7, 195, 8, 86, 128, 8, 23, 0, 0, 0, 0, 0, 7, 196, 44, 243, 5, 52, 8, 0, 6, 195, 44, 193, 18, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 60, 65, 64, 72, 28, 9, 3, 226, 130, 172, 128, 51, 39, 0, 0, 0, 8, 195, 76, 180, 154, 72, 28, 23, 0, 9, 67, 64, 17, 197, 48, 131, 75, 0, 6, 131, 196, 141, 1, 17, 0, 0, 8, 133, 13, 195, 161, 197, 161, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 9, 81, 5, 80, 80, 72, 11, 3, 95, 50, 6, 72, 84, 57, 6, 36, 0, 0, 12, 66, 29, 112, 81, 37, 81, 35, 84, 35, 47, 0, 0, 6, 195, 61, 51, 128, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 77, 52, 128, 17, 6, 195, 8, 84, 192, 17, 0, 0, 0, 14, 4, 95, 13, 3, 14, 65, 6, 35, 49, 51, 39, 50, 0, 0, 0, 0, 0, 6, 195, 76, 52, 201, 17, 0, 0, 0, 0, 7, 194, 16, 240, 72, 28, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 131, 196, 141, 18, 17, 0, 13, 66, 44, 32, 49, 37, 55, 39, 71, 35, 57, 47, 0, 0, 13, 3, 95, 51, 88, 47, 134, 6, 37, 117, 36, 47, 0, 0, 10, 3, 95, 48, 67, 89, 6, 36, 47, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 84, 129, 128, 17, 0, 10, 3, 95, 49, 67, 89, 47, 6, 39, 0, 0, 0, 0, 0, 0, 0, 5, 194, 40, 80, 72, 17, 3, 95, 49, 57, 72, 6, 36, 84, 35, 47, 36, 50, 124, 117, 47, 0, 0, 15, 3, 95, 49, 56, 6, 39, 89, 40, 65, 50, 124, 117, 47, 0, 0, 15, 3, 95, 50, 67, 72, 84, 57, 6, 36, 89, 80, 6, 36, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 49, 49, 57, 6, 36, 72, 36, 50, 124, 117, 47, 0, 0, 6, 195, 65, 35, 64, 17, 12, 3, 95, 49, 48, 72, 6, 36, 89, 36, 47, 0, 0, 14, 3, 95, 51, 67, 47, 134, 6, 37, 89, 47, 6, 35, 0, 14, 3, 95, 49, 51, 47, 134, 6, 37, 50, 124, 117, 47, 0, 0, 14, 3, 95, 49, 50, 72, 84, 6, 35, 50, 124, 117, 47, 0, 0, 14, 3, 95, 49, 53, 48, 6, 35, 47, 50, 124, 117, 47, 0, 0, 6, 195, 81, 35, 64, 17, 14, 3, 95, 49, 52, 76, 47, 6, 44, 50, 124, 117, 47, 0, 0, 16, 3, 95, 49, 55, 89, 6, 36, 72, 40, 65, 50, 124, 117, 47, 0, 0, 15, 3, 95, 49, 54, 91, 6, 36, 89, 47, 50, 124, 117, 47, 0, 0, 0, 17, 3, 95, 55, 88, 89, 6, 36, 72, 40, 65, 72, 36, 89, 124, 47, 0, 0, 15, 3, 95, 52, 67, 76, 47, 37, 133, 37, 89, 47, 6, 35, 0, 0, 0, 0, 0, 0, 0, 9, 66, 33, 160, 107, 36, 51, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 67, 52, 134, 128, 65, 36, 81, 35, 107, 36, 51, 117, 0, 0, 7, 196, 9, 148, 212, 20, 72, 7, 196, 64, 241, 12, 20, 8, 0, 0, 0, 9, 132, 16, 197, 153, 9, 72, 8, 23, 0, 0, 0, 0, 13, 3, 95, 50, 88, 72, 84, 6, 35, 117, 36, 47, 0, 0, 15, 5, 95, 48, 77, 65, 49, 80, 6, 37, 89, 121, 117, 36, 0, 0, 0, 17, 5, 95, 48, 77, 65, 51, 65, 6, 37, 55, 37, 35, 51, 72, 37, 0, 0, 16, 5, 95, 48, 77, 65, 50, 65, 6, 37, 55, 37, 125, 50, 37, 0, 0, 0, 16, 5, 95, 48, 77, 65, 52, 71, 6, 37, 55, 37, 125, 50, 37, 0, 0, 13, 66, 28, 224, 81, 37, 81, 35, 67, 40, 47, 50, 0, 0, 6, 195, 88, 112, 64, 17, 0, 11, 68, 48, 22, 133, 72, 55, 131, 88, 44, 0, 0, 0, 0, 0, 6, 195, 52, 147, 79, 8, 12, 3, 95, 63, 63, 89, 37, 65, 71, 39, 55, 0, 0, 0, 0, 15, 3, 95, 52, 88, 76, 47, 6, 37, 133, 37, 117, 36, 47, 0, 0, 0, 0, 0, 0, 0, 8, 195, 56, 17, 0, 72, 8, 23, 0, 7, 194, 56, 16, 72, 28, 23, 0, 6, 195, 64, 50, 64, 17, 14, 3, 95, 53, 88, 48, 6, 35, 72, 36, 89, 124, 47, 0, 0, 0, 0, 0, 0, 0, 6, 195, 77, 52, 210, 17, 0, 12, 66, 45, 112, 49, 37, 55, 39, 84, 35, 47, 0, 0, 14, 3, 95, 54, 88, 91, 6, 36, 72, 36, 89, 124, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 60, 68, 192, 17, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 56, 88, 6, 39, 89, 40, 65, 72, 36, 89, 124, 47, 0, 0, 0, 0, 6, 195, 77, 69, 129, 17, 0, 6, 195, 17, 37, 128, 17, 0, 0, 0, 0, 16, 3, 95, 57, 88, 72, 6, 36, 84, 35, 72, 36, 89, 124, 47, 0, 0, 0, 0, 0, 0, 0, 0, 6, 131, 13, 195, 161, 76, 10, 3, 95, 63, 65, 88, 50, 35, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 15, 7, 15, 6, 39, 81, 39, 50, 36, 49, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 13, 195, 161, 13, 5, 76, 0, 0, 0, 0, 0, 9, 134, 3, 8, 3, 5, 197, 161, 76, 0, 0, 0, 0, 0, 0, 8, 197, 9, 144, 200, 60, 208, 72, 0, 0, 8, 195, 65, 35, 192, 72, 8, 23, 0, 15, 4, 95, 48, 77, 52, 71, 6, 37, 55, 37, 125, 50, 126, 0, 0, 0, 15, 4, 95, 48, 77, 50, 65, 6, 37, 55, 37, 125, 50, 126, 0, 0, 15, 4, 95, 48, 77, 51, 65, 6, 37, 55, 37, 35, 51, 72, 0, 0, 0, 13, 4, 95, 48, 77, 49, 80, 6, 37, 89, 121, 117, 0, 0, 7, 194, 60, 64, 72, 28, 23, 15, 4, 95, 2, 18, 22, 6, 39, 71, 55, 129, 76, 36, 49, 0, 0, 0, 0, 12, 69, 56, 85, 212, 60, 224, 67, 126, 47, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 66, 44, 208, 49, 37, 55, 39, 65, 36, 47, 44, 0, 5, 194, 52, 144, 72, 0, 0, 0, 13, 69, 16, 83, 5, 80, 80, 72, 37, 55, 121, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 66, 44, 224, 49, 37, 55, 39, 67, 40, 47, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 195, 16, 193, 64, 72, 8, 23, 0, 0, 0, 0, 0, 7, 196, 60, 179, 204, 60, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 36, 35, 64, 17, 0, 0, 0, 15, 4, 95, 3, 9, 18, 89, 47, 133, 6, 121, 91, 49, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 196, 76, 180, 154, 20, 72, 8, 0, 0, 0, 19, 4, 95, 19, 20, 11, 91, 6, 37, 49, 65, 124, 76, 6, 124, 51, 49, 35, 0, 0, 0, 13, 4, 95, 1, 3, 21, 76, 6, 124, 51, 49, 35, 0, 0, 0, 0, 0, 0, 5, 194, 72, 48, 17, 0, 0, 0, 0, 0, 14, 4, 95, 18, 14, 7, 49, 51, 6, 129, 90, 36, 49, 0, 0, 0, 0, 5, 194, 73, 48, 17, 0, 19, 67, 33, 69, 16, 107, 124, 47, 36, 47, 36, 48, 123, 0, 81, 58, 47, 47, 32, 0, 0, 0, 7, 132, 196, 141, 1, 22, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 17, 64, 64, 17, 0, 0, 0, 5, 194, 77, 32, 17, 0, 0, 7, 195, 56, 17, 5, 72, 8, 0, 0, 18, 4, 95, 1, 3, 50, 72, 84, 57, 6, 36, 76, 6, 124, 51, 49, 37, 0, 0, 0, 0, 0, 0, 6, 195, 60, 177, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 64, 68, 128, 17, 0, 0, 0, 0, 6, 195, 64, 196, 128, 17, 0, 0, 9, 2, 195, 151, 49, 51, 124, 47, 0, 7, 2, 196, 143, 79, 123, 0, 0, 0, 7, 2, 196, 141, 76, 123, 0, 0, 0, 0, 0, 0, 0, 13, 2, 194, 167, 48, 35, 51, 35, 81, 51, 35, 83, 0, 0, 5, 194, 60, 208, 17, 5, 194, 76, 80, 72, 0, 0, 0, 0, 10, 3, 5, 46, 7, 50, 35, 48, 133, 0, 7, 2, 197, 136, 36, 67, 0, 0, 0, 0, 0, 0, 0, 0, 8, 2, 196, 155, 37, 57, 36, 0, 0, 0, 14, 2, 194, 169, 49, 6, 39, 48, 37, 51, 35, 57, 47, 0, 13, 2, 195, 161, 72, 55, 6, 129, 107, 123, 4, 124, 0, 0, 7, 132, 2, 195, 189, 20, 72, 0, 0, 0, 13, 2, 195, 173, 72, 55, 6, 129, 107, 123, 4, 121, 0, 0, 0, 5, 130, 195, 171, 43, 0, 8, 133, 13, 195, 161, 20, 5, 76, 11, 2, 194, 176, 89, 47, 40, 48, 36, 67, 0, 0, 6, 195, 12, 112, 64, 17, 7, 2, 197, 153, 36, 133, 0, 13, 2, 195, 169, 72, 55, 6, 129, 107, 123, 4, 123, 0, 0, 5, 130, 195, 182, 43, 0, 12, 69, 76, 80, 82, 12, 128, 89, 36, 51, 76, 0, 11, 2, 195, 183, 79, 36, 55, 36, 50, 39, 0, 0, 5, 194, 73, 128, 17, 7, 2, 195, 180, 40, 125, 0, 0, 7, 2, 197, 165, 80, 123, 0, 0, 14, 4, 95, 3, 5, 4, 117, 6, 36, 79, 37, 55, 35, 0, 0, 13, 2, 195, 179, 72, 55, 6, 129, 107, 123, 4, 125, 0, 0, 0, 17, 4, 95, 12, 9, 7, 55, 6, 37, 81, 35, 47, 4, 40, 51, 35, 0, 7, 2, 197, 161, 36, 91, 0, 0, 0, 17, 2, 197, 175, 6, 126, 89, 10, 49, 51, 6, 129, 90, 49, 36, 65, 0, 0, 5, 130, 195, 188, 43, 0, 6, 195, 5, 34, 128, 17, 18, 2, 195, 189, 72, 55, 6, 129, 123, 4, 37, 48, 89, 37, 55, 39, 50, 0, 0, 13, 2, 195, 186, 72, 55, 6, 129, 107, 123, 4, 126, 0, 0, 0, 0, 0, 7, 2, 196, 190, 36, 61, 0, 0, 0, 0, 0, 14, 2, 196, 186, 72, 55, 6, 129, 107, 123, 4, 36, 55, 0, 0, 0, 6, 195, 92, 116, 15, 17, 0, 0, 6, 195, 9, 147, 1, 72, 8, 2, 197, 190, 90, 36, 47, 0, 0, 0, 6, 195, 9, 147, 15, 72, 0, 0, 0, 0, 0, 0, 6, 195, 9, 147, 9, 72, 0, 0, 0, 0, 7, 196, 9, 81, 15, 84, 72, 6, 131, 1, 196, 141, 8, 0, 0, 0, 0, 0, 0, 7, 194, 64, 240, 72, 8, 23, 5, 194, 76, 144, 72, 0, 8, 195, 64, 241, 0, 72, 8, 23, 0, 0, 0, 0, 0, 6, 195, 9, 147, 25, 72, 0, 0, 0, 6, 2, 95, 1, 124, 0, 0, 0, 0, 0, 0, 7, 2, 95, 11, 49, 124, 0, 0, 0, 6, 2, 95, 9, 121, 0, 0, 0, 6, 195, 5, 32, 192, 17, 6, 2, 95, 15, 125, 0, 0, 0, 0, 0, 6, 195, 85, 48, 64, 17, 7, 2, 95, 19, 36, 89, 0, 0, 0, 0, 0, 0, 7, 2, 95, 22, 84, 123, 0, 0, 6, 2, 95, 21, 126, 0, 0, 0, 0, 8, 2, 95, 26, 88, 36, 47, 0, 0, 0, 7, 131, 197, 190, 5, 72, 8, 5, 194, 80, 144, 72, 0, 0, 0, 0, 0, 0, 13, 2, 95, 34, 40, 84, 39, 88, 39, 84, 49, 37, 0, 0, 0, 0, 13, 2, 95, 39, 35, 48, 39, 89, 47, 51, 39, 83, 0, 0, 0, 0, 10, 2, 95, 36, 72, 39, 55, 124, 51, 0, 0, 0, 12, 4, 95, 3, 1, 16, 84, 36, 55, 49, 123, 0, 0, 18, 2, 95, 41, 88, 124, 84, 39, 34, 49, 35, 88, 35, 84, 133, 121, 47, 0, 0, 12, 2, 95, 40, 88, 124, 84, 39, 51, 49, 35, 0, 0, 6, 195, 52, 180, 128, 17, 0, 10, 2, 95, 46, 47, 36, 76, 49, 35, 0, 0, 10, 2, 95, 45, 65, 121, 50, 40, 89, 0, 0, 10, 2, 95, 44, 76, 124, 51, 49, 35, 0, 0, 8, 2, 95, 51, 47, 134, 37, 0, 0, 9, 2, 95, 50, 72, 84, 6, 35, 0, 0, 11, 2, 95, 49, 57, 6, 36, 72, 36, 50, 0, 0, 10, 2, 95, 48, 50, 6, 40, 55, 35, 0, 0, 6, 195, 84, 181, 128, 17, 11, 2, 95, 55, 89, 6, 36, 72, 40, 65, 0, 0, 10, 2, 95, 54, 91, 6, 36, 89, 47, 0, 0, 10, 2, 95, 53, 48, 6, 57, 36, 47, 0, 0, 11, 2, 95, 52, 76, 47, 6, 37, 133, 37, 0, 0, 13, 2, 95, 59, 88, 72, 133, 36, 72, 67, 121, 49, 0, 0, 15, 2, 95, 58, 72, 84, 6, 39, 57, 47, 36, 76, 49, 35, 0, 0, 12, 2, 95, 57, 72, 6, 36, 84, 57, 36, 47, 0, 0, 10, 2, 95, 56, 6, 39, 89, 40, 65, 0, 0, 12, 2, 95, 63, 39, 47, 35, 88, 67, 121, 49, 0, 0, 10, 2, 95, 62, 84, 57, 36, 76, 121, 0, 0, 8, 197, 12, 128, 197, 52, 80, 76, 0, 10, 2, 95, 60, 65, 36, 50, 91, 121, 0, 0, 0, 8, 133, 13, 1, 10, 195, 173, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 20, 177, 192, 17, 0, 13, 4, 95, 4, 15, 20, 47, 6, 36, 76, 49, 35, 0, 0, 0, 0, 6, 195, 4, 193, 64, 8, 22, 2, 95, 91, 107, 51, 6, 35, 50, 35, 47, 124, 15, 88, 6, 124, 84, 39, 51, 49, 35, 0, 0, 0, 0, 7, 194, 104, 16, 72, 8, 23, 0, 14, 2, 95, 95, 48, 39, 47, 47, 44, 90, 36, 67, 121, 0, 0, 0, 21, 2, 95, 93, 107, 51, 6, 35, 50, 35, 47, 124, 15, 88, 6, 35, 84, 133, 121, 47, 0, 0, 0, 0, 0, 0, 22, 2, 95, 96, 6, 39, 71, 51, 124, 117, 4, 36, 50, 124, 15, 76, 6, 124, 51, 49, 35, 0, 0, 9, 134, 13, 195, 173, 19, 20, 15, 8, 0, 0, 8, 133, 196, 141, 22, 21, 20, 17, 0, 0, 0, 0, 0, 21, 4, 95, 7, 18, 22, 80, 6, 36, 91, 49, 121, 38, 6, 35, 49, 117, 36, 50, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 2, 95, 123, 89, 55, 6, 39, 90, 36, 50, 124, 15, 88, 6, 124, 84, 39, 51, 49, 35, 0, 13, 4, 95, 4, 9, 1, 47, 51, 6, 36, 65, 35, 0, 0, 0, 0, 8, 133, 22, 197, 161, 1, 11, 8, 0, 0, 10, 68, 64, 245, 197, 72, 48, 127, 44, 0, 0, 21, 2, 95, 125, 89, 55, 6, 39, 90, 36, 50, 124, 15, 88, 6, 35, 84, 133, 121, 47, 0, 0, 18, 2, 95, 124, 89, 84, 6, 37, 89, 55, 124, 15, 76, 6, 124, 51, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 132, 196, 141, 12, 1, 17, 0, 0, 0, 0, 12, 67, 21, 48, 192, 37, 89, 49, 36, 37, 48, 0, 0, 0, 0, 7, 195, 64, 241, 5, 72, 8, 0, 0, 0, 0, 14, 4, 95, 35, 51, 50, 65, 6, 36, 88, 36, 51, 35, 0, 0, 6, 195, 9, 144, 200, 72, 0, 0, 0, 7, 132, 196, 141, 12, 18, 17, 7, 194, 104, 80, 72, 28, 23, 0, 0, 0, 0, 0, 0, 0, 0, 14, 70, 61, 85, 12, 60, 242, 192, 127, 47, 55, 126, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 52, 196, 128, 17, 0, 0, 0, 0, 6, 195, 9, 148, 192, 72, 0, 0, 0, 0, 12, 67, 93, 117, 192, 84, 123, 84, 123, 84, 123, 0, 6, 195, 60, 133, 128, 17, 0, 0, 0, 0, 0, 19, 67, 12, 20, 19, 49, 35, 48, 89, 55, 39, 49, 0, 81, 108, 111, 99, 107, 32, 0, 0, 0, 14, 67, 28, 134, 128, 81, 37, 81, 35, 107, 36, 34, 117, 0, 0, 0, 12, 67, 64, 113, 14, 48, 131, 75, 72, 127, 50, 0, 0, 0, 14, 67, 44, 134, 128, 49, 37, 55, 39, 107, 36, 34, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 12, 128, 197, 76, 0, 6, 195, 60, 128, 192, 17, 7, 132, 13, 195, 161, 13, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 196, 141, 19, 1, 4, 17, 0, 6, 195, 12, 128, 201, 76, 0, 6, 195, 21, 65, 128, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 67, 32, 243, 69, 107, 129, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 196, 141, 19, 6, 18, 17, 0, 0, 0, 0, 0, 0, 14, 69, 36, 228, 197, 73, 64, 37, 50, 88, 36, 51, 47, 0, 0, 6, 195, 41, 53, 5, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 100, 105, 0, 4, 1, 97, 2, 107, 3, 72, 37, 0, 1, 97, 108, 2, 115, 0, 1, 97, 114, 116, 2, 99, 0, 1, 101, 109, 0, 1, 101, 112, 111, 116, 2, 99, 0, 1, 101, 114, 107, 2, 116, 0, 1, 105, 109, 0, 1, 108, 97, 114, 0, 1, 110, 2, 99, 0, 1, 110, 97, 2, 100, 0, 1, 110, 97, 109, 2, 116, 0, 1, 110, 105, 0, 1, 111, 2, 99, 0, 1, 111, 105, 114, 2, 99, 0, 1, 111, 107, 2, 102, 105, 0, 1, 111, 116, 101, 0, 1, 114, 97, 100, 2, 122, 0, 1, 114, 111, 0, 1, 155, 196, 109, 0, 1, 169, 195, 109, 0, 2, 97, 0, 2, 97, 32, 0, 2, 101, 0, 2, 103, 105, 0, 2, 106, 0, 2, 107, 0, 2, 110, 105, 107, 0, 2, 111, 0, 2, 114, 0, 2, 115, 99, 105, 112, 0, 2, 115, 107, 0, 2, 115, 109, 0, 2, 115, 112, 0, 2, 115, 116, 0, 2, 115, 116, 0, 2, 116, 105, 107, 0, 2, 117, 0, 2, 117, 109, 32, 0, 8, 2, 99, 104, 0, 8, 2, 102, 0, 8, 2, 103, 0, 8, 2, 108, 101, 116, 0, 8, 2, 109, 101, 0, 8, 2, 109, 105, 0, 8, 2, 112, 0, 8, 2, 115, 0, 8, 2, 118, 97, 110, 0, 8, 2, 118, 101, 114, 0, 8, 2, 118, 105, 100, 0, 8, 2, 122, 0, 8, 2, 195, 161, 0, 8, 97, 108, 103, 0, 8, 97, 114, 116, 0, 8, 101, 0, 8, 101, 110, 2, 112, 0, 8, 101, 112, 120, 101, 0, 8, 108, 111, 112, 0, 8, 110, 97, 99, 115, 0, 8, 111, 2, 110, 115, 116, 0, 8, 111, 109, 0, 8, 114, 97, 107, 0, 8, 114, 97, 115, 0, 8, 117, 97, 0, 99, 107, 8, 3, 72, 37, 49, 0, 4, 2, 101, 32, 3, 72, 37, 57, 0, 2, 101, 32, 0, 2, 105, 32, 0, 2, 111, 32, 0, 2, 117, 32, 0, 8, 2, 97, 0, 115, 116, 105, 2, 99, 3, 72, 37, 89, 47, 37, 0, 115, 107, 114, 101, 100, 105, 3, 72, 37, 89, 49, 14, 16, 36, 72, 37, 0, 115, 99, 111, 8, 3, 72, 37, 89, 49, 39, 0, 4, 1, 101, 153, 197, 2, 115, 107, 3, 79, 37, 0, 1, 111, 104, 99, 2, 115, 0, 8, 2, 114, 99, 0, 8, 2, 114, 107, 0, 8, 2, 118, 105, 122, 110, 97, 0, 8, 2, 118, 105, 122, 110, 121, 0, 8, 101, 108, 104, 0, 7, 6, 110, 105, 0, 4, 1, 97, 2, 100, 3, 50, 37, 0, 1, 97, 2, 107, 0, 1, 97, 2, 107, 111, 118, 0, 1, 97, 2, 122, 0, 1, 97, 103, 114, 111, 110, 97, 0, 1, 97, 104, 99, 2, 99, 0, 1, 97, 104, 99, 2, 107, 0, 1, 97, 104, 99, 101, 2, 115, 0, 1, 97, 109, 2, 102, 0, 1, 97, 109, 2, 112, 0, 1, 97, 109, 114, 101, 0, 1, 97, 110, 2, 115, 0, 1, 101, 2, 107, 0, 1, 101, 2, 115, 0, 1, 101, 103, 0, 1, 101, 108, 97, 2, 116, 0, 1, 101, 108, 101, 2, 116, 0, 1, 101, 122, 2, 116, 0, 1, 103, 2, 116, 0, 1, 105, 2, 99, 105, 0, 1, 105, 2, 107, 0, 1, 105, 2, 116, 0, 1, 105, 102, 101, 0, 1, 105, 108, 107, 0, 1, 105, 109, 0, 1, 107, 2, 112, 0, 1, 111, 2, 100, 0, 1, 111, 2, 107, 0, 1, 111, 2, 115, 0, 1, 111, 100, 2, 99, 0, 1, 111, 102, 2, 99, 0, 1, 111, 103, 0, 1, 111, 103, 97, 116, 2, 115, 0, 1, 111, 109, 101, 114, 101, 0, 1, 111, 109, 114, 97, 104, 0, 1, 111, 110, 2, 109, 0, 1, 111, 114, 2, 99, 0, 1, 111, 114, 100, 110, 101, 0, 1, 111, 114, 104, 99, 110, 121, 115, 0, 1, 111, 114, 105, 0, 1, 111, 116, 107, 0, 1, 117, 2, 116, 0, 1, 117, 109, 2, 107, 0, 1, 117, 109, 2, 115, 0, 1, 117, 109, 111, 107, 0, 1, 117, 116, 2, 115, 0, 1, 169, 195, 103, 0, 2, 97, 32, 0, 2, 97, 107, 0, 2, 107, 108, 0, 2, 110, 105, 107, 0, 2, 115, 109, 0, 2, 115, 116, 0, 2, 116, 105, 107, 0, 2, 117, 109, 32, 0, 2, 122, 117, 106, 0, 8, 2, 108, 0, 8, 2, 116, 114, 111, 0, 8, 97, 2, 109, 0, 8, 97, 103, 114, 111, 0, 8, 97, 107, 2, 98, 0, 8, 97, 109, 117, 104, 0, 8, 97, 110, 2, 116, 114, 0, 8, 97, 112, 2, 99, 107, 0, 8, 97, 115, 2, 116, 0, 8, 97, 116, 111, 98, 0, 8, 97, 118, 108, 97, 103, 0, 8, 101, 105, 103, 121, 104, 0, 8, 101, 115, 2, 108, 0, 8, 101, 116, 2, 115, 0, 8, 111, 98, 101, 0, 8, 111, 108, 111, 107, 0, 8, 111, 109, 0, 8, 116, 101, 2, 99, 0, 8, 117, 0, 8, 117, 109, 0, 8, 117, 109, 105, 2, 116, 0, 8, 121, 99, 0, 8, 169, 195, 114, 116, 0, 116, 105, 1, 105, 102, 3, 50, 37, 47, 37, 0, 107, 111, 116, 105, 8, 3, 50, 37, 49, 39, 47, 37, 0, 4, 2, 101, 32, 3, 50, 37, 57, 0, 2, 105, 32, 0, 2, 111, 32, 0, 2, 117, 32, 0, 2, 195, 173, 0, 4, 1, 97, 122, 2, 107, 3, 67, 37, 0, 1, 100, 111, 112, 2, 107, 0, 1, 100, 117, 111, 108, 0, 1, 105, 118, 2, 116, 0, 1, 105, 141, 196, 2, 116, 0, 1, 106, 111, 116, 115, 0, 1, 111, 114, 112, 2, 107, 0, 1, 117, 2, 107, 0, 1, 118, 2, 107, 108, 0, 1, 122, 118, 2, 107, 0, 1, 153, 197, 111, 109, 161, 195, 110, 0, 8, 2, 116, 114, 111, 32, 0, 8, 97, 104, 99, 173, 195, 109, 0, 8, 105, 108, 104, 2, 116, 0, 8, 111, 114, 98, 0, 7, 6, 116, 105, 0, 4, 109, 101, 2, 32, 3, 47, 35, 57, 65, 0, 109, 101, 8, 0, 4, 1, 97, 2, 99, 3, 47, 37, 0, 1, 97, 2, 107, 0, 1, 97, 2, 110, 0, 1, 97, 2, 118, 0, 1, 97, 2, 122, 0, 1, 97, 109, 2, 99, 107, 0, 1, 97, 109, 2, 107, 97, 0, 1, 97, 109, 97, 2, 99, 0, 1, 97, 109, 97, 2, 107, 0, 1, 97, 109, 97, 114, 100, 0, 1, 97, 109, 101, 2, 99, 0, 1, 97, 109, 101, 2, 107, 0, 1, 97, 109, 111, 114, 97, 0, 1, 97, 109, 111, 116, 2, 99, 0, 1, 97, 109, 117, 2, 99, 0, 1, 97, 112, 97, 2, 99, 0, 1, 97, 112, 97, 2, 196, 141, 0, 1, 97, 112, 109, 111, 2, 98, 0, 1, 97, 112, 109, 121, 0, 1, 101, 2, 99, 0, 1, 101, 2, 107, 0, 1, 101, 2, 118, 0, 1, 101, 2, 122, 0, 1, 101, 107, 114, 97, 2, 110, 103, 0, 1, 101, 110, 2, 99, 0, 1, 101, 114, 111, 101, 2, 99, 0, 1, 105, 2, 107, 0, 1, 105, 103, 2, 109, 0, 1, 105, 108, 2, 99, 0, 1, 105, 109, 105, 114, 2, 118, 0, 1, 105, 110, 97, 118, 2, 116, 0, 1, 105, 114, 2, 99, 0, 1, 105, 114, 2, 107, 0, 1, 105, 114, 107, 0, 1, 105, 118, 114, 0, 1, 107, 2, 118, 0, 1, 107, 97, 0, 1, 107, 101, 0, 1, 107, 114, 0, 1, 108, 117, 107, 2, 118, 0, 1, 110, 2, 99, 0, 1, 110, 2, 110, 0, 1, 110, 97, 2, 107, 0, 1, 110, 97, 2, 108, 0, 1, 110, 97, 2, 115, 0, 1, 110, 101, 2, 110, 0, 1, 110, 101, 118, 2, 108, 0, 1, 110, 105, 2, 109, 0, 1, 110, 111, 107, 0, 1, 111, 2, 107, 0, 1, 111, 98, 2, 122, 0, 1, 111, 109, 2, 118, 0, 1, 111, 114, 2, 107, 0, 1, 111, 114, 101, 2, 99, 0, 1, 111, 120, 2, 107, 0, 1, 112, 101, 2, 107, 0, 1, 112, 111, 0, 1, 114, 2, 122, 0, 1, 114, 111, 2, 109, 0, 1, 115, 2, 107, 0, 1, 115, 2, 109, 117, 108, 0, 1, 115, 2, 112, 0, 1, 115, 101, 100, 2, 108, 0, 1, 115, 101, 103, 117, 115, 0, 1, 115, 101, 118, 110, 0, 1, 115, 111, 2, 99, 0, 1, 117, 2, 107, 0, 1, 117, 97, 0, 1, 120, 2, 108, 0, 1, 189, 195, 2, 99, 107, 0, 2, 97, 32, 0, 2, 99, 107, 0, 2, 102, 0, 2, 110, 105, 107, 0, 2, 115, 109, 0, 2, 115, 116, 0, 2, 116, 105, 107, 0, 2, 116, 117, 108, 0, 2, 117, 109, 32, 0, 8, 2, 98, 0, 8, 2, 99, 105, 0, 8, 2, 109, 98, 0, 8, 2, 110, 107, 0, 8, 2, 114, 97, 110, 0, 8, 2, 116, 97, 110, 0, 8, 2, 116, 117, 108, 0, 8, 2, 116, 195, 161, 110, 0, 8, 2, 120, 0, 8, 97, 108, 112, 2, 110, 0, 8, 97, 109, 103, 101, 108, 102, 0, 8, 97, 109, 169, 195, 116, 0, 8, 97, 115, 2, 114, 0, 8, 97, 115, 2, 197, 153, 0, 8, 101, 109, 115, 111, 107, 0, 8, 101, 112, 2, 196, 141, 0, 8, 105, 115, 111, 112, 0, 8, 108, 117, 2, 109, 0, 8, 108, 117, 109, 0, 8, 110, 97, 0, 8, 110, 97, 108, 116, 97, 0, 8, 110, 101, 99, 0, 8, 110, 101, 115, 0, 8, 110, 101, 118, 101, 114, 112, 0, 8, 110, 111, 107, 2, 110, 0, 8, 111, 108, 102, 0, 8, 112, 105, 108, 107, 101, 0, 8, 112, 111, 2, 99, 0, 8, 114, 101, 118, 2, 107, 0, 8, 115, 98, 97, 0, 8, 115, 101, 98, 0, 8, 115, 101, 108, 97, 112, 0, 8, 115, 101, 114, 2, 116, 0, 8, 115, 110, 105, 0, 8, 115, 110, 111, 107, 0, 8, 115, 117, 106, 0, 8, 117, 114, 0, 110, 105, 2, 117, 3, 47, 37, 50, 37, 57, 0, 4, 2, 101, 32, 3, 47, 37, 57, 0, 2, 105, 32, 0, 2, 111, 32, 0, 2, 117, 32, 0, 109, 111, 110, 105, 2, 116, 3, 47, 37, 65, 39, 50, 37, 0, 4, 115, 116, 105, 1, 97, 3, 47, 37, 89, 47, 37, 0, 115, 116, 105, 8, 97, 116, 115, 0, 4, 1, 97, 104, 99, 2, 99, 3, 80, 37, 0, 1, 97, 108, 2, 110, 0, 1, 97, 109, 2, 99, 0, 1, 99, 0, 1, 101, 99, 105, 153, 197, 0, 1, 101, 108, 112, 0, 1, 101, 153, 197, 2, 99, 0, 1, 104, 99, 101, 108, 0, 1, 111, 114, 2, 118, 0, 1, 112, 97, 2, 118, 0, 1, 114, 100, 0, 1, 115, 101, 161, 197, 0, 1, 115, 109, 0, 1, 115, 111, 100, 0, 1, 115, 111, 104, 0, 1, 115, 111, 107, 2, 99, 0, 1, 115, 161, 195, 2, 99, 0, 1, 155, 196, 2, 99, 0, 1, 155, 196, 112, 0, 1, 155, 196, 118, 2, 118, 0, 1, 161, 195, 115, 101, 100, 0, 1, 173, 195, 118, 101, 0, 8, 97, 109, 2, 110, 0, 8, 101, 99, 97, 118, 100, 0, 8, 101, 115, 101, 100, 0, 8, 111, 114, 112, 0, 8, 115, 97, 114, 116, 115, 0, 8, 121, 107, 2, 99, 0, 8, 155, 196, 116, 0, 7, 6, 195, 161, 0, 3, 124, 0, 7, 6, 195, 164, 0, 3, 36, 0, 7, 6, 195, 169, 0, 3, 123, 0, 7, 6, 195, 173, 0, 3, 121, 0, 7, 6, 195, 179, 0, 3, 125, 0, 7, 6, 195, 180, 0, 3, 40, 39, 0, 7, 6, 195, 186, 0, 3, 126, 0, 7, 6, 195, 189, 0, 3, 121, 0, 7, 6, 196, 141, 0, 3, 76, 0, 7, 6, 196, 143, 0, 4, 3, 79, 0, 2, 32, 17, 70, 0, 2, 32, 3, 80, 0, 7, 6, 196, 155, 0, 3, 36, 0, 7, 6, 196, 190, 0, 3, 61, 0, 7, 6, 197, 136, 0, 3, 67, 0, 7, 6, 197, 153, 0, 3, 133, 0, 4, 1, 102, 3, 134, 0, 1, 107, 0, 1, 112, 0, 1, 116, 0, 7, 6, 197, 161, 0, 3, 91, 0, 7, 6, 197, 165, 0, 3, 80, 0, 7, 6, 197, 175, 0, 3, 126, 0, 7, 6, 197, 190, 0, 4, 3, 90, 0, 2, 32, 17, 70, 0, 2, 32, 3, 91, 0, 7, 6, 97, 0, 3, 35, 0, 99, 107, 1, 114, 116, 3, 36, 49, 0, 117, 3, 127, 0, 105, 1, 109, 2, 108, 3, 131, 0, 103, 101, 1, 112, 3, 131, 75, 0, 115, 116, 101, 1, 112, 2, 32, 3, 131, 89, 47, 0, 7, 6, 98, 0, 2, 32, 3, 48, 0, 4, 3, 71, 0, 2, 32, 17, 70, 0, 97, 99, 107, 3, 71, 36, 49, 0, 196, 155, 3, 71, 57, 36, 0, 111, 97, 114, 100, 3, 71, 125, 34, 72, 0, 97, 115, 105, 99, 3, 71, 131, 88, 37, 49, 0, 7, 6, 99, 0, 4, 1, 101, 114, 2, 111, 3, 49, 0, 1, 115, 97, 112, 2, 97, 108, 0, 2, 117, 115, 0, 8, 2, 97, 108, 0, 8, 2, 108, 97, 117, 0, 8, 2, 111, 109, 0, 8, 2, 111, 114, 0, 8, 97, 109, 2, 114, 0, 8, 115, 2, 111, 0, 107, 1, 97, 112, 0, 107, 1, 111, 108, 0, 107, 8, 97, 112, 2, 97, 0, 114, 101, 97, 116, 105, 8, 3, 49, 34, 36, 35, 47, 37, 0, 111, 118, 101, 114, 3, 49, 35, 84, 44, 0, 97, 8, 115, 2, 110, 3, 49, 36, 0, 116, 114, 108, 3, 49, 39, 50, 47, 14, 16, 39, 55, 0, 111, 103, 110, 105, 1, 101, 114, 2, 116, 3, 49, 39, 81, 50, 37, 0, 104, 3, 101, 0, 3, 117, 0, 7, 6, 100, 0, 2, 32, 3, 47, 0, 4, 3, 72, 0, 2, 32, 17, 70, 0, 2, 105, 28, 17, 0, 2, 195, 173, 28, 17, 0, 4, 197, 190, 3, 75, 0, 197, 190, 2, 32, 17, 70, 0, 197, 190, 2, 32, 3, 76, 0, 4, 2, 105, 3, 79, 0, 2, 195, 173, 0, 2, 196, 155, 0, 122, 2, 32, 3, 117, 0, 4, 122, 3, 118, 0, 122, 2, 32, 17, 70, 0, 7, 6, 101, 0, 3, 36, 0, 121, 1, 107, 3, 121, 0, 117, 3, 128, 0, 106, 2, 25, 3, 131, 0, 7, 6, 102, 0, 3, 83, 0, 196, 155, 3, 83, 57, 36, 0, 7, 6, 103, 0, 2, 32, 3, 49, 0, 4, 3, 81, 0, 2, 32, 17, 70, 0, 7, 6, 104, 0, 2, 32, 3, 101, 0, 4, 3, 107, 0, 2, 32, 17, 70, 0, 7, 6, 105, 0, 97, 3, 2, 37, 35, 0, 101, 3, 2, 37, 36, 0, 117, 3, 2, 37, 40, 0, 103, 104, 116, 1, 17, 67, 3, 35, 57, 47, 0, 3, 37, 0, 97, 2, 32, 3, 37, 35, 0, 101, 2, 32, 3, 37, 57, 36, 0, 105, 2, 32, 3, 37, 57, 37, 0, 111, 2, 32, 3, 37, 57, 39, 0, 117, 2, 32, 3, 37, 57, 40, 0, 8, 2, 111, 110, 3, 57, 0, 7, 6, 106, 0, 3, 57, 0, 7, 6, 107, 0, 4, 3, 49, 0, 107, 0, 7, 6, 108, 0, 1, 25, 2, 25, 3, 45, 0, 4, 3, 55, 0, 108, 0, 97, 115, 101, 114, 8, 3, 55, 131, 88, 34, 0, 7, 6, 109, 0, 3, 65, 0, 105, 99, 8, 2, 114, 111, 3, 65, 35, 57, 49, 0, 97, 110, 97, 103, 101, 114, 8, 3, 65, 36, 50, 36, 75, 44, 0, 101, 115, 115, 97, 103, 101, 8, 3, 65, 36, 89, 37, 75, 0, 196, 155, 3, 65, 67, 36, 0, 7, 6, 110, 0, 2, 110, 3, 0, 4, 3, 50, 0, 2, 105, 28, 17, 0, 2, 195, 173, 28, 17, 0, 4, 2, 105, 3, 67, 0, 2, 195, 173, 0, 2, 196, 155, 0, 101, 119, 3, 67, 126, 0, 4, 2, 103, 3, 68, 0, 2, 107, 0, 7, 6, 111, 0, 3, 39, 0, 105, 99, 101, 1, 118, 3, 39, 57, 89, 0, 4, 111, 1, 116, 2, 108, 3, 126, 0, 117, 1, 114, 103, 2, 112, 0, 4, 117, 3, 129, 0, 119, 8, 100, 110, 105, 119, 0, 7, 6, 112, 0, 4, 3, 48, 0, 112, 2, 17, 65, 32, 0, 196, 155, 3, 48, 57, 36, 0, 7, 6, 113, 0, 4, 3, 49, 84, 0, 117, 0, 7, 6, 114, 0, 1, 25, 2, 25, 3, 44, 0, 4, 3, 51, 0, 114, 0, 105, 103, 104, 116, 3, 51, 35, 57, 47, 0, 7, 6, 115, 0, 4, 1, 101, 2, 105, 100, 3, 88, 0, 8, 101, 114, 112, 2, 105, 100, 0, 4, 3, 89, 0, 115, 2, 17, 65, 32, 0, 115, 2, 32, 0, 101, 108, 101, 99, 2, 116, 3, 89, 37, 55, 36, 49, 0, 112, 97, 99, 101, 3, 89, 48, 131, 89, 0, 99, 97, 112, 101, 3, 89, 49, 131, 48, 0, 104, 105, 102, 116, 3, 91, 37, 83, 47, 0, 7, 6, 116, 0, 4, 3, 47, 0, 2, 105, 28, 17, 0, 2, 195, 173, 28, 17, 0, 116, 2, 17, 65, 32, 0, 116, 2, 32, 0, 4, 2, 105, 3, 80, 0, 2, 195, 173, 0, 2, 196, 155, 0, 7, 6, 117, 0, 3, 40, 0, 7, 6, 118, 0, 3, 84, 0, 196, 155, 3, 84, 57, 36, 0, 7, 6, 119, 0, 3, 84, 0, 97, 118, 101, 3, 84, 131, 83, 0, 7, 6, 120, 0, 3, 49, 89, 0, 111, 116, 105, 1, 101, 2, 99, 3, 81, 88, 39, 47, 37, 0, 7, 6, 121, 0, 3, 37, 0, 2, 195, 173, 3, 37, 57, 0, 7, 6, 122, 0, 4, 3, 88, 0, 2, 32, 17, 70, 0, 2, 32, 3, 89, 0, 7, 6, 0, 4, 45, 1, 32, 17, 65, 2, 32, 15, 3, 10, 0, 45, 1, 32, 17, 67, 2, 32, 15, 0, 195, 171, 3, 36, 0, 195, 188, 3, 37, 0, 197, 149, 3, 44, 0, 196, 186, 3, 45, 0, 45, 8, 32, 2, 32, 15, 3, 65, 121, 50, 40, 89, 0, 36, 3, 72, 39, 55, 124, 51, 0, 195, 182, 3, 123, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts8 = FileInMemory_createWithData (7614, reinterpret_cast (&espeakdata_dicts8_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/cs_dict", U"cs"); Collection_addItem (me.peek(), espeakdata_dicts8.transfer()); static unsigned char espeakdata_dicts9_data[3463] = { 0, 4, 0, 0, 31, 9, 0, 0, 0, 0, 0, 6, 195, 32, 243, 128, 76, 0, 0, 7, 65, 4, 2, 35, 0, 8, 0, 7, 66, 100, 224, 13, 50, 0, 9, 66, 5, 0, 10, 2, 35, 48, 0, 0, 0, 0, 0, 0, 6, 195, 64, 240, 128, 72, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 28, 19, 128, 76, 0, 0, 6, 65, 20, 108, 0, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 36, 109, 0, 76, 0, 0, 0, 0, 8, 197, 28, 19, 12, 92, 224, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 28, 84, 207, 56, 76, 0, 0, 0, 6, 195, 17, 118, 64, 72, 0, 0, 15, 65, 60, 118, 107, 6, 115, 72, 0, 8, 81, 104, 121, 100, 32, 7, 65, 60, 10, 2, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 70, 13, 147, 82, 4, 81, 192, 49, 113, 65, 34, 6, 120, 81, 0, 0, 0, 0, 0, 9, 66, 5, 32, 10, 2, 35, 34, 0, 0, 0, 0, 14, 69, 8, 19, 135, 61, 32, 71, 35, 68, 81, 111, 34, 0, 0, 0, 0, 0, 0, 6, 194, 4, 48, 72, 8, 0, 8, 195, 13, 147, 128, 72, 8, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 33, 115, 128, 76, 0, 0, 12, 4, 95, 49, 77, 49, 65, 6, 114, 55, 10, 0, 0, 0, 6, 195, 100, 224, 64, 76, 8, 195, 93, 37, 8, 72, 8, 11, 0, 0, 5, 65, 100, 13, 0, 0, 0, 0, 0, 0, 9, 66, 5, 64, 10, 2, 35, 47, 0, 0, 6, 195, 28, 20, 192, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 32, 243, 142, 4, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 52, 85, 206, 76, 0, 0, 0, 0, 8, 197, 28, 17, 143, 16, 64, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 72, 133, 206, 28, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 21, 32, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 196, 100, 210, 5, 56, 8, 11, 11, 4, 95, 4, 16, 20, 48, 132, 50, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 28, 19, 12, 4, 224, 72, 6, 195, 4, 195, 0, 72, 0, 0, 0, 0, 0, 0, 7, 67, 100, 225, 192, 13, 0, 6, 195, 56, 85, 64, 8, 0, 0, 0, 0, 6, 195, 56, 85, 68, 76, 0, 0, 0, 5, 194, 28, 16, 76, 9, 66, 4, 208, 10, 2, 35, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 21, 80, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 28, 19, 12, 4, 72, 7, 196, 24, 83, 12, 100, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 24, 80, 76, 0, 6, 195, 24, 83, 0, 72, 0, 0, 0, 0, 0, 0, 0, 6, 195, 17, 147, 65, 72, 0, 0, 0, 0, 0, 6, 195, 16, 19, 128, 72, 6, 195, 16, 19, 128, 76, 7, 195, 16, 19, 128, 8, 11, 7, 195, 80, 19, 128, 8, 11, 0, 0, 0, 0, 0, 7, 196, 28, 19, 12, 36, 72, 7, 196, 4, 50, 15, 76, 8, 0, 0, 0, 6, 195, 52, 244, 128, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 8, 241, 0, 72, 0, 5, 194, 20, 144, 72, 0, 0, 7, 196, 4, 195, 1, 56, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 16, 16, 200, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 68, 40, 243, 133, 76, 75, 118, 50, 89, 0, 0, 0, 6, 195, 17, 147, 129, 72, 5, 194, 25, 144, 72, 0, 0, 0, 0, 0, 6, 195, 33, 147, 128, 76, 0, 0, 0, 0, 7, 195, 56, 84, 192, 8, 11, 0, 7, 196, 4, 195, 23, 56, 72, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 64, 85, 1, 36, 8, 0, 0, 0, 6, 195, 80, 21, 192, 76, 0, 12, 67, 4, 115, 211, 10, 119, 81, 111, 89, 0, 76, 0, 0, 0, 0, 7, 196, 28, 19, 12, 84, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 92, 81, 9, 72, 0, 14, 3, 95, 51, 88, 47, 34, 6, 114, 86, 4, 117, 81, 0, 0, 11, 3, 95, 48, 67, 49, 6, 35, 50, 47, 0, 0, 0, 0, 0, 7, 196, 100, 225, 4, 36, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 66, 32, 144, 107, 114, 0, 76, 0, 0, 14, 3, 95, 50, 67, 72, 6, 122, 81, 4, 35, 50, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 51, 67, 47, 34, 6, 114, 101, 4, 35, 50, 47, 0, 0, 0, 0, 0, 7, 196, 100, 225, 4, 60, 76, 0, 0, 0, 14, 3, 95, 55, 88, 89, 6, 121, 87, 86, 4, 117, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 24, 241, 0, 72, 0, 0, 10, 3, 95, 49, 88, 72, 6, 117, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 50, 88, 72, 6, 122, 86, 4, 117, 81, 0, 0, 0, 12, 69, 33, 81, 200, 21, 48, 107, 127, 12, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 52, 17, 78, 72, 0, 0, 0, 0, 0, 0, 17, 3, 95, 52, 88, 48, 6, 108, 72, 58, 35, 34, 86, 4, 117, 81, 0, 0, 0, 0, 0, 6, 195, 52, 17, 64, 72, 6, 195, 52, 17, 64, 72, 0, 0, 0, 5, 194, 56, 16, 72, 0, 14, 3, 95, 53, 88, 48, 6, 110, 65, 86, 4, 117, 81, 0, 0, 0, 0, 9, 198, 72, 134, 87, 72, 18, 64, 72, 0, 6, 195, 52, 18, 64, 41, 6, 195, 52, 18, 64, 76, 0, 0, 0, 0, 14, 3, 95, 54, 88, 101, 58, 6, 117, 86, 4, 117, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 56, 88, 58, 6, 110, 87, 86, 4, 117, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 57, 88, 50, 6, 123, 86, 4, 117, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 61, 48, 72, 8, 0, 6, 195, 20, 147, 128, 72, 0, 0, 0, 14, 4, 95, 48, 77, 50, 65, 6, 114, 55, 127, 50, 10, 0, 0, 14, 4, 95, 48, 77, 51, 71, 6, 114, 55, 127, 50, 10, 0, 0, 0, 12, 4, 95, 48, 77, 49, 65, 6, 114, 55, 10, 0, 0, 0, 6, 195, 73, 118, 84, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 131, 39, 13, 1, 76, 0, 0, 6, 195, 17, 35, 211, 76, 0, 0, 0, 0, 0, 0, 6, 131, 39, 14, 1, 76, 0, 0, 0, 6, 195, 73, 118, 64, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 17, 37, 217, 76, 0, 0, 0, 11, 3, 195, 180, 12, 10, 2, 118, 55, 0, 11, 0, 0, 0, 0, 0, 0, 0, 8, 66, 56, 144, 50, 114, 0, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 60, 84, 192, 72, 0, 7, 196, 8, 192, 69, 56, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 72, 241, 68, 16, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 33, 115, 142, 4, 76, 0, 0, 0, 0, 0, 8, 197, 84, 228, 136, 101, 112, 72, 0, 0, 0, 0, 0, 0, 0, 7, 196, 72, 128, 73, 56, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 195, 77, 81, 0, 72, 8, 11, 0, 8, 2, 195, 162, 10, 2, 119, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 60, 225, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 198, 60, 129, 82, 93, 145, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 81, 80, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 67, 56, 133, 192, 50, 107, 116, 0, 76, 0, 0, 0, 0, 0, 7, 196, 33, 115, 142, 92, 76, 0, 0, 0, 0, 0, 0, 0, 9, 198, 28, 21, 211, 60, 50, 0, 76, 0, 7, 196, 33, 147, 142, 100, 76, 0, 0, 6, 195, 73, 145, 23, 72, 6, 194, 77, 144, 72, 8, 0, 6, 2, 95, 1, 119, 0, 0, 0, 0, 0, 6, 2, 95, 5, 117, 0, 0, 0, 0, 0, 0, 6, 195, 32, 80, 128, 72, 6, 2, 95, 15, 118, 0, 0, 0, 8, 197, 73, 145, 25, 12, 128, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 2, 95, 25, 113, 0, 0, 8, 66, 80, 144, 47, 114, 0, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 4, 195, 1, 72, 0, 0, 0, 0, 0, 0, 0, 8, 197, 29, 115, 133, 84, 64, 76, 8, 197, 4, 195, 23, 12, 128, 72, 0, 6, 195, 4, 195, 9, 72, 0, 8, 195, 21, 36, 192, 72, 8, 11, 9, 2, 95, 51, 47, 34, 6, 114, 0, 0, 7, 196, 21, 32, 153, 56, 76, 8, 2, 95, 50, 72, 6, 122, 0, 0, 8, 2, 95, 49, 6, 110, 50, 0, 0, 9, 2, 95, 48, 50, 6, 112, 55, 0, 0, 9, 2, 95, 55, 89, 6, 121, 87, 0, 0, 10, 2, 95, 54, 101, 58, 6, 117, 99, 0, 0, 10, 2, 95, 53, 48, 6, 110, 65, 48, 0, 0, 12, 2, 95, 52, 48, 6, 108, 72, 58, 35, 34, 0, 0, 0, 0, 8, 2, 95, 57, 50, 6, 123, 0, 0, 9, 2, 95, 56, 58, 6, 110, 87, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 72, 129, 73, 56, 16, 76, 0, 0, 0, 0, 0, 0, 0, 0, 6, 2, 95, 73, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 66, 101, 32, 13, 34, 0, 0, 0, 0, 0, 0, 6, 195, 56, 17, 192, 72, 0, 0, 0, 0, 0, 0, 0, 0, 9, 67, 12, 130, 64, 101, 114, 0, 76, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 73, 147, 128, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 73, 145, 25, 56, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 198, 28, 19, 12, 92, 50, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 28, 21, 211, 60, 224, 76, 0, 0, 0, 0, 0, 0, 6, 195, 73, 144, 200, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 66, 101, 112, 2, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 28, 19, 12, 72, 0, 0, 0, 0, 0, 0, 8, 197, 28, 84, 207, 12, 128, 76, 0, 0, 10, 199, 72, 134, 87, 24, 18, 78, 80, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 72, 129, 73, 56, 144, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 100, 208, 64, 76, 0, 0, 0, 6, 195, 29, 145, 1, 76, 0, 7, 195, 77, 145, 4, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 12, 17, 76, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 101, 48, 146, 100, 64, 66, 0, 0, 8, 195, 76, 133, 196, 72, 8, 11, 0, 0, 0, 0, 0, 0, 0, 6, 66, 100, 208, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 18, 66, 99, 104, 0, 100, 100, 0, 102, 102, 0, 108, 108, 0, 116, 104, 0, 7, 6, 97, 0, 4, 2, 17, 67, 3, 35, 0, 2, 17, 67, 17, 67, 0, 4, 3, 119, 0, 2, 98, 0, 2, 99, 104, 0, 2, 100, 0, 2, 100, 100, 0, 2, 102, 0, 2, 102, 102, 0, 2, 103, 0, 2, 115, 0, 2, 116, 104, 0, 8, 2, 32, 0, 97, 0, 101, 3, 120, 0, 105, 3, 121, 0, 117, 3, 122, 0, 119, 2, 12, 3, 123, 0, 7, 6, 98, 0, 3, 71, 0, 8, 2, 32, 3, 71, 114, 0, 7, 6, 99, 0, 3, 49, 0, 119, 110, 8, 3, 49, 112, 65, 0, 4, 104, 1, 101, 3, 99, 0, 104, 1, 105, 0, 104, 1, 117, 0, 104, 3, 101, 0, 8, 2, 32, 3, 108, 49, 0, 104, 8, 2, 32, 3, 108, 101, 0, 7, 6, 100, 0, 3, 72, 0, 8, 2, 32, 3, 72, 114, 0, 100, 3, 86, 0, 100, 8, 2, 32, 3, 108, 86, 0, 7, 6, 101, 0, 4, 2, 17, 67, 3, 108, 0, 2, 17, 67, 17, 67, 0, 2, 119, 17, 65, 0, 4, 3, 117, 0, 2, 98, 0, 2, 99, 104, 0, 2, 100, 0, 2, 100, 100, 0, 2, 102, 0, 2, 102, 102, 0, 2, 103, 0, 2, 115, 0, 2, 116, 104, 0, 8, 2, 32, 0, 101, 0, 4, 105, 3, 124, 0, 121, 0, 117, 3, 125, 0, 119, 2, 12, 3, 126, 0, 7, 6, 102, 0, 102, 3, 83, 0, 3, 84, 0, 102, 8, 2, 32, 3, 108, 83, 0, 8, 2, 32, 3, 108, 84, 0, 7, 6, 103, 0, 3, 81, 0, 119, 114, 3, 81, 58, 14, 34, 0, 119, 110, 3, 81, 58, 14, 50, 0, 119, 108, 3, 81, 58, 14, 55, 0, 8, 2, 32, 3, 108, 81, 0, 7, 6, 104, 0, 3, 107, 0, 8, 2, 32, 3, 107, 119, 0, 7, 6, 105, 0, 2, 17, 65, 3, 57, 0, 4, 2, 17, 67, 3, 109, 0, 2, 17, 67, 17, 67, 0, 4, 3, 114, 0, 2, 98, 0, 2, 99, 104, 0, 2, 100, 0, 2, 100, 100, 0, 2, 102, 0, 2, 102, 102, 0, 2, 103, 0, 2, 108, 0, 2, 110, 0, 2, 114, 0, 2, 115, 0, 2, 116, 104, 0, 8, 2, 32, 0, 105, 0, 119, 2, 12, 3, 127, 0, 7, 6, 106, 0, 3, 75, 0, 8, 2, 32, 3, 75, 113, 0, 7, 6, 107, 0, 3, 49, 0, 8, 2, 32, 3, 49, 113, 0, 7, 6, 108, 0, 3, 55, 0, 108, 3, 105, 0, 108, 97, 110, 8, 3, 105, 35, 50, 0, 8, 2, 32, 3, 108, 55, 0, 108, 8, 2, 32, 3, 108, 105, 0, 7, 6, 109, 0, 3, 65, 0, 8, 2, 32, 3, 108, 65, 0, 7, 6, 110, 0, 3, 50, 0, 103, 3, 68, 0, 8, 2, 32, 3, 108, 50, 0, 103, 8, 2, 32, 3, 108, 68, 0, 7, 6, 111, 0, 4, 2, 17, 67, 3, 111, 0, 2, 17, 67, 17, 67, 0, 4, 3, 118, 0, 2, 98, 0, 2, 99, 104, 0, 2, 100, 0, 2, 100, 100, 0, 2, 102, 0, 2, 102, 102, 0, 2, 103, 0, 2, 115, 0, 2, 116, 104, 0, 8, 2, 32, 0, 111, 0, 105, 3, 129, 0, 4, 101, 3, 130, 0, 117, 0, 7, 6, 112, 0, 3, 48, 0, 8, 2, 32, 3, 48, 114, 0, 104, 3, 83, 0, 104, 8, 2, 32, 3, 83, 114, 0, 7, 6, 113, 0, 3, 49, 0, 117, 3, 49, 58, 0, 8, 2, 32, 3, 49, 58, 119, 0, 7, 6, 114, 0, 3, 34, 0, 104, 3, 107, 34, 0, 104, 8, 2, 32, 3, 107, 34, 118, 0, 8, 2, 32, 3, 108, 34, 0, 7, 6, 115, 0, 3, 89, 0, 105, 2, 17, 65, 3, 91, 0, 8, 2, 32, 3, 108, 89, 0, 7, 6, 116, 0, 3, 47, 0, 8, 2, 32, 3, 47, 114, 0, 104, 3, 87, 0, 104, 8, 2, 32, 3, 108, 87, 0, 7, 6, 117, 0, 8, 2, 32, 3, 4, 109, 71, 6, 108, 72, 111, 55, 0, 4, 2, 17, 67, 3, 110, 0, 2, 17, 67, 17, 67, 0, 4, 3, 115, 0, 2, 98, 0, 2, 99, 104, 0, 2, 100, 0, 2, 100, 100, 0, 2, 102, 0, 2, 102, 102, 0, 2, 103, 0, 2, 108, 0, 2, 108, 108, 0, 2, 110, 0, 2, 114, 0, 2, 115, 0, 2, 116, 104, 0, 117, 0, 119, 2, 12, 3, 128, 0, 7, 6, 118, 0, 3, 84, 0, 8, 2, 32, 3, 84, 114, 0, 7, 6, 119, 0, 8, 2, 108, 3, 0, 4, 1, 103, 3, 58, 0, 2, 17, 65, 0, 4, 1, 10, 2, 25, 12, 3, 112, 0, 2, 17, 67, 0, 2, 17, 67, 17, 67, 0, 4, 3, 116, 0, 2, 98, 0, 2, 99, 104, 0, 2, 100, 0, 2, 100, 100, 0, 2, 102, 0, 2, 102, 102, 0, 2, 103, 0, 2, 115, 0, 2, 116, 104, 0, 8, 2, 32, 0, 119, 0, 121, 3, 132, 0, 7, 6, 120, 0, 3, 49, 89, 0, 8, 2, 32, 3, 108, 49, 89, 0, 7, 6, 121, 0, 110, 8, 2, 32, 110, 3, 13, 0, 110, 8, 2, 32, 3, 13, 50, 0, 8, 2, 119, 3, 57, 0, 4, 2, 17, 67, 3, 110, 0, 2, 17, 67, 17, 67, 0, 4, 2, 21, 12, 3, 113, 0, 8, 2, 32, 0, 4, 3, 115, 0, 2, 99, 104, 0, 2, 100, 0, 2, 100, 100, 0, 2, 103, 0, 2, 115, 0, 2, 116, 104, 0, 119, 2, 12, 3, 128, 0, 7, 6, 122, 0, 3, 88, 0, 8, 2, 32, 3, 88, 116, 0, 7, 6, 0, 39, 114, 2, 32, 14, 128, 128, 130, 3, 34, 0, 195, 160, 3, 35, 0, 46, 3, 48, 132, 50, 47, 0, 39, 110, 2, 32, 14, 128, 128, 130, 3, 50, 0, 39, 99, 104, 2, 32, 14, 128, 128, 131, 3, 101, 0, 195, 168, 3, 108, 0, 195, 172, 3, 109, 0, 4, 195, 185, 3, 110, 0, 225, 187, 179, 0, 195, 178, 3, 111, 0, 225, 186, 129, 3, 112, 0, 4, 195, 174, 3, 114, 0, 195, 175, 0, 4, 195, 187, 3, 115, 0, 197, 183, 0, 197, 181, 3, 116, 0, 195, 170, 3, 117, 0, 195, 180, 3, 118, 0, 195, 162, 3, 119, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts9 = FileInMemory_createWithData (3462, reinterpret_cast (&espeakdata_dicts9_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/cy_dict", U"cy"); Collection_addItem (me.peek(), espeakdata_dicts9.transfer()); static unsigned char espeakdata_dicts10_data[193792] = { 0, 4, 0, 0, 203, 216, 1, 0, 12, 201, 60, 101, 1, 48, 211, 204, 60, 114, 64, 20, 12, 201, 48, 20, 153, 56, 115, 204, 60, 114, 64, 20, 12, 201, 24, 20, 141, 4, 179, 204, 60, 114, 64, 20, 13, 138, 1, 18, 11, 195, 166, 15, 12, 15, 7, 9, 20, 17, 142, 1, 14, 195, 166, 19, 20, 5, 19, 9, 15, 12, 15, 7, 9, 20, 15, 140, 6, 15, 18, 6, 195, 184, 18, 5, 18, 9, 19, 11, 20, 0, 26, 73, 8, 80, 200, 4, 209, 76, 76, 245, 147, 71, 36, 91, 35, 65, 6, 36, 12, 60, 89, 6, 114, 58, 89, 0, 0, 10, 199, 72, 17, 9, 60, 195, 199, 36, 20, 10, 199, 61, 53, 5, 60, 195, 199, 36, 20, 10, 199, 45, 35, 206, 60, 195, 199, 36, 20, 10, 199, 36, 181, 25, 60, 195, 199, 36, 20, 10, 199, 36, 179, 206, 60, 195, 199, 36, 20, 10, 199, 32, 148, 16, 60, 195, 199, 36, 20, 10, 199, 25, 33, 78, 60, 195, 199, 36, 20, 10, 199, 24, 147, 13, 60, 195, 199, 36, 20, 14, 203, 24, 147, 140, 4, 225, 9, 76, 84, 137, 56, 112, 20, 14, 203, 20, 180, 208, 72, 244, 18, 36, 84, 137, 56, 112, 20, 14, 203, 16, 81, 137, 9, 34, 76, 48, 84, 137, 56, 112, 20, 10, 199, 4, 69, 133, 72, 34, 69, 48, 20, 12, 201, 16, 144, 71, 56, 244, 212, 36, 49, 82, 20, 12, 201, 64, 243, 25, 80, 82, 206, 36, 177, 82, 20, 0, 17, 67, 52, 83, 128, 65, 36, 50, 15, 89, 114, 0, 81, 115, 195, 165, 32, 9, 198, 60, 224, 78, 37, 53, 0, 20, 9, 198, 9, 81, 134, 37, 53, 0, 20, 12, 201, 8, 81, 21, 36, 228, 212, 4, 211, 69, 67, 9, 198, 76, 84, 150, 36, 49, 82, 20, 9, 198, 16, 84, 193, 72, 209, 82, 20, 9, 198, 5, 4, 12, 36, 177, 82, 20, 12, 137, 19, 22, 195, 166, 18, 13, 5, 18, 9, 20, 12, 137, 4, 18, 195, 184, 13, 13, 5, 18, 9, 20, 9, 198, 4, 96, 84, 36, 177, 82, 20, 6, 195, 52, 83, 128, 8, 0, 9, 198, 36, 225, 21, 77, 68, 137, 20, 0, 13, 202, 64, 20, 143, 16, 243, 148, 60, 195, 199, 36, 20, 9, 198, 21, 33, 207, 56, 243, 64, 20, 9, 198, 4, 116, 143, 56, 243, 64, 20, 8, 197, 8, 192, 77, 21, 32, 20, 10, 135, 22, 195, 165, 19, 5, 18, 9, 20, 0, 9, 198, 65, 54, 75, 61, 49, 64, 20, 9, 198, 48, 22, 129, 72, 243, 128, 20, 9, 198, 80, 244, 147, 36, 243, 128, 20, 9, 198, 77, 64, 68, 36, 243, 128, 20, 9, 198, 8, 147, 12, 36, 243, 128, 20, 9, 198, 5, 82, 212, 36, 243, 128, 20, 12, 137, 7, 18, 195, 166, 3, 9, 19, 5, 18, 20, 11, 136, 6, 195, 166, 18, 7, 5, 18, 9, 20, 9, 198, 5, 0, 84, 37, 50, 192, 20, 12, 201, 52, 83, 1, 56, 179, 204, 36, 177, 82, 20, 12, 201, 16, 144, 71, 56, 244, 212, 36, 177, 82, 20, 10, 199, 52, 21, 83, 60, 193, 85, 52, 20, 9, 198, 4, 48, 197, 77, 50, 84, 20, 7, 196, 5, 0, 84, 36, 20, 9, 198, 56, 146, 207, 80, 147, 128, 20, 9, 198, 44, 20, 143, 80, 147, 128, 20, 10, 199, 33, 83, 65, 56, 148, 205, 20, 20, 10, 199, 4, 197, 18, 84, 148, 205, 20, 20, 9, 198, 76, 20, 129, 12, 83, 128, 20, 9, 198, 64, 19, 129, 52, 19, 128, 20, 9, 198, 44, 243, 150, 20, 229, 0, 20, 10, 199, 64, 84, 141, 4, 225, 78, 76, 20, 9, 198, 44, 243, 148, 4, 229, 0, 20, 9, 198, 5, 0, 78, 4, 113, 64, 20, 0, 17, 70, 72, 82, 137, 12, 84, 133, 34, 36, 57, 37, 89, 6, 36, 114, 0, 10, 199, 65, 35, 195, 20, 69, 82, 20, 20, 10, 199, 80, 19, 80, 60, 225, 82, 20, 20, 10, 199, 80, 16, 133, 48, 193, 82, 20, 20, 10, 199, 72, 80, 133, 48, 193, 82, 20, 20, 10, 199, 52, 241, 5, 48, 193, 82, 20, 20, 10, 199, 16, 84, 201, 28, 225, 82, 20, 20, 10, 199, 5, 4, 5, 48, 193, 82, 20, 20, 9, 198, 81, 38, 76, 48, 84, 137, 20, 9, 198, 49, 83, 83, 44, 84, 137, 20, 9, 198, 45, 82, 143, 56, 84, 137, 20, 9, 198, 45, 38, 68, 16, 84, 137, 20, 9, 198, 44, 192, 84, 80, 84, 137, 20, 9, 198, 17, 34, 76, 48, 84, 137, 20, 10, 199, 4, 224, 75, 60, 197, 84, 36, 20, 0, 11, 200, 77, 65, 82, 20, 244, 203, 61, 0, 20, 9, 198, 20, 193, 75, 81, 35, 206, 20, 7, 196, 52, 84, 193, 56, 21, 0, 12, 201, 81, 32, 78, 76, 101, 83, 36, 243, 128, 20, 12, 201, 77, 84, 16, 72, 84, 211, 36, 243, 128, 20, 12, 201, 72, 84, 1, 73, 66, 84, 36, 243, 128, 20, 12, 201, 45, 96, 68, 72, 147, 12, 36, 243, 128, 20, 12, 201, 44, 243, 80, 72, 84, 211, 36, 243, 128, 20, 12, 201, 36, 229, 5, 72, 18, 212, 36, 243, 128, 20, 12, 201, 20, 180, 208, 20, 66, 84, 36, 243, 128, 20, 12, 201, 24, 147, 15, 76, 241, 137, 45, 83, 64, 20, 12, 201, 80, 84, 146, 37, 67, 210, 37, 83, 64, 20, 12, 201, 60, 97, 133, 73, 67, 210, 37, 83, 64, 20, 8, 197, 16, 83, 148, 36, 224, 20, 8, 197, 8, 84, 140, 36, 224, 20, 13, 202, 88, 144, 212, 61, 34, 65, 56, 148, 205, 20, 20, 13, 202, 60, 36, 203, 85, 32, 78, 80, 148, 205, 20, 20, 13, 202, 16, 242, 212, 72, 147, 129, 72, 148, 205, 20, 20, 8, 197, 8, 84, 140, 36, 224, 20, 8, 197, 45, 83, 80, 4, 224, 21, 6, 65, 8, 71, 36, 0, 0, 18, 70, 52, 19, 129, 29, 80, 64, 65, 110, 50, 6, 110, 12, 81, 58, 110, 0, 9, 198, 72, 80, 75, 80, 244, 128, 20, 9, 198, 77, 1, 78, 16, 84, 128, 20, 9, 198, 76, 84, 15, 56, 84, 128, 20, 9, 198, 72, 84, 207, 56, 84, 128, 20, 9, 198, 72, 82, 137, 12, 84, 128, 20, 9, 198, 64, 245, 83, 76, 84, 128, 20, 9, 198, 61, 33, 9, 56, 84, 128, 20, 9, 198, 61, 4, 15, 56, 84, 128, 20, 9, 198, 44, 195, 193, 44, 84, 128, 20, 9, 198, 36, 212, 15, 56, 84, 128, 20, 9, 198, 25, 32, 80, 64, 84, 128, 20, 9, 198, 20, 225, 193, 28, 84, 128, 20, 9, 198, 5, 52, 213, 72, 84, 128, 20, 15, 140, 12, 195, 184, 19, 7, 195, 166, 14, 7, 5, 18, 9, 20, 8, 133, 195, 184, 4, 5, 13, 20, 9, 198, 5, 97, 79, 48, 20, 128, 20, 9, 198, 52, 147, 9, 80, 19, 148, 20, 9, 198, 4, 66, 149, 16, 19, 148, 20, 0, 10, 199, 32, 148, 212, 60, 195, 199, 36, 20, 9, 198, 52, 243, 143, 52, 19, 137, 20, 10, 199, 77, 82, 203, 84, 193, 78, 80, 20, 14, 203, 56, 21, 18, 37, 83, 66, 20, 230, 143, 5, 64, 20, 10, 199, 5, 48, 197, 56, 64, 78, 80, 20, 0, 15, 204, 44, 20, 129, 45, 65, 82, 37, 53, 9, 45, 83, 64, 20, 9, 198, 4, 224, 76, 101, 48, 66, 20, 7, 196, 21, 64, 71, 20, 20, 9, 68, 76, 208, 76, 48, 21, 0, 10, 0, 12, 201, 88, 149, 1, 52, 147, 137, 76, 84, 128, 20, 12, 201, 84, 225, 5, 73, 101, 82, 16, 84, 128, 20, 12, 201, 81, 32, 78, 77, 3, 210, 80, 84, 128, 20, 12, 201, 81, 32, 78, 76, 99, 210, 52, 84, 128, 20, 12, 201, 77, 68, 129, 80, 145, 137, 12, 84, 128, 20, 12, 201, 72, 83, 210, 28, 19, 137, 76, 84, 128, 20, 12, 201, 36, 229, 5, 72, 99, 204, 36, 84, 128, 20, 12, 201, 36, 212, 12, 20, 209, 78, 80, 84, 128, 20, 12, 201, 28, 192, 77, 61, 84, 137, 76, 84, 128, 20, 12, 201, 25, 32, 84, 21, 35, 137, 76, 84, 128, 20, 12, 201, 5, 85, 15, 56, 243, 73, 76, 84, 128, 20, 8, 197, 32, 245, 133, 72, 144, 20, 8, 197, 64, 85, 18, 60, 192, 20, 12, 201, 76, 178, 83, 52, 21, 9, 44, 84, 128, 20, 12, 201, 64, 20, 129, 49, 149, 9, 44, 84, 128, 20, 12, 201, 21, 128, 197, 57, 68, 137, 44, 84, 128, 20, 12, 201, 8, 192, 83, 24, 83, 73, 44, 84, 128, 20, 11, 136, 195, 184, 11, 15, 14, 15, 13, 9, 20, 6, 65, 12, 89, 36, 0, 0, 17, 70, 8, 83, 9, 104, 84, 128, 71, 36, 55, 37, 12, 89, 114, 0, 66, 12, 202, 65, 54, 75, 60, 96, 82, 52, 18, 207, 56, 9, 198, 72, 83, 133, 28, 84, 128, 20, 9, 198, 60, 97, 133, 72, 84, 128, 20, 9, 198, 52, 241, 5, 72, 84, 128, 20, 9, 198, 52, 148, 197, 72, 84, 128, 20, 9, 198, 36, 227, 143, 88, 84, 128, 20, 9, 198, 36, 225, 9, 12, 84, 128, 20, 9, 198, 24, 192, 77, 8, 84, 128, 20, 9, 198, 16, 148, 137, 28, 84, 128, 20, 9, 198, 16, 85, 15, 56, 84, 128, 20, 9, 198, 16, 84, 15, 56, 84, 128, 20, 9, 198, 16, 83, 9, 72, 84, 128, 20, 9, 198, 8, 147, 208, 80, 84, 128, 20, 12, 201, 45, 33, 65, 80, 147, 206, 37, 51, 69, 20, 9, 198, 45, 99, 212, 36, 83, 148, 20, 9, 198, 48, 81, 193, 80, 20, 128, 20, 9, 198, 76, 82, 211, 80, 19, 148, 20, 9, 198, 60, 178, 213, 64, 19, 148, 20, 9, 198, 45, 96, 68, 72, 19, 148, 20, 9, 198, 88, 84, 137, 80, 16, 128, 20, 0, 9, 198, 4, 116, 143, 56, 243, 73, 20, 9, 198, 4, 229, 9, 24, 243, 137, 20, 10, 199, 8, 144, 140, 36, 243, 65, 56, 21, 14, 4, 95, 8, 1, 3, 107, 6, 35, 76, 4, 109, 49, 0, 0, 14, 139, 7, 25, 14, 195, 166, 11, 15, 12, 15, 7, 9, 20, 11, 200, 77, 81, 199, 21, 53, 9, 60, 224, 20, 11, 200, 72, 84, 207, 73, 5, 9, 60, 224, 20, 9, 198, 44, 20, 142, 20, 243, 0, 20, 9, 198, 25, 33, 85, 16, 144, 78, 20, 0, 12, 201, 72, 81, 201, 77, 68, 129, 80, 244, 128, 20, 12, 201, 44, 243, 147, 21, 37, 129, 80, 244, 128, 20, 12, 201, 44, 243, 132, 20, 228, 193, 80, 244, 128, 20, 12, 201, 44, 243, 80, 20, 228, 193, 80, 244, 128, 20, 12, 201, 36, 195, 21, 77, 68, 129, 80, 244, 128, 20, 10, 135, 2, 5, 19, 22, 195, 166, 18, 20, 12, 201, 64, 243, 25, 52, 84, 137, 76, 84, 128, 20, 12, 201, 64, 192, 83, 80, 145, 137, 12, 84, 128, 20, 12, 201, 61, 3, 65, 28, 20, 201, 56, 84, 128, 20, 12, 201, 45, 96, 78, 80, 145, 137, 12, 84, 128, 20, 12, 201, 32, 145, 82, 5, 34, 201, 76, 84, 128, 20, 12, 201, 29, 147, 78, 5, 53, 9, 12, 84, 128, 20, 8, 197, 4, 226, 77, 21, 32, 20, 12, 201, 32, 243, 73, 48, 85, 9, 44, 84, 128, 20, 12, 201, 16, 144, 76, 20, 181, 9, 44, 84, 128, 20, 15, 204, 36, 229, 5, 73, 97, 78, 80, 147, 206, 37, 51, 69, 20, 6, 65, 16, 72, 36, 0, 0, 11, 136, 20, 5, 18, 20, 9, 195, 166, 18, 20, 11, 136, 8, 15, 14, 15, 18, 195, 166, 18, 20, 9, 198, 104, 243, 206, 61, 49, 64, 20, 9, 198, 56, 20, 139, 61, 49, 64, 20, 9, 198, 28, 197, 75, 61, 49, 64, 20, 16, 141, 6, 195, 166, 14, 15, 13, 5, 14, 15, 12, 15, 7, 9, 20, 9, 198, 76, 244, 130, 37, 67, 204, 20, 17, 70, 64, 83, 132, 4, 229, 0, 48, 112, 68, 72, 6, 112, 68, 0, 20, 0, 9, 198, 45, 82, 143, 56, 84, 133, 20, 9, 198, 44, 20, 146, 36, 84, 133, 20, 9, 198, 29, 34, 76, 48, 84, 133, 20, 10, 199, 61, 1, 143, 72, 209, 82, 20, 20, 9, 198, 48, 18, 197, 72, 84, 137, 20, 9, 198, 29, 37, 66, 48, 84, 137, 20, 10, 199, 21, 35, 212, 60, 208, 78, 36, 20, 9, 198, 33, 148, 132, 36, 225, 5, 20, 11, 67, 76, 147, 128, 89, 6, 37, 50, 0, 76, 0, 9, 198, 65, 35, 205, 61, 67, 210, 20, 11, 200, 12, 84, 148, 36, 98, 75, 5, 64, 20, 13, 138, 16, 18, 195, 166, 19, 5, 14, 20, 1, 2, 20, 0, 9, 198, 61, 67, 211, 44, 244, 0, 20, 12, 201, 45, 33, 65, 80, 149, 137, 80, 85, 0, 20, 12, 201, 88, 147, 132, 36, 49, 82, 36, 225, 192, 20, 12, 201, 77, 80, 147, 84, 209, 82, 36, 225, 192, 20, 12, 201, 76, 83, 5, 45, 65, 82, 36, 225, 192, 20, 12, 201, 64, 192, 84, 36, 225, 82, 36, 225, 192, 20, 12, 201, 64, 20, 211, 37, 97, 82, 36, 225, 192, 20, 12, 201, 64, 20, 208, 60, 193, 82, 36, 225, 192, 20, 12, 201, 61, 34, 69, 57, 65, 82, 36, 225, 192, 20, 12, 201, 52, 20, 141, 61, 33, 82, 36, 225, 192, 20, 12, 201, 48, 19, 69, 57, 65, 82, 36, 225, 192, 20, 12, 201, 45, 84, 147, 37, 97, 82, 36, 225, 192, 20, 12, 201, 44, 244, 212, 84, 209, 82, 36, 225, 192, 20, 12, 201, 44, 243, 134, 21, 33, 82, 36, 225, 192, 20, 12, 201, 44, 243, 66, 36, 225, 82, 36, 225, 192, 20, 12, 201, 44, 19, 11, 84, 193, 82, 36, 225, 192, 20, 12, 201, 36, 229, 5, 72, 225, 82, 36, 225, 192, 20, 12, 201, 36, 228, 212, 73, 81, 82, 36, 225, 192, 20, 12, 201, 36, 225, 143, 72, 209, 82, 36, 225, 192, 20, 12, 201, 36, 225, 12, 21, 97, 82, 36, 225, 192, 20, 12, 201, 24, 245, 82, 4, 113, 82, 36, 225, 192, 20, 12, 201, 20, 180, 208, 60, 225, 82, 36, 225, 192, 20, 12, 201, 16, 148, 208, 60, 225, 82, 36, 225, 192, 20, 12, 201, 16, 147, 73, 81, 65, 82, 36, 225, 192, 20, 12, 201, 16, 83, 69, 57, 65, 82, 36, 225, 192, 20, 12, 201, 16, 82, 204, 36, 225, 82, 36, 225, 192, 20, 12, 201, 16, 82, 204, 5, 33, 82, 36, 225, 192, 20, 12, 201, 12, 83, 5, 9, 33, 82, 36, 225, 192, 20, 12, 201, 8, 192, 78, 12, 129, 82, 36, 225, 192, 20, 12, 201, 8, 19, 1, 56, 49, 82, 36, 225, 192, 20, 12, 201, 5, 4, 18, 60, 33, 82, 36, 225, 192, 20, 12, 201, 48, 245, 134, 61, 35, 69, 48, 145, 192, 20, 0, 11, 136, 11, 22, 195, 166, 19, 20, 15, 18, 20, 9, 198, 21, 0, 85, 48, 85, 0, 20, 9, 198, 52, 147, 12, 36, 243, 128, 20, 9, 198, 20, 194, 83, 36, 243, 128, 20, 9, 198, 76, 19, 137, 80, 85, 0, 20, 9, 198, 44, 21, 137, 80, 85, 0, 20, 9, 198, 20, 229, 9, 80, 85, 0, 20, 9, 198, 44, 20, 146, 85, 49, 76, 20, 12, 201, 77, 80, 138, 20, 181, 9, 88, 84, 133, 20, 12, 201, 29, 82, 76, 48, 245, 9, 56, 84, 133, 20, 12, 201, 16, 147, 5, 81, 64, 78, 80, 84, 137, 20, 9, 198, 77, 147, 148, 21, 49, 64, 20, 9, 198, 16, 82, 207, 73, 83, 64, 20, 9, 198, 56, 144, 133, 56, 149, 0, 20, 9, 198, 16, 242, 212, 72, 147, 128, 20, 12, 137, 7, 18, 195, 166, 3, 9, 19, 13, 5, 20, 9, 198, 72, 81, 133, 72, 21, 0, 20, 9, 198, 36, 229, 18, 36, 176, 84, 20, 9, 198, 36, 226, 21, 52, 19, 128, 21, 9, 198, 17, 83, 3, 36, 19, 128, 21, 9, 198, 4, 116, 129, 52, 19, 128, 21, 0, 9, 198, 4, 84, 143, 17, 35, 205, 20, 10, 199, 24, 19, 19, 44, 225, 82, 36, 20, 10, 199, 77, 98, 71, 4, 117, 9, 28, 20, 9, 198, 52, 17, 206, 21, 50, 69, 20, 10, 199, 80, 84, 141, 60, 116, 129, 24, 20, 10, 199, 44, 244, 133, 60, 116, 129, 24, 20, 10, 199, 77, 98, 71, 4, 117, 9, 28, 20, 0, 9, 198, 48, 16, 146, 4, 67, 210, 20, 9, 198, 44, 244, 146, 36, 67, 210, 20, 9, 198, 20, 193, 86, 5, 67, 210, 20, 15, 204, 81, 32, 78, 77, 3, 1, 57, 65, 82, 36, 225, 192, 20, 15, 204, 80, 82, 206, 60, 195, 199, 37, 49, 82, 36, 225, 192, 20, 15, 204, 44, 243, 80, 72, 243, 73, 81, 65, 82, 36, 225, 192, 20, 15, 204, 36, 228, 212, 73, 83, 69, 57, 65, 82, 36, 225, 192, 20, 15, 204, 36, 211, 65, 81, 34, 75, 84, 193, 82, 36, 225, 192, 20, 15, 204, 8, 144, 140, 36, 241, 210, 4, 97, 82, 36, 225, 192, 20, 9, 198, 77, 147, 132, 36, 177, 82, 20, 9, 198, 73, 80, 146, 36, 49, 82, 20, 9, 198, 24, 84, 142, 37, 49, 82, 20, 15, 204, 20, 180, 200, 36, 34, 84, 36, 243, 137, 76, 209, 64, 20, 6, 195, 76, 147, 133, 76, 0, 12, 201, 81, 32, 78, 76, 18, 212, 36, 243, 128, 20, 12, 201, 72, 84, 212, 37, 69, 84, 36, 243, 128, 20, 12, 201, 64, 244, 201, 80, 149, 137, 80, 85, 0, 20, 12, 201, 56, 81, 193, 80, 149, 137, 80, 85, 0, 20, 12, 201, 52, 147, 137, 77, 65, 82, 37, 83, 64, 20, 8, 197, 80, 84, 141, 36, 176, 20, 8, 197, 80, 83, 210, 20, 208, 20, 8, 197, 8, 17, 193, 28, 80, 20, 6, 65, 24, 109, 83, 0, 0, 10, 135, 11, 21, 18, 9, 195, 184, 19, 20, 9, 198, 65, 83, 12, 36, 213, 84, 20, 9, 198, 28, 83, 204, 60, 114, 64, 20, 9, 198, 17, 35, 199, 37, 53, 0, 20, 13, 202, 25, 37, 71, 81, 51, 205, 52, 83, 9, 28, 20, 9, 198, 64, 19, 132, 20, 210, 64, 20, 9, 198, 60, 33, 21, 12, 83, 148, 20, 0, 10, 199, 48, 147, 78, 60, 195, 199, 36, 20, 10, 199, 29, 32, 70, 60, 195, 199, 36, 20, 10, 199, 28, 83, 77, 60, 195, 199, 36, 20, 10, 199, 5, 81, 9, 60, 195, 199, 36, 20, 12, 137, 16, 18, 195, 166, 3, 9, 19, 5, 18, 20, 12, 201, 64, 84, 147, 60, 226, 70, 36, 49, 82, 20, 12, 201, 52, 20, 203, 84, 194, 78, 37, 49, 82, 20, 10, 199, 36, 70, 76, 48, 146, 197, 72, 20, 10, 199, 8, 245, 1, 56, 146, 197, 72, 20, 13, 138, 16, 18, 195, 166, 12, 21, 4, 9, 21, 13, 20, 17, 70, 105, 80, 195, 32, 147, 137, 89, 40, 49, 6, 37, 50, 37, 0, 20, 9, 198, 49, 81, 15, 52, 19, 137, 20, 12, 201, 25, 83, 132, 4, 209, 78, 80, 19, 0, 20, 10, 199, 8, 20, 212, 60, 224, 68, 20, 20, 0, 9, 134, 22, 9, 7, 195, 184, 18, 20, 7, 196, 45, 84, 15, 56, 20, 11, 200, 80, 21, 15, 88, 84, 137, 56, 112, 20, 11, 200, 76, 242, 71, 56, 84, 137, 56, 112, 20, 11, 200, 20, 210, 71, 72, 84, 137, 56, 112, 20, 11, 200, 16, 81, 137, 48, 84, 137, 56, 112, 20, 11, 200, 8, 243, 137, 80, 84, 137, 56, 112, 20, 9, 198, 77, 1, 67, 36, 83, 0, 20, 11, 200, 16, 148, 212, 4, 224, 197, 72, 80, 20, 11, 200, 5, 52, 201, 77, 64, 78, 12, 80, 20, 9, 198, 61, 5, 9, 52, 19, 0, 20, 0, 13, 138, 13, 25, 19, 20, 5, 18, 9, 195, 184, 19, 20, 10, 135, 13, 1, 19, 19, 195, 184, 18, 20, 10, 135, 13, 1, 18, 11, 195, 184, 18, 20, 8, 197, 56, 147, 194, 36, 80, 20, 8, 197, 20, 228, 201, 4, 224, 21, 8, 197, 53, 84, 197, 4, 192, 20, 6, 65, 28, 81, 36, 0, 0, 9, 198, 72, 84, 1, 72, 84, 128, 20, 9, 198, 64, 17, 201, 56, 84, 128, 20, 9, 198, 45, 98, 84, 80, 84, 128, 20, 9, 198, 40, 243, 137, 76, 84, 128, 20, 9, 198, 36, 225, 9, 44, 84, 128, 20, 9, 198, 28, 195, 211, 76, 84, 128, 20, 13, 202, 20, 180, 203, 60, 211, 85, 56, 146, 197, 72, 20, 9, 198, 8, 20, 146, 36, 84, 128, 20, 9, 198, 4, 33, 9, 12, 84, 128, 20, 12, 201, 52, 20, 203, 84, 194, 78, 37, 51, 69, 20, 9, 198, 76, 192, 86, 60, 98, 76, 20, 9, 198, 88, 81, 197, 80, 20, 128, 20, 0, 12, 137, 18, 5, 7, 9, 19, 19, 195, 184, 18, 20, 9, 198, 25, 148, 201, 85, 33, 201, 20, 9, 198, 88, 20, 197, 48, 147, 133, 20, 9, 198, 28, 83, 1, 80, 147, 133, 20, 14, 203, 72, 83, 1, 80, 149, 137, 76, 84, 137, 56, 112, 20, 10, 199, 52, 19, 137, 65, 83, 5, 72, 20, 10, 199, 48, 81, 201, 80, 147, 69, 72, 20, 9, 198, 76, 18, 210, 37, 53, 9, 20, 9, 198, 88, 20, 197, 48, 147, 133, 20, 10, 199, 72, 145, 207, 72, 148, 205, 20, 20, 10, 199, 32, 147, 132, 84, 148, 205, 20, 20, 10, 199, 28, 21, 76, 48, 148, 205, 20, 20, 9, 198, 20, 194, 84, 37, 51, 69, 20, 10, 199, 16, 148, 137, 28, 148, 205, 20, 20, 10, 199, 88, 242, 193, 9, 83, 1, 72, 20, 6, 195, 44, 19, 128, 76, 14, 4, 95, 51, 88, 15, 47, 34, 6, 111, 83, 47, 13, 0, 0, 11, 200, 88, 145, 9, 52, 84, 137, 56, 112, 20, 11, 200, 56, 243, 73, 56, 84, 137, 56, 112, 20, 11, 200, 52, 84, 137, 80, 84, 137, 56, 112, 20, 11, 200, 5, 96, 78, 12, 84, 137, 56, 112, 20, 7, 196, 20, 180, 201, 48, 20, 0, 28, 67, 80, 245, 82, 47, 40, 12, 13, 72, 13, 15, 6, 83, 114, 12, 89, 0, 82, 100, 101, 32, 102, 111, 114, 99, 101, 32, 12, 201, 36, 225, 137, 49, 68, 129, 80, 244, 128, 20, 12, 201, 16, 83, 79, 17, 83, 1, 80, 244, 128, 20, 10, 135, 18, 1, 4, 9, 195, 166, 18, 20, 12, 201, 44, 243, 12, 5, 66, 79, 56, 84, 128, 20, 12, 201, 12, 83, 148, 72, 19, 9, 76, 84, 128, 20, 7, 65, 32, 107, 113, 12, 0, 0, 9, 198, 8, 243, 137, 80, 85, 0, 20, 9, 198, 4, 194, 193, 48, 242, 68, 20, 9, 198, 64, 84, 137, 45, 83, 64, 20, 9, 198, 16, 81, 137, 56, 149, 0, 20, 9, 198, 88, 20, 197, 48, 147, 128, 20, 9, 198, 48, 80, 201, 80, 147, 128, 20, 12, 201, 72, 21, 9, 60, 224, 76, 37, 51, 69, 20, 12, 201, 64, 21, 5, 72, 224, 76, 37, 51, 69, 20, 9, 198, 77, 147, 132, 36, 176, 84, 20, 9, 198, 52, 243, 143, 52, 19, 128, 21, 9, 198, 49, 81, 15, 52, 19, 128, 21, 9, 198, 5, 54, 76, 4, 229, 0, 20, 0, 25, 67, 28, 21, 128, 81, 110, 15, 89, 35, 57, 15, 47, 36, 55, 0, 82, 115, 105, 103, 32, 116, 105, 108, 32, 14, 203, 84, 68, 1, 72, 49, 76, 48, 84, 137, 56, 112, 20, 14, 203, 36, 225, 11, 4, 194, 213, 48, 84, 137, 56, 112, 20, 10, 199, 77, 68, 137, 44, 177, 82, 36, 20, 9, 198, 44, 21, 5, 28, 244, 137, 20, 6, 195, 5, 67, 204, 20, 0, 6, 195, 5, 67, 205, 20, 9, 198, 25, 84, 201, 60, 225, 82, 20, 9, 198, 8, 20, 212, 60, 225, 82, 20, 9, 1, 35, 50, 6, 113, 65, 114, 0, 0, 22, 65, 36, 37, 15, 49, 84, 6, 112, 12, 72, 114, 0, 81, 107, 118, 97, 114, 116, 101, 114, 32, 12, 201, 44, 20, 130, 61, 37, 78, 17, 83, 64, 20, 12, 201, 64, 20, 148, 36, 50, 80, 37, 83, 64, 20, 15, 204, 65, 35, 198, 21, 52, 201, 60, 224, 76, 37, 51, 69, 20, 12, 201, 4, 193, 75, 76, 19, 132, 72, 147, 128, 20, 7, 65, 36, 10, 37, 0, 76, 0, 9, 198, 77, 64, 84, 36, 243, 128, 20, 11, 136, 8, 195, 165, 14, 4, 20, 5, 18, 20, 13, 202, 44, 243, 147, 21, 37, 129, 80, 244, 137, 20, 20, 9, 198, 52, 17, 206, 21, 50, 84, 20, 9, 198, 28, 20, 207, 48, 147, 128, 20, 9, 198, 65, 84, 137, 80, 19, 128, 20, 13, 1, 37, 48, 51, 39, 89, 6, 36, 50, 72, 0, 27, 0, 10, 199, 53, 84, 201, 44, 243, 15, 28, 20, 10, 199, 25, 85, 21, 72, 243, 15, 28, 20, 10, 199, 21, 50, 201, 52, 243, 15, 28, 20, 10, 199, 16, 83, 132, 72, 243, 15, 28, 20, 9, 198, 77, 2, 79, 56, 84, 133, 20, 9, 198, 52, 20, 137, 56, 84, 133, 20, 9, 198, 29, 37, 78, 16, 84, 133, 20, 9, 198, 28, 20, 129, 28, 84, 133, 20, 9, 198, 24, 145, 213, 72, 84, 133, 20, 9, 198, 81, 38, 75, 44, 84, 137, 20, 9, 198, 76, 225, 82, 64, 84, 137, 20, 9, 198, 76, 180, 137, 88, 84, 137, 20, 10, 199, 48, 19, 135, 52, 241, 9, 28, 20, 10, 199, 24, 244, 133, 56, 83, 9, 28, 20, 10, 199, 32, 83, 22, 21, 66, 83, 44, 20, 10, 199, 20, 226, 204, 37, 66, 83, 44, 20, 10, 199, 20, 224, 217, 44, 194, 83, 44, 20, 10, 199, 8, 84, 130, 21, 34, 83, 44, 20, 12, 201, 81, 148, 15, 80, 82, 206, 36, 177, 82, 20, 15, 140, 16, 18, 15, 16, 195, 166, 4, 5, 21, 20, 9, 11, 20, 10, 199, 77, 65, 78, 60, 116, 129, 24, 20, 10, 199, 48, 19, 135, 4, 117, 9, 28, 20, 12, 137, 6, 195, 184, 4, 19, 5, 12, 1, 18, 20, 6, 1, 38, 114, 58, 0, 0, 9, 198, 36, 225, 21, 45, 67, 210, 20, 7, 196, 64, 241, 83, 36, 20, 13, 138, 195, 166, 11, 22, 9, 22, 1, 12, 5, 18, 20, 7, 196, 64, 19, 137, 44, 20, 11, 200, 64, 243, 148, 36, 98, 75, 5, 64, 20, 13, 1, 39, 35, 48, 39, 89, 47, 34, 6, 114, 83, 0, 0, 12, 201, 81, 33, 80, 4, 224, 84, 36, 243, 128, 20, 12, 201, 65, 35, 198, 4, 224, 84, 36, 243, 128, 20, 12, 201, 44, 243, 208, 21, 32, 84, 36, 243, 128, 20, 12, 201, 36, 228, 203, 72, 148, 20, 36, 243, 128, 20, 12, 201, 36, 226, 193, 72, 224, 84, 36, 243, 128, 20, 12, 201, 25, 37, 83, 81, 32, 84, 36, 243, 128, 20, 12, 201, 21, 96, 80, 61, 32, 84, 36, 243, 128, 20, 12, 201, 16, 84, 18, 5, 96, 84, 36, 243, 128, 20, 12, 201, 5, 36, 133, 77, 64, 84, 36, 243, 128, 20, 12, 201, 4, 97, 133, 45, 64, 84, 36, 243, 128, 20, 12, 201, 4, 48, 197, 65, 64, 84, 36, 243, 128, 20, 8, 197, 44, 20, 130, 60, 192, 20, 12, 201, 12, 19, 9, 24, 244, 142, 36, 83, 128, 20, 8, 197, 4, 180, 201, 4, 192, 20, 7, 65, 40, 57, 114, 86, 0, 0, 9, 198, 81, 148, 9, 76, 84, 128, 20, 9, 198, 80, 243, 5, 72, 84, 128, 20, 9, 198, 77, 81, 134, 48, 84, 128, 20, 9, 198, 77, 64, 71, 56, 84, 128, 20, 9, 198, 76, 84, 1, 72, 84, 128, 20, 15, 204, 65, 35, 198, 21, 52, 201, 60, 224, 76, 37, 49, 82, 20, 9, 198, 52, 83, 129, 28, 84, 128, 20, 9, 198, 44, 243, 15, 72, 84, 128, 20, 9, 198, 36, 243, 137, 76, 84, 128, 20, 9, 198, 28, 19, 15, 56, 84, 128, 20, 9, 198, 21, 64, 66, 48, 84, 128, 20, 9, 198, 16, 19, 137, 76, 84, 128, 20, 9, 198, 5, 97, 82, 80, 84, 128, 20, 9, 198, 4, 67, 213, 12, 84, 128, 20, 12, 201, 44, 148, 211, 20, 210, 83, 76, 84, 137, 20, 13, 202, 77, 147, 139, 72, 85, 9, 77, 66, 83, 44, 20, 13, 202, 76, 84, 1, 72, 21, 9, 77, 66, 83, 44, 20, 13, 202, 52, 147, 137, 52, 19, 9, 77, 66, 83, 44, 20, 13, 202, 25, 32, 71, 52, 83, 148, 5, 34, 83, 44, 20, 13, 202, 24, 147, 1, 80, 83, 9, 77, 66, 83, 44, 20, 13, 202, 16, 242, 213, 52, 83, 148, 5, 34, 83, 44, 20, 13, 202, 5, 34, 201, 80, 82, 212, 60, 226, 83, 44, 20, 9, 198, 16, 148, 137, 28, 83, 148, 20, 0, 12, 201, 44, 243, 131, 20, 229, 18, 5, 67, 210, 20, 10, 199, 44, 244, 205, 60, 195, 199, 36, 20, 12, 201, 4, 32, 146, 21, 98, 65, 80, 147, 206, 20, 10, 199, 36, 225, 22, 20, 225, 9, 28, 20, 10, 199, 104, 243, 204, 60, 114, 83, 44, 20, 10, 199, 24, 244, 133, 57, 50, 83, 44, 20, 10, 199, 9, 84, 141, 21, 50, 83, 44, 20, 9, 198, 53, 149, 15, 52, 19, 137, 20, 9, 198, 104, 147, 206, 37, 51, 69, 20, 10, 199, 36, 229, 5, 56, 64, 78, 80, 20, 10, 199, 5, 4, 5, 48, 192, 78, 80, 20, 15, 1, 42, 6, 35, 89, 72, 110, 34, 4, 37, 89, 81, 0, 27, 0, 19, 72, 8, 82, 71, 56, 85, 4, 20, 160, 71, 36, 68, 36, 72, 35, 57, 0, 66, 13, 138, 195, 166, 19, 20, 5, 20, 9, 19, 5, 18, 20, 7, 196, 49, 84, 9, 56, 20, 11, 200, 44, 243, 148, 72, 243, 12, 4, 32, 20, 11, 200, 36, 224, 67, 12, 84, 20, 4, 32, 20, 8, 1, 43, 48, 55, 40, 89, 0, 0, 12, 201, 52, 19, 137, 65, 83, 1, 80, 244, 128, 20, 12, 201, 44, 243, 80, 72, 147, 65, 80, 244, 128, 20, 12, 201, 44, 148, 143, 65, 32, 75, 80, 244, 128, 20, 8, 197, 8, 81, 21, 36, 224, 67, 12, 201, 81, 32, 78, 76, 101, 78, 16, 84, 128, 20, 12, 201, 77, 147, 139, 72, 243, 137, 76, 84, 128, 20, 8, 197, 76, 145, 206, 21, 32, 20, 12, 201, 52, 18, 193, 16, 19, 73, 76, 84, 128, 20, 12, 201, 44, 243, 132, 37, 66, 79, 56, 84, 128, 20, 12, 201, 44, 195, 210, 60, 99, 210, 52, 84, 128, 20, 12, 201, 44, 192, 83, 76, 145, 137, 12, 84, 128, 20, 8, 197, 33, 145, 18, 21, 32, 20, 8, 197, 25, 84, 142, 21, 32, 20, 12, 201, 20, 180, 212, 72, 21, 129, 28, 84, 128, 20, 12, 201, 77, 64, 84, 37, 53, 9, 44, 84, 128, 20, 12, 201, 76, 179, 204, 5, 53, 9, 44, 84, 128, 20, 12, 201, 76, 19, 135, 88, 147, 137, 44, 84, 128, 20, 12, 201, 60, 36, 212, 21, 68, 137, 44, 84, 128, 20, 12, 201, 4, 194, 207, 32, 243, 9, 44, 84, 128, 20, 8, 197, 8, 81, 21, 36, 224, 20, 11, 136, 13, 25, 24, 195, 184, 4, 5, 13, 20, 8, 197, 48, 147, 133, 4, 192, 20, 8, 197, 48, 16, 137, 4, 192, 20, 12, 201, 65, 35, 212, 84, 33, 82, 4, 228, 192, 20, 7, 65, 44, 49, 113, 12, 0, 0, 9, 198, 56, 21, 137, 28, 84, 128, 20, 9, 198, 16, 82, 207, 72, 84, 128, 20, 13, 202, 44, 147, 133, 76, 147, 204, 60, 114, 83, 44, 20, 12, 201, 72, 85, 137, 76, 147, 206, 37, 51, 69, 20, 9, 198, 76, 180, 137, 8, 83, 148, 20, 9, 198, 61, 4, 15, 56, 83, 148, 20, 9, 198, 25, 33, 75, 88, 83, 148, 20, 14, 139, 195, 166, 11, 22, 9, 22, 1, 12, 5, 14, 19, 20, 9, 198, 41, 80, 137, 48, 20, 128, 20, 0, 9, 67, 28, 149, 128, 81, 6, 37, 0, 10, 199, 44, 243, 132, 20, 228, 207, 72, 20, 16, 141, 7, 18, 195, 184, 14, 12, 1, 14, 4, 9, 19, 5, 18, 20, 9, 198, 32, 81, 197, 52, 243, 137, 20, 9, 198, 76, 192, 86, 36, 225, 5, 20, 14, 139, 195, 166, 11, 22, 9, 22, 1, 12, 5, 14, 20, 20, 10, 199, 81, 34, 75, 61, 64, 71, 20, 20, 0, 11, 200, 81, 32, 78, 77, 2, 82, 21, 32, 20, 11, 200, 81, 32, 78, 76, 97, 82, 21, 32, 20, 11, 200, 76, 19, 139, 80, 147, 206, 21, 32, 20, 11, 200, 64, 20, 129, 29, 32, 70, 21, 32, 20, 15, 204, 61, 1, 82, 5, 66, 79, 56, 19, 9, 76, 84, 128, 20, 11, 200, 60, 34, 133, 45, 66, 86, 21, 32, 20, 11, 200, 44, 147, 15, 52, 85, 18, 21, 32, 20, 11, 200, 36, 229, 5, 73, 97, 78, 21, 32, 20, 11, 200, 28, 20, 142, 37, 51, 206, 21, 32, 20, 11, 200, 77, 147, 66, 36, 245, 9, 76, 176, 20, 11, 200, 44, 148, 137, 8, 21, 9, 76, 176, 20, 11, 200, 20, 226, 71, 52, 21, 9, 76, 176, 20, 11, 200, 4, 193, 77, 4, 227, 137, 76, 176, 20, 15, 204, 64, 20, 140, 4, 209, 78, 80, 20, 137, 44, 84, 128, 20, 7, 196, 77, 67, 205, 36, 20, 11, 200, 65, 35, 214, 36, 228, 201, 4, 224, 20, 11, 200, 9, 32, 78, 16, 84, 201, 4, 224, 20, 9, 198, 64, 20, 148, 37, 48, 78, 21, 11, 200, 44, 21, 5, 28, 244, 137, 4, 192, 20, 14, 1, 47, 89, 81, 51, 114, 89, 72, 34, 35, 37, 0, 27, 0, 12, 201, 56, 243, 69, 56, 179, 1, 80, 244, 128, 20, 12, 201, 4, 178, 213, 53, 83, 1, 80, 244, 128, 20, 12, 201, 76, 243, 9, 16, 20, 137, 76, 84, 128, 20, 12, 201, 76, 82, 213, 48, 20, 137, 76, 84, 128, 20, 12, 201, 72, 82, 207, 28, 227, 211, 12, 84, 128, 20, 12, 201, 52, 147, 9, 80, 20, 137, 76, 84, 128, 20, 12, 201, 44, 243, 139, 72, 85, 9, 76, 84, 128, 20, 12, 201, 36, 65, 78, 80, 145, 137, 12, 84, 128, 20, 8, 197, 32, 19, 22, 21, 32, 20, 8, 197, 24, 195, 210, 21, 32, 20, 8, 197, 65, 35, 211, 37, 64, 20, 8, 197, 64, 192, 75, 5, 64, 20, 6, 65, 48, 109, 55, 0, 10, 67, 33, 99, 210, 84, 6, 114, 34, 0, 0, 9, 198, 52, 19, 20, 61, 49, 64, 20, 9, 198, 16, 144, 77, 4, 229, 0, 20, 11, 70, 92, 130, 80, 12, 244, 132, 21, 0, 10, 0, 9, 198, 77, 68, 153, 28, 84, 137, 20, 10, 199, 76, 179, 205, 4, 113, 82, 36, 20, 10, 199, 64, 20, 134, 84, 209, 82, 36, 20, 14, 203, 20, 193, 75, 81, 35, 211, 80, 21, 9, 76, 176, 20, 0, 9, 198, 44, 243, 132, 37, 67, 210, 20, 9, 198, 25, 83, 132, 5, 67, 210, 20, 9, 198, 16, 146, 212, 5, 67, 210, 20, 9, 198, 8, 85, 129, 81, 35, 206, 20, 11, 200, 77, 80, 147, 45, 34, 66, 21, 32, 20, 11, 200, 65, 35, 211, 45, 34, 66, 21, 32, 20, 12, 137, 1, 6, 8, 195, 166, 14, 7, 9, 7, 20, 11, 200, 52, 21, 18, 36, 20, 139, 5, 64, 20, 9, 68, 13, 148, 149, 76, 21, 0, 10, 0, 12, 201, 8, 84, 212, 36, 19, 9, 80, 85, 0, 69, 12, 201, 85, 53, 1, 8, 147, 9, 80, 85, 0, 20, 12, 201, 76, 83, 147, 84, 19, 9, 80, 85, 0, 20, 12, 201, 36, 229, 129, 48, 145, 9, 80, 85, 0, 20, 12, 201, 36, 211, 79, 8, 147, 9, 80, 85, 0, 20, 12, 201, 36, 195, 5, 28, 19, 9, 80, 85, 0, 20, 12, 201, 8, 84, 212, 36, 19, 9, 80, 85, 0, 20, 12, 201, 4, 224, 201, 20, 227, 137, 80, 85, 0, 20, 12, 201, 77, 65, 87, 5, 33, 5, 77, 49, 64, 20, 9, 198, 25, 33, 75, 88, 83, 147, 20, 9, 198, 77, 80, 147, 80, 19, 147, 20, 6, 65, 52, 109, 65, 0, 0, 9, 198, 60, 181, 1, 28, 243, 128, 20, 9, 198, 88, 84, 147, 36, 243, 128, 20, 9, 198, 61, 96, 84, 36, 243, 128, 20, 9, 198, 24, 148, 211, 36, 243, 128, 20, 6, 195, 52, 83, 147, 8, 0, 10, 199, 52, 147, 133, 72, 19, 15, 28, 20, 10, 199, 45, 33, 77, 48, 243, 15, 28, 20, 10, 199, 45, 83, 20, 85, 35, 9, 28, 20, 10, 199, 28, 83, 5, 4, 117, 9, 28, 20, 10, 199, 80, 83, 210, 21, 66, 83, 44, 20, 10, 199, 80, 19, 201, 77, 66, 83, 44, 20, 10, 199, 76, 241, 137, 77, 66, 83, 44, 20, 10, 199, 56, 83, 204, 37, 66, 83, 44, 20, 10, 199, 56, 82, 210, 61, 66, 83, 44, 20, 10, 199, 52, 243, 137, 77, 66, 83, 44, 20, 10, 199, 20, 193, 75, 81, 34, 83, 44, 20, 10, 199, 4, 224, 76, 101, 66, 83, 44, 20, 10, 199, 44, 20, 148, 60, 116, 129, 24, 20, 0, 11, 200, 20, 194, 77, 36, 224, 84, 61, 32, 20, 14, 68, 92, 17, 207, 56, 84, 110, 81, 6, 114, 68, 0, 20, 9, 198, 64, 192, 83, 81, 35, 206, 20, 15, 204, 29, 32, 77, 52, 21, 9, 44, 19, 9, 80, 85, 0, 20, 12, 201, 33, 145, 210, 61, 50, 207, 64, 148, 203, 20, 7, 196, 60, 35, 9, 44, 20, 11, 200, 64, 21, 18, 36, 20, 139, 5, 64, 20, 0, 8, 197, 104, 243, 204, 60, 112, 20, 12, 201, 81, 32, 78, 76, 192, 84, 36, 243, 128, 20, 12, 201, 77, 1, 75, 84, 192, 84, 36, 243, 128, 20, 12, 201, 72, 84, 197, 73, 96, 84, 36, 243, 128, 20, 12, 201, 65, 35, 199, 72, 84, 211, 36, 243, 128, 20, 12, 201, 64, 84, 134, 61, 32, 84, 36, 243, 128, 20, 12, 201, 60, 36, 197, 73, 96, 84, 36, 243, 128, 20, 12, 201, 48, 19, 69, 57, 64, 84, 36, 243, 128, 20, 12, 201, 45, 83, 13, 36, 224, 84, 36, 243, 128, 20, 12, 201, 44, 243, 147, 84, 212, 20, 36, 243, 128, 20, 12, 201, 44, 243, 142, 61, 64, 84, 36, 243, 128, 20, 12, 201, 44, 243, 80, 5, 32, 84, 36, 243, 128, 20, 12, 201, 44, 243, 77, 85, 64, 84, 36, 243, 128, 20, 12, 201, 44, 243, 66, 36, 224, 84, 36, 243, 128, 20, 12, 201, 44, 19, 11, 84, 192, 84, 36, 243, 128, 20, 12, 201, 36, 229, 5, 29, 32, 84, 36, 243, 128, 20, 12, 201, 36, 228, 208, 37, 32, 84, 36, 243, 128, 20, 12, 201, 36, 225, 9, 28, 224, 84, 36, 243, 128, 20, 12, 201, 29, 32, 84, 84, 192, 84, 36, 243, 128, 20, 12, 201, 20, 180, 193, 49, 64, 84, 36, 243, 128, 20, 12, 201, 16, 84, 212, 36, 224, 84, 36, 243, 128, 20, 12, 201, 16, 84, 203, 72, 148, 20, 36, 243, 128, 20, 12, 201, 16, 84, 197, 73, 64, 84, 36, 243, 128, 20, 12, 201, 16, 84, 15, 73, 64, 84, 36, 243, 128, 20, 12, 201, 16, 82, 204, 36, 224, 84, 36, 243, 128, 20, 12, 201, 8, 19, 12, 61, 64, 84, 36, 243, 128, 20, 12, 201, 5, 69, 5, 77, 64, 84, 36, 243, 128, 20, 12, 201, 5, 4, 18, 60, 32, 84, 36, 243, 128, 20, 12, 201, 4, 36, 197, 57, 64, 84, 36, 243, 128, 20, 12, 201, 84, 226, 70, 61, 35, 73, 80, 85, 0, 20, 12, 201, 72, 17, 9, 44, 19, 9, 80, 85, 0, 20, 12, 201, 44, 20, 1, 8, 147, 9, 80, 85, 0, 20, 12, 201, 32, 243, 79, 28, 83, 137, 80, 85, 0, 20, 12, 201, 72, 81, 133, 45, 67, 210, 37, 83, 64, 20, 12, 201, 65, 35, 214, 37, 51, 210, 37, 83, 64, 20, 12, 201, 45, 33, 77, 5, 67, 210, 37, 83, 64, 20, 8, 197, 44, 243, 15, 56, 144, 20, 12, 201, 81, 32, 78, 77, 3, 210, 80, 21, 0, 20, 9, 198, 36, 212, 5, 16, 19, 147, 20, 6, 65, 56, 109, 50, 0, 9, 5, 95, 48, 1, 14, 4, 114, 0, 0, 10, 135, 6, 21, 18, 9, 195, 184, 19, 20, 9, 198, 44, 193, 82, 21, 50, 64, 20, 9, 198, 40, 19, 15, 85, 50, 64, 20, 13, 202, 28, 20, 212, 72, 244, 203, 61, 2, 83, 44, 20, 13, 202, 20, 193, 75, 81, 35, 204, 101, 66, 83, 44, 20, 13, 202, 4, 229, 1, 28, 243, 137, 77, 66, 83, 44, 20, 13, 202, 4, 224, 75, 72, 243, 137, 77, 66, 83, 44, 20, 9, 198, 36, 225, 5, 12, 83, 148, 20, 9, 198, 20, 179, 1, 80, 19, 148, 20, 0, 11, 136, 16, 18, 5, 20, 9, 195, 184, 19, 20, 12, 137, 9, 14, 6, 5, 18, 9, 195, 184, 18, 20, 10, 199, 76, 213, 75, 44, 84, 197, 72, 20, 10, 199, 48, 85, 19, 36, 225, 9, 28, 20, 10, 199, 76, 195, 214, 4, 178, 83, 44, 20, 10, 199, 72, 148, 5, 57, 50, 83, 44, 20, 10, 199, 28, 83, 203, 20, 210, 83, 44, 20, 10, 199, 21, 2, 68, 20, 210, 83, 44, 20, 10, 199, 20, 196, 193, 77, 50, 83, 44, 20, 10, 199, 52, 83, 15, 16, 146, 197, 72, 20, 9, 198, 77, 97, 67, 37, 51, 69, 20, 9, 198, 76, 192, 86, 37, 51, 69, 20, 12, 201, 44, 243, 4, 36, 225, 197, 57, 49, 82, 20, 12, 201, 44, 243, 132, 37, 66, 79, 56, 19, 0, 20, 10, 199, 52, 20, 141, 20, 192, 68, 20, 20, 0, 12, 137, 13, 9, 14, 21, 20, 9, 195, 184, 19, 20, 12, 137, 13, 5, 12, 15, 4, 9, 195, 184, 19, 20, 13, 138, 5, 11, 19, 20, 5, 18, 9, 195, 184, 18, 20, 11, 200, 44, 147, 133, 76, 147, 204, 60, 112, 20, 15, 204, 81, 32, 78, 77, 3, 1, 57, 64, 84, 36, 243, 128, 20, 15, 204, 36, 228, 212, 73, 83, 69, 57, 64, 84, 36, 243, 128, 20, 15, 204, 36, 211, 65, 81, 34, 75, 84, 192, 84, 36, 243, 128, 20, 15, 204, 76, 83, 148, 36, 209, 78, 80, 19, 9, 80, 85, 0, 20, 15, 204, 72, 84, 208, 20, 181, 1, 8, 147, 9, 80, 85, 0, 20, 11, 200, 52, 241, 21, 48, 84, 137, 56, 112, 20, 11, 200, 4, 212, 21, 80, 84, 137, 56, 112, 20, 11, 200, 88, 148, 148, 84, 244, 197, 72, 144, 20, 11, 200, 65, 35, 212, 20, 147, 146, 36, 112, 20, 11, 200, 77, 80, 129, 72, 181, 9, 76, 176, 20, 11, 200, 65, 32, 71, 52, 21, 9, 76, 176, 20, 11, 200, 33, 148, 15, 80, 85, 9, 76, 176, 20, 11, 200, 21, 96, 78, 28, 83, 9, 76, 176, 20, 11, 200, 13, 148, 18, 36, 245, 9, 76, 176, 20, 9, 198, 41, 85, 133, 56, 147, 0, 20, 9, 198, 24, 241, 5, 72, 19, 0, 20, 0, 10, 135, 6, 1, 18, 3, 195, 184, 18, 20, 8, 197, 4, 211, 133, 76, 144, 20, 8, 197, 28, 226, 69, 72, 144, 20, 16, 205, 20, 180, 208, 72, 84, 211, 36, 243, 137, 77, 66, 83, 44, 20, 8, 197, 84, 224, 201, 4, 192, 20, 5, 65, 60, 39, 0, 0, 11, 136, 4, 18, 5, 19, 19, 195, 184, 18, 20, 9, 198, 61, 0, 67, 37, 65, 84, 20, 9, 198, 85, 53, 82, 64, 84, 128, 20, 9, 198, 72, 85, 83, 76, 84, 128, 20, 9, 198, 61, 0, 76, 37, 49, 82, 20, 9, 198, 60, 33, 21, 12, 84, 128, 20, 9, 198, 52, 245, 83, 76, 84, 128, 20, 9, 198, 44, 20, 21, 56, 84, 128, 20, 9, 198, 36, 229, 21, 8, 84, 128, 20, 9, 198, 36, 229, 15, 56, 84, 128, 20, 9, 198, 36, 225, 21, 12, 84, 128, 20, 9, 198, 8, 20, 213, 56, 84, 128, 20, 9, 198, 4, 195, 15, 44, 84, 128, 20, 11, 200, 61, 0, 153, 28, 113, 76, 36, 112, 20, 13, 202, 45, 34, 77, 36, 227, 204, 60, 114, 83, 44, 20, 13, 202, 32, 84, 144, 21, 67, 204, 60, 114, 83, 44, 20, 12, 201, 32, 148, 212, 61, 34, 67, 37, 51, 69, 20, 12, 201, 21, 81, 1, 36, 211, 206, 37, 51, 69, 20, 12, 201, 20, 179, 5, 45, 66, 67, 37, 51, 69, 20, 12, 201, 8, 82, 1, 88, 147, 210, 37, 51, 69, 20, 12, 201, 4, 115, 143, 77, 66, 67, 37, 51, 69, 20, 6, 195, 61, 0, 76, 20, 10, 1, 61, 55, 6, 37, 65, 36, 86, 0, 0, 19, 71, 48, 81, 197, 56, 65, 82, 76, 55, 36, 81, 6, 109, 50, 72, 114, 89, 0, 9, 198, 17, 85, 133, 80, 147, 133, 20, 10, 199, 13, 146, 204, 61, 68, 143, 56, 20, 10, 199, 77, 84, 16, 72, 147, 69, 72, 20, 10, 199, 44, 243, 80, 72, 147, 69, 72, 20, 10, 199, 36, 225, 140, 4, 211, 69, 72, 20, 10, 199, 5, 37, 9, 45, 83, 5, 72, 20, 14, 203, 44, 20, 146, 36, 84, 133, 52, 17, 197, 72, 144, 20, 10, 199, 52, 147, 12, 20, 227, 137, 20, 20, 10, 199, 8, 20, 201, 48, 146, 213, 52, 20, 10, 199, 44, 243, 147, 36, 194, 85, 52, 20, 9, 198, 80, 16, 200, 37, 51, 69, 20, 9, 198, 52, 20, 152, 37, 51, 69, 20, 9, 198, 16, 17, 1, 37, 51, 69, 20, 12, 201, 44, 243, 148, 36, 225, 78, 80, 19, 0, 20, 0, 11, 200, 76, 147, 143, 48, 241, 201, 76, 176, 20, 11, 200, 64, 21, 15, 48, 241, 201, 76, 176, 20, 11, 200, 60, 226, 207, 48, 241, 201, 76, 176, 20, 11, 200, 56, 244, 141, 4, 227, 137, 76, 176, 20, 11, 200, 44, 21, 5, 44, 85, 9, 76, 176, 20, 11, 200, 36, 66, 79, 52, 21, 9, 76, 176, 20, 11, 200, 24, 243, 143, 48, 241, 201, 76, 176, 20, 11, 200, 24, 193, 71, 52, 21, 9, 76, 176, 20, 9, 198, 36, 208, 133, 12, 147, 0, 20, 11, 200, 45, 38, 80, 80, 241, 210, 4, 96, 20, 0, 12, 201, 72, 146, 207, 12, 129, 84, 80, 84, 128, 20, 12, 201, 44, 21, 5, 28, 244, 137, 76, 84, 128, 20, 12, 201, 36, 229, 5, 73, 1, 76, 48, 84, 128, 20, 12, 201, 12, 130, 70, 24, 243, 142, 36, 84, 128, 20, 12, 201, 12, 83, 148, 72, 145, 149, 28, 84, 128, 20, 12, 201, 56, 244, 212, 4, 193, 201, 44, 84, 128, 20, 6, 65, 64, 48, 36, 0, 15, 1, 64, 89, 50, 4, 110, 12, 71, 36, 55, 6, 110, 12, 0, 0, 18, 70, 12, 128, 78, 76, 243, 128, 91, 57, 112, 50, 89, 6, 114, 68, 0, 20, 9, 198, 64, 243, 25, 28, 243, 128, 20, 9, 198, 61, 37, 15, 28, 243, 128, 20, 9, 198, 61, 2, 78, 36, 243, 128, 20, 9, 198, 61, 3, 211, 77, 83, 64, 20, 9, 198, 72, 82, 214, 37, 50, 84, 20, 9, 198, 65, 70, 65, 48, 147, 128, 20, 12, 201, 64, 20, 129, 48, 193, 76, 37, 51, 69, 20, 12, 201, 56, 21, 9, 60, 224, 76, 37, 51, 69, 20, 12, 201, 44, 19, 142, 36, 32, 76, 37, 51, 69, 20, 9, 198, 9, 33, 84, 4, 115, 128, 20, 9, 198, 65, 33, 83, 20, 229, 0, 20, 9, 198, 53, 149, 15, 52, 19, 128, 21, 11, 70, 64, 20, 211, 92, 244, 132, 21, 0, 10, 0, 11, 67, 76, 145, 192, 89, 35, 57, 0, 14, 45, 17, 67, 76, 145, 192, 89, 37, 15, 84, 110, 0, 81, 104, 118, 97, 100, 32, 17, 67, 76, 145, 192, 89, 37, 15, 65, 35, 57, 0, 81, 109, 105, 103, 32, 10, 199, 24, 195, 210, 4, 116, 129, 52, 20, 9, 198, 64, 193, 84, 80, 84, 133, 20, 9, 198, 9, 34, 76, 48, 84, 133, 20, 9, 198, 4, 64, 80, 80, 84, 133, 20, 9, 198, 77, 2, 78, 16, 84, 137, 20, 9, 198, 52, 83, 129, 28, 84, 137, 20, 10, 199, 65, 35, 211, 12, 83, 137, 20, 20, 6, 195, 84, 226, 84, 20, 14, 203, 12, 132, 137, 77, 66, 65, 57, 50, 1, 88, 224, 20, 6, 195, 76, 145, 192, 72, 0, 9, 198, 45, 84, 148, 37, 49, 82, 20, 0, 12, 201, 81, 34, 86, 36, 19, 9, 80, 85, 0, 20, 12, 201, 76, 82, 211, 84, 19, 9, 80, 85, 0, 20, 12, 201, 72, 83, 1, 80, 149, 137, 80, 85, 0, 20, 12, 201, 56, 245, 1, 8, 147, 9, 80, 85, 0, 20, 12, 201, 53, 84, 201, 44, 19, 9, 80, 85, 0, 20, 12, 201, 17, 84, 129, 8, 147, 9, 80, 85, 0, 20, 10, 135, 16, 12, 195, 166, 4, 5, 18, 20, 8, 197, 77, 69, 80, 36, 64, 20, 12, 201, 36, 229, 5, 73, 33, 71, 57, 83, 64, 20, 12, 201, 44, 20, 18, 36, 99, 204, 37, 83, 64, 20, 12, 201, 36, 229, 5, 72, 209, 68, 37, 83, 64, 20, 12, 201, 4, 229, 5, 64, 83, 132, 37, 83, 64, 20, 6, 65, 68, 49, 40, 0, 0, 12, 201, 65, 35, 212, 60, 179, 204, 48, 84, 133, 20, 12, 201, 16, 148, 195, 37, 3, 9, 56, 84, 133, 20, 12, 201, 52, 20, 139, 76, 180, 137, 28, 84, 137, 20, 9, 198, 88, 20, 137, 4, 229, 0, 20, 0, 10, 199, 76, 225, 68, 44, 84, 133, 72, 20, 12, 201, 72, 21, 9, 60, 224, 76, 37, 49, 82, 20, 12, 201, 64, 84, 147, 60, 224, 76, 37, 49, 82, 20, 12, 201, 64, 20, 129, 48, 193, 76, 37, 49, 82, 20, 12, 201, 52, 20, 135, 36, 224, 76, 37, 49, 82, 20, 12, 201, 45, 34, 77, 36, 224, 76, 37, 49, 82, 20, 12, 201, 36, 229, 5, 72, 224, 76, 37, 49, 82, 20, 10, 199, 20, 180, 208, 48, 244, 133, 72, 20, 10, 199, 76, 83, 73, 61, 66, 83, 44, 20, 10, 199, 61, 53, 9, 56, 66, 83, 44, 20, 10, 199, 20, 97, 77, 21, 34, 83, 44, 20, 10, 199, 17, 32, 86, 36, 66, 83, 44, 20, 10, 199, 16, 145, 1, 45, 66, 83, 44, 20, 10, 199, 9, 84, 149, 56, 66, 83, 44, 20, 10, 199, 4, 181, 129, 52, 20, 137, 56, 20, 12, 201, 32, 84, 142, 36, 225, 197, 57, 49, 82, 20, 10, 199, 72, 17, 9, 60, 116, 129, 24, 20, 10, 199, 44, 19, 12, 36, 116, 129, 24, 20, 10, 199, 72, 80, 197, 57, 49, 78, 80, 20, 10, 199, 44, 243, 135, 73, 81, 78, 80, 20, 0, 9, 198, 88, 144, 146, 5, 67, 210, 20, 15, 204, 36, 228, 212, 73, 83, 69, 57, 64, 76, 37, 53, 0, 20, 9, 198, 28, 197, 75, 4, 115, 206, 20, 15, 204, 77, 147, 139, 72, 240, 217, 44, 195, 212, 72, 243, 128, 20, 14, 68, 76, 19, 15, 56, 89, 110, 55, 6, 114, 68, 0, 20, 9, 198, 72, 83, 1, 80, 147, 206, 20, 10, 135, 13, 195, 166, 14, 1, 4, 5, 20, 6, 195, 28, 17, 197, 20, 0, 9, 198, 104, 83, 15, 80, 148, 203, 20, 9, 198, 77, 147, 143, 16, 148, 203, 20, 9, 198, 64, 192, 83, 80, 148, 203, 20, 9, 198, 52, 83, 15, 16, 148, 203, 20, 9, 198, 36, 66, 79, 80, 148, 203, 20, 9, 198, 20, 192, 83, 80, 148, 203, 20, 8, 197, 80, 84, 141, 36, 224, 20, 8, 197, 52, 244, 137, 4, 224, 21, 6, 65, 72, 109, 34, 0, 0, 13, 202, 84, 226, 70, 61, 35, 73, 77, 66, 83, 44, 20, 13, 202, 77, 65, 82, 20, 243, 69, 81, 34, 83, 44, 20, 13, 202, 44, 243, 134, 61, 35, 73, 77, 66, 83, 44, 20, 13, 202, 44, 20, 9, 80, 19, 9, 77, 66, 83, 44, 20, 13, 202, 36, 229, 5, 72, 147, 73, 77, 66, 83, 44, 20, 13, 202, 24, 83, 142, 61, 50, 193, 56, 66, 83, 44, 20, 13, 202, 12, 83, 148, 72, 19, 9, 77, 66, 83, 44, 20, 9, 198, 16, 84, 15, 56, 83, 148, 20, 13, 70, 13, 35, 209, 84, 148, 192, 21, 102, 114, 0, 10, 8, 67, 48, 243, 203, 21, 0, 10, 0, 10, 199, 80, 16, 149, 48, 21, 15, 72, 20, 10, 199, 36, 226, 1, 48, 21, 15, 72, 20, 12, 201, 16, 83, 79, 57, 53, 18, 5, 67, 210, 20, 9, 198, 80, 244, 15, 48, 241, 201, 20, 9, 198, 76, 86, 15, 48, 241, 201, 20, 9, 198, 9, 38, 79, 48, 241, 201, 20, 12, 201, 72, 21, 9, 32, 16, 137, 80, 147, 206, 20, 12, 201, 65, 35, 211, 80, 149, 21, 80, 147, 206, 20, 12, 201, 44, 243, 147, 80, 149, 21, 80, 147, 206, 20, 12, 201, 44, 243, 147, 36, 115, 129, 80, 147, 206, 20, 12, 201, 36, 226, 193, 52, 147, 129, 80, 147, 206, 20, 12, 201, 36, 195, 21, 52, 147, 129, 80, 147, 206, 20, 12, 201, 24, 144, 146, 36, 195, 1, 80, 147, 206, 20, 10, 199, 52, 19, 20, 21, 50, 83, 44, 20, 10, 199, 72, 82, 214, 37, 33, 78, 80, 20, 10, 199, 44, 243, 80, 21, 65, 78, 80, 20, 10, 199, 72, 84, 208, 20, 181, 1, 8, 20, 9, 198, 25, 84, 197, 48, 17, 197, 20, 9, 198, 4, 97, 149, 80, 17, 197, 20, 8, 67, 80, 129, 64, 21, 0, 10, 0, 7, 196, 53, 147, 211, 20, 20, 7, 196, 64, 147, 143, 48, 20, 12, 201, 64, 20, 129, 48, 192, 75, 80, 148, 203, 20, 12, 201, 56, 245, 133, 48, 194, 83, 80, 148, 203, 20, 12, 201, 52, 241, 5, 72, 226, 83, 80, 148, 203, 20, 12, 201, 52, 20, 207, 12, 130, 83, 80, 148, 203, 20, 12, 201, 44, 243, 77, 84, 226, 83, 80, 148, 203, 20, 12, 201, 32, 148, 212, 61, 34, 83, 80, 148, 203, 20, 12, 201, 25, 148, 201, 60, 115, 143, 52, 148, 203, 20, 11, 200, 65, 35, 206, 60, 210, 78, 4, 192, 20, 9, 198, 5, 4, 5, 48, 192, 66, 20, 0, 8, 197, 81, 34, 66, 85, 64, 20, 8, 197, 77, 64, 82, 85, 64, 20, 12, 201, 65, 35, 208, 61, 37, 9, 60, 225, 76, 20, 8, 197, 20, 229, 18, 21, 32, 20, 16, 205, 25, 83, 132, 4, 209, 78, 80, 19, 9, 77, 66, 83, 44, 20, 8, 197, 77, 2, 78, 4, 192, 20, 8, 197, 64, 197, 82, 4, 192, 20, 8, 197, 28, 195, 194, 4, 192, 20, 6, 65, 76, 36, 89, 0, 0, 13, 202, 53, 83, 20, 37, 3, 9, 44, 21, 15, 72, 20, 15, 140, 4, 9, 19, 3, 9, 16, 12, 9, 14, 195, 166, 18, 20, 12, 201, 77, 0, 83, 80, 144, 201, 80, 85, 0, 20, 11, 200, 77, 0, 84, 36, 84, 137, 56, 112, 20, 9, 198, 77, 0, 84, 36, 84, 128, 20, 10, 199, 77, 0, 78, 45, 83, 5, 72, 20, 9, 198, 77, 0, 76, 36, 84, 133, 20, 9, 198, 77, 0, 68, 76, 84, 128, 20, 13, 202, 76, 84, 137, 21, 4, 143, 17, 80, 197, 72, 20, 12, 201, 77, 0, 82, 76, 243, 77, 20, 194, 71, 20, 9, 198, 77, 0, 78, 36, 243, 0, 20, 11, 200, 77, 0, 83, 52, 241, 9, 76, 176, 20, 9, 198, 77, 0, 82, 80, 19, 128, 20, 8, 197, 77, 0, 71, 5, 64, 20, 0, 10, 199, 45, 99, 212, 21, 34, 78, 28, 20, 10, 199, 28, 20, 132, 21, 34, 78, 28, 20, 10, 199, 17, 80, 140, 21, 34, 78, 28, 20, 18, 67, 48, 241, 192, 55, 114, 49, 6, 36, 50, 0, 44, 20, 81, 105, 110, 32, 0, 11, 200, 44, 244, 205, 21, 67, 204, 60, 112, 20, 11, 200, 56, 20, 131, 37, 52, 201, 77, 64, 20, 11, 200, 44, 192, 83, 76, 144, 201, 77, 64, 20, 13, 138, 16, 18, 195, 166, 3, 9, 19, 9, 15, 14, 20, 11, 200, 16, 148, 212, 36, 225, 214, 21, 32, 20, 7, 196, 45, 33, 79, 48, 20, 11, 200, 81, 148, 15, 48, 241, 201, 76, 176, 20, 11, 200, 77, 145, 137, 48, 149, 9, 76, 176, 20, 11, 200, 76, 84, 143, 48, 241, 201, 76, 176, 20, 11, 200, 21, 67, 143, 48, 241, 201, 76, 176, 20, 11, 200, 21, 2, 76, 21, 5, 9, 76, 176, 20, 11, 200, 9, 84, 135, 84, 225, 9, 76, 176, 20, 11, 200, 13, 84, 146, 36, 53, 76, 84, 208, 20, 11, 200, 80, 83, 80, 21, 33, 82, 21, 64, 20, 11, 200, 72, 84, 201, 28, 225, 82, 21, 64, 20, 11, 200, 72, 17, 134, 36, 225, 82, 21, 64, 20, 11, 200, 48, 19, 69, 48, 193, 82, 21, 64, 20, 11, 200, 36, 226, 193, 72, 225, 82, 21, 64, 20, 11, 200, 16, 148, 12, 60, 209, 82, 21, 64, 20, 11, 200, 16, 85, 1, 48, 161, 82, 21, 64, 20, 12, 137, 9, 14, 8, 195, 166, 18, 5, 14, 19, 20, 0, 8, 197, 88, 144, 146, 21, 32, 20, 8, 197, 76, 84, 150, 21, 32, 20, 9, 198, 32, 84, 129, 48, 66, 75, 20, 12, 201, 25, 148, 201, 60, 115, 143, 52, 146, 192, 20, 8, 197, 60, 181, 76, 5, 32, 20, 8, 197, 28, 20, 129, 57, 64, 20, 10, 69, 76, 84, 150, 21, 32, 21, 0, 10, 0, 9, 198, 76, 86, 15, 48, 241, 192, 20, 9, 198, 21, 67, 143, 48, 241, 192, 20, 9, 198, 81, 84, 130, 36, 225, 64, 20, 9, 198, 80, 84, 154, 36, 225, 64, 20, 9, 198, 24, 244, 134, 36, 225, 64, 20, 9, 198, 21, 50, 193, 64, 148, 212, 20, 13, 202, 76, 81, 9, 52, 83, 148, 21, 34, 78, 28, 20, 13, 202, 65, 35, 214, 36, 19, 148, 21, 34, 78, 28, 20, 12, 201, 48, 81, 19, 4, 113, 82, 36, 225, 5, 20, 6, 195, 84, 226, 75, 20, 9, 198, 80, 19, 135, 20, 229, 0, 20, 9, 198, 44, 20, 132, 36, 224, 76, 20, 0, 9, 198, 52, 19, 137, 13, 84, 133, 20, 10, 199, 72, 84, 197, 73, 98, 83, 80, 20, 10, 199, 12, 19, 22, 36, 226, 83, 80, 20, 10, 199, 28, 20, 212, 72, 243, 143, 52, 20, 14, 203, 76, 83, 22, 8, 147, 199, 72, 17, 137, 76, 176, 20, 10, 199, 80, 18, 211, 60, 227, 205, 36, 20, 10, 199, 44, 243, 135, 73, 81, 78, 76, 20, 0, 7, 196, 81, 83, 79, 72, 20, 7, 196, 80, 83, 143, 72, 20, 9, 198, 25, 83, 139, 80, 147, 206, 20, 9, 198, 25, 34, 75, 80, 147, 206, 20, 9, 198, 21, 33, 75, 80, 147, 206, 20, 11, 200, 76, 181, 129, 17, 35, 206, 21, 32, 20, 7, 196, 44, 243, 9, 44, 20, 11, 200, 44, 243, 77, 37, 69, 5, 57, 64, 20, 11, 200, 65, 32, 75, 80, 146, 193, 57, 64, 20, 11, 200, 5, 84, 203, 84, 197, 1, 57, 64, 20, 0, 8, 197, 8, 240, 137, 56, 80, 20, 13, 138, 195, 166, 18, 22, 195, 166, 18, 4, 9, 7, 20, 12, 201, 76, 224, 75, 44, 84, 193, 48, 145, 192, 20, 13, 138, 18, 5, 20, 6, 195, 166, 18, 4, 9, 7, 20, 12, 201, 60, 212, 212, 36, 195, 5, 48, 145, 192, 20, 12, 201, 60, 36, 212, 21, 35, 129, 76, 145, 192, 20, 13, 138, 2, 15, 4, 6, 195, 166, 18, 4, 9, 7, 20, 12, 201, 8, 148, 203, 61, 4, 5, 48, 145, 192, 20, 9, 198, 64, 21, 5, 80, 148, 203, 20, 9, 198, 44, 84, 129, 52, 148, 203, 20, 9, 198, 20, 212, 1, 80, 148, 203, 20, 9, 198, 17, 37, 73, 16, 148, 203, 20, 10, 69, 92, 147, 132, 61, 112, 21, 0, 10, 6, 65, 84, 40, 19, 0, 0, 9, 198, 5, 85, 15, 65, 50, 64, 20, 9, 198, 88, 149, 1, 48, 148, 212, 20, 13, 202, 88, 83, 148, 72, 147, 15, 45, 98, 83, 80, 20, 13, 202, 64, 84, 139, 85, 52, 201, 60, 226, 83, 80, 20, 13, 202, 36, 225, 5, 80, 84, 141, 36, 226, 83, 80, 20, 9, 198, 36, 65, 65, 48, 148, 212, 20, 13, 202, 25, 83, 139, 80, 147, 206, 4, 194, 83, 80, 20, 13, 202, 16, 242, 213, 52, 83, 148, 5, 34, 83, 80, 20, 14, 139, 195, 184, 13, 20, 195, 165, 12, 5, 12, 9, 7, 20, 14, 139, 20, 18, 25, 11, 6, 195, 166, 18, 4, 9, 7, 20, 14, 139, 19, 16, 1, 7, 6, 195, 166, 18, 4, 9, 7, 20, 14, 139, 19, 12, 1, 7, 6, 195, 166, 18, 4, 9, 7, 20, 14, 139, 19, 1, 14, 4, 6, 195, 166, 18, 4, 9, 7, 20, 14, 139, 16, 18, 9, 19, 22, 195, 166, 18, 4, 9, 7, 20, 14, 139, 15, 16, 19, 195, 166, 20, 20, 5, 12, 9, 7, 20, 14, 139, 15, 13, 19, 195, 166, 20, 20, 5, 12, 9, 7, 20, 14, 139, 15, 13, 7, 195, 166, 14, 7, 5, 12, 9, 7, 20, 9, 198, 5, 35, 79, 16, 145, 192, 20, 14, 139, 1, 14, 20, 195, 166, 14, 4, 5, 12, 9, 7, 20, 14, 139, 1, 6, 19, 195, 166, 20, 20, 5, 12, 9, 7, 20, 0, 18, 71, 72, 82, 137, 12, 84, 133, 72, 34, 36, 57, 37, 89, 6, 36, 114, 0, 10, 199, 29, 32, 77, 52, 241, 143, 56, 20, 12, 201, 36, 229, 5, 72, 161, 75, 80, 147, 206, 20, 15, 140, 22, 9, 4, 5, 18, 22, 195, 166, 18, 4, 9, 7, 20, 15, 140, 19, 20, 18, 1, 6, 22, 195, 166, 18, 4, 9, 7, 20, 15, 140, 11, 21, 14, 19, 20, 6, 195, 166, 18, 4, 9, 7, 20, 15, 140, 6, 15, 18, 19, 195, 184, 13, 13, 5, 12, 9, 7, 20, 15, 140, 6, 15, 18, 19, 13, 195, 166, 4, 5, 12, 9, 7, 20, 15, 140, 6, 15, 18, 6, 195, 166, 18, 4, 5, 12, 9, 7, 20, 10, 199, 88, 19, 149, 5, 66, 83, 44, 20, 10, 199, 80, 83, 12, 85, 34, 83, 44, 20, 10, 199, 72, 17, 129, 20, 194, 83, 44, 20, 10, 199, 65, 35, 211, 60, 66, 83, 44, 20, 10, 199, 64, 84, 137, 60, 66, 83, 44, 20, 10, 199, 45, 80, 137, 77, 66, 83, 44, 20, 10, 199, 21, 51, 212, 21, 34, 83, 44, 20, 10, 199, 17, 32, 75, 60, 226, 83, 44, 20, 10, 199, 5, 4, 137, 61, 34, 83, 44, 20, 10, 199, 4, 192, 77, 60, 66, 83, 44, 20, 10, 199, 4, 115, 143, 77, 66, 83, 44, 20, 9, 198, 32, 20, 141, 60, 226, 69, 20, 9, 198, 8, 84, 153, 48, 194, 69, 20, 10, 199, 76, 49, 78, 60, 116, 129, 24, 20, 10, 199, 72, 84, 18, 60, 116, 129, 24, 20, 10, 199, 64, 19, 148, 60, 116, 129, 24, 20, 0, 9, 198, 32, 82, 211, 4, 115, 206, 20, 7, 196, 80, 19, 15, 56, 20, 9, 198, 64, 244, 201, 80, 147, 206, 20, 11, 200, 52, 81, 9, 12, 147, 133, 72, 80, 20, 16, 141, 22, 5, 12, 195, 166, 18, 22, 195, 166, 18, 4, 9, 7, 20, 15, 204, 76, 19, 77, 20, 226, 204, 5, 4, 5, 48, 145, 192, 20, 16, 141, 15, 22, 5, 18, 19, 195, 166, 20, 20, 5, 12, 9, 7, 20, 15, 204, 28, 83, 142, 20, 212, 203, 36, 227, 133, 48, 145, 192, 20, 12, 201, 5, 34, 83, 80, 245, 5, 48, 148, 203, 20, 9, 198, 48, 149, 15, 72, 19, 0, 20, 0, 8, 197, 65, 35, 204, 60, 112, 20, 8, 197, 61, 67, 204, 60, 112, 20, 8, 197, 48, 85, 133, 72, 80, 20, 9, 198, 49, 146, 211, 4, 194, 71, 20, 17, 142, 12, 5, 20, 1, 14, 20, 195, 166, 14, 4, 5, 12, 9, 7, 20, 17, 142, 8, 195, 184, 10, 195, 166, 18, 22, 195, 166, 18, 4, 9, 7, 20, 9, 198, 4, 228, 197, 20, 194, 71, 20, 8, 197, 5, 32, 76, 36, 80, 20, 12, 201, 61, 37, 15, 12, 84, 129, 80, 149, 0, 20, 8, 197, 36, 225, 129, 52, 144, 20, 6, 65, 88, 84, 36, 0, 0, 10, 135, 11, 1, 18, 9, 195, 184, 19, 20, 10, 135, 3, 1, 18, 9, 195, 184, 19, 20, 11, 136, 3, 8, 1, 18, 13, 195, 184, 18, 20, 13, 202, 64, 244, 201, 80, 149, 137, 77, 66, 83, 44, 20, 13, 202, 56, 81, 193, 80, 149, 137, 77, 66, 83, 44, 20, 13, 202, 52, 147, 9, 80, 20, 137, 77, 66, 83, 44, 20, 13, 202, 44, 19, 15, 72, 147, 69, 81, 34, 83, 44, 20, 13, 202, 33, 145, 18, 60, 209, 75, 4, 226, 83, 44, 20, 13, 202, 12, 128, 85, 88, 147, 137, 77, 66, 83, 44, 20, 9, 198, 76, 18, 203, 5, 34, 68, 20, 9, 198, 44, 243, 12, 60, 145, 0, 20, 9, 198, 32, 20, 141, 60, 226, 64, 20, 9, 198, 5, 67, 5, 80, 146, 192, 20, 9, 198, 24, 97, 82, 52, 21, 0, 20, 0, 10, 67, 64, 130, 76, 83, 37, 60, 0, 25, 19, 71, 72, 82, 137, 12, 84, 133, 76, 34, 36, 57, 37, 89, 6, 36, 114, 89, 0, 10, 199, 72, 81, 213, 48, 21, 15, 72, 20, 10, 199, 72, 80, 201, 80, 21, 15, 72, 20, 10, 199, 36, 225, 9, 44, 21, 15, 72, 20, 10, 199, 21, 50, 193, 48, 21, 15, 72, 20, 12, 201, 72, 21, 9, 24, 146, 193, 80, 147, 206, 20, 12, 201, 61, 33, 193, 56, 148, 193, 80, 147, 206, 20, 12, 201, 52, 241, 9, 24, 146, 193, 80, 147, 206, 20, 12, 201, 44, 243, 148, 72, 144, 149, 80, 147, 206, 20, 12, 201, 44, 243, 134, 37, 50, 193, 80, 147, 206, 20, 12, 201, 44, 243, 134, 37, 35, 65, 80, 147, 206, 20, 12, 201, 44, 241, 9, 24, 146, 193, 80, 147, 206, 20, 12, 201, 44, 19, 143, 56, 148, 193, 80, 147, 206, 20, 12, 201, 36, 228, 212, 4, 195, 1, 80, 147, 206, 20, 12, 201, 16, 84, 212, 36, 195, 1, 80, 147, 206, 20, 12, 201, 4, 229, 9, 12, 148, 1, 80, 147, 206, 20, 10, 199, 44, 21, 1, 49, 148, 197, 72, 20, 10, 199, 16, 82, 204, 5, 52, 197, 72, 20, 10, 199, 16, 80, 200, 36, 100, 133, 72, 20, 10, 199, 81, 80, 82, 20, 114, 83, 44, 20, 10, 199, 44, 20, 148, 4, 114, 83, 44, 20, 10, 199, 8, 148, 195, 5, 146, 83, 44, 20, 8, 133, 195, 166, 20, 1, 14, 21, 9, 198, 77, 64, 70, 24, 17, 197, 20, 0, 11, 200, 45, 34, 77, 36, 227, 204, 60, 112, 20, 9, 198, 44, 20, 129, 88, 83, 0, 20, 11, 200, 5, 81, 205, 20, 229, 5, 72, 80, 20, 12, 201, 61, 97, 82, 44, 243, 77, 20, 194, 71, 20, 12, 201, 25, 33, 68, 76, 243, 77, 20, 194, 71, 20, 12, 201, 20, 161, 78, 16, 243, 77, 20, 194, 71, 20, 16, 141, 2, 18, 195, 184, 19, 20, 6, 195, 166, 12, 4, 9, 7, 20, 11, 200, 88, 242, 193, 80, 149, 137, 76, 176, 20, 11, 200, 72, 80, 76, 37, 53, 9, 76, 176, 20, 11, 200, 65, 35, 195, 20, 229, 9, 76, 176, 20, 11, 200, 64, 145, 84, 37, 53, 9, 76, 176, 20, 11, 200, 61, 5, 1, 80, 149, 137, 76, 176, 20, 11, 200, 28, 83, 199, 72, 17, 137, 76, 176, 20, 11, 200, 17, 84, 129, 80, 149, 137, 76, 176, 20, 11, 200, 17, 80, 76, 37, 53, 9, 76, 176, 20, 11, 200, 16, 162, 66, 61, 85, 9, 76, 176, 20, 11, 200, 16, 144, 75, 72, 243, 137, 76, 176, 20, 11, 200, 5, 67, 205, 37, 53, 9, 76, 176, 20, 11, 200, 5, 34, 193, 37, 53, 9, 76, 176, 20, 11, 200, 64, 197, 84, 60, 180, 129, 80, 144, 20, 9, 198, 33, 96, 66, 20, 128, 82, 20, 9, 198, 12, 83, 148, 72, 19, 0, 20, 21, 4, 95, 49, 77, 52, 6, 36, 12, 50, 15, 71, 37, 55, 37, 57, 6, 39, 12, 50, 0, 0, 14, 139, 16, 18, 15, 7, 18, 1, 13, 13, 195, 184, 18, 20, 8, 197, 4, 193, 75, 76, 144, 20, 9, 198, 28, 82, 147, 80, 194, 71, 20, 8, 197, 44, 20, 141, 36, 224, 20, 16, 69, 72, 243, 65, 56, 144, 34, 39, 65, 6, 110, 50, 37, 0, 20, 12, 201, 32, 84, 141, 20, 225, 85, 80, 146, 192, 20, 12, 201, 13, 149, 15, 28, 83, 133, 80, 146, 192, 20, 8, 197, 28, 84, 141, 4, 224, 20, 8, 197, 88, 19, 5, 57, 48, 20, 8, 197, 76, 145, 206, 4, 192, 20, 8, 197, 56, 243, 65, 16, 80, 20, 14, 65, 92, 72, 6, 114, 71, 36, 55, 47, 84, 36, 12, 0, 22, 1, 92, 6, 114, 65, 84, 36, 50, 72, 89, 81, 34, 4, 114, 89, 72, 51, 35, 37, 0, 27, 0, 9, 198, 48, 19, 80, 37, 53, 0, 20, 9, 198, 28, 20, 132, 37, 53, 0, 20, 9, 198, 52, 85, 15, 16, 146, 192, 20, 9, 198, 44, 21, 15, 48, 146, 192, 20, 0, 10, 199, 5, 3, 208, 48, 82, 211, 36, 20, 14, 203, 20, 180, 208, 21, 34, 77, 20, 229, 5, 72, 80, 20, 14, 203, 77, 147, 132, 36, 176, 76, 37, 53, 9, 76, 176, 20, 14, 203, 52, 21, 5, 72, 144, 76, 37, 53, 9, 76, 176, 20, 14, 203, 36, 212, 5, 72, 144, 76, 37, 53, 9, 76, 176, 20, 14, 203, 16, 85, 5, 72, 210, 78, 37, 53, 9, 76, 176, 20, 10, 199, 13, 144, 78, 44, 19, 9, 20, 20, 10, 199, 44, 243, 12, 60, 66, 85, 52, 20, 10, 199, 28, 195, 211, 5, 34, 85, 52, 20, 10, 199, 44, 243, 80, 21, 65, 78, 76, 20, 6, 195, 4, 224, 76, 20, 0, 9, 198, 45, 32, 75, 20, 193, 82, 20, 9, 198, 16, 84, 212, 73, 81, 82, 20, 9, 198, 4, 113, 210, 5, 97, 82, 20, 12, 201, 20, 101, 5, 73, 98, 83, 20, 194, 71, 20, 11, 200, 100, 83, 69, 56, 149, 9, 76, 176, 20, 11, 200, 76, 19, 15, 52, 243, 137, 76, 176, 20, 11, 200, 65, 34, 83, 52, 21, 9, 76, 176, 20, 11, 200, 64, 19, 143, 72, 19, 73, 76, 176, 20, 11, 200, 61, 33, 201, 5, 53, 9, 76, 176, 20, 11, 200, 41, 81, 1, 37, 53, 9, 76, 176, 20, 11, 200, 36, 225, 15, 48, 241, 201, 76, 176, 20, 11, 200, 20, 194, 84, 37, 53, 9, 76, 176, 20, 11, 200, 8, 19, 12, 37, 53, 9, 76, 176, 20, 11, 200, 4, 225, 75, 16, 245, 9, 76, 176, 20, 11, 200, 4, 180, 143, 8, 21, 9, 76, 176, 20, 7, 196, 88, 19, 9, 16, 20, 9, 198, 77, 68, 153, 44, 226, 78, 20, 13, 68, 45, 32, 65, 48, 49, 34, 114, 12, 55, 0, 20, 0, 14, 139, 22, 21, 12, 11, 1, 14, 9, 19, 195, 184, 18, 20, 14, 139, 19, 25, 13, 16, 1, 20, 9, 19, 195, 184, 18, 20, 14, 139, 13, 1, 7, 14, 5, 20, 9, 19, 195, 184, 18, 20, 12, 201, 44, 243, 15, 56, 144, 76, 37, 53, 0, 20, 18, 70, 52, 17, 206, 36, 98, 75, 65, 110, 68, 37, 83, 6, 37, 49, 0, 20, 7, 65, 96, 109, 49, 89, 0, 17, 4, 95, 49, 77, 49, 36, 72, 15, 47, 6, 40, 12, 89, 14, 50, 0, 0, 17, 206, 36, 229, 5, 48, 193, 75, 81, 80, 76, 37, 53, 9, 76, 176, 20, 17, 206, 20, 180, 201, 77, 65, 78, 80, 144, 76, 37, 53, 9, 76, 176, 20, 13, 202, 77, 84, 16, 61, 50, 84, 61, 34, 85, 52, 20, 9, 66, 4, 64, 110, 86, 0, 14, 45, 7, 66, 4, 64, 110, 12, 0, 21, 4, 95, 49, 77, 50, 6, 36, 12, 50, 15, 65, 37, 55, 37, 57, 6, 39, 12, 50, 0, 0, 9, 198, 76, 147, 133, 13, 84, 133, 20, 10, 199, 88, 145, 5, 60, 116, 129, 52, 20, 10, 199, 77, 65, 78, 60, 116, 129, 52, 20, 14, 203, 48, 82, 211, 36, 179, 199, 72, 17, 137, 76, 176, 20, 14, 203, 45, 35, 205, 5, 67, 199, 72, 17, 137, 76, 176, 20, 14, 203, 44, 243, 15, 56, 144, 76, 37, 53, 9, 76, 176, 20, 10, 199, 77, 147, 80, 61, 50, 85, 52, 20, 12, 201, 5, 49, 82, 8, 18, 132, 76, 160, 78, 20, 12, 201, 5, 49, 82, 8, 18, 132, 76, 160, 78, 21, 21, 4, 95, 49, 77, 51, 6, 36, 12, 50, 15, 65, 37, 55, 37, 57, 6, 112, 12, 72, 0, 0, 9, 198, 77, 80, 195, 20, 65, 82, 20, 9, 198, 77, 66, 77, 84, 193, 82, 20, 9, 198, 72, 85, 21, 72, 225, 82, 20, 13, 138, 16, 18, 195, 166, 19, 5, 14, 20, 5, 18, 20, 9, 198, 32, 20, 141, 60, 225, 82, 20, 9, 198, 76, 18, 203, 5, 34, 78, 20, 11, 200, 44, 243, 139, 61, 33, 1, 57, 48, 20, 11, 200, 44, 243, 132, 84, 181, 1, 57, 48, 20, 0, 12, 201, 61, 34, 69, 57, 64, 76, 37, 53, 0, 20, 9, 198, 64, 243, 9, 80, 148, 203, 20, 9, 198, 8, 20, 201, 48, 148, 203, 20, 12, 201, 16, 85, 5, 72, 210, 78, 4, 229, 0, 20, 6, 65, 100, 117, 19, 0, 0, 13, 202, 64, 20, 129, 48, 193, 76, 60, 116, 129, 52, 20, 15, 140, 18, 5, 16, 18, 195, 166, 19, 5, 14, 20, 5, 18, 20, 0, 9, 198, 81, 35, 205, 8, 244, 197, 20, 9, 198, 65, 35, 199, 56, 244, 197, 20, 12, 201, 56, 21, 9, 60, 224, 76, 37, 49, 82, 20, 10, 199, 44, 243, 147, 64, 148, 133, 72, 20, 12, 201, 44, 243, 77, 84, 224, 76, 37, 49, 82, 20, 12, 201, 44, 19, 142, 36, 32, 76, 37, 49, 82, 20, 10, 199, 36, 225, 11, 48, 20, 133, 72, 20, 9, 198, 44, 147, 133, 76, 84, 137, 20, 9, 198, 24, 20, 193, 56, 84, 137, 20, 10, 199, 80, 83, 211, 60, 98, 83, 44, 20, 10, 199, 24, 20, 129, 60, 226, 83, 44, 20, 10, 199, 17, 32, 77, 5, 66, 83, 44, 20, 10, 199, 4, 224, 70, 61, 34, 83, 44, 20, 9, 198, 4, 224, 77, 56, 84, 197, 20, 10, 199, 80, 84, 144, 20, 229, 9, 56, 20, 10, 199, 76, 84, 144, 20, 229, 9, 56, 20, 10, 199, 20, 225, 15, 77, 49, 78, 80, 20, 0, 9, 198, 56, 245, 1, 80, 147, 206, 20, 9, 198, 45, 33, 65, 80, 147, 206, 20, 9, 198, 16, 245, 1, 80, 147, 206, 20, 12, 201, 52, 146, 210, 61, 50, 207, 64, 148, 203, 20, 21, 68, 77, 64, 78, 16, 89, 47, 110, 50, 72, 6, 37, 50, 0, 44, 20, 81, 105, 110, 32, 9, 198, 44, 243, 150, 20, 224, 66, 20, 0, 8, 197, 28, 19, 9, 60, 224, 20, 9, 198, 60, 198, 77, 64, 148, 203, 20, 9, 198, 52, 85, 15, 16, 148, 203, 20, 9, 198, 44, 21, 15, 16, 148, 203, 20, 9, 198, 20, 180, 207, 80, 148, 203, 20, 9, 198, 9, 82, 207, 48, 148, 203, 20, 8, 197, 44, 195, 210, 36, 224, 20, 8, 197, 44, 243, 150, 4, 192, 20, 7, 65, 104, 89, 109, 47, 0, 0, 16, 66, 5, 64, 110, 15, 107, 110, 12, 0, 81, 104, 97, 118, 101, 32, 9, 198, 72, 149, 15, 72, 225, 76, 20, 12, 201, 12, 128, 82, 48, 21, 1, 56, 84, 137, 20, 13, 202, 77, 80, 147, 80, 19, 148, 37, 98, 83, 44, 20, 13, 202, 64, 84, 147, 64, 82, 212, 37, 98, 83, 44, 20, 13, 202, 52, 83, 15, 17, 32, 77, 5, 66, 83, 44, 20, 13, 202, 44, 243, 80, 61, 50, 84, 61, 34, 83, 44, 20, 13, 202, 36, 226, 214, 37, 50, 84, 61, 34, 83, 44, 20, 12, 201, 20, 180, 208, 20, 66, 84, 72, 144, 197, 20, 8, 66, 5, 64, 110, 12, 0, 72, 0, 10, 199, 72, 81, 140, 20, 181, 15, 72, 20, 10, 199, 65, 35, 212, 20, 181, 15, 72, 20, 10, 199, 36, 228, 208, 20, 181, 15, 72, 20, 12, 201, 52, 83, 147, 81, 37, 65, 80, 147, 206, 20, 12, 201, 36, 229, 9, 52, 145, 1, 80, 147, 206, 20, 10, 199, 36, 225, 11, 5, 52, 197, 72, 20, 10, 199, 52, 19, 1, 101, 50, 83, 44, 20, 10, 199, 44, 148, 143, 52, 19, 148, 36, 20, 0, 11, 200, 88, 148, 201, 80, 21, 9, 60, 224, 20, 11, 200, 88, 81, 197, 80, 21, 9, 60, 224, 20, 11, 200, 72, 80, 201, 80, 21, 9, 60, 224, 20, 11, 200, 52, 241, 21, 48, 21, 9, 60, 224, 20, 11, 200, 21, 50, 193, 48, 21, 9, 60, 224, 20, 11, 200, 16, 84, 21, 80, 21, 9, 60, 224, 20, 11, 200, 16, 84, 9, 48, 21, 9, 60, 224, 20, 11, 200, 4, 212, 21, 80, 21, 9, 60, 224, 20, 12, 201, 65, 35, 198, 100, 192, 75, 80, 148, 203, 20, 12, 201, 64, 197, 82, 4, 194, 83, 80, 148, 203, 20, 12, 201, 53, 148, 212, 36, 98, 83, 80, 148, 203, 20, 12, 201, 44, 16, 130, 4, 194, 83, 80, 148, 203, 20, 12, 201, 32, 83, 12, 20, 226, 83, 80, 148, 203, 20, 12, 201, 28, 20, 212, 72, 243, 143, 52, 148, 203, 20, 12, 201, 17, 32, 77, 5, 69, 82, 28, 148, 203, 20, 12, 201, 12, 19, 22, 36, 226, 83, 80, 148, 203, 20, 11, 200, 76, 19, 22, 4, 67, 210, 4, 224, 20, 11, 200, 16, 148, 133, 45, 67, 210, 4, 192, 20, 0, 12, 201, 36, 229, 5, 56, 64, 78, 81, 84, 128, 20, 8, 197, 88, 84, 137, 77, 64, 20, 8, 197, 4, 244, 137, 77, 64, 20, 12, 201, 44, 243, 150, 20, 229, 9, 60, 225, 76, 20, 8, 197, 37, 34, 83, 21, 32, 20, 8, 197, 9, 81, 211, 21, 32, 20, 8, 197, 8, 19, 132, 37, 64, 20, 8, 197, 16, 83, 6, 36, 224, 20, 8, 197, 88, 19, 5, 57, 64, 20, 8, 197, 80, 19, 5, 57, 64, 20, 8, 197, 64, 147, 69, 57, 64, 20, 8, 197, 52, 243, 69, 57, 64, 20, 8, 197, 16, 83, 69, 57, 64, 20, 8, 197, 48, 18, 212, 5, 64, 20, 8, 197, 49, 83, 66, 4, 192, 20, 0, 9, 198, 5, 81, 9, 80, 244, 128, 20, 12, 201, 64, 20, 129, 76, 149, 15, 48, 241, 201, 20, 12, 201, 16, 144, 76, 20, 181, 15, 48, 241, 201, 20, 9, 198, 80, 243, 148, 36, 225, 64, 20, 9, 198, 44, 19, 148, 36, 225, 64, 20, 9, 198, 65, 32, 75, 80, 146, 192, 20, 9, 198, 9, 34, 71, 4, 65, 64, 20, 9, 198, 8, 195, 203, 4, 65, 64, 20, 0, 10, 199, 81, 35, 212, 76, 178, 83, 80, 20, 10, 199, 64, 20, 139, 21, 34, 78, 28, 20, 15, 204, 25, 83, 139, 80, 147, 206, 4, 194, 83, 80, 148, 203, 20, 0, 22, 72, 9, 33, 65, 44, 64, 78, 12, 80, 71, 34, 109, 37, 81, 6, 72, 35, 12, 50, 89, 0, 11, 200, 44, 21, 129, 48, 84, 137, 77, 64, 20, 11, 200, 52, 81, 9, 80, 21, 9, 60, 224, 20, 11, 200, 48, 144, 201, 80, 21, 9, 60, 224, 20, 11, 200, 44, 244, 146, 20, 181, 9, 60, 224, 20, 11, 200, 80, 83, 210, 21, 66, 83, 21, 32, 20, 11, 200, 77, 147, 80, 5, 66, 83, 21, 32, 20, 11, 200, 56, 20, 139, 61, 66, 83, 21, 32, 20, 11, 200, 52, 20, 148, 101, 34, 83, 21, 32, 20, 11, 200, 52, 17, 206, 21, 66, 83, 21, 32, 20, 11, 200, 44, 20, 130, 60, 226, 83, 21, 32, 20, 11, 200, 33, 148, 14, 61, 66, 83, 21, 32, 20, 11, 200, 28, 195, 194, 4, 194, 83, 21, 32, 20, 11, 200, 20, 193, 75, 81, 34, 83, 21, 32, 20, 11, 200, 16, 144, 76, 60, 114, 83, 21, 32, 20, 11, 200, 4, 227, 206, 100, 210, 83, 21, 32, 20, 11, 200, 4, 224, 76, 60, 114, 83, 21, 32, 20, 11, 200, 4, 176, 68, 20, 210, 83, 21, 32, 20, 11, 200, 80, 131, 205, 37, 53, 9, 76, 176, 20, 11, 200, 64, 21, 18, 36, 245, 9, 76, 176, 20, 11, 200, 48, 19, 65, 37, 53, 9, 76, 176, 20, 11, 200, 32, 243, 73, 48, 85, 9, 76, 176, 20, 11, 200, 16, 146, 207, 80, 243, 73, 76, 176, 20, 11, 200, 16, 145, 148, 60, 225, 201, 76, 176, 20, 11, 200, 16, 144, 76, 20, 181, 9, 76, 176, 20, 11, 200, 72, 85, 77, 5, 66, 75, 21, 32, 20, 11, 200, 33, 148, 212, 21, 34, 75, 21, 32, 20, 11, 200, 32, 148, 212, 61, 34, 75, 21, 32, 20, 11, 200, 17, 32, 77, 5, 66, 75, 21, 32, 20, 11, 200, 16, 241, 205, 5, 66, 75, 21, 32, 20, 9, 198, 52, 86, 154, 4, 226, 78, 20, 11, 200, 4, 35, 206, 56, 83, 69, 57, 64, 20, 11, 200, 72, 85, 19, 36, 225, 82, 21, 64, 20, 11, 200, 44, 20, 9, 81, 83, 1, 57, 64, 20, 0, 8, 197, 72, 82, 210, 85, 64, 20, 12, 201, 9, 34, 76, 48, 19, 148, 36, 225, 64, 20, 8, 197, 72, 16, 201, 77, 64, 20, 8, 197, 65, 84, 137, 77, 64, 20, 8, 197, 44, 244, 137, 77, 64, 20, 8, 197, 44, 19, 11, 21, 32, 20, 8, 197, 21, 34, 71, 21, 32, 20, 8, 197, 48, 21, 5, 57, 64, 20, 8, 197, 64, 81, 1, 57, 64, 20, 0, 11, 66, 12, 16, 89, 37, 34, 49, 110, 0, 25, 9, 198, 32, 243, 79, 48, 241, 192, 20, 9, 198, 32, 21, 83, 76, 148, 212, 20, 9, 198, 84, 69, 69, 48, 145, 192, 20, 9, 198, 32, 244, 141, 60, 224, 76, 20, 9, 198, 33, 145, 18, 4, 229, 0, 20, 0, 9, 198, 76, 147, 9, 44, 244, 197, 20, 10, 199, 76, 84, 137, 4, 194, 83, 80, 20, 10, 199, 60, 178, 213, 49, 66, 83, 80, 20, 14, 203, 25, 83, 139, 80, 147, 206, 4, 194, 83, 21, 32, 20, 14, 203, 8, 243, 129, 64, 20, 148, 37, 53, 9, 76, 176, 20, 0, 11, 200, 24, 243, 11, 48, 244, 137, 77, 64, 20, 19, 70, 16, 148, 212, 36, 179, 206, 72, 37, 89, 47, 37, 49, 6, 114, 50, 0, 20, 9, 198, 41, 83, 139, 80, 147, 206, 20, 9, 198, 25, 32, 75, 80, 147, 206, 20, 11, 200, 44, 243, 77, 84, 226, 75, 21, 32, 20, 11, 200, 16, 243, 69, 77, 66, 67, 21, 32, 20, 12, 137, 195, 184, 13, 20, 195, 165, 12, 9, 7, 20, 12, 137, 22, 5, 12, 4, 195, 166, 4, 9, 7, 20, 12, 137, 7, 15, 4, 4, 195, 166, 4, 9, 7, 20, 11, 200, 5, 53, 13, 5, 66, 75, 21, 32, 20, 7, 196, 61, 33, 193, 56, 21, 11, 200, 72, 81, 140, 20, 181, 1, 57, 64, 20, 0, 12, 201, 16, 144, 76, 20, 181, 15, 48, 241, 192, 20, 12, 201, 48, 81, 201, 80, 147, 73, 80, 85, 0, 20, 12, 201, 25, 32, 84, 21, 35, 137, 80, 85, 0, 20, 8, 197, 64, 243, 5, 72, 80, 20, 8, 197, 52, 83, 5, 72, 80, 20, 12, 201, 80, 147, 19, 80, 81, 5, 48, 145, 192, 20, 13, 138, 15, 22, 5, 18, 19, 195, 166, 4, 9, 7, 20, 13, 138, 14, 195, 184, 4, 22, 5, 14, 4, 9, 7, 20, 12, 201, 32, 83, 2, 72, 81, 5, 48, 145, 192, 20, 12, 201, 32, 19, 19, 77, 64, 82, 72, 145, 192, 20, 12, 201, 28, 83, 130, 73, 81, 197, 48, 145, 192, 20, 12, 201, 24, 244, 132, 72, 17, 197, 48, 145, 192, 20, 9, 198, 72, 18, 201, 80, 148, 203, 20, 9, 198, 32, 20, 141, 60, 226, 75, 20, 12, 201, 80, 85, 18, 5, 96, 76, 20, 229, 0, 20, 0, 13, 202, 76, 17, 15, 52, 20, 207, 12, 130, 83, 80, 20, 9, 198, 56, 146, 9, 48, 148, 212, 20, 13, 202, 52, 19, 149, 24, 18, 212, 85, 34, 83, 80, 20, 9, 198, 37, 51, 1, 52, 148, 212, 20, 9, 198, 24, 21, 1, 48, 148, 212, 20, 9, 198, 4, 194, 217, 52, 148, 212, 20, 14, 139, 20, 9, 12, 2, 195, 184, 10, 5, 12, 9, 7, 20, 14, 139, 16, 195, 165, 18, 5, 7, 14, 5, 12, 9, 7, 20, 9, 198, 77, 64, 78, 56, 147, 204, 20, 9, 198, 5, 4, 5, 80, 149, 0, 20, 9, 198, 76, 225, 71, 48, 21, 0, 20, 9, 198, 72, 16, 130, 36, 224, 84, 20, 0, 12, 201, 44, 243, 147, 81, 37, 75, 80, 147, 206, 20, 12, 201, 36, 229, 18, 60, 69, 75, 80, 147, 206, 20, 12, 201, 16, 84, 201, 56, 97, 75, 80, 147, 206, 20, 12, 201, 12, 245, 133, 73, 97, 82, 76, 147, 206, 20, 10, 199, 52, 243, 137, 80, 244, 133, 72, 20, 10, 199, 52, 20, 211, 4, 180, 133, 72, 20, 15, 140, 20, 9, 12, 7, 195, 166, 14, 7, 5, 12, 9, 7, 20, 10, 199, 44, 21, 1, 52, 20, 129, 56, 21, 0, 22, 3, 7, 195, 165, 81, 113, 15, 48, 6, 113, 15, 110, 0, 82, 112, 195, 165, 32, 97, 102, 32, 12, 201, 48, 20, 153, 56, 115, 211, 44, 244, 0, 20, 6, 195, 48, 241, 201, 20, 9, 198, 76, 243, 21, 80, 147, 206, 20, 9, 198, 72, 245, 1, 80, 147, 206, 20, 9, 198, 56, 81, 193, 80, 147, 206, 20, 9, 198, 48, 81, 193, 80, 147, 206, 20, 9, 198, 20, 213, 76, 76, 147, 206, 20, 9, 198, 12, 149, 1, 80, 147, 206, 20, 11, 200, 64, 242, 213, 48, 84, 137, 56, 112, 20, 11, 200, 48, 144, 201, 80, 84, 137, 56, 112, 20, 11, 200, 12, 148, 197, 48, 84, 137, 56, 112, 20, 11, 200, 64, 83, 147, 36, 243, 133, 72, 80, 20, 16, 141, 15, 13, 11, 18, 9, 14, 7, 19, 195, 166, 4, 9, 7, 20, 11, 200, 45, 98, 78, 16, 17, 212, 36, 112, 20, 15, 204, 29, 81, 22, 20, 192, 133, 32, 17, 197, 48, 145, 192, 20, 15, 204, 29, 81, 19, 8, 84, 208, 61, 69, 5, 48, 145, 192, 20, 12, 137, 1, 6, 6, 195, 166, 12, 4, 9, 7, 20, 12, 201, 60, 229, 15, 28, 83, 133, 80, 148, 203, 20, 12, 201, 32, 84, 141, 20, 225, 85, 80, 148, 203, 20, 11, 200, 32, 83, 7, 20, 226, 78, 16, 80, 20, 11, 200, 45, 98, 78, 16, 17, 212, 36, 112, 20, 7, 196, 4, 97, 129, 8, 20, 11, 200, 44, 20, 148, 60, 227, 129, 28, 80, 20, 0, 33, 69, 65, 80, 140, 36, 48, 48, 114, 71, 55, 36, 49, 15, 89, 13, 12, 84, 37, 89, 14, 50, 0, 81, 115, 101, 114, 118, 105, 99, 101, 110, 32, 30, 69, 65, 80, 140, 36, 48, 48, 114, 71, 55, 36, 49, 15, 89, 13, 12, 84, 37, 89, 0, 81, 115, 101, 114, 118, 105, 99, 101, 32, 12, 201, 77, 2, 82, 37, 69, 65, 48, 148, 212, 20, 12, 201, 76, 243, 78, 4, 208, 149, 48, 148, 212, 20, 16, 205, 56, 21, 9, 60, 224, 76, 76, 240, 201, 4, 194, 83, 80, 20, 8, 197, 56, 245, 5, 72, 80, 20, 13, 138, 22, 195, 166, 18, 19, 1, 18, 20, 9, 7, 20, 12, 201, 56, 21, 21, 72, 96, 71, 48, 145, 192, 20, 13, 138, 7, 5, 19, 11, 195, 166, 6, 20, 9, 7, 20, 13, 138, 7, 5, 19, 10, 195, 166, 6, 20, 9, 7, 20, 12, 201, 24, 244, 132, 20, 192, 71, 80, 145, 192, 20, 8, 197, 20, 212, 1, 80, 144, 20, 31, 69, 65, 80, 140, 36, 48, 48, 114, 71, 55, 36, 49, 15, 72, 39, 65, 6, 110, 57, 50, 0, 20, 81, 100, 111, 109, 97, 105, 110, 32, 12, 201, 44, 244, 147, 21, 69, 5, 72, 85, 0, 20, 12, 201, 52, 81, 4, 20, 192, 71, 80, 145, 192, 20, 12, 201, 24, 244, 132, 20, 192, 71, 80, 145, 192, 20, 0, 9, 198, 32, 244, 141, 60, 225, 76, 20, 9, 198, 36, 229, 129, 48, 145, 0, 20, 9, 198, 21, 84, 143, 64, 145, 0, 20, 9, 198, 29, 80, 82, 4, 226, 64, 20, 9, 198, 64, 243, 9, 80, 146, 192, 20, 9, 198, 44, 84, 129, 52, 146, 192, 20, 9, 198, 52, 83, 5, 72, 85, 0, 20, 0, 9, 198, 21, 67, 143, 48, 241, 201, 20, 12, 201, 88, 19, 15, 72, 148, 193, 80, 147, 206, 20, 12, 201, 81, 148, 9, 24, 146, 193, 80, 147, 206, 20, 12, 201, 64, 243, 1, 72, 148, 193, 80, 147, 206, 20, 12, 201, 44, 243, 148, 36, 229, 65, 80, 147, 206, 20, 12, 201, 44, 243, 147, 80, 148, 1, 80, 147, 206, 20, 12, 201, 44, 243, 135, 72, 81, 193, 80, 147, 206, 20, 12, 201, 20, 208, 78, 12, 148, 1, 80, 147, 206, 20, 12, 201, 4, 211, 210, 80, 148, 193, 80, 147, 206, 20, 12, 201, 4, 194, 77, 20, 229, 1, 80, 147, 206, 20, 12, 201, 4, 48, 197, 57, 69, 65, 80, 147, 206, 20, 14, 203, 52, 146, 210, 61, 50, 207, 64, 84, 137, 56, 112, 20, 12, 201, 44, 243, 132, 37, 66, 79, 56, 83, 0, 20, 10, 199, 44, 244, 146, 84, 212, 5, 72, 20, 15, 140, 195, 165, 2, 5, 14, 8, 10, 5, 18, 20, 9, 7, 20, 15, 140, 22, 5, 4, 5, 18, 8, 195, 166, 6, 20, 9, 7, 20, 15, 140, 6, 15, 18, 18, 195, 165, 4, 14, 5, 12, 9, 7, 20, 15, 140, 6, 15, 18, 7, 195, 166, 14, 7, 5, 12, 9, 7, 20, 15, 140, 6, 15, 18, 6, 195, 166, 14, 7, 5, 12, 9, 7, 20, 9, 198, 44, 243, 12, 60, 66, 69, 20, 14, 203, 44, 243, 150, 20, 229, 21, 4, 194, 78, 16, 80, 20, 12, 201, 44, 243, 148, 84, 33, 82, 56, 19, 0, 20, 5, 195, 32, 244, 192, 0, 11, 200, 88, 148, 201, 80, 84, 137, 56, 112, 20, 11, 200, 88, 81, 197, 80, 84, 137, 56, 112, 20, 11, 200, 77, 64, 70, 24, 84, 137, 56, 112, 20, 11, 200, 72, 85, 137, 16, 84, 137, 56, 112, 20, 11, 200, 72, 83, 1, 80, 84, 137, 56, 112, 20, 11, 200, 56, 20, 193, 48, 84, 137, 56, 112, 20, 11, 200, 44, 194, 67, 32, 84, 137, 56, 112, 20, 11, 200, 72, 20, 16, 61, 37, 5, 72, 80, 20, 11, 200, 28, 20, 146, 61, 69, 5, 72, 80, 20, 12, 201, 81, 34, 75, 36, 226, 15, 48, 66, 71, 20, 12, 201, 48, 245, 141, 20, 66, 15, 48, 66, 71, 20, 12, 201, 48, 19, 135, 76, 243, 77, 20, 194, 71, 20, 12, 201, 25, 33, 77, 44, 243, 77, 20, 194, 71, 20, 16, 141, 6, 15, 18, 20, 18, 195, 166, 6, 6, 5, 12, 9, 7, 20, 11, 200, 80, 244, 15, 48, 241, 201, 76, 176, 20, 11, 200, 76, 86, 15, 48, 241, 201, 76, 176, 20, 11, 200, 53, 149, 15, 48, 241, 201, 76, 176, 20, 11, 200, 52, 243, 143, 48, 241, 201, 76, 176, 20, 11, 200, 9, 38, 79, 48, 241, 201, 76, 176, 20, 11, 200, 36, 229, 5, 72, 209, 68, 36, 80, 20, 11, 200, 44, 243, 147, 84, 194, 78, 16, 80, 20, 7, 196, 76, 83, 137, 48, 20, 7, 196, 72, 16, 129, 80, 20, 9, 198, 77, 147, 143, 16, 19, 0, 20, 0, 8, 197, 28, 83, 204, 60, 112, 20, 8, 197, 25, 84, 201, 60, 224, 20, 9, 198, 28, 85, 129, 48, 66, 71, 20, 8, 197, 65, 81, 82, 36, 192, 20, 8, 197, 80, 82, 206, 36, 176, 20, 8, 197, 77, 148, 212, 20, 208, 20, 8, 197, 16, 83, 69, 57, 48, 20, 0, 13, 202, 4, 67, 73, 56, 148, 212, 72, 21, 15, 72, 20, 9, 198, 80, 16, 200, 37, 53, 0, 20, 9, 198, 52, 20, 152, 37, 53, 0, 20, 9, 198, 16, 17, 1, 37, 53, 0, 20, 9, 198, 52, 83, 15, 16, 146, 192, 20, 9, 198, 20, 192, 83, 80, 146, 192, 20, 0, 10, 199, 44, 244, 9, 21, 34, 78, 28, 20, 14, 203, 20, 180, 208, 48, 144, 201, 80, 84, 137, 56, 112, 20, 10, 199, 12, 19, 80, 21, 34, 78, 28, 20, 19, 144, 7, 5, 14, 14, 5, 13, 20, 18, 195, 166, 14, 7, 5, 12, 9, 7, 20, 14, 203, 21, 2, 68, 20, 210, 79, 48, 241, 201, 76, 176, 20, 14, 203, 16, 144, 76, 20, 181, 15, 48, 241, 201, 76, 176, 20, 10, 199, 4, 69, 133, 72, 34, 85, 52, 20, 10, 199, 80, 244, 141, 20, 229, 9, 48, 20, 12, 137, 6, 195, 184, 14, 9, 11, 9, 5, 14, 20, 10, 199, 73, 85, 9, 56, 84, 133, 80, 20, 8, 67, 84, 226, 88, 21, 0, 10, 0, 11, 200, 60, 225, 21, 48, 21, 9, 60, 224, 20, 11, 200, 16, 148, 203, 72, 85, 9, 60, 224, 20, 11, 200, 16, 147, 1, 80, 21, 9, 60, 224, 20, 11, 200, 4, 100, 133, 4, 181, 9, 60, 224, 20, 11, 200, 4, 33, 82, 72, 21, 9, 60, 224, 20, 7, 196, 52, 241, 5, 48, 20, 9, 198, 44, 243, 150, 20, 225, 82, 20, 9, 198, 44, 240, 71, 84, 193, 82, 20, 9, 198, 36, 227, 203, 84, 193, 82, 20, 9, 198, 16, 85, 1, 12, 129, 82, 20, 11, 200, 17, 148, 208, 21, 5, 9, 76, 176, 20, 9, 198, 88, 19, 137, 48, 194, 78, 20, 11, 200, 56, 144, 193, 72, 17, 213, 4, 224, 20, 9, 198, 4, 84, 143, 64, 192, 78, 21, 11, 200, 77, 80, 140, 36, 210, 78, 4, 192, 20, 11, 200, 64, 84, 134, 61, 35, 65, 57, 48, 20, 0, 12, 201, 45, 34, 77, 36, 224, 76, 37, 53, 0, 20, 12, 201, 56, 245, 133, 48, 194, 83, 80, 146, 192, 20, 0, 9, 198, 52, 85, 15, 16, 148, 212, 20, 13, 202, 52, 19, 20, 72, 18, 212, 21, 34, 78, 28, 20, 13, 202, 24, 18, 211, 36, 210, 76, 21, 34, 78, 28, 20, 13, 202, 20, 180, 208, 5, 68, 137, 21, 34, 78, 28, 20, 13, 202, 20, 180, 208, 21, 34, 77, 20, 229, 5, 48, 20, 13, 202, 16, 242, 213, 52, 83, 148, 5, 34, 85, 52, 20, 9, 198, 8, 18, 197, 48, 149, 0, 20, 13, 202, 76, 83, 22, 12, 83, 148, 72, 84, 133, 80, 20, 6, 66, 4, 96, 110, 0, 0, 6, 195, 89, 51, 208, 17, 12, 201, 8, 83, 133, 16, 146, 212, 36, 225, 82, 68, 10, 199, 32, 148, 212, 60, 116, 129, 52, 20, 12, 201, 77, 80, 150, 20, 229, 9, 60, 225, 82, 20, 12, 201, 65, 35, 208, 61, 37, 9, 60, 225, 82, 20, 0, 7, 196, 85, 33, 197, 72, 20, 9, 198, 72, 84, 201, 28, 225, 82, 20, 9, 198, 72, 17, 134, 36, 225, 82, 20, 9, 198, 21, 128, 197, 48, 193, 82, 20, 9, 198, 20, 208, 129, 48, 193, 82, 20, 9, 198, 53, 84, 211, 20, 194, 78, 20, 7, 196, 44, 147, 137, 56, 20, 9, 68, 25, 33, 65, 44, 21, 0, 10, 0, 24, 73, 76, 176, 84, 20, 35, 193, 72, 65, 84, 89, 49, 6, 36, 37, 47, 71, 39, 13, 72, 108, 86, 0, 9, 198, 37, 51, 1, 52, 148, 203, 20, 9, 198, 36, 229, 73, 80, 148, 203, 20, 9, 198, 21, 66, 79, 64, 148, 203, 20, 9, 198, 16, 82, 193, 16, 148, 203, 20, 9, 198, 5, 50, 197, 80, 148, 203, 20, 12, 201, 65, 35, 208, 61, 37, 9, 60, 224, 76, 20, 0, 9, 198, 20, 193, 70, 4, 229, 0, 20, 0, 10, 199, 88, 83, 133, 72, 243, 15, 28, 20, 10, 199, 61, 35, 137, 80, 243, 15, 28, 20, 10, 199, 28, 192, 67, 36, 243, 15, 28, 20, 10, 199, 45, 34, 78, 60, 194, 78, 20, 20, 12, 201, 44, 243, 148, 72, 20, 201, 28, 225, 82, 20, 10, 199, 36, 212, 12, 4, 229, 5, 72, 20, 10, 199, 77, 81, 134, 37, 48, 78, 80, 20, 0, 15, 204, 65, 35, 198, 21, 52, 201, 60, 224, 76, 37, 53, 0, 20, 7, 196, 41, 81, 197, 72, 20, 12, 201, 77, 65, 84, 61, 50, 207, 64, 148, 203, 20, 12, 201, 64, 243, 25, 12, 83, 148, 72, 148, 203, 20, 12, 201, 64, 84, 137, 64, 21, 5, 80, 148, 203, 20, 12, 201, 52, 18, 210, 61, 50, 207, 64, 148, 203, 20, 12, 201, 44, 244, 205, 60, 224, 85, 80, 148, 203, 20, 12, 201, 13, 149, 15, 28, 83, 133, 80, 148, 203, 20, 7, 196, 21, 97, 78, 80, 20, 9, 198, 16, 82, 204, 36, 224, 66, 20, 9, 68, 21, 97, 78, 80, 21, 0, 10, 0, 13, 138, 7, 25, 14, 195, 166, 11, 15, 12, 15, 7, 20, 8, 197, 84, 226, 83, 60, 224, 20, 8, 197, 61, 5, 9, 60, 224, 20, 8, 197, 48, 81, 201, 60, 224, 20, 11, 136, 12, 195, 184, 22, 9, 14, 4, 5, 20, 0, 8, 67, 80, 19, 11, 21, 0, 10, 0, 10, 199, 76, 147, 85, 48, 21, 15, 72, 20, 10, 199, 36, 226, 9, 8, 149, 15, 72, 20, 15, 140, 6, 195, 166, 14, 15, 13, 5, 14, 15, 12, 15, 7, 20, 12, 201, 88, 242, 193, 48, 148, 193, 80, 147, 206, 20, 10, 199, 88, 20, 137, 5, 66, 79, 56, 20, 12, 201, 72, 84, 212, 5, 84, 129, 80, 147, 206, 20, 10, 199, 65, 35, 205, 61, 66, 79, 56, 20, 12, 201, 48, 81, 193, 48, 148, 193, 80, 147, 206, 20, 10, 199, 44, 243, 77, 84, 226, 79, 56, 20, 12, 201, 44, 243, 15, 56, 148, 193, 80, 147, 206, 20, 12, 201, 44, 21, 5, 44, 148, 193, 80, 147, 206, 20, 12, 201, 44, 19, 129, 48, 148, 193, 80, 147, 206, 20, 10, 199, 5, 52, 197, 73, 66, 79, 56, 20, 10, 199, 4, 226, 77, 5, 66, 79, 56, 20, 10, 199, 64, 244, 212, 16, 21, 5, 72, 20, 10, 199, 24, 197, 79, 72, 145, 5, 72, 20, 15, 204, 44, 243, 77, 84, 224, 76, 64, 243, 9, 80, 148, 203, 20, 10, 199, 28, 83, 198, 101, 50, 83, 44, 20, 10, 199, 5, 85, 1, 72, 178, 83, 44, 20, 0, 11, 200, 32, 84, 131, 20, 115, 214, 36, 224, 20, 9, 198, 16, 148, 203, 85, 64, 66, 20, 9, 198, 4, 48, 197, 65, 64, 66, 20, 0, 8, 197, 48, 19, 131, 21, 32, 20, 8, 197, 25, 83, 135, 21, 32, 20, 8, 197, 44, 197, 83, 36, 192, 20, 8, 197, 12, 130, 76, 20, 224, 20, 8, 197, 65, 35, 198, 4, 224, 21, 8, 197, 5, 67, 205, 5, 32, 20, 0, 9, 198, 12, 245, 84, 85, 33, 64, 20, 13, 202, 76, 81, 9, 52, 83, 148, 5, 66, 79, 56, 20, 13, 202, 44, 243, 134, 72, 243, 148, 5, 66, 79, 56, 20, 13, 202, 16, 242, 213, 52, 83, 148, 5, 66, 79, 56, 20, 13, 202, 5, 33, 213, 52, 83, 148, 5, 66, 79, 56, 20, 9, 198, 77, 83, 77, 21, 33, 64, 20, 9, 198, 37, 32, 75, 37, 50, 192, 20, 9, 198, 36, 33, 82, 37, 50, 192, 20, 9, 198, 20, 198, 83, 37, 50, 192, 20, 16, 141, 9, 19, 12, 195, 166, 14, 4, 5, 18, 9, 14, 4, 5, 20, 9, 198, 72, 82, 212, 61, 32, 76, 20, 0, 10, 199, 65, 80, 140, 36, 50, 83, 80, 20, 10, 199, 52, 18, 84, 72, 84, 211, 20, 20, 6, 195, 61, 32, 76, 20, 9, 198, 64, 19, 9, 76, 17, 5, 20, 20, 70, 45, 37, 83, 80, 17, 5, 49, 34, 116, 89, 72, 6, 110, 12, 86, 13, 0, 20, 10, 199, 36, 225, 21, 45, 64, 78, 76, 20, 0, 7, 196, 81, 34, 83, 80, 20, 11, 200, 65, 35, 214, 36, 228, 201, 20, 192, 20, 11, 200, 88, 84, 130, 4, 194, 83, 21, 32, 20, 11, 200, 81, 148, 129, 56, 226, 83, 21, 32, 20, 11, 200, 77, 65, 82, 36, 194, 83, 21, 32, 20, 11, 200, 77, 64, 66, 36, 194, 83, 21, 32, 20, 11, 200, 76, 145, 206, 4, 194, 83, 21, 32, 20, 11, 200, 28, 84, 141, 4, 226, 83, 21, 32, 20, 11, 200, 28, 19, 22, 4, 226, 83, 21, 32, 20, 0, 12, 201, 65, 54, 75, 60, 102, 83, 37, 50, 192, 20, 12, 201, 64, 243, 25, 4, 225, 18, 37, 50, 192, 20, 12, 201, 20, 115, 195, 20, 229, 18, 37, 50, 192, 20, 0, 9, 198, 64, 21, 15, 48, 241, 192, 20, 9, 198, 60, 226, 207, 48, 241, 192, 20, 9, 198, 4, 194, 207, 48, 241, 192, 20, 9, 198, 64, 20, 139, 21, 33, 64, 20, 9, 198, 24, 146, 211, 21, 33, 64, 20, 5, 194, 16, 16, 72, 0, 10, 199, 5, 48, 133, 77, 67, 211, 20, 20, 10, 199, 65, 35, 203, 85, 34, 83, 80, 20, 10, 199, 56, 245, 133, 48, 194, 83, 80, 20, 10, 199, 52, 241, 5, 72, 226, 83, 80, 20, 10, 199, 44, 243, 80, 60, 226, 83, 80, 20, 10, 199, 44, 243, 77, 84, 226, 83, 80, 20, 10, 199, 32, 20, 144, 20, 226, 83, 80, 20, 14, 203, 36, 225, 21, 77, 68, 137, 4, 194, 83, 21, 32, 20, 14, 203, 16, 149, 137, 76, 147, 206, 4, 194, 83, 21, 32, 20, 9, 198, 76, 84, 133, 56, 17, 5, 20, 0, 11, 200, 88, 84, 147, 36, 98, 67, 21, 32, 20, 11, 200, 72, 84, 18, 60, 69, 67, 21, 32, 20, 11, 200, 53, 148, 212, 36, 98, 67, 21, 32, 20, 11, 200, 45, 96, 76, 36, 98, 67, 21, 32, 20, 11, 200, 36, 229, 18, 60, 69, 67, 21, 32, 20, 15, 204, 80, 161, 75, 44, 244, 204, 61, 96, 75, 37, 50, 192, 20, 0, 16, 205, 84, 65, 9, 24, 97, 82, 20, 229, 9, 21, 34, 78, 28, 20, 12, 201, 72, 84, 197, 73, 97, 82, 36, 225, 192, 20, 12, 201, 72, 83, 73, 81, 65, 82, 36, 225, 192, 20, 12, 201, 64, 192, 75, 5, 65, 82, 36, 225, 192, 20, 12, 201, 64, 84, 134, 61, 33, 82, 36, 225, 192, 20, 12, 201, 64, 21, 5, 57, 65, 82, 36, 225, 192, 20, 12, 201, 60, 36, 197, 73, 97, 82, 36, 225, 192, 20, 12, 201, 57, 83, 77, 21, 33, 82, 36, 225, 192, 20, 12, 201, 45, 83, 20, 37, 97, 82, 36, 225, 192, 20, 12, 201, 45, 33, 68, 37, 65, 82, 36, 225, 192, 20, 12, 201, 44, 243, 77, 85, 65, 82, 36, 225, 192, 20, 12, 201, 44, 20, 130, 85, 33, 82, 36, 225, 192, 20, 12, 201, 44, 19, 9, 9, 33, 82, 36, 225, 192, 20, 12, 201, 36, 229, 133, 57, 65, 82, 36, 225, 192, 20, 12, 201, 36, 229, 5, 29, 33, 82, 36, 225, 192, 20, 12, 201, 32, 244, 208, 37, 65, 82, 36, 225, 192, 20, 12, 201, 24, 16, 197, 81, 65, 82, 36, 225, 192, 20, 12, 201, 16, 84, 197, 73, 65, 82, 36, 225, 192, 20, 12, 201, 16, 84, 15, 73, 65, 82, 36, 225, 192, 20, 12, 201, 8, 19, 12, 61, 65, 82, 36, 225, 192, 20, 12, 201, 5, 69, 5, 77, 65, 82, 36, 225, 192, 20, 12, 201, 5, 49, 129, 49, 65, 82, 36, 225, 192, 20, 12, 201, 5, 4, 18, 21, 65, 82, 36, 225, 192, 20, 12, 201, 4, 36, 197, 57, 65, 82, 36, 225, 192, 20, 0, 13, 202, 88, 147, 204, 60, 224, 197, 48, 194, 83, 80, 20, 9, 198, 65, 35, 211, 4, 148, 212, 20, 9, 198, 56, 144, 143, 56, 149, 0, 20, 0, 26, 73, 64, 21, 18, 60, 230, 77, 36, 179, 206, 48, 110, 47, 34, 39, 50, 6, 116, 65, 37, 49, 114, 50, 0, 20, 12, 201, 76, 21, 9, 76, 96, 75, 80, 147, 206, 20, 12, 201, 72, 84, 18, 60, 69, 75, 80, 147, 206, 20, 12, 201, 41, 84, 137, 76, 66, 75, 80, 147, 206, 20, 10, 199, 4, 48, 197, 77, 50, 79, 56, 20, 10, 199, 81, 32, 86, 21, 36, 197, 72, 20, 10, 199, 72, 80, 201, 16, 149, 133, 72, 20, 10, 199, 4, 48, 197, 48, 84, 133, 72, 20, 10, 199, 61, 3, 1, 16, 83, 9, 28, 20, 0, 12, 201, 44, 19, 5, 40, 67, 211, 44, 244, 0, 20, 12, 201, 28, 19, 22, 4, 227, 211, 44, 244, 0, 20, 11, 200, 88, 19, 9, 16, 84, 137, 56, 112, 20, 11, 200, 84, 68, 129, 16, 84, 137, 56, 112, 20, 11, 200, 81, 84, 195, 32, 84, 137, 56, 112, 20, 11, 200, 77, 3, 206, 76, 84, 137, 56, 112, 20, 11, 200, 76, 19, 21, 80, 84, 137, 56, 112, 20, 11, 200, 60, 225, 21, 48, 84, 137, 56, 112, 20, 11, 200, 52, 147, 137, 52, 84, 137, 56, 112, 20, 11, 200, 52, 18, 213, 48, 84, 137, 56, 112, 20, 15, 204, 44, 243, 148, 36, 225, 197, 57, 65, 82, 36, 225, 192, 20, 11, 200, 28, 19, 15, 64, 84, 137, 56, 112, 20, 11, 200, 24, 147, 5, 80, 84, 137, 56, 112, 20, 11, 200, 20, 180, 201, 48, 84, 137, 56, 112, 20, 11, 200, 16, 82, 193, 80, 84, 137, 56, 112, 20, 15, 204, 9, 35, 206, 44, 244, 203, 61, 1, 82, 36, 225, 192, 20, 7, 196, 45, 33, 69, 72, 20, 11, 200, 81, 83, 135, 76, 147, 132, 36, 112, 20, 11, 200, 80, 18, 211, 45, 147, 4, 36, 112, 20, 11, 200, 52, 19, 135, 24, 243, 4, 36, 112, 20, 11, 200, 44, 243, 4, 8, 195, 196, 36, 112, 20, 11, 200, 29, 81, 6, 73, 145, 212, 36, 112, 20, 11, 200, 4, 193, 129, 16, 84, 140, 36, 112, 20, 11, 200, 65, 35, 214, 77, 66, 78, 16, 80, 20, 7, 196, 76, 81, 1, 56, 21, 9, 68, 8, 246, 76, 20, 21, 0, 10, 0, 12, 201, 77, 65, 82, 20, 243, 69, 81, 34, 64, 20, 12, 201, 44, 243, 15, 72, 147, 69, 81, 34, 64, 20, 8, 197, 32, 21, 129, 72, 144, 20, 8, 197, 8, 20, 143, 56, 144, 20, 0, 9, 198, 64, 84, 147, 60, 225, 76, 20, 9, 198, 88, 20, 203, 21, 34, 64, 20, 9, 198, 64, 192, 71, 21, 34, 64, 20, 9, 198, 48, 147, 135, 21, 34, 64, 20, 9, 198, 32, 82, 211, 21, 34, 64, 20, 9, 198, 48, 19, 212, 37, 50, 192, 20, 9, 198, 44, 19, 212, 37, 50, 192, 20, 9, 198, 8, 147, 212, 37, 50, 192, 20, 9, 198, 52, 19, 1, 44, 149, 0, 20, 0, 10, 199, 65, 35, 195, 21, 52, 207, 72, 20, 14, 203, 77, 147, 80, 80, 243, 65, 80, 243, 15, 28, 144, 20, 9, 198, 64, 21, 15, 48, 241, 201, 20, 9, 198, 60, 226, 207, 48, 241, 201, 20, 9, 198, 32, 243, 79, 48, 241, 201, 20, 9, 198, 13, 149, 15, 48, 241, 201, 20, 10, 199, 64, 243, 12, 85, 66, 79, 56, 20, 10, 199, 4, 97, 133, 45, 66, 79, 56, 20, 14, 203, 72, 82, 1, 8, 147, 9, 80, 84, 137, 56, 112, 20, 14, 203, 52, 243, 143, 25, 67, 206, 28, 84, 137, 56, 112, 20, 0, 18, 7, 12, 39, 3, 8, 1, 9, 13, 55, 110, 49, 34, 6, 35, 57, 65, 0, 12, 137, 11, 1, 22, 5, 18, 14, 195, 184, 19, 20, 11, 200, 88, 83, 133, 72, 243, 15, 28, 144, 20, 11, 200, 61, 35, 137, 80, 243, 15, 28, 144, 20, 11, 200, 28, 192, 67, 36, 243, 15, 28, 144, 20, 9, 134, 19, 195, 166, 19, 15, 14, 20, 16, 6, 18, 195, 166, 19, 15, 14, 51, 109, 89, 6, 114, 68, 0, 20, 11, 200, 21, 50, 193, 48, 84, 137, 56, 112, 20, 11, 200, 36, 225, 19, 81, 81, 5, 72, 80, 20, 11, 200, 48, 145, 66, 32, 21, 133, 72, 144, 20, 11, 200, 8, 241, 200, 60, 193, 5, 72, 144, 20, 11, 200, 36, 229, 5, 72, 197, 68, 36, 80, 20, 11, 200, 44, 243, 80, 61, 50, 84, 84, 208, 20, 11, 200, 64, 243, 25, 56, 243, 73, 84, 208, 20, 11, 200, 52, 147, 12, 20, 227, 137, 84, 208, 20, 11, 200, 21, 96, 78, 28, 83, 9, 84, 208, 20, 11, 200, 32, 84, 148, 84, 114, 78, 16, 80, 20, 7, 196, 52, 240, 137, 48, 20, 7, 196, 16, 80, 129, 80, 20, 9, 198, 45, 38, 83, 80, 19, 0, 20, 0, 12, 201, 64, 19, 132, 20, 176, 71, 21, 34, 64, 20, 12, 201, 81, 34, 78, 36, 64, 68, 37, 50, 192, 20, 12, 201, 80, 83, 5, 76, 179, 208, 37, 50, 192, 20, 12, 201, 64, 20, 129, 80, 18, 212, 37, 50, 192, 20, 12, 201, 48, 16, 153, 72, 147, 148, 37, 50, 192, 20, 12, 201, 37, 52, 129, 20, 194, 84, 37, 50, 192, 20, 12, 201, 33, 148, 15, 80, 18, 212, 37, 50, 192, 20, 12, 201, 33, 145, 18, 60, 198, 84, 37, 50, 192, 20, 12, 201, 4, 193, 207, 72, 149, 13, 37, 50, 192, 20, 12, 201, 16, 243, 73, 12, 147, 5, 72, 85, 0, 20, 8, 197, 76, 17, 146, 4, 224, 21, 0, 14, 139, 19, 5, 14, 20, 5, 14, 20, 9, 195, 184, 19, 20, 14, 139, 16, 18, 15, 13, 9, 19, 11, 21, 195, 184, 19, 20, 9, 198, 41, 81, 1, 37, 53, 0, 20, 9, 198, 4, 65, 78, 60, 145, 0, 20, 9, 198, 24, 244, 131, 21, 33, 84, 20, 9, 198, 72, 81, 201, 60, 224, 76, 20, 9, 198, 29, 85, 20, 85, 32, 76, 20, 0, 15, 140, 16, 18, 195, 166, 20, 5, 14, 20, 9, 195, 184, 19, 20, 12, 137, 7, 21, 22, 5, 18, 14, 195, 184, 18, 20, 10, 199, 44, 195, 210, 21, 34, 78, 28, 20, 12, 201, 72, 81, 133, 72, 83, 148, 36, 83, 0, 20, 10, 199, 16, 83, 5, 28, 84, 133, 80, 20, 10, 199, 16, 80, 201, 16, 84, 133, 80, 20, 10, 199, 4, 197, 5, 72, 84, 133, 80, 20, 12, 201, 16, 147, 69, 57, 50, 79, 56, 19, 0, 20, 0, 7, 196, 88, 243, 21, 80, 20, 9, 198, 77, 1, 75, 84, 193, 82, 20, 9, 198, 64, 192, 84, 36, 225, 82, 20, 9, 198, 64, 20, 208, 60, 193, 82, 20, 9, 198, 44, 242, 197, 81, 65, 82, 20, 9, 198, 44, 19, 11, 84, 193, 82, 20, 9, 198, 16, 148, 211, 60, 225, 82, 20, 9, 198, 16, 84, 212, 36, 225, 82, 20, 9, 198, 16, 82, 204, 36, 225, 82, 20, 9, 198, 5, 4, 18, 60, 33, 82, 20, 9, 198, 88, 149, 18, 36, 243, 0, 20, 11, 200, 9, 35, 205, 44, 19, 9, 84, 208, 20, 9, 198, 77, 80, 141, 5, 34, 78, 20, 9, 198, 16, 19, 13, 5, 66, 78, 20, 7, 196, 64, 81, 1, 48, 20, 7, 196, 52, 241, 1, 48, 20, 7, 196, 5, 33, 65, 48, 20, 0, 14, 139, 1, 13, 2, 1, 19, 19, 1, 4, 195, 184, 18, 20, 12, 201, 65, 35, 205, 37, 50, 213, 37, 65, 84, 20, 12, 201, 80, 83, 5, 80, 82, 206, 37, 50, 192, 20, 12, 201, 76, 147, 135, 4, 193, 83, 37, 50, 192, 20, 12, 201, 52, 17, 1, 28, 20, 203, 37, 50, 192, 20, 12, 201, 44, 244, 205, 60, 115, 206, 37, 50, 192, 20, 12, 201, 28, 84, 149, 56, 66, 86, 37, 50, 192, 20, 12, 201, 64, 84, 137, 4, 194, 83, 21, 33, 84, 20, 0, 9, 198, 48, 19, 65, 37, 53, 0, 20, 20, 66, 12, 64, 89, 36, 72, 36, 51, 6, 114, 65, 0, 44, 20, 81, 114, 111, 109, 32, 9, 198, 17, 147, 129, 52, 149, 0, 20, 13, 202, 20, 180, 208, 21, 34, 77, 20, 229, 1, 48, 20, 13, 202, 16, 84, 1, 73, 65, 77, 20, 229, 1, 48, 20, 0, 12, 137, 16, 18, 195, 166, 13, 1, 20, 21, 18, 20, 10, 199, 56, 21, 9, 88, 149, 5, 80, 20, 10, 199, 52, 18, 143, 72, 149, 5, 80, 20, 10, 199, 48, 246, 65, 48, 149, 5, 80, 20, 10, 199, 36, 229, 9, 52, 149, 5, 80, 20, 10, 199, 4, 97, 137, 56, 149, 5, 80, 20, 12, 201, 36, 211, 65, 81, 34, 75, 84, 193, 82, 20, 12, 201, 8, 144, 140, 36, 241, 210, 4, 97, 82, 20, 10, 199, 52, 244, 129, 80, 244, 137, 20, 20, 10, 199, 65, 148, 129, 52, 145, 1, 48, 20, 0, 21, 68, 77, 67, 210, 80, 89, 47, 39, 34, 72, 15, 107, 112, 40, 0, 81, 104, 97, 118, 32, 15, 204, 84, 225, 5, 72, 82, 211, 81, 33, 77, 37, 65, 84, 20, 9, 198, 81, 33, 77, 84, 193, 82, 20, 9, 198, 65, 35, 198, 4, 225, 82, 20, 9, 198, 56, 149, 133, 48, 193, 82, 20, 9, 198, 52, 245, 73, 48, 193, 82, 20, 9, 198, 44, 243, 77, 5, 65, 82, 20, 9, 198, 36, 226, 193, 72, 225, 82, 20, 9, 198, 25, 37, 83, 81, 33, 82, 20, 9, 198, 16, 148, 203, 85, 65, 82, 20, 7, 196, 4, 65, 5, 72, 20, 0, 9, 198, 76, 130, 73, 80, 148, 203, 20, 9, 198, 65, 35, 211, 4, 148, 203, 20, 9, 198, 49, 83, 129, 80, 148, 203, 20, 9, 198, 9, 83, 9, 52, 148, 203, 20, 9, 198, 5, 67, 5, 80, 148, 203, 20, 9, 198, 17, 32, 77, 5, 66, 75, 20, 0, 13, 202, 77, 80, 147, 36, 66, 65, 72, 149, 5, 80, 20, 13, 202, 64, 192, 85, 76, 144, 137, 48, 149, 5, 80, 20, 13, 202, 21, 128, 197, 57, 68, 137, 12, 149, 5, 80, 20, 13, 202, 4, 113, 210, 21, 52, 201, 88, 149, 5, 80, 20, 9, 198, 52, 20, 135, 21, 34, 84, 20, 9, 198, 24, 244, 198, 61, 34, 84, 20, 0, 10, 199, 20, 118, 80, 80, 243, 15, 28, 20, 10, 199, 72, 80, 75, 80, 149, 133, 72, 20, 12, 137, 13, 195, 166, 1, 14, 4, 18, 5, 18, 20, 10, 199, 44, 243, 150, 21, 33, 197, 72, 20, 10, 199, 44, 243, 147, 84, 197, 5, 72, 20, 12, 201, 44, 243, 80, 48, 83, 69, 57, 65, 82, 20, 10, 199, 44, 243, 77, 4, 225, 5, 72, 20, 10, 199, 77, 67, 210, 4, 117, 9, 28, 20, 10, 199, 8, 20, 142, 4, 117, 9, 28, 20, 10, 199, 52, 243, 143, 45, 32, 84, 36, 20, 10, 199, 77, 67, 210, 4, 117, 9, 28, 20, 10, 199, 8, 20, 142, 4, 117, 9, 28, 20, 10, 199, 36, 229, 18, 36, 112, 78, 80, 20, 0, 9, 198, 44, 244, 148, 37, 51, 206, 20, 7, 196, 52, 83, 15, 56, 20, 13, 138, 9, 13, 16, 18, 195, 166, 7, 14, 5, 18, 20, 7, 196, 49, 81, 193, 72, 20, 9, 198, 44, 243, 77, 85, 64, 66, 20, 0, 7, 197, 8, 19, 12, 60, 224, 12, 201, 20, 180, 208, 21, 34, 77, 20, 229, 0, 20, 12, 201, 44, 243, 77, 84, 226, 75, 4, 229, 0, 20, 10, 69, 64, 145, 7, 36, 224, 21, 0, 10, 0, 13, 202, 20, 101, 5, 73, 33, 84, 80, 83, 9, 28, 20, 12, 201, 64, 244, 212, 76, 52, 137, 65, 69, 77, 20, 0, 12, 201, 53, 83, 73, 24, 146, 193, 80, 147, 206, 20, 10, 199, 72, 84, 208, 20, 181, 5, 72, 20, 10, 199, 52, 83, 147, 81, 37, 69, 72, 20, 10, 199, 44, 243, 147, 81, 37, 69, 72, 20, 10, 199, 36, 228, 212, 37, 69, 69, 72, 20, 10, 199, 5, 53, 18, 36, 225, 197, 72, 20, 10, 199, 4, 225, 204, 37, 53, 9, 44, 20, 10, 199, 29, 32, 84, 84, 192, 78, 80, 20, 10, 199, 16, 83, 196, 61, 32, 78, 80, 20, 10, 199, 44, 243, 134, 37, 50, 193, 8, 20, 0, 10, 67, 16, 21, 5, 72, 36, 57, 47, 0, 12, 201, 88, 246, 69, 85, 34, 83, 80, 148, 203, 20, 12, 201, 80, 84, 146, 61, 34, 83, 80, 148, 203, 20, 12, 201, 77, 147, 66, 60, 194, 83, 80, 148, 203, 20, 12, 201, 77, 64, 76, 36, 226, 83, 80, 148, 203, 20, 12, 201, 77, 2, 82, 37, 66, 83, 80, 148, 203, 20, 12, 201, 76, 240, 201, 4, 194, 83, 80, 148, 203, 20, 12, 201, 72, 149, 21, 4, 194, 83, 80, 148, 203, 20, 12, 201, 65, 34, 86, 5, 66, 83, 80, 148, 203, 20, 12, 201, 28, 83, 197, 48, 82, 212, 72, 148, 203, 20, 12, 201, 24, 244, 141, 4, 194, 83, 80, 148, 203, 20, 12, 201, 24, 85, 68, 4, 194, 83, 80, 148, 203, 20, 12, 201, 24, 85, 9, 12, 130, 83, 80, 148, 203, 20, 12, 201, 16, 20, 151, 36, 226, 83, 80, 148, 203, 20, 12, 201, 9, 37, 84, 4, 194, 83, 80, 148, 203, 20, 12, 201, 4, 36, 213, 72, 66, 83, 80, 148, 203, 20, 0, 21, 73, 64, 20, 211, 21, 0, 82, 80, 245, 84, 48, 110, 35, 71, 112, 47, 6, 40, 0, 20, 8, 197, 76, 19, 4, 21, 32, 20, 8, 197, 4, 114, 84, 21, 32, 20, 8, 197, 64, 83, 131, 36, 192, 20, 8, 197, 44, 243, 131, 36, 192, 20, 12, 201, 81, 32, 78, 77, 0, 82, 20, 229, 0, 20, 12, 201, 81, 32, 78, 77, 0, 82, 20, 228, 192, 20, 0, 13, 202, 45, 96, 76, 36, 98, 75, 5, 66, 79, 56, 20, 9, 198, 80, 16, 149, 21, 33, 64, 20, 9, 198, 56, 244, 141, 21, 33, 64, 20, 9, 198, 24, 84, 137, 21, 33, 64, 20, 9, 198, 36, 179, 206, 37, 50, 192, 20, 9, 198, 77, 1, 75, 81, 32, 76, 20, 9, 198, 44, 244, 144, 61, 32, 76, 20, 9, 198, 24, 84, 212, 37, 96, 76, 20, 0, 15, 204, 76, 17, 15, 52, 20, 207, 12, 130, 83, 80, 148, 203, 20, 15, 204, 64, 84, 134, 20, 181, 9, 60, 226, 83, 80, 148, 203, 20, 15, 204, 44, 243, 77, 84, 226, 84, 5, 34, 83, 80, 148, 203, 20, 15, 204, 36, 225, 9, 88, 145, 21, 4, 194, 83, 80, 148, 203, 20, 15, 204, 36, 212, 18, 21, 52, 201, 60, 226, 83, 80, 148, 203, 20, 15, 204, 20, 180, 208, 4, 228, 201, 60, 226, 83, 80, 148, 203, 20, 13, 138, 12, 195, 166, 18, 5, 18, 9, 14, 4, 5, 20, 9, 198, 44, 19, 143, 56, 17, 5, 20, 0, 11, 200, 44, 19, 132, 36, 64, 84, 85, 32, 20, 11, 200, 61, 33, 193, 56, 241, 210, 4, 208, 20, 11, 200, 45, 38, 80, 80, 241, 210, 4, 208, 20, 11, 200, 20, 180, 208, 48, 242, 84, 21, 32, 20, 11, 200, 4, 178, 207, 52, 211, 196, 21, 32, 20, 16, 141, 16, 18, 15, 16, 195, 166, 4, 5, 21, 20, 9, 19, 11, 20, 11, 200, 77, 66, 80, 20, 225, 9, 84, 208, 20, 11, 200, 44, 243, 80, 20, 225, 9, 84, 208, 20, 0, 8, 197, 45, 83, 20, 85, 32, 20, 8, 197, 45, 34, 68, 21, 32, 20, 8, 197, 41, 84, 212, 21, 32, 20, 12, 201, 36, 225, 140, 5, 67, 210, 37, 50, 192, 20, 0, 9, 198, 80, 19, 135, 21, 33, 64, 20, 9, 198, 64, 21, 83, 21, 33, 64, 20, 9, 198, 52, 20, 211, 21, 33, 64, 20, 9, 198, 52, 20, 203, 21, 33, 64, 20, 9, 198, 52, 20, 139, 21, 33, 64, 20, 9, 198, 52, 19, 139, 21, 33, 64, 20, 9, 198, 45, 84, 147, 21, 33, 64, 20, 9, 198, 44, 20, 211, 21, 33, 64, 20, 9, 198, 24, 147, 135, 21, 33, 64, 20, 0, 10, 199, 88, 20, 197, 45, 67, 205, 36, 20, 9, 198, 72, 83, 85, 48, 17, 5, 20, 9, 198, 52, 84, 211, 36, 17, 5, 20, 10, 199, 61, 33, 15, 56, 224, 78, 76, 20, 0, 15, 204, 24, 244, 148, 36, 98, 75, 5, 67, 210, 37, 50, 192, 20, 7, 196, 88, 83, 137, 56, 20, 11, 200, 77, 66, 80, 20, 225, 9, 5, 64, 20, 7, 196, 61, 34, 193, 56, 21, 0, 8, 197, 21, 2, 76, 60, 112, 20, 8, 197, 52, 19, 5, 72, 144, 20, 9, 198, 88, 242, 193, 48, 148, 203, 20, 9, 198, 76, 177, 77, 5, 66, 75, 20, 12, 201, 44, 243, 147, 80, 149, 21, 20, 229, 0, 20, 0, 9, 198, 88, 242, 193, 48, 148, 212, 20, 9, 198, 4, 227, 129, 48, 148, 212, 20, 9, 198, 44, 19, 148, 61, 34, 64, 20, 9, 198, 76, 178, 90, 60, 145, 0, 20, 9, 198, 72, 82, 212, 61, 32, 84, 20, 9, 198, 52, 241, 5, 72, 21, 0, 20, 9, 198, 48, 82, 212, 61, 32, 84, 20, 0, 10, 199, 76, 81, 205, 20, 229, 5, 72, 20, 10, 199, 64, 145, 205, 20, 229, 5, 72, 20, 10, 199, 44, 243, 134, 84, 225, 5, 72, 20, 10, 199, 5, 84, 203, 84, 197, 5, 72, 20, 10, 199, 61, 4, 201, 28, 83, 9, 28, 20, 10, 199, 33, 83, 4, 76, 19, 9, 28, 20, 10, 199, 4, 229, 1, 28, 83, 9, 28, 20, 10, 199, 4, 228, 203, 84, 83, 9, 28, 20, 9, 198, 32, 148, 212, 61, 34, 69, 20, 0, 22, 72, 48, 81, 197, 56, 65, 82, 56, 80, 55, 36, 81, 6, 109, 50, 72, 114, 50, 108, 89, 0, 21, 72, 48, 81, 197, 56, 65, 82, 56, 80, 55, 36, 81, 6, 109, 50, 72, 114, 50, 108, 0, 11, 200, 16, 84, 212, 36, 195, 5, 72, 144, 20, 11, 200, 81, 98, 86, 48, 17, 212, 36, 112, 20, 11, 200, 76, 176, 76, 44, 17, 212, 36, 112, 20, 11, 200, 72, 81, 197, 16, 84, 140, 36, 112, 20, 11, 200, 52, 19, 132, 32, 17, 148, 36, 112, 20, 11, 200, 24, 244, 149, 17, 49, 76, 36, 112, 20, 11, 200, 24, 244, 147, 80, 19, 132, 36, 112, 20, 11, 200, 64, 20, 129, 16, 148, 201, 76, 176, 20, 11, 200, 52, 19, 131, 33, 84, 137, 76, 176, 20, 12, 201, 5, 66, 5, 56, 145, 78, 76, 148, 203, 20, 11, 200, 45, 144, 133, 72, 225, 84, 36, 176, 20, 11, 200, 81, 98, 86, 48, 17, 212, 36, 112, 20, 11, 200, 76, 176, 76, 44, 17, 212, 36, 112, 20, 9, 198, 4, 229, 9, 45, 96, 82, 20, 0, 8, 197, 73, 81, 197, 72, 144, 20, 12, 201, 72, 81, 213, 48, 17, 5, 81, 34, 64, 20, 8, 197, 48, 149, 1, 56, 144, 20, 8, 197, 57, 80, 78, 12, 80, 20, 12, 201, 36, 228, 212, 73, 82, 212, 61, 32, 84, 20, 0, 11, 136, 3, 9, 19, 5, 12, 195, 184, 18, 20, 9, 198, 80, 145, 199, 21, 34, 64, 20, 9, 198, 72, 83, 147, 21, 34, 64, 20, 9, 198, 64, 18, 203, 21, 34, 64, 20, 9, 198, 40, 20, 203, 21, 34, 64, 20, 9, 198, 24, 148, 203, 21, 34, 64, 20, 9, 198, 64, 20, 148, 37, 50, 192, 20, 18, 70, 60, 64, 76, 37, 50, 192, 39, 72, 35, 55, 6, 37, 89, 49, 0, 20, 9, 198, 4, 96, 84, 37, 50, 192, 20, 0, 12, 137, 9, 14, 7, 5, 14, 9, 195, 184, 18, 20, 10, 199, 65, 83, 19, 5, 66, 79, 56, 20, 12, 137, 1, 4, 8, 195, 166, 19, 9, 15, 14, 20, 10, 199, 81, 32, 78, 76, 149, 5, 72, 20, 10, 199, 20, 97, 133, 45, 69, 69, 72, 20, 10, 199, 45, 84, 141, 4, 113, 82, 36, 20, 10, 199, 56, 20, 15, 48, 149, 1, 56, 20, 10, 199, 8, 148, 135, 37, 69, 9, 56, 20, 0, 12, 137, 9, 14, 7, 5, 14, 9, 195, 184, 19, 20, 9, 134, 7, 5, 8, 195, 184, 18, 20, 11, 200, 72, 81, 213, 48, 84, 137, 56, 112, 20, 11, 200, 21, 53, 9, 52, 84, 137, 56, 112, 20, 11, 200, 9, 83, 148, 52, 17, 197, 72, 144, 20, 11, 200, 76, 19, 132, 77, 147, 140, 36, 112, 20, 11, 200, 4, 225, 1, 49, 84, 201, 76, 176, 20, 11, 200, 65, 35, 211, 12, 83, 137, 84, 208, 20, 9, 198, 16, 243, 73, 12, 147, 0, 20, 7, 196, 16, 80, 137, 48, 20, 9, 198, 48, 21, 5, 72, 19, 0, 20, 0, 10, 135, 12, 195, 166, 19, 9, 15, 14, 20, 9, 198, 49, 85, 135, 37, 34, 71, 20, 8, 197, 8, 83, 154, 60, 192, 20, 12, 201, 88, 149, 1, 48, 148, 212, 37, 50, 192, 20, 12, 201, 84, 226, 79, 56, 148, 212, 37, 50, 192, 20, 12, 201, 80, 245, 5, 52, 148, 212, 37, 50, 192, 20, 12, 201, 76, 227, 194, 8, 148, 212, 37, 50, 192, 20, 12, 201, 76, 21, 1, 56, 148, 212, 37, 50, 192, 20, 12, 201, 72, 246, 65, 48, 148, 212, 37, 50, 192, 20, 12, 201, 72, 145, 207, 72, 148, 212, 37, 50, 192, 20, 12, 201, 65, 54, 75, 60, 65, 76, 37, 50, 192, 20, 12, 201, 64, 244, 21, 48, 148, 212, 37, 50, 192, 20, 12, 201, 64, 193, 79, 56, 20, 212, 37, 50, 192, 20, 12, 201, 64, 19, 148, 20, 148, 212, 37, 50, 192, 20, 12, 201, 61, 5, 9, 52, 148, 212, 37, 50, 192, 20, 12, 201, 56, 146, 9, 48, 148, 212, 37, 50, 192, 20, 12, 201, 52, 244, 135, 4, 224, 84, 37, 50, 192, 20, 12, 201, 52, 82, 193, 56, 148, 212, 37, 50, 192, 20, 12, 201, 48, 246, 65, 48, 148, 212, 37, 50, 192, 20, 12, 201, 48, 241, 193, 72, 149, 13, 37, 50, 192, 20, 12, 201, 37, 51, 1, 52, 148, 212, 37, 50, 192, 20, 12, 201, 36, 65, 65, 48, 148, 212, 37, 50, 192, 20, 12, 201, 33, 83, 65, 56, 148, 212, 37, 50, 192, 20, 12, 201, 32, 147, 132, 84, 148, 212, 37, 50, 192, 20, 12, 201, 32, 81, 15, 56, 148, 212, 37, 50, 192, 20, 12, 201, 28, 21, 76, 48, 148, 212, 37, 50, 192, 20, 12, 201, 24, 83, 73, 56, 148, 212, 37, 50, 192, 20, 12, 201, 24, 21, 1, 48, 148, 212, 37, 50, 192, 20, 12, 201, 21, 52, 193, 100, 148, 212, 37, 50, 192, 20, 12, 201, 21, 50, 193, 64, 148, 212, 37, 50, 192, 20, 12, 201, 20, 212, 9, 72, 148, 212, 37, 50, 192, 20, 12, 201, 16, 148, 137, 28, 148, 212, 37, 50, 192, 20, 12, 201, 16, 144, 71, 56, 244, 212, 37, 50, 192, 20, 12, 201, 16, 83, 9, 72, 148, 212, 37, 50, 192, 20, 12, 201, 4, 224, 82, 44, 148, 212, 37, 50, 192, 20, 12, 201, 4, 197, 18, 84, 148, 212, 37, 50, 192, 20, 12, 201, 4, 194, 217, 52, 148, 212, 37, 50, 192, 20, 12, 201, 4, 181, 9, 88, 148, 212, 37, 50, 192, 20, 8, 197, 24, 147, 129, 57, 48, 20, 0, 19, 67, 80, 145, 19, 47, 37, 89, 15, 50, 6, 114, 49, 0, 81, 110, 111, 107, 32, 14, 139, 20, 5, 14, 4, 5, 14, 20, 9, 195, 184, 19, 20, 11, 136, 4, 15, 13, 16, 20, 195, 184, 18, 20, 9, 198, 72, 84, 207, 49, 85, 0, 20, 13, 202, 41, 84, 212, 36, 98, 75, 5, 66, 79, 56, 20, 13, 202, 24, 19, 19, 36, 98, 75, 5, 66, 79, 56, 20, 9, 198, 4, 227, 149, 37, 65, 84, 20, 9, 198, 24, 244, 148, 36, 227, 128, 20, 9, 198, 8, 192, 83, 21, 33, 84, 20, 0, 11, 136, 14, 15, 18, 13, 12, 195, 184, 19, 20, 12, 137, 3, 8, 9, 11, 1, 14, 195, 184, 18, 20, 12, 137, 1, 18, 18, 1, 14, 7, 195, 184, 18, 20, 10, 199, 44, 21, 1, 48, 84, 19, 36, 20, 10, 199, 9, 35, 205, 44, 19, 9, 20, 20, 0, 12, 137, 3, 8, 9, 11, 1, 14, 195, 184, 19, 20, 7, 196, 36, 130, 133, 48, 20, 9, 198, 72, 16, 129, 81, 65, 82, 20, 9, 198, 64, 84, 134, 61, 33, 82, 20, 9, 198, 60, 36, 197, 73, 97, 82, 20, 9, 198, 57, 83, 77, 21, 33, 82, 20, 9, 198, 44, 243, 77, 85, 65, 82, 20, 9, 198, 24, 16, 197, 81, 65, 82, 20, 9, 198, 16, 82, 25, 17, 33, 82, 20, 9, 198, 8, 19, 12, 61, 65, 82, 20, 9, 198, 5, 49, 129, 49, 65, 82, 20, 9, 198, 4, 67, 73, 81, 65, 82, 20, 15, 204, 80, 245, 1, 48, 149, 1, 72, 148, 212, 37, 50, 192, 20, 15, 204, 77, 80, 138, 20, 181, 9, 88, 148, 212, 37, 50, 192, 20, 15, 204, 77, 2, 82, 37, 69, 65, 48, 148, 212, 37, 50, 192, 20, 15, 204, 52, 84, 139, 4, 229, 9, 48, 148, 212, 37, 50, 192, 20, 15, 204, 37, 51, 204, 5, 66, 79, 56, 148, 212, 37, 50, 192, 20, 15, 204, 16, 80, 197, 57, 68, 129, 48, 148, 212, 37, 50, 192, 20, 15, 204, 5, 96, 78, 80, 112, 82, 16, 148, 212, 37, 50, 192, 20, 11, 200, 44, 243, 15, 24, 243, 137, 84, 208, 20, 11, 200, 44, 243, 12, 60, 181, 137, 84, 208, 20, 9, 198, 28, 198, 67, 21, 34, 78, 20, 0, 14, 69, 76, 128, 77, 65, 80, 91, 57, 35, 65, 71, 39, 0, 12, 201, 80, 16, 133, 48, 192, 82, 37, 50, 192, 20, 12, 201, 64, 243, 25, 80, 82, 206, 37, 50, 192, 20, 12, 201, 48, 81, 197, 56, 64, 82, 37, 50, 192, 20, 12, 201, 45, 81, 134, 21, 37, 6, 37, 50, 192, 20, 12, 201, 44, 19, 5, 56, 64, 82, 37, 50, 192, 20, 12, 201, 41, 81, 207, 76, 192, 86, 37, 50, 192, 20, 12, 201, 16, 81, 140, 5, 67, 210, 37, 50, 192, 20, 12, 201, 36, 229, 5, 72, 84, 211, 21, 33, 84, 20, 12, 201, 24, 147, 9, 64, 83, 147, 21, 33, 84, 20, 6, 195, 85, 96, 78, 21, 0, 5, 194, 8, 128, 17, 9, 198, 61, 1, 82, 37, 53, 0, 20, 9, 198, 37, 32, 78, 37, 53, 0, 20, 17, 142, 16, 18, 195, 166, 16, 15, 19, 9, 20, 9, 15, 14, 5, 12, 20, 9, 198, 44, 21, 5, 17, 32, 76, 20, 13, 4, 95, 20, 21, 18, 47, 6, 108, 12, 50, 72, 0, 0, 10, 199, 88, 82, 212, 61, 34, 69, 48, 20, 12, 201, 45, 35, 208, 77, 98, 83, 37, 65, 82, 20, 12, 201, 36, 229, 5, 73, 5, 78, 45, 65, 82, 20, 18, 207, 36, 229, 5, 72, 224, 84, 36, 243, 129, 48, 148, 212, 37, 50, 192, 20, 10, 199, 44, 243, 15, 24, 243, 137, 20, 20, 10, 199, 44, 243, 12, 60, 181, 137, 20, 20, 0, 14, 68, 5, 33, 207, 56, 6, 35, 34, 81, 114, 50, 0, 20, 13, 138, 16, 18, 195, 166, 19, 5, 18, 22, 5, 18, 20, 9, 198, 65, 35, 205, 61, 97, 82, 20, 9, 198, 21, 128, 197, 73, 1, 82, 20, 9, 198, 20, 180, 197, 45, 97, 82, 20, 9, 198, 12, 83, 147, 85, 33, 82, 20, 9, 198, 4, 48, 197, 65, 65, 82, 20, 11, 200, 44, 243, 147, 20, 181, 133, 57, 48, 20, 7, 196, 8, 242, 129, 56, 21, 0, 12, 201, 5, 37, 9, 48, 193, 82, 37, 53, 0, 20, 12, 201, 44, 243, 80, 48, 82, 211, 37, 65, 84, 20, 8, 197, 33, 145, 18, 36, 64, 20, 8, 197, 64, 244, 212, 36, 192, 20, 8, 67, 64, 18, 82, 21, 0, 10, 0, 13, 202, 77, 80, 138, 20, 181, 9, 88, 149, 5, 80, 20, 13, 202, 64, 84, 141, 37, 52, 201, 88, 149, 5, 80, 20, 13, 202, 32, 85, 5, 72, 241, 197, 56, 149, 5, 80, 20, 13, 202, 5, 69, 18, 4, 181, 9, 88, 149, 5, 80, 20, 15, 140, 16, 18, 195, 166, 4, 9, 19, 16, 15, 14, 5, 18, 20, 9, 198, 52, 244, 203, 61, 98, 84, 20, 9, 198, 36, 228, 212, 4, 228, 192, 20, 9, 198, 20, 193, 71, 4, 229, 0, 20, 17, 70, 16, 19, 147, 4, 229, 0, 72, 35, 50, 89, 6, 112, 50, 0, 20, 0, 10, 199, 65, 35, 203, 80, 243, 15, 28, 20, 10, 199, 16, 82, 210, 21, 65, 82, 20, 20, 10, 199, 4, 225, 201, 88, 83, 9, 28, 20, 6, 195, 60, 35, 204, 20, 9, 198, 72, 83, 69, 16, 149, 77, 20, 9, 198, 4, 181, 129, 72, 149, 77, 20, 10, 199, 16, 83, 79, 45, 32, 84, 36, 20, 10, 199, 80, 20, 148, 72, 22, 137, 56, 20, 12, 4, 95, 49, 49, 15, 109, 55, 83, 72, 108, 0, 0, 7, 196, 88, 83, 9, 56, 20, 14, 139, 16, 18, 195, 166, 6, 5, 18, 5, 14, 3, 5, 20, 0, 11, 67, 20, 113, 78, 35, 12, 57, 13, 50, 0, 12, 201, 60, 36, 212, 37, 0, 84, 36, 243, 128, 20, 12, 201, 36, 225, 9, 24, 97, 82, 20, 228, 192, 20, 0, 13, 202, 72, 85, 143, 49, 85, 9, 60, 225, 82, 20, 20, 13, 202, 36, 228, 212, 73, 83, 69, 57, 65, 82, 20, 20, 13, 202, 28, 83, 142, 20, 212, 203, 84, 83, 9, 28, 20, 12, 201, 72, 84, 208, 60, 228, 207, 72, 149, 77, 20, 9, 198, 76, 83, 148, 20, 228, 192, 20, 8, 66, 21, 32, 109, 34, 0, 72, 0, 10, 199, 76, 145, 206, 4, 193, 82, 20, 20, 10, 199, 72, 81, 143, 72, 209, 82, 20, 20, 10, 199, 44, 243, 134, 37, 50, 197, 72, 20, 10, 199, 20, 180, 212, 72, 18, 5, 72, 20, 10, 199, 24, 244, 147, 100, 227, 9, 28, 20, 9, 198, 4, 209, 137, 8, 149, 77, 20, 10, 199, 12, 19, 66, 60, 66, 129, 56, 20, 10, 199, 4, 36, 212, 36, 225, 78, 80, 20, 6, 195, 72, 80, 76, 20, 10, 199, 16, 147, 5, 81, 64, 78, 80, 20, 0, 9, 198, 76, 144, 137, 72, 145, 78, 20, 9, 198, 28, 83, 210, 28, 145, 78, 20, 11, 200, 25, 32, 78, 12, 148, 203, 4, 224, 20, 0, 10, 135, 22, 21, 12, 7, 195, 166, 18, 20, 8, 197, 21, 2, 84, 21, 64, 20, 8, 197, 64, 240, 200, 21, 32, 20, 15, 204, 20, 180, 208, 21, 34, 77, 20, 229, 1, 72, 149, 77, 20, 8, 197, 29, 32, 78, 37, 64, 20, 8, 197, 28, 19, 66, 37, 64, 20, 8, 197, 20, 210, 82, 5, 64, 20, 8, 197, 8, 20, 130, 5, 32, 20, 14, 69, 5, 81, 213, 77, 64, 113, 81, 113, 89, 72, 0, 41, 0, 13, 202, 16, 81, 137, 9, 34, 76, 48, 21, 15, 72, 20, 9, 198, 4, 50, 68, 61, 49, 64, 20, 9, 198, 24, 244, 141, 21, 33, 64, 20, 9, 198, 104, 20, 137, 76, 209, 64, 20, 9, 198, 88, 84, 137, 76, 209, 64, 20, 9, 198, 76, 130, 73, 76, 209, 64, 20, 13, 138, 11, 22, 195, 166, 18, 21, 12, 1, 14, 20, 20, 0, 10, 199, 80, 18, 212, 21, 34, 78, 28, 20, 10, 199, 77, 3, 204, 21, 34, 78, 28, 20, 10, 199, 76, 243, 132, 21, 34, 78, 28, 20, 10, 199, 52, 243, 148, 21, 34, 78, 28, 20, 10, 199, 8, 20, 132, 21, 34, 78, 28, 20, 10, 199, 65, 34, 78, 76, 84, 211, 20, 20, 12, 201, 76, 176, 78, 16, 147, 129, 88, 145, 78, 20, 10, 199, 4, 36, 212, 36, 225, 78, 76, 20, 0, 11, 200, 36, 212, 18, 36, 208, 84, 85, 32, 20, 11, 200, 77, 1, 67, 36, 19, 9, 77, 64, 20, 11, 200, 56, 85, 84, 72, 19, 9, 77, 64, 20, 11, 200, 56, 21, 21, 72, 19, 9, 77, 64, 20, 11, 200, 44, 243, 139, 72, 85, 9, 77, 64, 20, 11, 200, 4, 36, 207, 49, 85, 9, 77, 64, 20, 7, 196, 28, 83, 143, 52, 20, 11, 200, 52, 241, 5, 72, 226, 84, 21, 64, 20, 11, 200, 48, 147, 133, 5, 34, 84, 21, 64, 20, 11, 200, 44, 243, 77, 84, 226, 84, 21, 64, 20, 11, 200, 24, 84, 212, 37, 98, 84, 21, 64, 20, 11, 200, 36, 226, 207, 52, 211, 196, 21, 32, 20, 9, 198, 8, 19, 19, 4, 210, 78, 20, 9, 198, 88, 83, 133, 104, 144, 78, 20, 9, 198, 60, 65, 78, 76, 80, 78, 20, 11, 200, 81, 34, 85, 53, 98, 82, 5, 64, 20, 9, 198, 44, 195, 196, 72, 144, 78, 21, 13, 72, 76, 85, 20, 48, 83, 69, 57, 64, 21, 0, 10, 0, 8, 197, 80, 242, 76, 21, 64, 20, 8, 197, 60, 209, 76, 21, 64, 20, 8, 197, 36, 99, 204, 21, 64, 20, 8, 197, 64, 20, 9, 77, 64, 20, 8, 197, 8, 147, 9, 77, 64, 20, 8, 197, 80, 244, 148, 21, 32, 20, 8, 197, 60, 181, 76, 21, 32, 20, 8, 197, 44, 243, 148, 21, 32, 20, 8, 197, 44, 20, 148, 21, 32, 20, 8, 197, 53, 84, 214, 37, 64, 20, 12, 201, 76, 177, 80, 80, 144, 201, 76, 209, 64, 20, 12, 201, 52, 84, 211, 36, 19, 137, 76, 209, 64, 20, 12, 201, 4, 229, 1, 28, 243, 137, 76, 209, 64, 20, 8, 197, 45, 32, 86, 5, 64, 20, 8, 197, 17, 32, 86, 5, 64, 20, 6, 195, 48, 144, 78, 21, 0, 17, 66, 16, 80, 72, 6, 37, 15, 72, 36, 34, 0, 81, 100, 101, 114, 32, 17, 66, 16, 80, 72, 6, 37, 15, 107, 36, 34, 0, 81, 104, 101, 114, 32, 18, 66, 16, 80, 72, 37, 15, 89, 47, 6, 36, 0, 81, 115, 116, 101, 103, 32, 13, 202, 25, 33, 75, 88, 83, 148, 21, 34, 78, 28, 20, 13, 202, 25, 32, 71, 52, 83, 148, 21, 34, 78, 28, 20, 13, 202, 4, 178, 210, 20, 66, 84, 21, 34, 78, 28, 20, 18, 143, 16, 1, 12, 195, 166, 19, 20, 9, 14, 5, 14, 19, 9, 19, 11, 20, 9, 198, 44, 243, 69, 16, 145, 64, 20, 9, 198, 28, 84, 129, 56, 145, 64, 20, 9, 198, 76, 147, 9, 12, 145, 64, 20, 9, 198, 28, 84, 129, 56, 145, 64, 20, 9, 198, 52, 19, 201, 76, 209, 64, 20, 9, 198, 45, 80, 137, 76, 209, 64, 20, 9, 198, 24, 20, 153, 56, 112, 76, 20, 9, 198, 52, 243, 148, 4, 113, 64, 20, 5, 194, 16, 80, 72, 0, 14, 203, 72, 84, 212, 72, 146, 212, 37, 98, 84, 21, 64, 20, 14, 203, 72, 17, 9, 60, 18, 212, 37, 98, 84, 21, 64, 20, 15, 140, 16, 195, 166, 4, 5, 18, 1, 19, 20, 9, 19, 11, 20, 12, 201, 77, 68, 133, 65, 67, 205, 100, 50, 78, 20, 10, 199, 44, 243, 15, 77, 67, 205, 36, 20, 10, 199, 80, 243, 5, 72, 19, 131, 20, 20, 6, 195, 32, 144, 84, 20, 6, 195, 4, 112, 84, 20, 0, 21, 68, 44, 244, 212, 20, 49, 39, 89, 72, 13, 15, 65, 109, 86, 0, 81, 109, 101, 100, 32, 19, 68, 88, 147, 12, 20, 84, 37, 55, 108, 15, 89, 114, 0, 81, 115, 195, 165, 32, 11, 200, 4, 116, 137, 45, 83, 20, 85, 32, 20, 11, 200, 72, 82, 77, 64, 244, 148, 21, 32, 20, 11, 200, 61, 35, 129, 52, 83, 148, 21, 32, 20, 11, 200, 44, 243, 134, 72, 243, 148, 21, 32, 20, 11, 200, 36, 229, 5, 73, 3, 204, 21, 32, 20, 11, 200, 36, 225, 11, 88, 20, 148, 21, 32, 20, 11, 200, 72, 84, 208, 60, 225, 5, 57, 64, 20, 11, 200, 44, 243, 147, 20, 181, 133, 57, 64, 20, 11, 200, 16, 83, 9, 56, 181, 133, 57, 64, 20, 11, 200, 37, 36, 133, 48, 85, 129, 57, 64, 20, 0, 12, 201, 88, 146, 193, 72, 145, 82, 36, 225, 192, 20, 12, 201, 81, 83, 142, 20, 193, 82, 36, 225, 192, 20, 12, 201, 80, 16, 149, 37, 49, 82, 36, 225, 192, 20, 12, 201, 77, 148, 212, 20, 209, 82, 36, 225, 192, 20, 12, 201, 77, 83, 6, 60, 225, 82, 36, 225, 192, 20, 12, 201, 77, 66, 77, 84, 193, 82, 36, 225, 192, 20, 12, 201, 76, 81, 210, 20, 113, 82, 36, 225, 192, 20, 12, 201, 72, 85, 21, 72, 225, 82, 36, 225, 192, 20, 12, 201, 64, 245, 5, 57, 49, 82, 36, 225, 192, 20, 12, 201, 64, 241, 19, 60, 193, 82, 36, 225, 192, 20, 12, 201, 56, 81, 204, 36, 113, 82, 36, 225, 192, 20, 12, 201, 48, 144, 197, 57, 49, 82, 36, 225, 192, 20, 12, 201, 45, 84, 148, 37, 49, 82, 36, 225, 192, 20, 12, 201, 45, 33, 78, 20, 193, 82, 36, 225, 192, 20, 12, 201, 44, 244, 146, 84, 113, 82, 36, 225, 192, 20, 12, 201, 41, 81, 1, 37, 49, 82, 36, 225, 192, 20, 12, 201, 36, 226, 204, 84, 65, 82, 36, 225, 192, 20, 12, 201, 36, 226, 193, 77, 49, 82, 36, 225, 192, 20, 12, 201, 36, 225, 5, 45, 49, 82, 36, 225, 192, 20, 12, 201, 25, 84, 201, 60, 225, 82, 36, 225, 192, 20, 12, 201, 24, 197, 75, 81, 81, 82, 36, 225, 192, 20, 12, 201, 8, 19, 132, 4, 113, 82, 36, 225, 192, 20, 12, 201, 5, 67, 205, 37, 49, 82, 36, 225, 192, 20, 12, 201, 5, 34, 193, 37, 49, 82, 36, 225, 192, 20, 12, 201, 4, 227, 143, 56, 49, 82, 36, 225, 192, 20, 12, 201, 4, 178, 207, 72, 65, 82, 36, 225, 192, 20, 8, 197, 20, 212, 9, 72, 144, 20, 11, 136, 195, 184, 11, 21, 13, 5, 14, 9, 20, 12, 201, 44, 21, 15, 48, 144, 201, 76, 209, 64, 20, 12, 201, 76, 145, 206, 36, 98, 75, 4, 229, 0, 20, 0, 14, 139, 195, 166, 18, 5, 6, 18, 25, 7, 20, 9, 7, 20, 9, 198, 65, 54, 75, 37, 50, 192, 20, 9, 198, 4, 84, 143, 48, 149, 0, 20, 13, 202, 20, 180, 212, 72, 21, 129, 28, 19, 131, 20, 20, 9, 198, 16, 21, 1, 52, 21, 0, 20, 0, 18, 67, 16, 85, 0, 72, 6, 36, 15, 72, 36, 34, 0, 81, 100, 101, 114, 32, 18, 67, 16, 85, 0, 72, 6, 36, 15, 107, 36, 34, 0, 81, 104, 101, 114, 32, 25, 67, 16, 85, 0, 72, 36, 15, 49, 84, 112, 6, 47, 36, 34, 0, 81, 107, 118, 97, 114, 116, 101, 114, 32, 10, 199, 20, 180, 197, 45, 85, 15, 72, 20, 10, 199, 20, 229, 15, 52, 243, 15, 28, 20, 9, 198, 52, 84, 139, 60, 227, 205, 20, 15, 140, 15, 13, 19, 20, 195, 166, 14, 4, 5, 12, 9, 7, 20, 9, 198, 88, 149, 129, 72, 149, 77, 20, 9, 67, 16, 85, 0, 72, 36, 0, 72, 0, 10, 135, 12, 195, 184, 10, 2, 15, 13, 20, 15, 204, 72, 21, 9, 60, 224, 76, 37, 49, 82, 36, 225, 192, 20, 15, 204, 65, 35, 204, 21, 64, 82, 37, 49, 82, 36, 225, 192, 20, 15, 204, 65, 34, 77, 37, 66, 86, 37, 49, 82, 36, 225, 192, 20, 15, 204, 64, 84, 147, 60, 224, 76, 37, 49, 82, 36, 225, 192, 20, 15, 204, 64, 20, 129, 48, 193, 76, 37, 49, 82, 36, 225, 192, 20, 15, 204, 60, 34, 133, 45, 66, 86, 37, 49, 82, 36, 225, 192, 20, 15, 204, 56, 21, 9, 60, 224, 76, 37, 49, 82, 36, 225, 192, 20, 15, 204, 52, 20, 135, 36, 224, 76, 37, 49, 82, 36, 225, 192, 20, 15, 204, 45, 34, 77, 36, 224, 76, 37, 49, 82, 36, 225, 192, 20, 15, 204, 44, 243, 77, 84, 224, 76, 37, 49, 82, 36, 225, 192, 20, 15, 204, 44, 20, 129, 45, 65, 82, 37, 49, 82, 36, 225, 192, 20, 15, 204, 44, 19, 142, 36, 32, 76, 37, 49, 82, 36, 225, 192, 20, 15, 204, 36, 229, 5, 72, 224, 76, 37, 49, 82, 36, 225, 192, 20, 15, 204, 24, 19, 73, 48, 144, 82, 37, 49, 82, 36, 225, 192, 20, 15, 204, 20, 193, 75, 81, 34, 70, 36, 49, 82, 36, 225, 192, 20, 15, 204, 20, 97, 133, 45, 66, 86, 37, 49, 82, 36, 225, 192, 20, 15, 204, 16, 149, 133, 73, 50, 70, 36, 49, 82, 36, 225, 192, 20, 15, 204, 16, 145, 134, 21, 33, 78, 80, 145, 82, 36, 225, 192, 20, 15, 204, 12, 243, 80, 85, 65, 82, 37, 49, 82, 36, 225, 192, 20, 15, 204, 4, 209, 82, 36, 176, 78, 37, 49, 82, 36, 225, 192, 20, 7, 196, 72, 17, 5, 72, 20, 11, 200, 45, 35, 206, 60, 209, 84, 72, 144, 20, 11, 200, 5, 81, 9, 60, 209, 84, 72, 144, 20, 11, 200, 36, 195, 21, 76, 244, 137, 76, 176, 20, 11, 200, 21, 128, 197, 57, 68, 137, 76, 176, 20, 11, 200, 4, 195, 21, 76, 244, 137, 76, 176, 20, 11, 200, 56, 82, 210, 60, 208, 78, 80, 144, 20, 7, 196, 37, 35, 206, 36, 20, 11, 200, 8, 144, 140, 36, 243, 65, 56, 144, 20, 15, 204, 44, 243, 147, 81, 37, 75, 80, 149, 137, 76, 209, 64, 20, 9, 198, 52, 19, 132, 72, 147, 0, 20, 14, 4, 95, 4, 16, 20, 10, 49, 4, 114, 65, 110, 12, 0, 0, 10, 135, 16, 1, 18, 12, 195, 184, 18, 20, 12, 201, 52, 146, 210, 60, 225, 83, 37, 50, 192, 20, 8, 197, 64, 245, 1, 28, 80, 20, 0, 29, 4, 7, 195, 184, 18, 81, 4, 118, 34, 15, 89, 35, 57, 15, 47, 6, 36, 55, 0, 82, 115, 105, 103, 32, 116, 105, 108, 32, 17, 66, 17, 80, 72, 40, 15, 107, 110, 12, 0, 81, 104, 97, 118, 101, 32, 10, 135, 6, 9, 2, 18, 195, 184, 19, 20, 11, 136, 19, 15, 9, 7, 14, 195, 184, 18, 20, 9, 198, 44, 20, 129, 52, 35, 204, 20, 9, 198, 76, 19, 65, 72, 149, 0, 20, 9, 198, 32, 16, 137, 80, 21, 0, 20, 8, 66, 17, 80, 72, 40, 0, 72, 0, 11, 136, 19, 11, 1, 2, 18, 195, 184, 19, 20, 11, 136, 7, 18, 1, 3, 9, 195, 184, 19, 20, 10, 199, 36, 227, 143, 88, 21, 15, 72, 20, 18, 207, 65, 35, 198, 21, 52, 201, 60, 224, 76, 37, 49, 82, 36, 225, 192, 20, 10, 199, 72, 84, 212, 37, 69, 69, 72, 20, 10, 199, 72, 81, 140, 20, 181, 5, 72, 20, 10, 199, 65, 35, 199, 72, 81, 5, 72, 20, 10, 199, 44, 243, 147, 80, 21, 5, 72, 20, 15, 140, 6, 15, 18, 20, 18, 195, 166, 4, 5, 12, 9, 7, 20, 11, 136, 19, 6, 195, 166, 18, 9, 19, 11, 20, 10, 199, 4, 68, 133, 56, 19, 9, 56, 20, 6, 195, 4, 114, 76, 20, 10, 199, 8, 19, 12, 37, 53, 9, 44, 20, 6, 195, 32, 19, 64, 72, 0, 13, 138, 14, 1, 22, 9, 7, 1, 20, 195, 184, 18, 20, 7, 196, 52, 147, 149, 80, 20, 11, 200, 8, 241, 211, 80, 21, 133, 72, 80, 20, 11, 200, 77, 147, 77, 21, 68, 137, 76, 176, 20, 11, 200, 8, 147, 205, 21, 68, 137, 76, 176, 20, 11, 200, 44, 243, 147, 61, 37, 9, 84, 208, 20, 11, 200, 56, 85, 82, 5, 53, 5, 56, 144, 20, 9, 198, 32, 243, 79, 24, 147, 0, 20, 0, 9, 134, 19, 5, 18, 195, 184, 19, 20, 10, 135, 11, 15, 18, 19, 195, 184, 18, 20, 10, 135, 11, 12, 1, 11, 195, 184, 18, 20, 8, 197, 32, 83, 132, 21, 48, 76, 0, 9, 198, 4, 36, 207, 49, 85, 0, 20, 9, 198, 24, 195, 210, 37, 53, 0, 20, 9, 198, 76, 22, 15, 24, 243, 128, 20, 9, 198, 65, 35, 199, 72, 19, 64, 20, 9, 198, 56, 147, 194, 37, 83, 64, 20, 9, 198, 52, 20, 139, 21, 33, 84, 20, 0, 22, 9, 6, 195, 184, 12, 10, 5, 20, 15, 14, 83, 118, 55, 57, 36, 47, 6, 114, 50, 0, 20, 10, 199, 24, 147, 129, 57, 50, 69, 48, 20, 14, 203, 80, 84, 212, 4, 209, 78, 80, 20, 137, 76, 176, 20, 14, 203, 64, 20, 140, 4, 209, 78, 80, 20, 137, 76, 176, 20, 10, 199, 8, 83, 133, 24, 144, 201, 20, 20, 10, 199, 21, 81, 133, 52, 148, 205, 20, 20, 10, 199, 64, 84, 212, 36, 193, 78, 76, 20, 10, 199, 36, 212, 12, 4, 229, 1, 80, 20, 12, 201, 44, 21, 1, 77, 68, 143, 24, 19, 0, 20, 6, 195, 20, 112, 76, 20, 12, 4, 95, 49, 48, 15, 47, 37, 13, 50, 108, 0, 0, 7, 196, 76, 19, 21, 80, 20, 9, 198, 60, 36, 212, 73, 81, 82, 20, 9, 198, 36, 228, 213, 49, 65, 82, 20, 9, 198, 36, 228, 212, 73, 81, 82, 20, 9, 198, 36, 225, 143, 72, 209, 82, 20, 9, 198, 36, 225, 12, 21, 97, 82, 20, 9, 198, 5, 32, 137, 81, 33, 82, 20, 12, 137, 11, 9, 13, 195, 166, 18, 9, 19, 11, 20, 11, 200, 44, 83, 143, 80, 17, 137, 84, 208, 20, 7, 196, 36, 229, 73, 80, 20, 9, 198, 12, 20, 132, 36, 112, 78, 21, 0, 9, 198, 52, 85, 18, 60, 195, 199, 20, 12, 201, 16, 243, 79, 72, 112, 78, 37, 53, 0, 20, 12, 201, 5, 69, 18, 36, 37, 84, 36, 243, 128, 20, 17, 142, 19, 20, 18, 1, 20, 15, 19, 6, 195, 166, 18, 9, 19, 11, 20, 8, 197, 64, 245, 5, 57, 48, 20, 0, 21, 66, 4, 192, 35, 55, 15, 49, 6, 35, 57, 72, 35, 0, 81, 113, 97, 101, 100, 97, 32, 14, 139, 7, 1, 14, 7, 18, 195, 166, 14, 195, 184, 19, 20, 9, 198, 28, 19, 66, 37, 53, 0, 20, 9, 198, 52, 83, 1, 56, 243, 64, 20, 12, 137, 22, 18, 195, 184, 22, 12, 5, 18, 9, 20, 14, 139, 13, 9, 12, 9, 20, 195, 166, 18, 9, 19, 11, 20, 9, 198, 24, 84, 141, 20, 229, 0, 20, 9, 198, 52, 19, 137, 21, 33, 84, 20, 9, 198, 52, 20, 139, 4, 229, 0, 20, 0, 10, 199, 88, 149, 1, 48, 149, 5, 80, 20, 10, 199, 80, 245, 1, 48, 149, 5, 80, 20, 10, 199, 76, 243, 9, 16, 149, 5, 80, 20, 10, 199, 76, 83, 137, 48, 149, 5, 80, 20, 10, 199, 72, 149, 129, 48, 149, 5, 80, 20, 10, 199, 72, 145, 201, 16, 149, 5, 80, 20, 10, 199, 72, 20, 9, 16, 149, 5, 80, 20, 10, 199, 56, 240, 137, 48, 149, 5, 80, 20, 10, 199, 56, 21, 1, 48, 149, 5, 80, 20, 10, 199, 56, 20, 193, 48, 149, 5, 80, 20, 10, 199, 52, 241, 1, 48, 149, 5, 80, 20, 10, 199, 52, 240, 137, 48, 149, 5, 80, 20, 10, 199, 48, 242, 193, 48, 149, 5, 80, 20, 10, 199, 48, 81, 193, 48, 149, 5, 80, 20, 10, 199, 36, 211, 85, 56, 149, 5, 80, 20, 10, 199, 36, 65, 65, 48, 149, 5, 80, 20, 10, 199, 24, 145, 5, 48, 149, 5, 80, 20, 10, 199, 24, 21, 1, 48, 149, 5, 80, 20, 10, 199, 24, 16, 201, 48, 149, 5, 80, 20, 10, 199, 16, 80, 137, 48, 149, 5, 80, 20, 10, 199, 76, 82, 212, 61, 34, 69, 48, 20, 10, 199, 21, 52, 197, 57, 66, 69, 48, 20, 10, 199, 8, 18, 212, 21, 34, 69, 48, 20, 12, 201, 80, 82, 206, 60, 195, 199, 37, 49, 82, 20, 12, 201, 44, 243, 80, 72, 243, 73, 81, 65, 82, 20, 13, 138, 19, 11, 18, 195, 166, 4, 4, 5, 18, 9, 20, 15, 140, 1, 20, 13, 15, 19, 6, 195, 166, 18, 9, 19, 11, 20, 10, 199, 44, 243, 135, 20, 226, 65, 48, 20, 0, 9, 198, 72, 80, 197, 65, 69, 82, 20, 7, 196, 16, 243, 143, 72, 20, 9, 198, 44, 242, 203, 21, 33, 82, 20, 9, 198, 24, 147, 135, 21, 33, 82, 20, 9, 198, 16, 81, 140, 61, 33, 82, 20, 14, 139, 15, 16, 20, 18, 195, 166, 11, 11, 5, 18, 9, 20, 16, 141, 11, 22, 195, 166, 18, 21, 12, 1, 14, 20, 9, 19, 11, 20, 16, 141, 1, 13, 1, 20, 195, 184, 18, 9, 19, 20, 9, 19, 11, 20, 7, 196, 45, 33, 84, 36, 20, 7, 196, 44, 19, 137, 56, 20, 11, 136, 13, 195, 166, 3, 5, 14, 1, 20, 20, 9, 198, 56, 20, 139, 60, 208, 78, 21, 9, 3, 95, 35, 57, 47, 35, 71, 0, 12, 4, 95, 20, 12, 4, 47, 37, 55, 72, 13, 0, 0, 12, 201, 61, 5, 15, 52, 85, 18, 37, 53, 0, 20, 12, 201, 32, 148, 212, 61, 34, 67, 37, 65, 84, 20, 12, 201, 20, 193, 75, 81, 34, 67, 37, 65, 84, 20, 12, 201, 5, 85, 5, 57, 66, 67, 37, 65, 84, 20, 11, 136, 20, 195, 184, 18, 18, 5, 18, 9, 20, 8, 197, 52, 243, 135, 60, 192, 20, 8, 197, 104, 80, 200, 36, 224, 20, 0, 13, 202, 77, 2, 82, 37, 69, 65, 48, 149, 5, 80, 20, 13, 202, 65, 49, 85, 16, 243, 153, 52, 149, 5, 80, 20, 13, 202, 44, 243, 135, 20, 226, 65, 48, 149, 5, 80, 20, 13, 202, 36, 195, 5, 28, 149, 9, 52, 149, 5, 80, 20, 13, 202, 24, 193, 75, 76, 144, 137, 48, 149, 5, 80, 20, 9, 198, 72, 81, 213, 48, 84, 128, 20, 9, 198, 21, 53, 9, 52, 84, 128, 20, 12, 137, 19, 11, 195, 166, 12, 13, 5, 18, 9, 20, 15, 140, 195, 165, 12, 2, 15, 18, 7, 5, 14, 19, 5, 18, 20, 15, 140, 6, 195, 165, 2, 15, 18, 7, 5, 14, 19, 5, 18, 20, 9, 198, 76, 82, 214, 20, 228, 192, 20, 9, 198, 72, 84, 212, 4, 229, 0, 20, 0, 12, 201, 81, 32, 78, 76, 98, 71, 85, 33, 82, 20, 10, 199, 72, 21, 9, 60, 225, 82, 20, 20, 10, 199, 64, 19, 12, 21, 65, 82, 20, 20, 10, 199, 45, 83, 13, 36, 225, 82, 20, 20, 10, 199, 24, 244, 198, 5, 65, 82, 20, 20, 10, 199, 4, 181, 9, 60, 225, 82, 20, 20, 9, 198, 48, 147, 143, 48, 85, 77, 20, 9, 198, 76, 147, 9, 12, 149, 77, 20, 10, 199, 32, 82, 212, 60, 116, 129, 24, 20, 0, 23, 72, 4, 180, 143, 77, 66, 75, 60, 224, 35, 49, 34, 114, 89, 72, 37, 49, 6, 114, 50, 0, 20, 9, 198, 64, 21, 137, 48, 195, 206, 20, 9, 198, 52, 81, 1, 48, 163, 206, 20, 11, 200, 20, 180, 208, 4, 228, 201, 60, 224, 20, 11, 200, 16, 84, 18, 21, 52, 201, 60, 224, 20, 12, 201, 88, 84, 147, 36, 243, 133, 72, 147, 135, 20, 11, 200, 76, 145, 82, 72, 19, 5, 60, 224, 20, 0, 8, 197, 88, 83, 148, 36, 192, 20, 8, 197, 28, 83, 148, 36, 192, 20, 12, 201, 88, 144, 143, 72, 113, 78, 76, 84, 128, 20, 8, 197, 76, 195, 214, 20, 224, 20, 12, 201, 77, 80, 147, 45, 34, 66, 20, 229, 0, 20, 12, 201, 44, 243, 148, 72, 243, 12, 4, 229, 0, 20, 8, 197, 64, 20, 211, 4, 32, 20, 0, 23, 66, 21, 64, 36, 72, 15, 83, 6, 114, 34, 89, 116, 50, 0, 81, 102, 111, 114, 115, 121, 110, 32, 17, 66, 21, 64, 36, 72, 15, 107, 6, 112, 40, 0, 81, 104, 97, 118, 32, 17, 66, 21, 64, 36, 72, 15, 6, 83, 39, 34, 0, 81, 102, 111, 114, 32, 16, 66, 21, 64, 36, 72, 15, 107, 112, 40, 0, 81, 104, 97, 118, 32, 24, 66, 21, 64, 36, 47, 15, 49, 84, 112, 6, 47, 36, 34, 0, 81, 107, 118, 97, 114, 116, 101, 114, 32, 13, 202, 76, 83, 22, 24, 147, 129, 57, 50, 69, 72, 20, 9, 198, 60, 213, 18, 20, 229, 0, 20, 9, 198, 44, 243, 132, 20, 228, 192, 20, 11, 70, 76, 178, 78, 32, 80, 68, 21, 0, 10, 8, 66, 21, 64, 36, 47, 0, 72, 0, 12, 137, 6, 1, 13, 9, 12, 9, 195, 166, 18, 20, 10, 199, 60, 33, 21, 45, 66, 79, 56, 20, 10, 199, 36, 225, 21, 45, 66, 79, 56, 20, 10, 199, 72, 82, 204, 4, 209, 82, 20, 20, 10, 199, 12, 128, 77, 9, 34, 69, 72, 20, 10, 199, 4, 227, 143, 56, 49, 82, 20, 20, 9, 198, 64, 243, 25, 28, 19, 73, 20, 10, 199, 21, 128, 197, 57, 68, 137, 44, 20, 10, 199, 32, 84, 140, 61, 98, 65, 56, 20, 10, 199, 44, 244, 144, 84, 193, 78, 80, 20, 0, 13, 138, 19, 21, 2, 19, 9, 4, 9, 195, 166, 18, 20, 9, 134, 2, 5, 7, 195, 166, 18, 20, 11, 200, 72, 81, 210, 21, 52, 201, 60, 224, 20, 11, 200, 60, 178, 193, 76, 147, 206, 20, 192, 20, 11, 200, 25, 83, 139, 80, 147, 206, 20, 192, 20, 7, 196, 24, 83, 143, 48, 20, 12, 137, 6, 195, 184, 14, 9, 11, 9, 19, 11, 20, 0, 10, 135, 16, 18, 5, 11, 195, 166, 18, 20, 8, 197, 52, 19, 201, 77, 64, 20, 8, 197, 45, 33, 77, 21, 32, 20, 8, 197, 65, 35, 198, 37, 64, 20, 8, 197, 52, 17, 206, 5, 64, 20, 8, 197, 24, 244, 198, 5, 64, 20, 8, 197, 88, 243, 1, 57, 64, 20, 12, 201, 64, 20, 148, 36, 50, 80, 4, 229, 0, 20, 8, 197, 45, 83, 1, 57, 64, 20, 0, 13, 202, 44, 243, 147, 80, 84, 142, 5, 66, 79, 56, 20, 13, 202, 36, 226, 207, 73, 3, 210, 5, 66, 79, 56, 20, 9, 198, 4, 209, 137, 8, 145, 64, 20, 8, 133, 195, 165, 18, 20, 9, 20, 9, 198, 81, 84, 137, 76, 209, 64, 20, 9, 198, 80, 19, 201, 76, 209, 64, 20, 9, 198, 72, 16, 201, 76, 209, 64, 20, 9, 198, 65, 84, 137, 76, 209, 64, 20, 9, 198, 56, 22, 137, 76, 209, 64, 20, 9, 198, 49, 148, 137, 76, 209, 64, 20, 9, 198, 20, 115, 201, 76, 209, 64, 20, 13, 202, 48, 145, 67, 33, 65, 78, 77, 65, 73, 56, 20, 9, 198, 80, 243, 142, 4, 113, 64, 20, 9, 198, 12, 245, 82, 4, 113, 64, 20, 0, 10, 135, 6, 195, 166, 18, 9, 19, 20, 20, 10, 199, 81, 84, 142, 21, 34, 78, 28, 20, 10, 199, 80, 18, 211, 21, 34, 78, 28, 20, 10, 199, 64, 192, 78, 21, 34, 78, 28, 20, 10, 199, 48, 19, 131, 21, 34, 78, 28, 20, 10, 199, 28, 20, 142, 21, 34, 78, 28, 20, 10, 199, 24, 146, 211, 21, 34, 78, 28, 20, 10, 199, 8, 20, 130, 21, 34, 78, 28, 20, 13, 4, 95, 49, 50, 15, 47, 114, 55, 83, 72, 108, 0, 0, 11, 200, 64, 243, 25, 32, 148, 212, 61, 32, 20, 13, 138, 11, 15, 13, 13, 9, 19, 19, 195, 166, 18, 20, 11, 200, 65, 81, 82, 36, 194, 84, 21, 64, 20, 11, 200, 65, 80, 140, 36, 50, 84, 21, 64, 20, 11, 200, 64, 21, 5, 72, 226, 84, 21, 64, 20, 11, 200, 44, 21, 83, 4, 194, 84, 21, 64, 20, 11, 200, 25, 37, 71, 4, 194, 84, 21, 64, 20, 11, 200, 25, 34, 86, 60, 194, 84, 21, 64, 20, 11, 200, 25, 32, 71, 36, 194, 84, 21, 64, 20, 11, 200, 4, 226, 77, 61, 50, 84, 21, 64, 20, 11, 200, 4, 208, 137, 29, 82, 84, 21, 64, 20, 9, 198, 8, 20, 148, 32, 144, 78, 20, 9, 198, 4, 100, 137, 44, 16, 78, 20, 9, 198, 4, 100, 137, 44, 16, 78, 20, 11, 200, 20, 180, 203, 72, 83, 69, 57, 64, 20, 11, 200, 5, 34, 83, 80, 242, 210, 5, 64, 20, 0, 8, 197, 80, 21, 140, 21, 64, 20, 8, 197, 76, 242, 204, 21, 64, 20, 11, 136, 12, 195, 166, 11, 11, 5, 18, 9, 20, 11, 136, 8, 195, 184, 14, 19, 5, 18, 9, 20, 13, 138, 7, 5, 15, 4, 195, 166, 20, 9, 19, 11, 20, 13, 138, 5, 21, 18, 15, 16, 195, 166, 9, 19, 11, 20, 8, 197, 76, 241, 134, 37, 64, 20, 12, 201, 28, 227, 211, 80, 144, 201, 76, 209, 64, 20, 12, 201, 9, 32, 72, 52, 19, 137, 76, 209, 64, 20, 8, 197, 64, 245, 5, 57, 64, 20, 8, 197, 64, 84, 211, 5, 32, 20, 0, 13, 202, 88, 84, 130, 4, 194, 83, 21, 34, 78, 28, 20, 13, 202, 81, 148, 129, 56, 226, 83, 21, 34, 78, 28, 20, 13, 202, 77, 65, 82, 36, 194, 83, 21, 34, 78, 28, 20, 13, 202, 77, 64, 66, 36, 194, 83, 21, 34, 78, 28, 20, 13, 202, 76, 145, 206, 4, 194, 83, 21, 34, 78, 28, 20, 13, 202, 52, 85, 1, 48, 194, 83, 21, 34, 78, 28, 20, 13, 202, 52, 20, 203, 36, 226, 83, 21, 34, 78, 28, 20, 13, 202, 32, 20, 141, 60, 226, 83, 21, 34, 78, 28, 20, 13, 202, 28, 84, 141, 4, 226, 83, 21, 34, 78, 28, 20, 13, 202, 28, 19, 22, 4, 226, 83, 21, 34, 78, 28, 20, 13, 202, 16, 149, 137, 76, 147, 206, 21, 34, 78, 28, 20, 13, 202, 8, 19, 11, 4, 226, 83, 21, 34, 78, 28, 20, 13, 202, 4, 32, 78, 16, 243, 142, 21, 34, 78, 28, 20, 12, 201, 81, 34, 71, 60, 227, 205, 21, 68, 137, 20, 14, 139, 16, 20, 15, 12, 5, 13, 195, 166, 9, 19, 11, 20, 9, 198, 24, 19, 73, 48, 145, 64, 20, 9, 198, 20, 225, 9, 88, 145, 64, 20, 9, 198, 88, 149, 129, 72, 145, 64, 20, 9, 198, 72, 83, 69, 16, 145, 64, 20, 9, 198, 4, 181, 129, 72, 145, 64, 20, 9, 198, 45, 147, 137, 76, 209, 64, 20, 9, 198, 60, 97, 137, 12, 144, 76, 20, 9, 198, 4, 195, 21, 88, 144, 76, 20, 17, 70, 8, 243, 132, 4, 113, 64, 71, 6, 114, 50, 72, 37, 75, 0, 20, 9, 198, 8, 19, 132, 4, 113, 64, 20, 11, 70, 8, 243, 132, 4, 113, 64, 21, 0, 10, 0, 14, 203, 44, 243, 147, 81, 37, 75, 80, 149, 137, 77, 64, 20, 14, 203, 64, 20, 129, 16, 242, 211, 4, 194, 84, 21, 64, 20, 15, 140, 8, 5, 13, 9, 19, 6, 195, 166, 18, 9, 19, 11, 20, 10, 199, 44, 243, 134, 49, 81, 78, 76, 20, 10, 199, 4, 208, 149, 48, 19, 131, 20, 20, 0, 7, 196, 76, 243, 143, 72, 20, 11, 200, 97, 147, 15, 24, 243, 137, 77, 64, 20, 11, 200, 88, 84, 147, 36, 243, 137, 77, 64, 20, 11, 200, 44, 195, 203, 44, 83, 137, 77, 64, 20, 16, 141, 11, 1, 13, 195, 166, 12, 5, 15, 14, 20, 9, 19, 11, 20, 9, 198, 32, 21, 193, 36, 144, 78, 20, 7, 196, 61, 51, 65, 56, 21, 7, 196, 8, 242, 129, 72, 20, 0, 12, 137, 6, 12, 195, 184, 10, 20, 9, 19, 20, 20, 16, 205, 84, 66, 210, 101, 53, 1, 48, 194, 83, 21, 34, 78, 28, 20, 12, 201, 73, 80, 146, 36, 49, 82, 36, 225, 192, 20, 16, 205, 36, 225, 21, 77, 68, 137, 4, 194, 83, 21, 34, 78, 28, 20, 12, 201, 24, 84, 142, 37, 49, 82, 36, 225, 192, 20, 16, 205, 16, 149, 137, 76, 147, 206, 4, 194, 83, 21, 34, 78, 28, 20, 11, 136, 19, 20, 195, 184, 2, 5, 18, 9, 20, 13, 138, 15, 16, 12, 195, 184, 19, 5, 12, 9, 7, 20, 13, 138, 7, 5, 12, 195, 169, 1, 7, 20, 9, 7, 20, 17, 142, 9, 14, 4, 15, 5, 21, 18, 15, 16, 195, 166, 9, 19, 11, 20, 12, 201, 72, 84, 208, 60, 228, 207, 72, 145, 64, 20, 12, 201, 48, 19, 65, 72, 50, 201, 76, 209, 64, 20, 12, 201, 12, 128, 85, 88, 147, 137, 76, 209, 64, 20, 12, 201, 44, 20, 129, 52, 35, 204, 4, 113, 64, 20, 10, 69, 72, 83, 65, 44, 80, 21, 0, 10, 0, 9, 198, 48, 85, 1, 72, 114, 64, 20, 14, 139, 9, 14, 4, 12, 195, 184, 19, 5, 12, 9, 7, 20, 9, 198, 4, 225, 18, 60, 145, 0, 20, 13, 202, 64, 20, 148, 20, 227, 199, 20, 225, 83, 20, 20, 13, 202, 25, 33, 68, 21, 34, 75, 76, 128, 86, 56, 20, 8, 198, 4, 35, 210, 36, 114, 64, 0, 10, 199, 24, 147, 129, 57, 50, 69, 72, 20, 10, 199, 24, 147, 15, 76, 241, 133, 72, 20, 10, 199, 61, 33, 7, 100, 65, 82, 36, 20, 10, 199, 45, 83, 147, 80, 193, 82, 36, 20, 10, 199, 44, 242, 197, 81, 65, 82, 36, 20, 10, 199, 44, 194, 77, 65, 33, 82, 36, 20, 10, 199, 41, 84, 137, 77, 65, 82, 36, 20, 13, 138, 7, 5, 14, 4, 195, 184, 2, 5, 18, 9, 20, 10, 199, 16, 21, 1, 52, 21, 9, 44, 20, 10, 199, 72, 81, 197, 57, 50, 65, 56, 20, 10, 199, 24, 195, 210, 20, 229, 9, 56, 20, 10, 199, 44, 243, 132, 20, 211, 129, 8, 20, 0, 11, 200, 17, 32, 77, 5, 69, 82, 28, 144, 20, 11, 200, 76, 147, 85, 48, 84, 137, 56, 112, 20, 15, 204, 64, 84, 147, 60, 226, 70, 36, 49, 82, 36, 225, 192, 20, 15, 204, 52, 20, 203, 84, 194, 78, 37, 49, 82, 36, 225, 192, 20, 16, 141, 12, 5, 20, 15, 16, 12, 195, 184, 19, 5, 12, 9, 7, 20, 9, 198, 64, 20, 129, 8, 243, 0, 20, 11, 200, 77, 81, 1, 56, 84, 201, 76, 176, 20, 11, 200, 52, 147, 137, 77, 65, 82, 36, 80, 20, 15, 204, 20, 180, 208, 21, 34, 77, 20, 229, 1, 72, 145, 64, 20, 7, 196, 81, 82, 193, 56, 21, 9, 198, 64, 19, 1, 80, 19, 0, 20, 0, 8, 197, 8, 84, 204, 60, 112, 20, 15, 69, 8, 83, 9, 104, 80, 71, 36, 55, 37, 12, 89, 0, 66, 17, 142, 20, 9, 12, 19, 20, 18, 195, 166, 11, 11, 5, 12, 9, 7, 20, 13, 138, 20, 9, 12, 6, 195, 166, 12, 4, 9, 7, 20, 12, 201, 44, 243, 77, 37, 69, 5, 72, 85, 0, 20, 0, 5, 194, 21, 80, 17, 18, 70, 8, 80, 200, 4, 209, 76, 71, 36, 91, 35, 65, 6, 36, 12, 60, 0, 9, 198, 80, 16, 140, 60, 145, 0, 20, 9, 198, 64, 243, 25, 4, 210, 68, 20, 18, 70, 61, 34, 71, 4, 210, 64, 39, 34, 36, 81, 6, 35, 65, 37, 0, 20, 9, 198, 77, 80, 140, 36, 208, 84, 20, 0, 14, 203, 4, 195, 5, 28, 244, 137, 76, 84, 137, 56, 112, 20, 12, 201, 52, 147, 137, 77, 65, 82, 36, 83, 0, 20, 10, 199, 4, 99, 65, 72, 50, 5, 72, 20, 19, 144, 19, 1, 13, 13, 5, 14, 20, 18, 195, 166, 11, 11, 5, 12, 9, 7, 20, 15, 140, 14, 195, 184, 4, 20, 195, 184, 18, 6, 20, 9, 7, 20, 14, 203, 72, 81, 204, 20, 209, 78, 80, 20, 137, 76, 176, 20, 10, 199, 52, 19, 5, 72, 147, 132, 20, 20, 10, 199, 8, 243, 19, 40, 85, 137, 44, 20, 0, 9, 198, 88, 144, 146, 4, 99, 206, 20, 11, 200, 80, 245, 67, 32, 84, 137, 56, 112, 20, 11, 200, 76, 176, 78, 16, 84, 137, 56, 112, 20, 11, 200, 76, 176, 77, 24, 84, 137, 56, 112, 20, 11, 200, 73, 83, 83, 80, 84, 137, 56, 112, 20, 11, 200, 72, 81, 149, 76, 84, 137, 56, 112, 20, 11, 200, 72, 81, 133, 72, 84, 137, 56, 112, 20, 11, 200, 72, 81, 9, 28, 84, 137, 56, 112, 20, 11, 200, 64, 242, 78, 80, 84, 137, 56, 112, 20, 11, 200, 64, 192, 71, 36, 84, 137, 56, 112, 20, 11, 200, 64, 21, 9, 56, 84, 137, 56, 112, 20, 11, 200, 61, 5, 9, 52, 84, 137, 56, 112, 20, 11, 200, 52, 245, 9, 88, 84, 137, 56, 112, 20, 11, 200, 44, 17, 13, 36, 84, 137, 56, 112, 20, 11, 200, 40, 243, 135, 48, 84, 137, 56, 112, 20, 11, 200, 36, 226, 84, 36, 84, 137, 56, 112, 20, 11, 200, 32, 243, 143, 72, 84, 137, 56, 112, 20, 11, 200, 29, 37, 80, 64, 84, 137, 56, 112, 20, 11, 200, 20, 208, 76, 40, 84, 137, 56, 112, 20, 11, 200, 20, 181, 137, 64, 84, 137, 56, 112, 20, 11, 200, 16, 85, 143, 88, 84, 137, 56, 112, 20, 11, 200, 16, 80, 201, 52, 84, 137, 56, 112, 20, 11, 200, 12, 83, 148, 72, 84, 137, 56, 112, 20, 11, 200, 12, 17, 13, 36, 84, 137, 56, 112, 20, 11, 200, 9, 32, 73, 76, 84, 137, 56, 112, 20, 11, 200, 4, 192, 82, 52, 84, 137, 56, 112, 20, 11, 200, 4, 181, 9, 88, 84, 137, 56, 112, 20, 11, 200, 4, 69, 137, 76, 84, 137, 56, 112, 20, 11, 200, 4, 35, 210, 80, 84, 137, 56, 112, 20, 14, 68, 44, 19, 133, 48, 49, 110, 50, 6, 36, 55, 0, 20, 11, 200, 81, 35, 205, 64, 85, 5, 72, 80, 20, 11, 200, 44, 243, 131, 21, 37, 5, 72, 80, 20, 11, 200, 21, 66, 75, 21, 69, 5, 72, 80, 20, 11, 200, 9, 81, 7, 21, 69, 5, 72, 80, 20, 11, 200, 9, 34, 75, 21, 69, 5, 72, 80, 20, 12, 137, 16, 25, 7, 13, 195, 166, 9, 19, 11, 20, 11, 200, 60, 194, 71, 5, 34, 201, 76, 176, 20, 11, 200, 72, 81, 133, 45, 67, 210, 36, 80, 20, 11, 200, 65, 35, 214, 37, 51, 210, 36, 80, 20, 11, 200, 45, 33, 77, 5, 67, 210, 36, 80, 20, 7, 196, 24, 147, 137, 80, 20, 7, 196, 32, 16, 137, 48, 20, 11, 200, 61, 35, 129, 52, 83, 148, 36, 176, 20, 12, 137, 4, 9, 195, 166, 20, 5, 20, 9, 11, 20, 9, 198, 12, 20, 137, 8, 145, 78, 20, 7, 196, 5, 50, 65, 80, 20, 11, 200, 77, 4, 153, 17, 53, 1, 28, 80, 20, 0, 6, 195, 48, 145, 82, 20, 10, 69, 8, 244, 212, 60, 224, 21, 0, 10, 0, 13, 202, 81, 32, 78, 76, 99, 210, 52, 21, 15, 72, 20, 9, 198, 16, 21, 1, 56, 243, 64, 20, 0, 14, 203, 80, 84, 212, 4, 209, 78, 80, 84, 137, 56, 112, 20, 14, 203, 77, 147, 139, 72, 85, 9, 76, 84, 137, 56, 112, 20, 10, 199, 77, 69, 68, 21, 34, 78, 28, 20, 14, 203, 76, 147, 80, 48, 145, 137, 12, 84, 137, 56, 112, 20, 10, 199, 76, 19, 4, 21, 34, 78, 28, 20, 14, 203, 64, 244, 21, 48, 20, 137, 76, 84, 137, 56, 112, 20, 14, 203, 64, 20, 140, 4, 209, 78, 80, 84, 137, 56, 112, 20, 10, 199, 64, 19, 16, 21, 34, 78, 28, 20, 10, 199, 45, 33, 77, 21, 34, 78, 28, 20, 14, 203, 44, 19, 12, 36, 116, 129, 24, 84, 137, 56, 112, 20, 14, 203, 36, 65, 79, 48, 241, 201, 76, 84, 137, 56, 112, 20, 14, 203, 25, 83, 132, 4, 209, 78, 80, 84, 137, 56, 112, 20, 14, 203, 24, 244, 198, 61, 33, 83, 12, 84, 137, 56, 112, 20, 10, 199, 20, 213, 76, 21, 34, 78, 28, 20, 14, 203, 5, 85, 15, 52, 21, 9, 76, 84, 137, 56, 112, 20, 14, 203, 4, 193, 129, 8, 85, 9, 76, 84, 137, 56, 112, 20, 12, 201, 61, 1, 82, 5, 66, 79, 56, 83, 0, 20, 9, 198, 37, 51, 205, 21, 68, 137, 20, 10, 199, 16, 84, 15, 76, 149, 21, 52, 20, 10, 199, 52, 20, 137, 8, 243, 137, 80, 20, 10, 199, 45, 98, 82, 72, 85, 137, 80, 20, 10, 199, 85, 32, 129, 56, 148, 205, 20, 20, 10, 199, 48, 21, 9, 56, 148, 205, 20, 20, 10, 199, 44, 243, 15, 72, 148, 205, 20, 20, 10, 199, 28, 83, 210, 28, 148, 205, 20, 20, 10, 199, 9, 81, 4, 32, 148, 205, 20, 20, 10, 199, 20, 180, 201, 77, 65, 78, 76, 20, 6, 195, 76, 176, 76, 76, 0, 9, 198, 77, 80, 140, 36, 209, 82, 20, 9, 198, 65, 35, 214, 60, 177, 82, 20, 9, 198, 65, 35, 212, 20, 113, 82, 20, 9, 198, 5, 52, 207, 12, 145, 82, 20, 9, 198, 4, 66, 149, 56, 113, 82, 20, 9, 198, 4, 194, 207, 32, 243, 0, 20, 16, 141, 195, 184, 11, 15, 14, 15, 13, 5, 20, 18, 9, 19, 11, 20, 12, 137, 195, 166, 7, 25, 16, 20, 9, 19, 11, 20, 7, 196, 20, 243, 9, 80, 20, 9, 198, 48, 144, 133, 72, 144, 78, 20, 9, 198, 60, 36, 201, 16, 144, 78, 21, 7, 196, 4, 227, 129, 48, 20, 8, 67, 60, 176, 89, 21, 0, 10, 0, 9, 198, 32, 148, 16, 60, 195, 199, 20, 9, 198, 25, 33, 78, 60, 195, 199, 20, 12, 201, 88, 19, 4, 32, 244, 142, 37, 53, 0, 20, 12, 201, 8, 82, 1, 88, 147, 210, 37, 53, 0, 20, 11, 136, 19, 12, 195, 184, 19, 5, 18, 9, 20, 17, 142, 19, 20, 195, 184, 11, 9, 15, 13, 5, 20, 18, 9, 19, 11, 20, 13, 138, 19, 16, 15, 14, 4, 195, 166, 9, 19, 11, 20, 17, 142, 6, 195, 184, 4, 5, 18, 1, 12, 9, 19, 20, 9, 19, 11, 20, 17, 142, 5, 14, 3, 25, 11, 12, 15, 16, 195, 166, 4, 9, 19, 11, 20, 0, 13, 202, 52, 21, 18, 36, 181, 76, 21, 34, 78, 28, 20, 13, 202, 36, 225, 18, 20, 117, 76, 21, 34, 78, 28, 20, 13, 202, 20, 180, 208, 48, 242, 84, 21, 34, 78, 28, 20, 13, 202, 8, 20, 146, 36, 176, 68, 21, 34, 78, 28, 20, 14, 139, 16, 195, 166, 4, 1, 7, 15, 7, 9, 19, 11, 20, 13, 202, 81, 32, 78, 77, 97, 83, 80, 148, 205, 20, 20, 13, 202, 76, 176, 78, 16, 147, 129, 88, 148, 205, 20, 20, 13, 202, 21, 99, 204, 85, 66, 79, 56, 148, 205, 20, 20, 13, 202, 21, 67, 143, 12, 83, 148, 72, 148, 205, 20, 20, 9, 198, 48, 20, 153, 56, 112, 76, 20, 13, 202, 44, 243, 138, 84, 226, 212, 36, 243, 129, 48, 20, 11, 70, 52, 243, 148, 72, 80, 76, 21, 0, 10, 0, 10, 199, 24, 83, 142, 60, 195, 199, 36, 20, 10, 199, 32, 82, 212, 60, 116, 129, 52, 20, 15, 140, 16, 18, 195, 166, 16, 1, 18, 5, 18, 9, 14, 7, 20, 14, 139, 16, 18, 195, 166, 10, 21, 4, 9, 11, 1, 20, 20, 10, 199, 20, 229, 18, 20, 50, 1, 80, 20, 0, 9, 198, 65, 35, 208, 4, 113, 82, 20, 9, 198, 44, 243, 138, 84, 113, 82, 20, 9, 198, 21, 52, 1, 48, 145, 82, 20, 9, 198, 8, 19, 19, 4, 209, 82, 20, 14, 139, 6, 18, 9, 20, 195, 166, 14, 11, 5, 18, 9, 20, 9, 198, 4, 35, 210, 36, 114, 78, 20, 11, 200, 77, 80, 147, 37, 53, 5, 57, 48, 20, 9, 198, 64, 83, 77, 36, 176, 78, 21, 0, 13, 138, 195, 166, 7, 25, 16, 20, 15, 12, 15, 7, 20, 9, 198, 29, 32, 70, 60, 195, 199, 20, 17, 142, 5, 21, 18, 15, 16, 195, 166, 9, 19, 5, 18, 9, 14, 7, 20, 16, 205, 16, 82, 207, 57, 53, 18, 84, 181, 9, 88, 148, 205, 20, 20, 10, 135, 19, 9, 7, 195, 184, 10, 14, 20, 7, 196, 16, 147, 129, 72, 20, 7, 196, 64, 20, 129, 8, 20, 0, 8, 197, 104, 148, 139, 60, 224, 20, 9, 198, 4, 192, 82, 52, 84, 133, 20, 9, 198, 4, 35, 210, 80, 84, 133, 20, 0, 9, 198, 80, 16, 149, 48, 84, 128, 20, 9, 198, 76, 21, 9, 56, 84, 128, 20, 9, 198, 72, 84, 213, 52, 84, 128, 20, 12, 201, 25, 33, 77, 65, 35, 214, 60, 177, 82, 20, 9, 198, 52, 243, 137, 80, 84, 128, 20, 9, 198, 52, 83, 79, 72, 84, 128, 20, 9, 198, 45, 83, 85, 48, 84, 128, 20, 9, 198, 36, 228, 197, 72, 84, 128, 20, 9, 198, 36, 226, 1, 48, 84, 128, 20, 9, 198, 36, 195, 21, 16, 84, 128, 20, 9, 198, 28, 83, 73, 56, 84, 128, 20, 9, 198, 24, 242, 213, 76, 84, 128, 20, 9, 198, 24, 16, 149, 48, 84, 128, 20, 9, 198, 20, 210, 84, 80, 84, 128, 20, 9, 198, 16, 243, 73, 56, 84, 128, 20, 9, 198, 16, 80, 137, 80, 84, 128, 20, 9, 198, 5, 52, 9, 72, 84, 128, 20, 9, 198, 4, 195, 21, 16, 84, 128, 20, 9, 198, 4, 67, 208, 80, 84, 128, 20, 17, 142, 19, 11, 18, 21, 5, 2, 18, 195, 166, 11, 11, 5, 18, 9, 20, 9, 198, 32, 243, 143, 72, 20, 128, 20, 9, 198, 88, 83, 133, 72, 16, 128, 20, 0, 10, 199, 36, 212, 12, 61, 50, 79, 56, 20, 10, 199, 44, 243, 150, 60, 161, 82, 20, 20, 10, 199, 44, 21, 84, 36, 243, 133, 72, 20, 10, 199, 32, 20, 144, 84, 225, 82, 20, 20, 10, 199, 20, 180, 193, 52, 147, 133, 72, 20, 10, 199, 16, 85, 1, 48, 161, 82, 20, 20, 10, 199, 12, 19, 79, 84, 99, 5, 72, 20, 10, 199, 25, 83, 132, 4, 209, 78, 80, 20, 10, 199, 16, 85, 5, 72, 113, 78, 80, 20, 10, 199, 77, 84, 16, 48, 80, 78, 80, 20, 10, 199, 44, 243, 150, 21, 36, 193, 8, 20, 0, 11, 200, 52, 85, 1, 48, 195, 198, 60, 224, 20, 7, 196, 77, 2, 79, 56, 20, 12, 201, 80, 84, 212, 4, 209, 78, 80, 84, 133, 20, 11, 200, 44, 243, 5, 77, 65, 82, 60, 192, 20, 14, 139, 4, 9, 195, 166, 20, 5, 20, 9, 11, 5, 18, 20, 7, 196, 72, 244, 201, 56, 20, 11, 200, 56, 80, 80, 60, 194, 84, 4, 224, 20, 7, 196, 88, 83, 1, 56, 21, 7, 196, 44, 20, 1, 8, 20, 7, 196, 16, 83, 142, 20, 76, 0, 12, 201, 81, 32, 78, 76, 210, 84, 80, 84, 128, 20, 9, 198, 64, 148, 129, 80, 84, 133, 20, 12, 201, 53, 149, 15, 48, 241, 201, 76, 84, 128, 20, 12, 201, 53, 83, 20, 37, 3, 9, 12, 84, 128, 20, 9, 198, 45, 38, 80, 80, 84, 133, 20, 12, 201, 36, 229, 5, 72, 210, 84, 80, 84, 128, 20, 12, 201, 32, 243, 79, 28, 83, 137, 76, 84, 128, 20, 12, 201, 20, 180, 208, 72, 244, 18, 36, 84, 128, 20, 12, 201, 16, 148, 203, 72, 147, 73, 56, 84, 128, 20, 9, 198, 9, 35, 206, 104, 84, 133, 20, 12, 201, 8, 20, 212, 5, 33, 9, 76, 84, 128, 20, 9, 198, 8, 18, 129, 16, 84, 133, 20, 12, 201, 77, 145, 137, 48, 149, 9, 44, 84, 128, 20, 12, 201, 21, 2, 76, 21, 5, 9, 44, 84, 128, 20, 8, 197, 28, 20, 132, 36, 224, 20, 8, 197, 4, 226, 76, 36, 224, 20, 9, 198, 44, 243, 80, 4, 115, 137, 20, 8, 197, 80, 20, 148, 4, 224, 21, 8, 197, 64, 192, 84, 4, 224, 21, 8, 197, 72, 17, 9, 4, 192, 20, 8, 197, 24, 147, 9, 4, 192, 20, 0, 9, 198, 52, 85, 1, 24, 244, 128, 20, 9, 198, 76, 16, 143, 80, 84, 128, 20, 9, 198, 73, 83, 83, 80, 84, 128, 20, 9, 198, 72, 148, 201, 44, 84, 128, 20, 9, 198, 65, 33, 77, 36, 84, 128, 20, 9, 198, 64, 21, 9, 56, 84, 128, 20, 9, 198, 52, 20, 143, 16, 84, 128, 20, 9, 198, 48, 19, 73, 56, 84, 128, 20, 13, 202, 44, 243, 80, 48, 147, 69, 57, 65, 82, 20, 20, 9, 198, 12, 128, 82, 52, 84, 128, 20, 9, 198, 12, 83, 148, 72, 84, 128, 20, 9, 198, 12, 17, 13, 36, 84, 128, 20, 9, 198, 5, 36, 137, 88, 84, 128, 20, 9, 198, 57, 82, 204, 20, 20, 128, 20, 9, 198, 37, 36, 137, 80, 16, 128, 20, 0, 10, 199, 44, 244, 146, 20, 181, 21, 72, 20, 10, 199, 48, 18, 212, 5, 66, 79, 56, 20, 10, 199, 44, 243, 132, 37, 66, 79, 56, 20, 10, 199, 36, 229, 21, 37, 66, 79, 56, 20, 10, 199, 16, 148, 133, 45, 66, 79, 56, 20, 10, 199, 8, 19, 132, 4, 113, 82, 20, 20, 10, 199, 44, 148, 149, 72, 114, 83, 44, 20, 10, 199, 52, 85, 1, 24, 244, 137, 44, 20, 10, 199, 24, 148, 141, 4, 209, 78, 80, 20, 10, 199, 16, 148, 211, 36, 65, 78, 80, 20, 12, 201, 20, 180, 207, 72, 34, 84, 4, 229, 0, 20, 0, 10, 135, 195, 166, 15, 12, 9, 19, 11, 20, 11, 200, 85, 48, 133, 44, 148, 212, 4, 224, 21, 11, 200, 45, 35, 205, 61, 51, 205, 4, 192, 20, 0, 12, 201, 76, 147, 80, 48, 145, 137, 12, 84, 128, 20, 12, 201, 72, 82, 207, 53, 1, 78, 76, 84, 128, 20, 12, 201, 72, 82, 207, 52, 208, 78, 16, 84, 128, 20, 12, 201, 4, 195, 5, 28, 244, 137, 76, 84, 128, 20, 9, 198, 76, 209, 76, 80, 84, 137, 20, 9, 198, 76, 194, 75, 44, 84, 137, 20, 9, 198, 76, 178, 76, 16, 84, 137, 20, 9, 198, 64, 148, 129, 80, 84, 137, 20, 12, 201, 17, 148, 204, 20, 181, 9, 44, 84, 128, 20, 8, 197, 53, 84, 203, 5, 64, 20, 12, 201, 8, 144, 140, 36, 245, 5, 44, 20, 128, 20, 10, 69, 77, 68, 133, 21, 64, 21, 0, 10, 0, 9, 198, 56, 85, 82, 61, 49, 64, 20, 13, 202, 25, 32, 71, 52, 83, 148, 5, 66, 79, 56, 20, 13, 202, 16, 148, 208, 72, 244, 15, 73, 66, 79, 56, 20, 9, 198, 44, 20, 203, 4, 65, 64, 20, 0, 10, 199, 77, 83, 77, 21, 34, 78, 28, 20, 9, 198, 36, 211, 65, 56, 83, 147, 20, 0, 11, 200, 44, 20, 129, 8, 147, 137, 21, 32, 20, 12, 137, 16, 10, 195, 166, 11, 11, 5, 18, 9, 20, 12, 201, 44, 192, 77, 64, 133, 71, 28, 84, 137, 20, 7, 196, 81, 34, 79, 48, 20, 18, 143, 195, 166, 11, 22, 9, 12, 9, 2, 18, 9, 19, 20, 9, 19, 11, 20, 14, 139, 16, 195, 166, 4, 9, 1, 20, 18, 9, 19, 11, 20, 14, 139, 15, 18, 20, 15, 16, 195, 166, 4, 9, 19, 11, 20, 14, 139, 12, 15, 7, 15, 16, 195, 166, 4, 9, 19, 11, 20, 13, 72, 77, 113, 65, 81, 50, 9, 73, 64, 21, 0, 10, 0, 9, 198, 21, 2, 76, 21, 4, 201, 20, 9, 198, 17, 148, 208, 21, 4, 201, 20, 12, 201, 45, 38, 83, 80, 19, 12, 61, 49, 64, 20, 8, 197, 88, 20, 137, 21, 32, 20, 9, 198, 76, 160, 83, 44, 84, 137, 20, 9, 198, 61, 32, 78, 28, 84, 137, 20, 12, 201, 24, 244, 130, 36, 225, 20, 48, 145, 192, 20, 12, 201, 76, 19, 77, 20, 228, 213, 72, 145, 64, 20, 8, 197, 77, 64, 75, 37, 64, 20, 14, 139, 8, 9, 12, 12, 5, 18, 195, 184, 4, 1, 14, 20, 8, 197, 64, 20, 211, 5, 64, 20, 8, 197, 44, 244, 147, 5, 32, 20, 0, 9, 198, 36, 211, 65, 56, 83, 148, 20, 0, 14, 139, 15, 18, 20, 15, 16, 195, 166, 4, 9, 19, 20, 20, 0, 9, 198, 72, 80, 197, 65, 67, 210, 20, 9, 198, 44, 243, 80, 48, 85, 0, 20, 9, 198, 44, 21, 129, 48, 85, 0, 20, 9, 198, 12, 243, 80, 48, 85, 0, 20, 9, 198, 64, 20, 137, 80, 85, 0, 20, 7, 196, 76, 19, 133, 72, 20, 7, 196, 16, 243, 133, 72, 20, 9, 198, 45, 38, 79, 48, 149, 0, 20, 9, 198, 32, 148, 212, 4, 210, 78, 20, 9, 198, 5, 4, 5, 49, 50, 78, 20, 7, 196, 33, 83, 65, 56, 21, 7, 196, 8, 19, 129, 56, 21, 0, 12, 201, 52, 85, 1, 52, 244, 134, 61, 49, 64, 20, 8, 197, 20, 225, 82, 28, 144, 20, 12, 201, 77, 66, 76, 37, 49, 82, 36, 225, 192, 20, 12, 201, 76, 145, 206, 4, 193, 82, 36, 225, 192, 20, 12, 201, 76, 50, 1, 81, 65, 82, 36, 225, 192, 20, 12, 201, 72, 82, 204, 4, 209, 82, 36, 225, 192, 20, 12, 201, 72, 81, 143, 72, 209, 82, 36, 225, 192, 20, 12, 201, 65, 35, 198, 36, 193, 82, 36, 225, 192, 20, 12, 201, 64, 241, 84, 37, 49, 82, 36, 225, 192, 20, 12, 201, 45, 32, 75, 20, 193, 82, 36, 225, 192, 20, 12, 201, 44, 19, 132, 37, 49, 82, 36, 225, 192, 20, 12, 201, 36, 225, 12, 60, 113, 82, 36, 225, 192, 20, 12, 201, 36, 67, 204, 37, 49, 82, 36, 225, 192, 20, 12, 201, 32, 84, 143, 37, 49, 82, 36, 225, 192, 20, 12, 201, 24, 16, 146, 36, 177, 82, 36, 225, 192, 20, 12, 201, 20, 112, 76, 37, 49, 82, 36, 225, 192, 20, 12, 201, 16, 148, 211, 20, 177, 82, 36, 225, 192, 20, 12, 201, 16, 85, 129, 49, 81, 82, 36, 225, 192, 20, 12, 201, 16, 84, 212, 73, 81, 82, 36, 225, 192, 20, 12, 201, 16, 82, 204, 4, 209, 82, 36, 225, 192, 20, 12, 201, 16, 81, 143, 72, 209, 82, 36, 225, 192, 20, 12, 201, 8, 149, 149, 4, 177, 82, 36, 225, 192, 20, 12, 201, 4, 227, 196, 37, 49, 82, 36, 225, 192, 20, 12, 201, 4, 113, 210, 5, 97, 82, 36, 225, 192, 20, 13, 138, 19, 195, 184, 18, 195, 184, 22, 5, 18, 9, 20, 9, 198, 28, 84, 129, 56, 149, 77, 20, 12, 201, 72, 83, 1, 80, 149, 137, 76, 209, 64, 20, 8, 197, 80, 148, 129, 16, 80, 20, 8, 197, 64, 20, 129, 16, 80, 20, 11, 67, 16, 149, 0, 72, 6, 37, 47, 0, 72, 0, 9, 198, 77, 147, 133, 72, 114, 64, 20, 0, 10, 199, 72, 80, 197, 77, 50, 79, 56, 20, 10, 199, 4, 227, 133, 45, 50, 79, 56, 20, 10, 199, 4, 67, 73, 77, 50, 79, 56, 20, 12, 201, 64, 21, 15, 28, 83, 137, 80, 85, 0, 20, 12, 201, 24, 83, 73, 56, 147, 137, 80, 85, 0, 20, 10, 199, 44, 243, 132, 20, 211, 133, 72, 20, 10, 199, 36, 228, 197, 52, 147, 133, 72, 20, 10, 199, 28, 83, 1, 80, 147, 133, 72, 20, 15, 140, 195, 184, 10, 5, 14, 20, 10, 5, 14, 5, 18, 9, 20, 10, 199, 77, 98, 78, 16, 193, 82, 36, 20, 10, 199, 77, 84, 141, 84, 193, 82, 36, 20, 10, 199, 76, 180, 137, 8, 193, 82, 36, 20, 10, 199, 65, 34, 86, 5, 65, 82, 36, 20, 10, 199, 28, 19, 1, 57, 65, 82, 36, 20, 10, 199, 25, 34, 77, 85, 33, 82, 36, 20, 10, 199, 21, 2, 71, 60, 225, 82, 36, 20, 10, 199, 12, 130, 75, 4, 225, 82, 36, 20, 10, 199, 8, 146, 143, 85, 65, 82, 36, 20, 10, 199, 5, 37, 9, 48, 193, 82, 36, 20, 12, 201, 4, 229, 9, 32, 148, 212, 4, 210, 78, 20, 10, 199, 52, 85, 1, 25, 148, 201, 44, 20, 10, 199, 52, 20, 203, 21, 32, 68, 20, 20, 0, 12, 201, 61, 48, 201, 48, 195, 211, 44, 244, 0, 20, 9, 198, 64, 18, 76, 48, 85, 0, 20, 11, 200, 80, 149, 21, 48, 84, 137, 56, 112, 20, 11, 200, 76, 176, 76, 64, 84, 137, 56, 112, 20, 11, 200, 72, 83, 143, 88, 84, 137, 56, 112, 20, 11, 200, 72, 83, 5, 28, 84, 137, 56, 112, 20, 15, 204, 72, 81, 201, 60, 224, 76, 37, 49, 82, 36, 225, 192, 20, 15, 204, 65, 54, 75, 60, 195, 199, 37, 49, 82, 36, 225, 192, 20, 11, 200, 64, 194, 83, 76, 84, 137, 56, 112, 20, 15, 204, 48, 82, 211, 36, 176, 76, 37, 49, 82, 36, 225, 192, 20, 11, 200, 48, 19, 73, 56, 84, 137, 56, 112, 20, 15, 204, 45, 38, 83, 80, 19, 12, 37, 49, 82, 36, 225, 192, 20, 15, 204, 45, 38, 80, 80, 241, 210, 4, 97, 82, 36, 225, 192, 20, 15, 204, 32, 244, 208, 37, 64, 76, 37, 49, 82, 36, 225, 192, 20, 11, 200, 25, 32, 78, 44, 84, 137, 56, 112, 20, 11, 200, 21, 96, 75, 84, 84, 137, 56, 112, 20, 15, 204, 16, 84, 212, 4, 34, 76, 37, 49, 82, 36, 225, 192, 20, 15, 204, 16, 84, 207, 72, 112, 78, 37, 49, 82, 36, 225, 192, 20, 15, 204, 16, 83, 79, 45, 32, 84, 37, 49, 82, 36, 225, 192, 20, 11, 200, 16, 83, 5, 28, 84, 137, 56, 112, 20, 11, 200, 5, 69, 1, 44, 84, 137, 56, 112, 20, 15, 204, 4, 178, 204, 36, 208, 84, 37, 49, 82, 36, 225, 192, 20, 11, 200, 84, 226, 70, 61, 35, 69, 72, 80, 20, 11, 200, 44, 192, 85, 77, 83, 5, 72, 80, 20, 11, 200, 64, 21, 18, 60, 225, 83, 76, 80, 20, 11, 200, 56, 83, 204, 37, 66, 75, 84, 208, 20, 11, 200, 56, 20, 139, 61, 66, 75, 84, 208, 20, 9, 198, 64, 243, 70, 72, 149, 0, 20, 11, 200, 44, 243, 80, 21, 65, 78, 12, 80, 20, 7, 196, 88, 83, 1, 72, 20, 7, 196, 32, 83, 132, 20, 72, 0, 11, 136, 12, 21, 11, 19, 21, 195, 184, 19, 20, 12, 201, 76, 149, 21, 5, 66, 79, 56, 83, 0, 20, 12, 201, 72, 81, 1, 45, 66, 79, 56, 83, 0, 20, 9, 198, 44, 193, 78, 60, 66, 69, 20, 9, 198, 77, 147, 80, 61, 50, 69, 20, 9, 198, 21, 81, 143, 52, 19, 137, 20, 12, 69, 52, 17, 1, 52, 80, 21, 102, 114, 0, 10, 0, 17, 142, 5, 14, 3, 25, 11, 12, 15, 16, 195, 166, 4, 9, 19, 20, 20, 9, 198, 60, 97, 137, 12, 145, 76, 20, 9, 198, 77, 84, 146, 20, 19, 0, 20, 0, 20, 67, 32, 19, 128, 107, 110, 50, 15, 89, 47, 6, 36, 0, 81, 115, 116, 101, 103, 32, 10, 199, 72, 80, 197, 65, 66, 79, 56, 20, 10, 199, 45, 33, 77, 5, 66, 79, 56, 20, 10, 199, 16, 81, 21, 45, 66, 79, 56, 20, 12, 201, 36, 224, 75, 80, 149, 137, 80, 85, 0, 20, 14, 203, 77, 65, 78, 60, 116, 129, 24, 84, 137, 56, 112, 20, 14, 203, 72, 85, 137, 80, 19, 9, 76, 84, 137, 56, 112, 20, 14, 203, 64, 20, 212, 21, 84, 137, 76, 84, 137, 56, 112, 20, 14, 203, 64, 19, 1, 80, 19, 9, 76, 84, 137, 56, 112, 20, 14, 203, 52, 243, 143, 64, 243, 9, 76, 84, 137, 56, 112, 20, 14, 203, 44, 21, 1, 48, 241, 201, 76, 84, 137, 56, 112, 20, 18, 207, 36, 228, 212, 73, 83, 69, 57, 64, 76, 37, 49, 82, 36, 225, 192, 20, 14, 203, 36, 225, 15, 45, 68, 137, 56, 84, 137, 56, 112, 20, 14, 203, 32, 82, 212, 60, 116, 129, 24, 84, 137, 56, 112, 20, 14, 203, 24, 81, 5, 72, 19, 9, 76, 84, 137, 56, 112, 20, 14, 203, 20, 180, 212, 20, 212, 15, 72, 84, 137, 56, 112, 20, 14, 203, 16, 145, 201, 80, 19, 9, 76, 84, 137, 56, 112, 20, 14, 203, 12, 128, 80, 80, 19, 9, 76, 84, 137, 56, 112, 20, 14, 203, 4, 100, 137, 44, 19, 137, 76, 84, 137, 56, 112, 20, 10, 199, 44, 20, 143, 77, 49, 82, 36, 20, 10, 199, 36, 225, 137, 72, 209, 82, 36, 20, 10, 199, 80, 19, 65, 72, 147, 132, 20, 20, 10, 199, 65, 34, 79, 72, 147, 132, 20, 20, 11, 67, 16, 147, 128, 72, 6, 37, 50, 0, 76, 6, 195, 32, 19, 128, 72, 0, 11, 200, 24, 192, 78, 44, 84, 137, 56, 112, 20, 11, 200, 5, 81, 9, 80, 84, 137, 56, 112, 20, 11, 200, 44, 243, 80, 5, 36, 197, 72, 144, 20, 11, 68, 24, 147, 129, 48, 20, 36, 89, 36, 0, 7, 196, 32, 16, 137, 80, 20, 7, 196, 48, 16, 137, 48, 20, 7, 196, 60, 35, 1, 80, 20, 7, 196, 80, 243, 129, 48, 20, 7, 196, 44, 19, 129, 48, 20, 7, 196, 24, 147, 129, 48, 20, 7, 196, 8, 19, 129, 48, 20, 11, 200, 44, 243, 16, 61, 37, 1, 28, 80, 20, 0, 9, 198, 76, 182, 76, 48, 84, 137, 20, 9, 198, 44, 21, 129, 48, 84, 137, 20, 6, 195, 73, 82, 78, 20, 9, 198, 48, 19, 65, 37, 51, 69, 20, 9, 198, 5, 67, 205, 37, 51, 69, 20, 25, 4, 95, 55, 88, 15, 107, 110, 55, 83, 57, 6, 110, 34, 89, 36, 50, 89, 47, 116, 84, 13, 50, 13, 0, 0, 11, 67, 20, 115, 133, 35, 12, 37, 50, 13, 0, 11, 136, 20, 18, 1, 11, 20, 195, 184, 18, 20, 13, 202, 81, 32, 78, 77, 2, 82, 5, 66, 79, 56, 20, 13, 202, 44, 243, 148, 4, 210, 78, 5, 66, 79, 56, 20, 13, 202, 44, 243, 12, 4, 35, 210, 5, 66, 79, 56, 20, 13, 202, 32, 19, 12, 84, 50, 78, 5, 66, 79, 56, 20, 13, 202, 20, 180, 208, 5, 68, 137, 5, 66, 79, 56, 20, 9, 198, 25, 85, 21, 73, 83, 64, 20, 9, 198, 20, 198, 83, 37, 83, 64, 20, 9, 198, 44, 20, 129, 8, 147, 128, 20, 9, 198, 8, 18, 18, 4, 147, 128, 20, 9, 198, 77, 3, 206, 80, 19, 128, 21, 11, 67, 16, 147, 133, 72, 6, 37, 50, 36, 0, 0, 10, 199, 44, 20, 132, 36, 19, 7, 36, 20, 10, 199, 5, 53, 18, 60, 195, 199, 36, 20, 9, 198, 80, 20, 133, 72, 147, 135, 20, 10, 199, 80, 19, 10, 21, 34, 78, 28, 20, 10, 199, 76, 145, 206, 21, 34, 78, 28, 20, 10, 199, 65, 83, 19, 21, 34, 78, 28, 20, 9, 198, 64, 20, 133, 72, 147, 135, 20, 9, 198, 64, 19, 133, 72, 147, 135, 20, 10, 199, 37, 34, 83, 21, 34, 78, 28, 20, 10, 199, 33, 145, 18, 21, 34, 78, 28, 20, 10, 199, 25, 84, 142, 21, 34, 78, 28, 20, 9, 198, 24, 147, 133, 72, 147, 135, 20, 10, 199, 9, 81, 211, 21, 34, 78, 28, 20, 10, 199, 44, 83, 73, 44, 19, 9, 20, 20, 10, 199, 64, 85, 18, 60, 193, 85, 52, 20, 10, 199, 77, 67, 201, 12, 148, 205, 20, 20, 10, 199, 64, 16, 201, 24, 148, 205, 20, 20, 10, 199, 52, 244, 129, 48, 148, 205, 20, 20, 10, 199, 24, 19, 129, 80, 148, 205, 20, 20, 10, 199, 48, 242, 207, 52, 240, 137, 48, 20, 10, 199, 24, 192, 71, 20, 195, 1, 80, 20, 10, 199, 52, 81, 9, 12, 147, 129, 48, 20, 10, 199, 20, 208, 146, 100, 243, 129, 48, 20, 0, 9, 198, 16, 82, 204, 4, 209, 82, 20, 9, 198, 8, 149, 149, 4, 177, 82, 20, 12, 201, 16, 85, 5, 72, 210, 78, 37, 51, 69, 20, 7, 196, 24, 243, 133, 52, 20, 9, 198, 40, 19, 65, 36, 48, 78, 20, 7, 196, 77, 82, 193, 80, 20, 7, 196, 61, 2, 65, 80, 20, 7, 196, 17, 82, 193, 80, 20, 11, 70, 16, 80, 149, 28, 113, 82, 21, 0, 10, 0, 14, 139, 9, 14, 19, 20, 18, 21, 11, 20, 195, 184, 18, 20, 9, 198, 52, 147, 129, 72, 147, 133, 20, 9, 198, 28, 83, 210, 28, 147, 133, 20, 9, 198, 4, 35, 206, 56, 147, 133, 20, 12, 201, 77, 84, 16, 61, 50, 84, 36, 243, 128, 20, 12, 201, 52, 19, 149, 17, 82, 212, 36, 243, 128, 20, 12, 201, 45, 98, 78, 80, 147, 12, 36, 243, 128, 20, 12, 201, 44, 243, 138, 84, 226, 212, 36, 243, 128, 20, 12, 201, 36, 228, 212, 37, 69, 84, 36, 243, 128, 20, 12, 201, 36, 226, 214, 37, 50, 84, 36, 243, 128, 20, 12, 201, 20, 180, 212, 36, 226, 212, 36, 243, 128, 20, 12, 201, 20, 180, 208, 61, 50, 84, 36, 243, 128, 20, 12, 201, 16, 148, 212, 36, 226, 212, 36, 243, 128, 20, 12, 201, 16, 148, 208, 61, 50, 84, 36, 243, 128, 20, 12, 201, 16, 84, 212, 73, 82, 212, 36, 243, 128, 20, 0, 15, 140, 11, 15, 14, 19, 20, 18, 21, 11, 20, 195, 184, 18, 20, 9, 198, 44, 243, 15, 24, 243, 128, 20, 13, 202, 89, 83, 11, 4, 226, 83, 21, 34, 78, 28, 20, 13, 202, 81, 32, 78, 77, 2, 82, 21, 34, 78, 28, 20, 13, 202, 81, 32, 78, 76, 97, 82, 21, 34, 78, 28, 20, 13, 202, 80, 83, 210, 21, 66, 83, 21, 34, 78, 28, 20, 13, 202, 80, 83, 5, 29, 32, 70, 21, 34, 78, 28, 20, 13, 202, 77, 84, 5, 73, 98, 83, 21, 34, 78, 28, 20, 12, 201, 77, 3, 206, 76, 244, 133, 72, 147, 135, 20, 13, 202, 76, 177, 77, 5, 66, 83, 21, 34, 78, 28, 20, 13, 202, 76, 19, 139, 80, 147, 206, 21, 34, 78, 28, 20, 12, 201, 72, 21, 9, 32, 16, 133, 72, 147, 135, 20, 13, 202, 64, 20, 129, 29, 32, 70, 21, 34, 78, 28, 20, 13, 202, 60, 34, 133, 45, 66, 86, 21, 34, 78, 28, 20, 13, 202, 56, 20, 139, 61, 66, 83, 21, 34, 78, 28, 20, 13, 202, 52, 241, 5, 72, 226, 83, 21, 34, 78, 28, 20, 13, 202, 52, 84, 131, 21, 34, 83, 21, 34, 78, 28, 20, 12, 201, 52, 81, 9, 12, 147, 133, 72, 147, 135, 20, 13, 202, 52, 17, 206, 21, 66, 83, 21, 34, 78, 28, 20, 13, 202, 44, 243, 148, 4, 210, 78, 21, 34, 78, 28, 20, 13, 202, 44, 194, 77, 5, 66, 83, 21, 34, 78, 28, 20, 13, 202, 44, 147, 15, 52, 85, 18, 21, 34, 78, 28, 20, 12, 201, 44, 21, 84, 36, 243, 133, 72, 147, 135, 20, 13, 202, 44, 20, 130, 60, 226, 83, 21, 34, 78, 28, 20, 12, 201, 36, 225, 18, 84, 195, 5, 72, 147, 135, 20, 12, 201, 36, 225, 11, 48, 20, 133, 72, 147, 135, 20, 13, 202, 33, 148, 14, 61, 66, 83, 21, 34, 78, 28, 20, 13, 202, 32, 148, 212, 61, 34, 83, 21, 34, 78, 28, 20, 13, 202, 28, 195, 194, 4, 194, 83, 21, 34, 78, 28, 20, 13, 202, 28, 129, 84, 80, 242, 83, 21, 34, 78, 28, 20, 13, 202, 28, 20, 142, 37, 51, 206, 21, 34, 78, 28, 20, 13, 202, 24, 245, 15, 29, 32, 70, 21, 34, 78, 28, 20, 13, 202, 24, 147, 13, 5, 66, 83, 21, 34, 78, 28, 20, 13, 202, 17, 32, 77, 5, 66, 83, 21, 34, 78, 28, 20, 13, 202, 16, 241, 205, 5, 66, 83, 21, 34, 78, 28, 20, 13, 202, 16, 83, 196, 61, 34, 83, 21, 34, 78, 28, 20, 12, 201, 12, 149, 137, 48, 148, 197, 72, 147, 135, 20, 12, 201, 12, 19, 79, 84, 99, 5, 72, 147, 135, 20, 13, 202, 5, 35, 205, 5, 66, 83, 21, 34, 78, 28, 20, 13, 202, 4, 227, 206, 100, 210, 83, 21, 34, 78, 28, 20, 13, 202, 4, 224, 76, 60, 114, 83, 21, 34, 78, 28, 20, 13, 202, 4, 176, 68, 20, 210, 83, 21, 34, 78, 28, 20, 13, 202, 36, 228, 212, 37, 69, 84, 36, 243, 133, 48, 20, 9, 198, 64, 147, 135, 88, 147, 128, 20, 9, 198, 52, 81, 9, 12, 147, 128, 20, 13, 202, 84, 226, 86, 21, 36, 193, 48, 148, 205, 20, 20, 13, 202, 44, 243, 12, 20, 181, 9, 88, 148, 205, 20, 20, 9, 198, 52, 242, 9, 44, 19, 128, 20, 9, 198, 52, 81, 9, 12, 147, 128, 20, 9, 198, 4, 225, 207, 48, 19, 128, 20, 9, 198, 81, 83, 9, 64, 19, 128, 21, 9, 198, 64, 83, 9, 44, 19, 128, 21, 9, 198, 52, 83, 66, 72, 19, 128, 21, 9, 198, 21, 81, 143, 52, 19, 128, 21, 7, 66, 16, 160, 21, 0, 10, 0, 31, 67, 64, 20, 128, 48, 35, 12, 36, 81, 89, 13, 6, 55, 35, 12, 68, 89, 0, 81, 101, 120, 99, 101, 108, 108, 101, 110, 99, 101, 32, 10, 199, 77, 65, 84, 61, 50, 207, 64, 20, 10, 199, 80, 85, 18, 4, 195, 199, 36, 20, 10, 199, 64, 85, 18, 60, 195, 199, 36, 20, 10, 199, 28, 83, 133, 4, 195, 199, 36, 20, 9, 198, 76, 19, 133, 72, 147, 135, 20, 9, 198, 52, 147, 133, 72, 147, 135, 20, 9, 198, 28, 148, 133, 72, 147, 135, 20, 12, 201, 65, 54, 75, 60, 195, 199, 37, 49, 82, 20, 12, 201, 21, 70, 77, 60, 195, 199, 37, 49, 82, 20, 10, 199, 45, 84, 129, 80, 244, 137, 20, 20, 10, 199, 28, 195, 211, 76, 20, 137, 20, 20, 10, 199, 48, 144, 197, 57, 66, 65, 80, 20, 10, 67, 32, 20, 128, 107, 112, 34, 0, 76, 0, 40, 68, 16, 147, 133, 72, 72, 37, 50, 6, 36, 47, 34, 112, 68, 89, 48, 114, 47, 6, 35, 71, 55, 13, 0, 81, 116, 114, 97, 110, 115, 112, 111, 114, 116, 97, 98, 108, 101, 32, 7, 196, 64, 19, 133, 72, 20, 9, 198, 61, 34, 71, 4, 209, 82, 20, 7, 196, 16, 147, 133, 72, 20, 9, 198, 5, 67, 205, 37, 49, 82, 20, 12, 201, 65, 54, 75, 60, 195, 199, 37, 51, 69, 20, 7, 196, 16, 83, 129, 72, 20, 16, 73, 52, 17, 5, 52, 242, 83, 20, 195, 5, 21, 102, 114, 0, 10, 6, 196, 20, 195, 5, 72, 0, 8, 197, 64, 21, 18, 60, 224, 20, 17, 69, 56, 21, 18, 60, 224, 50, 6, 110, 12, 47, 51, 114, 50, 0, 20, 16, 205, 81, 32, 78, 76, 148, 212, 61, 34, 83, 21, 34, 78, 28, 20, 16, 205, 25, 83, 139, 80, 147, 206, 4, 194, 83, 21, 34, 78, 28, 20, 9, 198, 76, 176, 78, 16, 84, 133, 20, 9, 198, 64, 242, 78, 80, 84, 133, 20, 9, 198, 52, 245, 9, 88, 84, 133, 20, 9, 198, 29, 37, 80, 64, 84, 133, 20, 9, 198, 4, 181, 9, 88, 84, 133, 20, 8, 197, 28, 243, 132, 60, 192, 20, 8, 197, 8, 147, 195, 36, 64, 20, 8, 197, 40, 20, 205, 36, 224, 20, 9, 198, 77, 147, 139, 72, 243, 137, 20, 12, 201, 72, 85, 19, 52, 81, 9, 12, 147, 128, 20, 0, 9, 198, 16, 149, 137, 76, 244, 128, 20, 9, 198, 45, 96, 78, 80, 244, 128, 20, 12, 201, 76, 82, 212, 36, 243, 133, 72, 147, 135, 20, 12, 201, 44, 243, 210, 16, 147, 133, 72, 147, 135, 20, 12, 201, 44, 243, 132, 20, 211, 133, 72, 147, 135, 20, 12, 201, 36, 228, 197, 52, 147, 133, 72, 147, 135, 20, 12, 201, 28, 83, 1, 80, 147, 133, 72, 147, 135, 20, 12, 201, 5, 85, 15, 72, 148, 197, 72, 147, 135, 20, 9, 198, 88, 145, 9, 52, 84, 128, 20, 9, 198, 72, 18, 76, 48, 84, 128, 20, 9, 198, 56, 243, 73, 56, 84, 128, 20, 9, 198, 52, 84, 137, 80, 84, 128, 20, 9, 198, 44, 20, 137, 44, 84, 128, 20, 9, 198, 21, 128, 201, 80, 84, 128, 20, 9, 198, 16, 149, 137, 16, 84, 128, 20, 9, 198, 4, 208, 149, 48, 84, 128, 20, 9, 198, 28, 198, 67, 21, 35, 204, 20, 0, 10, 199, 77, 147, 80, 61, 50, 79, 56, 20, 10, 199, 64, 20, 131, 20, 195, 5, 72, 20, 12, 201, 52, 85, 1, 52, 244, 134, 61, 49, 82, 20, 10, 199, 76, 176, 66, 4, 117, 9, 28, 20, 10, 199, 84, 226, 84, 5, 34, 83, 44, 20, 10, 199, 77, 147, 70, 60, 226, 83, 44, 20, 10, 199, 76, 86, 9, 77, 66, 83, 44, 20, 10, 199, 76, 17, 9, 77, 66, 83, 44, 20, 10, 199, 52, 20, 148, 101, 34, 83, 44, 20, 10, 199, 32, 243, 9, 77, 66, 83, 44, 20, 10, 199, 32, 149, 20, 37, 66, 83, 44, 20, 10, 199, 28, 19, 1, 45, 66, 83, 44, 20, 10, 199, 16, 243, 69, 77, 66, 83, 44, 20, 10, 199, 16, 149, 82, 21, 66, 83, 44, 20, 10, 199, 16, 144, 66, 21, 66, 83, 44, 20, 10, 199, 5, 85, 9, 77, 66, 83, 44, 20, 10, 199, 5, 65, 73, 77, 66, 83, 44, 20, 10, 199, 76, 176, 66, 4, 117, 9, 28, 20, 10, 199, 24, 16, 146, 36, 176, 78, 80, 20, 6, 195, 40, 84, 128, 72, 0, 11, 200, 77, 147, 139, 72, 245, 18, 60, 224, 20, 7, 196, 65, 34, 79, 56, 20, 7, 196, 28, 83, 5, 72, 20, 7, 196, 28, 19, 1, 72, 20, 7, 196, 64, 243, 1, 72, 20, 13, 68, 24, 244, 132, 36, 83, 114, 72, 6, 37, 0, 8, 0, 9, 198, 64, 195, 205, 8, 84, 133, 20, 9, 198, 64, 20, 129, 16, 84, 133, 20, 9, 198, 64, 19, 133, 48, 84, 133, 20, 9, 198, 52, 20, 131, 32, 84, 133, 20, 12, 201, 36, 225, 11, 4, 194, 213, 48, 84, 128, 20, 9, 198, 9, 35, 195, 32, 84, 133, 20, 9, 198, 5, 96, 78, 12, 84, 133, 20, 8, 197, 9, 32, 77, 36, 224, 20, 8, 197, 40, 245, 137, 4, 192, 20, 8, 197, 28, 83, 137, 4, 192, 20, 0, 9, 66, 33, 32, 107, 110, 34, 0, 25, 9, 198, 76, 176, 77, 24, 84, 128, 20, 9, 198, 76, 176, 76, 64, 84, 128, 20, 9, 198, 72, 82, 210, 20, 84, 128, 20, 9, 198, 72, 81, 149, 76, 84, 128, 20, 15, 140, 16, 18, 195, 166, 6, 1, 2, 18, 9, 11, 5, 18, 20, 9, 198, 64, 244, 148, 36, 84, 128, 20, 9, 198, 64, 194, 83, 76, 84, 128, 20, 9, 198, 44, 17, 13, 36, 84, 128, 20, 9, 198, 40, 243, 135, 48, 84, 128, 20, 9, 198, 36, 226, 84, 36, 84, 128, 20, 9, 198, 25, 32, 78, 44, 84, 128, 20, 9, 198, 21, 96, 75, 84, 84, 128, 20, 9, 198, 20, 209, 78, 16, 84, 128, 20, 9, 198, 20, 181, 137, 64, 84, 128, 20, 9, 198, 16, 83, 143, 80, 84, 128, 20, 9, 198, 5, 69, 1, 44, 84, 128, 20, 13, 202, 80, 84, 141, 61, 3, 1, 77, 66, 83, 44, 20, 13, 202, 76, 83, 147, 84, 19, 9, 77, 66, 83, 44, 20, 13, 202, 72, 85, 129, 56, 50, 9, 77, 66, 83, 44, 20, 13, 202, 56, 20, 131, 37, 52, 201, 77, 66, 83, 44, 20, 13, 202, 52, 243, 143, 64, 243, 9, 77, 66, 83, 44, 20, 13, 202, 48, 81, 201, 80, 147, 73, 77, 66, 83, 44, 20, 13, 202, 44, 192, 83, 76, 144, 201, 77, 66, 83, 44, 20, 13, 202, 24, 81, 5, 72, 19, 9, 77, 66, 83, 44, 20, 13, 202, 20, 180, 212, 72, 83, 73, 77, 66, 83, 44, 20, 9, 198, 80, 83, 132, 20, 228, 192, 20, 9, 198, 9, 33, 86, 36, 20, 128, 20, 9, 198, 5, 34, 201, 88, 20, 128, 20, 9, 198, 24, 21, 143, 72, 16, 128, 20, 0, 10, 67, 32, 21, 128, 107, 112, 40, 0, 14, 10, 199, 80, 18, 211, 5, 66, 79, 56, 20, 10, 199, 44, 148, 135, 37, 50, 83, 44, 20, 10, 199, 81, 33, 77, 84, 192, 78, 80, 20, 0, 9, 198, 8, 85, 1, 81, 35, 206, 20, 6, 195, 32, 19, 147, 76, 0, 12, 201, 81, 32, 78, 76, 49, 78, 16, 84, 128, 20, 12, 201, 76, 19, 69, 45, 50, 83, 80, 84, 128, 20, 12, 201, 65, 35, 208, 4, 112, 78, 16, 84, 128, 20, 12, 201, 64, 244, 21, 48, 20, 137, 76, 84, 128, 20, 12, 201, 64, 20, 212, 21, 84, 137, 76, 84, 128, 20, 12, 201, 64, 20, 140, 4, 209, 78, 80, 84, 128, 20, 8, 197, 49, 82, 210, 21, 32, 20, 12, 201, 44, 21, 1, 48, 241, 201, 76, 84, 128, 20, 12, 201, 36, 229, 5, 73, 5, 78, 28, 84, 128, 20, 12, 201, 36, 225, 15, 45, 68, 137, 56, 84, 128, 20, 12, 201, 36, 65, 79, 48, 241, 201, 76, 84, 128, 20, 12, 201, 20, 180, 212, 20, 228, 201, 88, 84, 128, 20, 12, 201, 20, 180, 212, 20, 212, 15, 72, 84, 128, 20, 12, 201, 4, 100, 137, 44, 19, 137, 76, 84, 128, 20, 12, 201, 44, 243, 77, 20, 228, 213, 72, 16, 128, 20, 0, 9, 198, 44, 195, 210, 61, 49, 64, 20, 9, 198, 24, 144, 146, 61, 49, 64, 20, 9, 198, 12, 243, 80, 61, 49, 64, 20, 13, 202, 24, 84, 148, 36, 194, 83, 5, 66, 79, 56, 20, 13, 202, 76, 19, 141, 5, 34, 78, 21, 50, 83, 44, 20, 13, 202, 45, 38, 80, 80, 241, 210, 4, 98, 83, 44, 20, 13, 138, 16, 18, 195, 166, 19, 9, 4, 5, 14, 20, 20, 9, 198, 36, 225, 15, 48, 83, 148, 20, 9, 198, 25, 32, 71, 52, 83, 148, 20, 9, 198, 20, 195, 203, 88, 83, 148, 20, 9, 198, 53, 84, 201, 44, 19, 148, 20, 9, 198, 48, 16, 143, 72, 19, 148, 20, 9, 198, 36, 115, 143, 72, 19, 148, 20, 9, 198, 17, 81, 76, 48, 19, 148, 20, 0, 14, 139, 16, 18, 195, 166, 20, 5, 14, 4, 5, 14, 20, 20, 10, 199, 72, 84, 15, 73, 64, 71, 20, 20, 10, 199, 21, 33, 77, 37, 64, 71, 20, 20, 0, 30, 68, 24, 244, 131, 20, 83, 114, 34, 89, 15, 4, 65, 35, 6, 89, 57, 118, 12, 34, 0, 81, 109, 97, 106, 101, 117, 114, 101, 32, 11, 200, 97, 147, 15, 29, 32, 70, 21, 32, 20, 11, 200, 96, 84, 143, 29, 32, 70, 21, 32, 20, 11, 200, 81, 148, 15, 29, 32, 70, 21, 32, 20, 11, 200, 64, 85, 9, 80, 147, 206, 21, 32, 20, 11, 200, 48, 149, 15, 29, 32, 70, 21, 32, 20, 7, 196, 81, 148, 143, 48, 20, 0, 16, 205, 84, 66, 210, 101, 53, 1, 48, 194, 83, 5, 66, 79, 56, 20, 9, 198, 45, 32, 68, 76, 84, 137, 20, 12, 201, 81, 32, 78, 76, 49, 78, 16, 83, 148, 20, 0, 9, 198, 24, 147, 1, 52, 83, 148, 20, 13, 202, 76, 50, 1, 48, 37, 82, 29, 64, 71, 20, 20, 0, 12, 201, 36, 212, 18, 61, 98, 83, 5, 67, 210, 20, 9, 198, 72, 83, 65, 56, 83, 147, 20, 9, 198, 36, 225, 15, 48, 83, 147, 20, 9, 198, 20, 195, 203, 88, 83, 147, 20, 9, 198, 49, 83, 73, 56, 19, 147, 20, 0, 7, 196, 77, 85, 21, 72, 20, 11, 200, 5, 85, 15, 44, 192, 86, 21, 32, 20, 9, 198, 77, 144, 129, 72, 149, 0, 20, 9, 198, 52, 81, 193, 8, 149, 0, 20, 9, 198, 44, 147, 15, 8, 149, 0, 20, 7, 196, 53, 84, 201, 44, 20, 7, 196, 4, 116, 129, 24, 20, 0, 12, 201, 81, 80, 133, 72, 181, 76, 61, 49, 64, 20, 12, 201, 64, 20, 129, 16, 83, 148, 61, 49, 64, 20, 12, 201, 5, 98, 84, 4, 210, 78, 61, 49, 64, 20, 0, 11, 200, 77, 68, 143, 8, 244, 203, 61, 0, 20, 9, 198, 8, 243, 77, 21, 50, 64, 20, 12, 201, 81, 32, 78, 76, 49, 78, 16, 83, 147, 20, 9, 198, 44, 20, 132, 36, 19, 0, 20, 0, 9, 134, 6, 1, 13, 195, 184, 19, 20, 11, 136, 4, 18, 195, 166, 19, 9, 14, 5, 20, 10, 199, 44, 243, 12, 37, 50, 79, 56, 20, 12, 201, 36, 211, 79, 72, 19, 9, 80, 85, 0, 20, 10, 199, 72, 81, 197, 56, 84, 133, 72, 20, 10, 199, 72, 81, 5, 24, 147, 133, 72, 20, 10, 199, 72, 80, 83, 77, 83, 69, 72, 20, 10, 199, 44, 243, 210, 16, 147, 133, 72, 20, 10, 199, 104, 20, 137, 77, 66, 83, 44, 20, 10, 199, 88, 84, 137, 77, 66, 83, 44, 20, 10, 199, 77, 147, 80, 5, 66, 83, 44, 20, 10, 199, 76, 245, 138, 21, 66, 83, 44, 20, 10, 199, 65, 35, 198, 21, 66, 83, 44, 20, 10, 199, 64, 20, 211, 37, 98, 83, 44, 20, 10, 199, 61, 51, 65, 56, 226, 83, 44, 20, 10, 199, 56, 85, 82, 61, 66, 83, 44, 20, 10, 199, 56, 20, 139, 61, 66, 83, 44, 20, 10, 199, 52, 19, 4, 37, 98, 83, 44, 20, 10, 199, 52, 17, 206, 21, 66, 83, 44, 20, 10, 199, 33, 148, 14, 61, 66, 83, 44, 20, 10, 199, 32, 84, 141, 21, 66, 83, 44, 20, 10, 199, 20, 115, 201, 77, 66, 83, 44, 20, 10, 199, 17, 147, 129, 77, 66, 83, 44, 20, 10, 199, 8, 19, 5, 5, 34, 83, 44, 20, 0, 7, 196, 65, 34, 79, 72, 20, 11, 200, 16, 21, 1, 52, 21, 9, 76, 176, 20, 9, 198, 52, 20, 207, 56, 149, 0, 20, 7, 196, 5, 67, 206, 36, 20, 7, 196, 4, 229, 9, 44, 20, 9, 198, 60, 35, 9, 28, 21, 0, 20, 7, 196, 28, 19, 1, 56, 21, 0, 8, 197, 24, 19, 148, 60, 208, 20, 8, 197, 72, 81, 5, 72, 144, 20, 8, 197, 44, 243, 147, 84, 208, 20, 9, 198, 64, 243, 25, 24, 243, 137, 20, 19, 70, 64, 84, 5, 72, 243, 137, 48, 36, 48, 13, 34, 6, 39, 50, 37, 0, 20, 8, 197, 16, 84, 15, 56, 144, 20, 0, 13, 202, 56, 85, 82, 61, 4, 217, 44, 243, 15, 28, 20, 9, 198, 8, 20, 213, 56, 148, 212, 20, 9, 198, 45, 84, 129, 80, 83, 0, 20, 13, 202, 81, 32, 78, 76, 194, 84, 80, 84, 133, 72, 20, 13, 202, 77, 3, 206, 80, 19, 137, 77, 66, 83, 44, 20, 13, 202, 72, 84, 208, 37, 32, 84, 61, 34, 83, 44, 20, 13, 202, 44, 243, 66, 36, 224, 84, 61, 34, 83, 44, 20, 13, 202, 32, 83, 9, 60, 49, 78, 81, 34, 83, 44, 20, 0, 29, 75, 44, 243, 134, 37, 35, 65, 56, 65, 82, 56, 80, 49, 114, 50, 83, 36, 34, 65, 6, 110, 50, 72, 108, 20, 50, 13, 0, 13, 138, 7, 12, 1, 13, 15, 21, 18, 195, 184, 19, 20, 12, 137, 19, 15, 21, 20, 5, 14, 195, 184, 18, 20, 12, 137, 13, 5, 4, 1, 12, 10, 195, 184, 18, 20, 10, 199, 49, 82, 211, 5, 66, 79, 56, 20, 10, 199, 36, 210, 84, 5, 66, 79, 56, 20, 10, 199, 24, 195, 212, 5, 66, 79, 56, 20, 10, 199, 16, 84, 197, 73, 66, 79, 56, 20, 10, 199, 4, 114, 84, 5, 66, 79, 56, 20, 12, 201, 77, 1, 67, 36, 19, 9, 80, 85, 0, 20, 12, 201, 64, 244, 21, 48, 20, 137, 80, 85, 0, 20, 12, 201, 56, 85, 84, 72, 19, 9, 80, 85, 0, 20, 12, 201, 53, 85, 1, 8, 147, 9, 80, 85, 0, 20, 10, 199, 81, 32, 75, 5, 52, 197, 72, 20, 10, 199, 44, 243, 134, 61, 35, 69, 72, 20, 10, 199, 44, 243, 134, 37, 35, 69, 72, 20, 10, 199, 8, 81, 18, 4, 113, 82, 36, 20, 10, 199, 52, 148, 212, 72, 242, 83, 44, 20, 10, 199, 44, 21, 75, 5, 50, 83, 44, 20, 10, 199, 4, 34, 200, 5, 50, 83, 44, 20, 10, 199, 4, 208, 129, 77, 48, 68, 20, 20, 0, 9, 134, 16, 15, 19, 195, 184, 18, 20, 9, 134, 13, 1, 12, 195, 184, 18, 20, 9, 198, 77, 64, 84, 37, 53, 0, 20, 9, 198, 21, 50, 193, 17, 35, 206, 20, 11, 200, 81, 32, 85, 52, 21, 9, 76, 176, 20, 11, 200, 65, 35, 203, 48, 149, 9, 76, 176, 20, 11, 200, 52, 21, 5, 52, 21, 9, 76, 176, 20, 11, 200, 16, 144, 75, 72, 149, 9, 76, 176, 20, 11, 200, 5, 34, 84, 52, 85, 9, 76, 176, 20, 11, 200, 4, 227, 210, 20, 181, 9, 76, 176, 20, 12, 201, 76, 19, 77, 20, 228, 213, 72, 149, 77, 20, 11, 200, 56, 81, 204, 36, 113, 78, 12, 80, 20, 7, 196, 45, 35, 193, 80, 20, 7, 196, 4, 115, 129, 80, 20, 0, 10, 135, 6, 15, 18, 8, 195, 184, 18, 20, 10, 135, 1, 13, 1, 20, 195, 184, 18, 20, 9, 198, 77, 69, 84, 80, 84, 137, 20, 9, 198, 8, 84, 133, 16, 84, 137, 20, 9, 198, 80, 131, 205, 37, 51, 69, 20, 9, 198, 41, 81, 1, 37, 51, 69, 20, 9, 198, 5, 34, 193, 37, 51, 69, 20, 10, 69, 8, 18, 76, 21, 144, 21, 0, 10, 0, 8, 198, 64, 84, 137, 44, 243, 128, 9, 198, 77, 147, 139, 72, 243, 128, 20, 9, 198, 52, 81, 193, 24, 243, 128, 20, 13, 202, 64, 20, 148, 36, 50, 80, 5, 66, 79, 56, 20, 13, 202, 44, 243, 147, 80, 83, 12, 5, 66, 79, 56, 20, 13, 202, 36, 229, 5, 73, 5, 78, 45, 66, 79, 56, 20, 15, 204, 44, 243, 147, 81, 37, 75, 80, 149, 137, 80, 85, 0, 20, 9, 198, 77, 84, 9, 57, 83, 64, 20, 17, 70, 60, 147, 19, 44, 147, 128, 114, 57, 55, 89, 49, 109, 50, 0, 20, 9, 198, 60, 97, 137, 12, 147, 128, 20, 13, 202, 88, 147, 204, 36, 226, 83, 80, 147, 132, 20, 20, 9, 198, 64, 84, 147, 36, 19, 128, 20, 16, 70, 33, 99, 210, 16, 19, 128, 84, 114, 72, 6, 110, 50, 0, 20, 0, 12, 137, 19, 16, 5, 4, 9, 20, 195, 184, 18, 20, 12, 137, 1, 14, 14, 15, 14, 3, 195, 184, 18, 20, 9, 198, 48, 85, 133, 72, 147, 135, 20, 9, 198, 48, 21, 133, 72, 147, 135, 20, 9, 198, 4, 65, 5, 72, 147, 135, 20, 10, 199, 64, 243, 25, 56, 243, 73, 20, 20, 10, 199, 21, 96, 78, 28, 83, 9, 20, 20, 10, 199, 53, 148, 212, 21, 34, 85, 52, 20, 10, 199, 45, 34, 84, 21, 34, 85, 52, 20, 10, 199, 44, 243, 131, 36, 194, 85, 52, 20, 10, 199, 16, 85, 84, 21, 34, 85, 52, 20, 10, 199, 88, 81, 197, 80, 16, 137, 48, 20, 0, 13, 138, 18, 5, 20, 15, 21, 3, 8, 195, 184, 18, 20, 13, 138, 16, 1, 19, 20, 9, 3, 8, 195, 184, 18, 20, 13, 138, 8, 5, 12, 19, 9, 14, 7, 195, 184, 18, 20, 7, 196, 64, 243, 5, 80, 20, 7, 196, 64, 19, 5, 80, 20, 9, 198, 12, 83, 12, 37, 53, 0, 20, 9, 198, 80, 20, 5, 81, 49, 82, 20, 9, 198, 72, 85, 129, 49, 81, 82, 20, 7, 196, 88, 148, 201, 80, 20, 7, 196, 76, 19, 1, 80, 20, 13, 72, 64, 144, 195, 4, 66, 76, 49, 144, 21, 0, 10, 0, 14, 139, 22, 5, 14, 20, 9, 12, 1, 20, 195, 184, 18, 20, 14, 139, 8, 25, 16, 14, 15, 20, 9, 19, 195, 184, 18, 20, 12, 201, 88, 147, 132, 36, 176, 84, 36, 243, 128, 20, 12, 201, 77, 80, 140, 36, 208, 84, 36, 243, 128, 20, 12, 201, 76, 81, 210, 20, 112, 84, 36, 243, 128, 20, 12, 201, 72, 84, 208, 37, 32, 84, 36, 243, 128, 20, 12, 201, 72, 83, 1, 45, 48, 84, 36, 243, 128, 20, 12, 201, 72, 82, 204, 4, 208, 84, 36, 243, 128, 20, 12, 201, 72, 82, 70, 36, 176, 84, 36, 243, 128, 20, 12, 201, 72, 81, 143, 72, 208, 84, 36, 243, 128, 20, 12, 201, 72, 80, 76, 37, 48, 84, 36, 243, 128, 20, 12, 201, 65, 80, 140, 36, 176, 84, 36, 243, 128, 20, 12, 201, 65, 35, 214, 60, 176, 84, 36, 243, 128, 20, 12, 201, 64, 84, 141, 85, 64, 84, 36, 243, 128, 20, 12, 201, 44, 244, 144, 61, 32, 84, 36, 243, 128, 20, 12, 201, 44, 243, 138, 84, 112, 84, 36, 243, 128, 20, 12, 201, 44, 243, 12, 60, 176, 84, 36, 243, 128, 20, 12, 201, 36, 228, 201, 57, 80, 84, 36, 243, 128, 20, 12, 201, 36, 225, 143, 72, 208, 84, 36, 243, 128, 20, 12, 201, 36, 212, 12, 36, 176, 84, 36, 243, 128, 20, 12, 201, 36, 211, 73, 29, 32, 84, 36, 243, 128, 20, 12, 201, 32, 16, 137, 81, 80, 84, 36, 243, 128, 20, 12, 201, 29, 32, 86, 37, 64, 84, 36, 243, 128, 20, 12, 201, 24, 197, 75, 81, 80, 84, 36, 243, 128, 20, 12, 201, 24, 16, 146, 36, 176, 84, 36, 243, 128, 20, 12, 201, 17, 148, 198, 84, 226, 212, 36, 243, 128, 20, 12, 201, 17, 84, 12, 36, 176, 84, 36, 243, 128, 20, 12, 201, 16, 84, 208, 21, 32, 84, 36, 243, 128, 20, 12, 201, 16, 84, 18, 37, 96, 84, 36, 243, 128, 20, 12, 201, 16, 83, 65, 72, 176, 84, 36, 243, 128, 20, 12, 201, 16, 82, 204, 5, 32, 84, 36, 243, 128, 20, 12, 201, 16, 82, 204, 4, 208, 84, 36, 243, 128, 20, 12, 201, 16, 81, 143, 72, 208, 84, 36, 243, 128, 20, 12, 201, 16, 81, 140, 61, 32, 84, 36, 243, 128, 20, 12, 201, 5, 52, 207, 12, 144, 84, 36, 243, 128, 20, 12, 201, 5, 4, 12, 36, 176, 84, 36, 243, 128, 20, 12, 201, 4, 178, 204, 4, 208, 84, 36, 243, 128, 20, 12, 201, 4, 97, 137, 72, 208, 84, 36, 243, 128, 20, 16, 205, 16, 83, 132, 72, 242, 210, 60, 227, 204, 60, 114, 83, 44, 20, 12, 201, 16, 84, 201, 16, 84, 129, 81, 83, 64, 20, 12, 201, 80, 84, 212, 36, 211, 206, 37, 83, 64, 20, 12, 201, 44, 243, 21, 52, 32, 82, 37, 83, 64, 20, 12, 201, 44, 19, 5, 56, 64, 82, 37, 83, 64, 20, 12, 201, 41, 81, 207, 76, 192, 86, 36, 83, 128, 20, 8, 197, 36, 229, 5, 57, 48, 20, 0, 15, 140, 4, 9, 19, 20, 18, 9, 2, 21, 20, 195, 184, 18, 20, 17, 70, 48, 144, 73, 76, 243, 128, 55, 37, 110, 89, 6, 114, 68, 0, 20, 17, 70, 8, 195, 213, 76, 243, 128, 71, 55, 40, 89, 6, 114, 68, 0, 20, 9, 198, 60, 181, 15, 28, 243, 128, 20, 9, 198, 64, 243, 25, 24, 243, 128, 20, 12, 201, 77, 84, 208, 20, 225, 5, 72, 147, 135, 20, 12, 201, 72, 80, 75, 80, 149, 133, 72, 147, 135, 20, 12, 201, 44, 243, 77, 20, 229, 5, 72, 147, 135, 20, 12, 201, 36, 225, 7, 72, 21, 133, 72, 147, 135, 20, 12, 201, 16, 148, 208, 21, 33, 197, 72, 147, 135, 20, 12, 201, 16, 148, 203, 60, 229, 5, 72, 147, 135, 20, 13, 202, 44, 243, 80, 61, 50, 84, 36, 243, 133, 48, 20, 9, 198, 64, 85, 9, 16, 147, 128, 20, 9, 198, 5, 68, 143, 64, 147, 128, 20, 9, 198, 44, 20, 21, 12, 147, 128, 20, 9, 198, 4, 100, 137, 44, 19, 128, 20, 9, 198, 65, 148, 143, 52, 19, 128, 21, 9, 198, 9, 32, 72, 52, 19, 128, 21, 0, 12, 201, 64, 242, 78, 80, 147, 12, 37, 53, 0, 20, 12, 137, 11, 22, 195, 166, 18, 21, 12, 5, 18, 20, 6, 195, 72, 83, 204, 20, 10, 199, 52, 17, 206, 21, 50, 85, 52, 20, 10, 199, 20, 180, 208, 48, 144, 201, 80, 20, 10, 199, 16, 144, 77, 21, 68, 129, 48, 20, 0, 15, 204, 81, 32, 78, 76, 98, 71, 85, 32, 84, 36, 243, 128, 20, 15, 204, 64, 84, 147, 60, 226, 70, 36, 176, 84, 36, 243, 128, 20, 15, 204, 52, 21, 5, 72, 144, 76, 37, 48, 84, 36, 243, 128, 20, 15, 204, 45, 38, 83, 80, 19, 12, 37, 48, 84, 36, 243, 128, 20, 15, 204, 16, 149, 133, 73, 50, 70, 36, 176, 84, 36, 243, 128, 20, 15, 204, 16, 145, 134, 21, 33, 78, 80, 144, 84, 36, 243, 128, 20, 15, 204, 5, 85, 5, 57, 66, 70, 36, 176, 84, 36, 243, 128, 20, 15, 140, 19, 21, 22, 5, 18, 195, 166, 14, 9, 20, 5, 20, 20, 7, 196, 80, 20, 133, 72, 20, 9, 198, 80, 16, 149, 37, 49, 82, 20, 9, 198, 73, 149, 13, 37, 49, 82, 20, 9, 198, 36, 228, 201, 57, 81, 82, 20, 9, 198, 5, 34, 193, 37, 49, 82, 20, 0, 9, 198, 77, 147, 66, 36, 244, 197, 20, 9, 198, 5, 3, 212, 20, 244, 197, 20, 9, 198, 16, 83, 65, 28, 241, 201, 20, 12, 201, 36, 229, 5, 72, 197, 68, 37, 83, 64, 20, 9, 198, 4, 229, 15, 57, 147, 73, 20, 8, 197, 77, 65, 82, 36, 192, 20, 6, 195, 64, 147, 206, 20, 8, 197, 52, 84, 137, 4, 224, 21, 8, 197, 77, 2, 82, 4, 192, 20, 0, 12, 201, 81, 32, 86, 21, 36, 197, 72, 147, 135, 20, 12, 201, 77, 64, 84, 36, 243, 133, 72, 147, 135, 20, 12, 201, 76, 81, 205, 20, 229, 5, 72, 147, 135, 20, 12, 201, 72, 83, 1, 80, 149, 133, 72, 147, 135, 20, 12, 201, 64, 145, 205, 20, 229, 5, 72, 147, 135, 20, 12, 201, 52, 243, 137, 80, 244, 133, 72, 147, 135, 20, 12, 201, 44, 243, 134, 84, 225, 5, 72, 147, 135, 20, 12, 201, 16, 81, 197, 56, 84, 133, 72, 147, 135, 20, 12, 201, 8, 241, 211, 80, 21, 133, 72, 147, 135, 20, 12, 201, 8, 147, 199, 72, 17, 133, 72, 147, 135, 20, 12, 201, 4, 48, 197, 48, 84, 133, 72, 147, 135, 20, 9, 198, 52, 20, 203, 36, 225, 76, 20, 9, 198, 37, 52, 129, 20, 194, 84, 20, 0, 27, 67, 73, 80, 128, 51, 6, 113, 71, 15, 114, 15, 89, 72, 6, 113, 71, 0, 82, 111, 103, 32, 115, 116, 117, 98, 32, 18, 207, 81, 32, 78, 77, 53, 66, 77, 64, 78, 80, 144, 84, 36, 243, 128, 20, 10, 199, 72, 21, 9, 32, 16, 133, 72, 20, 10, 199, 24, 82, 140, 4, 117, 9, 28, 20, 10, 199, 80, 244, 142, 37, 34, 83, 44, 20, 10, 199, 77, 147, 143, 65, 66, 83, 44, 20, 10, 199, 76, 243, 9, 77, 66, 83, 44, 20, 10, 199, 76, 82, 212, 21, 34, 83, 44, 20, 10, 199, 57, 81, 9, 77, 66, 83, 44, 20, 10, 199, 45, 84, 147, 61, 34, 83, 44, 20, 10, 199, 20, 179, 5, 45, 66, 83, 44, 20, 10, 199, 17, 148, 198, 5, 66, 83, 44, 20, 10, 199, 8, 20, 130, 5, 34, 83, 44, 20, 10, 199, 5, 67, 1, 57, 66, 83, 44, 20, 10, 199, 49, 83, 132, 20, 228, 197, 72, 20, 10, 199, 24, 82, 140, 4, 117, 9, 28, 20, 10, 199, 52, 19, 135, 20, 176, 78, 80, 20, 0, 29, 68, 16, 84, 133, 76, 72, 109, 12, 114, 89, 15, 49, 84, 112, 6, 47, 36, 34, 0, 81, 107, 118, 97, 114, 116, 101, 114, 32, 9, 198, 72, 83, 9, 28, 147, 206, 20, 13, 138, 16, 18, 195, 166, 20, 5, 14, 4, 5, 18, 20, 7, 196, 4, 212, 5, 72, 20, 11, 200, 88, 81, 197, 80, 20, 137, 4, 224, 20, 7, 196, 40, 20, 1, 56, 20, 11, 200, 20, 53, 65, 16, 244, 137, 4, 224, 20, 9, 198, 76, 84, 135, 20, 229, 0, 20, 7, 196, 33, 84, 193, 72, 20, 11, 200, 37, 36, 129, 80, 147, 206, 4, 192, 20, 7, 196, 40, 84, 133, 76, 76, 13, 68, 16, 84, 133, 76, 72, 109, 12, 114, 89, 0, 72, 12, 3, 95, 49, 15, 83, 118, 34, 89, 72, 108, 0, 0, 8, 197, 28, 83, 149, 36, 224, 20, 9, 198, 65, 148, 143, 52, 19, 137, 20, 9, 198, 44, 18, 207, 24, 243, 137, 20, 8, 197, 36, 225, 9, 4, 224, 20, 8, 197, 8, 21, 137, 4, 224, 21, 12, 137, 16, 18, 195, 166, 7, 14, 1, 14, 20, 20, 0, 15, 66, 25, 128, 83, 114, 36, 81, 89, 36, 65, 48, 13, 55, 0, 9, 198, 80, 147, 139, 81, 84, 128, 20, 9, 198, 4, 113, 78, 81, 84, 128, 20, 13, 202, 76, 179, 204, 20, 209, 83, 80, 84, 133, 72, 20, 13, 202, 77, 84, 146, 20, 19, 9, 77, 66, 83, 44, 20, 13, 202, 77, 65, 82, 20, 244, 203, 61, 2, 83, 44, 20, 13, 202, 56, 85, 84, 72, 19, 9, 77, 66, 83, 44, 20, 13, 202, 56, 21, 21, 72, 19, 9, 77, 66, 83, 44, 20, 13, 202, 48, 144, 133, 72, 19, 9, 77, 66, 83, 44, 20, 13, 202, 44, 243, 139, 72, 85, 9, 77, 66, 83, 44, 20, 13, 202, 44, 243, 80, 36, 192, 84, 61, 34, 83, 44, 20, 13, 202, 44, 243, 15, 72, 147, 69, 81, 34, 83, 44, 20, 13, 202, 40, 245, 82, 56, 19, 9, 77, 66, 83, 44, 20, 13, 202, 24, 192, 71, 20, 195, 1, 57, 66, 83, 44, 20, 13, 202, 9, 84, 133, 5, 82, 210, 5, 66, 83, 44, 20, 13, 202, 8, 83, 12, 21, 68, 137, 77, 66, 83, 44, 20, 13, 202, 4, 36, 207, 49, 85, 9, 77, 66, 83, 44, 20, 9, 198, 52, 146, 210, 60, 194, 84, 20, 9, 198, 44, 243, 80, 61, 50, 84, 20, 0, 10, 199, 44, 243, 150, 20, 181, 15, 72, 20, 10, 199, 44, 243, 148, 4, 181, 15, 72, 20, 12, 201, 77, 80, 147, 80, 149, 21, 80, 147, 206, 20, 12, 201, 65, 35, 203, 48, 19, 65, 80, 147, 206, 20, 12, 201, 44, 20, 9, 81, 83, 1, 80, 147, 206, 20, 12, 201, 5, 52, 201, 52, 147, 1, 80, 147, 206, 20, 12, 201, 4, 208, 76, 28, 19, 65, 80, 147, 206, 20, 12, 201, 4, 178, 213, 53, 83, 1, 80, 147, 206, 20, 10, 199, 56, 243, 65, 16, 148, 197, 72, 20, 10, 199, 4, 194, 193, 48, 148, 197, 72, 20, 10, 199, 77, 80, 147, 60, 226, 83, 44, 20, 10, 199, 77, 1, 75, 84, 192, 78, 80, 20, 10, 67, 16, 145, 192, 72, 35, 57, 0, 76, 10, 3, 226, 130, 172, 36, 40, 34, 39, 0, 0, 17, 142, 14, 195, 166, 19, 20, 11, 15, 13, 13, 1, 14, 4, 5, 18, 20, 11, 200, 64, 20, 129, 29, 80, 89, 4, 224, 20, 0, 8, 197, 76, 86, 9, 77, 64, 20, 8, 197, 41, 84, 137, 77, 64, 20, 8, 197, 64, 147, 206, 21, 32, 20, 16, 205, 76, 83, 147, 5, 66, 79, 56, 19, 9, 77, 66, 83, 44, 20, 8, 197, 24, 19, 12, 37, 64, 20, 8, 197, 36, 226, 84, 5, 32, 20, 8, 197, 32, 82, 212, 5, 32, 20, 9, 198, 20, 228, 201, 48, 17, 197, 20, 11, 70, 32, 243, 69, 64, 17, 197, 21, 0, 10, 0, 22, 67, 48, 145, 197, 55, 37, 13, 15, 49, 39, 89, 72, 13, 0, 81, 107, 111, 115, 116, 101, 32, 17, 67, 48, 145, 197, 55, 37, 13, 15, 89, 114, 0, 81, 115, 195, 165, 32, 9, 198, 9, 35, 203, 4, 65, 64, 20, 12, 137, 16, 18, 195, 166, 7, 14, 1, 14, 19, 20, 6, 195, 64, 17, 197, 20, 0, 10, 199, 28, 84, 141, 4, 226, 83, 80, 20, 12, 201, 52, 19, 137, 65, 83, 1, 80, 147, 206, 20, 10, 199, 89, 84, 132, 21, 34, 78, 28, 20, 10, 199, 80, 245, 80, 21, 34, 78, 28, 20, 10, 199, 53, 83, 132, 21, 34, 78, 28, 20, 10, 199, 44, 16, 200, 21, 34, 78, 28, 20, 10, 199, 25, 83, 132, 21, 34, 78, 28, 20, 10, 199, 21, 35, 196, 21, 34, 78, 28, 20, 10, 199, 20, 66, 84, 21, 34, 78, 28, 20, 10, 199, 16, 146, 212, 21, 34, 78, 28, 20, 9, 198, 80, 82, 83, 80, 148, 203, 20, 9, 198, 61, 33, 193, 56, 148, 203, 20, 9, 198, 44, 84, 149, 8, 148, 203, 20, 9, 198, 16, 82, 83, 80, 148, 203, 20, 9, 198, 12, 20, 137, 8, 148, 203, 20, 10, 199, 5, 53, 18, 60, 227, 205, 36, 20, 10, 199, 5, 32, 137, 81, 32, 71, 20, 20, 10, 67, 40, 81, 192, 57, 35, 37, 0, 76, 0, 29, 68, 12, 243, 133, 100, 6, 49, 39, 40, 50, 37, 15, 6, 35, 57, 55, 108, 50, 72, 0, 81, 105, 115, 108, 97, 110, 100, 32, 11, 200, 72, 85, 129, 56, 50, 9, 77, 64, 20, 11, 200, 9, 32, 84, 76, 50, 9, 77, 64, 20, 11, 200, 36, 229, 5, 57, 50, 86, 21, 32, 20, 11, 200, 52, 20, 147, 44, 19, 12, 5, 64, 20, 9, 198, 12, 83, 12, 60, 96, 78, 21, 10, 3, 95, 50, 15, 110, 50, 13, 50, 0, 0, 12, 201, 60, 213, 133, 45, 51, 5, 48, 145, 192, 20, 12, 201, 48, 19, 132, 24, 198, 71, 80, 145, 192, 20, 8, 197, 76, 179, 204, 5, 32, 20, 8, 197, 28, 145, 193, 57, 64, 20, 0, 6, 194, 12, 240, 17, 42, 9, 198, 52, 20, 203, 36, 225, 64, 20, 13, 202, 77, 68, 149, 45, 69, 82, 4, 194, 83, 80, 20, 13, 202, 36, 225, 21, 77, 68, 137, 4, 194, 83, 80, 20, 13, 202, 88, 17, 193, 8, 243, 132, 21, 34, 78, 28, 20, 13, 202, 8, 19, 132, 21, 35, 204, 21, 34, 78, 28, 20, 12, 137, 19, 1, 13, 8, 195, 184, 18, 9, 7, 20, 9, 198, 4, 228, 197, 48, 145, 192, 20, 12, 201, 77, 147, 12, 60, 114, 83, 80, 148, 203, 20, 12, 201, 64, 243, 9, 80, 243, 15, 28, 148, 203, 20, 12, 201, 21, 50, 193, 80, 243, 15, 28, 148, 203, 20, 9, 198, 4, 225, 204, 60, 98, 76, 20, 9, 198, 20, 210, 84, 80, 83, 148, 20, 9, 198, 53, 148, 137, 4, 65, 64, 20, 9, 198, 76, 147, 85, 48, 19, 148, 20, 13, 70, 41, 81, 197, 52, 83, 148, 21, 102, 114, 0, 10, 0, 12, 201, 44, 243, 77, 84, 226, 75, 5, 67, 210, 20, 10, 199, 64, 197, 82, 4, 194, 83, 80, 20, 10, 199, 29, 82, 84, 5, 34, 83, 80, 20, 10, 199, 12, 83, 66, 4, 194, 83, 80, 20, 13, 138, 25, 14, 11, 22, 195, 166, 18, 4, 9, 7, 20, 13, 138, 20, 18, 15, 22, 195, 166, 18, 4, 9, 7, 20, 13, 138, 16, 195, 165, 12, 9, 4, 5, 12, 9, 7, 20, 13, 138, 12, 5, 20, 6, 195, 166, 18, 4, 9, 7, 20, 9, 198, 76, 83, 73, 80, 148, 203, 20, 9, 198, 4, 224, 82, 44, 148, 203, 20, 9, 198, 16, 146, 203, 20, 66, 75, 20, 0, 9, 198, 72, 17, 9, 5, 67, 210, 20, 11, 200, 81, 32, 78, 77, 3, 206, 21, 32, 20, 11, 200, 72, 83, 79, 57, 53, 18, 21, 32, 20, 7, 196, 28, 148, 133, 72, 20, 11, 200, 16, 83, 79, 57, 53, 18, 21, 32, 20, 14, 139, 19, 20, 9, 12, 6, 195, 166, 18, 4, 9, 7, 20, 14, 139, 15, 13, 19, 20, 195, 184, 4, 5, 12, 9, 7, 20, 14, 139, 8, 21, 19, 11, 22, 195, 166, 18, 4, 9, 7, 20, 14, 139, 7, 12, 15, 18, 22, 195, 166, 18, 4, 9, 7, 20, 14, 139, 5, 12, 19, 11, 22, 195, 166, 18, 4, 9, 7, 20, 14, 139, 1, 14, 19, 20, 195, 184, 4, 5, 12, 9, 7, 20, 9, 198, 56, 81, 210, 60, 145, 0, 20, 9, 198, 81, 84, 141, 4, 194, 78, 20, 7, 196, 76, 244, 129, 56, 20, 7, 196, 8, 83, 137, 56, 20, 11, 200, 16, 84, 195, 20, 225, 5, 57, 64, 20, 7, 196, 44, 244, 129, 56, 21, 11, 200, 44, 243, 131, 21, 37, 1, 57, 64, 20, 11, 200, 44, 243, 66, 5, 69, 1, 57, 64, 20, 11, 200, 4, 194, 77, 20, 229, 1, 57, 64, 20, 0, 8, 197, 16, 144, 76, 60, 112, 20, 8, 197, 44, 16, 137, 56, 80, 20, 8, 197, 41, 83, 5, 72, 144, 20, 15, 140, 13, 195, 166, 18, 11, 22, 195, 166, 18, 4, 9, 7, 20, 12, 201, 44, 81, 19, 60, 211, 69, 48, 145, 192, 20, 12, 201, 29, 81, 4, 60, 211, 69, 48, 145, 192, 20, 12, 201, 24, 244, 142, 20, 211, 69, 48, 145, 192, 20, 15, 204, 64, 20, 148, 36, 181, 76, 5, 34, 83, 80, 148, 203, 20, 15, 204, 56, 243, 139, 60, 225, 143, 72, 210, 83, 80, 148, 203, 20, 8, 197, 52, 19, 137, 76, 176, 20, 9, 198, 64, 197, 84, 60, 226, 69, 20, 16, 69, 76, 19, 1, 52, 144, 89, 110, 55, 6, 110, 65, 37, 0, 20, 8, 197, 52, 85, 18, 36, 176, 20, 8, 197, 64, 243, 9, 12, 80, 20, 8, 197, 64, 243, 65, 16, 80, 20, 0, 9, 198, 61, 5, 9, 52, 148, 212, 20, 9, 198, 32, 21, 129, 72, 148, 212, 20, 9, 198, 4, 181, 129, 72, 148, 212, 20, 12, 137, 195, 166, 4, 18, 21, 5, 12, 9, 7, 20, 16, 141, 22, 5, 12, 1, 14, 19, 20, 195, 166, 14, 4, 9, 7, 20, 12, 201, 88, 83, 133, 72, 243, 15, 28, 148, 203, 20, 12, 201, 61, 35, 137, 80, 243, 15, 28, 148, 203, 20, 12, 201, 60, 67, 206, 80, 243, 15, 28, 148, 203, 20, 12, 201, 60, 49, 65, 56, 243, 15, 28, 148, 203, 20, 12, 201, 52, 148, 193, 57, 68, 143, 64, 148, 203, 20, 12, 201, 33, 145, 18, 61, 53, 1, 80, 148, 203, 20, 12, 201, 28, 192, 67, 36, 243, 15, 28, 148, 203, 20, 12, 201, 24, 147, 1, 57, 68, 143, 64, 148, 203, 20, 12, 201, 24, 83, 73, 56, 243, 15, 28, 148, 203, 20, 9, 198, 5, 49, 80, 80, 146, 192, 20, 0, 22, 71, 64, 244, 212, 36, 195, 15, 56, 48, 4, 114, 89, 72, 37, 55, 57, 6, 114, 68, 0, 20, 10, 199, 76, 82, 212, 36, 243, 133, 72, 20, 10, 199, 5, 85, 15, 72, 148, 197, 72, 20, 10, 199, 29, 34, 78, 4, 117, 9, 28, 20, 9, 198, 28, 83, 89, 80, 194, 71, 20, 9, 198, 20, 225, 143, 48, 66, 71, 20, 10, 199, 77, 147, 148, 21, 66, 83, 44, 20, 10, 199, 77, 83, 142, 37, 66, 83, 44, 20, 10, 199, 76, 242, 210, 5, 66, 83, 44, 20, 10, 199, 76, 83, 65, 57, 66, 83, 44, 20, 10, 199, 72, 243, 65, 57, 66, 83, 44, 20, 10, 199, 65, 54, 75, 61, 66, 83, 44, 20, 10, 199, 61, 32, 84, 61, 34, 83, 44, 20, 10, 199, 52, 21, 82, 37, 66, 83, 44, 20, 10, 199, 52, 19, 201, 77, 66, 83, 44, 20, 10, 199, 49, 147, 70, 5, 66, 83, 44, 20, 10, 199, 48, 241, 201, 77, 66, 83, 44, 20, 10, 199, 44, 194, 77, 5, 66, 83, 44, 20, 10, 199, 21, 96, 83, 61, 34, 83, 44, 20, 10, 199, 20, 179, 9, 65, 66, 83, 44, 20, 10, 199, 16, 241, 205, 5, 66, 83, 44, 20, 10, 199, 16, 84, 208, 61, 66, 83, 44, 20, 10, 199, 5, 37, 9, 77, 66, 83, 44, 20, 10, 199, 5, 35, 205, 5, 66, 83, 44, 20, 12, 201, 28, 19, 12, 37, 83, 79, 96, 145, 0, 20, 10, 199, 65, 32, 71, 52, 21, 9, 44, 20, 10, 199, 64, 244, 142, 60, 116, 129, 24, 20, 10, 199, 29, 34, 78, 4, 117, 9, 28, 20, 0, 9, 134, 20, 18, 9, 195, 184, 18, 20, 11, 200, 52, 85, 1, 48, 197, 82, 28, 144, 20, 9, 198, 64, 83, 148, 4, 115, 206, 20, 7, 196, 5, 35, 69, 72, 20, 14, 139, 22, 9, 4, 20, 12, 195, 184, 6, 20, 9, 7, 20, 18, 143, 16, 5, 20, 5, 18, 1, 14, 19, 20, 195, 166, 14, 4, 9, 7, 20, 14, 139, 1, 14, 6, 195, 166, 7, 20, 5, 12, 9, 7, 20, 11, 200, 80, 83, 5, 52, 21, 9, 76, 176, 20, 11, 200, 76, 241, 15, 52, 149, 9, 76, 176, 20, 11, 200, 64, 225, 85, 52, 21, 9, 76, 176, 20, 11, 200, 52, 243, 143, 48, 149, 9, 76, 176, 20, 11, 200, 52, 85, 15, 57, 147, 73, 76, 176, 20, 11, 200, 29, 147, 78, 5, 53, 9, 76, 176, 20, 11, 200, 29, 32, 77, 52, 21, 9, 76, 176, 20, 11, 200, 25, 148, 201, 85, 33, 201, 76, 176, 20, 11, 200, 24, 195, 210, 37, 53, 9, 76, 176, 20, 11, 200, 24, 147, 15, 76, 241, 137, 76, 176, 20, 11, 200, 20, 225, 82, 28, 85, 9, 76, 176, 20, 11, 200, 8, 147, 199, 72, 17, 137, 76, 176, 20, 11, 200, 8, 16, 153, 48, 243, 137, 76, 176, 20, 11, 200, 4, 99, 210, 37, 53, 9, 76, 176, 20, 12, 3, 95, 51, 15, 47, 34, 109, 72, 57, 108, 0, 8, 4, 95, 15, 18, 4, 108, 0, 0, 11, 136, 1, 13, 15, 21, 18, 195, 184, 19, 20, 15, 140, 14, 5, 4, 6, 195, 166, 12, 4, 5, 12, 9, 7, 20, 15, 140, 6, 15, 18, 14, 195, 166, 18, 13, 5, 12, 9, 7, 20, 12, 201, 80, 83, 5, 60, 195, 199, 37, 50, 192, 20, 12, 201, 80, 82, 206, 60, 195, 199, 37, 50, 192, 20, 12, 201, 56, 85, 82, 60, 195, 199, 37, 50, 192, 20, 12, 201, 52, 244, 134, 60, 195, 199, 37, 50, 192, 20, 12, 201, 52, 85, 18, 60, 195, 199, 37, 50, 192, 20, 16, 69, 52, 83, 137, 76, 176, 65, 36, 50, 6, 37, 89, 49, 0, 20, 9, 198, 52, 17, 206, 60, 194, 69, 20, 12, 201, 65, 35, 194, 48, 83, 65, 80, 146, 192, 20, 12, 201, 44, 148, 143, 65, 32, 75, 80, 146, 192, 20, 8, 197, 52, 19, 9, 12, 80, 20, 12, 201, 20, 180, 212, 20, 212, 15, 72, 19, 0, 20, 0, 9, 198, 61, 33, 193, 56, 148, 212, 20, 18, 70, 4, 181, 129, 72, 83, 0, 112, 49, 84, 112, 51, 6, 111, 55, 0, 20, 13, 202, 72, 83, 1, 80, 149, 137, 77, 66, 83, 44, 20, 13, 202, 65, 35, 214, 60, 176, 84, 61, 34, 83, 44, 20, 13, 202, 64, 20, 129, 16, 145, 205, 5, 66, 83, 44, 20, 13, 202, 48, 147, 12, 20, 20, 201, 5, 66, 83, 44, 20, 13, 202, 44, 19, 11, 84, 192, 84, 61, 34, 83, 44, 20, 13, 202, 36, 228, 208, 37, 32, 84, 61, 34, 83, 44, 20, 13, 202, 36, 225, 143, 72, 208, 84, 61, 34, 83, 44, 20, 13, 202, 32, 245, 20, 20, 229, 15, 81, 66, 83, 44, 20, 13, 202, 16, 144, 71, 72, 19, 77, 5, 66, 83, 44, 20, 13, 202, 16, 82, 204, 5, 32, 84, 61, 34, 83, 44, 20, 13, 202, 8, 243, 19, 40, 85, 137, 77, 66, 83, 44, 20, 13, 202, 5, 34, 83, 80, 242, 210, 5, 66, 83, 44, 20, 13, 202, 4, 180, 207, 56, 243, 69, 81, 34, 83, 44, 20, 9, 198, 80, 83, 65, 80, 146, 192, 20, 9, 198, 4, 181, 83, 80, 146, 192, 20, 9, 198, 64, 21, 18, 60, 224, 84, 20, 0, 10, 199, 4, 66, 149, 56, 181, 21, 72, 20, 10, 199, 88, 148, 201, 80, 21, 15, 72, 20, 10, 199, 85, 53, 82, 64, 21, 15, 72, 20, 12, 201, 36, 225, 137, 49, 68, 129, 80, 147, 206, 20, 12, 201, 36, 225, 15, 64, 84, 129, 80, 147, 206, 20, 12, 201, 16, 148, 212, 72, 144, 149, 80, 147, 206, 20, 12, 201, 16, 83, 149, 57, 66, 65, 80, 147, 206, 20, 12, 201, 36, 195, 15, 100, 19, 9, 80, 85, 0, 20, 12, 201, 5, 51, 195, 36, 19, 9, 80, 85, 0, 20, 10, 199, 88, 242, 193, 48, 148, 197, 72, 20, 14, 203, 8, 244, 148, 5, 82, 212, 36, 243, 133, 72, 80, 20, 21, 146, 13, 9, 19, 21, 14, 4, 5, 12, 19, 5, 19, 22, 195, 166, 18, 4, 9, 7, 20, 14, 203, 44, 243, 148, 72, 20, 21, 56, 181, 9, 76, 176, 20, 10, 199, 4, 208, 146, 61, 50, 83, 44, 20, 10, 199, 77, 147, 143, 57, 147, 73, 44, 20, 12, 201, 44, 243, 135, 48, 243, 69, 72, 21, 0, 20, 0, 11, 200, 32, 84, 144, 21, 67, 204, 60, 112, 20, 9, 198, 32, 20, 144, 37, 53, 0, 20, 11, 200, 76, 20, 129, 12, 83, 137, 76, 176, 20, 11, 200, 64, 144, 78, 37, 53, 9, 76, 176, 20, 11, 200, 56, 18, 86, 37, 53, 9, 76, 176, 20, 11, 200, 52, 243, 143, 24, 243, 137, 76, 176, 20, 15, 204, 44, 20, 129, 45, 65, 82, 60, 195, 199, 37, 50, 192, 20, 11, 200, 32, 85, 82, 37, 53, 9, 76, 176, 20, 11, 200, 32, 81, 197, 52, 243, 137, 76, 176, 20, 11, 200, 24, 21, 86, 37, 53, 9, 76, 176, 20, 11, 200, 8, 18, 203, 4, 229, 9, 76, 176, 20, 11, 200, 4, 116, 143, 56, 243, 73, 76, 176, 20, 11, 200, 65, 34, 86, 36, 193, 71, 36, 80, 20, 7, 196, 52, 84, 137, 80, 20, 11, 200, 80, 82, 206, 60, 180, 129, 80, 144, 20, 11, 200, 21, 128, 197, 48, 193, 78, 12, 80, 20, 7, 196, 76, 83, 129, 80, 20, 7, 196, 64, 20, 129, 80, 20, 7, 196, 52, 244, 129, 48, 20, 7, 196, 44, 244, 129, 48, 20, 0, 16, 205, 44, 243, 147, 81, 37, 75, 80, 149, 137, 77, 66, 83, 44, 20, 16, 205, 20, 180, 200, 36, 34, 84, 36, 243, 137, 77, 66, 83, 44, 20, 0, 9, 198, 80, 83, 5, 24, 243, 128, 20, 15, 204, 36, 229, 5, 57, 66, 79, 56, 19, 9, 80, 85, 0, 20, 12, 201, 88, 83, 2, 20, 128, 71, 20, 194, 71, 20, 12, 201, 77, 68, 129, 25, 50, 217, 48, 66, 71, 20, 12, 201, 32, 245, 133, 17, 48, 71, 20, 194, 71, 20, 9, 198, 41, 83, 135, 36, 19, 128, 20, 9, 198, 72, 19, 65, 16, 19, 128, 21, 0, 12, 137, 9, 13, 16, 15, 18, 20, 195, 184, 18, 20, 12, 201, 44, 243, 147, 81, 34, 75, 80, 147, 206, 20, 12, 201, 36, 225, 140, 4, 211, 65, 80, 147, 206, 20, 12, 201, 5, 37, 9, 45, 83, 1, 80, 147, 206, 20, 14, 203, 85, 66, 76, 37, 64, 82, 37, 53, 9, 76, 176, 20, 14, 203, 81, 34, 71, 60, 227, 205, 21, 68, 137, 76, 176, 20, 14, 203, 44, 192, 85, 77, 68, 143, 24, 240, 137, 76, 176, 20, 14, 203, 20, 181, 137, 48, 144, 146, 37, 53, 9, 76, 176, 20, 15, 140, 16, 195, 166, 4, 1, 7, 15, 7, 9, 11, 21, 13, 20, 10, 199, 76, 147, 5, 57, 66, 85, 52, 20, 10, 199, 61, 32, 84, 61, 34, 85, 52, 20, 10, 199, 32, 84, 130, 5, 34, 85, 52, 20, 10, 199, 88, 242, 193, 48, 148, 205, 20, 20, 10, 199, 56, 243, 65, 16, 148, 205, 20, 20, 10, 199, 45, 98, 69, 80, 148, 205, 20, 20, 10, 199, 32, 85, 5, 72, 241, 137, 48, 20, 12, 137, 195, 165, 18, 8, 21, 19, 9, 1, 14, 20, 10, 199, 44, 243, 210, 16, 147, 129, 80, 20, 9, 198, 52, 20, 131, 37, 0, 78, 21, 10, 199, 84, 226, 86, 21, 36, 193, 48, 20, 10, 199, 28, 19, 15, 65, 0, 68, 20, 20, 8, 67, 73, 83, 128, 21, 0, 10, 0, 13, 138, 19, 11, 195, 166, 12, 19, 11, 195, 184, 18, 20, 7, 196, 8, 17, 21, 80, 20, 7, 196, 76, 243, 5, 80, 20, 9, 198, 85, 67, 208, 37, 53, 0, 20, 9, 198, 56, 244, 132, 37, 53, 0, 20, 9, 198, 76, 50, 1, 81, 65, 82, 20, 9, 198, 44, 243, 12, 4, 33, 82, 20, 9, 198, 20, 160, 75, 84, 193, 82, 20, 9, 198, 16, 85, 129, 49, 81, 82, 20, 11, 200, 4, 208, 137, 88, 19, 5, 57, 48, 20, 0, 9, 198, 4, 225, 201, 88, 84, 137, 20, 0, 5, 194, 36, 64, 17, 12, 201, 64, 84, 211, 36, 210, 83, 80, 148, 203, 20, 12, 201, 52, 243, 143, 80, 82, 83, 80, 148, 203, 20, 12, 201, 52, 243, 129, 72, 178, 83, 80, 148, 203, 20, 12, 201, 24, 19, 1, 56, 114, 83, 80, 148, 203, 20, 12, 201, 16, 81, 129, 37, 66, 83, 80, 148, 203, 20, 13, 202, 60, 36, 197, 73, 96, 84, 61, 34, 85, 52, 20, 13, 202, 72, 81, 204, 20, 209, 78, 80, 84, 133, 80, 20, 13, 202, 4, 194, 207, 32, 243, 9, 76, 84, 133, 80, 20, 0, 19, 71, 12, 129, 86, 72, 243, 5, 80, 89, 57, 109, 84, 34, 39, 55, 6, 36, 0, 10, 199, 24, 192, 71, 20, 243, 5, 80, 20, 10, 199, 64, 83, 148, 4, 116, 129, 52, 20, 10, 199, 32, 82, 211, 4, 116, 129, 52, 20, 12, 201, 45, 35, 206, 60, 195, 199, 37, 49, 82, 20, 9, 198, 21, 36, 129, 80, 148, 203, 20, 9, 198, 9, 37, 78, 20, 148, 203, 20, 10, 199, 64, 193, 66, 37, 48, 201, 80, 20, 10, 199, 21, 2, 83, 44, 244, 1, 48, 20, 0, 9, 198, 77, 83, 6, 60, 225, 82, 20, 7, 196, 64, 20, 133, 72, 20, 9, 198, 33, 145, 18, 5, 162, 78, 20, 7, 196, 4, 116, 129, 72, 20, 13, 72, 8, 80, 67, 32, 37, 71, 29, 144, 21, 0, 10, 0, 9, 198, 80, 245, 82, 57, 84, 133, 20, 9, 198, 76, 179, 5, 72, 244, 197, 20, 9, 198, 76, 176, 66, 36, 244, 197, 20, 8, 197, 16, 144, 75, 60, 224, 20, 8, 197, 88, 148, 201, 60, 224, 20, 8, 197, 16, 147, 216, 36, 64, 20, 8, 197, 48, 21, 18, 36, 224, 20, 8, 197, 12, 149, 18, 36, 224, 20, 9, 198, 80, 83, 5, 24, 243, 137, 20, 8, 197, 65, 35, 198, 36, 192, 20, 8, 197, 88, 84, 130, 4, 192, 20, 0, 12, 201, 24, 147, 129, 57, 50, 69, 72, 147, 135, 20, 12, 201, 24, 147, 15, 76, 241, 133, 72, 147, 135, 20, 9, 198, 80, 21, 15, 88, 84, 128, 20, 9, 198, 76, 242, 71, 56, 84, 128, 20, 9, 198, 72, 85, 9, 72, 84, 128, 20, 9, 198, 20, 210, 71, 72, 84, 128, 20, 9, 198, 16, 81, 137, 48, 84, 128, 20, 9, 198, 16, 80, 149, 80, 84, 128, 20, 9, 198, 12, 128, 83, 76, 84, 128, 20, 9, 198, 8, 243, 137, 80, 84, 128, 20, 9, 198, 65, 35, 212, 60, 179, 204, 20, 12, 201, 36, 211, 85, 56, 243, 15, 28, 148, 203, 20, 12, 201, 32, 84, 143, 77, 68, 129, 80, 148, 203, 20, 12, 201, 20, 118, 80, 80, 243, 15, 28, 148, 203, 20, 9, 198, 76, 21, 5, 48, 194, 84, 20, 0, 10, 199, 72, 80, 197, 57, 50, 79, 56, 20, 10, 199, 36, 226, 204, 85, 50, 79, 56, 20, 10, 199, 44, 243, 150, 21, 36, 197, 72, 20, 10, 199, 44, 243, 147, 20, 180, 133, 72, 20, 10, 199, 12, 149, 137, 48, 148, 197, 72, 20, 10, 199, 77, 83, 77, 5, 34, 83, 44, 20, 10, 199, 76, 177, 77, 5, 66, 83, 44, 20, 10, 199, 32, 148, 212, 61, 34, 83, 44, 20, 10, 199, 20, 195, 9, 65, 66, 83, 44, 20, 10, 199, 52, 19, 12, 61, 32, 193, 56, 20, 0, 22, 72, 44, 243, 134, 37, 35, 65, 56, 64, 49, 114, 50, 83, 36, 34, 65, 6, 110, 50, 72, 0, 10, 200, 64, 19, 143, 65, 66, 75, 60, 224, 11, 200, 65, 35, 198, 21, 52, 201, 60, 224, 20, 11, 200, 44, 243, 139, 49, 84, 201, 60, 224, 20, 11, 200, 44, 243, 134, 21, 52, 201, 60, 224, 20, 11, 200, 20, 180, 208, 48, 244, 201, 60, 224, 20, 7, 196, 44, 20, 5, 72, 20, 7, 196, 48, 21, 9, 56, 20, 7, 196, 48, 21, 9, 56, 20, 9, 198, 77, 2, 82, 4, 229, 0, 20, 7, 196, 56, 245, 1, 8, 20, 11, 3, 95, 53, 15, 83, 109, 65, 47, 108, 0, 0, 9, 198, 9, 35, 195, 33, 84, 133, 20, 9, 198, 8, 83, 133, 24, 144, 197, 67, 8, 197, 44, 20, 212, 20, 192, 20, 8, 197, 44, 20, 148, 20, 192, 20, 8, 197, 44, 20, 212, 20, 192, 20, 8, 197, 44, 20, 148, 20, 192, 20, 12, 201, 72, 83, 1, 80, 149, 137, 76, 84, 128, 20, 12, 201, 21, 2, 71, 72, 17, 137, 44, 84, 128, 20, 9, 198, 20, 180, 197, 28, 84, 197, 20, 8, 197, 24, 195, 210, 36, 224, 20, 9, 198, 8, 83, 133, 24, 144, 197, 20, 8, 197, 76, 244, 18, 4, 224, 21, 0, 5, 194, 37, 64, 17, 13, 202, 77, 68, 143, 8, 244, 203, 61, 2, 83, 44, 20, 13, 202, 72, 81, 143, 72, 208, 84, 61, 34, 83, 44, 20, 13, 202, 21, 2, 71, 72, 19, 77, 5, 66, 83, 44, 20, 13, 202, 16, 82, 204, 4, 208, 84, 61, 34, 83, 44, 20, 9, 198, 80, 83, 196, 60, 194, 84, 20, 9, 198, 76, 178, 66, 60, 226, 84, 20, 15, 4, 95, 13, 3, 14, 65, 6, 35, 49, 34, 4, 115, 50, 0, 0, 10, 199, 44, 243, 132, 84, 181, 15, 72, 20, 10, 199, 28, 192, 68, 36, 21, 15, 72, 20, 10, 199, 21, 96, 76, 84, 21, 15, 72, 20, 12, 201, 48, 81, 201, 80, 147, 65, 80, 147, 206, 20, 10, 199, 21, 99, 204, 85, 66, 79, 56, 20, 10, 199, 20, 193, 86, 5, 66, 79, 56, 20, 10, 199, 72, 243, 65, 56, 148, 197, 72, 20, 10, 199, 72, 81, 18, 21, 52, 197, 72, 20, 10, 199, 64, 20, 129, 49, 148, 197, 72, 20, 10, 199, 52, 19, 149, 17, 80, 197, 72, 20, 10, 199, 4, 229, 9, 12, 148, 5, 72, 20, 10, 199, 77, 148, 212, 20, 210, 83, 44, 20, 10, 199, 64, 19, 132, 20, 210, 83, 44, 20, 10, 199, 28, 128, 78, 21, 50, 83, 44, 20, 10, 199, 28, 83, 204, 60, 114, 83, 44, 20, 10, 199, 72, 84, 201, 77, 65, 78, 80, 20, 13, 67, 56, 85, 192, 21, 0, 10, 81, 97, 103, 101, 32, 0, 11, 200, 72, 84, 18, 21, 52, 201, 60, 224, 20, 11, 200, 65, 35, 195, 21, 52, 201, 60, 224, 20, 11, 200, 64, 84, 141, 37, 52, 201, 60, 224, 20, 11, 200, 64, 84, 139, 85, 52, 201, 60, 224, 20, 11, 200, 44, 243, 131, 21, 52, 201, 60, 224, 20, 11, 200, 44, 243, 77, 37, 52, 201, 60, 224, 20, 11, 200, 64, 84, 141, 37, 52, 201, 60, 224, 20, 11, 200, 64, 83, 148, 4, 115, 206, 4, 192, 20, 11, 200, 32, 82, 211, 4, 115, 206, 4, 192, 20, 9, 198, 24, 244, 141, 36, 64, 66, 20, 0, 8, 197, 72, 80, 71, 21, 32, 20, 8, 197, 12, 131, 203, 21, 32, 20, 9, 198, 76, 210, 71, 72, 84, 137, 20, 9, 198, 76, 178, 68, 80, 84, 137, 20, 9, 198, 24, 163, 204, 48, 84, 137, 20, 8, 197, 8, 21, 88, 37, 64, 20, 8, 197, 16, 146, 212, 5, 64, 20, 0, 11, 67, 76, 52, 201, 89, 49, 114, 89, 37, 0, 9, 198, 21, 64, 77, 36, 225, 64, 20, 13, 202, 77, 80, 143, 72, 66, 78, 5, 66, 79, 56, 20, 9, 198, 88, 83, 79, 16, 145, 192, 20, 13, 202, 64, 83, 15, 64, 243, 142, 21, 50, 83, 44, 20, 9, 198, 33, 145, 18, 60, 98, 76, 20, 9, 198, 45, 35, 203, 4, 65, 64, 20, 0, 10, 199, 80, 19, 135, 21, 34, 78, 28, 20, 10, 199, 73, 82, 78, 21, 34, 78, 28, 20, 10, 199, 72, 19, 135, 21, 34, 78, 28, 20, 10, 199, 64, 192, 67, 21, 34, 78, 28, 20, 10, 199, 64, 21, 83, 21, 34, 78, 28, 20, 10, 199, 52, 20, 203, 21, 34, 78, 28, 20, 10, 199, 52, 20, 139, 21, 34, 78, 28, 20, 10, 199, 48, 243, 135, 21, 34, 78, 28, 20, 10, 199, 48, 147, 138, 21, 34, 78, 28, 20, 10, 199, 24, 244, 131, 21, 34, 78, 28, 20, 9, 198, 77, 83, 69, 72, 148, 203, 20, 9, 198, 52, 19, 1, 92, 148, 203, 20, 9, 198, 44, 19, 129, 72, 148, 203, 20, 9, 198, 16, 82, 75, 80, 148, 203, 20, 9, 198, 77, 147, 66, 60, 194, 75, 20, 10, 199, 72, 84, 201, 77, 65, 78, 76, 20, 0, 12, 201, 24, 20, 141, 4, 179, 199, 56, 244, 201, 20, 11, 200, 89, 83, 7, 5, 34, 83, 21, 32, 20, 11, 200, 77, 147, 148, 21, 66, 83, 21, 32, 20, 11, 200, 76, 82, 212, 61, 34, 83, 21, 32, 20, 11, 200, 72, 243, 65, 57, 66, 83, 21, 32, 20, 11, 200, 65, 83, 22, 21, 34, 83, 21, 32, 20, 11, 200, 65, 34, 86, 5, 66, 83, 21, 32, 20, 11, 200, 64, 84, 137, 60, 66, 83, 21, 32, 20, 11, 200, 64, 20, 211, 37, 98, 83, 21, 32, 20, 11, 200, 56, 85, 82, 61, 66, 83, 21, 32, 20, 11, 200, 48, 16, 137, 4, 194, 83, 21, 32, 20, 11, 200, 44, 19, 148, 60, 226, 83, 21, 32, 20, 11, 200, 36, 212, 18, 61, 98, 83, 21, 32, 20, 11, 200, 32, 84, 130, 5, 34, 83, 21, 32, 20, 11, 200, 28, 116, 149, 8, 194, 83, 21, 32, 20, 11, 200, 8, 20, 130, 5, 34, 83, 21, 32, 20, 9, 198, 52, 84, 203, 4, 194, 78, 20, 9, 198, 52, 19, 132, 60, 194, 78, 20, 9, 198, 32, 84, 141, 20, 194, 78, 20, 11, 200, 52, 81, 9, 44, 19, 69, 57, 64, 20, 11, 200, 36, 228, 212, 73, 83, 69, 57, 64, 20, 9, 198, 44, 20, 5, 48, 192, 78, 21, 21, 72, 56, 243, 131, 32, 19, 1, 57, 64, 50, 114, 50, 91, 13, 55, 6, 112, 68, 0, 20, 11, 3, 95, 54, 15, 89, 57, 109, 72, 108, 0, 0, 30, 69, 76, 80, 210, 21, 64, 89, 37, 81, 34, 36, 72, 15, 89, 6, 118, 84, 37, 89, 0, 81, 115, 101, 114, 118, 105, 99, 101, 32, 16, 70, 8, 17, 213, 21, 69, 5, 71, 2, 35, 6, 81, 36, 47, 0, 8, 197, 81, 84, 137, 77, 64, 20, 8, 197, 56, 22, 137, 77, 64, 20, 16, 205, 36, 228, 212, 37, 69, 84, 36, 243, 129, 48, 148, 197, 72, 20, 8, 197, 8, 195, 203, 21, 32, 20, 9, 198, 4, 195, 5, 28, 244, 137, 20, 12, 201, 45, 32, 77, 64, 80, 71, 80, 145, 192, 20, 8, 197, 104, 83, 204, 37, 64, 20, 16, 141, 7, 195, 165, 19, 5, 16, 15, 20, 5, 14, 20, 9, 12, 20, 8, 197, 64, 21, 5, 57, 64, 20, 12, 201, 45, 32, 77, 64, 80, 71, 80, 145, 192, 20, 8, 197, 60, 181, 1, 57, 64, 20, 8, 197, 4, 181, 1, 57, 64, 20, 10, 69, 80, 80, 83, 21, 32, 21, 0, 10, 0, 25, 70, 88, 148, 139, 20, 65, 64, 84, 6, 37, 34, 49, 36, 86, 13, 15, 89, 114, 0, 81, 115, 195, 165, 32, 13, 202, 88, 148, 213, 4, 194, 83, 21, 34, 78, 28, 20, 13, 202, 88, 19, 132, 4, 194, 83, 21, 34, 78, 28, 20, 13, 202, 80, 84, 146, 61, 34, 83, 21, 34, 78, 28, 20, 13, 202, 77, 147, 66, 60, 194, 83, 21, 34, 78, 28, 20, 13, 202, 76, 240, 201, 4, 194, 83, 21, 34, 78, 28, 20, 13, 202, 72, 149, 21, 4, 194, 83, 21, 34, 78, 28, 20, 13, 202, 64, 21, 18, 60, 226, 83, 21, 34, 78, 28, 20, 13, 202, 56, 244, 141, 4, 194, 83, 21, 34, 78, 28, 20, 13, 202, 53, 84, 197, 4, 194, 83, 21, 34, 78, 28, 20, 13, 202, 36, 229, 5, 57, 50, 86, 21, 34, 78, 28, 20, 13, 202, 24, 244, 141, 4, 194, 83, 21, 34, 78, 28, 20, 13, 202, 24, 84, 148, 36, 194, 83, 21, 34, 78, 28, 20, 13, 202, 16, 85, 18, 60, 226, 83, 21, 34, 78, 28, 20, 13, 202, 9, 37, 84, 4, 194, 83, 21, 34, 78, 28, 20, 13, 202, 4, 181, 21, 4, 194, 83, 21, 34, 78, 28, 20, 13, 202, 4, 68, 212, 72, 147, 135, 21, 34, 78, 28, 20, 9, 198, 45, 34, 77, 36, 224, 76, 20, 9, 198, 29, 81, 5, 48, 145, 192, 20, 12, 201, 76, 21, 68, 36, 20, 129, 8, 148, 203, 20, 12, 201, 65, 35, 194, 48, 83, 65, 80, 148, 203, 20, 12, 201, 52, 147, 133, 72, 19, 15, 28, 148, 203, 20, 12, 201, 45, 33, 77, 48, 243, 15, 28, 148, 203, 20, 12, 201, 44, 148, 143, 65, 32, 75, 80, 148, 203, 20, 12, 201, 44, 20, 148, 60, 116, 129, 24, 148, 203, 20, 0, 10, 199, 77, 2, 82, 37, 66, 83, 80, 20, 10, 199, 76, 82, 212, 21, 34, 83, 80, 20, 10, 199, 65, 34, 86, 5, 66, 83, 80, 20, 10, 199, 53, 149, 20, 21, 34, 83, 80, 20, 10, 199, 52, 19, 137, 21, 34, 83, 80, 20, 10, 199, 44, 243, 131, 37, 2, 83, 80, 20, 14, 203, 48, 21, 144, 5, 53, 5, 85, 34, 83, 21, 32, 20, 14, 203, 9, 84, 133, 5, 82, 210, 5, 66, 83, 21, 32, 20, 13, 138, 16, 195, 165, 20, 1, 7, 5, 12, 9, 7, 20, 13, 138, 15, 13, 2, 195, 184, 10, 5, 12, 9, 7, 20, 9, 198, 76, 243, 65, 80, 148, 203, 20, 9, 198, 76, 84, 129, 24, 148, 203, 20, 9, 198, 16, 144, 84, 60, 226, 75, 20, 0, 11, 200, 76, 83, 73, 56, 20, 137, 77, 64, 20, 11, 200, 52, 243, 133, 80, 20, 137, 77, 64, 20, 11, 200, 80, 82, 206, 36, 98, 67, 21, 32, 20, 11, 200, 52, 85, 18, 61, 3, 204, 37, 64, 20, 11, 200, 44, 244, 205, 61, 3, 204, 37, 64, 20, 7, 196, 28, 245, 9, 44, 20, 11, 200, 44, 243, 148, 36, 225, 197, 57, 64, 20, 11, 200, 44, 243, 147, 37, 53, 5, 57, 64, 20, 9, 198, 24, 147, 20, 72, 21, 0, 20, 7, 196, 88, 20, 129, 56, 21, 11, 200, 65, 35, 212, 21, 53, 1, 57, 64, 20, 9, 68, 9, 35, 206, 96, 21, 0, 10, 0, 8, 197, 4, 224, 76, 60, 112, 20, 8, 197, 52, 20, 137, 56, 80, 20, 16, 205, 44, 243, 77, 21, 32, 201, 4, 194, 83, 21, 34, 78, 28, 20, 16, 205, 36, 225, 9, 88, 145, 21, 4, 194, 83, 21, 34, 78, 28, 20, 12, 201, 76, 176, 82, 65, 50, 78, 16, 145, 192, 20, 12, 201, 61, 97, 82, 76, 181, 69, 48, 145, 192, 20, 12, 201, 60, 213, 22, 37, 53, 5, 48, 145, 192, 20, 12, 201, 56, 81, 2, 73, 145, 5, 48, 145, 192, 20, 12, 201, 24, 244, 148, 73, 145, 5, 48, 145, 192, 20, 12, 201, 24, 244, 148, 60, 194, 197, 48, 145, 192, 20, 12, 201, 24, 244, 147, 45, 145, 5, 48, 145, 192, 20, 12, 201, 24, 244, 141, 5, 53, 5, 48, 145, 192, 20, 15, 140, 6, 15, 18, 4, 195, 166, 18, 22, 5, 12, 9, 7, 20, 15, 204, 45, 38, 83, 80, 19, 12, 60, 116, 129, 24, 148, 203, 20, 9, 198, 44, 243, 139, 100, 194, 69, 20, 9, 198, 44, 243, 147, 36, 194, 69, 20, 8, 197, 44, 194, 78, 36, 176, 20, 8, 197, 52, 83, 129, 28, 80, 20, 0, 6, 195, 20, 212, 0, 17, 6, 195, 72, 81, 201, 20, 9, 198, 72, 246, 65, 48, 148, 212, 20, 9, 198, 64, 244, 21, 48, 148, 212, 20, 9, 198, 48, 246, 65, 48, 148, 212, 20, 13, 202, 44, 243, 77, 84, 226, 84, 5, 34, 83, 80, 20, 9, 198, 8, 145, 193, 52, 148, 212, 20, 9, 198, 4, 224, 82, 44, 148, 212, 20, 16, 141, 195, 184, 10, 5, 2, 12, 9, 11, 11, 5, 12, 9, 7, 20, 12, 137, 195, 166, 18, 2, 195, 184, 4, 9, 7, 20, 16, 141, 8, 195, 165, 14, 4, 7, 18, 9, 2, 5, 12, 9, 7, 20, 12, 201, 77, 147, 148, 4, 115, 65, 80, 148, 203, 20, 12, 201, 77, 147, 80, 80, 243, 65, 80, 148, 203, 20, 12, 201, 64, 19, 139, 72, 243, 65, 80, 148, 203, 20, 12, 201, 45, 96, 68, 72, 241, 143, 56, 148, 203, 20, 12, 201, 44, 19, 12, 36, 116, 129, 24, 148, 203, 20, 12, 201, 36, 179, 206, 60, 116, 129, 24, 148, 203, 20, 12, 201, 25, 32, 83, 20, 243, 15, 28, 148, 203, 20, 12, 201, 16, 148, 203, 60, 116, 129, 24, 148, 203, 20, 9, 198, 5, 36, 197, 56, 146, 192, 20, 0, 10, 199, 4, 194, 214, 4, 229, 15, 72, 20, 9, 198, 48, 149, 147, 4, 194, 71, 20, 10, 199, 52, 21, 5, 52, 21, 9, 44, 20, 10, 199, 5, 34, 84, 52, 85, 9, 44, 20, 12, 201, 20, 50, 1, 84, 97, 133, 72, 85, 0, 20, 0, 28, 68, 88, 244, 133, 76, 84, 114, 12, 89, 15, 49, 84, 112, 6, 47, 36, 34, 0, 81, 107, 118, 97, 114, 116, 101, 114, 32, 9, 198, 72, 83, 5, 28, 147, 206, 20, 9, 198, 53, 85, 1, 80, 147, 206, 20, 11, 200, 24, 147, 20, 72, 84, 137, 56, 112, 20, 11, 200, 80, 83, 5, 24, 243, 133, 72, 80, 20, 11, 200, 52, 17, 193, 76, 147, 133, 72, 80, 20, 14, 139, 16, 195, 165, 16, 1, 19, 19, 5, 12, 9, 7, 20, 14, 139, 6, 15, 18, 14, 195, 184, 10, 5, 12, 9, 7, 20, 11, 200, 21, 2, 71, 72, 17, 137, 76, 176, 20, 11, 200, 64, 20, 148, 36, 50, 80, 36, 80, 20, 9, 198, 37, 51, 1, 52, 149, 0, 20, 9, 198, 12, 240, 203, 64, 149, 0, 20, 7, 196, 44, 149, 9, 56, 20, 9, 198, 52, 147, 12, 36, 32, 82, 20, 9, 198, 17, 35, 205, 20, 64, 82, 20, 13, 68, 32, 21, 132, 20, 107, 110, 12, 86, 13, 0, 76, 7, 196, 88, 244, 133, 76, 72, 11, 3, 95, 55, 15, 89, 116, 84, 50, 108, 0, 0, 8, 197, 56, 81, 197, 72, 80, 20, 15, 140, 7, 5, 2, 18, 195, 166, 11, 11, 5, 12, 9, 7, 20, 15, 140, 1, 6, 7, 18, 195, 166, 14, 19, 5, 12, 9, 7, 20, 8, 197, 64, 243, 9, 80, 144, 20, 0, 9, 198, 52, 82, 133, 72, 148, 212, 20, 9, 198, 33, 83, 65, 56, 148, 212, 20, 9, 198, 4, 196, 9, 56, 148, 212, 20, 9, 198, 45, 34, 77, 36, 225, 76, 20, 16, 141, 195, 166, 7, 20, 5, 19, 11, 1, 2, 5, 12, 9, 7, 20, 9, 198, 4, 225, 197, 48, 146, 192, 20, 9, 198, 44, 243, 147, 84, 192, 84, 20, 9, 198, 25, 32, 75, 80, 19, 0, 20, 0, 10, 199, 76, 84, 1, 72, 21, 15, 72, 20, 12, 201, 65, 35, 204, 60, 225, 193, 80, 147, 206, 20, 12, 201, 64, 84, 148, 85, 32, 129, 80, 147, 206, 20, 12, 201, 52, 20, 212, 85, 32, 129, 80, 147, 206, 20, 12, 201, 24, 84, 141, 20, 229, 1, 80, 147, 206, 20, 14, 203, 77, 68, 129, 80, 145, 137, 12, 84, 137, 56, 112, 20, 0, 9, 198, 72, 80, 75, 80, 147, 206, 20, 9, 198, 36, 229, 129, 76, 147, 206, 20, 11, 200, 81, 148, 9, 76, 84, 137, 56, 112, 20, 11, 200, 81, 37, 78, 44, 84, 137, 56, 112, 20, 11, 200, 81, 32, 75, 80, 84, 137, 56, 112, 20, 11, 200, 77, 64, 71, 56, 84, 137, 56, 112, 20, 11, 200, 65, 83, 139, 80, 84, 137, 56, 112, 20, 11, 200, 61, 33, 9, 56, 84, 137, 56, 112, 20, 11, 200, 60, 178, 213, 64, 84, 137, 56, 112, 20, 11, 200, 57, 80, 78, 12, 84, 137, 56, 112, 20, 11, 200, 45, 96, 68, 72, 84, 137, 56, 112, 20, 11, 200, 44, 20, 212, 72, 84, 137, 56, 112, 20, 11, 200, 36, 243, 137, 76, 84, 137, 56, 112, 20, 11, 200, 29, 83, 77, 36, 84, 137, 56, 112, 20, 11, 200, 29, 37, 78, 16, 84, 137, 56, 112, 20, 11, 200, 21, 64, 66, 48, 84, 137, 56, 112, 20, 11, 200, 20, 225, 193, 28, 84, 137, 56, 112, 20, 11, 200, 20, 213, 76, 28, 84, 137, 56, 112, 20, 11, 200, 16, 82, 213, 64, 84, 137, 56, 112, 20, 11, 200, 12, 130, 70, 72, 84, 137, 56, 112, 20, 11, 200, 5, 97, 82, 80, 84, 137, 56, 112, 20, 11, 200, 4, 227, 143, 80, 84, 137, 56, 112, 20, 11, 200, 72, 82, 210, 85, 69, 5, 72, 80, 20, 11, 200, 36, 229, 129, 48, 145, 5, 72, 80, 20, 11, 200, 52, 241, 2, 100, 65, 76, 36, 112, 20, 11, 200, 44, 20, 18, 36, 99, 204, 36, 80, 20, 11, 200, 44, 20, 18, 36, 99, 204, 36, 80, 20, 11, 200, 64, 243, 25, 80, 82, 206, 36, 176, 20, 7, 196, 64, 148, 129, 80, 20, 7, 196, 44, 20, 129, 80, 20, 9, 198, 24, 244, 141, 84, 192, 82, 20, 0, 0, 9, 198, 44, 243, 150, 60, 197, 84, 20, 13, 202, 72, 82, 207, 57, 96, 76, 21, 48, 197, 72, 20, 12, 201, 24, 244, 149, 17, 50, 71, 20, 194, 71, 20, 9, 198, 44, 243, 77, 84, 224, 76, 20, 0, 14, 203, 88, 149, 1, 52, 147, 137, 76, 84, 137, 56, 112, 20, 10, 199, 88, 21, 20, 21, 34, 78, 28, 20, 14, 203, 81, 32, 78, 77, 3, 210, 80, 84, 137, 56, 112, 20, 14, 203, 81, 32, 78, 76, 99, 210, 52, 84, 137, 56, 112, 20, 14, 203, 77, 147, 139, 72, 243, 137, 76, 84, 137, 56, 112, 20, 14, 203, 77, 65, 82, 20, 245, 25, 64, 84, 137, 56, 112, 20, 14, 203, 72, 82, 207, 57, 53, 18, 84, 84, 137, 56, 112, 20, 10, 199, 64, 244, 212, 21, 34, 78, 28, 20, 14, 203, 44, 243, 132, 37, 66, 79, 56, 84, 137, 56, 112, 20, 14, 203, 44, 192, 83, 76, 145, 137, 12, 84, 137, 56, 112, 20, 10, 199, 29, 32, 68, 21, 34, 78, 28, 20, 14, 203, 28, 192, 77, 61, 84, 137, 76, 84, 137, 56, 112, 20, 10, 199, 25, 34, 84, 21, 34, 78, 28, 20, 10, 199, 20, 195, 216, 21, 34, 78, 28, 20, 14, 203, 16, 84, 201, 56, 99, 210, 52, 84, 137, 56, 112, 20, 14, 203, 5, 85, 15, 56, 243, 73, 76, 84, 137, 56, 112, 20, 14, 203, 76, 19, 77, 20, 227, 9, 28, 225, 76, 36, 112, 20, 9, 198, 48, 149, 15, 80, 148, 203, 20, 9, 198, 44, 19, 143, 56, 148, 203, 20, 9, 198, 20, 225, 82, 28, 148, 203, 20, 9, 198, 4, 209, 137, 8, 148, 203, 20, 10, 199, 56, 84, 20, 84, 226, 85, 52, 20, 10, 199, 52, 20, 148, 101, 34, 85, 52, 20, 10, 199, 48, 83, 137, 56, 148, 205, 20, 20, 10, 199, 52, 84, 139, 4, 229, 9, 48, 20, 9, 198, 77, 1, 67, 36, 98, 75, 20, 10, 199, 5, 96, 78, 12, 84, 133, 80, 20, 10, 199, 44, 243, 134, 21, 33, 78, 76, 20, 10, 199, 64, 197, 84, 60, 180, 129, 80, 20, 0, 7, 196, 52, 245, 5, 48, 20, 9, 198, 44, 243, 132, 60, 193, 82, 20, 9, 198, 32, 20, 131, 20, 193, 82, 20, 9, 198, 12, 148, 139, 84, 193, 82, 20, 7, 196, 72, 20, 9, 16, 20, 7, 196, 64, 20, 9, 48, 20, 0, 9, 198, 45, 84, 148, 60, 148, 201, 20, 0, 25, 66, 20, 224, 36, 50, 15, 49, 110, 50, 39, 50, 6, 36, 34, 0, 81, 107, 97, 110, 111, 110, 101, 114, 32, 16, 66, 20, 224, 36, 50, 15, 89, 6, 114, 0, 81, 115, 195, 165, 32, 25, 66, 20, 224, 36, 50, 15, 55, 36, 81, 6, 109, 50, 72, 13, 0, 81, 108, 101, 103, 101, 110, 100, 101, 32, 23, 66, 20, 224, 112, 68, 15, 48, 110, 89, 6, 112, 68, 0, 81, 112, 97, 115, 115, 97, 110, 116, 32, 19, 66, 20, 224, 35, 68, 15, 6, 71, 55, 114, 49, 0, 81, 98, 108, 111, 99, 32, 18, 66, 20, 224, 35, 68, 15, 83, 6, 35, 89, 0, 81, 102, 97, 99, 101, 32, 9, 198, 44, 244, 147, 20, 193, 84, 20, 13, 202, 81, 34, 65, 56, 117, 76, 21, 34, 78, 28, 20, 13, 202, 77, 80, 147, 80, 149, 21, 21, 34, 78, 28, 20, 13, 202, 77, 68, 129, 56, 117, 76, 21, 34, 78, 28, 20, 13, 202, 72, 80, 201, 72, 181, 76, 21, 34, 78, 28, 20, 13, 202, 65, 35, 211, 64, 82, 212, 21, 34, 78, 28, 20, 13, 202, 64, 20, 148, 36, 50, 80, 21, 34, 78, 28, 20, 13, 202, 44, 243, 147, 80, 149, 21, 21, 34, 78, 28, 20, 13, 202, 44, 243, 80, 48, 85, 20, 21, 34, 78, 28, 20, 12, 201, 80, 84, 141, 60, 116, 129, 24, 148, 203, 20, 12, 201, 52, 85, 15, 16, 243, 15, 28, 148, 203, 20, 12, 201, 45, 34, 83, 80, 243, 15, 28, 148, 203, 20, 12, 201, 44, 244, 133, 60, 116, 129, 24, 148, 203, 20, 12, 201, 32, 82, 211, 4, 209, 84, 72, 148, 203, 20, 12, 201, 24, 20, 141, 4, 49, 85, 80, 148, 203, 20, 12, 201, 20, 229, 21, 76, 144, 83, 80, 148, 203, 20, 12, 201, 20, 229, 15, 52, 243, 15, 28, 148, 203, 20, 5, 194, 20, 224, 72, 0, 10, 199, 64, 146, 212, 60, 116, 129, 52, 20, 9, 198, 88, 83, 133, 72, 148, 203, 20, 9, 198, 76, 243, 65, 48, 148, 203, 20, 9, 198, 64, 83, 1, 28, 148, 203, 20, 9, 198, 57, 83, 69, 72, 148, 203, 20, 9, 198, 32, 19, 73, 80, 148, 203, 20, 9, 198, 4, 181, 83, 80, 148, 203, 20, 10, 199, 36, 225, 149, 76, 244, 137, 20, 20, 10, 199, 28, 84, 141, 4, 226, 85, 52, 20, 10, 199, 21, 2, 83, 44, 244, 1, 80, 20, 13, 3, 95, 51, 88, 47, 51, 6, 111, 86, 84, 13, 0, 0, 7, 196, 8, 20, 143, 56, 20, 9, 198, 72, 84, 207, 72, 33, 82, 20, 9, 198, 72, 19, 80, 60, 225, 82, 20, 9, 198, 61, 48, 201, 48, 193, 82, 20, 7, 196, 52, 245, 133, 72, 20, 9, 198, 44, 243, 80, 60, 225, 82, 20, 9, 198, 24, 244, 141, 84, 193, 82, 20, 9, 198, 5, 69, 1, 12, 129, 82, 20, 9, 198, 4, 227, 149, 48, 193, 82, 20, 11, 200, 44, 243, 148, 36, 225, 197, 57, 48, 20, 11, 200, 44, 243, 147, 37, 53, 5, 57, 48, 20, 14, 3, 95, 48, 67, 107, 6, 40, 50, 16, 13, 12, 86, 0, 0, 0, 12, 201, 80, 84, 141, 61, 53, 1, 80, 148, 203, 20, 12, 201, 77, 65, 78, 60, 116, 129, 24, 148, 203, 20, 12, 201, 25, 85, 21, 72, 243, 15, 28, 148, 203, 20, 12, 201, 21, 50, 201, 52, 243, 15, 28, 148, 203, 20, 12, 201, 16, 83, 132, 72, 243, 15, 28, 148, 203, 20, 0, 10, 199, 52, 20, 135, 5, 34, 78, 20, 20, 10, 199, 44, 243, 134, 85, 50, 79, 56, 20, 10, 199, 36, 211, 73, 77, 50, 79, 56, 20, 12, 201, 81, 32, 78, 77, 50, 210, 36, 33, 82, 20, 10, 199, 44, 243, 77, 20, 229, 5, 72, 20, 10, 199, 16, 148, 208, 21, 33, 197, 72, 20, 12, 201, 16, 83, 79, 57, 53, 18, 4, 229, 0, 20, 8, 67, 81, 34, 80, 21, 0, 10, 0, 11, 200, 72, 81, 140, 20, 180, 201, 60, 224, 20, 11, 200, 64, 84, 150, 21, 36, 201, 60, 224, 20, 11, 200, 44, 243, 150, 21, 36, 201, 60, 224, 20, 11, 200, 5, 37, 9, 24, 144, 201, 20, 192, 20, 7, 196, 88, 245, 5, 72, 20, 7, 196, 12, 149, 5, 72, 20, 9, 198, 16, 83, 79, 29, 32, 70, 20, 9, 198, 52, 244, 132, 20, 229, 0, 20, 7, 196, 80, 149, 1, 56, 21, 7, 196, 68, 21, 1, 72, 20, 7, 196, 44, 21, 1, 72, 20, 9, 198, 44, 243, 80, 5, 32, 66, 20, 11, 3, 95, 57, 15, 50, 37, 13, 50, 108, 0, 0, 15, 140, 16, 1, 12, 195, 166, 15, 14, 20, 15, 12, 15, 7, 20, 13, 138, 16, 18, 195, 166, 19, 20, 9, 14, 4, 5, 20, 0, 16, 141, 1, 14, 195, 166, 19, 20, 5, 19, 9, 15, 12, 15, 7, 20, 13, 202, 72, 85, 18, 60, 99, 5, 45, 50, 79, 56, 20, 0, 10, 199, 65, 35, 211, 20, 181, 15, 72, 20, 10, 199, 76, 82, 210, 21, 66, 79, 56, 20, 12, 201, 44, 243, 132, 20, 228, 193, 80, 147, 206, 20, 12, 201, 44, 243, 80, 20, 228, 193, 80, 147, 206, 20, 12, 201, 36, 195, 21, 77, 68, 129, 80, 147, 206, 20, 10, 199, 25, 83, 132, 5, 66, 79, 56, 20, 12, 201, 16, 148, 208, 20, 228, 193, 80, 147, 206, 20, 10, 199, 16, 147, 206, 101, 50, 83, 44, 20, 10, 199, 61, 37, 15, 16, 243, 148, 36, 20, 10, 199, 5, 36, 133, 77, 64, 78, 80, 20, 0, 12, 67, 77, 65, 71, 89, 72, 35, 57, 0, 14, 45, 11, 200, 65, 34, 78, 12, 148, 9, 20, 192, 20, 7, 196, 64, 148, 143, 48, 20, 12, 137, 22, 195, 166, 18, 20, 9, 14, 4, 5, 20, 9, 198, 24, 245, 15, 29, 32, 70, 20, 9, 198, 21, 67, 143, 29, 32, 70, 20, 11, 200, 52, 81, 9, 80, 84, 146, 4, 224, 21, 17, 3, 95, 49, 67, 36, 72, 15, 107, 6, 40, 50, 51, 13, 12, 86, 0, 0, 8, 197, 44, 243, 132, 61, 32, 20, 8, 197, 64, 192, 67, 21, 32, 20, 8, 197, 24, 244, 131, 21, 32, 20, 12, 137, 16, 195, 184, 14, 9, 20, 5, 14, 20, 20, 0, 9, 198, 29, 32, 86, 85, 33, 64, 20, 9, 198, 80, 19, 10, 21, 33, 64, 20, 9, 198, 24, 245, 82, 4, 113, 64, 20, 0, 10, 67, 81, 33, 64, 47, 34, 6, 36, 0, 10, 199, 64, 19, 9, 56, 68, 143, 52, 20, 10, 199, 16, 85, 137, 21, 34, 78, 28, 20, 10, 199, 64, 85, 9, 80, 84, 211, 20, 20, 0, 11, 200, 88, 148, 213, 4, 194, 83, 21, 32, 20, 11, 200, 88, 19, 132, 4, 194, 83, 21, 32, 20, 11, 200, 80, 84, 146, 61, 34, 83, 21, 32, 20, 11, 200, 77, 147, 66, 60, 194, 83, 21, 32, 20, 11, 200, 76, 240, 201, 4, 194, 83, 21, 32, 20, 11, 200, 72, 149, 21, 4, 194, 83, 21, 32, 20, 11, 200, 64, 21, 18, 60, 226, 83, 21, 32, 20, 11, 200, 56, 244, 141, 4, 194, 83, 21, 32, 20, 11, 200, 33, 145, 18, 60, 198, 83, 21, 32, 20, 11, 200, 24, 244, 141, 4, 194, 83, 21, 32, 20, 11, 200, 24, 84, 148, 36, 194, 83, 21, 32, 20, 11, 200, 16, 85, 18, 60, 226, 83, 21, 32, 20, 11, 200, 9, 37, 84, 4, 194, 83, 21, 32, 20, 11, 200, 4, 181, 21, 4, 194, 83, 21, 32, 20, 11, 200, 4, 178, 214, 36, 84, 195, 21, 32, 20, 9, 198, 49, 85, 8, 21, 32, 78, 20, 11, 200, 36, 224, 201, 80, 19, 69, 57, 64, 20, 0, 8, 197, 88, 84, 147, 21, 32, 20, 12, 201, 80, 83, 5, 29, 32, 70, 21, 33, 64, 20, 12, 201, 24, 245, 15, 29, 32, 70, 21, 33, 64, 20, 8, 197, 24, 20, 147, 21, 32, 20, 12, 201, 5, 85, 15, 29, 32, 70, 21, 33, 64, 20, 8, 197, 21, 33, 77, 37, 64, 20, 8, 197, 52, 17, 217, 5, 32, 20, 9, 198, 52, 20, 137, 56, 17, 5, 20, 0, 17, 70, 52, 150, 20, 85, 33, 64, 65, 36, 81, 89, 47, 57, 114, 0, 20, 9, 198, 25, 34, 84, 85, 33, 64, 20, 9, 198, 77, 69, 68, 21, 33, 64, 20, 9, 198, 29, 32, 68, 21, 33, 64, 20, 12, 137, 15, 16, 19, 195, 166, 20, 19, 9, 7, 20, 18, 143, 11, 1, 18, 18, 5, 2, 195, 166, 11, 19, 13, 9, 14, 4, 5, 20, 12, 3, 95, 49, 57, 50, 6, 36, 72, 14, 50, 0, 0, 10, 199, 76, 243, 4, 21, 34, 83, 80, 20, 10, 199, 32, 148, 212, 61, 34, 83, 80, 20, 10, 199, 24, 17, 207, 81, 66, 83, 80, 20, 14, 203, 44, 243, 77, 21, 32, 201, 4, 194, 83, 21, 32, 20, 14, 203, 36, 225, 9, 88, 145, 21, 4, 194, 83, 21, 32, 20, 16, 75, 84, 225, 5, 73, 53, 1, 80, 83, 69, 57, 64, 21, 0, 10, 11, 3, 95, 49, 56, 6, 110, 72, 14, 50, 0, 0, 10, 68, 28, 149, 133, 72, 81, 37, 34, 0, 11, 68, 20, 229, 5, 72, 36, 50, 47, 114, 0, 11, 200, 77, 1, 67, 36, 98, 67, 21, 32, 20, 11, 200, 73, 84, 211, 36, 98, 67, 21, 32, 20, 11, 200, 72, 83, 66, 61, 84, 147, 21, 32, 20, 11, 200, 44, 192, 82, 36, 98, 67, 21, 32, 20, 7, 196, 44, 21, 133, 72, 20, 11, 200, 36, 229, 5, 72, 84, 211, 21, 32, 20, 11, 200, 28, 195, 210, 36, 98, 67, 21, 32, 20, 7, 196, 28, 84, 133, 72, 20, 11, 200, 24, 19, 19, 36, 98, 67, 21, 32, 20, 11, 200, 16, 84, 201, 56, 98, 67, 21, 32, 20, 7, 196, 40, 21, 129, 56, 20, 9, 198, 61, 53, 9, 56, 21, 0, 20, 12, 201, 44, 243, 148, 4, 181, 6, 48, 17, 5, 20, 0, 8, 197, 45, 84, 201, 56, 80, 20, 12, 201, 80, 20, 5, 81, 49, 82, 36, 225, 192, 20, 12, 201, 72, 85, 133, 73, 49, 82, 36, 225, 192, 20, 12, 201, 72, 85, 129, 49, 81, 82, 36, 225, 192, 20, 12, 201, 72, 80, 76, 37, 49, 82, 36, 225, 192, 20, 12, 201, 24, 19, 148, 5, 49, 82, 36, 225, 192, 20, 12, 201, 21, 35, 212, 37, 49, 82, 36, 225, 192, 20, 12, 201, 20, 225, 15, 77, 49, 82, 36, 225, 192, 20, 12, 201, 16, 84, 12, 61, 145, 82, 36, 225, 192, 20, 12, 201, 4, 225, 204, 37, 49, 82, 36, 225, 192, 20, 12, 201, 4, 68, 133, 77, 49, 82, 36, 225, 192, 20, 9, 198, 45, 34, 84, 21, 34, 69, 20, 9, 198, 44, 243, 131, 36, 194, 69, 20, 0, 9, 198, 48, 147, 135, 88, 148, 212, 20, 9, 198, 76, 176, 66, 21, 34, 64, 20, 9, 198, 17, 34, 86, 21, 34, 64, 20, 9, 198, 52, 147, 143, 37, 50, 192, 20, 9, 198, 17, 37, 83, 37, 50, 192, 20, 9, 198, 81, 34, 86, 36, 19, 0, 20, 0, 10, 199, 72, 85, 15, 73, 50, 79, 56, 20, 10, 199, 16, 147, 69, 57, 50, 79, 56, 20, 10, 199, 72, 83, 66, 85, 36, 197, 72, 20, 10, 199, 72, 83, 1, 80, 149, 133, 72, 20, 10, 199, 20, 180, 212, 20, 225, 5, 72, 20, 10, 199, 16, 80, 197, 48, 84, 133, 72, 20, 9, 198, 61, 4, 137, 29, 66, 71, 20, 10, 199, 24, 244, 148, 72, 243, 9, 28, 20, 10, 199, 4, 100, 203, 100, 83, 9, 28, 20, 14, 203, 44, 20, 148, 4, 114, 78, 36, 83, 147, 21, 32, 20, 12, 201, 76, 82, 210, 21, 64, 82, 36, 21, 0, 20, 12, 201, 4, 229, 9, 45, 96, 82, 36, 21, 0, 20, 0, 21, 72, 72, 82, 137, 12, 84, 137, 56, 112, 34, 36, 57, 37, 89, 6, 36, 51, 37, 68, 0, 12, 201, 77, 1, 75, 81, 35, 211, 44, 244, 0, 20, 10, 135, 13, 1, 6, 9, 195, 184, 19, 20, 11, 200, 40, 84, 137, 44, 244, 143, 76, 80, 20, 11, 200, 25, 85, 21, 72, 243, 15, 28, 144, 20, 11, 200, 21, 50, 201, 52, 243, 15, 28, 144, 20, 11, 200, 16, 83, 132, 72, 243, 15, 28, 144, 20, 9, 198, 64, 19, 70, 48, 85, 0, 20, 11, 200, 8, 83, 133, 24, 144, 201, 84, 208, 67, 15, 204, 77, 148, 212, 20, 208, 84, 37, 49, 82, 36, 225, 192, 20, 11, 200, 77, 81, 134, 48, 84, 137, 56, 112, 20, 15, 204, 77, 64, 78, 16, 20, 132, 37, 49, 82, 36, 225, 192, 20, 11, 200, 76, 178, 84, 76, 84, 137, 56, 112, 20, 11, 200, 76, 84, 1, 72, 84, 137, 56, 112, 20, 15, 204, 76, 83, 147, 36, 34, 76, 37, 49, 82, 36, 225, 192, 20, 11, 200, 72, 82, 137, 12, 84, 137, 56, 112, 20, 11, 200, 64, 147, 15, 80, 84, 137, 56, 112, 20, 15, 204, 52, 21, 5, 72, 144, 76, 37, 49, 82, 36, 225, 192, 20, 11, 200, 52, 20, 137, 56, 84, 137, 56, 112, 20, 11, 200, 44, 243, 15, 72, 84, 137, 56, 112, 20, 11, 200, 44, 195, 193, 44, 84, 137, 56, 112, 20, 11, 200, 28, 20, 129, 28, 84, 137, 56, 112, 20, 11, 200, 24, 145, 213, 72, 84, 137, 56, 112, 20, 11, 200, 16, 19, 137, 76, 84, 137, 56, 112, 20, 15, 204, 8, 17, 193, 80, 83, 12, 37, 49, 82, 36, 225, 192, 20, 11, 200, 5, 52, 213, 72, 84, 137, 56, 112, 20, 7, 196, 16, 21, 5, 72, 20, 7, 196, 33, 99, 210, 36, 20, 11, 200, 64, 84, 148, 20, 229, 12, 36, 112, 20, 11, 200, 61, 3, 21, 44, 177, 76, 36, 112, 20, 11, 200, 60, 210, 25, 28, 113, 76, 36, 112, 20, 11, 200, 28, 83, 148, 4, 113, 76, 36, 112, 20, 11, 200, 24, 244, 148, 72, 147, 140, 36, 112, 20, 11, 200, 24, 244, 140, 36, 113, 76, 36, 112, 20, 11, 200, 81, 48, 82, 37, 53, 9, 76, 176, 20, 11, 200, 56, 244, 212, 4, 193, 201, 76, 176, 20, 11, 200, 37, 51, 205, 21, 68, 137, 76, 176, 20, 11, 200, 28, 83, 205, 21, 68, 137, 76, 176, 20, 11, 200, 8, 243, 66, 5, 53, 9, 76, 176, 20, 11, 200, 60, 229, 15, 28, 83, 133, 76, 80, 20, 11, 200, 8, 83, 133, 24, 144, 201, 84, 208, 20, 11, 200, 84, 226, 84, 5, 34, 83, 52, 80, 20, 11, 200, 64, 197, 82, 4, 194, 83, 52, 80, 20, 11, 200, 52, 17, 206, 21, 66, 83, 52, 80, 20, 11, 200, 33, 148, 14, 61, 66, 83, 52, 80, 20, 11, 200, 12, 19, 22, 36, 226, 83, 52, 80, 20, 0, 11, 136, 7, 12, 15, 18, 9, 195, 184, 19, 20, 12, 201, 76, 83, 147, 5, 66, 79, 56, 83, 0, 20, 12, 201, 80, 21, 84, 60, 195, 199, 37, 50, 192, 20, 12, 201, 76, 240, 201, 60, 195, 199, 37, 50, 192, 20, 12, 201, 76, 83, 73, 60, 195, 199, 37, 50, 192, 20, 12, 201, 65, 54, 75, 60, 195, 199, 37, 50, 192, 20, 12, 201, 64, 244, 148, 84, 114, 83, 37, 50, 192, 20, 12, 201, 33, 145, 18, 60, 195, 199, 37, 50, 192, 20, 12, 201, 28, 83, 133, 4, 195, 199, 37, 50, 192, 20, 12, 201, 25, 148, 201, 60, 195, 199, 37, 50, 192, 20, 12, 201, 21, 70, 77, 60, 195, 199, 37, 50, 192, 20, 0, 9, 198, 80, 83, 143, 72, 148, 212, 20, 9, 198, 28, 83, 210, 28, 148, 212, 20, 9, 198, 76, 243, 4, 21, 34, 64, 20, 9, 198, 65, 32, 76, 21, 34, 64, 20, 9, 198, 64, 147, 80, 21, 34, 64, 20, 9, 198, 64, 147, 12, 21, 34, 64, 20, 9, 198, 64, 19, 80, 21, 34, 64, 20, 9, 198, 52, 19, 20, 21, 34, 64, 20, 9, 198, 48, 245, 20, 21, 34, 64, 20, 9, 198, 33, 146, 204, 21, 34, 64, 20, 9, 198, 28, 19, 12, 21, 34, 64, 20, 9, 198, 9, 83, 20, 21, 34, 64, 20, 9, 198, 8, 21, 20, 21, 34, 64, 20, 9, 198, 5, 67, 205, 37, 50, 192, 20, 9, 198, 17, 147, 129, 52, 146, 192, 20, 9, 198, 16, 83, 79, 45, 32, 84, 20, 9, 198, 8, 148, 213, 48, 96, 84, 20, 9, 198, 8, 145, 78, 56, 19, 0, 20, 11, 3, 95, 49, 49, 6, 109, 55, 84, 13, 0, 0, 10, 199, 72, 81, 21, 45, 66, 79, 56, 20, 10, 199, 61, 1, 82, 5, 66, 79, 56, 20, 10, 199, 20, 208, 78, 5, 66, 79, 56, 20, 14, 203, 52, 18, 193, 16, 19, 73, 76, 84, 137, 56, 112, 20, 14, 203, 44, 195, 210, 60, 99, 210, 52, 84, 137, 56, 112, 20, 18, 207, 36, 229, 5, 48, 193, 75, 81, 80, 76, 37, 49, 82, 36, 225, 192, 20, 14, 203, 36, 225, 5, 45, 49, 82, 12, 84, 137, 56, 112, 20, 14, 203, 36, 212, 12, 20, 209, 78, 80, 84, 137, 56, 112, 20, 14, 203, 25, 32, 84, 21, 35, 137, 76, 84, 137, 56, 112, 20, 14, 203, 20, 180, 212, 72, 20, 15, 48, 84, 137, 56, 112, 20, 14, 203, 4, 194, 207, 32, 243, 9, 76, 84, 137, 56, 112, 20, 14, 203, 4, 67, 73, 56, 148, 212, 72, 84, 137, 56, 112, 20, 10, 199, 36, 229, 9, 52, 145, 5, 72, 20, 10, 199, 20, 180, 208, 48, 241, 5, 72, 20, 10, 199, 16, 83, 9, 44, 21, 5, 72, 20, 10, 199, 44, 243, 132, 37, 67, 210, 36, 20, 14, 203, 44, 20, 129, 45, 65, 82, 37, 53, 9, 76, 176, 20, 14, 203, 16, 83, 147, 37, 67, 205, 21, 68, 137, 76, 176, 20, 14, 203, 36, 225, 5, 80, 84, 141, 36, 226, 83, 52, 80, 20, 14, 203, 25, 83, 139, 80, 147, 206, 4, 194, 83, 52, 80, 20, 14, 203, 16, 242, 213, 52, 83, 148, 5, 34, 83, 52, 80, 20, 10, 199, 64, 19, 133, 29, 148, 137, 44, 20, 9, 3, 95, 49, 48, 47, 6, 37, 0, 0, 7, 196, 44, 19, 149, 80, 20, 11, 200, 36, 211, 85, 56, 243, 15, 28, 144, 20, 11, 200, 20, 118, 80, 80, 243, 15, 28, 144, 20, 11, 200, 60, 213, 18, 20, 229, 12, 36, 112, 20, 11, 200, 52, 241, 20, 4, 113, 76, 36, 112, 20, 11, 200, 40, 243, 70, 73, 81, 76, 36, 112, 20, 11, 200, 24, 244, 141, 20, 229, 12, 36, 112, 20, 11, 200, 24, 244, 129, 72, 113, 76, 36, 112, 20, 16, 141, 16, 1, 12, 195, 166, 15, 12, 9, 20, 9, 11, 21, 13, 20, 11, 200, 13, 144, 78, 44, 19, 9, 84, 208, 20, 7, 196, 48, 85, 137, 80, 20, 22, 72, 12, 19, 142, 20, 195, 15, 56, 144, 49, 110, 50, 13, 55, 6, 39, 12, 50, 37, 0, 20, 11, 200, 44, 244, 144, 84, 193, 78, 12, 80, 20, 7, 196, 76, 148, 129, 80, 20, 9, 68, 48, 85, 133, 48, 21, 0, 10, 13, 3, 95, 49, 51, 47, 51, 6, 111, 72, 14, 50, 0, 0, 12, 201, 76, 176, 78, 16, 147, 129, 88, 148, 212, 20, 12, 201, 28, 83, 146, 20, 208, 76, 21, 34, 64, 20, 12, 201, 4, 180, 207, 56, 243, 69, 81, 34, 64, 20, 12, 201, 80, 18, 211, 60, 227, 205, 37, 50, 192, 20, 12, 201, 65, 54, 75, 60, 177, 77, 37, 50, 192, 20, 12, 201, 64, 243, 25, 73, 149, 13, 37, 50, 192, 20, 12, 201, 29, 32, 70, 60, 227, 205, 37, 50, 192, 20, 12, 201, 16, 149, 25, 72, 19, 66, 37, 50, 192, 20, 12, 201, 5, 3, 204, 60, 113, 84, 37, 50, 192, 20, 12, 201, 8, 20, 137, 84, 212, 213, 48, 96, 84, 20, 10, 3, 95, 49, 50, 47, 6, 114, 55, 0, 0, 13, 202, 72, 85, 18, 61, 52, 5, 45, 66, 79, 56, 20, 13, 202, 64, 84, 147, 21, 97, 82, 5, 66, 79, 56, 20, 13, 202, 16, 85, 5, 72, 210, 78, 5, 66, 79, 56, 20, 17, 206, 61, 1, 82, 5, 66, 79, 56, 19, 9, 76, 84, 137, 56, 112, 20, 9, 198, 24, 19, 12, 21, 33, 84, 20, 9, 198, 20, 195, 216, 21, 33, 84, 20, 9, 198, 61, 34, 71, 36, 224, 76, 20, 9, 198, 12, 84, 133, 9, 32, 76, 20, 13, 3, 95, 49, 53, 83, 6, 36, 65, 47, 14, 50, 0, 0, 12, 137, 11, 1, 13, 195, 166, 12, 5, 15, 14, 20, 10, 199, 80, 149, 18, 21, 34, 78, 28, 20, 10, 199, 48, 149, 18, 21, 34, 78, 28, 20, 10, 199, 25, 34, 83, 21, 34, 78, 28, 20, 10, 199, 17, 32, 71, 21, 34, 78, 28, 20, 14, 203, 88, 81, 5, 73, 53, 25, 28, 113, 76, 36, 112, 20, 9, 198, 76, 144, 137, 72, 148, 203, 20, 9, 198, 28, 83, 210, 28, 148, 203, 20, 9, 198, 28, 83, 133, 72, 148, 203, 20, 9, 198, 20, 118, 80, 80, 148, 203, 20, 10, 199, 56, 18, 211, 44, 245, 137, 80, 20, 10, 199, 80, 82, 206, 60, 180, 129, 80, 20, 10, 199, 77, 3, 206, 76, 244, 129, 80, 20, 14, 3, 95, 49, 52, 83, 57, 6, 39, 34, 72, 14, 50, 0, 0, 9, 198, 5, 67, 205, 37, 53, 0, 20, 7, 196, 32, 245, 5, 48, 20, 9, 198, 52, 147, 135, 20, 193, 82, 20, 9, 198, 44, 244, 146, 60, 65, 82, 20, 9, 198, 24, 245, 82, 4, 113, 82, 20, 9, 198, 16, 148, 211, 36, 65, 82, 20, 9, 198, 5, 69, 18, 4, 129, 82, 20, 6, 195, 21, 2, 75, 20, 7, 196, 88, 149, 1, 48, 20, 7, 196, 80, 245, 1, 48, 20, 10, 3, 95, 52, 15, 83, 57, 36, 114, 0, 12, 3, 95, 49, 55, 89, 6, 118, 72, 14, 50, 0, 0, 14, 139, 1, 18, 2, 9, 20, 18, 1, 7, 195, 184, 18, 20, 9, 198, 56, 243, 79, 29, 32, 77, 20, 9, 198, 24, 245, 15, 29, 32, 77, 20, 14, 3, 95, 49, 54, 89, 6, 35, 57, 89, 72, 14, 50, 0, 0, 13, 202, 81, 148, 15, 29, 32, 70, 21, 34, 78, 28, 20, 13, 202, 77, 147, 148, 21, 66, 83, 21, 34, 78, 28, 20, 13, 202, 77, 68, 149, 45, 69, 82, 21, 34, 78, 28, 20, 13, 202, 72, 243, 65, 57, 66, 83, 21, 34, 78, 28, 20, 13, 202, 65, 83, 22, 21, 34, 83, 21, 34, 78, 28, 20, 13, 202, 65, 34, 86, 5, 66, 83, 21, 34, 78, 28, 20, 13, 202, 64, 84, 137, 60, 66, 83, 21, 34, 78, 28, 20, 13, 202, 64, 20, 211, 37, 98, 83, 21, 34, 78, 28, 20, 13, 202, 48, 149, 15, 29, 32, 70, 21, 34, 78, 28, 20, 13, 202, 48, 16, 137, 4, 194, 83, 21, 34, 78, 28, 20, 13, 202, 44, 19, 148, 60, 226, 83, 21, 34, 78, 28, 20, 13, 202, 36, 226, 210, 36, 210, 78, 21, 34, 78, 28, 20, 13, 202, 36, 212, 18, 61, 98, 83, 21, 34, 78, 28, 20, 13, 202, 16, 85, 5, 72, 210, 78, 21, 34, 78, 28, 20, 13, 202, 8, 20, 130, 5, 34, 83, 21, 34, 78, 28, 20, 12, 201, 76, 176, 78, 16, 147, 129, 88, 148, 203, 20, 12, 201, 76, 49, 78, 60, 116, 129, 24, 148, 203, 20, 12, 201, 72, 84, 18, 60, 116, 129, 24, 148, 203, 20, 12, 201, 72, 81, 143, 72, 210, 83, 80, 148, 203, 20, 12, 201, 64, 244, 142, 60, 116, 129, 24, 148, 203, 20, 12, 201, 64, 243, 25, 80, 82, 83, 80, 148, 203, 20, 12, 201, 44, 20, 132, 36, 243, 15, 28, 148, 203, 20, 12, 201, 33, 145, 18, 60, 116, 129, 24, 148, 203, 20, 14, 139, 11, 22, 195, 166, 18, 21, 12, 1, 14, 3, 5, 20, 0, 10, 199, 52, 146, 210, 61, 50, 207, 64, 20, 12, 201, 16, 85, 5, 72, 210, 78, 37, 53, 0, 20, 10, 199, 88, 149, 129, 12, 149, 5, 80, 20, 10, 199, 64, 243, 1, 72, 149, 5, 80, 20, 10, 199, 52, 147, 143, 72, 149, 5, 80, 20, 10, 199, 48, 21, 9, 56, 149, 5, 80, 20, 10, 199, 45, 96, 78, 80, 149, 5, 80, 20, 10, 199, 44, 243, 137, 12, 149, 5, 80, 20, 10, 199, 44, 20, 1, 12, 149, 5, 80, 20, 10, 199, 36, 65, 78, 80, 149, 5, 80, 20, 10, 199, 25, 85, 9, 48, 149, 5, 80, 20, 10, 199, 21, 67, 137, 12, 149, 5, 80, 20, 9, 198, 92, 19, 9, 76, 148, 203, 20, 9, 198, 80, 83, 65, 80, 148, 203, 20, 9, 198, 48, 144, 133, 72, 148, 203, 20, 9, 198, 4, 116, 129, 72, 148, 203, 20, 10, 199, 76, 83, 73, 56, 20, 137, 20, 20, 10, 199, 76, 19, 129, 80, 244, 137, 20, 20, 9, 198, 16, 241, 205, 5, 66, 75, 20, 15, 3, 95, 55, 88, 107, 110, 55, 83, 57, 6, 110, 34, 89, 0, 0, 9, 198, 65, 35, 195, 20, 65, 82, 20, 11, 136, 19, 195, 166, 2, 25, 14, 9, 20, 20, 9, 198, 80, 19, 66, 85, 34, 78, 20, 9, 198, 64, 21, 9, 20, 229, 0, 20, 9, 198, 64, 20, 211, 4, 229, 0, 20, 0, 12, 201, 72, 80, 201, 65, 35, 195, 37, 65, 84, 20, 16, 205, 9, 84, 133, 5, 82, 210, 5, 66, 83, 21, 34, 78, 28, 20, 15, 204, 65, 54, 75, 60, 194, 78, 29, 98, 83, 80, 148, 203, 20, 8, 197, 9, 35, 205, 36, 64, 20, 9, 198, 48, 20, 135, 21, 52, 197, 20, 8, 197, 81, 34, 75, 36, 224, 20, 8, 197, 80, 18, 87, 4, 224, 20, 8, 197, 80, 18, 87, 4, 224, 21, 8, 197, 64, 20, 195, 4, 192, 20, 0, 13, 202, 77, 81, 199, 21, 53, 9, 88, 149, 5, 80, 20, 13, 202, 65, 35, 196, 84, 181, 9, 88, 149, 5, 80, 20, 13, 202, 44, 243, 132, 84, 181, 9, 88, 149, 5, 80, 20, 13, 202, 16, 84, 18, 21, 52, 201, 88, 149, 5, 80, 20, 12, 201, 80, 84, 141, 60, 209, 84, 72, 148, 203, 20, 12, 201, 77, 65, 82, 20, 241, 143, 56, 148, 203, 20, 12, 201, 52, 246, 129, 52, 34, 81, 84, 148, 203, 20, 12, 201, 52, 240, 193, 52, 34, 81, 84, 148, 203, 20, 13, 202, 20, 180, 193, 52, 147, 129, 80, 244, 137, 20, 20, 0, 10, 199, 36, 211, 85, 56, 243, 15, 28, 20, 10, 199, 77, 84, 208, 20, 225, 5, 72, 20, 11, 136, 10, 195, 184, 4, 9, 14, 4, 5, 20, 10, 199, 5, 85, 15, 52, 21, 9, 44, 20, 10, 199, 52, 19, 12, 61, 32, 201, 56, 20, 10, 199, 44, 243, 77, 20, 229, 1, 72, 20, 10, 199, 36, 228, 201, 57, 80, 78, 80, 20, 0, 9, 198, 64, 85, 9, 80, 147, 206, 20, 9, 198, 5, 81, 9, 80, 147, 206, 20, 11, 200, 76, 82, 214, 20, 229, 9, 20, 192, 20, 11, 200, 44, 243, 77, 21, 32, 201, 20, 192, 20, 7, 196, 72, 245, 5, 72, 20, 7, 196, 16, 245, 5, 72, 20, 11, 200, 36, 225, 15, 56, 84, 201, 20, 224, 20, 9, 198, 97, 147, 15, 29, 32, 70, 20, 9, 198, 48, 149, 15, 29, 32, 70, 20, 9, 198, 44, 83, 73, 29, 32, 70, 20, 7, 196, 60, 181, 1, 56, 21, 7, 196, 56, 245, 1, 72, 20, 7, 196, 12, 149, 1, 72, 20, 9, 198, 9, 34, 83, 4, 229, 0, 20, 9, 198, 89, 83, 14, 21, 32, 66, 20, 0, 12, 201, 4, 32, 146, 21, 98, 65, 81, 84, 128, 20, 8, 197, 80, 19, 80, 60, 224, 20, 9, 198, 5, 53, 18, 60, 227, 205, 20, 8, 197, 76, 84, 137, 20, 192, 20, 9, 198, 80, 83, 203, 72, 21, 9, 20, 8, 197, 80, 243, 147, 36, 192, 20, 8, 197, 89, 83, 11, 4, 224, 21, 8, 197, 88, 84, 147, 4, 192, 20, 0, 0, 10, 199, 4, 113, 210, 21, 52, 207, 72, 20, 10, 199, 65, 34, 79, 72, 149, 5, 72, 20, 10, 199, 88, 19, 139, 84, 225, 9, 28, 20, 10, 199, 52, 83, 147, 40, 85, 137, 44, 20, 10, 199, 76, 19, 65, 72, 149, 1, 56, 20, 12, 201, 32, 148, 212, 61, 34, 79, 29, 32, 70, 20, 10, 199, 76, 19, 65, 72, 149, 1, 56, 21, 10, 199, 36, 211, 73, 29, 32, 78, 80, 20, 10, 199, 12, 83, 5, 9, 32, 78, 80, 20, 0, 11, 200, 12, 244, 212, 5, 34, 67, 4, 224, 20, 9, 198, 80, 244, 15, 29, 32, 70, 20, 9, 198, 80, 83, 5, 29, 32, 70, 20, 9, 198, 32, 243, 79, 29, 32, 70, 20, 9, 198, 5, 85, 15, 29, 32, 70, 20, 0, 8, 197, 72, 245, 76, 21, 32, 20, 8, 197, 36, 210, 84, 21, 32, 20, 8, 197, 25, 34, 84, 21, 32, 20, 12, 137, 13, 5, 4, 9, 195, 166, 22, 1, 12, 20, 0, 13, 202, 88, 84, 147, 36, 98, 75, 5, 66, 79, 56, 20, 13, 202, 77, 65, 82, 36, 194, 83, 5, 66, 79, 56, 20, 13, 202, 77, 1, 67, 36, 98, 75, 5, 66, 79, 56, 20, 13, 202, 76, 240, 201, 4, 194, 83, 5, 66, 79, 56, 20, 13, 202, 53, 148, 212, 36, 98, 75, 5, 66, 79, 56, 20, 13, 202, 36, 229, 5, 73, 35, 199, 5, 66, 79, 56, 20, 13, 202, 29, 32, 84, 36, 98, 75, 5, 66, 79, 56, 20, 9, 198, 29, 32, 86, 21, 33, 64, 20, 9, 198, 9, 37, 78, 21, 33, 64, 20, 8, 67, 76, 86, 25, 21, 0, 10, 0, 9, 198, 44, 144, 83, 80, 148, 203, 20, 9, 198, 32, 84, 141, 21, 66, 75, 20, 12, 201, 44, 147, 133, 52, 21, 15, 29, 32, 70, 20, 10, 199, 52, 243, 147, 81, 32, 78, 76, 20, 0, 12, 201, 20, 224, 197, 24, 19, 15, 29, 32, 77, 20, 11, 200, 81, 34, 65, 56, 117, 76, 21, 32, 20, 11, 200, 77, 68, 129, 56, 117, 76, 21, 32, 20, 11, 200, 72, 80, 201, 72, 181, 76, 21, 32, 20, 11, 200, 65, 35, 211, 64, 82, 212, 21, 32, 20, 11, 200, 64, 20, 148, 36, 50, 80, 21, 32, 20, 0, 9, 198, 44, 147, 15, 29, 32, 77, 20, 9, 198, 32, 243, 15, 29, 32, 77, 20, 12, 201, 77, 68, 149, 45, 69, 82, 21, 33, 64, 20, 12, 201, 76, 181, 76, 65, 69, 82, 21, 33, 64, 20, 8, 197, 17, 32, 80, 21, 32, 20, 8, 197, 40, 84, 213, 37, 64, 20, 0, 9, 198, 80, 84, 212, 21, 33, 64, 20, 9, 198, 72, 84, 212, 21, 33, 64, 20, 9, 198, 64, 244, 212, 21, 33, 64, 20, 9, 198, 16, 243, 12, 21, 33, 64, 20, 0, 11, 4, 9, 4, 195, 169, 37, 72, 6, 36, 0, 9, 198, 56, 243, 65, 16, 148, 203, 20, 9, 198, 17, 147, 129, 52, 148, 203, 20, 9, 198, 4, 194, 193, 48, 148, 203, 20, 0, 11, 200, 44, 20, 129, 52, 35, 204, 21, 32, 20, 11, 200, 28, 84, 212, 36, 181, 76, 21, 32, 20, 11, 200, 60, 209, 143, 72, 213, 76, 21, 32, 20, 7, 196, 12, 148, 133, 72, 20, 9, 198, 16, 81, 137, 12, 149, 0, 20, 7, 196, 24, 20, 137, 56, 20, 7, 196, 4, 196, 9, 56, 20, 9, 198, 4, 225, 15, 73, 32, 78, 20, 9, 198, 44, 19, 9, 24, 21, 0, 20, 7, 196, 4, 197, 1, 56, 21, 0, 8, 197, 16, 148, 12, 60, 208, 20, 12, 201, 44, 243, 148, 72, 243, 12, 21, 33, 64, 20, 9, 198, 76, 49, 78, 5, 34, 69, 20, 9, 198, 76, 49, 78, 5, 34, 69, 20, 9, 198, 53, 148, 212, 21, 34, 69, 20, 9, 198, 16, 85, 84, 21, 34, 69, 20, 8, 197, 36, 225, 82, 80, 144, 20, 8, 197, 45, 34, 84, 36, 176, 20, 9, 198, 72, 85, 129, 56, 50, 5, 20, 0, 9, 198, 45, 83, 20, 85, 33, 76, 20, 9, 198, 77, 98, 78, 21, 34, 64, 20, 9, 198, 76, 49, 78, 21, 34, 64, 20, 9, 198, 17, 33, 74, 21, 34, 64, 20, 9, 198, 65, 35, 214, 77, 66, 64, 20, 0, 10, 199, 64, 243, 9, 80, 243, 15, 28, 20, 10, 199, 32, 85, 5, 72, 243, 15, 28, 20, 10, 199, 44, 244, 146, 61, 50, 79, 56, 20, 10, 199, 20, 180, 208, 4, 225, 5, 72, 20, 10, 199, 16, 145, 134, 84, 225, 5, 72, 20, 10, 199, 17, 34, 76, 4, 117, 9, 28, 20, 10, 199, 24, 243, 129, 77, 65, 78, 36, 20, 10, 199, 17, 34, 76, 4, 117, 9, 28, 20, 0, 23, 72, 4, 98, 67, 36, 243, 129, 16, 240, 35, 83, 37, 89, 57, 39, 6, 50, 35, 12, 72, 39, 0, 10, 135, 11, 15, 16, 9, 195, 184, 19, 20, 10, 135, 4, 21, 2, 9, 195, 184, 19, 20, 9, 134, 8, 21, 13, 195, 184, 18, 20, 7, 196, 24, 85, 5, 72, 20, 11, 200, 4, 225, 210, 36, 33, 76, 36, 112, 20, 11, 200, 4, 195, 73, 56, 65, 76, 36, 112, 20, 11, 200, 48, 144, 129, 56, 84, 201, 76, 176, 20, 11, 200, 36, 225, 15, 56, 84, 201, 76, 176, 20, 11, 200, 28, 16, 143, 56, 84, 201, 76, 176, 20, 11, 200, 64, 244, 212, 49, 81, 9, 84, 208, 20, 9, 198, 64, 20, 129, 44, 149, 0, 20, 9, 198, 16, 243, 5, 72, 149, 0, 20, 7, 196, 17, 84, 201, 56, 20, 11, 200, 72, 81, 143, 72, 210, 83, 52, 80, 20, 11, 200, 64, 243, 25, 80, 82, 83, 52, 80, 20, 11, 200, 61, 53, 18, 4, 178, 83, 52, 80, 20, 11, 200, 56, 244, 150, 4, 114, 83, 52, 80, 20, 11, 200, 53, 148, 212, 36, 50, 83, 52, 80, 20, 11, 200, 28, 145, 193, 57, 66, 83, 52, 80, 20, 11, 200, 28, 84, 141, 4, 226, 83, 52, 80, 20, 11, 200, 4, 225, 204, 36, 50, 83, 52, 80, 20, 11, 200, 4, 176, 68, 20, 210, 83, 52, 80, 20, 9, 198, 65, 34, 79, 72, 21, 0, 20, 7, 196, 52, 85, 1, 56, 21, 7, 196, 80, 21, 1, 72, 20, 8, 67, 24, 246, 0, 21, 0, 10, 0, 8, 197, 81, 149, 133, 72, 144, 20, 8, 197, 72, 241, 5, 72, 144, 20, 12, 201, 45, 96, 75, 76, 19, 22, 21, 34, 64, 20, 8, 197, 44, 241, 197, 72, 144, 20, 8, 197, 40, 17, 197, 72, 144, 20, 8, 197, 8, 17, 197, 72, 144, 20, 12, 201, 44, 20, 143, 48, 147, 135, 37, 50, 192, 20, 9, 198, 8, 50, 75, 61, 34, 69, 20, 9, 198, 21, 2, 90, 60, 245, 9, 20, 9, 198, 16, 144, 84, 21, 35, 73, 20, 8, 197, 77, 64, 84, 36, 176, 20, 12, 201, 80, 84, 146, 37, 67, 210, 36, 19, 0, 20, 0, 12, 137, 15, 6, 6, 9, 3, 9, 195, 184, 19, 20, 9, 198, 48, 83, 137, 56, 148, 212, 20, 9, 198, 33, 83, 79, 72, 148, 212, 20, 9, 198, 80, 20, 16, 21, 34, 64, 20, 9, 198, 76, 182, 68, 21, 34, 64, 20, 9, 198, 76, 182, 68, 21, 34, 64, 20, 9, 198, 76, 19, 20, 21, 34, 64, 20, 9, 198, 72, 148, 212, 21, 34, 64, 20, 9, 198, 52, 244, 212, 21, 34, 64, 20, 9, 198, 48, 20, 16, 21, 34, 64, 20, 9, 198, 40, 20, 16, 21, 34, 64, 20, 9, 198, 33, 148, 212, 21, 34, 64, 20, 9, 198, 24, 81, 20, 21, 34, 64, 20, 9, 198, 17, 32, 80, 21, 34, 64, 20, 9, 198, 9, 38, 68, 21, 34, 64, 20, 9, 198, 8, 85, 12, 21, 34, 64, 20, 13, 202, 28, 83, 129, 57, 97, 78, 16, 83, 9, 28, 20, 9, 198, 5, 34, 193, 37, 50, 192, 20, 9, 198, 16, 84, 208, 61, 66, 64, 20, 9, 198, 64, 20, 203, 88, 147, 0, 20, 13, 138, 6, 195, 166, 14, 15, 13, 5, 14, 1, 12, 20, 9, 198, 24, 81, 5, 72, 19, 0, 20, 0, 13, 138, 11, 15, 14, 20, 1, 7, 9, 195, 184, 19, 20, 13, 138, 11, 1, 16, 18, 9, 3, 9, 195, 184, 19, 20, 13, 138, 9, 14, 3, 5, 19, 20, 21, 195, 184, 19, 20, 10, 199, 81, 32, 68, 37, 66, 79, 56, 20, 10, 199, 76, 83, 5, 45, 66, 79, 56, 20, 10, 199, 44, 243, 12, 5, 66, 79, 56, 20, 10, 199, 29, 32, 68, 5, 66, 79, 56, 20, 10, 199, 44, 243, 142, 20, 181, 5, 72, 20, 10, 199, 4, 48, 197, 57, 69, 69, 72, 20, 14, 203, 48, 245, 141, 20, 66, 15, 48, 65, 76, 36, 112, 20, 14, 203, 77, 68, 149, 45, 69, 82, 4, 194, 83, 52, 80, 20, 14, 203, 65, 35, 212, 21, 53, 1, 57, 66, 83, 52, 80, 20, 14, 203, 44, 244, 205, 61, 3, 204, 37, 66, 83, 52, 80, 20, 14, 203, 44, 244, 144, 61, 32, 84, 37, 98, 83, 52, 80, 20, 14, 203, 36, 225, 21, 77, 68, 137, 4, 194, 83, 52, 80, 20, 10, 199, 25, 148, 147, 80, 147, 132, 20, 20, 12, 201, 65, 35, 212, 60, 179, 204, 48, 21, 0, 20, 10, 69, 48, 20, 20, 61, 0, 21, 0, 10, 11, 3, 95, 50, 88, 47, 6, 116, 12, 58, 0, 0, 14, 139, 11, 15, 13, 16, 5, 14, 4, 9, 195, 184, 19, 20, 9, 134, 4, 21, 19, 195, 184, 18, 20, 9, 198, 44, 20, 213, 37, 53, 0, 20, 11, 200, 48, 145, 197, 52, 17, 197, 72, 144, 20, 11, 200, 61, 4, 137, 56, 65, 76, 36, 112, 20, 15, 204, 44, 20, 148, 4, 114, 78, 36, 83, 147, 37, 50, 192, 20, 12, 201, 16, 148, 12, 60, 208, 84, 5, 34, 69, 20, 11, 200, 48, 147, 135, 88, 148, 212, 36, 176, 20, 7, 196, 88, 149, 129, 80, 20, 7, 196, 72, 149, 129, 48, 20, 0, 12, 201, 45, 96, 78, 80, 85, 5, 61, 34, 64, 20, 12, 201, 44, 19, 77, 21, 32, 84, 21, 34, 64, 20, 12, 201, 76, 243, 129, 72, 20, 16, 5, 32, 84, 20, 12, 201, 44, 20, 132, 36, 224, 76, 80, 19, 0, 20, 0, 13, 202, 81, 34, 65, 56, 117, 76, 5, 66, 79, 56, 20, 13, 202, 81, 32, 78, 76, 195, 203, 5, 66, 79, 56, 20, 13, 202, 77, 68, 129, 56, 117, 76, 5, 66, 79, 56, 20, 13, 202, 44, 243, 148, 20, 212, 12, 5, 66, 79, 56, 20, 13, 202, 36, 229, 18, 61, 52, 5, 45, 66, 79, 56, 20, 13, 202, 36, 212, 18, 61, 98, 83, 5, 66, 79, 56, 20, 13, 202, 4, 178, 207, 52, 211, 196, 5, 66, 79, 56, 20, 0, 12, 201, 61, 4, 15, 73, 69, 78, 37, 53, 0, 20, 14, 203, 64, 192, 84, 80, 83, 147, 48, 17, 197, 72, 144, 20, 14, 203, 76, 19, 77, 20, 225, 143, 48, 65, 76, 36, 112, 20, 10, 199, 8, 144, 140, 36, 241, 137, 48, 20, 10, 199, 60, 36, 197, 73, 96, 78, 76, 20, 0, 9, 198, 80, 19, 66, 85, 33, 82, 20, 9, 198, 72, 83, 73, 81, 65, 82, 20, 9, 198, 72, 82, 213, 73, 33, 82, 20, 9, 198, 64, 148, 5, 81, 65, 82, 20, 9, 198, 44, 243, 142, 61, 65, 82, 20, 9, 198, 44, 243, 80, 5, 33, 82, 20, 9, 198, 45, 35, 205, 5, 66, 78, 20, 7, 196, 56, 245, 1, 80, 20, 7, 196, 8, 21, 1, 80, 20, 9, 198, 77, 80, 139, 85, 64, 78, 21, 7, 196, 52, 85, 1, 48, 20, 7, 196, 48, 85, 1, 48, 20, 7, 196, 24, 21, 1, 48, 20, 10, 3, 95, 56, 15, 114, 47, 50, 108, 0, 0, 13, 138, 1, 4, 8, 195, 166, 18, 5, 14, 3, 5, 20, 0, 9, 198, 16, 83, 147, 37, 65, 84, 20, 11, 136, 11, 15, 8, 195, 166, 18, 5, 18, 20, 11, 136, 1, 4, 8, 195, 166, 18, 5, 18, 20, 9, 198, 80, 19, 10, 21, 33, 84, 20, 14, 139, 18, 5, 14, 195, 166, 19, 19, 1, 14, 3, 5, 20, 0, 12, 201, 65, 34, 77, 37, 66, 86, 37, 53, 0, 20, 12, 201, 36, 195, 21, 76, 147, 206, 37, 53, 0, 20, 10, 199, 85, 32, 129, 56, 149, 5, 80, 20, 10, 199, 65, 34, 79, 72, 149, 5, 80, 20, 10, 199, 33, 83, 65, 56, 149, 5, 80, 20, 10, 199, 4, 181, 9, 88, 149, 5, 80, 20, 12, 201, 45, 96, 75, 76, 19, 22, 21, 33, 82, 20, 12, 201, 9, 35, 206, 44, 244, 203, 61, 1, 82, 20, 10, 199, 77, 66, 80, 20, 225, 9, 20, 20, 10, 199, 44, 243, 80, 20, 225, 9, 20, 20, 9, 198, 45, 35, 205, 5, 66, 75, 20, 0, 9, 198, 80, 83, 80, 21, 33, 82, 20, 9, 198, 77, 147, 139, 61, 1, 82, 20, 9, 198, 72, 84, 207, 49, 97, 82, 20, 9, 198, 36, 226, 214, 37, 33, 82, 20, 7, 196, 29, 86, 65, 56, 20, 11, 200, 44, 243, 150, 21, 33, 197, 57, 48, 20, 9, 198, 76, 147, 85, 49, 64, 78, 21, 9, 198, 24, 147, 9, 29, 32, 78, 21, 0, 8, 197, 56, 85, 82, 60, 224, 20, 9, 198, 52, 85, 18, 60, 227, 205, 20, 12, 201, 64, 84, 144, 48, 82, 211, 37, 65, 84, 20, 12, 201, 29, 32, 78, 16, 147, 211, 37, 65, 84, 20, 9, 198, 81, 32, 86, 21, 53, 9, 20, 8, 197, 32, 84, 143, 36, 224, 20, 8, 197, 17, 82, 212, 36, 192, 20, 8, 197, 12, 242, 84, 4, 192, 20, 0, 13, 202, 72, 81, 140, 20, 180, 201, 88, 149, 5, 80, 20, 13, 202, 44, 243, 12, 20, 181, 9, 88, 149, 5, 80, 20, 13, 202, 37, 36, 133, 29, 83, 1, 72, 149, 5, 80, 20, 13, 202, 20, 180, 203, 49, 84, 201, 88, 149, 5, 80, 20, 9, 198, 52, 85, 5, 61, 34, 84, 20, 11, 70, 24, 148, 133, 92, 19, 12, 21, 0, 10, 0, 10, 199, 60, 67, 206, 80, 243, 15, 28, 20, 10, 199, 60, 49, 65, 56, 243, 15, 28, 20, 12, 201, 60, 212, 212, 73, 82, 212, 85, 33, 82, 20, 12, 201, 72, 84, 212, 73, 82, 212, 85, 33, 82, 20, 10, 199, 72, 84, 197, 73, 97, 82, 20, 20, 10, 199, 72, 84, 15, 73, 65, 82, 20, 20, 10, 199, 64, 21, 5, 57, 65, 82, 20, 20, 10, 199, 16, 84, 197, 73, 65, 82, 20, 20, 10, 199, 5, 69, 5, 77, 65, 82, 20, 20, 0, 12, 137, 1, 14, 195, 166, 19, 20, 5, 19, 9, 20, 9, 198, 8, 245, 73, 48, 195, 206, 20, 12, 201, 48, 16, 143, 72, 21, 15, 72, 149, 77, 20, 11, 200, 64, 243, 25, 56, 84, 201, 20, 224, 20, 11, 200, 52, 83, 1, 56, 84, 201, 20, 224, 20, 9, 198, 5, 35, 69, 56, 145, 78, 20, 9, 198, 4, 208, 137, 20, 229, 0, 20, 9, 198, 81, 32, 70, 36, 176, 66, 20, 9, 68, 77, 21, 65, 92, 21, 0, 10, 12, 3, 95, 63, 63, 89, 116, 65, 71, 39, 55, 0, 0, 13, 138, 19, 25, 14, 195, 166, 19, 20, 5, 19, 9, 20, 13, 138, 11, 9, 14, 195, 166, 19, 20, 5, 19, 9, 20, 12, 201, 20, 180, 208, 60, 225, 78, 80, 145, 76, 20, 8, 197, 24, 195, 206, 20, 192, 20, 8, 197, 28, 198, 75, 60, 192, 20, 9, 198, 72, 81, 149, 28, 149, 77, 20, 9, 198, 36, 225, 9, 12, 149, 77, 20, 9, 198, 16, 83, 9, 72, 149, 77, 20, 8, 197, 72, 84, 20, 36, 192, 20, 8, 197, 64, 148, 212, 36, 192, 20, 8, 197, 9, 84, 139, 36, 224, 20, 12, 137, 11, 15, 8, 195, 166, 18, 5, 14, 20, 20, 0, 11, 66, 53, 32, 65, 36, 89, 47, 114, 0, 25, 19, 144, 11, 195, 184, 14, 19, 4, 9, 19, 11, 18, 9, 13, 9, 14, 5, 18, 20, 13, 202, 76, 83, 22, 8, 82, 1, 28, 83, 9, 28, 20, 9, 198, 64, 21, 9, 20, 228, 192, 20, 9, 198, 5, 81, 9, 20, 228, 192, 20, 0, 10, 199, 65, 35, 202, 20, 181, 15, 72, 20, 12, 137, 12, 9, 20, 20, 5, 18, 195, 166, 18, 20, 10, 199, 72, 85, 129, 56, 50, 5, 72, 20, 10, 199, 36, 225, 11, 61, 2, 69, 72, 20, 10, 199, 16, 148, 212, 72, 18, 5, 72, 20, 10, 199, 4, 68, 133, 77, 49, 82, 20, 20, 10, 199, 24, 244, 142, 84, 101, 9, 28, 20, 10, 199, 81, 32, 77, 64, 243, 9, 56, 20, 10, 199, 72, 84, 213, 49, 64, 78, 80, 20, 10, 199, 60, 36, 197, 73, 96, 78, 80, 20, 11, 3, 95, 52, 88, 83, 6, 118, 12, 114, 0, 0, 13, 138, 16, 5, 14, 19, 9, 15, 14, 195, 166, 18, 20, 12, 201, 76, 181, 70, 24, 81, 1, 72, 149, 77, 20, 12, 201, 44, 243, 77, 37, 52, 207, 72, 149, 77, 20, 0, 14, 139, 6, 21, 14, 11, 20, 9, 15, 14, 195, 166, 18, 20, 8, 197, 76, 177, 76, 21, 64, 20, 8, 197, 72, 245, 76, 21, 64, 20, 8, 197, 8, 147, 12, 21, 64, 20, 8, 197, 89, 84, 132, 21, 32, 20, 8, 197, 20, 66, 84, 21, 32, 20, 8, 197, 16, 146, 212, 21, 32, 20, 9, 198, 77, 147, 77, 21, 68, 137, 20, 8, 197, 45, 98, 86, 37, 64, 20, 8, 197, 20, 35, 206, 37, 64, 20, 6, 195, 60, 208, 78, 20, 8, 197, 72, 80, 197, 57, 64, 20, 8, 197, 65, 34, 86, 5, 64, 20, 8, 197, 45, 32, 66, 5, 64, 20, 10, 69, 77, 2, 82, 37, 64, 21, 0, 10, 0, 11, 136, 19, 5, 11, 21, 12, 195, 166, 18, 20, 11, 136, 18, 5, 7, 21, 12, 195, 166, 18, 20, 15, 140, 16, 18, 195, 166, 12, 9, 13, 9, 14, 195, 166, 18, 20, 15, 140, 9, 14, 6, 12, 1, 20, 9, 15, 14, 195, 166, 18, 20, 15, 140, 5, 22, 15, 12, 21, 20, 9, 15, 14, 195, 166, 18, 20, 10, 135, 6, 195, 184, 12, 5, 18, 9, 20, 9, 198, 76, 243, 1, 72, 145, 64, 20, 9, 198, 41, 81, 9, 12, 145, 64, 20, 12, 137, 11, 15, 8, 195, 166, 18, 5, 14, 19, 20, 12, 137, 1, 4, 8, 195, 166, 18, 5, 14, 19, 20, 9, 198, 72, 83, 143, 56, 49, 64, 20, 9, 198, 36, 212, 5, 72, 144, 76, 20, 0, 16, 141, 18, 5, 22, 15, 12, 21, 20, 9, 15, 14, 195, 166, 18, 20, 12, 137, 11, 15, 14, 19, 21, 12, 195, 166, 18, 20, 12, 137, 7, 18, 1, 14, 21, 12, 195, 166, 18, 20, 16, 141, 4, 9, 19, 11, 18, 5, 20, 9, 15, 14, 195, 166, 18, 20, 12, 137, 3, 9, 18, 11, 21, 12, 195, 166, 18, 20, 10, 199, 76, 244, 148, 21, 34, 78, 28, 20, 10, 199, 76, 21, 84, 21, 34, 78, 28, 20, 10, 199, 73, 83, 132, 21, 34, 78, 28, 20, 10, 199, 60, 181, 76, 21, 34, 78, 28, 20, 10, 199, 44, 243, 148, 21, 34, 78, 28, 20, 10, 199, 44, 20, 148, 21, 34, 78, 28, 20, 10, 199, 9, 35, 196, 21, 34, 78, 28, 20, 11, 136, 19, 13, 195, 184, 12, 5, 18, 9, 20, 9, 198, 44, 244, 205, 21, 66, 75, 20, 0, 13, 138, 13, 15, 12, 5, 11, 25, 12, 195, 166, 18, 20, 13, 138, 5, 12, 5, 13, 5, 14, 20, 195, 166, 18, 20, 11, 200, 89, 83, 7, 5, 34, 84, 21, 64, 20, 11, 200, 80, 242, 211, 36, 50, 84, 21, 64, 20, 11, 200, 77, 80, 148, 36, 194, 84, 21, 64, 20, 11, 200, 64, 20, 211, 37, 98, 84, 21, 64, 20, 11, 200, 52, 244, 148, 4, 194, 84, 21, 64, 20, 11, 200, 52, 83, 148, 4, 194, 84, 21, 64, 20, 11, 200, 52, 21, 5, 72, 226, 84, 21, 64, 20, 11, 200, 40, 245, 137, 4, 194, 84, 21, 64, 20, 11, 200, 36, 225, 5, 52, 226, 84, 21, 64, 20, 11, 200, 28, 83, 137, 4, 194, 84, 21, 64, 20, 11, 200, 4, 229, 9, 45, 98, 84, 21, 64, 20, 11, 200, 4, 35, 143, 72, 210, 84, 21, 64, 20, 11, 200, 9, 84, 133, 5, 82, 210, 5, 64, 20, 9, 198, 57, 147, 70, 60, 208, 78, 21, 0, 8, 197, 76, 83, 147, 61, 32, 20, 8, 197, 12, 83, 147, 61, 32, 20, 14, 139, 19, 5, 4, 9, 13, 5, 14, 20, 195, 166, 18, 20, 8, 197, 4, 213, 76, 21, 64, 20, 8, 197, 44, 244, 9, 77, 64, 20, 8, 197, 21, 99, 204, 21, 32, 20, 9, 198, 28, 84, 137, 5, 68, 137, 20, 11, 136, 9, 8, 195, 166, 18, 4, 9, 7, 20, 12, 201, 36, 229, 15, 48, 84, 129, 56, 49, 64, 20, 8, 197, 88, 17, 193, 57, 64, 20, 16, 141, 18, 5, 16, 18, 195, 166, 19, 5, 14, 20, 1, 14, 20, 20, 8, 197, 61, 5, 1, 57, 64, 20, 0, 10, 66, 52, 48, 65, 35, 49, 6, 0, 41, 15, 140, 16, 1, 18, 12, 1, 13, 5, 14, 20, 195, 166, 18, 20, 13, 202, 61, 35, 129, 52, 83, 148, 21, 34, 78, 28, 20, 13, 202, 52, 19, 137, 24, 84, 212, 21, 34, 78, 28, 20, 13, 202, 44, 243, 150, 60, 197, 84, 21, 34, 78, 28, 20, 13, 202, 44, 243, 134, 72, 243, 148, 21, 34, 78, 28, 20, 13, 202, 36, 229, 5, 73, 3, 204, 21, 34, 78, 28, 20, 13, 202, 36, 225, 11, 88, 20, 148, 21, 34, 78, 28, 20, 13, 202, 16, 242, 213, 52, 83, 148, 21, 34, 78, 28, 20, 13, 202, 5, 33, 213, 52, 83, 148, 21, 34, 78, 28, 20, 12, 137, 19, 5, 22, 195, 166, 18, 4, 9, 7, 20, 9, 198, 72, 240, 137, 56, 145, 64, 20, 9, 198, 64, 243, 15, 56, 145, 64, 20, 9, 198, 36, 212, 5, 72, 145, 64, 20, 9, 198, 81, 32, 70, 36, 176, 76, 20, 9, 198, 76, 194, 84, 4, 113, 64, 20, 0, 16, 141, 11, 15, 13, 16, 12, 5, 13, 5, 14, 20, 195, 166, 18, 20, 10, 199, 32, 85, 5, 72, 243, 143, 52, 20, 14, 203, 65, 35, 214, 36, 228, 201, 4, 194, 84, 21, 64, 20, 14, 203, 20, 115, 195, 20, 229, 18, 36, 50, 84, 21, 64, 20, 13, 138, 15, 22, 5, 18, 8, 195, 184, 18, 9, 7, 20, 13, 138, 1, 7, 20, 22, 195, 166, 18, 4, 9, 7, 20, 10, 199, 72, 81, 133, 72, 83, 131, 20, 20, 10, 199, 16, 147, 9, 28, 83, 131, 20, 20, 10, 199, 16, 82, 193, 16, 83, 131, 20, 20, 10, 199, 5, 52, 213, 72, 19, 131, 20, 20, 14, 3, 95, 53, 88, 107, 110, 55, 6, 47, 16, 109, 89, 0, 0, 17, 142, 16, 5, 18, 16, 5, 14, 4, 9, 11, 21, 12, 195, 166, 18, 20, 9, 198, 60, 36, 207, 48, 85, 0, 20, 11, 200, 72, 82, 78, 88, 84, 212, 21, 32, 20, 11, 200, 44, 243, 147, 60, 194, 68, 21, 32, 20, 11, 200, 44, 241, 75, 76, 148, 212, 21, 32, 20, 11, 200, 20, 101, 5, 72, 64, 84, 21, 32, 20, 14, 139, 12, 1, 19, 20, 22, 195, 166, 18, 4, 9, 7, 20, 9, 198, 81, 32, 78, 76, 149, 0, 20, 7, 196, 8, 21, 9, 44, 20, 11, 200, 44, 243, 150, 21, 33, 197, 57, 64, 20, 11, 200, 8, 146, 193, 72, 35, 206, 5, 64, 20, 9, 198, 88, 19, 5, 72, 144, 78, 21, 0, 15, 140, 195, 184, 14, 19, 11, 22, 195, 166, 18, 4, 9, 7, 20, 15, 140, 12, 195, 166, 19, 5, 22, 195, 166, 18, 4, 9, 7, 20, 15, 140, 6, 15, 18, 4, 195, 184, 13, 13, 5, 12, 9, 7, 20, 9, 198, 24, 18, 212, 61, 69, 77, 20, 9, 198, 80, 149, 1, 56, 149, 77, 20, 9, 198, 52, 243, 143, 28, 19, 73, 20, 8, 197, 76, 147, 79, 56, 144, 20, 0, 9, 198, 48, 149, 21, 72, 114, 64, 20, 9, 198, 81, 34, 86, 36, 83, 0, 20, 12, 137, 15, 16, 14, 195, 165, 5, 12, 9, 7, 20, 16, 141, 6, 15, 18, 11, 18, 195, 166, 14, 11, 5, 12, 9, 7, 20, 6, 195, 44, 83, 73, 20, 9, 198, 48, 149, 20, 21, 32, 84, 20, 9, 198, 16, 148, 12, 60, 208, 84, 20, 9, 198, 5, 85, 15, 45, 32, 84, 20, 9, 198, 4, 113, 210, 20, 112, 84, 20, 9, 198, 56, 85, 84, 72, 19, 0, 20, 0, 17, 142, 6, 15, 18, 19, 11, 18, 195, 166, 11, 11, 5, 12, 9, 7, 20, 10, 199, 77, 98, 78, 4, 117, 9, 28, 20, 0, 7, 196, 8, 85, 15, 56, 20, 9, 198, 33, 145, 18, 60, 99, 206, 20, 9, 198, 29, 32, 70, 60, 99, 206, 20, 16, 141, 11, 195, 184, 2, 5, 14, 8, 1, 22, 14, 5, 18, 9, 20, 14, 139, 16, 195, 165, 19, 20, 195, 165, 5, 12, 9, 7, 20, 14, 139, 15, 22, 5, 18, 6, 12, 195, 184, 4, 9, 7, 20, 14, 139, 6, 15, 18, 19, 20, 195, 165, 5, 12, 9, 7, 20, 14, 139, 4, 18, 9, 11, 6, 195, 166, 12, 4, 9, 7, 20, 11, 200, 60, 36, 212, 21, 68, 137, 76, 176, 20, 11, 200, 52, 85, 1, 24, 244, 137, 76, 176, 20, 11, 200, 13, 147, 9, 56, 68, 137, 76, 176, 20, 11, 200, 44, 193, 80, 80, 243, 65, 56, 144, 20, 11, 200, 76, 128, 77, 4, 226, 83, 52, 80, 20, 11, 200, 64, 83, 142, 4, 194, 83, 52, 80, 20, 11, 200, 44, 242, 193, 36, 226, 83, 52, 80, 20, 11, 200, 32, 83, 12, 20, 226, 83, 52, 80, 20, 0, 11, 136, 16, 18, 5, 3, 9, 195, 184, 19, 20, 13, 138, 13, 1, 14, 195, 184, 22, 18, 5, 18, 5, 20, 15, 140, 13, 195, 184, 10, 19, 15, 13, 13, 5, 12, 9, 7, 20, 12, 201, 72, 17, 9, 60, 195, 199, 37, 50, 192, 20, 12, 201, 45, 35, 206, 60, 195, 199, 37, 50, 192, 20, 12, 201, 32, 148, 16, 60, 195, 199, 37, 50, 192, 20, 12, 201, 25, 33, 78, 60, 195, 199, 37, 50, 192, 20, 12, 201, 24, 147, 13, 60, 195, 199, 37, 50, 192, 20, 8, 197, 61, 96, 82, 36, 80, 20, 8, 197, 61, 96, 82, 36, 80, 20, 8, 197, 21, 85, 15, 56, 144, 20, 8, 197, 5, 53, 5, 56, 144, 20, 8, 197, 73, 84, 212, 36, 176, 20, 12, 201, 65, 35, 198, 21, 52, 207, 72, 19, 0, 20, 12, 201, 44, 243, 138, 20, 181, 21, 72, 19, 0, 20, 10, 69, 77, 21, 65, 72, 80, 21, 0, 10, 0, 10, 135, 8, 195, 166, 18, 5, 19, 9, 20, 9, 198, 81, 34, 76, 60, 114, 64, 20, 9, 198, 25, 83, 135, 36, 50, 68, 20, 9, 198, 72, 84, 213, 49, 64, 84, 20, 0, 6, 195, 32, 35, 192, 17, 10, 199, 16, 85, 15, 56, 21, 15, 72, 20, 10, 199, 8, 80, 82, 8, 82, 132, 20, 67, 10, 199, 72, 85, 129, 48, 145, 5, 72, 20, 10, 199, 72, 85, 15, 84, 50, 5, 72, 20, 10, 199, 4, 36, 212, 72, 18, 5, 72, 20, 14, 203, 20, 208, 78, 12, 148, 1, 80, 244, 137, 76, 176, 20, 10, 199, 24, 83, 129, 12, 85, 9, 56, 20, 14, 203, 88, 81, 197, 80, 20, 137, 4, 226, 83, 52, 80, 20, 14, 203, 37, 36, 129, 80, 147, 206, 4, 194, 83, 52, 80, 20, 10, 199, 9, 83, 7, 5, 34, 69, 56, 20, 12, 201, 65, 35, 198, 21, 52, 207, 72, 21, 0, 20, 11, 3, 95, 54, 88, 47, 16, 6, 109, 89, 0, 0, 11, 200, 77, 84, 16, 61, 37, 5, 72, 80, 20, 12, 137, 16, 18, 195, 166, 19, 20, 5, 18, 5, 20, 11, 200, 8, 147, 199, 72, 17, 133, 72, 80, 20, 11, 200, 77, 64, 84, 84, 20, 137, 76, 176, 20, 11, 200, 49, 83, 132, 20, 228, 201, 76, 176, 20, 11, 200, 45, 83, 9, 56, 20, 137, 76, 176, 20, 11, 200, 29, 148, 129, 80, 244, 137, 76, 176, 20, 11, 200, 28, 84, 137, 5, 68, 137, 76, 176, 20, 11, 200, 64, 192, 78, 21, 64, 82, 36, 80, 20, 11, 200, 16, 83, 6, 36, 224, 82, 36, 80, 20, 11, 200, 77, 148, 212, 20, 208, 84, 36, 176, 20, 11, 200, 57, 83, 73, 76, 208, 84, 36, 176, 20, 11, 200, 20, 208, 140, 20, 208, 84, 36, 176, 20, 11, 200, 16, 148, 12, 60, 208, 84, 36, 176, 20, 0, 10, 135, 2, 1, 14, 11, 195, 184, 18, 20, 14, 4, 95, 50, 88, 15, 47, 6, 116, 84, 13, 50, 13, 0, 0, 10, 135, 11, 195, 166, 12, 5, 18, 9, 20, 9, 198, 20, 180, 212, 72, 83, 64, 20, 15, 204, 56, 21, 18, 37, 83, 75, 5, 32, 143, 56, 21, 0, 20, 9, 198, 25, 85, 20, 21, 32, 76, 20, 0, 12, 137, 11, 18, 15, 14, 9, 11, 195, 184, 18, 20, 9, 198, 80, 82, 206, 60, 195, 199, 20, 9, 198, 56, 85, 82, 60, 195, 199, 20, 9, 198, 56, 82, 210, 60, 195, 199, 20, 12, 201, 85, 66, 76, 37, 64, 82, 37, 53, 0, 20, 12, 201, 20, 181, 137, 48, 144, 146, 37, 53, 0, 20, 14, 203, 8, 144, 140, 36, 245, 5, 44, 20, 137, 76, 176, 20, 14, 203, 36, 228, 212, 73, 83, 69, 57, 64, 82, 36, 80, 20, 10, 199, 52, 20, 135, 84, 84, 137, 80, 20, 10, 199, 25, 32, 78, 44, 241, 137, 48, 20, 9, 198, 48, 149, 21, 72, 114, 75, 20, 0, 9, 198, 56, 18, 86, 37, 53, 0, 20, 9, 198, 72, 84, 213, 49, 65, 82, 20, 9, 198, 72, 84, 208, 37, 33, 82, 20, 9, 198, 64, 84, 141, 85, 65, 82, 20, 9, 198, 64, 20, 211, 37, 97, 82, 20, 9, 198, 60, 36, 212, 37, 1, 82, 20, 9, 198, 16, 147, 73, 81, 65, 82, 20, 7, 196, 12, 149, 1, 80, 20, 13, 70, 52, 243, 147, 36, 85, 82, 21, 102, 114, 0, 10, 0, 9, 198, 80, 83, 5, 29, 32, 77, 20, 13, 138, 11, 195, 166, 18, 5, 19, 20, 5, 18, 9, 20, 9, 198, 24, 243, 137, 5, 68, 137, 20, 0, 21, 66, 36, 192, 37, 55, 15, 72, 6, 40, 12, 76, 57, 13, 0, 81, 100, 117, 99, 101, 32, 13, 202, 44, 243, 148, 72, 245, 133, 73, 50, 69, 48, 20, 9, 198, 8, 243, 66, 21, 33, 84, 20, 0, 10, 199, 88, 148, 137, 48, 149, 5, 80, 20, 10, 199, 88, 19, 9, 16, 149, 5, 80, 20, 10, 199, 80, 243, 129, 48, 149, 5, 80, 20, 10, 199, 52, 244, 129, 48, 149, 5, 80, 20, 10, 199, 48, 16, 137, 48, 149, 5, 80, 20, 10, 199, 44, 19, 1, 52, 149, 5, 80, 20, 10, 199, 8, 19, 129, 48, 149, 5, 80, 20, 10, 199, 64, 245, 5, 57, 66, 69, 48, 20, 12, 201, 4, 229, 9, 12, 128, 77, 9, 33, 82, 20, 0, 22, 68, 32, 20, 16, 100, 107, 110, 48, 37, 15, 6, 112, 40, 114, 0, 81, 104, 111, 117, 114, 32, 9, 198, 8, 82, 203, 5, 50, 78, 67, 9, 198, 4, 100, 133, 4, 113, 82, 20, 9, 198, 36, 211, 73, 29, 33, 82, 20, 9, 198, 5, 69, 18, 5, 1, 82, 20, 9, 198, 4, 113, 210, 20, 113, 82, 20, 9, 198, 52, 242, 203, 5, 50, 78, 20, 9, 198, 8, 82, 203, 5, 50, 78, 20, 7, 196, 25, 148, 201, 44, 20, 7, 196, 8, 150, 129, 72, 20, 0, 12, 201, 77, 1, 67, 36, 98, 67, 37, 65, 84, 20, 12, 201, 64, 84, 137, 60, 66, 67, 37, 65, 84, 20, 12, 201, 77, 1, 75, 81, 35, 199, 72, 19, 64, 20, 14, 139, 16, 195, 165, 15, 11, 20, 18, 15, 10, 5, 18, 20, 9, 198, 64, 243, 15, 56, 149, 77, 20, 8, 197, 80, 18, 212, 36, 192, 20, 14, 139, 7, 18, 5, 14, 195, 165, 5, 14, 19, 5, 18, 20, 12, 201, 44, 243, 134, 20, 65, 82, 21, 33, 84, 20, 12, 201, 16, 148, 211, 20, 210, 78, 21, 33, 84, 20, 12, 201, 16, 85, 5, 72, 210, 78, 21, 33, 84, 20, 0, 13, 202, 88, 82, 147, 80, 16, 137, 48, 149, 5, 80, 20, 13, 202, 84, 226, 86, 21, 36, 193, 48, 149, 5, 80, 20, 13, 202, 37, 36, 137, 80, 16, 137, 48, 149, 5, 80, 20, 13, 202, 20, 211, 212, 36, 243, 129, 48, 149, 5, 80, 20, 12, 201, 44, 243, 148, 72, 18, 5, 72, 147, 135, 20, 9, 198, 56, 245, 1, 72, 145, 76, 20, 9, 198, 16, 84, 21, 80, 84, 128, 20, 9, 198, 4, 212, 21, 80, 84, 128, 20, 15, 140, 7, 18, 5, 14, 195, 165, 7, 5, 14, 19, 5, 18, 20, 9, 198, 72, 80, 71, 20, 228, 192, 20, 0, 19, 5, 4, 10, 39, 5, 14, 72, 37, 12, 6, 72, 57, 36, 12, 57, 108, 50, 0, 10, 199, 61, 85, 133, 73, 69, 82, 20, 20, 10, 199, 44, 243, 134, 37, 69, 82, 20, 20, 10, 199, 24, 147, 9, 65, 2, 78, 20, 20, 10, 199, 16, 241, 5, 44, 17, 143, 56, 20, 10, 199, 65, 35, 214, 37, 50, 79, 56, 20, 10, 199, 44, 243, 148, 85, 50, 79, 56, 20, 10, 199, 16, 147, 73, 77, 50, 79, 56, 20, 10, 199, 16, 83, 73, 77, 50, 79, 56, 20, 10, 199, 64, 192, 75, 5, 65, 82, 20, 20, 10, 199, 45, 85, 133, 73, 65, 82, 20, 20, 10, 199, 16, 242, 212, 61, 33, 82, 20, 20, 10, 199, 16, 80, 129, 81, 65, 82, 20, 20, 10, 199, 5, 4, 15, 73, 65, 82, 20, 20, 10, 135, 195, 166, 20, 1, 14, 15, 12, 20, 12, 201, 5, 3, 208, 48, 82, 212, 36, 177, 82, 20, 10, 199, 44, 193, 77, 20, 229, 9, 56, 20, 0, 14, 204, 44, 20, 129, 45, 65, 82, 37, 53, 9, 44, 243, 128, 11, 200, 80, 83, 5, 88, 148, 201, 60, 224, 20, 11, 200, 77, 80, 195, 21, 52, 201, 60, 224, 20, 11, 200, 20, 180, 203, 49, 84, 201, 60, 224, 20, 11, 200, 16, 148, 203, 85, 52, 201, 60, 224, 20, 11, 200, 16, 145, 210, 21, 52, 201, 60, 224, 20, 11, 200, 16, 81, 210, 21, 52, 201, 60, 224, 20, 11, 200, 36, 225, 21, 77, 68, 137, 20, 192, 20, 11, 200, 72, 83, 1, 80, 147, 206, 20, 192, 20, 11, 200, 64, 83, 137, 12, 147, 12, 36, 224, 20, 7, 196, 80, 86, 1, 56, 20, 11, 200, 65, 4, 137, 56, 50, 80, 4, 192, 20, 0, 10, 135, 20, 5, 18, 14, 195, 166, 18, 20, 16, 205, 44, 243, 77, 20, 228, 213, 72, 16, 137, 48, 149, 5, 80, 20, 12, 201, 20, 180, 201, 77, 65, 78, 80, 145, 76, 20, 12, 201, 16, 145, 134, 21, 33, 78, 80, 145, 76, 20, 9, 198, 52, 241, 21, 48, 84, 133, 20, 8, 197, 77, 80, 148, 36, 192, 20, 8, 197, 4, 97, 200, 4, 224, 20, 8, 197, 52, 83, 148, 4, 192, 20, 10, 69, 5, 84, 212, 36, 224, 21, 0, 10, 0, 11, 136, 11, 15, 14, 20, 18, 195, 166, 18, 20, 9, 198, 5, 37, 5, 72, 145, 76, 20, 15, 140, 16, 18, 195, 166, 4, 5, 19, 20, 9, 14, 5, 18, 20, 0, 10, 199, 48, 16, 143, 72, 21, 15, 72, 20, 10, 199, 16, 81, 140, 20, 181, 15, 72, 20, 12, 137, 12, 5, 7, 9, 15, 14, 195, 166, 18, 20, 12, 137, 12, 1, 20, 18, 9, 14, 195, 166, 18, 20, 12, 137, 1, 11, 20, 9, 15, 14, 195, 166, 18, 20, 21, 71, 48, 147, 79, 85, 50, 78, 20, 55, 37, 65, 113, 89, 6, 37, 12, 50, 13, 0, 20, 10, 199, 88, 144, 146, 5, 66, 79, 56, 20, 10, 199, 52, 145, 210, 5, 66, 79, 56, 20, 10, 199, 44, 241, 206, 37, 66, 79, 56, 20, 10, 199, 44, 20, 142, 5, 66, 79, 56, 20, 14, 203, 44, 243, 147, 80, 149, 21, 80, 147, 206, 20, 192, 20, 10, 199, 77, 80, 148, 72, 18, 5, 72, 20, 10, 199, 64, 245, 5, 57, 49, 82, 20, 20, 10, 199, 64, 20, 212, 36, 50, 5, 72, 20, 10, 199, 4, 32, 146, 21, 98, 69, 72, 20, 13, 138, 195, 184, 11, 15, 14, 15, 13, 9, 19, 11, 20, 10, 199, 88, 144, 212, 61, 34, 65, 56, 20, 10, 199, 5, 52, 201, 77, 65, 78, 80, 20, 11, 3, 95, 56, 88, 83, 6, 37, 34, 89, 0, 0, 11, 200, 4, 113, 210, 21, 52, 201, 60, 224, 20, 11, 200, 64, 244, 201, 80, 147, 206, 20, 192, 20, 0, 10, 135, 21, 22, 21, 12, 195, 166, 18, 20, 10, 135, 5, 12, 9, 20, 195, 166, 18, 20, 9, 198, 8, 147, 205, 21, 68, 137, 20, 8, 197, 77, 83, 142, 37, 64, 20, 8, 197, 28, 19, 1, 57, 64, 20, 0, 13, 202, 64, 244, 21, 48, 20, 137, 76, 21, 15, 72, 20, 11, 136, 19, 1, 14, 9, 20, 195, 166, 18, 20, 13, 202, 72, 83, 79, 57, 53, 18, 5, 66, 79, 56, 20, 13, 202, 44, 243, 131, 20, 229, 18, 5, 66, 79, 56, 20, 13, 202, 16, 83, 79, 57, 53, 18, 5, 66, 79, 56, 20, 16, 141, 7, 25, 14, 195, 166, 11, 15, 12, 15, 7, 9, 19, 11, 20, 9, 198, 36, 226, 149, 72, 145, 64, 20, 9, 198, 8, 85, 15, 56, 145, 64, 20, 9, 198, 5, 37, 5, 72, 145, 64, 20, 9, 198, 72, 81, 149, 28, 145, 64, 20, 9, 198, 36, 225, 9, 12, 145, 64, 20, 9, 198, 16, 83, 9, 72, 145, 64, 20, 9, 198, 44, 240, 75, 76, 144, 76, 20, 9, 198, 16, 147, 21, 88, 144, 76, 20, 9, 198, 64, 20, 211, 4, 113, 64, 20, 0, 12, 137, 1, 12, 22, 5, 15, 12, 195, 166, 18, 20, 10, 199, 88, 144, 146, 21, 34, 78, 28, 20, 10, 199, 76, 84, 150, 21, 34, 78, 28, 20, 10, 199, 45, 35, 203, 21, 34, 78, 28, 20, 10, 199, 44, 20, 211, 21, 34, 78, 28, 20, 10, 199, 28, 192, 83, 21, 34, 78, 28, 20, 10, 199, 16, 244, 211, 21, 34, 78, 28, 20, 11, 136, 11, 195, 166, 22, 12, 5, 18, 9, 20, 10, 199, 44, 21, 1, 45, 33, 83, 20, 20, 12, 201, 16, 145, 134, 21, 33, 78, 80, 144, 66, 20, 0, 13, 138, 20, 15, 20, 1, 12, 9, 20, 195, 166, 18, 20, 11, 200, 76, 240, 201, 4, 194, 84, 21, 64, 20, 11, 200, 64, 84, 134, 36, 66, 84, 21, 64, 20, 11, 200, 56, 244, 141, 4, 194, 84, 21, 64, 20, 11, 200, 52, 244, 130, 36, 66, 84, 21, 64, 20, 11, 200, 48, 146, 214, 36, 66, 84, 21, 64, 20, 11, 200, 29, 32, 86, 36, 66, 84, 21, 64, 20, 11, 200, 25, 34, 71, 36, 66, 84, 21, 64, 20, 11, 200, 24, 244, 141, 4, 194, 84, 21, 64, 20, 11, 200, 24, 84, 148, 36, 194, 84, 21, 64, 20, 11, 200, 17, 82, 212, 36, 194, 84, 21, 64, 20, 11, 200, 9, 37, 84, 4, 194, 84, 21, 64, 20, 11, 200, 4, 181, 21, 4, 194, 84, 21, 64, 20, 11, 200, 4, 36, 213, 72, 66, 84, 21, 64, 20, 11, 200, 65, 35, 199, 72, 81, 9, 21, 32, 20, 12, 201, 64, 192, 78, 28, 83, 205, 21, 68, 137, 20, 12, 137, 4, 10, 195, 166, 22, 12, 5, 18, 9, 20, 14, 139, 195, 166, 20, 9, 15, 12, 15, 7, 9, 19, 11, 20, 18, 143, 6, 195, 166, 14, 15, 13, 5, 14, 15, 12, 15, 7, 9, 19, 11, 20, 9, 198, 8, 19, 4, 4, 178, 78, 20, 9, 198, 72, 245, 1, 72, 144, 78, 20, 9, 198, 44, 244, 147, 36, 176, 78, 20, 13, 72, 52, 19, 129, 28, 83, 69, 57, 64, 21, 0, 10, 11, 70, 32, 243, 204, 36, 112, 78, 21, 0, 10, 0, 14, 139, 16, 18, 15, 16, 18, 9, 5, 20, 195, 166, 18, 20, 14, 139, 11, 15, 13, 13, 21, 14, 9, 20, 195, 166, 18, 20, 8, 197, 72, 17, 9, 21, 32, 20, 8, 197, 24, 243, 9, 21, 32, 20, 12, 201, 76, 181, 70, 24, 81, 1, 72, 145, 64, 20, 12, 201, 44, 243, 77, 37, 52, 207, 72, 145, 64, 20, 8, 197, 24, 84, 146, 37, 64, 20, 12, 201, 52, 84, 193, 48, 194, 65, 56, 49, 64, 20, 8, 197, 44, 241, 206, 5, 64, 20, 8, 197, 53, 85, 1, 57, 64, 20, 6, 195, 52, 81, 0, 76, 0, 13, 202, 88, 84, 147, 36, 98, 67, 21, 34, 78, 28, 20, 13, 202, 72, 82, 212, 36, 98, 67, 21, 34, 78, 28, 20, 13, 202, 64, 20, 129, 24, 98, 78, 21, 34, 78, 28, 20, 13, 202, 52, 244, 148, 36, 98, 67, 21, 34, 78, 28, 20, 13, 202, 45, 96, 76, 36, 98, 67, 21, 34, 78, 28, 20, 13, 202, 44, 243, 131, 20, 229, 18, 21, 34, 78, 28, 20, 13, 202, 25, 32, 75, 80, 147, 206, 21, 34, 78, 28, 20, 13, 202, 12, 84, 148, 36, 98, 67, 21, 34, 78, 28, 20, 10, 135, 22, 195, 166, 22, 5, 18, 9, 20, 10, 135, 20, 195, 184, 10, 5, 18, 9, 20, 9, 198, 52, 21, 5, 72, 145, 64, 20, 9, 198, 52, 18, 15, 56, 145, 64, 20, 9, 198, 8, 81, 207, 56, 145, 64, 20, 9, 198, 80, 149, 1, 56, 145, 64, 20, 9, 198, 44, 20, 18, 36, 49, 64, 20, 9, 198, 24, 18, 129, 56, 49, 64, 20, 9, 198, 44, 243, 15, 56, 144, 76, 20, 9, 198, 45, 84, 148, 4, 113, 64, 20, 0, 14, 203, 52, 243, 149, 52, 83, 148, 4, 194, 84, 21, 64, 20, 14, 203, 36, 225, 9, 88, 145, 21, 4, 194, 84, 21, 64, 20, 13, 138, 16, 195, 165, 22, 9, 19, 5, 12, 9, 7, 20, 13, 138, 1, 14, 19, 20, 195, 166, 14, 4, 9, 7, 20, 13, 138, 1, 6, 12, 195, 165, 19, 5, 12, 9, 7, 20, 12, 201, 29, 37, 78, 17, 69, 137, 28, 144, 78, 20, 10, 199, 48, 85, 133, 72, 19, 131, 20, 20, 10, 199, 5, 36, 143, 28, 19, 131, 20, 20, 8, 67, 8, 246, 64, 21, 0, 10, 14, 3, 95, 57, 88, 107, 110, 55, 83, 6, 109, 65, 89, 0, 0, 9, 198, 33, 145, 18, 60, 99, 210, 20, 9, 198, 80, 244, 133, 4, 67, 210, 20, 11, 200, 65, 35, 203, 85, 32, 84, 61, 32, 20, 7, 196, 32, 245, 133, 72, 20, 16, 141, 11, 22, 195, 166, 18, 21, 12, 1, 14, 20, 5, 18, 9, 20, 14, 139, 9, 14, 4, 19, 20, 195, 166, 14, 4, 9, 7, 20, 11, 200, 77, 84, 16, 48, 146, 193, 57, 64, 20, 7, 196, 16, 85, 20, 20, 76, 0, 9, 198, 44, 243, 77, 84, 227, 205, 20, 15, 140, 13, 9, 19, 20, 195, 166, 14, 11, 5, 12, 9, 7, 20, 12, 201, 48, 16, 143, 72, 21, 15, 72, 145, 64, 20, 12, 201, 4, 208, 149, 48, 21, 15, 72, 145, 64, 20, 9, 198, 5, 85, 15, 56, 243, 73, 20, 8, 197, 80, 18, 212, 36, 176, 20, 8, 197, 52, 244, 134, 20, 208, 20, 12, 201, 36, 228, 208, 20, 181, 18, 36, 49, 64, 20, 0, 9, 198, 104, 243, 204, 60, 114, 64, 20, 17, 206, 20, 180, 212, 21, 36, 137, 80, 244, 137, 4, 194, 84, 21, 64, 20, 9, 198, 52, 21, 5, 72, 145, 76, 20, 14, 139, 20, 9, 12, 19, 11, 195, 166, 18, 5, 18, 9, 20, 14, 139, 15, 22, 5, 18, 12, 195, 184, 2, 5, 18, 9, 20, 9, 198, 9, 32, 75, 80, 80, 84, 20, 0, 10, 199, 25, 32, 78, 44, 241, 143, 56, 20, 10, 199, 80, 83, 5, 52, 85, 18, 36, 20, 10, 199, 76, 241, 137, 77, 65, 82, 36, 20, 10, 199, 72, 85, 8, 5, 97, 82, 36, 20, 10, 199, 64, 81, 1, 57, 65, 82, 36, 20, 10, 199, 36, 225, 129, 57, 65, 82, 36, 20, 13, 138, 12, 5, 13, 6, 195, 166, 12, 4, 9, 7, 20, 13, 138, 1, 6, 12, 195, 166, 19, 5, 12, 9, 7, 20, 10, 199, 80, 83, 5, 52, 21, 9, 44, 20, 10, 199, 64, 225, 85, 52, 21, 9, 44, 20, 10, 199, 29, 32, 77, 52, 21, 9, 44, 20, 10, 199, 20, 225, 82, 28, 85, 9, 44, 20, 10, 199, 4, 34, 200, 5, 50, 69, 56, 20, 10, 199, 24, 20, 200, 36, 243, 129, 8, 20, 0, 11, 200, 80, 84, 146, 5, 52, 197, 72, 80, 20, 14, 139, 16, 195, 165, 22, 9, 18, 11, 5, 12, 9, 7, 20, 14, 139, 6, 15, 18, 4, 195, 184, 10, 5, 12, 9, 7, 20, 11, 200, 64, 84, 137, 24, 84, 137, 76, 176, 20, 11, 200, 64, 83, 135, 20, 116, 137, 76, 176, 20, 11, 200, 4, 193, 65, 80, 244, 137, 76, 176, 20, 11, 200, 80, 84, 146, 37, 67, 210, 36, 80, 20, 11, 200, 60, 97, 133, 73, 67, 210, 36, 80, 20, 12, 201, 4, 208, 149, 48, 21, 15, 72, 149, 77, 20, 0, 12, 201, 44, 147, 133, 76, 147, 204, 60, 114, 64, 20, 12, 201, 80, 84, 146, 37, 67, 210, 36, 83, 0, 20, 8, 197, 64, 244, 197, 72, 80, 20, 8, 197, 4, 181, 5, 72, 80, 20, 9, 198, 64, 148, 212, 4, 50, 69, 20, 9, 198, 5, 84, 208, 36, 50, 69, 20, 8, 197, 36, 66, 79, 80, 144, 20, 8, 197, 52, 20, 212, 36, 176, 20, 8, 197, 8, 84, 212, 36, 176, 20, 12, 201, 44, 243, 77, 37, 52, 193, 72, 144, 84, 20, 0, 9, 198, 41, 81, 9, 12, 145, 76, 20, 10, 135, 12, 195, 166, 4, 5, 18, 5, 20, 16, 141, 19, 5, 12, 22, 6, 195, 184, 12, 7, 5, 12, 9, 7, 20, 9, 198, 64, 84, 212, 36, 50, 68, 20, 9, 198, 21, 84, 153, 80, 210, 64, 20, 9, 198, 25, 32, 75, 80, 147, 0, 20, 9, 198, 8, 84, 212, 40, 19, 0, 20, 13, 3, 95, 63, 65, 71, 39, 40, 89, 47, 35, 58, 0, 0, 16, 5, 3, 4, 39, 5, 14, 89, 36, 12, 72, 36, 12, 108, 50, 0, 10, 199, 61, 33, 9, 56, 21, 15, 72, 20, 10, 199, 72, 84, 1, 81, 34, 69, 72, 20, 11, 136, 13, 195, 184, 2, 12, 5, 18, 5, 20, 10, 199, 44, 243, 148, 72, 18, 5, 72, 20, 10, 199, 16, 83, 149, 57, 66, 69, 72, 20, 10, 199, 72, 245, 9, 77, 49, 82, 36, 20, 10, 199, 4, 193, 143, 57, 49, 82, 36, 20, 17, 142, 12, 5, 20, 16, 195, 165, 22, 9, 18, 11, 5, 12, 9, 7, 20, 14, 203, 61, 33, 193, 56, 148, 193, 80, 244, 137, 76, 176, 20, 14, 203, 44, 243, 134, 37, 50, 193, 80, 244, 137, 76, 176, 20, 12, 201, 64, 20, 211, 36, 243, 133, 72, 85, 0, 20, 0, 7, 196, 12, 84, 149, 80, 20, 9, 198, 104, 147, 206, 37, 53, 0, 20, 11, 200, 77, 64, 84, 84, 84, 137, 56, 112, 20, 11, 200, 76, 180, 129, 88, 84, 137, 56, 112, 20, 11, 200, 72, 81, 21, 12, 84, 137, 56, 112, 20, 11, 200, 64, 20, 129, 24, 84, 137, 56, 112, 20, 11, 200, 44, 19, 143, 56, 84, 137, 56, 112, 20, 11, 200, 36, 225, 137, 12, 84, 137, 56, 112, 20, 11, 200, 36, 115, 143, 72, 84, 137, 56, 112, 20, 11, 200, 28, 83, 133, 72, 84, 137, 56, 112, 20, 11, 200, 20, 228, 201, 48, 84, 137, 56, 112, 20, 11, 200, 17, 81, 76, 48, 84, 137, 56, 112, 20, 11, 200, 16, 84, 137, 88, 84, 137, 56, 112, 20, 11, 200, 4, 35, 206, 56, 84, 137, 56, 112, 20, 11, 200, 76, 177, 76, 21, 69, 5, 72, 80, 20, 11, 200, 72, 245, 76, 21, 69, 5, 72, 80, 20, 11, 200, 65, 35, 202, 20, 181, 5, 72, 80, 20, 11, 200, 8, 147, 12, 21, 69, 5, 72, 80, 20, 11, 200, 80, 17, 19, 40, 146, 201, 76, 176, 20, 11, 200, 40, 21, 129, 56, 84, 201, 76, 176, 20, 11, 200, 4, 195, 5, 28, 244, 137, 76, 176, 20, 11, 200, 9, 32, 86, 85, 32, 82, 36, 80, 20, 7, 196, 12, 149, 137, 48, 20, 11, 200, 16, 144, 71, 56, 244, 212, 36, 176, 20, 9, 198, 4, 192, 129, 56, 145, 78, 20, 0, 12, 201, 81, 32, 68, 37, 66, 79, 56, 83, 0, 20, 9, 198, 28, 83, 205, 21, 68, 137, 20, 0, 20, 3, 13, 195, 165, 65, 6, 113, 12, 15, 107, 110, 12, 0, 81, 104, 97, 118, 101, 32, 14, 70, 48, 145, 197, 76, 243, 64, 55, 37, 89, 114, 65, 0, 17, 70, 77, 98, 78, 28, 243, 64, 89, 84, 36, 68, 6, 114, 65, 0, 20, 9, 198, 5, 85, 15, 56, 243, 64, 20, 9, 198, 4, 224, 71, 72, 19, 64, 20, 10, 135, 8, 195, 166, 12, 5, 18, 9, 20, 13, 202, 24, 244, 134, 5, 69, 5, 72, 147, 132, 20, 20, 9, 198, 48, 82, 211, 36, 176, 76, 20, 6, 131, 13, 195, 165, 76, 0, 17, 5, 2, 8, 39, 5, 18, 71, 4, 36, 12, 107, 6, 113, 12, 114, 0, 15, 5, 3, 4, 39, 5, 18, 89, 36, 12, 72, 36, 12, 114, 0, 12, 201, 72, 85, 137, 76, 147, 206, 37, 53, 0, 20, 14, 203, 84, 66, 207, 56, 181, 82, 72, 84, 137, 56, 112, 20, 14, 203, 81, 32, 85, 52, 21, 9, 76, 84, 137, 56, 112, 20, 14, 203, 80, 84, 141, 60, 116, 129, 24, 84, 137, 56, 112, 20, 14, 203, 77, 1, 67, 36, 19, 9, 76, 84, 137, 56, 112, 20, 10, 199, 61, 134, 68, 21, 34, 78, 28, 20, 10, 199, 61, 130, 68, 21, 34, 78, 28, 20, 14, 203, 56, 243, 73, 56, 19, 9, 76, 84, 137, 56, 112, 20, 14, 203, 56, 85, 84, 72, 19, 9, 76, 84, 137, 56, 112, 20, 14, 203, 56, 21, 21, 72, 19, 9, 76, 84, 137, 56, 112, 20, 10, 199, 52, 21, 20, 21, 34, 78, 28, 20, 14, 203, 48, 144, 133, 72, 19, 9, 76, 84, 137, 56, 112, 20, 10, 199, 45, 34, 68, 21, 34, 78, 28, 20, 14, 203, 44, 20, 9, 80, 19, 9, 76, 84, 137, 56, 112, 20, 10, 199, 41, 84, 212, 21, 34, 78, 28, 20, 10, 199, 37, 51, 204, 21, 34, 78, 28, 20, 10, 199, 16, 243, 12, 21, 34, 78, 28, 20, 14, 203, 16, 147, 69, 57, 50, 79, 56, 84, 137, 56, 112, 20, 14, 203, 16, 21, 1, 52, 21, 9, 76, 84, 137, 56, 112, 20, 14, 203, 4, 48, 197, 77, 50, 79, 56, 84, 137, 56, 112, 20, 15, 140, 16, 15, 18, 20, 18, 195, 166, 20, 20, 5, 18, 5, 20, 12, 201, 12, 83, 148, 72, 19, 1, 76, 145, 78, 20, 10, 199, 16, 145, 134, 21, 33, 78, 76, 20, 10, 199, 64, 84, 147, 21, 34, 193, 80, 20, 10, 199, 29, 147, 78, 5, 50, 65, 48, 20, 0, 9, 198, 17, 32, 71, 37, 53, 0, 20, 9, 198, 81, 32, 70, 36, 177, 82, 20, 9, 198, 77, 81, 134, 36, 113, 82, 20, 9, 198, 72, 84, 12, 36, 49, 82, 20, 9, 198, 72, 83, 143, 56, 49, 82, 20, 9, 198, 44, 243, 147, 84, 209, 82, 20, 9, 198, 36, 226, 149, 72, 145, 82, 20, 9, 198, 16, 84, 12, 4, 49, 82, 20, 12, 137, 19, 11, 195, 166, 20, 20, 5, 18, 9, 20, 12, 201, 16, 83, 147, 37, 67, 205, 21, 68, 137, 20, 9, 198, 56, 145, 197, 72, 144, 78, 20, 9, 198, 4, 225, 204, 60, 208, 78, 21, 0, 0, 9, 198, 21, 2, 71, 72, 19, 64, 20, 13, 202, 16, 148, 212, 72, 144, 149, 21, 34, 78, 28, 20, 11, 70, 92, 84, 212, 21, 35, 128, 21, 0, 10, 0, 9, 198, 32, 148, 212, 60, 195, 199, 20, 12, 201, 45, 33, 65, 80, 147, 206, 37, 53, 0, 20, 12, 201, 72, 17, 9, 60, 66, 82, 36, 113, 82, 20, 12, 201, 65, 35, 199, 56, 244, 212, 36, 49, 82, 20, 11, 136, 19, 13, 195, 184, 18, 5, 18, 9, 20, 10, 199, 72, 84, 208, 60, 228, 213, 52, 20, 10, 199, 29, 32, 80, 80, 243, 9, 80, 20, 10, 199, 65, 35, 202, 20, 181, 9, 48, 20, 12, 137, 11, 195, 184, 7, 5, 14, 19, 5, 18, 20, 10, 199, 64, 245, 5, 57, 66, 65, 48, 20, 0, 9, 198, 5, 36, 129, 56, 113, 82, 20, 16, 141, 195, 166, 18, 5, 19, 11, 195, 166, 14, 4, 5, 18, 9, 20, 18, 143, 16, 1, 12, 195, 166, 15, 14, 20, 15, 12, 15, 7, 9, 19, 11, 20, 13, 138, 8, 195, 166, 18, 5, 20, 9, 11, 5, 18, 20, 9, 198, 20, 193, 71, 36, 177, 82, 20, 18, 70, 52, 20, 143, 12, 18, 78, 65, 112, 34, 39, 6, 49, 109, 68, 0, 20, 11, 200, 44, 242, 78, 12, 145, 5, 57, 48, 20, 9, 198, 21, 35, 212, 60, 208, 78, 21, 11, 4, 95, 8, 15, 11, 107, 6, 40, 49, 0, 0, 19, 144, 1, 14, 195, 166, 19, 20, 5, 19, 9, 15, 12, 15, 7, 9, 19, 11, 20, 12, 137, 16, 18, 195, 166, 4, 9, 11, 1, 20, 20, 9, 198, 45, 34, 84, 37, 48, 66, 20, 0, 12, 137, 1, 18, 11, 195, 166, 15, 12, 15, 7, 20, 14, 139, 15, 18, 4, 11, 12, 195, 184, 22, 5, 18, 9, 20, 11, 136, 6, 195, 184, 14, 9, 11, 5, 18, 20, 13, 202, 44, 243, 15, 72, 21, 21, 72, 20, 137, 20, 20, 8, 197, 76, 20, 132, 36, 224, 20, 8, 197, 16, 147, 216, 36, 224, 20, 8, 197, 40, 244, 132, 4, 224, 20, 8, 197, 8, 192, 68, 4, 224, 21, 8, 197, 37, 36, 133, 4, 192, 20, 0, 9, 198, 16, 80, 201, 76, 244, 128, 20, 9, 198, 88, 81, 197, 80, 84, 128, 20, 9, 198, 88, 19, 21, 80, 84, 128, 20, 9, 198, 76, 19, 21, 80, 84, 128, 20, 9, 198, 72, 85, 137, 16, 84, 128, 20, 9, 198, 72, 84, 201, 16, 84, 128, 20, 9, 198, 72, 82, 217, 48, 84, 128, 20, 9, 198, 72, 81, 193, 48, 84, 128, 20, 9, 198, 72, 80, 201, 80, 84, 128, 20, 9, 198, 64, 242, 213, 48, 84, 128, 20, 9, 198, 61, 1, 1, 80, 84, 128, 20, 9, 198, 52, 81, 9, 80, 84, 128, 20, 9, 198, 48, 144, 201, 80, 84, 128, 20, 9, 198, 44, 194, 67, 32, 84, 128, 20, 9, 198, 16, 84, 9, 48, 84, 128, 20, 9, 198, 16, 80, 201, 16, 84, 128, 20, 9, 198, 12, 148, 197, 48, 84, 128, 20, 12, 201, 5, 85, 5, 57, 66, 70, 36, 49, 82, 20, 12, 201, 65, 35, 199, 56, 244, 212, 36, 177, 82, 20, 9, 198, 53, 144, 78, 52, 20, 128, 20, 9, 198, 16, 148, 212, 4, 229, 0, 20, 9, 198, 8, 20, 212, 4, 229, 0, 20, 9, 198, 80, 243, 5, 72, 16, 128, 20, 14, 70, 33, 99, 210, 24, 244, 128, 84, 114, 83, 6, 114, 0, 0, 10, 199, 52, 147, 137, 5, 69, 82, 20, 20, 10, 199, 52, 147, 137, 5, 69, 82, 20, 20, 16, 6, 11, 195, 184, 18, 15, 13, 49, 118, 51, 6, 114, 65, 0, 20, 10, 199, 16, 145, 134, 85, 50, 79, 56, 20, 9, 198, 57, 80, 78, 12, 84, 133, 20, 10, 199, 36, 228, 212, 4, 195, 5, 72, 20, 9, 198, 29, 83, 77, 36, 84, 133, 20, 10, 199, 16, 84, 212, 36, 195, 5, 72, 20, 9, 198, 16, 144, 75, 72, 243, 137, 20, 17, 142, 16, 1, 12, 195, 166, 19, 20, 9, 14, 5, 14, 19, 5, 18, 20, 17, 142, 14, 25, 11, 195, 184, 2, 9, 14, 7, 5, 14, 19, 5, 18, 20, 17, 142, 8, 10, 195, 184, 18, 18, 9, 14, 7, 5, 14, 19, 5, 18, 20, 10, 135, 195, 184, 4, 9, 16, 1, 12, 20, 15, 4, 95, 15, 7, 15, 6, 115, 81, 115, 50, 4, 109, 49, 0, 0, 18, 143, 18, 21, 4, 11, 195, 184, 2, 9, 14, 7, 5, 14, 19, 5, 18, 20, 0, 8, 197, 64, 84, 147, 60, 224, 20, 12, 201, 52, 243, 143, 25, 67, 206, 28, 84, 128, 20, 12, 201, 52, 146, 210, 61, 50, 207, 64, 84, 128, 20, 8, 197, 17, 83, 208, 60, 192, 20, 8, 197, 25, 34, 71, 36, 64, 20, 8, 197, 64, 192, 84, 36, 224, 20, 8, 197, 44, 19, 204, 36, 224, 20, 19, 144, 19, 195, 184, 14, 4, 5, 18, 2, 15, 18, 7, 5, 14, 19, 5, 18, 20, 19, 144, 19, 1, 11, 19, 11, 195, 184, 2, 9, 14, 7, 5, 14, 19, 5, 18, 20, 19, 144, 18, 9, 14, 7, 11, 195, 184, 2, 9, 14, 7, 5, 14, 19, 5, 18, 20, 12, 201, 32, 240, 146, 60, 113, 78, 76, 84, 128, 20, 8, 197, 64, 192, 84, 36, 224, 20, 8, 197, 44, 20, 211, 4, 32, 20, 0, 9, 198, 81, 37, 78, 44, 84, 128, 20, 9, 198, 81, 32, 75, 80, 84, 128, 20, 13, 202, 77, 80, 147, 80, 19, 148, 37, 97, 82, 20, 20, 9, 198, 64, 149, 143, 80, 84, 128, 20, 13, 202, 64, 84, 147, 64, 82, 212, 37, 97, 82, 20, 20, 9, 198, 44, 20, 212, 72, 84, 128, 20, 9, 198, 24, 147, 20, 72, 84, 128, 20, 9, 198, 21, 50, 193, 64, 84, 128, 20, 9, 198, 12, 130, 70, 72, 84, 128, 20, 9, 198, 4, 178, 207, 48, 84, 128, 20, 12, 137, 10, 21, 2, 9, 12, 195, 166, 21, 13, 20, 18, 143, 14, 195, 184, 18, 18, 5, 19, 21, 14, 4, 2, 25, 14, 9, 20, 20, 11, 136, 7, 18, 195, 165, 19, 20, 5, 14, 20, 9, 198, 77, 65, 76, 48, 20, 128, 20, 9, 198, 28, 195, 211, 76, 20, 128, 20, 9, 198, 72, 84, 1, 72, 16, 128, 20, 9, 198, 56, 21, 137, 28, 16, 128, 20, 0, 10, 199, 77, 69, 75, 44, 21, 21, 72, 20, 9, 198, 29, 32, 70, 60, 227, 205, 20, 10, 199, 72, 85, 5, 57, 66, 79, 56, 20, 10, 199, 60, 181, 76, 5, 66, 79, 56, 20, 10, 199, 24, 244, 141, 5, 66, 79, 56, 20, 10, 199, 16, 85, 5, 57, 66, 79, 56, 20, 10, 199, 16, 81, 140, 5, 66, 79, 56, 20, 9, 198, 56, 20, 193, 48, 84, 133, 20, 10, 199, 4, 224, 76, 101, 49, 82, 20, 20, 10, 199, 8, 147, 198, 101, 50, 83, 44, 20, 10, 199, 29, 35, 211, 29, 32, 73, 56, 20, 10, 199, 4, 193, 65, 80, 244, 137, 44, 20, 21, 146, 19, 20, 21, 2, 2, 5, 11, 195, 184, 2, 9, 14, 7, 5, 14, 19, 5, 18, 20, 10, 199, 44, 243, 208, 21, 32, 78, 80, 20, 0, 9, 198, 80, 18, 211, 5, 67, 210, 20, 11, 200, 20, 180, 203, 85, 36, 201, 60, 224, 20, 15, 204, 65, 34, 86, 5, 65, 137, 56, 19, 147, 36, 84, 128, 20, 11, 200, 72, 129, 85, 52, 21, 15, 36, 64, 20, 11, 200, 81, 80, 133, 72, 181, 76, 36, 224, 20, 11, 200, 88, 83, 133, 105, 81, 76, 4, 224, 20, 11, 200, 44, 20, 193, 44, 132, 212, 4, 224, 21, 7, 196, 36, 208, 71, 20, 20, 9, 68, 36, 208, 71, 20, 21, 0, 10, 0, 8, 197, 5, 162, 77, 85, 64, 20, 12, 201, 44, 243, 147, 64, 148, 129, 80, 244, 128, 20, 12, 201, 44, 243, 77, 20, 229, 1, 80, 244, 128, 20, 12, 201, 4, 48, 197, 48, 84, 129, 80, 244, 128, 20, 12, 201, 77, 65, 82, 20, 245, 25, 64, 84, 128, 20, 12, 201, 36, 225, 5, 45, 49, 82, 12, 84, 128, 20, 12, 201, 4, 67, 73, 56, 148, 212, 72, 84, 128, 20, 0, 15, 140, 16, 18, 15, 20, 15, 11, 15, 12, 12, 195, 166, 18, 20, 9, 198, 56, 82, 210, 61, 49, 64, 20, 9, 198, 36, 225, 15, 48, 241, 192, 20, 13, 202, 36, 229, 5, 73, 3, 204, 5, 66, 79, 56, 20, 9, 198, 4, 68, 133, 77, 49, 64, 20, 9, 198, 44, 19, 15, 72, 145, 64, 20, 9, 198, 28, 83, 199, 72, 17, 128, 20, 0, 10, 199, 56, 244, 141, 21, 34, 78, 28, 20, 10, 199, 4, 226, 77, 21, 34, 78, 28, 20, 0, 9, 198, 72, 243, 139, 20, 67, 210, 20, 15, 204, 20, 180, 208, 21, 34, 77, 20, 229, 1, 80, 244, 128, 20, 9, 198, 4, 226, 77, 5, 67, 210, 20, 11, 200, 44, 243, 132, 61, 69, 9, 21, 32, 20, 15, 204, 44, 19, 21, 56, 64, 143, 72, 113, 78, 76, 84, 128, 20, 0, 11, 136, 11, 195, 166, 20, 20, 5, 18, 9, 20, 11, 136, 8, 195, 166, 18, 4, 5, 18, 9, 20, 12, 201, 48, 82, 211, 36, 179, 199, 72, 17, 128, 20, 8, 197, 77, 6, 71, 5, 64, 20, 0, 9, 198, 48, 18, 212, 61, 49, 64, 20, 9, 198, 12, 148, 146, 61, 49, 64, 20, 13, 202, 16, 148, 211, 20, 229, 9, 21, 34, 78, 28, 20, 12, 137, 19, 13, 195, 165, 20, 20, 5, 18, 9, 20, 9, 198, 8, 147, 199, 72, 17, 128, 20, 9, 198, 60, 48, 201, 16, 83, 148, 20, 9, 198, 24, 192, 71, 72, 19, 148, 20, 0, 18, 207, 8, 83, 133, 16, 146, 212, 36, 225, 82, 44, 195, 211, 80, 84, 128, 68, 9, 198, 76, 192, 71, 80, 84, 137, 20, 13, 138, 6, 15, 18, 18, 195, 166, 4, 5, 18, 9, 20, 10, 199, 72, 84, 211, 61, 84, 131, 20, 20, 10, 199, 36, 115, 143, 72, 19, 131, 20, 20, 0, 11, 200, 77, 66, 77, 84, 192, 84, 61, 32, 20, 11, 200, 4, 224, 76, 101, 48, 84, 61, 32, 20, 11, 200, 16, 148, 211, 20, 229, 9, 21, 32, 20, 10, 135, 18, 195, 184, 22, 5, 18, 9, 20, 6, 195, 28, 83, 137, 20, 9, 198, 44, 20, 9, 80, 19, 0, 20, 0, 12, 201, 84, 225, 196, 60, 211, 69, 48, 145, 192, 20, 8, 197, 20, 198, 83, 36, 80, 20, 8, 197, 8, 82, 214, 20, 208, 20, 12, 201, 77, 1, 75, 81, 35, 199, 72, 17, 128, 20, 8, 197, 44, 20, 129, 16, 80, 20, 0, 11, 136, 20, 1, 20, 15, 22, 195, 184, 18, 20, 9, 198, 72, 20, 137, 80, 85, 0, 20, 18, 70, 8, 148, 203, 84, 149, 0, 71, 37, 89, 49, 84, 6, 37, 47, 0, 20, 9, 198, 88, 146, 193, 72, 144, 84, 20, 9, 198, 77, 84, 146, 60, 112, 84, 20, 0, 9, 198, 36, 225, 15, 48, 241, 201, 20, 9, 198, 52, 146, 210, 61, 67, 205, 20, 10, 199, 36, 226, 193, 52, 147, 133, 72, 20, 10, 199, 36, 195, 21, 52, 147, 133, 72, 20, 10, 199, 65, 54, 75, 36, 21, 18, 36, 20, 10, 199, 64, 20, 9, 77, 65, 82, 36, 20, 10, 199, 61, 5, 15, 52, 85, 18, 36, 20, 10, 199, 17, 148, 197, 57, 65, 82, 36, 20, 9, 198, 36, 212, 5, 72, 149, 77, 20, 28, 67, 48, 149, 0, 55, 37, 72, 108, 48, 110, 34, 6, 112, 72, 0, 20, 82, 100, 101, 32, 112, 97, 114, 97, 100, 101, 32, 0, 11, 200, 44, 243, 134, 20, 181, 21, 72, 80, 20, 12, 201, 80, 18, 201, 77, 67, 211, 44, 244, 0, 20, 12, 201, 20, 193, 75, 81, 35, 211, 44, 244, 0, 20, 11, 200, 52, 147, 133, 72, 19, 15, 28, 144, 20, 11, 200, 45, 33, 77, 48, 243, 15, 28, 144, 20, 11, 200, 84, 67, 5, 88, 84, 137, 56, 112, 20, 11, 200, 81, 32, 83, 76, 84, 137, 56, 112, 20, 11, 200, 80, 20, 137, 24, 84, 137, 56, 112, 20, 11, 200, 77, 84, 16, 48, 84, 137, 56, 112, 20, 11, 200, 64, 19, 143, 72, 84, 137, 56, 112, 20, 11, 200, 53, 83, 11, 80, 84, 137, 56, 112, 20, 12, 137, 12, 195, 166, 4, 5, 18, 9, 14, 7, 20, 11, 200, 29, 32, 68, 84, 84, 137, 56, 112, 20, 11, 200, 25, 35, 212, 80, 84, 137, 56, 112, 20, 11, 200, 21, 96, 76, 84, 84, 137, 56, 112, 20, 11, 200, 17, 33, 83, 76, 84, 137, 56, 112, 20, 11, 200, 16, 83, 79, 48, 84, 137, 56, 112, 20, 11, 200, 16, 81, 137, 56, 84, 137, 56, 112, 20, 11, 200, 5, 34, 201, 88, 84, 137, 56, 112, 20, 11, 200, 24, 19, 148, 5, 50, 82, 36, 112, 20, 9, 198, 4, 84, 143, 76, 243, 0, 20, 11, 200, 64, 84, 137, 60, 66, 75, 84, 208, 20, 11, 200, 21, 2, 67, 20, 229, 18, 84, 208, 20, 6, 195, 52, 19, 137, 20, 9, 198, 44, 241, 9, 12, 147, 0, 20, 9, 198, 12, 19, 69, 72, 245, 78, 20, 11, 200, 44, 243, 134, 21, 33, 78, 12, 80, 20, 9, 198, 25, 35, 206, 80, 19, 0, 20, 9, 198, 16, 80, 201, 52, 19, 0, 20, 0, 12, 201, 32, 85, 5, 72, 241, 15, 45, 50, 64, 20, 12, 201, 44, 243, 134, 36, 65, 78, 80, 145, 76, 20, 8, 197, 52, 82, 133, 72, 144, 20, 8, 197, 4, 225, 5, 72, 144, 20, 15, 204, 65, 54, 75, 61, 0, 84, 60, 195, 199, 37, 50, 192, 20, 12, 201, 65, 54, 75, 61, 0, 84, 37, 50, 192, 20, 10, 199, 65, 54, 75, 61, 0, 84, 36, 20, 8, 197, 73, 149, 13, 36, 176, 20, 9, 198, 65, 54, 75, 61, 0, 84, 20, 8, 197, 5, 34, 193, 16, 80, 20, 0, 10, 135, 16, 1, 19, 20, 195, 184, 19, 20, 11, 136, 19, 1, 2, 15, 20, 195, 184, 18, 20, 9, 198, 17, 148, 198, 5, 50, 64, 20, 9, 198, 76, 147, 9, 44, 21, 0, 20, 9, 198, 64, 192, 71, 36, 21, 0, 20, 9, 198, 44, 20, 197, 52, 21, 0, 20, 8, 66, 61, 48, 114, 89, 0, 76, 11, 4, 14, 195, 165, 18, 50, 114, 34, 0, 8, 0, 10, 199, 4, 69, 143, 44, 21, 21, 72, 20, 12, 137, 18, 5, 4, 1, 11, 20, 195, 184, 18, 20, 12, 137, 16, 18, 15, 3, 5, 4, 195, 184, 18, 20, 14, 203, 8, 84, 212, 36, 19, 9, 76, 84, 137, 56, 112, 69, 10, 199, 76, 149, 21, 5, 66, 79, 56, 20, 10, 199, 72, 81, 1, 45, 66, 79, 56, 20, 10, 199, 72, 17, 9, 5, 66, 79, 56, 20, 10, 199, 36, 226, 133, 45, 66, 79, 56, 20, 10, 199, 36, 225, 133, 45, 66, 79, 56, 20, 14, 203, 81, 34, 86, 36, 19, 9, 76, 84, 137, 56, 112, 20, 14, 203, 77, 66, 71, 52, 21, 9, 76, 84, 137, 56, 112, 20, 14, 203, 76, 176, 78, 16, 19, 9, 76, 84, 137, 56, 112, 20, 14, 203, 76, 82, 211, 84, 19, 9, 76, 84, 137, 56, 112, 20, 14, 203, 72, 17, 9, 44, 19, 9, 76, 84, 137, 56, 112, 20, 14, 203, 53, 84, 201, 44, 19, 9, 76, 84, 137, 56, 112, 20, 14, 203, 40, 245, 82, 56, 19, 9, 76, 84, 137, 56, 112, 20, 14, 203, 36, 211, 79, 8, 147, 9, 76, 84, 137, 56, 112, 20, 14, 203, 32, 243, 79, 48, 241, 201, 76, 84, 137, 56, 112, 20, 14, 203, 28, 83, 133, 72, 19, 9, 76, 84, 137, 56, 112, 20, 14, 203, 16, 83, 79, 72, 19, 9, 76, 84, 137, 56, 112, 20, 14, 203, 8, 84, 212, 36, 19, 9, 76, 84, 137, 56, 112, 20, 12, 201, 36, 229, 5, 57, 66, 79, 56, 83, 0, 20, 9, 198, 76, 243, 1, 72, 149, 77, 20, 9, 198, 41, 81, 9, 12, 149, 77, 20, 9, 198, 52, 85, 15, 57, 147, 73, 20, 9, 198, 64, 225, 85, 52, 243, 137, 20, 10, 199, 72, 149, 129, 48, 147, 132, 20, 20, 10, 67, 52, 147, 128, 65, 37, 50, 0, 72, 0, 7, 196, 32, 84, 149, 80, 20, 11, 200, 64, 243, 9, 80, 243, 15, 28, 144, 20, 11, 200, 21, 50, 193, 80, 243, 15, 28, 144, 20, 11, 200, 20, 208, 146, 100, 243, 15, 28, 144, 20, 11, 200, 65, 35, 212, 21, 53, 5, 72, 80, 20, 9, 198, 45, 34, 84, 37, 49, 82, 20, 9, 198, 44, 244, 146, 36, 113, 82, 20, 9, 198, 36, 212, 12, 36, 49, 82, 20, 9, 198, 32, 84, 143, 37, 49, 82, 20, 9, 198, 16, 148, 211, 20, 177, 82, 20, 11, 200, 80, 84, 212, 36, 211, 206, 36, 80, 20, 11, 200, 16, 145, 134, 21, 33, 78, 12, 80, 20, 17, 4, 95, 48, 77, 52, 71, 37, 55, 37, 57, 6, 39, 12, 50, 108, 0, 0, 14, 139, 13, 1, 14, 21, 4, 21, 11, 20, 195, 184, 18, 20, 12, 201, 64, 84, 150, 21, 36, 201, 80, 85, 0, 20, 9, 198, 88, 148, 197, 72, 147, 135, 20, 9, 198, 72, 20, 197, 72, 147, 135, 20, 9, 198, 65, 84, 133, 72, 147, 135, 20, 17, 142, 16, 15, 18, 20, 18, 195, 166, 20, 20, 5, 18, 9, 14, 7, 20, 9, 198, 64, 243, 5, 72, 147, 135, 20, 13, 138, 13, 195, 184, 2, 12, 5, 18, 9, 14, 7, 20, 9, 198, 48, 20, 197, 72, 147, 135, 20, 9, 198, 28, 83, 5, 72, 147, 135, 20, 9, 198, 8, 20, 197, 72, 147, 135, 20, 12, 137, 16, 18, 195, 166, 19, 5, 14, 9, 12, 20, 0, 15, 140, 4, 5, 19, 9, 14, 6, 5, 11, 20, 195, 184, 18, 20, 9, 198, 64, 21, 75, 37, 53, 0, 20, 9, 198, 16, 144, 75, 72, 243, 128, 20, 9, 198, 76, 82, 212, 36, 243, 128, 20, 9, 198, 72, 82, 212, 36, 243, 128, 20, 9, 198, 64, 244, 148, 36, 243, 128, 20, 9, 198, 48, 82, 212, 36, 243, 128, 20, 13, 202, 44, 243, 134, 36, 117, 82, 5, 66, 79, 56, 20, 13, 202, 44, 243, 134, 20, 65, 82, 5, 66, 79, 56, 20, 13, 202, 36, 225, 9, 88, 145, 21, 5, 66, 79, 56, 20, 9, 198, 24, 146, 212, 36, 243, 128, 20, 9, 198, 24, 18, 212, 36, 243, 128, 20, 9, 198, 20, 66, 84, 36, 243, 128, 20, 9, 198, 16, 146, 212, 36, 243, 128, 20, 13, 202, 4, 195, 9, 81, 65, 82, 5, 66, 79, 56, 20, 13, 202, 4, 113, 204, 85, 66, 78, 5, 66, 79, 56, 20, 9, 198, 52, 83, 1, 56, 147, 128, 20, 9, 198, 52, 22, 129, 72, 147, 128, 20, 17, 70, 12, 128, 71, 72, 147, 128, 91, 35, 81, 34, 6, 109, 68, 0, 20, 9, 198, 52, 86, 9, 12, 19, 128, 20, 9, 198, 44, 19, 148, 36, 19, 128, 20, 9, 198, 32, 18, 84, 36, 19, 128, 20, 9, 198, 29, 82, 78, 20, 19, 128, 20, 9, 198, 8, 245, 19, 92, 19, 128, 20, 17, 4, 95, 48, 77, 50, 65, 37, 55, 37, 57, 6, 39, 12, 50, 114, 0, 0, 18, 5, 4, 10, 39, 5, 18, 72, 37, 12, 6, 72, 57, 36, 12, 57, 114, 0, 16, 141, 16, 18, 195, 166, 19, 5, 14, 20, 1, 20, 9, 15, 14, 20, 10, 199, 56, 149, 18, 21, 34, 78, 28, 20, 10, 199, 44, 19, 11, 21, 34, 78, 28, 20, 10, 199, 32, 19, 22, 21, 34, 78, 28, 20, 10, 199, 29, 32, 86, 21, 34, 78, 28, 20, 10, 199, 28, 195, 211, 21, 34, 78, 28, 20, 10, 199, 60, 97, 137, 12, 147, 133, 48, 20, 12, 137, 16, 18, 195, 166, 12, 21, 4, 5, 18, 20, 12, 201, 45, 38, 80, 80, 241, 210, 4, 97, 82, 20, 10, 199, 64, 84, 134, 20, 181, 21, 52, 20, 10, 199, 64, 243, 25, 28, 243, 129, 48, 20, 10, 199, 61, 37, 15, 28, 243, 129, 48, 20, 10, 199, 72, 83, 21, 45, 64, 78, 76, 20, 17, 4, 95, 48, 77, 51, 65, 37, 55, 37, 57, 6, 112, 12, 72, 108, 0, 0, 7, 196, 44, 20, 21, 80, 20, 12, 201, 85, 32, 129, 56, 148, 197, 72, 147, 135, 20, 12, 201, 84, 64, 129, 77, 83, 133, 72, 147, 135, 20, 12, 201, 81, 148, 9, 24, 144, 197, 72, 147, 135, 20, 12, 201, 80, 149, 143, 48, 148, 197, 72, 147, 135, 20, 12, 201, 80, 83, 65, 80, 148, 197, 72, 147, 135, 20, 12, 201, 80, 83, 5, 24, 243, 133, 72, 147, 135, 20, 12, 201, 76, 128, 77, 64, 243, 133, 72, 147, 135, 20, 12, 201, 76, 21, 9, 72, 148, 197, 72, 147, 135, 20, 12, 201, 72, 243, 65, 56, 148, 197, 72, 147, 135, 20, 12, 201, 72, 149, 129, 48, 148, 197, 72, 147, 135, 20, 12, 201, 72, 84, 212, 5, 84, 133, 72, 147, 135, 20, 12, 201, 72, 83, 80, 48, 16, 197, 72, 147, 135, 20, 12, 201, 72, 81, 84, 4, 35, 5, 72, 147, 135, 20, 12, 201, 72, 81, 18, 21, 52, 197, 72, 147, 135, 20, 12, 201, 72, 21, 9, 24, 144, 197, 72, 147, 135, 20, 12, 201, 64, 243, 65, 16, 148, 197, 72, 147, 135, 20, 12, 201, 64, 243, 5, 52, 148, 197, 72, 147, 135, 20, 12, 201, 64, 83, 147, 36, 243, 133, 72, 147, 135, 20, 12, 201, 64, 20, 129, 49, 148, 197, 72, 147, 135, 20, 12, 201, 61, 33, 193, 56, 148, 197, 72, 147, 135, 20, 12, 201, 53, 83, 73, 24, 144, 197, 72, 147, 135, 20, 12, 201, 52, 245, 15, 72, 148, 197, 72, 147, 135, 20, 12, 201, 52, 244, 129, 48, 148, 197, 72, 147, 135, 20, 12, 201, 52, 240, 137, 48, 148, 197, 72, 147, 135, 20, 12, 201, 52, 18, 143, 72, 148, 197, 72, 147, 135, 20, 12, 201, 52, 17, 193, 76, 147, 133, 72, 147, 135, 20, 12, 201, 44, 21, 5, 44, 148, 197, 72, 147, 135, 20, 12, 201, 44, 19, 143, 56, 148, 197, 72, 147, 135, 20, 12, 201, 44, 19, 129, 48, 148, 197, 72, 147, 135, 20, 12, 201, 36, 228, 212, 4, 195, 5, 72, 147, 135, 20, 12, 201, 36, 225, 16, 48, 16, 197, 72, 147, 135, 20, 12, 201, 36, 225, 11, 5, 52, 197, 72, 147, 135, 20, 12, 201, 36, 211, 85, 56, 148, 197, 72, 147, 135, 20, 12, 201, 33, 83, 65, 56, 148, 197, 72, 147, 135, 20, 12, 201, 24, 83, 73, 56, 148, 197, 72, 147, 135, 20, 12, 201, 24, 21, 143, 72, 148, 197, 72, 147, 135, 20, 12, 201, 24, 19, 129, 80, 148, 197, 72, 147, 135, 20, 12, 201, 20, 208, 78, 12, 148, 5, 72, 147, 135, 20, 12, 201, 16, 84, 212, 36, 195, 5, 72, 147, 135, 20, 12, 201, 16, 83, 129, 81, 84, 133, 72, 147, 135, 20, 12, 201, 8, 19, 129, 48, 148, 197, 72, 147, 135, 20, 12, 201, 4, 181, 9, 88, 148, 197, 72, 147, 135, 20, 9, 198, 88, 146, 193, 72, 145, 82, 20, 9, 198, 76, 81, 210, 20, 113, 82, 20, 9, 198, 72, 83, 1, 45, 49, 82, 20, 9, 198, 56, 81, 204, 36, 113, 82, 20, 9, 198, 44, 244, 146, 84, 113, 82, 20, 9, 198, 8, 243, 9, 88, 144, 78, 20, 11, 67, 52, 147, 133, 65, 6, 37, 50, 13, 0, 0, 9, 198, 28, 83, 133, 4, 195, 199, 20, 12, 201, 88, 149, 137, 76, 82, 212, 36, 243, 128, 20, 12, 201, 77, 80, 148, 72, 18, 212, 36, 243, 128, 20, 12, 201, 72, 84, 212, 72, 146, 212, 36, 243, 128, 20, 18, 143, 18, 5, 16, 18, 195, 166, 19, 5, 14, 20, 1, 20, 9, 15, 14, 20, 12, 201, 72, 82, 214, 37, 50, 84, 36, 243, 128, 20, 12, 201, 65, 83, 139, 80, 18, 212, 36, 243, 128, 20, 12, 201, 65, 35, 208, 61, 50, 84, 36, 243, 128, 20, 12, 201, 60, 36, 212, 73, 82, 212, 36, 243, 128, 20, 12, 201, 44, 243, 148, 72, 18, 212, 36, 243, 128, 20, 12, 201, 44, 243, 80, 61, 50, 84, 36, 243, 128, 20, 12, 201, 36, 228, 212, 73, 82, 212, 36, 243, 128, 20, 12, 201, 16, 148, 212, 72, 18, 212, 36, 243, 128, 20, 12, 201, 16, 145, 134, 72, 18, 212, 36, 243, 128, 20, 12, 201, 8, 83, 133, 16, 146, 212, 36, 243, 128, 20, 12, 201, 4, 178, 214, 37, 50, 84, 36, 243, 128, 20, 12, 201, 4, 36, 212, 72, 18, 212, 36, 243, 128, 20, 9, 198, 72, 242, 197, 72, 147, 135, 20, 9, 198, 24, 147, 5, 72, 147, 135, 20, 9, 198, 16, 244, 197, 72, 147, 135, 20, 9, 198, 5, 35, 69, 72, 147, 135, 20, 14, 139, 11, 195, 184, 14, 19, 11, 22, 15, 20, 5, 18, 20, 14, 4, 95, 48, 77, 49, 47, 6, 40, 12, 89, 14, 50, 0, 0, 9, 198, 56, 85, 84, 72, 243, 128, 20, 13, 138, 16, 15, 18, 195, 184, 19, 9, 20, 5, 20, 20, 13, 202, 77, 68, 129, 8, 17, 19, 21, 34, 78, 28, 20, 13, 202, 64, 20, 129, 25, 32, 83, 21, 34, 78, 28, 20, 13, 202, 33, 148, 15, 77, 64, 83, 21, 34, 78, 28, 20, 13, 202, 16, 243, 69, 77, 66, 67, 21, 34, 78, 28, 20, 15, 204, 36, 228, 212, 73, 83, 69, 57, 64, 76, 37, 49, 82, 20, 11, 66, 64, 32, 83, 37, 50, 35, 55, 0, 42, 9, 198, 44, 241, 134, 20, 147, 128, 20, 12, 201, 65, 34, 77, 37, 66, 86, 37, 51, 69, 20, 12, 201, 60, 34, 133, 45, 66, 86, 37, 51, 69, 20, 12, 201, 49, 85, 8, 21, 32, 78, 37, 51, 69, 20, 13, 4, 95, 2, 18, 22, 71, 34, 6, 37, 12, 84, 0, 0, 9, 198, 64, 83, 5, 72, 147, 133, 20, 9, 198, 44, 243, 5, 72, 147, 133, 20, 10, 199, 12, 16, 146, 36, 243, 5, 80, 20, 14, 139, 13, 15, 14, 4, 195, 166, 14, 9, 20, 5, 20, 20, 15, 204, 80, 82, 206, 60, 180, 129, 80, 148, 197, 72, 147, 135, 20, 15, 204, 76, 176, 78, 16, 147, 129, 88, 148, 197, 72, 147, 135, 20, 15, 204, 65, 35, 194, 48, 83, 65, 80, 148, 197, 72, 147, 135, 20, 15, 204, 52, 84, 139, 4, 229, 9, 48, 148, 197, 72, 147, 135, 20, 15, 204, 24, 146, 212, 36, 243, 129, 48, 148, 197, 72, 147, 135, 20, 15, 204, 16, 83, 73, 56, 84, 129, 48, 148, 197, 72, 147, 135, 20, 15, 204, 16, 80, 197, 57, 68, 129, 48, 148, 197, 72, 147, 135, 20, 15, 204, 12, 243, 148, 4, 147, 133, 72, 148, 197, 72, 147, 135, 20, 12, 201, 65, 34, 77, 37, 66, 86, 37, 49, 82, 20, 12, 201, 60, 34, 133, 45, 66, 86, 37, 49, 82, 20, 12, 201, 20, 193, 75, 81, 34, 70, 36, 49, 82, 20, 12, 201, 16, 145, 134, 21, 33, 78, 80, 145, 82, 20, 13, 138, 8, 15, 13, 195, 184, 15, 16, 1, 20, 9, 20, 9, 198, 32, 84, 143, 37, 51, 69, 20, 9, 198, 24, 20, 195, 37, 51, 69, 20, 0, 11, 136, 19, 20, 195, 184, 22, 12, 5, 20, 20, 12, 201, 88, 242, 193, 48, 148, 197, 72, 147, 135, 20, 12, 201, 88, 148, 137, 48, 148, 197, 72, 147, 135, 20, 12, 201, 80, 84, 146, 5, 52, 197, 72, 147, 135, 20, 12, 201, 76, 213, 75, 44, 84, 197, 72, 147, 135, 20, 12, 201, 64, 243, 9, 80, 148, 197, 72, 147, 135, 20, 12, 201, 48, 242, 193, 48, 148, 197, 72, 147, 135, 20, 12, 201, 48, 81, 193, 48, 148, 197, 72, 147, 135, 20, 12, 201, 44, 243, 134, 61, 35, 69, 72, 147, 135, 20, 12, 201, 44, 243, 134, 37, 35, 69, 72, 147, 135, 20, 12, 201, 37, 51, 1, 52, 148, 197, 72, 147, 135, 20, 12, 201, 36, 195, 21, 52, 147, 133, 72, 147, 135, 20, 12, 201, 36, 65, 65, 48, 148, 197, 72, 147, 135, 20, 12, 201, 29, 34, 77, 5, 52, 197, 72, 147, 135, 20, 12, 201, 24, 197, 73, 16, 148, 197, 72, 147, 135, 20, 12, 201, 24, 20, 200, 36, 243, 133, 72, 147, 135, 20, 12, 201, 16, 82, 204, 5, 52, 197, 72, 147, 135, 20, 12, 201, 16, 80, 200, 36, 100, 133, 72, 147, 135, 20, 13, 138, 195, 166, 19, 20, 5, 20, 9, 11, 5, 18, 20, 7, 196, 52, 20, 137, 56, 20, 7, 196, 52, 147, 73, 44, 20, 7, 196, 52, 20, 137, 56, 20, 6, 195, 88, 244, 133, 72, 0, 12, 201, 77, 84, 5, 73, 98, 83, 36, 243, 128, 20, 16, 141, 18, 5, 12, 9, 7, 9, 195, 184, 19, 9, 20, 5, 20, 20, 16, 141, 13, 15, 14, 19, 20, 18, 195, 184, 19, 9, 20, 5, 20, 20, 8, 197, 44, 21, 84, 20, 192, 20, 8, 197, 44, 21, 84, 20, 192, 20, 14, 139, 195, 184, 11, 21, 13, 5, 14, 9, 11, 5, 18, 20, 8, 197, 9, 33, 84, 60, 224, 20, 8, 197, 52, 81, 9, 4, 224, 21, 0, 18, 207, 36, 229, 5, 72, 224, 84, 36, 243, 129, 48, 148, 197, 72, 147, 135, 20, 18, 207, 36, 228, 212, 37, 69, 84, 36, 243, 129, 48, 148, 197, 72, 147, 135, 20, 9, 198, 88, 148, 201, 80, 84, 128, 20, 9, 198, 88, 19, 9, 16, 84, 128, 20, 9, 198, 81, 84, 195, 32, 84, 128, 20, 9, 198, 77, 64, 70, 24, 84, 128, 20, 9, 198, 77, 3, 206, 76, 84, 128, 20, 9, 198, 72, 84, 5, 80, 84, 128, 20, 9, 198, 72, 83, 1, 80, 84, 128, 20, 9, 198, 60, 225, 21, 48, 84, 128, 20, 9, 198, 52, 147, 137, 52, 84, 128, 20, 9, 198, 52, 18, 213, 48, 84, 128, 20, 9, 198, 41, 80, 137, 48, 84, 128, 20, 9, 198, 36, 229, 129, 16, 84, 128, 20, 9, 198, 28, 19, 15, 64, 84, 128, 20, 9, 198, 16, 82, 193, 80, 84, 128, 20, 12, 201, 64, 242, 78, 80, 147, 12, 37, 51, 69, 20, 9, 198, 24, 243, 9, 4, 229, 0, 20, 9, 198, 77, 1, 78, 16, 16, 128, 20, 0, 12, 201, 16, 148, 211, 60, 50, 65, 80, 147, 206, 20, 18, 143, 9, 18, 18, 5, 12, 9, 7, 9, 195, 184, 19, 9, 20, 5, 20, 20, 9, 198, 76, 178, 84, 76, 84, 133, 20, 10, 199, 76, 128, 77, 64, 243, 133, 72, 20, 9, 198, 65, 83, 139, 80, 84, 133, 20, 9, 198, 64, 147, 15, 80, 84, 133, 20, 10, 199, 44, 243, 147, 36, 115, 133, 72, 20, 10, 199, 48, 21, 129, 16, 83, 9, 28, 20, 10, 199, 28, 145, 193, 57, 66, 83, 44, 20, 10, 199, 25, 33, 78, 21, 66, 83, 44, 20, 9, 198, 77, 147, 143, 57, 147, 73, 20, 10, 199, 77, 66, 76, 37, 53, 9, 44, 20, 10, 199, 77, 64, 84, 37, 53, 9, 44, 20, 10, 199, 76, 179, 204, 5, 53, 9, 44, 20, 6, 195, 88, 244, 128, 72, 5, 195, 24, 244, 128, 0, 19, 70, 21, 53, 18, 4, 115, 206, 36, 89, 47, 51, 35, 81, 6, 114, 68, 0, 20, 7, 196, 48, 20, 9, 56, 20, 11, 200, 76, 192, 71, 20, 196, 197, 4, 224, 20, 0, 8, 197, 64, 243, 80, 60, 224, 20, 12, 201, 80, 18, 212, 72, 81, 213, 48, 84, 128, 20, 12, 201, 77, 65, 84, 61, 50, 207, 64, 84, 128, 20, 12, 201, 72, 82, 212, 61, 50, 207, 64, 84, 128, 20, 12, 201, 72, 82, 1, 8, 147, 9, 80, 84, 128, 20, 12, 201, 4, 100, 1, 81, 37, 76, 40, 84, 128, 20, 12, 201, 44, 243, 147, 81, 34, 78, 28, 84, 128, 20, 12, 201, 20, 180, 208, 48, 144, 201, 80, 84, 128, 20, 15, 204, 77, 84, 18, 4, 224, 84, 85, 32, 76, 37, 51, 69, 20, 8, 197, 64, 20, 21, 4, 224, 20, 12, 201, 81, 32, 78, 77, 3, 210, 80, 16, 128, 20, 0, 9, 198, 76, 83, 129, 80, 244, 128, 20, 9, 198, 16, 243, 129, 80, 244, 128, 20, 18, 207, 8, 83, 133, 24, 144, 197, 24, 244, 133, 77, 66, 76, 48, 147, 135, 67, 9, 198, 60, 178, 213, 64, 84, 128, 20, 9, 198, 45, 96, 68, 72, 84, 128, 20, 9, 198, 20, 213, 76, 28, 84, 128, 20, 9, 198, 16, 82, 213, 64, 84, 128, 20, 9, 198, 4, 227, 143, 80, 84, 128, 20, 13, 202, 33, 145, 18, 60, 70, 78, 4, 210, 83, 44, 20, 13, 202, 16, 84, 141, 5, 67, 204, 60, 114, 83, 44, 20, 13, 202, 9, 35, 205, 5, 67, 204, 60, 114, 83, 44, 20, 13, 202, 4, 229, 18, 61, 3, 204, 60, 114, 83, 44, 20, 9, 198, 72, 80, 71, 20, 229, 0, 20, 9, 198, 52, 148, 197, 72, 16, 128, 20, 0, 10, 199, 77, 80, 195, 21, 52, 207, 72, 20, 9, 198, 64, 243, 25, 45, 35, 205, 20, 10, 199, 76, 83, 147, 5, 66, 79, 56, 20, 10, 199, 44, 20, 211, 5, 66, 79, 56, 20, 10, 199, 44, 20, 18, 36, 243, 5, 72, 20, 9, 198, 24, 147, 5, 80, 84, 133, 20, 9, 198, 20, 180, 201, 48, 84, 133, 20, 10, 199, 8, 19, 19, 81, 148, 137, 28, 20, 10, 199, 80, 82, 212, 60, 226, 83, 44, 20, 10, 199, 21, 2, 83, 60, 66, 83, 44, 20, 9, 198, 45, 84, 137, 61, 53, 77, 20, 10, 199, 60, 36, 203, 85, 32, 78, 80, 20, 10, 199, 32, 244, 208, 37, 64, 78, 80, 20, 10, 199, 5, 69, 5, 77, 64, 78, 80, 20, 10, 199, 4, 48, 197, 65, 64, 78, 80, 20, 0, 11, 200, 44, 243, 147, 20, 228, 213, 4, 192, 20, 0, 12, 201, 72, 81, 197, 56, 84, 129, 80, 244, 128, 20, 12, 201, 44, 243, 210, 16, 147, 129, 80, 244, 128, 20, 12, 201, 36, 228, 197, 52, 147, 129, 80, 244, 128, 20, 12, 201, 20, 180, 193, 52, 147, 129, 80, 244, 128, 20, 12, 201, 20, 180, 212, 72, 20, 15, 48, 84, 128, 20, 12, 201, 57, 144, 143, 72, 113, 78, 76, 84, 128, 20, 9, 198, 80, 243, 5, 72, 19, 147, 20, 9, 198, 72, 83, 5, 88, 19, 147, 20, 0, 9, 198, 88, 148, 203, 61, 49, 64, 20, 13, 202, 81, 32, 78, 77, 3, 211, 37, 66, 79, 56, 20, 13, 202, 72, 82, 212, 36, 98, 75, 5, 66, 79, 56, 20, 9, 198, 77, 146, 207, 24, 19, 148, 20, 9, 198, 36, 212, 15, 76, 19, 148, 20, 9, 198, 9, 34, 76, 48, 19, 148, 20, 0, 12, 201, 88, 84, 147, 36, 98, 75, 5, 67, 210, 20, 12, 201, 77, 64, 66, 36, 194, 83, 5, 67, 210, 20, 9, 198, 17, 148, 204, 20, 180, 201, 20, 10, 199, 32, 148, 16, 60, 68, 143, 52, 20, 9, 198, 76, 19, 1, 80, 84, 137, 20, 10, 199, 72, 84, 201, 77, 64, 78, 76, 20, 0, 11, 200, 44, 243, 148, 4, 210, 78, 21, 32, 20, 12, 201, 36, 225, 137, 56, 149, 9, 88, 148, 203, 20, 9, 198, 81, 85, 129, 49, 80, 78, 20, 0, 12, 201, 64, 20, 143, 16, 243, 148, 61, 49, 64, 20, 8, 197, 85, 34, 78, 21, 32, 20, 8, 197, 56, 149, 18, 21, 32, 20, 12, 201, 4, 178, 213, 72, 21, 5, 77, 49, 64, 20, 9, 198, 24, 147, 9, 64, 83, 147, 20, 9, 198, 9, 34, 76, 48, 19, 147, 20, 12, 201, 36, 229, 5, 73, 1, 76, 48, 19, 148, 20, 0, 18, 70, 20, 180, 208, 61, 49, 64, 36, 81, 89, 48, 39, 89, 6, 36, 0, 20, 9, 198, 21, 2, 71, 72, 17, 128, 20, 9, 198, 73, 81, 9, 52, 83, 148, 20, 9, 198, 16, 82, 193, 16, 83, 148, 20, 9, 198, 72, 85, 133, 73, 48, 76, 20, 9, 198, 80, 243, 5, 72, 19, 148, 20, 9, 198, 72, 83, 5, 88, 19, 148, 20, 9, 198, 61, 33, 9, 56, 19, 148, 20, 9, 198, 25, 32, 80, 64, 19, 148, 20, 9, 198, 24, 145, 213, 72, 19, 148, 20, 0, 9, 198, 76, 181, 76, 44, 84, 137, 20, 10, 199, 20, 208, 129, 48, 192, 71, 20, 20, 0, 7, 196, 76, 145, 143, 56, 20, 9, 198, 21, 65, 82, 56, 83, 0, 20, 9, 198, 44, 244, 132, 36, 19, 0, 20, 9, 198, 4, 67, 73, 72, 19, 0, 20, 0, 9, 134, 22, 9, 14, 195, 184, 19, 20, 8, 197, 44, 243, 132, 60, 208, 20, 12, 201, 16, 83, 9, 44, 21, 5, 77, 49, 64, 20, 8, 197, 8, 146, 201, 56, 144, 20, 8, 197, 81, 32, 70, 36, 176, 20, 12, 201, 20, 180, 212, 72, 21, 129, 28, 19, 148, 20, 0, 10, 135, 14, 9, 20, 18, 195, 184, 19, 20, 11, 136, 5, 13, 1, 12, 10, 195, 184, 18, 20, 9, 198, 25, 33, 78, 21, 50, 64, 20, 9, 198, 44, 245, 5, 48, 85, 0, 20, 9, 198, 61, 33, 9, 56, 21, 0, 20, 9, 198, 4, 181, 15, 72, 21, 0, 20, 0, 26, 67, 52, 149, 0, 65, 37, 47, 15, 49, 84, 112, 6, 47, 36, 34, 0, 81, 107, 118, 97, 114, 116, 101, 114, 32, 10, 199, 32, 21, 130, 36, 243, 15, 28, 20, 10, 199, 52, 148, 211, 36, 243, 133, 72, 20, 10, 199, 21, 98, 78, 16, 83, 9, 28, 20, 10, 199, 4, 101, 1, 28, 83, 9, 28, 20, 10, 199, 81, 84, 137, 77, 66, 83, 44, 20, 10, 199, 77, 64, 84, 5, 34, 83, 44, 20, 10, 199, 72, 16, 201, 77, 66, 83, 44, 20, 10, 199, 65, 84, 137, 77, 66, 83, 44, 20, 10, 199, 64, 81, 1, 57, 66, 83, 44, 20, 10, 199, 61, 33, 193, 77, 66, 83, 44, 20, 10, 199, 56, 22, 137, 77, 66, 83, 44, 20, 10, 199, 48, 149, 21, 72, 114, 83, 44, 20, 10, 199, 45, 34, 71, 21, 34, 83, 44, 20, 10, 199, 44, 244, 205, 21, 66, 83, 44, 20, 10, 199, 20, 180, 212, 5, 66, 83, 44, 20, 10, 199, 4, 176, 68, 20, 210, 83, 44, 20, 10, 199, 81, 32, 86, 21, 37, 9, 56, 20, 9, 198, 32, 243, 79, 24, 243, 137, 20, 10, 199, 60, 198, 77, 64, 144, 68, 20, 20, 10, 67, 52, 149, 0, 65, 37, 47, 0, 72, 0, 7, 196, 56, 21, 21, 72, 20, 11, 200, 76, 83, 5, 56, 243, 15, 28, 144, 20, 9, 198, 8, 17, 193, 80, 83, 0, 20, 11, 200, 81, 32, 75, 5, 52, 197, 72, 144, 20, 11, 200, 52, 85, 1, 25, 148, 201, 76, 176, 20, 11, 200, 77, 81, 134, 37, 48, 78, 12, 80, 20, 9, 198, 52, 20, 147, 44, 19, 0, 20, 0, 13, 138, 1, 12, 2, 21, 13, 9, 14, 195, 184, 19, 20, 12, 201, 76, 147, 80, 48, 144, 201, 80, 85, 0, 20, 8, 197, 81, 34, 65, 16, 80, 20, 8, 197, 72, 242, 193, 16, 80, 20, 8, 197, 17, 38, 65, 16, 80, 20, 0, 10, 135, 16, 15, 13, 16, 195, 184, 19, 20, 11, 136, 19, 1, 14, 9, 20, 195, 184, 18, 20, 11, 136, 4, 5, 11, 1, 20, 195, 184, 18, 20, 13, 202, 20, 180, 212, 72, 245, 133, 73, 50, 79, 56, 20, 13, 202, 88, 145, 5, 57, 50, 193, 8, 83, 9, 28, 20, 13, 202, 48, 145, 5, 57, 50, 193, 8, 83, 9, 28, 20, 13, 202, 76, 83, 73, 56, 20, 137, 77, 66, 83, 44, 20, 13, 202, 72, 85, 77, 5, 67, 204, 60, 114, 83, 44, 20, 13, 202, 65, 35, 212, 21, 53, 1, 57, 66, 83, 44, 20, 13, 202, 52, 243, 133, 80, 20, 137, 77, 66, 83, 44, 20, 13, 202, 52, 85, 5, 61, 35, 204, 60, 114, 83, 44, 20, 13, 202, 45, 96, 75, 76, 19, 22, 21, 34, 83, 44, 20, 13, 202, 44, 244, 205, 61, 3, 204, 37, 66, 83, 44, 20, 13, 202, 44, 243, 148, 72, 17, 129, 45, 66, 83, 44, 20, 13, 202, 24, 243, 11, 48, 244, 137, 77, 66, 83, 44, 20, 13, 202, 16, 148, 12, 60, 208, 84, 5, 34, 83, 44, 20, 13, 202, 4, 195, 5, 72, 115, 204, 60, 114, 83, 44, 20, 9, 198, 28, 198, 75, 61, 50, 68, 20, 9, 198, 5, 4, 1, 72, 21, 0, 20, 9, 198, 4, 68, 133, 77, 48, 84, 20, 0, 10, 199, 80, 149, 21, 48, 21, 21, 72, 20, 10, 199, 44, 243, 138, 20, 181, 21, 72, 20, 10, 199, 44, 192, 86, 36, 21, 21, 72, 20, 10, 199, 44, 20, 137, 44, 21, 21, 72, 20, 12, 137, 9, 19, 15, 12, 1, 20, 195, 184, 18, 20, 12, 137, 4, 5, 2, 1, 20, 20, 195, 184, 18, 20, 10, 199, 65, 35, 198, 21, 52, 207, 72, 20, 10, 199, 80, 84, 212, 5, 66, 79, 56, 20, 10, 199, 77, 1, 68, 37, 66, 79, 56, 20, 10, 199, 44, 240, 76, 37, 66, 79, 56, 20, 10, 199, 77, 65, 78, 12, 147, 5, 72, 20, 10, 199, 45, 98, 78, 44, 83, 5, 72, 20, 10, 199, 44, 20, 148, 60, 227, 133, 72, 20, 10, 199, 44, 19, 148, 60, 227, 133, 72, 20, 10, 199, 88, 83, 2, 101, 33, 9, 28, 20, 10, 199, 81, 148, 129, 56, 226, 83, 44, 20, 10, 199, 76, 144, 77, 21, 50, 83, 44, 20, 10, 199, 44, 20, 193, 44, 130, 83, 44, 20, 10, 199, 28, 19, 22, 4, 226, 83, 44, 20, 10, 199, 64, 197, 86, 37, 84, 201, 56, 20, 12, 201, 48, 16, 137, 60, 65, 78, 80, 19, 0, 20, 10, 199, 21, 52, 12, 4, 224, 68, 20, 20, 10, 199, 12, 131, 203, 60, 192, 68, 20, 20, 0, 13, 138, 19, 20, 21, 11, 11, 1, 20, 195, 184, 18, 20, 13, 138, 18, 5, 16, 5, 20, 9, 20, 195, 184, 18, 20, 13, 138, 18, 5, 14, 15, 22, 1, 20, 195, 184, 18, 20, 13, 138, 9, 14, 14, 15, 22, 1, 20, 195, 184, 18, 20, 13, 138, 4, 5, 11, 15, 18, 1, 20, 195, 184, 18, 20, 13, 138, 2, 9, 12, 12, 5, 20, 20, 195, 184, 18, 20, 16, 141, 195, 166, 19, 20, 5, 20, 9, 19, 5, 18, 9, 14, 7, 20, 9, 198, 72, 85, 133, 73, 49, 82, 20, 11, 200, 88, 147, 132, 52, 17, 197, 72, 144, 20, 11, 200, 25, 34, 66, 101, 69, 5, 72, 144, 20, 11, 200, 8, 84, 141, 84, 64, 82, 36, 112, 20, 11, 200, 4, 193, 197, 9, 32, 73, 76, 176, 20, 0, 14, 139, 20, 18, 1, 14, 19, 12, 1, 20, 195, 184, 18, 20, 14, 139, 16, 18, 15, 22, 15, 11, 1, 20, 195, 184, 18, 20, 14, 139, 15, 2, 19, 5, 18, 22, 1, 20, 195, 184, 18, 20, 14, 139, 12, 5, 22, 5, 18, 1, 14, 4, 195, 184, 18, 20, 14, 139, 11, 15, 14, 20, 18, 15, 12, 12, 195, 184, 18, 20, 14, 139, 5, 11, 19, 16, 5, 4, 9, 20, 195, 184, 18, 20, 14, 139, 1, 19, 19, 21, 18, 1, 14, 4, 195, 184, 18, 20, 12, 201, 84, 226, 86, 21, 36, 201, 80, 85, 0, 20, 12, 201, 44, 192, 83, 76, 144, 201, 80, 85, 0, 20, 12, 201, 28, 83, 133, 72, 244, 201, 80, 85, 0, 20, 12, 201, 8, 148, 15, 48, 20, 137, 80, 85, 0, 20, 9, 198, 88, 245, 5, 72, 147, 135, 20, 9, 198, 72, 81, 197, 72, 147, 135, 20, 9, 198, 61, 5, 5, 72, 147, 135, 20, 9, 198, 60, 194, 69, 72, 147, 135, 20, 9, 198, 56, 245, 5, 72, 147, 135, 20, 9, 198, 56, 81, 197, 72, 147, 135, 20, 9, 198, 48, 81, 197, 72, 147, 135, 20, 9, 198, 48, 18, 197, 72, 147, 135, 20, 9, 198, 41, 81, 197, 72, 147, 135, 20, 9, 198, 16, 245, 5, 72, 147, 135, 20, 9, 198, 12, 149, 5, 72, 147, 135, 20, 9, 198, 5, 5, 5, 72, 147, 135, 20, 0, 15, 140, 18, 5, 11, 15, 13, 13, 1, 14, 4, 195, 184, 18, 20, 9, 198, 29, 32, 84, 37, 53, 0, 20, 9, 198, 13, 146, 204, 37, 53, 0, 20, 9, 198, 8, 20, 211, 37, 53, 0, 20, 9, 198, 8, 20, 20, 37, 53, 0, 20, 9, 198, 32, 243, 79, 24, 243, 128, 20, 13, 202, 52, 244, 148, 36, 98, 75, 5, 66, 79, 56, 20, 13, 202, 44, 243, 77, 84, 226, 75, 5, 66, 79, 56, 20, 13, 202, 28, 84, 212, 36, 181, 76, 5, 66, 79, 56, 20, 13, 202, 24, 244, 148, 36, 98, 75, 5, 66, 79, 56, 20, 9, 198, 20, 211, 212, 36, 243, 128, 20, 13, 202, 16, 148, 211, 36, 210, 76, 5, 66, 79, 56, 20, 9, 198, 8, 20, 212, 36, 243, 128, 20, 14, 139, 16, 18, 195, 166, 13, 9, 5, 18, 9, 14, 7, 20, 13, 202, 72, 244, 203, 36, 193, 5, 57, 50, 83, 44, 20, 9, 198, 65, 35, 212, 20, 147, 128, 20, 9, 198, 40, 18, 207, 8, 147, 128, 20, 0, 16, 141, 11, 15, 13, 13, 21, 14, 9, 11, 1, 20, 195, 184, 18, 20, 19, 144, 7, 18, 195, 184, 14, 12, 1, 14, 4, 9, 19, 5, 18, 9, 14, 7, 20, 10, 199, 20, 211, 212, 36, 243, 133, 48, 20, 12, 201, 76, 83, 147, 36, 34, 76, 37, 49, 82, 20, 12, 201, 8, 17, 193, 80, 83, 12, 37, 49, 82, 20, 9, 198, 28, 20, 148, 56, 84, 137, 20, 14, 203, 44, 19, 5, 40, 67, 211, 44, 244, 9, 76, 176, 20, 10, 199, 76, 49, 78, 5, 34, 85, 52, 20, 9, 198, 5, 64, 86, 37, 51, 69, 20, 9, 198, 4, 226, 77, 37, 51, 69, 20, 8, 67, 61, 85, 0, 21, 0, 10, 0, 9, 3, 14, 195, 165, 50, 114, 0, 15, 12, 201, 84, 67, 9, 12, 149, 5, 72, 147, 135, 20, 12, 201, 84, 65, 5, 48, 81, 197, 72, 147, 135, 20, 12, 201, 77, 80, 148, 72, 18, 5, 72, 147, 135, 20, 12, 201, 77, 80, 147, 36, 66, 69, 72, 147, 135, 20, 12, 201, 72, 82, 210, 85, 69, 5, 72, 147, 135, 20, 12, 201, 72, 20, 16, 61, 37, 5, 72, 147, 135, 20, 12, 201, 65, 34, 79, 72, 149, 5, 72, 147, 135, 20, 12, 201, 64, 84, 141, 37, 69, 5, 72, 147, 135, 20, 12, 201, 44, 244, 147, 21, 69, 5, 72, 147, 135, 20, 12, 201, 44, 243, 147, 81, 37, 69, 72, 147, 135, 20, 12, 201, 44, 243, 134, 37, 50, 197, 72, 147, 135, 20, 12, 201, 44, 243, 16, 61, 37, 5, 72, 147, 135, 20, 12, 201, 36, 229, 129, 48, 145, 5, 72, 147, 135, 20, 12, 201, 36, 228, 212, 37, 69, 69, 72, 147, 135, 20, 12, 201, 36, 225, 11, 61, 2, 69, 72, 147, 135, 20, 12, 201, 28, 20, 146, 61, 69, 5, 72, 147, 135, 20, 12, 201, 24, 197, 79, 72, 145, 5, 72, 147, 135, 20, 12, 201, 16, 148, 212, 72, 18, 5, 72, 147, 135, 20, 12, 201, 8, 243, 66, 5, 33, 5, 72, 147, 135, 20, 12, 201, 5, 53, 18, 36, 225, 197, 72, 147, 135, 20, 9, 198, 77, 67, 204, 81, 49, 82, 20, 9, 198, 24, 197, 75, 81, 81, 82, 20, 9, 68, 48, 84, 143, 100, 21, 0, 10, 9, 68, 12, 240, 67, 32, 21, 0, 10, 0, 12, 201, 44, 243, 80, 5, 32, 84, 37, 53, 0, 20, 12, 201, 80, 84, 212, 61, 53, 5, 72, 243, 128, 20, 12, 201, 88, 83, 148, 36, 192, 84, 36, 243, 128, 20, 12, 201, 88, 16, 195, 36, 224, 84, 36, 243, 128, 20, 12, 201, 77, 80, 147, 84, 212, 20, 36, 243, 128, 20, 12, 201, 77, 66, 80, 84, 192, 84, 36, 243, 128, 20, 12, 201, 77, 66, 77, 84, 192, 84, 36, 243, 128, 20, 12, 201, 77, 64, 71, 24, 192, 84, 36, 243, 128, 20, 12, 201, 72, 85, 1, 72, 64, 84, 36, 243, 128, 20, 12, 201, 72, 84, 201, 28, 224, 84, 36, 243, 128, 20, 12, 201, 61, 48, 201, 48, 192, 84, 36, 243, 128, 20, 12, 201, 60, 36, 212, 73, 80, 212, 36, 243, 128, 20, 12, 201, 48, 146, 214, 36, 64, 84, 36, 243, 128, 20, 12, 201, 44, 244, 146, 20, 192, 84, 36, 243, 128, 20, 12, 201, 44, 243, 132, 60, 192, 84, 36, 243, 128, 20, 12, 201, 44, 243, 80, 36, 192, 84, 36, 243, 128, 20, 12, 201, 44, 240, 71, 84, 192, 84, 36, 243, 128, 20, 12, 201, 36, 227, 203, 84, 192, 84, 36, 243, 128, 20, 12, 201, 36, 226, 204, 36, 224, 84, 36, 243, 128, 20, 12, 201, 36, 226, 193, 77, 48, 84, 36, 243, 128, 20, 12, 201, 29, 32, 78, 84, 192, 84, 36, 243, 128, 20, 12, 201, 24, 20, 195, 36, 224, 84, 36, 243, 128, 20, 12, 201, 20, 194, 77, 36, 224, 84, 36, 243, 128, 20, 12, 201, 20, 180, 212, 72, 18, 212, 36, 243, 128, 20, 12, 201, 20, 160, 75, 84, 192, 84, 36, 243, 128, 20, 12, 201, 16, 84, 201, 28, 224, 84, 36, 243, 128, 20, 12, 201, 12, 148, 139, 84, 192, 84, 36, 243, 128, 20, 12, 201, 4, 197, 5, 72, 224, 84, 36, 243, 128, 20, 12, 201, 4, 113, 210, 5, 96, 84, 36, 243, 128, 20, 12, 137, 7, 18, 195, 166, 3, 9, 20, 5, 20, 20, 9, 198, 72, 17, 5, 72, 147, 135, 20, 9, 198, 45, 33, 69, 72, 147, 135, 20, 9, 198, 28, 17, 197, 72, 147, 135, 20, 9, 198, 24, 85, 5, 72, 147, 135, 20, 9, 198, 16, 21, 5, 72, 147, 135, 20, 9, 198, 4, 181, 5, 72, 147, 135, 20, 12, 201, 65, 81, 82, 80, 244, 137, 12, 19, 128, 20, 0, 9, 198, 97, 147, 15, 24, 243, 128, 20, 9, 198, 76, 84, 211, 36, 243, 128, 20, 9, 198, 64, 20, 211, 36, 243, 128, 20, 9, 198, 52, 148, 211, 36, 243, 128, 20, 9, 198, 21, 96, 83, 36, 243, 128, 20, 9, 198, 77, 65, 65, 72, 147, 128, 20, 12, 201, 61, 4, 15, 73, 69, 78, 37, 51, 69, 20, 12, 201, 52, 48, 193, 73, 66, 25, 37, 51, 69, 20, 15, 204, 88, 244, 132, 36, 225, 194, 61, 33, 197, 57, 49, 82, 20, 9, 198, 37, 99, 210, 36, 19, 128, 20, 9, 198, 88, 85, 5, 72, 19, 128, 21, 9, 198, 44, 243, 15, 77, 48, 76, 20, 13, 202, 20, 225, 9, 52, 83, 147, 36, 243, 129, 48, 20, 13, 70, 13, 35, 213, 80, 243, 128, 21, 102, 114, 0, 10, 0, 10, 199, 77, 80, 147, 80, 149, 21, 80, 20, 14, 139, 19, 5, 18, 9, 195, 184, 19, 9, 20, 5, 20, 20, 14, 139, 16, 15, 13, 16, 195, 184, 19, 9, 20, 5, 20, 20, 14, 139, 14, 5, 18, 22, 195, 184, 19, 9, 20, 5, 20, 20, 12, 137, 15, 13, 13, 195, 184, 2, 12, 5, 18, 20, 9, 198, 77, 66, 75, 48, 84, 137, 20, 10, 199, 56, 84, 15, 80, 148, 205, 20, 20, 10, 199, 36, 66, 79, 80, 148, 205, 20, 20, 10, 199, 21, 50, 193, 64, 148, 205, 20, 20, 9, 198, 13, 146, 204, 37, 51, 69, 20, 9, 198, 8, 20, 20, 37, 51, 69, 20, 12, 201, 21, 48, 138, 21, 33, 197, 57, 49, 82, 20, 0, 15, 204, 36, 228, 213, 8, 244, 132, 36, 224, 84, 36, 243, 128, 20, 9, 198, 16, 149, 137, 76, 147, 206, 20, 15, 204, 4, 178, 204, 36, 208, 84, 37, 48, 84, 36, 243, 128, 20, 15, 140, 16, 18, 5, 20, 9, 195, 184, 19, 9, 20, 5, 20, 20, 15, 140, 16, 18, 5, 3, 9, 195, 184, 19, 9, 20, 5, 20, 20, 15, 140, 7, 5, 14, 5, 18, 195, 184, 19, 9, 20, 5, 20, 20, 12, 201, 88, 84, 137, 24, 144, 197, 72, 147, 135, 20, 12, 201, 88, 19, 15, 72, 148, 197, 72, 147, 135, 20, 12, 201, 81, 32, 78, 76, 149, 5, 72, 147, 135, 20, 12, 201, 80, 83, 5, 88, 148, 197, 72, 147, 135, 20, 12, 201, 80, 82, 211, 81, 84, 133, 72, 147, 135, 20, 12, 201, 76, 177, 76, 21, 69, 5, 72, 147, 135, 20, 12, 201, 72, 85, 129, 48, 145, 5, 72, 147, 135, 20, 12, 201, 72, 85, 15, 84, 50, 5, 72, 147, 135, 20, 12, 201, 72, 84, 212, 37, 69, 69, 72, 147, 135, 20, 12, 201, 72, 81, 140, 20, 181, 5, 72, 147, 135, 20, 12, 201, 72, 81, 86, 4, 197, 69, 72, 147, 135, 20, 12, 201, 65, 35, 202, 20, 181, 5, 72, 147, 135, 20, 12, 201, 64, 243, 1, 72, 148, 197, 72, 147, 135, 20, 12, 201, 64, 84, 150, 21, 37, 5, 72, 147, 135, 20, 12, 201, 64, 16, 201, 24, 144, 197, 72, 147, 135, 20, 12, 201, 56, 22, 137, 24, 144, 197, 72, 147, 135, 20, 12, 201, 52, 241, 9, 24, 144, 197, 72, 147, 135, 20, 12, 201, 52, 82, 193, 56, 148, 197, 72, 147, 135, 20, 12, 201, 48, 21, 9, 56, 148, 197, 72, 147, 135, 20, 12, 201, 44, 244, 146, 84, 212, 5, 72, 147, 135, 20, 12, 201, 44, 243, 150, 21, 37, 5, 72, 147, 135, 20, 12, 201, 44, 243, 147, 80, 21, 5, 72, 147, 135, 20, 12, 201, 44, 243, 77, 37, 69, 5, 72, 147, 135, 20, 12, 201, 44, 243, 15, 56, 148, 197, 72, 147, 135, 20, 12, 201, 44, 241, 9, 24, 144, 197, 72, 147, 135, 20, 12, 201, 36, 229, 9, 52, 145, 5, 72, 147, 135, 20, 12, 201, 36, 70, 76, 48, 148, 197, 72, 147, 135, 20, 12, 201, 29, 37, 66, 48, 148, 197, 72, 147, 135, 20, 12, 201, 21, 85, 18, 60, 98, 69, 72, 147, 135, 20, 12, 201, 21, 81, 143, 72, 148, 197, 72, 147, 135, 20, 12, 201, 21, 66, 75, 21, 69, 5, 72, 147, 135, 20, 12, 201, 20, 97, 133, 45, 69, 69, 72, 147, 135, 20, 12, 201, 9, 81, 7, 21, 69, 5, 72, 147, 135, 20, 12, 201, 9, 34, 75, 21, 69, 5, 72, 147, 135, 20, 12, 201, 8, 245, 1, 56, 148, 197, 72, 147, 135, 20, 12, 201, 8, 147, 12, 21, 69, 5, 72, 147, 135, 20, 12, 201, 8, 20, 212, 5, 33, 5, 72, 147, 135, 20, 12, 201, 4, 229, 9, 44, 148, 197, 72, 147, 135, 20, 12, 201, 4, 229, 5, 16, 21, 5, 72, 147, 135, 20, 12, 201, 4, 211, 210, 80, 148, 197, 72, 147, 135, 20, 12, 201, 4, 48, 197, 57, 69, 69, 72, 147, 135, 20, 12, 201, 4, 36, 212, 72, 18, 5, 72, 147, 135, 20, 0, 12, 201, 65, 35, 199, 21, 53, 5, 72, 243, 128, 20, 16, 141, 16, 18, 195, 166, 13, 1, 20, 21, 18, 9, 20, 5, 20, 20, 8, 197, 45, 33, 83, 60, 192, 20, 8, 197, 44, 20, 197, 36, 224, 20, 8, 197, 84, 180, 129, 36, 224, 20, 12, 201, 52, 243, 148, 20, 225, 71, 72, 147, 128, 20, 8, 197, 44, 244, 133, 4, 224, 20, 8, 197, 44, 83, 153, 4, 224, 20, 16, 205, 56, 21, 18, 37, 83, 66, 36, 176, 82, 8, 243, 129, 80, 20, 8, 197, 72, 83, 148, 4, 32, 20, 0, 9, 198, 64, 243, 9, 81, 84, 128, 20, 9, 198, 48, 145, 193, 81, 84, 128, 20, 9, 198, 45, 33, 65, 81, 84, 128, 20, 12, 201, 25, 84, 197, 57, 64, 83, 80, 84, 137, 20, 12, 201, 72, 81, 201, 60, 224, 76, 37, 51, 69, 20, 12, 201, 44, 243, 80, 5, 32, 84, 37, 51, 69, 20, 12, 201, 44, 193, 82, 36, 176, 76, 37, 51, 69, 20, 12, 201, 16, 83, 79, 45, 32, 84, 37, 51, 69, 20, 15, 204, 76, 176, 78, 16, 84, 130, 61, 33, 197, 57, 49, 82, 20, 0, 9, 198, 16, 144, 71, 56, 244, 197, 20, 12, 201, 36, 229, 5, 73, 97, 78, 80, 147, 206, 20, 15, 204, 44, 243, 12, 20, 181, 9, 88, 148, 197, 72, 147, 135, 20, 15, 204, 20, 180, 197, 53, 3, 9, 24, 144, 197, 72, 147, 135, 20, 15, 204, 16, 148, 203, 88, 19, 9, 24, 144, 197, 72, 147, 135, 20, 15, 204, 16, 83, 73, 48, 149, 1, 72, 148, 197, 72, 147, 135, 20, 10, 199, 76, 21, 9, 72, 148, 197, 72, 20, 10, 199, 53, 83, 73, 24, 144, 197, 72, 20, 10, 199, 52, 245, 15, 72, 148, 197, 72, 20, 10, 199, 52, 18, 143, 72, 148, 197, 72, 20, 10, 199, 44, 21, 5, 44, 148, 197, 72, 20, 10, 199, 36, 224, 85, 29, 84, 133, 72, 20, 10, 199, 24, 83, 73, 56, 148, 197, 72, 20, 10, 199, 85, 35, 204, 60, 114, 83, 44, 20, 10, 199, 76, 83, 147, 61, 34, 83, 44, 20, 10, 199, 64, 20, 9, 77, 66, 83, 44, 20, 10, 199, 48, 85, 129, 57, 66, 83, 44, 20, 10, 199, 44, 244, 137, 57, 66, 83, 44, 20, 9, 198, 52, 243, 143, 80, 243, 137, 20, 10, 199, 44, 20, 213, 37, 53, 9, 44, 20, 10, 199, 81, 84, 130, 84, 193, 78, 80, 20, 10, 199, 5, 48, 197, 56, 65, 78, 80, 20, 0, 13, 138, 13, 9, 19, 19, 9, 15, 14, 195, 166, 18, 20, 6, 195, 52, 17, 201, 20, 11, 200, 77, 84, 208, 20, 228, 201, 60, 224, 20, 9, 198, 76, 176, 78, 76, 147, 206, 20, 9, 198, 36, 225, 149, 76, 147, 206, 20, 9, 198, 21, 128, 201, 76, 147, 206, 20, 11, 200, 20, 180, 212, 20, 228, 201, 60, 224, 20, 11, 136, 16, 18, 195, 166, 19, 5, 14, 20, 20, 0, 8, 197, 64, 20, 212, 20, 192, 20, 8, 197, 44, 242, 193, 36, 224, 20, 8, 197, 64, 84, 149, 4, 224, 20, 12, 201, 36, 229, 5, 72, 84, 211, 20, 229, 0, 20, 12, 201, 36, 229, 5, 48, 194, 71, 20, 229, 0, 20, 8, 197, 76, 17, 137, 4, 224, 21, 12, 201, 12, 192, 73, 73, 99, 217, 4, 229, 0, 20, 0, 9, 198, 25, 32, 75, 81, 84, 128, 20, 13, 202, 80, 84, 141, 36, 227, 204, 60, 114, 83, 44, 20, 13, 202, 76, 83, 147, 60, 211, 212, 61, 34, 83, 44, 20, 13, 138, 16, 18, 195, 166, 4, 9, 11, 1, 14, 20, 20, 0, 17, 67, 52, 145, 192, 65, 35, 57, 15, 89, 114, 0, 81, 115, 195, 165, 32, 16, 141, 11, 15, 13, 13, 9, 19, 19, 9, 15, 14, 195, 166, 18, 20, 10, 199, 64, 144, 195, 60, 194, 78, 20, 20, 10, 199, 4, 68, 203, 36, 195, 9, 28, 20, 10, 199, 80, 19, 13, 84, 66, 83, 44, 20, 10, 199, 76, 20, 132, 60, 226, 83, 44, 20, 10, 199, 64, 193, 66, 20, 162, 83, 44, 20, 10, 199, 32, 84, 129, 48, 66, 83, 44, 20, 20, 71, 8, 243, 150, 37, 96, 78, 80, 71, 114, 68, 84, 37, 84, 6, 112, 68, 0, 20, 10, 67, 52, 145, 192, 65, 35, 57, 0, 72, 0, 7, 196, 36, 209, 78, 76, 20, 7, 196, 56, 145, 67, 20, 20, 0, 12, 69, 8, 194, 86, 21, 32, 71, 55, 37, 34, 0, 8, 197, 81, 84, 142, 21, 32, 20, 8, 197, 60, 224, 78, 21, 32, 20, 9, 198, 80, 21, 1, 72, 148, 203, 20, 9, 198, 44, 147, 133, 76, 148, 203, 20, 9, 198, 36, 70, 76, 48, 148, 203, 20, 16, 205, 24, 145, 5, 36, 179, 205, 52, 148, 211, 5, 34, 83, 44, 20, 9, 198, 8, 245, 1, 56, 148, 203, 20, 9, 198, 80, 82, 212, 60, 226, 75, 20, 8, 197, 16, 240, 197, 57, 64, 20, 9, 198, 72, 84, 201, 16, 83, 147, 20, 0, 9, 198, 80, 83, 5, 76, 179, 208, 20, 9, 198, 52, 243, 143, 48, 241, 192, 20, 9, 198, 84, 180, 129, 36, 225, 64, 20, 15, 140, 8, 9, 12, 12, 5, 18, 195, 184, 4, 9, 1, 14, 20, 9, 198, 52, 20, 135, 36, 224, 76, 20, 9, 198, 72, 245, 76, 4, 65, 64, 20, 9, 198, 8, 19, 12, 4, 65, 64, 20, 9, 198, 65, 35, 214, 36, 19, 148, 20, 9, 198, 5, 36, 143, 28, 19, 148, 20, 0, 10, 199, 12, 83, 12, 84, 195, 211, 20, 20, 10, 199, 44, 16, 130, 4, 194, 83, 80, 20, 10, 199, 64, 20, 148, 21, 34, 78, 28, 20, 10, 199, 21, 99, 204, 21, 34, 78, 28, 20, 14, 139, 195, 166, 11, 22, 1, 20, 15, 18, 9, 1, 12, 20, 0, 11, 200, 76, 84, 1, 72, 21, 9, 77, 64, 20, 11, 200, 24, 147, 1, 80, 83, 9, 77, 64, 20, 11, 200, 4, 32, 78, 16, 243, 142, 21, 32, 20, 12, 137, 20, 195, 165, 12, 13, 15, 4, 9, 7, 20, 12, 201, 60, 35, 9, 28, 21, 15, 72, 148, 203, 20, 12, 201, 36, 225, 9, 44, 21, 9, 88, 148, 203, 20, 12, 201, 33, 145, 18, 61, 65, 75, 56, 148, 203, 20, 12, 201, 5, 3, 203, 4, 198, 80, 80, 148, 203, 20, 0, 8, 197, 76, 17, 9, 77, 64, 20, 8, 197, 5, 85, 9, 77, 64, 20, 8, 197, 5, 65, 73, 77, 64, 20, 8, 197, 65, 35, 194, 21, 32, 20, 8, 197, 52, 145, 210, 21, 32, 20, 13, 138, 19, 195, 184, 18, 7, 13, 15, 4, 9, 7, 20, 12, 201, 44, 243, 148, 72, 18, 212, 48, 145, 192, 20, 13, 138, 6, 15, 18, 19, 195, 166, 20, 12, 9, 7, 20, 9, 198, 80, 149, 1, 56, 148, 203, 20, 9, 198, 76, 145, 5, 72, 148, 203, 20, 9, 198, 64, 20, 137, 76, 148, 203, 20, 9, 198, 52, 82, 193, 56, 148, 203, 20, 9, 198, 48, 18, 207, 56, 148, 203, 20, 9, 198, 41, 83, 143, 56, 148, 203, 20, 11, 136, 19, 195, 166, 12, 1, 18, 9, 5, 20, 8, 197, 72, 84, 208, 37, 64, 20, 12, 201, 32, 84, 147, 44, 84, 137, 56, 65, 64, 20, 12, 201, 25, 34, 83, 80, 84, 137, 56, 65, 64, 20, 12, 201, 8, 18, 203, 4, 229, 9, 56, 65, 64, 20, 0, 9, 198, 88, 16, 195, 36, 225, 64, 20, 27, 74, 8, 80, 200, 4, 209, 76, 76, 21, 67, 20, 71, 36, 91, 35, 65, 6, 36, 12, 60, 89, 6, 113, 12, 89, 0, 13, 202, 44, 243, 148, 72, 20, 212, 21, 34, 78, 28, 20, 13, 202, 44, 243, 147, 60, 194, 68, 21, 34, 78, 28, 20, 9, 198, 20, 193, 78, 16, 145, 192, 20, 9, 198, 56, 82, 210, 60, 98, 76, 20, 9, 198, 72, 84, 201, 16, 83, 148, 20, 9, 198, 52, 243, 149, 52, 83, 148, 20, 8, 66, 60, 112, 114, 0, 76, 8, 0, 15, 204, 44, 192, 83, 76, 145, 137, 44, 21, 15, 72, 148, 203, 20, 10, 199, 81, 84, 130, 84, 193, 78, 76, 20, 10, 199, 5, 48, 197, 56, 65, 78, 76, 20, 10, 199, 80, 18, 203, 20, 192, 71, 20, 20, 9, 198, 77, 2, 79, 56, 17, 197, 20, 6, 195, 88, 244, 148, 72, 0, 11, 200, 44, 243, 80, 72, 84, 211, 61, 32, 20, 11, 200, 76, 83, 147, 84, 19, 9, 77, 64, 20, 11, 200, 48, 81, 201, 80, 147, 73, 77, 64, 20, 11, 200, 20, 180, 212, 72, 83, 73, 77, 64, 20, 8, 198, 48, 82, 211, 36, 179, 206, 11, 200, 64, 20, 129, 24, 98, 78, 21, 32, 20, 11, 200, 44, 243, 131, 20, 229, 18, 21, 32, 20, 7, 196, 16, 240, 197, 72, 20, 12, 137, 14, 195, 184, 10, 1, 7, 20, 9, 7, 20, 12, 137, 12, 195, 184, 19, 1, 7, 20, 9, 7, 20, 12, 201, 48, 19, 135, 60, 32, 82, 16, 148, 203, 20, 12, 201, 44, 243, 147, 60, 224, 78, 80, 148, 203, 20, 12, 201, 36, 226, 9, 8, 149, 15, 72, 148, 203, 20, 12, 201, 16, 147, 5, 81, 64, 78, 80, 148, 203, 20, 12, 201, 4, 208, 149, 48, 21, 15, 72, 148, 203, 20, 7, 196, 44, 243, 73, 44, 20, 11, 200, 72, 84, 197, 73, 97, 82, 21, 64, 20, 11, 200, 45, 83, 20, 37, 97, 82, 21, 64, 20, 11, 200, 8, 19, 1, 56, 49, 82, 21, 64, 20, 12, 137, 14, 195, 184, 10, 1, 7, 20, 9, 7, 20, 12, 137, 12, 195, 184, 19, 1, 7, 20, 9, 7, 20, 7, 196, 12, 145, 193, 72, 20, 9, 198, 36, 226, 84, 36, 19, 0, 20, 0, 12, 201, 77, 64, 78, 16, 128, 70, 80, 145, 192, 20, 9, 198, 48, 80, 133, 56, 66, 71, 20, 12, 201, 33, 84, 205, 60, 65, 82, 48, 145, 192, 20, 9, 198, 25, 34, 77, 60, 66, 71, 20, 9, 198, 24, 145, 213, 72, 194, 71, 20, 12, 201, 8, 20, 141, 32, 161, 82, 80, 145, 192, 20, 12, 201, 72, 240, 137, 57, 51, 206, 4, 65, 64, 20, 0, 10, 135, 21, 18, 9, 14, 195, 184, 19, 20, 9, 198, 48, 17, 197, 72, 148, 212, 20, 14, 139, 4, 22, 195, 166, 18, 7, 1, 7, 20, 9, 7, 20, 9, 198, 77, 3, 5, 56, 66, 68, 20, 0, 11, 136, 12, 21, 13, 9, 14, 195, 184, 19, 20, 11, 136, 4, 5, 12, 9, 18, 195, 184, 19, 20, 12, 201, 81, 32, 78, 76, 210, 83, 76, 147, 206, 20, 10, 199, 88, 149, 1, 48, 148, 197, 72, 20, 10, 199, 72, 20, 16, 20, 195, 5, 72, 20, 10, 199, 64, 243, 9, 80, 148, 197, 72, 20, 10, 199, 64, 84, 147, 36, 99, 5, 72, 20, 10, 199, 48, 242, 193, 48, 148, 197, 72, 20, 10, 199, 48, 81, 193, 48, 148, 197, 72, 20, 10, 199, 36, 65, 65, 48, 148, 197, 72, 20, 15, 140, 11, 18, 1, 19, 2, 195, 184, 18, 19, 20, 9, 7, 20, 15, 140, 1, 13, 1, 20, 195, 184, 18, 1, 7, 20, 9, 7, 20, 10, 199, 80, 83, 204, 60, 114, 83, 44, 20, 10, 199, 76, 49, 78, 5, 34, 83, 44, 20, 10, 199, 72, 85, 77, 5, 66, 83, 44, 20, 10, 199, 52, 85, 5, 61, 34, 83, 44, 20, 10, 199, 45, 35, 205, 5, 66, 83, 44, 20, 10, 199, 44, 241, 206, 5, 66, 83, 44, 20, 10, 199, 40, 84, 213, 37, 66, 83, 44, 20, 10, 199, 33, 148, 212, 21, 34, 83, 44, 20, 10, 199, 21, 50, 201, 52, 242, 83, 44, 20, 10, 199, 21, 34, 84, 72, 82, 83, 44, 20, 10, 199, 8, 147, 204, 60, 114, 83, 44, 20, 10, 199, 5, 85, 5, 57, 66, 83, 44, 20, 12, 201, 76, 83, 148, 36, 209, 78, 80, 19, 0, 20, 10, 199, 40, 84, 133, 52, 144, 68, 20, 20, 0, 12, 137, 7, 12, 21, 20, 9, 14, 195, 184, 19, 20, 11, 200, 4, 229, 18, 61, 3, 204, 60, 112, 20, 11, 200, 8, 20, 139, 20, 229, 9, 56, 80, 20, 9, 198, 65, 33, 83, 76, 147, 206, 20, 9, 198, 20, 210, 83, 76, 147, 206, 20, 9, 198, 77, 3, 210, 80, 83, 0, 20, 11, 200, 77, 3, 206, 76, 244, 133, 72, 80, 20, 12, 201, 48, 19, 132, 76, 176, 66, 20, 194, 71, 20, 16, 141, 11, 18, 1, 4, 19, 2, 195, 184, 18, 19, 20, 9, 7, 20, 12, 201, 36, 225, 19, 45, 34, 86, 20, 194, 71, 20, 15, 204, 16, 148, 203, 60, 229, 9, 57, 81, 82, 48, 145, 192, 20, 11, 200, 77, 80, 148, 72, 244, 9, 76, 176, 20, 11, 200, 44, 21, 5, 28, 244, 137, 76, 176, 20, 15, 204, 76, 181, 69, 77, 2, 76, 48, 84, 137, 56, 65, 64, 20, 15, 204, 33, 84, 194, 21, 53, 25, 72, 84, 137, 56, 65, 64, 20, 11, 200, 20, 193, 75, 81, 35, 206, 36, 176, 20, 9, 68, 92, 130, 84, 20, 21, 0, 10, 0, 13, 138, 22, 15, 12, 21, 13, 9, 14, 195, 184, 19, 20, 13, 138, 11, 1, 4, 1, 22, 5, 18, 195, 184, 19, 20, 13, 138, 2, 9, 20, 21, 13, 9, 14, 195, 184, 19, 20, 14, 139, 19, 11, 22, 1, 4, 18, 15, 14, 195, 184, 18, 20, 10, 135, 13, 15, 14, 20, 195, 184, 18, 20, 8, 197, 61, 53, 5, 72, 144, 20, 9, 198, 52, 19, 133, 72, 194, 71, 20, 9, 198, 28, 241, 13, 60, 66, 71, 20, 8, 197, 37, 34, 68, 36, 80, 20, 8, 197, 45, 35, 206, 36, 176, 20, 0, 7, 66, 57, 144, 50, 116, 0, 9, 198, 84, 226, 79, 56, 148, 212, 20, 9, 198, 76, 21, 1, 56, 148, 212, 20, 9, 198, 64, 19, 148, 20, 148, 212, 20, 9, 198, 48, 240, 130, 100, 148, 212, 20, 9, 198, 44, 243, 15, 56, 148, 212, 20, 9, 198, 32, 81, 15, 56, 148, 212, 20, 9, 198, 29, 35, 211, 76, 148, 212, 20, 9, 198, 16, 83, 9, 72, 148, 212, 20, 13, 202, 76, 19, 147, 20, 211, 212, 61, 34, 83, 44, 20, 13, 202, 64, 20, 129, 80, 17, 205, 5, 66, 83, 44, 20, 13, 202, 52, 243, 143, 45, 35, 205, 5, 66, 83, 44, 20, 13, 202, 32, 81, 197, 52, 243, 137, 77, 66, 83, 44, 20, 9, 198, 100, 83, 69, 56, 149, 0, 20, 9, 198, 16, 83, 132, 72, 149, 0, 20, 9, 198, 21, 81, 197, 56, 146, 192, 20, 0, 6, 195, 56, 115, 192, 17, 12, 137, 4, 5, 19, 5, 18, 20, 195, 184, 18, 20, 10, 199, 64, 20, 132, 60, 227, 133, 72, 20, 10, 199, 16, 148, 208, 20, 228, 197, 72, 20, 10, 199, 5, 52, 201, 52, 147, 5, 72, 20, 10, 199, 80, 19, 148, 4, 194, 83, 44, 20, 10, 199, 77, 3, 210, 4, 66, 83, 44, 20, 10, 199, 49, 82, 213, 48, 194, 83, 44, 20, 10, 199, 37, 35, 203, 21, 50, 83, 44, 20, 10, 199, 16, 18, 212, 100, 194, 83, 44, 20, 9, 198, 64, 19, 12, 4, 66, 69, 20, 10, 199, 88, 82, 140, 20, 228, 197, 72, 20, 10, 199, 16, 148, 208, 20, 228, 197, 72, 20, 17, 4, 95, 52, 88, 15, 83, 118, 114, 6, 47, 116, 84, 13, 50, 13, 0, 0, 9, 198, 77, 66, 76, 37, 49, 82, 20, 9, 198, 72, 85, 149, 72, 65, 82, 20, 9, 198, 72, 81, 210, 20, 65, 82, 20, 11, 200, 12, 128, 82, 13, 85, 5, 72, 144, 20, 12, 201, 28, 83, 143, 64, 192, 68, 20, 194, 71, 20, 11, 200, 88, 82, 140, 20, 228, 201, 76, 176, 20, 11, 200, 88, 20, 132, 20, 228, 201, 76, 176, 20, 11, 200, 64, 19, 133, 29, 148, 137, 76, 176, 20, 11, 200, 8, 84, 135, 20, 228, 201, 76, 176, 20, 7, 196, 28, 17, 193, 80, 20, 9, 4, 4, 195, 169, 20, 72, 36, 0, 0, 13, 138, 19, 11, 18, 15, 6, 21, 12, 195, 184, 19, 20, 19, 70, 8, 83, 9, 104, 148, 203, 71, 36, 55, 37, 12, 89, 37, 89, 81, 0, 66, 9, 198, 76, 21, 1, 56, 148, 203, 20, 9, 198, 32, 80, 146, 4, 148, 203, 20, 9, 198, 16, 83, 9, 72, 148, 203, 20, 9, 198, 8, 83, 9, 104, 148, 203, 20, 11, 136, 12, 5, 21, 11, 195, 166, 13, 9, 20, 0, 27, 70, 24, 244, 147, 100, 225, 84, 83, 6, 114, 34, 89, 116, 50, 13, 72, 15, 107, 112, 34, 0, 81, 104, 97, 114, 32, 9, 198, 16, 148, 16, 20, 69, 84, 20, 20, 4, 95, 3, 9, 18, 89, 6, 108, 12, 49, 114, 65, 83, 55, 4, 109, 49, 89, 0, 0, 12, 201, 72, 81, 201, 60, 224, 76, 37, 49, 82, 20, 12, 201, 44, 20, 129, 52, 83, 12, 37, 49, 82, 20, 12, 201, 16, 83, 79, 45, 32, 84, 37, 49, 82, 20, 14, 203, 52, 19, 137, 65, 83, 1, 80, 244, 137, 76, 176, 20, 10, 199, 80, 84, 146, 5, 34, 85, 52, 20, 10, 199, 44, 243, 12, 20, 114, 85, 52, 20, 10, 199, 64, 83, 147, 36, 243, 129, 80, 20, 10, 199, 16, 84, 212, 36, 195, 1, 80, 20, 6, 195, 45, 83, 128, 72, 0, 7, 196, 80, 18, 211, 36, 20, 9, 198, 36, 226, 204, 84, 65, 82, 20, 12, 201, 81, 83, 85, 49, 69, 65, 72, 148, 203, 20, 12, 201, 77, 80, 138, 20, 181, 9, 88, 148, 203, 20, 12, 201, 72, 80, 201, 80, 21, 9, 88, 148, 203, 20, 7, 196, 48, 147, 73, 80, 20, 7, 196, 80, 19, 73, 48, 20, 0, 0, 9, 198, 4, 225, 204, 37, 53, 0, 20, 13, 202, 16, 148, 12, 60, 208, 84, 5, 34, 85, 52, 20, 0, 10, 199, 24, 245, 15, 80, 18, 211, 36, 20, 10, 199, 76, 130, 66, 8, 243, 5, 80, 20, 12, 201, 65, 35, 204, 21, 64, 82, 37, 49, 82, 20, 12, 201, 45, 38, 68, 77, 33, 86, 36, 65, 82, 20, 10, 199, 56, 20, 212, 85, 37, 9, 20, 20, 10, 199, 29, 147, 78, 5, 50, 85, 52, 20, 10, 199, 72, 246, 65, 48, 148, 205, 20, 20, 10, 199, 61, 5, 9, 52, 148, 205, 20, 20, 10, 199, 24, 21, 1, 48, 148, 205, 20, 20, 10, 199, 4, 224, 82, 44, 148, 205, 20, 20, 14, 203, 72, 82, 207, 57, 96, 76, 21, 48, 197, 57, 48, 20, 10, 199, 61, 34, 197, 77, 68, 129, 48, 20, 0, 6, 195, 44, 101, 77, 17, 7, 196, 24, 16, 207, 56, 20, 7, 196, 81, 145, 143, 56, 20, 12, 201, 64, 21, 18, 84, 194, 133, 72, 147, 135, 20, 12, 201, 52, 83, 147, 40, 85, 137, 44, 148, 203, 20, 12, 201, 48, 243, 135, 60, 32, 82, 16, 148, 203, 20, 7, 196, 13, 80, 129, 56, 20, 0, 8, 197, 76, 18, 210, 4, 192, 20, 0, 7, 195, 44, 101, 75, 17, 42, 9, 198, 64, 244, 201, 81, 84, 128, 20, 9, 198, 5, 35, 65, 81, 84, 128, 20, 9, 198, 72, 85, 137, 76, 244, 128, 20, 9, 198, 21, 50, 193, 48, 84, 128, 20, 9, 198, 17, 84, 16, 20, 66, 84, 20, 13, 202, 77, 2, 82, 37, 69, 65, 48, 148, 205, 20, 20, 13, 202, 76, 243, 78, 4, 208, 149, 48, 148, 205, 20, 20, 13, 202, 44, 243, 147, 21, 37, 129, 80, 148, 205, 20, 20, 13, 202, 16, 80, 197, 57, 68, 129, 48, 148, 205, 20, 20, 9, 198, 21, 98, 68, 20, 229, 0, 20, 9, 198, 4, 208, 82, 4, 229, 0, 20, 0, 9, 198, 53, 149, 15, 48, 241, 201, 20, 10, 199, 36, 229, 133, 73, 50, 79, 56, 20, 10, 199, 72, 149, 129, 48, 148, 197, 72, 20, 10, 199, 72, 84, 212, 5, 84, 133, 72, 20, 10, 199, 61, 33, 193, 56, 148, 197, 72, 20, 10, 199, 52, 240, 137, 48, 148, 197, 72, 20, 10, 199, 44, 19, 143, 56, 148, 197, 72, 20, 10, 199, 36, 211, 85, 56, 148, 197, 72, 20, 10, 199, 24, 21, 143, 72, 148, 197, 72, 20, 10, 199, 52, 17, 217, 5, 34, 83, 44, 20, 10, 199, 45, 85, 193, 37, 66, 83, 44, 20, 10, 199, 21, 33, 77, 37, 66, 83, 44, 20, 10, 199, 8, 19, 19, 4, 210, 83, 44, 20, 10, 199, 5, 53, 13, 5, 66, 83, 44, 20, 10, 199, 81, 34, 86, 4, 193, 78, 80, 20, 10, 199, 65, 35, 205, 36, 225, 78, 80, 20, 13, 138, 16, 18, 195, 166, 10, 21, 4, 9, 3, 5, 20, 0, 11, 200, 76, 84, 1, 72, 21, 9, 60, 224, 20, 11, 200, 60, 35, 9, 28, 21, 9, 60, 224, 20, 11, 200, 44, 243, 150, 84, 196, 201, 60, 224, 20, 11, 200, 44, 243, 147, 84, 213, 9, 60, 224, 20, 11, 200, 44, 243, 142, 20, 180, 201, 60, 224, 20, 11, 200, 44, 243, 12, 20, 181, 9, 60, 224, 20, 11, 200, 24, 145, 213, 72, 21, 9, 60, 224, 20, 7, 196, 85, 32, 129, 56, 21, 0, 8, 197, 76, 84, 150, 36, 192, 20, 8, 197, 24, 80, 146, 36, 192, 20, 12, 201, 5, 66, 5, 56, 145, 78, 76, 84, 128, 20, 10, 69, 61, 33, 71, 60, 224, 21, 0, 10, 0, 9, 198, 80, 82, 211, 81, 84, 128, 20, 9, 198, 76, 82, 211, 81, 84, 128, 20, 9, 198, 65, 83, 139, 81, 84, 128, 20, 9, 198, 52, 146, 211, 81, 84, 128, 20, 9, 198, 41, 83, 139, 81, 84, 128, 20, 12, 201, 21, 2, 68, 20, 210, 79, 48, 241, 201, 20, 21, 146, 18, 5, 16, 18, 195, 166, 19, 5, 14, 20, 1, 20, 9, 22, 9, 20, 5, 20, 20, 13, 202, 80, 82, 206, 60, 180, 129, 80, 148, 197, 72, 20, 13, 202, 52, 84, 139, 4, 229, 9, 48, 148, 197, 72, 20, 13, 202, 77, 84, 5, 72, 192, 84, 37, 98, 83, 44, 20, 13, 202, 65, 35, 199, 72, 19, 77, 5, 66, 83, 44, 20, 13, 202, 5, 4, 5, 48, 192, 84, 37, 98, 83, 44, 20, 9, 198, 61, 5, 76, 20, 229, 0, 20, 9, 198, 24, 19, 12, 20, 229, 0, 20, 9, 198, 17, 32, 66, 4, 229, 0, 20, 11, 70, 92, 20, 146, 36, 244, 128, 21, 0, 10, 0, 14, 203, 44, 192, 83, 76, 145, 137, 44, 21, 9, 60, 224, 20, 10, 199, 72, 81, 201, 77, 68, 133, 72, 20, 10, 199, 61, 34, 197, 77, 68, 133, 72, 20, 10, 199, 44, 243, 80, 20, 228, 197, 72, 20, 10, 199, 36, 225, 137, 49, 68, 133, 72, 20, 10, 199, 36, 195, 21, 77, 68, 133, 72, 20, 10, 199, 45, 148, 137, 48, 194, 83, 44, 20, 10, 199, 37, 50, 201, 4, 66, 83, 44, 20, 10, 199, 77, 65, 71, 20, 228, 197, 72, 20, 10, 199, 45, 33, 84, 20, 228, 197, 72, 20, 14, 4, 95, 19, 20, 11, 89, 47, 34, 6, 39, 40, 49, 0, 0, 31, 76, 44, 243, 134, 37, 35, 65, 56, 65, 82, 56, 84, 192, 49, 114, 50, 83, 36, 34, 65, 6, 110, 50, 72, 108, 20, 50, 13, 89, 0, 11, 200, 77, 64, 71, 56, 21, 9, 60, 224, 20, 11, 200, 61, 33, 9, 56, 21, 9, 60, 224, 20, 11, 200, 36, 243, 137, 76, 21, 9, 60, 224, 20, 11, 200, 16, 148, 211, 20, 181, 9, 60, 224, 20, 12, 4, 95, 3, 18, 12, 49, 6, 108, 12, 55, 0, 0, 8, 197, 76, 241, 137, 77, 64, 20, 16, 141, 16, 18, 195, 166, 19, 9, 4, 5, 14, 20, 9, 5, 12, 20, 8, 197, 81, 32, 67, 21, 32, 20, 8, 197, 85, 33, 71, 21, 32, 20, 16, 205, 36, 229, 5, 72, 224, 84, 36, 243, 129, 48, 148, 197, 72, 20, 9, 198, 88, 148, 149, 48, 83, 147, 20, 8, 197, 88, 19, 21, 5, 32, 20, 14, 4, 95, 1, 3, 21, 35, 49, 57, 6, 40, 12, 47, 0, 0, 9, 198, 76, 147, 143, 48, 241, 192, 20, 9, 198, 53, 149, 15, 48, 241, 192, 20, 9, 198, 81, 33, 69, 56, 145, 192, 20, 9, 198, 44, 19, 148, 60, 224, 76, 20, 9, 198, 33, 148, 212, 4, 65, 64, 20, 0, 10, 199, 80, 19, 13, 84, 66, 83, 80, 20, 10, 199, 77, 64, 76, 36, 226, 83, 80, 20, 14, 203, 81, 32, 78, 76, 99, 210, 52, 21, 9, 60, 224, 20, 14, 203, 77, 68, 129, 80, 145, 137, 44, 21, 9, 60, 224, 20, 10, 199, 44, 192, 82, 21, 34, 78, 28, 20, 10, 199, 24, 20, 147, 21, 34, 78, 28, 20, 0, 11, 200, 80, 83, 5, 24, 243, 137, 77, 64, 20, 7, 196, 80, 82, 83, 80, 20, 11, 200, 64, 20, 131, 20, 195, 9, 77, 64, 20, 11, 200, 48, 144, 146, 21, 69, 9, 77, 64, 20, 11, 200, 44, 244, 142, 21, 69, 9, 77, 64, 20, 11, 200, 4, 229, 1, 28, 243, 137, 77, 64, 20, 11, 200, 89, 83, 11, 4, 226, 83, 21, 32, 20, 11, 200, 77, 84, 5, 73, 98, 83, 21, 32, 20, 11, 200, 76, 177, 77, 5, 66, 83, 21, 32, 20, 11, 200, 52, 241, 5, 72, 226, 83, 21, 32, 20, 11, 200, 52, 84, 131, 21, 34, 83, 21, 32, 20, 11, 200, 44, 194, 77, 5, 66, 83, 21, 32, 20, 11, 200, 32, 148, 212, 61, 34, 83, 21, 32, 20, 11, 200, 28, 129, 84, 80, 242, 83, 21, 32, 20, 11, 200, 24, 147, 13, 5, 66, 83, 21, 32, 20, 11, 200, 17, 32, 77, 5, 66, 83, 21, 32, 20, 11, 200, 16, 241, 205, 5, 66, 83, 21, 32, 20, 11, 200, 16, 83, 196, 61, 34, 83, 21, 32, 20, 11, 200, 5, 35, 205, 5, 66, 83, 21, 32, 20, 11, 200, 80, 83, 210, 21, 66, 75, 21, 32, 20, 11, 200, 16, 144, 66, 21, 66, 75, 21, 32, 20, 11, 200, 44, 243, 139, 85, 36, 133, 57, 64, 20, 0, 8, 197, 20, 115, 201, 77, 64, 20, 8, 197, 12, 21, 83, 21, 32, 20, 13, 138, 19, 195, 166, 4, 22, 1, 14, 12, 9, 7, 20, 12, 201, 56, 244, 132, 88, 84, 212, 48, 145, 192, 20, 13, 138, 13, 5, 4, 7, 195, 184, 18, 12, 9, 7, 20, 9, 198, 52, 19, 1, 40, 148, 203, 20, 9, 198, 44, 131, 69, 72, 148, 203, 20, 9, 198, 21, 81, 143, 72, 148, 203, 20, 12, 201, 45, 33, 79, 48, 84, 137, 56, 65, 64, 20, 8, 197, 52, 19, 132, 5, 64, 20, 8, 197, 4, 181, 21, 5, 32, 20, 0, 9, 198, 29, 148, 143, 76, 179, 208, 20, 9, 198, 24, 20, 203, 36, 225, 64, 20, 13, 202, 65, 35, 212, 20, 181, 9, 60, 226, 83, 80, 20, 13, 202, 64, 84, 134, 20, 181, 9, 60, 226, 83, 80, 20, 13, 202, 16, 242, 213, 52, 83, 148, 4, 194, 83, 80, 20, 13, 202, 81, 32, 78, 77, 3, 206, 21, 34, 78, 28, 20, 13, 202, 77, 1, 67, 36, 98, 67, 21, 34, 78, 28, 20, 13, 202, 73, 84, 211, 36, 98, 67, 21, 34, 78, 28, 20, 13, 202, 64, 244, 201, 80, 147, 206, 21, 34, 78, 28, 20, 13, 202, 44, 192, 82, 36, 98, 67, 21, 34, 78, 28, 20, 13, 202, 28, 195, 210, 36, 98, 67, 21, 34, 78, 28, 20, 13, 202, 24, 19, 19, 36, 98, 67, 21, 34, 78, 28, 20, 13, 202, 16, 84, 201, 56, 98, 67, 21, 34, 78, 28, 20, 13, 202, 16, 83, 79, 57, 53, 18, 21, 34, 78, 28, 20, 13, 202, 4, 96, 129, 48, 19, 131, 21, 34, 78, 28, 20, 14, 139, 195, 184, 13, 6, 9, 14, 4, 20, 12, 9, 7, 20, 9, 198, 88, 83, 137, 56, 65, 64, 20, 9, 198, 16, 84, 137, 56, 65, 64, 20, 9, 198, 88, 148, 149, 48, 83, 148, 20, 9, 198, 80, 84, 141, 36, 224, 76, 20, 9, 198, 21, 53, 18, 4, 65, 64, 20, 9, 198, 9, 32, 86, 4, 65, 64, 20, 0, 10, 199, 4, 69, 133, 57, 66, 83, 80, 20, 14, 203, 81, 32, 78, 76, 148, 212, 61, 34, 83, 21, 32, 20, 10, 199, 16, 82, 193, 56, 84, 211, 20, 20, 14, 203, 72, 82, 207, 57, 96, 76, 21, 48, 197, 57, 64, 20, 9, 198, 64, 192, 78, 80, 17, 197, 20, 0, 18, 70, 48, 81, 197, 56, 65, 78, 55, 36, 81, 6, 109, 50, 72, 13, 50, 0, 10, 68, 76, 145, 197, 72, 89, 37, 34, 0, 11, 200, 21, 96, 80, 61, 32, 84, 61, 32, 20, 11, 200, 5, 4, 12, 36, 176, 84, 61, 32, 20, 11, 200, 77, 3, 206, 80, 19, 137, 77, 64, 20, 11, 200, 44, 19, 131, 20, 195, 9, 77, 64, 20, 11, 200, 33, 148, 15, 77, 64, 83, 21, 32, 20, 12, 137, 1, 6, 13, 195, 166, 7, 20, 9, 7, 20, 12, 201, 32, 145, 82, 60, 115, 25, 24, 148, 203, 20, 11, 200, 77, 147, 70, 60, 226, 75, 21, 32, 20, 11, 200, 20, 193, 75, 81, 34, 75, 21, 32, 20, 11, 200, 4, 224, 76, 101, 66, 75, 21, 32, 20, 11, 200, 4, 195, 5, 72, 114, 75, 21, 32, 20, 11, 200, 4, 176, 68, 20, 210, 75, 21, 32, 20, 7, 196, 88, 81, 193, 56, 20, 11, 200, 44, 243, 148, 72, 18, 5, 57, 64, 20, 11, 200, 32, 20, 193, 72, 65, 82, 21, 64, 20, 11, 200, 16, 84, 18, 36, 209, 82, 21, 64, 20, 0, 12, 201, 88, 145, 21, 56, 65, 82, 48, 145, 192, 20, 12, 201, 88, 81, 5, 72, 129, 70, 80, 145, 192, 20, 13, 138, 20, 9, 12, 2, 195, 184, 18, 12, 9, 7, 20, 12, 201, 77, 2, 68, 76, 98, 78, 16, 145, 192, 20, 13, 138, 15, 22, 5, 18, 4, 195, 165, 4, 9, 7, 20, 13, 138, 12, 195, 184, 7, 14, 1, 7, 20, 9, 7, 20, 13, 138, 6, 195, 184, 12, 7, 1, 7, 20, 9, 7, 20, 12, 201, 24, 244, 149, 56, 65, 82, 48, 145, 192, 20, 12, 201, 24, 244, 129, 56, 65, 82, 48, 145, 192, 20, 9, 198, 24, 147, 149, 72, 194, 71, 20, 13, 138, 5, 14, 4, 18, 195, 166, 7, 20, 9, 7, 20, 9, 198, 4, 101, 5, 56, 194, 71, 20, 8, 197, 81, 32, 71, 36, 176, 20, 8, 197, 8, 147, 206, 36, 176, 20, 8, 197, 16, 144, 68, 20, 208, 20, 13, 138, 12, 195, 184, 7, 14, 1, 7, 20, 9, 7, 20, 13, 138, 6, 195, 184, 12, 7, 1, 7, 20, 9, 7, 20, 12, 201, 32, 20, 140, 20, 178, 78, 4, 65, 64, 20, 10, 69, 72, 240, 68, 36, 80, 21, 0, 10, 0, 9, 198, 81, 32, 80, 64, 148, 212, 20, 13, 202, 64, 20, 148, 36, 181, 76, 5, 34, 83, 80, 20, 14, 139, 19, 5, 14, 4, 18, 195, 166, 7, 20, 9, 7, 20, 14, 139, 19, 1, 13, 4, 18, 195, 166, 7, 20, 9, 7, 20, 9, 198, 77, 65, 82, 60, 145, 0, 20, 12, 137, 16, 18, 195, 166, 12, 21, 4, 9, 5, 20, 9, 198, 52, 81, 193, 48, 149, 0, 20, 9, 198, 80, 84, 141, 36, 226, 64, 20, 9, 198, 28, 198, 80, 80, 146, 192, 20, 9, 198, 8, 245, 1, 56, 146, 192, 20, 9, 198, 64, 146, 197, 72, 85, 0, 20, 9, 198, 81, 32, 75, 80, 21, 0, 20, 9, 198, 72, 83, 211, 80, 21, 0, 20, 9, 198, 29, 32, 78, 84, 192, 84, 20, 9, 198, 5, 85, 15, 52, 21, 0, 20, 0, 9, 198, 81, 148, 15, 48, 241, 201, 20, 9, 198, 76, 84, 143, 48, 241, 201, 20, 9, 198, 4, 229, 15, 48, 241, 201, 20, 10, 199, 52, 82, 193, 56, 148, 197, 72, 20, 10, 199, 45, 85, 20, 21, 36, 137, 28, 20, 15, 204, 16, 148, 203, 72, 147, 73, 56, 21, 15, 72, 148, 203, 20, 10, 199, 57, 147, 70, 60, 208, 78, 36, 20, 10, 199, 32, 85, 82, 37, 53, 9, 44, 20, 12, 201, 81, 32, 78, 77, 97, 82, 76, 19, 0, 20, 11, 4, 95, 18, 14, 7, 34, 37, 50, 81, 0, 0, 11, 200, 4, 195, 5, 72, 115, 204, 60, 112, 20, 9, 198, 76, 179, 210, 64, 147, 206, 20, 11, 200, 64, 193, 84, 80, 84, 137, 56, 112, 20, 11, 200, 64, 17, 201, 56, 84, 137, 56, 112, 20, 11, 200, 60, 33, 21, 12, 84, 137, 56, 112, 20, 11, 200, 56, 21, 137, 28, 84, 137, 56, 112, 20, 11, 200, 45, 82, 143, 56, 84, 137, 56, 112, 20, 11, 200, 44, 20, 21, 56, 84, 137, 56, 112, 20, 11, 200, 36, 229, 15, 56, 84, 137, 56, 112, 20, 11, 200, 36, 225, 9, 44, 84, 137, 56, 112, 20, 11, 200, 36, 225, 9, 12, 84, 137, 56, 112, 20, 11, 200, 29, 34, 76, 48, 84, 137, 56, 112, 20, 11, 200, 28, 195, 211, 76, 84, 137, 56, 112, 20, 11, 200, 24, 192, 77, 8, 84, 137, 56, 112, 20, 11, 200, 16, 148, 137, 28, 84, 137, 56, 112, 20, 11, 200, 16, 85, 15, 56, 84, 137, 56, 112, 20, 11, 200, 16, 84, 15, 56, 84, 137, 56, 112, 20, 11, 200, 16, 82, 207, 72, 84, 137, 56, 112, 20, 11, 200, 4, 195, 15, 44, 84, 137, 56, 112, 20, 11, 200, 4, 33, 9, 12, 84, 137, 56, 112, 20, 12, 201, 88, 147, 132, 76, 178, 66, 20, 194, 71, 20, 11, 200, 80, 147, 7, 37, 97, 76, 36, 112, 20, 11, 200, 61, 1, 129, 81, 65, 76, 36, 112, 20, 11, 200, 61, 1, 18, 37, 97, 76, 36, 112, 20, 11, 200, 60, 208, 153, 81, 65, 76, 36, 112, 20, 16, 141, 14, 5, 4, 5, 18, 4, 18, 195, 166, 7, 20, 9, 7, 20, 16, 141, 7, 5, 14, 14, 5, 13, 6, 195, 184, 18, 12, 9, 7, 20, 12, 201, 24, 244, 141, 60, 65, 78, 80, 194, 71, 20, 9, 198, 44, 20, 18, 36, 243, 0, 20, 11, 200, 52, 19, 1, 8, 20, 137, 76, 176, 20, 7, 196, 60, 224, 78, 36, 20, 11, 200, 88, 84, 212, 4, 194, 78, 16, 80, 20, 11, 200, 16, 145, 212, 21, 34, 78, 16, 80, 20, 11, 200, 16, 148, 133, 45, 68, 137, 12, 80, 20, 0, 12, 201, 32, 83, 12, 20, 32, 82, 16, 148, 212, 20, 8, 197, 76, 20, 139, 60, 208, 20, 8, 197, 60, 194, 69, 72, 80, 20, 9, 198, 4, 68, 212, 4, 66, 71, 20, 12, 201, 45, 38, 83, 80, 19, 12, 60, 145, 0, 20, 8, 197, 4, 194, 217, 52, 144, 20, 12, 201, 28, 145, 193, 57, 67, 205, 4, 226, 64, 20, 12, 201, 64, 84, 137, 77, 64, 76, 80, 146, 192, 20, 12, 201, 16, 148, 212, 72, 18, 5, 72, 85, 0, 20, 0, 9, 198, 72, 145, 207, 72, 148, 212, 20, 9, 198, 32, 147, 132, 84, 148, 212, 20, 9, 198, 16, 148, 137, 28, 148, 212, 20, 9, 198, 21, 65, 82, 56, 149, 0, 20, 9, 198, 9, 35, 206, 44, 149, 0, 20, 9, 198, 52, 82, 193, 56, 146, 192, 20, 9, 198, 76, 178, 86, 28, 21, 0, 20, 9, 198, 64, 244, 212, 84, 192, 84, 20, 9, 198, 45, 96, 68, 72, 21, 0, 20, 9, 198, 44, 20, 130, 60, 224, 84, 20, 0, 14, 203, 77, 80, 138, 20, 181, 9, 88, 84, 137, 56, 112, 20, 14, 203, 76, 243, 9, 16, 20, 137, 76, 84, 137, 56, 112, 20, 14, 203, 76, 82, 213, 48, 20, 137, 76, 84, 137, 56, 112, 20, 14, 203, 72, 146, 207, 12, 129, 84, 80, 84, 137, 56, 112, 20, 14, 203, 72, 82, 207, 28, 227, 211, 12, 84, 137, 56, 112, 20, 14, 203, 65, 35, 212, 60, 179, 204, 48, 84, 137, 56, 112, 20, 14, 203, 64, 243, 25, 52, 84, 137, 76, 84, 137, 56, 112, 20, 14, 203, 64, 192, 83, 80, 145, 137, 12, 84, 137, 56, 112, 20, 14, 203, 45, 96, 78, 80, 145, 137, 12, 84, 137, 56, 112, 20, 14, 203, 44, 243, 139, 72, 85, 9, 76, 84, 137, 56, 112, 20, 14, 203, 44, 243, 12, 5, 66, 79, 56, 84, 137, 56, 112, 20, 14, 203, 44, 21, 5, 28, 244, 137, 76, 84, 137, 56, 112, 20, 14, 203, 36, 229, 5, 73, 1, 76, 48, 84, 137, 56, 112, 20, 14, 203, 36, 65, 78, 80, 145, 137, 12, 84, 137, 56, 112, 20, 14, 203, 32, 145, 82, 5, 34, 201, 76, 84, 137, 56, 112, 20, 14, 203, 29, 82, 76, 48, 245, 9, 56, 84, 137, 56, 112, 20, 14, 203, 16, 148, 195, 37, 3, 9, 56, 84, 137, 56, 112, 20, 14, 203, 12, 83, 148, 72, 145, 149, 28, 84, 137, 56, 112, 20, 10, 199, 64, 84, 148, 85, 32, 133, 72, 20, 14, 203, 36, 225, 140, 4, 211, 65, 80, 244, 137, 76, 176, 20, 14, 203, 5, 37, 9, 45, 83, 1, 80, 244, 137, 76, 176, 20, 9, 198, 28, 84, 149, 56, 66, 69, 20, 9, 198, 4, 197, 77, 36, 226, 69, 20, 9, 198, 4, 69, 133, 72, 34, 69, 20, 10, 199, 53, 82, 1, 52, 81, 1, 56, 20, 0, 23, 72, 88, 194, 69, 76, 83, 9, 56, 80, 83, 55, 37, 89, 13, 55, 6, 37, 12, 50, 13, 0, 20, 9, 198, 77, 66, 80, 84, 193, 82, 20, 9, 198, 64, 244, 212, 84, 193, 82, 20, 9, 198, 44, 243, 12, 36, 65, 82, 20, 9, 198, 36, 229, 5, 56, 65, 82, 20, 9, 198, 20, 194, 77, 36, 225, 82, 20, 9, 198, 4, 36, 207, 72, 33, 82, 20, 12, 201, 44, 243, 148, 36, 229, 69, 72, 194, 71, 20, 12, 201, 36, 225, 19, 80, 147, 12, 20, 194, 71, 20, 11, 200, 28, 83, 147, 81, 34, 68, 36, 112, 20, 11, 200, 24, 244, 129, 29, 65, 76, 36, 112, 20, 11, 200, 17, 83, 68, 72, 148, 212, 36, 112, 20, 11, 200, 5, 4, 5, 80, 149, 12, 36, 112, 20, 11, 200, 56, 84, 1, 48, 84, 201, 76, 176, 20, 12, 137, 195, 184, 11, 21, 13, 5, 14, 9, 11, 20, 19, 70, 48, 19, 147, 20, 225, 82, 55, 110, 50, 89, 13, 50, 6, 36, 34, 0, 20, 0, 12, 201, 72, 80, 197, 65, 66, 79, 56, 148, 212, 20, 12, 201, 44, 192, 82, 36, 225, 84, 80, 148, 212, 20, 9, 198, 32, 147, 132, 84, 148, 203, 20, 12, 201, 20, 208, 78, 12, 148, 5, 72, 85, 0, 20, 0, 9, 198, 5, 69, 18, 36, 37, 84, 20, 9, 198, 88, 148, 135, 36, 224, 76, 20, 9, 198, 44, 19, 142, 36, 32, 76, 20, 0, 10, 199, 24, 243, 9, 21, 34, 78, 28, 20, 10, 199, 17, 32, 80, 21, 34, 78, 28, 20, 10, 199, 32, 244, 148, 20, 228, 201, 20, 20, 14, 203, 24, 244, 147, 80, 19, 132, 21, 34, 78, 16, 80, 20, 0, 17, 70, 48, 81, 197, 56, 65, 82, 55, 36, 81, 6, 109, 50, 72, 114, 0, 9, 198, 88, 16, 195, 36, 225, 82, 20, 9, 198, 81, 32, 78, 12, 129, 82, 20, 9, 198, 65, 35, 208, 60, 225, 82, 20, 9, 198, 65, 35, 205, 20, 225, 82, 20, 9, 198, 44, 243, 80, 36, 193, 82, 20, 9, 198, 29, 32, 78, 84, 193, 82, 20, 9, 198, 24, 20, 195, 36, 225, 82, 20, 9, 198, 4, 68, 207, 72, 33, 82, 20, 12, 201, 88, 145, 84, 56, 19, 69, 76, 148, 203, 20, 12, 201, 64, 84, 137, 77, 64, 76, 80, 148, 203, 20, 7, 196, 76, 83, 73, 80, 20, 10, 135, 12, 195, 166, 11, 1, 7, 5, 20, 0, 16, 141, 16, 18, 195, 166, 6, 5, 18, 5, 14, 20, 9, 5, 12, 20, 9, 198, 4, 196, 193, 12, 148, 203, 20, 0, 11, 5, 15, 7, 19, 195, 165, 114, 89, 13, 0, 9, 198, 76, 19, 13, 37, 53, 0, 20, 9, 198, 20, 194, 84, 37, 53, 0, 20, 13, 202, 65, 35, 199, 72, 19, 77, 21, 34, 78, 28, 20, 0, 10, 199, 16, 80, 197, 56, 226, 85, 52, 20, 10, 199, 77, 64, 76, 4, 115, 73, 80, 20, 10, 199, 61, 33, 193, 56, 148, 205, 20, 20, 10, 199, 52, 82, 193, 56, 148, 205, 20, 20, 10, 199, 48, 18, 207, 56, 148, 205, 20, 20, 10, 199, 24, 83, 73, 56, 148, 205, 20, 20, 10, 199, 4, 196, 9, 56, 148, 205, 20, 20, 10, 199, 16, 148, 208, 20, 228, 193, 80, 20, 10, 199, 52, 17, 201, 77, 68, 129, 48, 20, 0, 13, 68, 56, 241, 197, 56, 50, 6, 39, 12, 14, 50, 0, 9, 198, 36, 195, 21, 76, 147, 206, 20, 9, 198, 4, 195, 21, 76, 147, 206, 20, 7, 196, 72, 81, 197, 72, 20, 7, 196, 48, 81, 197, 72, 20, 12, 201, 76, 83, 133, 28, 19, 5, 76, 148, 203, 20, 12, 201, 20, 180, 197, 53, 3, 1, 72, 148, 203, 20, 12, 201, 4, 69, 143, 44, 21, 15, 72, 148, 203, 20, 9, 198, 64, 20, 129, 29, 32, 70, 20, 7, 196, 88, 81, 193, 72, 20, 0, 16, 69, 24, 192, 75, 60, 224, 83, 55, 110, 49, 6, 114, 68, 0, 20, 16, 205, 20, 226, 5, 17, 50, 207, 52, 208, 84, 21, 34, 78, 28, 20, 12, 137, 18, 195, 184, 4, 2, 25, 14, 9, 20, 20, 8, 197, 80, 19, 142, 36, 224, 20, 8, 197, 52, 244, 134, 36, 224, 20, 8, 197, 4, 211, 210, 36, 224, 20, 8, 197, 29, 32, 67, 36, 192, 20, 8, 197, 25, 32, 71, 36, 192, 20, 8, 197, 81, 35, 202, 4, 224, 20, 8, 197, 72, 16, 130, 36, 224, 20, 0, 13, 202, 80, 245, 1, 48, 149, 1, 72, 148, 205, 20, 20, 13, 202, 44, 243, 147, 60, 224, 78, 80, 148, 205, 20, 20, 13, 202, 44, 243, 134, 84, 50, 65, 56, 148, 205, 20, 20, 13, 202, 16, 147, 5, 81, 64, 78, 80, 148, 205, 20, 20, 13, 202, 5, 96, 78, 80, 112, 82, 16, 148, 205, 20, 20, 0, 21, 71, 5, 80, 133, 72, 114, 78, 20, 39, 71, 36, 34, 91, 6, 37, 12, 50, 13, 0, 20, 10, 199, 64, 84, 141, 37, 69, 5, 72, 20, 10, 199, 44, 243, 16, 61, 37, 5, 72, 20, 9, 198, 17, 80, 200, 21, 52, 197, 20, 0, 13, 68, 4, 193, 78, 20, 110, 55, 6, 36, 50, 13, 0, 11, 200, 4, 36, 207, 73, 5, 9, 60, 224, 20, 9, 198, 81, 148, 15, 29, 32, 70, 20, 9, 198, 8, 20, 143, 29, 32, 70, 20, 7, 196, 60, 49, 65, 56, 21, 11, 136, 6, 195, 184, 4, 5, 18, 1, 12, 20, 0, 8, 197, 52, 148, 211, 36, 192, 20, 0, 9, 198, 45, 38, 83, 60, 194, 84, 20, 0, 12, 201, 77, 80, 147, 45, 34, 80, 80, 147, 206, 20, 10, 199, 72, 82, 133, 45, 66, 79, 56, 20, 12, 201, 65, 35, 211, 45, 34, 80, 80, 147, 206, 20, 10, 199, 36, 229, 133, 57, 66, 79, 56, 20, 10, 199, 16, 145, 197, 77, 66, 79, 56, 20, 10, 199, 16, 85, 137, 5, 66, 79, 56, 20, 10, 199, 88, 147, 132, 36, 176, 78, 80, 20, 0, 11, 200, 8, 144, 140, 36, 244, 203, 61, 0, 20, 9, 198, 5, 52, 197, 77, 51, 210, 20, 11, 200, 44, 244, 146, 85, 5, 9, 60, 224, 20, 11, 200, 16, 148, 208, 21, 36, 201, 60, 224, 20, 11, 200, 4, 229, 9, 24, 80, 146, 36, 224, 20, 0, 8, 197, 72, 82, 212, 61, 32, 20, 8, 197, 24, 18, 212, 61, 32, 20, 8, 197, 80, 18, 211, 21, 32, 20, 8, 197, 48, 18, 211, 21, 32, 20, 0, 13, 202, 52, 19, 137, 24, 84, 212, 5, 66, 79, 56, 20, 9, 198, 64, 192, 78, 21, 33, 64, 20, 9, 198, 48, 147, 138, 21, 33, 64, 20, 9, 198, 28, 20, 142, 21, 33, 64, 20, 9, 198, 8, 20, 130, 21, 33, 64, 20, 18, 4, 95, 1, 3, 50, 72, 114, 13, 55, 35, 49, 57, 6, 40, 12, 47, 0, 0, 10, 199, 52, 244, 134, 36, 226, 83, 80, 20, 10, 199, 80, 16, 149, 21, 34, 78, 28, 20, 6, 195, 61, 96, 76, 20, 9, 198, 48, 147, 79, 56, 17, 5, 20, 0, 11, 200, 36, 226, 214, 37, 50, 84, 61, 32, 20, 11, 200, 52, 85, 1, 48, 194, 83, 21, 32, 20, 11, 200, 52, 20, 203, 36, 226, 83, 21, 32, 20, 11, 200, 32, 20, 141, 60, 226, 83, 21, 32, 20, 11, 200, 24, 197, 79, 72, 84, 195, 21, 32, 20, 11, 200, 8, 19, 11, 4, 226, 83, 21, 32, 20, 9, 198, 48, 144, 133, 73, 66, 78, 20, 0, 8, 197, 45, 35, 203, 21, 32, 20, 8, 197, 28, 192, 83, 21, 32, 20, 8, 197, 16, 244, 211, 21, 32, 20, 12, 201, 16, 149, 137, 76, 147, 206, 21, 33, 64, 20, 12, 201, 61, 97, 82, 76, 145, 212, 48, 145, 192, 20, 8, 197, 36, 228, 85, 37, 64, 20, 12, 201, 64, 21, 18, 36, 245, 9, 76, 209, 64, 20, 9, 198, 16, 145, 1, 45, 66, 75, 20, 0, 9, 198, 48, 82, 212, 85, 33, 64, 20, 9, 198, 80, 18, 212, 21, 33, 64, 20, 9, 198, 77, 3, 204, 21, 33, 64, 20, 9, 198, 76, 243, 132, 21, 33, 64, 20, 9, 198, 45, 99, 212, 21, 33, 64, 20, 9, 198, 28, 20, 132, 21, 33, 64, 20, 9, 198, 8, 20, 132, 21, 33, 64, 20, 9, 198, 44, 193, 82, 36, 176, 76, 20, 0, 10, 199, 64, 241, 1, 29, 34, 83, 80, 20, 10, 199, 52, 243, 143, 80, 82, 83, 80, 20, 10, 199, 45, 83, 20, 85, 34, 83, 80, 20, 10, 199, 44, 243, 148, 61, 34, 83, 80, 20, 10, 199, 21, 128, 197, 73, 2, 83, 80, 20, 10, 199, 16, 81, 129, 37, 66, 83, 80, 20, 10, 199, 8, 20, 143, 56, 84, 211, 20, 20, 14, 203, 77, 97, 78, 16, 35, 210, 28, 83, 147, 21, 32, 20, 14, 203, 76, 147, 11, 20, 35, 210, 28, 83, 147, 21, 32, 20, 14, 203, 52, 20, 137, 4, 113, 82, 28, 83, 147, 21, 32, 20, 0, 31, 68, 84, 226, 79, 56, 57, 40, 50, 57, 108, 50, 15, 89, 47, 36, 37, 89, 57, 13, 50, 0, 81, 115, 116, 97, 116, 105, 111, 110, 32, 11, 200, 88, 83, 148, 36, 192, 84, 61, 32, 20, 11, 200, 81, 32, 78, 76, 148, 212, 61, 32, 20, 11, 200, 61, 48, 201, 48, 192, 84, 61, 32, 20, 11, 200, 48, 146, 214, 36, 64, 84, 61, 32, 20, 11, 200, 36, 226, 193, 77, 48, 84, 61, 32, 20, 7, 196, 84, 226, 79, 56, 20, 11, 200, 72, 82, 212, 36, 98, 67, 21, 32, 20, 11, 200, 52, 244, 148, 36, 98, 67, 21, 32, 20, 7, 196, 48, 241, 197, 72, 20, 11, 200, 44, 243, 77, 84, 226, 67, 21, 32, 20, 11, 200, 24, 244, 148, 36, 98, 67, 21, 32, 20, 11, 200, 12, 84, 148, 36, 98, 67, 21, 32, 20, 7, 196, 73, 80, 137, 56, 20, 15, 204, 4, 229, 18, 61, 3, 205, 61, 33, 137, 76, 209, 64, 20, 9, 198, 52, 147, 133, 72, 19, 0, 20, 9, 198, 28, 83, 133, 72, 19, 0, 20, 0, 12, 201, 81, 34, 85, 52, 97, 82, 36, 225, 192, 20, 12, 201, 77, 66, 80, 84, 193, 82, 36, 225, 192, 20, 12, 201, 76, 82, 213, 56, 65, 82, 36, 225, 192, 20, 12, 201, 76, 80, 197, 72, 225, 82, 36, 225, 192, 20, 12, 201, 72, 85, 1, 8, 193, 82, 36, 225, 192, 20, 12, 201, 64, 83, 132, 84, 193, 82, 36, 225, 192, 20, 12, 201, 44, 240, 71, 84, 193, 82, 36, 225, 192, 20, 12, 201, 44, 20, 197, 72, 225, 82, 36, 225, 192, 20, 12, 201, 44, 19, 85, 24, 193, 82, 36, 225, 192, 20, 12, 201, 36, 227, 203, 84, 193, 82, 36, 225, 192, 20, 12, 201, 32, 20, 131, 20, 193, 82, 36, 225, 192, 20, 12, 201, 20, 194, 77, 36, 225, 82, 36, 225, 192, 20, 12, 201, 16, 85, 1, 12, 129, 82, 36, 225, 192, 20, 12, 201, 12, 148, 139, 84, 193, 82, 36, 225, 192, 20, 12, 201, 4, 36, 207, 72, 33, 82, 36, 225, 192, 20, 12, 201, 44, 21, 1, 65, 83, 20, 21, 33, 64, 20, 12, 201, 25, 32, 71, 52, 83, 148, 21, 33, 64, 20, 12, 201, 8, 19, 132, 21, 35, 204, 21, 33, 64, 20, 15, 140, 195, 166, 19, 20, 5, 20, 9, 3, 9, 19, 13, 5, 20, 8, 197, 45, 84, 129, 28, 80, 20, 0, 9, 198, 48, 21, 9, 56, 148, 212, 20, 9, 198, 44, 243, 15, 72, 148, 212, 20, 9, 198, 8, 18, 83, 76, 148, 212, 20, 9, 198, 73, 81, 134, 21, 34, 64, 20, 9, 198, 40, 240, 130, 21, 34, 64, 20, 9, 198, 28, 20, 150, 21, 34, 64, 20, 9, 198, 76, 18, 211, 37, 50, 192, 20, 9, 198, 37, 64, 76, 37, 50, 192, 20, 9, 198, 32, 84, 143, 37, 50, 192, 20, 9, 198, 33, 145, 18, 61, 130, 68, 20, 9, 198, 77, 147, 70, 60, 226, 64, 20, 9, 198, 16, 84, 137, 88, 21, 0, 20, 9, 198, 4, 69, 143, 44, 21, 0, 20, 5, 131, 239, 187, 191, 0, 6, 195, 53, 34, 64, 17, 11, 136, 19, 16, 1, 20, 9, 195, 184, 19, 20, 12, 137, 9, 14, 20, 5, 18, 9, 195, 184, 18, 20, 9, 198, 76, 147, 143, 48, 241, 201, 20, 9, 198, 24, 243, 143, 48, 241, 201, 20, 10, 199, 64, 16, 201, 24, 144, 197, 72, 20, 10, 199, 44, 243, 15, 56, 148, 197, 72, 20, 10, 199, 36, 70, 76, 48, 148, 197, 72, 20, 10, 199, 20, 180, 208, 61, 37, 5, 72, 20, 10, 199, 8, 245, 1, 56, 148, 197, 72, 20, 9, 198, 8, 18, 212, 21, 34, 69, 20, 9, 198, 32, 84, 130, 5, 34, 69, 20, 0, 12, 137, 1, 13, 2, 9, 20, 9, 195, 184, 19, 20, 11, 200, 25, 32, 83, 20, 243, 15, 28, 144, 20, 15, 204, 84, 67, 65, 81, 34, 75, 84, 193, 82, 36, 225, 192, 20, 15, 204, 77, 80, 150, 20, 229, 9, 60, 225, 82, 36, 225, 192, 20, 15, 204, 65, 35, 208, 61, 37, 9, 60, 225, 82, 36, 225, 192, 20, 11, 200, 45, 98, 84, 80, 84, 137, 56, 112, 20, 11, 200, 40, 243, 137, 76, 84, 137, 56, 112, 20, 9, 198, 64, 20, 148, 36, 83, 0, 20, 7, 196, 80, 83, 210, 36, 20, 11, 200, 32, 84, 148, 84, 113, 76, 36, 112, 20, 9, 198, 52, 85, 1, 56, 243, 0, 20, 11, 200, 45, 33, 84, 20, 228, 201, 76, 176, 20, 11, 200, 52, 83, 79, 72, 19, 132, 84, 208, 20, 11, 200, 45, 33, 83, 80, 243, 65, 80, 144, 20, 20, 68, 12, 129, 67, 44, 47, 57, 109, 49, 6, 37, 50, 0, 44, 20, 81, 105, 110, 32, 11, 200, 45, 96, 68, 72, 241, 143, 56, 144, 20, 11, 200, 89, 83, 7, 5, 34, 83, 52, 80, 20, 11, 200, 88, 246, 69, 85, 34, 83, 52, 80, 20, 11, 200, 77, 2, 82, 37, 66, 83, 52, 80, 20, 11, 200, 76, 84, 137, 4, 194, 83, 52, 80, 20, 11, 200, 76, 82, 212, 21, 34, 83, 52, 80, 20, 11, 200, 72, 243, 65, 57, 66, 83, 52, 80, 20, 11, 200, 65, 34, 86, 5, 66, 83, 52, 80, 20, 11, 200, 60, 178, 213, 49, 66, 83, 52, 80, 20, 11, 200, 52, 19, 137, 21, 34, 83, 52, 80, 20, 11, 200, 8, 20, 130, 5, 34, 83, 52, 80, 20, 11, 200, 77, 147, 132, 21, 34, 78, 16, 80, 20, 7, 196, 77, 81, 1, 56, 20, 7, 196, 77, 81, 1, 56, 21, 9, 198, 72, 17, 9, 44, 19, 0, 20, 0, 12, 201, 44, 244, 205, 21, 67, 204, 60, 114, 64, 20, 12, 201, 21, 99, 204, 85, 66, 79, 56, 148, 212, 20, 8, 197, 4, 180, 201, 60, 208, 20, 14, 139, 4, 5, 6, 195, 166, 11, 1, 20, 9, 15, 14, 20, 9, 198, 16, 83, 1, 29, 66, 71, 20, 12, 201, 77, 147, 80, 5, 65, 84, 37, 50, 192, 20, 12, 201, 65, 35, 212, 61, 70, 80, 37, 50, 192, 20, 12, 201, 56, 84, 15, 80, 148, 212, 37, 50, 192, 20, 12, 201, 52, 85, 15, 16, 148, 212, 37, 50, 192, 20, 12, 201, 52, 84, 143, 88, 147, 135, 37, 50, 192, 20, 12, 201, 45, 144, 133, 72, 225, 84, 37, 50, 192, 20, 12, 201, 32, 84, 146, 56, 133, 84, 37, 50, 192, 20, 12, 201, 12, 243, 135, 60, 193, 83, 37, 50, 192, 20, 12, 201, 12, 86, 76, 60, 225, 83, 37, 50, 192, 20, 12, 201, 5, 3, 208, 48, 82, 212, 37, 50, 192, 20, 12, 201, 4, 224, 75, 60, 197, 84, 37, 50, 192, 20, 8, 197, 80, 81, 5, 84, 208, 20, 6, 195, 85, 34, 78, 20, 8, 197, 8, 145, 193, 52, 144, 20, 12, 201, 65, 35, 204, 21, 64, 82, 36, 21, 0, 20, 9, 198, 16, 83, 1, 29, 66, 71, 20, 0, 9, 198, 64, 16, 201, 24, 148, 212, 20, 14, 139, 8, 195, 165, 14, 4, 20, 5, 18, 9, 14, 7, 20, 9, 198, 53, 149, 20, 21, 34, 64, 20, 9, 198, 53, 148, 132, 21, 34, 64, 20, 9, 198, 48, 81, 140, 21, 34, 64, 20, 9, 198, 44, 243, 9, 9, 34, 64, 20, 9, 198, 24, 145, 140, 21, 34, 64, 20, 9, 198, 8, 20, 130, 5, 34, 64, 20, 9, 198, 76, 20, 6, 37, 50, 192, 20, 9, 198, 52, 244, 193, 37, 50, 192, 20, 9, 198, 5, 32, 66, 37, 50, 192, 20, 9, 198, 45, 84, 5, 72, 85, 0, 20, 9, 198, 4, 180, 143, 8, 21, 0, 20, 0, 10, 199, 12, 83, 148, 85, 34, 79, 56, 20, 15, 140, 16, 18, 195, 166, 3, 9, 19, 5, 18, 9, 14, 7, 20, 14, 203, 12, 83, 148, 72, 19, 9, 76, 84, 137, 56, 112, 20, 10, 199, 44, 243, 139, 49, 81, 5, 72, 20, 10, 199, 5, 4, 12, 5, 81, 5, 72, 20, 14, 203, 33, 145, 18, 60, 83, 5, 45, 68, 137, 76, 176, 20, 9, 198, 56, 82, 212, 5, 34, 69, 20, 14, 203, 76, 17, 15, 52, 20, 207, 12, 130, 83, 52, 80, 20, 14, 203, 65, 35, 214, 36, 228, 201, 4, 194, 83, 52, 80, 20, 14, 203, 52, 19, 20, 33, 84, 201, 4, 226, 83, 52, 80, 20, 14, 203, 44, 243, 77, 84, 226, 84, 5, 34, 83, 52, 80, 20, 14, 203, 24, 192, 71, 20, 195, 1, 57, 66, 83, 52, 80, 20, 14, 203, 9, 84, 133, 5, 82, 210, 5, 66, 83, 52, 80, 20, 14, 203, 9, 32, 78, 16, 84, 201, 4, 226, 83, 52, 80, 20, 14, 203, 5, 34, 83, 80, 242, 210, 5, 66, 83, 52, 80, 20, 24, 4, 95, 53, 88, 15, 107, 110, 55, 47, 16, 6, 109, 89, 36, 50, 89, 47, 116, 84, 13, 50, 13, 0, 0, 9, 198, 80, 20, 212, 5, 69, 82, 20, 9, 198, 77, 68, 137, 45, 69, 82, 20, 13, 138, 16, 18, 15, 10, 5, 11, 20, 195, 184, 18, 20, 13, 138, 11, 15, 14, 4, 21, 11, 20, 195, 184, 18, 20, 11, 200, 60, 67, 206, 80, 243, 15, 28, 144, 20, 11, 200, 60, 49, 65, 56, 243, 15, 28, 144, 20, 11, 200, 24, 83, 73, 56, 243, 15, 28, 144, 20, 16, 141, 195, 166, 11, 22, 9, 22, 1, 12, 5, 18, 9, 14, 7, 20, 9, 198, 52, 20, 141, 61, 33, 82, 20, 9, 198, 29, 32, 84, 84, 193, 82, 20, 9, 198, 20, 180, 208, 60, 225, 82, 20, 9, 198, 20, 180, 201, 77, 65, 82, 20, 9, 198, 16, 148, 208, 60, 225, 82, 20, 11, 200, 77, 145, 22, 21, 53, 12, 36, 112, 20, 11, 200, 61, 4, 21, 77, 65, 76, 36, 112, 20, 18, 70, 9, 83, 12, 21, 66, 78, 71, 116, 55, 13, 47, 6, 109, 68, 0, 20, 11, 200, 45, 38, 80, 80, 241, 193, 52, 144, 20, 9, 198, 5, 81, 213, 77, 66, 78, 20, 7, 196, 72, 81, 193, 48, 20, 7, 196, 36, 65, 65, 48, 20, 0, 12, 201, 44, 243, 12, 20, 181, 9, 88, 148, 212, 20, 14, 139, 16, 18, 195, 166, 19, 20, 1, 20, 9, 15, 14, 20, 12, 201, 72, 17, 134, 36, 224, 68, 21, 34, 64, 20, 12, 201, 97, 147, 15, 29, 32, 70, 37, 50, 192, 20, 12, 201, 96, 84, 143, 29, 32, 70, 37, 50, 192, 20, 12, 201, 81, 148, 15, 29, 32, 70, 37, 50, 192, 20, 12, 201, 80, 244, 15, 29, 32, 70, 37, 50, 192, 20, 12, 201, 80, 243, 79, 29, 32, 70, 37, 50, 192, 20, 12, 201, 80, 83, 5, 29, 32, 70, 37, 50, 192, 20, 12, 201, 77, 84, 5, 73, 51, 206, 37, 50, 192, 20, 12, 201, 65, 148, 143, 80, 82, 206, 37, 50, 192, 20, 12, 201, 61, 37, 15, 29, 32, 70, 37, 50, 192, 20, 12, 201, 56, 243, 79, 29, 32, 70, 37, 50, 192, 20, 12, 201, 53, 83, 20, 36, 85, 14, 37, 50, 192, 20, 12, 201, 52, 243, 143, 29, 32, 70, 37, 50, 192, 20, 12, 201, 48, 149, 15, 29, 32, 70, 37, 50, 192, 20, 12, 201, 45, 38, 79, 80, 82, 206, 37, 50, 192, 20, 9, 198, 44, 243, 5, 72, 148, 203, 20, 12, 201, 44, 83, 73, 29, 32, 70, 37, 50, 192, 20, 12, 201, 36, 65, 79, 29, 32, 70, 37, 50, 192, 20, 12, 201, 32, 243, 15, 29, 32, 70, 37, 50, 192, 20, 12, 201, 24, 245, 15, 29, 32, 70, 37, 50, 192, 20, 12, 201, 24, 243, 143, 29, 32, 70, 37, 50, 192, 20, 12, 201, 21, 67, 143, 29, 32, 70, 37, 50, 192, 20, 12, 201, 16, 83, 79, 29, 32, 70, 37, 50, 192, 20, 12, 201, 8, 20, 143, 52, 85, 18, 37, 50, 192, 20, 12, 201, 5, 85, 15, 29, 32, 70, 37, 50, 192, 20, 12, 201, 9, 84, 133, 5, 82, 210, 5, 66, 64, 20, 9, 198, 77, 147, 70, 60, 226, 75, 20, 6, 195, 37, 32, 78, 20, 0, 9, 198, 80, 131, 205, 37, 53, 0, 20, 9, 198, 56, 18, 86, 37, 65, 84, 20, 12, 201, 16, 242, 213, 52, 83, 148, 5, 34, 69, 20, 9, 198, 56, 244, 141, 4, 227, 128, 20, 9, 198, 8, 18, 203, 4, 224, 76, 20, 0, 10, 199, 64, 20, 211, 21, 34, 78, 28, 20, 10, 199, 25, 32, 83, 21, 34, 78, 28, 20, 10, 199, 9, 37, 78, 21, 34, 78, 28, 20, 10, 199, 8, 195, 203, 21, 34, 78, 28, 20, 14, 203, 20, 101, 5, 73, 68, 153, 44, 177, 76, 36, 112, 20, 12, 201, 20, 115, 195, 20, 229, 18, 36, 177, 82, 20, 16, 141, 19, 11, 195, 166, 12, 19, 11, 195, 184, 18, 9, 1, 14, 20, 0, 9, 198, 81, 37, 66, 4, 69, 82, 20, 7, 196, 20, 193, 71, 36, 20, 9, 198, 77, 84, 16, 60, 225, 82, 20, 9, 198, 72, 82, 214, 37, 33, 82, 20, 9, 198, 72, 81, 149, 56, 65, 82, 20, 9, 198, 52, 243, 5, 77, 65, 82, 20, 9, 198, 12, 130, 75, 4, 225, 82, 20, 9, 198, 4, 227, 133, 45, 65, 82, 20, 9, 198, 4, 178, 214, 37, 33, 82, 20, 12, 201, 85, 53, 82, 64, 21, 15, 72, 148, 203, 20, 12, 201, 76, 82, 83, 52, 243, 15, 28, 148, 203, 20, 12, 201, 52, 243, 9, 56, 243, 15, 28, 148, 203, 20, 15, 204, 44, 147, 133, 52, 21, 15, 29, 32, 70, 37, 50, 192, 20, 15, 204, 32, 148, 212, 61, 34, 79, 29, 32, 70, 37, 50, 192, 20, 7, 196, 80, 147, 73, 16, 20, 9, 198, 64, 244, 212, 20, 194, 78, 20, 9, 198, 32, 20, 140, 20, 178, 78, 20, 9, 198, 20, 225, 15, 45, 34, 78, 20, 11, 70, 72, 80, 197, 37, 97, 82, 21, 0, 10, 0, 9, 198, 5, 53, 18, 60, 195, 199, 20, 12, 201, 76, 147, 85, 49, 64, 78, 37, 65, 84, 20, 12, 201, 72, 80, 197, 65, 66, 86, 37, 65, 84, 20, 12, 201, 65, 34, 77, 37, 66, 86, 37, 65, 84, 20, 12, 201, 60, 34, 133, 45, 66, 86, 37, 65, 84, 20, 12, 201, 20, 97, 133, 45, 66, 86, 37, 65, 84, 20, 9, 198, 36, 65, 78, 80, 148, 203, 20, 9, 198, 21, 81, 197, 56, 148, 203, 20, 9, 198, 76, 83, 73, 61, 66, 75, 20, 0, 9, 198, 20, 112, 76, 37, 65, 84, 20, 13, 202, 80, 82, 206, 36, 98, 67, 21, 34, 78, 28, 20, 18, 143, 6, 195, 184, 4, 5, 18, 1, 12, 9, 19, 5, 18, 9, 14, 7, 20, 13, 202, 5, 85, 15, 44, 192, 86, 21, 34, 78, 28, 20, 0, 9, 198, 52, 243, 143, 29, 32, 77, 20, 9, 198, 36, 65, 79, 29, 32, 77, 20, 12, 137, 18, 195, 166, 19, 15, 14, 14, 5, 18, 20, 10, 199, 80, 245, 5, 52, 148, 205, 20, 20, 10, 199, 64, 19, 148, 20, 148, 205, 20, 20, 10, 199, 32, 81, 15, 56, 148, 205, 20, 20, 10, 199, 4, 192, 137, 56, 148, 205, 20, 20, 10, 199, 52, 17, 201, 77, 68, 129, 80, 20, 0, 12, 201, 72, 81, 140, 20, 181, 15, 72, 148, 203, 20, 12, 201, 44, 243, 77, 37, 52, 193, 72, 148, 203, 20, 12, 201, 16, 149, 137, 56, 21, 15, 72, 148, 203, 20, 7, 196, 44, 19, 73, 44, 20, 9, 198, 24, 243, 143, 29, 32, 70, 20, 0, 8, 197, 12, 149, 18, 60, 224, 20, 12, 201, 36, 225, 129, 57, 66, 76, 37, 65, 84, 20, 8, 197, 76, 19, 79, 4, 224, 20, 12, 201, 16, 148, 212, 36, 225, 214, 21, 33, 84, 20, 0, 13, 202, 53, 82, 1, 52, 81, 1, 56, 148, 205, 20, 20, 13, 202, 52, 84, 139, 4, 229, 9, 48, 148, 205, 20, 20, 13, 202, 37, 51, 204, 5, 66, 79, 56, 148, 205, 20, 20, 0, 17, 70, 8, 84, 131, 21, 84, 197, 71, 109, 34, 89, 118, 12, 89, 0, 66, 10, 199, 72, 84, 208, 60, 225, 5, 72, 20, 10, 199, 64, 148, 149, 21, 69, 5, 72, 20, 10, 199, 16, 148, 12, 60, 208, 84, 36, 20, 10, 199, 5, 85, 15, 45, 32, 84, 36, 20, 12, 201, 24, 195, 206, 20, 195, 15, 29, 32, 70, 20, 10, 199, 76, 82, 213, 56, 64, 78, 80, 20, 10, 199, 72, 81, 21, 56, 64, 78, 80, 20, 0, 11, 200, 36, 229, 5, 72, 97, 82, 60, 224, 20, 9, 198, 81, 34, 76, 48, 147, 206, 20, 9, 198, 4, 64, 80, 80, 147, 206, 20, 15, 204, 65, 35, 208, 61, 37, 9, 60, 224, 76, 37, 65, 84, 20, 11, 200, 5, 84, 212, 72, 19, 9, 20, 224, 20, 9, 198, 76, 84, 137, 29, 32, 70, 20, 11, 200, 64, 20, 129, 16, 242, 211, 4, 192, 20, 0, 15, 140, 19, 20, 195, 184, 11, 9, 15, 13, 5, 20, 18, 9, 20, 8, 197, 64, 84, 19, 36, 224, 20, 16, 205, 36, 229, 5, 72, 224, 84, 36, 243, 129, 48, 148, 205, 20, 20, 8, 197, 24, 148, 211, 36, 192, 20, 12, 201, 36, 229, 5, 72, 97, 82, 20, 228, 192, 20, 10, 2, 195, 151, 81, 6, 35, 68, 36, 0, 0, 13, 202, 45, 34, 77, 36, 224, 76, 37, 53, 9, 44, 20, 0, 10, 199, 81, 32, 86, 21, 53, 5, 72, 20, 10, 199, 64, 84, 147, 37, 53, 5, 72, 20, 10, 199, 44, 242, 78, 12, 145, 5, 72, 20, 10, 199, 20, 180, 212, 73, 81, 5, 72, 20, 17, 4, 95, 19, 13, 3, 89, 65, 6, 113, 12, 55, 49, 4, 35, 48, 0, 5, 130, 196, 141, 43, 0, 11, 200, 80, 83, 132, 20, 229, 9, 20, 192, 20, 11, 200, 80, 19, 135, 20, 229, 9, 20, 192, 20, 0, 8, 197, 88, 243, 20, 21, 32, 20, 8, 197, 64, 19, 16, 21, 32, 20, 8, 197, 20, 213, 76, 21, 32, 20, 9, 198, 16, 243, 69, 77, 66, 75, 20, 8, 197, 72, 16, 137, 5, 64, 20, 0, 13, 202, 36, 225, 9, 77, 3, 211, 37, 66, 79, 56, 20, 9, 198, 73, 82, 78, 21, 33, 64, 20, 9, 198, 20, 193, 86, 21, 33, 64, 20, 0, 9, 198, 72, 85, 9, 72, 17, 5, 20, 9, 198, 48, 83, 79, 56, 17, 5, 20, 0, 19, 5, 6, 46, 5, 11, 19, 83, 114, 36, 81, 89, 36, 65, 48, 13, 55, 0, 25, 11, 200, 52, 21, 18, 36, 181, 76, 21, 32, 20, 11, 200, 8, 20, 146, 36, 176, 68, 21, 32, 20, 12, 201, 88, 20, 207, 52, 245, 15, 72, 148, 203, 20, 12, 201, 8, 243, 19, 40, 85, 137, 44, 148, 203, 20, 9, 198, 56, 82, 212, 5, 34, 78, 20, 9, 198, 48, 148, 9, 105, 160, 78, 20, 15, 140, 195, 166, 11, 22, 9, 4, 9, 19, 20, 1, 14, 20, 20, 0, 8, 197, 77, 64, 84, 85, 32, 20, 12, 201, 64, 244, 201, 80, 147, 206, 21, 33, 64, 20, 8, 197, 61, 134, 68, 21, 32, 20, 8, 197, 61, 130, 68, 21, 32, 20, 8, 197, 52, 21, 20, 21, 32, 20, 8, 197, 37, 51, 204, 21, 32, 20, 12, 201, 25, 83, 139, 80, 147, 206, 21, 33, 64, 20, 12, 201, 25, 32, 75, 80, 147, 206, 21, 33, 64, 20, 8, 197, 21, 2, 76, 21, 32, 20, 12, 201, 4, 208, 137, 80, 147, 206, 21, 33, 64, 20, 8, 197, 24, 244, 141, 5, 64, 20, 8, 197, 37, 51, 194, 5, 32, 20, 14, 2, 194, 167, 48, 35, 34, 35, 81, 34, 6, 35, 83, 0, 0, 15, 66, 76, 80, 89, 36, 15, 89, 114, 0, 81, 115, 195, 165, 32, 9, 198, 8, 244, 132, 85, 33, 64, 20, 9, 198, 76, 245, 80, 21, 33, 64, 20, 9, 198, 76, 244, 148, 21, 33, 64, 20, 9, 198, 64, 20, 148, 21, 33, 64, 20, 9, 198, 9, 35, 196, 21, 33, 64, 20, 9, 198, 84, 49, 78, 81, 32, 76, 20, 9, 198, 36, 229, 5, 29, 32, 76, 20, 11, 70, 88, 83, 148, 85, 33, 64, 21, 0, 10, 6, 194, 60, 208, 76, 28, 0, 9, 198, 56, 19, 143, 29, 32, 77, 20, 10, 199, 81, 34, 83, 80, 84, 211, 20, 20, 10, 199, 36, 229, 5, 72, 84, 211, 20, 20, 10, 199, 72, 81, 21, 56, 64, 78, 76, 20, 12, 137, 18, 195, 166, 19, 15, 14, 14, 1, 2, 20, 10, 2, 194, 165, 57, 6, 36, 50, 12, 0, 0, 11, 200, 80, 83, 80, 21, 32, 84, 85, 32, 20, 11, 200, 48, 149, 20, 21, 32, 84, 85, 32, 20, 12, 201, 40, 245, 82, 56, 19, 9, 77, 66, 75, 20, 10, 2, 194, 162, 89, 6, 36, 50, 47, 0, 0, 9, 134, 15, 4, 9, 195, 184, 19, 20, 10, 135, 8, 15, 14, 14, 195, 184, 18, 20, 10, 135, 6, 18, 9, 19, 195, 184, 18, 20, 12, 201, 88, 17, 193, 8, 243, 132, 21, 33, 64, 20, 12, 201, 44, 243, 150, 60, 197, 84, 21, 33, 64, 20, 12, 201, 44, 243, 148, 72, 20, 212, 21, 33, 64, 20, 12, 201, 16, 242, 213, 52, 83, 148, 21, 33, 64, 20, 12, 201, 5, 33, 213, 52, 83, 148, 21, 33, 64, 20, 8, 197, 21, 81, 143, 72, 144, 20, 8, 197, 53, 84, 197, 84, 208, 20, 8, 197, 80, 82, 83, 52, 80, 20, 8, 197, 16, 82, 83, 52, 80, 20, 8, 197, 85, 48, 78, 12, 80, 20, 9, 2, 194, 163, 48, 40, 50, 19, 0, 0, 10, 135, 22, 9, 19, 11, 195, 184, 19, 20, 10, 135, 19, 5, 18, 9, 195, 184, 19, 20, 9, 198, 80, 20, 129, 57, 65, 76, 20, 9, 198, 76, 194, 66, 21, 34, 64, 20, 9, 198, 76, 192, 86, 21, 34, 64, 20, 9, 198, 56, 20, 146, 21, 34, 64, 20, 9, 198, 44, 226, 66, 21, 34, 64, 20, 9, 198, 28, 224, 86, 21, 34, 64, 20, 9, 198, 24, 20, 150, 21, 34, 64, 20, 9, 198, 48, 20, 16, 37, 50, 192, 20, 9, 198, 20, 193, 71, 37, 50, 192, 20, 9, 198, 28, 20, 129, 57, 66, 64, 20, 9, 198, 72, 83, 133, 28, 21, 0, 20, 9, 198, 24, 245, 15, 77, 64, 84, 20, 9, 198, 12, 83, 147, 61, 32, 84, 20, 9, 198, 5, 69, 5, 57, 64, 84, 20, 9, 198, 4, 197, 77, 56, 21, 0, 20, 0, 12, 137, 11, 15, 8, 195, 166, 19, 9, 15, 14, 20, 10, 199, 36, 229, 5, 57, 50, 79, 56, 20, 10, 199, 16, 149, 133, 73, 50, 79, 56, 20, 10, 199, 52, 19, 137, 13, 84, 133, 72, 20, 10, 199, 44, 243, 148, 36, 229, 69, 72, 20, 10, 199, 44, 21, 15, 48, 144, 197, 72, 20, 10, 199, 5, 69, 18, 36, 37, 69, 72, 20, 12, 201, 77, 83, 6, 5, 66, 65, 104, 243, 0, 20, 9, 198, 80, 84, 146, 5, 34, 69, 20, 10, 199, 44, 20, 140, 40, 242, 1, 56, 21, 0, 11, 200, 8, 245, 82, 28, 83, 201, 76, 144, 20, 11, 200, 44, 20, 146, 61, 52, 197, 72, 144, 20, 11, 200, 80, 147, 12, 4, 65, 76, 36, 112, 20, 11, 200, 77, 3, 9, 16, 17, 212, 36, 112, 20, 11, 200, 52, 148, 213, 56, 65, 76, 36, 112, 20, 11, 200, 4, 229, 133, 56, 65, 76, 36, 112, 20, 11, 200, 77, 144, 129, 72, 149, 9, 76, 176, 20, 11, 200, 37, 51, 1, 52, 149, 9, 76, 176, 20, 11, 200, 33, 145, 201, 20, 163, 137, 76, 176, 20, 11, 200, 32, 19, 147, 20, 21, 9, 76, 176, 20, 11, 200, 5, 34, 201, 52, 81, 9, 76, 176, 20, 11, 200, 4, 229, 1, 72, 181, 9, 76, 176, 20, 11, 200, 4, 193, 129, 8, 85, 9, 76, 176, 20, 11, 200, 4, 180, 143, 52, 21, 9, 76, 176, 20, 11, 200, 76, 178, 90, 60, 100, 133, 56, 144, 20, 11, 200, 81, 35, 212, 76, 178, 83, 52, 80, 20, 11, 200, 77, 147, 12, 60, 114, 83, 52, 80, 20, 11, 200, 76, 130, 78, 80, 242, 83, 52, 80, 20, 11, 200, 56, 83, 204, 60, 114, 83, 52, 80, 20, 11, 200, 28, 19, 12, 36, 50, 83, 52, 80, 20, 11, 200, 20, 180, 207, 72, 50, 83, 52, 80, 20, 11, 200, 77, 3, 9, 16, 17, 212, 36, 112, 20, 28, 2, 194, 174, 34, 36, 81, 37, 89, 47, 34, 6, 109, 34, 13, 86, 15, 84, 6, 35, 34, 13, 65, 109, 34, 49, 108, 0, 0, 13, 138, 19, 16, 9, 18, 9, 20, 21, 195, 184, 19, 20, 14, 139, 7, 1, 12, 22, 1, 14, 9, 19, 195, 184, 18, 20, 8, 197, 25, 34, 69, 72, 144, 20, 12, 201, 76, 86, 67, 32, 83, 12, 37, 50, 192, 20, 12, 201, 65, 54, 75, 20, 65, 76, 37, 50, 192, 20, 12, 201, 65, 35, 199, 56, 244, 212, 37, 50, 192, 20, 12, 201, 64, 20, 133, 57, 65, 84, 37, 50, 192, 20, 12, 201, 64, 16, 201, 24, 148, 212, 37, 50, 192, 20, 12, 201, 52, 244, 129, 48, 148, 212, 37, 50, 192, 20, 12, 201, 52, 243, 133, 28, 20, 203, 37, 50, 192, 20, 12, 201, 52, 85, 1, 77, 64, 84, 37, 50, 192, 20, 12, 201, 48, 147, 135, 88, 148, 212, 37, 50, 192, 20, 12, 201, 48, 83, 137, 56, 148, 212, 37, 50, 192, 20, 12, 201, 44, 243, 15, 72, 148, 212, 37, 50, 192, 20, 12, 201, 44, 21, 1, 48, 84, 20, 37, 50, 192, 20, 12, 201, 33, 83, 79, 72, 148, 212, 37, 50, 192, 20, 12, 201, 28, 83, 210, 28, 148, 212, 37, 50, 192, 20, 12, 201, 25, 85, 21, 72, 148, 212, 37, 50, 192, 20, 12, 201, 21, 81, 133, 52, 148, 212, 37, 50, 192, 20, 12, 201, 16, 83, 79, 45, 32, 84, 37, 50, 192, 20, 12, 201, 9, 81, 4, 32, 148, 212, 37, 50, 192, 20, 12, 201, 4, 227, 129, 48, 148, 212, 37, 50, 192, 20, 12, 201, 12, 132, 137, 77, 66, 65, 56, 149, 0, 20, 10, 69, 76, 245, 82, 12, 80, 21, 0, 10, 5, 130, 195, 167, 43, 0, 9, 198, 76, 230, 68, 21, 34, 64, 20, 9, 198, 73, 149, 20, 21, 34, 64, 20, 9, 198, 64, 147, 132, 21, 34, 64, 20, 9, 198, 44, 241, 204, 21, 34, 64, 20, 9, 198, 44, 240, 140, 21, 34, 64, 20, 9, 198, 44, 20, 148, 21, 34, 64, 20, 9, 198, 28, 226, 68, 21, 34, 64, 20, 9, 198, 16, 145, 148, 21, 34, 64, 20, 9, 198, 9, 35, 196, 21, 34, 64, 20, 9, 198, 8, 147, 132, 21, 34, 64, 20, 9, 198, 64, 20, 129, 76, 149, 0, 20, 9, 198, 24, 81, 5, 77, 66, 64, 20, 9, 198, 12, 130, 65, 57, 66, 64, 20, 9, 198, 76, 83, 137, 61, 32, 84, 20, 9, 198, 72, 85, 19, 77, 64, 84, 20, 9, 198, 16, 148, 208, 5, 32, 84, 20, 5, 130, 195, 164, 43, 0, 12, 137, 13, 15, 4, 5, 12, 12, 195, 184, 18, 20, 10, 199, 61, 130, 68, 5, 66, 79, 56, 20, 10, 199, 61, 101, 76, 5, 66, 79, 56, 20, 10, 199, 37, 51, 204, 5, 66, 79, 56, 20, 10, 199, 36, 229, 5, 57, 66, 79, 56, 20, 10, 199, 36, 225, 140, 5, 66, 79, 56, 20, 10, 199, 44, 243, 80, 61, 53, 5, 72, 20, 9, 198, 52, 20, 148, 101, 34, 69, 20, 14, 203, 64, 21, 18, 36, 20, 139, 4, 194, 83, 52, 80, 20, 14, 203, 64, 20, 148, 36, 181, 76, 5, 34, 83, 52, 80, 20, 0, 13, 138, 11, 15, 13, 13, 1, 14, 4, 195, 184, 18, 20, 9, 198, 72, 148, 15, 77, 65, 82, 20, 9, 198, 45, 33, 68, 37, 65, 82, 20, 9, 198, 44, 20, 130, 85, 33, 82, 20, 9, 198, 44, 19, 9, 9, 33, 82, 20, 9, 198, 36, 229, 5, 29, 33, 82, 20, 9, 198, 36, 228, 208, 37, 33, 82, 20, 9, 198, 28, 20, 129, 57, 65, 82, 20, 9, 198, 16, 149, 133, 73, 65, 82, 20, 9, 198, 16, 145, 134, 21, 33, 82, 20, 9, 198, 5, 52, 201, 77, 65, 82, 20, 12, 201, 76, 198, 78, 28, 83, 1, 29, 66, 71, 20, 15, 204, 84, 226, 86, 21, 36, 193, 48, 148, 212, 37, 50, 192, 20, 11, 200, 80, 83, 5, 64, 21, 9, 76, 176, 20, 15, 204, 76, 176, 78, 16, 147, 129, 88, 148, 212, 37, 50, 192, 20, 15, 204, 65, 35, 208, 4, 112, 78, 16, 148, 212, 37, 50, 192, 20, 11, 200, 60, 229, 15, 48, 241, 201, 76, 176, 20, 15, 204, 44, 243, 12, 20, 181, 9, 88, 148, 212, 37, 50, 192, 20, 15, 204, 24, 20, 141, 4, 179, 199, 56, 244, 212, 37, 50, 192, 20, 15, 204, 21, 99, 204, 85, 66, 79, 56, 148, 212, 37, 50, 192, 20, 11, 200, 5, 85, 15, 52, 21, 9, 76, 176, 20, 11, 200, 5, 3, 211, 80, 243, 9, 76, 176, 20, 7, 196, 24, 16, 201, 48, 20, 11, 200, 72, 243, 65, 56, 148, 212, 36, 176, 20, 9, 198, 32, 243, 132, 85, 32, 78, 20, 15, 204, 24, 194, 80, 65, 35, 204, 21, 64, 82, 36, 21, 0, 20, 7, 196, 48, 81, 193, 48, 20, 20, 2, 194, 170, 83, 36, 65, 37, 50, 37, 50, 15, 118, 72, 37, 50, 6, 35, 55, 0, 0, 13, 138, 12, 21, 11, 19, 21, 18, 9, 195, 184, 19, 20, 12, 201, 72, 16, 149, 48, 148, 212, 21, 34, 64, 20, 12, 201, 56, 21, 20, 21, 35, 196, 21, 34, 64, 20, 12, 201, 81, 83, 85, 49, 64, 82, 37, 50, 192, 20, 12, 201, 80, 83, 5, 52, 85, 18, 37, 50, 192, 20, 12, 201, 72, 85, 8, 5, 97, 82, 37, 50, 192, 20, 12, 201, 65, 35, 204, 21, 64, 82, 37, 50, 192, 20, 12, 201, 64, 192, 78, 21, 64, 82, 37, 50, 192, 20, 12, 201, 4, 229, 9, 45, 96, 82, 37, 50, 192, 20, 12, 201, 4, 48, 197, 77, 51, 210, 37, 50, 192, 20, 0, 15, 140, 16, 15, 18, 20, 18, 195, 166, 20, 20, 195, 184, 18, 20, 15, 140, 13, 1, 14, 9, 16, 21, 12, 1, 20, 195, 184, 18, 20, 15, 140, 9, 14, 19, 20, 1, 12, 12, 1, 20, 195, 184, 18, 20, 15, 140, 4, 5, 19, 20, 9, 12, 12, 1, 20, 195, 184, 18, 20, 6, 195, 16, 85, 19, 72, 15, 4, 95, 18, 5, 22, 34, 37, 84, 6, 108, 12, 89, 72, 0, 6, 130, 195, 160, 43, 14, 0, 9, 198, 24, 243, 143, 29, 32, 77, 20, 9, 198, 4, 84, 143, 29, 32, 77, 20, 10, 199, 52, 146, 210, 60, 34, 69, 48, 20, 9, 198, 29, 147, 129, 56, 68, 137, 20, 14, 203, 8, 18, 212, 21, 34, 79, 48, 241, 201, 76, 176, 20, 10, 199, 44, 243, 139, 61, 33, 1, 80, 20, 13, 2, 194, 169, 49, 114, 48, 37, 34, 35, 57, 47, 0, 0, 9, 198, 64, 83, 12, 21, 65, 82, 20, 9, 198, 44, 243, 208, 21, 33, 82, 20, 9, 198, 36, 229, 133, 77, 65, 82, 20, 9, 198, 36, 228, 201, 77, 65, 82, 20, 9, 198, 24, 18, 212, 85, 33, 82, 20, 9, 198, 16, 85, 5, 45, 65, 82, 20, 9, 198, 5, 36, 133, 77, 65, 82, 20, 9, 198, 4, 36, 207, 49, 97, 82, 20, 15, 204, 24, 245, 15, 29, 32, 77, 52, 85, 18, 37, 50, 192, 20, 9, 198, 52, 19, 132, 5, 34, 78, 20, 9, 198, 44, 244, 147, 61, 32, 78, 20, 9, 3, 16, 195, 165, 48, 113, 0, 72, 0, 12, 201, 76, 83, 147, 37, 66, 86, 37, 65, 84, 20, 12, 201, 76, 83, 5, 45, 66, 86, 37, 65, 84, 20, 12, 201, 61, 4, 15, 73, 69, 78, 37, 65, 84, 20, 12, 201, 5, 52, 197, 73, 66, 86, 37, 65, 84, 20, 12, 137, 16, 18, 195, 166, 16, 1, 18, 1, 20, 20, 5, 130, 197, 159, 43, 5, 130, 195, 175, 43, 0, 9, 198, 81, 80, 129, 37, 53, 0, 20, 9, 198, 72, 80, 76, 37, 65, 84, 20, 9, 198, 57, 83, 12, 37, 65, 84, 20, 0, 20, 8, 23, 3, 39, 5, 18, 14, 5, 19, 84, 6, 36, 89, 36, 114, 50, 13, 89, 0, 9, 198, 8, 20, 143, 29, 32, 77, 20, 9, 198, 5, 69, 15, 29, 32, 77, 20, 12, 137, 7, 195, 166, 19, 20, 5, 18, 5, 18, 20, 10, 199, 12, 83, 12, 84, 195, 201, 16, 20, 10, 199, 44, 83, 143, 80, 17, 137, 20, 20, 7, 2, 194, 181, 65, 116, 0, 0, 7, 196, 64, 146, 197, 72, 20, 7, 196, 48, 18, 197, 72, 20, 7, 196, 80, 244, 20, 36, 20, 9, 198, 16, 19, 65, 76, 49, 78, 20, 7, 196, 88, 146, 193, 72, 20, 5, 130, 195, 170, 43, 0, 12, 201, 80, 83, 5, 29, 32, 70, 37, 53, 0, 20, 12, 201, 76, 83, 147, 36, 34, 76, 37, 65, 84, 20, 12, 201, 60, 97, 137, 12, 144, 76, 37, 65, 84, 20, 12, 201, 52, 21, 5, 72, 144, 76, 37, 65, 84, 20, 12, 201, 36, 211, 79, 73, 64, 76, 37, 65, 84, 20, 12, 201, 36, 195, 9, 45, 98, 68, 37, 65, 84, 20, 14, 139, 19, 11, 18, 195, 166, 4, 4, 5, 18, 5, 18, 20, 14, 139, 11, 195, 166, 18, 5, 19, 20, 5, 18, 5, 18, 20, 12, 201, 44, 243, 147, 80, 84, 142, 21, 33, 84, 20, 5, 130, 195, 171, 43, 0, 9, 198, 16, 148, 211, 20, 228, 192, 20, 17, 142, 19, 21, 12, 6, 1, 16, 18, 195, 166, 16, 1, 18, 1, 20, 20, 9, 198, 88, 20, 137, 4, 228, 192, 20, 0, 10, 199, 65, 35, 198, 21, 65, 82, 20, 20, 10, 199, 44, 244, 212, 84, 209, 82, 20, 20, 10, 199, 8, 19, 1, 56, 49, 82, 20, 20, 10, 199, 20, 212, 9, 72, 146, 197, 72, 20, 10, 199, 4, 181, 83, 80, 146, 197, 72, 20, 9, 198, 36, 225, 197, 56, 149, 77, 20, 10, 199, 80, 147, 79, 45, 32, 84, 36, 20, 5, 130, 195, 169, 43, 0, 13, 138, 19, 20, 1, 20, 9, 15, 14, 195, 166, 18, 20, 9, 134, 16, 15, 12, 195, 166, 18, 20, 9, 134, 13, 15, 12, 195, 166, 18, 20, 13, 138, 13, 9, 12, 12, 9, 15, 14, 195, 166, 18, 20, 7, 196, 64, 20, 148, 36, 20, 7, 196, 8, 81, 201, 44, 20, 14, 2, 194, 190, 47, 34, 109, 49, 84, 6, 35, 34, 47, 0, 5, 130, 195, 182, 43, 0, 10, 135, 19, 11, 1, 12, 195, 166, 18, 20, 8, 197, 29, 32, 86, 36, 64, 20, 8, 197, 8, 20, 211, 36, 224, 20, 8, 197, 64, 20, 212, 36, 192, 20, 8, 197, 56, 244, 208, 36, 192, 20, 12, 201, 45, 98, 78, 80, 84, 211, 20, 228, 192, 20, 12, 201, 36, 229, 5, 48, 194, 71, 20, 228, 192, 20, 12, 201, 36, 229, 5, 72, 84, 211, 4, 229, 0, 20, 19, 2, 195, 183, 72, 37, 84, 37, 72, 6, 36, 51, 36, 86, 15, 65, 36, 86, 0, 0, 13, 202, 56, 82, 210, 60, 208, 78, 80, 146, 197, 72, 20, 13, 202, 24, 147, 8, 5, 35, 79, 56, 146, 197, 72, 20, 12, 201, 44, 194, 77, 4, 181, 5, 72, 149, 77, 20, 13, 2, 194, 188, 36, 50, 15, 49, 84, 35, 34, 47, 0, 0, 12, 137, 16, 21, 2, 5, 18, 20, 195, 166, 18, 20, 12, 137, 3, 5, 12, 12, 21, 12, 195, 166, 18, 20, 10, 199, 65, 35, 198, 36, 193, 82, 20, 20, 10, 199, 76, 19, 86, 37, 69, 9, 28, 20, 10, 199, 76, 17, 212, 52, 241, 9, 28, 20, 10, 199, 17, 144, 147, 36, 225, 9, 28, 20, 14, 203, 20, 180, 202, 84, 115, 211, 48, 21, 137, 20, 224, 20, 10, 199, 85, 37, 71, 84, 22, 65, 56, 20, 9, 198, 4, 195, 9, 4, 224, 197, 20, 10, 199, 81, 32, 70, 36, 176, 78, 80, 20, 11, 2, 194, 189, 36, 50, 6, 107, 35, 55, 0, 0, 9, 198, 48, 85, 129, 57, 66, 78, 20, 9, 198, 5, 33, 197, 57, 66, 78, 20, 9, 198, 4, 225, 204, 36, 176, 78, 20, 9, 198, 17, 32, 71, 60, 208, 78, 21, 22, 2, 194, 186, 65, 6, 35, 89, 49, 40, 55, 37, 50, 15, 118, 72, 37, 50, 6, 35, 55, 0, 16, 4, 95, 18, 6, 24, 34, 47, 34, 39, 83, 55, 109, 49, 89, 0, 14, 4, 95, 3, 5, 4, 89, 13, 72, 6, 37, 55, 35, 0, 0, 14, 139, 18, 21, 4, 9, 13, 5, 14, 20, 195, 166, 18, 20, 8, 197, 64, 83, 12, 21, 64, 20, 8, 197, 8, 19, 12, 21, 64, 20, 8, 197, 60, 35, 201, 77, 64, 20, 8, 197, 52, 243, 148, 21, 32, 20, 15, 204, 44, 83, 79, 80, 84, 129, 64, 85, 84, 36, 181, 77, 20, 8, 197, 36, 226, 214, 37, 64, 20, 8, 197, 29, 32, 70, 37, 64, 20, 8, 197, 16, 80, 197, 57, 64, 20, 8, 197, 44, 195, 210, 5, 64, 20, 0, 9, 198, 48, 240, 133, 48, 145, 64, 20, 9, 198, 88, 19, 129, 16, 145, 64, 20, 9, 198, 56, 240, 133, 48, 145, 64, 20, 9, 198, 8, 19, 1, 56, 49, 64, 20, 0, 9, 67, 36, 177, 64, 35, 57, 49, 0, 10, 199, 76, 240, 201, 60, 227, 205, 36, 20, 14, 4, 95, 12, 9, 7, 55, 37, 81, 35, 47, 40, 34, 0, 5, 130, 195, 177, 43, 5, 130, 197, 161, 43, 0, 9, 198, 16, 81, 133, 57, 51, 210, 20, 11, 200, 76, 22, 15, 24, 243, 137, 77, 64, 20, 11, 200, 44, 243, 134, 61, 35, 73, 77, 64, 20, 11, 200, 44, 20, 9, 80, 19, 9, 77, 64, 20, 11, 200, 84, 211, 210, 4, 194, 84, 21, 64, 20, 11, 200, 64, 197, 82, 4, 194, 84, 21, 64, 20, 11, 200, 52, 20, 211, 37, 98, 84, 21, 64, 20, 11, 200, 48, 20, 195, 37, 98, 84, 21, 64, 20, 11, 200, 44, 243, 139, 5, 98, 84, 21, 64, 20, 11, 200, 36, 229, 5, 29, 34, 84, 21, 64, 20, 11, 200, 24, 18, 212, 36, 50, 84, 21, 64, 20, 11, 200, 16, 81, 143, 72, 210, 84, 21, 64, 20, 11, 200, 12, 83, 5, 9, 34, 84, 21, 64, 20, 11, 200, 4, 227, 206, 100, 210, 84, 21, 64, 20, 11, 200, 25, 33, 75, 88, 83, 148, 21, 32, 20, 11, 200, 4, 178, 210, 20, 66, 84, 21, 32, 20, 9, 198, 88, 83, 133, 80, 144, 78, 20, 11, 200, 72, 84, 212, 5, 84, 129, 57, 64, 20, 0, 8, 197, 80, 244, 148, 85, 32, 20, 8, 197, 73, 84, 20, 85, 32, 20, 8, 197, 44, 243, 148, 85, 32, 20, 8, 197, 77, 64, 84, 85, 64, 20, 8, 197, 41, 83, 137, 61, 32, 20, 8, 197, 77, 66, 76, 21, 64, 20, 8, 197, 57, 81, 9, 77, 64, 20, 12, 201, 76, 84, 150, 36, 49, 82, 36, 225, 192, 20, 12, 201, 64, 20, 134, 84, 209, 82, 36, 225, 192, 20, 12, 201, 16, 84, 193, 72, 209, 82, 36, 225, 192, 20, 12, 201, 5, 36, 129, 56, 113, 82, 36, 225, 192, 20, 8, 197, 76, 21, 84, 21, 32, 20, 8, 197, 20, 194, 68, 21, 32, 20, 8, 197, 16, 19, 132, 21, 32, 20, 11, 136, 13, 195, 184, 12, 12, 5, 18, 9, 20, 13, 138, 8, 195, 184, 10, 1, 4, 5, 12, 9, 7, 20, 12, 201, 88, 242, 193, 9, 83, 1, 72, 145, 64, 20, 8, 197, 21, 52, 18, 37, 64, 20, 12, 201, 56, 85, 84, 72, 19, 9, 76, 209, 64, 20, 12, 201, 56, 21, 21, 72, 19, 9, 76, 209, 64, 20, 12, 201, 44, 243, 134, 61, 35, 73, 76, 209, 64, 20, 12, 201, 44, 20, 9, 80, 19, 9, 76, 209, 64, 20, 8, 197, 44, 194, 69, 57, 64, 20, 12, 201, 56, 243, 131, 32, 19, 1, 56, 49, 64, 20, 8, 197, 77, 83, 6, 5, 64, 20, 8, 197, 56, 149, 18, 5, 64, 20, 12, 201, 44, 243, 147, 37, 53, 15, 72, 144, 76, 20, 8, 197, 64, 146, 193, 57, 64, 20, 0, 14, 139, 14, 15, 18, 4, 195, 184, 19, 20, 12, 9, 7, 20, 14, 139, 8, 195, 184, 10, 20, 9, 4, 5, 12, 9, 7, 20, 9, 198, 76, 19, 65, 72, 145, 64, 20, 9, 198, 4, 211, 79, 56, 145, 64, 20, 9, 198, 52, 21, 18, 36, 49, 64, 20, 9, 198, 4, 181, 18, 36, 49, 64, 20, 9, 198, 25, 35, 205, 4, 113, 64, 20, 7, 132, 2, 195, 184, 18, 76, 5, 130, 195, 188, 43, 0, 14, 203, 25, 83, 132, 4, 209, 78, 80, 19, 9, 77, 64, 20, 14, 203, 65, 35, 199, 72, 84, 211, 37, 98, 84, 21, 64, 20, 14, 203, 36, 225, 70, 24, 82, 212, 37, 98, 84, 21, 64, 20, 14, 203, 25, 83, 139, 80, 147, 206, 4, 194, 84, 21, 64, 20, 14, 203, 16, 148, 212, 36, 226, 212, 37, 98, 84, 21, 64, 20, 14, 203, 16, 84, 212, 73, 82, 212, 37, 98, 84, 21, 64, 20, 13, 138, 4, 195, 184, 4, 2, 9, 4, 5, 18, 9, 20, 10, 199, 53, 84, 203, 20, 67, 206, 56, 20, 0, 11, 200, 77, 84, 146, 20, 19, 9, 77, 64, 20, 11, 200, 48, 144, 133, 72, 19, 9, 77, 64, 20, 11, 136, 4, 9, 195, 166, 20, 9, 19, 20, 20, 11, 200, 8, 83, 12, 21, 68, 137, 77, 64, 20, 11, 200, 8, 80, 82, 8, 82, 132, 21, 32, 67, 9, 198, 76, 176, 66, 20, 195, 206, 20, 9, 198, 52, 146, 210, 60, 99, 206, 20, 15, 204, 5, 85, 5, 57, 66, 70, 36, 49, 82, 36, 225, 192, 20, 11, 200, 52, 19, 137, 24, 84, 212, 21, 32, 20, 12, 137, 195, 166, 18, 7, 5, 18, 18, 9, 7, 20, 16, 141, 6, 15, 18, 8, 195, 165, 2, 5, 14, 20, 12, 9, 7, 20, 15, 204, 81, 32, 78, 77, 97, 83, 80, 149, 9, 76, 209, 64, 20, 15, 204, 25, 83, 132, 4, 209, 78, 80, 19, 9, 76, 209, 64, 20, 9, 198, 81, 83, 133, 76, 145, 78, 20, 9, 198, 5, 52, 217, 72, 145, 78, 20, 11, 200, 20, 180, 208, 20, 66, 69, 57, 64, 20, 9, 198, 56, 243, 73, 56, 19, 0, 20, 0, 10, 135, 6, 12, 1, 14, 195, 184, 18, 20, 10, 135, 3, 1, 21, 19, 195, 184, 18, 20, 8, 197, 48, 21, 137, 56, 80, 20, 12, 201, 72, 82, 70, 36, 49, 82, 36, 225, 192, 20, 12, 201, 64, 20, 143, 16, 145, 82, 36, 225, 192, 20, 12, 201, 52, 18, 211, 36, 209, 82, 36, 225, 192, 20, 12, 201, 17, 84, 12, 36, 177, 82, 36, 225, 192, 20, 12, 201, 8, 19, 19, 4, 209, 82, 36, 225, 192, 20, 12, 201, 5, 68, 143, 24, 145, 82, 36, 225, 192, 20, 8, 197, 52, 147, 133, 72, 80, 20, 8, 197, 28, 83, 133, 72, 80, 20, 13, 138, 19, 25, 4, 195, 184, 19, 20, 12, 9, 7, 20, 12, 201, 77, 84, 208, 20, 228, 207, 72, 145, 64, 20, 12, 201, 44, 243, 147, 37, 53, 15, 72, 145, 64, 20, 8, 197, 76, 241, 15, 52, 144, 20, 12, 201, 77, 147, 139, 72, 85, 9, 76, 209, 64, 20, 12, 201, 76, 84, 1, 72, 21, 9, 76, 209, 64, 20, 12, 201, 52, 147, 137, 52, 19, 9, 76, 209, 64, 20, 12, 201, 44, 192, 83, 76, 144, 201, 76, 209, 64, 20, 8, 197, 29, 32, 70, 20, 208, 20, 0, 9, 198, 17, 80, 84, 48, 85, 0, 20, 9, 198, 44, 194, 69, 57, 65, 76, 20, 9, 198, 44, 194, 69, 57, 65, 76, 20, 14, 139, 20, 9, 12, 18, 195, 165, 4, 5, 12, 9, 7, 20, 9, 198, 32, 84, 130, 36, 50, 68, 20, 9, 198, 16, 243, 15, 52, 149, 0, 20, 9, 198, 64, 244, 212, 21, 64, 84, 20, 9, 198, 16, 84, 208, 21, 32, 84, 20, 6, 2, 195, 184, 118, 0, 0, 9, 198, 80, 82, 206, 60, 227, 205, 20, 9, 198, 44, 20, 131, 36, 227, 205, 20, 10, 199, 88, 149, 137, 76, 82, 197, 72, 20, 10, 199, 64, 84, 150, 21, 37, 5, 72, 20, 10, 199, 44, 19, 15, 72, 145, 133, 72, 20, 10, 199, 65, 35, 211, 4, 146, 197, 72, 20, 10, 199, 9, 83, 9, 52, 146, 197, 72, 20, 9, 198, 65, 35, 208, 72, 149, 77, 20, 10, 199, 4, 180, 143, 8, 21, 9, 44, 20, 10, 199, 65, 32, 75, 80, 148, 193, 8, 20, 0, 12, 137, 20, 18, 9, 11, 9, 14, 195, 184, 19, 20, 11, 200, 53, 150, 15, 52, 21, 15, 76, 80, 20, 11, 200, 77, 147, 139, 72, 243, 137, 76, 176, 20, 11, 200, 77, 66, 76, 37, 53, 9, 76, 176, 20, 11, 200, 77, 64, 84, 37, 53, 9, 76, 176, 20, 11, 200, 77, 2, 82, 4, 229, 9, 76, 176, 20, 11, 200, 76, 179, 204, 5, 53, 9, 76, 176, 20, 11, 200, 56, 85, 82, 4, 193, 201, 76, 176, 20, 11, 200, 44, 21, 1, 49, 149, 9, 76, 176, 20, 11, 200, 24, 20, 195, 37, 53, 9, 76, 176, 20, 11, 200, 16, 144, 83, 80, 243, 9, 76, 176, 20, 7, 196, 76, 21, 9, 56, 20, 7, 196, 44, 19, 73, 56, 20, 11, 200, 88, 19, 132, 4, 194, 83, 52, 80, 20, 11, 200, 80, 84, 146, 61, 34, 83, 52, 80, 20, 11, 200, 77, 147, 66, 60, 194, 83, 52, 80, 20, 11, 200, 77, 64, 76, 36, 226, 83, 52, 80, 20, 11, 200, 76, 240, 201, 4, 194, 83, 52, 80, 20, 11, 200, 64, 192, 84, 60, 226, 83, 52, 80, 20, 11, 200, 52, 243, 135, 60, 194, 83, 52, 80, 20, 11, 200, 45, 33, 84, 36, 226, 83, 52, 80, 20, 11, 200, 24, 244, 141, 4, 194, 83, 52, 80, 20, 11, 200, 24, 85, 68, 4, 194, 83, 52, 80, 20, 11, 200, 24, 85, 9, 12, 130, 83, 52, 80, 20, 11, 200, 16, 20, 151, 36, 226, 83, 52, 80, 20, 11, 200, 9, 37, 84, 4, 194, 83, 52, 80, 20, 11, 200, 4, 36, 213, 72, 66, 83, 52, 80, 20, 0, 12, 201, 16, 84, 141, 5, 67, 204, 60, 114, 64, 20, 12, 201, 9, 35, 205, 5, 67, 204, 60, 114, 64, 20, 12, 201, 4, 229, 18, 61, 3, 204, 60, 114, 64, 20, 8, 197, 73, 85, 9, 56, 80, 20, 8, 197, 53, 148, 212, 36, 176, 20, 8, 67, 76, 227, 194, 21, 0, 10, 0, 12, 137, 195, 166, 20, 9, 15, 12, 15, 7, 9, 20, 9, 198, 85, 35, 204, 60, 114, 64, 20, 13, 202, 32, 84, 141, 20, 225, 85, 80, 146, 197, 72, 20, 9, 198, 76, 241, 15, 52, 149, 0, 20, 9, 198, 52, 243, 143, 48, 149, 0, 20, 0, 17, 67, 44, 243, 64, 49, 114, 65, 15, 89, 114, 0, 81, 115, 195, 165, 32, 12, 137, 22, 15, 12, 15, 14, 20, 195, 184, 18, 20, 10, 199, 52, 18, 213, 48, 21, 15, 72, 20, 10, 199, 4, 195, 9, 28, 21, 15, 72, 20, 10, 199, 24, 147, 138, 85, 53, 5, 72, 20, 14, 203, 72, 81, 201, 60, 224, 76, 37, 53, 9, 76, 176, 20, 14, 203, 72, 21, 9, 60, 224, 76, 37, 53, 9, 76, 176, 20, 14, 203, 64, 242, 78, 80, 147, 12, 37, 53, 9, 76, 176, 20, 14, 203, 64, 21, 5, 72, 224, 76, 37, 53, 9, 76, 176, 20, 14, 203, 56, 21, 9, 60, 224, 76, 37, 53, 9, 76, 176, 20, 14, 203, 44, 19, 142, 36, 32, 76, 37, 53, 9, 76, 176, 20, 14, 203, 65, 35, 212, 20, 181, 9, 60, 226, 83, 52, 80, 20, 14, 203, 64, 84, 134, 20, 181, 9, 60, 226, 83, 52, 80, 20, 14, 203, 44, 243, 77, 21, 32, 201, 4, 194, 83, 52, 80, 20, 14, 203, 36, 225, 9, 88, 145, 21, 4, 194, 83, 52, 80, 20, 14, 203, 36, 212, 18, 21, 52, 201, 60, 226, 83, 52, 80, 20, 14, 203, 20, 180, 208, 4, 228, 201, 60, 226, 83, 52, 80, 20, 10, 199, 28, 83, 65, 48, 147, 132, 20, 20, 10, 67, 76, 243, 64, 89, 114, 65, 0, 72, 21, 4, 95, 54, 88, 15, 47, 34, 6, 109, 89, 36, 50, 89, 47, 116, 84, 13, 50, 13, 0, 0, 9, 198, 65, 83, 16, 37, 69, 82, 20, 9, 198, 16, 240, 197, 57, 69, 82, 20, 12, 137, 7, 18, 1, 14, 21, 12, 195, 184, 19, 20, 13, 138, 5, 11, 19, 16, 15, 18, 20, 195, 184, 18, 20, 13, 138, 4, 9, 19, 16, 1, 3, 8, 195, 184, 18, 20, 11, 200, 89, 83, 11, 4, 227, 204, 60, 112, 20, 11, 200, 28, 84, 143, 57, 67, 204, 60, 112, 20, 11, 200, 9, 34, 71, 4, 229, 9, 56, 80, 20, 9, 198, 88, 147, 132, 36, 49, 82, 20, 9, 198, 76, 83, 5, 45, 65, 82, 20, 9, 198, 72, 83, 1, 56, 49, 82, 20, 9, 198, 45, 84, 147, 37, 97, 82, 20, 9, 198, 44, 243, 134, 21, 33, 82, 20, 9, 198, 16, 82, 204, 5, 33, 82, 20, 9, 198, 12, 83, 5, 9, 33, 82, 20, 11, 200, 80, 16, 200, 37, 53, 9, 76, 176, 20, 11, 200, 77, 67, 203, 5, 53, 9, 76, 176, 20, 11, 200, 76, 178, 83, 52, 21, 9, 76, 176, 20, 11, 200, 64, 20, 129, 49, 149, 9, 76, 176, 20, 11, 200, 52, 20, 152, 37, 53, 9, 76, 176, 20, 11, 200, 45, 96, 68, 72, 21, 9, 76, 176, 20, 11, 200, 24, 19, 148, 5, 53, 9, 76, 176, 20, 12, 137, 4, 195, 166, 13, 15, 14, 9, 19, 11, 20, 11, 200, 16, 17, 1, 37, 53, 9, 76, 176, 20, 11, 200, 8, 20, 20, 37, 53, 9, 76, 176, 20, 11, 200, 5, 1, 82, 36, 241, 9, 76, 176, 20, 9, 198, 52, 85, 18, 36, 177, 82, 20, 7, 196, 24, 16, 201, 80, 20, 11, 200, 36, 225, 143, 72, 208, 84, 36, 176, 20, 7, 196, 4, 113, 78, 76, 20, 11, 200, 44, 243, 132, 60, 193, 78, 12, 80, 20, 7, 196, 48, 81, 193, 80, 20, 7, 196, 48, 242, 193, 48, 20, 0, 13, 138, 19, 11, 1, 14, 4, 1, 12, 195, 184, 19, 20, 13, 138, 13, 9, 18, 1, 11, 21, 12, 195, 184, 19, 20, 12, 201, 80, 84, 141, 36, 227, 204, 60, 114, 64, 20, 13, 138, 11, 195, 184, 7, 5, 14, 19, 9, 19, 11, 20, 8, 197, 48, 144, 197, 57, 48, 20, 8, 197, 21, 52, 197, 57, 48, 20, 14, 73, 8, 80, 67, 33, 99, 204, 48, 86, 64, 21, 0, 10, 0, 10, 67, 36, 177, 83, 35, 57, 49, 89, 0, 15, 140, 20, 18, 1, 14, 19, 16, 15, 18, 20, 195, 184, 18, 20, 9, 198, 29, 32, 86, 37, 65, 84, 20, 17, 206, 77, 84, 18, 4, 224, 84, 85, 32, 76, 37, 53, 9, 76, 176, 20, 14, 139, 1, 14, 1, 16, 195, 166, 19, 20, 9, 19, 11, 20, 9, 198, 64, 85, 9, 81, 83, 64, 20, 12, 4, 95, 2, 1, 18, 10, 71, 6, 112, 13, 0, 0, 19, 67, 16, 83, 64, 72, 6, 109, 65, 15, 72, 36, 34, 0, 81, 100, 101, 114, 32, 19, 67, 16, 83, 64, 72, 6, 109, 65, 15, 107, 36, 34, 0, 81, 104, 101, 114, 32, 12, 201, 88, 20, 133, 16, 82, 204, 5, 33, 82, 20, 9, 198, 36, 67, 204, 5, 68, 137, 20, 14, 203, 65, 54, 75, 60, 19, 129, 49, 149, 9, 76, 176, 20, 14, 203, 52, 85, 1, 48, 195, 199, 72, 17, 137, 76, 176, 20, 14, 203, 45, 34, 77, 36, 224, 76, 37, 53, 9, 76, 176, 20, 12, 201, 64, 19, 148, 60, 210, 77, 36, 177, 82, 20, 10, 199, 64, 244, 212, 49, 81, 9, 20, 20, 6, 195, 16, 83, 64, 72, 0, 13, 138, 16, 18, 195, 166, 6, 5, 11, 20, 21, 18, 20, 7, 196, 4, 96, 83, 36, 20, 9, 198, 80, 244, 148, 85, 33, 82, 20, 9, 198, 65, 35, 202, 36, 49, 82, 20, 9, 198, 36, 229, 143, 49, 97, 82, 20, 9, 198, 29, 32, 86, 37, 65, 82, 20, 9, 198, 16, 82, 193, 57, 65, 82, 20, 9, 198, 16, 19, 65, 76, 49, 82, 20, 7, 196, 32, 19, 73, 80, 20, 9, 198, 4, 209, 82, 36, 176, 78, 20, 9, 198, 52, 84, 137, 16, 144, 78, 21, 5, 130, 197, 190, 43, 0, 9, 198, 76, 240, 201, 60, 195, 199, 20, 9, 198, 25, 148, 201, 60, 195, 199, 20, 12, 201, 88, 144, 146, 4, 99, 206, 37, 53, 0, 20, 12, 201, 24, 19, 73, 48, 144, 82, 37, 65, 84, 20, 0, 16, 141, 18, 195, 184, 14, 20, 7, 5, 14, 15, 12, 15, 7, 9, 20, 9, 198, 80, 244, 130, 37, 53, 0, 20, 9, 198, 32, 244, 142, 37, 53, 0, 20, 9, 198, 45, 96, 76, 37, 65, 84, 20, 9, 198, 4, 114, 76, 37, 65, 84, 20, 9, 198, 61, 85, 18, 21, 33, 84, 20, 0, 27, 67, 24, 18, 84, 83, 109, 47, 35, 49, 114, 65, 48, 55, 6, 37, 0, 81, 97, 99, 99, 111, 109, 112, 108, 105, 32, 12, 201, 44, 243, 77, 4, 225, 1, 57, 69, 82, 20, 12, 137, 16, 18, 195, 166, 16, 1, 18, 5, 18, 20, 10, 199, 88, 149, 1, 48, 148, 205, 20, 20, 10, 199, 36, 65, 65, 48, 148, 205, 20, 20, 21, 71, 33, 145, 18, 60, 99, 201, 48, 107, 116, 72, 34, 39, 83, 6, 114, 37, 55, 0, 20, 10, 199, 80, 84, 141, 61, 53, 1, 80, 20, 0, 9, 134, 2, 9, 14, 195, 166, 18, 20, 15, 204, 44, 243, 80, 48, 83, 69, 57, 64, 82, 37, 65, 84, 20, 9, 68, 12, 128, 82, 80, 21, 0, 10, 0, 8, 197, 17, 32, 71, 60, 224, 20, 12, 201, 84, 213, 83, 36, 176, 76, 37, 65, 84, 20, 12, 201, 61, 34, 71, 36, 224, 76, 37, 65, 84, 20, 14, 139, 16, 18, 195, 166, 14, 21, 13, 5, 18, 5, 18, 20, 14, 139, 5, 21, 18, 15, 16, 195, 166, 9, 19, 5, 18, 20, 11, 136, 19, 16, 195, 184, 7, 5, 18, 9, 20, 11, 136, 13, 195, 166, 12, 11, 5, 18, 9, 20, 8, 197, 64, 84, 134, 36, 64, 20, 8, 197, 52, 244, 130, 36, 64, 20, 8, 197, 48, 146, 214, 36, 64, 20, 8, 197, 44, 20, 130, 36, 64, 20, 8, 197, 13, 144, 78, 36, 64, 20, 8, 197, 80, 19, 148, 4, 192, 20, 8, 197, 16, 83, 148, 4, 192, 20, 0, 11, 136, 15, 18, 4, 9, 14, 195, 166, 18, 20, 9, 198, 4, 229, 18, 4, 50, 84, 20, 9, 198, 8, 85, 10, 20, 229, 0, 20, 9, 198, 44, 243, 147, 20, 228, 192, 20, 13, 138, 9, 14, 1, 4, 195, 166, 11, 22, 1, 20, 20, 9, 134, 6, 195, 166, 11, 1, 12, 20, 0, 10, 199, 28, 20, 142, 37, 69, 82, 20, 20, 12, 137, 22, 9, 19, 9, 15, 14, 195, 166, 18, 20, 12, 137, 9, 13, 1, 7, 9, 14, 195, 166, 18, 20, 12, 137, 1, 18, 2, 9, 20, 18, 195, 166, 18, 20, 10, 199, 44, 243, 148, 85, 33, 82, 20, 20, 10, 199, 28, 243, 132, 60, 194, 69, 72, 20, 10, 199, 76, 177, 80, 80, 146, 197, 72, 20, 10, 199, 64, 243, 5, 52, 146, 197, 72, 20, 10, 199, 28, 83, 133, 80, 146, 197, 72, 20, 10, 199, 24, 243, 133, 80, 146, 197, 72, 20, 10, 199, 24, 19, 129, 80, 146, 197, 72, 20, 9, 198, 4, 211, 79, 56, 149, 77, 20, 10, 199, 76, 20, 132, 36, 226, 69, 56, 20, 9, 198, 20, 193, 71, 4, 224, 197, 20, 0, 7, 196, 52, 245, 15, 72, 20, 13, 138, 22, 5, 20, 5, 18, 9, 14, 195, 166, 18, 20, 9, 134, 22, 5, 12, 195, 166, 18, 20, 9, 134, 19, 1, 12, 195, 166, 18, 20, 13, 138, 4, 15, 11, 20, 18, 9, 14, 195, 166, 18, 20, 11, 200, 88, 83, 133, 72, 21, 9, 60, 224, 20, 11, 200, 76, 147, 85, 48, 21, 9, 60, 224, 20, 11, 200, 72, 84, 21, 80, 21, 9, 60, 224, 20, 11, 200, 72, 83, 143, 88, 21, 9, 60, 224, 20, 11, 200, 72, 83, 5, 28, 21, 9, 60, 224, 20, 11, 200, 65, 35, 212, 20, 181, 9, 60, 224, 20, 11, 200, 65, 35, 196, 84, 181, 9, 60, 224, 20, 11, 200, 64, 244, 21, 48, 21, 9, 60, 224, 20, 11, 200, 61, 4, 15, 76, 149, 9, 60, 224, 20, 11, 200, 36, 229, 137, 80, 21, 9, 60, 224, 20, 11, 200, 36, 228, 208, 20, 181, 9, 60, 224, 20, 11, 200, 36, 226, 9, 8, 149, 9, 60, 224, 20, 11, 200, 36, 224, 201, 80, 21, 9, 60, 224, 20, 11, 200, 28, 192, 67, 36, 21, 9, 60, 224, 20, 11, 200, 20, 209, 78, 16, 21, 9, 60, 224, 20, 11, 200, 16, 83, 5, 28, 21, 9, 60, 224, 20, 11, 200, 4, 211, 85, 56, 149, 9, 60, 224, 20, 12, 137, 8, 5, 2, 18, 195, 166, 9, 19, 11, 20, 9, 198, 21, 84, 129, 76, 145, 78, 20, 7, 196, 4, 113, 78, 80, 20, 11, 200, 32, 244, 137, 76, 243, 148, 4, 192, 20, 7, 196, 4, 147, 65, 8, 20, 0, 15, 69, 76, 18, 71, 60, 224, 89, 35, 57, 81, 108, 20, 50, 0, 14, 139, 18, 5, 1, 11, 20, 9, 15, 14, 195, 166, 18, 20, 8, 197, 21, 2, 71, 60, 224, 20, 8, 197, 72, 21, 9, 60, 224, 20, 12, 201, 44, 194, 77, 4, 181, 5, 72, 145, 76, 20, 13, 138, 195, 184, 11, 15, 12, 15, 7, 9, 19, 11, 20, 8, 197, 33, 144, 146, 36, 64, 20, 16, 69, 29, 32, 84, 36, 224, 81, 34, 112, 47, 6, 109, 68, 0, 20, 8, 197, 24, 84, 148, 36, 192, 20, 12, 201, 72, 83, 73, 56, 148, 195, 20, 228, 192, 20, 12, 201, 49, 83, 73, 56, 84, 195, 20, 228, 192, 20, 12, 201, 24, 197, 79, 72, 84, 195, 20, 228, 192, 20, 8, 197, 85, 33, 84, 4, 224, 21, 8, 197, 88, 19, 132, 4, 192, 20, 8, 197, 76, 19, 132, 4, 192, 20, 0, 11, 136, 20, 9, 20, 21, 12, 195, 166, 18, 20, 11, 136, 16, 15, 16, 21, 12, 195, 166, 18, 20, 11, 136, 13, 15, 14, 5, 20, 195, 166, 18, 20, 11, 136, 13, 15, 4, 21, 12, 195, 166, 18, 20, 11, 136, 9, 14, 19, 21, 12, 195, 166, 18, 20, 14, 139, 11, 1, 14, 1, 1, 14, 195, 166, 9, 19, 11, 20, 14, 139, 11, 1, 14, 1, 1, 14, 195, 166, 9, 19, 11, 20, 13, 202, 44, 148, 143, 65, 32, 75, 80, 146, 197, 72, 20, 0, 25, 73, 77, 21, 65, 72, 81, 1, 56, 49, 78, 89, 49, 58, 6, 36, 13, 72, 35, 12, 50, 89, 14, 50, 0, 10, 199, 44, 19, 142, 20, 197, 82, 20, 20, 10, 199, 28, 83, 133, 72, 21, 15, 72, 20, 12, 137, 19, 5, 11, 18, 5, 20, 195, 166, 18, 20, 12, 137, 13, 21, 19, 11, 21, 12, 195, 166, 18, 20, 10, 199, 44, 243, 139, 84, 34, 78, 20, 20, 14, 203, 76, 147, 80, 48, 145, 137, 44, 21, 9, 60, 224, 20, 14, 203, 72, 82, 207, 53, 1, 78, 76, 21, 9, 60, 224, 20, 14, 203, 72, 82, 207, 52, 208, 78, 16, 21, 9, 60, 224, 20, 14, 203, 72, 82, 193, 64, 149, 21, 48, 21, 9, 60, 224, 20, 14, 203, 36, 229, 5, 73, 4, 133, 80, 21, 9, 60, 224, 20, 14, 203, 20, 180, 212, 72, 20, 15, 76, 149, 9, 60, 224, 20, 10, 199, 81, 83, 142, 20, 193, 82, 20, 20, 10, 199, 4, 178, 207, 72, 65, 82, 20, 20, 11, 136, 195, 166, 20, 5, 18, 9, 19, 11, 20, 15, 140, 16, 1, 12, 195, 166, 15, 12, 9, 20, 9, 19, 11, 20, 15, 140, 13, 1, 10, 5, 19, 20, 195, 166, 20, 9, 19, 11, 20, 9, 198, 88, 19, 129, 16, 149, 77, 20, 9, 198, 56, 240, 133, 48, 149, 77, 20, 10, 199, 4, 209, 133, 80, 19, 73, 56, 20, 9, 134, 1, 14, 195, 166, 13, 9, 20, 14, 203, 81, 32, 78, 76, 49, 78, 16, 83, 148, 4, 192, 20, 0, 13, 138, 16, 1, 18, 1, 19, 9, 20, 195, 166, 18, 20, 13, 138, 8, 21, 13, 1, 14, 9, 20, 195, 166, 18, 20, 13, 138, 8, 5, 18, 5, 4, 9, 20, 195, 166, 18, 20, 13, 138, 2, 9, 14, 15, 11, 21, 12, 195, 166, 18, 20, 13, 138, 1, 21, 20, 15, 18, 9, 20, 195, 166, 18, 20, 11, 200, 72, 82, 210, 20, 21, 9, 60, 224, 20, 11, 200, 52, 245, 9, 88, 21, 9, 60, 224, 20, 11, 200, 44, 244, 21, 48, 21, 9, 60, 224, 20, 11, 200, 36, 226, 84, 36, 21, 9, 60, 224, 20, 11, 200, 16, 83, 143, 80, 21, 9, 60, 224, 20, 11, 200, 16, 81, 137, 56, 149, 9, 60, 224, 20, 11, 200, 5, 4, 15, 76, 149, 9, 60, 224, 20, 11, 200, 4, 197, 5, 72, 21, 9, 60, 224, 20, 12, 137, 16, 18, 195, 184, 10, 19, 9, 19, 11, 20, 11, 200, 64, 243, 25, 85, 33, 84, 4, 224, 21, 0, 14, 139, 16, 1, 18, 20, 9, 11, 21, 12, 195, 166, 18, 20, 14, 139, 13, 9, 12, 12, 9, 1, 18, 4, 195, 166, 18, 20, 14, 139, 13, 1, 20, 18, 9, 11, 21, 12, 195, 166, 18, 20, 8, 197, 80, 16, 140, 21, 64, 20, 8, 197, 45, 80, 137, 77, 64, 20, 8, 197, 52, 81, 9, 21, 32, 20, 8, 197, 80, 17, 198, 5, 64, 20, 8, 197, 65, 83, 19, 5, 32, 20, 0, 15, 140, 21, 14, 9, 22, 5, 18, 19, 9, 20, 195, 166, 18, 20, 15, 140, 19, 16, 5, 11, 20, 1, 11, 21, 12, 195, 166, 18, 20, 12, 201, 88, 242, 193, 9, 83, 1, 72, 149, 77, 20, 9, 198, 64, 20, 9, 76, 209, 64, 20, 9, 198, 8, 147, 9, 76, 209, 64, 20, 12, 201, 12, 192, 73, 73, 99, 217, 4, 224, 197, 20, 9, 198, 12, 244, 147, 4, 113, 64, 20, 0, 13, 138, 16, 18, 195, 166, 19, 9, 4, 9, 21, 13, 20, 12, 71, 64, 83, 148, 32, 245, 83, 20, 21, 0, 10, 0, 11, 200, 52, 147, 9, 80, 20, 137, 77, 64, 20, 11, 200, 52, 19, 137, 13, 84, 137, 77, 64, 20, 11, 200, 88, 148, 203, 61, 50, 84, 21, 64, 20, 11, 200, 77, 69, 80, 36, 66, 84, 21, 64, 20, 11, 200, 77, 65, 82, 36, 194, 84, 21, 64, 20, 11, 200, 77, 64, 66, 36, 194, 84, 21, 64, 20, 11, 200, 76, 84, 150, 36, 194, 84, 21, 64, 20, 11, 200, 45, 84, 137, 61, 50, 84, 21, 64, 20, 11, 200, 36, 229, 5, 57, 50, 84, 21, 64, 20, 11, 200, 16, 149, 133, 73, 50, 84, 21, 64, 20, 11, 200, 5, 67, 206, 4, 194, 84, 21, 64, 20, 11, 200, 4, 211, 210, 4, 194, 84, 21, 64, 20, 9, 198, 80, 19, 9, 76, 208, 78, 21, 11, 200, 72, 81, 201, 77, 68, 129, 57, 64, 20, 0, 23, 73, 77, 21, 65, 72, 81, 1, 56, 49, 64, 89, 49, 58, 6, 36, 13, 72, 35, 12, 50, 89, 0, 16, 69, 16, 148, 208, 85, 64, 72, 37, 89, 71, 6, 116, 47, 0, 20, 8, 197, 61, 32, 84, 61, 32, 20, 8, 197, 88, 147, 204, 21, 64, 20, 12, 201, 4, 178, 207, 53, 0, 71, 56, 84, 128, 20, 12, 201, 84, 226, 70, 61, 35, 73, 76, 209, 64, 20, 12, 201, 77, 84, 146, 20, 19, 9, 76, 209, 64, 20, 12, 201, 72, 17, 9, 44, 19, 9, 76, 209, 64, 20, 12, 201, 65, 32, 71, 52, 21, 9, 76, 209, 64, 20, 12, 201, 48, 144, 133, 72, 19, 9, 76, 209, 64, 20, 8, 197, 65, 35, 194, 5, 64, 20, 0, 9, 198, 65, 35, 208, 72, 145, 64, 20, 9, 198, 36, 225, 197, 56, 145, 64, 20, 9, 198, 76, 17, 9, 76, 209, 64, 20, 9, 198, 32, 243, 9, 76, 209, 64, 20, 9, 198, 5, 65, 73, 76, 209, 64, 20, 9, 198, 88, 18, 193, 56, 49, 64, 20, 9, 198, 64, 21, 18, 36, 49, 64, 20, 9, 198, 44, 17, 5, 56, 49, 64, 20, 9, 198, 4, 227, 143, 56, 49, 64, 20, 0, 14, 139, 6, 12, 195, 184, 10, 20, 5, 14, 9, 19, 20, 20, 14, 203, 72, 85, 133, 73, 50, 66, 36, 194, 84, 21, 64, 20, 14, 203, 65, 35, 198, 37, 64, 66, 36, 194, 84, 21, 64, 20, 14, 203, 44, 243, 80, 5, 66, 66, 36, 194, 84, 21, 64, 20, 14, 203, 37, 36, 129, 80, 147, 206, 4, 194, 84, 21, 64, 20, 14, 203, 4, 48, 197, 65, 64, 66, 36, 194, 84, 21, 64, 20, 0, 11, 200, 64, 84, 134, 61, 32, 84, 61, 32, 20, 11, 200, 60, 36, 197, 73, 96, 84, 61, 32, 20, 11, 200, 44, 243, 77, 85, 64, 84, 61, 32, 20, 11, 200, 44, 19, 11, 84, 192, 84, 61, 32, 20, 11, 200, 36, 225, 143, 72, 208, 84, 61, 32, 20, 11, 200, 17, 84, 12, 36, 176, 84, 61, 32, 20, 11, 200, 16, 85, 1, 36, 195, 9, 77, 64, 20, 11, 200, 16, 148, 212, 72, 144, 149, 21, 32, 20, 12, 137, 13, 1, 14, 195, 169, 18, 12, 9, 7, 20, 15, 204, 76, 83, 148, 36, 209, 78, 80, 19, 9, 76, 209, 64, 20, 9, 198, 60, 49, 65, 56, 145, 78, 20, 13, 138, 11, 195, 184, 2, 5, 14, 8, 1, 22, 14, 20, 7, 196, 5, 66, 5, 56, 20, 11, 200, 77, 81, 134, 36, 50, 69, 57, 64, 20, 11, 200, 44, 243, 139, 84, 34, 78, 5, 64, 20, 11, 200, 44, 243, 131, 20, 229, 18, 5, 64, 20, 11, 200, 4, 113, 204, 60, 209, 82, 5, 64, 20, 7, 196, 16, 82, 193, 56, 21, 9, 198, 52, 147, 137, 52, 19, 0, 20, 9, 198, 16, 145, 201, 80, 19, 0, 20, 0, 8, 197, 80, 83, 204, 60, 112, 20, 8, 197, 8, 147, 204, 60, 112, 20, 8, 197, 24, 147, 5, 72, 80, 20, 8, 197, 16, 244, 197, 72, 80, 20, 8, 197, 28, 83, 133, 76, 80, 20, 12, 201, 44, 194, 77, 4, 181, 5, 72, 145, 64, 20, 12, 201, 76, 83, 147, 84, 19, 9, 76, 209, 64, 20, 12, 201, 52, 243, 143, 64, 243, 9, 76, 209, 64, 20, 12, 201, 24, 81, 5, 72, 19, 9, 76, 209, 64, 20, 12, 201, 44, 243, 12, 20, 181, 18, 36, 49, 64, 20, 0, 9, 198, 84, 99, 204, 60, 114, 64, 20, 9, 198, 61, 67, 204, 60, 114, 64, 20, 9, 198, 21, 67, 204, 60, 114, 64, 20, 9, 198, 5, 3, 204, 60, 114, 64, 20, 13, 138, 8, 195, 184, 14, 19, 5, 18, 9, 19, 20, 20, 17, 206, 16, 145, 134, 21, 33, 78, 80, 144, 66, 36, 194, 84, 21, 64, 20, 14, 139, 15, 16, 20, 195, 166, 14, 11, 5, 12, 9, 7, 20, 9, 198, 21, 2, 68, 20, 210, 64, 20, 9, 198, 17, 84, 12, 36, 176, 84, 20, 9, 198, 13, 146, 204, 4, 208, 84, 20, 0, 9, 198, 32, 244, 148, 60, 227, 205, 20, 10, 199, 8, 150, 129, 73, 33, 82, 36, 20, 11, 136, 1, 14, 195, 166, 13, 9, 19, 11, 20, 10, 199, 16, 148, 195, 37, 3, 9, 56, 20, 9, 198, 16, 146, 207, 80, 243, 73, 20, 10, 199, 29, 147, 78, 5, 53, 9, 44, 20, 11, 67, 76, 149, 0, 89, 6, 37, 47, 0, 72, 0, 11, 200, 20, 208, 143, 84, 50, 21, 72, 80, 20, 11, 200, 5, 52, 217, 72, 147, 204, 60, 112, 20, 9, 198, 76, 245, 83, 4, 99, 206, 20, 11, 200, 29, 34, 77, 5, 52, 197, 72, 80, 20, 11, 200, 88, 148, 143, 48, 241, 201, 76, 176, 20, 11, 200, 80, 83, 5, 24, 243, 137, 76, 176, 20, 11, 200, 73, 83, 143, 48, 241, 201, 76, 176, 20, 11, 200, 53, 146, 207, 48, 241, 201, 76, 176, 20, 11, 200, 44, 20, 22, 21, 33, 9, 76, 176, 20, 11, 200, 36, 65, 79, 48, 241, 201, 76, 176, 20, 11, 200, 24, 147, 15, 48, 241, 201, 76, 176, 20, 11, 200, 16, 83, 65, 28, 241, 201, 76, 176, 20, 12, 137, 3, 195, 166, 19, 1, 18, 9, 19, 11, 20, 12, 137, 1, 18, 1, 13, 195, 166, 9, 19, 11, 20, 11, 200, 28, 20, 212, 72, 243, 143, 52, 144, 20, 15, 204, 81, 32, 68, 37, 66, 79, 56, 19, 9, 76, 209, 64, 20, 15, 204, 32, 84, 141, 4, 100, 143, 16, 149, 9, 76, 209, 64, 20, 9, 198, 45, 35, 193, 80, 145, 78, 20, 7, 196, 72, 243, 65, 56, 21, 0, 12, 201, 45, 34, 77, 36, 227, 204, 60, 114, 64, 20, 12, 201, 44, 194, 77, 5, 67, 204, 60, 114, 64, 20, 12, 201, 32, 84, 144, 21, 67, 204, 60, 114, 64, 20, 8, 197, 72, 21, 137, 56, 80, 20, 17, 142, 16, 21, 4, 19, 5, 12, 195, 184, 10, 5, 18, 12, 9, 7, 20, 13, 138, 6, 15, 18, 6, 195, 184, 18, 9, 19, 11, 20, 12, 201, 32, 84, 141, 4, 100, 143, 16, 149, 0, 20, 8, 197, 28, 84, 212, 36, 176, 20, 12, 201, 72, 81, 140, 20, 181, 5, 72, 85, 0, 20, 0, 14, 139, 1, 14, 195, 166, 19, 20, 5, 20, 9, 19, 11, 20, 12, 201, 77, 84, 208, 20, 228, 207, 72, 149, 77, 20, 12, 201, 44, 243, 147, 37, 53, 15, 72, 149, 77, 20, 9, 198, 4, 224, 84, 60, 210, 64, 20, 0, 6, 195, 4, 181, 84, 20, 10, 199, 36, 212, 5, 72, 21, 15, 72, 20, 10, 199, 20, 213, 76, 28, 21, 15, 72, 20, 9, 198, 56, 244, 212, 4, 193, 201, 20, 10, 199, 64, 243, 25, 4, 225, 18, 36, 20, 15, 140, 19, 25, 14, 195, 166, 19, 20, 5, 20, 9, 19, 11, 20, 15, 140, 11, 9, 14, 195, 166, 19, 20, 5, 20, 9, 19, 11, 20, 14, 203, 33, 83, 65, 56, 34, 79, 48, 241, 201, 76, 176, 20, 10, 199, 44, 243, 12, 20, 114, 65, 56, 20, 0, 11, 200, 60, 101, 1, 48, 211, 204, 60, 112, 20, 9, 198, 64, 150, 154, 36, 177, 82, 20, 9, 198, 36, 228, 208, 36, 49, 82, 20, 9, 198, 20, 180, 197, 72, 49, 82, 20, 9, 198, 17, 84, 12, 36, 49, 82, 20, 11, 200, 8, 20, 212, 5, 33, 5, 72, 80, 20, 16, 141, 195, 166, 7, 25, 16, 20, 15, 12, 15, 7, 9, 19, 11, 20, 11, 200, 77, 68, 129, 80, 81, 201, 76, 176, 20, 11, 200, 28, 83, 137, 80, 149, 137, 76, 176, 20, 11, 200, 17, 148, 204, 20, 181, 9, 76, 176, 20, 11, 200, 32, 85, 5, 72, 243, 143, 52, 144, 20, 7, 196, 88, 242, 193, 48, 20, 7, 196, 64, 242, 193, 48, 20, 7, 196, 24, 242, 193, 48, 20, 11, 200, 64, 192, 84, 52, 83, 129, 28, 80, 20, 0, 15, 5, 23, 3, 39, 5, 20, 84, 6, 36, 89, 36, 13, 72, 0, 12, 201, 89, 83, 11, 4, 227, 204, 60, 114, 64, 20, 12, 201, 28, 84, 143, 57, 67, 204, 60, 114, 64, 20, 9, 198, 72, 17, 9, 60, 195, 199, 20, 9, 198, 24, 147, 13, 60, 195, 199, 20, 13, 138, 1, 20, 8, 5, 14, 195, 166, 9, 19, 11, 20, 12, 201, 24, 20, 200, 36, 243, 133, 72, 85, 0, 20, 0, 10, 135, 195, 184, 11, 15, 12, 15, 7, 20, 9, 198, 76, 192, 86, 37, 53, 0, 20, 9, 198, 16, 144, 71, 72, 19, 64, 20, 12, 137, 16, 18, 195, 166, 13, 9, 5, 18, 5, 20, 9, 198, 65, 35, 194, 48, 83, 64, 20, 9, 198, 52, 18, 211, 36, 208, 76, 20, 0, 14, 5, 23, 3, 39, 5, 18, 84, 6, 36, 89, 36, 114, 0, 24, 73, 77, 21, 65, 72, 81, 1, 56, 49, 82, 89, 49, 58, 6, 36, 13, 72, 35, 12, 50, 89, 114, 0, 10, 199, 80, 83, 5, 60, 195, 199, 36, 20, 10, 199, 80, 82, 206, 60, 195, 199, 36, 20, 10, 199, 56, 85, 82, 60, 195, 199, 36, 20, 10, 199, 52, 244, 134, 60, 195, 199, 36, 20, 10, 199, 52, 85, 18, 60, 195, 199, 36, 20, 10, 199, 32, 20, 12, 60, 195, 199, 36, 20, 15, 140, 1, 18, 11, 195, 166, 15, 12, 15, 7, 9, 19, 11, 20, 12, 201, 20, 193, 75, 81, 35, 206, 36, 177, 82, 20, 12, 201, 65, 33, 83, 9, 149, 5, 72, 144, 78, 20, 7, 2, 95, 5, 36, 12, 0, 0, 7, 196, 48, 19, 69, 48, 20, 9, 198, 72, 82, 70, 36, 49, 82, 20, 9, 198, 52, 18, 211, 36, 209, 82, 20, 9, 198, 17, 84, 12, 36, 177, 82, 20, 9, 198, 5, 68, 143, 24, 145, 82, 20, 9, 198, 21, 35, 212, 36, 177, 82, 20, 7, 196, 64, 85, 9, 80, 20, 7, 196, 5, 81, 9, 80, 20, 7, 196, 28, 83, 65, 48, 20, 0, 9, 198, 28, 83, 77, 60, 195, 199, 20, 11, 136, 19, 195, 166, 20, 20, 5, 18, 9, 20, 11, 136, 14, 195, 165, 4, 12, 5, 18, 9, 20, 0, 13, 202, 44, 20, 129, 45, 65, 82, 60, 195, 199, 36, 20, 12, 137, 19, 11, 195, 166, 14, 4, 5, 18, 9, 20, 12, 137, 2, 18, 195, 166, 14, 4, 5, 18, 9, 20, 7, 2, 95, 9, 37, 12, 0, 0, 12, 201, 77, 148, 212, 20, 208, 84, 36, 177, 82, 20, 12, 201, 57, 83, 73, 76, 208, 84, 36, 177, 82, 20, 12, 201, 44, 148, 143, 52, 19, 148, 36, 177, 82, 20, 12, 201, 44, 20, 137, 76, 208, 84, 36, 177, 82, 20, 12, 201, 5, 53, 9, 28, 208, 84, 36, 177, 82, 20, 10, 199, 77, 64, 76, 4, 181, 9, 80, 20, 10, 199, 44, 243, 12, 20, 114, 65, 48, 20, 0, 13, 138, 4, 195, 166, 13, 15, 14, 9, 19, 5, 18, 20, 11, 200, 77, 81, 134, 36, 50, 69, 57, 48, 20, 0, 14, 139, 195, 184, 11, 15, 14, 15, 13, 9, 19, 5, 18, 20, 7, 196, 4, 113, 82, 20, 20, 17, 70, 24, 243, 132, 4, 229, 0, 83, 114, 68, 72, 6, 112, 68, 0, 20, 9, 198, 72, 80, 76, 37, 48, 66, 20, 9, 68, 81, 83, 133, 72, 21, 0, 10, 0, 9, 198, 77, 64, 84, 84, 84, 133, 20, 9, 198, 44, 19, 143, 56, 84, 133, 20, 9, 198, 17, 81, 76, 48, 84, 133, 20, 8, 197, 76, 244, 132, 36, 224, 20, 8, 197, 64, 82, 212, 36, 224, 20, 13, 202, 24, 244, 130, 73, 81, 197, 72, 148, 205, 20, 20, 8, 197, 65, 35, 208, 4, 224, 21, 0, 9, 198, 80, 245, 67, 32, 84, 128, 20, 9, 198, 76, 147, 85, 48, 84, 128, 20, 9, 198, 72, 83, 5, 28, 84, 128, 20, 9, 198, 72, 81, 133, 72, 84, 128, 20, 9, 198, 72, 81, 9, 28, 84, 128, 20, 9, 198, 61, 5, 9, 52, 84, 128, 20, 9, 198, 36, 229, 137, 80, 84, 128, 20, 9, 198, 36, 224, 201, 80, 84, 128, 20, 9, 198, 32, 243, 143, 72, 84, 128, 20, 9, 198, 32, 21, 129, 72, 84, 128, 20, 9, 198, 29, 32, 83, 76, 84, 128, 20, 9, 198, 16, 85, 143, 88, 84, 128, 20, 9, 198, 16, 83, 5, 28, 84, 128, 20, 9, 198, 16, 80, 201, 52, 84, 128, 20, 9, 198, 12, 128, 82, 28, 84, 128, 20, 9, 198, 12, 128, 78, 28, 84, 128, 20, 9, 198, 9, 32, 73, 76, 84, 128, 20, 9, 198, 4, 197, 5, 72, 84, 128, 20, 9, 198, 4, 69, 137, 76, 84, 128, 20, 9, 198, 48, 19, 73, 56, 20, 128, 20, 0, 6, 195, 85, 48, 64, 17, 10, 199, 72, 85, 143, 49, 65, 82, 20, 20, 10, 199, 24, 244, 141, 5, 65, 82, 20, 20, 10, 199, 60, 36, 212, 21, 68, 137, 44, 20, 12, 201, 36, 225, 9, 24, 97, 82, 20, 229, 0, 20, 0, 11, 200, 77, 80, 150, 20, 229, 9, 60, 224, 20, 11, 200, 65, 35, 208, 61, 37, 9, 60, 224, 20, 7, 196, 88, 243, 69, 72, 20, 12, 201, 16, 147, 69, 57, 50, 79, 56, 84, 133, 20, 11, 200, 24, 20, 195, 37, 53, 15, 36, 64, 20, 11, 200, 8, 83, 133, 16, 146, 212, 36, 224, 20, 9, 198, 17, 80, 140, 4, 229, 0, 20, 0, 12, 201, 81, 32, 78, 76, 69, 75, 80, 244, 128, 20, 12, 201, 72, 85, 137, 80, 19, 9, 76, 84, 128, 20, 12, 201, 52, 243, 143, 64, 243, 9, 76, 84, 128, 20, 12, 201, 32, 82, 212, 60, 116, 129, 24, 84, 128, 20, 12, 201, 16, 83, 73, 77, 50, 79, 56, 84, 128, 20, 12, 201, 5, 85, 15, 52, 21, 9, 76, 84, 128, 20, 8, 197, 64, 148, 212, 60, 192, 20, 11, 136, 21, 18, 195, 166, 13, 9, 19, 11, 20, 8, 197, 88, 147, 204, 36, 224, 20, 8, 197, 8, 133, 84, 4, 224, 20, 8, 197, 8, 133, 84, 4, 224, 21, 8, 197, 72, 149, 21, 4, 192, 20, 0, 11, 200, 21, 2, 68, 36, 20, 203, 61, 0, 20, 9, 198, 52, 21, 1, 16, 244, 128, 20, 9, 198, 45, 84, 129, 80, 244, 128, 20, 9, 198, 81, 32, 83, 76, 84, 128, 20, 9, 198, 77, 84, 16, 48, 84, 128, 20, 9, 198, 72, 81, 21, 12, 84, 128, 20, 9, 198, 53, 83, 11, 80, 84, 128, 20, 9, 198, 36, 226, 137, 12, 84, 128, 20, 9, 198, 36, 226, 9, 8, 84, 128, 20, 9, 198, 36, 225, 140, 84, 84, 128, 20, 9, 198, 36, 225, 137, 12, 84, 128, 20, 9, 198, 36, 115, 143, 72, 84, 128, 20, 9, 198, 16, 84, 137, 88, 84, 128, 20, 9, 198, 16, 81, 137, 56, 84, 128, 20, 9, 198, 16, 81, 21, 12, 84, 128, 20, 9, 198, 16, 81, 9, 44, 84, 128, 20, 9, 198, 16, 81, 9, 12, 84, 128, 20, 9, 198, 4, 97, 137, 12, 84, 128, 20, 9, 198, 4, 69, 143, 44, 84, 128, 20, 9, 198, 8, 145, 137, 48, 20, 128, 20, 11, 70, 76, 48, 78, 56, 84, 128, 21, 0, 10, 0, 10, 199, 52, 18, 213, 48, 21, 21, 72, 20, 10, 199, 64, 192, 71, 36, 21, 15, 72, 20, 10, 199, 16, 84, 133, 29, 83, 5, 72, 20, 0, 11, 200, 72, 81, 146, 4, 181, 9, 60, 224, 20, 11, 200, 44, 243, 150, 20, 229, 9, 60, 224, 20, 11, 200, 36, 228, 197, 45, 66, 67, 36, 64, 20, 11, 200, 8, 18, 212, 21, 34, 67, 36, 64, 20, 11, 200, 29, 80, 84, 20, 208, 76, 4, 224, 20, 11, 200, 76, 82, 83, 52, 241, 210, 4, 96, 20, 11, 200, 60, 49, 65, 56, 241, 210, 4, 96, 20, 11, 200, 44, 20, 132, 36, 241, 210, 4, 96, 20, 11, 200, 8, 144, 140, 36, 241, 210, 4, 96, 20, 0, 8, 197, 76, 82, 212, 61, 32, 20, 12, 201, 80, 245, 1, 48, 148, 193, 80, 244, 128, 20, 12, 201, 72, 84, 212, 5, 84, 129, 80, 244, 128, 20, 12, 201, 44, 243, 15, 56, 148, 193, 80, 244, 128, 20, 12, 201, 44, 21, 1, 49, 148, 193, 80, 244, 128, 20, 12, 201, 81, 34, 86, 36, 19, 9, 76, 84, 128, 20, 12, 201, 81, 32, 85, 52, 21, 9, 76, 84, 128, 20, 12, 201, 77, 66, 71, 52, 21, 9, 76, 84, 128, 20, 12, 201, 76, 82, 211, 84, 19, 9, 76, 84, 128, 20, 12, 201, 56, 243, 73, 56, 19, 9, 76, 84, 128, 20, 12, 201, 53, 84, 201, 44, 19, 9, 76, 84, 128, 20, 12, 201, 48, 144, 133, 72, 19, 9, 76, 84, 128, 20, 12, 201, 40, 245, 82, 56, 19, 9, 76, 84, 128, 20, 12, 201, 36, 211, 79, 8, 147, 9, 76, 84, 128, 20, 12, 201, 32, 245, 141, 21, 53, 5, 72, 84, 128, 20, 12, 201, 32, 243, 79, 48, 241, 201, 76, 84, 128, 20, 12, 201, 8, 84, 212, 36, 19, 9, 76, 84, 128, 20, 8, 197, 4, 195, 9, 21, 32, 20, 12, 201, 8, 244, 148, 4, 67, 208, 80, 84, 128, 20, 9, 198, 44, 195, 214, 56, 84, 137, 20, 12, 201, 29, 32, 77, 52, 21, 9, 44, 84, 128, 20, 12, 201, 24, 193, 71, 52, 21, 9, 44, 84, 128, 20, 12, 201, 16, 21, 1, 52, 21, 9, 44, 84, 128, 20, 8, 197, 25, 33, 71, 5, 64, 20, 0, 9, 198, 33, 148, 14, 61, 49, 64, 20, 15, 140, 16, 18, 195, 166, 16, 1, 18, 1, 20, 9, 15, 14, 20, 9, 198, 24, 147, 133, 77, 49, 64, 20, 9, 198, 4, 35, 206, 56, 83, 148, 20, 9, 198, 17, 80, 140, 20, 19, 148, 20, 0, 10, 199, 24, 244, 141, 21, 34, 78, 28, 20, 6, 195, 80, 147, 0, 76, 6, 195, 88, 83, 0, 76, 0, 11, 136, 7, 18, 195, 166, 3, 9, 19, 20, 20, 17, 142, 16, 18, 195, 166, 14, 21, 13, 5, 18, 1, 20, 9, 15, 14, 20, 11, 200, 24, 19, 19, 36, 98, 75, 5, 64, 20, 0, 8, 197, 16, 85, 137, 21, 32, 20, 9, 198, 76, 225, 68, 44, 84, 137, 20, 12, 201, 4, 68, 203, 36, 195, 5, 48, 145, 192, 20, 12, 201, 76, 82, 211, 84, 19, 9, 76, 209, 64, 20, 9, 198, 29, 33, 86, 36, 225, 5, 20, 12, 201, 61, 48, 201, 48, 195, 199, 72, 17, 128, 20, 12, 201, 20, 229, 18, 21, 4, 133, 56, 19, 148, 20, 6, 195, 88, 81, 0, 76, 0, 10, 66, 92, 48, 84, 6, 36, 89, 36, 0, 9, 198, 56, 243, 73, 56, 83, 0, 20, 9, 198, 64, 20, 129, 76, 243, 0, 20, 9, 198, 72, 147, 69, 77, 49, 64, 20, 14, 139, 6, 1, 18, 9, 19, 195, 166, 9, 19, 13, 5, 20, 9, 198, 36, 224, 201, 16, 83, 148, 20, 9, 198, 29, 32, 68, 36, 83, 148, 20, 9, 198, 16, 242, 213, 52, 83, 148, 20, 9, 198, 48, 144, 133, 72, 19, 0, 20, 9, 198, 28, 192, 67, 36, 19, 0, 20, 0, 0, 11, 200, 44, 243, 80, 36, 192, 84, 61, 32, 20, 14, 70, 8, 82, 71, 56, 85, 0, 71, 36, 68, 36, 0, 66, 7, 196, 72, 242, 197, 72, 20, 11, 200, 44, 243, 148, 72, 144, 149, 21, 32, 20, 9, 198, 24, 18, 212, 60, 145, 0, 20, 9, 198, 24, 21, 143, 72, 149, 0, 20, 9, 198, 4, 181, 129, 88, 149, 0, 20, 16, 141, 195, 166, 11, 22, 9, 12, 9, 2, 18, 9, 19, 13, 5, 20, 15, 204, 76, 83, 147, 5, 66, 79, 56, 19, 9, 76, 209, 64, 20, 9, 198, 21, 68, 149, 72, 145, 78, 20, 9, 198, 29, 32, 83, 76, 21, 0, 20, 9, 198, 16, 83, 5, 28, 21, 0, 20, 0, 9, 198, 16, 144, 83, 44, 244, 0, 20, 8, 197, 5, 96, 78, 12, 80, 20, 8, 197, 76, 181, 76, 48, 80, 76, 0, 20, 67, 16, 82, 129, 72, 36, 91, 57, 35, 15, 6, 84, 116, 0, 44, 81, 118, 117, 32, 9, 198, 24, 19, 148, 5, 50, 64, 20, 14, 139, 13, 1, 12, 20, 7, 195, 184, 18, 5, 18, 9, 20, 9, 198, 52, 85, 18, 61, 3, 204, 20, 0, 12, 137, 22, 15, 12, 20, 9, 7, 195, 184, 18, 20, 10, 199, 72, 80, 133, 48, 194, 79, 56, 20, 12, 201, 77, 3, 206, 80, 19, 137, 80, 85, 0, 20, 10, 199, 72, 81, 210, 20, 66, 69, 72, 20, 10, 199, 64, 146, 193, 57, 65, 82, 36, 20, 10, 199, 24, 245, 15, 52, 85, 18, 36, 20, 10, 199, 24, 147, 9, 77, 65, 82, 36, 20, 10, 199, 8, 145, 207, 81, 65, 82, 36, 20, 10, 199, 5, 37, 9, 77, 65, 82, 36, 20, 10, 199, 44, 243, 5, 72, 146, 197, 72, 20, 10, 199, 56, 20, 139, 60, 208, 78, 36, 20, 10, 199, 61, 32, 78, 28, 80, 68, 20, 20, 0, 7, 196, 72, 85, 21, 72, 20, 11, 200, 44, 20, 132, 36, 243, 15, 28, 144, 20, 11, 200, 64, 83, 1, 72, 115, 206, 36, 80, 20, 20, 145, 1, 6, 22, 195, 166, 18, 7, 5, 13, 5, 11, 1, 14, 9, 19, 13, 5, 20, 11, 136, 16, 195, 166, 4, 15, 6, 9, 12, 20, 0, 30, 69, 69, 82, 67, 32, 80, 49, 37, 91, 15, 55, 39, 34, 6, 109, 12, 50, 12, 0, 81, 108, 111, 114, 114, 97, 105, 110, 101, 32, 10, 135, 12, 5, 11, 20, 195, 184, 18, 20, 15, 140, 13, 1, 14, 195, 184, 22, 18, 5, 18, 9, 14, 7, 20, 9, 198, 28, 84, 141, 4, 226, 69, 20, 9, 198, 12, 84, 133, 52, 243, 137, 20, 8, 197, 56, 245, 137, 12, 80, 20, 8, 197, 64, 19, 129, 16, 80, 20, 8, 197, 56, 18, 129, 16, 80, 20, 15, 2, 95, 33, 40, 72, 51, 114, 71, 89, 47, 36, 57, 50, 0, 0, 20, 67, 4, 195, 5, 110, 55, 108, 15, 89, 47, 6, 36, 0, 81, 115, 116, 101, 103, 32, 16, 141, 16, 18, 195, 166, 19, 5, 18, 22, 5, 18, 9, 14, 7, 20, 16, 141, 4, 195, 166, 13, 15, 14, 9, 19, 5, 18, 9, 14, 7, 20, 13, 202, 80, 147, 6, 61, 35, 1, 16, 83, 9, 28, 20, 9, 198, 56, 245, 137, 12, 144, 84, 20, 9, 198, 24, 16, 146, 36, 176, 84, 20, 0, 13, 138, 9, 14, 6, 5, 11, 20, 9, 195, 184, 19, 20, 12, 201, 76, 243, 9, 16, 20, 137, 80, 85, 0, 20, 12, 201, 72, 81, 213, 48, 20, 137, 80, 85, 0, 20, 17, 142, 195, 184, 11, 15, 14, 15, 13, 9, 19, 5, 18, 9, 14, 7, 20, 13, 138, 20, 18, 195, 166, 14, 5, 18, 9, 14, 7, 20, 9, 198, 45, 84, 5, 72, 147, 135, 20, 10, 199, 44, 244, 212, 84, 210, 69, 72, 20, 10, 199, 60, 208, 146, 100, 65, 82, 36, 20, 10, 199, 52, 20, 203, 36, 225, 82, 36, 20, 10, 199, 45, 32, 75, 36, 193, 82, 36, 20, 12, 201, 81, 32, 78, 77, 97, 83, 80, 149, 0, 20, 12, 201, 52, 84, 207, 64, 245, 1, 52, 145, 78, 20, 10, 199, 80, 19, 80, 60, 224, 68, 20, 20, 10, 199, 44, 243, 15, 56, 224, 68, 20, 20, 0, 13, 138, 9, 14, 19, 16, 5, 11, 20, 195, 184, 18, 20, 11, 200, 52, 85, 15, 16, 243, 15, 28, 144, 20, 11, 200, 45, 34, 83, 80, 243, 15, 28, 144, 20, 11, 200, 20, 229, 15, 52, 243, 15, 28, 144, 20, 15, 204, 16, 83, 132, 72, 242, 210, 60, 227, 204, 60, 114, 64, 20, 9, 198, 36, 225, 12, 60, 113, 82, 20, 9, 198, 24, 16, 146, 36, 177, 82, 20, 9, 198, 20, 112, 76, 37, 49, 82, 20, 11, 200, 16, 145, 148, 60, 225, 197, 72, 80, 20, 9, 198, 16, 84, 18, 36, 209, 82, 20, 9, 198, 16, 81, 143, 72, 209, 82, 20, 9, 198, 4, 227, 196, 37, 49, 82, 20, 11, 200, 24, 244, 141, 100, 225, 5, 72, 144, 20, 9, 198, 37, 35, 206, 36, 177, 82, 20, 11, 200, 44, 243, 21, 52, 32, 82, 36, 80, 20, 11, 200, 44, 19, 5, 56, 64, 82, 36, 80, 20, 21, 72, 80, 244, 148, 20, 195, 9, 56, 144, 47, 114, 47, 13, 55, 6, 37, 50, 37, 0, 20, 7, 196, 88, 148, 137, 48, 20, 9, 198, 52, 20, 143, 44, 176, 78, 20, 8, 67, 76, 243, 135, 21, 0, 10, 0, 14, 139, 1, 11, 21, 16, 21, 14, 11, 20, 195, 184, 18, 20, 15, 140, 7, 18, 195, 166, 3, 9, 19, 5, 18, 9, 14, 7, 20, 9, 198, 44, 192, 77, 52, 84, 137, 20, 9, 198, 9, 38, 71, 28, 84, 137, 20, 9, 198, 56, 18, 86, 37, 51, 69, 20, 13, 70, 20, 228, 197, 52, 35, 5, 21, 102, 114, 0, 10, 0, 9, 198, 77, 147, 132, 72, 243, 64, 20, 12, 201, 72, 81, 201, 77, 68, 133, 72, 147, 135, 20, 12, 201, 61, 34, 197, 77, 68, 133, 72, 147, 135, 20, 12, 201, 44, 243, 80, 20, 228, 197, 72, 147, 135, 20, 12, 201, 36, 225, 137, 49, 68, 133, 72, 147, 135, 20, 12, 201, 36, 195, 21, 77, 68, 133, 72, 147, 135, 20, 12, 201, 4, 208, 76, 28, 19, 69, 72, 147, 135, 20, 9, 198, 88, 19, 129, 16, 147, 128, 20, 9, 198, 52, 83, 1, 52, 147, 128, 20, 9, 198, 37, 64, 76, 36, 83, 128, 20, 0, 19, 67, 16, 83, 128, 72, 6, 109, 50, 15, 107, 36, 34, 0, 81, 104, 101, 114, 32, 19, 67, 16, 83, 128, 72, 6, 109, 50, 15, 72, 36, 34, 0, 81, 100, 101, 114, 32, 16, 141, 3, 8, 5, 6, 18, 5, 4, 1, 11, 20, 195, 184, 18, 20, 10, 199, 80, 21, 84, 60, 195, 199, 36, 20, 10, 199, 76, 240, 201, 60, 195, 199, 36, 20, 10, 199, 76, 83, 73, 60, 195, 199, 36, 20, 10, 199, 65, 54, 75, 60, 195, 199, 36, 20, 10, 199, 33, 145, 18, 60, 195, 199, 36, 20, 10, 199, 25, 148, 201, 60, 195, 199, 36, 20, 10, 199, 21, 70, 77, 60, 195, 199, 36, 20, 12, 201, 45, 38, 83, 80, 19, 12, 37, 49, 82, 20, 12, 201, 32, 244, 208, 37, 64, 76, 37, 49, 82, 20, 10, 199, 84, 197, 9, 52, 21, 21, 52, 20, 10, 199, 5, 85, 15, 52, 240, 137, 48, 20, 10, 135, 13, 195, 166, 18, 11, 1, 20, 20, 11, 70, 72, 86, 78, 60, 193, 19, 21, 0, 10, 10, 67, 16, 83, 128, 72, 109, 50, 0, 72, 0, 9, 198, 72, 80, 197, 57, 49, 82, 20, 9, 198, 44, 243, 135, 73, 81, 82, 20, 12, 201, 77, 6, 84, 76, 194, 75, 44, 84, 137, 20, 12, 201, 32, 243, 204, 36, 112, 78, 37, 51, 69, 20, 12, 201, 25, 33, 85, 16, 144, 78, 37, 51, 69, 20, 12, 201, 8, 20, 148, 32, 144, 78, 37, 51, 69, 20, 12, 201, 4, 209, 82, 36, 176, 78, 37, 51, 69, 20, 7, 196, 61, 35, 129, 80, 20, 9, 198, 5, 53, 18, 4, 176, 78, 21, 20, 4, 95, 3, 1, 16, 89, 47, 39, 114, 47, 15, 71, 39, 40, 89, 47, 35, 58, 0, 0, 9, 198, 104, 144, 133, 48, 147, 133, 20, 9, 198, 76, 243, 129, 80, 147, 133, 20, 14, 139, 16, 18, 195, 166, 10, 21, 4, 9, 3, 5, 18, 20, 9, 198, 76, 213, 71, 48, 84, 137, 20, 12, 201, 44, 20, 130, 60, 194, 78, 21, 83, 64, 20, 9, 198, 85, 67, 208, 37, 51, 69, 20, 9, 198, 72, 80, 76, 37, 51, 69, 20, 9, 198, 56, 244, 132, 37, 51, 69, 20, 9, 198, 21, 35, 212, 37, 51, 69, 20, 9, 198, 17, 80, 76, 37, 51, 69, 20, 11, 70, 16, 80, 68, 48, 147, 133, 21, 0, 10, 0, 9, 198, 44, 21, 84, 36, 243, 128, 20, 12, 201, 84, 226, 70, 61, 35, 69, 72, 147, 135, 20, 12, 201, 77, 65, 78, 12, 147, 5, 72, 147, 135, 20, 12, 201, 52, 19, 137, 65, 83, 5, 72, 147, 135, 20, 12, 201, 48, 81, 201, 80, 147, 69, 72, 147, 135, 20, 12, 201, 44, 243, 132, 20, 228, 197, 72, 147, 135, 20, 12, 201, 44, 243, 80, 72, 147, 69, 72, 147, 135, 20, 12, 201, 44, 192, 85, 77, 83, 5, 72, 147, 135, 20, 12, 201, 44, 20, 148, 60, 227, 133, 72, 147, 135, 20, 12, 201, 44, 19, 148, 60, 227, 133, 72, 147, 135, 20, 12, 201, 16, 148, 208, 20, 228, 197, 72, 147, 135, 20, 12, 201, 13, 84, 20, 85, 35, 133, 72, 147, 135, 20, 12, 201, 5, 52, 201, 52, 147, 5, 72, 147, 135, 20, 12, 201, 4, 178, 213, 53, 83, 5, 72, 147, 135, 20, 9, 198, 5, 68, 129, 104, 147, 128, 20, 9, 198, 5, 32, 66, 36, 83, 128, 20, 9, 198, 80, 144, 133, 80, 19, 128, 20, 9, 198, 4, 33, 83, 76, 147, 128, 20, 9, 198, 52, 83, 79, 72, 144, 76, 20, 0, 12, 201, 44, 20, 129, 45, 65, 82, 37, 49, 82, 20, 12, 201, 20, 97, 133, 45, 66, 86, 37, 49, 82, 20, 12, 201, 12, 243, 80, 85, 65, 82, 37, 49, 82, 20, 12, 201, 4, 209, 82, 36, 176, 78, 37, 49, 82, 20, 10, 199, 5, 81, 9, 80, 244, 137, 20, 20, 10, 199, 84, 226, 79, 56, 148, 205, 20, 20, 10, 199, 76, 21, 1, 56, 148, 205, 20, 20, 10, 199, 48, 240, 130, 100, 148, 205, 20, 20, 15, 204, 29, 37, 78, 17, 69, 137, 28, 144, 78, 37, 51, 69, 20, 10, 199, 77, 66, 77, 84, 192, 78, 76, 20, 8, 67, 92, 244, 132, 21, 0, 10, 6, 195, 32, 84, 128, 72, 0, 17, 142, 16, 18, 195, 166, 11, 22, 1, 12, 9, 6, 9, 3, 5, 18, 20, 12, 201, 77, 147, 132, 36, 176, 76, 37, 51, 69, 20, 12, 201, 52, 21, 5, 72, 144, 76, 37, 51, 69, 20, 12, 201, 36, 225, 129, 57, 66, 76, 37, 51, 69, 20, 12, 201, 36, 212, 5, 72, 144, 76, 37, 51, 69, 20, 7, 196, 17, 84, 129, 8, 20, 11, 2, 95, 46, 48, 113, 68, 47, 113, 65, 0, 0, 9, 198, 28, 83, 133, 72, 84, 133, 20, 9, 198, 5, 34, 201, 88, 84, 133, 20, 8, 197, 4, 224, 66, 60, 192, 20, 8, 197, 81, 145, 143, 36, 64, 20, 8, 197, 64, 19, 13, 36, 224, 20, 15, 69, 76, 84, 129, 36, 192, 89, 36, 34, 6, 35, 57, 0, 20, 12, 201, 52, 21, 82, 21, 64, 78, 36, 83, 128, 20, 8, 197, 64, 84, 137, 4, 192, 20, 8, 197, 56, 244, 141, 4, 192, 20, 8, 197, 52, 19, 149, 4, 192, 20, 15, 2, 95, 45, 71, 37, 50, 50, 36, 89, 72, 34, 35, 37, 0, 0, 9, 198, 20, 161, 75, 80, 244, 128, 20, 9, 198, 80, 149, 21, 48, 84, 128, 20, 9, 198, 72, 83, 143, 88, 84, 128, 20, 9, 198, 64, 192, 71, 36, 84, 128, 20, 9, 198, 48, 147, 73, 80, 84, 128, 20, 9, 198, 20, 208, 76, 40, 84, 128, 20, 9, 198, 4, 99, 5, 88, 84, 128, 20, 13, 202, 77, 80, 138, 20, 181, 9, 88, 148, 205, 20, 20, 13, 202, 64, 20, 139, 36, 228, 207, 56, 148, 205, 20, 20, 9, 198, 80, 19, 135, 20, 228, 192, 20, 9, 198, 76, 19, 79, 88, 20, 128, 20, 9, 198, 72, 148, 201, 44, 16, 128, 20, 9, 198, 44, 243, 147, 80, 16, 128, 20, 11, 2, 95, 44, 49, 6, 39, 65, 35, 12, 0, 0, 12, 67, 53, 36, 192, 65, 36, 89, 36, 89, 0, 25, 10, 199, 28, 83, 194, 36, 243, 15, 28, 20, 10, 199, 80, 18, 206, 20, 211, 9, 28, 20, 10, 199, 16, 144, 76, 60, 114, 83, 44, 20, 15, 204, 36, 229, 5, 48, 193, 75, 81, 80, 76, 37, 51, 69, 20, 10, 199, 20, 180, 197, 53, 3, 1, 72, 20, 10, 67, 88, 20, 128, 84, 112, 34, 0, 76, 11, 67, 16, 84, 128, 72, 109, 34, 0, 76, 72, 9, 2, 95, 51, 47, 51, 6, 36, 0, 0, 11, 200, 32, 244, 147, 20, 228, 201, 4, 224, 20, 8, 2, 95, 50, 47, 6, 39, 0, 0, 9, 198, 25, 37, 75, 80, 244, 197, 20, 12, 201, 77, 147, 139, 72, 85, 9, 76, 84, 128, 20, 12, 201, 77, 65, 78, 60, 116, 129, 24, 84, 128, 20, 12, 201, 72, 82, 193, 64, 149, 21, 48, 84, 128, 20, 12, 201, 64, 19, 1, 80, 19, 9, 76, 84, 128, 20, 12, 201, 44, 19, 12, 36, 116, 129, 24, 84, 128, 20, 12, 201, 36, 229, 5, 73, 4, 133, 80, 84, 128, 20, 12, 201, 24, 244, 198, 61, 33, 83, 12, 84, 128, 20, 12, 201, 16, 145, 201, 80, 19, 9, 76, 84, 128, 20, 12, 201, 12, 128, 80, 80, 19, 9, 76, 84, 128, 20, 12, 201, 4, 193, 129, 8, 85, 9, 76, 84, 128, 20, 8, 197, 77, 147, 66, 60, 192, 20, 8, 197, 12, 128, 84, 60, 192, 20, 9, 198, 44, 21, 1, 80, 243, 137, 20, 8, 197, 76, 240, 201, 4, 192, 20, 8, 197, 24, 244, 141, 4, 192, 20, 9, 2, 95, 49, 6, 36, 12, 50, 0, 0, 9, 198, 64, 144, 193, 16, 244, 128, 20, 9, 198, 77, 3, 206, 76, 244, 128, 20, 9, 198, 80, 20, 137, 24, 84, 128, 20, 9, 198, 76, 180, 129, 88, 84, 128, 20, 9, 198, 64, 20, 129, 24, 84, 128, 20, 9, 198, 64, 19, 143, 72, 84, 128, 20, 9, 198, 53, 84, 201, 12, 84, 128, 20, 9, 198, 48, 16, 143, 72, 84, 128, 20, 9, 198, 37, 36, 137, 80, 84, 128, 20, 9, 198, 29, 32, 68, 84, 84, 128, 20, 9, 198, 25, 35, 212, 80, 84, 128, 20, 9, 198, 21, 96, 76, 84, 84, 128, 20, 9, 198, 20, 228, 201, 48, 84, 128, 20, 9, 198, 17, 81, 84, 80, 84, 128, 20, 9, 198, 17, 33, 83, 76, 84, 128, 20, 9, 198, 16, 83, 79, 48, 84, 128, 20, 9, 198, 4, 35, 206, 56, 84, 128, 20, 13, 202, 44, 194, 77, 5, 67, 204, 60, 114, 83, 44, 20, 9, 198, 45, 96, 82, 81, 50, 84, 20, 9, 198, 76, 83, 73, 56, 20, 128, 20, 9, 2, 95, 48, 6, 50, 113, 55, 0, 0, 10, 199, 45, 96, 68, 72, 21, 21, 72, 20, 10, 199, 44, 243, 15, 72, 21, 21, 72, 20, 10, 199, 5, 4, 1, 72, 21, 21, 72, 20, 11, 136, 7, 5, 15, 4, 195, 166, 19, 9, 20, 12, 201, 88, 84, 137, 24, 146, 193, 80, 147, 206, 20, 12, 201, 56, 245, 9, 24, 146, 193, 80, 147, 206, 20, 12, 201, 44, 243, 80, 48, 146, 193, 80, 147, 206, 20, 12, 201, 20, 180, 208, 48, 146, 193, 80, 147, 206, 20, 10, 199, 4, 208, 76, 28, 19, 69, 72, 20, 10, 199, 28, 241, 22, 36, 195, 9, 28, 20, 10, 199, 80, 85, 84, 60, 226, 83, 44, 20, 9, 198, 41, 84, 137, 16, 148, 203, 20, 10, 199, 21, 82, 204, 36, 66, 83, 44, 20, 10, 199, 44, 193, 80, 80, 243, 65, 56, 21, 9, 198, 64, 243, 69, 72, 19, 147, 20, 10, 199, 44, 243, 69, 16, 144, 78, 80, 20, 9, 2, 95, 55, 89, 6, 116, 58, 0, 0, 9, 198, 36, 210, 84, 5, 67, 210, 20, 9, 198, 4, 114, 84, 5, 67, 210, 20, 12, 201, 25, 83, 132, 4, 209, 78, 80, 84, 133, 20, 9, 198, 16, 19, 65, 77, 50, 78, 20, 11, 200, 72, 19, 132, 73, 84, 201, 4, 224, 20, 6, 195, 16, 83, 147, 76, 10, 2, 95, 54, 89, 6, 109, 81, 89, 0, 0, 12, 201, 61, 33, 193, 56, 148, 193, 80, 244, 128, 20, 12, 201, 16, 84, 212, 36, 195, 1, 80, 244, 128, 20, 12, 201, 80, 84, 141, 60, 116, 129, 24, 84, 128, 20, 12, 201, 80, 80, 84, 72, 19, 9, 76, 84, 128, 20, 12, 201, 77, 1, 67, 36, 19, 9, 76, 84, 128, 20, 12, 201, 76, 176, 78, 16, 19, 9, 76, 84, 128, 20, 12, 201, 76, 49, 78, 60, 116, 129, 24, 84, 128, 20, 12, 201, 72, 17, 9, 44, 19, 9, 76, 84, 128, 20, 12, 201, 56, 85, 84, 72, 19, 9, 76, 84, 128, 20, 12, 201, 56, 21, 21, 72, 19, 9, 76, 84, 128, 20, 12, 201, 44, 244, 133, 60, 116, 129, 24, 84, 128, 20, 8, 197, 44, 195, 210, 21, 32, 20, 12, 201, 44, 20, 9, 80, 19, 9, 76, 84, 128, 20, 12, 201, 28, 83, 137, 57, 97, 83, 80, 84, 128, 20, 12, 201, 36, 226, 84, 36, 19, 9, 76, 84, 128, 20, 12, 201, 28, 83, 133, 72, 19, 9, 76, 84, 128, 20, 12, 201, 24, 195, 210, 4, 116, 129, 24, 84, 128, 20, 12, 201, 16, 21, 1, 52, 21, 9, 76, 84, 128, 20, 9, 198, 76, 165, 83, 44, 84, 137, 20, 9, 198, 44, 226, 82, 44, 84, 137, 20, 12, 201, 65, 32, 71, 52, 21, 9, 44, 84, 128, 20, 12, 201, 52, 85, 1, 25, 148, 201, 44, 84, 128, 20, 12, 201, 52, 21, 5, 52, 21, 9, 44, 84, 128, 20, 12, 201, 5, 34, 84, 52, 85, 9, 44, 84, 128, 20, 12, 201, 4, 227, 210, 20, 181, 9, 44, 84, 128, 20, 9, 198, 32, 83, 20, 36, 225, 5, 20, 12, 201, 76, 145, 206, 36, 98, 75, 4, 228, 192, 20, 9, 2, 95, 53, 83, 6, 109, 65, 0, 0, 15, 204, 20, 180, 203, 60, 211, 85, 56, 146, 193, 80, 147, 206, 20, 15, 204, 20, 180, 197, 53, 3, 9, 24, 146, 193, 80, 147, 206, 20, 12, 201, 25, 147, 15, 28, 83, 133, 80, 148, 203, 20, 9, 198, 16, 149, 82, 21, 49, 64, 20, 9, 198, 81, 32, 83, 76, 83, 148, 20, 9, 198, 36, 212, 15, 80, 83, 148, 20, 12, 201, 24, 244, 198, 61, 33, 83, 12, 83, 147, 20, 9, 198, 24, 16, 149, 48, 19, 148, 20, 9, 198, 20, 210, 71, 72, 19, 148, 20, 9, 198, 16, 243, 73, 56, 19, 148, 20, 9, 198, 16, 80, 149, 80, 19, 148, 20, 9, 198, 4, 208, 149, 48, 19, 148, 20, 10, 2, 95, 52, 83, 6, 37, 12, 114, 0, 0, 9, 198, 36, 225, 140, 84, 83, 147, 20, 9, 198, 16, 243, 73, 56, 19, 147, 20, 17, 2, 95, 59, 89, 36, 12, 65, 37, 12, 49, 39, 12, 55, 114, 50, 0, 0, 9, 198, 61, 1, 82, 5, 67, 210, 20, 9, 198, 36, 226, 133, 45, 67, 210, 20, 15, 204, 76, 83, 148, 36, 209, 78, 80, 19, 9, 76, 84, 128, 20, 11, 200, 72, 85, 129, 12, 50, 78, 21, 32, 20, 11, 200, 44, 243, 12, 4, 35, 210, 21, 32, 20, 11, 200, 32, 19, 12, 84, 50, 78, 21, 32, 20, 18, 70, 52, 20, 143, 69, 82, 78, 65, 112, 34, 39, 6, 49, 109, 68, 0, 20, 12, 2, 95, 58, 49, 6, 39, 12, 55, 114, 50, 0, 0, 12, 201, 8, 147, 8, 5, 38, 137, 61, 49, 64, 20, 8, 197, 80, 149, 18, 21, 32, 20, 8, 197, 61, 1, 82, 21, 32, 20, 8, 197, 48, 149, 18, 21, 32, 20, 8, 197, 20, 208, 78, 21, 32, 20, 9, 198, 77, 66, 75, 44, 84, 137, 20, 9, 198, 17, 34, 75, 44, 84, 137, 20, 12, 201, 36, 229, 5, 73, 97, 78, 36, 83, 148, 20, 8, 2, 95, 57, 50, 6, 37, 0, 0, 9, 198, 44, 20, 129, 52, 83, 0, 20, 9, 198, 65, 35, 212, 21, 49, 64, 20, 9, 198, 16, 144, 84, 21, 49, 64, 20, 14, 139, 1, 13, 1, 20, 195, 184, 18, 9, 19, 13, 5, 20, 9, 198, 12, 128, 82, 52, 19, 148, 20, 10, 2, 95, 56, 6, 113, 12, 72, 13, 0, 0, 9, 134, 16, 15, 18, 195, 184, 19, 20, 15, 140, 6, 195, 184, 4, 5, 18, 1, 12, 9, 19, 13, 5, 20, 10, 199, 44, 19, 85, 24, 192, 71, 20, 20, 12, 71, 36, 229, 5, 72, 96, 67, 20, 21, 0, 10, 19, 2, 95, 63, 89, 48, 118, 34, 81, 89, 65, 114, 55, 89, 47, 35, 57, 50, 0, 0, 9, 134, 13, 9, 14, 195, 184, 18, 20, 9, 134, 12, 9, 11, 195, 184, 18, 20, 11, 200, 64, 84, 147, 21, 97, 82, 21, 32, 20, 11, 200, 44, 243, 134, 36, 117, 82, 21, 32, 20, 11, 200, 36, 226, 210, 36, 210, 78, 21, 32, 20, 11, 200, 16, 85, 5, 72, 210, 78, 21, 32, 20, 11, 200, 4, 195, 9, 81, 65, 82, 21, 32, 20, 11, 200, 5, 4, 5, 56, 66, 67, 37, 64, 20, 7, 196, 81, 148, 129, 56, 21, 0, 9, 198, 29, 147, 78, 5, 50, 69, 20, 8, 197, 4, 176, 67, 36, 80, 20, 9, 198, 29, 147, 78, 5, 50, 69, 20, 8, 197, 52, 244, 193, 36, 176, 20, 8, 197, 29, 32, 70, 36, 176, 20, 12, 201, 36, 228, 213, 24, 98, 67, 36, 83, 148, 20, 8, 197, 24, 16, 193, 16, 80, 20, 0, 11, 136, 19, 13, 9, 14, 11, 195, 184, 18, 20, 9, 198, 52, 243, 132, 36, 19, 0, 20, 9, 198, 45, 96, 82, 80, 19, 0, 20, 0, 12, 201, 84, 227, 210, 52, 19, 9, 80, 85, 0, 20, 12, 201, 48, 144, 133, 72, 19, 9, 80, 85, 0, 20, 10, 199, 65, 32, 75, 80, 148, 197, 72, 20, 10, 199, 25, 34, 80, 61, 53, 9, 28, 20, 10, 199, 44, 19, 13, 84, 178, 83, 44, 20, 10, 199, 4, 224, 76, 60, 114, 83, 44, 20, 10, 199, 4, 195, 5, 72, 114, 83, 44, 20, 10, 199, 52, 85, 15, 16, 146, 197, 72, 20, 0, 9, 134, 22, 1, 12, 195, 184, 18, 20, 11, 200, 76, 82, 83, 52, 243, 15, 28, 144, 20, 11, 200, 52, 243, 9, 56, 243, 15, 28, 144, 20, 7, 196, 61, 35, 133, 72, 20, 11, 200, 76, 19, 79, 40, 81, 9, 76, 176, 20, 11, 200, 64, 20, 137, 80, 85, 9, 76, 176, 20, 11, 200, 20, 180, 197, 28, 85, 9, 76, 176, 20, 11, 200, 4, 229, 9, 80, 85, 9, 76, 176, 20, 7, 196, 4, 115, 206, 36, 20, 7, 196, 45, 80, 137, 44, 20, 9, 198, 76, 84, 1, 72, 21, 0, 20, 0, 14, 139, 14, 1, 18, 11, 15, 20, 9, 19, 195, 184, 18, 20, 10, 135, 12, 25, 4, 8, 195, 184, 18, 20, 8, 197, 44, 245, 5, 72, 144, 20, 9, 198, 32, 243, 79, 57, 147, 73, 20, 8, 197, 16, 82, 193, 16, 80, 20, 8, 197, 12, 146, 193, 16, 80, 20, 0, 11, 136, 1, 21, 4, 9, 20, 195, 184, 18, 20, 9, 198, 72, 16, 149, 48, 148, 212, 20, 9, 198, 12, 149, 137, 48, 148, 212, 20, 15, 204, 64, 84, 134, 20, 181, 9, 8, 147, 9, 80, 85, 0, 20, 13, 202, 80, 242, 211, 36, 179, 204, 60, 114, 83, 44, 20, 0, 10, 199, 44, 243, 148, 4, 181, 21, 72, 20, 12, 137, 15, 16, 5, 18, 1, 20, 195, 184, 18, 20, 12, 201, 88, 148, 148, 84, 244, 201, 80, 85, 0, 20, 12, 201, 64, 192, 83, 80, 144, 201, 80, 85, 0, 20, 12, 201, 44, 244, 132, 36, 19, 9, 80, 85, 0, 20, 12, 201, 44, 243, 150, 20, 180, 201, 80, 85, 0, 20, 12, 201, 44, 243, 148, 36, 229, 73, 80, 85, 0, 20, 12, 201, 44, 243, 142, 20, 180, 201, 80, 85, 0, 20, 12, 201, 44, 243, 134, 61, 35, 73, 80, 85, 0, 20, 12, 201, 25, 35, 206, 80, 19, 9, 80, 85, 0, 20, 12, 201, 20, 192, 83, 80, 144, 201, 80, 85, 0, 20, 12, 201, 4, 67, 73, 72, 19, 9, 80, 85, 0, 20, 10, 199, 65, 81, 19, 21, 35, 9, 28, 20, 14, 203, 81, 32, 78, 77, 97, 83, 80, 149, 9, 76, 176, 20, 10, 199, 77, 147, 12, 4, 34, 83, 44, 20, 10, 199, 52, 243, 4, 61, 98, 83, 44, 20, 10, 199, 32, 84, 139, 84, 194, 83, 44, 20, 12, 201, 65, 35, 212, 20, 181, 15, 72, 21, 0, 20, 12, 201, 36, 228, 208, 20, 181, 15, 72, 21, 0, 20, 10, 199, 72, 83, 79, 84, 192, 68, 20, 20, 10, 199, 24, 20, 150, 20, 192, 68, 20, 20, 12, 71, 52, 19, 147, 24, 145, 76, 16, 21, 0, 10, 0, 13, 138, 18, 5, 16, 1, 18, 1, 20, 195, 184, 18, 20, 9, 198, 77, 70, 76, 37, 53, 0, 20, 9, 198, 77, 66, 76, 37, 53, 0, 20, 9, 198, 45, 84, 147, 37, 53, 0, 20, 9, 198, 72, 80, 76, 37, 49, 82, 20, 9, 198, 24, 19, 148, 5, 49, 82, 20, 9, 198, 21, 35, 212, 37, 49, 82, 20, 9, 198, 20, 225, 15, 77, 49, 82, 20, 9, 198, 16, 144, 76, 101, 49, 82, 20, 9, 198, 16, 84, 12, 61, 145, 82, 20, 9, 198, 4, 225, 204, 37, 49, 82, 20, 7, 196, 24, 197, 73, 16, 20, 9, 198, 72, 148, 5, 57, 49, 82, 20, 9, 198, 8, 241, 197, 57, 49, 82, 20, 0, 14, 139, 11, 15, 15, 16, 5, 18, 1, 20, 195, 184, 18, 20, 9, 198, 8, 195, 206, 16, 147, 133, 20, 9, 198, 76, 227, 194, 8, 84, 137, 20, 9, 198, 81, 48, 82, 37, 51, 69, 20, 9, 198, 24, 21, 86, 37, 51, 69, 20, 9, 198, 4, 99, 210, 37, 51, 69, 20, 0, 15, 140, 18, 5, 19, 20, 1, 21, 18, 1, 20, 195, 184, 18, 20, 12, 201, 8, 80, 82, 8, 82, 132, 56, 147, 135, 67, 13, 202, 28, 195, 210, 36, 98, 75, 5, 66, 79, 56, 20, 15, 204, 77, 81, 199, 21, 53, 9, 8, 147, 9, 80, 85, 0, 20, 15, 204, 44, 243, 150, 21, 37, 9, 8, 147, 9, 80, 85, 0, 20, 15, 204, 21, 67, 143, 12, 83, 148, 72, 144, 201, 80, 85, 0, 20, 12, 201, 81, 32, 86, 21, 53, 5, 72, 147, 135, 20, 12, 201, 36, 225, 19, 81, 81, 5, 72, 147, 135, 20, 12, 201, 21, 50, 193, 52, 245, 5, 72, 147, 135, 20, 12, 201, 20, 180, 203, 49, 81, 5, 72, 147, 135, 20, 12, 201, 16, 84, 18, 20, 50, 69, 72, 147, 135, 20, 12, 201, 8, 19, 12, 5, 53, 5, 72, 147, 135, 20, 13, 202, 76, 84, 130, 60, 180, 143, 5, 66, 83, 44, 20, 9, 198, 21, 36, 129, 81, 83, 64, 20, 9, 198, 37, 34, 68, 37, 83, 64, 20, 9, 198, 88, 149, 1, 52, 147, 128, 20, 9, 198, 72, 21, 133, 48, 147, 128, 20, 9, 198, 53, 81, 90, 104, 147, 128, 20, 9, 198, 52, 17, 193, 76, 147, 128, 20, 9, 198, 44, 84, 129, 80, 147, 128, 20, 9, 198, 36, 228, 213, 48, 147, 128, 20, 9, 198, 4, 192, 149, 52, 147, 128, 20, 9, 198, 61, 69, 15, 52, 19, 128, 21, 0, 12, 201, 72, 81, 201, 60, 224, 76, 37, 53, 0, 20, 9, 198, 17, 84, 5, 72, 147, 135, 20, 12, 201, 77, 148, 212, 20, 208, 84, 37, 49, 82, 20, 12, 201, 77, 64, 78, 16, 20, 132, 37, 49, 82, 20, 12, 137, 16, 18, 195, 166, 19, 9, 4, 5, 18, 20, 12, 201, 52, 21, 5, 72, 144, 76, 37, 49, 82, 20, 12, 201, 72, 244, 203, 36, 193, 5, 57, 49, 82, 20, 0, 9, 198, 24, 20, 195, 37, 53, 0, 20, 9, 198, 48, 144, 197, 57, 49, 82, 20, 9, 198, 44, 20, 133, 77, 49, 82, 20, 9, 198, 36, 225, 5, 45, 49, 82, 20, 12, 201, 85, 66, 76, 37, 64, 82, 37, 51, 69, 20, 12, 201, 20, 181, 137, 48, 144, 146, 37, 51, 69, 20, 7, 196, 25, 85, 9, 48, 20, 7, 196, 80, 243, 65, 80, 20, 9, 68, 52, 16, 200, 60, 21, 0, 10, 0, 9, 198, 44, 21, 129, 80, 147, 133, 20, 9, 198, 81, 35, 204, 16, 84, 137, 20, 12, 201, 65, 34, 86, 36, 193, 71, 37, 83, 64, 20, 9, 198, 81, 35, 208, 37, 51, 69, 20, 9, 198, 64, 145, 84, 37, 51, 69, 20, 12, 201, 76, 147, 135, 5, 3, 210, 20, 19, 128, 20, 0, 9, 198, 12, 130, 70, 24, 243, 128, 20, 9, 198, 80, 83, 147, 36, 243, 128, 20, 9, 198, 64, 83, 147, 36, 243, 128, 20, 9, 198, 21, 35, 211, 36, 243, 128, 20, 12, 201, 76, 82, 214, 20, 228, 197, 72, 147, 135, 20, 12, 201, 65, 35, 204, 60, 225, 197, 72, 147, 135, 20, 12, 201, 44, 243, 147, 21, 37, 133, 72, 147, 135, 20, 12, 201, 44, 243, 80, 61, 53, 5, 72, 147, 135, 20, 12, 201, 36, 225, 18, 4, 225, 197, 72, 147, 135, 20, 12, 201, 24, 84, 141, 20, 229, 5, 72, 147, 135, 20, 12, 201, 16, 148, 212, 4, 224, 197, 72, 147, 135, 20, 12, 201, 16, 145, 148, 60, 225, 197, 72, 147, 135, 20, 12, 201, 16, 84, 193, 88, 245, 69, 72, 147, 135, 20, 12, 201, 16, 80, 197, 57, 68, 133, 72, 147, 135, 20, 11, 136, 16, 195, 184, 14, 9, 20, 5, 18, 20, 15, 204, 36, 229, 5, 48, 193, 75, 81, 80, 76, 37, 49, 82, 20, 9, 198, 61, 96, 82, 37, 83, 64, 20, 9, 198, 48, 19, 143, 48, 147, 128, 20, 9, 198, 24, 83, 73, 56, 147, 128, 20, 9, 198, 81, 84, 139, 52, 83, 128, 20, 9, 198, 52, 18, 197, 16, 243, 128, 20, 9, 198, 24, 244, 149, 72, 83, 128, 20, 9, 198, 8, 18, 1, 52, 19, 128, 20, 9, 198, 72, 82, 142, 24, 19, 128, 21, 0, 6, 195, 16, 224, 64, 17, 10, 199, 61, 37, 15, 16, 242, 211, 36, 20, 14, 139, 15, 2, 19, 11, 195, 184, 14, 9, 20, 5, 20, 20, 10, 199, 52, 85, 1, 48, 195, 201, 16, 20, 10, 199, 44, 243, 147, 61, 37, 9, 20, 20, 10, 199, 64, 197, 84, 60, 226, 85, 52, 20, 10, 199, 32, 20, 141, 60, 226, 85, 52, 20, 10, 199, 8, 84, 153, 48, 194, 85, 52, 20, 10, 199, 52, 85, 15, 16, 148, 205, 20, 20, 15, 204, 52, 20, 139, 20, 68, 205, 20, 176, 78, 37, 51, 69, 20, 10, 199, 20, 180, 207, 80, 148, 205, 20, 20, 0, 15, 68, 32, 18, 84, 36, 107, 110, 6, 37, 12, 47, 37, 0, 20, 12, 201, 104, 83, 130, 84, 65, 8, 37, 51, 69, 20, 12, 201, 44, 244, 144, 61, 32, 84, 37, 51, 69, 20, 12, 201, 44, 243, 15, 56, 144, 76, 37, 51, 69, 20, 12, 201, 8, 243, 129, 64, 20, 148, 37, 51, 69, 20, 12, 201, 5, 53, 9, 28, 208, 84, 37, 51, 69, 20, 9, 198, 65, 35, 195, 20, 229, 0, 20, 7, 196, 8, 20, 193, 72, 20, 0, 9, 198, 64, 81, 9, 13, 84, 133, 20, 9, 198, 88, 148, 143, 48, 241, 201, 20, 9, 198, 73, 83, 143, 48, 241, 201, 20, 9, 198, 53, 146, 207, 48, 241, 201, 20, 9, 198, 36, 65, 79, 48, 241, 201, 20, 8, 197, 52, 18, 210, 60, 224, 20, 8, 197, 24, 195, 212, 20, 192, 20, 12, 201, 64, 192, 78, 21, 64, 82, 37, 83, 64, 20, 12, 201, 16, 83, 6, 36, 224, 82, 37, 83, 64, 20, 8, 197, 77, 64, 66, 36, 192, 20, 12, 201, 32, 83, 19, 36, 225, 207, 72, 19, 128, 20, 12, 201, 25, 33, 68, 21, 34, 67, 36, 19, 128, 20, 8, 197, 24, 146, 137, 4, 224, 20, 8, 197, 9, 84, 141, 4, 224, 20, 12, 137, 8, 15, 13, 195, 184, 15, 16, 1, 20, 20, 8, 197, 76, 128, 77, 4, 224, 21, 0, 0, 10, 199, 85, 32, 129, 56, 148, 197, 72, 20, 10, 199, 80, 149, 143, 48, 148, 197, 72, 20, 10, 199, 80, 83, 65, 80, 148, 197, 72, 20, 10, 199, 72, 83, 80, 48, 16, 197, 72, 20, 10, 199, 72, 21, 9, 24, 144, 197, 72, 20, 10, 199, 64, 243, 65, 16, 148, 197, 72, 20, 10, 199, 4, 181, 9, 88, 148, 197, 72, 20, 10, 199, 24, 244, 147, 60, 227, 9, 28, 20, 10, 199, 64, 21, 18, 36, 50, 83, 44, 20, 10, 199, 52, 84, 207, 104, 242, 83, 44, 20, 10, 199, 48, 85, 1, 72, 114, 83, 44, 20, 10, 199, 21, 68, 149, 76, 178, 83, 44, 20, 10, 199, 4, 224, 84, 60, 210, 83, 44, 20, 15, 204, 20, 180, 201, 77, 65, 78, 80, 144, 76, 37, 51, 69, 20, 10, 199, 65, 35, 208, 60, 225, 78, 80, 20, 10, 199, 44, 243, 70, 61, 37, 1, 8, 20, 0, 9, 198, 16, 243, 129, 80, 147, 206, 20, 9, 198, 5, 97, 82, 76, 147, 206, 20, 7, 196, 45, 84, 5, 72, 20, 15, 204, 36, 228, 212, 73, 83, 69, 57, 64, 82, 37, 83, 64, 20, 7, 196, 25, 149, 9, 56, 20, 7, 196, 61, 5, 9, 44, 20, 0, 12, 201, 72, 81, 201, 77, 68, 129, 81, 84, 128, 20, 9, 198, 81, 32, 75, 80, 244, 197, 20, 8, 197, 48, 81, 213, 4, 224, 21, 8, 197, 85, 34, 78, 4, 192, 20, 8, 197, 5, 53, 18, 4, 192, 20, 8, 197, 64, 244, 148, 4, 32, 20, 0, 13, 202, 28, 84, 143, 57, 67, 204, 60, 114, 83, 44, 20, 0, 6, 195, 20, 177, 192, 17, 10, 67, 36, 65, 64, 37, 72, 6, 36, 0, 10, 199, 29, 33, 78, 4, 66, 78, 20, 20, 12, 201, 44, 243, 132, 20, 211, 129, 80, 147, 206, 20, 12, 201, 36, 229, 18, 61, 97, 82, 76, 147, 206, 20, 12, 201, 36, 228, 197, 52, 147, 129, 80, 147, 206, 20, 12, 201, 20, 180, 193, 52, 147, 129, 80, 147, 206, 20, 10, 199, 52, 147, 137, 77, 68, 133, 72, 20, 10, 199, 44, 244, 144, 61, 35, 9, 28, 20, 10, 199, 72, 20, 19, 60, 66, 83, 44, 20, 10, 199, 64, 192, 84, 60, 226, 83, 44, 20, 9, 198, 44, 147, 133, 80, 148, 203, 20, 10, 199, 29, 33, 78, 4, 66, 83, 44, 20, 9, 198, 20, 209, 129, 80, 148, 203, 20, 9, 198, 5, 34, 193, 16, 148, 203, 20, 10, 199, 81, 32, 78, 76, 145, 78, 80, 20, 10, 199, 72, 80, 201, 64, 145, 78, 80, 20, 9, 198, 72, 85, 133, 72, 83, 147, 20, 9, 198, 44, 243, 147, 80, 19, 147, 20, 10, 199, 36, 225, 143, 72, 208, 78, 80, 20, 0, 9, 198, 80, 84, 212, 5, 67, 210, 20, 9, 198, 72, 243, 12, 5, 67, 210, 20, 9, 198, 37, 51, 204, 5, 67, 210, 20, 18, 4, 95, 4, 15, 20, 58, 37, 86, 72, 6, 115, 47, 35, 71, 114, 84, 0, 0, 8, 197, 76, 83, 137, 61, 32, 20, 18, 143, 16, 18, 195, 166, 19, 21, 16, 16, 15, 19, 9, 20, 9, 15, 14, 20, 12, 201, 65, 35, 198, 21, 52, 201, 60, 225, 76, 20, 12, 201, 44, 243, 134, 21, 52, 201, 60, 225, 76, 20, 8, 197, 45, 33, 68, 37, 64, 20, 8, 197, 45, 84, 129, 57, 64, 20, 0, 9, 198, 88, 148, 143, 48, 241, 192, 20, 9, 198, 73, 83, 143, 48, 241, 192, 20, 9, 198, 53, 146, 207, 48, 241, 192, 20, 9, 198, 36, 65, 79, 48, 241, 192, 20, 13, 202, 76, 82, 83, 52, 241, 210, 4, 98, 83, 44, 20, 12, 201, 64, 197, 84, 60, 180, 129, 80, 148, 203, 20, 13, 202, 60, 49, 65, 56, 241, 210, 4, 98, 83, 44, 20, 12, 201, 52, 84, 207, 64, 245, 1, 52, 148, 203, 20, 13, 202, 44, 20, 132, 36, 241, 210, 4, 98, 83, 44, 20, 13, 202, 8, 144, 140, 36, 241, 210, 4, 98, 83, 44, 20, 13, 202, 8, 19, 135, 48, 17, 5, 76, 130, 83, 44, 20, 9, 198, 81, 34, 66, 84, 224, 76, 20, 9, 198, 5, 52, 9, 72, 19, 148, 20, 9, 198, 4, 67, 208, 80, 19, 148, 20, 0, 20, 67, 88, 147, 0, 84, 36, 55, 15, 107, 6, 110, 12, 0, 81, 104, 97, 118, 101, 32, 10, 199, 44, 242, 193, 36, 226, 83, 80, 20, 10, 199, 32, 83, 12, 20, 226, 83, 80, 20, 9, 198, 76, 21, 9, 72, 148, 203, 20, 9, 198, 64, 20, 143, 16, 148, 203, 20, 9, 198, 61, 51, 79, 80, 148, 203, 20, 9, 198, 60, 49, 65, 56, 148, 203, 20, 9, 198, 4, 193, 197, 72, 148, 203, 20, 8, 67, 80, 80, 200, 21, 0, 10, 6, 195, 88, 147, 0, 76, 0, 31, 76, 77, 21, 65, 72, 81, 1, 56, 49, 82, 56, 84, 192, 89, 49, 58, 6, 36, 13, 72, 35, 12, 50, 89, 114, 20, 50, 13, 89, 0, 9, 198, 36, 229, 133, 77, 67, 210, 20, 9, 198, 16, 85, 5, 45, 67, 210, 20, 11, 200, 52, 147, 137, 52, 19, 9, 77, 64, 20, 11, 200, 4, 194, 207, 32, 243, 9, 77, 64, 20, 9, 198, 20, 225, 15, 72, 98, 78, 20, 11, 200, 16, 242, 213, 52, 83, 148, 5, 32, 20, 11, 200, 36, 229, 15, 48, 84, 129, 57, 64, 20, 0, 6, 195, 36, 179, 206, 20, 8, 197, 24, 192, 78, 21, 32, 20, 12, 201, 88, 83, 147, 44, 16, 133, 48, 145, 192, 20, 12, 201, 80, 18, 206, 20, 211, 69, 48, 145, 192, 20, 12, 201, 76, 83, 19, 44, 16, 133, 48, 145, 192, 20, 12, 201, 32, 84, 147, 44, 16, 133, 48, 145, 192, 20, 8, 197, 32, 149, 20, 37, 64, 20, 12, 201, 64, 144, 78, 37, 53, 9, 56, 65, 64, 20, 8, 197, 76, 243, 4, 5, 64, 20, 8, 197, 25, 64, 76, 5, 64, 20, 8, 197, 4, 49, 84, 5, 64, 20, 8, 197, 76, 82, 193, 57, 64, 20, 9, 198, 20, 181, 137, 64, 17, 197, 20, 0, 18, 66, 88, 144, 84, 37, 15, 89, 47, 6, 36, 0, 81, 115, 116, 101, 103, 32, 18, 67, 36, 178, 197, 36, 81, 36, 15, 107, 110, 0, 81, 104, 97, 118, 101, 32, 9, 198, 20, 225, 15, 76, 179, 208, 20, 9, 198, 77, 69, 68, 36, 225, 64, 20, 12, 201, 65, 80, 140, 36, 50, 83, 80, 148, 203, 20, 12, 201, 56, 85, 82, 5, 53, 5, 56, 148, 203, 20, 12, 201, 52, 81, 9, 84, 210, 83, 80, 148, 203, 20, 9, 198, 84, 197, 137, 56, 65, 64, 20, 9, 198, 29, 81, 9, 56, 65, 64, 20, 9, 198, 72, 81, 133, 72, 83, 148, 20, 9, 198, 44, 243, 147, 80, 19, 148, 20, 8, 66, 88, 144, 84, 37, 0, 72, 0, 10, 199, 72, 81, 143, 72, 210, 83, 80, 20, 10, 199, 64, 243, 25, 80, 82, 83, 80, 20, 10, 199, 64, 84, 147, 60, 224, 71, 20, 20, 14, 2, 95, 95, 71, 6, 113, 50, 89, 72, 34, 35, 37, 0, 0, 9, 134, 6, 1, 22, 195, 184, 18, 20, 11, 200, 52, 243, 143, 64, 243, 9, 77, 64, 20, 11, 200, 24, 81, 5, 72, 19, 9, 77, 64, 20, 12, 201, 8, 84, 212, 101, 33, 82, 36, 225, 5, 68, 11, 200, 77, 80, 143, 72, 66, 78, 21, 32, 20, 11, 200, 36, 229, 5, 72, 97, 82, 21, 32, 20, 11, 200, 5, 3, 211, 81, 35, 198, 21, 32, 20, 12, 137, 16, 18, 195, 166, 19, 9, 4, 9, 5, 20, 12, 201, 45, 83, 147, 80, 225, 82, 36, 225, 5, 20, 12, 201, 8, 84, 212, 101, 33, 82, 36, 225, 5, 20, 11, 200, 72, 83, 143, 52, 209, 82, 21, 64, 20, 11, 200, 52, 19, 137, 21, 33, 82, 21, 64, 20, 11, 200, 36, 225, 9, 28, 225, 82, 21, 64, 20, 11, 200, 24, 16, 197, 81, 65, 82, 21, 64, 20, 11, 200, 20, 180, 193, 49, 65, 82, 21, 64, 20, 11, 200, 16, 84, 129, 56, 113, 82, 21, 64, 20, 11, 200, 16, 84, 18, 37, 97, 82, 21, 64, 20, 11, 200, 5, 52, 207, 73, 65, 82, 21, 64, 20, 11, 200, 4, 229, 9, 45, 97, 82, 21, 64, 20, 11, 200, 4, 97, 133, 45, 65, 82, 21, 64, 20, 9, 198, 48, 19, 73, 56, 21, 0, 20, 7, 196, 45, 84, 129, 8, 20, 0, 8, 197, 84, 225, 9, 56, 80, 20, 12, 201, 28, 80, 143, 52, 209, 82, 48, 145, 192, 20, 13, 138, 16, 195, 166, 4, 5, 18, 1, 19, 20, 9, 20, 12, 201, 4, 67, 73, 72, 19, 9, 56, 65, 64, 20, 10, 69, 60, 227, 9, 56, 80, 21, 0, 10, 0, 9, 198, 64, 20, 143, 16, 148, 212, 20, 9, 198, 49, 85, 5, 56, 148, 212, 20, 9, 198, 21, 52, 193, 100, 148, 212, 20, 9, 198, 52, 243, 135, 60, 194, 68, 20, 9, 198, 81, 148, 129, 56, 226, 64, 20, 9, 198, 16, 144, 75, 60, 226, 64, 20, 9, 198, 64, 243, 5, 52, 146, 192, 20, 9, 198, 28, 83, 133, 80, 146, 192, 20, 9, 198, 24, 243, 133, 80, 146, 192, 20, 9, 198, 81, 34, 66, 84, 224, 84, 20, 9, 198, 40, 245, 82, 56, 19, 0, 20, 8, 67, 12, 242, 197, 21, 0, 10, 0, 14, 203, 81, 32, 68, 37, 66, 79, 56, 19, 9, 77, 64, 20, 12, 201, 20, 180, 212, 72, 83, 73, 80, 85, 0, 20, 10, 199, 88, 148, 137, 48, 148, 197, 72, 20, 10, 199, 37, 51, 1, 52, 148, 197, 72, 20, 10, 199, 24, 197, 73, 16, 148, 197, 72, 20, 9, 198, 32, 245, 141, 60, 66, 71, 20, 9, 198, 28, 83, 69, 56, 194, 71, 20, 6, 195, 88, 147, 204, 20, 6, 195, 24, 147, 204, 20, 10, 199, 52, 243, 129, 72, 178, 83, 44, 20, 10, 199, 44, 19, 13, 100, 178, 83, 44, 20, 10, 199, 21, 84, 212, 4, 178, 83, 44, 20, 10, 199, 72, 17, 9, 60, 99, 206, 36, 20, 10, 199, 16, 243, 73, 56, 144, 193, 56, 20, 10, 199, 44, 21, 129, 48, 176, 68, 20, 20, 10, 199, 8, 20, 146, 36, 176, 68, 20, 20, 10, 199, 65, 32, 75, 80, 146, 193, 8, 20, 10, 199, 4, 211, 210, 80, 148, 193, 8, 20, 8, 67, 12, 243, 204, 21, 0, 10, 0, 13, 138, 9, 14, 19, 5, 13, 9, 14, 195, 184, 18, 20, 11, 200, 16, 84, 141, 5, 67, 204, 60, 112, 20, 11, 200, 9, 35, 205, 5, 67, 204, 60, 112, 20, 11, 200, 76, 84, 144, 20, 229, 9, 56, 80, 20, 9, 198, 21, 37, 80, 80, 147, 206, 20, 9, 198, 4, 208, 137, 80, 147, 206, 20, 11, 200, 33, 148, 15, 44, 243, 132, 72, 144, 20, 11, 200, 28, 83, 132, 5, 35, 69, 72, 144, 20, 11, 200, 96, 83, 143, 24, 240, 137, 76, 176, 20, 11, 200, 88, 81, 197, 80, 20, 137, 76, 176, 20, 11, 200, 88, 19, 21, 80, 20, 137, 76, 176, 20, 11, 200, 76, 243, 9, 16, 20, 137, 76, 176, 20, 11, 200, 52, 85, 1, 8, 243, 9, 76, 176, 20, 11, 200, 48, 20, 9, 16, 20, 137, 76, 176, 20, 11, 200, 8, 19, 21, 77, 68, 129, 16, 80, 20, 11, 200, 24, 84, 142, 37, 52, 193, 28, 80, 20, 0, 8, 197, 84, 99, 204, 60, 112, 20, 8, 197, 64, 241, 210, 60, 208, 20, 8, 197, 61, 34, 197, 72, 80, 20, 8, 197, 5, 50, 197, 76, 80, 20, 9, 198, 21, 2, 84, 4, 98, 69, 20, 9, 198, 16, 80, 197, 56, 226, 69, 20, 8, 197, 24, 16, 146, 36, 176, 20, 12, 201, 76, 18, 210, 4, 209, 78, 80, 19, 0, 20, 11, 70, 25, 34, 69, 56, 67, 25, 21, 0, 10, 20, 4, 95, 56, 88, 15, 83, 37, 34, 89, 36, 50, 89, 47, 116, 84, 13, 50, 13, 0, 0, 11, 67, 81, 83, 133, 47, 40, 50, 108, 0, 41, 12, 137, 18, 5, 12, 9, 7, 9, 195, 184, 19, 20, 12, 137, 13, 1, 12, 9, 3, 9, 195, 184, 19, 20, 11, 136, 16, 12, 1, 14, 20, 195, 184, 18, 20, 13, 202, 60, 101, 1, 48, 211, 204, 60, 114, 83, 44, 20, 13, 202, 48, 20, 153, 56, 115, 204, 60, 114, 83, 44, 20, 13, 202, 24, 20, 141, 4, 179, 204, 60, 114, 83, 44, 20, 9, 198, 16, 144, 75, 60, 224, 84, 20, 13, 202, 36, 226, 207, 52, 209, 78, 77, 84, 129, 8, 20, 0, 20, 67, 33, 83, 128, 107, 113, 50, 15, 89, 47, 6, 36, 0, 81, 115, 116, 101, 103, 32, 13, 138, 16, 5, 18, 14, 9, 3, 9, 195, 184, 19, 20, 12, 201, 44, 243, 210, 16, 147, 129, 80, 147, 206, 20, 12, 201, 44, 243, 147, 20, 180, 129, 80, 147, 206, 20, 12, 201, 24, 192, 71, 20, 195, 1, 80, 147, 206, 20, 12, 201, 36, 208, 133, 12, 147, 9, 80, 85, 0, 20, 12, 201, 4, 227, 210, 52, 19, 9, 80, 85, 0, 20, 10, 199, 65, 35, 203, 48, 19, 69, 72, 20, 10, 199, 44, 243, 139, 85, 36, 133, 72, 20, 10, 199, 44, 243, 132, 20, 228, 197, 72, 20, 10, 199, 44, 20, 9, 81, 83, 5, 72, 20, 10, 199, 4, 178, 213, 53, 83, 5, 72, 20, 10, 199, 64, 197, 84, 60, 226, 83, 44, 20, 14, 203, 56, 243, 69, 56, 179, 1, 80, 244, 137, 76, 176, 20, 10, 199, 52, 85, 1, 48, 194, 83, 44, 20, 9, 198, 48, 85, 137, 80, 148, 203, 20, 10, 199, 48, 84, 207, 80, 130, 83, 44, 20, 14, 203, 44, 243, 80, 20, 228, 193, 80, 244, 137, 76, 176, 20, 9, 198, 21, 84, 129, 76, 148, 203, 20, 10, 199, 16, 144, 84, 60, 226, 83, 44, 20, 10, 199, 8, 20, 130, 4, 66, 83, 44, 20, 9, 198, 5, 165, 5, 44, 148, 203, 20, 10, 199, 44, 244, 205, 60, 115, 206, 36, 20, 10, 199, 88, 20, 132, 20, 228, 197, 72, 20, 12, 201, 12, 149, 137, 48, 148, 197, 72, 85, 0, 20, 10, 199, 44, 20, 130, 60, 224, 68, 20, 20, 6, 195, 33, 83, 128, 72, 0, 14, 139, 16, 18, 5, 19, 20, 9, 7, 9, 195, 184, 19, 20, 11, 200, 44, 194, 77, 5, 67, 204, 60, 112, 20, 7, 196, 5, 67, 5, 80, 20, 9, 198, 64, 145, 84, 37, 53, 0, 20, 7, 196, 5, 4, 5, 48, 20, 9, 198, 64, 241, 84, 37, 49, 82, 20, 9, 198, 44, 19, 132, 37, 49, 82, 20, 9, 198, 36, 67, 204, 37, 49, 82, 20, 11, 200, 48, 19, 80, 37, 53, 5, 72, 144, 20, 11, 200, 24, 19, 148, 5, 53, 5, 72, 144, 20, 11, 200, 76, 20, 139, 5, 53, 9, 76, 176, 20, 11, 200, 32, 145, 82, 5, 34, 201, 76, 176, 20, 7, 196, 76, 130, 73, 80, 20, 9, 198, 64, 20, 129, 24, 98, 78, 20, 11, 200, 44, 243, 148, 20, 224, 78, 12, 80, 20, 7, 196, 73, 84, 129, 48, 20, 7, 196, 8, 20, 193, 48, 20, 0, 12, 201, 52, 84, 139, 4, 229, 9, 48, 148, 212, 20, 9, 198, 76, 181, 77, 48, 84, 137, 20, 9, 198, 45, 37, 75, 44, 84, 137, 20, 12, 201, 28, 84, 141, 4, 226, 83, 80, 146, 192, 20, 11, 67, 20, 192, 78, 36, 55, 35, 50, 0, 21, 8, 197, 45, 84, 129, 57, 48, 20, 0, 15, 204, 81, 32, 78, 76, 194, 84, 80, 84, 129, 80, 147, 206, 20, 15, 204, 36, 225, 140, 20, 180, 201, 8, 147, 9, 80, 85, 0, 20, 12, 201, 80, 82, 206, 60, 180, 129, 80, 148, 203, 20, 13, 202, 52, 81, 137, 77, 67, 198, 20, 194, 83, 44, 20, 12, 201, 33, 81, 213, 20, 227, 212, 80, 148, 203, 20, 0, 24, 73, 44, 243, 134, 37, 35, 65, 56, 65, 82, 49, 114, 50, 83, 36, 34, 65, 6, 110, 50, 72, 108, 0, 10, 67, 36, 65, 84, 37, 72, 6, 36, 0, 12, 201, 48, 82, 211, 36, 176, 76, 37, 49, 82, 20, 12, 201, 4, 178, 204, 36, 208, 84, 37, 49, 82, 20, 14, 203, 44, 243, 147, 64, 148, 129, 80, 244, 137, 76, 176, 20, 14, 203, 20, 180, 193, 52, 147, 129, 80, 244, 137, 76, 176, 20, 14, 203, 12, 149, 137, 48, 148, 193, 80, 244, 137, 76, 176, 20, 9, 198, 5, 53, 5, 56, 148, 203, 20, 10, 199, 5, 84, 208, 36, 50, 85, 52, 20, 0, 9, 198, 72, 80, 76, 37, 53, 0, 20, 9, 198, 17, 80, 76, 37, 53, 0, 20, 9, 198, 16, 83, 148, 37, 53, 0, 20, 9, 198, 12, 19, 80, 37, 53, 0, 20, 9, 198, 60, 181, 18, 60, 161, 82, 20, 9, 198, 37, 35, 206, 37, 49, 82, 20, 9, 198, 36, 226, 204, 36, 225, 82, 20, 9, 198, 36, 226, 193, 77, 49, 82, 20, 7, 196, 53, 83, 1, 80, 20, 0, 9, 198, 21, 85, 1, 56, 20, 201, 20, 9, 198, 64, 84, 137, 24, 84, 137, 20, 0, 15, 204, 20, 180, 201, 77, 65, 78, 80, 144, 76, 37, 53, 0, 20, 12, 201, 52, 225, 77, 61, 65, 75, 56, 148, 203, 20, 9, 198, 16, 148, 203, 60, 98, 76, 20, 9, 198, 16, 144, 75, 60, 224, 76, 20, 13, 4, 95, 7, 18, 22, 35, 49, 89, 6, 35, 68, 0, 0, 6, 195, 76, 244, 192, 17, 30, 75, 9, 33, 65, 44, 64, 78, 12, 84, 142, 21, 48, 71, 34, 109, 37, 81, 6, 72, 35, 12, 50, 89, 114, 20, 50, 13, 89, 0, 10, 199, 44, 83, 79, 80, 18, 211, 36, 20, 12, 201, 77, 147, 132, 36, 176, 76, 37, 53, 0, 20, 12, 201, 52, 21, 5, 72, 144, 76, 37, 53, 0, 20, 12, 201, 36, 212, 5, 72, 144, 76, 37, 53, 0, 20, 12, 201, 21, 52, 5, 72, 19, 148, 37, 53, 0, 20, 12, 201, 24, 19, 73, 48, 144, 82, 37, 49, 82, 20, 10, 199, 52, 243, 135, 60, 195, 201, 16, 20, 10, 135, 16, 18, 195, 166, 12, 1, 20, 20, 0, 9, 198, 72, 81, 149, 76, 147, 206, 20, 9, 198, 16, 85, 143, 80, 147, 206, 20, 7, 196, 65, 84, 133, 72, 20, 11, 200, 65, 35, 214, 20, 226, 69, 57, 48, 20, 11, 200, 44, 243, 150, 20, 226, 69, 57, 48, 20, 11, 200, 36, 225, 210, 20, 66, 69, 57, 48, 20, 0, 9, 198, 24, 147, 15, 48, 241, 201, 20, 8, 197, 44, 21, 9, 60, 224, 20, 8, 197, 44, 244, 132, 20, 192, 20, 8, 197, 8, 244, 132, 20, 192, 20, 12, 201, 65, 35, 198, 21, 52, 201, 60, 224, 76, 20, 0, 15, 204, 36, 229, 5, 48, 193, 75, 81, 80, 76, 37, 53, 0, 20, 9, 198, 44, 244, 21, 48, 84, 128, 20, 9, 198, 5, 81, 9, 80, 84, 128, 20, 9, 198, 44, 242, 203, 60, 194, 84, 20, 0, 10, 199, 81, 148, 9, 24, 144, 197, 72, 20, 10, 199, 64, 243, 5, 52, 148, 197, 72, 20, 10, 199, 56, 245, 9, 24, 144, 197, 72, 20, 10, 199, 52, 244, 129, 48, 148, 197, 72, 20, 10, 199, 44, 243, 80, 48, 144, 197, 72, 20, 10, 199, 44, 19, 129, 48, 148, 197, 72, 20, 10, 199, 33, 83, 65, 56, 148, 197, 72, 20, 10, 199, 24, 19, 129, 80, 148, 197, 72, 20, 10, 199, 16, 83, 129, 81, 84, 133, 72, 20, 10, 199, 8, 83, 133, 16, 144, 197, 72, 20, 10, 199, 8, 19, 129, 48, 148, 197, 72, 20, 10, 199, 44, 243, 80, 60, 225, 78, 80, 20, 10, 199, 20, 180, 208, 60, 225, 78, 80, 20, 10, 199, 16, 148, 208, 60, 225, 78, 80, 20, 0, 11, 200, 85, 53, 82, 64, 21, 9, 60, 224, 20, 11, 200, 72, 84, 5, 80, 149, 9, 60, 224, 20, 11, 200, 72, 84, 1, 72, 21, 9, 60, 224, 20, 11, 200, 40, 243, 137, 76, 21, 9, 60, 224, 20, 11, 200, 36, 229, 15, 56, 21, 9, 60, 224, 20, 11, 200, 36, 225, 9, 44, 21, 9, 60, 224, 20, 11, 200, 24, 81, 5, 72, 21, 9, 60, 224, 20, 11, 200, 5, 69, 18, 4, 181, 9, 60, 224, 20, 11, 200, 4, 195, 15, 44, 21, 9, 60, 224, 20, 9, 198, 4, 67, 208, 80, 147, 206, 20, 11, 200, 4, 67, 143, 80, 21, 9, 60, 224, 20, 11, 200, 4, 64, 80, 80, 21, 9, 60, 224, 20, 18, 207, 20, 180, 212, 72, 20, 1, 72, 192, 77, 20, 229, 1, 72, 148, 203, 20, 7, 196, 49, 148, 137, 44, 20, 13, 138, 11, 15, 18, 19, 195, 184, 18, 9, 1, 14, 20, 9, 198, 77, 69, 68, 20, 229, 0, 20, 7, 196, 53, 85, 1, 8, 20, 0, 12, 201, 56, 243, 69, 56, 179, 1, 81, 84, 128, 20, 12, 201, 24, 195, 211, 45, 83, 1, 81, 84, 128, 20, 9, 198, 16, 21, 1, 48, 241, 201, 20, 9, 198, 24, 192, 78, 44, 84, 133, 20, 9, 198, 33, 148, 15, 80, 84, 197, 20, 8, 197, 32, 83, 12, 20, 224, 20, 9, 198, 72, 83, 148, 72, 144, 197, 20, 9, 198, 52, 243, 148, 72, 144, 197, 20, 8, 197, 56, 85, 82, 4, 192, 20, 0, 28, 74, 9, 33, 65, 44, 64, 78, 12, 84, 142, 20, 71, 34, 109, 37, 81, 6, 72, 35, 12, 50, 89, 114, 20, 50, 13, 0, 11, 200, 44, 21, 15, 16, 244, 203, 61, 0, 20, 11, 200, 28, 20, 212, 72, 244, 203, 61, 0, 20, 13, 202, 76, 176, 78, 16, 147, 129, 88, 148, 197, 72, 20, 13, 202, 65, 35, 194, 48, 83, 65, 80, 148, 197, 72, 20, 13, 202, 24, 146, 212, 36, 243, 129, 48, 148, 197, 72, 20, 13, 202, 12, 243, 148, 4, 147, 133, 72, 148, 197, 72, 20, 13, 202, 80, 84, 141, 60, 70, 78, 4, 210, 83, 44, 20, 0, 10, 199, 80, 84, 141, 37, 53, 15, 72, 20, 14, 203, 36, 229, 5, 73, 1, 76, 48, 21, 9, 60, 224, 20, 14, 203, 36, 65, 78, 80, 145, 137, 44, 21, 9, 60, 224, 20, 14, 203, 20, 180, 212, 72, 20, 15, 48, 21, 9, 60, 224, 20, 14, 203, 12, 83, 148, 72, 19, 9, 76, 21, 9, 60, 224, 20, 12, 201, 5, 81, 205, 20, 229, 1, 80, 147, 206, 20, 14, 203, 4, 67, 73, 56, 148, 212, 72, 21, 9, 60, 224, 20, 10, 199, 80, 19, 154, 4, 226, 83, 44, 20, 9, 198, 80, 19, 65, 72, 148, 203, 20, 10, 199, 77, 148, 212, 60, 194, 83, 44, 20, 9, 198, 45, 35, 193, 80, 148, 203, 20, 10, 199, 32, 20, 141, 60, 226, 83, 44, 20, 9, 198, 25, 85, 21, 72, 148, 203, 20, 9, 198, 24, 243, 133, 80, 148, 203, 20, 9, 198, 4, 115, 129, 80, 148, 203, 20, 10, 199, 16, 149, 133, 72, 113, 78, 80, 20, 12, 201, 77, 80, 132, 60, 210, 78, 4, 229, 0, 20, 10, 199, 56, 81, 204, 36, 113, 65, 8, 20, 12, 71, 77, 64, 84, 20, 209, 78, 80, 21, 0, 10, 0, 11, 200, 72, 85, 143, 49, 85, 9, 60, 224, 20, 11, 200, 72, 84, 207, 49, 85, 9, 60, 224, 20, 11, 200, 60, 178, 213, 64, 21, 9, 60, 224, 20, 11, 200, 56, 21, 137, 28, 21, 9, 60, 224, 20, 11, 200, 52, 241, 5, 72, 21, 9, 60, 224, 20, 11, 200, 45, 96, 68, 72, 21, 9, 60, 224, 20, 11, 200, 44, 20, 212, 72, 21, 9, 60, 224, 20, 11, 200, 36, 227, 143, 88, 21, 9, 60, 224, 20, 11, 200, 16, 85, 15, 56, 21, 9, 60, 224, 20, 11, 200, 16, 82, 207, 72, 21, 9, 60, 224, 20, 11, 200, 5, 85, 15, 52, 21, 9, 60, 224, 20, 11, 200, 5, 4, 1, 72, 149, 9, 60, 224, 20, 11, 200, 4, 227, 143, 80, 21, 9, 60, 224, 20, 11, 200, 4, 33, 9, 44, 21, 9, 60, 224, 20, 0, 8, 197, 80, 19, 201, 77, 64, 20, 8, 197, 52, 243, 137, 77, 64, 20, 8, 197, 8, 147, 208, 5, 64, 20, 0, 9, 198, 24, 147, 15, 48, 241, 192, 20, 12, 201, 80, 83, 5, 44, 147, 133, 80, 148, 203, 20, 12, 201, 56, 81, 5, 73, 48, 75, 76, 148, 203, 20, 12, 201, 36, 225, 15, 44, 147, 133, 76, 148, 203, 20, 15, 140, 12, 195, 184, 7, 19, 20, 195, 184, 18, 9, 1, 14, 20, 9, 198, 72, 21, 9, 60, 224, 76, 20, 9, 198, 24, 244, 140, 4, 65, 64, 20, 0, 10, 199, 76, 18, 203, 5, 35, 211, 20, 20, 10, 199, 88, 147, 204, 36, 226, 83, 80, 20, 10, 199, 80, 84, 146, 61, 34, 83, 80, 20, 10, 199, 77, 147, 66, 60, 194, 83, 80, 20, 10, 199, 76, 240, 201, 4, 194, 83, 80, 20, 10, 199, 76, 163, 198, 20, 194, 83, 80, 20, 10, 199, 52, 245, 9, 60, 226, 83, 80, 20, 10, 199, 24, 244, 141, 4, 194, 83, 80, 20, 10, 199, 24, 85, 9, 12, 130, 83, 80, 20, 10, 199, 16, 20, 151, 36, 226, 83, 80, 20, 10, 199, 4, 181, 9, 60, 226, 83, 80, 20, 10, 199, 4, 36, 213, 72, 66, 83, 80, 20, 14, 203, 64, 243, 25, 52, 84, 137, 76, 21, 9, 60, 224, 20, 9, 198, 84, 112, 78, 16, 148, 203, 20, 9, 198, 81, 83, 133, 76, 148, 203, 20, 9, 198, 76, 21, 25, 72, 148, 203, 20, 9, 198, 52, 245, 9, 88, 148, 203, 20, 9, 198, 32, 243, 69, 72, 148, 203, 20, 9, 198, 20, 212, 9, 72, 148, 203, 20, 9, 198, 5, 52, 217, 72, 148, 203, 20, 9, 198, 4, 181, 9, 88, 148, 203, 20, 10, 199, 16, 149, 133, 72, 113, 78, 76, 20, 12, 71, 76, 178, 78, 32, 80, 68, 76, 21, 0, 10, 13, 4, 95, 4, 9, 1, 6, 39, 65, 55, 116, 72, 0, 0, 11, 200, 64, 83, 147, 36, 243, 137, 77, 64, 20, 11, 200, 44, 21, 84, 36, 243, 137, 77, 64, 20, 7, 196, 16, 82, 83, 80, 20, 14, 139, 8, 195, 165, 14, 4, 20, 5, 18, 12, 9, 7, 20, 11, 200, 76, 82, 212, 21, 34, 75, 21, 32, 20, 11, 200, 72, 243, 65, 57, 66, 75, 21, 32, 20, 11, 200, 56, 85, 82, 61, 66, 75, 21, 32, 20, 11, 200, 48, 241, 201, 77, 66, 75, 21, 32, 20, 11, 200, 20, 179, 5, 45, 66, 75, 21, 32, 20, 11, 200, 17, 148, 198, 5, 66, 75, 21, 32, 20, 11, 200, 16, 145, 1, 45, 66, 75, 21, 32, 20, 9, 198, 32, 244, 148, 84, 192, 78, 21, 0, 12, 201, 60, 212, 203, 72, 149, 133, 48, 145, 192, 20, 12, 201, 60, 212, 203, 36, 101, 5, 48, 145, 192, 20, 12, 201, 44, 19, 77, 21, 32, 84, 48, 145, 192, 20, 12, 201, 29, 32, 78, 28, 149, 133, 48, 145, 192, 20, 12, 201, 28, 83, 139, 20, 225, 5, 48, 145, 192, 20, 12, 201, 24, 244, 150, 20, 229, 5, 48, 145, 192, 20, 12, 201, 24, 244, 149, 17, 49, 69, 48, 145, 192, 20, 12, 201, 24, 244, 139, 5, 53, 5, 48, 145, 192, 20, 12, 201, 8, 241, 211, 80, 21, 133, 48, 145, 192, 20, 8, 197, 61, 34, 69, 57, 64, 20, 9, 198, 76, 16, 143, 80, 17, 197, 20, 0, 11, 136, 195, 166, 11, 22, 1, 20, 15, 18, 20, 9, 198, 44, 21, 1, 48, 241, 192, 20, 9, 198, 16, 21, 1, 48, 241, 192, 20, 13, 202, 36, 225, 9, 88, 145, 21, 4, 194, 83, 80, 20, 13, 202, 36, 212, 18, 21, 52, 201, 60, 226, 83, 80, 20, 9, 198, 16, 80, 201, 8, 83, 0, 20, 12, 201, 45, 35, 206, 60, 209, 84, 72, 148, 203, 20, 12, 201, 44, 244, 21, 48, 21, 15, 72, 148, 203, 20, 12, 201, 28, 84, 141, 4, 226, 83, 80, 148, 203, 20, 12, 201, 16, 81, 137, 56, 149, 15, 72, 148, 203, 20, 12, 201, 4, 225, 197, 49, 48, 75, 76, 148, 203, 20, 18, 70, 28, 83, 9, 56, 65, 64, 81, 36, 55, 6, 36, 50, 72, 13, 0, 20, 9, 198, 16, 144, 71, 60, 224, 76, 20, 9, 198, 64, 193, 74, 4, 65, 64, 20, 11, 70, 60, 97, 140, 36, 225, 64, 21, 0, 10, 0, 10, 199, 4, 229, 9, 8, 147, 211, 20, 20, 14, 203, 20, 180, 208, 72, 84, 211, 36, 243, 137, 77, 64, 20, 10, 199, 20, 180, 207, 72, 50, 83, 80, 20, 10, 199, 24, 192, 84, 84, 193, 78, 76, 20, 13, 138, 2, 12, 195, 184, 4, 1, 7, 20, 9, 7, 20, 0, 11, 200, 72, 84, 208, 37, 32, 84, 61, 32, 20, 11, 200, 45, 83, 20, 37, 96, 84, 61, 32, 20, 15, 204, 28, 84, 212, 4, 197, 16, 77, 146, 207, 48, 241, 192, 20, 11, 200, 4, 224, 66, 5, 5, 9, 77, 64, 20, 7, 196, 52, 84, 207, 56, 20, 9, 198, 72, 85, 137, 76, 147, 206, 20, 9, 198, 16, 80, 201, 76, 147, 206, 20, 7, 196, 45, 84, 133, 72, 20, 14, 139, 20, 22, 9, 22, 12, 18, 195, 165, 4, 9, 7, 20, 11, 200, 76, 83, 73, 61, 66, 75, 21, 32, 20, 11, 200, 76, 83, 65, 57, 66, 75, 21, 32, 20, 11, 200, 5, 67, 1, 57, 66, 75, 21, 32, 20, 11, 200, 4, 115, 143, 77, 66, 75, 21, 32, 20, 11, 200, 76, 244, 132, 36, 225, 82, 21, 64, 20, 11, 200, 72, 85, 1, 72, 65, 82, 21, 64, 20, 11, 200, 45, 33, 78, 20, 193, 82, 21, 64, 20, 11, 200, 24, 16, 207, 56, 225, 82, 21, 64, 20, 11, 200, 24, 192, 77, 8, 246, 65, 57, 64, 20, 0, 9, 198, 77, 68, 129, 80, 81, 201, 20, 12, 201, 77, 80, 147, 80, 19, 148, 36, 83, 0, 20, 8, 197, 72, 20, 197, 72, 80, 20, 8, 197, 33, 84, 197, 72, 80, 20, 8, 197, 8, 20, 197, 72, 80, 20, 15, 204, 77, 68, 149, 45, 69, 82, 4, 194, 83, 80, 148, 203, 20, 8, 197, 64, 20, 133, 76, 80, 20, 8, 197, 9, 83, 9, 52, 144, 20, 9, 198, 52, 148, 207, 29, 147, 137, 20, 8, 197, 28, 20, 129, 28, 80, 20, 0, 9, 198, 24, 83, 73, 56, 148, 212, 20, 9, 198, 20, 212, 9, 72, 148, 212, 20, 9, 198, 4, 197, 18, 84, 148, 212, 20, 9, 198, 4, 181, 9, 88, 148, 212, 20, 9, 198, 44, 147, 133, 80, 146, 192, 20, 9, 198, 77, 83, 20, 4, 224, 84, 20, 9, 198, 44, 244, 146, 20, 192, 84, 20, 9, 198, 52, 148, 212, 72, 19, 0, 20, 0, 10, 199, 88, 19, 15, 72, 148, 197, 72, 20, 10, 199, 80, 83, 5, 88, 148, 197, 72, 20, 10, 199, 72, 80, 83, 77, 84, 133, 72, 20, 10, 199, 64, 243, 1, 72, 148, 197, 72, 20, 10, 199, 52, 241, 9, 24, 144, 197, 72, 20, 10, 199, 48, 21, 9, 56, 148, 197, 72, 20, 10, 199, 44, 241, 9, 24, 144, 197, 72, 20, 10, 199, 21, 81, 143, 72, 148, 197, 72, 20, 10, 199, 4, 211, 210, 80, 148, 197, 72, 20, 9, 198, 44, 244, 148, 20, 194, 71, 20, 9, 198, 4, 197, 143, 72, 194, 71, 20, 9, 198, 4, 117, 5, 72, 194, 71, 20, 9, 198, 4, 100, 201, 56, 66, 71, 20, 14, 203, 44, 243, 135, 21, 53, 9, 60, 225, 82, 21, 64, 20, 0, 11, 200, 52, 85, 5, 61, 35, 204, 60, 112, 20, 11, 200, 8, 83, 133, 16, 144, 197, 72, 80, 68, 7, 196, 25, 85, 15, 56, 20, 9, 198, 56, 245, 129, 80, 147, 206, 20, 7, 196, 17, 84, 5, 72, 20, 11, 200, 64, 243, 25, 56, 84, 201, 76, 176, 20, 11, 200, 52, 147, 1, 56, 84, 201, 76, 176, 20, 11, 200, 52, 83, 1, 56, 84, 201, 76, 176, 20, 11, 200, 20, 180, 207, 80, 84, 137, 76, 176, 20, 11, 200, 8, 19, 19, 81, 148, 137, 76, 176, 20, 14, 68, 28, 19, 73, 56, 81, 110, 65, 6, 109, 68, 0, 20, 11, 200, 76, 19, 135, 21, 34, 78, 16, 80, 20, 11, 200, 64, 20, 212, 61, 34, 78, 16, 80, 20, 11, 200, 44, 82, 147, 21, 34, 78, 16, 80, 20, 15, 204, 44, 19, 77, 21, 34, 5, 73, 33, 73, 56, 65, 64, 20, 9, 68, 5, 4, 12, 20, 21, 0, 10, 0, 9, 198, 21, 2, 83, 44, 244, 0, 20, 12, 201, 60, 36, 203, 85, 32, 78, 80, 148, 212, 20, 12, 201, 5, 96, 78, 80, 112, 82, 16, 148, 212, 20, 12, 201, 61, 4, 15, 76, 149, 9, 60, 225, 76, 20, 14, 139, 8, 195, 166, 13, 15, 7, 12, 15, 2, 9, 14, 20, 11, 136, 195, 166, 19, 20, 5, 20, 9, 11, 20, 8, 197, 73, 80, 146, 36, 176, 20, 8, 197, 20, 208, 140, 20, 208, 20, 0, 9, 198, 64, 19, 133, 48, 148, 212, 20, 9, 198, 28, 21, 76, 48, 148, 212, 20, 9, 198, 24, 147, 129, 48, 148, 212, 20, 9, 198, 5, 33, 197, 48, 148, 212, 20, 12, 201, 8, 80, 82, 8, 82, 132, 20, 194, 71, 67, 14, 204, 60, 227, 205, 5, 67, 208, 60, 145, 84, 36, 179, 206, 6, 195, 33, 84, 137, 20, 12, 201, 45, 84, 134, 101, 36, 212, 20, 194, 71, 20, 12, 201, 24, 244, 150, 20, 180, 204, 20, 194, 71, 20, 12, 201, 8, 80, 82, 8, 82, 132, 20, 194, 71, 20, 9, 198, 72, 85, 15, 72, 146, 192, 20, 9, 198, 52, 245, 15, 72, 146, 192, 20, 0, 12, 201, 8, 83, 133, 24, 144, 197, 72, 85, 0, 68, 12, 201, 44, 243, 147, 84, 197, 1, 80, 147, 206, 20, 12, 201, 36, 225, 9, 76, 180, 133, 80, 147, 206, 20, 12, 201, 36, 212, 12, 4, 229, 1, 80, 147, 206, 20, 12, 201, 5, 84, 203, 84, 197, 1, 80, 147, 206, 20, 10, 199, 76, 82, 214, 20, 228, 197, 72, 20, 10, 199, 52, 20, 212, 85, 32, 133, 72, 20, 14, 203, 65, 54, 75, 60, 19, 129, 49, 148, 197, 72, 80, 20, 14, 203, 77, 84, 5, 72, 83, 12, 37, 5, 9, 76, 176, 20, 9, 198, 64, 243, 5, 52, 148, 203, 20, 9, 198, 56, 245, 15, 72, 148, 203, 20, 9, 198, 56, 19, 73, 8, 148, 203, 20, 9, 198, 5, 53, 5, 72, 148, 203, 20, 9, 198, 5, 37, 5, 76, 148, 203, 20, 10, 199, 44, 20, 5, 48, 192, 78, 36, 20, 14, 203, 44, 243, 134, 37, 35, 65, 56, 66, 78, 16, 80, 20, 12, 137, 18, 21, 13, 195, 166, 14, 9, 5, 14, 20, 12, 201, 44, 243, 80, 48, 144, 197, 72, 85, 0, 20, 12, 201, 8, 83, 133, 24, 144, 197, 72, 85, 0, 20, 0, 11, 200, 80, 242, 211, 36, 179, 204, 60, 112, 20, 9, 198, 76, 80, 197, 72, 225, 82, 20, 9, 198, 72, 85, 1, 8, 193, 82, 20, 9, 198, 44, 19, 85, 24, 193, 82, 20, 11, 200, 64, 243, 25, 12, 83, 148, 72, 144, 20, 11, 200, 25, 38, 71, 80, 17, 212, 36, 112, 20, 11, 200, 80, 241, 207, 48, 84, 201, 76, 176, 20, 11, 200, 4, 229, 5, 64, 83, 132, 36, 80, 20, 9, 198, 56, 17, 148, 4, 194, 78, 20, 11, 200, 80, 161, 78, 21, 34, 78, 16, 80, 20, 11, 200, 77, 98, 71, 21, 34, 78, 16, 80, 20, 11, 200, 36, 225, 129, 57, 66, 78, 16, 80, 20, 11, 200, 20, 196, 203, 21, 34, 78, 16, 80, 20, 11, 200, 16, 19, 147, 21, 34, 78, 16, 80, 20, 19, 70, 24, 19, 11, 60, 225, 82, 83, 110, 55, 49, 39, 50, 6, 36, 34, 0, 20, 11, 200, 76, 84, 150, 37, 68, 137, 12, 80, 20, 7, 196, 8, 84, 193, 80, 20, 11, 200, 25, 38, 71, 80, 17, 212, 36, 112, 20, 7, 196, 88, 20, 193, 48, 20, 7, 196, 56, 20, 193, 48, 20, 11, 200, 64, 84, 147, 36, 99, 1, 28, 80, 20, 0, 12, 201, 44, 243, 77, 4, 225, 9, 80, 148, 212, 20, 12, 201, 37, 51, 204, 5, 66, 79, 56, 148, 212, 20, 12, 201, 52, 225, 77, 61, 65, 75, 56, 146, 192, 20, 0, 19, 3, 19, 195, 165, 89, 114, 15, 89, 36, 50, 47, 0, 81, 115, 101, 110, 116, 32, 17, 3, 19, 195, 165, 89, 114, 15, 107, 35, 34, 0, 81, 104, 97, 114, 32, 27, 3, 19, 195, 165, 89, 6, 113, 15, 65, 6, 113, 89, 6, 37, 13, 0, 82, 109, 195, 165, 32, 115, 105, 103, 101, 32, 17, 3, 19, 195, 165, 89, 114, 15, 65, 6, 113, 0, 81, 109, 195, 165, 32, 20, 3, 19, 195, 165, 89, 114, 15, 84, 6, 109, 114, 0, 81, 118, 195, 166, 114, 101, 32, 22, 3, 19, 195, 165, 89, 114, 15, 55, 6, 109, 68, 108, 0, 81, 108, 195, 166, 110, 103, 101, 32, 18, 3, 19, 195, 165, 89, 114, 15, 84, 6, 112, 34, 0, 81, 118, 97, 114, 32, 21, 3, 19, 195, 165, 89, 114, 15, 107, 6, 114, 57, 47, 0, 81, 104, 195, 184, 106, 116, 32, 18, 3, 19, 195, 165, 89, 114, 15, 84, 6, 36, 55, 0, 81, 118, 105, 108, 32, 21, 3, 19, 195, 165, 89, 114, 15, 55, 6, 112, 68, 47, 0, 81, 108, 97, 110, 103, 116, 32, 19, 3, 19, 195, 165, 89, 114, 15, 81, 6, 118, 34, 0, 81, 103, 195, 184, 114, 32, 16, 3, 19, 195, 165, 89, 114, 15, 6, 109, 34, 0, 81, 101, 114, 32, 21, 3, 19, 195, 165, 89, 114, 15, 65, 6, 35, 68, 108, 0, 81, 109, 97, 110, 103, 101, 32, 23, 3, 19, 195, 165, 89, 114, 15, 65, 6, 35, 12, 57, 13, 86, 0, 81, 109, 101, 103, 101, 116, 32, 12, 201, 56, 21, 137, 28, 21, 15, 72, 148, 203, 20, 12, 201, 52, 85, 1, 48, 197, 82, 28, 148, 203, 20, 12, 201, 52, 20, 212, 60, 67, 206, 80, 148, 203, 20, 12, 201, 36, 212, 5, 72, 21, 9, 88, 148, 203, 20, 12, 201, 24, 244, 130, 73, 145, 5, 72, 148, 203, 20, 13, 202, 12, 148, 212, 21, 32, 201, 20, 228, 197, 72, 20, 15, 204, 16, 83, 73, 56, 84, 129, 48, 148, 197, 72, 85, 0, 20, 9, 198, 56, 21, 9, 60, 224, 76, 20, 0, 12, 201, 56, 21, 9, 60, 224, 76, 37, 53, 0, 20, 12, 201, 44, 244, 146, 21, 52, 15, 56, 65, 82, 20, 12, 201, 44, 243, 131, 21, 52, 201, 60, 225, 82, 20, 12, 201, 44, 243, 77, 37, 52, 201, 60, 225, 82, 20, 9, 198, 85, 48, 133, 44, 148, 203, 20, 9, 198, 72, 85, 15, 72, 148, 203, 20, 9, 198, 52, 245, 15, 72, 148, 203, 20, 9, 198, 44, 244, 193, 44, 148, 203, 20, 9, 198, 12, 243, 79, 72, 148, 203, 20, 10, 199, 44, 243, 150, 21, 37, 9, 80, 20, 9, 198, 65, 35, 211, 60, 66, 75, 20, 10, 199, 72, 85, 137, 76, 244, 129, 80, 20, 11, 136, 2, 18, 195, 166, 11, 1, 7, 5, 20, 0, 15, 204, 36, 229, 5, 72, 224, 84, 36, 243, 129, 48, 148, 212, 20, 9, 198, 80, 244, 144, 20, 65, 82, 20, 9, 198, 72, 85, 1, 72, 65, 82, 20, 9, 198, 48, 146, 214, 36, 65, 82, 20, 9, 198, 44, 244, 146, 20, 193, 82, 20, 9, 198, 44, 19, 142, 20, 193, 82, 20, 9, 198, 20, 180, 208, 20, 65, 82, 20, 9, 198, 4, 197, 5, 72, 225, 82, 20, 7, 196, 5, 4, 137, 48, 20, 7, 196, 20, 180, 197, 52, 20, 9, 68, 12, 245, 67, 32, 21, 0, 10, 0, 13, 69, 12, 19, 1, 37, 48, 49, 35, 55, 6, 109, 0, 0, 9, 198, 80, 20, 148, 20, 193, 84, 20, 12, 201, 60, 36, 203, 85, 32, 78, 80, 148, 203, 20, 12, 201, 13, 149, 15, 64, 192, 83, 52, 148, 203, 20, 12, 201, 4, 178, 213, 76, 21, 9, 88, 148, 203, 20, 0, 12, 201, 72, 21, 9, 60, 224, 76, 37, 53, 0, 20, 12, 201, 64, 84, 134, 20, 181, 9, 60, 225, 82, 20, 12, 201, 44, 243, 134, 20, 181, 9, 60, 225, 82, 20, 10, 199, 64, 19, 12, 4, 66, 85, 52, 20, 10, 199, 28, 84, 149, 56, 66, 85, 52, 20, 10, 199, 21, 2, 84, 4, 98, 85, 52, 20, 10, 199, 4, 197, 77, 36, 226, 85, 52, 20, 10, 199, 20, 212, 9, 72, 148, 205, 20, 20, 10, 199, 4, 181, 9, 88, 148, 205, 20, 20, 10, 199, 16, 84, 21, 80, 84, 133, 80, 20, 10, 199, 44, 243, 132, 20, 228, 193, 80, 20, 0, 9, 198, 28, 20, 142, 37, 51, 206, 20, 9, 198, 76, 19, 139, 80, 147, 206, 20, 9, 198, 24, 193, 75, 76, 147, 206, 20, 7, 196, 61, 5, 5, 72, 20, 9, 198, 52, 145, 210, 4, 229, 0, 20, 0, 8, 197, 25, 34, 86, 60, 192, 20, 9, 198, 44, 243, 84, 21, 52, 197, 20, 8, 197, 25, 37, 71, 4, 192, 20, 8, 197, 88, 20, 137, 4, 32, 20, 0, 13, 202, 65, 54, 75, 60, 96, 82, 52, 18, 213, 52, 20, 9, 198, 20, 180, 208, 20, 66, 84, 20, 0, 17, 67, 33, 96, 68, 84, 110, 15, 89, 114, 0, 14, 81, 115, 195, 165, 32, 6, 195, 20, 64, 128, 17, 10, 199, 48, 243, 66, 5, 33, 5, 72, 20, 10, 199, 36, 229, 5, 72, 17, 197, 72, 20, 10, 199, 8, 243, 66, 5, 33, 5, 72, 20, 10, 199, 49, 85, 135, 21, 36, 137, 28, 20, 10, 199, 44, 243, 148, 36, 225, 78, 80, 20, 10, 199, 44, 243, 147, 84, 193, 78, 80, 20, 6, 195, 25, 32, 64, 76, 0, 11, 200, 4, 68, 207, 73, 5, 9, 60, 224, 20, 7, 196, 53, 85, 5, 72, 20, 9, 198, 65, 35, 198, 37, 64, 66, 20, 9, 198, 16, 83, 79, 57, 64, 66, 20, 0, 8, 197, 72, 81, 201, 60, 224, 20, 8, 197, 80, 84, 146, 36, 224, 20, 8, 197, 8, 83, 154, 36, 224, 20, 8, 197, 44, 21, 83, 4, 192, 20, 0, 11, 200, 9, 35, 206, 44, 244, 203, 61, 0, 20, 13, 202, 72, 85, 18, 4, 228, 205, 37, 69, 5, 72, 20, 13, 202, 64, 84, 147, 64, 82, 212, 37, 100, 137, 28, 20, 0, 12, 201, 44, 243, 150, 21, 36, 193, 80, 147, 206, 20, 12, 201, 44, 243, 147, 64, 148, 129, 80, 147, 206, 20, 12, 201, 20, 180, 211, 64, 148, 129, 80, 147, 206, 20, 12, 201, 20, 180, 208, 48, 244, 129, 80, 147, 206, 20, 12, 201, 12, 149, 137, 48, 148, 193, 80, 147, 206, 20, 12, 201, 5, 85, 15, 72, 148, 193, 80, 147, 206, 20, 12, 201, 4, 48, 197, 48, 84, 129, 80, 147, 206, 20, 10, 199, 21, 50, 193, 52, 245, 5, 72, 20, 10, 199, 20, 180, 203, 49, 81, 5, 72, 20, 9, 198, 72, 84, 21, 8, 194, 75, 20, 13, 138, 16, 195, 166, 4, 1, 7, 15, 7, 9, 11, 20, 9, 198, 53, 82, 203, 20, 34, 75, 20, 10, 199, 77, 68, 137, 56, 113, 78, 80, 20, 10, 199, 44, 243, 147, 84, 209, 78, 80, 20, 0, 11, 200, 77, 80, 147, 84, 213, 9, 60, 224, 20, 11, 200, 64, 84, 131, 21, 5, 9, 60, 224, 20, 11, 200, 44, 243, 131, 21, 5, 9, 60, 224, 20, 11, 200, 20, 180, 197, 45, 85, 9, 60, 224, 20, 11, 200, 84, 197, 18, 4, 208, 82, 36, 224, 20, 0, 13, 69, 77, 65, 71, 21, 64, 89, 47, 36, 13, 72, 0, 8, 197, 4, 224, 70, 61, 32, 20, 14, 139, 6, 195, 184, 4, 5, 18, 1, 20, 9, 15, 14, 20, 12, 201, 52, 81, 9, 44, 19, 69, 57, 65, 76, 20, 12, 201, 36, 228, 212, 73, 83, 69, 57, 65, 76, 20, 9, 198, 28, 19, 15, 64, 17, 5, 20, 0, 9, 198, 25, 34, 83, 85, 33, 64, 20, 9, 198, 88, 149, 18, 36, 225, 64, 20, 9, 198, 48, 145, 82, 36, 225, 192, 20, 9, 198, 65, 83, 19, 21, 33, 64, 20, 9, 198, 25, 34, 83, 21, 33, 64, 20, 9, 198, 21, 64, 71, 21, 33, 64, 20, 9, 198, 17, 32, 71, 21, 33, 64, 20, 9, 198, 88, 83, 133, 16, 145, 192, 20, 12, 4, 95, 35, 51, 50, 71, 55, 35, 50, 49, 0, 0, 33, 67, 76, 19, 20, 89, 6, 114, 55, 47, 15, 55, 109, 57, 49, 15, 89, 6, 37, 47, 37, 0, 82, 108, 97, 107, 101, 32, 99, 105, 116, 121, 32, 10, 199, 52, 20, 207, 12, 130, 83, 80, 20, 10, 199, 52, 20, 203, 36, 226, 83, 80, 20, 10, 199, 12, 243, 21, 52, 226, 83, 80, 20, 14, 203, 4, 229, 9, 44, 243, 131, 21, 5, 9, 60, 224, 20, 10, 199, 77, 68, 137, 56, 113, 78, 76, 20, 0, 11, 200, 36, 228, 212, 73, 82, 212, 61, 32, 20, 7, 196, 36, 66, 79, 52, 20, 7, 196, 28, 194, 79, 52, 20, 17, 142, 19, 20, 195, 166, 18, 15, 16, 5, 18, 1, 20, 9, 15, 14, 20, 17, 142, 11, 15, 14, 6, 195, 184, 4, 5, 18, 1, 20, 9, 15, 14, 20, 11, 200, 65, 34, 86, 36, 193, 71, 21, 32, 20, 11, 200, 64, 192, 84, 60, 226, 75, 21, 32, 20, 11, 200, 32, 84, 129, 48, 66, 75, 21, 32, 20, 9, 198, 16, 82, 211, 81, 34, 78, 20, 9, 198, 64, 18, 201, 77, 64, 78, 20, 9, 198, 80, 20, 140, 5, 64, 78, 21, 9, 198, 52, 243, 69, 57, 64, 78, 21, 0, 12, 201, 8, 18, 212, 21, 34, 79, 48, 241, 192, 20, 12, 201, 88, 243, 20, 36, 113, 82, 36, 225, 192, 20, 12, 201, 84, 68, 129, 56, 113, 82, 36, 225, 192, 20, 12, 201, 84, 68, 12, 4, 49, 82, 36, 225, 192, 20, 12, 201, 81, 32, 70, 36, 177, 82, 36, 225, 192, 20, 12, 201, 77, 80, 140, 36, 209, 82, 36, 225, 192, 20, 12, 201, 65, 80, 140, 36, 49, 82, 36, 225, 192, 20, 12, 201, 65, 35, 212, 20, 113, 82, 36, 225, 192, 20, 12, 201, 44, 243, 147, 84, 209, 82, 36, 225, 192, 20, 12, 201, 36, 228, 208, 36, 49, 82, 36, 225, 192, 20, 12, 201, 17, 84, 12, 36, 49, 82, 36, 225, 192, 20, 12, 201, 16, 84, 12, 4, 49, 82, 36, 225, 192, 20, 12, 201, 16, 83, 65, 76, 177, 82, 36, 225, 192, 20, 12, 201, 16, 83, 65, 72, 177, 82, 36, 225, 192, 20, 12, 201, 5, 52, 207, 12, 145, 82, 36, 225, 192, 20, 12, 201, 5, 4, 12, 36, 49, 82, 36, 225, 192, 20, 8, 197, 72, 19, 135, 21, 32, 20, 8, 197, 48, 243, 135, 21, 32, 20, 12, 201, 80, 147, 18, 20, 115, 133, 48, 145, 192, 20, 8, 197, 65, 34, 77, 5, 64, 20, 8, 197, 48, 147, 133, 5, 32, 20, 8, 197, 40, 17, 213, 5, 32, 20, 8, 197, 48, 147, 133, 5, 32, 20, 12, 201, 20, 180, 203, 72, 83, 69, 57, 64, 76, 20, 10, 69, 72, 19, 135, 21, 32, 21, 0, 10, 0, 9, 198, 64, 84, 137, 76, 179, 208, 20, 9, 198, 32, 244, 143, 76, 179, 208, 20, 9, 198, 44, 244, 9, 21, 33, 64, 20, 18, 70, 9, 37, 89, 21, 33, 64, 71, 34, 116, 57, 6, 109, 12, 34, 0, 20, 9, 198, 5, 36, 197, 56, 19, 0, 20, 8, 67, 49, 82, 197, 21, 0, 10, 0, 10, 199, 64, 84, 211, 36, 210, 83, 80, 20, 10, 199, 52, 243, 129, 72, 178, 83, 80, 20, 10, 199, 24, 19, 1, 56, 114, 83, 80, 20, 10, 199, 8, 19, 132, 4, 114, 83, 80, 20, 9, 198, 81, 149, 129, 29, 66, 71, 20, 9, 198, 56, 20, 129, 29, 66, 71, 20, 9, 198, 48, 149, 129, 29, 66, 71, 20, 6, 195, 21, 64, 84, 20, 9, 198, 81, 149, 129, 29, 66, 71, 20, 9, 198, 56, 20, 129, 29, 66, 71, 20, 9, 198, 48, 149, 129, 29, 66, 71, 20, 0, 11, 200, 81, 34, 85, 52, 96, 84, 61, 32, 20, 11, 200, 72, 81, 143, 72, 208, 84, 61, 32, 20, 11, 200, 16, 82, 204, 4, 208, 84, 61, 32, 20, 15, 204, 72, 17, 9, 60, 66, 82, 36, 113, 82, 36, 225, 192, 20, 15, 204, 65, 35, 199, 56, 244, 212, 36, 49, 82, 36, 225, 192, 20, 15, 204, 16, 144, 71, 56, 244, 212, 36, 49, 82, 36, 225, 192, 20, 11, 200, 72, 84, 212, 72, 147, 135, 21, 32, 20, 7, 196, 52, 148, 197, 72, 20, 11, 200, 4, 68, 212, 72, 147, 135, 21, 32, 20, 12, 137, 16, 195, 166, 4, 9, 1, 20, 18, 9, 20, 9, 198, 81, 32, 83, 76, 21, 0, 20, 0, 9, 198, 60, 229, 15, 48, 241, 201, 20, 12, 201, 24, 245, 15, 44, 244, 9, 21, 33, 64, 20, 24, 73, 8, 243, 130, 60, 227, 137, 21, 33, 64, 71, 114, 68, 71, 114, 68, 57, 6, 109, 12, 34, 0, 20, 8, 197, 48, 144, 133, 72, 144, 20, 9, 198, 72, 83, 9, 45, 98, 69, 20, 9, 198, 76, 147, 5, 57, 66, 69, 20, 9, 198, 28, 195, 211, 5, 34, 69, 20, 8, 197, 29, 84, 129, 52, 144, 20, 0, 9, 198, 9, 81, 4, 32, 148, 212, 20, 9, 198, 88, 19, 11, 21, 34, 64, 20, 9, 198, 29, 34, 83, 21, 34, 64, 20, 9, 198, 9, 145, 199, 21, 34, 64, 20, 9, 198, 44, 20, 146, 36, 243, 0, 20, 9, 198, 85, 67, 208, 37, 50, 192, 20, 9, 198, 32, 18, 84, 37, 50, 192, 20, 9, 198, 21, 35, 212, 37, 50, 192, 20, 9, 198, 77, 147, 80, 5, 66, 64, 20, 9, 198, 24, 20, 133, 77, 66, 64, 20, 9, 198, 17, 147, 129, 77, 66, 64, 20, 9, 198, 16, 83, 69, 57, 66, 64, 20, 0, 10, 199, 88, 84, 137, 24, 144, 197, 72, 20, 10, 199, 56, 22, 137, 24, 144, 197, 72, 20, 10, 199, 44, 243, 77, 37, 69, 5, 72, 20, 10, 199, 20, 180, 208, 48, 144, 197, 72, 20, 10, 199, 4, 229, 9, 44, 148, 197, 72, 20, 6, 195, 61, 130, 68, 20, 16, 141, 18, 195, 184, 14, 20, 7, 5, 14, 15, 7, 18, 1, 6, 20, 0, 10, 135, 2, 9, 12, 12, 195, 184, 19, 20, 9, 134, 1, 11, 20, 195, 184, 18, 20, 12, 201, 8, 18, 212, 21, 34, 79, 48, 241, 201, 20, 11, 200, 24, 244, 147, 88, 20, 140, 36, 112, 20, 11, 200, 24, 244, 139, 48, 20, 140, 36, 112, 20, 11, 200, 4, 195, 79, 16, 84, 140, 36, 112, 20, 9, 198, 36, 225, 9, 88, 145, 0, 20, 12, 201, 77, 84, 16, 61, 50, 84, 61, 34, 69, 20, 11, 200, 72, 81, 133, 72, 83, 132, 84, 208, 20, 11, 200, 77, 65, 82, 20, 241, 143, 56, 144, 20, 11, 200, 89, 83, 11, 4, 226, 83, 52, 80, 20, 11, 200, 52, 244, 141, 60, 226, 83, 52, 80, 20, 11, 200, 52, 241, 5, 72, 226, 83, 52, 80, 20, 11, 200, 44, 243, 77, 84, 226, 83, 52, 80, 20, 11, 200, 32, 148, 212, 61, 34, 83, 52, 80, 20, 11, 200, 16, 241, 205, 5, 66, 83, 52, 80, 20, 11, 200, 16, 84, 208, 61, 66, 83, 52, 80, 20, 11, 200, 41, 81, 76, 76, 210, 78, 16, 80, 20, 9, 198, 16, 83, 9, 44, 21, 0, 20, 0, 8, 197, 8, 147, 208, 76, 144, 20, 12, 201, 65, 35, 208, 4, 112, 78, 16, 148, 212, 20, 12, 201, 5, 4, 15, 76, 149, 9, 60, 225, 76, 20, 12, 201, 77, 147, 133, 72, 113, 84, 37, 50, 192, 20, 12, 201, 53, 84, 201, 44, 19, 148, 37, 50, 192, 20, 12, 201, 52, 244, 203, 61, 98, 84, 37, 50, 192, 20, 12, 201, 45, 38, 83, 80, 19, 12, 37, 50, 192, 20, 12, 201, 44, 244, 205, 60, 195, 199, 37, 50, 192, 20, 12, 201, 44, 148, 143, 52, 19, 148, 37, 50, 192, 20, 12, 201, 44, 21, 1, 65, 83, 20, 37, 50, 192, 20, 12, 201, 32, 148, 212, 60, 195, 199, 37, 50, 192, 20, 12, 201, 32, 83, 73, 13, 146, 204, 37, 50, 192, 20, 9, 198, 56, 84, 20, 84, 226, 69, 20, 9, 134, 21, 18, 195, 166, 13, 9, 20, 10, 69, 76, 147, 135, 48, 80, 21, 0, 10, 24, 4, 95, 57, 88, 15, 107, 110, 55, 83, 6, 109, 65, 89, 36, 50, 89, 47, 116, 84, 13, 50, 13, 0, 0, 25, 67, 32, 243, 5, 107, 6, 39, 40, 55, 37, 50, 58, 4, 115, 50, 0, 82, 105, 110, 32, 111, 110, 101, 32, 11, 136, 19, 21, 6, 6, 12, 195, 184, 18, 20, 9, 198, 56, 21, 21, 72, 148, 212, 20, 9, 198, 52, 244, 129, 48, 148, 212, 20, 9, 198, 25, 85, 21, 72, 148, 212, 20, 16, 141, 9, 13, 16, 18, 195, 166, 7, 14, 5, 18, 9, 14, 7, 20, 13, 202, 44, 243, 12, 20, 181, 9, 88, 148, 197, 72, 20, 13, 202, 20, 180, 203, 60, 211, 85, 56, 144, 197, 72, 20, 13, 202, 20, 180, 197, 53, 3, 9, 24, 144, 197, 72, 20, 12, 201, 61, 97, 82, 88, 147, 132, 20, 194, 71, 20, 12, 201, 28, 83, 142, 20, 212, 201, 29, 66, 71, 20, 9, 198, 104, 18, 82, 37, 50, 192, 20, 9, 198, 76, 244, 130, 37, 50, 192, 20, 9, 198, 76, 84, 130, 37, 50, 192, 20, 9, 198, 44, 243, 66, 36, 224, 84, 20, 9, 198, 44, 19, 132, 36, 64, 84, 20, 9, 198, 36, 229, 5, 72, 224, 84, 20, 0, 12, 137, 12, 195, 184, 7, 19, 20, 195, 184, 18, 20, 12, 137, 4, 9, 18, 5, 11, 20, 195, 184, 18, 20, 10, 199, 44, 243, 147, 21, 37, 133, 72, 20, 9, 198, 28, 83, 133, 80, 148, 203, 20, 9, 198, 24, 19, 129, 80, 148, 203, 20, 14, 203, 64, 84, 147, 64, 82, 212, 37, 98, 83, 52, 80, 20, 10, 199, 8, 84, 135, 20, 228, 197, 72, 20, 0, 9, 198, 5, 4, 18, 21, 69, 82, 20, 13, 138, 11, 15, 18, 18, 5, 11, 20, 195, 184, 18, 20, 13, 138, 11, 15, 12, 12, 5, 11, 20, 195, 184, 18, 20, 11, 200, 77, 65, 82, 20, 241, 210, 4, 208, 20, 11, 200, 76, 82, 83, 52, 241, 210, 4, 208, 20, 11, 200, 61, 33, 193, 56, 145, 210, 4, 208, 20, 11, 200, 44, 20, 132, 36, 241, 210, 4, 208, 20, 9, 198, 77, 80, 147, 84, 209, 82, 20, 9, 198, 48, 19, 69, 57, 65, 82, 20, 9, 198, 44, 243, 66, 36, 225, 82, 20, 9, 198, 44, 19, 132, 36, 65, 82, 20, 9, 198, 36, 229, 5, 72, 225, 82, 20, 9, 198, 16, 83, 69, 57, 65, 82, 20, 9, 198, 8, 192, 78, 12, 129, 82, 20, 11, 200, 81, 35, 211, 45, 147, 4, 36, 112, 20, 11, 200, 44, 243, 4, 76, 147, 132, 36, 112, 20, 11, 200, 16, 81, 137, 56, 84, 140, 36, 112, 20, 11, 200, 16, 241, 5, 44, 17, 143, 56, 144, 20, 11, 200, 44, 84, 148, 20, 210, 78, 16, 80, 20, 6, 195, 21, 66, 75, 20, 9, 198, 64, 243, 77, 21, 32, 78, 20, 0, 12, 201, 84, 226, 86, 21, 36, 193, 48, 148, 212, 20, 12, 201, 72, 17, 9, 60, 99, 206, 37, 50, 192, 20, 12, 201, 65, 54, 75, 36, 21, 18, 37, 50, 192, 20, 12, 201, 64, 19, 148, 60, 210, 77, 37, 50, 192, 20, 12, 201, 52, 85, 1, 52, 244, 134, 37, 50, 192, 20, 12, 201, 29, 32, 70, 60, 195, 199, 37, 50, 192, 20, 12, 201, 28, 83, 77, 60, 195, 199, 37, 50, 192, 20, 12, 201, 20, 193, 75, 81, 35, 206, 37, 50, 192, 20, 12, 201, 16, 85, 5, 45, 66, 86, 37, 50, 192, 20, 12, 201, 12, 19, 9, 24, 244, 142, 37, 50, 192, 20, 12, 201, 8, 81, 18, 4, 113, 82, 37, 50, 192, 20, 12, 201, 5, 81, 9, 60, 195, 199, 37, 50, 192, 20, 12, 201, 4, 114, 84, 5, 67, 210, 37, 50, 192, 20, 12, 201, 52, 84, 137, 80, 242, 210, 5, 66, 64, 20, 12, 201, 5, 34, 83, 80, 242, 210, 5, 66, 64, 20, 12, 201, 81, 32, 78, 77, 3, 1, 57, 64, 84, 20, 0, 9, 198, 76, 84, 150, 37, 69, 84, 20, 12, 201, 44, 243, 150, 84, 196, 201, 88, 148, 203, 20, 12, 201, 33, 148, 15, 44, 243, 132, 72, 148, 203, 20, 0, 17, 142, 21, 4, 13, 1, 14, 195, 184, 22, 18, 5, 18, 9, 14, 7, 20, 12, 201, 81, 32, 78, 77, 3, 1, 57, 65, 82, 20, 9, 198, 77, 68, 143, 24, 148, 203, 20, 9, 198, 5, 68, 143, 24, 148, 203, 20, 9, 198, 5, 32, 77, 4, 148, 203, 20, 10, 199, 77, 83, 132, 9, 147, 137, 80, 20, 9, 198, 76, 83, 65, 57, 66, 75, 20, 10, 199, 77, 147, 129, 28, 241, 193, 48, 20, 0, 9, 198, 45, 84, 150, 5, 69, 82, 20, 9, 198, 81, 33, 80, 4, 225, 82, 20, 9, 198, 65, 35, 198, 37, 65, 82, 20, 9, 198, 64, 84, 131, 37, 1, 82, 20, 9, 198, 52, 245, 9, 60, 225, 82, 20, 9, 198, 36, 212, 15, 73, 65, 82, 20, 9, 198, 29, 32, 84, 36, 225, 82, 20, 9, 198, 21, 50, 207, 73, 65, 82, 20, 9, 198, 16, 81, 210, 4, 65, 82, 20, 9, 198, 4, 36, 212, 36, 225, 82, 20, 15, 204, 88, 84, 147, 36, 98, 75, 5, 67, 210, 37, 50, 192, 20, 15, 204, 36, 212, 18, 61, 98, 83, 5, 67, 210, 37, 50, 192, 20, 7, 196, 65, 84, 9, 48, 20, 10, 67, 33, 98, 83, 84, 36, 89, 0, 76, 0, 9, 198, 4, 227, 210, 20, 180, 201, 20, 12, 201, 52, 20, 203, 84, 194, 78, 37, 65, 84, 20, 0, 12, 201, 81, 35, 212, 76, 178, 83, 80, 148, 203, 20, 12, 201, 24, 147, 8, 5, 35, 79, 56, 148, 203, 20, 12, 201, 21, 67, 143, 12, 83, 148, 72, 148, 203, 20, 13, 138, 11, 195, 166, 6, 5, 18, 5, 18, 5, 20, 20, 0, 12, 137, 16, 18, 195, 166, 6, 5, 18, 5, 18, 20, 10, 199, 56, 21, 21, 72, 148, 205, 20, 20, 10, 199, 25, 85, 21, 72, 148, 205, 20, 20, 10, 199, 16, 144, 76, 20, 181, 1, 48, 20, 0, 7, 196, 5, 5, 5, 72, 20, 0, 12, 201, 72, 83, 148, 4, 34, 76, 37, 65, 84, 20, 9, 198, 56, 240, 140, 21, 52, 197, 20, 8, 197, 5, 82, 211, 36, 224, 20, 16, 141, 11, 15, 14, 6, 195, 184, 4, 5, 18, 5, 18, 5, 20, 20, 12, 201, 36, 228, 212, 73, 83, 69, 57, 64, 76, 20, 0, 13, 202, 44, 243, 12, 20, 114, 65, 48, 149, 5, 80, 20, 14, 139, 195, 184, 11, 15, 14, 15, 13, 5, 20, 18, 9, 20, 13, 202, 4, 224, 76, 24, 16, 133, 80, 148, 205, 20, 20, 13, 202, 44, 19, 3, 37, 83, 78, 37, 68, 129, 80, 20, 13, 202, 12, 19, 3, 37, 83, 78, 37, 68, 129, 80, 20, 0, 10, 199, 77, 84, 18, 20, 208, 84, 36, 20, 0, 9, 198, 4, 65, 9, 80, 147, 206, 20, 15, 204, 65, 35, 198, 21, 52, 201, 60, 224, 76, 37, 65, 84, 20, 11, 200, 4, 225, 1, 49, 84, 201, 20, 224, 20, 11, 200, 72, 84, 21, 8, 194, 75, 4, 224, 20, 7, 196, 9, 85, 1, 56, 21, 9, 198, 16, 148, 208, 85, 64, 66, 20, 0, 14, 139, 16, 18, 195, 166, 4, 9, 11, 20, 9, 15, 14, 20, 8, 197, 52, 83, 148, 60, 192, 20, 8, 197, 24, 244, 211, 36, 192, 20, 8, 197, 76, 160, 75, 4, 192, 20, 8, 197, 24, 148, 203, 4, 192, 20, 8, 197, 61, 1, 82, 4, 32, 20, 0, 9, 198, 56, 243, 142, 21, 66, 84, 20, 0, 9, 198, 12, 19, 129, 16, 148, 203, 20, 9, 198, 5, 50, 65, 80, 148, 203, 20, 10, 199, 12, 128, 78, 28, 80, 78, 80, 20, 0, 27, 68, 36, 66, 79, 80, 37, 72, 37, 6, 39, 15, 89, 110, 84, 6, 112, 68, 0, 81, 115, 97, 118, 97, 110, 116, 32, 11, 200, 12, 84, 133, 52, 243, 137, 20, 192, 20, 0, 8, 197, 12, 19, 80, 21, 32, 20, 8, 197, 80, 84, 141, 37, 64, 20, 0, 18, 70, 40, 19, 66, 61, 33, 64, 72, 57, 35, 65, 71, 39, 51, 6, 109, 0, 9, 198, 64, 20, 211, 21, 33, 64, 20, 9, 198, 28, 195, 211, 21, 33, 64, 20, 9, 198, 25, 32, 83, 21, 33, 64, 20, 12, 201, 36, 212, 5, 72, 21, 15, 72, 148, 203, 20, 12, 201, 44, 243, 66, 36, 224, 84, 61, 34, 75, 20, 9, 198, 12, 85, 1, 57, 64, 76, 20, 13, 202, 12, 128, 84, 20, 21, 66, 72, 144, 78, 80, 20, 0, 9, 198, 72, 243, 65, 57, 66, 75, 20, 9, 198, 48, 241, 201, 77, 66, 75, 20, 0, 11, 200, 44, 243, 138, 84, 226, 212, 85, 32, 20, 11, 200, 36, 229, 133, 77, 66, 84, 85, 32, 20, 11, 200, 4, 181, 80, 84, 226, 212, 85, 32, 20, 9, 198, 16, 147, 73, 77, 51, 210, 20, 11, 200, 52, 19, 20, 72, 18, 212, 21, 32, 20, 11, 200, 24, 18, 211, 36, 210, 76, 21, 32, 20, 9, 198, 72, 244, 205, 5, 34, 78, 20, 7, 196, 16, 148, 211, 20, 76, 0, 8, 197, 88, 21, 20, 21, 32, 20, 12, 201, 77, 68, 129, 8, 17, 19, 21, 33, 64, 20, 8, 197, 76, 176, 76, 21, 32, 20, 12, 201, 64, 20, 129, 25, 32, 83, 21, 33, 64, 20, 12, 201, 52, 85, 1, 77, 64, 83, 21, 33, 64, 20, 8, 197, 45, 33, 80, 21, 32, 20, 8, 197, 28, 245, 84, 21, 32, 20, 12, 201, 60, 208, 68, 72, 84, 211, 21, 33, 64, 20, 8, 197, 52, 20, 141, 37, 64, 20, 13, 138, 3, 195, 166, 19, 1, 18, 9, 19, 13, 5, 20, 9, 198, 21, 50, 193, 64, 17, 5, 20, 0, 18, 70, 29, 37, 89, 21, 33, 64, 81, 34, 116, 57, 6, 109, 12, 34, 0, 20, 9, 198, 52, 243, 143, 64, 243, 0, 20, 0, 9, 134, 22, 5, 14, 195, 184, 19, 20, 9, 198, 64, 147, 129, 29, 66, 71, 20, 15, 140, 5, 16, 9, 11, 21, 18, 195, 166, 9, 19, 13, 5, 20, 9, 198, 64, 147, 129, 29, 66, 71, 20, 0, 11, 200, 16, 83, 79, 45, 32, 84, 85, 32, 20, 10, 135, 15, 13, 9, 14, 195, 184, 19, 20, 7, 196, 4, 226, 79, 56, 20, 11, 200, 48, 244, 135, 56, 85, 20, 21, 32, 20, 11, 200, 44, 243, 80, 48, 85, 20, 21, 32, 20, 11, 200, 16, 148, 211, 36, 210, 76, 21, 32, 20, 9, 198, 24, 197, 79, 72, 145, 0, 20, 13, 138, 16, 1, 12, 195, 166, 15, 7, 18, 1, 6, 20, 9, 198, 16, 82, 193, 56, 21, 0, 20, 9, 198, 36, 229, 133, 57, 64, 82, 20, 0, 9, 198, 45, 35, 205, 61, 51, 205, 20, 12, 201, 65, 35, 199, 72, 19, 77, 21, 33, 64, 20, 8, 197, 72, 20, 197, 72, 144, 20, 16, 69, 64, 243, 9, 76, 176, 48, 39, 55, 6, 37, 89, 49, 0, 20, 9, 198, 88, 19, 11, 101, 34, 69, 20, 9, 198, 61, 32, 84, 61, 34, 69, 20, 9, 198, 80, 83, 5, 64, 21, 9, 20, 8, 197, 72, 84, 12, 36, 176, 20, 8, 197, 76, 80, 78, 12, 80, 20, 0, 12, 137, 13, 15, 14, 19, 20, 18, 195, 184, 19, 20, 9, 198, 80, 244, 211, 21, 34, 64, 20, 9, 198, 72, 20, 19, 21, 34, 64, 20, 9, 198, 49, 84, 203, 21, 34, 64, 20, 9, 198, 48, 241, 19, 21, 34, 64, 20, 9, 198, 48, 20, 19, 21, 34, 64, 20, 9, 198, 25, 84, 203, 21, 34, 64, 20, 9, 198, 12, 21, 83, 21, 34, 64, 20, 9, 198, 44, 243, 148, 72, 243, 0, 20, 9, 198, 76, 21, 68, 37, 50, 192, 20, 9, 198, 64, 241, 84, 37, 50, 192, 20, 9, 198, 65, 35, 198, 21, 66, 64, 20, 9, 198, 45, 96, 82, 80, 147, 0, 20, 9, 198, 64, 245, 5, 57, 64, 84, 20, 9, 198, 88, 17, 201, 56, 19, 0, 20, 9, 198, 72, 85, 137, 88, 19, 0, 20, 9, 198, 36, 195, 5, 28, 19, 0, 20, 0, 13, 138, 12, 9, 2, 9, 4, 9, 14, 195, 184, 19, 20, 13, 138, 6, 9, 12, 9, 19, 20, 18, 195, 184, 19, 20, 8, 133, 15, 4, 195, 184, 18, 20, 12, 137, 3, 8, 1, 21, 6, 6, 195, 184, 18, 20, 9, 198, 44, 149, 129, 29, 66, 71, 20, 10, 199, 44, 20, 141, 60, 148, 201, 56, 20, 10, 199, 4, 229, 9, 65, 148, 137, 56, 20, 10, 199, 4, 224, 84, 60, 194, 69, 56, 20, 9, 198, 44, 149, 129, 29, 66, 71, 20, 0, 13, 68, 56, 241, 204, 20, 50, 6, 39, 12, 14, 50, 0, 13, 138, 18, 195, 166, 19, 15, 14, 14, 195, 184, 18, 20, 9, 134, 11, 21, 12, 195, 184, 18, 20, 11, 200, 21, 97, 78, 81, 148, 140, 36, 112, 20, 11, 200, 80, 83, 203, 72, 21, 9, 76, 176, 20, 11, 200, 77, 147, 148, 4, 181, 9, 76, 176, 20, 11, 200, 64, 20, 129, 8, 243, 9, 76, 176, 20, 11, 200, 8, 147, 210, 101, 67, 73, 76, 176, 20, 12, 201, 60, 36, 197, 73, 96, 84, 61, 34, 69, 20, 11, 200, 45, 84, 129, 80, 244, 137, 84, 208, 20, 11, 200, 28, 195, 211, 76, 20, 137, 84, 208, 20, 9, 198, 44, 243, 15, 72, 149, 0, 20, 11, 200, 76, 243, 9, 65, 50, 83, 52, 80, 20, 11, 200, 72, 85, 77, 5, 66, 83, 52, 80, 20, 11, 200, 64, 84, 211, 36, 210, 83, 52, 80, 20, 11, 200, 52, 243, 143, 80, 82, 83, 52, 80, 20, 11, 200, 52, 243, 129, 72, 178, 83, 52, 80, 20, 11, 200, 45, 83, 20, 85, 34, 83, 52, 80, 20, 11, 200, 40, 84, 213, 37, 66, 83, 52, 80, 20, 11, 200, 16, 81, 129, 37, 66, 83, 52, 80, 20, 9, 198, 80, 83, 203, 72, 21, 0, 20, 9, 198, 16, 145, 206, 37, 64, 82, 20, 9, 198, 65, 35, 204, 21, 64, 82, 20, 0, 15, 140, 19, 11, 1, 18, 12, 1, 20, 9, 14, 195, 184, 19, 20, 8, 197, 24, 144, 146, 60, 208, 20, 12, 201, 80, 147, 79, 45, 32, 84, 37, 50, 192, 20, 12, 201, 80, 84, 129, 64, 85, 84, 37, 50, 192, 20, 12, 201, 77, 148, 212, 20, 208, 84, 37, 50, 192, 20, 12, 201, 72, 16, 149, 48, 148, 212, 37, 50, 192, 20, 12, 201, 61, 37, 15, 16, 243, 148, 37, 50, 192, 20, 12, 201, 57, 83, 73, 76, 208, 84, 37, 50, 192, 20, 12, 201, 52, 244, 134, 20, 208, 84, 37, 50, 192, 20, 12, 201, 44, 20, 137, 76, 208, 84, 37, 50, 192, 20, 12, 201, 29, 32, 86, 37, 65, 84, 37, 50, 192, 20, 12, 201, 24, 144, 133, 72, 244, 20, 37, 50, 192, 20, 12, 201, 20, 208, 140, 20, 208, 84, 37, 50, 192, 20, 12, 201, 16, 148, 12, 60, 208, 84, 37, 50, 192, 20, 12, 201, 5, 85, 15, 45, 32, 84, 37, 50, 192, 20, 12, 201, 5, 53, 9, 28, 208, 84, 37, 50, 192, 20, 12, 201, 4, 229, 9, 76, 84, 20, 37, 50, 192, 20, 12, 201, 4, 180, 201, 60, 208, 84, 37, 50, 192, 20, 12, 201, 4, 84, 143, 56, 21, 84, 37, 50, 192, 20, 9, 198, 52, 243, 69, 57, 69, 77, 20, 12, 201, 12, 83, 148, 72, 145, 149, 28, 19, 0, 20, 0, 12, 137, 13, 21, 19, 11, 21, 12, 195, 184, 19, 20, 11, 136, 13, 1, 18, 15, 4, 195, 184, 18, 20, 11, 136, 11, 18, 5, 1, 20, 195, 184, 18, 20, 11, 136, 4, 5, 11, 21, 16, 195, 184, 18, 20, 9, 198, 72, 243, 65, 56, 148, 212, 20, 9, 198, 76, 49, 78, 37, 50, 192, 20, 9, 198, 72, 243, 66, 37, 50, 192, 20, 9, 198, 37, 35, 206, 37, 50, 192, 20, 9, 198, 36, 176, 82, 37, 50, 192, 20, 9, 198, 5, 85, 5, 57, 66, 64, 20, 9, 198, 4, 211, 133, 77, 66, 64, 20, 9, 198, 72, 84, 197, 73, 96, 84, 20, 0, 12, 137, 19, 11, 21, 12, 16, 20, 195, 184, 18, 20, 12, 137, 19, 9, 7, 14, 1, 12, 195, 184, 18, 20, 12, 137, 14, 9, 22, 5, 12, 12, 195, 184, 18, 20, 12, 137, 4, 5, 20, 1, 3, 8, 195, 184, 18, 20, 10, 199, 65, 35, 204, 60, 225, 197, 72, 20, 10, 199, 24, 84, 141, 20, 229, 5, 72, 20, 10, 199, 45, 33, 80, 21, 35, 9, 28, 20, 10, 199, 4, 228, 214, 5, 35, 9, 28, 20, 14, 203, 44, 243, 147, 21, 37, 129, 80, 244, 137, 84, 208, 20, 10, 199, 76, 18, 210, 37, 53, 1, 56, 21, 0, 9, 198, 64, 20, 148, 37, 69, 82, 20, 9, 198, 16, 146, 212, 5, 69, 82, 20, 14, 139, 20, 21, 2, 5, 18, 11, 21, 12, 195, 184, 19, 20, 9, 198, 77, 81, 199, 21, 33, 82, 20, 9, 198, 76, 181, 76, 65, 65, 82, 20, 9, 198, 45, 83, 20, 37, 97, 82, 20, 9, 198, 36, 229, 133, 57, 65, 82, 20, 9, 198, 36, 225, 4, 5, 65, 82, 20, 9, 198, 32, 244, 208, 37, 65, 82, 20, 9, 198, 16, 84, 15, 73, 65, 82, 20, 9, 198, 5, 4, 18, 21, 65, 82, 20, 9, 198, 4, 36, 197, 57, 65, 82, 20, 11, 200, 76, 181, 82, 44, 17, 212, 36, 112, 20, 11, 200, 61, 34, 193, 56, 17, 212, 36, 112, 20, 11, 200, 56, 21, 142, 45, 83, 132, 36, 112, 20, 11, 200, 45, 32, 77, 64, 17, 212, 36, 112, 20, 11, 200, 44, 193, 74, 56, 211, 196, 36, 112, 20, 15, 204, 60, 227, 205, 5, 67, 208, 60, 145, 84, 37, 50, 192, 20, 11, 200, 48, 243, 66, 5, 33, 9, 76, 176, 20, 11, 200, 24, 243, 133, 52, 21, 9, 76, 176, 20, 11, 200, 20, 230, 153, 52, 21, 9, 76, 176, 20, 11, 200, 76, 83, 73, 56, 20, 137, 84, 208, 20, 11, 200, 76, 19, 129, 80, 244, 137, 84, 208, 20, 11, 200, 52, 244, 129, 80, 244, 137, 84, 208, 20, 7, 196, 24, 197, 65, 80, 20, 11, 200, 76, 181, 82, 44, 17, 212, 36, 112, 20, 11, 200, 45, 32, 77, 64, 17, 212, 36, 112, 20, 0, 14, 139, 18, 5, 11, 22, 9, 19, 9, 20, 195, 184, 18, 20, 14, 139, 16, 5, 18, 6, 15, 18, 1, 20, 195, 184, 18, 20, 14, 139, 14, 21, 13, 13, 5, 18, 1, 20, 195, 184, 18, 20, 14, 139, 9, 14, 6, 15, 18, 13, 1, 20, 195, 184, 18, 20, 14, 139, 1, 11, 11, 22, 9, 19, 9, 20, 195, 184, 18, 20, 14, 139, 16, 18, 195, 166, 20, 5, 14, 20, 9, 15, 14, 20, 12, 201, 80, 84, 146, 21, 53, 18, 37, 50, 192, 20, 12, 201, 76, 83, 22, 37, 35, 206, 37, 50, 192, 20, 12, 201, 65, 35, 214, 37, 51, 210, 37, 50, 192, 20, 12, 201, 52, 146, 210, 60, 99, 206, 37, 50, 192, 20, 12, 201, 44, 243, 131, 20, 229, 18, 37, 50, 192, 20, 12, 201, 28, 83, 195, 20, 229, 18, 37, 50, 192, 20, 12, 201, 16, 146, 212, 5, 67, 210, 37, 50, 192, 20, 0, 11, 136, 11, 22, 195, 166, 19, 20, 21, 18, 20, 15, 140, 19, 20, 5, 18, 5, 15, 20, 25, 16, 195, 184, 18, 20, 9, 198, 64, 245, 5, 57, 66, 76, 20, 12, 201, 24, 243, 11, 48, 244, 137, 77, 66, 75, 20, 9, 198, 80, 83, 80, 61, 32, 76, 20, 9, 198, 36, 229, 5, 73, 96, 76, 20, 0, 16, 141, 11, 15, 12, 12, 1, 2, 15, 18, 1, 20, 195, 184, 18, 20, 16, 141, 4, 5, 13, 15, 14, 19, 20, 18, 1, 20, 195, 184, 18, 20, 12, 201, 36, 225, 129, 57, 65, 82, 37, 53, 0, 20, 12, 201, 44, 243, 148, 36, 225, 197, 57, 65, 82, 20, 14, 203, 32, 84, 141, 4, 100, 143, 16, 149, 9, 76, 176, 20, 14, 203, 20, 180, 193, 52, 147, 129, 80, 244, 137, 84, 208, 20, 9, 198, 65, 35, 212, 21, 66, 75, 20, 0, 9, 198, 77, 68, 149, 45, 69, 82, 20, 9, 198, 76, 145, 206, 5, 69, 82, 20, 17, 142, 1, 11, 11, 15, 13, 16, 1, 7, 14, 1, 20, 195, 184, 18, 20, 9, 198, 72, 83, 79, 57, 65, 82, 20, 9, 198, 36, 229, 133, 73, 65, 82, 20, 9, 198, 28, 19, 15, 65, 1, 82, 20, 9, 198, 21, 96, 80, 61, 33, 82, 20, 9, 198, 16, 84, 18, 5, 97, 82, 20, 15, 204, 44, 243, 148, 72, 17, 9, 45, 67, 210, 37, 50, 192, 20, 15, 204, 32, 19, 12, 84, 50, 78, 5, 67, 210, 37, 50, 192, 20, 15, 204, 5, 33, 213, 52, 83, 148, 5, 67, 210, 37, 50, 192, 20, 9, 198, 24, 147, 9, 65, 2, 78, 20, 7, 196, 72, 246, 65, 48, 20, 0, 12, 201, 60, 97, 133, 57, 50, 86, 37, 65, 84, 20, 12, 201, 36, 229, 5, 57, 50, 86, 37, 65, 84, 20, 12, 201, 36, 225, 133, 72, 147, 210, 37, 65, 84, 20, 12, 201, 36, 212, 21, 49, 50, 86, 37, 65, 84, 20, 12, 201, 12, 148, 139, 84, 192, 82, 37, 65, 84, 20, 0, 9, 198, 36, 228, 212, 37, 69, 84, 20, 9, 198, 17, 80, 76, 37, 65, 84, 20, 9, 198, 36, 225, 129, 57, 66, 76, 20, 9, 198, 32, 244, 208, 37, 64, 76, 20, 0, 18, 67, 64, 112, 64, 48, 113, 15, 81, 51, 6, 113, 19, 50, 15, 110, 0, 25, 10, 199, 76, 243, 143, 72, 149, 5, 80, 20, 12, 201, 81, 84, 139, 52, 83, 137, 77, 64, 78, 21, 12, 201, 80, 17, 19, 40, 146, 201, 77, 64, 78, 21, 10, 199, 64, 145, 68, 21, 53, 1, 48, 20, 10, 199, 44, 243, 147, 60, 224, 78, 76, 20, 8, 67, 8, 32, 192, 21, 0, 10, 0, 11, 136, 3, 195, 184, 12, 9, 2, 1, 20, 20, 11, 136, 1, 4, 195, 166, 11, 22, 1, 20, 20, 9, 198, 16, 148, 203, 4, 229, 0, 20, 9, 198, 8, 18, 203, 4, 229, 0, 20, 9, 198, 72, 83, 65, 72, 176, 66, 20, 0, 11, 67, 92, 145, 78, 84, 6, 37, 12, 50, 0, 9, 198, 44, 243, 132, 100, 195, 205, 20, 12, 201, 88, 20, 137, 4, 34, 76, 37, 65, 84, 20, 12, 201, 80, 82, 206, 36, 176, 76, 37, 65, 84, 20, 12, 201, 72, 21, 9, 60, 224, 76, 37, 65, 84, 20, 12, 201, 64, 20, 129, 48, 193, 76, 37, 65, 84, 20, 12, 201, 45, 34, 77, 36, 224, 76, 37, 65, 84, 20, 12, 201, 21, 97, 78, 81, 80, 76, 37, 65, 84, 20, 8, 197, 44, 195, 210, 36, 64, 20, 8, 197, 80, 242, 211, 36, 224, 20, 9, 198, 20, 210, 78, 20, 224, 197, 20, 8, 197, 24, 85, 68, 4, 192, 20, 0, 9, 198, 21, 98, 68, 20, 228, 192, 20, 0, 10, 199, 76, 21, 9, 72, 146, 197, 72, 20, 10, 199, 72, 85, 15, 72, 146, 197, 72, 20, 10, 199, 5, 53, 5, 56, 146, 197, 72, 20, 10, 199, 76, 192, 86, 37, 53, 9, 44, 20, 10, 199, 33, 145, 18, 5, 83, 9, 44, 20, 10, 199, 61, 53, 9, 56, 66, 69, 56, 20, 10, 199, 9, 32, 83, 36, 194, 69, 56, 20, 10, 199, 44, 243, 147, 60, 224, 78, 80, 20, 8, 67, 12, 144, 64, 21, 0, 10, 0, 15, 204, 37, 36, 133, 88, 84, 147, 36, 34, 76, 37, 65, 84, 20, 15, 204, 36, 229, 5, 48, 193, 75, 81, 80, 76, 37, 65, 84, 20, 11, 200, 4, 229, 9, 80, 242, 211, 36, 224, 20, 11, 200, 52, 18, 197, 16, 243, 137, 20, 224, 20, 9, 198, 21, 66, 79, 64, 145, 78, 20, 11, 200, 4, 33, 83, 76, 147, 137, 20, 224, 20, 9, 198, 20, 193, 77, 20, 229, 0, 20, 9, 198, 64, 20, 139, 4, 229, 0, 20, 9, 198, 56, 81, 207, 80, 144, 66, 20, 0, 7, 197, 64, 84, 146, 60, 224, 8, 197, 77, 83, 6, 36, 64, 20, 8, 197, 56, 19, 139, 36, 224, 20, 15, 69, 16, 84, 211, 36, 224, 72, 36, 89, 6, 109, 68, 0, 20, 9, 198, 4, 229, 9, 56, 243, 73, 20, 8, 197, 56, 21, 84, 36, 192, 20, 8, 197, 80, 243, 135, 4, 224, 20, 8, 197, 52, 19, 135, 4, 224, 21, 8, 197, 64, 244, 212, 4, 192, 20, 8, 197, 9, 37, 84, 4, 192, 20, 0, 26, 74, 77, 21, 65, 72, 81, 1, 56, 49, 82, 20, 89, 49, 58, 6, 36, 13, 72, 35, 12, 50, 89, 114, 108, 0, 15, 140, 16, 18, 195, 166, 16, 15, 19, 9, 20, 9, 15, 14, 20, 13, 202, 56, 85, 82, 5, 53, 5, 56, 146, 197, 72, 20, 0, 11, 136, 195, 184, 11, 15, 12, 15, 7, 9, 20, 10, 199, 28, 16, 129, 72, 66, 78, 20, 20, 10, 199, 76, 82, 213, 56, 65, 82, 20, 20, 10, 199, 72, 84, 18, 20, 210, 69, 72, 20, 10, 199, 64, 83, 132, 84, 193, 82, 20, 20, 10, 199, 44, 20, 197, 72, 225, 82, 20, 20, 10, 199, 21, 82, 193, 72, 148, 212, 36, 20, 14, 203, 81, 32, 78, 77, 54, 76, 88, 19, 137, 20, 224, 20, 14, 203, 81, 32, 78, 77, 50, 76, 88, 19, 137, 20, 224, 20, 10, 199, 65, 35, 196, 84, 49, 78, 80, 20, 12, 201, 44, 241, 70, 24, 144, 201, 20, 229, 0, 20, 12, 201, 29, 85, 133, 72, 225, 77, 20, 229, 0, 20, 10, 199, 60, 97, 137, 12, 144, 78, 80, 20, 10, 199, 36, 226, 149, 72, 144, 78, 80, 20, 0, 12, 201, 8, 80, 82, 8, 82, 132, 20, 196, 197, 67, 11, 200, 12, 21, 1, 48, 243, 137, 20, 224, 20, 0, 14, 139, 16, 18, 195, 166, 22, 5, 14, 20, 9, 15, 14, 20, 8, 197, 64, 20, 140, 21, 32, 20, 8, 197, 17, 80, 140, 21, 32, 20, 8, 197, 88, 148, 197, 57, 64, 20, 8, 197, 72, 81, 197, 57, 64, 20, 8, 197, 4, 48, 197, 57, 64, 20, 0, 13, 202, 61, 97, 82, 61, 33, 5, 57, 67, 9, 28, 20, 9, 198, 32, 244, 208, 36, 49, 64, 20, 9, 198, 4, 36, 197, 56, 49, 64, 20, 9, 198, 52, 17, 18, 36, 112, 76, 20, 9, 198, 44, 243, 12, 4, 113, 64, 20, 11, 70, 52, 84, 211, 4, 113, 64, 21, 0, 10, 0, 0, 11, 200, 52, 19, 149, 24, 18, 212, 85, 32, 20, 11, 200, 5, 34, 201, 80, 82, 212, 85, 32, 20, 11, 200, 4, 66, 149, 16, 19, 148, 85, 32, 20, 9, 198, 65, 35, 214, 37, 51, 210, 20, 11, 200, 72, 17, 9, 44, 19, 9, 77, 64, 20, 11, 200, 64, 243, 25, 28, 19, 73, 77, 64, 20, 11, 200, 64, 19, 70, 48, 85, 9, 77, 64, 20, 11, 200, 28, 83, 133, 72, 19, 9, 77, 64, 20, 11, 200, 21, 96, 78, 28, 83, 9, 77, 64, 20, 11, 200, 76, 81, 9, 52, 83, 148, 21, 32, 20, 11, 200, 65, 35, 214, 36, 19, 148, 21, 32, 20, 9, 198, 44, 195, 210, 4, 210, 78, 20, 9, 198, 76, 144, 201, 48, 144, 78, 20, 11, 200, 16, 81, 133, 57, 51, 210, 5, 64, 20, 11, 200, 12, 128, 77, 64, 147, 206, 5, 64, 20, 11, 200, 44, 243, 77, 4, 225, 1, 57, 64, 20, 0, 14, 69, 40, 19, 15, 85, 128, 89, 57, 110, 6, 55, 40, 0, 8, 197, 76, 243, 9, 77, 64, 20, 8, 197, 52, 241, 9, 77, 64, 20, 8, 197, 8, 21, 9, 77, 64, 20, 12, 201, 88, 83, 148, 36, 193, 82, 36, 225, 192, 20, 12, 201, 88, 16, 195, 36, 225, 82, 36, 225, 192, 20, 12, 201, 84, 68, 207, 73, 65, 82, 36, 225, 192, 20, 12, 201, 81, 33, 80, 4, 225, 82, 36, 225, 192, 20, 12, 201, 81, 32, 78, 12, 129, 82, 36, 225, 192, 20, 12, 201, 80, 244, 144, 20, 65, 82, 36, 225, 192, 20, 12, 201, 80, 83, 80, 21, 33, 82, 36, 225, 192, 20, 12, 201, 80, 19, 80, 60, 225, 82, 36, 225, 192, 20, 12, 201, 80, 16, 133, 48, 193, 82, 36, 225, 192, 20, 12, 201, 77, 147, 139, 61, 1, 82, 36, 225, 192, 20, 12, 201, 72, 85, 1, 72, 65, 82, 36, 225, 192, 20, 12, 201, 72, 82, 214, 37, 33, 82, 36, 225, 192, 20, 12, 201, 72, 81, 149, 56, 65, 82, 36, 225, 192, 20, 12, 201, 72, 21, 9, 60, 225, 82, 36, 225, 192, 20, 12, 201, 72, 19, 80, 60, 225, 82, 36, 225, 192, 20, 12, 201, 72, 17, 134, 36, 225, 82, 36, 225, 192, 20, 12, 201, 65, 35, 205, 61, 97, 82, 36, 225, 192, 20, 12, 201, 65, 35, 202, 36, 49, 82, 36, 225, 192, 20, 12, 201, 65, 35, 198, 4, 225, 82, 36, 225, 192, 20, 12, 201, 64, 83, 12, 21, 65, 82, 36, 225, 192, 20, 12, 201, 64, 19, 12, 21, 65, 82, 36, 225, 192, 20, 12, 201, 52, 245, 73, 48, 193, 82, 36, 225, 192, 20, 12, 201, 52, 245, 9, 60, 225, 82, 36, 225, 192, 20, 12, 201, 52, 243, 5, 77, 65, 82, 36, 225, 192, 20, 12, 201, 52, 241, 5, 48, 193, 82, 36, 225, 192, 20, 12, 201, 52, 20, 135, 36, 225, 82, 36, 225, 192, 20, 12, 201, 48, 146, 214, 36, 65, 82, 36, 225, 192, 20, 12, 201, 45, 85, 133, 73, 65, 82, 36, 225, 192, 20, 12, 201, 44, 243, 150, 60, 161, 82, 36, 225, 192, 20, 12, 201, 44, 243, 148, 85, 33, 82, 36, 225, 192, 20, 12, 201, 44, 243, 80, 60, 225, 82, 36, 225, 192, 20, 12, 201, 44, 243, 80, 36, 193, 82, 36, 225, 192, 20, 12, 201, 44, 243, 77, 5, 65, 82, 36, 225, 192, 20, 12, 201, 44, 242, 203, 21, 33, 82, 36, 225, 192, 20, 12, 201, 44, 19, 142, 20, 193, 82, 36, 225, 192, 20, 12, 201, 36, 229, 143, 49, 97, 82, 36, 225, 192, 20, 12, 201, 36, 229, 133, 77, 65, 82, 36, 225, 192, 20, 12, 201, 36, 229, 133, 73, 65, 82, 36, 225, 192, 20, 12, 201, 32, 20, 144, 84, 225, 82, 36, 225, 192, 20, 12, 201, 29, 32, 86, 37, 65, 82, 36, 225, 192, 20, 12, 201, 29, 32, 84, 36, 225, 82, 36, 225, 192, 20, 12, 201, 29, 32, 78, 84, 193, 82, 36, 225, 192, 20, 12, 201, 28, 19, 15, 65, 1, 82, 36, 225, 192, 20, 12, 201, 25, 37, 83, 81, 33, 82, 36, 225, 192, 20, 12, 201, 24, 244, 198, 5, 65, 82, 36, 225, 192, 20, 12, 201, 24, 244, 141, 84, 193, 82, 36, 225, 192, 20, 12, 201, 24, 244, 141, 5, 65, 82, 36, 225, 192, 20, 12, 201, 24, 18, 212, 85, 33, 82, 36, 225, 192, 20, 12, 201, 21, 128, 197, 73, 1, 82, 36, 225, 192, 20, 12, 201, 21, 96, 80, 61, 33, 82, 36, 225, 192, 20, 12, 201, 21, 50, 207, 73, 65, 82, 36, 225, 192, 20, 12, 201, 20, 208, 129, 48, 193, 82, 36, 225, 192, 20, 12, 201, 20, 180, 208, 20, 65, 82, 36, 225, 192, 20, 12, 201, 20, 180, 197, 45, 97, 82, 36, 225, 192, 20, 12, 201, 16, 85, 5, 45, 65, 82, 36, 225, 192, 20, 12, 201, 16, 85, 1, 48, 161, 82, 36, 225, 192, 20, 12, 201, 16, 84, 201, 28, 225, 82, 36, 225, 192, 20, 12, 201, 16, 84, 18, 5, 97, 82, 36, 225, 192, 20, 12, 201, 16, 83, 79, 57, 65, 82, 36, 225, 192, 20, 12, 201, 16, 82, 193, 57, 65, 82, 36, 225, 192, 20, 12, 201, 16, 81, 210, 4, 65, 82, 36, 225, 192, 20, 12, 201, 16, 81, 140, 61, 33, 82, 36, 225, 192, 20, 12, 201, 16, 19, 65, 76, 49, 82, 36, 225, 192, 20, 12, 201, 12, 83, 147, 85, 33, 82, 36, 225, 192, 20, 12, 201, 12, 83, 69, 57, 65, 82, 36, 225, 192, 20, 12, 201, 5, 69, 18, 5, 1, 82, 36, 225, 192, 20, 12, 201, 5, 69, 1, 12, 129, 82, 36, 225, 192, 20, 12, 201, 5, 52, 207, 73, 65, 82, 36, 225, 192, 20, 12, 201, 5, 4, 15, 73, 65, 82, 36, 225, 192, 20, 12, 201, 4, 227, 149, 48, 193, 82, 36, 225, 192, 20, 12, 201, 4, 227, 133, 45, 65, 82, 36, 225, 192, 20, 12, 201, 4, 197, 5, 72, 225, 82, 36, 225, 192, 20, 12, 201, 4, 181, 9, 60, 225, 82, 36, 225, 192, 20, 12, 201, 4, 113, 210, 20, 113, 82, 36, 225, 192, 20, 12, 201, 4, 68, 207, 72, 33, 82, 36, 225, 192, 20, 12, 201, 4, 48, 197, 65, 65, 82, 36, 225, 192, 20, 12, 201, 4, 36, 207, 49, 97, 82, 36, 225, 192, 20, 8, 197, 80, 245, 80, 21, 32, 20, 8, 197, 80, 83, 132, 21, 32, 20, 8, 197, 44, 16, 200, 21, 32, 20, 8, 197, 25, 83, 132, 21, 32, 20, 8, 197, 21, 35, 196, 21, 32, 20, 12, 201, 72, 84, 18, 21, 52, 193, 48, 145, 64, 20, 8, 197, 77, 83, 6, 37, 64, 20, 8, 197, 56, 149, 18, 37, 64, 20, 12, 201, 88, 81, 197, 80, 20, 137, 76, 209, 64, 20, 12, 201, 76, 82, 213, 48, 20, 137, 76, 209, 64, 20, 12, 201, 52, 147, 9, 80, 20, 137, 76, 209, 64, 20, 12, 201, 52, 85, 1, 8, 243, 9, 76, 209, 64, 20, 12, 201, 44, 243, 139, 72, 85, 9, 76, 209, 64, 20, 12, 201, 8, 243, 19, 40, 85, 137, 76, 209, 64, 20, 12, 201, 4, 36, 207, 49, 85, 9, 76, 209, 64, 20, 12, 201, 44, 243, 139, 85, 36, 133, 56, 49, 64, 20, 8, 197, 77, 2, 78, 5, 64, 20, 8, 197, 33, 145, 18, 5, 64, 20, 8, 197, 29, 32, 78, 5, 64, 20, 8, 197, 12, 149, 18, 5, 64, 20, 8, 197, 88, 18, 193, 57, 64, 20, 10, 69, 13, 84, 147, 61, 32, 21, 0, 10, 0, 16, 141, 22, 9, 4, 5, 2, 5, 7, 195, 166, 18, 12, 9, 7, 20, 9, 198, 76, 241, 137, 76, 209, 64, 20, 9, 198, 76, 86, 9, 76, 209, 64, 20, 9, 198, 53, 85, 9, 76, 209, 64, 20, 9, 198, 52, 243, 137, 76, 209, 64, 20, 9, 198, 16, 19, 137, 76, 209, 64, 20, 9, 198, 72, 83, 79, 56, 49, 64, 20, 9, 198, 45, 83, 1, 56, 49, 64, 20, 9, 198, 77, 1, 67, 36, 19, 0, 20, 9, 198, 9, 35, 206, 44, 144, 76, 20, 9, 198, 64, 192, 77, 4, 113, 64, 20, 0, 6, 195, 4, 210, 68, 20, 13, 138, 19, 11, 195, 166, 12, 1, 7, 20, 9, 7, 20, 0, 11, 200, 53, 84, 203, 84, 192, 84, 85, 32, 20, 10, 135, 14, 5, 18, 22, 195, 184, 19, 20, 11, 200, 81, 35, 205, 64, 85, 9, 77, 64, 20, 11, 200, 40, 245, 82, 56, 19, 9, 77, 64, 20, 15, 204, 81, 32, 78, 77, 50, 210, 36, 33, 82, 36, 225, 192, 20, 15, 204, 77, 80, 147, 80, 19, 148, 37, 97, 82, 36, 225, 192, 20, 15, 204, 72, 148, 201, 44, 245, 149, 72, 65, 82, 36, 225, 192, 20, 15, 204, 64, 84, 147, 64, 82, 212, 37, 97, 82, 36, 225, 192, 20, 15, 204, 64, 84, 134, 20, 181, 9, 60, 225, 82, 36, 225, 192, 20, 15, 204, 44, 243, 134, 20, 181, 9, 60, 225, 82, 36, 225, 192, 20, 15, 204, 36, 225, 18, 20, 114, 83, 81, 33, 82, 36, 225, 192, 20, 11, 200, 36, 225, 13, 5, 32, 200, 21, 32, 20, 12, 201, 8, 85, 78, 17, 33, 82, 36, 225, 5, 20, 7, 196, 9, 85, 9, 44, 20, 18, 70, 84, 225, 21, 48, 21, 0, 114, 50, 72, 40, 55, 6, 110, 47, 0, 20, 11, 200, 8, 20, 130, 37, 69, 82, 5, 64, 20, 9, 198, 52, 19, 132, 5, 64, 82, 20, 11, 200, 24, 192, 71, 20, 195, 1, 57, 64, 20, 0, 7, 195, 85, 52, 210, 17, 42, 11, 136, 7, 5, 14, 5, 18, 195, 184, 19, 20, 10, 135, 7, 18, 1, 22, 195, 184, 18, 20, 9, 198, 44, 243, 12, 20, 114, 69, 20, 12, 201, 77, 147, 139, 72, 243, 137, 76, 209, 64, 20, 12, 201, 72, 85, 129, 56, 50, 9, 76, 209, 64, 20, 12, 201, 56, 20, 131, 37, 52, 201, 76, 209, 64, 20, 12, 201, 48, 84, 194, 36, 19, 137, 76, 209, 64, 20, 12, 201, 37, 51, 205, 61, 33, 137, 76, 209, 64, 20, 12, 201, 4, 224, 75, 72, 243, 137, 76, 209, 64, 20, 12, 201, 4, 194, 207, 32, 243, 9, 76, 209, 64, 20, 8, 197, 21, 35, 212, 36, 176, 20, 8, 197, 17, 84, 12, 36, 176, 20, 0, 18, 7, 23, 3, 39, 5, 18, 14, 5, 84, 6, 36, 89, 36, 114, 50, 13, 0, 9, 198, 4, 224, 76, 60, 114, 64, 20, 9, 198, 4, 195, 5, 72, 114, 64, 20, 9, 198, 36, 211, 79, 73, 65, 76, 20, 9, 198, 36, 211, 79, 73, 65, 76, 20, 9, 198, 4, 176, 68, 20, 210, 64, 20, 9, 198, 44, 19, 77, 21, 32, 84, 20, 9, 198, 28, 83, 137, 80, 19, 0, 20, 9, 198, 24, 197, 86, 36, 19, 0, 20, 9, 198, 5, 51, 195, 36, 19, 0, 20, 11, 70, 52, 18, 15, 56, 86, 64, 21, 0, 10, 0, 10, 199, 44, 243, 150, 21, 37, 5, 72, 20, 10, 199, 24, 147, 147, 61, 37, 5, 72, 20, 6, 195, 36, 67, 204, 20, 10, 199, 64, 243, 9, 80, 146, 197, 72, 20, 10, 199, 44, 84, 129, 52, 146, 197, 72, 20, 10, 199, 32, 243, 73, 48, 85, 9, 44, 20, 10, 199, 16, 144, 76, 20, 181, 9, 44, 20, 10, 199, 76, 195, 214, 20, 226, 69, 56, 20, 10, 199, 12, 20, 212, 36, 194, 69, 56, 20, 10, 199, 16, 243, 73, 56, 146, 193, 56, 20, 10, 199, 12, 243, 15, 52, 34, 65, 56, 20, 0, 14, 139, 9, 14, 20, 18, 1, 22, 5, 14, 195, 184, 19, 20, 11, 200, 80, 84, 141, 36, 227, 204, 60, 112, 20, 11, 200, 77, 64, 84, 36, 243, 133, 72, 80, 20, 11, 200, 5, 82, 212, 36, 243, 133, 72, 80, 20, 11, 200, 104, 147, 206, 37, 53, 9, 76, 176, 20, 11, 200, 104, 147, 66, 4, 37, 201, 76, 176, 20, 11, 200, 52, 18, 197, 16, 243, 137, 76, 176, 20, 11, 200, 44, 20, 213, 37, 53, 9, 76, 176, 20, 11, 200, 37, 51, 212, 21, 35, 73, 76, 176, 20, 11, 200, 4, 194, 207, 32, 243, 9, 76, 176, 20, 11, 200, 5, 81, 9, 80, 244, 137, 84, 208, 20, 11, 200, 81, 32, 75, 20, 245, 15, 52, 144, 20, 11, 200, 24, 147, 8, 5, 35, 79, 56, 144, 20, 11, 200, 52, 244, 134, 36, 226, 83, 52, 80, 20, 11, 200, 52, 20, 207, 12, 130, 83, 52, 80, 20, 15, 204, 20, 180, 208, 72, 84, 211, 36, 243, 137, 76, 209, 64, 20, 7, 196, 48, 241, 201, 44, 20, 9, 198, 36, 228, 197, 72, 21, 0, 20, 0, 10, 135, 16, 15, 18, 20, 195, 184, 18, 20, 12, 201, 72, 85, 77, 5, 67, 204, 60, 114, 64, 20, 12, 201, 52, 85, 5, 61, 35, 204, 60, 114, 64, 20, 12, 201, 4, 195, 5, 72, 115, 204, 60, 114, 64, 20, 9, 198, 76, 240, 201, 60, 227, 205, 20, 8, 197, 4, 224, 84, 60, 208, 20, 9, 198, 53, 144, 197, 48, 149, 77, 20, 8, 197, 64, 241, 84, 36, 176, 20, 8, 197, 56, 21, 84, 36, 176, 20, 12, 201, 17, 32, 77, 5, 69, 82, 28, 144, 84, 20, 0, 11, 136, 10, 15, 14, 7, 12, 195, 184, 18, 20, 15, 140, 5, 14, 20, 18, 5, 16, 18, 5, 14, 195, 184, 18, 20, 9, 198, 80, 83, 204, 60, 114, 64, 20, 9, 198, 72, 83, 204, 60, 114, 64, 20, 9, 198, 8, 147, 204, 60, 114, 64, 20, 16, 141, 16, 1, 12, 195, 166, 15, 7, 18, 1, 6, 9, 19, 11, 20, 13, 202, 64, 84, 137, 64, 21, 5, 80, 146, 197, 72, 20, 9, 198, 64, 20, 129, 56, 242, 68, 20, 14, 139, 16, 18, 195, 166, 20, 5, 18, 9, 20, 21, 13, 20, 9, 198, 77, 80, 147, 81, 32, 84, 20, 9, 198, 64, 20, 212, 61, 32, 84, 20, 0, 7, 195, 92, 131, 192, 17, 42, 13, 138, 7, 12, 1, 14, 4, 21, 12, 195, 184, 19, 20, 10, 199, 32, 16, 137, 48, 149, 5, 72, 20, 10, 199, 64, 245, 16, 61, 84, 146, 36, 20, 14, 203, 81, 32, 78, 76, 21, 12, 4, 229, 9, 76, 176, 20, 14, 203, 72, 85, 137, 76, 147, 206, 37, 53, 9, 76, 176, 20, 14, 203, 61, 4, 15, 73, 69, 78, 37, 53, 9, 76, 176, 20, 14, 203, 45, 33, 65, 80, 147, 206, 37, 53, 9, 76, 176, 20, 14, 203, 36, 195, 21, 76, 147, 206, 37, 53, 9, 76, 176, 20, 14, 203, 44, 194, 84, 61, 34, 68, 20, 181, 15, 52, 144, 20, 10, 199, 21, 81, 1, 36, 211, 206, 36, 20, 14, 203, 52, 16, 200, 36, 21, 133, 48, 194, 83, 52, 80, 20, 14, 203, 44, 244, 146, 21, 52, 15, 56, 64, 78, 12, 80, 20, 0, 9, 198, 76, 181, 76, 65, 69, 82, 20, 13, 138, 18, 1, 16, 16, 15, 18, 20, 195, 184, 18, 20, 13, 138, 11, 15, 12, 16, 15, 18, 20, 195, 184, 18, 20, 15, 70, 64, 20, 148, 61, 85, 0, 48, 112, 47, 6, 40, 0, 20, 9, 198, 24, 21, 86, 37, 53, 0, 20, 11, 200, 88, 84, 147, 36, 243, 133, 72, 80, 20, 9, 198, 61, 34, 69, 57, 65, 82, 20, 11, 200, 64, 20, 129, 76, 149, 9, 76, 176, 20, 11, 200, 52, 18, 193, 72, 243, 137, 76, 176, 20, 11, 200, 33, 145, 18, 5, 83, 9, 76, 176, 20, 11, 200, 21, 33, 207, 56, 243, 73, 76, 176, 20, 11, 200, 20, 208, 146, 100, 243, 137, 76, 176, 20, 11, 200, 8, 192, 83, 24, 83, 73, 76, 176, 20, 11, 200, 5, 64, 86, 37, 53, 9, 76, 176, 20, 11, 200, 4, 226, 77, 37, 53, 9, 76, 176, 20, 7, 196, 72, 145, 201, 16, 20, 11, 200, 80, 84, 129, 64, 85, 84, 36, 176, 20, 0, 12, 201, 5, 52, 217, 72, 147, 204, 60, 114, 64, 20, 0, 9, 198, 77, 147, 80, 80, 243, 64, 20, 13, 202, 29, 81, 19, 40, 19, 77, 21, 35, 9, 28, 20, 17, 206, 4, 224, 82, 44, 244, 217, 56, 66, 75, 4, 194, 83, 52, 80, 20, 9, 198, 76, 149, 21, 21, 33, 84, 20, 0, 29, 75, 77, 21, 65, 72, 81, 1, 56, 49, 82, 56, 80, 89, 49, 58, 6, 36, 13, 72, 35, 12, 50, 89, 114, 20, 50, 13, 0, 9, 198, 65, 54, 75, 60, 195, 199, 20, 10, 199, 5, 85, 15, 72, 149, 5, 80, 20, 14, 203, 36, 66, 79, 77, 147, 139, 72, 21, 9, 76, 176, 20, 14, 203, 32, 148, 212, 61, 34, 67, 37, 53, 9, 76, 176, 20, 14, 203, 8, 82, 1, 88, 147, 210, 37, 53, 9, 76, 176, 20, 10, 199, 20, 180, 203, 88, 148, 201, 80, 20, 10, 199, 44, 19, 143, 56, 146, 193, 80, 20, 10, 199, 4, 69, 133, 72, 34, 65, 48, 20, 0, 9, 198, 64, 144, 78, 37, 53, 0, 20, 9, 198, 44, 243, 131, 37, 1, 82, 20, 9, 198, 16, 148, 208, 85, 65, 82, 20, 9, 198, 12, 83, 69, 57, 65, 82, 20, 9, 198, 4, 211, 133, 77, 65, 82, 20, 7, 196, 48, 246, 65, 48, 20, 11, 200, 16, 148, 203, 72, 84, 1, 57, 48, 20, 0, 25, 73, 9, 33, 65, 44, 64, 78, 12, 83, 128, 71, 34, 109, 37, 81, 6, 72, 35, 12, 50, 89, 14, 50, 0, 12, 201, 44, 20, 9, 48, 192, 82, 37, 65, 84, 20, 12, 201, 52, 146, 210, 60, 225, 83, 36, 83, 128, 20, 12, 201, 65, 35, 211, 80, 149, 21, 21, 33, 84, 20, 0, 13, 202, 64, 245, 5, 57, 66, 65, 48, 149, 5, 80, 20, 9, 198, 64, 20, 212, 61, 32, 76, 20, 0, 8, 133, 9, 19, 195, 166, 18, 20, 10, 199, 32, 16, 137, 48, 149, 5, 80, 20, 10, 199, 88, 17, 5, 52, 80, 213, 52, 20, 10, 199, 76, 227, 194, 8, 148, 205, 20, 20, 10, 199, 64, 244, 21, 48, 148, 205, 20, 20, 10, 199, 56, 146, 9, 48, 148, 205, 20, 20, 10, 199, 37, 51, 1, 52, 148, 205, 20, 20, 10, 199, 8, 245, 21, 48, 148, 205, 20, 20, 10, 199, 21, 128, 197, 48, 193, 78, 76, 20, 0, 9, 68, 48, 241, 201, 56, 21, 0, 10, 0, 9, 198, 56, 85, 82, 4, 193, 201, 20, 8, 197, 56, 21, 9, 60, 224, 20, 12, 201, 56, 21, 9, 60, 224, 76, 37, 65, 84, 20, 8, 197, 44, 244, 142, 20, 192, 20, 8, 197, 44, 244, 142, 20, 192, 20, 8, 197, 44, 243, 147, 60, 192, 20, 16, 69, 64, 244, 12, 36, 224, 48, 114, 48, 55, 6, 109, 68, 0, 20, 8, 197, 52, 244, 140, 36, 192, 20, 12, 201, 76, 241, 137, 77, 66, 75, 21, 33, 84, 20, 9, 198, 72, 84, 212, 4, 224, 197, 20, 0, 15, 140, 16, 195, 166, 4, 1, 7, 15, 7, 9, 19, 5, 18, 20, 12, 137, 15, 18, 11, 14, 195, 184, 9, 19, 11, 20, 13, 202, 29, 83, 77, 36, 20, 129, 8, 144, 213, 52, 20, 13, 202, 64, 243, 25, 12, 83, 148, 72, 148, 205, 20, 20, 0, 10, 199, 72, 81, 146, 4, 181, 15, 72, 20, 12, 137, 20, 5, 13, 16, 15, 18, 195, 166, 18, 20, 10, 199, 77, 80, 147, 36, 66, 69, 72, 20, 10, 199, 65, 35, 196, 84, 49, 82, 20, 20, 10, 199, 64, 20, 143, 16, 145, 82, 20, 20, 10, 199, 64, 20, 134, 84, 209, 82, 20, 20, 13, 138, 195, 184, 11, 21, 13, 5, 14, 9, 19, 11, 20, 10, 199, 28, 227, 211, 80, 146, 197, 72, 20, 10, 199, 9, 32, 83, 36, 194, 65, 56, 20, 10, 199, 72, 84, 5, 48, 193, 78, 80, 20, 10, 199, 64, 84, 141, 4, 225, 78, 80, 20, 12, 201, 36, 212, 5, 73, 66, 78, 20, 229, 0, 20, 10, 199, 21, 128, 197, 48, 193, 78, 80, 20, 0, 14, 68, 64, 128, 82, 52, 83, 112, 12, 34, 65, 19, 0, 25, 13, 138, 11, 22, 1, 20, 5, 18, 14, 195, 166, 18, 20, 9, 134, 7, 5, 22, 195, 166, 18, 20, 11, 200, 81, 32, 78, 76, 149, 9, 60, 224, 20, 11, 200, 64, 84, 134, 20, 181, 9, 60, 224, 20, 11, 200, 44, 243, 150, 20, 181, 9, 60, 224, 20, 11, 200, 44, 243, 135, 21, 53, 9, 60, 224, 20, 11, 200, 44, 243, 134, 20, 181, 9, 60, 224, 20, 11, 200, 44, 21, 137, 80, 21, 9, 60, 224, 20, 11, 200, 37, 36, 137, 80, 21, 9, 60, 224, 20, 11, 200, 36, 226, 213, 8, 21, 9, 60, 224, 20, 11, 200, 36, 226, 1, 48, 21, 9, 60, 224, 20, 11, 200, 29, 32, 68, 84, 21, 9, 60, 224, 20, 11, 200, 28, 83, 73, 56, 21, 9, 60, 224, 20, 11, 200, 20, 210, 71, 72, 21, 9, 60, 224, 20, 11, 200, 16, 149, 137, 56, 21, 9, 60, 224, 20, 11, 200, 16, 81, 9, 44, 21, 9, 60, 224, 20, 11, 200, 5, 52, 9, 72, 21, 9, 60, 224, 20, 14, 139, 16, 18, 195, 166, 19, 5, 14, 20, 9, 19, 11, 20, 7, 196, 64, 193, 84, 36, 20, 9, 198, 76, 243, 22, 20, 229, 0, 20, 9, 198, 20, 210, 78, 20, 229, 0, 20, 11, 200, 61, 35, 129, 52, 83, 148, 4, 192, 20, 11, 200, 60, 48, 201, 16, 83, 148, 4, 192, 20, 11, 200, 52, 243, 149, 52, 83, 148, 4, 192, 20, 9, 198, 5, 4, 12, 36, 176, 66, 20, 0, 24, 73, 9, 33, 65, 44, 64, 78, 12, 84, 128, 71, 34, 109, 37, 81, 6, 72, 35, 12, 50, 89, 114, 0, 8, 197, 52, 245, 9, 60, 224, 20, 8, 197, 4, 181, 9, 60, 224, 20, 15, 140, 6, 15, 18, 18, 195, 166, 4, 5, 18, 9, 19, 11, 20, 8, 197, 56, 81, 210, 36, 64, 20, 8, 197, 45, 33, 84, 36, 224, 20, 8, 197, 64, 244, 148, 4, 192, 20, 0, 11, 136, 19, 15, 12, 9, 20, 195, 166, 18, 20, 11, 136, 13, 9, 12, 9, 20, 195, 166, 18, 20, 12, 137, 20, 18, 15, 11, 195, 166, 9, 19, 11, 20, 16, 141, 16, 25, 20, 8, 1, 7, 15, 18, 195, 166, 9, 19, 11, 20, 12, 137, 5, 12, 25, 19, 195, 166, 9, 19, 11, 20, 13, 202, 44, 244, 146, 21, 52, 15, 56, 65, 78, 80, 20, 9, 198, 76, 243, 22, 20, 228, 192, 20, 0, 12, 137, 16, 5, 11, 21, 14, 9, 195, 166, 18, 20, 14, 203, 77, 66, 71, 52, 21, 9, 76, 21, 9, 60, 224, 20, 14, 203, 53, 83, 20, 37, 3, 9, 44, 21, 9, 60, 224, 20, 14, 203, 36, 211, 79, 8, 147, 9, 76, 21, 9, 60, 224, 20, 14, 203, 28, 83, 133, 72, 19, 9, 76, 21, 9, 60, 224, 20, 14, 203, 16, 148, 203, 72, 147, 73, 56, 21, 9, 60, 224, 20, 14, 203, 5, 4, 18, 60, 180, 201, 52, 21, 9, 60, 224, 20, 10, 199, 88, 83, 148, 36, 193, 82, 20, 20, 10, 199, 81, 34, 85, 52, 97, 82, 20, 20, 10, 199, 52, 20, 135, 36, 225, 82, 20, 20, 10, 199, 44, 243, 147, 84, 193, 82, 20, 20, 10, 199, 16, 148, 211, 60, 50, 69, 72, 20, 10, 199, 16, 84, 18, 20, 50, 69, 72, 20, 13, 138, 6, 1, 18, 9, 19, 195, 166, 9, 19, 11, 20, 13, 138, 4, 9, 195, 166, 20, 5, 20, 9, 19, 11, 20, 10, 199, 40, 19, 137, 81, 50, 1, 72, 20, 0, 25, 73, 9, 33, 65, 44, 64, 78, 12, 84, 133, 71, 34, 109, 37, 81, 6, 72, 35, 12, 50, 89, 114, 108, 0, 11, 200, 88, 145, 9, 52, 21, 9, 60, 224, 20, 11, 200, 65, 35, 202, 20, 181, 9, 60, 224, 20, 11, 200, 56, 243, 73, 56, 21, 9, 60, 224, 20, 11, 200, 45, 83, 85, 48, 21, 9, 60, 224, 20, 11, 200, 44, 243, 139, 72, 85, 9, 60, 224, 20, 11, 200, 28, 83, 133, 72, 21, 9, 60, 224, 20, 11, 200, 24, 16, 149, 48, 21, 9, 60, 224, 20, 11, 200, 16, 84, 137, 88, 21, 9, 60, 224, 20, 11, 200, 4, 36, 207, 49, 85, 9, 60, 224, 20, 0, 8, 197, 17, 80, 140, 21, 64, 20, 15, 140, 8, 15, 13, 195, 184, 15, 16, 1, 20, 9, 19, 11, 20, 8, 197, 28, 195, 211, 5, 32, 20, 0, 14, 139, 195, 166, 7, 25, 16, 20, 15, 12, 15, 7, 9, 20, 12, 137, 8, 195, 184, 10, 13, 15, 4, 9, 7, 20, 9, 198, 53, 144, 197, 48, 145, 64, 20, 9, 198, 57, 81, 9, 76, 209, 64, 20, 9, 198, 88, 84, 148, 36, 176, 76, 20, 9, 198, 52, 20, 211, 4, 113, 64, 20, 9, 198, 44, 244, 147, 4, 113, 64, 20, 9, 198, 25, 84, 212, 4, 113, 64, 20, 9, 198, 12, 243, 12, 4, 113, 64, 20, 11, 70, 76, 50, 69, 56, 49, 64, 21, 0, 10, 0, 14, 203, 81, 32, 78, 77, 50, 210, 37, 5, 9, 60, 224, 20, 14, 203, 56, 85, 84, 72, 19, 9, 76, 21, 9, 60, 224, 20, 14, 203, 56, 21, 21, 72, 19, 9, 76, 21, 9, 60, 224, 20, 14, 203, 20, 180, 208, 72, 244, 18, 36, 21, 9, 60, 224, 20, 14, 203, 16, 81, 137, 9, 34, 76, 48, 21, 9, 60, 224, 20, 13, 138, 22, 9, 12, 11, 195, 165, 18, 12, 9, 7, 20, 0, 11, 200, 81, 35, 205, 8, 243, 137, 77, 64, 20, 11, 200, 64, 244, 201, 80, 149, 137, 77, 64, 20, 11, 200, 56, 81, 193, 80, 149, 137, 77, 64, 20, 11, 200, 12, 128, 85, 88, 147, 137, 77, 64, 20, 11, 200, 20, 180, 208, 5, 68, 137, 21, 32, 20, 11, 200, 16, 148, 133, 45, 67, 210, 5, 64, 20, 11, 200, 52, 147, 137, 77, 68, 129, 57, 64, 20, 11, 200, 24, 195, 210, 37, 52, 193, 57, 64, 20, 0, 24, 69, 88, 19, 132, 21, 64, 84, 110, 50, 13, 86, 15, 89, 47, 6, 36, 0, 81, 115, 116, 101, 103, 32, 8, 197, 5, 37, 9, 77, 64, 20, 8, 197, 4, 229, 18, 37, 64, 20, 12, 201, 65, 84, 137, 80, 19, 137, 76, 209, 64, 20, 12, 201, 64, 244, 201, 80, 149, 137, 76, 209, 64, 20, 12, 201, 56, 81, 193, 80, 149, 137, 76, 209, 64, 20, 12, 201, 32, 81, 197, 52, 243, 137, 76, 209, 64, 20, 12, 201, 12, 83, 148, 72, 19, 9, 76, 209, 64, 20, 8, 197, 12, 83, 69, 57, 64, 20, 8, 197, 9, 82, 203, 5, 32, 20, 12, 201, 16, 82, 207, 48, 193, 84, 4, 113, 64, 20, 0, 10, 135, 18, 195, 184, 7, 5, 18, 9, 20, 12, 137, 1, 14, 4, 195, 166, 7, 20, 9, 7, 20, 12, 137, 1, 12, 13, 195, 166, 7, 20, 9, 7, 20, 9, 198, 81, 37, 73, 76, 209, 64, 20, 9, 198, 5, 85, 9, 76, 209, 64, 20, 9, 198, 80, 82, 211, 80, 147, 0, 20, 6, 195, 64, 241, 77, 20, 9, 198, 76, 84, 150, 36, 49, 64, 20, 9, 198, 72, 243, 65, 56, 49, 64, 20, 9, 198, 8, 192, 77, 4, 113, 64, 20, 0, 14, 203, 88, 149, 137, 76, 82, 212, 36, 243, 137, 77, 64, 20, 13, 138, 22, 9, 12, 4, 18, 195, 165, 4, 9, 7, 20, 13, 138, 6, 15, 18, 4, 195, 166, 7, 20, 9, 7, 20, 10, 199, 16, 84, 5, 56, 65, 78, 76, 20, 0, 27, 68, 32, 21, 84, 20, 2, 39, 12, 47, 49, 40, 6, 47, 116, 12, 34, 0, 81, 99, 111, 117, 116, 117, 114, 101, 32, 11, 200, 44, 20, 130, 85, 32, 84, 61, 32, 20, 11, 200, 36, 228, 208, 37, 32, 84, 61, 32, 20, 15, 140, 195, 166, 11, 22, 9, 12, 9, 2, 18, 9, 19, 20, 20, 11, 200, 72, 83, 1, 80, 149, 137, 77, 64, 20, 11, 200, 72, 80, 201, 16, 149, 137, 77, 64, 20, 11, 200, 77, 80, 147, 80, 149, 21, 21, 32, 20, 11, 200, 65, 35, 211, 80, 149, 21, 21, 32, 20, 11, 200, 44, 243, 147, 80, 149, 21, 21, 32, 20, 14, 139, 19, 20, 15, 18, 13, 195, 166, 7, 20, 9, 7, 20, 14, 139, 15, 22, 5, 18, 13, 195, 166, 7, 20, 9, 7, 20, 14, 139, 13, 9, 19, 20, 18, 195, 184, 19, 20, 9, 7, 20, 9, 198, 21, 53, 9, 52, 21, 0, 20, 9, 68, 56, 145, 200, 80, 21, 0, 10, 0, 8, 197, 61, 51, 79, 76, 80, 20, 8, 197, 52, 147, 79, 76, 80, 20, 8, 197, 45, 80, 133, 72, 80, 20, 8, 197, 28, 17, 197, 72, 80, 20, 11, 136, 195, 166, 7, 195, 166, 9, 19, 11, 20, 8, 197, 44, 147, 133, 76, 80, 20, 12, 201, 77, 3, 206, 80, 19, 137, 76, 209, 64, 20, 12, 201, 76, 83, 73, 56, 20, 137, 76, 209, 64, 20, 12, 201, 52, 243, 133, 80, 20, 137, 76, 209, 64, 20, 12, 201, 20, 180, 212, 72, 83, 73, 76, 209, 64, 20, 12, 201, 12, 83, 148, 72, 148, 5, 80, 19, 0, 20, 8, 197, 72, 21, 129, 28, 80, 20, 0, 14, 139, 6, 25, 18, 22, 195, 166, 18, 11, 5, 18, 9, 20, 12, 137, 195, 166, 19, 20, 5, 20, 9, 19, 11, 20, 13, 202, 44, 244, 146, 21, 52, 15, 56, 65, 78, 76, 20, 9, 198, 64, 20, 139, 60, 208, 84, 20, 9, 198, 36, 195, 15, 100, 19, 0, 20, 0, 14, 139, 6, 195, 184, 4, 5, 18, 1, 12, 9, 19, 20, 20, 14, 203, 20, 180, 200, 36, 34, 84, 36, 243, 137, 77, 64, 20, 10, 199, 44, 243, 132, 60, 209, 82, 36, 20, 13, 138, 16, 25, 18, 5, 14, 195, 166, 9, 19, 11, 20, 10, 199, 52, 82, 193, 56, 146, 197, 72, 20, 10, 199, 4, 225, 18, 60, 118, 78, 36, 20, 10, 199, 5, 32, 71, 60, 226, 69, 56, 20, 10, 199, 56, 85, 82, 85, 4, 9, 56, 20, 10, 199, 12, 20, 212, 36, 194, 65, 56, 20, 0, 11, 200, 76, 180, 143, 25, 83, 15, 76, 80, 20, 9, 198, 88, 145, 5, 60, 99, 206, 20, 11, 200, 84, 68, 193, 56, 84, 137, 56, 112, 20, 11, 200, 80, 16, 149, 48, 84, 137, 56, 112, 20, 11, 200, 72, 84, 213, 52, 84, 137, 56, 112, 20, 11, 200, 64, 195, 205, 8, 84, 137, 56, 112, 20, 11, 200, 52, 243, 137, 80, 84, 137, 56, 112, 20, 11, 200, 45, 38, 80, 80, 84, 137, 56, 112, 20, 11, 200, 36, 226, 1, 48, 84, 137, 56, 112, 20, 11, 200, 28, 83, 73, 56, 84, 137, 56, 112, 20, 11, 200, 24, 242, 213, 76, 84, 137, 56, 112, 20, 11, 200, 9, 35, 206, 104, 84, 137, 56, 112, 20, 11, 200, 4, 67, 208, 80, 84, 137, 56, 112, 20, 11, 200, 60, 209, 210, 85, 4, 5, 72, 80, 20, 14, 139, 19, 1, 4, 4, 21, 11, 195, 166, 9, 19, 11, 20, 11, 200, 44, 18, 207, 24, 243, 137, 76, 176, 20, 14, 139, 5, 16, 9, 11, 21, 18, 195, 166, 9, 19, 11, 20, 11, 200, 16, 21, 1, 48, 241, 201, 76, 176, 20, 15, 204, 64, 20, 140, 4, 209, 78, 80, 20, 137, 76, 209, 64, 20, 9, 198, 76, 144, 201, 48, 145, 78, 20, 0, 8, 197, 52, 149, 15, 76, 80, 20, 12, 201, 80, 242, 211, 36, 179, 204, 60, 114, 64, 20, 9, 198, 21, 33, 207, 56, 243, 73, 20, 9, 198, 8, 192, 83, 24, 83, 73, 20, 0, 9, 198, 44, 148, 149, 72, 114, 64, 20, 17, 142, 16, 18, 195, 166, 12, 9, 13, 9, 14, 1, 18, 9, 19, 20, 20, 12, 137, 8, 195, 166, 18, 5, 20, 9, 19, 11, 20, 13, 202, 44, 20, 129, 45, 65, 82, 37, 53, 9, 44, 20, 0, 14, 203, 81, 32, 78, 76, 210, 84, 80, 84, 137, 56, 112, 20, 14, 203, 53, 149, 15, 48, 241, 201, 76, 84, 137, 56, 112, 20, 14, 203, 32, 243, 79, 28, 83, 137, 76, 84, 137, 56, 112, 20, 14, 203, 16, 148, 203, 72, 147, 73, 56, 84, 137, 56, 112, 20, 14, 203, 8, 20, 212, 5, 33, 9, 76, 84, 137, 56, 112, 20, 10, 199, 20, 115, 195, 20, 229, 18, 36, 20, 13, 138, 7, 1, 12, 9, 12, 195, 166, 9, 19, 11, 20, 18, 207, 17, 32, 77, 4, 67, 203, 84, 209, 78, 80, 20, 137, 76, 209, 64, 20, 10, 199, 77, 34, 76, 4, 226, 193, 56, 20, 12, 201, 80, 82, 211, 81, 84, 133, 72, 85, 0, 20, 0, 7, 196, 52, 20, 213, 80, 20, 16, 141, 16, 1, 12, 195, 166, 15, 14, 20, 15, 12, 15, 7, 9, 20, 11, 200, 48, 20, 153, 56, 115, 204, 60, 112, 20, 9, 198, 48, 149, 146, 37, 53, 0, 20, 11, 200, 64, 20, 129, 16, 84, 137, 56, 112, 20, 11, 200, 64, 19, 133, 48, 84, 137, 56, 112, 20, 11, 200, 45, 83, 85, 48, 84, 137, 56, 112, 20, 11, 200, 44, 20, 137, 44, 84, 137, 56, 112, 20, 11, 200, 24, 16, 149, 48, 84, 137, 56, 112, 20, 11, 200, 16, 243, 73, 56, 84, 137, 56, 112, 20, 11, 200, 16, 80, 137, 80, 84, 137, 56, 112, 20, 11, 200, 9, 35, 195, 32, 84, 137, 56, 112, 20, 9, 198, 88, 243, 20, 36, 113, 82, 20, 9, 198, 65, 80, 140, 36, 49, 82, 20, 11, 200, 64, 21, 18, 84, 194, 133, 72, 80, 20, 9, 198, 16, 149, 133, 72, 113, 82, 20, 9, 198, 16, 83, 65, 72, 177, 82, 20, 9, 198, 5, 4, 12, 36, 49, 82, 20, 11, 200, 5, 3, 203, 73, 145, 137, 76, 176, 20, 11, 200, 64, 21, 15, 28, 83, 133, 76, 80, 20, 11, 200, 25, 147, 15, 28, 83, 133, 76, 80, 20, 12, 137, 19, 195, 166, 12, 1, 18, 9, 21, 13, 20, 11, 200, 25, 148, 201, 60, 115, 143, 52, 144, 20, 9, 134, 18, 21, 13, 195, 166, 14, 20, 11, 200, 16, 81, 133, 45, 68, 137, 12, 80, 20, 11, 200, 12, 19, 79, 84, 99, 1, 28, 80, 20, 0, 6, 20, 0, 0, 0, 252, 0, 0, 0, 121, 0, 0, 0, 246, 0, 0, 0, 248, 0, 0, 0, 228, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 6, 18, 66, 99, 107, 0, 110, 107, 0, 110, 103, 0, 107, 0, 103, 0, 113, 0, 106, 0, 7, 6, 18, 67, 112, 0, 98, 0, 102, 0, 118, 0, 109, 0, 7, 6, 18, 68, 108, 0, 100, 0, 7, 6, 18, 69, 195, 184, 0, 117, 0, 121, 0, 105, 0, 111, 0, 7, 6, 18, 70, 195, 166, 0, 195, 165, 0, 97, 0, 7, 6, 18, 71, 112, 0, 98, 0, 7, 6, 18, 72, 116, 0, 107, 0, 118, 0, 7, 6, 18, 73, 115, 112, 0, 115, 116, 0, 115, 107, 0, 7, 6, 18, 74, 109, 0, 110, 0, 7, 6, 18, 75, 99, 0, 107, 0, 7, 6, 18, 76, 97, 0, 101, 0, 7, 6, 97, 102, 0, 1, 114, 103, 10, 2, 28, 33, 3, 6, 112, 83, 0, 4, 8, 112, 3, 35, 83, 0, 102, 1, 107, 2, 101, 0, 102, 1, 108, 2, 101, 0, 102, 1, 116, 2, 101, 0, 102, 1, 116, 115, 2, 101, 3, 110, 83, 0, 1, 114, 103, 10, 2, 105, 28, 33, 3, 112, 83, 6, 0, 7, 6, 97, 103, 0, 1, 108, 114, 111, 102, 3, 2, 110, 57, 0, 1, 98, 108, 105, 116, 2, 101, 3, 6, 110, 12, 0, 101, 1, 10, 2, 28, 33, 12, 12, 12, 3, 6, 110, 12, 91, 13, 0, 101, 1, 10, 2, 114, 28, 33, 12, 12, 3, 6, 110, 12, 91, 114, 0, 4, 110, 1, 115, 97, 108, 2, 101, 3, 6, 110, 50, 57, 0, 110, 1, 116, 101, 114, 98, 2, 101, 0, 101, 1, 114, 10, 2, 28, 33, 12, 12, 3, 6, 112, 12, 91, 13, 0, 1, 116, 2, 108, 105, 97, 116, 101, 108, 108, 101, 3, 21, 105, 116, 0, 4, 1, 102, 2, 21, 3, 35, 40, 0, 1, 108, 2, 17, 67, 0, 1, 108, 102, 2, 114, 101, 0, 1, 108, 115, 2, 17, 67, 21, 0, 1, 108, 115, 2, 115, 118, 195, 166, 114, 100, 0, 103, 1, 108, 115, 2, 101, 3, 35, 49, 0, 1, 116, 2, 17, 67, 3, 35, 58, 0, 4, 1, 17, 67, 2, 116, 12, 3, 35, 81, 0, 1, 102, 2, 116, 101, 114, 0, 1, 106, 2, 116, 0, 1, 106, 2, 117, 97, 114, 0, 1, 108, 115, 2, 116, 101, 12, 0, 1, 108, 115, 2, 116, 110, 12, 0, 1, 118, 115, 100, 101, 104, 114, 101, 107, 107, 105, 115, 2, 116, 0, 1, 118, 115, 101, 114, 166, 195, 2, 116, 0, 1, 118, 115, 103, 110, 105, 114, 101, 107, 114, 97, 112, 2, 116, 0, 1, 118, 115, 107, 105, 116, 117, 98, 2, 116, 0, 1, 118, 115, 108, 97, 116, 105, 112, 115, 111, 104, 2, 116, 0, 2, 116, 105, 103, 0, 8, 108, 115, 2, 115, 32, 0, 8, 108, 115, 2, 115, 101, 110, 0, 104, 1, 108, 108, 97, 103, 3, 108, 81, 0, 8, 98, 2, 101, 108, 12, 3, 109, 57, 81, 0, 4, 1, 100, 21, 2, 32, 12, 12, 3, 110, 0, 1, 100, 115, 2, 12, 0, 1, 116, 2, 102, 97, 116, 0, 4, 1, 98, 2, 102, 114, 3, 110, 4, 0, 1, 98, 2, 105, 0, 1, 98, 2, 112, 195, 165, 0, 1, 98, 2, 116, 105, 108, 0, 1, 116, 2, 115, 101, 108, 118, 3, 110, 6, 0, 4, 1, 98, 2, 111, 118, 101, 114, 3, 110, 9, 0, 1, 98, 2, 117, 100, 0, 1, 98, 2, 118, 101, 100, 0, 4, 1, 106, 2, 101, 12, 3, 110, 12, 0, 100, 1, 115, 2, 101, 12, 0, 100, 1, 108, 2, 101, 3, 110, 12, 57, 0, 101, 1, 17, 67, 2, 12, 3, 110, 12, 57, 13, 0, 101, 114, 1, 17, 67, 2, 12, 3, 110, 12, 57, 114, 0, 4, 101, 1, 100, 110, 97, 98, 3, 110, 12, 91, 13, 0, 101, 1, 103, 2, 32, 12, 0, 101, 1, 112, 2, 12, 12, 0, 101, 1, 115, 115, 97, 109, 101, 116, 114, 101, 106, 104, 0, 101, 1, 116, 117, 102, 102, 97, 0, 101, 1, 103, 97, 98, 3, 110, 12, 91, 108, 0, 110, 1, 116, 115, 97, 107, 2, 101, 116, 3, 110, 50, 57, 6, 0, 4, 1, 17, 67, 115, 2, 12, 3, 110, 57, 0, 1, 98, 2, 101, 102, 116, 101, 114, 0, 1, 98, 2, 101, 114, 105, 12, 0, 1, 98, 101, 109, 109, 101, 106, 104, 2, 32, 0, 1, 100, 2, 32, 0, 1, 100, 2, 101, 12, 0, 1, 100, 2, 115, 32, 0, 1, 108, 2, 32, 0, 1, 108, 2, 110, 0, 1, 108, 2, 114, 101, 0, 1, 108, 2, 114, 101, 12, 0, 1, 108, 112, 0, 1, 108, 115, 2, 110, 101, 0, 1, 108, 115, 2, 110, 105, 12, 0, 1, 108, 115, 109, 101, 110, 110, 101, 103, 2, 12, 0, 1, 108, 115, 112, 111, 0, 1, 115, 110, 97, 114, 2, 110, 0, 1, 116, 2, 32, 0, 1, 116, 2, 110, 101, 0, 1, 118, 115, 2, 116, 0, 1, 118, 115, 101, 110, 118, 101, 0, 1, 118, 115, 115, 100, 110, 165, 195, 0, 2, 110, 105, 110, 103, 0, 8, 18, 71, 2, 32, 0, 8, 106, 2, 32, 0, 8, 115, 2, 116, 101, 32, 0, 4, 101, 1, 108, 115, 115, 108, 101, 115, 100, 166, 195, 114, 2, 110, 3, 110, 57, 13, 0, 101, 1, 116, 2, 108, 115, 101, 0, 101, 1, 116, 101, 98, 0, 101, 1, 116, 101, 114, 97, 118, 0, 101, 1, 116, 101, 114, 111, 102, 0, 101, 8, 2, 32, 3, 110, 57, 108, 0, 4, 101, 110, 100, 1, 98, 2, 101, 32, 104, 101, 100, 3, 110, 57, 108, 50, 0, 101, 110, 100, 1, 98, 2, 101, 32, 115, 111, 108, 0, 101, 110, 100, 1, 98, 2, 101, 32, 118, 97, 114, 109, 0, 4, 101, 2, 114, 110, 3, 110, 57, 114, 0, 101, 114, 1, 116, 116, 103, 97, 105, 2, 32, 0, 101, 114, 2, 104, 195, 184, 110, 0, 101, 114, 8, 2, 32, 0, 110, 97, 110, 1, 116, 114, 97, 3, 110, 68, 112, 68, 0, 4, 1, 100, 2, 111, 103, 12, 3, 110, 81, 0, 1, 108, 112, 2, 105, 0, 1, 112, 115, 2, 97, 116, 0, 103, 1, 116, 2, 101, 0, 4, 1, 112, 115, 2, 101, 116, 116, 3, 110, 81, 6, 0, 104, 1, 112, 115, 2, 101, 116, 116, 0, 101, 1, 116, 117, 109, 2, 110, 3, 110, 81, 6, 36, 0, 101, 116, 101, 115, 1, 116, 3, 110, 81, 6, 36, 47, 108, 89, 0, 101, 8, 2, 110, 116, 12, 12, 3, 110, 81, 6, 109, 0, 101, 2, 110, 116, 12, 12, 3, 110, 81, 109, 0, 101, 114, 1, 103, 2, 101, 12, 3, 110, 91, 6, 36, 0, 101, 1, 10, 2, 114, 101, 28, 33, 12, 3, 110, 91, 6, 36, 13, 0, 4, 101, 1, 110, 111, 3, 110, 91, 13, 0, 101, 1, 115, 115, 97, 0, 101, 1, 116, 110, 97, 108, 112, 0, 101, 1, 116, 101, 3, 110, 91, 108, 0, 101, 114, 1, 116, 101, 3, 110, 91, 114, 0, 4, 101, 114, 1, 116, 101, 114, 111, 102, 3, 112, 34, 0, 101, 114, 8, 116, 2, 32, 0, 4, 1, 98, 2, 17, 65, 110, 3, 112, 40, 0, 1, 98, 2, 18, 66, 0, 1, 98, 2, 98, 0, 1, 98, 2, 100, 0, 1, 98, 2, 102, 0, 1, 98, 2, 104, 12, 0, 1, 98, 2, 107, 0, 1, 98, 2, 108, 0, 1, 98, 2, 109, 0, 1, 98, 2, 112, 0, 1, 98, 2, 114, 117, 100, 0, 1, 98, 2, 115, 0, 1, 98, 2, 116, 21, 0, 1, 98, 2, 117, 100, 103, 97, 110, 103, 0, 1, 98, 2, 118, 0, 1, 100, 2, 105, 110, 115, 116, 105, 0, 1, 100, 2, 108, 21, 12, 0, 1, 108, 115, 2, 115, 105, 100, 101, 0, 1, 108, 115, 2, 115, 109, 195, 165, 108, 0, 1, 108, 115, 2, 116, 105, 108, 102, 0, 1, 108, 115, 101, 2, 108, 17, 65, 0, 1, 112, 115, 2, 110, 117, 109, 0, 1, 114, 2, 101, 12, 0, 1, 115, 2, 110, 0, 1, 115, 2, 115, 195, 184, 0, 110, 1, 116, 115, 3, 112, 40, 68, 0, 101, 110, 100, 1, 98, 2, 101, 3, 112, 40, 109, 50, 0, 101, 114, 1, 108, 102, 2, 109, 117, 115, 3, 112, 40, 114, 0, 1, 107, 115, 2, 108, 101, 114, 3, 112, 58, 0, 101, 1, 114, 2, 12, 12, 3, 112, 58, 13, 0, 101, 114, 1, 114, 2, 12, 12, 3, 112, 58, 114, 0, 1, 98, 2, 116, 101, 3, 112, 81, 0, 101, 100, 105, 101, 1, 114, 116, 3, 112, 81, 6, 36, 86, 57, 13, 0, 101, 1, 114, 102, 102, 117, 115, 2, 116, 116, 101, 3, 112, 91, 6, 109, 0, 7, 6, 97, 108, 0, 4, 8, 98, 97, 107, 2, 101, 3, 6, 110, 12, 55, 0, 8, 98, 109, 105, 116, 2, 101, 0, 8, 100, 110, 97, 107, 115, 2, 101, 0, 8, 103, 101, 114, 2, 101, 0, 8, 104, 114, 111, 102, 2, 101, 0, 8, 105, 114, 101, 116, 97, 109, 2, 101, 0, 8, 105, 116, 97, 114, 103, 2, 101, 0, 8, 105, 116, 110, 101, 116, 111, 112, 2, 101, 0, 8, 107, 111, 108, 2, 101, 0, 8, 109, 114, 111, 102, 2, 101, 0, 8, 110, 105, 102, 2, 101, 0, 8, 110, 110, 101, 105, 98, 0, 8, 110, 110, 101, 105, 114, 116, 2, 101, 0, 8, 115, 115, 105, 109, 2, 101, 0, 8, 116, 114, 111, 102, 2, 101, 0, 8, 116, 114, 111, 109, 111, 116, 108, 97, 115, 2, 101, 0, 8, 117, 100, 97, 114, 103, 2, 101, 0, 8, 117, 110, 97, 109, 2, 101, 0, 4, 101, 8, 105, 99, 101, 112, 115, 2, 32, 3, 6, 110, 12, 55, 13, 0, 101, 8, 105, 116, 110, 101, 114, 101, 102, 102, 105, 100, 0, 4, 1, 100, 101, 112, 115, 2, 115, 107, 3, 6, 110, 55, 0, 1, 117, 115, 107, 101, 115, 0, 4, 8, 114, 101, 109, 117, 110, 2, 101, 3, 6, 112, 12, 55, 0, 8, 114, 111, 109, 2, 101, 0, 8, 114, 111, 116, 115, 97, 112, 2, 101, 0, 4, 8, 110, 105, 114, 117, 3, 7, 110, 12, 55, 0, 8, 110, 111, 105, 116, 97, 114, 2, 101, 0, 8, 110, 111, 115, 114, 101, 112, 2, 101, 0, 7, 6, 98, 101, 0, 97, 117, 8, 3, 2, 71, 39, 0, 8, 2, 21, 3, 71, 2, 36, 0, 8, 2, 106, 108, 101, 3, 71, 35, 0, 4, 103, 8, 2, 98, 108, 101, 110, 100, 101, 3, 71, 35, 57, 0, 103, 8, 2, 109, 97, 110, 100, 0, 103, 8, 2, 110, 105, 110, 103, 0, 4, 8, 2, 100, 100, 105, 110, 103, 3, 71, 36, 0, 8, 2, 100, 101, 0, 8, 2, 101, 116, 97, 32, 0, 8, 2, 110, 97, 114, 98, 101, 106, 100, 101, 0, 8, 2, 110, 98, 98, 117, 107, 0, 8, 2, 110, 98, 114, 117, 100, 0, 8, 2, 110, 101, 100, 100, 101, 114, 0, 8, 2, 110, 101, 116, 0, 8, 2, 110, 102, 101, 100, 116, 0, 8, 2, 110, 102, 105, 115, 107, 0, 8, 2, 110, 102, 114, 105, 0, 8, 2, 110, 107, 108, 0, 8, 2, 110, 109, 101, 108, 0, 8, 2, 110, 109, 101, 108, 0, 8, 2, 110, 112, 105, 98, 101, 0, 8, 2, 110, 112, 108, 97, 100, 115, 0, 8, 2, 110, 114, 97, 100, 0, 8, 2, 110, 115, 107, 105, 110, 110, 101, 0, 8, 2, 110, 115, 112, 195, 166, 110, 100, 0, 8, 2, 110, 116, 195, 184, 106, 0, 8, 2, 116, 97, 115, 116, 114, 195, 165, 108, 0, 8, 2, 116, 97, 116, 114, 111, 110, 0, 8, 2, 116, 97, 118, 101, 114, 115, 105, 111, 110, 0, 8, 2, 116, 101, 108, 0, 8, 2, 116, 108, 0, 101, 116, 104, 111, 118, 101, 110, 3, 71, 36, 47, 39, 84, 108, 50, 0, 101, 99, 104, 8, 3, 71, 37, 76, 0, 4, 8, 2, 100, 114, 101, 3, 71, 109, 0, 8, 2, 100, 114, 105, 110, 103, 0, 8, 2, 100, 115, 116, 101, 0, 8, 2, 103, 103, 101, 0, 8, 2, 106, 100, 115, 0, 8, 2, 108, 103, 105, 0, 8, 2, 108, 108, 97, 0, 8, 2, 110, 98, 114, 195, 166, 107, 0, 8, 2, 110, 99, 104, 109, 97, 114, 107, 0, 8, 2, 110, 101, 110, 100, 101, 0, 8, 2, 110, 103, 101, 108, 0, 8, 2, 110, 103, 110, 97, 0, 8, 2, 110, 104, 0, 8, 2, 110, 106, 97, 109, 105, 110, 0, 8, 2, 110, 108, 0, 8, 2, 110, 118, 0, 8, 2, 114, 98, 0, 8, 2, 114, 103, 101, 110, 32, 0, 105, 103, 101, 8, 3, 71, 109, 12, 91, 0, 114, 107, 101, 108, 101, 121, 3, 71, 118, 49, 59, 37, 0, 7, 6, 101, 100, 0, 4, 1, 112, 105, 99, 111, 108, 101, 118, 2, 101, 3, 6, 36, 86, 0, 1, 116, 115, 102, 97, 2, 107, 111, 109, 0, 1, 114, 100, 110, 117, 104, 2, 12, 3, 13, 12, 86, 0, 101, 1, 107, 121, 115, 112, 2, 108, 105, 115, 107, 3, 13, 72, 6, 36, 0, 1, 118, 111, 104, 3, 13, 86, 0, 101, 1, 21, 2, 32, 3, 13, 86, 13, 0, 4, 1, 110, 114, 101, 100, 2, 101, 3, 36, 86, 0, 1, 110, 114, 101, 104, 2, 101, 0, 4, 101, 1, 98, 108, 105, 116, 3, 36, 86, 13, 0, 101, 1, 98, 109, 101, 2, 32, 12, 0, 101, 1, 98, 109, 101, 2, 116, 32, 12, 0, 101, 1, 102, 2, 12, 12, 0, 101, 1, 104, 2, 12, 0, 101, 1, 107, 10, 2, 12, 0, 101, 1, 108, 100, 108, 105, 118, 2, 12, 0, 101, 1, 108, 100, 110, 105, 2, 12, 0, 101, 1, 108, 100, 117, 2, 12, 0, 101, 1, 108, 102, 97, 2, 12, 0, 101, 1, 108, 106, 101, 118, 2, 12, 0, 101, 1, 108, 110, 101, 104, 2, 12, 0, 101, 1, 108, 112, 111, 2, 12, 0, 101, 1, 108, 114, 111, 102, 2, 12, 0, 101, 1, 108, 115, 105, 109, 2, 12, 0, 101, 1, 108, 115, 118, 105, 108, 2, 12, 0, 101, 1, 108, 116, 101, 114, 2, 12, 0, 101, 1, 108, 116, 114, 111, 98, 2, 12, 0, 101, 1, 109, 115, 3, 36, 86, 108, 0, 4, 101, 114, 1, 98, 108, 105, 116, 3, 36, 86, 114, 0, 101, 114, 1, 102, 2, 32, 12, 0, 101, 114, 1, 104, 2, 12, 0, 101, 114, 1, 108, 100, 108, 105, 118, 2, 12, 0, 101, 114, 1, 108, 100, 110, 105, 2, 12, 0, 101, 114, 1, 108, 100, 117, 2, 12, 0, 101, 114, 1, 108, 102, 97, 2, 12, 0, 101, 114, 1, 108, 106, 101, 118, 2, 12, 0, 101, 114, 1, 108, 110, 101, 104, 2, 12, 0, 101, 114, 1, 108, 112, 111, 2, 12, 0, 101, 114, 1, 108, 114, 111, 102, 2, 12, 0, 101, 114, 1, 108, 115, 105, 109, 2, 12, 0, 101, 114, 1, 108, 115, 118, 105, 108, 2, 12, 0, 101, 114, 1, 108, 116, 101, 114, 2, 12, 0, 101, 114, 1, 108, 116, 114, 111, 98, 2, 12, 0, 101, 1, 114, 10, 2, 32, 3, 108, 86, 13, 0, 4, 101, 1, 108, 116, 114, 111, 98, 3, 109, 86, 13, 0, 101, 1, 114, 98, 108, 101, 104, 0, 101, 1, 114, 100, 108, 105, 118, 2, 32, 12, 0, 101, 1, 114, 101, 98, 2, 32, 12, 0, 101, 1, 114, 101, 108, 2, 32, 12, 0, 101, 1, 114, 101, 110, 114, 184, 195, 0, 101, 1, 114, 101, 115, 112, 101, 118, 104, 2, 32, 12, 0, 101, 1, 114, 101, 116, 116, 111, 114, 2, 32, 12, 0, 101, 1, 114, 112, 115, 2, 32, 12, 0, 101, 1, 114, 114, 101, 2, 12, 0, 101, 1, 114, 115, 118, 111, 107, 115, 108, 101, 0, 101, 1, 114, 118, 2, 32, 12, 0, 101, 8, 114, 98, 2, 32, 12, 0, 101, 8, 114, 102, 2, 32, 12, 0, 7, 6, 101, 108, 0, 4, 1, 98, 101, 114, 3, 6, 36, 55, 0, 1, 98, 111, 108, 2, 105, 97, 0, 1, 100, 97, 116, 105, 99, 0, 1, 100, 105, 102, 0, 1, 100, 110, 111, 114, 0, 1, 100, 114, 166, 195, 115, 2, 101, 115, 0, 1, 101, 114, 0, 1, 105, 98, 114, 101, 118, 0, 1, 108, 108, 97, 104, 2, 117, 106, 97, 0, 1, 109, 97, 107, 0, 1, 109, 109, 97, 114, 103, 111, 114, 112, 0, 1, 112, 111, 114, 112, 0, 1, 115, 100, 110, 117, 2, 105, 103, 0, 1, 115, 114, 101, 118, 105, 110, 117, 0, 1, 116, 110, 97, 114, 97, 116, 0, 1, 116, 114, 111, 112, 115, 0, 1, 117, 2, 32, 12, 0, 1, 117, 122, 101, 110, 101, 118, 2, 97, 0, 1, 118, 97, 106, 0, 1, 118, 117, 106, 0, 1, 118, 165, 195, 115, 0, 8, 98, 97, 116, 0, 8, 105, 99, 105, 102, 102, 111, 2, 12, 0, 8, 110, 97, 112, 0, 8, 112, 108, 97, 107, 115, 0, 105, 103, 1, 115, 10, 2, 28, 33, 3, 6, 36, 55, 37, 0, 4, 1, 99, 114, 97, 109, 3, 6, 109, 55, 0, 1, 99, 114, 97, 112, 0, 1, 100, 97, 116, 114, 111, 109, 0, 1, 100, 101, 112, 2, 12, 0, 1, 100, 114, 97, 115, 0, 1, 105, 114, 101, 116, 97, 109, 0, 1, 108, 108, 97, 114, 97, 112, 0, 1, 109, 114, 111, 102, 2, 108, 0, 1, 109, 114, 111, 102, 2, 116, 0, 1, 112, 97, 107, 0, 1, 114, 111, 102, 2, 115, 0, 1, 116, 110, 101, 109, 97, 107, 105, 100, 101, 109, 0, 1, 116, 111, 109, 0, 1, 116, 115, 97, 112, 0, 1, 118, 114, 97, 102, 0, 1, 118, 117, 110, 0, 8, 100, 97, 107, 105, 114, 102, 2, 108, 0, 103, 1, 104, 101, 108, 108, 97, 2, 101, 110, 115, 3, 6, 109, 55, 57, 0, 4, 8, 114, 107, 97, 109, 2, 12, 3, 6, 111, 55, 0, 8, 114, 111, 102, 0, 1, 117, 2, 116, 32, 12, 12, 3, 7, 36, 55, 0, 1, 10, 2, 108, 28, 33, 12, 12, 12, 3, 7, 109, 0, 4, 1, 10, 2, 28, 33, 12, 12, 12, 3, 7, 109, 55, 0, 1, 10, 2, 116, 28, 33, 0, 1, 116, 97, 107, 115, 117, 109, 0, 1, 114, 10, 2, 108, 28, 33, 12, 12, 12, 3, 7, 111, 0, 1, 114, 10, 2, 28, 33, 12, 12, 3, 7, 111, 55, 0, 105, 103, 1, 10, 2, 28, 33, 3, 8, 13, 55, 37, 0, 1, 117, 107, 115, 109, 101, 110, 110, 101, 103, 2, 105, 103, 3, 8, 36, 55, 0, 4, 1, 21, 2, 17, 65, 114, 3, 13, 55, 0, 1, 21, 2, 32, 0, 1, 21, 2, 115, 0, 1, 21, 2, 116, 32, 0, 1, 98, 97, 116, 107, 101, 112, 115, 101, 114, 0, 1, 100, 101, 107, 2, 12, 0, 1, 100, 101, 108, 2, 115, 101, 0, 1, 100, 110, 97, 2, 115, 101, 0, 1, 100, 110, 97, 104, 0, 1, 105, 110, 97, 112, 115, 0, 1, 107, 115, 111, 108, 102, 0, 1, 107, 115, 114, 0, 8, 114, 111, 102, 2, 105, 103, 0, 101, 116, 1, 10, 2, 28, 33, 3, 13, 55, 6, 109, 47, 0, 101, 103, 1, 108, 117, 106, 3, 13, 55, 35, 57, 0, 4, 1, 10, 2, 101, 118, 3, 36, 55, 0, 1, 21, 2, 195, 184, 115, 0, 1, 98, 97, 116, 0, 1, 100, 2, 101, 12, 0, 1, 100, 2, 105, 110, 103, 0, 1, 100, 2, 116, 12, 0, 1, 100, 100, 101, 109, 0, 1, 100, 100, 110, 97, 116, 115, 101, 98, 0, 1, 100, 100, 110, 117, 114, 0, 1, 100, 101, 2, 12, 0, 1, 100, 101, 100, 0, 1, 100, 101, 107, 107, 105, 116, 115, 0, 1, 100, 101, 118, 114, 101, 115, 101, 114, 0, 1, 100, 103, 97, 98, 0, 1, 100, 107, 184, 195, 114, 98, 0, 1, 100, 110, 97, 0, 1, 100, 110, 101, 106, 101, 0, 1, 100, 110, 101, 118, 111, 0, 1, 100, 110, 111, 0, 1, 100, 111, 109, 0, 1, 100, 114, 101, 100, 101, 110, 0, 1, 100, 114, 111, 102, 0, 1, 100, 115, 109, 101, 103, 101, 108, 0, 1, 100, 115, 110, 101, 100, 114, 101, 118, 0, 1, 100, 115, 184, 195, 108, 0, 1, 100, 116, 110, 101, 99, 111, 114, 112, 0, 1, 100, 118, 108, 97, 104, 0, 1, 100, 121, 98, 0, 1, 103, 110, 97, 118, 101, 0, 1, 104, 2, 116, 12, 0, 1, 105, 110, 97, 100, 0, 1, 107, 115, 101, 115, 110, 166, 195, 114, 103, 0, 1, 107, 115, 107, 114, 97, 109, 0, 1, 107, 115, 114, 111, 0, 1, 109, 2, 111, 110, 0, 1, 109, 101, 100, 101, 118, 104, 0, 1, 109, 101, 116, 103, 105, 115, 0, 1, 109, 103, 117, 114, 0, 1, 109, 110, 101, 98, 0, 1, 109, 111, 103, 97, 115, 0, 1, 109, 114, 111, 102, 117, 0, 1, 109, 115, 105, 114, 0, 1, 110, 97, 112, 0, 1, 110, 114, 111, 107, 2, 101, 118, 97, 116, 111, 114, 0, 1, 114, 2, 97, 116, 0, 1, 115, 2, 101, 32, 0, 1, 115, 2, 101, 114, 32, 0, 1, 115, 2, 101, 114, 115, 32, 0, 1, 116, 2, 101, 0, 1, 116, 2, 101, 102, 0, 1, 116, 2, 116, 32, 0, 1, 116, 110, 0, 1, 116, 115, 101, 108, 108, 105, 114, 98, 0, 1, 116, 115, 101, 115, 105, 112, 115, 0, 1, 116, 115, 101, 116, 110, 97, 118, 114, 101, 115, 0, 1, 116, 115, 114, 101, 100, 110, 117, 2, 12, 0, 1, 116, 115, 115, 103, 110, 105, 100, 110, 97, 108, 0, 1, 117, 116, 107, 101, 108, 108, 101, 116, 110, 105, 0, 2, 105, 107, 115, 105, 114, 0, 2, 115, 107, 12, 0, 8, 116, 115, 2, 32, 0, 101, 114, 1, 100, 2, 12, 3, 36, 55, 114, 0, 4, 1, 97, 104, 99, 105, 3, 55, 0, 1, 97, 107, 105, 0, 1, 100, 100, 101, 115, 0, 4, 1, 100, 110, 105, 118, 107, 2, 17, 65, 3, 108, 55, 0, 8, 114, 111, 102, 2, 195, 166, 103, 0, 101, 1, 100, 110, 105, 98, 2, 100, 3, 108, 55, 36, 0, 4, 1, 98, 97, 115, 105, 3, 109, 55, 0, 1, 100, 97, 107, 105, 114, 102, 2, 108, 0, 1, 102, 21, 2, 116, 0, 1, 104, 2, 105, 107, 111, 112, 116, 0, 1, 104, 2, 115, 116, 0, 1, 105, 116, 0, 1, 107, 115, 2, 32, 0, 1, 110, 105, 109, 105, 114, 107, 0, 1, 110, 111, 105, 116, 97, 114, 0, 1, 110, 111, 115, 114, 101, 112, 0, 1, 112, 10, 2, 115, 32, 0, 1, 115, 2, 115, 0, 1, 116, 111, 104, 21, 0, 1, 118, 0, 8, 0, 8, 112, 112, 97, 2, 115, 105, 110, 0, 8, 117, 109, 97, 115, 0, 108, 8, 0, 108, 105, 111, 116, 3, 109, 55, 57, 114, 47, 0, 1, 114, 21, 2, 32, 12, 3, 111, 55, 0, 1, 114, 100, 2, 12, 3, 114, 55, 0, 7, 6, 101, 110, 0, 4, 1, 99, 166, 195, 109, 3, 6, 36, 50, 0, 1, 109, 111, 110, 166, 195, 102, 0, 1, 114, 121, 115, 2, 101, 110, 32, 0, 1, 114, 121, 115, 2, 101, 114, 32, 0, 1, 116, 115, 105, 115, 107, 101, 2, 115, 0, 8, 100, 97, 2, 32, 0, 8, 100, 105, 115, 101, 114, 2, 115, 0, 8, 100, 105, 115, 166, 195, 114, 112, 2, 116, 0, 8, 103, 97, 2, 116, 0, 8, 108, 121, 116, 101, 99, 97, 0, 8, 109, 101, 103, 0, 8, 109, 114, 111, 102, 2, 101, 0, 8, 114, 121, 115, 32, 110, 101, 0, 116, 1, 10, 2, 28, 33, 12, 12, 3, 6, 36, 50, 47, 0, 115, 1, 21, 2, 28, 33, 12, 3, 6, 36, 50, 89, 0, 4, 1, 112, 112, 97, 2, 100, 105, 107, 115, 3, 6, 109, 50, 0, 1, 114, 102, 111, 122, 105, 107, 115, 0, 8, 108, 111, 112, 2, 116, 97, 0, 8, 117, 108, 102, 110, 105, 2, 122, 97, 0, 100, 1, 108, 105, 116, 2, 101, 98, 114, 0, 110, 8, 105, 115, 114, 101, 112, 0, 4, 99, 101, 1, 108, 108, 101, 99, 120, 101, 2, 28, 33, 3, 6, 109, 50, 89, 13, 0, 99, 101, 1, 110, 105, 109, 101, 2, 28, 33, 0, 100, 101, 114, 8, 108, 97, 107, 3, 6, 109, 50, 114, 0, 115, 1, 114, 21, 2, 28, 33, 12, 3, 6, 111, 50, 89, 0, 8, 118, 101, 114, 2, 99, 104, 101, 3, 6, 112, 50, 0, 4, 116, 1, 99, 99, 10, 2, 28, 33, 12, 3, 6, 112, 68, 0, 116, 1, 115, 101, 10, 2, 28, 33, 12, 0, 115, 101, 114, 1, 10, 2, 28, 33, 3, 7, 109, 50, 89, 114, 0, 116, 1, 114, 10, 2, 28, 33, 12, 3, 7, 111, 50, 47, 0, 99, 101, 1, 10, 2, 28, 33, 3, 7, 112, 68, 89, 13, 0, 99, 101, 1, 10, 2, 114, 28, 33, 3, 7, 112, 68, 89, 114, 0, 4, 1, 10, 2, 32, 24, 3, 13, 50, 0, 1, 98, 97, 116, 115, 2, 12, 0, 1, 98, 98, 2, 32, 12, 12, 0, 1, 98, 98, 105, 114, 103, 2, 101, 12, 0, 1, 98, 109, 111, 98, 2, 12, 0, 1, 98, 165, 195, 118, 2, 12, 12, 0, 1, 100, 105, 115, 0, 1, 100, 114, 111, 0, 1, 102, 102, 97, 107, 115, 116, 101, 114, 0, 1, 114, 101, 105, 10, 2, 32, 24, 0, 1, 116, 2, 195, 165, 0, 1, 116, 102, 97, 0, 8, 98, 165, 195, 2, 32, 12, 0, 8, 98, 165, 195, 2, 116, 32, 12, 0, 1, 98, 97, 107, 115, 2, 12, 3, 14, 50, 0, 115, 1, 10, 2, 32, 12, 3, 14, 50, 89, 0, 100, 101, 114, 1, 114, 10, 2, 32, 3, 35, 50, 114, 0, 4, 1, 98, 10, 2, 32, 12, 3, 36, 50, 0, 1, 98, 98, 105, 114, 2, 12, 12, 0, 1, 98, 110, 101, 102, 108, 101, 2, 12, 0, 1, 100, 105, 115, 101, 114, 2, 115, 0, 1, 100, 105, 115, 166, 195, 114, 112, 2, 116, 0, 1, 103, 2, 115, 107, 0, 1, 103, 2, 115, 116, 0, 1, 103, 10, 2, 107, 101, 110, 100, 0, 1, 103, 10, 2, 115, 116, 0, 1, 103, 97, 2, 116, 0, 1, 112, 115, 117, 115, 2, 115, 105, 111, 110, 0, 1, 114, 115, 100, 108, 121, 107, 115, 0, 1, 116, 115, 2, 17, 65, 0, 1, 116, 115, 97, 116, 117, 97, 98, 0, 1, 116, 115, 100, 110, 97, 115, 0, 1, 116, 115, 100, 110, 97, 116, 0, 1, 116, 115, 100, 110, 117, 114, 103, 0, 1, 116, 115, 101, 98, 105, 108, 115, 0, 1, 116, 115, 101, 100, 108, 97, 103, 0, 1, 116, 115, 101, 100, 110, 101, 114, 0, 1, 116, 115, 101, 100, 110, 105, 109, 0, 1, 116, 115, 101, 100, 166, 195, 114, 116, 0, 1, 116, 115, 101, 103, 103, 121, 98, 0, 1, 116, 115, 101, 106, 184, 195, 0, 1, 116, 115, 101, 107, 107, 111, 114, 0, 1, 116, 115, 101, 107, 107, 121, 109, 115, 0, 1, 116, 115, 101, 107, 110, 105, 104, 0, 1, 116, 115, 101, 107, 110, 117, 109, 0, 1, 116, 115, 101, 107, 115, 101, 118, 115, 0, 1, 116, 115, 101, 108, 103, 110, 97, 114, 0, 1, 116, 115, 101, 108, 108, 117, 114, 0, 1, 116, 115, 101, 108, 108, 184, 195, 109, 0, 1, 116, 115, 101, 110, 114, 184, 195, 106, 104, 0, 1, 116, 115, 101, 110, 117, 114, 0, 1, 116, 115, 101, 110, 165, 195, 109, 0, 1, 116, 115, 101, 112, 109, 97, 107, 0, 1, 116, 115, 101, 112, 112, 97, 114, 116, 0, 1, 116, 115, 101, 114, 121, 110, 0, 1, 116, 115, 101, 116, 110, 105, 108, 102, 0, 1, 116, 115, 101, 118, 184, 195, 114, 112, 0, 1, 116, 115, 102, 117, 116, 0, 1, 116, 115, 103, 97, 116, 0, 1, 116, 115, 103, 110, 117, 116, 0, 1, 116, 115, 107, 108, 97, 107, 0, 1, 116, 115, 107, 166, 195, 100, 0, 1, 116, 115, 108, 101, 100, 101, 107, 0, 1, 116, 115, 108, 101, 100, 166, 195, 0, 1, 116, 115, 108, 101, 100, 166, 195, 0, 1, 116, 115, 108, 103, 101, 116, 0, 1, 116, 115, 108, 111, 104, 0, 1, 116, 115, 109, 105, 108, 0, 1, 116, 115, 110, 105, 104, 114, 0, 1, 116, 115, 110, 105, 118, 0, 1, 116, 115, 110, 114, 166, 195, 118, 107, 0, 1, 116, 115, 111, 114, 98, 0, 1, 116, 115, 112, 109, 105, 112, 0, 1, 116, 115, 112, 121, 114, 100, 0, 1, 116, 115, 114, 101, 100, 97, 118, 107, 0, 1, 116, 115, 114, 101, 108, 111, 109, 0, 1, 116, 115, 114, 111, 101, 116, 101, 109, 0, 1, 116, 115, 114, 111, 107, 115, 0, 1, 116, 115, 114, 111, 109, 114, 97, 109, 0, 1, 116, 115, 114, 117, 109, 0, 1, 116, 115, 116, 100, 101, 102, 0, 1, 116, 115, 116, 110, 97, 107, 0, 1, 116, 115, 116, 110, 105, 108, 102, 0, 1, 116, 115, 116, 117, 108, 115, 0, 1, 116, 115, 116, 117, 109, 115, 0, 1, 116, 115, 118, 97, 114, 103, 0, 1, 116, 115, 165, 195, 109, 115, 0, 1, 116, 115, 165, 195, 109, 115, 0, 1, 116, 115, 165, 195, 114, 103, 0, 1, 118, 2, 115, 107, 12, 0, 1, 118, 115, 21, 2, 32, 0, 8, 114, 117, 2, 32, 0, 110, 1, 103, 10, 2, 101, 109, 0, 116, 1, 118, 101, 2, 17, 65, 12, 3, 36, 50, 47, 0, 4, 116, 1, 10, 2, 97, 108, 115, 107, 28, 33, 12, 3, 36, 50, 47, 6, 0, 116, 1, 10, 2, 117, 114, 28, 33, 12, 0, 115, 1, 118, 107, 3, 36, 50, 89, 0, 116, 105, 1, 118, 2, 111, 110, 3, 36, 50, 91, 57, 0, 115, 101, 1, 103, 10, 2, 28, 33, 3, 81, 7, 109, 50, 89, 114, 0, 1, 114, 121, 115, 2, 101, 100, 115, 195, 166, 116, 116, 101, 110, 100, 101, 3, 108, 50, 0, 4, 1, 106, 116, 2, 115, 116, 3, 109, 50, 0, 1, 109, 2, 115, 12, 0, 1, 112, 101, 100, 0, 1, 112, 101, 108, 103, 117, 107, 0, 1, 112, 116, 108, 105, 102, 0, 1, 114, 103, 101, 105, 108, 111, 0, 1, 114, 103, 115, 116, 114, 111, 112, 115, 0, 1, 118, 101, 114, 121, 100, 0, 1, 118, 101, 115, 115, 184, 195, 98, 0, 100, 101, 114, 1, 116, 114, 97, 98, 3, 109, 50, 72, 114, 0, 4, 115, 101, 114, 1, 10, 2, 101, 28, 33, 3, 109, 50, 89, 6, 36, 34, 0, 115, 101, 114, 1, 112, 10, 2, 32, 28, 33, 0, 100, 101, 114, 1, 10, 2, 32, 3, 109, 50, 114, 0, 110, 1, 105, 99, 110, 97, 3, 109, 68, 0, 1, 114, 115, 98, 184, 195, 108, 102, 97, 2, 115, 3, 111, 50, 0, 1, 118, 101, 114, 2, 99, 104, 101, 3, 112, 50, 0, 4, 1, 115, 2, 115, 105, 98, 3, 112, 68, 0, 2, 32, 103, 114, 111, 115, 0, 2, 100, 111, 115, 0, 2, 116, 117, 115, 105, 97, 115, 0, 116, 1, 99, 99, 97, 2, 12, 0, 103, 114, 111, 115, 3, 112, 68, 81, 34, 6, 39, 0, 115, 1, 114, 10, 2, 32, 3, 114, 20, 50, 89, 0, 1, 114, 10, 2, 32, 24, 3, 114, 50, 0, 7, 6, 101, 114, 0, 105, 110, 103, 1, 17, 67, 21, 2, 12, 12, 3, 4, 36, 34, 36, 68, 0, 1, 105, 118, 97, 120, 3, 6, 36, 0, 4, 1, 99, 105, 102, 102, 111, 3, 6, 36, 34, 0, 1, 107, 114, 97, 112, 2, 32, 98, 105, 108, 0, 1, 108, 101, 118, 117, 106, 2, 101, 110, 0, 1, 109, 97, 2, 105, 107, 97, 32, 0, 1, 110, 97, 109, 2, 32, 0, 1, 115, 115, 97, 112, 2, 32, 103, 97, 100, 101, 110, 0, 1, 115, 115, 97, 112, 2, 115, 101, 100, 0, 1, 116, 101, 102, 97, 99, 2, 105, 0, 1, 116, 114, 111, 109, 0, 1, 116, 115, 21, 2, 105, 101, 0, 1, 116, 116, 97, 108, 102, 2, 101, 110, 100, 101, 0, 1, 118, 104, 110, 101, 0, 8, 98, 114, 97, 98, 2, 12, 0, 8, 102, 105, 114, 101, 112, 0, 8, 105, 118, 105, 114, 2, 97, 0, 8, 108, 97, 118, 97, 107, 0, 8, 108, 108, 97, 102, 2, 12, 0, 8, 110, 105, 102, 0, 8, 115, 115, 97, 107, 2, 101, 114, 0, 8, 116, 107, 97, 114, 97, 107, 0, 8, 116, 111, 110, 2, 32, 100, 101, 110, 0, 8, 116, 111, 110, 2, 32, 100, 101, 116, 0, 8, 116, 114, 97, 118, 107, 0, 8, 116, 115, 121, 109, 2, 105, 117, 0, 8, 118, 97, 108, 107, 2, 12, 12, 0, 105, 1, 116, 115, 2, 115, 107, 28, 33, 3, 6, 36, 34, 37, 0, 4, 116, 1, 107, 114, 111, 102, 3, 6, 36, 34, 47, 0, 116, 1, 109, 114, 111, 102, 101, 114, 0, 116, 1, 110, 101, 103, 0, 116, 1, 110, 105, 0, 116, 1, 110, 114, 111, 98, 0, 116, 1, 115, 97, 108, 98, 0, 116, 1, 116, 107, 101, 102, 102, 97, 0, 116, 1, 117, 110, 105, 116, 110, 111, 107, 0, 116, 1, 117, 110, 105, 116, 110, 111, 107, 115, 105, 100, 0, 116, 1, 118, 114, 101, 115, 101, 114, 0, 110, 101, 8, 116, 117, 97, 115, 2, 12, 3, 6, 36, 34, 50, 0, 4, 110, 101, 8, 99, 117, 108, 2, 12, 3, 6, 36, 34, 50, 13, 0, 110, 101, 8, 100, 111, 109, 2, 12, 12, 0, 110, 101, 8, 115, 97, 107, 2, 12, 0, 110, 101, 8, 116, 115, 105, 99, 2, 12, 0, 110, 101, 8, 118, 97, 116, 2, 12, 0, 110, 101, 114, 8, 115, 97, 107, 2, 12, 3, 6, 36, 34, 50, 114, 0, 101, 8, 103, 97, 101, 114, 2, 32, 3, 6, 36, 34, 108, 0, 4, 101, 114, 8, 110, 97, 109, 3, 6, 36, 114, 0, 101, 114, 8, 110, 97, 109, 0, 4, 1, 98, 108, 97, 2, 116, 17, 65, 3, 6, 109, 34, 0, 1, 102, 110, 105, 2, 110, 111, 0, 1, 116, 110, 105, 2, 110, 32, 12, 12, 0, 1, 116, 111, 115, 105, 2, 109, 0, 1, 118, 114, 101, 112, 2, 115, 12, 0, 8, 108, 108, 97, 116, 2, 107, 0, 8, 115, 110, 111, 107, 2, 118, 97, 116, 105, 118, 0, 8, 115, 110, 111, 107, 2, 118, 101, 115, 0, 8, 115, 166, 195, 114, 112, 2, 118, 97, 116, 105, 118, 0, 8, 116, 110, 105, 2, 110, 32, 12, 12, 0, 8, 116, 110, 105, 2, 110, 101, 32, 12, 12, 0, 8, 118, 105, 110, 117, 2, 115, 12, 0, 8, 118, 111, 114, 116, 110, 111, 107, 2, 115, 0, 4, 116, 1, 99, 110, 111, 107, 3, 6, 109, 34, 47, 0, 116, 1, 112, 115, 107, 101, 0, 116, 1, 115, 115, 101, 100, 0, 116, 1, 118, 104, 116, 101, 0, 116, 1, 118, 111, 114, 116, 110, 105, 0, 116, 1, 118, 117, 107, 2, 12, 12, 0, 110, 101, 8, 116, 110, 97, 108, 2, 12, 3, 6, 109, 34, 50, 13, 0, 1, 116, 108, 97, 2, 110, 97, 116, 105, 118, 3, 6, 109, 51, 0, 4, 101, 1, 21, 2, 32, 28, 33, 12, 12, 3, 7, 36, 12, 114, 0, 101, 1, 21, 2, 100, 101, 28, 33, 12, 12, 0, 101, 1, 21, 2, 114, 28, 33, 12, 12, 0, 101, 1, 21, 2, 114, 101, 28, 33, 12, 12, 12, 0, 101, 1, 21, 2, 114, 101, 110, 28, 33, 12, 12, 0, 101, 1, 21, 2, 115, 32, 28, 33, 12, 12, 0, 101, 1, 21, 2, 116, 28, 33, 12, 12, 0, 101, 1, 105, 21, 2, 110, 32, 28, 33, 12, 12, 0, 4, 1, 21, 2, 28, 33, 12, 12, 12, 3, 7, 36, 34, 0, 1, 21, 2, 32, 28, 33, 12, 12, 0, 1, 21, 2, 101, 32, 28, 33, 12, 12, 12, 0, 1, 21, 2, 101, 116, 28, 33, 12, 12, 12, 12, 0, 105, 110, 103, 1, 10, 2, 28, 33, 12, 12, 3, 7, 36, 34, 36, 68, 0, 101, 116, 1, 10, 2, 28, 33, 12, 12, 3, 7, 36, 34, 108, 86, 0, 101, 114, 1, 108, 101, 118, 117, 106, 3, 7, 36, 114, 0, 1, 100, 110, 97, 120, 101, 108, 97, 3, 8, 72, 114, 0, 4, 1, 107, 105, 10, 2, 32, 28, 33, 12, 12, 3, 8, 114, 0, 1, 107, 105, 10, 2, 115, 32, 28, 33, 12, 12, 0, 105, 1, 21, 2, 115, 107, 28, 33, 3, 8, 114, 34, 37, 0, 4, 1, 102, 110, 10, 2, 101, 114, 21, 3, 13, 34, 0, 1, 118, 101, 108, 2, 101, 103, 12, 0, 101, 100, 101, 8, 108, 108, 97, 2, 32, 3, 13, 34, 36, 86, 13, 0, 101, 116, 1, 116, 108, 97, 3, 13, 34, 108, 86, 0, 101, 110, 1, 102, 110, 10, 2, 99, 3, 13, 34, 112, 68, 0, 1, 116, 2, 114, 97, 115, 115, 3, 35, 0, 4, 1, 99, 2, 101, 12, 3, 36, 34, 0, 1, 100, 2, 102, 114, 97, 0, 1, 100, 114, 117, 2, 101, 116, 0, 1, 102, 97, 114, 103, 111, 116, 111, 102, 110, 101, 103, 2, 101, 0, 1, 102, 105, 114, 101, 112, 0, 1, 103, 2, 97, 110, 105, 0, 1, 103, 2, 101, 12, 0, 1, 103, 2, 109, 97, 110, 115, 0, 1, 103, 115, 121, 110, 2, 114, 105, 0, 1, 106, 102, 2, 32, 0, 1, 107, 114, 111, 102, 2, 116, 12, 0, 1, 108, 98, 2, 101, 0, 1, 108, 108, 97, 2, 103, 0, 1, 109, 109, 111, 107, 2, 99, 105, 101, 108, 0, 1, 110, 105, 102, 0, 1, 112, 101, 116, 114, 111, 115, 0, 1, 112, 103, 105, 116, 103, 105, 118, 0, 1, 116, 2, 97, 12, 0, 1, 116, 105, 99, 21, 2, 101, 0, 1, 116, 107, 97, 114, 97, 107, 0, 1, 116, 114, 97, 118, 107, 0, 1, 116, 115, 2, 101, 111, 0, 1, 116, 115, 2, 105, 0, 1, 116, 115, 2, 108, 105, 110, 103, 0, 1, 116, 115, 117, 104, 2, 105, 0, 1, 118, 2, 101, 116, 0, 1, 118, 2, 114, 32, 0, 1, 118, 97, 108, 107, 2, 12, 12, 0, 1, 118, 97, 114, 103, 21, 2, 101, 0, 1, 118, 104, 2, 12, 0, 8, 2, 103, 111, 0, 8, 103, 2, 116, 97, 12, 0, 8, 104, 2, 32, 0, 8, 107, 115, 2, 32, 0, 8, 108, 2, 32, 12, 12, 0, 8, 110, 115, 2, 32, 0, 8, 115, 2, 32, 0, 8, 115, 114, 101, 118, 111, 0, 8, 116, 2, 32, 0, 8, 2, 17, 67, 3, 36, 34, 6, 0, 110, 101, 1, 116, 117, 97, 115, 2, 12, 3, 36, 34, 50, 0, 4, 110, 101, 1, 99, 117, 108, 2, 12, 3, 36, 34, 50, 13, 0, 110, 101, 1, 100, 111, 109, 2, 12, 12, 0, 110, 101, 1, 115, 97, 107, 2, 12, 0, 110, 101, 1, 116, 115, 105, 99, 2, 12, 0, 110, 101, 1, 118, 97, 116, 2, 12, 0, 4, 101, 1, 100, 114, 117, 118, 2, 32, 3, 36, 34, 108, 0, 101, 1, 103, 97, 101, 114, 2, 32, 0, 101, 1, 109, 109, 117, 115, 112, 111, 0, 101, 1, 114, 101, 112, 111, 0, 101, 1, 114, 116, 2, 12, 0, 101, 1, 115, 105, 116, 97, 109, 97, 114, 100, 21, 0, 101, 1, 116, 97, 108, 101, 114, 0, 101, 1, 116, 117, 107, 115, 105, 100, 0, 101, 116, 1, 116, 110, 101, 105, 114, 111, 3, 36, 34, 108, 86, 0, 4, 101, 1, 115, 97, 98, 3, 36, 114, 0, 101, 114, 1, 110, 97, 109, 0, 4, 1, 100, 110, 117, 104, 3, 108, 34, 0, 1, 109, 109, 17, 65, 2, 97, 0, 1, 116, 114, 111, 112, 101, 114, 2, 101, 12, 0, 1, 116, 114, 111, 112, 101, 114, 2, 101, 110, 12, 0, 1, 118, 121, 108, 102, 2, 117, 116, 101, 0, 101, 1, 21, 2, 114, 101, 28, 33, 12, 12, 3, 108, 34, 6, 36, 0, 4, 105, 1, 107, 115, 97, 118, 2, 28, 33, 3, 108, 34, 7, 37, 0, 105, 1, 116, 110, 97, 102, 110, 105, 2, 28, 33, 0, 1, 112, 115, 101, 100, 2, 97, 116, 3, 108, 51, 0, 4, 101, 1, 21, 2, 32, 3, 108, 114, 0, 101, 1, 100, 105, 118, 0, 101, 1, 114, 2, 32, 0, 1, 116, 2, 114, 3, 109, 0, 4, 1, 102, 2, 110, 105, 3, 109, 34, 0, 1, 103, 2, 100, 97, 0, 1, 103, 2, 110, 12, 12, 0, 1, 103, 2, 114, 105, 103, 0, 1, 104, 2, 108, 105, 12, 0, 1, 104, 101, 98, 2, 115, 107, 0, 1, 106, 2, 103, 0, 1, 106, 2, 110, 12, 12, 12, 12, 12, 0, 1, 110, 2, 118, 0, 1, 115, 2, 116, 12, 0, 1, 115, 2, 118, 12, 0, 1, 116, 2, 109, 105, 110, 0, 1, 116, 2, 109, 111, 0, 1, 116, 2, 110, 105, 12, 0, 1, 116, 2, 112, 0, 1, 116, 2, 114, 105, 101, 114, 0, 1, 116, 115, 2, 111, 108, 0, 1, 118, 2, 17, 67, 12, 12, 12, 0, 1, 118, 105, 110, 117, 0, 1, 118, 115, 2, 105, 103, 101, 0, 2, 102, 97, 114, 105, 0, 8, 18, 71, 2, 32, 0, 8, 103, 2, 110, 101, 32, 12, 0, 8, 110, 101, 103, 2, 116, 0, 114, 1, 103, 114, 166, 195, 0, 110, 1, 100, 111, 109, 2, 105, 12, 3, 109, 34, 50, 0, 110, 101, 1, 116, 110, 97, 108, 112, 111, 116, 2, 12, 12, 3, 109, 34, 50, 13, 0, 4, 115, 1, 21, 2, 116, 97, 116, 3, 109, 34, 89, 0, 115, 1, 102, 2, 107, 0, 8, 2, 32, 3, 110, 34, 0, 114, 195, 166, 110, 1, 116, 3, 110, 34, 6, 111, 68, 0, 1, 116, 2, 114, 111, 114, 3, 111, 34, 0, 98, 121, 1, 100, 3, 112, 12, 71, 37, 0, 4, 1, 18, 71, 18, 71, 3, 114, 0, 1, 18, 74, 2, 110, 101, 32, 0, 1, 21, 2, 32, 24, 0, 1, 21, 2, 115, 17, 67, 0, 1, 98, 111, 2, 115, 116, 0, 1, 100, 2, 98, 121, 103, 0, 1, 100, 21, 2, 17, 67, 0, 1, 100, 100, 117, 0, 1, 100, 101, 108, 2, 21, 0, 1, 100, 110, 117, 0, 1, 102, 102, 2, 17, 65, 116, 0, 1, 102, 102, 117, 107, 2, 116, 0, 1, 103, 2, 12, 0, 1, 103, 2, 32, 12, 12, 0, 1, 103, 110, 166, 195, 108, 2, 101, 0, 1, 103, 114, 111, 98, 2, 101, 0, 1, 103, 117, 115, 2, 101, 0, 1, 106, 101, 108, 0, 1, 106, 108, 97, 116, 2, 25, 12, 12, 0, 1, 106, 110, 105, 108, 2, 12, 12, 12, 0, 1, 107, 105, 17, 67, 2, 12, 0, 1, 107, 107, 2, 12, 0, 1, 107, 110, 117, 98, 0, 1, 107, 111, 112, 0, 1, 107, 115, 0, 1, 108, 103, 117, 109, 115, 0, 1, 108, 108, 105, 112, 0, 1, 108, 184, 195, 0, 1, 109, 21, 2, 115, 107, 0, 1, 109, 109, 2, 101, 116, 0, 1, 109, 109, 17, 65, 2, 17, 67, 0, 1, 109, 109, 117, 0, 1, 109, 111, 114, 0, 1, 110, 2, 32, 12, 0, 1, 110, 97, 109, 32, 114, 101, 100, 2, 32, 0, 1, 110, 97, 109, 109, 101, 114, 102, 0, 1, 110, 97, 109, 111, 2, 12, 0, 1, 110, 97, 109, 114, 111, 2, 32, 0, 1, 110, 105, 102, 108, 101, 100, 0, 1, 110, 116, 0, 1, 112, 117, 2, 17, 67, 0, 1, 114, 2, 17, 67, 0, 1, 114, 2, 32, 0, 1, 115, 110, 97, 100, 0, 1, 115, 110, 97, 112, 0, 1, 115, 117, 114, 98, 0, 1, 115, 121, 0, 1, 116, 2, 32, 0, 1, 116, 2, 101, 116, 32, 0, 1, 116, 10, 2, 17, 67, 0, 1, 116, 101, 109, 2, 12, 0, 1, 116, 102, 101, 0, 1, 116, 103, 0, 1, 116, 108, 97, 0, 1, 116, 108, 111, 112, 2, 97, 98, 0, 1, 116, 110, 101, 100, 0, 1, 116, 110, 105, 2, 21, 0, 1, 116, 110, 105, 2, 110, 97, 116, 0, 1, 116, 112, 101, 99, 115, 0, 1, 116, 114, 111, 112, 101, 114, 2, 12, 0, 1, 116, 115, 105, 0, 1, 116, 115, 110, 184, 195, 2, 12, 0, 1, 116, 115, 121, 114, 107, 2, 21, 0, 1, 116, 116, 2, 17, 67, 0, 1, 118, 97, 17, 67, 2, 32, 12, 0, 1, 118, 97, 114, 103, 100, 108, 117, 103, 2, 101, 0, 1, 118, 101, 108, 2, 17, 67, 12, 12, 0, 1, 118, 108, 111, 118, 101, 114, 2, 12, 0, 1, 118, 111, 2, 12, 12, 12, 0, 1, 118, 114, 97, 102, 2, 115, 12, 0, 1, 118, 121, 2, 12, 0, 1, 118, 166, 195, 110, 115, 2, 12, 12, 0, 1, 118, 184, 195, 2, 115, 116, 12, 12, 0, 8, 108, 108, 97, 0, 8, 112, 97, 107, 2, 115, 12, 12, 0, 95, 1, 104, 116, 0, 101, 1, 118, 111, 2, 110, 115, 12, 3, 114, 6, 36, 0, 4, 1, 100, 105, 107, 115, 3, 114, 34, 0, 1, 100, 111, 114, 98, 2, 101, 110, 0, 1, 118, 101, 108, 2, 101, 110, 12, 0, 105, 1, 21, 2, 28, 33, 12, 12, 3, 114, 34, 6, 37, 0, 105, 1, 118, 184, 195, 114, 21, 3, 114, 34, 37, 0, 101, 110, 1, 21, 2, 32, 3, 114, 34, 108, 50, 0, 101, 110, 115, 1, 21, 2, 32, 3, 114, 34, 108, 50, 89, 0, 4, 116, 1, 21, 2, 32, 3, 114, 47, 0, 116, 1, 21, 2, 115, 32, 0, 116, 1, 98, 109, 97, 108, 115, 0, 4, 110, 101, 1, 21, 2, 32, 12, 12, 3, 114, 50, 13, 0, 110, 101, 1, 100, 21, 2, 12, 12, 0, 110, 101, 1, 116, 110, 97, 108, 112, 2, 12, 12, 0, 110, 101, 1, 116, 115, 105, 99, 115, 97, 102, 2, 12, 0, 110, 101, 1, 118, 97, 116, 115, 2, 12, 0, 110, 101, 115, 1, 21, 2, 32, 3, 114, 50, 13, 89, 0, 110, 101, 1, 103, 110, 105, 102, 2, 109, 3, 114, 50, 36, 0, 110, 101, 1, 116, 110, 105, 2, 116, 12, 3, 114, 50, 109, 0, 1, 103, 110, 105, 102, 2, 101, 110, 3, 114, 51, 0, 115, 1, 21, 2, 32, 3, 114, 89, 0, 115, 116, 101, 1, 21, 2, 32, 3, 114, 89, 47, 13, 0, 4, 1, 115, 2, 118, 105, 99, 101, 109, 101, 100, 3, 118, 0, 1, 115, 2, 118, 105, 99, 101, 110, 0, 1, 115, 2, 118, 105, 99, 101, 115, 116, 97, 116, 105, 111, 110, 0, 110, 105, 101, 8, 3, 118, 12, 50, 37, 0, 103, 105, 101, 1, 102, 3, 118, 12, 81, 37, 0, 110, 111, 110, 1, 118, 2, 12, 12, 3, 118, 50, 108, 50, 0, 4, 118, 105, 99, 101, 1, 115, 101, 100, 110, 117, 107, 3, 118, 84, 37, 89, 0, 118, 105, 99, 101, 1, 115, 109, 111, 111, 114, 0, 118, 105, 99, 101, 109, 105, 110, 100, 101, 116, 1, 115, 3, 118, 84, 37, 89, 65, 35, 57, 50, 72, 13, 86, 0, 7, 6, 101, 116, 0, 4, 1, 114, 107, 101, 100, 2, 12, 3, 6, 36, 47, 0, 1, 116, 105, 2, 32, 12, 0, 1, 116, 105, 2, 115, 32, 12, 0, 8, 98, 97, 102, 108, 97, 0, 8, 98, 101, 103, 2, 12, 0, 8, 98, 105, 116, 0, 8, 102, 111, 114, 112, 0, 8, 107, 115, 97, 0, 8, 107, 115, 97, 107, 0, 8, 110, 97, 108, 112, 0, 8, 112, 97, 116, 0, 8, 112, 109, 111, 114, 116, 0, 8, 116, 114, 101, 98, 117, 112, 0, 116, 8, 107, 115, 97, 107, 0, 101, 114, 1, 109, 10, 3, 6, 36, 47, 114, 0, 4, 1, 98, 114, 111, 115, 3, 6, 109, 0, 1, 108, 101, 104, 99, 105, 109, 0, 4, 1, 99, 110, 105, 112, 3, 6, 109, 47, 0, 1, 102, 97, 116, 115, 0, 1, 107, 110, 97, 108, 98, 32, 110, 101, 0, 1, 108, 117, 109, 97, 0, 1, 110, 111, 105, 114, 97, 109, 0, 1, 110, 111, 115, 32, 110, 101, 0, 1, 114, 97, 107, 2, 12, 12, 0, 1, 114, 107, 110, 111, 107, 0, 1, 117, 100, 21, 2, 32, 0, 1, 117, 100, 32, 101, 103, 110, 121, 115, 2, 32, 0, 1, 117, 100, 32, 103, 110, 97, 115, 2, 32, 0, 1, 117, 100, 32, 110, 101, 2, 32, 0, 1, 117, 100, 32, 114, 101, 103, 110, 121, 115, 2, 32, 0, 1, 117, 100, 32, 116, 101, 103, 110, 117, 115, 2, 32, 0, 1, 117, 114, 105, 112, 0, 8, 100, 97, 107, 2, 12, 0, 8, 103, 100, 117, 98, 0, 8, 105, 118, 114, 101, 115, 0, 8, 107, 105, 114, 98, 0, 8, 107, 111, 107, 0, 8, 107, 114, 97, 112, 0, 8, 108, 105, 111, 116, 0, 8, 108, 105, 111, 116, 0, 8, 108, 108, 105, 98, 0, 8, 110, 105, 114, 97, 108, 107, 0, 8, 110, 111, 106, 97, 98, 0, 8, 114, 107, 101, 115, 2, 12, 0, 8, 115, 108, 97, 102, 0, 8, 115, 114, 111, 107, 32, 116, 101, 0, 8, 116, 110, 105, 118, 107, 0, 8, 116, 114, 97, 118, 107, 0, 116, 1, 110, 111, 105, 114, 97, 109, 0, 116, 1, 110, 111, 115, 2, 101, 0, 116, 8, 105, 118, 114, 101, 115, 0, 116, 8, 108, 108, 105, 98, 0, 116, 8, 110, 111, 106, 97, 98, 0, 116, 101, 8, 103, 114, 111, 101, 103, 0, 116, 101, 8, 117, 103, 97, 98, 0, 4, 116, 101, 8, 103, 97, 114, 102, 102, 117, 115, 3, 6, 109, 47, 13, 0, 116, 101, 8, 103, 114, 117, 111, 99, 0, 116, 101, 8, 107, 97, 108, 112, 0, 116, 101, 8, 107, 111, 107, 0, 116, 101, 8, 107, 115, 105, 100, 0, 116, 101, 8, 108, 105, 111, 116, 0, 116, 101, 8, 108, 108, 101, 118, 111, 110, 0, 116, 101, 8, 108, 111, 18, 75, 105, 110, 0, 116, 101, 8, 108, 117, 111, 114, 0, 116, 101, 8, 108, 121, 0, 116, 101, 8, 109, 108, 97, 112, 0, 116, 101, 8, 110, 97, 105, 112, 0, 116, 101, 8, 110, 105, 101, 114, 0, 116, 101, 8, 110, 117, 114, 98, 0, 116, 101, 8, 112, 105, 112, 0, 116, 101, 8, 114, 111, 98, 109, 97, 106, 0, 116, 101, 8, 114, 117, 98, 0, 116, 101, 8, 115, 105, 109, 101, 104, 99, 0, 116, 101, 8, 115, 105, 117, 113, 114, 97, 109, 0, 116, 101, 8, 115, 117, 109, 0, 116, 101, 8, 117, 116, 97, 116, 115, 0, 116, 101, 8, 118, 117, 99, 0, 116, 101, 114, 8, 117, 116, 97, 116, 115, 3, 6, 109, 47, 114, 0, 4, 116, 101, 8, 114, 98, 117, 111, 115, 3, 6, 110, 47, 13, 0, 116, 101, 8, 114, 103, 105, 97, 110, 105, 118, 0, 8, 114, 117, 98, 97, 116, 2, 12, 3, 6, 111, 47, 0, 1, 116, 105, 10, 2, 28, 33, 12, 3, 7, 36, 47, 0, 4, 8, 107, 105, 116, 101, 3, 7, 109, 47, 0, 8, 108, 111, 105, 118, 2, 12, 0, 116, 101, 8, 107, 105, 116, 101, 3, 7, 109, 47, 13, 0, 1, 114, 2, 195, 184, 106, 12, 3, 13, 47, 0, 4, 1, 21, 2, 32, 12, 3, 13, 86, 0, 1, 103, 97, 116, 0, 1, 114, 117, 2, 32, 12, 12, 0, 1, 117, 100, 110, 105, 118, 2, 32, 0, 1, 118, 97, 2, 12, 0, 115, 1, 21, 2, 32, 12, 3, 13, 86, 89, 0, 4, 1, 98, 97, 102, 108, 97, 3, 36, 47, 0, 1, 98, 105, 116, 0, 1, 102, 111, 114, 112, 0, 1, 103, 101, 109, 2, 12, 0, 1, 105, 118, 114, 101, 115, 0, 1, 112, 97, 116, 0, 1, 112, 109, 111, 114, 116, 0, 1, 115, 108, 105, 116, 0, 1, 115, 109, 101, 110, 110, 101, 103, 0, 1, 115, 114, 101, 118, 111, 0, 8, 107, 115, 0, 8, 115, 2, 32, 12, 0, 8, 115, 100, 110, 105, 2, 32, 0, 8, 115, 101, 100, 108, 105, 0, 8, 115, 117, 2, 32, 0, 95, 1, 114, 111, 102, 3, 47, 0, 4, 1, 102, 111, 114, 112, 2, 105, 3, 108, 47, 0, 1, 105, 114, 114, 97, 104, 0, 1, 114, 107, 101, 115, 2, 195, 166, 114, 0, 1, 114, 21, 2, 32, 12, 3, 108, 86, 0, 4, 1, 107, 105, 114, 98, 3, 109, 47, 0, 1, 108, 98, 97, 116, 0, 1, 108, 101, 109, 111, 0, 1, 108, 101, 114, 166, 195, 112, 2, 12, 0, 1, 108, 105, 111, 116, 0, 1, 108, 108, 97, 98, 122, 122, 97, 106, 0, 1, 108, 108, 105, 98, 0, 1, 108, 111, 105, 118, 0, 1, 108, 112, 2, 12, 0, 1, 108, 112, 100, 108, 117, 103, 0, 1, 108, 112, 109, 97, 107, 115, 0, 1, 108, 112, 114, 101, 118, 101, 108, 0, 1, 108, 112, 115, 2, 12, 0, 1, 108, 112, 118, 108, 184, 195, 115, 0, 1, 110, 101, 103, 97, 108, 102, 117, 109, 97, 107, 0, 1, 110, 101, 107, 115, 105, 102, 0, 1, 110, 105, 114, 97, 108, 107, 0, 1, 110, 108, 101, 2, 12, 0, 1, 110, 111, 106, 97, 98, 0, 1, 110, 114, 165, 195, 104, 0, 1, 116, 110, 105, 118, 107, 0, 1, 116, 114, 97, 118, 107, 0, 8, 115, 115, 97, 98, 0, 116, 1, 108, 105, 111, 116, 0, 116, 1, 108, 108, 105, 98, 0, 116, 1, 108, 112, 2, 12, 0, 4, 1, 114, 97, 103, 114, 97, 109, 3, 111, 47, 0, 1, 114, 97, 122, 97, 110, 0, 1, 114, 100, 110, 105, 2, 12, 0, 1, 114, 101, 98, 184, 195, 107, 2, 12, 0, 1, 114, 101, 100, 121, 114, 103, 2, 12, 0, 1, 114, 101, 100, 165, 195, 114, 2, 12, 0, 1, 114, 101, 100, 184, 195, 109, 2, 12, 0, 1, 114, 101, 102, 102, 97, 114, 116, 115, 2, 12, 0, 1, 114, 101, 103, 97, 108, 107, 2, 12, 0, 1, 114, 101, 103, 103, 121, 98, 2, 12, 0, 1, 114, 101, 103, 105, 108, 2, 12, 0, 1, 114, 101, 103, 110, 101, 112, 103, 97, 100, 2, 12, 0, 1, 114, 101, 105, 108, 105, 109, 97, 102, 2, 12, 0, 1, 114, 101, 107, 115, 101, 110, 110, 101, 109, 2, 12, 0, 1, 114, 101, 107, 115, 105, 102, 2, 12, 0, 1, 114, 101, 108, 97, 116, 2, 12, 0, 1, 114, 101, 108, 97, 116, 165, 195, 112, 2, 12, 0, 1, 114, 101, 108, 111, 107, 115, 2, 12, 0, 1, 114, 101, 109, 109, 101, 116, 115, 2, 12, 0, 1, 114, 101, 110, 97, 118, 100, 166, 195, 115, 2, 12, 0, 1, 114, 101, 110, 101, 2, 12, 12, 0, 1, 114, 101, 116, 115, 101, 106, 184, 195, 104, 0, 1, 114, 101, 116, 115, 114, 184, 195, 102, 2, 12, 0, 1, 114, 101, 116, 116, 97, 107, 115, 2, 12, 0, 1, 114, 101, 116, 116, 121, 98, 2, 12, 0, 1, 114, 101, 117, 107, 115, 2, 12, 0, 1, 114, 101, 118, 114, 97, 2, 12, 0, 1, 114, 103, 105, 100, 114, 166, 195, 102, 2, 12, 0, 1, 114, 108, 101, 103, 101, 114, 2, 12, 0, 1, 114, 110, 101, 104, 2, 32, 0, 1, 114, 111, 116, 101, 118, 2, 12, 0, 1, 114, 114, 101, 100, 110, 117, 2, 12, 0, 1, 114, 114, 101, 103, 114, 111, 98, 0, 1, 114, 115, 2, 12, 12, 0, 1, 114, 117, 32, 101, 114, 184, 195, 103, 2, 12, 12, 0, 1, 114, 117, 32, 103, 105, 100, 2, 12, 12, 0, 1, 114, 117, 32, 103, 105, 100, 32, 101, 2, 12, 12, 0, 1, 114, 117, 32, 103, 105, 100, 32, 116, 2, 12, 12, 0, 1, 114, 117, 32, 103, 105, 109, 32, 101, 2, 12, 12, 0, 1, 114, 117, 32, 103, 105, 109, 32, 116, 2, 12, 12, 0, 1, 114, 117, 32, 103, 111, 32, 116, 101, 114, 2, 12, 0, 1, 114, 117, 32, 109, 101, 100, 32, 116, 2, 12, 12, 0, 1, 114, 117, 32, 110, 101, 2, 12, 12, 0, 1, 114, 117, 32, 114, 101, 106, 32, 116, 2, 12, 12, 0, 1, 114, 117, 32, 114, 184, 195, 103, 2, 12, 12, 0, 1, 114, 118, 105, 108, 2, 12, 0, 8, 114, 100, 114, 111, 2, 12, 0, 8, 114, 117, 2, 32, 109, 111, 100, 32, 12, 12, 0, 43, 8, 114, 0, 116, 1, 114, 2, 12, 12, 12, 12, 0, 1, 114, 100, 110, 166, 195, 2, 12, 3, 114, 86, 0, 7, 6, 103, 101, 0, 2, 110, 105, 117, 115, 3, 0, 4, 8, 101, 110, 97, 109, 3, 8, 91, 108, 0, 8, 101, 116, 114, 111, 107, 0, 1, 108, 184, 195, 102, 3, 57, 108, 0, 4, 1, 111, 108, 97, 104, 2, 110, 3, 81, 6, 36, 0, 8, 97, 2, 114, 101, 0, 4, 2, 110, 105, 97, 108, 3, 81, 36, 0, 2, 110, 105, 116, 97, 108, 0, 2, 110, 105, 116, 105, 118, 0, 8, 2, 110, 101, 114, 101, 114, 101, 32, 0, 4, 2, 98, 101, 116, 3, 81, 36, 6, 0, 2, 98, 105, 115, 0, 2, 98, 111, 109, 109, 101, 114, 108, 105, 103, 0, 2, 98, 114, 111, 107, 107, 101, 110, 0, 2, 98, 114, 195, 166, 107, 107, 101, 108, 105, 103, 0, 2, 98, 121, 114, 0, 2, 98, 195, 166, 114, 100, 101, 0, 2, 100, 105, 103, 101, 110, 0, 2, 100, 117, 108, 103, 116, 0, 2, 104, 97, 108, 116, 0, 2, 104, 101, 106, 109, 101, 114, 195, 165, 100, 0, 2, 104, 101, 110, 110, 97, 0, 2, 104, 195, 166, 110, 103, 0, 2, 104, 195, 184, 114, 0, 2, 108, 97, 115, 115, 101, 110, 0, 2, 108, 101, 100, 0, 2, 108, 101, 106, 100, 101, 0, 2, 108, 105, 110, 100, 101, 0, 2, 108, 195, 166, 110, 100, 101, 114, 0, 2, 109, 97, 107, 0, 2, 109, 97, 108, 0, 2, 109, 101, 110, 0, 2, 109, 121, 115, 101, 0, 2, 109, 121, 116, 0, 2, 109, 121, 116, 108, 105, 103, 0, 2, 110, 111, 109, 0, 2, 110, 116, 105, 108, 0, 2, 110, 117, 105, 110, 0, 2, 112, 97, 114, 100, 0, 2, 114, 97, 110, 105, 101, 0, 2, 114, 97, 110, 105, 117, 109, 0, 2, 114, 195, 165, 100, 101, 0, 2, 115, 97, 110, 100, 116, 0, 2, 115, 105, 109, 115, 0, 2, 115, 106, 195, 166, 102, 116, 0, 2, 115, 107, 195, 166, 102, 116, 105, 103, 0, 2, 115, 112, 101, 110, 115, 116, 0, 2, 115, 116, 97, 103, 101, 110, 0, 2, 115, 116, 97, 108, 116, 0, 2, 115, 116, 105, 107, 0, 2, 115, 118, 101, 106, 115, 110, 105, 110, 103, 0, 2, 115, 118, 105, 110, 100, 116, 0, 2, 118, 97, 108, 100, 105, 103, 0, 2, 118, 97, 108, 116, 0, 2, 118, 97, 110, 100, 116, 0, 2, 118, 105, 110, 100, 0, 2, 118, 105, 110, 115, 116, 0, 2, 118, 105, 114, 0, 2, 118, 195, 166, 107, 115, 116, 0, 2, 118, 195, 166, 114, 0, 110, 101, 114, 101, 108, 8, 3, 81, 36, 50, 13, 34, 6, 111, 55, 0, 110, 105, 2, 110, 100, 3, 81, 36, 50, 36, 0, 2, 110, 105, 110, 118, 101, 115, 116, 3, 81, 109, 0, 114, 2, 110, 105, 110, 103, 3, 81, 109, 34, 0, 114, 109, 97, 105, 110, 3, 90, 109, 34, 65, 6, 110, 68, 0, 4, 1, 97, 100, 110, 97, 98, 2, 114, 101, 3, 91, 6, 36, 0, 1, 97, 103, 2, 114, 101, 0, 1, 97, 103, 110, 101, 2, 114, 101, 0, 1, 97, 110, 101, 109, 2, 114, 101, 0, 1, 97, 114, 97, 103, 2, 114, 101, 0, 1, 97, 114, 117, 111, 102, 2, 114, 101, 0, 1, 101, 116, 111, 114, 112, 2, 114, 101, 0, 1, 105, 108, 103, 101, 110, 2, 114, 101, 0, 1, 110, 97, 104, 99, 2, 114, 101, 0, 1, 110, 97, 114, 2, 114, 101, 0, 1, 110, 97, 114, 100, 110, 105, 2, 114, 101, 0, 1, 110, 97, 114, 100, 117, 2, 114, 101, 0, 1, 110, 97, 114, 114, 97, 2, 114, 101, 0, 1, 111, 108, 2, 114, 101, 0, 1, 111, 108, 100, 110, 105, 2, 114, 101, 0, 1, 114, 97, 104, 99, 2, 114, 101, 0, 1, 114, 117, 2, 114, 101, 0, 1, 117, 106, 2, 114, 101, 0, 1, 100, 117, 98, 2, 116, 3, 91, 6, 109, 0, 4, 1, 111, 108, 2, 109, 195, 184, 3, 91, 36, 0, 2, 110, 101, 114, 116, 0, 2, 110, 101, 114, 195, 184, 115, 0, 2, 110, 105, 0, 8, 2, 110, 101, 32, 0, 8, 2, 110, 101, 114, 101, 0, 8, 2, 110, 101, 118, 101, 114, 0, 4, 110, 101, 114, 2, 32, 109, 105, 103, 3, 91, 36, 50, 6, 36, 34, 0, 110, 101, 114, 2, 101, 32, 109, 105, 103, 0, 4, 1, 101, 110, 97, 109, 3, 91, 108, 0, 1, 101, 116, 114, 111, 107, 0, 1, 111, 108, 2, 98, 114, 111, 0, 1, 111, 108, 2, 110, 0, 1, 111, 108, 114, 101, 114, 117, 109, 105, 114, 102, 0, 8, 111, 108, 2, 32, 0, 114, 8, 111, 108, 2, 32, 3, 91, 114, 0, 4, 1, 111, 108, 111, 107, 121, 2, 110, 3, 108, 0, 1, 111, 108, 111, 116, 107, 111, 114, 112, 2, 110, 0, 7, 6, 105, 103, 0, 1, 114, 116, 110, 105, 2, 12, 3, 6, 37, 0, 101, 1, 116, 108, 111, 118, 3, 6, 37, 12, 91, 0, 1, 100, 114, 166, 195, 118, 2, 101, 110, 115, 116, 97, 110, 100, 3, 6, 37, 81, 0, 1, 10, 2, 28, 33, 12, 12, 3, 8, 37, 0, 104, 116, 1, 108, 3, 35, 57, 47, 0, 104, 116, 121, 1, 109, 3, 35, 57, 47, 37, 0, 4, 8, 108, 2, 32, 103, 111, 100, 116, 3, 36, 49, 0, 8, 108, 2, 32, 111, 114, 100, 101, 110, 116, 108, 105, 103, 116, 0, 8, 108, 2, 32, 112, 195, 166, 110, 116, 0, 8, 108, 2, 32, 114, 111, 108, 105, 103, 116, 0, 8, 108, 2, 32, 115, 116, 105, 108, 108, 101, 0, 4, 1, 100, 97, 100, 100, 101, 2, 116, 3, 36, 81, 0, 1, 100, 97, 115, 111, 114, 112, 2, 116, 0, 1, 100, 101, 100, 166, 195, 109, 115, 2, 116, 0, 1, 100, 101, 116, 108, 101, 104, 2, 116, 0, 1, 100, 101, 116, 109, 166, 195, 107, 115, 2, 116, 0, 1, 100, 112, 111, 2, 116, 0, 1, 100, 117, 107, 105, 97, 104, 2, 116, 0, 1, 108, 112, 2, 116, 12, 0, 1, 115, 100, 2, 116, 12, 0, 1, 115, 110, 2, 116, 12, 0, 1, 115, 112, 111, 2, 116, 12, 0, 1, 118, 115, 2, 116, 12, 0, 8, 98, 2, 32, 0, 8, 100, 2, 116, 0, 103, 1, 108, 2, 101, 12, 12, 0, 103, 101, 114, 1, 110, 3, 36, 81, 114, 0, 4, 1, 100, 97, 116, 115, 3, 37, 0, 1, 100, 108, 0, 1, 100, 110, 166, 195, 104, 101, 98, 0, 1, 108, 111, 98, 2, 12, 0, 1, 115, 100, 105, 104, 0, 1, 115, 100, 111, 114, 116, 0, 1, 115, 100, 117, 109, 115, 0, 1, 115, 100, 117, 112, 0, 1, 115, 100, 117, 112, 2, 116, 0, 1, 116, 116, 97, 102, 0, 2, 32, 0, 2, 104, 101, 100, 12, 0, 2, 115, 0, 4, 101, 1, 114, 107, 2, 110, 3, 37, 12, 13, 0, 101, 1, 115, 2, 12, 12, 0, 101, 2, 12, 12, 0, 101, 110, 1, 112, 3, 37, 12, 108, 50, 0, 101, 114, 2, 12, 3, 37, 12, 114, 0, 116, 1, 21, 2, 32, 3, 37, 47, 0, 1, 112, 2, 32, 3, 37, 49, 0, 116, 1, 110, 101, 103, 184, 195, 100, 3, 37, 49, 47, 0, 4, 1, 100, 101, 110, 115, 3, 37, 57, 0, 1, 100, 105, 115, 110, 101, 103, 0, 1, 100, 121, 0, 1, 108, 2, 101, 110, 101, 0, 1, 110, 115, 0, 1, 116, 115, 2, 101, 12, 0, 101, 1, 100, 2, 110, 100, 101, 3, 37, 57, 13, 0, 4, 101, 1, 110, 115, 2, 12, 3, 37, 57, 108, 0, 101, 1, 118, 2, 110, 0, 4, 1, 107, 100, 117, 3, 37, 81, 0, 1, 108, 2, 97, 12, 12, 0, 1, 108, 2, 114, 97, 109, 0, 1, 114, 105, 100, 2, 101, 110, 116, 0, 8, 107, 2, 32, 0, 4, 101, 1, 100, 101, 114, 2, 114, 3, 37, 81, 6, 36, 0, 101, 1, 108, 105, 118, 105, 114, 112, 0, 101, 1, 108, 108, 101, 116, 110, 105, 2, 110, 0, 101, 1, 114, 101, 2, 114, 101, 0, 101, 1, 114, 105, 100, 2, 114, 0, 101, 1, 114, 114, 2, 114, 0, 101, 1, 118, 97, 110, 2, 114, 0, 101, 114, 105, 97, 1, 110, 3, 37, 81, 6, 36, 51, 37, 110, 0, 101, 2, 110, 12, 3, 37, 81, 6, 109, 0, 101, 1, 110, 2, 114, 105, 3, 37, 81, 36, 0, 101, 97, 1, 114, 102, 2, 114, 3, 37, 81, 37, 0, 101, 114, 8, 110, 2, 32, 3, 37, 81, 114, 0, 115, 1, 114, 107, 3, 37, 89, 0, 101, 110, 1, 108, 105, 100, 2, 99, 101, 3, 37, 91, 6, 112, 68, 0, 101, 1, 108, 111, 114, 3, 37, 109, 0, 7, 6, 105, 110, 0, 4, 1, 21, 2, 28, 33, 3, 6, 37, 50, 0, 1, 116, 97, 108, 10, 2, 28, 33, 0, 1, 116, 110, 97, 122, 121, 98, 0, 101, 1, 10, 2, 116, 114, 121, 107, 28, 33, 3, 6, 37, 50, 13, 0, 101, 1, 10, 2, 28, 33, 3, 6, 37, 50, 108, 0, 101, 1, 10, 2, 114, 28, 33, 3, 6, 37, 50, 114, 0, 4, 1, 115, 115, 97, 10, 2, 28, 33, 3, 6, 109, 68, 0, 1, 116, 97, 10, 2, 28, 33, 0, 4, 1, 108, 101, 118, 2, 102, 111, 114, 109, 101, 114, 101, 116, 3, 36, 50, 0, 100, 2, 104, 111, 108, 100, 0, 1, 10, 2, 97, 114, 28, 33, 3, 37, 50, 6, 0, 101, 1, 10, 2, 114, 101, 28, 33, 3, 37, 50, 6, 36, 0, 101, 1, 98, 97, 107, 2, 116, 3, 37, 50, 6, 109, 0, 7, 6, 105, 115, 0, 116, 1, 10, 2, 28, 33, 12, 12, 12, 3, 7, 37, 89, 47, 0, 116, 1, 10, 2, 105, 107, 28, 33, 3, 37, 89, 47, 6, 0, 116, 105, 107, 101, 1, 10, 2, 114, 101, 3, 37, 89, 47, 37, 49, 6, 36, 0, 7, 6, 105, 116, 0, 1, 10, 2, 116, 28, 33, 3, 6, 37, 0, 1, 10, 2, 28, 33, 3, 6, 37, 47, 0, 1, 10, 2, 97, 110, 28, 33, 3, 37, 47, 6, 0, 105, 111, 110, 1, 10, 2, 28, 33, 3, 37, 91, 6, 39, 50, 0, 7, 6, 105, 118, 0, 4, 8, 116, 97, 116, 115, 3, 6, 37, 58, 0, 8, 116, 107, 97, 114, 116, 110, 111, 107, 0, 4, 8, 97, 110, 3, 6, 37, 84, 0, 8, 99, 115, 97, 108, 0, 8, 100, 110, 117, 114, 101, 103, 0, 8, 107, 114, 97, 0, 8, 115, 105, 99, 101, 100, 0, 8, 115, 114, 117, 107, 0, 8, 115, 115, 97, 109, 0, 8, 115, 166, 195, 104, 100, 97, 0, 8, 116, 97, 105, 116, 105, 110, 105, 0, 8, 116, 97, 108, 117, 103, 101, 114, 0, 8, 116, 107, 101, 112, 115, 114, 101, 112, 0, 8, 116, 107, 101, 114, 105, 100, 0, 8, 116, 107, 101, 116, 101, 100, 0, 8, 116, 111, 109, 0, 8, 116, 111, 109, 111, 107, 111, 108, 0, 8, 116, 112, 97, 100, 97, 0, 8, 116, 112, 117, 114, 101, 0, 8, 116, 114, 101, 115, 115, 97, 0, 8, 116, 114, 111, 98, 97, 0, 8, 116, 114, 111, 112, 115, 0, 8, 116, 115, 97, 114, 116, 110, 111, 107, 0, 8, 116, 115, 101, 103, 105, 100, 0, 8, 116, 117, 107, 101, 115, 107, 101, 0, 7, 6, 109, 101, 0, 116, 8, 114, 117, 111, 103, 3, 65, 6, 36, 0, 110, 116, 1, 10, 3, 65, 6, 36, 50, 47, 0, 4, 110, 116, 1, 101, 115, 115, 111, 100, 110, 101, 3, 65, 6, 112, 68, 0, 110, 116, 8, 97, 114, 101, 112, 109, 101, 116, 0, 110, 116, 8, 101, 98, 109, 97, 106, 110, 101, 0, 110, 116, 8, 101, 99, 97, 108, 112, 101, 100, 0, 110, 116, 8, 101, 99, 110, 97, 118, 97, 0, 110, 116, 8, 101, 100, 114, 97, 98, 109, 111, 98, 0, 110, 116, 8, 101, 103, 97, 103, 110, 101, 0, 110, 116, 8, 101, 103, 110, 97, 104, 99, 0, 110, 116, 8, 101, 103, 110, 97, 114, 114, 97, 0, 110, 116, 8, 101, 104, 99, 97, 116, 101, 100, 0, 110, 116, 8, 101, 108, 98, 184, 195, 109, 0, 110, 116, 8, 101, 108, 103, 101, 114, 0, 110, 116, 8, 101, 108, 108, 101, 118, 105, 110, 0, 110, 116, 8, 101, 108, 112, 112, 117, 115, 0, 110, 116, 8, 101, 110, 105, 102, 102, 97, 114, 0, 110, 116, 8, 101, 110, 110, 111, 98, 97, 0, 110, 116, 8, 101, 110, 110, 111, 116, 97, 107, 0, 110, 116, 8, 101, 110, 114, 101, 118, 117, 103, 0, 110, 116, 8, 101, 115, 115, 97, 108, 107, 0, 110, 116, 8, 101, 115, 115, 105, 108, 98, 97, 116, 101, 0, 110, 116, 8, 101, 115, 115, 105, 116, 114, 101, 118, 97, 0, 110, 116, 8, 101, 115, 115, 105, 116, 114, 101, 118, 105, 100, 0, 110, 116, 8, 101, 115, 115, 111, 110, 97, 107, 0, 110, 116, 8, 101, 115, 115, 111, 112, 0, 110, 116, 8, 101, 116, 107, 97, 114, 116, 0, 110, 116, 8, 101, 116, 114, 97, 112, 101, 100, 0, 110, 116, 8, 101, 118, 97, 108, 0, 110, 116, 8, 105, 108, 112, 109, 111, 107, 0, 110, 116, 8, 105, 116, 110, 101, 115, 115, 101, 114, 0, 110, 116, 8, 105, 116, 114, 111, 115, 0, 4, 110, 116, 8, 101, 108, 97, 110, 103, 105, 115, 3, 65, 7, 112, 68, 0, 110, 116, 8, 101, 110, 110, 111, 115, 166, 195, 114, 0, 116, 1, 114, 117, 111, 103, 3, 65, 36, 0, 4, 110, 116, 101, 1, 101, 108, 103, 101, 114, 2, 114, 101, 116, 3, 65, 36, 50, 47, 6, 36, 0, 110, 116, 101, 8, 101, 108, 103, 101, 114, 2, 114, 101, 0, 110, 116, 101, 108, 8, 117, 114, 116, 115, 110, 105, 3, 65, 36, 50, 47, 6, 36, 55, 0, 110, 116, 101, 108, 1, 117, 114, 116, 115, 110, 105, 3, 65, 36, 50, 47, 36, 55, 0, 4, 110, 2, 116, 117, 115, 105, 97, 115, 3, 65, 112, 68, 0, 110, 116, 1, 97, 114, 101, 112, 109, 101, 116, 0, 110, 116, 1, 101, 98, 109, 97, 106, 110, 101, 0, 110, 116, 1, 101, 99, 97, 108, 112, 101, 100, 0, 110, 116, 1, 101, 99, 110, 97, 118, 97, 0, 110, 116, 1, 101, 100, 114, 97, 98, 109, 111, 98, 0, 110, 116, 1, 101, 103, 97, 103, 110, 101, 0, 110, 116, 1, 101, 103, 110, 97, 104, 99, 0, 110, 116, 1, 101, 103, 110, 97, 114, 114, 97, 0, 110, 116, 1, 101, 104, 99, 97, 116, 101, 100, 0, 110, 116, 1, 101, 108, 97, 110, 103, 105, 115, 0, 110, 116, 1, 101, 108, 98, 184, 195, 109, 0, 110, 116, 1, 101, 108, 103, 101, 114, 0, 110, 116, 1, 101, 108, 108, 101, 118, 105, 110, 0, 110, 116, 1, 101, 108, 112, 112, 117, 115, 0, 110, 116, 1, 101, 110, 105, 102, 102, 97, 114, 0, 110, 116, 1, 101, 110, 110, 111, 98, 97, 0, 110, 116, 1, 101, 110, 110, 111, 115, 166, 195, 114, 0, 110, 116, 1, 101, 110, 110, 111, 116, 97, 107, 0, 110, 116, 1, 101, 110, 114, 101, 118, 117, 103, 0, 110, 116, 1, 101, 115, 115, 97, 108, 107, 0, 110, 116, 1, 101, 115, 115, 105, 108, 98, 97, 116, 101, 0, 110, 116, 1, 101, 115, 115, 105, 116, 114, 101, 118, 97, 0, 110, 116, 1, 101, 115, 115, 105, 116, 114, 101, 118, 105, 100, 0, 110, 116, 1, 101, 115, 115, 111, 110, 110, 111, 107, 0, 110, 116, 1, 101, 115, 115, 111, 112, 0, 110, 116, 1, 101, 116, 107, 97, 114, 116, 0, 110, 116, 1, 101, 116, 114, 97, 112, 101, 100, 0, 110, 116, 1, 101, 118, 97, 108, 0, 110, 116, 1, 105, 108, 112, 109, 111, 107, 0, 110, 116, 1, 105, 116, 110, 101, 115, 115, 101, 114, 0, 110, 116, 1, 105, 116, 114, 111, 115, 0, 7, 6, 110, 100, 0, 4, 1, 97, 101, 110, 2, 101, 114, 3, 8, 50, 72, 0, 1, 97, 109, 97, 2, 97, 0, 1, 97, 110, 114, 101, 102, 2, 111, 0, 1, 97, 115, 115, 105, 108, 103, 2, 111, 0, 1, 101, 107, 115, 105, 2, 101, 114, 117, 110, 0, 4, 1, 17, 65, 3, 50, 0, 1, 97, 98, 2, 101, 108, 0, 1, 97, 98, 32, 103, 101, 106, 2, 101, 114, 0, 1, 97, 98, 32, 117, 100, 2, 101, 114, 0, 1, 97, 98, 114, 111, 102, 2, 101, 114, 0, 1, 97, 104, 2, 101, 108, 0, 1, 97, 108, 0, 1, 97, 108, 2, 97, 114, 0, 1, 97, 112, 2, 101, 108, 111, 107, 0, 1, 97, 116, 115, 2, 12, 0, 1, 97, 118, 2, 97, 102, 0, 1, 101, 2, 101, 12, 0, 1, 101, 2, 101, 108, 105, 103, 0, 1, 101, 107, 2, 101, 108, 0, 1, 105, 2, 101, 114, 107, 114, 101, 100, 115, 12, 0, 1, 105, 2, 101, 114, 108, 12, 0, 1, 105, 2, 101, 114, 115, 116, 12, 0, 1, 105, 2, 105, 109, 101, 108, 108, 101, 109, 0, 1, 105, 98, 2, 101, 0, 1, 105, 98, 2, 105, 110, 0, 1, 105, 102, 2, 12, 0, 1, 105, 102, 2, 101, 108, 195, 184, 110, 0, 1, 105, 109, 2, 101, 0, 1, 105, 116, 2, 105, 110, 0, 1, 105, 118, 2, 101, 0, 1, 105, 118, 2, 105, 110, 0, 1, 105, 118, 107, 0, 1, 105, 118, 115, 2, 101, 108, 0, 1, 117, 100, 2, 114, 101, 0, 1, 117, 104, 2, 12, 0, 1, 121, 2, 101, 108, 0, 1, 121, 108, 112, 2, 114, 0, 1, 165, 195, 2, 101, 108, 105, 0, 1, 165, 195, 104, 2, 97, 114, 0, 2, 101, 108, 115, 101, 0, 8, 97, 98, 32, 101, 100, 2, 101, 114, 0, 8, 97, 98, 32, 105, 2, 101, 114, 0, 8, 97, 98, 32, 105, 118, 2, 101, 114, 0, 8, 97, 98, 32, 110, 97, 109, 2, 101, 114, 0, 8, 105, 2, 114, 101, 116, 0, 101, 1, 101, 118, 2, 108, 0, 101, 1, 105, 109, 2, 108, 105, 0, 101, 1, 117, 115, 105, 109, 2, 108, 105, 103, 0, 110, 1, 17, 65, 0, 101, 1, 105, 118, 101, 2, 108, 105, 3, 50, 13, 0, 101, 108, 1, 97, 109, 3, 50, 13, 55, 0, 1, 97, 98, 2, 101, 114, 3, 50, 19, 0, 4, 1, 17, 65, 2, 97, 116, 3, 50, 72, 0, 1, 17, 65, 2, 114, 101, 0, 1, 17, 65, 2, 114, 105, 110, 0, 1, 97, 2, 97, 108, 117, 115, 0, 1, 97, 2, 101, 108, 0, 1, 97, 2, 101, 115, 98, 106, 0, 1, 97, 2, 114, 101, 0, 1, 97, 2, 121, 0, 1, 97, 98, 2, 97, 103, 101, 0, 1, 97, 98, 2, 101, 107, 114, 105, 0, 1, 97, 98, 2, 101, 109, 101, 100, 108, 101, 109, 0, 1, 97, 98, 2, 101, 110, 115, 0, 1, 97, 98, 2, 101, 114, 110, 101, 0, 1, 97, 98, 2, 101, 114, 111, 0, 1, 97, 98, 2, 101, 117, 118, 195, 166, 115, 101, 110, 0, 1, 97, 98, 2, 105, 116, 0, 1, 97, 103, 2, 97, 0, 1, 97, 103, 2, 101, 114, 101, 0, 1, 97, 104, 2, 105, 0, 1, 97, 107, 115, 2, 97, 0, 1, 97, 107, 115, 2, 105, 110, 97, 118, 0, 1, 97, 107, 115, 114, 97, 109, 0, 1, 97, 109, 2, 97, 103, 0, 1, 97, 109, 2, 97, 114, 105, 110, 0, 1, 97, 109, 109, 2, 101, 114, 0, 1, 97, 109, 109, 2, 111, 0, 1, 97, 109, 109, 111, 107, 0, 1, 97, 112, 2, 97, 0, 1, 97, 114, 101, 118, 2, 97, 0, 1, 97, 114, 105, 109, 2, 97, 0, 1, 97, 115, 2, 97, 108, 0, 1, 97, 116, 115, 2, 97, 114, 0, 1, 97, 118, 2, 97, 108, 0, 1, 97, 118, 2, 101, 114, 98, 105, 108, 116, 0, 1, 97, 118, 2, 114, 101, 0, 1, 101, 2, 111, 103, 101, 110, 0, 1, 101, 2, 111, 107, 114, 105, 0, 1, 101, 2, 111, 115, 0, 1, 101, 2, 111, 115, 107, 111, 112, 0, 1, 101, 32, 121, 112, 112, 97, 104, 2, 32, 0, 1, 101, 100, 100, 97, 0, 1, 101, 100, 105, 108, 97, 118, 101, 114, 0, 1, 101, 100, 105, 118, 105, 100, 0, 1, 101, 102, 2, 101, 114, 0, 1, 101, 103, 2, 97, 110, 0, 1, 101, 103, 101, 108, 2, 97, 114, 105, 115, 107, 0, 1, 101, 103, 117, 106, 0, 1, 101, 104, 2, 101, 114, 115, 111, 110, 0, 1, 101, 104, 97, 114, 116, 98, 117, 115, 0, 1, 101, 106, 101, 2, 101, 108, 0, 1, 101, 107, 2, 105, 115, 0, 1, 101, 108, 98, 2, 101, 0, 1, 101, 108, 101, 2, 105, 103, 0, 1, 101, 112, 2, 101, 114, 103, 97, 115, 116, 0, 1, 101, 112, 2, 105, 0, 1, 101, 112, 115, 2, 101, 114, 0, 1, 101, 116, 2, 101, 110, 0, 1, 101, 116, 2, 101, 110, 115, 0, 1, 101, 116, 115, 0, 1, 101, 116, 116, 105, 109, 105, 100, 0, 1, 101, 117, 110, 105, 109, 0, 1, 101, 118, 100, 184, 195, 110, 2, 105, 103, 0, 1, 101, 119, 2, 101, 108, 0, 1, 101, 119, 2, 121, 0, 1, 101, 119, 103, 2, 97, 0, 1, 105, 2, 101, 107, 115, 0, 1, 105, 2, 101, 117, 0, 1, 105, 2, 105, 0, 1, 105, 2, 105, 103, 12, 0, 1, 105, 2, 111, 107, 105, 0, 1, 105, 2, 111, 110, 101, 0, 1, 105, 2, 117, 0, 1, 105, 99, 2, 121, 0, 1, 105, 102, 2, 101, 108, 0, 1, 105, 108, 2, 97, 0, 1, 105, 108, 2, 121, 0, 1, 105, 118, 2, 114, 105, 107, 0, 1, 105, 118, 2, 117, 0, 1, 111, 2, 105, 0, 1, 111, 98, 32, 115, 101, 109, 97, 106, 0, 1, 111, 107, 2, 101, 109, 110, 101, 114, 101, 0, 1, 111, 107, 2, 101, 110, 115, 0, 1, 111, 107, 2, 105, 0, 1, 111, 107, 2, 111, 108, 0, 1, 111, 107, 2, 111, 108, 101, 114, 101, 0, 1, 111, 114, 2, 101, 108, 0, 1, 117, 2, 110, 101, 0, 1, 117, 2, 114, 101, 0, 1, 117, 102, 2, 97, 0, 1, 117, 102, 2, 101, 114, 0, 1, 117, 104, 2, 106, 195, 166, 118, 101, 108, 0, 1, 117, 104, 2, 121, 114, 0, 1, 117, 107, 101, 115, 0, 1, 117, 109, 2, 101, 114, 105, 110, 103, 0, 1, 117, 114, 32, 110, 101, 2, 101, 0, 1, 117, 114, 115, 2, 101, 0, 1, 184, 195, 115, 2, 97, 103, 0, 2, 97, 103, 0, 2, 101, 110, 116, 0, 2, 105, 100, 97, 0, 2, 105, 103, 0, 2, 111, 109, 0, 2, 121, 114, 0, 2, 195, 165, 115, 101, 0, 2, 195, 184, 100, 0, 2, 195, 184, 114, 0, 8, 97, 98, 32, 110, 101, 2, 101, 0, 8, 97, 98, 32, 110, 101, 100, 2, 101, 0, 8, 105, 2, 101, 114, 32, 12, 0, 8, 105, 2, 121, 0, 8, 105, 103, 97, 98, 0, 8, 111, 98, 2, 32, 0, 4, 1, 97, 109, 114, 111, 110, 2, 105, 3, 50, 72, 6, 0, 1, 97, 112, 2, 111, 114, 97, 0, 1, 101, 109, 2, 111, 122, 97, 0, 1, 101, 112, 2, 117, 108, 0, 101, 8, 97, 109, 2, 108, 97, 3, 50, 72, 6, 36, 0, 4, 105, 103, 1, 101, 118, 3, 50, 72, 37, 0, 105, 103, 1, 117, 114, 103, 0, 105, 103, 1, 121, 0, 105, 103, 1, 121, 109, 0, 4, 101, 1, 97, 98, 2, 108, 101, 100, 101, 114, 12, 3, 50, 72, 108, 0, 101, 1, 97, 98, 2, 109, 101, 100, 108, 101, 109, 0, 101, 1, 97, 98, 2, 111, 112, 103, 195, 184, 114, 0, 101, 1, 97, 98, 32, 101, 108, 101, 104, 0, 101, 1, 97, 98, 32, 110, 105, 100, 0, 101, 1, 97, 98, 32, 110, 105, 109, 0, 101, 1, 97, 98, 32, 115, 101, 114, 0, 101, 1, 97, 98, 101, 110, 114, 184, 195, 106, 98, 0, 101, 1, 97, 98, 101, 118, 121, 116, 0, 101, 1, 97, 98, 114, 101, 118, 184, 195, 114, 0, 97, 108, 101, 1, 101, 112, 112, 105, 104, 99, 3, 50, 72, 109, 57, 55, 0, 101, 1, 97, 115, 2, 108, 105, 103, 3, 50, 108, 0, 7, 6, 110, 103, 0, 1, 105, 109, 97, 108, 102, 2, 111, 3, 8, 50, 81, 0, 1, 105, 102, 2, 114, 101, 3, 8, 68, 0, 1, 97, 114, 111, 2, 101, 3, 8, 68, 89, 57, 0, 2, 117, 100, 3, 50, 72, 0, 1, 105, 114, 114, 101, 100, 2, 101, 114, 3, 50, 75, 0, 4, 1, 17, 65, 2, 111, 3, 50, 81, 0, 1, 97, 2, 105, 118, 0, 1, 97, 116, 2, 101, 110, 116, 0, 1, 97, 118, 101, 2, 101, 108, 0, 1, 101, 103, 2, 105, 118, 12, 0, 1, 101, 103, 114, 111, 109, 2, 114, 121, 0, 1, 101, 104, 2, 101, 109, 0, 1, 101, 104, 2, 105, 118, 0, 1, 101, 114, 2, 195, 184, 114, 0, 1, 105, 118, 2, 195, 165, 114, 100, 0, 1, 118, 97, 110, 2, 105, 118, 0, 1, 166, 195, 107, 2, 117, 114, 117, 0, 2, 97, 0, 2, 101, 118, 195, 166, 114, 0, 2, 108, 97, 115, 0, 2, 114, 97, 100, 0, 2, 117, 108, 118, 0, 2, 121, 109, 110, 97, 115, 116, 0, 2, 195, 166, 108, 100, 0, 8, 97, 2, 17, 65, 0, 8, 105, 102, 2, 101, 114, 101, 0, 1, 97, 112, 2, 195, 166, 97, 3, 50, 81, 6, 0, 117, 1, 97, 108, 2, 115, 116, 3, 50, 81, 6, 40, 0, 101, 114, 2, 114, 105, 103, 3, 50, 81, 109, 34, 0, 101, 110, 105, 1, 105, 2, 195, 184, 3, 50, 91, 37, 50, 0, 4, 3, 68, 0, 1, 97, 102, 2, 97, 114, 109, 0, 1, 105, 102, 2, 101, 114, 101, 110, 12, 0, 4, 1, 105, 116, 2, 101, 110, 116, 3, 68, 81, 0, 1, 117, 102, 2, 101, 114, 0, 4, 1, 97, 104, 99, 2, 101, 109, 101, 110, 116, 3, 68, 89, 57, 0, 8, 97, 114, 2, 101, 114, 0, 101, 97, 1, 97, 114, 111, 2, 100, 101, 3, 68, 89, 57, 6, 110, 0, 4, 1, 97, 114, 2, 101, 114, 101, 3, 68, 91, 0, 1, 97, 114, 114, 97, 0, 1, 111, 108, 108, 97, 2, 101, 0, 101, 114, 1, 105, 102, 3, 68, 114, 0, 7, 6, 111, 110, 0, 1, 10, 2, 110, 28, 33, 3, 6, 39, 0, 4, 1, 21, 2, 28, 33, 12, 3, 6, 39, 50, 0, 1, 102, 101, 108, 10, 2, 28, 33, 0, 1, 102, 111, 10, 2, 28, 33, 0, 1, 108, 101, 10, 2, 28, 33, 0, 1, 116, 111, 102, 0, 1, 116, 111, 110, 111, 109, 0, 8, 100, 101, 107, 97, 109, 0, 110, 1, 108, 111, 107, 3, 6, 114, 50, 0, 4, 1, 98, 114, 97, 107, 3, 6, 114, 68, 0, 1, 99, 10, 2, 28, 33, 0, 1, 102, 105, 10, 2, 28, 33, 0, 1, 102, 108, 97, 2, 115, 0, 1, 106, 10, 2, 28, 33, 0, 1, 108, 10, 2, 28, 33, 0, 1, 112, 10, 2, 28, 33, 0, 1, 114, 114, 101, 112, 0, 1, 115, 166, 195, 10, 2, 28, 33, 0, 1, 116, 10, 2, 28, 33, 0, 1, 116, 114, 97, 107, 0, 8, 108, 97, 115, 0, 8, 108, 108, 97, 98, 0, 8, 108, 108, 105, 118, 97, 112, 0, 8, 115, 166, 195, 115, 0, 4, 1, 108, 116, 97, 105, 114, 116, 3, 8, 114, 50, 0, 1, 108, 116, 97, 117, 100, 0, 1, 10, 2, 101, 108, 28, 33, 3, 39, 50, 0, 1, 116, 111, 110, 111, 109, 2, 105, 3, 39, 50, 6, 0, 4, 1, 98, 98, 105, 103, 3, 114, 50, 0, 1, 98, 101, 100, 101, 114, 0, 1, 101, 110, 0, 1, 101, 114, 102, 0, 1, 103, 114, 97, 0, 1, 104, 2, 100, 0, 1, 105, 100, 97, 116, 115, 0, 1, 107, 105, 115, 107, 101, 108, 0, 1, 108, 97, 114, 100, 0, 1, 108, 102, 101, 116, 0, 1, 108, 108, 97, 103, 0, 1, 108, 111, 107, 2, 32, 0, 1, 108, 114, 101, 112, 0, 1, 108, 114, 111, 0, 1, 110, 97, 98, 105, 108, 0, 1, 112, 2, 116, 0, 1, 115, 2, 100, 0, 1, 115, 105, 98, 0, 1, 115, 105, 108, 97, 0, 1, 115, 110, 105, 98, 111, 114, 0, 1, 116, 2, 32, 0, 1, 116, 2, 105, 99, 0, 1, 116, 2, 115, 32, 0, 1, 116, 2, 115, 118, 0, 1, 116, 97, 103, 101, 109, 0, 1, 116, 97, 114, 97, 109, 0, 1, 116, 116, 103, 166, 195, 118, 100, 184, 195, 100, 0, 1, 121, 114, 98, 109, 101, 0, 2, 100, 18, 69, 0, 2, 116, 111, 108, 0, 8, 109, 2, 116, 101, 32, 0, 110, 1, 114, 100, 2, 105, 110, 103, 0, 116, 121, 1, 109, 3, 114, 50, 47, 37, 0, 100, 1, 102, 3, 114, 50, 72, 0, 100, 1, 112, 115, 3, 114, 50, 72, 6, 0, 4, 1, 98, 2, 32, 3, 114, 68, 0, 1, 98, 2, 101, 110, 32, 0, 1, 108, 97, 115, 0, 1, 108, 97, 116, 0, 1, 108, 108, 105, 118, 97, 112, 0, 1, 110, 103, 0, 1, 114, 98, 0, 1, 115, 166, 195, 115, 0, 103, 1, 107, 0, 98, 111, 110, 1, 98, 3, 114, 68, 71, 114, 50, 0, 106, 111, 117, 114, 1, 98, 3, 114, 68, 90, 6, 40, 34, 0, 7, 6, 111, 114, 0, 8, 102, 2, 32, 118, 105, 108, 100, 3, 2, 39, 34, 0, 4, 1, 102, 2, 104, 97, 108, 17, 65, 12, 12, 3, 2, 114, 0, 8, 102, 2, 21, 12, 12, 0, 8, 102, 2, 104, 111, 108, 100, 101, 0, 8, 102, 2, 115, 107, 101, 108, 108, 105, 12, 3, 2, 114, 34, 0, 101, 116, 97, 103, 8, 102, 2, 115, 111, 109, 3, 2, 114, 108, 6, 47, 110, 12, 0, 1, 116, 111, 109, 2, 101, 114, 3, 6, 39, 0, 4, 1, 100, 2, 28, 33, 12, 3, 6, 39, 34, 0, 1, 100, 97, 101, 10, 2, 28, 33, 0, 1, 102, 10, 2, 28, 33, 0, 1, 110, 101, 10, 2, 28, 33, 0, 1, 116, 10, 2, 105, 101, 28, 33, 0, 105, 117, 109, 1, 116, 10, 2, 28, 33, 12, 3, 6, 39, 34, 37, 113, 65, 0, 8, 102, 2, 101, 116, 32, 12, 3, 6, 39, 108, 0, 8, 102, 2, 116, 105, 100, 12, 3, 6, 113, 12, 0, 8, 102, 2, 100, 195, 184, 114, 12, 3, 6, 113, 51, 0, 4, 1, 102, 103, 110, 105, 115, 108, 101, 104, 2, 115, 3, 6, 114, 0, 1, 112, 101, 114, 2, 116, 101, 114, 0, 8, 102, 2, 97, 32, 12, 0, 8, 102, 2, 97, 110, 32, 12, 0, 8, 102, 2, 97, 110, 107, 195, 184, 114, 101, 110, 100, 101, 12, 0, 8, 102, 2, 97, 110, 110, 195, 166, 118, 110, 116, 12, 0, 8, 102, 2, 97, 110, 115, 97, 116, 12, 0, 8, 102, 2, 97, 110, 115, 116, 105, 108, 108, 101, 12, 0, 8, 102, 2, 97, 110, 115, 116, 195, 165, 101, 110, 100, 101, 12, 0, 8, 102, 2, 98, 101, 104, 97, 110, 100, 12, 0, 8, 102, 2, 98, 101, 104, 111, 12, 0, 8, 102, 2, 98, 101, 110, 32, 12, 0, 8, 102, 2, 98, 101, 110, 101, 110, 101, 12, 0, 8, 102, 2, 98, 101, 110, 115, 12, 0, 8, 102, 2, 98, 101, 114, 101, 100, 12, 0, 8, 102, 2, 98, 105, 108, 12, 0, 8, 102, 2, 98, 106, 101, 114, 103, 12, 0, 8, 102, 2, 98, 111, 103, 115, 116, 97, 118, 12, 0, 8, 102, 2, 98, 117, 100, 32, 12, 0, 8, 102, 2, 98, 117, 100, 115, 12, 0, 8, 102, 2, 98, 117, 110, 100, 12, 0, 8, 102, 2, 98, 195, 184, 110, 12, 0, 8, 102, 2, 99, 101, 110, 115, 117, 114, 12, 0, 8, 102, 2, 100, 97, 110, 115, 101, 114, 12, 0, 8, 102, 2, 100, 101, 108, 32, 12, 0, 8, 102, 2, 100, 111, 109, 12, 0, 8, 102, 2, 100, 114, 105, 110, 103, 12, 0, 8, 102, 2, 100, 195, 166, 107, 32, 12, 0, 8, 102, 2, 100, 195, 166, 107, 107, 101, 110, 101, 12, 0, 8, 102, 2, 100, 195, 166, 107, 115, 12, 0, 8, 102, 2, 102, 97, 100, 101, 114, 12, 0, 8, 102, 2, 102, 97, 114, 12, 0, 8, 102, 2, 102, 114, 97, 12, 0, 8, 102, 2, 102, 195, 166, 100, 114, 12, 0, 8, 102, 2, 103, 97, 110, 103, 12, 0, 8, 102, 2, 103, 101, 109, 97, 107, 12, 0, 8, 102, 2, 103, 114, 117, 110, 100, 12, 0, 8, 102, 2, 103, 195, 165, 114, 100, 12, 0, 8, 102, 2, 103, 195, 166, 110, 103, 101, 114, 12, 0, 8, 102, 2, 103, 195, 166, 114, 101, 12, 0, 8, 102, 2, 104, 97, 108, 12, 0, 8, 102, 2, 104, 97, 109, 12, 0, 8, 102, 2, 104, 97, 118, 101, 12, 0, 8, 102, 2, 104, 101, 110, 12, 0, 8, 102, 2, 104, 105, 115, 116, 111, 12, 0, 8, 102, 2, 104, 106, 117, 108, 12, 0, 8, 102, 2, 104, 111, 108, 100, 0, 8, 102, 2, 104, 111, 108, 100, 101, 116, 12, 0, 8, 102, 2, 104, 117, 100, 12, 0, 8, 102, 2, 104, 117, 115, 12, 0, 8, 102, 2, 104, 195, 165, 110, 100, 12, 0, 8, 102, 2, 104, 195, 165, 110, 100, 115, 12, 0, 8, 102, 2, 104, 195, 166, 110, 103, 12, 0, 8, 102, 2, 107, 97, 109, 109, 101, 114, 0, 8, 102, 2, 107, 97, 114, 108, 12, 0, 8, 102, 2, 107, 108, 111, 103, 12, 0, 8, 102, 2, 107, 111, 110, 116, 111, 114, 12, 0, 8, 102, 2, 107, 114, 111, 112, 12, 0, 8, 102, 2, 107, 118, 105, 110, 100, 101, 12, 0, 8, 102, 2, 107, 195, 166, 109, 112, 101, 114, 12, 0, 8, 102, 2, 107, 195, 166, 114, 108, 105, 103, 104, 101, 100, 0, 8, 102, 2, 107, 195, 184, 98, 12, 0, 8, 102, 2, 108, 97, 103, 12, 0, 8, 102, 2, 108, 97, 103, 115, 12, 0, 8, 102, 2, 108, 97, 110, 100, 12, 0, 8, 102, 2, 108, 101, 109, 12, 0, 8, 102, 2, 108, 111, 118, 101, 114, 12, 0, 8, 102, 2, 108, 121, 100, 12, 0, 8, 102, 2, 108, 121, 115, 12, 0, 8, 102, 2, 108, 195, 166, 103, 103, 101, 114, 0, 8, 102, 2, 108, 195, 166, 110, 115, 12, 0, 8, 102, 2, 108, 195, 166, 115, 101, 12, 0, 8, 102, 2, 109, 97, 108, 100, 101, 104, 121, 100, 12, 0, 8, 102, 2, 109, 97, 110, 100, 12, 0, 8, 102, 2, 109, 98, 97, 114, 12, 0, 8, 102, 2, 109, 98, 114, 195, 184, 100, 12, 0, 8, 102, 2, 109, 101, 12, 12, 0, 8, 102, 2, 109, 101, 108, 105, 103, 12, 0, 8, 102, 2, 109, 108, 101, 12, 0, 8, 102, 2, 109, 195, 166, 110, 100, 12, 0, 8, 102, 2, 117, 100, 101, 32, 12, 0, 101, 110, 100, 8, 102, 2, 101, 12, 3, 6, 114, 4, 36, 50, 0, 4, 1, 107, 97, 2, 100, 3, 6, 114, 12, 0, 1, 107, 101, 114, 2, 100, 0, 1, 112, 112, 97, 114, 2, 116, 0, 1, 112, 115, 107, 101, 2, 116, 0, 8, 107, 115, 101, 2, 116, 101, 0, 8, 112, 115, 110, 97, 114, 116, 2, 116, 0, 8, 102, 109, 111, 107, 2, 116, 3, 6, 114, 12, 19, 0, 100, 8, 107, 107, 97, 3, 6, 114, 12, 19, 72, 0, 1, 107, 101, 100, 2, 32, 3, 6, 114, 12, 34, 0, 100, 1, 99, 110, 111, 99, 2, 101, 3, 6, 114, 12, 72, 0, 4, 1, 102, 111, 114, 112, 2, 109, 97, 3, 6, 114, 34, 0, 8, 98, 97, 2, 116, 0, 8, 102, 2, 102, 117, 108, 100, 101, 110, 100, 116, 12, 0, 8, 102, 2, 108, 121, 103, 116, 101, 12, 0, 8, 102, 2, 108, 195, 166, 98, 101, 12, 0, 8, 102, 2, 109, 102, 97, 115, 116, 12, 0, 8, 102, 2, 109, 102, 114, 105, 12, 0, 8, 102, 2, 109, 103, 105, 118, 12, 0, 8, 102, 2, 109, 105, 100, 100, 97, 103, 12, 0, 8, 102, 2, 109, 107, 97, 103, 101, 12, 0, 8, 102, 2, 109, 108, 195, 166, 114, 101, 12, 0, 8, 102, 2, 109, 108, 195, 184, 115, 12, 0, 8, 102, 2, 109, 110, 105, 110, 103, 12, 0, 8, 102, 2, 109, 111, 114, 12, 0, 8, 102, 2, 109, 112, 114, 101, 115, 115, 101, 12, 0, 8, 102, 2, 109, 115, 12, 0, 8, 102, 2, 109, 116, 12, 0, 8, 102, 2, 109, 117, 101, 12, 0, 8, 102, 2, 109, 121, 110, 100, 101, 114, 12, 0, 8, 102, 2, 109, 195, 165, 108, 12, 0, 8, 102, 2, 109, 195, 184, 100, 114, 101, 12, 0, 8, 102, 2, 110, 97, 118, 110, 12, 0, 8, 102, 2, 110, 101, 109, 32, 12, 0, 8, 102, 2, 111, 109, 116, 97, 108, 101, 12, 0, 8, 102, 2, 111, 114, 100, 12, 0, 8, 102, 2, 111, 118, 101, 114, 12, 0, 8, 102, 2, 112, 97, 110, 116, 104, 97, 118, 101, 114, 12, 0, 8, 102, 2, 112, 97, 114, 116, 105, 12, 0, 8, 102, 2, 112, 111, 115, 116, 12, 0, 8, 102, 2, 112, 114, 97, 107, 116, 105, 107, 12, 0, 8, 102, 2, 112, 114, 101, 109, 105, 101, 114, 101, 12, 0, 8, 102, 2, 112, 114, 111, 103, 114, 97, 109, 109, 101, 114, 101, 12, 0, 8, 102, 2, 112, 114, 195, 184, 118, 101, 12, 0, 8, 102, 2, 112, 195, 165, 12, 0, 8, 102, 2, 114, 97, 110, 103, 12, 0, 8, 102, 2, 114, 101, 115, 116, 12, 0, 8, 102, 2, 114, 101, 116, 12, 0, 8, 102, 2, 114, 105, 100, 101, 114, 12, 0, 8, 102, 2, 114, 105, 103, 101, 12, 0, 8, 102, 2, 114, 117, 100, 101, 12, 0, 8, 102, 2, 114, 195, 165, 100, 32, 12, 0, 8, 102, 2, 115, 97, 110, 103, 101, 114, 12, 0, 8, 102, 2, 115, 97, 116, 115, 12, 0, 8, 102, 2, 115, 105, 100, 101, 12, 0, 8, 102, 2, 115, 107, 101, 12, 0, 8, 102, 2, 115, 107, 101, 108, 32, 12, 0, 8, 102, 2, 115, 107, 101, 108, 115, 98, 101, 104, 97, 110, 100, 108, 12, 0, 8, 102, 2, 115, 107, 101, 108, 115, 108, 195, 184, 115, 12, 0, 8, 102, 2, 115, 107, 101, 114, 12, 0, 8, 102, 2, 115, 107, 110, 12, 0, 8, 102, 2, 115, 107, 111, 108, 12, 0, 8, 102, 2, 115, 107, 114, 105, 102, 116, 12, 0, 8, 102, 2, 115, 107, 117, 100, 12, 0, 8, 102, 2, 115, 107, 121, 108, 12, 0, 8, 102, 2, 115, 107, 195, 166, 114, 101, 12, 0, 8, 102, 2, 115, 107, 195, 166, 114, 109, 12, 0, 8, 102, 2, 115, 108, 97, 103, 12, 0, 8, 102, 2, 115, 108, 97, 103, 32, 12, 0, 8, 102, 2, 115, 108, 97, 103, 115, 12, 0, 8, 102, 2, 115, 109, 97, 103, 12, 0, 8, 102, 2, 115, 111, 109, 109, 101, 114, 12, 0, 8, 102, 2, 115, 111, 114, 103, 12, 0, 8, 102, 2, 115, 112, 97, 110, 100, 12, 0, 8, 102, 2, 115, 112, 105, 108, 32, 12, 0, 8, 102, 2, 115, 112, 105, 108, 108, 101, 110, 101, 12, 0, 8, 102, 2, 115, 112, 105, 108, 108, 101, 116, 12, 0, 8, 102, 2, 115, 112, 105, 114, 12, 0, 8, 102, 2, 115, 112, 114, 105, 110, 103, 12, 0, 8, 102, 2, 115, 112, 195, 166, 110, 100, 116, 12, 0, 8, 102, 2, 115, 116, 97, 100, 12, 0, 8, 102, 2, 115, 116, 97, 110, 100, 101, 114, 12, 0, 8, 102, 2, 115, 116, 97, 118, 101, 108, 115, 101, 12, 0, 8, 102, 2, 115, 116, 97, 118, 110, 12, 0, 8, 102, 2, 115, 116, 98, 111, 116, 97, 110, 105, 107, 12, 0, 8, 102, 2, 115, 116, 107, 97, 110, 100, 105, 100, 97, 116, 12, 0, 8, 102, 2, 115, 116, 108, 105, 103, 12, 0, 8, 102, 2, 115, 116, 109, 97, 110, 100, 12, 0, 8, 102, 2, 115, 116, 109, 195, 166, 115, 115, 105, 103, 12, 0, 8, 102, 2, 115, 116, 117, 100, 105, 101, 12, 0, 8, 102, 2, 115, 116, 117, 100, 105, 117, 109, 12, 0, 8, 102, 2, 115, 116, 117, 101, 12, 0, 8, 102, 2, 115, 116, 118, 195, 166, 115, 101, 110, 12, 0, 8, 102, 2, 115, 116, 122, 111, 111, 108, 111, 103, 105, 12, 0, 8, 102, 2, 115, 116, 195, 166, 100, 101, 114, 12, 0, 8, 102, 2, 115, 116, 195, 166, 118, 110, 12, 0, 8, 102, 2, 115, 118, 97, 114, 32, 12, 0, 8, 102, 2, 115, 118, 97, 114, 101, 114, 12, 0, 8, 102, 2, 115, 118, 97, 114, 115, 12, 0, 8, 102, 2, 115, 195, 165, 32, 12, 0, 8, 102, 2, 115, 195, 166, 100, 101, 12, 0, 8, 102, 2, 115, 195, 166, 116, 12, 0, 8, 102, 2, 116, 97, 110, 100, 12, 0, 8, 102, 2, 116, 97, 110, 100, 115, 12, 0, 8, 102, 2, 116, 101, 103, 110, 32, 12, 0, 8, 102, 2, 116, 101, 103, 110, 105, 110, 103, 115, 114, 101, 116, 12, 0, 8, 102, 2, 116, 101, 107, 115, 116, 12, 0, 8, 102, 2, 116, 101, 108, 116, 12, 0, 8, 102, 2, 116, 102, 97, 114, 101, 110, 100, 101, 12, 0, 8, 102, 2, 116, 105, 108, 12, 0, 8, 102, 2, 116, 108, 195, 184, 98, 101, 110, 100, 101, 12, 0, 8, 102, 2, 116, 111, 103, 12, 0, 8, 102, 2, 116, 111, 118, 12, 0, 8, 102, 2, 116, 114, 97, 112, 112, 101, 12, 0, 8, 102, 2, 116, 114, 105, 110, 32, 12, 0, 8, 102, 2, 116, 114, 105, 110, 115, 12, 0, 8, 102, 2, 116, 114, 111, 112, 12, 0, 8, 102, 2, 116, 114, 121, 107, 12, 0, 8, 102, 2, 116, 115, 195, 166, 116, 116, 101, 12, 0, 8, 102, 2, 116, 117, 110, 103, 101, 12, 0, 8, 102, 2, 116, 195, 166, 110, 100, 101, 114, 12, 0, 8, 102, 2, 116, 195, 166, 112, 112, 101, 12, 0, 8, 102, 2, 117, 100, 12, 0, 8, 102, 2, 118, 97, 108, 103, 12, 0, 8, 102, 2, 118, 97, 114, 109, 12, 0, 8, 102, 2, 118, 97, 114, 115, 12, 0, 8, 102, 2, 118, 97, 115, 107, 32, 12, 0, 8, 102, 2, 118, 101, 106, 101, 110, 12, 0, 8, 102, 2, 118, 195, 166, 114, 101, 108, 115, 101, 12, 0, 8, 102, 2, 195, 165, 100, 12, 0, 8, 102, 2, 195, 165, 114, 12, 0, 116, 97, 108, 101, 114, 43, 8, 102, 3, 6, 114, 34, 47, 110, 55, 114, 0, 109, 115, 115, 97, 103, 43, 8, 102, 2, 25, 3, 6, 114, 34, 65, 19, 89, 4, 89, 35, 0, 109, 101, 114, 8, 102, 2, 32, 12, 3, 6, 114, 34, 65, 114, 0, 4, 100, 1, 118, 2, 105, 3, 6, 114, 34, 72, 0, 100, 2, 101, 110, 116, 108, 105, 103, 12, 0, 100, 2, 110, 105, 110, 0, 101, 8, 102, 2, 12, 12, 3, 6, 115, 12, 108, 0, 1, 10, 2, 105, 115, 107, 28, 33, 3, 7, 39, 0, 1, 10, 2, 101, 114, 28, 33, 3, 7, 39, 12, 0, 1, 21, 2, 28, 33, 12, 3, 8, 8, 114, 0, 101, 1, 17, 67, 2, 32, 3, 39, 12, 114, 0, 4, 1, 115, 2, 116, 3, 39, 34, 0, 1, 115, 2, 116, 101, 0, 1, 116, 115, 2, 116, 0, 1, 118, 2, 18, 76, 12, 0, 1, 118, 115, 2, 101, 12, 0, 8, 2, 97, 0, 8, 102, 2, 101, 108, 32, 12, 0, 8, 102, 2, 111, 114, 100, 110, 0, 8, 110, 2, 100, 0, 100, 8, 2, 114, 101, 116, 12, 0, 117, 100, 101, 110, 8, 102, 2, 32, 12, 3, 39, 34, 6, 40, 86, 20, 50, 0, 101, 110, 115, 105, 115, 8, 102, 2, 107, 3, 39, 34, 6, 111, 50, 89, 37, 89, 0, 4, 101, 8, 102, 2, 108, 32, 12, 3, 39, 34, 6, 111, 55, 0, 101, 8, 102, 2, 108, 108, 101, 12, 0, 101, 108, 1, 109, 0, 109, 3, 39, 34, 65, 0, 4, 100, 1, 107, 2, 114, 101, 110, 103, 3, 39, 34, 72, 0, 100, 1, 109, 2, 101, 114, 0, 100, 1, 116, 2, 101, 110, 101, 110, 12, 0, 100, 8, 116, 2, 12, 12, 0, 100, 114, 117, 112, 3, 39, 34, 72, 34, 115, 71, 0, 100, 101, 1, 98, 2, 110, 100, 101, 3, 39, 34, 109, 0, 4, 2, 97, 108, 3, 39, 51, 0, 100, 1, 109, 2, 101, 116, 0, 100, 2, 12, 12, 0, 100, 2, 101, 110, 101, 12, 0, 4, 100, 1, 106, 2, 97, 110, 3, 39, 51, 72, 0, 100, 1, 106, 2, 105, 0, 100, 101, 97, 117, 120, 1, 98, 3, 39, 51, 72, 6, 39, 0, 100, 105, 1, 110, 2, 115, 107, 3, 39, 51, 72, 37, 0, 100, 1, 106, 2, 101, 110, 3, 39, 114, 0, 4, 1, 98, 2, 116, 3, 113, 0, 1, 115, 2, 116, 17, 65, 0, 1, 118, 2, 116, 0, 4, 1, 107, 2, 116, 3, 113, 12, 0, 1, 107, 2, 116, 17, 65, 0, 1, 116, 115, 2, 109, 0, 100, 1, 104, 2, 101, 3, 113, 12, 72, 0, 2, 100, 101, 110, 3, 113, 34, 0, 4, 1, 102, 3, 114, 0, 1, 102, 2, 101, 110, 0, 1, 102, 2, 116, 101, 114, 12, 0, 1, 109, 117, 104, 0, 1, 116, 107, 101, 114, 0, 1, 116, 107, 101, 115, 0, 1, 118, 108, 97, 0, 8, 2, 105, 0, 8, 102, 2, 102, 97, 110, 103, 12, 0, 8, 102, 2, 102, 101, 108, 116, 12, 0, 8, 102, 2, 102, 105, 108, 109, 12, 0, 8, 102, 2, 102, 106, 111, 114, 12, 0, 8, 102, 2, 102, 111, 114, 100, 12, 0, 8, 102, 2, 102, 111, 114, 102, 111, 100, 12, 0, 8, 102, 2, 102, 111, 114, 115, 116, 195, 166, 114, 107, 12, 0, 8, 102, 2, 102, 111, 114, 115, 195, 184, 103, 12, 0, 8, 102, 2, 102, 111, 114, 121, 115, 101, 114, 117, 109, 12, 0, 8, 102, 2, 102, 195, 184, 100, 100, 101, 114, 12, 0, 8, 102, 2, 103, 97, 115, 116, 12, 0, 8, 102, 2, 107, 97, 110, 116, 0, 8, 102, 2, 107, 195, 184, 114, 115, 101, 108, 115, 114, 101, 116, 0, 1, 102, 2, 21, 3, 114, 4, 0, 4, 1, 10, 2, 105, 28, 33, 12, 3, 114, 6, 0, 8, 102, 2, 101, 108, 115, 107, 12, 0, 8, 102, 2, 108, 121, 100, 101, 110, 100, 101, 12, 0, 101, 8, 102, 2, 110, 12, 3, 114, 6, 36, 12, 0, 101, 118, 8, 102, 2, 105, 103, 101, 3, 114, 6, 36, 12, 84, 0, 4, 101, 110, 107, 108, 8, 102, 2, 101, 12, 3, 114, 6, 36, 50, 49, 55, 0, 101, 110, 107, 108, 8, 102, 2, 105, 110, 103, 0, 4, 1, 109, 2, 102, 3, 114, 12, 0, 1, 109, 2, 109, 0, 1, 109, 2, 115, 101, 0, 1, 112, 115, 2, 116, 0, 1, 118, 2, 101, 12, 0, 8, 102, 2, 114, 105, 110, 103, 32, 0, 8, 102, 2, 114, 105, 110, 103, 101, 110, 0, 1, 102, 2, 116, 3, 114, 12, 19, 0, 108, 101, 97, 110, 115, 8, 3, 114, 12, 55, 36, 50, 89, 0, 4, 100, 1, 102, 2, 12, 3, 114, 12, 72, 0, 100, 1, 103, 2, 111, 110, 0, 100, 8, 108, 2, 32, 0, 116, 104, 1, 110, 3, 114, 12, 87, 0, 103, 101, 1, 109, 3, 114, 12, 108, 0, 4, 1, 110, 2, 109, 3, 114, 34, 0, 1, 110, 2, 115, 107, 0, 2, 100, 114, 101, 12, 0, 2, 105, 101, 110, 116, 0, 2, 116, 111, 0, 8, 102, 2, 103, 195, 165, 114, 115, 12, 0, 8, 102, 2, 114, 101, 116, 110, 105, 12, 0, 109, 111, 110, 8, 104, 3, 114, 34, 65, 6, 39, 50, 0, 4, 100, 1, 107, 2, 101, 108, 3, 114, 34, 72, 0, 100, 1, 118, 2, 101, 0, 100, 1, 118, 104, 2, 97, 110, 0, 100, 2, 101, 110, 12, 0, 100, 2, 101, 110, 101, 110, 12, 0, 100, 2, 105, 110, 12, 0, 100, 2, 110, 101, 12, 0, 100, 2, 114, 101, 116, 105, 108, 12, 0, 100, 8, 108, 2, 101, 114, 32, 0, 4, 100, 1, 98, 2, 101, 108, 3, 114, 34, 72, 6, 0, 100, 2, 114, 117, 107, 0, 100, 111, 110, 110, 97, 110, 115, 3, 114, 34, 72, 39, 50, 6, 110, 50, 89, 0, 101, 1, 102, 110, 101, 103, 2, 110, 12, 3, 114, 36, 12, 0, 108, 121, 115, 116, 8, 102, 3, 114, 55, 6, 118, 89, 72, 0, 4, 100, 1, 102, 2, 195, 166, 3, 114, 72, 6, 0, 100, 1, 102, 2, 195, 184, 0, 101, 1, 102, 2, 115, 17, 67, 3, 115, 12, 108, 0, 7, 6, 112, 104, 0, 2, 105, 108, 3, 83, 0, 111, 101, 3, 83, 37, 0, 105, 108, 108, 105, 112, 112, 101, 3, 83, 37, 55, 6, 37, 12, 48, 0, 105, 108, 97, 100, 101, 108, 112, 104, 105, 97, 3, 83, 37, 55, 110, 72, 6, 109, 55, 83, 37, 110, 0, 7, 6, 116, 105, 0, 4, 1, 105, 99, 105, 100, 110, 101, 112, 112, 97, 2, 115, 3, 8, 47, 37, 0, 1, 105, 103, 110, 105, 110, 101, 109, 2, 115, 0, 1, 105, 103, 110, 121, 114, 97, 108, 2, 115, 0, 1, 105, 107, 97, 114, 2, 115, 0, 1, 105, 107, 110, 111, 114, 98, 2, 115, 0, 1, 105, 108, 117, 108, 108, 101, 99, 2, 115, 0, 1, 105, 114, 101, 116, 102, 105, 100, 2, 115, 0, 1, 105, 114, 116, 115, 97, 103, 2, 115, 0, 1, 105, 116, 97, 112, 101, 104, 2, 115, 0, 1, 110, 97, 114, 101, 2, 115, 0, 115, 1, 115, 97, 112, 3, 47, 6, 37, 89, 0, 108, 1, 114, 2, 32, 3, 47, 36, 55, 0, 4, 108, 2, 98, 97, 103, 101, 3, 47, 36, 55, 6, 0, 108, 2, 102, 111, 114, 110, 0, 108, 2, 102, 114, 101, 100, 115, 0, 108, 2, 102, 195, 166, 108, 100, 105, 103, 0, 108, 2, 102, 195, 166, 108, 108, 101, 115, 0, 108, 2, 103, 111, 100, 101, 104, 97, 118, 101, 110, 100, 101, 0, 108, 2, 103, 111, 100, 101, 115, 101, 0, 108, 2, 103, 111, 100, 101, 115, 101, 100, 100, 101, 108, 0, 108, 2, 103, 111, 100, 101, 115, 107, 114, 105, 118, 101, 0, 108, 2, 103, 114, 117, 110, 100, 108, 105, 103, 103, 101, 110, 100, 101, 0, 108, 2, 103, 195, 166, 110, 103, 101, 108, 105, 103, 0, 108, 2, 105, 110, 116, 101, 116, 103, 195, 184, 114, 101, 0, 108, 2, 105, 110, 116, 101, 116, 103, 195, 184, 114, 101, 108, 115, 101, 0, 108, 2, 107, 101, 110, 100, 101, 103, 105, 118, 101, 0, 108, 2, 107, 101, 110, 100, 101, 103, 105, 118, 101, 108, 115, 101, 0, 108, 2, 108, 97, 100, 101, 108, 105, 103, 0, 108, 2, 108, 105, 103, 101, 0, 108, 2, 108, 105, 103, 101, 109, 101, 100, 0, 108, 2, 108, 121, 107, 107, 101, 0, 108, 2, 111, 118, 101, 114, 115, 0, 108, 2, 112, 97, 115, 0, 108, 2, 114, 101, 116, 116, 101, 108, 195, 166, 103, 103, 101, 0, 108, 2, 114, 101, 116, 116, 101, 118, 105, 115, 101, 0, 108, 2, 114, 101, 116, 116, 101, 118, 105, 115, 110, 105, 110, 103, 0, 108, 2, 115, 97, 109, 109, 101, 110, 0, 108, 2, 115, 107, 97, 100, 101, 107, 111, 109, 109, 101, 110, 0, 108, 2, 115, 107, 97, 100, 101, 107, 111, 109, 109, 101, 116, 0, 108, 2, 115, 107, 97, 100, 101, 107, 111, 109, 115, 116, 0, 108, 2, 115, 116, 101, 100, 101, 107, 111, 109, 115, 116, 0, 108, 2, 115, 116, 101, 100, 101, 108, 105, 103, 0, 108, 2, 115, 116, 101, 100, 101, 118, 195, 166, 114, 0, 108, 2, 115, 116, 101, 100, 101, 118, 195, 166, 114, 101, 108, 115, 101, 0, 108, 2, 115, 116, 101, 100, 101, 118, 195, 166, 114, 101, 110, 100, 101, 0, 108, 2, 115, 116, 114, 195, 166, 107, 107, 101, 108, 105, 103, 0, 108, 2, 115, 121, 110, 101, 107, 111, 109, 115, 116, 0, 108, 2, 115, 121, 110, 101, 108, 97, 100, 101, 110, 100, 101, 0, 1, 115, 97, 98, 2, 111, 110, 3, 47, 37, 0, 4, 1, 10, 2, 111, 110, 12, 3, 91, 0, 1, 97, 112, 2, 101, 110, 116, 0, 1, 107, 97, 2, 101, 0, 1, 107, 101, 108, 2, 101, 0, 1, 111, 118, 107, 2, 101, 110, 0, 2, 195, 184, 115, 12, 0, 7, 6, 195, 165, 0, 4, 1, 112, 110, 101, 118, 111, 2, 32, 3, 6, 113, 0, 1, 112, 165, 195, 103, 2, 109, 111, 100, 0, 1, 116, 115, 100, 111, 109, 105, 117, 2, 101, 108, 105, 103, 0, 114, 1, 110, 114, 111, 118, 104, 3, 6, 113, 19, 0, 98, 101, 110, 116, 108, 105, 103, 1, 104, 114, 111, 102, 3, 6, 113, 71, 109, 50, 47, 55, 37, 0, 1, 115, 97, 106, 2, 32, 3, 6, 114, 0, 4, 3, 113, 0, 1, 103, 2, 116, 117, 114, 0, 1, 108, 115, 103, 110, 105, 100, 110, 166, 195, 116, 2, 115, 0, 1, 108, 115, 110, 97, 0, 1, 109, 2, 100, 101, 12, 12, 0, 1, 109, 2, 108, 105, 110, 103, 12, 12, 0, 1, 109, 115, 103, 97, 108, 115, 2, 108, 0, 1, 109, 115, 103, 114, 184, 195, 112, 115, 2, 108, 0, 1, 109, 115, 114, 101, 100, 111, 109, 2, 108, 0, 1, 112, 2, 115, 107, 101, 0, 1, 114, 2, 100, 12, 0, 1, 114, 103, 2, 100, 0, 1, 114, 103, 2, 110, 101, 0, 1, 115, 0, 114, 100, 1, 103, 3, 113, 12, 0, 114, 100, 101, 1, 103, 3, 113, 12, 20, 108, 0, 100, 1, 98, 2, 12, 3, 113, 86, 0, 100, 110, 101, 1, 114, 116, 2, 116, 3, 113, 86, 50, 109, 0, 114, 100, 101, 110, 3, 113, 114, 50, 0, 4, 1, 100, 2, 100, 121, 114, 3, 114, 0, 1, 106, 116, 115, 0, 1, 108, 2, 114, 0, 1, 108, 98, 2, 21, 0, 1, 108, 115, 2, 98, 114, 111, 107, 0, 1, 108, 115, 2, 115, 0, 1, 109, 2, 108, 108, 195, 184, 115, 12, 0, 1, 109, 2, 108, 116, 105, 100, 12, 0, 1, 109, 2, 116, 0, 1, 109, 115, 2, 17, 67, 21, 12, 0, 1, 112, 2, 115, 0, 1, 112, 115, 2, 100, 111, 109, 0, 1, 112, 115, 2, 107, 111, 110, 101, 0, 1, 112, 115, 2, 107, 118, 105, 110, 100, 101, 0, 1, 112, 115, 2, 109, 97, 110, 100, 0, 1, 112, 115, 2, 109, 195, 166, 110, 100, 0, 1, 114, 2, 98, 116, 0, 1, 114, 2, 100, 100, 12, 0, 1, 114, 2, 100, 102, 12, 0, 1, 114, 2, 100, 103, 12, 0, 1, 114, 2, 100, 104, 12, 0, 1, 114, 2, 100, 108, 195, 184, 115, 0, 1, 114, 2, 100, 109, 97, 110, 100, 0, 1, 114, 2, 100, 110, 12, 0, 1, 114, 2, 100, 115, 108, 0, 1, 114, 2, 100, 115, 110, 97, 114, 0, 1, 114, 2, 100, 115, 112, 0, 1, 114, 2, 100, 118, 105, 108, 100, 0, 1, 114, 2, 108, 97, 109, 0, 1, 114, 2, 109, 97, 116, 101, 114, 105, 97, 108, 0, 1, 114, 2, 115, 101, 106, 108, 0, 1, 114, 2, 116, 0, 1, 114, 18, 73, 2, 116, 0, 1, 114, 103, 2, 21, 0, 1, 114, 107, 115, 2, 112, 0, 1, 114, 116, 2, 100, 116, 0, 1, 114, 116, 115, 2, 100, 195, 184, 100, 0, 1, 114, 116, 115, 2, 102, 111, 114, 107, 111, 114, 116, 0, 1, 114, 116, 115, 2, 104, 97, 116, 0, 1, 114, 116, 115, 2, 109, 97, 110, 100, 0, 1, 114, 116, 115, 2, 109, 195, 166, 110, 100, 0, 1, 115, 2, 32, 102, 195, 165, 0, 1, 115, 2, 32, 115, 110, 97, 114, 116, 0, 1, 115, 2, 100, 0, 1, 115, 2, 107, 97, 108, 100, 0, 1, 115, 2, 109, 195, 166, 110, 100, 0, 1, 115, 2, 116, 0, 1, 115, 2, 118, 101, 108, 0, 1, 115, 116, 108, 97, 0, 1, 116, 2, 108, 109, 111, 0, 1, 118, 2, 100, 116, 0, 2, 108, 116, 105, 0, 2, 110, 100, 0, 2, 116, 0, 8, 112, 0, 8, 115, 32, 114, 97, 118, 2, 32, 0, 114, 3, 114, 12, 0, 114, 1, 104, 3, 114, 12, 19, 0, 114, 100, 101, 1, 104, 3, 114, 12, 20, 108, 0, 114, 100, 101, 115, 116, 1, 104, 3, 114, 12, 34, 13, 89, 47, 0, 114, 101, 3, 114, 12, 108, 0, 114, 101, 114, 3, 114, 12, 114, 20, 0, 100, 2, 115, 3, 114, 86, 0, 115, 101, 8, 112, 3, 114, 89, 36, 0, 7, 6, 195, 166, 0, 4, 1, 100, 101, 108, 166, 195, 107, 2, 103, 103, 101, 3, 6, 109, 0, 1, 102, 111, 114, 116, 0, 1, 116, 115, 101, 106, 97, 109, 2, 116, 0, 1, 118, 101, 103, 2, 114, 0, 1, 118, 115, 101, 98, 2, 114, 32, 0, 8, 100, 97, 102, 2, 115, 101, 0, 8, 108, 97, 112, 0, 8, 108, 101, 99, 114, 111, 112, 2, 110, 0, 8, 108, 105, 98, 117, 106, 0, 8, 108, 105, 108, 97, 103, 2, 101, 114, 0, 8, 108, 121, 112, 111, 114, 112, 2, 101, 114, 0, 8, 109, 97, 114, 97, 2, 101, 114, 0, 8, 109, 103, 121, 112, 0, 8, 109, 111, 100, 2, 110, 101, 0, 8, 110, 97, 97, 110, 97, 107, 2, 101, 114, 0, 8, 110, 97, 97, 110, 97, 107, 2, 101, 114, 0, 8, 110, 101, 104, 116, 97, 2, 101, 114, 0, 8, 112, 111, 114, 117, 101, 2, 101, 114, 0, 8, 114, 97, 122, 97, 110, 2, 101, 114, 0, 8, 114, 98, 101, 104, 2, 101, 114, 0, 8, 114, 103, 105, 109, 2, 110, 101, 0, 8, 114, 105, 115, 97, 110, 2, 101, 114, 0, 8, 114, 111, 103, 97, 104, 116, 121, 112, 2, 101, 114, 0, 8, 114, 111, 109, 2, 110, 101, 12, 0, 8, 114, 117, 107, 105, 112, 101, 2, 101, 114, 0, 8, 115, 105, 114, 97, 102, 2, 101, 114, 0, 8, 116, 110, 97, 114, 97, 107, 2, 110, 101, 0, 8, 116, 110, 111, 102, 2, 110, 101, 0, 4, 1, 102, 2, 114, 101, 3, 6, 109, 12, 0, 1, 104, 102, 97, 2, 110, 103, 105, 103, 0, 114, 114, 101, 1, 118, 115, 101, 100, 3, 6, 110, 34, 108, 0, 110, 1, 114, 102, 101, 114, 3, 6, 110, 68, 0, 8, 114, 116, 114, 111, 112, 2, 116, 3, 6, 111, 0, 8, 116, 115, 109, 111, 2, 110, 100, 3, 7, 109, 0, 114, 1, 10, 2, 28, 33, 3, 7, 109, 34, 0, 4, 3, 109, 0, 1, 114, 2, 17, 67, 18, 69, 0, 1, 114, 2, 18, 67, 0, 1, 114, 2, 115, 0, 1, 114, 100, 2, 98, 101, 114, 0, 1, 114, 100, 2, 110, 12, 0, 1, 114, 107, 2, 32, 0, 1, 114, 111, 102, 2, 100, 108, 101, 0, 1, 114, 112, 2, 103, 110, 0, 1, 114, 112, 2, 107, 0, 1, 114, 112, 2, 115, 116, 97, 0, 1, 114, 112, 2, 115, 116, 101, 114, 101, 0, 1, 114, 116, 0, 1, 114, 116, 2, 110, 12, 0, 2, 17, 67, 11, 17, 65, 0, 2, 108, 12, 0, 101, 1, 116, 2, 114, 0, 2, 103, 121, 112, 116, 3, 109, 6, 0, 4, 1, 112, 115, 2, 110, 101, 3, 109, 12, 0, 1, 114, 2, 17, 67, 17, 65, 0, 1, 114, 116, 2, 17, 67, 101, 12, 12, 0, 2, 17, 67, 17, 65, 0, 114, 103, 101, 1, 17, 67, 3, 109, 12, 34, 40, 13, 0, 114, 103, 101, 114, 1, 118, 3, 109, 12, 34, 40, 114, 0, 103, 101, 1, 116, 3, 109, 12, 57, 13, 0, 118, 108, 3, 109, 40, 55, 0, 114, 105, 110, 100, 101, 3, 109, 51, 50, 13, 0, 108, 100, 1, 107, 2, 114, 3, 109, 55, 0, 108, 100, 2, 114, 12, 3, 109, 55, 72, 0, 103, 1, 114, 116, 2, 104, 101, 100, 3, 109, 57, 0, 100, 105, 1, 114, 112, 2, 107, 97, 110, 116, 3, 109, 72, 37, 0, 103, 1, 114, 184, 195, 114, 3, 109, 81, 0, 100, 105, 1, 114, 112, 3, 109, 86, 0, 114, 114, 101, 3, 110, 34, 108, 0, 4, 1, 114, 3, 111, 0, 1, 114, 2, 17, 67, 11, 17, 65, 0, 1, 114, 2, 18, 67, 11, 0, 1, 114, 2, 18, 67, 116, 0, 1, 114, 2, 100, 101, 12, 12, 0, 1, 114, 2, 109, 0, 1, 114, 2, 116, 12, 0, 1, 114, 18, 73, 2, 17, 67, 0, 1, 114, 103, 2, 115, 0, 1, 114, 112, 2, 115, 116, 0, 1, 114, 112, 115, 2, 107, 107, 0, 1, 114, 114, 2, 17, 67, 101, 114, 12, 0, 1, 114, 116, 2, 17, 67, 0, 1, 114, 116, 2, 110, 103, 12, 0, 8, 114, 116, 2, 98, 101, 110, 12, 12, 0, 7, 6, 195, 169, 0, 3, 6, 36, 0, 7, 6, 195, 184, 0, 103, 1, 108, 3, 6, 114, 57, 0, 4, 1, 100, 114, 111, 110, 2, 115, 116, 3, 6, 118, 0, 1, 100, 121, 115, 2, 115, 116, 0, 1, 103, 108, 101, 118, 2, 114, 101, 110, 104, 101, 100, 0, 8, 102, 102, 117, 97, 104, 99, 2, 114, 0, 8, 106, 108, 105, 109, 0, 8, 109, 97, 2, 98, 101, 0, 8, 110, 97, 109, 2, 118, 114, 101, 0, 8, 118, 101, 110, 0, 4, 1, 107, 115, 98, 111, 2, 110, 3, 6, 118, 12, 0, 1, 109, 105, 2, 100, 101, 107, 111, 109, 0, 8, 110, 2, 100, 21, 0, 114, 101, 1, 105, 2, 102, 97, 108, 100, 101, 110, 100, 101, 3, 6, 118, 12, 114, 0, 4, 1, 103, 114, 117, 98, 2, 106, 115, 3, 6, 119, 0, 1, 108, 116, 115, 114, 101, 98, 111, 2, 106, 116, 110, 97, 110, 116, 0, 8, 108, 108, 97, 104, 2, 106, 0, 4, 1, 18, 74, 2, 103, 3, 114, 0, 1, 104, 2, 106, 0, 2, 106, 101, 0, 106, 43, 3, 114, 12, 57, 0, 4, 103, 1, 100, 2, 110, 3, 114, 57, 0, 103, 1, 103, 2, 108, 0, 103, 1, 112, 115, 2, 32, 0, 103, 1, 112, 115, 2, 101, 110, 0, 4, 3, 118, 0, 1, 18, 73, 2, 103, 0, 1, 108, 2, 115, 0, 1, 114, 2, 12, 0, 1, 114, 2, 18, 74, 101, 0, 1, 114, 2, 103, 101, 108, 115, 101, 0, 1, 114, 2, 103, 116, 101, 0, 1, 114, 2, 118, 101, 114, 0, 1, 114, 100, 2, 110, 0, 1, 114, 100, 2, 118, 101, 116, 0, 1, 114, 100, 101, 98, 2, 118, 0, 1, 114, 101, 98, 2, 118, 101, 0, 1, 114, 111, 102, 2, 103, 0, 1, 114, 112, 2, 118, 0, 1, 115, 2, 103, 0, 2, 100, 100, 0, 4, 1, 114, 2, 109, 101, 114, 3, 118, 12, 0, 2, 100, 101, 0, 95, 1, 115, 0, 103, 1, 114, 111, 102, 2, 32, 3, 118, 12, 19, 0, 114, 1, 112, 115, 2, 103, 3, 118, 12, 34, 0, 4, 114, 101, 3, 118, 12, 114, 0, 114, 101, 95, 0, 4, 114, 1, 112, 115, 2, 103, 115, 3, 118, 34, 0, 114, 103, 101, 114, 1, 112, 115, 2, 32, 0, 114, 101, 2, 106, 115, 101, 3, 118, 34, 35, 0, 114, 101, 1, 115, 2, 100, 110, 105, 3, 118, 34, 109, 0, 4, 103, 1, 109, 115, 2, 32, 115, 105, 103, 3, 118, 57, 0, 103, 8, 2, 32, 0, 100, 116, 8, 110, 2, 32, 3, 118, 72, 0, 4, 103, 1, 108, 107, 2, 116, 3, 118, 81, 0, 103, 1, 110, 2, 116, 101, 114, 110, 0, 103, 103, 1, 108, 103, 0, 100, 1, 107, 3, 118, 86, 0, 4, 1, 17, 67, 2, 106, 12, 3, 119, 0, 1, 114, 2, 18, 74, 0, 1, 114, 2, 103, 0, 1, 114, 2, 118, 0, 1, 114, 101, 100, 110, 111, 98, 2, 118, 0, 1, 114, 114, 97, 110, 2, 118, 0, 2, 106, 110, 0, 8, 114, 2, 118, 101, 110, 0, 106, 101, 114, 3, 119, 57, 114, 0, 115, 1, 10, 2, 28, 33, 3, 6, 118, 12, 89, 0, 114, 1, 10, 2, 28, 33, 3, 7, 118, 34, 0, 7, 6, 39, 0, 101, 114, 2, 32, 14, 128, 128, 131, 3, 2, 114, 0, 101, 114, 110, 101, 2, 32, 14, 128, 128, 133, 3, 2, 114, 50, 13, 0, 101, 114, 110, 101, 115, 2, 32, 14, 128, 128, 134, 3, 2, 114, 50, 13, 89, 0, 101, 110, 2, 32, 14, 128, 128, 131, 3, 13, 50, 0, 101, 116, 2, 32, 14, 128, 128, 131, 3, 13, 86, 0, 115, 2, 32, 14, 128, 128, 130, 3, 89, 0, 101, 114, 101, 2, 32, 14, 128, 128, 132, 3, 114, 34, 114, 0, 7, 6, 97, 0, 103, 2, 110, 111, 115, 3, 2, 35, 81, 0, 4, 117, 2, 32, 112, 97, 105, 114, 3, 2, 39, 0, 117, 2, 32, 114, 101, 118, 111, 105, 114, 0, 1, 108, 2, 107, 114, 3, 2, 110, 0, 2, 109, 112, 3, 2, 112, 0, 102, 8, 114, 101, 100, 2, 32, 3, 4, 110, 0, 4, 1, 100, 114, 101, 116, 115, 109, 97, 2, 109, 3, 6, 35, 0, 1, 102, 108, 105, 116, 2, 110, 103, 101, 0, 1, 103, 110, 101, 2, 110, 103, 0, 1, 103, 110, 101, 2, 110, 103, 0, 1, 114, 107, 115, 110, 101, 112, 112, 97, 114, 2, 108, 100, 101, 0, 1, 116, 115, 101, 103, 2, 112, 111, 0, 8, 108, 97, 103, 2, 107, 115, 101, 0, 8, 108, 111, 112, 2, 107, 0, 8, 112, 109, 111, 107, 2, 107, 116, 0, 8, 114, 97, 116, 97, 107, 2, 107, 116, 0, 8, 114, 116, 110, 111, 107, 2, 107, 116, 0, 8, 114, 116, 115, 98, 97, 2, 107, 116, 0, 8, 114, 116, 115, 107, 101, 2, 107, 116, 0, 8, 115, 107, 101, 2, 107, 116, 0, 8, 115, 111, 107, 2, 107, 0, 8, 115, 115, 97, 109, 2, 107, 114, 101, 0, 8, 116, 101, 2, 112, 101, 0, 8, 116, 110, 105, 2, 107, 116, 0, 8, 116, 110, 111, 107, 2, 107, 116, 0, 8, 116, 112, 97, 107, 2, 106, 110, 0, 109, 1, 114, 103, 10, 2, 109, 28, 33, 12, 0, 1, 108, 115, 105, 2, 109, 3, 6, 35, 12, 0, 117, 8, 115, 115, 105, 98, 3, 6, 35, 12, 58, 0, 117, 114, 101, 114, 8, 115, 111, 110, 105, 100, 3, 6, 35, 40, 34, 114, 0, 117, 114, 8, 115, 111, 110, 105, 100, 3, 6, 35, 40, 114, 0, 110, 103, 101, 108, 111, 1, 108, 101, 104, 99, 105, 109, 3, 6, 35, 50, 75, 108, 55, 39, 0, 105, 1, 116, 101, 100, 2, 108, 3, 6, 35, 57, 0, 117, 1, 110, 111, 114, 116, 115, 97, 2, 116, 3, 6, 35, 58, 0, 109, 1, 114, 103, 10, 2, 28, 33, 12, 3, 6, 35, 65, 0, 103, 116, 105, 103, 1, 10, 2, 28, 33, 12, 3, 6, 35, 81, 47, 37, 0, 117, 120, 1, 103, 3, 6, 39, 0, 105, 115, 101, 3, 6, 109, 12, 89, 13, 0, 105, 1, 116, 110, 111, 99, 2, 110, 3, 6, 109, 57, 0, 105, 99, 104, 101, 1, 114, 102, 3, 6, 109, 91, 0, 4, 1, 98, 97, 108, 97, 2, 109, 3, 6, 110, 0, 1, 98, 101, 108, 97, 116, 2, 110, 0, 1, 98, 101, 115, 2, 115, 116, 105, 97, 110, 0, 1, 98, 109, 117, 108, 2, 103, 111, 0, 1, 99, 97, 100, 2, 112, 111, 0, 1, 99, 105, 112, 2, 115, 115, 111, 0, 1, 100, 97, 107, 2, 118, 101, 114, 0, 1, 100, 101, 112, 112, 117, 115, 2, 115, 0, 1, 100, 114, 101, 100, 110, 117, 2, 110, 105, 103, 0, 1, 100, 114, 111, 118, 104, 2, 110, 0, 1, 100, 117, 97, 108, 2, 110, 117, 109, 0, 1, 102, 110, 105, 2, 109, 0, 1, 103, 114, 111, 2, 115, 0, 1, 104, 97, 98, 2, 109, 97, 0, 1, 106, 121, 112, 2, 109, 97, 0, 1, 107, 115, 108, 105, 116, 2, 100, 101, 0, 1, 108, 97, 2, 115, 107, 0, 1, 108, 97, 112, 2, 118, 101, 114, 12, 0, 1, 108, 105, 112, 2, 116, 117, 115, 0, 1, 108, 111, 122, 0, 1, 108, 115, 111, 103, 117, 106, 2, 118, 0, 1, 108, 116, 97, 2, 110, 116, 105, 115, 0, 1, 109, 97, 108, 97, 115, 2, 110, 100, 101, 114, 0, 1, 109, 101, 116, 97, 117, 103, 2, 108, 0, 1, 109, 105, 114, 103, 2, 115, 115, 101, 0, 1, 109, 109, 111, 107, 2, 110, 100, 0, 1, 110, 97, 98, 2, 110, 0, 1, 110, 105, 100, 110, 97, 107, 115, 2, 118, 0, 1, 110, 105, 104, 2, 110, 0, 1, 112, 111, 116, 2, 115, 0, 1, 114, 101, 118, 111, 2, 108, 116, 0, 1, 115, 101, 109, 114, 97, 112, 2, 110, 0, 1, 115, 108, 97, 98, 2, 109, 105, 0, 1, 116, 111, 103, 111, 98, 0, 1, 116, 115, 97, 107, 2, 110, 106, 101, 0, 1, 116, 115, 97, 116, 101, 109, 2, 115, 101, 0, 1, 116, 115, 107, 101, 2, 115, 0, 1, 116, 115, 110, 97, 114, 111, 102, 2, 108, 116, 0, 1, 116, 115, 112, 111, 2, 110, 100, 101, 108, 115, 101, 0, 1, 116, 115, 114, 101, 2, 116, 110, 105, 110, 103, 0, 1, 116, 117, 112, 115, 105, 100, 2, 116, 115, 0, 1, 118, 2, 110, 108, 105, 103, 0, 1, 118, 97, 104, 2, 110, 97, 0, 1, 118, 97, 104, 2, 110, 110, 97, 0, 1, 122, 121, 98, 2, 110, 115, 32, 0, 2, 115, 109, 101, 0, 8, 100, 100, 110, 101, 2, 32, 0, 8, 100, 101, 109, 2, 108, 106, 101, 0, 8, 101, 116, 2, 116, 101, 114, 0, 8, 103, 97, 112, 111, 114, 112, 2, 110, 100, 0, 8, 105, 100, 110, 105, 2, 110, 97, 0, 8, 105, 115, 117, 116, 110, 101, 2, 115, 0, 8, 107, 97, 107, 2, 111, 0, 8, 107, 97, 109, 2, 98, 0, 8, 107, 105, 104, 99, 2, 110, 101, 0, 8, 107, 105, 116, 97, 118, 2, 110, 0, 8, 107, 108, 97, 2, 108, 105, 0, 8, 107, 110, 111, 107, 2, 118, 0, 8, 108, 107, 101, 114, 2, 109, 101, 0, 8, 108, 107, 110, 101, 2, 118, 101, 12, 0, 8, 108, 115, 105, 116, 97, 114, 98, 2, 118, 0, 8, 109, 105, 2, 109, 0, 8, 109, 105, 114, 112, 2, 108, 0, 8, 110, 97, 99, 2, 100, 105, 101, 114, 0, 8, 110, 105, 109, 111, 100, 2, 110, 0, 8, 110, 121, 100, 2, 109, 111, 0, 8, 111, 2, 115, 101, 0, 8, 112, 97, 2, 99, 104, 0, 8, 112, 109, 105, 104, 99, 2, 110, 0, 8, 115, 97, 102, 2, 110, 0, 8, 115, 107, 101, 2, 109, 12, 0, 8, 116, 97, 98, 2, 108, 106, 101, 0, 8, 116, 101, 100, 2, 108, 106, 101, 0, 8, 116, 107, 111, 2, 118, 0, 8, 118, 97, 114, 97, 107, 2, 110, 101, 0, 100, 1, 107, 115, 117, 98, 2, 115, 0, 100, 1, 108, 97, 112, 2, 115, 0, 100, 8, 108, 106, 101, 115, 2, 115, 0, 103, 1, 115, 101, 107, 107, 97, 110, 115, 2, 108, 105, 103, 0, 4, 1, 103, 101, 114, 111, 2, 110, 111, 3, 6, 110, 12, 0, 1, 108, 105, 109, 2, 110, 111, 0, 1, 116, 114, 97, 107, 2, 103, 111, 0, 100, 101, 1, 10, 2, 28, 33, 3, 6, 110, 12, 86, 13, 0, 100, 101, 1, 10, 2, 114, 28, 33, 3, 6, 110, 12, 86, 114, 0, 116, 1, 10, 2, 28, 33, 3, 6, 110, 47, 0, 103, 110, 101, 1, 112, 109, 97, 104, 99, 3, 6, 110, 50, 57, 13, 0, 110, 100, 101, 1, 98, 97, 114, 116, 110, 111, 107, 3, 6, 110, 50, 72, 108, 0, 110, 115, 1, 10, 2, 28, 33, 3, 6, 110, 50, 89, 0, 4, 98, 1, 10, 2, 101, 108, 28, 33, 3, 6, 110, 71, 0, 98, 1, 10, 2, 108, 101, 28, 33, 0, 4, 100, 1, 110, 114, 111, 116, 2, 111, 3, 6, 110, 72, 0, 100, 1, 118, 101, 110, 2, 97, 0, 118, 101, 114, 97, 108, 1, 110, 97, 99, 3, 6, 110, 84, 108, 34, 108, 55, 0, 118, 101, 114, 8, 108, 107, 110, 101, 3, 6, 110, 84, 114, 0, 4, 1, 98, 110, 101, 98, 165, 195, 2, 114, 105, 110, 103, 3, 6, 112, 0, 1, 102, 97, 115, 2, 114, 105, 0, 1, 102, 114, 101, 2, 114, 0, 1, 112, 115, 101, 98, 2, 114, 105, 110, 103, 0, 1, 114, 98, 105, 118, 2, 116, 111, 0, 1, 114, 101, 109, 111, 111, 98, 2, 110, 103, 0, 1, 114, 105, 103, 2, 102, 0, 1, 114, 105, 109, 2, 107, 0, 1, 114, 108, 165, 195, 107, 2, 98, 105, 0, 1, 114, 116, 115, 97, 112, 2, 109, 105, 0, 1, 118, 97, 104, 2, 114, 116, 105, 0, 1, 118, 97, 107, 115, 2, 110, 107, 0, 1, 118, 114, 111, 102, 2, 114, 105, 110, 103, 0, 8, 98, 101, 108, 108, 101, 104, 2, 114, 100, 0, 8, 98, 109, 111, 108, 2, 114, 100, 0, 8, 98, 111, 103, 110, 111, 108, 2, 114, 100, 0, 8, 103, 108, 117, 98, 2, 114, 0, 8, 104, 97, 115, 2, 114, 97, 0, 8, 105, 108, 108, 105, 109, 2, 114, 0, 8, 105, 108, 108, 105, 114, 116, 2, 114, 0, 8, 108, 97, 2, 114, 109, 0, 8, 108, 97, 109, 2, 114, 105, 97, 0, 8, 108, 117, 111, 102, 2, 114, 100, 0, 8, 108, 117, 111, 112, 2, 114, 100, 0, 8, 110, 111, 109, 2, 114, 107, 0, 8, 111, 105, 100, 97, 114, 2, 107, 116, 105, 0, 8, 114, 97, 2, 98, 101, 114, 0, 8, 114, 97, 98, 2, 107, 0, 8, 114, 100, 97, 109, 2, 115, 0, 8, 114, 114, 117, 104, 0, 8, 115, 97, 104, 2, 114, 100, 0, 8, 115, 101, 114, 112, 109, 105, 2, 114, 105, 111, 0, 8, 115, 110, 97, 109, 2, 114, 100, 0, 8, 116, 115, 97, 98, 2, 114, 100, 0, 110, 1, 114, 10, 2, 110, 101, 28, 34, 12, 0, 8, 111, 108, 107, 2, 107, 12, 3, 6, 112, 12, 0, 100, 101, 1, 114, 10, 2, 28, 33, 3, 6, 112, 12, 86, 13, 0, 100, 101, 1, 114, 10, 2, 114, 28, 33, 3, 6, 112, 12, 86, 114, 0, 116, 1, 114, 10, 2, 28, 33, 3, 6, 112, 47, 0, 110, 1, 114, 10, 2, 28, 34, 12, 3, 6, 112, 50, 0, 110, 116, 1, 114, 10, 2, 28, 33, 3, 6, 112, 50, 47, 0, 110, 115, 1, 114, 10, 2, 28, 33, 3, 6, 112, 50, 89, 0, 4, 108, 1, 114, 2, 28, 33, 12, 12, 3, 6, 112, 55, 0, 108, 1, 114, 10, 2, 101, 32, 28, 33, 12, 0, 118, 1, 104, 110, 101, 98, 184, 195, 107, 2, 110, 3, 6, 112, 58, 0, 110, 116, 1, 114, 117, 97, 116, 115, 101, 114, 3, 6, 112, 68, 0, 4, 110, 99, 101, 1, 10, 2, 28, 33, 3, 6, 112, 68, 89, 13, 0, 110, 99, 104, 101, 1, 10, 2, 28, 33, 0, 110, 99, 101, 1, 10, 2, 114, 28, 33, 3, 6, 112, 68, 89, 114, 0, 98, 1, 114, 10, 2, 101, 108, 28, 33, 3, 6, 112, 71, 0, 114, 98, 101, 114, 8, 98, 97, 114, 3, 6, 112, 71, 114, 0, 100, 111, 1, 114, 111, 108, 111, 99, 3, 6, 112, 72, 39, 0, 4, 8, 105, 107, 121, 115, 112, 2, 116, 3, 7, 110, 0, 116, 1, 10, 2, 116, 28, 33, 0, 110, 1, 10, 2, 28, 34, 12, 3, 7, 110, 50, 0, 110, 116, 1, 10, 2, 28, 33, 3, 7, 110, 50, 47, 0, 4, 108, 1, 10, 2, 28, 33, 12, 3, 7, 110, 55, 0, 108, 1, 10, 2, 101, 32, 28, 33, 12, 0, 1, 108, 114, 111, 102, 2, 103, 116, 32, 3, 7, 112, 0, 114, 1, 10, 2, 28, 33, 3, 7, 112, 34, 0, 110, 99, 101, 1, 121, 111, 118, 2, 28, 33, 3, 7, 112, 68, 89, 0, 102, 1, 114, 111, 118, 104, 3, 8, 4, 110, 0, 4, 8, 110, 97, 98, 101, 107, 105, 3, 8, 110, 0, 8, 110, 97, 100, 110, 97, 98, 0, 8, 110, 97, 103, 114, 111, 109, 97, 116, 97, 102, 0, 8, 110, 97, 107, 114, 97, 0, 8, 110, 97, 117, 104, 105, 114, 97, 109, 0, 8, 110, 97, 118, 114, 105, 110, 0, 8, 110, 97, 119, 115, 116, 111, 17, 66, 0, 8, 110, 97, 121, 117, 103, 0, 8, 110, 101, 114, 97, 0, 8, 110, 101, 122, 105, 97, 109, 0, 8, 110, 105, 103, 110, 97, 0, 8, 110, 105, 108, 117, 107, 115, 97, 109, 0, 8, 110, 105, 110, 105, 109, 101, 102, 0, 8, 110, 105, 114, 97, 107, 111, 0, 8, 110, 105, 114, 97, 109, 0, 8, 110, 105, 114, 97, 115, 116, 0, 8, 110, 105, 114, 97, 122, 0, 8, 110, 105, 114, 101, 108, 108, 97, 98, 0, 8, 110, 105, 115, 116, 101, 114, 0, 8, 110, 105, 116, 110, 101, 103, 114, 97, 0, 8, 110, 105, 116, 114, 101, 99, 110, 111, 107, 0, 8, 110, 105, 116, 115, 166, 195, 108, 97, 112, 0, 8, 110, 105, 118, 111, 103, 101, 99, 114, 101, 104, 0, 8, 110, 110, 97, 105, 115, 111, 104, 0, 8, 110, 110, 111, 100, 97, 109, 0, 8, 110, 110, 111, 100, 97, 109, 105, 114, 112, 0, 8, 110, 111, 109, 111, 112, 120, 111, 99, 0, 8, 110, 111, 114, 111, 107, 0, 108, 1, 110, 97, 2, 102, 97, 98, 101, 116, 3, 8, 110, 55, 0, 1, 102, 101, 98, 2, 114, 105, 110, 103, 3, 16, 112, 0, 118, 101, 8, 100, 3, 21, 0, 4, 1, 104, 2, 99, 105, 101, 110, 100, 97, 3, 21, 101, 115, 0, 108, 101, 106, 97, 110, 100, 114, 111, 0, 4, 1, 17, 67, 2, 18, 71, 11, 3, 35, 0, 1, 17, 67, 2, 18, 75, 0, 1, 17, 67, 2, 18, 75, 18, 69, 12, 12, 0, 1, 17, 67, 2, 18, 75, 101, 0, 1, 17, 67, 2, 99, 107, 0, 1, 17, 67, 2, 109, 12, 0, 1, 17, 67, 2, 110, 18, 75, 18, 69, 12, 12, 0, 1, 17, 67, 2, 114, 18, 76, 0, 1, 17, 67, 2, 114, 114, 0, 1, 17, 67, 2, 120, 12, 0, 1, 18, 73, 2, 109, 0, 1, 18, 74, 2, 106, 0, 1, 18, 75, 2, 112, 12, 0, 1, 98, 2, 106, 101, 114, 0, 1, 100, 2, 102, 110, 0, 1, 100, 2, 103, 21, 12, 0, 1, 100, 2, 103, 115, 21, 0, 1, 102, 2, 118, 111, 12, 0, 1, 104, 2, 18, 66, 0, 1, 104, 2, 106, 0, 1, 104, 2, 106, 12, 12, 0, 1, 104, 2, 112, 0, 1, 104, 99, 2, 110, 0, 1, 105, 108, 108, 105, 119, 2, 109, 0, 1, 106, 2, 112, 112, 0, 1, 106, 2, 112, 115, 0, 1, 107, 2, 106, 0, 1, 107, 2, 109, 0, 1, 107, 2, 109, 117, 102, 108, 12, 0, 1, 107, 2, 112, 115, 0, 1, 107, 115, 2, 102, 12, 0, 1, 108, 2, 98, 32, 12, 0, 1, 108, 2, 98, 98, 0, 1, 108, 2, 112, 12, 0, 1, 108, 107, 2, 18, 71, 0, 1, 108, 115, 2, 18, 71, 0, 1, 108, 115, 2, 110, 103, 101, 12, 0, 1, 108, 115, 118, 105, 108, 2, 110, 103, 12, 0, 1, 109, 105, 108, 107, 2, 107, 115, 0, 1, 112, 2, 112, 114, 105, 12, 0, 1, 112, 115, 2, 110, 107, 117, 108, 101, 114, 0, 1, 114, 2, 18, 73, 0, 1, 114, 2, 115, 101, 0, 1, 114, 2, 116, 0, 1, 114, 2, 118, 0, 1, 114, 107, 115, 2, 108, 0, 1, 115, 2, 110, 103, 12, 0, 1, 115, 2, 120, 0, 1, 116, 2, 98, 116, 0, 1, 116, 2, 112, 0, 1, 118, 2, 99, 99, 0, 1, 118, 2, 102, 12, 12, 0, 1, 118, 2, 106, 0, 2, 18, 66, 12, 12, 0, 2, 18, 66, 101, 12, 12, 0, 2, 98, 17, 67, 105, 0, 2, 98, 110, 111, 114, 109, 0, 2, 102, 17, 67, 12, 0, 2, 109, 101, 114, 105, 107, 97, 110, 0, 2, 109, 109, 12, 0, 2, 109, 115, 0, 2, 109, 117, 108, 101, 116, 0, 2, 112, 111, 116, 101, 0, 2, 112, 112, 97, 114, 0, 2, 112, 112, 101, 108, 115, 105, 110, 0, 2, 112, 112, 101, 116, 105, 116, 0, 2, 114, 114, 101, 115, 116, 0, 8, 2, 108, 100, 114, 105, 103, 0, 8, 2, 110, 100, 101, 114, 0, 8, 100, 2, 109, 32, 0, 8, 100, 2, 109, 109, 0, 114, 101, 8, 98, 2, 116, 3, 35, 34, 6, 111, 0, 114, 97, 103, 100, 1, 109, 115, 3, 35, 34, 6, 112, 58, 72, 0, 4, 118, 1, 103, 2, 116, 121, 118, 3, 35, 40, 0, 118, 1, 104, 32, 101, 100, 184, 195, 0, 118, 101, 114, 116, 1, 106, 3, 35, 40, 34, 47, 0, 116, 116, 101, 110, 116, 105, 111, 110, 3, 35, 47, 6, 109, 50, 91, 13, 50, 0, 112, 101, 103, 195, 184, 106, 101, 1, 112, 3, 35, 48, 13, 81, 6, 114, 57, 108, 0, 103, 1, 18, 74, 2, 116, 3, 35, 49, 0, 99, 99, 97, 114, 97, 116, 1, 98, 3, 35, 49, 35, 34, 6, 35, 0, 110, 100, 97, 1, 114, 2, 108, 3, 35, 50, 72, 20, 115, 0, 4, 110, 103, 1, 109, 2, 111, 3, 35, 50, 81, 0, 110, 103, 2, 117, 108, 12, 12, 0, 110, 103, 8, 2, 111, 108, 0, 4, 105, 1, 99, 2, 114, 111, 3, 35, 57, 0, 105, 8, 110, 105, 115, 0, 121, 1, 109, 2, 97, 0, 121, 1, 117, 103, 0, 105, 1, 110, 2, 114, 111, 98, 105, 3, 35, 57, 6, 0, 105, 114, 111, 8, 107, 3, 35, 57, 34, 39, 0, 121, 114, 101, 117, 116, 104, 1, 98, 3, 35, 57, 51, 6, 114, 57, 47, 0, 121, 97, 116, 111, 108, 108, 97, 104, 3, 35, 57, 110, 47, 6, 114, 55, 110, 0, 121, 101, 114, 1, 98, 3, 35, 57, 114, 0, 4, 117, 2, 12, 12, 3, 35, 58, 0, 119, 2, 25, 0, 118, 102, 108, 97, 98, 1, 103, 3, 35, 58, 83, 55, 110, 71, 0, 4, 110, 2, 99, 105, 101, 110, 3, 35, 68, 0, 110, 103, 2, 114, 101, 0, 110, 103, 8, 2, 101, 17, 67, 0, 98, 97, 114, 101, 116, 1, 107, 3, 35, 71, 35, 34, 6, 109, 0, 98, 101, 114, 110, 97, 107, 1, 116, 3, 35, 71, 114, 50, 6, 35, 49, 0, 103, 103, 105, 111, 114, 101, 1, 109, 3, 35, 75, 6, 39, 12, 53, 36, 0, 103, 1, 109, 2, 97, 115, 105, 3, 35, 81, 0, 103, 97, 115, 97, 107, 105, 1, 110, 3, 35, 81, 110, 89, 6, 35, 49, 37, 0, 102, 116, 101, 114, 115, 104, 97, 118, 101, 3, 35, 83, 47, 114, 91, 109, 57, 84, 0, 122, 122, 105, 1, 114, 3, 35, 91, 57, 0, 99, 104, 1, 98, 3, 35, 101, 0, 104, 97, 8, 2, 32, 3, 35, 107, 6, 35, 0, 105, 1, 116, 110, 117, 111, 109, 2, 110, 3, 36, 0, 4, 1, 102, 114, 101, 116, 110, 105, 2, 99, 101, 3, 36, 37, 0, 1, 109, 101, 99, 97, 112, 2, 107, 0, 98, 121, 1, 98, 2, 12, 3, 36, 37, 71, 37, 0, 99, 101, 1, 112, 3, 36, 37, 89, 0, 4, 117, 1, 104, 99, 2, 102, 3, 39, 0, 117, 1, 104, 99, 2, 118, 105, 110, 0, 117, 1, 115, 2, 116, 101, 114, 110, 101, 0, 117, 1, 116, 115, 101, 114, 2, 114, 0, 117, 2, 32, 110, 97, 116, 117, 114, 101, 108, 0, 117, 120, 8, 102, 0, 117, 103, 117, 105, 110, 1, 103, 3, 39, 81, 6, 110, 68, 0, 4, 1, 114, 2, 99, 101, 114, 98, 97, 110, 101, 3, 109, 0, 1, 114, 2, 99, 101, 114, 98, 105, 108, 0, 1, 114, 2, 99, 101, 114, 99, 121, 107, 0, 1, 114, 2, 99, 101, 114, 107, 195, 184, 114, 0, 1, 114, 2, 99, 101, 114, 118, 111, 103, 110, 0, 101, 2, 114, 111, 0, 105, 2, 109, 97, 98, 101, 108, 0, 105, 114, 101, 1, 108, 99, 3, 109, 12, 34, 0, 105, 114, 99, 111, 110, 100, 105, 116, 105, 111, 110, 3, 109, 12, 34, 49, 114, 50, 72, 37, 12, 91, 13, 50, 0, 105, 114, 3, 109, 34, 0, 105, 100, 115, 3, 109, 37, 72, 89, 0, 4, 1, 104, 2, 115, 116, 105, 110, 103, 3, 109, 57, 0, 1, 108, 2, 115, 101, 114, 101, 110, 0, 1, 108, 2, 115, 101, 114, 110, 101, 115, 0, 1, 108, 2, 115, 101, 114, 112, 114, 0, 1, 108, 2, 115, 101, 114, 115, 116, 0, 1, 108, 32, 110, 101, 2, 115, 101, 114, 0, 1, 109, 107, 111, 111, 98, 2, 107, 101, 114, 0, 1, 114, 2, 116, 105, 110, 103, 0, 121, 1, 100, 0, 121, 2, 25, 0, 121, 8, 98, 2, 32, 0, 116, 101, 1, 109, 121, 97, 108, 112, 3, 109, 57, 47, 0, 116, 105, 101, 1, 107, 3, 109, 57, 47, 37, 0, 98, 101, 8, 98, 2, 32, 3, 109, 57, 48, 0, 99, 111, 8, 119, 3, 109, 57, 49, 39, 58, 0, 99, 111, 110, 1, 98, 2, 12, 3, 109, 57, 49, 114, 50, 0, 121, 110, 101, 1, 112, 3, 109, 57, 50, 0, 4, 105, 108, 1, 116, 107, 99, 111, 99, 3, 109, 57, 55, 0, 108, 101, 1, 32, 114, 101, 103, 110, 105, 103, 0, 109, 121, 8, 3, 109, 57, 65, 37, 0, 103, 101, 110, 99, 121, 3, 109, 57, 75, 13, 50, 89, 37, 0, 103, 97, 115, 8, 118, 3, 109, 57, 81, 13, 89, 0, 107, 101, 115, 1, 108, 102, 110, 114, 111, 99, 3, 109, 57, 81, 89, 0, 118, 101, 114, 121, 3, 109, 57, 84, 34, 37, 0, 121, 101, 115, 1, 17, 67, 3, 109, 57, 89, 0, 116, 105, 111, 110, 1, 116, 115, 2, 99, 97, 114, 3, 109, 57, 91, 108, 50, 0, 104, 97, 98, 8, 3, 109, 57, 107, 110, 71, 0, 112, 101, 1, 114, 103, 3, 109, 71, 0, 4, 3, 110, 0, 1, 17, 67, 2, 17, 67, 11, 0, 1, 17, 67, 2, 18, 75, 18, 69, 0, 1, 17, 67, 2, 109, 105, 12, 0, 1, 17, 67, 2, 109, 195, 166, 12, 0, 1, 18, 67, 2, 18, 67, 101, 0, 1, 18, 67, 2, 18, 67, 108, 101, 0, 1, 18, 71, 2, 110, 0, 1, 18, 73, 2, 18, 75, 18, 69, 0, 1, 18, 73, 2, 118, 0, 1, 18, 74, 2, 108, 100, 0, 1, 18, 75, 2, 109, 101, 12, 0, 1, 18, 75, 2, 112, 18, 69, 12, 0, 1, 21, 2, 107, 114, 18, 69, 12, 0, 1, 98, 2, 103, 97, 103, 101, 12, 12, 0, 1, 98, 2, 118, 105, 97, 110, 12, 0, 1, 98, 32, 103, 105, 98, 2, 110, 103, 0, 1, 98, 114, 105, 97, 2, 103, 0, 1, 99, 2, 109, 112, 12, 0, 1, 100, 2, 109, 18, 76, 12, 0, 1, 100, 100, 2, 103, 12, 0, 1, 100, 108, 2, 107, 0, 1, 100, 108, 101, 109, 109, 97, 103, 2, 103, 115, 0, 1, 101, 0, 1, 101, 2, 114, 18, 69, 12, 0, 1, 101, 114, 2, 103, 12, 0, 1, 102, 2, 18, 67, 114, 18, 69, 0, 1, 102, 2, 18, 74, 0, 1, 102, 2, 99, 18, 76, 0, 1, 102, 2, 110, 107, 108, 117, 98, 12, 0, 1, 102, 111, 115, 0, 1, 103, 2, 98, 114, 105, 101, 108, 0, 1, 103, 2, 110, 103, 115, 116, 101, 114, 12, 0, 1, 103, 105, 108, 0, 1, 104, 2, 99, 107, 12, 0, 1, 104, 2, 109, 98, 117, 114, 103, 101, 114, 0, 1, 104, 2, 110, 0, 1, 104, 2, 110, 107, 97, 116, 0, 1, 104, 2, 110, 107, 195, 184, 110, 12, 12, 0, 1, 104, 2, 112, 112, 17, 65, 0, 1, 104, 101, 98, 2, 103, 0, 1, 104, 115, 2, 109, 18, 76, 0, 1, 104, 116, 2, 110, 107, 115, 0, 1, 105, 100, 2, 18, 66, 12, 0, 1, 106, 2, 109, 101, 110, 0, 1, 107, 2, 12, 0, 1, 107, 2, 112, 18, 76, 12, 0, 1, 107, 2, 112, 114, 101, 12, 0, 1, 107, 2, 112, 114, 105, 110, 103, 0, 1, 107, 105, 116, 111, 107, 114, 97, 110, 0, 1, 107, 115, 2, 18, 71, 12, 0, 1, 108, 2, 98, 101, 0, 1, 108, 2, 109, 17, 65, 12, 0, 1, 108, 2, 110, 0, 1, 108, 2, 118, 101, 110, 100, 101, 108, 0, 1, 108, 97, 109, 2, 18, 66, 97, 0, 1, 108, 98, 2, 99, 107, 0, 1, 108, 98, 2, 100, 0, 1, 108, 102, 2, 98, 32, 12, 0, 1, 108, 111, 99, 0, 1, 108, 112, 2, 99, 101, 0, 1, 108, 112, 2, 107, 97, 0, 1, 108, 115, 2, 110, 103, 12, 0, 1, 108, 115, 105, 2, 109, 105, 0, 1, 109, 2, 106, 111, 12, 0, 1, 109, 2, 107, 97, 0, 1, 109, 105, 108, 107, 0, 1, 109, 105, 114, 112, 0, 1, 109, 114, 105, 102, 0, 1, 109, 114, 105, 102, 2, 12, 0, 1, 109, 115, 2, 99, 107, 0, 1, 110, 2, 112, 97, 108, 109, 0, 1, 110, 97, 112, 2, 109, 97, 0, 1, 110, 103, 2, 118, 110, 101, 0, 1, 110, 105, 103, 97, 118, 0, 1, 110, 115, 2, 99, 107, 0, 1, 112, 2, 103, 18, 76, 12, 0, 1, 112, 2, 103, 110, 12, 0, 1, 112, 2, 112, 105, 0, 1, 112, 2, 118, 12, 0, 1, 114, 2, 110, 99, 104, 0, 1, 114, 2, 110, 115, 105, 103, 116, 0, 1, 114, 99, 2, 99, 107, 12, 0, 1, 114, 101, 116, 102, 101, 2, 98, 0, 1, 114, 111, 102, 2, 110, 0, 1, 115, 2, 98, 98, 97, 116, 0, 1, 115, 2, 103, 12, 0, 1, 115, 2, 103, 115, 97, 110, 12, 12, 0, 1, 115, 2, 103, 115, 98, 101, 104, 97, 110, 100, 108, 12, 12, 0, 1, 115, 2, 103, 115, 109, 97, 12, 12, 0, 1, 115, 2, 103, 115, 111, 109, 12, 12, 0, 1, 115, 2, 109, 97, 110, 116, 0, 1, 115, 2, 109, 117, 101, 108, 0, 1, 115, 107, 101, 10, 2, 109, 0, 1, 116, 2, 110, 100, 0, 1, 116, 2, 112, 18, 76, 0, 1, 116, 2, 112, 105, 0, 1, 116, 115, 2, 99, 99, 97, 116, 111, 0, 1, 116, 115, 2, 102, 102, 97, 103, 101, 0, 1, 116, 115, 2, 107, 97, 0, 1, 116, 115, 101, 116, 2, 109, 0, 1, 118, 2, 110, 100, 114, 195, 184, 114, 0, 1, 118, 108, 101, 115, 2, 110, 103, 105, 118, 0, 1, 118, 115, 2, 98, 0, 1, 120, 97, 116, 0, 1, 122, 122, 105, 112, 0, 2, 18, 66, 18, 69, 12, 12, 0, 2, 98, 98, 0, 2, 100, 114, 101, 115, 115, 12, 0, 2, 100, 118, 97, 114, 0, 2, 102, 102, 117, 116, 97, 103, 101, 0, 2, 102, 102, 195, 166, 114, 101, 12, 0, 2, 102, 115, 116, 101, 100, 12, 0, 2, 103, 103, 114, 101, 115, 12, 12, 0, 2, 107, 11, 18, 69, 12, 0, 2, 107, 97, 12, 12, 0, 2, 107, 97, 100, 101, 109, 12, 12, 0, 2, 107, 118, 17, 65, 12, 0, 2, 108, 100, 101, 0, 2, 108, 116, 0, 2, 110, 103, 97, 118, 12, 12, 0, 2, 110, 103, 195, 165, 12, 12, 0, 2, 110, 104, 111, 12, 12, 0, 2, 110, 107, 108, 97, 103, 12, 12, 0, 2, 110, 108, 195, 166, 103, 12, 0, 2, 110, 115, 116, 0, 2, 110, 115, 116, 114, 101, 110, 103, 12, 0, 2, 110, 116, 97, 108, 12, 0, 2, 110, 118, 101, 110, 100, 12, 0, 2, 116, 116, 97, 99, 104, 12, 0, 8, 2, 18, 66, 18, 69, 12, 12, 0, 8, 2, 102, 102, 101, 107, 116, 12, 0, 8, 2, 110, 100, 101, 110, 0, 8, 2, 110, 100, 101, 116, 0, 100, 1, 108, 106, 101, 115, 2, 115, 0, 103, 1, 100, 101, 114, 102, 2, 115, 0, 103, 1, 100, 110, 97, 109, 2, 115, 0, 103, 1, 100, 110, 184, 195, 115, 2, 115, 0, 103, 1, 100, 114, 101, 118, 104, 0, 103, 1, 100, 114, 184, 195, 108, 2, 115, 0, 103, 1, 100, 115, 110, 111, 2, 115, 0, 103, 1, 100, 115, 114, 105, 116, 2, 115, 0, 103, 1, 100, 115, 114, 111, 116, 2, 115, 0, 103, 2, 103, 114, 101, 103, 97, 116, 0, 104, 1, 104, 115, 0, 114, 1, 107, 2, 108, 101, 110, 101, 0, 114, 1, 107, 21, 2, 108, 0, 114, 1, 108, 110, 101, 118, 111, 100, 2, 115, 0, 118, 1, 104, 2, 32, 0, 4, 1, 107, 2, 106, 97, 107, 3, 110, 6, 0, 1, 116, 97, 107, 2, 112, 117, 108, 116, 0, 105, 1, 107, 2, 110, 3, 110, 6, 37, 12, 0, 4, 1, 17, 67, 2, 17, 67, 101, 3, 110, 12, 0, 1, 17, 67, 2, 110, 101, 0, 1, 18, 73, 2, 98, 18, 76, 0, 1, 18, 73, 2, 100, 0, 1, 18, 74, 2, 18, 67, 101, 0, 1, 18, 74, 2, 108, 0, 1, 103, 2, 118, 0, 1, 106, 116, 2, 32, 0, 1, 108, 115, 2, 118, 0, 1, 112, 115, 2, 109, 0, 1, 112, 115, 2, 110, 107, 105, 110, 103, 0, 1, 116, 2, 108, 17, 65, 0, 8, 2, 101, 32, 0, 110, 110, 101, 115, 8, 99, 3, 110, 12, 50, 12, 0, 118, 1, 108, 2, 101, 116, 3, 110, 12, 84, 0, 118, 101, 1, 108, 2, 109, 101, 110, 116, 3, 110, 13, 0, 114, 97, 112, 97, 104, 111, 101, 3, 110, 34, 6, 110, 48, 110, 107, 113, 58, 0, 4, 114, 114, 121, 1, 98, 3, 110, 34, 37, 0, 114, 121, 1, 109, 32, 121, 100, 111, 111, 108, 98, 0, 116, 104, 101, 110, 3, 110, 47, 6, 36, 50, 0, 116, 116, 114, 105, 98, 117, 116, 105, 111, 110, 8, 3, 110, 47, 51, 37, 71, 40, 91, 6, 39, 50, 0, 116, 116, 114, 105, 98, 117, 116, 105, 111, 110, 3, 110, 47, 51, 37, 71, 40, 91, 39, 50, 0, 116, 97, 107, 111, 109, 98, 1, 107, 3, 110, 47, 110, 49, 6, 39, 65, 71, 0, 4, 112, 101, 1, 110, 97, 107, 3, 110, 48, 6, 36, 0, 112, 195, 169, 1, 110, 97, 107, 0, 112, 112, 101, 97, 108, 3, 110, 48, 6, 37, 55, 0, 112, 111, 108, 101, 111, 110, 1, 110, 3, 110, 48, 6, 39, 55, 57, 114, 50, 0, 107, 107, 111, 114, 100, 101, 111, 110, 3, 110, 49, 6, 114, 12, 72, 36, 114, 50, 0, 107, 114, 121, 108, 3, 110, 49, 34, 6, 116, 55, 0, 107, 117, 108, 116, 101, 116, 8, 102, 3, 110, 49, 40, 55, 47, 6, 36, 47, 0, 99, 116, 105, 111, 110, 3, 110, 49, 91, 57, 13, 50, 0, 110, 100, 114, 101, 97, 8, 3, 110, 50, 72, 34, 6, 36, 110, 0, 110, 100, 114, 101, 119, 3, 110, 50, 72, 34, 40, 0, 110, 100, 114, 101, 119, 115, 3, 110, 50, 72, 51, 40, 12, 89, 0, 110, 100, 111, 8, 114, 98, 3, 110, 50, 72, 113, 58, 0, 110, 100, 111, 108, 112, 104, 1, 114, 3, 110, 50, 72, 114, 55, 83, 0, 110, 100, 101, 114, 115, 111, 110, 8, 3, 110, 50, 72, 114, 89, 114, 50, 0, 110, 103, 101, 108, 97, 8, 3, 110, 50, 75, 13, 55, 110, 0, 110, 103, 105, 101, 8, 3, 110, 50, 75, 37, 0, 110, 103, 101, 108, 101, 115, 3, 110, 50, 75, 108, 55, 109, 89, 0, 4, 110, 103, 2, 114, 101, 98, 3, 110, 50, 81, 0, 110, 103, 2, 114, 105, 12, 0, 110, 103, 111, 111, 110, 1, 114, 3, 110, 50, 81, 6, 40, 12, 50, 0, 110, 104, 97, 116, 116, 97, 110, 1, 109, 3, 110, 50, 107, 6, 110, 47, 13, 50, 0, 114, 114, 111, 119, 3, 110, 51, 39, 40, 0, 108, 1, 10, 2, 105, 115, 116, 28, 33, 12, 3, 110, 55, 0, 4, 108, 1, 10, 2, 105, 115, 109, 28, 33, 12, 3, 110, 55, 6, 0, 108, 1, 110, 97, 2, 121, 12, 0, 108, 97, 106, 1, 109, 3, 110, 55, 6, 35, 57, 0, 4, 108, 108, 105, 101, 8, 2, 32, 3, 110, 55, 37, 0, 108, 108, 121, 1, 115, 0, 108, 100, 101, 116, 104, 97, 3, 110, 55, 72, 6, 37, 87, 110, 0, 108, 100, 101, 104, 121, 100, 1, 109, 114, 111, 102, 3, 110, 55, 72, 108, 107, 6, 116, 86, 0, 108, 97, 107, 108, 97, 118, 1, 98, 2, 97, 3, 110, 55, 110, 49, 55, 6, 110, 12, 84, 0, 108, 97, 99, 101, 8, 112, 3, 110, 55, 110, 89, 0, 4, 1, 108, 21, 2, 103, 3, 110, 57, 0, 103, 1, 100, 101, 109, 109, 111, 100, 0, 103, 1, 102, 2, 32, 0, 103, 1, 109, 2, 114, 101, 0, 103, 1, 115, 2, 115, 32, 12, 0, 103, 1, 118, 32, 116, 100, 105, 108, 2, 116, 0, 103, 8, 109, 2, 32, 12, 0, 103, 8, 118, 2, 32, 0, 103, 8, 118, 2, 101, 32, 0, 108, 98, 117, 113, 117, 101, 114, 113, 117, 101, 3, 110, 59, 71, 108, 49, 118, 49, 37, 0, 109, 97, 114, 111, 1, 99, 3, 110, 65, 6, 109, 34, 39, 0, 109, 97, 1, 103, 2, 99, 104, 3, 110, 65, 6, 110, 0, 109, 117, 114, 97, 105, 1, 115, 3, 110, 65, 40, 34, 6, 35, 57, 0, 109, 98, 114, 111, 115, 101, 3, 110, 65, 71, 51, 115, 40, 89, 0, 103, 110, 97, 1, 109, 114, 97, 2, 99, 3, 110, 68, 6, 112, 0, 98, 98, 121, 8, 3, 110, 71, 37, 0, 98, 105, 108, 101, 110, 101, 3, 110, 71, 37, 55, 37, 12, 50, 0, 98, 108, 97, 110, 1, 115, 97, 99, 2, 99, 97, 3, 110, 71, 55, 6, 112, 68, 0, 100, 101, 114, 1, 10, 2, 101, 28, 33, 3, 110, 72, 6, 36, 34, 0, 100, 101, 110, 116, 1, 10, 2, 28, 33, 3, 110, 72, 6, 36, 50, 47, 0, 100, 98, 117, 114, 121, 1, 114, 98, 3, 110, 72, 71, 14, 34, 36, 0, 4, 103, 1, 109, 2, 105, 12, 3, 110, 81, 0, 103, 1, 110, 97, 108, 102, 2, 97, 110, 0, 103, 1, 110, 121, 115, 2, 111, 103, 101, 0, 103, 2, 110, 101, 119, 0, 103, 103, 105, 101, 3, 110, 81, 37, 0, 103, 97, 122, 105, 110, 101, 1, 109, 3, 110, 81, 110, 89, 6, 37, 12, 50, 0, 4, 118, 1, 108, 2, 97, 17, 67, 3, 110, 84, 0, 118, 1, 108, 2, 97, 32, 0, 118, 1, 108, 2, 97, 101, 0, 118, 1, 108, 2, 101, 100, 0, 118, 1, 108, 2, 101, 114, 0, 118, 1, 108, 2, 101, 115, 0, 118, 1, 108, 2, 105, 110, 101, 0, 118, 1, 108, 2, 110, 105, 0, 118, 1, 108, 2, 116, 32, 0, 118, 1, 116, 115, 2, 110, 105, 110, 0, 118, 1, 116, 115, 103, 111, 98, 0, 118, 8, 108, 2, 32, 0, 118, 101, 114, 1, 108, 107, 2, 32, 3, 110, 84, 6, 36, 34, 0, 118, 101, 1, 108, 2, 32, 3, 110, 84, 13, 0, 118, 101, 116, 1, 108, 110, 111, 110, 97, 107, 3, 110, 84, 36, 47, 0, 118, 97, 110, 116, 103, 97, 114, 100, 101, 3, 110, 84, 112, 68, 81, 6, 35, 34, 72, 108, 0, 118, 101, 114, 1, 108, 2, 32, 3, 110, 84, 114, 0, 115, 116, 97, 105, 114, 101, 3, 110, 89, 72, 6, 109, 12, 34, 0, 115, 101, 114, 98, 97, 106, 100, 115, 106, 97, 110, 3, 110, 89, 114, 71, 110, 91, 6, 110, 50, 0, 99, 104, 101, 1, 116, 116, 97, 3, 110, 91, 6, 36, 0, 4, 116, 105, 111, 1, 103, 105, 108, 98, 111, 2, 110, 3, 110, 91, 6, 39, 0, 116, 105, 111, 8, 103, 105, 108, 98, 111, 2, 110, 0, 116, 105, 111, 110, 1, 10, 2, 28, 33, 3, 110, 91, 7, 39, 50, 0, 116, 105, 111, 1, 110, 114, 101, 116, 110, 105, 2, 110, 97, 108, 3, 110, 91, 39, 0, 104, 101, 110, 1, 104, 115, 3, 110, 108, 50, 0, 1, 114, 114, 101, 116, 2, 115, 3, 111, 0, 4, 1, 17, 67, 2, 102, 116, 3, 112, 0, 1, 17, 67, 2, 114, 18, 69, 0, 1, 18, 66, 2, 18, 71, 116, 12, 0, 1, 18, 67, 2, 18, 67, 0, 1, 18, 67, 2, 18, 67, 115, 101, 114, 0, 1, 18, 71, 2, 110, 107, 0, 1, 100, 2, 109, 112, 0, 1, 100, 97, 2, 109, 0, 1, 102, 2, 109, 108, 101, 12, 0, 1, 105, 114, 2, 109, 0, 1, 106, 2, 18, 75, 111, 12, 0, 1, 106, 109, 2, 118, 0, 1, 107, 2, 103, 0, 1, 107, 115, 2, 107, 0, 1, 108, 2, 103, 116, 12, 0, 1, 110, 2, 112, 0, 1, 110, 115, 2, 118, 115, 0, 1, 114, 2, 17, 67, 12, 0, 1, 114, 2, 17, 67, 18, 69, 0, 1, 114, 2, 18, 66, 12, 12, 0, 1, 114, 2, 18, 67, 18, 69, 12, 0, 1, 114, 2, 18, 71, 0, 1, 114, 2, 32, 0, 1, 114, 2, 100, 0, 1, 114, 2, 101, 110, 0, 1, 114, 2, 108, 0, 1, 114, 2, 108, 21, 21, 12, 0, 1, 114, 2, 110, 0, 1, 114, 2, 110, 101, 0, 1, 114, 17, 67, 2, 110, 0, 1, 114, 18, 66, 0, 1, 114, 98, 2, 17, 67, 0, 1, 114, 101, 109, 97, 107, 0, 1, 114, 102, 0, 1, 114, 111, 102, 2, 110, 100, 0, 1, 114, 111, 102, 2, 110, 107, 0, 1, 114, 116, 0, 1, 114, 116, 2, 17, 67, 0, 1, 114, 116, 115, 0, 1, 114, 117, 97, 108, 0, 1, 114, 118, 2, 108, 116, 0, 1, 116, 2, 110, 107, 0, 1, 118, 2, 110, 100, 114, 0, 2, 18, 66, 116, 12, 0, 2, 98, 17, 67, 0, 2, 98, 99, 0, 2, 99, 99, 0, 2, 102, 98, 114, 121, 100, 0, 2, 102, 118, 105, 0, 2, 103, 116, 0, 2, 107, 116, 0, 2, 109, 102, 0, 2, 109, 116, 0, 2, 110, 100, 114, 101, 0, 2, 114, 12, 0, 2, 118, 108, 0, 2, 118, 110, 12, 0, 8, 2, 98, 115, 0, 8, 2, 109, 98, 0, 8, 2, 109, 101, 110, 32, 0, 104, 1, 114, 97, 115, 0, 4, 1, 114, 2, 111, 117, 108, 3, 112, 6, 0, 8, 110, 111, 109, 2, 114, 107, 105, 0, 97, 1, 107, 105, 114, 102, 97, 2, 110, 3, 112, 12, 0, 110, 99, 101, 1, 108, 101, 101, 114, 102, 3, 112, 12, 68, 89, 0, 114, 1, 10, 2, 105, 97, 116, 28, 33, 3, 112, 34, 0, 97, 114, 111, 110, 3, 112, 34, 114, 50, 0, 4, 103, 1, 18, 74, 2, 12, 3, 112, 40, 0, 103, 1, 104, 2, 108, 0, 103, 1, 114, 2, 110, 97, 12, 0, 103, 1, 115, 2, 17, 67, 12, 0, 103, 1, 115, 2, 115, 195, 184, 0, 103, 2, 110, 12, 0, 118, 1, 18, 73, 2, 17, 67, 0, 118, 1, 98, 2, 12, 12, 0, 118, 1, 103, 2, 109, 105, 0, 118, 1, 104, 2, 17, 67, 0, 118, 1, 104, 2, 97, 98, 111, 114, 114, 0, 118, 1, 104, 2, 105, 115, 0, 118, 1, 104, 2, 111, 118, 101, 114, 0, 118, 1, 104, 2, 117, 100, 0, 118, 1, 104, 21, 2, 32, 0, 118, 1, 104, 32, 101, 107, 115, 0, 118, 1, 104, 32, 103, 111, 32, 108, 101, 109, 109, 105, 104, 0, 118, 1, 115, 2, 17, 67, 0, 118, 8, 2, 32, 0, 118, 95, 1, 104, 21, 0, 103, 110, 101, 1, 109, 2, 116, 3, 112, 40, 50, 6, 36, 0, 116, 1, 114, 10, 2, 105, 28, 33, 3, 112, 47, 0, 116, 1, 114, 10, 2, 117, 114, 28, 33, 3, 112, 47, 6, 0, 114, 107, 97, 110, 115, 97, 115, 3, 112, 49, 13, 50, 89, 113, 12, 0, 4, 102, 2, 115, 3, 112, 58, 0, 102, 2, 116, 97, 108, 0, 103, 1, 114, 112, 115, 2, 108, 101, 116, 0, 118, 1, 110, 103, 2, 112, 111, 116, 0, 118, 1, 116, 2, 115, 0, 118, 2, 108, 12, 0, 118, 8, 108, 0, 118, 8, 108, 2, 118, 0, 118, 8, 116, 2, 32, 0, 109, 101, 108, 117, 1, 109, 2, 107, 3, 112, 65, 108, 55, 6, 40, 0, 109, 97, 103, 101, 114, 8, 3, 112, 65, 112, 34, 0, 4, 110, 1, 108, 2, 99, 101, 3, 112, 68, 0, 110, 1, 108, 112, 2, 99, 104, 0, 110, 1, 114, 98, 2, 99, 104, 0, 110, 100, 1, 100, 2, 101, 114, 101, 3, 112, 68, 72, 0, 110, 99, 101, 1, 10, 2, 114, 101, 28, 33, 3, 112, 68, 89, 6, 36, 0, 110, 99, 101, 1, 10, 2, 12, 3, 112, 68, 89, 13, 0, 110, 99, 101, 1, 10, 2, 114, 101, 12, 3, 112, 68, 89, 36, 0, 110, 99, 104, 101, 116, 1, 109, 3, 112, 68, 91, 6, 109, 72, 0, 98, 101, 108, 1, 114, 105, 109, 3, 112, 71, 6, 109, 55, 0, 98, 97, 100, 115, 1, 114, 116, 115, 3, 112, 71, 6, 110, 89, 0, 98, 100, 111, 2, 109, 3, 112, 71, 72, 6, 39, 0, 98, 115, 111, 108, 117, 116, 105, 111, 110, 8, 3, 112, 71, 89, 39, 55, 40, 91, 6, 39, 50, 0, 98, 115, 111, 108, 117, 116, 105, 111, 110, 3, 112, 71, 89, 39, 55, 40, 91, 39, 50, 0, 100, 101, 114, 1, 114, 10, 2, 101, 28, 33, 3, 112, 72, 6, 36, 34, 0, 100, 97, 114, 1, 114, 3, 112, 72, 112, 34, 0, 114, 103, 101, 1, 108, 3, 112, 75, 0, 103, 103, 101, 114, 1, 100, 2, 116, 3, 112, 81, 114, 0, 102, 97, 101, 1, 114, 3, 112, 83, 110, 6, 36, 0, 116, 105, 111, 110, 1, 114, 10, 2, 28, 33, 3, 112, 91, 6, 39, 50, 0, 101, 114, 1, 114, 2, 32, 3, 112, 114, 0, 4, 1, 119, 2, 116, 101, 114, 3, 113, 0, 8, 116, 115, 2, 108, 108, 0, 117, 1, 115, 2, 116, 101, 114, 101, 0, 117, 8, 112, 2, 108, 0, 119, 1, 114, 0, 117, 1, 115, 2, 99, 101, 3, 113, 12, 0, 108, 108, 1, 98, 121, 101, 108, 108, 111, 118, 3, 113, 12, 55, 0, 117, 98, 114, 101, 121, 3, 113, 12, 71, 34, 37, 0, 117, 100, 114, 101, 121, 3, 113, 12, 72, 51, 37, 0, 117, 114, 105, 101, 1, 108, 3, 113, 34, 37, 0, 97, 103, 101, 8, 3, 113, 40, 108, 0, 108, 107, 1, 116, 2, 115, 104, 111, 119, 3, 113, 49, 0, 117, 114, 101, 101, 110, 1, 109, 3, 113, 51, 6, 37, 12, 50, 0, 108, 108, 2, 32, 114, 105, 103, 104, 116, 3, 113, 55, 0, 108, 100, 105, 110, 103, 1, 112, 115, 3, 113, 55, 72, 4, 36, 68, 0, 119, 1, 114, 99, 3, 114, 0, 108, 1, 119, 2, 107, 3, 114, 12, 0, 108, 108, 1, 119, 3, 114, 12, 55, 0, 119, 114, 101, 110, 99, 101, 1, 108, 3, 115, 34, 13, 50, 89, 0, 7, 6, 98, 0, 4, 1, 184, 195, 107, 2, 109, 97, 3, 0, 1, 184, 195, 107, 2, 109, 195, 166, 3, 0, 4, 114, 111, 119, 110, 3, 21, 0, 121, 114, 111, 110, 0, 2, 32, 3, 48, 0, 4, 1, 101, 112, 2, 101, 114, 3, 58, 0, 1, 101, 112, 2, 114, 101, 0, 98, 1, 111, 107, 2, 101, 114, 0, 4, 3, 71, 0, 98, 0, 101, 97, 116, 8, 3, 71, 6, 37, 12, 47, 0, 111, 110, 107, 97, 109, 109, 101, 114, 97, 116, 3, 71, 6, 114, 68, 49, 35, 65, 13, 34, 112, 47, 0, 114, 97, 105, 108, 108, 101, 3, 71, 34, 35, 57, 12, 0, 114, 105, 110, 116, 105, 111, 110, 3, 71, 34, 36, 50, 72, 57, 39, 12, 50, 0, 114, 111, 97, 100, 3, 71, 34, 113, 72, 0, 97, 114, 121, 116, 111, 110, 3, 71, 35, 37, 47, 114, 50, 0, 101, 105, 2, 114, 117, 116, 3, 71, 35, 57, 0, 105, 107, 101, 3, 71, 35, 57, 49, 0, 117, 105, 2, 108, 100, 105, 110, 103, 3, 71, 36, 0, 97, 115, 101, 98, 97, 108, 108, 3, 71, 36, 57, 89, 82, 113, 12, 59, 0, 105, 110, 103, 104, 97, 109, 3, 71, 36, 68, 108, 65, 0, 117, 115, 105, 110, 101, 115, 115, 3, 71, 36, 89, 50, 109, 89, 0, 101, 97, 2, 116, 114, 105, 3, 71, 36, 110, 6, 0, 101, 101, 1, 115, 105, 114, 102, 3, 71, 37, 0, 101, 98, 111, 112, 3, 71, 37, 12, 71, 114, 48, 0, 101, 97, 99, 104, 3, 71, 37, 12, 76, 0, 101, 97, 103, 108, 101, 3, 71, 37, 12, 81, 13, 55, 0, 105, 108, 108, 105, 101, 3, 71, 37, 59, 37, 0, 101, 97, 117, 106, 111, 108, 97, 105, 115, 3, 71, 39, 91, 57, 39, 55, 6, 109, 0, 111, 117, 114, 103, 111, 103, 110, 101, 3, 71, 40, 34, 81, 6, 114, 50, 57, 13, 0, 111, 117, 105, 108, 108, 2, 111, 110, 3, 71, 40, 55, 57, 0, 111, 117, 105, 108, 108, 97, 98, 97, 105, 115, 115, 101, 3, 71, 40, 57, 35, 71, 6, 109, 89, 0, 111, 117, 100, 111, 105, 114, 3, 71, 40, 72, 58, 6, 112, 12, 0, 114, 117, 99, 101, 8, 3, 71, 51, 40, 12, 89, 0, 114, 111, 119, 115, 101, 114, 3, 71, 51, 112, 58, 89, 114, 0, 108, 97, 107, 101, 8, 3, 71, 55, 109, 57, 49, 0, 108, 105, 103, 104, 8, 3, 71, 55, 112, 57, 0, 108, 111, 111, 100, 121, 3, 71, 55, 114, 72, 37, 0, 117, 116, 116, 101, 8, 2, 32, 3, 71, 57, 40, 12, 47, 0, 117, 105, 99, 8, 3, 71, 57, 40, 37, 49, 0, 101, 108, 108, 101, 118, 117, 101, 3, 71, 109, 55, 13, 84, 6, 116, 0, 101, 105, 106, 105, 110, 103, 3, 71, 109, 57, 75, 6, 36, 68, 0, 101, 118, 101, 114, 108, 121, 3, 71, 109, 84, 114, 55, 37, 0, 97, 99, 107, 117, 112, 8, 3, 71, 110, 49, 6, 114, 71, 0, 97, 108, 107, 111, 110, 8, 3, 71, 110, 55, 49, 6, 114, 68, 0, 97, 108, 107, 111, 110, 3, 71, 110, 55, 49, 114, 68, 0, 97, 98, 121, 108, 111, 110, 2, 101, 114, 3, 71, 110, 71, 116, 55, 6, 39, 50, 0, 97, 98, 121, 108, 111, 110, 2, 105, 115, 107, 3, 71, 110, 71, 116, 55, 39, 50, 0, 97, 98, 121, 108, 111, 110, 3, 71, 110, 71, 116, 55, 114, 50, 0, 97, 99, 107, 103, 97, 109, 109, 111, 110, 3, 71, 110, 81, 6, 110, 65, 108, 50, 0, 97, 115, 115, 105, 110, 1, 10, 3, 71, 110, 89, 6, 109, 68, 0, 97, 114, 98, 105, 101, 3, 71, 112, 34, 71, 37, 0, 97, 115, 107, 101, 116, 98, 97, 108, 108, 3, 71, 112, 89, 81, 36, 47, 71, 113, 12, 55, 0, 111, 97, 114, 100, 3, 71, 113, 12, 72, 0, 97, 108, 116, 105, 109, 111, 114, 101, 3, 71, 113, 55, 47, 37, 65, 114, 12, 0, 111, 110, 101, 1, 32, 116, 3, 71, 113, 58, 50, 0, 111, 114, 111, 117, 103, 104, 3, 71, 114, 34, 114, 0, 117, 116, 116, 101, 114, 102, 108, 121, 3, 71, 114, 47, 114, 83, 55, 35, 57, 0, 111, 100, 121, 103, 117, 97, 114, 100, 3, 71, 114, 72, 37, 81, 112, 12, 72, 0, 111, 100, 121, 115, 116, 111, 99, 107, 105, 110, 103, 3, 71, 114, 72, 37, 89, 47, 114, 49, 36, 68, 0, 117, 103, 115, 121, 3, 71, 114, 81, 89, 37, 0, 117, 102, 102, 97, 108, 111, 3, 71, 114, 83, 108, 55, 113, 58, 0, 4, 117, 102, 102, 101, 116, 1, 21, 3, 71, 116, 83, 6, 36, 0, 117, 102, 102, 101, 116, 8, 0, 117, 114, 103, 104, 3, 71, 118, 12, 81, 0, 117, 114, 116, 111, 110, 3, 71, 118, 47, 114, 50, 0, 101, 114, 110, 105, 101, 3, 71, 118, 50, 37, 0, 105, 114, 109, 105, 110, 103, 104, 97, 109, 3, 71, 118, 65, 37, 68, 13, 65, 0, 117, 114, 103, 101, 115, 115, 3, 71, 118, 75, 36, 89, 0, 7, 6, 99, 0, 4, 1, 115, 2, 104, 97, 3, 0, 2, 107, 3, 0, 99, 1, 101, 98, 101, 114, 2, 97, 3, 8, 49, 0, 101, 114, 1, 105, 100, 101, 100, 2, 28, 33, 3, 8, 49, 7, 36, 34, 0, 1, 105, 114, 101, 100, 101, 114, 102, 2, 105, 97, 3, 8, 49, 89, 0, 101, 114, 1, 10, 2, 28, 33, 3, 8, 89, 7, 36, 34, 0, 101, 114, 101, 1, 10, 2, 28, 33, 3, 8, 89, 7, 36, 34, 108, 0, 4, 101, 1, 10, 2, 32, 28, 33, 3, 8, 89, 13, 0, 101, 1, 10, 2, 110, 28, 33, 0, 101, 1, 10, 2, 114, 28, 33, 3, 8, 89, 114, 0, 101, 114, 101, 110, 1, 117, 100, 111, 114, 112, 3, 8, 89, 114, 108, 50, 0, 101, 110, 101, 1, 115, 3, 36, 50, 108, 0, 101, 110, 101, 114, 1, 115, 3, 36, 50, 114, 0, 104, 105, 110, 97, 3, 47, 57, 35, 57, 50, 110, 0, 104, 97, 2, 116, 3, 47, 57, 110, 0, 4, 3, 49, 0, 1, 97, 108, 108, 105, 100, 97, 99, 0, 99, 1, 105, 112, 2, 111, 0, 99, 1, 111, 114, 2, 111, 0, 99, 1, 111, 115, 2, 101, 114, 0, 104, 1, 101, 116, 2, 110, 111, 0, 104, 1, 105, 109, 2, 97, 0, 104, 1, 105, 110, 2, 111, 108, 0, 104, 1, 111, 115, 97, 109, 2, 105, 115, 0, 104, 2, 108, 111, 101, 0, 104, 2, 114, 0, 104, 8, 97, 109, 2, 32, 0, 115, 1, 110, 97, 114, 102, 0, 99, 1, 97, 116, 115, 2, 97, 116, 111, 3, 49, 6, 0, 114, 101, 101, 107, 3, 49, 34, 37, 12, 49, 0, 114, 101, 97, 115, 121, 3, 49, 34, 37, 89, 37, 0, 114, 111, 105, 115, 115, 97, 110, 116, 3, 49, 34, 39, 35, 89, 6, 112, 68, 0, 114, 101, 109, 101, 3, 49, 34, 109, 12, 65, 0, 97, 114, 116, 105, 101, 114, 8, 3, 49, 35, 34, 47, 57, 6, 36, 0, 111, 119, 98, 111, 121, 3, 49, 35, 40, 71, 113, 57, 0, 97, 109, 101, 109, 98, 101, 114, 116, 3, 49, 35, 65, 112, 68, 71, 6, 109, 34, 0, 97, 109, 98, 114, 105, 100, 103, 101, 3, 49, 36, 57, 65, 71, 51, 37, 75, 0, 111, 108, 97, 100, 97, 3, 49, 39, 55, 6, 112, 86, 110, 0, 114, 97, 122, 121, 3, 49, 51, 109, 57, 89, 37, 0, 108, 101, 118, 101, 108, 97, 110, 100, 3, 49, 55, 37, 12, 84, 55, 110, 50, 0, 108, 97, 105, 114, 2, 118, 111, 121, 3, 49, 55, 109, 34, 0, 108, 97, 114, 101, 110, 99, 101, 8, 3, 49, 55, 110, 51, 13, 50, 89, 0, 108, 101, 114, 107, 3, 49, 55, 112, 12, 49, 0, 108, 97, 117, 100, 101, 3, 49, 55, 113, 12, 72, 0, 108, 97, 117, 100, 101, 116, 116, 101, 3, 49, 55, 113, 72, 6, 36, 47, 0, 104, 105, 97, 110, 116, 105, 3, 49, 57, 6, 110, 50, 47, 37, 0, 99, 3, 49, 89, 0, 97, 116, 101, 114, 105, 110, 103, 3, 49, 109, 37, 47, 13, 34, 37, 68, 0, 97, 112, 101, 8, 2, 32, 116, 111, 119, 110, 3, 49, 109, 57, 48, 0, 97, 106, 117, 110, 3, 49, 109, 75, 108, 50, 0, 97, 114, 111, 108, 105, 110, 97, 1, 32, 104, 116, 114, 111, 110, 3, 49, 110, 34, 39, 55, 6, 35, 57, 50, 110, 0, 97, 112, 111, 110, 101, 8, 3, 49, 110, 48, 6, 113, 58, 50, 0, 97, 110, 116, 101, 114, 98, 117, 114, 121, 3, 49, 110, 50, 47, 114, 71, 34, 37, 0, 97, 103, 110, 101, 121, 8, 3, 49, 110, 81, 50, 37, 0, 97, 116, 104, 121, 8, 3, 49, 110, 87, 37, 0, 97, 114, 109, 105, 110, 101, 3, 49, 112, 12, 65, 35, 57, 50, 0, 97, 114, 100, 105, 110, 8, 3, 49, 112, 34, 72, 6, 110, 68, 0, 97, 114, 108, 105, 115, 108, 101, 3, 49, 112, 55, 35, 57, 55, 0, 111, 117, 114, 116, 110, 101, 121, 3, 49, 113, 12, 47, 50, 37, 0, 111, 104, 101, 110, 3, 49, 113, 40, 13, 50, 0, 111, 108, 101, 114, 105, 100, 103, 101, 3, 49, 113, 58, 55, 34, 37, 75, 0, 111, 2, 110, 114, 97, 100, 3, 49, 114, 0, 111, 114, 110, 2, 102, 3, 49, 114, 12, 50, 0, 111, 114, 110, 105, 99, 104, 111, 110, 3, 49, 114, 34, 50, 37, 91, 6, 114, 68, 0, 111, 116, 116, 97, 103, 101, 3, 49, 114, 47, 37, 75, 0, 117, 116, 108, 101, 114, 3, 49, 114, 47, 55, 114, 0, 111, 99, 107, 110, 101, 121, 3, 49, 114, 49, 50, 37, 0, 111, 110, 110, 101, 99, 116, 105, 99, 117, 116, 3, 49, 114, 50, 6, 36, 47, 37, 49, 114, 72, 0, 111, 110, 110, 105, 101, 3, 49, 114, 50, 37, 0, 111, 117, 110, 116, 114, 121, 3, 49, 114, 50, 47, 34, 37, 0, 111, 110, 110, 111, 114, 3, 49, 114, 50, 114, 0, 97, 108, 108, 103, 105, 114, 108, 3, 49, 114, 55, 81, 118, 12, 55, 0, 111, 109, 112, 117, 116, 101, 114, 3, 49, 114, 65, 48, 57, 6, 40, 12, 47, 114, 0, 111, 114, 100, 101, 108, 105, 97, 3, 49, 114, 72, 6, 37, 55, 37, 20, 110, 0, 117, 115, 116, 101, 114, 8, 3, 49, 114, 89, 47, 114, 0, 121, 112, 101, 114, 3, 49, 116, 48, 114, 0, 117, 114, 108, 101, 114, 3, 49, 118, 55, 114, 0, 4, 104, 1, 105, 119, 3, 76, 0, 104, 2, 101, 101, 115, 101, 0, 104, 2, 105, 0, 4, 1, 114, 111, 99, 115, 2, 101, 115, 101, 3, 76, 6, 0, 8, 97, 112, 2, 105, 110, 111, 0, 104, 105, 108, 100, 3, 76, 35, 57, 55, 72, 0, 104, 105, 104, 117, 97, 104, 117, 97, 3, 76, 37, 58, 6, 35, 58, 35, 0, 104, 2, 105, 112, 3, 76, 57, 0, 99, 1, 117, 112, 112, 97, 99, 2, 105, 110, 111, 3, 76, 57, 6, 0, 105, 97, 111, 8, 2, 32, 3, 76, 57, 112, 58, 0, 104, 101, 108, 115, 101, 97, 3, 76, 109, 55, 89, 37, 0, 104, 97, 112, 108, 105, 110, 3, 76, 110, 48, 55, 37, 50, 0, 104, 97, 108, 108, 101, 110, 103, 101, 3, 76, 110, 55, 36, 50, 75, 0, 104, 97, 114, 108, 101, 115, 3, 76, 112, 12, 55, 89, 0, 104, 97, 114, 108, 105, 101, 3, 76, 112, 55, 37, 0, 104, 97, 117, 99, 101, 114, 3, 76, 113, 12, 89, 114, 0, 104, 117, 99, 107, 8, 3, 76, 114, 49, 0, 104, 117, 114, 99, 104, 105, 108, 108, 3, 76, 118, 12, 91, 37, 55, 0, 4, 1, 17, 65, 2, 101, 3, 89, 0, 1, 97, 102, 2, 97, 100, 0, 1, 97, 102, 2, 111, 110, 0, 2, 101, 0, 2, 101, 108, 108, 111, 102, 97, 110, 0, 2, 105, 0, 2, 121, 0, 2, 195, 166, 115, 97, 114, 0, 2, 195, 184, 108, 105, 98, 97, 116, 0, 101, 8, 105, 108, 97, 0, 101, 8, 105, 102, 102, 111, 2, 114, 3, 89, 6, 36, 0, 195, 169, 114, 1, 10, 2, 32, 3, 89, 6, 36, 34, 0, 101, 2, 114, 116, 3, 89, 6, 109, 0, 195, 184, 114, 1, 10, 2, 32, 3, 89, 6, 118, 34, 0, 101, 121, 108, 111, 110, 3, 89, 35, 57, 59, 114, 50, 0, 101, 1, 105, 102, 102, 111, 2, 114, 3, 89, 36, 0, 101, 114, 1, 105, 102, 105, 108, 97, 118, 107, 115, 105, 100, 3, 89, 36, 34, 0, 121, 110, 116, 104, 105, 97, 3, 89, 36, 50, 87, 37, 110, 0, 105, 110, 99, 105, 110, 110, 97, 116, 105, 3, 89, 36, 50, 89, 37, 50, 6, 110, 47, 37, 0, 195, 169, 122, 97, 110, 110, 101, 3, 89, 36, 89, 6, 110, 50, 0, 195, 169, 122, 97, 110, 110, 101, 110, 3, 89, 36, 89, 6, 110, 50, 108, 50, 0, 4, 105, 103, 97, 114, 101, 116, 3, 89, 37, 81, 108, 34, 6, 111, 47, 0, 105, 103, 97, 114, 101, 116, 116, 0, 105, 101, 117, 120, 3, 89, 57, 6, 118, 0, 105, 114, 99, 117, 115, 1, 32, 121, 108, 108, 105, 100, 97, 99, 99, 105, 112, 3, 89, 118, 49, 13, 89, 0, 4, 2, 104, 97, 3, 91, 0, 104, 1, 114, 0, 104, 2, 12, 0, 104, 2, 97, 116, 101, 97, 117, 0, 99, 105, 110, 105, 1, 117, 112, 3, 91, 6, 37, 50, 37, 0, 104, 101, 121, 101, 110, 110, 101, 3, 91, 35, 57, 6, 109, 50, 0, 104, 105, 99, 97, 103, 111, 3, 91, 37, 49, 6, 112, 81, 113, 58, 0, 104, 111, 112, 105, 110, 3, 91, 39, 48, 109, 68, 0, 2, 101, 108, 108, 111, 3, 91, 57, 0, 104, 101, 114, 121, 108, 3, 91, 109, 34, 36, 59, 0, 104, 97, 98, 108, 105, 115, 3, 91, 110, 71, 55, 6, 37, 0, 104, 97, 103, 97, 108, 108, 3, 91, 110, 81, 6, 110, 55, 0, 104, 111, 107, 101, 114, 101, 110, 2, 32, 3, 91, 113, 58, 49, 114, 34, 13, 50, 0, 7, 6, 100, 0, 4, 1, 17, 65, 2, 116, 32, 12, 12, 3, 0, 4, 1, 17, 65, 2, 116, 101, 32, 12, 12, 3, 0, 4, 1, 17, 65, 2, 116, 101, 114, 32, 12, 12, 3, 0, 4, 1, 97, 118, 104, 3, 0, 4, 1, 101, 114, 107, 2, 115, 3, 0, 4, 1, 105, 2, 116, 3, 0, 4, 1, 105, 98, 2, 115, 107, 3, 0, 4, 1, 105, 103, 2, 115, 12, 3, 0, 4, 1, 105, 116, 2, 115, 101, 108, 3, 0, 4, 1, 108, 3, 0, 4, 1, 108, 101, 109, 2, 105, 110, 103, 3, 0, 4, 1, 108, 117, 103, 3, 0, 4, 1, 110, 97, 2, 101, 3, 0, 4, 1, 110, 105, 2, 17, 67, 3, 0, 4, 1, 114, 101, 106, 102, 2, 101, 3, 0, 4, 1, 114, 111, 2, 101, 3, 0, 4, 1, 114, 111, 107, 105, 116, 115, 3, 0, 4, 1, 114, 165, 195, 104, 3, 0, 4, 1, 114, 166, 195, 2, 32, 3, 0, 4, 1, 114, 166, 195, 102, 3, 0, 4, 1, 114, 166, 195, 118, 2, 115, 3, 0, 4, 1, 114, 166, 195, 118, 115, 3, 0, 4, 1, 114, 166, 195, 118, 115, 2, 101, 116, 3, 0, 4, 1, 117, 98, 2, 103, 101, 116, 3, 0, 4, 1, 184, 195, 2, 115, 101, 108, 12, 12, 3, 0, 4, 1, 184, 195, 2, 116, 3, 0, 4, 1, 184, 195, 102, 2, 115, 12, 12, 3, 0, 4, 2, 115, 116, 12, 12, 3, 0, 4, 8, 97, 109, 2, 115, 101, 110, 3, 0, 4, 8, 114, 117, 116, 2, 101, 3, 0, 101, 8, 110, 97, 102, 2, 109, 101, 3, 0, 4, 1, 105, 100, 110, 97, 107, 2, 97, 116, 3, 6, 72, 0, 1, 111, 109, 2, 97, 108, 0, 1, 108, 101, 109, 105, 2, 97, 3, 8, 72, 0, 4, 111, 114, 111, 116, 104, 121, 3, 21, 0, 114, 105, 115, 99, 111, 0, 4, 97, 117, 109, 105, 101, 114, 3, 21, 102, 114, 0, 101, 103, 97, 115, 8, 0, 105, 1, 114, 101, 106, 102, 2, 110, 103, 3, 36, 0, 4, 1, 111, 111, 119, 3, 47, 0, 116, 1, 101, 102, 2, 21, 0, 116, 1, 101, 114, 112, 115, 0, 116, 1, 105, 107, 115, 0, 116, 1, 117, 2, 12, 0, 101, 1, 108, 97, 98, 3, 55, 108, 0, 4, 3, 72, 0, 1, 17, 67, 2, 101, 116, 17, 65, 0, 1, 21, 2, 101, 108, 116, 0, 1, 21, 2, 121, 114, 0, 1, 97, 2, 97, 109, 0, 1, 97, 2, 111, 112, 116, 101, 114, 0, 1, 97, 109, 2, 114, 97, 115, 0, 1, 101, 2, 103, 97, 114, 0, 1, 101, 109, 2, 97, 108, 106, 0, 1, 101, 109, 111, 114, 100, 2, 97, 114, 0, 1, 101, 110, 101, 118, 2, 105, 103, 0, 1, 101, 112, 2, 114, 111, 0, 1, 101, 114, 2, 97, 0, 1, 105, 2, 111, 108, 0, 1, 105, 99, 97, 2, 111, 115, 101, 0, 1, 105, 115, 2, 101, 110, 116, 0, 1, 105, 118, 101, 2, 101, 110, 0, 1, 108, 2, 97, 107, 105, 110, 0, 1, 108, 2, 105, 103, 0, 1, 108, 2, 117, 103, 0, 1, 108, 97, 2, 114, 105, 103, 0, 1, 108, 97, 109, 114, 111, 102, 2, 101, 0, 1, 108, 97, 115, 2, 111, 0, 1, 108, 101, 104, 2, 105, 0, 1, 108, 101, 116, 114, 117, 116, 2, 117, 101, 0, 1, 108, 101, 118, 2, 114, 101, 106, 0, 1, 108, 105, 2, 114, 105, 110, 103, 0, 1, 108, 105, 98, 2, 195, 166, 107, 0, 1, 108, 105, 100, 2, 111, 0, 1, 108, 105, 107, 2, 114, 101, 0, 1, 108, 108, 117, 98, 2, 111, 0, 1, 108, 111, 2, 105, 110, 103, 0, 1, 108, 111, 98, 0, 1, 108, 111, 115, 2, 195, 166, 107, 0, 1, 110, 17, 65, 2, 114, 17, 65, 0, 1, 110, 17, 65, 2, 114, 101, 0, 1, 110, 105, 2, 117, 0, 1, 110, 105, 2, 117, 17, 67, 0, 1, 110, 111, 104, 2, 117, 114, 97, 0, 1, 111, 98, 2, 101, 103, 97, 0, 1, 111, 109, 2, 101, 108, 0, 1, 111, 109, 2, 101, 109, 0, 1, 111, 109, 2, 101, 114, 110, 0, 1, 114, 101, 118, 2, 101, 110, 0, 1, 114, 105, 2, 32, 0, 1, 114, 111, 2, 101, 108, 0, 1, 114, 111, 2, 101, 110, 0, 1, 114, 111, 2, 101, 114, 0, 1, 114, 111, 106, 104, 0, 1, 114, 111, 107, 97, 0, 1, 114, 111, 107, 101, 114, 0, 1, 114, 166, 195, 102, 2, 101, 17, 67, 0, 1, 114, 166, 195, 108, 2, 32, 0, 1, 114, 166, 195, 118, 2, 105, 0, 1, 117, 98, 2, 97, 112, 101, 115, 116, 0, 1, 117, 108, 107, 2, 101, 114, 101, 0, 1, 117, 109, 114, 101, 98, 2, 97, 0, 1, 121, 111, 108, 102, 0, 1, 165, 195, 2, 97, 110, 0, 1, 166, 195, 2, 114, 117, 0, 1, 166, 195, 112, 2, 97, 0, 2, 97, 103, 0, 2, 101, 108, 101, 0, 2, 101, 109, 101, 110, 115, 0, 2, 105, 0, 2, 111, 98, 108, 0, 2, 111, 107, 0, 2, 111, 108, 108, 0, 2, 111, 109, 0, 2, 111, 110, 110, 97, 0, 2, 114, 97, 109, 97, 0, 2, 114, 101, 118, 0, 2, 114, 121, 115, 0, 2, 117, 102, 116, 101, 0, 2, 117, 115, 0, 2, 195, 165, 115, 101, 0, 2, 195, 184, 109, 0, 2, 195, 184, 114, 0, 8, 97, 2, 114, 0, 8, 105, 2, 101, 0, 8, 105, 2, 195, 169, 0, 8, 108, 105, 104, 2, 97, 0, 39, 0, 100, 1, 105, 109, 2, 97, 0, 100, 104, 1, 117, 98, 0, 100, 104, 1, 117, 98, 2, 105, 115, 116, 0, 4, 1, 110, 101, 112, 2, 117, 108, 3, 72, 6, 0, 1, 111, 109, 2, 117, 108, 0, 101, 1, 105, 107, 114, 111, 3, 72, 6, 36, 0, 101, 110, 100, 114, 111, 110, 3, 72, 6, 36, 50, 72, 34, 114, 50, 0, 105, 1, 117, 111, 104, 2, 110, 105, 3, 72, 6, 37, 0, 111, 115, 1, 101, 110, 114, 117, 111, 116, 3, 72, 6, 39, 0, 4, 117, 1, 97, 105, 118, 2, 107, 116, 3, 72, 6, 113, 0, 117, 8, 111, 114, 112, 2, 107, 116, 0, 111, 114, 1, 97, 118, 108, 97, 115, 3, 72, 6, 113, 12, 0, 114, 101, 100, 8, 108, 105, 109, 3, 72, 34, 109, 72, 0, 111, 119, 110, 3, 72, 35, 58, 50, 0, 111, 119, 110, 108, 111, 97, 100, 3, 72, 35, 58, 50, 55, 39, 58, 72, 0, 111, 117, 98, 116, 102, 105, 114, 101, 3, 72, 35, 58, 72, 83, 35, 57, 114, 0, 4, 101, 1, 105, 117, 103, 2, 110, 3, 72, 36, 0, 101, 1, 121, 98, 2, 108, 0, 101, 116, 101, 110, 116, 101, 3, 72, 36, 47, 6, 112, 12, 68, 47, 0, 101, 116, 114, 111, 105, 116, 3, 72, 36, 47, 34, 6, 114, 57, 47, 0, 4, 105, 99, 107, 105, 101, 3, 72, 36, 49, 37, 0, 105, 99, 107, 121, 0, 105, 103, 1, 114, 166, 195, 102, 3, 72, 37, 0, 101, 97, 110, 8, 3, 72, 37, 12, 50, 0, 111, 114, 97, 100, 111, 1, 108, 101, 3, 72, 39, 34, 6, 112, 72, 39, 0, 111, 117, 103, 104, 110, 117, 116, 3, 72, 39, 58, 50, 114, 72, 0, 117, 8, 111, 114, 112, 2, 107, 116, 105, 118, 3, 72, 40, 0, 114, 105, 118, 101, 8, 2, 45, 3, 72, 51, 112, 57, 84, 0, 4, 117, 99, 101, 114, 1, 111, 114, 112, 2, 32, 3, 72, 57, 6, 40, 89, 114, 0, 117, 99, 101, 114, 1, 111, 114, 112, 2, 97, 115, 115, 105, 115, 116, 101, 110, 116, 0, 101, 119, 101, 121, 3, 72, 57, 40, 37, 0, 119, 105, 103, 104, 116, 3, 72, 58, 35, 57, 47, 0, 100, 115, 1, 111, 3, 72, 89, 0, 115, 116, 111, 110, 101, 1, 97, 108, 103, 3, 72, 89, 47, 115, 58, 50, 0, 101, 98, 98, 105, 101, 3, 72, 109, 71, 37, 0, 97, 114, 121, 108, 3, 72, 110, 34, 108, 59, 0, 97, 105, 113, 117, 105, 114, 105, 3, 72, 110, 49, 13, 34, 37, 0, 97, 114, 108, 101, 110, 101, 3, 72, 112, 55, 6, 37, 50, 0, 97, 118, 8, 2, 32, 3, 72, 112, 58, 0, 97, 118, 115, 8, 2, 32, 3, 72, 112, 58, 89, 0, 117, 110, 100, 1, 101, 114, 2, 97, 110, 116, 3, 72, 113, 50, 72, 0, 101, 114, 1, 105, 117, 103, 3, 72, 114, 0, 97, 119, 115, 111, 110, 3, 72, 114, 12, 89, 108, 50, 0, 111, 99, 8, 2, 32, 3, 72, 114, 49, 0, 111, 117, 98, 108, 101, 3, 72, 114, 71, 13, 55, 0, 111, 117, 98, 108, 101, 116, 111, 110, 3, 72, 114, 71, 13, 55, 47, 114, 50, 0, 111, 100, 103, 101, 3, 72, 114, 75, 0, 117, 116, 99, 104, 3, 72, 114, 76, 0, 111, 114, 101, 101, 110, 8, 3, 72, 115, 34, 6, 37, 50, 0, 117, 98, 111, 105, 115, 3, 72, 116, 71, 58, 6, 112, 0, 117, 107, 101, 8, 3, 75, 40, 12, 49, 0, 101, 117, 99, 101, 3, 75, 40, 12, 89, 0, 4, 1, 17, 65, 3, 86, 0, 1, 17, 65, 2, 17, 67, 0, 1, 17, 65, 2, 101, 115, 0, 1, 17, 65, 2, 105, 103, 0, 1, 17, 65, 18, 74, 2, 116, 97, 0, 1, 97, 98, 2, 101, 0, 1, 100, 101, 110, 2, 115, 0, 1, 101, 110, 2, 115, 116, 0, 1, 101, 114, 102, 2, 115, 0, 1, 105, 2, 116, 105, 12, 0, 1, 105, 98, 2, 101, 0, 1, 105, 112, 115, 2, 115, 116, 101, 103, 0, 1, 105, 114, 2, 101, 0, 1, 105, 114, 116, 115, 2, 115, 0, 1, 105, 116, 2, 101, 0, 1, 105, 116, 2, 115, 12, 0, 1, 105, 118, 2, 101, 114, 0, 1, 111, 102, 2, 17, 67, 12, 12, 0, 1, 111, 109, 2, 115, 116, 12, 0, 1, 117, 2, 105, 0, 1, 117, 2, 115, 116, 121, 114, 12, 0, 1, 117, 98, 2, 115, 12, 12, 0, 1, 121, 2, 115, 116, 97, 116, 12, 0, 1, 121, 98, 2, 101, 108, 105, 103, 0, 1, 121, 108, 0, 1, 166, 195, 114, 2, 115, 101, 108, 0, 1, 184, 195, 2, 115, 12, 12, 0, 1, 184, 195, 100, 2, 12, 0, 8, 117, 2, 12, 12, 0, 100, 1, 17, 65, 0, 100, 1, 17, 65, 2, 17, 65, 12, 0, 101, 1, 97, 2, 108, 3, 86, 13, 0, 105, 1, 17, 65, 2, 115, 107, 3, 86, 37, 0, 4, 100, 1, 101, 109, 2, 101, 108, 3, 86, 72, 0, 100, 1, 117, 2, 97, 110, 110, 0, 100, 1, 117, 2, 195, 184, 12, 0, 100, 1, 117, 103, 2, 12, 12, 0, 100, 1, 117, 107, 115, 2, 117, 12, 0, 100, 1, 117, 108, 2, 111, 118, 0, 100, 1, 121, 108, 2, 195, 166, 109, 112, 0, 115, 1, 17, 65, 2, 195, 166, 116, 3, 86, 89, 0, 4, 101, 1, 17, 65, 2, 32, 3, 86, 108, 0, 101, 1, 97, 2, 17, 67, 114, 0, 101, 1, 121, 0, 101, 1, 121, 98, 100, 110, 105, 0, 101, 1, 166, 195, 2, 108, 12, 0, 101, 1, 121, 115, 2, 110, 103, 3, 86, 109, 0, 101, 114, 1, 121, 2, 32, 3, 86, 114, 0, 4, 115, 1, 17, 65, 2, 101, 108, 3, 89, 0, 115, 1, 97, 108, 112, 0, 115, 1, 97, 112, 115, 2, 101, 114, 0, 115, 1, 97, 114, 107, 0, 115, 1, 97, 116, 115, 0, 115, 1, 101, 114, 102, 108, 0, 115, 1, 105, 104, 0, 115, 1, 105, 104, 2, 101, 0, 115, 1, 105, 112, 0, 115, 1, 105, 114, 0, 115, 1, 117, 109, 115, 0, 115, 1, 117, 112, 0, 115, 1, 117, 114, 116, 115, 0, 115, 1, 117, 116, 2, 101, 0, 115, 1, 117, 116, 115, 0, 115, 1, 121, 0, 115, 1, 105, 116, 2, 110, 111, 107, 3, 89, 6, 0, 115, 101, 108, 1, 117, 108, 112, 3, 89, 59, 0, 101, 1, 114, 166, 195, 103, 3, 114, 0, 7, 6, 101, 0, 4, 1, 99, 97, 102, 114, 101, 116, 110, 105, 3, 0, 4, 1, 99, 97, 112, 2, 109, 97, 107, 101, 114, 3, 0, 4, 1, 99, 97, 112, 114, 111, 116, 111, 109, 3, 0, 4, 1, 99, 101, 101, 108, 102, 3, 0, 4, 1, 99, 105, 112, 115, 111, 104, 2, 32, 3, 0, 4, 1, 99, 105, 116, 102, 111, 115, 3, 0, 4, 1, 99, 105, 117, 106, 3, 0, 4, 1, 99, 105, 118, 114, 101, 115, 2, 102, 97, 103, 3, 0, 4, 1, 99, 105, 118, 114, 101, 115, 2, 109, 101, 100, 3, 0, 4, 1, 99, 105, 118, 114, 101, 115, 2, 115, 101, 107, 116, 111, 114, 3, 0, 4, 1, 99, 105, 118, 114, 101, 115, 2, 115, 116, 97, 116, 105, 111, 110, 3, 0, 4, 1, 99, 105, 118, 114, 101, 115, 2, 121, 100, 101, 108, 115, 101, 3, 0, 4, 1, 99, 110, 97, 108, 101, 101, 114, 102, 3, 0, 4, 1, 99, 110, 101, 112, 3, 0, 4, 1, 99, 110, 101, 118, 111, 114, 112, 3, 0, 4, 1, 99, 117, 97, 115, 3, 0, 4, 1, 99, 121, 111, 106, 3, 0, 4, 1, 105, 112, 117, 111, 114, 103, 3, 0, 4, 1, 105, 114, 98, 2, 102, 3, 0, 4, 1, 108, 108, 2, 100, 101, 3, 0, 4, 1, 116, 115, 97, 116, 117, 97, 98, 2, 110, 3, 0, 4, 8, 99, 105, 102, 102, 111, 2, 32, 3, 0, 4, 8, 105, 110, 3, 0, 4, 8, 105, 110, 97, 106, 3, 0, 8, 105, 116, 114, 97, 3, 0, 1, 110, 114, 2, 100, 12, 3, 4, 36, 0, 1, 115, 2, 114, 118, 105, 99, 101, 101, 102, 116, 101, 114, 115, 121, 110, 3, 6, 13, 0, 8, 114, 114, 97, 2, 115, 116, 3, 6, 35, 0, 4, 106, 1, 105, 103, 121, 104, 2, 110, 101, 3, 6, 35, 57, 0, 106, 1, 108, 97, 103, 0, 106, 8, 98, 101, 108, 112, 2, 101, 114, 0, 4, 1, 99, 101, 100, 2, 109, 98, 101, 114, 3, 6, 36, 0, 1, 99, 114, 101, 109, 2, 100, 101, 115, 0, 1, 100, 111, 98, 2, 103, 97, 0, 1, 100, 117, 116, 115, 2, 114, 101, 0, 1, 107, 115, 111, 109, 0, 1, 107, 115, 165, 195, 109, 2, 32, 0, 1, 108, 97, 100, 103, 97, 109, 2, 110, 0, 1, 108, 108, 97, 2, 103, 114, 111, 0, 1, 109, 97, 110, 116, 101, 105, 118, 2, 115, 101, 114, 0, 1, 109, 103, 114, 111, 98, 2, 115, 116, 101, 114, 0, 1, 109, 105, 107, 114, 97, 2, 100, 101, 115, 0, 1, 109, 114, 117, 111, 103, 0, 1, 110, 97, 118, 105, 100, 2, 115, 101, 114, 0, 1, 110, 101, 118, 2, 100, 105, 103, 0, 1, 110, 105, 107, 2, 115, 0, 1, 110, 110, 97, 118, 97, 104, 2, 115, 101, 114, 0, 1, 110, 114, 117, 116, 0, 1, 112, 117, 107, 2, 12, 0, 1, 112, 117, 111, 116, 0, 1, 114, 97, 108, 2, 100, 111, 0, 1, 114, 107, 115, 105, 100, 2, 116, 12, 0, 1, 114, 116, 115, 107, 101, 2, 109, 0, 1, 114, 117, 114, 111, 102, 2, 110, 101, 0, 1, 114, 121, 116, 115, 2, 110, 0, 1, 115, 101, 114, 2, 114, 118, 101, 0, 1, 116, 101, 105, 114, 97, 118, 0, 1, 116, 105, 109, 111, 107, 0, 1, 116, 111, 114, 112, 2, 115, 101, 0, 1, 116, 112, 101, 115, 2, 109, 98, 101, 114, 0, 1, 116, 115, 107, 101, 2, 114, 110, 0, 1, 118, 111, 110, 2, 109, 98, 101, 114, 0, 8, 98, 100, 184, 195, 114, 2, 100, 101, 0, 8, 98, 115, 97, 2, 115, 116, 0, 8, 100, 105, 0, 8, 100, 105, 118, 105, 100, 2, 110, 116, 101, 0, 8, 100, 111, 114, 2, 111, 0, 8, 102, 105, 110, 97, 109, 2, 115, 116, 0, 8, 103, 101, 114, 2, 115, 116, 0, 8, 108, 101, 2, 118, 0, 8, 108, 101, 99, 2, 98, 101, 114, 0, 8, 108, 108, 111, 107, 2, 103, 97, 0, 8, 108, 111, 109, 2, 115, 116, 0, 8, 109, 97, 114, 107, 97, 115, 2, 110, 116, 101, 0, 8, 109, 97, 116, 115, 101, 116, 2, 110, 116, 101, 0, 8, 109, 105, 2, 110, 115, 12, 0, 8, 109, 105, 103, 101, 114, 2, 110, 116, 101, 0, 8, 110, 103, 97, 109, 2, 116, 0, 8, 112, 114, 111, 116, 2, 100, 111, 0, 8, 114, 105, 2, 110, 101, 0, 8, 115, 121, 102, 109, 101, 2, 109, 0, 8, 116, 97, 107, 2, 100, 101, 114, 0, 8, 116, 110, 101, 114, 97, 112, 2, 115, 0, 8, 116, 111, 114, 112, 2, 115, 116, 0, 8, 116, 116, 97, 2, 115, 116, 0, 103, 1, 116, 115, 101, 98, 2, 32, 0, 103, 1, 116, 115, 101, 98, 2, 101, 116, 32, 0, 115, 1, 99, 99, 117, 0, 101, 2, 114, 3, 6, 36, 12, 0, 101, 1, 116, 105, 109, 111, 107, 2, 110, 3, 6, 36, 13, 0, 114, 1, 98, 105, 2, 105, 97, 12, 3, 6, 36, 34, 0, 4, 110, 101, 1, 108, 114, 111, 102, 3, 6, 36, 50, 13, 0, 110, 101, 1, 114, 117, 2, 32, 116, 97, 110, 107, 101, 114, 0, 4, 110, 101, 1, 108, 114, 97, 109, 3, 6, 36, 50, 108, 0, 110, 101, 1, 109, 114, 111, 102, 32, 116, 97, 0, 110, 101, 8, 108, 101, 104, 0, 4, 103, 1, 116, 97, 114, 116, 115, 2, 32, 3, 6, 36, 57, 0, 103, 8, 108, 108, 111, 107, 2, 101, 0, 4, 109, 1, 10, 2, 32, 28, 33, 12, 3, 6, 36, 65, 0, 109, 1, 10, 2, 101, 114, 28, 33, 12, 0, 109, 1, 10, 2, 101, 116, 28, 33, 12, 0, 109, 1, 10, 2, 115, 28, 33, 12, 0, 100, 1, 108, 111, 116, 2, 111, 3, 6, 36, 72, 0, 100, 105, 101, 1, 109, 3, 6, 36, 72, 57, 108, 0, 100, 105, 101, 114, 1, 109, 3, 6, 36, 72, 57, 114, 0, 100, 101, 110, 1, 110, 114, 111, 102, 3, 6, 36, 86, 108, 50, 0, 115, 116, 101, 114, 1, 107, 114, 111, 3, 6, 36, 89, 47, 114, 0, 115, 101, 1, 10, 2, 28, 33, 3, 6, 36, 89, 108, 0, 115, 101, 1, 10, 2, 114, 28, 33, 3, 6, 36, 89, 114, 0, 115, 115, 105, 111, 110, 101, 108, 1, 102, 111, 114, 112, 3, 6, 36, 91, 39, 50, 36, 55, 0, 101, 1, 108, 104, 116, 97, 107, 2, 110, 3, 6, 37, 12, 0, 101, 102, 101, 1, 107, 3, 6, 37, 12, 83, 0, 97, 117, 3, 6, 39, 0, 4, 1, 98, 101, 108, 2, 110, 100, 105, 103, 3, 6, 109, 0, 1, 98, 101, 114, 2, 107, 107, 97, 0, 1, 98, 111, 114, 2, 114, 116, 111, 0, 1, 99, 98, 97, 2, 115, 0, 1, 99, 101, 114, 2, 115, 0, 1, 99, 111, 114, 112, 2, 115, 0, 1, 99, 120, 101, 2, 115, 0, 1, 100, 114, 97, 2, 110, 110, 101, 114, 0, 1, 107, 115, 117, 109, 2, 116, 12, 0, 1, 108, 97, 112, 2, 114, 109, 111, 0, 1, 108, 97, 118, 2, 110, 99, 105, 97, 0, 1, 110, 97, 118, 2, 115, 115, 97, 0, 1, 112, 97, 100, 117, 98, 2, 115, 116, 0, 1, 115, 115, 97, 107, 2, 116, 116, 101, 0, 1, 115, 117, 109, 2, 101, 116, 0, 1, 115, 117, 109, 2, 117, 109, 0, 1, 116, 107, 110, 97, 115, 2, 108, 109, 115, 105, 108, 100, 0, 1, 118, 100, 114, 111, 110, 2, 115, 116, 0, 1, 118, 100, 121, 115, 2, 115, 116, 0, 1, 118, 108, 121, 115, 2, 115, 116, 101, 114, 0, 1, 122, 97, 103, 2, 108, 108, 101, 0, 8, 99, 99, 97, 2, 112, 116, 0, 8, 99, 101, 114, 2, 112, 116, 0, 8, 99, 110, 105, 2, 115, 116, 0, 8, 99, 110, 111, 107, 2, 112, 116, 0, 8, 99, 110, 111, 107, 2, 114, 110, 0, 8, 102, 101, 100, 2, 107, 116, 0, 8, 102, 102, 97, 2, 107, 116, 0, 8, 102, 102, 101, 2, 107, 116, 32, 0, 8, 102, 110, 111, 107, 2, 107, 116, 0, 8, 102, 110, 111, 107, 2, 116, 116, 105, 0, 8, 102, 114, 101, 112, 2, 107, 116, 0, 8, 102, 118, 108, 97, 104, 2, 109, 115, 0, 8, 102, 166, 195, 114, 112, 2, 107, 116, 0, 8, 106, 98, 111, 2, 107, 116, 0, 8, 106, 98, 117, 115, 2, 107, 116, 0, 8, 106, 111, 114, 112, 2, 107, 116, 0, 8, 107, 97, 114, 2, 116, 12, 0, 8, 108, 97, 105, 100, 2, 107, 116, 0, 8, 108, 102, 101, 114, 2, 107, 115, 0, 8, 108, 105, 100, 2, 109, 109, 97, 0, 8, 108, 108, 97, 98, 2, 116, 21, 0, 8, 108, 108, 97, 98, 32, 110, 101, 2, 116, 0, 8, 108, 108, 97, 98, 32, 114, 111, 118, 2, 116, 0, 8, 108, 108, 97, 98, 32, 115, 101, 100, 110, 101, 104, 2, 116, 0, 8, 108, 108, 97, 98, 32, 115, 101, 114, 101, 100, 2, 116, 0, 8, 108, 108, 97, 98, 32, 115, 101, 114, 101, 106, 2, 116, 0, 8, 108, 108, 97, 98, 32, 115, 101, 114, 111, 118, 2, 116, 0, 8, 108, 108, 97, 98, 32, 115, 110, 97, 104, 2, 116, 0, 8, 108, 108, 101, 116, 110, 105, 2, 107, 116, 0, 8, 108, 108, 111, 107, 2, 107, 116, 32, 0, 8, 108, 108, 111, 107, 2, 107, 116, 101, 0, 8, 108, 111, 105, 99, 111, 115, 2, 107, 116, 0, 8, 108, 111, 105, 100, 105, 2, 107, 116, 0, 8, 108, 112, 109, 111, 107, 2, 107, 115, 0, 8, 109, 101, 115, 2, 115, 116, 101, 114, 0, 8, 109, 103, 114, 111, 98, 2, 115, 116, 0, 8, 112, 115, 97, 2, 107, 116, 0, 8, 112, 115, 101, 100, 2, 107, 116, 0, 8, 112, 115, 101, 114, 2, 107, 116, 0, 8, 112, 115, 111, 114, 112, 2, 107, 116, 0, 8, 112, 115, 117, 115, 2, 107, 116, 0, 8, 114, 105, 2, 110, 101, 12, 0, 8, 115, 101, 114, 112, 2, 110, 110, 105, 110, 103, 0, 8, 115, 107, 101, 2, 109, 112, 101, 108, 0, 8, 115, 110, 105, 2, 107, 116, 0, 8, 116, 105, 107, 114, 97, 2, 107, 116, 0, 8, 116, 110, 97, 2, 110, 110, 101, 0, 8, 116, 111, 114, 103, 2, 115, 0, 8, 105, 110, 2, 99, 101, 3, 6, 109, 12, 0, 4, 114, 1, 98, 111, 114, 2, 116, 97, 3, 6, 109, 34, 0, 114, 1, 112, 117, 115, 2, 108, 97, 116, 105, 118, 0, 122, 1, 112, 97, 114, 116, 3, 6, 109, 47, 89, 0, 110, 100, 1, 107, 114, 101, 2, 101, 32, 3, 6, 109, 50, 0, 110, 101, 1, 114, 105, 115, 2, 12, 3, 6, 109, 50, 13, 0, 110, 100, 101, 1, 118, 97, 108, 2, 108, 3, 6, 109, 50, 108, 0, 105, 108, 108, 1, 118, 101, 114, 2, 101, 3, 6, 109, 55, 57, 0, 108, 112, 104, 105, 1, 100, 97, 108, 105, 104, 112, 2, 97, 3, 6, 109, 55, 83, 57, 0, 115, 101, 1, 114, 10, 2, 28, 33, 3, 6, 109, 89, 108, 0, 115, 101, 1, 114, 10, 2, 114, 28, 33, 3, 6, 109, 89, 114, 0, 115, 104, 1, 100, 97, 108, 103, 110, 97, 98, 3, 6, 109, 91, 0, 1, 106, 102, 118, 108, 97, 104, 2, 114, 100, 115, 3, 6, 110, 0, 4, 1, 114, 97, 109, 2, 110, 103, 3, 6, 111, 0, 1, 114, 105, 107, 105, 116, 115, 2, 110, 100, 100, 114, 101, 110, 103, 0, 1, 114, 112, 121, 99, 2, 115, 0, 1, 114, 114, 111, 102, 2, 116, 110, 105, 110, 103, 12, 0, 8, 114, 103, 101, 114, 2, 115, 0, 8, 114, 103, 110, 111, 107, 2, 115, 0, 8, 114, 114, 111, 107, 2, 107, 116, 0, 115, 115, 101, 1, 114, 10, 2, 28, 33, 3, 6, 111, 89, 108, 0, 115, 115, 101, 1, 114, 10, 2, 114, 28, 33, 3, 6, 111, 89, 114, 0, 1, 118, 111, 114, 112, 2, 110, 99, 101, 3, 6, 112, 12, 0, 117, 116, 8, 112, 97, 114, 101, 116, 3, 6, 118, 58, 72, 0, 115, 115, 101, 1, 104, 99, 10, 2, 28, 33, 3, 7, 109, 89, 0, 115, 115, 101, 1, 10, 2, 28, 33, 3, 7, 109, 89, 108, 0, 115, 115, 101, 1, 10, 2, 114, 28, 33, 3, 7, 109, 89, 114, 0, 8, 108, 108, 105, 116, 115, 2, 98, 101, 110, 3, 8, 6, 36, 0, 4, 1, 18, 73, 2, 32, 3, 13, 0, 1, 98, 98, 111, 100, 2, 108, 0, 1, 99, 2, 32, 0, 1, 99, 97, 112, 114, 111, 116, 111, 109, 2, 110, 0, 1, 100, 2, 115, 32, 0, 1, 100, 101, 2, 45, 0, 1, 100, 101, 2, 114, 0, 1, 100, 111, 103, 0, 1, 100, 111, 107, 0, 1, 103, 121, 115, 2, 12, 0, 1, 108, 97, 118, 2, 114, 105, 12, 12, 0, 1, 108, 109, 97, 0, 1, 108, 111, 107, 2, 17, 67, 0, 1, 108, 114, 101, 112, 0, 1, 110, 97, 2, 114, 0, 1, 114, 2, 115, 32, 0, 1, 114, 117, 2, 110, 101, 0, 1, 114, 121, 2, 12, 0, 1, 115, 2, 32, 0, 1, 115, 110, 111, 107, 2, 107, 118, 0, 1, 115, 117, 108, 2, 12, 12, 0, 1, 116, 2, 32, 0, 1, 116, 114, 111, 108, 0, 1, 116, 115, 101, 104, 2, 110, 12, 0, 1, 116, 115, 114, 97, 99, 2, 110, 0, 1, 116, 115, 114, 97, 107, 2, 110, 0, 1, 118, 114, 101, 115, 0, 2, 106, 117, 108, 12, 0, 8, 110, 101, 0, 101, 2, 106, 101, 114, 3, 13, 35, 0, 4, 97, 117, 2, 107, 116, 105, 3, 13, 35, 40, 0, 97, 117, 2, 116, 111, 0, 4, 110, 100, 101, 1, 10, 2, 32, 3, 13, 50, 13, 0, 110, 101, 1, 21, 2, 32, 0, 110, 101, 1, 103, 103, 21, 2, 32, 14, 128, 128, 132, 0, 110, 101, 115, 1, 21, 2, 32, 3, 13, 50, 13, 89, 0, 106, 2, 97, 103, 116, 3, 13, 57, 0, 100, 1, 114, 114, 2, 17, 65, 3, 13, 72, 0, 4, 103, 1, 108, 2, 97, 110, 12, 12, 3, 13, 81, 0, 103, 1, 108, 101, 100, 2, 17, 65, 0, 103, 1, 116, 115, 2, 195, 165, 0, 103, 2, 97, 102, 102, 101, 108, 0, 103, 2, 114, 117, 110, 100, 0, 100, 1, 114, 114, 3, 13, 86, 0, 100, 101, 116, 1, 118, 111, 2, 32, 3, 13, 86, 108, 72, 0, 110, 1, 100, 17, 65, 2, 21, 3, 14, 50, 0, 103, 1, 108, 101, 114, 2, 105, 111, 110, 3, 20, 13, 81, 0, 120, 99, 104, 97, 110, 103, 101, 3, 21, 0, 115, 8, 108, 114, 97, 3, 21, 102, 114, 0, 4, 1, 114, 2, 110, 100, 116, 3, 35, 0, 2, 103, 102, 105, 0, 2, 103, 115, 111, 116, 0, 8, 114, 116, 2, 116, 116, 101, 110, 0, 103, 101, 116, 8, 2, 32, 3, 35, 12, 57, 13, 86, 0, 110, 100, 101, 1, 114, 118, 184, 195, 114, 2, 32, 3, 35, 20, 50, 13, 0, 110, 100, 101, 114, 1, 114, 118, 184, 195, 114, 2, 32, 3, 35, 20, 50, 114, 0, 4, 1, 103, 2, 106, 115, 3, 35, 57, 0, 103, 1, 18, 71, 2, 101, 0, 103, 1, 18, 73, 0, 103, 1, 101, 108, 101, 2, 12, 0, 103, 1, 104, 2, 108, 101, 0, 103, 1, 107, 2, 108, 101, 0, 103, 1, 108, 2, 101, 12, 0, 103, 1, 108, 98, 0, 103, 1, 108, 115, 98, 97, 107, 115, 108, 101, 115, 0, 103, 1, 110, 115, 2, 108, 0, 103, 1, 112, 0, 103, 1, 114, 107, 115, 0, 103, 1, 114, 116, 2, 101, 32, 0, 103, 1, 114, 116, 2, 101, 100, 101, 32, 0, 103, 1, 114, 116, 2, 101, 110, 32, 0, 103, 1, 114, 116, 2, 101, 114, 32, 0, 103, 1, 114, 116, 2, 101, 115, 32, 0, 103, 1, 114, 116, 115, 0, 103, 1, 115, 2, 108, 0, 103, 1, 116, 2, 108, 0, 103, 2, 110, 0, 103, 2, 114, 195, 184, 100, 0, 103, 8, 98, 2, 32, 0, 105, 1, 104, 2, 100, 101, 108, 0, 105, 1, 115, 2, 115, 0, 105, 1, 115, 2, 115, 109, 111, 108, 0, 105, 1, 116, 115, 2, 110, 25, 0, 105, 8, 104, 2, 100, 105, 0, 105, 8, 104, 2, 108, 32, 0, 106, 1, 114, 2, 115, 0, 106, 1, 114, 100, 2, 12, 0, 106, 1, 118, 109, 101, 106, 104, 0, 106, 2, 12, 12, 0, 107, 1, 115, 2, 115, 116, 101, 110, 0, 121, 1, 109, 2, 101, 114, 0, 4, 103, 101, 110, 100, 101, 1, 108, 2, 32, 98, 195, 184, 114, 110, 3, 35, 57, 13, 50, 13, 0, 103, 101, 110, 100, 101, 1, 108, 2, 32, 108, 101, 116, 0, 103, 101, 109, 1, 108, 98, 2, 105, 100, 3, 35, 57, 13, 65, 0, 105, 110, 115, 116, 101, 105, 110, 3, 35, 57, 50, 89, 47, 35, 57, 50, 0, 105, 110, 100, 104, 111, 118, 101, 110, 3, 35, 57, 50, 107, 6, 39, 12, 83, 13, 50, 0, 4, 106, 114, 1, 118, 2, 101, 32, 3, 35, 57, 51, 0, 106, 114, 1, 118, 2, 101, 114, 32, 0, 103, 108, 1, 110, 3, 35, 57, 55, 0, 105, 108, 101, 101, 110, 3, 35, 57, 55, 6, 37, 12, 50, 0, 121, 101, 108, 105, 110, 101, 114, 3, 35, 57, 55, 35, 57, 50, 114, 0, 105, 103, 101, 114, 3, 35, 57, 81, 114, 0, 105, 102, 102, 101, 108, 3, 35, 57, 83, 108, 55, 0, 105, 115, 101, 110, 104, 111, 119, 101, 114, 3, 35, 57, 89, 13, 50, 107, 112, 40, 114, 0, 106, 101, 114, 2, 17, 67, 3, 35, 57, 114, 0, 4, 110, 1, 112, 2, 115, 105, 111, 110, 3, 35, 68, 0, 110, 1, 115, 115, 101, 114, 2, 116, 105, 109, 101, 110, 116, 0, 110, 1, 116, 101, 112, 109, 111, 2, 99, 101, 0, 110, 2, 116, 114, 195, 169, 0, 110, 8, 2, 116, 114, 101, 0, 110, 103, 97, 103, 2, 101, 3, 35, 68, 81, 110, 91, 0, 4, 3, 36, 0, 1, 17, 67, 2, 18, 67, 18, 76, 0, 1, 17, 67, 2, 100, 17, 65, 0, 1, 18, 68, 2, 18, 67, 18, 69, 0, 1, 18, 73, 2, 103, 116, 0, 1, 18, 74, 2, 100, 101, 0, 1, 18, 74, 2, 116, 0, 1, 98, 2, 114, 101, 116, 12, 0, 1, 98, 2, 114, 105, 103, 0, 1, 98, 114, 111, 102, 0, 1, 100, 2, 112, 0, 1, 104, 2, 100, 100, 0, 1, 104, 2, 110, 32, 12, 0, 1, 104, 99, 97, 109, 112, 97, 112, 0, 1, 107, 115, 100, 184, 195, 114, 103, 0, 1, 107, 115, 101, 98, 184, 195, 116, 115, 0, 1, 107, 115, 101, 100, 121, 114, 103, 0, 1, 107, 115, 101, 103, 117, 102, 0, 1, 107, 115, 101, 108, 165, 195, 109, 0, 1, 107, 115, 101, 115, 105, 112, 115, 0, 1, 107, 115, 101, 116, 0, 1, 107, 115, 108, 117, 104, 0, 1, 107, 115, 110, 97, 107, 0, 1, 107, 115, 114, 117, 109, 0, 1, 107, 115, 116, 114, 101, 115, 115, 101, 100, 0, 1, 107, 115, 184, 195, 114, 116, 115, 0, 1, 108, 2, 118, 101, 0, 1, 108, 101, 2, 118, 0, 1, 108, 102, 2, 100, 101, 12, 0, 1, 108, 111, 112, 2, 114, 101, 12, 0, 1, 108, 117, 115, 110, 111, 107, 2, 110, 116, 0, 1, 109, 2, 100, 105, 12, 0, 1, 110, 2, 100, 103, 97, 110, 103, 0, 1, 110, 2, 100, 115, 108, 97, 103, 0, 1, 110, 2, 100, 115, 116, 105, 103, 0, 1, 110, 2, 100, 115, 195, 166, 116, 0, 1, 110, 101, 109, 2, 100, 0, 1, 110, 107, 2, 98, 0, 1, 110, 115, 2, 25, 12, 0, 1, 114, 2, 104, 97, 98, 105, 108, 0, 1, 114, 2, 109, 18, 69, 0, 1, 114, 2, 115, 116, 18, 76, 0, 1, 114, 2, 116, 97, 98, 0, 1, 114, 2, 116, 97, 114, 100, 0, 1, 114, 2, 116, 101, 110, 116, 105, 111, 110, 0, 1, 114, 2, 116, 105, 0, 1, 114, 2, 116, 111, 114, 0, 1, 114, 2, 116, 111, 117, 0, 1, 114, 2, 116, 114, 97, 110, 0, 1, 114, 2, 116, 114, 111, 0, 1, 114, 2, 116, 114, 195, 166, 0, 1, 114, 2, 116, 115, 105, 110, 97, 0, 1, 114, 2, 116, 117, 114, 0, 1, 114, 107, 115, 2, 118, 0, 1, 114, 111, 101, 116, 2, 116, 0, 1, 114, 116, 2, 109, 105, 108, 101, 0, 1, 115, 100, 110, 105, 0, 1, 115, 100, 110, 105, 2, 114, 32, 0, 1, 115, 100, 117, 114, 111, 102, 0, 1, 115, 101, 100, 111, 103, 0, 1, 115, 102, 97, 2, 32, 0, 1, 115, 102, 97, 2, 116, 32, 12, 0, 1, 115, 108, 105, 116, 0, 1, 115, 110, 97, 108, 101, 118, 2, 116, 0, 1, 115, 114, 101, 116, 102, 101, 0, 1, 115, 114, 101, 118, 111, 2, 32, 0, 1, 115, 116, 114, 111, 98, 2, 12, 0, 1, 116, 101, 108, 108, 105, 109, 97, 107, 0, 1, 116, 101, 116, 114, 117, 0, 1, 116, 110, 101, 103, 114, 111, 109, 0, 1, 116, 115, 101, 106, 184, 195, 2, 110, 12, 0, 1, 116, 115, 103, 97, 100, 100, 105, 109, 0, 1, 116, 115, 114, 101, 116, 101, 109, 2, 110, 0, 1, 116, 115, 114, 111, 107, 115, 2, 110, 0, 1, 116, 115, 114, 117, 109, 2, 110, 0, 1, 118, 109, 101, 106, 104, 0, 2, 100, 116, 0, 2, 108, 101, 103, 105, 0, 8, 100, 2, 115, 32, 0, 8, 107, 115, 2, 32, 0, 8, 107, 115, 2, 101, 114, 0, 8, 109, 2, 108, 32, 0, 8, 110, 115, 2, 114, 32, 0, 8, 112, 115, 2, 32, 0, 8, 114, 2, 110, 100, 121, 114, 12, 0, 8, 114, 116, 2, 12, 0, 8, 114, 116, 2, 116, 0, 8, 115, 100, 117, 2, 32, 12, 0, 8, 115, 100, 117, 2, 114, 32, 12, 0, 8, 115, 110, 97, 2, 12, 12, 0, 8, 116, 2, 32, 0, 8, 116, 115, 105, 0, 100, 1, 116, 115, 2, 100, 97, 0, 100, 1, 116, 115, 2, 102, 97, 0, 100, 1, 116, 115, 2, 109, 111, 0, 100, 1, 116, 115, 2, 115, 195, 184, 0, 103, 8, 116, 115, 2, 32, 0, 1, 98, 10, 2, 115, 21, 3, 36, 4, 0, 101, 1, 100, 105, 2, 108, 3, 36, 6, 109, 0, 4, 103, 101, 8, 2, 32, 3, 36, 12, 57, 13, 0, 103, 101, 8, 2, 98, 108, 97, 100, 0, 103, 101, 8, 2, 108, 195, 184, 118, 0, 103, 101, 8, 2, 116, 114, 195, 166, 0, 101, 8, 110, 115, 2, 100, 101, 32, 3, 36, 13, 0, 8, 115, 2, 32, 3, 36, 19, 0, 110, 100, 101, 1, 106, 102, 3, 36, 20, 50, 13, 0, 110, 100, 101, 114, 1, 106, 102, 3, 36, 20, 50, 114, 0, 114, 114, 105, 101, 114, 8, 112, 3, 36, 34, 37, 6, 36, 0, 101, 1, 98, 2, 100, 3, 36, 36, 0, 116, 97, 103, 101, 114, 101, 3, 36, 47, 110, 91, 6, 109, 12, 51, 0, 100, 107, 101, 114, 1, 110, 115, 3, 36, 49, 114, 0, 4, 110, 1, 99, 2, 116, 17, 67, 3, 36, 50, 0, 110, 1, 100, 17, 65, 2, 116, 0, 108, 108, 101, 118, 101, 3, 36, 55, 84, 13, 0, 4, 103, 1, 108, 114, 101, 100, 110, 117, 3, 36, 57, 0, 103, 1, 116, 115, 114, 101, 118, 111, 0, 103, 8, 118, 2, 32, 0, 103, 8, 118, 2, 101, 116, 32, 0, 106, 2, 97, 107, 117, 0, 103, 101, 110, 8, 2, 21, 3, 36, 57, 13, 50, 0, 4, 103, 1, 108, 2, 101, 110, 100, 97, 3, 36, 81, 0, 103, 1, 108, 2, 101, 114, 0, 103, 1, 108, 2, 101, 114, 101, 0, 103, 1, 108, 2, 105, 116, 105, 0, 103, 1, 109, 2, 97, 0, 103, 1, 112, 2, 97, 115, 117, 115, 0, 103, 2, 101, 118, 105, 110, 115, 116, 12, 0, 103, 8, 107, 115, 2, 97, 102, 102, 101, 108, 0, 103, 101, 110, 100, 101, 8, 108, 2, 32, 3, 36, 81, 6, 109, 50, 72, 108, 0, 100, 101, 116, 1, 108, 2, 12, 3, 36, 86, 13, 47, 0, 101, 1, 114, 2, 108, 3, 36, 109, 0, 4, 1, 115, 115, 101, 106, 3, 37, 0, 8, 2, 32, 109, 97, 105, 108, 0, 8, 2, 32, 115, 112, 101, 97, 107, 0, 8, 100, 2, 32, 0, 97, 1, 108, 2, 115, 101, 0, 97, 1, 108, 2, 115, 105, 110, 103, 0, 121, 1, 17, 67, 2, 32, 0, 121, 1, 107, 0, 121, 1, 108, 108, 0, 121, 1, 110, 115, 105, 100, 0, 121, 1, 115, 100, 110, 105, 108, 0, 121, 1, 118, 114, 97, 104, 0, 121, 8, 110, 114, 97, 98, 0, 4, 97, 1, 104, 2, 108, 3, 37, 12, 0, 97, 1, 107, 2, 116, 111, 110, 0, 97, 1, 112, 2, 99, 111, 0, 97, 1, 116, 2, 109, 0, 97, 8, 112, 2, 107, 32, 0, 101, 1, 104, 115, 2, 108, 97, 0, 101, 1, 107, 2, 112, 101, 114, 0, 101, 1, 114, 102, 0, 101, 1, 114, 102, 2, 108, 97, 110, 0, 101, 1, 114, 103, 2, 110, 0, 101, 1, 119, 0, 101, 1, 119, 2, 107, 0, 101, 8, 108, 102, 2, 99, 101, 12, 0, 105, 8, 100, 2, 100, 114, 101, 0, 116, 111, 110, 8, 3, 37, 12, 47, 13, 50, 0, 97, 108, 8, 110, 3, 37, 12, 59, 0, 4, 101, 100, 1, 112, 115, 3, 37, 12, 72, 0, 101, 100, 1, 119, 116, 0, 101, 100, 8, 114, 2, 25, 0, 97, 99, 104, 8, 112, 3, 37, 12, 76, 0, 97, 103, 108, 101, 3, 37, 12, 81, 13, 55, 0, 4, 97, 115, 101, 1, 116, 112, 105, 114, 116, 115, 3, 37, 12, 89, 0, 101, 115, 101, 1, 104, 99, 0, 97, 115, 116, 8, 3, 37, 12, 89, 72, 0, 98, 97, 121, 3, 37, 71, 109, 57, 0, 97, 98, 111, 100, 121, 1, 112, 3, 37, 71, 114, 72, 37, 0, 100, 105, 101, 8, 2, 32, 3, 37, 72, 37, 0, 103, 101, 1, 108, 108, 111, 99, 3, 37, 75, 0, 118, 105, 101, 8, 116, 115, 3, 37, 84, 37, 0, 97, 115, 121, 3, 37, 89, 37, 0, 115, 112, 101, 97, 107, 3, 37, 89, 48, 37, 12, 49, 0, 97, 117, 1, 114, 3, 39, 0, 119, 1, 108, 2, 105, 115, 3, 40, 12, 0, 119, 1, 116, 115, 3, 57, 40, 0, 117, 103, 101, 110, 101, 3, 57, 40, 75, 6, 37, 12, 50, 0, 116, 1, 103, 111, 110, 2, 32, 3, 86, 0, 4, 1, 21, 2, 32, 12, 3, 108, 0, 1, 98, 97, 118, 104, 2, 104, 97, 114, 32, 0, 1, 98, 109, 111, 98, 2, 114, 21, 0, 1, 99, 121, 111, 106, 2, 115, 0, 1, 100, 101, 98, 0, 1, 100, 117, 0, 1, 100, 184, 195, 0, 1, 105, 114, 0, 1, 107, 107, 121, 2, 17, 67, 0, 1, 107, 108, 166, 195, 109, 0, 1, 108, 98, 111, 98, 0, 1, 108, 98, 166, 195, 2, 103, 114, 195, 184, 100, 0, 1, 108, 98, 184, 195, 2, 109, 0, 1, 108, 101, 2, 118, 97, 116, 0, 1, 108, 101, 116, 0, 1, 108, 102, 97, 2, 118, 0, 1, 108, 112, 2, 109, 101, 110, 0, 1, 108, 117, 0, 1, 110, 2, 117, 110, 103, 101, 0, 1, 110, 21, 2, 100, 0, 1, 110, 115, 17, 65, 108, 2, 12, 0, 1, 110, 115, 105, 103, 2, 12, 0, 1, 110, 115, 105, 118, 2, 12, 0, 1, 110, 115, 107, 111, 118, 0, 1, 114, 2, 104, 0, 1, 114, 2, 114, 101, 0, 1, 114, 97, 112, 115, 0, 1, 114, 97, 118, 0, 1, 114, 100, 108, 166, 195, 2, 12, 0, 1, 114, 100, 114, 111, 0, 1, 114, 116, 110, 101, 2, 112, 114, 0, 1, 114, 166, 195, 2, 12, 0, 1, 116, 114, 184, 195, 107, 115, 2, 17, 67, 0, 1, 118, 97, 104, 0, 2, 106, 111, 98, 12, 0, 2, 106, 111, 117, 114, 12, 0, 2, 106, 195, 166, 103, 101, 114, 12, 0, 8, 97, 2, 32, 0, 8, 100, 2, 32, 103, 97, 117, 108, 108, 101, 0, 8, 100, 2, 32, 108, 97, 32, 0, 8, 110, 115, 105, 2, 12, 0, 1, 114, 17, 65, 2, 115, 32, 3, 108, 9, 0, 4, 106, 101, 114, 110, 1, 109, 3, 108, 57, 109, 34, 50, 0, 106, 101, 114, 110, 1, 118, 0, 4, 106, 1, 100, 110, 2, 111, 98, 3, 108, 75, 0, 106, 1, 109, 2, 111, 98, 0, 4, 103, 1, 107, 115, 105, 102, 3, 108, 81, 0, 103, 1, 108, 101, 116, 2, 114, 0, 103, 2, 97, 110, 103, 115, 0, 116, 1, 99, 105, 112, 115, 111, 104, 3, 108, 86, 0, 115, 1, 21, 2, 32, 24, 3, 108, 89, 0, 4, 1, 17, 67, 2, 17, 67, 11, 3, 109, 0, 1, 17, 67, 2, 18, 67, 0, 1, 18, 71, 2, 114, 0, 1, 18, 74, 2, 108, 0, 1, 98, 2, 114, 103, 12, 0, 1, 98, 117, 116, 2, 114, 107, 117, 0, 1, 106, 98, 111, 2, 107, 116, 105, 118, 0, 1, 107, 97, 114, 2, 116, 12, 0, 1, 108, 2, 18, 72, 0, 1, 108, 101, 2, 110, 100, 105, 103, 0, 1, 108, 101, 116, 2, 120, 0, 1, 108, 111, 107, 2, 115, 116, 0, 1, 108, 115, 2, 116, 12, 12, 0, 1, 110, 101, 2, 109, 0, 1, 110, 101, 2, 114, 103, 105, 0, 1, 110, 115, 2, 114, 112, 0, 1, 112, 115, 101, 114, 2, 107, 116, 97, 98, 101, 108, 0, 1, 114, 2, 17, 67, 11, 0, 1, 114, 2, 110, 103, 195, 184, 0, 1, 114, 2, 110, 115, 107, 114, 0, 1, 114, 2, 110, 115, 107, 117, 0, 1, 114, 2, 115, 116, 97, 117, 114, 97, 110, 116, 0, 1, 114, 17, 67, 2, 100, 0, 1, 114, 98, 2, 118, 0, 1, 114, 100, 2, 118, 110, 0, 1, 114, 101, 100, 101, 108, 2, 118, 110, 101, 0, 1, 114, 103, 2, 116, 0, 1, 114, 112, 2, 109, 0, 1, 114, 112, 101, 100, 2, 115, 115, 0, 1, 114, 112, 111, 2, 118, 0, 1, 114, 112, 115, 2, 100, 0, 1, 115, 2, 100, 100, 0, 1, 116, 2, 100, 0, 8, 106, 111, 114, 112, 2, 107, 116, 105, 108, 0, 8, 114, 101, 108, 108, 97, 2, 100, 101, 32, 0, 8, 114, 116, 2, 100, 0, 8, 114, 116, 2, 115, 0, 97, 1, 119, 115, 2, 116, 101, 114, 0, 97, 1, 119, 115, 2, 116, 114, 101, 0, 106, 1, 118, 2, 114, 0, 4, 1, 114, 112, 2, 115, 115, 101, 114, 101, 110, 100, 101, 3, 109, 6, 0, 1, 114, 116, 2, 109, 97, 0, 110, 100, 101, 1, 115, 112, 111, 3, 109, 10, 50, 13, 0, 4, 1, 114, 2, 100, 17, 65, 3, 109, 12, 0, 2, 118, 101, 110, 0, 110, 100, 1, 107, 2, 101, 32, 12, 3, 109, 20, 50, 0, 4, 110, 100, 101, 1, 118, 2, 12, 3, 109, 20, 50, 13, 0, 110, 100, 101, 1, 118, 110, 97, 2, 32, 0, 110, 100, 101, 1, 118, 110, 101, 104, 2, 32, 0, 110, 100, 101, 1, 118, 115, 2, 32, 0, 110, 100, 101, 1, 100, 108, 117, 102, 3, 109, 20, 50, 108, 0, 4, 110, 100, 101, 114, 1, 107, 2, 32, 3, 109, 20, 50, 114, 0, 110, 100, 101, 114, 1, 118, 2, 12, 0, 110, 100, 101, 114, 1, 118, 110, 97, 2, 32, 0, 110, 100, 101, 114, 1, 118, 110, 101, 104, 2, 32, 0, 114, 118, 101, 114, 1, 115, 101, 114, 2, 32, 101, 110, 3, 109, 34, 84, 6, 36, 34, 0, 116, 97, 108, 1, 109, 32, 121, 118, 97, 101, 104, 3, 109, 47, 108, 55, 0, 99, 104, 1, 116, 3, 109, 49, 0, 4, 110, 1, 99, 2, 116, 3, 109, 50, 0, 110, 1, 99, 2, 116, 17, 65, 0, 4, 110, 101, 1, 106, 116, 2, 12, 12, 3, 109, 50, 13, 0, 110, 101, 1, 114, 103, 2, 12, 0, 110, 100, 101, 1, 118, 2, 116, 116, 97, 3, 109, 50, 72, 6, 109, 0, 110, 100, 97, 1, 114, 98, 3, 109, 50, 72, 110, 0, 110, 103, 101, 1, 104, 101, 110, 111, 116, 115, 3, 109, 50, 75, 0, 110, 101, 114, 1, 106, 116, 2, 12, 3, 109, 50, 114, 0, 4, 97, 1, 114, 98, 2, 107, 3, 109, 57, 0, 97, 1, 114, 103, 2, 116, 0, 103, 1, 108, 114, 101, 118, 111, 0, 121, 1, 114, 0, 103, 101, 1, 108, 2, 109, 101, 3, 109, 57, 20, 13, 0, 4, 103, 101, 108, 1, 114, 3, 109, 57, 55, 0, 103, 108, 1, 114, 0, 109, 112, 105, 114, 101, 2, 32, 115, 116, 97, 116, 101, 3, 109, 65, 48, 35, 57, 108, 0, 105, 110, 116, 1, 116, 3, 109, 68, 0, 4, 97, 100, 1, 104, 3, 109, 72, 0, 100, 100, 1, 114, 98, 0, 4, 100, 100, 105, 101, 1, 114, 102, 3, 109, 72, 37, 0, 100, 100, 105, 101, 8, 0, 100, 100, 121, 1, 114, 102, 0, 100, 100, 105, 107, 101, 3, 109, 72, 49, 108, 0, 100, 97, 103, 1, 114, 102, 3, 109, 72, 110, 0, 4, 103, 1, 114, 2, 101, 114, 3, 109, 81, 0, 103, 1, 114, 97, 117, 116, 0, 103, 103, 121, 1, 112, 3, 109, 81, 37, 0, 103, 109, 97, 116, 105, 116, 1, 112, 3, 109, 81, 65, 110, 47, 6, 37, 47, 0, 100, 101, 116, 1, 116, 115, 2, 32, 3, 109, 86, 108, 47, 0, 100, 101, 116, 1, 114, 2, 32, 3, 109, 86, 108, 72, 0, 115, 116, 105, 103, 101, 1, 114, 112, 2, 32, 3, 109, 89, 47, 6, 37, 91, 0, 4, 99, 115, 116, 97, 99, 121, 3, 109, 89, 47, 110, 89, 37, 0, 99, 115, 116, 97, 115, 121, 0, 4, 1, 110, 115, 2, 114, 114, 101, 3, 111, 0, 1, 114, 2, 18, 67, 115, 0, 1, 114, 2, 18, 74, 115, 0, 1, 114, 2, 107, 116, 111, 0, 1, 114, 2, 109, 0, 1, 114, 2, 110, 100, 32, 0, 1, 114, 2, 110, 100, 101, 0, 1, 114, 2, 110, 103, 0, 1, 114, 2, 110, 115, 101, 0, 1, 114, 2, 110, 115, 110, 105, 110, 103, 0, 1, 114, 2, 110, 116, 101, 0, 1, 114, 2, 115, 116, 0, 1, 114, 2, 115, 116, 101, 0, 1, 114, 2, 116, 0, 1, 114, 2, 118, 108, 0, 1, 114, 2, 118, 110, 0, 1, 114, 18, 67, 2, 17, 67, 11, 0, 1, 114, 18, 72, 2, 109, 0, 1, 114, 98, 2, 18, 74, 0, 1, 114, 101, 98, 2, 116, 12, 12, 0, 1, 114, 102, 2, 108, 0, 1, 114, 102, 2, 109, 0, 1, 114, 102, 2, 109, 111, 118, 0, 1, 114, 103, 2, 108, 0, 1, 114, 103, 103, 97, 2, 115, 115, 111, 114, 0, 1, 114, 103, 110, 111, 107, 2, 115, 0, 1, 114, 105, 100, 2, 107, 116, 0, 1, 114, 112, 2, 17, 67, 11, 12, 0, 1, 114, 112, 2, 115, 12, 0, 1, 114, 112, 111, 2, 116, 12, 12, 0, 1, 114, 114, 111, 102, 2, 116, 12, 12, 0, 1, 114, 121, 114, 114, 97, 107, 2, 116, 12, 0, 2, 103, 97, 110, 115, 105, 103, 116, 0, 8, 114, 103, 101, 114, 2, 115, 115, 105, 118, 0, 100, 105, 118, 101, 1, 114, 116, 3, 111, 86, 84, 13, 0, 115, 115, 101, 1, 114, 21, 2, 114, 101, 28, 33, 3, 111, 89, 6, 36, 0, 2, 109, 98, 97, 108, 108, 3, 112, 0, 97, 114, 116, 1, 104, 3, 112, 12, 72, 0, 110, 1, 114, 2, 99, 101, 3, 112, 68, 0, 110, 116, 101, 110, 116, 101, 3, 112, 68, 47, 6, 112, 68, 47, 0, 97, 117, 120, 1, 114, 3, 113, 0, 4, 1, 99, 110, 97, 108, 101, 101, 114, 102, 2, 114, 3, 114, 0, 1, 108, 97, 109, 2, 114, 105, 0, 1, 114, 100, 2, 100, 101, 115, 32, 0, 1, 114, 100, 110, 2, 17, 65, 0, 1, 114, 100, 110, 97, 0, 1, 114, 111, 10, 2, 112, 108, 0, 1, 114, 111, 104, 0, 1, 114, 111, 116, 115, 0, 1, 114, 116, 97, 108, 107, 0, 1, 114, 116, 115, 110, 101, 118, 0, 1, 114, 121, 110, 2, 12, 0, 114, 1, 98, 17, 65, 10, 0, 114, 1, 100, 110, 101, 0, 114, 1, 108, 97, 109, 0, 114, 1, 108, 100, 105, 109, 0, 114, 1, 108, 108, 101, 0, 114, 1, 108, 165, 195, 109, 0, 114, 1, 110, 115, 17, 65, 108, 2, 12, 0, 114, 1, 110, 115, 105, 103, 2, 12, 0, 114, 1, 110, 115, 105, 118, 2, 12, 0, 114, 1, 112, 117, 115, 0, 114, 1, 115, 100, 117, 112, 2, 12, 0, 114, 1, 115, 117, 108, 2, 12, 0, 114, 8, 110, 115, 105, 2, 12, 0, 4, 110, 101, 1, 114, 21, 2, 32, 3, 114, 50, 13, 0, 110, 101, 1, 114, 103, 110, 105, 102, 0, 110, 101, 115, 1, 114, 21, 2, 32, 14, 128, 128, 132, 3, 114, 50, 13, 89, 0, 117, 1, 102, 101, 3, 114, 57, 0, 97, 114, 108, 8, 3, 118, 12, 59, 0, 97, 114, 112, 8, 3, 118, 12, 71, 0, 117, 1, 110, 3, 118, 40, 0, 117, 2, 114, 111, 3, 118, 58, 0, 117, 116, 1, 112, 97, 114, 101, 116, 3, 118, 58, 72, 0, 117, 115, 3, 118, 58, 89, 0, 7, 6, 102, 0, 1, 97, 2, 115, 116, 101, 100, 3, 0, 4, 1, 97, 2, 17, 65, 3, 58, 0, 1, 97, 2, 17, 67, 0, 4, 3, 83, 0, 1, 21, 2, 108, 97, 115, 107, 101, 0, 1, 97, 2, 97, 115, 105, 0, 1, 97, 2, 97, 116, 105, 115, 107, 0, 1, 97, 2, 105, 116, 0, 1, 97, 2, 111, 110, 0, 1, 97, 2, 111, 114, 0, 1, 97, 2, 114, 105, 107, 0, 1, 97, 2, 114, 111, 0, 1, 97, 2, 116, 101, 110, 0, 1, 97, 2, 116, 101, 115, 32, 0, 1, 97, 17, 67, 2, 17, 65, 0, 1, 97, 17, 67, 2, 116, 0, 1, 97, 100, 2, 110, 0, 1, 97, 103, 2, 108, 0, 1, 97, 107, 115, 0, 1, 97, 108, 2, 114, 101, 0, 1, 97, 114, 2, 102, 111, 114, 0, 1, 97, 114, 2, 102, 114, 0, 1, 97, 114, 2, 105, 107, 0, 1, 97, 114, 2, 108, 101, 0, 1, 97, 114, 103, 2, 17, 65, 0, 1, 97, 114, 105, 103, 0, 1, 97, 114, 116, 115, 0, 1, 97, 115, 2, 97, 114, 0, 1, 97, 116, 115, 2, 101, 0, 1, 97, 118, 2, 108, 0, 2, 106, 101, 100, 101, 114, 0, 2, 111, 108, 107, 0, 102, 0, 102, 1, 97, 2, 97, 98, 101, 108, 0, 102, 1, 97, 2, 97, 103, 101, 0, 102, 1, 97, 2, 101, 107, 116, 0, 102, 1, 97, 2, 101, 108, 0, 102, 1, 97, 2, 105, 99, 101, 114, 101, 0, 102, 1, 97, 2, 105, 110, 101, 0, 102, 1, 97, 2, 105, 110, 105, 116, 101, 116, 0, 102, 1, 97, 2, 105, 114, 109, 0, 102, 1, 97, 2, 117, 116, 97, 103, 101, 0, 102, 1, 97, 2, 195, 166, 114, 101, 0, 102, 1, 97, 106, 2, 97, 0, 102, 1, 97, 114, 2, 101, 0, 111, 114, 101, 8, 2, 100, 101, 32, 3, 83, 2, 6, 39, 34, 114, 0, 111, 114, 8, 2, 101, 32, 3, 83, 2, 39, 0, 4, 101, 1, 97, 99, 3, 83, 6, 36, 0, 195, 169, 1, 97, 99, 0, 111, 114, 8, 2, 117, 109, 3, 83, 6, 39, 34, 0, 195, 166, 114, 100, 105, 103, 1, 21, 3, 83, 6, 109, 34, 72, 37, 0, 114, 105, 116, 101, 115, 1, 32, 115, 101, 3, 83, 34, 37, 47, 0, 114, 97, 110, 107, 105, 101, 3, 83, 34, 110, 50, 49, 37, 0, 114, 97, 110, 195, 167, 111, 105, 115, 3, 83, 34, 112, 68, 89, 6, 58, 35, 0, 114, 101, 117, 100, 3, 83, 34, 114, 57, 47, 0, 101, 8, 2, 32, 3, 83, 36, 0, 101, 116, 116, 117, 99, 99, 105, 110, 101, 3, 83, 36, 47, 40, 87, 91, 6, 37, 12, 50, 13, 0, 105, 110, 108, 97, 121, 3, 83, 36, 50, 55, 37, 0, 105, 101, 108, 100, 3, 83, 37, 12, 59, 72, 0, 4, 105, 114, 101, 3, 83, 37, 12, 114, 0, 105, 114, 101, 111, 103, 0, 105, 114, 101, 110, 122, 101, 3, 83, 37, 51, 6, 110, 50, 89, 13, 0, 111, 98, 105, 1, 21, 3, 83, 39, 71, 6, 37, 0, 111, 117, 113, 117, 101, 116, 3, 83, 40, 49, 6, 36, 0, 114, 97, 110, 99, 101, 115, 99, 97, 3, 83, 51, 35, 50, 91, 6, 109, 89, 49, 110, 0, 108, 117, 115, 104, 3, 83, 55, 114, 91, 0, 195, 166, 114, 100, 105, 103, 1, 21, 21, 3, 83, 109, 34, 72, 37, 0, 97, 114, 97, 111, 3, 83, 112, 34, 112, 39, 0, 111, 117, 114, 8, 2, 32, 3, 83, 113, 12, 0, 111, 110, 116, 97, 105, 110, 101, 3, 83, 113, 68, 47, 6, 109, 12, 50, 0, 98, 105, 8, 3, 109, 83, 71, 37, 6, 35, 57, 0, 7, 6, 103, 0, 4, 1, 105, 100, 184, 195, 2, 116, 32, 3, 0, 4, 1, 105, 107, 2, 104, 111, 115, 116, 3, 0, 4, 1, 105, 116, 103, 2, 101, 114, 101, 3, 0, 4, 1, 108, 2, 17, 67, 3, 0, 4, 1, 108, 2, 116, 101, 32, 3, 0, 4, 1, 108, 97, 118, 2, 116, 3, 0, 4, 1, 111, 2, 101, 114, 110, 17, 65, 3, 0, 4, 1, 114, 117, 103, 2, 108, 101, 3, 0, 4, 1, 114, 184, 195, 2, 115, 3, 0, 4, 1, 117, 2, 108, 3, 0, 4, 1, 117, 100, 32, 110, 101, 3, 0, 4, 1, 117, 100, 101, 100, 101, 118, 115, 3, 0, 4, 1, 117, 100, 101, 115, 121, 108, 3, 0, 4, 1, 117, 100, 103, 97, 108, 102, 3, 0, 4, 1, 117, 100, 107, 115, 97, 109, 97, 100, 3, 0, 4, 1, 117, 100, 108, 106, 101, 115, 3, 0, 4, 1, 117, 100, 114, 101, 109, 108, 111, 3, 0, 4, 1, 117, 100, 114, 101, 109, 109, 97, 107, 3, 0, 4, 1, 117, 100, 115, 107, 111, 118, 3, 0, 4, 1, 117, 100, 116, 108, 101, 116, 3, 0, 4, 1, 117, 114, 3, 0, 4, 1, 117, 116, 114, 101, 104, 3, 0, 1, 121, 115, 3, 0, 4, 1, 97, 2, 97, 118, 101, 3, 6, 81, 0, 8, 97, 2, 97, 114, 0, 101, 110, 116, 1, 114, 101, 115, 3, 6, 89, 57, 110, 50, 47, 0, 4, 1, 111, 103, 3, 8, 0, 1, 111, 108, 0, 4, 1, 111, 108, 2, 111, 3, 8, 81, 0, 1, 111, 108, 98, 2, 115, 0, 105, 1, 10, 2, 115, 107, 28, 33, 3, 8, 81, 37, 0, 101, 115, 1, 114, 97, 112, 115, 97, 3, 8, 89, 0, 4, 1, 97, 114, 2, 101, 3, 12, 0, 1, 97, 115, 2, 115, 0, 1, 117, 2, 101, 0, 1, 117, 115, 0, 1, 97, 100, 100, 2, 115, 3, 12, 19, 0, 101, 1, 184, 195, 2, 12, 12, 12, 3, 12, 57, 13, 0, 101, 1, 184, 195, 109, 2, 108, 101, 110, 3, 12, 57, 36, 0, 4, 1, 97, 98, 2, 101, 3, 13, 0, 1, 97, 107, 2, 101, 0, 4, 101, 110, 1, 114, 2, 32, 3, 13, 50, 0, 101, 110, 1, 114, 2, 115, 32, 0, 1, 97, 98, 2, 105, 3, 15, 0, 4, 101, 111, 114, 103, 101, 3, 21, 0, 101, 111, 114, 103, 105, 101, 0, 114, 97, 99, 101, 0, 114, 97, 104, 97, 109, 2, 32, 0, 114, 97, 104, 97, 109, 115, 2, 32, 0, 111, 110, 122, 97, 108, 101, 115, 3, 21, 101, 115, 0, 4, 97, 99, 104, 101, 116, 3, 21, 102, 114, 0, 117, 105, 108, 108, 97, 117, 109, 105, 110, 0, 4, 1, 97, 98, 2, 116, 97, 108, 3, 40, 0, 1, 97, 104, 2, 108, 0, 1, 114, 2, 101, 114, 32, 0, 1, 114, 184, 195, 0, 1, 165, 195, 0, 1, 165, 195, 2, 101, 0, 1, 165, 195, 118, 2, 110, 0, 101, 1, 114, 184, 195, 2, 108, 12, 3, 40, 108, 0, 116, 1, 114, 117, 112, 115, 3, 47, 0, 116, 101, 1, 114, 117, 112, 115, 3, 47, 13, 0, 4, 1, 105, 107, 3, 49, 0, 1, 111, 98, 2, 115, 116, 0, 110, 1, 97, 112, 2, 105, 3, 50, 6, 0, 4, 110, 1, 105, 2, 111, 3, 50, 57, 0, 110, 1, 166, 195, 114, 112, 109, 105, 2, 101, 0, 4, 1, 17, 65, 2, 110, 3, 57, 0, 1, 97, 100, 2, 115, 32, 0, 1, 97, 104, 101, 98, 0, 1, 97, 108, 2, 110, 0, 1, 97, 115, 0, 1, 101, 2, 101, 110, 115, 107, 97, 98, 0, 1, 101, 2, 101, 110, 116, 108, 0, 1, 101, 18, 73, 0, 1, 101, 108, 98, 2, 97, 110, 115, 105, 103, 116, 0, 1, 101, 108, 98, 2, 102, 105, 0, 1, 101, 108, 98, 2, 115, 111, 116, 0, 1, 101, 110, 2, 32, 0, 1, 101, 110, 115, 0, 1, 101, 118, 2, 101, 110, 0, 1, 105, 109, 115, 0, 1, 108, 2, 32, 0, 1, 108, 2, 101, 110, 32, 0, 1, 108, 2, 101, 116, 32, 0, 1, 108, 2, 115, 0, 1, 108, 97, 2, 101, 0, 1, 108, 97, 118, 0, 1, 108, 97, 118, 2, 195, 165, 114, 0, 1, 108, 101, 2, 101, 32, 0, 1, 108, 101, 2, 101, 110, 101, 32, 0, 1, 108, 101, 2, 101, 110, 101, 115, 32, 0, 1, 108, 166, 195, 2, 101, 0, 1, 108, 184, 195, 2, 101, 0, 1, 121, 2, 101, 0, 1, 166, 195, 2, 101, 0, 1, 166, 195, 2, 101, 114, 110, 17, 65, 0, 1, 166, 195, 108, 2, 100, 111, 109, 0, 1, 166, 195, 108, 2, 102, 111, 108, 107, 0, 1, 166, 195, 108, 2, 109, 0, 1, 166, 195, 108, 2, 115, 195, 184, 115, 0, 1, 166, 195, 114, 112, 0, 1, 166, 195, 118, 107, 0, 1, 184, 195, 0, 1, 184, 195, 2, 110, 0, 2, 108, 101, 0, 8, 101, 2, 32, 0, 110, 1, 105, 115, 108, 101, 118, 3, 57, 50, 0, 114, 1, 97, 108, 2, 101, 3, 57, 51, 0, 101, 1, 101, 2, 114, 3, 57, 114, 0, 4, 1, 97, 98, 2, 105, 110, 3, 58, 0, 1, 97, 100, 2, 17, 67, 0, 1, 97, 114, 98, 0, 1, 97, 114, 100, 0, 1, 97, 114, 100, 2, 101, 110, 0, 1, 97, 114, 118, 0, 1, 97, 118, 2, 110, 0, 1, 111, 17, 67, 0, 1, 111, 108, 114, 111, 0, 1, 114, 2, 32, 0, 1, 114, 2, 101, 116, 32, 0, 1, 114, 101, 106, 2, 17, 65, 0, 1, 114, 101, 106, 2, 17, 67, 0, 1, 114, 166, 195, 106, 2, 101, 0, 8, 97, 114, 112, 0, 101, 114, 1, 114, 166, 195, 2, 108, 105, 103, 3, 58, 13, 0, 101, 110, 1, 114, 97, 109, 3, 58, 13, 50, 0, 101, 114, 110, 101, 1, 114, 2, 32, 3, 58, 114, 50, 108, 0, 101, 114, 110, 101, 115, 1, 114, 2, 32, 3, 58, 114, 50, 108, 89, 0, 110, 1, 105, 115, 2, 101, 114, 3, 68, 0, 4, 110, 1, 97, 112, 2, 101, 114, 3, 68, 57, 0, 110, 1, 97, 112, 2, 111, 110, 0, 101, 110, 116, 108, 101, 109, 101, 110, 3, 72, 57, 109, 50, 47, 13, 55, 65, 109, 50, 0, 101, 110, 116, 108, 101, 109, 97, 110, 3, 72, 57, 109, 50, 47, 13, 55, 65, 110, 50, 0, 2, 105, 103, 111, 108, 111, 3, 75, 0, 101, 114, 97, 108, 100, 1, 122, 116, 105, 102, 3, 75, 6, 109, 34, 108, 59, 0, 105, 97, 110, 116, 115, 8, 3, 75, 35, 57, 110, 50, 47, 89, 0, 105, 8, 2, 110, 3, 75, 36, 0, 101, 114, 111, 110, 105, 109, 111, 3, 75, 36, 34, 6, 114, 50, 37, 65, 113, 12, 40, 0, 105, 110, 103, 101, 114, 8, 3, 75, 36, 50, 75, 114, 0, 4, 105, 8, 2, 110, 18, 69, 3, 75, 37, 0, 105, 8, 2, 110, 97, 0, 105, 117, 115, 101, 112, 112, 101, 3, 75, 37, 89, 6, 109, 48, 13, 0, 101, 114, 114, 121, 3, 75, 109, 34, 37, 0, 101, 114, 97, 108, 100, 3, 75, 109, 34, 108, 59, 0, 101, 114, 97, 108, 100, 105, 110, 101, 3, 75, 109, 34, 108, 59, 72, 37, 12, 50, 0, 101, 111, 102, 102, 3, 75, 109, 83, 0, 101, 111, 114, 103, 105, 97, 3, 75, 114, 12, 75, 57, 110, 0, 4, 3, 81, 0, 1, 17, 65, 2, 116, 32, 0, 1, 17, 65, 108, 2, 97, 0, 1, 97, 2, 110, 111, 115, 0, 1, 97, 100, 110, 97, 2, 116, 0, 1, 97, 108, 2, 116, 0, 1, 97, 114, 98, 2, 116, 0, 1, 97, 114, 100, 2, 111, 110, 0, 1, 97, 114, 100, 2, 116, 0, 1, 97, 114, 112, 2, 116, 0, 1, 97, 115, 2, 111, 0, 1, 101, 18, 73, 2, 116, 0, 1, 101, 114, 2, 105, 17, 65, 0, 1, 101, 114, 2, 105, 109, 101, 110, 116, 0, 1, 101, 116, 2, 111, 114, 105, 0, 1, 105, 2, 105, 0, 1, 108, 105, 112, 2, 114, 105, 109, 0, 1, 111, 2, 114, 97, 102, 0, 1, 111, 2, 114, 97, 109, 0, 1, 111, 98, 2, 111, 116, 97, 0, 1, 111, 108, 2, 97, 0, 1, 111, 108, 2, 102, 105, 108, 0, 1, 111, 114, 2, 97, 110, 0, 1, 111, 114, 2, 101, 115, 0, 1, 111, 114, 112, 2, 114, 0, 1, 111, 114, 114, 117, 115, 2, 97, 116, 0, 1, 111, 116, 2, 97, 0, 1, 111, 116, 2, 111, 0, 1, 111, 116, 2, 116, 0, 1, 111, 118, 2, 116, 0, 1, 111, 118, 2, 116, 101, 0, 1, 117, 2, 101, 110, 18, 66, 0, 1, 117, 2, 101, 110, 110, 0, 1, 117, 104, 2, 110, 105, 110, 103, 0, 1, 117, 109, 2, 110, 0, 1, 117, 114, 102, 2, 116, 0, 1, 117, 114, 117, 2, 117, 97, 121, 0, 1, 121, 98, 2, 110, 0, 1, 121, 107, 115, 2, 110, 105, 0, 1, 121, 116, 2, 110, 105, 110, 103, 0, 1, 166, 195, 2, 110, 12, 0, 1, 166, 195, 114, 112, 2, 110, 97, 0, 1, 166, 195, 114, 112, 2, 116, 105, 103, 0, 1, 184, 195, 114, 2, 116, 101, 114, 0, 1, 184, 195, 115, 2, 97, 110, 103, 0, 2, 101, 110, 115, 116, 97, 110, 100, 12, 0, 2, 105, 118, 12, 0, 2, 108, 97, 115, 0, 2, 108, 101, 109, 0, 2, 114, 97, 110, 0, 2, 114, 111, 115, 115, 0, 2, 114, 117, 18, 71, 0, 2, 114, 195, 184, 110, 0, 2, 116, 101, 32, 0, 2, 121, 114, 111, 0, 2, 195, 165, 114, 100, 12, 12, 0, 8, 2, 108, 101, 100, 0, 8, 111, 98, 2, 97, 114, 116, 0, 8, 111, 98, 2, 101, 121, 0, 8, 111, 108, 2, 32, 0, 8, 111, 108, 2, 103, 0, 103, 1, 97, 2, 114, 101, 115, 0, 103, 1, 105, 0, 103, 1, 111, 0, 103, 1, 111, 108, 2, 101, 0, 103, 2, 101, 0, 104, 1, 102, 97, 2, 97, 0, 104, 2, 97, 110, 97, 0, 104, 2, 101, 116, 116, 111, 0, 4, 1, 97, 2, 117, 114, 107, 3, 81, 6, 0, 1, 111, 108, 2, 105, 0, 8, 101, 114, 2, 105, 115, 116, 0, 101, 114, 1, 21, 2, 28, 33, 3, 81, 6, 36, 34, 0, 4, 101, 110, 1, 111, 114, 101, 3, 81, 6, 36, 50, 0, 101, 110, 1, 111, 114, 116, 105, 110, 0, 101, 110, 1, 111, 114, 116, 115, 184, 195, 0, 105, 1, 101, 114, 2, 115, 116, 101, 114, 3, 81, 6, 37, 0, 97, 1, 111, 110, 111, 109, 2, 109, 3, 81, 6, 110, 0, 4, 105, 1, 17, 67, 21, 2, 28, 33, 3, 81, 7, 37, 0, 105, 1, 21, 2, 28, 33, 0, 108, 101, 1, 111, 111, 103, 3, 81, 20, 13, 55, 0, 114, 97, 110, 100, 101, 8, 2, 32, 3, 81, 34, 35, 50, 72, 108, 0, 114, 111, 115, 1, 32, 110, 101, 3, 81, 34, 39, 0, 114, 97, 100, 121, 3, 81, 34, 109, 57, 72, 37, 0, 114, 97, 110, 100, 112, 114, 105, 120, 3, 81, 34, 112, 68, 48, 34, 6, 37, 0, 114, 97, 102, 102, 105, 116, 105, 3, 81, 34, 112, 83, 6, 37, 47, 37, 0, 114, 117, 110, 103, 101, 8, 2, 32, 3, 81, 34, 114, 50, 75, 0, 114, 195, 184, 100, 1, 101, 108, 98, 166, 195, 3, 81, 34, 118, 86, 0, 4, 117, 121, 8, 2, 32, 3, 81, 35, 12, 57, 0, 117, 121, 8, 2, 115, 32, 0, 117, 105, 2, 110, 110, 101, 115, 3, 81, 36, 0, 101, 111, 114, 103, 105, 101, 110, 3, 81, 36, 6, 113, 12, 81, 37, 108, 50, 0, 105, 110, 115, 98, 101, 114, 103, 3, 81, 36, 50, 89, 71, 118, 12, 81, 0, 4, 105, 1, 101, 114, 2, 109, 101, 110, 28, 33, 12, 3, 81, 37, 0, 105, 1, 101, 114, 2, 111, 110, 12, 0, 105, 1, 101, 114, 2, 115, 116, 114, 101, 28, 33, 12, 0, 101, 97, 114, 3, 81, 37, 34, 0, 117, 105, 114, 108, 97, 110, 100, 3, 81, 37, 34, 55, 6, 110, 50, 72, 0, 117, 105, 110, 101, 97, 3, 81, 37, 50, 6, 36, 110, 0, 117, 105, 108, 108, 111, 116, 105, 110, 101, 3, 81, 37, 57, 40, 47, 6, 37, 12, 50, 13, 0, 111, 100, 97, 102, 116, 101, 110, 3, 81, 39, 6, 35, 83, 47, 50, 0, 111, 100, 110, 97, 116, 3, 81, 39, 50, 6, 110, 47, 0, 111, 100, 109, 111, 114, 103, 101, 110, 3, 81, 39, 65, 6, 114, 12, 50, 0, 111, 98, 101, 108, 105, 110, 3, 81, 39, 71, 13, 55, 6, 109, 68, 0, 111, 100, 100, 97, 103, 3, 81, 39, 72, 6, 110, 0, 117, 100, 115, 107, 101, 108, 111, 118, 8, 2, 32, 3, 81, 40, 89, 81, 13, 55, 114, 40, 0, 108, 111, 117, 99, 101, 115, 116, 101, 114, 3, 81, 55, 114, 89, 47, 114, 0, 106, 111, 114, 100, 101, 3, 81, 57, 39, 12, 114, 0, 117, 105, 114, 101, 3, 81, 58, 6, 120, 114, 0, 109, 97, 116, 97, 1, 105, 116, 115, 3, 81, 65, 6, 110, 12, 47, 110, 0, 195, 166, 1, 110, 3, 81, 109, 0, 97, 116, 101, 115, 8, 2, 32, 3, 81, 109, 57, 47, 89, 0, 97, 98, 108, 101, 8, 3, 81, 109, 57, 71, 13, 55, 0, 97, 114, 121, 8, 3, 81, 110, 34, 37, 0, 117, 97, 114, 100, 3, 81, 112, 12, 72, 0, 111, 117, 100, 97, 3, 81, 112, 58, 72, 110, 0, 97, 117, 108, 108, 101, 3, 81, 113, 12, 55, 0, 111, 103, 111, 3, 81, 113, 58, 81, 6, 113, 58, 0, 117, 115, 116, 97, 118, 3, 81, 113, 89, 47, 35, 58, 0, 117, 108, 102, 115, 116, 114, 101, 97, 109, 3, 81, 114, 55, 83, 89, 47, 34, 37, 12, 65, 0, 117, 116, 104, 114, 105, 101, 3, 81, 114, 87, 51, 37, 0, 117, 101, 114, 110, 115, 101, 121, 3, 81, 118, 12, 50, 89, 37, 0, 101, 114, 116, 105, 101, 3, 81, 118, 47, 37, 0, 4, 101, 108, 101, 3, 89, 57, 36, 55, 6, 36, 0, 101, 108, 195, 169, 0, 101, 111, 105, 115, 1, 114, 117, 111, 98, 3, 90, 58, 6, 112, 0, 101, 111, 105, 115, 105, 1, 114, 117, 111, 98, 3, 90, 58, 112, 89, 6, 37, 0, 4, 1, 101, 114, 2, 105, 109, 101, 3, 91, 0, 1, 117, 2, 101, 110, 101, 0, 2, 105, 114, 111, 0, 4, 105, 1, 101, 114, 2, 28, 33, 12, 3, 91, 6, 37, 0, 105, 8, 111, 108, 2, 32, 0, 105, 8, 111, 108, 2, 101, 0, 105, 101, 114, 1, 108, 97, 3, 91, 6, 37, 34, 0, 101, 1, 110, 105, 2, 110, 105, 195, 184, 114, 3, 91, 36, 0, 4, 101, 110, 101, 114, 2, 32, 100, 101, 109, 3, 91, 36, 50, 6, 36, 34, 0, 101, 110, 101, 114, 2, 32, 100, 101, 114, 101, 115, 0, 101, 110, 101, 114, 2, 32, 104, 97, 109, 0, 101, 110, 101, 114, 2, 32, 104, 101, 110, 100, 101, 0, 4, 101, 110, 101, 118, 101, 3, 91, 36, 50, 6, 109, 12, 84, 0, 101, 110, 195, 168, 118, 101, 0, 101, 114, 97, 114, 100, 8, 3, 91, 36, 51, 6, 112, 12, 0, 105, 1, 111, 108, 116, 97, 110, 3, 91, 37, 0, 105, 98, 114, 97, 108, 116, 97, 114, 3, 91, 37, 71, 51, 35, 55, 47, 6, 112, 0, 101, 114, 105, 115, 107, 1, 108, 97, 3, 91, 57, 6, 37, 12, 34, 89, 81, 0, 101, 114, 105, 101, 114, 1, 108, 97, 3, 91, 57, 6, 37, 114, 0, 101, 114, 105, 101, 116, 1, 108, 97, 3, 91, 57, 108, 34, 6, 37, 13, 72, 0, 101, 110, 100, 97, 114, 109, 3, 91, 110, 50, 72, 6, 35, 34, 65, 0, 4, 101, 114, 1, 101, 110, 2, 12, 12, 3, 114, 0, 114, 101, 1, 101, 110, 0, 7, 6, 104, 0, 4, 1, 17, 65, 2, 25, 3, 0, 4, 1, 119, 2, 105, 115, 107, 121, 3, 0, 4, 1, 119, 2, 105, 116, 3, 0, 4, 2, 106, 3, 0, 8, 114, 2, 105, 110, 3, 0, 4, 101, 109, 1, 111, 98, 2, 101, 3, 6, 109, 12, 65, 0, 101, 109, 101, 1, 111, 98, 2, 32, 0, 111, 1, 103, 2, 115, 116, 3, 39, 58, 0, 117, 101, 1, 108, 105, 115, 2, 116, 3, 40, 6, 109, 0, 118, 3, 84, 0, 4, 3, 107, 0, 1, 116, 2, 101, 110, 0, 105, 116, 101, 99, 104, 3, 107, 35, 57, 47, 36, 49, 0, 121, 100, 101, 8, 3, 107, 35, 57, 72, 0, 111, 119, 97, 114, 100, 3, 107, 35, 58, 114, 72, 0, 105, 108, 108, 97, 114, 121, 3, 107, 36, 55, 13, 16, 36, 0, 101, 97, 116, 3, 107, 37, 12, 47, 0, 105, 101, 114, 111, 103, 108, 121, 2, 102, 3, 107, 37, 34, 39, 83, 55, 6, 116, 0, 105, 112, 111, 107, 114, 97, 116, 101, 115, 3, 107, 37, 48, 6, 39, 49, 34, 35, 47, 109, 89, 0, 111, 109, 101, 114, 3, 107, 39, 65, 6, 36, 34, 0, 117, 103, 104, 3, 107, 57, 40, 12, 0, 117, 103, 101, 115, 8, 2, 32, 3, 107, 57, 40, 12, 89, 0, 111, 117, 115, 116, 111, 110, 3, 107, 57, 40, 12, 89, 72, 114, 50, 0, 97, 105, 103, 8, 3, 107, 109, 57, 81, 0, 101, 97, 118, 121, 3, 107, 109, 84, 37, 0, 101, 97, 116, 104, 101, 114, 3, 107, 109, 86, 114, 0, 97, 97, 103, 8, 2, 32, 3, 107, 110, 57, 0, 97, 119, 97, 105, 105, 3, 107, 110, 58, 6, 35, 12, 57, 37, 0, 105, 103, 104, 104, 97, 116, 3, 107, 112, 12, 57, 107, 110, 72, 0, 111, 117, 115, 101, 99, 111, 97, 116, 3, 107, 112, 40, 89, 49, 39, 58, 72, 0, 97, 119, 116, 104, 111, 114, 110, 101, 3, 107, 113, 12, 87, 39, 50, 0, 111, 109, 101, 3, 107, 113, 58, 65, 0, 97, 119, 107, 3, 107, 114, 12, 49, 0, 111, 116, 108, 105, 110, 101, 3, 107, 114, 47, 55, 35, 12, 57, 50, 0, 117, 99, 107, 108, 101, 98, 101, 114, 114, 121, 3, 107, 114, 49, 13, 55, 71, 109, 34, 37, 0, 111, 110, 101, 121, 3, 107, 114, 50, 37, 0, 117, 110, 116, 8, 2, 32, 3, 107, 114, 50, 47, 0, 111, 108, 108, 121, 3, 107, 114, 55, 37, 0, 117, 109, 118, 101, 101, 3, 107, 114, 65, 84, 37, 12, 0, 117, 109, 118, 101, 101, 114, 3, 107, 114, 65, 84, 37, 12, 114, 0, 117, 100, 115, 111, 110, 3, 107, 114, 72, 89, 114, 50, 0, 101, 114, 98, 8, 2, 32, 3, 107, 118, 12, 71, 0, 101, 97, 114, 115, 116, 8, 3, 107, 118, 89, 47, 0, 101, 105, 109, 3, 107, 120, 65, 0, 101, 114, 99, 117, 108, 101, 8, 3, 109, 34, 49, 6, 116, 55, 0, 7, 6, 105, 0, 4, 1, 110, 101, 103, 110, 105, 2, 195, 184, 114, 3, 0, 4, 1, 116, 2, 195, 184, 115, 3, 0, 4, 1, 117, 106, 2, 99, 101, 3, 0, 1, 118, 2, 110, 100, 114, 105, 107, 12, 3, 0, 107, 1, 21, 2, 101, 114, 28, 33, 12, 12, 3, 2, 37, 49, 0, 4, 1, 103, 101, 114, 116, 115, 109, 105, 104, 2, 109, 115, 3, 6, 36, 0, 1, 107, 121, 114, 2, 110, 100, 0, 1, 114, 101, 2, 110, 100, 114, 0, 1, 114, 121, 98, 97, 108, 2, 110, 116, 0, 1, 115, 116, 101, 108, 2, 110, 100, 105, 103, 0, 8, 108, 121, 99, 2, 110, 100, 0, 8, 114, 116, 115, 105, 100, 2, 107, 116, 0, 8, 115, 98, 97, 2, 110, 116, 0, 8, 116, 115, 101, 118, 2, 110, 100, 105, 0, 8, 116, 115, 110, 105, 2, 110, 107, 116, 0, 110, 100, 101, 1, 10, 2, 28, 33, 3, 6, 36, 50, 13, 0, 110, 103, 1, 109, 111, 100, 2, 111, 3, 6, 36, 50, 81, 0, 110, 100, 101, 1, 10, 2, 114, 28, 33, 3, 6, 36, 50, 114, 0, 108, 1, 116, 115, 97, 112, 10, 2, 28, 33, 12, 12, 12, 12, 3, 6, 36, 55, 0, 4, 1, 100, 111, 115, 111, 114, 112, 3, 6, 37, 0, 1, 100, 114, 166, 195, 118, 0, 1, 100, 117, 111, 104, 2, 110, 105, 0, 1, 102, 108, 121, 115, 2, 100, 101, 0, 1, 103, 105, 115, 107, 101, 2, 98, 101, 108, 0, 1, 103, 110, 117, 102, 2, 98, 101, 108, 0, 1, 104, 97, 116, 2, 116, 105, 0, 1, 104, 97, 119, 115, 2, 108, 105, 0, 1, 107, 2, 101, 116, 12, 0, 1, 108, 101, 98, 111, 2, 115, 107, 0, 1, 108, 105, 102, 2, 115, 116, 0, 1, 108, 108, 105, 99, 105, 112, 109, 97, 2, 110, 0, 1, 108, 111, 98, 2, 118, 105, 97, 0, 1, 108, 111, 115, 115, 117, 109, 2, 110, 105, 0, 1, 109, 10, 2, 28, 33, 0, 1, 109, 97, 2, 103, 111, 0, 1, 109, 97, 18, 75, 2, 108, 108, 97, 0, 1, 109, 97, 107, 2, 108, 108, 101, 0, 1, 109, 105, 2, 100, 108, 101, 114, 116, 105, 100, 0, 1, 110, 97, 112, 109, 97, 107, 2, 108, 101, 0, 1, 110, 101, 112, 2, 98, 101, 108, 0, 1, 110, 111, 112, 115, 105, 100, 2, 98, 101, 108, 0, 1, 112, 115, 97, 2, 99, 0, 1, 114, 10, 2, 101, 116, 28, 33, 0, 1, 114, 97, 109, 2, 97, 0, 1, 114, 97, 112, 2, 115, 0, 1, 114, 97, 116, 2, 102, 0, 1, 114, 100, 97, 109, 2, 100, 0, 1, 114, 100, 101, 122, 110, 101, 98, 2, 110, 0, 1, 114, 101, 104, 115, 2, 102, 0, 1, 114, 101, 118, 111, 116, 110, 105, 114, 98, 2, 108, 116, 101, 0, 1, 114, 105, 112, 115, 97, 2, 110, 0, 1, 114, 110, 101, 104, 2, 118, 101, 110, 100, 101, 0, 1, 114, 114, 111, 104, 2, 98, 101, 108, 0, 1, 115, 10, 2, 28, 33, 0, 1, 115, 97, 103, 97, 109, 0, 1, 115, 97, 107, 2, 110, 111, 0, 1, 115, 105, 118, 2, 98, 101, 108, 0, 1, 115, 107, 101, 108, 102, 2, 98, 101, 108, 0, 1, 115, 108, 105, 116, 2, 100, 101, 0, 1, 115, 110, 101, 115, 2, 98, 101, 108, 0, 1, 115, 114, 101, 118, 101, 114, 2, 98, 101, 108, 0, 1, 115, 114, 101, 118, 101, 114, 114, 105, 2, 98, 101, 108, 0, 1, 115, 115, 105, 115, 115, 105, 109, 2, 112, 112, 105, 0, 1, 115, 117, 97, 108, 112, 2, 98, 101, 108, 0, 1, 116, 97, 112, 109, 111, 107, 2, 98, 101, 108, 0, 1, 116, 107, 101, 102, 114, 101, 112, 2, 98, 101, 108, 0, 1, 116, 114, 101, 118, 110, 111, 107, 2, 98, 101, 108, 0, 1, 116, 114, 111, 115, 2, 101, 0, 1, 116, 115, 101, 103, 103, 117, 115, 2, 98, 101, 108, 0, 1, 116, 120, 105, 115, 2, 110, 115, 107, 0, 1, 118, 101, 114, 114, 105, 112, 115, 2, 112, 0, 8, 98, 105, 108, 97, 0, 8, 98, 108, 97, 2, 110, 111, 0, 8, 98, 111, 102, 0, 8, 99, 110, 97, 114, 102, 2, 115, 99, 111, 0, 8, 99, 110, 105, 114, 112, 2, 112, 0, 8, 99, 110, 111, 107, 2, 115, 0, 8, 99, 114, 101, 115, 107, 101, 2, 116, 115, 0, 8, 99, 166, 195, 114, 112, 2, 115, 0, 8, 100, 97, 114, 2, 115, 101, 0, 8, 100, 101, 98, 98, 97, 0, 8, 100, 101, 102, 102, 117, 109, 2, 115, 101, 0, 8, 100, 105, 102, 114, 101, 112, 0, 8, 100, 110, 97, 98, 2, 116, 0, 8, 100, 110, 97, 107, 115, 114, 97, 109, 2, 115, 0, 8, 100, 111, 107, 111, 114, 107, 2, 108, 108, 0, 8, 100, 111, 108, 101, 109, 0, 8, 100, 111, 114, 97, 112, 0, 8, 100, 111, 115, 112, 97, 114, 0, 8, 100, 166, 195, 112, 111, 116, 114, 111, 0, 8, 101, 114, 2, 115, 116, 101, 114, 0, 8, 102, 105, 99, 117, 114, 107, 2, 107, 115, 0, 8, 103, 97, 109, 2, 32, 0, 8, 103, 97, 109, 2, 101, 110, 32, 0, 8, 103, 97, 109, 2, 115, 116, 101, 114, 0, 8, 107, 114, 97, 109, 2, 115, 101, 0, 8, 107, 115, 97, 109, 2, 110, 0, 8, 108, 97, 103, 101, 109, 111, 114, 107, 97, 0, 8, 108, 97, 107, 2, 98, 101, 114, 0, 8, 108, 97, 109, 111, 110, 97, 0, 8, 108, 100, 101, 109, 2, 100, 101, 110, 104, 101, 100, 0, 8, 108, 101, 102, 102, 97, 116, 115, 0, 8, 108, 101, 116, 97, 108, 105, 102, 0, 8, 108, 102, 102, 117, 115, 0, 8, 108, 102, 110, 111, 107, 2, 107, 116, 0, 8, 108, 105, 102, 111, 100, 166, 195, 112, 0, 8, 108, 105, 102, 111, 105, 108, 98, 105, 98, 0, 8, 108, 105, 102, 111, 109, 111, 104, 0, 8, 108, 105, 102, 111, 111, 122, 0, 8, 108, 105, 102, 111, 114, 101, 116, 101, 104, 0, 8, 108, 105, 102, 111, 114, 107, 101, 110, 0, 8, 108, 105, 109, 2, 116, 115, 0, 8, 108, 108, 101, 99, 110, 97, 107, 0, 8, 108, 111, 2, 118, 101, 110, 0, 8, 108, 111, 2, 118, 105, 97, 0, 8, 108, 111, 107, 110, 97, 108, 101, 109, 0, 8, 108, 111, 115, 2, 100, 0, 8, 108, 115, 117, 109, 2, 109, 0, 8, 108, 117, 107, 2, 115, 115, 0, 8, 109, 97, 114, 121, 112, 2, 100, 0, 8, 109, 101, 114, 2, 115, 0, 8, 110, 105, 109, 2, 115, 116, 101, 114, 0, 8, 111, 114, 101, 116, 115, 97, 2, 100, 101, 0, 8, 112, 97, 107, 2, 116, 101, 108, 0, 8, 112, 97, 107, 2, 116, 108, 0, 8, 112, 97, 112, 2, 114, 0, 8, 112, 97, 114, 101, 116, 0, 8, 112, 97, 116, 2, 114, 0, 8, 112, 101, 107, 115, 97, 109, 0, 8, 112, 111, 107, 0, 8, 112, 111, 107, 115, 101, 108, 101, 116, 0, 8, 112, 111, 107, 115, 111, 107, 110, 111, 114, 98, 0, 8, 112, 111, 107, 115, 111, 108, 121, 116, 107, 97, 100, 0, 8, 112, 111, 107, 115, 111, 114, 116, 115, 97, 103, 0, 8, 112, 111, 107, 115, 111, 116, 101, 116, 115, 0, 8, 112, 111, 107, 115, 111, 116, 107, 101, 114, 0, 8, 112, 111, 107, 115, 111, 116, 111, 0, 8, 112, 111, 114, 116, 110, 97, 108, 105, 102, 0, 8, 112, 111, 114, 116, 110, 97, 115, 105, 109, 0, 8, 112, 111, 114, 116, 110, 101, 0, 8, 112, 111, 116, 111, 115, 105, 0, 8, 112, 111, 116, 117, 0, 8, 112, 111, 116, 117, 0, 8, 112, 121, 116, 111, 101, 114, 101, 116, 115, 0, 8, 112, 121, 116, 111, 101, 114, 114, 101, 117, 103, 97, 100, 0, 8, 112, 121, 116, 111, 110, 97, 118, 108, 97, 103, 0, 8, 112, 121, 116, 111, 110, 111, 109, 0, 8, 112, 121, 116, 111, 116, 105, 108, 0, 8, 112, 121, 116, 111, 116, 117, 97, 0, 8, 114, 101, 118, 121, 116, 0, 8, 114, 111, 103, 101, 116, 97, 107, 0, 8, 114, 111, 103, 108, 97, 2, 116, 109, 101, 0, 8, 114, 111, 109, 166, 195, 104, 2, 100, 0, 8, 114, 112, 101, 114, 2, 115, 101, 0, 8, 114, 112, 101, 114, 116, 110, 101, 2, 115, 101, 0, 8, 114, 116, 110, 101, 118, 2, 107, 0, 8, 115, 108, 101, 118, 2, 103, 110, 0, 8, 115, 115, 101, 109, 2, 97, 115, 0, 8, 116, 105, 103, 101, 108, 2, 109, 0, 8, 116, 105, 108, 111, 112, 0, 8, 116, 105, 108, 111, 112, 0, 8, 116, 110, 105, 2, 109, 0, 8, 116, 114, 97, 2, 107, 0, 8, 116, 114, 97, 109, 2, 110, 105, 0, 8, 116, 114, 97, 112, 2, 115, 107, 0, 8, 116, 115, 101, 116, 2, 107, 101, 108, 0, 8, 116, 115, 101, 116, 2, 107, 108, 0, 8, 116, 115, 117, 106, 2, 116, 115, 0, 8, 118, 97, 2, 115, 0, 8, 118, 97, 114, 103, 2, 100, 0, 8, 118, 101, 108, 111, 109, 2, 116, 0, 8, 118, 105, 99, 2, 108, 0, 101, 1, 116, 114, 111, 115, 2, 32, 0, 115, 1, 109, 101, 114, 2, 32, 0, 101, 8, 118, 108, 97, 115, 3, 6, 37, 12, 0, 103, 101, 8, 108, 100, 101, 118, 3, 6, 37, 13, 0, 103, 101, 118, 101, 108, 1, 108, 108, 97, 3, 6, 37, 13, 84, 109, 55, 0, 108, 1, 10, 2, 28, 33, 12, 12, 12, 12, 3, 6, 37, 55, 0, 4, 108, 108, 101, 1, 114, 100, 97, 107, 115, 101, 3, 6, 37, 55, 57, 108, 0, 108, 108, 101, 1, 114, 100, 97, 112, 115, 101, 0, 108, 108, 101, 1, 114, 100, 97, 118, 107, 0, 108, 108, 101, 1, 116, 115, 97, 98, 0, 103, 111, 110, 101, 1, 116, 110, 97, 3, 6, 37, 81, 39, 50, 13, 0, 115, 1, 117, 111, 108, 2, 101, 3, 6, 37, 89, 0, 115, 109, 101, 1, 10, 2, 114, 28, 33, 3, 6, 37, 89, 65, 114, 0, 111, 110, 1, 114, 111, 3, 6, 37, 114, 50, 0, 114, 116, 117, 97, 108, 1, 118, 2, 32, 114, 101, 97, 108, 105, 116, 121, 3, 6, 108, 76, 40, 20, 13, 59, 0, 1, 114, 107, 115, 10, 2, 112, 116, 3, 6, 109, 0, 4, 8, 114, 107, 109, 111, 2, 110, 103, 3, 7, 36, 0, 107, 1, 114, 10, 2, 107, 28, 33, 0, 107, 1, 114, 21, 2, 107, 28, 33, 12, 12, 12, 12, 0, 107, 1, 116, 115, 101, 21, 2, 107, 28, 33, 12, 12, 12, 0, 107, 1, 114, 10, 2, 28, 33, 12, 12, 3, 7, 36, 49, 0, 4, 1, 116, 10, 2, 28, 33, 12, 3, 7, 37, 0, 1, 116, 110, 101, 108, 97, 118, 2, 110, 111, 0, 8, 108, 101, 2, 116, 101, 0, 8, 116, 114, 101, 112, 115, 107, 101, 2, 115, 101, 0, 107, 1, 10, 2, 107, 28, 33, 12, 0, 107, 1, 21, 2, 107, 28, 33, 12, 12, 12, 0, 107, 1, 116, 115, 97, 21, 2, 107, 28, 33, 12, 12, 12, 0, 4, 107, 1, 21, 2, 28, 33, 12, 12, 12, 3, 7, 37, 49, 0, 107, 1, 114, 111, 10, 2, 28, 33, 12, 12, 0, 100, 1, 10, 2, 28, 33, 3, 7, 37, 86, 0, 115, 109, 101, 1, 10, 2, 28, 33, 3, 7, 37, 89, 65, 13, 0, 1, 114, 10, 2, 117, 109, 28, 33, 3, 8, 8, 37, 0, 103, 1, 109, 101, 112, 108, 166, 195, 106, 104, 100, 117, 103, 3, 8, 35, 57, 0, 4, 1, 109, 10, 2, 115, 107, 28, 33, 3, 8, 37, 0, 1, 114, 111, 108, 97, 107, 2, 117, 115, 0, 101, 1, 10, 2, 114, 101, 28, 33, 3, 8, 37, 7, 36, 0, 101, 1, 10, 2, 108, 105, 118, 28, 33, 3, 8, 37, 13, 0, 101, 110, 1, 10, 2, 28, 33, 3, 8, 37, 13, 50, 0, 116, 117, 109, 1, 21, 2, 109, 28, 33, 3, 8, 37, 47, 113, 0, 116, 117, 109, 1, 21, 2, 28, 33, 3, 8, 37, 47, 113, 65, 0, 107, 1, 21, 2, 101, 114, 101, 110, 28, 33, 12, 12, 3, 8, 37, 49, 0, 4, 107, 101, 114, 1, 10, 2, 28, 33, 12, 3, 8, 37, 49, 114, 0, 107, 101, 114, 1, 109, 10, 2, 101, 28, 33, 12, 12, 0, 107, 101, 114, 1, 110, 97, 107, 21, 2, 101, 32, 28, 33, 12, 12, 12, 0, 107, 101, 114, 1, 114, 116, 10, 2, 101, 28, 33, 12, 0, 107, 101, 114, 1, 116, 10, 2, 101, 28, 33, 12, 0, 4, 115, 107, 1, 10, 2, 32, 28, 33, 3, 8, 37, 89, 81, 0, 115, 107, 1, 10, 2, 101, 28, 33, 0, 115, 107, 1, 10, 2, 116, 28, 33, 0, 101, 1, 10, 2, 28, 33, 3, 8, 37, 108, 0, 117, 109, 1, 10, 2, 109, 28, 33, 3, 8, 37, 113, 0, 117, 109, 1, 10, 2, 28, 33, 3, 8, 37, 113, 65, 0, 101, 1, 115, 10, 2, 28, 33, 3, 8, 57, 108, 0, 4, 101, 1, 10, 2, 114, 28, 33, 3, 8, 57, 114, 0, 101, 114, 1, 108, 97, 114, 116, 115, 117, 97, 0, 109, 112, 114, 111, 109, 112, 116, 117, 3, 21, 102, 114, 0, 116, 104, 101, 1, 108, 98, 3, 35, 12, 57, 86, 0, 103, 110, 1, 115, 101, 100, 3, 35, 37, 50, 0, 4, 1, 108, 115, 117, 115, 107, 117, 108, 2, 110, 101, 114, 3, 35, 57, 0, 1, 114, 2, 108, 101, 121, 0, 1, 116, 2, 109, 105, 110, 103, 0, 1, 116, 102, 111, 115, 2, 99, 101, 0, 2, 111, 119, 97, 0, 103, 104, 1, 104, 0, 103, 104, 1, 108, 2, 116, 101, 114, 0, 106, 1, 110, 2, 109, 101, 103, 101, 110, 0, 107, 101, 8, 112, 115, 3, 35, 57, 49, 0, 115, 108, 97, 110, 100, 1, 32, 103, 110, 111, 108, 3, 35, 57, 55, 13, 50, 72, 0, 109, 101, 1, 116, 2, 111, 117, 116, 3, 35, 57, 65, 0, 4, 109, 101, 115, 1, 114, 103, 3, 35, 57, 65, 89, 0, 109, 101, 115, 1, 116, 32, 107, 114, 111, 121, 32, 119, 101, 110, 0, 100, 97, 104, 111, 3, 35, 57, 72, 110, 107, 6, 39, 58, 0, 118, 101, 1, 108, 99, 3, 35, 57, 84, 0, 118, 97, 110, 104, 111, 101, 3, 35, 57, 84, 13, 50, 107, 6, 39, 58, 0, 114, 101, 1, 119, 3, 35, 57, 114, 0, 114, 111, 110, 8, 2, 32, 3, 35, 57, 114, 50, 0, 4, 1, 17, 67, 2, 109, 17, 67, 3, 36, 0, 1, 17, 67, 2, 109, 18, 71, 0, 1, 17, 67, 2, 110, 103, 12, 0, 1, 17, 67, 2, 110, 107, 0, 1, 18, 67, 2, 112, 0, 1, 18, 67, 2, 112, 112, 0, 1, 18, 68, 2, 18, 66, 11, 12, 0, 1, 18, 68, 2, 107, 0, 1, 18, 71, 2, 107, 0, 1, 18, 71, 2, 108, 108, 101, 0, 1, 18, 72, 2, 102, 116, 101, 0, 1, 18, 73, 2, 108, 108, 0, 1, 18, 74, 2, 18, 68, 11, 97, 12, 0, 1, 18, 74, 2, 107, 115, 0, 1, 18, 74, 2, 112, 112, 0, 1, 18, 74, 2, 120, 0, 1, 98, 2, 116, 114, 101, 0, 1, 98, 2, 116, 116, 101, 114, 0, 1, 100, 2, 110, 103, 111, 0, 1, 100, 2, 115, 107, 0, 1, 102, 2, 18, 73, 12, 0, 1, 102, 2, 107, 115, 0, 1, 102, 2, 110, 108, 97, 110, 100, 0, 1, 102, 2, 110, 116, 101, 32, 0, 1, 102, 2, 120, 0, 1, 104, 2, 109, 12, 0, 1, 104, 2, 110, 100, 0, 1, 107, 2, 18, 74, 12, 12, 0, 1, 107, 2, 109, 115, 101, 0, 1, 107, 111, 109, 115, 2, 110, 103, 0, 1, 107, 115, 2, 108, 12, 12, 0, 1, 107, 115, 2, 110, 0, 1, 108, 2, 18, 66, 0, 1, 108, 2, 18, 73, 0, 1, 108, 2, 108, 108, 97, 0, 1, 108, 2, 110, 110, 101, 100, 0, 1, 108, 2, 110, 115, 0, 1, 108, 2, 110, 116, 0, 1, 108, 17, 67, 2, 112, 0, 1, 108, 18, 73, 2, 18, 72, 0, 1, 108, 103, 2, 109, 0, 1, 108, 107, 2, 107, 32, 0, 1, 108, 112, 2, 103, 116, 12, 0, 1, 108, 115, 2, 107, 0, 1, 109, 2, 107, 108, 101, 114, 0, 1, 109, 2, 115, 116, 101, 0, 1, 110, 2, 112, 0, 1, 110, 2, 115, 115, 101, 0, 1, 110, 2, 116, 116, 101, 110, 0, 1, 110, 107, 2, 112, 0, 1, 112, 2, 108, 114, 0, 1, 112, 2, 115, 115, 101, 0, 1, 112, 115, 2, 100, 115, 0, 1, 112, 115, 2, 108, 0, 1, 114, 2, 18, 66, 11, 0, 1, 114, 2, 18, 73, 12, 0, 1, 114, 2, 18, 75, 0, 1, 114, 2, 102, 0, 1, 114, 2, 103, 116, 105, 0, 1, 114, 17, 67, 2, 108, 108, 0, 1, 114, 17, 67, 2, 109, 17, 67, 0, 1, 114, 18, 71, 2, 110, 116, 0, 1, 114, 100, 2, 115, 116, 105, 103, 0, 1, 114, 102, 2, 115, 116, 101, 100, 101, 32, 0, 1, 114, 102, 2, 115, 116, 101, 100, 101, 115, 32, 0, 1, 114, 103, 2, 109, 0, 1, 114, 107, 2, 99, 107, 101, 116, 0, 1, 114, 107, 2, 115, 116, 105, 32, 0, 1, 114, 107, 2, 115, 116, 117, 115, 0, 1, 114, 112, 2, 110, 0, 1, 114, 118, 2, 115, 115, 0, 1, 115, 2, 18, 66, 18, 72, 0, 1, 115, 2, 100, 32, 0, 1, 115, 2, 100, 100, 101, 0, 1, 115, 2, 100, 110, 105, 110, 103, 0, 1, 115, 2, 107, 17, 67, 0, 1, 115, 2, 108, 107, 0, 1, 115, 2, 110, 107, 12, 12, 0, 1, 115, 2, 112, 112, 0, 1, 116, 2, 18, 66, 12, 0, 1, 116, 2, 103, 103, 12, 0, 1, 116, 2, 108, 0, 1, 116, 115, 2, 108, 32, 104, 97, 109, 0, 1, 116, 115, 2, 108, 32, 111, 112, 32, 0, 1, 116, 115, 2, 108, 108, 105, 110, 103, 12, 12, 0, 1, 116, 115, 100, 110, 166, 195, 116, 2, 107, 12, 0, 1, 116, 115, 101, 98, 2, 107, 12, 12, 0, 1, 116, 115, 101, 98, 2, 108, 0, 1, 116, 115, 101, 98, 166, 195, 108, 2, 102, 116, 0, 1, 116, 115, 101, 100, 97, 112, 115, 2, 107, 0, 1, 116, 115, 101, 103, 103, 121, 109, 2, 107, 0, 1, 116, 115, 101, 108, 165, 195, 110, 2, 107, 12, 0, 1, 116, 115, 101, 110, 103, 101, 116, 2, 102, 116, 0, 1, 116, 115, 101, 114, 111, 102, 2, 108, 0, 1, 116, 115, 103, 97, 108, 115, 2, 102, 116, 0, 1, 116, 115, 105, 98, 2, 107, 12, 12, 0, 1, 116, 115, 107, 166, 195, 108, 98, 2, 102, 116, 0, 1, 116, 115, 109, 105, 108, 2, 102, 116, 0, 1, 116, 115, 115, 116, 110, 97, 121, 108, 98, 2, 102, 116, 0, 1, 116, 115, 116, 110, 97, 121, 108, 98, 2, 102, 116, 0, 1, 116, 115, 118, 105, 110, 107, 2, 107, 0, 1, 118, 2, 18, 66, 0, 1, 118, 2, 18, 66, 17, 67, 12, 12, 0, 1, 118, 2, 108, 32, 12, 0, 1, 118, 2, 110, 116, 101, 114, 0, 1, 118, 2, 110, 116, 114, 101, 0, 1, 118, 2, 115, 32, 103, 114, 97, 100, 0, 1, 118, 2, 115, 104, 0, 1, 118, 2, 115, 107, 12, 0, 1, 118, 2, 115, 110, 101, 0, 1, 118, 2, 115, 115, 0, 1, 118, 2, 115, 116, 32, 105, 107, 107, 101, 0, 1, 118, 18, 72, 2, 115, 116, 12, 0, 1, 118, 32, 101, 107, 115, 110, 97, 103, 2, 115, 116, 32, 0, 1, 118, 97, 106, 2, 115, 116, 0, 1, 118, 101, 103, 2, 110, 115, 116, 0, 1, 118, 104, 2, 108, 107, 12, 0, 1, 118, 111, 106, 2, 115, 116, 0, 1, 118, 115, 2, 18, 74, 17, 67, 0, 1, 119, 116, 2, 115, 116, 0, 2, 107, 107, 101, 0, 2, 109, 112, 0, 2, 109, 112, 111, 0, 2, 110, 99, 0, 2, 110, 100, 0, 2, 110, 102, 97, 110, 116, 0, 2, 110, 110, 0, 2, 110, 110, 101, 0, 2, 110, 115, 0, 8, 2, 110, 12, 0, 8, 102, 2, 107, 32, 0, 8, 108, 2, 100, 116, 32, 0, 8, 109, 2, 115, 116, 32, 0, 8, 110, 2, 18, 75, 0, 8, 114, 100, 2, 108, 0, 8, 116, 2, 103, 32, 12, 0, 8, 116, 2, 110, 0, 8, 116, 2, 115, 107, 101, 32, 0, 8, 118, 2, 102, 116, 32, 0, 8, 118, 2, 115, 116, 32, 0, 100, 1, 118, 2, 115, 116, 0, 100, 8, 109, 2, 116, 0, 1, 118, 2, 115, 116, 110, 111, 107, 3, 36, 4, 0, 107, 97, 100, 101, 108, 108, 101, 1, 114, 102, 3, 36, 49, 110, 72, 6, 109, 55, 108, 0, 107, 97, 100, 101, 108, 108, 101, 114, 1, 114, 102, 3, 36, 49, 110, 72, 6, 109, 55, 114, 0, 4, 110, 100, 1, 102, 2, 101, 108, 195, 184, 110, 3, 36, 50, 0, 110, 100, 2, 101, 108, 115, 101, 12, 0, 110, 117, 112, 1, 112, 3, 36, 50, 6, 114, 48, 0, 110, 103, 111, 1, 98, 3, 36, 50, 81, 39, 0, 110, 115, 105, 100, 101, 8, 2, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 3, 36, 50, 89, 35, 57, 72, 0, 110, 115, 105, 100, 101, 114, 8, 3, 36, 50, 89, 35, 57, 72, 114, 0, 110, 115, 116, 105, 116, 117, 116, 105, 111, 110, 8, 3, 36, 50, 89, 47, 37, 47, 40, 91, 6, 39, 50, 0, 110, 115, 116, 105, 116, 117, 116, 105, 111, 110, 3, 36, 50, 89, 47, 37, 47, 40, 91, 39, 50, 0, 109, 112, 111, 116, 101, 110, 3, 36, 65, 48, 39, 47, 109, 50, 0, 109, 97, 108, 97, 121, 97, 1, 104, 3, 36, 65, 110, 55, 6, 35, 57, 110, 0, 103, 1, 114, 2, 110, 105, 110, 103, 3, 36, 81, 0, 107, 115, 101, 116, 1, 107, 2, 32, 3, 36, 81, 89, 13, 86, 0, 115, 1, 112, 2, 32, 3, 36, 89, 0, 115, 105, 107, 1, 114, 2, 101, 3, 36, 89, 37, 49, 0, 4, 3, 37, 0, 1, 18, 67, 2, 18, 71, 101, 0, 1, 18, 67, 2, 18, 71, 114, 101, 0, 1, 18, 68, 2, 18, 75, 97, 0, 1, 18, 68, 2, 107, 18, 69, 0, 1, 18, 68, 2, 107, 101, 0, 1, 18, 71, 2, 107, 101, 0, 1, 98, 2, 107, 105, 110, 105, 0, 1, 98, 2, 107, 117, 98, 101, 0, 1, 98, 2, 108, 108, 101, 32, 12, 0, 1, 98, 2, 108, 108, 101, 110, 32, 12, 0, 1, 98, 2, 108, 108, 101, 114, 32, 12, 0, 1, 98, 2, 108, 108, 101, 116, 12, 0, 1, 98, 2, 112, 12, 0, 1, 99, 2, 110, 110, 0, 1, 100, 2, 107, 116, 0, 1, 100, 2, 115, 18, 75, 97, 0, 1, 100, 2, 115, 107, 101, 116, 116, 0, 1, 100, 2, 115, 107, 111, 0, 1, 100, 2, 115, 107, 114, 101, 112, 97, 110, 115, 0, 1, 100, 2, 115, 107, 114, 101, 116, 0, 1, 100, 2, 115, 107, 114, 105, 109, 105, 0, 1, 100, 2, 115, 107, 117, 0, 1, 100, 2, 115, 107, 118, 97, 0, 1, 100, 110, 105, 2, 115, 107, 0, 1, 100, 114, 111, 106, 2, 115, 107, 0, 1, 102, 2, 107, 17, 67, 18, 69, 0, 1, 102, 2, 110, 107, 117, 108, 0, 1, 102, 2, 110, 107, 195, 166, 109, 0, 1, 102, 2, 110, 115, 107, 121, 0, 1, 102, 97, 114, 103, 2, 115, 107, 0, 1, 102, 97, 114, 116, 2, 107, 0, 1, 102, 110, 111, 107, 2, 115, 107, 101, 114, 0, 1, 102, 110, 111, 107, 2, 115, 107, 101, 114, 101, 0, 1, 104, 2, 110, 0, 1, 104, 99, 2, 107, 12, 0, 1, 107, 2, 12, 12, 0, 1, 107, 2, 18, 74, 18, 76, 12, 12, 0, 1, 107, 2, 109, 110, 105, 110, 103, 12, 0, 1, 107, 2, 115, 116, 101, 12, 0, 1, 107, 105, 98, 2, 110, 105, 0, 1, 107, 115, 2, 17, 67, 116, 0, 1, 107, 115, 2, 107, 12, 0, 1, 107, 115, 2, 108, 105, 102, 116, 12, 0, 1, 107, 115, 2, 108, 195, 184, 98, 12, 12, 0, 1, 107, 115, 2, 109, 111, 12, 0, 1, 107, 115, 21, 2, 108, 100, 12, 12, 0, 1, 108, 2, 107, 118, 12, 0, 1, 108, 2, 109, 110, 105, 12, 0, 1, 108, 2, 115, 107, 0, 1, 108, 97, 105, 99, 101, 112, 115, 2, 115, 116, 0, 1, 108, 98, 117, 112, 0, 1, 108, 105, 98, 2, 115, 0, 1, 108, 107, 2, 115, 116, 114, 0, 1, 108, 107, 121, 99, 21, 2, 115, 116, 0, 1, 108, 112, 2, 18, 66, 18, 76, 12, 0, 1, 108, 112, 2, 107, 0, 1, 108, 114, 111, 102, 2, 115, 0, 1, 108, 115, 2, 109, 0, 1, 109, 2, 107, 115, 116, 117, 114, 0, 1, 109, 2, 115, 116, 97, 110, 107, 101, 0, 1, 110, 2, 99, 104, 101, 0, 1, 110, 2, 107, 18, 69, 0, 1, 110, 100, 108, 105, 118, 2, 115, 0, 1, 110, 101, 108, 2, 110, 0, 1, 110, 101, 112, 2, 115, 0, 1, 110, 105, 108, 107, 2, 107, 0, 1, 110, 107, 2, 118, 0, 1, 110, 107, 101, 116, 2, 107, 0, 1, 112, 2, 110, 115, 101, 108, 0, 1, 112, 2, 110, 115, 108, 101, 114, 0, 1, 112, 2, 112, 12, 0, 1, 112, 114, 97, 104, 2, 107, 115, 0, 1, 112, 115, 2, 108, 100, 0, 1, 114, 2, 18, 73, 18, 69, 12, 0, 1, 114, 2, 18, 75, 17, 67, 18, 69, 0, 1, 114, 2, 18, 75, 18, 69, 0, 1, 114, 2, 18, 75, 18, 76, 0, 1, 114, 2, 99, 101, 0, 1, 114, 2, 115, 116, 105, 107, 12, 0, 1, 114, 10, 2, 115, 107, 0, 1, 114, 18, 66, 2, 108, 108, 0, 1, 114, 101, 116, 110, 97, 102, 110, 105, 0, 1, 114, 102, 2, 102, 12, 0, 1, 114, 102, 2, 103, 0, 1, 114, 102, 2, 107, 101, 110, 0, 1, 114, 102, 2, 107, 118, 97, 114, 116, 101, 114, 0, 1, 114, 102, 2, 115, 116, 97, 100, 0, 1, 114, 102, 2, 115, 116, 101, 100, 0, 1, 114, 103, 2, 18, 73, 12, 0, 1, 114, 112, 2, 109, 12, 0, 1, 114, 112, 2, 115, 0, 1, 114, 116, 2, 18, 73, 12, 0, 1, 114, 116, 2, 108, 108, 0, 1, 115, 101, 98, 2, 100, 100, 101, 0, 1, 115, 117, 109, 2, 107, 0, 1, 116, 2, 100, 12, 0, 1, 116, 2, 107, 97, 12, 0, 1, 116, 2, 110, 18, 76, 0, 1, 116, 2, 110, 110, 105, 116, 117, 115, 0, 1, 116, 21, 2, 107, 32, 12, 12, 0, 1, 116, 105, 108, 111, 112, 2, 107, 0, 1, 116, 107, 101, 106, 111, 114, 112, 2, 108, 0, 1, 116, 110, 97, 0, 1, 116, 110, 101, 118, 2, 108, 0, 1, 116, 114, 97, 2, 107, 0, 1, 116, 114, 97, 112, 0, 1, 116, 115, 2, 108, 32, 111, 118, 101, 114, 0, 1, 116, 115, 2, 108, 97, 114, 116, 0, 1, 116, 115, 2, 108, 102, 117, 108, 100, 0, 1, 116, 115, 17, 65, 2, 108, 32, 0, 1, 116, 115, 32, 101, 100, 118, 97, 104, 2, 108, 32, 0, 1, 116, 115, 32, 101, 114, 101, 109, 2, 108, 32, 111, 118, 101, 114, 32, 0, 1, 116, 115, 32, 110, 101, 2, 108, 32, 0, 1, 116, 115, 32, 114, 97, 104, 2, 108, 32, 0, 1, 116, 115, 32, 114, 97, 118, 2, 108, 32, 111, 118, 101, 114, 32, 0, 1, 116, 115, 32, 114, 101, 2, 108, 32, 111, 118, 101, 114, 32, 0, 1, 116, 115, 97, 108, 112, 2, 18, 75, 0, 1, 116, 115, 115, 118, 105, 108, 2, 108, 0, 1, 116, 117, 98, 2, 107, 0, 1, 118, 2, 18, 66, 97, 0, 1, 118, 2, 18, 75, 105, 0, 1, 118, 2, 98, 12, 0, 1, 118, 2, 99, 107, 0, 1, 118, 2, 107, 116, 18, 69, 12, 12, 0, 1, 118, 2, 110, 103, 108, 97, 115, 12, 12, 0, 1, 118, 2, 110, 103, 195, 165, 114, 100, 12, 0, 1, 118, 2, 110, 107, 111, 114, 116, 0, 1, 118, 2, 110, 107, 195, 166, 108, 100, 12, 0, 1, 118, 2, 115, 116, 101, 12, 0, 1, 118, 101, 98, 2, 115, 0, 1, 118, 104, 2, 108, 12, 0, 1, 118, 107, 2, 18, 72, 12, 12, 0, 1, 118, 115, 2, 110, 115, 0, 1, 118, 116, 114, 111, 98, 2, 115, 0, 1, 118, 184, 195, 104, 2, 115, 107, 0, 2, 17, 67, 11, 0, 2, 17, 67, 18, 76, 0, 2, 17, 67, 116, 0, 2, 18, 68, 0, 2, 18, 74, 0, 2, 99, 104, 0, 2, 99, 107, 0, 2, 103, 103, 106, 111, 12, 12, 0, 2, 103, 103, 195, 184, 114, 12, 12, 0, 2, 103, 110, 0, 2, 107, 0, 2, 110, 117, 0, 2, 112, 0, 2, 114, 17, 67, 0, 2, 114, 115, 0, 2, 115, 0, 2, 116, 0, 2, 118, 0, 8, 2, 110, 105, 0, 8, 108, 2, 100, 116, 32, 110, 101, 100, 101, 114, 108, 97, 103, 0, 8, 108, 2, 100, 116, 32, 111, 118, 101, 114, 108, 97, 115, 116, 0, 8, 108, 2, 100, 116, 32, 115, 107, 97, 100, 101, 0, 8, 108, 2, 100, 116, 32, 117, 110, 100, 101, 114, 0, 8, 108, 107, 2, 115, 116, 101, 114, 0, 8, 116, 115, 2, 108, 32, 111, 118, 101, 114, 32, 100, 101, 17, 67, 0, 8, 116, 115, 2, 108, 32, 111, 118, 101, 114, 32, 104, 97, 109, 0, 8, 116, 115, 2, 108, 32, 111, 118, 101, 114, 32, 104, 101, 110, 100, 101, 0, 8, 116, 115, 32, 100, 101, 109, 2, 108, 32, 0, 8, 116, 115, 32, 110, 105, 100, 2, 108, 32, 0, 8, 116, 115, 32, 110, 105, 109, 2, 108, 32, 0, 8, 116, 115, 32, 110, 105, 115, 2, 108, 32, 0, 8, 116, 115, 32, 115, 101, 100, 110, 101, 104, 2, 108, 32, 0, 8, 116, 115, 32, 115, 101, 114, 101, 100, 2, 108, 32, 0, 8, 116, 115, 32, 115, 101, 114, 101, 106, 2, 108, 32, 0, 8, 116, 115, 32, 115, 110, 97, 104, 2, 108, 32, 0, 8, 116, 115, 32, 121, 110, 2, 108, 32, 0, 8, 118, 2, 115, 116, 32, 115, 105, 103, 0, 101, 1, 100, 2, 115, 101, 108, 0, 101, 1, 100, 2, 116, 114, 105, 99, 104, 0, 101, 1, 108, 115, 101, 108, 0, 101, 1, 110, 110, 111, 114, 0, 101, 1, 112, 2, 100, 101, 115, 116, 97, 108, 0, 101, 1, 112, 112, 105, 104, 0, 101, 1, 117, 111, 108, 0, 101, 8, 98, 98, 111, 114, 0, 101, 8, 110, 97, 108, 101, 109, 0, 101, 8, 110, 110, 97, 0, 101, 8, 115, 117, 115, 0, 101, 8, 122, 117, 115, 0, 103, 1, 100, 114, 166, 195, 118, 0, 103, 1, 108, 116, 110, 101, 102, 102, 111, 0, 103, 1, 114, 2, 17, 67, 0, 103, 1, 116, 2, 12, 0, 115, 1, 117, 111, 108, 0, 4, 1, 102, 2, 107, 115, 101, 114, 98, 97, 100, 3, 37, 6, 0, 1, 102, 2, 107, 115, 101, 114, 98, 105, 108, 108, 101, 100, 0, 1, 102, 2, 107, 115, 101, 114, 101, 0, 1, 102, 2, 107, 115, 101, 114, 105, 110, 103, 0, 1, 102, 2, 107, 115, 101, 114, 118, 195, 166, 115, 107, 101, 0, 1, 114, 18, 75, 2, 115, 116, 105, 110, 0, 101, 1, 114, 10, 2, 108, 28, 33, 3, 37, 6, 109, 0, 4, 101, 110, 1, 10, 2, 101, 114, 28, 33, 3, 37, 6, 109, 50, 0, 101, 110, 1, 10, 2, 115, 107, 28, 33, 0, 4, 1, 18, 73, 2, 108, 101, 12, 12, 3, 37, 12, 0, 1, 114, 103, 2, 109, 18, 76, 0, 1, 116, 115, 2, 108, 101, 0, 100, 101, 108, 8, 2, 32, 3, 37, 12, 86, 13, 55, 0, 2, 17, 67, 3, 37, 19, 0, 114, 111, 115, 104, 105, 1, 104, 2, 109, 97, 3, 37, 34, 39, 91, 6, 37, 0, 116, 101, 115, 8, 114, 102, 2, 32, 3, 37, 47, 0, 4, 107, 1, 17, 67, 2, 97, 110, 101, 114, 12, 12, 3, 37, 49, 0, 107, 1, 17, 67, 2, 101, 114, 12, 0, 107, 1, 21, 2, 97, 116, 28, 33, 12, 12, 0, 107, 1, 21, 2, 101, 116, 28, 33, 12, 12, 12, 0, 4, 107, 1, 10, 2, 97, 108, 115, 107, 28, 33, 12, 3, 37, 49, 6, 0, 107, 1, 21, 2, 97, 110, 116, 28, 33, 12, 0, 107, 101, 114, 1, 10, 2, 101, 114, 28, 33, 12, 3, 37, 49, 6, 36, 0, 4, 107, 101, 114, 1, 110, 10, 2, 101, 32, 28, 33, 12, 3, 37, 49, 6, 36, 34, 0, 107, 101, 114, 1, 110, 10, 2, 101, 116, 32, 28, 33, 12, 0, 107, 101, 114, 1, 110, 117, 10, 2, 28, 33, 12, 0, 107, 101, 114, 1, 114, 97, 107, 10, 2, 101, 28, 33, 12, 0, 103, 110, 1, 115, 2, 97, 108, 3, 37, 50, 0, 110, 116, 101, 114, 110, 97, 116, 105, 111, 110, 97, 108, 1, 32, 121, 116, 115, 101, 110, 109, 97, 3, 37, 50, 47, 114, 50, 6, 110, 91, 39, 50, 110, 55, 0, 4, 110, 100, 1, 102, 2, 101, 108, 3, 37, 50, 72, 0, 110, 100, 1, 102, 2, 121, 114, 107, 0, 110, 100, 1, 118, 2, 114, 117, 101, 0, 110, 103, 1, 118, 2, 117, 109, 109, 105, 3, 37, 50, 81, 0, 108, 108, 97, 100, 115, 1, 116, 115, 3, 37, 55, 6, 110, 89, 0, 108, 111, 112, 1, 112, 115, 3, 37, 55, 6, 114, 48, 0, 108, 108, 101, 1, 116, 114, 97, 2, 114, 105, 3, 37, 55, 13, 0, 108, 108, 1, 118, 97, 112, 2, 111, 3, 37, 55, 57, 0, 4, 103, 1, 108, 2, 17, 67, 3, 37, 57, 0, 103, 1, 108, 108, 101, 104, 0, 4, 98, 101, 1, 112, 2, 116, 195, 184, 106, 3, 37, 58, 0, 112, 1, 110, 107, 2, 116, 97, 110, 103, 0, 109, 97, 103, 101, 3, 37, 65, 37, 75, 0, 100, 103, 101, 1, 114, 3, 37, 75, 0, 100, 103, 101, 116, 1, 114, 98, 3, 37, 75, 37, 47, 0, 4, 103, 1, 108, 2, 105, 3, 37, 81, 0, 103, 1, 108, 105, 102, 2, 114, 97, 110, 0, 103, 1, 114, 102, 2, 106, 111, 0, 103, 1, 116, 115, 2, 109, 97, 0, 103, 2, 114, 117, 112, 112, 101, 0, 115, 1, 18, 73, 2, 12, 3, 37, 89, 0, 115, 114, 97, 101, 108, 8, 100, 2, 105, 3, 37, 89, 34, 112, 6, 36, 55, 0, 115, 114, 97, 101, 108, 115, 107, 3, 37, 89, 34, 112, 6, 36, 55, 89, 49, 0, 115, 114, 97, 101, 108, 101, 114, 3, 37, 89, 34, 112, 6, 36, 55, 114, 0, 115, 114, 97, 101, 108, 3, 37, 89, 34, 112, 12, 55, 0, 115, 105, 107, 111, 1, 114, 3, 37, 89, 37, 49, 39, 0, 115, 116, 101, 108, 116, 101, 110, 1, 109, 3, 37, 89, 47, 109, 55, 47, 36, 50, 0, 115, 105, 97, 110, 97, 1, 117, 111, 108, 3, 37, 89, 57, 6, 110, 50, 110, 0, 110, 103, 101, 1, 108, 2, 114, 105, 3, 55, 110, 68, 91, 36, 0, 4, 1, 99, 2, 97, 3, 57, 0, 1, 108, 2, 101, 0, 1, 110, 117, 106, 2, 111, 114, 0, 1, 115, 2, 111, 110, 0, 1, 115, 97, 2, 101, 0, 1, 115, 2, 97, 114, 3, 57, 6, 0, 4, 101, 114, 1, 99, 110, 97, 108, 3, 57, 6, 36, 0, 101, 114, 1, 99, 110, 97, 110, 105, 102, 0, 101, 114, 1, 99, 110, 101, 114, 101, 102, 110, 111, 107, 0, 101, 114, 1, 100, 97, 98, 114, 97, 98, 0, 101, 114, 1, 100, 97, 110, 101, 114, 103, 0, 101, 114, 1, 107, 110, 97, 98, 0, 101, 114, 1, 108, 97, 112, 115, 0, 101, 114, 1, 108, 97, 112, 115, 101, 0, 101, 114, 1, 108, 101, 116, 97, 0, 101, 114, 1, 108, 108, 111, 99, 0, 101, 114, 1, 108, 117, 99, 105, 116, 114, 97, 112, 0, 101, 114, 1, 109, 117, 116, 115, 111, 107, 0, 101, 114, 1, 110, 101, 100, 0, 101, 114, 1, 112, 117, 111, 114, 99, 0, 101, 114, 1, 115, 110, 97, 110, 105, 102, 0, 101, 114, 1, 115, 115, 111, 100, 0, 101, 114, 1, 116, 101, 109, 0, 101, 114, 1, 116, 110, 97, 103, 101, 108, 101, 0, 101, 114, 1, 116, 110, 101, 114, 0, 101, 114, 1, 116, 114, 111, 112, 0, 101, 119, 3, 57, 6, 40, 0, 97, 118, 1, 109, 3, 57, 35, 58, 0, 4, 101, 1, 118, 2, 116, 32, 99, 111, 110, 103, 3, 57, 109, 0, 101, 1, 118, 2, 116, 110, 97, 109, 0, 4, 111, 1, 107, 2, 115, 107, 3, 57, 114, 0, 111, 114, 1, 110, 101, 115, 0, 110, 1, 108, 101, 104, 99, 105, 109, 3, 109, 68, 0, 114, 1, 108, 102, 2, 116, 3, 118, 12, 0, 114, 118, 105, 110, 103, 3, 118, 84, 36, 68, 0, 7, 6, 106, 0, 101, 97, 110, 110, 101, 2, 32, 100, 39, 3, 2, 91, 110, 12, 50, 0, 1, 104, 114, 101, 100, 2, 101, 109, 109, 101, 3, 6, 57, 0, 4, 3, 57, 0, 1, 184, 195, 2, 101, 116, 0, 2, 117, 110, 107, 116, 0, 1, 97, 109, 2, 111, 114, 3, 57, 6, 0, 101, 104, 111, 118, 97, 3, 57, 36, 107, 6, 39, 84, 110, 0, 101, 114, 8, 2, 32, 3, 57, 109, 34, 0, 101, 114, 115, 101, 121, 2, 107, 3, 57, 109, 34, 89, 37, 0, 97, 107, 101, 108, 8, 3, 57, 110, 49, 20, 13, 55, 0, 97, 109, 115, 101, 115, 115, 105, 111, 110, 3, 72, 57, 110, 12, 65, 89, 6, 36, 91, 57, 13, 50, 0, 4, 1, 105, 102, 2, 105, 3, 75, 0, 1, 110, 105, 110, 2, 97, 0, 2, 97, 119, 0, 2, 97, 122, 122, 0, 2, 101, 110, 110, 105, 102, 101, 114, 0, 2, 111, 98, 0, 2, 117, 105, 99, 101, 0, 2, 117, 110, 103, 108, 0, 2, 117, 110, 107, 0, 8, 2, 101, 102, 102, 0, 8, 2, 105, 109, 32, 0, 101, 114, 114, 121, 3, 75, 36, 34, 37, 0, 101, 107, 121, 108, 108, 3, 75, 36, 49, 14, 55, 0, 105, 110, 103, 108, 101, 3, 75, 36, 50, 81, 108, 55, 0, 4, 105, 109, 109, 105, 101, 3, 75, 36, 65, 37, 0, 105, 109, 109, 121, 0, 4, 101, 97, 110, 3, 75, 37, 12, 50, 0, 101, 97, 110, 110, 101, 0, 101, 101, 112, 3, 75, 37, 12, 71, 0, 105, 108, 108, 8, 3, 75, 37, 55, 0, 105, 116, 116, 101, 114, 98, 117, 103, 3, 75, 37, 72, 114, 71, 114, 81, 0, 105, 104, 97, 100, 3, 75, 37, 107, 6, 110, 47, 0, 117, 107, 101, 2, 98, 111, 107, 115, 3, 75, 40, 12, 49, 0, 4, 101, 119, 101, 108, 3, 75, 40, 12, 55, 0, 111, 117, 108, 101, 0, 4, 101, 1, 97, 109, 114, 105, 102, 2, 116, 3, 75, 109, 0, 101, 1, 111, 98, 109, 117, 106, 2, 116, 0, 101, 8, 2, 116, 0, 4, 101, 110, 110, 105, 101, 3, 75, 109, 50, 37, 0, 101, 110, 110, 121, 0, 97, 121, 3, 75, 109, 57, 0, 97, 107, 101, 8, 3, 75, 109, 57, 49, 0, 97, 110, 101, 121, 3, 75, 109, 57, 50, 37, 0, 97, 109, 105, 101, 3, 75, 109, 57, 65, 37, 0, 97, 109, 101, 115, 8, 3, 75, 109, 57, 65, 89, 0, 101, 115, 115, 3, 75, 109, 89, 0, 101, 115, 115, 105, 101, 3, 75, 109, 89, 37, 0, 4, 97, 2, 99, 107, 3, 75, 110, 0, 97, 2, 109, 97, 108, 0, 97, 99, 107, 105, 101, 3, 75, 110, 49, 37, 0, 97, 114, 118, 105, 115, 8, 3, 75, 112, 12, 84, 36, 89, 0, 97, 109, 98, 97, 108, 97, 121, 97, 3, 75, 112, 65, 71, 110, 55, 6, 35, 57, 110, 0, 111, 108, 101, 110, 101, 8, 3, 75, 113, 58, 55, 6, 37, 12, 50, 0, 111, 2, 99, 107, 101, 121, 3, 75, 114, 0, 111, 104, 110, 3, 75, 114, 50, 0, 111, 104, 110, 110, 121, 3, 75, 114, 50, 37, 0, 117, 110, 107, 105, 101, 3, 75, 114, 50, 49, 37, 0, 117, 110, 99, 116, 105, 111, 110, 3, 75, 114, 50, 49, 91, 13, 50, 0, 111, 121, 3, 75, 114, 57, 0, 111, 105, 110, 116, 3, 75, 114, 57, 50, 47, 0, 111, 115, 104, 8, 3, 75, 114, 91, 0, 111, 101, 3, 75, 115, 58, 0, 111, 110, 101, 115, 3, 75, 115, 58, 50, 89, 0, 4, 101, 114, 115, 101, 121, 8, 2, 32, 3, 75, 118, 12, 89, 37, 0, 101, 114, 115, 101, 121, 8, 2, 115, 32, 0, 111, 107, 101, 3, 75, 118, 58, 49, 0, 97, 99, 113, 117, 101, 115, 3, 90, 35, 49, 0, 4, 1, 110, 101, 2, 97, 109, 98, 101, 3, 91, 0, 1, 111, 114, 2, 101, 107, 116, 0, 2, 97, 115, 109, 105, 110, 0, 2, 111, 110, 103, 108, 0, 2, 111, 117, 114, 110, 97, 108, 0, 1, 97, 2, 111, 117, 3, 91, 6, 0, 101, 114, 111, 109, 101, 3, 91, 36, 34, 6, 39, 65, 0, 97, 110, 101, 105, 114, 111, 3, 91, 36, 50, 6, 109, 34, 39, 0, 97, 117, 98, 101, 114, 116, 3, 91, 39, 71, 6, 109, 34, 0, 117, 97, 110, 8, 3, 91, 40, 6, 112, 68, 0, 101, 116, 111, 110, 3, 91, 57, 36, 47, 6, 114, 68, 0, 97, 114, 100, 105, 110, 105, 101, 114, 101, 3, 91, 57, 112, 34, 72, 37, 50, 57, 6, 109, 12, 34, 0, 97, 114, 103, 111, 110, 3, 91, 57, 112, 34, 81, 6, 114, 68, 0, 101, 97, 2, 110, 101, 116, 116, 101, 3, 91, 110, 6, 0, 101, 97, 110, 111, 116, 3, 91, 110, 50, 6, 39, 0, 97, 108, 111, 117, 115, 105, 8, 3, 91, 110, 55, 40, 89, 6, 37, 0, 97, 108, 111, 117, 115, 105, 1, 21, 3, 91, 110, 55, 40, 89, 37, 0, 97, 109, 97, 105, 99, 97, 3, 91, 110, 65, 6, 35, 57, 49, 110, 0, 117, 103, 101, 114, 101, 3, 91, 116, 91, 6, 36, 114, 0, 1, 97, 118, 97, 110, 2, 111, 3, 107, 0, 7, 6, 107, 0, 4, 1, 101, 112, 115, 2, 116, 97, 107, 107, 3, 0, 1, 101, 112, 115, 2, 116, 97, 107, 108, 3, 0, 4, 8, 101, 112, 115, 2, 116, 97, 107, 107, 3, 6, 0, 8, 101, 112, 115, 2, 116, 97, 107, 108, 0, 4, 3, 49, 0, 1, 10, 0, 107, 0, 4, 114, 121, 115, 97, 110, 116, 101, 109, 117, 109, 3, 49, 34, 117, 89, 6, 110, 50, 47, 13, 65, 113, 65, 0, 114, 121, 115, 97, 110, 116, 101, 109, 117, 109, 109, 0, 97, 107, 101, 114, 108, 97, 2, 107, 3, 49, 35, 49, 13, 55, 6, 35, 0, 97, 110, 116, 101, 114, 101, 108, 3, 49, 35, 50, 47, 13, 34, 6, 111, 55, 0, 105, 100, 1, 32, 101, 104, 116, 3, 49, 36, 72, 0, 101, 105, 116, 104, 3, 49, 37, 12, 87, 0, 105, 108, 105, 109, 97, 110, 106, 97, 114, 111, 3, 49, 37, 55, 37, 65, 110, 50, 75, 6, 112, 34, 39, 0, 108, 111, 115, 2, 32, 104, 111, 108, 100, 3, 49, 55, 114, 89, 0, 118, 97, 114, 116, 101, 114, 1, 10, 3, 49, 84, 35, 34, 47, 36, 34, 0, 97, 116, 101, 8, 2, 32, 3, 49, 109, 57, 47, 0, 97, 114, 97, 111, 107, 101, 3, 49, 110, 34, 110, 6, 39, 40, 49, 37, 0, 111, 110, 116, 105, 110, 117, 117, 109, 3, 49, 114, 50, 47, 6, 37, 50, 40, 113, 65, 0, 117, 109, 113, 117, 97, 116, 3, 49, 114, 65, 49, 58, 114, 72, 0, 101, 114, 109, 105, 116, 8, 3, 49, 118, 12, 65, 36, 47, 0, 110, 105, 103, 104, 116, 3, 50, 112, 57, 47, 0, 110, 111, 99, 107, 3, 50, 114, 49, 0, 110, 111, 120, 3, 50, 114, 81, 89, 0, 7, 6, 108, 0, 4, 101, 1, 102, 102, 105, 107, 115, 3, 13, 55, 0, 101, 8, 112, 114, 97, 109, 0, 4, 3, 55, 0, 100, 1, 10, 2, 101, 114, 0, 108, 0, 118, 1, 101, 115, 0, 118, 1, 111, 116, 0, 118, 1, 184, 195, 115, 0, 101, 111, 100, 1, 32, 99, 97, 109, 3, 55, 6, 35, 58, 72, 0, 111, 103, 1, 10, 2, 28, 33, 3, 55, 6, 39, 0, 4, 101, 116, 1, 10, 2, 116, 28, 33, 3, 55, 6, 109, 0, 101, 116, 1, 111, 105, 114, 98, 97, 99, 0, 101, 116, 1, 10, 2, 28, 33, 3, 55, 6, 109, 47, 0, 105, 111, 110, 101, 108, 8, 3, 55, 35, 36, 108, 50, 109, 55, 0, 101, 103, 2, 32, 3, 55, 35, 57, 0, 101, 103, 101, 114, 2, 32, 3, 55, 35, 57, 114, 0, 111, 117, 110, 103, 101, 3, 55, 35, 58, 50, 75, 0, 4, 101, 116, 1, 105, 102, 101, 98, 98, 117, 114, 107, 115, 3, 55, 36, 0, 101, 116, 1, 105, 102, 101, 103, 110, 117, 116, 184, 195, 115, 0, 101, 116, 1, 105, 102, 101, 107, 115, 105, 102, 0, 101, 116, 1, 105, 102, 101, 109, 109, 97, 108, 0, 101, 116, 1, 105, 102, 101, 110, 105, 118, 115, 0, 101, 116, 1, 105, 102, 101, 114, 121, 100, 0, 101, 116, 1, 105, 102, 101, 115, 107, 111, 0, 101, 116, 1, 105, 102, 101, 116, 114, 111, 106, 104, 0, 101, 116, 1, 105, 102, 101, 116, 115, 101, 104, 0, 101, 116, 1, 105, 102, 101, 116, 116, 166, 195, 112, 115, 0, 101, 116, 1, 105, 102, 115, 103, 101, 116, 115, 0, 105, 110, 99, 111, 108, 110, 3, 55, 36, 50, 49, 114, 59, 50, 0, 105, 116, 116, 108, 101, 3, 55, 36, 72, 13, 55, 0, 101, 103, 101, 2, 114, 105, 110, 103, 3, 55, 36, 81, 6, 36, 0, 105, 118, 105, 110, 103, 115, 116, 111, 110, 101, 3, 55, 36, 84, 36, 68, 89, 47, 4, 108, 12, 58, 50, 0, 101, 118, 101, 114, 101, 1, 21, 3, 55, 36, 84, 36, 114, 0, 101, 121, 3, 55, 37, 0, 101, 101, 8, 2, 32, 3, 55, 37, 12, 0, 101, 101, 100, 8, 2, 115, 3, 55, 37, 12, 72, 0, 108, 97, 114, 100, 1, 105, 98, 3, 55, 37, 35, 72, 0, 105, 109, 111, 103, 101, 115, 3, 55, 37, 65, 6, 39, 12, 90, 0, 105, 122, 122, 105, 101, 3, 55, 37, 89, 37, 0, 97, 117, 116, 114, 101, 99, 3, 55, 39, 47, 34, 6, 109, 49, 0, 111, 114, 114, 97, 105, 110, 101, 3, 55, 39, 51, 109, 12, 50, 0, 111, 103, 1, 10, 2, 105, 28, 33, 3, 55, 39, 81, 6, 0, 103, 1, 101, 104, 2, 101, 3, 55, 57, 0, 108, 101, 110, 100, 101, 8, 97, 3, 55, 57, 6, 109, 50, 72, 108, 0, 4, 100, 1, 111, 98, 3, 55, 72, 0, 100, 1, 111, 115, 2, 97, 116, 0, 118, 101, 1, 101, 115, 3, 55, 84, 108, 0, 111, 116, 105, 111, 110, 3, 55, 108, 40, 91, 57, 50, 0, 101, 103, 101, 109, 2, 17, 67, 3, 55, 109, 57, 13, 65, 0, 97, 107, 101, 8, 2, 32, 3, 55, 109, 57, 49, 0, 97, 98, 111, 117, 114, 3, 55, 109, 57, 71, 114, 0, 4, 97, 100, 121, 1, 110, 114, 101, 106, 3, 55, 109, 57, 72, 37, 0, 97, 100, 121, 8, 0, 101, 97, 118, 101, 110, 119, 111, 114, 116, 104, 3, 55, 109, 84, 13, 50, 58, 118, 12, 108, 87, 0, 101, 105, 99, 101, 115, 116, 101, 114, 3, 55, 109, 89, 47, 114, 0, 97, 100, 121, 115, 1, 103, 3, 55, 110, 72, 37, 89, 0, 117, 99, 107, 121, 3, 55, 114, 49, 37, 0, 108, 111, 121, 100, 3, 55, 114, 57, 72, 0, 111, 110, 103, 2, 32, 105, 115, 108, 97, 110, 100, 3, 55, 114, 68, 0, 117, 100, 108, 111, 119, 3, 55, 114, 72, 55, 39, 58, 0, 4, 1, 98, 3, 59, 0, 1, 102, 0, 1, 115, 0, 97, 114, 114, 121, 3, 59, 110, 16, 37, 0, 7, 6, 109, 0, 97, 105, 108, 1, 32, 101, 3, 2, 65, 109, 57, 55, 0, 97, 110, 100, 1, 114, 117, 111, 103, 3, 2, 65, 112, 68, 0, 4, 97, 100, 101, 114, 111, 3, 21, 101, 115, 0, 105, 103, 117, 101, 108, 0, 111, 110, 116, 112, 101, 108, 108, 105, 101, 114, 3, 21, 102, 114, 0, 4, 3, 65, 0, 109, 0, 97, 110, 100, 8, 114, 117, 111, 103, 3, 65, 7, 112, 68, 0, 109, 1, 111, 2, 195, 184, 98, 108, 101, 3, 65, 15, 65, 0, 101, 103, 101, 110, 8, 2, 32, 3, 65, 35, 12, 57, 13, 50, 0, 101, 103, 101, 116, 8, 2, 32, 3, 65, 35, 12, 57, 13, 86, 0, 97, 107, 97, 114, 111, 110, 105, 3, 65, 35, 49, 108, 34, 6, 114, 50, 37, 0, 97, 114, 115, 101, 105, 108, 108, 101, 3, 65, 35, 51, 89, 6, 109, 12, 57, 0, 4, 105, 107, 101, 8, 2, 32, 3, 65, 35, 57, 49, 0, 105, 107, 101, 8, 2, 115, 32, 0, 111, 117, 115, 101, 8, 3, 65, 35, 58, 89, 0, 101, 114, 101, 8, 2, 32, 3, 65, 36, 34, 0, 105, 108, 107, 115, 104, 97, 107, 101, 3, 65, 36, 55, 49, 91, 109, 57, 49, 0, 105, 108, 119, 97, 117, 107, 101, 101, 3, 65, 36, 55, 58, 6, 113, 49, 37, 0, 101, 100, 101, 97, 8, 3, 65, 36, 72, 6, 109, 12, 110, 0, 105, 100, 110, 105, 103, 104, 116, 3, 65, 36, 72, 50, 35, 57, 47, 0, 105, 99, 104, 101, 108, 108, 101, 3, 65, 37, 91, 6, 109, 55, 0, 97, 117, 114, 105, 99, 101, 3, 65, 39, 34, 6, 37, 89, 0, 97, 117, 112, 97, 115, 115, 97, 110, 116, 3, 65, 39, 48, 110, 89, 6, 112, 68, 0, 111, 117, 108, 105, 110, 3, 65, 40, 55, 6, 110, 68, 0, 117, 115, 107, 101, 116, 101, 114, 3, 65, 40, 89, 81, 36, 47, 6, 36, 34, 0, 117, 115, 105, 99, 97, 108, 3, 65, 57, 40, 12, 89, 37, 49, 108, 55, 0, 4, 109, 1, 101, 108, 108, 101, 109, 3, 65, 65, 0, 109, 2, 97, 115, 115, 97, 103, 101, 0, 112, 115, 111, 110, 3, 65, 89, 114, 50, 0, 97, 107, 101, 117, 2, 112, 3, 65, 109, 57, 49, 6, 114, 0, 97, 105, 110, 101, 8, 3, 65, 109, 57, 50, 0, 97, 105, 108, 3, 65, 109, 57, 55, 0, 97, 121, 100, 97, 121, 3, 65, 109, 57, 72, 109, 12, 57, 0, 101, 108, 98, 111, 117, 114, 110, 101, 3, 65, 109, 59, 71, 118, 50, 0, 97, 114, 105, 108, 121, 110, 3, 65, 110, 34, 37, 55, 36, 50, 0, 97, 116, 105, 108, 100, 8, 3, 65, 110, 47, 6, 37, 55, 72, 0, 97, 116, 105, 110, 101, 3, 65, 110, 47, 37, 50, 6, 36, 0, 99, 8, 2, 17, 67, 21, 3, 65, 110, 49, 0, 97, 110, 110, 101, 113, 117, 105, 110, 8, 3, 65, 110, 50, 13, 49, 6, 109, 68, 0, 97, 110, 110, 101, 113, 117, 105, 110, 3, 65, 110, 50, 13, 49, 109, 68, 0, 97, 110, 97, 103, 101, 114, 3, 65, 110, 50, 36, 75, 114, 0, 105, 97, 109, 105, 3, 65, 110, 57, 6, 110, 12, 65, 37, 0, 97, 100, 97, 103, 97, 115, 107, 97, 114, 3, 65, 110, 72, 110, 81, 6, 110, 89, 49, 110, 0, 97, 116, 116, 104, 101, 119, 3, 65, 110, 87, 57, 40, 0, 97, 115, 115, 97, 99, 104, 117, 115, 101, 116, 116, 115, 3, 65, 110, 89, 110, 47, 57, 6, 40, 89, 109, 47, 89, 0, 97, 99, 104, 101, 116, 101, 3, 65, 110, 91, 6, 109, 72, 0, 97, 104, 111, 103, 110, 105, 3, 65, 110, 107, 6, 39, 50, 37, 0, 97, 114, 101, 114, 105, 100, 116, 3, 65, 112, 12, 13, 34, 37, 47, 0, 97, 114, 106, 111, 114, 105, 101, 3, 65, 112, 75, 113, 34, 37, 0, 111, 110, 116, 114, 101, 3, 65, 113, 12, 50, 47, 34, 114, 0, 97, 108, 116, 1, 32, 101, 108, 103, 110, 105, 115, 3, 65, 113, 55, 47, 0, 117, 114, 114, 97, 121, 3, 65, 114, 34, 37, 0, 117, 112, 112, 101, 116, 8, 3, 65, 114, 48, 36, 47, 0, 111, 110, 114, 111, 101, 3, 65, 114, 50, 34, 6, 113, 58, 0, 111, 110, 101, 121, 3, 65, 114, 50, 37, 0, 111, 110, 116, 103, 111, 109, 101, 114, 121, 3, 65, 114, 50, 72, 81, 6, 114, 65, 34, 37, 0, 111, 108, 121, 110, 101, 117, 120, 3, 65, 114, 55, 37, 50, 57, 40, 12, 0, 111, 116, 104, 101, 114, 3, 65, 114, 86, 114, 0, 117, 114, 100, 111, 99, 104, 3, 65, 118, 72, 114, 49, 0, 117, 114, 112, 104, 3, 65, 118, 83, 0, 4, 117, 114, 112, 104, 101, 121, 3, 65, 118, 83, 37, 0, 117, 114, 112, 104, 121, 0, 7, 6, 110, 0, 95, 1, 97, 107, 3, 0, 105, 1, 10, 2, 28, 33, 12, 3, 6, 50, 37, 0, 105, 1, 110, 10, 2, 28, 33, 12, 3, 7, 37, 0, 4, 1, 10, 2, 101, 114, 28, 33, 12, 3, 8, 50, 0, 1, 10, 2, 105, 115, 116, 97, 110, 28, 33, 0, 1, 10, 2, 115, 107, 28, 33, 0, 4, 105, 1, 10, 2, 115, 107, 28, 33, 12, 3, 8, 50, 37, 0, 105, 1, 97, 109, 2, 111, 12, 0, 105, 1, 105, 107, 105, 98, 0, 105, 107, 97, 8, 111, 109, 114, 97, 104, 3, 8, 50, 37, 49, 110, 0, 105, 101, 110, 1, 21, 3, 8, 50, 37, 108, 20, 50, 0, 105, 101, 114, 1, 21, 3, 8, 50, 37, 114, 0, 105, 103, 104, 116, 105, 110, 103, 97, 108, 101, 3, 21, 0, 4, 3, 50, 0, 110, 1, 17, 65, 0, 110, 1, 111, 115, 166, 195, 114, 0, 105, 97, 103, 97, 114, 97, 8, 3, 50, 35, 57, 6, 110, 81, 108, 34, 35, 0, 105, 103, 104, 116, 101, 110, 103, 97, 108, 101, 8, 3, 50, 35, 57, 47, 14, 50, 81, 109, 57, 55, 0, 121, 108, 111, 110, 3, 50, 35, 57, 55, 114, 50, 0, 105, 103, 101, 108, 8, 3, 50, 35, 57, 75, 108, 55, 0, 101, 103, 108, 105, 103, 101, 3, 50, 36, 81, 55, 37, 91, 6, 36, 0, 101, 105, 108, 3, 50, 37, 12, 55, 0, 105, 99, 111, 108, 101, 8, 3, 50, 37, 49, 6, 114, 55, 0, 105, 99, 111, 108, 8, 2, 101, 116, 116, 101, 3, 50, 37, 49, 39, 55, 0, 111, 117, 103, 97, 116, 3, 50, 40, 81, 6, 110, 0, 101, 119, 116, 111, 110, 3, 50, 57, 6, 40, 12, 47, 13, 50, 0, 101, 119, 3, 50, 57, 40, 0, 101, 119, 122, 101, 97, 108, 97, 110, 100, 3, 50, 57, 40, 89, 6, 36, 55, 110, 50, 0, 101, 108, 108, 105, 101, 8, 3, 50, 109, 55, 37, 0, 101, 118, 105, 108, 108, 101, 8, 3, 50, 109, 84, 36, 59, 0, 97, 105, 118, 8, 3, 50, 110, 6, 37, 84, 0, 97, 103, 8, 2, 32, 3, 50, 110, 12, 57, 0, 97, 105, 118, 1, 21, 3, 50, 110, 37, 84, 0, 111, 114, 101, 101, 110, 8, 3, 50, 113, 58, 34, 6, 37, 12, 50, 0, 111, 114, 119, 105, 99, 104, 8, 3, 50, 114, 34, 37, 76, 0, 111, 115, 116, 114, 97, 100, 97, 109, 117, 115, 3, 50, 114, 89, 47, 34, 112, 72, 6, 110, 65, 40, 89, 0, 107, 2, 116, 3, 68, 0, 7, 6, 111, 0, 1, 108, 32, 107, 97, 114, 116, 2, 100, 3, 0, 4, 1, 112, 2, 115, 116, 101, 106, 3, 2, 39, 0, 2, 107, 116, 111, 98, 0, 1, 114, 116, 110, 111, 107, 2, 108, 108, 101, 114, 3, 2, 113, 0, 4, 109, 109, 101, 8, 112, 2, 32, 3, 2, 114, 65, 0, 109, 109, 101, 115, 8, 112, 2, 32, 0, 119, 1, 108, 98, 3, 6, 13, 58, 0, 4, 117, 116, 8, 101, 109, 105, 116, 3, 6, 35, 58, 72, 0, 117, 116, 8, 107, 99, 97, 108, 98, 0, 117, 116, 8, 107, 99, 111, 108, 0, 117, 116, 8, 107, 99, 111, 110, 107, 0, 117, 116, 8, 107, 114, 111, 119, 0, 117, 116, 8, 121, 97, 108, 0, 4, 1, 21, 2, 108, 115, 107, 3, 6, 39, 0, 1, 98, 109, 97, 99, 2, 100, 106, 0, 1, 99, 101, 100, 32, 116, 114, 97, 0, 1, 100, 97, 116, 97, 109, 2, 114, 0, 1, 100, 105, 114, 114, 111, 107, 2, 114, 0, 1, 101, 108, 99, 2, 112, 97, 116, 114, 97, 0, 1, 101, 116, 101, 109, 2, 114, 0, 1, 103, 97, 112, 2, 100, 101, 0, 1, 103, 110, 97, 2, 108, 97, 0, 1, 105, 98, 105, 116, 110, 97, 2, 116, 105, 107, 0, 1, 105, 100, 2, 100, 101, 0, 1, 105, 114, 101, 112, 2, 100, 101, 0, 1, 105, 118, 97, 114, 2, 108, 105, 0, 1, 106, 97, 103, 2, 108, 0, 1, 107, 97, 108, 2, 116, 97, 0, 1, 107, 110, 97, 108, 101, 109, 2, 108, 115, 107, 0, 1, 108, 97, 2, 104, 97, 0, 1, 108, 97, 104, 115, 2, 109, 0, 1, 108, 107, 121, 99, 2, 110, 0, 1, 108, 107, 121, 107, 2, 112, 0, 1, 108, 108, 97, 104, 0, 1, 109, 97, 115, 2, 97, 0, 1, 109, 101, 109, 2, 114, 105, 97, 109, 0, 1, 109, 109, 111, 107, 2, 100, 101, 0, 1, 112, 101, 2, 107, 101, 0, 1, 114, 97, 2, 109, 97, 0, 1, 114, 101, 2, 98, 0, 1, 114, 101, 112, 112, 101, 112, 2, 110, 105, 0, 1, 114, 116, 107, 101, 108, 101, 2, 100, 101, 0, 1, 114, 116, 115, 105, 98, 0, 1, 115, 105, 112, 101, 2, 100, 101, 0, 1, 116, 97, 107, 2, 100, 101, 0, 1, 116, 97, 109, 166, 195, 104, 2, 109, 0, 1, 116, 101, 98, 2, 110, 105, 110, 103, 0, 1, 116, 101, 109, 2, 100, 101, 0, 1, 116, 110, 111, 107, 2, 114, 0, 1, 116, 115, 117, 107, 2, 100, 101, 0, 1, 121, 107, 2, 116, 111, 0, 8, 100, 97, 116, 101, 109, 2, 110, 0, 8, 100, 107, 101, 110, 97, 2, 116, 0, 8, 105, 100, 105, 2, 116, 0, 8, 105, 114, 112, 121, 99, 2, 116, 0, 8, 105, 114, 116, 97, 112, 2, 116, 0, 8, 106, 108, 97, 116, 97, 98, 2, 110, 0, 8, 106, 115, 110, 97, 2, 115, 0, 8, 106, 117, 107, 2, 110, 0, 8, 107, 105, 108, 105, 115, 2, 110, 101, 0, 8, 107, 105, 114, 98, 97, 2, 115, 0, 8, 108, 105, 112, 2, 116, 0, 8, 108, 105, 116, 110, 97, 2, 112, 101, 0, 8, 109, 97, 114, 2, 110, 97, 0, 8, 109, 101, 110, 97, 2, 110, 101, 0, 8, 109, 105, 2, 100, 0, 8, 109, 105, 107, 115, 101, 0, 8, 109, 114, 111, 109, 2, 110, 0, 8, 109, 166, 195, 100, 2, 110, 0, 8, 110, 97, 107, 2, 110, 0, 8, 110, 103, 105, 115, 2, 114, 0, 8, 110, 111, 107, 184, 195, 2, 109, 32, 0, 8, 112, 101, 100, 2, 116, 0, 8, 114, 101, 2, 116, 0, 8, 114, 101, 99, 105, 99, 2, 110, 101, 0, 8, 114, 101, 112, 97, 104, 99, 2, 110, 101, 0, 8, 114, 116, 97, 109, 2, 110, 101, 0, 8, 114, 116, 97, 109, 2, 115, 0, 8, 114, 117, 101, 2, 112, 97, 0, 8, 115, 111, 108, 105, 102, 2, 102, 105, 115, 107, 0, 8, 116, 101, 99, 97, 2, 110, 101, 0, 8, 116, 111, 105, 98, 2, 112, 0, 8, 116, 111, 115, 105, 2, 112, 0, 8, 122, 97, 109, 97, 2, 110, 101, 0, 8, 122, 108, 97, 99, 2, 110, 101, 0, 108, 1, 114, 116, 10, 2, 108, 108, 101, 28, 33, 0, 116, 1, 100, 114, 97, 98, 0, 116, 1, 107, 105, 114, 116, 0, 116, 1, 108, 114, 101, 109, 0, 1, 116, 105, 108, 2, 116, 101, 3, 6, 39, 12, 0, 102, 101, 1, 114, 116, 115, 97, 116, 97, 107, 3, 6, 39, 12, 83, 108, 0, 115, 101, 1, 10, 2, 28, 33, 12, 3, 6, 39, 12, 89, 13, 0, 115, 101, 43, 1, 10, 2, 114, 28, 33, 3, 6, 39, 12, 89, 114, 0, 116, 105, 1, 107, 114, 97, 110, 2, 107, 3, 6, 39, 47, 37, 0, 112, 1, 107, 115, 10, 2, 28, 33, 12, 12, 3, 6, 39, 48, 0, 110, 100, 1, 107, 101, 115, 2, 108, 195, 184, 106, 116, 110, 97, 110, 116, 3, 6, 39, 50, 72, 0, 4, 108, 1, 10, 2, 28, 33, 12, 12, 3, 6, 39, 55, 0, 108, 1, 104, 10, 2, 105, 28, 33, 12, 0, 108, 1, 114, 116, 10, 2, 101, 28, 33, 0, 108, 1, 115, 10, 2, 18, 69, 28, 33, 12, 0, 108, 1, 116, 110, 10, 2, 28, 33, 12, 0, 108, 1, 116, 115, 10, 2, 12, 28, 33, 0, 109, 1, 21, 2, 28, 33, 12, 12, 12, 3, 6, 39, 65, 0, 4, 111, 1, 122, 97, 107, 3, 6, 40, 0, 117, 1, 108, 101, 118, 2, 114, 0, 117, 116, 1, 103, 97, 114, 0, 4, 111, 1, 122, 97, 98, 3, 6, 40, 12, 0, 117, 1, 115, 115, 105, 109, 2, 114, 105, 0, 117, 105, 108, 108, 101, 1, 116, 97, 116, 97, 114, 3, 6, 40, 12, 57, 0, 117, 110, 1, 104, 108, 97, 99, 3, 6, 40, 50, 0, 105, 114, 101, 1, 116, 114, 101, 112, 101, 114, 3, 6, 58, 112, 12, 0, 110, 100, 1, 98, 97, 103, 97, 118, 3, 6, 113, 50, 72, 0, 4, 1, 98, 111, 114, 2, 116, 12, 12, 3, 6, 114, 0, 1, 100, 97, 114, 97, 112, 2, 107, 115, 0, 1, 100, 97, 114, 98, 97, 108, 2, 114, 0, 1, 100, 111, 116, 114, 111, 2, 107, 115, 0, 1, 102, 101, 100, 2, 114, 109, 0, 1, 102, 101, 114, 2, 114, 109, 0, 1, 102, 105, 110, 117, 2, 114, 109, 0, 1, 102, 110, 111, 107, 2, 114, 109, 0, 1, 102, 111, 114, 111, 108, 107, 2, 114, 109, 0, 1, 104, 99, 97, 107, 2, 116, 0, 1, 104, 110, 114, 111, 98, 2, 108, 109, 0, 1, 107, 115, 105, 116, 114, 97, 2, 107, 0, 1, 108, 97, 103, 2, 17, 67, 0, 1, 108, 97, 107, 2, 116, 0, 1, 108, 117, 2, 118, 0, 1, 109, 97, 2, 107, 0, 1, 110, 98, 97, 2, 114, 109, 0, 1, 110, 101, 2, 114, 109, 12, 0, 1, 110, 111, 109, 2, 107, 0, 1, 112, 97, 2, 108, 108, 111, 12, 12, 0, 1, 112, 109, 111, 107, 2, 115, 116, 0, 1, 114, 111, 116, 2, 110, 116, 111, 0, 1, 114, 116, 115, 101, 114, 101, 112, 2, 106, 107, 97, 0, 1, 115, 111, 108, 105, 102, 2, 102, 32, 0, 8, 107, 115, 97, 109, 2, 116, 0, 8, 107, 117, 104, 2, 109, 109, 101, 0, 8, 108, 111, 107, 2, 115, 0, 8, 112, 115, 101, 114, 2, 110, 115, 0, 8, 115, 105, 114, 111, 104, 2, 110, 0, 8, 116, 114, 97, 107, 2, 102, 0, 8, 118, 101, 114, 2, 108, 118, 0, 108, 1, 114, 116, 10, 2, 108, 101, 110, 28, 33, 0, 112, 116, 101, 114, 1, 107, 105, 108, 101, 104, 3, 6, 114, 48, 47, 114, 0, 103, 1, 107, 110, 105, 2, 110, 105, 116, 111, 3, 6, 114, 49, 0, 110, 100, 1, 107, 111, 112, 121, 104, 2, 101, 114, 3, 6, 114, 50, 72, 0, 4, 108, 1, 104, 10, 2, 28, 33, 12, 3, 6, 114, 55, 0, 108, 1, 107, 111, 10, 2, 28, 33, 12, 0, 108, 1, 114, 116, 10, 2, 28, 33, 12, 0, 108, 1, 115, 10, 2, 28, 33, 12, 0, 108, 1, 116, 10, 2, 28, 33, 12, 0, 108, 100, 101, 1, 115, 105, 3, 6, 114, 55, 72, 108, 0, 4, 106, 1, 118, 110, 111, 107, 3, 6, 114, 57, 0, 121, 2, 12, 0, 105, 97, 8, 110, 97, 114, 97, 112, 3, 6, 114, 57, 110, 0, 4, 103, 110, 101, 1, 99, 115, 97, 103, 3, 6, 114, 68, 57, 108, 0, 103, 110, 101, 1, 116, 115, 97, 98, 0, 114, 101, 114, 1, 115, 3, 7, 39, 12, 114, 0, 8, 2, 109, 17, 67, 3, 7, 114, 0, 103, 110, 1, 108, 117, 111, 98, 2, 101, 3, 7, 114, 68, 57, 0, 1, 114, 116, 107, 101, 108, 101, 3, 8, 39, 0, 114, 1, 115, 3, 8, 114, 0, 98, 108, 105, 103, 101, 1, 32, 101, 115, 115, 101, 108, 98, 111, 110, 3, 21, 102, 114, 0, 1, 100, 2, 119, 110, 105, 110, 103, 3, 35, 0, 117, 110, 3, 35, 40, 50, 0, 117, 116, 104, 1, 115, 3, 35, 40, 87, 0, 117, 116, 108, 97, 119, 3, 35, 58, 47, 55, 113, 12, 0, 4, 117, 116, 8, 100, 110, 97, 104, 3, 35, 58, 72, 0, 117, 116, 8, 110, 111, 114, 116, 115, 97, 0, 117, 116, 8, 112, 111, 114, 100, 0, 117, 116, 115, 105, 100, 101, 114, 3, 35, 58, 72, 89, 35, 57, 72, 114, 0, 4, 3, 39, 0, 1, 17, 67, 2, 18, 66, 97, 12, 0, 1, 17, 67, 2, 18, 68, 11, 97, 0, 1, 17, 67, 2, 18, 71, 18, 69, 12, 12, 0, 1, 17, 67, 2, 103, 12, 0, 1, 17, 67, 2, 107, 18, 69, 12, 0, 1, 17, 67, 2, 109, 18, 76, 0, 1, 17, 67, 102, 2, 116, 18, 69, 0, 1, 18, 66, 2, 109, 18, 69, 0, 1, 18, 66, 2, 109, 101, 0, 1, 18, 66, 2, 109, 109, 97, 110, 12, 0, 1, 18, 68, 2, 18, 74, 18, 69, 0, 1, 18, 68, 2, 18, 74, 18, 76, 0, 1, 18, 71, 2, 116, 18, 76, 0, 1, 18, 73, 2, 108, 12, 0, 1, 18, 73, 2, 116, 18, 69, 0, 1, 18, 74, 2, 100, 12, 0, 1, 18, 75, 2, 18, 71, 114, 18, 76, 0, 1, 97, 109, 2, 12, 0, 1, 98, 2, 100, 0, 1, 98, 2, 103, 111, 114, 109, 0, 1, 98, 2, 109, 0, 1, 98, 2, 109, 109, 12, 12, 0, 1, 98, 2, 112, 195, 166, 108, 0, 1, 98, 97, 110, 2, 12, 0, 1, 98, 109, 117, 106, 0, 1, 98, 109, 121, 115, 2, 108, 0, 1, 100, 2, 18, 66, 114, 18, 69, 0, 1, 100, 101, 112, 114, 111, 116, 0, 1, 101, 100, 105, 118, 0, 1, 102, 2, 98, 0, 1, 102, 2, 100, 12, 0, 1, 102, 2, 114, 18, 69, 12, 0, 1, 103, 2, 100, 12, 0, 1, 103, 2, 115, 108, 97, 118, 0, 1, 103, 97, 100, 2, 103, 0, 1, 104, 2, 18, 74, 18, 69, 12, 0, 1, 104, 2, 98, 12, 0, 1, 104, 2, 115, 112, 105, 116, 0, 1, 104, 2, 115, 116, 12, 0, 1, 104, 2, 118, 101, 114, 101, 0, 1, 104, 99, 2, 107, 111, 12, 0, 1, 105, 100, 97, 114, 0, 1, 106, 2, 100, 12, 0, 1, 106, 103, 2, 114, 116, 0, 1, 106, 107, 2, 114, 116, 0, 1, 106, 115, 2, 102, 0, 1, 107, 2, 17, 67, 11, 18, 69, 12, 12, 0, 1, 107, 2, 100, 12, 0, 1, 107, 2, 100, 101, 12, 0, 1, 107, 2, 107, 97, 0, 1, 107, 2, 108, 108, 101, 103, 12, 12, 12, 0, 1, 107, 2, 108, 108, 101, 107, 116, 32, 0, 1, 107, 2, 109, 109, 101, 110, 116, 17, 65, 12, 12, 12, 0, 1, 107, 2, 109, 109, 101, 114, 99, 105, 101, 108, 12, 12, 0, 1, 107, 2, 109, 112, 97, 103, 0, 1, 107, 2, 110, 116, 111, 114, 0, 1, 107, 2, 115, 107, 111, 0, 1, 107, 2, 115, 116, 18, 69, 0, 1, 107, 2, 115, 116, 32, 0, 1, 107, 2, 115, 116, 101, 115, 107, 97, 98, 0, 1, 107, 2, 115, 116, 101, 115, 107, 97, 102, 116, 0, 1, 107, 110, 97, 98, 2, 115, 112, 0, 1, 107, 111, 107, 2, 115, 0, 1, 107, 114, 97, 110, 0, 1, 107, 114, 97, 110, 2, 17, 67, 0, 1, 107, 115, 2, 115, 118, 195, 166, 114, 116, 101, 0, 1, 107, 115, 97, 107, 0, 1, 107, 115, 105, 100, 0, 1, 107, 115, 111, 114, 107, 105, 109, 2, 112, 0, 1, 108, 2, 18, 68, 12, 0, 1, 108, 2, 18, 74, 17, 67, 18, 69, 0, 1, 108, 2, 107, 17, 65, 0, 1, 108, 2, 107, 117, 109, 0, 1, 108, 97, 103, 2, 112, 112, 101, 114, 101, 0, 1, 108, 101, 109, 21, 2, 110, 0, 1, 108, 105, 107, 0, 1, 108, 105, 112, 2, 116, 0, 1, 108, 107, 2, 110, 0, 1, 108, 111, 107, 2, 115, 115, 97, 0, 1, 108, 111, 107, 2, 115, 116, 0, 1, 108, 112, 2, 109, 12, 0, 1, 108, 115, 2, 103, 0, 1, 109, 2, 115, 107, 101, 0, 1, 109, 2, 115, 115, 101, 116, 12, 12, 0, 1, 109, 101, 2, 12, 0, 1, 109, 114, 101, 116, 0, 1, 110, 2, 109, 105, 0, 1, 110, 17, 67, 2, 18, 71, 12, 12, 0, 1, 110, 97, 107, 2, 110, 0, 1, 110, 103, 2, 109, 0, 1, 110, 103, 111, 107, 101, 114, 2, 115, 99, 101, 114, 101, 0, 1, 110, 107, 2, 106, 0, 1, 110, 111, 2, 109, 0, 1, 112, 2, 107, 101, 114, 12, 12, 0, 1, 112, 2, 108, 0, 1, 112, 2, 108, 32, 0, 1, 112, 2, 108, 115, 107, 0, 1, 112, 2, 115, 116, 116, 114, 97, 117, 0, 1, 112, 101, 100, 2, 116, 0, 1, 114, 2, 18, 71, 18, 70, 12, 0, 1, 114, 2, 100, 12, 0, 1, 114, 2, 107, 18, 76, 12, 0, 1, 114, 2, 109, 17, 67, 18, 70, 0, 1, 114, 2, 115, 116, 12, 0, 1, 114, 17, 67, 2, 109, 18, 69, 0, 1, 114, 17, 67, 2, 115, 107, 0, 1, 114, 18, 71, 2, 106, 0, 1, 114, 18, 73, 2, 18, 66, 101, 110, 0, 1, 114, 18, 73, 2, 116, 18, 69, 0, 1, 114, 98, 2, 100, 101, 114, 0, 1, 114, 98, 2, 115, 116, 101, 110, 0, 1, 114, 100, 110, 121, 115, 2, 109, 0, 1, 114, 100, 121, 104, 0, 1, 114, 101, 116, 101, 104, 0, 1, 114, 102, 2, 109, 97, 0, 1, 114, 102, 2, 115, 115, 12, 12, 0, 1, 114, 103, 2, 115, 115, 105, 12, 0, 1, 114, 107, 2, 109, 0, 1, 114, 107, 2, 115, 0, 1, 114, 107, 2, 118, 195, 166, 0, 1, 114, 107, 105, 109, 0, 1, 114, 112, 2, 98, 108, 101, 0, 1, 114, 112, 2, 115, 12, 0, 1, 114, 112, 2, 115, 116, 105, 0, 1, 114, 112, 2, 118, 17, 65, 12, 0, 1, 114, 116, 2, 17, 67, 18, 69, 0, 1, 114, 116, 2, 106, 97, 110, 0, 1, 114, 116, 2, 109, 0, 1, 114, 116, 2, 109, 109, 101, 12, 0, 1, 114, 116, 2, 115, 98, 101, 107, 101, 110, 100, 0, 1, 114, 116, 2, 115, 114, 101, 116, 110, 105, 110, 103, 0, 1, 114, 116, 2, 115, 115, 97, 103, 0, 1, 114, 116, 2, 115, 115, 107, 105, 102, 116, 12, 0, 1, 114, 116, 2, 118, 12, 0, 1, 114, 116, 101, 109, 0, 1, 114, 116, 110, 111, 107, 2, 108, 108, 195, 184, 114, 0, 1, 115, 2, 108, 12, 0, 1, 115, 2, 108, 108, 121, 115, 12, 12, 0, 1, 115, 2, 112, 114, 97, 0, 1, 116, 2, 116, 17, 65, 0, 1, 116, 97, 2, 109, 0, 1, 116, 101, 98, 2, 110, 101, 116, 0, 1, 116, 110, 111, 107, 0, 1, 116, 115, 2, 100, 32, 0, 1, 116, 115, 2, 109, 18, 69, 0, 1, 116, 115, 101, 116, 2, 115, 116, 101, 114, 111, 110, 0, 1, 116, 115, 105, 114, 97, 2, 107, 0, 1, 116, 117, 97, 2, 12, 0, 1, 118, 2, 107, 18, 76, 12, 0, 1, 122, 105, 107, 115, 2, 102, 114, 101, 110, 0, 2, 18, 66, 18, 69, 0, 2, 18, 71, 18, 69, 12, 0, 2, 18, 71, 18, 76, 12, 0, 2, 98, 108, 18, 69, 0, 2, 98, 108, 97, 12, 0, 2, 107, 97, 17, 67, 0, 2, 108, 115, 101, 110, 0, 2, 112, 112, 111, 115, 105, 116, 0, 2, 115, 107, 111, 12, 0, 2, 115, 116, 105, 110, 100, 105, 0, 2, 118, 101, 106, 12, 0, 2, 118, 105, 12, 0, 8, 17, 67, 2, 32, 0, 8, 107, 2, 100, 12, 0, 8, 116, 115, 2, 114, 32, 0, 100, 1, 103, 2, 115, 0, 111, 1, 112, 109, 97, 104, 115, 0, 4, 1, 101, 108, 2, 112, 97, 114, 3, 39, 6, 0, 1, 115, 2, 109, 97, 108, 0, 8, 107, 2, 109, 112, 97, 115, 0, 8, 114, 107, 2, 107, 101, 116, 116, 0, 8, 115, 111, 108, 105, 102, 2, 102, 105, 32, 0, 8, 116, 2, 98, 97, 107, 0, 105, 114, 101, 1, 109, 101, 109, 3, 39, 6, 112, 12, 0, 4, 1, 107, 2, 109, 97, 3, 39, 12, 0, 1, 108, 2, 116, 117, 115, 0, 1, 109, 115, 2, 107, 105, 110, 103, 0, 2, 115, 18, 76, 0, 101, 1, 17, 67, 2, 100, 101, 0, 111, 1, 122, 0, 4, 103, 101, 100, 1, 102, 3, 39, 12, 13, 86, 0, 118, 101, 100, 1, 104, 0, 4, 101, 1, 107, 115, 2, 100, 101, 3, 39, 13, 0, 101, 1, 114, 116, 101, 98, 2, 100, 101, 0, 4, 114, 1, 107, 2, 107, 195, 165, 98, 101, 3, 39, 34, 0, 114, 1, 107, 2, 112, 105, 0, 114, 1, 107, 2, 112, 114, 195, 184, 118, 101, 0, 114, 1, 116, 115, 2, 12, 0, 118, 1, 108, 2, 101, 12, 3, 39, 40, 0, 39, 8, 3, 39, 40, 6, 0, 108, 108, 8, 114, 2, 105, 110, 103, 32, 115, 116, 111, 110, 101, 3, 39, 40, 55, 0, 4, 97, 109, 101, 115, 1, 115, 3, 39, 40, 65, 89, 0, 108, 109, 101, 115, 8, 104, 2, 32, 0, 104, 105, 111, 3, 39, 40, 107, 6, 35, 57, 39, 0, 116, 116, 101, 1, 114, 102, 2, 12, 12, 3, 39, 47, 6, 36, 0, 112, 1, 107, 115, 10, 2, 105, 28, 33, 3, 39, 48, 6, 0, 112, 111, 115, 1, 114, 112, 97, 3, 39, 48, 6, 39, 0, 107, 111, 1, 103, 110, 105, 110, 101, 109, 2, 107, 3, 39, 49, 6, 114, 0, 107, 111, 110, 1, 107, 3, 39, 49, 6, 114, 68, 0, 107, 108, 97, 104, 111, 109, 97, 3, 39, 49, 55, 110, 107, 6, 39, 65, 110, 0, 114, 1, 114, 2, 103, 3, 39, 51, 0, 108, 1, 100, 105, 21, 3, 39, 55, 0, 108, 105, 101, 116, 1, 103, 110, 111, 109, 3, 39, 55, 6, 37, 13, 86, 0, 4, 103, 1, 108, 107, 3, 39, 58, 0, 103, 1, 114, 112, 115, 0, 103, 1, 116, 2, 116, 117, 114, 0, 103, 8, 118, 2, 32, 0, 118, 1, 108, 2, 32, 109, 105, 103, 32, 0, 103, 101, 1, 108, 107, 3, 39, 58, 4, 13, 0, 103, 1, 104, 2, 97, 110, 3, 39, 58, 81, 0, 109, 1, 107, 114, 97, 115, 3, 39, 65, 0, 4, 109, 109, 101, 1, 110, 101, 114, 2, 12, 3, 39, 65, 6, 36, 0, 109, 109, 195, 169, 1, 110, 101, 114, 2, 12, 0, 109, 101, 116, 1, 107, 3, 39, 65, 6, 36, 47, 0, 109, 109, 101, 114, 115, 1, 107, 2, 32, 3, 39, 65, 6, 109, 34, 89, 0, 109, 97, 110, 8, 3, 39, 65, 6, 110, 50, 0, 103, 110, 101, 115, 101, 1, 108, 111, 98, 3, 39, 68, 6, 109, 89, 108, 0, 98, 111, 8, 3, 39, 71, 6, 39, 0, 114, 103, 1, 101, 103, 2, 105, 110, 101, 3, 39, 81, 0, 103, 101, 1, 116, 111, 102, 2, 110, 3, 39, 81, 6, 36, 0, 103, 110, 1, 114, 112, 2, 111, 3, 39, 81, 50, 0, 112, 104, 105, 97, 1, 115, 3, 39, 83, 6, 37, 110, 0, 4, 118, 1, 107, 2, 101, 110, 100, 3, 39, 84, 0, 118, 1, 107, 117, 118, 2, 97, 114, 0, 118, 1, 110, 2, 97, 12, 12, 0, 118, 1, 110, 2, 101, 108, 108, 0, 118, 1, 110, 2, 101, 109, 12, 0, 118, 1, 110, 2, 105, 99, 17, 65, 0, 118, 1, 110, 101, 114, 2, 101, 114, 0, 118, 1, 114, 116, 110, 111, 107, 2, 101, 114, 115, 0, 118, 1, 116, 2, 195, 184, 114, 0, 118, 1, 116, 97, 2, 101, 114, 0, 118, 2, 195, 166, 114, 110, 12, 0, 118, 1, 108, 115, 2, 97, 107, 3, 39, 84, 6, 0, 118, 105, 8, 114, 112, 2, 110, 115, 3, 39, 84, 6, 36, 0, 4, 100, 1, 103, 2, 116, 17, 65, 103, 3, 39, 86, 0, 100, 1, 103, 2, 116, 114, 0, 100, 1, 108, 98, 0, 115, 1, 114, 116, 2, 115, 97, 109, 102, 117, 110, 100, 3, 39, 89, 0, 115, 104, 1, 107, 2, 101, 114, 12, 3, 39, 91, 0, 115, 104, 1, 104, 115, 2, 111, 110, 101, 3, 39, 91, 6, 0, 105, 1, 116, 2, 108, 3, 39, 110, 0, 111, 114, 1, 107, 2, 100, 3, 39, 114, 12, 19, 0, 111, 118, 110, 1, 114, 107, 105, 109, 3, 39, 114, 58, 50, 0, 4, 111, 1, 119, 3, 40, 0, 117, 0, 117, 1, 108, 0, 4, 111, 3, 40, 12, 0, 111, 1, 122, 2, 109, 0, 4, 111, 100, 1, 102, 3, 40, 12, 72, 0, 111, 100, 1, 104, 0, 117, 99, 104, 101, 1, 100, 3, 40, 12, 91, 0, 111, 107, 101, 1, 114, 98, 3, 40, 49, 0, 111, 110, 97, 103, 104, 3, 40, 50, 110, 0, 4, 111, 103, 105, 101, 1, 98, 3, 40, 81, 37, 0, 111, 103, 105, 101, 1, 119, 0, 103, 110, 1, 108, 111, 99, 2, 101, 3, 55, 6, 114, 68, 57, 0, 105, 120, 1, 114, 99, 3, 58, 6, 35, 0, 105, 115, 1, 110, 97, 100, 3, 58, 6, 112, 0, 105, 110, 116, 1, 112, 2, 32, 3, 58, 109, 68, 0, 105, 110, 116, 101, 110, 101, 1, 112, 3, 58, 109, 68, 13, 50, 108, 0, 105, 110, 116, 101, 1, 112, 3, 58, 109, 68, 47, 13, 0, 105, 110, 116, 101, 114, 1, 112, 3, 58, 109, 68, 47, 114, 0, 119, 1, 116, 2, 101, 114, 3, 112, 40, 0, 117, 1, 114, 103, 2, 99, 104, 111, 3, 112, 58, 0, 117, 115, 101, 1, 104, 3, 112, 58, 89, 0, 4, 1, 107, 2, 98, 98, 101, 114, 3, 113, 0, 1, 112, 2, 114, 0, 1, 112, 2, 115, 116, 109, 111, 100, 0, 1, 114, 17, 67, 2, 18, 66, 18, 69, 0, 1, 118, 115, 2, 103, 101, 114, 0, 4, 97, 114, 1, 98, 2, 100, 105, 110, 103, 3, 113, 12, 0, 114, 2, 108, 0, 117, 114, 110, 101, 1, 98, 3, 113, 12, 50, 0, 114, 103, 2, 101, 108, 3, 113, 12, 58, 0, 121, 101, 114, 8, 102, 3, 113, 13, 57, 6, 36, 0, 121, 101, 114, 101, 110, 8, 102, 3, 113, 13, 57, 6, 36, 108, 50, 0, 121, 101, 114, 1, 102, 3, 113, 13, 57, 36, 0, 114, 108, 121, 8, 2, 32, 3, 113, 16, 55, 6, 37, 0, 1, 104, 2, 108, 100, 105, 110, 103, 3, 113, 40, 0, 118, 2, 101, 114, 104, 101, 97, 100, 3, 113, 40, 84, 0, 97, 115, 116, 98, 101, 101, 102, 1, 114, 3, 113, 40, 89, 72, 71, 37, 83, 0, 116, 105, 111, 110, 1, 109, 119, 111, 108, 115, 3, 113, 40, 91, 20, 13, 50, 0, 4, 1, 103, 2, 107, 97, 114, 116, 12, 3, 113, 58, 0, 117, 1, 115, 2, 108, 0, 112, 114, 97, 104, 3, 113, 58, 48, 34, 35, 0, 4, 108, 101, 1, 112, 109, 105, 119, 3, 113, 58, 55, 0, 108, 108, 8, 114, 2, 32, 12, 0, 108, 108, 115, 8, 114, 2, 32, 3, 113, 58, 55, 89, 0, 4, 118, 1, 108, 2, 101, 110, 12, 12, 3, 113, 84, 0, 118, 1, 118, 2, 101, 0, 4, 1, 17, 67, 2, 17, 67, 11, 101, 116, 32, 12, 12, 3, 114, 0, 1, 17, 67, 2, 18, 66, 12, 0, 1, 17, 67, 2, 18, 66, 116, 0, 1, 17, 67, 2, 18, 68, 11, 0, 1, 17, 67, 2, 18, 74, 110, 0, 1, 17, 67, 2, 98, 98, 101, 114, 32, 12, 12, 0, 1, 17, 67, 2, 103, 103, 12, 0, 1, 17, 67, 2, 109, 0, 1, 17, 67, 2, 109, 18, 69, 0, 1, 17, 67, 2, 114, 114, 0, 1, 17, 67, 2, 115, 17, 67, 18, 76, 12, 0, 1, 17, 67, 102, 2, 116, 0, 1, 18, 66, 2, 108, 100, 0, 1, 18, 66, 2, 109, 0, 1, 18, 67, 2, 18, 71, 11, 101, 12, 12, 0, 1, 18, 67, 2, 18, 71, 108, 101, 12, 0, 1, 18, 67, 2, 115, 116, 0, 1, 18, 68, 2, 18, 74, 0, 1, 18, 71, 2, 116, 0, 1, 18, 73, 2, 102, 0, 1, 18, 73, 2, 108, 17, 67, 12, 0, 1, 18, 73, 2, 116, 0, 1, 18, 73, 2, 116, 116, 0, 1, 18, 75, 2, 110, 17, 67, 0, 1, 97, 17, 67, 2, 115, 0, 1, 98, 2, 18, 66, 18, 69, 0, 1, 98, 2, 115, 115, 0, 1, 99, 2, 99, 107, 0, 1, 99, 2, 114, 115, 0, 1, 100, 2, 103, 32, 12, 0, 1, 100, 2, 110, 97, 108, 100, 0, 1, 102, 2, 110, 116, 0, 1, 103, 2, 100, 116, 12, 0, 1, 104, 2, 99, 107, 12, 0, 1, 104, 2, 102, 0, 1, 104, 2, 108, 108, 12, 0, 1, 104, 2, 110, 103, 0, 1, 104, 2, 115, 112, 105, 99, 101, 0, 1, 104, 99, 2, 107, 12, 0, 1, 104, 116, 2, 109, 97, 115, 32, 0, 1, 106, 2, 18, 66, 11, 18, 76, 0, 1, 106, 2, 98, 21, 0, 1, 106, 2, 114, 116, 0, 1, 107, 2, 98, 108, 105, 110, 103, 0, 1, 107, 2, 103, 108, 12, 0, 1, 107, 2, 103, 116, 12, 0, 1, 107, 2, 110, 17, 67, 0, 1, 107, 2, 112, 97, 114, 0, 1, 107, 2, 115, 116, 32, 111, 103, 32, 108, 111, 103, 105, 0, 1, 107, 2, 115, 116, 98, 97, 114, 0, 1, 107, 2, 115, 116, 112, 108, 97, 110, 0, 1, 107, 2, 115, 116, 112, 114, 105, 115, 0, 1, 107, 2, 115, 116, 114, 195, 165, 100, 0, 1, 107, 2, 115, 116, 115, 107, 111, 108, 101, 0, 1, 107, 2, 115, 116, 116, 105, 108, 115, 107, 117, 100, 0, 1, 107, 2, 115, 116, 118, 97, 110, 101, 0, 1, 107, 32, 112, 97, 114, 107, 115, 2, 115, 116, 0, 1, 107, 101, 98, 2, 115, 116, 0, 1, 107, 101, 115, 108, 101, 104, 2, 115, 116, 0, 1, 107, 111, 114, 102, 2, 115, 116, 0, 1, 107, 115, 2, 100, 0, 1, 107, 115, 100, 101, 104, 100, 110, 117, 115, 2, 115, 116, 0, 1, 107, 115, 103, 97, 100, 114, 101, 118, 104, 2, 115, 116, 0, 1, 107, 121, 111, 98, 2, 116, 0, 1, 108, 2, 18, 66, 11, 18, 76, 0, 1, 108, 2, 100, 116, 114, 195, 166, 107, 0, 1, 108, 2, 103, 102, 105, 108, 0, 1, 108, 2, 116, 0, 1, 108, 18, 71, 2, 18, 74, 0, 1, 108, 32, 101, 107, 107, 166, 195, 114, 116, 2, 100, 0, 1, 108, 32, 107, 166, 195, 114, 116, 2, 100, 0, 1, 108, 32, 114, 101, 107, 107, 166, 195, 114, 116, 2, 100, 0, 1, 108, 32, 115, 101, 107, 107, 166, 195, 114, 116, 2, 100, 0, 1, 108, 32, 116, 101, 107, 107, 117, 114, 116, 2, 100, 0, 1, 108, 98, 2, 107, 12, 0, 1, 108, 100, 114, 111, 106, 2, 100, 0, 1, 108, 102, 2, 115, 0, 1, 108, 107, 2, 115, 116, 114, 101, 0, 1, 108, 108, 97, 102, 2, 115, 0, 1, 108, 114, 111, 102, 2, 100, 115, 0, 1, 109, 2, 110, 105, 116, 111, 114, 0, 1, 110, 2, 110, 17, 67, 0, 1, 110, 2, 115, 32, 0, 1, 110, 107, 2, 116, 110, 0, 1, 110, 107, 2, 116, 116, 0, 1, 110, 115, 2, 116, 0, 1, 112, 2, 108, 116, 0, 1, 112, 2, 112, 105, 100, 111, 108, 12, 12, 0, 1, 112, 107, 99, 97, 106, 2, 116, 0, 1, 112, 115, 2, 110, 115, 111, 114, 0, 1, 114, 2, 17, 67, 11, 12, 12, 0, 1, 114, 2, 99, 107, 0, 1, 114, 2, 109, 107, 97, 103, 101, 0, 1, 114, 18, 73, 2, 18, 66, 0, 1, 114, 18, 73, 2, 116, 0, 1, 114, 98, 2, 100, 12, 0, 1, 114, 100, 2, 115, 99, 104, 101, 0, 1, 114, 100, 32, 116, 101, 2, 103, 0, 1, 114, 102, 2, 109, 0, 1, 114, 102, 2, 110, 116, 0, 1, 114, 102, 2, 115, 116, 12, 0, 1, 114, 107, 2, 107, 101, 116, 17, 67, 0, 1, 114, 108, 97, 118, 104, 2, 115, 0, 1, 114, 112, 2, 102, 32, 0, 1, 114, 116, 2, 106, 12, 0, 1, 114, 116, 2, 107, 108, 0, 1, 114, 116, 2, 108, 100, 0, 1, 114, 116, 2, 116, 115, 0, 1, 114, 116, 110, 111, 107, 2, 108, 0, 1, 114, 116, 120, 111, 102, 2, 116, 0, 1, 115, 2, 106, 97, 12, 0, 1, 115, 21, 2, 110, 32, 0, 1, 115, 21, 2, 110, 115, 32, 0, 1, 116, 2, 103, 116, 12, 0, 1, 116, 2, 108, 107, 0, 1, 116, 2, 109, 97, 115, 32, 0, 1, 116, 2, 116, 0, 1, 116, 115, 2, 112, 12, 12, 0, 1, 118, 2, 103, 0, 1, 118, 2, 103, 116, 12, 0, 1, 118, 108, 101, 115, 2, 112, 0, 2, 18, 68, 25, 12, 0, 2, 18, 71, 12, 0, 2, 98, 98, 17, 65, 12, 12, 12, 0, 2, 99, 104, 101, 0, 2, 102, 17, 67, 0, 2, 107, 0, 2, 108, 100, 32, 0, 2, 108, 100, 101, 0, 2, 108, 100, 101, 32, 0, 2, 109, 32, 0, 2, 109, 97, 100, 114, 101, 115, 115, 101, 0, 2, 109, 101, 103, 110, 0, 2, 109, 107, 0, 2, 109, 114, 195, 165, 100, 0, 2, 109, 115, 0, 2, 109, 116, 97, 108, 101, 0, 2, 112, 97, 100, 12, 0, 2, 112, 101, 102, 116, 101, 114, 12, 0, 2, 112, 105, 108, 100, 110, 101, 12, 0, 2, 112, 111, 102, 114, 101, 0, 2, 112, 111, 102, 114, 101, 12, 0, 2, 114, 103, 97, 12, 0, 2, 115, 17, 67, 18, 69, 0, 2, 116, 116, 97, 119, 97, 0, 2, 116, 116, 101, 110, 100, 101, 0, 2, 116, 116, 111, 0, 2, 120, 0, 8, 2, 108, 105, 118, 101, 114, 0, 8, 2, 109, 97, 114, 0, 8, 98, 2, 110, 100, 32, 0, 8, 98, 2, 110, 110, 32, 0, 8, 100, 2, 110, 32, 0, 8, 104, 2, 108, 105, 100, 97, 121, 0, 8, 104, 2, 116, 32, 0, 8, 108, 2, 103, 32, 0, 8, 108, 2, 115, 0, 8, 109, 2, 114, 116, 0, 8, 112, 2, 116, 32, 0, 8, 114, 2, 98, 105, 110, 12, 12, 0, 100, 1, 108, 107, 2, 115, 0, 100, 1, 114, 116, 2, 115, 0, 103, 1, 107, 101, 114, 2, 110, 111, 115, 99, 101, 114, 101, 0, 103, 2, 102, 105, 114, 115, 0, 103, 2, 116, 114, 101, 100, 105, 118, 101, 0, 114, 1, 110, 111, 100, 0, 114, 1, 112, 2, 99, 0, 114, 1, 116, 2, 32, 0, 114, 1, 116, 2, 101, 110, 0, 114, 1, 116, 2, 110, 121, 0, 114, 1, 116, 2, 115, 0, 114, 1, 116, 111, 109, 0, 114, 1, 116, 115, 97, 112, 0, 117, 114, 1, 98, 114, 97, 104, 0, 1, 112, 2, 115, 116, 121, 114, 12, 3, 114, 6, 0, 4, 111, 114, 1, 108, 102, 3, 114, 12, 0, 111, 114, 101, 1, 109, 0, 114, 1, 107, 2, 112, 0, 114, 1, 116, 2, 116, 3, 114, 12, 19, 0, 105, 108, 8, 2, 32, 3, 114, 12, 37, 59, 0, 105, 115, 1, 110, 105, 108, 108, 105, 3, 114, 12, 57, 0, 114, 103, 2, 12, 3, 114, 12, 58, 0, 4, 103, 1, 100, 108, 108, 117, 98, 3, 114, 12, 81, 0, 114, 103, 2, 105, 0, 114, 115, 1, 107, 3, 114, 12, 89, 0, 4, 114, 1, 114, 114, 101, 116, 3, 114, 34, 0, 114, 2, 107, 12, 12, 0, 114, 101, 103, 111, 110, 112, 105, 110, 101, 3, 114, 34, 36, 81, 114, 50, 15, 48, 35, 57, 50, 0, 4, 103, 1, 110, 107, 3, 114, 40, 0, 118, 2, 101, 12, 0, 118, 2, 114, 101, 0, 116, 101, 108, 101, 1, 107, 2, 116, 3, 114, 47, 13, 55, 6, 109, 0, 116, 100, 111, 103, 1, 104, 3, 114, 47, 72, 114, 81, 0, 4, 99, 99, 1, 114, 98, 2, 111, 108, 105, 3, 114, 49, 0, 103, 104, 1, 103, 32, 110, 97, 118, 0, 110, 110, 121, 1, 115, 3, 114, 50, 37, 0, 110, 116, 97, 110, 97, 1, 109, 3, 114, 50, 47, 6, 110, 50, 110, 0, 110, 100, 1, 108, 98, 3, 114, 50, 72, 0, 110, 100, 111, 110, 1, 108, 3, 114, 50, 72, 114, 50, 0, 110, 103, 1, 107, 2, 114, 101, 115, 3, 114, 50, 81, 0, 110, 111, 1, 100, 2, 118, 97, 110, 3, 114, 50, 108, 0, 108, 105, 115, 104, 1, 112, 3, 114, 55, 37, 91, 0, 108, 103, 116, 1, 115, 3, 114, 55, 47, 0, 108, 108, 97, 114, 1, 100, 3, 114, 55, 114, 0, 105, 1, 110, 97, 104, 3, 114, 57, 0, 4, 105, 110, 116, 1, 112, 2, 101, 114, 101, 3, 114, 57, 50, 47, 0, 105, 110, 116, 1, 112, 32, 116, 115, 101, 119, 0, 121, 99, 101, 1, 114, 3, 114, 57, 89, 0, 121, 101, 117, 114, 1, 118, 3, 114, 57, 118, 12, 34, 0, 4, 118, 1, 17, 67, 2, 12, 3, 114, 58, 0, 118, 1, 108, 112, 2, 12, 12, 0, 118, 2, 101, 114, 115, 12, 12, 0, 118, 2, 110, 0, 103, 114, 101, 1, 108, 3, 114, 58, 34, 114, 0, 103, 110, 1, 17, 67, 3, 114, 58, 50, 0, 118, 106, 101, 116, 1, 115, 3, 114, 58, 57, 6, 109, 47, 0, 109, 107, 111, 2, 115, 116, 3, 114, 65, 49, 114, 0, 109, 98, 97, 121, 1, 98, 3, 114, 65, 71, 4, 109, 57, 0, 109, 101, 98, 97, 99, 107, 1, 99, 3, 114, 65, 71, 6, 110, 49, 0, 4, 110, 1, 108, 108, 97, 98, 3, 114, 68, 0, 110, 1, 110, 110, 97, 2, 99, 17, 65, 0, 110, 1, 112, 109, 97, 116, 0, 110, 1, 112, 109, 111, 112, 0, 110, 1, 112, 117, 107, 0, 110, 1, 116, 101, 98, 0, 103, 110, 97, 99, 1, 99, 3, 114, 68, 35, 49, 0, 98, 121, 8, 114, 2, 110, 12, 12, 3, 114, 71, 36, 0, 4, 100, 1, 118, 2, 107, 97, 3, 114, 72, 0, 111, 100, 1, 108, 98, 0, 111, 100, 1, 108, 102, 0, 100, 121, 1, 98, 3, 114, 72, 37, 0, 100, 121, 98, 117, 105, 108, 100, 101, 114, 1, 98, 3, 114, 72, 37, 71, 37, 55, 72, 114, 0, 100, 108, 101, 1, 106, 3, 114, 72, 55, 108, 0, 100, 102, 97, 116, 104, 101, 114, 1, 103, 3, 114, 72, 83, 112, 86, 114, 0, 4, 1, 108, 2, 103, 98, 111, 103, 3, 114, 81, 0, 103, 1, 107, 2, 110, 105, 116, 0, 103, 1, 108, 98, 0, 103, 1, 109, 115, 2, 32, 0, 103, 1, 114, 103, 0, 103, 103, 1, 114, 103, 0, 114, 103, 2, 105, 101, 0, 117, 103, 1, 100, 0, 103, 103, 121, 1, 114, 103, 3, 114, 81, 37, 0, 120, 102, 111, 114, 100, 3, 114, 81, 89, 83, 114, 12, 72, 0, 117, 103, 104, 3, 114, 83, 0, 102, 102, 115, 105, 100, 101, 3, 114, 83, 89, 6, 35, 57, 72, 0, 116, 104, 1, 114, 98, 2, 101, 114, 3, 114, 86, 0, 100, 114, 101, 116, 1, 108, 2, 12, 3, 114, 86, 34, 111, 47, 0, 4, 114, 115, 101, 116, 1, 107, 32, 116, 101, 3, 114, 89, 6, 109, 47, 0, 114, 115, 101, 116, 116, 1, 107, 0, 115, 107, 118, 97, 1, 109, 3, 114, 89, 49, 84, 6, 110, 0, 115, 99, 97, 114, 3, 114, 89, 49, 112, 0, 115, 99, 111, 101, 1, 114, 3, 114, 89, 49, 113, 58, 0, 115, 98, 111, 114, 110, 101, 3, 114, 89, 71, 4, 113, 50, 0, 8, 114, 98, 2, 100, 121, 3, 115, 58, 0, 117, 114, 98, 111, 110, 1, 98, 3, 118, 12, 71, 13, 50, 0, 97, 107, 108, 97, 110, 100, 3, 118, 58, 49, 55, 13, 50, 72, 0, 101, 98, 98, 101, 108, 115, 1, 103, 3, 118, 71, 13, 55, 89, 0, 7, 6, 112, 0, 4, 1, 109, 121, 115, 2, 116, 111, 109, 3, 0, 2, 115, 121, 107, 3, 0, 4, 3, 48, 0, 1, 10, 2, 32, 0, 112, 0, 117, 114, 118, 105, 115, 8, 3, 48, 6, 108, 12, 84, 36, 89, 0, 195, 165, 8, 2, 115, 107, 101, 3, 48, 6, 113, 0, 195, 165, 8, 2, 14, 128, 132, 130, 3, 48, 6, 114, 0, 4, 114, 111, 116, 101, 103, 101, 3, 48, 34, 39, 72, 13, 91, 6, 36, 0, 114, 111, 116, 101, 103, 195, 169, 0, 114, 101, 115, 98, 121, 116, 101, 114, 105, 97, 110, 3, 48, 34, 109, 89, 71, 116, 47, 109, 34, 37, 6, 110, 50, 0, 105, 110, 99, 101, 110, 101, 122, 3, 48, 35, 12, 68, 89, 50, 6, 36, 0, 105, 112, 101, 108, 105, 110, 101, 3, 48, 35, 57, 48, 55, 35, 57, 50, 0, 195, 169, 116, 97, 105, 110, 8, 3, 48, 36, 47, 6, 110, 68, 0, 101, 110, 101, 108, 111, 112, 101, 3, 48, 36, 50, 6, 109, 55, 39, 48, 37, 0, 105, 116, 99, 104, 112, 105, 110, 101, 3, 48, 36, 87, 91, 48, 35, 12, 57, 50, 0, 105, 115, 115, 111, 105, 114, 3, 48, 36, 89, 58, 6, 112, 12, 0, 101, 116, 101, 8, 2, 32, 3, 48, 37, 12, 47, 0, 101, 116, 101, 121, 8, 3, 48, 37, 12, 47, 37, 0, 101, 97, 110, 117, 116, 3, 48, 37, 12, 50, 114, 72, 0, 101, 97, 99, 101, 3, 48, 37, 12, 89, 0, 105, 99, 107, 117, 2, 112, 3, 48, 37, 49, 6, 114, 0, 105, 103, 103, 121, 8, 3, 48, 37, 81, 37, 0, 112, 1, 111, 116, 2, 111, 115, 116, 3, 48, 48, 0, 114, 97, 108, 105, 110, 101, 3, 48, 51, 112, 55, 37, 50, 6, 36, 0, 105, 101, 114, 114, 101, 3, 48, 57, 109, 12, 34, 0, 105, 97, 102, 8, 3, 48, 57, 112, 83, 0, 111, 105, 114, 111, 116, 8, 3, 48, 58, 112, 34, 6, 39, 0, 111, 105, 116, 105, 101, 114, 8, 3, 48, 58, 112, 47, 57, 6, 36, 0, 97, 105, 103, 101, 3, 48, 109, 12, 57, 75, 0, 101, 105, 103, 110, 111, 105, 114, 3, 48, 109, 50, 57, 58, 6, 112, 12, 0, 97, 105, 110, 116, 98, 97, 108, 108, 3, 48, 109, 57, 50, 47, 71, 113, 12, 55, 0, 97, 105, 108, 108, 101, 2, 116, 3, 48, 110, 57, 6, 109, 0, 97, 115, 97, 100, 101, 110, 97, 3, 48, 110, 89, 110, 72, 6, 37, 50, 110, 0, 97, 115, 115, 97, 103, 101, 114, 8, 3, 48, 110, 89, 110, 89, 57, 6, 36, 34, 0, 97, 108, 109, 2, 32, 98, 101, 97, 99, 104, 3, 48, 112, 12, 65, 0, 97, 114, 102, 97, 105, 116, 3, 48, 112, 83, 6, 109, 0, 111, 115, 116, 104, 117, 109, 3, 48, 113, 89, 47, 107, 6, 40, 65, 0, 4, 195, 165, 2, 102, 117, 110, 100, 3, 48, 114, 0, 195, 165, 2, 108, 195, 166, 103, 0, 195, 165, 2, 118, 105, 114, 107, 0, 195, 165, 8, 2, 108, 105, 100, 101, 0, 195, 165, 8, 2, 118, 105, 115, 0, 111, 110, 121, 3, 48, 114, 50, 37, 0, 117, 110, 99, 104, 108, 105, 110, 101, 3, 48, 114, 50, 91, 55, 35, 57, 50, 0, 101, 97, 114, 108, 8, 2, 32, 3, 48, 118, 12, 55, 0, 101, 114, 116, 104, 3, 48, 118, 12, 87, 0, 101, 114, 107, 105, 110, 115, 3, 48, 118, 49, 36, 50, 89, 0, 101, 114, 99, 121, 3, 48, 118, 89, 37, 0, 101, 117, 103, 101, 111, 116, 3, 48, 118, 91, 6, 39, 0, 98, 1, 109, 97, 99, 2, 101, 108, 3, 71, 0, 4, 104, 1, 101, 115, 111, 106, 3, 83, 0, 104, 1, 108, 97, 114, 0, 104, 97, 101, 108, 1, 97, 114, 3, 83, 110, 6, 109, 55, 0, 115, 101, 117, 3, 89, 118, 58, 0, 7, 6, 113, 0, 117, 1, 101, 116, 2, 105, 108, 97, 3, 6, 49, 0, 117, 101, 1, 21, 3, 8, 49, 0, 3, 49, 0, 117, 101, 116, 1, 117, 111, 98, 3, 49, 7, 36, 0, 117, 105, 99, 104, 101, 3, 49, 37, 91, 0, 4, 117, 105, 106, 111, 116, 101, 3, 49, 37, 91, 6, 114, 47, 0, 117, 105, 120, 111, 116, 101, 0, 117, 101, 101, 110, 3, 49, 58, 37, 12, 50, 0, 117, 97, 114, 116, 101, 114, 3, 49, 58, 113, 47, 114, 0, 117, 2, 105, 115, 108, 105, 110, 103, 3, 49, 84, 0, 117, 105, 2, 122, 3, 49, 84, 37, 0, 117, 101, 98, 101, 99, 3, 49, 84, 37, 71, 6, 109, 49, 0, 117, 101, 122, 3, 49, 109, 12, 89, 0, 7, 6, 114, 0, 4, 1, 101, 2, 101, 32, 24, 3, 0, 4, 1, 111, 112, 115, 110, 97, 114, 116, 2, 116, 3, 0, 4, 1, 166, 195, 2, 101, 114, 32, 24, 3, 0, 100, 1, 165, 195, 104, 3, 0, 105, 1, 10, 2, 115, 107, 28, 33, 3, 8, 51, 37, 0, 100, 1, 165, 195, 104, 2, 101, 3, 12, 0, 97, 109, 105, 114, 101, 122, 3, 21, 101, 115, 0, 4, 1, 98, 3, 34, 0, 1, 101, 104, 2, 32, 0, 1, 101, 115, 2, 32, 0, 1, 101, 118, 104, 0, 2, 25, 0, 4, 101, 1, 97, 105, 100, 3, 34, 6, 36, 0, 101, 1, 114, 97, 105, 100, 0, 101, 110, 111, 105, 114, 3, 34, 13, 50, 58, 6, 112, 12, 0, 101, 118, 111, 105, 114, 1, 32, 117, 97, 3, 34, 13, 58, 6, 35, 12, 34, 0, 105, 99, 107, 115, 104, 97, 119, 3, 34, 36, 49, 91, 114, 12, 0, 105, 99, 107, 115, 104, 97, 119, 101, 114, 3, 34, 36, 49, 91, 114, 12, 114, 0, 101, 103, 1, 166, 195, 115, 2, 101, 110, 3, 34, 36, 57, 0, 101, 115, 101, 114, 118, 111, 105, 114, 8, 3, 34, 36, 89, 109, 34, 84, 39, 6, 35, 12, 0, 101, 115, 101, 114, 118, 111, 105, 114, 3, 34, 36, 89, 109, 34, 84, 39, 35, 12, 0, 4, 101, 97, 108, 105, 116, 121, 3, 34, 37, 6, 110, 55, 37, 47, 37, 0, 101, 97, 108, 105, 116, 121, 1, 32, 108, 97, 117, 116, 114, 105, 118, 0, 105, 111, 106, 97, 3, 34, 37, 6, 114, 49, 110, 0, 101, 101, 99, 101, 3, 34, 37, 12, 89, 0, 101, 99, 117, 116, 3, 34, 37, 49, 114, 72, 0, 101, 115, 101, 97, 114, 99, 104, 3, 34, 37, 89, 6, 118, 12, 76, 0, 105, 99, 104, 101, 108, 105, 101, 117, 3, 34, 37, 91, 55, 57, 6, 118, 0, 111, 117, 103, 101, 3, 34, 40, 12, 91, 0, 4, 100, 1, 97, 103, 2, 101, 3, 34, 72, 0, 100, 1, 97, 115, 2, 101, 108, 0, 100, 1, 101, 118, 2, 101, 25, 25, 0, 100, 1, 111, 2, 101, 108, 12, 12, 0, 100, 1, 111, 2, 101, 110, 12, 12, 0, 100, 1, 117, 98, 2, 101, 25, 0, 100, 1, 121, 2, 101, 32, 0, 97, 106, 97, 104, 3, 34, 112, 75, 110, 0, 4, 101, 1, 21, 2, 32, 3, 34, 114, 0, 101, 1, 103, 2, 32, 0, 101, 1, 118, 97, 104, 0, 111, 113, 117, 101, 102, 111, 114, 116, 3, 34, 114, 49, 83, 6, 114, 12, 0, 111, 98, 105, 101, 8, 3, 34, 114, 71, 37, 0, 111, 100, 110, 101, 121, 3, 34, 114, 72, 50, 37, 0, 111, 103, 101, 114, 3, 34, 114, 75, 114, 0, 117, 115, 115, 101, 108, 108, 3, 34, 114, 89, 14, 55, 0, 117, 115, 104, 109, 111, 114, 101, 3, 34, 114, 91, 65, 113, 12, 0, 111, 97, 100, 8, 2, 32, 3, 34, 118, 58, 72, 0, 4, 3, 51, 0, 114, 0, 105, 103, 104, 116, 3, 51, 6, 35, 57, 47, 0, 101, 8, 116, 110, 101, 2, 32, 3, 51, 6, 36, 0, 105, 1, 10, 2, 28, 33, 3, 51, 7, 37, 0, 105, 99, 104, 105, 101, 3, 51, 37, 76, 37, 0, 101, 103, 103, 97, 101, 3, 51, 109, 81, 109, 57, 0, 101, 97, 103, 97, 110, 3, 51, 109, 81, 110, 50, 0, 101, 115, 111, 108, 117, 116, 105, 111, 110, 3, 51, 109, 89, 39, 55, 40, 91, 6, 39, 50, 0, 117, 110, 1, 32, 101, 109, 111, 104, 3, 51, 114, 50, 0, 104, 101, 117, 2, 109, 97, 3, 51, 114, 57, 0, 117, 103, 98, 121, 3, 51, 114, 81, 71, 37, 0, 104, 111, 100, 101, 8, 3, 51, 118, 58, 72, 0, 100, 1, 111, 2, 114, 105, 110, 3, 72, 0, 4, 101, 1, 101, 100, 2, 115, 3, 114, 0, 101, 1, 101, 106, 2, 115, 0, 101, 1, 166, 195, 2, 32, 24, 0, 101, 1, 166, 195, 108, 0, 7, 6, 115, 0, 1, 105, 109, 109, 111, 107, 2, 101, 3, 0, 4, 1, 101, 99, 99, 117, 115, 3, 6, 0, 1, 105, 109, 111, 114, 112, 109, 111, 107, 0, 97, 99, 101, 1, 108, 97, 3, 6, 89, 110, 89, 0, 1, 105, 109, 109, 111, 107, 2, 32, 3, 8, 0, 4, 99, 1, 97, 98, 97, 116, 2, 111, 3, 8, 89, 49, 0, 99, 1, 105, 115, 110, 97, 114, 102, 2, 111, 0, 111, 109, 1, 21, 21, 3, 8, 89, 114, 65, 0, 105, 101, 103, 102, 114, 105, 101, 100, 3, 21, 100, 101, 0, 97, 105, 110, 116, 101, 3, 21, 102, 114, 0, 105, 103, 110, 111, 114, 101, 3, 21, 105, 116, 0, 4, 3, 89, 0, 1, 10, 2, 32, 28, 33, 14, 128, 128, 129, 0, 1, 101, 99, 98, 97, 0, 1, 101, 99, 101, 114, 0, 1, 101, 99, 120, 101, 0, 1, 101, 100, 101, 108, 114, 101, 100, 110, 97, 0, 1, 110, 101, 100, 105, 115, 101, 114, 0, 1, 110, 101, 114, 101, 102, 114, 101, 116, 110, 105, 0, 1, 110, 101, 116, 115, 105, 115, 107, 101, 0, 1, 121, 107, 0, 2, 17, 65, 0, 2, 99, 105, 103, 97, 114, 0, 2, 105, 101, 0, 2, 106, 0, 2, 111, 109, 107, 111, 115, 116, 12, 0, 2, 115, 104, 0, 99, 2, 101, 0, 115, 0, 99, 1, 105, 100, 2, 105, 112, 3, 89, 6, 0, 99, 101, 110, 101, 1, 105, 2, 115, 3, 89, 6, 36, 50, 13, 0, 111, 109, 1, 111, 109, 111, 114, 107, 3, 89, 6, 39, 65, 0, 97, 105, 110, 116, 3, 89, 6, 109, 57, 50, 72, 0, 4, 105, 103, 1, 32, 97, 114, 102, 2, 32, 3, 89, 35, 57, 0, 105, 103, 1, 32, 100, 101, 114, 2, 32, 0, 105, 103, 1, 32, 100, 111, 108, 2, 32, 0, 105, 103, 1, 32, 100, 184, 195, 98, 2, 32, 0, 105, 103, 1, 32, 100, 184, 195, 107, 115, 2, 32, 0, 105, 103, 1, 32, 100, 184, 195, 114, 98, 2, 32, 0, 105, 103, 1, 32, 101, 2, 32, 12, 0, 105, 103, 1, 32, 101, 2, 32, 116, 105, 108, 0, 105, 103, 1, 32, 101, 100, 2, 32, 0, 105, 103, 1, 32, 101, 100, 110, 101, 118, 2, 32, 0, 105, 103, 1, 32, 101, 103, 103, 121, 104, 2, 32, 0, 105, 103, 1, 32, 101, 108, 184, 195, 102, 2, 32, 0, 105, 103, 1, 32, 101, 114, 166, 195, 108, 107, 114, 101, 2, 32, 0, 105, 103, 1, 32, 101, 114, 184, 195, 103, 2, 32, 100, 101, 116, 0, 105, 103, 1, 32, 103, 101, 110, 115, 2, 32, 0, 105, 103, 1, 32, 103, 110, 97, 118, 116, 2, 32, 0, 105, 103, 1, 32, 103, 111, 108, 115, 2, 32, 0, 105, 103, 1, 32, 103, 111, 116, 2, 32, 0, 105, 103, 1, 32, 107, 97, 2, 32, 0, 105, 103, 1, 32, 107, 105, 103, 2, 32, 0, 105, 103, 1, 32, 107, 108, 111, 102, 32, 114, 101, 2, 32, 0, 105, 103, 1, 32, 108, 105, 116, 2, 32, 0, 105, 103, 1, 32, 109, 111, 107, 2, 32, 0, 105, 103, 1, 32, 110, 17, 65, 2, 32, 116, 105, 108, 0, 105, 103, 1, 32, 110, 97, 104, 2, 32, 0, 105, 103, 1, 32, 110, 97, 109, 2, 32, 0, 105, 103, 1, 32, 110, 101, 100, 2, 32, 0, 105, 103, 1, 32, 110, 117, 104, 2, 32, 0, 105, 103, 1, 32, 111, 114, 116, 101, 98, 2, 32, 0, 105, 103, 1, 32, 114, 101, 2, 32, 0, 105, 103, 1, 32, 114, 101, 2, 32, 116, 105, 108, 0, 105, 103, 1, 32, 114, 101, 115, 2, 32, 111, 109, 0, 105, 103, 1, 32, 114, 111, 102, 2, 32, 0, 105, 103, 1, 32, 114, 111, 114, 116, 101, 98, 2, 32, 0, 105, 103, 1, 32, 114, 165, 195, 2, 32, 0, 105, 103, 1, 32, 114, 165, 195, 108, 115, 2, 32, 0, 105, 103, 1, 32, 114, 184, 195, 2, 32, 0, 105, 103, 1, 32, 116, 2, 32, 0, 105, 103, 1, 32, 116, 97, 115, 2, 32, 0, 105, 103, 1, 32, 116, 101, 2, 32, 0, 105, 103, 1, 32, 116, 101, 2, 32, 116, 105, 108, 0, 105, 103, 1, 32, 118, 97, 103, 2, 32, 0, 105, 103, 1, 32, 118, 97, 103, 2, 32, 116, 105, 108, 0, 105, 103, 1, 32, 165, 195, 108, 115, 2, 32, 0, 105, 103, 1, 32, 165, 195, 112, 2, 32, 0, 105, 103, 1, 32, 165, 195, 115, 2, 32, 111, 109, 0, 105, 103, 1, 32, 165, 195, 116, 115, 2, 32, 0, 105, 103, 8, 2, 32, 97, 102, 32, 0, 105, 103, 8, 2, 32, 97, 108, 101, 110, 101, 0, 105, 103, 8, 2, 32, 102, 111, 114, 0, 105, 103, 8, 2, 32, 105, 32, 100, 101, 17, 67, 0, 105, 103, 8, 2, 32, 105, 110, 100, 32, 0, 105, 103, 8, 2, 32, 109, 101, 100, 0, 105, 103, 8, 2, 32, 111, 109, 0, 105, 103, 8, 2, 32, 111, 118, 101, 114, 0, 105, 103, 8, 2, 32, 112, 195, 165, 32, 0, 105, 103, 8, 2, 32, 115, 101, 108, 118, 0, 105, 103, 8, 2, 32, 117, 100, 32, 0, 105, 103, 8, 32, 101, 100, 2, 32, 116, 105, 108, 0, 105, 103, 8, 32, 102, 97, 2, 32, 0, 105, 103, 8, 32, 105, 2, 32, 0, 105, 103, 8, 32, 110, 97, 104, 2, 32, 0, 105, 103, 104, 116, 115, 101, 101, 105, 110, 103, 3, 89, 35, 57, 47, 89, 37, 12, 36, 68, 0, 99, 101, 110, 101, 3, 89, 36, 50, 108, 0, 99, 101, 110, 101, 114, 3, 89, 36, 50, 114, 0, 4, 105, 103, 1, 32, 101, 114, 97, 98, 2, 32, 3, 89, 37, 0, 105, 103, 1, 32, 101, 114, 97, 98, 2, 32, 116, 105, 108, 0, 105, 103, 2, 32, 100, 101, 116, 0, 105, 103, 2, 32, 117, 110, 100, 115, 107, 121, 108, 100, 12, 0, 101, 97, 116, 116, 108, 101, 3, 89, 37, 6, 110, 47, 13, 55, 0, 101, 121, 109, 111, 117, 114, 8, 3, 89, 37, 12, 65, 113, 12, 0, 105, 111, 110, 8, 3, 89, 37, 12, 114, 50, 0, 4, 105, 100, 110, 101, 121, 3, 89, 37, 72, 50, 37, 0, 121, 100, 110, 101, 121, 0, 105, 99, 105, 108, 105, 101, 110, 3, 89, 37, 89, 6, 37, 55, 37, 13, 50, 0, 101, 97, 115, 111, 110, 8, 3, 89, 37, 89, 13, 50, 0, 111, 105, 103, 110, 3, 89, 39, 110, 68, 0, 105, 111, 117, 120, 3, 89, 40, 12, 0, 117, 114, 1, 97, 108, 3, 89, 40, 34, 0, 117, 98, 115, 116, 105, 116, 117, 116, 105, 111, 110, 8, 3, 89, 40, 71, 89, 47, 37, 47, 40, 91, 6, 39, 50, 0, 117, 98, 115, 116, 105, 116, 117, 116, 105, 111, 110, 3, 89, 40, 71, 89, 47, 37, 47, 40, 91, 39, 50, 0, 116, 101, 118, 101, 8, 3, 89, 47, 37, 12, 84, 0, 116, 101, 118, 101, 110, 8, 3, 89, 47, 37, 12, 84, 13, 50, 0, 116, 101, 112, 104, 101, 110, 3, 89, 47, 37, 84, 13, 50, 0, 116, 114, 105, 107, 101, 3, 89, 47, 51, 35, 57, 49, 0, 116, 101, 97, 108, 116, 104, 3, 89, 47, 109, 55, 87, 0, 116, 97, 116, 101, 1, 32, 101, 114, 105, 112, 109, 101, 2, 32, 3, 89, 47, 109, 57, 47, 0, 116, 101, 97, 107, 3, 89, 47, 109, 57, 49, 0, 116, 97, 99, 121, 8, 3, 89, 47, 109, 57, 89, 37, 0, 112, 105, 116, 102, 105, 114, 101, 3, 89, 48, 36, 47, 83, 35, 57, 114, 0, 112, 101, 97, 107, 3, 89, 48, 37, 12, 49, 0, 112, 105, 101, 108, 98, 101, 114, 103, 3, 89, 48, 37, 55, 71, 118, 12, 81, 0, 112, 101, 99, 105, 97, 108, 2, 32, 98, 114, 97, 110, 99, 104, 3, 89, 48, 109, 89, 57, 108, 55, 0, 4, 99, 1, 101, 2, 111, 98, 97, 114, 3, 89, 49, 0, 99, 1, 101, 109, 2, 97, 108, 0, 99, 1, 105, 99, 110, 97, 114, 102, 2, 111, 0, 99, 2, 111, 111, 0, 99, 2, 111, 114, 0, 99, 2, 114, 97, 112, 0, 99, 104, 2, 111, 111, 108, 0, 4, 99, 1, 97, 109, 2, 97, 114, 97, 3, 89, 49, 6, 0, 99, 1, 105, 100, 2, 111, 117, 110, 116, 0, 99, 111, 114, 116, 1, 101, 3, 89, 49, 6, 114, 12, 47, 0, 107, 121, 108, 105, 110, 101, 3, 89, 49, 35, 57, 55, 35, 57, 50, 0, 99, 114, 101, 119, 100, 114, 105, 118, 101, 114, 3, 89, 49, 51, 40, 72, 34, 35, 57, 84, 114, 0, 107, 97, 116, 101, 98, 111, 97, 114, 100, 3, 89, 49, 109, 57, 47, 71, 113, 12, 72, 0, 99, 111, 2, 116, 3, 89, 49, 114, 0, 99, 111, 110, 101, 3, 89, 49, 114, 50, 0, 108, 105, 109, 108, 105, 110, 101, 3, 89, 55, 36, 65, 55, 35, 57, 50, 0, 108, 111, 118, 97, 107, 105, 101, 116, 3, 89, 55, 39, 84, 110, 49, 6, 37, 13, 86, 0, 108, 111, 97, 110, 101, 3, 89, 55, 113, 58, 50, 0, 104, 105, 110, 101, 3, 89, 57, 35, 57, 50, 13, 0, 119, 101, 101, 116, 3, 89, 58, 37, 12, 47, 0, 119, 97, 110, 101, 101, 3, 89, 58, 114, 50, 37, 0, 109, 105, 108, 101, 121, 3, 89, 65, 35, 57, 55, 37, 0, 109, 105, 116, 104, 3, 89, 65, 36, 47, 0, 109, 121, 116, 104, 101, 3, 89, 65, 112, 12, 57, 86, 0, 116, 114, 97, 105, 103, 104, 116, 3, 89, 72, 34, 109, 12, 57, 47, 0, 116, 111, 110, 101, 8, 3, 89, 72, 39, 40, 50, 0, 113, 117, 97, 115, 104, 3, 89, 81, 58, 114, 91, 0, 99, 104, 119, 101, 105, 122, 3, 89, 84, 35, 57, 47, 89, 0, 101, 105, 110, 101, 3, 89, 109, 50, 108, 0, 97, 105, 100, 1, 32, 116, 114, 111, 112, 3, 89, 110, 6, 37, 72, 0, 97, 108, 111, 111, 110, 3, 89, 110, 55, 6, 40, 12, 50, 0, 97, 118, 111, 105, 114, 3, 89, 110, 84, 39, 35, 12, 0, 111, 112, 104, 105, 101, 3, 89, 113, 40, 83, 37, 0, 117, 112, 112, 111, 114, 116, 3, 89, 113, 48, 6, 114, 34, 72, 0, 4, 195, 165, 1, 32, 100, 101, 109, 2, 32, 3, 89, 114, 0, 195, 165, 1, 32, 100, 108, 111, 104, 2, 32, 0, 195, 165, 1, 32, 101, 100, 32, 108, 105, 118, 2, 32, 0, 195, 165, 1, 32, 101, 114, 2, 32, 0, 195, 165, 1, 32, 101, 118, 105, 108, 98, 2, 32, 0, 195, 165, 1, 32, 103, 111, 2, 32, 118, 105, 100, 101, 114, 101, 0, 195, 165, 1, 32, 105, 32, 108, 105, 118, 2, 32, 0, 195, 165, 1, 32, 108, 105, 118, 2, 32, 0, 195, 165, 1, 32, 114, 2, 32, 98, 97, 110, 103, 101, 0, 195, 165, 1, 32, 114, 101, 2, 32, 0, 195, 165, 1, 32, 115, 101, 2, 32, 0, 195, 165, 1, 32, 117, 100, 32, 108, 105, 118, 2, 32, 0, 195, 165, 1, 32, 118, 101, 108, 98, 2, 32, 0, 195, 165, 8, 2, 32, 17, 67, 17, 65, 17, 67, 101, 114, 32, 0, 195, 165, 8, 2, 32, 98, 101, 115, 118, 195, 166, 114, 108, 105, 103, 0, 195, 165, 8, 2, 32, 98, 108, 101, 118, 32, 0, 195, 165, 8, 2, 32, 98, 108, 105, 118, 101, 114, 32, 0, 195, 165, 8, 2, 32, 100, 101, 32, 109, 195, 165, 0, 195, 165, 8, 2, 32, 100, 101, 110, 32, 109, 195, 165, 0, 195, 165, 8, 2, 32, 102, 105, 107, 32, 0, 195, 165, 8, 2, 32, 103, 105, 107, 32, 0, 195, 165, 8, 2, 32, 103, 111, 100, 32, 0, 195, 165, 8, 2, 32, 103, 195, 165, 32, 0, 195, 165, 8, 2, 32, 103, 195, 165, 114, 32, 0, 195, 165, 8, 2, 32, 103, 195, 184, 114, 101, 32, 0, 195, 165, 8, 2, 32, 104, 17, 65, 110, 32, 109, 195, 165, 0, 195, 165, 8, 2, 32, 104, 97, 118, 100, 101, 32, 0, 195, 165, 8, 2, 32, 104, 97, 118, 101, 32, 0, 195, 165, 8, 2, 32, 104, 101, 114, 32, 0, 195, 165, 8, 2, 32, 104, 111, 108, 100, 32, 0, 195, 165, 8, 2, 32, 105, 32, 109, 195, 165, 0, 195, 165, 8, 2, 32, 107, 97, 110, 32, 0, 195, 165, 8, 2, 32, 107, 111, 109, 32, 0, 195, 165, 8, 2, 32, 107, 111, 109, 109, 101, 114, 32, 0, 195, 165, 8, 2, 32, 108, 97, 100, 32, 0, 195, 165, 8, 2, 32, 110, 195, 166, 114, 32, 0, 195, 165, 8, 2, 32, 115, 105, 107, 107, 101, 114, 32, 0, 195, 165, 8, 2, 32, 115, 107, 97, 108, 32, 0, 195, 165, 8, 2, 32, 115, 107, 101, 116, 101, 32, 0, 195, 165, 8, 2, 32, 116, 97, 103, 101, 114, 32, 0, 195, 165, 8, 2, 32, 118, 101, 100, 32, 0, 195, 165, 8, 2, 32, 118, 105, 32, 107, 97, 110, 32, 0, 195, 165, 8, 2, 32, 118, 105, 32, 109, 195, 165, 0, 195, 165, 8, 2, 32, 118, 105, 108, 108, 101, 32, 0, 195, 165, 8, 32, 101, 100, 32, 101, 108, 108, 105, 118, 2, 32, 0, 195, 165, 8, 32, 101, 100, 32, 108, 105, 118, 2, 32, 0, 195, 165, 8, 32, 105, 32, 101, 108, 108, 105, 118, 2, 32, 0, 195, 165, 8, 32, 105, 32, 108, 105, 118, 2, 32, 0, 195, 165, 8, 32, 110, 97, 104, 32, 101, 108, 108, 105, 118, 2, 32, 0, 195, 165, 8, 32, 110, 97, 104, 32, 108, 105, 118, 2, 32, 0, 195, 165, 8, 32, 110, 97, 104, 32, 114, 184, 195, 103, 2, 32, 0, 195, 165, 8, 32, 110, 117, 104, 32, 101, 108, 108, 105, 118, 2, 32, 0, 195, 165, 8, 32, 110, 117, 104, 32, 108, 105, 118, 2, 32, 0, 195, 165, 8, 32, 117, 100, 32, 101, 108, 108, 105, 118, 2, 32, 0, 195, 165, 8, 32, 117, 100, 32, 101, 108, 108, 105, 118, 2, 32, 0, 195, 165, 8, 32, 117, 100, 32, 114, 101, 2, 32, 0, 111, 110, 121, 97, 3, 89, 114, 50, 57, 110, 0, 117, 110, 100, 97, 121, 3, 89, 114, 50, 72, 37, 0, 117, 110, 115, 101, 116, 8, 3, 89, 114, 50, 89, 109, 47, 0, 117, 108, 108, 121, 3, 89, 114, 55, 37, 0, 117, 108, 108, 105, 118, 97, 110, 3, 89, 114, 55, 37, 84, 108, 50, 0, 111, 108, 115, 106, 101, 110, 105, 116, 115, 121, 110, 3, 89, 114, 55, 89, 57, 13, 50, 6, 37, 47, 89, 37, 50, 0, 117, 102, 102, 111, 108, 107, 3, 89, 114, 83, 114, 49, 0, 111, 116, 104, 101, 98, 121, 3, 89, 114, 86, 108, 71, 37, 0, 117, 116, 104, 101, 114, 3, 89, 114, 86, 114, 0, 117, 115, 115, 101, 120, 3, 89, 114, 89, 109, 81, 89, 0, 105, 114, 8, 2, 32, 3, 89, 118, 12, 0, 117, 114, 102, 3, 89, 118, 83, 0, 4, 99, 104, 3, 91, 0, 104, 1, 97, 104, 0, 104, 1, 97, 110, 0, 104, 1, 97, 112, 2, 97, 0, 104, 1, 105, 98, 2, 111, 112, 0, 104, 1, 105, 102, 2, 101, 114, 0, 104, 1, 105, 114, 116, 0, 104, 1, 111, 109, 2, 101, 0, 104, 1, 114, 97, 109, 0, 104, 1, 117, 112, 0, 104, 1, 117, 115, 2, 105, 0, 104, 2, 101, 114, 105, 102, 0, 104, 8, 0, 105, 2, 111, 110, 0, 104, 105, 114, 101, 3, 91, 13, 0, 104, 101, 105, 107, 3, 91, 35, 57, 49, 0, 104, 101, 105, 108, 97, 3, 91, 37, 12, 55, 110, 0, 104, 111, 119, 3, 91, 39, 40, 0, 117, 103, 97, 114, 8, 2, 32, 3, 91, 40, 81, 114, 0, 104, 105, 114, 116, 3, 91, 108, 12, 47, 0, 104, 97, 107, 101, 115, 112, 101, 97, 114, 101, 3, 91, 109, 37, 49, 89, 71, 37, 12, 34, 0, 101, 97, 109, 117, 115, 3, 91, 109, 37, 65, 13, 89, 0, 104, 101, 112, 104, 101, 114, 100, 3, 91, 109, 48, 20, 114, 72, 0, 104, 97, 119, 3, 91, 113, 12, 0, 101, 97, 110, 8, 2, 32, 3, 91, 113, 12, 50, 0, 101, 97, 110, 115, 8, 2, 32, 3, 91, 113, 12, 50, 89, 0, 104, 97, 117, 103, 104, 110, 101, 115, 115, 121, 3, 91, 113, 50, 109, 89, 37, 0, 104, 111, 114, 2, 116, 3, 91, 114, 0, 104, 111, 116, 3, 91, 114, 47, 0, 104, 101, 114, 2, 119, 111, 111, 100, 3, 91, 118, 0, 104, 101, 114, 109, 97, 110, 3, 91, 118, 12, 65, 110, 50, 0, 104, 105, 114, 108, 101, 121, 8, 3, 91, 118, 55, 37, 0, 104, 101, 114, 108, 111, 99, 107, 3, 91, 118, 55, 114, 49, 0, 7, 6, 116, 0, 8, 114, 97, 2, 32, 100, 101, 99, 111, 3, 0, 104, 1, 110, 97, 109, 97, 115, 2, 97, 3, 8, 87, 0, 97, 110, 103, 117, 121, 8, 3, 21, 102, 114, 0, 4, 3, 47, 0, 104, 1, 117, 108, 2, 101, 114, 0, 104, 8, 2, 101, 111, 0, 116, 0, 4, 101, 107, 8, 97, 105, 100, 101, 109, 3, 47, 6, 36, 49, 0, 101, 107, 8, 101, 103, 101, 108, 0, 101, 107, 8, 111, 101, 100, 105, 118, 0, 101, 107, 8, 111, 105, 108, 98, 105, 98, 0, 101, 107, 8, 111, 107, 97, 110, 105, 112, 0, 101, 107, 8, 111, 107, 115, 105, 100, 0, 101, 107, 8, 111, 110, 111, 102, 0, 101, 107, 8, 111, 112, 97, 0, 101, 107, 8, 111, 112, 121, 104, 0, 101, 107, 8, 111, 116, 111, 102, 0, 101, 107, 8, 111, 116, 112, 121, 108, 103, 0, 101, 107, 8, 111, 116, 114, 97, 107, 0, 101, 107, 8, 114, 97, 104, 99, 0, 4, 8, 2, 32, 98, 111, 110, 101, 3, 47, 6, 37, 12, 2, 0, 8, 2, 32, 115, 104, 105, 114, 116, 0, 114, 101, 118, 111, 114, 8, 3, 47, 16, 109, 84, 114, 0, 114, 101, 110, 99, 104, 99, 111, 97, 116, 3, 47, 34, 6, 109, 50, 91, 49, 4, 39, 40, 72, 0, 101, 114, 101, 115, 115, 2, 97, 110, 116, 3, 47, 34, 108, 89, 0, 101, 114, 101, 115, 115, 101, 114, 101, 116, 1, 110, 105, 3, 47, 34, 108, 89, 6, 36, 34, 108, 86, 0, 4, 101, 114, 101, 115, 115, 101, 114, 101, 1, 110, 105, 3, 47, 34, 108, 89, 6, 36, 34, 114, 0, 101, 114, 101, 115, 115, 101, 114, 101, 114, 1, 110, 105, 0, 114, 195, 168, 115, 8, 2, 32, 3, 47, 34, 109, 0, 114, 97, 100, 101, 1, 32, 100, 108, 114, 111, 119, 3, 47, 34, 109, 57, 72, 0, 4, 114, 97, 99, 101, 121, 8, 3, 47, 34, 109, 57, 89, 37, 0, 114, 97, 99, 121, 8, 0, 4, 114, 101, 100, 105, 118, 116, 101, 100, 101, 108, 3, 47, 34, 110, 83, 72, 13, 72, 36, 55, 0, 114, 101, 100, 118, 116, 101, 100, 101, 108, 0, 104, 97, 105, 3, 47, 35, 57, 0, 105, 116, 97, 110, 105, 99, 3, 47, 35, 57, 47, 6, 110, 50, 37, 49, 0, 105, 109, 101, 115, 1, 32, 101, 104, 116, 3, 47, 35, 57, 65, 89, 0, 105, 109, 101, 115, 104, 97, 114, 101, 3, 47, 35, 57, 65, 91, 109, 12, 34, 0, 8, 2, 32, 3, 47, 36, 12, 0, 101, 114, 114, 121, 3, 47, 36, 34, 37, 0, 105, 109, 111, 116, 104, 121, 3, 47, 36, 65, 115, 87, 37, 0, 101, 97, 107, 3, 47, 37, 12, 49, 0, 101, 101, 110, 97, 103, 101, 3, 47, 37, 12, 50, 109, 75, 0, 101, 101, 110, 97, 103, 101, 114, 3, 47, 37, 12, 50, 109, 75, 114, 0, 101, 97, 99, 104, 8, 3, 47, 37, 12, 76, 0, 111, 109, 98, 115, 3, 47, 40, 12, 65, 89, 0, 111, 109, 98, 115, 116, 111, 110, 101, 3, 47, 40, 12, 65, 89, 72, 39, 40, 50, 0, 117, 99, 115, 111, 110, 8, 3, 47, 40, 12, 89, 114, 50, 0, 4, 116, 1, 101, 2, 97, 108, 3, 47, 47, 0, 116, 1, 101, 2, 105, 100, 0, 116, 2, 195, 184, 106, 0, 116, 1, 97, 110, 2, 195, 184, 106, 3, 47, 47, 4, 0, 104, 3, 47, 107, 0, 101, 114, 101, 115, 115, 101, 1, 110, 105, 3, 47, 108, 34, 6, 35, 89, 13, 0, 101, 114, 101, 115, 115, 101, 114, 1, 110, 105, 3, 47, 108, 34, 6, 35, 89, 114, 0, 101, 110, 110, 101, 115, 115, 101, 101, 3, 47, 109, 50, 13, 89, 37, 0, 97, 112, 101, 8, 2, 32, 3, 47, 109, 57, 48, 0, 97, 112, 101, 8, 2, 110, 32, 3, 47, 109, 57, 48, 108, 0, 97, 106, 8, 2, 32, 109, 97, 104, 97, 108, 3, 47, 110, 91, 0, 111, 119, 110, 3, 47, 112, 58, 50, 0, 111, 114, 113, 117, 97, 121, 3, 47, 113, 12, 49, 37, 0, 111, 97, 115, 116, 3, 47, 113, 58, 89, 47, 0, 111, 97, 115, 116, 109, 97, 115, 116, 101, 114, 3, 47, 113, 58, 89, 47, 65, 4, 112, 12, 89, 47, 114, 0, 111, 107, 121, 111, 3, 47, 114, 49, 57, 39, 0, 111, 117, 99, 104, 100, 111, 119, 110, 3, 47, 114, 76, 72, 35, 58, 50, 0, 106, 8, 3, 76, 0, 104, 1, 114, 97, 109, 2, 97, 3, 87, 0, 104, 101, 114, 105, 110, 101, 1, 97, 99, 3, 87, 34, 36, 50, 0, 104, 97, 99, 107, 101, 114, 121, 3, 87, 110, 49, 108, 34, 37, 0, 104, 117, 110, 100, 101, 114, 3, 87, 114, 50, 72, 114, 0, 104, 105, 114, 100, 3, 87, 118, 12, 72, 0, 115, 104, 1, 105, 110, 97, 106, 2, 97, 114, 3, 91, 0, 7, 6, 117, 0, 1, 115, 2, 98, 108, 105, 3, 2, 40, 0, 4, 1, 100, 101, 115, 117, 114, 107, 2, 108, 108, 101, 3, 6, 40, 0, 1, 102, 105, 114, 116, 110, 101, 99, 2, 103, 0, 1, 107, 109, 111, 2, 108, 100, 0, 1, 107, 111, 114, 112, 2, 114, 97, 0, 1, 108, 97, 100, 110, 97, 2, 115, 0, 1, 108, 97, 104, 99, 2, 112, 0, 1, 108, 97, 118, 2, 116, 97, 0, 1, 111, 115, 115, 101, 114, 2, 114, 115, 0, 1, 112, 97, 99, 97, 2, 108, 99, 111, 0, 1, 112, 108, 97, 118, 2, 114, 103, 105, 115, 0, 1, 112, 109, 105, 2, 108, 115, 0, 1, 114, 101, 106, 2, 115, 97, 108, 101, 109, 0, 1, 115, 101, 114, 2, 114, 115, 0, 1, 116, 107, 97, 102, 2, 114, 97, 0, 1, 116, 115, 111, 103, 110, 97, 2, 114, 97, 0, 2, 108, 106, 101, 0, 8, 2, 102, 111, 114, 0, 8, 98, 98, 105, 107, 2, 116, 122, 0, 8, 98, 111, 114, 2, 115, 116, 0, 8, 100, 105, 102, 2, 115, 0, 8, 102, 110, 111, 107, 2, 115, 0, 8, 103, 105, 102, 2, 114, 0, 8, 104, 114, 165, 195, 2, 110, 100, 114, 101, 100, 101, 0, 8, 107, 108, 97, 107, 2, 110, 0, 8, 107, 110, 111, 107, 2, 114, 115, 0, 8, 108, 111, 118, 110, 111, 107, 2, 116, 0, 8, 112, 114, 97, 104, 2, 110, 0, 8, 114, 101, 100, 2, 100, 0, 8, 114, 116, 115, 110, 105, 2, 107, 115, 0, 8, 115, 97, 98, 2, 110, 0, 8, 115, 97, 108, 103, 2, 114, 0, 8, 115, 98, 97, 2, 114, 100, 0, 8, 115, 117, 97, 108, 107, 2, 108, 0, 116, 1, 10, 2, 116, 28, 33, 0, 1, 103, 110, 166, 195, 107, 2, 114, 117, 3, 6, 40, 10, 0, 4, 1, 100, 110, 111, 104, 2, 114, 97, 3, 6, 40, 12, 0, 1, 109, 117, 2, 108, 105, 103, 0, 8, 17, 67, 97, 108, 2, 110, 101, 0, 8, 109, 109, 111, 107, 2, 110, 101, 0, 4, 114, 1, 115, 97, 108, 3, 6, 40, 34, 0, 114, 1, 115, 97, 108, 103, 0, 114, 1, 115, 97, 114, 0, 114, 1, 115, 110, 101, 99, 0, 114, 1, 115, 110, 101, 109, 0, 114, 1, 115, 110, 111, 116, 0, 114, 1, 115, 115, 101, 114, 100, 0, 114, 1, 115, 115, 105, 102, 0, 114, 1, 115, 166, 195, 99, 0, 114, 8, 102, 109, 111, 107, 0, 116, 1, 10, 2, 28, 33, 3, 6, 40, 47, 0, 4, 100, 8, 2, 97, 116, 12, 14, 128, 132, 130, 3, 6, 40, 72, 0, 100, 8, 2, 101, 108, 116, 12, 14, 128, 132, 130, 0, 100, 8, 2, 114, 195, 184, 106, 12, 14, 128, 132, 130, 0, 100, 8, 2, 121, 12, 14, 128, 132, 130, 0, 100, 8, 2, 195, 165, 100, 12, 14, 128, 132, 130, 0, 100, 8, 2, 195, 184, 98, 116, 12, 14, 128, 132, 130, 0, 116, 97, 104, 3, 6, 57, 40, 12, 47, 112, 0, 114, 102, 101, 114, 1, 115, 3, 6, 108, 12, 83, 114, 0, 4, 1, 103, 117, 97, 2, 115, 116, 3, 6, 113, 0, 1, 108, 97, 104, 2, 110, 107, 0, 1, 108, 111, 99, 2, 109, 98, 0, 8, 107, 101, 115, 2, 110, 100, 0, 110, 100, 1, 98, 97, 114, 2, 117, 115, 3, 6, 113, 50, 72, 0, 1, 99, 108, 97, 99, 2, 116, 116, 97, 3, 6, 114, 0, 99, 107, 121, 1, 116, 110, 101, 107, 3, 6, 114, 49, 37, 0, 4, 1, 98, 105, 116, 115, 101, 118, 2, 108, 3, 6, 116, 0, 1, 100, 101, 99, 111, 114, 112, 2, 114, 101, 0, 1, 102, 114, 97, 112, 2, 109, 101, 0, 1, 110, 101, 118, 111, 114, 112, 0, 1, 116, 101, 2, 100, 101, 12, 0, 8, 98, 105, 114, 116, 2, 110, 101, 0, 8, 110, 101, 109, 0, 8, 116, 115, 111, 107, 2, 109, 101, 0, 101, 1, 100, 110, 111, 102, 0, 101, 1, 110, 101, 118, 97, 0, 116, 8, 98, 101, 100, 0, 114, 101, 1, 116, 117, 111, 10, 2, 28, 33, 3, 6, 116, 12, 34, 0, 4, 114, 1, 100, 10, 2, 28, 33, 3, 7, 40, 34, 0, 114, 1, 116, 10, 2, 28, 33, 0, 100, 8, 2, 21, 21, 12, 14, 128, 132, 130, 3, 7, 40, 86, 0, 100, 101, 8, 2, 21, 21, 12, 14, 128, 132, 131, 3, 7, 40, 86, 13, 0, 114, 101, 1, 10, 2, 12, 12, 12, 28, 33, 3, 7, 116, 12, 114, 0, 101, 122, 1, 103, 3, 8, 36, 89, 0, 1, 112, 109, 105, 2, 108, 115, 105, 118, 3, 8, 40, 0, 109, 1, 10, 2, 28, 33, 3, 8, 113, 65, 0, 4, 105, 100, 1, 103, 32, 108, 105, 118, 2, 101, 3, 35, 57, 72, 0, 105, 100, 1, 103, 32, 116, 97, 2, 101, 0, 105, 100, 8, 103, 2, 101, 116, 0, 105, 100, 101, 1, 103, 0, 105, 100, 101, 114, 1, 103, 3, 35, 57, 72, 114, 0, 105, 1, 103, 2, 116, 97, 114, 3, 37, 0, 4, 3, 40, 0, 1, 17, 67, 2, 18, 66, 18, 76, 0, 1, 18, 74, 115, 2, 17, 67, 18, 76, 0, 1, 18, 74, 115, 2, 116, 0, 1, 98, 2, 103, 115, 101, 0, 1, 100, 2, 107, 116, 105, 0, 1, 104, 2, 106, 101, 12, 0, 1, 104, 2, 108, 17, 67, 0, 1, 104, 2, 108, 18, 76, 0, 1, 104, 2, 108, 116, 0, 1, 104, 2, 110, 0, 1, 106, 2, 18, 66, 18, 69, 0, 1, 107, 2, 107, 0, 1, 107, 2, 108, 18, 69, 0, 1, 107, 2, 108, 18, 70, 0, 1, 107, 2, 108, 100, 0, 1, 107, 2, 108, 100, 101, 0, 1, 107, 2, 108, 108, 101, 114, 0, 1, 107, 2, 108, 116, 0, 1, 107, 100, 101, 118, 111, 104, 2, 108, 115, 0, 1, 107, 115, 2, 108, 107, 0, 1, 107, 115, 2, 108, 108, 0, 1, 107, 115, 2, 108, 112, 0, 1, 107, 115, 2, 116, 101, 0, 1, 108, 2, 107, 97, 115, 0, 1, 108, 2, 107, 114, 18, 76, 0, 1, 108, 2, 107, 114, 101, 114, 101, 0, 1, 108, 2, 110, 32, 0, 1, 108, 2, 110, 101, 0, 1, 108, 98, 2, 102, 195, 166, 0, 1, 108, 103, 2, 103, 0, 1, 108, 115, 2, 103, 116, 0, 1, 109, 2, 102, 116, 0, 1, 109, 2, 115, 105, 107, 0, 1, 109, 97, 107, 2, 102, 108, 97, 103, 101, 0, 1, 109, 115, 2, 18, 68, 12, 0, 1, 109, 115, 2, 103, 108, 0, 1, 110, 102, 2, 103, 0, 1, 110, 115, 2, 98, 108, 101, 0, 1, 112, 2, 99, 107, 12, 0, 1, 112, 2, 110, 100, 0, 1, 114, 2, 18, 71, 18, 69, 0, 1, 114, 2, 103, 0, 1, 114, 2, 109, 101, 0, 1, 114, 98, 2, 103, 0, 1, 114, 102, 2, 115, 0, 1, 114, 103, 2, 18, 71, 0, 1, 114, 103, 2, 112, 0, 1, 114, 107, 115, 2, 112, 108, 101, 0, 1, 114, 116, 2, 18, 71, 0, 1, 114, 116, 2, 107, 116, 18, 69, 0, 1, 114, 116, 2, 109, 97, 110, 0, 1, 115, 2, 98, 115, 0, 1, 115, 2, 103, 0, 1, 115, 2, 112, 112, 108, 101, 0, 1, 115, 2, 112, 114, 97, 0, 1, 116, 2, 110, 100, 195, 165, 0, 1, 116, 115, 2, 98, 12, 0, 2, 100, 101, 12, 12, 0, 2, 100, 101, 110, 0, 2, 100, 101, 110, 102, 111, 114, 12, 0, 2, 100, 103, 114, 117, 110, 100, 101, 108, 105, 103, 12, 0, 2, 103, 101, 12, 12, 0, 2, 103, 108, 12, 0, 2, 103, 108, 101, 12, 0, 2, 104, 121, 114, 101, 12, 0, 2, 105, 109, 111, 100, 115, 116, 195, 165, 101, 108, 105, 103, 0, 2, 108, 116, 105, 109, 97, 0, 2, 108, 116, 114, 97, 0, 2, 110, 105, 12, 12, 0, 2, 115, 117, 114, 112, 0, 2, 116, 111, 112, 105, 0, 8, 2, 21, 21, 12, 14, 128, 132, 129, 0, 8, 2, 100, 115, 12, 0, 8, 2, 114, 12, 12, 0, 8, 2, 114, 101, 116, 102, 195, 166, 12, 12, 14, 128, 132, 129, 0, 8, 107, 2, 108, 108, 101, 100, 101, 0, 8, 114, 112, 2, 115, 116, 0, 103, 1, 98, 2, 116, 97, 0, 103, 1, 108, 115, 0, 103, 1, 109, 2, 32, 117, 100, 0, 103, 1, 109, 2, 101, 32, 117, 100, 0, 2, 101, 110, 105, 103, 12, 3, 40, 6, 0, 101, 1, 108, 102, 110, 105, 2, 110, 122, 97, 3, 40, 6, 109, 0, 101, 116, 1, 110, 101, 109, 3, 40, 6, 109, 47, 0, 4, 1, 104, 2, 108, 101, 3, 40, 12, 0, 1, 106, 2, 105, 99, 101, 0, 1, 107, 2, 17, 67, 101, 0, 101, 1, 98, 108, 97, 0, 101, 1, 100, 2, 115, 0, 101, 1, 116, 115, 0, 101, 2, 32, 0, 103, 1, 108, 2, 101, 0, 115, 97, 8, 2, 32, 3, 40, 12, 36, 89, 6, 110, 0, 115, 97, 39, 115, 8, 2, 32, 3, 40, 12, 36, 89, 6, 110, 89, 0, 4, 101, 1, 116, 115, 2, 32, 3, 40, 13, 0, 101, 1, 116, 115, 2, 110, 32, 0, 114, 1, 98, 109, 97, 116, 3, 40, 34, 0, 114, 1, 116, 10, 2, 101, 108, 28, 33, 3, 40, 34, 6, 0, 114, 101, 1, 115, 10, 2, 114, 101, 12, 12, 12, 3, 40, 34, 7, 36, 0, 107, 101, 116, 8, 98, 3, 40, 49, 6, 109, 47, 0, 107, 117, 108, 101, 108, 101, 3, 40, 49, 40, 55, 6, 36, 55, 108, 0, 99, 99, 101, 115, 115, 111, 114, 1, 115, 3, 40, 49, 89, 6, 109, 89, 114, 0, 99, 99, 101, 115, 115, 111, 114, 101, 114, 1, 115, 3, 40, 49, 89, 109, 89, 6, 39, 114, 0, 108, 114, 101, 116, 1, 107, 3, 40, 55, 51, 114, 86, 0, 103, 1, 109, 115, 3, 40, 58, 0, 4, 100, 8, 2, 114, 105, 107, 107, 101, 108, 105, 103, 12, 14, 128, 132, 130, 3, 40, 72, 0, 100, 8, 2, 117, 101, 108, 105, 103, 12, 0, 100, 8, 2, 195, 184, 100, 12, 14, 128, 132, 130, 0, 102, 111, 114, 109, 101, 108, 3, 40, 83, 114, 65, 6, 36, 55, 0, 4, 100, 8, 2, 101, 110, 12, 3, 40, 86, 0, 100, 8, 2, 107, 105, 103, 0, 115, 107, 121, 108, 100, 105, 103, 3, 40, 89, 81, 6, 116, 55, 72, 37, 0, 103, 97, 102, 1, 108, 3, 55, 113, 81, 6, 110, 0, 4, 1, 112, 109, 111, 99, 2, 116, 101, 114, 3, 57, 40, 0, 1, 116, 2, 110, 101, 0, 1, 116, 2, 110, 105, 110, 103, 12, 0, 1, 116, 2, 116, 111, 114, 0, 8, 116, 115, 2, 97, 114, 116, 0, 110, 105, 116, 101, 100, 3, 57, 40, 50, 6, 35, 57, 47, 36, 72, 0, 114, 101, 1, 116, 120, 105, 109, 3, 57, 114, 0, 105, 1, 115, 2, 116, 101, 3, 58, 37, 0, 4, 114, 1, 115, 2, 102, 98, 3, 108, 12, 0, 114, 1, 115, 2, 102, 101, 0, 101, 114, 105, 1, 103, 2, 108, 108, 97, 3, 109, 51, 6, 37, 0, 4, 1, 17, 67, 2, 18, 66, 101, 12, 3, 113, 0, 1, 17, 67, 2, 18, 66, 116, 0, 1, 18, 68, 2, 102, 0, 1, 18, 71, 2, 110, 107, 116, 0, 1, 18, 73, 2, 102, 0, 1, 18, 74, 2, 102, 0, 1, 18, 74, 2, 114, 114, 101, 0, 1, 98, 2, 107, 0, 1, 98, 2, 110, 116, 0, 1, 100, 2, 107, 0, 1, 103, 2, 102, 0, 1, 104, 2, 103, 0, 1, 104, 2, 108, 0, 1, 104, 2, 108, 98, 195, 165, 110, 100, 0, 1, 104, 2, 108, 106, 101, 114, 110, 0, 1, 104, 2, 108, 108, 101, 0, 1, 104, 2, 108, 115, 107, 101, 0, 1, 104, 2, 108, 115, 195, 184, 109, 0, 1, 104, 2, 108, 116, 97, 110, 103, 0, 1, 104, 2, 114, 116, 105, 103, 0, 1, 104, 112, 97, 110, 107, 2, 108, 0, 1, 104, 114, 101, 100, 100, 117, 109, 2, 108, 0, 1, 104, 116, 117, 109, 115, 2, 108, 0, 1, 106, 2, 110, 107, 116, 117, 114, 12, 12, 0, 1, 106, 104, 2, 108, 112, 0, 1, 107, 2, 102, 102, 101, 114, 116, 0, 1, 107, 2, 108, 0, 1, 107, 2, 108, 100, 105, 111, 0, 1, 107, 2, 108, 105, 108, 116, 0, 1, 107, 101, 115, 2, 110, 100, 195, 166, 0, 1, 107, 115, 2, 98, 0, 1, 108, 2, 107, 0, 1, 108, 103, 184, 195, 114, 2, 103, 116, 0, 1, 108, 115, 2, 98, 0, 1, 108, 115, 2, 112, 0, 1, 109, 115, 2, 17, 67, 0, 1, 110, 18, 66, 2, 18, 71, 0, 1, 112, 2, 102, 0, 1, 112, 2, 107, 107, 101, 0, 1, 112, 2, 107, 108, 0, 1, 112, 2, 110, 99, 104, 0, 1, 112, 115, 2, 110, 100, 101, 0, 1, 114, 2, 18, 71, 0, 1, 114, 2, 102, 0, 1, 114, 2, 109, 0, 1, 114, 2, 115, 116, 0, 1, 114, 17, 67, 2, 18, 71, 0, 1, 114, 17, 67, 2, 107, 0, 1, 114, 98, 2, 103, 116, 0, 1, 114, 116, 2, 102, 102, 0, 1, 116, 115, 2, 107, 107, 101, 116, 0, 1, 118, 115, 2, 112, 0, 2, 107, 115, 0, 2, 109, 25, 0, 2, 110, 18, 73, 0, 2, 110, 100, 0, 2, 110, 103, 12, 0, 2, 110, 107, 0, 8, 2, 110, 100, 12, 0, 8, 2, 110, 103, 12, 0, 8, 114, 2, 98, 32, 0, 8, 114, 2, 98, 98, 101, 0, 108, 118, 1, 103, 3, 113, 55, 0, 108, 118, 1, 103, 2, 101, 3, 113, 55, 84, 0, 109, 98, 117, 103, 1, 104, 3, 113, 65, 71, 113, 81, 0, 107, 97, 102, 1, 108, 3, 113, 81, 6, 110, 0, 4, 1, 32, 100, 110, 97, 116, 115, 2, 112, 3, 114, 0, 1, 98, 2, 99, 107, 0, 1, 98, 2, 102, 102, 101, 114, 0, 1, 98, 2, 116, 108, 101, 114, 0, 1, 100, 2, 98, 98, 101, 0, 1, 100, 2, 98, 98, 105, 110, 103, 0, 1, 100, 2, 98, 108, 105, 110, 0, 1, 100, 2, 100, 108, 101, 121, 0, 1, 100, 2, 110, 99, 97, 110, 0, 1, 102, 2, 99, 107, 12, 12, 0, 1, 104, 2, 110, 116, 101, 114, 0, 1, 104, 99, 116, 101, 107, 2, 112, 0, 1, 104, 100, 97, 101, 104, 2, 110, 116, 0, 1, 106, 2, 110, 107, 0, 1, 108, 2, 98, 98, 111, 99, 107, 0, 1, 108, 99, 2, 98, 0, 1, 108, 108, 2, 112, 0, 1, 109, 2, 112, 112, 101, 114, 110, 101, 0, 1, 112, 2, 98, 98, 0, 1, 114, 116, 2, 99, 107, 0, 1, 116, 115, 2, 110, 116, 0, 8, 100, 2, 115, 116, 105, 110, 0, 8, 102, 2, 110, 107, 0, 8, 109, 2, 108, 108, 105, 110, 0, 8, 112, 2, 98, 32, 0, 8, 112, 2, 110, 107, 0, 112, 112, 101, 114, 99, 117, 116, 3, 114, 48, 114, 49, 114, 47, 0, 99, 107, 101, 114, 1, 116, 3, 114, 49, 114, 0, 110, 99, 104, 1, 114, 98, 3, 114, 50, 91, 0, 109, 112, 104, 114, 101, 121, 1, 104, 3, 114, 65, 83, 34, 37, 0, 100, 100, 1, 98, 2, 121, 3, 114, 72, 0, 102, 102, 105, 110, 1, 109, 3, 114, 83, 36, 50, 0, 115, 116, 121, 1, 114, 3, 114, 89, 47, 37, 0, 4, 1, 18, 68, 2, 110, 115, 3, 115, 0, 1, 98, 2, 110, 107, 101, 114, 0, 1, 102, 2, 18, 71, 0, 1, 102, 2, 110, 12, 0, 1, 106, 2, 110, 116, 0, 1, 108, 2, 110, 116, 101, 0, 1, 108, 107, 2, 110, 115, 0, 1, 109, 2, 18, 66, 0, 1, 109, 2, 110, 116, 0, 1, 110, 115, 2, 18, 71, 0, 1, 112, 2, 108, 118, 0, 1, 115, 2, 18, 71, 11, 0, 1, 115, 2, 107, 0, 1, 116, 2, 110, 110, 0, 1, 118, 2, 103, 0, 8, 107, 2, 110, 32, 0, 8, 110, 2, 108, 0, 4, 1, 98, 2, 100, 103, 101, 116, 3, 116, 0, 1, 98, 105, 114, 116, 2, 110, 101, 0, 1, 100, 2, 99, 104, 101, 115, 115, 101, 0, 1, 102, 101, 114, 2, 115, 101, 114, 0, 1, 108, 103, 2, 107, 111, 115, 101, 0, 1, 110, 2, 97, 110, 99, 101, 0, 1, 110, 101, 109, 0, 1, 112, 2, 114, 195, 169, 0, 1, 115, 2, 99, 99, 0, 1, 115, 2, 114, 114, 101, 97, 0, 1, 116, 115, 111, 107, 2, 109, 101, 0, 8, 98, 2, 115, 116, 101, 32, 0, 8, 112, 2, 114, 101, 114, 101, 0, 116, 1, 98, 101, 100, 0, 8, 116, 97, 110, 2, 114, 101, 108, 32, 12, 3, 116, 6, 0, 114, 101, 1, 116, 117, 111, 99, 3, 116, 12, 34, 0, 4, 114, 101, 1, 99, 101, 110, 105, 115, 3, 116, 12, 114, 0, 114, 101, 1, 99, 105, 100, 101, 112, 0, 114, 101, 1, 99, 105, 110, 97, 109, 0, 114, 101, 1, 100, 101, 99, 111, 114, 112, 0, 114, 101, 1, 100, 114, 111, 98, 0, 114, 101, 1, 104, 99, 111, 114, 98, 0, 114, 101, 1, 104, 99, 117, 111, 98, 109, 101, 0, 114, 101, 1, 108, 101, 110, 110, 97, 107, 0, 114, 101, 1, 110, 114, 117, 111, 116, 0, 114, 101, 1, 115, 105, 114, 102, 0, 114, 101, 1, 116, 97, 105, 110, 105, 109, 0, 114, 101, 1, 116, 97, 105, 110, 105, 109, 0, 114, 101, 1, 116, 105, 102, 110, 111, 107, 0, 114, 101, 1, 116, 105, 110, 114, 97, 103, 0, 114, 101, 1, 116, 105, 114, 102, 0, 114, 101, 1, 116, 107, 101, 102, 110, 111, 107, 0, 114, 101, 1, 116, 107, 101, 108, 0, 114, 101, 1, 116, 114, 101, 118, 117, 111, 0, 114, 101, 1, 118, 97, 114, 103, 0, 114, 101, 1, 10, 2, 114, 101, 28, 33, 12, 12, 12, 3, 116, 34, 7, 36, 0, 4, 114, 101, 1, 112, 116, 97, 109, 111, 116, 3, 116, 34, 36, 0, 114, 195, 169, 1, 112, 116, 97, 109, 111, 116, 0, 116, 101, 1, 108, 102, 3, 116, 47, 0, 114, 101, 97, 117, 1, 98, 3, 116, 51, 6, 39, 0, 4, 109, 101, 1, 115, 101, 114, 3, 116, 65, 6, 36, 0, 109, 195, 169, 1, 115, 101, 114, 0, 120, 101, 108, 108, 101, 115, 1, 114, 98, 3, 116, 89, 6, 109, 55, 0, 1, 115, 2, 114, 114, 101, 108, 3, 117, 0, 114, 1, 98, 2, 109, 101, 115, 3, 118, 0, 4, 114, 1, 98, 2, 109, 97, 3, 118, 12, 0, 114, 1, 112, 2, 115, 101, 114, 0, 114, 8, 98, 2, 116, 0, 114, 112, 108, 101, 1, 112, 3, 118, 12, 48, 20, 13, 55, 0, 114, 110, 1, 98, 121, 97, 114, 3, 118, 12, 50, 0, 114, 100, 108, 101, 1, 104, 3, 118, 72, 13, 55, 0, 114, 100, 108, 101, 110, 1, 104, 3, 118, 72, 55, 108, 50, 0, 114, 103, 105, 115, 8, 116, 115, 3, 118, 75, 37, 89, 0, 114, 103, 1, 98, 2, 101, 114, 3, 118, 81, 0, 7, 6, 118, 0, 4, 1, 101, 108, 98, 3, 0, 4, 1, 108, 97, 104, 3, 0, 1, 108, 101, 2, 17, 67, 3, 0, 1, 97, 108, 2, 101, 109, 101, 110, 116, 3, 13, 0, 108, 101, 103, 1, 108, 97, 104, 3, 35, 57, 0, 4, 1, 97, 104, 2, 17, 67, 3, 40, 0, 1, 97, 104, 2, 111, 118, 101, 114, 102, 0, 4, 1, 97, 2, 110, 3, 58, 0, 1, 101, 108, 98, 101, 100, 117, 0, 1, 184, 195, 2, 101, 110, 0, 2, 110, 0, 118, 1, 105, 108, 3, 58, 84, 0, 2, 97, 110, 32, 103, 111, 103, 104, 3, 83, 0, 111, 110, 8, 2, 32, 3, 83, 114, 50, 0, 4, 3, 84, 0, 1, 17, 65, 10, 2, 17, 65, 0, 1, 17, 65, 10, 2, 32, 17, 65, 0, 1, 97, 108, 115, 2, 12, 0, 1, 108, 97, 2, 101, 0, 1, 108, 105, 2, 17, 65, 0, 1, 111, 18, 74, 2, 17, 65, 0, 1, 111, 114, 112, 2, 101, 110, 99, 101, 0, 1, 114, 10, 0, 1, 114, 117, 0, 118, 0, 105, 114, 103, 105, 110, 105, 97, 3, 84, 13, 75, 6, 37, 68, 57, 110, 0, 105, 110, 99, 101, 3, 84, 36, 50, 89, 0, 105, 108, 108, 97, 103, 101, 3, 84, 36, 55, 36, 75, 0, 111, 105, 108, 97, 3, 84, 58, 35, 55, 6, 35, 0, 101, 2, 108, 115, 101, 3, 84, 108, 0, 101, 114, 100, 117, 110, 3, 84, 109, 34, 72, 6, 108, 68, 0, 97, 117, 103, 104, 110, 3, 84, 113, 12, 50, 0, 111, 108, 105, 101, 114, 101, 3, 84, 114, 55, 37, 6, 109, 12, 34, 0, 7, 6, 119, 0, 114, 105, 103, 104, 116, 3, 21, 0, 3, 58, 0, 121, 111, 109, 105, 110, 103, 3, 58, 35, 57, 6, 113, 58, 65, 36, 68, 0, 105, 100, 101, 115, 99, 114, 101, 101, 110, 3, 58, 35, 57, 72, 89, 49, 34, 37, 12, 50, 0, 105, 110, 110, 105, 112, 101, 103, 3, 58, 36, 50, 37, 48, 109, 81, 0, 105, 115, 99, 111, 110, 115, 105, 110, 3, 58, 36, 89, 49, 6, 114, 50, 89, 36, 50, 0, 101, 101, 107, 101, 110, 100, 3, 58, 37, 12, 81, 109, 50, 72, 0, 101, 97, 118, 101, 114, 3, 58, 37, 12, 84, 114, 0, 104, 101, 101, 108, 3, 58, 37, 55, 0, 4, 105, 108, 108, 105, 101, 3, 58, 37, 55, 37, 0, 105, 108, 108, 121, 0, 97, 121, 110, 101, 3, 58, 109, 57, 50, 0, 97, 108, 101, 115, 3, 58, 109, 57, 55, 89, 0, 101, 97, 116, 104, 101, 114, 3, 58, 109, 86, 114, 0, 97, 114, 101, 3, 58, 110, 12, 34, 0, 105, 108, 100, 8, 3, 58, 112, 57, 55, 72, 0, 97, 116, 101, 114, 103, 97, 116, 101, 3, 58, 113, 47, 114, 81, 109, 57, 47, 0, 97, 108, 100, 111, 114, 102, 8, 3, 58, 113, 72, 114, 83, 0, 97, 116, 115, 111, 110, 3, 58, 114, 47, 89, 14, 50, 0, 97, 110, 100, 97, 3, 58, 114, 50, 72, 110, 0, 111, 110, 100, 101, 114, 8, 3, 58, 114, 50, 72, 114, 0, 97, 110, 115, 101, 97, 1, 115, 3, 58, 114, 50, 89, 4, 37, 0, 97, 108, 108, 97, 99, 101, 3, 58, 114, 55, 36, 89, 0, 97, 115, 104, 105, 110, 103, 116, 111, 110, 3, 58, 114, 91, 36, 68, 47, 114, 50, 0, 111, 114, 107, 3, 58, 118, 12, 49, 0, 111, 114, 116, 104, 3, 58, 118, 12, 87, 0, 111, 114, 108, 100, 8, 3, 58, 118, 55, 72, 0, 111, 114, 100, 3, 58, 118, 72, 0, 4, 1, 116, 110, 97, 2, 101, 114, 112, 101, 110, 3, 84, 0, 2, 97, 100, 101, 114, 115, 0, 2, 97, 100, 105, 0, 2, 97, 108, 105, 115, 0, 2, 97, 115, 115, 101, 114, 109, 97, 110, 110, 112, 114, 195, 184, 118, 101, 0, 2, 97, 116, 116, 0, 2, 101, 108, 116, 101, 114, 118, 195, 166, 103, 116, 0, 2, 101, 108, 116, 115, 99, 104, 109, 101, 114, 122, 0, 2, 101, 114, 110, 101, 114, 0, 2, 101, 115, 115, 101, 108, 0, 2, 104, 105, 115, 116, 0, 2, 105, 101, 110, 101, 114, 115, 99, 104, 110, 105, 116, 122, 101, 108, 0, 2, 111, 108, 102, 103, 97, 110, 103, 0, 2, 111, 108, 102, 114, 97, 109, 0, 97, 105, 1, 117, 107, 2, 116, 3, 84, 6, 35, 57, 0, 97, 114, 115, 122, 97, 119, 97, 3, 84, 35, 34, 91, 6, 110, 12, 84, 110, 0, 97, 108, 100, 3, 84, 35, 55, 72, 0, 97, 102, 102, 101, 3, 84, 35, 83, 108, 0, 105, 101, 110, 3, 84, 37, 50, 0, 105, 101, 115, 101, 110, 116, 104, 97, 108, 3, 84, 37, 89, 13, 50, 47, 112, 55, 0, 7, 6, 120, 0, 4, 3, 81, 89, 0, 99, 0, 4, 105, 100, 8, 111, 2, 32, 3, 81, 89, 6, 37, 86, 0, 121, 100, 8, 111, 2, 32, 0, 97, 108, 1, 111, 3, 81, 89, 6, 110, 55, 0, 4, 105, 100, 101, 8, 111, 2, 114, 101, 3, 81, 89, 37, 72, 6, 36, 0, 105, 100, 101, 8, 111, 2, 114, 105, 0, 121, 100, 101, 8, 111, 2, 114, 101, 0, 121, 100, 101, 8, 111, 2, 114, 105, 0, 121, 103, 101, 110, 1, 111, 3, 81, 89, 37, 81, 6, 36, 50, 0, 111, 110, 3, 81, 89, 114, 50, 0, 4, 1, 110, 3, 89, 0, 8, 0, 7, 6, 121, 0, 1, 98, 100, 110, 97, 116, 115, 3, 6, 35, 57, 0, 4, 1, 110, 111, 100, 117, 101, 115, 112, 2, 109, 3, 6, 116, 0, 8, 107, 101, 108, 111, 109, 2, 108, 101, 0, 8, 108, 112, 97, 114, 97, 112, 0, 8, 110, 105, 118, 2, 108, 0, 8, 115, 97, 2, 108, 0, 8, 116, 97, 108, 2, 114, 117, 115, 0, 8, 116, 111, 101, 114, 101, 116, 115, 2, 112, 0, 8, 118, 101, 114, 0, 8, 122, 110, 101, 2, 109, 0, 4, 1, 110, 97, 107, 2, 108, 101, 3, 6, 117, 0, 8, 98, 97, 107, 2, 115, 0, 8, 104, 97, 107, 2, 116, 0, 4, 1, 109, 2, 110, 116, 101, 3, 6, 118, 0, 8, 114, 97, 112, 2, 107, 0, 111, 114, 107, 115, 104, 105, 114, 101, 3, 10, 57, 113, 49, 91, 13, 0, 103, 1, 114, 2, 32, 3, 13, 49, 0, 4, 1, 99, 2, 98, 101, 114, 3, 35, 57, 0, 1, 107, 115, 2, 108, 105, 103, 104, 116, 0, 1, 116, 115, 2, 108, 105, 115, 116, 0, 116, 101, 1, 98, 3, 35, 57, 47, 0, 112, 97, 115, 115, 1, 98, 3, 35, 57, 48, 35, 12, 89, 0, 4, 108, 101, 1, 108, 114, 97, 99, 3, 35, 57, 55, 0, 108, 101, 8, 108, 0, 100, 101, 1, 108, 99, 3, 35, 57, 72, 0, 100, 101, 108, 108, 1, 114, 3, 35, 57, 72, 6, 109, 59, 0, 107, 101, 115, 8, 115, 3, 35, 57, 81, 89, 0, 97, 8, 119, 2, 116, 116, 3, 35, 57, 108, 0, 110, 100, 111, 110, 8, 108, 3, 36, 50, 72, 114, 50, 0, 110, 116, 104, 101, 115, 105, 122, 101, 114, 1, 115, 3, 36, 50, 87, 36, 89, 35, 57, 89, 114, 0, 108, 118, 97, 110, 105, 97, 1, 115, 110, 110, 101, 112, 3, 36, 55, 84, 6, 109, 57, 50, 57, 110, 0, 4, 1, 98, 98, 111, 3, 37, 0, 1, 98, 105, 108, 0, 1, 99, 110, 97, 110, 0, 1, 99, 117, 108, 0, 1, 100, 2, 32, 0, 1, 100, 2, 108, 97, 110, 0, 1, 100, 2, 115, 32, 0, 1, 107, 99, 97, 106, 0, 1, 107, 99, 101, 98, 0, 1, 107, 115, 105, 104, 119, 0, 1, 108, 105, 109, 101, 0, 1, 108, 107, 111, 111, 114, 98, 2, 110, 0, 1, 108, 108, 101, 104, 115, 0, 1, 108, 108, 101, 107, 0, 1, 108, 108, 105, 98, 0, 1, 108, 108, 105, 108, 0, 1, 108, 111, 114, 97, 99, 2, 110, 0, 1, 110, 110, 101, 112, 0, 1, 110, 110, 111, 100, 0, 1, 110, 110, 111, 114, 0, 1, 112, 112, 97, 104, 0, 1, 114, 97, 109, 2, 115, 0, 1, 114, 111, 103, 101, 114, 103, 0, 1, 114, 114, 97, 107, 2, 12, 0, 1, 114, 114, 101, 104, 115, 0, 1, 116, 102, 105, 102, 0, 1, 116, 105, 99, 0, 1, 116, 105, 110, 105, 114, 116, 0, 1, 116, 110, 117, 111, 99, 0, 1, 116, 114, 97, 112, 0, 1, 116, 115, 101, 110, 109, 97, 0, 1, 116, 116, 101, 98, 0, 1, 116, 116, 105, 107, 0, 1, 118, 108, 101, 109, 2, 110, 0, 8, 98, 97, 110, 114, 97, 98, 0, 8, 114, 114, 97, 104, 0, 1, 108, 111, 112, 2, 101, 115, 116, 3, 37, 6, 0, 112, 114, 101, 115, 8, 3, 37, 12, 48, 51, 20, 108, 0, 118, 101, 115, 8, 3, 37, 12, 84, 0, 102, 108, 111, 115, 115, 1, 100, 110, 97, 99, 3, 37, 83, 55, 114, 89, 0, 4, 1, 110, 2, 97, 3, 57, 0, 2, 97, 109, 115, 0, 2, 101, 109, 101, 110, 0, 2, 111, 103, 97, 0, 2, 111, 110, 110, 0, 101, 110, 110, 101, 1, 97, 99, 3, 57, 6, 109, 50, 108, 0, 97, 114, 100, 3, 57, 35, 34, 72, 0, 97, 99, 104, 116, 3, 57, 35, 81, 72, 0, 111, 107, 111, 104, 97, 109, 97, 3, 57, 39, 49, 39, 107, 6, 110, 65, 110, 0, 111, 121, 111, 3, 57, 39, 57, 6, 39, 0, 117, 112, 112, 105, 101, 3, 57, 40, 48, 37, 0, 111, 110, 1, 110, 97, 99, 3, 57, 108, 50, 0, 101, 110, 8, 3, 57, 109, 50, 0, 97, 116, 101, 115, 8, 3, 57, 109, 57, 47, 89, 0, 97, 108, 101, 3, 57, 109, 57, 59, 0, 101, 97, 103, 101, 114, 3, 57, 109, 81, 114, 0, 97, 116, 122, 121, 3, 57, 110, 47, 89, 37, 0, 97, 110, 107, 101, 101, 3, 57, 110, 50, 49, 37, 0, 111, 117, 110, 103, 3, 57, 114, 68, 0, 111, 114, 107, 3, 79, 114, 12, 49, 0, 2, 97, 115, 109, 105, 110, 3, 91, 0, 4, 3, 116, 0, 1, 17, 67, 2, 18, 73, 12, 0, 1, 98, 2, 17, 65, 0, 1, 107, 2, 108, 108, 105, 110, 103, 12, 0, 1, 107, 2, 115, 107, 12, 0, 1, 107, 115, 2, 115, 12, 0, 1, 107, 115, 2, 116, 101, 114, 0, 1, 107, 115, 2, 116, 105, 0, 1, 108, 2, 110, 32, 0, 1, 108, 102, 97, 2, 116, 0, 1, 108, 102, 97, 2, 116, 116, 0, 1, 110, 107, 2, 116, 0, 1, 114, 2, 17, 67, 17, 65, 12, 0, 1, 114, 2, 18, 71, 12, 0, 1, 114, 2, 100, 12, 0, 1, 114, 2, 103, 101, 12, 0, 1, 114, 2, 108, 108, 101, 0, 1, 114, 2, 115, 107, 12, 0, 1, 114, 2, 116, 12, 0, 1, 114, 98, 2, 110, 0, 1, 114, 102, 2, 115, 12, 0, 1, 114, 103, 2, 110, 0, 1, 114, 107, 2, 98, 98, 12, 0, 1, 114, 107, 2, 115, 12, 0, 1, 114, 116, 115, 2, 17, 67, 0, 1, 115, 2, 110, 100, 114, 111, 109, 0, 1, 115, 2, 110, 107, 114, 0, 1, 115, 2, 110, 116, 0, 1, 116, 2, 18, 66, 11, 101, 0, 8, 108, 2, 110, 0, 103, 1, 114, 2, 32, 101, 110, 0, 103, 1, 114, 2, 110, 105, 110, 103, 0, 103, 1, 114, 112, 2, 108, 0, 103, 1, 114, 116, 2, 108, 101, 0, 1, 107, 2, 115, 101, 12, 3, 116, 12, 0, 103, 101, 1, 114, 116, 115, 3, 116, 12, 13, 0, 110, 103, 1, 108, 2, 108, 105, 109, 116, 3, 116, 50, 81, 0, 4, 103, 1, 109, 100, 121, 3, 116, 57, 0, 103, 1, 114, 116, 115, 0, 118, 1, 115, 3, 116, 58, 0, 103, 101, 108, 107, 110, 97, 98, 101, 1, 114, 112, 3, 116, 81, 109, 55, 49, 50, 112, 71, 108, 0, 4, 1, 110, 2, 116, 3, 117, 0, 1, 114, 17, 67, 2, 18, 73, 0, 4, 114, 114, 101, 1, 102, 2, 107, 3, 117, 12, 114, 0, 114, 114, 101, 1, 102, 2, 116, 114, 0, 4, 1, 18, 73, 2, 116, 3, 118, 0, 1, 100, 2, 18, 66, 116, 0, 1, 100, 2, 107, 0, 1, 100, 2, 112, 0, 1, 107, 2, 109, 25, 0, 1, 107, 2, 115, 12, 0, 1, 107, 115, 2, 108, 32, 0, 1, 107, 115, 2, 108, 108, 0, 1, 107, 115, 2, 108, 110, 105, 0, 1, 108, 2, 103, 116, 0, 1, 108, 2, 107, 115, 97, 108, 105, 103, 0, 1, 108, 2, 107, 195, 184, 0, 1, 108, 2, 109, 17, 67, 0, 1, 108, 2, 110, 99, 104, 0, 1, 108, 2, 115, 116, 32, 116, 105, 108, 32, 0, 1, 108, 2, 115, 116, 98, 0, 1, 108, 2, 115, 116, 101, 108, 105, 103, 0, 1, 108, 2, 115, 116, 101, 110, 0, 1, 108, 2, 115, 116, 101, 114, 0, 1, 108, 2, 115, 116, 102, 105, 115, 107, 0, 1, 108, 2, 115, 116, 103, 195, 165, 114, 100, 0, 1, 108, 2, 115, 116, 104, 117, 115, 0, 1, 108, 2, 115, 116, 105, 103, 0, 1, 108, 2, 115, 116, 108, 195, 184, 103, 110, 0, 1, 108, 2, 115, 116, 109, 111, 114, 100, 0, 1, 108, 2, 115, 116, 110, 101, 0, 1, 108, 2, 115, 116, 115, 101, 106, 108, 0, 1, 108, 2, 115, 116, 115, 112, 105, 108, 0, 1, 108, 2, 115, 116, 121, 97, 99, 104, 116, 0, 1, 108, 32, 101, 107, 107, 105, 2, 115, 116, 0, 1, 108, 32, 114, 97, 104, 2, 115, 116, 0, 1, 108, 32, 114, 111, 116, 115, 2, 115, 116, 0, 1, 108, 32, 114, 165, 195, 102, 2, 115, 116, 0, 1, 108, 100, 97, 109, 2, 115, 116, 0, 1, 108, 101, 100, 105, 118, 2, 115, 116, 0, 1, 108, 101, 100, 166, 195, 2, 115, 116, 0, 1, 108, 101, 103, 114, 184, 195, 112, 115, 2, 115, 116, 0, 1, 108, 101, 107, 114, 105, 118, 2, 115, 116, 0, 1, 108, 101, 112, 112, 97, 107, 2, 115, 116, 0, 1, 108, 101, 114, 100, 110, 97, 118, 2, 115, 116, 0, 1, 108, 101, 114, 166, 195, 108, 2, 115, 116, 0, 1, 108, 101, 118, 105, 114, 107, 115, 2, 115, 116, 0, 1, 108, 102, 2, 116, 32, 0, 1, 108, 102, 2, 116, 98, 97, 114, 0, 1, 108, 102, 2, 116, 110, 0, 1, 108, 102, 2, 116, 116, 0, 1, 108, 108, 101, 118, 2, 115, 116, 0, 1, 108, 110, 101, 106, 184, 195, 2, 115, 116, 0, 1, 108, 110, 118, 166, 195, 104, 2, 115, 116, 0, 1, 108, 115, 110, 101, 106, 184, 195, 2, 115, 116, 0, 1, 108, 115, 110, 101, 114, 184, 195, 2, 115, 116, 0, 1, 108, 115, 118, 105, 108, 2, 115, 116, 0, 1, 108, 117, 2, 115, 116, 0, 1, 109, 115, 2, 107, 110, 0, 1, 110, 2, 107, 32, 0, 1, 110, 2, 107, 101, 114, 0, 1, 110, 2, 109, 102, 0, 1, 110, 2, 110, 110, 101, 0, 1, 110, 2, 116, 116, 0, 1, 110, 100, 117, 2, 116, 0, 1, 110, 101, 98, 2, 116, 0, 1, 112, 2, 110, 116, 0, 1, 114, 2, 17, 67, 12, 0, 1, 114, 100, 2, 112, 0, 1, 114, 103, 2, 110, 116, 0, 1, 114, 107, 2, 18, 66, 11, 12, 0, 1, 115, 2, 110, 107, 114, 111, 99, 0, 1, 115, 2, 116, 116, 101, 110, 0, 1, 116, 115, 2, 107, 12, 0, 1, 116, 115, 2, 109, 112, 101, 114, 0, 2, 107, 107, 12, 0, 2, 110, 100, 12, 0, 2, 110, 107, 0, 8, 110, 2, 110, 32, 0, 1, 110, 107, 2, 116, 116, 3, 118, 12, 0, 114, 114, 101, 1, 102, 3, 118, 12, 114, 0, 110, 100, 105, 1, 115, 2, 107, 3, 118, 50, 72, 37, 0, 110, 103, 2, 97, 3, 118, 50, 81, 0, 4, 110, 103, 3, 118, 68, 0, 110, 103, 1, 108, 0, 115, 115, 1, 107, 3, 118, 89, 0, 114, 111, 110, 101, 1, 116, 3, 120, 34, 6, 113, 58, 50, 0, 7, 6, 122, 0, 1, 101, 104, 99, 2, 32, 3, 0, 122, 1, 105, 112, 2, 97, 3, 47, 89, 0, 4, 3, 89, 0, 122, 0, 101, 97, 2, 108, 97, 110, 3, 89, 36, 0, 4, 111, 109, 98, 105, 3, 89, 114, 65, 71, 37, 0, 111, 109, 98, 105, 101, 0, 7, 6, 0, 195, 177, 3, 21, 101, 115, 0, 195, 175, 3, 37, 12, 0, 36, 3, 72, 114, 55, 114, 0, 195, 167, 3, 89, 0, 195, 160, 3, 110, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts10 = FileInMemory_createWithData (193791, reinterpret_cast (&espeakdata_dicts10_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/da_dict", U"da"); Collection_addItem (me.peek(), espeakdata_dicts10.transfer()); static unsigned char espeakdata_dicts11_data[21637] = { 0, 4, 0, 0, 140, 33, 0, 0, 0, 0, 0, 0, 0, 21, 65, 4, 116, 15, 116, 15, 10, 127, 0, 85, 46, 32, 97, 32, 46, 32, 111, 32, 46, 32, 0, 0, 0, 0, 0, 12, 201, 36, 228, 194, 21, 51, 206, 16, 84, 133, 67, 11, 70, 9, 35, 215, 76, 84, 128, 21, 0, 10, 0, 0, 9, 68, 76, 208, 76, 48, 21, 0, 10, 0, 0, 10, 135, 26, 21, 18, 195, 188, 3, 11, 66, 0, 13, 4, 95, 8, 1, 3, 107, 6, 35, 76, 109, 49, 0, 0, 0, 8, 67, 69, 82, 90, 21, 0, 10, 0, 0, 0, 0, 11, 67, 44, 19, 142, 4, 49, 35, 50, 0, 9, 0, 16, 70, 76, 243, 12, 80, 83, 128, 4, 88, 113, 55, 47, 13, 50, 0, 0, 11, 67, 76, 147, 132, 88, 111, 50, 47, 0, 72, 16, 4, 95, 48, 67, 15, 6, 107, 114, 50, 72, 108, 132, 47, 13, 0, 0, 0, 17, 7, 8, 195, 164, 20, 20, 5, 14, 107, 4, 109, 47, 13, 50, 0, 9, 0, 0, 0, 7, 196, 48, 147, 9, 20, 20, 7, 196, 45, 84, 137, 20, 20, 0, 0, 0, 8, 67, 28, 147, 128, 21, 0, 10, 17, 7, 8, 195, 164, 20, 20, 5, 20, 107, 4, 109, 47, 13, 47, 0, 9, 0, 0, 0, 0, 11, 67, 92, 148, 132, 84, 4, 111, 34, 72, 0, 17, 67, 9, 165, 192, 71, 13, 132, 118, 114, 68, 89, 84, 122, 88, 13, 0, 0, 6, 195, 21, 69, 193, 72, 9, 1, 35, 50, 114, 65, 108, 0, 27, 0, 0, 13, 1, 37, 48, 34, 127, 132, 6, 109, 50, 47, 0, 27, 0, 11, 67, 92, 148, 128, 84, 118, 34, 0, 72, 9, 7, 1, 38, 114, 50, 47, 0, 0, 0, 0, 0, 20, 71, 5, 97, 78, 81, 84, 137, 56, 35, 84, 109, 50, 47, 120, 34, 6, 118, 50, 0, 11, 67, 92, 20, 128, 2, 84, 116, 34, 0, 9, 22, 67, 28, 20, 128, 81, 4, 116, 34, 50, 6, 111, 99, 47, 0, 81, 110, 105, 99, 104, 116, 32, 10, 1, 42, 91, 47, 109, 34, 50, 0, 27, 0, 9, 1, 43, 48, 55, 114, 89, 0, 27, 0, 12, 201, 52, 149, 5, 36, 224, 78, 16, 84, 128, 65, 16, 69, 21, 133, 18, 20, 208, 109, 49, 89, 47, 34, 6, 126, 65, 0, 0, 0, 0, 0, 0, 0, 0, 12, 68, 8, 80, 133, 56, 71, 126, 71, 13, 50, 0, 0, 0, 0, 0, 9, 68, 77, 82, 84, 20, 21, 0, 10, 0, 13, 5, 95, 48, 1, 14, 4, 15, 23, 114, 50, 47, 0, 0, 20, 9, 1, 21, 195, 159, 5, 18, 4, 5, 13, 6, 121, 89, 108, 72, 4, 126, 65, 0, 0, 0, 0, 12, 67, 28, 19, 154, 81, 4, 35, 50, 132, 0, 9, 0, 21, 73, 77, 2, 78, 61, 160, 73, 76, 50, 0, 89, 48, 118, 50, 6, 127, 132, 122, 91, 0, 9, 1, 61, 81, 55, 122, 99, 0, 27, 0, 19, 71, 21, 38, 135, 20, 34, 82, 28, 126, 34, 132, 81, 13, 71, 111, 34, 81, 0, 0, 7, 196, 64, 147, 137, 20, 20, 0, 15, 1, 64, 49, 55, 6, 35, 65, 108, 10, 4, 35, 83, 13, 0, 0, 9, 66, 4, 32, 35, 48, 0, 76, 28, 0, 11, 67, 76, 144, 200, 88, 111, 99, 0, 72, 9, 0, 0, 0, 0, 0, 0, 0, 16, 70, 20, 147, 137, 28, 84, 192, 122, 50, 111, 81, 13, 89, 0, 76, 8, 67, 48, 243, 203, 21, 0, 10, 0, 8, 67, 80, 129, 64, 86, 13, 0, 0, 0, 8, 197, 4, 195, 5, 36, 224, 66, 0, 16, 70, 77, 0, 82, 76, 19, 64, 91, 48, 116, 34, 88, 116, 65, 0, 8, 67, 77, 0, 77, 21, 0, 10, 0, 17, 70, 16, 160, 75, 5, 37, 1, 75, 35, 49, 6, 35, 34, 47, 116, 0, 9, 67, 5, 37, 0, 116, 34, 47, 0, 10, 67, 5, 81, 128, 121, 83, 0, 76, 28, 11, 67, 8, 65, 64, 71, 109, 50, 72, 13, 0, 0, 0, 10, 69, 76, 84, 150, 21, 32, 21, 0, 10, 0, 12, 137, 20, 18, 1, 7, 195, 182, 4, 9, 5, 20, 0, 0, 15, 68, 32, 16, 133, 56, 107, 4, 116, 71, 13, 50, 0, 9, 12, 8, 196, 56, 80, 133, 56, 76, 28, 0, 10, 69, 92, 147, 132, 61, 112, 21, 0, 10, 0, 13, 5, 195, 182, 4, 5, 13, 130, 72, 6, 126, 65, 0, 0, 0, 0, 10, 69, 12, 128, 78, 28, 80, 21, 0, 10, 6, 65, 88, 83, 121, 0, 0, 0, 16, 67, 4, 227, 64, 6, 35, 50, 65, 4, 109, 34, 49, 114, 68, 0, 0, 0, 11, 1, 92, 71, 35, 49, 89, 55, 35, 91, 0, 0, 0, 17, 71, 92, 20, 211, 21, 37, 78, 28, 84, 35, 89, 13, 34, 114, 68, 0, 19, 71, 36, 195, 9, 8, 84, 129, 48, 111, 55, 118, 71, 13, 34, 6, 116, 55, 0, 12, 67, 92, 20, 148, 2, 84, 116, 34, 47, 0, 9, 10, 67, 16, 240, 200, 72, 113, 101, 0, 76, 0, 7, 196, 53, 83, 73, 20, 20, 0, 7, 65, 96, 111, 49, 89, 0, 0, 20, 4, 95, 49, 77, 50, 10, 6, 122, 50, 13, 15, 65, 111, 55, 111, 6, 127, 50, 0, 0, 22, 4, 95, 49, 77, 51, 10, 6, 122, 50, 13, 15, 65, 111, 55, 111, 6, 35, 34, 72, 13, 0, 0, 12, 68, 28, 80, 133, 56, 81, 126, 71, 13, 50, 0, 13, 68, 44, 243, 142, 80, 4, 49, 113, 50, 47, 0, 9, 0, 0, 0, 15, 67, 21, 101, 12, 126, 84, 109, 50, 47, 120, 6, 109, 55, 0, 0, 0, 21, 65, 104, 132, 114, 65, 71, 6, 122, 91, 48, 118, 55, 0, 83, 46, 32, 98, 32, 46, 32, 0, 0, 9, 67, 92, 20, 192, 84, 35, 89, 0, 0, 0, 8, 197, 105, 147, 66, 4, 192, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 69, 92, 82, 84, 84, 208, 84, 122, 47, 23, 6, 114, 65, 0, 0, 0, 10, 67, 76, 17, 212, 88, 116, 81, 47, 0, 9, 198, 44, 20, 212, 4, 226, 69, 20, 9, 198, 4, 227, 205, 4, 194, 69, 66, 0, 12, 68, 52, 241, 5, 52, 65, 127, 72, 109, 65, 0, 9, 68, 25, 32, 77, 20, 21, 0, 10, 0, 15, 69, 32, 21, 20, 20, 224, 107, 4, 35, 47, 13, 50, 0, 9, 0, 0, 8, 67, 84, 226, 88, 21, 0, 10, 9, 1, 126, 47, 111, 55, 72, 13, 0, 0, 0, 8, 197, 76, 19, 15, 65, 0, 66, 0, 9, 66, 8, 64, 71, 35, 50, 72, 0, 0, 7, 195, 21, 80, 200, 76, 9, 0, 9, 68, 25, 33, 65, 44, 21, 0, 10, 0, 0, 0, 15, 6, 8, 195, 164, 20, 20, 5, 107, 4, 109, 47, 13, 0, 9, 0, 9, 68, 21, 97, 78, 80, 21, 0, 10, 0, 0, 8, 67, 80, 19, 11, 21, 0, 10, 0, 0, 0, 0, 0, 9, 67, 5, 97, 64, 116, 84, 109, 0, 9, 67, 5, 80, 200, 4, 121, 101, 0, 0, 0, 0, 5, 194, 16, 16, 76, 0, 0, 0, 0, 0, 10, 67, 77, 34, 64, 89, 34, 4, 118, 0, 0, 11, 68, 81, 32, 73, 56, 47, 34, 126, 50, 0, 13, 68, 84, 210, 9, 56, 114, 65, 107, 6, 111, 50, 0, 0, 8, 197, 32, 244, 212, 36, 80, 20, 0, 0, 0, 0, 0, 0, 0, 13, 68, 36, 225, 5, 52, 111, 50, 72, 6, 126, 65, 0, 9, 198, 16, 86, 133, 52, 33, 82, 66, 0, 0, 0, 0, 13, 68, 36, 225, 5, 56, 111, 50, 72, 6, 126, 50, 0, 0, 0, 9, 198, 16, 83, 83, 20, 192, 128, 66, 0, 11, 67, 5, 84, 192, 4, 121, 89, 0, 28, 11, 0, 12, 68, 20, 147, 137, 28, 122, 50, 111, 99, 0, 9, 0, 14, 69, 52, 241, 5, 48, 192, 65, 127, 72, 6, 109, 55, 0, 10, 69, 64, 145, 7, 36, 224, 21, 0, 10, 0, 12, 66, 17, 32, 72, 113, 49, 47, 6, 127, 34, 0, 0, 0, 0, 0, 13, 138, 16, 18, 195, 164, 19, 9, 4, 5, 14, 20, 67, 9, 198, 16, 80, 129, 81, 65, 64, 66, 0, 0, 12, 68, 44, 19, 143, 20, 49, 35, 50, 6, 120, 0, 0, 8, 197, 76, 245, 197, 37, 64, 66, 0, 0, 8, 67, 4, 145, 0, 21, 0, 10, 0, 11, 68, 36, 225, 5, 72, 111, 50, 72, 108, 0, 0, 0, 0, 9, 198, 32, 148, 212, 61, 34, 69, 20, 0, 13, 68, 36, 225, 5, 76, 111, 50, 72, 6, 109, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 10, 7, 5, 7, 5, 14, 195, 188, 2, 5, 18, 81, 126, 81, 13, 50, 6, 128, 71, 108, 0, 0, 8, 67, 64, 18, 82, 21, 0, 10, 0, 9, 198, 16, 145, 83, 20, 192, 128, 66, 0, 20, 71, 56, 81, 204, 36, 113, 78, 80, 50, 126, 81, 55, 118, 75, 6, 109, 50, 47, 0, 0, 12, 68, 104, 195, 212, 100, 89, 55, 113, 47, 118, 0, 13, 68, 84, 228, 210, 20, 114, 50, 88, 34, 13, 0, 72, 0, 0, 10, 66, 21, 32, 109, 34, 0, 72, 28, 9, 0, 10, 199, 4, 36, 212, 36, 225, 78, 80, 67, 9, 67, 16, 145, 64, 2, 72, 118, 0, 0, 0, 0, 0, 0, 0, 0, 9, 198, 44, 19, 69, 48, 145, 64, 20, 17, 70, 28, 84, 129, 56, 145, 64, 81, 126, 34, 6, 116, 50, 111, 13, 0, 0, 9, 67, 8, 80, 84, 21, 0, 9, 10, 0, 10, 67, 36, 226, 193, 111, 68, 49, 116, 0, 0, 0, 0, 16, 70, 16, 17, 21, 72, 50, 0, 72, 116, 72, 6, 114, 34, 99, 0, 11, 67, 8, 82, 64, 71, 122, 0, 76, 28, 9, 0, 12, 4, 95, 4, 16, 20, 10, 49, 113, 65, 35, 0, 0, 0, 17, 66, 21, 48, 2, 109, 89, 2, 111, 89, 47, 0, 81, 105, 115, 116, 32, 9, 66, 21, 48, 109, 89, 0, 72, 9, 6, 194, 17, 80, 72, 9, 0, 9, 67, 80, 147, 64, 47, 111, 65, 0, 0, 7, 196, 52, 147, 149, 80, 66, 11, 67, 8, 82, 77, 71, 122, 65, 0, 76, 28, 0, 8, 67, 40, 80, 78, 21, 0, 10, 0, 10, 67, 16, 145, 83, 72, 118, 88, 0, 72, 17, 70, 84, 228, 197, 72, 83, 64, 114, 50, 89, 13, 34, 13, 65, 0, 72, 0, 16, 67, 36, 226, 204, 111, 50, 49, 55, 120, 88, 6, 118, 84, 13, 0, 0, 11, 67, 60, 35, 197, 127, 71, 6, 127, 13, 0, 0, 0, 0, 11, 67, 36, 228, 192, 111, 50, 89, 0, 76, 28, 0, 13, 4, 95, 20, 12, 4, 47, 6, 111, 55, 72, 13, 0, 17, 3, 95, 35, 57, 47, 4, 35, 71, 120, 55, 6, 116, 47, 127, 108, 0, 0, 0, 15, 70, 32, 21, 83, 36, 84, 128, 107, 121, 88, 6, 118, 34, 0, 0, 7, 195, 84, 228, 192, 76, 9, 0, 11, 200, 56, 85, 83, 20, 83, 1, 56, 64, 66, 12, 68, 4, 225, 18, 20, 35, 50, 72, 34, 13, 0, 13, 68, 84, 210, 5, 72, 114, 65, 107, 6, 109, 34, 0, 0, 0, 8, 66, 25, 32, 83, 34, 121, 0, 0, 19, 71, 4, 36, 197, 57, 66, 69, 72, 35, 48, 88, 109, 50, 47, 6, 118, 34, 0, 0, 0, 12, 67, 25, 35, 0, 83, 34, 124, 55, 122, 50, 0, 0, 9, 198, 80, 243, 142, 4, 113, 64, 20, 0, 0, 0, 0, 9, 198, 20, 225, 9, 88, 145, 64, 20, 9, 66, 4, 208, 35, 65, 0, 76, 28, 0, 0, 0, 8, 197, 4, 176, 90, 36, 80, 20, 10, 69, 72, 83, 65, 44, 80, 21, 0, 10, 14, 69, 76, 243, 12, 80, 80, 4, 88, 113, 55, 47, 13, 0, 0, 0, 0, 13, 68, 92, 242, 5, 72, 84, 127, 107, 6, 126, 34, 0, 12, 68, 92, 243, 12, 80, 2, 84, 113, 55, 47, 0, 8, 196, 36, 131, 133, 56, 76, 9, 0, 8, 197, 28, 195, 210, 36, 80, 20, 0, 17, 70, 81, 53, 78, 4, 210, 64, 132, 120, 50, 6, 35, 12, 65, 118, 0, 0, 18, 71, 28, 81, 204, 36, 50, 5, 56, 81, 13, 81, 55, 111, 99, 13, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 66, 4, 224, 35, 50, 0, 76, 28, 0, 16, 70, 12, 128, 78, 28, 145, 82, 91, 35, 68, 90, 6, 118, 34, 0, 0, 0, 0, 12, 67, 32, 16, 133, 2, 107, 116, 71, 13, 0, 9, 0, 0, 0, 13, 69, 16, 85, 1, 36, 192, 72, 126, 47, 6, 122, 0, 0, 0, 0, 0, 15, 69, 92, 147, 12, 77, 64, 2, 84, 111, 55, 89, 47, 0, 9, 0, 0, 0, 13, 72, 77, 113, 65, 81, 50, 9, 73, 64, 21, 0, 10, 0, 0, 11, 70, 72, 84, 197, 5, 32, 200, 21, 0, 10, 0, 0, 19, 8, 8, 195, 164, 20, 20, 5, 19, 20, 107, 4, 109, 47, 109, 89, 47, 0, 9, 0, 9, 198, 72, 83, 9, 69, 82, 69, 20, 12, 201, 44, 243, 147, 21, 37, 129, 80, 149, 128, 65, 11, 67, 32, 21, 0, 2, 107, 35, 47, 0, 9, 0, 12, 5, 11, 23, 1, 195, 159, 49, 84, 35, 89, 0, 0, 0, 11, 136, 23, 195, 164, 8, 18, 5, 14, 4, 72, 12, 68, 76, 50, 15, 56, 91, 4, 127, 50, 0, 12, 11, 136, 23, 195, 164, 8, 18, 5, 14, 4, 8, 0, 0, 0, 0, 0, 12, 67, 25, 81, 82, 83, 128, 34, 0, 76, 8, 9, 0, 9, 198, 16, 17, 197, 28, 83, 128, 66, 0, 11, 67, 105, 83, 64, 132, 114, 65, 0, 76, 8, 9, 67, 32, 147, 128, 107, 111, 50, 0, 0, 11, 70, 16, 80, 149, 28, 113, 82, 21, 0, 10, 0, 8, 197, 92, 244, 129, 85, 48, 66, 0, 18, 70, 16, 149, 137, 16, 83, 132, 72, 118, 84, 118, 72, 6, 109, 50, 47, 0, 7, 66, 16, 160, 21, 0, 10, 0, 7, 195, 16, 148, 128, 76, 9, 0, 12, 68, 20, 147, 133, 56, 122, 50, 13, 50, 0, 72, 0, 13, 69, 28, 83, 69, 36, 224, 81, 13, 65, 122, 50, 0, 6, 195, 16, 19, 142, 72, 0, 16, 70, 17, 32, 71, 36, 84, 128, 72, 34, 35, 90, 6, 118, 34, 0, 0, 0, 0, 23, 73, 65, 34, 86, 5, 66, 83, 36, 84, 128, 48, 34, 118, 84, 35, 47, 118, 88, 6, 118, 34, 0, 8, 197, 44, 243, 147, 84, 192, 65, 15, 69, 28, 83, 137, 4, 192, 81, 126, 50, 111, 6, 35, 55, 0, 0, 16, 70, 92, 82, 84, 32, 84, 128, 84, 122, 47, 107, 6, 109, 34, 0, 15, 70, 64, 240, 200, 36, 84, 128, 48, 113, 91, 6, 118, 34, 0, 8, 66, 33, 32, 107, 109, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 68, 17, 81, 84, 80, 72, 120, 6, 109, 47, 0, 0, 0, 0, 0, 13, 68, 4, 229, 9, 44, 35, 50, 47, 6, 118, 49, 0, 0, 0, 0, 0, 12, 68, 36, 132, 133, 52, 118, 34, 13, 65, 0, 72, 0, 0, 0, 17, 71, 92, 82, 84, 21, 37, 78, 28, 84, 122, 47, 13, 34, 114, 68, 0, 0, 12, 68, 20, 147, 133, 52, 122, 50, 13, 65, 0, 72, 0, 14, 73, 5, 52, 207, 12, 144, 84, 36, 243, 128, 21, 0, 10, 0, 0, 9, 67, 80, 160, 64, 47, 57, 116, 0, 8, 67, 76, 194, 80, 21, 0, 10, 0, 0, 0, 0, 0, 12, 68, 32, 19, 132, 100, 107, 109, 50, 72, 118, 0, 11, 68, 36, 132, 133, 72, 118, 34, 108, 0, 72, 13, 3, 95, 49, 15, 10, 6, 126, 34, 89, 47, 13, 0, 0, 13, 69, 28, 84, 211, 20, 224, 81, 109, 89, 13, 50, 0, 8, 197, 92, 244, 129, 84, 96, 66, 0, 10, 3, 95, 49, 1, 10, 6, 122, 50, 0, 0, 9, 3, 226, 130, 172, 124, 34, 127, 0, 0, 0, 11, 70, 32, 243, 69, 64, 17, 197, 21, 0, 10, 0, 0, 9, 67, 80, 17, 192, 47, 116, 81, 0, 0, 0, 16, 70, 52, 83, 149, 21, 69, 5, 65, 109, 50, 120, 6, 109, 47, 0, 0, 0, 0, 12, 68, 4, 50, 19, 60, 35, 101, 88, 6, 127, 0, 11, 68, 20, 147, 133, 72, 122, 50, 108, 0, 72, 7, 195, 36, 50, 0, 72, 9, 14, 68, 16, 84, 133, 56, 72, 126, 34, 13, 50, 0, 76, 28, 0, 0, 0, 15, 70, 20, 225, 12, 36, 50, 0, 109, 50, 47, 55, 111, 99, 0, 0, 10, 67, 52, 244, 147, 65, 113, 34, 89, 0, 13, 68, 92, 84, 132, 20, 84, 4, 109, 34, 72, 13, 0, 12, 68, 20, 147, 133, 76, 122, 50, 13, 89, 0, 72, 12, 3, 95, 51, 15, 72, 34, 6, 111, 47, 13, 0, 9, 4, 95, 15, 18, 4, 47, 13, 0, 0, 0, 0, 7, 195, 16, 144, 200, 76, 9, 0, 0, 10, 67, 37, 53, 0, 111, 89, 47, 0, 72, 0, 0, 8, 67, 73, 83, 128, 21, 0, 10, 7, 195, 36, 131, 64, 76, 9, 0, 0, 0, 0, 20, 71, 21, 2, 83, 44, 244, 1, 48, 126, 48, 111, 89, 49, 127, 48, 6, 116, 55, 0, 6, 195, 57, 84, 128, 28, 0, 0, 12, 67, 33, 34, 18, 107, 35, 34, 107, 35, 34, 0, 0, 8, 67, 76, 197, 77, 21, 0, 10, 0, 11, 67, 105, 84, 128, 132, 120, 34, 0, 76, 8, 10, 67, 16, 20, 192, 2, 72, 35, 89, 0, 0, 0, 0, 14, 4, 95, 13, 3, 14, 65, 6, 116, 49, 34, 113, 50, 0, 0, 0, 0, 0, 0, 11, 70, 40, 246, 83, 80, 144, 203, 21, 0, 10, 0, 0, 10, 69, 80, 80, 83, 21, 32, 21, 0, 10, 0, 0, 10, 67, 8, 84, 212, 71, 109, 89, 47, 0, 0, 13, 68, 92, 244, 129, 56, 84, 127, 34, 6, 35, 50, 0, 0, 0, 0, 19, 71, 25, 34, 69, 17, 99, 204, 48, 83, 34, 6, 118, 47, 83, 4, 113, 55, 0, 12, 67, 32, 20, 212, 2, 107, 35, 89, 47, 0, 9, 0, 10, 67, 16, 20, 211, 72, 35, 89, 0, 76, 12, 3, 95, 55, 15, 88, 6, 118, 71, 47, 13, 0, 0, 14, 69, 20, 147, 137, 28, 80, 122, 50, 111, 81, 13, 0, 76, 0, 0, 0, 0, 11, 67, 60, 65, 82, 127, 72, 108, 0, 76, 8, 0, 0, 0, 0, 0, 0, 13, 3, 95, 51, 88, 6, 72, 34, 122, 89, 111, 99, 0, 0, 12, 68, 84, 229, 5, 56, 114, 50, 47, 13, 50, 0, 9, 68, 76, 85, 133, 56, 21, 0, 10, 13, 3, 95, 48, 67, 6, 107, 114, 50, 72, 108, 47, 0, 0, 13, 69, 52, 16, 200, 20, 224, 65, 35, 101, 13, 50, 0, 0, 0, 8, 67, 81, 34, 80, 21, 0, 10, 0, 12, 68, 8, 85, 5, 56, 71, 126, 47, 13, 50, 0, 0, 0, 0, 14, 203, 88, 145, 76, 8, 84, 208, 72, 240, 200, 20, 224, 67, 0, 12, 68, 20, 147, 147, 80, 6, 122, 50, 89, 47, 0, 0, 0, 0, 0, 0, 0, 7, 66, 32, 144, 107, 122, 0, 5, 194, 40, 80, 72, 13, 3, 95, 49, 57, 6, 50, 124, 50, 132, 126, 50, 0, 0, 13, 3, 95, 49, 56, 6, 10, 35, 101, 132, 126, 50, 0, 0, 15, 68, 84, 229, 5, 72, 4, 114, 50, 47, 108, 0, 8, 11, 9, 0, 8, 67, 40, 85, 0, 21, 0, 10, 0, 8, 67, 32, 148, 0, 21, 0, 10, 0, 0, 0, 14, 69, 8, 84, 212, 36, 80, 71, 109, 89, 47, 111, 13, 0, 0, 11, 70, 8, 20, 197, 8, 19, 12, 21, 0, 10, 11, 3, 95, 49, 49, 6, 10, 109, 55, 83, 0, 0, 10, 3, 95, 49, 48, 6, 132, 126, 50, 0, 0, 9, 68, 48, 85, 133, 48, 21, 0, 10, 13, 3, 95, 49, 51, 6, 72, 34, 122, 132, 126, 50, 0, 0, 12, 3, 95, 49, 50, 6, 132, 84, 131, 55, 83, 0, 0, 14, 3, 95, 49, 53, 6, 83, 129, 50, 83, 132, 126, 50, 0, 0, 7, 195, 36, 131, 128, 76, 9, 14, 5, 195, 188, 2, 5, 18, 4, 129, 71, 108, 0, 8, 11, 13, 3, 95, 49, 52, 6, 83, 111, 34, 132, 126, 50, 0, 0, 13, 68, 76, 84, 137, 20, 89, 126, 34, 111, 38, 13, 0, 7, 196, 61, 33, 201, 20, 20, 13, 3, 95, 49, 55, 6, 88, 118, 48, 132, 126, 50, 0, 0, 13, 3, 95, 49, 54, 6, 88, 109, 99, 132, 126, 50, 0, 0, 10, 67, 36, 132, 133, 118, 34, 13, 0, 72, 0, 13, 3, 95, 55, 88, 6, 88, 118, 48, 132, 111, 99, 0, 0, 13, 68, 92, 20, 133, 56, 2, 84, 116, 34, 13, 50, 0, 0, 8, 197, 8, 19, 11, 4, 224, 65, 0, 9, 198, 16, 83, 147, 20, 192, 128, 66, 17, 70, 16, 20, 211, 20, 192, 128, 72, 35, 89, 88, 6, 109, 55, 71, 0, 17, 70, 16, 84, 211, 20, 192, 128, 72, 109, 89, 88, 6, 109, 55, 71, 0, 9, 198, 16, 84, 147, 20, 192, 128, 66, 0, 9, 67, 36, 132, 128, 118, 34, 0, 72, 0, 0, 0, 0, 0, 0, 0, 11, 70, 92, 80, 147, 37, 65, 64, 21, 0, 10, 8, 67, 76, 86, 25, 21, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 69, 48, 20, 20, 61, 0, 21, 0, 10, 14, 3, 95, 50, 88, 6, 132, 84, 35, 50, 132, 111, 99, 0, 0, 0, 0, 0, 10, 199, 36, 211, 79, 8, 147, 9, 20, 20, 0, 12, 3, 95, 56, 15, 10, 6, 35, 101, 47, 13, 0, 0, 0, 15, 70, 36, 226, 193, 37, 48, 200, 111, 68, 49, 116, 111, 91, 0, 0, 11, 67, 76, 82, 84, 88, 122, 47, 0, 72, 9, 0, 0, 0, 11, 70, 24, 148, 133, 92, 19, 12, 21, 0, 10, 0, 0, 9, 68, 77, 21, 65, 92, 21, 0, 10, 13, 3, 95, 63, 63, 88, 129, 65, 71, 6, 127, 55, 0, 0, 0, 0, 13, 3, 95, 52, 88, 6, 83, 111, 34, 132, 111, 99, 0, 0, 0, 10, 69, 77, 2, 82, 37, 64, 21, 0, 10, 0, 0, 11, 136, 11, 15, 13, 195, 182, 4, 9, 5, 20, 6, 195, 92, 82, 76, 8, 0, 0, 14, 69, 20, 147, 136, 21, 32, 122, 50, 107, 6, 126, 34, 0, 0, 8, 66, 52, 48, 65, 14, 49, 0, 8, 66, 32, 208, 107, 13, 65, 0, 0, 14, 3, 95, 53, 88, 6, 83, 129, 50, 83, 132, 111, 99, 0, 0, 14, 68, 8, 85, 143, 72, 71, 13, 83, 127, 34, 0, 66, 8, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 54, 88, 6, 88, 109, 99, 132, 111, 99, 0, 0, 0, 6, 195, 76, 82, 78, 72, 0, 0, 11, 67, 88, 243, 64, 83, 113, 65, 0, 76, 28, 0, 0, 0, 0, 8, 67, 24, 245, 76, 21, 0, 10, 0, 0, 0, 0, 10, 199, 56, 85, 77, 21, 130, 75, 60, 66, 0, 0, 0, 9, 66, 57, 32, 50, 114, 65, 108, 0, 0, 20, 71, 20, 33, 78, 16, 18, 5, 72, 126, 71, 13, 50, 72, 35, 107, 6, 126, 34, 0, 8, 67, 52, 18, 76, 21, 0, 10, 13, 3, 95, 56, 88, 6, 10, 35, 101, 132, 111, 99, 0, 0, 0, 13, 69, 76, 16, 130, 5, 64, 88, 35, 71, 35, 47, 0, 0, 16, 70, 64, 20, 211, 4, 113, 64, 48, 35, 89, 6, 35, 90, 13, 0, 9, 198, 36, 226, 149, 72, 145, 64, 20, 9, 198, 5, 37, 5, 72, 145, 64, 20, 0, 0, 11, 70, 32, 243, 204, 36, 112, 78, 21, 0, 10, 0, 9, 67, 44, 145, 0, 49, 111, 72, 0, 12, 137, 1, 20, 15, 13, 13, 195, 188, 12, 12, 65, 0, 9, 198, 52, 21, 5, 72, 145, 64, 20, 9, 66, 36, 208, 111, 65, 0, 76, 28, 0, 13, 3, 95, 57, 88, 6, 50, 124, 50, 132, 111, 99, 0, 0, 11, 200, 36, 226, 207, 57, 53, 1, 57, 64, 65, 13, 68, 32, 21, 20, 20, 107, 4, 35, 47, 13, 0, 9, 0, 8, 197, 57, 83, 69, 72, 240, 65, 0, 0, 0, 0, 0, 15, 3, 95, 63, 65, 71, 6, 120, 101, 89, 47, 116, 71, 13, 0, 0, 20, 71, 20, 33, 78, 16, 18, 9, 56, 126, 71, 13, 50, 72, 35, 107, 6, 111, 50, 0, 0, 13, 72, 20, 229, 5, 73, 4, 137, 76, 80, 21, 0, 10, 0, 0, 0, 0, 0, 0, 0, 11, 66, 60, 32, 4, 113, 71, 0, 8, 11, 9, 9, 66, 36, 224, 111, 50, 0, 76, 28, 0, 17, 70, 20, 225, 193, 28, 145, 82, 35, 68, 81, 35, 90, 6, 118, 34, 0, 8, 67, 40, 240, 128, 21, 0, 10, 0, 0, 0, 15, 70, 80, 129, 65, 80, 84, 128, 47, 126, 6, 116, 47, 108, 0, 0, 15, 4, 95, 15, 7, 15, 6, 127, 81, 113, 50, 4, 109, 49, 0, 0, 13, 68, 40, 85, 26, 80, 57, 4, 109, 132, 47, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 69, 48, 241, 201, 21, 32, 55, 127, 90, 6, 118, 34, 0, 0, 0, 0, 0, 15, 69, 73, 112, 78, 16, 16, 34, 114, 6, 35, 50, 72, 116, 0, 12, 67, 92, 83, 142, 4, 84, 109, 50, 0, 8, 11, 0, 0, 10, 67, 28, 80, 148, 81, 126, 71, 47, 0, 0, 0, 0, 0, 9, 67, 20, 147, 128, 122, 50, 0, 76, 11, 67, 65, 35, 192, 4, 48, 34, 127, 0, 8, 0, 14, 4, 95, 48, 77, 52, 71, 111, 55, 111, 6, 127, 50, 0, 0, 0, 15, 70, 25, 84, 131, 32, 83, 128, 83, 114, 34, 99, 13, 50, 0, 17, 4, 95, 48, 77, 50, 15, 65, 111, 55, 111, 6, 127, 50, 13, 50, 0, 0, 11, 67, 52, 19, 128, 65, 35, 50, 0, 72, 9, 11, 67, 88, 243, 128, 83, 113, 50, 0, 76, 28, 18, 4, 95, 48, 77, 51, 15, 65, 111, 55, 111, 6, 35, 34, 72, 13, 50, 0, 0, 10, 67, 20, 147, 133, 122, 50, 13, 0, 72, 0, 14, 4, 95, 48, 77, 49, 6, 47, 121, 88, 13, 50, 47, 0, 0, 9, 66, 60, 64, 127, 72, 108, 0, 9, 14, 4, 95, 2, 18, 22, 71, 14, 16, 6, 125, 84, 13, 0, 0, 7, 195, 52, 148, 128, 76, 9, 0, 0, 10, 69, 5, 4, 5, 4, 192, 21, 0, 10, 0, 16, 67, 33, 36, 199, 107, 109, 34, 6, 121, 89, 81, 126, 71, 108, 0, 0, 11, 67, 88, 244, 128, 4, 83, 113, 34, 0, 11, 0, 0, 0, 0, 0, 0, 12, 69, 76, 50, 21, 49, 64, 91, 120, 55, 47, 0, 0, 0, 0, 0, 0, 13, 66, 44, 208, 49, 118, 55, 127, 65, 126, 47, 108, 0, 0, 0, 11, 200, 88, 145, 76, 48, 82, 67, 33, 64, 66, 0, 12, 67, 105, 112, 82, 132, 84, 4, 35, 12, 34, 0, 0, 0, 11, 67, 52, 149, 0, 65, 111, 47, 0, 76, 8, 0, 0, 0, 7, 66, 53, 144, 21, 0, 10, 0, 18, 9, 8, 195, 164, 21, 19, 3, 8, 5, 14, 107, 124, 89, 99, 13, 50, 0, 0, 0, 0, 9, 198, 52, 243, 143, 80, 243, 128, 67, 0, 8, 67, 61, 85, 0, 21, 0, 10, 0, 9, 68, 12, 240, 67, 32, 21, 0, 10, 0, 0, 0, 0, 0, 0, 11, 70, 4, 48, 207, 84, 229, 0, 21, 0, 10, 0, 15, 70, 20, 147, 133, 72, 193, 73, 122, 50, 13, 34, 55, 122, 0, 0, 0, 0, 9, 198, 56, 80, 149, 48, 244, 192, 67, 0, 7, 195, 52, 144, 200, 72, 9, 0, 10, 67, 21, 33, 5, 126, 34, 72, 13, 0, 0, 0, 0, 24, 67, 56, 240, 200, 50, 6, 113, 101, 15, 50, 6, 111, 99, 47, 0, 28, 81, 110, 105, 99, 104, 116, 32, 6, 195, 56, 240, 200, 8, 0, 11, 68, 64, 240, 200, 76, 48, 113, 101, 89, 0, 0, 0, 0, 9, 198, 77, 2, 79, 56, 17, 197, 20, 0, 0, 0, 0, 0, 8, 67, 40, 242, 197, 21, 0, 10, 0, 11, 67, 4, 33, 82, 116, 71, 108, 0, 76, 8, 0, 16, 70, 5, 32, 200, 4, 146, 192, 35, 34, 99, 6, 116, 111, 49, 0, 0, 0, 16, 70, 20, 147, 129, 56, 65, 82, 122, 50, 6, 35, 50, 72, 108, 0, 0, 0, 19, 4, 95, 3, 9, 18, 132, 6, 111, 34, 49, 114, 65, 83, 55, 109, 49, 89, 0, 0, 0, 0, 0, 0, 0, 9, 68, 76, 130, 82, 80, 21, 0, 10, 0, 0, 0, 0, 0, 15, 69, 36, 229, 5, 72, 224, 111, 50, 47, 6, 109, 34, 50, 0, 15, 69, 92, 243, 12, 20, 224, 2, 84, 113, 55, 13, 50, 0, 9, 0, 0, 17, 4, 95, 19, 20, 11, 91, 34, 6, 126, 81, 89, 47, 34, 111, 99, 0, 0, 0, 15, 69, 64, 192, 78, 21, 64, 48, 55, 35, 50, 6, 126, 47, 0, 12, 4, 95, 1, 3, 21, 35, 49, 6, 120, 47, 0, 0, 10, 198, 60, 33, 204, 20, 144, 200, 66, 8, 21, 3, 95, 194, 171, 6, 35, 50, 83, 128, 51, 114, 68, 89, 132, 4, 122, 99, 13, 50, 0, 0, 0, 0, 0, 11, 70, 80, 84, 141, 36, 224, 76, 21, 0, 10, 0, 0, 0, 15, 69, 16, 144, 68, 20, 208, 72, 118, 35, 72, 6, 126, 65, 0, 10, 69, 72, 240, 68, 36, 80, 21, 0, 10, 0, 0, 9, 198, 48, 20, 16, 4, 194, 69, 20, 15, 4, 95, 18, 14, 7, 49, 34, 6, 127, 58, 90, 109, 49, 0, 0, 0, 0, 0, 0, 13, 68, 105, 81, 5, 52, 132, 120, 6, 72, 126, 65, 0, 0, 0, 0, 0, 0, 0, 0, 20, 71, 77, 64, 76, 4, 115, 73, 80, 89, 47, 35, 55, 35, 81, 65, 6, 111, 47, 0, 16, 67, 4, 32, 128, 6, 35, 71, 71, 4, 111, 55, 72, 114, 68, 0, 0, 7, 196, 76, 241, 193, 72, 66, 0, 0, 0, 0, 9, 67, 104, 243, 205, 88, 120, 65, 0, 11, 68, 16, 145, 78, 80, 72, 118, 50, 47, 0, 0, 14, 69, 21, 36, 212, 20, 224, 126, 34, 89, 47, 13, 50, 0, 0, 0, 0, 0, 14, 69, 76, 83, 2, 77, 64, 88, 109, 55, 48, 89, 47, 0, 0, 18, 4, 95, 1, 3, 50, 72, 6, 113, 48, 13, 55, 35, 49, 4, 120, 47, 0, 0, 0, 0, 0, 9, 66, 60, 176, 127, 49, 6, 126, 0, 0, 0, 0, 18, 70, 88, 244, 136, 21, 34, 71, 83, 127, 34, 107, 6, 126, 34, 111, 134, 0, 14, 69, 52, 243, 148, 4, 112, 65, 127, 50, 47, 116, 49, 0, 0, 0, 10, 67, 76, 243, 12, 4, 88, 113, 55, 0, 0, 6, 195, 5, 34, 69, 20, 0, 0, 0, 0, 0, 0, 25, 3, 95, 194, 187, 6, 35, 50, 83, 128, 51, 114, 68, 89, 132, 4, 122, 99, 13, 50, 15, 132, 6, 120, 0, 0, 10, 199, 20, 33, 78, 24, 19, 12, 76, 8, 0, 11, 70, 72, 80, 197, 37, 97, 82, 21, 0, 10, 0, 0, 0, 0, 14, 68, 28, 81, 197, 56, 81, 126, 81, 13, 50, 0, 76, 8, 0, 0, 0, 0, 0, 0, 10, 66, 77, 64, 6, 109, 89, 47, 126, 0, 12, 6, 95, 15, 18, 4, 50, 48, 89, 47, 13, 0, 0, 5, 130, 196, 141, 43, 0, 0, 12, 201, 21, 133, 18, 5, 96, 71, 4, 229, 0, 65, 0, 0, 0, 0, 0, 11, 70, 88, 83, 148, 85, 33, 64, 21, 0, 10, 0, 0, 8, 67, 76, 86, 0, 21, 0, 10, 23, 68, 56, 144, 200, 80, 50, 6, 111, 99, 47, 15, 50, 6, 120, 34, 0, 8, 81, 110, 117, 114, 32, 24, 68, 56, 144, 200, 80, 50, 4, 111, 99, 47, 15, 65, 6, 126, 34, 0, 14, 81, 109, 101, 104, 114, 32, 23, 68, 56, 144, 200, 80, 50, 6, 111, 99, 47, 15, 4, 65, 126, 34, 0, 81, 109, 101, 104, 114, 32, 0, 9, 2, 194, 163, 48, 121, 50, 72, 0, 0, 0, 0, 17, 70, 21, 36, 212, 52, 19, 0, 126, 34, 89, 47, 65, 35, 12, 55, 0, 5, 130, 195, 166, 43, 0, 10, 69, 76, 245, 82, 12, 80, 21, 0, 10, 5, 130, 195, 167, 43, 0, 0, 0, 0, 0, 0, 0, 11, 70, 12, 243, 80, 85, 65, 82, 21, 0, 10, 0, 0, 0, 0, 7, 196, 16, 82, 78, 20, 76, 0, 0, 9, 2, 194, 176, 81, 34, 116, 47, 0, 0, 16, 70, 16, 162, 66, 61, 85, 9, 75, 37, 71, 6, 120, 47, 118, 0, 5, 130, 195, 169, 43, 17, 2, 194, 177, 48, 55, 6, 114, 89, 15, 65, 6, 118, 50, 114, 89, 0, 0, 0, 0, 9, 198, 5, 52, 8, 4, 197, 0, 66, 0, 18, 71, 5, 36, 129, 56, 114, 69, 72, 35, 34, 35, 68, 90, 6, 118, 13, 0, 18, 71, 5, 36, 5, 28, 114, 69, 72, 35, 34, 48, 109, 75, 6, 118, 34, 0, 8, 67, 64, 195, 212, 21, 0, 10, 0, 13, 4, 95, 3, 5, 4, 89, 126, 72, 6, 118, 57, 0, 0, 0, 0, 5, 130, 197, 161, 43, 16, 4, 95, 12, 9, 7, 55, 6, 118, 81, 35, 47, 4, 120, 108, 0, 0, 0, 0, 0, 0, 0, 13, 69, 28, 83, 210, 28, 80, 75, 113, 12, 34, 75, 0, 18, 7, 11, 195, 182, 14, 14, 5, 14, 4, 49, 131, 50, 13, 50, 0, 9, 12, 0, 0, 0, 0, 8, 67, 76, 227, 194, 21, 0, 10, 6, 195, 16, 82, 78, 76, 0, 0, 0, 0, 9, 198, 64, 20, 129, 16, 145, 83, 67, 0, 0, 10, 67, 16, 83, 64, 2, 72, 126, 65, 0, 0, 9, 68, 53, 148, 209, 48, 21, 0, 10, 5, 130, 197, 190, 43, 0, 0, 9, 198, 76, 243, 132, 21, 35, 128, 8, 0, 11, 4, 4, 1, 195, 159, 72, 35, 89, 0, 76, 0, 9, 68, 12, 128, 82, 80, 21, 0, 10, 7, 196, 76, 82, 78, 20, 76, 0, 16, 69, 76, 241, 66, 20, 224, 88, 127, 10, 6, 126, 71, 13, 50, 0, 0, 0, 0, 0, 0, 15, 6, 11, 195, 182, 14, 14, 20, 4, 49, 131, 50, 47, 0, 9, 0, 0, 8, 67, 9, 149, 5, 21, 0, 10, 12, 68, 16, 145, 83, 20, 72, 118, 88, 13, 0, 72, 0, 14, 69, 49, 80, 197, 57, 64, 55, 120, 89, 109, 50, 47, 0, 15, 69, 93, 84, 132, 21, 64, 84, 4, 114, 34, 72, 13, 47, 0, 15, 69, 92, 84, 132, 21, 64, 84, 4, 109, 34, 72, 13, 47, 0, 0, 0, 12, 71, 64, 83, 148, 32, 245, 83, 20, 21, 0, 10, 0, 0, 0, 11, 70, 29, 35, 213, 64, 145, 64, 21, 0, 10, 13, 4, 6, 195, 188, 18, 83, 128, 34, 0, 76, 8, 9, 0, 9, 198, 64, 84, 144, 48, 86, 0, 66, 0, 0, 13, 69, 17, 34, 84, 80, 80, 72, 34, 111, 47, 13, 0, 0, 0, 0, 9, 68, 76, 244, 146, 100, 21, 0, 10, 0, 0, 0, 8, 67, 12, 245, 80, 49, 120, 0, 0, 0, 0, 0, 0, 0, 0, 15, 70, 28, 84, 212, 21, 35, 128, 81, 109, 89, 47, 108, 50, 0, 17, 70, 93, 84, 132, 21, 53, 0, 84, 4, 114, 34, 72, 109, 89, 47, 0, 0, 0, 0, 11, 68, 44, 131, 69, 72, 49, 65, 126, 34, 0, 11, 68, 8, 81, 82, 20, 71, 126, 34, 13, 0, 9, 68, 81, 83, 133, 72, 21, 0, 10, 0, 0, 0, 0, 12, 68, 88, 244, 137, 28, 83, 127, 34, 111, 134, 0, 0, 0, 11, 70, 76, 48, 78, 56, 84, 128, 21, 0, 10, 0, 0, 13, 68, 92, 148, 147, 80, 84, 4, 111, 34, 89, 47, 0, 0, 0, 10, 135, 16, 18, 195, 164, 13, 9, 5, 20, 16, 70, 32, 84, 130, 21, 33, 192, 107, 109, 34, 71, 109, 34, 81, 0, 0, 0, 0, 0, 0, 29, 75, 65, 35, 194, 48, 83, 65, 80, 148, 201, 21, 32, 48, 34, 127, 71, 55, 126, 65, 6, 35, 12, 47, 111, 88, 118, 34, 0, 10, 199, 44, 20, 148, 60, 224, 71, 20, 20, 0, 0, 14, 69, 84, 228, 197, 72, 80, 114, 50, 88, 34, 13, 0, 72, 0, 0, 0, 14, 67, 4, 195, 7, 6, 35, 55, 81, 13, 65, 122, 50, 0, 11, 2, 95, 34, 132, 118, 47, 6, 116, 47, 0, 0, 20, 2, 95, 33, 6, 121, 89, 23, 34, 4, 120, 83, 13, 132, 4, 122, 99, 13, 50, 0, 0, 0, 15, 2, 95, 39, 4, 35, 48, 127, 89, 47, 34, 6, 113, 83, 0, 0, 8, 67, 76, 243, 135, 21, 0, 10, 0, 18, 70, 20, 228, 197, 52, 35, 5, 113, 50, 89, 6, 113, 65, 71, 13, 55, 0, 0, 0, 10, 67, 8, 147, 128, 71, 111, 50, 0, 72, 10, 67, 16, 83, 128, 2, 72, 126, 50, 0, 0, 13, 68, 92, 20, 149, 52, 84, 116, 34, 6, 114, 65, 0, 9, 68, 20, 208, 73, 48, 21, 0, 10, 12, 4, 95, 3, 1, 16, 81, 34, 6, 127, 89, 0, 0, 11, 67, 16, 83, 142, 72, 109, 50, 0, 76, 8, 15, 2, 95, 41, 49, 55, 6, 35, 65, 108, 15, 132, 6, 120, 0, 0, 17, 70, 105, 81, 197, 28, 83, 128, 132, 120, 81, 6, 126, 81, 13, 50, 0, 17, 70, 105, 81, 197, 28, 83, 128, 132, 120, 81, 6, 126, 81, 13, 50, 0, 16, 2, 95, 40, 49, 55, 6, 35, 65, 108, 15, 23, 6, 121, 83, 0, 0, 8, 67, 92, 244, 132, 21, 0, 10, 11, 67, 64, 84, 128, 48, 109, 34, 0, 76, 28, 15, 2, 95, 47, 91, 34, 6, 126, 81, 91, 47, 34, 111, 99, 0, 0, 17, 70, 36, 225, 5, 77, 49, 78, 111, 50, 72, 6, 109, 89, 13, 50, 0, 10, 2, 95, 46, 48, 114, 50, 49, 47, 0, 0, 17, 2, 95, 45, 71, 6, 111, 50, 72, 13, 89, 47, 34, 4, 111, 99, 0, 0, 9, 2, 95, 44, 49, 113, 65, 35, 0, 0, 10, 67, 16, 84, 128, 2, 72, 109, 34, 0, 9, 2, 95, 51, 6, 72, 34, 122, 0, 0, 9, 2, 95, 50, 6, 132, 84, 122, 0, 0, 10, 2, 95, 49, 10, 6, 122, 50, 89, 0, 0, 9, 2, 95, 48, 6, 50, 114, 55, 0, 0, 11, 2, 95, 55, 6, 88, 118, 71, 13, 50, 0, 0, 14, 68, 92, 20, 147, 80, 2, 84, 116, 34, 89, 47, 0, 9, 10, 2, 95, 54, 6, 88, 109, 49, 89, 0, 0, 10, 2, 95, 53, 6, 83, 129, 50, 83, 0, 0, 9, 2, 95, 52, 6, 83, 118, 34, 0, 0, 15, 67, 88, 115, 0, 83, 109, 34, 81, 55, 6, 122, 99, 13, 0, 16, 2, 95, 59, 91, 47, 34, 6, 111, 99, 48, 114, 68, 49, 47, 0, 0, 17, 2, 95, 58, 72, 6, 113, 48, 13, 55, 48, 4, 114, 68, 49, 47, 0, 0, 8, 197, 8, 150, 129, 73, 32, 66, 15, 69, 44, 19, 142, 77, 64, 4, 49, 35, 50, 89, 47, 0, 9, 9, 2, 95, 57, 6, 50, 124, 50, 0, 0, 10, 2, 95, 56, 6, 10, 35, 101, 47, 0, 0, 10, 67, 21, 36, 212, 126, 34, 89, 47, 0, 12, 71, 36, 229, 5, 72, 96, 67, 20, 21, 0, 10, 17, 2, 95, 63, 83, 34, 6, 117, 81, 13, 132, 4, 122, 99, 13, 50, 0, 0, 13, 68, 92, 244, 137, 56, 84, 127, 34, 6, 111, 50, 0, 10, 2, 95, 62, 81, 34, 130, 89, 108, 0, 0, 0, 10, 2, 95, 60, 49, 55, 122, 50, 108, 0, 0, 0, 0, 0, 0, 0, 10, 68, 56, 148, 195, 32, 50, 118, 91, 0, 19, 72, 52, 146, 210, 60, 98, 67, 32, 80, 65, 118, 49, 34, 127, 83, 118, 91, 0, 0, 0, 17, 70, 80, 83, 5, 28, 83, 128, 47, 126, 55, 126, 81, 6, 126, 50, 0, 0, 0, 9, 68, 52, 16, 200, 60, 21, 0, 10, 8, 196, 76, 245, 201, 20, 66, 8, 0, 0, 0, 0, 9, 68, 48, 20, 197, 72, 21, 0, 10, 7, 196, 52, 82, 78, 20, 76, 0, 14, 69, 88, 84, 133, 36, 224, 83, 109, 34, 6, 122, 50, 0, 0, 0, 0, 9, 68, 40, 242, 78, 80, 21, 0, 10, 0, 8, 197, 52, 243, 147, 84, 224, 66, 0, 6, 195, 56, 17, 197, 20, 0, 0, 13, 4, 95, 4, 15, 20, 48, 6, 114, 50, 49, 47, 0, 0, 0, 9, 198, 24, 85, 69, 73, 35, 212, 67, 0, 8, 67, 80, 80, 200, 21, 0, 10, 17, 67, 85, 49, 128, 2, 114, 50, 47, 88, 127, 83, 6, 113, 34, 47, 0, 22, 2, 95, 91, 6, 109, 49, 111, 81, 13, 49, 55, 6, 35, 65, 108, 15, 23, 6, 121, 83, 0, 0, 13, 68, 28, 83, 210, 28, 81, 126, 113, 34, 49, 0, 9, 0, 0, 8, 66, 76, 240, 88, 127, 0, 76, 0, 8, 67, 12, 128, 84, 21, 0, 10, 16, 2, 95, 95, 4, 114, 50, 47, 108, 91, 47, 34, 6, 111, 99, 0, 0, 16, 2, 95, 94, 132, 111, 34, 49, 114, 65, 83, 55, 109, 49, 89, 0, 0, 13, 69, 12, 194, 81, 84, 80, 49, 55, 111, 49, 13, 0, 10, 69, 60, 227, 9, 56, 80, 21, 0, 10, 21, 2, 95, 93, 6, 109, 49, 111, 81, 13, 49, 55, 6, 35, 65, 108, 15, 132, 6, 120, 0, 0, 8, 67, 12, 242, 197, 21, 0, 10, 0, 17, 70, 36, 229, 5, 72, 84, 211, 111, 50, 47, 13, 34, 6, 109, 89, 0, 8, 67, 12, 243, 204, 21, 0, 10, 0, 13, 68, 93, 84, 132, 20, 84, 4, 114, 34, 72, 13, 0, 12, 68, 84, 228, 197, 72, 114, 50, 88, 108, 0, 72, 22, 4, 95, 226, 128, 148, 81, 13, 72, 6, 35, 68, 49, 13, 50, 91, 47, 34, 4, 111, 99, 0, 0, 8, 197, 16, 18, 12, 36, 80, 20, 9, 198, 9, 35, 206, 12, 130, 69, 20, 10, 69, 41, 83, 139, 36, 80, 21, 0, 10, 0, 9, 2, 95, 96, 81, 34, 116, 84, 0, 0, 0, 8, 196, 17, 84, 131, 32, 76, 8, 0, 0, 0, 11, 67, 56, 16, 200, 50, 116, 101, 0, 76, 28, 0, 0, 0, 14, 4, 95, 7, 18, 22, 81, 34, 6, 116, 84, 111, 89, 0, 0, 0, 0, 8, 197, 8, 19, 11, 60, 224, 66, 0, 0, 12, 71, 72, 240, 83, 80, 33, 69, 24, 21, 0, 10, 11, 67, 8, 148, 192, 71, 111, 89, 0, 76, 8, 10, 67, 16, 84, 192, 2, 72, 109, 89, 0, 0, 7, 196, 84, 213, 197, 28, 65, 0, 14, 69, 76, 243, 12, 20, 224, 4, 88, 113, 55, 13, 50, 0, 0, 0, 0, 0, 16, 69, 32, 16, 133, 77, 64, 107, 116, 71, 109, 89, 47, 0, 9, 72, 0, 0, 13, 4, 95, 4, 9, 1, 6, 114, 65, 55, 121, 47, 0, 25, 2, 95, 123, 81, 13, 91, 84, 6, 122, 83, 47, 13, 49, 55, 6, 35, 65, 108, 15, 23, 6, 121, 83, 0, 0, 0, 0, 11, 70, 60, 97, 140, 36, 225, 64, 21, 0, 10, 9, 66, 84, 208, 114, 65, 0, 76, 28, 0, 11, 67, 8, 148, 212, 71, 111, 89, 47, 0, 72, 0, 0, 24, 2, 95, 125, 81, 13, 91, 84, 6, 122, 83, 47, 13, 49, 55, 6, 35, 65, 108, 15, 132, 6, 120, 0, 0, 8, 2, 95, 124, 48, 122, 48, 0, 0, 0, 9, 68, 5, 4, 12, 20, 21, 0, 10, 0, 0, 0, 0, 7, 196, 73, 84, 9, 20, 20, 11, 200, 64, 85, 5, 73, 50, 76, 36, 80, 20, 0, 10, 69, 4, 48, 197, 77, 48, 21, 0, 10, 0, 0, 0, 9, 68, 12, 245, 67, 32, 21, 0, 10, 13, 68, 16, 19, 73, 80, 72, 116, 65, 6, 111, 47, 0, 0, 11, 67, 84, 225, 0, 114, 50, 47, 0, 76, 8, 0, 0, 0, 0, 8, 197, 76, 245, 207, 32, 192, 66, 15, 69, 93, 84, 132, 20, 224, 84, 4, 114, 34, 72, 13, 50, 0, 16, 69, 92, 84, 132, 20, 224, 84, 4, 109, 34, 72, 13, 50, 0, 12, 0, 0, 0, 7, 196, 72, 148, 201, 44, 65, 13, 68, 4, 35, 210, 80, 35, 71, 6, 113, 34, 47, 0, 0, 9, 197, 60, 37, 207, 32, 192, 66, 8, 0, 9, 198, 16, 84, 200, 4, 192, 128, 66, 0, 0, 0, 14, 69, 40, 19, 149, 5, 32, 57, 35, 50, 120, 116, 34, 0, 8, 197, 32, 82, 77, 5, 64, 65, 0, 17, 4, 95, 35, 51, 50, 55, 6, 126, 34, 132, 6, 122, 99, 13, 50, 0, 0, 0, 0, 14, 69, 76, 243, 12, 77, 64, 4, 88, 113, 55, 89, 47, 0, 0, 0, 0, 0, 14, 69, 84, 228, 197, 72, 208, 114, 50, 89, 108, 65, 0, 72, 0, 0, 11, 67, 92, 147, 12, 2, 84, 111, 55, 0, 9, 0, 11, 200, 52, 20, 135, 36, 224, 76, 36, 80, 20, 0, 10, 69, 76, 147, 135, 48, 80, 21, 0, 10, 0, 9, 66, 105, 80, 132, 120, 0, 76, 28, 0, 0, 0, 0, 0, 0, 0, 0, 17, 70, 36, 229, 5, 72, 225, 84, 111, 50, 47, 13, 34, 50, 109, 47, 0, 0, 0, 0, 0, 0, 12, 71, 12, 19, 67, 61, 33, 5, 72, 21, 0, 10, 14, 67, 12, 132, 128, 49, 13, 34, 111, 89, 47, 114, 89, 0, 0, 0, 8, 197, 16, 19, 129, 12, 128, 66, 0, 0, 0, 0, 0, 0, 18, 67, 85, 53, 192, 2, 114, 50, 47, 88, 127, 84, 6, 122, 47, 108, 0, 8, 0, 0, 10, 69, 64, 244, 212, 21, 32, 21, 0, 10, 0, 0, 0, 7, 196, 81, 84, 137, 56, 66, 0, 14, 69, 32, 244, 147, 4, 208, 107, 113, 108, 88, 116, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 71, 36, 195, 5, 28, 149, 9, 52, 111, 55, 126, 81, 118, 47, 6, 118, 65, 0, 0, 0, 0, 0, 8, 67, 8, 32, 192, 21, 0, 10, 0, 0, 0, 0, 0, 8, 67, 12, 144, 79, 76, 121, 0, 8, 67, 76, 131, 215, 21, 0, 10, 9, 68, 24, 246, 69, 72, 21, 0, 10, 0, 0, 0, 7, 195, 92, 145, 64, 72, 8, 0, 0, 8, 197, 76, 241, 143, 73, 64, 66, 0, 11, 70, 52, 84, 211, 4, 113, 64, 21, 0, 10, 0, 10, 67, 76, 145, 64, 88, 118, 0, 72, 9, 0, 0, 10, 69, 13, 84, 147, 61, 32, 21, 0, 10, 0, 8, 66, 92, 240, 84, 4, 127, 0, 0, 0, 0, 8, 197, 29, 32, 90, 36, 80, 20, 0, 0, 20, 73, 5, 84, 199, 21, 48, 200, 4, 213, 0, 121, 89, 81, 13, 91, 116, 65, 47, 0, 0, 12, 68, 28, 84, 212, 20, 81, 126, 89, 47, 13, 0, 0, 0, 0, 9, 67, 80, 243, 64, 47, 113, 65, 0, 19, 71, 8, 19, 132, 4, 114, 69, 72, 71, 35, 50, 72, 35, 90, 6, 118, 13, 0, 10, 67, 44, 19, 64, 4, 49, 116, 65, 0, 0, 0, 0, 16, 70, 49, 81, 84, 37, 48, 200, 55, 120, 6, 126, 47, 111, 91, 0, 0, 0, 7, 196, 25, 84, 137, 20, 20, 0, 0, 16, 70, 56, 16, 200, 16, 83, 64, 50, 35, 101, 72, 6, 126, 65, 0, 0, 0, 9, 68, 48, 241, 201, 56, 21, 0, 10, 0, 0, 0, 11, 67, 4, 196, 192, 35, 55, 89, 0, 76, 28, 0, 6, 195, 4, 196, 207, 8, 0, 6, 195, 52, 82, 78, 76, 0, 0, 0, 0, 0, 11, 70, 76, 50, 69, 56, 49, 64, 21, 0, 10, 0, 0, 0, 0, 15, 70, 76, 84, 150, 36, 49, 64, 89, 109, 34, 84, 111, 89, 0, 9, 198, 8, 192, 77, 4, 113, 64, 20, 0, 0, 0, 0, 16, 70, 36, 195, 15, 100, 19, 0, 111, 55, 113, 35, 57, 116, 55, 0, 0, 0, 9, 198, 77, 80, 138, 20, 181, 0, 65, 0, 8, 197, 20, 33, 78, 76, 240, 65, 0, 0, 0, 0, 6, 18, 66, 108, 0, 114, 0, 7, 6, 18, 67, 99, 0, 102, 0, 104, 0, 107, 0, 112, 0, 113, 0, 115, 0, 116, 0, 122, 0, 7, 6, 18, 68, 195, 164, 0, 97, 0, 7, 6, 18, 69, 195, 182, 0, 111, 0, 7, 6, 99, 104, 0, 4, 1, 117, 102, 2, 115, 3, 49, 0, 2, 111, 114, 32, 0, 2, 111, 114, 100, 0, 2, 195, 182, 114, 0, 8, 2, 18, 66, 17, 65, 0, 8, 2, 111, 0, 97, 114, 97, 2, 107, 116, 3, 49, 2, 35, 34, 35, 0, 114, 111, 3, 49, 34, 127, 0, 115, 3, 49, 89, 0, 115, 116, 117, 1, 97, 119, 2, 109, 3, 49, 89, 47, 120, 0, 105, 112, 2, 32, 3, 76, 111, 48, 0, 4, 8, 2, 97, 3, 91, 0, 8, 2, 105, 99, 0, 8, 2, 105, 102, 0, 8, 2, 105, 108, 0, 97, 110, 99, 101, 3, 91, 138, 89, 13, 0, 4, 3, 99, 0, 1, 117, 101, 0, 1, 117, 164, 195, 0, 8, 2, 17, 65, 0, 4, 101, 110, 1, 17, 67, 2, 32, 14, 128, 128, 132, 3, 99, 13, 50, 0, 101, 110, 1, 101, 2, 32, 0, 101, 110, 1, 164, 195, 2, 32, 0, 101, 110, 1, 188, 195, 2, 32, 0, 115, 1, 164, 195, 110, 2, 116, 3, 99, 89, 0, 4, 1, 97, 3, 101, 0, 1, 101, 114, 98, 2, 101, 110, 0, 1, 111, 0, 1, 117, 0, 7, 6, 103, 101, 0, 8, 2, 111, 114, 103, 3, 81, 2, 126, 0, 111, 8, 3, 81, 4, 126, 127, 0, 4, 1, 115, 103, 110, 117, 2, 17, 67, 21, 3, 81, 13, 0, 2, 109, 97, 99, 104, 0, 2, 109, 97, 108, 0, 2, 114, 195, 164, 116, 0, 2, 116, 114, 0, 8, 2, 21, 14, 128, 132, 130, 0, 8, 2, 105, 109, 112, 0, 8, 2, 111, 114, 14, 128, 132, 130, 0, 98, 105, 114, 103, 101, 2, 32, 14, 128, 128, 135, 3, 81, 13, 71, 111, 34, 81, 13, 0, 4, 2, 114, 109, 97, 110, 3, 81, 109, 0, 2, 115, 116, 114, 105, 103, 0, 8, 2, 18, 66, 25, 0, 8, 2, 109, 25, 0, 8, 2, 110, 25, 0, 8, 2, 110, 101, 114, 0, 105, 2, 12, 3, 81, 122, 0, 4, 8, 2, 98, 101, 29, 3, 81, 126, 0, 104, 8, 2, 101, 29, 0, 104, 101, 110, 3, 81, 126, 13, 50, 0, 110, 101, 114, 97, 108, 2, 105, 115, 3, 81, 126, 50, 13, 34, 35, 55, 0, 110, 101, 114, 97, 108, 3, 81, 126, 50, 109, 34, 6, 35, 55, 0, 98, 101, 110, 3, 81, 126, 71, 13, 50, 0, 4, 103, 101, 110, 3, 81, 126, 81, 13, 50, 0, 103, 101, 110, 8, 2, 21, 14, 128, 132, 133, 0, 103, 110, 3, 81, 126, 81, 50, 0, 7, 6, 105, 101, 0, 4, 1, 10, 2, 114, 32, 3, 6, 118, 0, 1, 10, 2, 114, 108, 105, 99, 104, 0, 1, 21, 2, 32, 0, 1, 21, 2, 114, 101, 29, 0, 2, 114, 115, 21, 0, 4, 110, 1, 103, 21, 2, 32, 3, 6, 118, 13, 50, 0, 110, 1, 104, 112, 2, 32, 0, 110, 1, 109, 21, 2, 32, 0, 110, 1, 112, 21, 2, 32, 0, 110, 1, 114, 101, 115, 2, 32, 0, 110, 1, 114, 101, 116, 116, 2, 32, 0, 110, 1, 114, 111, 101, 2, 32, 0, 110, 1, 114, 111, 103, 2, 32, 0, 110, 1, 114, 116, 101, 2, 32, 0, 110, 1, 114, 116, 115, 117, 100, 2, 32, 0, 110, 1, 115, 21, 2, 32, 0, 110, 1, 116, 21, 2, 32, 0, 114, 117, 110, 103, 3, 6, 118, 34, 114, 68, 0, 114, 117, 110, 103, 115, 3, 6, 118, 34, 114, 68, 89, 0, 4, 1, 21, 2, 32, 28, 17, 3, 8, 111, 13, 0, 1, 100, 117, 116, 115, 2, 32, 0, 1, 108, 97, 109, 114, 111, 102, 0, 1, 108, 105, 109, 97, 102, 0, 1, 108, 111, 102, 2, 32, 0, 1, 114, 101, 102, 2, 110, 0, 1, 114, 101, 116, 107, 97, 98, 0, 110, 1, 10, 2, 32, 3, 8, 111, 13, 50, 0, 110, 115, 1, 10, 2, 32, 3, 8, 111, 38, 13, 50, 89, 0, 4, 110, 1, 98, 10, 2, 32, 3, 8, 118, 13, 50, 0, 110, 1, 114, 10, 2, 32, 0, 1, 117, 2, 114, 32, 3, 23, 6, 118, 0, 1, 10, 2, 108, 108, 32, 3, 111, 6, 109, 0, 110, 116, 2, 32, 3, 111, 6, 109, 50, 47, 0, 110, 122, 1, 10, 2, 32, 3, 111, 6, 109, 50, 132, 0, 4, 1, 99, 110, 97, 110, 105, 102, 2, 114, 3, 111, 6, 126, 0, 1, 103, 121, 104, 2, 110, 0, 1, 107, 110, 97, 98, 2, 114, 0, 1, 108, 97, 116, 105, 2, 110, 0, 1, 108, 101, 116, 111, 104, 2, 114, 0, 1, 109, 101, 114, 112, 2, 114, 0, 1, 114, 114, 97, 2, 114, 0, 1, 114, 114, 97, 98, 2, 114, 0, 1, 110, 105, 2, 32, 3, 111, 13, 0, 110, 1, 110, 10, 2, 32, 3, 111, 13, 50, 0, 110, 1, 114, 2, 21, 3, 111, 109, 50, 0, 4, 3, 118, 0, 1, 104, 99, 115, 2, 110, 0, 104, 0, 110, 115, 116, 1, 100, 3, 118, 50, 89, 47, 0, 7, 6, 195, 159, 0, 3, 89, 0, 8, 2, 32, 3, 109, 89, 132, 109, 47, 0, 7, 6, 195, 164, 0, 2, 117, 109, 32, 24, 3, 6, 125, 0, 116, 1, 116, 2, 32, 3, 6, 125, 47, 0, 4, 2, 17, 67, 11, 3, 109, 0, 2, 17, 67, 17, 67, 0, 2, 115, 99, 104, 0, 117, 3, 124, 0, 4, 3, 125, 0, 104, 2, 12, 0, 98, 2, 116, 32, 3, 125, 48, 0, 103, 2, 116, 32, 3, 125, 49, 0, 7, 6, 195, 182, 0, 2, 32, 3, 6, 130, 0, 4, 3, 130, 0, 104, 2, 12, 0, 4, 2, 17, 67, 11, 3, 131, 0, 2, 17, 67, 17, 67, 0, 2, 115, 99, 104, 0, 7, 6, 195, 188, 0, 98, 101, 114, 8, 2, 98, 101, 21, 14, 128, 132, 132, 3, 11, 6, 128, 71, 108, 0, 98, 101, 114, 8, 2, 21, 14, 128, 132, 132, 3, 23, 4, 128, 71, 108, 0, 4, 3, 128, 0, 104, 2, 12, 0, 98, 2, 116, 32, 3, 128, 48, 0, 103, 2, 116, 32, 3, 128, 49, 0, 98, 101, 114, 8, 2, 103, 97, 110, 103, 115, 3, 128, 71, 108, 0, 4, 2, 17, 67, 11, 3, 129, 0, 2, 17, 67, 17, 67, 0, 2, 115, 99, 104, 0, 2, 120, 0, 7, 6, 97, 0, 114, 99, 104, 97, 8, 2, 105, 3, 2, 35, 34, 99, 117, 0, 116, 111, 8, 2, 109, 3, 2, 35, 47, 127, 0, 4, 98, 8, 2, 110, 111, 114, 3, 2, 35, 48, 0, 98, 8, 2, 115, 111, 0, 98, 8, 2, 115, 111, 114, 0, 98, 8, 2, 115, 116, 114, 0, 98, 8, 2, 115, 117, 114, 0, 107, 113, 117, 3, 2, 35, 49, 84, 0, 110, 8, 2, 97, 3, 2, 35, 50, 0, 110, 105, 8, 2, 115, 3, 2, 35, 50, 118, 0, 98, 98, 8, 2, 97, 3, 2, 35, 71, 0, 117, 115, 116, 114, 97, 2, 108, 3, 2, 121, 89, 47, 34, 117, 0, 112, 112, 101, 8, 2, 108, 108, 21, 3, 4, 35, 48, 109, 0, 110, 116, 104, 114, 111, 112, 111, 8, 3, 4, 35, 50, 47, 34, 127, 48, 2, 127, 0, 110, 116, 105, 8, 2, 21, 14, 128, 132, 132, 3, 4, 35, 50, 47, 111, 0, 110, 116, 105, 8, 2, 21, 14, 128, 132, 132, 3, 4, 35, 50, 47, 118, 0, 110, 105, 109, 8, 3, 4, 35, 50, 118, 65, 0, 110, 105, 109, 97, 108, 8, 3, 4, 35, 50, 118, 65, 116, 55, 0, 110, 103, 108, 111, 8, 2, 21, 3, 4, 35, 68, 81, 55, 127, 0, 4, 108, 1, 110, 97, 107, 10, 2, 32, 3, 4, 116, 55, 0, 108, 1, 110, 103, 105, 115, 10, 2, 32, 0, 1, 114, 103, 2, 109, 109, 32, 3, 6, 35, 0, 98, 8, 2, 101, 114, 21, 14, 128, 132, 130, 3, 6, 35, 48, 0, 98, 122, 117, 8, 2, 21, 14, 128, 132, 132, 3, 6, 35, 48, 132, 120, 0, 4, 99, 104, 115, 8, 2, 21, 14, 128, 132, 132, 3, 6, 35, 49, 89, 0, 99, 104, 115, 8, 2, 101, 108, 0, 4, 110, 1, 110, 105, 101, 2, 100, 101, 114, 3, 6, 35, 50, 0, 110, 8, 2, 21, 14, 128, 132, 130, 0, 110, 8, 2, 110, 18, 68, 104, 14, 128, 132, 130, 0, 110, 8, 2, 110, 97, 100, 14, 128, 132, 130, 0, 110, 116, 1, 21, 2, 32, 3, 6, 35, 50, 47, 0, 108, 108, 101, 114, 8, 2, 21, 14, 128, 132, 133, 3, 6, 35, 55, 13, 34, 0, 4, 1, 21, 2, 98, 101, 108, 32, 3, 6, 116, 0, 1, 21, 2, 98, 108, 32, 0, 2, 17, 67, 111, 32, 0, 2, 114, 99, 104, 32, 0, 8, 2, 110, 97, 116, 105, 111, 14, 128, 132, 129, 0, 4, 114, 1, 108, 21, 2, 32, 3, 6, 116, 34, 0, 114, 1, 116, 21, 2, 32, 0, 114, 105, 101, 114, 2, 32, 24, 3, 6, 116, 34, 118, 108, 0, 116, 1, 21, 2, 32, 3, 6, 116, 47, 0, 116, 105, 115, 99, 104, 1, 21, 2, 32, 14, 128, 128, 134, 3, 6, 116, 47, 111, 91, 0, 110, 1, 21, 2, 32, 3, 6, 116, 50, 0, 110, 105, 101, 114, 2, 32, 24, 3, 6, 116, 50, 118, 108, 0, 4, 108, 1, 17, 65, 21, 2, 32, 3, 6, 116, 55, 0, 108, 1, 98, 2, 32, 0, 108, 1, 103, 2, 32, 0, 108, 1, 107, 2, 32, 0, 108, 1, 110, 2, 32, 0, 108, 1, 114, 2, 32, 0, 108, 1, 116, 2, 32, 0, 109, 1, 114, 101, 107, 2, 105, 107, 3, 6, 116, 65, 0, 4, 103, 101, 2, 32, 28, 17, 3, 6, 116, 90, 13, 0, 103, 101, 2, 110, 32, 28, 33, 0, 110, 99, 101, 1, 115, 2, 32, 3, 6, 138, 89, 0, 110, 99, 101, 1, 114, 102, 2, 32, 3, 6, 138, 89, 13, 0, 110, 99, 101, 110, 1, 115, 2, 32, 3, 6, 138, 89, 13, 50, 0, 1, 17, 67, 17, 67, 10, 2, 32, 3, 8, 116, 0, 4, 98, 8, 2, 17, 67, 21, 14, 128, 132, 130, 3, 11, 6, 35, 48, 0, 98, 8, 2, 17, 67, 21, 14, 128, 132, 130, 0, 98, 8, 2, 195, 164, 14, 128, 132, 130, 0, 117, 102, 8, 2, 21, 14, 128, 132, 131, 3, 11, 6, 121, 83, 0, 117, 115, 8, 2, 21, 14, 128, 132, 131, 3, 11, 6, 121, 89, 0, 105, 114, 8, 3, 21, 0, 4, 2, 17, 67, 11, 3, 35, 0, 2, 17, 67, 17, 67, 0, 2, 105, 115, 105, 101, 114, 0, 2, 115, 99, 104, 0, 2, 116, 105, 111, 110, 0, 2, 120, 0, 100, 8, 2, 106, 117, 3, 35, 47, 0, 4, 98, 8, 2, 105, 3, 35, 48, 0, 98, 8, 2, 106, 0, 98, 8, 2, 115, 101, 0, 98, 8, 2, 115, 122, 0, 98, 8, 2, 111, 114, 3, 35, 48, 23, 0, 98, 100, 8, 2, 12, 3, 35, 48, 72, 0, 4, 110, 8, 2, 100, 101, 114, 3, 35, 50, 0, 110, 8, 2, 116, 101, 110, 0, 110, 8, 2, 116, 104, 0, 110, 8, 2, 116, 119, 0, 110, 110, 8, 0, 110, 97, 116, 104, 8, 3, 35, 50, 35, 47, 0, 110, 104, 101, 105, 109, 8, 2, 17, 67, 21, 14, 128, 132, 134, 3, 35, 50, 107, 6, 122, 65, 0, 110, 103, 108, 105, 8, 2, 17, 67, 3, 35, 68, 81, 55, 118, 0, 98, 98, 8, 2, 114, 101, 118, 3, 35, 71, 0, 98, 101, 114, 114, 8, 3, 35, 71, 23, 109, 34, 0, 99, 8, 2, 101, 116, 3, 35, 132, 0, 101, 2, 17, 67, 17, 67, 3, 109, 0, 105, 110, 1, 114, 116, 3, 109, 50, 0, 4, 1, 108, 21, 2, 103, 3, 116, 0, 1, 108, 99, 115, 2, 103, 0, 1, 114, 112, 115, 2, 99, 104, 0, 1, 115, 2, 103, 0, 1, 115, 2, 109, 32, 0, 1, 115, 2, 109, 107, 101, 105, 116, 0, 2, 17, 67, 32, 0, 2, 32, 0, 2, 112, 104, 0, 8, 2, 32, 0, 97, 0, 104, 2, 12, 0, 116, 105, 115, 105, 101, 114, 101, 110, 1, 21, 2, 32, 14, 128, 128, 137, 3, 116, 47, 111, 89, 6, 118, 34, 13, 50, 0, 98, 2, 116, 32, 3, 116, 48, 0, 4, 103, 1, 106, 2, 100, 3, 116, 49, 0, 103, 1, 108, 104, 99, 115, 2, 103, 101, 0, 103, 2, 116, 32, 0, 1, 109, 2, 108, 116, 32, 3, 116, 55, 0, 98, 101, 110, 8, 2, 100, 3, 116, 71, 13, 50, 0, 101, 108, 3, 116, 109, 55, 0, 105, 2, 115, 99, 104, 3, 116, 111, 0, 3, 117, 0, 4, 117, 3, 121, 0, 117, 8, 2, 17, 67, 101, 105, 110, 97, 110, 100, 0, 117, 104, 2, 32, 0, 117, 116, 104, 101, 110, 8, 3, 121, 47, 109, 50, 0, 117, 102, 101, 110, 116, 8, 3, 121, 83, 13, 50, 47, 0, 117, 115, 8, 2, 107, 117, 3, 121, 89, 0, 4, 105, 3, 122, 0, 121, 0, 4, 105, 114, 1, 109, 2, 32, 3, 122, 108, 0, 121, 114, 1, 109, 2, 32, 0, 4, 121, 1, 112, 3, 123, 0, 121, 2, 32, 24, 0, 101, 3, 125, 0, 105, 114, 2, 32, 3, 125, 34, 0, 7, 6, 98, 0, 1, 98, 3, 0, 4, 97, 98, 121, 3, 21, 0, 105, 107, 101, 8, 0, 108, 117, 101, 8, 0, 111, 97, 114, 100, 0, 111, 111, 109, 8, 0, 4, 2, 18, 67, 3, 48, 0, 2, 32, 24, 0, 8, 111, 2, 17, 67, 0, 116, 2, 32, 24, 3, 48, 47, 0, 4, 3, 71, 0, 2, 115, 17, 65, 0, 8, 2, 18, 66, 17, 65, 0, 8, 2, 101, 17, 68, 17, 67, 0, 8, 2, 101, 98, 17, 67, 0, 8, 2, 101, 99, 17, 67, 0, 8, 2, 101, 101, 116, 0, 8, 2, 101, 110, 122, 105, 110, 0, 8, 2, 101, 114, 17, 67, 0, 8, 2, 101, 115, 101, 110, 0, 8, 2, 101, 115, 115, 0, 8, 2, 101, 115, 116, 101, 110, 0, 8, 2, 101, 117, 103, 0, 8, 2, 101, 117, 108, 0, 8, 2, 101, 117, 116, 0, 8, 2, 106, 17, 65, 0, 4, 97, 8, 2, 108, 17, 65, 3, 71, 2, 35, 0, 97, 8, 2, 108, 108, 21, 0, 105, 115, 8, 2, 104, 14, 128, 132, 131, 3, 71, 2, 111, 89, 0, 101, 111, 8, 2, 98, 3, 71, 4, 13, 127, 0, 117, 110, 100, 101, 115, 8, 3, 71, 6, 114, 50, 72, 13, 89, 0, 101, 105, 8, 3, 71, 6, 122, 0, 4, 101, 1, 110, 101, 17, 67, 10, 2, 17, 67, 21, 3, 71, 13, 0, 101, 1, 115, 103, 110, 117, 2, 17, 67, 21, 0, 101, 2, 114, 101, 105, 99, 104, 0, 101, 8, 2, 21, 14, 128, 132, 130, 0, 101, 8, 2, 105, 110, 104, 14, 128, 132, 130, 0, 101, 8, 2, 17, 67, 11, 3, 71, 109, 0, 101, 115, 116, 105, 97, 3, 71, 109, 89, 47, 118, 6, 116, 0, 97, 114, 1, 10, 2, 32, 14, 128, 128, 131, 3, 71, 116, 34, 0, 97, 114, 101, 1, 10, 2, 32, 14, 128, 128, 132, 3, 71, 116, 34, 13, 0, 97, 114, 101, 110, 1, 10, 2, 32, 14, 128, 128, 133, 3, 71, 116, 34, 13, 50, 0, 97, 114, 101, 109, 1, 10, 2, 32, 14, 128, 128, 133, 3, 71, 116, 34, 13, 65, 0, 97, 114, 101, 115, 1, 10, 2, 32, 14, 128, 128, 133, 3, 71, 116, 34, 13, 89, 0, 97, 114, 101, 114, 1, 10, 2, 32, 14, 128, 128, 133, 3, 71, 116, 34, 108, 0, 101, 105, 103, 101, 8, 2, 21, 3, 71, 122, 81, 13, 0, 8, 2, 32, 3, 71, 126, 0, 101, 116, 101, 110, 3, 71, 126, 47, 13, 50, 0, 101, 105, 103, 101, 8, 2, 32, 3, 71, 126, 91, 0, 111, 2, 115, 104, 3, 71, 127, 0, 7, 6, 99, 0, 1, 99, 3, 0, 4, 111, 97, 116, 2, 32, 3, 21, 0, 111, 119, 8, 0, 114, 101, 119, 0, 117, 112, 0, 4, 3, 49, 0, 8, 2, 18, 66, 17, 65, 0, 107, 0, 111, 109, 112, 117, 116, 101, 114, 8, 2, 21, 14, 128, 132, 128, 3, 49, 113, 65, 48, 57, 6, 120, 47, 108, 0, 111, 100, 101, 8, 3, 49, 127, 47, 0, 4, 2, 105, 101, 3, 89, 0, 2, 121, 0, 121, 98, 101, 114, 8, 3, 89, 122, 71, 108, 0, 8, 2, 32, 3, 89, 126, 0, 104, 101, 102, 2, 32, 3, 91, 109, 83, 0, 4, 1, 97, 102, 2, 101, 116, 3, 132, 0, 1, 97, 108, 112, 2, 105, 101, 0, 8, 2, 101, 108, 0, 8, 2, 101, 110, 116, 0, 101, 121, 8, 3, 132, 122, 0, 7, 6, 100, 0, 1, 100, 3, 0, 4, 101, 97, 108, 8, 3, 21, 0, 101, 115, 105, 103, 110, 0, 103, 101, 2, 32, 0, 114, 105, 118, 101, 0, 114, 117, 103, 8, 0, 4, 2, 18, 67, 3, 47, 0, 2, 32, 24, 0, 100, 116, 0, 116, 0, 4, 3, 72, 0, 1, 110, 117, 111, 115, 0, 2, 115, 17, 65, 0, 8, 2, 114, 17, 65, 0, 8, 2, 115, 99, 104, 17, 65, 0, 8, 2, 115, 104, 17, 65, 0, 4, 117, 114, 99, 104, 8, 2, 98, 3, 72, 2, 114, 34, 99, 0, 117, 114, 99, 104, 8, 2, 102, 0, 117, 114, 99, 104, 8, 2, 107, 114, 0, 117, 114, 99, 104, 8, 2, 108, 97, 0, 117, 114, 99, 104, 8, 2, 115, 99, 104, 97, 117, 0, 117, 114, 99, 104, 8, 2, 115, 116, 0, 117, 114, 99, 104, 8, 2, 115, 117, 0, 117, 114, 99, 104, 8, 2, 116, 114, 101, 0, 117, 114, 99, 104, 8, 2, 119, 0, 117, 114, 99, 104, 113, 117, 101, 8, 3, 72, 2, 114, 34, 99, 49, 84, 126, 0, 105, 118, 101, 114, 8, 3, 72, 2, 118, 84, 109, 34, 0, 4, 101, 8, 2, 105, 107, 14, 128, 132, 130, 3, 72, 2, 126, 0, 101, 8, 2, 105, 110, 115, 116, 97, 14, 128, 132, 130, 0, 105, 97, 8, 3, 72, 4, 118, 35, 0, 97, 116, 101, 110, 8, 2, 21, 14, 128, 132, 133, 3, 72, 6, 35, 47, 13, 50, 0, 111, 114, 116, 8, 2, 17, 67, 21, 14, 128, 132, 132, 3, 72, 6, 113, 34, 47, 0, 4, 117, 114, 99, 104, 8, 2, 21, 14, 128, 132, 133, 3, 72, 6, 114, 34, 99, 0, 117, 114, 99, 104, 8, 2, 119, 97, 99, 104, 14, 128, 132, 133, 0, 117, 114, 99, 104, 119, 101, 103, 8, 3, 72, 114, 34, 99, 84, 126, 49, 0, 97, 98, 101, 105, 8, 2, 14, 128, 132, 133, 3, 72, 116, 6, 71, 122, 0, 97, 114, 97, 110, 8, 2, 14, 128, 132, 133, 3, 72, 116, 34, 6, 35, 50, 0, 97, 114, 105, 110, 8, 2, 14, 128, 132, 133, 3, 72, 116, 34, 6, 111, 50, 0, 97, 114, 117, 110, 116, 101, 114, 8, 2, 14, 128, 132, 136, 3, 72, 116, 34, 6, 114, 50, 47, 13, 34, 0, 97, 114, 117, 109, 8, 2, 14, 128, 132, 133, 3, 72, 116, 34, 6, 114, 65, 0, 97, 114, 97, 117, 102, 8, 2, 14, 128, 132, 134, 3, 72, 116, 34, 6, 121, 83, 0, 97, 114, 97, 117, 115, 8, 2, 14, 128, 132, 134, 3, 72, 116, 34, 6, 121, 89, 0, 97, 114, 101, 105, 110, 8, 2, 14, 128, 132, 134, 3, 72, 116, 34, 6, 122, 50, 0, 97, 114, 195, 188, 98, 101, 114, 8, 2, 14, 128, 132, 135, 3, 72, 116, 34, 6, 128, 71, 13, 34, 0, 97, 110, 101, 98, 101, 110, 8, 2, 14, 128, 132, 135, 3, 72, 116, 50, 6, 126, 71, 13, 50, 0, 97, 118, 111, 110, 8, 2, 14, 128, 132, 133, 3, 72, 116, 83, 6, 113, 50, 0, 97, 118, 111, 114, 8, 2, 14, 128, 132, 133, 3, 72, 116, 83, 6, 127, 34, 0, 97, 102, 195, 188, 114, 8, 2, 14, 128, 132, 133, 3, 72, 116, 83, 6, 129, 34, 0, 97, 104, 101, 114, 8, 2, 14, 128, 132, 133, 3, 72, 116, 107, 6, 109, 34, 0, 97, 104, 105, 110, 8, 2, 14, 128, 132, 133, 3, 72, 116, 107, 6, 111, 50, 0, 97, 104, 105, 110, 116, 101, 114, 8, 2, 14, 128, 132, 136, 3, 72, 116, 107, 6, 111, 50, 47, 108, 0, 97, 122, 117, 8, 2, 14, 128, 132, 132, 3, 72, 116, 132, 6, 120, 0, 4, 8, 2, 32, 3, 72, 126, 0, 101, 8, 2, 105, 102, 0, 101, 109, 101, 8, 3, 72, 126, 65, 109, 0, 4, 101, 109, 111, 2, 103, 3, 72, 126, 65, 127, 0, 101, 109, 111, 2, 107, 0, 115, 2, 32, 3, 132, 0, 7, 6, 101, 0, 8, 2, 102, 102, 3, 2, 109, 0, 114, 111, 98, 8, 2, 101, 114, 3, 2, 109, 34, 127, 71, 0, 109, 112, 8, 2, 105, 114, 3, 2, 109, 65, 48, 0, 109, 112, 104, 8, 2, 21, 3, 2, 109, 65, 83, 0, 117, 114, 8, 2, 111, 112, 3, 2, 124, 0, 8, 2, 108, 101, 107, 3, 2, 126, 0, 110, 101, 8, 2, 114, 103, 3, 2, 126, 50, 109, 0, 110, 100, 111, 8, 2, 21, 3, 4, 109, 50, 72, 127, 0, 105, 1, 114, 102, 10, 2, 32, 3, 4, 122, 0, 112, 105, 8, 2, 21, 3, 4, 126, 48, 118, 0, 4, 1, 10, 2, 110, 122, 25, 3, 6, 109, 0, 1, 21, 2, 107, 116, 32, 0, 1, 21, 2, 112, 116, 32, 0, 114, 115, 116, 8, 2, 17, 67, 14, 128, 132, 132, 3, 6, 109, 34, 89, 47, 0, 116, 116, 1, 21, 2, 32, 3, 6, 109, 47, 0, 4, 110, 100, 8, 2, 17, 67, 21, 14, 128, 132, 131, 3, 6, 109, 50, 47, 0, 110, 116, 1, 21, 2, 32, 0, 110, 116, 1, 109, 21, 2, 32, 0, 110, 116, 1, 116, 97, 112, 0, 110, 116, 101, 1, 109, 21, 2, 32, 3, 6, 109, 50, 47, 13, 0, 108, 108, 2, 32, 3, 6, 109, 55, 0, 105, 1, 21, 2, 32, 3, 6, 122, 0, 4, 105, 108, 8, 2, 97, 14, 128, 132, 131, 3, 6, 122, 55, 0, 105, 108, 8, 2, 102, 14, 128, 132, 131, 0, 105, 115, 101, 110, 8, 2, 21, 14, 128, 132, 133, 3, 6, 122, 88, 13, 50, 0, 4, 1, 108, 2, 103, 32, 3, 6, 126, 0, 101, 1, 104, 2, 32, 0, 114, 2, 111, 32, 3, 6, 126, 34, 0, 101, 110, 2, 32, 3, 6, 126, 42, 0, 109, 1, 10, 2, 32, 3, 6, 126, 65, 0, 117, 109, 2, 32, 3, 6, 126, 114, 65, 0, 117, 114, 1, 21, 2, 32, 3, 6, 130, 34, 0, 117, 115, 101, 2, 32, 3, 6, 130, 88, 13, 0, 117, 115, 101, 110, 2, 32, 3, 6, 130, 88, 13, 50, 0, 114, 117, 110, 103, 1, 10, 2, 32, 3, 8, 13, 34, 114, 68, 0, 110, 104, 97, 102, 116, 1, 21, 2, 32, 3, 8, 13, 50, 107, 35, 83, 47, 0, 117, 109, 1, 21, 21, 2, 32, 3, 8, 126, 114, 65, 0, 105, 110, 8, 2, 21, 14, 128, 132, 131, 3, 11, 6, 122, 50, 0, 4, 1, 10, 2, 32, 14, 128, 128, 129, 3, 13, 0, 1, 10, 2, 108, 116, 32, 0, 1, 116, 21, 2, 32, 14, 128, 128, 129, 0, 4, 114, 1, 10, 2, 105, 103, 32, 3, 13, 34, 0, 114, 1, 10, 2, 105, 103, 115, 116, 0, 114, 1, 21, 2, 32, 14, 128, 128, 130, 0, 114, 101, 1, 10, 2, 32, 14, 128, 128, 131, 3, 13, 34, 13, 0, 114, 101, 110, 1, 10, 2, 32, 14, 128, 128, 132, 3, 13, 34, 13, 50, 0, 114, 101, 109, 1, 10, 2, 32, 14, 128, 128, 132, 3, 13, 34, 13, 65, 0, 114, 101, 115, 1, 10, 2, 32, 14, 128, 128, 132, 3, 13, 34, 13, 89, 0, 114, 101, 114, 1, 10, 2, 32, 14, 128, 128, 132, 3, 13, 34, 108, 0, 114, 105, 110, 1, 10, 2, 32, 3, 13, 34, 111, 50, 0, 4, 114, 105, 115, 99, 104, 1, 10, 2, 32, 3, 13, 34, 111, 91, 0, 114, 105, 115, 99, 104, 1, 21, 21, 0, 116, 1, 10, 2, 32, 14, 128, 128, 130, 3, 13, 47, 0, 4, 110, 1, 10, 2, 116, 117, 109, 3, 13, 50, 0, 110, 1, 21, 2, 32, 14, 128, 128, 130, 0, 4, 110, 100, 1, 10, 2, 32, 24, 14, 128, 128, 131, 3, 13, 50, 47, 0, 110, 100, 1, 114, 101, 105, 2, 32, 24, 14, 128, 128, 131, 0, 110, 116, 108, 105, 99, 104, 1, 21, 3, 13, 50, 47, 55, 2, 111, 99, 0, 4, 110, 100, 1, 10, 2, 32, 3, 13, 50, 72, 0, 110, 100, 1, 114, 101, 105, 2, 32, 0, 110, 100, 101, 1, 10, 2, 32, 14, 128, 128, 132, 3, 13, 50, 72, 13, 0, 110, 100, 101, 110, 1, 10, 2, 32, 14, 128, 128, 133, 3, 13, 50, 72, 13, 50, 0, 110, 100, 101, 109, 1, 10, 2, 32, 14, 128, 128, 133, 3, 13, 50, 72, 13, 65, 0, 110, 100, 101, 115, 1, 10, 2, 32, 14, 128, 128, 133, 3, 13, 50, 72, 13, 89, 0, 110, 100, 101, 114, 1, 10, 2, 32, 14, 128, 128, 133, 3, 13, 50, 72, 108, 0, 108, 1, 10, 2, 32, 3, 13, 55, 0, 108, 110, 100, 1, 10, 2, 32, 3, 13, 55, 50, 72, 0, 109, 1, 10, 2, 32, 24, 14, 128, 128, 130, 3, 13, 65, 0, 115, 1, 21, 2, 32, 14, 128, 128, 130, 3, 13, 89, 0, 115, 116, 1, 10, 2, 32, 14, 128, 128, 131, 3, 13, 89, 47, 0, 115, 116, 101, 1, 10, 2, 32, 14, 128, 128, 132, 3, 13, 89, 47, 13, 0, 115, 116, 101, 110, 1, 10, 2, 32, 14, 128, 128, 133, 3, 13, 89, 47, 13, 50, 0, 115, 116, 101, 109, 1, 10, 2, 32, 14, 128, 128, 133, 3, 13, 89, 47, 13, 65, 0, 115, 116, 101, 115, 1, 10, 2, 32, 14, 128, 128, 133, 3, 13, 89, 47, 13, 89, 0, 115, 116, 101, 114, 1, 10, 2, 32, 14, 128, 128, 133, 3, 13, 89, 47, 108, 0, 110, 116, 101, 114, 116, 8, 3, 21, 0, 114, 8, 2, 21, 14, 128, 132, 130, 3, 23, 2, 109, 34, 0, 114, 115, 8, 2, 116, 114, 12, 3, 23, 2, 109, 34, 91, 0, 110, 116, 8, 2, 21, 14, 128, 132, 131, 3, 23, 2, 109, 50, 47, 0, 109, 112, 8, 2, 21, 14, 128, 132, 131, 3, 23, 2, 109, 65, 48, 0, 105, 110, 2, 97, 110, 100, 3, 23, 2, 122, 50, 0, 108, 110, 1, 10, 2, 32, 24, 14, 128, 128, 129, 3, 50, 0, 114, 1, 21, 2, 17, 67, 3, 108, 0, 4, 1, 21, 2, 110, 115, 105, 3, 109, 0, 1, 21, 2, 114, 110, 17, 67, 0, 1, 21, 2, 114, 114, 0, 1, 21, 2, 114, 116, 105, 0, 1, 21, 21, 2, 107, 116, 32, 0, 1, 100, 111, 109, 2, 108, 21, 0, 1, 109, 2, 110, 116, 0, 2, 17, 67, 11, 0, 2, 17, 67, 17, 67, 0, 2, 115, 99, 104, 0, 2, 120, 0, 114, 1, 10, 2, 114, 32, 0, 4, 114, 1, 21, 2, 118, 3, 109, 34, 0, 114, 1, 100, 111, 109, 2, 110, 0, 114, 1, 112, 120, 101, 2, 116, 0, 114, 1, 119, 2, 107, 32, 0, 114, 8, 2, 17, 68, 17, 67, 0, 114, 8, 2, 98, 101, 25, 0, 114, 8, 2, 103, 105, 101, 0, 114, 103, 101, 98, 8, 2, 110, 105, 115, 3, 109, 34, 81, 6, 126, 71, 0, 4, 110, 1, 116, 2, 116, 3, 109, 50, 0, 110, 1, 117, 113, 2, 116, 17, 65, 0, 110, 116, 8, 2, 101, 114, 3, 109, 50, 47, 0, 110, 116, 101, 110, 8, 3, 109, 50, 47, 13, 50, 0, 109, 115, 1, 114, 98, 3, 109, 65, 89, 0, 99, 104, 111, 3, 109, 99, 127, 0, 1, 10, 2, 17, 66, 17, 66, 32, 3, 110, 0, 110, 1, 10, 2, 21, 3, 110, 50, 0, 108, 1, 10, 2, 21, 3, 110, 55, 0, 4, 105, 3, 122, 0, 105, 1, 108, 114, 2, 32, 0, 105, 104, 2, 32, 0, 121, 0, 105, 110, 101, 8, 2, 114, 21, 3, 122, 50, 13, 0, 105, 110, 105, 103, 8, 3, 122, 50, 111, 81, 0, 105, 114, 1, 109, 2, 32, 3, 122, 108, 0, 4, 117, 3, 124, 0, 117, 1, 104, 2, 115, 101, 12, 12, 0, 117, 1, 108, 104, 99, 115, 2, 115, 0, 4, 3, 126, 0, 1, 108, 108, 2, 108, 0, 1, 114, 107, 2, 105, 101, 114, 0, 1, 115, 2, 108, 105, 103, 0, 2, 103, 116, 32, 12, 0, 2, 112, 104, 0, 8, 2, 32, 0, 101, 0, 104, 2, 12, 0, 121, 2, 32, 0, 4, 114, 2, 100, 32, 3, 126, 34, 0, 114, 2, 100, 105, 103, 0, 98, 2, 116, 32, 3, 126, 48, 0, 112, 105, 8, 2, 115, 107, 3, 126, 48, 111, 0, 103, 2, 116, 32, 3, 126, 49, 0, 110, 1, 21, 2, 105, 3, 126, 50, 0, 110, 101, 114, 103, 105, 101, 8, 3, 126, 50, 109, 34, 81, 6, 118, 0, 108, 101, 107, 116, 114, 111, 8, 2, 21, 14, 128, 132, 135, 3, 126, 55, 6, 109, 49, 47, 34, 127, 0, 108, 101, 110, 8, 3, 126, 55, 109, 50, 0, 115, 101, 110, 1, 21, 2, 32, 3, 126, 88, 13, 50, 0, 7, 6, 102, 0, 1, 102, 3, 0, 114, 101, 101, 8, 3, 21, 0, 4, 3, 83, 0, 8, 2, 18, 66, 17, 65, 0, 8, 2, 106, 111, 114, 100, 0, 97, 107, 115, 8, 2, 105, 3, 83, 2, 35, 49, 88, 0, 101, 117, 100, 97, 108, 8, 3, 83, 2, 124, 72, 116, 55, 0, 97, 114, 98, 8, 2, 17, 67, 21, 14, 128, 132, 132, 3, 83, 6, 35, 34, 48, 0, 97, 114, 98, 8, 2, 108, 21, 14, 128, 132, 132, 3, 83, 6, 35, 34, 71, 0, 101, 114, 116, 105, 103, 8, 2, 17, 67, 21, 14, 128, 132, 134, 3, 83, 6, 109, 34, 47, 37, 99, 0, 101, 115, 116, 8, 2, 21, 14, 128, 132, 132, 3, 83, 6, 109, 89, 47, 0, 101, 105, 110, 8, 2, 21, 14, 128, 132, 132, 3, 83, 6, 122, 50, 0, 114, 111, 104, 8, 2, 21, 14, 128, 132, 132, 3, 83, 34, 6, 127, 0, 114, 101, 118, 8, 3, 83, 34, 126, 83, 0, 114, 111, 104, 108, 111, 99, 107, 8, 3, 83, 34, 127, 55, 6, 113, 49, 0, 97, 114, 99, 8, 3, 83, 35, 34, 89, 0, 108, 117, 103, 8, 3, 83, 55, 6, 120, 81, 0, 117, 110, 103, 8, 2, 17, 65, 3, 83, 114, 68, 81, 0, 101, 117, 101, 114, 8, 2, 21, 3, 83, 124, 13, 34, 0, 111, 116, 111, 3, 83, 127, 47, 127, 0, 8, 2, 32, 3, 109, 83, 0, 7, 6, 103, 0, 2, 103, 3, 0, 4, 104, 116, 1, 21, 2, 32, 3, 21, 0, 114, 101, 101, 110, 0, 117, 105, 100, 101, 0, 4, 2, 18, 67, 3, 49, 0, 2, 32, 24, 0, 117, 101, 2, 32, 0, 4, 100, 2, 32, 24, 3, 49, 47, 0, 116, 1, 105, 101, 2, 32, 0, 116, 101, 116, 2, 32, 3, 49, 47, 13, 47, 0, 116, 101, 115, 116, 3, 49, 47, 13, 89, 47, 0, 4, 3, 81, 0, 2, 115, 17, 65, 0, 8, 2, 18, 66, 17, 65, 0, 8, 2, 101, 17, 68, 17, 67, 0, 104, 8, 2, 17, 65, 0, 195, 188, 116, 101, 8, 2, 21, 14, 128, 132, 132, 3, 81, 6, 128, 47, 13, 0, 8, 2, 110, 17, 65, 3, 81, 14, 0, 110, 1, 17, 66, 2, 17, 65, 3, 81, 14, 50, 0, 114, 97, 112, 104, 2, 32, 3, 81, 34, 6, 116, 83, 0, 114, 97, 112, 104, 3, 81, 34, 117, 83, 0, 8, 2, 32, 3, 81, 126, 0, 1, 97, 115, 115, 97, 109, 3, 90, 0, 116, 1, 105, 2, 32, 3, 99, 47, 0, 7, 6, 104, 0, 1, 104, 3, 0, 105, 103, 104, 8, 3, 21, 0, 4, 3, 107, 0, 1, 104, 99, 0, 105, 101, 114, 8, 2, 21, 3, 107, 2, 118, 34, 0, 101, 114, 111, 8, 3, 107, 2, 126, 34, 127, 0, 4, 105, 110, 116, 101, 114, 8, 2, 21, 3, 107, 4, 111, 50, 47, 108, 0, 105, 110, 116, 101, 114, 8, 2, 21, 14, 128, 132, 134, 0, 111, 109, 111, 103, 101, 110, 3, 107, 4, 127, 65, 127, 81, 126, 50, 0, 97, 110, 100, 8, 2, 17, 67, 14, 128, 132, 132, 3, 107, 6, 35, 50, 47, 0, 101, 114, 122, 8, 2, 101, 114, 21, 14, 128, 132, 132, 3, 107, 6, 109, 34, 132, 0, 105, 110, 103, 101, 8, 2, 21, 14, 128, 132, 133, 3, 107, 6, 111, 50, 81, 13, 0, 105, 108, 102, 8, 2, 21, 14, 128, 132, 132, 3, 107, 6, 111, 55, 83, 0, 105, 108, 102, 101, 8, 2, 21, 14, 128, 132, 133, 3, 107, 6, 111, 55, 83, 13, 0, 105, 108, 102, 115, 8, 2, 21, 14, 128, 132, 133, 3, 107, 6, 111, 55, 83, 89, 0, 97, 117, 112, 116, 8, 2, 21, 21, 14, 128, 132, 133, 3, 107, 6, 121, 48, 47, 0, 97, 117, 115, 8, 2, 21, 14, 128, 132, 132, 3, 107, 6, 121, 89, 0, 111, 99, 104, 8, 2, 21, 14, 128, 132, 132, 3, 107, 6, 127, 101, 0, 121, 112, 101, 114, 8, 2, 21, 14, 128, 132, 133, 3, 107, 6, 128, 48, 108, 0, 97, 110, 100, 8, 2, 108, 117, 110, 103, 3, 107, 35, 50, 72, 0, 101, 114, 97, 110, 8, 2, 14, 128, 132, 133, 3, 107, 109, 34, 6, 35, 50, 0, 101, 114, 97, 98, 8, 2, 14, 128, 132, 133, 3, 107, 109, 34, 6, 35, 71, 0, 101, 114, 98, 101, 105, 8, 2, 14, 128, 132, 134, 3, 107, 109, 34, 6, 71, 122, 0, 101, 114, 117, 110, 116, 101, 114, 8, 2, 14, 128, 132, 136, 3, 107, 109, 34, 6, 114, 50, 47, 108, 0, 101, 114, 117, 109, 8, 2, 14, 128, 132, 133, 3, 107, 109, 34, 6, 114, 65, 0, 101, 114, 97, 117, 102, 8, 2, 14, 128, 132, 134, 3, 107, 109, 34, 6, 121, 83, 0, 101, 114, 97, 117, 115, 8, 2, 14, 128, 132, 134, 3, 107, 109, 34, 6, 121, 89, 0, 101, 114, 101, 105, 110, 8, 2, 14, 128, 132, 134, 3, 107, 109, 34, 6, 122, 50, 0, 101, 114, 195, 188, 98, 101, 114, 8, 2, 14, 128, 132, 135, 3, 107, 109, 34, 6, 128, 71, 108, 0, 101, 114, 118, 111, 114, 8, 2, 14, 128, 132, 134, 3, 107, 109, 34, 83, 6, 127, 34, 0, 105, 110, 97, 110, 8, 2, 14, 128, 132, 133, 3, 107, 111, 50, 6, 35, 50, 0, 105, 110, 97, 98, 8, 2, 14, 128, 132, 133, 3, 107, 111, 50, 6, 35, 71, 0, 105, 110, 117, 110, 116, 101, 114, 8, 2, 14, 128, 132, 136, 3, 107, 111, 50, 6, 114, 50, 47, 108, 0, 105, 110, 117, 109, 8, 2, 14, 128, 132, 133, 3, 107, 111, 50, 6, 114, 65, 0, 105, 110, 97, 117, 102, 8, 2, 14, 128, 132, 134, 3, 107, 111, 50, 6, 121, 83, 0, 105, 110, 97, 117, 115, 8, 2, 14, 128, 132, 134, 3, 107, 111, 50, 6, 121, 89, 0, 105, 110, 101, 105, 110, 8, 2, 14, 128, 132, 134, 3, 107, 111, 50, 6, 122, 50, 0, 105, 110, 195, 188, 98, 101, 114, 8, 2, 14, 128, 132, 135, 3, 107, 111, 50, 6, 128, 71, 108, 0, 105, 110, 103, 101, 103, 101, 110, 8, 3, 107, 111, 50, 81, 6, 126, 81, 13, 50, 0, 105, 110, 119, 101, 103, 8, 2, 14, 128, 132, 134, 3, 107, 111, 50, 84, 6, 126, 81, 0, 105, 110, 122, 117, 8, 2, 14, 128, 132, 133, 3, 107, 111, 50, 132, 6, 120, 0, 8, 2, 32, 3, 107, 116, 0, 111, 99, 104, 3, 107, 127, 101, 0, 7, 6, 105, 0, 8, 2, 108, 108, 117, 3, 2, 111, 0, 110, 8, 2, 107, 3, 2, 111, 50, 0, 2, 100, 101, 101, 3, 2, 118, 0, 108, 108, 101, 103, 8, 3, 4, 111, 55, 126, 81, 0, 116, 1, 21, 2, 32, 24, 3, 6, 111, 47, 0, 115, 2, 109, 117, 115, 32, 3, 6, 111, 89, 0, 115, 116, 1, 21, 2, 32, 3, 6, 111, 89, 47, 0, 4, 1, 21, 2, 98, 101, 108, 32, 3, 6, 118, 0, 1, 21, 2, 98, 108, 32, 0, 1, 114, 2, 110, 97, 32, 0, 1, 115, 21, 2, 118, 32, 0, 1, 116, 21, 2, 118, 32, 0, 2, 17, 67, 111, 32, 0, 2, 100, 32, 0, 2, 108, 32, 0, 116, 101, 1, 21, 2, 32, 3, 6, 118, 47, 13, 0, 4, 107, 1, 21, 2, 101, 108, 32, 3, 6, 118, 49, 0, 107, 1, 114, 98, 2, 32, 0, 107, 1, 115, 2, 32, 0, 107, 1, 116, 105, 108, 111, 112, 0, 4, 110, 1, 21, 2, 111, 32, 3, 6, 118, 50, 0, 110, 1, 108, 2, 32, 0, 110, 1, 109, 2, 32, 0, 110, 1, 115, 2, 32, 0, 110, 1, 122, 2, 32, 0, 115, 99, 104, 1, 10, 2, 32, 3, 8, 111, 91, 0, 4, 1, 17, 67, 17, 67, 10, 2, 32, 3, 8, 118, 0, 2, 101, 114, 105, 110, 0, 107, 1, 116, 21, 2, 32, 3, 8, 118, 49, 0, 109, 1, 10, 2, 111, 32, 3, 8, 118, 65, 0, 117, 109, 1, 10, 2, 32, 3, 8, 118, 114, 65, 0, 103, 104, 2, 25, 3, 21, 0, 111, 110, 1, 103, 2, 32, 3, 37, 6, 127, 50, 0, 111, 110, 1, 21, 2, 32, 3, 57, 6, 127, 50, 0, 4, 1, 21, 2, 97, 116, 32, 3, 111, 0, 1, 21, 2, 110, 103, 0, 1, 107, 2, 108, 32, 0, 2, 17, 67, 11, 0, 2, 17, 67, 17, 67, 0, 2, 115, 99, 104, 0, 2, 120, 0, 8, 2, 109, 97, 103, 0, 107, 1, 114, 21, 2, 32, 3, 111, 49, 0, 110, 116, 101, 114, 8, 3, 111, 50, 47, 13, 34, 0, 115, 1, 21, 2, 32, 3, 111, 89, 0, 4, 111, 3, 111, 127, 0, 111, 1, 21, 2, 110, 0, 103, 1, 21, 2, 12, 3, 111, 134, 0, 4, 3, 118, 0, 2, 112, 104, 0, 8, 2, 32, 0, 104, 2, 12, 0, 2, 105, 3, 118, 11, 0, 116, 195, 164, 116, 1, 21, 2, 32, 14, 128, 128, 132, 3, 118, 47, 6, 125, 47, 0, 98, 2, 116, 32, 3, 118, 48, 0, 107, 2, 111, 32, 3, 118, 49, 0, 110, 1, 10, 2, 32, 3, 119, 50, 0, 7, 6, 106, 0, 3, 57, 0, 8, 2, 32, 3, 57, 113, 47, 0, 7, 6, 107, 0, 1, 107, 3, 0, 4, 3, 49, 0, 8, 2, 18, 66, 17, 65, 0, 8, 2, 104, 97, 0, 8, 2, 110, 17, 65, 0, 97, 2, 114, 116, 111, 102, 102, 3, 49, 2, 35, 0, 4, 111, 8, 2, 109, 112, 3, 49, 2, 113, 0, 111, 8, 2, 110, 21, 0, 111, 108, 108, 101, 103, 3, 49, 2, 113, 55, 126, 81, 0, 111, 109, 109, 101, 8, 2, 17, 67, 21, 3, 49, 2, 113, 65, 109, 0, 4, 111, 8, 2, 109, 112, 111, 115, 116, 3, 49, 113, 0, 111, 8, 2, 110, 116, 101, 114, 0, 8, 2, 32, 3, 49, 116, 0, 111, 2, 101, 21, 3, 49, 127, 0, 7, 6, 108, 0, 1, 108, 3, 0, 101, 98, 8, 2, 17, 67, 21, 21, 14, 128, 132, 131, 3, 6, 55, 126, 48, 0, 97, 100, 121, 3, 21, 0, 3, 55, 0, 97, 110, 100, 8, 2, 17, 67, 21, 14, 128, 132, 132, 3, 55, 6, 35, 50, 47, 0, 97, 110, 100, 101, 115, 8, 2, 21, 14, 128, 132, 134, 3, 55, 6, 35, 50, 72, 13, 89, 0, 4, 97, 110, 103, 8, 2, 17, 67, 21, 14, 128, 132, 132, 3, 55, 6, 35, 68, 0, 97, 110, 103, 8, 2, 116, 21, 0, 97, 110, 103, 115, 97, 109, 3, 55, 6, 35, 68, 88, 116, 65, 0, 101, 114, 110, 8, 2, 21, 21, 14, 128, 132, 132, 3, 55, 6, 109, 34, 50, 0, 117, 102, 116, 8, 2, 17, 67, 14, 128, 132, 132, 3, 55, 6, 114, 83, 47, 0, 101, 105, 116, 8, 2, 21, 14, 128, 132, 132, 3, 55, 6, 122, 47, 0, 101, 104, 114, 8, 2, 17, 67, 21, 14, 128, 132, 132, 3, 55, 6, 126, 34, 0, 111, 1, 21, 2, 103, 105, 115, 99, 104, 3, 55, 6, 127, 0, 101, 120, 105, 8, 2, 21, 3, 55, 109, 49, 89, 118, 0, 101, 98, 8, 2, 17, 67, 3, 55, 126, 48, 0, 101, 98, 101, 110, 8, 2, 100, 105, 103, 3, 55, 126, 71, 6, 109, 50, 0, 8, 2, 32, 3, 109, 55, 0, 105, 99, 104, 1, 10, 2, 32, 14, 128, 128, 132, 3, 139, 111, 99, 0, 105, 99, 104, 117, 110, 103, 1, 10, 2, 32, 14, 128, 128, 135, 3, 139, 111, 99, 2, 114, 68, 0, 105, 99, 104, 101, 1, 10, 2, 32, 14, 128, 128, 133, 3, 139, 111, 99, 13, 0, 105, 99, 104, 101, 114, 101, 1, 10, 2, 32, 14, 128, 128, 135, 3, 139, 111, 99, 13, 34, 13, 0, 105, 99, 104, 101, 114, 101, 110, 1, 10, 2, 32, 14, 128, 128, 136, 3, 139, 111, 99, 13, 34, 13, 50, 0, 105, 99, 104, 101, 114, 101, 109, 1, 10, 2, 32, 14, 128, 128, 136, 3, 139, 111, 99, 13, 34, 13, 65, 0, 105, 99, 104, 101, 114, 101, 115, 1, 10, 2, 32, 14, 128, 128, 136, 3, 139, 111, 99, 13, 34, 13, 89, 0, 105, 99, 104, 101, 114, 101, 114, 1, 10, 2, 32, 14, 128, 128, 136, 3, 139, 111, 99, 13, 34, 13, 108, 0, 105, 99, 104, 101, 110, 1, 10, 2, 32, 14, 128, 128, 134, 3, 139, 111, 99, 13, 50, 0, 105, 99, 104, 101, 109, 1, 10, 2, 32, 14, 128, 128, 134, 3, 139, 111, 99, 13, 65, 0, 105, 99, 104, 101, 115, 1, 10, 2, 32, 14, 128, 128, 134, 3, 139, 111, 99, 13, 89, 0, 105, 99, 104, 107, 101, 105, 116, 1, 10, 2, 32, 14, 128, 128, 136, 3, 139, 111, 99, 49, 122, 47, 0, 105, 99, 104, 115, 116, 101, 1, 10, 2, 32, 14, 128, 128, 135, 3, 139, 111, 99, 89, 47, 13, 0, 105, 99, 104, 115, 116, 101, 114, 1, 10, 2, 32, 14, 128, 128, 136, 3, 139, 111, 99, 89, 47, 13, 34, 0, 105, 99, 104, 115, 116, 101, 110, 1, 10, 2, 32, 14, 128, 128, 136, 3, 139, 111, 99, 89, 47, 13, 50, 0, 105, 99, 104, 115, 116, 101, 109, 1, 10, 2, 32, 14, 128, 128, 136, 3, 139, 111, 99, 89, 47, 13, 65, 0, 105, 99, 104, 115, 116, 101, 115, 1, 10, 2, 32, 14, 128, 128, 136, 3, 139, 111, 99, 89, 47, 13, 89, 0, 105, 99, 104, 101, 114, 1, 10, 2, 32, 14, 128, 128, 134, 3, 139, 111, 99, 108, 0, 7, 6, 109, 0, 1, 109, 3, 0, 4, 105, 99, 114, 111, 8, 3, 21, 0, 115, 8, 0, 4, 3, 65, 0, 8, 2, 110, 101, 109, 0, 111, 8, 2, 114, 98, 3, 65, 2, 113, 0, 117, 115, 105, 107, 3, 65, 2, 120, 88, 118, 49, 0, 4, 101, 116, 8, 2, 97, 108, 108, 3, 65, 2, 126, 47, 0, 101, 116, 104, 8, 0, 101, 110, 97, 103, 8, 3, 65, 2, 126, 50, 116, 90, 0, 105, 107, 114, 111, 8, 2, 21, 14, 128, 132, 133, 3, 65, 4, 118, 49, 34, 127, 0, 101, 116, 114, 111, 8, 2, 21, 14, 128, 132, 133, 3, 65, 4, 126, 47, 34, 127, 0, 111, 110, 111, 8, 2, 21, 3, 65, 4, 127, 50, 127, 0, 101, 195, 159, 8, 2, 21, 14, 128, 132, 131, 3, 65, 6, 109, 89, 0, 105, 116, 8, 2, 14, 128, 132, 131, 3, 65, 6, 111, 47, 0, 105, 101, 116, 8, 2, 17, 67, 21, 14, 128, 132, 132, 3, 65, 6, 118, 47, 0, 101, 116, 101, 114, 3, 65, 6, 126, 47, 108, 0, 111, 116, 111, 114, 8, 3, 65, 6, 127, 47, 127, 34, 0, 97, 110, 99, 104, 8, 3, 65, 35, 50, 99, 0, 97, 110, 97, 103, 101, 114, 3, 65, 35, 50, 109, 75, 108, 34, 0, 105, 116, 116, 3, 65, 111, 47, 0, 105, 116, 116, 2, 101, 105, 108, 3, 65, 111, 47, 47, 0, 97, 114, 105, 110, 101, 3, 65, 116, 34, 6, 118, 50, 13, 0, 8, 2, 32, 3, 109, 65, 0, 7, 6, 110, 0, 1, 110, 3, 0, 4, 99, 101, 2, 32, 3, 21, 0, 99, 101, 115, 2, 32, 0, 101, 115, 115, 1, 10, 2, 32, 24, 0, 101, 119, 115, 0, 3, 50, 0, 4, 111, 114, 100, 2, 18, 69, 115, 116, 3, 50, 2, 113, 34, 47, 0, 111, 114, 100, 2, 119, 101, 115, 116, 0, 97, 8, 2, 116, 195, 188, 114, 3, 50, 2, 116, 0, 101, 98, 101, 110, 101, 105, 110, 97, 2, 110, 100, 3, 50, 4, 126, 71, 13, 50, 23, 122, 50, 6, 35, 0, 101, 98, 101, 110, 8, 2, 21, 14, 128, 132, 133, 3, 50, 6, 126, 71, 13, 50, 0, 107, 2, 17, 65, 3, 50, 49, 0, 103, 1, 111, 2, 101, 3, 50, 81, 0, 97, 116, 117, 114, 8, 2, 17, 67, 21, 14, 128, 132, 133, 3, 50, 116, 47, 6, 120, 34, 0, 105, 101, 100, 101, 114, 3, 50, 118, 72, 108, 0, 4, 101, 8, 2, 98, 3, 50, 126, 0, 101, 8, 2, 103, 0, 4, 101, 103, 108, 105, 103, 3, 50, 126, 81, 55, 118, 90, 0, 101, 103, 108, 105, 103, 101, 0, 103, 3, 68, 0, 4, 107, 3, 68, 49, 0, 107, 1, 117, 102, 0, 4, 103, 1, 111, 2, 17, 65, 3, 68, 81, 0, 103, 1, 117, 2, 105, 0, 103, 2, 114, 0, 8, 2, 32, 3, 109, 50, 0, 7, 6, 111, 0, 98, 8, 2, 106, 101, 107, 3, 2, 113, 48, 0, 110, 1, 114, 116, 105, 122, 3, 6, 39, 50, 0, 114, 116, 115, 8, 2, 21, 14, 128, 132, 132, 3, 6, 113, 34, 132, 0, 4, 1, 17, 65, 21, 2, 110, 32, 3, 6, 127, 0, 1, 21, 2, 103, 32, 0, 1, 21, 2, 103, 105, 110, 32, 0, 2, 17, 67, 111, 32, 0, 2, 108, 32, 0, 2, 109, 32, 0, 114, 101, 110, 1, 10, 2, 32, 3, 6, 127, 34, 13, 50, 0, 98, 115, 116, 8, 2, 114, 101, 14, 128, 132, 132, 3, 6, 127, 48, 89, 47, 0, 110, 101, 2, 32, 3, 6, 127, 50, 13, 0, 110, 101, 110, 2, 32, 3, 6, 127, 50, 13, 50, 0, 115, 111, 2, 32, 3, 6, 127, 88, 127, 0, 115, 116, 101, 114, 8, 3, 6, 127, 89, 47, 13, 34, 0, 1, 17, 67, 17, 67, 10, 2, 32, 3, 8, 127, 0, 114, 1, 116, 10, 2, 32, 3, 8, 127, 34, 0, 98, 101, 114, 8, 2, 21, 14, 128, 132, 132, 3, 23, 4, 127, 71, 108, 0, 101, 110, 1, 21, 2, 32, 14, 128, 128, 129, 3, 50, 0, 4, 2, 17, 67, 11, 3, 113, 0, 2, 17, 67, 17, 67, 0, 2, 115, 99, 104, 0, 2, 120, 0, 114, 99, 104, 101, 115, 3, 113, 34, 49, 109, 89, 0, 4, 111, 1, 21, 2, 32, 3, 120, 0, 111, 1, 114, 2, 109, 0, 111, 1, 122, 2, 109, 0, 117, 0, 121, 2, 25, 3, 124, 0, 4, 3, 127, 0, 1, 116, 115, 2, 115, 115, 0, 2, 108, 111, 32, 0, 2, 108, 115, 97, 109, 0, 2, 112, 104, 0, 8, 2, 32, 0, 8, 110, 2, 101, 0, 104, 2, 12, 0, 111, 0, 101, 2, 32, 3, 127, 13, 0, 98, 2, 116, 32, 3, 127, 48, 0, 103, 2, 116, 32, 3, 127, 49, 0, 98, 101, 114, 8, 2, 101, 29, 3, 127, 71, 13, 34, 0, 98, 101, 114, 8, 2, 115, 116, 101, 3, 127, 71, 108, 0, 103, 101, 110, 1, 116, 2, 32, 3, 127, 81, 6, 126, 50, 0, 101, 3, 130, 0, 101, 2, 17, 67, 17, 67, 3, 131, 0, 7, 6, 112, 0, 1, 112, 3, 0, 114, 111, 8, 2, 21, 3, 2, 48, 34, 127, 0, 111, 111, 108, 3, 21, 0, 4, 3, 48, 0, 8, 2, 18, 66, 17, 65, 0, 8, 2, 110, 101, 117, 0, 8, 2, 115, 17, 65, 0, 8, 2, 116, 111, 108, 0, 97, 114, 116, 101, 105, 3, 48, 2, 35, 34, 47, 122, 0, 97, 107, 101, 2, 116, 3, 48, 2, 35, 49, 126, 0, 101, 114, 102, 101, 8, 2, 107, 3, 48, 2, 109, 34, 83, 109, 0, 101, 114, 115, 111, 110, 3, 48, 2, 109, 34, 88, 127, 50, 0, 117, 8, 2, 101, 3, 48, 2, 120, 0, 4, 111, 2, 101, 109, 3, 48, 2, 127, 0, 111, 2, 101, 116, 0, 111, 8, 2, 108, 105, 116, 0, 97, 114, 97, 8, 2, 21, 3, 48, 4, 35, 34, 35, 0, 101, 114, 105, 111, 8, 3, 48, 4, 126, 34, 111, 127, 0, 101, 114, 105, 8, 3, 48, 4, 126, 34, 118, 0, 101, 114, 105, 112, 104, 101, 8, 3, 48, 4, 126, 34, 118, 83, 126, 0, 111, 108, 121, 8, 2, 21, 14, 128, 132, 132, 3, 48, 4, 127, 55, 128, 0, 111, 108, 105, 107, 8, 3, 48, 6, 127, 55, 118, 49, 0, 114, 111, 98, 108, 101, 109, 3, 48, 34, 2, 127, 71, 55, 126, 65, 0, 114, 101, 195, 159, 8, 2, 21, 14, 128, 132, 132, 3, 48, 34, 6, 109, 89, 0, 114, 105, 110, 122, 105, 112, 105, 101, 110, 8, 2, 21, 14, 128, 132, 137, 3, 48, 34, 111, 50, 132, 6, 118, 48, 111, 13, 0, 114, 105, 109, 195, 164, 114, 8, 2, 14, 128, 132, 134, 3, 48, 34, 118, 65, 6, 125, 34, 0, 114, 105, 118, 97, 116, 8, 2, 21, 14, 128, 132, 134, 3, 48, 34, 118, 84, 6, 116, 47, 0, 114, 111, 98, 101, 8, 3, 48, 34, 127, 71, 13, 0, 97, 115, 115, 97, 103, 105, 101, 3, 48, 35, 89, 35, 90, 6, 118, 0, 115, 121, 99, 104, 111, 8, 2, 21, 14, 128, 132, 134, 3, 48, 89, 4, 128, 99, 127, 0, 115, 121, 99, 104, 111, 8, 2, 116, 105, 3, 48, 89, 128, 99, 6, 127, 0, 101, 114, 115, 111, 110, 101, 110, 8, 2, 21, 14, 128, 132, 136, 3, 48, 109, 34, 88, 6, 127, 50, 13, 50, 0, 111, 119, 101, 114, 3, 48, 121, 13, 34, 0, 8, 2, 32, 3, 48, 126, 0, 111, 108, 121, 103, 111, 110, 8, 2, 21, 14, 128, 132, 135, 3, 48, 127, 55, 128, 81, 6, 127, 50, 0, 111, 101, 115, 105, 101, 3, 48, 127, 126, 88, 6, 118, 0, 4, 104, 3, 83, 0, 104, 8, 2, 17, 65, 0, 104, 8, 2, 18, 66, 17, 65, 0, 104, 111, 116, 111, 8, 3, 83, 4, 127, 47, 127, 0, 104, 105, 108, 105, 101, 3, 83, 6, 118, 55, 118, 0, 104, 116, 104, 8, 2, 17, 65, 3, 83, 47, 0, 4, 102, 8, 2, 17, 65, 3, 133, 0, 102, 8, 2, 18, 66, 17, 65, 0, 7, 6, 113, 0, 117, 101, 1, 21, 2, 32, 3, 8, 49, 0, 117, 101, 110, 1, 21, 2, 32, 3, 8, 49, 13, 50, 0, 3, 49, 0, 117, 3, 49, 84, 0, 8, 2, 32, 3, 49, 120, 0, 7, 6, 114, 0, 2, 114, 3, 0, 4, 3, 34, 0, 1, 98, 0, 104, 8, 2, 17, 65, 0, 101, 118, 101, 114, 115, 3, 34, 2, 126, 84, 109, 34, 89, 0, 101, 115, 115, 111, 117, 114, 99, 3, 34, 109, 89, 6, 114, 34, 89, 0, 97, 110, 103, 105, 101, 114, 3, 34, 116, 68, 90, 6, 118, 34, 0, 101, 8, 2, 100, 3, 34, 126, 0, 8, 2, 32, 3, 109, 34, 0, 7, 6, 115, 0, 4, 97, 102, 101, 8, 3, 21, 0, 104, 111, 112, 0, 107, 121, 8, 0, 112, 101, 101, 100, 0, 116, 114, 101, 101, 116, 8, 0, 116, 121, 108, 101, 0, 121, 110, 116, 104, 101, 115, 105, 0, 4, 1, 17, 65, 2, 32, 3, 88, 0, 2, 17, 65, 0, 2, 32, 0, 101, 114, 118, 105, 99, 101, 2, 32, 14, 128, 128, 135, 3, 88, 2, 109, 34, 84, 118, 89, 0, 111, 108, 100, 97, 116, 3, 88, 2, 113, 55, 72, 116, 47, 0, 4, 195, 188, 100, 2, 18, 69, 115, 116, 3, 88, 2, 128, 47, 0, 195, 188, 100, 2, 119, 101, 115, 116, 0, 121, 115, 116, 101, 109, 3, 88, 2, 129, 89, 47, 126, 65, 0, 101, 99, 104, 115, 8, 2, 14, 128, 132, 133, 3, 88, 6, 109, 49, 89, 0, 101, 108, 98, 115, 116, 8, 2, 21, 21, 14, 128, 132, 134, 3, 88, 6, 109, 55, 48, 89, 47, 0, 101, 107, 117, 2, 110, 100, 101, 110, 3, 88, 126, 49, 6, 114, 0, 4, 3, 89, 0, 1, 17, 65, 2, 32, 24, 0, 1, 107, 2, 105, 0, 1, 112, 2, 97, 0, 1, 112, 2, 105, 0, 1, 116, 2, 105, 0, 2, 32, 24, 14, 128, 128, 129, 0, 2, 115, 121, 115, 116, 101, 109, 0, 8, 2, 99, 17, 65, 0, 8, 2, 99, 114, 0, 8, 2, 107, 17, 65, 0, 8, 2, 107, 18, 66, 17, 65, 0, 8, 2, 108, 17, 65, 0, 8, 2, 109, 17, 65, 0, 8, 2, 110, 17, 65, 0, 8, 2, 112, 104, 17, 65, 0, 8, 2, 112, 108, 101, 110, 100, 0, 8, 2, 113, 117, 17, 65, 0, 8, 2, 118, 101, 0, 8, 2, 119, 17, 65, 0, 8, 2, 122, 17, 65, 0, 115, 0, 115, 1, 117, 97, 116, 115, 0, 111, 2, 114, 116, 32, 3, 89, 23, 113, 0, 4, 116, 1, 17, 67, 10, 2, 32, 14, 128, 128, 130, 3, 89, 47, 0, 116, 1, 110, 10, 2, 32, 0, 116, 2, 117, 110, 103, 0, 116, 8, 2, 105, 108, 17, 65, 0, 116, 101, 1, 17, 67, 10, 2, 32, 14, 128, 128, 131, 3, 89, 47, 13, 0, 116, 101, 110, 1, 17, 67, 10, 2, 32, 14, 128, 128, 132, 3, 89, 47, 13, 50, 0, 116, 101, 109, 1, 17, 67, 10, 2, 32, 14, 128, 128, 132, 3, 89, 47, 13, 65, 0, 116, 101, 115, 1, 17, 67, 10, 2, 32, 14, 128, 128, 132, 3, 89, 47, 13, 89, 0, 116, 114, 97, 195, 159, 101, 1, 21, 2, 32, 14, 128, 128, 134, 3, 89, 47, 34, 4, 116, 89, 13, 0, 116, 101, 114, 1, 17, 67, 10, 2, 32, 14, 128, 128, 132, 3, 89, 47, 108, 0, 116, 101, 1, 97, 2, 108, 108, 3, 89, 47, 109, 0, 112, 104, 3, 89, 83, 0, 115, 116, 2, 21, 3, 89, 91, 47, 0, 4, 99, 104, 101, 110, 1, 101, 102, 3, 89, 99, 13, 50, 0, 99, 104, 101, 110, 1, 101, 105, 0, 99, 104, 101, 110, 1, 104, 0, 99, 104, 101, 110, 1, 117, 164, 195, 0, 99, 104, 101, 110, 1, 164, 195, 0, 99, 104, 101, 110, 1, 182, 195, 0, 111, 117, 2, 110, 100, 3, 89, 121, 0, 4, 8, 2, 112, 17, 65, 3, 91, 0, 8, 2, 112, 108, 17, 65, 0, 8, 2, 112, 114, 17, 65, 0, 8, 2, 116, 17, 65, 0, 8, 2, 116, 114, 17, 65, 0, 99, 104, 0, 99, 104, 8, 2, 17, 65, 0, 99, 104, 8, 2, 18, 66, 17, 65, 0, 99, 104, 8, 2, 109, 17, 65, 0, 99, 104, 8, 2, 110, 17, 65, 0, 99, 104, 8, 2, 119, 0, 104, 2, 25, 0, 104, 8, 2, 17, 65, 0, 104, 8, 2, 114, 17, 65, 0, 99, 104, 117, 108, 8, 2, 100, 3, 91, 6, 114, 55, 0, 99, 104, 117, 108, 8, 2, 21, 14, 128, 132, 133, 3, 91, 6, 120, 55, 0, 99, 104, 101, 105, 110, 2, 108, 105, 99, 104, 3, 91, 6, 122, 50, 0, 4, 99, 104, 101, 110, 1, 117, 164, 195, 116, 3, 91, 13, 50, 0, 99, 104, 101, 110, 1, 164, 195, 119, 0, 99, 104, 101, 110, 1, 182, 195, 108, 0, 99, 104, 101, 110, 1, 182, 195, 114, 0, 99, 104, 97, 102, 116, 1, 10, 2, 32, 14, 128, 128, 134, 3, 91, 35, 83, 47, 0, 4, 116, 2, 97, 104, 3, 91, 47, 0, 116, 2, 101, 104, 0, 116, 2, 117, 104, 0, 116, 2, 195, 164, 0, 116, 2, 195, 182, 0, 116, 2, 195, 188, 0, 116, 8, 101, 98, 0, 116, 8, 101, 103, 0, 116, 8, 114, 101, 118, 0, 116, 101, 2, 108, 108, 3, 91, 47, 109, 0, 4, 112, 2, 97, 110, 3, 91, 48, 0, 112, 2, 101, 105, 99, 104, 0, 112, 2, 101, 114, 114, 0, 112, 2, 105, 101, 108, 0, 112, 2, 114, 0, 112, 8, 101, 98, 0, 112, 8, 101, 103, 0, 112, 8, 114, 101, 118, 0, 99, 104, 119, 101, 114, 3, 91, 84, 126, 34, 0, 8, 2, 32, 3, 109, 89, 0, 7, 6, 116, 0, 1, 116, 3, 0, 101, 1, 116, 10, 2, 32, 3, 13, 0, 4, 101, 101, 110, 8, 3, 21, 0, 104, 114, 105, 108, 108, 0, 114, 97, 105, 108, 8, 0, 114, 97, 110, 113, 117, 8, 0, 119, 8, 0, 4, 3, 47, 0, 1, 114, 101, 105, 2, 32, 14, 128, 128, 129, 0, 2, 99, 104, 101, 110, 32, 0, 8, 2, 114, 17, 65, 0, 8, 2, 115, 101, 116, 115, 101, 0, 104, 1, 25, 0, 104, 2, 25, 0, 104, 8, 2, 17, 65, 0, 104, 8, 2, 114, 17, 65, 0, 104, 8, 97, 112, 0, 101, 108, 101, 8, 2, 21, 3, 47, 4, 126, 55, 126, 0, 105, 101, 102, 8, 2, 21, 14, 128, 132, 132, 3, 47, 6, 118, 83, 0, 101, 1, 114, 101, 105, 2, 32, 14, 128, 128, 130, 3, 47, 13, 0, 101, 114, 101, 1, 114, 101, 105, 2, 32, 14, 128, 128, 132, 3, 47, 13, 34, 13, 0, 101, 114, 101, 110, 1, 114, 101, 105, 2, 32, 14, 128, 128, 133, 3, 47, 13, 34, 13, 50, 0, 101, 114, 101, 109, 1, 114, 101, 105, 2, 32, 14, 128, 128, 133, 3, 47, 13, 34, 13, 65, 0, 101, 114, 101, 115, 1, 114, 101, 105, 2, 32, 14, 128, 128, 133, 3, 47, 13, 34, 13, 89, 0, 101, 114, 101, 114, 1, 114, 101, 105, 2, 32, 14, 128, 128, 133, 3, 47, 13, 34, 108, 0, 101, 116, 1, 114, 101, 105, 2, 32, 14, 128, 128, 131, 3, 47, 13, 47, 0, 101, 110, 1, 114, 101, 105, 2, 32, 14, 128, 128, 131, 3, 47, 13, 50, 0, 101, 109, 1, 114, 101, 105, 2, 32, 14, 128, 128, 131, 3, 47, 13, 65, 0, 101, 115, 1, 114, 101, 105, 2, 32, 14, 128, 128, 131, 3, 47, 13, 89, 0, 101, 115, 116, 1, 114, 101, 105, 2, 32, 14, 128, 128, 132, 3, 47, 13, 89, 47, 0, 101, 115, 116, 101, 1, 114, 101, 105, 2, 32, 14, 128, 128, 133, 3, 47, 13, 89, 47, 13, 0, 101, 115, 116, 101, 110, 1, 114, 101, 105, 2, 32, 14, 128, 128, 134, 3, 47, 13, 89, 47, 13, 50, 0, 101, 115, 116, 101, 109, 1, 114, 101, 105, 2, 32, 14, 128, 128, 134, 3, 47, 13, 89, 47, 13, 65, 0, 101, 115, 116, 101, 115, 1, 114, 101, 105, 2, 32, 14, 128, 128, 134, 3, 47, 13, 89, 47, 13, 89, 0, 101, 115, 116, 101, 114, 1, 114, 101, 105, 2, 32, 14, 128, 128, 134, 3, 47, 13, 89, 47, 108, 0, 114, 97, 118, 101, 114, 3, 47, 34, 2, 35, 84, 109, 34, 0, 97, 108, 101, 110, 116, 8, 3, 47, 35, 55, 6, 109, 50, 47, 0, 119, 8, 2, 17, 65, 3, 47, 58, 0, 101, 114, 1, 114, 101, 105, 2, 32, 14, 128, 128, 131, 3, 47, 108, 0, 104, 101, 114, 109, 111, 8, 3, 47, 109, 34, 65, 127, 0, 117, 101, 114, 101, 105, 2, 32, 3, 47, 120, 13, 34, 6, 122, 0, 4, 8, 2, 32, 3, 47, 126, 0, 104, 101, 2, 101, 114, 97, 0, 4, 99, 104, 3, 76, 0, 115, 99, 104, 8, 2, 17, 65, 0, 122, 3, 132, 0, 115, 116, 1, 114, 101, 105, 2, 32, 14, 128, 128, 131, 3, 132, 47, 0, 115, 116, 101, 1, 114, 101, 105, 2, 32, 14, 128, 128, 132, 3, 132, 47, 13, 0, 115, 116, 101, 110, 1, 114, 101, 105, 2, 32, 14, 128, 128, 133, 3, 132, 47, 13, 50, 0, 115, 116, 101, 109, 1, 114, 101, 105, 2, 32, 14, 128, 128, 133, 3, 132, 47, 13, 65, 0, 115, 116, 101, 115, 1, 114, 101, 105, 2, 32, 14, 128, 128, 133, 3, 132, 47, 13, 89, 0, 115, 116, 101, 114, 1, 114, 101, 105, 2, 32, 14, 128, 128, 133, 3, 132, 47, 108, 0, 105, 111, 110, 1, 21, 3, 132, 111, 4, 127, 50, 0, 105, 101, 110, 116, 1, 21, 2, 32, 3, 132, 111, 6, 109, 50, 47, 0, 105, 111, 110, 1, 21, 2, 32, 3, 132, 111, 6, 127, 50, 0, 7, 6, 117, 0, 110, 103, 115, 1, 10, 2, 17, 65, 3, 2, 114, 68, 89, 23, 0, 108, 116, 114, 97, 8, 2, 21, 14, 128, 132, 133, 3, 4, 114, 55, 47, 34, 35, 0, 110, 105, 118, 101, 114, 2, 115, 3, 4, 120, 50, 118, 84, 109, 34, 0, 2, 112, 116, 32, 3, 6, 114, 0, 4, 109, 8, 2, 111, 114, 103, 14, 128, 132, 130, 3, 6, 114, 65, 0, 109, 8, 2, 115, 116, 17, 65, 14, 128, 132, 130, 0, 109, 98, 101, 8, 2, 21, 14, 128, 132, 132, 3, 6, 114, 65, 71, 13, 0, 109, 103, 101, 8, 2, 21, 14, 128, 132, 132, 3, 6, 114, 65, 81, 13, 0, 101, 114, 105, 115, 99, 104, 1, 21, 2, 32, 3, 6, 120, 34, 111, 91, 0, 101, 2, 32, 3, 6, 128, 0, 4, 110, 100, 101, 114, 8, 3, 21, 0, 115, 101, 114, 8, 0, 110, 97, 98, 8, 2, 21, 14, 128, 132, 132, 3, 23, 4, 114, 50, 23, 35, 48, 0, 110, 116, 101, 114, 8, 2, 21, 14, 128, 132, 133, 3, 23, 4, 114, 50, 47, 108, 0, 101, 98, 101, 114, 8, 2, 21, 14, 128, 132, 133, 3, 23, 4, 128, 71, 108, 0, 4, 110, 8, 2, 21, 14, 128, 132, 130, 3, 23, 6, 114, 50, 0, 110, 8, 2, 105, 110, 21, 14, 128, 132, 130, 0, 110, 97, 110, 8, 2, 21, 14, 128, 132, 132, 3, 23, 6, 114, 50, 23, 35, 50, 0, 110, 117, 109, 8, 2, 21, 14, 128, 132, 132, 3, 23, 6, 114, 50, 23, 114, 65, 0, 110, 97, 117, 102, 8, 2, 21, 14, 128, 132, 133, 3, 23, 6, 114, 50, 23, 121, 83, 0, 110, 97, 117, 115, 8, 2, 21, 14, 128, 132, 133, 3, 23, 6, 114, 50, 23, 121, 89, 0, 110, 101, 105, 110, 8, 2, 21, 14, 128, 132, 133, 3, 23, 6, 114, 50, 23, 122, 50, 0, 110, 98, 101, 8, 2, 21, 14, 128, 132, 132, 3, 23, 6, 114, 50, 71, 13, 0, 110, 103, 101, 8, 2, 21, 14, 128, 132, 132, 3, 23, 6, 114, 50, 81, 13, 0, 110, 118, 101, 114, 8, 2, 21, 14, 128, 132, 133, 3, 23, 6, 114, 50, 83, 109, 34, 0, 4, 1, 21, 2, 109, 32, 3, 114, 0, 1, 21, 2, 110, 103, 0, 2, 17, 67, 11, 0, 2, 17, 67, 17, 67, 0, 2, 115, 99, 104, 0, 2, 120, 0, 110, 8, 3, 114, 50, 0, 110, 116, 101, 114, 8, 2, 101, 29, 3, 114, 50, 47, 13, 34, 0, 4, 109, 2, 32, 3, 114, 65, 0, 109, 8, 2, 21, 14, 128, 132, 130, 0, 109, 103, 101, 8, 2, 98, 3, 114, 65, 81, 6, 126, 0, 115, 2, 32, 3, 114, 89, 0, 4, 3, 120, 0, 1, 108, 17, 65, 2, 116, 32, 0, 1, 112, 101, 114, 2, 98, 108, 0, 1, 115, 2, 99, 104, 0, 1, 116, 114, 2, 109, 32, 0, 2, 101, 0, 8, 2, 32, 0, 8, 2, 114, 107, 0, 8, 2, 114, 108, 0, 8, 2, 114, 118, 0, 8, 100, 2, 115, 99, 104, 0, 104, 2, 12, 0, 101, 108, 97, 1, 10, 2, 32, 3, 120, 4, 126, 55, 35, 0, 101, 108, 108, 3, 120, 6, 109, 55, 0, 4, 101, 1, 114, 2, 32, 3, 120, 13, 0, 101, 1, 116, 2, 32, 0, 98, 2, 116, 32, 3, 120, 48, 0, 103, 2, 116, 32, 3, 120, 49, 0, 110, 8, 2, 105, 3, 120, 50, 0, 110, 105, 118, 101, 114, 115, 105, 116, 195, 164, 116, 115, 8, 2, 14, 128, 132, 140, 3, 120, 50, 118, 84, 109, 34, 88, 118, 47, 6, 125, 132, 0, 109, 1, 116, 2, 32, 3, 120, 65, 0, 7, 6, 118, 0, 1, 118, 3, 0, 4, 111, 114, 8, 2, 21, 14, 128, 132, 131, 3, 6, 83, 127, 34, 0, 111, 114, 8, 2, 110, 101, 0, 4, 2, 32, 24, 3, 83, 0, 2, 101, 114, 0, 2, 111, 103, 0, 2, 111, 108, 107, 0, 2, 111, 108, 108, 0, 2, 195, 182, 108, 17, 67, 0, 8, 2, 97, 116, 105, 32, 0, 8, 2, 105, 101, 0, 8, 2, 105, 122, 0, 8, 2, 108, 105, 101, 115, 0, 8, 2, 111, 110, 0, 8, 2, 114, 105, 0, 8, 2, 195, 164, 116, 0, 4, 101, 114, 2, 98, 105, 110, 100, 3, 83, 2, 109, 34, 0, 101, 114, 2, 100, 105, 101, 110, 0, 101, 114, 2, 115, 105, 99, 104, 116, 0, 101, 114, 2, 116, 105, 101, 102, 0, 101, 114, 8, 2, 21, 14, 128, 132, 131, 0, 4, 111, 108, 108, 8, 2, 98, 114, 3, 83, 2, 113, 55, 0, 111, 108, 108, 8, 2, 107, 111, 0, 111, 108, 108, 8, 2, 115, 116, 114, 101, 0, 111, 108, 108, 8, 2, 122, 0, 111, 108, 108, 8, 2, 101, 110, 100, 3, 83, 2, 113, 55, 23, 0, 111, 108, 108, 8, 2, 17, 67, 21, 14, 128, 132, 132, 3, 83, 6, 113, 55, 0, 105, 101, 114, 8, 2, 103, 21, 14, 128, 132, 132, 3, 83, 6, 118, 34, 0, 105, 101, 108, 8, 2, 21, 14, 128, 132, 132, 3, 83, 6, 118, 55, 0, 101, 114, 103, 101, 115, 115, 1, 21, 3, 83, 109, 34, 81, 4, 109, 89, 0, 101, 114, 102, 97, 104, 114, 101, 110, 1, 21, 2, 32, 14, 128, 128, 137, 3, 83, 109, 34, 83, 4, 116, 34, 13, 50, 0, 101, 114, 115, 105, 99, 104, 1, 21, 3, 83, 109, 34, 88, 4, 111, 99, 0, 111, 114, 8, 2, 110, 3, 83, 113, 34, 0, 111, 114, 100, 101, 114, 3, 83, 113, 34, 72, 108, 0, 111, 108, 107, 115, 8, 3, 83, 113, 55, 49, 89, 0, 97, 116, 101, 114, 3, 83, 116, 47, 108, 0, 105, 101, 8, 3, 83, 118, 0, 8, 2, 32, 3, 83, 121, 0, 195, 164, 116, 101, 114, 3, 83, 125, 47, 108, 0, 111, 114, 1, 17, 67, 3, 83, 127, 34, 0, 111, 114, 98, 101, 105, 8, 2, 14, 128, 132, 134, 3, 83, 127, 34, 6, 71, 122, 0, 111, 114, 97, 117, 115, 8, 2, 14, 128, 132, 134, 3, 83, 127, 34, 6, 121, 89, 0, 111, 114, 195, 188, 98, 101, 114, 8, 2, 14, 128, 132, 135, 3, 83, 127, 34, 6, 129, 71, 108, 0, 111, 114, 104, 97, 1, 45, 2, 110, 100, 3, 83, 127, 34, 107, 6, 35, 0, 111, 114, 104, 101, 114, 8, 2, 14, 128, 132, 134, 3, 83, 127, 34, 107, 6, 126, 34, 0, 4, 3, 84, 0, 1, 97, 2, 101, 114, 0, 1, 101, 114, 2, 101, 114, 0, 1, 105, 2, 101, 114, 0, 1, 111, 2, 101, 114, 0, 1, 117, 2, 101, 114, 0, 8, 2, 17, 65, 0, 8, 2, 105, 101, 116, 0, 8, 2, 108, 97, 100, 0, 8, 17, 65, 2, 101, 114, 0, 101, 8, 2, 114, 98, 111, 115, 3, 84, 2, 109, 0, 4, 101, 1, 98, 117, 115, 2, 114, 3, 84, 109, 0, 101, 1, 100, 97, 2, 114, 0, 101, 1, 110, 111, 107, 2, 114, 0, 101, 1, 114, 101, 112, 2, 114, 0, 101, 1, 115, 110, 97, 114, 116, 2, 114, 0, 101, 2, 114, 116, 105, 0, 101, 8, 2, 114, 98, 97, 108, 0, 101, 8, 2, 114, 115, 97, 116, 0, 101, 8, 2, 114, 115, 105, 101, 0, 101, 8, 2, 114, 115, 105, 102, 0, 101, 8, 2, 114, 115, 105, 111, 110, 0, 101, 8, 2, 114, 116, 101, 98, 0, 101, 108, 118, 2, 101, 114, 3, 84, 109, 55, 84, 0, 105, 8, 2, 17, 67, 17, 67, 3, 84, 111, 0, 105, 101, 116, 8, 3, 84, 111, 109, 47, 0, 105, 8, 3, 84, 118, 0, 101, 104, 101, 8, 3, 84, 126, 107, 126, 0, 7, 6, 119, 0, 4, 97, 114, 101, 1, 10, 2, 32, 3, 21, 0, 104, 8, 0, 111, 114, 107, 0, 4, 3, 84, 0, 8, 2, 108, 97, 100, 0, 8, 2, 114, 17, 65, 0, 104, 8, 2, 17, 65, 0, 111, 8, 2, 104, 105, 110, 3, 84, 2, 127, 0, 97, 115, 115, 101, 114, 8, 2, 21, 14, 128, 132, 134, 3, 84, 6, 35, 89, 13, 34, 0, 97, 115, 99, 104, 8, 2, 21, 14, 128, 132, 133, 3, 84, 6, 35, 91, 0, 101, 105, 116, 8, 2, 17, 67, 21, 14, 128, 132, 132, 3, 84, 6, 122, 47, 0, 101, 105, 116, 101, 114, 8, 2, 21, 14, 128, 132, 134, 3, 84, 6, 122, 47, 13, 34, 0, 101, 103, 8, 2, 17, 67, 21, 14, 128, 132, 131, 3, 84, 6, 126, 49, 0, 111, 104, 108, 8, 2, 21, 14, 128, 132, 132, 3, 84, 6, 127, 55, 0, 105, 101, 100, 101, 114, 8, 2, 21, 14, 128, 132, 134, 3, 84, 118, 72, 108, 0, 101, 105, 116, 104, 101, 114, 8, 3, 84, 122, 47, 107, 126, 34, 0, 8, 2, 32, 3, 84, 126, 0, 101, 114, 116, 1, 21, 2, 32, 3, 84, 126, 34, 47, 0, 111, 118, 111, 114, 8, 3, 84, 127, 83, 6, 127, 34, 0, 7, 6, 120, 0, 3, 49, 89, 0, 8, 2, 32, 3, 111, 49, 89, 0, 7, 6, 121, 0, 1, 116, 2, 32, 3, 21, 0, 4, 1, 17, 65, 2, 17, 65, 3, 57, 0, 8, 2, 17, 65, 0, 1, 21, 2, 32, 3, 118, 0, 3, 128, 0, 4, 2, 17, 67, 17, 67, 3, 129, 0, 2, 120, 0, 8, 2, 32, 3, 129, 48, 89, 111, 55, 113, 50, 0, 7, 6, 122, 0, 2, 122, 3, 0, 121, 107, 108, 111, 8, 2, 21, 14, 128, 132, 133, 3, 4, 132, 128, 49, 55, 127, 0, 8, 2, 100, 101, 110, 3, 88, 0, 4, 3, 132, 0, 8, 2, 119, 17, 65, 0, 121, 108, 105, 110, 3, 132, 2, 118, 55, 111, 50, 0, 4, 117, 8, 2, 17, 67, 21, 14, 128, 132, 130, 3, 132, 2, 120, 0, 117, 8, 2, 101, 14, 128, 132, 130, 0, 117, 8, 2, 103, 117, 21, 14, 128, 132, 130, 0, 105, 101, 8, 2, 103, 101, 21, 14, 128, 132, 131, 3, 132, 6, 118, 0, 105, 101, 114, 8, 2, 21, 14, 128, 132, 132, 3, 132, 6, 118, 34, 0, 105, 101, 108, 8, 2, 21, 14, 128, 132, 132, 3, 132, 6, 118, 55, 0, 101, 105, 116, 8, 2, 21, 14, 128, 132, 132, 3, 132, 6, 122, 47, 0, 105, 101, 108, 108, 3, 132, 57, 6, 109, 55, 0, 101, 114, 8, 2, 21, 14, 128, 132, 131, 3, 132, 109, 34, 0, 8, 2, 32, 3, 132, 109, 47, 0, 101, 110, 116, 114, 97, 108, 8, 2, 21, 14, 128, 132, 135, 3, 132, 109, 50, 47, 34, 6, 116, 55, 0, 101, 110, 116, 114, 97, 108, 8, 2, 105, 3, 132, 109, 50, 47, 34, 35, 55, 0, 4, 117, 8, 2, 99, 107, 3, 132, 114, 0, 117, 8, 2, 110, 17, 67, 0, 105, 103, 101, 117, 8, 3, 132, 118, 81, 6, 124, 0, 105, 103, 97, 114, 101, 116, 116, 101, 110, 8, 2, 21, 14, 128, 132, 138, 3, 132, 118, 81, 35, 34, 6, 109, 47, 13, 50, 0, 117, 8, 2, 103, 21, 3, 132, 120, 0, 117, 114, 195, 188, 99, 107, 8, 2, 21, 14, 128, 132, 134, 3, 132, 120, 34, 6, 129, 49, 0, 117, 115, 97, 109, 109, 101, 110, 8, 2, 21, 14, 128, 132, 136, 3, 132, 120, 88, 6, 35, 65, 13, 50, 0, 4, 101, 114, 101, 8, 2, 98, 3, 132, 126, 34, 126, 0, 101, 114, 101, 8, 2, 109, 0, 7, 6, 0, 4, 195, 169, 2, 32, 3, 6, 126, 0, 195, 169, 101, 0, 45, 8, 2, 32, 15, 3, 10, 0, 44, 2, 15, 3, 49, 113, 65, 35, 0, 45, 8, 32, 2, 32, 15, 3, 65, 118, 50, 114, 89, 0, 36, 3, 72, 113, 55, 6, 116, 0, 196, 141, 3, 76, 0, 195, 167, 3, 89, 0, 197, 190, 3, 90, 0, 197, 161, 3, 91, 0, 45, 1, 32, 15, 2, 32, 15, 3, 91, 47, 34, 111, 99, 0, 195, 166, 3, 109, 0, 195, 169, 3, 126, 0, 195, 184, 3, 131, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts11 = FileInMemory_createWithData (21636, reinterpret_cast (&espeakdata_dicts11_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/de_dict", U"de"); Collection_addItem (me.peek(), espeakdata_dicts11.transfer()); static unsigned char espeakdata_dicts12_data[3607] = { 0, 4, 0, 0, 154, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 51, 57, 122, 50, 47, 118, 55, 6, 113, 89, 0, 12, 3, 95, 50, 49, 113, 49, 12, 6, 113, 89, 0, 0, 12, 3, 95, 51, 56, 35, 34, 47, 6, 113, 89, 0, 10, 3, 95, 50, 48, 71, 6, 112, 89, 0, 0, 11, 3, 95, 50, 51, 47, 6, 114, 113, 89, 0, 0, 11, 3, 95, 50, 50, 71, 6, 118, 113, 89, 0, 0, 13, 3, 95, 50, 53, 48, 13, 80, 12, 6, 113, 89, 0, 0, 12, 3, 95, 50, 52, 80, 6, 120, 71, 113, 89, 0, 0, 14, 3, 95, 50, 55, 89, 13, 47, 12, 6, 118, 113, 89, 0, 0, 14, 3, 95, 50, 54, 144, 13, 71, 71, 6, 112, 34, 89, 0, 0, 14, 3, 95, 51, 49, 113, 49, 13, 47, 12, 6, 113, 89, 0, 0, 10, 3, 95, 51, 48, 47, 6, 112, 89, 0, 0, 12, 3, 95, 51, 51, 47, 127, 47, 6, 113, 89, 0, 0, 13, 3, 95, 51, 50, 71, 35, 47, 12, 6, 113, 89, 0, 0, 12, 3, 95, 51, 53, 48, 127, 47, 6, 113, 89, 0, 0, 12, 3, 95, 51, 52, 80, 130, 47, 6, 113, 89, 0, 0, 12, 3, 95, 51, 55, 89, 127, 47, 6, 113, 89, 0, 0, 13, 3, 95, 51, 54, 144, 35, 87, 6, 47, 113, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 55, 57, 4, 122, 67, 113, 118, 89, 6, 112, 0, 12, 3, 95, 54, 49, 6, 113, 49, 89, 13, 142, 0, 0, 16, 3, 95, 55, 56, 35, 138, 107, 35, 47, 12, 6, 109, 34, 12, 0, 10, 3, 95, 54, 48, 89, 6, 118, 142, 0, 0, 14, 3, 95, 48, 67, 89, 35, 6, 138, 36, 113, 49, 35, 0, 13, 3, 95, 54, 51, 47, 6, 113, 34, 89, 13, 142, 0, 0, 12, 3, 95, 54, 50, 71, 6, 118, 89, 13, 142, 0, 0, 12, 3, 95, 54, 53, 48, 134, 50, 89, 13, 142, 0, 0, 12, 3, 95, 54, 52, 80, 6, 130, 89, 13, 142, 0, 0, 13, 3, 95, 54, 55, 89, 6, 109, 34, 89, 13, 142, 0, 0, 14, 3, 95, 54, 54, 144, 6, 113, 57, 118, 89, 13, 142, 0, 0, 15, 3, 95, 55, 49, 113, 146, 35, 47, 12, 6, 109, 34, 12, 0, 0, 14, 3, 95, 55, 48, 89, 35, 47, 12, 6, 109, 34, 12, 0, 0, 16, 3, 95, 55, 51, 47, 113, 107, 35, 47, 12, 6, 109, 34, 12, 0, 0, 16, 3, 95, 55, 50, 71, 13, 107, 35, 47, 12, 6, 109, 34, 12, 0, 0, 17, 3, 95, 55, 53, 48, 35, 144, 4, 35, 47, 12, 6, 109, 34, 12, 0, 0, 16, 3, 95, 55, 52, 80, 120, 107, 35, 47, 12, 6, 109, 34, 12, 0, 0, 18, 3, 95, 55, 55, 89, 13, 47, 13, 107, 35, 47, 12, 6, 109, 34, 12, 0, 0, 16, 3, 95, 55, 54, 144, 113, 107, 35, 47, 12, 6, 109, 34, 12, 0, 0, 12, 3, 95, 49, 57, 122, 50, 50, 6, 113, 89, 0, 0, 13, 3, 95, 49, 56, 109, 142, 12, 6, 118, 34, 111, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 50, 57, 122, 50, 47, 6, 113, 89, 0, 15, 3, 95, 49, 49, 36, 6, 81, 57, 6, 118, 34, 13, 17, 0, 0, 13, 3, 95, 50, 56, 35, 138, 12, 6, 118, 113, 89, 0, 13, 3, 95, 49, 48, 72, 6, 37, 107, 35, 36, 113, 0, 0, 11, 3, 95, 49, 51, 47, 6, 115, 34, 111, 0, 0, 11, 3, 95, 49, 50, 71, 6, 35, 34, 111, 0, 0, 13, 3, 95, 49, 53, 48, 6, 109, 50, 72, 34, 111, 0, 0, 11, 3, 95, 49, 52, 144, 6, 120, 72, 111, 0, 0, 13, 3, 95, 49, 55, 89, 6, 109, 47, 12, 34, 111, 0, 0, 11, 3, 95, 49, 54, 89, 6, 119, 55, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 52, 57, 6, 122, 67, 80, 118, 89, 0, 0, 14, 3, 95, 52, 56, 35, 34, 47, 118, 55, 6, 113, 89, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 53, 57, 122, 50, 89, 6, 109, 138, 0, 14, 3, 95, 52, 49, 113, 49, 47, 118, 55, 6, 113, 89, 0, 0, 14, 3, 95, 53, 56, 35, 138, 12, 6, 118, 58, 13, 50, 0, 12, 3, 95, 52, 48, 80, 118, 55, 6, 113, 89, 0, 0, 14, 3, 95, 52, 51, 47, 127, 47, 118, 55, 6, 113, 89, 0, 0, 13, 3, 95, 52, 50, 71, 134, 118, 55, 6, 113, 89, 0, 0, 16, 3, 95, 52, 53, 48, 134, 6, 50, 47, 118, 55, 6, 113, 89, 0, 0, 14, 3, 95, 52, 52, 80, 120, 58, 118, 55, 6, 113, 89, 0, 0, 14, 3, 95, 52, 55, 89, 127, 47, 118, 55, 6, 113, 89, 0, 0, 15, 3, 95, 52, 54, 144, 107, 113, 57, 118, 55, 6, 113, 89, 0, 0, 18, 3, 95, 54, 57, 122, 50, 13, 107, 4, 35, 47, 12, 6, 109, 34, 12, 0, 14, 3, 95, 53, 49, 113, 49, 57, 6, 118, 58, 109, 50, 0, 0, 11, 3, 95, 54, 56, 35, 34, 89, 13, 142, 0, 12, 3, 95, 53, 48, 48, 13, 80, 6, 118, 89, 0, 0, 13, 3, 95, 53, 51, 47, 6, 113, 34, 48, 109, 50, 0, 0, 12, 3, 95, 53, 50, 71, 6, 118, 58, 109, 50, 0, 0, 13, 3, 95, 53, 53, 48, 6, 35, 144, 48, 109, 50, 0, 0, 13, 3, 95, 53, 52, 80, 6, 121, 123, 58, 109, 50, 0, 0, 15, 3, 95, 53, 55, 89, 109, 47, 12, 6, 118, 58, 13, 50, 0, 0, 14, 3, 95, 53, 54, 144, 107, 13, 48, 12, 6, 109, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 56, 57, 50, 109, 58, 118, 89, 6, 112, 0, 0, 13, 3, 95, 56, 56, 35, 138, 12, 118, 89, 6, 112, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 57, 57, 50, 113, 67, 57, 6, 118, 50, 13, 58, 114, 0, 13, 3, 95, 56, 49, 113, 49, 57, 118, 89, 6, 112, 0, 0, 15, 3, 95, 57, 56, 35, 138, 12, 6, 118, 50, 13, 58, 114, 0, 12, 3, 95, 56, 48, 4, 109, 89, 89, 6, 112, 0, 0, 13, 3, 95, 56, 51, 47, 113, 34, 118, 89, 6, 112, 0, 0, 12, 3, 95, 56, 50, 71, 134, 118, 89, 6, 112, 0, 0, 14, 3, 95, 56, 53, 48, 113, 6, 80, 118, 89, 6, 112, 0, 0, 13, 3, 95, 56, 52, 80, 120, 34, 118, 89, 6, 112, 0, 0, 14, 3, 95, 56, 55, 89, 109, 47, 12, 118, 89, 6, 112, 0, 0, 13, 3, 95, 56, 54, 144, 113, 57, 118, 89, 6, 112, 0, 0, 15, 3, 95, 57, 49, 113, 49, 57, 6, 118, 50, 13, 58, 114, 0, 0, 12, 3, 95, 57, 48, 50, 109, 71, 12, 6, 114, 0, 0, 15, 3, 95, 57, 51, 47, 113, 34, 6, 118, 50, 13, 58, 114, 0, 0, 13, 3, 95, 57, 50, 71, 6, 118, 50, 13, 58, 114, 0, 0, 15, 3, 95, 57, 53, 48, 13, 80, 6, 118, 50, 13, 58, 114, 0, 0, 15, 3, 95, 57, 52, 80, 120, 34, 6, 118, 65, 13, 58, 114, 0, 0, 16, 3, 95, 57, 55, 89, 13, 47, 12, 6, 118, 50, 13, 58, 114, 0, 0, 15, 3, 95, 57, 54, 144, 113, 57, 6, 118, 50, 13, 58, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 95, 48, 77, 50, 55, 6, 118, 146, 0, 0, 13, 4, 95, 48, 77, 51, 80, 34, 6, 39, 34, 36, 0, 0, 0, 13, 4, 95, 48, 77, 49, 107, 13, 88, 6, 118, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 131, 239, 187, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 2, 95, 51, 47, 37, 50, 36, 113, 0, 0, 9, 2, 95, 50, 72, 6, 36, 113, 0, 0, 10, 2, 95, 49, 36, 6, 49, 36, 113, 0, 0, 11, 2, 95, 48, 89, 6, 40, 65, 36, 113, 0, 0, 11, 2, 95, 55, 107, 35, 6, 138, 36, 113, 0, 0, 10, 2, 95, 54, 107, 35, 6, 36, 113, 0, 0, 11, 2, 95, 53, 83, 35, 6, 107, 36, 113, 0, 0, 14, 2, 95, 52, 107, 35, 6, 138, 35, 6, 34, 36, 113, 0, 0, 0, 0, 11, 2, 95, 57, 50, 6, 40, 35, 36, 113, 0, 0, 10, 2, 95, 56, 35, 6, 91, 36, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 2, 222, 135, 6, 35, 55, 37, 83, 40, 0, 0, 10, 2, 222, 134, 49, 6, 118, 83, 40, 0, 0, 15, 2, 222, 133, 62, 6, 35, 84, 4, 37, 57, 35, 50, 37, 0, 0, 8, 2, 222, 132, 71, 6, 118, 0, 0, 8, 2, 222, 131, 51, 6, 118, 0, 0, 10, 2, 222, 130, 50, 6, 123, 50, 40, 0, 0, 14, 2, 222, 129, 93, 6, 35, 84, 37, 57, 35, 50, 37, 0, 0, 8, 2, 222, 128, 107, 6, 118, 0, 0, 14, 2, 222, 143, 67, 6, 35, 84, 37, 57, 35, 50, 37, 0, 0, 10, 2, 222, 142, 81, 6, 118, 83, 40, 0, 0, 10, 2, 222, 141, 55, 6, 118, 65, 40, 0, 0, 8, 2, 222, 140, 47, 6, 118, 0, 0, 10, 2, 222, 139, 72, 6, 118, 55, 40, 0, 0, 10, 2, 222, 138, 83, 6, 118, 83, 40, 0, 0, 10, 2, 222, 137, 65, 6, 112, 65, 40, 0, 0, 10, 2, 222, 136, 84, 6, 118, 84, 40, 0, 0, 14, 2, 222, 151, 76, 6, 35, 84, 37, 57, 35, 50, 37, 0, 0, 14, 2, 222, 150, 75, 6, 35, 84, 37, 57, 35, 50, 37, 0, 0, 14, 2, 222, 149, 48, 6, 35, 84, 37, 57, 35, 50, 37, 0, 0, 8, 2, 222, 148, 57, 6, 118, 0, 0, 14, 2, 222, 147, 140, 6, 35, 84, 37, 57, 35, 50, 37, 0, 0, 14, 2, 222, 146, 88, 6, 35, 84, 37, 57, 35, 50, 37, 0, 0, 14, 2, 222, 145, 141, 6, 35, 84, 37, 57, 35, 50, 37, 0, 0, 10, 2, 222, 144, 89, 6, 112, 50, 40, 0, 0, 10, 2, 222, 159, 72, 6, 118, 72, 40, 0, 0, 10, 2, 222, 158, 89, 6, 118, 72, 40, 0, 0, 10, 2, 222, 157, 91, 6, 112, 50, 40, 0, 0, 8, 2, 222, 156, 88, 6, 118, 0, 0, 10, 2, 222, 155, 86, 6, 118, 55, 40, 0, 0, 8, 2, 222, 154, 101, 6, 118, 0, 0, 9, 2, 222, 153, 107, 107, 6, 118, 0, 0, 8, 2, 222, 152, 87, 6, 118, 0, 0, 15, 2, 222, 167, 6, 118, 71, 118, 15, 83, 4, 37, 55, 37, 0, 0, 15, 2, 222, 166, 6, 35, 71, 35, 15, 83, 4, 37, 55, 37, 0, 0, 10, 2, 222, 165, 58, 6, 118, 84, 40, 0, 0, 10, 2, 222, 164, 104, 6, 118, 83, 40, 0, 0, 11, 2, 222, 163, 100, 35, 6, 37, 50, 40, 0, 0, 10, 2, 222, 162, 35, 6, 37, 50, 40, 0, 0, 8, 2, 222, 161, 88, 6, 39, 0, 0, 8, 2, 222, 160, 47, 6, 39, 0, 0, 15, 2, 222, 175, 6, 119, 71, 119, 15, 83, 4, 37, 55, 37, 0, 0, 15, 2, 222, 174, 6, 39, 71, 39, 15, 83, 4, 37, 55, 37, 0, 0, 15, 2, 222, 173, 6, 114, 71, 114, 15, 83, 4, 37, 55, 37, 0, 0, 15, 2, 222, 172, 6, 36, 71, 36, 15, 83, 4, 37, 55, 37, 0, 0, 15, 2, 222, 171, 6, 123, 71, 123, 15, 83, 4, 37, 55, 37, 0, 0, 15, 2, 222, 170, 6, 40, 71, 40, 15, 83, 4, 37, 55, 37, 0, 0, 15, 2, 222, 169, 6, 112, 71, 112, 15, 83, 4, 37, 55, 37, 0, 0, 15, 2, 222, 168, 6, 37, 71, 37, 15, 83, 4, 37, 55, 37, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 222, 177, 50, 6, 35, 15, 84, 37, 57, 35, 50, 37, 0, 0, 11, 2, 222, 176, 89, 6, 40, 49, 40, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 1, 1, 0, 3, 107, 0, 7, 6, 1, 2, 0, 3, 93, 0, 7, 6, 1, 3, 0, 3, 50, 0, 222, 176, 2, 222, 130, 3, 50, 50, 0, 222, 176, 2, 222, 137, 3, 65, 65, 0, 222, 176, 2, 222, 143, 3, 67, 67, 0, 7, 6, 1, 4, 0, 3, 51, 0, 7, 6, 1, 5, 0, 3, 71, 0, 7, 6, 1, 6, 0, 3, 62, 0, 7, 6, 1, 7, 0, 3, 49, 0, 7, 6, 1, 8, 0, 3, 0, 222, 176, 2, 32, 3, 36, 107, 0, 222, 176, 2, 222, 140, 3, 47, 0, 222, 176, 2, 222, 149, 3, 48, 0, 222, 176, 2, 222, 134, 3, 49, 0, 222, 176, 2, 222, 130, 3, 50, 0, 222, 176, 2, 222, 131, 3, 51, 0, 222, 176, 2, 222, 141, 3, 55, 0, 222, 176, 2, 222, 148, 3, 57, 0, 222, 176, 2, 222, 133, 3, 62, 0, 222, 176, 2, 222, 137, 3, 65, 0, 222, 176, 2, 222, 143, 3, 68, 0, 222, 176, 2, 222, 132, 3, 71, 0, 222, 176, 2, 222, 139, 3, 72, 0, 222, 176, 2, 222, 150, 3, 75, 0, 222, 176, 2, 222, 151, 3, 76, 0, 222, 176, 2, 222, 142, 3, 81, 0, 222, 176, 2, 222, 134, 3, 84, 0, 222, 176, 2, 222, 146, 3, 88, 0, 222, 176, 2, 222, 144, 3, 89, 0, 222, 176, 2, 222, 156, 3, 90, 0, 222, 176, 2, 222, 128, 3, 93, 0, 4, 222, 176, 2, 222, 128, 3, 107, 0, 222, 176, 2, 222, 129, 0, 222, 176, 2, 222, 147, 3, 140, 0, 222, 176, 2, 222, 145, 3, 141, 0, 7, 6, 1, 9, 0, 3, 84, 0, 7, 6, 1, 10, 0, 3, 65, 0, 7, 6, 1, 11, 0, 3, 83, 0, 7, 6, 1, 12, 0, 3, 72, 0, 7, 6, 1, 13, 0, 3, 47, 0, 7, 6, 1, 14, 0, 3, 55, 0, 7, 6, 1, 15, 0, 3, 81, 0, 7, 6, 1, 16, 0, 3, 67, 0, 7, 6, 1, 17, 0, 3, 89, 0, 7, 6, 1, 18, 0, 3, 141, 0, 7, 6, 1, 19, 0, 3, 88, 0, 7, 6, 1, 20, 0, 3, 140, 0, 7, 6, 1, 21, 0, 3, 57, 0, 7, 6, 1, 22, 0, 3, 48, 0, 7, 6, 1, 23, 0, 3, 75, 0, 7, 6, 1, 24, 0, 3, 76, 0, 7, 6, 1, 25, 0, 3, 87, 0, 7, 6, 1, 26, 0, 3, 107, 0, 7, 6, 1, 27, 0, 3, 101, 0, 7, 6, 1, 28, 0, 3, 86, 0, 7, 6, 1, 29, 0, 3, 90, 0, 7, 6, 1, 30, 0, 3, 91, 0, 7, 6, 1, 31, 0, 3, 89, 0, 7, 6, 1, 32, 0, 3, 72, 0, 7, 6, 1, 33, 0, 3, 47, 0, 7, 6, 1, 34, 0, 3, 88, 0, 7, 6, 1, 35, 0, 3, 19, 0, 7, 6, 1, 36, 0, 3, 100, 0, 7, 6, 1, 37, 0, 3, 104, 0, 7, 6, 1, 38, 0, 3, 58, 0, 7, 6, 1, 39, 0, 3, 35, 0, 7, 6, 1, 40, 0, 3, 118, 0, 7, 6, 1, 41, 0, 3, 37, 0, 7, 6, 1, 42, 0, 3, 112, 0, 7, 6, 1, 43, 0, 3, 40, 0, 7, 6, 1, 44, 0, 3, 123, 0, 7, 6, 1, 45, 0, 3, 36, 0, 7, 6, 1, 46, 0, 3, 114, 0, 7, 6, 1, 47, 0, 3, 39, 0, 7, 6, 1, 48, 0, 3, 119, 0, 7, 6, 1, 49, 0, 3, 0, 7, 6, 1, 50, 0, 3, 66, 0, 7, 6, 0, 36, 3, 72, 39, 55, 35, 51, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts12 = FileInMemory_createWithData (3606, reinterpret_cast (&espeakdata_dicts12_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/dv_dict", U"dv"); Collection_addItem (me.peek(), espeakdata_dicts12.transfer()); static unsigned char espeakdata_dicts13_data[5352] = { 0, 4, 0, 0, 19, 16, 0, 0, 0, 0, 0, 0, 13, 138, 206, 181, 206, 175, 207, 135, 206, 177, 206, 189, 72, 0, 0, 0, 0, 17, 142, 206, 174, 207, 131, 206, 177, 207, 131, 207, 132, 206, 177, 206, 189, 72, 17, 142, 206, 174, 206, 188, 206, 177, 207, 131, 207, 132, 206, 177, 206, 189, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 207, 140, 207, 132, 206, 185, 8, 10, 134, 207, 140, 207, 132, 206, 185, 72, 8, 0, 0, 0, 0, 0, 9, 134, 206, 188, 206, 177, 207, 130, 72, 0, 0, 0, 0, 0, 0, 0, 16, 4, 95, 51, 88, 15, 47, 34, 37, 35, 49, 39, 89, 47, 6, 0, 0, 0, 0, 0, 0, 0, 12, 1, 36, 86, 39, 55, 6, 35, 34, 37, 35, 0, 0, 14, 1, 37, 47, 37, 89, 36, 49, 35, 47, 6, 39, 0, 27, 0, 0, 0, 0, 0, 9, 134, 207, 132, 207, 137, 206, 189, 72, 9, 1, 42, 36, 48, 37, 0, 72, 27, 0, 9, 1, 43, 89, 37, 50, 0, 72, 27, 0, 11, 136, 207, 131, 207, 132, 207, 137, 206, 189, 72, 0, 9, 1, 45, 65, 6, 37, 39, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 136, 206, 188, 206, 185, 206, 177, 207, 130, 72, 0, 0, 0, 0, 9, 1, 61, 37, 89, 39, 50, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 138, 206, 181, 206, 175, 206, 188, 206, 177, 206, 185, 72, 0, 0, 0, 0, 17, 142, 206, 189, 206, 177, 206, 181, 206, 175, 206, 188, 206, 177, 206, 185, 72, 0, 0, 0, 0, 0, 0, 0, 0, 15, 4, 95, 49, 67, 15, 36, 49, 35, 47, 39, 89, 47, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 95, 49, 77, 49, 99, 6, 37, 61, 35, 0, 0, 22, 4, 95, 49, 77, 50, 6, 36, 50, 35, 36, 49, 35, 47, 39, 65, 6, 37, 34, 37, 39, 0, 0, 25, 4, 95, 49, 77, 51, 6, 36, 50, 35, 86, 37, 89, 36, 49, 35, 47, 39, 65, 6, 37, 34, 37, 39, 0, 0, 0, 0, 0, 12, 6, 206, 186, 206, 177, 206, 185, 49, 36, 0, 72, 0, 0, 0, 0, 0, 0, 11, 136, 206, 174, 207, 132, 206, 177, 206, 189, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 49, 67, 48, 36, 49, 35, 47, 6, 39, 0, 0, 0, 0, 0, 0, 0, 0, 17, 4, 95, 50, 67, 15, 86, 38, 35, 49, 39, 95, 39, 89, 47, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 138, 206, 184, 206, 177, 206, 173, 207, 135, 207, 137, 72, 0, 0, 0, 15, 140, 206, 181, 207, 128, 206, 181, 206, 185, 206, 180, 206, 174, 8, 0, 9, 134, 207, 131, 206, 191, 207, 133, 72, 0, 0, 7, 132, 206, 189, 206, 177, 72, 7, 132, 206, 189, 206, 177, 72, 0, 0, 15, 4, 95, 49, 49, 15, 36, 50, 86, 6, 36, 49, 35, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 4, 95, 51, 67, 15, 47, 34, 38, 35, 49, 39, 95, 39, 89, 47, 6, 0, 0, 13, 4, 95, 4, 16, 20, 10, 49, 6, 39, 65, 35, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 49, 48, 15, 86, 6, 36, 49, 35, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 132, 207, 132, 206, 183, 72, 0, 0, 9, 134, 207, 131, 207, 132, 206, 183, 72, 7, 132, 207, 132, 206, 177, 72, 0, 0, 9, 134, 207, 131, 207, 132, 206, 177, 72, 13, 138, 206, 181, 206, 175, 207, 131, 207, 132, 206, 181, 72, 0, 0, 15, 140, 206, 181, 206, 175, 207, 135, 206, 177, 206, 188, 206, 181, 72, 15, 140, 206, 173, 207, 135, 206, 191, 207, 133, 206, 188, 206, 181, 72, 0, 0, 17, 142, 206, 189, 206, 177, 206, 181, 206, 175, 207, 131, 207, 132, 206, 181, 72, 7, 132, 207, 132, 206, 191, 72, 15, 4, 95, 49, 50, 15, 86, 39, 86, 6, 36, 49, 35, 47, 0, 0, 0, 9, 134, 207, 131, 207, 132, 206, 191, 72, 19, 144, 206, 189, 206, 177, 206, 173, 207, 135, 206, 191, 207, 133, 206, 188, 206, 181, 72, 0, 0, 10, 134, 206, 181, 206, 172, 206, 189, 72, 8, 0, 0, 0, 0, 0, 18, 5, 95, 50, 77, 49, 15, 86, 37, 89, 99, 37, 61, 39, 89, 47, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 138, 206, 186, 206, 191, 206, 189, 207, 132, 206, 172, 28, 0, 9, 134, 207, 128, 206, 191, 207, 133, 72, 0, 0, 0, 0, 0, 0, 0, 13, 138, 206, 173, 207, 135, 206, 181, 207, 132, 206, 181, 72, 0, 0, 0, 0, 17, 142, 206, 189, 206, 177, 206, 173, 207, 135, 206, 181, 207, 132, 206, 181, 72, 17, 142, 206, 184, 206, 177, 206, 181, 206, 175, 207, 131, 207, 132, 206, 181, 72, 0, 0, 0, 0, 21, 146, 206, 184, 206, 177, 206, 181, 206, 175, 206, 188, 206, 177, 207, 131, 207, 132, 206, 181, 72, 0, 0, 0, 0, 13, 138, 206, 180, 206, 185, 207, 140, 207, 132, 206, 185, 8, 19, 4, 95, 52, 67, 15, 47, 36, 47, 34, 35, 49, 39, 95, 39, 89, 47, 6, 0, 0, 0, 0, 0, 0, 15, 5, 95, 48, 77, 49, 15, 99, 37, 61, 39, 89, 47, 6, 0, 0, 0, 0, 18, 4, 95, 55, 88, 15, 36, 84, 86, 39, 65, 37, 49, 39, 89, 47, 6, 0, 0, 0, 0, 0, 0, 11, 136, 207, 128, 207, 129, 206, 191, 207, 130, 28, 0, 0, 11, 6, 95, 35, 206, 191, 207, 130, 39, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 142, 206, 184, 206, 177, 206, 181, 206, 175, 207, 131, 206, 177, 206, 185, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 207, 131, 206, 177, 207, 130, 72, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 49, 15, 48, 34, 6, 39, 47, 0, 0, 0, 0, 7, 132, 206, 191, 206, 185, 72, 11, 3, 226, 130, 172, 36, 84, 34, 6, 39, 0, 0, 0, 0, 0, 0, 13, 3, 95, 50, 15, 86, 6, 36, 83, 47, 36, 34, 0, 0, 13, 138, 206, 181, 206, 175, 207, 131, 206, 177, 206, 185, 72, 0, 0, 0, 0, 17, 142, 206, 189, 206, 177, 206, 181, 206, 175, 207, 131, 206, 177, 206, 185, 72, 18, 4, 95, 53, 67, 15, 48, 36, 72, 35, 49, 39, 95, 39, 89, 47, 6, 0, 0, 0, 0, 11, 3, 95, 51, 15, 47, 34, 6, 37, 47, 0, 9, 4, 95, 15, 18, 4, 39, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 51, 6, 47, 34, 6, 37, 89, 0, 0, 0, 0, 0, 15, 140, 207, 128, 206, 177, 207, 129, 207, 140, 206, 187, 206, 191, 8, 8, 4, 95, 35, 206, 183, 37, 0, 0, 0, 0, 12, 3, 95, 53, 15, 48, 6, 36, 65, 48, 47, 0, 0, 14, 3, 95, 52, 6, 47, 6, 36, 89, 36, 34, 37, 89, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 95, 54, 15, 6, 36, 49, 47, 0, 0, 0, 0, 19, 144, 206, 184, 206, 177, 206, 173, 207, 135, 206, 191, 207, 133, 206, 188, 206, 181, 72, 0, 0, 0, 0, 0, 12, 3, 95, 55, 15, 6, 36, 84, 86, 39, 65, 0, 0, 0, 0, 0, 0, 8, 4, 95, 35, 206, 191, 39, 0, 0, 0, 0, 14, 3, 95, 48, 15, 65, 37, 86, 36, 50, 37, 49, 6, 0, 0, 0, 0, 14, 3, 95, 51, 88, 47, 34, 37, 6, 35, 50, 72, 35, 0, 0, 14, 3, 95, 48, 67, 36, 49, 35, 47, 6, 39, 50, 10, 0, 0, 0, 0, 0, 11, 3, 95, 57, 15, 6, 36, 50, 35, 47, 0, 0, 9, 134, 206, 173, 207, 135, 207, 137, 72, 0, 0, 0, 14, 3, 95, 49, 67, 36, 49, 35, 47, 6, 39, 50, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 50, 67, 86, 38, 35, 49, 6, 39, 95, 35, 10, 0, 0, 18, 4, 95, 54, 67, 15, 36, 49, 89, 35, 49, 39, 95, 39, 89, 47, 6, 0, 0, 0, 0, 0, 0, 13, 3, 95, 49, 49, 6, 36, 50, 86, 36, 49, 35, 0, 0, 0, 16, 3, 95, 51, 67, 47, 34, 37, 35, 49, 6, 39, 95, 35, 10, 0, 0, 13, 4, 95, 49, 88, 15, 86, 6, 36, 49, 35, 47, 0, 13, 3, 95, 49, 50, 86, 6, 39, 86, 36, 49, 35, 0, 0, 0, 0, 13, 3, 95, 52, 15, 47, 6, 36, 47, 35, 34, 47, 0, 0, 9, 134, 206, 188, 206, 191, 207, 133, 72, 0, 0, 16, 3, 95, 55, 88, 36, 71, 72, 39, 65, 6, 37, 50, 72, 35, 0, 0, 17, 3, 95, 52, 67, 47, 36, 47, 34, 35, 49, 6, 39, 95, 35, 10, 0, 0, 13, 6, 207, 129, 206, 185, 206, 177, 34, 100, 38, 35, 0, 0, 0, 0, 0, 9, 134, 206, 173, 206, 189, 206, 177, 72, 0, 0, 0, 17, 3, 95, 53, 67, 48, 36, 50, 72, 35, 49, 6, 39, 95, 35, 10, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 49, 88, 86, 6, 36, 49, 35, 0, 0, 16, 3, 95, 54, 67, 36, 49, 89, 35, 49, 6, 39, 95, 35, 10, 0, 0, 17, 142, 206, 184, 206, 177, 206, 173, 207, 135, 206, 191, 207, 133, 206, 189, 72, 0, 0, 0, 0, 0, 0, 12, 3, 95, 50, 88, 6, 37, 49, 39, 89, 37, 0, 0, 16, 3, 95, 55, 67, 36, 48, 47, 35, 49, 6, 39, 95, 35, 10, 0, 0, 0, 0, 0, 11, 3, 95, 56, 15, 6, 39, 100, 86, 39, 0, 0, 0, 0, 0, 16, 3, 95, 56, 67, 39, 49, 47, 35, 49, 6, 39, 95, 35, 10, 0, 0, 0, 0, 0, 0, 9, 134, 206, 188, 206, 175, 206, 177, 72, 0, 0, 14, 3, 95, 52, 88, 89, 35, 34, 6, 35, 50, 72, 35, 0, 0, 17, 142, 206, 184, 206, 177, 206, 173, 207, 135, 206, 181, 206, 185, 207, 130, 72, 15, 3, 95, 57, 67, 36, 67, 35, 49, 6, 39, 95, 35, 10, 0, 0, 0, 0, 0, 12, 136, 207, 128, 206, 177, 207, 129, 206, 172, 72, 28, 0, 13, 138, 206, 174, 207, 131, 206, 191, 207, 133, 206, 189, 72, 0, 0, 14, 3, 95, 53, 88, 48, 36, 50, 6, 37, 50, 72, 35, 0, 0, 0, 13, 138, 206, 188, 206, 173, 207, 135, 207, 129, 206, 185, 28, 18, 4, 95, 55, 67, 15, 36, 48, 47, 35, 49, 39, 95, 39, 89, 47, 6, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 54, 88, 36, 49, 89, 6, 37, 50, 72, 35, 0, 0, 0, 13, 4, 95, 50, 88, 15, 37, 49, 39, 89, 47, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 56, 88, 39, 81, 72, 6, 39, 50, 72, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 57, 88, 36, 50, 36, 50, 6, 37, 50, 72, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 206, 181, 207, 128, 206, 175, 72, 0, 0, 9, 134, 207, 132, 206, 191, 207, 133, 72, 13, 138, 206, 173, 207, 135, 206, 191, 207, 133, 206, 189, 72, 13, 138, 206, 174, 206, 188, 206, 191, 207, 133, 206, 189, 72, 9, 134, 207, 132, 206, 191, 207, 133, 72, 0, 0, 11, 136, 207, 131, 207, 132, 206, 191, 207, 133, 72, 0, 0, 17, 142, 206, 189, 206, 177, 206, 173, 207, 135, 206, 191, 207, 133, 206, 189, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 4, 95, 56, 67, 15, 39, 49, 47, 35, 49, 39, 95, 39, 89, 47, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 4, 95, 48, 77, 50, 36, 49, 35, 47, 39, 65, 6, 37, 34, 37, 35, 0, 0, 21, 4, 95, 48, 77, 51, 86, 37, 89, 36, 49, 35, 47, 39, 65, 6, 37, 34, 37, 35, 0, 0, 0, 15, 4, 95, 48, 77, 49, 99, 37, 61, 6, 35, 86, 36, 89, 0, 0, 0, 0, 0, 7, 132, 207, 131, 206, 181, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 207, 132, 206, 191, 206, 189, 72, 0, 0, 11, 136, 207, 131, 207, 132, 206, 191, 206, 189, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 6, 206, 188, 206, 185, 206, 177, 65, 67, 35, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 4, 95, 57, 67, 15, 36, 50, 36, 35, 49, 39, 95, 39, 89, 47, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 4, 95, 52, 88, 15, 47, 36, 89, 89, 35, 34, 35, 49, 39, 89, 47, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 136, 206, 177, 206, 187, 206, 187, 206, 172, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 136, 206, 188, 206, 173, 207, 131, 206, 177, 72, 28, 15, 140, 206, 181, 206, 175, 207, 135, 206, 177, 207, 132, 206, 181, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 207, 132, 206, 185, 207, 130, 72, 0, 0, 11, 136, 207, 131, 207, 132, 206, 185, 207, 130, 72, 0, 0, 0, 13, 138, 206, 179, 206, 185, 206, 177, 207, 132, 206, 175, 8, 0, 11, 136, 207, 132, 206, 191, 207, 133, 207, 130, 72, 11, 136, 207, 132, 206, 191, 207, 133, 207, 130, 72, 0, 0, 13, 138, 207, 131, 207, 132, 206, 191, 207, 133, 207, 130, 72, 0, 0, 0, 0, 0, 8, 132, 206, 188, 206, 181, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 136, 206, 188, 206, 177, 206, 182, 206, 175, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 16, 4, 95, 53, 88, 15, 48, 36, 72, 37, 49, 39, 89, 47, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 142, 206, 184, 206, 177, 206, 173, 207, 135, 206, 181, 207, 132, 206, 181, 72, 0, 0, 0, 0, 0, 0, 0, 0, 13, 138, 206, 181, 206, 175, 206, 189, 206, 177, 206, 185, 72, 0, 0, 0, 0, 17, 142, 206, 189, 206, 177, 206, 181, 206, 175, 206, 189, 206, 177, 206, 185, 72, 0, 0, 0, 0, 0, 0, 0, 10, 3, 95, 206, 183, 6, 37, 47, 35, 0, 0, 0, 13, 138, 206, 181, 206, 175, 207, 135, 206, 181, 207, 130, 72, 0, 0, 0, 0, 0, 16, 3, 95, 206, 174, 4, 37, 47, 35, 47, 6, 39, 50, 39, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 4, 95, 54, 88, 15, 36, 49, 89, 37, 49, 39, 89, 47, 6, 0, 0, 0, 0, 0, 0, 0, 0, 11, 136, 206, 181, 206, 189, 207, 140, 207, 130, 72, 0, 0, 32, 10, 206, 181, 206, 186, 207, 132, 207, 140, 207, 130, 36, 49, 47, 6, 39, 89, 36, 4, 35, 50, 0, 8, 81, 206, 181, 206, 172, 206, 189, 32, 0, 11, 136, 206, 173, 207, 135, 206, 181, 206, 185, 72, 0, 22, 12, 206, 188, 206, 185, 206, 181, 207, 129, 207, 140, 207, 130, 65, 37, 36, 34, 6, 39, 89, 0, 0, 0, 0, 15, 140, 206, 189, 206, 177, 206, 173, 207, 135, 206, 181, 206, 185, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 5, 95, 51, 77, 49, 15, 47, 34, 37, 89, 99, 37, 61, 39, 89, 47, 6, 0, 0, 0, 0, 0, 7, 2, 207, 134, 83, 37, 0, 15, 5, 95, 49, 77, 49, 15, 99, 37, 61, 39, 89, 47, 6, 0, 0, 7, 2, 207, 135, 99, 37, 0, 0, 8, 2, 207, 132, 47, 35, 83, 0, 14, 3, 95, 206, 191, 6, 39, 65, 37, 49, 34, 39, 50, 0, 0, 13, 2, 207, 133, 6, 37, 48, 89, 37, 55, 39, 50, 0, 0, 11, 2, 207, 130, 89, 6, 37, 100, 65, 35, 0, 0, 11, 2, 207, 131, 89, 6, 37, 100, 65, 35, 0, 0, 7, 2, 207, 128, 48, 37, 0, 7, 132, 206, 181, 206, 186, 72, 0, 7, 2, 207, 129, 51, 39, 0, 0, 0, 17, 2, 207, 142, 39, 65, 4, 36, 100, 35, 47, 6, 39, 50, 39, 89, 0, 0, 19, 2, 207, 141, 4, 37, 48, 89, 37, 55, 39, 50, 47, 6, 39, 50, 39, 89, 0, 0, 19, 2, 207, 140, 4, 39, 65, 37, 49, 34, 39, 50, 47, 6, 39, 50, 39, 89, 0, 0, 13, 2, 207, 139, 6, 37, 48, 89, 37, 55, 39, 50, 0, 0, 10, 2, 207, 138, 37, 6, 39, 47, 35, 0, 0, 11, 2, 207, 137, 39, 65, 6, 36, 100, 35, 0, 0, 8, 2, 207, 136, 48, 89, 37, 0, 0, 0, 0, 0, 17, 142, 206, 184, 206, 177, 206, 181, 206, 175, 206, 189, 206, 177, 206, 185, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 2, 206, 175, 37, 4, 39, 47, 35, 47, 6, 39, 50, 39, 89, 0, 0, 16, 2, 206, 174, 4, 37, 47, 35, 47, 6, 39, 50, 39, 89, 0, 14, 6, 130, 206, 174, 72, 8, 0, 19, 2, 206, 173, 4, 36, 48, 89, 37, 55, 39, 50, 47, 6, 39, 50, 39, 89, 0, 0, 16, 2, 206, 172, 4, 35, 55, 83, 35, 47, 6, 39, 50, 39, 89, 0, 0, 0, 0, 0, 0, 10, 2, 206, 183, 6, 37, 47, 35, 0, 14, 7, 2, 206, 183, 37, 0, 72, 0, 9, 2, 206, 182, 88, 37, 47, 35, 0, 0, 13, 2, 206, 181, 6, 36, 48, 89, 37, 55, 39, 50, 0, 0, 10, 2, 206, 180, 86, 36, 55, 47, 35, 0, 0, 9, 2, 206, 179, 100, 35, 65, 35, 0, 0, 11, 2, 95, 46, 47, 36, 55, 6, 37, 35, 0, 9, 2, 206, 178, 84, 37, 47, 35, 0, 13, 138, 206, 173, 207, 135, 206, 181, 206, 185, 207, 130, 72, 11, 2, 95, 46, 47, 36, 55, 6, 37, 35, 0, 0, 9, 2, 206, 177, 35, 55, 83, 35, 0, 0, 10, 2, 95, 44, 49, 6, 39, 65, 35, 0, 19, 2, 206, 176, 4, 37, 48, 89, 37, 55, 39, 50, 47, 6, 39, 50, 39, 89, 0, 0, 14, 2, 206, 191, 6, 39, 65, 37, 49, 34, 39, 50, 0, 14, 11, 136, 206, 181, 206, 175, 207, 135, 206, 181, 72, 7, 2, 206, 191, 39, 0, 72, 10, 2, 95, 51, 47, 34, 6, 37, 35, 0, 0, 8, 2, 206, 190, 49, 89, 37, 0, 17, 142, 206, 189, 206, 177, 206, 173, 207, 135, 206, 181, 206, 185, 207, 130, 72, 9, 2, 95, 50, 86, 6, 37, 39, 0, 0, 7, 2, 206, 189, 50, 37, 0, 9, 2, 95, 49, 6, 36, 50, 35, 0, 0, 7, 2, 206, 188, 65, 37, 0, 11, 2, 95, 48, 65, 37, 86, 6, 36, 50, 0, 0, 10, 2, 206, 187, 55, 35, 65, 86, 35, 0, 11, 136, 206, 181, 206, 175, 207, 135, 206, 177, 72, 10, 2, 95, 55, 36, 48, 47, 6, 35, 0, 0, 9, 2, 206, 186, 49, 35, 48, 35, 0, 10, 2, 95, 54, 6, 36, 49, 89, 37, 0, 0, 10, 2, 206, 185, 37, 6, 39, 47, 35, 0, 11, 2, 95, 53, 48, 6, 36, 50, 47, 36, 0, 0, 9, 2, 206, 184, 87, 37, 47, 35, 0, 12, 2, 95, 52, 47, 6, 36, 89, 36, 34, 35, 0, 0, 0, 0, 10, 2, 95, 57, 36, 50, 6, 36, 35, 0, 0, 10, 2, 95, 56, 39, 49, 47, 6, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 206, 177, 207, 128, 207, 140, 72, 0, 0, 0, 21, 6, 206, 179, 206, 185, 206, 177, 57, 35, 50, 6, 35, 0, 72, 81, 206, 189, 206, 177, 32, 9, 134, 206, 179, 206, 185, 206, 177, 8, 0, 0, 0, 0, 11, 136, 207, 128, 206, 181, 207, 129, 206, 175, 28, 0, 10, 134, 206, 180, 206, 185, 206, 172, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 4, 95, 56, 88, 15, 39, 100, 86, 120, 49, 39, 89, 47, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 140, 206, 184, 206, 177, 206, 173, 207, 135, 206, 181, 206, 185, 72, 0, 0, 17, 142, 206, 184, 206, 177, 206, 181, 206, 175, 206, 188, 206, 177, 206, 185, 72, 0, 0, 0, 0, 17, 142, 206, 181, 206, 175, 206, 188, 206, 177, 207, 131, 207, 132, 206, 181, 72, 0, 0, 0, 0, 21, 146, 206, 189, 206, 177, 206, 181, 206, 175, 206, 188, 206, 177, 207, 131, 207, 132, 206, 181, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 134, 206, 181, 206, 185, 207, 130, 72, 28, 0, 0, 0, 7, 132, 206, 184, 206, 177, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 4, 95, 57, 88, 15, 36, 50, 36, 50, 37, 49, 39, 89, 47, 6, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 207, 132, 206, 183, 207, 130, 72, 0, 0, 11, 136, 207, 131, 207, 132, 206, 183, 207, 130, 72, 11, 136, 206, 188, 206, 175, 206, 177, 207, 130, 72, 11, 136, 206, 173, 206, 189, 206, 177, 207, 130, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 207, 132, 206, 183, 206, 189, 72, 0, 0, 11, 136, 207, 131, 207, 132, 206, 183, 206, 189, 72, 11, 136, 206, 173, 206, 189, 206, 177, 206, 189, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 132, 206, 177, 206, 189, 72, 8, 0, 0, 6, 18, 66, 206, 177, 206, 185, 0, 206, 191, 206, 185, 0, 206, 181, 206, 185, 0, 206, 177, 206, 175, 0, 206, 191, 206, 175, 0, 206, 181, 206, 175, 0, 206, 181, 0, 206, 185, 0, 206, 183, 0, 207, 133, 0, 206, 173, 0, 206, 175, 0, 206, 174, 0, 207, 141, 0, 7, 6, 1, 61, 0, 3, 71, 0, 7, 6, 1, 50, 0, 207, 141, 2, 17, 66, 3, 6, 35, 83, 0, 207, 141, 3, 6, 35, 84, 0, 206, 175, 3, 6, 36, 0, 3, 35, 0, 207, 133, 2, 17, 66, 3, 35, 83, 0, 207, 133, 3, 35, 84, 0, 206, 185, 3, 36, 0, 4, 206, 183, 3, 117, 0, 207, 138, 0, 7, 6, 1, 51, 0, 2, 206, 178, 3, 0, 3, 84, 0, 7, 6, 1, 52, 0, 4, 2, 18, 66, 3, 57, 0, 206, 177, 206, 185, 2, 17, 65, 0, 206, 181, 2, 17, 65, 0, 206, 181, 206, 185, 2, 17, 65, 0, 206, 183, 2, 17, 65, 0, 206, 185, 2, 17, 65, 0, 206, 191, 206, 185, 2, 17, 65, 0, 207, 133, 2, 17, 65, 0, 2, 207, 135, 3, 68, 0, 4, 206, 179, 1, 17, 65, 3, 68, 81, 0, 206, 186, 1, 17, 65, 0, 4, 206, 179, 3, 81, 0, 206, 186, 0, 3, 100, 0, 7, 6, 1, 53, 0, 2, 206, 180, 3, 0, 3, 86, 0, 7, 6, 1, 54, 0, 4, 207, 141, 2, 206, 178, 3, 6, 36, 0, 207, 141, 2, 207, 134, 0, 207, 141, 2, 17, 66, 3, 6, 36, 83, 0, 207, 141, 3, 6, 36, 84, 0, 206, 175, 3, 6, 37, 0, 4, 3, 36, 0, 207, 133, 2, 206, 178, 0, 207, 133, 2, 207, 134, 0, 207, 133, 2, 17, 66, 3, 36, 83, 0, 207, 133, 3, 36, 84, 0, 206, 185, 3, 37, 0, 206, 185, 1, 17, 67, 2, 17, 65, 3, 99, 0, 7, 6, 1, 55, 0, 2, 206, 182, 3, 0, 3, 88, 0, 4, 206, 181, 206, 185, 2, 17, 65, 3, 88, 57, 0, 206, 183, 2, 17, 65, 0, 206, 185, 2, 17, 65, 0, 206, 191, 206, 185, 2, 17, 65, 0, 207, 133, 2, 17, 65, 0, 7, 6, 1, 56, 0, 3, 37, 0, 207, 133, 2, 17, 66, 3, 37, 83, 0, 207, 133, 3, 37, 84, 0, 7, 6, 1, 57, 0, 2, 206, 184, 3, 0, 3, 87, 0, 7, 6, 1, 58, 0, 4, 3, 37, 0, 1, 129, 207, 2, 17, 65, 0, 2, 206, 181, 0, 1, 180, 206, 2, 206, 177, 32, 3, 57, 0, 4, 1, 128, 207, 2, 17, 65, 3, 99, 0, 1, 132, 207, 2, 206, 145, 0, 1, 132, 207, 2, 206, 145, 0, 1, 186, 206, 2, 206, 145, 0, 7, 6, 1, 59, 0, 2, 206, 186, 3, 0, 3, 49, 0, 4, 2, 17, 71, 3, 80, 0, 2, 206, 177, 206, 175, 0, 2, 206, 177, 206, 185, 0, 2, 206, 191, 206, 175, 0, 2, 206, 191, 206, 185, 0, 206, 181, 206, 185, 2, 17, 65, 0, 206, 183, 2, 17, 65, 0, 206, 185, 2, 17, 65, 0, 206, 191, 206, 185, 2, 17, 65, 0, 207, 133, 2, 17, 65, 0, 1, 32, 189, 206, 3, 81, 0, 7, 6, 1, 60, 0, 2, 206, 187, 3, 0, 3, 55, 0, 4, 206, 181, 206, 185, 2, 17, 65, 3, 61, 0, 206, 183, 2, 17, 65, 0, 206, 185, 2, 17, 65, 0, 206, 191, 206, 185, 2, 17, 65, 0, 207, 133, 2, 17, 65, 0, 7, 6, 1, 61, 0, 4, 1, 17, 65, 2, 206, 188, 3, 0, 2, 207, 128, 3, 0, 3, 65, 0, 7, 6, 1, 62, 0, 2, 206, 189, 3, 0, 4, 3, 50, 0, 2, 32, 206, 186, 206, 177, 206, 185, 32, 0, 4, 2, 32, 207, 128, 3, 65, 0, 2, 32, 207, 136, 0, 4, 206, 181, 206, 185, 2, 17, 65, 3, 67, 0, 206, 183, 2, 17, 65, 0, 206, 185, 2, 17, 65, 0, 206, 191, 206, 185, 2, 17, 65, 0, 207, 133, 2, 17, 65, 0, 4, 2, 32, 206, 186, 3, 68, 0, 2, 32, 206, 190, 0, 207, 132, 3, 72, 0, 7, 6, 1, 63, 0, 2, 206, 190, 3, 0, 3, 49, 89, 0, 1, 32, 189, 206, 3, 81, 88, 0, 7, 6, 1, 64, 0, 206, 175, 3, 6, 37, 0, 207, 141, 3, 6, 40, 0, 206, 185, 3, 37, 0, 3, 39, 0, 207, 133, 3, 40, 0, 4, 206, 183, 3, 120, 0, 207, 138, 0, 7, 6, 1, 65, 0, 2, 207, 128, 3, 0, 3, 48, 0, 4, 1, 32, 189, 206, 3, 71, 0, 1, 188, 206, 0, 7, 6, 1, 66, 0, 4, 3, 34, 0, 1, 17, 65, 2, 17, 65, 0, 1, 17, 67, 0, 1, 133, 207, 177, 206, 0, 1, 133, 207, 181, 206, 0, 1, 133, 207, 183, 206, 0, 1, 141, 207, 177, 206, 0, 1, 141, 207, 181, 206, 0, 1, 141, 207, 183, 206, 0, 207, 129, 0, 7, 6, 1, 67, 0, 2, 32, 17, 67, 3, 88, 0, 4, 3, 89, 0, 2, 32, 17, 66, 0, 7, 6, 1, 68, 0, 3, 89, 0, 4, 206, 181, 206, 185, 2, 17, 65, 3, 89, 57, 0, 206, 183, 2, 17, 65, 0, 206, 185, 2, 17, 65, 0, 206, 191, 206, 185, 2, 17, 65, 0, 207, 133, 2, 17, 65, 0, 7, 6, 1, 69, 0, 2, 207, 132, 3, 0, 3, 47, 0, 1, 32, 189, 206, 3, 72, 0, 4, 206, 182, 3, 72, 88, 0, 207, 131, 1, 32, 189, 206, 0, 207, 131, 3, 123, 0, 7, 6, 1, 70, 0, 206, 175, 3, 6, 37, 0, 4, 3, 37, 0, 206, 185, 0, 7, 6, 1, 71, 0, 2, 207, 134, 3, 0, 3, 83, 0, 7, 6, 1, 72, 0, 4, 2, 17, 71, 3, 99, 0, 2, 206, 177, 206, 175, 0, 2, 206, 177, 206, 185, 0, 2, 206, 191, 206, 175, 0, 2, 206, 191, 206, 185, 0, 206, 181, 206, 185, 2, 17, 65, 0, 206, 183, 2, 17, 65, 0, 206, 185, 2, 17, 65, 0, 206, 191, 206, 185, 2, 17, 65, 0, 207, 133, 2, 17, 65, 0, 3, 101, 0, 7, 6, 1, 73, 0, 2, 207, 136, 3, 0, 3, 48, 89, 0, 1, 32, 189, 206, 3, 71, 88, 0, 7, 6, 1, 74, 0, 3, 39, 0, 7, 6, 0, 33, 1, 19, 3, 0, 206, 172, 3, 6, 35, 0, 206, 173, 3, 6, 36, 0, 4, 206, 174, 3, 6, 37, 0, 206, 175, 0, 206, 176, 0, 207, 141, 0, 4, 207, 140, 3, 6, 39, 0, 207, 142, 0, 4, 206, 172, 206, 183, 3, 6, 117, 0, 206, 172, 206, 185, 0, 4, 207, 140, 206, 183, 3, 6, 120, 0, 207, 140, 206, 185, 0, 4, 207, 138, 3, 37, 0, 207, 139, 0, 46, 3, 47, 36, 55, 6, 37, 35, 0, 44, 2, 15, 3, 49, 6, 39, 65, 35, 0, 33, 3, 87, 35, 84, 65, 35, 89, 47, 37, 49, 6, 39, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts13 = FileInMemory_createWithData (5351, reinterpret_cast (&espeakdata_dicts13_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/el_dict", U"el"); Collection_addItem (me.peek(), espeakdata_dicts13.transfer()); static unsigned char espeakdata_dicts14_data[94548] = { 0, 4, 0, 0, 180, 191, 0, 0, 13, 69, 65, 33, 67, 37, 48, 48, 34, 138, 89, 129, 0, 0, 14, 70, 56, 21, 83, 20, 19, 64, 50, 130, 88, 141, 65, 0, 0, 17, 71, 52, 16, 203, 20, 230, 137, 20, 65, 13, 49, 121, 50, 88, 37, 0, 0, 12, 68, 76, 81, 213, 20, 89, 121, 81, 58, 138, 0, 11, 200, 24, 244, 133, 76, 128, 68, 61, 112, 66, 10, 68, 21, 148, 137, 20, 141, 34, 37, 0, 0, 14, 69, 52, 147, 4, 21, 112, 65, 122, 55, 72, 57, 134, 0, 12, 68, 32, 20, 212, 100, 107, 138, 89, 47, 122, 0, 0, 11, 65, 4, 35, 55, 35, 0, 81, 108, 97, 32, 16, 65, 4, 119, 15, 58, 137, 55, 0, 81, 119, 104, 105, 108, 101, 32, 12, 69, 12, 243, 142, 61, 32, 49, 124, 50, 114, 0, 16, 70, 80, 244, 142, 4, 67, 192, 47, 132, 50, 6, 138, 72, 136, 0, 13, 69, 80, 129, 83, 37, 48, 87, 129, 89, 122, 89, 0, 19, 65, 4, 35, 49, 119, 11, 0, 85, 46, 32, 107, 32, 46, 32, 97, 32, 46, 32, 6, 65, 4, 138, 0, 14, 4, 193, 4, 34, 0, 11, 67, 84, 225, 15, 125, 50, 72, 6, 134, 0, 14, 70, 61, 85, 23, 5, 33, 0, 135, 47, 58, 114, 72, 0, 19, 71, 52, 21, 83, 60, 193, 85, 52, 65, 130, 89, 13, 6, 55, 129, 13, 65, 0, 16, 70, 12, 243, 150, 20, 229, 0, 49, 124, 50, 84, 13, 50, 47, 0, 13, 69, 5, 0, 67, 32, 80, 119, 48, 35, 76, 37, 0, 0, 0, 10, 68, 72, 81, 83, 20, 34, 129, 89, 0, 11, 68, 37, 48, 65, 12, 137, 89, 13, 49, 0, 13, 68, 9, 86, 15, 52, 71, 125, 49, 89, 13, 65, 0, 21, 72, 4, 229, 9, 80, 129, 83, 37, 48, 35, 50, 47, 6, 122, 87, 13, 89, 122, 89, 0, 0, 14, 69, 8, 84, 140, 36, 224, 71, 128, 55, 6, 122, 50, 0, 13, 69, 72, 83, 9, 76, 128, 34, 121, 55, 113, 91, 0, 11, 67, 13, 144, 78, 89, 137, 6, 35, 50, 0, 15, 69, 12, 243, 150, 20, 224, 49, 124, 50, 84, 6, 129, 50, 0, 23, 73, 12, 243, 80, 21, 66, 84, 36, 243, 128, 49, 124, 65, 48, 13, 47, 6, 122, 91, 13, 50, 0, 6, 65, 8, 71, 129, 0, 0, 16, 70, 4, 229, 9, 29, 80, 64, 35, 50, 47, 6, 129, 81, 13, 0, 15, 70, 88, 17, 213, 21, 53, 0, 84, 138, 81, 13, 89, 47, 0, 14, 70, 76, 227, 207, 44, 84, 128, 89, 50, 134, 49, 114, 0, 15, 70, 61, 85, 12, 36, 84, 128, 6, 135, 47, 55, 4, 145, 0, 15, 70, 36, 51, 206, 8, 20, 128, 137, 49, 124, 50, 71, 127, 0, 15, 70, 12, 21, 5, 72, 84, 128, 49, 138, 47, 114, 34, 114, 0, 0, 6, 195, 85, 64, 192, 17, 14, 67, 21, 64, 192, 121, 47, 6, 89, 121, 47, 34, 13, 0, 0, 10, 67, 12, 17, 133, 49, 35, 83, 138, 0, 0, 12, 69, 16, 145, 83, 20, 192, 72, 129, 88, 118, 0, 17, 70, 4, 224, 76, 101, 50, 83, 119, 50, 35, 55, 13, 89, 122, 89, 0, 6, 65, 12, 89, 129, 0, 0, 9, 198, 4, 193, 201, 21, 36, 192, 66, 16, 70, 76, 83, 148, 36, 83, 148, 89, 121, 50, 47, 141, 50, 47, 0, 0, 19, 71, 21, 132, 5, 73, 66, 83, 20, 121, 49, 89, 48, 114, 47, 6, 129, 88, 0, 14, 4, 95, 8, 1, 3, 107, 6, 35, 76, 4, 121, 49, 0, 0, 12, 68, 85, 48, 71, 20, 57, 134, 89, 113, 75, 0, 0, 13, 69, 53, 84, 141, 85, 32, 65, 148, 65, 114, 0, 105, 12, 69, 53, 84, 141, 85, 32, 65, 128, 65, 114, 0, 13, 69, 8, 19, 12, 61, 64, 71, 35, 55, 13, 47, 0, 6, 65, 16, 72, 129, 0, 0, 15, 70, 65, 81, 82, 36, 193, 64, 48, 57, 143, 34, 118, 0, 103, 14, 70, 72, 82, 78, 36, 225, 192, 34, 138, 50, 122, 68, 0, 17, 70, 36, 224, 197, 57, 49, 64, 122, 50, 89, 6, 121, 50, 89, 0, 36, 0, 16, 70, 64, 20, 211, 21, 32, 153, 48, 35, 89, 114, 71, 6, 137, 0, 19, 71, 36, 212, 18, 20, 50, 83, 20, 122, 65, 48, 34, 122, 89, 6, 137, 89, 0, 20, 71, 4, 35, 210, 36, 114, 78, 20, 35, 71, 13, 34, 6, 122, 75, 13, 50, 37, 0, 0, 12, 68, 29, 84, 149, 76, 81, 134, 34, 134, 88, 0, 12, 68, 24, 198, 66, 100, 83, 55, 137, 71, 137, 0, 0, 8, 197, 52, 81, 21, 76, 16, 66, 15, 69, 37, 64, 76, 36, 16, 122, 47, 6, 35, 55, 113, 13, 0, 18, 70, 5, 48, 133, 77, 67, 211, 35, 89, 71, 6, 121, 89, 47, 13, 89, 0, 21, 65, 20, 83, 132, 121, 81, 88, 6, 120, 65, 48, 118, 0, 83, 46, 32, 103, 32, 46, 32, 5, 65, 20, 129, 0, 0, 14, 70, 52, 147, 12, 36, 243, 128, 65, 122, 55, 141, 50, 0, 15, 70, 8, 148, 195, 84, 149, 0, 71, 122, 89, 49, 122, 47, 0, 0, 17, 70, 36, 225, 21, 77, 68, 153, 122, 50, 72, 125, 89, 47, 34, 122, 0, 0, 12, 68, 56, 147, 138, 4, 50, 122, 50, 75, 13, 0, 15, 70, 52, 85, 1, 64, 131, 210, 65, 121, 47, 13, 83, 132, 0, 13, 68, 4, 69, 76, 80, 35, 72, 125, 55, 47, 0, 135, 0, 15, 69, 16, 210, 84, 72, 144, 72, 13, 65, 129, 47, 34, 37, 0, 8, 197, 52, 86, 9, 12, 240, 65, 14, 69, 32, 21, 193, 36, 144, 107, 13, 58, 6, 137, 129, 0, 13, 69, 17, 84, 136, 4, 208, 72, 125, 34, 13, 65, 0, 13, 69, 72, 80, 129, 80, 80, 34, 129, 71, 138, 47, 0, 13, 69, 64, 148, 129, 80, 80, 48, 137, 34, 13, 47, 0, 14, 69, 52, 18, 143, 72, 16, 65, 119, 75, 133, 34, 13, 0, 14, 69, 44, 20, 129, 80, 80, 49, 13, 34, 126, 47, 37, 0, 13, 69, 4, 84, 129, 80, 80, 140, 34, 6, 138, 47, 0, 6, 65, 24, 121, 83, 0, 0, 17, 70, 65, 33, 84, 21, 133, 0, 48, 34, 129, 108, 121, 49, 89, 47, 0, 0, 17, 71, 5, 32, 200, 36, 32, 76, 16, 127, 76, 122, 71, 130, 55, 72, 0, 19, 67, 92, 147, 132, 58, 6, 137, 50, 72, 15, 6, 125, 48, 0, 81, 117, 112, 32, 23, 67, 92, 147, 132, 58, 6, 122, 50, 72, 15, 48, 6, 135, 114, 0, 81, 112, 111, 119, 101, 114, 32, 11, 67, 92, 147, 132, 58, 137, 50, 72, 0, 36, 0, 9, 67, 16, 243, 133, 72, 125, 50, 0, 18, 72, 64, 130, 76, 48, 148, 9, 56, 80, 83, 122, 55, 113, 48, 129, 50, 0, 9, 67, 80, 243, 133, 47, 136, 50, 0, 13, 68, 20, 208, 133, 16, 121, 65, 71, 6, 121, 72, 0, 0, 14, 69, 52, 243, 129, 12, 240, 65, 124, 50, 13, 49, 136, 0, 13, 69, 72, 17, 9, 76, 128, 34, 35, 72, 122, 91, 0, 13, 69, 24, 147, 137, 80, 80, 83, 137, 50, 137, 47, 0, 14, 69, 16, 148, 205, 4, 192, 72, 122, 88, 65, 13, 55, 0, 6, 65, 28, 75, 129, 0, 0, 14, 70, 64, 197, 77, 8, 84, 128, 48, 55, 125, 65, 114, 0, 0, 17, 70, 21, 97, 82, 100, 243, 133, 121, 84, 34, 122, 58, 125, 50, 0, 106, 16, 70, 21, 97, 82, 100, 243, 133, 121, 84, 34, 122, 58, 124, 50, 0, 15, 7, 20, 8, 5, 25, 39, 12, 12, 86, 138, 55, 0, 72, 32, 13, 67, 12, 19, 128, 2, 49, 35, 50, 0, 32, 9, 12, 16, 70, 88, 20, 197, 48, 147, 133, 84, 35, 89, 13, 55, 129, 50, 0, 10, 67, 80, 243, 128, 47, 125, 50, 0, 10, 11, 67, 76, 19, 128, 4, 89, 35, 50, 0, 9, 14, 4, 95, 54, 48, 15, 89, 6, 122, 49, 89, 47, 141, 0, 0, 0, 14, 69, 44, 19, 147, 5, 48, 49, 35, 50, 88, 13, 89, 0, 13, 69, 24, 82, 83, 81, 144, 83, 137, 89, 47, 37, 0, 6, 65, 32, 138, 76, 0, 0, 16, 70, 32, 245, 83, 80, 243, 128, 107, 57, 134, 89, 47, 13, 50, 0, 17, 70, 36, 226, 5, 72, 149, 0, 122, 50, 107, 6, 121, 34, 122, 47, 0, 14, 70, 13, 84, 2, 60, 20, 132, 49, 125, 71, 13, 72, 0, 9, 198, 4, 229, 9, 28, 83, 128, 65, 0, 17, 71, 52, 17, 5, 48, 82, 78, 20, 65, 35, 72, 13, 55, 113, 50, 0, 20, 71, 65, 33, 83, 20, 229, 12, 100, 48, 34, 121, 88, 13, 50, 47, 55, 122, 0, 32, 0, 11, 67, 4, 229, 9, 35, 50, 47, 137, 0, 103, 11, 68, 37, 33, 78, 20, 137, 34, 129, 50, 0, 12, 68, 80, 242, 217, 60, 47, 136, 49, 122, 136, 0, 10, 68, 60, 50, 18, 20, 136, 49, 114, 0, 10, 67, 36, 225, 25, 122, 50, 72, 37, 0, 8, 1, 35, 107, 35, 91, 0, 27, 0, 14, 65, 36, 2, 137, 35, 65, 0, 14, 42, 81, 97, 109, 32, 13, 65, 36, 2, 137, 119, 65, 0, 42, 81, 97, 109, 32, 9, 65, 36, 137, 0, 76, 32, 9, 42, 16, 70, 88, 84, 148, 36, 49, 83, 84, 128, 47, 122, 89, 129, 88, 0, 5, 65, 36, 137, 0, 0, 12, 67, 84, 229, 15, 4, 125, 50, 108, 117, 0, 103, 11, 67, 84, 229, 15, 4, 125, 50, 47, 117, 0, 17, 70, 37, 0, 78, 20, 208, 64, 122, 48, 119, 50, 6, 129, 65, 13, 0, 15, 70, 88, 147, 133, 100, 20, 132, 84, 122, 50, 57, 114, 72, 0, 14, 70, 76, 129, 80, 32, 84, 132, 91, 121, 48, 13, 72, 0, 16, 70, 16, 80, 146, 36, 81, 128, 72, 129, 71, 34, 6, 129, 83, 0, 13, 1, 37, 48, 148, 89, 6, 121, 50, 47, 0, 105, 27, 12, 1, 37, 48, 114, 89, 6, 121, 50, 47, 0, 27, 0, 11, 67, 37, 68, 192, 122, 47, 89, 0, 72, 34, 13, 70, 12, 129, 83, 32, 148, 133, 76, 121, 91, 114, 0, 8, 67, 100, 84, 128, 57, 114, 0, 9, 1, 38, 10, 35, 50, 72, 0, 76, 0, 16, 70, 60, 48, 213, 64, 145, 82, 124, 49, 57, 134, 48, 137, 114, 0, 0, 24, 73, 92, 244, 139, 77, 64, 84, 36, 243, 128, 58, 6, 148, 49, 89, 47, 4, 138, 91, 13, 50, 0, 105, 23, 73, 92, 244, 139, 77, 64, 84, 36, 243, 128, 58, 6, 128, 49, 89, 47, 4, 138, 91, 13, 50, 0, 13, 69, 61, 33, 5, 4, 192, 132, 72, 6, 141, 55, 0, 16, 70, 52, 16, 200, 37, 51, 79, 65, 119, 76, 122, 88, 65, 136, 0, 18, 8, 4, 195, 169, 20, 5, 14, 20, 5, 72, 138, 47, 6, 124, 50, 47, 0, 23, 73, 12, 243, 148, 72, 20, 20, 36, 243, 128, 49, 13, 50, 47, 34, 6, 35, 48, 91, 13, 50, 0, 6, 65, 40, 75, 138, 0, 0, 15, 70, 80, 129, 82, 21, 48, 64, 47, 13, 34, 129, 88, 13, 0, 16, 70, 84, 229, 207, 84, 225, 0, 125, 50, 58, 6, 135, 50, 72, 0, 9, 198, 32, 245, 197, 88, 84, 128, 66, 0, 11, 67, 76, 148, 128, 89, 4, 148, 0, 105, 9, 10, 67, 76, 148, 128, 89, 4, 128, 0, 9, 11, 67, 16, 243, 148, 72, 136, 50, 47, 0, 9, 15, 70, 8, 245, 84, 37, 21, 69, 71, 134, 47, 6, 129, 49, 0, 17, 71, 4, 116, 133, 77, 50, 86, 20, 119, 81, 34, 121, 89, 122, 84, 0, 13, 1, 42, 35, 89, 47, 13, 34, 122, 89, 49, 0, 27, 0, 12, 68, 56, 17, 9, 4, 50, 126, 72, 57, 13, 0, 9, 1, 43, 48, 55, 125, 89, 0, 27, 0, 15, 70, 36, 195, 9, 56, 242, 83, 122, 55, 13, 50, 6, 139, 0, 12, 69, 76, 145, 206, 21, 32, 89, 137, 50, 114, 0, 16, 70, 36, 224, 207, 52, 147, 135, 122, 50, 49, 125, 65, 122, 68, 0, 16, 69, 21, 133, 18, 20, 208, 121, 49, 89, 47, 34, 6, 129, 65, 0, 6, 65, 44, 49, 138, 0, 0, 15, 70, 76, 84, 135, 20, 19, 148, 89, 127, 75, 13, 50, 47, 0, 16, 70, 61, 4, 15, 56, 83, 148, 13, 48, 136, 50, 13, 50, 47, 0, 14, 70, 16, 145, 72, 5, 33, 0, 72, 137, 107, 127, 72, 0, 0, 19, 4, 9, 20, 39, 19, 122, 47, 89, 107, 35, 72, 0, 78, 81, 104, 97, 100, 32, 16, 70, 72, 83, 1, 80, 149, 133, 34, 121, 55, 13, 47, 122, 84, 0, 17, 70, 65, 83, 129, 80, 149, 133, 48, 57, 134, 50, 13, 47, 122, 84, 0, 15, 70, 56, 244, 197, 16, 149, 133, 50, 136, 88, 72, 137, 84, 0, 17, 71, 20, 229, 15, 85, 32, 71, 20, 124, 50, 108, 117, 34, 126, 90, 0, 10, 67, 5, 67, 208, 119, 47, 124, 48, 0, 0, 24, 67, 25, 35, 205, 2, 83, 34, 125, 65, 15, 58, 6, 122, 76, 0, 8, 81, 119, 104, 105, 99, 104, 32, 23, 67, 25, 35, 205, 2, 83, 34, 125, 65, 15, 58, 6, 140, 0, 8, 81, 119, 104, 101, 114, 101, 32, 12, 67, 25, 35, 205, 83, 34, 125, 65, 0, 103, 72, 11, 67, 25, 35, 205, 83, 34, 124, 65, 0, 72, 11, 68, 56, 21, 82, 84, 50, 135, 34, 134, 0, 9, 198, 20, 229, 18, 4, 147, 0, 65, 10, 67, 4, 229, 5, 35, 50, 47, 129, 0, 9, 1, 47, 89, 55, 35, 91, 0, 27, 0, 6, 65, 48, 121, 55, 0, 0, 14, 70, 80, 129, 82, 21, 49, 64, 47, 13, 34, 129, 88, 0, 9, 198, 12, 130, 78, 21, 49, 64, 66, 9, 198, 77, 81, 134, 85, 49, 64, 66, 0, 19, 71, 80, 20, 203, 24, 244, 131, 20, 47, 6, 35, 89, 49, 83, 4, 133, 89, 0, 19, 71, 36, 212, 5, 16, 19, 131, 20, 122, 65, 48, 6, 129, 72, 13, 50, 89, 0, 0, 12, 68, 56, 17, 10, 4, 50, 126, 72, 57, 13, 0, 10, 67, 28, 20, 153, 81, 35, 34, 37, 0, 12, 68, 72, 83, 9, 12, 34, 121, 55, 122, 49, 0, 13, 68, 60, 20, 197, 76, 136, 6, 138, 89, 129, 88, 0, 15, 70, 12, 130, 70, 25, 35, 206, 91, 122, 83, 34, 124, 50, 0, 0, 22, 73, 92, 129, 69, 48, 32, 82, 72, 245, 192, 58, 6, 129, 55, 10, 71, 4, 35, 34, 136, 0, 13, 69, 5, 98, 65, 73, 144, 138, 84, 141, 34, 37, 0, 6, 65, 52, 121, 65, 0, 0, 15, 70, 65, 33, 67, 37, 49, 64, 48, 34, 113, 89, 137, 89, 0, 0, 10, 199, 56, 240, 212, 85, 35, 129, 48, 66, 0, 11, 68, 100, 17, 83, 84, 57, 138, 89, 134, 0, 21, 72, 81, 32, 74, 20, 53, 15, 73, 144, 47, 34, 13, 75, 121, 49, 47, 13, 34, 122, 0, 12, 68, 77, 82, 84, 20, 89, 58, 129, 47, 0, 10, 0, 15, 69, 8, 84, 201, 16, 80, 71, 122, 89, 137, 72, 0, 74, 12, 14, 69, 32, 80, 193, 80, 80, 107, 121, 49, 13, 47, 138, 0, 11, 67, 49, 99, 214, 55, 14, 84, 124, 84, 0, 22, 73, 72, 84, 197, 73, 96, 84, 36, 243, 128, 34, 121, 88, 114, 84, 6, 138, 91, 13, 50, 0, 15, 69, 24, 81, 15, 72, 16, 83, 113, 72, 6, 133, 34, 13, 0, 23, 73, 16, 80, 204, 5, 32, 84, 36, 243, 128, 72, 121, 49, 55, 13, 6, 34, 138, 91, 13, 50, 0, 11, 5, 95, 48, 1, 14, 4, 13, 50, 0, 135, 6, 65, 56, 121, 50, 0, 0, 10, 67, 36, 225, 15, 122, 50, 72, 136, 0, 0, 20, 71, 88, 145, 201, 48, 19, 148, 20, 84, 122, 75, 113, 55, 6, 35, 50, 47, 37, 0, 9, 198, 76, 83, 73, 80, 243, 133, 65, 19, 71, 52, 20, 137, 41, 80, 78, 4, 65, 35, 34, 113, 58, 6, 126, 50, 13, 0, 17, 71, 21, 98, 76, 16, 241, 82, 76, 129, 84, 118, 72, 134, 114, 88, 0, 16, 70, 16, 240, 212, 72, 147, 133, 72, 124, 49, 47, 34, 113, 50, 0, 0, 13, 68, 72, 80, 133, 48, 34, 113, 71, 121, 55, 0, 36, 18, 72, 8, 192, 78, 12, 208, 78, 28, 80, 71, 55, 13, 65, 124, 50, 90, 0, 18, 72, 4, 195, 5, 28, 144, 78, 12, 80, 119, 55, 129, 75, 13, 50, 89, 0, 0, 14, 69, 32, 82, 193, 80, 80, 107, 121, 49, 13, 47, 138, 0, 13, 69, 8, 160, 82, 56, 80, 71, 57, 127, 50, 13, 0, 13, 69, 16, 19, 12, 5, 48, 72, 35, 55, 13, 89, 0, 5, 65, 60, 136, 0, 0, 14, 6, 19, 8, 5, 39, 12, 12, 91, 129, 55, 0, 72, 32, 10, 67, 81, 112, 83, 47, 58, 124, 88, 0, 13, 69, 61, 0, 81, 84, 80, 136, 48, 6, 138, 49, 0, 12, 1, 61, 9, 129, 49, 58, 118, 88, 9, 0, 27, 0, 16, 70, 52, 17, 5, 48, 147, 133, 65, 35, 72, 13, 55, 113, 50, 0, 18, 70, 16, 144, 83, 64, 244, 129, 72, 137, 6, 35, 89, 48, 13, 34, 13, 0, 0, 12, 4, 9, 20, 39, 4, 2, 122, 47, 13, 72, 0, 0, 12, 201, 16, 148, 212, 72, 144, 149, 80, 244, 128, 66, 14, 69, 16, 84, 195, 73, 144, 72, 113, 89, 49, 34, 138, 0, 9, 1, 64, 10, 35, 47, 10, 0, 76, 6, 65, 64, 48, 129, 0, 0, 15, 6, 20, 8, 1, 20, 39, 4, 2, 86, 35, 47, 13, 72, 0, 15, 70, 80, 129, 82, 21, 67, 192, 4, 86, 140, 6, 47, 134, 0, 9, 198, 65, 33, 83, 20, 229, 0, 36, 17, 70, 65, 33, 83, 20, 229, 0, 48, 34, 121, 88, 13, 50, 47, 0, 9, 15, 70, 61, 3, 211, 77, 83, 64, 13, 48, 124, 89, 13, 65, 0, 23, 74, 12, 243, 135, 72, 84, 211, 36, 243, 129, 48, 49, 13, 50, 81, 34, 121, 91, 13, 50, 118, 0, 0, 10, 67, 8, 193, 72, 71, 55, 121, 107, 0, 0, 0, 13, 69, 76, 145, 206, 85, 0, 89, 137, 50, 125, 48, 0, 18, 70, 4, 224, 76, 101, 49, 83, 35, 50, 13, 55, 137, 88, 123, 88, 0, 36, 17, 70, 4, 224, 76, 101, 49, 83, 119, 50, 35, 55, 13, 89, 129, 88, 0, 7, 65, 68, 49, 57, 134, 0, 0, 21, 67, 80, 130, 83, 86, 6, 122, 89, 58, 4, 125, 50, 0, 103, 33, 81, 111, 110, 101, 32, 20, 67, 80, 130, 83, 86, 6, 122, 89, 58, 4, 124, 50, 0, 33, 81, 111, 110, 101, 32, 12, 67, 80, 130, 83, 86, 122, 89, 0, 76, 34, 33, 17, 70, 52, 243, 148, 4, 224, 64, 65, 124, 50, 47, 6, 35, 50, 13, 0, 15, 70, 64, 148, 129, 56, 128, 64, 48, 13, 34, 126, 50, 13, 0, 15, 70, 64, 17, 197, 4, 229, 0, 48, 35, 75, 13, 50, 47, 0, 16, 70, 12, 130, 77, 21, 32, 64, 49, 137, 65, 6, 141, 34, 13, 0, 16, 70, 4, 64, 77, 4, 229, 0, 35, 72, 13, 65, 13, 50, 47, 0, 0, 10, 67, 84, 224, 64, 57, 134, 50, 13, 0, 15, 70, 81, 33, 65, 80, 148, 197, 47, 34, 129, 47, 122, 88, 0, 0, 11, 67, 80, 129, 77, 4, 86, 121, 65, 0, 9, 26, 68, 76, 19, 148, 4, 89, 6, 35, 50, 47, 13, 15, 49, 55, 6, 130, 88, 0, 81, 99, 108, 97, 117, 115, 32, 11, 68, 61, 48, 193, 72, 124, 89, 49, 114, 0, 11, 68, 17, 80, 78, 20, 72, 58, 138, 50, 0, 10, 68, 93, 34, 84, 32, 34, 137, 86, 0, 13, 68, 76, 19, 15, 56, 89, 119, 55, 124, 50, 0, 103, 12, 68, 64, 83, 137, 76, 48, 129, 50, 113, 89, 0, 17, 70, 20, 193, 67, 81, 35, 206, 113, 55, 121, 49, 47, 34, 124, 50, 0, 0, 10, 67, 80, 129, 78, 86, 121, 50, 0, 32, 13, 69, 28, 144, 130, 60, 224, 81, 122, 71, 13, 50, 0, 5, 65, 72, 127, 0, 0, 14, 70, 80, 80, 82, 28, 20, 192, 47, 142, 81, 35, 89, 0, 15, 70, 52, 246, 137, 48, 192, 64, 65, 13, 88, 122, 55, 13, 0, 16, 70, 49, 83, 129, 80, 144, 192, 55, 134, 50, 13, 47, 122, 49, 0, 17, 70, 48, 20, 193, 28, 224, 64, 55, 13, 88, 126, 50, 57, 13, 0, 103, 16, 70, 48, 20, 193, 28, 224, 64, 55, 13, 88, 35, 50, 57, 13, 0, 0, 19, 67, 80, 129, 64, 86, 115, 15, 58, 137, 55, 0, 81, 119, 104, 105, 108, 101, 32, 10, 67, 80, 129, 64, 86, 115, 0, 9, 34, 17, 70, 25, 84, 197, 48, 17, 197, 83, 57, 134, 88, 13, 55, 126, 90, 0, 0, 0, 14, 69, 9, 32, 90, 36, 192, 71, 34, 119, 88, 122, 55, 0, 13, 69, 77, 2, 78, 4, 192, 89, 48, 137, 50, 118, 0, 12, 69, 76, 130, 86, 21, 32, 91, 122, 84, 114, 0, 13, 69, 65, 149, 8, 60, 224, 48, 137, 87, 13, 50, 0, 14, 69, 8, 243, 130, 60, 224, 71, 124, 50, 71, 124, 50, 0, 16, 8, 95, 2, 18, 1, 9, 12, 12, 5, 71, 34, 6, 138, 55, 0, 0, 9, 198, 85, 4, 212, 5, 37, 0, 65, 13, 68, 77, 0, 83, 52, 89, 48, 35, 89, 13, 65, 0, 17, 71, 77, 0, 71, 32, 85, 20, 36, 89, 48, 119, 81, 121, 47, 37, 0, 9, 198, 76, 20, 132, 36, 225, 64, 66, 9, 198, 72, 245, 84, 36, 225, 64, 66, 15, 70, 72, 80, 193, 48, 193, 68, 34, 113, 49, 130, 55, 72, 0, 9, 198, 53, 83, 132, 4, 225, 64, 66, 16, 70, 36, 225, 9, 12, 84, 192, 122, 50, 72, 113, 89, 129, 88, 0, 0, 9, 67, 48, 240, 200, 55, 124, 101, 0, 9, 67, 28, 145, 192, 81, 122, 81, 0, 19, 71, 12, 243, 80, 21, 66, 78, 28, 49, 13, 65, 48, 6, 129, 47, 122, 68, 0, 9, 67, 12, 16, 200, 49, 35, 91, 0, 0, 9, 67, 80, 129, 69, 4, 86, 129, 0, 10, 67, 76, 17, 193, 89, 126, 81, 13, 0, 11, 200, 4, 229, 9, 12, 132, 137, 77, 64, 65, 0, 14, 69, 8, 82, 82, 85, 64, 71, 138, 34, 6, 134, 47, 0, 8, 197, 85, 4, 143, 61, 64, 66, 14, 69, 81, 37, 69, 77, 64, 47, 34, 134, 13, 89, 47, 0, 6, 65, 80, 47, 129, 0, 0, 15, 70, 25, 32, 71, 36, 193, 64, 83, 34, 35, 75, 118, 0, 103, 14, 70, 52, 21, 20, 32, 85, 192, 65, 35, 87, 57, 134, 0, 17, 70, 48, 20, 193, 28, 225, 64, 108, 97, 115, 97, 103, 110, 97, 0, 29, 5, 194, 4, 48, 17, 0, 9, 67, 76, 146, 200, 89, 129, 49, 0, 13, 70, 12, 21, 1, 73, 34, 0, 49, 13, 47, 127, 0, 6, 195, 12, 147, 192, 17, 0, 16, 70, 69, 81, 83, 80, 147, 206, 49, 58, 121, 89, 76, 13, 50, 0, 13, 68, 44, 80, 129, 8, 49, 13, 71, 126, 71, 0, 103, 12, 68, 44, 80, 129, 8, 49, 13, 71, 35, 71, 0, 11, 68, 20, 208, 133, 72, 121, 65, 71, 114, 0, 0, 14, 69, 8, 245, 212, 36, 80, 71, 4, 136, 47, 6, 137, 0, 6, 65, 84, 57, 134, 0, 0, 9, 66, 85, 0, 4, 125, 48, 0, 12, 10, 67, 77, 147, 131, 89, 122, 68, 49, 0, 16, 70, 16, 83, 9, 52, 149, 0, 72, 113, 55, 122, 65, 122, 47, 0, 16, 70, 12, 195, 211, 20, 198, 64, 49, 55, 136, 89, 55, 122, 0, 32, 0, 10, 67, 84, 226, 64, 57, 134, 50, 37, 0, 28, 75, 77, 84, 5, 72, 147, 148, 20, 225, 5, 57, 64, 89, 134, 48, 114, 122, 50, 47, 6, 121, 50, 72, 13, 50, 47, 0, 0, 22, 7, 20, 8, 5, 25, 39, 22, 5, 86, 138, 84, 107, 35, 72, 0, 78, 81, 104, 97, 100, 32, 15, 7, 20, 8, 5, 25, 39, 22, 5, 86, 138, 84, 0, 72, 35, 13, 68, 17, 80, 78, 4, 72, 58, 6, 126, 50, 13, 0, 12, 68, 52, 243, 148, 20, 65, 124, 50, 108, 37, 0, 11, 67, 84, 229, 25, 125, 50, 47, 6, 137, 0, 0, 12, 69, 72, 81, 199, 36, 80, 34, 121, 75, 37, 0, 14, 69, 76, 195, 214, 4, 176, 89, 55, 136, 84, 35, 49, 0, 14, 69, 69, 81, 66, 20, 48, 49, 58, 113, 71, 121, 49, 0, 13, 69, 80, 245, 67, 32, 80, 47, 134, 91, 138, 0, 9, 14, 69, 76, 84, 193, 52, 80, 89, 121, 89, 119, 65, 37, 0, 9, 67, 4, 96, 82, 119, 83, 127, 0, 6, 65, 88, 84, 129, 0, 0, 21, 66, 5, 48, 4, 35, 88, 122, 47, 4, 122, 88, 0, 76, 82, 105, 116, 32, 105, 115, 32, 16, 66, 5, 48, 4, 35, 88, 4, 122, 88, 0, 8, 81, 105, 115, 32, 9, 66, 5, 48, 2, 35, 88, 0, 9, 12, 67, 36, 229, 15, 4, 122, 50, 108, 117, 0, 103, 11, 67, 36, 229, 15, 4, 122, 50, 47, 117, 0, 9, 198, 65, 35, 202, 20, 53, 0, 36, 17, 70, 65, 35, 202, 20, 53, 0, 48, 34, 124, 75, 121, 49, 47, 0, 10, 0, 23, 73, 36, 228, 212, 4, 195, 1, 80, 147, 206, 122, 50, 89, 47, 13, 55, 6, 138, 91, 13, 50, 0, 17, 71, 12, 128, 77, 60, 210, 76, 20, 49, 35, 65, 13, 65, 137, 55, 0, 0, 11, 4, 9, 39, 12, 12, 137, 55, 0, 72, 32, 12, 68, 88, 147, 153, 48, 84, 137, 50, 113, 55, 0, 12, 200, 77, 64, 76, 4, 115, 73, 80, 80, 103, 66, 20, 72, 12, 243, 77, 84, 226, 81, 84, 80, 49, 13, 65, 57, 134, 50, 113, 49, 138, 0, 13, 68, 12, 16, 129, 48, 49, 119, 71, 126, 55, 0, 103, 12, 68, 12, 16, 129, 48, 49, 119, 71, 35, 55, 0, 0, 13, 69, 52, 20, 137, 4, 224, 65, 35, 34, 141, 50, 0, 14, 69, 76, 145, 206, 4, 192, 89, 122, 81, 50, 13, 55, 0, 22, 73, 65, 84, 144, 61, 37, 5, 16, 198, 64, 48, 114, 48, 6, 133, 47, 113, 72, 55, 122, 0, 13, 69, 64, 85, 9, 80, 80, 48, 13, 47, 129, 47, 0, 12, 1, 92, 71, 35, 49, 89, 55, 35, 91, 0, 27, 11, 65, 92, 72, 6, 125, 71, 118, 57, 134, 0, 0, 14, 70, 32, 145, 5, 61, 85, 0, 107, 137, 72, 135, 47, 0, 0, 20, 67, 80, 243, 192, 47, 6, 134, 15, 65, 4, 125, 76, 0, 81, 109, 117, 99, 104, 32, 21, 67, 80, 243, 192, 47, 6, 134, 15, 65, 4, 121, 50, 37, 0, 81, 109, 97, 110, 121, 32, 19, 67, 80, 243, 192, 47, 6, 134, 15, 83, 4, 57, 134, 0, 81, 102, 101, 119, 32, 15, 70, 5, 1, 78, 56, 147, 133, 35, 48, 13, 50, 137, 50, 0, 9, 67, 4, 224, 76, 138, 50, 118, 0, 15, 4, 95, 55, 48, 15, 89, 6, 121, 84, 13, 50, 47, 141, 0, 0, 12, 4, 23, 5, 39, 4, 58, 129, 72, 0, 72, 35, 19, 72, 92, 147, 4, 21, 35, 133, 77, 48, 58, 122, 55, 72, 114, 50, 121, 89, 0, 13, 68, 84, 225, 133, 16, 125, 50, 83, 6, 121, 72, 0, 17, 70, 16, 144, 77, 21, 65, 82, 72, 137, 6, 35, 65, 113, 47, 114, 0, 0, 13, 69, 72, 80, 76, 49, 144, 34, 141, 55, 122, 0, 32, 7, 65, 96, 121, 49, 89, 0, 0, 16, 70, 52, 20, 137, 49, 147, 128, 65, 35, 34, 13, 55, 113, 50, 0, 10, 67, 4, 225, 87, 119, 50, 134, 0, 103, 10, 67, 4, 225, 87, 119, 50, 57, 134, 0, 0, 16, 70, 76, 130, 73, 80, 18, 197, 91, 129, 47, 6, 126, 49, 152, 0, 16, 70, 65, 32, 67, 80, 148, 197, 48, 34, 35, 49, 47, 113, 89, 0, 8, 67, 4, 65, 0, 35, 72, 0, 0, 11, 68, 92, 19, 12, 100, 58, 124, 55, 37, 0, 12, 68, 17, 32, 67, 60, 72, 34, 138, 49, 136, 0, 21, 72, 81, 32, 78, 77, 3, 210, 81, 48, 47, 34, 35, 50, 89, 48, 133, 47, 89, 0, 34, 10, 67, 60, 33, 89, 136, 71, 6, 138, 0, 9, 67, 16, 244, 197, 72, 136, 89, 0, 0, 12, 67, 16, 245, 206, 4, 72, 135, 50, 0, 9, 12, 0, 9, 198, 56, 21, 1, 76, 128, 64, 66, 10, 67, 4, 211, 211, 138, 65, 124, 89, 0, 16, 70, 64, 84, 147, 60, 224, 64, 48, 128, 89, 6, 136, 50, 13, 0, 16, 70, 8, 83, 9, 76, 128, 64, 71, 13, 55, 6, 129, 91, 13, 0, 0, 18, 70, 77, 83, 1, 92, 84, 201, 89, 134, 55, 119, 58, 6, 138, 89, 37, 0, 15, 70, 56, 80, 203, 48, 16, 197, 50, 121, 49, 55, 13, 89, 0, 11, 67, 48, 244, 192, 4, 55, 124, 89, 0, 9, 0, 13, 68, 84, 225, 15, 76, 125, 50, 72, 6, 134, 88, 0, 0, 12, 69, 72, 16, 200, 20, 192, 34, 138, 76, 118, 0, 13, 69, 76, 19, 13, 60, 224, 89, 35, 65, 13, 50, 0, 7, 65, 104, 88, 129, 0, 103, 7, 65, 104, 88, 121, 72, 0, 0, 18, 66, 5, 64, 119, 47, 10, 58, 6, 122, 55, 0, 81, 119, 105, 108, 108, 32, 19, 66, 5, 64, 119, 47, 10, 58, 125, 50, 89, 0, 106, 81, 111, 110, 99, 101, 32, 18, 66, 5, 64, 119, 47, 10, 58, 124, 50, 89, 0, 81, 111, 110, 99, 101, 32, 13, 66, 5, 64, 2, 35, 47, 13, 0, 34, 81, 97, 32, 10, 66, 5, 64, 35, 47, 0, 34, 9, 72, 16, 70, 9, 34, 65, 56, 224, 64, 71, 34, 122, 6, 35, 50, 13, 0, 16, 70, 64, 245, 15, 52, 16, 192, 48, 13, 47, 136, 65, 13, 49, 0, 17, 70, 64, 243, 9, 80, 144, 192, 48, 124, 55, 13, 47, 122, 49, 0, 10, 0, 17, 67, 92, 20, 192, 58, 2, 125, 88, 86, 115, 0, 81, 116, 104, 101, 32, 14, 67, 92, 20, 192, 58, 2, 125, 88, 119, 0, 81, 97, 32, 13, 67, 92, 20, 192, 2, 58, 125, 88, 0, 103, 35, 9, 12, 67, 92, 20, 192, 2, 58, 124, 88, 0, 35, 9, 9, 67, 80, 133, 64, 87, 147, 0, 105, 8, 67, 80, 133, 64, 87, 128, 0, 9, 67, 21, 84, 128, 57, 143, 0, 9, 0, 12, 201, 40, 242, 1, 56, 225, 83, 9, 84, 135, 66, 0, 13, 69, 44, 145, 82, 4, 224, 49, 141, 34, 13, 50, 0, 14, 69, 80, 19, 5, 57, 64, 47, 35, 55, 13, 50, 47, 0, 12, 69, 76, 244, 130, 21, 64, 89, 132, 71, 138, 0, 0, 16, 70, 72, 19, 69, 76, 84, 192, 34, 35, 65, 13, 89, 129, 88, 0, 14, 70, 80, 129, 82, 52, 244, 192, 87, 128, 65, 13, 89, 0, 9, 198, 61, 85, 12, 36, 225, 64, 65, 9, 198, 9, 34, 71, 4, 65, 64, 66, 14, 70, 5, 3, 211, 80, 193, 64, 119, 48, 124, 89, 118, 0, 16, 70, 4, 225, 77, 60, 225, 64, 119, 50, 121, 65, 13, 50, 37, 0, 10, 67, 4, 211, 203, 119, 65, 124, 49, 0, 0, 10, 199, 84, 225, 5, 72, 194, 78, 28, 65, 8, 67, 16, 245, 192, 72, 135, 0, 0, 12, 68, 64, 147, 15, 80, 48, 137, 55, 13, 47, 0, 19, 72, 4, 69, 133, 73, 66, 83, 21, 32, 35, 72, 84, 114, 47, 137, 88, 114, 0, 0, 15, 69, 65, 84, 137, 77, 64, 48, 57, 134, 44, 122, 89, 47, 0, 14, 69, 4, 65, 9, 13, 64, 35, 72, 122, 49, 47, 0, 10, 0, 14, 70, 52, 148, 211, 36, 193, 64, 65, 122, 89, 118, 0, 103, 14, 70, 56, 85, 137, 48, 193, 64, 50, 121, 84, 122, 55, 0, 15, 70, 21, 66, 69, 56, 225, 64, 121, 47, 122, 6, 121, 50, 0, 13, 70, 12, 129, 65, 16, 193, 64, 76, 129, 72, 118, 0, 0, 11, 67, 32, 245, 192, 4, 107, 135, 0, 12, 10, 12, 67, 4, 230, 64, 4, 121, 50, 37, 0, 34, 9, 9, 67, 80, 134, 64, 4, 86, 137, 0, 9, 198, 12, 19, 3, 85, 69, 1, 66, 16, 70, 16, 17, 197, 56, 128, 77, 72, 35, 81, 13, 50, 13, 65, 0, 0, 10, 67, 80, 129, 89, 86, 138, 0, 72, 32, 0, 18, 4, 9, 39, 22, 5, 137, 84, 107, 35, 72, 0, 78, 81, 104, 97, 100, 32, 11, 4, 9, 39, 22, 5, 137, 84, 0, 72, 35, 13, 69, 80, 243, 129, 28, 80, 47, 125, 50, 122, 75, 0, 13, 69, 76, 242, 82, 20, 80, 89, 58, 126, 34, 138, 0, 14, 69, 64, 20, 212, 73, 144, 48, 138, 89, 47, 34, 37, 0, 0, 16, 70, 81, 34, 80, 60, 194, 64, 47, 34, 122, 48, 13, 55, 37, 0, 15, 70, 5, 85, 15, 65, 54, 64, 130, 108, 124, 48, 89, 37, 0, 0, 17, 67, 80, 128, 84, 2, 86, 35, 47, 86, 115, 0, 81, 116, 104, 101, 32, 20, 67, 80, 128, 84, 86, 6, 35, 47, 58, 4, 125, 50, 0, 103, 81, 111, 110, 101, 32, 19, 67, 80, 128, 84, 86, 6, 35, 47, 58, 4, 124, 50, 0, 81, 111, 110, 101, 32, 17, 67, 80, 128, 84, 4, 86, 119, 47, 122, 47, 0, 33, 81, 105, 116, 32, 17, 67, 80, 128, 84, 4, 86, 35, 47, 13, 50, 0, 34, 81, 97, 110, 32, 15, 67, 80, 128, 84, 4, 86, 35, 47, 13, 0, 34, 81, 97, 32, 13, 67, 80, 128, 84, 86, 35, 47, 0, 72, 34, 12, 33, 17, 71, 72, 84, 197, 73, 99, 201, 72, 34, 121, 88, 114, 84, 58, 127, 0, 18, 71, 20, 229, 133, 48, 244, 5, 76, 121, 50, 84, 13, 55, 136, 48, 89, 0, 0, 14, 7, 20, 8, 5, 25, 39, 18, 5, 2, 86, 138, 114, 0, 20, 72, 64, 84, 147, 21, 2, 15, 56, 80, 48, 114, 89, 6, 121, 83, 13, 50, 37, 0, 13, 70, 12, 18, 83, 20, 19, 0, 49, 35, 91, 118, 0, 11, 68, 77, 81, 68, 20, 89, 58, 138, 72, 0, 16, 70, 76, 243, 21, 80, 147, 206, 89, 13, 55, 134, 91, 13, 50, 0, 12, 68, 76, 147, 149, 76, 89, 137, 50, 13, 89, 0, 20, 72, 48, 149, 5, 72, 21, 21, 72, 80, 55, 122, 47, 114, 34, 13, 76, 114, 0, 103, 18, 72, 48, 149, 5, 72, 21, 21, 72, 80, 55, 122, 47, 34, 123, 76, 114, 0, 11, 68, 8, 144, 140, 20, 71, 137, 71, 118, 0, 0, 14, 69, 56, 144, 207, 48, 16, 50, 122, 49, 13, 55, 13, 0, 17, 70, 12, 243, 131, 21, 37, 15, 49, 13, 50, 76, 6, 140, 47, 136, 0, 15, 70, 12, 21, 8, 60, 194, 67, 49, 35, 87, 55, 122, 49, 0, 0, 18, 70, 4, 196, 133, 4, 70, 64, 130, 55, 34, 121, 72, 37, 0, 74, 32, 12, 10, 67, 52, 83, 215, 65, 37, 6, 135, 0, 16, 70, 12, 244, 143, 56, 85, 0, 49, 124, 34, 13, 50, 121, 47, 0, 14, 70, 8, 245, 81, 84, 85, 0, 71, 134, 49, 6, 138, 0, 7, 66, 5, 80, 4, 136, 0, 0, 20, 71, 48, 245, 73, 76, 144, 78, 4, 55, 134, 4, 129, 88, 129, 6, 35, 50, 13, 0, 17, 71, 80, 147, 69, 80, 16, 140, 20, 47, 137, 65, 47, 138, 71, 118, 0, 20, 71, 76, 83, 73, 12, 243, 15, 56, 89, 121, 65, 122, 49, 6, 136, 55, 13, 50, 0, 17, 71, 12, 128, 82, 48, 21, 1, 56, 91, 127, 55, 13, 47, 13, 50, 0, 0, 12, 68, 72, 16, 137, 16, 34, 138, 71, 122, 72, 0, 20, 72, 64, 82, 143, 72, 21, 9, 88, 80, 48, 13, 75, 124, 34, 13, 47, 122, 84, 0, 13, 68, 52, 241, 5, 52, 65, 136, 72, 13, 65, 0, 103, 12, 68, 52, 241, 5, 52, 65, 136, 72, 121, 65, 0, 10, 67, 44, 149, 201, 49, 129, 58, 129, 0, 0, 0, 10, 67, 4, 229, 83, 138, 50, 125, 89, 0, 0, 10, 1, 126, 47, 122, 55, 72, 13, 0, 27, 0, 11, 68, 28, 144, 130, 76, 81, 122, 71, 88, 0, 11, 68, 80, 145, 1, 48, 47, 137, 72, 118, 0, 0, 17, 67, 80, 128, 78, 4, 86, 35, 50, 13, 50, 0, 34, 81, 97, 110, 32, 15, 67, 80, 128, 78, 4, 86, 35, 50, 13, 0, 34, 81, 97, 32, 11, 67, 80, 128, 78, 86, 119, 50, 0, 72, 9, 14, 69, 81, 37, 69, 49, 144, 47, 34, 134, 55, 122, 0, 32, 13, 69, 52, 148, 211, 21, 48, 65, 122, 89, 113, 88, 0, 0, 16, 70, 12, 240, 207, 57, 85, 0, 49, 136, 49, 13, 50, 125, 47, 0, 0, 9, 67, 21, 96, 64, 129, 84, 13, 0, 0, 0, 17, 70, 4, 229, 9, 48, 193, 83, 35, 50, 47, 6, 122, 55, 129, 88, 0, 13, 69, 92, 144, 203, 20, 64, 58, 122, 49, 123, 72, 0, 15, 69, 84, 228, 133, 4, 64, 125, 50, 34, 6, 121, 72, 0, 9, 0, 15, 70, 72, 146, 1, 56, 224, 64, 34, 122, 6, 126, 50, 13, 0, 9, 67, 81, 115, 211, 47, 134, 88, 0, 0, 17, 71, 92, 129, 82, 20, 85, 133, 72, 58, 2, 140, 44, 121, 84, 114, 0, 0, 7, 196, 80, 16, 143, 60, 66, 10, 67, 40, 81, 9, 75, 121, 72, 137, 0, 11, 68, 21, 113, 69, 44, 129, 58, 129, 49, 0, 16, 70, 12, 147, 142, 4, 211, 206, 89, 122, 50, 13, 65, 13, 50, 0, 0, 11, 69, 80, 131, 213, 28, 128, 4, 86, 136, 0, 12, 69, 52, 148, 211, 20, 64, 65, 122, 89, 47, 0, 0, 9, 198, 64, 19, 132, 61, 32, 64, 66, 16, 70, 85, 68, 133, 12, 133, 0, 57, 134, 47, 34, 121, 99, 47, 0, 0, 18, 71, 8, 20, 143, 52, 85, 5, 72, 71, 13, 34, 124, 65, 113, 47, 114, 0, 0, 9, 67, 8, 81, 5, 71, 129, 72, 0, 13, 70, 16, 245, 71, 4, 195, 0, 72, 134, 81, 118, 0, 15, 70, 92, 19, 19, 4, 195, 0, 58, 130, 55, 89, 130, 55, 0, 10, 68, 4, 32, 133, 100, 35, 71, 37, 0, 7, 196, 57, 148, 19, 16, 17, 0, 14, 69, 28, 144, 147, 60, 224, 81, 122, 71, 89, 13, 50, 0, 22, 73, 77, 84, 5, 72, 99, 21, 61, 84, 192, 89, 134, 48, 6, 128, 83, 55, 134, 13, 89, 0, 13, 69, 28, 86, 83, 21, 32, 81, 137, 88, 114, 0, 103, 12, 69, 28, 86, 83, 21, 32, 81, 129, 88, 114, 0, 13, 69, 24, 21, 8, 60, 208, 83, 35, 86, 13, 65, 0, 21, 73, 12, 193, 65, 56, 194, 78, 21, 52, 192, 49, 55, 121, 50, 55, 122, 50, 13, 89, 0, 0, 14, 70, 76, 145, 206, 4, 113, 64, 89, 137, 50, 113, 75, 0, 16, 70, 64, 244, 148, 20, 225, 0, 48, 133, 47, 6, 121, 50, 72, 0, 0, 17, 71, 12, 19, 66, 72, 145, 7, 20, 49, 138, 65, 71, 34, 122, 75, 0, 0, 12, 68, 76, 243, 137, 4, 89, 124, 50, 57, 13, 0, 11, 200, 80, 132, 143, 84, 114, 15, 85, 64, 66, 0, 21, 73, 56, 243, 133, 80, 129, 76, 21, 52, 192, 50, 125, 50, 86, 13, 55, 6, 121, 89, 0, 12, 69, 48, 243, 211, 21, 32, 55, 134, 88, 114, 0, 12, 69, 8, 22, 129, 5, 32, 71, 119, 88, 127, 0, 0, 10, 66, 8, 80, 71, 129, 0, 35, 9, 76, 14, 70, 76, 85, 137, 48, 193, 64, 89, 13, 84, 122, 55, 0, 15, 70, 20, 228, 143, 85, 65, 64, 124, 50, 34, 6, 134, 47, 0, 0, 11, 67, 48, 244, 212, 55, 131, 89, 47, 0, 103, 17, 70, 76, 84, 133, 56, 17, 5, 89, 121, 34, 113, 50, 6, 138, 72, 0, 16, 70, 24, 21, 143, 72, 149, 5, 83, 138, 84, 14, 34, 113, 47, 0, 10, 199, 12, 243, 147, 81, 37, 67, 80, 36, 20, 71, 12, 243, 147, 81, 37, 67, 80, 49, 124, 50, 89, 47, 34, 125, 49, 47, 0, 10, 0, 14, 68, 84, 225, 5, 72, 125, 50, 72, 114, 0, 72, 12, 9, 16, 70, 80, 240, 143, 28, 112, 78, 47, 13, 71, 124, 81, 13, 50, 0, 12, 68, 65, 34, 86, 100, 48, 34, 122, 84, 37, 0, 11, 68, 44, 81, 137, 72, 49, 129, 83, 114, 0, 11, 67, 32, 18, 1, 107, 126, 107, 6, 126, 0, 0, 15, 69, 8, 19, 129, 56, 16, 71, 119, 50, 35, 50, 13, 0, 103, 17, 70, 52, 147, 132, 4, 224, 79, 65, 122, 50, 72, 13, 50, 6, 135, 0, 14, 69, 20, 198, 83, 20, 80, 138, 55, 6, 129, 88, 138, 0, 14, 69, 76, 145, 82, 72, 16, 89, 129, 6, 140, 34, 13, 0, 13, 69, 20, 229, 18, 20, 80, 124, 50, 47, 34, 138, 0, 8, 197, 20, 212, 9, 72, 80, 65, 13, 69, 12, 18, 143, 48, 80, 49, 119, 75, 136, 55, 0, 14, 69, 8, 19, 129, 56, 16, 71, 13, 50, 126, 50, 13, 0, 23, 73, 5, 4, 18, 61, 130, 77, 5, 65, 64, 119, 48, 34, 124, 49, 89, 122, 65, 138, 47, 0, 36, 23, 73, 5, 4, 18, 61, 130, 77, 5, 65, 64, 119, 48, 34, 124, 49, 89, 122, 65, 13, 47, 0, 9, 12, 69, 4, 50, 9, 56, 112, 138, 49, 122, 68, 0, 0, 15, 70, 92, 245, 78, 16, 81, 0, 58, 134, 50, 72, 123, 72, 0, 0, 10, 67, 77, 34, 64, 89, 34, 4, 129, 0, 18, 70, 48, 147, 135, 21, 34, 69, 55, 124, 50, 90, 13, 34, 6, 138, 0, 103, 16, 70, 48, 147, 135, 21, 34, 69, 55, 124, 50, 90, 13, 34, 37, 0, 10, 199, 25, 37, 83, 81, 32, 84, 20, 66, 16, 70, 9, 35, 195, 12, 243, 9, 71, 34, 124, 49, 13, 55, 37, 0, 0, 12, 68, 76, 81, 1, 56, 89, 113, 72, 35, 50, 0, 12, 68, 28, 243, 142, 4, 81, 4, 13, 50, 13, 0, 12, 68, 12, 240, 146, 4, 49, 136, 71, 34, 13, 0, 10, 68, 5, 81, 197, 72, 130, 81, 114, 0, 0, 12, 69, 65, 32, 71, 84, 80, 48, 34, 126, 81, 0, 13, 69, 61, 32, 78, 28, 80, 124, 34, 113, 50, 75, 0, 24, 73, 20, 193, 67, 81, 34, 67, 37, 70, 64, 113, 55, 121, 49, 47, 34, 6, 122, 89, 113, 47, 37, 0, 22, 73, 4, 227, 137, 88, 84, 147, 5, 38, 64, 35, 50, 122, 84, 6, 128, 89, 13, 34, 37, 0, 14, 69, 4, 69, 193, 72, 80, 6, 35, 72, 58, 4, 140, 0, 0, 0, 16, 70, 28, 147, 214, 4, 227, 137, 75, 13, 84, 6, 126, 50, 37, 0, 18, 71, 64, 20, 211, 21, 36, 194, 100, 48, 35, 89, 114, 88, 71, 6, 137, 0, 19, 71, 44, 147, 15, 52, 85, 5, 72, 49, 122, 55, 6, 124, 65, 113, 47, 114, 0, 17, 71, 24, 244, 148, 84, 224, 84, 20, 83, 132, 76, 13, 50, 13, 47, 0, 18, 71, 4, 67, 73, 72, 16, 140, 20, 35, 72, 65, 13, 34, 13, 71, 118, 0, 0, 12, 68, 81, 32, 67, 100, 47, 34, 138, 89, 37, 0, 15, 70, 76, 48, 76, 64, 83, 0, 89, 49, 35, 55, 48, 118, 0, 0, 13, 69, 16, 148, 206, 21, 144, 72, 122, 88, 50, 37, 0, 13, 69, 32, 83, 9, 84, 208, 107, 129, 55, 141, 65, 0, 17, 70, 17, 32, 77, 5, 66, 67, 72, 34, 13, 65, 35, 47, 122, 49, 0, 14, 69, 4, 194, 193, 48, 144, 35, 55, 49, 13, 55, 137, 0, 0, 10, 67, 80, 133, 83, 86, 125, 89, 0, 8, 13, 202, 92, 244, 132, 65, 35, 195, 21, 52, 207, 72, 66, 15, 70, 32, 244, 212, 21, 52, 192, 107, 136, 89, 47, 121, 89, 0, 18, 70, 12, 192, 82, 36, 225, 84, 49, 55, 35, 34, 13, 50, 6, 121, 47, 0, 0, 12, 67, 9, 85, 0, 4, 71, 125, 47, 0, 8, 9, 14, 67, 92, 20, 212, 2, 58, 124, 89, 47, 0, 9, 35, 9, 10, 67, 92, 20, 212, 58, 138, 89, 47, 0, 0, 11, 68, 28, 198, 78, 56, 81, 55, 122, 50, 0, 21, 72, 72, 130, 78, 60, 49, 82, 61, 48, 34, 137, 50, 6, 124, 89, 13, 34, 13, 89, 0, 0, 10, 67, 21, 96, 78, 121, 84, 13, 50, 0, 13, 69, 32, 80, 146, 21, 112, 107, 129, 71, 34, 134, 0, 15, 69, 84, 225, 5, 57, 144, 125, 50, 72, 122, 50, 6, 137, 0, 13, 69, 81, 35, 208, 33, 144, 47, 34, 136, 83, 37, 0, 8, 197, 77, 84, 150, 21, 144, 36, 14, 69, 77, 84, 150, 21, 144, 89, 148, 84, 138, 0, 105, 10, 13, 69, 77, 84, 150, 21, 144, 89, 128, 84, 138, 0, 10, 0, 15, 70, 52, 20, 135, 5, 33, 84, 65, 127, 81, 34, 13, 47, 0, 9, 198, 52, 20, 148, 36, 225, 84, 67, 0, 12, 67, 32, 21, 8, 2, 107, 35, 87, 0, 35, 9, 19, 71, 65, 148, 129, 52, 145, 1, 48, 48, 113, 34, 6, 35, 65, 122, 72, 118, 0, 18, 71, 24, 192, 71, 20, 195, 21, 52, 83, 55, 119, 75, 121, 55, 13, 65, 0, 19, 71, 4, 225, 67, 16, 245, 1, 48, 35, 50, 122, 49, 72, 6, 136, 47, 118, 0, 0, 13, 68, 64, 20, 212, 4, 48, 126, 89, 47, 13, 0, 103, 17, 70, 92, 129, 78, 21, 97, 82, 58, 121, 50, 121, 84, 114, 0, 74, 8, 11, 67, 64, 20, 1, 48, 126, 48, 13, 0, 103, 11, 67, 64, 20, 1, 48, 119, 48, 6, 126, 0, 12, 68, 52, 19, 9, 12, 65, 35, 55, 122, 49, 0, 0, 12, 69, 32, 19, 135, 20, 64, 107, 35, 68, 72, 0, 0, 15, 70, 81, 114, 76, 36, 114, 20, 47, 58, 137, 55, 137, 47, 0, 0, 17, 70, 65, 33, 84, 20, 228, 197, 48, 34, 129, 47, 121, 50, 89, 0, 103, 10, 67, 21, 98, 84, 121, 84, 113, 47, 0, 10, 199, 4, 229, 9, 25, 33, 90, 20, 65, 0, 12, 68, 88, 83, 149, 76, 84, 129, 50, 13, 89, 0, 10, 68, 80, 243, 142, 20, 47, 125, 50, 0, 16, 70, 76, 245, 86, 20, 226, 82, 89, 134, 84, 13, 50, 6, 142, 0, 13, 68, 56, 240, 140, 100, 50, 136, 71, 55, 122, 0, 32, 12, 68, 52, 83, 15, 56, 65, 121, 55, 13, 50, 0, 11, 68, 12, 81, 1, 72, 89, 129, 72, 114, 0, 0, 0, 10, 67, 45, 34, 83, 49, 34, 122, 89, 0, 14, 70, 32, 20, 142, 21, 52, 192, 107, 127, 50, 123, 89, 0, 11, 66, 17, 32, 72, 124, 49, 47, 114, 0, 24, 0, 18, 71, 64, 84, 137, 52, 85, 5, 72, 48, 13, 34, 122, 65, 113, 47, 114, 0, 17, 71, 52, 147, 5, 77, 67, 206, 20, 65, 137, 55, 89, 47, 136, 50, 0, 17, 70, 52, 18, 143, 72, 149, 25, 65, 13, 75, 124, 34, 113, 47, 37, 0, 19, 70, 21, 48, 193, 64, 148, 205, 121, 89, 49, 6, 138, 48, 113, 88, 13, 65, 0, 0, 11, 68, 37, 50, 65, 32, 137, 88, 6, 144, 0, 11, 68, 80, 241, 1, 100, 47, 13, 72, 138, 0, 11, 68, 72, 18, 129, 32, 34, 126, 75, 126, 0, 12, 68, 21, 32, 83, 20, 113, 34, 138, 89, 0, 103, 11, 68, 21, 32, 83, 20, 113, 34, 138, 88, 0, 0, 13, 69, 76, 243, 4, 21, 32, 89, 126, 72, 114, 0, 103, 13, 69, 76, 243, 4, 21, 32, 89, 124, 55, 72, 114, 0, 20, 73, 52, 148, 195, 32, 145, 86, 61, 84, 192, 65, 122, 89, 76, 113, 84, 13, 89, 0, 0, 16, 6, 8, 1, 4, 14, 39, 20, 107, 35, 72, 13, 50, 47, 0, 35, 15, 70, 84, 224, 87, 5, 33, 64, 125, 50, 13, 58, 6, 140, 0, 10, 67, 72, 84, 15, 34, 129, 48, 136, 0, 15, 70, 25, 34, 71, 5, 65, 64, 83, 34, 122, 81, 13, 47, 0, 14, 70, 12, 244, 144, 61, 32, 76, 49, 132, 48, 34, 118, 0, 0, 25, 67, 53, 84, 212, 65, 4, 125, 89, 47, 35, 84, 47, 116, 0, 35, 82, 104, 97, 118, 101, 32, 116, 111, 32, 21, 67, 53, 84, 212, 65, 125, 89, 47, 107, 35, 84, 0, 35, 14, 81, 104, 97, 118, 101, 32, 20, 67, 53, 84, 212, 65, 125, 89, 47, 119, 84, 0, 35, 65, 81, 104, 97, 118, 101, 32, 6, 195, 53, 84, 212, 32, 18, 71, 65, 33, 67, 37, 2, 67, 20, 48, 34, 121, 89, 113, 48, 122, 89, 0, 18, 70, 29, 32, 68, 84, 21, 5, 81, 34, 35, 72, 57, 134, 138, 47, 0, 36, 17, 70, 29, 32, 68, 84, 21, 5, 81, 34, 35, 72, 57, 134, 13, 47, 0, 16, 70, 16, 83, 9, 12, 21, 5, 72, 121, 55, 113, 49, 13, 47, 0, 0, 11, 67, 8, 85, 1, 71, 138, 47, 13, 0, 103, 12, 68, 76, 147, 131, 20, 89, 122, 50, 89, 0, 8, 11, 67, 80, 22, 25, 47, 35, 49, 89, 37, 0, 10, 67, 64, 21, 5, 48, 35, 108, 138, 0, 9, 67, 24, 85, 5, 83, 138, 47, 0, 10, 67, 8, 85, 1, 71, 129, 47, 13, 0, 0, 14, 69, 64, 84, 141, 37, 64, 48, 114, 65, 122, 47, 0, 36, 14, 69, 64, 84, 141, 37, 64, 48, 128, 65, 122, 47, 0, 10, 12, 69, 16, 144, 80, 21, 32, 72, 137, 48, 114, 0, 0, 15, 6, 4, 9, 4, 14, 39, 20, 72, 122, 72, 50, 47, 0, 32, 15, 70, 61, 85, 12, 37, 97, 64, 135, 47, 55, 6, 122, 84, 0, 17, 70, 21, 129, 67, 85, 65, 64, 121, 49, 89, 113, 49, 57, 134, 47, 0, 16, 70, 13, 33, 77, 5, 65, 64, 49, 34, 129, 65, 138, 47, 0, 103, 14, 70, 12, 83, 147, 85, 33, 64, 89, 121, 50, 91, 114, 0, 14, 70, 12, 21, 137, 5, 33, 64, 49, 35, 84, 122, 127, 0, 5, 194, 4, 144, 17, 0, 17, 70, 17, 83, 135, 5, 33, 69, 72, 125, 68, 81, 119, 34, 6, 129, 0, 0, 33, 8, 3, 15, 21, 12, 4, 14, 39, 20, 6, 49, 117, 72, 13, 50, 47, 35, 84, 47, 116, 0, 32, 12, 82, 104, 97, 118, 101, 32, 116, 111, 32, 27, 8, 3, 15, 21, 12, 4, 14, 39, 20, 49, 117, 72, 13, 50, 47, 13, 84, 0, 35, 77, 81, 104, 97, 118, 101, 32, 20, 8, 3, 15, 21, 12, 4, 14, 39, 20, 4, 49, 117, 72, 13, 50, 47, 0, 32, 12, 18, 8, 19, 8, 1, 12, 12, 14, 39, 20, 4, 91, 126, 50, 47, 0, 32, 12, 12, 68, 32, 17, 5, 76, 107, 138, 72, 129, 88, 0, 10, 67, 80, 145, 25, 47, 137, 72, 37, 0, 10, 67, 48, 147, 25, 55, 122, 55, 37, 0, 12, 68, 5, 33, 78, 4, 119, 34, 129, 50, 13, 0, 0, 13, 69, 76, 51, 5, 72, 16, 89, 49, 55, 141, 34, 0, 12, 201, 36, 228, 212, 36, 224, 212, 37, 97, 64, 66, 13, 69, 16, 83, 135, 84, 80, 72, 121, 50, 81, 37, 0, 12, 69, 5, 3, 133, 60, 16, 35, 48, 50, 141, 0, 22, 73, 4, 197, 5, 72, 224, 84, 37, 97, 64, 130, 55, 47, 6, 128, 50, 13, 47, 122, 84, 0, 0, 10, 67, 72, 81, 15, 34, 129, 72, 134, 0, 0, 13, 70, 72, 19, 5, 36, 114, 0, 34, 126, 55, 37, 0, 19, 71, 21, 84, 8, 72, 21, 5, 76, 57, 134, 83, 34, 6, 138, 47, 129, 88, 0, 18, 71, 24, 21, 143, 72, 149, 5, 76, 83, 138, 84, 14, 34, 113, 47, 89, 0, 0, 12, 68, 4, 225, 5, 76, 35, 50, 72, 129, 88, 0, 15, 70, 72, 85, 18, 36, 19, 0, 34, 129, 47, 34, 144, 55, 0, 10, 67, 72, 83, 25, 34, 113, 55, 137, 0, 11, 68, 72, 17, 1, 72, 34, 138, 72, 127, 0, 10, 68, 53, 148, 146, 32, 65, 148, 0, 105, 9, 68, 53, 148, 146, 32, 65, 128, 0, 12, 68, 36, 225, 133, 72, 122, 50, 83, 6, 128, 0, 10, 67, 8, 83, 25, 71, 113, 55, 137, 0, 0, 14, 69, 57, 80, 78, 12, 80, 50, 134, 124, 50, 89, 0, 103, 0, 16, 70, 60, 33, 76, 37, 50, 192, 124, 71, 13, 55, 113, 89, 49, 0, 13, 70, 28, 245, 82, 52, 85, 0, 81, 143, 65, 138, 0, 15, 70, 24, 148, 200, 56, 85, 0, 83, 122, 91, 50, 121, 47, 0, 0, 17, 71, 77, 84, 146, 60, 112, 84, 20, 89, 128, 13, 81, 13, 47, 0, 103, 17, 71, 77, 84, 146, 60, 112, 84, 20, 89, 125, 34, 13, 81, 138, 47, 0, 17, 71, 4, 195, 5, 52, 19, 132, 20, 35, 55, 13, 65, 35, 50, 72, 0, 0, 21, 72, 49, 86, 5, 52, 35, 213, 72, 112, 55, 125, 49, 89, 13, 65, 71, 148, 81, 0, 105, 20, 72, 49, 86, 5, 52, 35, 213, 72, 112, 55, 125, 49, 89, 13, 65, 71, 128, 81, 0, 10, 68, 32, 243, 13, 20, 107, 136, 65, 0, 0, 0, 17, 70, 4, 211, 206, 29, 53, 0, 119, 65, 125, 68, 89, 47, 0, 74, 12, 15, 70, 77, 84, 144, 49, 84, 192, 89, 128, 48, 55, 13, 89, 0, 0, 0, 13, 68, 49, 82, 71, 36, 55, 134, 6, 129, 75, 37, 0, 20, 72, 72, 80, 201, 65, 35, 195, 4, 192, 34, 113, 89, 122, 48, 34, 13, 49, 118, 0, 19, 72, 24, 21, 143, 85, 34, 84, 21, 48, 83, 138, 84, 14, 34, 113, 47, 89, 0, 11, 68, 8, 145, 5, 80, 71, 129, 72, 138, 0, 0, 14, 69, 16, 81, 133, 57, 48, 72, 113, 83, 121, 50, 89, 0, 0, 8, 67, 101, 97, 83, 129, 84, 0, 16, 70, 24, 243, 212, 32, 243, 4, 83, 117, 47, 107, 136, 55, 72, 0, 12, 4, 95, 20, 21, 18, 47, 6, 128, 50, 72, 0, 0, 11, 67, 72, 80, 68, 34, 121, 72, 0, 38, 9, 9, 67, 72, 80, 68, 34, 129, 72, 0, 0, 11, 68, 88, 147, 12, 36, 84, 122, 55, 137, 0, 12, 68, 85, 34, 78, 20, 57, 143, 34, 122, 50, 0, 11, 68, 12, 17, 18, 20, 49, 126, 72, 114, 0, 11, 68, 5, 33, 207, 56, 127, 81, 124, 50, 0, 11, 68, 4, 65, 15, 56, 35, 72, 124, 50, 0, 0, 14, 69, 52, 17, 18, 36, 64, 65, 13, 72, 34, 122, 72, 0, 13, 69, 64, 22, 80, 4, 192, 48, 138, 48, 35, 55, 0, 0, 17, 70, 33, 148, 15, 96, 144, 64, 107, 137, 48, 6, 124, 49, 89, 141, 0, 0, 0, 12, 68, 45, 80, 76, 4, 49, 58, 126, 55, 119, 0, 11, 68, 4, 65, 9, 76, 35, 72, 122, 89, 0, 10, 68, 17, 34, 69, 72, 72, 34, 145, 0, 20, 72, 5, 35, 83, 48, 83, 135, 80, 128, 4, 127, 65, 88, 55, 6, 121, 68, 87, 0, 0, 10, 67, 13, 37, 90, 49, 34, 134, 88, 0, 8, 197, 72, 80, 207, 72, 64, 36, 15, 69, 72, 80, 207, 72, 64, 34, 121, 49, 114, 72, 0, 103, 10, 14, 69, 72, 80, 207, 72, 64, 34, 121, 49, 132, 72, 0, 10, 14, 69, 12, 19, 148, 60, 224, 49, 35, 50, 47, 124, 50, 0, 0, 17, 70, 48, 144, 133, 72, 144, 64, 55, 137, 71, 6, 141, 34, 129, 13, 0, 10, 67, 48, 147, 79, 55, 122, 65, 136, 0, 15, 70, 24, 244, 133, 80, 83, 12, 83, 133, 47, 6, 121, 55, 0, 17, 70, 16, 147, 5, 52, 208, 64, 72, 123, 55, 6, 121, 65, 13, 0, 103, 16, 70, 16, 147, 5, 52, 208, 64, 72, 137, 55, 6, 121, 65, 13, 0, 0, 10, 67, 100, 245, 64, 57, 134, 0, 72, 32, 9, 67, 4, 113, 68, 138, 75, 72, 0, 0, 12, 68, 16, 243, 3, 20, 72, 124, 55, 76, 138, 0, 0, 14, 69, 17, 83, 131, 4, 224, 72, 125, 50, 49, 13, 50, 0, 14, 69, 48, 243, 132, 60, 224, 55, 125, 50, 72, 13, 50, 0, 0, 14, 70, 65, 85, 20, 36, 225, 192, 48, 117, 47, 122, 68, 0, 15, 70, 80, 129, 82, 20, 241, 128, 4, 86, 140, 6, 124, 84, 0, 9, 198, 77, 84, 16, 61, 49, 64, 66, 17, 70, 65, 33, 84, 72, 144, 76, 48, 34, 129, 47, 34, 6, 137, 118, 0, 16, 70, 21, 2, 84, 60, 209, 64, 113, 48, 122, 47, 13, 65, 122, 0, 16, 70, 12, 243, 131, 37, 49, 64, 49, 124, 50, 89, 6, 137, 89, 0, 0, 10, 199, 16, 148, 195, 61, 84, 147, 20, 65, 0, 8, 67, 80, 131, 213, 86, 135, 0, 10, 67, 48, 144, 77, 55, 129, 13, 65, 0, 10, 68, 72, 245, 83, 20, 34, 135, 88, 0, 0, 8, 197, 61, 85, 6, 37, 64, 65, 13, 69, 60, 209, 76, 21, 64, 124, 65, 55, 13, 47, 0, 0, 18, 66, 16, 80, 72, 138, 75, 6, 143, 34, 37, 0, 81, 106, 117, 114, 101, 32, 14, 70, 52, 21, 82, 36, 49, 64, 65, 124, 34, 122, 89, 0, 14, 70, 48, 83, 206, 5, 33, 0, 55, 121, 50, 13, 72, 0, 8, 66, 16, 80, 72, 13, 0, 9, 0, 9, 67, 72, 82, 68, 34, 129, 72, 0, 9, 67, 76, 178, 64, 89, 49, 129, 0, 17, 71, 56, 84, 195, 36, 83, 131, 20, 50, 121, 89, 122, 13, 50, 89, 0, 0, 12, 68, 81, 34, 78, 4, 47, 34, 129, 50, 13, 0, 13, 68, 17, 98, 78, 4, 72, 13, 84, 129, 50, 13, 0, 15, 204, 56, 245, 23, 37, 66, 19, 80, 19, 132, 36, 225, 192, 67, 12, 68, 48, 147, 1, 12, 55, 137, 55, 13, 49, 0, 12, 68, 37, 32, 84, 20, 137, 34, 6, 138, 47, 0, 12, 68, 33, 86, 154, 4, 107, 13, 88, 6, 126, 0, 0, 13, 67, 8, 81, 78, 4, 71, 122, 50, 0, 103, 35, 9, 12, 67, 8, 81, 78, 4, 71, 129, 50, 0, 35, 9, 13, 69, 8, 20, 129, 12, 176, 71, 119, 34, 126, 49, 0, 12, 69, 61, 4, 15, 76, 80, 13, 48, 136, 88, 0, 8, 197, 33, 83, 65, 56, 80, 66, 0, 14, 70, 48, 16, 143, 72, 81, 0, 55, 138, 71, 13, 72, 0, 9, 198, 12, 243, 150, 36, 53, 0, 36, 17, 70, 12, 243, 150, 36, 53, 0, 49, 124, 50, 84, 122, 49, 47, 0, 10, 0, 15, 70, 12, 20, 142, 20, 114, 69, 49, 127, 50, 13, 81, 37, 0, 10, 199, 92, 130, 67, 32, 85, 133, 72, 66, 0, 10, 67, 41, 81, 25, 75, 134, 72, 37, 0, 11, 68, 76, 21, 84, 20, 89, 130, 47, 138, 0, 10, 68, 60, 97, 133, 72, 124, 83, 114, 0, 12, 68, 52, 147, 149, 76, 65, 137, 50, 13, 89, 0, 21, 72, 16, 145, 76, 20, 53, 18, 36, 48, 72, 144, 55, 6, 121, 49, 47, 34, 122, 49, 0, 11, 4, 95, 4, 16, 20, 48, 139, 50, 47, 0, 0, 15, 69, 8, 80, 207, 52, 80, 71, 122, 49, 125, 65, 0, 74, 12, 13, 69, 61, 69, 1, 92, 16, 124, 47, 119, 58, 13, 0, 13, 69, 88, 19, 9, 76, 80, 84, 119, 55, 129, 89, 0, 14, 69, 76, 145, 67, 48, 80, 89, 57, 121, 49, 55, 14, 0, 15, 69, 21, 84, 133, 44, 16, 57, 134, 6, 34, 129, 49, 119, 0, 13, 69, 8, 85, 1, 44, 80, 71, 113, 47, 138, 49, 0, 10, 67, 4, 227, 206, 119, 50, 124, 50, 0, 9, 67, 4, 112, 82, 138, 81, 127, 0, 0, 8, 66, 9, 144, 71, 137, 0, 76, 0, 10, 199, 92, 244, 139, 80, 16, 140, 20, 20, 9, 67, 80, 131, 192, 86, 136, 0, 9, 15, 70, 64, 131, 197, 56, 150, 0, 83, 129, 50, 122, 49, 89, 0, 6, 195, 84, 99, 192, 17, 0, 11, 68, 4, 193, 137, 20, 35, 55, 83, 37, 0, 10, 67, 48, 147, 65, 55, 129, 65, 119, 0, 12, 68, 52, 147, 149, 80, 65, 122, 50, 122, 47, 0, 19, 72, 12, 132, 143, 52, 244, 207, 52, 80, 49, 34, 136, 65, 13, 89, 136, 65, 0, 0, 12, 67, 100, 245, 82, 57, 143, 0, 106, 72, 34, 9, 11, 67, 100, 245, 82, 57, 132, 0, 72, 34, 9, 18, 8, 6, 195, 173, 18, 9, 14, 14, 5, 83, 129, 34, 122, 50, 38, 13, 0, 14, 69, 84, 227, 5, 77, 48, 125, 50, 55, 6, 121, 89, 0, 8, 197, 80, 21, 20, 60, 240, 66, 9, 67, 72, 82, 78, 34, 138, 50, 0, 14, 69, 32, 147, 132, 85, 48, 107, 122, 50, 72, 134, 88, 0, 10, 67, 4, 114, 78, 119, 81, 122, 50, 0, 0, 15, 70, 4, 195, 25, 76, 243, 128, 35, 55, 122, 89, 13, 50, 0, 15, 70, 80, 129, 82, 20, 243, 128, 4, 86, 140, 6, 124, 50, 0, 9, 198, 65, 35, 212, 21, 53, 0, 36, 17, 70, 65, 35, 212, 21, 53, 0, 48, 34, 136, 47, 121, 89, 47, 0, 10, 9, 198, 12, 243, 148, 21, 53, 0, 36, 17, 70, 12, 243, 148, 21, 53, 0, 49, 124, 50, 108, 121, 89, 47, 0, 10, 0, 11, 67, 32, 147, 64, 4, 107, 122, 65, 0, 9, 6, 195, 21, 53, 0, 17, 6, 195, 4, 115, 64, 17, 0, 18, 70, 92, 128, 84, 21, 97, 82, 58, 125, 47, 121, 84, 114, 0, 103, 66, 8, 17, 70, 92, 128, 84, 21, 97, 82, 58, 124, 47, 121, 84, 114, 0, 66, 8, 12, 68, 32, 19, 143, 36, 107, 35, 50, 6, 139, 0, 12, 68, 12, 17, 5, 80, 49, 119, 72, 121, 47, 0, 0, 0, 10, 67, 100, 246, 79, 57, 136, 57, 136, 0, 16, 70, 80, 19, 12, 100, 131, 192, 47, 35, 55, 122, 6, 107, 136, 0, 0, 0, 16, 70, 92, 129, 82, 21, 97, 82, 58, 2, 140, 44, 121, 84, 114, 0, 17, 70, 76, 16, 143, 80, 85, 82, 89, 35, 71, 13, 47, 6, 148, 0, 105, 16, 70, 76, 16, 143, 80, 85, 82, 89, 35, 71, 13, 47, 6, 128, 0, 11, 68, 16, 243, 143, 72, 72, 136, 50, 114, 0, 12, 68, 4, 66, 5, 72, 35, 72, 107, 6, 142, 0, 9, 3, 95, 35, 57, 47, 35, 71, 0, 13, 4, 95, 20, 12, 4, 47, 6, 122, 55, 72, 13, 0, 0, 14, 69, 37, 48, 66, 20, 192, 122, 88, 13, 71, 121, 55, 0, 12, 69, 76, 130, 76, 60, 128, 91, 137, 55, 136, 0, 14, 69, 92, 21, 19, 60, 224, 58, 124, 47, 89, 13, 50, 0, 12, 69, 36, 227, 129, 72, 64, 122, 50, 114, 72, 0, 9, 67, 4, 195, 0, 130, 55, 0, 42, 0, 14, 70, 72, 86, 78, 60, 193, 0, 34, 121, 50, 118, 72, 0, 17, 70, 52, 242, 1, 52, 208, 68, 65, 136, 107, 6, 35, 65, 113, 72, 0, 0, 18, 71, 88, 19, 5, 57, 66, 78, 20, 84, 35, 55, 13, 50, 47, 137, 50, 0, 12, 6, 19, 195, 173, 4, 8, 5, 91, 129, 13, 0, 10, 199, 76, 83, 73, 9, 33, 86, 20, 65, 6, 195, 20, 69, 0, 17, 0, 11, 68, 12, 242, 5, 56, 49, 136, 13, 50, 0, 12, 68, 4, 225, 18, 20, 124, 50, 72, 34, 138, 0, 7, 196, 12, 17, 9, 104, 66, 11, 67, 41, 83, 25, 75, 134, 55, 6, 137, 0, 11, 68, 12, 243, 15, 72, 49, 125, 55, 114, 0, 0, 13, 69, 85, 49, 70, 84, 192, 57, 134, 89, 83, 118, 0, 15, 69, 52, 148, 204, 20, 64, 65, 122, 89, 55, 6, 121, 72, 0, 0, 9, 198, 61, 97, 82, 48, 244, 132, 65, 16, 70, 24, 244, 141, 36, 48, 64, 83, 132, 65, 6, 137, 49, 13, 0, 10, 67, 16, 18, 83, 72, 138, 122, 89, 0, 0, 18, 71, 20, 194, 90, 4, 33, 84, 32, 113, 55, 122, 88, 13, 71, 13, 87, 0, 16, 70, 65, 35, 214, 20, 224, 197, 48, 34, 124, 84, 6, 150, 89, 0, 0, 11, 68, 40, 243, 129, 32, 75, 136, 50, 13, 0, 11, 68, 16, 147, 129, 32, 72, 137, 50, 13, 0, 10, 67, 76, 181, 65, 89, 49, 134, 13, 0, 11, 68, 64, 244, 211, 20, 48, 124, 89, 37, 0, 20, 72, 32, 19, 12, 20, 197, 73, 4, 128, 107, 35, 55, 113, 6, 55, 134, 57, 13, 0, 10, 67, 4, 117, 69, 138, 81, 57, 134, 0, 0, 15, 69, 72, 240, 149, 77, 64, 34, 136, 71, 6, 125, 89, 47, 0, 14, 69, 16, 148, 212, 72, 240, 72, 122, 89, 47, 34, 136, 0, 0, 15, 70, 32, 20, 212, 36, 225, 192, 107, 138, 89, 47, 122, 68, 0, 9, 198, 77, 80, 140, 36, 209, 64, 66, 17, 70, 65, 35, 212, 20, 113, 64, 48, 34, 136, 47, 13, 90, 138, 0, 103, 16, 70, 65, 35, 212, 20, 113, 64, 48, 34, 124, 47, 13, 90, 138, 0, 9, 198, 61, 85, 18, 4, 113, 64, 65, 15, 70, 8, 20, 146, 4, 113, 64, 71, 114, 34, 126, 90, 0, 103, 14, 70, 8, 20, 146, 4, 113, 64, 71, 35, 34, 126, 90, 0, 0, 17, 70, 52, 243, 148, 4, 117, 69, 65, 124, 50, 108, 13, 81, 57, 134, 0, 10, 199, 52, 19, 135, 4, 225, 83, 20, 65, 18, 71, 8, 243, 15, 28, 225, 83, 20, 71, 124, 55, 13, 50, 6, 138, 88, 0, 0, 13, 68, 32, 83, 9, 96, 107, 129, 55, 122, 49, 89, 0, 0, 14, 69, 36, 225, 9, 13, 64, 122, 50, 72, 6, 137, 47, 0, 13, 69, 33, 84, 211, 5, 32, 107, 125, 88, 6, 127, 0, 15, 69, 21, 48, 207, 73, 64, 121, 89, 49, 6, 132, 47, 0, 36, 0, 15, 70, 92, 21, 6, 61, 33, 0, 58, 124, 47, 83, 13, 72, 0, 15, 70, 92, 80, 144, 4, 113, 64, 58, 121, 71, 48, 138, 75, 0, 13, 70, 76, 51, 213, 72, 113, 64, 89, 49, 128, 75, 0, 15, 70, 72, 85, 133, 72, 145, 64, 34, 121, 84, 13, 34, 37, 0, 16, 70, 16, 85, 143, 80, 81, 64, 72, 121, 84, 136, 47, 6, 129, 0, 0, 13, 6, 3, 18, 195, 168, 13, 5, 49, 34, 121, 65, 0, 6, 195, 16, 150, 64, 17, 0, 15, 70, 32, 21, 193, 36, 144, 78, 107, 13, 58, 6, 144, 50, 0, 12, 68, 80, 147, 4, 20, 47, 122, 55, 72, 13, 0, 15, 70, 76, 246, 65, 8, 80, 78, 89, 139, 13, 71, 129, 50, 0, 11, 68, 13, 33, 80, 20, 49, 34, 138, 48, 0, 22, 72, 4, 229, 5, 12, 81, 5, 57, 64, 35, 50, 47, 122, 89, 6, 129, 72, 13, 50, 47, 0, 0, 10, 67, 56, 80, 82, 4, 50, 142, 0, 12, 0, 17, 70, 60, 33, 83, 37, 70, 64, 136, 71, 6, 129, 89, 13, 47, 37, 0, 0, 20, 71, 52, 243, 69, 57, 64, 82, 100, 65, 136, 65, 13, 50, 108, 140, 34, 37, 0, 103, 19, 71, 52, 243, 69, 57, 64, 82, 100, 65, 136, 65, 13, 50, 47, 13, 34, 37, 0, 17, 71, 21, 66, 81, 84, 85, 20, 20, 121, 47, 123, 49, 13, 47, 0, 103, 10, 199, 21, 66, 81, 84, 85, 20, 20, 65, 0, 7, 196, 77, 66, 76, 48, 32, 10, 68, 48, 245, 73, 76, 55, 134, 37, 0, 11, 68, 9, 34, 69, 56, 71, 34, 144, 50, 0, 7, 196, 52, 147, 1, 56, 66, 17, 70, 77, 1, 67, 36, 209, 78, 89, 48, 121, 89, 113, 65, 13, 50, 0, 19, 72, 76, 147, 8, 61, 81, 84, 80, 80, 89, 113, 55, 117, 58, 6, 121, 47, 0, 9, 67, 32, 150, 65, 107, 137, 119, 0, 12, 68, 12, 243, 15, 56, 49, 136, 55, 13, 50, 0, 0, 14, 69, 8, 83, 9, 104, 80, 71, 121, 55, 6, 129, 88, 0, 13, 69, 85, 49, 65, 28, 80, 57, 134, 89, 113, 75, 0, 14, 69, 52, 244, 143, 76, 80, 65, 13, 34, 6, 136, 89, 0, 10, 67, 48, 145, 78, 55, 129, 13, 50, 0, 0, 9, 198, 16, 18, 15, 52, 86, 64, 66, 5, 194, 21, 80, 17, 0, 11, 67, 52, 241, 84, 65, 136, 6, 121, 47, 0, 19, 71, 4, 208, 82, 100, 195, 9, 76, 35, 65, 13, 34, 6, 122, 55, 122, 89, 0, 0, 12, 68, 52, 83, 5, 20, 65, 138, 55, 138, 0, 103, 11, 68, 52, 83, 5, 20, 65, 121, 55, 138, 0, 11, 68, 32, 83, 12, 60, 107, 13, 55, 136, 0, 15, 70, 24, 19, 73, 48, 144, 82, 83, 13, 65, 122, 55, 142, 0, 14, 68, 16, 80, 149, 80, 72, 138, 71, 6, 57, 134, 0, 103, 12, 68, 16, 80, 149, 80, 72, 138, 71, 57, 134, 0, 19, 72, 5, 4, 18, 20, 229, 9, 12, 80, 119, 48, 34, 121, 50, 108, 122, 89, 0, 0, 13, 69, 8, 85, 19, 21, 144, 71, 121, 47, 89, 37, 0, 15, 69, 8, 244, 212, 60, 224, 71, 131, 89, 47, 13, 50, 0, 103, 8, 67, 48, 145, 82, 55, 145, 0, 8, 197, 17, 147, 129, 52, 240, 65, 0, 9, 198, 36, 229, 5, 72, 147, 64, 65, 16, 70, 8, 84, 212, 21, 53, 0, 71, 121, 89, 47, 13, 89, 47, 0, 0, 17, 71, 25, 34, 67, 5, 52, 197, 20, 83, 34, 122, 49, 119, 89, 138, 0, 0, 12, 68, 29, 82, 68, 60, 81, 58, 129, 72, 136, 0, 13, 68, 76, 18, 5, 48, 89, 126, 107, 6, 121, 55, 0, 12, 68, 85, 50, 78, 28, 57, 134, 88, 122, 68, 0, 16, 70, 77, 4, 129, 100, 48, 78, 89, 48, 34, 138, 49, 35, 50, 0, 12, 68, 76, 19, 1, 16, 89, 35, 55, 13, 72, 0, 10, 67, 60, 176, 89, 136, 49, 6, 138, 0, 0, 8, 67, 64, 145, 82, 48, 142, 0, 15, 70, 12, 245, 83, 12, 245, 83, 49, 134, 89, 49, 134, 89, 0, 0, 12, 67, 4, 225, 0, 35, 50, 72, 0, 72, 8, 9, 9, 67, 72, 81, 83, 34, 129, 89, 0, 18, 70, 52, 243, 148, 72, 80, 76, 65, 124, 50, 47, 34, 122, 6, 130, 55, 0, 14, 70, 76, 242, 143, 85, 35, 128, 89, 136, 75, 128, 50, 0, 0, 9, 66, 4, 224, 119, 50, 0, 34, 9, 10, 67, 80, 147, 153, 47, 137, 50, 37, 0, 16, 71, 21, 52, 197, 57, 66, 65, 48, 113, 89, 121, 50, 91, 118, 0, 0, 17, 70, 20, 118, 80, 80, 144, 78, 122, 75, 6, 122, 48, 91, 13, 50, 0, 16, 70, 77, 84, 5, 72, 208, 78, 89, 134, 48, 114, 65, 35, 50, 0, 12, 201, 76, 147, 85, 49, 64, 78, 20, 245, 83, 67, 0, 10, 67, 72, 83, 143, 34, 129, 50, 136, 0, 11, 68, 76, 243, 129, 72, 89, 136, 50, 127, 0, 7, 196, 84, 226, 3, 72, 17, 0, 16, 69, 8, 86, 79, 56, 64, 71, 122, 57, 124, 50, 72, 0, 74, 12, 13, 69, 12, 240, 207, 60, 224, 49, 13, 49, 134, 50, 0, 0, 0, 19, 71, 65, 35, 193, 13, 66, 86, 20, 48, 34, 136, 6, 35, 49, 47, 122, 84, 0, 0, 12, 68, 4, 115, 133, 76, 35, 81, 50, 13, 89, 0, 12, 68, 12, 243, 135, 60, 49, 124, 68, 81, 136, 0, 12, 68, 76, 147, 133, 92, 89, 122, 50, 57, 134, 0, 19, 72, 76, 130, 76, 48, 83, 1, 28, 128, 91, 4, 113, 55, 6, 138, 55, 13, 0, 0, 9, 197, 16, 85, 1, 36, 192, 103, 66, 15, 70, 12, 20, 200, 52, 84, 133, 49, 35, 90, 65, 142, 0, 103, 14, 70, 12, 20, 200, 52, 84, 133, 49, 35, 91, 65, 142, 0, 0, 16, 70, 8, 145, 5, 24, 244, 132, 71, 122, 72, 122, 83, 13, 72, 0, 15, 70, 65, 33, 77, 36, 84, 128, 48, 34, 13, 65, 142, 0, 103, 15, 70, 65, 33, 77, 36, 84, 128, 48, 34, 121, 65, 122, 114, 0, 9, 198, 60, 53, 15, 8, 84, 128, 66, 14, 70, 12, 20, 200, 36, 84, 128, 49, 35, 91, 6, 142, 0, 14, 70, 4, 227, 212, 32, 84, 128, 119, 50, 125, 86, 114, 0, 0, 10, 67, 64, 147, 148, 48, 137, 50, 47, 0, 8, 67, 21, 113, 64, 57, 134, 0, 0, 21, 72, 8, 19, 135, 48, 81, 5, 76, 128, 71, 35, 68, 81, 55, 13, 72, 6, 121, 91, 0, 12, 68, 12, 240, 143, 48, 49, 136, 71, 124, 55, 0, 11, 68, 5, 34, 83, 20, 119, 34, 137, 88, 0, 0, 17, 70, 80, 83, 133, 72, 145, 133, 47, 121, 50, 114, 34, 6, 129, 83, 0, 13, 69, 12, 20, 133, 21, 32, 49, 13, 34, 6, 142, 0, 0, 15, 70, 92, 147, 132, 36, 225, 192, 58, 137, 50, 72, 122, 68, 0, 0, 0, 11, 68, 12, 131, 15, 20, 49, 55, 136, 37, 0, 21, 68, 92, 147, 132, 76, 58, 6, 137, 50, 72, 88, 15, 6, 125, 48, 0, 81, 117, 112, 32, 24, 68, 92, 147, 132, 76, 58, 6, 137, 50, 72, 88, 15, 72, 6, 135, 50, 0, 81, 100, 111, 119, 110, 32, 13, 68, 72, 85, 83, 20, 34, 129, 6, 57, 134, 88, 0, 11, 68, 8, 146, 143, 84, 71, 129, 90, 134, 0, 0, 19, 67, 16, 145, 0, 72, 122, 72, 50, 124, 47, 0, 32, 78, 81, 110, 111, 116, 32, 10, 67, 16, 145, 0, 72, 122, 72, 0, 32, 19, 67, 32, 17, 0, 107, 4, 35, 72, 86, 121, 65, 0, 81, 116, 104, 101, 109, 32, 16, 67, 32, 17, 0, 107, 4, 35, 72, 113, 47, 0, 81, 105, 116, 32, 21, 67, 32, 17, 0, 2, 107, 119, 72, 2, 71, 122, 50, 0, 35, 81, 98, 101, 101, 110, 32, 16, 67, 32, 17, 0, 107, 35, 72, 47, 134, 0, 14, 81, 116, 111, 32, 16, 67, 32, 17, 0, 107, 2, 35, 72, 47, 116, 0, 81, 116, 111, 32, 11, 67, 32, 17, 0, 4, 107, 35, 72, 0, 14, 13, 67, 32, 17, 0, 2, 107, 119, 72, 0, 35, 12, 9, 20, 73, 4, 192, 149, 69, 81, 82, 69, 81, 64, 35, 55, 71, 13, 49, 128, 49, 37, 0, 14, 69, 17, 33, 65, 53, 64, 72, 34, 121, 65, 48, 47, 0, 0, 15, 70, 24, 244, 148, 84, 225, 64, 83, 132, 76, 13, 50, 0, 103, 8, 66, 16, 144, 72, 137, 0, 41, 14, 70, 92, 20, 146, 36, 225, 192, 58, 132, 34, 122, 68, 0, 18, 70, 25, 33, 81, 84, 83, 148, 83, 34, 113, 49, 58, 121, 50, 47, 0, 36, 14, 70, 24, 244, 148, 84, 225, 64, 83, 132, 76, 134, 50, 0, 9, 66, 16, 144, 72, 4, 122, 0, 9, 16, 66, 20, 112, 83, 132, 121, 81, 88, 6, 120, 65, 48, 118, 0, 9, 0, 17, 71, 88, 83, 135, 20, 19, 131, 20, 84, 121, 50, 75, 13, 50, 89, 0, 18, 71, 20, 51, 205, 52, 84, 131, 20, 6, 129, 49, 4, 124, 65, 128, 89, 0, 6, 195, 4, 243, 0, 17, 0, 11, 68, 4, 195, 5, 56, 35, 55, 13, 50, 0, 12, 68, 48, 147, 133, 56, 55, 122, 50, 113, 50, 0, 11, 68, 48, 16, 143, 72, 55, 138, 71, 114, 0, 12, 68, 5, 50, 197, 92, 119, 89, 49, 57, 134, 0, 11, 68, 5, 34, 69, 76, 140, 34, 129, 88, 0, 0, 14, 69, 64, 19, 69, 48, 16, 48, 35, 65, 13, 55, 13, 0, 13, 69, 12, 129, 82, 36, 80, 91, 140, 34, 6, 129, 0, 14, 69, 64, 82, 201, 56, 112, 48, 129, 49, 6, 122, 68, 0, 14, 69, 80, 148, 129, 16, 80, 47, 137, 34, 6, 138, 72, 0, 20, 73, 72, 21, 1, 80, 245, 73, 48, 193, 64, 34, 35, 47, 13, 47, 6, 134, 122, 0, 14, 69, 24, 147, 129, 48, 80, 83, 113, 50, 126, 55, 37, 0, 17, 70, 4, 195, 5, 49, 82, 65, 35, 55, 113, 55, 6, 134, 57, 13, 0, 12, 69, 4, 195, 5, 48, 80, 119, 55, 129, 55, 0, 0, 0, 16, 70, 41, 82, 197, 8, 246, 0, 75, 134, 49, 71, 124, 49, 89, 0, 17, 71, 24, 21, 143, 85, 34, 84, 20, 83, 138, 84, 14, 34, 113, 47, 0, 0, 11, 68, 76, 243, 142, 100, 89, 125, 50, 122, 0, 12, 68, 37, 35, 206, 100, 137, 34, 13, 50, 122, 0, 15, 70, 13, 35, 195, 32, 85, 0, 49, 34, 136, 91, 6, 138, 0, 0, 13, 69, 52, 240, 137, 48, 80, 65, 136, 71, 118, 0, 103, 14, 69, 76, 16, 137, 56, 16, 89, 119, 71, 129, 50, 13, 0, 15, 69, 24, 144, 83, 12, 240, 83, 129, 6, 35, 89, 49, 136, 0, 0, 10, 67, 80, 147, 129, 47, 129, 50, 13, 0, 0, 13, 69, 64, 147, 5, 85, 0, 48, 137, 55, 125, 48, 0, 0, 11, 200, 4, 229, 1, 72, 53, 9, 12, 16, 66, 11, 68, 72, 83, 129, 48, 34, 129, 50, 118, 0, 11, 68, 64, 83, 129, 48, 48, 129, 50, 118, 0, 20, 72, 16, 83, 9, 8, 84, 129, 80, 80, 72, 113, 55, 122, 71, 13, 34, 13, 47, 0, 12, 68, 12, 19, 129, 48, 49, 13, 50, 35, 55, 0, 11, 68, 8, 19, 129, 48, 71, 138, 50, 118, 0, 0, 13, 69, 77, 64, 82, 73, 144, 89, 47, 126, 34, 122, 0, 10, 67, 73, 82, 78, 34, 134, 113, 50, 0, 17, 70, 52, 81, 9, 12, 147, 133, 65, 121, 72, 13, 89, 13, 50, 0, 103, 15, 70, 52, 81, 9, 12, 147, 133, 65, 121, 72, 89, 13, 50, 0, 0, 10, 67, 16, 19, 129, 72, 138, 50, 13, 0, 9, 198, 8, 18, 18, 4, 147, 128, 66, 17, 70, 32, 243, 73, 56, 83, 64, 107, 124, 65, 13, 50, 13, 65, 0, 103, 16, 70, 32, 243, 73, 56, 83, 64, 107, 124, 65, 122, 50, 121, 65, 0, 0, 19, 71, 64, 85, 18, 60, 193, 85, 52, 48, 13, 47, 34, 136, 55, 129, 13, 65, 0, 16, 71, 12, 245, 78, 80, 84, 133, 16, 49, 135, 50, 47, 114, 72, 0, 19, 71, 4, 97, 137, 16, 21, 137, 80, 35, 83, 122, 72, 6, 138, 84, 122, 47, 0, 0, 10, 67, 104, 85, 83, 88, 57, 134, 89, 0, 10, 67, 81, 148, 15, 47, 137, 48, 136, 0, 14, 70, 77, 84, 16, 48, 145, 82, 89, 13, 48, 55, 145, 0, 15, 70, 61, 85, 16, 61, 53, 0, 135, 47, 48, 136, 89, 47, 0, 12, 68, 52, 244, 5, 16, 65, 136, 48, 121, 72, 0, 11, 68, 5, 33, 213, 20, 127, 81, 57, 134, 0, 0, 13, 69, 76, 80, 77, 85, 48, 91, 138, 65, 13, 89, 0, 15, 70, 93, 34, 84, 4, 35, 5, 34, 137, 47, 13, 71, 118, 0, 13, 69, 76, 84, 137, 21, 48, 89, 129, 34, 129, 88, 0, 15, 70, 24, 19, 12, 36, 35, 5, 83, 35, 55, 13, 71, 118, 0, 0, 15, 70, 77, 65, 80, 32, 83, 128, 89, 47, 129, 84, 13, 50, 0, 17, 70, 4, 225, 207, 48, 19, 128, 35, 68, 81, 6, 136, 55, 13, 50, 0, 9, 198, 32, 16, 137, 81, 80, 76, 66, 6, 66, 20, 128, 138, 0, 0, 15, 70, 64, 192, 71, 84, 147, 135, 48, 55, 138, 81, 122, 68, 0, 17, 71, 20, 21, 133, 76, 68, 143, 64, 129, 84, 88, 72, 34, 124, 48, 0, 0, 14, 70, 72, 82, 78, 16, 81, 82, 34, 138, 50, 72, 142, 0, 21, 73, 52, 17, 5, 52, 242, 83, 20, 195, 5, 65, 35, 72, 13, 65, 13, 88, 121, 55, 0, 17, 70, 13, 84, 212, 60, 209, 82, 49, 6, 125, 89, 47, 13, 65, 114, 0, 11, 68, 4, 34, 15, 72, 119, 71, 107, 133, 0, 0, 14, 69, 5, 34, 83, 20, 224, 13, 34, 122, 88, 13, 50, 0, 0, 15, 70, 92, 131, 197, 88, 84, 128, 107, 134, 121, 84, 114, 0, 66, 14, 70, 76, 49, 80, 80, 84, 128, 89, 121, 48, 47, 114, 0, 0, 0, 12, 68, 16, 84, 133, 44, 72, 121, 34, 122, 49, 0, 0, 28, 69, 76, 131, 213, 48, 64, 91, 117, 72, 107, 35, 84, 47, 116, 0, 74, 32, 12, 82, 104, 97, 118, 101, 32, 116, 111, 32, 21, 69, 76, 131, 213, 48, 64, 91, 117, 72, 13, 84, 0, 35, 77, 81, 104, 97, 118, 101, 32, 15, 69, 76, 131, 213, 48, 64, 4, 91, 117, 72, 0, 32, 9, 12, 13, 69, 52, 20, 129, 84, 64, 65, 13, 34, 130, 72, 0, 13, 69, 33, 84, 146, 4, 128, 107, 125, 34, 6, 138, 0, 13, 69, 33, 84, 146, 4, 128, 107, 13, 34, 6, 126, 0, 13, 3, 226, 132, 162, 47, 34, 138, 72, 65, 127, 49, 0, 0, 13, 70, 48, 242, 78, 56, 148, 128, 55, 125, 50, 141, 0, 14, 70, 64, 147, 206, 20, 84, 128, 48, 144, 50, 6, 142, 0, 13, 202, 12, 243, 148, 20, 212, 12, 5, 66, 86, 20, 66, 25, 74, 5, 85, 8, 61, 34, 84, 5, 66, 86, 20, 119, 87, 6, 131, 34, 13, 108, 138, 108, 122, 84, 0, 103, 24, 74, 5, 85, 8, 61, 34, 84, 5, 66, 86, 20, 130, 87, 6, 124, 34, 113, 47, 13, 47, 122, 84, 0, 0, 0, 20, 72, 32, 19, 12, 20, 197, 74, 4, 128, 107, 35, 55, 113, 6, 55, 134, 57, 13, 0, 0, 0, 19, 67, 32, 21, 133, 107, 119, 84, 50, 124, 47, 0, 35, 14, 81, 110, 111, 116, 32, 19, 67, 32, 21, 133, 107, 119, 84, 50, 4, 124, 47, 0, 35, 81, 110, 111, 116, 32, 21, 67, 32, 21, 133, 2, 107, 119, 84, 2, 71, 122, 50, 0, 35, 81, 98, 101, 101, 110, 32, 13, 67, 32, 21, 133, 107, 35, 84, 0, 35, 9, 72, 12, 10, 67, 48, 149, 133, 55, 122, 84, 0, 36, 10, 67, 48, 149, 133, 55, 137, 84, 0, 10, 10, 67, 48, 21, 129, 55, 126, 84, 13, 0, 13, 70, 12, 240, 203, 21, 145, 64, 49, 124, 49, 137, 0, 0, 6, 195, 72, 85, 128, 24, 6, 195, 32, 149, 128, 17, 0, 14, 68, 44, 244, 133, 4, 49, 114, 34, 6, 129, 13, 0, 103, 13, 68, 44, 244, 133, 4, 49, 131, 34, 6, 129, 13, 0, 10, 68, 24, 244, 131, 20, 83, 133, 89, 0, 11, 68, 12, 19, 143, 20, 49, 13, 50, 134, 0, 12, 68, 5, 35, 205, 4, 119, 34, 136, 65, 13, 0, 0, 15, 69, 72, 81, 140, 21, 128, 34, 129, 83, 55, 121, 49, 89, 0, 16, 69, 52, 147, 149, 21, 64, 65, 122, 50, 57, 134, 6, 121, 47, 0, 12, 69, 32, 82, 70, 21, 32, 107, 121, 83, 114, 0, 8, 67, 20, 145, 0, 129, 72, 0, 0, 16, 70, 20, 195, 213, 37, 49, 64, 121, 55, 134, 58, 6, 129, 88, 0, 10, 67, 80, 16, 149, 47, 35, 71, 134, 0, 0, 18, 71, 36, 225, 133, 72, 83, 131, 20, 122, 50, 83, 13, 34, 13, 50, 89, 0, 0, 0, 13, 69, 88, 148, 137, 48, 80, 84, 122, 34, 118, 0, 103, 13, 69, 16, 240, 201, 48, 80, 72, 136, 89, 118, 0, 103, 13, 67, 28, 85, 0, 2, 81, 121, 47, 0, 12, 35, 9, 14, 69, 32, 84, 143, 36, 48, 107, 113, 34, 136, 122, 49, 0, 18, 73, 4, 48, 207, 84, 50, 5, 52, 83, 148, 119, 49, 134, 91, 65, 151, 0, 13, 3, 226, 132, 150, 50, 57, 134, 65, 13, 34, 136, 0, 0, 15, 70, 76, 19, 131, 32, 86, 128, 89, 35, 50, 76, 121, 88, 0, 10, 67, 52, 243, 153, 65, 125, 50, 122, 0, 0, 17, 71, 76, 19, 9, 76, 37, 82, 100, 89, 130, 55, 89, 71, 34, 37, 0, 19, 71, 37, 51, 211, 12, 83, 5, 76, 137, 89, 6, 124, 89, 13, 55, 129, 88, 0, 0, 12, 68, 61, 34, 79, 56, 124, 34, 6, 144, 50, 0, 10, 68, 36, 227, 133, 72, 122, 50, 114, 0, 12, 68, 32, 21, 143, 12, 107, 35, 84, 13, 49, 0, 14, 68, 21, 128, 76, 80, 121, 81, 88, 6, 124, 55, 47, 0, 19, 72, 5, 85, 15, 52, 240, 137, 48, 80, 130, 47, 13, 65, 13, 71, 141, 55, 0, 0, 13, 69, 16, 20, 8, 56, 80, 72, 35, 83, 50, 37, 0, 8, 197, 72, 245, 1, 80, 80, 66, 18, 70, 72, 80, 68, 60, 227, 25, 4, 34, 129, 72, 6, 136, 50, 55, 122, 0, 13, 69, 56, 81, 193, 80, 80, 50, 113, 81, 138, 47, 0, 13, 69, 48, 145, 193, 80, 80, 55, 129, 81, 138, 47, 0, 14, 69, 13, 84, 129, 80, 80, 49, 57, 143, 34, 138, 47, 0, 8, 197, 5, 84, 143, 72, 16, 66, 0, 16, 70, 12, 149, 1, 16, 83, 0, 89, 122, 47, 13, 72, 121, 55, 0, 0, 18, 71, 88, 81, 197, 80, 16, 140, 20, 84, 121, 75, 113, 47, 13, 71, 118, 0, 11, 199, 36, 229, 5, 73, 37, 80, 80, 67, 36, 11, 199, 36, 229, 5, 73, 37, 80, 80, 65, 10, 20, 71, 36, 225, 140, 84, 83, 154, 4, 122, 50, 83, 55, 134, 6, 121, 50, 88, 13, 0, 13, 3, 226, 133, 148, 47, 134, 87, 6, 128, 72, 88, 0, 0, 11, 68, 44, 21, 9, 20, 49, 138, 47, 37, 0, 0, 15, 70, 49, 82, 197, 92, 20, 141, 55, 134, 49, 58, 132, 65, 0, 13, 69, 32, 84, 141, 21, 48, 107, 128, 65, 129, 88, 0, 13, 69, 4, 66, 69, 85, 48, 119, 72, 57, 134, 88, 0, 0, 15, 70, 28, 147, 12, 36, 19, 128, 75, 122, 55, 129, 13, 50, 0, 14, 70, 76, 80, 76, 36, 243, 128, 89, 129, 55, 144, 50, 0, 16, 70, 12, 20, 129, 88, 19, 128, 49, 35, 34, 13, 84, 35, 50, 0, 0, 9, 198, 4, 229, 9, 32, 84, 143, 65, 0, 13, 68, 56, 84, 1, 48, 50, 121, 48, 6, 130, 55, 0, 13, 68, 88, 19, 5, 80, 84, 35, 55, 6, 138, 0, 103, 11, 68, 88, 19, 5, 80, 84, 35, 55, 138, 0, 12, 68, 84, 229, 9, 20, 125, 50, 47, 6, 137, 0, 12, 68, 72, 84, 5, 48, 34, 113, 48, 121, 55, 0, 11, 68, 64, 20, 1, 48, 48, 138, 48, 118, 0, 12, 68, 8, 148, 5, 16, 71, 137, 48, 121, 72, 0, 15, 70, 8, 19, 12, 5, 53, 0, 71, 35, 55, 13, 89, 47, 0, 13, 3, 226, 133, 147, 58, 124, 50, 87, 6, 128, 72, 0, 0, 23, 73, 72, 84, 212, 61, 32, 84, 36, 243, 128, 34, 121, 89, 47, 13, 34, 6, 138, 91, 13, 50, 0, 23, 73, 72, 84, 208, 37, 32, 84, 36, 243, 128, 34, 121, 89, 48, 113, 34, 6, 138, 91, 13, 50, 0, 23, 73, 65, 33, 80, 5, 32, 84, 36, 243, 128, 48, 34, 121, 48, 13, 34, 6, 138, 91, 13, 50, 0, 14, 69, 52, 148, 197, 73, 144, 65, 122, 88, 13, 34, 122, 0, 13, 69, 32, 17, 199, 37, 48, 107, 35, 81, 122, 89, 0, 21, 73, 4, 97, 137, 72, 208, 84, 36, 243, 128, 35, 83, 114, 65, 6, 138, 91, 13, 50, 0, 0, 17, 70, 8, 85, 23, 20, 83, 128, 71, 122, 47, 58, 129, 50, 0, 74, 12, 16, 70, 32, 17, 18, 36, 19, 128, 107, 138, 72, 34, 129, 13, 50, 0, 16, 70, 76, 52, 143, 81, 83, 64, 89, 49, 34, 136, 47, 13, 65, 0, 16, 70, 48, 144, 73, 76, 243, 128, 55, 129, 6, 138, 88, 124, 50, 0, 0, 0, 12, 68, 44, 20, 133, 56, 49, 35, 34, 13, 50, 0, 11, 68, 16, 83, 8, 36, 72, 121, 55, 37, 0, 15, 70, 64, 148, 85, 4, 229, 0, 48, 129, 49, 13, 50, 47, 0, 12, 68, 61, 2, 78, 20, 136, 48, 6, 137, 50, 0, 11, 68, 44, 244, 10, 20, 49, 124, 48, 37, 0, 12, 201, 16, 148, 210, 21, 5, 84, 4, 35, 5, 66, 12, 68, 12, 18, 149, 56, 49, 138, 75, 13, 50, 0, 12, 68, 9, 84, 197, 76, 71, 125, 89, 123, 88, 0, 0, 13, 69, 48, 21, 78, 12, 128, 55, 126, 50, 76, 0, 103, 14, 69, 8, 147, 141, 4, 224, 71, 122, 50, 65, 35, 50, 0, 13, 69, 8, 19, 12, 4, 64, 71, 35, 55, 13, 72, 0, 0, 16, 70, 52, 21, 9, 48, 64, 64, 65, 119, 47, 122, 55, 72, 13, 0, 0, 18, 71, 64, 19, 5, 77, 66, 78, 20, 48, 35, 55, 13, 89, 47, 137, 50, 0, 17, 71, 44, 148, 139, 12, 19, 4, 100, 49, 147, 49, 6, 124, 72, 37, 0, 18, 71, 36, 229, 133, 72, 225, 83, 76, 122, 50, 84, 114, 50, 6, 121, 89, 0, 9, 67, 4, 128, 64, 126, 107, 126, 0, 0, 12, 68, 52, 147, 132, 100, 65, 122, 50, 72, 37, 0, 10, 67, 12, 193, 79, 49, 55, 129, 136, 0, 12, 68, 40, 20, 1, 56, 75, 13, 48, 35, 50, 0, 12, 68, 28, 83, 146, 20, 90, 124, 50, 34, 13, 0, 20, 72, 4, 229, 9, 64, 131, 206, 4, 192, 35, 50, 47, 6, 122, 83, 13, 50, 118, 0, 9, 3, 95, 49, 15, 83, 6, 128, 0, 0, 10, 67, 4, 128, 66, 138, 107, 35, 71, 0, 10, 67, 56, 83, 206, 50, 129, 124, 50, 0, 0, 0, 9, 67, 88, 81, 192, 84, 121, 75, 0, 10, 67, 60, 193, 68, 136, 55, 121, 72, 0, 8, 67, 20, 113, 192, 121, 81, 0, 15, 71, 8, 245, 82, 28, 83, 201, 76, 71, 143, 90, 58, 126, 0, 11, 3, 226, 130, 172, 57, 143, 34, 136, 88, 0, 0, 11, 68, 76, 20, 129, 32, 89, 140, 34, 13, 0, 12, 5, 16, 9, 195, 177, 1, 48, 129, 67, 119, 0, 12, 68, 60, 244, 129, 32, 6, 134, 34, 6, 126, 0, 0, 13, 5, 13, 15, 195, 171, 20, 65, 136, 6, 121, 47, 0, 13, 69, 69, 82, 86, 21, 32, 49, 58, 122, 84, 114, 0, 15, 70, 32, 243, 69, 64, 17, 197, 107, 136, 65, 48, 138, 75, 0, 14, 70, 12, 20, 211, 21, 69, 5, 49, 119, 89, 121, 47, 0, 0, 15, 70, 40, 20, 205, 36, 225, 64, 75, 35, 88, 65, 122, 50, 0, 16, 70, 21, 48, 193, 72, 115, 212, 113, 89, 49, 6, 127, 81, 136, 0, 9, 198, 12, 20, 195, 4, 65, 64, 66, 9, 3, 226, 130, 169, 58, 124, 50, 0, 0, 9, 67, 72, 81, 192, 34, 121, 75, 0, 10, 3, 226, 130, 168, 34, 134, 48, 129, 0, 0, 10, 68, 4, 195, 1, 100, 119, 55, 138, 0, 10, 3, 95, 50, 15, 89, 6, 121, 49, 0, 0, 16, 69, 72, 84, 15, 77, 64, 34, 4, 129, 48, 6, 136, 89, 47, 0, 17, 70, 65, 33, 83, 80, 145, 197, 48, 34, 121, 89, 47, 6, 129, 90, 0, 14, 69, 12, 245, 133, 73, 64, 49, 136, 84, 6, 128, 47, 0, 0, 9, 66, 32, 80, 107, 129, 0, 72, 33, 13, 70, 76, 128, 76, 48, 245, 192, 91, 35, 55, 136, 0, 17, 70, 65, 34, 77, 21, 96, 76, 48, 34, 137, 65, 6, 129, 84, 118, 0, 7, 66, 40, 16, 57, 126, 0, 15, 70, 36, 208, 71, 36, 225, 64, 113, 65, 35, 75, 113, 50, 0, 8, 66, 24, 144, 83, 4, 137, 0, 16, 70, 5, 69, 1, 12, 129, 64, 35, 108, 35, 6, 91, 138, 0, 103, 16, 70, 5, 69, 1, 12, 129, 64, 35, 47, 6, 35, 91, 138, 0, 9, 11, 67, 4, 129, 77, 119, 107, 6, 121, 65, 0, 14, 70, 4, 50, 9, 48, 193, 64, 119, 49, 122, 55, 129, 0, 0, 0, 12, 68, 8, 83, 137, 56, 71, 121, 50, 122, 50, 0, 12, 68, 64, 20, 133, 56, 48, 119, 34, 121, 50, 0, 13, 68, 44, 244, 129, 56, 49, 132, 34, 6, 126, 50, 0, 10, 67, 32, 82, 0, 107, 121, 107, 0, 9, 21, 72, 12, 148, 131, 84, 213, 133, 57, 64, 89, 147, 49, 13, 65, 84, 121, 50, 47, 0, 105, 20, 72, 12, 148, 131, 84, 213, 133, 57, 64, 89, 128, 49, 13, 65, 84, 121, 50, 47, 0, 16, 70, 12, 16, 137, 56, 85, 0, 49, 35, 71, 123, 50, 13, 47, 0, 11, 68, 4, 35, 5, 72, 138, 71, 55, 114, 0, 0, 15, 69, 16, 144, 76, 60, 112, 72, 137, 13, 55, 130, 81, 0, 103, 15, 69, 17, 99, 210, 4, 176, 72, 14, 84, 133, 90, 35, 49, 0, 13, 69, 8, 243, 199, 36, 80, 71, 117, 81, 37, 0, 103, 12, 69, 8, 243, 199, 36, 80, 71, 134, 81, 37, 0, 0, 10, 67, 48, 146, 197, 55, 137, 49, 0, 12, 15, 70, 44, 20, 129, 12, 130, 64, 49, 119, 34, 127, 76, 37, 0, 15, 70, 49, 83, 12, 4, 38, 64, 55, 125, 55, 13, 71, 137, 0, 9, 198, 12, 243, 134, 48, 144, 212, 36, 18, 70, 12, 243, 134, 48, 144, 212, 49, 124, 50, 83, 55, 122, 49, 47, 0, 10, 0, 0, 12, 68, 16, 19, 148, 20, 72, 126, 50, 108, 138, 0, 20, 72, 65, 33, 67, 20, 65, 78, 12, 80, 48, 34, 121, 89, 113, 72, 13, 50, 89, 0, 16, 70, 64, 84, 134, 20, 53, 0, 48, 114, 83, 121, 49, 47, 0, 36, 16, 70, 64, 84, 134, 20, 53, 0, 48, 128, 83, 121, 49, 47, 0, 10, 17, 70, 25, 37, 73, 80, 147, 206, 83, 34, 134, 6, 122, 91, 13, 50, 0, 10, 67, 24, 150, 0, 83, 122, 49, 89, 0, 19, 72, 12, 243, 12, 20, 114, 65, 80, 80, 49, 13, 55, 129, 75, 122, 13, 47, 0, 9, 3, 95, 51, 15, 87, 6, 128, 0, 8, 4, 95, 15, 18, 4, 87, 0, 0, 14, 69, 76, 16, 137, 56, 80, 89, 119, 71, 6, 129, 50, 0, 13, 69, 52, 19, 9, 12, 80, 65, 35, 55, 113, 89, 0, 11, 69, 28, 21, 67, 32, 80, 81, 136, 91, 0, 0, 10, 66, 37, 48, 2, 122, 88, 0, 35, 9, 16, 70, 37, 52, 129, 20, 194, 64, 122, 88, 34, 6, 138, 55, 37, 0, 16, 70, 76, 132, 137, 48, 198, 64, 91, 34, 122, 55, 55, 122, 0, 32, 0, 14, 70, 29, 82, 78, 56, 84, 211, 81, 122, 50, 122, 89, 0, 13, 67, 9, 99, 4, 71, 117, 55, 13, 84, 127, 72, 0, 0, 12, 68, 40, 20, 133, 16, 75, 35, 34, 121, 72, 0, 11, 68, 88, 148, 129, 48, 84, 145, 34, 118, 0, 11, 68, 28, 21, 133, 48, 81, 35, 84, 118, 0, 11, 68, 12, 244, 129, 48, 49, 124, 34, 118, 0, 10, 67, 4, 115, 199, 119, 81, 124, 81, 0, 0, 13, 69, 24, 147, 133, 77, 48, 83, 113, 50, 121, 89, 0, 13, 69, 16, 147, 135, 33, 144, 72, 122, 68, 81, 37, 0, 0, 0, 17, 71, 80, 83, 142, 21, 52, 197, 20, 47, 121, 50, 13, 89, 6, 129, 0, 0, 19, 72, 65, 54, 67, 32, 144, 84, 73, 144, 89, 137, 49, 6, 144, 47, 34, 122, 0, 13, 68, 32, 20, 133, 52, 107, 126, 34, 6, 129, 65, 0, 15, 70, 24, 18, 82, 21, 53, 0, 83, 140, 34, 13, 89, 47, 0, 12, 68, 16, 147, 135, 100, 72, 122, 50, 75, 122, 0, 0, 13, 69, 76, 17, 133, 81, 144, 89, 138, 83, 47, 37, 0, 8, 197, 61, 85, 3, 73, 144, 65, 13, 69, 48, 149, 133, 49, 144, 55, 137, 84, 55, 122, 0, 0, 9, 66, 20, 192, 4, 121, 55, 0, 9, 5, 194, 36, 64, 17, 0, 10, 67, 32, 20, 192, 107, 35, 88, 0, 42, 17, 67, 32, 20, 192, 107, 4, 35, 88, 113, 47, 0, 14, 81, 105, 116, 32, 19, 67, 32, 20, 192, 107, 119, 88, 50, 124, 47, 0, 35, 14, 81, 110, 111, 116, 32, 19, 67, 32, 20, 192, 107, 13, 88, 50, 2, 124, 47, 0, 35, 81, 110, 111, 116, 32, 16, 67, 32, 20, 192, 107, 35, 88, 47, 134, 0, 14, 81, 116, 111, 32, 21, 67, 32, 20, 192, 2, 107, 119, 88, 2, 71, 122, 50, 0, 35, 81, 98, 101, 101, 110, 32, 11, 67, 32, 20, 192, 107, 35, 88, 0, 9, 14, 12, 67, 32, 20, 192, 2, 107, 119, 88, 0, 35, 9, 8, 67, 81, 148, 128, 47, 145, 0, 10, 67, 80, 148, 192, 47, 122, 88, 0, 9, 18, 71, 12, 129, 86, 72, 243, 5, 80, 91, 121, 84, 34, 13, 55, 6, 138, 0, 0, 10, 67, 16, 148, 195, 72, 122, 89, 49, 0, 11, 68, 12, 19, 22, 20, 49, 35, 84, 0, 103, 10, 68, 12, 19, 22, 20, 49, 126, 84, 0, 0, 16, 69, 8, 82, 9, 56, 64, 71, 122, 107, 137, 50, 72, 0, 74, 12, 12, 69, 16, 20, 146, 100, 192, 72, 35, 34, 118, 0, 9, 198, 61, 97, 82, 81, 84, 133, 65, 14, 69, 4, 211, 210, 4, 192, 138, 65, 6, 124, 34, 118, 0, 0, 15, 70, 80, 84, 85, 36, 192, 64, 47, 13, 49, 129, 55, 13, 0, 15, 70, 25, 34, 78, 28, 84, 128, 83, 34, 122, 50, 75, 114, 0, 14, 70, 5, 36, 197, 56, 144, 192, 127, 89, 50, 122, 49, 0, 0, 13, 67, 32, 148, 192, 107, 122, 88, 0, 72, 34, 9, 12, 16, 71, 44, 21, 8, 21, 34, 78, 20, 49, 35, 87, 34, 113, 50, 0, 19, 71, 80, 19, 135, 21, 34, 78, 20, 47, 35, 50, 75, 13, 34, 6, 129, 50, 0, 12, 67, 48, 20, 192, 4, 55, 126, 89, 0, 103, 9, 11, 67, 48, 20, 192, 4, 55, 35, 89, 0, 9, 0, 16, 70, 72, 83, 78, 4, 229, 0, 34, 121, 65, 50, 13, 50, 47, 0, 12, 68, 13, 147, 82, 84, 49, 125, 65, 34, 37, 0, 10, 3, 95, 53, 15, 83, 6, 122, 83, 0, 0, 23, 73, 52, 147, 142, 20, 20, 15, 48, 148, 192, 65, 122, 50, 129, 6, 35, 48, 13, 55, 113, 89, 0, 14, 69, 12, 244, 146, 4, 192, 49, 13, 34, 6, 35, 55, 0, 16, 70, 12, 240, 203, 77, 84, 133, 4, 49, 124, 49, 91, 6, 143, 0, 17, 70, 9, 35, 195, 33, 84, 133, 71, 34, 136, 6, 91, 143, 34, 0, 103, 14, 70, 9, 35, 195, 33, 84, 133, 71, 34, 136, 91, 114, 0, 0, 6, 194, 37, 64, 42, 17, 19, 66, 37, 64, 2, 122, 47, 15, 58, 125, 88, 0, 103, 14, 81, 119, 97, 115, 32, 18, 66, 37, 64, 2, 122, 47, 15, 58, 124, 88, 0, 14, 81, 119, 97, 115, 32, 16, 66, 37, 64, 2, 122, 47, 15, 122, 88, 0, 14, 81, 105, 115, 32, 18, 66, 37, 64, 2, 122, 47, 15, 107, 35, 88, 0, 14, 81, 104, 97, 115, 32, 9, 66, 37, 64, 122, 47, 0, 72, 33, 10, 67, 36, 245, 193, 137, 13, 58, 13, 0, 17, 70, 65, 35, 212, 60, 51, 204, 48, 34, 136, 47, 13, 49, 124, 55, 0, 15, 70, 52, 17, 208, 36, 84, 192, 65, 35, 81, 48, 137, 88, 0, 15, 4, 95, 13, 3, 14, 65, 6, 35, 49, 34, 4, 124, 50, 0, 0, 19, 67, 24, 85, 192, 83, 6, 57, 134, 65, 4, 133, 0, 81, 109, 111, 114, 101, 32, 0, 0, 13, 69, 4, 66, 69, 85, 128, 119, 72, 57, 134, 88, 0, 0, 15, 70, 48, 82, 80, 104, 145, 192, 55, 137, 48, 89, 122, 81, 0, 15, 70, 77, 80, 147, 36, 65, 64, 89, 13, 71, 89, 137, 72, 0, 15, 70, 76, 245, 70, 24, 193, 64, 89, 134, 83, 55, 6, 138, 0, 14, 70, 21, 2, 83, 80, 193, 64, 113, 48, 122, 89, 118, 0, 16, 70, 16, 83, 79, 48, 148, 200, 72, 113, 65, 124, 55, 122, 91, 0, 11, 67, 76, 52, 201, 89, 49, 125, 88, 37, 0, 0, 16, 71, 21, 66, 5, 72, 145, 7, 20, 121, 87, 14, 34, 122, 75, 0, 0, 11, 68, 12, 148, 131, 20, 89, 128, 89, 37, 0, 13, 68, 12, 19, 9, 96, 49, 138, 55, 122, 49, 89, 0, 0, 15, 69, 64, 21, 5, 57, 64, 48, 35, 47, 13, 50, 47, 0, 103, 14, 69, 77, 69, 65, 73, 64, 89, 47, 134, 114, 47, 0, 103, 14, 69, 77, 69, 65, 73, 64, 89, 47, 57, 134, 114, 47, 0, 9, 67, 36, 115, 210, 129, 81, 133, 0, 14, 69, 76, 80, 210, 21, 64, 89, 129, 49, 34, 13, 47, 0, 13, 69, 72, 21, 197, 77, 64, 34, 130, 13, 89, 47, 0, 14, 69, 21, 32, 83, 21, 32, 113, 34, 138, 89, 114, 0, 103, 13, 69, 21, 32, 83, 21, 32, 113, 34, 138, 88, 114, 0, 11, 69, 17, 32, 87, 21, 32, 72, 34, 132, 0, 15, 69, 16, 145, 197, 77, 64, 72, 137, 75, 121, 89, 47, 0, 37, 16, 70, 8, 85, 133, 72, 17, 197, 71, 121, 84, 13, 34, 113, 75, 0, 14, 69, 4, 69, 133, 73, 64, 119, 72, 84, 128, 47, 0, 36, 0, 15, 66, 16, 240, 72, 134, 15, 89, 136, 0, 14, 81, 115, 111, 32, 17, 66, 16, 240, 72, 134, 50, 124, 47, 0, 32, 78, 81, 110, 111, 116, 32, 8, 66, 16, 240, 72, 134, 0, 32, 9, 198, 64, 19, 129, 12, 129, 64, 66, 10, 66, 36, 80, 137, 129, 11, 0, 8, 9, 0, 21, 71, 21, 133, 18, 20, 210, 83, 80, 121, 49, 89, 47, 34, 6, 129, 65, 122, 89, 47, 0, 10, 67, 8, 84, 212, 71, 121, 89, 47, 0, 0, 13, 68, 8, 83, 15, 92, 71, 122, 55, 136, 0, 74, 12, 13, 5, 10, 15, 19, 195, 169, 107, 136, 89, 6, 138, 0, 12, 68, 4, 229, 15, 56, 35, 50, 47, 124, 50, 0, 7, 196, 21, 130, 76, 20, 65, 12, 68, 16, 149, 129, 56, 72, 113, 84, 35, 50, 0, 0, 14, 69, 16, 18, 207, 80, 16, 72, 119, 49, 136, 47, 13, 0, 14, 69, 52, 148, 129, 28, 80, 65, 114, 34, 126, 90, 0, 103, 13, 69, 52, 148, 129, 28, 80, 65, 122, 34, 126, 90, 0, 13, 69, 5, 32, 66, 48, 80, 35, 34, 119, 71, 118, 0, 14, 69, 4, 224, 76, 60, 112, 35, 50, 13, 55, 124, 81, 0, 0, 14, 70, 8, 84, 151, 36, 50, 192, 71, 121, 34, 122, 49, 0, 14, 70, 92, 244, 139, 76, 134, 64, 58, 128, 49, 91, 137, 0, 0, 16, 70, 56, 144, 200, 60, 192, 83, 50, 122, 49, 13, 55, 13, 89, 0, 17, 70, 77, 1, 67, 36, 98, 67, 89, 48, 13, 89, 122, 83, 122, 49, 0, 9, 198, 72, 81, 3, 72, 244, 211, 66, 0, 11, 68, 4, 148, 133, 76, 137, 34, 122, 88, 0, 11, 200, 52, 85, 1, 77, 64, 66, 48, 80, 20, 21, 72, 32, 244, 208, 37, 64, 66, 48, 80, 107, 124, 89, 48, 6, 122, 47, 13, 71, 118, 0, 12, 68, 12, 84, 133, 76, 89, 141, 34, 129, 88, 0, 0, 14, 6, 14, 1, 195, 175, 22, 5, 50, 137, 6, 129, 84, 0, 13, 69, 52, 22, 72, 20, 208, 65, 138, 107, 121, 65, 0, 12, 69, 5, 35, 213, 76, 80, 119, 34, 135, 88, 0, 0, 13, 70, 44, 82, 71, 32, 194, 64, 49, 138, 55, 37, 0, 15, 70, 16, 243, 129, 28, 134, 64, 72, 124, 50, 6, 107, 129, 0, 0, 17, 70, 52, 85, 1, 48, 194, 67, 65, 13, 47, 6, 35, 55, 122, 49, 0, 10, 199, 21, 133, 18, 36, 48, 84, 20, 65, 0, 15, 70, 4, 112, 73, 57, 53, 0, 119, 81, 121, 50, 89, 47, 0, 19, 72, 64, 244, 148, 84, 117, 69, 76, 80, 48, 133, 76, 13, 81, 6, 129, 88, 0, 14, 68, 85, 4, 197, 80, 125, 48, 89, 6, 121, 47, 0, 38, 8, 196, 85, 4, 197, 80, 65, 10, 11, 68, 48, 149, 133, 16, 55, 122, 84, 72, 0, 15, 6, 95, 18, 15, 13, 1, 14, 34, 136, 65, 13, 50, 10, 0, 0, 14, 69, 8, 197, 82, 73, 144, 71, 55, 148, 34, 122, 0, 105, 13, 69, 8, 197, 82, 73, 144, 71, 55, 128, 34, 122, 0, 0, 10, 67, 73, 80, 153, 34, 134, 71, 37, 0, 9, 67, 5, 116, 153, 119, 34, 137, 0, 0, 17, 70, 32, 84, 131, 84, 193, 83, 107, 128, 49, 57, 117, 55, 129, 88, 0, 0, 14, 70, 76, 131, 213, 48, 65, 82, 91, 136, 55, 72, 114, 0, 13, 68, 52, 245, 5, 48, 65, 136, 47, 6, 121, 55, 0, 15, 70, 52, 20, 129, 84, 65, 82, 65, 13, 34, 130, 72, 114, 0, 6, 195, 21, 132, 15, 65, 0, 14, 69, 56, 144, 197, 81, 144, 50, 137, 89, 13, 47, 37, 0, 15, 69, 9, 84, 201, 49, 144, 71, 122, 88, 113, 55, 122, 0, 32, 0, 7, 194, 36, 96, 72, 8, 9, 20, 66, 20, 224, 4, 124, 50, 15, 34, 6, 134, 47, 0, 81, 114, 111, 117, 116, 101, 32, 20, 66, 20, 224, 4, 124, 50, 15, 65, 6, 35, 89, 0, 81, 109, 97, 115, 115, 101, 32, 15, 70, 72, 144, 207, 12, 129, 84, 34, 122, 49, 13, 91, 138, 0, 0, 15, 70, 5, 69, 1, 12, 129, 83, 119, 47, 35, 76, 123, 88, 0, 12, 3, 95, 51, 88, 87, 6, 147, 47, 37, 0, 105, 11, 3, 95, 51, 88, 87, 6, 128, 47, 37, 0, 0, 17, 70, 48, 198, 87, 20, 198, 78, 105, 13, 58, 6, 121, 55, 122, 50, 0, 9, 198, 81, 32, 78, 76, 97, 82, 36, 10, 198, 81, 32, 78, 76, 97, 82, 65, 10, 11, 68, 72, 85, 133, 72, 34, 113, 84, 142, 0, 10, 198, 12, 243, 148, 20, 229, 0, 36, 38, 17, 70, 12, 243, 148, 20, 229, 0, 49, 124, 50, 47, 121, 50, 47, 0, 10, 14, 3, 95, 48, 67, 107, 6, 125, 50, 72, 34, 13, 72, 0, 0, 14, 69, 52, 145, 213, 20, 192, 65, 129, 100, 6, 121, 55, 0, 8, 197, 12, 86, 76, 60, 224, 66, 18, 70, 20, 229, 18, 4, 224, 197, 121, 50, 47, 34, 6, 120, 50, 89, 0, 36, 10, 198, 20, 229, 18, 4, 224, 197, 65, 10, 13, 69, 12, 245, 80, 60, 224, 49, 134, 48, 124, 50, 0, 0, 0, 17, 71, 64, 130, 76, 37, 2, 78, 20, 83, 122, 55, 113, 48, 129, 50, 0, 18, 71, 64, 84, 134, 20, 53, 12, 100, 48, 128, 83, 121, 49, 47, 55, 122, 0, 19, 71, 64, 20, 129, 49, 148, 201, 76, 48, 13, 34, 35, 55, 13, 89, 122, 89, 0, 18, 71, 52, 20, 135, 5, 34, 78, 20, 65, 127, 75, 114, 34, 13, 50, 0, 103, 17, 71, 52, 20, 135, 5, 34, 78, 20, 65, 127, 75, 114, 34, 129, 50, 0, 17, 71, 5, 85, 8, 61, 34, 84, 100, 119, 87, 124, 34, 113, 47, 37, 0, 0, 9, 198, 88, 84, 141, 60, 229, 0, 66, 11, 68, 68, 21, 1, 72, 49, 35, 47, 127, 0, 12, 68, 64, 20, 137, 76, 48, 35, 34, 122, 89, 0, 12, 68, 80, 149, 1, 56, 47, 137, 47, 13, 50, 0, 11, 68, 77, 80, 86, 20, 89, 58, 126, 84, 0, 0, 17, 70, 76, 50, 65, 80, 144, 193, 89, 137, 6, 35, 47, 122, 49, 13, 0, 13, 69, 13, 85, 15, 24, 96, 49, 125, 47, 124, 83, 0, 12, 69, 8, 144, 83, 20, 64, 71, 144, 89, 47, 0, 0, 11, 67, 52, 17, 5, 65, 4, 138, 72, 0, 12, 13, 67, 52, 17, 5, 65, 4, 138, 72, 0, 12, 9, 76, 16, 70, 77, 67, 205, 5, 64, 64, 89, 47, 136, 65, 13, 47, 13, 0, 15, 70, 12, 131, 204, 21, 32, 64, 49, 124, 55, 13, 34, 13, 0, 17, 70, 12, 19, 4, 21, 32, 64, 49, 124, 55, 72, 6, 140, 34, 13, 0, 14, 70, 4, 230, 9, 61, 84, 192, 35, 68, 91, 13, 89, 0, 0, 9, 67, 65, 34, 88, 48, 34, 129, 0, 0, 12, 68, 12, 20, 143, 48, 49, 35, 34, 13, 55, 0, 0, 12, 201, 92, 244, 132, 65, 35, 195, 21, 52, 192, 66, 17, 70, 52, 241, 5, 72, 21, 5, 65, 124, 72, 13, 34, 138, 47, 0, 36, 9, 198, 48, 149, 5, 72, 21, 5, 21, 15, 69, 4, 192, 133, 37, 64, 130, 55, 71, 6, 129, 122, 47, 0, 15, 3, 226, 136, 158, 122, 50, 83, 6, 122, 50, 113, 47, 113, 0, 0, 20, 5, 19, 8, 5, 39, 19, 91, 129, 88, 107, 35, 72, 0, 78, 81, 104, 97, 100, 32, 13, 5, 19, 8, 5, 39, 19, 91, 129, 88, 0, 72, 35, 17, 6, 23, 1, 19, 14, 39, 20, 58, 125, 88, 50, 47, 0, 103, 35, 9, 17, 6, 23, 1, 19, 14, 39, 20, 58, 4, 124, 88, 50, 47, 0, 35, 9, 15, 70, 64, 148, 5, 81, 65, 64, 48, 122, 48, 6, 121, 47, 0, 0, 17, 7, 4, 15, 5, 19, 14, 39, 20, 72, 125, 88, 13, 50, 47, 0, 32, 10, 199, 28, 83, 204, 60, 114, 83, 80, 66, 16, 3, 226, 137, 160, 50, 124, 47, 6, 129, 49, 58, 118, 47, 117, 0, 0, 12, 68, 16, 84, 15, 80, 72, 129, 48, 136, 0, 103, 12, 68, 81, 38, 83, 80, 47, 34, 122, 89, 47, 0, 12, 200, 81, 32, 78, 76, 52, 137, 65, 64, 65, 10, 11, 68, 16, 84, 15, 80, 72, 121, 48, 136, 0, 0, 9, 198, 8, 83, 7, 72, 17, 5, 66, 13, 69, 12, 21, 137, 5, 32, 49, 35, 84, 122, 127, 0, 9, 198, 8, 195, 195, 44, 17, 5, 66, 16, 70, 4, 48, 213, 72, 21, 5, 35, 49, 57, 117, 34, 13, 47, 0, 15, 3, 226, 136, 154, 89, 49, 58, 4, 140, 34, 6, 134, 47, 0, 0, 16, 70, 52, 16, 193, 9, 33, 64, 65, 13, 49, 126, 71, 34, 13, 0, 9, 66, 48, 16, 4, 55, 35, 0, 9, 13, 3, 95, 49, 57, 50, 6, 137, 50, 47, 129, 50, 0, 0, 17, 67, 52, 244, 212, 65, 136, 89, 47, 15, 13, 84, 0, 81, 111, 102, 32, 10, 67, 72, 84, 212, 34, 121, 89, 47, 0, 10, 67, 52, 19, 12, 65, 130, 55, 0, 103, 9, 67, 52, 19, 12, 65, 35, 55, 0, 6, 195, 5, 2, 64, 17, 11, 3, 95, 49, 56, 6, 138, 47, 129, 50, 0, 0, 12, 68, 48, 85, 133, 56, 55, 129, 84, 13, 50, 0, 11, 68, 16, 245, 133, 72, 72, 136, 84, 114, 0, 22, 73, 36, 229, 5, 72, 209, 68, 36, 21, 5, 122, 50, 47, 114, 65, 6, 129, 72, 141, 47, 0, 16, 3, 226, 151, 143, 71, 55, 4, 35, 49, 89, 6, 128, 49, 118, 0, 0, 12, 201, 20, 193, 67, 81, 35, 195, 85, 65, 64, 66, 13, 69, 16, 240, 66, 48, 80, 72, 134, 13, 71, 118, 0, 0, 10, 67, 52, 19, 9, 65, 126, 55, 37, 0, 15, 70, 88, 20, 137, 21, 70, 64, 84, 13, 34, 144, 47, 37, 0, 19, 70, 4, 36, 212, 72, 16, 212, 119, 71, 89, 47, 34, 6, 35, 49, 47, 0, 36, 18, 70, 4, 36, 212, 72, 16, 212, 35, 71, 89, 47, 34, 35, 49, 47, 0, 9, 0, 10, 199, 53, 83, 20, 37, 69, 68, 20, 65, 16, 70, 16, 83, 79, 56, 84, 211, 72, 129, 65, 13, 50, 121, 89, 0, 0, 12, 68, 52, 21, 137, 76, 65, 138, 84, 122, 89, 0, 12, 68, 76, 21, 1, 56, 89, 138, 47, 13, 50, 0, 0, 14, 69, 72, 81, 5, 100, 80, 34, 6, 121, 72, 4, 137, 0, 14, 69, 64, 20, 143, 48, 80, 48, 119, 34, 6, 136, 55, 0, 13, 69, 48, 244, 201, 56, 112, 55, 134, 88, 122, 68, 0, 14, 69, 12, 246, 79, 80, 80, 49, 137, 6, 136, 47, 37, 0, 11, 3, 226, 136, 146, 65, 137, 50, 13, 89, 0, 0, 14, 70, 76, 85, 133, 72, 19, 0, 89, 121, 84, 34, 118, 0, 13, 3, 95, 49, 49, 122, 55, 6, 121, 84, 13, 50, 0, 0, 17, 71, 81, 84, 142, 80, 16, 140, 20, 47, 128, 50, 108, 138, 71, 118, 0, 19, 71, 65, 34, 86, 5, 66, 79, 56, 48, 34, 137, 84, 6, 138, 91, 13, 50, 0, 10, 3, 95, 49, 48, 47, 6, 121, 50, 0, 0, 10, 67, 81, 34, 79, 47, 34, 129, 136, 0, 12, 68, 36, 229, 5, 48, 122, 50, 108, 121, 55, 0, 18, 72, 21, 97, 82, 101, 66, 9, 56, 112, 121, 84, 34, 113, 87, 122, 68, 0, 12, 68, 16, 243, 149, 80, 72, 136, 50, 125, 47, 0, 13, 3, 95, 49, 51, 87, 6, 147, 47, 129, 50, 0, 105, 12, 3, 95, 49, 51, 87, 6, 128, 47, 129, 50, 0, 0, 13, 69, 12, 19, 143, 21, 48, 49, 13, 50, 134, 88, 0, 12, 4, 95, 52, 48, 15, 83, 6, 133, 47, 141, 0, 12, 3, 95, 49, 50, 47, 58, 6, 121, 55, 84, 0, 0, 13, 3, 95, 49, 53, 83, 6, 122, 83, 47, 129, 50, 0, 0, 18, 71, 52, 81, 9, 4, 85, 129, 48, 65, 121, 72, 122, 6, 129, 84, 118, 0, 20, 71, 12, 243, 148, 72, 19, 20, 60, 49, 13, 50, 47, 34, 6, 35, 55, 47, 136, 0, 19, 71, 5, 85, 15, 13, 32, 67, 100, 130, 47, 6, 124, 49, 34, 13, 89, 37, 0, 12, 3, 95, 49, 52, 83, 6, 133, 47, 129, 50, 0, 0, 12, 68, 64, 21, 5, 48, 48, 119, 47, 121, 55, 0, 11, 68, 36, 225, 9, 20, 122, 50, 72, 37, 0, 13, 68, 32, 245, 5, 48, 107, 136, 47, 6, 121, 55, 0, 11, 67, 5, 129, 83, 35, 49, 89, 123, 88, 0, 16, 3, 95, 49, 55, 89, 6, 13, 84, 13, 50, 47, 129, 50, 0, 107, 15, 3, 95, 49, 55, 89, 6, 121, 84, 13, 50, 47, 129, 50, 0, 0, 13, 69, 80, 131, 205, 5, 48, 47, 124, 65, 13, 89, 0, 8, 197, 61, 85, 12, 5, 112, 65, 9, 197, 56, 80, 82, 9, 144, 66, 14, 14, 3, 95, 49, 54, 89, 6, 122, 49, 89, 47, 129, 50, 0, 0, 0, 17, 70, 52, 84, 131, 20, 65, 83, 65, 128, 89, 6, 138, 72, 129, 88, 0, 10, 67, 5, 115, 204, 138, 58, 124, 55, 0, 15, 3, 95, 55, 88, 89, 6, 13, 84, 13, 50, 47, 37, 0, 107, 14, 3, 95, 55, 88, 89, 6, 121, 84, 13, 50, 47, 37, 0, 0, 21, 72, 12, 243, 77, 20, 229, 1, 73, 144, 49, 124, 65, 13, 50, 47, 121, 34, 37, 0, 103, 7, 196, 56, 85, 133, 72, 32, 11, 68, 12, 132, 137, 76, 49, 34, 122, 89, 0, 13, 6, 2, 10, 195, 184, 18, 14, 71, 57, 128, 50, 0, 12, 68, 16, 85, 143, 56, 72, 121, 84, 13, 50, 0, 12, 68, 72, 84, 12, 100, 34, 113, 48, 55, 137, 0, 19, 72, 12, 243, 77, 20, 229, 1, 73, 144, 49, 124, 65, 13, 50, 47, 34, 122, 0, 13, 68, 4, 212, 12, 100, 35, 65, 48, 55, 122, 0, 32, 20, 72, 4, 36, 212, 20, 210, 79, 85, 48, 119, 71, 89, 47, 6, 129, 65, 141, 89, 0, 12, 200, 4, 36, 207, 49, 85, 5, 49, 144, 67, 32, 0, 13, 69, 72, 80, 71, 4, 224, 34, 138, 81, 13, 50, 0, 17, 70, 64, 83, 133, 48, 244, 5, 48, 13, 50, 121, 55, 13, 48, 37, 0, 14, 69, 80, 18, 87, 4, 224, 47, 137, 6, 58, 126, 50, 0, 13, 69, 72, 20, 195, 4, 192, 34, 120, 89, 49, 118, 0, 12, 69, 9, 35, 207, 12, 128, 71, 34, 136, 76, 0, 0, 15, 70, 77, 21, 73, 73, 33, 76, 89, 49, 58, 122, 34, 118, 0, 15, 70, 12, 243, 131, 32, 84, 192, 49, 124, 50, 76, 123, 88, 0, 0, 18, 71, 65, 54, 67, 32, 245, 9, 12, 89, 137, 49, 6, 124, 47, 122, 49, 0, 11, 67, 21, 130, 84, 121, 81, 88, 122, 47, 0, 9, 67, 9, 84, 192, 71, 125, 89, 0, 0, 11, 68, 32, 21, 133, 76, 107, 35, 84, 88, 0, 15, 70, 72, 18, 77, 20, 229, 0, 34, 138, 65, 13, 50, 47, 0, 12, 68, 48, 144, 146, 20, 55, 129, 71, 34, 13, 0, 10, 68, 20, 20, 140, 100, 128, 55, 122, 0, 0, 13, 69, 76, 147, 133, 4, 64, 91, 113, 50, 138, 72, 0, 14, 69, 80, 19, 80, 60, 224, 47, 35, 65, 48, 124, 50, 0, 9, 198, 56, 21, 9, 88, 149, 25, 66, 0, 0, 9, 67, 81, 165, 64, 47, 89, 134, 0, 17, 71, 72, 83, 132, 21, 99, 213, 76, 34, 124, 50, 72, 113, 84, 134, 0, 18, 71, 64, 20, 129, 52, 85, 5, 72, 48, 13, 34, 35, 65, 113, 47, 114, 0, 17, 71, 5, 85, 15, 29, 32, 80, 32, 130, 47, 13, 81, 34, 35, 83, 0, 11, 3, 224, 165, 164, 72, 125, 50, 72, 119, 0, 0, 18, 72, 32, 83, 131, 20, 99, 210, 80, 128, 107, 121, 50, 89, 83, 133, 87, 0, 0, 12, 69, 92, 149, 8, 21, 32, 58, 122, 86, 114, 0, 9, 198, 77, 64, 77, 64, 81, 5, 66, 16, 70, 72, 83, 133, 28, 17, 5, 34, 121, 50, 13, 81, 138, 72, 0, 16, 70, 64, 20, 129, 76, 149, 5, 48, 35, 34, 13, 89, 137, 47, 0, 9, 198, 4, 229, 9, 16, 245, 5, 65, 0, 15, 6, 1, 18, 5, 14, 39, 20, 4, 127, 50, 47, 0, 35, 12, 15, 70, 92, 80, 147, 37, 65, 64, 58, 121, 71, 89, 137, 47, 0, 9, 198, 64, 194, 67, 5, 65, 64, 66, 14, 70, 8, 150, 129, 73, 33, 64, 71, 122, 88, 6, 127, 0, 9, 198, 4, 230, 77, 61, 33, 64, 67, 0, 17, 7, 8, 1, 22, 5, 14, 39, 20, 107, 35, 84, 13, 50, 47, 0, 35, 16, 70, 92, 147, 142, 37, 1, 71, 58, 122, 50, 113, 48, 121, 81, 0, 0, 0, 28, 5, 23, 15, 14, 39, 20, 58, 6, 136, 50, 47, 35, 84, 47, 116, 0, 32, 12, 82, 104, 97, 118, 101, 32, 116, 111, 32, 23, 5, 23, 15, 14, 39, 20, 58, 136, 50, 47, 107, 35, 84, 0, 35, 14, 81, 104, 97, 118, 101, 32, 22, 5, 23, 15, 14, 39, 20, 58, 136, 50, 47, 119, 84, 0, 35, 73, 81, 104, 97, 118, 101, 32, 16, 5, 23, 15, 14, 39, 20, 58, 136, 50, 47, 0, 76, 32, 12, 9, 9, 198, 77, 64, 71, 56, 21, 5, 66, 17, 70, 76, 84, 1, 72, 21, 5, 89, 121, 48, 114, 34, 138, 47, 0, 36, 16, 70, 76, 84, 1, 72, 21, 5, 89, 121, 48, 14, 34, 13, 47, 0, 13, 69, 72, 21, 8, 21, 32, 34, 126, 86, 114, 0, 135, 10, 67, 21, 5, 66, 129, 48, 125, 71, 0, 21, 73, 12, 84, 148, 36, 98, 67, 5, 65, 64, 89, 114, 47, 122, 83, 122, 49, 13, 47, 0, 11, 69, 4, 85, 8, 21, 32, 129, 87, 13, 0, 0, 15, 70, 72, 81, 133, 73, 32, 76, 34, 113, 83, 128, 34, 118, 0, 13, 70, 56, 245, 200, 21, 33, 64, 50, 136, 58, 140, 0, 14, 70, 5, 84, 212, 21, 33, 64, 130, 89, 47, 6, 142, 0, 0, 6, 195, 41, 84, 212, 32, 17, 7, 23, 5, 18, 5, 14, 39, 20, 4, 58, 128, 50, 47, 0, 35, 12, 18, 71, 49, 83, 131, 33, 35, 207, 52, 55, 125, 50, 76, 15, 34, 134, 65, 0, 17, 71, 25, 33, 69, 48, 19, 131, 20, 83, 34, 129, 55, 120, 50, 89, 0, 0, 11, 68, 4, 20, 143, 56, 140, 34, 13, 50, 0, 19, 72, 24, 18, 18, 20, 226, 5, 37, 64, 83, 35, 34, 13, 50, 107, 137, 47, 0, 16, 70, 16, 81, 137, 12, 149, 0, 72, 121, 83, 113, 89, 122, 47, 0, 20, 72, 4, 197, 15, 28, 85, 8, 21, 32, 4, 130, 55, 47, 13, 81, 121, 86, 114, 0, 0, 20, 73, 80, 83, 80, 21, 32, 84, 85, 33, 64, 47, 121, 65, 48, 34, 113, 76, 114, 0, 9, 198, 61, 85, 3, 72, 244, 0, 65, 8, 197, 5, 32, 66, 36, 48, 65, 0, 16, 70, 4, 230, 9, 21, 70, 64, 35, 68, 88, 6, 144, 47, 37, 0, 0, 12, 201, 84, 197, 18, 5, 98, 79, 48, 85, 0, 67, 16, 3, 226, 150, 160, 71, 55, 6, 35, 49, 89, 49, 58, 6, 140, 0, 0, 13, 68, 104, 80, 146, 4, 88, 129, 71, 34, 13, 0, 103, 9, 198, 36, 228, 212, 20, 17, 0, 8, 11, 68, 80, 21, 1, 72, 47, 126, 47, 114, 0, 11, 68, 48, 149, 5, 72, 55, 129, 47, 114, 0, 0, 14, 69, 72, 80, 201, 64, 80, 34, 121, 89, 113, 48, 129, 0, 13, 69, 32, 84, 133, 80, 240, 107, 142, 6, 47, 134, 0, 0, 0, 15, 70, 40, 82, 15, 88, 18, 0, 75, 13, 107, 136, 84, 13, 0, 13, 3, 95, 50, 88, 47, 58, 6, 121, 50, 108, 37, 0, 0, 11, 68, 21, 21, 65, 48, 129, 49, 58, 118, 0, 0, 14, 69, 64, 148, 129, 13, 144, 48, 145, 34, 13, 89, 37, 0, 15, 69, 12, 244, 205, 61, 48, 49, 124, 88, 65, 136, 89, 0, 103, 14, 69, 12, 244, 205, 61, 48, 49, 124, 88, 65, 124, 89, 0, 14, 69, 12, 241, 9, 25, 144, 49, 136, 72, 113, 83, 137, 0, 0, 13, 202, 36, 229, 5, 73, 35, 199, 5, 67, 210, 100, 67, 0, 17, 70, 76, 49, 78, 5, 34, 79, 89, 13, 50, 35, 34, 37, 136, 0, 103, 16, 70, 76, 49, 78, 5, 34, 79, 89, 13, 50, 127, 34, 37, 136, 0, 17, 71, 52, 19, 135, 21, 67, 213, 80, 65, 124, 50, 90, 47, 6, 134, 0, 19, 71, 16, 240, 212, 72, 147, 129, 48, 72, 124, 49, 47, 34, 6, 137, 50, 118, 0, 0, 11, 68, 16, 21, 137, 20, 72, 138, 84, 37, 0, 0, 14, 69, 88, 17, 193, 73, 144, 84, 138, 81, 13, 34, 122, 0, 14, 69, 80, 84, 212, 21, 48, 47, 121, 89, 47, 129, 88, 0, 8, 197, 61, 85, 12, 5, 144, 65, 0, 15, 70, 72, 84, 212, 25, 83, 0, 34, 121, 89, 47, 83, 118, 0, 17, 70, 52, 145, 20, 21, 35, 64, 65, 6, 122, 72, 47, 4, 128, 65, 0, 0, 20, 71, 25, 35, 206, 81, 0, 71, 20, 83, 34, 6, 125, 50, 47, 48, 4, 138, 75, 0, 0, 22, 72, 28, 193, 78, 72, 245, 8, 21, 48, 81, 55, 4, 121, 50, 34, 6, 124, 87, 123, 89, 0, 0, 12, 69, 48, 85, 8, 4, 192, 55, 129, 87, 118, 0, 14, 69, 32, 84, 143, 36, 224, 107, 121, 34, 136, 122, 50, 0, 0, 11, 67, 76, 83, 73, 89, 121, 65, 137, 0, 103, 0, 0, 11, 68, 76, 16, 146, 20, 89, 138, 71, 114, 0, 11, 3, 95, 63, 63, 89, 122, 65, 71, 118, 0, 0, 13, 69, 5, 35, 213, 56, 64, 119, 34, 135, 50, 72, 0, 14, 69, 80, 245, 193, 72, 64, 47, 117, 58, 132, 72, 0, 66, 14, 69, 64, 20, 212, 20, 64, 48, 138, 89, 47, 123, 72, 0, 13, 69, 9, 34, 68, 4, 192, 71, 34, 137, 72, 118, 0, 13, 67, 49, 65, 0, 55, 122, 65, 113, 47, 113, 72, 0, 0, 5, 194, 49, 64, 24, 11, 66, 53, 32, 65, 122, 89, 47, 114, 0, 24, 0, 19, 71, 5, 85, 15, 52, 21, 15, 56, 130, 47, 6, 124, 65, 13, 47, 13, 50, 0, 11, 3, 95, 52, 88, 83, 6, 133, 47, 37, 0, 0, 26, 68, 24, 148, 147, 80, 83, 6, 147, 89, 47, 10, 48, 55, 4, 138, 89, 0, 105, 81, 112, 108, 97, 99, 101, 32, 25, 68, 24, 148, 147, 80, 83, 6, 128, 89, 47, 10, 48, 55, 4, 138, 89, 0, 81, 112, 108, 97, 99, 101, 32, 0, 9, 67, 76, 80, 78, 91, 130, 50, 0, 17, 70, 104, 147, 66, 4, 37, 197, 88, 113, 65, 71, 126, 71, 58, 37, 0, 11, 67, 60, 208, 78, 136, 65, 6, 35, 50, 0, 8, 197, 85, 3, 9, 25, 64, 66, 8, 197, 36, 228, 197, 13, 64, 65, 0, 0, 9, 67, 56, 240, 72, 50, 136, 125, 0, 0, 0, 13, 69, 8, 241, 193, 73, 64, 71, 136, 81, 127, 47, 0, 8, 197, 60, 34, 133, 13, 64, 36, 9, 197, 60, 34, 133, 13, 64, 65, 10, 0, 10, 66, 28, 240, 4, 81, 136, 0, 12, 9, 15, 66, 48, 80, 55, 129, 6, 35, 50, 0, 81, 97, 110, 110, 32, 15, 70, 64, 244, 148, 84, 112, 76, 48, 133, 76, 13, 81, 118, 0, 15, 70, 65, 33, 70, 4, 49, 64, 48, 34, 121, 83, 13, 89, 0, 9, 66, 48, 80, 55, 13, 23, 0, 9, 15, 70, 32, 244, 212, 4, 113, 64, 107, 124, 89, 47, 113, 75, 0, 9, 198, 24, 147, 129, 56, 49, 64, 36, 16, 70, 24, 147, 129, 56, 49, 64, 83, 137, 50, 35, 50, 89, 0, 9, 0, 17, 71, 72, 81, 133, 72, 83, 131, 20, 34, 121, 83, 34, 13, 50, 89, 0, 14, 70, 52, 19, 77, 61, 66, 0, 65, 35, 65, 13, 87, 0, 12, 3, 95, 53, 88, 83, 6, 122, 83, 47, 37, 0, 0, 10, 68, 76, 145, 8, 20, 91, 129, 13, 0, 11, 68, 48, 21, 20, 20, 55, 126, 108, 138, 0, 0, 13, 67, 28, 245, 0, 2, 81, 124, 47, 0, 12, 35, 9, 15, 69, 28, 243, 69, 72, 16, 81, 136, 65, 6, 140, 34, 13, 0, 17, 70, 81, 32, 86, 21, 53, 25, 47, 34, 35, 84, 13, 89, 47, 37, 0, 13, 69, 25, 84, 195, 36, 16, 83, 57, 134, 91, 13, 0, 13, 69, 16, 148, 15, 48, 80, 72, 137, 48, 136, 55, 0, 20, 73, 8, 245, 82, 28, 83, 201, 76, 145, 64, 71, 143, 90, 58, 126, 88, 6, 129, 0, 0, 16, 70, 52, 148, 129, 8, 83, 0, 65, 122, 34, 13, 71, 121, 55, 0, 14, 70, 56, 244, 134, 60, 194, 192, 50, 132, 83, 13, 49, 0, 15, 70, 56, 21, 21, 72, 19, 0, 50, 35, 76, 13, 34, 118, 0, 0, 16, 71, 76, 86, 67, 32, 83, 12, 20, 89, 138, 91, 6, 121, 55, 0, 20, 71, 21, 131, 206, 21, 32, 84, 20, 121, 81, 88, 6, 124, 50, 13, 34, 138, 47, 0, 18, 71, 16, 148, 208, 5, 32, 84, 20, 72, 122, 89, 48, 13, 34, 13, 47, 0, 0, 9, 198, 21, 132, 12, 60, 149, 0, 36, 10, 198, 21, 132, 12, 60, 149, 0, 65, 10, 0, 13, 69, 81, 34, 65, 28, 80, 47, 34, 129, 126, 90, 0, 14, 69, 76, 85, 133, 72, 80, 89, 113, 84, 6, 142, 0, 9, 13, 69, 76, 49, 78, 36, 48, 89, 129, 50, 122, 49, 0, 14, 69, 64, 81, 1, 48, 240, 48, 121, 72, 13, 55, 136, 0, 13, 69, 52, 19, 149, 72, 80, 65, 13, 50, 57, 143, 0, 0, 9, 198, 28, 243, 196, 16, 22, 64, 66, 15, 70, 13, 85, 1, 92, 22, 64, 49, 125, 47, 13, 58, 138, 0, 0, 9, 67, 56, 245, 20, 50, 124, 47, 0, 18, 71, 20, 193, 67, 81, 35, 196, 20, 113, 55, 121, 49, 47, 34, 136, 72, 0, 6, 195, 60, 83, 64, 17, 13, 3, 95, 54, 88, 89, 6, 122, 49, 89, 47, 37, 0, 0, 11, 68, 69, 80, 83, 32, 49, 58, 124, 91, 0, 0, 13, 69, 72, 16, 130, 37, 48, 34, 35, 71, 137, 88, 0, 13, 69, 32, 245, 11, 21, 144, 107, 124, 47, 49, 129, 0, 22, 73, 9, 84, 133, 5, 80, 210, 4, 54, 64, 71, 57, 143, 6, 124, 49, 34, 13, 89, 37, 0, 13, 4, 95, 53, 48, 15, 83, 6, 122, 83, 47, 141, 0, 0, 10, 67, 12, 195, 197, 49, 55, 136, 37, 0, 17, 7, 2, 15, 7, 15, 20, 195, 161, 98, 111, 103, 111, 116, 97, 0, 29, 15, 70, 52, 19, 22, 21, 35, 128, 65, 130, 55, 84, 114, 50, 0, 10, 67, 52, 19, 65, 65, 126, 65, 119, 0, 0, 16, 71, 29, 33, 69, 57, 114, 67, 32, 81, 34, 121, 50, 122, 76, 0, 0, 10, 67, 56, 245, 19, 50, 124, 47, 89, 0, 15, 70, 52, 243, 147, 36, 85, 82, 65, 13, 89, 57, 148, 0, 105, 14, 70, 52, 243, 147, 36, 85, 82, 65, 13, 89, 57, 128, 0, 0, 15, 69, 4, 52, 143, 77, 48, 13, 49, 34, 124, 89, 0, 74, 12, 13, 69, 32, 84, 144, 21, 48, 107, 128, 48, 129, 88, 0, 14, 69, 12, 19, 80, 85, 48, 49, 35, 65, 48, 13, 89, 0, 0, 0, 21, 73, 12, 243, 142, 20, 53, 9, 13, 85, 0, 49, 13, 50, 121, 47, 113, 49, 13, 47, 0, 16, 70, 36, 225, 129, 52, 245, 83, 122, 50, 83, 13, 65, 13, 89, 0, 0, 12, 68, 64, 17, 18, 20, 48, 126, 72, 34, 138, 0, 0, 16, 69, 92, 149, 8, 36, 224, 58, 122, 86, 122, 50, 0, 74, 12, 28, 13, 69, 56, 21, 8, 4, 224, 50, 138, 87, 13, 50, 0, 15, 70, 12, 243, 77, 20, 224, 197, 49, 13, 65, 121, 50, 89, 0, 0, 0, 7, 195, 48, 36, 192, 17, 42, 11, 67, 48, 36, 192, 48, 135, 50, 72, 88, 0, 0, 12, 68, 16, 21, 137, 76, 72, 138, 84, 122, 89, 0, 12, 68, 52, 150, 5, 72, 65, 122, 49, 89, 114, 0, 0, 13, 69, 4, 97, 200, 4, 224, 35, 83, 81, 35, 50, 0, 15, 69, 36, 228, 212, 4, 192, 122, 50, 89, 47, 6, 130, 55, 0, 0, 14, 70, 12, 243, 142, 20, 195, 0, 49, 124, 50, 13, 55, 0, 0, 9, 67, 104, 241, 64, 88, 136, 37, 0, 17, 71, 48, 147, 79, 85, 50, 78, 20, 55, 122, 65, 13, 88, 129, 50, 0, 13, 67, 13, 68, 140, 49, 13, 50, 47, 34, 136, 55, 0, 10, 3, 95, 56, 88, 6, 138, 47, 37, 0, 0, 11, 200, 36, 228, 201, 28, 133, 6, 84, 192, 66, 12, 68, 32, 84, 143, 16, 107, 121, 34, 13, 72, 0, 0, 8, 197, 61, 85, 16, 85, 64, 65, 16, 70, 56, 81, 204, 36, 113, 69, 50, 121, 81, 55, 122, 90, 138, 0, 14, 69, 52, 84, 133, 77, 64, 65, 141, 34, 13, 89, 47, 0, 20, 67, 52, 18, 78, 65, 6, 138, 50, 89, 47, 34, 4, 129, 47, 0, 81, 115, 116, 32, 8, 197, 21, 132, 15, 73, 64, 36, 9, 197, 21, 132, 15, 73, 64, 65, 10, 0, 16, 70, 93, 147, 205, 36, 225, 192, 58, 137, 6, 136, 65, 122, 68, 0, 15, 70, 65, 33, 83, 4, 113, 64, 48, 34, 121, 89, 122, 75, 0, 0, 0, 12, 68, 52, 20, 137, 4, 65, 119, 34, 129, 13, 0, 11, 68, 32, 84, 143, 20, 107, 141, 34, 136, 0, 19, 72, 12, 128, 78, 16, 83, 9, 21, 32, 91, 35, 50, 72, 13, 55, 6, 142, 0, 20, 72, 12, 20, 130, 85, 33, 84, 61, 32, 49, 127, 71, 13, 34, 138, 47, 114, 0, 103, 20, 72, 12, 20, 130, 85, 33, 84, 61, 32, 49, 127, 71, 13, 34, 6, 121, 47, 114, 0, 0, 9, 67, 36, 18, 78, 129, 13, 50, 0, 14, 69, 8, 197, 69, 77, 64, 71, 55, 134, 13, 89, 47, 0, 0, 9, 66, 52, 80, 65, 129, 0, 15, 14, 9, 66, 52, 80, 4, 65, 129, 0, 9, 14, 70, 80, 16, 140, 20, 21, 64, 47, 35, 71, 55, 136, 0, 14, 70, 52, 147, 5, 4, 113, 64, 65, 137, 55, 113, 75, 0, 16, 70, 12, 20, 18, 36, 49, 64, 49, 119, 48, 34, 6, 129, 89, 0, 0, 12, 3, 95, 57, 88, 50, 6, 137, 50, 47, 37, 0, 0, 14, 70, 32, 20, 146, 36, 85, 0, 107, 35, 34, 141, 47, 0, 16, 70, 56, 81, 204, 20, 53, 0, 50, 113, 81, 55, 121, 49, 47, 0, 15, 70, 13, 35, 207, 44, 81, 0, 49, 34, 117, 49, 122, 72, 0, 19, 72, 9, 81, 7, 21, 34, 71, 5, 32, 71, 125, 75, 13, 34, 122, 81, 127, 0, 0, 17, 69, 32, 21, 137, 56, 112, 4, 107, 35, 84, 122, 68, 0, 12, 35, 9, 13, 69, 72, 80, 68, 52, 80, 34, 129, 72, 65, 129, 0, 16, 69, 25, 84, 143, 72, 80, 83, 57, 134, 34, 6, 130, 34, 37, 0, 14, 69, 12, 241, 206, 4, 48, 49, 124, 50, 57, 35, 49, 0, 15, 70, 8, 243, 136, 60, 210, 69, 71, 124, 50, 13, 65, 129, 0, 0, 14, 70, 48, 147, 132, 76, 86, 64, 55, 122, 50, 88, 37, 0, 8, 67, 52, 22, 65, 65, 144, 0, 14, 70, 77, 81, 134, 60, 194, 192, 89, 125, 83, 13, 49, 0, 13, 202, 12, 148, 131, 84, 209, 133, 72, 83, 131, 20, 66, 16, 70, 8, 148, 5, 16, 19, 0, 71, 137, 48, 6, 129, 72, 118, 0, 9, 67, 4, 131, 217, 119, 107, 139, 0, 0, 26, 67, 52, 22, 64, 4, 65, 138, 107, 6, 35, 84, 47, 116, 0, 32, 14, 82, 104, 97, 118, 101, 32, 116, 111, 32, 19, 67, 52, 22, 64, 65, 138, 107, 119, 84, 0, 35, 77, 81, 104, 97, 118, 101, 32, 10, 67, 52, 22, 64, 65, 138, 0, 32, 12, 15, 71, 12, 128, 82, 48, 245, 20, 20, 91, 127, 55, 13, 47, 0, 18, 71, 76, 80, 210, 21, 64, 82, 100, 89, 121, 49, 34, 13, 47, 34, 122, 0, 20, 71, 37, 66, 78, 21, 32, 82, 100, 137, 47, 6, 122, 50, 13, 34, 13, 34, 122, 0, 17, 71, 29, 35, 211, 88, 83, 143, 72, 81, 34, 136, 84, 13, 50, 114, 0, 0, 13, 68, 52, 83, 149, 76, 65, 121, 50, 57, 134, 88, 0, 16, 70, 12, 244, 9, 48, 245, 0, 49, 136, 48, 137, 55, 13, 47, 0, 0, 15, 69, 4, 230, 79, 56, 80, 121, 50, 122, 58, 125, 50, 0, 106, 14, 69, 4, 230, 79, 56, 80, 121, 50, 122, 58, 124, 50, 0, 9, 67, 60, 208, 82, 136, 65, 127, 0, 14, 69, 56, 245, 77, 20, 16, 50, 134, 65, 6, 138, 13, 0, 14, 69, 12, 20, 9, 80, 16, 49, 35, 48, 122, 47, 13, 0, 12, 69, 8, 195, 213, 76, 80, 71, 55, 135, 88, 0, 0, 17, 70, 65, 34, 86, 4, 54, 64, 48, 34, 137, 84, 13, 89, 37, 0, 103, 16, 70, 81, 34, 76, 60, 118, 64, 47, 34, 122, 55, 13, 75, 37, 0, 15, 70, 72, 80, 201, 80, 19, 0, 34, 113, 89, 137, 47, 118, 0, 11, 3, 95, 63, 65, 55, 4, 121, 47, 114, 0, 0, 10, 199, 76, 80, 129, 77, 66, 65, 56, 66, 18, 71, 4, 69, 133, 73, 48, 82, 100, 35, 72, 84, 114, 89, 13, 34, 37, 0, 0, 20, 72, 77, 68, 153, 12, 131, 137, 56, 80, 89, 47, 34, 6, 122, 49, 50, 129, 50, 0, 12, 68, 72, 81, 137, 80, 34, 129, 83, 122, 47, 0, 0, 0, 0, 0, 9, 198, 92, 245, 76, 17, 53, 0, 76, 16, 70, 52, 144, 200, 36, 112, 78, 65, 122, 91, 122, 81, 13, 50, 0, 10, 68, 12, 244, 144, 76, 49, 132, 0, 9, 0, 17, 70, 77, 84, 137, 56, 19, 69, 89, 143, 34, 122, 50, 6, 35, 65, 0, 14, 69, 64, 19, 20, 73, 144, 48, 130, 55, 47, 34, 122, 0, 14, 69, 33, 80, 146, 37, 48, 107, 134, 71, 34, 122, 89, 0, 0, 11, 67, 85, 3, 206, 13, 48, 124, 50, 0, 74, 16, 70, 72, 84, 85, 36, 83, 64, 34, 121, 49, 58, 113, 121, 65, 0, 17, 70, 61, 33, 71, 4, 227, 192, 124, 34, 122, 81, 6, 126, 50, 136, 0, 0, 19, 66, 36, 224, 122, 50, 119, 15, 34, 6, 136, 0, 82, 97, 32, 114, 111, 119, 32, 20, 66, 36, 224, 122, 50, 15, 58, 122, 76, 0, 74, 8, 81, 119, 104, 105, 99, 104, 32, 15, 66, 36, 224, 2, 122, 50, 86, 115, 0, 81, 116, 104, 101, 32, 11, 66, 36, 224, 2, 122, 50, 0, 11, 9, 34, 20, 71, 52, 83, 129, 28, 84, 137, 20, 65, 13, 50, 6, 35, 75, 57, 13, 34, 37, 0, 5, 194, 56, 64, 9, 9, 3, 226, 153, 175, 91, 127, 48, 0, 0, 15, 70, 16, 147, 143, 76, 21, 82, 72, 137, 50, 13, 89, 132, 0, 6, 195, 61, 67, 200, 17, 6, 195, 53, 144, 64, 17, 11, 4, 95, 8, 15, 11, 107, 6, 117, 49, 0, 0, 11, 68, 104, 18, 82, 20, 88, 137, 6, 142, 0, 10, 68, 76, 131, 206, 20, 91, 124, 50, 0, 12, 68, 32, 84, 143, 56, 107, 121, 34, 13, 50, 0, 10, 3, 226, 153, 173, 83, 55, 35, 47, 0, 0, 0, 16, 70, 13, 84, 146, 20, 229, 0, 49, 6, 114, 13, 50, 47, 0, 103, 18, 70, 53, 82, 1, 52, 208, 68, 109, 111, 104, 97, 109, 109, 97, 100, 0, 29, 9, 198, 85, 5, 9, 28, 133, 0, 66, 16, 70, 64, 243, 9, 80, 84, 128, 48, 13, 55, 6, 137, 47, 114, 0, 0, 19, 71, 33, 148, 5, 72, 35, 204, 4, 107, 137, 48, 6, 128, 71, 13, 55, 13, 0, 15, 4, 95, 15, 7, 15, 6, 124, 81, 124, 50, 4, 121, 49, 0, 0, 13, 68, 56, 243, 206, 20, 50, 136, 58, 125, 50, 0, 106, 12, 68, 56, 243, 206, 20, 50, 136, 58, 124, 50, 0, 12, 68, 61, 97, 82, 80, 136, 84, 6, 128, 47, 0, 0, 13, 69, 72, 81, 9, 4, 192, 34, 129, 72, 144, 55, 0, 0, 9, 66, 61, 32, 132, 0, 72, 8, 9, 10, 67, 65, 35, 211, 48, 34, 136, 88, 0, 15, 70, 32, 243, 19, 80, 84, 128, 107, 136, 55, 89, 47, 114, 0, 13, 202, 16, 83, 79, 57, 53, 18, 5, 66, 86, 20, 66, 0, 0, 0, 0, 10, 67, 76, 83, 147, 89, 121, 50, 89, 0, 0, 13, 67, 92, 83, 148, 2, 58, 121, 50, 47, 0, 12, 9, 17, 71, 4, 69, 133, 73, 66, 83, 20, 35, 72, 84, 114, 47, 137, 88, 0, 0, 21, 72, 52, 17, 1, 28, 20, 195, 5, 32, 65, 35, 72, 13, 81, 6, 35, 89, 49, 114, 0, 0, 11, 69, 48, 21, 217, 21, 32, 55, 139, 114, 0, 12, 69, 9, 84, 147, 5, 32, 71, 128, 89, 114, 0, 0, 15, 70, 16, 148, 197, 5, 49, 64, 72, 122, 88, 6, 129, 88, 0, 17, 70, 12, 243, 134, 72, 243, 148, 49, 13, 50, 83, 34, 125, 50, 47, 0, 15, 70, 4, 229, 9, 69, 81, 64, 35, 50, 47, 6, 129, 49, 0, 0, 10, 67, 29, 82, 64, 81, 134, 37, 0, 10, 0, 16, 8, 20, 8, 5, 18, 5, 39, 12, 12, 86, 140, 55, 0, 72, 32, 10, 67, 72, 243, 137, 34, 124, 50, 37, 0, 13, 68, 80, 86, 1, 76, 47, 121, 49, 89, 13, 89, 0, 9, 198, 61, 134, 77, 61, 35, 206, 67, 10, 67, 28, 83, 137, 75, 129, 50, 37, 0, 0, 14, 69, 52, 19, 1, 92, 144, 65, 119, 55, 126, 58, 37, 0, 14, 69, 28, 83, 133, 88, 16, 75, 13, 50, 129, 84, 13, 0, 13, 69, 60, 85, 86, 72, 80, 148, 84, 34, 13, 0, 105, 12, 69, 60, 85, 86, 72, 80, 128, 84, 34, 13, 0, 17, 70, 24, 244, 133, 57, 50, 67, 83, 13, 34, 121, 50, 89, 122, 49, 0, 8, 197, 5, 32, 193, 16, 80, 66, 0, 16, 70, 76, 243, 9, 12, 149, 0, 89, 13, 55, 122, 89, 113, 47, 0, 0, 18, 71, 80, 83, 80, 61, 32, 82, 100, 47, 121, 65, 48, 34, 13, 34, 122, 0, 20, 71, 52, 85, 1, 8, 243, 9, 12, 65, 121, 47, 13, 71, 6, 124, 55, 122, 49, 0, 0, 12, 68, 4, 32, 66, 4, 35, 71, 119, 71, 13, 0, 12, 68, 72, 80, 68, 16, 34, 129, 6, 35, 72, 0, 0, 12, 69, 64, 84, 147, 36, 16, 48, 128, 90, 13, 0, 14, 69, 44, 244, 207, 88, 240, 49, 124, 89, 13, 84, 136, 0, 12, 69, 65, 54, 67, 32, 80, 89, 137, 49, 129, 0, 8, 67, 40, 245, 82, 90, 143, 0, 0, 13, 70, 65, 54, 67, 32, 81, 0, 89, 137, 49, 72, 0, 9, 198, 61, 85, 2, 85, 36, 212, 65, 5, 194, 61, 48, 17, 0, 9, 67, 36, 19, 128, 129, 13, 50, 0, 14, 203, 36, 225, 146, 5, 53, 18, 84, 53, 21, 72, 80, 65, 17, 71, 24, 244, 133, 77, 64, 76, 48, 83, 133, 89, 47, 6, 130, 55, 0, 16, 71, 5, 48, 197, 73, 64, 73, 56, 35, 89, 114, 47, 138, 50, 0, 0, 9, 67, 56, 243, 133, 50, 125, 50, 0, 11, 68, 8, 84, 153, 48, 71, 121, 34, 118, 0, 0, 13, 69, 84, 225, 9, 21, 48, 125, 50, 72, 37, 88, 0, 12, 201, 12, 243, 148, 72, 245, 133, 73, 54, 64, 65, 14, 69, 12, 19, 129, 73, 144, 49, 13, 50, 140, 34, 37, 0, 15, 70, 4, 230, 84, 32, 147, 135, 121, 50, 113, 87, 122, 68, 0, 6, 195, 65, 35, 198, 24, 0, 17, 70, 32, 84, 143, 37, 51, 64, 107, 121, 34, 136, 122, 88, 13, 65, 0, 15, 70, 20, 66, 84, 36, 243, 128, 113, 72, 122, 91, 13, 50, 0, 17, 70, 8, 149, 21, 52, 83, 128, 71, 122, 76, 134, 65, 13, 50, 0, 135, 13, 4, 95, 48, 77, 50, 65, 6, 122, 55, 141, 50, 0, 0, 10, 198, 12, 17, 134, 20, 147, 133, 103, 66, 19, 71, 40, 84, 149, 76, 19, 5, 52, 75, 13, 34, 134, 89, 13, 55, 13, 65, 0, 9, 67, 72, 245, 84, 34, 135, 47, 0, 17, 71, 72, 81, 133, 73, 34, 78, 28, 34, 113, 83, 128, 34, 122, 68, 0, 13, 4, 95, 48, 77, 51, 71, 6, 122, 55, 141, 50, 0, 0, 11, 68, 52, 20, 137, 20, 65, 119, 34, 129, 0, 12, 68, 44, 20, 21, 80, 49, 119, 48, 117, 47, 0, 0, 23, 73, 56, 85, 198, 61, 83, 132, 48, 19, 132, 50, 57, 134, 83, 13, 50, 72, 55, 119, 50, 72, 0, 14, 69, 77, 68, 137, 65, 144, 89, 47, 34, 137, 48, 122, 0, 13, 69, 64, 21, 8, 61, 48, 48, 138, 87, 124, 89, 0, 14, 4, 95, 48, 77, 49, 87, 6, 135, 88, 13, 50, 72, 0, 0, 17, 70, 88, 243, 3, 4, 227, 192, 84, 124, 55, 49, 6, 138, 50, 136, 0, 12, 4, 95, 2, 18, 22, 71, 34, 6, 129, 84, 0, 0, 0, 12, 68, 8, 85, 23, 76, 71, 121, 47, 117, 89, 0, 0, 10, 67, 77, 81, 90, 89, 134, 113, 88, 0, 12, 201, 77, 84, 5, 73, 98, 83, 36, 243, 128, 67, 14, 69, 52, 20, 131, 20, 192, 65, 127, 89, 6, 121, 55, 0, 17, 70, 20, 212, 8, 5, 50, 83, 121, 65, 83, 13, 89, 122, 89, 0, 9, 12, 69, 12, 130, 83, 20, 192, 76, 122, 88, 118, 0, 0, 15, 70, 52, 83, 9, 77, 48, 64, 65, 13, 55, 122, 89, 13, 0, 9, 198, 52, 83, 12, 37, 48, 64, 66, 9, 198, 92, 81, 75, 20, 225, 0, 66, 13, 70, 52, 19, 136, 61, 84, 128, 65, 35, 50, 146, 0, 0, 10, 67, 56, 244, 128, 50, 132, 0, 8, 9, 18, 67, 24, 244, 128, 83, 132, 58, 124, 50, 0, 66, 14, 81, 111, 110, 101, 32, 23, 67, 24, 244, 128, 83, 13, 13, 15, 58, 6, 137, 55, 0, 82, 97, 32, 119, 104, 105, 108, 101, 32, 16, 67, 24, 244, 128, 83, 114, 86, 115, 0, 34, 81, 116, 104, 101, 32, 15, 67, 24, 244, 128, 83, 13, 13, 50, 0, 34, 81, 97, 110, 32, 13, 67, 24, 244, 128, 83, 13, 13, 0, 34, 81, 97, 32, 9, 67, 24, 244, 128, 83, 132, 0, 72, 18, 71, 76, 80, 210, 21, 66, 86, 20, 89, 129, 49, 34, 13, 47, 122, 84, 0, 15, 71, 13, 35, 201, 77, 48, 78, 80, 49, 58, 126, 89, 150, 0, 0, 16, 67, 52, 19, 153, 65, 121, 50, 122, 13, 84, 0, 81, 111, 102, 32, 11, 67, 52, 19, 153, 65, 121, 50, 37, 0, 34, 11, 67, 92, 84, 133, 2, 58, 128, 0, 35, 9, 15, 70, 8, 244, 215, 20, 195, 0, 71, 124, 88, 58, 121, 55, 0, 12, 68, 76, 147, 79, 56, 89, 137, 65, 13, 50, 0, 9, 67, 20, 148, 133, 140, 34, 13, 0, 0, 14, 69, 8, 21, 13, 4, 224, 71, 35, 47, 65, 35, 50, 0, 0, 15, 70, 76, 83, 129, 80, 244, 128, 89, 121, 50, 13, 47, 114, 0, 0, 10, 199, 64, 243, 25, 80, 129, 78, 20, 65, 0, 12, 68, 32, 243, 193, 32, 107, 6, 134, 6, 126, 0, 0, 14, 69, 8, 83, 143, 37, 64, 71, 121, 50, 58, 6, 126, 0, 12, 201, 53, 83, 20, 37, 3, 5, 96, 84, 128, 65, 13, 69, 4, 35, 1, 85, 64, 35, 71, 55, 135, 47, 0, 0, 16, 70, 8, 80, 193, 85, 49, 64, 71, 122, 49, 125, 88, 0, 66, 8, 0, 0, 0, 13, 5, 23, 5, 39, 12, 12, 58, 129, 55, 0, 72, 32, 14, 69, 20, 194, 67, 37, 64, 113, 55, 122, 89, 113, 47, 0, 0, 14, 70, 12, 129, 77, 37, 49, 64, 91, 13, 65, 129, 88, 0, 24, 66, 44, 208, 89, 49, 58, 4, 140, 49, 122, 55, 6, 124, 65, 122, 47, 114, 88, 0, 81, 194, 178, 32, 0, 19, 71, 9, 80, 200, 5, 33, 83, 80, 71, 134, 49, 119, 34, 6, 121, 89, 47, 0, 16, 70, 8, 20, 130, 21, 21, 69, 71, 127, 71, 13, 49, 57, 134, 0, 0, 11, 68, 52, 242, 82, 4, 65, 139, 34, 13, 0, 13, 68, 80, 22, 9, 76, 47, 35, 49, 89, 37, 88, 0, 12, 68, 24, 85, 21, 76, 83, 129, 47, 13, 89, 0, 0, 14, 69, 80, 18, 80, 20, 144, 47, 4, 137, 48, 6, 138, 0, 15, 69, 8, 146, 201, 56, 144, 71, 122, 49, 6, 129, 50, 37, 0, 0, 16, 70, 52, 147, 4, 72, 81, 0, 65, 122, 55, 72, 34, 113, 72, 0, 9, 198, 61, 85, 19, 44, 148, 148, 65, 16, 70, 8, 19, 145, 84, 85, 0, 71, 35, 68, 49, 58, 113, 47, 0, 0, 14, 70, 56, 244, 151, 36, 50, 0, 50, 124, 34, 113, 76, 0, 19, 71, 80, 83, 5, 52, 85, 18, 100, 47, 13, 55, 121, 65, 13, 47, 34, 37, 0, 19, 71, 33, 148, 5, 72, 35, 204, 20, 107, 137, 48, 6, 128, 71, 13, 55, 37, 0, 16, 70, 21, 2, 80, 32, 19, 153, 113, 48, 122, 83, 13, 50, 122, 0, 17, 71, 12, 132, 137, 77, 67, 65, 76, 49, 34, 122, 89, 65, 13, 89, 0, 0, 11, 67, 60, 227, 25, 136, 50, 55, 37, 0, 40, 12, 68, 16, 244, 137, 76, 72, 124, 34, 122, 89, 0, 15, 70, 13, 34, 67, 33, 67, 206, 49, 34, 137, 47, 13, 50, 0, 12, 68, 8, 244, 137, 76, 71, 124, 34, 122, 89, 0, 11, 68, 16, 128, 66, 36, 72, 126, 71, 37, 0, 11, 68, 69, 81, 83, 60, 49, 138, 89, 136, 0, 18, 72, 65, 33, 83, 12, 145, 78, 12, 80, 48, 34, 129, 89, 141, 50, 89, 0, 0, 13, 69, 24, 16, 201, 48, 80, 83, 35, 89, 118, 0, 103, 13, 69, 12, 80, 201, 48, 80, 89, 121, 89, 129, 55, 0, 8, 197, 85, 1, 1, 80, 80, 36, 9, 197, 85, 1, 1, 80, 80, 65, 10, 13, 69, 76, 81, 1, 80, 80, 89, 113, 72, 138, 47, 0, 15, 69, 12, 194, 67, 32, 80, 49, 55, 129, 91, 6, 138, 0, 103, 13, 69, 12, 194, 67, 32, 80, 49, 55, 129, 91, 138, 0, 0, 10, 66, 53, 144, 65, 137, 0, 72, 34, 12, 0, 10, 67, 77, 81, 84, 89, 134, 113, 47, 0, 19, 71, 65, 35, 205, 20, 224, 68, 20, 48, 34, 124, 65, 13, 50, 6, 126, 72, 0, 28, 75, 36, 225, 9, 76, 52, 137, 52, 147, 129, 80, 80, 122, 50, 72, 113, 89, 49, 34, 6, 122, 65, 113, 50, 13, 47, 0, 0, 18, 72, 93, 35, 206, 28, 67, 201, 56, 112, 34, 124, 68, 72, 134, 122, 68, 0, 0, 0, 15, 70, 80, 131, 213, 76, 19, 132, 87, 135, 88, 13, 50, 72, 0, 13, 202, 32, 84, 141, 5, 2, 18, 60, 66, 84, 20, 66, 16, 70, 12, 131, 210, 37, 163, 192, 76, 131, 34, 6, 129, 88, 136, 0, 15, 70, 8, 20, 212, 36, 243, 128, 71, 35, 89, 47, 141, 50, 0, 0, 15, 67, 61, 85, 0, 4, 135, 47, 13, 84, 0, 81, 111, 102, 32, 19, 71, 20, 66, 78, 9, 84, 135, 32, 121, 72, 122, 50, 71, 2, 125, 34, 13, 0, 18, 71, 21, 21, 73, 88, 240, 193, 48, 113, 49, 58, 122, 84, 13, 49, 118, 0, 0, 11, 68, 48, 84, 143, 100, 55, 129, 34, 139, 0, 0, 13, 69, 52, 245, 137, 21, 48, 65, 134, 84, 122, 88, 0, 0, 20, 66, 60, 96, 125, 84, 58, 122, 76, 0, 106, 66, 8, 81, 119, 104, 105, 99, 104, 32, 17, 66, 60, 96, 2, 125, 84, 86, 115, 0, 106, 34, 81, 116, 104, 101, 32, 16, 66, 60, 96, 3, 124, 84, 86, 115, 0, 34, 81, 116, 104, 101, 32, 19, 66, 60, 96, 124, 84, 58, 122, 76, 0, 66, 8, 81, 119, 104, 105, 99, 104, 32, 14, 66, 60, 96, 13, 84, 13, 50, 0, 34, 81, 97, 110, 32, 12, 66, 60, 96, 13, 84, 13, 0, 34, 81, 97, 32, 10, 66, 60, 96, 125, 84, 0, 106, 72, 9, 9, 66, 60, 96, 124, 84, 0, 72, 9, 14, 70, 76, 147, 194, 32, 19, 128, 91, 13, 84, 130, 50, 0, 14, 70, 8, 19, 12, 60, 243, 128, 71, 13, 55, 134, 50, 0, 16, 70, 4, 33, 15, 52, 83, 128, 35, 71, 72, 13, 65, 13, 50, 0, 0, 16, 70, 52, 243, 143, 80, 243, 133, 65, 124, 50, 13, 47, 136, 50, 0, 9, 67, 52, 144, 192, 65, 137, 49, 0, 17, 70, 24, 193, 88, 36, 35, 5, 83, 55, 121, 49, 89, 122, 71, 118, 0, 0, 9, 68, 92, 131, 210, 20, 107, 133, 0, 13, 68, 88, 242, 76, 4, 84, 58, 35, 55, 6, 35, 0, 11, 68, 88, 144, 193, 72, 84, 122, 49, 114, 0, 10, 67, 52, 144, 193, 65, 137, 49, 13, 0, 0, 16, 69, 44, 244, 133, 4, 224, 49, 114, 34, 6, 129, 13, 50, 0, 103, 15, 69, 44, 244, 133, 4, 224, 49, 131, 34, 6, 129, 13, 50, 0, 14, 69, 77, 84, 5, 72, 32, 89, 134, 48, 6, 128, 71, 0, 13, 69, 76, 80, 66, 20, 64, 89, 129, 71, 121, 72, 0, 0, 16, 70, 64, 16, 201, 24, 144, 192, 48, 119, 89, 122, 83, 122, 49, 0, 12, 201, 80, 129, 82, 52, 244, 212, 4, 35, 5, 20, 17, 70, 65, 148, 137, 80, 84, 192, 48, 137, 34, 6, 137, 47, 129, 88, 0, 14, 70, 48, 148, 85, 21, 84, 128, 55, 113, 49, 128, 0, 103, 14, 70, 48, 148, 85, 21, 84, 128, 55, 113, 49, 57, 143, 0, 0, 0, 22, 72, 12, 244, 5, 56, 128, 71, 20, 224, 49, 136, 48, 13, 50, 107, 6, 138, 81, 13, 50, 0, 10, 67, 52, 17, 201, 65, 138, 75, 137, 0, 0, 14, 69, 4, 198, 67, 20, 224, 35, 55, 122, 89, 13, 50, 0, 18, 70, 76, 19, 148, 36, 17, 207, 89, 35, 50, 47, 122, 6, 126, 81, 136, 0, 12, 69, 76, 48, 82, 20, 64, 89, 49, 140, 72, 0, 0, 28, 74, 36, 229, 133, 77, 66, 71, 5, 66, 86, 20, 122, 50, 84, 4, 121, 89, 47, 113, 81, 6, 138, 47, 122, 84, 0, 103, 15, 70, 28, 84, 129, 36, 229, 0, 81, 121, 34, 137, 50, 47, 0, 15, 70, 56, 20, 195, 20, 229, 0, 50, 138, 89, 13, 50, 47, 0, 15, 70, 8, 243, 138, 61, 84, 128, 71, 130, 50, 90, 6, 143, 0, 15, 70, 4, 116, 143, 84, 225, 0, 119, 81, 34, 135, 50, 72, 0, 0, 8, 67, 4, 33, 64, 138, 71, 0, 19, 71, 65, 33, 68, 20, 98, 78, 20, 48, 34, 129, 72, 113, 83, 6, 137, 50, 0, 17, 70, 36, 224, 210, 20, 20, 197, 122, 50, 49, 34, 6, 129, 89, 0, 36, 14, 70, 13, 33, 65, 81, 84, 133, 49, 34, 129, 76, 114, 0, 0, 13, 68, 92, 131, 211, 20, 4, 107, 134, 88, 0, 8, 9, 16, 7, 8, 1, 23, 1, 9, 39, 9, 107, 13, 58, 6, 137, 129, 0, 0, 14, 69, 16, 84, 197, 73, 64, 72, 113, 88, 128, 47, 0, 36, 14, 69, 16, 84, 197, 73, 64, 72, 121, 89, 114, 47, 0, 9, 13, 69, 16, 84, 197, 73, 64, 72, 113, 88, 128, 47, 0, 14, 69, 12, 243, 80, 5, 64, 49, 13, 65, 48, 35, 47, 0, 0, 15, 70, 77, 65, 82, 36, 193, 64, 89, 47, 121, 34, 118, 0, 103, 15, 70, 36, 211, 199, 20, 225, 64, 122, 65, 13, 75, 13, 50, 0, 15, 70, 28, 192, 83, 28, 245, 192, 81, 55, 120, 88, 81, 136, 0, 13, 70, 88, 82, 9, 12, 193, 64, 84, 141, 49, 118, 0, 18, 70, 84, 181, 76, 20, 193, 64, 57, 134, 49, 13, 55, 6, 138, 55, 37, 0, 15, 70, 77, 65, 82, 36, 193, 64, 89, 47, 121, 34, 137, 55, 0, 14, 70, 52, 244, 129, 36, 225, 64, 65, 13, 34, 138, 50, 0, 15, 70, 12, 240, 193, 36, 225, 64, 49, 136, 49, 6, 138, 50, 0, 0, 13, 67, 60, 225, 64, 58, 125, 50, 0, 106, 34, 10, 13, 12, 67, 60, 225, 64, 58, 124, 50, 0, 34, 10, 13, 16, 67, 20, 16, 200, 129, 76, 15, 13, 84, 0, 8, 81, 111, 102, 32, 14, 70, 60, 209, 76, 21, 69, 5, 124, 65, 55, 13, 47, 0, 10, 67, 4, 33, 68, 119, 71, 121, 72, 0, 6, 195, 60, 209, 192, 17, 0, 0, 14, 69, 17, 34, 69, 77, 64, 72, 34, 137, 13, 89, 47, 0, 0, 16, 70, 12, 243, 82, 4, 65, 64, 49, 124, 65, 34, 35, 72, 0, 103, 13, 67, 60, 229, 15, 4, 124, 50, 108, 117, 0, 103, 12, 12, 67, 60, 229, 15, 4, 124, 50, 47, 117, 0, 12, 14, 70, 28, 84, 136, 5, 33, 0, 81, 140, 107, 127, 47, 0, 16, 70, 77, 3, 203, 4, 225, 64, 89, 48, 136, 49, 6, 35, 50, 0, 15, 70, 92, 19, 142, 4, 33, 64, 58, 124, 50, 119, 71, 129, 0, 15, 70, 32, 84, 143, 36, 225, 64, 107, 121, 34, 136, 122, 50, 0, 15, 70, 29, 33, 78, 4, 65, 64, 81, 34, 13, 50, 138, 72, 0, 9, 198, 4, 229, 9, 48, 241, 192, 65, 0, 20, 71, 76, 147, 131, 21, 33, 83, 80, 89, 122, 50, 89, 6, 141, 34, 13, 89, 47, 0, 15, 70, 4, 229, 9, 60, 50, 0, 35, 50, 108, 129, 124, 49, 0, 0, 12, 68, 80, 129, 73, 72, 86, 140, 0, 72, 34, 9, 11, 67, 52, 18, 197, 65, 4, 138, 49, 0, 12, 12, 67, 52, 18, 197, 65, 4, 138, 49, 0, 12, 9, 12, 68, 64, 80, 193, 56, 48, 129, 49, 13, 50, 0, 11, 68, 12, 145, 193, 72, 89, 113, 81, 127, 0, 8, 4, 95, 35, 18, 4, 72, 0, 0, 14, 69, 25, 85, 9, 48, 80, 83, 57, 134, 47, 118, 0, 103, 12, 69, 80, 129, 78, 12, 80, 86, 121, 50, 89, 0, 13, 69, 44, 20, 133, 56, 80, 49, 119, 34, 129, 50, 0, 8, 197, 4, 208, 78, 16, 16, 66, 14, 69, 32, 20, 129, 72, 80, 107, 119, 34, 126, 34, 37, 0, 14, 69, 85, 48, 66, 48, 80, 57, 134, 88, 13, 71, 118, 0, 13, 69, 76, 84, 133, 56, 80, 89, 13, 34, 129, 50, 0, 13, 69, 12, 20, 129, 24, 80, 49, 119, 34, 35, 83, 0, 9, 67, 4, 160, 82, 119, 75, 127, 0, 0, 0, 10, 67, 36, 34, 68, 122, 71, 123, 72, 0, 0, 12, 68, 4, 192, 78, 4, 119, 55, 35, 50, 13, 0, 12, 68, 48, 17, 207, 76, 55, 138, 81, 124, 89, 0, 12, 68, 76, 48, 76, 16, 89, 49, 124, 55, 72, 0, 0, 15, 70, 5, 34, 193, 57, 48, 83, 127, 49, 13, 50, 89, 130, 0, 13, 69, 84, 228, 213, 72, 80, 125, 50, 91, 6, 143, 0, 14, 69, 76, 81, 21, 12, 80, 89, 113, 72, 57, 134, 89, 0, 14, 69, 28, 83, 73, 56, 144, 75, 121, 65, 113, 50, 137, 0, 0, 11, 5, 23, 5, 39, 18, 5, 2, 58, 142, 0, 17, 70, 65, 83, 138, 4, 34, 64, 48, 125, 50, 75, 6, 126, 71, 37, 0, 20, 70, 37, 53, 1, 56, 37, 76, 4, 122, 89, 47, 4, 35, 50, 71, 6, 117, 55, 0, 17, 70, 76, 21, 1, 56, 148, 212, 89, 138, 47, 13, 50, 122, 89, 47, 0, 5, 194, 57, 144, 17, 0, 13, 6, 25, 15, 21, 39, 18, 5, 2, 57, 143, 0, 106, 12, 6, 25, 15, 21, 39, 18, 5, 2, 57, 132, 0, 9, 67, 65, 81, 0, 48, 117, 72, 0, 6, 195, 36, 35, 64, 17, 0, 12, 68, 8, 85, 19, 100, 71, 121, 47, 89, 37, 0, 21, 72, 77, 67, 206, 20, 129, 78, 28, 80, 89, 47, 4, 136, 50, 107, 6, 121, 50, 75, 0, 13, 68, 60, 209, 71, 4, 136, 65, 6, 138, 81, 13, 0, 14, 70, 4, 148, 144, 61, 113, 82, 6, 140, 48, 4, 146, 0, 0, 15, 69, 84, 229, 9, 17, 144, 125, 50, 47, 6, 137, 72, 37, 0, 13, 69, 65, 33, 84, 81, 144, 48, 34, 122, 47, 37, 0, 0, 15, 70, 104, 130, 86, 4, 115, 192, 90, 113, 84, 126, 81, 136, 0, 19, 4, 95, 3, 9, 18, 89, 6, 128, 49, 125, 65, 83, 55, 4, 121, 49, 89, 0, 0, 14, 7, 20, 8, 5, 18, 5, 39, 4, 2, 86, 140, 72, 0, 12, 67, 65, 85, 0, 4, 48, 117, 47, 0, 10, 12, 11, 67, 4, 160, 88, 138, 75, 35, 49, 89, 0, 10, 67, 4, 33, 84, 119, 71, 121, 47, 0, 6, 195, 57, 149, 0, 17, 6, 195, 12, 83, 192, 17, 0, 16, 70, 12, 132, 153, 76, 193, 82, 49, 34, 137, 89, 55, 114, 0, 103, 15, 70, 12, 132, 153, 76, 193, 82, 49, 34, 137, 88, 55, 114, 0, 11, 68, 80, 146, 203, 4, 47, 129, 49, 13, 0, 12, 68, 48, 147, 73, 80, 55, 122, 65, 113, 47, 0, 9, 198, 24, 244, 133, 92, 20, 142, 66, 9, 67, 20, 32, 89, 129, 71, 138, 0, 0, 14, 69, 72, 20, 137, 81, 144, 34, 140, 34, 13, 47, 37, 0, 0, 14, 6, 25, 15, 21, 39, 12, 12, 57, 134, 55, 0, 72, 32, 15, 70, 52, 19, 3, 60, 195, 64, 65, 35, 55, 49, 13, 65, 0, 15, 70, 65, 35, 206, 61, 83, 128, 48, 34, 136, 50, 135, 50, 0, 13, 3, 95, 194, 183, 65, 122, 72, 118, 72, 124, 47, 0, 0, 12, 67, 61, 84, 128, 135, 114, 0, 103, 72, 34, 9, 10, 67, 61, 84, 128, 146, 0, 72, 34, 9, 15, 71, 80, 19, 201, 76, 80, 67, 32, 47, 129, 91, 13, 101, 0, 9, 198, 52, 17, 193, 104, 147, 133, 67, 16, 71, 12, 243, 77, 37, 69, 5, 20, 49, 13, 65, 122, 47, 37, 0, 17, 3, 95, 194, 180, 119, 49, 57, 134, 47, 35, 49, 89, 121, 50, 47, 0, 0, 12, 68, 60, 208, 72, 4, 136, 65, 119, 107, 126, 0, 13, 68, 44, 240, 76, 4, 49, 136, 6, 126, 55, 13, 0, 19, 72, 4, 195, 8, 4, 195, 15, 93, 48, 130, 55, 107, 6, 35, 55, 136, 88, 0, 0, 14, 69, 80, 82, 18, 4, 224, 47, 140, 34, 6, 126, 50, 0, 13, 69, 48, 84, 201, 60, 224, 55, 129, 90, 13, 50, 0, 12, 69, 12, 83, 9, 16, 128, 49, 138, 55, 37, 0, 19, 3, 95, 194, 178, 89, 134, 48, 13, 89, 49, 34, 122, 48, 47, 47, 6, 134, 0, 0, 9, 67, 72, 134, 83, 34, 129, 89, 0, 17, 70, 4, 193, 129, 48, 96, 64, 35, 55, 83, 6, 35, 55, 83, 13, 0, 20, 3, 95, 194, 179, 89, 134, 48, 13, 89, 49, 34, 122, 48, 47, 87, 6, 34, 129, 0, 0, 20, 71, 4, 225, 18, 60, 209, 68, 4, 35, 50, 72, 34, 6, 124, 65, 122, 72, 13, 0, 16, 71, 12, 21, 8, 21, 34, 78, 20, 49, 35, 87, 34, 113, 50, 0, 19, 71, 65, 33, 67, 20, 65, 78, 80, 48, 34, 121, 89, 113, 72, 13, 50, 47, 0, 0, 11, 67, 40, 244, 197, 107, 136, 89, 6, 138, 0, 11, 200, 84, 225, 5, 73, 115, 210, 48, 64, 65, 0, 14, 69, 61, 33, 71, 60, 224, 124, 34, 113, 81, 13, 50, 0, 12, 69, 92, 148, 146, 4, 192, 58, 122, 34, 118, 0, 14, 69, 76, 16, 210, 20, 64, 89, 138, 49, 34, 13, 72, 0, 9, 197, 36, 229, 5, 72, 224, 65, 10, 14, 69, 36, 229, 5, 72, 224, 122, 50, 47, 128, 50, 0, 37, 13, 69, 12, 20, 144, 20, 192, 49, 127, 48, 13, 55, 0, 14, 69, 9, 33, 65, 80, 128, 71, 34, 129, 86, 0, 36, 10, 13, 69, 9, 33, 65, 80, 128, 71, 34, 121, 87, 0, 10, 0, 0, 19, 4, 8, 5, 39, 19, 107, 129, 88, 107, 35, 72, 0, 78, 81, 104, 97, 100, 32, 12, 4, 8, 5, 39, 19, 107, 129, 88, 0, 72, 35, 9, 67, 4, 37, 64, 35, 71, 134, 0, 9, 67, 72, 245, 192, 34, 135, 0, 37, 8, 67, 72, 245, 192, 34, 136, 0, 21, 71, 36, 225, 197, 57, 82, 84, 100, 122, 50, 75, 113, 50, 6, 57, 134, 113, 47, 37, 0, 9, 67, 8, 245, 192, 71, 135, 0, 36, 8, 67, 8, 245, 192, 71, 136, 0, 13, 4, 95, 19, 20, 11, 89, 47, 34, 6, 136, 49, 0, 0, 14, 68, 80, 131, 211, 20, 86, 136, 88, 0, 72, 34, 12, 9, 9, 4, 95, 35, 19, 20, 89, 47, 0, 12, 3, 95, 194, 173, 65, 35, 49, 34, 124, 50, 0, 11, 4, 95, 3, 18, 12, 49, 6, 128, 55, 0, 0, 14, 69, 16, 81, 133, 13, 64, 72, 129, 83, 121, 49, 47, 0, 19, 3, 95, 194, 170, 83, 121, 65, 113, 50, 122, 50, 6, 132, 72, 113, 50, 118, 0, 13, 4, 95, 1, 3, 21, 119, 49, 57, 6, 134, 47, 0, 0, 15, 70, 13, 66, 21, 48, 133, 64, 49, 14, 87, 134, 105, 134, 0, 14, 70, 93, 33, 84, 12, 129, 68, 34, 121, 76, 123, 72, 0, 15, 70, 76, 84, 85, 36, 225, 64, 89, 129, 49, 58, 113, 50, 0, 18, 70, 76, 80, 207, 56, 65, 68, 89, 121, 49, 6, 124, 50, 72, 123, 72, 0, 15, 70, 65, 84, 144, 61, 37, 0, 48, 128, 48, 6, 133, 47, 0, 16, 70, 28, 83, 149, 36, 225, 64, 75, 121, 50, 57, 134, 123, 50, 0, 18, 3, 95, 194, 171, 55, 121, 83, 47, 6, 81, 122, 55, 13, 65, 121, 47, 0, 0, 10, 67, 56, 245, 192, 50, 135, 0, 32, 42, 6, 195, 56, 245, 192, 32, 9, 67, 16, 69, 64, 86, 122, 0, 9, 15, 3, 95, 194, 168, 72, 137, 119, 34, 6, 129, 89, 122, 89, 0, 0, 10, 67, 77, 86, 153, 89, 134, 88, 37, 0, 13, 68, 81, 83, 9, 64, 47, 57, 134, 55, 122, 48, 0, 11, 68, 48, 192, 77, 4, 55, 126, 65, 13, 0, 8, 4, 95, 35, 20, 8, 87, 0, 0, 15, 3, 95, 194, 166, 71, 34, 136, 49, 13, 50, 71, 6, 127, 0, 0, 13, 202, 88, 83, 148, 72, 147, 15, 69, 82, 83, 80, 66, 16, 70, 65, 33, 76, 84, 65, 64, 48, 34, 138, 55, 134, 72, 0, 103, 16, 70, 65, 33, 76, 84, 65, 64, 48, 34, 121, 55, 57, 134, 72, 0, 0, 18, 71, 65, 34, 86, 36, 193, 71, 20, 48, 34, 122, 84, 113, 55, 113, 75, 0, 0, 12, 68, 64, 17, 193, 56, 48, 138, 81, 13, 50, 0, 11, 68, 48, 80, 70, 100, 55, 129, 83, 37, 0, 0, 16, 70, 77, 66, 76, 21, 69, 15, 89, 47, 113, 55, 121, 47, 136, 0, 13, 69, 52, 147, 137, 56, 112, 65, 137, 50, 122, 68, 0, 13, 69, 24, 244, 129, 28, 80, 83, 124, 34, 113, 75, 0, 0, 15, 70, 80, 84, 141, 36, 226, 64, 47, 128, 65, 122, 50, 137, 0, 16, 70, 77, 64, 78, 16, 38, 64, 89, 47, 35, 50, 72, 71, 137, 0, 0, 13, 3, 95, 194, 160, 107, 127, 72, 89, 48, 138, 89, 0, 12, 4, 95, 18, 14, 7, 34, 6, 122, 68, 81, 0, 0, 18, 72, 44, 19, 7, 60, 244, 140, 36, 80, 49, 35, 55, 81, 143, 55, 37, 0, 10, 68, 56, 144, 200, 20, 50, 129, 91, 0, 17, 72, 8, 245, 82, 28, 83, 201, 76, 80, 71, 143, 90, 58, 126, 88, 0, 27, 3, 95, 194, 161, 2, 122, 50, 84, 4, 128, 47, 113, 72, 121, 49, 89, 49, 55, 13, 65, 6, 138, 91, 13, 50, 0, 0, 19, 8, 16, 18, 15, 20, 5, 7, 195, 169, 112, 114, 111, 116, 101, 103, 101, 0, 29, 8, 197, 61, 85, 9, 56, 112, 65, 13, 69, 24, 83, 9, 56, 80, 83, 129, 55, 137, 50, 0, 12, 69, 13, 80, 203, 60, 240, 49, 117, 49, 134, 0, 0, 20, 5, 23, 5, 39, 22, 5, 58, 129, 84, 107, 35, 72, 0, 78, 81, 104, 97, 100, 32, 13, 5, 23, 5, 39, 22, 5, 58, 129, 84, 0, 72, 35, 15, 70, 16, 244, 143, 80, 134, 64, 72, 124, 34, 13, 87, 37, 0, 15, 70, 4, 229, 8, 60, 230, 64, 35, 50, 47, 13, 50, 37, 0, 17, 70, 9, 84, 149, 56, 66, 64, 71, 117, 34, 6, 117, 50, 72, 37, 0, 20, 9, 16, 18, 15, 20, 195, 169, 7, 195, 169, 112, 114, 111, 116, 101, 103, 101, 0, 29, 0, 21, 6, 25, 15, 21, 39, 22, 5, 57, 134, 84, 107, 35, 72, 0, 78, 81, 104, 97, 100, 32, 14, 6, 25, 15, 21, 39, 22, 5, 57, 134, 84, 0, 72, 35, 9, 67, 72, 134, 76, 34, 122, 55, 0, 14, 70, 92, 130, 84, 37, 50, 0, 58, 137, 47, 122, 91, 0, 17, 71, 52, 245, 83, 80, 16, 200, 20, 65, 13, 89, 47, 6, 120, 91, 0, 18, 71, 8, 16, 203, 77, 67, 210, 100, 71, 35, 49, 89, 47, 133, 34, 37, 0, 21, 67, 33, 69, 16, 138, 76, 108, 129, 108, 129, 6, 48, 129, 10, 0, 81, 58, 47, 47, 32, 0, 17, 70, 80, 241, 197, 80, 129, 82, 47, 13, 81, 121, 86, 114, 0, 74, 12, 11, 68, 4, 129, 65, 16, 119, 107, 121, 72, 0, 11, 68, 96, 131, 211, 4, 49, 130, 89, 13, 0, 13, 68, 17, 145, 133, 16, 72, 6, 125, 84, 122, 72, 0, 20, 72, 12, 243, 80, 72, 243, 73, 76, 80, 49, 124, 65, 48, 34, 13, 65, 137, 88, 0, 11, 200, 12, 130, 77, 64, 19, 154, 20, 80, 67, 0, 14, 69, 76, 144, 201, 49, 144, 89, 122, 89, 113, 55, 37, 0, 13, 69, 72, 80, 197, 77, 48, 34, 129, 89, 121, 89, 0, 22, 73, 64, 131, 212, 60, 116, 129, 64, 134, 64, 83, 13, 47, 6, 124, 81, 34, 13, 83, 37, 0, 14, 69, 13, 34, 83, 21, 48, 49, 34, 137, 89, 129, 88, 0, 15, 69, 72, 148, 195, 61, 48, 34, 122, 89, 49, 136, 121, 89, 0, 0, 13, 67, 60, 225, 83, 58, 125, 50, 88, 0, 106, 9, 13, 12, 67, 60, 225, 83, 58, 124, 50, 88, 0, 9, 13, 17, 70, 72, 244, 193, 72, 147, 192, 34, 136, 88, 6, 127, 34, 122, 136, 0, 17, 70, 28, 19, 9, 48, 83, 192, 81, 35, 55, 113, 55, 6, 138, 136, 0, 0, 0, 22, 72, 84, 226, 86, 21, 36, 201, 81, 144, 57, 134, 50, 122, 84, 6, 128, 89, 113, 47, 37, 0, 14, 68, 72, 83, 73, 80, 34, 129, 65, 6, 122, 47, 0, 36, 12, 68, 72, 83, 73, 80, 34, 129, 65, 122, 47, 0, 11, 68, 12, 128, 78, 28, 76, 35, 68, 0, 10, 11, 68, 12, 128, 78, 28, 76, 138, 50, 75, 0, 0, 15, 69, 84, 37, 78, 81, 80, 134, 71, 6, 134, 50, 108, 134, 0, 15, 70, 72, 241, 5, 72, 144, 203, 34, 124, 72, 34, 122, 49, 0, 10, 67, 5, 32, 66, 35, 34, 13, 71, 0, 0, 10, 198, 12, 243, 80, 61, 83, 132, 66, 36, 5, 194, 72, 64, 9, 0, 22, 73, 64, 131, 212, 60, 116, 129, 64, 129, 82, 83, 13, 47, 6, 124, 81, 34, 13, 83, 13, 0, 0, 10, 68, 76, 243, 212, 32, 89, 134, 86, 0, 11, 68, 48, 17, 197, 72, 55, 126, 81, 114, 0, 0, 14, 69, 81, 35, 202, 4, 224, 47, 34, 136, 75, 13, 50, 0, 0, 15, 70, 92, 144, 200, 37, 64, 64, 58, 122, 76, 113, 47, 127, 0, 9, 198, 20, 225, 137, 20, 193, 0, 65, 0, 17, 70, 20, 229, 133, 48, 244, 5, 126, 50, 84, 13, 55, 136, 48, 0, 103, 10, 199, 81, 32, 78, 77, 3, 210, 80, 36, 19, 71, 81, 32, 78, 77, 3, 210, 80, 47, 34, 35, 50, 89, 48, 133, 47, 0, 9, 20, 71, 80, 20, 129, 57, 69, 76, 4, 47, 13, 34, 35, 50, 47, 57, 117, 55, 13, 0, 9, 198, 20, 229, 133, 48, 244, 5, 36, 17, 70, 20, 229, 133, 48, 244, 5, 121, 50, 84, 13, 55, 136, 48, 0, 9, 15, 70, 13, 33, 86, 5, 52, 197, 49, 34, 13, 84, 35, 89, 0, 16, 71, 5, 80, 133, 72, 114, 78, 20, 136, 71, 114, 90, 129, 50, 0, 0, 11, 68, 80, 130, 78, 20, 4, 86, 137, 50, 0, 12, 68, 88, 81, 193, 76, 84, 138, 81, 13, 89, 0, 12, 68, 48, 83, 206, 20, 55, 129, 6, 136, 50, 0, 10, 68, 64, 147, 213, 76, 48, 144, 89, 0, 11, 68, 60, 49, 65, 56, 136, 91, 13, 50, 0, 0, 16, 70, 77, 148, 8, 36, 194, 83, 89, 122, 83, 13, 55, 123, 89, 0, 13, 69, 24, 20, 212, 20, 224, 83, 120, 89, 13, 50, 0, 0, 15, 70, 8, 20, 130, 5, 32, 64, 71, 127, 71, 13, 34, 13, 0, 0, 10, 67, 5, 33, 64, 2, 127, 0, 35, 9, 11, 67, 85, 32, 76, 57, 134, 13, 34, 118, 0, 21, 71, 64, 83, 137, 57, 53, 76, 4, 48, 13, 50, 6, 122, 50, 89, 57, 117, 55, 13, 0, 9, 198, 61, 85, 8, 61, 84, 197, 65, 0, 13, 68, 52, 144, 77, 36, 65, 137, 6, 35, 65, 37, 0, 13, 68, 64, 144, 78, 60, 48, 122, 6, 35, 50, 136, 0, 0, 30, 5, 3, 1, 14, 39, 20, 4, 49, 35, 50, 47, 6, 35, 84, 47, 116, 0, 103, 32, 14, 82, 104, 97, 118, 101, 32, 116, 111, 32, 22, 5, 3, 1, 14, 39, 20, 49, 35, 50, 47, 119, 84, 0, 103, 35, 81, 104, 97, 118, 101, 32, 16, 5, 3, 1, 14, 39, 20, 49, 35, 50, 47, 0, 103, 32, 9, 12, 29, 5, 3, 1, 14, 39, 20, 4, 49, 126, 50, 47, 6, 35, 84, 47, 116, 0, 32, 14, 82, 104, 97, 118, 101, 32, 116, 111, 32, 21, 5, 3, 1, 14, 39, 20, 49, 126, 50, 47, 119, 84, 0, 35, 81, 104, 97, 118, 101, 32, 15, 5, 3, 1, 14, 39, 20, 49, 126, 50, 47, 0, 32, 9, 12, 24, 73, 4, 36, 129, 12, 17, 1, 9, 32, 64, 35, 71, 34, 13, 49, 13, 72, 6, 35, 71, 34, 13, 0, 0, 17, 70, 56, 18, 86, 21, 65, 64, 50, 137, 6, 129, 84, 13, 47, 138, 0, 9, 198, 12, 243, 131, 21, 37, 0, 36, 16, 70, 12, 243, 131, 21, 37, 0, 49, 124, 50, 89, 114, 47, 0, 10, 18, 70, 12, 243, 80, 21, 65, 68, 49, 13, 65, 48, 6, 129, 47, 122, 72, 0, 14, 202, 4, 69, 133, 73, 66, 83, 20, 209, 78, 80, 103, 67, 24, 74, 4, 69, 133, 73, 66, 83, 20, 209, 78, 80, 119, 72, 84, 128, 47, 122, 89, 65, 13, 50, 47, 0, 18, 4, 95, 1, 3, 50, 72, 125, 71, 13, 55, 119, 49, 57, 6, 134, 47, 0, 0, 17, 70, 80, 83, 80, 48, 21, 5, 47, 121, 65, 48, 55, 13, 47, 0, 103, 18, 67, 77, 80, 200, 89, 125, 76, 15, 10, 119, 88, 0, 8, 81, 97, 115, 32, 16, 70, 60, 36, 207, 48, 85, 5, 124, 71, 89, 13, 55, 129, 47, 0, 8, 67, 21, 33, 64, 140, 0, 9, 0, 19, 72, 4, 208, 129, 77, 48, 68, 61, 32, 119, 65, 71, 35, 89, 13, 72, 114, 0, 0, 16, 5, 9, 19, 14, 39, 20, 4, 122, 88, 13, 50, 47, 0, 35, 12, 13, 69, 52, 19, 135, 21, 32, 65, 138, 50, 75, 114, 0, 10, 4, 4, 39, 25, 5, 72, 57, 13, 0, 13, 69, 17, 81, 207, 85, 64, 72, 125, 81, 135, 47, 0, 0, 16, 6, 8, 1, 19, 14, 39, 20, 107, 35, 88, 13, 50, 47, 0, 35, 16, 70, 93, 148, 201, 93, 145, 192, 58, 122, 88, 129, 58, 122, 81, 0, 9, 66, 72, 80, 34, 4, 129, 0, 9, 14, 70, 8, 150, 154, 5, 33, 64, 71, 122, 88, 6, 127, 0, 5, 194, 60, 176, 17, 0, 17, 70, 12, 243, 148, 72, 149, 5, 49, 124, 50, 47, 34, 6, 137, 47, 0, 16, 70, 4, 225, 67, 16, 245, 5, 35, 50, 122, 49, 72, 136, 47, 0, 0, 14, 68, 76, 128, 76, 48, 4, 91, 35, 55, 0, 32, 9, 12, 12, 68, 72, 83, 85, 76, 34, 129, 65, 13, 89, 0, 13, 70, 72, 16, 200, 4, 83, 0, 34, 138, 76, 118, 0, 9, 67, 21, 34, 69, 141, 34, 37, 0, 12, 68, 105, 83, 21, 76, 88, 134, 55, 134, 88, 0, 17, 70, 64, 80, 213, 48, 144, 82, 48, 113, 49, 57, 134, 55, 122, 114, 0, 11, 68, 16, 80, 207, 72, 72, 138, 49, 132, 0, 0, 14, 69, 88, 145, 78, 56, 16, 84, 122, 6, 121, 50, 13, 0, 15, 69, 72, 144, 133, 56, 16, 34, 137, 71, 6, 129, 50, 13, 0, 13, 69, 16, 244, 193, 28, 80, 72, 136, 89, 113, 75, 0, 0, 0, 18, 71, 12, 20, 137, 8, 33, 65, 56, 49, 35, 34, 13, 71, 6, 141, 50, 0, 16, 71, 92, 82, 18, 52, 16, 200, 80, 84, 140, 65, 35, 101, 47, 0, 17, 71, 12, 244, 144, 61, 32, 84, 20, 49, 132, 48, 13, 34, 13, 47, 0, 17, 71, 5, 96, 76, 4, 224, 200, 20, 35, 84, 13, 55, 120, 50, 91, 0, 0, 13, 68, 92, 130, 76, 20, 58, 4, 137, 55, 0, 8, 11, 13, 6, 5, 9, 14, 195, 173, 14, 121, 50, 129, 50, 0, 13, 68, 77, 81, 1, 56, 89, 134, 72, 6, 35, 50, 0, 12, 68, 4, 192, 77, 60, 35, 55, 13, 65, 136, 0, 11, 68, 4, 48, 210, 4, 35, 49, 34, 119, 0, 11, 200, 76, 83, 73, 12, 148, 131, 48, 80, 65, 11, 67, 32, 82, 5, 107, 129, 107, 6, 129, 0, 16, 70, 9, 33, 84, 33, 33, 78, 71, 34, 121, 86, 34, 13, 50, 0, 0, 13, 69, 77, 83, 132, 4, 80, 89, 125, 50, 72, 138, 0, 0, 10, 67, 5, 33, 83, 140, 34, 129, 88, 0, 16, 70, 64, 192, 89, 80, 84, 212, 48, 55, 138, 47, 121, 89, 47, 0, 23, 3, 95, 194, 191, 2, 122, 50, 84, 4, 128, 47, 113, 72, 49, 58, 6, 121, 89, 76, 13, 50, 0, 0, 17, 71, 64, 147, 133, 5, 4, 12, 20, 48, 6, 137, 50, 35, 48, 118, 0, 11, 4, 95, 56, 48, 15, 6, 138, 47, 141, 0, 0, 10, 68, 76, 83, 213, 48, 89, 136, 55, 0, 18, 72, 24, 243, 11, 21, 53, 15, 56, 80, 83, 136, 49, 89, 47, 136, 50, 0, 11, 68, 72, 81, 193, 48, 34, 129, 81, 118, 0, 0, 13, 69, 72, 84, 12, 5, 144, 34, 129, 48, 55, 138, 0, 17, 70, 16, 144, 66, 21, 65, 83, 72, 144, 71, 6, 129, 47, 129, 88, 0, 13, 69, 12, 243, 69, 49, 144, 49, 125, 65, 55, 122, 0, 13, 3, 95, 194, 186, 72, 113, 81, 34, 6, 129, 88, 0, 0, 10, 67, 64, 197, 83, 48, 55, 125, 89, 0, 17, 3, 95, 194, 187, 34, 137, 47, 6, 81, 122, 55, 13, 65, 121, 47, 0, 0, 14, 70, 12, 129, 89, 20, 227, 133, 91, 137, 6, 35, 50, 0, 20, 71, 16, 148, 12, 60, 208, 67, 100, 72, 122, 48, 55, 6, 136, 65, 13, 89, 37, 0, 13, 3, 95, 194, 184, 89, 121, 72, 6, 122, 55, 13, 0, 0, 11, 200, 72, 145, 9, 13, 83, 15, 85, 48, 66, 11, 68, 4, 225, 197, 48, 138, 50, 75, 118, 0, 6, 195, 84, 51, 1, 17, 20, 3, 95, 194, 185, 89, 134, 48, 13, 89, 49, 34, 122, 48, 47, 58, 6, 124, 50, 0, 0, 12, 67, 32, 212, 6, 107, 6, 13, 65, 48, 83, 0, 13, 69, 4, 197, 193, 101, 48, 130, 55, 58, 138, 88, 0, 0, 16, 70, 92, 149, 8, 61, 85, 0, 58, 122, 86, 135, 47, 0, 74, 12, 9, 198, 92, 149, 8, 61, 85, 0, 66, 10, 67, 37, 34, 83, 137, 34, 122, 89, 0, 10, 67, 28, 245, 15, 81, 136, 47, 134, 0, 10, 67, 56, 21, 15, 50, 138, 47, 136, 0, 0, 16, 71, 76, 243, 69, 80, 130, 78, 28, 89, 125, 65, 87, 122, 68, 0, 0, 10, 67, 77, 84, 197, 89, 134, 89, 13, 0, 12, 68, 76, 48, 76, 100, 89, 49, 138, 55, 122, 0, 0, 13, 69, 76, 243, 5, 52, 224, 89, 124, 55, 13, 65, 0, 14, 69, 53, 148, 137, 4, 64, 65, 122, 34, 122, 35, 72, 0, 0, 9, 198, 40, 18, 193, 73, 64, 64, 66, 14, 70, 80, 243, 137, 28, 133, 0, 47, 13, 50, 137, 47, 0, 13, 70, 52, 20, 147, 32, 19, 12, 65, 127, 91, 118, 0, 0, 15, 70, 80, 245, 76, 61, 84, 197, 47, 134, 55, 6, 134, 88, 0, 0, 13, 68, 88, 147, 204, 4, 84, 137, 6, 136, 55, 13, 0, 10, 67, 16, 83, 9, 72, 121, 55, 122, 0, 12, 68, 12, 16, 212, 36, 49, 35, 49, 47, 137, 0, 11, 68, 4, 112, 73, 56, 119, 81, 121, 50, 0, 0, 18, 70, 5, 67, 1, 57, 66, 83, 35, 47, 55, 6, 35, 50, 47, 122, 89, 0, 9, 2, 195, 151, 47, 137, 65, 88, 0, 0, 15, 70, 4, 197, 8, 61, 81, 200, 131, 55, 86, 6, 136, 0, 8, 5, 194, 77, 64, 24, 5, 194, 77, 64, 9, 9, 66, 77, 64, 89, 13, 50, 47, 0, 0, 20, 71, 92, 148, 195, 60, 228, 201, 56, 58, 113, 89, 49, 6, 124, 50, 89, 113, 50, 0, 18, 71, 52, 148, 195, 72, 80, 78, 80, 65, 122, 89, 49, 34, 141, 50, 47, 0, 16, 4, 95, 19, 13, 3, 89, 65, 6, 130, 55, 49, 4, 35, 48, 0, 5, 130, 196, 141, 43, 0, 20, 72, 5, 35, 65, 28, 81, 4, 60, 224, 127, 65, 119, 81, 6, 121, 72, 13, 50, 0, 9, 67, 4, 50, 25, 138, 49, 37, 0, 0, 12, 197, 12, 19, 142, 61, 64, 103, 66, 32, 9, 12, 15, 69, 48, 244, 133, 57, 160, 55, 124, 34, 13, 50, 47, 89, 0, 15, 69, 12, 21, 133, 5, 64, 49, 35, 84, 122, 126, 47, 0, 103, 14, 69, 12, 21, 133, 5, 64, 49, 35, 84, 122, 35, 47, 0, 0, 16, 70, 72, 84, 208, 37, 65, 64, 34, 121, 89, 48, 113, 47, 0, 103, 15, 70, 72, 148, 15, 77, 65, 64, 34, 113, 48, 124, 89, 47, 0, 15, 70, 72, 84, 208, 37, 65, 64, 34, 121, 89, 48, 137, 47, 0, 15, 70, 36, 228, 208, 37, 33, 64, 122, 50, 89, 48, 6, 145, 0, 16, 70, 20, 229, 5, 57, 65, 64, 124, 50, 47, 6, 124, 50, 47, 0, 17, 70, 12, 83, 5, 9, 33, 64, 89, 121, 55, 6, 121, 71, 34, 13, 0, 0, 16, 70, 8, 83, 133, 5, 66, 0, 71, 113, 50, 129, 87, 0, 74, 12, 15, 70, 4, 65, 76, 4, 145, 5, 35, 72, 13, 55, 138, 72, 0, 9, 198, 48, 83, 79, 56, 17, 5, 67, 0, 11, 68, 4, 194, 67, 20, 35, 55, 122, 89, 0, 12, 68, 8, 192, 83, 20, 71, 55, 126, 88, 138, 0, 0, 13, 5, 4, 15, 14, 39, 20, 72, 136, 50, 47, 0, 32, 8, 197, 61, 85, 19, 21, 64, 65, 13, 69, 52, 148, 212, 21, 32, 65, 122, 89, 47, 114, 0, 21, 73, 25, 84, 148, 32, 84, 141, 61, 33, 64, 83, 148, 86, 114, 65, 6, 133, 0, 105, 8, 20, 73, 25, 84, 148, 32, 84, 141, 61, 33, 64, 83, 128, 86, 114, 65, 6, 133, 0, 8, 12, 2, 195, 159, 91, 4, 127, 48, 6, 121, 89, 0, 11, 2, 194, 167, 89, 121, 49, 91, 13, 50, 0, 0, 17, 66, 56, 240, 50, 6, 136, 4, 65, 133, 0, 81, 109, 111, 114, 101, 32, 23, 66, 56, 240, 50, 4, 136, 15, 55, 6, 124, 68, 81, 114, 0, 81, 108, 111, 110, 103, 101, 114, 32, 18, 66, 56, 240, 6, 50, 136, 6, 58, 125, 50, 0, 106, 81, 111, 110, 101, 32, 17, 66, 56, 240, 6, 50, 136, 6, 58, 124, 50, 0, 81, 111, 110, 101, 32, 9, 198, 8, 243, 66, 5, 33, 0, 66, 8, 66, 56, 240, 50, 136, 0, 42, 15, 2, 194, 164, 49, 125, 34, 13, 50, 89, 122, 89, 137, 50, 0, 0, 15, 67, 16, 84, 20, 72, 113, 48, 127, 47, 65, 13, 50, 47, 0, 8, 2, 194, 165, 57, 121, 50, 0, 0, 14, 68, 76, 128, 76, 80, 4, 91, 35, 55, 47, 0, 32, 9, 10, 67, 76, 86, 0, 89, 121, 49, 89, 0, 11, 68, 4, 112, 80, 20, 119, 81, 138, 48, 0, 10, 4, 95, 35, 14, 4, 13, 50, 72, 0, 10, 2, 194, 162, 89, 121, 50, 47, 89, 0, 0, 15, 69, 53, 84, 197, 84, 208, 65, 57, 134, 88, 6, 141, 65, 0, 15, 69, 52, 242, 137, 80, 240, 65, 136, 107, 6, 129, 47, 136, 0, 18, 70, 28, 145, 193, 57, 66, 67, 75, 137, 81, 6, 35, 50, 47, 122, 49, 0, 8, 2, 197, 139, 121, 68, 81, 0, 9, 2, 194, 163, 48, 135, 50, 72, 0, 0, 16, 70, 65, 35, 199, 20, 230, 64, 48, 34, 124, 75, 13, 50, 37, 0, 24, 73, 16, 148, 195, 60, 228, 207, 48, 21, 5, 72, 122, 89, 49, 6, 124, 50, 89, 13, 55, 13, 47, 0, 0, 11, 67, 56, 245, 0, 50, 124, 47, 0, 42, 40, 15, 67, 56, 245, 0, 4, 50, 124, 47, 13, 0, 34, 81, 97, 32, 26, 67, 56, 245, 0, 4, 50, 124, 47, 107, 35, 84, 47, 116, 0, 35, 11, 82, 104, 97, 118, 101, 32, 116, 111, 32, 20, 67, 56, 245, 0, 50, 124, 47, 107, 35, 84, 0, 35, 14, 81, 104, 97, 118, 101, 32, 19, 67, 56, 245, 0, 50, 124, 47, 119, 84, 0, 35, 73, 81, 104, 97, 118, 101, 32, 13, 67, 56, 245, 0, 4, 50, 124, 47, 0, 40, 9, 11, 10, 199, 52, 19, 136, 5, 69, 5, 56, 66, 17, 70, 64, 150, 154, 21, 34, 65, 48, 129, 47, 89, 13, 34, 6, 141, 0, 13, 70, 64, 128, 82, 4, 242, 0, 83, 140, 34, 136, 0, 9, 67, 56, 245, 0, 50, 136, 47, 0, 18, 71, 16, 84, 208, 21, 32, 84, 20, 72, 121, 89, 48, 13, 34, 13, 47, 0, 0, 18, 72, 12, 243, 147, 12, 145, 78, 12, 80, 49, 124, 50, 91, 13, 50, 89, 0, 13, 2, 194, 174, 34, 121, 75, 122, 89, 47, 114, 72, 0, 0, 12, 67, 61, 97, 82, 136, 84, 114, 0, 72, 12, 9, 11, 69, 100, 245, 78, 28, 80, 57, 125, 68, 0, 19, 70, 32, 243, 132, 85, 32, 83, 107, 124, 50, 72, 6, 57, 143, 34, 13, 89, 0, 13, 69, 28, 83, 143, 52, 80, 75, 129, 50, 136, 65, 0, 12, 69, 12, 243, 77, 36, 80, 49, 124, 65, 122, 0, 5, 130, 195, 167, 43, 0, 13, 66, 77, 80, 89, 134, 89, 13, 0, 81, 115, 101, 32, 9, 198, 65, 35, 195, 20, 81, 0, 9, 9, 198, 65, 35, 195, 20, 81, 0, 36, 16, 70, 65, 35, 195, 20, 81, 0, 48, 34, 136, 89, 129, 72, 0, 10, 12, 2, 194, 172, 50, 124, 47, 23, 89, 137, 50, 0, 5, 130, 195, 164, 43, 0, 10, 199, 76, 84, 85, 21, 53, 5, 72, 66, 20, 71, 29, 80, 67, 4, 211, 204, 20, 81, 58, 126, 49, 119, 65, 6, 136, 55, 129, 0, 22, 73, 12, 131, 204, 21, 53, 5, 72, 243, 0, 49, 13, 55, 121, 89, 47, 13, 34, 124, 55, 0, 16, 71, 12, 131, 195, 60, 192, 84, 20, 76, 124, 49, 55, 13, 47, 0, 0, 15, 68, 92, 130, 67, 32, 4, 58, 122, 76, 0, 8, 12, 9, 32, 23, 73, 52, 144, 200, 20, 192, 78, 28, 83, 15, 65, 137, 49, 118, 6, 35, 50, 75, 13, 55, 136, 0, 11, 68, 56, 145, 197, 48, 50, 137, 75, 118, 0, 11, 68, 40, 19, 73, 20, 75, 138, 65, 37, 0, 11, 68, 12, 80, 201, 48, 89, 121, 89, 118, 0, 13, 68, 69, 80, 137, 80, 49, 57, 134, 71, 122, 47, 0, 12, 68, 56, 18, 197, 16, 50, 138, 49, 123, 72, 0, 15, 70, 52, 19, 149, 21, 97, 82, 65, 13, 50, 134, 84, 114, 0, 15, 70, 52, 19, 133, 85, 97, 82, 65, 13, 50, 134, 84, 114, 0, 11, 68, 48, 83, 77, 20, 55, 121, 65, 37, 0, 11, 68, 8, 17, 197, 48, 71, 138, 81, 118, 0, 0, 13, 69, 64, 148, 195, 21, 48, 48, 137, 89, 129, 88, 0, 0, 14, 4, 95, 18, 5, 22, 34, 122, 84, 6, 128, 89, 72, 0, 6, 130, 195, 160, 43, 14, 0, 12, 2, 194, 169, 49, 124, 48, 122, 34, 137, 47, 0, 0, 10, 68, 4, 113, 201, 20, 35, 81, 37, 0, 11, 68, 76, 178, 69, 16, 89, 49, 129, 72, 0, 22, 72, 65, 33, 70, 21, 32, 66, 49, 144, 48, 34, 121, 83, 14, 34, 13, 71, 55, 122, 0, 32, 11, 68, 16, 80, 207, 100, 72, 129, 49, 139, 0, 13, 2, 194, 182, 48, 35, 34, 13, 81, 34, 35, 83, 0, 0, 13, 69, 52, 243, 132, 5, 144, 65, 125, 50, 72, 138, 0, 17, 70, 16, 85, 18, 37, 69, 83, 72, 113, 47, 34, 137, 47, 13, 89, 0, 5, 130, 197, 159, 43, 5, 130, 195, 175, 43, 0, 15, 66, 60, 224, 2, 124, 50, 86, 115, 0, 81, 116, 104, 101, 32, 9, 66, 60, 224, 4, 124, 50, 0, 12, 0, 16, 70, 60, 36, 212, 4, 51, 5, 124, 71, 89, 47, 13, 49, 118, 0, 9, 67, 48, 80, 68, 55, 129, 72, 0, 6, 195, 4, 32, 192, 17, 10, 2, 194, 181, 65, 137, 49, 34, 136, 0, 0, 6, 195, 60, 224, 197, 8, 12, 68, 52, 81, 193, 56, 65, 121, 81, 13, 50, 0, 11, 68, 32, 82, 68, 36, 107, 137, 72, 37, 0, 10, 68, 4, 242, 70, 20, 129, 83, 13, 0, 12, 68, 92, 131, 201, 76, 107, 134, 6, 122, 88, 0, 12, 68, 72, 21, 9, 60, 34, 138, 91, 122, 136, 0, 11, 68, 52, 144, 79, 92, 65, 129, 6, 135, 0, 21, 72, 4, 229, 9, 80, 129, 83, 21, 48, 35, 50, 47, 6, 122, 87, 13, 89, 129, 88, 0, 12, 68, 4, 67, 194, 20, 119, 72, 136, 71, 37, 0, 5, 130, 195, 170, 43, 0, 13, 69, 56, 117, 89, 20, 224, 50, 134, 57, 121, 50, 0, 5, 130, 195, 171, 43, 0, 14, 70, 25, 80, 200, 76, 144, 64, 83, 57, 134, 91, 13, 0, 12, 2, 194, 176, 72, 122, 81, 34, 6, 129, 88, 0, 0, 16, 70, 16, 162, 66, 61, 85, 9, 75, 122, 71, 6, 134, 47, 37, 0, 13, 5, 3, 39, 13, 15, 14, 49, 13, 65, 124, 50, 0, 9, 67, 4, 176, 64, 35, 49, 119, 0, 17, 71, 4, 69, 133, 73, 66, 90, 20, 35, 72, 84, 114, 47, 137, 88, 0, 16, 2, 194, 177, 48, 55, 125, 89, 132, 65, 6, 137, 50, 13, 89, 0, 5, 130, 195, 169, 43, 0, 11, 68, 80, 80, 200, 100, 47, 121, 49, 37, 0, 13, 68, 52, 245, 9, 24, 65, 136, 47, 6, 129, 83, 0, 13, 2, 194, 190, 87, 34, 129, 49, 58, 132, 47, 114, 0, 5, 130, 195, 182, 43, 0, 14, 69, 52, 148, 212, 20, 64, 65, 122, 89, 47, 123, 72, 0, 6, 195, 85, 35, 0, 17, 13, 2, 195, 183, 72, 113, 84, 6, 137, 72, 71, 137, 0, 0, 15, 70, 12, 19, 80, 8, 83, 12, 49, 35, 65, 71, 13, 55, 0, 17, 70, 81, 83, 137, 76, 144, 64, 47, 134, 50, 6, 129, 90, 13, 0, 103, 11, 2, 194, 188, 119, 49, 58, 132, 47, 114, 0, 0, 15, 70, 48, 21, 82, 20, 224, 197, 55, 124, 34, 13, 50, 89, 0, 17, 70, 76, 85, 133, 72, 83, 25, 89, 113, 84, 6, 142, 55, 122, 0, 32, 16, 70, 56, 243, 147, 20, 228, 197, 50, 124, 50, 89, 13, 50, 89, 0, 9, 2, 194, 189, 119, 107, 126, 83, 0, 0, 16, 70, 52, 244, 143, 12, 48, 78, 65, 13, 34, 124, 49, 13, 50, 0, 11, 68, 52, 144, 79, 84, 65, 129, 6, 135, 0, 18, 4, 95, 18, 6, 24, 34, 6, 121, 47, 34, 13, 83, 55, 121, 49, 89, 0, 14, 4, 95, 3, 5, 4, 89, 13, 72, 6, 122, 55, 119, 0, 0, 10, 67, 44, 240, 78, 49, 136, 126, 50, 0, 14, 69, 16, 80, 197, 57, 64, 72, 129, 89, 13, 50, 47, 0, 14, 69, 8, 19, 12, 21, 64, 71, 35, 55, 6, 138, 0, 103, 12, 69, 8, 19, 12, 21, 64, 71, 35, 55, 138, 0, 0, 15, 70, 100, 241, 200, 85, 37, 0, 57, 136, 81, 114, 47, 0, 103, 14, 70, 100, 241, 200, 85, 37, 0, 57, 124, 81, 114, 47, 0, 14, 70, 52, 20, 145, 84, 81, 64, 65, 127, 49, 6, 129, 0, 7, 2, 195, 176, 121, 86, 0, 0, 19, 71, 36, 212, 5, 72, 97, 67, 80, 122, 65, 48, 6, 128, 83, 121, 49, 47, 0, 10, 67, 12, 241, 68, 49, 136, 121, 72, 0, 14, 4, 95, 12, 9, 7, 55, 4, 122, 81, 119, 76, 13, 0, 5, 130, 195, 177, 43, 5, 130, 197, 161, 43, 0, 19, 72, 72, 84, 212, 5, 84, 129, 57, 64, 34, 121, 89, 47, 34, 124, 50, 47, 0, 8, 2, 195, 190, 87, 132, 50, 0, 0, 12, 69, 72, 85, 84, 21, 32, 34, 139, 47, 114, 0, 22, 67, 80, 83, 0, 47, 4, 121, 55, 15, 119, 84, 6, 129, 84, 0, 81, 97, 118, 105, 118, 32, 11, 67, 56, 18, 70, 50, 137, 6, 129, 83, 0, 14, 69, 12, 243, 66, 5, 64, 49, 124, 65, 71, 35, 47, 0, 0, 16, 6, 19, 8, 1, 14, 39, 20, 4, 91, 126, 50, 47, 0, 32, 12, 9, 67, 93, 84, 211, 58, 117, 89, 0, 17, 70, 65, 35, 196, 84, 49, 64, 48, 34, 124, 72, 57, 134, 89, 0, 37, 13, 70, 12, 128, 84, 20, 21, 64, 91, 35, 47, 136, 0, 5, 130, 195, 188, 43, 0, 14, 70, 80, 132, 143, 84, 114, 0, 87, 34, 134, 0, 72, 12, 0, 11, 68, 4, 114, 76, 20, 35, 75, 118, 0, 103, 10, 67, 32, 211, 77, 107, 6, 13, 65, 0, 10, 68, 24, 194, 69, 72, 83, 55, 145, 0, 0, 15, 69, 56, 85, 129, 16, 16, 50, 113, 84, 35, 72, 13, 0, 103, 14, 69, 56, 85, 129, 16, 16, 50, 113, 84, 126, 72, 13, 0, 21, 73, 72, 83, 129, 37, 52, 193, 56, 49, 64, 34, 121, 50, 13, 89, 124, 50, 89, 0, 103, 12, 69, 49, 144, 200, 20, 80, 55, 129, 76, 129, 0, 14, 69, 24, 18, 137, 80, 16, 83, 119, 107, 129, 47, 13, 0, 7, 2, 202, 131, 121, 91, 0, 0, 9, 198, 77, 84, 208, 20, 53, 0, 36, 17, 70, 77, 84, 208, 20, 53, 0, 89, 125, 89, 48, 121, 49, 47, 0, 10, 15, 70, 24, 192, 67, 12, 145, 0, 83, 55, 35, 89, 122, 72, 0, 9, 67, 8, 144, 83, 71, 144, 89, 0, 0, 10, 67, 65, 52, 212, 48, 89, 89, 47, 0, 10, 67, 24, 144, 84, 83, 129, 13, 47, 0, 0, 17, 70, 85, 65, 78, 76, 147, 0, 57, 134, 47, 6, 121, 50, 89, 118, 0, 10, 68, 72, 82, 71, 56, 34, 138, 50, 0, 15, 70, 12, 20, 9, 80, 243, 0, 49, 35, 48, 122, 47, 118, 0, 12, 68, 4, 194, 66, 36, 35, 55, 13, 71, 137, 0, 0, 14, 69, 8, 81, 143, 72, 80, 71, 122, 83, 133, 0, 74, 12, 13, 69, 81, 34, 67, 36, 16, 47, 34, 122, 91, 13, 0, 13, 69, 48, 83, 143, 72, 80, 55, 121, 50, 6, 133, 0, 13, 69, 29, 32, 72, 4, 208, 81, 34, 138, 13, 65, 0, 11, 69, 4, 242, 70, 24, 80, 129, 83, 13, 0, 8, 197, 4, 226, 193, 72, 16, 65, 16, 70, 64, 19, 131, 72, 80, 83, 48, 35, 50, 49, 34, 141, 89, 0, 14, 69, 64, 17, 76, 48, 16, 48, 137, 6, 121, 55, 13, 0, 6, 195, 4, 178, 78, 66, 9, 67, 4, 49, 82, 138, 89, 114, 0, 0, 6, 194, 85, 48, 17, 42, 9, 66, 85, 48, 4, 125, 89, 0, 9, 9, 198, 12, 243, 132, 84, 53, 0, 36, 16, 70, 12, 243, 132, 84, 53, 0, 49, 124, 50, 72, 125, 49, 47, 0, 12, 2, 201, 148, 136, 48, 13, 50, 6, 130, 10, 0, 0, 18, 71, 77, 67, 210, 101, 65, 76, 48, 89, 47, 130, 34, 122, 47, 121, 55, 0, 18, 71, 65, 54, 67, 32, 244, 201, 76, 89, 137, 49, 6, 136, 89, 122, 89, 0, 18, 71, 36, 229, 133, 57, 67, 210, 100, 122, 50, 84, 13, 50, 47, 34, 122, 0, 18, 71, 20, 116, 133, 28, 147, 213, 76, 122, 81, 34, 6, 129, 75, 13, 89, 0, 13, 4, 95, 57, 48, 15, 50, 6, 137, 50, 47, 141, 0, 0, 9, 67, 37, 51, 1, 137, 55, 13, 0, 12, 68, 4, 131, 69, 16, 35, 101, 65, 121, 72, 0, 11, 68, 28, 147, 77, 20, 81, 122, 65, 37, 0, 0, 11, 69, 80, 129, 73, 73, 48, 86, 140, 88, 0, 16, 70, 76, 144, 133, 48, 149, 83, 89, 113, 71, 138, 55, 141, 89, 0, 15, 69, 56, 240, 143, 17, 144, 6, 50, 136, 71, 124, 72, 37, 0, 12, 69, 52, 80, 68, 61, 112, 65, 121, 72, 136, 0, 15, 69, 21, 131, 196, 85, 48, 121, 49, 89, 13, 72, 13, 89, 0, 13, 69, 12, 20, 133, 77, 48, 49, 13, 34, 121, 89, 0, 14, 69, 12, 19, 150, 5, 48, 49, 35, 50, 84, 13, 89, 0, 0, 12, 67, 28, 241, 83, 2, 81, 136, 88, 0, 12, 9, 8, 2, 196, 184, 49, 34, 126, 0, 11, 4, 95, 2, 1, 18, 10, 71, 6, 127, 0, 0, 15, 70, 52, 16, 203, 20, 227, 129, 65, 13, 49, 121, 50, 13, 0, 18, 70, 60, 179, 1, 32, 243, 65, 136, 49, 55, 119, 107, 6, 136, 65, 13, 0, 9, 198, 61, 97, 82, 80, 147, 69, 65, 9, 67, 32, 211, 64, 107, 13, 65, 0, 0, 18, 67, 76, 243, 69, 89, 125, 65, 58, 124, 50, 0, 106, 81, 111, 110, 101, 32, 18, 67, 76, 243, 69, 89, 125, 65, 58, 125, 50, 0, 106, 81, 111, 110, 101, 32, 17, 67, 76, 243, 69, 89, 125, 65, 58, 124, 50, 0, 81, 111, 110, 101, 32, 13, 67, 76, 243, 69, 4, 89, 125, 65, 0, 34, 13, 9, 11, 68, 88, 81, 199, 100, 84, 121, 75, 122, 0, 10, 2, 204, 134, 71, 34, 121, 84, 10, 0, 5, 130, 197, 190, 43, 0, 11, 67, 8, 17, 90, 71, 137, 6, 121, 88, 0, 17, 70, 17, 83, 70, 72, 145, 83, 72, 125, 65, 83, 34, 6, 129, 89, 0, 12, 69, 60, 97, 133, 73, 48, 124, 83, 114, 88, 0, 15, 69, 32, 144, 84, 85, 48, 107, 137, 6, 138, 47, 13, 89, 0, 14, 69, 16, 80, 146, 37, 48, 72, 13, 71, 34, 129, 0, 103, 13, 69, 16, 80, 146, 37, 48, 72, 121, 71, 34, 129, 0, 0, 10, 67, 16, 83, 79, 72, 121, 65, 136, 0, 12, 2, 204, 132, 65, 35, 49, 34, 124, 50, 10, 0, 20, 2, 203, 140, 89, 6, 121, 49, 13, 50, 72, 34, 122, 89, 47, 34, 4, 121, 89, 0, 15, 2, 202, 148, 81, 55, 6, 124, 19, 118, 89, 47, 124, 48, 0, 0, 0, 10, 68, 52, 17, 86, 20, 65, 138, 84, 0, 10, 67, 49, 84, 5, 55, 134, 48, 138, 0, 11, 68, 52, 149, 18, 20, 65, 137, 47, 114, 0, 11, 67, 17, 84, 5, 72, 57, 134, 48, 0, 135, 16, 2, 204, 130, 89, 128, 49, 125, 65, 83, 55, 121, 49, 89, 10, 0, 7, 2, 202, 146, 121, 90, 0, 0, 8, 197, 12, 243, 146, 4, 64, 65, 13, 69, 76, 19, 15, 60, 224, 89, 119, 55, 134, 50, 0, 12, 69, 64, 20, 137, 4, 128, 48, 13, 34, 144, 0, 11, 2, 204, 131, 47, 122, 55, 72, 13, 10, 0, 13, 2, 201, 155, 136, 48, 13, 50, 6, 121, 12, 10, 0, 0, 16, 8, 19, 9, 15, 2, 8, 195, 161, 14, 91, 13, 84, 130, 50, 0, 17, 70, 56, 144, 207, 76, 144, 64, 50, 122, 49, 13, 89, 6, 129, 13, 0, 10, 2, 204, 128, 81, 34, 126, 84, 10, 0, 10, 2, 203, 136, 89, 47, 34, 121, 89, 0, 0, 8, 67, 21, 36, 128, 140, 0, 103, 16, 70, 12, 19, 130, 21, 36, 129, 49, 35, 50, 71, 13, 34, 13, 0, 15, 71, 52, 244, 133, 12, 19, 66, 20, 65, 133, 49, 13, 65, 0, 7, 67, 21, 36, 128, 128, 0, 19, 71, 4, 229, 9, 64, 21, 8, 100, 35, 50, 47, 6, 122, 48, 13, 87, 37, 0, 6, 195, 57, 148, 4, 17, 11, 2, 204, 129, 119, 49, 57, 134, 47, 10, 0, 8, 2, 201, 153, 91, 58, 126, 0, 0, 22, 72, 72, 84, 21, 80, 21, 9, 60, 224, 34, 121, 48, 57, 134, 47, 6, 138, 91, 13, 50, 0, 17, 7, 16, 9, 195, 177, 1, 20, 1, 48, 129, 67, 6, 35, 47, 119, 0, 12, 68, 64, 84, 149, 76, 48, 13, 34, 134, 88, 0, 11, 200, 32, 244, 137, 104, 243, 148, 4, 192, 67, 11, 200, 16, 148, 195, 61, 83, 148, 20, 64, 66, 11, 68, 4, 194, 65, 76, 138, 55, 141, 89, 0, 0, 14, 69, 76, 18, 71, 60, 224, 89, 137, 81, 6, 124, 50, 0, 14, 69, 92, 147, 132, 20, 64, 58, 122, 50, 72, 123, 72, 0, 12, 67, 28, 242, 78, 4, 81, 136, 113, 50, 0, 9, 0, 12, 2, 201, 164, 34, 35, 65, 89, 107, 132, 50, 0, 0, 27, 75, 72, 80, 207, 52, 209, 78, 16, 21, 9, 60, 224, 34, 121, 49, 13, 65, 121, 50, 72, 6, 138, 91, 13, 50, 0, 0, 15, 68, 8, 82, 78, 28, 4, 71, 129, 122, 68, 0, 35, 9, 12, 12, 68, 8, 16, 213, 64, 71, 138, 49, 13, 48, 0, 10, 68, 28, 81, 83, 20, 81, 129, 89, 0, 12, 68, 20, 66, 67, 80, 129, 72, 122, 49, 47, 0, 12, 68, 12, 243, 66, 60, 49, 124, 65, 71, 136, 0, 11, 68, 4, 114, 78, 28, 138, 75, 122, 68, 0, 10, 2, 204, 138, 34, 122, 68, 81, 10, 0, 0, 14, 69, 80, 16, 140, 21, 64, 47, 35, 71, 55, 13, 47, 0, 14, 69, 4, 195, 79, 77, 64, 130, 55, 65, 136, 89, 47, 0, 14, 69, 4, 35, 5, 77, 64, 138, 71, 55, 13, 89, 47, 0, 0, 15, 70, 77, 65, 87, 5, 37, 0, 89, 47, 134, 114, 47, 0, 103, 15, 70, 77, 65, 87, 5, 37, 0, 89, 47, 57, 134, 114, 47, 0, 15, 70, 12, 19, 132, 4, 49, 64, 49, 35, 50, 72, 122, 89, 0, 16, 70, 72, 81, 133, 72, 81, 64, 34, 121, 83, 13, 34, 6, 129, 0, 14, 70, 72, 20, 16, 61, 37, 0, 34, 35, 48, 6, 133, 0, 12, 2, 204, 136, 72, 145, 34, 129, 89, 113, 89, 0, 13, 2, 203, 144, 55, 121, 68, 87, 13, 50, 72, 10, 0, 0, 0, 12, 68, 48, 80, 78, 56, 55, 129, 6, 35, 50, 0, 22, 72, 84, 226, 78, 80, 84, 133, 77, 64, 125, 50, 6, 122, 50, 47, 13, 34, 13, 89, 47, 0, 13, 68, 72, 82, 197, 100, 34, 4, 129, 49, 6, 129, 0, 22, 72, 72, 18, 78, 24, 244, 133, 77, 64, 34, 6, 138, 50, 83, 4, 124, 34, 113, 89, 47, 0, 0, 13, 69, 100, 84, 211, 37, 32, 57, 121, 89, 89, 128, 0, 11, 69, 65, 32, 89, 21, 32, 48, 34, 140, 0, 8, 67, 64, 80, 82, 48, 140, 0, 8, 197, 61, 85, 12, 21, 64, 65, 13, 69, 12, 128, 82, 37, 64, 76, 35, 34, 122, 47, 0, 12, 69, 12, 17, 83, 5, 32, 89, 129, 88, 114, 0, 8, 2, 202, 167, 76, 121, 91, 0, 0, 7, 66, 76, 144, 89, 129, 0, 14, 70, 29, 35, 213, 64, 145, 64, 81, 34, 134, 48, 37, 0, 15, 70, 5, 50, 193, 56, 49, 64, 119, 89, 49, 120, 50, 89, 0, 8, 2, 202, 164, 75, 121, 90, 0, 0, 0, 12, 68, 40, 16, 207, 8, 75, 138, 49, 13, 71, 0, 12, 68, 8, 19, 66, 36, 71, 35, 65, 71, 129, 0, 11, 68, 76, 178, 69, 76, 89, 49, 137, 88, 0, 11, 68, 4, 208, 83, 76, 119, 65, 35, 89, 0, 0, 15, 69, 80, 243, 65, 80, 240, 47, 13, 65, 138, 47, 136, 0, 103, 18, 67, 80, 80, 82, 47, 6, 140, 15, 6, 124, 83, 0, 81, 111, 102, 102, 32, 21, 67, 80, 80, 82, 47, 4, 140, 15, 119, 48, 127, 47, 0, 81, 97, 112, 97, 114, 116, 32, 9, 67, 80, 80, 82, 47, 140, 0, 36, 9, 67, 80, 80, 82, 47, 142, 0, 10, 13, 69, 76, 19, 9, 56, 80, 89, 138, 55, 137, 50, 0, 12, 69, 61, 85, 1, 28, 80, 135, 47, 113, 75, 0, 12, 69, 28, 19, 15, 72, 80, 81, 119, 55, 133, 0, 0, 15, 70, 64, 198, 77, 61, 85, 8, 48, 55, 122, 65, 13, 87, 0, 12, 67, 96, 208, 83, 121, 49, 89, 65, 119, 89, 0, 10, 198, 21, 133, 18, 4, 53, 0, 66, 36, 10, 198, 21, 133, 18, 4, 53, 0, 65, 9, 10, 198, 21, 133, 18, 4, 53, 0, 65, 10, 0, 20, 71, 65, 34, 77, 5, 97, 82, 4, 48, 34, 129, 65, 13, 84, 6, 140, 34, 13, 0, 18, 71, 12, 145, 193, 72, 85, 20, 20, 89, 122, 81, 13, 6, 34, 121, 47, 0, 0, 11, 68, 12, 130, 76, 20, 76, 122, 55, 37, 0, 12, 68, 76, 83, 69, 56, 89, 129, 65, 13, 50, 0, 17, 70, 52, 20, 129, 80, 131, 206, 65, 35, 34, 13, 87, 124, 50, 0, 103, 11, 68, 16, 147, 196, 20, 72, 137, 136, 72, 0, 11, 68, 4, 81, 201, 76, 129, 75, 122, 89, 0, 18, 2, 204, 158, 119, 48, 34, 6, 124, 49, 89, 122, 65, 13, 50, 47, 10, 0, 0, 12, 69, 12, 243, 142, 36, 80, 49, 124, 50, 37, 0, 8, 197, 76, 85, 20, 20, 80, 66, 14, 69, 72, 81, 15, 56, 80, 34, 129, 72, 6, 125, 50, 0, 13, 69, 72, 21, 137, 56, 80, 34, 13, 84, 129, 50, 0, 17, 70, 52, 244, 209, 84, 149, 15, 65, 13, 89, 49, 6, 129, 47, 136, 0, 14, 69, 5, 85, 9, 76, 208, 130, 108, 122, 88, 13, 65, 0, 0, 15, 70, 81, 84, 142, 44, 86, 64, 47, 148, 50, 49, 129, 0, 105, 14, 70, 81, 84, 142, 44, 86, 64, 47, 128, 50, 49, 129, 0, 0, 16, 70, 64, 21, 18, 36, 50, 65, 48, 119, 47, 34, 122, 91, 13, 0, 18, 71, 12, 20, 211, 4, 225, 18, 4, 49, 13, 89, 35, 50, 72, 34, 13, 0, 19, 71, 72, 84, 21, 80, 16, 140, 20, 34, 121, 48, 57, 134, 47, 13, 71, 118, 0, 10, 199, 12, 244, 143, 48, 192, 82, 100, 66, 6, 2, 95, 1, 138, 0, 0, 15, 70, 12, 245, 207, 72, 177, 82, 49, 136, 58, 128, 49, 114, 0, 9, 198, 12, 21, 129, 48, 145, 82, 67, 7, 2, 201, 178, 67, 121, 0, 0, 14, 69, 64, 145, 211, 81, 144, 48, 122, 81, 89, 47, 137, 0, 15, 69, 28, 19, 1, 97, 144, 81, 35, 55, 119, 49, 89, 37, 0, 14, 69, 13, 34, 83, 37, 48, 49, 34, 137, 89, 122, 89, 0, 0, 10, 67, 16, 85, 83, 72, 138, 117, 89, 0, 0, 15, 70, 76, 192, 86, 37, 50, 0, 89, 55, 138, 84, 122, 91, 0, 14, 70, 44, 224, 86, 37, 50, 0, 50, 138, 84, 122, 91, 0, 0, 11, 200, 72, 81, 193, 72, 67, 5, 77, 48, 8, 11, 68, 76, 21, 143, 100, 89, 119, 84, 139, 0, 17, 70, 36, 229, 5, 72, 210, 78, 122, 50, 47, 6, 128, 65, 122, 50, 0, 11, 68, 12, 240, 207, 4, 49, 136, 49, 136, 0, 0, 17, 70, 16, 19, 65, 76, 53, 83, 72, 119, 65, 35, 89, 49, 13, 89, 0, 9, 198, 61, 85, 2, 72, 80, 75, 65, 13, 69, 16, 148, 200, 21, 48, 72, 122, 91, 123, 88, 0, 14, 69, 4, 194, 66, 37, 48, 35, 55, 13, 71, 137, 88, 0, 11, 2, 201, 190, 10, 6, 127, 47, 35, 48, 0, 0, 10, 2, 204, 165, 34, 122, 68, 81, 10, 0, 0, 5, 194, 80, 128, 9, 6, 66, 80, 128, 87, 0, 0, 8, 67, 5, 32, 192, 127, 49, 0, 6, 195, 37, 32, 192, 17, 0, 10, 68, 44, 131, 69, 72, 49, 65, 142, 0, 12, 2, 202, 178, 65, 4, 124, 72, 75, 6, 138, 0, 0, 14, 69, 16, 80, 204, 4, 224, 72, 121, 49, 55, 119, 50, 0, 14, 69, 4, 194, 83, 60, 224, 35, 55, 122, 89, 13, 50, 0, 17, 70, 4, 117, 73, 48, 84, 129, 35, 81, 129, 55, 6, 140, 34, 13, 0, 14, 69, 77, 83, 148, 4, 224, 89, 125, 50, 47, 35, 50, 0, 12, 69, 61, 36, 8, 4, 224, 132, 83, 13, 50, 0, 0, 15, 70, 88, 19, 133, 77, 48, 64, 84, 119, 50, 121, 89, 13, 0, 13, 70, 73, 84, 211, 20, 195, 0, 34, 125, 89, 118, 0, 15, 70, 80, 147, 73, 16, 84, 128, 47, 122, 65, 122, 72, 114, 0, 15, 2, 202, 176, 35, 89, 48, 113, 34, 138, 47, 113, 72, 10, 0, 0, 18, 71, 20, 194, 83, 4, 33, 84, 32, 113, 55, 122, 88, 13, 71, 13, 87, 0, 19, 71, 48, 19, 132, 61, 115, 133, 72, 55, 6, 35, 50, 72, 4, 136, 50, 114, 0, 18, 67, 24, 21, 88, 83, 6, 136, 15, 48, 6, 126, 0, 81, 112, 97, 115, 32, 6, 195, 85, 48, 64, 17, 17, 2, 204, 175, 50, 4, 124, 50, 89, 113, 55, 6, 35, 71, 113, 49, 0, 7, 2, 95, 19, 121, 89, 0, 0, 10, 68, 21, 83, 5, 72, 139, 55, 114, 0, 12, 68, 17, 147, 1, 56, 72, 122, 55, 13, 50, 0, 11, 68, 80, 147, 79, 72, 47, 129, 65, 133, 0, 20, 68, 92, 245, 78, 16, 58, 4, 135, 50, 72, 15, 6, 125, 48, 0, 81, 117, 112, 32, 23, 68, 92, 245, 78, 16, 58, 4, 135, 50, 72, 15, 6, 72, 135, 50, 0, 81, 100, 111, 119, 110, 32, 12, 68, 92, 245, 78, 16, 58, 135, 50, 72, 0, 38, 11, 68, 92, 245, 78, 16, 58, 134, 50, 72, 0, 11, 68, 52, 80, 78, 80, 65, 121, 50, 47, 0, 11, 68, 48, 80, 78, 80, 55, 121, 50, 47, 0, 12, 68, 5, 67, 1, 76, 35, 47, 55, 13, 89, 0, 0, 13, 69, 32, 19, 73, 76, 128, 107, 138, 65, 122, 91, 0, 14, 69, 8, 133, 84, 4, 224, 71, 134, 47, 6, 35, 50, 0, 8, 197, 88, 147, 204, 36, 224, 66, 13, 69, 33, 86, 154, 4, 128, 107, 13, 88, 6, 126, 0, 0, 10, 67, 76, 241, 129, 89, 136, 83, 13, 0, 21, 67, 93, 114, 73, 72, 125, 71, 118, 57, 134, 72, 125, 71, 118, 57, 134, 47, 6, 134, 0, 13, 2, 202, 188, 113, 75, 121, 49, 47, 113, 84, 10, 0, 0, 8, 67, 5, 32, 200, 127, 76, 0, 0, 11, 2, 204, 170, 72, 121, 50, 47, 118, 10, 0, 0, 12, 69, 16, 83, 137, 21, 32, 72, 113, 50, 145, 0, 0, 14, 70, 24, 147, 133, 77, 49, 64, 83, 113, 50, 121, 89, 0, 0, 10, 67, 85, 49, 64, 57, 134, 88, 0, 36, 9, 67, 85, 49, 64, 57, 134, 89, 0, 10, 199, 32, 80, 68, 24, 148, 147, 80, 66, 0, 11, 68, 20, 194, 83, 20, 113, 55, 129, 88, 0, 7, 196, 36, 64, 72, 60, 65, 9, 198, 52, 18, 78, 80, 18, 78, 66, 7, 196, 36, 229, 18, 60, 65, 12, 68, 12, 193, 82, 44, 49, 55, 127, 49, 0, 135, 0, 14, 69, 60, 49, 76, 61, 64, 124, 89, 13, 55, 124, 47, 0, 9, 197, 36, 228, 213, 49, 64, 65, 10, 8, 197, 36, 228, 213, 49, 64, 66, 23, 73, 36, 212, 18, 20, 115, 129, 8, 193, 64, 122, 65, 48, 34, 6, 121, 81, 50, 13, 71, 118, 0, 14, 69, 4, 97, 140, 85, 128, 119, 83, 55, 125, 49, 89, 0, 0, 13, 70, 76, 19, 201, 73, 49, 64, 89, 141, 91, 13, 0, 14, 70, 12, 193, 65, 57, 49, 64, 49, 55, 121, 50, 88, 0, 0, 18, 71, 21, 52, 9, 60, 224, 71, 20, 121, 89, 48, 122, 13, 50, 126, 90, 0, 6, 195, 5, 48, 80, 17, 0, 11, 68, 25, 147, 4, 20, 83, 137, 55, 72, 0, 10, 67, 88, 86, 0, 84, 121, 49, 89, 0, 0, 13, 69, 29, 32, 69, 52, 80, 81, 34, 138, 13, 65, 0, 13, 69, 5, 33, 217, 48, 80, 127, 81, 6, 137, 55, 0, 13, 69, 52, 244, 129, 48, 80, 65, 13, 34, 35, 55, 0, 8, 67, 37, 35, 206, 145, 50, 0, 0, 11, 67, 16, 82, 129, 72, 138, 90, 126, 0, 9, 0, 11, 67, 72, 21, 76, 34, 135, 6, 134, 55, 0, 14, 70, 32, 20, 151, 36, 50, 0, 107, 35, 34, 122, 75, 0, 10, 199, 64, 149, 21, 37, 64, 82, 100, 66, 10, 199, 28, 243, 196, 56, 145, 200, 80, 66, 0, 18, 70, 52, 242, 1, 52, 81, 0, 109, 111, 104, 97, 109, 109, 97, 100, 0, 29, 12, 68, 12, 129, 82, 36, 91, 140, 34, 6, 129, 0, 19, 72, 64, 130, 76, 37, 53, 9, 56, 80, 83, 122, 55, 113, 89, 47, 137, 50, 0, 11, 200, 52, 243, 25, 8, 65, 78, 84, 208, 66, 11, 68, 48, 80, 80, 80, 55, 121, 48, 47, 0, 11, 200, 36, 195, 9, 80, 84, 129, 80, 80, 21, 11, 68, 28, 83, 196, 20, 75, 129, 136, 72, 0, 12, 68, 16, 80, 210, 100, 72, 113, 49, 34, 137, 0, 21, 72, 12, 243, 210, 16, 147, 129, 80, 80, 49, 136, 6, 130, 72, 113, 50, 138, 47, 0, 36, 10, 2, 95, 34, 49, 58, 136, 47, 89, 0, 0, 8, 197, 101, 99, 206, 56, 80, 66, 12, 69, 64, 131, 197, 8, 80, 83, 129, 71, 129, 0, 15, 70, 4, 225, 204, 21, 49, 89, 35, 68, 81, 118, 89, 37, 0, 14, 69, 76, 145, 78, 56, 16, 89, 129, 6, 121, 50, 13, 0, 11, 69, 69, 82, 67, 32, 80, 49, 129, 91, 0, 14, 69, 65, 146, 129, 52, 16, 48, 13, 75, 126, 65, 13, 0, 14, 69, 52, 147, 149, 80, 80, 65, 122, 50, 122, 47, 0, 10, 13, 69, 16, 18, 12, 36, 16, 72, 138, 55, 129, 13, 0, 11, 69, 5, 84, 211, 36, 80, 124, 88, 37, 0, 17, 2, 95, 33, 121, 49, 89, 49, 55, 13, 65, 6, 138, 91, 13, 50, 0, 0, 13, 67, 28, 243, 133, 2, 81, 131, 50, 0, 103, 12, 9, 12, 67, 28, 243, 133, 2, 81, 124, 50, 0, 12, 9, 0, 9, 67, 76, 243, 128, 89, 125, 50, 0, 17, 70, 24, 192, 77, 20, 224, 207, 83, 55, 119, 65, 121, 68, 49, 136, 0, 12, 67, 17, 81, 84, 72, 57, 134, 6, 121, 47, 0, 9, 67, 12, 243, 128, 49, 124, 50, 0, 9, 2, 95, 39, 49, 58, 136, 47, 0, 0, 11, 68, 72, 82, 75, 36, 34, 138, 49, 129, 0, 21, 72, 36, 212, 5, 72, 21, 9, 88, 80, 122, 65, 48, 6, 121, 34, 13, 47, 122, 84, 0, 13, 2, 95, 38, 35, 65, 48, 13, 89, 35, 50, 72, 0, 0, 17, 70, 20, 228, 197, 52, 35, 5, 124, 50, 89, 6, 124, 65, 71, 118, 0, 14, 4, 95, 50, 48, 15, 47, 58, 6, 121, 50, 47, 141, 0, 13, 2, 95, 37, 48, 148, 89, 6, 121, 50, 47, 0, 105, 12, 2, 95, 37, 48, 114, 89, 6, 121, 50, 47, 0, 0, 9, 67, 12, 243, 133, 49, 136, 50, 0, 9, 2, 95, 36, 72, 124, 55, 114, 0, 0, 16, 67, 88, 19, 128, 84, 35, 50, 72, 128, 0, 81, 100, 101, 114, 32, 17, 67, 88, 19, 128, 84, 35, 50, 72, 121, 50, 0, 81, 100, 101, 110, 32, 9, 67, 80, 83, 128, 47, 121, 50, 0, 19, 71, 36, 212, 9, 56, 114, 78, 28, 122, 65, 48, 6, 122, 50, 75, 122, 68, 0, 0, 9, 198, 61, 85, 3, 5, 53, 0, 65, 11, 68, 4, 66, 69, 84, 119, 72, 57, 134, 0, 13, 2, 95, 42, 35, 89, 47, 13, 34, 122, 89, 49, 0, 14, 4, 95, 3, 1, 16, 49, 4, 35, 48, 14, 47, 118, 0, 0, 9, 67, 32, 84, 130, 128, 71, 0, 103, 12, 69, 12, 20, 211, 21, 144, 49, 138, 89, 37, 0, 14, 69, 9, 81, 78, 61, 48, 71, 58, 138, 50, 124, 89, 0, 17, 70, 80, 20, 5, 77, 68, 153, 47, 35, 48, 13, 89, 47, 34, 122, 0, 13, 2, 95, 41, 34, 137, 47, 48, 119, 34, 121, 50, 0, 0, 16, 70, 80, 244, 143, 57, 67, 192, 47, 13, 34, 124, 50, 47, 136, 0, 18, 70, 36, 66, 84, 5, 35, 196, 137, 72, 6, 122, 47, 13, 34, 124, 72, 0, 16, 70, 76, 245, 84, 32, 83, 132, 89, 126, 83, 6, 121, 50, 72, 0, 10, 67, 36, 67, 25, 137, 72, 55, 122, 0, 14, 2, 95, 40, 55, 121, 83, 47, 48, 119, 34, 121, 50, 0, 0, 11, 67, 32, 84, 128, 107, 128, 0, 72, 34, 9, 17, 67, 64, 84, 128, 48, 4, 128, 15, 89, 6, 138, 0, 81, 115, 101, 32, 20, 67, 64, 84, 128, 48, 114, 15, 89, 6, 121, 50, 47, 0, 81, 99, 101, 110, 116, 32, 9, 67, 64, 84, 128, 48, 128, 0, 72, 19, 71, 16, 243, 7, 20, 195, 1, 84, 72, 124, 55, 81, 6, 121, 99, 55, 137, 0, 6, 195, 37, 36, 192, 17, 0, 10, 67, 49, 82, 83, 55, 134, 122, 89, 0, 13, 68, 44, 80, 78, 84, 49, 122, 6, 126, 50, 134, 0, 11, 68, 20, 66, 84, 32, 129, 72, 122, 87, 0, 11, 68, 20, 35, 207, 44, 129, 71, 117, 49, 0, 8, 2, 95, 46, 72, 124, 47, 0, 0, 13, 69, 4, 68, 137, 4, 224, 138, 72, 34, 141, 50, 0, 14, 69, 53, 83, 137, 12, 128, 65, 57, 134, 50, 122, 49, 0, 15, 70, 5, 69, 15, 72, 225, 89, 119, 47, 148, 50, 37, 0, 105, 14, 70, 5, 69, 15, 72, 225, 89, 119, 47, 128, 50, 37, 0, 12, 69, 4, 195, 9, 20, 64, 35, 55, 137, 72, 0, 9, 2, 95, 45, 72, 35, 91, 0, 103, 11, 2, 95, 45, 107, 4, 137, 83, 13, 50, 0, 0, 28, 67, 32, 84, 133, 107, 6, 142, 15, 13, 50, 72, 15, 86, 6, 140, 0, 82, 97, 110, 100, 32, 116, 104, 101, 114, 101, 32, 14, 70, 76, 243, 4, 36, 84, 128, 89, 136, 55, 75, 114, 0, 9, 198, 24, 244, 133, 88, 84, 128, 66, 15, 70, 4, 195, 15, 88, 84, 128, 130, 55, 6, 136, 84, 114, 0, 9, 2, 95, 44, 49, 124, 65, 13, 0, 0, 19, 67, 24, 20, 128, 83, 6, 127, 10, 65, 4, 133, 0, 81, 109, 111, 114, 101, 32, 16, 71, 32, 243, 69, 61, 115, 133, 72, 107, 136, 65, 136, 50, 114, 0, 20, 71, 5, 4, 1, 72, 21, 21, 76, 35, 48, 13, 34, 6, 35, 47, 13, 89, 0, 103, 19, 71, 5, 4, 1, 72, 21, 21, 76, 35, 48, 13, 34, 6, 138, 47, 13, 89, 0, 12, 67, 53, 36, 192, 65, 122, 89, 113, 88, 0, 24, 9, 2, 95, 51, 87, 34, 6, 129, 0, 0, 12, 68, 4, 226, 84, 4, 119, 50, 129, 47, 13, 0, 21, 72, 104, 147, 66, 4, 37, 197, 4, 224, 88, 113, 65, 71, 126, 71, 58, 122, 13, 50, 0, 8, 2, 95, 50, 47, 6, 134, 0, 0, 13, 69, 77, 147, 66, 60, 192, 89, 122, 65, 71, 118, 0, 9, 198, 12, 243, 150, 21, 36, 197, 36, 10, 198, 12, 243, 150, 21, 36, 197, 65, 9, 10, 2, 95, 49, 58, 6, 125, 50, 0, 106, 9, 2, 95, 49, 58, 6, 124, 50, 0, 0, 16, 70, 8, 20, 133, 57, 68, 192, 71, 35, 34, 13, 50, 47, 89, 0, 14, 70, 61, 4, 15, 76, 84, 128, 13, 48, 136, 88, 114, 0, 15, 70, 48, 16, 143, 72, 84, 128, 55, 138, 71, 13, 34, 114, 0, 10, 2, 95, 48, 88, 6, 141, 34, 136, 0, 0, 19, 71, 72, 80, 207, 52, 209, 78, 16, 34, 4, 121, 49, 13, 65, 121, 50, 72, 0, 12, 2, 95, 55, 89, 6, 13, 84, 13, 50, 0, 107, 11, 2, 95, 55, 89, 6, 121, 84, 13, 50, 0, 0, 10, 67, 56, 148, 143, 50, 141, 34, 136, 0, 10, 67, 21, 35, 211, 141, 34, 124, 89, 0, 10, 2, 95, 54, 89, 6, 122, 49, 89, 0, 0, 9, 2, 95, 53, 83, 6, 137, 84, 0, 0, 16, 70, 72, 84, 18, 37, 48, 76, 34, 113, 48, 34, 137, 88, 118, 0, 17, 70, 64, 83, 131, 32, 19, 148, 48, 121, 50, 91, 13, 50, 47, 0, 103, 15, 70, 64, 83, 131, 32, 19, 148, 48, 124, 50, 91, 124, 50, 0, 14, 70, 24, 21, 9, 29, 81, 64, 83, 119, 47, 129, 81, 0, 8, 2, 95, 52, 83, 6, 133, 0, 0, 15, 2, 95, 59, 89, 121, 65, 122, 49, 6, 136, 55, 13, 50, 0, 0, 11, 67, 32, 84, 147, 107, 128, 88, 0, 72, 12, 11, 68, 4, 226, 83, 20, 35, 50, 122, 89, 0, 10, 2, 95, 58, 49, 136, 55, 13, 50, 0, 0, 15, 69, 92, 130, 76, 77, 64, 58, 4, 137, 55, 89, 47, 0, 8, 13, 5, 8, 5, 39, 12, 12, 107, 129, 55, 0, 72, 32, 13, 69, 21, 131, 79, 61, 32, 121, 49, 89, 65, 143, 0, 15, 69, 72, 81, 140, 85, 128, 34, 129, 83, 55, 125, 49, 89, 0, 9, 2, 95, 57, 50, 6, 137, 50, 0, 0, 10, 66, 92, 80, 58, 129, 0, 72, 32, 9, 13, 202, 52, 20, 211, 4, 50, 21, 76, 85, 20, 76, 67, 8, 66, 100, 16, 57, 119, 0, 9, 9, 198, 77, 84, 18, 37, 49, 64, 66, 18, 70, 12, 240, 88, 36, 19, 0, 49, 136, 6, 35, 49, 89, 122, 13, 55, 0, 16, 70, 12, 20, 129, 52, 83, 0, 49, 35, 34, 13, 65, 121, 55, 0, 16, 70, 4, 48, 213, 73, 49, 68, 119, 49, 148, 89, 123, 72, 0, 105, 15, 70, 4, 48, 213, 73, 49, 68, 119, 49, 128, 89, 123, 72, 0, 5, 194, 84, 144, 17, 8, 2, 95, 56, 6, 138, 47, 0, 0, 16, 70, 64, 84, 147, 64, 86, 0, 48, 128, 89, 48, 121, 49, 89, 0, 10, 199, 36, 229, 5, 72, 96, 67, 20, 65, 18, 71, 12, 243, 131, 36, 84, 135, 20, 49, 124, 50, 89, 122, 6, 140, 90, 0, 12, 2, 95, 63, 49, 58, 121, 89, 76, 13, 50, 0, 0, 11, 68, 24, 145, 82, 100, 83, 145, 34, 122, 0, 12, 68, 12, 19, 69, 60, 49, 35, 65, 122, 136, 0, 13, 2, 95, 62, 81, 34, 138, 47, 13, 86, 35, 50, 0, 0, 15, 69, 28, 64, 78, 76, 176, 81, 14, 72, 35, 50, 89, 49, 0, 14, 69, 48, 240, 193, 48, 80, 55, 136, 49, 6, 120, 55, 0, 12, 69, 29, 82, 78, 20, 16, 81, 122, 50, 37, 0, 13, 69, 24, 16, 193, 16, 80, 83, 13, 89, 126, 72, 0, 13, 69, 16, 80, 193, 16, 80, 72, 121, 49, 138, 72, 0, 10, 2, 95, 61, 129, 49, 58, 118, 88, 0, 0, 17, 70, 16, 243, 133, 28, 19, 0, 72, 124, 50, 113, 81, 6, 130, 55, 0, 10, 67, 16, 83, 153, 72, 113, 50, 137, 0, 11, 2, 95, 60, 55, 121, 89, 86, 35, 50, 0, 0, 0, 27, 68, 92, 245, 76, 16, 58, 117, 72, 107, 35, 84, 47, 116, 0, 74, 32, 12, 82, 104, 97, 118, 101, 32, 116, 111, 32, 21, 68, 92, 245, 76, 16, 58, 117, 72, 107, 35, 84, 0, 35, 14, 81, 104, 97, 118, 101, 32, 22, 68, 92, 245, 76, 16, 58, 2, 117, 72, 107, 2, 119, 84, 0, 35, 81, 104, 97, 118, 101, 32, 10, 196, 92, 245, 76, 16, 76, 32, 9, 12, 12, 68, 4, 211, 65, 56, 119, 65, 6, 126, 50, 0, 10, 67, 5, 53, 83, 138, 89, 13, 89, 0, 13, 68, 4, 66, 79, 76, 35, 86, 57, 6, 149, 89, 0, 0, 15, 69, 81, 34, 65, 56, 144, 47, 34, 129, 6, 35, 50, 37, 0, 14, 69, 76, 243, 21, 80, 80, 89, 124, 55, 57, 134, 47, 0, 15, 69, 16, 80, 149, 56, 176, 72, 129, 71, 6, 125, 50, 49, 0, 9, 198, 4, 229, 9, 52, 243, 153, 66, 0, 10, 2, 95, 64, 35, 47, 89, 137, 50, 0, 0, 19, 71, 21, 133, 18, 4, 66, 84, 20, 121, 49, 89, 47, 34, 13, 72, 137, 47, 0, 0, 20, 72, 65, 35, 202, 20, 53, 9, 48, 80, 48, 34, 13, 75, 121, 49, 47, 118, 0, 103, 11, 68, 5, 4, 1, 48, 119, 48, 130, 55, 0, 0, 16, 70, 12, 20, 143, 48, 147, 133, 49, 35, 34, 13, 55, 137, 50, 0, 16, 70, 24, 83, 73, 56, 147, 133, 83, 121, 65, 13, 50, 122, 50, 0, 12, 69, 5, 52, 197, 77, 48, 119, 89, 121, 89, 0, 0, 17, 70, 88, 149, 1, 52, 147, 128, 84, 137, 47, 13, 65, 122, 50, 0, 103, 17, 70, 88, 149, 1, 52, 147, 128, 84, 137, 47, 13, 65, 123, 50, 0, 103, 16, 70, 88, 149, 1, 52, 147, 128, 84, 122, 47, 13, 65, 123, 50, 0, 14, 70, 80, 84, 146, 4, 147, 128, 47, 13, 34, 138, 50, 0, 15, 70, 29, 34, 70, 24, 243, 128, 81, 34, 122, 83, 13, 50, 0, 0, 24, 75, 72, 80, 207, 56, 224, 73, 77, 48, 78, 12, 80, 34, 113, 49, 124, 50, 122, 89, 13, 50, 89, 0, 0, 10, 67, 48, 81, 207, 55, 121, 81, 136, 0, 15, 70, 12, 193, 65, 57, 49, 82, 49, 55, 121, 50, 88, 114, 0, 11, 68, 4, 113, 210, 60, 35, 81, 34, 136, 0, 0, 14, 70, 52, 144, 200, 20, 195, 5, 65, 113, 91, 121, 55, 0, 13, 69, 5, 53, 12, 21, 144, 35, 89, 47, 55, 37, 0, 18, 70, 12, 20, 143, 48, 147, 129, 49, 35, 34, 13, 55, 6, 137, 50, 13, 0, 9, 198, 84, 208, 146, 20, 195, 1, 66, 15, 70, 80, 244, 148, 36, 195, 1, 47, 132, 47, 6, 129, 119, 0, 15, 69, 77, 80, 148, 49, 144, 89, 125, 47, 13, 55, 122, 0, 32, 17, 70, 72, 81, 137, 56, 84, 153, 34, 113, 83, 137, 50, 13, 34, 122, 0, 19, 8, 16, 9, 195, 177, 1, 20, 1, 19, 48, 129, 67, 6, 35, 47, 119, 88, 0, 13, 69, 52, 245, 84, 33, 48, 65, 135, 86, 88, 0, 9, 12, 201, 24, 244, 133, 76, 131, 210, 80, 83, 128, 66, 18, 70, 12, 243, 148, 72, 20, 153, 49, 124, 50, 47, 34, 140, 34, 37, 0, 103, 17, 70, 12, 243, 148, 72, 20, 153, 49, 124, 50, 47, 34, 13, 34, 122, 0, 12, 4, 95, 226, 128, 163, 71, 117, 55, 113, 47, 0, 0, 9, 198, 12, 243, 12, 20, 83, 128, 66, 19, 70, 25, 35, 206, 80, 83, 132, 83, 34, 6, 125, 50, 47, 4, 121, 50, 72, 0, 16, 4, 194, 182, 194, 182, 48, 35, 34, 13, 81, 34, 35, 83, 89, 0, 12, 4, 95, 226, 128, 162, 71, 117, 55, 113, 47, 0, 0, 10, 67, 4, 64, 64, 138, 72, 13, 0, 10, 18, 71, 12, 243, 15, 77, 49, 85, 52, 49, 124, 55, 13, 89, 6, 141, 65, 0, 15, 4, 95, 226, 128, 161, 72, 125, 71, 118, 72, 35, 81, 114, 0, 0, 11, 68, 48, 20, 197, 72, 55, 138, 88, 114, 0, 11, 68, 24, 147, 210, 16, 83, 129, 132, 72, 0, 16, 70, 8, 16, 203, 20, 225, 0, 71, 35, 49, 6, 121, 50, 72, 0, 11, 4, 95, 226, 128, 160, 72, 35, 81, 114, 0, 0, 12, 67, 92, 129, 78, 4, 58, 121, 50, 0, 15, 10, 12, 67, 92, 129, 78, 58, 2, 121, 50, 0, 12, 10, 16, 70, 65, 33, 78, 80, 144, 197, 48, 34, 121, 50, 108, 122, 89, 0, 14, 69, 36, 211, 199, 20, 224, 122, 65, 13, 75, 13, 50, 0, 8, 197, 4, 81, 197, 4, 224, 66, 0, 16, 70, 4, 225, 197, 48, 84, 192, 35, 50, 75, 13, 55, 129, 88, 0, 15, 7, 6, 1, 195, 167, 1, 4, 5, 83, 13, 89, 126, 72, 0, 15, 4, 95, 226, 128, 166, 122, 55, 6, 122, 48, 89, 122, 89, 0, 0, 13, 70, 12, 82, 76, 36, 66, 0, 49, 138, 55, 37, 0, 6, 195, 85, 48, 128, 17, 13, 4, 95, 226, 128, 165, 47, 134, 72, 124, 47, 89, 0, 0, 11, 68, 52, 148, 200, 4, 65, 129, 91, 13, 0, 10, 4, 95, 226, 128, 164, 72, 124, 47, 0, 0, 14, 69, 4, 193, 146, 20, 64, 35, 55, 83, 34, 113, 72, 0, 10, 67, 4, 192, 78, 35, 55, 13, 50, 0, 12, 69, 72, 82, 78, 20, 64, 34, 138, 50, 72, 0, 14, 69, 32, 21, 18, 20, 64, 107, 138, 47, 34, 123, 72, 0, 15, 4, 95, 226, 128, 155, 55, 121, 83, 47, 49, 58, 136, 47, 0, 0, 15, 70, 52, 83, 80, 32, 148, 192, 65, 121, 65, 83, 113, 89, 0, 13, 4, 95, 226, 128, 154, 55, 136, 49, 58, 136, 47, 0, 0, 15, 70, 76, 21, 67, 21, 0, 78, 89, 130, 89, 48, 13, 50, 0, 14, 4, 95, 226, 128, 153, 34, 137, 47, 49, 58, 136, 47, 0, 0, 14, 68, 28, 242, 78, 28, 4, 81, 136, 122, 68, 0, 12, 9, 10, 67, 4, 193, 67, 35, 55, 122, 49, 0, 14, 70, 48, 83, 208, 5, 33, 0, 55, 121, 48, 114, 72, 0, 10, 68, 28, 21, 71, 20, 81, 138, 75, 0, 15, 4, 95, 226, 128, 152, 55, 121, 83, 47, 49, 58, 136, 47, 0, 18, 4, 95, 4, 15, 20, 58, 122, 86, 72, 6, 124, 47, 119, 71, 125, 84, 0, 0, 14, 69, 76, 80, 193, 57, 64, 89, 129, 49, 13, 50, 47, 0, 14, 69, 21, 132, 5, 73, 64, 121, 49, 89, 48, 128, 47, 0, 13, 69, 4, 211, 213, 57, 64, 119, 65, 135, 50, 47, 0, 16, 4, 95, 226, 128, 159, 55, 121, 83, 47, 49, 58, 136, 47, 89, 0, 0, 18, 70, 81, 34, 66, 84, 224, 76, 47, 34, 137, 71, 6, 57, 134, 50, 118, 0, 16, 70, 77, 3, 207, 56, 97, 68, 89, 48, 134, 50, 83, 121, 72, 0, 11, 67, 56, 22, 137, 50, 126, 47, 89, 122, 0, 14, 70, 28, 148, 129, 24, 97, 64, 75, 113, 34, 120, 83, 0, 10, 67, 4, 64, 77, 35, 72, 13, 65, 0, 14, 4, 95, 226, 128, 158, 55, 136, 49, 58, 136, 47, 89, 0, 0, 11, 67, 76, 129, 64, 91, 129, 0, 72, 9, 33, 15, 4, 95, 226, 128, 157, 34, 137, 47, 49, 58, 136, 47, 89, 0, 15, 2, 95, 91, 55, 121, 83, 47, 71, 34, 35, 49, 113, 47, 0, 0, 16, 70, 65, 33, 67, 21, 5, 0, 48, 34, 129, 89, 121, 48, 47, 0, 11, 200, 52, 18, 78, 80, 18, 78, 21, 32, 66, 11, 68, 32, 82, 83, 80, 107, 137, 89, 47, 0, 16, 4, 95, 226, 128, 156, 55, 121, 83, 47, 49, 58, 136, 47, 89, 0, 0, 10, 67, 48, 83, 206, 55, 129, 124, 50, 0, 16, 70, 52, 148, 211, 61, 84, 137, 65, 122, 88, 6, 143, 34, 37, 0, 18, 70, 60, 34, 84, 84, 20, 153, 124, 71, 6, 122, 76, 117, 140, 37, 0, 103, 16, 70, 60, 34, 84, 84, 20, 153, 124, 71, 6, 122, 76, 143, 37, 0, 10, 67, 20, 65, 78, 129, 72, 13, 50, 0, 18, 70, 16, 147, 1, 80, 244, 153, 72, 122, 55, 35, 47, 149, 34, 122, 0, 103, 17, 70, 16, 147, 1, 80, 244, 153, 72, 122, 55, 13, 47, 13, 34, 122, 0, 14, 69, 12, 21, 143, 73, 64, 49, 119, 84, 6, 132, 47, 0, 10, 4, 95, 226, 128, 147, 72, 35, 91, 0, 0, 16, 70, 76, 243, 69, 60, 225, 64, 89, 125, 65, 58, 125, 50, 0, 106, 15, 70, 76, 243, 69, 60, 225, 64, 89, 125, 65, 58, 124, 50, 0, 19, 66, 76, 240, 89, 6, 136, 15, 65, 4, 125, 76, 0, 81, 109, 117, 99, 104, 32, 20, 66, 76, 240, 89, 4, 136, 15, 65, 6, 121, 50, 37, 0, 81, 109, 97, 110, 121, 32, 18, 66, 76, 240, 89, 6, 136, 15, 83, 4, 127, 0, 12, 81, 102, 97, 114, 32, 9, 66, 76, 240, 4, 89, 136, 0, 12, 15, 70, 65, 33, 84, 104, 83, 0, 48, 34, 121, 47, 89, 118, 0, 16, 70, 29, 33, 68, 36, 83, 148, 81, 34, 129, 72, 141, 50, 47, 0, 16, 70, 16, 80, 129, 12, 193, 64, 72, 138, 71, 6, 126, 49, 118, 0, 6, 194, 88, 144, 17, 42, 5, 194, 84, 176, 17, 10, 4, 95, 226, 128, 146, 72, 35, 91, 0, 0, 13, 70, 4, 19, 9, 100, 18, 0, 13, 55, 129, 13, 0, 12, 4, 95, 226, 128, 145, 107, 137, 83, 13, 50, 0, 14, 2, 95, 95, 6, 125, 50, 72, 114, 89, 49, 4, 133, 0, 0, 12, 68, 72, 148, 197, 56, 34, 122, 88, 13, 50, 0, 12, 68, 72, 85, 18, 100, 34, 129, 47, 34, 137, 0, 9, 67, 12, 130, 67, 91, 129, 49, 0, 11, 67, 4, 192, 83, 119, 55, 6, 35, 89, 0, 11, 4, 95, 226, 130, 160, 57, 143, 34, 136, 0, 12, 4, 95, 226, 128, 144, 107, 137, 83, 13, 50, 0, 17, 2, 95, 94, 89, 147, 49, 125, 65, 83, 55, 4, 121, 49, 89, 0, 105, 16, 2, 95, 94, 89, 128, 49, 125, 65, 83, 55, 4, 121, 49, 89, 0, 0, 6, 195, 76, 243, 206, 32, 15, 69, 8, 80, 193, 52, 80, 71, 122, 49, 138, 65, 0, 74, 12, 10, 67, 4, 65, 78, 138, 72, 13, 50, 0, 14, 69, 64, 20, 1, 100, 16, 48, 119, 48, 137, 38, 13, 0, 10, 67, 36, 51, 206, 137, 49, 124, 50, 0, 13, 69, 12, 19, 137, 56, 80, 49, 138, 50, 137, 50, 0, 14, 2, 95, 93, 34, 137, 47, 71, 34, 35, 49, 113, 47, 0, 0, 10, 67, 64, 84, 149, 48, 13, 34, 134, 0, 16, 70, 56, 18, 82, 60, 34, 64, 50, 137, 34, 6, 136, 71, 37, 0, 18, 70, 9, 81, 1, 64, 84, 212, 71, 134, 72, 13, 48, 6, 121, 89, 47, 0, 15, 70, 77, 83, 132, 36, 19, 0, 89, 125, 50, 72, 144, 55, 0, 9, 67, 76, 130, 65, 91, 129, 13, 0, 27, 74, 52, 144, 210, 60, 244, 135, 4, 226, 83, 52, 65, 137, 49, 34, 136, 6, 132, 81, 13, 50, 122, 88, 13, 65, 0, 15, 4, 95, 226, 128, 150, 72, 4, 125, 71, 118, 71, 6, 127, 0, 0, 20, 4, 95, 226, 128, 149, 107, 124, 34, 113, 88, 4, 124, 50, 47, 118, 71, 6, 127, 0, 0, 27, 68, 12, 245, 76, 16, 49, 117, 72, 107, 35, 84, 47, 116, 0, 74, 32, 12, 82, 104, 97, 118, 101, 32, 116, 111, 32, 21, 68, 12, 245, 76, 16, 49, 117, 72, 107, 35, 84, 0, 35, 14, 81, 104, 97, 118, 101, 32, 20, 68, 12, 245, 76, 16, 4, 49, 117, 72, 119, 84, 0, 35, 81, 104, 97, 118, 101, 32, 14, 68, 12, 245, 76, 16, 2, 49, 117, 72, 0, 32, 12, 9, 13, 68, 60, 20, 201, 76, 136, 6, 138, 89, 113, 89, 0, 12, 68, 16, 83, 79, 56, 72, 129, 65, 13, 50, 0, 11, 68, 12, 243, 69, 72, 49, 125, 65, 114, 0, 9, 68, 12, 241, 85, 72, 49, 128, 0, 12, 4, 95, 226, 128, 148, 121, 65, 72, 35, 91, 0, 0, 16, 70, 76, 19, 65, 57, 66, 1, 89, 13, 65, 35, 50, 87, 13, 0, 14, 69, 72, 85, 9, 56, 16, 34, 121, 47, 122, 50, 13, 0, 14, 69, 72, 81, 201, 52, 80, 34, 138, 90, 6, 129, 65, 0, 16, 70, 56, 84, 5, 57, 66, 5, 50, 113, 48, 121, 50, 87, 37, 0, 15, 69, 53, 85, 1, 80, 80, 65, 57, 134, 47, 6, 138, 47, 0, 23, 73, 4, 197, 5, 72, 224, 84, 20, 198, 64, 130, 55, 47, 6, 128, 50, 13, 47, 55, 122, 0, 32, 0, 9, 198, 61, 85, 2, 4, 50, 192, 65, 12, 2, 95, 96, 71, 35, 49, 48, 34, 137, 65, 0, 0, 20, 71, 48, 165, 66, 48, 160, 78, 4, 55, 57, 134, 71, 55, 57, 6, 126, 50, 13, 0, 17, 71, 76, 245, 78, 16, 34, 84, 20, 89, 135, 50, 72, 71, 137, 47, 0, 0, 11, 67, 60, 130, 79, 136, 107, 6, 137, 136, 0, 11, 68, 12, 18, 82, 60, 49, 137, 34, 136, 0, 9, 198, 61, 85, 13, 61, 53, 0, 65, 11, 68, 8, 20, 193, 48, 71, 138, 89, 118, 0, 20, 72, 5, 34, 84, 32, 209, 84, 36, 48, 119, 34, 122, 87, 65, 13, 47, 122, 49, 0, 0, 8, 67, 12, 129, 82, 91, 140, 0, 14, 69, 52, 244, 129, 77, 48, 65, 124, 34, 6, 35, 89, 0, 16, 70, 16, 148, 195, 37, 3, 5, 72, 122, 89, 6, 137, 48, 118, 0, 12, 69, 4, 148, 130, 85, 48, 140, 71, 125, 89, 0, 12, 4, 95, 51, 48, 15, 87, 6, 128, 47, 141, 0, 0, 11, 67, 81, 83, 129, 47, 57, 134, 50, 13, 0, 15, 70, 24, 195, 213, 72, 148, 200, 83, 55, 128, 113, 91, 0, 103, 15, 70, 24, 195, 213, 72, 148, 200, 83, 55, 125, 34, 113, 91, 0, 0, 9, 67, 72, 147, 192, 34, 129, 136, 0, 9, 198, 12, 243, 21, 52, 37, 83, 66, 9, 67, 48, 83, 192, 55, 129, 136, 0, 18, 71, 32, 84, 133, 80, 144, 193, 48, 107, 113, 34, 121, 47, 113, 49, 118, 0, 16, 70, 25, 34, 78, 28, 147, 135, 83, 34, 122, 50, 75, 122, 68, 0, 12, 201, 12, 131, 15, 72, 244, 12, 5, 53, 0, 65, 9, 67, 8, 147, 192, 71, 137, 136, 0, 8, 67, 4, 195, 64, 126, 65, 0, 0, 22, 72, 52, 243, 148, 28, 243, 69, 73, 144, 65, 124, 50, 47, 81, 6, 124, 65, 13, 34, 37, 0, 13, 68, 84, 229, 197, 16, 125, 50, 58, 6, 121, 72, 0, 20, 72, 69, 80, 84, 21, 35, 129, 73, 144, 49, 58, 13, 47, 128, 50, 13, 34, 122, 0, 11, 68, 32, 245, 212, 60, 107, 135, 47, 134, 0, 12, 68, 12, 243, 69, 80, 49, 124, 65, 113, 47, 0, 0, 14, 69, 13, 148, 18, 85, 48, 89, 137, 48, 34, 13, 89, 0, 13, 69, 36, 229, 18, 5, 144, 122, 50, 47, 34, 138, 0, 0, 15, 70, 52, 244, 143, 12, 51, 192, 65, 13, 34, 124, 49, 136, 0, 10, 67, 88, 148, 193, 84, 129, 88, 13, 0, 10, 67, 88, 20, 197, 84, 126, 88, 0, 135, 9, 198, 80, 240, 129, 12, 51, 192, 66, 5, 194, 100, 64, 17, 12, 4, 95, 7, 18, 22, 81, 34, 6, 126, 84, 0, 0, 10, 67, 20, 66, 84, 121, 72, 122, 47, 0, 0, 13, 68, 53, 83, 20, 36, 65, 125, 55, 47, 137, 0, 103, 13, 68, 4, 35, 214, 20, 13, 71, 125, 84, 0, 74, 12, 12, 68, 48, 18, 84, 100, 55, 138, 13, 47, 37, 0, 13, 68, 16, 82, 84, 100, 72, 129, 13, 108, 37, 0, 103, 12, 68, 16, 82, 84, 100, 72, 138, 13, 47, 37, 0, 12, 68, 8, 148, 207, 56, 71, 137, 89, 13, 50, 0, 0, 12, 69, 12, 129, 82, 100, 192, 91, 121, 34, 118, 0, 15, 69, 84, 229, 201, 56, 64, 125, 50, 58, 6, 137, 50, 72, 0, 17, 69, 48, 149, 133, 12, 64, 55, 6, 137, 84, 89, 129, 72, 6, 129, 0, 13, 69, 21, 36, 129, 56, 64, 121, 34, 13, 50, 72, 0, 0, 16, 70, 16, 243, 73, 56, 144, 192, 72, 124, 65, 113, 50, 122, 49, 0, 10, 67, 56, 20, 193, 50, 35, 89, 119, 0, 0, 11, 67, 4, 193, 88, 35, 55, 122, 49, 89, 0, 19, 67, 16, 84, 192, 72, 13, 65, 139, 50, 0, 81, 109, 111, 105, 110, 101, 115, 32, 12, 201, 4, 99, 210, 20, 209, 78, 80, 147, 206, 66, 0, 0, 13, 69, 28, 244, 208, 20, 192, 81, 124, 89, 48, 118, 0, 23, 73, 12, 128, 82, 37, 51, 65, 80, 144, 192, 49, 35, 34, 122, 89, 65, 6, 35, 47, 122, 49, 0, 12, 69, 12, 128, 80, 20, 192, 76, 35, 48, 118, 0, 9, 198, 4, 195, 19, 64, 144, 197, 65, 0, 15, 70, 52, 18, 197, 56, 224, 64, 65, 13, 49, 121, 50, 13, 0, 15, 70, 44, 19, 142, 4, 64, 64, 49, 126, 50, 13, 72, 13, 0, 16, 70, 8, 243, 15, 28, 224, 64, 71, 13, 55, 136, 50, 38, 13, 0, 17, 70, 60, 49, 65, 56, 144, 192, 136, 91, 122, 6, 35, 50, 122, 49, 0, 0, 9, 67, 12, 243, 208, 49, 134, 48, 0, 19, 71, 12, 243, 77, 84, 226, 84, 100, 49, 13, 65, 57, 134, 50, 113, 47, 37, 0, 23, 73, 5, 81, 205, 20, 229, 1, 80, 147, 206, 130, 81, 65, 121, 50, 47, 6, 138, 91, 13, 50, 0, 10, 199, 4, 229, 9, 12, 194, 78, 20, 65, 0, 22, 73, 56, 243, 69, 56, 51, 1, 81, 84, 133, 50, 13, 65, 121, 68, 49, 55, 13, 76, 114, 0, 12, 68, 12, 195, 211, 20, 49, 55, 136, 88, 0, 36, 12, 68, 12, 195, 211, 20, 49, 55, 136, 89, 0, 9, 21, 72, 4, 67, 79, 56, 149, 9, 60, 224, 35, 72, 65, 13, 50, 6, 122, 91, 13, 50, 0, 0, 9, 198, 76, 128, 78, 28, 128, 73, 66, 13, 69, 12, 195, 211, 21, 32, 49, 55, 136, 89, 114, 0, 12, 69, 9, 81, 134, 21, 64, 71, 125, 83, 138, 0, 16, 69, 4, 36, 197, 57, 64, 35, 71, 89, 6, 121, 50, 47, 0, 36, 15, 69, 4, 36, 197, 57, 64, 35, 71, 89, 13, 50, 47, 0, 10, 15, 69, 4, 36, 197, 57, 64, 35, 71, 89, 6, 121, 50, 47, 0, 0, 14, 70, 52, 144, 200, 20, 193, 64, 65, 113, 91, 121, 55, 0, 15, 70, 76, 80, 84, 80, 193, 64, 89, 129, 6, 35, 47, 118, 0, 14, 70, 12, 243, 15, 28, 225, 64, 49, 13, 55, 136, 50, 0, 0, 13, 2, 95, 123, 55, 121, 83, 47, 71, 34, 138, 89, 0, 13, 4, 95, 4, 9, 1, 6, 117, 65, 55, 135, 47, 0, 0, 18, 72, 81, 35, 213, 8, 17, 15, 85, 32, 47, 34, 134, 71, 13, 72, 133, 0, 12, 68, 20, 69, 67, 20, 113, 72, 57, 134, 89, 0, 9, 67, 8, 20, 211, 71, 138, 89, 0, 20, 4, 95, 226, 128, 188, 121, 49, 89, 49, 55, 119, 65, 6, 138, 91, 13, 50, 88, 0, 0, 15, 69, 16, 241, 83, 57, 64, 72, 125, 88, 13, 50, 47, 0, 32, 13, 69, 24, 243, 7, 21, 32, 83, 136, 55, 75, 114, 0, 16, 70, 88, 145, 206, 21, 69, 5, 84, 122, 50, 57, 6, 121, 47, 0, 16, 70, 76, 16, 143, 80, 17, 197, 89, 35, 71, 13, 47, 126, 90, 0, 16, 70, 36, 229, 5, 72, 225, 69, 122, 50, 47, 6, 128, 50, 129, 0, 23, 73, 12, 21, 1, 77, 68, 143, 64, 129, 64, 49, 119, 47, 35, 89, 47, 34, 13, 83, 2, 37, 0, 15, 4, 95, 226, 128, 179, 72, 125, 71, 118, 48, 34, 137, 65, 0, 0, 15, 70, 32, 244, 212, 36, 193, 64, 107, 124, 89, 47, 118, 0, 103, 14, 70, 24, 84, 148, 36, 193, 64, 83, 128, 47, 118, 0, 103, 9, 66, 80, 240, 47, 134, 0, 72, 42, 9, 66, 80, 240, 47, 134, 0, 72, 14, 23, 66, 80, 240, 47, 134, 13, 50, 72, 83, 34, 6, 136, 0, 82, 97, 110, 100, 32, 102, 114, 111, 32, 16, 66, 80, 240, 2, 47, 117, 10, 47, 116, 0, 32, 81, 116, 111, 32, 16, 66, 80, 240, 47, 13, 15, 6, 71, 129, 0, 14, 81, 98, 101, 32, 15, 66, 80, 240, 47, 13, 71, 2, 37, 0, 35, 81, 98, 101, 32, 8, 66, 80, 240, 47, 116, 0, 32, 7, 66, 100, 80, 57, 129, 0, 9, 198, 85, 1, 210, 4, 65, 64, 36, 10, 198, 85, 1, 210, 4, 65, 64, 65, 10, 11, 67, 65, 83, 153, 48, 57, 134, 50, 37, 0, 14, 70, 12, 128, 82, 4, 65, 64, 91, 119, 34, 126, 72, 0, 11, 4, 95, 226, 128, 178, 48, 34, 137, 65, 0, 0, 11, 67, 92, 134, 64, 4, 58, 137, 0, 12, 10, 9, 67, 20, 198, 64, 129, 55, 37, 0, 9, 198, 65, 35, 199, 72, 84, 211, 36, 18, 70, 65, 35, 199, 72, 84, 211, 48, 34, 124, 81, 34, 121, 89, 0, 103, 9, 17, 70, 65, 35, 199, 72, 84, 211, 48, 34, 136, 81, 34, 121, 89, 0, 9, 0, 13, 4, 95, 226, 128, 176, 48, 128, 65, 6, 129, 55, 0, 0, 14, 69, 28, 20, 129, 28, 80, 81, 119, 34, 126, 90, 0, 103, 13, 69, 16, 83, 137, 76, 80, 72, 13, 50, 129, 89, 0, 11, 69, 5, 32, 200, 36, 80, 127, 76, 37, 0, 16, 70, 12, 243, 15, 52, 34, 65, 49, 13, 55, 125, 65, 71, 141, 0, 16, 69, 8, 241, 207, 80, 16, 71, 136, 81, 13, 47, 6, 126, 0, 103, 15, 69, 8, 241, 207, 80, 16, 71, 124, 81, 13, 47, 6, 126, 0, 14, 69, 84, 224, 66, 48, 80, 125, 50, 6, 138, 71, 118, 0, 12, 2, 95, 125, 34, 137, 47, 71, 34, 138, 89, 0, 0, 8, 3, 19, 195, 173, 91, 129, 0, 19, 70, 12, 243, 148, 72, 20, 212, 49, 124, 50, 47, 34, 6, 35, 89, 47, 0, 36, 10, 2, 95, 124, 84, 129, 71, 6, 127, 0, 0, 13, 67, 92, 128, 84, 4, 58, 125, 47, 0, 103, 12, 10, 12, 67, 92, 128, 84, 4, 58, 124, 47, 0, 15, 10, 12, 67, 92, 128, 84, 58, 2, 124, 47, 0, 12, 10, 19, 71, 80, 83, 5, 64, 131, 206, 100, 47, 121, 55, 6, 121, 83, 13, 50, 37, 0, 0, 18, 70, 77, 80, 138, 20, 53, 0, 89, 125, 71, 75, 6, 121, 49, 47, 0, 36, 8, 67, 76, 129, 87, 91, 136, 0, 12, 68, 25, 85, 15, 56, 83, 134, 47, 124, 50, 0, 16, 70, 21, 21, 65, 80, 147, 206, 113, 49, 58, 138, 90, 13, 50, 0, 11, 68, 20, 98, 76, 20, 129, 83, 137, 55, 0, 14, 70, 12, 243, 15, 72, 81, 0, 49, 125, 55, 114, 72, 0, 9, 68, 4, 148, 204, 20, 144, 55, 0, 16, 4, 95, 226, 128, 180, 47, 34, 122, 48, 118, 48, 34, 137, 65, 0, 0, 12, 69, 76, 244, 8, 36, 80, 89, 136, 83, 37, 0, 15, 70, 4, 36, 201, 57, 66, 5, 35, 71, 89, 122, 50, 87, 0, 0, 16, 70, 61, 97, 82, 80, 198, 64, 136, 84, 6, 128, 47, 55, 122, 0, 0, 15, 71, 72, 145, 200, 80, 83, 213, 76, 34, 137, 76, 13, 89, 0, 18, 71, 72, 21, 9, 60, 224, 76, 20, 34, 35, 91, 13, 50, 6, 35, 55, 0, 0, 18, 70, 9, 80, 200, 4, 224, 78, 71, 57, 134, 49, 6, 35, 50, 13, 50, 0, 9, 67, 92, 129, 87, 83, 57, 134, 0, 0, 14, 69, 28, 192, 68, 101, 48, 81, 55, 35, 72, 122, 89, 0, 22, 73, 65, 54, 67, 32, 144, 84, 72, 148, 212, 89, 137, 49, 6, 144, 47, 34, 122, 89, 47, 0, 14, 69, 4, 48, 197, 77, 48, 35, 49, 89, 121, 89, 0, 36, 14, 69, 4, 48, 197, 77, 48, 35, 49, 89, 121, 89, 0, 10, 0, 9, 198, 76, 128, 77, 64, 243, 192, 66, 16, 70, 48, 243, 135, 4, 115, 192, 55, 124, 68, 81, 13, 81, 136, 0, 0, 17, 70, 32, 80, 146, 36, 65, 83, 107, 121, 71, 34, 13, 72, 129, 88, 0, 14, 70, 12, 130, 83, 92, 144, 203, 76, 122, 88, 122, 49, 0, 0, 10, 67, 76, 147, 15, 89, 137, 55, 136, 0, 11, 68, 61, 85, 5, 16, 135, 47, 123, 72, 0, 16, 70, 52, 145, 5, 5, 53, 0, 65, 122, 72, 6, 129, 89, 47, 0, 12, 68, 4, 226, 77, 20, 35, 50, 122, 65, 138, 0, 0, 0, 9, 198, 76, 21, 129, 56, 224, 72, 66, 16, 70, 12, 16, 133, 72, 225, 84, 49, 35, 71, 114, 50, 6, 138, 0, 6, 194, 84, 224, 17, 42, 0, 20, 67, 92, 19, 12, 58, 6, 130, 55, 89, 47, 34, 4, 129, 47, 0, 81, 115, 116, 32, 9, 67, 64, 243, 12, 48, 136, 55, 0, 18, 71, 64, 145, 67, 20, 209, 65, 48, 48, 6, 129, 89, 65, 4, 129, 55, 0, 20, 71, 4, 197, 77, 36, 226, 85, 52, 35, 55, 57, 117, 65, 6, 122, 50, 141, 65, 0, 0, 10, 67, 80, 241, 15, 47, 13, 72, 134, 0, 11, 68, 76, 21, 68, 36, 89, 135, 72, 37, 0, 0, 15, 69, 64, 243, 9, 76, 128, 48, 136, 55, 122, 91, 0, 41, 9, 13, 69, 5, 33, 217, 48, 192, 127, 81, 38, 137, 55, 0, 13, 69, 73, 81, 199, 20, 64, 34, 125, 81, 123, 72, 0, 9, 197, 72, 80, 193, 48, 192, 66, 36, 13, 69, 72, 80, 193, 48, 192, 34, 129, 49, 130, 55, 0, 13, 69, 48, 144, 200, 20, 224, 55, 137, 49, 13, 50, 0, 14, 69, 9, 83, 137, 60, 224, 71, 125, 50, 113, 13, 50, 0, 0, 14, 70, 64, 149, 5, 61, 84, 192, 48, 122, 47, 141, 89, 0, 17, 70, 5, 50, 65, 80, 144, 192, 138, 91, 122, 6, 35, 47, 122, 49, 0, 0, 18, 71, 80, 81, 4, 100, 33, 65, 72, 47, 6, 121, 72, 122, 71, 4, 140, 0, 18, 71, 16, 19, 132, 20, 194, 79, 56, 72, 35, 50, 72, 113, 55, 144, 50, 0, 0, 12, 68, 12, 195, 212, 32, 49, 55, 136, 86, 0, 36, 12, 68, 8, 20, 201, 76, 71, 138, 89, 122, 89, 0, 0, 14, 69, 105, 84, 137, 12, 128, 88, 57, 117, 34, 122, 49, 0, 11, 67, 85, 64, 78, 134, 47, 6, 35, 50, 0, 13, 69, 72, 81, 201, 60, 224, 34, 129, 75, 13, 50, 0, 15, 69, 28, 147, 5, 4, 64, 81, 6, 122, 55, 122, 35, 72, 0, 0, 15, 70, 52, 147, 133, 73, 96, 64, 65, 113, 50, 128, 84, 13, 0, 0, 16, 71, 52, 83, 2, 61, 84, 142, 20, 65, 121, 55, 71, 114, 50, 0, 11, 67, 61, 1, 68, 124, 48, 6, 121, 72, 0, 18, 71, 4, 49, 84, 100, 193, 78, 20, 119, 89, 121, 47, 13, 55, 129, 50, 0, 0, 6, 195, 97, 134, 0, 17, 0, 17, 70, 21, 53, 9, 52, 21, 5, 121, 89, 47, 113, 65, 138, 47, 0, 36, 14, 69, 12, 195, 211, 21, 64, 49, 55, 124, 88, 113, 47, 0, 0, 14, 70, 48, 82, 83, 85, 33, 64, 55, 129, 90, 114, 0, 103, 13, 70, 48, 82, 83, 85, 33, 64, 55, 121, 90, 114, 0, 11, 4, 95, 35, 51, 50, 89, 48, 138, 89, 0, 0, 11, 67, 85, 64, 72, 57, 134, 108, 131, 0, 103, 10, 67, 85, 64, 72, 57, 134, 108, 126, 0, 0, 13, 68, 4, 211, 206, 28, 119, 65, 125, 68, 0, 74, 12, 10, 67, 44, 147, 15, 49, 129, 55, 136, 0, 12, 68, 4, 114, 83, 80, 138, 75, 122, 89, 47, 0, 0, 14, 69, 65, 33, 83, 21, 64, 48, 34, 129, 89, 121, 47, 0, 13, 69, 33, 83, 135, 21, 32, 107, 125, 68, 81, 114, 0, 9, 198, 21, 53, 18, 4, 225, 197, 66, 13, 69, 13, 85, 15, 85, 64, 49, 125, 47, 135, 47, 0, 13, 69, 12, 243, 135, 21, 32, 49, 124, 68, 81, 114, 0, 12, 69, 8, 243, 199, 21, 32, 71, 117, 81, 114, 0, 0, 15, 70, 76, 129, 82, 36, 97, 128, 91, 6, 121, 34, 113, 83, 0, 14, 70, 76, 49, 80, 81, 33, 64, 89, 121, 48, 47, 114, 0, 15, 70, 52, 16, 200, 21, 65, 64, 65, 119, 91, 121, 47, 37, 0, 14, 70, 5, 36, 197, 56, 19, 0, 127, 89, 13, 50, 118, 0, 0, 0, 12, 68, 72, 84, 201, 56, 34, 121, 88, 122, 50, 0, 0, 13, 69, 24, 19, 73, 56, 80, 83, 35, 65, 122, 50, 0, 9, 198, 4, 229, 9, 8, 241, 25, 65, 18, 70, 4, 36, 197, 57, 66, 65, 35, 71, 89, 6, 121, 50, 108, 129, 13, 0, 0, 17, 70, 36, 228, 85, 37, 38, 64, 122, 50, 49, 58, 13, 34, 37, 0, 103, 19, 70, 36, 225, 9, 72, 80, 212, 122, 50, 72, 114, 34, 6, 121, 49, 47, 0, 103, 9, 198, 36, 225, 9, 72, 80, 212, 67, 9, 198, 24, 20, 133, 92, 83, 12, 66, 9, 198, 12, 243, 148, 72, 16, 212, 36, 10, 198, 12, 243, 148, 72, 16, 212, 65, 10, 9, 67, 9, 34, 69, 71, 34, 129, 0, 0, 15, 67, 92, 147, 12, 58, 122, 55, 47, 116, 0, 81, 116, 111, 32, 9, 195, 92, 147, 12, 76, 9, 32, 12, 10, 199, 88, 19, 131, 61, 85, 133, 72, 66, 17, 70, 72, 129, 84, 61, 34, 67, 34, 121, 47, 13, 34, 122, 49, 0, 10, 19, 71, 36, 224, 78, 36, 208, 84, 20, 122, 50, 6, 35, 50, 122, 65, 13, 47, 0, 20, 71, 36, 115, 143, 72, 19, 85, 76, 122, 81, 50, 133, 34, 6, 138, 65, 13, 89, 0, 0, 22, 72, 64, 19, 5, 77, 66, 78, 36, 16, 48, 35, 55, 13, 89, 47, 6, 122, 50, 129, 13, 0, 21, 72, 12, 147, 131, 36, 227, 129, 80, 144, 89, 122, 50, 89, 122, 50, 6, 35, 47, 37, 0, 17, 70, 16, 148, 213, 76, 81, 0, 72, 122, 89, 6, 57, 134, 88, 72, 0, 6, 195, 4, 65, 147, 17, 0, 15, 69, 100, 19, 65, 32, 16, 57, 126, 65, 13, 107, 126, 0, 103, 14, 69, 100, 19, 65, 32, 16, 57, 35, 65, 13, 107, 126, 0, 23, 73, 72, 85, 1, 48, 144, 84, 61, 38, 64, 34, 113, 47, 35, 55, 129, 13, 47, 13, 34, 122, 0, 23, 73, 72, 84, 208, 37, 32, 84, 61, 38, 64, 34, 121, 89, 48, 34, 13, 47, 149, 34, 37, 0, 103, 23, 73, 72, 84, 208, 37, 32, 84, 61, 38, 64, 34, 113, 89, 48, 122, 34, 13, 47, 13, 34, 122, 0, 13, 69, 64, 84, 149, 76, 80, 48, 13, 34, 134, 88, 0, 15, 69, 16, 148, 213, 76, 80, 72, 122, 89, 6, 57, 134, 89, 0, 0, 9, 198, 61, 85, 12, 60, 242, 192, 65, 5, 194, 97, 144, 17, 0, 18, 71, 4, 227, 206, 100, 211, 213, 76, 119, 50, 124, 50, 13, 65, 13, 89, 0, 6, 195, 5, 67, 64, 17, 0, 14, 68, 16, 242, 78, 28, 4, 72, 134, 122, 68, 0, 12, 9, 20, 72, 72, 80, 207, 53, 1, 78, 76, 80, 34, 121, 49, 13, 65, 48, 121, 50, 89, 0, 20, 72, 16, 81, 137, 56, 149, 9, 88, 80, 72, 113, 83, 122, 50, 113, 47, 122, 84, 0, 10, 68, 8, 242, 78, 28, 71, 139, 68, 0, 0, 15, 69, 52, 145, 4, 5, 144, 65, 4, 122, 72, 72, 6, 138, 0, 13, 69, 24, 17, 67, 21, 48, 83, 129, 89, 129, 88, 0, 0, 10, 67, 28, 19, 1, 81, 126, 55, 13, 0, 0, 0, 12, 68, 12, 197, 217, 16, 49, 55, 134, 122, 72, 0, 18, 72, 72, 83, 132, 21, 165, 143, 85, 48, 34, 124, 50, 72, 113, 84, 134, 0, 0, 16, 70, 88, 243, 1, 80, 147, 5, 84, 124, 55, 119, 47, 118, 0, 103, 9, 198, 44, 83, 148, 84, 50, 217, 66, 14, 69, 72, 83, 69, 17, 144, 34, 121, 65, 13, 72, 37, 0, 17, 70, 64, 20, 129, 8, 243, 1, 48, 13, 34, 35, 71, 13, 55, 13, 0, 0, 11, 67, 60, 18, 21, 136, 6, 126, 107, 134, 0, 15, 70, 48, 147, 131, 60, 195, 128, 55, 122, 50, 49, 13, 50, 0, 16, 70, 36, 229, 5, 72, 225, 84, 122, 50, 47, 114, 50, 121, 47, 0, 0, 18, 67, 92, 149, 8, 58, 2, 122, 86, 86, 115, 0, 34, 81, 116, 104, 101, 32, 10, 67, 92, 149, 8, 58, 122, 86, 0, 72, 8, 67, 5, 52, 192, 35, 89, 0, 0, 17, 70, 36, 229, 5, 73, 97, 78, 122, 50, 47, 114, 84, 6, 129, 50, 0, 15, 70, 12, 243, 77, 20, 229, 0, 49, 124, 65, 121, 50, 47, 0, 0, 15, 70, 12, 19, 12, 36, 244, 5, 49, 119, 55, 144, 48, 37, 0, 13, 69, 16, 19, 137, 76, 128, 72, 138, 50, 122, 91, 0, 13, 69, 72, 17, 199, 20, 64, 34, 35, 81, 123, 72, 0, 13, 69, 40, 17, 199, 20, 64, 75, 35, 81, 123, 72, 0, 13, 69, 16, 241, 199, 20, 64, 72, 124, 81, 123, 72, 0, 0, 12, 70, 40, 16, 209, 84, 84, 192, 90, 35, 49, 0, 14, 70, 12, 128, 83, 76, 148, 192, 76, 35, 89, 37, 0, 103, 13, 70, 12, 128, 83, 76, 148, 192, 91, 35, 89, 37, 0, 6, 195, 57, 148, 197, 17, 0, 17, 71, 8, 81, 84, 32, 245, 133, 56, 71, 138, 108, 136, 84, 13, 50, 0, 0, 10, 68, 61, 85, 5, 72, 135, 47, 114, 0, 15, 70, 12, 243, 77, 20, 225, 0, 49, 13, 65, 121, 50, 72, 0, 12, 68, 5, 4, 143, 56, 138, 48, 34, 13, 50, 0, 0, 14, 69, 52, 84, 131, 20, 64, 65, 128, 89, 6, 121, 72, 0, 16, 69, 8, 83, 135, 4, 192, 71, 4, 121, 50, 81, 6, 130, 55, 0, 13, 69, 92, 83, 23, 100, 224, 58, 121, 55, 122, 50, 0, 12, 69, 92, 147, 135, 20, 64, 58, 122, 68, 72, 0, 12, 69, 64, 147, 135, 20, 64, 48, 122, 68, 72, 0, 14, 69, 24, 244, 141, 36, 64, 83, 132, 65, 6, 122, 72, 0, 13, 69, 8, 19, 135, 20, 64, 71, 35, 68, 81, 72, 0, 0, 9, 67, 76, 149, 5, 89, 137, 47, 0, 9, 198, 60, 211, 137, 9, 84, 192, 65, 16, 70, 52, 147, 137, 9, 84, 192, 65, 122, 50, 122, 71, 125, 89, 0, 0, 9, 67, 33, 85, 192, 107, 57, 134, 0, 17, 71, 64, 20, 211, 20, 225, 197, 72, 48, 35, 89, 113, 50, 75, 114, 0, 17, 71, 12, 128, 77, 64, 17, 206, 20, 91, 35, 65, 48, 6, 138, 50, 0, 0, 0, 13, 69, 44, 147, 20, 21, 32, 49, 122, 55, 47, 114, 0, 10, 67, 12, 19, 22, 49, 35, 84, 0, 103, 9, 67, 12, 19, 22, 49, 126, 84, 0, 0, 9, 198, 16, 84, 208, 37, 65, 64, 8, 11, 67, 92, 22, 25, 58, 35, 49, 89, 37, 0, 15, 70, 72, 84, 212, 37, 97, 64, 34, 121, 89, 47, 122, 84, 0, 10, 198, 52, 19, 132, 5, 65, 64, 66, 36, 16, 70, 16, 85, 5, 57, 65, 64, 72, 138, 47, 6, 124, 50, 47, 0, 0, 31, 7, 13, 21, 19, 20, 14, 39, 20, 65, 6, 125, 89, 50, 47, 107, 35, 84, 47, 116, 0, 35, 82, 104, 97, 118, 101, 32, 116, 111, 32, 26, 7, 13, 21, 19, 20, 14, 39, 20, 65, 125, 89, 50, 47, 107, 119, 84, 0, 35, 77, 81, 104, 97, 118, 101, 32, 16, 7, 13, 21, 19, 20, 14, 39, 20, 65, 125, 89, 50, 47, 0, 32, 0, 32, 8, 23, 15, 21, 12, 4, 14, 39, 20, 4, 58, 117, 72, 50, 47, 35, 84, 47, 116, 0, 32, 12, 82, 104, 97, 118, 101, 32, 116, 111, 32, 27, 8, 23, 15, 21, 12, 4, 14, 39, 20, 58, 117, 72, 50, 47, 13, 84, 0, 73, 35, 12, 81, 104, 97, 118, 101, 32, 11, 68, 13, 84, 147, 20, 49, 148, 89, 0, 105, 10, 68, 13, 84, 147, 20, 49, 128, 89, 0, 0, 33, 9, 19, 8, 15, 21, 12, 4, 14, 39, 20, 6, 91, 117, 72, 50, 47, 35, 84, 47, 116, 0, 32, 12, 82, 104, 97, 118, 101, 32, 116, 111, 32, 28, 9, 19, 8, 15, 21, 12, 4, 14, 39, 20, 91, 117, 72, 50, 47, 107, 13, 84, 0, 35, 77, 81, 104, 97, 118, 101, 32, 21, 9, 19, 8, 15, 21, 12, 4, 14, 39, 20, 4, 91, 117, 72, 50, 47, 0, 32, 12, 9, 14, 69, 21, 129, 84, 21, 32, 121, 49, 89, 122, 47, 114, 0, 17, 70, 21, 132, 5, 16, 149, 5, 121, 49, 89, 48, 13, 72, 137, 47, 0, 16, 70, 16, 84, 207, 48, 21, 5, 72, 121, 89, 13, 55, 13, 47, 0, 17, 70, 12, 242, 78, 12, 145, 5, 49, 136, 122, 50, 89, 6, 137, 72, 0, 0, 14, 70, 56, 20, 146, 5, 65, 64, 50, 119, 34, 138, 47, 0, 0, 18, 71, 76, 16, 210, 36, 98, 67, 20, 89, 35, 49, 34, 113, 83, 137, 89, 0, 0, 11, 200, 4, 229, 9, 52, 21, 20, 21, 32, 65, 12, 68, 4, 226, 79, 56, 35, 50, 138, 13, 50, 0, 21, 72, 4, 225, 77, 60, 209, 84, 21, 32, 35, 50, 122, 65, 6, 124, 65, 113, 47, 114, 0, 0, 15, 69, 80, 35, 9, 76, 144, 47, 14, 71, 55, 129, 89, 37, 0, 12, 201, 77, 80, 143, 72, 66, 78, 5, 65, 64, 66, 13, 69, 76, 80, 78, 12, 80, 89, 138, 124, 50, 89, 0, 11, 67, 61, 129, 78, 124, 49, 89, 13, 50, 0, 0, 10, 67, 64, 243, 25, 48, 124, 55, 122, 0, 9, 67, 4, 70, 133, 35, 72, 88, 0, 16, 70, 4, 34, 76, 37, 70, 64, 119, 71, 122, 55, 13, 47, 37, 0, 10, 3, 9, 46, 5, 137, 129, 11, 0, 8, 0, 15, 70, 77, 2, 78, 4, 50, 0, 89, 48, 122, 50, 113, 76, 0, 18, 71, 65, 33, 68, 36, 48, 84, 20, 48, 34, 121, 72, 113, 49, 138, 47, 0, 19, 71, 64, 243, 25, 4, 210, 68, 20, 48, 124, 55, 122, 6, 138, 65, 137, 72, 0, 0, 12, 68, 28, 20, 197, 76, 81, 35, 89, 123, 88, 0, 0, 17, 70, 56, 80, 146, 5, 50, 193, 50, 13, 71, 34, 35, 89, 49, 13, 0, 14, 69, 88, 17, 201, 56, 16, 84, 13, 75, 137, 50, 13, 0, 9, 198, 52, 243, 69, 57, 69, 77, 66, 8, 197, 16, 243, 73, 56, 240, 65, 0, 24, 74, 36, 224, 80, 65, 35, 208, 72, 144, 84, 20, 4, 122, 50, 119, 48, 34, 136, 48, 34, 141, 47, 0, 0, 18, 71, 4, 197, 5, 72, 224, 84, 20, 130, 55, 47, 114, 50, 138, 47, 0, 36, 19, 71, 4, 197, 5, 72, 224, 84, 20, 130, 55, 47, 6, 128, 50, 13, 47, 0, 9, 0, 20, 72, 21, 146, 129, 24, 160, 76, 48, 16, 138, 57, 119, 83, 57, 35, 47, 55, 119, 0, 11, 68, 17, 85, 133, 80, 72, 134, 84, 138, 0, 0, 15, 69, 16, 148, 195, 85, 48, 72, 122, 89, 49, 13, 89, 0, 9, 0, 15, 70, 36, 229, 5, 73, 96, 76, 122, 50, 47, 114, 84, 118, 0, 6, 195, 36, 212, 9, 65, 10, 67, 32, 244, 9, 107, 136, 48, 129, 0, 0, 0, 10, 67, 48, 242, 83, 55, 136, 122, 89, 0, 11, 68, 8, 163, 210, 56, 71, 57, 132, 50, 0, 21, 72, 65, 149, 8, 4, 115, 210, 5, 48, 48, 137, 87, 6, 35, 81, 13, 34, 13, 89, 0, 0, 13, 69, 56, 20, 12, 21, 48, 50, 138, 48, 118, 88, 0, 14, 69, 52, 17, 18, 5, 48, 65, 13, 72, 34, 120, 89, 0, 13, 69, 88, 84, 147, 85, 48, 84, 128, 89, 113, 88, 0, 14, 69, 61, 97, 82, 49, 144, 136, 84, 114, 55, 122, 0, 9, 0, 0, 8, 67, 100, 80, 64, 57, 138, 0, 0, 21, 72, 48, 16, 143, 72, 21, 15, 73, 144, 55, 35, 71, 34, 13, 47, 130, 34, 37, 0, 103, 12, 68, 20, 210, 76, 100, 121, 65, 113, 55, 37, 0, 10, 198, 80, 244, 141, 20, 229, 0, 66, 36, 9, 198, 80, 244, 141, 20, 229, 0, 65, 21, 72, 48, 16, 143, 72, 21, 15, 73, 144, 55, 119, 71, 6, 124, 34, 13, 47, 34, 122, 0, 0, 15, 70, 48, 21, 210, 20, 224, 197, 55, 124, 34, 13, 50, 89, 0, 0, 15, 70, 52, 147, 9, 80, 144, 64, 65, 13, 55, 122, 91, 13, 0, 0, 17, 71, 33, 84, 146, 36, 48, 78, 20, 107, 128, 13, 49, 138, 50, 0, 103, 17, 71, 33, 84, 146, 36, 48, 78, 20, 107, 125, 34, 113, 49, 138, 50, 0, 17, 71, 12, 128, 77, 20, 193, 79, 56, 49, 13, 65, 129, 55, 141, 50, 0, 6, 195, 12, 144, 64, 17, 0, 13, 68, 92, 129, 82, 20, 4, 58, 140, 0, 8, 12, 10, 12, 68, 40, 84, 213, 76, 75, 129, 88, 13, 89, 0, 12, 68, 81, 81, 15, 72, 47, 57, 134, 72, 114, 0, 9, 198, 52, 19, 139, 36, 225, 0, 66, 12, 68, 44, 147, 211, 44, 49, 129, 124, 89, 49, 0, 12, 68, 40, 84, 213, 76, 75, 129, 88, 13, 89, 0, 10, 68, 24, 246, 69, 72, 83, 139, 138, 0, 8, 67, 12, 144, 79, 76, 135, 0, 0, 8, 197, 36, 225, 210, 36, 64, 65, 15, 69, 72, 81, 149, 56, 64, 34, 129, 83, 125, 50, 72, 0, 37, 14, 6, 195, 169, 12, 9, 20, 5, 122, 55, 6, 129, 47, 0, 0, 15, 70, 12, 240, 200, 48, 80, 64, 49, 124, 49, 55, 129, 13, 0, 0, 18, 71, 48, 193, 87, 20, 195, 25, 56, 105, 13, 58, 6, 121, 55, 122, 50, 0, 6, 195, 76, 17, 64, 17, 0, 0, 12, 69, 44, 244, 200, 21, 32, 49, 136, 91, 114, 0, 12, 69, 12, 243, 208, 21, 32, 49, 134, 48, 114, 0, 0, 9, 198, 8, 82, 74, 36, 225, 192, 66, 9, 198, 28, 243, 196, 9, 145, 64, 66, 14, 70, 21, 97, 78, 36, 225, 192, 129, 84, 50, 122, 68, 0, 16, 70, 4, 48, 68, 20, 209, 64, 119, 49, 35, 72, 13, 65, 37, 0, 15, 70, 4, 36, 197, 56, 49, 64, 35, 71, 89, 13, 50, 89, 0, 0, 18, 71, 9, 33, 65, 44, 96, 83, 80, 71, 34, 121, 49, 83, 13, 89, 47, 0, 0, 21, 72, 77, 80, 147, 21, 21, 69, 57, 64, 89, 125, 71, 89, 113, 49, 58, 13, 50, 47, 0, 11, 68, 56, 245, 193, 100, 50, 136, 58, 138, 0, 10, 67, 52, 83, 79, 65, 121, 65, 136, 0, 0, 13, 67, 4, 209, 78, 4, 138, 65, 6, 121, 50, 0, 103, 9, 197, 36, 225, 15, 61, 32, 65, 9, 13, 67, 4, 209, 78, 4, 126, 65, 6, 121, 50, 0, 10, 13, 69, 4, 114, 1, 77, 64, 119, 81, 120, 89, 47, 0, 0, 18, 70, 28, 85, 20, 36, 225, 192, 4, 81, 121, 47, 122, 68, 0, 12, 35, 9, 14, 70, 77, 81, 134, 36, 49, 64, 89, 13, 83, 137, 89, 0, 14, 70, 72, 80, 68, 36, 225, 192, 34, 129, 72, 122, 68, 0, 14, 70, 64, 19, 12, 36, 225, 192, 48, 35, 55, 122, 68, 0, 15, 70, 16, 84, 129, 56, 113, 64, 72, 113, 34, 138, 50, 75, 0, 0, 9, 67, 92, 146, 64, 58, 129, 12, 0, 15, 70, 4, 195, 5, 72, 114, 67, 119, 55, 128, 75, 122, 49, 0, 0, 11, 68, 84, 224, 204, 20, 125, 68, 49, 118, 0, 15, 7, 15, 39, 3, 12, 15, 3, 11, 13, 49, 55, 124, 49, 0, 11, 68, 56, 244, 201, 72, 50, 136, 89, 128, 0, 13, 68, 48, 241, 207, 56, 55, 124, 81, 6, 124, 50, 0, 0, 13, 69, 16, 245, 1, 28, 80, 72, 136, 47, 113, 75, 0, 6, 195, 85, 52, 210, 17, 0, 16, 70, 76, 80, 210, 20, 54, 64, 89, 129, 49, 34, 13, 89, 37, 0, 16, 70, 21, 53, 15, 65, 1, 76, 121, 89, 47, 6, 124, 48, 118, 0, 9, 198, 5, 32, 200, 92, 22, 64, 65, 0, 9, 67, 92, 131, 204, 107, 136, 55, 0, 17, 71, 32, 22, 129, 72, 67, 213, 76, 107, 35, 88, 114, 72, 13, 89, 0, 18, 71, 20, 69, 193, 72, 66, 65, 56, 121, 72, 58, 6, 132, 72, 141, 50, 0, 0, 19, 67, 16, 241, 83, 72, 125, 88, 50, 124, 47, 0, 32, 78, 81, 110, 111, 116, 32, 10, 67, 16, 241, 83, 72, 125, 88, 0, 32, 13, 68, 20, 194, 90, 4, 122, 55, 6, 137, 88, 13, 0, 10, 68, 52, 22, 65, 56, 65, 144, 50, 0, 15, 70, 12, 16, 129, 72, 85, 0, 49, 35, 71, 13, 34, 138, 0, 11, 68, 8, 20, 212, 20, 71, 138, 89, 47, 0, 0, 13, 69, 48, 80, 78, 56, 80, 55, 129, 6, 35, 50, 0, 13, 69, 24, 18, 78, 56, 80, 83, 35, 50, 38, 13, 0, 14, 69, 76, 245, 197, 80, 240, 89, 13, 58, 121, 47, 136, 0, 15, 69, 52, 242, 129, 88, 80, 65, 136, 107, 6, 126, 84, 37, 0, 14, 69, 52, 19, 137, 48, 16, 65, 119, 50, 122, 55, 13, 0, 10, 67, 44, 145, 86, 49, 129, 121, 83, 0, 14, 69, 12, 19, 129, 16, 16, 49, 35, 50, 13, 72, 13, 0, 16, 70, 29, 32, 70, 24, 149, 9, 81, 34, 119, 83, 129, 47, 37, 0, 9, 67, 16, 241, 82, 72, 134, 114, 0, 0, 9, 67, 20, 211, 65, 121, 65, 13, 0, 9, 67, 92, 131, 193, 107, 58, 136, 0, 0, 13, 67, 92, 131, 192, 4, 107, 134, 0, 32, 8, 12, 10, 16, 70, 52, 19, 4, 37, 97, 83, 65, 130, 55, 72, 6, 129, 84, 0, 19, 71, 36, 225, 15, 12, 130, 78, 4, 122, 50, 72, 136, 76, 6, 137, 50, 13, 0, 19, 71, 12, 243, 150, 60, 197, 84, 20, 49, 124, 50, 84, 13, 55, 6, 134, 47, 0, 9, 67, 4, 67, 192, 119, 72, 134, 0, 0, 16, 70, 52, 18, 13, 61, 81, 0, 65, 35, 101, 65, 6, 134, 72, 0, 0, 16, 70, 77, 80, 144, 60, 83, 129, 89, 134, 48, 6, 129, 50, 13, 0, 12, 69, 5, 32, 200, 21, 48, 127, 76, 123, 88, 0, 0, 16, 70, 4, 36, 129, 32, 19, 64, 138, 71, 34, 13, 107, 35, 65, 0, 25, 74, 36, 225, 5, 80, 84, 141, 36, 224, 84, 20, 122, 50, 72, 113, 47, 6, 128, 65, 113, 50, 13, 47, 0, 12, 201, 4, 208, 137, 16, 86, 20, 72, 245, 83, 67, 0, 17, 70, 65, 148, 133, 56, 81, 83, 48, 122, 34, 13, 50, 6, 129, 88, 0, 0, 13, 68, 4, 35, 213, 80, 119, 71, 135, 47, 0, 74, 12, 9, 67, 76, 22, 83, 89, 121, 88, 0, 20, 72, 5, 32, 200, 36, 209, 68, 21, 48, 127, 49, 122, 65, 6, 129, 72, 129, 88, 0, 0, 13, 69, 5, 66, 5, 57, 48, 35, 87, 113, 50, 88, 0, 15, 69, 76, 147, 135, 49, 144, 89, 122, 68, 81, 55, 122, 0, 32, 0, 9, 67, 20, 211, 89, 121, 65, 37, 0, 16, 70, 48, 84, 207, 80, 131, 192, 55, 13, 89, 6, 134, 47, 134, 0, 0, 17, 71, 92, 21, 5, 73, 50, 5, 16, 58, 130, 47, 114, 91, 121, 72, 0, 0, 16, 70, 80, 83, 5, 64, 131, 206, 47, 121, 55, 113, 83, 136, 50, 0, 13, 68, 72, 80, 83, 44, 34, 129, 6, 120, 89, 49, 0, 12, 68, 48, 241, 201, 56, 55, 124, 81, 122, 50, 0, 12, 68, 8, 244, 213, 56, 71, 136, 89, 13, 50, 0, 0, 13, 69, 80, 20, 137, 24, 96, 47, 35, 34, 122, 83, 0, 0, 17, 70, 64, 19, 129, 12, 80, 64, 48, 35, 50, 119, 89, 6, 129, 13, 0, 0, 0, 20, 68, 80, 129, 82, 20, 86, 2, 140, 4, 58, 128, 0, 11, 81, 119, 101, 114, 101, 32, 16, 68, 80, 129, 82, 20, 86, 140, 71, 6, 129, 0, 81, 98, 101, 32, 18, 68, 80, 129, 82, 20, 86, 2, 140, 4, 127, 0, 11, 81, 97, 114, 101, 32, 12, 68, 80, 129, 82, 20, 86, 140, 0, 72, 12, 9, 12, 68, 72, 81, 201, 76, 34, 129, 75, 113, 89, 0, 11, 68, 80, 129, 84, 4, 87, 129, 47, 13, 0, 12, 68, 48, 20, 211, 60, 55, 35, 89, 136, 0, 103, 12, 68, 48, 20, 211, 60, 55, 35, 89, 6, 134, 0, 0, 0, 0, 10, 67, 20, 213, 64, 129, 65, 57, 134, 0, 0, 18, 72, 72, 144, 207, 12, 129, 84, 20, 64, 34, 122, 49, 13, 91, 138, 72, 0, 11, 68, 32, 245, 83, 20, 107, 135, 88, 0, 36, 15, 70, 12, 240, 85, 80, 131, 210, 49, 136, 6, 130, 87, 114, 0, 0, 13, 69, 77, 84, 133, 77, 64, 91, 143, 13, 89, 47, 0, 12, 69, 76, 16, 200, 21, 64, 89, 35, 91, 138, 0, 12, 69, 72, 20, 9, 21, 32, 34, 138, 48, 142, 0, 15, 69, 36, 228, 197, 73, 64, 122, 50, 89, 6, 128, 47, 0, 36, 14, 69, 36, 228, 197, 73, 64, 122, 50, 89, 128, 47, 0, 10, 10, 67, 16, 242, 78, 72, 134, 122, 50, 0, 12, 69, 12, 245, 71, 5, 32, 49, 134, 81, 114, 0, 12, 69, 12, 128, 76, 21, 64, 91, 35, 55, 138, 0, 12, 69, 12, 16, 200, 21, 64, 49, 35, 91, 138, 0, 0, 15, 70, 56, 21, 1, 48, 145, 64, 50, 35, 47, 119, 55, 37, 0, 15, 70, 92, 20, 212, 4, 113, 64, 58, 138, 89, 47, 113, 75, 0, 15, 70, 88, 84, 212, 36, 113, 64, 84, 121, 89, 47, 113, 75, 0, 14, 70, 80, 80, 82, 36, 225, 192, 47, 140, 44, 122, 68, 0, 15, 70, 76, 48, 82, 36, 225, 192, 89, 49, 140, 34, 122, 68, 0, 15, 70, 64, 244, 212, 4, 113, 64, 48, 136, 89, 47, 113, 75, 0, 15, 70, 52, 20, 211, 4, 113, 64, 65, 119, 89, 126, 90, 0, 103, 14, 70, 52, 20, 211, 4, 113, 64, 65, 35, 89, 126, 90, 0, 0, 18, 70, 8, 20, 130, 4, 67, 211, 71, 127, 6, 71, 138, 72, 136, 89, 0, 103, 17, 70, 8, 20, 130, 4, 67, 211, 71, 127, 6, 71, 138, 72, 124, 89, 0, 0, 14, 68, 80, 129, 83, 20, 86, 129, 88, 0, 72, 34, 12, 9, 0, 22, 73, 60, 211, 137, 76, 50, 69, 56, 49, 64, 124, 65, 50, 6, 122, 89, 122, 13, 50, 89, 0, 14, 70, 52, 84, 137, 56, 117, 69, 65, 13, 34, 35, 68, 0, 12, 69, 12, 244, 9, 21, 32, 49, 124, 48, 142, 0, 16, 70, 8, 18, 197, 48, 149, 5, 71, 138, 49, 13, 55, 137, 47, 0, 15, 70, 4, 224, 76, 60, 117, 69, 35, 50, 13, 55, 124, 81, 0, 0, 16, 70, 72, 243, 65, 56, 49, 64, 34, 136, 65, 6, 35, 50, 89, 0, 15, 70, 64, 20, 212, 36, 225, 192, 48, 138, 89, 47, 122, 68, 0, 15, 70, 61, 97, 82, 4, 113, 64, 136, 84, 13, 44, 138, 75, 0, 9, 198, 61, 85, 3, 60, 209, 64, 65, 14, 70, 56, 245, 8, 36, 225, 192, 50, 125, 87, 122, 68, 0, 14, 70, 56, 80, 203, 80, 145, 64, 50, 121, 49, 47, 137, 0, 14, 70, 12, 243, 12, 20, 113, 64, 49, 124, 55, 113, 75, 0, 15, 70, 5, 97, 82, 4, 113, 64, 35, 84, 14, 34, 113, 75, 0, 0, 0, 28, 68, 52, 145, 200, 80, 4, 65, 137, 47, 107, 6, 35, 84, 47, 116, 0, 32, 14, 82, 104, 97, 118, 101, 32, 116, 111, 32, 21, 68, 52, 145, 200, 80, 65, 137, 47, 107, 119, 84, 0, 35, 77, 81, 104, 97, 118, 101, 32, 14, 68, 52, 145, 200, 80, 4, 65, 137, 47, 0, 32, 12, 9, 18, 72, 16, 83, 143, 84, 83, 69, 57, 64, 72, 138, 50, 6, 134, 65, 151, 0, 9, 67, 5, 85, 15, 130, 47, 136, 0, 0, 8, 197, 84, 229, 201, 76, 80, 66, 13, 69, 36, 229, 1, 44, 80, 122, 50, 108, 138, 49, 0, 15, 69, 21, 84, 143, 64, 16, 57, 143, 34, 6, 136, 48, 13, 0, 0, 14, 70, 12, 243, 15, 56, 83, 0, 49, 148, 50, 118, 0, 105, 13, 70, 12, 243, 15, 56, 83, 0, 49, 128, 50, 118, 0, 0, 9, 67, 4, 214, 64, 138, 65, 37, 0, 18, 71, 9, 34, 71, 4, 66, 69, 72, 71, 34, 122, 81, 119, 72, 6, 142, 0, 0, 0, 12, 69, 76, 129, 73, 48, 16, 91, 129, 55, 13, 0, 14, 69, 48, 245, 73, 76, 80, 55, 134, 58, 6, 129, 88, 0, 14, 69, 64, 19, 129, 52, 16, 48, 35, 50, 13, 65, 126, 0, 12, 69, 80, 245, 80, 20, 80, 47, 134, 48, 138, 0, 12, 69, 53, 148, 148, 48, 80, 65, 128, 47, 118, 0, 0, 14, 70, 48, 147, 132, 76, 22, 64, 55, 122, 50, 88, 37, 0, 15, 70, 8, 19, 15, 56, 86, 64, 71, 13, 55, 136, 50, 37, 0, 0, 16, 70, 88, 244, 148, 36, 49, 83, 84, 132, 47, 122, 89, 129, 88, 0, 16, 70, 72, 21, 133, 56, 245, 83, 34, 35, 84, 13, 50, 13, 89, 0, 15, 70, 21, 97, 78, 36, 225, 211, 129, 84, 50, 122, 68, 88, 0, 11, 199, 5, 69, 18, 36, 37, 84, 20, 66, 36, 18, 71, 5, 69, 18, 36, 37, 84, 20, 35, 47, 34, 122, 71, 57, 134, 47, 0, 0, 19, 72, 4, 197, 18, 36, 224, 200, 4, 208, 130, 55, 47, 34, 122, 68, 13, 65, 0, 19, 72, 36, 227, 143, 88, 21, 9, 88, 80, 122, 50, 13, 84, 138, 47, 122, 84, 0, 11, 200, 36, 225, 9, 12, 21, 9, 88, 80, 66, 19, 72, 16, 80, 207, 72, 21, 9, 88, 80, 72, 121, 49, 34, 13, 47, 122, 84, 0, 0, 6, 18, 66, 108, 0, 114, 0, 7, 6, 18, 67, 105, 0, 121, 0, 7, 6, 18, 68, 97, 0, 105, 0, 111, 0, 117, 0, 7, 6, 18, 70, 99, 0, 103, 0, 107, 0, 7, 6, 18, 71, 115, 0, 122, 0, 7, 6, 18, 75, 103, 114, 97, 112, 0, 115, 99, 111, 112, 0, 108, 111, 103, 0, 109, 101, 116, 0, 7, 6, 20, 0, 0, 0, 251, 0, 0, 102, 0, 102, 0, 1, 251, 0, 0, 102, 0, 105, 0, 2, 251, 0, 0, 102, 0, 108, 0, 0, 0, 0, 0, 6, 97, 98, 0, 4, 2, 111, 108, 105, 116, 3, 4, 35, 71, 0, 8, 2, 111, 114, 105, 0, 115, 101, 110, 2, 116, 3, 4, 35, 71, 89, 13, 50, 0, 101, 114, 8, 2, 21, 3, 4, 35, 71, 114, 0, 2, 117, 108, 97, 114, 3, 6, 35, 71, 0, 4, 8, 110, 101, 2, 108, 3, 6, 138, 71, 0, 8, 110, 117, 2, 108, 101, 0, 8, 115, 105, 100, 2, 108, 101, 0, 108, 105, 110, 103, 3, 6, 138, 71, 55, 122, 68, 0, 108, 101, 1, 116, 99, 21, 2, 32, 3, 8, 13, 71, 118, 0, 97, 100, 1, 21, 2, 32, 3, 8, 119, 71, 35, 72, 0, 1, 17, 67, 2, 105, 108, 105, 116, 12, 3, 13, 71, 0, 105, 108, 105, 116, 121, 1, 10, 2, 14, 128, 139, 135, 3, 13, 71, 6, 122, 55, 113, 47, 2, 37, 0, 105, 108, 105, 116, 105, 101, 115, 1, 10, 2, 14, 128, 139, 137, 3, 13, 71, 6, 122, 55, 113, 47, 2, 37, 88, 0, 4, 108, 121, 1, 10, 2, 32, 14, 128, 171, 132, 3, 13, 71, 55, 2, 122, 0, 108, 121, 1, 99, 10, 2, 32, 14, 128, 168, 132, 0, 4, 108, 101, 1, 10, 2, 32, 14, 128, 139, 132, 3, 13, 71, 118, 0, 108, 101, 1, 99, 10, 2, 32, 0, 4, 1, 98, 2, 121, 108, 3, 35, 71, 0, 2, 97, 99, 17, 65, 0, 2, 97, 116, 116, 0, 2, 106, 101, 99, 116, 0, 2, 108, 97, 116, 105, 118, 0, 2, 110, 101, 103, 0, 2, 114, 111, 103, 0, 2, 114, 117, 99, 0, 2, 115, 99, 101, 0, 2, 115, 101, 105, 0, 2, 115, 111, 108, 117, 0, 2, 115, 116, 105, 0, 8, 2, 100, 0, 8, 2, 105, 0, 8, 2, 114, 97, 99, 0, 98, 8, 0, 98, 111, 8, 3, 35, 71, 13, 0, 101, 114, 1, 17, 67, 2, 21, 3, 35, 71, 114, 0, 4, 8, 2, 21, 3, 119, 71, 0, 8, 2, 100, 117, 99, 0, 8, 2, 105, 100, 101, 0, 8, 2, 114, 97, 0, 98, 8, 2, 114, 101, 118, 0, 111, 118, 101, 8, 2, 21, 14, 128, 132, 133, 3, 119, 71, 4, 125, 84, 0, 101, 114, 8, 2, 114, 97, 110, 3, 119, 71, 121, 0, 4, 1, 17, 67, 29, 2, 108, 101, 3, 138, 71, 0, 1, 98, 2, 121, 0, 1, 108, 2, 111, 117, 114, 0, 1, 116, 115, 2, 105, 108, 0, 8, 2, 114, 97, 109, 0, 8, 108, 2, 105, 0, 108, 121, 3, 138, 71, 55, 122, 0, 101, 114, 8, 115, 2, 21, 3, 138, 71, 114, 0, 4, 101, 108, 8, 3, 138, 71, 118, 0, 108, 101, 0, 108, 101, 1, 10, 2, 32, 28, 17, 0, 7, 6, 97, 99, 0, 2, 99, 101, 110, 116, 117, 3, 2, 35, 49, 0, 2, 113, 117, 105, 101, 3, 4, 35, 0, 4, 2, 97, 32, 3, 6, 35, 49, 0, 2, 116, 111, 114, 121, 0, 2, 116, 117, 114, 101, 0, 2, 117, 108, 97, 114, 0, 104, 105, 97, 3, 6, 138, 91, 13, 0, 101, 97, 110, 2, 32, 3, 6, 138, 91, 13, 50, 0, 105, 111, 117, 115, 3, 6, 138, 91, 13, 89, 0, 1, 114, 99, 2, 121, 32, 3, 8, 13, 89, 0, 4, 1, 10, 2, 108, 101, 32, 3, 13, 49, 0, 104, 1, 114, 116, 2, 101, 0, 114, 101, 1, 115, 115, 97, 109, 3, 13, 49, 114, 0, 4, 1, 10, 2, 121, 32, 3, 13, 89, 0, 1, 102, 2, 105, 108, 105, 116, 0, 1, 108, 112, 2, 101, 98, 0, 8, 108, 112, 2, 101, 110, 116, 0, 104, 105, 1, 109, 2, 110, 17, 65, 13, 3, 13, 91, 129, 0, 4, 2, 99, 101, 110, 116, 3, 35, 49, 0, 2, 99, 105, 100, 0, 2, 111, 110, 0, 2, 114, 111, 0, 2, 117, 109, 0, 2, 117, 112, 0, 8, 2, 111, 0, 8, 2, 114, 105, 0, 8, 2, 116, 0, 99, 2, 111, 108, 0, 104, 2, 114, 111, 109, 0, 107, 8, 0, 97, 2, 100, 101, 109, 3, 35, 49, 13, 0, 114, 111, 1, 109, 2, 21, 3, 35, 49, 34, 13, 0, 110, 101, 3, 35, 49, 50, 122, 0, 99, 117, 2, 114, 97, 3, 35, 49, 57, 117, 0, 109, 101, 3, 35, 49, 65, 122, 0, 116, 117, 2, 17, 65, 3, 35, 49, 76, 134, 0, 4, 2, 101, 114, 98, 3, 35, 89, 0, 2, 105, 100, 32, 0, 4, 101, 8, 2, 116, 3, 35, 89, 122, 0, 101, 8, 109, 2, 100, 0, 104, 105, 110, 97, 1, 109, 2, 116, 3, 35, 91, 113, 50, 138, 0, 4, 1, 108, 112, 2, 97, 116, 3, 119, 49, 0, 8, 2, 21, 0, 99, 8, 2, 21, 0, 107, 8, 2, 110, 0, 97, 2, 100, 101, 109, 121, 3, 119, 49, 35, 0, 99, 117, 115, 2, 17, 65, 3, 119, 49, 57, 134, 88, 0, 113, 117, 8, 3, 119, 49, 58, 0, 99, 8, 2, 101, 3, 119, 49, 89, 0, 4, 99, 111, 117, 2, 116, 3, 119, 49, 134, 0, 111, 117, 2, 115, 116, 0, 104, 8, 3, 119, 76, 0, 4, 8, 2, 101, 3, 119, 89, 0, 8, 2, 101, 114, 98, 105, 0, 8, 2, 105, 0, 101, 8, 2, 116, 105, 3, 119, 89, 129, 0, 4, 1, 102, 114, 117, 2, 101, 32, 3, 122, 89, 0, 1, 108, 97, 2, 101, 32, 0, 1, 108, 111, 115, 2, 101, 32, 0, 1, 109, 105, 2, 101, 32, 0, 1, 110, 21, 2, 101, 32, 0, 1, 114, 114, 2, 101, 32, 0, 104, 1, 121, 2, 116, 3, 124, 0, 4, 1, 118, 2, 97, 3, 138, 49, 0, 2, 111, 114, 110, 0, 8, 98, 2, 111, 0, 104, 101, 1, 100, 2, 32, 0, 104, 101, 1, 104, 2, 32, 0, 104, 101, 1, 107, 2, 32, 0, 104, 101, 1, 114, 2, 32, 0, 104, 101, 1, 116, 114, 2, 32, 0, 104, 101, 1, 121, 2, 32, 0, 104, 101, 8, 2, 12, 0, 114, 101, 8, 3, 138, 49, 13, 0, 4, 104, 101, 115, 1, 100, 2, 32, 3, 138, 49, 89, 0, 104, 101, 115, 1, 104, 2, 32, 0, 104, 101, 115, 1, 114, 2, 32, 0, 104, 101, 115, 1, 116, 114, 2, 32, 0, 4, 1, 112, 115, 2, 101, 13, 3, 138, 89, 0, 8, 114, 2, 101, 0, 8, 114, 2, 105, 115, 0, 101, 2, 32, 0, 7, 6, 97, 100, 0, 1, 115, 117, 114, 99, 3, 6, 138, 72, 0, 1, 108, 97, 109, 2, 121, 3, 13, 72, 0, 105, 111, 8, 114, 2, 21, 14, 128, 132, 133, 3, 34, 4, 138, 72, 122, 2, 136, 0, 2, 106, 117, 116, 97, 110, 3, 35, 0, 4, 1, 108, 103, 2, 105, 3, 35, 72, 0, 1, 114, 2, 105, 99, 0, 1, 120, 101, 104, 2, 101, 0, 2, 97, 103, 0, 2, 97, 109, 0, 2, 101, 110, 0, 2, 101, 113, 0, 2, 106, 117, 110, 99, 116, 32, 0, 2, 109, 97, 110, 32, 0, 2, 109, 105, 110, 32, 0, 2, 109, 105, 114, 97, 0, 2, 111, 108, 0, 2, 111, 110, 0, 2, 117, 108, 97, 0, 2, 118, 101, 110, 116, 0, 2, 118, 101, 114, 0, 2, 118, 101, 114, 116, 32, 0, 2, 118, 111, 0, 8, 2, 105, 0, 8, 2, 114, 105, 21, 0, 8, 2, 117, 109, 0, 100, 2, 101, 114, 0, 100, 2, 105, 116, 105, 118, 0, 100, 8, 2, 108, 0, 101, 1, 108, 2, 115, 104, 3, 35, 72, 6, 121, 0, 111, 2, 108, 101, 115, 3, 35, 72, 13, 0, 118, 101, 114, 2, 115, 3, 35, 72, 84, 6, 128, 0, 101, 113, 117, 97, 3, 35, 72, 122, 49, 58, 13, 0, 106, 101, 99, 3, 35, 75, 121, 49, 0, 4, 2, 118, 101, 110, 116, 117, 3, 119, 72, 0, 2, 118, 101, 114, 115, 97, 0, 2, 118, 101, 114, 116, 0, 8, 2, 21, 0, 8, 114, 116, 2, 105, 116, 0, 100, 8, 2, 21, 0, 97, 1, 99, 2, 118, 101, 114, 3, 119, 72, 35, 0, 106, 8, 3, 119, 75, 0, 1, 117, 113, 3, 124, 72, 0, 4, 1, 98, 2, 111, 115, 32, 3, 138, 72, 0, 1, 99, 2, 101, 110, 99, 0, 1, 108, 2, 101, 110, 0, 1, 108, 2, 121, 0, 1, 110, 114, 111, 116, 0, 1, 114, 99, 0, 1, 115, 2, 105, 115, 0, 2, 105, 17, 65, 0, 2, 108, 101, 0, 8, 114, 2, 17, 65, 0, 105, 1, 114, 2, 111, 18, 75, 12, 3, 138, 72, 122, 0, 7, 6, 97, 102, 0, 1, 21, 2, 116, 101, 114, 3, 6, 120, 83, 0, 4, 2, 114, 105, 3, 35, 83, 0, 8, 2, 103, 0, 102, 2, 97, 98, 0, 102, 2, 101, 114, 0, 102, 2, 108, 117, 0, 114, 111, 8, 3, 35, 83, 34, 136, 0, 4, 2, 101, 97, 3, 119, 83, 0, 8, 2, 21, 0, 102, 8, 2, 21, 0, 111, 114, 101, 3, 119, 83, 133, 0, 102, 105, 97, 8, 3, 119, 83, 144, 0, 4, 2, 116, 12, 3, 120, 83, 0, 102, 1, 116, 115, 0, 102, 1, 119, 3, 124, 83, 0, 7, 6, 97, 103, 0, 8, 116, 110, 97, 3, 6, 35, 81, 0, 117, 97, 1, 21, 2, 32, 3, 6, 35, 81, 57, 134, 13, 0, 105, 111, 2, 32, 3, 6, 126, 75, 122, 136, 0, 2, 97, 32, 3, 6, 126, 81, 0, 105, 2, 32, 3, 6, 126, 81, 122, 0, 4, 1, 103, 110, 2, 101, 32, 3, 6, 138, 75, 0, 1, 114, 110, 101, 2, 101, 32, 0, 101, 1, 103, 2, 109, 101, 110, 116, 0, 104, 2, 32, 3, 13, 0, 1, 109, 2, 101, 110, 116, 97, 3, 13, 75, 0, 1, 10, 2, 111, 110, 32, 3, 13, 81, 0, 8, 114, 116, 3, 35, 75, 0, 4, 103, 8, 2, 114, 97, 118, 3, 35, 81, 0, 103, 8, 2, 114, 101, 103, 0, 4, 111, 110, 1, 114, 100, 3, 35, 81, 13, 50, 0, 111, 110, 1, 119, 2, 12, 0, 4, 101, 1, 21, 2, 32, 3, 113, 75, 0, 101, 1, 21, 2, 109, 101, 110, 116, 0, 101, 1, 112, 112, 2, 32, 0, 101, 114, 1, 21, 2, 32, 3, 113, 75, 114, 0, 2, 101, 110, 100, 3, 119, 75, 0, 4, 2, 114, 101, 101, 3, 119, 81, 0, 8, 2, 108, 21, 0, 8, 2, 111, 32, 0, 8, 2, 114, 111, 110, 0, 103, 2, 114, 101, 115, 0, 103, 2, 114, 105, 101, 118, 0, 103, 8, 2, 21, 0, 101, 110, 1, 104, 10, 2, 32, 3, 126, 81, 13, 50, 0, 4, 1, 116, 110, 111, 109, 2, 101, 32, 3, 126, 90, 0, 101, 1, 108, 102, 2, 32, 0, 4, 1, 110, 101, 101, 116, 2, 101, 3, 138, 75, 0, 1, 114, 101, 100, 2, 101, 32, 0, 1, 114, 116, 117, 111, 2, 101, 32, 0, 1, 116, 115, 2, 101, 0, 8, 2, 101, 0, 8, 2, 105, 115, 0, 101, 1, 99, 2, 32, 0, 101, 1, 99, 98, 0, 101, 1, 99, 100, 0, 101, 1, 112, 17, 67, 2, 32, 0, 101, 8, 2, 105, 0, 101, 8, 2, 108, 0, 105, 1, 116, 2, 111, 3, 138, 75, 57, 0, 4, 1, 108, 102, 2, 114, 97, 110, 3, 138, 81, 0, 1, 114, 102, 2, 114, 0, 1, 118, 2, 114, 97, 0, 2, 111, 32, 0, 117, 101, 0, 7, 6, 97, 105, 0, 4, 1, 21, 2, 17, 67, 97, 32, 3, 6, 138, 0, 1, 116, 110, 101, 2, 108, 0, 1, 116, 114, 117, 99, 2, 108, 0, 103, 2, 110, 0, 110, 1, 100, 2, 32, 3, 6, 138, 50, 0, 110, 101, 100, 1, 100, 2, 32, 3, 6, 138, 50, 72, 0, 115, 101, 2, 32, 3, 6, 138, 88, 0, 4, 99, 2, 32, 3, 6, 138, 122, 49, 0, 99, 2, 97, 108, 0, 114, 101, 3, 6, 140, 0, 4, 1, 108, 108, 105, 118, 3, 13, 0, 1, 116, 102, 0, 1, 116, 105, 114, 98, 0, 1, 116, 114, 101, 99, 0, 1, 116, 114, 117, 99, 0, 4, 115, 8, 2, 108, 105, 3, 35, 91, 0, 115, 8, 99, 2, 108, 0, 1, 115, 2, 100, 3, 121, 0, 4, 1, 103, 114, 97, 98, 3, 122, 0, 1, 108, 112, 97, 0, 1, 108, 114, 101, 98, 0, 1, 116, 110, 117, 111, 0, 1, 116, 112, 0, 4, 2, 32, 3, 137, 0, 2, 105, 0, 1, 110, 2, 118, 3, 137, 6, 129, 0, 4, 3, 138, 0, 8, 0, 115, 1, 108, 21, 2, 32, 0, 101, 3, 138, 13, 0, 4, 114, 3, 140, 0, 114, 8, 0, 114, 101, 2, 32, 0, 7, 6, 97, 108, 0, 1, 109, 2, 110, 111, 3, 2, 35, 55, 0, 2, 109, 105, 103, 3, 2, 124, 55, 0, 8, 2, 114, 3, 2, 130, 55, 0, 2, 105, 116, 121, 3, 6, 35, 55, 0, 100, 101, 2, 104, 121, 3, 6, 35, 55, 72, 122, 0, 103, 105, 97, 1, 21, 2, 32, 3, 6, 35, 55, 75, 13, 0, 4, 1, 103, 2, 105, 32, 3, 6, 126, 55, 0, 1, 122, 110, 111, 103, 0, 97, 110, 100, 1, 21, 2, 32, 3, 8, 13, 55, 119, 50, 72, 0, 4, 1, 10, 2, 105, 17, 66, 97, 116, 105, 3, 13, 55, 0, 1, 10, 2, 105, 17, 66, 101, 0, 1, 10, 2, 105, 115, 17, 67, 105, 99, 0, 1, 10, 2, 111, 117, 115, 32, 0, 1, 115, 2, 117, 116, 0, 1, 117, 113, 101, 0, 1, 118, 17, 65, 2, 101, 110, 0, 97, 121, 1, 109, 3, 13, 55, 6, 138, 0, 105, 1, 10, 2, 115, 17, 67, 32, 3, 13, 55, 122, 0, 111, 1, 10, 2, 32, 3, 13, 55, 136, 0, 101, 105, 1, 107, 2, 100, 3, 13, 55, 137, 0, 4, 5, 3, 1, 99, 2, 102, 3, 35, 0, 5, 3, 1, 104, 2, 102, 0, 5, 3, 1, 104, 2, 118, 0, 4, 1, 29, 2, 101, 100, 3, 35, 55, 0, 1, 112, 2, 101, 116, 0, 1, 115, 2, 117, 116, 97, 0, 1, 116, 101, 114, 2, 105, 97, 0, 1, 118, 2, 105, 97, 0, 2, 116, 111, 0, 2, 117, 109, 32, 0, 8, 2, 97, 115, 116, 0, 8, 2, 98, 0, 8, 2, 99, 0, 8, 2, 103, 0, 8, 2, 105, 0, 8, 2, 107, 0, 8, 2, 112, 0, 8, 2, 115, 0, 8, 2, 118, 0, 8, 2, 121, 0, 8, 99, 2, 101, 0, 108, 1, 102, 2, 97, 0, 108, 1, 102, 2, 105, 98, 0, 108, 1, 116, 2, 17, 65, 0, 108, 2, 101, 108, 0, 108, 2, 101, 114, 0, 108, 2, 111, 116, 114, 0, 108, 8, 2, 97, 0, 108, 8, 2, 101, 103, 0, 108, 8, 2, 105, 0, 108, 8, 2, 111, 0, 108, 8, 17, 67, 2, 111, 119, 0, 108, 111, 8, 2, 99, 97, 3, 35, 55, 13, 0, 97, 98, 97, 8, 3, 35, 55, 13, 71, 6, 35, 0, 122, 3, 35, 55, 47, 89, 0, 116, 105, 8, 3, 35, 55, 47, 122, 0, 112, 2, 104, 111, 3, 35, 55, 48, 0, 99, 111, 2, 104, 3, 35, 55, 49, 13, 0, 98, 101, 114, 8, 2, 116, 17, 65, 3, 35, 55, 71, 6, 128, 0, 4, 102, 97, 8, 3, 35, 55, 83, 13, 0, 112, 104, 97, 0, 101, 112, 104, 3, 35, 55, 121, 83, 0, 4, 108, 101, 121, 3, 35, 55, 122, 0, 108, 121, 1, 116, 0, 101, 120, 97, 110, 8, 3, 35, 55, 122, 81, 88, 6, 120, 50, 0, 108, 121, 8, 3, 35, 55, 137, 0, 4, 108, 121, 1, 21, 2, 32, 14, 128, 128, 130, 3, 55, 2, 37, 0, 108, 121, 1, 99, 21, 21, 2, 32, 14, 128, 128, 132, 0, 108, 121, 1, 99, 97, 2, 32, 0, 4, 1, 10, 2, 32, 3, 118, 0, 1, 10, 2, 100, 32, 0, 1, 10, 2, 116, 121, 32, 0, 114, 121, 1, 10, 2, 32, 3, 118, 34, 2, 122, 0, 4, 1, 104, 2, 117, 99, 105, 110, 3, 119, 55, 0, 2, 111, 110, 103, 0, 5, 8, 1, 10, 2, 32, 0, 8, 2, 21, 0, 8, 2, 105, 103, 0, 8, 99, 2, 97, 109, 105, 116, 0, 108, 2, 101, 103, 114, 0, 108, 8, 2, 21, 0, 108, 8, 2, 105, 97, 110, 0, 108, 8, 2, 105, 116, 101, 114, 0, 108, 8, 2, 111, 116, 0, 108, 8, 2, 111, 119, 0, 108, 101, 2, 103, 101, 3, 119, 55, 121, 0, 105, 8, 2, 17, 66, 101, 3, 119, 55, 137, 0, 4, 1, 102, 2, 107, 3, 124, 55, 0, 1, 102, 2, 115, 0, 1, 115, 2, 102, 0, 1, 115, 2, 116, 0, 1, 117, 113, 2, 21, 0, 1, 119, 2, 17, 67, 0, 2, 116, 17, 65, 114, 0, 2, 116, 32, 0, 8, 2, 109, 0, 8, 17, 67, 2, 116, 17, 65, 0, 8, 104, 2, 116, 0, 108, 1, 119, 2, 17, 65, 0, 108, 1, 119, 2, 97, 0, 108, 1, 119, 2, 101, 116, 0, 115, 111, 3, 124, 55, 89, 136, 0, 4, 1, 98, 2, 109, 3, 126, 0, 1, 99, 2, 102, 0, 1, 99, 2, 109, 0, 1, 104, 2, 102, 0, 1, 104, 2, 118, 0, 1, 112, 2, 109, 0, 1, 115, 112, 2, 109, 0, 1, 117, 113, 2, 109, 0, 8, 2, 109, 115, 0, 4, 1, 104, 99, 2, 107, 3, 130, 0, 1, 116, 2, 107, 0, 1, 119, 2, 107, 0, 4, 1, 98, 2, 100, 12, 3, 130, 55, 0, 1, 98, 2, 107, 0, 1, 116, 115, 2, 119, 0, 1, 116, 115, 110, 105, 2, 32, 0, 8, 2, 100, 0, 8, 2, 116, 0, 108, 1, 98, 2, 25, 0, 108, 1, 98, 10, 2, 101, 114, 32, 0, 108, 1, 99, 2, 25, 0, 108, 1, 99, 2, 105, 110, 0, 108, 1, 102, 0, 108, 1, 104, 2, 17, 67, 0, 108, 1, 109, 115, 0, 108, 1, 114, 104, 116, 0, 108, 1, 116, 0, 108, 1, 116, 2, 101, 0, 108, 1, 116, 115, 0, 108, 1, 119, 0, 108, 2, 32, 0, 108, 8, 2, 17, 67, 21, 14, 128, 132, 131, 0, 108, 101, 1, 119, 0, 108, 101, 114, 2, 32, 3, 130, 55, 114, 0, 108, 101, 114, 115, 2, 32, 3, 130, 55, 114, 88, 0, 2, 116, 101, 114, 110, 97, 116, 111, 3, 131, 55, 0, 119, 8, 3, 131, 55, 58, 0, 4, 1, 29, 2, 105, 110, 3, 138, 55, 0, 2, 105, 97, 0, 2, 105, 101, 110, 0, 8, 99, 115, 2, 17, 65, 0, 8, 104, 2, 111, 0, 101, 2, 32, 0, 101, 2, 104, 0, 7, 6, 97, 109, 0, 8, 2, 32, 3, 2, 35, 65, 0, 101, 8, 108, 2, 110, 116, 3, 2, 35, 65, 121, 0, 4, 1, 32, 15, 2, 32, 3, 4, 138, 6, 121, 65, 0, 1, 32, 32, 15, 2, 32, 0, 112, 116, 111, 110, 3, 6, 35, 65, 48, 47, 13, 50, 0, 4, 1, 114, 21, 2, 97, 32, 3, 6, 126, 65, 0, 2, 105, 32, 0, 101, 1, 115, 17, 65, 2, 32, 3, 6, 126, 65, 121, 0, 1, 103, 10, 2, 111, 117, 115, 3, 8, 119, 65, 0, 105, 110, 101, 1, 10, 2, 32, 3, 8, 119, 65, 129, 50, 0, 4, 1, 10, 2, 101, 110, 116, 3, 13, 65, 0, 1, 10, 2, 101, 110, 116, 0, 1, 10, 2, 111, 32, 0, 1, 100, 10, 2, 32, 0, 1, 100, 110, 117, 2, 101, 110, 0, 1, 115, 10, 2, 32, 0, 5, 35, 1, 104, 10, 2, 32, 24, 0, 101, 1, 10, 2, 110, 116, 97, 3, 13, 65, 6, 121, 0, 4, 1, 99, 2, 101, 108, 3, 35, 65, 0, 1, 100, 114, 101, 21, 2, 32, 0, 1, 108, 2, 112, 108, 0, 97, 116, 101, 117, 114, 3, 35, 65, 13, 47, 114, 0, 97, 122, 2, 111, 3, 35, 65, 13, 88, 0, 98, 105, 118, 3, 35, 65, 71, 6, 122, 84, 0, 98, 105, 2, 100, 3, 35, 65, 71, 122, 0, 112, 104, 105, 98, 3, 35, 65, 83, 6, 122, 71, 0, 105, 108, 1, 102, 3, 35, 65, 122, 55, 0, 4, 2, 117, 115, 101, 3, 119, 65, 0, 8, 2, 97, 108, 0, 8, 2, 101, 110, 0, 8, 2, 105, 100, 0, 8, 2, 105, 110, 111, 0, 8, 2, 105, 115, 115, 0, 8, 2, 111, 114, 17, 67, 0, 109, 2, 101, 110, 100, 0, 101, 8, 2, 110, 116, 3, 119, 65, 121, 0, 101, 114, 2, 105, 99, 3, 119, 65, 121, 34, 0, 4, 101, 2, 110, 97, 98, 3, 119, 65, 129, 0, 101, 8, 2, 108, 0, 105, 2, 103, 0, 111, 101, 98, 3, 119, 65, 129, 71, 0, 97, 122, 3, 119, 65, 138, 88, 0, 4, 1, 17, 67, 2, 100, 3, 120, 65, 0, 1, 17, 67, 2, 112, 108, 0, 4, 1, 102, 2, 111, 117, 115, 3, 138, 65, 0, 1, 104, 99, 2, 98, 0, 8, 100, 2, 105, 0, 101, 1, 108, 102, 0, 101, 8, 110, 0, 7, 6, 97, 110, 0, 8, 114, 116, 2, 115, 3, 2, 35, 50, 0, 115, 102, 101, 114, 1, 114, 116, 3, 2, 35, 50, 89, 83, 128, 0, 116, 105, 8, 2, 21, 14, 128, 132, 132, 3, 4, 35, 50, 47, 122, 0, 100, 117, 1, 21, 2, 32, 3, 4, 35, 50, 72, 6, 134, 0, 4, 1, 21, 2, 17, 67, 97, 32, 3, 6, 35, 50, 0, 1, 103, 97, 112, 111, 114, 112, 2, 100, 0, 1, 110, 105, 102, 2, 99, 0, 2, 103, 117, 108, 0, 2, 122, 97, 0, 100, 111, 2, 32, 3, 6, 35, 50, 72, 136, 0, 97, 1, 21, 2, 32, 3, 6, 126, 50, 13, 0, 105, 1, 10, 2, 32, 3, 6, 126, 50, 122, 0, 2, 105, 97, 3, 6, 138, 50, 0, 105, 97, 2, 99, 32, 3, 6, 138, 50, 122, 35, 0, 101, 97, 110, 2, 32, 3, 6, 138, 50, 141, 50, 0, 101, 111, 117, 115, 1, 21, 3, 6, 138, 50, 141, 89, 0, 4, 1, 10, 2, 32, 3, 13, 50, 0, 1, 10, 2, 99, 101, 32, 0, 1, 10, 2, 99, 121, 0, 1, 10, 2, 101, 115, 101, 0, 1, 10, 2, 105, 101, 32, 0, 1, 10, 2, 105, 101, 115, 32, 0, 1, 10, 2, 116, 32, 0, 1, 10, 2, 116, 121, 32, 0, 1, 10, 2, 121, 32, 0, 1, 98, 115, 117, 2, 100, 0, 1, 104, 112, 2, 97, 103, 101, 0, 1, 108, 10, 2, 100, 0, 1, 108, 101, 109, 2, 99, 104, 111, 108, 0, 1, 108, 108, 2, 32, 0, 1, 109, 10, 2, 32, 0, 1, 109, 114, 101, 112, 0, 1, 109, 117, 104, 2, 32, 0, 1, 114, 21, 21, 2, 32, 0, 110, 1, 10, 2, 105, 101, 32, 0, 105, 112, 117, 1, 109, 3, 13, 50, 122, 48, 57, 117, 0, 111, 101, 117, 1, 109, 2, 118, 3, 13, 50, 134, 0, 4, 1, 99, 2, 99, 3, 35, 50, 0, 1, 99, 17, 67, 2, 32, 0, 1, 102, 2, 99, 0, 1, 108, 2, 32, 0, 1, 108, 10, 2, 100, 105, 0, 1, 108, 112, 2, 116, 32, 0, 1, 108, 121, 2, 100, 0, 1, 109, 2, 32, 0, 1, 110, 2, 99, 0, 1, 112, 2, 32, 0, 1, 112, 2, 99, 0, 1, 112, 2, 101, 108, 0, 1, 112, 115, 2, 105, 97, 0, 1, 114, 116, 2, 32, 0, 1, 114, 116, 2, 115, 105, 0, 1, 114, 116, 2, 115, 111, 109, 0, 1, 116, 115, 2, 32, 0, 1, 118, 100, 97, 2, 99, 0, 8, 108, 2, 105, 97, 0, 8, 119, 2, 103, 0, 8, 119, 2, 107, 0, 110, 97, 8, 3, 35, 50, 13, 0, 116, 8, 2, 105, 113, 12, 3, 35, 50, 47, 0, 116, 101, 2, 110, 110, 3, 35, 50, 47, 6, 121, 0, 116, 105, 2, 99, 105, 3, 35, 50, 47, 6, 122, 0, 4, 103, 1, 108, 102, 2, 101, 3, 35, 50, 75, 0, 103, 2, 101, 108, 0, 103, 105, 110, 103, 1, 108, 102, 3, 35, 50, 75, 122, 68, 0, 115, 105, 115, 1, 114, 116, 3, 35, 50, 88, 6, 122, 89, 0, 101, 8, 2, 115, 3, 35, 50, 122, 0, 103, 1, 104, 2, 101, 114, 3, 35, 68, 0, 103, 2, 101, 114, 3, 35, 68, 81, 0, 103, 101, 108, 1, 109, 3, 35, 68, 81, 118, 0, 4, 1, 105, 21, 2, 32, 14, 128, 128, 129, 3, 50, 0, 1, 117, 21, 2, 32, 14, 128, 128, 129, 0, 103, 101, 100, 1, 114, 2, 14, 128, 128, 129, 3, 72, 0, 4, 2, 97, 108, 111, 103, 3, 119, 50, 0, 2, 97, 116, 104, 0, 5, 8, 1, 10, 2, 32, 0, 5, 8, 1, 10, 2, 99, 101, 32, 0, 5, 8, 1, 10, 2, 116, 32, 0, 5, 8, 1, 109, 10, 2, 32, 0, 8, 2, 101, 109, 0, 8, 2, 111, 105, 0, 8, 99, 2, 97, 100, 105, 0, 110, 2, 101, 97, 108, 0, 110, 2, 105, 104, 0, 110, 2, 111, 117, 110, 0, 110, 2, 117, 105, 0, 110, 2, 117, 108, 0, 110, 2, 117, 110, 0, 110, 8, 2, 111, 121, 0, 105, 97, 1, 122, 3, 119, 50, 6, 141, 0, 111, 109, 8, 3, 119, 50, 124, 65, 0, 101, 8, 2, 109, 105, 3, 119, 50, 129, 0, 105, 97, 2, 99, 3, 119, 50, 144, 0, 4, 1, 17, 67, 2, 99, 3, 120, 50, 0, 1, 17, 67, 2, 116, 0, 1, 104, 2, 99, 101, 32, 0, 1, 108, 115, 2, 100, 0, 1, 109, 21, 2, 100, 0, 1, 122, 2, 99, 101, 32, 0, 115, 119, 2, 101, 114, 3, 120, 50, 89, 0, 121, 8, 3, 121, 50, 113, 0, 4, 1, 119, 2, 116, 32, 3, 124, 50, 0, 8, 117, 113, 0, 8, 119, 2, 17, 67, 0, 8, 2, 99, 105, 101, 3, 138, 50, 0, 4, 103, 1, 100, 2, 101, 114, 3, 138, 50, 75, 0, 103, 1, 104, 99, 2, 101, 0, 103, 1, 114, 2, 101, 0, 103, 2, 101, 108, 32, 0, 103, 101, 1, 104, 99, 2, 21, 0, 4, 103, 105, 110, 103, 1, 104, 99, 3, 138, 50, 75, 122, 68, 0, 103, 105, 110, 103, 1, 114, 0, 7, 6, 97, 112, 0, 104, 1, 114, 103, 10, 2, 121, 3, 8, 13, 83, 0, 104, 101, 114, 1, 114, 103, 10, 3, 8, 13, 83, 114, 0, 1, 99, 2, 97, 99, 3, 13, 48, 0, 101, 1, 114, 116, 2, 122, 3, 13, 48, 129, 0, 4, 2, 97, 116, 104, 3, 35, 48, 0, 2, 101, 108, 32, 0, 2, 105, 99, 0, 2, 111, 103, 0, 2, 111, 108, 105, 0, 8, 2, 115, 0, 8, 2, 116, 0, 112, 2, 97, 114, 97, 0, 112, 2, 101, 116, 105, 0, 112, 2, 108, 101, 0, 112, 2, 108, 105, 99, 0, 112, 2, 114, 101, 104, 0, 101, 114, 8, 2, 116, 3, 35, 48, 13, 0, 114, 101, 115, 3, 35, 48, 34, 138, 0, 101, 1, 114, 116, 2, 122, 111, 3, 35, 48, 122, 0, 104, 8, 2, 111, 3, 35, 83, 0, 104, 114, 111, 3, 35, 83, 34, 13, 0, 4, 8, 2, 21, 3, 119, 48, 0, 112, 2, 101, 97, 114, 0, 112, 2, 108, 105, 99, 97, 98, 0, 112, 8, 2, 21, 0, 112, 114, 101, 99, 8, 2, 18, 67, 3, 119, 48, 34, 129, 91, 0, 101, 114, 105, 8, 2, 116, 3, 119, 48, 121, 34, 13, 0, 101, 114, 2, 105, 101, 3, 119, 48, 141, 34, 0, 104, 8, 2, 21, 3, 119, 83, 0, 4, 1, 99, 2, 111, 110, 3, 138, 48, 0, 1, 109, 2, 108, 101, 0, 1, 112, 2, 101, 114, 0, 1, 116, 115, 2, 108, 0, 2, 105, 97, 0, 2, 105, 115, 0, 2, 114, 111, 0, 8, 2, 101, 0, 8, 2, 114, 105, 0, 8, 112, 2, 105, 115, 0, 8, 118, 2, 111, 0, 104, 8, 2, 105, 100, 3, 138, 83, 0, 7, 6, 97, 114, 0, 8, 2, 116, 105, 108, 3, 2, 127, 0, 98, 111, 1, 99, 2, 104, 3, 4, 127, 71, 136, 0, 99, 104, 8, 2, 21, 14, 128, 132, 132, 3, 4, 127, 76, 0, 5, 3, 1, 21, 2, 105, 111, 32, 3, 6, 35, 34, 0, 105, 108, 121, 1, 21, 2, 32, 3, 6, 121, 34, 13, 55, 2, 122, 0, 4, 2, 97, 32, 3, 6, 126, 34, 0, 2, 105, 32, 0, 4, 2, 105, 97, 17, 67, 32, 3, 6, 140, 0, 2, 105, 97, 32, 0, 2, 105, 117, 12, 3, 6, 140, 34, 0, 4, 1, 10, 2, 105, 110, 32, 3, 13, 34, 0, 1, 103, 111, 108, 2, 105, 0, 1, 104, 2, 97, 115, 115, 0, 1, 109, 2, 105, 0, 1, 109, 2, 105, 110, 0, 8, 116, 97, 107, 0, 121, 1, 10, 2, 32, 3, 13, 34, 2, 37, 0, 97, 110, 1, 109, 10, 3, 13, 34, 35, 50, 0, 101, 1, 112, 2, 110, 116, 104, 101, 3, 13, 34, 121, 0, 105, 115, 101, 1, 10, 2, 32, 3, 13, 34, 137, 88, 0, 97, 8, 112, 2, 100, 101, 3, 13, 34, 138, 0, 105, 110, 103, 1, 103, 3, 13, 44, 113, 68, 0, 2, 114, 3, 35, 0, 4, 1, 21, 2, 105, 116, 121, 3, 35, 34, 0, 1, 99, 2, 101, 101, 114, 0, 1, 99, 2, 105, 0, 1, 104, 99, 2, 105, 116, 0, 1, 104, 112, 2, 105, 0, 1, 107, 2, 121, 0, 1, 108, 99, 2, 105, 0, 1, 109, 2, 105, 110, 101, 114, 0, 1, 109, 2, 105, 111, 0, 1, 109, 2, 105, 116, 0, 1, 112, 2, 105, 0, 1, 112, 112, 2, 101, 110, 17, 67, 0, 1, 112, 115, 2, 101, 110, 17, 67, 0, 2, 97, 0, 2, 101, 110, 0, 2, 105, 99, 0, 2, 111, 0, 8, 2, 17, 65, 0, 8, 98, 2, 18, 67, 116, 0, 8, 109, 2, 105, 0, 8, 109, 2, 105, 110, 97, 17, 67, 0, 114, 8, 2, 97, 110, 116, 0, 114, 8, 2, 111, 0, 4, 97, 8, 112, 3, 35, 34, 13, 0, 101, 2, 116, 0, 114, 111, 8, 2, 103, 0, 4, 1, 10, 2, 100, 105, 115, 3, 114, 0, 1, 10, 2, 100, 105, 122, 0, 1, 10, 2, 100, 121, 32, 0, 1, 100, 10, 2, 32, 0, 1, 100, 10, 2, 100, 32, 0, 1, 103, 10, 2, 32, 0, 1, 103, 103, 2, 100, 32, 0, 1, 104, 10, 2, 100, 32, 0, 1, 104, 99, 10, 2, 100, 0, 1, 107, 10, 2, 100, 32, 0, 1, 108, 10, 2, 32, 0, 1, 108, 10, 2, 105, 115, 116, 0, 1, 109, 10, 2, 32, 0, 1, 112, 2, 116, 105, 99, 117, 0, 1, 112, 10, 2, 100, 32, 0, 1, 116, 10, 2, 32, 0, 1, 116, 115, 10, 2, 100, 32, 0, 1, 119, 2, 100, 0, 1, 119, 10, 2, 100, 32, 0, 1, 122, 10, 2, 100, 32, 0, 2, 100, 114, 121, 0, 1, 112, 101, 115, 2, 97, 116, 3, 114, 34, 0, 105, 110, 103, 1, 17, 67, 11, 2, 32, 3, 114, 34, 113, 68, 0, 4, 99, 104, 1, 110, 97, 3, 114, 49, 0, 99, 104, 1, 110, 111, 109, 0, 101, 100, 1, 17, 67, 11, 2, 32, 3, 114, 72, 0, 4, 8, 2, 111, 115, 3, 119, 34, 0, 8, 2, 111, 117, 0, 114, 8, 2, 21, 0, 97, 99, 104, 8, 3, 119, 34, 35, 49, 0, 111, 109, 2, 97, 116, 3, 119, 34, 136, 65, 0, 121, 5, 3, 1, 110, 111, 105, 2, 32, 3, 121, 34, 2, 37, 0, 4, 1, 117, 113, 2, 114, 3, 124, 0, 1, 119, 2, 114, 0, 1, 119, 2, 114, 0, 4, 1, 117, 113, 2, 97, 3, 124, 34, 0, 119, 1, 119, 2, 105, 0, 2, 17, 65, 3, 126, 34, 0, 4, 3, 127, 0, 1, 104, 2, 100, 121, 32, 0, 1, 116, 105, 117, 103, 2, 32, 0, 1, 116, 111, 101, 2, 100, 32, 0, 1, 116, 115, 2, 32, 0, 2, 32, 0, 8, 116, 2, 32, 0, 39, 2, 110, 116, 0, 114, 2, 32, 0, 114, 101, 2, 32, 0, 4, 99, 104, 1, 21, 2, 105, 3, 127, 49, 0, 99, 104, 1, 21, 2, 121, 0, 99, 104, 8, 2, 17, 65, 17, 65, 0, 99, 104, 8, 2, 101, 116, 0, 99, 104, 97, 105, 8, 3, 127, 49, 6, 138, 122, 0, 99, 104, 105, 8, 2, 21, 3, 127, 49, 122, 0, 99, 104, 105, 118, 8, 2, 12, 3, 127, 49, 137, 84, 0, 108, 105, 97, 8, 112, 3, 127, 55, 13, 0, 114, 101, 100, 2, 32, 3, 127, 72, 0, 99, 104, 8, 2, 101, 114, 3, 127, 76, 0, 114, 105, 110, 103, 2, 32, 3, 127, 113, 68, 0, 4, 1, 104, 119, 3, 132, 0, 1, 117, 113, 2, 116, 0, 1, 119, 0, 1, 119, 97, 2, 100, 0, 1, 119, 101, 114, 2, 100, 0, 1, 119, 104, 99, 2, 100, 0, 1, 119, 115, 2, 100, 0, 8, 119, 2, 100, 0, 1, 119, 111, 116, 2, 100, 3, 133, 0, 4, 1, 109, 116, 104, 3, 140, 0, 1, 112, 2, 105, 110, 0, 1, 119, 2, 105, 0, 1, 119, 2, 121, 0, 2, 105, 111, 117, 115, 0, 8, 109, 2, 121, 0, 101, 0, 101, 1, 99, 2, 17, 67, 21, 0, 101, 1, 119, 0, 4, 1, 112, 2, 101, 110, 116, 3, 140, 34, 0, 1, 117, 2, 105, 115, 104, 0, 1, 118, 2, 105, 17, 65, 0, 121, 1, 17, 67, 29, 2, 32, 3, 140, 34, 2, 37, 0, 101, 115, 116, 2, 32, 3, 140, 34, 13, 89, 47, 0, 4, 121, 5, 3, 1, 17, 65, 21, 21, 2, 32, 3, 140, 34, 37, 0, 121, 5, 3, 1, 17, 67, 17, 65, 21, 21, 2, 32, 0, 101, 97, 3, 140, 34, 141, 0, 105, 110, 103, 3, 140, 44, 113, 68, 0, 7, 6, 97, 115, 0, 2, 101, 120, 117, 3, 2, 138, 89, 0, 2, 105, 118, 101, 3, 6, 138, 89, 0, 4, 115, 1, 99, 10, 2, 32, 3, 13, 89, 0, 115, 1, 108, 116, 10, 2, 32, 0, 115, 1, 112, 109, 111, 2, 32, 0, 115, 1, 112, 115, 10, 2, 32, 0, 115, 1, 114, 114, 0, 115, 1, 118, 10, 2, 32, 0, 115, 1, 118, 10, 2, 32, 0, 4, 101, 121, 1, 10, 2, 32, 3, 13, 89, 2, 37, 0, 121, 1, 10, 2, 32, 0, 115, 2, 117, 3, 13, 91, 0, 115, 117, 114, 3, 13, 91, 57, 143, 0, 1, 98, 2, 105, 108, 3, 35, 88, 0, 4, 1, 109, 2, 111, 110, 105, 3, 35, 89, 0, 1, 116, 110, 2, 116, 0, 2, 112, 104, 97, 0, 2, 112, 105, 0, 2, 116, 104, 109, 0, 2, 116, 114, 97, 108, 0, 2, 116, 114, 111, 0, 2, 121, 109, 112, 0, 8, 2, 101, 0, 8, 2, 105, 110, 0, 8, 2, 112, 101, 0, 115, 1, 108, 99, 2, 105, 17, 67, 0, 115, 1, 112, 2, 111, 0, 115, 2, 97, 103, 0, 115, 2, 101, 116, 0, 115, 2, 111, 110, 0, 115, 2, 121, 109, 0, 115, 8, 2, 104, 0, 99, 105, 105, 3, 35, 89, 49, 122, 0, 104, 8, 3, 35, 91, 0, 115, 105, 111, 110, 1, 112, 3, 35, 91, 13, 50, 0, 99, 105, 1, 102, 2, 115, 3, 35, 91, 122, 0, 2, 115, 105, 115, 116, 3, 119, 0, 4, 1, 10, 2, 116, 121, 32, 3, 119, 89, 0, 2, 116, 101, 114, 110, 0, 2, 116, 114, 111, 108, 111, 103, 0, 2, 116, 114, 111, 110, 111, 0, 8, 2, 21, 0, 8, 2, 112, 101, 114, 0, 8, 2, 112, 105, 114, 101, 0, 115, 2, 117, 109, 112, 0, 115, 8, 2, 21, 0, 4, 104, 8, 2, 97, 3, 119, 91, 0, 104, 8, 2, 111, 0, 4, 1, 17, 67, 2, 112, 3, 120, 89, 0, 1, 17, 67, 2, 112, 101, 0, 1, 17, 67, 2, 116, 0, 2, 107, 0, 2, 116, 101, 114, 0, 8, 2, 107, 0, 115, 1, 108, 17, 67, 0, 115, 1, 112, 0, 115, 1, 114, 17, 67, 0, 1, 104, 99, 114, 117, 112, 2, 101, 3, 122, 89, 0, 1, 119, 2, 112, 3, 124, 89, 0, 4, 101, 1, 104, 112, 2, 32, 3, 138, 88, 0, 101, 1, 114, 2, 32, 0, 4, 1, 98, 2, 105, 3, 138, 89, 0, 1, 104, 2, 116, 101, 0, 1, 106, 2, 111, 110, 0, 1, 109, 2, 111, 110, 0, 1, 112, 2, 116, 101, 32, 0, 1, 116, 2, 116, 0, 8, 2, 111, 0, 116, 1, 119, 2, 101, 13, 3, 138, 89, 47, 0, 105, 97, 5, 3, 8, 3, 138, 90, 13, 0, 99, 1, 102, 2, 105, 97, 3, 138, 91, 0, 105, 97, 8, 3, 138, 91, 13, 0, 7, 6, 97, 116, 0, 111, 8, 2, 110, 97, 3, 2, 138, 47, 136, 0, 4, 1, 21, 2, 114, 97, 32, 3, 6, 126, 47, 0, 2, 117, 109, 0, 105, 1, 21, 2, 32, 3, 6, 126, 47, 122, 0, 4, 1, 21, 2, 111, 114, 32, 3, 6, 138, 47, 0, 1, 100, 2, 117, 109, 32, 0, 1, 108, 117, 2, 111, 114, 121, 0, 1, 109, 2, 117, 109, 32, 0, 2, 105, 109, 32, 0, 114, 105, 99, 101, 115, 3, 6, 138, 47, 34, 113, 89, 129, 88, 0, 114, 105, 120, 3, 6, 138, 47, 34, 122, 49, 89, 0, 105, 2, 97, 29, 3, 6, 138, 91, 0, 114, 121, 1, 21, 2, 32, 3, 8, 13, 47, 34, 122, 0, 104, 1, 21, 2, 105, 115, 3, 8, 13, 87, 0, 104, 121, 1, 10, 3, 8, 13, 87, 113, 0, 4, 1, 10, 2, 101, 101, 114, 32, 3, 13, 47, 0, 1, 10, 2, 105, 118, 101, 0, 1, 109, 2, 101, 114, 105, 0, 1, 109, 105, 108, 99, 2, 101, 0, 1, 110, 101, 115, 0, 1, 112, 2, 101, 114, 110, 0, 1, 116, 115, 2, 105, 115, 116, 0, 8, 115, 114, 101, 118, 0, 101, 1, 10, 2, 32, 28, 18, 0, 101, 1, 108, 97, 112, 2, 32, 0, 101, 1, 108, 117, 99, 97, 109, 2, 32, 0, 101, 1, 108, 117, 115, 110, 111, 99, 2, 32, 0, 101, 1, 109, 105, 116, 2, 32, 0, 101, 1, 110, 105, 100, 2, 32, 0, 101, 1, 110, 111, 105, 2, 32, 0, 101, 1, 114, 101, 100, 2, 32, 0, 101, 1, 114, 101, 112, 109, 2, 32, 0, 101, 8, 114, 97, 112, 101, 115, 32, 116, 105, 2, 32, 0, 111, 114, 121, 1, 10, 3, 13, 47, 114, 34, 37, 0, 105, 115, 109, 1, 10, 3, 13, 47, 122, 88, 13, 65, 0, 101, 114, 1, 109, 2, 110, 3, 13, 47, 128, 0, 111, 114, 121, 5, 3, 1, 10, 3, 13, 47, 149, 34, 37, 0, 117, 114, 101, 1, 108, 2, 32, 3, 13, 76, 114, 0, 4, 117, 114, 1, 99, 3, 13, 76, 143, 0, 117, 114, 1, 109, 0, 4, 1, 99, 2, 101, 17, 67, 3, 35, 47, 0, 1, 103, 2, 101, 97, 117, 0, 1, 108, 112, 2, 101, 97, 0, 1, 109, 2, 101, 114, 0, 1, 114, 116, 115, 2, 101, 103, 0, 8, 107, 2, 101, 114, 0, 116, 2, 105, 99, 0, 116, 2, 105, 116, 0, 101, 8, 115, 2, 108, 108, 3, 35, 47, 13, 0, 117, 115, 5, 3, 1, 116, 115, 3, 35, 47, 13, 89, 0, 101, 103, 111, 1, 99, 2, 114, 105, 99, 3, 35, 47, 122, 81, 6, 124, 0, 101, 103, 111, 1, 99, 3, 35, 47, 122, 81, 13, 0, 105, 8, 99, 2, 111, 110, 3, 35, 47, 137, 0, 104, 2, 108, 111, 110, 3, 35, 87, 0, 4, 1, 114, 102, 2, 101, 114, 110, 3, 119, 47, 0, 2, 111, 109, 105, 0, 8, 2, 108, 97, 110, 0, 8, 2, 114, 111, 99, 0, 116, 8, 2, 21, 0, 114, 111, 108, 1, 112, 3, 119, 47, 34, 136, 55, 0, 111, 8, 2, 110, 3, 119, 47, 136, 0, 4, 104, 1, 98, 3, 120, 87, 0, 104, 1, 112, 0, 1, 119, 2, 116, 3, 124, 47, 0, 104, 1, 102, 2, 101, 114, 3, 126, 86, 0, 4, 1, 21, 21, 2, 111, 114, 32, 3, 138, 47, 0, 1, 99, 2, 101, 114, 32, 0, 1, 102, 2, 97, 108, 0, 1, 108, 98, 2, 17, 65, 0, 1, 110, 2, 105, 118, 101, 0, 2, 111, 114, 32, 0, 5, 3, 1, 112, 2, 114, 105, 17, 65, 0, 101, 1, 110, 111, 105, 110, 2, 32, 0, 97, 1, 100, 3, 138, 47, 13, 0, 117, 115, 1, 116, 115, 3, 138, 47, 13, 89, 0, 114, 111, 110, 2, 32, 3, 138, 47, 34, 13, 50, 0, 101, 115, 1, 114, 97, 112, 2, 32, 3, 138, 47, 89, 0, 101, 100, 1, 109, 105, 116, 2, 32, 3, 138, 47, 113, 72, 0, 111, 114, 8, 103, 3, 138, 47, 114, 0, 4, 105, 110, 103, 1, 21, 2, 12, 12, 32, 3, 138, 47, 122, 68, 0, 105, 110, 103, 1, 109, 105, 116, 2, 32, 0, 101, 100, 1, 21, 2, 12, 12, 32, 3, 138, 47, 122, 72, 0, 104, 1, 98, 2, 101, 3, 138, 86, 0, 104, 101, 100, 2, 32, 3, 138, 86, 72, 0, 104, 101, 105, 3, 138, 87, 113, 122, 0, 2, 105, 97, 3, 138, 91, 0, 7, 6, 97, 117, 0, 116, 111, 8, 2, 110, 3, 2, 130, 47, 124, 0, 103, 109, 101, 110, 116, 3, 2, 130, 81, 65, 121, 50, 47, 0, 116, 104, 101, 110, 3, 2, 130, 87, 121, 50, 0, 99, 104, 8, 3, 2, 130, 101, 0, 116, 111, 8, 2, 21, 14, 128, 132, 132, 3, 4, 130, 47, 136, 0, 4, 1, 21, 2, 114, 105, 3, 6, 130, 0, 1, 115, 2, 114, 117, 115, 32, 0, 100, 2, 32, 3, 6, 130, 72, 0, 8, 2, 110, 116, 3, 120, 0, 4, 103, 104, 1, 108, 3, 120, 83, 0, 103, 104, 1, 114, 100, 0, 4, 1, 99, 2, 108, 105, 3, 124, 0, 5, 35, 1, 115, 2, 115, 0, 5, 35, 2, 115, 116, 114, 0, 108, 2, 116, 3, 124, 55, 0, 4, 3, 130, 0, 1, 110, 2, 116, 32, 0, 103, 104, 0, 103, 104, 1, 108, 115, 0, 108, 2, 107, 0, 116, 111, 2, 109, 97, 3, 130, 47, 13, 0, 114, 2, 32, 3, 132, 0, 4, 1, 21, 2, 116, 32, 3, 135, 0, 1, 103, 2, 115, 0, 2, 32, 0, 115, 1, 17, 67, 2, 32, 3, 135, 89, 0, 2, 118, 3, 136, 0, 7, 6, 97, 118, 0, 1, 108, 97, 2, 101, 114, 3, 6, 126, 84, 0, 4, 1, 99, 115, 2, 101, 110, 3, 35, 84, 0, 1, 100, 2, 101, 110, 0, 1, 106, 2, 101, 108, 0, 1, 108, 2, 101, 110, 0, 1, 108, 2, 105, 0, 1, 114, 2, 101, 108, 0, 97, 114, 2, 105, 99, 3, 35, 84, 13, 34, 0, 4, 2, 97, 105, 108, 3, 119, 84, 0, 2, 101, 110, 103, 0, 2, 111, 17, 65, 0, 8, 2, 101, 114, 17, 67, 0, 111, 119, 3, 119, 84, 135, 0, 4, 1, 106, 2, 97, 3, 126, 84, 0, 1, 108, 115, 2, 105, 0, 4, 1, 100, 2, 105, 100, 3, 138, 84, 0, 1, 102, 2, 111, 0, 1, 108, 102, 2, 111, 0, 1, 115, 2, 105, 0, 1, 115, 2, 111, 0, 8, 2, 111, 110, 0, 105, 8, 2, 17, 65, 3, 138, 84, 122, 0, 7, 6, 98, 101, 0, 103, 8, 2, 17, 65, 110, 25, 3, 71, 2, 122, 81, 0, 116, 97, 8, 3, 71, 4, 129, 47, 13, 0, 116, 97, 5, 3, 8, 3, 71, 4, 138, 47, 13, 0, 110, 101, 118, 111, 3, 71, 13, 50, 121, 84, 13, 0, 4, 2, 103, 17, 65, 3, 71, 113, 0, 2, 103, 114, 0, 2, 108, 97, 116, 0, 2, 108, 105, 101, 0, 2, 109, 117, 0, 2, 113, 117, 0, 2, 115, 101, 101, 0, 2, 115, 105, 101, 0, 2, 116, 114, 97, 121, 0, 8, 2, 17, 67, 17, 65, 0, 8, 2, 99, 108, 0, 8, 2, 100, 114, 97, 0, 8, 2, 102, 0, 8, 2, 108, 108, 105, 0, 8, 2, 115, 17, 67, 0, 8, 2, 115, 116, 111, 0, 8, 2, 116, 17, 67, 0, 8, 2, 119, 0, 104, 97, 2, 118, 3, 71, 113, 107, 138, 0, 114, 8, 2, 115, 3, 71, 114, 0, 4, 8, 2, 17, 67, 11, 3, 71, 121, 0, 8, 2, 99, 107, 0, 8, 2, 99, 113, 0, 8, 2, 100, 17, 67, 0, 8, 2, 103, 103, 0, 8, 2, 108, 17, 67, 0, 8, 2, 115, 116, 105, 97, 0, 8, 2, 116, 104, 0, 8, 2, 118, 17, 65, 0, 110, 101, 8, 3, 71, 121, 50, 122, 0, 4, 100, 1, 104, 2, 32, 3, 71, 121, 72, 0, 100, 1, 114, 101, 2, 32, 0, 100, 1, 116, 2, 32, 0, 4, 1, 121, 97, 109, 2, 32, 3, 71, 129, 0, 8, 2, 98, 0, 7, 6, 98, 105, 0, 8, 2, 17, 67, 21, 21, 3, 2, 71, 137, 0, 4, 2, 115, 101, 99, 3, 71, 2, 137, 0, 8, 2, 101, 110, 0, 111, 8, 2, 21, 14, 128, 132, 131, 3, 71, 4, 137, 136, 0, 2, 110, 111, 99, 3, 71, 113, 0, 4, 2, 98, 108, 105, 3, 71, 122, 0, 2, 98, 117, 0, 2, 99, 107, 0, 2, 103, 12, 0, 2, 108, 105, 111, 0, 2, 110, 109, 0, 2, 111, 17, 67, 32, 0, 2, 111, 117, 115, 0, 2, 114, 105, 0, 2, 114, 121, 0, 2, 115, 99, 0, 2, 115, 104, 0, 2, 115, 109, 0, 2, 122, 12, 0, 8, 2, 17, 67, 11, 0, 8, 2, 108, 17, 67, 0, 8, 2, 110, 103, 0, 8, 2, 116, 17, 67, 0, 8, 2, 116, 117, 109, 101, 110, 3, 71, 123, 0, 114, 2, 17, 67, 3, 71, 128, 0, 4, 2, 115, 113, 3, 71, 129, 0, 2, 115, 116, 114, 0, 4, 1, 21, 2, 111, 115, 17, 65, 3, 71, 137, 0, 1, 111, 2, 116, 17, 65, 0, 2, 99, 121, 99, 0, 2, 107, 101, 114, 0, 2, 110, 97, 114, 121, 0, 2, 110, 100, 0, 2, 111, 116, 105, 99, 0, 8, 2, 32, 0, 8, 2, 111, 18, 75, 12, 0, 103, 104, 2, 116, 0, 4, 111, 2, 110, 105, 3, 71, 137, 6, 124, 0, 111, 2, 112, 115, 0, 114, 5, 5, 2, 17, 67, 3, 71, 147, 0, 7, 6, 99, 104, 0, 101, 109, 101, 110, 116, 2, 32, 3, 8, 91, 65, 151, 0, 4, 1, 21, 2, 105, 97, 3, 49, 0, 1, 97, 2, 105, 108, 0, 1, 97, 114, 98, 0, 1, 97, 114, 116, 0, 1, 101, 2, 111, 0, 1, 101, 109, 2, 97, 0, 1, 101, 116, 2, 25, 0, 1, 105, 109, 2, 97, 0, 1, 110, 111, 114, 98, 0, 1, 111, 2, 32, 0, 1, 114, 97, 2, 105, 118, 101, 0, 1, 114, 97, 17, 67, 21, 21, 2, 32, 0, 1, 114, 111, 2, 105, 0, 2, 97, 101, 0, 2, 97, 115, 109, 0, 2, 101, 109, 0, 2, 105, 99, 32, 0, 2, 105, 111, 0, 2, 105, 114, 17, 65, 0, 2, 105, 115, 17, 67, 0, 2, 111, 108, 0, 2, 111, 110, 100, 0, 2, 111, 114, 17, 65, 0, 2, 111, 114, 100, 0, 2, 114, 0, 8, 2, 18, 66, 17, 71, 0, 8, 97, 116, 0, 8, 114, 97, 2, 17, 65, 0, 8, 114, 97, 2, 97, 0, 8, 114, 111, 2, 101, 115, 0, 4, 97, 2, 114, 105, 115, 3, 49, 13, 0, 111, 114, 1, 110, 97, 0, 114, 121, 2, 115, 97, 3, 49, 34, 122, 0, 108, 111, 114, 111, 3, 49, 55, 4, 133, 34, 136, 0, 108, 111, 2, 114, 3, 49, 55, 133, 0, 111, 105, 114, 3, 49, 58, 145, 0, 105, 8, 114, 97, 2, 21, 3, 49, 122, 0, 97, 8, 2, 111, 3, 49, 138, 0, 97, 111, 115, 3, 49, 138, 124, 89, 0, 4, 3, 76, 0, 1, 97, 116, 0, 1, 111, 111, 2, 32, 0, 1, 114, 97, 2, 101, 114, 0, 2, 111, 114, 101, 32, 0, 8, 2, 17, 71, 0, 8, 2, 111, 108, 97, 0, 101, 1, 97, 98, 3, 76, 13, 0, 97, 114, 105, 111, 2, 116, 3, 76, 35, 34, 141, 0, 4, 1, 97, 17, 67, 2, 101, 3, 91, 0, 1, 97, 116, 115, 0, 1, 101, 2, 101, 108, 0, 1, 101, 114, 99, 0, 1, 105, 102, 0, 1, 105, 108, 99, 0, 1, 105, 110, 0, 1, 111, 99, 105, 0, 1, 111, 108, 99, 0, 2, 97, 115, 115, 0, 2, 97, 116, 101, 97, 0, 2, 101, 102, 0, 2, 101, 118, 0, 2, 105, 111, 32, 0, 2, 117, 114, 101, 0, 2, 117, 116, 101, 0, 2, 195, 169, 12, 0, 8, 2, 97, 110, 100, 17, 65, 0, 8, 2, 97, 114, 116, 114, 101, 0, 8, 111, 2, 101, 0, 101, 1, 105, 2, 32, 24, 0, 105, 111, 110, 3, 91, 13, 50, 0, 97, 112, 2, 101, 114, 111, 3, 91, 35, 48, 0, 105, 99, 97, 2, 103, 3, 91, 113, 49, 126, 0, 105, 99, 97, 2, 110, 3, 91, 113, 49, 138, 0, 4, 97, 117, 2, 102, 3, 91, 136, 0, 97, 117, 2, 118, 0, 101, 122, 3, 91, 138, 0, 7, 6, 99, 111, 0, 4, 2, 110, 115, 116, 105, 116, 117, 17, 65, 3, 49, 2, 124, 0, 8, 2, 110, 102, 105, 100, 101, 0, 8, 2, 110, 115, 117, 108, 116, 0, 110, 8, 2, 21, 3, 49, 2, 124, 50, 0, 110, 116, 114, 97, 99, 2, 116, 3, 49, 2, 124, 50, 47, 34, 35, 49, 0, 110, 116, 114, 97, 114, 3, 49, 2, 124, 50, 47, 34, 140, 0, 110, 115, 101, 114, 2, 118, 3, 49, 2, 124, 50, 89, 128, 0, 109, 112, 8, 2, 116, 114, 3, 49, 2, 124, 65, 0, 4, 2, 104, 97, 98, 3, 49, 2, 136, 0, 8, 2, 97, 103, 0, 97, 2, 108, 101, 115, 3, 49, 2, 136, 13, 0, 4, 2, 109, 112, 117, 116, 97, 3, 49, 4, 124, 0, 8, 2, 110, 116, 114, 111, 118, 0, 114, 114, 101, 115, 112, 111, 3, 49, 4, 124, 34, 122, 89, 48, 6, 124, 0, 110, 116, 114, 97, 8, 2, 17, 67, 21, 14, 128, 132, 134, 3, 49, 4, 124, 50, 47, 34, 13, 0, 110, 100, 101, 8, 2, 115, 99, 3, 49, 4, 124, 50, 72, 113, 0, 8, 2, 101, 17, 67, 14, 128, 132, 130, 3, 49, 4, 136, 0, 117, 110, 116, 101, 114, 8, 2, 21, 14, 128, 132, 135, 3, 49, 6, 135, 50, 47, 13, 0, 112, 111, 108, 121, 8, 3, 49, 6, 136, 48, 4, 124, 55, 122, 0, 4, 2, 108, 108, 97, 98, 3, 49, 13, 0, 2, 108, 108, 97, 112, 0, 2, 108, 108, 97, 116, 0, 2, 108, 108, 101, 99, 0, 2, 108, 108, 105, 100, 0, 2, 108, 108, 105, 115, 0, 2, 108, 108, 117, 0, 2, 108, 111, 115, 115, 0, 2, 109, 109, 101, 110, 115, 0, 2, 110, 115, 101, 99, 117, 0, 2, 110, 116, 114, 111, 108, 12, 0, 2, 114, 114, 101, 99, 116, 0, 2, 114, 114, 111, 0, 2, 114, 114, 117, 112, 0, 8, 2, 109, 21, 0, 8, 2, 109, 112, 108, 0, 8, 2, 110, 99, 105, 0, 8, 2, 110, 102, 105, 103, 117, 0, 8, 2, 110, 110, 101, 99, 116, 0, 8, 2, 110, 110, 101, 120, 0, 8, 2, 110, 115, 105, 0, 8, 2, 110, 118, 101, 110, 17, 65, 0, 8, 2, 110, 118, 105, 0, 110, 115, 105, 100, 101, 114, 3, 49, 13, 50, 89, 122, 72, 114, 0, 110, 110, 105, 118, 3, 49, 13, 50, 137, 84, 0, 108, 108, 101, 2, 103, 105, 3, 49, 13, 55, 129, 0, 4, 109, 109, 117, 110, 2, 97, 3, 49, 13, 65, 57, 134, 50, 0, 109, 109, 117, 110, 2, 105, 99, 0, 109, 101, 2, 100, 105, 3, 49, 13, 65, 129, 0, 4, 2, 109, 98, 97, 3, 49, 124, 0, 2, 109, 98, 105, 110, 97, 0, 2, 109, 101, 100, 121, 0, 2, 109, 109, 97, 32, 0, 2, 109, 109, 97, 110, 100, 97, 0, 2, 109, 109, 101, 110, 0, 2, 109, 109, 101, 114, 99, 101, 0, 2, 109, 109, 111, 100, 111, 114, 0, 2, 109, 109, 117, 116, 97, 0, 2, 109, 112, 101, 110, 115, 0, 2, 109, 112, 101, 114, 0, 2, 109, 112, 105, 108, 97, 0, 2, 109, 112, 108, 101, 109, 0, 2, 109, 112, 108, 101, 120, 32, 0, 2, 109, 112, 108, 105, 99, 97, 0, 2, 109, 112, 108, 105, 109, 0, 2, 109, 112, 111, 115, 105, 116, 0, 2, 109, 112, 111, 115, 116, 0, 2, 109, 112, 111, 117, 0, 2, 109, 112, 114, 101, 104, 101, 110, 0, 2, 109, 112, 114, 111, 109, 0, 2, 110, 115, 101, 99, 0, 2, 110, 115, 111, 110, 0, 2, 110, 115, 116, 97, 110, 0, 2, 110, 115, 116, 105, 116, 0, 2, 110, 116, 105, 110, 101, 0, 8, 2, 109, 105, 0, 8, 2, 109, 114, 0, 8, 2, 110, 99, 101, 112, 116, 32, 0, 8, 2, 110, 99, 114, 101, 116, 0, 8, 2, 110, 100, 105, 109, 0, 8, 2, 110, 100, 111, 109, 0, 8, 2, 110, 100, 111, 114, 0, 8, 2, 110, 100, 117, 105, 116, 0, 8, 2, 110, 102, 101, 114, 101, 110, 0, 8, 2, 110, 102, 105, 100, 0, 8, 2, 110, 102, 105, 115, 0, 8, 2, 110, 102, 108, 117, 0, 8, 2, 110, 103, 114, 101, 0, 8, 2, 110, 105, 0, 8, 2, 110, 106, 117, 103, 0, 8, 2, 110, 113, 117, 101, 0, 8, 2, 110, 115, 99, 0, 8, 2, 110, 115, 111, 108, 101, 0, 8, 2, 110, 115, 116, 97, 98, 108, 0, 8, 2, 110, 115, 116, 105, 112, 0, 8, 2, 110, 115, 117, 108, 0, 8, 2, 110, 116, 97, 99, 116, 0, 8, 2, 110, 116, 101, 109, 112, 108, 0, 8, 2, 110, 116, 101, 120, 116, 0, 8, 2, 110, 116, 111, 117, 114, 0, 8, 2, 110, 116, 114, 17, 65, 0, 8, 2, 110, 116, 114, 105, 98, 0, 8, 2, 110, 118, 111, 121, 0, 8, 2, 110, 119, 0, 8, 2, 114, 114, 105, 0, 114, 111, 2, 108, 108, 3, 49, 124, 34, 124, 0, 112, 121, 8, 3, 49, 124, 48, 122, 0, 110, 110, 111, 105, 8, 2, 115, 3, 49, 124, 50, 13, 0, 110, 116, 114, 97, 115, 116, 8, 3, 49, 124, 50, 47, 34, 120, 89, 47, 0, 110, 103, 114, 101, 115, 115, 5, 3, 8, 3, 49, 124, 50, 81, 34, 13, 89, 0, 110, 103, 114, 117, 3, 49, 124, 50, 81, 34, 134, 0, 110, 102, 105, 8, 2, 100, 101, 110, 3, 49, 124, 50, 83, 122, 0, 110, 118, 97, 2, 108, 3, 49, 124, 50, 84, 13, 0, 4, 110, 99, 101, 8, 2, 110, 116, 114, 97, 3, 49, 124, 50, 89, 13, 0, 110, 115, 101, 114, 2, 118, 97, 116, 105, 111, 0, 110, 115, 101, 8, 2, 113, 3, 49, 124, 50, 89, 122, 0, 109, 109, 111, 110, 3, 49, 124, 65, 13, 50, 0, 109, 112, 97, 114, 97, 98, 3, 49, 124, 65, 48, 13, 34, 13, 71, 0, 109, 112, 101, 2, 116, 17, 65, 110, 3, 49, 124, 65, 48, 122, 0, 109, 109, 117, 110, 3, 49, 124, 65, 57, 134, 50, 0, 4, 2, 109, 101, 32, 3, 49, 125, 0, 2, 109, 112, 97, 110, 121, 0, 2, 109, 112, 97, 115, 115, 32, 0, 8, 2, 109, 102, 0, 8, 2, 110, 106, 117, 114, 0, 109, 101, 2, 98, 3, 49, 125, 65, 0, 109, 102, 111, 114, 116, 97, 98, 3, 49, 125, 65, 83, 47, 13, 71, 0, 109, 102, 111, 114, 2, 116, 3, 49, 125, 65, 83, 114, 0, 109, 105, 110, 103, 3, 49, 125, 65, 113, 68, 0, 8, 2, 109, 97, 3, 49, 136, 0, 97, 2, 108, 105, 116, 3, 49, 136, 13, 0, 115, 116, 97, 114, 8, 3, 49, 136, 89, 47, 127, 0, 101, 8, 2, 108, 3, 89, 129, 0, 7, 6, 100, 101, 0, 8, 2, 104, 121, 100, 3, 4, 72, 129, 0, 4, 2, 97, 99, 116, 3, 72, 2, 129, 0, 2, 97, 114, 99, 0, 2, 102, 108, 97, 116, 0, 2, 112, 101, 114, 0, 2, 112, 111, 108, 0, 2, 112, 111, 112, 0, 2, 114, 101, 103, 0, 2, 116, 111, 120, 0, 2, 116, 114, 97, 105, 0, 2, 118, 97, 108, 0, 8, 2, 101, 109, 112, 0, 8, 2, 111, 0, 8, 2, 116, 104, 0, 110, 105, 2, 116, 114, 105, 3, 72, 2, 129, 50, 137, 0, 4, 115, 2, 101, 103, 3, 72, 2, 129, 89, 0, 115, 2, 101, 110, 0, 115, 2, 117, 108, 0, 115, 116, 97, 2, 98, 3, 72, 2, 129, 89, 47, 138, 0, 115, 101, 2, 108, 3, 72, 4, 129, 89, 113, 0, 4, 2, 99, 111, 114, 117, 3, 72, 113, 0, 2, 100, 117, 0, 2, 109, 97, 0, 2, 109, 101, 110, 0, 2, 109, 105, 115, 101, 0, 2, 109, 111, 99, 114, 97, 99, 0, 2, 109, 111, 114, 0, 2, 109, 111, 116, 0, 2, 109, 117, 114, 0, 2, 114, 105, 17, 67, 0, 2, 114, 111, 103, 0, 8, 2, 98, 97, 0, 8, 2, 102, 21, 0, 8, 2, 103, 21, 0, 8, 2, 106, 0, 8, 2, 108, 21, 0, 8, 2, 110, 111, 0, 8, 2, 112, 21, 0, 8, 2, 114, 97, 105, 0, 8, 2, 116, 21, 0, 8, 2, 118, 17, 65, 0, 116, 101, 115, 116, 3, 72, 113, 47, 121, 89, 47, 0, 116, 101, 114, 3, 72, 113, 47, 128, 0, 116, 101, 114, 2, 105, 3, 72, 113, 47, 141, 34, 0, 110, 105, 8, 2, 97, 3, 72, 113, 50, 137, 0, 109, 101, 97, 3, 72, 113, 65, 6, 129, 0, 109, 111, 2, 98, 105, 3, 72, 113, 65, 136, 0, 4, 115, 8, 2, 101, 114, 3, 72, 113, 88, 0, 115, 8, 2, 105, 0, 115, 115, 8, 0, 4, 115, 2, 105, 115, 3, 72, 113, 89, 0, 115, 8, 2, 21, 0, 4, 2, 99, 105, 98, 3, 72, 121, 0, 2, 99, 105, 108, 0, 2, 99, 105, 109, 0, 2, 99, 107, 0, 2, 99, 111, 114, 0, 2, 99, 114, 101, 109, 0, 2, 102, 101, 114, 101, 110, 0, 2, 102, 105, 110, 105, 116, 0, 2, 102, 116, 0, 2, 108, 97, 119, 0, 2, 108, 101, 103, 0, 2, 108, 105, 99, 97, 0, 2, 108, 112, 104, 0, 2, 108, 118, 12, 0, 2, 109, 97, 103, 111, 103, 0, 2, 112, 114, 101, 99, 97, 0, 2, 112, 116, 0, 2, 112, 117, 116, 0, 2, 114, 17, 65, 17, 67, 97, 116, 105, 111, 0, 2, 114, 101, 108, 0, 2, 116, 111, 110, 0, 2, 116, 114, 105, 0, 2, 118, 105, 108, 0, 2, 118, 111, 110, 0, 8, 2, 108, 108, 0, 8, 2, 108, 116, 0, 115, 2, 99, 97, 0, 112, 111, 2, 115, 105, 116, 105, 3, 72, 121, 48, 13, 0, 99, 97, 2, 100, 101, 110, 3, 72, 121, 49, 13, 0, 108, 117, 2, 103, 3, 72, 121, 55, 57, 134, 0, 118, 97, 115, 8, 3, 72, 121, 84, 13, 89, 0, 115, 2, 105, 103, 110, 97, 3, 72, 121, 88, 0, 4, 115, 2, 101, 99, 3, 72, 121, 89, 0, 115, 2, 105, 99, 0, 115, 2, 111, 108, 0, 115, 2, 112, 111, 116, 0, 115, 8, 2, 104, 0, 115, 8, 2, 107, 0, 115, 116, 105, 3, 72, 121, 89, 47, 122, 0, 4, 8, 2, 98, 105, 108, 3, 72, 123, 0, 8, 2, 99, 21, 0, 4, 2, 99, 101, 110, 99, 3, 72, 129, 0, 2, 99, 111, 109, 0, 2, 99, 114, 101, 97, 115, 0, 2, 116, 97, 105, 108, 0, 2, 116, 111, 117, 0, 2, 118, 105, 97, 0, 2, 118, 105, 111, 0, 109, 8, 2, 111, 110, 105, 3, 72, 129, 65, 0, 98, 117, 2, 103, 3, 72, 129, 71, 4, 125, 0, 7, 6, 100, 105, 0, 4, 2, 115, 98, 101, 21, 3, 4, 72, 122, 0, 2, 115, 99, 111, 110, 0, 2, 115, 111, 98, 0, 2, 115, 112, 111, 115, 115, 0, 2, 115, 112, 114, 111, 112, 0, 8, 2, 115, 97, 21, 0, 8, 2, 115, 114, 101, 0, 4, 8, 2, 115, 101, 14, 128, 132, 131, 3, 4, 72, 122, 89, 0, 115, 8, 2, 105, 110, 14, 128, 132, 131, 0, 115, 97, 8, 2, 112, 3, 4, 72, 122, 89, 13, 0, 4, 2, 103, 114, 101, 115, 3, 72, 2, 137, 0, 2, 109, 101, 110, 115, 0, 2, 111, 120, 0, 2, 118, 101, 114, 17, 67, 0, 2, 118, 101, 115, 116, 0, 2, 118, 117, 108, 0, 8, 2, 104, 21, 0, 103, 101, 2, 115, 116, 3, 72, 2, 137, 75, 121, 0, 4, 2, 99, 116, 97, 116, 3, 72, 113, 0, 2, 102, 102, 114, 97, 99, 0, 2, 102, 102, 117, 115, 0, 2, 109, 105, 110, 0, 2, 115, 97, 115, 116, 0, 2, 115, 99, 111, 118, 0, 2, 115, 105, 110, 116, 0, 2, 118, 105, 100, 0, 2, 118, 105, 110, 0, 2, 118, 105, 115, 0, 2, 118, 111, 114, 99, 0, 8, 2, 115, 21, 0, 8, 2, 115, 104, 101, 118, 12, 0, 115, 8, 2, 104, 17, 65, 3, 72, 113, 89, 0, 4, 2, 115, 99, 32, 3, 72, 122, 0, 2, 115, 99, 111, 32, 0, 2, 115, 99, 111, 114, 100, 32, 0, 2, 115, 99, 111, 116, 0, 2, 115, 99, 111, 117, 110, 116, 0, 2, 115, 104, 17, 67, 0, 2, 115, 104, 32, 0, 2, 115, 107, 0, 2, 115, 111, 108, 0, 2, 115, 112, 111, 115, 105, 116, 0, 2, 115, 115, 105, 100, 0, 2, 115, 115, 105, 112, 0, 2, 115, 115, 111, 108, 117, 0, 2, 115, 115, 111, 110, 0, 2, 115, 116, 97, 110, 0, 2, 115, 116, 105, 108, 108, 97, 116, 101, 0, 2, 115, 116, 114, 105, 0, 108, 105, 2, 103, 3, 72, 122, 55, 122, 0, 118, 105, 2, 100, 101, 110, 3, 72, 122, 84, 122, 0, 115, 99, 105, 112, 108, 105, 3, 72, 122, 89, 122, 48, 55, 122, 0, 4, 2, 99, 104, 114, 111, 3, 72, 137, 0, 2, 115, 115, 101, 99, 116, 0, 2, 115, 117, 108, 0, 4, 97, 8, 2, 103, 111, 110, 3, 72, 137, 6, 35, 0, 97, 8, 2, 110, 0, 97, 8, 3, 72, 137, 13, 0, 99, 104, 111, 2, 116, 3, 72, 137, 49, 6, 124, 0, 108, 117, 2, 116, 3, 72, 137, 55, 6, 134, 0, 97, 8, 2, 108, 3, 72, 144, 0, 7, 6, 101, 97, 0, 4, 1, 104, 2, 100, 109, 17, 65, 21, 3, 2, 121, 0, 1, 104, 2, 100, 113, 0, 1, 114, 2, 32, 3, 6, 141, 0, 110, 1, 112, 2, 32, 3, 6, 141, 50, 0, 1, 21, 2, 116, 105, 118, 101, 3, 8, 141, 0, 4, 1, 10, 2, 98, 105, 108, 105, 3, 13, 0, 1, 10, 2, 98, 108, 0, 98, 108, 121, 1, 10, 3, 13, 71, 55, 2, 122, 0, 117, 2, 116, 3, 57, 134, 0, 4, 1, 17, 67, 2, 108, 116, 3, 121, 0, 1, 17, 67, 2, 118, 101, 110, 0, 1, 100, 2, 102, 0, 1, 100, 2, 116, 104, 0, 1, 100, 110, 101, 2, 118, 0, 1, 102, 2, 116, 104, 0, 1, 104, 2, 116, 104, 101, 114, 0, 1, 108, 2, 100, 101, 110, 0, 1, 114, 2, 100, 105, 101, 100, 0, 1, 114, 2, 100, 105, 108, 121, 0, 1, 114, 2, 100, 121, 0, 1, 114, 98, 2, 100, 0, 1, 114, 98, 2, 115, 0, 1, 114, 98, 2, 116, 104, 0, 1, 114, 104, 116, 2, 100, 0, 1, 114, 104, 116, 2, 116, 0, 1, 114, 112, 115, 2, 100, 0, 1, 114, 116, 2, 99, 104, 101, 114, 0, 1, 114, 116, 2, 100, 0, 1, 116, 115, 2, 100, 0, 1, 119, 115, 2, 116, 0, 1, 122, 2, 108, 111, 0, 8, 104, 2, 118, 105, 0, 8, 108, 2, 109, 105, 0, 8, 114, 100, 2, 100, 0, 112, 111, 1, 119, 3, 121, 48, 13, 0, 108, 111, 117, 1, 106, 3, 121, 55, 13, 0, 109, 2, 116, 32, 3, 121, 65, 48, 0, 4, 100, 1, 100, 3, 121, 72, 0, 100, 1, 104, 0, 100, 101, 100, 8, 108, 3, 121, 72, 113, 72, 0, 118, 121, 1, 104, 3, 121, 84, 37, 0, 4, 116, 104, 1, 108, 3, 121, 86, 0, 116, 104, 1, 119, 0, 4, 115, 2, 97, 110, 3, 121, 88, 0, 115, 2, 101, 110, 0, 115, 117, 114, 3, 121, 90, 114, 0, 4, 114, 1, 104, 2, 107, 3, 127, 0, 114, 1, 104, 2, 116, 0, 114, 1, 104, 2, 116, 104, 0, 4, 114, 1, 104, 2, 100, 3, 128, 0, 114, 1, 104, 2, 115, 101, 0, 114, 1, 104, 101, 114, 2, 115, 0, 114, 1, 108, 2, 110, 0, 114, 1, 112, 2, 108, 0, 114, 1, 115, 2, 99, 104, 0, 114, 1, 121, 2, 110, 0, 114, 2, 116, 104, 0, 114, 8, 2, 108, 0, 114, 8, 2, 110, 0, 4, 3, 129, 0, 1, 17, 67, 29, 2, 110, 32, 0, 1, 98, 2, 110, 0, 1, 102, 2, 108, 116, 0, 1, 104, 2, 118, 0, 1, 109, 2, 108, 116, 0, 1, 115, 17, 67, 2, 32, 0, 2, 110, 100, 101, 114, 3, 129, 6, 35, 0, 1, 114, 99, 2, 116, 3, 129, 6, 138, 0, 1, 104, 116, 2, 116, 114, 105, 3, 129, 35, 0, 100, 109, 101, 1, 114, 3, 129, 72, 65, 129, 0, 103, 101, 114, 3, 129, 81, 114, 0, 116, 104, 1, 114, 98, 2, 101, 3, 129, 86, 0, 115, 111, 2, 110, 3, 129, 88, 13, 0, 115, 101, 2, 21, 3, 129, 89, 0, 4, 117, 3, 136, 0, 117, 120, 0, 4, 1, 114, 98, 2, 107, 3, 138, 0, 1, 114, 103, 2, 116, 0, 1, 116, 115, 2, 107, 0, 4, 114, 1, 98, 3, 140, 0, 114, 1, 116, 2, 17, 65, 0, 114, 1, 119, 0, 114, 1, 119, 115, 0, 4, 1, 21, 2, 32, 3, 141, 0, 1, 104, 116, 2, 116, 0, 8, 98, 2, 116, 114, 105, 0, 110, 2, 32, 3, 141, 50, 0, 108, 1, 10, 2, 32, 3, 141, 55, 0, 4, 114, 3, 142, 0, 114, 1, 98, 2, 100, 0, 114, 1, 119, 2, 121, 0, 7, 6, 101, 100, 0, 4, 1, 21, 2, 105, 101, 110, 3, 6, 129, 72, 0, 1, 99, 2, 101, 32, 0, 1, 104, 2, 114, 97, 0, 1, 104, 2, 114, 97, 108, 0, 1, 104, 2, 114, 111, 110, 0, 1, 115, 114, 2, 101, 0, 117, 114, 1, 21, 3, 6, 129, 75, 114, 0, 1, 10, 2, 121, 3, 13, 72, 0, 4, 1, 99, 21, 2, 32, 14, 128, 155, 130, 3, 47, 0, 1, 102, 21, 2, 32, 14, 128, 155, 130, 0, 1, 104, 99, 10, 2, 32, 14, 128, 139, 130, 0, 1, 104, 115, 10, 2, 32, 14, 128, 139, 130, 0, 1, 107, 21, 2, 32, 14, 128, 155, 130, 0, 1, 112, 21, 2, 32, 14, 128, 155, 130, 0, 1, 115, 115, 21, 2, 32, 14, 128, 152, 130, 0, 1, 120, 21, 2, 32, 14, 128, 138, 130, 0, 4, 1, 17, 67, 21, 2, 32, 14, 128, 155, 130, 3, 72, 0, 1, 21, 21, 2, 32, 14, 128, 155, 130, 0, 1, 103, 21, 2, 32, 14, 128, 138, 129, 0, 1, 105, 17, 65, 2, 32, 14, 128, 153, 130, 0, 1, 108, 99, 2, 32, 14, 128, 136, 129, 0, 1, 108, 101, 2, 32, 14, 128, 152, 130, 0, 1, 110, 101, 10, 2, 32, 14, 128, 136, 130, 0, 1, 114, 101, 21, 21, 2, 32, 14, 128, 136, 130, 0, 1, 121, 2, 32, 14, 128, 136, 130, 0, 4, 1, 104, 115, 17, 67, 21, 2, 32, 3, 121, 72, 0, 1, 119, 121, 2, 32, 0, 5, 8, 1, 100, 21, 2, 32, 14, 128, 155, 130, 0, 5, 8, 1, 116, 21, 2, 32, 14, 128, 155, 130, 0, 97, 108, 1, 112, 3, 121, 72, 118, 0, 105, 98, 1, 114, 99, 3, 121, 72, 122, 71, 0, 103, 2, 101, 13, 3, 121, 75, 0, 4, 1, 114, 100, 21, 2, 32, 3, 122, 72, 0, 1, 114, 102, 21, 2, 32, 14, 128, 136, 130, 0, 108, 121, 2, 32, 3, 122, 72, 55, 2, 122, 0, 4, 1, 100, 21, 2, 32, 14, 128, 155, 130, 3, 123, 72, 0, 1, 116, 21, 2, 32, 14, 128, 155, 130, 0, 4, 1, 109, 2, 105, 97, 3, 129, 72, 0, 1, 109, 2, 105, 111, 0, 1, 109, 2, 105, 117, 0, 1, 112, 2, 101, 32, 0, 1, 116, 2, 105, 0, 1, 119, 115, 0, 105, 97, 116, 101, 1, 109, 21, 3, 129, 72, 113, 13, 47, 0, 7, 6, 101, 105, 0, 4, 1, 108, 2, 115, 3, 121, 0, 99, 101, 1, 108, 2, 115, 116, 0, 4, 1, 102, 2, 116, 32, 3, 122, 0, 1, 102, 2, 116, 101, 0, 2, 110, 97, 116, 101, 0, 4, 1, 21, 2, 110, 32, 3, 129, 0, 1, 21, 2, 110, 101, 0, 1, 99, 0, 2, 116, 104, 0, 2, 118, 0, 2, 122, 0, 103, 104, 1, 108, 0, 108, 1, 110, 3, 129, 55, 0, 103, 104, 1, 107, 3, 129, 87, 0, 4, 1, 98, 2, 110, 103, 3, 129, 122, 0, 1, 104, 116, 2, 115, 17, 67, 0, 4, 1, 104, 2, 116, 32, 3, 137, 0, 2, 115, 116, 101, 114, 0, 5, 35, 2, 116, 104, 101, 114, 0, 8, 0, 103, 104, 1, 104, 2, 116, 0, 114, 8, 3, 137, 34, 0, 4, 115, 2, 101, 3, 137, 88, 0, 115, 8, 115, 2, 109, 0, 99, 104, 3, 137, 101, 0, 4, 3, 138, 0, 103, 2, 110, 0, 103, 104, 0, 103, 104, 1, 108, 115, 0, 103, 104, 116, 104, 3, 138, 47, 87, 0, 114, 3, 140, 0, 114, 1, 119, 3, 142, 0, 7, 6, 101, 108, 0, 4, 8, 2, 17, 65, 3, 2, 122, 55, 0, 108, 8, 2, 105, 112, 0, 101, 8, 2, 99, 116, 114, 111, 3, 2, 122, 55, 4, 121, 0, 101, 8, 2, 99, 116, 114, 111, 108, 3, 2, 122, 55, 121, 0, 105, 116, 8, 3, 2, 122, 55, 129, 47, 0, 4, 1, 99, 120, 2, 32, 3, 6, 121, 55, 0, 1, 108, 108, 97, 2, 111, 0, 1, 110, 110, 111, 2, 32, 0, 1, 112, 2, 32, 0, 2, 105, 103, 105, 0, 108, 97, 1, 10, 2, 32, 3, 6, 121, 55, 13, 0, 111, 112, 1, 118, 3, 6, 121, 55, 13, 48, 0, 108, 105, 1, 21, 2, 32, 3, 6, 121, 55, 122, 0, 4, 1, 100, 2, 105, 118, 3, 13, 55, 0, 1, 118, 2, 111, 99, 0, 108, 1, 10, 2, 111, 117, 115, 0, 108, 101, 114, 1, 118, 10, 2, 32, 3, 13, 55, 13, 0, 108, 105, 110, 103, 1, 10, 3, 13, 55, 113, 68, 0, 1, 115, 2, 101, 99, 116, 3, 113, 55, 0, 4, 1, 10, 2, 32, 3, 118, 0, 1, 10, 2, 115, 32, 0, 1, 116, 2, 112, 0, 4, 1, 98, 105, 99, 2, 32, 3, 121, 55, 0, 1, 108, 108, 97, 0, 5, 8, 1, 10, 2, 32, 0, 5, 8, 1, 10, 2, 115, 32, 0, 111, 2, 113, 3, 121, 55, 13, 0, 115, 101, 8, 3, 121, 55, 89, 0, 101, 8, 2, 99, 116, 114, 111, 110, 3, 121, 55, 121, 0, 4, 101, 8, 2, 103, 3, 121, 55, 122, 0, 101, 8, 2, 112, 0, 101, 8, 2, 118, 97, 0, 101, 109, 8, 3, 121, 55, 122, 65, 0, 101, 1, 107, 115, 2, 116, 3, 121, 55, 123, 0, 1, 102, 2, 105, 120, 3, 129, 55, 0, 7, 6, 101, 109, 0, 8, 3, 2, 121, 65, 0, 1, 21, 2, 98, 101, 114, 3, 6, 121, 65, 0, 1, 104, 112, 115, 2, 101, 3, 6, 129, 65, 0, 4, 1, 10, 2, 32, 3, 13, 65, 0, 1, 10, 2, 121, 32, 0, 1, 104, 112, 115, 0, 4, 2, 105, 115, 115, 105, 3, 113, 65, 0, 2, 117, 108, 115, 0, 8, 2, 97, 0, 8, 2, 101, 0, 8, 2, 105, 116, 0, 8, 2, 111, 0, 109, 2, 97, 110, 0, 4, 2, 97, 110, 97, 3, 121, 65, 0, 2, 98, 108, 101, 109, 0, 2, 98, 114, 121, 0, 2, 101, 114, 97, 108, 0, 2, 101, 114, 121, 0, 2, 105, 0, 2, 112, 97, 116, 104, 0, 2, 112, 101, 114, 0, 2, 112, 104, 97, 115, 0, 2, 112, 114, 101, 115, 0, 2, 112, 116, 105, 0, 2, 112, 116, 121, 0, 2, 117, 108, 0, 109, 2, 101, 0, 111, 114, 114, 104, 1, 104, 3, 121, 65, 13, 34, 0, 98, 97, 2, 115, 3, 121, 65, 71, 13, 0, 4, 1, 102, 2, 97, 108, 101, 3, 129, 65, 0, 1, 104, 2, 111, 0, 2, 97, 105, 108, 0, 7, 6, 101, 110, 0, 4, 2, 100, 101, 97, 3, 2, 121, 50, 0, 2, 105, 103, 109, 97, 32, 0, 2, 109, 101, 115, 0, 8, 2, 21, 0, 8, 2, 100, 97, 0, 8, 2, 100, 117, 0, 8, 2, 116, 105, 0, 110, 8, 0, 114, 111, 108, 3, 2, 121, 50, 34, 136, 55, 0, 114, 97, 103, 101, 3, 2, 121, 50, 34, 138, 75, 0, 116, 105, 99, 101, 1, 10, 3, 2, 121, 50, 47, 137, 89, 0, 108, 105, 2, 118, 3, 2, 121, 50, 55, 137, 0, 100, 111, 114, 8, 3, 2, 121, 50, 72, 133, 0, 99, 104, 97, 8, 2, 110, 3, 2, 121, 50, 76, 120, 0, 118, 105, 114, 111, 3, 2, 121, 50, 84, 137, 34, 13, 0, 116, 104, 114, 97, 2, 108, 3, 2, 121, 50, 87, 34, 130, 0, 99, 121, 2, 99, 108, 105, 3, 2, 121, 50, 89, 122, 0, 115, 104, 114, 105, 110, 101, 3, 2, 121, 50, 91, 34, 137, 50, 0, 2, 116, 101, 114, 116, 3, 4, 121, 50, 0, 2, 116, 114, 101, 112, 3, 4, 124, 50, 0, 4, 1, 21, 2, 100, 111, 32, 3, 6, 121, 50, 0, 1, 21, 2, 116, 18, 68, 32, 0, 1, 21, 2, 116, 97, 108, 0, 1, 21, 2, 116, 111, 117, 115, 0, 1, 21, 2, 116, 117, 0, 1, 108, 108, 105, 109, 2, 105, 97, 0, 1, 115, 101, 114, 112, 101, 2, 116, 0, 1, 115, 115, 2, 116, 0, 1, 116, 115, 111, 2, 115, 0, 2, 100, 17, 65, 32, 0, 2, 116, 105, 97, 108, 0, 110, 2, 105, 97, 0, 116, 97, 114, 121, 1, 109, 2, 32, 3, 6, 121, 50, 47, 13, 34, 2, 37, 0, 107, 111, 1, 10, 2, 32, 3, 6, 121, 50, 49, 136, 0, 100, 114, 111, 110, 2, 32, 3, 6, 121, 50, 72, 34, 13, 50, 0, 115, 107, 2, 32, 3, 6, 121, 50, 89, 49, 0, 103, 2, 32, 3, 6, 121, 68, 0, 4, 2, 97, 32, 3, 6, 129, 50, 0, 2, 97, 114, 121, 0, 2, 105, 97, 0, 111, 117, 115, 1, 21, 2, 32, 3, 8, 13, 50, 13, 89, 0, 101, 115, 1, 104, 116, 21, 21, 2, 32, 3, 8, 13, 50, 129, 88, 0, 4, 1, 10, 2, 17, 65, 110, 99, 101, 3, 13, 50, 0, 1, 10, 2, 32, 0, 1, 10, 2, 99, 101, 32, 0, 1, 10, 2, 101, 100, 32, 0, 1, 10, 2, 101, 114, 32, 0, 1, 10, 2, 109, 101, 110, 116, 0, 1, 10, 2, 116, 32, 0, 1, 10, 2, 116, 104, 32, 0, 1, 99, 114, 101, 109, 0, 1, 103, 101, 2, 100, 0, 1, 112, 114, 97, 99, 0, 1, 118, 18, 66, 2, 116, 32, 0, 1, 118, 21, 21, 2, 116, 32, 0, 99, 121, 1, 10, 2, 32, 3, 13, 50, 89, 2, 37, 0, 105, 110, 101, 1, 10, 3, 13, 50, 129, 50, 0, 4, 8, 2, 111, 3, 113, 50, 0, 8, 2, 111, 117, 103, 104, 0, 8, 2, 117, 0, 97, 8, 2, 109, 3, 113, 50, 35, 0, 4, 1, 10, 2, 99, 104, 3, 121, 50, 0, 1, 99, 114, 101, 112, 2, 116, 0, 1, 99, 115, 97, 2, 116, 0, 1, 102, 2, 99, 101, 32, 0, 1, 107, 2, 100, 32, 0, 1, 115, 110, 2, 116, 0, 1, 116, 110, 2, 116, 0, 1, 116, 120, 2, 116, 0, 1, 118, 2, 116, 32, 0, 2, 100, 111, 117, 115, 0, 2, 105, 103, 0, 2, 115, 105, 103, 0, 2, 116, 101, 114, 0, 2, 116, 105, 0, 2, 116, 105, 116, 121, 0, 2, 116, 114, 97, 110, 0, 2, 116, 114, 105, 0, 2, 116, 114, 111, 0, 2, 118, 105, 17, 65, 0, 2, 118, 111, 121, 0, 2, 118, 121, 0, 2, 122, 121, 0, 5, 8, 1, 10, 2, 99, 101, 32, 0, 5, 8, 1, 10, 2, 116, 32, 0, 8, 2, 100, 0, 8, 2, 101, 0, 8, 2, 109, 0, 8, 2, 116, 114, 121, 0, 8, 99, 115, 101, 100, 2, 116, 0, 8, 115, 101, 114, 2, 116, 0, 101, 109, 1, 116, 3, 121, 50, 13, 65, 0, 116, 105, 8, 99, 3, 121, 50, 47, 122, 0, 99, 108, 97, 118, 3, 121, 50, 49, 55, 138, 84, 0, 100, 111, 119, 3, 121, 50, 72, 6, 135, 0, 100, 111, 8, 3, 121, 50, 72, 136, 0, 103, 105, 110, 3, 121, 50, 75, 122, 50, 0, 103, 105, 110, 103, 3, 121, 50, 75, 122, 68, 0, 101, 114, 8, 3, 121, 50, 114, 0, 103, 2, 116, 104, 3, 121, 68, 0, 4, 1, 10, 2, 103, 101, 114, 3, 122, 50, 0, 1, 107, 99, 105, 104, 99, 0, 103, 2, 108, 17, 65, 3, 122, 68, 81, 0, 4, 2, 99, 111, 114, 101, 3, 124, 50, 0, 2, 116, 114, 101, 99, 0, 4, 1, 99, 115, 2, 101, 3, 129, 50, 0, 1, 103, 2, 105, 17, 65, 0, 2, 97, 108, 32, 0, 8, 115, 2, 105, 0, 101, 2, 32, 0, 4, 105, 1, 108, 2, 101, 3, 129, 50, 122, 0, 105, 1, 118, 2, 101, 0, 101, 97, 8, 103, 3, 129, 50, 122, 6, 35, 0, 7, 6, 101, 111, 0, 8, 103, 3, 4, 122, 124, 0, 1, 21, 21, 2, 32, 3, 6, 138, 136, 0, 117, 115, 1, 10, 2, 32, 3, 8, 141, 89, 0, 4, 110, 1, 103, 3, 13, 50, 0, 110, 1, 104, 99, 0, 1, 104, 116, 2, 21, 3, 113, 13, 0, 1, 103, 3, 113, 124, 0, 4, 101, 115, 2, 32, 3, 113, 136, 88, 0, 115, 2, 32, 0, 4, 1, 103, 2, 102, 102, 3, 121, 0, 1, 106, 2, 112, 0, 4, 1, 104, 116, 2, 99, 114, 97, 99, 121, 3, 122, 6, 124, 0, 1, 104, 116, 2, 108, 111, 103, 105, 115, 0, 1, 104, 116, 2, 108, 111, 103, 121, 0, 4, 1, 102, 3, 129, 0, 1, 112, 2, 112, 108, 0, 115, 105, 115, 1, 21, 3, 129, 6, 136, 89, 122, 89, 0, 114, 8, 103, 3, 132, 0, 2, 100, 32, 3, 135, 0, 118, 101, 114, 3, 136, 84, 13, 0, 114, 8, 3, 138, 114, 0, 4, 1, 104, 116, 2, 114, 3, 141, 0, 8, 108, 0, 97, 2, 32, 0, 7, 6, 101, 114, 0, 109, 101, 8, 102, 2, 110, 116, 3, 2, 128, 65, 121, 0, 4, 1, 21, 2, 105, 116, 121, 3, 6, 121, 34, 0, 2, 105, 99, 32, 0, 2, 105, 99, 97, 108, 0, 4, 1, 21, 2, 17, 67, 97, 108, 32, 3, 6, 128, 0, 1, 21, 2, 17, 67, 105, 99, 32, 0, 1, 21, 2, 115, 105, 97, 108, 0, 1, 109, 2, 103, 101, 0, 1, 118, 2, 103, 101, 0, 1, 118, 2, 115, 97, 108, 0, 2, 98, 105, 97, 108, 0, 2, 103, 105, 99, 32, 0, 2, 110, 97, 108, 32, 0, 2, 115, 105, 111, 110, 0, 114, 101, 100, 2, 32, 3, 6, 128, 72, 0, 103, 105, 110, 103, 3, 6, 128, 75, 113, 68, 0, 1, 21, 2, 111, 32, 3, 6, 140, 34, 0, 105, 2, 17, 65, 3, 6, 141, 34, 2, 122, 0, 101, 97, 108, 3, 6, 141, 34, 113, 118, 0, 4, 1, 104, 100, 97, 2, 101, 3, 6, 142, 0, 1, 104, 111, 99, 2, 101, 0, 101, 1, 99, 2, 32, 0, 4, 1, 10, 2, 111, 17, 67, 101, 32, 3, 8, 13, 34, 0, 1, 10, 2, 111, 117, 115, 0, 4, 105, 115, 101, 1, 10, 2, 32, 3, 8, 13, 34, 137, 88, 0, 105, 122, 101, 1, 10, 2, 32, 0, 121, 2, 32, 3, 13, 34, 2, 37, 0, 97, 108, 1, 21, 2, 105, 116, 121, 3, 13, 34, 6, 35, 55, 0, 4, 105, 115, 1, 10, 2, 97, 3, 13, 34, 137, 88, 0, 105, 122, 1, 10, 2, 97, 0, 116, 111, 1, 104, 2, 32, 3, 13, 47, 134, 0, 97, 1, 109, 97, 99, 3, 14, 34, 13, 0, 4, 1, 21, 2, 101, 110, 99, 101, 32, 3, 34, 0, 2, 101, 110, 116, 32, 0, 97, 109, 1, 10, 2, 101, 110, 116, 3, 34, 13, 65, 0, 105, 101, 115, 2, 32, 14, 128, 130, 130, 3, 88, 0, 4, 1, 99, 2, 97, 109, 3, 113, 34, 0, 8, 2, 17, 65, 0, 8, 104, 2, 101, 100, 0, 101, 1, 104, 2, 100, 105, 3, 113, 34, 121, 0, 101, 1, 105, 2, 32, 3, 113, 140, 0, 4, 1, 10, 3, 114, 0, 1, 10, 2, 32, 0, 1, 10, 2, 110, 32, 0, 1, 10, 2, 115, 32, 0, 1, 10, 2, 116, 32, 0, 1, 17, 67, 11, 2, 32, 14, 128, 128, 131, 0, 1, 21, 21, 21, 2, 32, 14, 128, 145, 130, 0, 1, 98, 109, 2, 32, 0, 1, 99, 115, 97, 2, 116, 0, 1, 108, 108, 2, 32, 14, 128, 128, 130, 0, 1, 108, 108, 97, 2, 32, 0, 1, 110, 105, 108, 2, 32, 14, 128, 128, 129, 0, 1, 110, 114, 2, 32, 14, 128, 128, 130, 0, 1, 112, 2, 99, 101, 110, 0, 1, 112, 2, 104, 97, 112, 0, 1, 114, 101, 2, 32, 14, 128, 128, 130, 0, 1, 115, 115, 2, 32, 14, 128, 128, 130, 0, 101, 1, 10, 2, 32, 0, 101, 1, 10, 2, 32, 0, 4, 1, 10, 2, 17, 65, 3, 114, 34, 0, 1, 10, 2, 105, 110, 103, 0, 2, 105, 101, 0, 2, 105, 101, 32, 0, 121, 2, 17, 65, 3, 114, 57, 0, 4, 115, 1, 17, 67, 11, 2, 32, 14, 128, 128, 132, 3, 114, 88, 0, 115, 1, 108, 108, 2, 32, 14, 128, 128, 131, 0, 115, 1, 110, 105, 108, 2, 32, 14, 128, 128, 130, 0, 115, 1, 114, 101, 2, 32, 14, 128, 128, 131, 0, 115, 1, 115, 115, 2, 32, 14, 128, 128, 131, 0, 5, 8, 1, 10, 2, 32, 3, 119, 0, 115, 5, 8, 1, 17, 67, 11, 2, 32, 14, 128, 128, 132, 3, 119, 88, 0, 2, 114, 17, 65, 3, 121, 0, 4, 2, 105, 17, 67, 3, 121, 34, 0, 8, 2, 117, 100, 0, 8, 17, 67, 17, 67, 2, 17, 65, 0, 8, 104, 2, 17, 65, 0, 114, 1, 17, 67, 29, 0, 114, 8, 2, 17, 65, 0, 114, 121, 5, 3, 1, 98, 2, 32, 3, 121, 34, 2, 122, 0, 4, 101, 1, 104, 2, 115, 3, 121, 34, 13, 0, 101, 1, 104, 2, 116, 0, 4, 101, 1, 99, 2, 109, 111, 110, 3, 121, 34, 113, 0, 101, 1, 104, 2, 102, 0, 121, 8, 118, 0, 101, 111, 1, 116, 115, 3, 121, 34, 113, 136, 0, 97, 108, 1, 103, 2, 100, 3, 121, 34, 118, 0, 4, 5, 35, 1, 104, 2, 116, 102, 3, 127, 0, 5, 35, 8, 100, 2, 98, 0, 4, 3, 128, 0, 1, 17, 67, 29, 0, 1, 21, 2, 115, 121, 0, 1, 99, 2, 110, 32, 0, 1, 99, 2, 116, 0, 1, 99, 110, 111, 99, 2, 116, 32, 0, 1, 104, 2, 116, 122, 0, 1, 109, 2, 99, 0, 1, 115, 2, 118, 97, 110, 0, 1, 118, 2, 116, 0, 1, 118, 21, 2, 116, 32, 0, 2, 17, 66, 32, 0, 2, 32, 0, 2, 115, 101, 0, 2, 115, 105, 98, 0, 2, 115, 105, 102, 0, 2, 115, 105, 118, 0, 2, 116, 105, 111, 110, 0, 2, 118, 101, 0, 8, 0, 8, 117, 113, 0, 101, 2, 32, 0, 2, 17, 65, 3, 128, 34, 0, 109, 101, 97, 1, 112, 2, 98, 3, 128, 65, 141, 0, 4, 101, 1, 112, 109, 2, 32, 3, 140, 0, 114, 2, 32, 24, 0, 4, 1, 104, 2, 101, 110, 3, 141, 34, 0, 1, 122, 2, 111, 0, 8, 17, 67, 2, 111, 32, 0, 97, 1, 29, 2, 32, 3, 141, 34, 13, 0, 105, 1, 112, 120, 101, 2, 101, 110, 3, 141, 34, 113, 0, 105, 111, 8, 112, 2, 100, 105, 99, 3, 141, 34, 113, 6, 124, 0, 105, 111, 8, 112, 2, 100, 3, 141, 34, 113, 13, 0, 121, 1, 117, 113, 3, 141, 34, 122, 0, 4, 101, 1, 17, 67, 29, 2, 32, 3, 142, 0, 101, 1, 104, 112, 115, 2, 32, 0, 101, 1, 109, 2, 32, 0, 101, 1, 118, 101, 2, 32, 0, 101, 8, 104, 0, 7, 6, 101, 115, 0, 4, 2, 99, 97, 112, 101, 3, 2, 121, 89, 0, 2, 99, 97, 112, 105, 0, 8, 2, 112, 21, 0, 4, 2, 116, 114, 97, 108, 32, 3, 6, 121, 89, 0, 99, 1, 21, 2, 101, 110, 17, 67, 0, 113, 117, 101, 3, 6, 121, 89, 49, 0, 4, 2, 105, 97, 110, 32, 3, 6, 129, 88, 0, 2, 105, 99, 0, 101, 1, 110, 21, 2, 32, 0, 2, 105, 118, 101, 3, 6, 129, 89, 0, 105, 115, 2, 32, 3, 6, 129, 89, 122, 89, 0, 4, 1, 10, 2, 116, 32, 3, 13, 89, 0, 1, 10, 2, 121, 32, 0, 1, 104, 116, 2, 105, 18, 71, 101, 32, 0, 1, 118, 2, 116, 121, 0, 115, 1, 114, 101, 2, 32, 0, 115, 1, 114, 116, 10, 2, 32, 0, 115, 97, 1, 99, 101, 110, 2, 114, 121, 3, 13, 89, 13, 0, 105, 115, 1, 104, 116, 2, 32, 3, 13, 89, 122, 89, 0, 101, 115, 1, 104, 116, 2, 32, 3, 13, 89, 129, 88, 0, 4, 1, 10, 2, 32, 14, 128, 130, 129, 3, 88, 0, 1, 17, 67, 10, 2, 32, 14, 128, 130, 129, 0, 1, 104, 112, 10, 2, 32, 14, 128, 128, 129, 0, 1, 104, 116, 10, 2, 32, 14, 128, 128, 129, 0, 1, 105, 114, 101, 110, 2, 32, 14, 128, 130, 130, 0, 1, 114, 10, 2, 32, 14, 128, 128, 129, 0, 4, 1, 102, 10, 2, 32, 14, 128, 128, 129, 3, 89, 0, 1, 107, 10, 2, 32, 14, 128, 128, 129, 0, 1, 112, 10, 2, 32, 14, 128, 128, 129, 0, 1, 116, 10, 2, 32, 14, 128, 128, 129, 0, 1, 117, 113, 10, 2, 32, 14, 128, 128, 129, 0, 4, 2, 99, 97, 114, 112, 3, 113, 89, 0, 2, 112, 101, 99, 105, 0, 2, 116, 97, 116, 101, 0, 8, 2, 116, 97, 98, 0, 1, 114, 112, 2, 101, 110, 116, 3, 121, 88, 0, 4, 1, 114, 17, 67, 2, 116, 3, 121, 89, 0, 1, 118, 2, 116, 12, 0, 8, 2, 112, 108, 0, 115, 1, 116, 115, 105, 100, 2, 32, 0, 116, 105, 2, 109, 3, 121, 89, 47, 123, 0, 1, 118, 114, 97, 104, 2, 116, 3, 122, 89, 0, 111, 112, 104, 97, 3, 122, 89, 6, 124, 83, 13, 0, 4, 1, 99, 10, 2, 32, 14, 128, 128, 129, 3, 123, 88, 0, 1, 103, 10, 2, 32, 14, 128, 128, 129, 0, 1, 104, 99, 10, 2, 32, 14, 128, 128, 129, 0, 1, 104, 115, 2, 32, 14, 128, 128, 130, 0, 1, 115, 10, 2, 32, 14, 128, 128, 129, 0, 1, 115, 115, 10, 2, 32, 14, 128, 128, 130, 0, 1, 115, 117, 10, 2, 32, 14, 128, 129, 130, 0, 1, 115, 117, 114, 10, 2, 32, 14, 128, 128, 130, 0, 1, 115, 117, 116, 10, 2, 32, 14, 128, 128, 130, 0, 1, 120, 10, 2, 32, 14, 128, 128, 130, 0, 1, 122, 10, 2, 32, 14, 128, 128, 130, 0, 4, 2, 105, 17, 65, 3, 129, 88, 0, 8, 120, 97, 0, 101, 2, 32, 0, 8, 2, 112, 101, 97, 107, 3, 129, 89, 0, 7, 6, 101, 116, 0, 4, 2, 105, 116, 111, 114, 3, 6, 121, 47, 0, 116, 101, 2, 32, 0, 116, 97, 2, 32, 3, 6, 121, 47, 13, 0, 105, 110, 103, 1, 108, 2, 32, 3, 6, 129, 47, 122, 68, 0, 4, 101, 100, 1, 108, 2, 32, 3, 6, 129, 47, 123, 72, 0, 101, 100, 1, 114, 99, 2, 32, 0, 114, 121, 1, 109, 2, 32, 3, 8, 13, 47, 34, 2, 122, 0, 4, 1, 108, 10, 2, 32, 3, 13, 47, 0, 8, 109, 2, 105, 99, 0, 116, 1, 108, 97, 112, 2, 101, 0, 104, 1, 17, 67, 21, 2, 32, 14, 128, 129, 131, 3, 13, 87, 0, 114, 121, 2, 32, 14, 128, 128, 130, 3, 34, 122, 0, 114, 105, 101, 115, 2, 32, 14, 128, 128, 132, 3, 34, 122, 88, 0, 4, 1, 21, 2, 32, 3, 113, 47, 0, 8, 2, 101, 114, 110, 0, 116, 1, 10, 2, 32, 0, 4, 1, 98, 97, 104, 112, 2, 32, 3, 121, 47, 0, 1, 106, 2, 32, 0, 1, 110, 17, 65, 21, 21, 2, 32, 0, 1, 114, 103, 2, 12, 0, 1, 115, 2, 32, 0, 1, 116, 2, 32, 0, 4, 104, 2, 105, 99, 3, 121, 87, 0, 104, 2, 121, 108, 101, 110, 0, 104, 8, 2, 97, 0, 104, 8, 2, 101, 108, 0, 4, 1, 21, 2, 97, 116, 101, 3, 122, 47, 0, 1, 21, 2, 97, 116, 105, 111, 110, 0, 1, 107, 114, 0, 1, 108, 108, 2, 32, 0, 105, 110, 103, 1, 10, 2, 32, 3, 123, 47, 2, 122, 68, 0, 101, 100, 1, 10, 2, 32, 14, 128, 128, 130, 3, 123, 72, 0, 4, 1, 102, 2, 97, 3, 129, 47, 0, 8, 2, 111, 110, 0, 8, 109, 2, 101, 0, 8, 112, 2, 101, 0, 101, 2, 32, 0, 4, 101, 114, 1, 109, 2, 32, 3, 129, 47, 114, 0, 114, 101, 1, 109, 0, 4, 104, 2, 121, 108, 3, 129, 87, 0, 104, 5, 35, 2, 97, 110, 101, 0, 104, 8, 2, 17, 65, 0, 1, 114, 101, 98, 2, 32, 3, 138, 0, 7, 6, 101, 118, 0, 4, 101, 114, 2, 99, 3, 4, 121, 84, 114, 0, 101, 114, 2, 108, 0, 101, 114, 2, 109, 0, 4, 8, 3, 113, 84, 0, 8, 2, 105, 99, 116, 0, 8, 2, 105, 115, 0, 101, 8, 2, 110, 116, 3, 113, 84, 121, 0, 101, 114, 8, 2, 115, 3, 113, 84, 128, 0, 4, 1, 108, 2, 101, 108, 3, 121, 84, 0, 5, 3, 8, 2, 111, 108, 117, 0, 8, 2, 105, 0, 97, 8, 2, 110, 101, 3, 121, 84, 13, 0, 101, 114, 121, 3, 121, 84, 34, 113, 0, 4, 101, 114, 1, 108, 99, 3, 121, 84, 114, 0, 101, 114, 2, 32, 0, 101, 114, 8, 0, 4, 1, 108, 108, 97, 3, 129, 84, 0, 1, 114, 98, 98, 97, 0, 1, 116, 115, 2, 101, 0, 2, 105, 108, 0, 101, 1, 108, 99, 2, 108, 0, 101, 8, 0, 101, 110, 8, 3, 129, 84, 13, 50, 0, 4, 101, 114, 1, 102, 2, 12, 3, 129, 84, 114, 0, 101, 114, 5, 35, 8, 108, 0, 7, 6, 101, 120, 0, 4, 8, 3, 2, 121, 49, 89, 0, 99, 2, 105, 0, 99, 8, 2, 101, 0, 116, 114, 97, 2, 111, 114, 3, 2, 121, 49, 89, 47, 34, 0, 116, 114, 97, 118, 97, 2, 103, 3, 2, 121, 49, 89, 47, 34, 35, 84, 13, 0, 112, 101, 114, 105, 109, 3, 2, 121, 49, 89, 48, 121, 34, 122, 65, 0, 4, 8, 2, 17, 65, 3, 2, 121, 81, 88, 0, 104, 8, 0, 1, 21, 2, 105, 97, 3, 6, 121, 49, 89, 0, 4, 1, 17, 67, 2, 101, 3, 121, 49, 89, 0, 2, 101, 114, 99, 0, 2, 112, 101, 114, 116, 0, 99, 101, 2, 108, 108, 101, 110, 3, 121, 49, 89, 13, 0, 116, 101, 114, 2, 17, 67, 3, 121, 49, 89, 47, 6, 128, 0, 116, 114, 97, 2, 112, 111, 108, 3, 121, 49, 89, 47, 34, 6, 35, 0, 4, 116, 114, 97, 3, 121, 49, 89, 47, 34, 13, 0, 116, 114, 111, 8, 0, 116, 114, 97, 2, 99, 116, 3, 121, 49, 89, 47, 34, 35, 0, 116, 114, 97, 2, 110, 21, 3, 121, 49, 89, 47, 34, 138, 0, 112, 101, 100, 2, 105, 116, 3, 121, 49, 89, 48, 13, 72, 0, 99, 97, 118, 3, 121, 49, 89, 49, 13, 84, 0, 111, 114, 2, 99, 3, 121, 49, 89, 114, 0, 101, 2, 99, 117, 116, 105, 111, 3, 121, 49, 89, 122, 0, 8, 2, 105, 116, 3, 121, 81, 88, 0, 1, 115, 115, 2, 32, 3, 122, 49, 89, 0, 7, 6, 101, 121, 0, 1, 10, 2, 32, 3, 2, 122, 0, 111, 114, 2, 32, 3, 6, 138, 114, 0, 101, 100, 2, 32, 14, 128, 128, 130, 3, 72, 0, 1, 21, 2, 17, 67, 21, 3, 122, 0, 8, 107, 2, 12, 3, 129, 0, 4, 3, 137, 0, 101, 1, 21, 2, 32, 14, 128, 128, 131, 0, 101, 8, 0, 4, 1, 17, 67, 29, 3, 138, 0, 1, 118, 17, 67, 2, 32, 0, 2, 97, 110, 0, 8, 98, 97, 0, 101, 0, 101, 114, 1, 109, 21, 2, 32, 3, 145, 0, 7, 6, 105, 97, 0, 4, 1, 102, 2, 110, 116, 3, 6, 144, 0, 1, 102, 101, 2, 110, 99, 101, 0, 1, 108, 2, 110, 99, 101, 0, 1, 108, 112, 2, 110, 116, 0, 104, 2, 32, 0, 116, 104, 3, 6, 144, 87, 0, 1, 21, 2, 32, 3, 8, 37, 13, 0, 114, 121, 1, 10, 3, 8, 57, 13, 34, 2, 122, 0, 116, 101, 1, 21, 2, 32, 3, 8, 113, 138, 47, 0, 99, 1, 10, 2, 32, 3, 8, 122, 35, 49, 0, 4, 1, 21, 2, 116, 105, 118, 101, 3, 8, 141, 0, 1, 21, 21, 2, 32, 0, 114, 121, 1, 108, 10, 3, 8, 141, 34, 2, 122, 0, 2, 110, 103, 32, 3, 57, 35, 0, 4, 1, 114, 2, 98, 3, 113, 13, 0, 1, 116, 2, 98, 0, 2, 109, 0, 103, 101, 1, 10, 2, 32, 3, 113, 75, 0, 114, 100, 2, 32, 3, 113, 114, 72, 0, 114, 99, 104, 3, 113, 127, 49, 0, 105, 3, 113, 137, 0, 4, 1, 21, 2, 110, 105, 99, 3, 122, 6, 35, 0, 1, 21, 2, 110, 105, 116, 0, 8, 102, 2, 110, 99, 3, 122, 6, 124, 0, 110, 99, 101, 8, 102, 3, 122, 6, 124, 50, 89, 138, 0, 114, 97, 2, 32, 3, 122, 6, 126, 34, 13, 0, 4, 1, 108, 97, 2, 110, 116, 3, 122, 13, 0, 1, 108, 108, 105, 2, 110, 116, 0, 4, 116, 101, 1, 103, 2, 32, 3, 122, 13, 47, 0, 116, 101, 1, 114, 112, 111, 2, 32, 0, 110, 1, 21, 2, 99, 121, 3, 122, 13, 50, 0, 1, 112, 2, 110, 111, 3, 122, 35, 0, 114, 2, 105, 116, 121, 3, 122, 35, 34, 0, 105, 115, 1, 108, 3, 122, 138, 88, 0, 1, 21, 2, 110, 97, 3, 129, 6, 35, 0, 1, 108, 10, 2, 110, 99, 101, 3, 129, 13, 0, 4, 1, 17, 67, 29, 3, 137, 13, 0, 1, 102, 2, 98, 0, 114, 5, 8, 1, 17, 67, 3, 137, 119, 0, 4, 1, 10, 2, 110, 3, 141, 0, 8, 112, 2, 110, 17, 65, 0, 110, 8, 3, 141, 50, 0, 4, 114, 1, 108, 21, 2, 32, 3, 142, 0, 114, 2, 105, 17, 67, 0, 4, 114, 3, 145, 0, 114, 1, 17, 67, 0, 7, 6, 105, 101, 0, 1, 10, 2, 32, 3, 2, 37, 0, 117, 1, 108, 2, 116, 101, 3, 2, 121, 83, 0, 8, 118, 2, 116, 3, 2, 141, 0, 110, 101, 1, 100, 2, 32, 3, 6, 137, 129, 50, 0, 116, 121, 1, 21, 3, 6, 144, 47, 2, 122, 0, 108, 1, 114, 10, 2, 32, 3, 8, 129, 118, 0, 115, 116, 1, 10, 2, 32, 14, 128, 130, 131, 3, 13, 89, 47, 0, 121, 2, 32, 3, 37, 0, 108, 1, 110, 10, 2, 32, 3, 57, 118, 0, 4, 119, 3, 57, 134, 0, 119, 2, 32, 0, 100, 2, 32, 14, 128, 130, 130, 3, 72, 0, 100, 115, 2, 32, 14, 128, 130, 131, 3, 72, 88, 0, 115, 2, 32, 14, 128, 130, 130, 3, 88, 0, 4, 2, 108, 108, 17, 65, 3, 113, 6, 121, 0, 2, 110, 17, 67, 105, 17, 65, 0, 2, 116, 116, 0, 114, 1, 10, 2, 121, 3, 113, 13, 34, 0, 115, 99, 3, 113, 121, 89, 0, 1, 100, 101, 109, 2, 118, 97, 108, 3, 113, 129, 0, 114, 114, 101, 2, 32, 3, 113, 140, 0, 114, 1, 10, 2, 32, 24, 14, 128, 130, 130, 3, 114, 0, 114, 39, 115, 1, 10, 2, 32, 24, 14, 128, 130, 132, 3, 114, 88, 0, 1, 114, 102, 2, 110, 100, 3, 121, 0, 4, 3, 122, 0, 1, 112, 112, 2, 32, 0, 1, 115, 2, 118, 101, 0, 2, 110, 116, 97, 108, 3, 122, 6, 121, 0, 110, 110, 3, 122, 6, 121, 50, 0, 2, 103, 111, 3, 122, 6, 138, 0, 114, 2, 97, 3, 122, 6, 140, 34, 0, 100, 108, 121, 3, 122, 72, 55, 2, 122, 0, 4, 1, 29, 3, 129, 0, 1, 102, 2, 110, 100, 0, 1, 103, 2, 110, 0, 1, 114, 112, 2, 115, 116, 0, 2, 99, 101, 0, 2, 102, 0, 2, 107, 0, 2, 108, 0, 2, 118, 0, 2, 118, 101, 0, 2, 122, 0, 8, 114, 0, 8, 122, 0, 104, 2, 17, 67, 0, 115, 116, 97, 3, 129, 6, 121, 89, 47, 13, 0, 106, 3, 129, 6, 138, 0, 103, 2, 101, 13, 3, 129, 75, 0, 4, 115, 1, 99, 101, 112, 115, 2, 32, 3, 129, 88, 0, 115, 1, 114, 101, 115, 2, 32, 0, 105, 2, 32, 3, 129, 137, 0, 117, 1, 108, 3, 134, 0, 117, 116, 101, 5, 3, 1, 108, 3, 134, 47, 6, 121, 0, 4, 1, 112, 2, 32, 3, 137, 0, 2, 32, 0, 2, 99, 0, 8, 116, 2, 17, 66, 0, 8, 116, 103, 111, 104, 0, 5, 8, 8, 99, 115, 2, 110, 3, 137, 119, 0, 4, 1, 10, 2, 116, 32, 3, 141, 0, 1, 21, 2, 116, 104, 0, 2, 110, 0, 4, 114, 3, 142, 0, 114, 2, 99, 0, 4, 1, 99, 115, 2, 110, 99, 3, 144, 0, 1, 108, 99, 2, 110, 116, 0, 2, 110, 116, 105, 17, 67, 0, 2, 116, 0, 8, 99, 115, 2, 110, 0, 4, 8, 104, 2, 114, 3, 145, 0, 114, 1, 108, 112, 2, 32, 0, 114, 8, 114, 17, 67, 0, 7, 6, 105, 103, 0, 110, 1, 115, 2, 111, 3, 2, 122, 50, 57, 0, 4, 2, 110, 111, 3, 2, 122, 81, 0, 8, 2, 110, 105, 0, 8, 109, 2, 114, 97, 116, 3, 2, 137, 81, 0, 110, 101, 2, 32, 3, 6, 129, 50, 0, 4, 117, 2, 32, 3, 6, 129, 81, 0, 117, 2, 101, 0, 97, 110, 1, 110, 2, 32, 3, 8, 122, 81, 13, 50, 0, 110, 111, 110, 2, 32, 3, 37, 50, 57, 124, 50, 0, 101, 111, 3, 122, 75, 13, 0, 105, 98, 1, 10, 3, 122, 75, 13, 71, 0, 4, 1, 100, 2, 110, 17, 65, 3, 122, 81, 0, 2, 110, 97, 0, 2, 110, 111, 109, 0, 110, 111, 2, 114, 97, 110, 3, 122, 81, 50, 114, 0, 1, 109, 97, 2, 97, 32, 3, 129, 81, 0, 4, 1, 21, 2, 110, 32, 3, 137, 0, 1, 21, 2, 110, 101, 0, 104, 1, 104, 0, 104, 1, 110, 0, 104, 1, 115, 0, 104, 2, 116, 0, 4, 110, 2, 17, 67, 3, 137, 50, 0, 110, 2, 32, 0, 109, 2, 32, 3, 137, 65, 0, 4, 1, 116, 2, 101, 12, 3, 137, 81, 0, 8, 109, 2, 114, 97, 0, 8, 116, 2, 114, 0, 7, 6, 105, 109, 0, 4, 8, 2, 21, 3, 2, 122, 65, 0, 8, 2, 112, 101, 114, 17, 67, 21, 14, 128, 132, 130, 0, 8, 2, 112, 114, 101, 21, 14, 128, 132, 130, 0, 109, 8, 2, 21, 0, 4, 2, 112, 101, 99, 117, 3, 4, 122, 65, 0, 2, 112, 111, 114, 116, 117, 0, 2, 112, 114, 101, 103, 110, 97, 0, 2, 112, 114, 101, 115, 97, 0, 109, 2, 97, 116, 0, 109, 2, 101, 109, 0, 105, 108, 101, 1, 115, 3, 6, 122, 65, 113, 55, 122, 0, 1, 104, 115, 2, 97, 32, 3, 6, 129, 65, 0, 111, 117, 115, 1, 21, 2, 32, 3, 8, 122, 65, 13, 89, 0, 4, 1, 21, 2, 101, 116, 114, 3, 122, 65, 0, 1, 108, 0, 1, 108, 2, 101, 114, 0, 2, 97, 103, 101, 0, 2, 101, 110, 116, 12, 0, 2, 105, 116, 0, 2, 112, 97, 99, 0, 2, 112, 101, 116, 117, 115, 0, 2, 112, 108, 97, 110, 116, 32, 0, 2, 112, 108, 101, 0, 2, 112, 108, 105, 99, 97, 0, 2, 112, 114, 111, 118, 105, 115, 0, 2, 112, 117, 108, 115, 101, 32, 0, 2, 117, 109, 0, 109, 2, 105, 103, 0, 109, 2, 105, 110, 0, 109, 2, 117, 110, 105, 115, 0, 101, 2, 110, 116, 111, 3, 122, 65, 6, 121, 0, 109, 111, 2, 98, 105, 3, 122, 65, 6, 136, 0, 112, 111, 2, 116, 101, 110, 3, 122, 65, 48, 13, 0, 4, 101, 2, 116, 101, 114, 32, 3, 122, 65, 129, 0, 101, 2, 116, 114, 101, 0, 1, 10, 2, 32, 3, 123, 65, 0, 4, 1, 108, 99, 3, 137, 65, 0, 5, 3, 1, 115, 2, 117, 108, 116, 0, 8, 114, 112, 2, 97, 0, 98, 1, 108, 99, 0, 101, 1, 108, 0, 101, 1, 100, 2, 110, 115, 3, 137, 65, 121, 0, 7, 6, 105, 110, 0, 4, 8, 2, 21, 14, 128, 132, 130, 3, 2, 122, 50, 0, 8, 2, 99, 111, 114, 112, 0, 8, 2, 99, 114, 101, 100, 0, 8, 2, 115, 116, 105, 108, 0, 8, 2, 116, 101, 103, 114, 105, 0, 110, 8, 2, 117, 109, 0, 116, 8, 2, 101, 114, 105, 111, 12, 3, 2, 122, 50, 47, 0, 116, 101, 114, 8, 2, 114, 111, 103, 3, 2, 122, 50, 47, 121, 0, 4, 116, 101, 114, 8, 2, 110, 32, 3, 2, 122, 50, 47, 128, 0, 116, 101, 114, 8, 2, 110, 97, 108, 0, 116, 101, 114, 8, 2, 112, 111, 108, 21, 0, 116, 101, 114, 8, 2, 112, 114, 0, 116, 101, 114, 112, 114, 101, 2, 116, 3, 2, 122, 50, 47, 128, 48, 34, 122, 0, 100, 8, 2, 101, 102, 105, 110, 3, 2, 122, 50, 72, 0, 102, 114, 97, 8, 2, 99, 3, 2, 122, 50, 83, 34, 35, 0, 102, 97, 8, 2, 108, 3, 2, 122, 50, 83, 35, 0, 4, 103, 1, 21, 2, 32, 12, 14, 128, 153, 131, 3, 2, 122, 68, 0, 103, 1, 108, 101, 2, 32, 12, 14, 128, 152, 131, 0, 103, 1, 109, 111, 21, 21, 2, 32, 14, 128, 152, 131, 0, 103, 1, 110, 101, 2, 32, 14, 128, 136, 131, 0, 103, 1, 114, 17, 66, 10, 2, 32, 0, 103, 1, 114, 101, 2, 32, 14, 128, 136, 131, 0, 103, 1, 117, 103, 111, 108, 2, 32, 14, 128, 136, 132, 0, 103, 1, 120, 10, 2, 32, 12, 14, 128, 136, 131, 0, 4, 103, 108, 121, 1, 21, 2, 32, 14, 128, 153, 133, 3, 2, 122, 68, 55, 2, 122, 0, 103, 108, 121, 1, 110, 101, 2, 32, 14, 128, 168, 133, 0, 103, 108, 121, 1, 114, 101, 2, 32, 14, 128, 168, 133, 0, 4, 103, 109, 101, 110, 116, 1, 21, 2, 32, 14, 128, 153, 135, 3, 2, 122, 68, 65, 13, 50, 47, 0, 103, 109, 101, 110, 116, 1, 114, 101, 2, 32, 14, 128, 136, 135, 0, 4, 103, 115, 1, 21, 2, 32, 14, 128, 153, 132, 3, 2, 122, 68, 88, 0, 103, 115, 1, 110, 101, 2, 32, 14, 128, 136, 132, 0, 103, 115, 1, 114, 101, 2, 32, 14, 128, 136, 132, 0, 4, 8, 2, 100, 101, 14, 128, 132, 130, 3, 4, 122, 50, 0, 8, 2, 100, 105, 115, 14, 128, 132, 130, 0, 8, 2, 100, 105, 118, 14, 128, 132, 130, 0, 8, 2, 101, 120, 14, 128, 132, 130, 0, 8, 2, 115, 101, 99, 14, 128, 132, 130, 0, 8, 2, 115, 105, 103, 110, 105, 102, 14, 128, 132, 130, 0, 8, 2, 115, 105, 110, 99, 14, 128, 132, 130, 0, 116, 101, 114, 8, 2, 17, 65, 14, 128, 132, 133, 3, 4, 122, 50, 47, 13, 34, 0, 116, 114, 111, 8, 2, 21, 3, 4, 122, 50, 47, 34, 13, 0, 116, 101, 114, 8, 2, 21, 14, 128, 132, 133, 3, 4, 122, 50, 47, 114, 0, 102, 114, 97, 8, 2, 14, 128, 132, 133, 3, 4, 122, 50, 83, 34, 13, 0, 1, 21, 2, 99, 105, 97, 108, 3, 6, 122, 50, 0, 100, 97, 1, 21, 2, 32, 3, 6, 122, 50, 72, 13, 0, 2, 103, 97, 32, 3, 6, 122, 68, 0, 4, 1, 98, 2, 97, 32, 3, 6, 129, 50, 0, 1, 107, 2, 97, 32, 0, 1, 108, 2, 97, 32, 0, 1, 114, 2, 97, 32, 0, 1, 116, 2, 97, 32, 0, 105, 1, 21, 2, 32, 3, 6, 129, 50, 122, 0, 111, 2, 32, 3, 6, 129, 50, 136, 0, 105, 110, 1, 10, 2, 32, 3, 8, 13, 50, 122, 50, 0, 1, 109, 10, 2, 97, 108, 32, 3, 8, 122, 50, 0, 111, 117, 115, 1, 21, 2, 32, 3, 8, 122, 50, 13, 89, 0, 1, 21, 2, 97, 116, 101, 3, 8, 123, 50, 0, 4, 1, 115, 97, 98, 2, 32, 3, 13, 50, 0, 5, 7, 1, 10, 2, 32, 0, 101, 115, 115, 1, 103, 2, 32, 14, 128, 130, 132, 3, 50, 13, 89, 0, 4, 1, 109, 97, 120, 2, 101, 3, 113, 50, 0, 101, 1, 109, 114, 101, 2, 32, 0, 4, 116, 114, 97, 8, 2, 99, 116, 3, 113, 50, 47, 34, 35, 0, 116, 114, 97, 8, 2, 110, 115, 0, 4, 1, 10, 2, 101, 110, 17, 67, 3, 122, 50, 0, 1, 99, 2, 101, 0, 1, 99, 110, 105, 2, 101, 0, 1, 103, 2, 101, 0, 1, 107, 2, 100, 101, 114, 103, 0, 1, 107, 2, 100, 108, 0, 1, 107, 2, 100, 114, 0, 1, 114, 116, 2, 105, 0, 2, 100, 101, 120, 0, 2, 100, 105, 97, 0, 2, 101, 97, 0, 2, 101, 101, 0, 2, 102, 105, 110, 105, 116, 101, 0, 2, 115, 101, 99, 116, 0, 8, 2, 98, 0, 8, 2, 99, 97, 110, 0, 8, 2, 99, 101, 110, 115, 0, 8, 2, 99, 104, 0, 8, 2, 99, 111, 109, 17, 65, 0, 8, 2, 99, 114, 101, 0, 8, 2, 99, 117, 98, 0, 8, 2, 99, 117, 108, 0, 8, 2, 100, 105, 99, 0, 8, 2, 100, 105, 103, 111, 0, 8, 2, 100, 111, 108, 0, 8, 2, 102, 97, 109, 0, 8, 2, 102, 105, 100, 0, 8, 2, 102, 105, 108, 0, 8, 2, 102, 108, 111, 0, 8, 2, 102, 108, 117, 0, 8, 2, 102, 111, 32, 0, 8, 2, 106, 117, 114, 0, 8, 2, 108, 0, 8, 2, 109, 0, 8, 2, 111, 102, 0, 8, 2, 111, 114, 103, 0, 8, 2, 112, 0, 8, 2, 113, 117, 101, 0, 8, 2, 113, 117, 105, 115, 0, 8, 2, 114, 0, 8, 2, 115, 101, 116, 0, 8, 2, 115, 104, 0, 8, 2, 115, 105, 103, 104, 0, 8, 2, 115, 111, 102, 0, 8, 2, 115, 111, 108, 97, 0, 8, 2, 115, 111, 108, 101, 0, 8, 2, 115, 111, 109, 117, 0, 8, 2, 115, 112, 105, 114, 0, 8, 2, 115, 116, 97, 110, 0, 8, 2, 115, 116, 105, 0, 8, 2, 115, 116, 114, 117, 109, 0, 8, 2, 115, 117, 98, 0, 8, 2, 115, 117, 108, 0, 8, 2, 116, 101, 103, 0, 8, 2, 116, 105, 109, 97, 0, 8, 2, 116, 111, 110, 97, 0, 8, 2, 117, 110, 0, 8, 2, 118, 111, 105, 0, 8, 2, 119, 97, 0, 101, 1, 108, 97, 110, 2, 32, 0, 101, 1, 108, 117, 2, 32, 0, 110, 8, 2, 25, 0, 101, 120, 8, 2, 111, 114, 3, 122, 50, 6, 121, 49, 89, 0, 4, 105, 1, 102, 21, 2, 116, 101, 3, 122, 50, 13, 0, 110, 111, 8, 2, 99, 101, 0, 110, 111, 8, 2, 118, 0, 101, 114, 97, 1, 109, 2, 108, 3, 122, 50, 13, 34, 13, 0, 116, 101, 2, 108, 108, 101, 99, 3, 122, 50, 47, 13, 0, 116, 101, 114, 102, 101, 114, 3, 122, 50, 47, 13, 83, 6, 142, 0, 116, 101, 114, 2, 101, 115, 116, 3, 122, 50, 47, 34, 0, 116, 114, 105, 103, 117, 3, 122, 50, 47, 34, 6, 129, 81, 0, 4, 116, 114, 97, 8, 3, 122, 50, 47, 34, 13, 0, 116, 114, 111, 8, 2, 118, 0, 116, 114, 105, 99, 97, 3, 122, 50, 47, 34, 122, 49, 13, 0, 116, 101, 114, 2, 118, 105, 101, 119, 3, 122, 50, 47, 114, 0, 99, 114, 101, 109, 3, 122, 50, 49, 34, 122, 65, 0, 100, 101, 108, 105, 8, 2, 98, 3, 122, 50, 72, 6, 121, 55, 13, 0, 100, 105, 8, 2, 103, 101, 110, 3, 122, 50, 72, 6, 122, 0, 100, 105, 103, 101, 8, 2, 115, 3, 122, 50, 72, 122, 75, 6, 121, 0, 103, 1, 114, 102, 110, 3, 122, 50, 75, 0, 102, 97, 110, 8, 3, 122, 50, 83, 13, 50, 0, 102, 111, 114, 2, 109, 97, 116, 105, 111, 3, 122, 50, 83, 114, 0, 115, 116, 97, 110, 116, 8, 3, 122, 50, 89, 47, 13, 50, 47, 0, 99, 105, 2, 100, 101, 3, 122, 50, 89, 122, 0, 4, 105, 1, 109, 100, 97, 3, 122, 50, 122, 0, 105, 8, 109, 0, 117, 116, 101, 8, 109, 2, 109, 3, 122, 50, 122, 47, 0, 105, 97, 116, 117, 114, 1, 109, 3, 122, 50, 122, 76, 114, 0, 105, 115, 109, 2, 32, 3, 122, 50, 122, 88, 13, 65, 0, 101, 1, 118, 2, 103, 3, 122, 50, 123, 0, 4, 2, 103, 111, 116, 3, 122, 68, 0, 8, 2, 103, 114, 111, 0, 8, 2, 107, 0, 1, 21, 2, 97, 116, 105, 111, 110, 3, 123, 50, 0, 4, 101, 1, 99, 21, 2, 32, 3, 129, 50, 0, 101, 1, 100, 10, 2, 32, 0, 101, 1, 104, 99, 17, 65, 2, 32, 0, 101, 1, 104, 112, 2, 32, 0, 101, 1, 108, 105, 2, 32, 0, 101, 1, 108, 111, 2, 32, 0, 101, 1, 114, 21, 2, 32, 0, 101, 1, 116, 21, 2, 32, 0, 101, 1, 122, 2, 32, 0, 4, 1, 98, 2, 100, 3, 137, 50, 0, 1, 102, 2, 97, 0, 1, 102, 2, 100, 0, 1, 103, 21, 2, 97, 32, 0, 1, 104, 2, 100, 17, 66, 0, 1, 104, 2, 100, 32, 0, 1, 104, 99, 2, 97, 0, 1, 104, 101, 98, 2, 100, 0, 1, 104, 115, 2, 105, 0, 1, 107, 2, 100, 0, 1, 108, 98, 2, 100, 0, 1, 109, 2, 100, 0, 1, 114, 103, 2, 100, 0, 1, 119, 2, 100, 101, 114, 32, 0, 1, 119, 2, 100, 105, 110, 103, 0, 1, 119, 101, 114, 2, 100, 0, 1, 119, 110, 117, 2, 100, 0, 8, 114, 2, 100, 0, 101, 1, 112, 2, 32, 0, 101, 1, 114, 99, 2, 32, 0, 101, 1, 116, 110, 101, 21, 21, 2, 32, 0, 117, 8, 109, 2, 116, 101, 3, 137, 50, 6, 57, 134, 0, 7, 6, 105, 111, 0, 110, 101, 2, 32, 3, 6, 144, 50, 37, 0, 117, 115, 1, 103, 2, 32, 3, 8, 13, 89, 0, 117, 115, 1, 21, 2, 32, 3, 8, 113, 13, 89, 0, 1, 10, 2, 32, 3, 8, 113, 136, 0, 110, 5, 8, 1, 10, 2, 32, 3, 8, 122, 125, 50, 0, 5, 7, 1, 10, 2, 32, 3, 8, 129, 136, 0, 4, 110, 1, 10, 2, 32, 3, 8, 141, 50, 0, 110, 1, 110, 0, 4, 1, 103, 2, 110, 12, 3, 13, 0, 1, 104, 115, 2, 110, 0, 117, 2, 114, 17, 65, 3, 57, 13, 0, 4, 114, 1, 10, 2, 32, 3, 57, 114, 0, 117, 114, 2, 25, 0, 2, 108, 105, 32, 3, 113, 6, 136, 0, 1, 109, 2, 110, 3, 113, 124, 0, 1, 100, 114, 97, 99, 3, 113, 136, 0, 114, 105, 116, 121, 3, 122, 6, 124, 34, 113, 47, 2, 122, 0, 2, 116, 32, 3, 122, 13, 0, 114, 1, 114, 2, 32, 3, 122, 114, 0, 2, 32, 3, 129, 136, 0, 117, 120, 3, 134, 0, 4, 1, 98, 2, 108, 111, 103, 121, 3, 137, 124, 0, 1, 118, 0, 8, 2, 110, 0, 114, 1, 10, 2, 12, 3, 142, 0, 4, 1, 118, 2, 108, 3, 144, 0, 1, 122, 2, 110, 0, 8, 114, 2, 116, 0, 110, 8, 108, 3, 144, 50, 0, 7, 6, 105, 114, 0, 4, 2, 97, 116, 3, 2, 137, 34, 0, 2, 101, 99, 116, 0, 4, 1, 21, 2, 111, 32, 3, 6, 141, 34, 0, 2, 97, 32, 0, 2, 105, 32, 0, 2, 97, 98, 108, 101, 3, 6, 145, 0, 2, 97, 116, 101, 3, 8, 141, 34, 0, 1, 112, 115, 97, 2, 105, 3, 34, 0, 8, 2, 114, 101, 21, 14, 128, 132, 130, 3, 113, 0, 4, 2, 111, 3, 113, 34, 0, 8, 2, 97, 0, 4, 2, 114, 111, 3, 122, 0, 2, 114, 117, 0, 8, 2, 114, 17, 65, 0, 4, 1, 21, 2, 97, 116, 105, 111, 110, 3, 122, 34, 0, 1, 109, 2, 97, 99, 0, 1, 112, 0, 2, 105, 0, 4, 3, 128, 0, 1, 116, 115, 2, 32, 0, 4, 1, 103, 2, 111, 3, 137, 34, 0, 1, 118, 2, 117, 115, 0, 2, 101, 116, 121, 0, 8, 2, 105, 115, 104, 0, 8, 17, 67, 2, 111, 32, 0, 111, 110, 2, 17, 65, 3, 137, 34, 6, 124, 50, 0, 4, 101, 1, 99, 2, 110, 3, 137, 34, 13, 0, 111, 1, 118, 2, 110, 0, 101, 5, 8, 3, 137, 119, 0, 1, 17, 67, 21, 2, 32, 3, 142, 0, 4, 1, 115, 2, 101, 110, 3, 145, 0, 1, 115, 101, 100, 0, 2, 101, 101, 0, 97, 8, 112, 2, 99, 0, 101, 0, 101, 1, 112, 0, 101, 114, 2, 32, 3, 145, 34, 114, 0, 97, 108, 1, 112, 115, 3, 145, 34, 118, 0, 121, 2, 32, 3, 145, 34, 122, 0, 111, 110, 8, 3, 145, 50, 0, 4, 5, 5, 3, 147, 0, 5, 5, 1, 116, 115, 2, 32, 0, 7, 6, 105, 115, 0, 4, 1, 21, 2, 99, 111, 32, 3, 6, 122, 89, 0, 1, 21, 2, 116, 105, 99, 0, 99, 1, 21, 2, 101, 110, 17, 67, 0, 115, 2, 97, 32, 0, 115, 105, 109, 111, 2, 32, 3, 6, 122, 89, 122, 65, 136, 0, 116, 101, 1, 21, 2, 32, 3, 6, 129, 89, 47, 0, 1, 114, 2, 121, 32, 3, 8, 13, 89, 0, 1, 115, 17, 67, 21, 2, 32, 3, 8, 122, 89, 0, 116, 97, 110, 1, 21, 2, 32, 3, 8, 122, 89, 47, 35, 50, 0, 97, 5, 3, 2, 116, 105, 111, 110, 3, 13, 88, 138, 0, 8, 100, 2, 101, 3, 113, 89, 0, 104, 1, 10, 2, 32, 3, 113, 91, 0, 1, 118, 2, 105, 116, 3, 122, 88, 0, 4, 109, 1, 17, 66, 105, 21, 2, 32, 14, 128, 144, 131, 3, 122, 88, 13, 65, 0, 109, 1, 21, 2, 32, 14, 128, 145, 131, 0, 109, 1, 110, 97, 2, 32, 14, 128, 144, 131, 0, 4, 1, 98, 2, 32, 3, 122, 89, 0, 1, 99, 2, 32, 0, 1, 109, 17, 65, 114, 112, 0, 116, 97, 110, 105, 1, 21, 2, 32, 3, 122, 89, 47, 6, 126, 50, 122, 0, 4, 1, 118, 2, 99, 111, 117, 110, 3, 137, 0, 2, 108, 101, 32, 0, 8, 2, 108, 101, 0, 108, 97, 110, 100, 8, 3, 137, 55, 13, 50, 72, 0, 4, 1, 10, 2, 97, 98, 108, 3, 137, 88, 0, 1, 118, 100, 97, 0, 2, 101, 114, 12, 32, 0, 2, 111, 32, 0, 2, 111, 114, 32, 0, 101, 2, 32, 0, 101, 2, 100, 32, 0, 101, 114, 2, 32, 3, 137, 88, 114, 0, 97, 2, 116, 105, 111, 110, 3, 137, 88, 138, 0, 4, 1, 114, 104, 99, 2, 116, 32, 3, 137, 89, 0, 2, 105, 118, 101, 0, 7, 6, 105, 116, 0, 105, 117, 115, 2, 32, 3, 6, 122, 91, 13, 89, 0, 4, 1, 116, 17, 65, 17, 67, 2, 32, 3, 6, 129, 47, 0, 2, 97, 32, 24, 0, 2, 105, 32, 0, 2, 111, 32, 0, 105, 115, 2, 32, 3, 6, 137, 47, 122, 89, 0, 1, 10, 2, 105, 118, 101, 32, 3, 8, 113, 47, 0, 4, 121, 1, 10, 2, 32, 3, 8, 113, 47, 2, 37, 0, 121, 1, 100, 10, 2, 32, 14, 128, 128, 131, 0, 121, 1, 100, 117, 29, 2, 32, 0, 1, 21, 21, 2, 97, 110, 32, 3, 8, 122, 47, 0, 111, 117, 115, 1, 10, 3, 8, 122, 47, 13, 89, 0, 97, 114, 121, 5, 3, 1, 10, 2, 32, 3, 13, 47, 121, 34, 2, 122, 0, 4, 1, 10, 2, 101, 32, 3, 122, 47, 0, 1, 98, 114, 111, 0, 1, 100, 101, 114, 99, 0, 1, 108, 2, 101, 114, 0, 1, 110, 97, 114, 103, 2, 101, 0, 1, 110, 105, 102, 110, 2, 101, 0, 1, 114, 99, 2, 101, 32, 0, 1, 114, 117, 2, 101, 0, 1, 115, 105, 117, 113, 2, 101, 0, 1, 115, 111, 112, 2, 101, 0, 2, 101, 114, 97, 116, 0, 8, 100, 101, 0, 121, 8, 17, 67, 2, 32, 3, 122, 47, 37, 0, 101, 115, 1, 115, 111, 112, 2, 32, 3, 122, 47, 89, 0, 104, 1, 108, 2, 101, 114, 3, 122, 86, 0, 114, 101, 1, 108, 3, 129, 47, 114, 0, 4, 1, 10, 2, 101, 32, 24, 3, 137, 47, 0, 1, 99, 2, 101, 32, 0, 1, 99, 2, 101, 114, 32, 0, 1, 109, 97, 2, 101, 0, 1, 110, 2, 114, 17, 65, 0, 1, 110, 117, 2, 101, 0, 1, 116, 2, 108, 0, 1, 118, 2, 97, 108, 0, 1, 118, 2, 101, 114, 32, 0, 2, 117, 109, 0, 8, 109, 2, 111, 0, 8, 112, 115, 2, 101, 0, 8, 115, 2, 101, 0, 101, 1, 114, 119, 0, 101, 1, 120, 2, 32, 0, 114, 111, 1, 110, 2, 103, 101, 3, 137, 47, 34, 13, 0, 114, 111, 1, 110, 3, 137, 47, 34, 136, 0, 101, 115, 1, 10, 2, 32, 3, 137, 47, 89, 0, 4, 104, 8, 116, 3, 137, 86, 0, 104, 101, 1, 108, 0, 104, 101, 2, 32, 0, 7, 6, 105, 118, 0, 4, 1, 114, 116, 110, 111, 99, 3, 6, 137, 84, 0, 1, 116, 99, 2, 97, 108, 0, 1, 118, 21, 2, 97, 108, 0, 97, 1, 108, 21, 2, 32, 3, 6, 137, 84, 13, 0, 4, 1, 17, 67, 17, 67, 29, 2, 101, 110, 3, 122, 84, 0, 1, 17, 67, 29, 2, 101, 108, 0, 1, 21, 2, 101, 0, 1, 104, 115, 2, 101, 114, 0, 1, 108, 2, 101, 114, 0, 1, 114, 2, 101, 108, 0, 1, 114, 2, 101, 110, 0, 1, 114, 2, 101, 114, 0, 1, 114, 2, 101, 116, 0, 8, 103, 2, 101, 0, 8, 108, 2, 101, 0, 8, 114, 2, 101, 114, 32, 0, 101, 2, 110, 101, 115, 115, 0, 4, 1, 100, 121, 2, 101, 3, 137, 84, 0, 1, 104, 2, 101, 32, 0, 1, 108, 2, 101, 110, 0, 1, 110, 2, 101, 32, 0, 1, 114, 100, 2, 101, 32, 0, 1, 114, 100, 2, 101, 114, 0, 1, 114, 101, 100, 2, 101, 0, 1, 114, 112, 101, 100, 2, 101, 0, 1, 118, 2, 101, 0, 1, 119, 2, 101, 32, 0, 2, 101, 13, 0, 2, 111, 114, 32, 0, 8, 2, 97, 110, 0, 8, 108, 2, 101, 17, 66, 0, 8, 108, 97, 2, 101, 0, 8, 114, 114, 97, 2, 101, 0, 101, 8, 108, 2, 17, 66, 0, 97, 108, 1, 114, 3, 137, 84, 118, 0, 7, 6, 108, 101, 0, 1, 116, 116, 2, 21, 3, 14, 55, 0, 4, 1, 10, 2, 32, 3, 55, 0, 1, 114, 10, 2, 32, 0, 1, 17, 67, 11, 2, 17, 66, 105, 97, 3, 55, 6, 129, 0, 4, 1, 17, 67, 10, 2, 115, 115, 3, 55, 13, 0, 1, 98, 17, 65, 2, 17, 67, 32, 0, 114, 1, 98, 17, 65, 2, 32, 0, 115, 115, 1, 21, 2, 32, 14, 128, 130, 132, 3, 55, 13, 89, 0, 115, 115, 110, 101, 115, 115, 1, 21, 2, 32, 14, 128, 130, 136, 3, 55, 13, 89, 50, 13, 89, 0, 115, 115, 108, 121, 1, 21, 2, 32, 14, 128, 130, 134, 3, 55, 13, 89, 55, 2, 122, 0, 114, 1, 98, 21, 2, 17, 67, 21, 3, 55, 114, 0, 103, 103, 101, 100, 3, 55, 121, 81, 122, 72, 0, 115, 115, 5, 8, 1, 21, 2, 32, 14, 128, 130, 132, 3, 55, 121, 89, 0, 115, 115, 110, 101, 115, 115, 5, 8, 1, 21, 2, 32, 14, 128, 130, 136, 3, 55, 121, 89, 50, 121, 89, 0, 115, 115, 108, 121, 5, 8, 1, 21, 2, 32, 14, 128, 130, 134, 3, 55, 121, 89, 55, 2, 122, 0, 109, 1, 112, 10, 2, 101, 110, 116, 3, 55, 122, 65, 0, 4, 1, 17, 67, 2, 116, 111, 110, 32, 3, 118, 0, 1, 17, 67, 10, 2, 32, 0, 1, 17, 67, 11, 2, 17, 66, 21, 0, 1, 98, 21, 2, 17, 67, 21, 0, 1, 100, 21, 2, 17, 66, 21, 0, 1, 116, 21, 2, 17, 67, 21, 0, 109, 1, 10, 2, 101, 110, 116, 3, 118, 65, 0, 100, 1, 98, 17, 65, 2, 32, 3, 118, 72, 0, 5, 8, 1, 17, 67, 10, 2, 32, 3, 121, 55, 0, 7, 6, 109, 105, 0, 4, 115, 8, 2, 116, 105, 109, 3, 65, 2, 122, 89, 0, 115, 8, 2, 116, 105, 116, 0, 115, 8, 2, 105, 110, 3, 65, 4, 122, 89, 0, 2, 115, 116, 97, 3, 65, 113, 0, 108, 108, 101, 110, 3, 65, 113, 55, 121, 50, 0, 115, 8, 2, 21, 14, 128, 132, 131, 3, 65, 113, 89, 0, 4, 2, 115, 115, 105, 3, 65, 122, 0, 8, 2, 110, 101, 114, 97, 0, 108, 108, 105, 8, 3, 65, 122, 55, 122, 0, 115, 101, 114, 97, 98, 3, 65, 122, 88, 14, 34, 13, 71, 0, 4, 115, 2, 99, 104, 105, 101, 3, 65, 122, 89, 0, 115, 2, 100, 101, 109, 0, 115, 2, 102, 105, 0, 115, 2, 104, 97, 112, 0, 115, 2, 116, 114, 97, 108, 0, 115, 2, 116, 114, 101, 115, 0, 115, 2, 116, 121, 0, 115, 8, 2, 116, 105, 0, 115, 115, 0, 115, 99, 105, 8, 2, 98, 3, 65, 122, 89, 13, 0, 115, 116, 108, 101, 3, 65, 122, 89, 118, 0, 115, 104, 2, 109, 97, 3, 65, 122, 91, 0, 8, 2, 110, 17, 65, 114, 3, 65, 137, 0, 99, 114, 2, 111, 3, 65, 137, 49, 34, 0, 99, 114, 111, 2, 17, 67, 17, 67, 21, 3, 65, 137, 49, 34, 124, 0, 99, 114, 111, 2, 17, 67, 17, 65, 21, 3, 65, 137, 49, 34, 136, 0, 115, 2, 101, 114, 3, 65, 137, 88, 0, 7, 6, 110, 103, 0, 4, 1, 17, 65, 109, 2, 121, 3, 50, 75, 0, 1, 105, 98, 2, 101, 114, 0, 1, 105, 103, 2, 101, 114, 0, 1, 117, 2, 121, 0, 2, 101, 0, 2, 105, 101, 32, 0, 2, 105, 116, 105, 0, 105, 2, 98, 3, 50, 75, 13, 0, 4, 101, 100, 3, 50, 75, 72, 0, 101, 100, 1, 111, 112, 115, 0, 4, 105, 110, 103, 1, 105, 104, 3, 50, 75, 113, 68, 0, 105, 110, 103, 1, 105, 114, 99, 0, 105, 110, 103, 1, 117, 2, 32, 0, 101, 1, 111, 99, 2, 115, 116, 3, 50, 75, 121, 0, 4, 1, 105, 114, 2, 101, 114, 3, 68, 0, 1, 105, 115, 2, 101, 114, 0, 2, 121, 0, 117, 101, 0, 4, 101, 100, 1, 97, 3, 68, 72, 0, 101, 100, 1, 111, 0, 4, 1, 97, 98, 2, 101, 114, 3, 68, 81, 0, 1, 97, 108, 99, 2, 101, 114, 0, 1, 105, 2, 101, 114, 0, 1, 111, 2, 101, 114, 0, 1, 117, 111, 121, 2, 101, 114, 0, 2, 17, 65, 0, 2, 101, 115, 116, 0, 2, 108, 0, 2, 114, 0, 8, 97, 2, 101, 114, 0, 8, 105, 114, 2, 101, 0, 105, 110, 103, 2, 32, 3, 68, 113, 68, 0, 7, 6, 111, 108, 0, 121, 1, 112, 32, 24, 3, 4, 124, 55, 122, 0, 111, 2, 103, 105, 3, 6, 124, 55, 13, 0, 4, 1, 21, 21, 2, 97, 114, 3, 6, 136, 55, 0, 1, 21, 21, 2, 117, 115, 0, 105, 115, 1, 112, 10, 3, 8, 13, 55, 122, 89, 0, 4, 1, 10, 2, 101, 110, 17, 67, 3, 13, 55, 0, 1, 10, 2, 111, 117, 115, 32, 0, 1, 109, 2, 101, 99, 0, 1, 112, 2, 105, 116, 101, 0, 1, 115, 2, 105, 99, 0, 1, 115, 2, 105, 100, 105, 0, 1, 115, 2, 105, 108, 0, 108, 1, 112, 2, 117, 0, 108, 1, 114, 97, 99, 0, 111, 2, 103, 105, 99, 3, 13, 55, 6, 124, 0, 101, 1, 109, 2, 115, 116, 3, 13, 55, 121, 0, 105, 99, 101, 1, 112, 3, 13, 55, 129, 89, 0, 102, 1, 119, 3, 117, 55, 83, 0, 118, 1, 119, 3, 117, 55, 84, 0, 4, 1, 114, 116, 101, 112, 2, 32, 3, 118, 0, 1, 116, 115, 10, 2, 32, 0, 8, 100, 105, 0, 4, 1, 10, 2, 105, 32, 3, 124, 55, 0, 1, 21, 2, 111, 32, 0, 1, 104, 2, 97, 114, 0, 1, 109, 2, 101, 99, 117, 108, 101, 0, 1, 115, 2, 101, 109, 0, 1, 116, 2, 101, 114, 0, 8, 100, 105, 2, 97, 0, 108, 1, 114, 98, 0, 108, 1, 114, 116, 2, 17, 65, 0, 108, 1, 116, 97, 0, 1, 99, 2, 111, 117, 114, 3, 125, 55, 0, 4, 1, 102, 2, 107, 3, 136, 0, 1, 121, 2, 107, 0, 4, 1, 114, 116, 110, 111, 99, 3, 136, 55, 0, 1, 116, 120, 101, 0, 2, 97, 110, 100, 32, 0, 2, 97, 114, 0, 8, 2, 97, 29, 0, 108, 1, 114, 0, 108, 1, 116, 0, 108, 1, 119, 0, 116, 3, 136, 55, 47, 0, 100, 3, 136, 55, 72, 0, 109, 2, 32, 3, 136, 65, 0, 7, 6, 111, 109, 0, 8, 2, 105, 17, 67, 3, 2, 136, 65, 0, 101, 1, 21, 2, 116, 114, 121, 3, 6, 124, 65, 13, 0, 4, 101, 1, 21, 2, 116, 114, 101, 3, 6, 124, 65, 122, 0, 101, 2, 116, 101, 114, 0, 105, 110, 2, 111, 3, 6, 124, 65, 122, 50, 0, 101, 1, 110, 105, 21, 21, 2, 32, 3, 6, 136, 65, 138, 0, 4, 1, 10, 2, 105, 115, 101, 32, 3, 8, 13, 65, 0, 1, 10, 2, 105, 122, 101, 32, 0, 1, 21, 2, 105, 115, 116, 32, 0, 121, 1, 10, 2, 32, 3, 8, 13, 65, 2, 122, 0, 4, 1, 10, 2, 32, 3, 13, 65, 0, 1, 100, 2, 101, 115, 116, 0, 1, 100, 2, 105, 110, 105, 0, 8, 100, 2, 97, 0, 97, 1, 116, 2, 116, 111, 3, 13, 65, 126, 0, 97, 1, 119, 2, 110, 3, 117, 65, 13, 0, 101, 1, 119, 2, 110, 3, 122, 65, 122, 0, 4, 1, 99, 2, 32, 3, 124, 65, 0, 1, 108, 103, 2, 101, 114, 0, 1, 114, 2, 32, 0, 8, 112, 2, 101, 0, 110, 105, 8, 2, 21, 3, 124, 65, 50, 6, 122, 0, 4, 1, 99, 2, 101, 3, 125, 65, 0, 1, 99, 2, 112, 97, 110, 0, 1, 115, 2, 101, 32, 0, 101, 8, 115, 0, 109, 1, 99, 2, 101, 0, 97, 99, 104, 1, 116, 115, 3, 125, 65, 13, 49, 0, 4, 98, 1, 116, 2, 25, 3, 134, 65, 0, 98, 1, 119, 2, 32, 0, 98, 101, 1, 99, 2, 32, 0, 4, 1, 110, 2, 97, 100, 3, 136, 65, 0, 1, 114, 2, 97, 110, 0, 1, 114, 104, 99, 0, 98, 1, 99, 2, 32, 0, 97, 110, 1, 114, 2, 116, 105, 3, 136, 65, 6, 35, 50, 0, 7, 6, 111, 110, 0, 1, 100, 2, 97, 116, 3, 2, 136, 50, 0, 4, 1, 21, 2, 105, 99, 97, 3, 6, 124, 50, 0, 1, 115, 114, 101, 112, 2, 105, 0, 121, 109, 111, 117, 115, 3, 6, 124, 50, 122, 65, 13, 89, 0, 4, 1, 112, 116, 115, 111, 112, 3, 6, 136, 50, 0, 2, 105, 32, 0, 105, 115, 109, 1, 10, 2, 32, 3, 8, 13, 50, 122, 88, 13, 65, 0, 105, 115, 116, 1, 10, 2, 32, 3, 8, 13, 50, 122, 89, 47, 0, 4, 1, 10, 2, 101, 114, 32, 3, 13, 50, 0, 1, 17, 67, 11, 2, 32, 0, 1, 21, 21, 2, 32, 0, 1, 98, 10, 2, 32, 0, 1, 99, 10, 2, 32, 0, 1, 99, 101, 2, 100, 0, 1, 100, 17, 67, 2, 32, 0, 1, 103, 114, 2, 32, 0, 1, 104, 112, 2, 101, 116, 105, 0, 1, 109, 2, 100, 32, 0, 1, 109, 10, 2, 32, 0, 1, 114, 97, 2, 32, 0, 1, 114, 100, 2, 32, 0, 1, 115, 10, 2, 32, 0, 1, 115, 114, 101, 112, 0, 1, 116, 10, 2, 32, 0, 1, 116, 111, 104, 112, 0, 121, 1, 10, 2, 32, 3, 13, 50, 2, 122, 0, 111, 117, 115, 1, 10, 3, 13, 50, 13, 89, 0, 101, 8, 3, 58, 124, 50, 0, 99, 101, 8, 2, 32, 3, 58, 124, 50, 89, 0, 101, 5, 6, 8, 3, 58, 125, 50, 0, 99, 101, 5, 6, 8, 2, 32, 3, 58, 125, 50, 89, 0, 101, 100, 1, 17, 67, 10, 2, 32, 14, 128, 136, 130, 3, 72, 0, 105, 110, 103, 1, 17, 67, 10, 2, 32, 14, 128, 136, 131, 3, 113, 68, 0, 4, 1, 103, 2, 101, 3, 124, 50, 0, 1, 108, 102, 2, 32, 0, 1, 108, 105, 2, 32, 0, 1, 108, 121, 2, 32, 0, 1, 110, 2, 101, 0, 1, 112, 2, 32, 12, 0, 1, 114, 99, 2, 32, 0, 1, 114, 111, 2, 32, 0, 1, 114, 116, 10, 2, 32, 0, 1, 119, 2, 107, 0, 1, 119, 2, 116, 0, 1, 120, 2, 32, 12, 0, 2, 97, 108, 100, 0, 5, 3, 1, 103, 97, 2, 32, 0, 5, 8, 1, 21, 2, 32, 12, 12, 0, 101, 1, 109, 2, 116, 105, 3, 124, 50, 113, 0, 4, 1, 109, 2, 101, 121, 3, 125, 50, 0, 1, 109, 2, 107, 0, 1, 109, 2, 116, 104, 0, 1, 114, 102, 2, 116, 0, 1, 115, 100, 2, 32, 0, 1, 119, 0, 8, 2, 105, 111, 0, 8, 104, 2, 101, 121, 0, 101, 1, 100, 110, 117, 2, 32, 0, 103, 8, 112, 115, 3, 125, 50, 75, 0, 101, 1, 109, 2, 116, 97, 3, 125, 50, 122, 0, 103, 5, 35, 1, 109, 2, 101, 114, 3, 125, 68, 81, 0, 4, 2, 97, 110, 32, 3, 136, 50, 0, 8, 112, 2, 121, 0, 101, 8, 2, 114, 3, 136, 50, 13, 0, 117, 115, 3, 136, 50, 13, 89, 0, 7, 6, 111, 111, 0, 1, 10, 2, 110, 3, 6, 134, 0, 4, 1, 17, 67, 2, 107, 3, 117, 0, 1, 102, 2, 116, 0, 1, 103, 2, 100, 0, 1, 104, 2, 100, 0, 1, 104, 2, 100, 0, 1, 104, 2, 107, 0, 1, 115, 2, 116, 0, 1, 116, 115, 2, 100, 0, 1, 119, 2, 100, 0, 1, 119, 2, 108, 0, 4, 1, 108, 98, 2, 100, 3, 125, 0, 1, 108, 102, 2, 100, 0, 4, 114, 3, 133, 0, 114, 2, 32, 0, 4, 3, 134, 0, 1, 107, 2, 107, 0, 1, 109, 2, 110, 32, 0, 1, 112, 2, 107, 0, 1, 112, 115, 2, 110, 32, 0, 1, 115, 2, 116, 104, 0, 8, 2, 114, 0, 116, 2, 105, 99, 32, 3, 134, 6, 124, 47, 0, 115, 101, 1, 104, 99, 3, 134, 88, 0, 4, 115, 2, 101, 3, 134, 89, 0, 115, 101, 1, 103, 0, 8, 99, 2, 112, 3, 136, 6, 124, 0, 114, 1, 99, 2, 100, 3, 136, 6, 132, 0, 115, 1, 104, 99, 2, 101, 110, 3, 136, 88, 0, 4, 114, 1, 112, 3, 143, 0, 114, 8, 109, 0, 7, 6, 111, 114, 0, 8, 102, 2, 115, 21, 3, 2, 132, 0, 4, 101, 1, 102, 2, 99, 108, 111, 3, 2, 133, 0, 101, 1, 102, 2, 103, 111, 0, 101, 1, 102, 2, 115, 101, 0, 101, 1, 102, 2, 116, 111, 0, 4, 1, 21, 2, 105, 99, 32, 3, 6, 124, 34, 0, 1, 21, 2, 105, 99, 97, 108, 0, 1, 21, 2, 99, 97, 32, 3, 6, 132, 0, 2, 105, 32, 3, 6, 132, 34, 0, 2, 117, 109, 32, 3, 6, 133, 34, 0, 116, 101, 1, 102, 2, 32, 3, 6, 133, 47, 138, 0, 105, 108, 121, 1, 21, 2, 32, 3, 8, 13, 34, 13, 55, 2, 122, 0, 4, 1, 10, 2, 97, 116, 105, 111, 110, 3, 13, 34, 0, 2, 105, 103, 105, 110, 97, 0, 121, 1, 10, 2, 32, 3, 13, 34, 2, 122, 0, 101, 115, 99, 3, 13, 34, 6, 121, 89, 0, 105, 1, 104, 2, 122, 3, 13, 34, 137, 0, 101, 100, 1, 10, 2, 32, 3, 13, 72, 0, 103, 8, 102, 2, 17, 65, 118, 3, 13, 81, 0, 101, 100, 1, 104, 2, 32, 14, 128, 128, 129, 3, 72, 0, 4, 1, 10, 2, 32, 3, 114, 0, 1, 98, 98, 2, 110, 0, 1, 100, 110, 2, 32, 0, 1, 102, 2, 103, 17, 65, 116, 0, 1, 102, 10, 2, 100, 32, 0, 1, 102, 102, 101, 2, 116, 0, 1, 114, 114, 101, 116, 0, 1, 116, 110, 101, 118, 2, 32, 0, 101, 1, 116, 21, 2, 32, 0, 4, 1, 10, 2, 97, 116, 101, 3, 114, 34, 0, 1, 10, 2, 111, 117, 115, 0, 99, 101, 1, 119, 2, 115, 116, 3, 117, 0, 2, 114, 3, 124, 0, 4, 1, 21, 2, 105, 116, 105, 3, 124, 34, 0, 1, 21, 2, 105, 116, 121, 0, 1, 108, 102, 2, 105, 0, 1, 109, 2, 97, 108, 0, 2, 101, 17, 66, 32, 0, 2, 101, 110, 17, 67, 0, 2, 105, 103, 0, 5, 35, 8, 104, 2, 111, 0, 8, 2, 105, 17, 67, 0, 114, 8, 109, 0, 4, 97, 2, 99, 108, 3, 124, 34, 13, 0, 97, 8, 2, 116, 111, 0, 101, 105, 103, 110, 1, 102, 3, 124, 34, 13, 50, 0, 4, 101, 1, 102, 2, 115, 116, 3, 124, 34, 122, 0, 105, 1, 104, 2, 122, 111, 110, 116, 0, 1, 119, 2, 114, 3, 125, 0, 111, 117, 103, 104, 3, 125, 34, 13, 0, 111, 117, 103, 104, 5, 3, 3, 125, 34, 136, 0, 4, 1, 119, 3, 128, 0, 1, 119, 2, 109, 0, 1, 119, 2, 115, 101, 0, 1, 119, 2, 116, 104, 0, 5, 3, 2, 114, 3, 130, 0, 4, 1, 99, 2, 107, 3, 132, 0, 1, 102, 2, 101, 118, 101, 114, 0, 1, 102, 2, 107, 0, 1, 104, 99, 2, 100, 0, 1, 108, 2, 100, 0, 1, 121, 2, 107, 0, 2, 99, 104, 32, 0, 2, 101, 115, 105, 115, 0, 2, 109, 32, 0, 2, 110, 32, 0, 2, 115, 101, 32, 0, 2, 116, 0, 8, 0, 8, 99, 2, 21, 0, 8, 102, 2, 21, 0, 8, 109, 0, 101, 8, 102, 2, 17, 65, 0, 101, 8, 102, 2, 17, 67, 0, 116, 1, 109, 101, 2, 32, 0, 4, 3, 133, 0, 1, 99, 2, 101, 32, 0, 1, 100, 2, 32, 0, 1, 108, 112, 0, 1, 112, 2, 116, 0, 1, 116, 110, 2, 32, 0, 1, 116, 115, 2, 109, 0, 1, 119, 2, 101, 0, 1, 119, 2, 110, 0, 1, 119, 2, 116, 32, 0, 1, 119, 115, 2, 100, 0, 5, 8, 1, 10, 2, 32, 0, 5, 8, 1, 21, 21, 2, 32, 14, 128, 144, 130, 0, 101, 0, 101, 1, 116, 115, 2, 32, 0, 101, 8, 109, 0, 114, 2, 32, 0, 4, 1, 108, 104, 99, 2, 105, 99, 3, 133, 34, 0, 1, 108, 104, 99, 2, 111, 117, 115, 0, 2, 17, 65, 0, 2, 101, 17, 65, 0, 2, 101, 116, 0, 2, 101, 120, 0, 121, 8, 116, 115, 3, 133, 34, 122, 0, 4, 5, 5, 1, 119, 3, 148, 0, 5, 5, 1, 119, 2, 109, 0, 5, 5, 1, 119, 2, 115, 101, 0, 5, 5, 1, 119, 2, 116, 104, 0, 121, 5, 3, 1, 116, 17, 65, 21, 21, 2, 32, 3, 149, 34, 37, 0, 7, 6, 111, 115, 0, 2, 105, 116, 121, 3, 6, 124, 89, 0, 111, 1, 21, 2, 112, 104, 3, 6, 124, 89, 13, 0, 2, 97, 108, 32, 3, 6, 136, 88, 0, 2, 105, 118, 101, 3, 6, 136, 89, 0, 105, 115, 2, 32, 3, 6, 136, 89, 122, 89, 0, 117, 114, 101, 3, 6, 136, 90, 114, 0, 4, 1, 112, 2, 105, 116, 105, 111, 3, 13, 88, 0, 115, 1, 112, 2, 101, 115, 115, 0, 101, 1, 112, 114, 117, 112, 3, 13, 89, 0, 111, 1, 21, 2, 112, 104, 105, 99, 3, 13, 89, 6, 124, 0, 4, 116, 1, 112, 2, 101, 114, 105, 3, 124, 89, 47, 0, 116, 1, 112, 2, 117, 0, 116, 1, 112, 97, 0, 116, 1, 112, 101, 114, 0, 116, 1, 112, 101, 114, 112, 0, 116, 1, 112, 109, 105, 0, 116, 1, 112, 109, 111, 99, 0, 116, 1, 112, 120, 101, 0, 116, 1, 112, 121, 104, 0, 4, 5, 3, 1, 99, 2, 116, 3, 131, 89, 0, 5, 3, 1, 114, 102, 2, 116, 0, 115, 5, 3, 1, 98, 0, 115, 5, 3, 1, 108, 0, 115, 5, 3, 1, 109, 0, 115, 5, 3, 1, 114, 0, 8, 108, 2, 101, 3, 134, 88, 0, 4, 1, 29, 2, 121, 3, 136, 88, 0, 8, 114, 2, 101, 13, 0, 101, 2, 32, 0, 4, 1, 99, 2, 101, 99, 3, 136, 89, 0, 1, 99, 2, 105, 110, 101, 32, 0, 115, 1, 114, 103, 0, 4, 116, 1, 104, 2, 32, 3, 136, 89, 47, 0, 116, 1, 104, 103, 0, 116, 1, 109, 0, 116, 1, 112, 0, 7, 6, 111, 117, 0, 116, 8, 2, 21, 14, 128, 132, 131, 3, 2, 135, 47, 0, 1, 21, 2, 109, 32, 3, 6, 134, 0, 4, 115, 1, 17, 66, 10, 2, 32, 3, 8, 13, 89, 0, 115, 1, 114, 100, 10, 2, 32, 0, 4, 103, 104, 1, 114, 98, 2, 32, 3, 13, 0, 103, 104, 1, 114, 111, 0, 114, 101, 100, 1, 10, 3, 13, 72, 0, 4, 115, 1, 10, 2, 32, 3, 13, 89, 0, 115, 1, 108, 10, 2, 32, 0, 115, 1, 109, 10, 2, 32, 0, 115, 1, 110, 10, 2, 32, 0, 115, 121, 1, 10, 2, 32, 3, 13, 89, 2, 37, 0, 1, 104, 2, 109, 3, 57, 134, 0, 97, 3, 58, 126, 0, 4, 114, 1, 10, 2, 32, 3, 114, 0, 114, 1, 112, 17, 65, 0, 108, 2, 100, 3, 117, 0, 99, 101, 1, 108, 103, 2, 115, 3, 124, 0, 4, 103, 104, 1, 99, 3, 124, 83, 0, 103, 104, 1, 114, 116, 0, 4, 1, 99, 2, 110, 116, 114, 3, 125, 0, 1, 99, 2, 112, 108, 0, 1, 99, 2, 114, 97, 103, 0, 1, 99, 2, 115, 105, 0, 1, 100, 2, 98, 0, 1, 100, 2, 103, 0, 1, 110, 2, 114, 105, 0, 1, 114, 116, 2, 98, 108, 0, 1, 115, 2, 116, 104, 101, 114, 0, 1, 116, 2, 99, 104, 0, 1, 121, 2, 110, 103, 0, 4, 103, 104, 1, 108, 3, 125, 83, 0, 103, 104, 1, 110, 0, 103, 104, 1, 114, 0, 103, 104, 1, 116, 0, 4, 114, 3, 128, 0, 114, 1, 99, 2, 116, 101, 0, 114, 2, 110, 0, 114, 5, 3, 1, 99, 2, 97, 103, 0, 114, 5, 3, 1, 110, 2, 105, 0, 4, 103, 104, 1, 98, 2, 116, 3, 130, 0, 103, 104, 1, 104, 2, 116, 0, 103, 104, 1, 110, 2, 116, 0, 103, 104, 1, 114, 98, 2, 116, 0, 103, 104, 1, 114, 119, 0, 103, 104, 2, 116, 0, 103, 104, 8, 0, 4, 103, 104, 5, 3, 1, 99, 3, 131, 83, 0, 103, 104, 5, 3, 1, 114, 116, 0, 4, 114, 1, 98, 2, 110, 3, 133, 0, 114, 1, 99, 2, 115, 0, 114, 1, 99, 2, 116, 0, 114, 1, 99, 2, 116, 101, 115, 97, 0, 114, 1, 109, 2, 110, 0, 114, 1, 112, 0, 114, 1, 112, 110, 2, 32, 0, 114, 8, 102, 0, 114, 8, 121, 0, 114, 99, 101, 1, 115, 3, 133, 89, 0, 4, 1, 98, 2, 100, 3, 134, 0, 1, 98, 2, 108, 108, 0, 1, 99, 2, 116, 104, 0, 1, 104, 103, 2, 108, 0, 1, 107, 0, 1, 109, 2, 115, 115, 101, 0, 1, 110, 2, 103, 97, 0, 1, 114, 2, 98, 108, 0, 1, 114, 2, 116, 105, 110, 0, 1, 116, 2, 99, 97, 110, 0, 1, 119, 2, 110, 100, 17, 65, 0, 1, 119, 2, 110, 100, 17, 67, 0, 1, 121, 2, 116, 0, 2, 32, 0, 2, 102, 0, 2, 105, 0, 2, 108, 17, 65, 0, 2, 112, 0, 2, 118, 0, 2, 122, 0, 5, 35, 1, 114, 2, 116, 101, 0, 103, 104, 1, 114, 104, 116, 0, 120, 2, 32, 0, 103, 101, 1, 114, 3, 134, 90, 0, 99, 104, 1, 100, 3, 134, 91, 0, 4, 3, 135, 0, 1, 102, 2, 108, 101, 0, 1, 114, 17, 67, 2, 116, 0, 1, 121, 2, 116, 32, 0, 2, 116, 0, 98, 1, 100, 2, 116, 0, 103, 104, 1, 98, 0, 103, 104, 1, 100, 2, 116, 0, 103, 104, 1, 108, 112, 0, 103, 104, 1, 108, 115, 0, 103, 104, 1, 114, 100, 0, 4, 1, 98, 2, 108, 100, 3, 136, 0, 1, 104, 115, 2, 108, 100, 101, 114, 0, 1, 109, 2, 108, 17, 67, 0, 1, 112, 2, 108, 116, 0, 1, 115, 2, 108, 0, 103, 104, 0, 103, 104, 1, 100, 0, 103, 104, 1, 104, 0, 103, 104, 1, 108, 114, 0, 4, 114, 1, 98, 2, 115, 101, 3, 143, 0, 114, 1, 116, 0, 114, 1, 116, 2, 32, 0, 114, 1, 116, 2, 110, 0, 114, 5, 7, 8, 121, 0, 114, 8, 103, 2, 100, 0, 4, 114, 1, 99, 115, 3, 146, 0, 114, 1, 104, 0, 114, 1, 108, 102, 0, 114, 1, 115, 0, 114, 1, 116, 115, 0, 114, 1, 118, 101, 2, 101, 100, 0, 114, 1, 118, 101, 100, 0, 114, 8, 0, 114, 8, 100, 0, 4, 114, 5, 5, 3, 148, 0, 114, 5, 5, 1, 99, 2, 116, 101, 0, 114, 5, 5, 2, 110, 0, 7, 6, 111, 118, 0, 101, 114, 8, 2, 21, 14, 128, 132, 132, 3, 4, 136, 84, 114, 0, 105, 116, 99, 104, 1, 21, 2, 32, 3, 8, 13, 84, 122, 76, 0, 4, 1, 99, 2, 101, 110, 17, 67, 3, 124, 84, 0, 1, 104, 2, 101, 108, 0, 1, 104, 2, 101, 114, 0, 1, 110, 2, 101, 108, 0, 1, 114, 103, 2, 101, 108, 0, 1, 114, 112, 2, 101, 114, 0, 1, 114, 116, 2, 101, 114, 0, 8, 2, 117, 108, 0, 101, 114, 1, 112, 2, 21, 3, 124, 84, 13, 0, 101, 114, 101, 105, 103, 110, 1, 115, 3, 124, 84, 13, 34, 122, 50, 0, 4, 1, 99, 2, 101, 110, 3, 125, 84, 0, 1, 99, 2, 101, 116, 0, 1, 104, 115, 2, 12, 0, 1, 108, 0, 1, 108, 2, 101, 0, 8, 2, 101, 110, 0, 101, 1, 100, 0, 101, 8, 108, 0, 4, 101, 114, 1, 99, 3, 125, 84, 114, 0, 101, 114, 1, 99, 2, 32, 0, 101, 114, 110, 1, 103, 3, 125, 84, 114, 50, 0, 4, 1, 21, 2, 97, 108, 3, 134, 84, 0, 1, 109, 2, 17, 65, 0, 1, 109, 2, 105, 0, 1, 114, 112, 2, 101, 13, 0, 101, 114, 1, 114, 112, 2, 32, 3, 134, 84, 114, 0, 4, 1, 108, 99, 2, 101, 3, 136, 84, 0, 1, 108, 108, 117, 112, 0, 1, 108, 112, 0, 2, 101, 114, 0, 8, 2, 17, 65, 0, 8, 108, 115, 2, 101, 110, 17, 65, 0, 4, 101, 114, 1, 10, 2, 32, 3, 136, 84, 114, 0, 101, 114, 2, 99, 111, 97, 0, 101, 114, 2, 100, 111, 115, 0, 101, 114, 2, 100, 114, 97, 0, 101, 114, 2, 100, 114, 105, 0, 101, 114, 2, 115, 105, 103, 0, 101, 114, 2, 116, 111, 110, 0, 101, 114, 2, 118, 105, 101, 0, 7, 6, 111, 119, 0, 2, 105, 116, 122, 32, 3, 8, 136, 84, 0, 2, 97, 121, 32, 3, 13, 58, 0, 108, 101, 1, 110, 107, 2, 100, 3, 124, 55, 122, 0, 4, 1, 97, 3, 135, 0, 1, 98, 2, 101, 108, 0, 1, 98, 2, 101, 114, 0, 1, 98, 2, 115, 17, 65, 0, 1, 98, 2, 115, 112, 0, 1, 99, 0, 1, 100, 2, 110, 0, 1, 100, 110, 101, 0, 1, 102, 0, 1, 103, 0, 1, 104, 0, 1, 104, 99, 0, 1, 104, 115, 2, 101, 114, 0, 1, 104, 119, 0, 1, 104, 121, 0, 1, 106, 0, 1, 107, 0, 1, 108, 99, 0, 1, 108, 102, 2, 101, 114, 0, 1, 108, 103, 2, 101, 114, 0, 1, 108, 108, 97, 115, 105, 0, 1, 108, 112, 0, 1, 110, 2, 97, 100, 0, 1, 110, 101, 2, 110, 0, 1, 112, 0, 1, 114, 2, 100, 0, 1, 114, 98, 0, 1, 114, 99, 2, 110, 0, 1, 114, 100, 0, 1, 114, 102, 0, 1, 114, 103, 2, 108, 0, 1, 114, 112, 0, 1, 114, 116, 2, 101, 0, 1, 116, 2, 101, 108, 0, 1, 116, 2, 101, 114, 0, 1, 116, 2, 110, 0, 1, 118, 0, 1, 119, 0, 1, 121, 0, 8, 2, 108, 0, 8, 100, 0, 8, 108, 108, 97, 0, 8, 110, 2, 32, 0, 8, 110, 2, 116, 0, 4, 3, 136, 0, 1, 99, 115, 111, 109, 0, 1, 104, 115, 0, 7, 6, 112, 101, 0, 8, 2, 110, 114, 3, 48, 2, 121, 0, 4, 2, 110, 105, 110, 115, 117, 3, 48, 13, 0, 114, 2, 115, 112, 0, 114, 2, 105, 112, 104, 3, 48, 13, 34, 0, 4, 8, 2, 114, 111, 103, 3, 48, 114, 0, 114, 2, 99, 101, 105, 0, 114, 2, 99, 101, 112, 0, 114, 2, 99, 117, 108, 105, 0, 114, 2, 99, 117, 115, 0, 114, 2, 102, 101, 99, 0, 114, 2, 102, 111, 114, 109, 0, 114, 2, 102, 117, 110, 0, 114, 2, 102, 117, 115, 0, 114, 2, 109, 105, 115, 115, 0, 114, 2, 109, 105, 116, 0, 114, 2, 112, 101, 116, 0, 114, 2, 112, 108, 101, 0, 114, 2, 115, 105, 115, 0, 114, 2, 115, 117, 0, 114, 2, 115, 117, 0, 114, 2, 116, 97, 105, 0, 114, 2, 116, 117, 0, 114, 2, 118, 21, 0, 114, 101, 103, 114, 105, 110, 8, 3, 48, 121, 34, 13, 81, 34, 122, 50, 0, 4, 114, 2, 112, 101, 116, 114, 3, 48, 128, 0, 114, 2, 118, 105, 0, 114, 109, 101, 2, 97, 3, 48, 128, 65, 122, 0, 114, 115, 112, 105, 2, 114, 97, 3, 48, 128, 89, 48, 13, 0, 114, 115, 101, 118, 101, 114, 3, 48, 128, 89, 122, 84, 6, 142, 0, 97, 99, 101, 3, 48, 129, 89, 0, 7, 6, 112, 114, 0, 101, 8, 2, 100, 105, 14, 128, 132, 131, 3, 48, 34, 2, 37, 0, 4, 101, 8, 2, 17, 67, 21, 3, 48, 34, 2, 122, 0, 101, 8, 2, 100, 105, 99, 0, 101, 8, 2, 115, 99, 114, 0, 101, 115, 8, 2, 101, 110, 116, 3, 48, 34, 2, 122, 88, 0, 4, 101, 8, 2, 101, 109, 3, 48, 34, 2, 129, 0, 101, 8, 2, 109, 111, 108, 0, 101, 8, 2, 117, 0, 101, 8, 2, 105, 110, 21, 14, 128, 132, 131, 3, 48, 34, 4, 129, 0, 111, 2, 112, 97, 110, 3, 48, 34, 6, 136, 0, 4, 111, 2, 99, 101, 100, 3, 48, 34, 13, 0, 111, 2, 99, 101, 101, 0, 111, 2, 99, 101, 115, 115, 105, 0, 111, 2, 99, 108, 97, 105, 0, 111, 2, 99, 117, 114, 0, 111, 2, 100, 117, 99, 0, 111, 2, 102, 97, 110, 0, 111, 2, 102, 101, 115, 0, 111, 2, 102, 105, 99, 0, 111, 2, 102, 111, 117, 0, 111, 2, 102, 117, 0, 111, 2, 103, 114, 101, 115, 0, 111, 2, 104, 105, 98, 0, 111, 2, 106, 101, 99, 0, 111, 2, 108, 105, 102, 0, 111, 2, 108, 111, 110, 0, 111, 2, 109, 111, 116, 0, 111, 2, 110, 111, 117, 110, 99, 0, 111, 2, 110, 117, 110, 0, 111, 2, 112, 101, 108, 0, 111, 2, 112, 101, 110, 115, 0, 111, 2, 112, 105, 116, 0, 111, 2, 112, 114, 105, 101, 0, 111, 2, 112, 117, 108, 0, 111, 2, 115, 112, 101, 99, 116, 17, 65, 0, 111, 2, 116, 101, 99, 0, 111, 2, 116, 101, 115, 116, 0, 111, 2, 116, 114, 97, 99, 0, 111, 2, 116, 114, 117, 0, 111, 2, 118, 105, 100, 0, 111, 2, 118, 105, 115, 0, 111, 2, 118, 111, 99, 0, 111, 2, 118, 111, 107, 0, 111, 8, 2, 112, 17, 65, 0, 111, 8, 2, 115, 97, 0, 111, 8, 2, 115, 99, 0, 4, 101, 2, 99, 105, 111, 3, 48, 34, 121, 0, 101, 2, 106, 117, 100, 105, 0, 101, 8, 2, 17, 67, 11, 0, 101, 8, 2, 102, 101, 114, 101, 110, 0, 101, 8, 2, 103, 110, 0, 101, 8, 2, 109, 105, 0, 101, 8, 2, 110, 25, 0, 101, 8, 2, 112, 32, 0, 101, 8, 2, 112, 111, 115, 105, 0, 101, 8, 2, 115, 99, 111, 0, 101, 8, 2, 115, 116, 0, 101, 100, 97, 2, 116, 111, 3, 48, 34, 121, 72, 13, 0, 101, 118, 8, 2, 97, 108, 3, 48, 34, 121, 84, 0, 4, 101, 115, 2, 101, 110, 99, 3, 48, 34, 121, 88, 0, 101, 115, 8, 2, 101, 110, 116, 97, 0, 101, 115, 105, 2, 100, 101, 110, 3, 48, 34, 121, 88, 122, 0, 105, 110, 99, 2, 101, 13, 3, 48, 34, 122, 50, 89, 0, 4, 111, 2, 100, 117, 99, 116, 3, 48, 34, 124, 0, 111, 2, 112, 101, 114, 0, 111, 2, 112, 104, 0, 111, 2, 112, 111, 115, 105, 116, 0, 111, 2, 115, 101, 99, 0, 111, 2, 116, 101, 115, 116, 97, 110, 0, 111, 2, 118, 105, 100, 101, 110, 0, 111, 5, 3, 2, 99, 101, 115, 115, 0, 111, 8, 2, 112, 97, 103, 0, 111, 98, 97, 98, 3, 48, 34, 124, 71, 13, 71, 0, 4, 101, 2, 102, 105, 120, 3, 48, 34, 129, 0, 101, 2, 104, 105, 115, 116, 0, 101, 8, 2, 32, 0, 101, 8, 2, 97, 109, 0, 101, 8, 2, 99, 105, 110, 99, 0, 101, 8, 2, 102, 101, 99, 0, 101, 8, 2, 109, 105, 117, 0, 101, 8, 2, 113, 117, 0, 101, 8, 2, 115, 99, 0, 101, 8, 2, 118, 105, 101, 119, 0, 101, 8, 2, 118, 105, 111, 0, 101, 97, 8, 2, 99, 104, 0, 101, 100, 101, 2, 99, 101, 115, 3, 48, 34, 129, 72, 122, 0, 4, 111, 2, 102, 105, 108, 3, 48, 34, 136, 0, 111, 2, 103, 114, 97, 0, 111, 2, 108, 111, 103, 0, 111, 109, 101, 2, 116, 104, 3, 48, 34, 136, 65, 129, 0, 105, 8, 2, 111, 3, 48, 34, 137, 0, 105, 111, 2, 114, 105, 116, 3, 48, 34, 137, 6, 124, 0, 105, 118, 97, 116, 8, 3, 48, 34, 137, 84, 13, 47, 0, 7, 6, 114, 101, 0, 4, 2, 103, 101, 110, 101, 114, 3, 2, 34, 129, 0, 8, 2, 97, 114, 109, 0, 4, 8, 2, 97, 108, 105, 103, 3, 4, 34, 129, 0, 8, 2, 97, 108, 108, 0, 8, 2, 97, 117, 21, 14, 128, 132, 130, 0, 8, 2, 99, 111, 110, 14, 128, 132, 130, 0, 8, 2, 99, 114, 101, 97, 116, 0, 8, 2, 100, 101, 17, 67, 14, 128, 132, 130, 0, 97, 8, 2, 108, 108, 111, 14, 128, 132, 130, 0, 100, 101, 1, 110, 117, 2, 17, 67, 3, 4, 34, 129, 72, 113, 0, 1, 118, 117, 3, 13, 0, 100, 1, 116, 17, 67, 10, 2, 32, 3, 13, 72, 0, 4, 8, 2, 100, 114, 3, 34, 2, 129, 0, 8, 2, 101, 100, 117, 14, 128, 132, 130, 0, 8, 2, 101, 109, 14, 128, 132, 130, 0, 8, 2, 101, 110, 14, 128, 132, 130, 0, 8, 2, 101, 113, 14, 128, 132, 130, 0, 8, 2, 101, 115, 14, 128, 132, 130, 0, 8, 2, 101, 120, 14, 128, 132, 130, 0, 116, 114, 111, 2, 14, 128, 132, 133, 3, 34, 4, 121, 47, 34, 136, 0, 4, 8, 2, 99, 111, 109, 14, 128, 132, 130, 3, 34, 4, 129, 0, 8, 2, 105, 21, 14, 128, 132, 130, 0, 8, 2, 117, 110, 14, 128, 132, 130, 0, 4, 97, 2, 17, 67, 11, 3, 34, 4, 129, 13, 0, 97, 8, 2, 100, 17, 67, 0, 4, 1, 17, 65, 2, 32, 3, 34, 13, 0, 1, 114, 2, 32, 0, 2, 109, 101, 110, 116, 0, 114, 2, 32, 0, 100, 1, 17, 66, 10, 2, 32, 3, 34, 13, 72, 0, 4, 1, 110, 117, 2, 17, 67, 21, 3, 34, 113, 0, 2, 97, 99, 116, 0, 2, 100, 101, 109, 12, 0, 8, 2, 17, 67, 21, 0, 8, 99, 2, 109, 97, 116, 0, 97, 2, 108, 105, 116, 3, 34, 113, 35, 0, 112, 101, 2, 116, 105, 116, 105, 118, 3, 34, 113, 48, 121, 0, 108, 101, 2, 110, 116, 3, 34, 113, 55, 121, 0, 4, 108, 105, 1, 110, 117, 2, 97, 3, 34, 113, 55, 137, 0, 108, 105, 2, 97, 0, 4, 115, 2, 105, 103, 110, 3, 34, 113, 88, 0, 115, 2, 117, 108, 116, 0, 97, 2, 108, 116, 101, 3, 34, 113, 124, 0, 97, 2, 103, 101, 110, 3, 34, 113, 138, 0, 4, 2, 17, 67, 101, 108, 32, 3, 34, 121, 0, 2, 99, 107, 0, 2, 99, 116, 0, 2, 100, 17, 67, 0, 2, 102, 117, 103, 0, 2, 103, 105, 115, 116, 0, 2, 112, 108, 105, 0, 2, 112, 114, 105, 109, 0, 2, 112, 116, 0, 2, 115, 105, 100, 117, 101, 0, 2, 115, 111, 108, 117, 0, 2, 115, 111, 110, 0, 2, 115, 116, 108, 0, 2, 116, 105, 99, 0, 2, 116, 105, 110, 97, 0, 2, 118, 101, 108, 0, 2, 118, 101, 114, 101, 110, 0, 2, 118, 111, 108, 117, 0, 8, 2, 17, 67, 17, 67, 32, 0, 8, 2, 17, 67, 32, 0, 8, 2, 99, 114, 101, 97, 116, 105, 0, 8, 2, 100, 17, 67, 0, 8, 2, 100, 111, 108, 101, 110, 0, 8, 2, 110, 17, 67, 0, 8, 2, 115, 99, 117, 0, 97, 2, 108, 109, 0, 112, 101, 2, 116, 105, 116, 3, 34, 121, 48, 13, 0, 112, 114, 101, 115, 101, 110, 116, 3, 34, 121, 48, 34, 113, 88, 6, 121, 50, 47, 0, 112, 101, 114, 8, 2, 116, 3, 34, 121, 48, 114, 0, 99, 111, 2, 103, 3, 34, 121, 49, 13, 0, 4, 99, 107, 111, 110, 3, 34, 121, 49, 13, 50, 0, 99, 111, 110, 2, 99, 0, 99, 114, 101, 8, 2, 97, 110, 3, 34, 121, 49, 34, 129, 0, 108, 101, 8, 2, 103, 3, 34, 121, 55, 113, 0, 108, 101, 2, 118, 3, 34, 121, 55, 123, 0, 100, 1, 98, 17, 67, 2, 32, 12, 3, 34, 121, 72, 0, 103, 105, 109, 3, 34, 121, 75, 122, 65, 0, 103, 117, 2, 108, 3, 34, 121, 81, 57, 134, 0, 102, 101, 114, 101, 110, 100, 3, 34, 121, 83, 13, 34, 6, 121, 50, 72, 0, 118, 101, 2, 110, 17, 65, 3, 34, 121, 84, 13, 0, 115, 105, 2, 100, 101, 110, 3, 34, 121, 88, 113, 0, 109, 101, 110, 116, 3, 34, 122, 65, 13, 50, 47, 0, 104, 101, 110, 3, 34, 122, 107, 6, 121, 50, 0, 4, 2, 103, 101, 110, 3, 34, 129, 0, 2, 103, 105, 111, 110, 0, 2, 116, 97, 105, 108, 0, 8, 2, 97, 110, 0, 8, 2, 99, 101, 110, 116, 0, 97, 2, 109, 0, 97, 5, 3, 2, 108, 3, 34, 129, 14, 0, 115, 101, 2, 108, 3, 34, 129, 89, 121, 0, 4, 105, 8, 2, 99, 3, 34, 137, 0, 105, 8, 2, 108, 0, 97, 2, 108, 3, 34, 141, 0, 1, 10, 2, 32, 3, 114, 0, 7, 6, 115, 117, 0, 1, 101, 114, 2, 109, 17, 65, 3, 88, 57, 134, 0, 109, 97, 98, 1, 101, 114, 3, 88, 57, 134, 65, 13, 71, 0, 5, 3, 1, 101, 114, 2, 109, 17, 65, 3, 88, 134, 0, 4, 2, 98, 100, 117, 101, 3, 89, 2, 125, 0, 2, 98, 115, 101, 114, 0, 2, 98, 115, 105, 115, 0, 2, 98, 116, 114, 97, 0, 4, 2, 98, 109, 105, 3, 89, 13, 0, 2, 98, 115, 99, 114, 105, 98, 0, 2, 98, 117, 114, 98, 97, 0, 2, 98, 118, 0, 2, 99, 99, 17, 65, 0, 2, 102, 102, 105, 99, 0, 2, 112, 112, 108, 0, 2, 112, 112, 111, 114, 0, 2, 112, 112, 114, 101, 115, 0, 8, 2, 98, 109, 101, 114, 0, 98, 115, 116, 97, 2, 110, 116, 3, 89, 13, 71, 89, 47, 35, 0, 4, 115, 8, 2, 112, 3, 89, 13, 89, 0, 115, 8, 2, 116, 97, 105, 0, 115, 99, 8, 2, 101, 0, 1, 110, 2, 97, 108, 3, 89, 57, 134, 0, 4, 114, 1, 110, 117, 2, 112, 3, 89, 114, 0, 114, 2, 109, 0, 114, 2, 112, 97, 0, 114, 2, 112, 114, 0, 114, 2, 114, 0, 114, 2, 118, 0, 4, 2, 99, 99, 117, 108, 3, 89, 125, 0, 2, 112, 112, 108, 101, 0, 2, 112, 112, 108, 105, 99, 0, 8, 2, 98, 0, 114, 2, 114, 101, 121, 0, 4, 114, 3, 89, 128, 0, 114, 8, 0, 115, 8, 2, 17, 65, 3, 89, 134, 88, 0, 4, 114, 5, 5, 3, 89, 148, 0, 114, 5, 5, 8, 0, 4, 114, 1, 97, 101, 3, 90, 114, 0, 114, 1, 111, 0, 114, 101, 1, 10, 2, 32, 0, 4, 2, 97, 108, 3, 90, 134, 0, 8, 97, 99, 0, 103, 97, 114, 3, 91, 117, 81, 114, 0, 4, 114, 1, 110, 101, 3, 91, 143, 0, 114, 1, 110, 105, 2, 17, 65, 0, 114, 2, 97, 110, 99, 0, 114, 101, 8, 0, 7, 6, 116, 104, 0, 1, 32, 48, 15, 2, 32, 3, 13, 87, 0, 8, 2, 111, 109, 21, 3, 47, 0, 4, 2, 97, 110, 100, 3, 47, 107, 0, 2, 101, 97, 100, 0, 2, 101, 97, 114, 116, 0, 2, 105, 108, 108, 0, 2, 111, 108, 101, 0, 2, 111, 111, 100, 0, 2, 111, 117, 115, 101, 0, 101, 113, 117, 101, 3, 47, 121, 49, 0, 97, 109, 101, 115, 8, 3, 47, 121, 65, 88, 0, 97, 105, 3, 47, 137, 0, 4, 1, 97, 101, 2, 101, 114, 3, 86, 0, 1, 111, 111, 109, 115, 0, 1, 114, 2, 105, 101, 114, 0, 1, 114, 2, 121, 0, 1, 114, 111, 2, 105, 0, 2, 101, 110, 32, 0, 2, 101, 114, 17, 67, 0, 2, 101, 114, 110, 32, 0, 2, 101, 115, 116, 0, 2, 105, 116, 104, 0, 101, 2, 32, 0, 101, 109, 8, 3, 86, 2, 121, 65, 0, 101, 108, 101, 115, 115, 3, 86, 13, 55, 6, 121, 89, 0, 101, 100, 1, 117, 111, 2, 32, 3, 86, 72, 0, 105, 110, 103, 1, 101, 101, 3, 86, 113, 68, 0, 4, 101, 114, 2, 32, 3, 86, 114, 0, 101, 114, 2, 101, 114, 0, 101, 114, 101, 2, 32, 0, 101, 114, 101, 8, 3, 86, 140, 0, 4, 3, 87, 0, 1, 32, 48, 48, 2, 32, 0, 1, 32, 48, 49, 2, 32, 0, 1, 97, 99, 2, 101, 114, 105, 0, 1, 103, 2, 101, 110, 32, 0, 1, 104, 112, 0, 1, 110, 2, 101, 114, 12, 0, 1, 114, 97, 101, 2, 121, 0, 1, 114, 111, 119, 2, 32, 0, 2, 101, 114, 109, 0, 8, 2, 17, 71, 0, 8, 2, 114, 17, 71, 0, 8, 2, 119, 17, 71, 0, 8, 101, 2, 101, 114, 0, 105, 111, 8, 3, 87, 4, 137, 136, 0, 101, 114, 97, 112, 3, 87, 121, 34, 13, 48, 0, 101, 8, 2, 109, 17, 65, 3, 87, 129, 0, 7, 6, 117, 101, 0, 3, 57, 134, 0, 2, 110, 100, 3, 57, 134, 6, 121, 0, 4, 2, 110, 3, 57, 134, 13, 0, 2, 116, 0, 8, 17, 67, 2, 108, 0, 101, 3, 57, 134, 129, 0, 110, 101, 2, 32, 3, 57, 134, 129, 50, 0, 114, 2, 116, 3, 58, 140, 0, 4, 1, 108, 3, 134, 0, 1, 114, 0, 8, 115, 0, 1, 108, 2, 110, 116, 105, 3, 134, 6, 121, 0, 4, 1, 108, 2, 110, 3, 134, 13, 0, 8, 17, 67, 17, 67, 2, 108, 0, 7, 6, 117, 105, 0, 1, 21, 2, 116, 121, 3, 6, 57, 134, 122, 0, 1, 99, 114, 2, 116, 111, 117, 115, 3, 7, 57, 134, 122, 0, 1, 110, 2, 115, 3, 57, 134, 0, 1, 115, 101, 106, 2, 116, 3, 57, 134, 113, 0, 114, 2, 32, 3, 57, 143, 0, 115, 1, 99, 3, 58, 122, 88, 0, 115, 105, 110, 101, 1, 99, 3, 58, 122, 88, 129, 50, 0, 1, 103, 2, 116, 97, 3, 113, 0, 4, 1, 98, 2, 108, 3, 122, 0, 1, 99, 114, 2, 116, 0, 1, 103, 2, 108, 17, 67, 0, 8, 103, 2, 110, 0, 4, 1, 106, 2, 99, 3, 134, 0, 1, 108, 115, 0, 1, 114, 2, 116, 0, 1, 115, 2, 116, 0, 115, 1, 114, 2, 101, 3, 134, 88, 0, 1, 114, 103, 2, 116, 3, 134, 113, 0, 4, 1, 108, 102, 2, 100, 3, 134, 122, 0, 1, 114, 100, 2, 100, 0, 4, 1, 103, 2, 100, 17, 65, 13, 3, 137, 0, 1, 103, 2, 115, 101, 0, 1, 103, 101, 98, 2, 108, 0, 8, 103, 2, 108, 101, 0, 100, 101, 1, 103, 2, 108, 3, 137, 72, 0, 7, 6, 117, 110, 0, 4, 2, 97, 110, 105, 3, 2, 57, 134, 50, 0, 8, 2, 105, 113, 0, 4, 2, 114, 101, 103, 105, 3, 2, 125, 50, 0, 8, 2, 17, 65, 14, 128, 132, 130, 0, 8, 2, 21, 14, 128, 132, 130, 0, 110, 8, 3, 2, 125, 50, 50, 0, 8, 2, 105, 108, 3, 4, 57, 134, 50, 0, 4, 8, 2, 100, 101, 14, 128, 132, 130, 3, 4, 125, 50, 0, 8, 2, 101, 110, 14, 128, 132, 130, 0, 8, 2, 101, 120, 14, 128, 132, 130, 0, 8, 2, 105, 100, 101, 0, 8, 2, 105, 109, 14, 128, 132, 130, 0, 8, 2, 105, 110, 14, 128, 132, 130, 0, 8, 2, 114, 101, 17, 67, 21, 14, 128, 132, 130, 0, 100, 101, 114, 8, 2, 21, 14, 128, 132, 133, 3, 4, 125, 50, 72, 114, 0, 97, 8, 2, 98, 3, 4, 125, 50, 119, 0, 1, 21, 2, 97, 108, 3, 6, 57, 134, 50, 0, 4, 1, 17, 67, 2, 101, 114, 3, 57, 134, 50, 0, 1, 116, 2, 101, 0, 2, 105, 0, 8, 2, 105, 111, 0, 8, 2, 105, 120, 0, 101, 2, 32, 0, 105, 116, 2, 101, 3, 57, 134, 50, 6, 137, 47, 0, 105, 8, 3, 57, 134, 50, 122, 0, 4, 1, 112, 2, 105, 115, 104, 3, 125, 50, 0, 2, 17, 65, 0, 8, 2, 100, 117, 108, 97, 0, 8, 2, 103, 117, 0, 4, 1, 106, 2, 17, 65, 3, 134, 50, 0, 1, 114, 2, 105, 0, 5, 3, 1, 116, 2, 101, 0, 101, 1, 108, 2, 32, 0, 101, 1, 114, 2, 32, 0, 101, 5, 3, 1, 100, 2, 32, 0, 101, 5, 3, 1, 116, 2, 32, 0, 7, 6, 117, 112, 0, 4, 8, 2, 98, 3, 2, 125, 48, 0, 8, 2, 99, 0, 8, 2, 100, 0, 8, 2, 101, 0, 8, 2, 103, 0, 8, 2, 104, 0, 8, 2, 115, 101, 0, 8, 2, 115, 116, 0, 1, 115, 2, 114, 101, 3, 2, 134, 48, 0, 1, 99, 99, 111, 3, 57, 117, 48, 0, 121, 1, 99, 99, 111, 3, 57, 117, 48, 137, 0, 111, 110, 3, 125, 48, 124, 50, 0, 4, 1, 17, 67, 2, 108, 101, 3, 134, 48, 0, 1, 17, 67, 2, 108, 105, 0, 2, 108, 32, 0, 101, 114, 105, 1, 115, 2, 111, 3, 134, 48, 6, 141, 34, 122, 0, 101, 114, 1, 115, 3, 134, 48, 114, 0, 7, 6, 117, 114, 0, 1, 106, 2, 121, 3, 13, 34, 0, 101, 100, 1, 103, 2, 32, 3, 13, 72, 0, 1, 116, 2, 17, 65, 3, 57, 13, 34, 0, 101, 1, 115, 10, 2, 32, 3, 57, 13, 114, 0, 4, 101, 1, 110, 101, 2, 32, 3, 57, 114, 0, 101, 5, 3, 1, 103, 2, 32, 0, 4, 1, 17, 67, 2, 17, 65, 3, 57, 117, 34, 0, 1, 21, 2, 97, 116, 105, 111, 110, 0, 1, 21, 2, 121, 0, 97, 1, 21, 2, 116, 3, 57, 117, 34, 138, 0, 4, 2, 101, 100, 32, 3, 57, 143, 0, 8, 2, 17, 65, 0, 8, 102, 2, 17, 65, 0, 8, 102, 2, 121, 0, 101, 1, 116, 97, 99, 105, 2, 32, 0, 101, 2, 32, 0, 1, 98, 2, 101, 3, 57, 143, 34, 0, 4, 1, 103, 10, 2, 32, 3, 114, 0, 1, 104, 10, 2, 32, 0, 1, 109, 10, 2, 32, 0, 1, 116, 97, 115, 2, 100, 0, 101, 1, 103, 2, 32, 0, 101, 1, 106, 110, 2, 32, 0, 101, 1, 122, 105, 0, 4, 1, 98, 2, 105, 3, 121, 34, 0, 1, 98, 2, 121, 0, 114, 5, 35, 1, 98, 2, 111, 3, 125, 34, 0, 4, 1, 112, 115, 2, 32, 3, 128, 0, 2, 17, 66, 0, 2, 32, 0, 114, 1, 102, 2, 121, 0, 114, 2, 32, 0, 114, 5, 3, 0, 103, 1, 98, 2, 101, 114, 3, 128, 81, 0, 4, 101, 1, 108, 105, 2, 32, 3, 142, 0, 101, 1, 114, 2, 32, 0, 4, 1, 106, 2, 105, 3, 143, 0, 1, 108, 2, 17, 65, 12, 0, 1, 112, 10, 2, 32, 0, 8, 106, 2, 121, 0, 1, 114, 2, 17, 65, 12, 3, 143, 34, 0, 4, 5, 5, 1, 112, 115, 2, 32, 3, 148, 0, 5, 5, 2, 17, 66, 0, 5, 5, 2, 32, 0, 114, 5, 5, 1, 102, 2, 121, 0, 114, 5, 5, 2, 32, 0, 103, 5, 5, 1, 98, 2, 101, 114, 3, 148, 81, 0, 7, 6, 39, 0, 114, 101, 2, 32, 14, 128, 128, 131, 3, 13, 0, 118, 101, 2, 32, 14, 128, 128, 131, 3, 13, 84, 0, 100, 2, 32, 14, 128, 128, 130, 3, 72, 0, 4, 115, 1, 32, 54, 49, 2, 32, 3, 88, 0, 115, 2, 32, 14, 128, 128, 130, 0, 4, 115, 1, 102, 2, 32, 14, 128, 128, 130, 3, 89, 0, 115, 1, 104, 99, 111, 2, 32, 14, 128, 128, 130, 0, 115, 1, 107, 2, 32, 14, 128, 128, 130, 0, 115, 1, 112, 2, 32, 14, 128, 128, 130, 0, 115, 1, 116, 2, 32, 14, 128, 128, 130, 0, 4, 115, 1, 32, 54, 2, 32, 3, 113, 88, 0, 115, 1, 101, 99, 2, 32, 14, 128, 128, 130, 0, 115, 1, 101, 115, 2, 32, 14, 128, 128, 130, 0, 115, 1, 104, 99, 2, 32, 14, 128, 128, 130, 0, 115, 1, 104, 115, 2, 32, 14, 128, 128, 130, 0, 115, 1, 115, 2, 32, 14, 128, 128, 130, 0, 115, 1, 120, 2, 32, 14, 128, 128, 130, 0, 115, 1, 122, 2, 32, 14, 128, 128, 130, 0, 108, 108, 2, 32, 14, 128, 128, 131, 3, 118, 0, 7, 6, 69, 0, 3, 0, 4, 1, 21, 2, 109, 98, 101, 114, 3, 6, 121, 0, 2, 110, 116, 105, 0, 2, 110, 116, 111, 117, 115, 0, 2, 110, 116, 117, 0, 116, 116, 101, 2, 32, 3, 6, 121, 47, 0, 116, 116, 97, 2, 32, 3, 6, 121, 47, 13, 0, 99, 116, 111, 109, 121, 2, 32, 14, 128, 128, 134, 3, 6, 121, 49, 47, 13, 65, 122, 0, 110, 2, 100, 17, 65, 32, 3, 6, 121, 50, 0, 110, 115, 107, 2, 32, 3, 6, 121, 50, 89, 49, 0, 108, 108, 97, 2, 32, 3, 6, 121, 55, 13, 0, 115, 113, 117, 101, 3, 6, 121, 89, 49, 0, 4, 2, 17, 67, 105, 97, 3, 6, 129, 0, 2, 115, 105, 97, 0, 109, 2, 105, 99, 32, 3, 6, 129, 65, 0, 97, 2, 110, 32, 3, 6, 141, 0, 114, 105, 2, 17, 65, 3, 6, 141, 34, 113, 0, 101, 114, 2, 32, 3, 6, 142, 0, 111, 117, 115, 2, 32, 3, 8, 57, 13, 89, 0, 97, 2, 32, 3, 8, 141, 0, 110, 101, 114, 2, 32, 3, 10, 50, 13, 0, 110, 105, 110, 103, 2, 32, 3, 10, 50, 113, 68, 0, 4, 2, 17, 66, 17, 67, 32, 3, 13, 0, 2, 17, 66, 17, 67, 101, 32, 0, 2, 17, 66, 32, 0, 2, 110, 116, 32, 0, 114, 2, 105, 101, 32, 3, 13, 34, 0, 114, 121, 2, 32, 3, 13, 34, 2, 122, 0, 4, 110, 2, 32, 3, 13, 50, 0, 110, 2, 97, 116, 17, 65, 0, 110, 101, 100, 2, 32, 3, 13, 50, 72, 0, 109, 2, 32, 3, 13, 65, 0, 115, 1, 114, 17, 67, 2, 32, 14, 128, 129, 130, 3, 13, 88, 0, 116, 114, 121, 2, 32, 14, 128, 128, 130, 3, 34, 122, 0, 4, 100, 1, 99, 10, 2, 32, 14, 128, 139, 130, 3, 47, 0, 100, 1, 104, 99, 10, 2, 32, 14, 128, 139, 130, 0, 100, 1, 107, 10, 2, 32, 14, 128, 139, 130, 0, 100, 1, 112, 10, 2, 32, 14, 128, 139, 130, 0, 100, 1, 120, 10, 2, 32, 14, 128, 136, 130, 0, 4, 100, 1, 21, 21, 2, 32, 14, 128, 139, 130, 3, 72, 0, 100, 1, 109, 111, 21, 21, 10, 2, 32, 14, 128, 136, 130, 0, 100, 1, 114, 117, 2, 32, 14, 128, 138, 129, 0, 100, 1, 121, 2, 32, 0, 115, 1, 10, 2, 32, 14, 128, 129, 130, 3, 88, 0, 100, 1, 17, 67, 10, 2, 32, 14, 128, 139, 130, 3, 109, 0, 4, 115, 1, 102, 2, 32, 14, 128, 129, 130, 3, 110, 0, 115, 1, 107, 2, 32, 14, 128, 129, 130, 0, 115, 1, 112, 2, 32, 14, 128, 129, 130, 0, 115, 1, 116, 2, 32, 14, 128, 129, 130, 0, 2, 111, 32, 3, 113, 0, 117, 115, 2, 32, 3, 113, 13, 89, 0, 4, 114, 1, 100, 97, 2, 32, 14, 128, 128, 129, 3, 114, 0, 114, 2, 17, 67, 0, 114, 2, 32, 0, 114, 115, 1, 100, 97, 2, 32, 14, 128, 128, 130, 3, 114, 88, 0, 4, 108, 2, 32, 3, 118, 0, 108, 101, 2, 32, 0, 108, 108, 2, 12, 0, 4, 1, 108, 2, 112, 115, 3, 121, 0, 1, 108, 2, 112, 116, 0, 2, 110, 100, 111, 117, 115, 0, 2, 110, 105, 110, 103, 0, 2, 115, 115, 0, 2, 116, 105, 99, 32, 0, 2, 116, 114, 105, 99, 0, 2, 120, 32, 0, 114, 2, 105, 99, 32, 3, 121, 34, 0, 110, 5, 8, 2, 32, 3, 121, 50, 0, 110, 105, 110, 103, 5, 8, 2, 32, 3, 121, 50, 113, 68, 0, 108, 5, 8, 2, 32, 3, 121, 55, 0, 115, 115, 2, 32, 3, 121, 89, 0, 1, 107, 97, 110, 2, 100, 3, 122, 0, 100, 108, 121, 2, 32, 14, 128, 129, 132, 3, 122, 72, 55, 2, 122, 0, 4, 100, 1, 100, 10, 2, 32, 14, 128, 139, 130, 3, 123, 72, 0, 100, 1, 116, 10, 2, 32, 14, 128, 139, 130, 0, 4, 39, 115, 1, 99, 2, 32, 14, 128, 129, 131, 3, 123, 88, 0, 39, 115, 1, 115, 2, 32, 14, 128, 129, 130, 0, 115, 1, 99, 2, 32, 14, 128, 129, 130, 0, 115, 1, 103, 2, 32, 14, 128, 129, 130, 0, 115, 1, 104, 99, 2, 32, 14, 128, 129, 130, 0, 115, 1, 104, 112, 2, 32, 14, 128, 129, 130, 0, 115, 1, 104, 115, 2, 32, 14, 128, 129, 130, 0, 115, 1, 115, 2, 32, 14, 128, 129, 130, 0, 115, 1, 120, 2, 32, 14, 128, 128, 130, 0, 4, 2, 100, 105, 97, 32, 3, 129, 0, 2, 100, 105, 99, 32, 0, 2, 116, 101, 32, 0, 69, 2, 32, 0, 101, 2, 32, 0, 101, 2, 100, 0, 105, 2, 110, 32, 0, 110, 101, 2, 32, 3, 129, 50, 0, 109, 101, 2, 32, 3, 129, 65, 0, 115, 101, 2, 32, 3, 129, 88, 0, 119, 2, 32, 3, 134, 0, 105, 2, 32, 3, 137, 0, 121, 1, 98, 111, 2, 32, 3, 138, 0, 7, 6, 97, 0, 8, 2, 113, 117, 3, 2, 35, 0, 101, 114, 8, 99, 3, 2, 140, 0, 8, 2, 32, 15, 3, 4, 138, 0, 4, 1, 21, 2, 107, 105, 32, 3, 6, 35, 0, 1, 104, 2, 122, 97, 114, 0, 2, 122, 122, 32, 0, 4, 1, 21, 2, 122, 105, 32, 3, 6, 126, 0, 2, 17, 66, 111, 32, 0, 2, 17, 66, 117, 32, 0, 2, 17, 67, 97, 32, 0, 107, 117, 2, 32, 3, 6, 126, 49, 134, 0, 119, 105, 1, 21, 2, 32, 3, 6, 126, 58, 122, 0, 122, 101, 1, 107, 21, 2, 32, 3, 6, 126, 88, 122, 0, 4, 97, 114, 3, 6, 127, 0, 101, 114, 1, 114, 0, 101, 2, 118, 97, 108, 3, 6, 129, 0, 4, 1, 21, 2, 17, 66, 105, 97, 3, 6, 138, 0, 1, 21, 2, 17, 66, 105, 117, 0, 1, 21, 2, 116, 105, 111, 117, 115, 0, 2, 17, 67, 97, 98, 108, 101, 0, 2, 17, 67, 97, 98, 108, 121, 0, 2, 17, 67, 105, 98, 108, 101, 0, 2, 116, 105, 111, 110, 0, 2, 122, 105, 100, 101, 0, 8, 2, 45, 0, 101, 97, 3, 6, 141, 0, 1, 98, 10, 2, 32, 3, 8, 13, 0, 111, 2, 32, 3, 8, 135, 0, 4, 1, 10, 2, 32, 3, 13, 0, 1, 103, 2, 122, 101, 17, 67, 11, 0, 1, 109, 2, 104, 111, 103, 0, 1, 119, 111, 2, 100, 0, 2, 119, 97, 121, 32, 0, 104, 1, 10, 2, 32, 0, 113, 117, 97, 2, 116, 3, 13, 49, 58, 35, 0, 4, 3, 35, 0, 1, 17, 67, 2, 120, 12, 0, 1, 109, 2, 106, 101, 115, 0, 1, 110, 2, 116, 105, 111, 110, 97, 108, 0, 1, 110, 2, 116, 117, 114, 97, 0, 1, 114, 98, 2, 122, 105, 108, 0, 1, 114, 114, 105, 2, 116, 105, 111, 0, 1, 119, 115, 2, 103, 0, 1, 119, 115, 2, 109, 32, 0, 1, 119, 115, 2, 110, 107, 0, 2, 17, 66, 101, 17, 67, 111, 32, 0, 2, 17, 66, 101, 114, 17, 65, 0, 2, 17, 66, 101, 114, 17, 67, 0, 2, 17, 66, 101, 116, 0, 2, 17, 67, 101, 101, 12, 0, 2, 119, 17, 65, 0, 8, 2, 118, 101, 0, 8, 2, 120, 12, 0, 8, 114, 2, 116, 105, 111, 110, 0, 4, 97, 1, 97, 97, 3, 35, 12, 0, 97, 2, 97, 0, 107, 1, 21, 2, 105, 97, 3, 35, 49, 0, 113, 117, 2, 97, 3, 35, 49, 58, 0, 113, 117, 105, 3, 35, 49, 58, 122, 0, 101, 100, 1, 21, 2, 32, 14, 128, 128, 130, 3, 72, 0, 4, 1, 45, 2, 45, 3, 119, 0, 8, 2, 32, 0, 8, 2, 45, 104, 97, 108, 102, 0, 8, 2, 107, 21, 0, 8, 2, 119, 104, 21, 0, 113, 117, 2, 97, 114, 105, 17, 65, 3, 119, 49, 58, 0, 4, 119, 8, 2, 97, 12, 3, 119, 58, 0, 119, 8, 2, 111, 107, 0, 1, 108, 2, 116, 104, 3, 120, 0, 2, 17, 66, 105, 110, 103, 3, 121, 0, 101, 109, 111, 114, 114, 104, 1, 104, 3, 121, 65, 114, 34, 0, 1, 110, 103, 105, 115, 2, 116, 117, 114, 101, 3, 122, 0, 4, 1, 117, 113, 115, 2, 115, 104, 3, 124, 0, 1, 119, 2, 98, 0, 1, 119, 2, 100, 0, 1, 119, 2, 115, 0, 1, 119, 2, 116, 99, 0, 1, 119, 115, 2, 17, 66, 0, 4, 1, 17, 67, 29, 2, 32, 3, 126, 0, 1, 17, 67, 100, 110, 97, 114, 103, 2, 32, 0, 1, 119, 115, 2, 122, 0, 97, 0, 104, 2, 17, 67, 0, 104, 2, 32, 0, 4, 101, 3, 129, 0, 101, 1, 104, 2, 109, 0, 101, 8, 2, 111, 110, 0, 111, 105, 115, 2, 32, 3, 129, 91, 0, 111, 105, 115, 101, 2, 32, 3, 129, 91, 13, 0, 4, 1, 119, 2, 116, 101, 114, 3, 130, 0, 119, 0, 119, 8, 2, 102, 0, 119, 8, 2, 107, 0, 119, 101, 2, 17, 66, 0, 119, 101, 2, 32, 0, 119, 101, 8, 0, 119, 97, 108, 3, 130, 55, 0, 4, 111, 1, 109, 3, 135, 0, 111, 1, 109, 2, 114, 105, 0, 111, 1, 116, 0, 4, 101, 1, 109, 2, 115, 116, 3, 137, 0, 121, 8, 0, 4, 1, 17, 67, 29, 2, 17, 66, 121, 32, 3, 138, 0, 1, 32, 15, 2, 32, 0, 1, 104, 2, 122, 17, 65, 0, 1, 108, 2, 122, 17, 71, 0, 1, 108, 98, 2, 122, 111, 110, 0, 1, 108, 103, 2, 99, 105, 0, 1, 109, 2, 106, 111, 114, 32, 0, 1, 109, 2, 106, 111, 114, 101, 0, 1, 110, 2, 17, 67, 97, 108, 0, 1, 110, 2, 116, 117, 114, 0, 1, 112, 2, 116, 105, 101, 110, 0, 1, 114, 2, 99, 105, 17, 65, 0, 1, 114, 2, 122, 105, 0, 1, 114, 101, 2, 115, 117, 114, 0, 1, 119, 2, 17, 66, 101, 13, 0, 1, 119, 115, 2, 116, 104, 0, 2, 17, 66, 101, 13, 0, 2, 17, 67, 97, 98, 105, 108, 105, 116, 121, 0, 2, 115, 105, 111, 110, 0, 2, 116, 104, 101, 32, 12, 0, 2, 122, 121, 0, 8, 2, 32, 45, 0, 8, 2, 118, 105, 97, 116, 0, 8, 2, 118, 111, 110, 0, 101, 2, 108, 0, 121, 0, 121, 1, 119, 0, 111, 114, 3, 138, 6, 133, 0, 111, 1, 103, 2, 108, 3, 138, 13, 0, 113, 117, 101, 2, 111, 3, 138, 49, 58, 122, 0, 39, 115, 8, 2, 32, 3, 138, 88, 0, 122, 111, 114, 1, 114, 3, 138, 88, 114, 0, 121, 108, 101, 8, 3, 138, 118, 0, 111, 3, 138, 124, 0, 4, 101, 114, 3, 140, 0, 101, 114, 8, 2, 111, 0, 121, 114, 8, 0, 4, 101, 114, 111, 2, 112, 108, 97, 110, 3, 140, 34, 13, 0, 101, 114, 111, 2, 115, 111, 108, 0, 101, 114, 111, 8, 3, 140, 34, 136, 0, 119, 114, 2, 32, 3, 146, 0, 7, 6, 98, 0, 4, 1, 109, 2, 32, 3, 0, 2, 98, 3, 0, 4, 116, 1, 101, 100, 3, 47, 0, 116, 1, 117, 115, 2, 108, 0, 4, 3, 71, 0, 8, 2, 18, 66, 17, 71, 0, 104, 8, 0, 97, 8, 2, 109, 98, 21, 3, 71, 2, 35, 0, 4, 97, 108, 108, 105, 8, 2, 21, 3, 71, 4, 35, 55, 113, 0, 97, 108, 108, 121, 8, 2, 21, 0, 97, 116, 116, 108, 101, 8, 2, 21, 14, 128, 132, 134, 3, 71, 6, 35, 47, 118, 0, 111, 111, 107, 8, 2, 21, 21, 14, 128, 132, 132, 3, 71, 6, 117, 49, 0, 117, 114, 121, 1, 21, 2, 32, 14, 128, 130, 132, 3, 71, 34, 2, 122, 0, 114, 122, 8, 2, 101, 3, 71, 34, 88, 0, 117, 103, 8, 2, 108, 101, 3, 71, 57, 134, 81, 0, 111, 8, 2, 115, 111, 109, 3, 71, 117, 0, 97, 108, 108, 105, 2, 115, 116, 3, 71, 119, 55, 6, 122, 0, 117, 114, 121, 5, 3, 1, 21, 2, 32, 14, 128, 130, 132, 3, 71, 121, 34, 2, 122, 0, 121, 116, 101, 8, 3, 71, 137, 47, 0, 97, 121, 111, 117, 8, 3, 71, 137, 134, 0, 7, 6, 99, 0, 4, 1, 115, 2, 101, 3, 0, 2, 113, 3, 0, 122, 8, 2, 97, 114, 3, 47, 89, 0, 4, 3, 49, 0, 1, 97, 109, 2, 105, 110, 0, 2, 101, 108, 116, 0, 8, 2, 18, 66, 17, 71, 0, 99, 0, 99, 1, 111, 99, 2, 105, 32, 0, 99, 1, 111, 115, 2, 101, 114, 0, 99, 104, 0, 107, 0, 104, 97, 114, 97, 2, 99, 116, 3, 49, 35, 34, 113, 0, 117, 97, 1, 101, 3, 49, 58, 35, 0, 4, 99, 2, 101, 3, 49, 89, 0, 99, 2, 105, 0, 119, 109, 8, 3, 49, 117, 65, 0, 97, 99, 111, 2, 112, 104, 3, 49, 119, 49, 6, 124, 0, 105, 97, 8, 2, 114, 97, 3, 49, 141, 0, 4, 99, 2, 105, 110, 111, 3, 76, 0, 122, 8, 2, 101, 0, 2, 101, 108, 108, 18, 68, 32, 3, 76, 6, 0, 122, 101, 99, 104, 3, 76, 121, 49, 0, 4, 2, 69, 3, 89, 0, 2, 97, 101, 115, 0, 2, 101, 0, 2, 105, 0, 2, 121, 0, 2, 195, 169, 0, 101, 8, 2, 108, 101, 115, 116, 3, 89, 13, 0, 101, 109, 101, 110, 116, 8, 3, 89, 113, 65, 121, 50, 47, 0, 105, 115, 109, 2, 32, 3, 89, 122, 88, 13, 65, 0, 105, 112, 104, 2, 101, 114, 3, 89, 137, 83, 0, 105, 97, 2, 114, 121, 3, 91, 8, 13, 0, 4, 101, 111, 117, 115, 3, 91, 8, 13, 89, 0, 105, 111, 117, 115, 0, 4, 105, 97, 110, 2, 32, 3, 91, 13, 50, 0, 105, 101, 110, 0, 105, 111, 110, 0, 105, 97, 108, 3, 91, 13, 55, 0, 105, 97, 108, 2, 32, 3, 91, 118, 0, 105, 97, 108, 5, 8, 2, 32, 3, 91, 119, 55, 0, 105, 101, 110, 5, 8, 3, 91, 121, 50, 0, 105, 97, 2, 108, 105, 116, 121, 3, 91, 122, 35, 0, 105, 97, 2, 98, 3, 91, 141, 0, 105, 97, 110, 3, 91, 141, 50, 0, 7, 6, 100, 0, 2, 100, 3, 0, 117, 109, 1, 21, 2, 32, 3, 8, 72, 13, 65, 0, 116, 2, 32, 3, 47, 0, 110, 101, 1, 101, 119, 2, 115, 100, 3, 50, 0, 4, 3, 72, 0, 1, 101, 21, 21, 2, 32, 14, 128, 128, 129, 0, 8, 2, 18, 66, 17, 71, 0, 8, 2, 104, 21, 21, 0, 8, 2, 110, 105, 101, 0, 8, 2, 119, 17, 71, 0, 39, 8, 2, 17, 65, 14, 128, 132, 130, 0, 100, 104, 0, 104, 2, 25, 0, 98, 2, 32, 3, 72, 4, 129, 71, 129, 0, 109, 105, 8, 2, 116, 114, 3, 72, 13, 65, 129, 0, 117, 5, 35, 2, 112, 108, 3, 72, 57, 134, 0, 4, 117, 114, 2, 17, 65, 3, 72, 57, 143, 0, 117, 114, 2, 32, 0, 117, 8, 2, 112, 3, 72, 134, 0, 121, 101, 8, 3, 72, 137, 0, 105, 114, 8, 2, 32, 3, 72, 145, 0, 4, 103, 2, 17, 66, 3, 75, 0, 103, 2, 32, 0, 103, 2, 101, 0, 103, 2, 105, 0, 103, 2, 121, 0, 106, 0, 106, 8, 2, 17, 71, 0, 103, 101, 100, 2, 32, 3, 75, 72, 0, 117, 114, 101, 1, 101, 99, 3, 75, 114, 0, 4, 117, 2, 97, 108, 32, 3, 75, 134, 0, 117, 2, 99, 97, 116, 0, 117, 5, 3, 1, 10, 2, 17, 67, 17, 65, 0, 7, 6, 101, 0, 4, 1, 10, 2, 32, 3, 0, 4, 1, 21, 21, 2, 109, 101, 110, 116, 32, 3, 0, 4, 2, 102, 117, 108, 3, 0, 2, 119, 111, 114, 107, 3, 0, 4, 1, 17, 66, 99, 97, 2, 32, 3, 2, 122, 0, 2, 102, 102, 101, 99, 0, 2, 102, 102, 105, 99, 0, 2, 113, 117, 105, 112, 0, 8, 2, 99, 108, 0, 8, 2, 102, 102, 117, 0, 8, 2, 106, 17, 65, 0, 8, 2, 112, 104, 101, 109, 0, 8, 2, 113, 117, 97, 116, 0, 113, 117, 105, 118, 3, 2, 122, 49, 58, 122, 84, 0, 2, 17, 67, 105, 99, 97, 108, 3, 6, 121, 0, 117, 114, 2, 32, 3, 6, 128, 0, 117, 115, 101, 1, 21, 2, 32, 3, 6, 128, 88, 0, 4, 1, 21, 2, 17, 67, 105, 97, 32, 3, 6, 129, 0, 1, 21, 2, 103, 105, 99, 0, 1, 104, 2, 115, 105, 111, 110, 0, 2, 17, 66, 111, 32, 0, 2, 17, 66, 111, 101, 32, 0, 101, 1, 116, 2, 110, 32, 0, 101, 2, 109, 0, 117, 115, 101, 5, 3, 1, 21, 2, 32, 3, 6, 134, 88, 0, 117, 1, 115, 2, 109, 32, 3, 6, 141, 0, 101, 114, 3, 6, 142, 0, 117, 114, 5, 3, 2, 32, 3, 6, 143, 0, 117, 114, 5, 5, 2, 32, 3, 6, 148, 0, 117, 115, 1, 10, 2, 32, 3, 8, 113, 13, 89, 0, 122, 1, 21, 2, 32, 3, 8, 121, 88, 0, 4, 1, 10, 2, 110, 3, 13, 0, 1, 108, 2, 103, 105, 116, 0, 1, 108, 101, 99, 2, 98, 114, 97, 0, 98, 108, 101, 1, 21, 21, 2, 32, 3, 13, 71, 118, 0, 103, 1, 10, 2, 121, 3, 13, 75, 0, 39, 115, 1, 114, 17, 67, 10, 2, 32, 3, 13, 88, 0, 99, 121, 1, 10, 2, 32, 3, 13, 89, 2, 37, 0, 4, 117, 3, 57, 134, 0, 119, 0, 119, 2, 32, 0, 117, 114, 111, 8, 3, 57, 143, 34, 136, 0, 117, 114, 111, 8, 2, 112, 101, 3, 57, 143, 44, 13, 0, 119, 97, 121, 2, 32, 14, 128, 128, 131, 3, 58, 138, 0, 4, 39, 115, 1, 17, 67, 10, 2, 32, 14, 128, 130, 130, 3, 88, 0, 39, 115, 1, 104, 116, 10, 2, 32, 14, 128, 130, 130, 0, 39, 115, 1, 114, 10, 2, 32, 14, 128, 130, 130, 0, 4, 39, 115, 1, 102, 10, 2, 32, 14, 128, 130, 130, 3, 89, 0, 39, 115, 1, 107, 10, 2, 32, 14, 128, 130, 130, 0, 39, 115, 1, 112, 10, 2, 32, 14, 128, 130, 130, 0, 39, 115, 1, 116, 10, 2, 32, 14, 128, 130, 130, 0, 4, 1, 110, 2, 103, 111, 116, 3, 113, 0, 2, 111, 0, 4, 112, 2, 111, 120, 3, 113, 48, 0, 112, 8, 2, 105, 115, 17, 67, 0, 102, 121, 1, 21, 21, 2, 32, 3, 113, 83, 137, 0, 102, 105, 101, 114, 2, 32, 3, 113, 83, 145, 0, 4, 3, 121, 0, 1, 104, 17, 65, 2, 110, 0, 1, 112, 115, 2, 99, 105, 97, 0, 1, 114, 10, 2, 110, 0, 1, 114, 99, 2, 112, 101, 12, 0, 1, 114, 99, 115, 105, 100, 2, 116, 105, 111, 110, 0, 2, 17, 67, 105, 99, 32, 0, 112, 105, 8, 3, 121, 48, 122, 0, 112, 105, 100, 101, 114, 8, 3, 121, 48, 122, 72, 6, 128, 0, 99, 104, 1, 116, 2, 32, 3, 121, 49, 0, 103, 105, 1, 108, 2, 98, 3, 121, 75, 13, 0, 4, 1, 108, 108, 2, 110, 103, 101, 3, 122, 0, 1, 109, 2, 99, 104, 97, 110, 105, 99, 0, 1, 116, 110, 105, 2, 103, 101, 0, 1, 116, 110, 105, 2, 103, 114, 97, 0, 1, 116, 114, 101, 118, 2, 98, 0, 8, 108, 101, 2, 109, 101, 110, 0, 101, 1, 102, 102, 111, 99, 0, 99, 111, 110, 111, 2, 109, 3, 122, 49, 6, 124, 50, 13, 0, 4, 39, 115, 1, 99, 10, 2, 32, 14, 128, 130, 130, 3, 122, 88, 0, 39, 115, 1, 103, 10, 2, 32, 14, 128, 130, 130, 0, 39, 115, 1, 104, 99, 10, 2, 32, 14, 128, 130, 130, 0, 39, 115, 1, 104, 112, 10, 2, 32, 14, 128, 130, 130, 0, 39, 115, 1, 104, 115, 10, 2, 32, 14, 128, 130, 130, 0, 39, 115, 1, 115, 10, 2, 32, 14, 128, 130, 130, 0, 39, 115, 1, 120, 10, 2, 32, 14, 128, 130, 130, 0, 117, 114, 1, 108, 3, 128, 0, 4, 1, 17, 67, 29, 2, 17, 66, 101, 32, 3, 129, 0, 1, 17, 67, 29, 2, 32, 24, 0, 1, 21, 2, 116, 105, 111, 0, 1, 29, 2, 103, 97, 110, 32, 0, 1, 100, 2, 102, 97, 117, 108, 116, 0, 1, 108, 2, 103, 97, 108, 0, 1, 110, 2, 103, 114, 111, 0, 1, 112, 115, 2, 99, 105, 101, 115, 0, 1, 114, 2, 103, 97, 108, 0, 1, 114, 102, 2, 113, 0, 2, 17, 67, 105, 117, 17, 66, 0, 2, 98, 114, 105, 97, 0, 2, 109, 101, 32, 0, 2, 109, 101, 111, 117, 0, 2, 113, 117, 97, 108, 0, 8, 2, 113, 117, 97, 0, 8, 17, 67, 2, 109, 117, 114, 0, 8, 115, 2, 113, 117, 101, 0, 101, 0, 117, 2, 109, 32, 0, 99, 111, 110, 111, 2, 109, 105, 99, 3, 129, 49, 13, 50, 6, 124, 0, 99, 111, 8, 2, 115, 3, 129, 49, 136, 0, 103, 105, 111, 110, 1, 108, 3, 129, 75, 13, 50, 0, 103, 121, 2, 112, 116, 3, 129, 75, 122, 0, 4, 101, 115, 101, 1, 104, 99, 3, 129, 88, 0, 101, 122, 101, 2, 21, 0, 4, 119, 1, 106, 2, 12, 3, 134, 0, 119, 1, 108, 2, 12, 0, 119, 1, 114, 2, 12, 0, 119, 5, 3, 1, 100, 0, 119, 5, 3, 1, 110, 0, 119, 5, 3, 1, 116, 0, 119, 8, 115, 0, 119, 101, 1, 106, 2, 108, 3, 134, 13, 0, 119, 8, 115, 2, 32, 3, 136, 0, 4, 104, 2, 25, 3, 138, 0, 106, 1, 118, 2, 32, 0, 4, 117, 1, 100, 2, 116, 115, 3, 139, 0, 117, 1, 114, 2, 100, 0, 39, 101, 114, 3, 140, 0, 117, 114, 5, 5, 3, 148, 0, 7, 6, 102, 0, 2, 102, 3, 0, 4, 3, 83, 0, 8, 2, 18, 66, 17, 71, 0, 116, 2, 101, 110, 0, 111, 114, 2, 115, 101, 101, 3, 83, 2, 132, 0, 111, 114, 2, 119, 97, 114, 100, 3, 83, 6, 133, 0, 4, 97, 2, 109, 105, 108, 105, 97, 114, 3, 83, 13, 0, 111, 114, 2, 98, 97, 100, 0, 111, 114, 2, 98, 105, 100, 0, 105, 8, 2, 116, 122, 21, 3, 83, 113, 0, 101, 100, 1, 114, 101, 2, 32, 3, 83, 121, 72, 0, 106, 8, 2, 111, 114, 100, 3, 83, 122, 6, 0, 97, 2, 99, 105, 17, 65, 3, 83, 138, 0, 7, 6, 103, 0, 8, 2, 110, 17, 71, 3, 0, 2, 121, 110, 111, 117, 115, 32, 3, 8, 75, 0, 111, 2, 110, 97, 108, 32, 3, 8, 81, 124, 0, 104, 116, 3, 47, 0, 110, 2, 32, 3, 50, 0, 109, 2, 32, 3, 65, 0, 4, 1, 101, 118, 2, 101, 116, 3, 75, 0, 1, 111, 2, 101, 116, 0, 1, 114, 101, 2, 101, 116, 0, 2, 69, 0, 2, 101, 0, 2, 101, 116, 116, 101, 32, 0, 2, 105, 0, 2, 121, 0, 103, 1, 97, 120, 101, 2, 101, 114, 0, 101, 2, 110, 105, 99, 32, 3, 75, 6, 121, 0, 101, 110, 101, 115, 105, 115, 3, 75, 6, 121, 50, 113, 89, 122, 89, 0, 101, 111, 117, 115, 3, 75, 8, 13, 89, 0, 4, 105, 97, 1, 10, 2, 17, 67, 32, 3, 75, 13, 0, 105, 97, 1, 10, 2, 32, 0, 105, 117, 1, 10, 2, 109, 0, 4, 105, 110, 103, 1, 108, 3, 75, 113, 68, 0, 105, 110, 103, 1, 114, 0, 97, 111, 108, 8, 3, 75, 138, 55, 0, 4, 3, 81, 0, 1, 17, 65, 11, 2, 101, 114, 0, 1, 110, 117, 104, 0, 1, 111, 2, 121, 32, 0, 1, 111, 98, 2, 69, 121, 0, 1, 111, 103, 2, 105, 99, 32, 0, 2, 101, 97, 114, 0, 2, 101, 101, 107, 0, 2, 101, 116, 0, 2, 105, 102, 116, 0, 2, 105, 103, 103, 0, 2, 105, 108, 17, 67, 0, 2, 105, 108, 116, 0, 2, 105, 114, 25, 0, 2, 105, 118, 101, 0, 8, 2, 18, 66, 17, 71, 0, 8, 2, 101, 99, 0, 8, 2, 101, 107, 0, 8, 2, 101, 114, 116, 0, 8, 2, 105, 100, 0, 8, 2, 105, 108, 25, 0, 8, 2, 105, 109, 0, 8, 2, 105, 116, 0, 8, 2, 105, 122, 0, 8, 2, 119, 17, 71, 0, 8, 2, 121, 110, 0, 103, 0, 104, 1, 17, 67, 2, 17, 65, 0, 104, 2, 17, 67, 0, 104, 2, 32, 0, 104, 2, 97, 110, 0, 104, 8, 2, 17, 71, 0, 117, 101, 2, 32, 0, 105, 2, 32, 3, 81, 2, 122, 0, 101, 2, 100, 100, 3, 81, 6, 121, 0, 110, 117, 8, 3, 81, 13, 50, 134, 0, 117, 97, 121, 1, 21, 2, 32, 3, 81, 58, 137, 0, 4, 101, 1, 114, 111, 102, 2, 116, 3, 81, 121, 0, 117, 101, 8, 0, 105, 103, 97, 8, 3, 81, 122, 81, 13, 0, 117, 101, 114, 8, 2, 110, 3, 81, 128, 0, 105, 1, 97, 2, 32, 3, 81, 137, 0, 7, 6, 104, 0, 4, 2, 32, 3, 0, 4, 2, 104, 3, 0, 4, 8, 2, 111, 110, 111, 114, 3, 0, 4, 8, 2, 111, 110, 111, 117, 3, 0, 8, 17, 66, 3, 0, 101, 39, 8, 3, 2, 107, 129, 0, 108, 1, 25, 3, 105, 0, 3, 107, 0, 111, 109, 111, 8, 2, 115, 3, 107, 4, 136, 65, 136, 0, 4, 121, 112, 111, 2, 100, 101, 3, 107, 4, 137, 48, 13, 0, 121, 112, 111, 2, 116, 104, 101, 116, 0, 121, 112, 111, 8, 2, 21, 14, 128, 132, 132, 3, 107, 4, 137, 48, 136, 0, 97, 109, 109, 101, 100, 1, 21, 3, 107, 6, 35, 65, 122, 72, 0, 97, 110, 1, 101, 2, 32, 3, 107, 13, 50, 0, 97, 110, 1, 17, 65, 2, 32, 3, 107, 35, 50, 0, 111, 111, 100, 1, 10, 2, 32, 14, 128, 128, 132, 3, 107, 117, 72, 0, 111, 111, 100, 115, 1, 10, 2, 32, 14, 128, 128, 133, 3, 107, 117, 72, 88, 0, 101, 116, 101, 114, 111, 8, 3, 107, 121, 47, 34, 136, 0, 101, 97, 100, 1, 21, 2, 32, 14, 128, 128, 132, 3, 107, 121, 72, 0, 121, 112, 111, 8, 2, 99, 114, 3, 107, 122, 48, 124, 0, 111, 114, 114, 105, 8, 3, 107, 124, 34, 122, 0, 111, 114, 115, 101, 8, 3, 107, 132, 89, 0, 111, 117, 115, 101, 115, 2, 32, 14, 128, 128, 134, 3, 107, 135, 88, 113, 88, 0, 4, 111, 117, 115, 101, 2, 32, 14, 128, 128, 133, 3, 107, 135, 89, 0, 111, 117, 115, 101, 8, 2, 21, 0, 111, 108, 100, 1, 10, 2, 32, 14, 128, 128, 132, 3, 107, 136, 55, 72, 0, 111, 108, 109, 101, 3, 107, 136, 65, 0, 111, 109, 101, 8, 2, 111, 3, 107, 136, 65, 129, 0, 111, 109, 111, 101, 111, 8, 3, 107, 136, 65, 129, 136, 0, 4, 121, 112, 111, 2, 116, 101, 110, 117, 3, 107, 137, 48, 6, 124, 0, 121, 112, 111, 2, 116, 104, 101, 115, 0, 97, 2, 115, 116, 3, 107, 138, 0, 101, 114, 111, 3, 107, 141, 34, 136, 0, 111, 110, 101, 2, 115, 116, 3, 124, 50, 122, 0, 101, 105, 114, 3, 140, 0, 111, 117, 114, 3, 146, 0, 7, 6, 105, 0, 108, 8, 2, 108, 21, 3, 2, 122, 55, 0, 4, 8, 100, 2, 108, 97, 116, 3, 2, 137, 0, 39, 8, 0, 4, 1, 21, 2, 98, 117, 116, 105, 118, 101, 3, 6, 122, 0, 1, 21, 2, 98, 117, 116, 111, 114, 0, 1, 21, 2, 99, 105, 112, 0, 2, 17, 67, 17, 67, 105, 32, 0, 2, 99, 105, 97, 108, 0, 2, 103, 101, 110, 111, 117, 115, 0, 2, 116, 105, 111, 110, 0, 4, 108, 97, 1, 21, 2, 32, 3, 6, 122, 55, 13, 0, 108, 108, 97, 1, 21, 2, 32, 0, 102, 2, 105, 99, 17, 65, 110, 17, 67, 3, 6, 122, 83, 0, 99, 105, 97, 110, 3, 6, 122, 91, 13, 50, 0, 4, 1, 21, 2, 100, 111, 32, 3, 6, 129, 0, 2, 98, 97, 32, 0, 2, 113, 117, 101, 32, 0, 2, 119, 111, 0, 4, 1, 99, 2, 100, 97, 108, 3, 6, 137, 0, 2, 122, 111, 110, 32, 0, 99, 104, 97, 101, 108, 1, 109, 3, 6, 137, 49, 118, 0, 97, 108, 1, 10, 2, 32, 3, 8, 113, 13, 55, 0, 117, 115, 1, 10, 3, 8, 113, 13, 89, 0, 99, 111, 1, 10, 2, 32, 3, 8, 113, 49, 136, 0, 102, 121, 1, 10, 2, 32, 3, 8, 113, 83, 137, 0, 4, 1, 10, 2, 99, 32, 3, 8, 122, 0, 1, 10, 2, 99, 97, 32, 0, 1, 10, 2, 99, 97, 108, 0, 1, 10, 2, 99, 105, 17, 67, 101, 32, 0, 1, 10, 2, 99, 105, 115, 109, 32, 0, 1, 10, 2, 99, 105, 115, 116, 32, 0, 1, 100, 2, 32, 0, 1, 104, 21, 21, 2, 32, 0, 1, 107, 115, 10, 2, 32, 0, 2, 99, 117, 115, 32, 0, 1, 21, 2, 17, 67, 97, 116, 101, 32, 3, 8, 123, 0, 1, 104, 2, 32, 3, 8, 137, 0, 117, 1, 10, 2, 109, 3, 8, 141, 0, 4, 108, 2, 105, 115, 101, 3, 13, 55, 0, 108, 2, 105, 122, 101, 0, 108, 101, 1, 10, 2, 103, 101, 3, 13, 55, 122, 0, 98, 108, 121, 1, 21, 2, 32, 14, 128, 169, 132, 3, 13, 71, 55, 2, 122, 0, 98, 108, 101, 1, 21, 2, 32, 14, 128, 137, 132, 3, 13, 71, 118, 0, 122, 97, 5, 3, 2, 116, 105, 111, 110, 3, 13, 88, 138, 0, 4, 1, 98, 98, 2, 32, 3, 37, 0, 1, 104, 115, 2, 32, 0, 2, 32, 0, 100, 104, 2, 32, 0, 108, 121, 1, 10, 2, 32, 14, 128, 130, 130, 3, 55, 2, 122, 0, 4, 1, 21, 2, 99, 101, 32, 3, 113, 0, 1, 21, 2, 99, 101, 100, 32, 0, 1, 102, 2, 100, 101, 108, 0, 2, 111, 0, 2, 122, 101, 110, 0, 4, 99, 101, 1, 102, 102, 111, 3, 113, 89, 0, 99, 101, 1, 118, 114, 101, 115, 0, 4, 108, 1, 98, 21, 2, 32, 3, 118, 0, 108, 1, 99, 17, 67, 21, 2, 32, 0, 108, 1, 112, 21, 2, 32, 0, 108, 1, 114, 21, 2, 32, 0, 108, 1, 115, 21, 2, 32, 0, 108, 1, 116, 110, 2, 32, 0, 108, 1, 118, 21, 2, 32, 0, 4, 3, 122, 0, 1, 10, 2, 17, 67, 101, 110, 99, 0, 1, 10, 2, 17, 67, 101, 110, 116, 0, 1, 17, 67, 2, 120, 12, 12, 0, 1, 21, 2, 17, 67, 101, 114, 0, 1, 21, 2, 99, 101, 110, 99, 101, 0, 1, 21, 2, 108, 101, 115, 115, 0, 1, 21, 2, 110, 101, 115, 115, 0, 1, 99, 99, 97, 2, 100, 0, 1, 104, 99, 2, 108, 100, 114, 0, 1, 108, 2, 98, 101, 114, 0, 1, 108, 108, 101, 116, 110, 0, 1, 112, 117, 2, 100, 101, 0, 1, 114, 98, 2, 100, 103, 0, 1, 114, 105, 2, 100, 0, 1, 115, 115, 111, 103, 2, 112, 0, 1, 119, 2, 108, 100, 101, 114, 17, 67, 0, 2, 17, 66, 101, 101, 0, 2, 17, 66, 101, 108, 32, 0, 2, 17, 66, 101, 116, 32, 0, 2, 97, 110, 105, 32, 0, 2, 98, 105, 108, 105, 116, 0, 2, 100, 101, 111, 0, 2, 108, 101, 17, 65, 0, 8, 2, 100, 105, 0, 8, 108, 2, 17, 67, 121, 32, 0, 8, 112, 2, 116, 121, 32, 0, 112, 101, 100, 101, 3, 122, 48, 129, 72, 0, 99, 104, 8, 3, 122, 49, 0, 4, 108, 8, 2, 108, 110, 3, 122, 55, 0, 108, 8, 2, 108, 117, 115, 116, 0, 108, 101, 1, 114, 99, 97, 115, 3, 122, 55, 122, 0, 98, 101, 1, 116, 2, 116, 3, 122, 71, 6, 121, 0, 102, 101, 1, 110, 97, 109, 2, 115, 3, 122, 83, 121, 0, 102, 105, 101, 114, 2, 32, 3, 122, 83, 145, 0, 105, 2, 32, 3, 122, 137, 0, 4, 1, 17, 67, 29, 2, 17, 67, 97, 32, 3, 129, 0, 1, 17, 67, 29, 2, 17, 67, 111, 32, 0, 1, 102, 2, 106, 0, 2, 98, 111, 32, 0, 2, 113, 117, 32, 0, 5, 7, 2, 111, 0, 8, 108, 2, 98, 114, 101, 0, 122, 122, 8, 112, 3, 129, 47, 89, 0, 108, 108, 97, 114, 100, 1, 10, 2, 32, 3, 129, 126, 0, 4, 1, 10, 2, 122, 97, 98, 108, 3, 137, 0, 1, 17, 67, 2, 108, 101, 114, 0, 1, 17, 67, 29, 2, 17, 67, 101, 114, 32, 0, 1, 17, 67, 29, 2, 17, 67, 121, 32, 0, 1, 17, 67, 29, 2, 32, 0, 1, 21, 2, 17, 67, 105, 110, 103, 0, 1, 98, 2, 32, 0, 1, 98, 2, 98, 108, 101, 32, 0, 1, 99, 2, 32, 0, 1, 102, 2, 98, 114, 101, 0, 1, 104, 2, 106, 0, 1, 104, 99, 2, 108, 100, 0, 1, 108, 2, 98, 101, 108, 0, 1, 114, 2, 102, 108, 0, 1, 114, 98, 2, 100, 108, 0, 1, 114, 99, 115, 2, 98, 101, 114, 0, 1, 114, 102, 2, 100, 97, 121, 0, 1, 114, 112, 2, 99, 101, 0, 1, 115, 2, 108, 101, 110, 0, 1, 115, 2, 122, 17, 65, 0, 1, 116, 110, 101, 2, 99, 101, 0, 1, 116, 115, 2, 102, 108, 0, 1, 118, 2, 98, 114, 0, 1, 118, 100, 97, 2, 99, 101, 0, 1, 118, 101, 100, 2, 99, 101, 0, 2, 17, 66, 101, 13, 0, 2, 98, 101, 114, 32, 0, 2, 100, 101, 114, 12, 32, 0, 2, 100, 101, 114, 32, 12, 0, 8, 2, 17, 66, 111, 0, 8, 2, 17, 67, 121, 32, 0, 8, 2, 97, 0, 8, 2, 98, 0, 8, 2, 99, 0, 8, 2, 100, 0, 8, 2, 100, 108, 101, 0, 8, 2, 104, 0, 8, 2, 111, 0, 8, 17, 67, 2, 108, 97, 103, 101, 0, 8, 17, 67, 2, 108, 111, 0, 8, 108, 2, 98, 114, 0, 8, 109, 2, 108, 100, 0, 8, 115, 2, 100, 101, 114, 0, 8, 115, 2, 100, 108, 0, 8, 115, 2, 112, 104, 0, 8, 119, 2, 108, 100, 0, 104, 105, 1, 110, 3, 137, 13, 0, 108, 1, 108, 2, 97, 104, 32, 3, 137, 55, 0, 98, 97, 98, 1, 21, 3, 137, 71, 13, 71, 0, 100, 101, 97, 8, 3, 137, 72, 6, 141, 0, 4, 122, 2, 101, 114, 32, 3, 137, 88, 0, 122, 101, 2, 32, 0, 122, 101, 2, 100, 32, 0, 122, 97, 2, 116, 105, 111, 110, 3, 137, 88, 138, 0, 7, 6, 106, 0, 2, 106, 3, 0, 4, 1, 110, 2, 97, 32, 3, 57, 0, 2, 195, 188, 0, 4, 111, 107, 117, 108, 108, 2, 32, 14, 128, 128, 134, 3, 57, 128, 49, 134, 47, 107, 0, 195, 182, 107, 117, 108, 108, 2, 32, 14, 128, 128, 134, 0, 3, 75, 0, 97, 8, 2, 109, 97, 105, 3, 75, 119, 0, 101, 114, 101, 8, 2, 17, 67, 3, 75, 121, 34, 13, 0, 101, 115, 8, 2, 117, 105, 3, 75, 121, 88, 0, 111, 97, 8, 2, 110, 21, 3, 75, 136, 6, 35, 0, 117, 97, 110, 3, 107, 58, 126, 50, 0, 7, 6, 107, 0, 2, 107, 3, 0, 4, 3, 49, 0, 8, 2, 18, 66, 17, 71, 0, 8, 2, 104, 17, 71, 0, 8, 2, 119, 17, 71, 0, 105, 110, 101, 115, 105, 115, 3, 49, 13, 50, 6, 129, 89, 123, 89, 0, 106, 8, 2, 101, 21, 3, 49, 57, 0, 117, 97, 110, 3, 49, 58, 35, 50, 0, 105, 8, 2, 108, 17, 67, 21, 3, 49, 113, 0, 105, 8, 2, 108, 108, 21, 3, 49, 122, 0, 105, 108, 111, 8, 2, 21, 3, 49, 122, 55, 13, 0, 104, 97, 3, 49, 126, 0, 104, 97, 114, 3, 49, 127, 0, 117, 2, 99, 104, 3, 49, 134, 0, 117, 119, 97, 105, 116, 3, 49, 134, 58, 6, 138, 47, 0, 4, 110, 2, 105, 102, 3, 50, 0, 110, 2, 105, 116, 0, 110, 2, 105, 118, 0, 110, 2, 111, 98, 0, 110, 2, 111, 119, 0, 110, 8, 2, 17, 71, 0, 7, 6, 108, 0, 4, 1, 108, 3, 0, 1, 108, 17, 65, 2, 32, 3, 0, 111, 1, 21, 2, 103, 111, 117, 115, 3, 8, 55, 13, 0, 105, 110, 103, 1, 116, 10, 2, 32, 3, 10, 55, 122, 68, 0, 105, 110, 103, 1, 103, 110, 2, 32, 3, 14, 55, 122, 68, 0, 121, 1, 108, 21, 2, 32, 14, 128, 128, 130, 3, 37, 0, 4, 3, 55, 0, 1, 17, 65, 2, 108, 121, 32, 0, 1, 114, 2, 32, 0, 1, 119, 2, 32, 0, 2, 17, 67, 0, 2, 32, 0, 2, 69, 0, 8, 2, 104, 17, 71, 0, 108, 1, 17, 65, 0, 108, 1, 17, 65, 2, 17, 65, 0, 108, 1, 39, 17, 65, 0, 108, 1, 121, 0, 108, 2, 17, 67, 0, 108, 8, 2, 17, 71, 0, 108, 101, 2, 32, 0, 4, 121, 1, 21, 2, 32, 14, 128, 130, 130, 3, 55, 2, 37, 0, 121, 1, 102, 101, 105, 2, 32, 14, 128, 128, 130, 0, 121, 1, 102, 102, 2, 32, 14, 128, 128, 130, 0, 121, 1, 102, 111, 2, 32, 14, 128, 128, 130, 0, 121, 1, 111, 2, 32, 0, 121, 1, 112, 10, 2, 32, 14, 128, 128, 130, 0, 69, 115, 115, 1, 21, 2, 32, 14, 128, 130, 132, 3, 55, 13, 89, 0, 69, 115, 115, 108, 121, 1, 21, 2, 32, 14, 128, 130, 134, 3, 55, 13, 89, 55, 2, 37, 0, 106, 117, 8, 3, 55, 57, 134, 0, 121, 8, 2, 100, 3, 55, 122, 0, 105, 110, 117, 120, 3, 55, 122, 50, 125, 49, 89, 0, 105, 109, 1, 10, 2, 101, 110, 116, 3, 55, 122, 65, 0, 105, 110, 103, 1, 17, 66, 10, 2, 32, 3, 55, 122, 68, 0, 105, 110, 103, 115, 1, 17, 66, 10, 2, 32, 3, 55, 122, 68, 88, 0, 105, 115, 116, 101, 110, 3, 55, 122, 89, 13, 50, 0, 111, 5, 3, 8, 2, 103, 25, 3, 55, 131, 0, 117, 2, 110, 97, 3, 55, 134, 0, 4, 121, 1, 102, 2, 32, 3, 55, 137, 0, 121, 1, 112, 2, 32, 0, 121, 1, 112, 105, 116, 108, 117, 109, 0, 4, 108, 101, 100, 1, 21, 21, 2, 32, 14, 128, 136, 131, 3, 72, 0, 108, 101, 100, 1, 111, 21, 21, 2, 32, 14, 128, 136, 131, 0, 108, 97, 110, 8, 3, 105, 2, 35, 50, 0, 1, 17, 66, 2, 32, 3, 118, 0, 105, 110, 103, 1, 108, 10, 2, 32, 14, 128, 152, 132, 3, 122, 68, 0, 7, 6, 109, 0, 4, 1, 17, 66, 2, 32, 3, 13, 65, 0, 1, 104, 2, 32, 0, 110, 8, 2, 101, 3, 50, 0, 4, 3, 65, 0, 1, 108, 2, 32, 0, 98, 1, 111, 2, 101, 0, 98, 2, 32, 0, 98, 8, 111, 98, 2, 25, 0, 98, 8, 117, 100, 0, 109, 0, 110, 2, 32, 0, 101, 116, 97, 8, 2, 108, 108, 117, 3, 65, 2, 121, 47, 35, 0, 101, 1, 17, 66, 10, 2, 32, 3, 65, 2, 122, 0, 4, 97, 108, 8, 2, 102, 14, 128, 132, 131, 3, 65, 4, 35, 55, 0, 97, 108, 8, 2, 110, 14, 128, 132, 131, 0, 97, 108, 8, 2, 112, 14, 128, 132, 131, 0, 97, 108, 8, 2, 116, 114, 14, 128, 132, 131, 0, 101, 116, 97, 8, 2, 21, 3, 65, 4, 121, 47, 13, 0, 117, 108, 116, 105, 8, 2, 21, 21, 14, 128, 132, 133, 3, 65, 4, 125, 55, 47, 122, 0, 101, 1, 114, 111, 116, 2, 110, 116, 12, 3, 65, 6, 121, 0, 69, 110, 116, 97, 114, 121, 2, 32, 3, 65, 6, 121, 50, 47, 13, 34, 2, 122, 0, 101, 110, 116, 101, 100, 1, 17, 67, 3, 65, 6, 121, 50, 47, 122, 72, 0, 4, 99, 8, 2, 18, 70, 3, 65, 13, 0, 99, 8, 2, 32, 18, 70, 0, 111, 2, 110, 111, 116, 111, 0, 4, 97, 99, 8, 2, 97, 100, 14, 128, 132, 131, 3, 65, 13, 49, 0, 97, 99, 8, 2, 98, 14, 128, 132, 131, 0, 97, 99, 8, 2, 100, 14, 128, 132, 131, 0, 97, 99, 8, 2, 108, 14, 128, 132, 131, 0, 97, 99, 8, 2, 109, 14, 128, 132, 131, 0, 99, 8, 2, 17, 67, 0, 99, 8, 2, 32, 17, 67, 0, 111, 110, 2, 111, 112, 111, 108, 3, 65, 13, 50, 0, 111, 110, 111, 2, 103, 97, 3, 65, 13, 50, 6, 124, 0, 4, 69, 110, 116, 2, 32, 3, 65, 13, 50, 47, 0, 101, 110, 116, 1, 10, 2, 32, 14, 128, 128, 132, 0, 101, 110, 116, 1, 117, 2, 32, 0, 4, 101, 110, 116, 115, 1, 10, 2, 32, 14, 128, 128, 133, 3, 65, 13, 50, 47, 89, 0, 101, 110, 116, 115, 1, 117, 2, 32, 0, 4, 97, 108, 8, 2, 101, 118, 3, 65, 13, 55, 0, 97, 108, 8, 2, 105, 0, 111, 98, 105, 108, 101, 3, 65, 13, 71, 129, 55, 0, 111, 117, 116, 104, 1, 10, 2, 32, 3, 65, 13, 87, 0, 97, 8, 2, 109, 3, 65, 35, 0, 4, 99, 8, 2, 17, 65, 3, 65, 35, 49, 0, 99, 8, 2, 32, 17, 65, 0, 98, 108, 121, 3, 65, 71, 55, 2, 122, 0, 101, 116, 97, 98, 111, 3, 65, 121, 47, 6, 35, 71, 124, 0, 101, 116, 97, 108, 8, 2, 17, 67, 3, 65, 121, 47, 118, 0, 101, 110, 1, 21, 2, 32, 3, 65, 121, 50, 0, 101, 110, 116, 5, 8, 1, 10, 2, 32, 14, 128, 128, 132, 3, 65, 121, 50, 47, 0, 101, 110, 116, 115, 5, 8, 1, 10, 2, 32, 14, 128, 128, 133, 3, 65, 121, 50, 47, 89, 0, 101, 103, 97, 8, 3, 65, 121, 81, 13, 0, 111, 110, 2, 111, 120, 3, 65, 124, 50, 0, 111, 110, 111, 8, 3, 65, 124, 50, 136, 0, 117, 108, 116, 105, 8, 3, 65, 125, 55, 47, 122, 0, 111, 98, 105, 108, 101, 8, 3, 65, 136, 71, 137, 55, 0, 111, 115, 116, 1, 21, 2, 32, 14, 128, 128, 132, 3, 65, 136, 89, 47, 0, 97, 121, 111, 114, 5, 35, 3, 65, 140, 0, 7, 6, 110, 0, 4, 1, 110, 3, 0, 4, 1, 110, 2, 32, 3, 0, 4, 100, 1, 32, 50, 2, 32, 3, 0, 101, 1, 110, 10, 2, 32, 3, 0, 2, 17, 67, 111, 32, 3, 8, 50, 0, 4, 1, 17, 66, 2, 32, 3, 13, 50, 0, 1, 69, 2, 32, 0, 8, 2, 103, 17, 71, 12, 3, 14, 68, 0, 4, 3, 50, 0, 1, 21, 2, 99, 104, 0, 1, 97, 105, 10, 2, 32, 14, 128, 128, 129, 0, 1, 103, 2, 32, 0, 1, 103, 2, 105, 110, 103, 12, 0, 1, 108, 2, 32, 0, 2, 107, 110, 0, 101, 1, 17, 66, 10, 2, 32, 3, 50, 2, 122, 0, 97, 110, 111, 8, 2, 14, 128, 132, 132, 3, 50, 4, 35, 50, 136, 0, 111, 110, 8, 2, 21, 14, 128, 132, 131, 3, 50, 4, 124, 50, 0, 101, 119, 115, 8, 2, 14, 128, 132, 132, 3, 50, 6, 57, 134, 88, 0, 101, 119, 115, 5, 3, 8, 2, 14, 128, 132, 132, 3, 50, 6, 134, 88, 0, 101, 115, 115, 1, 10, 2, 32, 14, 128, 130, 132, 3, 50, 13, 89, 0, 101, 99, 101, 115, 115, 105, 116, 3, 50, 13, 89, 121, 89, 122, 47, 0, 39, 116, 3, 50, 47, 0, 107, 5, 7, 3, 50, 49, 0, 115, 1, 97, 105, 10, 2, 32, 14, 128, 128, 130, 3, 50, 88, 0, 101, 115, 115, 5, 8, 1, 10, 2, 32, 14, 128, 130, 132, 3, 50, 121, 89, 0, 111, 110, 99, 104, 97, 108, 97, 5, 3, 2, 110, 3, 50, 124, 50, 91, 13, 55, 6, 126, 0, 111, 110, 99, 104, 97, 108, 97, 2, 110, 3, 50, 124, 50, 91, 13, 55, 13, 0, 117, 114, 115, 101, 8, 2, 17, 66, 3, 50, 128, 89, 0, 101, 111, 8, 3, 50, 129, 136, 0, 97, 117, 115, 101, 3, 50, 130, 89, 122, 0, 105, 110, 116, 104, 3, 50, 137, 50, 87, 0, 97, 109, 101, 1, 10, 2, 32, 14, 128, 128, 132, 3, 50, 138, 65, 0, 4, 1, 21, 2, 99, 17, 67, 3, 68, 0, 2, 99, 32, 0, 2, 120, 0, 103, 0, 107, 3, 68, 49, 0, 7, 6, 111, 0, 4, 2, 98, 106, 101, 3, 2, 124, 0, 2, 98, 108, 105, 103, 97, 116, 111, 0, 8, 2, 98, 108, 0, 8, 2, 98, 115, 0, 8, 2, 98, 116, 0, 112, 112, 111, 114, 2, 116, 117, 3, 2, 124, 48, 114, 0, 98, 115, 8, 2, 101, 114, 3, 2, 124, 71, 88, 0, 4, 1, 99, 2, 105, 110, 99, 105, 3, 2, 136, 0, 1, 100, 2, 100, 101, 99, 0, 1, 108, 2, 99, 97, 116, 0, 8, 2, 98, 101, 115, 0, 39, 8, 2, 14, 128, 132, 130, 0, 1, 108, 2, 99, 111, 109, 3, 4, 136, 0, 101, 2, 118, 101, 3, 4, 136, 6, 121, 0, 4, 2, 17, 67, 105, 99, 32, 3, 6, 124, 0, 2, 17, 67, 105, 99, 97, 108, 0, 2, 103, 101, 110, 111, 117, 115, 0, 2, 103, 101, 110, 121, 0, 116, 114, 111, 2, 112, 121, 3, 6, 124, 47, 34, 13, 0, 112, 111, 108, 1, 21, 2, 18, 67, 3, 6, 124, 48, 13, 55, 0, 99, 114, 97, 116, 101, 115, 2, 32, 3, 6, 124, 49, 34, 119, 47, 129, 88, 0, 120, 2, 105, 100, 101, 3, 6, 124, 49, 89, 0, 109, 101, 116, 101, 114, 1, 21, 3, 6, 124, 65, 122, 47, 114, 0, 103, 114, 97, 112, 104, 101, 114, 1, 21, 3, 6, 124, 81, 34, 13, 83, 114, 0, 112, 104, 97, 1, 99, 114, 2, 103, 3, 6, 124, 83, 13, 0, 4, 1, 116, 115, 117, 99, 2, 100, 105, 3, 6, 136, 0, 2, 17, 66, 97, 32, 0, 2, 17, 66, 101, 111, 110, 0, 2, 17, 66, 105, 17, 65, 0, 2, 17, 67, 105, 32, 0, 2, 17, 67, 111, 32, 0, 2, 17, 67, 111, 105, 115, 116, 0, 2, 98, 105, 99, 32, 0, 2, 99, 114, 101, 32, 0, 97, 2, 32, 3, 6, 136, 13, 0, 4, 105, 2, 110, 97, 32, 3, 6, 139, 0, 121, 2, 17, 65, 32, 0, 101, 97, 2, 32, 3, 6, 141, 0, 4, 1, 10, 2, 112, 104, 101, 114, 3, 8, 13, 0, 2, 99, 121, 116, 101, 32, 0, 103, 1, 108, 21, 2, 121, 3, 8, 13, 75, 0, 103, 105, 115, 109, 1, 108, 3, 8, 13, 75, 122, 88, 13, 65, 0, 112, 104, 101, 1, 10, 2, 32, 3, 8, 13, 83, 2, 122, 0, 1, 17, 67, 21, 21, 2, 32, 3, 8, 136, 0, 4, 1, 10, 2, 103, 101, 110, 32, 3, 13, 0, 1, 10, 2, 112, 32, 0, 1, 102, 102, 2, 99, 17, 65, 0, 1, 104, 115, 105, 98, 2, 112, 0, 1, 104, 116, 101, 109, 2, 100, 32, 0, 1, 105, 114, 101, 112, 2, 100, 32, 0, 1, 109, 2, 120, 0, 1, 109, 109, 2, 100, 111, 114, 0, 1, 112, 2, 116, 101, 110, 116, 105, 0, 1, 115, 2, 112, 104, 105, 115, 116, 105, 99, 0, 1, 116, 2, 98, 97, 99, 99, 0, 1, 116, 115, 117, 99, 2, 100, 0, 1, 118, 105, 112, 2, 116, 0, 2, 99, 99, 97, 115, 105, 0, 2, 99, 99, 108, 117, 0, 2, 102, 102, 105, 99, 105, 0, 2, 112, 105, 110, 105, 0, 102, 2, 102, 101, 110, 0, 4, 116, 1, 103, 10, 2, 32, 3, 13, 47, 0, 116, 1, 114, 114, 2, 32, 0, 112, 112, 2, 114, 101, 115, 3, 13, 48, 0, 112, 111, 108, 105, 116, 97, 110, 3, 13, 48, 6, 124, 55, 122, 47, 13, 50, 0, 112, 101, 100, 1, 10, 2, 32, 3, 13, 48, 72, 0, 99, 107, 1, 17, 67, 11, 10, 2, 32, 3, 13, 49, 0, 4, 99, 99, 117, 114, 3, 13, 49, 128, 0, 99, 99, 117, 114, 114, 0, 4, 99, 99, 117, 114, 5, 5, 3, 13, 49, 148, 0, 99, 99, 117, 114, 114, 5, 5, 0, 105, 120, 2, 32, 3, 58, 35, 0, 105, 115, 1, 21, 2, 32, 3, 58, 126, 0, 4, 105, 114, 3, 58, 127, 0, 105, 114, 101, 0, 101, 1, 10, 2, 115, 32, 14, 128, 128, 130, 3, 88, 0, 101, 115, 111, 112, 104, 97, 3, 113, 89, 124, 83, 13, 0, 4, 3, 124, 0, 1, 98, 2, 116, 104, 101, 114, 0, 1, 104, 2, 112, 32, 0, 1, 108, 102, 2, 112, 32, 0, 1, 109, 2, 100, 101, 108, 0, 1, 109, 2, 100, 101, 114, 0, 1, 109, 2, 100, 101, 115, 116, 0, 1, 112, 2, 112, 32, 0, 1, 114, 2, 103, 101, 114, 0, 1, 114, 2, 112, 32, 0, 1, 114, 112, 2, 112, 101, 0, 1, 116, 2, 112, 32, 0, 2, 17, 66, 101, 17, 67, 111, 32, 0, 2, 17, 67, 101, 109, 105, 99, 0, 2, 17, 67, 101, 116, 32, 0, 2, 98, 108, 105, 103, 97, 0, 2, 98, 108, 111, 0, 2, 98, 115, 116, 105, 110, 0, 2, 102, 102, 105, 99, 0, 2, 120, 12, 12, 0, 8, 2, 17, 67, 121, 12, 0, 8, 2, 112, 101, 114, 0, 8, 98, 2, 100, 121, 0, 8, 114, 2, 98, 101, 114, 0, 8, 114, 2, 116, 104, 101, 114, 0, 104, 1, 106, 2, 110, 0, 116, 121, 108, 101, 1, 99, 3, 124, 47, 122, 55, 6, 129, 0, 120, 121, 3, 124, 49, 89, 122, 0, 98, 115, 111, 2, 108, 3, 124, 71, 89, 13, 0, 4, 103, 101, 1, 108, 21, 2, 32, 3, 124, 81, 0, 103, 117, 101, 1, 21, 21, 0, 4, 1, 100, 2, 122, 101, 110, 3, 125, 0, 1, 116, 2, 110, 103, 117, 0, 2, 116, 104, 101, 114, 12, 0, 4, 101, 1, 102, 2, 116, 17, 65, 3, 129, 0, 101, 8, 2, 100, 0, 101, 8, 2, 115, 0, 97, 1, 114, 98, 2, 100, 3, 130, 0, 4, 5, 3, 1, 10, 2, 102, 102, 3, 131, 0, 5, 3, 1, 99, 2, 102, 102, 0, 5, 3, 1, 103, 2, 110, 103, 0, 5, 3, 1, 108, 99, 2, 116, 104, 0, 5, 3, 1, 109, 2, 116, 104, 0, 5, 3, 1, 114, 2, 110, 103, 0, 5, 3, 1, 115, 2, 110, 103, 0, 5, 3, 2, 102, 116, 0, 5, 3, 8, 2, 102, 102, 0, 4, 39, 101, 114, 3, 133, 0, 97, 114, 0, 97, 114, 2, 32, 0, 4, 1, 100, 2, 105, 110, 103, 3, 134, 0, 101, 1, 104, 115, 2, 12, 0, 4, 1, 17, 67, 29, 2, 17, 66, 97, 108, 3, 136, 0, 1, 17, 67, 29, 2, 17, 66, 117, 115, 32, 0, 1, 21, 2, 105, 115, 116, 0, 1, 29, 2, 17, 66, 121, 32, 0, 1, 29, 2, 112, 104, 101, 114, 0, 1, 98, 2, 116, 104, 0, 1, 99, 2, 116, 97, 110, 0, 1, 100, 2, 99, 105, 108, 0, 1, 102, 2, 99, 17, 65, 0, 1, 103, 105, 2, 32, 0, 1, 107, 2, 100, 17, 65, 0, 1, 109, 2, 116, 105, 118, 0, 1, 110, 2, 98, 105, 108, 0, 1, 110, 2, 98, 108, 0, 1, 110, 2, 116, 97, 0, 1, 110, 2, 116, 111, 114, 0, 1, 114, 2, 116, 97, 0, 1, 114, 2, 116, 111, 0, 1, 114, 99, 2, 97, 116, 0, 1, 114, 99, 2, 99, 117, 0, 1, 114, 112, 112, 97, 2, 112, 0, 1, 116, 2, 116, 97, 0, 2, 17, 66, 101, 13, 0, 2, 17, 66, 101, 110, 17, 67, 0, 2, 17, 66, 105, 110, 103, 0, 2, 17, 67, 97, 103, 104, 32, 0, 2, 32, 0, 2, 98, 97, 0, 2, 98, 101, 100, 0, 2, 98, 121, 32, 0, 2, 100, 97, 32, 0, 2, 103, 97, 110, 32, 0, 2, 104, 17, 65, 0, 2, 105, 110, 103, 0, 2, 105, 115, 109, 0, 2, 107, 121, 32, 0, 2, 115, 104, 17, 65, 32, 0, 2, 116, 97, 116, 0, 2, 116, 105, 111, 110, 0, 8, 2, 17, 66, 97, 108, 0, 8, 2, 122, 111, 0, 8, 17, 67, 2, 116, 105, 0, 8, 104, 2, 99, 117, 0, 8, 108, 2, 99, 17, 65, 0, 8, 109, 2, 98, 105, 108, 0, 8, 114, 2, 98, 111, 0, 8, 118, 2, 99, 17, 65, 0, 97, 0, 101, 0, 104, 0, 101, 114, 3, 136, 13, 0, 116, 105, 99, 1, 110, 2, 17, 65, 3, 136, 47, 113, 89, 0, 116, 111, 114, 1, 109, 3, 136, 47, 114, 0, 116, 111, 1, 114, 112, 2, 110, 3, 136, 47, 124, 0, 116, 111, 1, 114, 112, 3, 136, 47, 136, 0, 4, 112, 101, 1, 110, 117, 2, 110, 3, 136, 48, 13, 0, 112, 101, 8, 2, 110, 0, 112, 101, 100, 1, 99, 2, 32, 3, 136, 48, 72, 0, 99, 104, 1, 114, 116, 3, 136, 49, 0, 100, 111, 2, 114, 17, 65, 3, 136, 72, 13, 0, 4, 100, 111, 114, 3, 136, 72, 114, 0, 100, 111, 117, 114, 0, 103, 101, 110, 105, 2, 99, 3, 136, 75, 6, 121, 50, 122, 0, 4, 103, 8, 2, 114, 101, 3, 136, 81, 0, 103, 117, 101, 1, 114, 0, 103, 117, 101, 1, 118, 0, 4, 116, 104, 1, 108, 2, 105, 3, 136, 86, 0, 116, 104, 1, 108, 2, 105, 97, 110, 0, 116, 104, 1, 114, 116, 101, 98, 0, 116, 104, 101, 1, 108, 99, 0, 116, 104, 101, 1, 114, 116, 0, 105, 2, 99, 3, 136, 113, 0, 101, 1, 112, 2, 116, 105, 3, 136, 121, 0, 4, 101, 1, 112, 2, 109, 3, 136, 122, 0, 101, 1, 112, 2, 116, 0, 4, 105, 3, 139, 0, 105, 2, 99, 101, 0, 105, 2, 99, 101, 13, 0, 105, 2, 99, 107, 0, 121, 0, 105, 97, 3, 139, 13, 0, 7, 6, 112, 0, 4, 1, 115, 97, 114, 2, 98, 3, 0, 2, 112, 3, 0, 104, 111, 110, 121, 1, 10, 2, 32, 3, 8, 83, 13, 50, 122, 0, 4, 116, 1, 105, 101, 3, 47, 0, 116, 8, 2, 17, 71, 0, 4, 3, 48, 0, 2, 104, 97, 122, 97, 0, 2, 104, 111, 108, 101, 0, 8, 2, 18, 66, 17, 71, 0, 104, 2, 97, 109, 32, 0, 104, 2, 101, 114, 100, 0, 111, 114, 2, 116, 114, 97, 121, 3, 48, 2, 133, 0, 111, 108, 121, 2, 21, 21, 3, 48, 4, 124, 55, 122, 0, 121, 114, 111, 8, 2, 21, 21, 14, 128, 132, 132, 3, 48, 4, 137, 34, 136, 0, 97, 108, 101, 111, 8, 2, 21, 14, 128, 132, 133, 3, 48, 4, 138, 55, 129, 136, 0, 97, 1, 109, 121, 115, 3, 48, 13, 0, 111, 116, 97, 2, 116, 3, 48, 13, 47, 138, 0, 121, 111, 110, 3, 48, 57, 124, 50, 0, 117, 114, 8, 2, 115, 117, 3, 48, 114, 0, 117, 116, 2, 32, 3, 48, 117, 47, 0, 111, 108, 121, 2, 21, 3, 48, 124, 55, 122, 0, 117, 116, 1, 115, 2, 32, 3, 48, 125, 47, 0, 105, 99, 111, 8, 3, 48, 129, 49, 136, 0, 105, 101, 99, 101, 2, 32, 14, 128, 128, 133, 3, 48, 129, 89, 0, 121, 114, 111, 109, 2, 101, 3, 48, 137, 34, 6, 124, 65, 0, 110, 8, 2, 101, 117, 3, 50, 0, 110, 101, 117, 3, 50, 57, 134, 0, 4, 102, 8, 2, 17, 71, 3, 83, 0, 104, 0, 104, 8, 2, 17, 71, 0, 104, 8, 2, 18, 66, 17, 71, 0, 104, 101, 110, 121, 108, 3, 83, 4, 129, 50, 137, 55, 0, 104, 111, 116, 111, 8, 2, 21, 21, 14, 128, 132, 133, 3, 83, 4, 136, 47, 136, 0, 104, 121, 99, 111, 8, 3, 83, 4, 137, 49, 136, 0, 104, 116, 104, 8, 2, 17, 65, 3, 83, 87, 0, 104, 101, 110, 111, 109, 101, 2, 110, 3, 83, 113, 50, 124, 65, 122, 0, 104, 105, 108, 97, 3, 83, 122, 55, 35, 0, 4, 104, 111, 116, 2, 111, 103, 114, 97, 112, 104, 12, 3, 83, 136, 47, 0, 104, 111, 116, 8, 2, 111, 18, 75, 12, 12, 0, 104, 111, 116, 111, 99, 111, 112, 3, 83, 136, 47, 13, 49, 124, 48, 0, 104, 111, 116, 111, 110, 3, 83, 136, 47, 124, 50, 0, 104, 111, 116, 111, 3, 83, 136, 47, 136, 0, 115, 8, 2, 17, 71, 3, 89, 0, 115, 121, 99, 104, 111, 2, 108, 111, 3, 89, 2, 137, 49, 124, 0, 115, 101, 117, 100, 111, 3, 89, 134, 72, 136, 0, 115, 121, 99, 104, 3, 89, 137, 49, 0, 115, 121, 99, 104, 111, 3, 89, 137, 49, 136, 0, 7, 6, 113, 0, 2, 113, 3, 0, 4, 3, 49, 0, 117, 1, 99, 97, 106, 0, 117, 2, 32, 0, 117, 2, 101, 114, 32, 0, 117, 101, 1, 21, 2, 32, 0, 117, 101, 1, 101, 104, 99, 0, 117, 101, 116, 116, 3, 49, 6, 121, 47, 0, 117, 105, 1, 115, 101, 109, 2, 116, 3, 49, 6, 129, 0, 117, 101, 117, 3, 49, 57, 134, 0, 117, 3, 49, 58, 0, 117, 2, 17, 67, 3, 49, 58, 13, 0, 117, 101, 8, 2, 32, 3, 49, 58, 121, 0, 117, 101, 115, 116, 3, 49, 58, 121, 89, 47, 0, 117, 121, 3, 49, 58, 122, 0, 117, 97, 1, 115, 2, 17, 66, 3, 49, 58, 124, 0, 117, 97, 115, 2, 17, 65, 3, 49, 58, 138, 88, 0, 117, 97, 115, 105, 3, 49, 58, 138, 88, 137, 0, 117, 101, 116, 1, 97, 114, 3, 49, 113, 47, 0, 117, 111, 114, 1, 105, 108, 3, 49, 114, 0, 117, 97, 121, 3, 49, 129, 0, 117, 101, 116, 2, 32, 3, 49, 138, 0, 7, 6, 114, 0, 4, 1, 114, 2, 32, 3, 0, 100, 1, 32, 51, 2, 32, 3, 0, 109, 8, 3, 4, 127, 121, 65, 0, 1, 21, 2, 17, 66, 3, 13, 0, 4, 3, 34, 0, 104, 1, 17, 67, 0, 104, 8, 2, 17, 71, 0, 114, 0, 119, 8, 2, 97, 3, 34, 2, 117, 0, 121, 1, 116, 110, 97, 10, 2, 32, 14, 128, 128, 130, 3, 34, 2, 122, 0, 4, 114, 104, 101, 97, 3, 34, 6, 141, 0, 114, 104, 111, 101, 97, 0, 1, 17, 67, 2, 32, 24, 3, 34, 13, 0, 69, 114, 2, 32, 3, 34, 114, 0, 104, 121, 116, 104, 3, 34, 122, 86, 0, 4, 117, 110, 8, 2, 97, 3, 34, 125, 50, 0, 117, 110, 8, 2, 111, 0, 4, 104, 101, 117, 3, 34, 134, 0, 117, 8, 2, 98, 18, 66, 0, 4, 104, 111, 8, 2, 100, 3, 34, 136, 0, 104, 111, 8, 2, 116, 0, 104, 111, 100, 111, 8, 2, 21, 3, 34, 136, 72, 13, 0, 4, 104, 105, 2, 110, 3, 34, 137, 0, 104, 105, 2, 122, 0, 1, 101, 2, 32, 3, 114, 0, 7, 6, 115, 0, 4, 2, 99, 105, 111, 117, 115, 3, 0, 4, 2, 115, 3, 0, 116, 1, 32, 49, 2, 32, 3, 0, 104, 101, 39, 8, 3, 2, 91, 129, 0, 101, 108, 102, 2, 32, 3, 6, 89, 121, 55, 83, 0, 101, 108, 118, 101, 115, 2, 32, 3, 6, 89, 121, 55, 84, 88, 0, 105, 97, 2, 32, 3, 8, 88, 141, 0, 99, 111, 112, 121, 1, 21, 2, 32, 3, 8, 89, 49, 13, 48, 2, 122, 0, 99, 105, 115, 2, 32, 3, 8, 89, 49, 122, 89, 0, 99, 105, 2, 32, 3, 8, 89, 49, 137, 0, 105, 97, 1, 17, 67, 2, 32, 3, 8, 89, 141, 0, 105, 97, 5, 3, 2, 32, 3, 8, 90, 13, 0, 115, 105, 111, 110, 3, 8, 91, 13, 50, 0, 115, 105, 111, 110, 5, 8, 2, 32, 3, 8, 91, 125, 50, 0, 105, 97, 110, 1, 21, 2, 32, 14, 128, 128, 129, 3, 50, 0, 4, 1, 10, 2, 105, 99, 32, 3, 88, 0, 1, 17, 65, 2, 105, 116, 105, 118, 0, 1, 21, 2, 32, 14, 128, 128, 129, 0, 1, 32, 15, 2, 32, 0, 1, 32, 54, 49, 2, 32, 0, 1, 39, 32, 15, 2, 32, 0, 1, 97, 2, 101, 108, 32, 0, 1, 97, 2, 109, 0, 1, 97, 101, 2, 105, 101, 0, 1, 97, 101, 2, 105, 108, 0, 1, 97, 101, 2, 121, 0, 1, 97, 101, 108, 112, 2, 101, 0, 1, 97, 101, 112, 2, 101, 0, 1, 97, 101, 116, 2, 101, 0, 1, 97, 104, 112, 2, 101, 0, 1, 97, 108, 2, 101, 0, 1, 97, 109, 2, 101, 0, 1, 97, 112, 2, 101, 0, 1, 97, 114, 2, 101, 0, 1, 103, 110, 2, 32, 14, 128, 128, 129, 0, 1, 105, 17, 65, 2, 121, 0, 1, 105, 97, 2, 101, 0, 1, 105, 114, 112, 2, 111, 0, 1, 109, 2, 105, 0, 1, 109, 2, 121, 0, 1, 110, 2, 32, 14, 128, 128, 129, 0, 1, 111, 2, 109, 0, 1, 111, 17, 67, 2, 69, 110, 0, 1, 111, 17, 67, 2, 69, 114, 0, 1, 114, 2, 100, 0, 1, 117, 109, 2, 105, 99, 0, 2, 32, 0, 8, 97, 101, 2, 101, 0, 8, 97, 104, 2, 32, 0, 8, 101, 114, 2, 111, 0, 8, 105, 111, 17, 67, 2, 101, 0, 101, 1, 105, 117, 2, 32, 0, 101, 1, 111, 2, 32, 0, 101, 1, 111, 100, 2, 32, 0, 101, 1, 111, 111, 104, 99, 0, 101, 1, 111, 116, 2, 32, 0, 101, 1, 117, 97, 2, 32, 0, 101, 1, 117, 102, 2, 32, 0, 101, 1, 119, 0, 4, 105, 110, 1, 105, 97, 2, 32, 3, 88, 13, 50, 0, 105, 110, 1, 117, 2, 32, 0, 105, 98, 1, 17, 65, 3, 88, 13, 71, 0, 4, 3, 89, 0, 1, 21, 2, 104, 101, 97, 100, 32, 0, 1, 21, 2, 104, 105, 108, 108, 32, 0, 1, 21, 2, 104, 111, 117, 115, 0, 1, 97, 2, 101, 0, 1, 99, 2, 32, 0, 1, 99, 10, 2, 32, 14, 128, 128, 129, 0, 1, 101, 112, 10, 2, 32, 14, 128, 128, 129, 0, 1, 101, 116, 2, 32, 14, 128, 128, 129, 0, 1, 102, 2, 32, 0, 1, 102, 10, 2, 32, 14, 128, 128, 129, 0, 1, 104, 116, 2, 32, 0, 1, 104, 116, 10, 2, 32, 14, 128, 128, 129, 0, 1, 105, 114, 2, 32, 14, 128, 128, 129, 0, 1, 107, 2, 32, 0, 1, 107, 10, 2, 32, 14, 128, 128, 129, 0, 1, 112, 2, 32, 0, 1, 112, 10, 2, 32, 14, 128, 128, 129, 0, 1, 116, 2, 32, 14, 128, 128, 129, 0, 1, 116, 10, 2, 32, 14, 128, 128, 129, 0, 2, 115, 104, 0, 5, 3, 1, 101, 114, 2, 111, 117, 114, 0, 8, 2, 99, 17, 71, 0, 8, 2, 99, 18, 66, 17, 71, 0, 8, 2, 107, 17, 71, 0, 8, 2, 107, 18, 66, 17, 71, 0, 8, 2, 108, 17, 71, 0, 8, 2, 109, 17, 71, 0, 8, 2, 110, 17, 71, 0, 8, 2, 112, 17, 71, 0, 8, 2, 112, 18, 66, 17, 71, 0, 8, 2, 112, 104, 17, 71, 0, 8, 2, 113, 117, 0, 8, 2, 114, 105, 0, 8, 2, 116, 17, 71, 0, 8, 2, 116, 114, 17, 71, 0, 8, 2, 117, 0, 8, 2, 118, 97, 0, 8, 2, 118, 101, 0, 8, 2, 119, 17, 71, 0, 8, 2, 122, 17, 71, 0, 8, 17, 65, 17, 66, 2, 32, 0, 8, 105, 109, 2, 104, 0, 99, 1, 117, 109, 2, 108, 0, 99, 2, 18, 67, 0, 101, 1, 111, 111, 2, 32, 0, 115, 1, 111, 114, 99, 2, 104, 0, 115, 2, 32, 0, 115, 101, 2, 32, 0, 101, 109, 105, 8, 2, 21, 21, 14, 128, 132, 132, 3, 89, 4, 121, 65, 113, 0, 99, 105, 2, 98, 3, 89, 13, 0, 105, 110, 1, 97, 2, 32, 3, 89, 13, 50, 0, 116, 8, 2, 32, 3, 89, 13, 50, 47, 0, 111, 109, 97, 8, 2, 108, 105, 3, 89, 13, 65, 126, 0, 105, 98, 1, 10, 3, 89, 13, 71, 0, 111, 99, 105, 101, 8, 2, 116, 3, 89, 13, 89, 144, 0, 116, 101, 105, 110, 3, 89, 47, 137, 50, 0, 116, 97, 116, 101, 8, 2, 21, 3, 89, 47, 138, 47, 0, 4, 99, 2, 101, 112, 116, 3, 89, 49, 0, 99, 104, 2, 111, 0, 99, 104, 5, 3, 2, 101, 100, 0, 99, 104, 8, 2, 105, 115, 109, 0, 99, 97, 114, 8, 2, 97, 3, 89, 49, 35, 34, 0, 99, 104, 105, 122, 8, 3, 89, 49, 122, 47, 89, 0, 99, 104, 101, 2, 109, 3, 89, 49, 129, 0, 99, 97, 114, 8, 2, 17, 65, 3, 89, 49, 140, 0, 99, 97, 114, 99, 3, 89, 49, 140, 89, 0, 101, 8, 2, 99, 108, 117, 3, 89, 113, 0, 101, 99, 117, 114, 3, 89, 113, 49, 57, 143, 0, 101, 109, 105, 110, 8, 3, 89, 121, 65, 122, 50, 0, 121, 2, 110, 101, 114, 103, 3, 89, 122, 0, 111, 109, 101, 1, 21, 2, 32, 14, 128, 128, 132, 3, 89, 125, 65, 0, 111, 109, 101, 1, 111, 21, 21, 2, 32, 14, 128, 128, 132, 3, 89, 136, 65, 0, 105, 122, 101, 8, 2, 17, 67, 21, 3, 89, 137, 88, 0, 4, 105, 111, 110, 1, 17, 65, 3, 90, 13, 50, 0, 105, 111, 110, 5, 3, 1, 114, 101, 0, 105, 111, 110, 5, 8, 1, 17, 65, 3, 90, 125, 50, 0, 4, 99, 104, 2, 17, 67, 3, 91, 0, 99, 104, 2, 32, 0, 99, 104, 8, 0, 99, 104, 8, 2, 105, 108, 0, 99, 104, 8, 101, 0, 104, 0, 104, 8, 2, 17, 71, 0, 104, 8, 2, 18, 66, 17, 71, 0, 115, 2, 117, 101, 0, 115, 117, 114, 101, 1, 97, 3, 91, 6, 143, 0, 4, 104, 105, 114, 101, 1, 10, 2, 32, 14, 128, 128, 133, 3, 91, 13, 0, 115, 105, 97, 2, 32, 0, 105, 111, 110, 1, 17, 67, 3, 91, 13, 50, 0, 115, 117, 114, 3, 91, 114, 0, 104, 105, 112, 1, 10, 2, 32, 14, 128, 128, 132, 3, 91, 122, 48, 0, 104, 105, 112, 115, 1, 10, 2, 32, 14, 128, 128, 133, 3, 91, 122, 48, 89, 0, 105, 111, 110, 5, 8, 1, 17, 67, 3, 91, 125, 50, 0, 195, 173, 111, 8, 3, 91, 129, 0, 115, 117, 101, 1, 105, 116, 3, 91, 134, 0, 104, 105, 114, 101, 5, 3, 1, 10, 2, 32, 14, 128, 128, 133, 3, 91, 141, 0, 115, 117, 114, 1, 97, 3, 91, 143, 0, 1, 32, 54, 2, 32, 3, 113, 88, 0, 8, 2, 32, 3, 121, 89, 0, 4, 1, 101, 99, 21, 2, 32, 14, 128, 128, 129, 3, 123, 88, 0, 1, 101, 115, 10, 2, 32, 14, 128, 128, 129, 0, 1, 101, 115, 115, 10, 2, 32, 14, 128, 128, 130, 0, 7, 6, 116, 0, 4, 1, 115, 2, 108, 3, 0, 1, 116, 3, 0, 105, 118, 101, 1, 17, 67, 17, 65, 2, 32, 3, 8, 47, 122, 84, 0, 117, 1, 21, 2, 108, 97, 116, 101, 3, 8, 76, 117, 0, 117, 1, 99, 2, 97, 108, 32, 3, 8, 76, 134, 0, 4, 3, 47, 0, 1, 105, 112, 2, 105, 97, 0, 1, 115, 105, 2, 105, 97, 110, 12, 0, 8, 2, 114, 17, 71, 0, 8, 2, 115, 17, 71, 0, 8, 2, 119, 17, 71, 0, 115, 107, 8, 3, 47, 6, 13, 89, 49, 0, 4, 111, 2, 109, 111, 114, 114, 3, 47, 13, 0, 116, 117, 2, 114, 0, 4, 114, 105, 8, 2, 98, 117, 3, 47, 34, 122, 0, 114, 105, 8, 2, 103, 0, 114, 105, 8, 2, 110, 105, 0, 114, 105, 8, 2, 118, 105, 0, 114, 105, 8, 2, 120, 17, 65, 0, 4, 114, 105, 8, 2, 17, 65, 3, 47, 34, 137, 0, 114, 105, 8, 2, 17, 67, 17, 65, 0, 114, 105, 8, 2, 17, 67, 121, 0, 114, 105, 101, 8, 0, 114, 105, 98, 101, 3, 47, 34, 137, 71, 0, 105, 97, 110, 8, 3, 47, 57, 35, 50, 0, 105, 97, 108, 1, 115, 10, 3, 47, 57, 118, 0, 4, 122, 3, 47, 89, 0, 122, 8, 2, 97, 114, 0, 4, 115, 101, 2, 32, 3, 47, 89, 37, 0, 122, 101, 2, 32, 0, 115, 117, 8, 3, 47, 89, 134, 0, 101, 114, 97, 8, 3, 47, 121, 34, 13, 0, 101, 108, 101, 8, 3, 47, 121, 55, 113, 0, 111, 8, 2, 110, 110, 3, 47, 125, 0, 119, 111, 8, 3, 47, 134, 0, 111, 119, 110, 1, 21, 2, 32, 14, 128, 128, 132, 3, 47, 135, 50, 0, 4, 99, 104, 3, 76, 0, 115, 99, 104, 0, 117, 114, 1, 21, 2, 97, 108, 32, 3, 76, 8, 13, 34, 0, 105, 97, 1, 115, 10, 2, 32, 3, 76, 13, 0, 4, 117, 114, 1, 21, 2, 17, 65, 3, 76, 13, 34, 0, 117, 114, 1, 21, 2, 121, 0, 105, 111, 110, 1, 115, 10, 3, 76, 13, 50, 0, 4, 117, 114, 1, 21, 2, 32, 3, 76, 114, 0, 117, 114, 101, 2, 32, 0, 105, 111, 110, 5, 8, 1, 115, 10, 3, 76, 125, 50, 0, 4, 117, 1, 21, 2, 97, 108, 3, 76, 134, 0, 117, 8, 97, 116, 115, 0, 103, 97, 1, 114, 2, 103, 3, 81, 122, 0, 1, 21, 2, 105, 97, 3, 91, 0, 105, 111, 110, 1, 10, 3, 91, 8, 13, 50, 0, 105, 111, 117, 115, 1, 10, 3, 91, 8, 13, 89, 0, 105, 111, 110, 2, 97, 108, 3, 91, 8, 14, 50, 0, 105, 111, 110, 5, 8, 1, 10, 3, 91, 8, 125, 50, 0, 4, 105, 97, 1, 10, 2, 32, 3, 91, 13, 0, 105, 97, 1, 105, 2, 108, 105, 18, 71, 0, 4, 105, 97, 110, 1, 10, 2, 32, 3, 91, 13, 50, 0, 105, 101, 110, 1, 10, 0, 105, 101, 110, 99, 101, 1, 10, 3, 91, 13, 50, 89, 0, 105, 97, 108, 1, 10, 3, 91, 118, 0, 105, 1, 10, 2, 97, 108, 105, 3, 91, 122, 0, 2, 105, 109, 101, 32, 3, 108, 0, 101, 2, 114, 114, 101, 115, 116, 3, 108, 13, 0, 7, 6, 117, 0, 8, 2, 107, 114, 97, 105, 110, 3, 2, 57, 134, 0, 108, 1, 102, 2, 102, 105, 108, 3, 2, 117, 55, 0, 108, 116, 114, 97, 8, 2, 21, 3, 4, 117, 55, 47, 34, 35, 0, 4, 1, 21, 2, 100, 97, 32, 3, 6, 57, 134, 0, 1, 102, 2, 103, 97, 108, 0, 2, 17, 67, 105, 17, 65, 0, 2, 115, 105, 111, 110, 0, 2, 116, 105, 111, 110, 0, 4, 1, 108, 2, 115, 105, 111, 110, 3, 6, 134, 0, 1, 114, 2, 17, 67, 105, 17, 65, 0, 1, 114, 2, 115, 105, 111, 110, 0, 1, 115, 2, 17, 67, 17, 65, 32, 0, 2, 103, 97, 32, 0, 2, 107, 105, 32, 0, 2, 109, 97, 32, 0, 2, 109, 111, 32, 0, 2, 122, 122, 105, 32, 0, 121, 2, 17, 65, 32, 3, 6, 134, 57, 0, 4, 1, 10, 2, 108, 111, 117, 115, 32, 3, 8, 57, 117, 0, 1, 21, 2, 108, 97, 32, 0, 1, 21, 2, 108, 97, 114, 0, 1, 21, 2, 108, 97, 116, 101, 0, 1, 21, 2, 108, 117, 109, 0, 108, 105, 1, 21, 2, 32, 3, 8, 57, 117, 55, 137, 0, 2, 97, 32, 3, 8, 57, 134, 0, 111, 117, 115, 1, 21, 3, 8, 57, 134, 13, 89, 0, 1, 104, 2, 32, 3, 8, 134, 0, 111, 117, 115, 1, 18, 66, 21, 3, 8, 134, 13, 89, 0, 108, 108, 121, 1, 102, 10, 2, 32, 3, 13, 55, 2, 122, 0, 109, 1, 114, 2, 101, 110, 116, 3, 13, 65, 0, 103, 103, 101, 1, 115, 2, 115, 116, 3, 13, 75, 121, 0, 4, 115, 1, 10, 2, 32, 3, 13, 89, 0, 115, 1, 99, 111, 102, 0, 97, 1, 103, 2, 114, 17, 65, 3, 35, 0, 2, 108, 17, 65, 3, 57, 117, 0, 4, 1, 25, 2, 116, 114, 105, 3, 57, 134, 0, 1, 100, 2, 108, 121, 0, 1, 104, 2, 109, 97, 110, 0, 1, 108, 97, 118, 0, 1, 108, 108, 2, 108, 0, 1, 108, 111, 118, 2, 109, 0, 1, 110, 97, 109, 0, 1, 110, 101, 109, 2, 32, 0, 1, 115, 2, 108, 101, 32, 0, 2, 17, 67, 17, 65, 0, 2, 17, 67, 101, 17, 67, 111, 32, 0, 2, 32, 0, 2, 97, 0, 2, 97, 108, 32, 0, 2, 101, 115, 113, 0, 2, 105, 0, 2, 108, 101, 32, 0, 2, 109, 101, 0, 2, 111, 0, 2, 116, 121, 0, 8, 2, 116, 105, 108, 0, 8, 108, 111, 115, 2, 17, 67, 0, 103, 1, 112, 109, 2, 110, 0, 103, 104, 1, 104, 0, 117, 1, 99, 97, 118, 0, 117, 2, 109, 3, 57, 134, 13, 0, 97, 114, 121, 2, 32, 3, 57, 134, 13, 34, 2, 122, 0, 99, 108, 101, 1, 110, 3, 57, 134, 49, 55, 122, 0, 99, 108, 101, 97, 114, 1, 110, 3, 57, 134, 49, 55, 142, 0, 115, 8, 2, 17, 65, 3, 57, 134, 88, 0, 115, 117, 114, 112, 3, 57, 134, 88, 6, 128, 48, 0, 115, 117, 114, 112, 5, 5, 3, 57, 134, 88, 6, 148, 48, 0, 115, 117, 2, 97, 108, 3, 57, 134, 90, 134, 0, 1, 103, 2, 105, 3, 58, 0, 97, 1, 103, 21, 2, 103, 101, 3, 58, 122, 0, 97, 8, 103, 3, 58, 126, 0, 4, 97, 1, 115, 2, 100, 101, 3, 58, 138, 0, 97, 1, 115, 2, 115, 0, 97, 103, 1, 115, 3, 58, 138, 75, 0, 4, 1, 98, 2, 100, 100, 104, 3, 117, 0, 1, 98, 2, 115, 104, 0, 1, 98, 2, 116, 99, 104, 0, 1, 99, 2, 115, 104, 0, 1, 112, 2, 115, 104, 0, 1, 112, 2, 115, 115, 0, 8, 102, 2, 108, 17, 67, 0, 4, 108, 1, 98, 2, 114, 3, 117, 55, 0, 108, 1, 98, 2, 119, 0, 108, 108, 1, 98, 0, 108, 108, 1, 102, 0, 108, 108, 1, 112, 0, 108, 108, 121, 1, 98, 3, 117, 55, 122, 0, 4, 108, 1, 99, 105, 10, 2, 116, 32, 3, 118, 0, 108, 1, 102, 10, 2, 32, 0, 1, 116, 116, 101, 108, 2, 99, 101, 3, 122, 0, 4, 115, 1, 98, 2, 105, 17, 65, 3, 122, 88, 0, 115, 1, 98, 2, 121, 0, 115, 105, 110, 101, 115, 115, 1, 98, 3, 122, 88, 50, 13, 89, 0, 4, 3, 125, 0, 1, 102, 2, 108, 99, 114, 0, 1, 108, 2, 99, 107, 0, 2, 103, 117, 17, 67, 0, 2, 108, 117, 108, 0, 2, 115, 104, 0, 2, 120, 17, 65, 12, 0, 99, 117, 108, 3, 125, 49, 57, 117, 55, 0, 108, 5, 8, 1, 102, 10, 2, 32, 3, 125, 55, 0, 108, 108, 121, 5, 8, 1, 102, 10, 2, 32, 3, 125, 55, 2, 122, 0, 103, 1, 108, 112, 2, 17, 65, 3, 125, 81, 0, 120, 117, 114, 1, 108, 3, 125, 81, 90, 134, 114, 0, 115, 8, 2, 32, 3, 125, 88, 0, 97, 114, 1, 103, 2, 100, 3, 127, 0, 4, 1, 18, 66, 2, 32, 3, 134, 0, 1, 104, 99, 2, 17, 67, 17, 65, 0, 1, 104, 114, 2, 17, 67, 17, 65, 0, 1, 106, 2, 17, 67, 17, 65, 0, 1, 106, 2, 108, 105, 0, 1, 106, 10, 2, 17, 67, 17, 65, 0, 1, 108, 2, 17, 67, 17, 65, 0, 1, 108, 2, 97, 0, 1, 108, 2, 98, 114, 105, 0, 1, 114, 2, 17, 67, 17, 65, 0, 1, 114, 2, 97, 17, 67, 12, 0, 1, 114, 2, 105, 0, 1, 114, 2, 116, 104, 0, 1, 115, 2, 17, 67, 17, 65, 0, 1, 115, 2, 105, 0, 1, 119, 2, 17, 67, 17, 65, 0, 1, 119, 2, 99, 104, 17, 65, 0, 2, 17, 67, 117, 32, 0, 2, 32, 24, 0, 2, 108, 121, 0, 5, 3, 1, 100, 2, 17, 67, 17, 65, 0, 5, 3, 1, 100, 2, 116, 121, 0, 5, 3, 1, 110, 2, 17, 67, 17, 65, 0, 5, 3, 1, 116, 2, 17, 67, 17, 65, 12, 0, 5, 3, 1, 116, 2, 105, 0, 8, 2, 108, 17, 65, 0, 8, 108, 2, 97, 0, 8, 108, 2, 99, 0, 104, 2, 17, 67, 0, 97, 114, 121, 1, 114, 2, 32, 3, 134, 34, 2, 122, 0, 99, 108, 101, 5, 3, 1, 110, 3, 134, 49, 55, 122, 0, 99, 108, 101, 97, 114, 5, 3, 1, 110, 3, 134, 49, 55, 142, 0, 103, 2, 101, 114, 32, 3, 134, 81, 0, 121, 3, 137, 0, 111, 121, 3, 139, 0, 111, 114, 1, 108, 102, 3, 143, 0, 7, 6, 118, 0, 2, 118, 3, 0, 4, 3, 84, 0, 8, 2, 108, 97, 0, 105, 98, 114, 97, 8, 2, 116, 3, 84, 2, 137, 71, 34, 138, 0, 105, 118, 105, 2, 21, 3, 84, 122, 84, 122, 0, 105, 118, 2, 32, 3, 84, 137, 84, 0, 97, 1, 21, 2, 108, 101, 110, 3, 84, 138, 0, 101, 104, 101, 109, 8, 3, 84, 141, 65, 0, 7, 6, 119, 0, 4, 1, 109, 2, 105, 99, 104, 32, 3, 0, 4, 1, 115, 17, 65, 2, 105, 99, 107, 3, 0, 2, 119, 3, 0, 101, 1, 17, 67, 2, 32, 3, 8, 58, 122, 0, 4, 114, 3, 34, 0, 114, 8, 2, 17, 71, 0, 4, 3, 58, 0, 104, 0, 104, 8, 2, 17, 71, 0, 4, 105, 116, 104, 2, 17, 65, 3, 58, 2, 122, 86, 0, 105, 116, 104, 2, 17, 67, 0, 101, 115, 116, 1, 17, 67, 3, 58, 6, 121, 89, 47, 0, 105, 116, 104, 1, 101, 2, 32, 3, 58, 6, 122, 86, 0, 101, 114, 101, 8, 2, 14, 128, 132, 132, 3, 58, 6, 140, 23, 0, 1, 17, 67, 2, 32, 3, 58, 13, 0, 111, 111, 100, 1, 10, 2, 32, 14, 128, 128, 132, 3, 58, 117, 72, 0, 105, 107, 105, 3, 58, 122, 49, 37, 0, 4, 105, 110, 103, 1, 17, 66, 2, 32, 3, 58, 122, 68, 0, 105, 110, 103, 1, 17, 66, 2, 115, 32, 0, 104, 105, 99, 104, 3, 58, 122, 76, 0, 105, 116, 104, 2, 101, 3, 58, 122, 86, 0, 104, 97, 116, 3, 58, 124, 47, 0, 4, 111, 114, 1, 115, 115, 2, 100, 3, 58, 128, 0, 111, 114, 2, 116, 104, 32, 0, 101, 2, 119, 3, 58, 129, 0, 105, 115, 101, 1, 21, 2, 32, 14, 128, 128, 132, 3, 58, 137, 88, 0, 97, 121, 1, 69, 2, 32, 14, 128, 128, 131, 3, 58, 138, 0, 104, 101, 114, 101, 3, 58, 140, 0, 4, 111, 114, 5, 5, 1, 115, 115, 2, 100, 3, 58, 148, 0, 111, 114, 5, 5, 2, 116, 104, 32, 0, 104, 2, 111, 108, 3, 107, 0, 4, 104, 111, 2, 32, 3, 107, 134, 0, 104, 111, 2, 100, 0, 104, 111, 2, 109, 0, 104, 111, 2, 115, 0, 104, 111, 39, 0, 1, 17, 67, 2, 29, 3, 117, 0, 111, 114, 1, 115, 2, 100, 3, 133, 0, 7, 6, 120, 0, 1, 120, 2, 17, 65, 3, 0, 105, 115, 2, 32, 3, 8, 49, 89, 122, 89, 0, 105, 111, 117, 115, 3, 8, 49, 91, 13, 89, 0, 117, 2, 97, 3, 8, 49, 91, 134, 0, 3, 49, 89, 0, 117, 114, 101, 2, 32, 3, 49, 91, 2, 143, 0, 105, 111, 2, 110, 3, 49, 91, 13, 0, 8, 2, 17, 71, 3, 88, 0, 121, 8, 3, 88, 137, 0, 7, 6, 121, 0, 1, 10, 2, 32, 24, 3, 2, 37, 0, 111, 117, 39, 3, 2, 57, 134, 0, 4, 1, 10, 2, 32, 3, 2, 122, 0, 1, 17, 67, 0, 1, 102, 17, 65, 11, 2, 32, 0, 1, 102, 17, 67, 2, 32, 0, 1, 104, 2, 112, 111, 99, 114, 0, 4, 2, 17, 67, 105, 99, 32, 3, 6, 122, 0, 2, 17, 67, 105, 99, 97, 108, 0, 2, 17, 67, 105, 102, 121, 0, 2, 110, 97, 32, 3, 6, 129, 0, 4, 1, 21, 2, 114, 97, 32, 3, 6, 137, 0, 2, 112, 97, 108, 0, 115, 105, 115, 1, 10, 2, 32, 3, 8, 13, 89, 122, 89, 0, 1, 107, 115, 10, 2, 32, 3, 8, 37, 0, 1, 17, 67, 10, 2, 108, 101, 110, 101, 32, 3, 8, 122, 0, 4, 1, 45, 2, 45, 3, 13, 0, 114, 2, 32, 0, 1, 17, 66, 11, 2, 32, 24, 14, 128, 144, 129, 3, 37, 0, 4, 3, 57, 0, 2, 97, 114, 0, 2, 101, 97, 114, 0, 2, 105, 17, 67, 32, 0, 97, 110, 103, 3, 57, 6, 35, 68, 0, 39, 8, 2, 17, 67, 14, 128, 132, 130, 3, 57, 13, 0, 101, 115, 8, 3, 57, 121, 89, 0, 101, 97, 104, 3, 57, 121, 107, 0, 117, 2, 21, 3, 57, 134, 0, 101, 111, 2, 17, 67, 3, 57, 136, 0, 8, 2, 32, 3, 58, 137, 0, 1, 17, 67, 2, 97, 98, 108, 3, 113, 0, 114, 105, 110, 103, 1, 115, 3, 113, 34, 122, 50, 75, 0, 4, 1, 17, 66, 11, 2, 32, 14, 128, 144, 129, 3, 122, 0, 1, 17, 66, 111, 29, 2, 21, 12, 0, 1, 17, 67, 2, 105, 0, 1, 17, 67, 17, 67, 2, 110, 32, 0, 1, 17, 67, 21, 2, 103, 101, 110, 0, 1, 17, 67, 21, 2, 109, 17, 65, 110, 32, 0, 1, 99, 2, 108, 105, 110, 0, 1, 99, 2, 110, 105, 0, 1, 99, 2, 114, 0, 1, 99, 105, 98, 2, 99, 108, 0, 1, 102, 102, 2, 32, 0, 1, 108, 2, 114, 105, 0, 1, 108, 102, 2, 110, 0, 1, 108, 103, 2, 99, 101, 114, 0, 1, 108, 103, 2, 112, 104, 0, 1, 112, 2, 114, 97, 0, 1, 112, 2, 114, 105, 0, 1, 116, 2, 112, 105, 99, 0, 1, 116, 2, 114, 97, 110, 110, 0, 1, 119, 2, 110, 0, 2, 17, 67, 0, 2, 17, 67, 17, 67, 0, 2, 17, 67, 32, 0, 2, 115, 116, 0, 5, 35, 1, 100, 2, 110, 97, 115, 0, 8, 2, 17, 67, 21, 0, 8, 115, 0, 101, 105, 103, 104, 116, 1, 116, 2, 32, 3, 122, 6, 138, 47, 0, 116, 119, 111, 1, 116, 2, 32, 3, 122, 47, 6, 134, 0, 112, 111, 99, 114, 105, 1, 104, 2, 116, 3, 122, 48, 13, 49, 34, 122, 0, 120, 1, 17, 67, 2, 32, 3, 122, 49, 89, 0, 110, 99, 104, 1, 115, 3, 122, 50, 49, 0, 111, 110, 101, 1, 116, 2, 32, 3, 122, 58, 6, 124, 50, 0, 111, 110, 101, 5, 6, 1, 116, 2, 32, 3, 122, 58, 6, 125, 50, 0, 102, 111, 117, 114, 1, 116, 2, 32, 3, 122, 83, 6, 133, 0, 102, 105, 118, 101, 1, 116, 2, 32, 3, 122, 83, 6, 137, 84, 0, 115, 1, 104, 112, 2, 105, 3, 122, 88, 0, 115, 101, 118, 101, 110, 1, 116, 2, 32, 3, 122, 89, 6, 121, 84, 13, 50, 0, 115, 101, 1, 100, 2, 110, 3, 122, 89, 13, 0, 4, 8, 2, 110, 21, 3, 125, 0, 8, 2, 115, 21, 0, 4, 1, 17, 67, 21, 2, 17, 66, 101, 13, 3, 137, 0, 1, 17, 67, 29, 0, 1, 98, 101, 114, 101, 2, 32, 0, 1, 98, 114, 97, 101, 2, 32, 0, 1, 99, 2, 99, 108, 0, 1, 99, 2, 99, 108, 105, 99, 32, 0, 1, 102, 2, 32, 0, 1, 102, 115, 2, 32, 0, 1, 104, 2, 17, 67, 114, 0, 1, 104, 116, 2, 108, 32, 0, 1, 107, 2, 108, 32, 0, 1, 108, 101, 98, 2, 32, 0, 1, 108, 102, 0, 1, 110, 2, 108, 32, 0, 1, 110, 101, 100, 2, 32, 0, 1, 112, 2, 116, 104, 0, 1, 116, 2, 108, 32, 0, 1, 116, 2, 112, 32, 0, 1, 116, 2, 112, 105, 115, 116, 0, 1, 116, 115, 2, 114, 101, 0, 2, 17, 66, 101, 13, 0, 2, 32, 0, 2, 101, 114, 32, 0, 2, 108, 117, 109, 0, 2, 116, 104, 101, 32, 0, 8, 17, 67, 0, 8, 17, 67, 2, 17, 67, 101, 0, 8, 17, 67, 2, 112, 104, 0, 8, 17, 67, 115, 0, 8, 98, 2, 12, 0, 101, 2, 32, 0, 116, 101, 2, 32, 3, 137, 47, 0, 112, 101, 1, 116, 3, 137, 48, 0, 110, 97, 109, 1, 100, 3, 137, 50, 35, 65, 0, 4, 101, 115, 1, 17, 67, 2, 32, 3, 137, 88, 0, 115, 101, 2, 32, 12, 0, 4, 115, 101, 100, 2, 32, 3, 137, 88, 72, 0, 122, 101, 100, 2, 32, 0, 115, 105, 110, 103, 2, 32, 3, 137, 88, 113, 68, 0, 114, 101, 2, 32, 3, 145, 0, 7, 6, 122, 0, 2, 122, 3, 0, 117, 2, 32, 3, 8, 88, 134, 0, 4, 3, 88, 0, 8, 2, 108, 111, 116, 0, 8, 2, 119, 17, 71, 0, 115, 8, 2, 17, 71, 0, 97, 108, 101, 115, 1, 21, 2, 32, 3, 88, 6, 126, 55, 13, 89, 0, 117, 101, 3, 88, 58, 6, 138, 0, 101, 115, 2, 32, 3, 88, 113, 88, 0, 111, 2, 111, 108, 111, 3, 88, 134, 0, 4, 104, 3, 90, 0, 104, 8, 2, 17, 71, 0, 117, 114, 101, 3, 90, 114, 0, 7, 6, 206, 0, 4, 172, 3, 6, 35, 55, 83, 13, 10, 0, 177, 0, 4, 173, 3, 6, 121, 48, 89, 122, 55, 124, 50, 10, 0, 181, 0, 4, 174, 3, 6, 129, 47, 13, 10, 0, 183, 0, 191, 3, 6, 136, 65, 122, 49, 34, 124, 50, 10, 0, 186, 3, 49, 6, 35, 48, 13, 10, 0, 190, 3, 49, 89, 6, 137, 10, 0, 189, 3, 50, 6, 57, 134, 10, 0, 187, 3, 55, 6, 35, 65, 72, 13, 10, 0, 188, 3, 65, 6, 57, 134, 10, 0, 178, 3, 71, 6, 129, 47, 13, 10, 0, 178, 5, 3, 3, 71, 6, 138, 47, 13, 10, 0, 180, 3, 72, 6, 121, 55, 47, 13, 10, 0, 179, 3, 81, 6, 35, 65, 13, 10, 0, 184, 3, 87, 6, 129, 47, 13, 10, 0, 182, 3, 88, 6, 129, 47, 13, 10, 0, 4, 175, 3, 137, 6, 136, 47, 13, 10, 0, 185, 0, 7, 6, 207, 0, 4, 133, 3, 6, 117, 48, 89, 122, 55, 124, 50, 10, 0, 141, 0, 140, 3, 6, 136, 65, 122, 49, 34, 124, 50, 10, 0, 4, 137, 3, 6, 136, 65, 122, 81, 13, 10, 0, 142, 0, 129, 3, 34, 6, 136, 10, 0, 132, 3, 47, 6, 135, 10, 0, 128, 3, 48, 6, 137, 10, 0, 136, 3, 48, 89, 6, 137, 10, 0, 135, 3, 76, 6, 137, 10, 0, 134, 3, 83, 6, 137, 10, 0, 4, 130, 3, 89, 6, 122, 81, 65, 13, 10, 0, 131, 0, 7, 6, 0, 4, 33, 2, 33, 3, 0, 4, 39, 3, 0, 4, 46, 1, 46, 3, 0, 58, 1, 32, 15, 2, 32, 15, 15, 32, 3, 0, 195, 169, 8, 3, 2, 122, 0, 46, 2, 46, 3, 9, 0, 33, 3, 9, 121, 49, 89, 49, 55, 13, 65, 138, 91, 13, 50, 9, 0, 45, 8, 2, 32, 15, 3, 10, 0, 195, 177, 3, 21, 101, 115, 0, 195, 160, 3, 35, 0, 58, 3, 49, 136, 55, 13, 50, 0, 33, 61, 3, 50, 124, 47, 129, 49, 58, 118, 88, 0, 60, 61, 3, 55, 121, 89, 132, 129, 49, 58, 118, 0, 45, 8, 32, 2, 32, 15, 3, 65, 137, 50, 13, 89, 0, 45, 1, 32, 15, 2, 32, 15, 3, 72, 35, 91, 0, 46, 3, 72, 124, 47, 0, 36, 3, 72, 124, 55, 114, 0, 196, 141, 3, 76, 0, 62, 61, 3, 81, 34, 138, 47, 13, 132, 129, 49, 58, 118, 0, 195, 176, 3, 86, 0, 195, 190, 3, 87, 0, 4, 195, 159, 3, 89, 0, 195, 167, 0, 197, 190, 3, 90, 0, 4, 197, 159, 3, 91, 0, 197, 161, 0, 4, 195, 164, 3, 121, 0, 195, 171, 0, 195, 170, 3, 121, 12, 0, 195, 182, 3, 128, 0, 4, 195, 169, 101, 3, 129, 0, 195, 175, 0, 195, 188, 3, 134, 0, 195, 169, 3, 138, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts14 = FileInMemory_createWithData (94547, reinterpret_cast (&espeakdata_dicts14_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/en_dict", U"en"); Collection_addItem (me.peek(), espeakdata_dicts14.transfer()); static unsigned char espeakdata_dicts15_data[4669] = { 0, 4, 0, 0, 9, 14, 0, 0, 0, 0, 0, 12, 67, 57, 35, 192, 50, 40, 65, 36, 51, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 8, 1, 3, 107, 35, 76, 6, 36, 49, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 44, 18, 128, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 21, 53, 9, 76, 76, 0, 0, 0, 10, 134, 1, 14, 20, 1, 197, 173, 76, 8, 0, 0, 0, 14, 1, 37, 48, 14, 16, 39, 114, 36, 50, 47, 39, 0, 27, 0, 7, 1, 38, 10, 49, 110, 0, 0, 0, 0, 0, 7, 195, 64, 244, 128, 76, 8, 14, 1, 42, 35, 89, 47, 36, 51, 37, 89, 49, 39, 0, 27, 0, 0, 0, 15, 66, 45, 0, 49, 4, 39, 65, 48, 6, 35, 34, 40, 0, 24, 0, 0, 11, 1, 47, 39, 71, 55, 37, 49, 84, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 11, 46, 1, 49, 110, 35, 55, 6, 37, 110, 0, 0, 0, 15, 3, 11, 46, 3, 49, 110, 114, 36, 47, 6, 36, 51, 36, 0, 0, 0, 0, 0, 10, 1, 61, 36, 81, 35, 55, 35, 0, 27, 0, 0, 7, 196, 21, 53, 21, 76, 76, 0, 8, 1, 64, 10, 76, 36, 10, 0, 0, 0, 7, 195, 44, 147, 192, 76, 8, 0, 0, 0, 0, 0, 0, 0, 16, 3, 11, 46, 19, 49, 110, 4, 89, 37, 6, 65, 37, 55, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 88, 84, 39, 0, 0, 0, 0, 0, 11, 1, 92, 72, 36, 49, 55, 37, 84, 39, 0, 0, 0, 0, 0, 8, 65, 96, 37, 49, 89, 39, 0, 12, 4, 95, 49, 77, 49, 65, 6, 37, 55, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 1, 124, 72, 40, 49, 47, 39, 89, 37, 81, 50, 39, 0, 0, 0, 9, 1, 126, 47, 37, 55, 72, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 12, 39, 55, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 16, 16, 76, 0, 15, 4, 1, 197, 173, 7, 35, 40, 81, 40, 89, 47, 39, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 64, 244, 212, 76, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 66, 9, 96, 71, 39, 50, 4, 84, 39, 55, 40, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 48, 144, 64, 76, 0, 0, 0, 0, 6, 195, 8, 80, 64, 17, 0, 0, 0, 0, 0, 0, 6, 195, 48, 144, 74, 76, 0, 0, 0, 0, 0, 15, 66, 16, 80, 72, 36, 55, 35, 0, 72, 28, 81, 108, 97, 32, 6, 194, 16, 80, 76, 28, 0, 0, 0, 0, 0, 0, 13, 4, 95, 4, 16, 20, 10, 49, 39, 65, 39, 10, 0, 0, 0, 0, 0, 8, 3, 95, 35, 1, 2, 35, 0, 0, 0, 0, 0, 0, 0, 15, 66, 4, 192, 35, 55, 55, 35, 0, 72, 28, 81, 108, 97, 32, 6, 194, 4, 192, 76, 28, 0, 0, 11, 3, 95, 35, 57, 47, 6, 35, 71, 39, 0, 13, 4, 95, 20, 12, 4, 47, 6, 37, 55, 72, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 12, 144, 72, 0, 0, 0, 0, 0, 14, 67, 4, 228, 212, 35, 50, 89, 47, 35, 47, 108, 0, 24, 0, 0, 17, 3, 14, 46, 2, 50, 6, 39, 47, 40, 15, 71, 6, 39, 50, 36, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 80, 144, 77, 28, 0, 0, 0, 0, 17, 67, 24, 80, 128, 83, 4, 36, 71, 14, 16, 40, 6, 35, 51, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 32, 21, 137, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 36, 16, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 32, 21, 137, 76, 76, 0, 0, 0, 8, 133, 197, 157, 9, 1, 10, 76, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 56, 82, 192, 72, 8, 0, 7, 196, 52, 85, 15, 76, 76, 0, 0, 0, 0, 7, 196, 64, 245, 129, 76, 76, 0, 0, 0, 6, 195, 80, 147, 192, 76, 0, 0, 0, 0, 12, 67, 41, 83, 128, 37, 40, 50, 6, 37, 39, 0, 0, 0, 0, 15, 66, 20, 192, 36, 55, 55, 35, 0, 72, 8, 81, 108, 97, 32, 6, 194, 20, 192, 76, 8, 0, 0, 7, 196, 52, 85, 9, 76, 76, 0, 21, 5, 11, 46, 20, 46, 16, 49, 110, 47, 6, 37, 36, 55, 4, 48, 55, 4, 40, 10, 0, 0, 0, 11, 5, 95, 35, 45, 1, 14, 2, 35, 50, 0, 0, 0, 0, 7, 131, 196, 137, 5, 76, 8, 14, 4, 95, 13, 3, 14, 89, 47, 14, 16, 6, 37, 35, 0, 0, 8, 133, 196, 157, 9, 1, 10, 76, 10, 5, 95, 35, 45, 1, 10, 2, 110, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 16, 240, 8, 0, 0, 0, 0, 0, 0, 7, 196, 32, 21, 143, 76, 76, 0, 0, 0, 0, 0, 0, 0, 0, 20, 3, 16, 46, 11, 48, 4, 39, 89, 47, 49, 14, 16, 6, 37, 89, 47, 39, 0, 24, 0, 0, 15, 66, 20, 224, 36, 50, 55, 35, 0, 72, 28, 81, 108, 97, 32, 6, 194, 20, 224, 76, 28, 0, 14, 3, 95, 51, 88, 47, 14, 16, 6, 37, 72, 36, 49, 0, 0, 10, 3, 95, 48, 67, 114, 36, 50, 47, 0, 0, 0, 0, 7, 195, 81, 32, 64, 72, 8, 0, 7, 196, 32, 21, 129, 76, 76, 20, 3, 16, 46, 19, 48, 4, 39, 89, 47, 35, 89, 49, 14, 16, 6, 37, 71, 39, 0, 0, 0, 0, 0, 11, 3, 95, 49, 67, 114, 6, 36, 50, 47, 0, 0, 0, 0, 0, 0, 0, 6, 194, 40, 80, 72, 28, 8, 66, 48, 16, 2, 55, 35, 0, 0, 7, 195, 65, 34, 64, 76, 8, 0, 0, 0, 6, 131, 196, 137, 9, 72, 0, 0, 0, 0, 6, 194, 41, 80, 72, 28, 7, 131, 196, 137, 21, 72, 28, 0, 12, 67, 41, 83, 0, 37, 40, 55, 6, 37, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 55, 88, 89, 6, 36, 48, 72, 36, 49, 0, 0, 7, 196, 52, 85, 1, 76, 76, 0, 0, 0, 0, 7, 196, 16, 85, 129, 76, 76, 0, 0, 0, 7, 132, 197, 157, 9, 1, 76, 0, 0, 0, 19, 67, 45, 68, 0, 49, 110, 47, 6, 37, 36, 55, 4, 48, 55, 4, 40, 10, 0, 0, 7, 195, 5, 5, 68, 76, 8, 0, 0, 0, 6, 194, 44, 80, 72, 8, 0, 10, 3, 95, 49, 88, 72, 6, 36, 49, 0, 0, 8, 196, 36, 229, 5, 72, 76, 8, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 50, 88, 72, 6, 40, 72, 36, 49, 0, 0, 20, 3, 1, 46, 11, 4, 35, 50, 47, 108, 49, 14, 16, 6, 37, 89, 47, 39, 0, 24, 0, 0, 0, 0, 0, 0, 0, 6, 195, 52, 144, 64, 76, 0, 0, 0, 0, 0, 13, 3, 95, 63, 63, 55, 37, 47, 4, 36, 51, 39, 0, 0, 0, 0, 14, 3, 95, 52, 88, 49, 84, 6, 35, 51, 72, 36, 49, 0, 0, 0, 6, 195, 52, 144, 74, 76, 0, 0, 0, 0, 0, 17, 66, 44, 112, 49, 6, 37, 55, 39, 81, 14, 16, 6, 35, 65, 112, 0, 0, 17, 67, 76, 84, 20, 89, 36, 48, 4, 47, 36, 65, 71, 14, 16, 39, 0, 14, 3, 95, 53, 88, 49, 84, 6, 37, 50, 72, 36, 49, 0, 0, 0, 0, 0, 0, 7, 196, 16, 85, 143, 76, 76, 0, 0, 0, 13, 3, 95, 54, 88, 89, 6, 36, 89, 72, 36, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 67, 5, 4, 128, 35, 48, 14, 16, 6, 37, 55, 39, 0, 0, 0, 0, 0, 14, 67, 77, 68, 128, 89, 47, 14, 16, 6, 35, 47, 39, 0, 0, 7, 196, 16, 85, 137, 76, 76, 0, 0, 0, 12, 3, 95, 56, 88, 6, 39, 49, 72, 36, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 57, 88, 50, 6, 108, 72, 36, 49, 0, 0, 0, 0, 6, 131, 196, 157, 9, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 52, 85, 21, 76, 76, 0, 0, 0, 15, 4, 95, 15, 7, 15, 89, 40, 71, 107, 6, 39, 49, 35, 0, 0, 7, 196, 16, 85, 149, 76, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 48, 144, 72, 5, 194, 56, 80, 76, 0, 0, 0, 0, 0, 11, 67, 52, 18, 128, 65, 6, 110, 39, 2, 0, 0, 0, 0, 0, 7, 195, 65, 35, 192, 76, 8, 0, 6, 195, 20, 35, 5, 72, 16, 4, 95, 48, 77, 52, 72, 40, 37, 55, 37, 6, 39, 50, 39, 0, 0, 0, 15, 4, 95, 48, 77, 50, 65, 37, 55, 37, 6, 39, 50, 39, 0, 0, 7, 195, 76, 83, 128, 76, 8, 16, 4, 95, 48, 77, 51, 65, 37, 55, 37, 6, 35, 34, 72, 39, 0, 0, 0, 12, 4, 95, 48, 77, 49, 65, 4, 37, 55, 10, 0, 0, 12, 4, 95, 2, 18, 22, 107, 6, 39, 49, 35, 0, 0, 0, 0, 0, 0, 13, 67, 52, 20, 128, 65, 6, 35, 14, 16, 47, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 52, 144, 72, 17, 66, 44, 208, 49, 6, 37, 55, 39, 65, 6, 36, 47, 20, 16, 112, 0, 0, 0, 0, 0, 0, 0, 6, 131, 197, 157, 9, 72, 0, 0, 19, 66, 65, 48, 48, 4, 39, 89, 47, 35, 89, 49, 14, 16, 6, 37, 71, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 77, 80, 128, 76, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 56, 144, 72, 0, 0, 0, 0, 0, 6, 195, 60, 226, 64, 72, 10, 67, 64, 194, 64, 48, 55, 4, 37, 0, 0, 0, 0, 0, 0, 0, 0, 20, 4, 95, 3, 9, 18, 114, 37, 51, 49, 40, 65, 83, 55, 6, 36, 49, 89, 35, 0, 0, 7, 195, 45, 83, 128, 76, 8, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 77, 84, 128, 76, 8, 0, 0, 0, 0, 14, 4, 95, 19, 20, 11, 89, 47, 14, 16, 36, 49, 35, 0, 0, 0, 21, 4, 95, 1, 3, 21, 72, 36, 49, 89, 47, 14, 16, 35, 49, 6, 39, 51, 50, 35, 0, 0, 21, 3, 95, 194, 171, 72, 40, 6, 39, 71, 55, 35, 49, 14, 16, 6, 35, 65, 48, 39, 0, 0, 0, 0, 0, 0, 0, 15, 3, 20, 46, 5, 47, 37, 39, 4, 36, 89, 47, 35, 89, 0, 0, 10, 67, 64, 193, 74, 48, 55, 4, 111, 0, 0, 0, 13, 4, 95, 18, 14, 7, 51, 6, 37, 50, 81, 35, 0, 0, 0, 19, 3, 20, 46, 14, 47, 6, 37, 36, 55, 4, 50, 39, 65, 6, 35, 47, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 4, 95, 1, 3, 50, 72, 40, 39, 71, 55, 35, 49, 6, 39, 51, 50, 35, 0, 0, 0, 6, 195, 20, 177, 5, 8, 0, 0, 6, 195, 37, 32, 83, 76, 0, 0, 0, 0, 0, 15, 67, 60, 181, 0, 39, 49, 4, 47, 39, 71, 14, 16, 39, 0, 0, 0, 0, 0, 0, 0, 0, 27, 3, 95, 194, 187, 83, 6, 36, 51, 65, 35, 72, 40, 4, 39, 71, 55, 35, 49, 14, 16, 6, 35, 65, 48, 39, 0, 0, 0, 0, 0, 6, 195, 37, 34, 83, 76, 6, 194, 60, 192, 76, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 76, 80, 72, 8, 0, 7, 195, 76, 81, 0, 72, 8, 0, 0, 0, 0, 0, 0, 0, 6, 195, 37, 37, 83, 76, 0, 11, 5, 95, 35, 1, 10, 14, 2, 110, 50, 0, 0, 0, 0, 0, 13, 2, 194, 169, 49, 39, 48, 37, 51, 110, 47, 39, 0, 0, 0, 0, 0, 6, 195, 88, 144, 64, 76, 6, 195, 56, 144, 64, 76, 0, 7, 196, 36, 194, 65, 40, 76, 0, 0, 10, 2, 194, 176, 81, 34, 35, 72, 112, 0, 0, 0, 0, 6, 195, 56, 144, 74, 76, 0, 0, 0, 14, 4, 95, 3, 5, 4, 114, 36, 72, 6, 37, 55, 35, 0, 0, 0, 0, 16, 4, 95, 12, 9, 7, 55, 37, 81, 35, 47, 6, 40, 51, 35, 0, 0, 11, 3, 16, 196, 157, 48, 35, 75, 39, 0, 24, 0, 0, 10, 4, 95, 35, 1, 14, 2, 35, 50, 0, 0, 0, 0, 0, 9, 4, 95, 35, 1, 10, 2, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 76, 144, 72, 0, 0, 0, 0, 0, 0, 7, 196, 64, 245, 149, 76, 76, 6, 195, 21, 53, 9, 76, 0, 6, 195, 88, 144, 74, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 132, 12, 1, 197, 173, 76, 28, 0, 0, 0, 0, 0, 7, 196, 80, 19, 69, 56, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 131, 1, 197, 173, 72, 8, 0, 0, 0, 0, 0, 0, 7, 196, 64, 245, 137, 76, 76, 9, 2, 95, 34, 114, 37, 47, 39, 0, 0, 16, 2, 95, 33, 10, 49, 14, 16, 37, 89, 37, 81, 50, 39, 10, 0, 0, 0, 15, 67, 40, 19, 128, 37, 4, 35, 50, 40, 6, 35, 51, 39, 0, 16, 2, 95, 39, 35, 48, 39, 89, 47, 14, 16, 6, 39, 83, 39, 0, 0, 0, 0, 0, 7, 195, 17, 83, 64, 72, 8, 0, 15, 4, 95, 3, 1, 16, 65, 110, 4, 40, 89, 49, 55, 35, 0, 0, 21, 2, 95, 41, 83, 6, 36, 51, 65, 35, 48, 35, 34, 36, 50, 47, 6, 36, 88, 39, 0, 0, 21, 67, 24, 20, 133, 83, 35, 14, 16, 36, 2, 72, 6, 36, 0, 76, 28, 81, 100, 101, 32, 14, 2, 95, 40, 48, 35, 34, 36, 50, 47, 36, 88, 39, 0, 0, 7, 195, 64, 84, 128, 76, 28, 0, 11, 2, 95, 46, 48, 40, 50, 49, 47, 39, 0, 0, 18, 2, 95, 45, 72, 37, 84, 37, 72, 39, 89, 47, 14, 16, 36, 49, 39, 0, 0, 21, 67, 64, 84, 133, 48, 36, 14, 16, 36, 2, 72, 6, 36, 0, 76, 28, 81, 100, 101, 32, 9, 2, 95, 44, 49, 39, 65, 39, 0, 0, 10, 2, 95, 51, 47, 14, 34, 6, 37, 0, 0, 6, 195, 37, 35, 211, 76, 8, 2, 95, 50, 72, 6, 40, 0, 0, 9, 2, 95, 49, 6, 40, 50, 40, 0, 0, 8, 2, 95, 48, 50, 40, 55, 0, 0, 9, 2, 95, 55, 89, 6, 36, 48, 0, 0, 9, 2, 95, 54, 89, 6, 36, 89, 0, 0, 10, 2, 95, 53, 49, 84, 6, 37, 50, 0, 0, 10, 2, 95, 52, 49, 84, 6, 35, 51, 0, 0, 15, 2, 95, 59, 48, 40, 50, 49, 47, 39, 49, 39, 65, 39, 0, 0, 13, 2, 95, 58, 72, 40, 48, 40, 50, 49, 47, 39, 0, 0, 8, 2, 95, 57, 50, 6, 108, 0, 0, 8, 2, 95, 56, 6, 39, 49, 0, 0, 18, 67, 20, 182, 128, 36, 49, 88, 36, 65, 48, 55, 36, 0, 44, 81, 101, 32, 15, 67, 20, 182, 128, 36, 49, 88, 36, 65, 48, 55, 36, 0, 24, 17, 2, 95, 63, 72, 36, 65, 35, 50, 72, 39, 89, 37, 81, 50, 39, 0, 0, 24, 2, 95, 62, 83, 6, 36, 51, 65, 35, 35, 50, 81, 40, 55, 49, 14, 16, 6, 35, 65, 48, 39, 0, 0, 0, 18, 2, 95, 60, 35, 50, 81, 40, 55, 49, 14, 16, 6, 35, 65, 48, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67, 16, 80, 192, 72, 36, 114, 36, 65, 71, 14, 16, 39, 0, 0, 7, 196, 64, 245, 143, 76, 76, 0, 0, 0, 0, 14, 4, 95, 4, 15, 20, 48, 6, 40, 50, 49, 47, 35, 0, 0, 0, 0, 19, 2, 95, 91, 51, 6, 36, 49, 47, 35, 49, 14, 16, 6, 35, 65, 48, 39, 0, 0, 12, 6, 95, 35, 45, 1, 10, 14, 2, 110, 50, 0, 0, 0, 8, 66, 88, 144, 84, 37, 0, 72, 5, 194, 84, 176, 17, 0, 15, 2, 95, 95, 89, 40, 71, 89, 47, 14, 16, 36, 49, 39, 0, 0, 0, 24, 2, 95, 93, 83, 6, 36, 51, 65, 35, 51, 36, 49, 47, 35, 49, 14, 16, 6, 35, 65, 48, 39, 0, 0, 6, 195, 36, 194, 65, 76, 0, 6, 195, 36, 194, 64, 72, 13, 67, 4, 178, 192, 35, 55, 37, 50, 39, 65, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 4, 95, 7, 18, 22, 65, 35, 55, 72, 36, 49, 89, 47, 14, 16, 35, 49, 6, 39, 51, 50, 35, 0, 0, 0, 0, 0, 0, 7, 195, 16, 84, 192, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 19, 2, 95, 123, 49, 6, 40, 51, 71, 35, 49, 14, 16, 6, 35, 65, 48, 39, 0, 15, 4, 95, 4, 9, 1, 72, 40, 48, 40, 50, 49, 47, 35, 0, 0, 0, 0, 0, 0, 0, 24, 2, 95, 125, 83, 6, 36, 51, 65, 35, 49, 40, 51, 71, 35, 49, 14, 16, 6, 35, 65, 48, 39, 0, 0, 0, 0, 0, 0, 8, 132, 196, 137, 1, 18, 72, 8, 0, 0, 0, 0, 0, 0, 7, 196, 44, 149, 74, 56, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 35, 51, 50, 89, 48, 6, 35, 114, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 132, 196, 157, 9, 1, 76, 9, 4, 95, 35, 45, 1, 2, 35, 0, 0, 0, 9, 197, 65, 33, 84, 21, 32, 76, 28, 0, 10, 3, 9, 46, 1, 6, 37, 6, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 132, 196, 157, 9, 19, 76, 8, 0, 0, 0, 0, 0, 0, 7, 195, 44, 145, 76, 76, 8, 0, 7, 196, 21, 53, 15, 76, 76, 0, 0, 0, 7, 195, 44, 144, 64, 76, 8, 6, 195, 76, 144, 64, 76, 6, 195, 12, 144, 64, 76, 6, 195, 84, 80, 64, 17, 0, 0, 0, 0, 0, 0, 6, 195, 76, 144, 74, 76, 6, 195, 12, 144, 74, 76, 0, 0, 7, 195, 44, 145, 64, 76, 8, 0, 0, 0, 0, 0, 7, 196, 21, 53, 1, 76, 76, 0, 0, 0, 0, 0, 0, 7, 195, 44, 144, 77, 76, 8, 0, 0, 0, 0, 0, 0, 0, 6, 195, 44, 149, 78, 8, 0, 0, 0, 0, 7, 195, 44, 149, 74, 76, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 131, 5, 196, 137, 28, 0, 7, 195, 44, 149, 64, 76, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 20, 0, 99, 0, 120, 0, 9, 1, 0, 0, 103, 0, 120, 0, 29, 1, 0, 0, 104, 0, 120, 0, 37, 1, 0, 0, 106, 0, 120, 0, 53, 1, 0, 0, 115, 0, 120, 0, 93, 1, 0, 0, 117, 0, 120, 0, 109, 1, 0, 0, 0, 0, 0, 0, 6, 97, 0, 4, 3, 35, 0, 8, 2, 32, 0, 197, 173, 3, 108, 0, 106, 3, 110, 0, 7, 6, 98, 0, 3, 71, 0, 8, 2, 32, 3, 71, 39, 0, 7, 6, 99, 0, 4, 104, 1, 25, 3, 76, 0, 104, 2, 25, 0, 104, 8, 2, 32, 3, 76, 39, 0, 3, 114, 0, 8, 2, 32, 3, 114, 39, 0, 7, 6, 100, 0, 3, 72, 0, 8, 2, 45, 114, 105, 110, 111, 3, 72, 4, 39, 49, 47, 39, 0, 8, 2, 32, 3, 72, 39, 0, 8, 2, 45, 114, 111, 3, 72, 39, 49, 47, 6, 39, 0, 7, 6, 101, 0, 4, 3, 36, 0, 8, 2, 32, 0, 197, 173, 3, 109, 0, 106, 3, 111, 0, 7, 6, 102, 0, 3, 83, 0, 8, 2, 32, 3, 83, 39, 0, 8, 2, 45, 105, 110, 111, 3, 83, 51, 2, 108, 55, 0, 8, 2, 45, 108, 111, 3, 83, 51, 108, 0, 7, 6, 103, 0, 104, 2, 25, 3, 75, 0, 3, 81, 0, 8, 2, 32, 3, 81, 39, 0, 7, 6, 104, 0, 104, 3, 101, 0, 3, 107, 0, 8, 2, 32, 3, 107, 39, 0, 7, 6, 105, 0, 4, 3, 37, 0, 8, 2, 32, 0, 7, 6, 106, 0, 3, 57, 0, 8, 2, 32, 3, 57, 39, 0, 104, 2, 17, 67, 3, 90, 0, 7, 6, 107, 0, 3, 49, 0, 8, 2, 45, 100, 105, 110, 111, 3, 49, 6, 35, 65, 35, 51, 35, 0, 8, 2, 45, 105, 110, 111, 3, 49, 6, 35, 65, 35, 51, 35, 72, 0, 8, 2, 45, 100, 111, 3, 49, 35, 65, 35, 51, 6, 35, 0, 8, 2, 32, 3, 49, 39, 0, 7, 6, 108, 0, 4, 3, 55, 0, 108, 2, 32, 0, 8, 2, 32, 3, 55, 39, 0, 7, 6, 109, 0, 3, 65, 0, 8, 2, 32, 3, 65, 39, 0, 7, 6, 110, 0, 4, 3, 50, 0, 2, 32, 14, 128, 128, 129, 0, 8, 2, 32, 3, 50, 39, 0, 8, 2, 45, 114, 111, 3, 50, 40, 65, 6, 36, 0, 7, 6, 111, 0, 4, 1, 29, 45, 2, 32, 3, 2, 39, 0, 1, 45, 2, 32, 0, 4, 110, 1, 29, 45, 2, 32, 3, 2, 39, 50, 0, 110, 1, 45, 2, 32, 0, 4, 106, 1, 29, 45, 2, 32, 3, 2, 112, 0, 106, 1, 45, 2, 32, 0, 4, 3, 39, 0, 8, 2, 32, 0, 106, 3, 112, 0, 7, 6, 112, 0, 3, 48, 0, 8, 2, 32, 3, 48, 39, 0, 4, 104, 1, 25, 3, 83, 0, 104, 2, 25, 0, 7, 6, 113, 0, 3, 49, 0, 8, 2, 32, 3, 49, 58, 39, 0, 117, 3, 49, 84, 0, 7, 6, 114, 0, 1, 25, 2, 17, 65, 3, 14, 16, 0, 4, 3, 51, 0, 1, 17, 65, 2, 17, 65, 0, 8, 2, 32, 3, 51, 39, 0, 114, 3, 51, 51, 0, 7, 6, 115, 0, 3, 89, 0, 8, 2, 45, 105, 110, 111, 3, 89, 4, 37, 50, 57, 39, 51, 0, 8, 2, 45, 116, 97, 32, 3, 89, 6, 35, 50, 49, 0, 4, 8, 2, 45, 97, 110, 105, 110, 111, 3, 89, 6, 35, 65, 4, 37, 72, 36, 0, 8, 2, 45, 97, 110, 111, 0, 8, 2, 45, 114, 111, 3, 89, 37, 50, 57, 6, 39, 0, 8, 2, 32, 3, 89, 39, 0, 4, 104, 1, 25, 3, 91, 0, 104, 2, 25, 0, 104, 8, 2, 32, 3, 91, 39, 0, 7, 6, 116, 0, 3, 47, 0, 97, 1, 45, 2, 32, 3, 47, 2, 35, 0, 8, 2, 32, 3, 47, 39, 0, 4, 104, 1, 25, 3, 87, 0, 104, 2, 25, 0, 7, 6, 117, 0, 4, 3, 40, 0, 8, 2, 32, 0, 106, 3, 113, 0, 7, 6, 118, 0, 3, 84, 0, 8, 2, 32, 3, 84, 39, 0, 7, 6, 119, 0, 4, 3, 58, 0, 104, 1, 25, 0, 8, 2, 32, 3, 72, 40, 6, 39, 71, 55, 35, 84, 4, 39, 0, 7, 6, 120, 0, 8, 2, 32, 3, 37, 49, 89, 39, 0, 3, 49, 89, 0, 8, 3, 88, 0, 7, 6, 121, 0, 1, 25, 2, 25, 3, 37, 0, 8, 2, 32, 3, 37, 48, 89, 37, 55, 39, 50, 39, 0, 3, 57, 0, 7, 6, 122, 0, 3, 88, 0, 8, 2, 32, 3, 88, 39, 0, 7, 6, 0, 4, 39, 3, 0, 4, 45, 1, 45, 45, 3, 0, 4, 45, 2, 32, 97, 3, 0, 46, 1, 46, 3, 0, 46, 2, 46, 3, 9, 0, 4, 45, 1, 32, 17, 65, 2, 32, 15, 3, 10, 0, 45, 1, 32, 17, 67, 2, 32, 15, 0, 194, 163, 2, 32, 15, 3, 10, 48, 40, 50, 72, 112, 9, 0, 36, 2, 32, 15, 3, 10, 72, 39, 55, 35, 51, 112, 9, 0, 46, 3, 48, 40, 50, 49, 47, 39, 0, 194, 163, 3, 48, 40, 50, 72, 39, 0, 43, 3, 48, 55, 40, 89, 10, 0, 43, 43, 8, 2, 32, 3, 48, 55, 40, 89, 48, 55, 40, 89, 0, 197, 173, 3, 58, 0, 197, 173, 8, 2, 32, 3, 58, 39, 0, 4, 45, 3, 65, 37, 50, 40, 89, 10, 0, 45, 8, 32, 2, 32, 15, 0, 36, 3, 72, 39, 55, 35, 51, 39, 0, 196, 157, 3, 75, 0, 196, 157, 8, 2, 32, 3, 75, 39, 0, 196, 137, 3, 76, 0, 196, 137, 8, 2, 32, 3, 76, 39, 0, 45, 1, 32, 15, 2, 32, 15, 3, 89, 47, 14, 16, 36, 49, 6, 36, 47, 39, 10, 0, 196, 181, 3, 90, 0, 196, 181, 8, 2, 32, 3, 90, 39, 0, 197, 157, 3, 91, 0, 197, 157, 8, 2, 32, 3, 91, 39, 0, 196, 165, 3, 101, 0, 196, 165, 8, 2, 32, 3, 101, 39, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts15 = FileInMemory_createWithData (4668, reinterpret_cast (&espeakdata_dicts15_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/eo_dict", U"eo"); Collection_addItem (me.peek(), espeakdata_dicts15.transfer()); static unsigned char espeakdata_dicts16_data[6340] = { 0, 4, 0, 0, 218, 19, 0, 0, 0, 0, 0, 0, 0, 4, 193, 4, 14, 4, 193, 4, 72, 0, 0, 17, 70, 32, 20, 132, 92, 20, 133, 107, 6, 35, 34, 72, 58, 36, 34, 0, 0, 0, 6, 65, 8, 71, 36, 0, 0, 0, 0, 0, 6, 65, 12, 87, 36, 0, 0, 0, 11, 67, 81, 114, 84, 47, 58, 6, 37, 47, 0, 6, 195, 69, 81, 64, 14, 6, 195, 69, 81, 64, 72, 13, 4, 95, 8, 1, 3, 49, 35, 34, 6, 110, 50, 0, 0, 0, 6, 65, 16, 72, 36, 0, 0, 0, 6, 195, 76, 147, 128, 14, 6, 195, 76, 147, 128, 72, 0, 0, 17, 65, 20, 37, 89, 48, 6, 37, 49, 0, 81, 115, 112, 101, 97, 107, 32, 4, 193, 20, 14, 5, 193, 20, 72, 9, 0, 0, 16, 4, 95, 48, 67, 15, 87, 109, 50, 47, 6, 109, 89, 37, 65, 0, 0, 0, 8, 65, 24, 23, 109, 83, 36, 0, 0, 0, 0, 0, 6, 65, 28, 101, 36, 0, 0, 0, 16, 4, 95, 51, 88, 15, 47, 34, 37, 101, 6, 109, 89, 37, 65, 0, 0, 0, 7, 65, 32, 35, 76, 36, 0, 0, 9, 198, 89, 81, 83, 81, 35, 192, 14, 9, 198, 89, 81, 83, 81, 35, 192, 72, 9, 198, 57, 81, 83, 81, 35, 192, 14, 9, 198, 57, 81, 83, 81, 35, 192, 72, 0, 0, 15, 1, 35, 35, 55, 65, 110, 35, 86, 6, 37, 98, 35, 0, 27, 0, 14, 65, 36, 6, 117, 48, 39, 72, 0, 81, 112, 111, 100, 32, 16, 65, 36, 6, 117, 83, 39, 50, 0, 81, 112, 104, 111, 110, 101, 32, 0, 15, 1, 37, 48, 110, 34, 87, 57, 6, 109, 50, 47, 39, 0, 27, 0, 14, 1, 38, 35, 65, 48, 109, 34, 89, 6, 35, 50, 47, 0, 0, 0, 8, 65, 40, 101, 110, 47, 35, 0, 0, 0, 6, 195, 64, 244, 128, 14, 6, 195, 64, 244, 128, 72, 15, 1, 42, 35, 89, 47, 109, 34, 6, 37, 89, 49, 39, 0, 27, 0, 9, 1, 43, 65, 6, 35, 89, 0, 27, 0, 6, 65, 44, 49, 35, 0, 0, 0, 10, 1, 46, 48, 40, 50, 47, 39, 0, 27, 0, 6, 195, 4, 229, 5, 14, 7, 195, 4, 229, 5, 72, 9, 9, 1, 47, 71, 35, 51, 52, 35, 0, 0, 8, 65, 48, 23, 109, 55, 36, 0, 0, 0, 0, 0, 8, 65, 52, 23, 109, 65, 36, 0, 9, 198, 89, 81, 83, 81, 35, 211, 14, 9, 198, 89, 81, 83, 81, 35, 211, 72, 9, 198, 57, 81, 83, 81, 35, 211, 14, 9, 198, 57, 81, 83, 81, 35, 211, 72, 0, 0, 0, 0, 8, 65, 56, 23, 109, 50, 36, 0, 9, 5, 95, 48, 1, 14, 4, 37, 0, 0, 0, 0, 0, 4, 193, 60, 14, 4, 193, 60, 72, 0, 11, 1, 61, 37, 100, 58, 6, 35, 55, 0, 27, 0, 0, 0, 6, 65, 64, 48, 36, 0, 11, 1, 64, 35, 51, 52, 6, 39, 82, 35, 0, 0, 0, 0, 0, 6, 65, 68, 49, 40, 0, 0, 0, 0, 0, 8, 65, 72, 23, 109, 34, 36, 0, 0, 16, 70, 52, 246, 137, 48, 192, 64, 65, 39, 87, 6, 37, 55, 35, 0, 0, 0, 0, 8, 65, 76, 23, 109, 89, 36, 0, 0, 16, 70, 77, 0, 78, 37, 50, 0, 89, 48, 6, 35, 50, 37, 91, 0, 0, 0, 0, 6, 65, 80, 47, 36, 0, 0, 0, 0, 0, 15, 69, 92, 147, 132, 61, 112, 58, 6, 37, 50, 72, 39, 58, 0, 4, 193, 84, 14, 4, 193, 84, 72, 0, 0, 16, 4, 95, 49, 67, 15, 87, 109, 50, 47, 6, 109, 89, 37, 65, 0, 0, 0, 8, 65, 88, 23, 40, 82, 36, 0, 0, 0, 0, 18, 4, 95, 49, 77, 52, 6, 40, 50, 71, 37, 57, 12, 6, 110, 50, 0, 102, 16, 4, 95, 49, 77, 52, 6, 40, 50, 71, 37, 98, 6, 110, 50, 0, 0, 14, 65, 92, 40, 82, 36, 15, 72, 6, 110, 82, 55, 36, 0, 0, 0, 16, 1, 94, 87, 37, 34, 49, 40, 65, 83, 55, 6, 36, 101, 39, 0, 0, 0, 9, 65, 96, 23, 109, 49, 37, 89, 0, 0, 18, 4, 95, 49, 77, 50, 6, 40, 50, 65, 37, 57, 12, 6, 110, 50, 0, 102, 16, 4, 95, 49, 77, 50, 6, 40, 50, 65, 37, 98, 6, 110, 50, 0, 0, 0, 0, 13, 65, 100, 37, 81, 34, 37, 6, 36, 100, 35, 0, 14, 6, 65, 100, 2, 37, 0, 0, 0, 6, 195, 48, 244, 192, 14, 6, 195, 48, 244, 192, 72, 0, 0, 8, 65, 104, 87, 109, 47, 35, 0, 0, 0, 0, 0, 0, 0, 0, 18, 67, 77, 37, 1, 115, 101, 195, 177, 111, 114, 105, 116, 97, 0, 41, 24, 29, 0, 0, 0, 0, 0, 0, 19, 67, 17, 5, 15, 100, 101, 112, 97, 114, 116, 97, 109, 101, 110, 116, 111, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 67, 77, 32, 64, 115, 101, 195, 177, 111, 114, 97, 0, 41, 24, 29, 19, 4, 95, 49, 57, 15, 86, 36, 87, 37, 65, 39, 50, 39, 82, 6, 36, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 95, 49, 67, 48, 87, 57, 6, 36, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 4, 95, 49, 56, 15, 86, 36, 87, 37, 65, 110, 49, 47, 6, 35, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 66, 17, 32, 100, 111, 99, 116, 111, 114, 0, 41, 24, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 67, 77, 32, 83, 115, 101, 195, 177, 111, 114, 97, 115, 0, 41, 24, 29, 0, 0, 0, 0, 0, 0, 0, 0, 17, 67, 77, 33, 83, 115, 101, 195, 177, 111, 114, 101, 115, 0, 41, 24, 29, 0, 0, 7, 196, 69, 82, 69, 56, 14, 7, 196, 69, 82, 69, 56, 72, 0, 0, 0, 15, 4, 95, 49, 49, 15, 40, 50, 72, 6, 109, 87, 37, 65, 0, 0, 0, 0, 0, 0, 7, 196, 48, 147, 149, 96, 65, 0, 0, 0, 0, 0, 0, 5, 194, 16, 80, 14, 5, 194, 16, 80, 72, 0, 0, 0, 6, 195, 16, 83, 0, 14, 6, 195, 16, 83, 0, 72, 0, 0, 20, 4, 95, 49, 51, 15, 86, 36, 87, 37, 65, 39, 47, 109, 34, 87, 6, 109, 34, 0, 0, 7, 196, 16, 243, 132, 20, 14, 7, 196, 16, 243, 132, 20, 72, 11, 4, 95, 4, 16, 20, 49, 39, 65, 35, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 49, 48, 15, 86, 6, 109, 87, 37, 65, 0, 0, 0, 0, 7, 66, 12, 128, 76, 36, 0, 5, 194, 4, 192, 14, 5, 194, 4, 192, 72, 0, 0, 13, 4, 95, 20, 12, 4, 47, 6, 37, 55, 72, 36, 0, 0, 0, 0, 18, 4, 95, 49, 53, 15, 86, 36, 87, 37, 65, 39, 49, 6, 37, 50, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 4, 95, 49, 50, 15, 86, 58, 39, 86, 6, 109, 87, 37, 65, 0, 0, 23, 68, 21, 128, 205, 4, 101, 120, 99, 101, 108, 101, 110, 116, 195, 173, 115, 105, 109, 97, 0, 24, 29, 0, 0, 0, 0, 0, 0, 16, 70, 4, 225, 18, 60, 145, 0, 6, 35, 50, 72, 34, 120, 72, 0, 0, 20, 4, 95, 49, 55, 15, 86, 36, 87, 37, 65, 39, 89, 6, 109, 48, 47, 37, 65, 0, 0, 0, 8, 197, 13, 80, 78, 80, 240, 14, 8, 197, 13, 80, 78, 80, 240, 72, 0, 0, 0, 0, 0, 0, 19, 4, 95, 49, 52, 15, 86, 36, 87, 37, 65, 39, 49, 58, 6, 35, 34, 47, 0, 0, 0, 0, 0, 0, 0, 18, 68, 37, 164, 68, 4, 105, 122, 113, 117, 105, 101, 114, 100, 97, 0, 24, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 4, 95, 49, 54, 15, 86, 36, 87, 37, 65, 39, 89, 6, 109, 49, 89, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 69, 21, 52, 5, 4, 176, 37, 89, 48, 6, 37, 49, 0, 0, 0, 0, 0, 0, 16, 5, 95, 48, 77, 49, 15, 65, 37, 55, 6, 109, 89, 37, 65, 0, 0, 0, 0, 19, 4, 95, 55, 88, 15, 89, 109, 48, 47, 58, 35, 101, 6, 109, 89, 37, 65, 0, 0, 0, 0, 0, 0, 6, 195, 64, 20, 129, 14, 6, 195, 64, 20, 129, 72, 0, 0, 0, 17, 70, 76, 241, 148, 92, 20, 133, 89, 6, 39, 83, 47, 58, 36, 34, 0, 0, 0, 0, 23, 68, 21, 128, 205, 60, 101, 120, 99, 101, 108, 101, 110, 116, 195, 173, 115, 105, 109, 111, 0, 24, 29, 0, 0, 0, 0, 0, 0, 10, 67, 48, 149, 133, 55, 6, 117, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 49, 15, 48, 34, 37, 65, 6, 109, 34, 0, 0, 0, 0, 9, 3, 226, 130, 172, 115, 34, 39, 0, 0, 0, 0, 0, 0, 13, 3, 95, 50, 15, 89, 36, 100, 6, 40, 50, 72, 0, 0, 0, 0, 0, 0, 8, 197, 64, 244, 145, 84, 80, 14, 8, 197, 64, 244, 145, 84, 80, 72, 0, 0, 16, 70, 24, 16, 197, 8, 243, 203, 83, 6, 118, 89, 71, 40, 49, 0, 0, 13, 3, 95, 51, 15, 47, 109, 34, 87, 6, 109, 34, 0, 8, 4, 95, 15, 18, 4, 39, 0, 0, 0, 0, 0, 18, 68, 37, 164, 68, 60, 105, 122, 113, 117, 105, 101, 114, 100, 111, 0, 24, 29, 0, 0, 0, 18, 70, 20, 225, 204, 37, 50, 0, 195, 173, 110, 103, 108, 105, 115, 104, 0, 29, 0, 0, 0, 5, 194, 20, 192, 14, 5, 194, 20, 192, 72, 0, 12, 3, 95, 50, 48, 71, 6, 118, 50, 47, 36, 0, 0, 0, 0, 0, 6, 195, 48, 20, 192, 14, 6, 195, 48, 20, 192, 72, 0, 10, 3, 95, 53, 15, 49, 37, 50, 47, 0, 0, 0, 14, 4, 95, 13, 3, 14, 65, 35, 49, 34, 6, 110, 50, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 54, 15, 89, 6, 109, 49, 89, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 55, 15, 89, 6, 109, 47, 37, 65, 0, 0, 13, 69, 37, 2, 15, 56, 80, 6, 117, 83, 39, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 20, 224, 14, 5, 194, 20, 224, 72, 0, 13, 3, 95, 51, 88, 47, 34, 6, 118, 50, 47, 35, 0, 0, 14, 3, 95, 48, 67, 87, 57, 6, 109, 50, 47, 110, 89, 0, 0, 0, 0, 16, 67, 17, 32, 64, 100, 111, 99, 116, 111, 114, 97, 0, 41, 24, 29, 0, 7, 196, 76, 240, 146, 20, 14, 7, 196, 76, 240, 146, 20, 72, 12, 3, 95, 57, 15, 50, 39, 82, 6, 36, 50, 0, 0, 0, 0, 0, 13, 3, 95, 49, 67, 87, 57, 6, 36, 50, 47, 39, 0, 0, 0, 0, 0, 0, 0, 5, 194, 48, 16, 14, 5, 194, 48, 16, 72, 8, 4, 95, 35, 194, 170, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 49, 49, 6, 110, 50, 87, 36, 0, 0, 0, 12, 3, 95, 49, 51, 47, 34, 6, 36, 87, 36, 0, 0, 11, 3, 95, 49, 50, 72, 6, 39, 87, 36, 0, 0, 12, 3, 95, 49, 53, 49, 6, 37, 50, 87, 36, 0, 0, 14, 3, 95, 49, 52, 49, 35, 47, 6, 110, 34, 87, 36, 0, 0, 12, 3, 95, 52, 15, 49, 58, 6, 35, 34, 47, 0, 0, 0, 8, 4, 95, 35, 194, 186, 39, 0, 0, 14, 3, 95, 55, 88, 89, 109, 47, 6, 109, 50, 47, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 53, 67, 49, 37, 50, 57, 6, 109, 50, 47, 110, 89, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 49, 88, 72, 57, 6, 109, 87, 0, 0, 0, 0, 0, 0, 6, 195, 81, 32, 83, 14, 6, 195, 81, 32, 83, 72, 0, 0, 0, 11, 3, 95, 50, 88, 71, 6, 118, 50, 47, 0, 0, 19, 3, 95, 55, 67, 89, 4, 36, 47, 36, 87, 57, 6, 109, 50, 47, 110, 89, 0, 0, 0, 0, 0, 12, 3, 95, 56, 15, 110, 49, 47, 6, 35, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 63, 63, 89, 6, 37, 65, 71, 110, 55, 39, 0, 0, 0, 0, 15, 3, 95, 52, 88, 49, 58, 35, 34, 6, 109, 50, 47, 35, 0, 0, 19, 3, 95, 57, 67, 50, 4, 110, 82, 36, 87, 57, 6, 109, 50, 47, 110, 89, 0, 0, 0, 0, 0, 0, 0, 16, 66, 44, 112, 107, 105, 108, 111, 103, 114, 97, 109, 111, 0, 24, 29, 5, 194, 48, 80, 14, 5, 194, 48, 80, 72, 0, 19, 71, 20, 195, 209, 84, 83, 131, 20, 6, 36, 55, 39, 49, 58, 36, 50, 89, 0, 16, 3, 95, 53, 88, 87, 37, 50, 49, 58, 6, 109, 50, 47, 35, 0, 0, 0, 0, 0, 0, 0, 13, 69, 60, 97, 137, 12, 80, 6, 39, 83, 37, 89, 0, 0, 0, 14, 3, 95, 54, 88, 89, 109, 89, 6, 109, 50, 47, 35, 0, 0, 0, 15, 4, 95, 50, 88, 15, 82, 37, 101, 6, 109, 89, 37, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 56, 88, 110, 76, 6, 109, 50, 47, 35, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 52, 80, 14, 6, 194, 52, 80, 72, 9, 0, 14, 3, 95, 57, 88, 50, 110, 82, 6, 109, 50, 47, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 15, 7, 15, 49, 39, 55, 6, 37, 47, 35, 0, 0, 7, 196, 20, 229, 18, 20, 14, 7, 196, 20, 229, 18, 20, 72, 0, 15, 3, 13, 194, 170, 109, 97, 114, 195, 173, 97, 0, 41, 24, 29, 0, 0, 20, 71, 52, 144, 210, 61, 51, 198, 80, 65, 6, 117, 49, 34, 39, 89, 39, 83, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 70, 52, 86, 9, 12, 19, 143, 65, 109, 101, 37, 49, 35, 50, 39, 0, 0, 9, 67, 21, 145, 83, 6, 117, 89, 0, 5, 194, 61, 48, 14, 5, 194, 61, 48, 72, 0, 0, 18, 4, 95, 48, 77, 52, 10, 71, 37, 57, 12, 6, 39, 50, 109, 89, 0, 102, 16, 4, 95, 48, 77, 52, 10, 71, 37, 98, 6, 39, 50, 109, 89, 0, 0, 0, 24, 5, 5, 5, 46, 21, 21, 109, 89, 47, 6, 35, 86, 39, 89, 15, 40, 50, 6, 37, 86, 39, 89, 0, 17, 4, 95, 48, 77, 50, 65, 37, 57, 12, 6, 39, 50, 36, 89, 0, 102, 15, 4, 95, 48, 77, 50, 65, 37, 98, 6, 39, 50, 36, 89, 0, 0, 11, 67, 37, 3, 196, 6, 117, 48, 39, 72, 0, 0, 0, 11, 4, 95, 48, 77, 49, 65, 6, 37, 55, 0, 0, 13, 4, 95, 2, 18, 22, 71, 34, 6, 36, 82, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 52, 144, 14, 5, 194, 52, 144, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 66, 48, 192, 6, 109, 61, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 5, 83, 145, 84, 80, 14, 8, 197, 5, 83, 145, 84, 80, 72, 0, 0, 19, 4, 95, 52, 88, 15, 49, 58, 35, 86, 34, 35, 101, 6, 109, 89, 37, 65, 0, 0, 0, 0, 19, 4, 95, 3, 9, 18, 87, 37, 34, 49, 40, 65, 83, 55, 6, 36, 101, 39, 0, 0, 0, 0, 0, 0, 6, 195, 52, 148, 192, 14, 6, 195, 52, 148, 192, 72, 0, 0, 0, 0, 6, 195, 56, 244, 192, 14, 6, 195, 56, 244, 192, 72, 0, 0, 0, 0, 13, 4, 95, 19, 20, 11, 71, 6, 35, 51, 52, 35, 0, 0, 0, 13, 4, 95, 1, 3, 21, 35, 100, 6, 40, 86, 39, 0, 0, 19, 3, 95, 195, 179, 6, 39, 15, 35, 87, 109, 50, 47, 58, 6, 35, 86, 35, 0, 25, 3, 95, 194, 171, 49, 39, 65, 6, 37, 98, 35, 89, 15, 37, 87, 49, 98, 6, 109, 34, 86, 35, 89, 0, 0, 0, 0, 13, 4, 4, 195, 177, 1, 100, 111, 195, 177, 97, 0, 29, 0, 5, 194, 48, 240, 14, 5, 194, 48, 240, 72, 0, 0, 0, 0, 0, 13, 4, 95, 18, 14, 7, 35, 50, 6, 37, 98, 39, 0, 0, 23, 3, 95, 194, 161, 35, 82, 34, 6, 37, 34, 35, 86, 65, 37, 34, 35, 87, 57, 6, 110, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 66, 77, 32, 115, 101, 195, 177, 111, 114, 0, 41, 24, 29, 0, 19, 67, 65, 65, 64, 112, 114, 101, 115, 105, 100, 101, 110, 116, 101, 0, 41, 24, 29, 0, 0, 0, 20, 4, 95, 1, 3, 50, 72, 6, 110, 71, 55, 36, 15, 35, 100, 6, 40, 86, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 131, 239, 187, 191, 0, 0, 0, 0, 27, 3, 95, 194, 191, 35, 82, 34, 6, 37, 34, 37, 50, 47, 109, 51, 52, 4, 39, 100, 35, 87, 57, 6, 110, 50, 0, 0, 19, 4, 95, 53, 88, 15, 49, 37, 50, 49, 58, 35, 101, 6, 109, 89, 37, 65, 0, 0, 0, 0, 23, 3, 95, 194, 187, 49, 39, 65, 6, 37, 98, 35, 89, 15, 72, 109, 34, 6, 109, 76, 35, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 67, 37, 164, 64, 105, 122, 113, 117, 105, 101, 114, 100, 97, 0, 24, 29, 6, 195, 77, 84, 192, 14, 6, 195, 77, 84, 192, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 2, 194, 167, 89, 109, 49, 87, 57, 6, 110, 50, 0, 0, 5, 194, 76, 80, 14, 5, 194, 76, 80, 72, 0, 0, 0, 11, 2, 194, 163, 55, 37, 82, 34, 35, 89, 0, 0, 0, 0, 0, 0, 5, 194, 77, 80, 14, 5, 194, 77, 80, 72, 0, 0, 6, 2, 194, 170, 35, 0, 0, 0, 0, 18, 2, 195, 161, 6, 35, 15, 35, 87, 109, 50, 47, 58, 6, 35, 86, 35, 0, 14, 2, 194, 169, 49, 39, 48, 37, 51, 52, 6, 117, 47, 0, 0, 13, 2, 194, 182, 48, 6, 35, 51, 52, 35, 83, 39, 0, 0, 0, 0, 18, 2, 195, 173, 6, 37, 15, 35, 87, 109, 50, 47, 58, 6, 35, 86, 35, 0, 0, 0, 0, 0, 18, 2, 195, 169, 6, 36, 15, 35, 87, 109, 50, 47, 58, 6, 35, 86, 35, 0, 0, 0, 0, 0, 0, 12, 68, 88, 242, 67, 20, 98, 111, 105, 115, 0, 29, 6, 2, 194, 186, 39, 0, 14, 4, 95, 3, 5, 4, 87, 36, 86, 6, 37, 98, 35, 0, 0, 0, 0, 9, 2, 195, 177, 23, 109, 67, 36, 0, 16, 4, 95, 12, 9, 7, 55, 37, 100, 35, 86, 6, 40, 34, 35, 0, 0, 7, 196, 32, 16, 201, 4, 14, 7, 196, 32, 16, 201, 4, 72, 0, 23, 73, 80, 133, 78, 16, 84, 130, 37, 33, 0, 47, 6, 35, 50, 72, 36, 34, 71, 37, 34, 72, 0, 0, 16, 2, 195, 188, 4, 40, 86, 57, 6, 109, 34, 109, 89, 37, 89, 0, 5, 194, 80, 80, 14, 5, 194, 80, 80, 72, 0, 0, 18, 2, 195, 186, 6, 40, 15, 35, 87, 109, 50, 47, 58, 6, 35, 86, 35, 0, 0, 0, 6, 195, 12, 243, 79, 14, 6, 195, 12, 243, 79, 72, 0, 0, 0, 0, 5, 194, 81, 80, 14, 5, 194, 81, 80, 72, 0, 18, 4, 95, 54, 88, 15, 89, 36, 100, 89, 35, 101, 6, 109, 89, 37, 65, 0, 0, 0, 0, 0, 0, 0, 0, 13, 66, 84, 64, 117, 115, 116, 101, 100, 0, 41, 24, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 76, 144, 14, 5, 194, 76, 144, 72, 0, 0, 0, 8, 197, 13, 80, 78, 16, 240, 14, 8, 197, 13, 80, 78, 16, 240, 72, 0, 0, 0, 0, 0, 0, 6, 2, 95, 1, 35, 0, 0, 0, 0, 0, 6, 2, 95, 5, 36, 0, 0, 0, 0, 0, 0, 6, 2, 95, 15, 39, 0, 0, 0, 0, 0, 0, 0, 0, 16, 70, 81, 114, 84, 80, 84, 128, 47, 58, 6, 37, 47, 36, 34, 0, 0, 0, 0, 17, 70, 64, 192, 84, 24, 244, 141, 48, 55, 6, 35, 47, 83, 39, 65, 0, 0, 0, 0, 0, 13, 2, 95, 25, 37, 81, 34, 37, 6, 36, 100, 35, 0, 0, 0, 0, 12, 68, 76, 182, 80, 20, 89, 49, 6, 117, 48, 0, 0, 0, 0, 0, 13, 2, 95, 34, 49, 39, 65, 6, 37, 98, 35, 89, 0, 0, 23, 2, 95, 33, 87, 109, 51, 52, 6, 35, 34, 35, 86, 65, 37, 34, 35, 87, 57, 6, 110, 50, 0, 0, 0, 6, 195, 12, 243, 128, 14, 6, 195, 12, 243, 128, 72, 15, 2, 95, 39, 35, 48, 110, 89, 47, 34, 6, 39, 83, 39, 0, 0, 6, 195, 8, 18, 143, 14, 6, 195, 8, 18, 143, 72, 0, 0, 0, 19, 2, 95, 43, 89, 6, 37, 100, 50, 110, 72, 36, 89, 40, 65, 6, 35, 34, 0, 0, 13, 4, 95, 3, 1, 16, 65, 6, 35, 98, 40, 89, 0, 0, 23, 2, 95, 41, 87, 57, 4, 109, 51, 52, 35, 48, 35, 34, 6, 109, 50, 47, 36, 89, 37, 89, 0, 0, 21, 2, 95, 40, 4, 35, 82, 34, 36, 48, 35, 34, 6, 109, 50, 47, 36, 89, 37, 89, 0, 0, 10, 2, 95, 47, 71, 35, 51, 52, 35, 0, 0, 10, 2, 95, 46, 48, 40, 50, 47, 39, 0, 0, 9, 2, 95, 45, 81, 98, 110, 50, 0, 0, 9, 2, 95, 44, 49, 39, 65, 35, 0, 0, 10, 2, 95, 51, 47, 34, 6, 36, 89, 0, 0, 9, 2, 95, 50, 72, 6, 110, 89, 0, 0, 9, 2, 95, 49, 6, 40, 50, 39, 0, 0, 10, 2, 95, 48, 87, 6, 36, 34, 39, 0, 0, 11, 2, 95, 55, 89, 57, 6, 36, 47, 36, 0, 0, 6, 195, 64, 84, 143, 14, 6, 195, 64, 84, 143, 72, 9, 2, 95, 54, 89, 6, 118, 89, 0, 0, 11, 2, 95, 53, 87, 6, 37, 50, 49, 39, 0, 20, 4, 95, 4, 1, 3, 72, 6, 110, 71, 55, 36, 15, 35, 100, 6, 40, 86, 39, 0, 0, 12, 2, 95, 52, 49, 58, 6, 35, 47, 34, 39, 0, 0, 17, 2, 95, 59, 48, 4, 40, 50, 47, 39, 37, 49, 6, 39, 65, 35, 0, 0, 16, 2, 95, 58, 72, 4, 110, 89, 48, 6, 40, 50, 47, 110, 89, 0, 0, 11, 2, 95, 57, 50, 58, 6, 36, 82, 36, 0, 0, 9, 2, 95, 56, 6, 110, 76, 39, 0, 0, 27, 2, 95, 63, 87, 109, 51, 52, 6, 35, 34, 37, 50, 47, 109, 51, 52, 4, 39, 100, 35, 87, 57, 6, 110, 50, 0, 0, 13, 2, 95, 62, 65, 35, 98, 6, 110, 34, 49, 36, 0, 0, 0, 13, 2, 95, 60, 65, 36, 50, 6, 110, 34, 49, 36, 0, 0, 0, 7, 196, 16, 84, 196, 20, 14, 7, 196, 16, 84, 196, 20, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 198, 69, 82, 69, 56, 84, 192, 14, 9, 198, 69, 82, 69, 56, 84, 192, 72, 0, 0, 0, 0, 0, 0, 13, 4, 95, 4, 15, 20, 48, 6, 40, 50, 47, 39, 0, 0, 0, 0, 18, 2, 95, 91, 4, 35, 82, 34, 36, 49, 110, 34, 76, 6, 36, 47, 36, 0, 0, 20, 67, 36, 195, 79, 105, 108, 117, 115, 116, 114, 195, 173, 115, 105, 109, 111, 0, 24, 29, 0, 0, 7, 66, 88, 144, 71, 37, 0, 0, 7, 195, 16, 226, 64, 17, 42, 15, 2, 95, 95, 89, 40, 82, 34, 35, 98, 6, 35, 86, 39, 0, 0, 0, 20, 2, 95, 93, 87, 57, 4, 109, 51, 52, 35, 49, 110, 34, 76, 6, 36, 47, 36, 0, 0, 21, 2, 95, 92, 71, 6, 35, 51, 52, 35, 37, 65, 71, 109, 34, 47, 6, 37, 86, 35, 0, 0, 0, 0, 10, 67, 40, 22, 154, 75, 6, 35, 89, 0, 17, 4, 95, 56, 88, 15, 110, 49, 47, 39, 101, 6, 109, 89, 37, 65, 0, 0, 18, 2, 95, 96, 35, 87, 6, 109, 50, 47, 110, 81, 34, 6, 35, 82, 36, 0, 0, 0, 0, 0, 20, 67, 36, 195, 65, 105, 108, 117, 115, 116, 114, 195, 173, 115, 105, 109, 97, 0, 24, 29, 0, 0, 0, 0, 13, 4, 95, 7, 18, 22, 81, 34, 6, 35, 82, 36, 0, 0, 0, 17, 7, 13, 195, 169, 24, 9, 3, 15, 65, 6, 109, 101, 37, 49, 39, 0, 0, 0, 17, 70, 92, 147, 132, 61, 116, 192, 58, 6, 37, 50, 72, 39, 58, 89, 0, 0, 6, 195, 48, 84, 192, 14, 6, 195, 48, 84, 192, 72, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 95, 123, 4, 35, 82, 34, 36, 98, 6, 35, 82, 36, 0, 16, 4, 95, 4, 9, 1, 72, 57, 6, 109, 34, 36, 89, 37, 89, 0, 0, 0, 0, 0, 0, 13, 68, 64, 245, 197, 72, 48, 6, 35, 58, 36, 34, 0, 0, 17, 2, 95, 125, 87, 57, 4, 109, 51, 52, 35, 98, 6, 35, 82, 36, 0, 0, 0, 17, 70, 24, 148, 133, 24, 246, 0, 83, 6, 117, 34, 83, 39, 49, 89, 0, 0, 10, 67, 40, 21, 211, 75, 6, 39, 89, 0, 12, 68, 5, 4, 12, 20, 6, 35, 48, 13, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 69, 77, 1, 69, 12, 128, 89, 48, 6, 37, 76, 0, 0, 9, 198, 89, 81, 83, 81, 32, 64, 14, 9, 198, 89, 81, 83, 81, 32, 64, 72, 9, 198, 57, 81, 83, 81, 32, 64, 14, 9, 198, 57, 81, 83, 81, 32, 64, 72, 0, 0, 0, 0, 10, 67, 25, 33, 69, 83, 34, 6, 37, 0, 0, 0, 0, 0, 15, 4, 95, 35, 51, 50, 109, 89, 48, 6, 35, 87, 57, 39, 0, 0, 0, 0, 0, 0, 9, 198, 89, 81, 83, 81, 32, 83, 14, 9, 198, 89, 81, 83, 81, 32, 83, 72, 9, 198, 57, 81, 83, 81, 32, 83, 14, 9, 198, 57, 81, 83, 81, 32, 83, 72, 0, 0, 14, 69, 12, 132, 143, 52, 80, 49, 34, 6, 39, 58, 65, 0, 0, 0, 9, 198, 52, 145, 78, 81, 32, 83, 14, 9, 198, 52, 145, 78, 81, 32, 83, 72, 0, 0, 17, 4, 95, 57, 88, 15, 50, 39, 50, 35, 101, 6, 109, 89, 37, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 81, 84, 192, 14, 6, 195, 81, 84, 192, 72, 0, 7, 196, 32, 20, 212, 4, 14, 7, 196, 32, 20, 212, 4, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 69, 28, 243, 199, 48, 80, 81, 6, 40, 81, 13, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 71, 52, 84, 211, 20, 225, 197, 72, 65, 6, 36, 89, 36, 50, 75, 36, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 67, 84, 68, 192, 117, 115, 116, 101, 100, 101, 115, 0, 41, 24, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 70, 76, 84, 150, 36, 49, 64, 89, 6, 36, 34, 82, 37, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 18, 66, 108, 0, 114, 0, 121, 0, 7, 6, 18, 67, 98, 0, 100, 0, 103, 0, 110, 0, 109, 0, 7, 6, 18, 68, 102, 0, 104, 0, 106, 0, 115, 0, 121, 0, 122, 0, 114, 0, 7, 6, 18, 69, 98, 0, 118, 0, 102, 0, 112, 0, 7, 6, 18, 70, 103, 0, 107, 0, 7, 6, 18, 71, 106, 0, 119, 0, 108, 0, 114, 0, 98, 0, 100, 0, 103, 0, 110, 0, 109, 0, 112, 0, 116, 0, 107, 0, 99, 0, 7, 6, 97, 0, 117, 2, 32, 3, 6, 114, 0, 121, 2, 32, 3, 6, 117, 0, 3, 35, 0, 117, 3, 114, 0, 4, 105, 3, 117, 0, 121, 2, 25, 0, 7, 6, 98, 0, 4, 3, 71, 0, 1, 109, 0, 1, 110, 0, 2, 105, 17, 65, 0, 2, 117, 17, 65, 0, 8, 2, 17, 65, 0, 8, 2, 18, 66, 17, 65, 0, 8, 2, 28, 1, 0, 4, 2, 17, 65, 3, 82, 0, 2, 18, 68, 0, 2, 99, 17, 71, 0, 7, 6, 99, 0, 4, 3, 49, 0, 8, 2, 18, 66, 17, 65, 0, 107, 1, 17, 65, 0, 4, 104, 3, 76, 0, 104, 8, 2, 17, 65, 0, 2, 17, 71, 3, 87, 0, 7, 6, 100, 0, 4, 3, 72, 0, 1, 108, 0, 1, 109, 0, 1, 110, 0, 1, 114, 0, 8, 2, 17, 65, 0, 8, 2, 28, 1, 0, 8, 2, 114, 17, 65, 0, 4, 2, 17, 65, 3, 86, 0, 2, 18, 68, 0, 2, 99, 17, 71, 0, 7, 6, 101, 0, 117, 2, 32, 3, 6, 115, 0, 121, 2, 32, 3, 6, 118, 0, 4, 3, 36, 0, 2, 17, 67, 104, 0, 4, 1, 114, 17, 65, 3, 109, 0, 2, 110, 25, 0, 2, 114, 0, 117, 3, 115, 0, 4, 105, 3, 118, 0, 121, 2, 25, 0, 7, 6, 102, 0, 4, 3, 83, 0, 8, 2, 18, 66, 17, 65, 0, 7, 6, 103, 0, 110, 8, 2, 17, 65, 3, 50, 0, 4, 3, 81, 0, 1, 109, 0, 1, 110, 0, 8, 2, 17, 65, 0, 8, 2, 18, 66, 17, 65, 0, 8, 2, 28, 1, 0, 104, 8, 2, 17, 65, 0, 4, 2, 17, 65, 3, 100, 0, 2, 18, 68, 0, 2, 99, 17, 71, 0, 2, 17, 71, 12, 3, 101, 0, 7, 6, 104, 0, 3, 0, 105, 8, 2, 17, 65, 3, 57, 0, 7, 6, 105, 0, 4, 5, 35, 1, 108, 2, 17, 65, 3, 2, 37, 0, 5, 35, 1, 114, 2, 17, 65, 0, 3, 37, 0, 4, 1, 17, 67, 2, 17, 65, 3, 57, 0, 1, 117, 103, 2, 17, 65, 0, 2, 17, 65, 0, 7, 6, 106, 0, 3, 101, 0, 7, 6, 107, 0, 4, 3, 49, 0, 8, 2, 18, 66, 17, 65, 0, 7, 6, 108, 0, 4, 3, 55, 0, 108, 2, 32, 0, 108, 5, 2, 3, 57, 12, 0, 4, 108, 3, 61, 0, 108, 8, 2, 17, 65, 0, 108, 5, 2, 1, 32, 110, 2, 17, 65, 3, 75, 0, 108, 5, 2, 8, 2, 17, 65, 3, 98, 0, 7, 6, 109, 0, 1, 21, 2, 32, 3, 8, 65, 0, 110, 8, 2, 101, 109, 3, 50, 0, 3, 65, 0, 98, 8, 2, 17, 65, 3, 65, 71, 0, 7, 6, 110, 0, 4, 3, 50, 0, 104, 8, 2, 17, 65, 0, 4, 2, 18, 69, 3, 65, 0, 2, 32, 18, 69, 0, 121, 2, 17, 65, 3, 67, 0, 4, 2, 18, 70, 3, 68, 0, 2, 32, 18, 70, 0, 2, 106, 0, 7, 6, 111, 0, 121, 2, 32, 3, 6, 120, 0, 4, 3, 39, 0, 2, 17, 67, 104, 0, 117, 3, 39, 58, 0, 4, 1, 114, 17, 65, 3, 110, 0, 2, 17, 67, 25, 0, 2, 114, 0, 4, 105, 3, 120, 0, 121, 2, 25, 0, 7, 6, 112, 0, 4, 116, 8, 2, 101, 114, 111, 3, 47, 0, 116, 8, 2, 111, 108, 0, 4, 3, 48, 0, 8, 2, 18, 66, 17, 65, 0, 2, 116, 3, 48, 12, 0, 4, 104, 2, 21, 3, 83, 0, 104, 2, 25, 0, 104, 8, 2, 17, 65, 0, 4, 115, 8, 2, 101, 117, 100, 111, 3, 89, 0, 115, 8, 2, 105, 0, 7, 6, 113, 0, 4, 3, 49, 0, 117, 2, 17, 71, 0, 119, 8, 2, 17, 65, 3, 49, 58, 0, 7, 6, 114, 0, 4, 3, 34, 0, 1, 17, 65, 2, 17, 65, 0, 1, 17, 67, 2, 17, 65, 0, 2, 32, 0, 2, 116, 0, 4, 1, 108, 2, 17, 65, 3, 51, 0, 1, 109, 2, 17, 65, 0, 1, 110, 2, 17, 65, 0, 1, 115, 2, 17, 65, 0, 8, 2, 17, 65, 0, 114, 3, 51, 52, 0, 7, 6, 115, 0, 4, 3, 89, 0, 1, 10, 2, 32, 14, 128, 128, 129, 0, 8, 2, 25, 21, 0, 99, 5, 33, 2, 17, 71, 0, 115, 0, 4, 104, 2, 25, 3, 91, 0, 104, 8, 2, 17, 65, 0, 104, 8, 2, 18, 66, 17, 65, 0, 7, 6, 116, 0, 4, 3, 47, 0, 8, 2, 18, 66, 17, 65, 0, 104, 2, 25, 0, 104, 8, 2, 21, 0, 4, 120, 3, 76, 0, 120, 8, 2, 17, 65, 0, 7, 6, 117, 0, 4, 1, 103, 2, 101, 3, 0, 4, 1, 103, 2, 105, 3, 0, 4, 1, 103, 2, 195, 169, 3, 0, 1, 103, 2, 195, 173, 3, 0, 4, 5, 35, 1, 108, 2, 17, 65, 3, 2, 40, 0, 5, 35, 1, 114, 2, 17, 65, 0, 4, 3, 40, 0, 2, 117, 0, 2, 17, 65, 3, 58, 0, 7, 6, 118, 0, 4, 3, 71, 0, 1, 109, 0, 1, 110, 0, 2, 105, 17, 65, 0, 2, 117, 17, 65, 0, 8, 2, 17, 65, 0, 8, 2, 18, 66, 17, 65, 0, 8, 2, 28, 1, 0, 4, 2, 17, 65, 3, 82, 0, 2, 18, 68, 0, 2, 99, 17, 71, 0, 7, 6, 119, 0, 4, 3, 58, 0, 104, 8, 2, 17, 65, 0, 7, 6, 120, 0, 4, 3, 49, 89, 0, 99, 5, 33, 2, 17, 71, 0, 8, 2, 28, 1, 3, 89, 0, 7, 6, 121, 0, 4, 3, 37, 0, 2, 32, 0, 4, 8, 108, 2, 17, 65, 3, 57, 0, 8, 109, 2, 17, 65, 0, 4, 1, 117, 2, 25, 3, 57, 12, 0, 2, 17, 65, 0, 1, 32, 110, 2, 17, 65, 3, 75, 0, 8, 2, 28, 1, 3, 79, 0, 8, 2, 17, 65, 3, 98, 0, 7, 6, 122, 0, 3, 87, 0, 5, 2, 2, 18, 67, 3, 88, 0, 122, 3, 123, 0, 7, 6, 0, 195, 161, 3, 7, 35, 0, 195, 173, 3, 7, 37, 0, 195, 186, 3, 7, 40, 0, 195, 169, 3, 7, 109, 0, 195, 179, 3, 7, 110, 0, 4, 45, 1, 32, 17, 65, 2, 32, 15, 3, 10, 0, 45, 1, 32, 17, 67, 2, 32, 15, 0, 195, 188, 3, 40, 0, 44, 2, 15, 3, 49, 110, 65, 35, 0, 45, 8, 2, 32, 15, 3, 65, 6, 109, 50, 110, 89, 0, 195, 177, 3, 67, 0, 36, 3, 72, 6, 110, 55, 35, 34, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts16 = FileInMemory_createWithData (6339, reinterpret_cast (&espeakdata_dicts16_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/es_dict", U"es"); Collection_addItem (me.peek(), espeakdata_dicts16.transfer()); static unsigned char espeakdata_dicts17_data[6778] = { 0, 4, 0, 0, 55, 19, 0, 0, 0, 0, 0, 0, 0, 6, 65, 4, 35, 108, 0, 0, 7, 194, 5, 0, 17, 42, 42, 0, 0, 0, 7, 65, 8, 71, 36, 110, 0, 0, 0, 17, 67, 21, 64, 192, 36, 47, 15, 47, 89, 36, 47, 36, 34, 35, 0, 24, 0, 0, 8, 65, 12, 47, 89, 36, 110, 0, 0, 0, 0, 0, 7, 65, 16, 72, 36, 110, 0, 0, 0, 0, 7, 196, 76, 83, 12, 20, 76, 6, 195, 76, 147, 129, 72, 0, 42, 65, 20, 6, 36, 50, 50, 36, 15, 65, 4, 36, 37, 57, 36, 15, 4, 35, 57, 109, 15, 6, 35, 34, 12, 84, 35, 65, 37, 89, 47, 0, 24, 84, 46, 32, 109, 32, 46, 32, 97, 32, 25, 65, 20, 6, 36, 50, 50, 36, 15, 49, 34, 6, 37, 89, 12, 47, 40, 89, 47, 0, 24, 81, 107, 114, 32, 6, 65, 20, 36, 110, 0, 0, 0, 16, 67, 76, 18, 128, 89, 6, 35, 57, 109, 50, 72, 37, 55, 0, 24, 20, 67, 41, 34, 192, 57, 4, 121, 34, 57, 36, 15, 49, 6, 39, 34, 34, 72, 0, 24, 0, 0, 7, 65, 24, 36, 83, 83, 0, 0, 0, 0, 0, 7, 65, 28, 81, 36, 110, 0, 0, 0, 0, 0, 7, 65, 32, 107, 35, 108, 0, 0, 0, 0, 0, 13, 1, 36, 47, 39, 55, 12, 55, 35, 34, 37, 47, 0, 6, 65, 36, 37, 112, 0, 0, 16, 1, 37, 48, 34, 39, 47, 89, 6, 36, 50, 47, 12, 37, 0, 27, 0, 7, 1, 38, 10, 36, 47, 0, 0, 0, 8, 65, 40, 57, 39, 47, 12, 0, 0, 0, 10, 1, 42, 47, 121, 51, 12, 50, 0, 27, 0, 11, 1, 43, 48, 55, 40, 89, 12, 89, 0, 27, 0, 7, 65, 44, 49, 35, 108, 0, 0, 14, 66, 45, 0, 49, 6, 117, 48, 6, 121, 36, 84, 0, 24, 0, 0, 15, 1, 47, 49, 35, 55, 12, 72, 15, 49, 34, 112, 48, 89, 0, 0, 7, 65, 48, 36, 55, 55, 0, 0, 18, 66, 49, 0, 55, 4, 40, 81, 118, 15, 48, 6, 110, 47, 40, 72, 0, 24, 0, 0, 7, 196, 52, 147, 12, 20, 76, 0, 42, 65, 52, 65, 4, 36, 37, 57, 36, 15, 6, 35, 57, 109, 15, 6, 35, 34, 84, 35, 65, 4, 37, 89, 36, 15, 57, 6, 121, 34, 81, 37, 0, 84, 46, 32, 97, 32, 46, 32, 106, 32, 7, 65, 52, 36, 65, 65, 0, 0, 0, 0, 0, 7, 65, 56, 36, 50, 50, 0, 0, 0, 0, 0, 6, 65, 60, 39, 115, 0, 0, 18, 1, 61, 84, 119, 51, 12, 72, 40, 89, 15, 65, 121, 34, 49, 12, 0, 27, 0, 0, 0, 26, 65, 64, 48, 6, 121, 34, 109, 89, 47, 15, 49, 34, 6, 37, 89, 47, 40, 89, 47, 0, 24, 81, 107, 114, 32, 7, 1, 64, 10, 121, 47, 0, 7, 65, 64, 48, 36, 110, 0, 0, 0, 0, 0, 7, 65, 68, 49, 40, 117, 0, 0, 0, 0, 0, 7, 65, 72, 36, 51, 51, 0, 0, 0, 0, 0, 21, 65, 76, 89, 6, 36, 55, 15, 6, 108, 89, 47, 35, 55, 0, 24, 82, 46, 32, 97, 32, 7, 65, 76, 36, 89, 89, 0, 0, 0, 0, 0, 7, 65, 80, 47, 36, 110, 0, 0, 0, 0, 0, 5, 65, 84, 117, 0, 0, 0, 0, 0, 7, 65, 88, 84, 36, 110, 0, 0, 7, 194, 5, 48, 17, 42, 42, 0, 0, 13, 4, 95, 49, 77, 52, 71, 37, 61, 57, 39, 50, 0, 0, 14, 1, 92, 55, 121, 68, 81, 15, 49, 34, 112, 48, 89, 0, 14, 65, 92, 49, 6, 35, 49, 89, 37, 89, 84, 36, 110, 0, 0, 0, 0, 7, 196, 60, 195, 149, 16, 72, 0, 12, 4, 95, 49, 77, 49, 47, 40, 107, 109, 47, 0, 8, 65, 96, 37, 49, 12, 89, 0, 0, 6, 194, 4, 64, 17, 24, 13, 4, 95, 49, 77, 50, 65, 37, 61, 57, 39, 50, 0, 0, 14, 4, 95, 49, 77, 51, 65, 37, 61, 57, 35, 34, 72, 0, 0, 0, 9, 65, 100, 37, 81, 34, 36, 49, 0, 0, 0, 0, 0, 9, 65, 104, 47, 89, 36, 47, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 66, 12, 16, 47, 89, 6, 37, 34, 49, 35, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, 126, 47, 37, 55, 72, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 67, 48, 147, 12, 55, 6, 37, 55, 12, 0, 0, 0, 8, 132, 1, 195, 188, 5, 17, 42, 0, 0, 0, 0, 13, 5, 16, 195, 181, 12, 12, 48, 6, 119, 55, 12, 0, 0, 0, 14, 67, 5, 81, 192, 6, 35, 117, 81, 40, 89, 47, 0, 24, 0, 0, 0, 0, 0, 7, 196, 44, 83, 12, 20, 76, 0, 0, 0, 18, 67, 41, 50, 192, 57, 4, 35, 39, 89, 49, 6, 39, 50, 50, 72, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 66, 16, 32, 47, 4, 36, 114, 132, 89, 37, 15, 71, 6, 36, 55, 55, 37, 0, 24, 0, 0, 0, 0, 20, 67, 72, 213, 11, 34, 6, 108, 65, 35, 47, 40, 15, 49, 6, 39, 81, 40, 0, 24, 0, 0, 0, 0, 14, 66, 17, 32, 47, 6, 39, 49, 12, 47, 39, 34, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 20, 112, 64, 72, 8, 0, 0, 0, 0, 7, 195, 4, 112, 64, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 56, 81, 68, 76, 0, 0, 0, 0, 0, 0, 0, 0, 23, 67, 73, 66, 128, 34, 4, 35, 40, 72, 15, 47, 6, 36, 110, 15, 57, 6, 35, 108, 65, 0, 24, 6, 195, 56, 82, 68, 76, 0, 11, 4, 95, 4, 16, 20, 49, 39, 65, 109, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67, 77, 35, 128, 89, 6, 40, 34, 34, 50, 40, 72, 0, 24, 6, 195, 56, 82, 76, 76, 0, 0, 0, 0, 0, 12, 4, 95, 20, 12, 4, 47, 37, 55, 72, 36, 0, 15, 3, 95, 35, 57, 47, 35, 71, 40, 55, 108, 47, 39, 34, 0, 0, 10, 67, 4, 195, 0, 6, 35, 55, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 56, 83, 132, 20, 76, 0, 0, 0, 0, 0, 0, 0, 0, 11, 67, 60, 176, 89, 39, 49, 6, 36, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67, 52, 240, 128, 65, 4, 39, 71, 6, 37, 112, 55, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 66, 32, 16, 107, 6, 36, 49, 12, 47, 35, 34, 37, 47, 0, 24, 14, 66, 20, 112, 50, 6, 127, 47, 12, 36, 49, 89, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 60, 195, 1, 72, 0, 0, 0, 0, 0, 18, 67, 16, 148, 128, 72, 4, 37, 34, 6, 36, 49, 12, 47, 39, 34, 0, 24, 0, 0, 0, 0, 0, 0, 0, 12, 66, 33, 32, 107, 6, 121, 51, 51, 35, 0, 24, 0, 19, 67, 33, 35, 0, 107, 6, 35, 34, 113, 55, 4, 37, 49, 40, 55, 47, 0, 24, 0, 0, 0, 0, 0, 0, 0, 20, 66, 12, 208, 89, 6, 36, 50, 47, 37, 15, 65, 4, 110, 47, 34, 37, 47, 0, 24, 5, 194, 20, 144, 72, 0, 0, 0, 0, 0, 0, 0, 0, 15, 66, 37, 16, 6, 37, 112, 15, 49, 6, 40, 117, 0, 24, 42, 0, 0, 0, 0, 0, 0, 0, 0, 22, 66, 16, 192, 47, 4, 36, 114, 132, 89, 37, 15, 55, 6, 112, 47, 12, 34, 37, 47, 0, 24, 0, 8, 195, 72, 224, 64, 17, 42, 42, 0, 0, 0, 0, 0, 0, 11, 67, 57, 83, 142, 50, 6, 40, 50, 12, 0, 0, 0, 21, 67, 40, 225, 64, 57, 4, 108, 15, 50, 4, 112, 15, 6, 36, 72, 35, 89, 37, 0, 24, 6, 195, 60, 193, 68, 72, 11, 3, 226, 130, 172, 36, 40, 34, 39, 47, 0, 0, 0, 0, 0, 6, 195, 60, 193, 64, 72, 0, 0, 0, 21, 66, 16, 208, 47, 4, 36, 114, 132, 89, 37, 15, 65, 6, 110, 47, 34, 37, 47, 0, 24, 6, 194, 40, 16, 72, 8, 0, 6, 195, 60, 194, 68, 72, 0, 0, 0, 0, 8, 195, 20, 242, 192, 17, 42, 42, 6, 195, 60, 194, 64, 72, 0, 0, 0, 0, 0, 0, 6, 195, 60, 194, 78, 72, 0, 0, 0, 0, 0, 0, 24, 67, 40, 212, 192, 57, 4, 108, 15, 65, 6, 40, 117, 15, 89, 6, 36, 55, 55, 37, 50, 36, 0, 24, 0, 0, 0, 0, 29, 67, 88, 212, 192, 84, 4, 119, 37, 15, 65, 6, 40, 117, 15, 89, 6, 36, 110, 15, 89, 4, 40, 81, 40, 50, 36, 0, 24, 0, 0, 0, 13, 66, 41, 32, 57, 6, 117, 67, 37, 39, 34, 0, 24, 7, 194, 37, 64, 17, 42, 42, 0, 16, 67, 45, 3, 0, 49, 6, 35, 40, 48, 12, 55, 40, 89, 0, 24, 0, 0, 15, 67, 45, 5, 0, 49, 6, 35, 48, 12, 47, 36, 50, 0, 24, 14, 69, 100, 241, 213, 73, 64, 57, 39, 81, 40, 34, 47, 0, 0, 0, 0, 0, 0, 6, 194, 20, 208, 17, 24, 0, 0, 0, 6, 195, 60, 193, 78, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 194, 20, 224, 17, 42, 42, 0, 20, 3, 95, 51, 88, 49, 6, 39, 55, 65, 15, 49, 4, 125, 65, 65, 36, 50, 72, 0, 0, 11, 3, 95, 48, 67, 89, 35, 72, 109, 10, 0, 0, 0, 0, 24, 3, 11, 195, 188, 49, 6, 39, 34, 47, 36, 34, 37, 15, 6, 125, 107, 4, 37, 89, 47, 40, 0, 24, 0, 0, 0, 17, 66, 41, 64, 57, 4, 108, 15, 47, 6, 36, 37, 89, 36, 72, 0, 24, 6, 195, 52, 145, 1, 76, 0, 0, 10, 3, 95, 49, 67, 89, 35, 72, 109, 0, 0, 14, 67, 45, 37, 0, 49, 6, 39, 34, 47, 36, 34, 0, 24, 0, 6, 195, 44, 81, 1, 76, 6, 195, 76, 81, 1, 76, 0, 0, 0, 0, 18, 3, 95, 49, 57, 6, 125, 107, 36, 49, 89, 35, 47, 36, 37, 89, 47, 0, 0, 11, 67, 44, 83, 12, 49, 6, 36, 55, 12, 0, 18, 67, 61, 50, 192, 6, 39, 89, 109, 15, 49, 6, 39, 50, 50, 72, 0, 24, 19, 3, 95, 49, 56, 49, 6, 35, 107, 36, 49, 89, 35, 47, 36, 37, 89, 47, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 49, 49, 125, 49, 89, 47, 36, 37, 89, 47, 0, 0, 12, 3, 95, 49, 48, 49, 6, 125, 65, 65, 36, 0, 0, 16, 3, 95, 49, 51, 49, 6, 39, 55, 65, 47, 36, 37, 89, 47, 0, 0, 16, 3, 95, 49, 50, 49, 6, 35, 49, 89, 47, 36, 37, 89, 47, 0, 0, 15, 3, 95, 49, 53, 84, 6, 112, 89, 47, 36, 37, 89, 47, 0, 0, 16, 3, 95, 49, 52, 50, 6, 36, 55, 37, 47, 36, 37, 89, 47, 0, 0, 18, 3, 95, 49, 55, 89, 6, 36, 37, 47, 89, 36, 47, 36, 37, 89, 47, 0, 0, 15, 3, 95, 49, 54, 49, 6, 117, 89, 47, 36, 37, 89, 47, 0, 0, 11, 66, 44, 64, 49, 6, 128, 72, 36, 0, 24, 0, 22, 3, 95, 55, 88, 89, 6, 36, 37, 47, 89, 36, 15, 49, 4, 125, 65, 65, 36, 50, 72, 0, 0, 0, 0, 0, 0, 0, 0, 12, 66, 41, 96, 57, 6, 121, 34, 34, 84, 0, 24, 6, 194, 45, 64, 17, 24, 0, 0, 0, 0, 0, 0, 0, 0, 7, 194, 52, 16, 17, 42, 42, 5, 194, 52, 16, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 3, 95, 50, 88, 49, 6, 35, 49, 89, 15, 49, 4, 125, 65, 65, 36, 50, 72, 0, 0, 0, 8, 197, 52, 147, 12, 21, 48, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 63, 63, 65, 6, 121, 34, 49, 0, 0, 0, 13, 66, 53, 32, 65, 6, 37, 89, 47, 36, 34, 0, 24, 0, 20, 3, 95, 52, 88, 50, 6, 36, 55, 113, 15, 49, 4, 125, 65, 65, 36, 50, 72, 0, 0, 0, 0, 0, 6, 195, 76, 81, 64, 76, 0, 0, 6, 195, 56, 17, 0, 72, 0, 17, 66, 44, 112, 49, 4, 37, 55, 116, 81, 34, 6, 35, 65, 65, 0, 24, 0, 19, 67, 76, 84, 20, 89, 6, 36, 48, 47, 6, 36, 65, 65, 71, 36, 34, 0, 24, 7, 195, 20, 130, 192, 72, 8, 19, 3, 95, 53, 88, 84, 6, 112, 89, 15, 49, 4, 125, 65, 65, 36, 50, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 3, 95, 54, 88, 49, 6, 117, 89, 15, 49, 4, 125, 65, 65, 36, 50, 72, 0, 0, 0, 0, 0, 0, 0, 0, 21, 66, 40, 160, 57, 4, 108, 15, 57, 6, 121, 34, 34, 81, 65, 37, 89, 36, 72, 0, 24, 0, 16, 67, 5, 4, 128, 4, 35, 48, 48, 34, 6, 37, 61, 61, 0, 24, 0, 0, 0, 0, 0, 14, 4, 14, 195, 164, 4, 50, 6, 121, 72, 109, 55, 0, 24, 0, 0, 14, 66, 57, 32, 50, 6, 40, 65, 65, 71, 36, 34, 0, 24, 0, 23, 3, 95, 56, 88, 49, 6, 35, 107, 36, 49, 89, 35, 15, 49, 4, 125, 65, 65, 36, 50, 72, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 52, 80, 72, 0, 22, 3, 95, 57, 88, 6, 125, 107, 36, 49, 89, 35, 15, 49, 4, 125, 65, 65, 36, 50, 72, 0, 0, 8, 132, 13, 20, 195, 188, 17, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 66, 57, 64, 50, 6, 127, 47, 36, 49, 89, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 20, 66, 52, 112, 65, 4, 37, 61, 61, 37, 15, 81, 34, 6, 35, 65, 65, 37, 0, 24, 15, 66, 40, 208, 57, 4, 108, 15, 65, 6, 40, 117, 72, 0, 24, 0, 18, 67, 65, 34, 192, 48, 6, 36, 34, 111, 15, 49, 6, 39, 50, 72, 0, 24, 0, 0, 0, 0, 24, 67, 40, 213, 0, 57, 4, 108, 15, 65, 6, 40, 117, 72, 15, 47, 6, 36, 37, 89, 36, 72, 0, 24, 29, 67, 76, 82, 128, 89, 6, 115, 57, 40, 89, 15, 36, 55, 6, 36, 49, 47, 34, 37, 15, 57, 6, 35, 108, 65, 0, 42, 42, 0, 7, 196, 60, 194, 84, 20, 72, 0, 0, 0, 19, 67, 93, 67, 192, 84, 4, 110, 15, 47, 4, 110, 15, 6, 39, 115, 0, 42, 42, 0, 6, 195, 52, 147, 129, 72, 13, 4, 95, 48, 77, 52, 71, 37, 61, 57, 39, 50, 0, 0, 18, 67, 65, 35, 198, 48, 34, 4, 39, 83, 6, 36, 89, 130, 39, 34, 0, 24, 0, 13, 4, 95, 48, 77, 50, 65, 37, 61, 57, 39, 50, 0, 0, 14, 4, 95, 48, 77, 51, 65, 37, 61, 57, 35, 34, 72, 0, 0, 0, 12, 4, 95, 48, 77, 49, 47, 40, 107, 109, 47, 0, 0, 18, 66, 52, 128, 65, 6, 40, 117, 15, 107, 6, 40, 55, 81, 35, 89, 0, 24, 12, 66, 40, 224, 57, 6, 115, 67, 37, 89, 0, 24, 10, 4, 95, 2, 18, 22, 49, 108, 34, 0, 0, 0, 0, 0, 0, 0, 0, 14, 67, 65, 35, 0, 48, 34, 6, 36, 37, 55, 37, 0, 24, 0, 12, 66, 65, 32, 48, 34, 6, 39, 40, 35, 0, 24, 0, 0, 0, 0, 0, 18, 67, 56, 245, 128, 50, 4, 39, 84, 6, 36, 65, 65, 71, 36, 34, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 19, 46, 15, 89, 6, 36, 110, 15, 6, 39, 50, 50, 0, 24, 0, 0, 0, 0, 0, 18, 67, 65, 53, 0, 48, 6, 40, 37, 57, 36, 89, 15, 47, 4, 110, 0, 24, 0, 0, 0, 0, 17, 67, 44, 225, 0, 49, 4, 35, 67, 72, 37, 72, 6, 108, 47, 0, 24, 0, 0, 8, 197, 52, 147, 12, 20, 192, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 3, 195, 181, 1, 6, 119, 48, 12, 36, 15, 4, 108, 89, 47, 35, 0, 24, 0, 0, 16, 66, 52, 176, 65, 6, 108, 15, 49, 6, 39, 50, 50, 72, 0, 24, 0, 15, 67, 44, 241, 0, 49, 6, 39, 72, 109, 50, 37, 49, 0, 24, 0, 0, 8, 132, 22, 195, 181, 9, 72, 8, 0, 0, 16, 67, 76, 82, 192, 89, 6, 36, 49, 118, 50, 72, 37, 47, 0, 24, 0, 0, 0, 0, 0, 0, 0, 12, 4, 95, 3, 9, 18, 49, 35, 47, 40, 89, 0, 0, 21, 67, 28, 211, 192, 81, 6, 36, 110, 15, 4, 36, 65, 65, 15, 6, 39, 115, 0, 24, 42, 0, 0, 13, 67, 72, 35, 0, 34, 6, 40, 71, 55, 35, 0, 24, 0, 20, 66, 52, 192, 65, 4, 37, 61, 61, 37, 15, 55, 6, 112, 47, 34, 37, 47, 0, 24, 0, 17, 67, 52, 193, 0, 65, 6, 37, 61, 57, 35, 34, 72, 37, 47, 0, 24, 6, 195, 52, 148, 192, 76, 0, 0, 0, 0, 6, 195, 44, 84, 192, 76, 0, 21, 68, 76, 80, 76, 32, 89, 6, 36, 35, 55, 15, 107, 4, 40, 55, 81, 35, 89, 0, 24, 0, 26, 67, 77, 3, 0, 89, 6, 40, 48, 113, 15, 55, 4, 40, 89, 37, 49, 35, 15, 47, 6, 127, 47, 12, 0, 24, 0, 0, 0, 0, 12, 4, 95, 1, 3, 21, 35, 49, 6, 117, 47, 0, 0, 0, 0, 0, 0, 5, 194, 76, 16, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 195, 181, 16, 6, 119, 48, 111, 47, 4, 35, 57, 35, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 16, 67, 72, 69, 0, 34, 4, 35, 40, 72, 15, 47, 6, 110, 0, 24, 16, 67, 52, 229, 0, 65, 6, 108, 50, 15, 47, 6, 36, 110, 0, 24, 6, 131, 15, 195, 188, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 66, 60, 176, 39, 49, 6, 36, 112, 0, 5, 194, 80, 16, 72, 0, 0, 0, 0, 0, 11, 67, 88, 147, 12, 84, 6, 37, 55, 12, 0, 16, 67, 60, 181, 0, 4, 39, 49, 47, 6, 115, 71, 36, 34, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 68, 88, 81, 66, 72, 84, 6, 110, 71, 34, 40, 35, 34, 0, 24, 0, 0, 22, 66, 56, 224, 50, 6, 37, 112, 15, 50, 6, 37, 65, 36, 47, 4, 35, 47, 40, 72, 0, 24, 0, 13, 67, 52, 164, 128, 65, 6, 35, 57, 116, 34, 0, 24, 0, 0, 0, 0, 0, 0, 0, 12, 66, 81, 32, 47, 34, 6, 125, 49, 12, 0, 24, 20, 66, 77, 64, 89, 6, 36, 110, 15, 47, 6, 121, 107, 36, 50, 72, 35, 71, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 12, 2, 194, 164, 84, 35, 55, 6, 117, 47, 35, 0, 0, 0, 0, 10, 2, 194, 163, 50, 35, 110, 55, 35, 0, 0, 0, 0, 0, 0, 7, 2, 195, 164, 121, 122, 0, 0, 0, 0, 0, 19, 67, 16, 85, 19, 47, 4, 36, 47, 89, 6, 36, 65, 65, 71, 36, 34, 0, 24, 16, 2, 195, 160, 6, 35, 108, 15, 55, 108, 0, 24, 81, 108, 97, 32, 0, 0, 0, 0, 5, 194, 60, 224, 72, 0, 6, 195, 4, 32, 192, 17, 0, 7, 196, 88, 82, 68, 36, 72, 0, 0, 0, 0, 7, 2, 195, 182, 123, 124, 0, 0, 0, 0, 7, 2, 195, 181, 119, 120, 0, 0, 11, 4, 95, 3, 5, 4, 89, 36, 72, 112, 0, 0, 0, 15, 70, 100, 241, 200, 85, 37, 0, 57, 39, 81, 40, 34, 47, 0, 0, 8, 2, 197, 161, 91, 35, 108, 0, 0, 0, 15, 67, 80, 83, 0, 47, 6, 36, 55, 111, 83, 39, 50, 0, 24, 0, 5, 194, 80, 80, 72, 7, 2, 195, 188, 125, 126, 0, 0, 16, 67, 80, 194, 192, 47, 6, 119, 61, 49, 37, 50, 40, 72, 0, 24, 0, 6, 195, 80, 82, 69, 72, 0, 0, 0, 11, 67, 33, 83, 12, 107, 6, 40, 55, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 60, 194, 77, 20, 72, 6, 195, 80, 83, 65, 72, 8, 2, 197, 190, 90, 36, 110, 0, 0, 0, 19, 66, 76, 128, 89, 6, 36, 35, 55, 15, 107, 4, 40, 55, 81, 35, 89, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 67, 89, 33, 0, 84, 6, 119, 34, 34, 72, 55, 36, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 56, 82, 76, 20, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 67, 44, 243, 142, 49, 6, 39, 50, 12, 0, 0, 0, 8, 195, 85, 48, 64, 17, 42, 42, 0, 0, 0, 12, 66, 89, 64, 84, 6, 35, 108, 47, 35, 0, 24, 7, 194, 85, 96, 17, 42, 42, 0, 6, 195, 37, 49, 64, 72, 0, 0, 0, 0, 0, 0, 0, 16, 66, 92, 48, 84, 6, 36, 110, 15, 47, 89, 6, 36, 110, 0, 24, 0, 17, 67, 65, 66, 192, 48, 4, 36, 35, 15, 47, 6, 125, 49, 12, 0, 24, 14, 3, 1, 195, 188, 6, 35, 108, 15, 6, 125, 126, 0, 24, 0, 0, 0, 0, 12, 2, 95, 35, 47, 34, 36, 61, 61, 37, 72, 0, 0, 15, 2, 95, 34, 57, 40, 47, 118, 65, 4, 121, 34, 49, 12, 0, 0, 16, 2, 95, 33, 107, 129, 12, 57, 40, 65, 4, 121, 34, 49, 12, 0, 0, 0, 13, 2, 95, 39, 125, 55, 109, 15, 49, 39, 65, 35, 0, 0, 7, 195, 56, 147, 135, 72, 8, 16, 2, 95, 38, 57, 6, 35, 108, 15, 65, 4, 121, 34, 49, 12, 0, 0, 15, 2, 95, 37, 48, 34, 39, 47, 89, 36, 50, 47, 12, 0, 66, 15, 2, 95, 37, 48, 34, 39, 47, 89, 6, 36, 50, 47, 12, 0, 0, 12, 2, 95, 36, 47, 39, 55, 12, 55, 35, 34, 0, 0, 0, 10, 4, 95, 3, 1, 16, 89, 117, 34, 0, 0, 18, 2, 95, 41, 55, 119, 48, 36, 47, 35, 84, 15, 89, 40, 55, 12, 81, 0, 0, 18, 2, 95, 40, 35, 55, 118, 89, 47, 35, 84, 15, 89, 40, 55, 12, 81, 0, 0, 0, 11, 2, 95, 46, 48, 40, 50, 49, 12, 47, 0, 0, 10, 2, 95, 45, 49, 34, 112, 48, 89, 0, 0, 9, 2, 95, 44, 49, 39, 65, 109, 0, 0, 14, 67, 53, 36, 192, 65, 6, 37, 131, 131, 37, 89, 0, 24, 11, 2, 95, 51, 49, 6, 39, 55, 12, 65, 0, 0, 11, 2, 95, 50, 49, 6, 35, 49, 12, 89, 0, 0, 10, 2, 95, 49, 6, 125, 49, 12, 89, 0, 0, 11, 2, 95, 48, 50, 6, 40, 55, 12, 55, 0, 0, 12, 2, 95, 55, 89, 6, 36, 37, 47, 89, 36, 0, 0, 10, 2, 95, 54, 49, 6, 40, 117, 89, 0, 0, 10, 2, 95, 53, 84, 6, 37, 112, 89, 0, 0, 10, 2, 95, 52, 50, 6, 36, 55, 113, 0, 0, 0, 10, 2, 95, 58, 49, 115, 55, 39, 50, 0, 0, 12, 2, 95, 57, 6, 125, 107, 36, 49, 89, 35, 0, 0, 12, 66, 80, 176, 47, 6, 125, 49, 12, 37, 0, 24, 13, 2, 95, 56, 49, 6, 35, 107, 36, 49, 89, 35, 0, 0, 15, 2, 95, 63, 49, 125, 131, 113, 65, 4, 121, 34, 49, 12, 0, 0, 10, 2, 95, 62, 89, 117, 34, 36, 65, 0, 0, 0, 12, 2, 95, 60, 84, 127, 49, 12, 89, 36, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 67, 76, 225, 0, 89, 6, 125, 67, 67, 72, 37, 50, 40, 72, 0, 24, 0, 0, 8, 195, 16, 224, 64, 17, 42, 42, 0, 0, 0, 0, 0, 0, 0, 0, 21, 67, 20, 177, 192, 6, 36, 110, 15, 49, 4, 35, 108, 15, 81, 6, 36, 110, 0, 24, 42, 0, 0, 0, 0, 31, 2, 95, 91, 6, 35, 55, 118, 89, 47, 35, 84, 15, 49, 6, 35, 50, 72, 37, 62, 37, 50, 36, 15, 89, 6, 40, 55, 12, 81, 0, 0, 11, 4, 95, 226, 130, 172, 36, 40, 34, 39, 0, 0, 0, 0, 14, 2, 95, 95, 35, 55, 12, 55, 49, 34, 112, 48, 89, 0, 0, 0, 32, 2, 95, 93, 55, 6, 119, 48, 36, 47, 35, 84, 15, 49, 6, 35, 50, 72, 37, 55, 4, 37, 50, 36, 15, 89, 6, 40, 55, 12, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 66, 80, 224, 47, 6, 121, 50, 109, 84, 0, 24, 13, 4, 95, 7, 18, 22, 81, 34, 108, 84, 37, 89, 0, 0, 0, 0, 0, 0, 17, 67, 64, 212, 192, 48, 6, 36, 35, 65, 37, 89, 36, 55, 47, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 95, 4, 9, 1, 47, 121, 48, 37, 72, 0, 30, 2, 95, 123, 35, 55, 118, 89, 47, 35, 84, 15, 55, 6, 115, 81, 36, 55, 4, 37, 50, 36, 15, 89, 6, 40, 55, 12, 81, 0, 0, 0, 0, 0, 0, 0, 30, 2, 95, 125, 55, 119, 48, 36, 47, 35, 84, 15, 55, 6, 115, 81, 36, 55, 4, 37, 50, 36, 15, 89, 6, 40, 55, 12, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 35, 51, 50, 47, 6, 125, 107, 37, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 67, 52, 195, 128, 65, 6, 37, 61, 57, 39, 50, 37, 47, 0, 24, 8, 195, 5, 67, 64, 17, 42, 42, 0, 0, 0, 0, 0, 7, 196, 60, 193, 77, 20, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 5, 13, 195, 164, 19, 19, 65, 6, 121, 89, 12, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 67, 8, 32, 192, 71, 4, 112, 15, 71, 4, 112, 15, 89, 6, 37, 112, 0, 42, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 195, 164, 19, 19, 6, 121, 89, 12, 89, 0, 0, 0, 0, 0, 0, 6, 195, 52, 82, 69, 72, 0, 0, 0, 0, 0, 18, 67, 44, 130, 192, 49, 4, 37, 107, 111, 55, 49, 6, 39, 50, 72, 0, 24, 0, 7, 196, 60, 193, 84, 20, 72, 0, 0, 0, 11, 67, 76, 149, 20, 89, 6, 37, 47, 12, 0, 0, 0, 0, 9, 198, 60, 193, 75, 76, 147, 128, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 195, 5, 69, 128, 17, 42, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 18, 66, 105, 0, 106, 0, 7, 6, 18, 67, 98, 0, 100, 0, 102, 0, 103, 0, 104, 0, 106, 0, 108, 0, 109, 0, 110, 0, 114, 0, 115, 0, 118, 0, 7, 6, 18, 68, 108, 0, 109, 0, 110, 0, 114, 0, 7, 6, 18, 69, 195, 181, 0, 195, 164, 0, 195, 182, 0, 195, 188, 0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0, 103, 0, 104, 0, 105, 0, 106, 0, 107, 0, 108, 0, 109, 0, 110, 0, 111, 0, 112, 0, 113, 0, 114, 0, 115, 0, 116, 0, 117, 0, 118, 0, 7, 6, 18, 70, 195, 181, 0, 195, 164, 0, 195, 182, 0, 195, 188, 0, 97, 0, 101, 0, 105, 0, 108, 0, 109, 0, 110, 0, 111, 0, 114, 0, 117, 0, 7, 6, 195, 164, 0, 101, 2, 32, 3, 6, 121, 110, 0, 111, 3, 6, 121, 115, 0, 117, 2, 32, 3, 6, 121, 117, 0, 4, 195, 164, 1, 29, 2, 18, 67, 32, 3, 6, 121, 122, 0, 195, 164, 1, 29, 2, 32, 0, 195, 164, 3, 6, 122, 0, 105, 2, 32, 3, 6, 127, 12, 0, 3, 121, 0, 105, 3, 127, 0, 7, 6, 195, 181, 0, 97, 3, 6, 119, 108, 0, 101, 2, 32, 3, 6, 119, 110, 0, 105, 2, 32, 3, 6, 119, 112, 0, 111, 3, 6, 119, 115, 0, 117, 2, 32, 3, 6, 119, 117, 0, 4, 195, 181, 1, 29, 2, 18, 67, 32, 3, 6, 119, 120, 0, 195, 181, 1, 29, 2, 32, 0, 195, 181, 3, 6, 120, 0, 3, 119, 0, 117, 3, 119, 40, 0, 7, 6, 195, 182, 0, 97, 3, 6, 123, 108, 0, 101, 3, 6, 123, 110, 0, 4, 195, 182, 1, 29, 2, 18, 67, 32, 3, 6, 123, 124, 0, 195, 182, 1, 29, 2, 32, 0, 195, 182, 3, 6, 124, 0, 3, 123, 0, 105, 3, 128, 0, 7, 6, 195, 188, 0, 4, 195, 188, 1, 29, 2, 18, 67, 32, 3, 6, 125, 126, 0, 195, 188, 1, 29, 2, 32, 0, 195, 188, 3, 6, 126, 0, 3, 125, 0, 109, 98, 114, 105, 3, 125, 65, 71, 34, 37, 0, 4, 105, 3, 129, 0, 195, 188, 2, 106, 97, 0, 195, 188, 2, 97, 3, 129, 57, 0, 7, 6, 97, 0, 4, 97, 1, 29, 2, 18, 67, 32, 3, 6, 35, 108, 0, 97, 1, 29, 2, 32, 0, 101, 2, 32, 3, 6, 35, 110, 0, 105, 2, 32, 3, 6, 35, 112, 0, 111, 3, 6, 35, 115, 0, 117, 2, 32, 3, 6, 35, 117, 0, 97, 3, 6, 108, 0, 3, 35, 0, 109, 98, 105, 3, 35, 65, 71, 37, 0, 1, 105, 17, 65, 3, 57, 35, 0, 4, 1, 117, 97, 3, 58, 35, 0, 1, 117, 117, 0, 1, 117, 181, 195, 0, 4, 8, 18, 67, 17, 65, 2, 25, 3, 109, 0, 8, 18, 67, 17, 65, 17, 67, 2, 25, 0, 7, 6, 98, 0, 8, 3, 48, 0, 3, 71, 0, 7, 6, 99, 0, 4, 2, 101, 3, 47, 89, 0, 2, 105, 0, 3, 49, 0, 104, 8, 3, 76, 0, 8, 2, 101, 3, 89, 0, 105, 116, 121, 3, 89, 37, 47, 37, 0, 7, 6, 100, 0, 8, 3, 47, 0, 4, 3, 72, 0, 1, 21, 21, 2, 18, 66, 0, 1, 25, 2, 18, 66, 0, 1, 10, 2, 18, 66, 3, 133, 0, 7, 6, 101, 0, 97, 2, 32, 3, 6, 36, 108, 0, 4, 101, 1, 29, 2, 18, 67, 32, 3, 6, 36, 110, 0, 101, 1, 29, 2, 32, 0, 105, 2, 32, 3, 6, 36, 112, 0, 111, 3, 6, 36, 115, 0, 101, 3, 6, 110, 0, 3, 36, 0, 1, 105, 17, 65, 3, 57, 36, 0, 4, 1, 117, 97, 3, 58, 36, 0, 1, 117, 117, 0, 1, 117, 181, 195, 0, 4, 8, 18, 67, 17, 65, 2, 25, 3, 111, 0, 8, 18, 67, 17, 65, 17, 67, 2, 25, 0, 7, 6, 102, 0, 3, 83, 0, 7, 6, 103, 0, 8, 3, 49, 0, 3, 81, 0, 7, 6, 104, 0, 3, 107, 0, 1, 97, 108, 2, 116, 105, 3, 107, 107, 0, 7, 6, 105, 0, 4, 105, 1, 29, 2, 18, 67, 32, 3, 6, 37, 112, 0, 105, 1, 29, 2, 32, 0, 105, 3, 6, 112, 0, 3, 37, 0, 4, 8, 18, 67, 17, 65, 2, 25, 3, 113, 0, 8, 18, 67, 17, 65, 17, 67, 2, 25, 0, 7, 6, 106, 0, 97, 122, 122, 3, 47, 90, 121, 89, 12, 0, 3, 57, 0, 106, 3, 57, 12, 0, 117, 109, 98, 117, 3, 57, 40, 65, 71, 40, 0, 7, 6, 107, 0, 3, 49, 0, 97, 117, 103, 101, 3, 49, 6, 35, 117, 81, 36, 0, 4, 1, 17, 65, 2, 18, 68, 3, 49, 12, 0, 1, 17, 65, 17, 65, 2, 18, 70, 0, 1, 18, 68, 17, 65, 2, 18, 70, 0, 107, 0, 97, 109, 98, 97, 3, 49, 35, 65, 71, 35, 0, 105, 109, 98, 97, 116, 117, 115, 3, 49, 37, 65, 71, 35, 47, 40, 89, 0, 105, 109, 98, 117, 3, 49, 37, 65, 71, 40, 0, 7, 6, 108, 0, 4, 3, 55, 0, 1, 21, 21, 2, 18, 66, 0, 1, 25, 2, 18, 66, 0, 4, 108, 1, 21, 21, 2, 105, 3, 55, 12, 0, 108, 1, 25, 2, 105, 0, 4, 1, 10, 2, 18, 66, 3, 61, 0, 1, 10, 2, 100, 18, 66, 0, 1, 10, 2, 103, 18, 66, 0, 1, 10, 2, 107, 18, 66, 0, 1, 10, 2, 110, 105, 0, 1, 10, 2, 115, 11, 105, 0, 1, 10, 2, 115, 105, 0, 1, 10, 2, 116, 105, 0, 2, 115, 115, 32, 0, 108, 1, 10, 2, 105, 3, 61, 12, 0, 108, 1, 17, 65, 2, 32, 3, 114, 61, 12, 0, 7, 6, 109, 0, 4, 3, 65, 0, 1, 10, 2, 98, 17, 65, 11, 0, 1, 10, 2, 98, 3, 65, 65, 0, 7, 6, 110, 0, 4, 3, 50, 0, 1, 17, 65, 10, 2, 108, 18, 66, 0, 1, 21, 21, 2, 18, 66, 0, 1, 25, 2, 18, 66, 0, 110, 1, 105, 2, 32, 3, 50, 12, 0, 4, 110, 1, 17, 65, 21, 2, 32, 3, 50, 50, 0, 110, 1, 21, 21, 2, 105, 0, 110, 1, 25, 2, 105, 0, 4, 1, 10, 2, 18, 66, 3, 67, 0, 1, 10, 2, 100, 18, 66, 0, 1, 10, 2, 115, 105, 0, 1, 10, 2, 116, 32, 0, 1, 10, 2, 116, 105, 0, 2, 115, 116, 32, 0, 110, 1, 10, 2, 105, 3, 67, 12, 0, 4, 2, 32, 103, 3, 68, 0, 2, 32, 107, 0, 2, 103, 0, 2, 107, 0, 110, 1, 17, 65, 2, 32, 3, 114, 67, 12, 0, 7, 6, 111, 0, 97, 3, 6, 39, 108, 0, 101, 2, 32, 3, 6, 39, 110, 0, 105, 2, 32, 3, 6, 39, 112, 0, 4, 111, 1, 29, 2, 18, 67, 32, 3, 6, 39, 115, 0, 111, 1, 29, 2, 32, 0, 111, 3, 6, 115, 0, 4, 3, 39, 0, 1, 105, 105, 0, 1, 105, 17, 65, 3, 57, 39, 0, 4, 8, 18, 67, 17, 65, 2, 25, 3, 116, 0, 8, 18, 67, 17, 65, 17, 67, 2, 25, 0, 7, 6, 112, 0, 3, 48, 0, 4, 1, 17, 65, 17, 65, 2, 18, 70, 3, 48, 12, 0, 1, 18, 68, 17, 65, 2, 32, 0, 112, 0, 7, 6, 113, 0, 3, 49, 0, 113, 3, 49, 12, 0, 117, 3, 49, 84, 0, 7, 6, 114, 0, 3, 34, 0, 4, 1, 101, 107, 2, 103, 101, 3, 51, 51, 0, 1, 181, 195, 107, 2, 103, 101, 0, 114, 0, 7, 6, 115, 0, 4, 3, 89, 0, 1, 10, 2, 108, 18, 66, 0, 1, 10, 2, 110, 18, 66, 0, 1, 21, 21, 2, 18, 66, 0, 1, 25, 2, 18, 66, 0, 195, 188, 109, 98, 111, 108, 105, 115, 101, 101, 114, 3, 89, 4, 125, 65, 71, 39, 55, 37, 89, 6, 110, 34, 0, 111, 109, 98, 117, 3, 89, 39, 65, 71, 40, 0, 4, 115, 1, 21, 21, 2, 105, 3, 89, 89, 0, 115, 1, 25, 2, 105, 0, 115, 3, 89, 130, 0, 4, 99, 104, 1, 25, 3, 91, 0, 104, 1, 25, 0, 115, 1, 17, 65, 2, 32, 3, 114, 131, 12, 0, 4, 1, 10, 2, 18, 66, 3, 131, 0, 1, 10, 2, 100, 105, 0, 1, 17, 65, 2, 116, 105, 0, 115, 1, 10, 2, 105, 3, 131, 131, 0, 7, 6, 116, 0, 4, 3, 47, 0, 1, 21, 21, 2, 18, 66, 0, 1, 21, 21, 2, 115, 105, 0, 1, 25, 2, 18, 66, 0, 4, 1, 17, 65, 2, 18, 68, 3, 47, 12, 0, 1, 17, 65, 17, 65, 2, 18, 70, 0, 1, 97, 109, 10, 2, 97, 32, 0, 116, 0, 116, 1, 21, 21, 2, 105, 0, 116, 1, 25, 2, 105, 0, 97, 109, 98, 117, 3, 47, 35, 65, 71, 40, 0, 117, 109, 98, 97, 3, 47, 40, 65, 71, 35, 0, 1, 17, 65, 10, 2, 115, 105, 3, 114, 132, 0, 116, 1, 17, 65, 29, 2, 32, 3, 114, 132, 12, 0, 4, 1, 10, 2, 18, 66, 3, 132, 0, 1, 10, 2, 108, 18, 66, 0, 1, 10, 2, 110, 18, 66, 0, 116, 1, 10, 2, 105, 3, 132, 12, 0, 7, 6, 117, 0, 105, 2, 32, 3, 6, 40, 112, 0, 4, 117, 1, 29, 2, 18, 67, 32, 3, 6, 40, 117, 0, 117, 1, 29, 2, 32, 0, 117, 3, 6, 117, 0, 4, 3, 40, 0, 1, 105, 105, 0, 1, 105, 17, 65, 3, 57, 40, 0, 4, 8, 18, 67, 17, 65, 2, 25, 3, 118, 0, 8, 18, 67, 17, 65, 17, 67, 2, 25, 0, 7, 6, 118, 0, 3, 84, 0, 97, 98, 97, 114, 105, 105, 3, 84, 6, 35, 71, 35, 34, 4, 37, 37, 0, 101, 109, 98, 117, 3, 84, 36, 65, 71, 40, 0, 7, 6, 119, 0, 3, 84, 0, 7, 6, 120, 0, 120, 3, 49, 12, 89, 0, 3, 49, 89, 0, 7, 6, 121, 0, 3, 37, 0, 105, 3, 57, 37, 0, 121, 3, 126, 0, 7, 6, 122, 0, 122, 3, 47, 89, 0, 3, 88, 0, 104, 1, 25, 3, 90, 0, 7, 6, 0, 4, 45, 1, 32, 17, 65, 2, 32, 15, 3, 10, 0, 45, 1, 32, 17, 67, 2, 32, 15, 0, 45, 8, 32, 2, 32, 15, 3, 65, 112, 50, 40, 89, 0, 197, 190, 3, 90, 0, 197, 161, 3, 91, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts17 = FileInMemory_createWithData (6777, reinterpret_cast (&espeakdata_dicts17_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/et_dict", U"et"); Collection_addItem (me.peek(), espeakdata_dicts17.transfer()); static unsigned char espeakdata_dicts18_data[5131] = { 0, 4, 0, 0, 161, 16, 0, 0, 9, 198, 48, 145, 78, 20, 211, 69, 72, 0, 0, 0, 13, 67, 57, 35, 192, 50, 40, 65, 36, 34, 39, 0, 24, 0, 0, 6, 65, 4, 35, 12, 0, 0, 10, 135, 20, 195, 164, 12, 20, 195, 164, 76, 0, 0, 6, 195, 52, 83, 133, 19, 7, 196, 48, 21, 83, 20, 19, 0, 7, 65, 8, 71, 36, 12, 0, 0, 0, 16, 67, 21, 64, 192, 36, 47, 10, 89, 36, 47, 36, 34, 35, 0, 24, 0, 0, 7, 65, 12, 89, 36, 12, 0, 0, 0, 0, 0, 7, 65, 16, 72, 36, 12, 0, 0, 0, 0, 7, 196, 81, 83, 206, 4, 76, 0, 6, 65, 20, 36, 12, 0, 0, 0, 0, 0, 6, 65, 24, 109, 83, 0, 0, 0, 0, 0, 8, 197, 56, 242, 76, 48, 80, 76, 7, 65, 28, 81, 36, 12, 0, 0, 0, 0, 7, 196, 40, 243, 139, 4, 76, 0, 7, 65, 32, 107, 39, 12, 0, 0, 0, 0, 6, 195, 60, 148, 133, 19, 7, 196, 40, 243, 12, 4, 76, 7, 195, 37, 68, 197, 76, 19, 0, 6, 65, 36, 37, 12, 0, 0, 14, 1, 37, 48, 34, 39, 89, 36, 50, 47, 12, 108, 0, 27, 13, 1, 37, 48, 34, 39, 89, 36, 50, 47, 12, 37, 0, 0, 17, 70, 44, 243, 134, 85, 68, 197, 49, 39, 50, 83, 40, 47, 89, 36, 0, 7, 1, 38, 10, 36, 47, 0, 0, 0, 8, 197, 81, 83, 200, 60, 224, 76, 7, 65, 40, 57, 37, 12, 0, 0, 0, 14, 1, 42, 35, 89, 47, 36, 34, 37, 89, 49, 37, 0, 27, 0, 9, 1, 43, 48, 55, 40, 89, 0, 27, 0, 7, 65, 44, 49, 39, 12, 0, 0, 0, 0, 9, 1, 47, 49, 122, 47, 12, 35, 0, 0, 6, 65, 48, 109, 55, 0, 0, 0, 0, 12, 68, 64, 243, 12, 20, 48, 39, 55, 55, 36, 0, 7, 196, 40, 243, 12, 20, 76, 0, 6, 65, 52, 109, 65, 0, 0, 0, 0, 0, 6, 65, 56, 109, 50, 0, 0, 0, 0, 0, 6, 65, 60, 39, 12, 0, 0, 14, 1, 61, 6, 114, 107, 47, 109, 49, 6, 120, 50, 0, 27, 0, 0, 0, 7, 1, 64, 10, 109, 47, 0, 7, 65, 64, 48, 36, 12, 0, 0, 0, 0, 7, 196, 81, 83, 212, 4, 76, 0, 7, 65, 68, 49, 40, 12, 0, 0, 0, 0, 0, 6, 65, 72, 109, 34, 0, 0, 0, 0, 0, 6, 65, 76, 109, 89, 0, 0, 0, 0, 0, 7, 65, 80, 47, 36, 12, 0, 0, 0, 0, 12, 68, 64, 83, 12, 20, 48, 36, 55, 55, 36, 0, 0, 6, 65, 84, 40, 12, 0, 0, 0, 0, 0, 7, 65, 88, 84, 36, 12, 0, 0, 0, 0, 16, 4, 95, 49, 77, 52, 71, 6, 37, 55, 57, 39, 12, 50, 35, 0, 0, 8, 197, 60, 194, 77, 52, 80, 72, 8, 133, 13, 9, 14, 195, 164, 72, 8, 1, 92, 49, 36, 50, 39, 0, 13, 65, 92, 49, 35, 49, 89, 117, 89, 84, 36, 12, 0, 0, 0, 0, 0, 13, 4, 95, 49, 77, 49, 47, 6, 40, 107, 35, 47, 0, 7, 65, 96, 109, 49, 89, 0, 0, 6, 194, 4, 64, 17, 24, 16, 4, 95, 49, 77, 50, 65, 6, 37, 55, 57, 39, 12, 50, 35, 0, 0, 16, 4, 95, 49, 77, 51, 65, 6, 37, 55, 57, 35, 34, 72, 37, 0, 0, 7, 196, 81, 83, 210, 20, 19, 7, 196, 40, 243, 20, 4, 76, 0, 6, 65, 100, 114, 12, 0, 0, 0, 0, 0, 8, 65, 104, 47, 89, 36, 47, 0, 0, 0, 0, 0, 0, 16, 70, 77, 84, 193, 56, 225, 64, 89, 40, 89, 35, 50, 50, 36, 0, 0, 0, 0, 0, 6, 194, 12, 16, 17, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, 126, 47, 37, 55, 72, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 68, 52, 19, 142, 20, 65, 35, 50, 50, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 68, 32, 147, 12, 20, 107, 37, 55, 55, 36, 0, 7, 196, 65, 84, 146, 4, 19, 0, 0, 0, 0, 0, 8, 197, 56, 242, 83, 80, 16, 76, 0, 0, 0, 7, 196, 60, 195, 21, 80, 72, 7, 196, 40, 244, 211, 4, 76, 0, 0, 0, 0, 11, 67, 4, 227, 133, 35, 50, 50, 36, 0, 41, 0, 0, 0, 0, 12, 68, 72, 148, 212, 36, 51, 37, 89, 47, 108, 0, 7, 196, 40, 244, 212, 4, 76, 0, 0, 0, 0, 12, 68, 40, 19, 142, 20, 57, 35, 50, 50, 36, 0, 0, 0, 0, 0, 7, 196, 65, 82, 197, 4, 19, 0, 0, 0, 0, 0, 0, 0, 0, 12, 68, 56, 19, 12, 20, 50, 35, 55, 55, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 135, 14, 195, 164, 9, 20, 195, 164, 76, 0, 0, 0, 0, 0, 12, 68, 72, 20, 212, 36, 51, 35, 89, 47, 108, 0, 12, 68, 44, 244, 212, 36, 49, 39, 89, 47, 108, 0, 0, 0, 0, 6, 195, 80, 16, 64, 19, 0, 12, 68, 32, 19, 142, 20, 107, 35, 50, 50, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 68, 92, 147, 12, 20, 84, 37, 55, 55, 36, 0, 12, 68, 88, 147, 12, 20, 84, 37, 55, 55, 36, 0, 12, 68, 44, 19, 12, 20, 49, 35, 55, 55, 36, 0, 0, 8, 197, 40, 242, 76, 48, 16, 76, 8, 197, 56, 242, 76, 80, 16, 76, 0, 0, 7, 195, 80, 18, 64, 72, 8, 0, 13, 4, 95, 4, 16, 20, 48, 37, 55, 49, 12, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 95, 20, 12, 4, 47, 37, 55, 72, 36, 0, 12, 3, 95, 35, 57, 89, 35, 34, 49, 115, 50, 0, 0, 8, 197, 56, 242, 72, 36, 224, 76, 0, 0, 0, 0, 0, 5, 194, 21, 64, 72, 0, 0, 0, 8, 197, 60, 194, 86, 5, 64, 72, 0, 0, 0, 0, 0, 0, 0, 7, 196, 49, 83, 196, 20, 19, 0, 8, 197, 60, 193, 84, 80, 80, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 20, 195, 164, 13, 195, 164, 76, 0, 0, 9, 67, 60, 176, 89, 39, 49, 118, 0, 0, 0, 0, 0, 0, 12, 68, 64, 244, 212, 36, 48, 39, 89, 47, 108, 0, 0, 0, 0, 0, 0, 0, 11, 136, 14, 195, 164, 9, 20, 20, 5, 14, 76, 0, 0, 0, 0, 0, 0, 0, 0, 17, 66, 20, 112, 36, 89, 37, 65, 36, 34, 49, 37, 49, 89, 37, 0, 24, 0, 0, 0, 8, 197, 40, 242, 76, 48, 80, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 88, 83, 133, 19, 7, 195, 60, 195, 1, 72, 19, 9, 198, 56, 242, 84, 80, 83, 128, 76, 0, 0, 0, 17, 70, 65, 35, 205, 36, 195, 5, 48, 51, 39, 65, 108, 55, 55, 36, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 40, 242, 15, 56, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 20, 144, 72, 0, 0, 12, 68, 28, 19, 12, 20, 81, 35, 55, 55, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 20, 195, 164, 14, 195, 164, 76, 0, 0, 0, 0, 0, 6, 195, 60, 194, 84, 72, 0, 11, 136, 14, 195, 164, 9, 19, 19, 195, 164, 76, 0, 0, 0, 0, 0, 0, 0, 7, 195, 40, 225, 64, 17, 24, 9, 3, 226, 130, 172, 124, 34, 39, 0, 10, 3, 226, 130, 172, 124, 34, 39, 35, 0, 0, 0, 0, 15, 7, 18, 25, 195, 182, 19, 20, 9, 51, 132, 89, 47, 108, 0, 0, 7, 195, 60, 193, 64, 72, 19, 0, 0, 0, 6, 194, 40, 16, 72, 8, 5, 194, 32, 80, 72, 0, 17, 8, 16, 195, 164, 195, 164, 19, 20, 9, 48, 109, 12, 89, 47, 108, 0, 0, 0, 23, 73, 76, 148, 139, 85, 52, 5, 48, 193, 64, 89, 37, 51, 49, 40, 89, 48, 36, 55, 55, 36, 0, 0, 0, 6, 195, 60, 194, 64, 72, 0, 0, 0, 6, 195, 36, 131, 69, 19, 0, 0, 0, 6, 195, 60, 194, 78, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 56, 242, 68, 20, 224, 76, 0, 0, 0, 0, 16, 69, 100, 241, 213, 73, 64, 57, 39, 81, 40, 34, 47, 12, 37, 0, 0, 0, 0, 0, 9, 198, 60, 194, 83, 37, 69, 5, 72, 0, 6, 194, 20, 208, 17, 24, 0, 0, 0, 6, 195, 60, 193, 78, 72, 0, 0, 0, 0, 8, 197, 81, 83, 211, 80, 16, 76, 0, 0, 6, 195, 60, 193, 84, 72, 0, 0, 0, 0, 0, 0, 0, 5, 194, 20, 224, 72, 0, 6, 195, 61, 64, 64, 19, 20, 3, 95, 51, 88, 49, 6, 39, 55, 65, 36, 49, 114, 65, 65, 36, 50, 47, 109, 0, 0, 13, 3, 95, 48, 67, 89, 6, 35, 47, 35, 12, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 49, 67, 89, 6, 35, 47, 35, 0, 0, 0, 0, 0, 0, 0, 6, 195, 4, 146, 5, 19, 21, 3, 95, 49, 57, 6, 114, 107, 72, 36, 49, 89, 109, 50, 47, 4, 117, 89, 47, 35, 0, 0, 22, 3, 95, 49, 56, 49, 6, 35, 107, 72, 36, 49, 89, 35, 50, 47, 4, 117, 89, 47, 35, 0, 0, 0, 0, 0, 0, 0, 8, 197, 44, 146, 78, 56, 144, 19, 8, 197, 81, 83, 211, 76, 16, 76, 0, 16, 3, 95, 49, 49, 6, 114, 49, 89, 37, 47, 117, 89, 47, 35, 0, 0, 6, 195, 57, 83, 192, 76, 15, 3, 95, 49, 48, 49, 6, 114, 65, 65, 36, 50, 36, 50, 0, 0, 17, 3, 95, 49, 51, 49, 6, 39, 55, 65, 36, 47, 117, 89, 47, 35, 0, 0, 17, 3, 95, 49, 50, 49, 6, 35, 49, 89, 37, 47, 117, 89, 47, 35, 0, 0, 15, 7, 11, 25, 195, 182, 19, 20, 9, 49, 132, 89, 47, 108, 0, 17, 3, 95, 49, 53, 84, 6, 37, 12, 89, 37, 47, 117, 89, 47, 35, 0, 0, 17, 3, 95, 49, 52, 50, 6, 36, 55, 57, 109, 47, 117, 89, 47, 35, 0, 0, 21, 3, 95, 49, 55, 89, 6, 118, 47, 89, 36, 65, 109, 50, 47, 4, 117, 89, 47, 35, 0, 0, 17, 3, 95, 49, 54, 49, 6, 40, 12, 89, 37, 47, 117, 89, 47, 35, 0, 0, 0, 10, 135, 20, 195, 164, 19, 19, 195, 164, 76, 24, 3, 95, 55, 88, 89, 6, 118, 47, 89, 36, 65, 109, 68, 49, 4, 114, 65, 65, 36, 50, 47, 109, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 40, 245, 1, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 3, 95, 50, 88, 49, 6, 35, 49, 89, 37, 49, 114, 65, 65, 36, 50, 47, 109, 0, 0, 0, 0, 0, 0, 11, 136, 14, 195, 164, 9, 12, 12, 195, 164, 76, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 63, 63, 65, 6, 36, 34, 49, 12, 108, 0, 0, 0, 0, 20, 3, 95, 52, 88, 50, 6, 36, 55, 57, 109, 49, 114, 65, 65, 36, 50, 47, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 3, 95, 53, 88, 84, 6, 37, 12, 89, 37, 49, 114, 65, 65, 36, 50, 47, 109, 0, 0, 0, 8, 197, 40, 242, 76, 80, 16, 76, 0, 0, 0, 0, 0, 0, 20, 3, 95, 54, 88, 49, 6, 40, 12, 89, 37, 49, 114, 65, 65, 36, 50, 47, 109, 0, 0, 0, 0, 0, 0, 0, 10, 135, 20, 195, 164, 8, 195, 164, 14, 76, 0, 0, 10, 135, 20, 195, 164, 12, 12, 195, 164, 76, 10, 135, 20, 195, 164, 19, 20, 195, 164, 76, 0, 7, 196, 61, 65, 84, 4, 19, 0, 0, 0, 0, 7, 196, 65, 81, 84, 4, 19, 0, 0, 10, 135, 14, 195, 164, 9, 12, 12, 5, 76, 0, 25, 3, 95, 56, 88, 49, 6, 35, 107, 72, 36, 49, 89, 35, 68, 49, 4, 114, 65, 65, 36, 50, 47, 109, 0, 0, 0, 0, 7, 132, 8, 195, 164, 14, 72, 0, 0, 0, 0, 5, 194, 52, 80, 72, 0, 24, 3, 95, 57, 88, 6, 114, 107, 72, 36, 49, 89, 109, 68, 49, 4, 114, 65, 65, 36, 50, 47, 109, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 45, 144, 17, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 136, 14, 195, 164, 9, 19, 20, 195, 164, 76, 0, 7, 196, 81, 83, 12, 4, 19, 0, 0, 0, 0, 7, 196, 81, 83, 142, 20, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 56, 80, 72, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 61, 48, 17, 24, 0, 0, 6, 195, 40, 243, 129, 76, 17, 4, 95, 48, 77, 52, 71, 6, 37, 55, 57, 39, 12, 50, 35, 12, 0, 0, 0, 17, 4, 95, 48, 77, 50, 65, 6, 37, 55, 57, 39, 12, 50, 35, 12, 0, 0, 17, 4, 95, 48, 77, 51, 65, 6, 37, 55, 57, 35, 34, 72, 37, 35, 0, 0, 0, 15, 4, 95, 48, 77, 49, 47, 6, 40, 107, 35, 47, 12, 35, 0, 0, 13, 4, 95, 2, 18, 22, 71, 34, 6, 36, 84, 36, 0, 0, 0, 7, 196, 40, 242, 84, 4, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 14, 195, 164, 13, 195, 164, 76, 0, 0, 0, 0, 0, 6, 195, 4, 160, 64, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 48, 145, 78, 21, 64, 72, 0, 0, 9, 198, 48, 145, 78, 21, 69, 5, 72, 0, 6, 195, 40, 242, 193, 76, 0, 0, 0, 0, 0, 8, 197, 60, 193, 77, 52, 80, 72, 10, 135, 14, 195, 164, 9, 4, 5, 14, 76, 0, 0, 0, 0, 0, 21, 4, 95, 3, 9, 18, 89, 6, 37, 34, 49, 40, 65, 83, 55, 4, 36, 49, 89, 108, 0, 0, 0, 7, 196, 60, 194, 83, 36, 72, 0, 0, 9, 134, 13, 5, 14, 14, 195, 164, 19, 0, 0, 0, 0, 0, 9, 134, 20, 195, 164, 12, 12, 5, 76, 0, 0, 8, 197, 40, 242, 68, 20, 224, 76, 0, 0, 0, 0, 15, 4, 95, 1, 3, 21, 6, 35, 49, 40, 12, 47, 12, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 48, 145, 78, 20, 80, 72, 0, 5, 194, 61, 144, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 80, 84, 150, 20, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 66, 60, 176, 6, 39, 12, 10, 4, 49, 39, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 70, 64, 83, 1, 77, 66, 64, 48, 36, 55, 35, 89, 47, 108, 0, 0, 0, 7, 196, 40, 245, 11, 4, 76, 0, 0, 0, 0, 0, 0, 0, 0, 12, 68, 65, 148, 212, 36, 48, 114, 89, 47, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 76, 80, 72, 13, 2, 194, 164, 84, 35, 55, 40, 12, 47, 12, 35, 0, 0, 0, 0, 8, 197, 40, 242, 83, 76, 16, 76, 8, 197, 81, 83, 204, 48, 16, 76, 10, 2, 194, 163, 48, 40, 50, 47, 35, 0, 0, 0, 6, 195, 61, 96, 84, 72, 0, 0, 0, 9, 198, 60, 194, 83, 37, 96, 84, 72, 7, 2, 195, 164, 109, 12, 0, 0, 19, 2, 195, 165, 34, 6, 130, 47, 89, 35, 55, 115, 50, 36, 50, 6, 39, 12, 0, 0, 0, 0, 14, 2, 195, 160, 6, 35, 55, 35, 0, 24, 81, 108, 97, 32, 0, 0, 0, 0, 5, 194, 60, 224, 72, 9, 134, 20, 195, 164, 20, 195, 164, 76, 0, 6, 195, 4, 32, 192, 17, 0, 0, 0, 0, 0, 7, 196, 4, 161, 84, 4, 19, 7, 2, 195, 182, 111, 12, 0, 0, 0, 0, 0, 15, 4, 95, 3, 5, 4, 89, 6, 36, 72, 108, 55, 57, 108, 0, 0, 0, 17, 70, 100, 241, 200, 85, 37, 0, 57, 39, 81, 40, 34, 47, 12, 37, 0, 0, 13, 2, 197, 161, 107, 6, 35, 47, 12, 40, 109, 89, 0, 0, 7, 196, 88, 148, 139, 20, 19, 0, 0, 5, 194, 80, 80, 72, 0, 0, 7, 196, 56, 242, 78, 4, 76, 0, 0, 0, 7, 195, 88, 18, 64, 72, 8, 0, 6, 195, 65, 82, 5, 19, 0, 0, 0, 0, 6, 195, 81, 83, 5, 19, 0, 0, 0, 9, 198, 60, 194, 83, 36, 211, 69, 72, 0, 16, 2, 197, 190, 107, 6, 35, 47, 12, 40, 47, 89, 4, 36, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 48, 145, 78, 20, 224, 72, 0, 0, 17, 70, 64, 144, 78, 37, 53, 9, 48, 37, 35, 50, 37, 89, 47, 108, 0, 0, 0, 10, 135, 22, 195, 164, 8, 195, 164, 14, 76, 0, 0, 0, 6, 195, 5, 53, 5, 19, 0, 0, 0, 0, 7, 196, 40, 242, 78, 4, 76, 0, 8, 197, 60, 194, 84, 80, 80, 72, 8, 197, 81, 83, 204, 48, 80, 76, 0, 0, 0, 7, 196, 88, 148, 136, 20, 19, 0, 10, 135, 14, 195, 164, 9, 8, 9, 14, 76, 0, 9, 134, 5, 9, 22, 195, 164, 20, 72, 0, 0, 0, 12, 137, 12, 9, 5, 14, 5, 22, 195, 164, 20, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 65, 81, 64, 19, 0, 0, 0, 7, 132, 19, 25, 195, 182, 19, 0, 0, 0, 0, 0, 0, 7, 196, 48, 18, 84, 20, 19, 0, 16, 70, 88, 149, 76, 37, 53, 9, 84, 125, 55, 108, 89, 47, 108, 0, 0, 0, 6, 195, 4, 66, 4, 17, 9, 2, 95, 35, 34, 37, 89, 40, 0, 0, 10, 2, 95, 34, 55, 115, 50, 122, 89, 0, 0, 8, 197, 5, 85, 5, 80, 16, 19, 16, 2, 95, 33, 107, 40, 12, 47, 39, 65, 36, 34, 49, 12, 37, 0, 0, 0, 10, 2, 95, 39, 107, 118, 47, 12, 39, 0, 0, 13, 2, 95, 38, 36, 47, 65, 36, 34, 49, 12, 37, 0, 0, 14, 2, 95, 37, 48, 34, 39, 89, 36, 50, 47, 12, 37, 0, 0, 6, 195, 44, 243, 133, 19, 9, 198, 48, 145, 78, 56, 81, 84, 72, 13, 2, 95, 36, 72, 39, 55, 55, 35, 34, 37, 50, 0, 0, 0, 11, 4, 95, 3, 1, 16, 6, 37, 89, 39, 0, 0, 15, 2, 95, 41, 55, 39, 48, 12, 40, 89, 40, 55, 49, 40, 0, 0, 14, 2, 95, 40, 35, 55, 49, 40, 89, 40, 55, 49, 40, 0, 0, 7, 195, 20, 180, 128, 17, 24, 0, 10, 2, 95, 46, 48, 37, 89, 47, 36, 0, 0, 10, 2, 95, 45, 84, 37, 12, 84, 35, 0, 0, 0, 11, 2, 95, 51, 49, 6, 39, 55, 65, 36, 0, 0, 11, 2, 95, 50, 49, 6, 35, 49, 89, 37, 0, 0, 10, 2, 95, 49, 6, 114, 49, 89, 37, 0, 0, 11, 2, 95, 48, 50, 6, 39, 55, 55, 35, 0, 0, 14, 2, 95, 55, 89, 6, 118, 47, 89, 36, 65, 109, 50, 0, 0, 11, 2, 95, 54, 49, 6, 40, 12, 89, 37, 0, 0, 8, 197, 60, 194, 83, 37, 64, 72, 11, 2, 95, 53, 84, 6, 37, 12, 89, 37, 0, 0, 11, 2, 95, 52, 50, 6, 36, 55, 57, 109, 0, 0, 0, 16, 2, 95, 58, 49, 35, 49, 89, 117, 89, 48, 37, 89, 47, 36, 0, 0, 8, 197, 60, 195, 5, 21, 64, 72, 14, 2, 95, 57, 6, 114, 107, 72, 36, 49, 89, 109, 50, 0, 0, 15, 2, 95, 56, 49, 6, 35, 107, 72, 36, 49, 89, 35, 50, 0, 0, 18, 2, 95, 63, 49, 114, 89, 114, 65, 114, 89, 65, 36, 34, 49, 12, 108, 0, 0, 18, 2, 95, 62, 89, 6, 40, 12, 34, 36, 65, 48, 108, 49, 6, 120, 50, 0, 0, 0, 17, 2, 95, 60, 48, 6, 131, 50, 36, 65, 48, 108, 49, 6, 120, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 135, 14, 195, 164, 9, 14, 195, 164, 76, 0, 0, 8, 133, 19, 9, 14, 195, 164, 72, 0, 0, 0, 0, 0, 0, 0, 7, 196, 65, 84, 138, 20, 19, 0, 0, 0, 0, 0, 0, 0, 13, 2, 95, 91, 35, 55, 49, 40, 107, 35, 49, 35, 0, 0, 0, 0, 0, 13, 2, 95, 95, 35, 55, 35, 84, 37, 12, 84, 35, 0, 0, 0, 14, 2, 95, 93, 55, 39, 48, 12, 40, 107, 35, 49, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 70, 52, 20, 137, 4, 227, 133, 65, 35, 51, 108, 35, 50, 50, 36, 0, 0, 14, 4, 95, 7, 18, 22, 81, 34, 6, 35, 84, 108, 89, 0, 0, 0, 0, 0, 6, 195, 65, 84, 133, 19, 0, 0, 0, 0, 6, 195, 21, 69, 5, 72, 0, 0, 0, 0, 0, 13, 4, 95, 4, 9, 1, 6, 40, 65, 55, 122, 47, 0, 14, 2, 95, 123, 35, 55, 49, 40, 35, 12, 55, 47, 39, 0, 0, 0, 0, 0, 0, 0, 15, 2, 95, 125, 55, 39, 48, 12, 40, 35, 12, 55, 47, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 81, 83, 206, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 95, 35, 51, 50, 84, 109, 55, 37, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 40, 242, 83, 80, 16, 76, 0, 16, 70, 88, 20, 129, 77, 66, 64, 84, 35, 51, 35, 89, 47, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 49, 83, 192, 19, 6, 195, 81, 83, 192, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 68, 44, 84, 212, 36, 49, 36, 89, 47, 108, 0, 12, 68, 44, 20, 212, 36, 49, 35, 89, 47, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 56, 242, 83, 76, 16, 76, 8, 197, 81, 83, 204, 80, 16, 76, 0, 16, 70, 65, 84, 137, 77, 66, 64, 48, 40, 51, 108, 89, 47, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 196, 48, 145, 78, 20, 72, 19, 8, 196, 53, 85, 20, 4, 76, 8, 11, 136, 14, 195, 164, 9, 12, 20, 195, 164, 76, 0, 8, 197, 60, 194, 83, 36, 224, 72, 0, 0, 0, 0, 0, 0, 0, 0, 10, 135, 20, 195, 164, 13, 195, 164, 14, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 56, 242, 76, 48, 16, 76, 0, 0, 0, 0, 9, 133, 5, 14, 20, 195, 164, 72, 8, 0, 6, 195, 20, 211, 69, 72, 0, 0, 0, 0, 0, 10, 135, 19, 25, 195, 182, 4, 195, 164, 19, 0, 0, 9, 134, 14, 195, 164, 25, 20, 5, 19, 0, 0, 0, 0, 8, 197, 40, 242, 72, 36, 224, 76, 0, 6, 195, 5, 85, 1, 19, 0, 0, 0, 0, 0, 18, 71, 45, 83, 135, 25, 85, 19, 20, 49, 40, 68, 83, 40, 47, 89, 36, 0, 0, 0, 0, 16, 66, 100, 208, 114, 50, 50, 109, 10, 65, 40, 12, 47, 35, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 164, 0, 1, 10, 2, 108, 108, 97, 32, 3, 2, 109, 0, 3, 109, 0, 195, 164, 3, 109, 12, 0, 105, 105, 3, 109, 37, 12, 0, 121, 121, 3, 109, 114, 12, 0, 105, 3, 116, 0, 121, 3, 126, 0, 7, 6, 195, 182, 0, 3, 111, 0, 195, 182, 3, 111, 12, 0, 105, 105, 3, 111, 37, 12, 0, 121, 121, 3, 111, 114, 12, 0, 105, 3, 119, 0, 121, 3, 128, 0, 7, 6, 97, 0, 1, 10, 2, 108, 108, 97, 32, 3, 2, 35, 0, 3, 35, 0, 4, 8, 114, 116, 115, 117, 97, 2, 108, 3, 35, 12, 0, 97, 0, 105, 105, 3, 35, 37, 12, 0, 117, 117, 3, 35, 40, 12, 0, 105, 3, 115, 0, 117, 3, 122, 0, 7, 6, 98, 0, 3, 71, 0, 98, 3, 71, 12, 0, 7, 6, 99, 0, 4, 3, 49, 0, 104, 1, 25, 2, 114, 0, 99, 3, 49, 12, 0, 4, 2, 101, 3, 89, 0, 2, 105, 0, 2, 121, 0, 105, 116, 121, 3, 89, 37, 47, 37, 0, 7, 6, 100, 0, 3, 72, 0, 100, 3, 72, 12, 0, 7, 6, 101, 0, 4, 1, 10, 2, 108, 108, 97, 32, 3, 2, 36, 0, 1, 10, 2, 108, 108, 195, 164, 32, 0, 3, 36, 0, 101, 3, 36, 12, 0, 105, 105, 3, 36, 37, 12, 0, 117, 117, 3, 36, 40, 12, 0, 121, 121, 3, 36, 114, 12, 0, 105, 3, 118, 0, 117, 3, 124, 0, 121, 3, 127, 0, 7, 6, 102, 0, 3, 83, 0, 7, 6, 103, 0, 3, 81, 0, 103, 3, 81, 12, 0, 7, 6, 104, 0, 3, 107, 0, 7, 6, 105, 0, 1, 10, 2, 108, 108, 97, 32, 3, 2, 37, 0, 3, 37, 0, 105, 3, 37, 12, 0, 101, 101, 3, 37, 36, 12, 0, 117, 117, 3, 37, 40, 12, 0, 121, 121, 3, 37, 114, 12, 0, 117, 3, 125, 0, 121, 3, 129, 0, 101, 3, 131, 0, 7, 6, 106, 0, 3, 57, 0, 7, 6, 107, 0, 3, 49, 0, 107, 3, 49, 12, 0, 7, 6, 108, 0, 3, 55, 0, 108, 101, 1, 21, 2, 32, 3, 55, 55, 36, 22, 0, 7, 6, 109, 0, 3, 65, 0, 8, 164, 195, 100, 121, 115, 2, 17, 65, 3, 65, 12, 0, 7, 6, 110, 0, 3, 50, 0, 110, 101, 1, 21, 2, 32, 3, 50, 50, 36, 22, 0, 4, 2, 32, 112, 3, 65, 0, 2, 112, 0, 4, 2, 32, 107, 3, 68, 0, 2, 107, 0, 103, 2, 25, 0, 103, 3, 68, 12, 0, 7, 6, 111, 0, 4, 3, 39, 0, 1, 98, 109, 121, 115, 2, 108, 111, 105, 0, 4, 1, 98, 109, 121, 115, 2, 108, 3, 39, 12, 0, 111, 0, 105, 105, 3, 39, 37, 12, 0, 117, 117, 3, 39, 40, 12, 0, 105, 3, 117, 0, 117, 3, 123, 0, 7, 6, 112, 0, 3, 48, 0, 4, 1, 109, 97, 104, 115, 2, 111, 3, 48, 12, 0, 1, 109, 97, 107, 2, 97, 110, 106, 0, 8, 97, 116, 111, 2, 97, 0, 8, 101, 108, 111, 2, 97, 0, 112, 0, 7, 6, 113, 0, 3, 49, 0, 113, 3, 49, 12, 0, 7, 6, 114, 0, 3, 34, 0, 7, 6, 115, 0, 3, 89, 0, 116, 105, 1, 17, 65, 2, 32, 3, 89, 47, 37, 22, 0, 4, 104, 1, 21, 2, 97, 110, 32, 3, 89, 107, 0, 104, 1, 21, 2, 195, 164, 110, 32, 0, 115, 3, 89, 133, 0, 4, 99, 104, 1, 25, 3, 91, 0, 104, 1, 25, 0, 7, 6, 116, 0, 3, 47, 0, 116, 3, 47, 12, 0, 122, 3, 47, 89, 0, 115, 101, 1, 21, 2, 32, 3, 47, 89, 36, 22, 0, 7, 6, 117, 0, 3, 40, 0, 117, 3, 40, 12, 0, 105, 105, 3, 40, 37, 12, 0, 111, 111, 3, 40, 39, 12, 0, 105, 3, 58, 37, 0, 4, 105, 8, 3, 120, 0, 105, 8, 106, 0, 111, 3, 130, 0, 7, 6, 118, 0, 3, 84, 0, 7, 6, 119, 0, 3, 84, 0, 7, 6, 120, 0, 120, 3, 49, 12, 89, 0, 3, 49, 89, 0, 7, 6, 121, 0, 3, 114, 0, 121, 3, 114, 12, 0, 105, 105, 3, 114, 37, 12, 0, 195, 182, 195, 182, 3, 114, 111, 12, 0, 105, 3, 121, 0, 195, 182, 3, 132, 0, 7, 6, 122, 0, 4, 3, 47, 89, 0, 122, 0, 104, 1, 25, 3, 90, 0, 7, 6, 0, 4, 45, 1, 32, 17, 65, 2, 32, 15, 3, 10, 0, 45, 1, 32, 17, 67, 2, 32, 15, 0, 195, 165, 3, 39, 0, 195, 165, 195, 165, 3, 39, 12, 0, 45, 8, 32, 2, 32, 15, 3, 65, 37, 12, 50, 40, 89, 0, 36, 3, 72, 39, 55, 55, 35, 34, 37, 50, 0, 197, 190, 3, 90, 0, 197, 161, 3, 91, 0, 195, 188, 3, 114, 0, 195, 188, 195, 188, 3, 114, 12, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts18 = FileInMemory_createWithData (5130, reinterpret_cast (&espeakdata_dicts18_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/fi_dict", U"fi"); Collection_addItem (me.peek(), espeakdata_dicts18.transfer()); static unsigned char espeakdata_dicts19_data[21485] = { 0, 4, 0, 0, 166, 43, 0, 0, 0, 0, 0, 8, 67, 69, 82, 84, 21, 0, 10, 8, 67, 21, 81, 64, 111, 0, 76, 0, 0, 7, 65, 4, 35, 0, 14, 9, 5, 193, 4, 76, 36, 6, 65, 4, 35, 0, 76, 0, 13, 70, 12, 243, 150, 20, 229, 0, 49, 116, 84, 113, 0, 0, 0, 0, 6, 65, 8, 71, 36, 0, 0, 0, 6, 195, 85, 64, 192, 17, 6, 195, 57, 50, 64, 17, 14, 67, 21, 64, 192, 112, 47, 89, 36, 47, 36, 34, 35, 0, 0, 0, 6, 65, 12, 89, 36, 0, 0, 15, 70, 16, 244, 16, 48, 84, 128, 72, 127, 48, 55, 112, 34, 0, 0, 6, 195, 69, 81, 64, 76, 12, 4, 95, 8, 1, 3, 49, 35, 34, 6, 116, 0, 0, 0, 6, 65, 16, 72, 36, 0, 0, 6, 195, 76, 19, 147, 76, 0, 11, 67, 69, 82, 68, 49, 58, 37, 72, 0, 76, 0, 0, 6, 195, 64, 245, 82, 76, 14, 65, 20, 101, 98, 97, 121, 0, 29, 81, 98, 97, 121, 32, 6, 65, 20, 11, 13, 0, 0, 9, 67, 21, 81, 83, 111, 143, 0, 76, 0, 7, 195, 69, 82, 64, 32, 76, 0, 0, 7, 65, 24, 11, 112, 83, 0, 0, 0, 21, 67, 80, 245, 84, 47, 40, 55, 47, 113, 0, 82, 108, 101, 32, 116, 101, 109, 112, 115, 32, 22, 67, 80, 245, 84, 47, 40, 55, 65, 116, 72, 0, 82, 108, 101, 32, 109, 111, 110, 100, 101, 32, 11, 67, 80, 245, 84, 47, 6, 40, 140, 0, 76, 10, 199, 64, 197, 83, 36, 85, 82, 76, 76, 0, 0, 14, 69, 12, 19, 153, 60, 224, 49, 35, 50, 57, 127, 50, 0, 16, 65, 28, 90, 37, 81, 35, 112, 34, 47, 89, 0, 81, 104, 122, 32, 6, 65, 28, 90, 36, 0, 0, 16, 70, 16, 84, 142, 36, 84, 128, 72, 112, 34, 50, 57, 36, 120, 0, 0, 9, 67, 29, 147, 64, 90, 37, 65, 0, 9, 67, 28, 147, 128, 75, 37, 50, 0, 7, 195, 80, 243, 128, 72, 34, 0, 0, 7, 65, 32, 11, 35, 91, 0, 0, 6, 195, 80, 245, 83, 76, 0, 0, 0, 6, 65, 36, 11, 37, 0, 0, 8, 66, 37, 0, 37, 48, 36, 0, 10, 1, 37, 48, 40, 34, 89, 113, 0, 27, 0, 6, 195, 12, 20, 128, 37, 6, 195, 12, 20, 128, 72, 7, 1, 38, 36, 0, 72, 28, 0, 0, 11, 70, 56, 147, 148, 20, 225, 15, 21, 0, 10, 6, 65, 40, 90, 37, 0, 0, 15, 70, 77, 67, 195, 44, 84, 128, 89, 47, 39, 49, 36, 120, 0, 18, 8, 16, 15, 11, 195, 169, 13, 15, 14, 48, 39, 49, 36, 65, 127, 50, 0, 0, 8, 67, 76, 148, 128, 21, 0, 10, 10, 67, 16, 243, 148, 72, 116, 140, 0, 72, 14, 1, 42, 35, 89, 47, 36, 34, 37, 89, 49, 12, 0, 27, 0, 19, 9, 195, 169, 22, 9, 20, 9, 15, 14, 19, 36, 84, 37, 47, 57, 116, 143, 0, 12, 68, 52, 81, 9, 4, 65, 36, 72, 57, 35, 0, 9, 1, 43, 48, 55, 111, 89, 0, 27, 0, 6, 65, 44, 49, 35, 0, 0, 15, 7, 195, 169, 20, 9, 15, 14, 19, 36, 47, 57, 116, 143, 0, 0, 0, 8, 67, 25, 35, 205, 21, 0, 10, 3, 129, 47, 0, 7, 65, 48, 11, 112, 55, 0, 0, 23, 1, 49, 48, 34, 13, 65, 57, 112, 34, 65, 113, 0, 81, 195, 168, 114, 101, 109, 101, 110, 116, 32, 19, 1, 49, 48, 34, 13, 65, 57, 112, 34, 143, 0, 81, 195, 168, 114, 101, 115, 32, 17, 1, 49, 48, 34, 13, 65, 57, 112, 34, 0, 81, 195, 168, 114, 101, 32, 16, 1, 49, 48, 34, 13, 65, 57, 36, 143, 0, 81, 101, 114, 115, 32, 15, 1, 49, 48, 34, 13, 65, 57, 36, 120, 0, 81, 101, 114, 32, 16, 70, 69, 81, 76, 69, 81, 64, 49, 112, 55, 49, 8, 13, 0, 76, 0, 10, 67, 44, 20, 148, 49, 35, 34, 47, 0, 6, 195, 69, 81, 76, 76, 0, 7, 196, 80, 83, 12, 20, 76, 0, 7, 65, 52, 11, 112, 65, 0, 0, 9, 67, 52, 83, 147, 65, 113, 143, 0, 17, 66, 53, 0, 23, 112, 65, 48, 36, 47, 34, 58, 35, 0, 81, 51, 32, 0, 0, 9, 196, 48, 85, 82, 76, 72, 36, 40, 8, 196, 48, 85, 82, 76, 76, 34, 0, 9, 5, 95, 48, 1, 14, 4, 36, 0, 7, 65, 56, 11, 112, 50, 0, 0, 0, 0, 0, 14, 69, 64, 19, 1, 61, 48, 48, 35, 55, 35, 127, 89, 0, 6, 65, 60, 11, 39, 0, 0, 8, 67, 28, 20, 147, 81, 35, 0, 6, 195, 57, 50, 83, 17, 0, 0, 9, 133, 195, 170, 20, 5, 19, 76, 36, 0, 11, 1, 64, 24, 35, 34, 39, 71, 35, 88, 0, 6, 65, 64, 48, 36, 0, 0, 9, 198, 21, 84, 211, 20, 229, 0, 76, 0, 0, 0, 14, 6, 8, 195, 169, 12, 1, 19, 36, 55, 35, 89, 0, 76, 6, 65, 68, 49, 111, 0, 0, 0, 0, 0, 20, 5, 22, 9, 195, 170, 20, 84, 57, 112, 47, 50, 35, 65, 0, 81, 110, 97, 109, 32, 14, 69, 16, 80, 137, 4, 224, 72, 36, 71, 57, 35, 50, 0, 7, 65, 72, 11, 112, 34, 0, 0, 13, 70, 12, 128, 82, 48, 84, 192, 91, 35, 34, 55, 0, 0, 0, 0, 18, 9, 13, 15, 14, 20, 18, 195, 169, 1, 12, 65, 116, 34, 36, 35, 55, 0, 10, 5, 1, 15, 195, 187, 20, 40, 47, 0, 7, 65, 76, 11, 112, 89, 0, 0, 0, 7, 195, 84, 225, 64, 34, 76, 0, 0, 14, 65, 80, 21, 0, 10, 81, 115, 104, 105, 114, 116, 115, 32, 13, 65, 80, 21, 0, 10, 81, 115, 104, 105, 114, 116, 32, 11, 69, 5, 85, 133, 57, 64, 39, 84, 113, 0, 0, 5, 194, 4, 48, 17, 0, 6, 195, 12, 147, 192, 17, 0, 11, 68, 52, 145, 85, 96, 65, 37, 132, 0, 76, 0, 20, 73, 9, 32, 90, 104, 21, 137, 48, 193, 64, 71, 34, 35, 88, 35, 84, 37, 55, 0, 6, 65, 84, 11, 111, 0, 0, 7, 66, 85, 0, 21, 0, 10, 0, 0, 0, 6, 65, 88, 84, 36, 0, 0, 15, 70, 44, 225, 83, 76, 85, 0, 49, 50, 36, 89, 112, 47, 0, 12, 66, 5, 48, 35, 47, 111, 0, 81, 116, 117, 32, 9, 66, 5, 48, 35, 143, 0, 76, 36, 7, 66, 5, 48, 35, 89, 0, 6, 195, 48, 244, 147, 76, 0, 0, 0, 10, 69, 28, 84, 141, 4, 224, 21, 0, 10, 11, 67, 4, 98, 78, 35, 83, 114, 0, 76, 28, 12, 65, 92, 72, 40, 71, 55, 13, 84, 6, 36, 0, 0, 0, 0, 0, 10, 4, 95, 49, 77, 49, 65, 37, 55, 0, 8, 65, 96, 11, 37, 49, 89, 0, 0, 0, 13, 67, 44, 34, 84, 49, 37, 55, 39, 71, 37, 47, 0, 0, 11, 68, 69, 80, 78, 16, 49, 113, 140, 0, 76, 0, 10, 69, 37, 51, 1, 56, 64, 21, 0, 10, 13, 65, 100, 23, 37, 81, 34, 6, 112, 49, 0, 14, 9, 17, 70, 69, 81, 76, 69, 81, 83, 49, 112, 55, 49, 8, 13, 143, 0, 76, 5, 193, 100, 76, 32, 0, 10, 67, 4, 226, 83, 35, 50, 37, 89, 0, 0, 8, 67, 100, 84, 192, 21, 0, 10, 9, 67, 76, 20, 192, 89, 35, 89, 0, 10, 67, 48, 244, 192, 55, 39, 89, 0, 76, 0, 10, 67, 8, 197, 77, 71, 55, 40, 65, 0, 7, 196, 20, 225, 137, 56, 76, 0, 7, 65, 104, 88, 112, 72, 0, 0, 7, 66, 5, 64, 21, 0, 10, 0, 0, 11, 68, 5, 48, 201, 36, 35, 89, 49, 37, 0, 0, 0, 0, 0, 0, 0, 16, 70, 100, 241, 207, 85, 37, 0, 23, 37, 39, 81, 40, 34, 47, 0, 10, 66, 12, 16, 89, 35, 0, 76, 41, 32, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 5, 80, 72, 34, 0, 11, 67, 52, 84, 192, 65, 123, 143, 0, 72, 34, 0, 0, 0, 0, 9, 1, 126, 47, 37, 55, 72, 36, 0, 0, 7, 195, 5, 86, 0, 72, 34, 0, 0, 15, 66, 8, 64, 98, 111, 117, 108, 101, 118, 97, 114, 100, 0, 29, 0, 0, 0, 0, 0, 0, 6, 195, 69, 83, 201, 76, 0, 13, 69, 52, 147, 15, 84, 64, 65, 37, 55, 40, 72, 0, 0, 0, 0, 12, 67, 5, 98, 0, 35, 84, 4, 36, 35, 91, 0, 0, 13, 69, 12, 19, 131, 21, 32, 49, 113, 89, 112, 34, 0, 0, 0, 0, 10, 4, 95, 49, 67, 48, 89, 113, 140, 0, 0, 0, 7, 66, 8, 80, 21, 0, 10, 7, 195, 5, 97, 67, 76, 28, 0, 18, 71, 21, 52, 5, 72, 19, 148, 60, 112, 89, 48, 36, 34, 113, 47, 39, 0, 6, 195, 57, 66, 64, 17, 0, 0, 0, 0, 0, 11, 68, 20, 225, 133, 72, 113, 83, 112, 34, 0, 10, 2, 13, 46, 65, 13, 89, 37, 132, 0, 0, 0, 0, 0, 0, 0, 14, 70, 64, 128, 76, 49, 84, 192, 83, 35, 55, 111, 89, 0, 0, 9, 67, 9, 85, 0, 71, 111, 47, 0, 9, 67, 9, 85, 0, 71, 111, 0, 36, 0, 16, 70, 40, 83, 142, 36, 97, 82, 90, 36, 50, 37, 83, 112, 34, 0, 0, 0, 17, 70, 52, 20, 135, 5, 33, 84, 65, 35, 34, 81, 35, 34, 112, 47, 0, 0, 15, 71, 76, 128, 77, 64, 242, 78, 28, 91, 113, 48, 58, 114, 0, 0, 11, 68, 69, 80, 78, 80, 49, 113, 140, 0, 72, 0, 0, 0, 0, 7, 196, 5, 96, 78, 80, 76, 0, 0, 13, 66, 17, 32, 72, 39, 49, 47, 132, 34, 0, 24, 41, 0, 9, 67, 21, 84, 192, 111, 143, 0, 76, 0, 0, 0, 0, 9, 198, 64, 245, 82, 69, 83, 201, 76, 0, 8, 67, 48, 149, 5, 21, 0, 10, 10, 67, 8, 85, 1, 71, 36, 47, 35, 0, 0, 13, 69, 52, 22, 143, 85, 64, 65, 35, 88, 40, 47, 0, 13, 138, 14, 195, 169, 1, 14, 13, 15, 9, 14, 19, 76, 0, 14, 70, 52, 22, 79, 81, 65, 64, 65, 35, 57, 127, 47, 0, 12, 66, 4, 144, 112, 90, 0, 76, 81, 106, 101, 32, 6, 194, 4, 144, 76, 36, 6, 194, 12, 80, 76, 34, 0, 0, 0, 11, 69, 16, 83, 135, 84, 80, 72, 114, 81, 0, 0, 0, 7, 195, 4, 149, 0, 76, 36, 9, 134, 7, 21, 195, 168, 18, 5, 76, 7, 195, 12, 85, 0, 72, 34, 0, 9, 67, 4, 150, 0, 112, 49, 89, 0, 0, 0, 0, 0, 12, 68, 77, 67, 213, 80, 89, 47, 35, 40, 47, 0, 0, 21, 69, 12, 83, 12, 21, 48, 89, 112, 55, 15, 55, 35, 0, 32, 76, 81, 108, 195, 160, 32, 20, 69, 12, 83, 12, 21, 48, 89, 112, 55, 15, 89, 37, 0, 32, 76, 81, 99, 105, 32, 8, 197, 12, 83, 12, 21, 48, 76, 0, 18, 70, 76, 51, 210, 9, 85, 0, 115, 99, 111, 114, 98, 117, 116, 116, 0, 29, 0, 9, 67, 13, 85, 0, 49, 117, 47, 0, 0, 12, 68, 49, 82, 71, 36, 55, 58, 37, 75, 37, 0, 0, 0, 8, 67, 101, 97, 83, 37, 84, 0, 0, 0, 0, 0, 0, 8, 67, 57, 83, 12, 21, 0, 10, 0, 0, 20, 73, 12, 243, 148, 20, 229, 9, 60, 228, 192, 49, 116, 47, 113, 47, 57, 116, 143, 0, 0, 0, 19, 71, 29, 80, 84, 20, 208, 76, 4, 81, 58, 35, 47, 36, 65, 35, 55, 35, 0, 0, 0, 8, 67, 76, 48, 78, 21, 0, 10, 0, 0, 0, 0, 13, 5, 4, 39, 5, 19, 20, 72, 6, 112, 89, 47, 0, 0, 6, 194, 16, 80, 72, 34, 0, 0, 0, 0, 0, 18, 71, 32, 19, 66, 85, 33, 197, 72, 23, 113, 71, 13, 34, 81, 117, 34, 0, 9, 67, 8, 149, 0, 71, 37, 47, 0, 6, 195, 52, 242, 64, 76, 6, 195, 12, 50, 64, 17, 0, 9, 68, 9, 34, 65, 56, 21, 0, 10, 12, 68, 80, 245, 84, 20, 47, 6, 40, 47, 0, 76, 13, 4, 95, 4, 16, 20, 84, 37, 34, 81, 111, 55, 0, 0, 0, 15, 70, 81, 32, 77, 92, 22, 64, 47, 34, 35, 65, 58, 137, 0, 8, 66, 21, 48, 112, 143, 0, 76, 9, 66, 17, 80, 72, 130, 0, 72, 34, 0, 0, 0, 0, 11, 70, 65, 35, 199, 72, 19, 64, 21, 0, 10, 0, 11, 70, 76, 19, 69, 80, 147, 69, 21, 0, 10, 9, 67, 21, 53, 0, 112, 140, 0, 76, 0, 0, 0, 15, 70, 8, 80, 85, 12, 245, 80, 71, 39, 49, 40, 139, 0, 76, 0, 0, 15, 3, 95, 35, 57, 47, 35, 71, 111, 55, 35, 89, 37, 116, 0, 12, 4, 95, 20, 12, 4, 47, 6, 37, 55, 72, 0, 0, 0, 0, 12, 67, 52, 228, 192, 65, 37, 50, 111, 47, 143, 0, 10, 67, 4, 197, 0, 24, 35, 55, 47, 0, 0, 12, 68, 32, 147, 132, 36, 23, 37, 50, 72, 37, 0, 0, 0, 7, 66, 21, 64, 36, 0, 76, 0, 0, 0, 0, 24, 74, 48, 145, 67, 33, 65, 78, 77, 65, 73, 56, 55, 37, 91, 47, 117, 50, 91, 47, 35, 57, 50, 0, 0, 0, 11, 4, 5, 195, 187, 20, 111, 140, 0, 76, 36, 0, 8, 197, 5, 85, 1, 57, 64, 76, 0, 0, 12, 67, 4, 209, 0, 35, 4, 112, 65, 72, 36, 0, 0, 17, 72, 52, 243, 148, 76, 84, 146, 5, 64, 65, 116, 89, 36, 34, 35, 0, 0, 0, 9, 198, 21, 84, 211, 36, 86, 128, 76, 15, 70, 4, 225, 18, 60, 145, 0, 113, 72, 34, 39, 37, 72, 0, 0, 0, 10, 68, 48, 245, 73, 76, 55, 58, 37, 0, 0, 13, 69, 8, 83, 9, 104, 80, 71, 36, 55, 37, 88, 0, 10, 69, 64, 83, 208, 48, 80, 21, 0, 10, 0, 7, 66, 21, 80, 111, 0, 76, 0, 0, 0, 0, 0, 10, 67, 21, 85, 0, 111, 140, 0, 76, 36, 0, 9, 67, 21, 86, 0, 132, 143, 0, 76, 0, 15, 70, 12, 245, 83, 12, 245, 83, 49, 40, 89, 49, 40, 89, 0, 0, 8, 67, 4, 225, 0, 21, 0, 10, 0, 0, 0, 0, 0, 0, 10, 67, 25, 81, 76, 83, 57, 40, 55, 0, 0, 12, 68, 12, 147, 132, 100, 89, 37, 50, 72, 37, 0, 0, 0, 16, 70, 65, 33, 77, 36, 84, 128, 48, 34, 13, 65, 57, 36, 120, 0, 0, 16, 67, 80, 19, 148, 47, 113, 48, 37, 0, 76, 81, 112, 105, 115, 32, 19, 67, 80, 19, 148, 47, 113, 65, 57, 132, 0, 76, 81, 109, 105, 101, 117, 120, 32, 10, 67, 80, 19, 148, 47, 113, 140, 0, 76, 0, 0, 0, 0, 6, 195, 5, 97, 192, 17, 0, 0, 0, 9, 198, 69, 83, 201, 69, 81, 64, 72, 0, 16, 7, 11, 15, 23, 5, 195, 175, 20, 49, 39, 58, 112, 57, 47, 0, 11, 67, 4, 243, 0, 35, 4, 39, 112, 55, 0, 0, 20, 68, 12, 83, 12, 20, 89, 112, 55, 15, 55, 35, 0, 32, 76, 81, 108, 195, 160, 32, 19, 68, 12, 83, 12, 20, 89, 112, 55, 15, 89, 37, 0, 32, 76, 81, 99, 105, 32, 7, 196, 12, 83, 12, 20, 76, 0, 17, 70, 4, 195, 5, 49, 82, 65, 35, 55, 36, 55, 40, 37, 6, 35, 0, 0, 0, 0, 0, 0, 0, 8, 67, 32, 19, 128, 23, 113, 0, 0, 0, 11, 67, 25, 85, 0, 83, 111, 140, 0, 76, 36, 0, 0, 7, 195, 52, 243, 128, 72, 34, 0, 0, 0, 6, 194, 20, 128, 76, 28, 7, 66, 16, 160, 21, 0, 10, 0, 6, 195, 64, 20, 128, 76, 12, 67, 60, 52, 128, 39, 89, 4, 36, 112, 34, 0, 0, 0, 15, 69, 44, 192, 88, 60, 224, 49, 55, 35, 49, 89, 127, 50, 0, 0, 0, 0, 8, 196, 20, 195, 5, 76, 76, 32, 0, 18, 3, 226, 132, 162, 65, 35, 34, 49, 72, 13, 83, 35, 71, 34, 37, 49, 0, 0, 0, 18, 71, 24, 83, 4, 77, 0, 84, 32, 83, 112, 55, 72, 89, 48, 35, 47, 0, 0, 0, 12, 69, 8, 22, 69, 85, 128, 71, 35, 57, 132, 0, 0, 0, 0, 12, 68, 44, 83, 153, 4, 49, 36, 50, 57, 35, 0, 9, 68, 64, 245, 76, 76, 48, 40, 0, 10, 67, 16, 19, 147, 72, 113, 143, 0, 76, 22, 68, 64, 20, 131, 20, 48, 35, 34, 89, 49, 116, 134, 0, 76, 81, 113, 117, 39, 111, 110, 32, 26, 68, 64, 20, 131, 20, 48, 35, 34, 89, 49, 112, 55, 143, 0, 76, 81, 113, 117, 39, 101, 108, 108, 101, 115, 32, 24, 68, 64, 20, 131, 20, 48, 35, 34, 89, 49, 112, 55, 0, 76, 81, 113, 117, 39, 101, 108, 108, 101, 32, 24, 68, 64, 20, 131, 20, 48, 35, 34, 89, 49, 37, 55, 143, 0, 76, 81, 113, 117, 39, 105, 108, 115, 32, 22, 68, 64, 20, 131, 20, 48, 35, 34, 89, 49, 37, 55, 0, 76, 81, 113, 117, 39, 105, 108, 32, 19, 68, 64, 20, 131, 20, 48, 35, 34, 89, 49, 13, 0, 76, 81, 113, 117, 101, 32, 0, 0, 9, 198, 64, 245, 82, 80, 19, 148, 76, 17, 66, 12, 208, 99, 101, 110, 116, 105, 109, 195, 168, 116, 114, 101, 0, 29, 0, 12, 67, 16, 149, 152, 72, 37, 84, 37, 49, 89, 0, 0, 0, 8, 67, 28, 85, 0, 21, 0, 10, 0, 0, 9, 67, 32, 20, 148, 35, 34, 47, 0, 0, 0, 0, 0, 0, 0, 13, 69, 92, 19, 12, 37, 48, 58, 35, 55, 37, 89, 0, 14, 69, 32, 84, 141, 21, 48, 23, 112, 34, 65, 112, 89, 0, 0, 0, 0, 0, 0, 0, 0, 21, 70, 44, 212, 12, 5, 145, 82, 49, 35, 4, 112, 65, 48, 55, 112, 57, 6, 117, 34, 0, 0, 0, 0, 0, 12, 68, 92, 20, 137, 60, 58, 35, 34, 57, 39, 0, 0, 0, 16, 70, 4, 192, 137, 56, 244, 192, 35, 55, 71, 37, 50, 39, 89, 0, 6, 195, 57, 97, 1, 17, 0, 11, 3, 226, 130, 172, 13, 34, 6, 39, 0, 76, 0, 0, 10, 69, 60, 194, 86, 21, 32, 21, 0, 10, 0, 0, 15, 70, 80, 83, 148, 36, 243, 147, 47, 113, 47, 57, 116, 143, 0, 6, 195, 44, 65, 64, 17, 0, 0, 10, 69, 72, 81, 8, 5, 64, 21, 0, 10, 12, 69, 21, 84, 133, 57, 64, 111, 34, 140, 0, 76, 0, 7, 66, 32, 80, 21, 0, 10, 0, 0, 12, 68, 5, 37, 66, 4, 35, 34, 40, 71, 35, 0, 6, 195, 88, 84, 147, 37, 10, 67, 88, 84, 147, 84, 112, 34, 0, 76, 0, 14, 69, 25, 85, 21, 56, 16, 83, 40, 47, 40, 50, 35, 0, 8, 197, 12, 128, 81, 84, 80, 76, 16, 69, 20, 32, 196, 36, 48, 13, 71, 36, 89, 36, 72, 37, 49, 0, 0, 0, 0, 0, 13, 69, 4, 113, 78, 16, 16, 35, 90, 114, 72, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 20, 192, 76, 12, 3, 95, 50, 49, 84, 114, 47, 36, 12, 115, 0, 0, 9, 67, 64, 20, 192, 48, 35, 0, 37, 11, 67, 64, 20, 192, 48, 6, 35, 143, 0, 76, 9, 3, 95, 50, 48, 84, 114, 140, 0, 0, 12, 68, 44, 85, 137, 56, 49, 36, 84, 37, 50, 0, 14, 3, 95, 50, 51, 84, 114, 47, 47, 34, 58, 35, 143, 0, 0, 18, 5, 19, 46, 20, 46, 16, 89, 37, 55, 47, 13, 12, 48, 55, 6, 112, 0, 12, 3, 95, 50, 50, 84, 114, 47, 72, 132, 143, 0, 0, 11, 70, 69, 81, 82, 36, 84, 192, 21, 0, 10, 12, 3, 95, 50, 53, 84, 114, 47, 89, 114, 49, 0, 0, 8, 67, 32, 148, 192, 21, 0, 10, 13, 3, 95, 50, 52, 84, 114, 47, 49, 35, 47, 34, 0, 0, 12, 3, 95, 50, 55, 84, 114, 47, 89, 112, 47, 0, 0, 12, 3, 95, 50, 54, 84, 114, 47, 89, 37, 144, 0, 0, 7, 66, 37, 64, 21, 0, 10, 13, 3, 95, 51, 49, 47, 34, 113, 47, 36, 12, 115, 0, 13, 4, 95, 13, 3, 14, 65, 35, 49, 34, 6, 116, 0, 0, 0, 0, 0, 6, 195, 76, 52, 201, 17, 0, 0, 10, 67, 48, 19, 211, 55, 35, 127, 89, 0, 0, 0, 7, 66, 16, 240, 21, 0, 10, 0, 12, 67, 20, 211, 0, 13, 4, 112, 65, 112, 55, 0, 0, 0, 9, 67, 16, 245, 0, 72, 127, 47, 0, 0, 0, 0, 9, 68, 64, 20, 5, 72, 21, 0, 10, 0, 0, 0, 0, 14, 6, 95, 18, 15, 13, 1, 14, 34, 39, 65, 6, 114, 0, 0, 0, 0, 10, 134, 5, 195, 187, 13, 5, 19, 76, 36, 10, 134, 6, 195, 187, 13, 5, 19, 76, 36, 0, 0, 8, 67, 20, 225, 0, 21, 0, 10, 8, 197, 16, 84, 21, 37, 48, 76, 0, 17, 66, 20, 224, 113, 15, 47, 40, 143, 0, 76, 81, 116, 111, 117, 115, 32, 7, 194, 20, 224, 76, 36, 40, 5, 194, 20, 224, 76, 5, 194, 20, 224, 72, 15, 3, 95, 54, 49, 89, 58, 35, 89, 113, 47, 36, 12, 115, 0, 0, 10, 3, 95, 51, 88, 47, 34, 113, 47, 0, 0, 11, 68, 77, 84, 200, 36, 89, 40, 91, 37, 0, 12, 68, 52, 19, 21, 76, 65, 35, 55, 111, 89, 0, 8, 3, 95, 48, 67, 89, 113, 0, 0, 0, 0, 0, 7, 196, 5, 52, 197, 104, 76, 18, 3, 16, 46, 19, 48, 127, 89, 47, 89, 49, 34, 37, 48, 47, 127, 65, 0, 0, 0, 8, 67, 52, 17, 5, 21, 0, 10, 13, 70, 16, 84, 211, 61, 84, 192, 72, 13, 89, 40, 0, 16, 3, 95, 55, 49, 89, 112, 48, 47, 113, 47, 36, 12, 115, 0, 102, 16, 3, 95, 55, 49, 89, 58, 35, 89, 113, 47, 36, 12, 116, 88, 0, 0, 0, 0, 0, 0, 10, 67, 77, 65, 64, 89, 6, 114, 47, 0, 0, 7, 196, 64, 20, 141, 36, 76, 0, 0, 19, 66, 48, 16, 55, 121, 15, 55, 132, 34, 0, 76, 32, 81, 108, 101, 117, 114, 32, 6, 194, 40, 80, 72, 32, 10, 66, 48, 16, 55, 121, 0, 36, 40, 72, 9, 66, 48, 16, 55, 121, 0, 34, 76, 12, 3, 95, 49, 57, 72, 37, 88, 50, 117, 83, 0, 0, 11, 67, 5, 2, 64, 35, 48, 4, 36, 37, 0, 12, 3, 95, 49, 56, 72, 37, 88, 111, 37, 141, 0, 0, 0, 8, 197, 20, 224, 207, 72, 80, 76, 0, 0, 0, 0, 0, 14, 70, 80, 130, 69, 73, 38, 64, 47, 57, 112, 34, 37, 0, 12, 3, 95, 50, 57, 84, 114, 47, 50, 117, 83, 0, 9, 3, 95, 49, 49, 23, 116, 88, 0, 0, 12, 3, 95, 50, 56, 84, 114, 47, 111, 37, 141, 0, 9, 3, 95, 49, 48, 72, 37, 144, 0, 0, 10, 3, 95, 49, 51, 47, 34, 112, 88, 0, 0, 9, 3, 95, 49, 50, 72, 40, 88, 0, 0, 7, 195, 12, 83, 1, 76, 32, 9, 3, 95, 49, 53, 49, 114, 88, 0, 0, 12, 3, 95, 49, 52, 49, 35, 47, 127, 34, 88, 0, 0, 7, 196, 4, 147, 147, 36, 76, 11, 3, 95, 49, 55, 72, 37, 89, 112, 47, 0, 0, 9, 3, 95, 49, 54, 89, 112, 88, 0, 0, 0, 7, 195, 25, 84, 192, 76, 36, 17, 70, 52, 84, 131, 20, 65, 83, 65, 112, 34, 89, 36, 72, 112, 89, 0, 13, 3, 95, 55, 88, 89, 112, 48, 47, 113, 47, 0, 102, 0, 0, 0, 0, 11, 67, 21, 130, 84, 36, 81, 88, 37, 47, 0, 9, 67, 9, 84, 192, 71, 111, 0, 36, 9, 67, 9, 84, 192, 71, 111, 89, 0, 0, 0, 0, 10, 66, 33, 160, 23, 112, 34, 47, 89, 0, 0, 19, 71, 88, 83, 133, 105, 81, 76, 4, 84, 36, 50, 36, 88, 111, 112, 55, 35, 0, 0, 24, 11, 4, 195, 169, 19, 5, 18, 20, 9, 15, 14, 19, 72, 36, 88, 112, 34, 47, 57, 116, 143, 0, 36, 0, 0, 0, 0, 0, 10, 69, 52, 20, 16, 21, 32, 21, 0, 10, 0, 16, 70, 88, 19, 149, 5, 69, 64, 84, 35, 50, 40, 35, 47, 40, 0, 9, 66, 52, 16, 65, 121, 0, 72, 34, 14, 3, 95, 52, 49, 49, 35, 34, 113, 47, 36, 12, 115, 0, 0, 14, 67, 52, 134, 128, 65, 36, 81, 35, 112, 34, 47, 89, 0, 0, 19, 72, 24, 18, 18, 20, 226, 5, 37, 64, 83, 35, 34, 13, 50, 35, 57, 47, 0, 0, 9, 67, 52, 21, 0, 65, 35, 47, 0, 0, 0, 0, 0, 10, 69, 52, 18, 76, 80, 240, 21, 0, 10, 0, 14, 3, 95, 53, 49, 89, 114, 49, 113, 47, 36, 12, 115, 0, 0, 17, 71, 77, 2, 9, 56, 53, 5, 72, 89, 83, 114, 49, 47, 112, 34, 0, 0, 0, 8, 197, 80, 83, 12, 21, 48, 76, 0, 0, 0, 0, 21, 2, 50, 49, 84, 114, 47, 36, 12, 111, 50, 37, 112, 65, 0, 81, 195, 168, 109, 101, 32, 0, 0, 0, 8, 67, 28, 81, 75, 21, 0, 10, 0, 0, 0, 6, 195, 92, 208, 64, 17, 0, 13, 3, 95, 63, 63, 89, 114, 71, 6, 39, 55, 55, 0, 0, 22, 2, 51, 49, 47, 34, 113, 47, 36, 12, 111, 50, 37, 112, 65, 0, 81, 195, 168, 109, 101, 32, 0, 15, 70, 13, 147, 148, 32, 144, 64, 89, 37, 50, 47, 37, 35, 0, 10, 66, 53, 32, 65, 13, 89, 37, 132, 0, 0, 11, 3, 95, 52, 88, 49, 35, 34, 113, 47, 0, 0, 0, 17, 70, 104, 147, 66, 4, 37, 197, 88, 37, 65, 71, 35, 71, 58, 36, 0, 10, 67, 60, 208, 78, 39, 65, 35, 50, 0, 0, 0, 7, 195, 4, 145, 64, 76, 36, 0, 0, 14, 69, 32, 19, 76, 21, 64, 23, 35, 65, 55, 112, 47, 0, 23, 2, 52, 49, 49, 35, 34, 113, 47, 36, 12, 111, 50, 37, 112, 65, 0, 81, 195, 168, 109, 101, 32, 0, 19, 66, 48, 80, 55, 14, 15, 55, 132, 34, 0, 76, 32, 81, 108, 101, 117, 114, 32, 7, 194, 48, 80, 36, 40, 72, 6, 194, 48, 80, 34, 76, 16, 66, 44, 112, 107, 105, 108, 111, 103, 114, 97, 109, 109, 101, 0, 29, 0, 6, 195, 64, 50, 64, 17, 14, 3, 95, 56, 48, 49, 35, 47, 34, 13, 84, 114, 143, 0, 11, 3, 95, 53, 88, 89, 114, 49, 113, 47, 0, 0, 8, 196, 12, 85, 20, 20, 72, 34, 0, 9, 67, 56, 21, 0, 50, 35, 47, 0, 8, 67, 48, 85, 0, 21, 0, 10, 0, 0, 8, 67, 52, 18, 64, 65, 112, 0, 0, 9, 68, 64, 85, 5, 72, 21, 0, 10, 15, 70, 40, 16, 203, 64, 245, 0, 75, 35, 49, 48, 127, 47, 0, 0, 8, 197, 69, 81, 76, 48, 80, 76, 23, 2, 53, 49, 89, 114, 49, 113, 47, 36, 12, 111, 50, 37, 112, 65, 0, 81, 195, 168, 109, 101, 32, 0, 16, 70, 92, 19, 21, 36, 114, 64, 58, 35, 55, 40, 37, 75, 37, 0, 14, 66, 45, 112, 107, 105, 108, 111, 119, 97, 116, 116, 0, 29, 15, 3, 95, 57, 49, 50, 39, 50, 113, 47, 36, 12, 115, 0, 102, 0, 16, 67, 60, 83, 64, 11, 4, 39, 11, 4, 13, 11, 6, 112, 65, 0, 12, 3, 95, 54, 88, 89, 58, 35, 89, 113, 47, 0, 0, 7, 196, 5, 84, 211, 36, 76, 0, 13, 69, 80, 83, 142, 37, 48, 47, 36, 50, 37, 89, 0, 0, 7, 131, 195, 167, 1, 76, 32, 0, 0, 11, 68, 48, 144, 153, 20, 55, 37, 71, 37, 0, 14, 70, 52, 243, 147, 36, 85, 82, 65, 13, 89, 57, 132, 0, 7, 195, 4, 145, 83, 76, 36, 0, 10, 67, 29, 83, 6, 81, 127, 55, 83, 0, 8, 197, 12, 84, 148, 21, 48, 76, 24, 2, 54, 49, 89, 58, 35, 89, 113, 47, 36, 12, 111, 50, 37, 112, 65, 0, 81, 195, 168, 109, 101, 32, 0, 6, 194, 36, 192, 76, 32, 0, 0, 17, 70, 72, 85, 143, 49, 97, 82, 34, 36, 84, 127, 55, 84, 112, 34, 0, 0, 17, 5, 19, 46, 22, 46, 16, 89, 37, 55, 84, 129, 48, 55, 6, 112, 0, 0, 0, 0, 6, 195, 52, 18, 83, 76, 0, 0, 0, 8, 67, 52, 18, 76, 21, 0, 10, 13, 67, 13, 68, 140, 24, 49, 116, 47, 34, 127, 55, 0, 14, 3, 95, 56, 88, 49, 35, 47, 34, 13, 84, 114, 12, 0, 0, 0, 10, 69, 61, 85, 16, 85, 64, 21, 0, 10, 11, 69, 12, 131, 197, 85, 32, 49, 117, 34, 0, 0, 15, 70, 76, 19, 83, 84, 225, 192, 89, 35, 65, 89, 40, 68, 0, 0, 0, 0, 24, 2, 56, 49, 49, 35, 47, 34, 13, 84, 114, 12, 111, 50, 37, 112, 65, 0, 81, 195, 168, 109, 101, 32, 0, 6, 194, 52, 80, 72, 32, 0, 9, 198, 21, 84, 211, 36, 243, 147, 76, 12, 3, 95, 57, 88, 50, 39, 50, 113, 47, 0, 102, 0, 0, 8, 67, 32, 245, 0, 21, 0, 10, 0, 0, 0, 0, 0, 11, 3, 95, 63, 65, 55, 6, 112, 47, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 70, 72, 84, 85, 36, 83, 64, 34, 36, 49, 111, 37, 57, 112, 65, 0, 0, 7, 66, 36, 224, 21, 0, 10, 0, 22, 67, 92, 80, 128, 119, 101, 98, 118, 105, 115, 117, 109, 0, 29, 81, 118, 105, 115, 117, 109, 32, 0, 0, 0, 7, 195, 77, 82, 83, 76, 36, 15, 70, 64, 130, 76, 37, 4, 192, 83, 37, 55, 37, 48, 89, 0, 0, 18, 67, 12, 85, 88, 89, 132, 15, 55, 35, 0, 32, 76, 81, 108, 195, 160, 32, 17, 67, 12, 85, 88, 89, 132, 15, 89, 37, 0, 32, 76, 81, 99, 105, 32, 6, 195, 12, 85, 88, 76, 14, 4, 95, 15, 7, 15, 39, 81, 39, 50, 6, 112, 49, 0, 0, 7, 196, 20, 229, 18, 20, 36, 7, 196, 20, 229, 18, 20, 76, 0, 0, 0, 0, 0, 15, 69, 5, 162, 77, 85, 64, 35, 88, 37, 65, 6, 111, 47, 0, 0, 10, 67, 76, 83, 147, 89, 113, 143, 0, 36, 9, 67, 76, 83, 147, 89, 113, 89, 0, 17, 70, 65, 33, 83, 69, 81, 64, 48, 34, 112, 89, 49, 8, 13, 0, 76, 17, 70, 65, 82, 83, 69, 81, 64, 48, 111, 37, 89, 49, 8, 13, 0, 76, 0, 11, 67, 81, 35, 208, 47, 34, 39, 139, 0, 76, 0, 0, 0, 6, 194, 56, 80, 72, 32, 0, 10, 67, 61, 82, 64, 23, 58, 37, 0, 76, 0, 14, 68, 80, 86, 1, 76, 47, 112, 49, 89, 6, 35, 89, 0, 0, 14, 69, 52, 19, 1, 92, 144, 65, 35, 55, 35, 58, 37, 0, 0, 0, 9, 67, 56, 85, 0, 50, 112, 47, 0, 0, 0, 15, 70, 52, 21, 20, 32, 144, 83, 65, 35, 47, 57, 35, 89, 0, 0, 0, 0, 0, 6, 195, 65, 35, 198, 24, 0, 7, 195, 88, 245, 83, 76, 32, 7, 195, 56, 245, 83, 76, 32, 12, 4, 95, 48, 77, 50, 65, 37, 55, 57, 116, 0, 0, 9, 67, 56, 243, 128, 50, 116, 0, 76, 13, 4, 95, 48, 77, 51, 65, 37, 55, 57, 35, 34, 0, 0, 0, 14, 6, 22, 195, 169, 14, 21, 19, 84, 36, 50, 111, 89, 0, 10, 4, 95, 48, 77, 49, 65, 37, 55, 0, 0, 12, 4, 95, 2, 18, 22, 71, 34, 6, 112, 84, 0, 0, 17, 67, 56, 244, 132, 50, 39, 34, 112, 89, 47, 0, 81, 101, 115, 116, 32, 18, 70, 8, 243, 212, 4, 35, 5, 98, 111, 117, 116, 97, 98, 108, 101, 0, 29, 0, 0, 0, 0, 6, 195, 24, 244, 128, 76, 11, 67, 85, 4, 192, 111, 48, 36, 112, 89, 0, 0, 0, 0, 8, 67, 28, 83, 147, 90, 113, 0, 17, 66, 65, 32, 112, 114, 111, 102, 101, 115, 115, 101, 117, 114, 0, 41, 29, 0, 0, 0, 16, 70, 64, 20, 148, 36, 243, 147, 48, 35, 34, 47, 57, 116, 143, 0, 14, 69, 76, 245, 137, 21, 64, 89, 39, 84, 37, 112, 47, 0, 0, 0, 0, 0, 0, 25, 66, 44, 208, 49, 35, 4, 112, 65, 48, 55, 112, 57, 6, 117, 34, 0, 81, 112, 108, 97, 121, 101, 114, 32, 16, 66, 44, 208, 107, 105, 108, 111, 109, 195, 168, 116, 114, 101, 0, 29, 0, 0, 13, 5, 20, 18, 195, 168, 19, 47, 34, 112, 143, 0, 76, 0, 10, 69, 16, 83, 5, 80, 80, 21, 0, 10, 0, 10, 67, 52, 20, 147, 65, 35, 34, 89, 0, 0, 17, 71, 12, 132, 137, 77, 67, 65, 76, 49, 34, 37, 89, 65, 35, 89, 0, 0, 0, 0, 8, 66, 61, 80, 40, 0, 72, 28, 13, 66, 69, 16, 113, 117, 101, 108, 113, 117, 101, 0, 29, 0, 0, 12, 68, 76, 19, 79, 4, 89, 35, 65, 39, 35, 0, 0, 0, 0, 9, 67, 61, 85, 0, 35, 40, 47, 0, 0, 0, 14, 69, 81, 85, 129, 49, 80, 47, 40, 84, 35, 55, 40, 0, 14, 69, 64, 20, 212, 37, 48, 48, 35, 89, 47, 37, 89, 0, 0, 0, 6, 195, 64, 64, 64, 17, 0, 0, 0, 0, 21, 67, 52, 16, 192, 65, 35, 49, 39, 112, 89, 37, 49, 89, 0, 82, 111, 115, 32, 120, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 12, 80, 201, 76, 32, 0, 0, 14, 70, 64, 245, 82, 12, 83, 148, 48, 40, 34, 89, 113, 0, 5, 194, 56, 144, 72, 0, 0, 9, 68, 20, 208, 67, 76, 21, 0, 10, 0, 0, 9, 3, 195, 168, 19, 112, 89, 0, 72, 0, 11, 4, 4, 195, 168, 19, 72, 112, 143, 0, 72, 0, 9, 68, 69, 81, 82, 100, 21, 0, 10, 0, 0, 0, 13, 67, 36, 35, 64, 37, 71, 4, 36, 6, 112, 65, 0, 0, 0, 0, 22, 4, 95, 3, 9, 18, 35, 49, 89, 113, 89, 37, 34, 49, 116, 83, 55, 6, 112, 49, 89, 0, 0, 8, 67, 77, 83, 128, 21, 0, 10, 0, 8, 67, 20, 32, 89, 21, 0, 10, 0, 14, 69, 8, 148, 211, 5, 80, 71, 37, 89, 35, 6, 39, 0, 8, 197, 5, 85, 18, 21, 48, 76, 0, 0, 13, 67, 52, 34, 84, 65, 36, 81, 35, 71, 37, 47, 0, 0, 12, 3, 95, 194, 181, 65, 37, 49, 34, 6, 39, 0, 0, 0, 16, 70, 28, 83, 133, 76, 148, 192, 90, 36, 50, 36, 88, 37, 89, 0, 16, 70, 76, 243, 1, 72, 148, 192, 89, 39, 55, 35, 34, 37, 89, 0, 0, 9, 67, 52, 20, 192, 65, 35, 89, 0, 6, 195, 77, 84, 128, 76, 7, 195, 88, 244, 192, 72, 34, 7, 195, 56, 244, 192, 72, 34, 11, 67, 76, 84, 192, 89, 123, 143, 0, 72, 34, 11, 67, 12, 84, 192, 89, 36, 143, 0, 72, 34, 0, 9, 68, 100, 244, 200, 36, 21, 0, 10, 12, 68, 81, 83, 137, 76, 47, 111, 50, 37, 89, 0, 0, 0, 27, 70, 9, 84, 139, 36, 224, 64, 71, 40, 34, 49, 37, 50, 35, 15, 83, 35, 89, 39, 0, 81, 102, 97, 115, 111, 32, 14, 70, 12, 130, 69, 56, 194, 84, 91, 57, 113, 55, 37, 0, 0, 11, 4, 95, 19, 20, 11, 71, 6, 35, 34, 0, 6, 131, 95, 195, 180, 43, 0, 9, 68, 80, 131, 211, 20, 21, 0, 10, 0, 16, 4, 95, 1, 3, 21, 35, 49, 89, 113, 47, 112, 81, 6, 111, 0, 0, 17, 3, 95, 194, 171, 40, 84, 34, 36, 15, 81, 37, 57, 65, 6, 112, 0, 0, 6, 195, 28, 229, 64, 17, 0, 0, 10, 69, 76, 50, 69, 57, 64, 89, 37, 0, 0, 9, 66, 76, 16, 89, 121, 0, 72, 34, 17, 66, 52, 208, 109, 105, 108, 108, 105, 109, 195, 168, 116, 114, 101, 0, 29, 13, 3, 95, 194, 167, 89, 112, 49, 89, 57, 6, 116, 0, 0, 10, 67, 45, 84, 148, 49, 40, 34, 47, 0, 0, 0, 0, 6, 195, 76, 20, 0, 17, 0, 15, 4, 95, 18, 14, 7, 34, 116, 140, 113, 91, 6, 112, 83, 0, 0, 0, 0, 16, 70, 9, 84, 149, 56, 66, 64, 71, 40, 34, 40, 50, 72, 37, 0, 0, 23, 67, 33, 69, 16, 35, 91, 47, 4, 36, 47, 4, 36, 48, 6, 36, 10, 0, 81, 58, 47, 47, 32, 0, 0, 15, 69, 72, 148, 195, 61, 48, 34, 37, 89, 49, 39, 112, 89, 0, 0, 0, 6, 131, 95, 195, 160, 43, 0, 11, 70, 72, 80, 207, 72, 65, 82, 21, 0, 10, 0, 14, 69, 84, 37, 78, 81, 80, 40, 71, 40, 50, 47, 40, 0, 0, 10, 66, 52, 224, 65, 37, 50, 111, 47, 0, 0, 0, 6, 131, 15, 195, 185, 76, 0, 0, 0, 0, 11, 68, 48, 83, 206, 20, 55, 36, 127, 50, 0, 0, 0, 0, 0, 0, 0, 20, 4, 95, 1, 3, 50, 72, 40, 71, 55, 35, 49, 89, 113, 47, 112, 81, 6, 111, 0, 0, 0, 0, 13, 69, 60, 97, 147, 21, 64, 127, 83, 89, 112, 47, 0, 0, 9, 66, 60, 176, 39, 49, 36, 0, 76, 9, 67, 61, 84, 147, 40, 34, 89, 0, 9, 66, 80, 16, 47, 121, 0, 72, 34, 0, 0, 15, 70, 52, 144, 200, 4, 83, 0, 65, 37, 49, 35, 112, 55, 0, 0, 9, 198, 80, 245, 74, 61, 84, 147, 76, 0, 0, 0, 0, 0, 0, 0, 11, 68, 76, 51, 213, 80, 89, 49, 40, 47, 0, 0, 0, 6, 195, 64, 197, 83, 76, 18, 3, 95, 194, 187, 83, 112, 34, 65, 36, 15, 81, 37, 57, 65, 6, 112, 0, 0, 9, 67, 73, 85, 0, 34, 111, 47, 0, 0, 15, 67, 24, 147, 5, 21, 0, 10, 81, 122, 105, 108, 108, 97, 32, 0, 0, 0, 15, 67, 80, 86, 20, 21, 0, 10, 81, 97, 108, 111, 117, 100, 32, 9, 67, 29, 84, 192, 81, 111, 89, 0, 15, 67, 69, 20, 192, 113, 117, 101, 108, 113, 117, 101, 115, 0, 29, 0, 12, 68, 56, 145, 197, 72, 50, 37, 90, 112, 34, 0, 0, 15, 69, 4, 208, 90, 60, 224, 35, 65, 35, 88, 6, 127, 50, 0, 0, 0, 9, 67, 77, 84, 192, 89, 111, 0, 36, 9, 67, 77, 84, 192, 89, 111, 89, 0, 0, 11, 68, 76, 131, 210, 80, 91, 127, 34, 47, 0, 12, 68, 4, 64, 77, 76, 35, 72, 35, 65, 89, 0, 0, 20, 2, 195, 151, 65, 111, 55, 47, 37, 48, 55, 37, 6, 36, 10, 48, 6, 35, 34, 0, 0, 17, 66, 77, 64, 89, 114, 49, 55, 40, 0, 81, 99, 108, 111, 117, 100, 32, 9, 66, 77, 64, 89, 6, 114, 140, 0, 0, 8, 67, 32, 83, 16, 21, 0, 10, 0, 19, 72, 5, 35, 65, 28, 81, 4, 60, 224, 35, 34, 65, 35, 81, 36, 72, 116, 0, 23, 68, 80, 83, 80, 76, 47, 113, 88, 113, 47, 113, 0, 82, 101, 110, 32, 116, 101, 109, 112, 115, 32, 0, 0, 16, 67, 77, 68, 0, 89, 37, 55, 47, 13, 12, 48, 55, 6, 112, 0, 0, 0, 22, 2, 194, 166, 89, 36, 48, 35, 34, 35, 47, 117, 34, 15, 84, 112, 47, 37, 49, 35, 55, 0, 0, 10, 69, 8, 85, 20, 21, 32, 21, 0, 10, 15, 69, 21, 131, 195, 21, 64, 112, 81, 88, 39, 89, 112, 47, 0, 0, 6, 194, 76, 80, 72, 32, 0, 19, 67, 16, 84, 20, 100, 195, 169, 112, 97, 114, 116, 101, 109, 101, 110, 116, 0, 29, 8, 2, 194, 165, 57, 112, 50, 0, 0, 15, 68, 13, 144, 133, 72, 21, 0, 10, 81, 108, 105, 110, 107, 32, 13, 5, 16, 18, 195, 168, 19, 48, 34, 112, 143, 0, 76, 9, 2, 194, 162, 89, 112, 50, 47, 0, 0, 15, 6, 1, 16, 18, 195, 168, 19, 35, 48, 34, 112, 143, 0, 76, 9, 2, 194, 163, 55, 37, 84, 34, 0, 0, 0, 8, 67, 56, 245, 0, 21, 0, 10, 9, 67, 76, 85, 0, 89, 112, 47, 0, 16, 70, 48, 17, 84, 37, 66, 65, 55, 36, 47, 37, 89, 57, 35, 0, 0, 16, 2, 194, 174, 65, 35, 34, 49, 72, 36, 48, 39, 88, 6, 36, 0, 0, 16, 70, 32, 243, 132, 85, 32, 83, 23, 116, 72, 111, 34, 35, 89, 0, 23, 73, 81, 85, 20, 37, 21, 65, 57, 66, 64, 47, 40, 47, 37, 49, 58, 6, 35, 50, 47, 37, 0, 10, 2, 194, 175, 65, 35, 49, 34, 116, 0, 5, 130, 195, 167, 43, 0, 20, 2, 194, 172, 47, 37, 34, 112, 10, 83, 35, 49, 111, 55, 47, 35, 47, 37, 83, 0, 5, 130, 195, 164, 43, 0, 17, 67, 77, 81, 0, 89, 111, 72, 112, 89, 47, 0, 81, 101, 115, 116, 32, 0, 11, 68, 28, 227, 205, 20, 81, 50, 127, 65, 0, 5, 130, 195, 162, 43, 0, 12, 2, 197, 147, 39, 15, 13, 15, 55, 37, 36, 0, 0, 7, 130, 195, 160, 14, 43, 9, 7, 2, 195, 160, 35, 0, 76, 0, 7, 2, 194, 169, 21, 0, 10, 0, 11, 70, 12, 243, 80, 85, 65, 82, 21, 0, 10, 24, 11, 1, 21, 10, 15, 21, 18, 4, 39, 8, 21, 9, 97, 117, 106, 111, 117, 114, 100, 117, 105, 0, 29, 13, 2, 194, 182, 48, 35, 34, 35, 81, 34, 35, 83, 0, 5, 130, 195, 174, 43, 0, 11, 69, 28, 147, 12, 21, 48, 90, 37, 55, 0, 8, 2, 194, 183, 48, 58, 114, 0, 5, 130, 195, 175, 43, 0, 14, 70, 52, 245, 76, 61, 81, 0, 65, 40, 55, 40, 72, 0, 7, 195, 76, 242, 83, 76, 36, 9, 66, 60, 224, 116, 134, 0, 76, 32, 0, 6, 195, 4, 32, 192, 17, 0, 16, 2, 194, 178, 48, 111, 37, 89, 6, 113, 89, 15, 72, 6, 132, 0, 5, 130, 195, 170, 43, 0, 16, 2, 194, 179, 48, 111, 37, 89, 113, 89, 15, 47, 34, 58, 35, 0, 5, 130, 195, 171, 43, 5, 130, 195, 171, 43, 0, 10, 3, 21, 46, 19, 111, 12, 112, 89, 0, 5, 130, 195, 168, 43, 0, 7, 195, 60, 229, 0, 76, 36, 6, 195, 76, 242, 84, 76, 15, 2, 194, 177, 48, 55, 6, 111, 88, 40, 65, 58, 6, 114, 0, 5, 130, 195, 169, 43, 0, 12, 68, 56, 85, 137, 76, 50, 36, 84, 37, 89, 0, 6, 195, 72, 144, 65, 17, 14, 2, 194, 190, 47, 34, 58, 35, 10, 49, 6, 35, 34, 0, 5, 130, 195, 182, 43, 0, 12, 67, 85, 35, 0, 111, 12, 112, 34, 112, 55, 0, 27, 2, 194, 191, 48, 58, 114, 15, 72, 114, 47, 36, 34, 39, 81, 35, 89, 57, 116, 15, 114, 84, 112, 34, 89, 36, 0, 17, 2, 195, 183, 72, 37, 84, 37, 88, 6, 36, 10, 48, 6, 35, 34, 0, 0, 6, 130, 195, 180, 14, 43, 11, 2, 194, 188, 115, 10, 49, 6, 35, 34, 0, 0, 12, 2, 194, 189, 115, 10, 72, 13, 65, 6, 37, 0, 0, 10, 2, 194, 186, 72, 13, 81, 34, 36, 0, 13, 4, 95, 3, 5, 4, 89, 36, 72, 6, 37, 57, 0, 0, 8, 197, 25, 84, 133, 57, 64, 76, 0, 15, 70, 13, 35, 193, 80, 145, 64, 49, 34, 39, 35, 89, 37, 0, 17, 70, 48, 244, 147, 69, 81, 64, 55, 127, 34, 89, 49, 8, 13, 0, 76, 15, 67, 77, 100, 0, 89, 37, 55, 84, 129, 48, 55, 6, 112, 0, 10, 2, 194, 184, 89, 36, 72, 37, 57, 0, 0, 12, 67, 60, 225, 192, 39, 4, 112, 50, 90, 36, 0, 15, 4, 95, 12, 9, 7, 55, 37, 81, 35, 47, 6, 111, 34, 0, 5, 130, 195, 177, 43, 0, 0, 19, 70, 12, 19, 22, 4, 67, 211, 99, 97, 108, 118, 97, 100, 111, 115, 115, 0, 29, 14, 69, 100, 19, 213, 73, 64, 23, 37, 35, 40, 34, 47, 0, 10, 67, 8, 145, 78, 71, 37, 114, 134, 0, 6, 195, 80, 83, 0, 76, 0, 16, 70, 44, 20, 129, 60, 177, 64, 49, 35, 34, 35, 39, 49, 36, 0, 16, 70, 9, 35, 199, 48, 145, 64, 98, 114, 101, 117, 105, 108, 0, 29, 6, 194, 80, 80, 72, 32, 5, 130, 195, 188, 43, 0, 17, 70, 48, 148, 212, 8, 246, 0, 55, 37, 89, 47, 71, 127, 49, 89, 0, 6, 195, 76, 242, 64, 76, 0, 0, 5, 130, 195, 187, 43, 0, 0, 6, 195, 52, 50, 64, 17, 5, 130, 195, 185, 43, 0, 0, 10, 67, 4, 49, 82, 35, 89, 112, 34, 0, 11, 67, 24, 145, 82, 83, 57, 36, 34, 0, 36, 0, 6, 194, 81, 80, 76, 32, 0, 6, 195, 72, 21, 16, 17, 12, 67, 60, 115, 64, 39, 90, 4, 36, 112, 65, 0, 0, 11, 68, 12, 243, 77, 20, 49, 127, 65, 0, 76, 7, 196, 88, 242, 67, 36, 76, 0, 0, 0, 9, 67, 32, 211, 64, 107, 117, 65, 0, 0, 0, 14, 69, 80, 245, 84, 21, 48, 47, 6, 40, 47, 143, 0, 76, 0, 0, 0, 0, 0, 0, 18, 71, 77, 112, 90, 36, 192, 78, 16, 89, 58, 35, 88, 37, 55, 113, 72, 0, 18, 71, 29, 35, 197, 56, 192, 78, 16, 81, 34, 39, 112, 50, 55, 113, 72, 0, 0, 11, 68, 12, 240, 213, 76, 49, 127, 49, 111, 0, 7, 196, 4, 145, 78, 80, 76, 0, 0, 7, 66, 85, 64, 111, 47, 0, 0, 18, 71, 77, 69, 84, 80, 112, 82, 80, 91, 47, 40, 47, 81, 35, 34, 47, 0, 6, 195, 64, 85, 64, 76, 0, 0, 0, 0, 0, 12, 4, 6, 195, 187, 20, 83, 111, 140, 0, 76, 36, 0, 12, 67, 72, 145, 78, 34, 37, 6, 114, 134, 0, 76, 0, 0, 8, 67, 8, 22, 64, 21, 0, 10, 0, 0, 12, 69, 32, 20, 133, 56, 112, 23, 35, 34, 113, 0, 0, 0, 0, 0, 14, 69, 12, 147, 133, 52, 16, 89, 37, 50, 36, 65, 35, 0, 0, 0, 10, 67, 24, 21, 84, 83, 39, 140, 0, 76, 0, 9, 68, 36, 228, 21, 80, 21, 0, 10, 10, 68, 64, 242, 78, 28, 48, 58, 114, 0, 7, 2, 95, 6, 112, 83, 0, 0, 8, 195, 48, 85, 82, 72, 36, 40, 7, 195, 48, 85, 82, 72, 34, 0, 0, 6, 2, 95, 5, 13, 0, 0, 0, 0, 6, 2, 95, 9, 37, 0, 0, 7, 2, 95, 8, 35, 91, 0, 0, 13, 67, 37, 32, 192, 125, 4, 112, 34, 23, 89, 36, 0, 6, 2, 95, 15, 39, 0, 0, 8, 196, 88, 245, 18, 20, 72, 34, 8, 196, 56, 245, 18, 20, 72, 34, 7, 2, 95, 14, 112, 50, 0, 0, 7, 2, 95, 13, 112, 65, 0, 0, 7, 2, 95, 12, 112, 55, 0, 0, 6, 195, 88, 21, 88, 76, 7, 195, 85, 48, 64, 17, 42, 7, 2, 95, 19, 112, 89, 0, 0, 7, 196, 64, 242, 78, 80, 37, 7, 196, 64, 242, 78, 80, 76, 7, 2, 95, 18, 112, 34, 0, 0, 0, 16, 70, 76, 48, 78, 56, 84, 128, 89, 49, 35, 50, 117, 34, 0, 37, 16, 70, 76, 48, 78, 56, 84, 128, 89, 49, 35, 50, 36, 120, 0, 36, 0, 0, 19, 72, 8, 19, 135, 48, 17, 5, 76, 128, 71, 113, 81, 55, 35, 72, 112, 91, 0, 0, 18, 9, 195, 169, 12, 15, 17, 21, 5, 14, 20, 36, 55, 39, 49, 113, 140, 0, 25, 5, 14, 39, 5, 19, 20, 50, 6, 112, 89, 15, 48, 6, 35, 143, 0, 82, 99, 101, 32, 112, 97, 115, 32, 6, 2, 95, 21, 111, 0, 0, 13, 4, 95, 226, 136, 158, 37, 50, 83, 37, 50, 37, 0, 0, 7, 195, 76, 243, 148, 76, 36, 0, 0, 22, 69, 4, 68, 204, 81, 96, 35, 72, 36, 112, 89, 6, 112, 55, 15, 47, 36, 84, 6, 36, 0, 13, 2, 95, 25, 11, 37, 12, 81, 34, 6, 112, 49, 0, 0, 8, 2, 95, 24, 37, 49, 89, 0, 0, 26, 67, 25, 146, 64, 83, 117, 34, 15, 57, 117, 34, 15, 125, 50, 83, 117, 34, 65, 6, 112, 57, 91, 117, 50, 0, 0, 0, 0, 0, 15, 70, 76, 48, 78, 56, 84, 147, 89, 49, 35, 50, 117, 34, 0, 7, 195, 49, 82, 64, 76, 32, 9, 2, 95, 35, 72, 57, 112, 88, 0, 0, 6, 195, 76, 245, 83, 76, 10, 2, 95, 34, 81, 37, 57, 65, 112, 0, 0, 8, 197, 12, 243, 148, 72, 80, 76, 22, 2, 95, 33, 48, 58, 114, 15, 72, 112, 49, 89, 49, 55, 35, 65, 35, 89, 57, 6, 116, 0, 0, 0, 6, 195, 88, 21, 84, 76, 9, 67, 76, 243, 128, 89, 116, 0, 37, 7, 195, 76, 243, 128, 76, 34, 14, 2, 95, 39, 35, 48, 39, 89, 47, 34, 6, 127, 83, 0, 0, 18, 2, 95, 38, 10, 36, 10, 49, 39, 65, 112, 34, 89, 37, 6, 35, 55, 0, 0, 0, 7, 195, 20, 195, 5, 76, 32, 19, 67, 52, 195, 5, 109, 97, 100, 101, 109, 111, 105, 115, 101, 108, 108, 101, 0, 29, 0, 9, 67, 8, 147, 128, 71, 37, 50, 0, 16, 71, 52, 84, 211, 36, 85, 82, 76, 65, 36, 89, 57, 132, 143, 0, 0, 16, 4, 95, 3, 1, 16, 65, 35, 90, 111, 89, 49, 6, 111, 55, 0, 0, 9, 197, 76, 243, 77, 21, 48, 76, 36, 18, 2, 95, 41, 48, 35, 34, 113, 47, 112, 88, 10, 72, 34, 58, 35, 47, 0, 0, 16, 70, 85, 4, 5, 72, 53, 84, 111, 48, 112, 34, 49, 117, 47, 0, 16, 2, 95, 40, 48, 35, 34, 113, 47, 112, 88, 10, 81, 39, 91, 0, 0, 8, 67, 32, 84, 128, 21, 0, 10, 13, 2, 95, 47, 71, 35, 34, 39, 71, 55, 37, 49, 0, 0, 15, 70, 72, 84, 211, 20, 229, 0, 34, 13, 89, 6, 113, 140, 0, 10, 2, 95, 46, 23, 48, 58, 2, 114, 0, 0, 9, 2, 95, 45, 47, 37, 34, 112, 0, 0, 8, 67, 32, 84, 133, 21, 0, 10, 11, 2, 95, 44, 84, 37, 34, 81, 111, 55, 0, 0, 8, 67, 53, 36, 192, 21, 0, 10, 10, 2, 95, 51, 47, 34, 58, 35, 143, 0, 0, 19, 68, 76, 18, 78, 80, 89, 114, 49, 55, 40, 0, 81, 99, 108, 111, 117, 100, 32, 8, 2, 95, 50, 72, 132, 143, 0, 0, 6, 2, 95, 49, 115, 0, 0, 10, 2, 95, 48, 88, 36, 34, 39, 0, 76, 0, 8, 2, 95, 55, 89, 112, 47, 0, 0, 9, 198, 64, 197, 80, 5, 37, 0, 76, 8, 2, 95, 54, 89, 37, 144, 0, 0, 8, 2, 95, 53, 89, 114, 49, 0, 0, 9, 2, 95, 52, 49, 35, 47, 34, 0, 0, 16, 2, 95, 59, 48, 58, 114, 15, 84, 37, 34, 81, 6, 111, 55, 0, 0, 13, 2, 95, 58, 72, 6, 132, 15, 48, 58, 6, 114, 0, 0, 8, 2, 95, 57, 50, 117, 83, 0, 0, 9, 2, 95, 56, 23, 111, 37, 141, 0, 0, 21, 2, 95, 63, 48, 58, 114, 15, 72, 114, 47, 112, 34, 39, 81, 35, 89, 57, 6, 116, 0, 0, 13, 2, 95, 62, 89, 111, 48, 36, 34, 37, 117, 34, 0, 0, 9, 2, 95, 61, 36, 81, 35, 55, 0, 0, 12, 2, 95, 60, 114, 83, 36, 34, 37, 117, 34, 0, 0, 8, 67, 72, 150, 128, 34, 37, 0, 0, 0, 0, 15, 70, 52, 84, 135, 84, 86, 128, 65, 112, 34, 81, 112, 88, 0, 0, 10, 134, 5, 195, 187, 20, 5, 19, 76, 36, 10, 134, 6, 195, 187, 20, 5, 19, 76, 36, 0, 0, 0, 0, 19, 71, 8, 19, 1, 8, 243, 11, 4, 71, 35, 55, 35, 71, 127, 55, 49, 35, 0, 0, 0, 18, 8, 2, 195, 169, 12, 1, 18, 21, 19, 71, 36, 55, 35, 34, 111, 89, 0, 8, 197, 9, 35, 20, 81, 144, 17, 0, 0, 0, 13, 70, 88, 147, 131, 20, 229, 0, 84, 114, 89, 113, 0, 12, 68, 48, 20, 197, 72, 55, 35, 88, 112, 34, 0, 0, 0, 16, 70, 4, 225, 197, 48, 84, 192, 113, 50, 90, 36, 55, 112, 89, 0, 0, 12, 67, 85, 48, 128, 111, 12, 112, 89, 71, 36, 0, 0, 9, 68, 64, 18, 78, 80, 21, 0, 10, 15, 70, 12, 243, 147, 20, 229, 0, 49, 116, 89, 6, 113, 140, 0, 0, 29, 67, 12, 129, 70, 99, 104, 195, 169, 100, 101, 117, 118, 114, 101, 115, 0, 29, 81, 100, 39, 111, 101, 117, 118, 114, 101, 115, 32, 27, 67, 12, 129, 70, 99, 104, 195, 169, 100, 101, 117, 118, 114, 101, 0, 29, 81, 100, 39, 111, 101, 117, 118, 114, 101, 32, 10, 67, 4, 192, 78, 35, 55, 35, 50, 0, 0, 15, 70, 8, 18, 1, 52, 20, 192, 71, 35, 35, 65, 35, 89, 0, 9, 198, 69, 81, 76, 48, 84, 192, 76, 0, 18, 9, 17, 21, 5, 12, 17, 21, 39, 21, 14, 49, 112, 55, 49, 115, 0, 76, 6, 195, 36, 65, 64, 17, 16, 4, 95, 226, 128, 153, 35, 48, 39, 89, 47, 34, 6, 127, 83, 0, 0, 16, 4, 95, 226, 128, 152, 35, 48, 39, 89, 47, 34, 6, 127, 83, 0, 17, 4, 95, 4, 15, 20, 48, 58, 114, 89, 111, 89, 49, 34, 6, 37, 0, 0, 13, 69, 9, 81, 134, 21, 32, 71, 132, 83, 117, 34, 0, 0, 9, 67, 4, 64, 77, 35, 72, 113, 0, 0, 8, 67, 76, 129, 64, 21, 0, 10, 14, 2, 95, 91, 49, 34, 127, 91, 112, 10, 81, 39, 91, 0, 0, 0, 0, 5, 194, 84, 176, 17, 0, 17, 71, 32, 85, 82, 80, 147, 206, 76, 23, 117, 34, 47, 57, 116, 143, 0, 11, 2, 95, 95, 89, 40, 55, 37, 67, 36, 0, 0, 15, 70, 48, 22, 129, 72, 85, 0, 55, 35, 88, 35, 34, 112, 0, 9, 68, 40, 19, 69, 76, 21, 0, 10, 12, 68, 4, 67, 73, 56, 35, 72, 65, 37, 50, 0, 15, 2, 95, 94, 89, 37, 34, 49, 116, 83, 55, 112, 49, 89, 0, 0, 15, 2, 95, 93, 49, 34, 127, 91, 112, 10, 72, 34, 58, 35, 0, 0, 17, 67, 88, 148, 0, 84, 4, 37, 15, 4, 35, 57, 15, 48, 6, 37, 0, 12, 2, 95, 92, 71, 35, 49, 89, 55, 35, 91, 0, 0, 0, 12, 68, 60, 20, 201, 76, 39, 35, 88, 37, 89, 0, 0, 0, 16, 2, 95, 96, 35, 49, 89, 6, 113, 10, 81, 34, 6, 35, 84, 0, 0, 0, 0, 16, 69, 4, 148, 130, 85, 48, 97, 105, 114, 98, 117, 115, 115, 0, 29, 0, 0, 0, 0, 8, 197, 80, 19, 132, 37, 48, 76, 0, 16, 4, 95, 7, 18, 22, 35, 49, 89, 113, 81, 34, 6, 35, 84, 0, 0, 8, 67, 20, 66, 84, 21, 0, 10, 20, 67, 88, 148, 192, 84, 37, 88, 35, 84, 37, 0, 82, 195, 160, 32, 118, 105, 115, 32, 6, 195, 76, 244, 192, 17, 0, 0, 6, 195, 12, 129, 90, 76, 0, 0, 12, 71, 8, 197, 69, 80, 243, 212, 32, 21, 0, 10, 9, 67, 8, 148, 192, 71, 37, 89, 0, 11, 67, 16, 84, 192, 72, 123, 143, 0, 72, 34, 21, 67, 48, 84, 192, 55, 123, 15, 55, 132, 34, 0, 76, 32, 81, 108, 101, 117, 114, 115, 32, 20, 67, 48, 84, 192, 55, 123, 15, 55, 132, 34, 0, 76, 32, 81, 108, 101, 117, 114, 32, 11, 67, 80, 84, 192, 47, 123, 143, 0, 72, 34, 12, 67, 48, 84, 192, 55, 123, 143, 0, 36, 40, 72, 11, 67, 48, 84, 192, 55, 123, 143, 0, 34, 76, 0, 0, 0, 13, 70, 28, 83, 210, 28, 84, 192, 90, 127, 34, 90, 0, 15, 70, 25, 32, 78, 12, 148, 192, 83, 34, 113, 89, 37, 89, 0, 0, 19, 71, 25, 32, 78, 12, 84, 195, 60, 83, 34, 113, 50, 91, 112, 89, 49, 39, 0, 0, 10, 68, 12, 242, 78, 28, 49, 58, 114, 0, 0, 12, 69, 4, 36, 197, 57, 64, 35, 71, 89, 113, 0, 0, 0, 15, 2, 95, 123, 35, 49, 127, 55, 35, 72, 10, 81, 39, 91, 0, 13, 4, 95, 4, 9, 1, 47, 34, 36, 65, 6, 35, 0, 0, 0, 13, 69, 5, 85, 15, 85, 32, 39, 47, 40, 34, 0, 76, 0, 20, 70, 5, 81, 9, 8, 193, 64, 21, 0, 10, 81, 109, 97, 110, 97, 103, 101, 114, 32, 8, 66, 80, 240, 47, 40, 0, 76, 0, 0, 0, 8, 67, 100, 85, 0, 21, 0, 10, 17, 2, 95, 125, 35, 49, 127, 55, 35, 72, 10, 72, 34, 58, 35, 47, 0, 0, 16, 70, 100, 241, 200, 61, 84, 148, 23, 37, 39, 81, 40, 34, 47, 0, 18, 2, 95, 124, 71, 35, 34, 10, 84, 112, 34, 47, 37, 49, 6, 35, 55, 0, 0, 17, 70, 4, 197, 5, 72, 81, 207, 35, 55, 47, 112, 34, 36, 81, 39, 0, 0, 9, 68, 5, 4, 12, 20, 21, 0, 10, 0, 16, 70, 9, 35, 215, 28, 194, 69, 98, 114, 101, 117, 105, 108, 0, 29, 15, 69, 52, 36, 143, 48, 16, 112, 65, 71, 34, 39, 55, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 67, 61, 1, 78, 21, 0, 10, 0, 6, 194, 84, 224, 34, 76, 0, 0, 0, 0, 0, 6, 195, 81, 96, 64, 17, 0, 0, 0, 8, 67, 25, 33, 69, 21, 0, 10, 0, 10, 67, 25, 33, 68, 83, 34, 112, 72, 0, 0, 0, 12, 69, 9, 81, 7, 21, 64, 71, 111, 75, 112, 0, 0, 12, 4, 95, 35, 51, 50, 112, 89, 48, 35, 89, 0, 0, 12, 67, 20, 65, 128, 13, 72, 4, 36, 112, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 70, 4, 52, 143, 8, 21, 0, 97, 99, 114, 111, 98, 97, 116, 101, 0, 29, 0, 0, 11, 70, 61, 85, 12, 60, 242, 192, 21, 0, 10, 5, 194, 97, 144, 17, 0, 11, 67, 25, 33, 84, 83, 34, 6, 112, 47, 0, 12, 67, 4, 67, 128, 35, 72, 4, 36, 112, 50, 0, 0, 16, 70, 28, 19, 135, 77, 65, 82, 81, 113, 81, 89, 47, 112, 34, 0, 0, 9, 67, 105, 85, 0, 88, 111, 47, 0, 0, 16, 70, 21, 66, 5, 72, 225, 84, 36, 47, 112, 34, 50, 112, 47, 0, 0, 18, 71, 4, 100, 137, 44, 16, 78, 76, 35, 83, 34, 37, 49, 35, 50, 89, 0, 0, 0, 8, 197, 40, 19, 65, 37, 48, 76, 0, 38, 70, 36, 229, 5, 72, 225, 84, 114, 47, 112, 34, 50, 6, 112, 47, 15, 112, 49, 89, 48, 55, 127, 34, 6, 117, 34, 0, 81, 101, 120, 112, 108, 111, 114, 101, 114, 32, 17, 70, 36, 229, 5, 72, 225, 84, 114, 47, 112, 34, 50, 6, 112, 47, 0, 0, 0, 9, 198, 12, 243, 77, 20, 229, 0, 76, 0, 0, 12, 70, 40, 16, 209, 84, 84, 192, 90, 35, 49, 0, 0, 0, 0, 0, 0, 6, 195, 13, 5, 64, 17, 0, 12, 68, 4, 195, 210, 76, 35, 55, 127, 34, 0, 76, 0, 0, 0, 0, 0, 14, 69, 64, 243, 4, 21, 32, 48, 127, 55, 72, 112, 34, 0, 0, 0, 14, 67, 28, 134, 128, 90, 37, 81, 35, 112, 34, 47, 89, 0, 0, 0, 9, 67, 88, 245, 0, 84, 127, 47, 0, 0, 0, 14, 67, 44, 134, 128, 49, 37, 55, 39, 112, 34, 47, 89, 0, 0, 9, 68, 8, 197, 69, 76, 21, 0, 10, 0, 10, 69, 28, 243, 199, 48, 80, 21, 0, 10, 0, 19, 9, 16, 1, 20, 1, 17, 21, 195, 168, 19, 48, 35, 47, 35, 49, 112, 89, 0, 0, 0, 0, 0, 9, 134, 22, 15, 9, 12, 195, 160, 76, 0, 11, 67, 9, 37, 84, 71, 34, 6, 111, 47, 0, 0, 0, 13, 69, 8, 148, 211, 85, 48, 71, 37, 89, 111, 89, 0, 0, 0, 0, 7, 196, 5, 85, 18, 20, 76, 0, 14, 69, 88, 148, 135, 36, 224, 84, 37, 34, 90, 37, 50, 0, 0, 14, 67, 96, 96, 197, 37, 49, 89, 112, 83, 89, 36, 13, 0, 0, 6, 195, 12, 144, 64, 17, 0, 0, 16, 70, 77, 84, 208, 20, 228, 197, 89, 111, 89, 48, 112, 50, 89, 0, 0, 16, 70, 72, 21, 9, 60, 228, 192, 34, 35, 47, 57, 116, 143, 0, 36, 15, 70, 16, 21, 9, 60, 228, 192, 72, 35, 47, 57, 116, 143, 0, 11, 70, 12, 243, 12, 36, 228, 192, 21, 0, 10, 0, 13, 67, 52, 209, 64, 109, 97, 100, 97, 109, 101, 0, 29, 0, 0, 21, 73, 12, 243, 147, 80, 21, 9, 60, 228, 192, 49, 116, 89, 47, 35, 47, 57, 116, 143, 0, 10, 69, 12, 83, 148, 21, 32, 21, 0, 10, 8, 197, 17, 84, 129, 57, 64, 76, 0, 23, 6, 17, 21, 39, 5, 19, 20, 49, 112, 89, 49, 13, 0, 72, 82, 99, 101, 32, 113, 117, 101, 32, 0, 6, 195, 85, 65, 128, 17, 0, 0, 0, 0, 9, 67, 92, 146, 64, 58, 37, 12, 0, 6, 195, 80, 242, 64, 76, 0, 9, 68, 48, 241, 207, 56, 21, 0, 10, 0, 0, 0, 10, 199, 80, 245, 84, 20, 99, 201, 76, 76, 0, 0, 0, 0, 12, 71, 52, 84, 211, 20, 225, 197, 72, 21, 0, 10, 0, 0, 6, 195, 48, 242, 78, 76, 0, 8, 67, 76, 19, 69, 21, 0, 10, 0, 0, 9, 68, 4, 35, 213, 80, 21, 0, 10, 0, 12, 69, 76, 245, 82, 37, 48, 89, 40, 34, 37, 0, 0, 15, 70, 48, 84, 207, 80, 131, 192, 55, 36, 88, 127, 47, 39, 0, 0, 0, 9, 68, 48, 241, 201, 56, 21, 0, 10, 0, 0, 16, 70, 88, 245, 9, 60, 228, 192, 84, 127, 39, 47, 57, 116, 143, 0, 0, 7, 195, 36, 196, 192, 76, 32, 0, 12, 68, 76, 208, 82, 80, 89, 65, 35, 34, 47, 0, 9, 68, 80, 129, 82, 20, 21, 0, 10, 0, 0, 0, 0, 0, 23, 73, 21, 132, 12, 60, 149, 9, 60, 228, 192, 112, 49, 89, 48, 55, 58, 35, 47, 57, 116, 143, 0, 0, 0, 14, 67, 4, 68, 204, 35, 72, 4, 36, 112, 89, 112, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 7, 20, 1, 195, 175, 23, 1, 14, 47, 35, 57, 58, 35, 50, 0, 8, 197, 64, 51, 67, 36, 16, 17, 0, 0, 0, 0, 6, 20, 83, 1, 0, 0, 111, 0, 101, 0, 0, 0, 0, 0, 6, 18, 66, 100, 0, 101, 0, 108, 0, 110, 0, 114, 0, 116, 0, 117, 0, 7, 6, 18, 67, 98, 0, 99, 0, 100, 0, 102, 0, 103, 0, 104, 0, 107, 0, 112, 0, 116, 0, 118, 0, 7, 6, 18, 68, 100, 0, 108, 0, 109, 0, 110, 0, 115, 0, 116, 0, 118, 0, 7, 6, 18, 69, 99, 0, 100, 0, 102, 0, 103, 0, 108, 0, 109, 0, 110, 0, 118, 0, 7, 6, 18, 70, 103, 0, 104, 0, 107, 0, 108, 0, 109, 0, 118, 0, 119, 0, 7, 6, 18, 71, 98, 108, 0, 98, 114, 0, 99, 108, 0, 99, 114, 0, 99, 116, 0, 100, 114, 0, 102, 108, 0, 102, 114, 0, 102, 116, 0, 103, 108, 0, 103, 114, 0, 107, 108, 0, 107, 114, 0, 112, 108, 0, 112, 114, 0, 116, 114, 0, 118, 114, 0, 7, 6, 18, 72, 195, 169, 99, 0, 195, 169, 100, 0, 101, 99, 0, 101, 100, 0, 108, 98, 0, 108, 99, 0, 108, 100, 0, 108, 103, 0, 108, 109, 0, 108, 110, 0, 108, 112, 0, 108, 116, 0, 108, 118, 0, 114, 98, 0, 114, 99, 0, 114, 100, 0, 114, 102, 0, 114, 103, 0, 114, 108, 0, 114, 109, 0, 114, 110, 0, 114, 112, 0, 114, 115, 0, 114, 116, 0, 114, 118, 0, 7, 6, 18, 73, 99, 104, 0, 113, 117, 0, 103, 117, 0, 98, 0, 99, 0, 100, 0, 102, 0, 103, 0, 104, 0, 106, 0, 107, 0, 108, 0, 109, 0, 110, 0, 112, 0, 113, 0, 114, 0, 115, 0, 116, 0, 118, 0, 119, 0, 120, 0, 122, 0, 7, 6, 18, 74, 108, 0, 114, 0, 115, 0, 7, 6, 18, 75, 105, 97, 0, 105, 101, 0, 105, 111, 0, 117, 97, 0, 117, 101, 0, 117, 105, 0, 117, 111, 0, 7, 6, 18, 76, 98, 0, 112, 0, 7, 6, 18, 77, 97, 195, 175, 0, 114, 195, 169, 0, 195, 169, 0, 195, 168, 0, 97, 108, 0, 105, 98, 0, 105, 101, 0, 105, 113, 0, 111, 109, 0, 111, 110, 0, 121, 109, 0, 108, 0, 7, 6, 18, 78, 101, 114, 0, 104, 110, 0, 100, 0, 103, 0, 107, 0, 108, 0, 112, 0, 7, 6, 18, 79, 98, 101, 0, 105, 110, 0, 117, 112, 0, 117, 116, 0, 7, 6, 18, 80, 99, 0, 102, 0, 103, 0, 104, 0, 7, 6, 18, 81, 48, 48, 0, 48, 49, 0, 48, 50, 0, 48, 51, 0, 48, 52, 0, 48, 53, 0, 48, 54, 0, 48, 55, 0, 48, 56, 0, 48, 57, 0, 49, 48, 0, 49, 49, 0, 49, 50, 0, 49, 51, 0, 49, 52, 0, 49, 53, 0, 49, 54, 0, 49, 55, 0, 49, 56, 0, 49, 57, 0, 50, 48, 0, 50, 49, 0, 50, 50, 0, 50, 51, 0, 48, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 7, 6, 18, 82, 48, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 7, 6, 195, 167, 0, 4, 3, 89, 0, 39, 8, 2, 14, 128, 140, 130, 0, 7, 6, 195, 168, 0, 109, 101, 1, 16, 3, 37, 112, 65, 0, 4, 3, 112, 0, 115, 2, 32, 0, 4, 115, 1, 109, 2, 32, 3, 112, 89, 0, 115, 1, 110, 2, 32, 0, 115, 1, 112, 2, 32, 0, 115, 1, 114, 17, 65, 2, 32, 0, 7, 6, 195, 171, 0, 1, 117, 3, 0, 1, 111, 110, 2, 32, 3, 36, 0, 3, 112, 0, 7, 6, 195, 175, 0, 3, 37, 0, 115, 1, 97, 17, 67, 2, 32, 3, 37, 89, 0, 4, 1, 17, 65, 2, 32, 3, 57, 0, 1, 17, 65, 2, 108, 17, 65, 0, 101, 1, 17, 65, 2, 32, 0, 110, 2, 25, 3, 114, 0, 7, 6, 195, 180, 0, 4, 3, 39, 0, 116, 2, 32, 0, 7, 6, 195, 188, 0, 109, 2, 32, 3, 39, 65, 0, 3, 111, 0, 108, 2, 32, 3, 111, 55, 55, 0, 115, 2, 32, 3, 111, 89, 0, 7, 6, 97, 0, 2, 195, 180, 3, 0, 105, 1, 102, 2, 115, 17, 65, 3, 13, 0, 4, 110, 121, 3, 21, 0, 119, 2, 25, 0, 4, 3, 35, 0, 2, 105, 108, 25, 0, 2, 110, 110, 17, 65, 0, 109, 2, 109, 0, 109, 2, 110, 0, 110, 2, 110, 32, 0, 4, 114, 99, 104, 8, 2, 97, 14, 128, 132, 132, 3, 35, 34, 49, 0, 114, 99, 104, 8, 2, 111, 14, 128, 132, 132, 0, 114, 99, 104, 195, 169, 8, 2, 21, 14, 128, 132, 133, 3, 35, 34, 49, 36, 0, 114, 99, 104, 195, 169, 111, 8, 2, 21, 14, 128, 132, 134, 3, 35, 34, 49, 36, 39, 0, 111, 195, 187, 116, 2, 105, 3, 35, 40, 89, 0, 4, 110, 1, 109, 18, 67, 2, 32, 3, 35, 50, 0, 110, 1, 109, 21, 21, 2, 32, 0, 110, 1, 109, 122, 2, 32, 0, 110, 1, 119, 2, 32, 0, 110, 2, 104, 0, 110, 8, 18, 69, 2, 32, 0, 110, 8, 104, 2, 32, 0, 110, 97, 114, 99, 104, 111, 8, 2, 21, 14, 128, 132, 135, 3, 35, 50, 35, 34, 49, 39, 0, 4, 121, 2, 97, 107, 3, 35, 57, 0, 121, 101, 1, 98, 98, 2, 32, 0, 4, 109, 1, 104, 2, 32, 14, 128, 128, 130, 3, 35, 65, 0, 109, 8, 2, 110, 0, 101, 3, 35, 112, 0, 4, 101, 2, 32, 3, 36, 0, 105, 2, 32, 0, 121, 101, 1, 98, 98, 2, 29, 3, 36, 37, 0, 4, 117, 3, 39, 0, 117, 100, 2, 32, 0, 117, 116, 111, 8, 2, 21, 14, 128, 132, 132, 3, 39, 47, 39, 0, 117, 116, 111, 109, 8, 2, 110, 3, 39, 47, 127, 0, 117, 100, 8, 17, 67, 2, 32, 3, 39, 72, 0, 117, 100, 105, 111, 8, 2, 21, 14, 128, 132, 133, 3, 39, 72, 37, 39, 0, 117, 116, 2, 32, 3, 39, 140, 0, 4, 111, 117, 1, 115, 2, 108, 101, 3, 40, 0, 111, 117, 108, 1, 115, 2, 32, 0, 111, 195, 187, 116, 3, 40, 47, 0, 4, 105, 3, 112, 0, 105, 8, 108, 97, 98, 2, 32, 0, 105, 8, 114, 118, 2, 32, 0, 105, 8, 115, 115, 101, 2, 32, 0, 105, 101, 0, 121, 2, 17, 67, 0, 121, 2, 32, 0, 121, 3, 112, 57, 0, 121, 101, 114, 1, 108, 29, 2, 29, 3, 112, 57, 117, 34, 0, 4, 105, 101, 110, 116, 3, 112, 140, 0, 105, 116, 2, 32, 0, 105, 115, 2, 32, 3, 112, 143, 0, 4, 101, 110, 3, 113, 0, 109, 2, 18, 76, 0, 110, 1, 109, 108, 117, 2, 32, 0, 110, 1, 109, 115, 105, 108, 2, 32, 0, 110, 2, 25, 0, 110, 8, 109, 175, 195, 97, 99, 2, 32, 0, 111, 110, 8, 17, 67, 2, 32, 0, 4, 110, 116, 105, 8, 2, 17, 67, 17, 65, 29, 14, 128, 132, 132, 3, 113, 47, 37, 0, 110, 116, 105, 8, 2, 21, 21, 14, 128, 132, 132, 0, 4, 105, 109, 2, 25, 3, 114, 0, 105, 110, 2, 25, 0, 4, 105, 110, 1, 104, 99, 2, 32, 3, 114, 134, 0, 105, 110, 1, 116, 17, 67, 2, 32, 0, 4, 117, 2, 108, 32, 3, 127, 0, 117, 2, 114, 101, 32, 0, 7, 6, 98, 0, 1, 109, 111, 2, 32, 3, 0, 4, 97, 99, 107, 3, 21, 0, 101, 8, 2, 18, 80, 17, 65, 0, 111, 97, 114, 100, 0, 111, 120, 2, 32, 0, 117, 103, 103, 0, 4, 3, 71, 0, 98, 0, 7, 6, 99, 0, 4, 1, 97, 98, 97, 116, 2, 32, 3, 0, 4, 1, 97, 109, 111, 116, 2, 32, 3, 0, 4, 1, 110, 97, 17, 67, 2, 32, 3, 0, 4, 1, 110, 111, 17, 67, 2, 32, 3, 0, 4, 1, 114, 97, 2, 116, 105, 3, 0, 4, 1, 114, 101, 108, 99, 2, 32, 3, 0, 4, 1, 115, 2, 17, 71, 3, 0, 4, 1, 117, 111, 104, 99, 116, 2, 32, 3, 0, 1, 120, 2, 17, 71, 3, 0, 4, 104, 1, 110, 2, 32, 3, 21, 0, 104, 2, 109, 101, 110, 116, 0, 117, 116, 2, 32, 0, 4, 3, 49, 0, 8, 110, 111, 100, 2, 32, 0, 99, 0, 99, 104, 0, 104, 1, 97, 2, 32, 0, 104, 1, 101, 2, 32, 0, 104, 1, 105, 110, 2, 32, 0, 104, 1, 105, 110, 97, 109, 2, 195, 169, 0, 104, 1, 111, 116, 105, 109, 2, 111, 0, 104, 1, 114, 111, 2, 101, 115, 17, 67, 0, 104, 1, 114, 111, 2, 105, 17, 67, 0, 104, 2, 108, 0, 104, 2, 110, 0, 104, 2, 114, 0, 104, 2, 115, 0, 104, 2, 116, 111, 0, 104, 8, 2, 97, 111, 0, 104, 8, 2, 97, 114, 105, 115, 109, 0, 104, 8, 2, 105, 114, 111, 112, 0, 104, 8, 2, 111, 114, 17, 65, 0, 104, 8, 17, 65, 2, 111, 32, 0, 104, 8, 117, 101, 2, 97, 114, 105, 0, 107, 0, 113, 0, 113, 117, 0, 104, 114, 111, 110, 111, 8, 2, 21, 14, 128, 132, 134, 3, 49, 34, 39, 50, 39, 0, 4, 97, 115, 116, 2, 32, 14, 128, 128, 132, 3, 49, 35, 89, 47, 0, 97, 115, 116, 115, 2, 32, 14, 128, 128, 133, 0, 108, 111, 119, 110, 8, 3, 49, 55, 40, 50, 0, 99, 2, 17, 71, 3, 49, 89, 0, 104, 1, 105, 119, 3, 76, 0, 4, 1, 101, 115, 2, 111, 110, 100, 3, 81, 0, 1, 110, 105, 122, 2, 32, 0, 4, 2, 17, 71, 3, 89, 0, 39, 8, 2, 14, 128, 140, 130, 0, 4, 8, 2, 100, 3, 89, 36, 0, 111, 101, 8, 2, 108, 97, 0, 121, 98, 101, 114, 8, 2, 14, 128, 132, 133, 3, 89, 37, 71, 112, 34, 0, 105, 101, 110, 116, 2, 32, 3, 89, 37, 140, 0, 4, 105, 101, 110, 116, 1, 105, 102, 102, 101, 3, 89, 57, 113, 0, 105, 101, 110, 116, 1, 105, 102, 169, 195, 100, 0, 4, 104, 3, 91, 0, 104, 8, 2, 111, 114, 105, 122, 0, 104, 8, 2, 111, 114, 111, 0, 7, 6, 100, 0, 4, 1, 105, 111, 2, 32, 3, 0, 4, 1, 110, 97, 2, 32, 3, 0, 4, 1, 110, 111, 17, 67, 2, 32, 3, 0, 4, 1, 114, 2, 32, 3, 0, 4, 1, 117, 111, 2, 32, 3, 0, 8, 105, 110, 2, 32, 3, 0, 4, 97, 121, 2, 32, 3, 21, 0, 101, 118, 105, 99, 8, 0, 108, 101, 2, 29, 0, 116, 2, 32, 3, 47, 0, 4, 3, 72, 0, 1, 114, 111, 108, 2, 32, 0, 8, 110, 97, 98, 2, 32, 0, 8, 110, 97, 108, 2, 32, 0, 8, 110, 97, 115, 2, 32, 0, 8, 110, 97, 116, 115, 2, 32, 0, 8, 114, 97, 104, 2, 32, 0, 39, 8, 2, 14, 128, 132, 130, 0, 100, 0, 4, 105, 101, 110, 1, 169, 195, 112, 120, 101, 32, 26, 2, 116, 32, 3, 72, 37, 0, 105, 101, 110, 2, 116, 32, 0, 4, 105, 101, 110, 8, 169, 195, 112, 120, 101, 2, 116, 32, 3, 72, 57, 113, 0, 105, 101, 110, 8, 169, 195, 114, 103, 110, 105, 2, 116, 32, 0, 101, 110, 100, 114, 111, 8, 2, 21, 14, 128, 132, 134, 3, 72, 114, 72, 34, 39, 0, 4, 1, 110, 101, 17, 67, 2, 32, 3, 140, 0, 1, 110, 101, 117, 113, 2, 32, 0, 1, 110, 111, 99, 2, 32, 0, 8, 110, 97, 114, 103, 2, 32, 0, 7, 6, 101, 0, 4, 1, 17, 65, 2, 114, 17, 65, 3, 0, 4, 1, 17, 67, 2, 45, 3, 0, 4, 1, 18, 73, 21, 2, 17, 67, 17, 65, 3, 0, 4, 1, 18, 73, 21, 2, 18, 71, 3, 0, 4, 1, 99, 45, 2, 32, 3, 0, 4, 1, 103, 2, 17, 65, 3, 0, 4, 1, 105, 2, 109, 17, 65, 3, 0, 4, 1, 106, 45, 2, 32, 3, 0, 4, 2, 32, 3, 0, 4, 2, 111, 105, 3, 0, 4, 110, 1, 108, 111, 26, 2, 116, 32, 3, 0, 4, 110, 1, 118, 117, 111, 99, 32, 26, 2, 116, 32, 3, 0, 110, 1, 118, 117, 111, 99, 32, 115, 2, 116, 32, 3, 0, 195, 175, 2, 25, 3, 6, 112, 57, 0, 4, 3, 13, 0, 1, 17, 67, 21, 2, 17, 67, 101, 17, 67, 17, 65, 0, 1, 18, 71, 21, 2, 17, 67, 17, 65, 0, 1, 18, 71, 21, 2, 18, 71, 0, 1, 18, 72, 21, 2, 17, 67, 17, 65, 0, 1, 18, 72, 21, 2, 18, 71, 0, 1, 18, 73, 21, 2, 17, 67, 18, 75, 17, 67, 0, 1, 18, 73, 21, 2, 18, 71, 18, 75, 17, 67, 0, 1, 100, 2, 115, 115, 117, 115, 32, 0, 1, 114, 116, 2, 17, 67, 17, 65, 0, 1, 114, 116, 2, 17, 67, 104, 17, 65, 0, 1, 117, 103, 18, 74, 21, 2, 17, 67, 17, 65, 0, 1, 117, 103, 18, 74, 21, 2, 18, 71, 0, 1, 117, 113, 18, 74, 21, 2, 17, 67, 17, 65, 0, 1, 117, 113, 18, 74, 21, 2, 18, 71, 0, 2, 17, 67, 108, 0, 2, 17, 67, 114, 0, 8, 100, 2, 99, 104, 0, 8, 108, 2, 17, 67, 17, 65, 0, 8, 108, 2, 17, 67, 104, 17, 65, 0, 8, 108, 2, 17, 67, 108, 17, 65, 0, 8, 114, 2, 99, 104, 0, 8, 114, 2, 115, 115, 0, 8, 114, 2, 115, 116, 114, 97, 0, 8, 114, 2, 115, 116, 114, 111, 0, 8, 114, 2, 115, 116, 114, 117, 0, 8, 17, 67, 2, 32, 3, 14, 0, 4, 8, 2, 17, 67, 101, 29, 3, 21, 0, 97, 0, 100, 2, 32, 0, 101, 0, 102, 111, 114, 101, 2, 32, 0, 105, 110, 103, 2, 32, 0, 105, 118, 101, 0, 108, 2, 17, 67, 29, 0, 110, 104, 97, 110, 8, 0, 110, 116, 101, 114, 8, 2, 32, 0, 115, 115, 2, 32, 0, 115, 116, 1, 117, 113, 2, 32, 0, 115, 116, 101, 1, 117, 113, 2, 29, 32, 0, 118, 101, 110, 2, 32, 0, 118, 101, 114, 1, 17, 67, 111, 0, 118, 101, 114, 8, 0, 119, 2, 12, 12, 0, 121, 101, 8, 0, 4, 109, 1, 21, 2, 109, 101, 3, 35, 0, 109, 1, 108, 2, 110, 0, 109, 8, 102, 2, 109, 101, 0, 4, 2, 114, 105, 32, 12, 12, 3, 36, 0, 2, 114, 105, 97, 32, 12, 12, 0, 2, 114, 111, 32, 12, 12, 0, 8, 2, 17, 67, 11, 0, 8, 2, 17, 67, 17, 65, 0, 8, 2, 17, 67, 17, 65, 24, 0, 8, 2, 18, 71, 17, 65, 0, 8, 109, 2, 103, 97, 0, 8, 114, 2, 115, 115, 117, 0, 8, 116, 114, 97, 2, 12, 12, 0, 100, 1, 105, 112, 2, 32, 0, 102, 8, 108, 99, 2, 32, 0, 114, 2, 32, 0, 114, 2, 115, 32, 0, 115, 1, 109, 17, 65, 2, 100, 17, 65, 0, 115, 1, 109, 17, 65, 2, 110, 17, 65, 0, 115, 8, 100, 2, 98, 17, 65, 0, 115, 8, 100, 2, 106, 17, 65, 0, 115, 8, 100, 2, 110, 17, 65, 0, 115, 8, 100, 2, 113, 17, 65, 0, 115, 8, 108, 2, 113, 17, 65, 0, 115, 8, 109, 2, 100, 17, 65, 0, 115, 8, 109, 2, 110, 17, 65, 0, 115, 104, 1, 100, 2, 17, 65, 3, 36, 88, 0, 114, 1, 119, 101, 105, 2, 29, 3, 36, 120, 0, 122, 2, 32, 3, 36, 143, 0, 97, 117, 2, 12, 12, 3, 39, 0, 4, 117, 1, 103, 2, 114, 101, 3, 111, 0, 117, 8, 2, 115, 115, 0, 195, 187, 8, 0, 117, 116, 8, 2, 32, 3, 111, 140, 0, 4, 1, 104, 103, 2, 116, 17, 65, 29, 3, 112, 0, 1, 105, 2, 114, 116, 32, 0, 1, 112, 97, 99, 2, 108, 97, 32, 0, 2, 17, 67, 17, 67, 0, 2, 17, 67, 32, 0, 2, 99, 116, 12, 12, 12, 12, 12, 0, 2, 105, 108, 0, 2, 114, 17, 67, 0, 2, 114, 114, 12, 12, 12, 0, 2, 120, 12, 12, 12, 12, 12, 0, 8, 17, 67, 101, 2, 17, 67, 17, 65, 12, 12, 0, 98, 1, 102, 2, 118, 17, 65, 0, 99, 116, 1, 112, 2, 32, 0, 105, 0, 108, 2, 108, 0, 109, 2, 109, 97, 0, 110, 1, 105, 17, 67, 2, 110, 17, 65, 0, 110, 2, 110, 17, 65, 0, 116, 1, 107, 99, 105, 116, 2, 32, 0, 121, 2, 17, 67, 0, 121, 2, 32, 0, 4, 114, 1, 107, 99, 111, 2, 25, 3, 112, 34, 0, 114, 1, 110, 105, 97, 116, 2, 29, 0, 114, 1, 116, 115, 17, 67, 2, 29, 0, 114, 8, 17, 67, 2, 32, 0, 114, 8, 104, 17, 67, 2, 32, 0, 114, 8, 105, 102, 2, 32, 0, 114, 8, 105, 104, 2, 32, 0, 114, 8, 105, 116, 2, 32, 0, 114, 8, 116, 114, 97, 99, 2, 29, 0, 114, 8, 118, 105, 104, 2, 29, 0, 114, 8, 118, 110, 101, 2, 32, 0, 4, 116, 1, 103, 100, 2, 32, 3, 112, 47, 0, 116, 1, 107, 2, 32, 0, 99, 116, 2, 32, 3, 112, 49, 47, 0, 4, 120, 116, 114, 97, 8, 2, 17, 67, 14, 128, 132, 133, 3, 112, 49, 89, 47, 34, 35, 0, 120, 116, 114, 97, 8, 2, 117, 14, 128, 132, 133, 0, 4, 105, 110, 8, 2, 25, 3, 112, 50, 0, 110, 1, 17, 67, 2, 32, 0, 110, 1, 17, 67, 2, 116, 111, 32, 0, 110, 8, 121, 2, 32, 0, 110, 115, 1, 112, 115, 2, 32, 3, 112, 50, 89, 0, 108, 2, 115, 29, 3, 112, 55, 0, 121, 3, 112, 57, 0, 109, 110, 1, 108, 105, 3, 112, 65, 0, 115, 116, 1, 45, 2, 32, 3, 112, 89, 47, 0, 116, 1, 109, 2, 32, 3, 112, 140, 0, 4, 109, 2, 18, 76, 3, 113, 0, 109, 2, 109, 17, 65, 17, 67, 17, 65, 17, 67, 0, 109, 2, 109, 17, 65, 17, 67, 17, 67, 0, 109, 2, 109, 97, 105, 0, 110, 1, 17, 67, 2, 100, 32, 0, 110, 1, 17, 67, 111, 17, 67, 109, 105, 2, 116, 32, 0, 110, 1, 17, 67, 111, 17, 67, 110, 105, 2, 116, 32, 0, 110, 1, 17, 67, 169, 195, 2, 116, 32, 0, 110, 1, 17, 67, 169, 195, 2, 116, 32, 0, 110, 1, 99, 97, 106, 2, 116, 32, 0, 110, 1, 99, 99, 2, 116, 32, 0, 110, 1, 99, 105, 116, 169, 195, 2, 116, 32, 0, 110, 1, 99, 115, 17, 65, 2, 116, 32, 0, 110, 1, 100, 105, 17, 67, 169, 195, 2, 116, 32, 0, 110, 1, 100, 105, 99, 17, 67, 17, 65, 29, 2, 116, 32, 0, 110, 1, 100, 105, 114, 116, 29, 2, 116, 32, 0, 110, 1, 100, 117, 17, 67, 2, 116, 32, 0, 110, 1, 103, 110, 105, 21, 21, 2, 116, 32, 0, 110, 1, 103, 114, 101, 118, 2, 116, 32, 0, 110, 1, 105, 17, 67, 2, 99, 0, 110, 1, 105, 116, 97, 112, 0, 110, 1, 108, 97, 118, 105, 2, 116, 32, 0, 110, 1, 108, 108, 101, 99, 120, 2, 116, 32, 0, 110, 1, 108, 111, 2, 116, 32, 0, 110, 1, 108, 117, 2, 116, 32, 0, 110, 1, 109, 97, 17, 67, 105, 2, 116, 32, 0, 110, 1, 109, 97, 109, 114, 2, 116, 32, 0, 110, 1, 109, 101, 2, 116, 32, 0, 110, 1, 109, 103, 2, 116, 32, 0, 110, 1, 109, 105, 17, 67, 17, 67, 17, 65, 17, 67, 2, 116, 32, 0, 110, 1, 109, 105, 97, 17, 65, 2, 116, 32, 0, 110, 1, 109, 105, 97, 17, 67, 2, 116, 32, 0, 110, 1, 109, 105, 100, 2, 116, 32, 0, 110, 1, 109, 105, 103, 17, 65, 2, 116, 32, 0, 110, 1, 109, 105, 108, 17, 65, 2, 116, 32, 0, 110, 1, 109, 105, 108, 112, 2, 116, 32, 0, 110, 1, 109, 105, 110, 97, 109, 2, 116, 32, 0, 110, 1, 109, 105, 110, 105, 2, 116, 32, 0, 110, 1, 109, 105, 110, 111, 2, 116, 32, 0, 110, 1, 109, 105, 115, 17, 65, 2, 116, 32, 0, 110, 1, 109, 105, 116, 17, 65, 2, 116, 32, 0, 110, 1, 109, 109, 2, 116, 32, 0, 110, 1, 109, 111, 109, 2, 116, 32, 0, 110, 1, 109, 114, 101, 2, 116, 32, 0, 110, 1, 109, 114, 117, 111, 116, 2, 116, 32, 0, 110, 1, 109, 117, 17, 67, 111, 2, 116, 32, 0, 110, 1, 109, 117, 100, 2, 116, 32, 0, 110, 1, 109, 117, 103, 2, 116, 32, 0, 110, 1, 109, 117, 106, 2, 116, 32, 0, 110, 1, 109, 117, 114, 2, 116, 32, 0, 110, 1, 110, 97, 109, 2, 116, 32, 0, 110, 1, 110, 105, 109, 109, 105, 2, 116, 32, 0, 110, 1, 110, 105, 109, 169, 195, 111, 2, 116, 32, 0, 110, 1, 110, 105, 116, 110, 111, 2, 116, 32, 0, 110, 1, 110, 105, 116, 114, 101, 2, 116, 32, 0, 110, 1, 112, 114, 17, 65, 29, 2, 116, 32, 0, 110, 1, 114, 97, 112, 115, 2, 116, 32, 0, 110, 1, 114, 114, 17, 65, 17, 67, 2, 116, 32, 0, 110, 1, 116, 105, 110, 169, 195, 2, 116, 32, 0, 110, 1, 116, 116, 105, 109, 2, 116, 32, 0, 110, 1, 117, 108, 102, 17, 67, 2, 116, 32, 0, 110, 1, 117, 113, 2, 100, 32, 0, 110, 1, 117, 113, 169, 195, 2, 116, 32, 0, 110, 2, 17, 67, 17, 65, 0, 110, 2, 17, 67, 17, 67, 0, 110, 2, 110, 117, 0, 110, 2, 115, 32, 0, 110, 8, 17, 67, 2, 116, 32, 0, 110, 8, 100, 114, 97, 2, 116, 32, 0, 110, 8, 103, 97, 2, 116, 32, 0, 110, 8, 103, 114, 97, 2, 116, 32, 0, 110, 8, 103, 114, 101, 115, 2, 116, 32, 0, 110, 8, 103, 114, 117, 2, 116, 32, 0, 110, 8, 108, 97, 116, 2, 116, 32, 0, 110, 8, 108, 111, 100, 2, 116, 32, 0, 110, 8, 109, 105, 99, 2, 116, 32, 0, 110, 8, 109, 105, 112, 2, 116, 32, 0, 110, 8, 109, 114, 17, 65, 115, 2, 116, 32, 0, 110, 8, 110, 105, 109, 169, 195, 2, 116, 32, 0, 110, 8, 114, 97, 112, 2, 116, 32, 0, 110, 8, 114, 97, 112, 112, 97, 2, 116, 32, 0, 110, 8, 114, 97, 118, 2, 116, 32, 0, 110, 8, 114, 111, 108, 102, 2, 116, 32, 0, 110, 8, 114, 117, 97, 108, 2, 116, 32, 0, 110, 8, 116, 97, 108, 2, 116, 32, 0, 110, 8, 116, 97, 112, 2, 116, 32, 0, 110, 8, 116, 110, 111, 99, 2, 116, 32, 0, 110, 8, 116, 110, 111, 99, 169, 195, 109, 2, 116, 32, 0, 110, 8, 118, 117, 111, 99, 2, 116, 14, 128, 160, 131, 0, 110, 8, 118, 117, 111, 115, 2, 116, 32, 0, 110, 115, 1, 99, 110, 2, 32, 0, 4, 110, 2, 104, 17, 65, 3, 113, 50, 0, 110, 8, 2, 17, 65, 0, 110, 2, 32, 3, 113, 134, 0, 4, 110, 116, 1, 103, 105, 100, 110, 2, 32, 3, 113, 140, 0, 110, 116, 1, 103, 105, 108, 105, 2, 32, 0, 110, 116, 1, 103, 105, 108, 108, 2, 32, 0, 110, 116, 1, 103, 110, 97, 116, 2, 32, 0, 110, 115, 1, 17, 67, 169, 195, 2, 32, 3, 113, 143, 0, 4, 105, 110, 2, 25, 3, 114, 0, 110, 1, 17, 65, 17, 65, 2, 32, 0, 110, 1, 100, 111, 2, 100, 114, 0, 110, 1, 105, 17, 67, 2, 25, 0, 110, 1, 109, 97, 120, 2, 32, 0, 110, 1, 112, 112, 97, 2, 100, 105, 0, 110, 1, 169, 195, 2, 32, 0, 110, 8, 17, 67, 2, 106, 0, 110, 8, 109, 97, 108, 102, 2, 99, 0, 105, 110, 1, 108, 112, 2, 32, 3, 114, 134, 0, 4, 1, 104, 99, 116, 2, 114, 29, 3, 117, 0, 1, 116, 114, 101, 118, 2, 114, 29, 0, 117, 1, 103, 0, 117, 2, 17, 67, 29, 0, 117, 2, 17, 67, 101, 29, 0, 117, 2, 105, 0, 117, 2, 108, 101, 29, 0, 117, 2, 114, 17, 67, 0, 117, 2, 114, 101, 29, 0, 117, 2, 114, 114, 101, 29, 0, 4, 114, 1, 107, 99, 97, 2, 25, 3, 117, 34, 0, 114, 1, 107, 99, 111, 114, 2, 25, 0, 114, 8, 116, 116, 117, 99, 2, 29, 0, 97, 109, 1, 114, 17, 67, 3, 125, 12, 65, 0, 97, 110, 101, 114, 1, 108, 17, 67, 3, 125, 50, 117, 34, 0, 97, 109, 101, 114, 1, 114, 17, 67, 3, 125, 65, 117, 34, 0, 4, 117, 3, 132, 0, 117, 2, 17, 67, 101, 29, 0, 117, 2, 17, 67, 101, 114, 32, 0, 117, 2, 108, 101, 114, 0, 195, 187, 3, 132, 12, 0, 117, 116, 2, 32, 3, 132, 140, 0, 117, 120, 2, 32, 3, 132, 143, 0, 4, 110, 116, 1, 17, 65, 2, 32, 3, 140, 0, 110, 116, 1, 100, 105, 17, 67, 169, 195, 26, 2, 32, 0, 110, 116, 1, 103, 105, 2, 32, 0, 110, 116, 1, 103, 114, 101, 118, 26, 2, 32, 0, 110, 116, 1, 103, 114, 117, 32, 26, 2, 32, 0, 110, 116, 1, 108, 97, 118, 105, 26, 2, 32, 0, 110, 116, 1, 108, 108, 101, 99, 120, 26, 2, 32, 0, 110, 116, 1, 108, 111, 29, 2, 32, 0, 110, 116, 1, 108, 117, 26, 2, 32, 0, 110, 116, 1, 108, 117, 99, 17, 67, 2, 32, 0, 110, 116, 1, 108, 117, 101, 2, 32, 0, 110, 116, 1, 109, 114, 101, 102, 26, 2, 32, 0, 110, 116, 1, 114, 97, 112, 32, 26, 2, 32, 0, 110, 116, 1, 114, 114, 101, 17, 67, 2, 32, 0, 110, 116, 1, 117, 108, 102, 17, 67, 26, 2, 32, 0, 110, 116, 2, 32, 0, 110, 116, 8, 116, 110, 111, 99, 26, 2, 32, 0, 115, 2, 32, 3, 143, 0, 7, 6, 102, 0, 4, 2, 102, 3, 0, 8, 114, 101, 110, 2, 29, 3, 0, 4, 105, 114, 101, 8, 2, 17, 67, 17, 65, 3, 21, 0, 105, 114, 101, 8, 2, 17, 67, 17, 67, 17, 65, 0, 108, 121, 0, 114, 97, 109, 101, 8, 0, 116, 101, 114, 2, 32, 0, 3, 83, 0, 4, 8, 117, 101, 110, 2, 32, 97, 110, 115, 3, 84, 0, 8, 117, 101, 110, 2, 32, 104, 101, 117, 114, 101, 115, 0, 7, 6, 103, 0, 4, 1, 110, 97, 116, 169, 195, 2, 32, 3, 0, 4, 1, 114, 117, 111, 98, 2, 32, 3, 0, 4, 8, 110, 97, 114, 2, 32, 3, 0, 4, 8, 110, 97, 115, 2, 32, 3, 0, 4, 8, 110, 111, 108, 2, 32, 3, 0, 4, 116, 1, 110, 105, 118, 2, 32, 117, 110, 3, 0, 116, 2, 32, 3, 0, 4, 97, 109, 101, 8, 2, 29, 3, 21, 0, 104, 2, 25, 0, 105, 114, 108, 0, 121, 2, 32, 0, 4, 116, 1, 110, 17, 65, 2, 17, 65, 3, 47, 0, 116, 1, 110, 105, 118, 2, 32, 17, 65, 0, 116, 1, 110, 105, 118, 2, 32, 99, 105, 110, 113, 0, 116, 1, 110, 105, 118, 2, 32, 100, 101, 117, 120, 0, 116, 1, 110, 105, 118, 2, 32, 104, 117, 105, 116, 0, 116, 1, 110, 105, 118, 2, 32, 110, 101, 117, 102, 0, 116, 1, 110, 105, 118, 2, 32, 110, 101, 117, 118, 105, 0, 116, 1, 110, 105, 118, 2, 32, 113, 117, 97, 116, 114, 0, 116, 1, 110, 105, 118, 2, 32, 115, 101, 112, 116, 0, 116, 1, 110, 105, 118, 2, 32, 115, 105, 120, 0, 116, 1, 110, 105, 118, 2, 32, 116, 114, 111, 105, 115, 0, 110, 2, 105, 101, 3, 50, 0, 110, 3, 50, 57, 0, 110, 2, 101, 17, 67, 17, 65, 3, 50, 57, 14, 0, 4, 110, 2, 32, 3, 67, 0, 110, 2, 101, 32, 0, 110, 105, 1, 105, 97, 0, 110, 105, 3, 67, 37, 0, 4, 3, 81, 0, 1, 97, 105, 100, 2, 110, 111, 0, 2, 17, 67, 0, 2, 32, 0, 8, 97, 2, 110, 111, 0, 103, 0, 117, 2, 105, 0, 110, 101, 114, 8, 97, 119, 2, 32, 3, 81, 50, 112, 34, 0, 103, 1, 117, 115, 2, 17, 71, 3, 81, 90, 0, 4, 117, 105, 1, 105, 97, 2, 108, 3, 81, 111, 37, 0, 117, 105, 1, 110, 105, 2, 115, 0, 4, 2, 17, 71, 3, 90, 0, 101, 2, 97, 0, 101, 2, 111, 0, 116, 115, 8, 110, 105, 118, 101, 114, 116, 97, 117, 113, 2, 32, 3, 143, 0, 7, 6, 104, 0, 4, 3, 0, 4, 8, 2, 97, 98, 105, 3, 0, 4, 8, 2, 97, 108, 108, 111, 3, 0, 4, 8, 2, 97, 109, 101, 3, 0, 4, 8, 2, 97, 110, 100, 114, 3, 0, 4, 8, 2, 97, 114, 109, 3, 0, 4, 8, 2, 101, 99, 116, 3, 0, 4, 8, 2, 101, 108, 3, 0, 4, 8, 2, 101, 114, 98, 3, 0, 4, 8, 2, 101, 117, 114, 101, 3, 0, 4, 8, 2, 105, 98, 101, 114, 3, 0, 4, 8, 2, 105, 112, 112, 111, 3, 0, 4, 8, 2, 105, 114, 111, 3, 0, 4, 8, 2, 105, 115, 116, 3, 0, 4, 8, 2, 105, 118, 3, 0, 4, 8, 2, 111, 109, 109, 3, 0, 4, 8, 2, 111, 110, 110, 3, 0, 4, 8, 2, 111, 114, 97, 3, 0, 4, 8, 2, 111, 114, 105, 112, 3, 0, 4, 8, 2, 111, 114, 105, 122, 3, 0, 4, 8, 2, 111, 114, 108, 111, 3, 0, 4, 8, 2, 111, 114, 111, 3, 0, 4, 8, 2, 111, 114, 114, 3, 0, 4, 8, 2, 111, 115, 3, 0, 4, 8, 2, 117, 105, 108, 3, 0, 4, 8, 2, 117, 105, 115, 115, 3, 0, 4, 8, 2, 117, 105, 116, 114, 3, 0, 4, 8, 2, 117, 109, 17, 65, 3, 0, 4, 8, 2, 117, 109, 17, 67, 3, 0, 4, 8, 2, 121, 3, 0, 4, 8, 2, 195, 169, 3, 0, 8, 2, 195, 180, 3, 0, 4, 97, 8, 2, 17, 67, 32, 3, 21, 0, 97, 108, 102, 8, 0, 110, 0, 4, 8, 3, 23, 0, 8, 2, 195, 169, 114, 105, 115, 0, 8, 2, 195, 169, 114, 111, 0, 105, 8, 2, 17, 65, 3, 23, 57, 0, 101, 105, 109, 2, 32, 3, 35, 57, 65, 0, 121, 112, 114, 97, 8, 2, 21, 14, 128, 132, 133, 3, 37, 48, 34, 35, 0, 4, 121, 112, 101, 114, 8, 2, 21, 14, 128, 132, 133, 3, 37, 48, 112, 34, 0, 121, 112, 101, 114, 8, 2, 32, 0, 97, 117, 115, 2, 32, 3, 39, 89, 0, 121, 8, 2, 17, 65, 3, 57, 0, 7, 6, 105, 0, 4, 1, 102, 32, 109, 97, 114, 2, 108, 101, 3, 21, 0, 2, 112, 17, 65, 100, 0, 98, 117, 116, 101, 114, 2, 29, 0, 101, 118, 0, 102, 101, 2, 32, 0, 103, 110, 2, 32, 0, 108, 108, 1, 17, 67, 2, 121, 32, 0, 108, 108, 2, 32, 0, 110, 100, 1, 17, 67, 17, 65, 2, 101, 114, 29, 0, 110, 100, 2, 29, 0, 110, 100, 8, 17, 67, 2, 101, 114, 29, 0, 110, 103, 2, 32, 0, 114, 100, 1, 17, 67, 2, 29, 0, 114, 116, 1, 17, 67, 2, 32, 0, 118, 101, 110, 2, 32, 0, 122, 101, 2, 25, 0, 4, 1, 108, 102, 102, 111, 2, 110, 101, 32, 3, 35, 57, 0, 1, 108, 110, 111, 2, 110, 101, 32, 0, 1, 108, 116, 111, 2, 110, 101, 29, 0, 1, 114, 100, 2, 118, 101, 0, 1, 116, 103, 2, 109, 0, 8, 2, 99, 101, 21, 0, 4, 3, 37, 0, 1, 17, 67, 2, 101, 114, 17, 65, 0, 101, 110, 1, 17, 67, 2, 116, 32, 0, 101, 110, 1, 118, 169, 195, 100, 2, 116, 32, 0, 108, 8, 2, 108, 0, 110, 2, 110, 0, 115, 1, 17, 67, 2, 32, 0, 110, 2, 104, 3, 37, 50, 0, 110, 116, 1, 114, 112, 2, 32, 3, 37, 50, 47, 0, 110, 103, 2, 104, 3, 37, 50, 81, 0, 4, 108, 108, 1, 99, 2, 105, 3, 37, 55, 0, 108, 108, 1, 99, 115, 111, 0, 108, 108, 1, 116, 115, 105, 100, 0, 108, 108, 1, 117, 113, 110, 97, 0, 108, 108, 1, 118, 2, 101, 32, 0, 108, 108, 8, 18, 70, 0, 4, 108, 108, 1, 17, 67, 3, 37, 57, 0, 108, 108, 1, 117, 103, 0, 108, 108, 1, 117, 103, 105, 97, 0, 108, 108, 1, 117, 113, 0, 109, 2, 32, 3, 37, 65, 0, 109, 109, 3, 37, 65, 65, 0, 110, 103, 2, 115, 3, 37, 68, 0, 4, 108, 115, 1, 102, 32, 18, 66, 2, 32, 3, 37, 89, 0, 115, 1, 114, 105, 25, 2, 32, 0, 115, 1, 114, 111, 98, 2, 32, 0, 115, 1, 114, 111, 100, 2, 32, 0, 115, 1, 114, 111, 116, 2, 32, 0, 4, 101, 110, 1, 108, 99, 2, 17, 67, 3, 37, 113, 0, 101, 110, 1, 114, 111, 2, 116, 0, 4, 108, 1, 97, 2, 32, 3, 57, 0, 108, 1, 101, 2, 32, 0, 108, 1, 117, 2, 32, 0, 108, 108, 1, 17, 65, 0, 4, 101, 110, 1, 108, 111, 109, 2, 17, 67, 3, 57, 113, 0, 101, 110, 1, 110, 169, 195, 118, 2, 17, 67, 0, 101, 110, 1, 112, 105, 99, 2, 17, 67, 0, 101, 110, 1, 116, 97, 2, 116, 32, 0, 101, 110, 1, 116, 111, 2, 116, 32, 0, 4, 101, 110, 1, 116, 2, 25, 32, 3, 57, 114, 0, 101, 110, 1, 118, 2, 25, 32, 0, 4, 109, 2, 17, 67, 3, 114, 0, 110, 2, 17, 67, 0, 110, 2, 32, 0, 110, 99, 116, 2, 32, 0, 4, 110, 116, 101, 114, 8, 2, 32, 3, 114, 47, 6, 112, 34, 0, 110, 116, 101, 114, 8, 2, 110, 101, 32, 0, 4, 110, 116, 114, 97, 8, 2, 110, 101, 14, 128, 132, 133, 3, 114, 47, 34, 35, 0, 110, 116, 114, 97, 8, 2, 117, 14, 128, 132, 133, 0, 4, 110, 116, 101, 114, 8, 2, 21, 21, 14, 128, 132, 133, 3, 114, 47, 112, 34, 0, 110, 116, 101, 114, 114, 8, 2, 17, 65, 0, 110, 102, 114, 97, 8, 2, 115, 14, 128, 132, 133, 3, 114, 83, 34, 35, 0, 114, 116, 1, 108, 102, 3, 117, 34, 47, 0, 7, 6, 106, 0, 4, 8, 2, 111, 98, 25, 3, 75, 0, 8, 2, 111, 104, 25, 0, 97, 122, 122, 8, 3, 75, 35, 88, 0, 4, 3, 90, 0, 39, 8, 2, 14, 128, 140, 130, 0, 101, 2, 97, 0, 117, 115, 113, 117, 39, 8, 2, 14, 128, 132, 134, 3, 90, 111, 89, 49, 0, 7, 6, 107, 0, 4, 1, 17, 67, 17, 65, 2, 29, 3, 21, 0, 101, 2, 32, 0, 101, 2, 110, 29, 0, 101, 2, 114, 29, 0, 101, 2, 115, 32, 0, 3, 49, 0, 7, 6, 108, 0, 4, 1, 105, 17, 67, 117, 2, 32, 3, 0, 4, 1, 105, 116, 110, 2, 32, 3, 0, 116, 1, 117, 97, 3, 0, 4, 1, 17, 67, 11, 2, 101, 29, 3, 21, 0, 1, 17, 67, 17, 65, 2, 29, 0, 100, 1, 111, 2, 32, 0, 100, 1, 117, 2, 32, 0, 101, 115, 115, 2, 32, 0, 105, 110, 101, 8, 2, 29, 0, 105, 118, 101, 8, 0, 111, 117, 100, 1, 21, 2, 32, 0, 4, 3, 55, 0, 1, 102, 102, 2, 101, 29, 0, 1, 112, 112, 2, 101, 29, 0, 39, 8, 2, 14, 128, 132, 130, 0, 108, 2, 17, 65, 0, 111, 114, 115, 113, 117, 39, 8, 2, 14, 128, 132, 135, 3, 55, 39, 34, 89, 49, 0, 4, 104, 1, 105, 116, 110, 3, 57, 0, 108, 1, 105, 117, 0, 7, 6, 109, 0, 4, 2, 110, 32, 3, 21, 0, 97, 105, 108, 1, 100, 0, 97, 105, 108, 1, 101, 0, 97, 105, 108, 1, 103, 0, 97, 105, 108, 1, 116, 0, 111, 118, 2, 17, 65, 29, 0, 111, 118, 2, 105, 101, 32, 0, 4, 3, 65, 0, 39, 8, 2, 14, 128, 140, 130, 0, 109, 0, 99, 8, 2, 21, 14, 128, 132, 130, 3, 65, 35, 49, 0, 97, 115, 116, 101, 114, 2, 32, 14, 128, 128, 134, 3, 65, 35, 89, 47, 117, 34, 0, 115, 8, 2, 14, 128, 132, 130, 3, 112, 65, 112, 89, 0, 7, 6, 110, 0, 4, 2, 101, 109, 101, 32, 3, 21, 0, 2, 101, 109, 101, 115, 32, 0, 97, 109, 101, 8, 0, 97, 109, 101, 8, 101, 114, 0, 4, 3, 50, 0, 39, 8, 2, 14, 128, 140, 130, 0, 110, 0, 103, 104, 3, 50, 81, 0, 8, 2, 32, 194, 176, 3, 50, 111, 65, 36, 34, 39, 0, 101, 114, 8, 17, 67, 17, 65, 119, 2, 32, 3, 50, 112, 34, 0, 101, 117, 114, 111, 8, 2, 21, 21, 14, 128, 132, 133, 3, 50, 132, 34, 39, 0, 103, 2, 32, 3, 68, 0, 118, 100, 97, 8, 2, 14, 128, 132, 132, 3, 112, 50, 84, 36, 72, 36, 35, 0, 7, 6, 111, 0, 4, 2, 108, 100, 101, 114, 32, 3, 21, 0, 8, 2, 114, 100, 101, 114, 32, 0, 97, 2, 17, 67, 101, 114, 29, 0, 97, 2, 29, 0, 97, 99, 104, 0, 101, 115, 0, 102, 8, 2, 29, 0, 105, 110, 103, 1, 17, 67, 2, 32, 0, 110, 1, 116, 103, 2, 32, 0, 110, 1, 116, 115, 17, 67, 2, 32, 0, 110, 101, 8, 0, 111, 2, 17, 67, 101, 0, 111, 2, 29, 0, 111, 2, 107, 0, 111, 2, 115, 116, 0, 111, 116, 1, 17, 67, 0, 116, 8, 17, 67, 115, 0, 117, 100, 1, 17, 67, 29, 2, 29, 0, 117, 100, 1, 108, 2, 29, 0, 117, 110, 2, 17, 67, 0, 118, 101, 114, 8, 0, 119, 2, 29, 0, 119, 2, 101, 0, 121, 8, 17, 67, 2, 29, 0, 117, 8, 2, 97, 116, 3, 23, 40, 0, 110, 8, 2, 122, 3, 23, 116, 0, 101, 8, 104, 112, 2, 17, 67, 3, 36, 0, 4, 1, 17, 67, 2, 109, 101, 32, 3, 39, 0, 2, 32, 0, 2, 101, 17, 67, 0, 2, 115, 17, 65, 0, 2, 116, 32, 0, 2, 122, 17, 65, 0, 99, 1, 114, 98, 2, 32, 0, 99, 1, 114, 99, 2, 32, 0, 105, 8, 2, 103, 110, 111, 110, 0, 111, 1, 122, 0, 112, 8, 108, 97, 103, 2, 32, 0, 112, 8, 114, 105, 115, 2, 32, 0, 115, 1, 32, 115, 2, 32, 0, 115, 1, 32, 120, 2, 32, 0, 115, 8, 118, 2, 103, 17, 71, 0, 115, 116, 1, 118, 2, 32, 0, 4, 97, 2, 32, 3, 39, 35, 0, 97, 2, 115, 32, 0, 111, 1, 122, 2, 17, 67, 3, 39, 39, 0, 115, 115, 1, 114, 103, 3, 39, 89, 0, 4, 111, 1, 122, 2, 109, 3, 40, 0, 117, 0, 117, 101, 2, 109, 17, 65, 0, 117, 112, 8, 17, 67, 2, 32, 0, 195, 185, 0, 195, 187, 0, 117, 2, 105, 110, 3, 58, 0, 4, 101, 2, 108, 108, 17, 65, 3, 58, 35, 0, 105, 0, 121, 0, 195, 170, 2, 108, 0, 121, 2, 17, 65, 3, 58, 35, 57, 0, 4, 105, 110, 2, 17, 67, 3, 58, 114, 0, 105, 110, 2, 32, 0, 4, 109, 1, 110, 2, 29, 3, 116, 0, 109, 2, 18, 76, 0, 109, 2, 116, 0, 110, 2, 25, 0, 110, 8, 99, 2, 32, 0, 110, 116, 8, 109, 2, 109, 0, 110, 116, 8, 109, 2, 112, 17, 65, 17, 67, 0, 110, 116, 8, 109, 2, 114, 17, 65, 97, 108, 0, 110, 115, 104, 2, 17, 65, 3, 116, 88, 0, 110, 8, 17, 67, 2, 32, 3, 116, 134, 0, 110, 2, 116, 32, 3, 116, 140, 0, 4, 101, 2, 105, 3, 117, 0, 101, 8, 104, 112, 2, 110, 32, 0, 101, 117, 0, 4, 3, 127, 0, 2, 17, 67, 17, 67, 0, 8, 17, 67, 2, 109, 101, 32, 0, 8, 121, 2, 121, 0, 110, 2, 110, 0, 111, 1, 99, 108, 97, 2, 108, 0, 121, 8, 99, 2, 111, 3, 127, 37, 0, 110, 104, 2, 17, 65, 3, 127, 50, 0, 121, 8, 98, 2, 99, 111, 3, 127, 57, 0, 109, 2, 32, 3, 127, 65, 0, 115, 8, 2, 32, 12, 12, 3, 127, 89, 0, 4, 101, 8, 2, 17, 67, 3, 132, 0, 101, 117, 100, 0, 101, 117, 102, 115, 2, 32, 0, 101, 117, 2, 120, 3, 132, 143, 0, 7, 6, 112, 0, 4, 1, 97, 98, 2, 116, 3, 0, 4, 1, 97, 114, 100, 2, 32, 3, 0, 4, 1, 108, 117, 99, 115, 2, 116, 3, 0, 4, 1, 109, 97, 99, 2, 32, 3, 0, 4, 1, 109, 97, 104, 99, 2, 32, 3, 0, 4, 1, 109, 111, 99, 2, 116, 3, 0, 4, 2, 112, 3, 0, 4, 115, 1, 109, 2, 32, 3, 0, 4, 115, 1, 114, 2, 32, 3, 0, 116, 1, 17, 67, 2, 32, 3, 0, 4, 97, 100, 2, 32, 3, 21, 0, 108, 117, 103, 0, 114, 105, 110, 116, 101, 114, 2, 32, 0, 4, 116, 1, 101, 115, 2, 32, 3, 47, 0, 116, 1, 101, 115, 2, 105, 195, 168, 0, 3, 48, 0, 97, 114, 97, 8, 2, 112, 17, 67, 14, 128, 132, 132, 3, 48, 35, 34, 35, 0, 111, 108, 121, 8, 2, 21, 14, 128, 132, 132, 3, 48, 39, 55, 37, 0, 4, 111, 115, 116, 8, 2, 17, 65, 17, 67, 17, 67, 14, 128, 132, 132, 3, 48, 39, 89, 47, 0, 111, 115, 116, 8, 2, 17, 67, 14, 128, 132, 132, 0, 115, 121, 99, 104, 8, 2, 21, 14, 128, 132, 133, 3, 48, 89, 37, 49, 0, 4, 115, 121, 99, 104, 8, 2, 17, 65, 17, 65, 32, 14, 128, 132, 133, 3, 48, 89, 37, 91, 0, 115, 121, 99, 104, 8, 2, 105, 17, 67, 14, 128, 132, 133, 0, 115, 101, 117, 100, 111, 8, 2, 21, 14, 128, 132, 134, 3, 48, 89, 132, 72, 39, 0, 117, 105, 115, 113, 117, 39, 8, 2, 14, 128, 132, 135, 3, 48, 111, 37, 89, 49, 0, 97, 121, 115, 3, 48, 112, 37, 143, 0, 104, 3, 83, 0, 104, 111, 116, 111, 8, 2, 21, 14, 128, 132, 133, 3, 83, 39, 47, 39, 0, 7, 6, 113, 0, 4, 1, 110, 2, 32, 99, 101, 110, 116, 32, 3, 0, 1, 110, 2, 32, 109, 105, 108, 108, 3, 0, 117, 105, 99, 107, 3, 21, 0, 4, 3, 49, 0, 1, 110, 2, 32, 0, 117, 0, 117, 39, 8, 2, 17, 65, 14, 128, 132, 131, 0, 117, 101, 8, 2, 32, 3, 49, 13, 0, 117, 97, 8, 2, 100, 114, 105, 108, 108, 3, 49, 35, 0, 117, 8, 97, 2, 105, 102, 3, 49, 40, 0, 4, 117, 97, 1, 169, 195, 100, 3, 49, 58, 35, 0, 117, 97, 8, 2, 100, 0, 117, 97, 8, 2, 114, 116, 122, 0, 117, 97, 8, 2, 116, 17, 65, 0, 117, 97, 8, 17, 65, 0, 117, 97, 8, 17, 67, 0, 117, 97, 8, 97, 0, 117, 97, 110, 8, 2, 116, 17, 65, 3, 49, 58, 113, 0, 4, 117, 105, 8, 17, 65, 2, 100, 105, 115, 116, 3, 49, 111, 37, 0, 117, 105, 8, 17, 65, 2, 108, 97, 116, 0, 7, 6, 114, 0, 4, 2, 17, 67, 121, 32, 3, 21, 0, 101, 97, 108, 8, 0, 115, 116, 2, 32, 0, 117, 108, 101, 8, 0, 4, 3, 34, 0, 114, 0, 114, 1, 117, 111, 99, 2, 105, 0, 114, 1, 117, 111, 99, 2, 111, 0, 4, 114, 1, 117, 111, 99, 3, 34, 34, 0, 114, 1, 117, 111, 109, 0, 114, 8, 117, 115, 0, 97, 100, 105, 111, 8, 2, 21, 14, 128, 132, 133, 3, 34, 35, 72, 37, 39, 0, 7, 6, 115, 0, 4, 1, 117, 17, 67, 2, 32, 3, 0, 4, 1, 117, 99, 111, 100, 2, 32, 3, 0, 4, 1, 117, 99, 169, 195, 2, 32, 3, 0, 4, 1, 117, 103, 105, 2, 32, 3, 0, 4, 1, 117, 109, 169, 195, 2, 32, 3, 0, 4, 1, 117, 110, 101, 2, 32, 3, 0, 4, 1, 117, 114, 97, 2, 32, 3, 0, 4, 1, 117, 114, 117, 111, 2, 32, 3, 0, 4, 1, 117, 116, 105, 97, 2, 32, 3, 0, 4, 8, 117, 98, 17, 65, 2, 32, 3, 0, 4, 8, 117, 109, 2, 32, 3, 0, 4, 8, 117, 111, 116, 2, 32, 17, 67, 101, 115, 32, 3, 0, 4, 8, 117, 111, 116, 2, 32, 17, 67, 111, 115, 32, 3, 0, 8, 117, 111, 116, 2, 32, 108, 101, 117, 114, 115, 32, 3, 0, 4, 8, 17, 65, 2, 32, 3, 21, 0, 101, 110, 100, 2, 32, 0, 101, 114, 118, 101, 114, 8, 2, 29, 0, 104, 2, 17, 65, 112, 0, 104, 2, 17, 65, 116, 0, 104, 2, 32, 0, 105, 100, 101, 1, 18, 79, 2, 29, 12, 12, 12, 0, 105, 100, 101, 8, 2, 29, 12, 12, 12, 0, 107, 121, 8, 0, 109, 105, 108, 8, 0, 111, 110, 1, 18, 78, 2, 32, 0, 112, 121, 0, 116, 111, 110, 1, 18, 78, 2, 32, 0, 116, 111, 110, 101, 2, 32, 0, 4, 1, 17, 65, 2, 17, 65, 3, 88, 0, 1, 98, 117, 2, 105, 115, 0, 1, 110, 97, 114, 116, 2, 17, 65, 0, 2, 98, 0, 2, 100, 0, 2, 103, 0, 2, 106, 0, 2, 118, 0, 8, 108, 97, 2, 97, 99, 0, 104, 1, 169, 195, 100, 2, 17, 65, 0, 4, 3, 89, 0, 1, 17, 65, 2, 111, 102, 116, 0, 1, 17, 65, 2, 111, 108, 32, 0, 1, 97, 107, 97, 2, 32, 0, 1, 97, 115, 110, 97, 107, 2, 32, 0, 1, 105, 97, 2, 101, 109, 0, 1, 110, 97, 114, 116, 2, 101, 0, 1, 110, 97, 114, 116, 2, 117, 98, 0, 1, 111, 114, 116, 97, 98, 2, 32, 0, 1, 111, 114, 169, 195, 99, 111, 2, 32, 0, 1, 117, 98, 17, 65, 2, 32, 0, 1, 117, 98, 109, 2, 32, 0, 1, 117, 99, 17, 65, 2, 32, 0, 1, 117, 100, 111, 2, 32, 0, 1, 117, 103, 2, 32, 0, 1, 117, 105, 2, 32, 0, 1, 117, 108, 117, 17, 67, 2, 32, 0, 1, 117, 108, 121, 2, 32, 0, 1, 117, 109, 2, 32, 0, 1, 117, 110, 17, 65, 2, 32, 0, 1, 117, 112, 111, 2, 32, 0, 1, 117, 114, 17, 65, 2, 32, 0, 1, 117, 115, 97, 2, 32, 0, 1, 117, 115, 112, 2, 32, 0, 1, 117, 115, 115, 101, 99, 2, 32, 0, 1, 117, 116, 97, 2, 32, 0, 1, 117, 116, 99, 2, 32, 0, 1, 117, 116, 101, 2, 32, 0, 1, 117, 116, 105, 2, 32, 0, 1, 117, 116, 108, 2, 32, 0, 1, 117, 116, 111, 2, 32, 0, 1, 117, 116, 117, 17, 67, 2, 32, 0, 1, 117, 175, 195, 2, 32, 0, 1, 168, 195, 17, 67, 97, 2, 32, 0, 1, 168, 195, 110, 2, 32, 0, 8, 117, 2, 32, 0, 8, 117, 111, 116, 2, 32, 0, 8, 117, 111, 116, 2, 32, 100, 101, 115, 32, 0, 8, 117, 112, 17, 67, 17, 65, 99, 2, 32, 0, 39, 8, 2, 14, 128, 140, 130, 0, 39, 8, 2, 101, 115, 29, 14, 128, 140, 130, 0, 115, 0, 195, 167, 0, 99, 105, 101, 110, 2, 116, 3, 89, 37, 113, 0, 111, 99, 105, 111, 8, 2, 21, 14, 128, 132, 133, 3, 89, 39, 89, 37, 39, 0, 4, 99, 104, 2, 105, 101, 3, 89, 49, 0, 99, 104, 2, 105, 122, 0, 99, 104, 2, 111, 108, 0, 99, 104, 2, 111, 111, 0, 117, 112, 114, 97, 8, 2, 21, 14, 128, 132, 133, 3, 89, 111, 48, 34, 35, 0, 4, 117, 112, 101, 114, 8, 2, 21, 21, 14, 128, 132, 133, 3, 89, 111, 48, 112, 34, 0, 117, 112, 101, 114, 8, 2, 32, 0, 4, 99, 104, 3, 91, 0, 104, 0, 99, 104, 117, 3, 91, 40, 0, 116, 101, 105, 110, 2, 32, 3, 91, 47, 35, 57, 50, 0, 113, 108, 2, 32, 14, 128, 128, 131, 3, 112, 89, 49, 111, 112, 55, 0, 4, 1, 117, 108, 112, 2, 32, 3, 143, 0, 2, 32, 14, 128, 128, 129, 0, 7, 6, 116, 0, 4, 1, 108, 117, 97, 2, 32, 3, 0, 4, 1, 110, 2, 32, 3, 0, 4, 1, 114, 2, 32, 3, 0, 4, 2, 32, 3, 0, 104, 1, 115, 2, 109, 3, 0, 4, 1, 105, 2, 117, 110, 101, 29, 3, 21, 0, 1, 114, 97, 17, 67, 115, 2, 32, 0, 1, 114, 97, 17, 67, 115, 2, 101, 114, 32, 0, 104, 2, 17, 65, 0, 104, 2, 25, 0, 105, 109, 101, 8, 0, 108, 101, 2, 32, 0, 111, 110, 1, 103, 2, 32, 0, 111, 111, 0, 114, 121, 2, 32, 0, 116, 108, 0, 117, 110, 8, 2, 17, 65, 29, 0, 4, 3, 47, 0, 1, 17, 67, 2, 32, 0, 1, 26, 2, 105, 111, 110, 0, 1, 99, 101, 26, 2, 105, 111, 110, 0, 1, 101, 17, 67, 2, 105, 111, 110, 115, 0, 1, 101, 104, 99, 97, 2, 105, 111, 110, 0, 1, 105, 17, 67, 169, 195, 2, 105, 111, 110, 115, 0, 1, 105, 97, 2, 105, 111, 110, 0, 1, 105, 98, 97, 104, 2, 105, 111, 110, 115, 0, 1, 105, 99, 2, 105, 111, 110, 115, 0, 1, 105, 107, 2, 32, 0, 1, 105, 109, 105, 2, 105, 111, 110, 115, 0, 1, 105, 110, 97, 114, 103, 2, 32, 0, 1, 105, 111, 2, 105, 111, 110, 0, 1, 105, 115, 105, 17, 67, 2, 105, 111, 110, 0, 1, 110, 97, 2, 105, 97, 0, 1, 110, 97, 104, 99, 2, 105, 111, 110, 0, 1, 110, 101, 115, 2, 105, 111, 110, 32, 0, 1, 112, 101, 26, 2, 105, 111, 110, 0, 1, 112, 109, 111, 99, 2, 105, 111, 110, 115, 0, 1, 114, 111, 112, 17, 65, 2, 105, 111, 110, 0, 1, 114, 111, 112, 17, 67, 2, 105, 111, 110, 0, 1, 114, 111, 115, 2, 105, 111, 110, 0, 1, 115, 2, 105, 111, 110, 0, 1, 116, 2, 105, 111, 110, 0, 1, 117, 17, 65, 26, 2, 105, 111, 110, 0, 1, 169, 195, 26, 2, 105, 111, 110, 0, 1, 170, 195, 114, 2, 105, 111, 110, 0, 8, 0, 8, 17, 65, 115, 110, 97, 114, 116, 2, 32, 0, 8, 97, 116, 2, 105, 111, 110, 0, 8, 101, 99, 2, 32, 0, 39, 8, 2, 14, 128, 140, 130, 0, 104, 0, 104, 1, 114, 111, 2, 12, 12, 0, 104, 2, 17, 65, 114, 17, 65, 12, 12, 0, 104, 2, 18, 77, 12, 12, 0, 104, 2, 111, 17, 67, 17, 65, 0, 104, 8, 2, 101, 114, 109, 0, 116, 0, 8, 2, 32, 3, 47, 36, 0, 4, 101, 108, 101, 8, 3, 47, 36, 55, 36, 0, 195, 169, 108, 195, 169, 8, 2, 21, 14, 128, 132, 132, 0, 104, 101, 114, 109, 111, 8, 2, 21, 14, 128, 132, 134, 3, 47, 112, 34, 65, 39, 0, 4, 1, 17, 67, 2, 105, 101, 117, 3, 89, 0, 1, 97, 2, 105, 97, 0, 1, 97, 2, 105, 101, 110, 0, 1, 97, 109, 17, 65, 2, 105, 101, 29, 0, 1, 97, 114, 99, 2, 105, 101, 29, 0, 1, 99, 110, 17, 65, 17, 67, 2, 105, 111, 110, 0, 1, 105, 2, 105, 101, 110, 0, 1, 105, 110, 105, 2, 105, 17, 65, 0, 1, 105, 115, 2, 105, 111, 110, 0, 1, 105, 116, 169, 195, 2, 105, 111, 110, 0, 1, 110, 97, 2, 105, 97, 116, 0, 1, 110, 101, 2, 105, 97, 0, 1, 111, 2, 105, 101, 110, 0, 1, 112, 2, 105, 97, 0, 1, 114, 2, 105, 97, 0, 1, 114, 97, 109, 2, 105, 101, 110, 0, 1, 114, 101, 110, 2, 105, 101, 0, 1, 114, 111, 112, 111, 2, 105, 111, 110, 0, 1, 117, 98, 108, 2, 105, 17, 65, 0, 1, 117, 108, 2, 105, 111, 110, 0, 1, 117, 110, 2, 105, 101, 29, 0, 1, 169, 195, 109, 97, 2, 105, 101, 29, 0, 1, 169, 195, 112, 105, 2, 105, 101, 29, 0, 2, 105, 17, 65, 109, 0, 2, 105, 101, 108, 0, 2, 105, 101, 117, 0, 2, 105, 111, 32, 0, 2, 105, 111, 110, 0, 4, 105, 101, 110, 1, 105, 110, 2, 116, 32, 3, 89, 37, 0, 105, 101, 110, 1, 117, 98, 2, 116, 32, 0, 4, 1, 17, 65, 2, 45, 3, 140, 0, 1, 45, 2, 45, 0, 1, 105, 17, 67, 26, 2, 32, 0, 1, 105, 116, 101, 112, 2, 32, 0, 1, 110, 26, 2, 32, 0, 1, 105, 117, 104, 2, 32, 3, 141, 0, 115, 2, 32, 14, 128, 128, 129, 3, 143, 0, 7, 6, 117, 0, 1, 103, 2, 17, 65, 3, 0, 4, 1, 114, 2, 110, 29, 3, 21, 0, 97, 108, 1, 18, 68, 2, 32, 0, 99, 104, 2, 32, 0, 105, 1, 17, 67, 2, 99, 101, 0, 108, 116, 1, 17, 67, 2, 32, 0, 109, 98, 101, 114, 2, 32, 0, 109, 112, 2, 32, 0, 110, 8, 17, 67, 2, 32, 0, 110, 8, 17, 67, 2, 110, 121, 0, 110, 99, 104, 0, 110, 100, 101, 114, 0, 112, 2, 32, 0, 112, 8, 2, 17, 67, 0, 114, 110, 2, 29, 0, 115, 105, 8, 98, 0, 115, 116, 2, 32, 0, 122, 122, 0, 4, 1, 103, 2, 97, 121, 3, 40, 0, 1, 107, 175, 195, 97, 104, 2, 29, 0, 1, 112, 2, 116, 115, 99, 104, 0, 99, 99, 105, 1, 17, 67, 3, 40, 76, 37, 0, 4, 97, 1, 103, 2, 108, 32, 3, 58, 35, 0, 97, 1, 103, 97, 2, 29, 0, 97, 1, 103, 105, 116, 17, 67, 2, 32, 0, 97, 8, 103, 0, 4, 3, 111, 0, 1, 103, 2, 195, 171, 0, 1, 103, 2, 195, 175, 0, 108, 8, 99, 2, 32, 0, 110, 2, 110, 0, 120, 1, 108, 102, 2, 32, 0, 105, 3, 111, 37, 0, 121, 2, 17, 65, 3, 111, 37, 57, 0, 108, 116, 114, 97, 8, 2, 14, 128, 132, 133, 3, 111, 55, 47, 34, 35, 0, 105, 110, 2, 25, 3, 111, 114, 0, 4, 109, 1, 102, 2, 32, 3, 115, 0, 109, 2, 18, 76, 0, 110, 1, 17, 67, 17, 67, 2, 32, 0, 110, 2, 17, 67, 0, 110, 8, 104, 2, 32, 0, 110, 116, 1, 114, 112, 2, 32, 0, 4, 110, 1, 99, 117, 2, 32, 3, 115, 134, 0, 110, 2, 32, 0, 4, 1, 17, 67, 2, 98, 29, 3, 117, 0, 1, 17, 67, 2, 103, 29, 0, 8, 17, 67, 2, 114, 102, 29, 0, 8, 108, 98, 2, 102, 102, 0, 8, 110, 2, 114, 115, 101, 0, 8, 115, 2, 114, 102, 101, 29, 0, 101, 2, 105, 108, 0, 122, 2, 122, 0, 109, 2, 32, 3, 127, 65, 0, 7, 6, 118, 0, 4, 111, 105, 99, 101, 2, 29, 3, 21, 0, 111, 105, 100, 2, 32, 0, 121, 2, 32, 0, 3, 84, 0, 105, 101, 119, 2, 29, 3, 84, 57, 40, 0, 105, 101, 119, 8, 2, 17, 65, 3, 84, 57, 40, 84, 0, 101, 114, 115, 2, 32, 3, 84, 112, 34, 143, 0, 101, 114, 1, 105, 114, 100, 2, 29, 3, 84, 117, 34, 0, 7, 6, 119, 0, 4, 8, 2, 17, 65, 17, 67, 3, 21, 0, 8, 2, 17, 65, 105, 0, 97, 114, 0, 97, 118, 0, 97, 121, 0, 101, 8, 0, 104, 0, 110, 1, 17, 65, 0, 111, 114, 0, 114, 0, 8, 2, 17, 65, 3, 23, 58, 0, 4, 3, 58, 0, 8, 2, 17, 65, 17, 67, 111, 0, 8, 2, 17, 65, 116, 116, 0, 8, 2, 105, 110, 97, 0, 2, 97, 103, 12, 12, 3, 84, 0, 7, 6, 120, 0, 4, 1, 105, 97, 2, 32, 3, 0, 4, 1, 105, 111, 2, 32, 3, 0, 4, 1, 105, 114, 2, 32, 3, 0, 8, 117, 97, 2, 113, 117, 101, 108, 3, 0, 109, 108, 2, 32, 14, 128, 128, 131, 3, 23, 37, 49, 89, 112, 65, 112, 55, 0, 8, 2, 17, 67, 14, 128, 132, 129, 3, 37, 49, 89, 0, 4, 3, 49, 89, 0, 1, 101, 18, 68, 2, 17, 65, 0, 120, 0, 4, 1, 101, 2, 17, 65, 3, 81, 88, 0, 8, 2, 17, 65, 0, 8, 101, 2, 104, 0, 8, 101, 110, 105, 2, 17, 65, 0, 4, 1, 105, 100, 2, 105, 195, 168, 3, 88, 0, 1, 105, 115, 2, 105, 195, 168, 0, 1, 117, 101, 100, 2, 105, 195, 168, 0, 8, 105, 100, 2, 32, 110, 101, 117, 102, 0, 4, 8, 105, 111, 115, 2, 17, 65, 3, 89, 0, 8, 105, 115, 2, 32, 110, 101, 117, 0, 1, 117, 17, 65, 2, 32, 3, 143, 0, 4, 8, 105, 100, 2, 32, 3, 144, 0, 8, 105, 115, 2, 32, 0, 7, 6, 121, 0, 4, 1, 17, 67, 2, 101, 32, 3, 21, 0, 1, 17, 67, 11, 2, 32, 0, 1, 17, 67, 17, 65, 2, 32, 0, 1, 17, 67, 101, 17, 67, 21, 2, 32, 0, 1, 17, 67, 110, 2, 32, 0, 8, 17, 67, 2, 32, 0, 97, 99, 104, 116, 8, 0, 122, 101, 0, 8, 2, 17, 65, 3, 23, 57, 0, 4, 3, 37, 0, 1, 115, 115, 2, 32, 0, 2, 110, 110, 0, 115, 1, 29, 2, 32, 3, 37, 89, 0, 8, 2, 101, 117, 3, 57, 0, 97, 104, 111, 111, 8, 2, 14, 128, 132, 133, 3, 57, 35, 6, 40, 0, 4, 109, 2, 18, 76, 3, 114, 0, 109, 2, 32, 0, 110, 2, 25, 0, 7, 6, 122, 0, 3, 88, 0, 101, 114, 1, 116, 2, 32, 3, 88, 112, 34, 0, 101, 114, 1, 17, 67, 2, 32, 3, 88, 117, 34, 0, 1, 116, 3, 89, 0, 7, 6, 0, 194, 176, 8, 32, 110, 3, 0, 39, 2, 17, 67, 3, 21, 0, 195, 162, 3, 35, 12, 0, 195, 169, 3, 36, 0, 195, 182, 3, 39, 0, 195, 177, 3, 67, 0, 194, 176, 3, 72, 13, 81, 34, 36, 0, 36, 3, 72, 127, 55, 35, 34, 0, 195, 188, 3, 111, 0, 195, 187, 3, 111, 12, 0, 195, 170, 3, 112, 0, 58, 8, 32, 18, 81, 2, 32, 18, 82, 15, 32, 3, 117, 34, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts19 = FileInMemory_createWithData (21484, reinterpret_cast (&espeakdata_dicts19_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/fr_dict", U"fr"); Collection_addItem (me.peek(), espeakdata_dicts19.transfer()); static unsigned char espeakdata_dicts20_data[1093] = { 0, 4, 0, 0, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 97, 0, 3, 106, 0, 7, 6, 98, 0, 3, 69, 0, 7, 6, 101, 0, 3, 108, 0, 7, 6, 105, 0, 3, 110, 0, 7, 6, 111, 0, 3, 112, 0, 7, 6, 116, 0, 3, 47, 0, 7, 6, 117, 0, 3, 114, 0, 7, 6, 0, 36, 3, 70, 111, 55, 13, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts20 = FileInMemory_createWithData (1092, reinterpret_cast (&espeakdata_dicts20_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/ga_dict", U"ga"); Collection_addItem (me.peek(), espeakdata_dicts20.transfer()); static unsigned char espeakdata_dicts21_data[3391] = { 0, 4, 0, 0, 220, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 6, 95, 48, 12, 1, 14, 7, 21, 0, 101, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 207, 132, 225, 191, 130, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 207, 132, 225, 191, 178, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 207, 132, 225, 189, 184, 72, 0, 0, 0, 0, 8, 133, 207, 132, 225, 189, 188, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 207, 132, 225, 189, 176, 72, 0, 0, 0, 0, 0, 0, 0, 0, 10, 135, 207, 132, 225, 189, 176, 207, 130, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 131, 8, 206, 183, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 131, 8, 206, 191, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 137, 207, 132, 206, 177, 225, 189, 182, 207, 130, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 137, 207, 132, 206, 177, 225, 189, 182, 206, 189, 72, 12, 137, 207, 132, 206, 177, 225, 189, 182, 206, 189, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 135, 207, 132, 225, 189, 180, 207, 130, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 135, 207, 132, 225, 189, 180, 206, 189, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 137, 207, 132, 206, 191, 225, 189, 182, 207, 130, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 137, 207, 132, 206, 191, 225, 189, 182, 206, 189, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 135, 207, 132, 206, 191, 225, 189, 186, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 135, 207, 132, 225, 189, 184, 206, 189, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 137, 207, 132, 206, 191, 225, 189, 186, 207, 130, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 206, 191, 8, 206, 185, 72, 0, 0, 0, 0, 8, 133, 206, 177, 8, 206, 185, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 135, 207, 132, 225, 189, 188, 206, 189, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 20, 0, 0, 50, 32, 0, 0, 39, 0, 0, 0, 97, 0, 0, 0, 177, 3, 0, 0, 111, 0, 0, 0, 191, 3, 0, 0, 118, 0, 0, 0, 189, 3, 0, 0, 65, 0, 0, 0, 145, 3, 0, 0, 66, 0, 0, 0, 146, 3, 0, 0, 69, 0, 0, 0, 149, 3, 0, 0, 90, 0, 0, 0, 150, 3, 0, 0, 72, 0, 0, 0, 151, 3, 0, 0, 73, 0, 0, 0, 153, 3, 0, 0, 75, 0, 0, 0, 154, 3, 0, 0, 77, 0, 0, 0, 156, 3, 0, 0, 78, 0, 0, 0, 157, 3, 0, 0, 79, 0, 0, 0, 159, 3, 0, 0, 80, 0, 0, 0, 161, 3, 0, 0, 84, 0, 0, 0, 164, 3, 0, 0, 89, 0, 0, 0, 165, 3, 0, 0, 88, 0, 0, 0, 167, 3, 0, 0, 116, 0, 104, 0, 184, 3, 0, 0, 112, 0, 104, 0, 198, 3, 0, 0, 107, 0, 104, 0, 199, 3, 0, 0, 112, 0, 115, 0, 200, 3, 0, 0, 98, 0, 0, 0, 178, 3, 0, 0, 103, 0, 0, 0, 179, 3, 0, 0, 100, 0, 0, 0, 180, 3, 0, 0, 101, 0, 0, 0, 181, 3, 0, 0, 122, 0, 0, 0, 182, 3, 0, 0, 113, 0, 0, 0, 183, 3, 0, 0, 105, 0, 0, 0, 185, 3, 0, 0, 107, 0, 0, 0, 186, 3, 0, 0, 108, 0, 0, 0, 187, 3, 0, 0, 109, 0, 0, 0, 188, 3, 0, 0, 110, 0, 0, 0, 189, 3, 0, 0, 120, 0, 0, 0, 190, 3, 0, 0, 112, 0, 0, 0, 192, 3, 0, 0, 114, 0, 0, 0, 193, 3, 0, 0, 115, 0, 0, 0, 195, 3, 0, 0, 116, 0, 0, 0, 196, 3, 0, 0, 117, 0, 0, 0, 197, 3, 0, 0, 121, 0, 0, 0, 197, 3, 0, 0, 119, 0, 0, 0, 201, 3, 0, 0, 172, 3, 0, 0, 112, 31, 0, 0, 113, 31, 0, 0, 112, 31, 0, 0, 180, 31, 0, 0, 178, 31, 0, 0, 182, 31, 0, 0, 112, 31, 0, 0, 183, 31, 0, 0, 178, 31, 0, 0, 0, 31, 0, 0, 177, 3, 0, 0, 1, 31, 0, 0, 104, 0, 177, 3, 2, 31, 0, 0, 112, 31, 0, 0, 3, 31, 0, 0, 104, 0, 112, 31, 4, 31, 0, 0, 112, 31, 0, 0, 5, 31, 0, 0, 104, 0, 112, 31, 6, 31, 0, 0, 112, 31, 0, 0, 7, 31, 0, 0, 104, 0, 112, 31, 128, 31, 0, 0, 179, 31, 0, 0, 129, 31, 0, 0, 104, 0, 179, 31, 130, 31, 0, 0, 178, 31, 0, 0, 131, 31, 0, 0, 104, 0, 178, 31, 132, 31, 0, 0, 178, 31, 0, 0, 133, 31, 0, 0, 104, 0, 178, 31, 134, 31, 0, 0, 178, 31, 0, 0, 135, 31, 0, 0, 104, 0, 178, 31, 173, 3, 0, 0, 114, 31, 0, 0, 115, 31, 0, 0, 114, 31, 0, 0, 16, 31, 0, 0, 181, 3, 0, 0, 17, 31, 0, 0, 104, 0, 181, 3, 18, 31, 0, 0, 114, 31, 0, 0, 19, 31, 0, 0, 104, 0, 114, 31, 20, 31, 0, 0, 114, 31, 0, 0, 21, 31, 0, 0, 104, 0, 114, 31, 174, 3, 0, 0, 116, 31, 0, 0, 117, 31, 0, 0, 116, 31, 0, 0, 196, 31, 0, 0, 194, 31, 0, 0, 198, 31, 0, 0, 116, 31, 0, 0, 199, 31, 0, 0, 194, 31, 0, 0, 32, 31, 0, 0, 183, 3, 0, 0, 33, 31, 0, 0, 104, 0, 183, 3, 34, 31, 0, 0, 116, 31, 0, 0, 35, 31, 0, 0, 104, 0, 116, 31, 36, 31, 0, 0, 116, 31, 0, 0, 37, 31, 0, 0, 104, 0, 116, 31, 38, 31, 0, 0, 116, 31, 0, 0, 39, 31, 0, 0, 104, 0, 116, 31, 144, 31, 0, 0, 195, 31, 0, 0, 145, 31, 0, 0, 104, 0, 195, 31, 146, 31, 0, 0, 194, 31, 0, 0, 147, 31, 0, 0, 104, 0, 194, 31, 148, 31, 0, 0, 194, 31, 0, 0, 149, 31, 0, 0, 104, 0, 194, 31, 150, 31, 0, 0, 194, 31, 0, 0, 151, 31, 0, 0, 104, 0, 194, 31, 175, 3, 0, 0, 118, 31, 0, 0, 119, 31, 0, 0, 118, 31, 0, 0, 214, 31, 0, 0, 118, 31, 0, 0, 48, 31, 0, 0, 185, 3, 0, 0, 49, 31, 0, 0, 104, 0, 185, 3, 50, 31, 0, 0, 118, 31, 0, 0, 51, 31, 0, 0, 104, 0, 118, 31, 52, 31, 0, 0, 118, 31, 0, 0, 53, 31, 0, 0, 104, 0, 118, 31, 54, 31, 0, 0, 118, 31, 0, 0, 55, 31, 0, 0, 104, 0, 118, 31, 211, 31, 0, 0, 210, 31, 0, 0, 215, 31, 0, 0, 210, 31, 0, 0, 204, 3, 0, 0, 120, 31, 0, 0, 121, 31, 0, 0, 120, 31, 0, 0, 64, 31, 0, 0, 191, 3, 0, 0, 65, 31, 0, 0, 104, 0, 191, 3, 66, 31, 0, 0, 120, 31, 0, 0, 67, 31, 0, 0, 104, 0, 120, 31, 68, 31, 0, 0, 120, 31, 0, 0, 69, 31, 0, 0, 104, 0, 120, 31, 205, 3, 0, 0, 122, 31, 0, 0, 123, 31, 0, 0, 122, 31, 0, 0, 230, 31, 0, 0, 122, 31, 0, 0, 80, 31, 0, 0, 197, 3, 0, 0, 81, 31, 0, 0, 104, 0, 197, 3, 82, 31, 0, 0, 122, 31, 0, 0, 83, 31, 0, 0, 104, 0, 122, 31, 84, 31, 0, 0, 122, 31, 0, 0, 85, 31, 0, 0, 104, 0, 122, 31, 86, 31, 0, 0, 122, 31, 0, 0, 87, 31, 0, 0, 104, 0, 122, 31, 227, 31, 0, 0, 226, 31, 0, 0, 231, 31, 0, 0, 226, 31, 0, 0, 206, 3, 0, 0, 124, 31, 0, 0, 125, 31, 0, 0, 124, 31, 0, 0, 244, 31, 0, 0, 242, 31, 0, 0, 246, 31, 0, 0, 124, 31, 0, 0, 247, 31, 0, 0, 242, 31, 0, 0, 96, 31, 0, 0, 201, 3, 0, 0, 97, 31, 0, 0, 104, 0, 201, 3, 98, 31, 0, 0, 124, 31, 0, 0, 99, 31, 0, 0, 104, 0, 124, 31, 100, 31, 0, 0, 124, 31, 0, 0, 101, 31, 0, 0, 104, 0, 124, 31, 102, 31, 0, 0, 124, 31, 0, 0, 103, 31, 0, 0, 104, 0, 124, 31, 160, 31, 0, 0, 243, 31, 0, 0, 161, 31, 0, 0, 104, 0, 243, 31, 162, 31, 0, 0, 242, 31, 0, 0, 163, 31, 0, 0, 104, 0, 242, 31, 164, 31, 0, 0, 242, 31, 0, 0, 165, 31, 0, 0, 104, 0, 242, 31, 166, 31, 0, 0, 242, 31, 0, 0, 167, 31, 0, 0, 104, 0, 242, 31, 228, 31, 0, 0, 193, 3, 0, 0, 229, 31, 0, 0, 104, 0, 193, 3, 0, 0, 0, 0, 6, 195, 175, 0, 3, 37, 0, 7, 6, 1, 50, 0, 104, 225, 189, 186, 3, 6, 107, 114, 0, 104, 225, 189, 182, 3, 6, 107, 117, 0, 225, 189, 186, 3, 6, 114, 0, 225, 189, 182, 3, 6, 117, 0, 3, 35, 0, 104, 207, 133, 3, 107, 114, 0, 104, 206, 185, 3, 107, 117, 0, 207, 133, 3, 114, 0, 206, 185, 3, 117, 0, 7, 6, 1, 51, 0, 3, 71, 0, 7, 6, 1, 52, 0, 206, 179, 3, 68, 81, 0, 3, 81, 0, 7, 6, 1, 53, 0, 3, 72, 0, 7, 6, 1, 54, 0, 225, 189, 182, 3, 6, 36, 12, 0, 104, 225, 189, 182, 3, 6, 107, 36, 12, 0, 104, 225, 189, 186, 3, 6, 107, 115, 0, 225, 189, 186, 3, 6, 115, 0, 3, 36, 0, 206, 185, 3, 36, 12, 0, 104, 206, 185, 3, 107, 36, 12, 0, 104, 207, 133, 3, 107, 115, 0, 207, 133, 3, 115, 0, 7, 6, 1, 55, 0, 3, 88, 0, 7, 6, 1, 56, 0, 104, 225, 189, 182, 3, 6, 107, 119, 12, 0, 104, 225, 189, 186, 3, 6, 107, 124, 12, 0, 225, 189, 182, 3, 6, 119, 12, 0, 225, 189, 186, 3, 6, 124, 12, 0, 104, 206, 185, 3, 107, 119, 12, 0, 104, 207, 133, 3, 107, 124, 12, 0, 3, 109, 12, 0, 206, 185, 3, 119, 12, 0, 207, 133, 3, 124, 12, 0, 7, 6, 1, 57, 0, 3, 87, 0, 7, 6, 1, 58, 0, 3, 37, 0, 7, 6, 1, 59, 0, 3, 49, 0, 7, 6, 1, 60, 0, 3, 55, 0, 7, 6, 1, 61, 0, 3, 65, 0, 7, 6, 1, 62, 0, 3, 50, 0, 7, 6, 1, 63, 0, 3, 49, 89, 0, 7, 6, 1, 64, 0, 225, 189, 186, 3, 6, 40, 12, 0, 104, 225, 189, 186, 3, 6, 107, 40, 12, 0, 104, 225, 189, 182, 3, 6, 107, 120, 0, 225, 189, 182, 3, 6, 120, 0, 3, 39, 0, 207, 133, 3, 40, 12, 0, 104, 207, 133, 3, 107, 40, 12, 0, 104, 206, 185, 3, 107, 120, 0, 206, 185, 3, 120, 0, 7, 6, 1, 65, 0, 3, 48, 0, 7, 6, 1, 66, 0, 3, 51, 0, 7, 6, 1, 67, 0, 3, 89, 0, 7, 6, 1, 68, 0, 3, 89, 0, 7, 6, 1, 69, 0, 3, 47, 0, 7, 6, 1, 70, 0, 104, 225, 189, 182, 3, 6, 107, 127, 0, 225, 189, 182, 3, 6, 127, 0, 104, 206, 185, 3, 107, 127, 0, 3, 112, 0, 206, 185, 3, 127, 0, 7, 6, 1, 71, 0, 3, 83, 0, 7, 6, 1, 72, 0, 3, 101, 0, 7, 6, 1, 73, 0, 3, 48, 89, 0, 7, 6, 1, 74, 0, 104, 225, 189, 182, 3, 6, 107, 125, 12, 0, 104, 225, 189, 186, 3, 6, 107, 126, 12, 0, 225, 189, 182, 3, 6, 125, 12, 0, 225, 189, 186, 3, 6, 126, 12, 0, 104, 206, 185, 3, 107, 125, 12, 0, 104, 207, 133, 3, 107, 126, 12, 0, 3, 110, 12, 0, 206, 185, 3, 125, 12, 0, 207, 133, 3, 126, 12, 0, 7, 6, 1, 75, 0, 3, 37, 0, 7, 6, 1, 76, 0, 104, 225, 189, 182, 3, 6, 107, 127, 0, 225, 189, 182, 3, 6, 127, 0, 104, 206, 185, 3, 107, 127, 0, 3, 112, 0, 206, 185, 3, 127, 0, 7, 6, 97, 0, 3, 35, 0, 117, 3, 114, 0, 105, 3, 117, 0, 7, 6, 98, 0, 3, 71, 0, 7, 6, 100, 0, 3, 72, 0, 7, 6, 101, 0, 3, 36, 0, 105, 3, 36, 12, 0, 117, 3, 115, 0, 7, 6, 102, 0, 3, 83, 0, 7, 6, 103, 0, 103, 3, 68, 81, 0, 3, 81, 0, 7, 6, 104, 0, 3, 107, 0, 7, 6, 105, 0, 3, 37, 0, 7, 6, 106, 0, 3, 57, 0, 7, 6, 107, 0, 3, 49, 0, 104, 3, 101, 0, 7, 6, 108, 0, 3, 55, 0, 7, 6, 109, 0, 3, 65, 0, 7, 6, 110, 0, 3, 50, 0, 7, 6, 111, 0, 3, 39, 0, 117, 3, 40, 12, 0, 105, 3, 120, 0, 7, 6, 112, 0, 3, 48, 0, 104, 3, 83, 0, 7, 6, 113, 0, 3, 109, 12, 0, 105, 3, 119, 12, 0, 117, 3, 124, 12, 0, 7, 6, 114, 0, 3, 51, 0, 7, 6, 115, 0, 3, 89, 0, 7, 6, 116, 0, 3, 47, 0, 104, 3, 87, 0, 7, 6, 117, 0, 3, 112, 0, 105, 3, 127, 0, 7, 6, 118, 0, 3, 84, 0, 7, 6, 119, 0, 3, 110, 12, 0, 105, 3, 125, 0, 117, 3, 126, 0, 7, 6, 120, 0, 3, 101, 0, 7, 6, 121, 0, 3, 112, 0, 105, 3, 127, 0, 7, 6, 122, 0, 3, 88, 0, 7, 6, 0, 225, 189, 176, 3, 6, 35, 0, 225, 189, 178, 3, 6, 36, 0, 4, 225, 189, 182, 3, 6, 37, 0, 225, 191, 146, 0, 225, 189, 184, 3, 6, 39, 0, 225, 189, 180, 3, 6, 109, 12, 0, 225, 189, 188, 3, 6, 110, 12, 0, 4, 225, 189, 186, 3, 6, 112, 0, 225, 191, 162, 0, 225, 190, 178, 3, 6, 117, 12, 0, 225, 191, 130, 3, 6, 119, 12, 0, 225, 191, 178, 3, 6, 125, 12, 0, 39, 3, 8, 0, 225, 190, 179, 3, 117, 12, 0, 225, 191, 131, 3, 119, 12, 0, 225, 191, 179, 3, 125, 12, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts21 = FileInMemory_createWithData (3390, reinterpret_cast (&espeakdata_dicts21_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/grc_dict", U"grc"); Collection_addItem (me.peek(), espeakdata_dicts21.transfer()); static unsigned char espeakdata_dicts22_data[7360] = { 0, 4, 0, 0, 139, 25, 0, 0, 0, 0, 0, 7, 195, 85, 81, 64, 9, 17, 7, 195, 4, 209, 128, 9, 17, 0, 0, 6, 65, 4, 35, 0, 14, 5, 193, 4, 72, 8, 0, 0, 0, 0, 6, 65, 8, 71, 13, 0, 0, 0, 7, 195, 57, 50, 64, 9, 17, 0, 0, 6, 65, 12, 117, 13, 0, 0, 0, 7, 195, 41, 49, 64, 9, 17, 7, 195, 20, 209, 128, 9, 17, 15, 4, 95, 8, 1, 3, 49, 84, 6, 35, 76, 138, 117, 122, 0, 0, 0, 6, 65, 16, 72, 13, 0, 0, 0, 6, 195, 57, 33, 192, 17, 0, 0, 8, 197, 56, 83, 65, 41, 80, 76, 0, 0, 0, 0, 6, 65, 24, 83, 13, 0, 0, 0, 7, 195, 57, 48, 64, 9, 17, 7, 195, 57, 32, 192, 9, 17, 0, 0, 6, 65, 28, 81, 13, 0, 0, 0, 0, 0, 6, 65, 32, 101, 13, 0, 0, 14, 1, 33, 6, 40, 88, 84, 138, 76, 50, 138, 49, 0, 102, 14, 1, 33, 6, 40, 89, 49, 55, 138, 76, 50, 138, 49, 0, 0, 0, 11, 1, 35, 71, 140, 6, 39, 57, 10, 0, 27, 0, 6, 65, 36, 37, 0, 14, 5, 193, 36, 72, 8, 0, 11, 1, 37, 48, 6, 39, 89, 47, 39, 0, 27, 0, 9, 1, 38, 10, 6, 36, 50, 72, 0, 0, 0, 6, 65, 40, 57, 136, 0, 0, 0, 7, 195, 61, 22, 64, 9, 17, 15, 1, 42, 88, 84, 57, 6, 36, 88, 72, 37, 117, 122, 0, 27, 0, 7, 195, 5, 2, 0, 9, 17, 9, 1, 43, 48, 55, 40, 89, 0, 27, 0, 7, 195, 5, 3, 0, 9, 17, 6, 65, 44, 49, 13, 0, 0, 7, 195, 5, 4, 0, 9, 17, 0, 7, 195, 37, 69, 192, 9, 17, 11, 1, 46, 47, 35, 76, 49, 122, 0, 104, 27, 10, 1, 46, 47, 39, 76, 49, 122, 0, 27, 0, 11, 1, 47, 49, 140, 6, 39, 88, 10, 0, 27, 0, 6, 65, 48, 55, 13, 0, 0, 0, 7, 195, 57, 37, 192, 9, 17, 0, 0, 6, 65, 52, 65, 13, 0, 0, 7, 195, 53, 0, 64, 9, 17, 0, 7, 195, 92, 150, 128, 9, 17, 0, 0, 6, 65, 56, 50, 13, 0, 0, 0, 7, 195, 57, 36, 192, 9, 17, 14, 1, 58, 72, 84, 6, 39, 47, 122, 76, 49, 122, 0, 104, 13, 1, 58, 72, 84, 6, 39, 47, 39, 76, 49, 122, 0, 0, 0, 6, 65, 60, 39, 0, 14, 5, 193, 60, 72, 28, 0, 14, 1, 61, 10, 57, 6, 36, 72, 50, 122, 49, 39, 0, 27, 0, 0, 0, 15, 1, 64, 47, 51, 81, 39, 84, 35, 76, 49, 39, 37, 0, 102, 8, 1, 64, 10, 6, 35, 47, 0, 6, 65, 64, 48, 13, 0, 0, 7, 195, 65, 0, 64, 9, 17, 7, 194, 4, 32, 9, 17, 41, 0, 7, 195, 56, 51, 192, 9, 17, 6, 195, 48, 128, 64, 17, 7, 195, 4, 209, 192, 9, 17, 0, 0, 7, 65, 68, 49, 84, 13, 0, 0, 0, 6, 195, 72, 48, 192, 17, 0, 0, 6, 65, 72, 51, 13, 0, 0, 8, 66, 5, 32, 122, 51, 0, 102, 6, 194, 73, 0, 9, 17, 0, 0, 0, 7, 65, 76, 89, 13, 0, 14, 7, 65, 76, 89, 10, 0, 28, 0, 0, 0, 0, 6, 65, 80, 47, 13, 0, 0, 0, 7, 195, 36, 209, 192, 9, 17, 0, 0, 6, 65, 84, 40, 0, 14, 5, 193, 84, 72, 28, 7, 195, 4, 51, 0, 9, 17, 0, 0, 0, 0, 6, 65, 88, 84, 13, 0, 0, 0, 0, 16, 4, 95, 49, 77, 52, 71, 6, 37, 55, 37, 57, 111, 50, 0, 104, 15, 4, 95, 49, 77, 52, 71, 6, 37, 55, 37, 57, 139, 50, 0, 0, 13, 1, 92, 71, 6, 109, 49, 89, 55, 109, 91, 0, 27, 13, 65, 92, 72, 40, 48, 55, 39, 15, 84, 13, 0, 102, 16, 65, 92, 72, 84, 39, 89, 47, 140, 40, 49, 39, 15, 84, 13, 0, 0, 7, 195, 5, 52, 0, 9, 17, 0, 6, 195, 16, 243, 192, 17, 16, 1, 94, 117, 6, 37, 51, 49, 40, 65, 83, 55, 36, 49, 89, 0, 0, 7, 195, 5, 54, 0, 9, 17, 0, 15, 4, 95, 49, 77, 49, 107, 6, 37, 61, 35, 72, 139, 0, 103, 16, 4, 95, 49, 77, 49, 107, 6, 37, 61, 4, 122, 72, 139, 0, 102, 14, 4, 95, 49, 77, 49, 47, 6, 37, 89, 139, 78, 139, 0, 7, 65, 96, 37, 49, 89, 0, 0, 7, 195, 97, 0, 64, 9, 17, 16, 4, 95, 49, 77, 50, 65, 6, 37, 55, 37, 57, 111, 50, 0, 104, 15, 4, 95, 49, 77, 50, 65, 6, 37, 55, 37, 57, 139, 50, 0, 0, 7, 195, 4, 65, 0, 9, 17, 17, 4, 95, 49, 77, 51, 65, 37, 55, 37, 57, 137, 34, 72, 139, 0, 102, 16, 4, 95, 49, 77, 51, 65, 6, 37, 55, 37, 35, 51, 72, 139, 0, 0, 0, 11, 65, 100, 37, 48, 89, 37, 55, 39, 50, 0, 0, 7, 195, 4, 68, 0, 9, 17, 0, 6, 195, 72, 52, 192, 17, 7, 195, 20, 212, 192, 9, 17, 0, 0, 6, 65, 104, 88, 13, 0, 0, 6, 194, 9, 32, 24, 17, 0, 7, 195, 21, 84, 128, 9, 17, 0, 0, 6, 195, 9, 35, 0, 17, 0, 6, 195, 5, 68, 0, 17, 0, 15, 67, 16, 240, 216, 72, 6, 39, 117, 15, 6, 37, 49, 89, 0, 7, 195, 36, 101, 64, 9, 17, 0, 6, 195, 9, 38, 0, 17, 0, 0, 0, 0, 0, 0, 6, 195, 29, 36, 19, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 1, 126, 47, 6, 37, 55, 72, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 97, 128, 64, 9, 17, 6, 195, 73, 64, 64, 17, 0, 0, 0, 6, 194, 13, 32, 9, 17, 6, 194, 5, 96, 9, 17, 0, 0, 0, 0, 0, 7, 195, 97, 129, 64, 9, 17, 7, 195, 36, 97, 128, 9, 17, 7, 195, 13, 37, 0, 9, 17, 0, 0, 0, 0, 15, 67, 76, 148, 216, 89, 6, 37, 89, 15, 6, 37, 49, 89, 0, 7, 195, 97, 2, 64, 9, 17, 7, 195, 93, 34, 64, 9, 17, 6, 195, 73, 69, 12, 17, 7, 195, 60, 34, 128, 9, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 5, 117, 0, 9, 17, 0, 0, 0, 0, 6, 195, 92, 36, 128, 17, 0, 0, 0, 0, 7, 195, 76, 36, 128, 9, 17, 6, 195, 73, 52, 192, 17, 0, 0, 0, 6, 194, 17, 32, 24, 17, 0, 7, 195, 77, 148, 192, 9, 17, 0, 0, 0, 0, 7, 195, 81, 5, 64, 9, 17, 0, 0, 0, 0, 7, 195, 60, 38, 128, 9, 17, 0, 0, 0, 7, 195, 4, 148, 0, 9, 17, 0, 0, 0, 0, 6, 194, 21, 16, 9, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 36, 224, 192, 24, 7, 195, 72, 208, 64, 9, 17, 7, 195, 52, 112, 64, 9, 17, 0, 0, 0, 0, 7, 195, 16, 16, 64, 9, 17, 6, 195, 12, 48, 64, 17, 0, 0, 8, 132, 197, 161, 20, 1, 104, 76, 0, 8, 66, 21, 32, 36, 51, 0, 102, 0, 7, 195, 72, 209, 64, 9, 17, 7, 195, 52, 113, 64, 9, 17, 0, 0, 0, 0, 7, 132, 197, 161, 20, 15, 76, 6, 195, 73, 65, 128, 17, 7, 195, 37, 97, 128, 9, 17, 0, 0, 0, 0, 7, 195, 72, 210, 64, 9, 17, 7, 195, 52, 114, 64, 9, 17, 0, 7, 196, 56, 148, 212, 20, 76, 0, 0, 7, 195, 20, 52, 0, 9, 17, 0, 0, 15, 4, 95, 4, 16, 20, 9, 88, 6, 35, 16, 109, 88, 10, 0, 0, 0, 0, 7, 195, 96, 19, 64, 9, 17, 0, 6, 195, 56, 83, 65, 76, 0, 8, 197, 56, 83, 65, 52, 240, 76, 0, 0, 7, 195, 64, 131, 192, 9, 17, 6, 195, 32, 131, 192, 17, 6, 195, 4, 115, 64, 17, 0, 0, 0, 0, 7, 195, 48, 148, 64, 9, 17, 6, 195, 29, 36, 128, 17, 0, 13, 4, 95, 20, 12, 4, 47, 6, 37, 55, 72, 122, 0, 0, 0, 0, 6, 195, 72, 68, 192, 17, 7, 195, 5, 100, 128, 9, 17, 0, 0, 0, 6, 194, 25, 32, 9, 17, 0, 7, 195, 21, 65, 0, 9, 17, 0, 0, 0, 8, 133, 9, 13, 1, 197, 161, 76, 0, 6, 195, 73, 69, 128, 17, 7, 195, 25, 37, 0, 9, 17, 0, 6, 195, 25, 38, 0, 17, 0, 0, 0, 7, 195, 4, 209, 0, 9, 17, 0, 0, 6, 195, 29, 36, 146, 17, 0, 0, 0, 0, 0, 6, 194, 21, 80, 9, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 77, 48, 64, 9, 17, 0, 0, 0, 6, 194, 29, 32, 9, 17, 0, 7, 195, 72, 209, 128, 9, 17, 0, 0, 0, 6, 195, 29, 36, 0, 17, 0, 6, 195, 5, 97, 192, 17, 0, 7, 195, 29, 38, 0, 9, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 60, 52, 128, 9, 17, 7, 195, 29, 36, 192, 9, 17, 0, 0, 0, 0, 7, 195, 76, 52, 128, 9, 17, 0, 0, 18, 3, 226, 132, 162, 48, 140, 6, 39, 6, 37, 88, 84, 39, 75, 122, 76, 0, 0, 6, 194, 33, 32, 9, 17, 0, 0, 0, 8, 195, 33, 37, 0, 9, 17, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 17, 22, 64, 17, 0, 0, 0, 6, 194, 37, 16, 9, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 96, 32, 64, 9, 17, 7, 195, 24, 96, 64, 9, 17, 0, 0, 18, 3, 226, 128, 166, 47, 140, 6, 37, 15, 47, 6, 35, 76, 49, 36, 0, 104, 17, 3, 226, 128, 166, 47, 140, 6, 37, 15, 47, 6, 39, 76, 49, 36, 0, 0, 23, 3, 226, 128, 161, 72, 84, 6, 39, 89, 47, 51, 139, 49, 37, 15, 49, 51, 6, 89, 47, 0, 102, 22, 3, 226, 128, 161, 72, 84, 6, 39, 89, 47, 140, 139, 49, 37, 15, 49, 140, 6, 37, 90, 0, 0, 7, 195, 12, 64, 64, 9, 17, 7, 195, 5, 112, 128, 9, 17, 12, 3, 226, 128, 160, 49, 44, 6, 89, 47, 0, 102, 11, 3, 226, 128, 160, 49, 140, 6, 37, 90, 0, 0, 0, 21, 3, 226, 128, 162, 49, 140, 6, 40, 48, 50, 35, 15, 47, 6, 35, 76, 49, 122, 0, 104, 20, 3, 226, 128, 162, 49, 140, 6, 40, 48, 50, 35, 15, 47, 6, 39, 76, 49, 122, 0, 0, 6, 195, 57, 97, 1, 17, 0, 12, 3, 226, 130, 172, 6, 36, 84, 140, 39, 0, 104, 11, 3, 226, 130, 172, 6, 36, 40, 51, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 56, 83, 65, 80, 80, 76, 0, 0, 0, 0, 11, 3, 95, 50, 6, 72, 84, 6, 109, 0, 102, 12, 3, 95, 50, 6, 72, 84, 6, 37, 57, 36, 0, 0, 0, 7, 195, 37, 51, 0, 9, 17, 0, 0, 0, 7, 195, 37, 52, 0, 9, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 37, 65, 0, 24, 17, 0, 15, 4, 95, 13, 3, 14, 65, 6, 35, 49, 140, 16, 39, 50, 0, 0, 0, 0, 0, 0, 7, 195, 96, 149, 192, 9, 17, 0, 0, 0, 0, 7, 195, 20, 211, 0, 9, 17, 0, 7, 195, 20, 210, 0, 9, 17, 0, 0, 0, 6, 195, 97, 150, 128, 17, 13, 3, 226, 128, 176, 48, 140, 6, 39, 65, 37, 55, 0, 0, 6, 195, 56, 81, 207, 8, 7, 195, 16, 246, 0, 9, 17, 0, 0, 0, 0, 16, 6, 95, 18, 15, 13, 1, 14, 140, 6, 37, 65, 89, 49, 39, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 93, 64, 64, 17, 15, 3, 95, 51, 88, 47, 140, 6, 37, 72, 109, 89, 109, 47, 0, 0, 12, 3, 95, 48, 67, 89, 47, 6, 111, 10, 0, 102, 11, 3, 95, 48, 67, 89, 47, 6, 39, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 77, 65, 64, 72, 7, 195, 53, 1, 64, 9, 17, 0, 0, 0, 5, 194, 40, 80, 72, 18, 3, 95, 49, 57, 72, 6, 109, 84, 109, 47, 50, 35, 109, 89, 47, 0, 102, 16, 3, 95, 49, 57, 72, 6, 109, 84, 109, 47, 50, 130, 89, 47, 0, 0, 17, 3, 95, 49, 56, 6, 39, 89, 122, 65, 50, 35, 109, 89, 47, 0, 102, 15, 3, 95, 49, 56, 6, 39, 89, 122, 65, 50, 130, 89, 47, 0, 0, 16, 3, 95, 50, 67, 72, 84, 6, 36, 89, 47, 6, 35, 10, 0, 102, 15, 3, 95, 50, 67, 72, 84, 57, 6, 36, 89, 47, 6, 39, 0, 0, 0, 0, 0, 0, 0, 17, 3, 95, 49, 49, 57, 6, 36, 72, 122, 50, 35, 109, 89, 47, 0, 102, 15, 3, 95, 49, 49, 57, 6, 36, 72, 122, 50, 130, 89, 47, 0, 0, 7, 195, 61, 67, 64, 9, 17, 7, 195, 5, 3, 64, 9, 17, 12, 3, 95, 49, 48, 72, 6, 109, 89, 109, 47, 0, 0, 16, 3, 95, 51, 67, 47, 51, 6, 37, 89, 47, 6, 35, 10, 0, 102, 16, 3, 95, 49, 51, 47, 140, 6, 37, 50, 35, 109, 89, 47, 0, 102, 14, 3, 95, 49, 51, 47, 140, 6, 37, 50, 130, 89, 47, 0, 0, 16, 3, 95, 49, 50, 72, 84, 6, 35, 50, 35, 109, 89, 47, 0, 102, 14, 3, 95, 49, 50, 72, 84, 6, 35, 50, 130, 89, 47, 0, 0, 16, 3, 95, 49, 53, 48, 6, 109, 47, 50, 35, 109, 89, 47, 0, 102, 14, 3, 95, 49, 53, 48, 6, 109, 47, 50, 130, 89, 47, 0, 0, 17, 3, 95, 49, 52, 76, 6, 109, 47, 44, 50, 35, 109, 89, 47, 0, 102, 15, 3, 95, 49, 52, 76, 6, 109, 47, 44, 50, 130, 89, 47, 0, 0, 18, 3, 95, 49, 55, 89, 6, 109, 72, 122, 65, 50, 35, 109, 89, 47, 0, 102, 16, 3, 95, 49, 55, 89, 6, 109, 72, 122, 65, 50, 130, 89, 47, 0, 0, 16, 3, 95, 49, 54, 91, 6, 109, 89, 50, 35, 109, 89, 47, 0, 102, 14, 3, 95, 49, 54, 91, 6, 109, 89, 50, 130, 89, 47, 0, 0, 0, 7, 195, 61, 52, 192, 9, 17, 6, 195, 12, 196, 128, 17, 17, 3, 95, 55, 88, 89, 6, 109, 72, 122, 65, 72, 109, 89, 109, 47, 0, 0, 18, 3, 95, 52, 67, 76, 36, 47, 51, 6, 37, 89, 47, 6, 39, 10, 0, 102, 0, 0, 0, 6, 195, 12, 68, 128, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 12, 68, 151, 17, 13, 3, 95, 54, 67, 91, 6, 109, 89, 47, 6, 39, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 50, 88, 72, 84, 6, 35, 72, 109, 89, 109, 47, 0, 0, 16, 5, 95, 48, 77, 65, 49, 107, 6, 37, 61, 35, 72, 36, 0, 103, 17, 5, 95, 48, 77, 65, 49, 107, 6, 37, 61, 4, 122, 72, 36, 0, 102, 15, 5, 95, 48, 77, 65, 49, 47, 6, 37, 89, 139, 78, 36, 0, 0, 0, 18, 5, 95, 48, 77, 65, 51, 65, 37, 55, 37, 57, 137, 34, 72, 36, 0, 102, 17, 5, 95, 48, 77, 65, 51, 65, 6, 37, 55, 37, 35, 51, 72, 36, 0, 0, 18, 5, 95, 48, 77, 65, 50, 65, 6, 37, 55, 37, 57, 111, 50, 35, 0, 104, 17, 5, 95, 48, 77, 65, 50, 65, 6, 37, 55, 37, 57, 139, 50, 35, 0, 0, 0, 0, 0, 6, 195, 88, 112, 64, 17, 6, 195, 4, 16, 64, 17, 0, 0, 0, 0, 7, 195, 92, 208, 64, 9, 17, 0, 10, 3, 95, 63, 63, 88, 50, 35, 49, 0, 0, 0, 6, 194, 53, 32, 24, 17, 0, 7, 195, 65, 33, 128, 9, 17, 7, 195, 61, 65, 128, 9, 17, 16, 3, 95, 52, 88, 76, 6, 109, 47, 44, 72, 109, 89, 109, 47, 0, 0, 0, 0, 0, 7, 195, 21, 1, 128, 9, 17, 0, 0, 0, 0, 7, 195, 72, 226, 192, 9, 17, 7, 195, 5, 2, 128, 9, 17, 14, 3, 95, 53, 88, 48, 6, 109, 72, 109, 89, 109, 47, 0, 0, 0, 0, 0, 7, 195, 4, 130, 192, 9, 17, 0, 0, 0, 0, 6, 195, 65, 35, 128, 17, 6, 195, 60, 83, 64, 17, 7, 195, 56, 99, 192, 9, 17, 15, 3, 95, 54, 88, 91, 6, 109, 88, 72, 109, 89, 109, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 69, 4, 128, 17, 0, 0, 0, 0, 8, 195, 77, 68, 128, 9, 24, 17, 7, 195, 53, 4, 128, 9, 17, 7, 195, 52, 20, 64, 9, 17, 0, 0, 0, 6, 194, 57, 32, 9, 17, 0, 13, 67, 13, 68, 140, 117, 39, 50, 47, 51, 125, 55, 0, 6, 195, 81, 165, 128, 24, 7, 195, 33, 37, 128, 9, 17, 6, 195, 13, 68, 140, 17, 16, 3, 95, 56, 88, 6, 39, 89, 122, 65, 72, 109, 89, 109, 47, 0, 0, 7, 195, 57, 34, 0, 9, 17, 0, 9, 134, 14, 5, 13, 1, 197, 161, 76, 0, 0, 0, 0, 0, 0, 7, 195, 36, 211, 0, 9, 17, 16, 3, 95, 57, 88, 72, 6, 109, 84, 109, 72, 109, 89, 109, 47, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 63, 65, 89, 55, 39, 84, 39, 0, 0, 0, 0, 0, 7, 195, 53, 84, 0, 17, 41, 0, 0, 0, 0, 0, 0, 7, 195, 60, 33, 0, 9, 17, 7, 195, 21, 128, 192, 9, 17, 0, 0, 0, 0, 6, 195, 72, 112, 128, 17, 7, 195, 60, 37, 0, 9, 17, 14, 4, 95, 15, 7, 15, 6, 39, 81, 39, 50, 109, 49, 0, 0, 13, 68, 77, 64, 82, 80, 89, 47, 6, 35, 51, 47, 0, 0, 0, 6, 195, 33, 166, 143, 17, 0, 7, 195, 84, 145, 128, 9, 17, 7, 195, 65, 33, 192, 9, 17, 0, 0, 0, 0, 7, 195, 4, 145, 128, 9, 17, 0, 0, 0, 5, 194, 48, 144, 72, 0, 7, 195, 97, 50, 64, 9, 17, 7, 195, 33, 34, 192, 9, 17, 7, 195, 29, 82, 64, 9, 17, 0, 7, 195, 60, 54, 0, 9, 17, 0, 0, 0, 0, 0, 0, 7, 194, 61, 48, 9, 17, 41, 0, 0, 17, 4, 95, 48, 77, 52, 71, 6, 37, 55, 37, 57, 111, 50, 35, 0, 104, 16, 4, 95, 48, 77, 52, 71, 6, 37, 55, 37, 57, 139, 50, 35, 0, 0, 6, 195, 65, 35, 198, 24, 0, 17, 4, 95, 48, 77, 50, 65, 6, 37, 55, 37, 57, 111, 50, 35, 0, 104, 16, 4, 95, 48, 77, 50, 65, 6, 37, 55, 37, 57, 139, 50, 35, 0, 0, 17, 4, 95, 48, 77, 51, 65, 37, 55, 37, 57, 137, 34, 72, 138, 0, 102, 16, 4, 95, 48, 77, 51, 65, 6, 37, 55, 37, 35, 51, 72, 138, 0, 0, 0, 15, 4, 95, 48, 77, 49, 107, 6, 37, 61, 35, 72, 122, 0, 103, 16, 4, 95, 48, 77, 49, 107, 6, 37, 61, 4, 122, 72, 122, 0, 102, 14, 4, 95, 48, 77, 49, 47, 6, 37, 89, 139, 78, 122, 0, 0, 13, 4, 95, 2, 18, 22, 71, 140, 16, 6, 109, 84, 0, 7, 66, 48, 160, 61, 13, 0, 0, 0, 0, 0, 0, 7, 195, 20, 20, 128, 9, 17, 0, 0, 0, 6, 194, 65, 32, 9, 17, 0, 0, 0, 0, 0, 7, 195, 65, 37, 0, 9, 17, 0, 0, 0, 0, 7, 195, 37, 22, 64, 9, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 64, 64, 64, 17, 6, 195, 4, 16, 192, 17, 0, 7, 195, 60, 102, 0, 9, 17, 0, 0, 0, 7, 195, 96, 192, 64, 9, 17, 7, 195, 60, 101, 0, 9, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 60, 115, 0, 9, 17, 0, 8, 66, 72, 16, 51, 122, 0, 102, 0, 7, 195, 64, 66, 64, 9, 17, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 76, 211, 192, 72, 6, 195, 80, 179, 192, 76, 6, 195, 36, 35, 64, 17, 0, 0, 0, 19, 4, 95, 3, 9, 18, 117, 6, 37, 51, 49, 139, 65, 83, 55, 109, 49, 89, 0, 0, 7, 195, 64, 179, 192, 9, 17, 0, 0, 0, 5, 194, 72, 32, 17, 7, 66, 56, 160, 67, 13, 0, 0, 0, 0, 6, 131, 95, 195, 186, 43, 0, 0, 7, 195, 17, 52, 128, 9, 17, 0, 0, 0, 0, 13, 4, 95, 19, 20, 11, 49, 140, 16, 6, 39, 88, 0, 0, 26, 3, 95, 194, 173, 48, 140, 6, 37, 84, 140, 36, 65, 36, 50, 122, 15, 117, 6, 44, 47, 6, 37, 117, 122, 0, 0, 12, 4, 95, 1, 3, 21, 6, 35, 49, 139, 47, 0, 0, 25, 3, 95, 194, 171, 6, 39, 47, 84, 39, 51, 36, 50, 37, 15, 50, 6, 35, 84, 39, 72, 50, 138, 49, 0, 6, 131, 95, 195, 179, 43, 0, 15, 67, 52, 16, 216, 65, 6, 35, 117, 15, 6, 37, 49, 89, 0, 6, 195, 60, 213, 192, 17, 7, 195, 52, 21, 192, 9, 17, 0, 0, 0, 6, 194, 72, 48, 9, 17, 0, 6, 195, 72, 49, 0, 17, 0, 6, 131, 95, 195, 173, 43, 0, 0, 0, 13, 4, 95, 18, 14, 7, 140, 16, 6, 37, 68, 81, 0, 0, 6, 131, 95, 195, 169, 43, 0, 0, 5, 194, 73, 48, 17, 0, 7, 195, 104, 243, 192, 9, 17, 0, 0, 0, 8, 133, 196, 141, 5, 7, 1, 8, 0, 0, 6, 131, 95, 195, 161, 43, 0, 0, 6, 194, 72, 64, 9, 17, 0, 7, 195, 33, 64, 64, 9, 17, 0, 0, 0, 0, 0, 0, 6, 195, 73, 67, 0, 17, 0, 6, 194, 77, 32, 9, 17, 0, 7, 195, 77, 33, 0, 9, 17, 7, 195, 60, 97, 128, 9, 17, 0, 0, 0, 13, 67, 41, 1, 71, 57, 136, 15, 48, 6, 36, 81, 0, 24, 4, 95, 1, 3, 50, 72, 84, 6, 39, 89, 47, 140, 16, 139, 49, 138, 38, 6, 35, 49, 139, 47, 0, 0, 0, 0, 0, 8, 66, 72, 80, 51, 36, 0, 102, 0, 7, 195, 41, 2, 64, 9, 17, 7, 195, 20, 49, 12, 9, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 3, 95, 194, 187, 88, 6, 35, 47, 84, 39, 51, 36, 50, 37, 15, 50, 6, 35, 84, 39, 72, 50, 138, 49, 0, 0, 7, 195, 73, 115, 192, 9, 17, 0, 6, 195, 8, 147, 1, 72, 0, 7, 2, 196, 135, 78, 136, 0, 0, 6, 195, 8, 147, 15, 72, 0, 6, 195, 68, 36, 128, 17, 0, 0, 0, 0, 0, 6, 195, 8, 147, 9, 72, 0, 10, 2, 195, 151, 48, 6, 40, 47, 122, 0, 0, 0, 7, 2, 196, 141, 76, 13, 0, 0, 20, 2, 197, 130, 55, 13, 15, 89, 122, 15, 117, 6, 44, 47, 6, 37, 117, 39, 65, 0, 0, 0, 0, 0, 0, 13, 2, 194, 167, 6, 39, 72, 55, 39, 65, 122, 49, 0, 0, 12, 2, 194, 164, 84, 6, 35, 55, 40, 47, 122, 0, 0, 0, 7, 196, 36, 208, 84, 20, 76, 0, 0, 0, 7, 2, 196, 145, 77, 136, 0, 0, 18, 2, 194, 174, 51, 6, 36, 81, 37, 89, 47, 140, 35, 117, 138, 57, 122, 0, 0, 0, 5, 194, 77, 80, 72, 5, 194, 73, 112, 17, 0, 0, 0, 0, 14, 2, 194, 168, 48, 140, 6, 36, 81, 55, 122, 89, 0, 102, 15, 2, 194, 168, 48, 140, 6, 37, 57, 36, 81, 55, 122, 89, 0, 0, 19, 2, 194, 169, 6, 127, 47, 39, 51, 89, 49, 122, 15, 48, 140, 35, 84, 122, 0, 0, 12, 2, 194, 182, 76, 55, 6, 35, 50, 122, 49, 0, 0, 10, 2, 194, 183, 48, 6, 40, 47, 122, 0, 0, 6, 194, 72, 128, 9, 17, 0, 7, 195, 104, 16, 64, 9, 17, 6, 195, 4, 32, 192, 17, 11, 2, 194, 181, 65, 6, 37, 49, 140, 39, 0, 0, 0, 6, 195, 37, 49, 14, 17, 0, 13, 2, 194, 176, 89, 47, 6, 36, 48, 36, 50, 0, 104, 12, 2, 194, 176, 89, 47, 6, 40, 48, 122, 67, 0, 0, 7, 195, 64, 208, 64, 9, 17, 0, 0, 7, 195, 85, 35, 0, 9, 17, 16, 2, 195, 183, 48, 6, 39, 72, 36, 61, 4, 36, 50, 39, 0, 102, 17, 2, 195, 183, 48, 6, 39, 72, 37, 57, 36, 61, 4, 36, 50, 39, 0, 0, 5, 194, 73, 128, 17, 0, 0, 14, 4, 95, 3, 5, 4, 117, 6, 109, 72, 138, 55, 122, 0, 0, 0, 12, 2, 194, 184, 89, 36, 72, 6, 37, 55, 122, 0, 0, 17, 4, 95, 12, 9, 7, 55, 6, 37, 81, 122, 47, 4, 139, 51, 122, 0, 7, 2, 197, 161, 91, 13, 0, 0, 0, 0, 0, 7, 195, 5, 34, 128, 9, 17, 7, 195, 4, 34, 192, 9, 17, 0, 0, 0, 0, 6, 195, 12, 114, 64, 17, 0, 0, 0, 0, 7, 195, 85, 49, 0, 9, 17, 7, 195, 36, 51, 64, 9, 17, 7, 195, 4, 51, 64, 9, 17, 0, 0, 0, 0, 0, 7, 2, 197, 190, 90, 13, 0, 0, 7, 195, 84, 67, 0, 9, 17, 0, 0, 6, 195, 4, 36, 192, 17, 0, 0, 0, 0, 7, 195, 57, 4, 128, 24, 17, 6, 195, 84, 69, 0, 17, 6, 195, 24, 20, 64, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 76, 144, 72, 6, 194, 72, 176, 9, 17, 0, 0, 7, 195, 92, 22, 0, 9, 17, 0, 0, 12, 2, 203, 152, 71, 140, 6, 36, 84, 37, 89, 0, 0, 0, 0, 0, 6, 194, 85, 80, 9, 17, 0, 0, 7, 196, 56, 83, 65, 52, 76, 0, 0, 7, 195, 85, 84, 0, 9, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 95, 19, 89, 13, 0, 0, 0, 0, 0, 7, 195, 5, 33, 192, 9, 17, 7, 195, 4, 49, 128, 9, 17, 0, 0, 0, 0, 0, 0, 0, 6, 194, 72, 208, 9, 17, 0, 0, 7, 196, 36, 208, 77, 60, 76, 6, 195, 72, 214, 0, 17, 0, 7, 195, 72, 213, 0, 9, 17, 0, 6, 195, 56, 146, 133, 76, 6, 195, 4, 49, 141, 17, 0, 7, 195, 53, 50, 64, 9, 17, 0, 12, 2, 95, 34, 50, 6, 35, 84, 39, 72, 0, 102, 14, 2, 95, 34, 50, 6, 35, 84, 39, 72, 50, 138, 49, 0, 0, 0, 0, 7, 195, 5, 51, 64, 9, 17, 14, 2, 95, 39, 6, 35, 48, 39, 89, 47, 140, 39, 83, 0, 0, 19, 2, 95, 38, 47, 6, 44, 81, 6, 39, 84, 122, 76, 49, 39, 15, 6, 37, 0, 0, 0, 11, 2, 95, 36, 72, 6, 39, 55, 122, 51, 0, 0, 0, 6, 195, 84, 130, 0, 17, 15, 2, 95, 42, 88, 84, 6, 36, 88, 72, 37, 117, 122, 0, 102, 15, 2, 95, 42, 88, 84, 57, 6, 36, 88, 72, 37, 117, 122, 0, 15, 4, 95, 3, 1, 16, 49, 6, 35, 48, 138, 47, 122, 55, 0, 0, 24, 2, 95, 41, 88, 6, 35, 47, 84, 39, 51, 36, 50, 122, 15, 88, 6, 35, 81, 140, 35, 72, 122, 0, 0, 5, 194, 80, 160, 24, 5, 194, 76, 192, 24, 6, 194, 72, 224, 9, 17, 23, 2, 95, 40, 6, 39, 47, 84, 39, 51, 36, 50, 122, 15, 88, 6, 35, 81, 140, 35, 72, 122, 0, 0, 0, 7, 196, 36, 208, 74, 84, 76, 12, 2, 95, 46, 47, 6, 35, 76, 49, 122, 0, 104, 11, 2, 95, 46, 47, 6, 39, 76, 49, 122, 0, 0, 13, 2, 95, 45, 117, 6, 44, 47, 6, 37, 117, 122, 0, 11, 2, 95, 45, 65, 6, 37, 50, 40, 89, 0, 0, 13, 2, 95, 44, 88, 6, 35, 48, 36, 47, 35, 0, 102, 11, 2, 95, 44, 88, 6, 35, 51, 36, 88, 0, 0, 7, 195, 53, 36, 192, 24, 17, 9, 2, 95, 51, 47, 140, 6, 37, 0, 0, 9, 2, 95, 50, 72, 84, 6, 35, 0, 0, 7, 195, 85, 129, 0, 9, 17, 11, 2, 95, 49, 57, 6, 36, 72, 122, 50, 0, 0, 10, 2, 95, 48, 50, 6, 40, 55, 122, 0, 0, 11, 2, 95, 55, 89, 6, 109, 72, 122, 65, 0, 0, 10, 2, 95, 54, 91, 6, 109, 89, 47, 0, 0, 9, 2, 95, 53, 48, 6, 109, 47, 0, 0, 12, 2, 95, 52, 76, 6, 109, 47, 138, 51, 138, 0, 0, 18, 2, 95, 59, 47, 6, 35, 76, 49, 122, 88, 4, 35, 16, 109, 88, 0, 103, 19, 2, 95, 59, 47, 6, 35, 76, 49, 122, 88, 4, 35, 48, 36, 47, 35, 0, 102, 17, 2, 95, 59, 47, 6, 39, 76, 49, 122, 88, 4, 35, 16, 109, 88, 0, 0, 0, 11, 2, 95, 57, 72, 6, 109, 84, 109, 47, 0, 0, 10, 2, 95, 56, 6, 39, 89, 122, 65, 0, 0, 7, 195, 73, 22, 64, 9, 17, 13, 2, 95, 63, 6, 40, 48, 37, 47, 50, 138, 49, 0, 0, 14, 2, 95, 62, 84, 6, 36, 76, 37, 15, 6, 39, 72, 0, 0, 13, 2, 95, 61, 57, 6, 36, 72, 50, 122, 49, 39, 0, 13, 2, 95, 61, 57, 6, 36, 72, 50, 122, 49, 39, 0, 0, 7, 195, 84, 148, 0, 9, 17, 14, 2, 95, 60, 65, 6, 35, 67, 37, 15, 6, 39, 72, 0, 0, 0, 0, 0, 8, 2, 95, 64, 36, 47, 0, 102, 19, 2, 95, 64, 47, 6, 44, 81, 6, 39, 84, 122, 76, 49, 39, 15, 6, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 72, 32, 64, 17, 7, 195, 60, 112, 192, 9, 17, 7, 195, 36, 48, 192, 9, 17, 7, 195, 4, 48, 192, 9, 17, 0, 0, 0, 0, 7, 195, 88, 32, 64, 9, 17, 7, 195, 52, 64, 64, 9, 17, 0, 0, 0, 6, 195, 44, 241, 193, 8, 26, 4, 95, 226, 128, 154, 6, 39, 47, 84, 39, 51, 36, 50, 37, 15, 50, 6, 35, 84, 39, 72, 50, 138, 49, 0, 0, 7, 195, 60, 113, 192, 9, 17, 7, 195, 5, 49, 128, 9, 17, 7, 195, 4, 49, 192, 9, 17, 30, 4, 95, 226, 128, 153, 57, 6, 36, 72, 50, 39, 89, 47, 140, 6, 40, 49, 37, 15, 50, 6, 35, 84, 39, 72, 50, 138, 49, 0, 0, 26, 4, 95, 226, 128, 152, 6, 39, 47, 84, 39, 51, 36, 50, 37, 15, 50, 6, 35, 84, 39, 72, 50, 138, 49, 0, 13, 4, 95, 4, 15, 20, 47, 6, 39, 76, 49, 122, 0, 0, 0, 27, 4, 95, 226, 128, 158, 88, 122, 47, 84, 39, 51, 36, 50, 37, 15, 50, 6, 35, 84, 39, 72, 50, 138, 49, 0, 102, 26, 4, 95, 226, 128, 158, 89, 48, 6, 40, 91, 47, 36, 50, 37, 15, 50, 6, 35, 84, 39, 72, 50, 138, 49, 0, 0, 7, 195, 88, 33, 64, 9, 17, 7, 195, 52, 65, 64, 9, 17, 24, 2, 95, 91, 6, 39, 47, 84, 39, 51, 36, 50, 122, 15, 6, 40, 81, 55, 122, 89, 47, 122, 0, 102, 22, 2, 95, 91, 6, 39, 47, 84, 39, 51, 36, 50, 122, 15, 6, 40, 81, 55, 122, 47, 122, 0, 27, 4, 95, 226, 128, 157, 88, 6, 35, 47, 84, 39, 51, 36, 50, 37, 15, 50, 6, 35, 84, 39, 72, 50, 138, 49, 0, 0, 26, 4, 95, 226, 128, 156, 6, 39, 47, 84, 39, 51, 36, 50, 37, 15, 50, 6, 35, 84, 39, 72, 50, 138, 49, 0, 0, 15, 4, 95, 226, 128, 147, 109, 50, 15, 117, 6, 44, 47, 122, 0, 0, 0, 7, 195, 56, 162, 64, 9, 17, 10, 2, 95, 95, 117, 6, 44, 47, 122, 0, 0, 0, 25, 2, 95, 93, 88, 6, 35, 47, 84, 39, 51, 36, 50, 122, 15, 6, 40, 81, 55, 122, 89, 47, 122, 0, 102, 23, 2, 95, 93, 88, 6, 35, 47, 84, 39, 51, 36, 50, 122, 15, 6, 40, 81, 55, 122, 47, 122, 0, 0, 6, 195, 4, 49, 205, 17, 0, 7, 195, 36, 194, 64, 72, 8, 6, 195, 4, 194, 64, 8, 7, 195, 52, 66, 64, 9, 17, 6, 195, 24, 34, 64, 17, 0, 15, 4, 95, 226, 128, 148, 109, 65, 15, 117, 6, 44, 47, 122, 0, 0, 0, 12, 2, 95, 96, 81, 140, 6, 35, 84, 37, 89, 0, 0, 7, 195, 36, 67, 64, 9, 17, 7, 195, 20, 195, 64, 9, 17, 7, 195, 5, 51, 128, 9, 17, 0, 0, 0, 0, 6, 195, 8, 147, 192, 72, 7, 195, 4, 195, 64, 9, 17, 0, 7, 196, 56, 148, 193, 52, 76, 0, 0, 16, 4, 95, 7, 18, 22, 50, 6, 35, 81, 55, 122, 89, 122, 49, 0, 0, 7, 195, 36, 52, 192, 9, 17, 0, 0, 0, 0, 7, 195, 85, 52, 128, 9, 17, 7, 195, 20, 52, 192, 9, 17, 0, 0, 0, 6, 195, 56, 148, 201, 76, 0, 7, 195, 72, 21, 192, 9, 17, 7, 195, 4, 53, 192, 9, 17, 26, 4, 95, 226, 128, 185, 6, 39, 47, 84, 39, 51, 36, 50, 37, 15, 50, 6, 35, 84, 39, 72, 50, 138, 49, 0, 0, 0, 0, 0, 25, 2, 95, 123, 6, 39, 47, 84, 39, 51, 36, 50, 122, 15, 84, 6, 37, 47, 37, 76, 122, 89, 47, 122, 0, 14, 4, 95, 4, 9, 1, 6, 40, 65, 55, 122, 139, 47, 0, 0, 0, 0, 0, 0, 0, 26, 2, 95, 125, 88, 6, 35, 47, 84, 39, 51, 36, 50, 122, 15, 84, 6, 37, 47, 37, 76, 122, 89, 47, 122, 0, 0, 15, 2, 95, 124, 6, 40, 89, 48, 51, 122, 84, 50, 122, 0, 102, 13, 2, 95, 124, 6, 39, 49, 39, 65, 37, 117, 122, 0, 0, 0, 0, 0, 6, 194, 101, 80, 9, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 36, 64, 128, 9, 17, 7, 195, 5, 48, 192, 9, 17, 0, 0, 0, 0, 7, 195, 57, 32, 64, 9, 17, 7, 195, 21, 48, 192, 9, 17, 0, 0, 0, 0, 7, 195, 13, 1, 64, 9, 17, 0, 0, 0, 0, 7, 195, 84, 65, 128, 9, 17, 7, 195, 57, 33, 64, 9, 17, 0, 0, 0, 0, 0, 0, 0, 6, 195, 56, 148, 213, 76, 0, 7, 195, 57, 34, 64, 9, 17, 0, 0, 0, 5, 194, 97, 144, 17, 0, 7, 195, 4, 67, 128, 9, 17, 0, 21, 5, 95, 49, 77, 65, 49, 57, 36, 72, 50, 122, 15, 107, 37, 61, 122, 72, 122, 0, 102, 0, 0, 0, 7, 195, 57, 35, 64, 9, 17, 6, 195, 25, 35, 64, 17, 0, 0, 0, 0, 7, 195, 37, 52, 192, 9, 17, 0, 0, 0, 0, 6, 195, 88, 36, 128, 17, 7, 195, 85, 52, 192, 9, 17, 7, 195, 57, 36, 64, 9, 17, 0, 0, 0, 0, 7, 195, 13, 5, 64, 9, 17, 0, 0, 0, 0, 7, 195, 57, 37, 64, 9, 17, 0, 0, 0, 0, 0, 0, 0, 16, 70, 12, 243, 148, 72, 243, 0, 117, 39, 50, 47, 51, 125, 55, 0, 0, 0, 7, 196, 56, 148, 205, 60, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 36, 64, 192, 9, 17, 0, 0, 0, 0, 15, 67, 64, 245, 24, 48, 6, 39, 47, 15, 6, 37, 49, 89, 0, 6, 195, 36, 208, 64, 76, 7, 195, 57, 32, 128, 9, 17, 0, 0, 0, 0, 6, 195, 9, 33, 128, 17, 7, 195, 5, 65, 128, 9, 17, 0, 0, 0, 0, 13, 67, 85, 65, 128, 40, 15, 47, 36, 15, 36, 83, 0, 7, 195, 57, 33, 128, 9, 17, 7, 195, 4, 193, 192, 9, 17, 0, 0, 0, 0, 7, 195, 64, 114, 64, 9, 17, 0, 0, 0, 0, 7, 195, 36, 194, 192, 9, 17, 0, 0, 0, 6, 195, 36, 208, 77, 76, 0, 6, 195, 76, 19, 64, 72, 7, 195, 28, 131, 192, 9, 17, 0, 0, 0, 0, 0, 0, 8, 3, 4, 197, 190, 75, 13, 0, 0, 0, 6, 195, 41, 36, 128, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 4, 68, 204, 17, 0, 0, 0, 0, 7, 195, 37, 70, 128, 9, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 196, 135, 0, 3, 78, 0, 7, 6, 196, 141, 0, 3, 76, 0, 7, 6, 196, 145, 0, 3, 77, 0, 7, 6, 197, 161, 0, 3, 91, 0, 7, 6, 197, 190, 0, 3, 90, 0, 7, 6, 97, 0, 3, 35, 0, 4, 2, 106, 3, 137, 0, 2, 114, 0, 7, 6, 98, 0, 3, 71, 0, 7, 6, 99, 0, 3, 117, 0, 7, 6, 100, 0, 3, 72, 0, 197, 190, 3, 75, 0, 122, 3, 118, 0, 7, 6, 101, 0, 120, 101, 5, 2, 8, 3, 2, 36, 37, 49, 89, 36, 0, 120, 101, 8, 3, 2, 36, 49, 89, 36, 0, 4, 1, 106, 3, 36, 0, 2, 106, 0, 3, 109, 0, 7, 6, 102, 0, 3, 83, 0, 7, 6, 103, 0, 3, 81, 0, 7, 6, 104, 0, 8, 3, 101, 0, 3, 107, 0, 7, 6, 105, 0, 110, 105, 1, 32, 46, 3, 2, 37, 50, 37, 0, 3, 37, 0, 7, 6, 106, 0, 3, 57, 0, 1, 17, 65, 29, 2, 32, 3, 57, 10, 0, 7, 6, 107, 0, 3, 49, 0, 7, 6, 108, 0, 1, 25, 2, 25, 3, 45, 0, 3, 55, 0, 106, 1, 118, 3, 55, 57, 0, 106, 2, 12, 3, 61, 0, 7, 6, 109, 0, 3, 65, 0, 7, 6, 110, 0, 3, 50, 0, 106, 3, 67, 0, 4, 2, 103, 3, 68, 0, 2, 107, 0, 7, 6, 111, 0, 3, 39, 0, 117, 3, 129, 0, 7, 6, 112, 0, 3, 48, 0, 7, 6, 113, 0, 3, 49, 0, 117, 5, 2, 3, 49, 40, 0, 117, 3, 49, 84, 0, 7, 6, 114, 0, 4, 3, 51, 0, 1, 17, 65, 2, 17, 65, 0, 2, 32, 0, 114, 0, 1, 25, 2, 25, 3, 52, 0, 1, 25, 2, 17, 65, 3, 140, 0, 7, 6, 115, 0, 3, 89, 0, 7, 6, 116, 0, 3, 47, 0, 7, 6, 117, 0, 3, 40, 0, 7, 6, 118, 0, 3, 84, 0, 7, 6, 119, 0, 3, 84, 0, 7, 6, 120, 0, 3, 49, 89, 0, 7, 6, 121, 0, 1, 25, 2, 25, 3, 37, 0, 3, 57, 0, 7, 6, 122, 0, 3, 88, 0, 7, 6, 206, 0, 177, 3, 6, 35, 55, 83, 122, 0, 172, 3, 6, 35, 55, 83, 122, 15, 47, 6, 39, 50, 39, 89, 0, 183, 3, 6, 36, 47, 122, 0, 174, 3, 6, 36, 47, 122, 15, 47, 6, 39, 50, 39, 89, 0, 181, 3, 6, 36, 48, 89, 138, 55, 39, 50, 0, 173, 3, 6, 36, 48, 89, 138, 55, 39, 50, 15, 47, 6, 39, 50, 39, 89, 0, 191, 3, 6, 39, 65, 138, 49, 140, 39, 50, 10, 0, 184, 3, 47, 101, 6, 36, 47, 122, 0, 186, 3, 49, 6, 35, 48, 122, 0, 190, 3, 49, 89, 6, 37, 0, 189, 3, 50, 6, 37, 0, 187, 3, 55, 6, 35, 65, 72, 122, 0, 185, 3, 57, 6, 39, 47, 122, 0, 175, 3, 57, 6, 39, 47, 122, 15, 47, 6, 39, 50, 39, 89, 0, 188, 3, 65, 6, 37, 0, 178, 3, 71, 6, 36, 47, 122, 0, 180, 3, 72, 6, 36, 55, 47, 122, 0, 179, 3, 81, 6, 35, 65, 122, 0, 182, 3, 88, 6, 36, 47, 122, 0, 7, 6, 207, 0, 137, 3, 6, 39, 65, 36, 81, 122, 0, 142, 3, 6, 39, 65, 36, 81, 122, 15, 47, 6, 39, 50, 39, 89, 0, 140, 3, 6, 39, 65, 138, 49, 140, 39, 50, 15, 47, 6, 39, 50, 39, 89, 0, 132, 3, 47, 6, 35, 40, 0, 128, 3, 48, 6, 37, 0, 136, 3, 48, 89, 6, 37, 0, 129, 3, 51, 6, 39, 0, 141, 3, 81, 44, 76, 49, 37, 15, 6, 37, 48, 89, 138, 55, 39, 50, 15, 47, 6, 39, 50, 39, 89, 0, 133, 3, 81, 44, 76, 49, 37, 23, 6, 37, 48, 89, 138, 55, 39, 50, 0, 130, 3, 81, 44, 76, 49, 39, 23, 88, 6, 35, 84, 44, 91, 50, 39, 23, 89, 6, 37, 81, 65, 122, 0, 134, 3, 83, 6, 37, 0, 131, 3, 89, 6, 37, 81, 65, 122, 0, 135, 3, 101, 6, 37, 0, 7, 6, 0, 4, 45, 1, 32, 17, 65, 2, 32, 15, 3, 10, 0, 45, 1, 32, 17, 67, 2, 32, 15, 0, 4, 195, 159, 3, 21, 100, 101, 0, 195, 164, 0, 195, 182, 0, 195, 188, 0, 45, 8, 32, 2, 32, 15, 3, 65, 37, 50, 40, 89, 0, 36, 3, 72, 6, 39, 55, 122, 51, 0, 195, 173, 3, 121, 0, 195, 169, 3, 123, 0, 195, 161, 3, 124, 0, 195, 179, 3, 125, 0, 195, 186, 3, 126, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts22 = FileInMemory_createWithData (7359, reinterpret_cast (&espeakdata_dicts22_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/hbs_dict", U"hbs"); Collection_addItem (me.peek(), espeakdata_dicts22.transfer()); static unsigned char espeakdata_dicts23_data[5724] = { 0, 4, 0, 0, 152, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 224, 164, 149, 224, 165, 128, 72, 0, 15, 140, 224, 164, 134, 224, 164, 170, 224, 164, 149, 224, 165, 139, 72, 0, 0, 12, 137, 224, 164, 176, 224, 164, 185, 224, 165, 128, 72, 9, 134, 224, 164, 175, 224, 165, 135, 72, 9, 134, 224, 164, 175, 224, 165, 135, 72, 0, 0, 0, 15, 140, 224, 164, 137, 224, 164, 168, 224, 164, 149, 224, 165, 128, 72, 15, 140, 224, 164, 137, 224, 164, 184, 224, 164, 149, 224, 165, 128, 72, 15, 140, 224, 164, 134, 224, 164, 170, 224, 164, 149, 224, 165, 128, 72, 0, 9, 134, 224, 164, 149, 224, 165, 135, 72, 9, 134, 224, 164, 181, 224, 165, 135, 72, 0, 0, 0, 12, 137, 224, 164, 176, 224, 164, 185, 224, 165, 135, 72, 0, 9, 134, 224, 164, 149, 224, 165, 139, 72, 9, 134, 224, 164, 181, 224, 165, 139, 72, 9, 134, 224, 164, 181, 224, 165, 139, 72, 0, 0, 15, 140, 224, 164, 137, 224, 164, 168, 224, 164, 149, 224, 165, 135, 72, 15, 140, 224, 164, 137, 224, 164, 184, 224, 164, 149, 224, 165, 135, 72, 15, 140, 224, 164, 134, 224, 164, 170, 224, 164, 149, 224, 165, 135, 72, 15, 140, 224, 164, 174, 224, 165, 129, 224, 164, 157, 224, 165, 135, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 224, 164, 185, 224, 165, 136, 72, 0, 0, 0, 9, 134, 224, 164, 185, 224, 165, 139, 72, 0, 0, 0, 0, 0, 0, 12, 137, 224, 164, 174, 224, 165, 135, 224, 164, 130, 72, 0, 0, 0, 15, 140, 224, 164, 185, 224, 164, 174, 224, 165, 135, 224, 164, 130, 72, 0, 0, 0, 0, 0, 0, 21, 146, 224, 164, 137, 224, 164, 168, 224, 165, 141, 224, 164, 185, 224, 165, 135, 224, 164, 130, 72, 21, 146, 224, 164, 135, 224, 164, 168, 224, 165, 141, 224, 164, 185, 224, 165, 135, 224, 164, 130, 72, 0, 0, 0, 15, 140, 224, 164, 164, 224, 165, 129, 224, 164, 157, 224, 165, 135, 72, 24, 149, 224, 164, 164, 224, 165, 129, 224, 164, 174, 224, 165, 141, 224, 164, 185, 224, 165, 135, 224, 164, 130, 72, 0, 0, 12, 137, 224, 164, 174, 224, 164, 151, 224, 164, 176, 8, 0, 11, 6, 224, 164, 151, 224, 164, 188, 100, 13, 0, 0, 9, 134, 224, 164, 181, 224, 164, 185, 72, 0, 0, 0, 11, 6, 224, 164, 149, 224, 164, 188, 104, 13, 0, 0, 0, 9, 134, 224, 164, 149, 224, 164, 190, 72, 0, 0, 0, 0, 0, 0, 15, 140, 224, 164, 137, 224, 164, 168, 224, 164, 149, 224, 164, 190, 72, 15, 140, 224, 164, 137, 224, 164, 184, 224, 164, 149, 224, 164, 190, 72, 15, 140, 224, 164, 135, 224, 164, 168, 224, 164, 149, 224, 164, 190, 72, 15, 140, 224, 164, 135, 224, 164, 184, 224, 164, 149, 224, 164, 190, 72, 0, 0, 0, 0, 11, 6, 224, 164, 171, 224, 164, 188, 83, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 140, 224, 164, 149, 224, 165, 141, 224, 164, 175, 224, 164, 190, 72, 8, 0, 12, 137, 224, 164, 176, 224, 164, 185, 224, 164, 190, 72, 0, 17, 4, 95, 4, 16, 20, 10, 72, 13, 89, 13, 65, 55, 6, 119, 10, 0, 0, 0, 15, 140, 224, 164, 134, 224, 164, 170, 224, 164, 149, 224, 164, 190, 72, 0, 0, 0, 0, 0, 0, 31, 21, 224, 164, 149, 224, 165, 141, 224, 164, 176, 224, 164, 191, 224, 164, 149, 224, 165, 135, 224, 164, 159, 49, 34, 113, 49, 6, 116, 47, 0, 0, 0, 0, 9, 134, 224, 164, 175, 224, 164, 185, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 224, 164, 161, 224, 164, 188, 70, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 224, 164, 185, 224, 164, 174, 72, 0, 0, 0, 12, 137, 224, 164, 164, 224, 165, 129, 224, 164, 174, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 51, 57, 122, 50, 47, 118, 55, 6, 113, 89, 0, 12, 3, 95, 50, 49, 113, 49, 12, 6, 113, 89, 0, 0, 12, 3, 95, 51, 56, 35, 34, 47, 6, 113, 89, 0, 10, 3, 95, 50, 48, 71, 6, 112, 89, 0, 0, 11, 3, 95, 50, 51, 47, 6, 114, 113, 89, 0, 0, 11, 3, 95, 50, 50, 71, 6, 118, 113, 89, 0, 0, 13, 3, 95, 50, 53, 48, 13, 80, 12, 6, 113, 89, 0, 0, 12, 3, 95, 50, 52, 80, 6, 120, 71, 113, 89, 0, 0, 14, 3, 95, 50, 55, 89, 13, 47, 12, 6, 118, 113, 89, 0, 0, 14, 3, 95, 50, 54, 144, 13, 71, 71, 6, 112, 34, 89, 0, 0, 14, 3, 95, 51, 49, 113, 49, 13, 47, 12, 6, 113, 89, 0, 0, 10, 3, 95, 51, 48, 47, 6, 112, 89, 0, 0, 12, 3, 95, 51, 51, 47, 127, 47, 6, 113, 89, 0, 0, 13, 3, 95, 51, 50, 71, 35, 47, 12, 6, 113, 89, 0, 0, 9, 134, 224, 164, 165, 224, 165, 128, 72, 12, 3, 95, 51, 53, 48, 127, 47, 6, 113, 89, 0, 0, 12, 3, 95, 51, 52, 80, 130, 47, 6, 113, 89, 0, 0, 12, 3, 95, 51, 55, 89, 127, 47, 6, 113, 89, 0, 0, 13, 3, 95, 51, 54, 144, 35, 87, 6, 47, 113, 89, 0, 0, 0, 9, 134, 224, 164, 165, 224, 165, 135, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 55, 57, 4, 122, 67, 113, 118, 89, 6, 112, 0, 12, 3, 95, 54, 49, 6, 113, 49, 89, 13, 142, 0, 0, 9, 3, 224, 165, 140, 148, 135, 0, 103, 8, 3, 224, 165, 140, 148, 120, 0, 16, 3, 95, 55, 56, 35, 138, 107, 35, 47, 12, 6, 109, 34, 12, 0, 10, 3, 95, 54, 48, 89, 6, 118, 142, 0, 0, 9, 3, 95, 48, 67, 89, 6, 120, 0, 13, 3, 95, 54, 51, 47, 6, 113, 34, 89, 13, 142, 0, 0, 12, 3, 95, 54, 50, 71, 6, 118, 89, 13, 142, 0, 0, 8, 3, 224, 165, 137, 18, 121, 0, 12, 3, 95, 54, 53, 48, 134, 50, 89, 13, 142, 0, 0, 9, 3, 224, 165, 136, 148, 134, 0, 102, 8, 3, 224, 165, 136, 148, 115, 0, 12, 3, 95, 54, 52, 80, 6, 130, 89, 13, 142, 0, 0, 8, 3, 224, 165, 139, 148, 119, 0, 13, 3, 95, 54, 55, 89, 6, 109, 34, 89, 13, 142, 0, 0, 8, 3, 224, 165, 138, 18, 39, 0, 14, 3, 95, 54, 54, 144, 6, 113, 57, 118, 89, 13, 142, 0, 0, 8, 3, 224, 165, 133, 18, 116, 0, 15, 3, 95, 55, 49, 113, 146, 35, 47, 12, 6, 109, 34, 12, 0, 0, 9, 3, 224, 165, 132, 18, 34, 113, 0, 14, 3, 95, 55, 48, 89, 35, 47, 12, 6, 109, 34, 12, 0, 0, 8, 3, 224, 165, 135, 148, 114, 0, 16, 3, 95, 55, 51, 47, 113, 107, 35, 47, 12, 6, 109, 34, 12, 0, 0, 8, 3, 224, 165, 134, 18, 36, 0, 16, 3, 95, 55, 50, 71, 13, 107, 35, 47, 12, 6, 109, 34, 12, 0, 0, 8, 3, 224, 165, 129, 18, 122, 0, 17, 3, 95, 55, 53, 48, 35, 144, 4, 35, 47, 12, 6, 109, 34, 12, 0, 0, 8, 3, 224, 165, 128, 148, 112, 0, 16, 3, 95, 55, 52, 80, 120, 107, 35, 47, 12, 6, 109, 34, 12, 0, 0, 9, 3, 224, 165, 131, 18, 34, 113, 0, 18, 3, 95, 55, 55, 89, 13, 47, 13, 107, 35, 47, 12, 6, 109, 34, 12, 0, 0, 8, 3, 224, 165, 130, 148, 123, 0, 16, 3, 95, 55, 54, 144, 113, 107, 35, 47, 12, 6, 109, 34, 12, 0, 0, 12, 3, 95, 49, 57, 122, 50, 50, 6, 113, 89, 0, 0, 13, 3, 95, 49, 56, 109, 142, 12, 6, 118, 34, 111, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 50, 57, 122, 50, 47, 6, 113, 89, 0, 12, 3, 95, 49, 49, 81, 57, 6, 118, 34, 111, 0, 0, 13, 3, 95, 50, 56, 35, 138, 12, 6, 118, 113, 89, 0, 10, 3, 95, 49, 48, 72, 6, 109, 89, 0, 0, 11, 3, 95, 49, 51, 47, 6, 115, 34, 111, 0, 0, 11, 3, 95, 49, 50, 71, 6, 118, 34, 111, 0, 0, 13, 3, 95, 49, 53, 48, 6, 109, 50, 72, 34, 111, 0, 0, 11, 3, 95, 49, 52, 144, 6, 120, 72, 111, 0, 0, 13, 3, 95, 49, 55, 89, 6, 109, 47, 12, 34, 111, 0, 0, 11, 3, 95, 49, 54, 89, 6, 119, 55, 111, 0, 0, 8, 3, 224, 164, 165, 138, 13, 0, 0, 8, 3, 224, 164, 164, 47, 13, 0, 0, 9, 134, 224, 164, 165, 224, 164, 190, 72, 8, 3, 224, 164, 167, 139, 13, 0, 0, 8, 3, 224, 164, 166, 72, 13, 0, 0, 8, 3, 224, 164, 161, 141, 13, 0, 0, 8, 3, 224, 164, 160, 142, 13, 0, 0, 8, 3, 224, 164, 163, 66, 13, 0, 0, 8, 3, 224, 164, 162, 143, 13, 0, 0, 8, 3, 224, 164, 157, 145, 13, 0, 12, 3, 95, 52, 57, 6, 122, 67, 80, 118, 89, 0, 0, 11, 3, 224, 165, 164, 72, 109, 66, 141, 109, 0, 8, 3, 224, 164, 156, 79, 13, 0, 14, 3, 95, 52, 56, 35, 34, 47, 118, 55, 6, 113, 89, 0, 0, 8, 3, 224, 164, 159, 140, 13, 0, 0, 8, 3, 224, 164, 158, 67, 13, 0, 0, 8, 3, 224, 164, 153, 68, 13, 0, 0, 8, 3, 224, 164, 152, 147, 13, 0, 0, 9, 3, 224, 165, 163, 148, 45, 12, 0, 8, 3, 224, 164, 155, 144, 13, 0, 0, 8, 3, 224, 165, 162, 18, 45, 0, 8, 3, 224, 164, 154, 80, 13, 0, 0, 9, 3, 224, 165, 157, 107, 34, 13, 0, 8, 3, 224, 164, 149, 49, 13, 0, 12, 3, 95, 53, 57, 122, 50, 89, 6, 109, 138, 0, 14, 3, 95, 52, 49, 113, 49, 47, 118, 55, 6, 113, 89, 0, 0, 8, 3, 224, 165, 156, 44, 13, 0, 14, 3, 95, 53, 56, 35, 138, 12, 6, 118, 58, 13, 50, 0, 12, 3, 95, 52, 48, 80, 118, 55, 6, 113, 89, 0, 0, 8, 3, 224, 165, 159, 57, 13, 0, 8, 3, 224, 164, 151, 81, 13, 0, 14, 3, 95, 52, 51, 47, 127, 47, 118, 55, 6, 113, 89, 0, 0, 8, 3, 224, 165, 158, 83, 13, 0, 8, 3, 224, 164, 150, 146, 13, 0, 13, 3, 95, 52, 50, 71, 134, 118, 55, 6, 113, 89, 0, 0, 8, 3, 224, 165, 153, 101, 13, 0, 16, 3, 95, 52, 53, 48, 134, 6, 50, 47, 118, 55, 6, 113, 89, 0, 0, 8, 3, 224, 165, 152, 104, 13, 0, 14, 3, 95, 52, 52, 80, 120, 58, 118, 55, 6, 113, 89, 0, 0, 8, 3, 224, 165, 155, 88, 13, 0, 14, 3, 95, 52, 55, 89, 127, 47, 118, 55, 6, 113, 89, 0, 0, 13, 137, 224, 164, 133, 224, 164, 151, 224, 164, 176, 72, 8, 8, 3, 224, 165, 154, 100, 13, 0, 15, 3, 95, 52, 54, 144, 107, 113, 57, 118, 55, 6, 113, 89, 0, 0, 18, 3, 95, 54, 57, 122, 50, 13, 107, 4, 35, 47, 12, 6, 109, 34, 12, 0, 14, 3, 95, 53, 49, 113, 49, 57, 6, 118, 58, 109, 50, 0, 0, 11, 3, 95, 54, 56, 35, 34, 89, 13, 142, 0, 12, 3, 95, 53, 48, 48, 13, 80, 6, 118, 89, 0, 0, 13, 3, 95, 53, 51, 47, 6, 113, 34, 48, 109, 50, 0, 0, 12, 3, 95, 53, 50, 71, 6, 118, 58, 109, 50, 0, 0, 13, 3, 95, 53, 53, 48, 6, 35, 144, 48, 109, 50, 0, 0, 9, 3, 224, 165, 144, 18, 131, 65, 0, 13, 3, 95, 53, 52, 80, 6, 121, 123, 58, 109, 50, 0, 0, 15, 3, 95, 53, 55, 89, 109, 47, 12, 6, 118, 58, 13, 50, 0, 0, 14, 3, 95, 53, 54, 144, 107, 13, 48, 12, 6, 109, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 56, 57, 50, 109, 58, 118, 89, 6, 112, 0, 0, 13, 3, 95, 56, 56, 35, 138, 12, 118, 89, 6, 112, 0, 0, 8, 3, 224, 164, 191, 18, 113, 0, 0, 8, 3, 224, 164, 190, 148, 118, 0, 0, 8, 3, 224, 164, 185, 108, 13, 0, 0, 8, 3, 224, 164, 184, 89, 13, 0, 0, 0, 0, 8, 3, 224, 164, 181, 84, 13, 0, 16, 3, 95, 57, 57, 50, 113, 67, 57, 6, 118, 50, 13, 58, 114, 0, 13, 3, 95, 56, 49, 113, 49, 57, 118, 89, 6, 112, 0, 0, 15, 3, 95, 57, 56, 35, 138, 12, 6, 118, 50, 13, 58, 114, 0, 12, 3, 95, 56, 48, 4, 109, 89, 89, 6, 112, 0, 0, 8, 3, 224, 164, 183, 93, 13, 0, 13, 3, 95, 56, 51, 47, 113, 34, 118, 89, 6, 112, 0, 0, 8, 3, 224, 164, 182, 91, 13, 0, 12, 3, 95, 56, 50, 71, 134, 118, 89, 6, 112, 0, 0, 8, 3, 224, 164, 177, 34, 13, 0, 14, 3, 95, 56, 53, 48, 113, 6, 80, 118, 89, 6, 112, 0, 0, 8, 3, 224, 164, 176, 34, 13, 0, 13, 3, 95, 56, 52, 80, 120, 34, 118, 89, 6, 112, 0, 0, 8, 3, 224, 164, 179, 62, 13, 0, 14, 3, 95, 56, 55, 89, 109, 47, 12, 118, 89, 6, 112, 0, 0, 8, 3, 224, 164, 178, 55, 13, 0, 13, 3, 95, 56, 54, 144, 113, 57, 118, 89, 6, 112, 0, 0, 8, 3, 224, 164, 173, 137, 13, 0, 15, 3, 95, 57, 49, 113, 49, 57, 6, 118, 50, 13, 58, 114, 0, 0, 8, 3, 224, 164, 172, 71, 13, 0, 12, 3, 95, 57, 48, 50, 109, 71, 12, 6, 114, 0, 0, 10, 3, 224, 164, 175, 57, 13, 0, 72, 8, 8, 3, 224, 164, 175, 57, 13, 0, 15, 3, 95, 57, 51, 47, 113, 34, 6, 118, 50, 13, 58, 114, 0, 0, 8, 3, 224, 164, 174, 65, 13, 0, 13, 3, 95, 57, 50, 71, 6, 118, 50, 13, 58, 114, 0, 0, 15, 3, 95, 57, 53, 48, 13, 80, 6, 118, 50, 13, 58, 114, 0, 0, 8, 3, 224, 164, 168, 50, 13, 0, 15, 3, 95, 57, 52, 80, 120, 34, 6, 118, 65, 13, 58, 114, 0, 0, 8, 3, 224, 164, 171, 136, 13, 0, 16, 3, 95, 57, 55, 89, 13, 47, 12, 6, 118, 50, 13, 58, 114, 0, 0, 8, 3, 224, 164, 170, 48, 13, 0, 15, 3, 95, 57, 54, 144, 113, 57, 6, 118, 50, 13, 58, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 95, 48, 77, 52, 6, 109, 34, 13, 71, 0, 0, 13, 4, 95, 48, 77, 53, 146, 6, 109, 34, 13, 71, 0, 0, 11, 4, 95, 48, 77, 50, 55, 6, 118, 146, 0, 0, 13, 4, 95, 48, 77, 51, 80, 34, 6, 39, 34, 36, 0, 0, 0, 13, 4, 95, 48, 77, 49, 107, 13, 88, 6, 118, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 137, 224, 164, 185, 224, 165, 136, 224, 164, 130, 72, 0, 0, 0, 0, 0, 9, 134, 224, 164, 164, 224, 165, 130, 72, 0, 0, 0, 0, 0, 0, 18, 143, 224, 164, 137, 224, 164, 184, 224, 165, 141, 224, 164, 184, 224, 165, 135, 72, 18, 143, 224, 164, 135, 224, 164, 184, 224, 165, 141, 224, 164, 184, 224, 165, 135, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 152, 224, 164, 164, 224, 165, 129, 224, 164, 174, 224, 165, 141, 224, 164, 185, 224, 164, 190, 224, 164, 176, 224, 165, 135, 72, 0, 0, 0, 0, 0, 27, 152, 224, 164, 164, 224, 165, 129, 224, 164, 174, 224, 165, 141, 224, 164, 185, 224, 164, 190, 224, 164, 176, 224, 165, 128, 72, 0, 0, 0, 0, 0, 0, 12, 137, 224, 164, 185, 224, 165, 130, 224, 164, 129, 72, 0, 12, 137, 224, 164, 165, 224, 165, 128, 224, 164, 130, 72, 12, 137, 224, 164, 174, 224, 165, 136, 224, 164, 130, 72, 0, 0, 9, 134, 224, 164, 184, 224, 165, 135, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 224, 164, 164, 224, 164, 149, 72, 0, 0, 0, 18, 143, 224, 164, 133, 224, 164, 151, 224, 164, 176, 224, 164, 154, 224, 165, 135, 8, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 224, 164, 150, 224, 164, 188, 101, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 152, 224, 164, 164, 224, 165, 129, 224, 164, 174, 224, 165, 141, 224, 164, 185, 224, 164, 190, 224, 164, 176, 224, 164, 190, 72, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 224, 164, 170, 224, 164, 176, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 224, 164, 156, 224, 164, 188, 88, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 134, 224, 164, 148, 224, 164, 176, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 16, 140, 224, 164, 172, 224, 164, 191, 224, 164, 168, 224, 164, 190, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 224, 164, 134, 224, 164, 170, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 2, 95, 51, 47, 6, 112, 50, 0, 0, 8, 2, 95, 50, 72, 6, 119, 0, 0, 8, 2, 95, 49, 6, 114, 49, 0, 0, 11, 2, 95, 48, 91, 6, 123, 66, 57, 109, 0, 0, 9, 2, 95, 55, 89, 6, 118, 47, 0, 0, 8, 2, 95, 54, 144, 6, 111, 0, 0, 10, 2, 95, 53, 48, 6, 118, 50, 80, 0, 0, 10, 2, 95, 52, 80, 6, 118, 34, 12, 0, 0, 0, 0, 9, 2, 95, 57, 50, 6, 135, 0, 103, 8, 2, 95, 57, 50, 6, 120, 0, 0, 8, 2, 95, 56, 6, 118, 142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 140, 224, 164, 174, 224, 165, 135, 224, 164, 176, 224, 165, 135, 72, 0, 0, 0, 0, 0, 0, 0, 15, 140, 224, 164, 174, 224, 165, 135, 224, 164, 176, 224, 165, 128, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 137, 224, 164, 175, 224, 164, 166, 224, 164, 191, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 143, 224, 164, 185, 224, 164, 174, 224, 164, 190, 224, 164, 176, 224, 165, 135, 72, 0, 0, 0, 0, 0, 0, 0, 18, 143, 224, 164, 185, 224, 164, 174, 224, 164, 190, 224, 164, 176, 224, 165, 128, 72, 0, 0, 0, 0, 0, 0, 0, 15, 140, 224, 164, 164, 224, 165, 135, 224, 164, 176, 224, 164, 190, 72, 15, 140, 224, 164, 174, 224, 165, 135, 224, 164, 176, 224, 164, 190, 72, 0, 24, 15, 224, 164, 184, 224, 164, 190, 224, 164, 175, 224, 164, 172, 224, 164, 176, 89, 6, 134, 71, 13, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 143, 224, 164, 185, 224, 164, 174, 224, 164, 190, 224, 164, 176, 224, 164, 190, 72, 0, 0, 0, 0, 0, 0, 0, 0, 6, 20, 0, 0, 102, 9, 0, 0, 48, 0, 0, 0, 103, 9, 0, 0, 49, 0, 0, 0, 104, 9, 0, 0, 50, 0, 0, 0, 105, 9, 0, 0, 51, 0, 0, 0, 106, 9, 0, 0, 52, 0, 0, 0, 107, 9, 0, 0, 53, 0, 0, 0, 108, 9, 0, 0, 54, 0, 0, 0, 109, 9, 0, 0, 55, 0, 0, 0, 110, 9, 0, 0, 56, 0, 0, 0, 111, 9, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 6, 1, 2, 0, 3, 50, 0, 7, 6, 1, 3, 0, 3, 50, 0, 4, 2, 224, 164, 170, 3, 65, 0, 2, 224, 164, 171, 0, 2, 224, 164, 172, 0, 2, 224, 164, 173, 0, 2, 224, 164, 174, 0, 4, 2, 224, 164, 159, 3, 66, 0, 2, 224, 164, 160, 0, 2, 224, 164, 161, 0, 2, 224, 164, 162, 0, 2, 224, 164, 163, 0, 4, 2, 224, 164, 154, 3, 67, 0, 2, 224, 164, 155, 0, 2, 224, 164, 156, 0, 2, 224, 164, 157, 0, 2, 224, 164, 158, 0, 2, 224, 164, 175, 0, 4, 2, 224, 164, 149, 3, 68, 0, 2, 224, 164, 150, 0, 2, 224, 164, 151, 0, 2, 224, 164, 152, 0, 2, 224, 164, 153, 0, 2, 224, 164, 185, 0, 7, 6, 1, 4, 0, 3, 108, 0, 7, 6, 1, 6, 0, 3, 109, 0, 4, 1, 185, 164, 224, 133, 164, 224, 3, 116, 0, 2, 224, 164, 185, 0, 7, 6, 1, 7, 0, 3, 118, 0, 7, 6, 1, 8, 0, 3, 113, 0, 7, 6, 1, 9, 0, 2, 32, 3, 37, 0, 3, 112, 0, 7, 6, 1, 10, 0, 3, 122, 0, 7, 6, 1, 11, 0, 3, 123, 0, 4, 224, 164, 129, 3, 133, 0, 224, 164, 130, 0, 7, 6, 1, 12, 0, 3, 34, 113, 0, 7, 6, 1, 13, 0, 3, 45, 0, 7, 6, 1, 14, 0, 3, 116, 0, 7, 6, 1, 15, 0, 3, 36, 0, 7, 6, 1, 16, 0, 3, 114, 0, 7, 6, 1, 17, 0, 3, 115, 0, 4, 224, 164, 129, 3, 127, 0, 224, 164, 130, 0, 5, 2, 3, 134, 0, 7, 6, 1, 18, 0, 3, 121, 0, 7, 6, 1, 19, 0, 3, 39, 0, 7, 6, 1, 20, 0, 3, 119, 0, 4, 224, 164, 129, 3, 131, 0, 224, 164, 130, 0, 7, 6, 1, 21, 0, 3, 120, 0, 4, 224, 164, 129, 3, 130, 0, 224, 164, 130, 0, 5, 3, 3, 135, 0, 7, 6, 1, 22, 0, 2, 17, 66, 3, 49, 0, 2, 224, 165, 141, 224, 164, 175, 3, 49, 12, 0, 3, 49, 109, 0, 224, 164, 188, 2, 17, 66, 3, 104, 0, 224, 164, 188, 3, 104, 109, 0, 7, 6, 1, 23, 0, 224, 164, 188, 2, 17, 66, 3, 101, 0, 224, 164, 188, 3, 101, 109, 0, 2, 17, 66, 3, 146, 0, 3, 146, 109, 0, 7, 6, 1, 24, 0, 2, 17, 66, 3, 81, 0, 3, 81, 109, 0, 224, 164, 188, 2, 17, 66, 3, 100, 0, 224, 164, 188, 3, 100, 109, 0, 7, 6, 1, 25, 0, 2, 17, 66, 3, 147, 0, 3, 147, 109, 0, 7, 6, 1, 26, 0, 2, 17, 66, 3, 68, 0, 1, 141, 165, 224, 2, 32, 3, 68, 13, 0, 3, 68, 109, 0, 7, 6, 1, 27, 0, 2, 17, 66, 3, 80, 0, 2, 224, 165, 141, 224, 164, 175, 3, 80, 12, 0, 3, 80, 109, 0, 7, 6, 1, 28, 0, 2, 17, 66, 3, 144, 0, 3, 144, 109, 0, 7, 6, 1, 29, 0, 2, 17, 66, 3, 79, 0, 3, 79, 109, 0, 224, 164, 188, 2, 17, 66, 3, 88, 0, 224, 164, 188, 3, 88, 109, 0, 7, 6, 1, 30, 0, 2, 17, 66, 3, 145, 0, 3, 145, 109, 0, 7, 6, 1, 31, 0, 4, 1, 141, 165, 224, 2, 32, 3, 67, 0, 2, 17, 66, 0, 3, 67, 109, 0, 7, 6, 1, 32, 0, 2, 17, 66, 3, 140, 0, 2, 224, 165, 141, 224, 164, 175, 3, 140, 12, 0, 3, 140, 109, 0, 7, 6, 1, 33, 0, 2, 17, 66, 3, 142, 0, 3, 142, 109, 0, 7, 6, 1, 34, 0, 224, 164, 188, 2, 17, 66, 3, 70, 0, 224, 164, 188, 3, 70, 109, 0, 2, 17, 66, 3, 141, 0, 3, 141, 109, 0, 7, 6, 1, 35, 0, 224, 164, 188, 2, 17, 66, 3, 70, 107, 0, 224, 164, 188, 3, 70, 107, 109, 0, 2, 17, 66, 3, 143, 0, 3, 143, 109, 0, 7, 6, 1, 36, 0, 2, 17, 66, 3, 66, 0, 1, 141, 165, 224, 2, 32, 3, 66, 13, 0, 3, 66, 109, 0, 7, 6, 1, 37, 0, 2, 17, 66, 3, 47, 0, 2, 224, 165, 141, 224, 164, 175, 3, 47, 12, 0, 3, 47, 109, 0, 7, 6, 1, 38, 0, 2, 17, 66, 3, 138, 0, 3, 138, 109, 0, 7, 6, 1, 39, 0, 2, 17, 66, 3, 72, 0, 3, 72, 109, 0, 7, 6, 1, 40, 0, 2, 17, 66, 3, 139, 0, 3, 139, 109, 0, 7, 6, 1, 41, 0, 4, 1, 141, 165, 224, 176, 164, 224, 2, 32, 3, 50, 0, 2, 17, 66, 0, 1, 141, 165, 224, 2, 32, 3, 50, 13, 0, 3, 50, 109, 0, 7, 6, 1, 42, 0, 3, 50, 12, 0, 7, 6, 1, 43, 0, 2, 17, 66, 3, 48, 0, 2, 224, 165, 141, 224, 164, 175, 3, 48, 12, 0, 3, 48, 109, 0, 7, 6, 1, 44, 0, 224, 164, 188, 2, 17, 66, 3, 83, 0, 224, 164, 188, 3, 83, 109, 0, 2, 17, 66, 3, 136, 0, 3, 136, 109, 0, 7, 6, 1, 45, 0, 2, 17, 66, 3, 71, 0, 3, 71, 109, 0, 7, 6, 1, 46, 0, 2, 17, 66, 3, 137, 0, 3, 137, 109, 0, 7, 6, 1, 47, 0, 4, 1, 141, 165, 224, 168, 164, 224, 2, 32, 3, 65, 0, 1, 141, 165, 224, 176, 164, 224, 2, 32, 0, 2, 17, 66, 0, 1, 141, 165, 224, 2, 32, 3, 65, 13, 0, 3, 65, 109, 0, 7, 6, 1, 48, 0, 2, 17, 66, 3, 57, 0, 1, 141, 165, 224, 2, 32, 3, 57, 13, 0, 3, 57, 109, 0, 7, 6, 1, 49, 0, 2, 17, 66, 3, 34, 0, 1, 141, 165, 224, 2, 32, 3, 34, 13, 0, 3, 34, 109, 0, 7, 6, 1, 50, 0, 2, 17, 66, 3, 34, 0, 1, 141, 165, 224, 2, 32, 3, 34, 13, 0, 3, 34, 109, 0, 7, 6, 1, 51, 0, 2, 17, 66, 3, 55, 0, 1, 141, 165, 224, 2, 32, 3, 55, 13, 0, 3, 55, 109, 0, 7, 6, 1, 52, 0, 2, 17, 66, 3, 62, 0, 1, 141, 165, 224, 2, 32, 3, 62, 13, 0, 3, 62, 109, 0, 7, 6, 1, 53, 0, 2, 17, 66, 3, 62, 0, 1, 141, 165, 224, 2, 32, 3, 62, 13, 0, 3, 62, 109, 0, 7, 6, 1, 54, 0, 8, 2, 17, 66, 3, 58, 0, 8, 3, 58, 109, 0, 4, 2, 17, 66, 3, 84, 0, 8, 2, 224, 165, 141, 0, 3, 84, 109, 0, 7, 6, 1, 55, 0, 2, 17, 66, 3, 91, 0, 3, 91, 109, 0, 7, 6, 1, 56, 0, 2, 17, 66, 3, 93, 0, 3, 93, 109, 0, 7, 6, 1, 57, 0, 2, 17, 66, 3, 89, 0, 3, 89, 109, 0, 7, 6, 1, 58, 0, 2, 17, 66, 3, 108, 0, 3, 108, 109, 0, 7, 6, 1, 62, 0, 3, 12, 0, 7, 6, 1, 63, 0, 3, 118, 0, 224, 164, 181, 3, 135, 0, 7, 6, 1, 64, 0, 3, 113, 0, 7, 6, 1, 65, 0, 2, 32, 3, 37, 0, 3, 112, 0, 7, 6, 1, 66, 0, 3, 122, 0, 7, 6, 1, 67, 0, 3, 123, 0, 4, 224, 164, 129, 3, 133, 0, 224, 164, 130, 0, 7, 6, 1, 68, 0, 3, 34, 113, 0, 7, 6, 1, 69, 0, 3, 34, 113, 0, 7, 6, 1, 70, 0, 3, 116, 0, 7, 6, 1, 71, 0, 3, 36, 0, 7, 6, 1, 72, 0, 3, 114, 0, 7, 6, 1, 73, 0, 3, 115, 0, 4, 224, 164, 129, 3, 127, 0, 224, 164, 130, 0, 5, 2, 3, 134, 0, 7, 6, 1, 74, 0, 3, 121, 0, 7, 6, 1, 75, 0, 3, 39, 0, 7, 6, 1, 76, 0, 3, 119, 0, 4, 224, 164, 129, 3, 131, 0, 224, 164, 130, 0, 7, 6, 1, 77, 0, 3, 120, 0, 4, 224, 164, 129, 3, 130, 0, 224, 164, 130, 0, 5, 3, 3, 135, 0, 7, 6, 1, 78, 0, 3, 0, 7, 6, 1, 81, 0, 3, 131, 65, 0, 7, 6, 1, 89, 0, 2, 17, 66, 3, 104, 0, 3, 104, 109, 0, 7, 6, 1, 90, 0, 2, 17, 66, 3, 101, 0, 3, 101, 109, 0, 7, 6, 1, 91, 0, 2, 17, 66, 3, 100, 0, 3, 100, 109, 0, 7, 6, 1, 92, 0, 2, 17, 66, 3, 88, 0, 3, 88, 109, 0, 7, 6, 1, 93, 0, 2, 17, 66, 3, 70, 0, 3, 70, 109, 0, 7, 6, 1, 94, 0, 2, 17, 66, 3, 70, 107, 0, 3, 70, 107, 109, 0, 7, 6, 1, 95, 0, 2, 17, 66, 3, 83, 0, 3, 83, 109, 0, 7, 6, 1, 96, 0, 2, 17, 66, 3, 57, 0, 3, 57, 109, 0, 7, 6, 1, 97, 0, 3, 109, 20, 34, 34, 0, 7, 6, 1, 98, 0, 3, 45, 12, 0, 7, 6, 1, 99, 0, 3, 45, 0, 7, 6, 1, 100, 0, 3, 45, 12, 0, 7, 6, 111, 0, 3, 21, 0, 102, 1, 32, 32, 15, 2, 32, 32, 15, 194, 160, 194, 160, 194, 160, 3, 65, 36, 0, 7, 6, 0, 37, 3, 48, 109, 89, 116, 50, 47, 0, 36, 3, 72, 121, 55, 109, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts23 = FileInMemory_createWithData (5723, reinterpret_cast (&espeakdata_dicts23_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/hi_dict", U"hi"); Collection_addItem (me.peek(), espeakdata_dicts23.transfer()); static unsigned char espeakdata_dicts24_data[2417] = { 0, 4, 0, 0, 93, 8, 0, 0, 0, 0, 0, 0, 0, 7, 65, 4, 35, 0, 15, 14, 4, 193, 4, 72, 4, 193, 4, 72, 0, 5, 194, 5, 0, 72, 0, 0, 0, 6, 65, 8, 71, 37, 0, 0, 0, 0, 0, 6, 65, 12, 89, 37, 0, 0, 0, 0, 0, 6, 65, 16, 72, 37, 0, 0, 0, 0, 0, 5, 65, 20, 36, 0, 0, 5, 194, 100, 240, 72, 0, 0, 0, 6, 65, 24, 112, 83, 0, 0, 0, 0, 0, 6, 65, 28, 81, 36, 0, 0, 0, 0, 0, 6, 65, 32, 35, 91, 0, 0, 0, 0, 9, 1, 35, 35, 91, 35, 57, 0, 27, 0, 5, 65, 36, 37, 0, 0, 9, 1, 37, 48, 40, 89, 113, 0, 27, 0, 0, 0, 6, 65, 40, 90, 37, 0, 0, 0, 12, 1, 42, 35, 89, 47, 36, 34, 37, 89, 0, 27, 0, 9, 1, 43, 48, 55, 37, 89, 0, 27, 0, 6, 65, 44, 49, 35, 0, 0, 0, 0, 9, 1, 47, 89, 55, 35, 91, 0, 27, 0, 7, 65, 48, 36, 55, 0, 14, 0, 0, 0, 0, 7, 65, 52, 36, 65, 0, 14, 0, 0, 0, 0, 7, 65, 56, 36, 50, 0, 14, 0, 0, 0, 0, 5, 65, 60, 39, 0, 0, 9, 1, 61, 36, 81, 35, 55, 0, 27, 0, 0, 0, 6, 65, 64, 48, 37, 0, 0, 0, 0, 0, 7, 65, 68, 49, 57, 40, 0, 0, 0, 0, 0, 7, 65, 72, 35, 34, 35, 0, 0, 0, 0, 0, 6, 65, 76, 112, 89, 0, 0, 0, 0, 0, 7, 65, 80, 47, 35, 0, 14, 12, 65, 80, 47, 35, 48, 0, 72, 81, 97, 112, 32, 0, 0, 0, 0, 5, 65, 84, 40, 0, 0, 0, 0, 0, 6, 65, 88, 84, 35, 0, 0, 0, 0, 0, 11, 65, 92, 72, 40, 71, 84, 6, 35, 0, 14, 12, 1, 92, 113, 47, 37, 89, 55, 35, 91, 0, 27, 0, 0, 0, 0, 10, 4, 95, 49, 77, 49, 65, 37, 55, 0, 0, 0, 0, 0, 13, 65, 100, 37, 48, 89, 37, 55, 6, 39, 50, 0, 14, 0, 0, 0, 0, 7, 65, 104, 88, 36, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 4, 176, 72, 28, 0, 0, 0, 0, 0, 0, 11, 4, 95, 4, 16, 20, 10, 48, 58, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 4, 224, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 48, 19, 128, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 53, 113, 78, 72, 0, 0, 6, 195, 100, 243, 128, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 51, 57, 47, 34, 113, 47, 50, 112, 83, 0, 12, 3, 95, 50, 49, 84, 114, 47, 36, 38, 114, 0, 0, 13, 3, 95, 51, 56, 47, 34, 113, 47, 111, 37, 47, 0, 8, 3, 95, 50, 48, 84, 114, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 51, 49, 47, 34, 113, 47, 36, 38, 114, 0, 0, 10, 3, 95, 51, 48, 47, 34, 113, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 54, 49, 89, 58, 35, 89, 113, 47, 36, 38, 114, 0, 0, 12, 3, 95, 54, 48, 89, 58, 35, 89, 113, 47, 0, 10, 3, 95, 51, 88, 47, 34, 113, 50, 0, 0, 8, 3, 95, 48, 67, 89, 113, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 55, 49, 89, 58, 35, 89, 113, 47, 36, 38, 116, 88, 0, 0, 15, 3, 95, 55, 48, 89, 58, 35, 89, 113, 47, 72, 37, 89, 0, 0, 0, 0, 0, 6, 195, 65, 32, 76, 72, 0, 0, 0, 5, 194, 48, 16, 72, 12, 3, 95, 49, 57, 72, 37, 88, 50, 112, 83, 0, 0, 12, 3, 95, 49, 56, 72, 37, 88, 111, 37, 47, 0, 0, 0, 0, 0, 7, 195, 21, 2, 64, 72, 8, 0, 0, 0, 12, 3, 95, 50, 57, 84, 114, 47, 50, 112, 83, 0, 8, 3, 95, 49, 49, 116, 88, 0, 0, 12, 3, 95, 50, 56, 84, 114, 47, 111, 37, 47, 0, 9, 3, 95, 49, 48, 72, 37, 89, 0, 0, 10, 3, 95, 49, 51, 47, 34, 112, 88, 0, 0, 9, 3, 95, 49, 50, 72, 40, 88, 0, 0, 9, 3, 95, 49, 53, 49, 114, 88, 0, 0, 11, 3, 95, 49, 52, 49, 35, 47, 127, 88, 0, 0, 11, 3, 95, 49, 55, 72, 37, 89, 112, 47, 0, 0, 9, 3, 95, 49, 54, 89, 112, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 52, 57, 49, 35, 34, 113, 47, 50, 112, 83, 0, 0, 14, 3, 95, 52, 56, 49, 35, 34, 113, 47, 111, 37, 47, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 53, 57, 89, 114, 49, 113, 47, 50, 112, 83, 0, 14, 3, 95, 52, 49, 49, 35, 34, 113, 47, 36, 38, 114, 0, 0, 14, 3, 95, 53, 56, 89, 114, 49, 113, 47, 111, 37, 47, 0, 11, 3, 95, 52, 48, 49, 35, 34, 113, 47, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 53, 49, 89, 114, 49, 113, 47, 36, 38, 114, 0, 0, 11, 3, 95, 53, 48, 89, 114, 49, 113, 47, 0, 9, 3, 95, 50, 88, 84, 114, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 52, 88, 49, 35, 34, 113, 50, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 56, 49, 49, 35, 47, 34, 36, 84, 114, 47, 114, 0, 0, 11, 3, 95, 53, 88, 89, 114, 49, 113, 50, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 57, 49, 49, 35, 47, 34, 36, 84, 114, 47, 116, 88, 0, 0, 12, 3, 95, 54, 88, 89, 58, 35, 89, 113, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 56, 88, 49, 35, 47, 34, 36, 84, 114, 0, 0, 0, 0, 0, 6, 195, 56, 245, 64, 72, 0, 0, 0, 5, 194, 44, 144, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 48, 144, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 48, 77, 52, 71, 37, 55, 57, 39, 50, 0, 0, 0, 13, 4, 95, 48, 77, 50, 65, 37, 55, 57, 39, 50, 0, 0, 12, 4, 95, 48, 77, 51, 65, 37, 55, 57, 35, 0, 0, 0, 10, 4, 95, 48, 77, 49, 65, 37, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 61, 80, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 76, 16, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 80, 16, 72, 0, 0, 0, 0, 6, 195, 80, 20, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 76, 80, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 60, 224, 72, 0, 0, 0, 0, 11, 2, 195, 168, 36, 81, 34, 6, 35, 84, 0, 0, 0, 0, 0, 0, 0, 11, 2, 195, 178, 39, 81, 34, 6, 35, 84, 0, 0, 0, 0, 0, 0, 0, 5, 194, 80, 80, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 2, 95, 1, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 95, 14, 36, 50, 0, 0, 7, 2, 95, 13, 36, 65, 0, 0, 7, 2, 95, 12, 36, 55, 0, 0, 0, 0, 0, 0, 11, 2, 95, 23, 72, 40, 71, 84, 6, 35, 0, 0, 0, 0, 7, 2, 95, 20, 47, 35, 0, 0, 0, 0, 13, 2, 95, 25, 37, 48, 89, 37, 55, 6, 39, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 88, 147, 128, 72, 0, 0, 0, 0, 6, 195, 56, 19, 128, 72, 0, 0, 0, 0, 0, 8, 2, 95, 46, 48, 58, 114, 0, 0, 0, 10, 2, 95, 44, 84, 37, 81, 37, 55, 0, 0, 8, 2, 95, 51, 47, 58, 35, 0, 0, 7, 2, 95, 50, 72, 36, 0, 0, 6, 2, 95, 49, 114, 0, 0, 9, 2, 95, 48, 88, 36, 58, 39, 0, 0, 8, 2, 95, 55, 89, 112, 47, 0, 0, 8, 2, 95, 54, 89, 37, 89, 0, 0, 8, 2, 95, 53, 89, 114, 49, 0, 0, 8, 2, 95, 52, 49, 35, 47, 0, 0, 13, 2, 95, 59, 48, 58, 114, 84, 37, 81, 37, 55, 0, 0, 0, 8, 2, 95, 57, 50, 112, 83, 0, 0, 8, 2, 95, 56, 111, 37, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 132, 11, 195, 168, 11, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 64, 245, 64, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 160, 0, 3, 35, 0, 7, 6, 195, 168, 0, 3, 112, 0, 7, 6, 195, 178, 0, 3, 127, 0, 7, 6, 97, 0, 3, 35, 0, 110, 2, 25, 3, 113, 0, 7, 6, 98, 0, 3, 71, 0, 7, 6, 99, 0, 3, 49, 0, 2, 17, 71, 3, 89, 0, 104, 3, 91, 0, 7, 6, 100, 0, 3, 72, 0, 7, 6, 101, 0, 3, 36, 0, 110, 2, 25, 3, 114, 0, 7, 6, 102, 0, 3, 83, 0, 7, 6, 103, 0, 3, 81, 0, 7, 6, 104, 0, 3, 0, 7, 6, 105, 0, 3, 37, 0, 7, 6, 106, 0, 3, 90, 0, 7, 6, 107, 0, 3, 49, 0, 7, 6, 108, 0, 3, 55, 0, 7, 6, 109, 0, 3, 65, 0, 7, 6, 110, 0, 3, 50, 0, 103, 3, 68, 0, 7, 6, 111, 0, 3, 39, 0, 117, 3, 40, 0, 110, 2, 25, 3, 116, 0, 7, 6, 112, 0, 3, 48, 0, 7, 6, 113, 0, 3, 49, 0, 7, 6, 114, 0, 3, 34, 0, 7, 6, 115, 0, 3, 89, 0, 7, 6, 116, 0, 3, 47, 0, 99, 104, 3, 76, 0, 7, 6, 117, 0, 3, 40, 0, 105, 3, 111, 37, 0, 7, 6, 118, 0, 3, 84, 0, 7, 6, 119, 0, 3, 58, 0, 7, 6, 120, 0, 3, 49, 89, 0, 7, 6, 121, 0, 1, 25, 2, 25, 3, 37, 0, 3, 57, 0, 7, 6, 122, 0, 3, 88, 0, 7, 6, 0, 36, 3, 72, 39, 55, 35, 0, 195, 167, 3, 89, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts24 = FileInMemory_createWithData (2416, reinterpret_cast (&espeakdata_dicts24_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/ht_dict", U"ht"); Collection_addItem (me.peek(), espeakdata_dicts24.transfer()); static unsigned char espeakdata_dicts25_data[112826] = { 0, 4, 0, 0, 190, 85, 1, 0, 13, 138, 11, 15, 18, 8, 1, 20, 195, 161, 18, 1, 13, 0, 9, 198, 80, 84, 150, 20, 177, 84, 13, 12, 137, 11, 9, 12, 195, 161, 20, 195, 161, 19, 13, 7, 132, 19, 195, 161, 22, 13, 0, 50, 12, 14, 5, 8, 195, 169, 26, 19, 195, 169, 7, 2, 5, 50, 109, 107, 113, 91, 12, 113, 81, 71, 109, 10, 6, 15, 111, 47, 49, 110, 88, 110, 47, 12, 0, 13, 81, 195, 188, 116, 107, 195, 182, 122, 195, 182, 116, 116, 32, 10, 135, 13, 1, 16, 16, 195, 161, 20, 13, 15, 140, 21, 20, 1, 19, 195, 173, 20, 195, 161, 19, 2, 1, 13, 0, 7, 196, 5, 166, 129, 48, 13, 7, 196, 21, 166, 133, 48, 13, 16, 141, 19, 26, 195, 161, 13, 12, 195, 161, 10, 195, 161, 18, 1, 13, 10, 135, 16, 195, 161, 18, 195, 161, 19, 13, 11, 136, 12, 195, 161, 14, 25, 195, 161, 20, 13, 11, 136, 4, 18, 195, 161, 22, 195, 161, 20, 13, 15, 140, 2, 197, 177, 14, 5, 19, 5, 20, 18, 197, 145, 12, 13, 19, 144, 11, 195, 182, 26, 12, 5, 11, 5, 4, 195, 169, 19, 2, 197, 145, 12, 13, 7, 196, 20, 118, 69, 80, 13, 12, 137, 18, 195, 161, 10, 195, 182, 14, 14, 9, 13, 11, 136, 19, 195, 186, 12, 25, 195, 161, 20, 13, 7, 196, 5, 166, 129, 48, 13, 8, 133, 195, 169, 18, 14, 9, 13, 0, 49, 14, 11, 1, 16, 3, 19, 15, 12, 195, 179, 4, 195, 161, 19, 9, 49, 108, 48, 76, 39, 55, 115, 72, 114, 91, 37, 23, 48, 52, 39, 71, 55, 113, 65, 108, 0, 13, 81, 112, 114, 111, 98, 108, 195, 169, 109, 97, 32, 7, 196, 21, 54, 137, 44, 13, 15, 140, 11, 15, 18, 12, 195, 161, 20, 15, 26, 195, 161, 19, 13, 12, 137, 1, 18, 195, 161, 14, 25, 195, 161, 20, 13, 0, 7, 65, 4, 108, 12, 0, 14, 26, 65, 4, 108, 6, 15, 49, 113, 52, 72, 113, 91, 47, 0, 13, 81, 107, 195, 169, 114, 100, 195, 169, 115, 116, 32, 29, 65, 4, 108, 6, 15, 48, 108, 50, 108, 89, 39, 49, 108, 47, 0, 13, 81, 112, 97, 110, 97, 115, 122, 111, 107, 97, 116, 32, 26, 65, 4, 108, 6, 15, 72, 110, 50, 47, 113, 91, 47, 0, 13, 81, 100, 195, 182, 110, 116, 195, 169, 115, 116, 32, 25, 65, 4, 108, 6, 15, 65, 108, 79, 108, 52, 39, 49, 0, 13, 81, 109, 97, 103, 121, 97, 114, 111, 107, 32, 27, 65, 4, 108, 6, 15, 107, 109, 57, 88, 109, 47, 109, 47, 0, 13, 81, 104, 101, 108, 121, 122, 101, 116, 101, 116, 32, 21, 65, 4, 108, 6, 15, 49, 108, 57, 114, 47, 0, 13, 81, 107, 97, 106, 195, 161, 116, 32, 16, 65, 4, 108, 6, 15, 71, 108, 57, 0, 13, 81, 98, 97, 106, 32, 30, 65, 4, 108, 6, 15, 47, 111, 50, 47, 109, 47, 113, 91, 47, 0, 13, 81, 116, 195, 188, 110, 116, 101, 116, 195, 169, 115, 116, 32, 30, 65, 4, 108, 6, 15, 49, 109, 72, 113, 57, 109, 49, 109, 47, 0, 13, 81, 107, 101, 100, 195, 169, 108, 121, 101, 107, 101, 116, 32, 22, 65, 4, 108, 6, 15, 89, 39, 49, 114, 91, 0, 13, 81, 115, 122, 111, 107, 195, 161, 115, 32, 25, 65, 4, 108, 6, 15, 84, 37, 55, 114, 81, 39, 50, 0, 13, 81, 118, 105, 108, 195, 161, 103, 111, 110, 32, 29, 65, 4, 108, 6, 15, 49, 40, 47, 108, 47, 115, 49, 108, 47, 0, 13, 81, 107, 117, 116, 97, 116, 195, 179, 107, 97, 116, 32, 28, 65, 4, 108, 6, 15, 71, 37, 88, 39, 76, 12, 114, 81, 0, 13, 81, 98, 105, 122, 111, 116, 116, 115, 195, 161, 103, 32, 26, 65, 4, 108, 6, 15, 83, 109, 55, 108, 72, 108, 47, 108, 0, 13, 81, 102, 101, 108, 97, 100, 97, 116, 97, 32, 35, 65, 4, 108, 6, 15, 65, 115, 72, 39, 91, 112, 47, 114, 91, 39, 49, 0, 13, 81, 109, 195, 179, 100, 111, 115, 195, 173, 116, 195, 161, 115, 111, 107, 32, 25, 65, 4, 108, 6, 15, 83, 109, 55, 111, 55, 109, 47, 0, 13, 81, 102, 101, 108, 195, 188, 108, 101, 116, 32, 28, 65, 4, 108, 6, 15, 47, 108, 71, 55, 109, 47, 107, 109, 88, 0, 13, 81, 116, 97, 98, 108, 101, 116, 104, 101, 122, 32, 23, 65, 4, 108, 6, 15, 89, 37, 50, 47, 109, 47, 0, 13, 81, 115, 122, 105, 110, 116, 101, 116, 32, 28, 65, 4, 108, 6, 15, 49, 113, 89, 111, 55, 113, 49, 0, 13, 81, 107, 195, 169, 115, 122, 195, 188, 108, 195, 169, 107, 32, 22, 65, 4, 108, 6, 15, 65, 39, 71, 37, 55, 47, 0, 13, 81, 109, 111, 98, 105, 108, 116, 32, 24, 65, 4, 108, 6, 15, 47, 109, 55, 109, 83, 39, 50, 0, 13, 81, 116, 101, 108, 101, 102, 111, 110, 32, 24, 65, 4, 108, 6, 15, 49, 113, 88, 71, 118, 55, 0, 13, 81, 107, 195, 169, 122, 98, 197, 145, 108, 32, 17, 65, 4, 108, 6, 15, 91, 114, 52, 0, 13, 81, 115, 195, 161, 114, 32, 22, 65, 4, 108, 6, 15, 107, 39, 50, 55, 108, 48, 0, 13, 81, 104, 111, 110, 108, 97, 112, 32, 40, 65, 4, 108, 6, 15, 48, 52, 109, 88, 109, 50, 47, 114, 55, 114, 91, 50, 108, 49, 0, 13, 81, 112, 114, 101, 122, 101, 110, 116, 195, 161, 108, 195, 161, 115, 110, 97, 107, 32, 24, 65, 4, 108, 6, 15, 83, 109, 55, 108, 72, 108, 47, 0, 13, 81, 102, 101, 108, 97, 100, 97, 116, 32, 27, 65, 4, 108, 6, 15, 89, 109, 34, 84, 109, 88, 109, 47, 0, 13, 81, 115, 122, 101, 114, 118, 101, 122, 101, 116, 32, 26, 65, 4, 108, 6, 15, 107, 108, 47, 115, 91, 114, 81, 0, 13, 81, 104, 97, 116, 195, 179, 115, 195, 161, 103, 32, 26, 65, 4, 108, 6, 15, 49, 110, 55, 47, 118, 52, 109, 0, 13, 81, 107, 195, 182, 108, 116, 197, 145, 114, 101, 32, 22, 65, 4, 108, 6, 15, 47, 37, 47, 49, 39, 47, 0, 13, 81, 116, 105, 116, 107, 111, 116, 32, 24, 65, 4, 108, 6, 15, 84, 114, 55, 108, 89, 47, 0, 13, 81, 118, 195, 161, 108, 97, 115, 122, 116, 32, 24, 65, 4, 108, 6, 15, 81, 113, 48, 113, 52, 109, 0, 13, 81, 103, 195, 169, 112, 195, 169, 114, 101, 32, 39, 65, 4, 108, 6, 15, 55, 109, 81, 83, 39, 50, 47, 39, 91, 108, 71, 50, 108, 49, 0, 13, 81, 108, 101, 103, 102, 111, 110, 116, 111, 115, 97, 98, 98, 110, 97, 107, 32, 41, 65, 4, 108, 6, 15, 49, 37, 57, 109, 55, 109, 50, 47, 113, 91, 109, 72, 12, 109, 55, 0, 13, 81, 107, 105, 106, 101, 108, 101, 110, 116, 195, 169, 115, 101, 100, 100, 101, 108, 32, 32, 65, 4, 108, 6, 15, 49, 113, 48, 84, 37, 91, 109, 55, 118, 49, 0, 13, 81, 107, 195, 169, 112, 118, 105, 115, 101, 108, 197, 145, 107, 32, 31, 65, 4, 108, 6, 15, 49, 109, 52, 111, 55, 109, 47, 71, 109, 50, 0, 13, 81, 107, 101, 114, 195, 188, 108, 101, 116, 98, 101, 110, 32, 28, 65, 4, 108, 6, 15, 52, 109, 50, 119, 109, 52, 71, 109, 0, 13, 81, 114, 101, 110, 100, 115, 122, 101, 114, 98, 101, 32, 29, 65, 4, 108, 6, 15, 52, 109, 50, 119, 109, 52, 113, 47, 0, 13, 81, 114, 101, 110, 100, 115, 122, 101, 114, 195, 169, 116, 32, 26, 65, 4, 108, 6, 15, 72, 39, 55, 81, 39, 49, 108, 47, 0, 13, 81, 100, 111, 108, 103, 111, 107, 97, 116, 32, 42, 65, 4, 108, 6, 15, 107, 39, 88, 88, 114, 89, 115, 55, 114, 91, 39, 49, 108, 47, 0, 13, 81, 104, 111, 122, 122, 195, 161, 115, 122, 195, 179, 108, 195, 161, 115, 111, 107, 97, 116, 32, 23, 65, 4, 108, 6, 15, 50, 113, 48, 50, 109, 49, 0, 13, 81, 110, 195, 169, 112, 110, 101, 107, 32, 28, 65, 4, 108, 6, 15, 83, 109, 55, 114, 55, 12, 114, 91, 0, 13, 81, 102, 101, 108, 195, 161, 108, 108, 195, 161, 115, 32, 31, 65, 4, 108, 6, 15, 84, 113, 55, 109, 65, 113, 67, 109, 65, 0, 13, 81, 118, 195, 169, 108, 101, 109, 195, 169, 110, 121, 101, 109, 32, 27, 65, 4, 108, 6, 15, 48, 52, 39, 71, 55, 113, 65, 108, 0, 13, 81, 112, 114, 111, 98, 108, 195, 169, 109, 97, 32, 36, 65, 4, 108, 6, 15, 83, 109, 57, 55, 109, 89, 47, 118, 49, 50, 109, 49, 0, 13, 81, 102, 101, 106, 108, 101, 115, 122, 116, 197, 145, 107, 110, 101, 107, 32, 23, 65, 4, 108, 6, 15, 119, 113, 55, 23, 108, 88, 0, 13, 82, 99, 195, 169, 108, 32, 97, 122, 32, 18, 65, 4, 108, 6, 15, 107, 37, 71, 108, 0, 13, 81, 104, 105, 98, 97, 32, 28, 65, 4, 108, 6, 15, 47, 108, 52, 47, 108, 55, 65, 108, 47, 0, 13, 81, 116, 97, 114, 116, 97, 108, 109, 97, 116, 32, 17, 65, 4, 108, 6, 15, 119, 112, 65, 0, 13, 81, 99, 195, 173, 109, 32, 22, 65, 4, 108, 6, 15, 72, 39, 55, 81, 39, 47, 0, 13, 81, 100, 111, 108, 103, 111, 116, 32, 25, 65, 4, 108, 6, 15, 107, 115, 50, 108, 48, 39, 49, 0, 13, 81, 104, 195, 179, 110, 97, 112, 111, 107, 32, 19, 65, 4, 108, 6, 15, 83, 110, 55, 72, 0, 13, 81, 102, 195, 182, 108, 100, 32, 30, 65, 4, 108, 6, 15, 49, 113, 52, 72, 113, 91, 23, 108, 88, 0, 13, 82, 107, 195, 169, 114, 100, 195, 169, 115, 32, 97, 122, 32, 32, 65, 4, 108, 6, 15, 76, 108, 55, 114, 72, 39, 49, 50, 108, 49, 0, 13, 81, 99, 115, 97, 108, 195, 161, 100, 111, 107, 110, 97, 107, 32, 24, 65, 4, 108, 6, 15, 47, 52, 109, 50, 72, 109, 47, 0, 13, 81, 116, 114, 101, 110, 100, 101, 116, 32, 26, 65, 4, 108, 6, 15, 47, 40, 72, 108, 47, 71, 108, 50, 0, 13, 81, 116, 117, 100, 97, 116, 98, 97, 110, 32, 33, 65, 4, 108, 6, 15, 65, 109, 81, 39, 55, 72, 114, 91, 12, 108, 55, 0, 13, 81, 109, 101, 103, 111, 108, 100, 195, 161, 115, 115, 97, 108, 32, 30, 65, 4, 108, 6, 15, 89, 108, 49, 108, 72, 113, 49, 39, 47, 0, 13, 81, 115, 122, 97, 107, 97, 100, 195, 169, 107, 111, 116, 32, 28, 65, 4, 108, 6, 15, 107, 109, 57, 88, 109, 47, 113, 47, 0, 13, 81, 104, 101, 108, 121, 122, 101, 116, 195, 169, 116, 32, 30, 65, 4, 108, 6, 15, 84, 114, 55, 108, 89, 39, 49, 108, 47, 0, 13, 81, 118, 195, 161, 108, 97, 115, 122, 111, 107, 97, 116, 32, 27, 65, 4, 108, 6, 15, 72, 39, 107, 114, 67, 88, 115, 0, 13, 81, 100, 111, 104, 195, 161, 110, 121, 122, 195, 179, 32, 36, 65, 4, 108, 6, 15, 72, 39, 107, 114, 67, 88, 114, 91, 34, 115, 55, 0, 13, 81, 100, 111, 104, 195, 161, 110, 121, 122, 195, 161, 115, 114, 195, 179, 108, 32, 31, 65, 4, 108, 6, 15, 72, 39, 107, 114, 67, 88, 114, 91, 47, 0, 13, 81, 100, 111, 104, 195, 161, 110, 121, 122, 195, 161, 115, 116, 32, 21, 65, 4, 108, 6, 15, 83, 113, 52, 83, 37, 0, 13, 81, 102, 195, 169, 114, 102, 105, 32, 26, 65, 4, 108, 6, 15, 57, 110, 84, 118, 71, 109, 50, 0, 13, 81, 106, 195, 182, 118, 197, 145, 98, 101, 110, 32, 28, 65, 4, 108, 6, 15, 71, 111, 50, 47, 109, 47, 113, 91, 0, 13, 81, 98, 195, 188, 110, 116, 101, 116, 195, 169, 115, 32, 22, 65, 4, 108, 6, 15, 91, 39, 52, 71, 108, 50, 0, 13, 81, 115, 111, 114, 98, 97, 110, 32, 21, 65, 4, 108, 6, 15, 47, 110, 65, 109, 81, 0, 13, 81, 116, 195, 182, 109, 101, 103, 32, 20, 65, 4, 108, 6, 15, 91, 39, 52, 71, 108, 0, 13, 81, 115, 111, 114, 98, 97, 32, 22, 65, 4, 108, 10, 6, 15, 107, 109, 57, 109, 47, 0, 13, 81, 104, 101, 108, 121, 101, 116, 32, 28, 65, 4, 108, 6, 15, 49, 113, 52, 72, 113, 91, 109, 65, 0, 13, 81, 107, 195, 169, 114, 100, 195, 169, 115, 101, 109, 32, 23, 65, 4, 108, 6, 15, 65, 113, 52, 81, 109, 47, 0, 13, 81, 109, 195, 169, 114, 103, 101, 116, 32, 24, 65, 4, 108, 6, 15, 49, 113, 52, 72, 113, 91, 0, 13, 81, 107, 195, 169, 114, 100, 195, 169, 115, 32, 26, 65, 4, 108, 6, 15, 84, 108, 55, 115, 91, 114, 81, 0, 13, 81, 118, 97, 108, 195, 179, 115, 195, 161, 103, 32, 29, 65, 4, 108, 6, 15, 49, 110, 55, 76, 113, 81, 109, 47, 0, 13, 81, 107, 195, 182, 108, 116, 115, 195, 169, 103, 101, 116, 32, 26, 65, 4, 108, 6, 15, 89, 109, 52, 84, 109, 88, 118, 0, 13, 81, 115, 122, 101, 114, 118, 101, 122, 197, 145, 32, 29, 65, 4, 108, 6, 15, 107, 39, 50, 55, 108, 48, 57, 114, 50, 0, 13, 81, 104, 111, 110, 108, 97, 112, 106, 195, 161, 110, 32, 33, 65, 4, 108, 6, 15, 83, 109, 55, 47, 113, 47, 109, 55, 12, 109, 55, 0, 13, 81, 102, 101, 108, 116, 195, 169, 116, 101, 108, 108, 101, 108, 32, 31, 65, 4, 108, 6, 15, 49, 37, 47, 113, 47, 109, 55, 12, 109, 55, 0, 13, 81, 107, 105, 116, 195, 169, 116, 101, 108, 108, 101, 108, 32, 28, 65, 4, 108, 6, 15, 72, 110, 50, 47, 113, 91, 52, 109, 0, 13, 81, 100, 195, 182, 110, 116, 195, 169, 115, 114, 101, 32, 29, 65, 4, 108, 6, 15, 89, 110, 84, 109, 76, 12, 113, 81, 0, 13, 81, 115, 122, 195, 182, 118, 101, 116, 115, 195, 169, 103, 32, 30, 65, 4, 108, 6, 15, 89, 110, 84, 109, 76, 12, 113, 81, 0, 13, 81, 115, 122, 195, 182, 118, 101, 116, 116, 115, 195, 169, 103, 32, 21, 65, 4, 108, 6, 15, 119, 113, 61, 57, 108, 0, 13, 81, 99, 195, 169, 108, 106, 97, 32, 43, 65, 4, 108, 6, 15, 65, 109, 81, 89, 39, 52, 112, 47, 114, 91, 39, 49, 71, 108, 50, 0, 13, 81, 109, 101, 103, 115, 122, 111, 114, 195, 173, 116, 195, 161, 115, 111, 107, 98, 97, 110, 32, 23, 65, 4, 108, 6, 15, 67, 40, 81, 108, 47, 37, 0, 13, 81, 110, 121, 117, 103, 97, 116, 105, 32, 47, 65, 4, 108, 6, 15, 49, 110, 88, 110, 50, 91, 113, 81, 23, 91, 39, 52, 108, 37, 71, 108, 50, 0, 13, 82, 107, 195, 182, 122, 195, 182, 110, 115, 195, 169, 103, 32, 115, 111, 114, 97, 105, 98, 97, 110, 32, 23, 65, 4, 108, 6, 15, 107, 109, 57, 88, 109, 47, 0, 13, 81, 104, 101, 108, 121, 122, 101, 116, 32, 23, 65, 4, 108, 6, 15, 65, 113, 52, 55, 109, 81, 0, 13, 81, 109, 195, 169, 114, 108, 101, 103, 32, 26, 65, 4, 108, 6, 15, 47, 109, 52, 84, 109, 88, 109, 47, 0, 13, 81, 116, 101, 114, 118, 101, 122, 101, 116, 32, 28, 65, 4, 108, 6, 15, 107, 108, 55, 81, 108, 47, 115, 49, 0, 13, 81, 104, 97, 108, 108, 103, 97, 116, 195, 179, 107, 32, 49, 65, 4, 108, 6, 15, 49, 39, 52, 114, 71, 12, 37, 23, 109, 55, 49, 113, 48, 88, 109, 55, 113, 91, 0, 13, 82, 107, 111, 114, 195, 161, 98, 98, 105, 32, 101, 108, 107, 195, 169, 112, 122, 101, 108, 195, 169, 115, 32, 30, 65, 4, 108, 6, 15, 107, 114, 47, 12, 113, 52, 71, 109, 50, 0, 13, 81, 104, 195, 161, 116, 116, 195, 169, 114, 98, 101, 110, 32, 36, 65, 4, 108, 6, 15, 49, 110, 55, 76, 113, 81, 109, 49, 52, 118, 55, 0, 13, 81, 107, 195, 182, 108, 116, 115, 195, 169, 103, 101, 107, 114, 197, 145, 108, 32, 32, 65, 4, 108, 6, 23, 107, 108, 55, 81, 108, 47, 115, 50, 108, 49, 0, 13, 81, 104, 97, 108, 108, 103, 97, 116, 195, 179, 110, 97, 107, 32, 28, 65, 4, 108, 6, 15, 84, 114, 55, 47, 39, 88, 114, 91, 0, 13, 81, 118, 195, 161, 108, 116, 111, 122, 195, 161, 115, 32, 28, 65, 4, 108, 6, 15, 49, 113, 52, 72, 113, 91, 52, 109, 0, 13, 81, 107, 195, 169, 114, 100, 195, 169, 115, 114, 101, 32, 37, 65, 4, 108, 6, 15, 79, 115, 79, 89, 109, 52, 109, 49, 113, 52, 47, 0, 13, 81, 103, 121, 195, 179, 103, 121, 115, 122, 101, 114, 101, 107, 195, 169, 114, 116, 32, 24, 65, 4, 108, 6, 15, 71, 109, 47, 109, 81, 109, 49, 0, 13, 81, 98, 101, 116, 101, 103, 101, 107, 32, 78, 65, 4, 108, 6, 15, 71, 109, 47, 109, 81, 109, 49, 50, 109, 49, 23, 108, 6, 15, 79, 115, 79, 89, 109, 52, 47, 114, 65, 39, 81, 108, 47, 114, 91, 114, 47, 0, 13, 83, 98, 101, 116, 101, 103, 101, 107, 110, 101, 107, 32, 97, 32, 103, 121, 195, 179, 103, 121, 115, 122, 101, 114, 116, 195, 161, 109, 111, 103, 97, 116, 195, 161, 115, 195, 161, 116, 32, 20, 65, 4, 108, 6, 15, 47, 113, 67, 47, 0, 13, 81, 116, 195, 169, 110, 121, 116, 32, 26, 65, 4, 108, 6, 15, 72, 112, 57, 108, 88, 114, 91, 0, 13, 81, 100, 195, 173, 106, 97, 122, 195, 161, 115, 32, 26, 65, 4, 108, 6, 15, 67, 39, 65, 39, 88, 115, 49, 0, 13, 81, 110, 121, 111, 109, 111, 122, 195, 179, 107, 32, 35, 65, 4, 108, 6, 15, 83, 109, 55, 109, 55, 118, 91, 113, 81, 109, 47, 0, 13, 81, 102, 101, 108, 101, 108, 197, 145, 115, 115, 195, 169, 103, 101, 116, 32, 21, 65, 4, 108, 6, 15, 47, 111, 88, 109, 47, 0, 13, 81, 116, 195, 188, 122, 101, 116, 32, 26, 65, 4, 108, 6, 15, 47, 113, 65, 114, 71, 108, 50, 0, 13, 81, 116, 195, 169, 109, 195, 161, 98, 97, 110, 32, 25, 65, 4, 108, 6, 15, 83, 109, 55, 109, 55, 118, 91, 0, 13, 81, 102, 101, 108, 101, 108, 197, 145, 115, 32, 34, 65, 4, 108, 6, 15, 49, 113, 52, 72, 113, 91, 109, 49, 71, 109, 50, 0, 13, 81, 107, 195, 169, 114, 100, 195, 169, 115, 101, 107, 98, 101, 110, 32, 26, 65, 4, 108, 6, 15, 72, 39, 55, 81, 39, 72, 108, 47, 0, 13, 81, 100, 111, 108, 103, 111, 100, 97, 116, 32, 30, 65, 4, 108, 6, 23, 107, 108, 79, 39, 65, 108, 12, 67, 47, 0, 13, 81, 104, 97, 103, 121, 111, 109, 195, 161, 110, 121, 116, 32, 16, 65, 4, 108, 6, 15, 91, 39, 49, 0, 13, 81, 115, 111, 107, 32, 34, 65, 4, 108, 6, 15, 49, 113, 48, 109, 91, 12, 113, 81, 109, 37, 47, 0, 13, 81, 107, 195, 169, 112, 101, 115, 115, 195, 169, 103, 101, 105, 116, 32, 35, 65, 4, 108, 6, 15, 83, 109, 55, 107, 108, 89, 50, 114, 55, 115, 47, 0, 13, 81, 102, 101, 108, 104, 97, 115, 122, 110, 195, 161, 108, 195, 179, 116, 32, 18, 65, 4, 108, 6, 15, 119, 37, 49, 12, 0, 13, 81, 99, 105, 107, 107, 32, 33, 65, 4, 108, 6, 15, 83, 114, 57, 55, 57, 108, 37, 50, 49, 108, 47, 0, 13, 81, 102, 195, 161, 106, 108, 106, 97, 105, 110, 107, 97, 116, 32, 41, 65, 4, 108, 6, 15, 83, 109, 55, 107, 108, 89, 50, 114, 55, 115, 49, 50, 108, 49, 0, 13, 81, 102, 101, 108, 104, 97, 115, 122, 110, 195, 161, 108, 195, 179, 107, 110, 97, 107, 32, 36, 65, 4, 108, 6, 23, 91, 111, 57, 57, 109, 89, 47, 118, 71, 109, 50, 0, 13, 81, 115, 195, 188, 108, 108, 121, 101, 115, 122, 116, 197, 145, 98, 101, 110, 32, 28, 65, 4, 108, 6, 23, 83, 109, 57, 55, 118, 72, 113, 91, 0, 13, 81, 102, 101, 106, 108, 197, 145, 100, 195, 169, 115, 32, 26, 65, 4, 108, 6, 23, 52, 109, 50, 119, 109, 52, 47, 0, 13, 81, 114, 101, 110, 100, 115, 122, 101, 114, 116, 32, 30, 65, 4, 108, 6, 15, 55, 113, 81, 65, 39, 88, 81, 114, 91, 0, 13, 81, 108, 195, 169, 103, 109, 111, 122, 103, 195, 161, 115, 32, 23, 65, 4, 108, 6, 9, 15, 49, 109, 55, 109, 47, 37, 0, 13, 81, 107, 101, 108, 101, 116, 105, 32, 20, 65, 4, 108, 6, 9, 15, 72, 113, 55, 37, 0, 13, 81, 100, 195, 169, 108, 105, 32, 27, 65, 4, 108, 6, 15, 72, 39, 49, 47, 39, 52, 50, 118, 0, 13, 81, 100, 111, 107, 116, 111, 114, 110, 197, 145, 32, 29, 65, 4, 108, 6, 23, 89, 49, 52, 37, 48, 47, 71, 109, 50, 0, 13, 81, 115, 122, 107, 114, 105, 112, 116, 98, 101, 110, 32, 40, 65, 4, 108, 6, 23, 83, 109, 55, 108, 72, 108, 47, 39, 47, 23, 49, 108, 48, 57, 108, 0, 13, 82, 102, 101, 108, 97, 100, 97, 116, 111, 116, 32, 107, 97, 112, 106, 97, 32, 30, 65, 4, 108, 6, 23, 49, 110, 84, 109, 47, 49, 109, 88, 118, 0, 13, 81, 107, 195, 182, 118, 101, 116, 107, 101, 122, 197, 145, 32, 28, 65, 4, 108, 6, 23, 84, 114, 55, 47, 114, 91, 39, 50, 0, 13, 81, 118, 195, 161, 108, 116, 195, 161, 115, 111, 110, 32, 21, 65, 4, 108, 6, 15, 83, 109, 55, 107, 118, 0, 13, 81, 102, 101, 108, 104, 197, 145, 32, 24, 65, 4, 108, 6, 23, 52, 109, 50, 119, 109, 52, 0, 13, 81, 114, 101, 110, 100, 115, 122, 101, 114, 32, 34, 65, 4, 108, 6, 15, 49, 37, 47, 110, 55, 47, 113, 91, 49, 39, 52, 0, 13, 81, 107, 105, 116, 195, 182, 108, 116, 195, 169, 115, 107, 111, 114, 32, 38, 65, 4, 108, 6, 15, 83, 109, 57, 55, 109, 89, 47, 113, 91, 109, 49, 109, 47, 0, 13, 81, 102, 101, 106, 108, 101, 115, 122, 116, 195, 169, 115, 101, 107, 101, 116, 32, 32, 65, 4, 108, 6, 15, 49, 37, 47, 110, 55, 47, 118, 84, 109, 55, 0, 13, 81, 107, 105, 116, 195, 182, 108, 116, 197, 145, 118, 101, 108, 32, 32, 65, 4, 108, 6, 15, 49, 113, 52, 72, 113, 91, 109, 49, 52, 109, 0, 13, 81, 107, 195, 169, 114, 100, 195, 169, 115, 101, 107, 114, 101, 32, 31, 65, 4, 108, 6, 15, 49, 113, 52, 72, 118, 112, 84, 109, 47, 0, 13, 81, 107, 195, 169, 114, 100, 197, 145, 195, 173, 118, 101, 116, 32, 20, 65, 4, 108, 6, 15, 50, 108, 48, 39, 47, 0, 13, 81, 110, 97, 112, 111, 116, 32, 21, 65, 4, 108, 6, 15, 48, 113, 50, 89, 47, 0, 13, 81, 112, 195, 169, 110, 122, 116, 32, 31, 65, 4, 108, 6, 15, 49, 113, 52, 113, 91, 113, 84, 109, 55, 0, 13, 81, 107, 195, 169, 114, 195, 169, 115, 195, 169, 118, 101, 108, 32, 38, 65, 4, 108, 6, 15, 65, 37, 50, 37, 89, 47, 109, 52, 109, 55, 50, 110, 49, 0, 13, 81, 109, 105, 110, 105, 115, 122, 116, 101, 114, 101, 108, 110, 195, 182, 107, 32, 34, 65, 4, 108, 6, 107, 118, 65, 113, 52, 91, 113, 49, 55, 109, 47, 0, 13, 81, 104, 197, 145, 109, 195, 169, 114, 115, 195, 169, 107, 108, 101, 116, 32, 23, 65, 4, 108, 6, 15, 55, 109, 84, 109, 81, 118, 0, 13, 81, 108, 101, 118, 101, 103, 197, 145, 32, 27, 65, 4, 108, 6, 15, 83, 109, 55, 107, 118, 88, 109, 47, 0, 13, 81, 102, 101, 108, 104, 197, 145, 122, 101, 116, 32, 35, 65, 4, 108, 6, 15, 49, 111, 55, 110, 50, 71, 91, 113, 81, 109, 47, 0, 13, 81, 107, 195, 188, 108, 195, 182, 110, 98, 115, 195, 169, 103, 101, 116, 32, 23, 65, 4, 108, 6, 15, 83, 109, 50, 113, 71, 109, 0, 13, 81, 102, 101, 110, 195, 169, 98, 101, 32, 20, 65, 4, 108, 6, 15, 72, 39, 55, 39, 81, 0, 13, 81, 100, 111, 108, 111, 103, 32, 21, 65, 4, 108, 6, 15, 107, 109, 57, 109, 72, 0, 13, 81, 104, 101, 108, 121, 101, 100, 32, 21, 65, 4, 108, 6, 15, 81, 113, 48, 109, 50, 0, 13, 81, 103, 195, 169, 112, 101, 110, 32, 30, 65, 4, 108, 6, 23, 48, 52, 39, 71, 55, 113, 65, 114, 65, 0, 13, 81, 112, 114, 111, 98, 108, 195, 169, 109, 195, 161, 109, 32, 17, 142, 20, 5, 12, 5, 16, 195, 173, 20, 195, 169, 19, 19, 5, 12, 13, 9, 198, 41, 85, 1, 48, 243, 64, 13, 9, 134, 16, 1, 3, 195, 161, 20, 13, 9, 198, 24, 84, 218, 20, 113, 84, 13, 9, 198, 60, 197, 129, 76, 243, 64, 13, 9, 134, 13, 1, 7, 195, 161, 20, 13, 5, 193, 4, 72, 12, 22, 65, 4, 108, 67, 67, 37, 15, 65, 6, 37, 50, 47, 0, 25, 83, 46, 32, 109, 32, 46, 32, 0, 9, 198, 77, 161, 77, 8, 83, 128, 13, 9, 198, 77, 161, 77, 8, 83, 128, 13, 0, 27, 67, 16, 240, 128, 72, 39, 71, 10, 6, 15, 48, 37, 108, 119, 52, 108, 0, 13, 81, 112, 105, 97, 99, 114, 97, 32, 11, 136, 11, 21, 12, 3, 19, 195, 161, 20, 13, 40, 11, 14, 195, 182, 22, 5, 12, 195, 169, 19, 5, 19, 50, 110, 84, 109, 55, 113, 91, 109, 91, 23, 47, 109, 89, 47, 109, 47, 0, 13, 81, 116, 101, 115, 122, 116, 101, 116, 32, 11, 200, 32, 17, 9, 24, 241, 207, 49, 144, 13, 10, 199, 80, 20, 148, 4, 195, 65, 44, 13, 6, 195, 64, 243, 148, 13, 0, 12, 137, 22, 9, 20, 195, 161, 10, 195, 161, 20, 13, 41, 12, 11, 15, 18, 18, 9, 7, 195, 161, 12, 195, 161, 19, 49, 39, 52, 52, 37, 81, 114, 55, 114, 91, 23, 52, 113, 84, 113, 50, 0, 13, 81, 114, 195, 169, 118, 195, 169, 110, 32, 12, 201, 80, 83, 5, 24, 243, 143, 44, 176, 76, 13, 13, 138, 22, 195, 161, 12, 15, 7, 1, 20, 14, 9, 13, 12, 201, 13, 51, 208, 61, 37, 15, 44, 176, 76, 13, 0, 6, 65, 8, 71, 113, 0, 14, 139, 4, 18, 195, 161, 7, 21, 12, 195, 161, 19, 1, 13, 22, 147, 13, 5, 7, 195, 161, 12, 12, 1, 16, 195, 173, 20, 195, 161, 19, 195, 161, 18, 1, 13, 13, 138, 2, 5, 14, 14, 195, 188, 14, 11, 5, 20, 13, 17, 142, 195, 169, 12, 5, 20, 20, 1, 18, 20, 1, 13, 195, 161, 20, 13, 13, 138, 13, 21, 14, 11, 195, 161, 10, 195, 161, 20, 13, 0, 23, 148, 22, 9, 19, 19, 26, 1, 195, 161, 12, 12, 195, 173, 20, 195, 161, 19, 195, 161, 18, 1, 13, 14, 139, 12, 5, 195, 173, 18, 195, 161, 19, 195, 161, 20, 13, 18, 143, 20, 5, 18, 8, 5, 19, 19, 195, 169, 7, 195, 188, 11, 5, 20, 13, 15, 140, 20, 195, 161, 13, 15, 7, 1, 20, 195, 161, 19, 1, 13, 9, 198, 33, 83, 12, 61, 69, 0, 13, 10, 135, 16, 195, 169, 14, 20, 5, 11, 20, 0, 15, 140, 11, 195, 169, 16, 22, 9, 19, 5, 12, 197, 145, 20, 13, 14, 139, 11, 9, 14, 195, 169, 26, 5, 20, 20, 5, 12, 13, 9, 134, 16, 195, 169, 12, 4, 1, 13, 9, 134, 11, 195, 182, 26, 20, 5, 13, 9, 134, 16, 195, 169, 12, 4, 1, 13, 15, 140, 10, 195, 161, 18, 1, 4, 195, 169, 11, 195, 161, 20, 13, 0, 11, 136, 13, 21, 14, 11, 195, 161, 19, 20, 13, 61, 13, 12, 5, 8, 5, 20, 197, 145, 19, 195, 169, 7, 5, 20, 55, 109, 107, 109, 47, 118, 91, 113, 81, 109, 47, 10, 6, 15, 65, 109, 81, 84, 108, 55, 115, 91, 112, 47, 108, 50, 37, 0, 13, 81, 109, 101, 103, 118, 97, 108, 195, 179, 115, 195, 173, 116, 97, 110, 105, 32, 19, 144, 14, 195, 169, 16, 19, 26, 195, 161, 13, 12, 195, 161, 12, 195, 161, 19, 13, 14, 139, 16, 18, 195, 179, 2, 195, 161, 12, 20, 1, 13, 13, 10, 135, 20, 195, 169, 20, 5, 12, 5, 13, 16, 141, 12, 5, 8, 5, 20, 197, 145, 19, 195, 169, 7, 5, 20, 13, 0, 6, 65, 12, 119, 113, 0, 9, 198, 24, 244, 132, 84, 195, 203, 13, 13, 138, 11, 195, 182, 22, 5, 20, 20, 195, 169, 11, 13, 10, 135, 13, 195, 169, 18, 20, 5, 14, 13, 11, 136, 19, 26, 195, 161, 14, 20, 1, 13, 13, 17, 142, 6, 5, 12, 5, 12, 197, 145, 19, 19, 195, 169, 7, 5, 20, 13, 8, 197, 44, 86, 132, 88, 80, 13, 0, 48, 73, 16, 242, 213, 52, 83, 148, 84, 212, 129, 72, 39, 49, 40, 65, 109, 50, 47, 40, 65, 52, 108, 23, 107, 37, 84, 108, 47, 49, 39, 88, 84, 108, 0, 13, 81, 104, 105, 118, 97, 116, 107, 111, 122, 118, 97, 32, 0, 9, 134, 195, 188, 26, 5, 13, 5, 13, 11, 4, 95, 8, 1, 3, 48, 37, 48, 108, 0, 0, 14, 139, 13, 1, 7, 25, 1, 18, 195, 161, 26, 20, 1, 13, 11, 136, 5, 12, 197, 145, 20, 20, 5, 4, 13, 11, 200, 77, 161, 82, 88, 86, 133, 80, 80, 13, 12, 137, 11, 5, 18, 5, 19, 20, 195, 169, 11, 13, 0, 6, 65, 16, 72, 113, 0, 15, 140, 1, 4, 15, 13, 195, 161, 14, 25, 15, 26, 20, 1, 13, 8, 197, 88, 148, 197, 49, 64, 13, 20, 145, 19, 26, 195, 161, 13, 195, 173, 20, 195, 179, 7, 195, 169, 16, 16, 5, 12, 13, 6, 195, 44, 147, 142, 13, 0, 27, 3, 58, 47, 47, 40, 107, 101, 116, 116, 197, 145, 115, 112, 111, 110, 116, 112, 101, 114, 112, 101, 114, 41, 0, 8, 29, 8, 133, 20, 195, 169, 13, 1, 13, 10, 135, 22, 195, 161, 18, 21, 14, 11, 13, 8, 133, 20, 195, 169, 13, 1, 13, 17, 142, 19, 26, 5, 18, 22, 5, 26, 5, 20, 11, 195, 169, 14, 20, 13, 9, 134, 20, 197, 145, 12, 5, 4, 13, 0, 13, 138, 2, 197, 145, 22, 195, 173, 20, 5, 14, 9, 13, 15, 140, 8, 15, 26, 26, 195, 161, 11, 5, 26, 4, 5, 11, 13, 9, 198, 40, 21, 129, 76, 195, 205, 13, 9, 198, 80, 20, 148, 4, 195, 205, 13, 0, 14, 139, 19, 26, 195, 161, 13, 195, 173, 20, 1, 14, 9, 13, 11, 200, 52, 81, 214, 21, 36, 197, 49, 64, 13, 10, 135, 14, 25, 195, 186, 12, 14, 9, 13, 10, 135, 195, 169, 18, 4, 5, 13, 5, 13, 11, 136, 19, 26, 195, 161, 14, 20, 1, 4, 13, 11, 136, 18, 5, 14, 4, 197, 145, 18, 20, 13, 0, 4, 193, 20, 72, 4, 193, 20, 14, 4, 193, 20, 72, 0, 8, 133, 195, 173, 18, 14, 9, 13, 9, 198, 56, 147, 131, 76, 83, 128, 13, 0, 10, 199, 48, 144, 197, 56, 49, 73, 80, 13, 10, 199, 32, 19, 12, 61, 69, 21, 44, 13, 15, 140, 12, 5, 6, 5, 4, 5, 20, 20, 19, 195, 169, 7, 13, 14, 4, 95, 48, 67, 15, 89, 114, 88, 108, 72, 37, 49, 0, 0, 0, 7, 65, 24, 109, 83, 83, 0, 8, 197, 20, 209, 76, 56, 144, 13, 11, 136, 22, 195, 161, 12, 1, 19, 26, 1, 13, 13, 138, 195, 161, 12, 12, 195, 173, 20, 21, 14, 11, 13, 0, 18, 143, 19, 26, 5, 13, 2, 5, 19, 195, 188, 12, 14, 9, 195, 188, 11, 13, 9, 198, 60, 179, 218, 61, 69, 0, 13, 0, 14, 139, 18, 195, 161, 2, 195, 182, 11, 195, 182, 20, 20, 13, 10, 135, 13, 1, 14, 21, 195, 161, 12, 13, 0, 45, 8, 195, 161, 12, 12, 1, 16, 15, 20, 114, 55, 12, 108, 48, 39, 47, 23, 57, 108, 84, 112, 47, 114, 91, 114, 52, 108, 0, 13, 81, 106, 97, 118, 195, 173, 116, 195, 161, 115, 195, 161, 114, 97, 32, 9, 134, 20, 195, 169, 12, 5, 14, 13, 11, 136, 195, 161, 12, 12, 1, 16, 15, 20, 13, 0, 6, 65, 28, 81, 113, 0, 16, 141, 20, 195, 182, 18, 22, 195, 169, 14, 25, 18, 197, 145, 12, 13, 46, 11, 9, 7, 195, 169, 14, 25, 5, 9, 8, 5, 26, 37, 81, 113, 67, 109, 37, 107, 109, 88, 23, 37, 81, 108, 88, 112, 47, 108, 50, 37, 0, 13, 81, 105, 103, 97, 122, 195, 173, 116, 97, 110, 105, 32, 20, 136, 5, 19, 26, 13, 195, 169, 10, 5, 13, 81, 104, 101, 118, 195, 173, 116, 105, 32, 10, 135, 14, 25, 15, 13, 195, 161, 14, 13, 0, 9, 198, 24, 147, 13, 20, 177, 84, 13, 11, 136, 6, 195, 161, 10, 12, 8, 15, 26, 13, 13, 138, 10, 21, 20, 20, 1, 20, 195, 161, 19, 20, 13, 0, 10, 199, 32, 21, 133, 72, 160, 73, 52, 13, 43, 6, 11, 195, 182, 26, 20, 9, 49, 110, 89, 47, 37, 23, 49, 111, 55, 110, 50, 71, 91, 113, 81, 109, 49, 0, 13, 81, 107, 195, 188, 108, 195, 182, 110, 98, 115, 195, 169, 103, 101, 107, 32, 28, 9, 7, 195, 169, 16, 5, 11, 8, 5, 26, 81, 113, 48, 109, 49, 107, 109, 88, 23, 37, 91, 0, 13, 81, 105, 115, 32, 53, 6, 11, 195, 182, 26, 20, 9, 49, 110, 89, 47, 37, 23, 50, 113, 88, 109, 47, 109, 55, 47, 113, 52, 113, 91, 109, 49, 109, 47, 0, 13, 81, 110, 195, 169, 122, 101, 116, 101, 108, 116, 195, 169, 114, 195, 169, 115, 101, 107, 101, 116, 32, 11, 136, 1, 11, 1, 18, 10, 195, 161, 11, 13, 10, 199, 16, 243, 7, 61, 166, 143, 56, 13, 10, 135, 14, 1, 16, 10, 195, 161, 20, 13, 17, 4, 95, 54, 48, 15, 107, 108, 47, 84, 108, 50, 108, 72, 37, 49, 0, 0, 38, 72, 44, 85, 133, 76, 80, 130, 20, 224, 49, 109, 84, 109, 91, 109, 71, 12, 109, 50, 10, 6, 15, 108, 50, 12, 114, 55, 0, 13, 81, 97, 110, 110, 195, 161, 108, 32, 17, 142, 11, 15, 14, 7, 18, 5, 19, 19, 26, 21, 19, 195, 161, 14, 13, 15, 140, 12, 195, 161, 20, 15, 7, 1, 20, 195, 161, 19, 20, 13, 0, 6, 65, 32, 107, 114, 0, 14, 67, 52, 196, 218, 109, 65, 109, 55, 109, 89, 0, 42, 42, 0, 47, 10, 195, 182, 19, 19, 26, 5, 7, 195, 169, 20, 110, 89, 12, 109, 81, 113, 47, 23, 83, 109, 55, 47, 111, 50, 47, 109, 91, 12, 109, 0, 13, 81, 102, 101, 108, 116, 195, 188, 110, 116, 101, 115, 115, 101, 32, 9, 134, 195, 169, 7, 5, 20, 20, 13, 8, 133, 20, 195, 169, 12, 9, 20, 0, 13, 138, 4, 195, 182, 14, 20, 195, 169, 19, 5, 9, 13, 10, 199, 44, 20, 8, 5, 67, 129, 44, 13, 15, 140, 20, 195, 161, 13, 15, 7, 1, 20, 10, 195, 161, 11, 13, 51, 71, 24, 145, 217, 20, 195, 69, 80, 83, 37, 79, 109, 55, 65, 109, 47, 23, 49, 109, 55, 12, 23, 83, 39, 52, 72, 112, 47, 108, 50, 37, 0, 13, 82, 107, 101, 108, 108, 32, 102, 111, 114, 100, 195, 173, 116, 97, 110, 105, 32, 10, 199, 24, 145, 217, 20, 195, 69, 80, 13, 15, 140, 2, 15, 19, 19, 26, 1, 14, 20, 195, 179, 1, 11, 13, 10, 199, 48, 18, 207, 76, 242, 193, 80, 13, 13, 138, 19, 26, 1, 11, 195, 173, 20, 1, 14, 9, 13, 10, 199, 24, 83, 22, 21, 66, 5, 80, 13, 10, 135, 14, 25, 15, 13, 195, 161, 20, 13, 0, 17, 1, 35, 49, 109, 47, 12, 118, 91, 49, 109, 52, 109, 89, 47, 0, 27, 16, 141, 9, 18, 195, 161, 14, 25, 195, 173, 20, 10, 195, 161, 11, 13, 15, 140, 14, 25, 195, 186, 10, 20, 195, 161, 19, 195, 161, 20, 13, 7, 132, 11, 195, 186, 20, 13, 7, 132, 3, 195, 169, 12, 13, 0, 45, 9, 22, 195, 161, 12, 12, 1, 12, 1, 20, 84, 114, 55, 12, 108, 55, 108, 47, 23, 49, 110, 88, 55, 109, 65, 113, 67, 109, 0, 13, 81, 107, 195, 182, 122, 108, 101, 109, 195, 169, 110, 121, 101, 32, 16, 141, 6, 15, 18, 13, 195, 161, 12, 195, 161, 19, 195, 161, 20, 13, 15, 140, 20, 5, 12, 10, 5, 19, 195, 173, 20, 5, 14, 9, 13, 15, 140, 20, 5, 12, 10, 5, 19, 195, 173, 20, 5, 14, 9, 13, 20, 145, 11, 195, 169, 19, 26, 195, 188, 12, 195, 169, 11, 195, 188, 14, 11, 5, 20, 13, 16, 141, 12, 5, 16, 1, 11, 15, 12, 195, 161, 19, 195, 161, 20, 13, 8, 197, 20, 210, 65, 81, 64, 13, 0, 24, 1, 37, 115, 122, 195, 161, 122, 97, 108, 195, 169, 107, 107, 97, 108, 0, 44, 29, 81, 107, 97, 108, 32, 12, 1, 37, 89, 114, 88, 108, 55, 113, 49, 0, 27, 13, 138, 11, 15, 18, 8, 1, 20, 195, 161, 18, 20, 13, 8, 197, 37, 0, 82, 8, 16, 13, 0, 7, 1, 38, 113, 91, 0, 27, 14, 139, 20, 5, 14, 4, 5, 14, 3, 9, 195, 161, 20, 13, 13, 138, 19, 195, 169, 18, 5, 12, 13, 5, 26, 9, 13, 9, 198, 40, 83, 5, 57, 68, 197, 13, 10, 199, 77, 163, 205, 8, 21, 9, 28, 22, 10, 199, 5, 81, 213, 77, 165, 21, 76, 20, 0, 12, 137, 6, 5, 12, 6, 15, 7, 195, 161, 19, 13, 19, 144, 18, 1, 20, 9, 6, 9, 11, 195, 161, 12, 195, 161, 19, 195, 161, 20, 13, 31, 68, 72, 18, 148, 4, 52, 108, 57, 47, 108, 23, 81, 113, 48, 109, 55, 50, 37, 0, 13, 81, 103, 195, 169, 112, 101, 108, 110, 105, 32, 57, 10, 11, 195, 169, 18, 4, 197, 145, 195, 173, 22, 49, 113, 52, 72, 118, 112, 84, 23, 84, 113, 55, 109, 65, 113, 67, 109, 88, 113, 91, 113, 52, 109, 0, 13, 81, 118, 195, 169, 108, 101, 109, 195, 169, 110, 121, 101, 122, 195, 169, 115, 195, 169, 114, 101, 32, 12, 137, 20, 1, 12, 195, 161, 12, 21, 14, 11, 13, 7, 196, 72, 18, 148, 4, 13, 0, 6, 65, 40, 57, 113, 0, 0, 11, 136, 6, 5, 2, 18, 21, 195, 161, 18, 20, 0, 11, 1, 42, 76, 37, 55, 55, 108, 81, 0, 27, 16, 141, 195, 161, 12, 12, 1, 13, 16, 15, 12, 7, 195, 161, 18, 13, 9, 198, 48, 84, 218, 60, 179, 137, 13, 13, 138, 3, 19, 9, 14, 195, 161, 12, 20, 1, 13, 13, 10, 199, 36, 225, 193, 80, 192, 78, 80, 13, 18, 143, 11, 195, 188, 12, 195, 182, 14, 2, 19, 195, 169, 7, 7, 5, 12, 13, 6, 195, 32, 246, 128, 13, 0, 9, 1, 43, 48, 55, 40, 89, 0, 27, 10, 135, 22, 195, 161, 18, 20, 1, 13, 13, 10, 135, 10, 195, 161, 18, 20, 1, 13, 13, 12, 137, 8, 9, 2, 195, 161, 26, 20, 1, 11, 13, 11, 136, 11, 195, 182, 26, 16, 15, 14, 20, 13, 0, 6, 65, 44, 49, 114, 0, 10, 135, 5, 19, 5, 20, 195, 169, 14, 13, 32, 8, 195, 169, 18, 5, 26, 20, 5, 13, 113, 52, 109, 89, 47, 109, 65, 23, 65, 108, 81, 108, 65, 0, 13, 81, 109, 97, 103, 97, 109, 32, 11, 136, 12, 5, 195, 173, 18, 20, 1, 13, 13, 15, 140, 13, 5, 12, 12, 195, 169, 11, 5, 12, 20, 5, 13, 13, 11, 136, 195, 169, 18, 5, 26, 20, 5, 13, 13, 8, 197, 48, 85, 20, 20, 176, 13, 10, 135, 5, 19, 5, 20, 195, 169, 14, 13, 8, 197, 44, 20, 14, 4, 176, 13, 0, 12, 137, 19, 195, 169, 18, 20, 5, 14, 195, 169, 13, 14, 139, 16, 18, 15, 2, 12, 195, 169, 13, 195, 161, 19, 13, 10, 135, 22, 195, 161, 12, 20, 1, 11, 13, 15, 140, 11, 195, 182, 18, 14, 25, 195, 169, 11, 195, 169, 14, 13, 15, 140, 11, 195, 182, 18, 14, 25, 195, 169, 11, 195, 169, 14, 22, 0, 10, 1, 46, 48, 2, 39, 50, 47, 0, 27, 10, 199, 32, 20, 131, 60, 195, 137, 4, 13, 7, 132, 3, 195, 169, 7, 13, 7, 195, 52, 84, 148, 72, 8, 0, 8, 1, 47, 48, 109, 52, 0, 27, 10, 135, 22, 195, 169, 4, 5, 14, 9, 13, 0, 7, 65, 48, 109, 55, 55, 0, 9, 198, 52, 17, 218, 5, 67, 203, 13, 8, 197, 32, 149, 5, 49, 64, 13, 8, 197, 44, 144, 211, 37, 64, 13, 13, 138, 19, 26, 5, 18, 5, 20, 14, 195, 169, 11, 13, 17, 1, 48, 50, 40, 55, 12, 114, 91, 47, 0, 44, 81, 32, 115, 116, 32, 20, 1, 48, 50, 40, 55, 12, 114, 52, 115, 55, 0, 44, 81, 32, 114, 195, 179, 108, 32, 15, 1, 48, 50, 40, 55, 12, 114, 50, 0, 44, 81, 32, 110, 32, 20, 1, 48, 50, 40, 55, 12, 114, 47, 115, 55, 0, 44, 81, 32, 116, 195, 179, 108, 32, 21, 1, 48, 50, 40, 55, 12, 114, 91, 39, 50, 0, 44, 81, 32, 195, 161, 115, 111, 110, 32, 19, 1, 48, 50, 40, 55, 12, 114, 71, 108, 0, 44, 81, 32, 195, 161, 98, 97, 32, 21, 1, 48, 50, 40, 55, 12, 114, 71, 108, 50, 0, 44, 81, 32, 195, 161, 98, 97, 110, 32, 16, 1, 48, 50, 40, 55, 12, 114, 50, 0, 44, 81, 32, 97, 110, 32, 16, 1, 48, 50, 40, 55, 12, 114, 47, 0, 44, 81, 32, 97, 116, 32, 22, 1, 48, 50, 40, 55, 12, 114, 47, 115, 55, 0, 44, 81, 32, 195, 161, 116, 195, 179, 108, 32, 17, 1, 48, 50, 40, 55, 12, 114, 47, 0, 44, 81, 32, 195, 161, 116, 32, 17, 1, 48, 50, 40, 55, 12, 114, 71, 108, 0, 44, 81, 32, 98, 97, 32, 19, 1, 48, 50, 40, 55, 12, 114, 71, 108, 50, 0, 44, 81, 32, 98, 97, 110, 32, 17, 1, 48, 50, 40, 55, 12, 114, 37, 81, 0, 44, 81, 32, 105, 103, 32, 17, 1, 48, 50, 40, 55, 12, 114, 50, 0, 44, 81, 32, 195, 161, 110, 32, 19, 1, 48, 50, 40, 55, 12, 114, 52, 108, 0, 44, 81, 32, 195, 161, 114, 97, 32, 19, 1, 48, 50, 40, 55, 12, 114, 91, 52, 108, 0, 44, 81, 32, 115, 114, 97, 32, 15, 1, 48, 50, 40, 55, 12, 114, 91, 0, 44, 81, 32, 115, 32, 19, 1, 48, 50, 40, 55, 12, 114, 107, 39, 88, 0, 44, 81, 32, 104, 111, 122, 32, 20, 1, 48, 50, 40, 55, 12, 114, 50, 114, 55, 0, 44, 81, 32, 110, 195, 161, 108, 32, 17, 1, 48, 50, 40, 55, 12, 114, 52, 108, 0, 44, 81, 32, 114, 97, 32, 19, 1, 48, 50, 40, 55, 12, 114, 84, 108, 55, 0, 44, 81, 32, 118, 97, 108, 32, 15, 1, 48, 50, 40, 55, 12, 114, 47, 0, 44, 81, 32, 116, 32, 17, 1, 48, 50, 40, 55, 12, 114, 91, 0, 44, 81, 32, 195, 161, 115, 32, 0, 14, 139, 22, 195, 169, 7, 26, 197, 145, 4, 20, 5, 11, 13, 8, 133, 13, 195, 169, 12, 25, 13, 17, 1, 49, 109, 79, 12, 109, 55, 0, 44, 81, 32, 103, 121, 101, 108, 32, 17, 1, 49, 109, 79, 12, 109, 91, 0, 44, 81, 32, 103, 121, 101, 115, 32, 17, 1, 49, 109, 79, 12, 109, 47, 0, 44, 81, 32, 103, 121, 101, 116, 32, 22, 1, 49, 101, 108, 115, 101, 106, 195, 169, 116, 0, 44, 21, 29, 81, 32, 106, 195, 169, 116, 32, 25, 1, 49, 101, 108, 115, 101, 106, 195, 169, 104, 101, 122, 0, 44, 21, 29, 81, 32, 195, 169, 104, 101, 122, 32, 21, 1, 49, 101, 108, 115, 101, 106, 101, 105, 0, 44, 21, 29, 81, 32, 105, 107, 101, 105, 32, 19, 1, 49, 101, 108, 115, 101, 106, 101, 0, 44, 21, 29, 81, 32, 105, 107, 101, 32, 20, 1, 49, 101, 108, 115, 101, 106, 101, 105, 0, 44, 21, 29, 81, 32, 105, 107, 105, 32, 27, 1, 49, 101, 108, 115, 101, 106, 195, 169, 110, 195, 169, 108, 0, 44, 21, 29, 81, 32, 195, 169, 110, 195, 169, 108, 32, 28, 1, 49, 101, 108, 115, 101, 106, 195, 169, 110, 195, 169, 108, 0, 44, 21, 29, 81, 32, 106, 195, 169, 110, 195, 169, 108, 32, 23, 1, 49, 101, 108, 115, 101, 106, 195, 169, 118, 101, 108, 0, 44, 21, 29, 81, 32, 118, 101, 108, 32, 25, 1, 49, 101, 108, 115, 101, 106, 195, 169, 110, 101, 107, 0, 44, 21, 29, 81, 32, 195, 169, 110, 101, 107, 32, 24, 1, 49, 101, 108, 115, 101, 106, 195, 169, 105, 103, 0, 44, 21, 29, 81, 32, 106, 195, 169, 105, 103, 32, 28, 1, 49, 101, 108, 115, 101, 106, 195, 169, 116, 197, 145, 108, 0, 44, 21, 29, 81, 32, 106, 195, 169, 116, 197, 145, 108, 32, 24, 1, 49, 101, 108, 115, 101, 106, 195, 169, 114, 101, 0, 44, 21, 29, 81, 32, 106, 195, 169, 114, 101, 32, 26, 1, 49, 101, 108, 115, 101, 106, 195, 169, 118, 101, 108, 0, 44, 21, 29, 81, 32, 106, 195, 169, 118, 101, 108, 32, 20, 1, 49, 101, 108, 115, 101, 106, 101, 105, 0, 44, 21, 29, 81, 32, 106, 101, 105, 32, 18, 1, 49, 101, 108, 115, 101, 106, 101, 0, 44, 21, 29, 81, 32, 106, 101, 32, 21, 1, 49, 101, 108, 115, 101, 106, 195, 169, 116, 0, 44, 21, 29, 81, 32, 195, 169, 116, 32, 27, 1, 49, 101, 108, 115, 101, 106, 195, 169, 116, 197, 145, 108, 0, 44, 21, 29, 81, 32, 195, 169, 116, 197, 145, 108, 32, 22, 1, 49, 101, 108, 115, 101, 106, 195, 169, 105, 103, 0, 44, 29, 81, 32, 195, 169, 105, 103, 32, 24, 1, 49, 101, 108, 115, 101, 106, 195, 169, 118, 101, 108, 0, 44, 29, 81, 32, 195, 169, 118, 101, 108, 32, 25, 1, 49, 101, 108, 115, 101, 106, 195, 169, 114, 197, 145, 108, 0, 44, 21, 29, 81, 32, 114, 197, 145, 108, 32, 27, 1, 49, 101, 108, 115, 101, 106, 195, 169, 114, 197, 145, 108, 0, 44, 21, 29, 81, 32, 195, 169, 114, 197, 145, 108, 32, 21, 1, 49, 101, 108, 115, 101, 106, 195, 169, 105, 103, 0, 44, 21, 29, 81, 32, 105, 103, 32, 25, 1, 49, 101, 108, 115, 101, 106, 195, 169, 116, 197, 145, 108, 0, 44, 21, 29, 81, 32, 116, 197, 145, 108, 32, 21, 1, 49, 101, 108, 115, 101, 106, 195, 169, 114, 101, 0, 44, 21, 29, 81, 32, 114, 101, 32, 23, 1, 49, 101, 108, 115, 101, 106, 195, 169, 114, 101, 0, 44, 21, 29, 81, 32, 195, 169, 114, 101, 32, 19, 1, 49, 101, 108, 115, 101, 106, 101, 105, 0, 44, 21, 29, 81, 32, 101, 105, 32, 18, 1, 49, 101, 108, 115, 101, 106, 101, 105, 0, 44, 21, 29, 81, 32, 105, 32, 22, 1, 49, 101, 108, 115, 101, 106, 195, 169, 110, 0, 44, 21, 29, 81, 32, 106, 195, 169, 110, 32, 21, 1, 49, 101, 108, 115, 101, 106, 195, 169, 110, 0, 44, 21, 29, 81, 32, 195, 169, 110, 32, 17, 1, 49, 101, 108, 115, 101, 106, 101, 0, 44, 21, 29, 81, 32, 101, 32, 0, 11, 136, 195, 179, 18, 195, 161, 11, 9, 7, 13, 13, 138, 10, 5, 12, 5, 14, 20, 5, 14, 195, 169, 13, 18, 1, 50, 49, 109, 47, 12, 118, 84, 109, 55, 0, 44, 81, 32, 101, 108, 32, 15, 1, 50, 49, 109, 47, 12, 118, 65, 0, 44, 81, 32, 109, 32, 15, 1, 50, 49, 109, 47, 12, 118, 50, 0, 44, 81, 32, 110, 32, 17, 1, 50, 49, 109, 47, 12, 118, 50, 0, 44, 81, 32, 197, 145, 110, 32, 17, 1, 50, 49, 109, 47, 12, 118, 47, 0, 44, 81, 32, 197, 145, 116, 32, 18, 1, 50, 49, 113, 119, 12, 109, 52, 0, 44, 81, 32, 115, 122, 101, 114, 32, 28, 1, 50, 109, 195, 161, 115, 111, 100, 105, 107, 195, 161, 116, 195, 179, 108, 0, 44, 21, 29, 81, 32, 116, 197, 145, 108, 32, 30, 1, 50, 109, 195, 161, 115, 111, 100, 105, 107, 195, 161, 116, 195, 179, 108, 0, 44, 21, 29, 81, 32, 195, 169, 116, 197, 145, 108, 32, 24, 1, 50, 109, 195, 161, 115, 111, 100, 105, 107, 195, 161, 105, 103, 0, 44, 21, 29, 81, 32, 105, 103, 32, 21, 1, 50, 109, 195, 161, 115, 111, 100, 105, 107, 97, 105, 0, 44, 21, 29, 81, 32, 105, 32, 0, 12, 137, 13, 15, 2, 9, 12, 3, 195, 169, 7, 13, 6, 131, 6, 197, 145, 13, 17, 1, 51, 107, 114, 52, 65, 108, 91, 0, 44, 81, 32, 109, 97, 115, 32, 15, 1, 51, 107, 114, 52, 65, 108, 47, 0, 44, 81, 32, 116, 32, 26, 1, 51, 107, 108, 52, 65, 108, 72, 37, 49, 12, 108, 55, 0, 44, 81, 32, 97, 100, 105, 107, 107, 97, 108, 32, 24, 1, 51, 107, 108, 52, 65, 108, 72, 37, 49, 39, 50, 0, 44, 81, 32, 97, 100, 105, 107, 111, 110, 32, 24, 1, 51, 107, 108, 52, 65, 108, 72, 37, 49, 108, 47, 0, 44, 81, 32, 97, 100, 105, 107, 97, 116, 32, 20, 1, 51, 107, 108, 52, 65, 108, 72, 37, 49, 0, 44, 81, 32, 97, 100, 105, 107, 32, 16, 1, 51, 107, 114, 52, 65, 39, 50, 0, 44, 81, 32, 111, 110, 32, 18, 1, 51, 107, 114, 52, 39, 65, 12, 108, 55, 0, 44, 81, 32, 97, 108, 32, 24, 1, 51, 104, 97, 114, 109, 97, 100, 105, 107, 195, 161, 105, 103, 0, 44, 21, 29, 81, 32, 105, 103, 32, 21, 1, 51, 107, 108, 52, 10, 65, 108, 72, 37, 49, 108, 37, 0, 44, 21, 81, 32, 105, 32, 0, 7, 65, 52, 109, 65, 65, 0, 45, 69, 60, 179, 218, 80, 16, 39, 49, 39, 89, 47, 108, 23, 48, 52, 39, 71, 55, 113, 65, 114, 49, 71, 115, 55, 0, 13, 81, 112, 114, 111, 98, 108, 195, 169, 109, 195, 161, 107, 98, 195, 179, 108, 32, 8, 197, 60, 179, 218, 80, 16, 13, 25, 1, 52, 50, 109, 79, 109, 72, 37, 49, 12, 109, 55, 0, 44, 81, 32, 101, 100, 105, 107, 107, 101, 108, 32, 23, 1, 52, 50, 109, 79, 109, 72, 37, 49, 109, 50, 0, 44, 81, 32, 101, 100, 105, 107, 101, 110, 32, 23, 1, 52, 50, 109, 79, 109, 72, 37, 49, 109, 47, 0, 44, 81, 32, 101, 100, 105, 107, 101, 116, 32, 19, 1, 52, 50, 109, 79, 109, 72, 37, 49, 0, 44, 81, 32, 101, 100, 105, 107, 32, 14, 1, 52, 50, 113, 79, 109, 47, 0, 44, 81, 32, 116, 32, 18, 1, 52, 50, 113, 79, 12, 109, 55, 0, 44, 81, 32, 103, 121, 101, 108, 32, 16, 1, 52, 50, 113, 79, 12, 109, 55, 0, 44, 81, 32, 101, 108, 32, 0, 40, 5, 11, 195, 169, 14, 5, 49, 113, 50, 109, 10, 6, 15, 84, 114, 55, 108, 89, 47, 108, 50, 39, 65, 0, 13, 81, 118, 195, 161, 108, 97, 115, 122, 116, 97, 110, 111, 109, 32, 31, 70, 20, 195, 65, 72, 17, 0, 109, 55, 65, 108, 52, 108, 72, 23, 108, 47, 12, 115, 55, 0, 13, 81, 97, 116, 116, 195, 179, 108, 32, 10, 135, 22, 195, 161, 12, 21, 14, 11, 13, 8, 133, 11, 195, 169, 14, 5, 13, 15, 1, 53, 110, 47, 12, 109, 55, 0, 44, 81, 32, 101, 108, 32, 18, 1, 53, 110, 119, 12, 110, 52, 0, 44, 81, 32, 115, 122, 195, 182, 114, 32, 13, 1, 53, 110, 47, 110, 47, 0, 44, 81, 32, 116, 32, 23, 1, 53, 110, 47, 110, 72, 37, 49, 113, 47, 118, 55, 0, 44, 21, 81, 32, 116, 197, 145, 108, 32, 15, 1, 53, 110, 47, 12, 109, 55, 0, 44, 81, 32, 101, 108, 32, 16, 1, 53, 110, 47, 12, 109, 55, 0, 44, 81, 32, 116, 101, 108, 32, 13, 7, 95, 35, 45, 195, 169, 9, 7, 113, 37, 81, 0, 0, 35, 7, 8, 195, 169, 20, 20, 5, 12, 107, 113, 47, 12, 109, 55, 23, 109, 88, 109, 55, 118, 47, 12, 0, 13, 81, 101, 122, 101, 108, 197, 145, 116, 116, 32, 10, 199, 20, 195, 69, 57, 65, 78, 36, 13, 10, 135, 195, 169, 18, 22, 5, 12, 20, 13, 10, 199, 32, 19, 12, 28, 21, 14, 36, 13, 6, 195, 52, 83, 148, 13, 18, 1, 54, 107, 108, 119, 12, 39, 52, 0, 44, 81, 32, 115, 122, 111, 114, 32, 24, 1, 54, 107, 108, 47, 39, 72, 37, 49, 114, 47, 115, 55, 0, 44, 21, 81, 32, 116, 195, 179, 108, 32, 18, 1, 54, 107, 108, 47, 12, 115, 55, 0, 44, 81, 32, 116, 195, 179, 108, 32, 17, 1, 54, 107, 108, 47, 12, 108, 55, 0, 44, 81, 32, 116, 97, 108, 32, 16, 1, 54, 107, 108, 47, 12, 108, 55, 0, 44, 81, 32, 97, 108, 32, 23, 1, 54, 104, 97, 116, 111, 100, 105, 107, 195, 161, 105, 103, 0, 44, 21, 29, 81, 32, 105, 103, 32, 19, 1, 54, 107, 108, 47, 39, 72, 37, 49, 108, 37, 0, 44, 21, 81, 32, 105, 32, 0, 31, 68, 80, 83, 142, 36, 47, 109, 50, 12, 37, 10, 6, 15, 108, 49, 108, 52, 114, 91, 0, 13, 81, 97, 107, 97, 114, 195, 161, 115, 32, 22, 68, 80, 83, 142, 36, 47, 109, 50, 12, 37, 23, 108, 89, 47, 0, 13, 81, 97, 122, 116, 32, 9, 134, 5, 19, 20, 195, 169, 14, 13, 7, 196, 80, 83, 142, 36, 13, 18, 1, 55, 107, 113, 119, 12, 109, 52, 0, 44, 81, 32, 115, 122, 101, 114, 32, 19, 1, 55, 107, 109, 47, 109, 91, 12, 109, 55, 0, 44, 81, 32, 115, 101, 108, 32, 22, 1, 55, 107, 109, 47, 109, 91, 109, 49, 52, 109, 0, 44, 81, 32, 115, 101, 107, 114, 101, 32, 16, 1, 55, 107, 113, 47, 12, 109, 55, 0, 44, 81, 32, 101, 108, 32, 17, 1, 55, 107, 113, 47, 12, 109, 55, 0, 44, 81, 32, 116, 101, 108, 32, 24, 1, 55, 107, 109, 47, 109, 72, 37, 49, 113, 47, 118, 55, 0, 44, 21, 81, 32, 116, 197, 145, 108, 32, 18, 1, 55, 107, 113, 47, 12, 118, 55, 0, 44, 81, 32, 116, 197, 145, 108, 32, 0, 7, 65, 56, 109, 50, 50, 0, 8, 197, 57, 147, 205, 60, 176, 13, 8, 197, 24, 17, 217, 56, 144, 13, 9, 134, 1, 11, 3, 9, 195, 179, 13, 8, 197, 88, 84, 218, 36, 176, 13, 10, 135, 22, 195, 169, 7, 195, 169, 14, 13, 7, 132, 195, 188, 7, 25, 13, 10, 135, 22, 195, 169, 7, 195, 169, 14, 20, 17, 1, 56, 67, 39, 55, 119, 12, 108, 55, 0, 44, 81, 32, 97, 108, 32, 18, 1, 56, 67, 39, 55, 119, 12, 108, 55, 0, 44, 81, 32, 99, 97, 108, 32, 25, 1, 56, 110, 121, 111, 108, 99, 97, 100, 105, 107, 195, 161, 105, 103, 0, 44, 21, 29, 81, 32, 105, 103, 32, 20, 1, 56, 67, 39, 55, 119, 108, 72, 37, 49, 108, 37, 0, 44, 21, 81, 32, 105, 32, 0, 51, 10, 22, 195, 161, 12, 1, 19, 26, 15, 12, 20, 84, 114, 55, 108, 89, 39, 55, 47, 23, 108, 6, 15, 83, 109, 55, 84, 109, 47, 113, 91, 52, 109, 0, 13, 82, 97, 32, 102, 101, 108, 118, 101, 116, 195, 169, 115, 114, 101, 32, 12, 137, 20, 1, 12, 195, 161, 12, 20, 1, 13, 13, 57, 15, 11, 195, 182, 20, 5, 12, 5, 26, 5, 20, 20, 19, 195, 169, 7, 49, 110, 47, 109, 55, 109, 88, 109, 76, 12, 113, 81, 23, 71, 37, 89, 47, 39, 91, 112, 47, 108, 50, 37, 0, 13, 81, 98, 105, 122, 116, 111, 115, 195, 173, 116, 97, 110, 105, 32, 10, 135, 20, 197, 177, 14, 20, 5, 11, 13, 19, 1, 57, 49, 37, 55, 109, 50, 119, 109, 47, 0, 44, 81, 32, 99, 101, 116, 32, 20, 1, 57, 49, 37, 55, 109, 50, 119, 12, 109, 55, 0, 44, 81, 32, 99, 101, 108, 32, 19, 1, 57, 49, 37, 55, 109, 50, 119, 12, 109, 55, 0, 44, 81, 32, 101, 108, 32, 0, 29, 10, 19, 26, 195, 161, 13, 15, 12, 20, 1, 13, 89, 114, 65, 39, 55, 47, 108, 65, 23, 49, 37, 0, 13, 81, 107, 105, 32, 10, 135, 26, 195, 161, 18, 21, 12, 20, 13, 10, 135, 2, 5, 19, 26, 195, 169, 12, 13, 9, 134, 2, 195, 173, 26, 22, 1, 13, 14, 139, 6, 5, 10, 12, 197, 145, 4, 195, 182, 20, 20, 13, 14, 139, 11, 5, 26, 4, 197, 145, 4, 195, 182, 20, 20, 13, 0, 12, 137, 5, 12, 20, 197, 177, 14, 20, 5, 11, 13, 7, 196, 77, 160, 71, 4, 13, 12, 137, 5, 10, 20, 5, 20, 20, 195, 169, 11, 13, 0, 36, 69, 80, 84, 212, 72, 80, 47, 109, 91, 47, 52, 109, 10, 6, 15, 89, 108, 71, 107, 108, 47, 115, 0, 13, 81, 115, 122, 97, 98, 104, 97, 116, 195, 179, 32, 38, 8, 5, 7, 25, 195, 188, 22, 195, 169, 109, 79, 12, 111, 84, 113, 23, 47, 108, 34, 47, 39, 88, 114, 91, 0, 13, 81, 116, 97, 114, 116, 111, 122, 195, 161, 115, 32, 9, 198, 13, 48, 80, 5, 67, 203, 13, 44, 12, 22, 1, 12, 195, 179, 19, 26, 195, 173, 14, 197, 177, 84, 108, 55, 115, 89, 112, 50, 117, 15, 10, 107, 37, 72, 109, 81, 109, 71, 12, 0, 13, 81, 104, 105, 100, 101, 103, 101, 98, 98, 32, 8, 197, 4, 64, 84, 60, 176, 13, 16, 141, 5, 12, 11, 5, 26, 4, 197, 145, 4, 195, 182, 20, 20, 13, 12, 137, 11, 9, 20, 195, 169, 20, 5, 12, 20, 13, 15, 140, 22, 1, 12, 195, 179, 19, 26, 195, 173, 14, 197, 177, 13, 16, 141, 10, 5, 12, 195, 182, 12, 195, 169, 19, 14, 195, 169, 12, 13, 0, 11, 1, 61, 109, 79, 109, 50, 55, 118, 0, 27, 18, 143, 6, 5, 12, 5, 12, 197, 145, 19, 19, 195, 169, 7, 195, 188, 11, 13, 17, 142, 13, 5, 7, 11, 5, 26, 4, 197, 145, 4, 195, 182, 20, 20, 13, 17, 142, 195, 169, 18, 4, 5, 11, 12, 197, 145, 4, 195, 182, 20, 20, 13, 0, 40, 9, 11, 195, 169, 16, 20, 5, 12, 5, 14, 49, 113, 48, 47, 109, 55, 109, 50, 23, 71, 109, 47, 109, 81, 50, 109, 49, 0, 13, 81, 98, 101, 116, 101, 103, 110, 101, 107, 32, 56, 13, 195, 169, 16, 195, 188, 12, 5, 20, 5, 11, 8, 5, 26, 113, 48, 111, 55, 109, 47, 109, 49, 107, 109, 88, 23, 107, 108, 89, 39, 50, 55, 112, 47, 39, 47, 12, 108, 0, 13, 81, 104, 97, 115, 111, 110, 108, 195, 173, 116, 111, 116, 116, 97, 32, 0, 45, 9, 20, 1, 12, 195, 161, 12, 20, 1, 11, 47, 108, 55, 114, 55, 47, 108, 49, 23, 108, 6, 15, 67, 39, 65, 39, 88, 115, 49, 0, 13, 82, 97, 32, 110, 121, 111, 109, 111, 122, 195, 179, 107, 32, 12, 137, 20, 1, 12, 195, 161, 12, 20, 1, 11, 13, 30, 9, 13, 5, 18, 195, 188, 12, 20, 5, 11, 65, 109, 52, 111, 55, 47, 109, 49, 23, 83, 109, 55, 0, 13, 81, 102, 101, 108, 32, 12, 137, 16, 195, 179, 26, 15, 12, 20, 1, 11, 13, 19, 144, 2, 9, 12, 12, 5, 14, 20, 25, 197, 177, 26, 5, 20, 20, 5, 12, 13, 14, 139, 9, 7, 1, 26, 7, 1, 20, 195, 179, 10, 1, 13, 11, 200, 72, 83, 132, 77, 161, 82, 8, 80, 13, 0, 10, 1, 64, 49, 40, 49, 108, 119, 0, 27, 6, 65, 64, 48, 113, 0, 13, 138, 19, 26, 195, 161, 13, 15, 12, 20, 1, 11, 13, 0, 13, 138, 11, 195, 169, 18, 195, 169, 19, 195, 169, 20, 13, 23, 5, 20, 195, 169, 14, 25, 47, 113, 67, 10, 6, 15, 91, 109, 65, 0, 13, 81, 115, 101, 109, 32, 42, 70, 77, 162, 78, 80, 83, 128, 89, 37, 50, 47, 109, 50, 23, 47, 109, 91, 47, 52, 109, 89, 108, 71, 50, 37, 0, 13, 81, 116, 101, 115, 116, 114, 101, 115, 122, 97, 98, 110, 105, 32, 9, 198, 77, 162, 78, 80, 83, 128, 13, 8, 133, 20, 195, 169, 14, 25, 13, 0, 14, 139, 20, 5, 13, 5, 20, 197, 145, 10, 195, 169, 20, 13, 17, 142, 13, 5, 7, 1, 12, 1, 16, 195, 173, 20, 195, 179, 10, 1, 13, 15, 140, 195, 169, 18, 20, 5, 19, 195, 188, 12, 20, 5, 11, 13, 0, 10, 135, 195, 169, 18, 9, 14, 20, 9, 13, 0, 6, 65, 68, 49, 40, 0, 31, 8, 195, 169, 10, 19, 26, 1, 11, 1, 113, 57, 89, 108, 49, 108, 10, 6, 15, 84, 39, 55, 47, 0, 13, 81, 118, 111, 108, 116, 32, 12, 137, 20, 197, 177, 26, 6, 1, 12, 1, 20, 13, 11, 136, 20, 1, 18, 20, 1, 14, 195, 161, 13, 0, 19, 144, 13, 197, 177, 11, 195, 182, 4, 20, 5, 20, 195, 169, 19, 8, 5, 26, 13, 0, 11, 136, 6, 195, 161, 10, 12, 21, 14, 11, 13, 10, 199, 12, 83, 148, 72, 146, 213, 76, 13, 0, 18, 68, 77, 161, 19, 104, 101, 115, 122, 100, 195, 169, 101, 115, 122, 0, 29, 42, 38, 68, 4, 32, 129, 56, 108, 71, 12, 108, 50, 23, 83, 39, 81, 55, 108, 55, 47, 108, 49, 108, 47, 0, 13, 81, 102, 111, 103, 108, 97, 108, 116, 97, 107, 97, 116, 32, 18, 143, 11, 195, 182, 26, 9, 14, 20, 195, 169, 26, 13, 195, 169, 14, 25, 13, 11, 136, 13, 195, 161, 19, 18, 195, 179, 12, 13, 16, 141, 3, 195, 169, 12, 11, 9, 20, 197, 177, 26, 195, 169, 19, 13, 7, 196, 20, 32, 133, 56, 13, 7, 196, 4, 32, 129, 56, 13, 0, 7, 65, 72, 109, 51, 51, 0, 21, 146, 22, 195, 169, 7, 12, 5, 7, 5, 19, 195, 173, 20, 5, 20, 20, 195, 169, 11, 13, 8, 197, 32, 148, 218, 20, 64, 13, 0, 10, 135, 18, 195, 169, 13, 12, 9, 11, 13, 8, 133, 13, 195, 169, 7, 25, 13, 0, 12, 137, 9, 18, 195, 161, 14, 25, 8, 15, 26, 13, 10, 199, 80, 20, 148, 4, 195, 65, 104, 13, 0, 7, 196, 81, 81, 19, 104, 76, 18, 67, 32, 241, 217, 107, 39, 79, 4, 108, 49, 37, 0, 81, 97, 107, 105, 32, 17, 67, 32, 241, 217, 107, 4, 39, 79, 4, 108, 88, 0, 81, 97, 122, 32, 15, 67, 32, 241, 217, 107, 4, 39, 79, 4, 108, 0, 81, 97, 32, 9, 198, 80, 84, 133, 52, 33, 78, 13, 34, 7, 5, 21, 18, 195, 179, 16, 1, 109, 40, 52, 115, 48, 108, 15, 10, 67, 40, 81, 108, 47, 37, 0, 13, 81, 110, 121, 117, 103, 97, 116, 105, 32, 6, 195, 52, 81, 217, 13, 7, 132, 19, 195, 179, 20, 13, 6, 195, 52, 81, 217, 13, 0, 7, 65, 76, 109, 91, 0, 14, 6, 65, 76, 91, 10, 0, 8, 197, 60, 179, 218, 56, 144, 13, 43, 10, 22, 15, 14, 1, 20, 11, 15, 26, 195, 179, 84, 39, 50, 108, 47, 49, 39, 88, 115, 10, 6, 15, 48, 39, 50, 80, 108, 37, 47, 0, 13, 81, 112, 111, 110, 116, 106, 97, 105, 116, 32, 8, 197, 88, 86, 133, 80, 144, 13, 8, 197, 44, 20, 21, 56, 176, 13, 13, 138, 22, 15, 14, 1, 20, 11, 15, 26, 195, 179, 13, 11, 136, 13, 9, 12, 12, 9, 195, 179, 13, 13, 8, 197, 16, 243, 7, 61, 64, 13, 19, 3, 22, 195, 182, 84, 6, 109, 90, 72, 15, 10, 6, 110, 89, 122, 109, 0, 25, 0, 9, 198, 60, 179, 218, 56, 18, 192, 13, 9, 198, 13, 48, 80, 5, 67, 212, 13, 0, 9, 198, 32, 19, 12, 61, 69, 1, 13, 18, 143, 22, 195, 161, 12, 20, 15, 26, 1, 20, 195, 161, 2, 195, 179, 12, 13, 0, 11, 200, 52, 20, 129, 16, 160, 78, 4, 176, 13, 0, 32, 70, 32, 18, 148, 4, 224, 75, 107, 108, 57, 47, 108, 50, 108, 49, 23, 84, 113, 81, 52, 109, 0, 13, 81, 118, 195, 169, 103, 114, 101, 32, 12, 201, 52, 20, 129, 16, 128, 84, 56, 18, 192, 13, 12, 201, 28, 243, 132, 61, 50, 207, 16, 146, 192, 13, 8, 197, 24, 83, 22, 21, 64, 13, 0, 21, 146, 14, 25, 9, 12, 22, 195, 161, 14, 195, 173, 20, 195, 161, 19, 20, 195, 179, 12, 13, 12, 137, 19, 195, 169, 20, 195, 161, 12, 14, 9, 13, 12, 137, 14, 25, 195, 186, 10, 20, 1, 14, 9, 13, 5, 194, 8, 16, 13, 0, 35, 67, 52, 81, 192, 65, 109, 81, 23, 49, 109, 55, 12, 23, 39, 55, 72, 108, 50, 37, 0, 13, 82, 107, 101, 108, 108, 32, 111, 108, 100, 97, 110, 105, 32, 41, 67, 52, 81, 192, 65, 109, 81, 23, 49, 109, 55, 12, 23, 84, 37, 90, 81, 114, 55, 50, 37, 0, 13, 82, 107, 101, 108, 108, 32, 118, 105, 122, 115, 103, 195, 161, 108, 110, 105, 32, 38, 67, 52, 81, 192, 65, 109, 81, 10, 6, 15, 49, 109, 55, 12, 10, 6, 15, 67, 39, 65, 50, 37, 0, 13, 82, 107, 101, 108, 108, 32, 110, 121, 111, 109, 110, 105, 32, 25, 67, 52, 81, 192, 65, 109, 81, 23, 108, 88, 39, 49, 108, 47, 0, 13, 81, 97, 122, 111, 107, 97, 116, 32, 28, 67, 52, 81, 192, 65, 109, 81, 23, 108, 6, 15, 91, 39, 52, 71, 108, 0, 13, 82, 97, 32, 115, 111, 114, 98, 97, 32, 45, 67, 52, 81, 192, 65, 109, 81, 23, 108, 6, 15, 57, 109, 55, 109, 50, 47, 49, 109, 88, 118, 84, 109, 55, 0, 13, 82, 97, 32, 106, 101, 108, 101, 110, 116, 107, 101, 122, 197, 145, 118, 101, 108, 32, 29, 67, 52, 81, 192, 65, 109, 81, 23, 37, 91, 23, 47, 40, 72, 39, 65, 0, 13, 82, 105, 115, 32, 116, 117, 100, 111, 109, 32, 24, 67, 52, 81, 192, 65, 109, 81, 23, 108, 23, 107, 112, 52, 0, 13, 82, 97, 32, 104, 195, 173, 114, 32, 15, 67, 52, 81, 192, 65, 109, 81, 23, 108, 0, 13, 81, 97, 32, 6, 195, 52, 81, 192, 13, 0, 11, 136, 13, 9, 12, 12, 9, 195, 179, 20, 13, 24, 68, 20, 208, 133, 72, 109, 65, 71, 109, 52, 23, 84, 39, 55, 47, 0, 13, 81, 118, 111, 108, 116, 32, 13, 196, 20, 208, 133, 72, 13, 81, 118, 111, 108, 116, 32, 8, 133, 1, 12, 22, 195, 179, 13, 7, 196, 20, 208, 133, 72, 13, 0, 8, 133, 11, 195, 182, 12, 20, 13, 28, 67, 8, 19, 0, 71, 108, 55, 23, 39, 55, 72, 108, 55, 114, 50, 0, 13, 81, 111, 108, 100, 97, 108, 195, 161, 110, 32, 12, 201, 20, 194, 5, 49, 145, 90, 21, 69, 0, 13, 8, 133, 10, 195, 182, 20, 20, 13, 11, 193, 84, 17, 83, 46, 32, 105, 32, 46, 32, 0, 6, 195, 12, 146, 203, 13, 9, 66, 85, 0, 40, 48, 0, 42, 42, 0, 11, 136, 10, 195, 161, 18, 20, 21, 14, 11, 13, 41, 73, 44, 20, 3, 76, 243, 1, 80, 32, 78, 49, 108, 48, 76, 39, 55, 108, 47, 71, 108, 50, 23, 108, 88, 23, 84, 39, 55, 47, 0, 13, 82, 97, 122, 32, 118, 111, 108, 116, 32, 10, 199, 20, 193, 143, 28, 17, 14, 36, 13, 10, 199, 8, 83, 85, 80, 21, 14, 36, 13, 10, 199, 20, 197, 137, 76, 83, 14, 36, 13, 9, 134, 3, 195, 169, 12, 10, 1, 13, 10, 135, 5, 12, 10, 195, 182, 20, 20, 13, 20, 145, 20, 5, 12, 10, 5, 19, 195, 173, 20, 195, 169, 19, 195, 169, 8, 5, 26, 13, 11, 136, 20, 197, 145, 12, 195, 188, 14, 11, 13, 0, 10, 135, 12, 195, 161, 20, 20, 1, 13, 13, 0, 4, 193, 88, 42, 6, 65, 88, 84, 113, 0, 12, 201, 40, 81, 217, 104, 85, 5, 44, 85, 0, 13, 9, 134, 22, 195, 173, 22, 15, 11, 13, 8, 197, 72, 243, 148, 40, 16, 13, 8, 197, 57, 147, 205, 60, 208, 13, 8, 197, 48, 83, 20, 20, 208, 13, 0, 9, 198, 29, 145, 82, 52, 82, 192, 13, 34, 11, 19, 26, 1, 2, 195, 161, 12, 25, 26, 195, 179, 89, 108, 71, 114, 57, 88, 115, 23, 40, 47, 114, 50, 0, 13, 81, 117, 116, 195, 161, 110, 32, 9, 198, 72, 17, 207, 104, 226, 64, 13, 13, 138, 22, 1, 4, 195, 161, 19, 26, 15, 20, 20, 13, 9, 198, 40, 83, 5, 104, 226, 64, 13, 9, 198, 57, 145, 82, 80, 82, 192, 13, 16, 141, 2, 9, 26, 15, 14, 25, 195, 173, 20, 1, 14, 9, 1, 13, 5, 194, 5, 48, 72, 0, 40, 6, 8, 195, 161, 18, 15, 13, 107, 114, 52, 39, 65, 23, 113, 84, 37, 81, 23, 71, 112, 52, 50, 37, 0, 13, 82, 195, 169, 118, 105, 103, 32, 98, 195, 173, 114, 110, 105, 32, 9, 134, 2, 195, 173, 26, 26, 1, 13, 13, 138, 11, 195, 182, 20, 5, 12, 5, 26, 197, 145, 13, 12, 137, 18, 195, 182, 22, 9, 4, 5, 2, 2, 13, 10, 135, 10, 15, 7, 18, 195, 179, 12, 13, 13, 138, 19, 26, 15, 12, 7, 195, 161, 12, 14, 1, 13, 8, 133, 195, 186, 20, 15, 14, 13, 8, 133, 11, 195, 182, 19, 26, 13, 8, 133, 195, 186, 20, 15, 14, 20, 0, 15, 140, 195, 182, 19, 19, 26, 5, 18, 1, 11, 15, 20, 20, 13, 16, 141, 13, 5, 7, 20, 5, 12, 195, 173, 20, 195, 188, 14, 11, 13, 15, 4, 95, 49, 77, 52, 109, 79, 71, 37, 55, 55, 37, 115, 0, 0, 12, 1, 92, 71, 109, 49, 122, 55, 109, 91, 0, 27, 11, 65, 92, 72, 40, 48, 55, 108, 84, 113, 0, 11, 136, 7, 25, 1, 14, 195, 186, 10, 1, 13, 8, 197, 88, 85, 20, 20, 176, 13, 11, 136, 6, 195, 188, 12, 5, 11, 18, 5, 13, 12, 201, 88, 243, 129, 80, 179, 218, 56, 18, 192, 13, 9, 134, 12, 1, 11, 195, 179, 11, 13, 12, 201, 24, 241, 204, 4, 194, 207, 104, 226, 64, 13, 0, 10, 135, 10, 195, 182, 20, 20, 5, 11, 13, 0, 14, 1, 94, 83, 110, 55, 83, 109, 55, 113, 67, 112, 55, 0, 9, 134, 20, 195, 169, 18, 14, 9, 13, 13, 138, 22, 9, 26, 19, 7, 195, 161, 12, 10, 1, 13, 9, 134, 11, 195, 182, 20, 14, 9, 13, 0, 14, 139, 11, 18, 9, 20, 9, 11, 195, 161, 11, 18, 1, 13, 38, 4, 7, 195, 169, 16, 81, 113, 48, 23, 83, 39, 79, 108, 89, 47, 114, 91, 114, 47, 0, 13, 81, 102, 111, 103, 121, 97, 115, 122, 116, 195, 161, 115, 195, 161, 116, 32, 11, 200, 57, 146, 84, 61, 69, 21, 56, 176, 13, 10, 135, 19, 5, 7, 195, 169, 12, 25, 13, 7, 132, 13, 195, 179, 4, 13, 7, 132, 7, 195, 169, 16, 13, 0, 4, 193, 96, 42, 7, 65, 96, 37, 49, 89, 0, 11, 136, 18, 195, 161, 22, 5, 14, 14, 9, 13, 16, 65, 96, 47, 112, 88, 88, 109, 55, 0, 44, 42, 81, 101, 108, 32, 0, 10, 135, 10, 195, 161, 18, 20, 1, 19, 13, 5, 194, 4, 64, 13, 15, 4, 95, 49, 77, 50, 109, 79, 65, 37, 55, 55, 37, 115, 0, 0, 14, 139, 11, 195, 169, 18, 4, 195, 169, 19, 195, 169, 20, 13, 18, 143, 13, 5, 7, 1, 12, 195, 161, 26, 195, 161, 19, 18, 195, 179, 12, 13, 10, 199, 80, 20, 148, 4, 195, 65, 80, 13, 15, 140, 195, 169, 12, 3, 5, 12, 197, 145, 4, 20, 5, 11, 13, 13, 138, 16, 9, 19, 26, 11, 195, 161, 12, 14, 9, 13, 13, 138, 19, 5, 2, 5, 19, 19, 195, 169, 7, 5, 13, 17, 4, 95, 49, 77, 51, 109, 79, 65, 37, 55, 55, 37, 114, 52, 72, 0, 0, 14, 139, 195, 186, 10, 4, 15, 14, 19, 195, 161, 7, 1, 13, 40, 7, 14, 25, 5, 12, 22, 197, 177, 67, 109, 55, 84, 117, 23, 37, 91, 65, 109, 52, 47, 109, 47, 118, 49, 0, 13, 81, 105, 115, 109, 101, 114, 116, 101, 116, 197, 145, 107, 32, 8, 133, 195, 169, 12, 5, 19, 13, 0, 11, 65, 100, 37, 48, 89, 37, 55, 39, 50, 0, 24, 149, 20, 195, 182, 18, 22, 195, 169, 14, 25, 10, 1, 22, 1, 19, 12, 1, 20, 18, 195, 179, 12, 13, 20, 145, 20, 195, 161, 13, 15, 7, 1, 20, 195, 161, 19, 195, 161, 2, 195, 179, 12, 13, 33, 6, 11, 5, 22, 195, 169, 19, 49, 109, 84, 113, 91, 23, 108, 23, 83, 109, 55, 107, 118, 0, 13, 82, 97, 32, 102, 101, 108, 104, 197, 145, 32, 11, 136, 22, 195, 169, 7, 5, 26, 14, 9, 13, 13, 138, 20, 5, 11, 9, 14, 20, 195, 188, 14, 11, 13, 8, 197, 4, 176, 82, 77, 160, 13, 9, 134, 11, 5, 22, 195, 169, 19, 13, 12, 67, 16, 245, 206, 72, 39, 58, 50, 0, 42, 42, 0, 16, 141, 195, 182, 14, 11, 195, 182, 12, 20, 19, 195, 169, 7, 5, 13, 33, 70, 57, 149, 71, 60, 69, 0, 67, 40, 81, 39, 47, 12, 15, 65, 108, 52, 108, 72, 50, 37, 0, 13, 81, 109, 97, 114, 97, 100, 110, 105, 32, 9, 198, 24, 244, 132, 84, 197, 0, 13, 0, 46, 10, 8, 15, 18, 4, 5, 18, 5, 10, 197, 177, 107, 39, 52, 72, 109, 52, 109, 57, 117, 23, 49, 113, 52, 72, 113, 91, 71, 109, 50, 0, 13, 81, 107, 195, 169, 114, 100, 195, 169, 115, 98, 101, 110, 32, 10, 199, 32, 83, 25, 104, 85, 2, 20, 13, 6, 195, 76, 20, 192, 13, 0, 19, 144, 13, 5, 7, 19, 26, 195, 188, 12, 5, 20, 195, 169, 19, 195, 169, 20, 13, 45, 68, 20, 118, 73, 44, 109, 79, 12, 37, 49, 10, 6, 15, 47, 109, 55, 109, 48, 107, 109, 57, 113, 52, 118, 55, 0, 13, 81, 116, 101, 108, 101, 112, 104, 101, 108, 121, 195, 169, 114, 197, 145, 108, 32, 33, 68, 20, 118, 73, 44, 109, 79, 12, 37, 49, 23, 84, 109, 88, 109, 47, 118, 57, 109, 0, 13, 81, 118, 101, 122, 101, 116, 197, 145, 106, 101, 32, 40, 68, 20, 118, 73, 44, 109, 79, 12, 37, 49, 23, 49, 113, 48, 84, 37, 91, 109, 55, 118, 57, 109, 0, 13, 81, 107, 195, 169, 112, 118, 105, 115, 101, 108, 197, 145, 106, 101, 32, 19, 144, 6, 5, 12, 20, 195, 188, 14, 20, 5, 20, 195, 169, 19, 195, 169, 20, 13, 12, 137, 12, 5, 8, 5, 20, 195, 188, 14, 11, 13, 7, 196, 20, 118, 73, 44, 13, 0, 6, 65, 104, 88, 113, 0, 25, 69, 24, 244, 132, 84, 192, 83, 39, 34, 72, 40, 55, 23, 109, 55, 118, 0, 13, 81, 101, 108, 197, 145, 32, 39, 69, 32, 243, 140, 5, 0, 107, 39, 50, 55, 108, 48, 10, 6, 15, 47, 110, 52, 55, 113, 91, 113, 47, 0, 13, 81, 116, 195, 182, 114, 108, 195, 169, 115, 195, 169, 116, 32, 8, 197, 57, 147, 205, 60, 224, 13, 13, 138, 18, 5, 14, 4, 197, 145, 18, 195, 182, 11, 13, 13, 138, 20, 5, 18, 5, 13, 20, 195, 188, 14, 11, 13, 8, 197, 64, 144, 67, 60, 224, 13, 8, 197, 24, 244, 132, 84, 192, 13, 0, 16, 141, 5, 18, 5, 4, 13, 195, 169, 14, 25, 5, 26, 197, 145, 13, 13, 138, 13, 21, 14, 11, 195, 161, 18, 195, 179, 12, 13, 9, 198, 88, 149, 1, 80, 160, 64, 13, 9, 198, 53, 85, 1, 80, 160, 64, 13, 12, 137, 6, 5, 12, 14, 195, 182, 22, 197, 145, 13, 8, 133, 12, 195, 169, 7, 25, 13, 0, 10, 135, 11, 195, 169, 13, 13, 5, 12, 13, 10, 199, 52, 243, 137, 80, 244, 143, 44, 13, 14, 139, 22, 195, 161, 12, 12, 195, 161, 18, 195, 179, 12, 13, 10, 199, 24, 244, 132, 84, 197, 1, 44, 13, 0, 25, 68, 97, 98, 73, 36, 47, 37, 88, 109, 50, 67, 39, 55, 119, 12, 108, 55, 0, 44, 42, 81, 97, 108, 32, 0, 34, 69, 40, 83, 5, 57, 64, 57, 109, 55, 109, 50, 47, 23, 89, 114, 65, 40, 49, 52, 108, 0, 13, 81, 115, 122, 195, 161, 109, 117, 107, 114, 97, 32, 12, 137, 195, 179, 18, 195, 161, 20, 195, 179, 12, 13, 13, 138, 19, 26, 195, 161, 18, 13, 1, 26, 195, 179, 13, 8, 197, 40, 83, 5, 57, 64, 13, 16, 9, 95, 35, 45, 195, 161, 18, 195, 179, 12, 114, 52, 115, 55, 0, 0, 0, 13, 138, 6, 197, 145, 8, 1, 4, 14, 1, 7, 25, 13, 0, 45, 68, 85, 64, 193, 36, 40, 119, 12, 108, 37, 23, 113, 48, 111, 55, 109, 47, 109, 23, 109, 55, 118, 47, 12, 0, 13, 82, 195, 169, 112, 195, 188, 108, 101, 116, 101, 32, 101, 108, 197, 145, 116, 116, 32, 0, 8, 197, 4, 192, 75, 61, 64, 13, 8, 197, 80, 84, 150, 21, 64, 13, 0, 14, 139, 11, 195, 182, 22, 5, 20, 11, 5, 26, 9, 11, 13, 9, 198, 8, 85, 137, 80, 83, 20, 13, 9, 134, 20, 195, 161, 13, 1, 4, 13, 0, 9, 198, 32, 83, 25, 21, 69, 5, 13, 14, 139, 6, 5, 12, 15, 12, 22, 1, 19, 195, 179, 20, 13, 10, 135, 7, 18, 195, 179, 6, 15, 20, 13, 0, 13, 138, 8, 5, 12, 25, 195, 188, 11, 195, 182, 14, 13, 19, 144, 8, 1, 19, 26, 14, 195, 161, 12, 1, 20, 195, 161, 18, 195, 179, 12, 13, 7, 132, 11, 195, 182, 4, 13, 7, 196, 80, 83, 9, 44, 13, 7, 132, 195, 188, 12, 20, 13, 0, 25, 5, 195, 161, 12, 12, 20, 114, 55, 47, 23, 110, 89, 12, 109, 0, 13, 81, 195, 182, 115, 115, 122, 101, 32, 35, 5, 195, 161, 12, 12, 20, 114, 55, 47, 23, 48, 113, 55, 72, 108, 49, 113, 50, 47, 0, 13, 81, 112, 195, 169, 108, 100, 97, 107, 195, 169, 110, 116, 32, 19, 4, 195, 173, 7, 25, 112, 79, 23, 84, 108, 50, 0, 13, 81, 118, 97, 110, 32, 8, 197, 77, 160, 75, 52, 16, 13, 21, 4, 195, 173, 7, 25, 112, 79, 15, 84, 39, 55, 47, 0, 13, 81, 118, 111, 108, 116, 32, 10, 135, 5, 19, 26, 11, 195, 182, 26, 13, 8, 133, 195, 161, 12, 12, 20, 13, 7, 132, 195, 173, 7, 25, 13, 0, 9, 198, 72, 243, 148, 4, 226, 64, 13, 9, 198, 80, 84, 141, 20, 149, 0, 13, 9, 198, 48, 85, 5, 56, 226, 64, 13, 21, 146, 13, 195, 179, 4, 15, 19, 195, 173, 20, 195, 161, 19, 195, 161, 18, 195, 179, 12, 13, 9, 198, 80, 20, 148, 4, 226, 64, 13, 9, 198, 52, 243, 132, 4, 226, 64, 13, 0, 9, 198, 80, 20, 148, 4, 226, 65, 13, 15, 204, 4, 194, 193, 48, 208, 90, 61, 69, 1, 44, 224, 75, 13, 0, 7, 196, 80, 242, 138, 4, 13, 10, 135, 21, 20, 3, 195, 161, 2, 1, 13, 11, 200, 32, 149, 129, 80, 179, 218, 88, 16, 13, 0, 8, 197, 88, 17, 217, 60, 176, 72, 11, 136, 20, 5, 19, 20, 195, 169, 2, 5, 13, 8, 197, 88, 20, 212, 4, 112, 13, 40, 9, 19, 9, 11, 5, 18, 195, 188, 12, 20, 91, 37, 49, 109, 52, 111, 55, 47, 23, 49, 37, 83, 39, 81, 50, 39, 65, 0, 13, 81, 107, 105, 102, 111, 103, 110, 111, 109, 32, 8, 197, 24, 17, 217, 60, 176, 13, 12, 201, 24, 83, 4, 60, 193, 207, 104, 226, 64, 13, 9, 134, 3, 195, 173, 13, 5, 11, 13, 13, 138, 11, 9, 20, 195, 169, 18, 195, 188, 14, 11, 13, 9, 134, 3, 195, 169, 12, 15, 11, 13, 16, 9, 95, 35, 45, 195, 161, 20, 195, 179, 12, 114, 47, 115, 55, 0, 0, 9, 198, 48, 84, 218, 80, 82, 192, 72, 9, 198, 24, 84, 212, 20, 226, 64, 13, 9, 198, 44, 84, 133, 76, 226, 64, 13, 9, 198, 88, 84, 218, 80, 82, 192, 13, 0, 22, 67, 44, 148, 192, 49, 37, 91, 23, 47, 109, 55, 115, 0, 13, 81, 116, 101, 108, 195, 179, 32, 30, 67, 44, 148, 192, 49, 37, 91, 15, 47, 111, 52, 109, 55, 65, 109, 47, 0, 13, 81, 116, 195, 188, 114, 101, 108, 109, 101, 116, 32, 19, 144, 5, 12, 11, 195, 169, 16, 26, 5, 12, 195, 169, 19, 195, 188, 14, 11, 13, 24, 67, 44, 148, 192, 49, 37, 91, 15, 109, 52, 109, 57, 117, 0, 13, 81, 101, 114, 101, 106, 197, 177, 32, 13, 138, 19, 26, 15, 12, 7, 195, 161, 12, 10, 1, 13, 10, 199, 77, 163, 205, 8, 21, 15, 56, 22, 0, 15, 140, 20, 18, 195, 179, 14, 10, 195, 161, 18, 195, 179, 12, 13, 15, 140, 20, 9, 12, 1, 12, 13, 195, 161, 18, 195, 179, 12, 13, 11, 200, 29, 144, 78, 4, 180, 218, 36, 176, 13, 15, 140, 4, 195, 182, 18, 195, 182, 13, 2, 195, 182, 12, 20, 13, 9, 134, 3, 195, 173, 13, 5, 14, 13, 12, 137, 22, 195, 161, 12, 20, 15, 26, 195, 179, 13, 0, 12, 201, 52, 83, 133, 81, 33, 78, 16, 85, 0, 13, 16, 141, 22, 195, 161, 12, 20, 15, 26, 20, 1, 20, 15, 20, 20, 13, 39, 69, 72, 18, 206, 4, 176, 52, 108, 49, 50, 108, 49, 10, 6, 15, 71, 109, 50, 12, 111, 50, 49, 109, 47, 0, 13, 81, 98, 101, 110, 110, 195, 188, 110, 107, 101, 116, 32, 24, 69, 88, 82, 5, 80, 144, 84, 109, 107, 109, 47, 37, 23, 108, 89, 47, 0, 13, 81, 97, 122, 116, 32, 12, 201, 44, 146, 133, 48, 83, 148, 20, 226, 64, 13, 0, 28, 70, 76, 146, 197, 72, 84, 192, 91, 37, 49, 109, 52, 109, 91, 23, 84, 39, 55, 47, 0, 13, 81, 118, 111, 108, 116, 32, 12, 137, 19, 26, 195, 161, 13, 21, 11, 18, 1, 13, 9, 198, 12, 146, 203, 56, 82, 192, 13, 0, 9, 1, 126, 47, 37, 55, 72, 109, 0, 10, 135, 20, 195, 182, 2, 2, 9, 20, 13, 0, 15, 140, 16, 15, 19, 26, 20, 10, 195, 161, 18, 195, 179, 12, 13, 15, 140, 15, 11, 20, 1, 20, 195, 161, 19, 2, 195, 179, 12, 13, 10, 135, 5, 12, 195, 169, 18, 14, 9, 13, 9, 198, 16, 80, 197, 52, 33, 82, 20, 9, 198, 56, 245, 133, 52, 33, 82, 20, 0, 12, 201, 36, 225, 15, 44, 243, 20, 56, 18, 192, 13, 9, 198, 80, 20, 148, 4, 224, 75, 13, 0, 33, 70, 77, 161, 82, 36, 229, 0, 89, 109, 52, 37, 50, 47, 23, 108, 88, 39, 49, 50, 108, 49, 0, 13, 81, 97, 122, 111, 107, 110, 97, 107, 32, 27, 70, 77, 161, 82, 36, 229, 0, 89, 109, 52, 37, 50, 47, 23, 84, 39, 55, 47, 0, 13, 81, 118, 111, 108, 116, 32, 44, 70, 77, 161, 82, 36, 229, 0, 89, 109, 52, 37, 50, 47, 23, 65, 115, 72, 39, 91, 112, 47, 107, 108, 47, 115, 0, 13, 81, 109, 195, 179, 100, 111, 115, 195, 173, 116, 104, 97, 116, 195, 179, 32, 12, 137, 13, 5, 7, 11, 195, 169, 18, 14, 9, 13, 16, 141, 10, 5, 12, 5, 14, 19, 195, 169, 7, 5, 11, 18, 5, 13, 12, 137, 13, 5, 7, 14, 195, 169, 26, 14, 9, 13, 9, 198, 77, 161, 82, 36, 229, 0, 13, 0, 18, 143, 6, 5, 12, 9, 14, 4, 21, 12, 195, 161, 19, 2, 195, 179, 12, 13, 18, 143, 20, 195, 161, 13, 15, 7, 1, 20, 195, 161, 19, 2, 195, 179, 12, 13, 0, 15, 204, 44, 243, 80, 72, 243, 73, 77, 54, 149, 52, 242, 192, 13, 55, 8, 19, 26, 195, 161, 13, 195, 173, 20, 89, 114, 65, 112, 47, 10, 6, 15, 108, 6, 15, 65, 37, 50, 37, 89, 47, 109, 52, 109, 55, 50, 110, 49, 0, 13, 82, 97, 32, 109, 105, 110, 105, 115, 122, 116, 101, 114, 101, 108, 110, 195, 182, 107, 32, 12, 201, 80, 20, 148, 4, 195, 65, 104, 224, 75, 13, 12, 201, 80, 20, 148, 4, 195, 65, 104, 224, 75, 13, 11, 136, 19, 26, 195, 161, 13, 195, 173, 20, 13, 0, 11, 136, 195, 169, 18, 11, 5, 26, 197, 145, 13, 12, 137, 195, 188, 26, 5, 13, 13, 195, 179, 4, 13, 13, 138, 9, 7, 195, 169, 14, 25, 195, 188, 14, 11, 13, 20, 145, 11, 15, 14, 3, 5, 16, 3, 9, 195, 179, 10, 195, 161, 18, 195, 179, 12, 13, 0, 20, 145, 20, 5, 22, 195, 169, 11, 5, 14, 25, 19, 195, 169, 7, 5, 11, 18, 5, 13, 9, 198, 32, 22, 149, 17, 64, 64, 13, 0, 31, 10, 22, 9, 26, 19, 7, 195, 161, 12, 14, 9, 84, 37, 90, 81, 114, 55, 50, 37, 23, 108, 89, 47, 0, 13, 81, 97, 122, 116, 32, 0, 26, 68, 48, 83, 142, 20, 55, 109, 50, 12, 109, 23, 109, 50, 12, 109, 49, 0, 13, 81, 101, 110, 110, 101, 107, 32, 21, 68, 48, 83, 142, 20, 55, 109, 50, 12, 109, 23, 52, 114, 0, 13, 81, 114, 195, 161, 32, 14, 139, 14, 195, 169, 16, 5, 19, 19, 195, 169, 7, 5, 13, 33, 68, 48, 83, 142, 20, 55, 109, 50, 12, 109, 23, 89, 109, 52, 37, 50, 47, 109, 65, 0, 13, 81, 115, 122, 101, 114, 105, 110, 116, 101, 109, 32, 24, 67, 77, 161, 77, 89, 109, 65, 23, 109, 55, 118, 47, 12, 0, 13, 81, 101, 108, 197, 145, 116, 116, 32, 22, 68, 48, 83, 142, 20, 55, 109, 50, 12, 109, 23, 89, 115, 0, 13, 81, 115, 122, 195, 179, 32, 35, 68, 48, 83, 142, 20, 55, 109, 50, 12, 109, 23, 89, 111, 49, 91, 113, 81, 109, 65, 0, 13, 81, 115, 122, 195, 188, 107, 115, 195, 169, 103, 101, 109, 32, 31, 68, 48, 83, 142, 20, 55, 109, 50, 12, 109, 15, 89, 111, 49, 91, 113, 81, 0, 13, 81, 115, 122, 195, 188, 107, 115, 195, 169, 103, 32, 14, 139, 11, 195, 169, 16, 5, 19, 19, 195, 169, 7, 5, 13, 14, 139, 11, 195, 169, 16, 22, 9, 19, 5, 12, 197, 145, 13, 12, 137, 19, 9, 5, 20, 20, 195, 188, 14, 11, 13, 7, 132, 11, 195, 182, 16, 13, 7, 196, 48, 83, 142, 20, 13, 0, 0, 31, 6, 1, 20, 20, 195, 179, 12, 108, 47, 12, 115, 55, 10, 6, 15, 83, 113, 55, 50, 37, 0, 13, 81, 102, 195, 169, 108, 110, 105, 32, 10, 135, 11, 15, 18, 195, 186, 1, 11, 13, 11, 136, 7, 25, 5, 14, 7, 195, 169, 14, 13, 8, 133, 14, 195, 169, 7, 25, 13, 9, 134, 1, 20, 20, 195, 179, 12, 13, 0, 9, 198, 52, 81, 212, 20, 227, 137, 13, 11, 136, 22, 195, 161, 7, 25, 14, 1, 11, 13, 10, 199, 20, 192, 86, 84, 197, 1, 44, 13, 6, 195, 32, 145, 4, 13, 0, 12, 137, 22, 195, 161, 12, 1, 19, 26, 15, 11, 13, 0, 12, 201, 77, 160, 66, 4, 67, 129, 65, 32, 64, 13, 11, 136, 20, 1, 12, 195, 161, 12, 20, 1, 13, 13, 138, 2, 15, 18, 195, 173, 20, 1, 14, 1, 11, 13, 12, 137, 3, 19, 195, 182, 11, 11, 5, 14, 20, 13, 8, 197, 28, 243, 66, 61, 64, 13, 8, 197, 21, 161, 75, 21, 64, 13, 0, 0, 15, 140, 8, 1, 20, 195, 179, 19, 195, 161, 7, 14, 1, 11, 13, 21, 146, 195, 161, 12, 12, 1, 13, 20, 9, 20, 11, 195, 161, 18, 19, 195, 161, 7, 1, 13, 15, 140, 5, 12, 12, 195, 161, 20, 195, 179, 11, 14, 1, 11, 13, 13, 138, 11, 9, 20, 1, 12, 195, 161, 12, 20, 1, 13, 6, 195, 5, 81, 192, 20, 0, 18, 68, 53, 54, 141, 64, 101, 109, 101, 115, 122, 101, 109, 112, 195, 169, 0, 29, 19, 68, 53, 54, 141, 64, 101, 109, 101, 115, 122, 101, 109, 112, 195, 169, 0, 29, 42, 22, 4, 195, 161, 12, 12, 114, 55, 12, 23, 108, 52, 52, 108, 0, 13, 81, 97, 114, 114, 97, 32, 16, 141, 13, 5, 7, 6, 5, 12, 5, 12, 197, 145, 14, 5, 11, 13, 16, 141, 19, 26, 1, 11, 195, 169, 18, 20, 197, 145, 14, 5, 11, 13, 16, 141, 2, 9, 26, 15, 20, 20, 19, 195, 161, 7, 14, 1, 11, 13, 7, 132, 195, 161, 12, 12, 13, 0, 13, 138, 15, 18, 19, 26, 195, 161, 7, 14, 1, 11, 13, 17, 142, 2, 9, 3, 9, 11, 12, 9, 26, 197, 145, 11, 14, 5, 11, 13, 15, 140, 11, 195, 182, 18, 195, 188, 12, 195, 182, 20, 20, 5, 13, 0, 20, 66, 8, 80, 71, 109, 23, 116, 57, 52, 108, 0, 13, 81, 195, 186, 106, 114, 97, 32, 12, 137, 3, 19, 5, 18, 195, 169, 12, 14, 9, 13, 25, 66, 8, 80, 71, 109, 10, 6, 15, 108, 89, 47, 23, 37, 91, 0, 13, 82, 97, 122, 116, 32, 105, 115, 32, 5, 194, 8, 80, 13, 5, 194, 8, 80, 13, 0, 9, 198, 72, 82, 212, 61, 32, 73, 13, 15, 140, 7, 1, 26, 4, 1, 19, 195, 161, 7, 14, 1, 11, 13, 15, 140, 5, 12, 5, 7, 5, 14, 4, 197, 145, 14, 5, 11, 13, 14, 203, 52, 81, 198, 60, 112, 76, 52, 22, 143, 81, 64, 13, 6, 195, 76, 20, 212, 13, 0, 27, 68, 88, 243, 14, 4, 84, 39, 55, 50, 108, 23, 65, 108, 81, 114, 47, 0, 13, 81, 109, 97, 103, 195, 161, 116, 32, 22, 68, 88, 243, 14, 4, 84, 39, 55, 50, 108, 23, 83, 109, 55, 0, 13, 81, 102, 101, 108, 32, 22, 68, 88, 243, 14, 4, 84, 39, 55, 50, 108, 23, 65, 109, 81, 0, 13, 81, 109, 101, 103, 32, 33, 68, 88, 243, 14, 4, 84, 39, 55, 50, 108, 23, 65, 109, 81, 23, 118, 49, 109, 47, 0, 13, 82, 109, 101, 103, 32, 197, 145, 107, 101, 116, 32, 32, 68, 88, 243, 14, 4, 84, 39, 55, 50, 108, 23, 47, 109, 52, 84, 109, 88, 50, 37, 0, 13, 81, 116, 101, 114, 118, 101, 122, 110, 105, 32, 45, 68, 88, 243, 14, 4, 84, 39, 55, 50, 108, 23, 108, 23, 49, 113, 52, 72, 118, 112, 84, 109, 49, 109, 47, 0, 13, 82, 97, 32, 107, 195, 169, 114, 100, 197, 145, 195, 173, 118, 101, 107, 101, 116, 32, 12, 137, 19, 26, 15, 11, 195, 161, 19, 15, 19, 13, 12, 137, 19, 5, 2, 5, 19, 19, 195, 169, 7, 13, 12, 137, 19, 26, 195, 188, 11, 19, 195, 169, 7, 13, 12, 137, 19, 26, 195, 188, 11, 19, 195, 169, 7, 13, 11, 200, 32, 19, 1, 77, 165, 15, 81, 64, 13, 7, 196, 32, 148, 218, 36, 13, 7, 196, 88, 243, 14, 4, 13, 0, 36, 69, 32, 243, 14, 5, 0, 107, 39, 55, 50, 108, 48, 23, 72, 113, 55, 109, 55, 118, 47, 12, 0, 13, 81, 100, 195, 169, 108, 101, 108, 197, 145, 116, 116, 32, 34, 69, 32, 243, 14, 5, 0, 107, 39, 55, 50, 108, 48, 23, 72, 113, 55, 40, 47, 114, 50, 0, 13, 81, 100, 195, 169, 108, 117, 116, 195, 161, 110, 32, 8, 197, 32, 243, 14, 5, 0, 13, 34, 69, 32, 243, 14, 5, 0, 107, 39, 55, 50, 108, 48, 15, 72, 113, 55, 40, 47, 114, 50, 0, 13, 81, 100, 195, 169, 108, 117, 116, 195, 161, 110, 32, 36, 69, 32, 243, 14, 5, 0, 107, 39, 55, 50, 108, 48, 15, 72, 113, 55, 109, 55, 118, 47, 12, 0, 13, 81, 100, 195, 169, 108, 101, 108, 197, 145, 116, 116, 32, 9, 198, 61, 37, 143, 76, 224, 75, 13, 8, 197, 52, 243, 132, 80, 16, 13, 0, 6, 195, 32, 19, 11, 13, 12, 67, 57, 54, 139, 109, 50, 109, 89, 49, 114, 0, 0, 10, 199, 57, 149, 71, 60, 69, 1, 56, 13, 11, 136, 13, 195, 169, 18, 14, 195, 182, 11, 13, 13, 67, 36, 98, 128, 37, 83, 57, 108, 71, 12, 0, 25, 17, 4, 95, 50, 67, 15, 49, 113, 47, 89, 114, 88, 108, 72, 37, 49, 0, 0, 6, 195, 84, 227, 137, 13, 7, 196, 52, 83, 142, 36, 13, 0, 9, 198, 80, 19, 149, 49, 69, 75, 13, 0, 7, 66, 13, 48, 76, 113, 0, 0, 10, 199, 77, 161, 82, 20, 197, 5, 44, 13, 0, 11, 200, 88, 148, 197, 48, 177, 68, 56, 144, 13, 11, 200, 16, 243, 7, 61, 163, 137, 84, 176, 13, 40, 68, 60, 193, 1, 48, 39, 55, 72, 108, 55, 23, 109, 55, 49, 113, 89, 112, 47, 113, 91, 109, 0, 13, 81, 101, 108, 107, 195, 169, 115, 122, 195, 173, 116, 195, 169, 115, 101, 32, 11, 200, 8, 85, 129, 48, 195, 212, 80, 16, 13, 6, 195, 8, 83, 5, 13, 11, 200, 52, 81, 205, 60, 225, 1, 56, 144, 13, 7, 196, 60, 193, 1, 48, 13, 16, 4, 95, 50, 77, 52, 49, 113, 47, 71, 37, 55, 55, 37, 115, 0, 0, 35, 70, 44, 86, 132, 20, 225, 75, 49, 109, 88, 72, 109, 50, 109, 49, 6, 23, 37, 52, 114, 50, 47, 108, 0, 13, 81, 105, 114, 195, 161, 110, 116, 97, 32, 12, 137, 22, 9, 26, 19, 7, 195, 161, 12, 20, 13, 0, 31, 6, 11, 5, 18, 195, 188, 12, 49, 109, 52, 111, 55, 10, 6, 15, 37, 47, 107, 39, 50, 0, 13, 81, 105, 116, 116, 104, 111, 110, 32, 24, 6, 11, 5, 18, 195, 188, 12, 49, 109, 52, 111, 55, 23, 91, 39, 52, 0, 13, 81, 115, 111, 114, 32, 9, 134, 11, 5, 18, 195, 188, 12, 13, 0, 29, 67, 61, 37, 20, 111, 101, 114, 114, 116, 195, 169, 116, 195, 169, 116, 197, 145, 108, 0, 44, 29, 42, 81, 116, 197, 145, 108, 32, 12, 137, 19, 1, 18, 11, 195, 161, 8, 15, 26, 13, 15, 140, 19, 26, 195, 161, 13, 195, 173, 20, 1, 14, 1, 11, 13, 61, 10, 20, 5, 18, 195, 188, 12, 5, 20, 18, 5, 47, 109, 52, 111, 55, 109, 47, 52, 109, 10, 6, 15, 37, 91, 10, 6, 15, 49, 39, 50, 119, 109, 50, 47, 52, 114, 55, 50, 37, 0, 13, 82, 105, 115, 32, 107, 111, 110, 99, 101, 110, 116, 114, 195, 161, 108, 110, 105, 32, 10, 135, 20, 195, 182, 2, 2, 5, 20, 13, 26, 7, 20, 195, 182, 2, 2, 5, 20, 47, 110, 71, 12, 109, 47, 23, 83, 39, 81, 0, 13, 81, 102, 111, 103, 32, 32, 7, 20, 195, 182, 2, 2, 5, 20, 47, 110, 71, 12, 109, 47, 15, 47, 40, 72, 50, 108, 49, 0, 13, 81, 116, 117, 100, 110, 97, 107, 32, 8, 195, 61, 37, 20, 17, 42, 42, 0, 11, 136, 19, 5, 18, 5, 7, 195, 169, 20, 13, 47, 12, 195, 182, 19, 19, 26, 5, 15, 13, 12, 15, 20, 20, 110, 89, 12, 109, 39, 65, 55, 39, 47, 12, 23, 108, 23, 52, 109, 50, 119, 109, 52, 0, 13, 82, 97, 32, 114, 101, 110, 100, 115, 122, 101, 114, 32, 6, 195, 24, 83, 5, 13, 6, 195, 88, 83, 5, 13, 0, 17, 142, 7, 25, 1, 14, 195, 186, 19, 195, 173, 20, 1, 14, 1, 11, 13, 9, 198, 36, 225, 21, 49, 64, 75, 13, 15, 140, 11, 195, 169, 16, 5, 18, 14, 25, 197, 145, 18, 5, 13, 17, 10, 95, 35, 45, 9, 11, 195, 161, 14, 1, 11, 114, 50, 108, 49, 0, 14, 4, 95, 50, 77, 49, 49, 113, 47, 109, 88, 109, 52, 0, 0, 18, 66, 16, 32, 100, 97, 114, 97, 98, 111, 116, 0, 44, 29, 81, 111, 116, 32, 18, 66, 16, 32, 100, 97, 114, 97, 98, 111, 115, 0, 44, 29, 81, 111, 115, 32, 17, 66, 12, 64, 99, 195, 169, 100, 195, 169, 109, 0, 44, 29, 81, 109, 32, 18, 66, 12, 64, 99, 195, 169, 100, 195, 169, 109, 0, 44, 29, 42, 81, 109, 32, 18, 66, 12, 64, 99, 195, 169, 100, 195, 169, 100, 0, 44, 29, 42, 81, 100, 32, 17, 66, 12, 64, 99, 195, 169, 100, 195, 169, 100, 0, 44, 29, 81, 100, 32, 17, 66, 12, 64, 99, 195, 169, 100, 195, 169, 110, 0, 44, 29, 81, 110, 32, 18, 66, 12, 64, 99, 195, 169, 100, 195, 169, 110, 0, 44, 29, 42, 81, 110, 32, 17, 66, 12, 64, 99, 195, 169, 100, 195, 169, 107, 0, 44, 29, 81, 107, 32, 18, 66, 12, 64, 99, 195, 169, 100, 195, 169, 107, 0, 44, 29, 42, 81, 107, 32, 12, 137, 195, 169, 16, 195, 173, 20, 5, 14, 9, 13, 37, 66, 12, 64, 119, 113, 72, 113, 109, 55, 12, 109, 50, 118, 52, 88, 113, 91, 47, 0, 44, 42, 81, 101, 108, 108, 101, 110, 197, 145, 114, 122, 195, 169, 115, 116, 32, 16, 4, 95, 50, 77, 50, 49, 113, 47, 65, 37, 55, 55, 37, 115, 0, 0, 28, 71, 57, 149, 71, 60, 69, 1, 52, 67, 40, 81, 39, 47, 12, 108, 65, 23, 65, 109, 81, 0, 13, 81, 109, 101, 103, 32, 19, 144, 11, 195, 169, 19, 26, 195, 188, 12, 195, 169, 11, 5, 9, 14, 5, 11, 13, 10, 135, 10, 195, 182, 22, 197, 145, 20, 13, 10, 135, 195, 188, 26, 5, 14, 5, 20, 13, 18, 4, 95, 50, 77, 51, 49, 113, 47, 65, 37, 55, 55, 37, 114, 52, 72, 0, 0, 43, 70, 72, 83, 132, 77, 161, 82, 52, 109, 50, 119, 109, 52, 23, 83, 40, 47, 12, 108, 47, 114, 91, 114, 52, 108, 0, 13, 81, 102, 117, 116, 116, 97, 116, 195, 161, 115, 195, 161, 114, 97, 32, 41, 70, 72, 83, 132, 77, 161, 82, 52, 109, 50, 119, 109, 52, 23, 83, 52, 37, 91, 12, 112, 47, 113, 91, 47, 0, 13, 81, 102, 114, 105, 115, 115, 195, 173, 116, 195, 169, 115, 116, 32, 15, 140, 19, 5, 2, 5, 19, 19, 195, 169, 7, 195, 169, 20, 13, 15, 140, 11, 195, 182, 12, 20, 19, 195, 169, 7, 195, 169, 20, 13, 9, 198, 72, 83, 132, 77, 161, 82, 13, 11, 136, 19, 26, 195, 161, 13, 195, 161, 20, 13, 7, 196, 16, 243, 15, 28, 13, 0, 11, 136, 19, 26, 5, 18, 5, 20, 197, 145, 13, 16, 141, 13, 21, 14, 11, 1, 20, 195, 161, 18, 19, 195, 161, 20, 13, 18, 143, 195, 161, 12, 12, 195, 173, 20, 195, 161, 19, 195, 161, 8, 15, 26, 13, 15, 140, 2, 5, 195, 161, 12, 12, 195, 173, 20, 1, 14, 9, 13, 15, 140, 5, 7, 25, 5, 14, 12, 195, 173, 20, 5, 14, 9, 13, 8, 197, 52, 243, 132, 60, 64, 13, 11, 136, 11, 5, 18, 195, 188, 12, 197, 145, 13, 8, 133, 6, 195, 161, 10, 20, 13, 0, 57, 70, 24, 241, 193, 17, 64, 64, 83, 39, 81, 108, 47, 12, 108, 23, 108, 88, 6, 23, 109, 55, 49, 113, 48, 88, 109, 55, 113, 91, 109, 49, 109, 47, 0, 13, 82, 97, 122, 32, 101, 108, 107, 195, 169, 112, 122, 101, 108, 195, 169, 115, 101, 107, 101, 116, 32, 9, 198, 48, 81, 202, 60, 32, 128, 13, 9, 198, 48, 20, 211, 4, 32, 128, 13, 9, 198, 24, 241, 193, 17, 64, 64, 13, 0, 9, 198, 36, 112, 90, 60, 195, 137, 13, 20, 145, 2, 9, 26, 20, 15, 19, 195, 173, 20, 195, 161, 19, 195, 161, 8, 15, 26, 13, 10, 199, 40, 83, 5, 57, 65, 78, 20, 13, 0, 7, 196, 24, 82, 130, 20, 13, 9, 134, 195, 161, 18, 2, 1, 14, 13, 7, 196, 80, 148, 218, 80, 13, 0, 12, 201, 32, 19, 135, 61, 165, 1, 81, 64, 64, 13, 0, 12, 66, 17, 32, 72, 39, 49, 47, 39, 52, 0, 25, 0, 9, 134, 13, 195, 182, 7, 195, 169, 13, 0, 12, 137, 11, 195, 188, 26, 4, 5, 14, 5, 11, 13, 9, 134, 11, 195, 179, 4, 195, 186, 13, 0, 32, 69, 64, 84, 131, 21, 64, 48, 109, 52, 119, 109, 47, 23, 83, 37, 88, 109, 47, 109, 49, 0, 13, 81, 102, 105, 122, 101, 116, 101, 107, 32, 8, 197, 9, 82, 203, 4, 224, 13, 12, 201, 52, 81, 212, 36, 197, 15, 81, 64, 64, 13, 8, 133, 6, 195, 161, 10, 12, 13, 8, 197, 52, 147, 139, 21, 64, 13, 8, 197, 52, 147, 139, 21, 64, 13, 12, 137, 5, 7, 25, 1, 18, 195, 161, 14, 20, 13, 0, 9, 198, 77, 161, 82, 21, 1, 64, 13, 12, 137, 11, 195, 182, 26, 195, 182, 12, 20, 5, 13, 9, 133, 197, 145, 19, 26, 9, 20, 13, 0, 13, 138, 195, 169, 18, 5, 26, 8, 5, 20, 20, 5, 13, 14, 139, 6, 197, 145, 15, 19, 26, 20, 195, 161, 10, 20, 13, 6, 195, 32, 19, 20, 13, 0, 49, 13, 15, 19, 26, 20, 195, 161, 12, 25, 195, 161, 14, 1, 11, 39, 89, 47, 114, 57, 114, 50, 108, 49, 23, 84, 109, 88, 109, 47, 113, 91, 113, 47, 0, 13, 81, 118, 101, 122, 101, 116, 195, 169, 115, 195, 169, 116, 32, 16, 141, 20, 195, 161, 18, 7, 25, 1, 12, 10, 1, 14, 1, 11, 13, 16, 141, 20, 195, 161, 18, 7, 25, 1, 12, 10, 1, 14, 1, 11, 13, 0, 10, 135, 195, 179, 18, 1, 11, 15, 18, 13, 38, 14, 9, 14, 4, 195, 173, 20, 22, 195, 161, 14, 25, 14, 1, 11, 37, 50, 72, 112, 47, 84, 114, 67, 50, 108, 49, 23, 84, 108, 50, 0, 13, 81, 118, 97, 110, 32, 34, 11, 195, 161, 12, 12, 1, 16, 15, 20, 2, 1, 14, 114, 55, 12, 108, 48, 39, 47, 71, 108, 50, 23, 84, 108, 50, 0, 13, 81, 118, 97, 110, 32, 17, 142, 5, 12, 22, 195, 161, 18, 195, 161, 19, 15, 11, 14, 1, 11, 13, 8, 197, 24, 241, 193, 37, 64, 13, 9, 198, 80, 20, 148, 61, 162, 75, 13, 0, 10, 135, 195, 182, 19, 19, 26, 5, 7, 13, 14, 139, 22, 5, 26, 5, 20, 197, 145, 11, 14, 5, 11, 13, 9, 198, 52, 243, 132, 61, 69, 0, 13, 0, 19, 144, 11, 195, 169, 16, 22, 9, 19, 5, 12, 20, 10, 5, 9, 14, 5, 11, 13, 11, 136, 26, 195, 161, 19, 26, 12, 195, 179, 13, 0, 16, 141, 11, 21, 20, 1, 20, 195, 161, 19, 15, 11, 14, 1, 11, 13, 10, 135, 22, 195, 169, 11, 15, 14, 25, 13, 0, 8, 197, 16, 243, 7, 60, 176, 13, 45, 69, 16, 243, 7, 60, 176, 72, 39, 55, 81, 39, 49, 10, 6, 15, 37, 72, 109, 81, 109, 91, 112, 47, 109, 50, 109, 49, 0, 13, 81, 105, 100, 101, 103, 101, 115, 195, 173, 116, 101, 110, 101, 107, 32, 13, 138, 2, 5, 12, 197, 145, 14, 9, 195, 188, 11, 13, 17, 142, 9, 14, 20, 195, 169, 26, 13, 195, 169, 14, 25, 14, 5, 11, 13, 6, 195, 77, 160, 82, 13, 9, 198, 4, 192, 80, 77, 162, 75, 13, 15, 140, 195, 169, 12, 5, 20, 20, 1, 18, 20, 1, 13, 1, 13, 12, 201, 24, 241, 193, 48, 208, 90, 61, 69, 0, 13, 6, 195, 77, 160, 82, 13, 0, 40, 11, 11, 195, 182, 26, 195, 182, 14, 19, 195, 169, 7, 49, 110, 88, 110, 50, 91, 113, 81, 23, 91, 39, 52, 108, 37, 71, 108, 0, 13, 81, 115, 111, 114, 97, 105, 98, 97, 32, 12, 201, 80, 20, 1, 77, 165, 1, 49, 64, 77, 13, 9, 198, 77, 165, 15, 72, 149, 0, 13, 13, 138, 22, 1, 12, 12, 15, 13, 195, 161, 19, 20, 13, 0, 11, 136, 20, 21, 4, 8, 1, 20, 195, 179, 13, 10, 199, 4, 64, 75, 61, 163, 212, 80, 13, 16, 134, 11, 195, 169, 26, 2, 5, 13, 81, 118, 101, 110, 110, 105, 32, 0, 7, 196, 85, 64, 76, 80, 13, 7, 196, 4, 65, 9, 28, 13, 58, 13, 20, 5, 22, 195, 169, 11, 5, 14, 25, 19, 195, 169, 7, 47, 109, 84, 113, 49, 109, 67, 91, 113, 81, 23, 49, 110, 88, 113, 48, 12, 39, 50, 80, 114, 71, 108, 0, 13, 81, 107, 195, 182, 122, 195, 169, 112, 112, 111, 110, 116, 106, 195, 161, 98, 97, 32, 38, 9, 19, 26, 1, 2, 8, 1, 20, 195, 179, 89, 108, 71, 107, 108, 47, 115, 23, 65, 109, 50, 111, 84, 109, 55, 0, 13, 81, 109, 101, 110, 195, 188, 118, 101, 108, 32, 12, 137, 15, 19, 26, 20, 8, 1, 20, 195, 179, 13, 11, 136, 3, 19, 9, 14, 195, 161, 12, 20, 13, 16, 141, 20, 5, 22, 195, 169, 11, 5, 14, 25, 19, 195, 169, 7, 13, 12, 137, 22, 195, 161, 7, 8, 1, 20, 195, 179, 13, 12, 137, 12, 195, 161, 20, 8, 1, 20, 195, 179, 13, 7, 196, 32, 147, 142, 36, 13, 7, 196, 48, 83, 142, 36, 13, 0, 11, 136, 8, 1, 12, 195, 161, 12, 18, 1, 13, 9, 198, 88, 148, 197, 49, 65, 75, 13, 17, 142, 20, 1, 12, 195, 161, 12, 13, 195, 161, 14, 25, 21, 14, 11, 13, 13, 138, 6, 15, 7, 1, 4, 8, 1, 20, 195, 179, 13, 0, 9, 198, 57, 145, 76, 88, 85, 0, 13, 42, 11, 5, 12, 22, 195, 161, 18, 8, 1, 20, 195, 179, 109, 55, 84, 114, 52, 107, 108, 47, 115, 23, 89, 109, 52, 37, 50, 47, 109, 0, 13, 81, 115, 122, 101, 114, 105, 110, 116, 101, 32, 12, 137, 19, 26, 195, 161, 13, 15, 4, 18, 1, 13, 14, 139, 6, 21, 20, 20, 1, 20, 8, 1, 20, 195, 179, 13, 12, 137, 5, 12, 11, 195, 182, 12, 20, 22, 5, 13, 14, 139, 20, 1, 12, 195, 161, 12, 8, 1, 20, 195, 179, 13, 0, 15, 140, 11, 1, 16, 3, 19, 15, 12, 8, 1, 20, 195, 179, 13, 9, 198, 88, 148, 197, 49, 65, 77, 13, 11, 136, 8, 1, 20, 195, 161, 19, 21, 11, 13, 15, 140, 6, 15, 18, 4, 195, 173, 20, 8, 1, 20, 195, 179, 13, 6, 195, 32, 149, 20, 13, 15, 8, 95, 35, 45, 195, 169, 14, 5, 11, 113, 50, 109, 49, 0, 0, 7, 196, 24, 82, 133, 16, 13, 16, 141, 11, 9, 20, 1, 12, 195, 161, 12, 8, 1, 20, 195, 179, 13, 12, 137, 22, 9, 12, 195, 161, 7, 14, 1, 11, 13, 0, 14, 139, 8, 195, 169, 20, 22, 195, 169, 7, 195, 169, 14, 13, 40, 14, 12, 5, 8, 5, 20, 197, 145, 19, 195, 169, 7, 195, 188, 11, 55, 109, 107, 109, 47, 118, 91, 113, 81, 111, 49, 23, 108, 52, 52, 108, 0, 13, 81, 97, 114, 114, 97, 32, 6, 195, 77, 161, 82, 72, 0, 9, 198, 80, 148, 9, 45, 84, 192, 13, 9, 134, 8, 195, 179, 14, 1, 16, 13, 0, 17, 142, 5, 12, 5, 11, 20, 18, 15, 14, 9, 11, 195, 161, 10, 1, 13, 0, 11, 136, 3, 195, 169, 12, 10, 1, 9, 20, 13, 50, 72, 36, 229, 5, 72, 225, 84, 21, 48, 37, 50, 47, 109, 52, 50, 109, 47, 109, 91, 15, 49, 37, 47, 110, 55, 47, 113, 91, 113, 52, 109, 0, 13, 81, 107, 105, 116, 195, 182, 108, 116, 195, 169, 115, 195, 169, 114, 101, 32, 20, 145, 13, 5, 7, 195, 161, 12, 12, 1, 16, 195, 173, 20, 8, 1, 20, 195, 179, 13, 0, 45, 10, 2, 197, 177, 14, 195, 182, 19, 14, 5, 11, 71, 117, 50, 110, 91, 50, 109, 49, 10, 6, 15, 47, 108, 55, 114, 61, 57, 114, 49, 0, 13, 81, 116, 97, 108, 195, 161, 108, 106, 195, 161, 107, 32, 12, 137, 7, 25, 5, 18, 5, 11, 195, 169, 20, 13, 14, 139, 195, 169, 16, 195, 188, 12, 5, 20, 2, 5, 14, 13, 14, 139, 11, 5, 18, 195, 188, 12, 5, 20, 2, 5, 14, 13, 0, 12, 137, 11, 5, 26, 4, 197, 145, 4, 197, 145, 13, 14, 139, 6, 21, 14, 11, 3, 9, 195, 179, 14, 1, 11, 13, 0, 0, 11, 136, 5, 7, 195, 169, 19, 26, 5, 20, 13, 0, 8, 197, 77, 160, 66, 4, 64, 76, 11, 136, 13, 195, 169, 18, 5, 20, 197, 177, 13, 64, 14, 6, 5, 12, 22, 195, 169, 20, 5, 12, 195, 169, 14, 5, 11, 83, 109, 55, 84, 113, 47, 109, 55, 113, 50, 109, 49, 23, 89, 111, 49, 91, 113, 81, 109, 91, 12, 113, 81, 113, 47, 0, 13, 81, 115, 122, 195, 188, 107, 115, 195, 169, 103, 101, 115, 115, 195, 169, 103, 195, 169, 116, 32, 11, 136, 195, 169, 16, 195, 188, 12, 197, 145, 13, 6, 195, 36, 113, 78, 13, 8, 133, 11, 195, 169, 18, 20, 13, 10, 4, 95, 49, 48, 5, 47, 37, 88, 0, 0, 0, 14, 139, 195, 169, 12, 13, 195, 169, 14, 25, 195, 169, 20, 13, 10, 199, 24, 148, 148, 5, 52, 213, 44, 13, 19, 144, 14, 195, 182, 22, 5, 11, 5, 4, 195, 169, 19, 195, 169, 14, 5, 11, 13, 14, 139, 20, 195, 161, 18, 8, 5, 12, 25, 195, 169, 20, 13, 32, 7, 18, 5, 1, 7, 195, 161, 12, 52, 109, 108, 81, 114, 55, 23, 47, 110, 71, 12, 113, 0, 13, 81, 116, 195, 182, 98, 98, 195, 169, 32, 6, 195, 60, 176, 64, 13, 10, 199, 20, 197, 133, 32, 85, 9, 44, 13, 10, 135, 195, 173, 7, 195, 169, 18, 20, 13, 0, 7, 196, 77, 162, 78, 80, 13, 0, 10, 135, 16, 9, 1, 3, 195, 161, 14, 13, 8, 133, 6, 9, 195, 186, 20, 13, 8, 133, 2, 197, 145, 18, 20, 13, 0, 39, 66, 5, 160, 108, 88, 23, 113, 52, 47, 113, 49, 109, 91, 112, 47, 113, 91, 47, 0, 13, 81, 195, 169, 114, 116, 195, 169, 107, 101, 115, 195, 173, 116, 195, 169, 115, 116, 32, 32, 66, 5, 160, 108, 88, 23, 109, 55, 12, 109, 50, 113, 52, 84, 109, 49, 0, 13, 81, 101, 108, 108, 101, 110, 195, 169, 114, 118, 101, 107, 32, 22, 66, 5, 160, 108, 88, 23, 37, 72, 118, 52, 109, 0, 13, 81, 105, 100, 197, 145, 114, 101, 32, 18, 66, 5, 160, 108, 88, 23, 89, 108, 52, 0, 13, 81, 115, 122, 97, 114, 32, 34, 66, 5, 160, 108, 88, 23, 108, 55, 108, 48, 113, 55, 65, 113, 67, 109, 0, 13, 81, 97, 108, 97, 112, 195, 169, 108, 109, 195, 169, 110, 121, 101, 32, 25, 66, 5, 160, 108, 88, 23, 111, 79, 109, 49, 109, 47, 0, 13, 81, 195, 188, 103, 121, 101, 107, 101, 116, 32, 27, 66, 5, 160, 108, 88, 23, 111, 79, 109, 49, 71, 109, 50, 0, 13, 81, 195, 188, 103, 121, 101, 107, 98, 101, 110, 32, 29, 66, 5, 160, 108, 88, 10, 6, 15, 108, 72, 108, 47, 39, 49, 108, 47, 0, 13, 81, 97, 100, 97, 116, 111, 107, 97, 116, 32, 32, 66, 5, 160, 108, 88, 10, 6, 15, 37, 50, 72, 39, 49, 55, 114, 91, 47, 0, 13, 81, 105, 110, 100, 111, 107, 108, 195, 161, 115, 116, 32, 22, 66, 5, 160, 108, 88, 10, 6, 15, 109, 55, 91, 118, 0, 13, 81, 101, 108, 115, 197, 145, 32, 28, 66, 5, 160, 108, 88, 10, 6, 15, 37, 55, 12, 109, 47, 118, 47, 0, 13, 81, 105, 108, 108, 101, 116, 197, 145, 116, 32, 27, 66, 5, 160, 108, 88, 10, 6, 15, 109, 91, 109, 47, 71, 109, 50, 0, 13, 81, 101, 115, 101, 116, 98, 101, 110, 32, 27, 66, 5, 160, 108, 88, 10, 6, 15, 49, 109, 55, 12, 109, 50, 109, 0, 13, 81, 107, 101, 108, 108, 101, 110, 101, 32, 23, 66, 5, 160, 108, 88, 10, 6, 15, 114, 52, 114, 47, 0, 13, 81, 195, 161, 114, 195, 161, 116, 32, 34, 66, 5, 160, 108, 88, 10, 6, 15, 109, 89, 49, 110, 88, 110, 49, 109, 47, 0, 13, 81, 101, 115, 122, 107, 195, 182, 122, 195, 182, 107, 101, 116, 32, 22, 66, 5, 160, 108, 88, 10, 6, 15, 113, 84, 109, 47, 0, 13, 81, 195, 169, 118, 101, 116, 32, 22, 66, 5, 160, 108, 88, 10, 6, 15, 37, 72, 118, 47, 0, 13, 81, 105, 100, 197, 145, 116, 32, 24, 66, 5, 160, 108, 88, 10, 6, 15, 108, 6, 15, 71, 108, 57, 0, 13, 82, 97, 32, 98, 97, 106, 32, 21, 66, 5, 160, 108, 88, 10, 6, 15, 108, 72, 108, 47, 0, 13, 81, 97, 100, 97, 116, 32, 31, 66, 5, 160, 108, 88, 10, 6, 15, 39, 34, 89, 114, 81, 71, 108, 50, 0, 13, 81, 111, 114, 115, 122, 195, 161, 103, 98, 97, 110, 32, 23, 66, 5, 160, 108, 88, 10, 6, 15, 109, 55, 84, 109, 47, 0, 13, 81, 101, 108, 118, 101, 116, 32, 24, 66, 5, 160, 108, 88, 10, 6, 15, 113, 61, 57, 109, 55, 0, 13, 81, 195, 169, 106, 106, 101, 108, 32, 23, 66, 5, 160, 108, 88, 10, 6, 15, 108, 50, 81, 39, 55, 0, 13, 81, 97, 110, 103, 111, 108, 32, 34, 66, 5, 160, 108, 88, 10, 6, 15, 37, 50, 72, 112, 47, 84, 114, 67, 108, 0, 13, 81, 105, 110, 100, 195, 173, 116, 118, 195, 161, 110, 121, 97, 32, 25, 66, 5, 160, 108, 88, 10, 6, 15, 39, 55, 72, 108, 55, 47, 0, 13, 81, 111, 108, 100, 97, 108, 116, 32, 26, 66, 5, 160, 108, 88, 10, 6, 15, 111, 79, 52, 118, 55, 0, 13, 81, 195, 188, 103, 121, 114, 197, 145, 108, 32, 35, 66, 5, 160, 108, 88, 10, 6, 15, 109, 55, 50, 110, 49, 91, 113, 81, 109, 47, 0, 13, 81, 101, 108, 110, 195, 182, 107, 115, 195, 169, 103, 101, 116, 32, 36, 66, 5, 160, 108, 88, 10, 6, 15, 109, 79, 12, 109, 91, 111, 55, 109, 47, 109, 49, 0, 13, 81, 101, 103, 121, 101, 115, 195, 188, 108, 101, 116, 101, 107, 32, 39, 66, 5, 160, 108, 88, 10, 6, 15, 109, 55, 118, 52, 109, 57, 109, 55, 88, 113, 91, 109, 0, 13, 81, 101, 108, 197, 145, 114, 101, 106, 101, 108, 122, 195, 169, 115, 101, 32, 36, 66, 5, 160, 108, 88, 10, 6, 15, 37, 50, 47, 113, 88, 65, 113, 67, 109, 49, 0, 13, 81, 105, 110, 116, 195, 169, 122, 109, 195, 169, 110, 121, 101, 107, 32, 36, 66, 5, 160, 108, 88, 10, 6, 15, 37, 50, 72, 39, 49, 55, 114, 91, 12, 108, 55, 0, 13, 81, 105, 110, 100, 111, 107, 108, 195, 161, 115, 115, 97, 108, 32, 36, 66, 5, 160, 108, 88, 10, 6, 15, 114, 55, 12, 108, 48, 39, 47, 40, 49, 39, 50, 0, 13, 81, 195, 161, 108, 108, 97, 112, 111, 116, 117, 107, 111, 110, 32, 38, 66, 5, 160, 108, 88, 23, 91, 109, 65, 23, 89, 39, 49, 84, 114, 67, 39, 91, 0, 13, 82, 115, 101, 109, 32, 115, 122, 111, 107, 118, 195, 161, 110, 121, 111, 115, 32, 25, 66, 5, 160, 108, 88, 10, 6, 15, 111, 79, 71, 109, 50, 0, 13, 81, 195, 188, 103, 121, 98, 101, 110, 32, 41, 66, 5, 160, 108, 88, 10, 6, 15, 108, 55, 108, 48, 37, 55, 12, 109, 47, 65, 113, 67, 109, 0, 13, 81, 97, 108, 97, 112, 105, 108, 108, 101, 116, 109, 195, 169, 110, 121, 101, 32, 29, 66, 5, 160, 108, 88, 10, 6, 15, 37, 88, 81, 108, 55, 65, 108, 91, 0, 13, 81, 105, 122, 103, 97, 108, 109, 97, 115, 32, 30, 66, 5, 160, 108, 88, 23, 108, 6, 15, 49, 113, 52, 72, 113, 91, 0, 13, 82, 97, 32, 107, 195, 169, 114, 100, 195, 169, 115, 32, 34, 66, 5, 160, 108, 88, 23, 37, 50, 47, 113, 88, 109, 47, 109, 49, 109, 47, 0, 13, 81, 105, 110, 116, 195, 169, 122, 101, 116, 101, 107, 101, 116, 32, 21, 66, 5, 160, 108, 88, 23, 109, 55, 84, 109, 47, 0, 13, 81, 101, 108, 118, 101, 116, 32, 24, 66, 5, 160, 108, 88, 23, 113, 55, 109, 47, 109, 72, 0, 13, 81, 195, 169, 108, 101, 116, 101, 100, 32, 31, 66, 5, 160, 108, 88, 6, 23, 116, 57, 112, 47, 114, 91, 39, 49, 0, 13, 81, 195, 186, 106, 195, 173, 116, 195, 161, 115, 111, 107, 32, 31, 66, 5, 160, 108, 88, 6, 23, 114, 55, 12, 108, 48, 39, 47, 39, 65, 0, 13, 81, 195, 161, 108, 108, 97, 112, 111, 116, 111, 109, 32, 38, 66, 5, 160, 108, 88, 10, 6, 15, 37, 50, 47, 109, 52, 50, 109, 47, 109, 88, 113, 91, 0, 13, 81, 105, 110, 116, 101, 114, 110, 101, 116, 101, 122, 195, 169, 115, 32, 35, 66, 5, 160, 108, 88, 10, 6, 15, 108, 6, 15, 48, 52, 39, 71, 55, 113, 65, 108, 0, 13, 82, 97, 32, 112, 114, 111, 98, 108, 195, 169, 109, 97, 32, 25, 66, 5, 160, 108, 88, 6, 15, 10, 113, 89, 108, 49, 37, 0, 13, 81, 195, 169, 115, 122, 97, 107, 105, 32, 18, 66, 5, 160, 108, 88, 23, 109, 91, 118, 0, 13, 81, 101, 115, 197, 145, 32, 17, 66, 5, 160, 108, 88, 23, 113, 4, 81, 0, 13, 81, 195, 169, 103, 32, 17, 66, 5, 160, 108, 88, 23, 84, 108, 50, 0, 13, 81, 118, 97, 110, 32, 22, 66, 5, 160, 108, 88, 23, 37, 50, 83, 115, 47, 0, 13, 81, 105, 110, 102, 195, 179, 116, 32, 15, 66, 5, 160, 108, 88, 15, 37, 91, 0, 13, 81, 105, 115, 32, 20, 66, 5, 160, 10, 108, 88, 15, 84, 39, 55, 47, 0, 13, 81, 118, 111, 108, 116, 32, 9, 134, 20, 195, 161, 18, 15, 12, 13, 6, 194, 5, 160, 72, 12, 0, 15, 140, 19, 26, 195, 169, 12, 12, 195, 182, 11, 195, 169, 19, 13, 8, 133, 11, 195, 169, 19, 26, 13, 0, 11, 136, 3, 195, 169, 7, 195, 169, 18, 20, 13, 9, 134, 16, 195, 161, 18, 15, 14, 13, 14, 139, 22, 9, 26, 19, 7, 195, 161, 12, 1, 20, 1, 13, 0, 12, 137, 16, 195, 169, 12, 4, 195, 161, 21, 12, 13, 8, 133, 11, 195, 169, 19, 20, 13, 15, 69, 29, 145, 83, 21, 96, 79, 109, 91, 109, 84, 0, 42, 42, 0, 39, 70, 44, 83, 12, 21, 69, 0, 49, 109, 55, 12, 109, 47, 12, 23, 49, 108, 48, 76, 39, 55, 50, 39, 65, 0, 13, 81, 107, 97, 112, 99, 115, 111, 108, 110, 111, 109, 32, 29, 70, 44, 83, 12, 21, 69, 0, 49, 109, 55, 12, 109, 47, 12, 23, 108, 107, 39, 88, 0, 13, 81, 97, 104, 104, 111, 122, 32, 40, 70, 44, 83, 12, 21, 69, 0, 49, 109, 55, 12, 109, 47, 12, 23, 109, 55, 39, 55, 84, 108, 91, 50, 39, 65, 0, 13, 81, 101, 108, 111, 108, 118, 97, 115, 110, 111, 109, 32, 13, 138, 20, 195, 182, 13, 5, 7, 18, 197, 145, 12, 13, 9, 198, 44, 83, 12, 21, 69, 0, 13, 6, 131, 8, 195, 179, 13, 0, 10, 135, 20, 15, 10, 195, 161, 19, 20, 13, 29, 67, 5, 165, 0, 108, 89, 47, 10, 6, 15, 84, 114, 52, 57, 114, 49, 0, 13, 81, 118, 195, 161, 114, 106, 195, 161, 107, 32, 31, 67, 5, 165, 0, 108, 89, 47, 10, 6, 15, 89, 109, 52, 109, 47, 50, 113, 0, 13, 81, 115, 122, 101, 114, 101, 116, 110, 195, 169, 32, 27, 67, 5, 165, 0, 108, 89, 47, 10, 6, 15, 57, 109, 55, 88, 37, 49, 0, 13, 81, 106, 101, 108, 122, 105, 107, 32, 38, 67, 5, 165, 0, 108, 89, 47, 10, 6, 15, 79, 108, 50, 112, 47, 39, 47, 12, 114, 49, 0, 13, 81, 103, 121, 97, 110, 195, 173, 116, 111, 116, 116, 195, 161, 107, 32, 33, 67, 5, 165, 0, 108, 89, 47, 10, 6, 49, 113, 48, 84, 37, 91, 109, 55, 37, 0, 13, 81, 107, 195, 169, 112, 118, 105, 115, 101, 108, 105, 32, 37, 67, 5, 165, 0, 108, 89, 47, 6, 23, 108, 23, 107, 108, 79, 39, 65, 114, 67, 47, 0, 13, 82, 97, 32, 104, 97, 103, 121, 111, 109, 195, 161, 110, 121, 116, 32, 36, 67, 5, 165, 0, 108, 89, 47, 23, 47, 108, 48, 108, 89, 47, 108, 55, 47, 108, 65, 0, 13, 81, 116, 97, 112, 97, 115, 122, 116, 97, 108, 116, 97, 109, 32, 37, 67, 5, 165, 0, 108, 89, 47, 23, 47, 108, 50, 114, 76, 39, 57, 57, 57, 114, 49, 0, 13, 81, 116, 97, 110, 195, 161, 99, 115, 111, 108, 106, 195, 161, 107, 32, 56, 67, 5, 165, 0, 108, 89, 47, 23, 49, 113, 52, 47, 109, 23, 108, 88, 23, 114, 55, 12, 108, 65, 47, 37, 47, 49, 114, 52, 0, 13, 83, 107, 195, 169, 114, 116, 101, 32, 97, 122, 32, 195, 161, 108, 108, 97, 109, 116, 105, 116, 107, 195, 161, 114, 32, 14, 195, 5, 165, 0, 13, 81, 108, 195, 161, 116, 110, 105, 32, 10, 195, 5, 165, 0, 13, 81, 105, 115, 32, 6, 195, 5, 165, 0, 13, 12, 137, 6, 15, 12, 25, 1, 13, 195, 161, 14, 20, 0, 11, 200, 72, 83, 132, 20, 193, 84, 21, 64, 13, 25, 67, 96, 146, 73, 47, 37, 88, 109, 50, 107, 114, 52, 39, 65, 12, 108, 55, 0, 44, 42, 81, 97, 108, 32, 0, 12, 201, 56, 85, 133, 48, 177, 68, 21, 69, 0, 13, 16, 141, 8, 1, 10, 12, 195, 169, 11, 20, 1, 12, 1, 14, 20, 13, 0, 6, 194, 16, 80, 76, 8, 0, 10, 135, 195, 173, 18, 195, 161, 19, 20, 13, 0, 10, 135, 7, 25, 197, 145, 26, 14, 9, 13, 14, 139, 22, 195, 161, 12, 1, 19, 26, 20, 1, 14, 9, 13, 7, 196, 5, 32, 78, 100, 13, 0, 8, 197, 24, 241, 213, 56, 176, 76, 11, 136, 20, 1, 12, 195, 161, 12, 14, 9, 13, 8, 197, 28, 243, 132, 40, 16, 13, 0, 10, 135, 22, 5, 18, 26, 9, 195, 179, 13, 21, 146, 11, 195, 182, 26, 2, 9, 26, 20, 15, 14, 19, 195, 161, 7, 195, 169, 18, 20, 13, 9, 198, 80, 149, 5, 44, 85, 0, 13, 0, 10, 199, 44, 20, 3, 76, 243, 14, 36, 13, 30, 7, 11, 5, 18, 195, 188, 12, 20, 49, 109, 52, 111, 55, 47, 23, 89, 115, 71, 108, 0, 13, 81, 115, 122, 195, 179, 98, 97, 32, 29, 7, 11, 5, 18, 195, 188, 12, 20, 49, 109, 52, 111, 55, 47, 23, 108, 107, 39, 88, 0, 13, 81, 97, 104, 104, 111, 122, 32, 10, 135, 11, 5, 18, 195, 188, 12, 20, 13, 14, 139, 22, 195, 161, 12, 20, 15, 26, 195, 161, 19, 20, 13, 10, 199, 48, 83, 69, 57, 65, 78, 36, 13, 10, 135, 11, 5, 18, 195, 188, 12, 20, 13, 25, 67, 96, 146, 64, 47, 37, 88, 109, 50, 49, 109, 47, 12, 118, 84, 109, 55, 0, 44, 42, 81, 101, 108, 32, 0, 22, 68, 20, 65, 9, 28, 109, 72, 12, 37, 81, 23, 91, 109, 65, 0, 13, 81, 115, 101, 109, 32, 11, 136, 9, 4, 195, 169, 26, 5, 20, 20, 13, 15, 204, 24, 145, 217, 20, 195, 69, 105, 65, 84, 21, 69, 0, 13, 7, 196, 88, 83, 142, 36, 13, 7, 196, 88, 147, 142, 36, 13, 12, 4, 95, 4, 16, 20, 15, 109, 81, 113, 89, 0, 0, 8, 197, 104, 18, 140, 36, 176, 13, 15, 140, 13, 5, 7, 11, 195, 188, 26, 4, 5, 14, 9, 5, 13, 47, 14, 14, 25, 9, 12, 22, 195, 161, 14, 15, 19, 19, 195, 161, 7, 67, 37, 55, 84, 114, 50, 39, 91, 12, 114, 81, 23, 89, 114, 65, 114, 52, 108, 0, 13, 81, 115, 122, 195, 161, 109, 195, 161, 114, 97, 32, 12, 201, 8, 148, 218, 80, 244, 207, 44, 21, 0, 13, 8, 197, 52, 83, 142, 20, 176, 13, 11, 136, 20, 195, 169, 13, 195, 161, 18, 1, 13, 12, 201, 52, 81, 207, 48, 64, 78, 84, 226, 192, 13, 8, 197, 32, 148, 218, 20, 208, 13, 15, 4, 95, 49, 48, 17, 47, 37, 88, 109, 72, 37, 49, 109, 0, 0, 32, 11, 13, 5, 7, 15, 12, 4, 8, 1, 20, 195, 179, 65, 109, 81, 39, 55, 72, 107, 108, 47, 115, 23, 108, 88, 0, 13, 81, 97, 122, 32, 13, 138, 195, 169, 18, 20, 5, 19, 195, 188, 12, 20, 13, 9, 198, 52, 17, 213, 44, 21, 0, 13, 5, 194, 21, 48, 72, 0, 39, 67, 56, 83, 64, 50, 109, 65, 23, 57, 109, 55, 109, 50, 47, 23, 91, 109, 65, 12, 37, 47, 0, 13, 82, 106, 101, 108, 101, 110, 116, 32, 115, 101, 109, 109, 105, 116, 32, 31, 71, 56, 147, 131, 76, 83, 133, 44, 50, 37, 50, 76, 109, 50, 109, 49, 23, 52, 115, 55, 108, 0, 13, 81, 114, 195, 179, 108, 97, 32, 12, 137, 195, 188, 12, 195, 169, 19, 195, 169, 14, 13, 47, 67, 56, 83, 64, 50, 109, 65, 23, 84, 39, 55, 47, 23, 47, 37, 89, 47, 109, 91, 12, 113, 81, 109, 91, 0, 13, 82, 118, 111, 108, 116, 32, 116, 105, 115, 122, 116, 101, 115, 115, 195, 169, 103, 101, 115, 32, 24, 67, 56, 83, 64, 50, 109, 65, 23, 55, 114, 47, 12, 108, 0, 13, 81, 108, 195, 161, 116, 116, 97, 32, 21, 67, 56, 83, 64, 50, 109, 65, 23, 84, 39, 55, 47, 0, 13, 81, 118, 111, 108, 116, 32, 44, 67, 56, 83, 64, 50, 109, 65, 23, 65, 39, 88, 81, 108, 47, 12, 108, 23, 47, 39, 84, 114, 71, 12, 0, 13, 82, 109, 111, 122, 103, 97, 116, 116, 97, 32, 116, 111, 118, 195, 161, 98, 98, 32, 14, 203, 77, 161, 82, 88, 86, 133, 80, 82, 206, 20, 176, 13, 20, 67, 56, 83, 64, 50, 109, 65, 23, 55, 109, 89, 0, 13, 81, 108, 101, 115, 122, 32, 40, 67, 56, 83, 64, 50, 109, 65, 15, 65, 109, 52, 47, 109, 65, 15, 55, 109, 112, 52, 50, 37, 0, 13, 82, 109, 101, 114, 116, 101, 109, 32, 108, 101, 195, 173, 114, 110, 105, 32, 14, 139, 18, 195, 169, 19, 26, 5, 19, 195, 188, 12, 20, 13, 10, 135, 195, 169, 16, 195, 188, 12, 20, 13, 7, 195, 56, 83, 64, 102, 12, 8, 195, 56, 83, 64, 12, 23, 22, 15, 8, 95, 35, 45, 195, 161, 14, 1, 11, 114, 50, 108, 49, 0, 0, 14, 139, 20, 1, 18, 20, 1, 12, 13, 195, 161, 18, 1, 13, 14, 139, 11, 195, 169, 18, 5, 12, 13, 195, 169, 18, 5, 13, 0, 12, 201, 64, 243, 9, 80, 146, 213, 76, 18, 64, 13, 15, 140, 9, 11, 15, 14, 20, 195, 169, 13, 195, 161, 18, 1, 13, 12, 201, 77, 161, 82, 88, 86, 133, 81, 65, 76, 13, 0, 9, 134, 195, 188, 12, 197, 145, 20, 13, 12, 137, 20, 195, 161, 12, 3, 195, 161, 18, 1, 13, 9, 198, 80, 85, 19, 104, 85, 20, 13, 0, 47, 67, 88, 85, 20, 84, 109, 47, 12, 23, 108, 23, 47, 114, 34, 79, 108, 55, 114, 91, 39, 49, 71, 108, 50, 0, 13, 82, 97, 32, 116, 195, 161, 114, 103, 121, 97, 108, 195, 161, 115, 111, 107, 98, 97, 110, 32, 8, 133, 14, 25, 195, 161, 18, 13, 6, 195, 88, 85, 20, 13, 8, 133, 14, 25, 195, 161, 18, 20, 14, 4, 95, 49, 48, 15, 47, 37, 88, 109, 72, 37, 49, 0, 0, 17, 142, 6, 5, 10, 12, 5, 19, 26, 20, 195, 169, 19, 195, 169, 14, 13, 17, 142, 22, 9, 19, 5, 12, 11, 5, 4, 195, 169, 19, 195, 169, 14, 13, 18, 143, 9, 14, 20, 195, 169, 26, 13, 195, 169, 14, 25, 5, 11, 2, 5, 13, 0, 17, 142, 22, 15, 14, 21, 12, 8, 1, 20, 14, 195, 161, 14, 1, 11, 13, 12, 137, 22, 9, 12, 195, 161, 7, 195, 161, 20, 13, 12, 201, 44, 145, 133, 41, 65, 84, 80, 83, 64, 13, 13, 138, 12, 195, 161, 20, 19, 26, 1, 14, 1, 11, 13, 17, 10, 95, 35, 45, 9, 11, 195, 169, 14, 5, 11, 113, 50, 109, 49, 0, 0, 29, 10, 15, 12, 3, 19, 195, 179, 2, 2, 1, 20, 39, 55, 76, 115, 71, 12, 108, 47, 23, 37, 91, 0, 13, 81, 105, 115, 32, 20, 145, 13, 5, 7, 195, 161, 12, 12, 195, 173, 20, 195, 161, 19, 195, 161, 18, 1, 13, 13, 138, 20, 1, 7, 19, 195, 161, 7, 195, 161, 20, 13, 9, 198, 52, 243, 132, 80, 19, 64, 13, 0, 14, 139, 11, 18, 9, 20, 9, 11, 195, 161, 11, 1, 20, 13, 9, 198, 24, 18, 193, 17, 64, 77, 13, 10, 135, 11, 195, 169, 16, 5, 9, 20, 13, 0, 14, 139, 195, 188, 26, 5, 13, 5, 12, 20, 5, 20, 9, 13, 23, 67, 61, 36, 129, 39, 52, 52, 108, 10, 6, 15, 108, 55, 114, 0, 13, 81, 97, 108, 195, 161, 32, 16, 141, 1, 12, 11, 15, 20, 13, 195, 161, 14, 25, 14, 1, 11, 13, 9, 3, 95, 35, 57, 47, 108, 71, 0, 12, 4, 95, 20, 12, 4, 47, 37, 55, 72, 109, 0, 0, 15, 140, 195, 186, 10, 18, 1, 195, 173, 18, 195, 161, 19, 1, 13, 0, 0, 17, 142, 22, 195, 169, 12, 5, 13, 195, 169, 14, 25, 5, 26, 14, 9, 13, 8, 133, 15, 11, 195, 161, 14, 13, 13, 138, 8, 1, 20, 195, 161, 18, 15, 26, 14, 9, 13, 11, 67, 4, 197, 0, 108, 55, 47, 0, 42, 42, 0, 23, 68, 76, 147, 131, 76, 91, 37, 50, 76, 15, 81, 39, 50, 72, 0, 13, 81, 103, 111, 110, 100, 32, 37, 68, 76, 147, 131, 76, 91, 37, 50, 76, 23, 109, 79, 12, 109, 47, 113, 52, 47, 113, 91, 0, 13, 81, 101, 103, 121, 101, 116, 195, 169, 114, 116, 195, 169, 115, 32, 11, 136, 19, 26, 15, 12, 7, 195, 161, 12, 13, 14, 139, 8, 5, 12, 25, 5, 26, 8, 5, 20, 197, 145, 13, 7, 196, 76, 147, 131, 76, 13, 7, 132, 197, 145, 18, 20, 13, 7, 132, 195, 161, 18, 20, 13, 7, 196, 72, 244, 211, 104, 13, 0, 19, 144, 11, 195, 182, 18, 2, 5, 10, 195, 161, 20, 19, 26, 195, 161, 19, 1, 13, 15, 140, 11, 9, 20, 195, 182, 12, 20, 8, 5, 20, 197, 145, 13, 0, 11, 136, 3, 195, 173, 13, 5, 11, 5, 14, 13, 9, 134, 7, 25, 195, 186, 10, 20, 13, 5, 194, 21, 64, 13, 0, 21, 67, 17, 97, 0, 100, 195, 169, 118, 195, 169, 100, 195, 169, 109, 0, 44, 29, 81, 109, 32, 22, 67, 17, 97, 0, 100, 195, 169, 118, 195, 169, 100, 195, 169, 116, 0, 44, 29, 42, 81, 109, 32, 22, 67, 17, 97, 0, 100, 195, 169, 118, 195, 169, 100, 195, 169, 100, 0, 44, 29, 42, 81, 100, 32, 21, 67, 17, 97, 0, 100, 195, 169, 118, 195, 169, 100, 195, 169, 100, 0, 44, 29, 81, 100, 32, 21, 67, 17, 97, 0, 100, 195, 169, 118, 195, 169, 100, 195, 169, 110, 0, 44, 29, 81, 110, 32, 22, 67, 17, 97, 0, 100, 195, 169, 118, 195, 169, 100, 195, 169, 110, 0, 44, 29, 42, 81, 110, 32, 21, 67, 17, 97, 0, 100, 195, 169, 118, 195, 169, 100, 195, 169, 107, 0, 44, 29, 81, 107, 32, 22, 67, 17, 97, 0, 100, 195, 169, 118, 195, 169, 100, 195, 169, 107, 0, 44, 29, 42, 81, 107, 32, 43, 8, 8, 195, 188, 22, 5, 12, 25, 11, 107, 111, 84, 109, 57, 49, 10, 6, 15, 114, 47, 65, 113, 52, 118, 57, 117, 0, 13, 81, 195, 161, 116, 109, 195, 169, 114, 197, 145, 106, 197, 177, 32, 16, 141, 195, 161, 12, 12, 1, 13, 20, 9, 20, 11, 195, 161, 18, 13, 0, 16, 141, 20, 5, 18, 22, 5, 26, 8, 5, 20, 195, 188, 14, 11, 13, 18, 143, 8, 15, 26, 26, 195, 161, 6, 195, 169, 18, 8, 5, 20, 197, 145, 13, 11, 136, 9, 18, 195, 161, 14, 25, 21, 12, 13, 0, 0, 9, 198, 40, 241, 207, 77, 83, 20, 13, 13, 202, 4, 194, 193, 48, 208, 90, 104, 19, 129, 44, 13, 13, 138, 10, 195, 182, 22, 197, 145, 18, 197, 145, 12, 13, 14, 5, 95, 50, 77, 49, 5, 49, 113, 47, 109, 88, 52, 0, 0, 9, 134, 6, 197, 177, 26, 14, 9, 13, 0, 0, 6, 195, 36, 112, 90, 13, 0, 12, 137, 5, 18, 197, 145, 19, 195, 173, 20, 9, 13, 12, 137, 11, 195, 182, 26, 195, 182, 12, 14, 9, 13, 16, 141, 20, 1, 14, 20, 5, 19, 20, 195, 188, 12, 5, 20, 5, 13, 12, 137, 195, 161, 20, 14, 195, 169, 26, 14, 9, 13, 11, 5, 95, 48, 77, 49, 5, 109, 88, 52, 0, 0, 24, 67, 20, 118, 64, 109, 79, 23, 49, 37, 91, 12, 109, 71, 0, 13, 81, 107, 105, 115, 101, 98, 98, 32, 28, 67, 20, 118, 64, 109, 79, 10, 6, 15, 48, 52, 115, 71, 114, 47, 0, 13, 81, 112, 114, 195, 179, 98, 195, 161, 116, 32, 35, 67, 20, 118, 64, 109, 79, 10, 6, 15, 83, 39, 81, 108, 72, 114, 91, 40, 50, 49, 0, 13, 81, 102, 111, 103, 97, 100, 195, 161, 115, 117, 110, 107, 32, 37, 67, 20, 118, 64, 109, 79, 23, 107, 108, 57, 55, 113, 49, 47, 108, 55, 108, 50, 47, 0, 13, 81, 104, 97, 106, 108, 195, 169, 107, 116, 97, 108, 97, 110, 116, 32, 27, 67, 20, 118, 64, 109, 79, 23, 83, 115, 52, 40, 65, 39, 50, 0, 13, 81, 102, 195, 179, 114, 117, 109, 111, 110, 32, 9, 198, 52, 147, 132, 20, 226, 201, 13, 23, 67, 20, 118, 64, 109, 79, 10, 6, 15, 72, 37, 114, 49, 0, 13, 81, 100, 105, 195, 161, 107, 32, 25, 67, 20, 118, 64, 109, 79, 10, 6, 15, 83, 113, 52, 83, 37, 0, 13, 81, 102, 195, 169, 114, 102, 105, 32, 32, 67, 20, 118, 64, 109, 79, 23, 83, 109, 55, 65, 113, 52, 113, 91, 47, 0, 13, 81, 102, 101, 108, 109, 195, 169, 114, 195, 169, 115, 116, 32, 29, 67, 20, 118, 64, 109, 79, 23, 89, 39, 83, 47, 84, 109, 52, 47, 0, 13, 81, 115, 122, 111, 102, 116, 118, 101, 114, 116, 32, 38, 67, 20, 118, 64, 109, 79, 23, 112, 52, 114, 91, 47, 40, 72, 108, 47, 55, 108, 50, 0, 13, 81, 195, 173, 114, 195, 161, 115, 116, 117, 100, 97, 116, 108, 97, 110, 32, 22, 67, 20, 118, 64, 109, 79, 23, 37, 72, 109, 37, 81, 0, 13, 81, 105, 100, 101, 105, 103, 32, 23, 67, 20, 118, 64, 109, 79, 23, 81, 113, 48, 109, 47, 0, 13, 81, 103, 195, 169, 112, 101, 116, 32, 33, 67, 20, 118, 64, 109, 79, 23, 89, 108, 71, 108, 72, 50, 108, 48, 52, 108, 0, 13, 81, 115, 122, 97, 98, 97, 100, 110, 97, 112, 114, 97, 32, 10, 135, 11, 195, 169, 16, 5, 19, 20, 13, 6, 195, 20, 118, 64, 13, 0, 49, 12, 19, 26, 5, 18, 26, 197, 145, 4, 195, 169, 19, 20, 89, 109, 52, 88, 118, 72, 113, 91, 47, 23, 49, 109, 55, 12, 23, 49, 110, 47, 50, 37, 0, 13, 82, 107, 101, 108, 108, 32, 107, 195, 182, 116, 110, 105, 32, 11, 200, 65, 35, 198, 21, 52, 218, 61, 32, 13, 19, 144, 9, 14, 6, 15, 18, 13, 195, 161, 3, 9, 195, 179, 195, 169, 18, 20, 13, 15, 140, 19, 26, 5, 18, 26, 197, 145, 4, 195, 169, 19, 20, 13, 7, 196, 4, 227, 129, 44, 13, 0, 8, 197, 81, 81, 21, 56, 176, 76, 30, 6, 6, 15, 12, 25, 195, 179, 83, 39, 57, 115, 15, 84, 109, 52, 91, 109, 67, 0, 13, 81, 118, 101, 114, 115, 101, 110, 121, 32, 13, 138, 20, 195, 161, 18, 19, 1, 19, 195, 161, 7, 13, 8, 197, 48, 18, 212, 4, 176, 13, 0, 9, 198, 52, 147, 132, 20, 118, 64, 13, 42, 10, 13, 5, 7, 15, 12, 4, 195, 161, 19, 20, 65, 109, 81, 39, 55, 72, 114, 91, 47, 23, 113, 48, 112, 47, 23, 71, 109, 0, 13, 82, 195, 169, 112, 195, 173, 116, 32, 98, 101, 32, 23, 70, 32, 83, 25, 104, 85, 0, 107, 109, 57, 88, 109, 47, 23, 108, 88, 0, 13, 81, 97, 122, 32, 9, 198, 44, 244, 146, 20, 181, 0, 13, 9, 198, 32, 83, 25, 104, 85, 0, 13, 13, 138, 13, 5, 7, 15, 12, 4, 195, 161, 19, 20, 13, 16, 67, 61, 33, 139, 39, 109, 51, 109, 83, 49, 114, 0, 17, 42, 42, 0, 29, 7, 5, 12, 13, 195, 186, 12, 20, 109, 55, 65, 116, 55, 47, 23, 113, 84, 109, 49, 0, 13, 81, 195, 169, 118, 101, 107, 32, 10, 135, 18, 5, 16, 195, 188, 12, 20, 13, 8, 133, 7, 25, 197, 145, 26, 13, 10, 135, 14, 195, 169, 26, 5, 20, 20, 13, 0, 11, 136, 195, 161, 20, 195, 161, 12, 12, 20, 13, 11, 136, 22, 195, 169, 7, 26, 5, 20, 20, 13, 11, 136, 22, 195, 169, 7, 26, 5, 20, 20, 13, 15, 140, 5, 12, 4, 15, 2, 195, 161, 12, 195, 161, 19, 20, 13, 7, 196, 80, 82, 5, 72, 13, 10, 135, 13, 21, 14, 11, 195, 161, 13, 13, 7, 196, 16, 240, 142, 36, 13, 18, 5, 95, 50, 77, 49, 15, 49, 113, 47, 109, 88, 52, 109, 72, 37, 49, 0, 0, 27, 8, 20, 195, 182, 12, 20, 19, 5, 13, 47, 110, 55, 76, 109, 65, 23, 65, 109, 81, 0, 13, 81, 109, 101, 103, 32, 8, 197, 80, 84, 150, 20, 176, 13, 12, 137, 16, 18, 15, 4, 21, 11, 195, 161, 12, 13, 8, 197, 52, 83, 142, 36, 80, 13, 12, 201, 77, 160, 75, 20, 208, 133, 72, 82, 64, 13, 8, 133, 13, 195, 186, 12, 20, 13, 0, 14, 66, 21, 80, 101, 117, 110, 0, 44, 29, 42, 81, 110, 32, 12, 137, 3, 19, 9, 18, 11, 195, 169, 18, 5, 13, 22, 147, 19, 26, 15, 6, 20, 22, 5, 18, 6, 5, 10, 12, 5, 19, 26, 20, 197, 145, 11, 13, 9, 198, 80, 20, 148, 84, 226, 192, 13, 0, 18, 143, 2, 5, 18, 5, 14, 4, 5, 26, 11, 5, 4, 195, 169, 19, 20, 13, 9, 134, 2, 195, 173, 26, 14, 1, 13, 52, 10, 13, 5, 7, 15, 12, 4, 195, 161, 19, 9, 65, 109, 81, 39, 55, 72, 114, 91, 37, 23, 55, 109, 107, 109, 47, 118, 91, 113, 81, 12, 109, 55, 0, 13, 81, 108, 101, 104, 101, 116, 197, 145, 115, 195, 169, 103, 103, 101, 108, 32, 9, 134, 10, 195, 179, 11, 1, 9, 13, 10, 135, 12, 195, 169, 16, 5, 20, 20, 13, 0, 33, 11, 22, 1, 12, 195, 179, 19, 195, 173, 20, 10, 1, 84, 108, 55, 115, 91, 112, 80, 12, 108, 23, 65, 109, 81, 0, 13, 81, 109, 101, 103, 32, 19, 144, 8, 15, 26, 26, 195, 161, 10, 195, 161, 18, 21, 12, 195, 161, 19, 20, 13, 40, 8, 13, 9, 5, 12, 197, 145, 20, 20, 65, 37, 109, 55, 118, 47, 12, 23, 83, 39, 57, 47, 108, 47, 50, 114, 0, 13, 81, 102, 111, 108, 121, 116, 97, 116, 110, 195, 161, 32, 11, 200, 44, 146, 133, 48, 83, 148, 36, 176, 13, 14, 139, 20, 1, 18, 20, 195, 161, 19, 195, 161, 18, 1, 13, 0, 28, 8, 20, 1, 12, 195, 161, 12, 10, 1, 47, 108, 55, 114, 55, 57, 108, 23, 65, 109, 81, 0, 13, 81, 109, 101, 103, 32, 15, 140, 9, 14, 4, 21, 12, 195, 161, 19, 195, 161, 18, 1, 13, 30, 9, 11, 195, 182, 22, 5, 20, 5, 20, 20, 49, 110, 84, 109, 47, 109, 47, 12, 10, 6, 15, 109, 55, 0, 13, 81, 101, 108, 32, 12, 137, 11, 195, 182, 22, 5, 20, 5, 20, 20, 13, 12, 137, 195, 169, 18, 9, 14, 20, 5, 20, 20, 13, 0, 20, 5, 195, 161, 6, 195, 161, 195, 161, 102, 195, 161, 116, 0, 44, 29, 42, 81, 116, 32, 13, 138, 4, 195, 169, 12, 5, 12, 197, 145, 20, 20, 22, 0, 39, 7, 13, 21, 14, 11, 195, 161, 20, 65, 40, 50, 49, 114, 47, 10, 6, 15, 84, 113, 81, 109, 89, 47, 109, 49, 0, 13, 81, 118, 195, 169, 103, 101, 122, 116, 101, 107, 32, 26, 7, 13, 21, 14, 11, 195, 161, 20, 65, 40, 50, 49, 114, 47, 23, 37, 47, 12, 0, 13, 81, 105, 116, 116, 32, 14, 139, 11, 195, 173, 22, 195, 188, 12, 18, 197, 145, 12, 13, 10, 135, 20, 9, 20, 11, 195, 161, 20, 13, 10, 135, 13, 21, 14, 11, 195, 161, 20, 13, 12, 137, 16, 195, 169, 14, 20, 5, 11, 5, 14, 22, 0, 35, 68, 48, 82, 5, 80, 55, 109, 107, 109, 47, 23, 89, 114, 65, 112, 47, 108, 50, 37, 0, 13, 81, 115, 122, 195, 161, 109, 195, 173, 116, 97, 110, 105, 32, 38, 68, 48, 82, 5, 80, 55, 109, 107, 109, 47, 23, 108, 49, 108, 72, 114, 57, 39, 88, 50, 37, 0, 13, 81, 97, 107, 97, 100, 195, 161, 108, 121, 111, 122, 110, 105, 32, 18, 143, 6, 5, 14, 14, 20, 1, 18, 20, 195, 161, 19, 195, 161, 18, 1, 13, 25, 68, 48, 82, 5, 80, 55, 109, 107, 109, 47, 23, 113, 52, 50, 37, 0, 13, 81, 195, 169, 114, 110, 105, 32, 41, 68, 48, 82, 5, 80, 55, 109, 107, 109, 47, 10, 6, 15, 47, 40, 72, 50, 37, 10, 6, 15, 51, 115, 55, 108, 0, 13, 82, 116, 117, 100, 110, 105, 32, 114, 195, 179, 108, 97, 32, 33, 68, 48, 82, 5, 80, 55, 109, 107, 109, 47, 10, 6, 15, 37, 91, 65, 109, 52, 118, 91, 0, 13, 81, 105, 115, 109, 101, 114, 197, 145, 115, 32, 28, 68, 48, 82, 5, 80, 55, 109, 107, 109, 47, 10, 6, 15, 84, 109, 50, 12, 37, 0, 13, 81, 118, 101, 110, 110, 105, 32, 34, 68, 48, 82, 5, 80, 55, 109, 107, 109, 47, 10, 6, 15, 65, 108, 34, 49, 39, 55, 50, 37, 0, 13, 81, 109, 97, 114, 107, 111, 108, 110, 105, 32, 36, 68, 48, 82, 5, 80, 55, 109, 107, 109, 47, 10, 6, 15, 57, 109, 55, 109, 50, 47, 109, 50, 37, 0, 13, 81, 106, 101, 108, 101, 110, 116, 101, 110, 105, 32, 26, 68, 48, 82, 5, 80, 55, 109, 107, 109, 47, 23, 109, 88, 88, 109, 55, 0, 13, 81, 101, 122, 122, 101, 108, 32, 34, 68, 48, 82, 5, 80, 55, 109, 107, 109, 47, 23, 107, 108, 89, 50, 114, 55, 50, 37, 0, 13, 81, 104, 97, 115, 122, 110, 195, 161, 108, 110, 105, 32, 36, 68, 48, 82, 5, 80, 55, 109, 107, 109, 47, 23, 108, 88, 10, 6, 15, 111, 79, 71, 109, 50, 0, 13, 82, 97, 122, 32, 195, 188, 103, 121, 98, 101, 110, 32, 27, 68, 48, 82, 5, 80, 55, 109, 107, 109, 47, 23, 50, 113, 88, 50, 37, 0, 13, 81, 110, 195, 169, 122, 110, 105, 32, 32, 68, 48, 82, 5, 80, 55, 109, 107, 109, 47, 23, 76, 108, 48, 108, 72, 113, 49, 0, 13, 81, 99, 115, 97, 112, 97, 100, 195, 169, 107, 32, 7, 196, 80, 82, 5, 80, 13, 11, 136, 4, 195, 173, 10, 1, 11, 1, 20, 13, 7, 196, 88, 83, 5, 16, 13, 7, 196, 48, 82, 5, 80, 13, 14, 139, 195, 169, 10, 19, 26, 1, 11, 195, 161, 18, 1, 22, 0, 11, 136, 20, 1, 18, 20, 195, 161, 19, 1, 13, 0, 39, 9, 15, 12, 22, 1, 19, 195, 161, 19, 1, 39, 55, 84, 108, 91, 114, 91, 108, 10, 6, 15, 49, 110, 88, 71, 109, 50, 0, 13, 81, 107, 195, 182, 122, 98, 101, 110, 32, 14, 139, 6, 15, 18, 4, 195, 173, 20, 19, 195, 161, 11, 13, 13, 138, 20, 1, 14, 195, 161, 3, 19, 195, 161, 20, 13, 0, 10, 135, 20, 1, 14, 25, 195, 161, 20, 13, 14, 139, 20, 5, 18, 13, 195, 169, 11, 5, 11, 5, 20, 13, 5, 194, 4, 224, 72, 15, 66, 28, 32, 81, 37, 81, 108, 71, 114, 57, 47, 0, 42, 42, 0, 15, 140, 13, 195, 161, 19, 15, 4, 16, 5, 18, 3, 5, 20, 13, 12, 137, 5, 19, 5, 4, 195, 169, 11, 5, 19, 13, 6, 195, 72, 82, 148, 13, 6, 195, 24, 80, 128, 20, 0, 46, 13, 19, 26, 195, 161, 26, 1, 12, 195, 169, 11, 195, 161, 20, 89, 114, 88, 108, 55, 113, 49, 114, 47, 23, 47, 109, 89, 37, 49, 23, 49, 37, 0, 13, 82, 116, 101, 115, 122, 105, 107, 32, 107, 105, 32, 16, 141, 19, 26, 195, 161, 26, 1, 12, 195, 169, 11, 195, 161, 20, 13, 12, 137, 12, 195, 169, 22, 197, 145, 11, 5, 20, 13, 11, 136, 195, 169, 18, 26, 195, 169, 19, 5, 13, 7, 196, 20, 130, 5, 104, 13, 16, 141, 19, 26, 195, 161, 26, 1, 12, 195, 169, 11, 195, 161, 20, 13, 7, 196, 12, 83, 12, 4, 13, 15, 140, 2, 5, 14, 25, 195, 186, 10, 20, 195, 161, 19, 1, 13, 0, 12, 137, 6, 5, 12, 5, 12, 197, 145, 19, 5, 13, 24, 5, 11, 195, 182, 26, 20, 49, 110, 89, 47, 15, 84, 39, 55, 47, 0, 13, 81, 118, 111, 108, 116, 32, 9, 198, 61, 54, 148, 61, 163, 137, 13, 17, 142, 11, 195, 169, 16, 22, 9, 19, 5, 12, 197, 145, 11, 5, 20, 13, 11, 136, 20, 18, 195, 161, 7, 195, 161, 18, 13, 9, 134, 22, 195, 169, 12, 5, 13, 13, 9, 133, 11, 195, 182, 26, 20, 13, 22, 8, 133, 7, 195, 161, 26, 20, 13, 0, 14, 139, 195, 182, 19, 19, 26, 5, 7, 5, 11, 5, 20, 13, 18, 143, 11, 195, 169, 19, 26, 195, 188, 12, 195, 169, 11, 5, 11, 5, 20, 13, 14, 139, 22, 195, 161, 12, 1, 19, 26, 15, 11, 1, 20, 13, 14, 139, 195, 169, 18, 20, 195, 169, 11, 5, 11, 5, 20, 13, 6, 195, 32, 144, 129, 13, 11, 136, 195, 161, 16, 18, 9, 12, 9, 19, 20, 0, 15, 140, 8, 1, 12, 12, 7, 1, 20, 195, 179, 11, 1, 20, 13, 55, 12, 19, 26, 1, 14, 11, 3, 9, 195, 179, 11, 1, 20, 89, 108, 50, 49, 119, 37, 115, 49, 108, 47, 15, 108, 55, 49, 108, 55, 65, 108, 88, 88, 108, 50, 108, 49, 0, 13, 81, 97, 108, 107, 97, 108, 109, 97, 122, 122, 97, 110, 97, 107, 32, 14, 139, 7, 25, 197, 145, 26, 11, 195, 182, 4, 14, 9, 13, 10, 199, 72, 83, 132, 77, 161, 82, 20, 13, 15, 140, 8, 5, 12, 25, 19, 195, 169, 7, 5, 11, 5, 20, 13, 11, 67, 80, 16, 128, 47, 108, 71, 0, 42, 42, 0, 20, 145, 16, 1, 18, 1, 14, 3, 19, 14, 15, 11, 19, 195, 161, 7, 195, 161, 20, 13, 7, 196, 4, 66, 143, 56, 13, 36, 68, 24, 18, 148, 4, 83, 108, 57, 47, 108, 23, 57, 108, 84, 112, 47, 114, 91, 39, 49, 0, 13, 81, 106, 97, 118, 195, 173, 116, 195, 161, 115, 111, 107, 32, 11, 200, 8, 150, 129, 48, 243, 77, 4, 192, 13, 12, 137, 195, 169, 18, 20, 5, 20, 20, 5, 13, 13, 7, 196, 13, 49, 82, 20, 13, 6, 195, 80, 19, 139, 13, 7, 196, 72, 243, 131, 76, 13, 0, 11, 136, 14, 195, 169, 26, 14, 195, 169, 11, 13, 13, 138, 19, 26, 195, 188, 12, 5, 20, 20, 5, 13, 13, 9, 134, 195, 169, 18, 20, 5, 13, 13, 17, 142, 14, 5, 8, 195, 169, 26, 19, 195, 169, 7, 5, 11, 5, 20, 13, 0, 22, 66, 25, 64, 83, 39, 52, 37, 50, 47, 12, 115, 55, 0, 44, 13, 81, 116, 195, 179, 108, 32, 21, 66, 25, 64, 83, 39, 52, 37, 50, 47, 50, 108, 49, 0, 44, 13, 81, 110, 97, 107, 32, 19, 66, 25, 64, 83, 39, 52, 37, 50, 47, 71, 108, 0, 44, 13, 81, 98, 97, 32, 19, 66, 25, 64, 83, 39, 52, 37, 50, 47, 39, 47, 0, 44, 13, 81, 111, 116, 32, 21, 66, 25, 64, 83, 39, 52, 37, 50, 47, 12, 108, 55, 0, 44, 13, 81, 116, 97, 108, 32, 12, 66, 25, 64, 83, 39, 52, 37, 50, 47, 0, 13, 31, 6, 5, 19, 195, 169, 10, 20, 109, 91, 113, 57, 47, 10, 6, 15, 55, 114, 47, 39, 49, 0, 13, 81, 108, 195, 161, 116, 111, 107, 32, 0, 24, 6, 195, 182, 12, 20, 5, 11, 110, 55, 47, 109, 49, 23, 65, 109, 81, 0, 13, 81, 109, 101, 103, 32, 11, 136, 3, 195, 173, 13, 5, 26, 20, 5, 13, 10, 199, 88, 19, 1, 44, 147, 133, 44, 13, 9, 134, 195, 169, 18, 4, 5, 11, 13, 0, 8, 133, 4, 195, 169, 12, 9, 13, 11, 200, 77, 162, 210, 37, 5, 2, 20, 224, 13, 16, 141, 20, 5, 12, 5, 16, 195, 173, 20, 5, 20, 20, 5, 13, 13, 7, 196, 4, 67, 137, 4, 13, 0, 34, 10, 6, 5, 12, 20, 195, 169, 20, 5, 12, 5, 83, 109, 55, 47, 113, 47, 109, 55, 109, 23, 84, 39, 55, 47, 0, 13, 81, 118, 111, 108, 116, 32, 8, 197, 36, 225, 21, 49, 64, 13, 6, 195, 77, 163, 210, 72, 0, 22, 147, 11, 195, 182, 20, 5, 12, 5, 26, 5, 20, 20, 19, 195, 169, 7, 5, 11, 5, 20, 13, 12, 137, 20, 195, 161, 13, 1, 4, 20, 1, 11, 13, 37, 5, 5, 12, 195, 169, 7, 109, 55, 113, 81, 15, 83, 37, 79, 109, 55, 65, 109, 91, 109, 50, 0, 13, 81, 102, 105, 103, 121, 101, 108, 109, 101, 115, 101, 110, 32, 8, 133, 5, 12, 195, 169, 7, 13, 9, 134, 22, 195, 169, 12, 5, 4, 13, 0, 13, 138, 19, 26, 195, 188, 12, 5, 20, 20, 5, 11, 13, 12, 201, 65, 32, 75, 80, 146, 213, 76, 16, 130, 13, 0, 17, 67, 13, 48, 75, 76, 108, 49, 23, 49, 37, 0, 13, 81, 107, 105, 32, 31, 67, 13, 48, 75, 76, 108, 49, 10, 6, 15, 65, 109, 81, 47, 109, 50, 12, 37, 0, 13, 81, 109, 101, 103, 116, 101, 110, 110, 105, 32, 18, 143, 13, 15, 18, 6, 15, 14, 4, 195, 173, 18, 15, 26, 20, 1, 11, 13, 27, 67, 13, 48, 75, 76, 108, 49, 23, 49, 113, 91, 118, 71, 12, 0, 13, 81, 107, 195, 169, 115, 197, 145, 98, 98, 32, 23, 67, 13, 48, 75, 76, 108, 49, 23, 108, 49, 12, 39, 52, 0, 13, 81, 97, 107, 107, 111, 114, 32, 23, 67, 13, 48, 75, 76, 108, 49, 23, 55, 109, 107, 109, 47, 0, 13, 81, 108, 101, 104, 101, 116, 32, 7, 196, 64, 84, 131, 20, 13, 12, 137, 19, 5, 7, 195, 173, 20, 5, 14, 9, 13, 10, 135, 195, 186, 10, 19, 195, 161, 7, 13, 16, 141, 8, 1, 14, 7, 19, 195, 186, 12, 25, 15, 26, 20, 1, 13, 10, 135, 6, 1, 11, 1, 4, 195, 179, 13, 14, 139, 9, 14, 4, 195, 173, 20, 15, 20, 20, 1, 11, 13, 6, 195, 13, 48, 75, 13, 0, 9, 134, 2, 195, 173, 26, 14, 9, 13, 8, 197, 52, 240, 137, 49, 64, 13, 6, 195, 13, 48, 74, 13, 0, 14, 139, 20, 1, 11, 1, 18, 195, 173, 20, 1, 14, 9, 13, 16, 141, 11, 195, 169, 19, 26, 195, 173, 20, 5, 20, 20, 5, 11, 13, 16, 141, 19, 26, 195, 161, 13, 195, 173, 20, 15, 20, 20, 1, 11, 13, 19, 66, 32, 16, 107, 108, 23, 49, 109, 55, 12, 0, 13, 81, 107, 101, 108, 108, 32, 14, 139, 11, 195, 169, 19, 26, 195, 173, 20, 5, 14, 9, 13, 9, 134, 195, 169, 18, 20, 5, 4, 13, 6, 194, 32, 16, 72, 8, 0, 20, 67, 24, 83, 0, 83, 109, 55, 10, 6, 15, 52, 114, 0, 13, 81, 114, 195, 161, 32, 30, 67, 24, 83, 0, 83, 109, 55, 23, 108, 6, 15, 91, 39, 52, 71, 108, 50, 0, 13, 82, 97, 32, 115, 111, 114, 98, 97, 110, 32, 15, 140, 5, 12, 8, 195, 161, 18, 195, 173, 20, 1, 14, 9, 13, 30, 67, 24, 83, 0, 83, 109, 55, 23, 108, 23, 55, 109, 84, 109, 81, 118, 0, 13, 82, 97, 32, 108, 101, 118, 101, 103, 197, 145, 32, 15, 140, 2, 9, 26, 20, 15, 19, 195, 173, 20, 1, 14, 9, 13, 6, 195, 32, 19, 0, 13, 6, 195, 24, 83, 0, 13, 0, 23, 68, 80, 84, 218, 36, 47, 109, 89, 37, 23, 65, 108, 57, 72, 0, 13, 81, 109, 97, 106, 100, 32, 46, 12, 19, 26, 195, 161, 26, 1, 12, 195, 169, 11, 15, 20, 89, 114, 88, 108, 55, 113, 49, 39, 47, 23, 84, 109, 89, 112, 47, 109, 50, 109, 0, 13, 81, 118, 101, 115, 122, 195, 173, 116, 101, 110, 101, 32, 9, 198, 77, 163, 205, 8, 21, 0, 20, 0, 8, 197, 52, 243, 132, 60, 176, 13, 8, 197, 28, 243, 132, 60, 176, 13, 6, 195, 32, 21, 0, 13, 6, 195, 24, 80, 146, 20, 0, 33, 74, 80, 20, 1, 77, 165, 1, 48, 21, 15, 16, 47, 108, 48, 108, 89, 47, 108, 55, 108, 47, 39, 72, 23, 37, 91, 0, 13, 81, 105, 115, 32, 18, 143, 11, 195, 169, 14, 25, 19, 26, 5, 18, 195, 173, 20, 5, 14, 9, 13, 12, 137, 16, 195, 169, 14, 20, 5, 11, 9, 7, 22, 11, 4, 195, 161, 19, 26, 114, 89, 0, 42, 42, 7, 132, 197, 145, 19, 26, 20, 7, 132, 195, 161, 16, 18, 20, 0, 10, 135, 6, 5, 11, 195, 188, 4, 20, 13, 10, 199, 88, 84, 218, 80, 85, 20, 20, 13, 11, 136, 22, 195, 161, 12, 20, 1, 14, 1, 13, 36, 71, 88, 84, 218, 80, 85, 20, 20, 84, 109, 89, 47, 109, 47, 12, 109, 23, 113, 55, 109, 47, 113, 47, 0, 13, 81, 195, 169, 108, 101, 116, 195, 169, 116, 32, 10, 135, 4, 5, 18, 195, 188, 12, 20, 13, 10, 135, 13, 5, 18, 195, 188, 12, 20, 13, 6, 195, 13, 48, 80, 13, 9, 134, 20, 197, 177, 14, 9, 11, 13, 11, 67, 80, 18, 128, 47, 108, 57, 0, 42, 42, 0, 10, 135, 195, 182, 22, 5, 26, 9, 11, 13, 20, 145, 195, 182, 19, 19, 26, 16, 15, 14, 20, 15, 19, 195, 173, 20, 1, 14, 9, 13, 19, 68, 56, 147, 131, 76, 50, 37, 50, 76, 23, 37, 91, 0, 13, 81, 105, 115, 32, 14, 139, 195, 161, 12, 20, 1, 12, 195, 161, 14, 15, 19, 13, 9, 134, 21, 20, 3, 195, 161, 14, 13, 7, 196, 76, 244, 130, 4, 13, 7, 196, 56, 147, 131, 76, 13, 0, 22, 69, 20, 209, 76, 80, 80, 109, 65, 109, 55, 47, 109, 23, 49, 37, 0, 13, 81, 107, 105, 32, 51, 73, 77, 161, 82, 88, 86, 133, 80, 82, 192, 89, 109, 52, 84, 109, 88, 109, 47, 109, 49, 23, 48, 114, 57, 114, 88, 107, 108, 47, 50, 108, 49, 0, 13, 81, 112, 195, 161, 108, 121, 195, 161, 122, 104, 97, 116, 110, 97, 107, 32, 15, 140, 19, 26, 195, 161, 26, 1, 12, 195, 169, 11, 15, 19, 13, 12, 137, 11, 9, 4, 5, 18, 195, 188, 12, 20, 13, 8, 197, 60, 193, 1, 56, 144, 13, 9, 134, 14, 195, 169, 26, 22, 5, 13, 8, 197, 60, 193, 1, 56, 144, 13, 6, 195, 24, 83, 142, 13, 8, 133, 3, 195, 169, 12, 20, 13, 0, 7, 132, 6, 9, 195, 186, 13, 15, 5, 95, 48, 77, 49, 15, 109, 88, 52, 109, 72, 37, 49, 0, 0, 6, 195, 72, 83, 132, 13, 10, 135, 13, 5, 19, 195, 169, 12, 20, 13, 15, 140, 16, 18, 15, 2, 12, 195, 169, 13, 195, 161, 18, 1, 13, 10, 135, 13, 5, 19, 195, 169, 12, 20, 13, 6, 195, 52, 243, 132, 13, 14, 67, 29, 51, 64, 81, 113, 109, 91, 109, 65, 0, 42, 42, 0, 11, 136, 11, 195, 188, 20, 25, 195, 188, 20, 13, 14, 139, 11, 195, 182, 12, 20, 195, 182, 26, 20, 5, 11, 13, 7, 196, 88, 83, 5, 52, 13, 7, 196, 29, 32, 77, 52, 13, 0, 25, 67, 25, 85, 0, 83, 40, 47, 10, 6, 15, 52, 108, 57, 47, 108, 0, 13, 81, 114, 97, 106, 116, 97, 32, 6, 195, 25, 85, 0, 13, 0, 40, 70, 29, 144, 75, 72, 19, 128, 79, 108, 49, 52, 108, 50, 23, 55, 109, 89, 23, 113, 55, 113, 50, 49, 0, 13, 82, 108, 101, 115, 122, 32, 195, 169, 108, 195, 169, 110, 107, 32, 12, 137, 3, 19, 1, 16, 1, 4, 195, 169, 11, 13, 13, 138, 22, 1, 12, 1, 13, 9, 18, 197, 145, 12, 13, 9, 134, 195, 169, 16, 195, 188, 12, 13, 0, 17, 142, 2, 9, 26, 15, 14, 25, 195, 173, 20, 195, 169, 11, 15, 11, 13, 6, 195, 8, 83, 128, 72, 0, 36, 11, 6, 5, 10, 12, 5, 19, 26, 20, 197, 145, 11, 83, 109, 57, 55, 109, 89, 47, 118, 49, 23, 83, 109, 55, 113, 0, 13, 81, 102, 101, 108, 195, 169, 32, 16, 141, 8, 1, 14, 7, 19, 195, 186, 12, 25, 15, 26, 22, 1, 13, 24, 67, 32, 19, 135, 107, 108, 50, 81, 15, 65, 37, 108, 47, 12, 0, 13, 81, 109, 105, 97, 116, 116, 32, 7, 196, 40, 83, 5, 80, 13, 7, 196, 24, 83, 5, 48, 13, 6, 195, 32, 19, 135, 13, 0, 9, 134, 11, 195, 169, 18, 197, 145, 13, 42, 6, 12, 195, 169, 22, 197, 145, 55, 113, 84, 118, 107, 108, 91, 39, 50, 55, 115, 91, 114, 81, 39, 47, 0, 13, 81, 104, 97, 115, 111, 110, 108, 195, 179, 115, 195, 161, 103, 111, 116, 32, 15, 140, 6, 5, 12, 11, 5, 18, 195, 188, 12, 20, 5, 11, 13, 9, 134, 12, 195, 169, 22, 197, 145, 13, 8, 197, 24, 243, 148, 61, 48, 13, 10, 135, 10, 1, 14, 21, 195, 161, 18, 20, 0, 15, 140, 8, 1, 10, 12, 195, 169, 11, 20, 1, 12, 1, 14, 13, 17, 142, 11, 195, 169, 19, 26, 195, 188, 12, 195, 169, 11, 11, 5, 12, 13, 0, 6, 195, 88, 84, 128, 13, 39, 12, 2, 15, 14, 25, 15, 12, 195, 173, 20, 1, 14, 9, 71, 39, 67, 39, 55, 112, 47, 108, 50, 37, 23, 52, 108, 57, 47, 108, 0, 13, 81, 114, 97, 106, 116, 97, 32, 0, 11, 136, 8, 9, 2, 195, 161, 11, 1, 20, 13, 14, 139, 19, 26, 5, 18, 5, 20, 14, 195, 169, 14, 11, 13, 6, 195, 32, 20, 131, 13, 0, 9, 134, 14, 195, 161, 12, 1, 13, 13, 45, 73, 24, 242, 207, 104, 21, 15, 76, 19, 128, 83, 39, 49, 39, 88, 108, 47, 39, 91, 108, 50, 23, 65, 109, 81, 89, 117, 50, 37, 49, 0, 13, 81, 109, 101, 103, 115, 122, 197, 177, 110, 105, 107, 32, 16, 141, 13, 5, 7, 19, 26, 195, 179, 12, 1, 12, 20, 1, 20, 13, 11, 136, 195, 161, 12, 12, 20, 21, 14, 11, 13, 6, 195, 8, 83, 142, 13, 8, 133, 19, 195, 173, 14, 20, 13, 0, 17, 142, 13, 5, 7, 1, 12, 11, 15, 20, 195, 161, 19, 195, 161, 20, 13, 17, 142, 13, 5, 3, 8, 1, 14, 9, 26, 13, 21, 19, 195, 161, 20, 13, 71, 6, 195, 161, 12, 20, 1, 12, 114, 55, 47, 108, 55, 10, 6, 15, 49, 112, 50, 114, 55, 47, 10, 6, 15, 89, 39, 55, 81, 114, 55, 47, 108, 47, 114, 91, 39, 49, 108, 47, 0, 13, 82, 107, 195, 173, 110, 195, 161, 108, 116, 32, 115, 122, 111, 108, 103, 195, 161, 108, 116, 97, 116, 195, 161, 115, 111, 107, 97, 116, 32, 9, 134, 13, 5, 19, 195, 169, 12, 13, 9, 134, 195, 161, 12, 20, 1, 12, 13, 13, 138, 22, 1, 18, 195, 161, 26, 19, 12, 1, 20, 13, 12, 137, 5, 7, 25, 195, 188, 20, 20, 5, 19, 13, 9, 195, 28, 68, 0, 102, 17, 42, 42, 14, 67, 28, 68, 0, 75, 112, 72, 112, 48, 112, 0, 42, 42, 0, 9, 134, 195, 173, 18, 20, 1, 11, 13, 6, 195, 32, 18, 148, 13, 0, 34, 68, 8, 83, 142, 20, 71, 109, 50, 12, 109, 23, 116, 57, 72, 39, 50, 91, 114, 81, 0, 13, 81, 195, 186, 106, 100, 111, 110, 115, 195, 161, 103, 32, 18, 143, 6, 195, 161, 10, 4, 1, 12, 15, 13, 13, 5, 14, 20, 5, 19, 13, 28, 68, 8, 83, 142, 20, 71, 109, 50, 12, 109, 15, 71, 37, 89, 47, 39, 91, 0, 13, 81, 98, 105, 122, 116, 111, 115, 32, 11, 200, 32, 21, 1, 48, 243, 77, 4, 192, 13, 7, 196, 60, 227, 129, 56, 13, 16, 141, 11, 195, 188, 12, 195, 182, 14, 2, 195, 182, 26, 197, 145, 13, 15, 140, 6, 5, 12, 20, 195, 169, 20, 5, 12, 5, 9, 20, 13, 7, 196, 8, 83, 142, 20, 13, 10, 135, 20, 195, 182, 18, 20, 5, 11, 13, 9, 198, 28, 243, 132, 60, 197, 0, 13, 7, 196, 36, 227, 133, 56, 13, 0, 12, 3, 226, 132, 162, 84, 113, 72, 57, 109, 79, 0, 12, 201, 81, 83, 1, 40, 67, 206, 61, 48, 64, 13, 22, 6, 195, 173, 18, 20, 1, 13, 112, 52, 47, 108, 65, 23, 55, 109, 0, 13, 81, 108, 101, 32, 12, 201, 81, 83, 1, 40, 67, 206, 61, 48, 64, 13, 12, 137, 20, 195, 182, 18, 20, 195, 169, 14, 20, 13, 9, 134, 195, 173, 18, 20, 1, 13, 13, 11, 136, 22, 195, 161, 7, 25, 195, 179, 11, 13, 12, 137, 20, 195, 182, 18, 20, 195, 169, 14, 20, 13, 0, 7, 66, 17, 160, 120, 113, 0, 36, 70, 64, 84, 131, 44, 244, 128, 48, 109, 52, 119, 49, 39, 52, 15, 10, 49, 113, 89, 111, 55, 47, 0, 13, 81, 107, 195, 169, 115, 122, 195, 188, 108, 116, 32, 0, 6, 195, 8, 83, 148, 13, 0, 33, 7, 22, 195, 161, 7, 10, 21, 11, 84, 114, 81, 57, 40, 49, 10, 6, 15, 90, 109, 71, 52, 109, 0, 13, 81, 122, 115, 101, 98, 114, 101, 32, 7, 196, 4, 227, 153, 36, 13, 14, 139, 22, 195, 169, 4, 5, 11, 5, 26, 20, 5, 11, 13, 6, 195, 64, 20, 139, 13, 0, 8, 197, 4, 210, 65, 81, 64, 13, 36, 69, 24, 83, 5, 49, 64, 83, 109, 55, 109, 55, 47, 23, 84, 39, 55, 50, 108, 23, 65, 109, 81, 0, 13, 82, 118, 111, 108, 110, 97, 32, 109, 101, 103, 32, 17, 142, 11, 5, 26, 4, 5, 13, 195, 169, 14, 25, 5, 26, 20, 5, 13, 20, 145, 9, 14, 6, 18, 1, 19, 20, 18, 21, 11, 20, 195, 186, 18, 195, 161, 20, 13, 16, 141, 8, 1, 19, 26, 14, 195, 161, 12, 1, 20, 20, 1, 12, 13, 20, 145, 19, 26, 195, 161, 12, 12, 195, 161, 19, 8, 5, 12, 25, 5, 11, 5, 20, 13, 8, 197, 24, 83, 5, 49, 64, 13, 0, 24, 6, 14, 195, 161, 12, 1, 4, 50, 114, 55, 108, 72, 23, 84, 108, 50, 0, 13, 81, 118, 97, 110, 32, 6, 195, 56, 85, 133, 13, 0, 30, 67, 24, 83, 148, 83, 109, 50, 47, 23, 108, 6, 15, 107, 109, 57, 109, 47, 0, 13, 82, 97, 32, 104, 101, 108, 121, 101, 116, 32, 6, 195, 24, 83, 148, 13, 12, 201, 32, 19, 12, 5, 68, 218, 61, 69, 0, 13, 10, 199, 24, 243, 148, 61, 48, 66, 8, 13, 23, 67, 96, 149, 128, 47, 37, 88, 109, 50, 50, 113, 79, 12, 109, 55, 0, 44, 42, 81, 101, 108, 32, 0, 12, 137, 16, 18, 15, 2, 12, 195, 169, 13, 1, 13, 14, 139, 11, 195, 169, 18, 4, 5, 26, 20, 195, 169, 11, 13, 0, 11, 136, 20, 5, 14, 14, 9, 195, 188, 11, 13, 31, 5, 14, 25, 195, 186, 12, 67, 116, 55, 15, 89, 109, 52, 109, 48, 113, 47, 0, 13, 81, 115, 122, 101, 114, 101, 112, 195, 169, 116, 32, 13, 138, 11, 9, 20, 195, 182, 12, 20, 5, 14, 9, 13, 8, 197, 49, 149, 75, 5, 64, 13, 8, 133, 14, 25, 195, 186, 12, 13, 8, 133, 8, 195, 186, 19, 20, 13, 0, 5, 194, 20, 144, 72, 21, 66, 12, 208, 119, 109, 50, 47, 37, 65, 113, 47, 109, 52, 47, 0, 44, 13, 81, 116, 32, 23, 66, 12, 208, 119, 109, 50, 47, 37, 65, 113, 47, 109, 52, 109, 91, 0, 44, 13, 81, 101, 115, 32, 24, 66, 12, 208, 119, 109, 50, 47, 37, 65, 113, 47, 109, 52, 67, 37, 0, 44, 13, 81, 110, 121, 105, 32, 28, 66, 12, 208, 119, 109, 50, 47, 37, 65, 113, 47, 109, 52, 67, 37, 52, 109, 0, 44, 13, 81, 110, 121, 105, 114, 101, 32, 23, 66, 12, 208, 119, 109, 50, 47, 37, 65, 113, 47, 109, 52, 52, 109, 0, 44, 13, 81, 114, 101, 32, 16, 66, 12, 208, 119, 109, 50, 47, 37, 65, 113, 47, 109, 52, 0, 13, 0, 0, 17, 68, 77, 165, 147, 104, 101, 115, 122, 118, 195, 169, 101, 115, 122, 0, 29, 39, 68, 20, 195, 5, 56, 109, 55, 12, 109, 50, 23, 55, 113, 47, 52, 109, 107, 39, 88, 39, 47, 12, 0, 13, 81, 108, 195, 169, 116, 114, 101, 104, 111, 122, 111, 116, 116, 32, 47, 68, 20, 195, 5, 56, 109, 55, 12, 109, 50, 10, 6, 15, 107, 37, 52, 72, 109, 47, 12, 113, 49, 10, 6, 15, 65, 109, 81, 0, 13, 82, 104, 105, 114, 100, 101, 116, 116, 195, 169, 107, 32, 109, 101, 103, 32, 47, 11, 19, 26, 195, 161, 13, 15, 12, 14, 21, 14, 11, 89, 114, 65, 39, 55, 50, 40, 50, 49, 23, 49, 109, 55, 12, 23, 108, 88, 88, 108, 55, 0, 13, 82, 107, 101, 108, 108, 32, 97, 122, 122, 97, 108, 32, 7, 196, 88, 85, 9, 44, 13, 26, 70, 24, 150, 133, 80, 81, 0, 83, 37, 88, 109, 47, 109, 72, 15, 65, 109, 81, 0, 13, 81, 109, 101, 103, 32, 7, 196, 20, 195, 5, 56, 13, 7, 196, 32, 21, 14, 4, 13, 7, 196, 4, 130, 15, 104, 13, 7, 196, 21, 49, 84, 80, 13, 7, 196, 20, 195, 5, 56, 13, 0, 21, 69, 80, 84, 218, 36, 176, 47, 109, 89, 37, 49, 23, 49, 37, 0, 13, 81, 107, 105, 32, 8, 197, 28, 243, 132, 60, 208, 13, 8, 197, 52, 243, 132, 60, 208, 13, 8, 197, 80, 84, 218, 36, 176, 13, 0, 9, 198, 65, 33, 77, 36, 84, 148, 13, 6, 195, 48, 22, 129, 13, 9, 134, 14, 25, 195, 173, 12, 20, 13, 0, 17, 142, 2, 5, 6, 5, 10, 5, 26, 195, 169, 19, 195, 169, 9, 7, 13, 9, 134, 18, 195, 161, 10, 21, 11, 13, 10, 135, 14, 195, 182, 22, 5, 12, 20, 13, 10, 199, 24, 243, 25, 80, 21, 10, 4, 13, 0, 11, 200, 8, 85, 133, 104, 85, 20, 20, 176, 13, 9, 134, 20, 5, 12, 195, 169, 14, 20, 0, 8, 197, 80, 148, 218, 80, 16, 13, 8, 197, 32, 148, 218, 36, 176, 13, 10, 6, 95, 35, 45, 9, 11, 9, 37, 0, 0, 14, 139, 4, 195, 182, 14, 20, 195, 182, 20, 20, 5, 13, 13, 0, 37, 71, 20, 118, 69, 80, 83, 69, 56, 109, 79, 109, 47, 109, 65, 109, 50, 23, 84, 113, 81, 88, 109, 47, 12, 0, 13, 81, 118, 195, 169, 103, 122, 101, 116, 116, 32, 14, 203, 44, 243, 80, 5, 66, 66, 36, 194, 83, 20, 176, 13, 10, 199, 24, 83, 5, 41, 65, 84, 80, 13, 11, 136, 22, 195, 169, 4, 5, 12, 5, 13, 13, 0, 14, 139, 2, 5, 14, 25, 15, 13, 195, 161, 19, 15, 11, 13, 7, 196, 32, 83, 25, 20, 13, 10, 135, 20, 195, 161, 18, 10, 21, 11, 13, 0, 45, 13, 5, 7, 25, 5, 19, 195, 188, 12, 5, 20, 20, 5, 12, 109, 79, 12, 109, 91, 111, 55, 109, 47, 12, 109, 55, 23, 89, 109, 65, 71, 109, 50, 0, 13, 81, 115, 122, 101, 109, 98, 101, 110, 32, 14, 139, 6, 5, 12, 195, 188, 12, 5, 20, 195, 169, 14, 13, 10, 135, 19, 26, 195, 169, 12, 5, 14, 13, 10, 6, 95, 35, 45, 9, 11, 5, 109, 0, 0, 18, 143, 9, 14, 6, 18, 1, 19, 20, 18, 21, 11, 20, 195, 186, 18, 1, 13, 12, 137, 19, 26, 195, 161, 14, 4, 195, 169, 11, 13, 0, 9, 198, 24, 243, 148, 61, 48, 75, 13, 13, 138, 11, 195, 182, 26, 195, 182, 12, 20, 5, 11, 13, 12, 137, 5, 19, 20, 195, 169, 10, 195, 169, 14, 22, 9, 134, 13, 195, 161, 10, 21, 19, 20, 0, 14, 139, 4, 195, 182, 14, 20, 195, 182, 20, 20, 5, 11, 13, 0, 12, 137, 5, 12, 14, 195, 182, 11, 195, 169, 20, 13, 38, 6, 195, 182, 18, 195, 182, 13, 110, 52, 110, 65, 23, 108, 6, 23, 89, 114, 65, 39, 65, 52, 108, 0, 13, 82, 97, 32, 115, 122, 195, 161, 109, 111, 109, 114, 97, 32, 17, 142, 6, 9, 14, 1, 14, 19, 26, 195, 173, 18, 15, 26, 22, 1, 13, 12, 201, 8, 150, 143, 57, 149, 1, 48, 19, 128, 13, 9, 134, 20, 21, 4, 14, 195, 161, 13, 11, 136, 22, 9, 19, 19, 26, 195, 188, 11, 13, 10, 6, 95, 35, 45, 9, 11, 1, 108, 0, 0, 16, 141, 13, 197, 177, 11, 195, 182, 4, 20, 5, 20, 20, 5, 11, 13, 15, 140, 7, 195, 169, 16, 5, 12, 195, 169, 19, 8, 5, 26, 13, 9, 198, 44, 86, 132, 40, 83, 128, 13, 15, 3, 95, 50, 17, 49, 109, 47, 12, 109, 72, 37, 49, 109, 0, 0, 15, 140, 22, 195, 161, 12, 1, 19, 26, 20, 195, 169, 11, 1, 13, 14, 139, 11, 195, 188, 12, 4, 195, 182, 20, 20, 5, 20, 13, 6, 195, 60, 64, 64, 13, 14, 139, 18, 5, 14, 4, 5, 12, 5, 20, 195, 169, 20, 13, 10, 199, 44, 20, 3, 76, 243, 1, 80, 13, 6, 195, 60, 64, 64, 13, 0, 0, 22, 3, 226, 128, 166, 10, 48, 2, 39, 50, 47, 48, 2, 39, 50, 47, 48, 2, 39, 50, 47, 0, 9, 134, 22, 5, 14, 14, 195, 169, 13, 16, 141, 1, 12, 1, 16, 195, 182, 20, 12, 5, 20, 195, 169, 20, 13, 6, 195, 20, 165, 0, 13, 8, 133, 2, 195, 186, 10, 20, 13, 0, 9, 198, 84, 69, 129, 72, 244, 192, 13, 0, 14, 139, 5, 13, 12, 195, 169, 11, 5, 26, 20, 5, 20, 13, 10, 199, 28, 243, 132, 60, 194, 149, 44, 13, 0, 31, 11, 6, 18, 9, 19, 19, 195, 173, 20, 195, 169, 19, 83, 52, 37, 91, 12, 112, 47, 113, 91, 23, 37, 91, 0, 13, 81, 105, 115, 32, 11, 5, 95, 35, 45, 5, 9, 109, 37, 0, 21, 13, 3, 95, 49, 15, 109, 79, 12, 109, 72, 37, 49, 0, 0, 0, 27, 67, 57, 97, 1, 101, 110, 118, 195, 169, 100, 195, 169, 195, 161, 118, 97, 108, 0, 44, 29, 42, 81, 118, 97, 108, 32, 29, 67, 57, 97, 1, 101, 110, 118, 195, 169, 100, 195, 169, 195, 161, 116, 195, 179, 108, 0, 44, 29, 42, 81, 116, 195, 179, 108, 32, 23, 67, 57, 97, 1, 101, 110, 118, 195, 169, 100, 195, 169, 195, 161, 116, 0, 44, 29, 42, 81, 116, 32, 23, 67, 57, 97, 1, 101, 110, 118, 195, 169, 100, 195, 169, 195, 161, 115, 0, 44, 29, 42, 81, 115, 32, 27, 67, 57, 97, 1, 101, 110, 118, 195, 169, 100, 195, 169, 195, 161, 110, 97, 107, 0, 44, 29, 42, 81, 110, 97, 107, 32, 27, 67, 57, 97, 1, 101, 110, 118, 195, 169, 100, 195, 169, 195, 161, 104, 111, 122, 0, 44, 29, 42, 81, 104, 111, 122, 32, 29, 67, 57, 97, 1, 101, 110, 118, 195, 169, 100, 195, 169, 195, 161, 98, 195, 179, 108, 0, 44, 29, 42, 81, 98, 195, 179, 108, 32, 27, 67, 57, 97, 1, 101, 110, 118, 195, 169, 100, 195, 169, 195, 161, 98, 97, 110, 0, 44, 29, 42, 81, 98, 97, 110, 32, 25, 67, 57, 97, 1, 101, 110, 118, 195, 169, 100, 195, 169, 195, 161, 98, 97, 0, 44, 29, 42, 81, 98, 97, 32, 27, 66, 21, 160, 109, 88, 10, 6, 15, 84, 108, 55, 108, 65, 37, 47, 0, 13, 81, 118, 97, 108, 97, 109, 105, 116, 32, 10, 135, 197, 145, 18, 14, 1, 7, 25, 13, 15, 66, 21, 160, 109, 88, 23, 108, 88, 0, 13, 81, 97, 122, 32, 35, 66, 21, 160, 109, 88, 10, 6, 15, 108, 6, 15, 48, 52, 39, 71, 55, 113, 65, 108, 0, 13, 82, 97, 32, 112, 114, 111, 98, 108, 195, 169, 109, 97, 32, 5, 194, 21, 160, 13, 15, 67, 57, 97, 1, 109, 50, 84, 113, 72, 113, 108, 0, 42, 42, 15, 8, 95, 35, 45, 195, 169, 8, 5, 26, 113, 107, 109, 88, 0, 16, 3, 95, 51, 17, 107, 108, 52, 10, 65, 108, 72, 37, 49, 108, 0, 0, 10, 3, 226, 130, 172, 109, 40, 52, 39, 0, 36, 71, 72, 83, 132, 77, 161, 82, 80, 52, 109, 50, 119, 109, 52, 47, 10, 6, 15, 49, 113, 89, 112, 47, 0, 13, 81, 107, 195, 169, 115, 122, 195, 173, 116, 32, 41, 12, 22, 5, 26, 5, 20, 197, 145, 19, 195, 169, 7, 9, 84, 109, 88, 109, 47, 118, 91, 113, 81, 37, 23, 47, 108, 81, 57, 108, 37, 0, 13, 81, 116, 97, 103, 106, 97, 105, 32, 17, 142, 19, 26, 195, 161, 13, 195, 173, 20, 8, 1, 20, 21, 14, 11, 13, 9, 198, 24, 150, 133, 80, 225, 75, 13, 6, 195, 60, 179, 212, 13, 10, 199, 72, 83, 132, 77, 161, 82, 80, 13, 0, 10, 135, 12, 195, 161, 14, 3, 15, 11, 13, 7, 196, 20, 227, 153, 36, 13, 6, 131, 10, 195, 179, 13, 0, 19, 67, 21, 165, 0, 109, 89, 47, 10, 6, 15, 108, 88, 0, 13, 81, 97, 122, 32, 21, 67, 21, 165, 0, 109, 89, 47, 23, 49, 109, 55, 12, 0, 13, 81, 107, 101, 108, 108, 32, 8, 197, 24, 244, 137, 57, 64, 13, 12, 137, 2, 1, 10, 15, 11, 18, 195, 179, 12, 13, 8, 197, 37, 51, 69, 73, 64, 13, 6, 195, 21, 165, 0, 13, 0, 13, 138, 22, 9, 12, 195, 161, 7, 18, 195, 179, 12, 13, 9, 198, 77, 161, 77, 24, 241, 192, 13, 6, 195, 64, 144, 201, 13, 12, 137, 13, 197, 177, 11, 195, 182, 4, 9, 11, 13, 9, 3, 95, 49, 5, 109, 79, 12, 0, 0, 14, 139, 22, 195, 169, 4, 5, 12, 5, 13, 13, 5, 12, 13, 12, 201, 61, 4, 133, 56, 68, 218, 21, 37, 0, 13, 12, 137, 13, 21, 14, 11, 195, 161, 8, 15, 26, 13, 13, 138, 5, 13, 12, 195, 169, 11, 19, 26, 9, 11, 13, 11, 136, 19, 26, 5, 13, 195, 169, 12, 25, 13, 6, 195, 80, 17, 192, 13, 0, 10, 135, 195, 188, 12, 195, 188, 14, 11, 13, 14, 3, 95, 50, 15, 49, 109, 47, 12, 109, 72, 37, 49, 0, 0, 8, 197, 56, 83, 90, 21, 64, 13, 9, 134, 18, 195, 161, 26, 14, 9, 13, 13, 138, 22, 195, 169, 12, 5, 13, 195, 169, 14, 25, 13, 13, 138, 8, 1, 19, 26, 14, 195, 161, 12, 14, 9, 13, 0, 13, 138, 8, 15, 26, 1, 4, 195, 169, 11, 15, 20, 13, 9, 3, 95, 50, 1, 49, 113, 47, 0, 0, 20, 67, 80, 20, 148, 47, 108, 52, 47, 23, 39, 47, 12, 0, 13, 81, 111, 116, 116, 32, 15, 140, 12, 5, 7, 5, 14, 5, 18, 195, 161, 12, 14, 9, 13, 9, 134, 10, 195, 161, 18, 195, 179, 13, 14, 139, 10, 195, 161, 18, 1, 4, 195, 169, 11, 15, 20, 13, 6, 195, 80, 20, 148, 13, 6, 195, 56, 82, 192, 13, 0, 22, 68, 40, 83, 26, 36, 57, 109, 55, 88, 37, 10, 6, 15, 108, 88, 0, 13, 81, 97, 122, 32, 7, 196, 88, 85, 14, 36, 13, 7, 196, 40, 83, 26, 36, 13, 10, 135, 22, 5, 12, 195, 188, 14, 11, 13, 6, 195, 88, 84, 147, 13, 0, 8, 197, 81, 81, 20, 60, 176, 76, 8, 197, 88, 19, 142, 4, 176, 13, 0, 9, 198, 85, 64, 90, 56, 18, 192, 13, 9, 198, 8, 19, 139, 56, 18, 192, 13, 12, 201, 88, 148, 218, 60, 230, 85, 48, 224, 75, 13, 31, 70, 72, 144, 68, 56, 18, 192, 51, 37, 108, 72, 50, 108, 49, 23, 84, 37, 89, 12, 108, 0, 13, 81, 118, 105, 115, 115, 122, 97, 32, 9, 198, 5, 163, 203, 56, 18, 192, 13, 9, 198, 32, 19, 135, 104, 146, 192, 13, 9, 198, 52, 243, 132, 41, 82, 192, 13, 9, 198, 32, 19, 135, 104, 146, 192, 13, 9, 134, 6, 195, 161, 10, 12, 20, 13, 10, 3, 95, 50, 5, 49, 109, 47, 12, 0, 0, 26, 5, 8, 195, 186, 19, 26, 107, 116, 89, 23, 113, 84, 71, 109, 50, 0, 13, 81, 195, 169, 118, 98, 101, 110, 32, 15, 140, 11, 195, 182, 18, 195, 188, 12, 13, 195, 169, 14, 25, 13, 20, 145, 13, 5, 7, 6, 9, 7, 25, 5, 12, 195, 169, 19, 195, 169, 8, 5, 26, 13, 15, 140, 11, 9, 8, 1, 19, 26, 14, 195, 161, 12, 14, 9, 13, 14, 139, 2, 15, 18, 195, 173, 20, 195, 169, 11, 15, 20, 13, 11, 136, 19, 26, 195, 179, 12, 20, 1, 13, 13, 8, 133, 8, 195, 186, 19, 26, 13, 6, 195, 88, 84, 148, 13, 0, 42, 8, 2, 5, 3, 19, 195, 188, 12, 20, 71, 109, 76, 111, 55, 47, 23, 113, 52, 47, 113, 49, 113, 50, 109, 49, 0, 13, 81, 195, 169, 114, 116, 195, 169, 107, 195, 169, 110, 101, 107, 32, 12, 137, 10, 5, 12, 19, 26, 195, 179, 18, 1, 13, 11, 200, 24, 83, 9, 76, 209, 82, 56, 144, 13, 15, 3, 95, 51, 15, 107, 108, 52, 10, 65, 108, 72, 37, 49, 0, 11, 4, 95, 15, 18, 4, 109, 72, 37, 49, 0, 0, 8, 197, 81, 81, 14, 4, 176, 76, 13, 138, 11, 195, 182, 26, 16, 15, 14, 20, 10, 1, 13, 8, 197, 81, 81, 14, 4, 176, 13, 11, 136, 18, 5, 13, 195, 169, 12, 9, 11, 13, 0, 13, 66, 33, 80, 104, 117, 110, 0, 44, 29, 81, 110, 32, 29, 66, 37, 48, 37, 91, 23, 114, 55, 112, 80, 12, 114, 49, 0, 13, 81, 195, 161, 108, 108, 195, 173, 116, 106, 195, 161, 107, 32, 29, 66, 37, 48, 37, 91, 23, 84, 113, 81, 109, 88, 47, 113, 49, 0, 13, 81, 118, 195, 169, 103, 101, 122, 116, 195, 169, 107, 32, 40, 66, 37, 48, 37, 91, 23, 108, 55, 114, 47, 114, 65, 108, 89, 47, 39, 47, 12, 108, 0, 13, 81, 97, 108, 195, 161, 116, 195, 161, 109, 97, 115, 122, 116, 111, 116, 116, 97, 32, 28, 66, 37, 48, 37, 91, 23, 84, 37, 47, 108, 80, 12, 114, 49, 0, 13, 81, 118, 105, 116, 97, 116, 106, 195, 161, 107, 32, 27, 66, 37, 48, 37, 91, 23, 108, 55, 114, 112, 52, 47, 108, 0, 13, 81, 97, 108, 195, 161, 195, 173, 114, 116, 97, 32, 30, 66, 37, 48, 37, 91, 23, 65, 109, 81, 109, 65, 55, 112, 47, 37, 0, 13, 81, 109, 101, 103, 101, 109, 108, 195, 173, 116, 105, 32, 22, 66, 37, 48, 37, 91, 23, 65, 113, 52, 37, 49, 0, 13, 81, 109, 195, 169, 114, 105, 107, 32, 27, 66, 37, 48, 37, 91, 23, 47, 110, 34, 47, 113, 50, 47, 0, 13, 81, 116, 195, 182, 114, 116, 195, 169, 110, 116, 32, 25, 66, 37, 48, 37, 91, 23, 71, 109, 89, 113, 55, 47, 0, 13, 81, 98, 101, 115, 122, 195, 169, 108, 116, 32, 54, 66, 37, 48, 37, 91, 10, 6, 15, 55, 109, 107, 109, 47, 10, 6, 15, 76, 108, 47, 55, 108, 49, 39, 89, 47, 108, 47, 50, 37, 0, 13, 82, 108, 101, 104, 101, 116, 32, 99, 115, 97, 116, 108, 97, 107, 111, 122, 116, 97, 116, 110, 105, 32, 45, 66, 37, 48, 37, 91, 10, 6, 15, 55, 109, 107, 109, 47, 10, 6, 15, 71, 118, 84, 112, 47, 109, 50, 37, 0, 13, 82, 108, 101, 104, 101, 116, 32, 98, 197, 145, 118, 195, 173, 116, 101, 110, 105, 32, 45, 66, 37, 48, 37, 91, 10, 6, 15, 55, 109, 107, 109, 47, 10, 6, 15, 107, 108, 89, 50, 114, 55, 50, 37, 0, 13, 82, 108, 101, 104, 101, 116, 32, 104, 97, 115, 122, 110, 195, 161, 108, 110, 105, 32, 33, 66, 37, 48, 37, 91, 10, 6, 15, 47, 108, 55, 114, 55, 107, 108, 47, 115, 0, 13, 81, 116, 97, 108, 195, 161, 108, 104, 97, 116, 195, 179, 32, 31, 66, 37, 48, 37, 91, 10, 6, 15, 57, 109, 79, 109, 89, 47, 111, 49, 0, 13, 81, 106, 101, 103, 121, 101, 122, 116, 195, 188, 107, 32, 25, 66, 37, 48, 37, 91, 10, 6, 15, 84, 108, 50, 12, 108, 49, 0, 13, 81, 118, 97, 110, 110, 97, 107, 32, 36, 66, 37, 48, 37, 91, 10, 6, 15, 65, 109, 81, 65, 40, 47, 108, 80, 12, 114, 49, 0, 13, 81, 109, 101, 103, 109, 117, 116, 97, 116, 106, 195, 161, 107, 32, 40, 66, 37, 48, 37, 91, 10, 6, 15, 49, 37, 109, 81, 113, 89, 112, 47, 109, 47, 12, 109, 0, 13, 81, 107, 105, 101, 103, 195, 169, 115, 122, 195, 173, 116, 101, 116, 116, 101, 32, 37, 66, 37, 48, 37, 91, 10, 6, 15, 52, 109, 50, 72, 109, 55, 49, 109, 89, 47, 109, 49, 0, 13, 81, 114, 101, 110, 100, 101, 108, 107, 101, 122, 116, 101, 107, 32, 34, 66, 37, 48, 37, 91, 6, 15, 49, 110, 89, 110, 50, 107, 109, 47, 118, 0, 13, 81, 107, 195, 182, 115, 122, 195, 182, 110, 104, 101, 116, 197, 145, 32, 33, 66, 37, 48, 37, 91, 10, 6, 15, 112, 47, 113, 55, 107, 109, 47, 37, 49, 0, 13, 81, 195, 173, 116, 195, 169, 108, 104, 101, 116, 105, 107, 32, 38, 66, 37, 48, 37, 91, 10, 6, 15, 49, 39, 50, 119, 109, 50, 47, 52, 114, 55, 50, 37, 0, 13, 81, 107, 111, 110, 99, 101, 110, 116, 114, 195, 161, 108, 110, 105, 32, 22, 66, 37, 48, 37, 91, 10, 6, 15, 114, 52, 40, 55, 0, 13, 81, 195, 161, 114, 117, 108, 32, 23, 66, 37, 48, 37, 91, 10, 6, 15, 47, 37, 55, 39, 91, 0, 13, 81, 116, 105, 108, 111, 115, 32, 29, 66, 37, 48, 37, 91, 10, 6, 15, 111, 79, 109, 55, 47, 109, 49, 0, 13, 81, 195, 188, 103, 121, 101, 108, 116, 101, 107, 32, 22, 66, 37, 48, 37, 91, 10, 6, 55, 109, 50, 12, 109, 0, 13, 81, 108, 101, 110, 110, 101, 32, 35, 66, 37, 48, 37, 91, 10, 6, 15, 84, 114, 55, 108, 89, 47, 39, 47, 12, 108, 0, 13, 81, 118, 195, 161, 108, 97, 115, 122, 116, 111, 116, 116, 97, 32, 24, 66, 37, 48, 37, 91, 10, 6, 15, 55, 114, 88, 108, 72, 0, 13, 81, 108, 195, 161, 122, 97, 100, 32, 18, 66, 37, 48, 37, 91, 10, 6, 15, 113, 52, 0, 13, 81, 195, 169, 114, 32, 25, 66, 37, 48, 37, 91, 10, 6, 15, 107, 108, 47, 39, 47, 12, 0, 13, 81, 104, 97, 116, 111, 116, 116, 32, 32, 66, 37, 48, 37, 91, 10, 6, 15, 89, 111, 49, 91, 113, 81, 109, 91, 0, 13, 81, 115, 122, 195, 188, 107, 115, 195, 169, 103, 101, 115, 32, 29, 66, 37, 48, 37, 91, 23, 89, 109, 52, 109, 47, 50, 113, 49, 0, 13, 81, 115, 122, 101, 114, 101, 116, 110, 195, 169, 107, 32, 39, 66, 37, 48, 37, 91, 23, 109, 79, 12, 111, 47, 65, 117, 49, 110, 72, 37, 49, 0, 13, 81, 101, 103, 121, 195, 188, 116, 116, 109, 197, 177, 107, 195, 182, 100, 105, 107, 32, 28, 66, 37, 48, 37, 91, 23, 57, 109, 55, 109, 88, 47, 113, 49, 0, 13, 81, 106, 101, 108, 101, 122, 116, 195, 169, 107, 32, 34, 66, 37, 48, 37, 91, 23, 89, 111, 49, 110, 91, 109, 71, 12, 109, 49, 0, 13, 81, 115, 122, 197, 177, 107, 195, 182, 115, 101, 98, 98, 101, 107, 32, 35, 66, 37, 48, 37, 91, 23, 49, 37, 57, 109, 55, 110, 55, 107, 109, 47, 118, 0, 13, 81, 107, 105, 106, 101, 108, 195, 182, 108, 104, 101, 116, 197, 145, 32, 34, 66, 37, 48, 37, 91, 23, 107, 108, 89, 50, 114, 55, 107, 108, 47, 115, 0, 13, 81, 104, 97, 115, 122, 110, 195, 161, 108, 104, 97, 116, 195, 179, 32, 36, 66, 37, 48, 37, 91, 23, 107, 108, 89, 50, 114, 55, 107, 108, 47, 115, 49, 0, 13, 81, 104, 97, 115, 122, 110, 195, 161, 108, 104, 97, 116, 195, 179, 107, 32, 35, 66, 37, 48, 37, 91, 23, 65, 109, 81, 89, 109, 52, 109, 89, 47, 113, 49, 0, 13, 81, 109, 101, 103, 115, 122, 101, 114, 101, 122, 116, 195, 169, 107, 32, 26, 66, 37, 48, 37, 91, 23, 55, 109, 55, 110, 84, 37, 49, 0, 13, 81, 108, 101, 108, 195, 182, 118, 105, 107, 32, 30, 66, 37, 48, 37, 91, 23, 47, 114, 65, 39, 81, 108, 80, 12, 108, 0, 13, 81, 116, 195, 161, 109, 111, 103, 97, 116, 106, 97, 32, 39, 66, 37, 48, 37, 91, 23, 109, 52, 109, 72, 65, 113, 67, 109, 88, 107, 109, 47, 37, 0, 13, 81, 101, 114, 101, 100, 109, 195, 169, 110, 121, 101, 122, 104, 101, 116, 105, 32, 23, 66, 37, 48, 37, 91, 23, 84, 39, 55, 47, 108, 49, 0, 13, 81, 118, 111, 108, 116, 97, 107, 32, 26, 66, 37, 48, 37, 91, 23, 49, 37, 72, 109, 52, 111, 55, 0, 13, 81, 107, 105, 100, 101, 114, 195, 188, 108, 32, 31, 66, 37, 48, 37, 91, 10, 6, 15, 83, 109, 55, 84, 109, 47, 107, 109, 47, 0, 13, 81, 102, 101, 108, 118, 101, 116, 104, 101, 116, 32, 42, 66, 37, 48, 37, 91, 23, 52, 109, 65, 113, 67, 49, 109, 72, 107, 109, 47, 111, 50, 49, 0, 13, 81, 114, 101, 109, 195, 169, 110, 121, 107, 101, 100, 104, 101, 116, 195, 188, 110, 107, 32, 18, 66, 37, 48, 37, 91, 23, 55, 109, 89, 0, 13, 81, 108, 101, 115, 122, 32, 30, 66, 37, 48, 37, 91, 23, 83, 109, 55, 65, 109, 52, 111, 55, 47, 0, 13, 81, 102, 101, 108, 109, 101, 114, 195, 188, 108, 116, 32, 38, 66, 37, 48, 37, 91, 23, 52, 114, 84, 37, 55, 114, 81, 112, 47, 39, 47, 12, 0, 13, 81, 114, 195, 161, 118, 105, 108, 195, 161, 103, 195, 173, 116, 111, 116, 116, 32, 67, 66, 37, 48, 37, 91, 23, 83, 37, 88, 109, 47, 107, 109, 47, 50, 109, 49, 23, 108, 6, 15, 79, 115, 79, 89, 109, 52, 109, 49, 113, 52, 47, 0, 13, 83, 102, 105, 122, 101, 116, 104, 101, 116, 110, 101, 107, 32, 97, 32, 103, 121, 195, 179, 103, 121, 115, 122, 101, 114, 101, 107, 195, 169, 114, 116, 32, 29, 66, 37, 48, 37, 91, 23, 47, 108, 52, 47, 108, 55, 65, 108, 88, 0, 13, 81, 116, 97, 114, 116, 97, 108, 109, 97, 122, 32, 24, 66, 37, 48, 37, 91, 23, 83, 39, 57, 50, 108, 49, 0, 13, 81, 102, 111, 108, 121, 110, 97, 107, 32, 21, 66, 37, 48, 37, 91, 23, 110, 52, 110, 65, 0, 13, 81, 195, 182, 114, 195, 182, 109, 32, 23, 66, 37, 48, 37, 91, 23, 71, 40, 49, 12, 108, 50, 0, 13, 81, 98, 117, 107, 107, 97, 110, 32, 29, 66, 37, 48, 37, 91, 23, 107, 37, 114, 67, 39, 55, 39, 65, 0, 13, 81, 104, 105, 195, 161, 110, 121, 111, 108, 111, 109, 32, 19, 66, 37, 48, 37, 91, 23, 55, 109, 47, 12, 0, 13, 81, 108, 101, 116, 116, 32, 19, 66, 37, 48, 37, 91, 23, 84, 39, 55, 47, 0, 13, 81, 118, 111, 108, 116, 32, 36, 66, 37, 48, 37, 91, 23, 65, 113, 52, 91, 113, 49, 55, 118, 72, 37, 49, 0, 13, 81, 109, 195, 169, 114, 115, 195, 169, 107, 108, 197, 145, 100, 105, 107, 32, 33, 66, 37, 48, 37, 91, 23, 49, 112, 91, 113, 52, 107, 109, 47, 37, 49, 0, 13, 81, 107, 195, 173, 115, 195, 169, 114, 104, 101, 116, 105, 107, 32, 26, 66, 37, 48, 37, 91, 23, 49, 37, 84, 114, 52, 50, 37, 0, 13, 81, 107, 105, 118, 195, 161, 114, 110, 105, 32, 28, 66, 37, 48, 37, 91, 23, 83, 109, 57, 55, 118, 72, 37, 49, 0, 13, 81, 102, 101, 106, 108, 197, 145, 100, 105, 107, 32, 22, 66, 37, 48, 37, 91, 23, 84, 114, 55, 37, 49, 0, 13, 81, 118, 195, 161, 108, 105, 107, 32, 20, 66, 37, 48, 37, 91, 23, 83, 111, 81, 12, 0, 13, 81, 102, 195, 188, 103, 103, 32, 27, 66, 37, 48, 37, 91, 23, 84, 114, 52, 107, 108, 47, 115, 0, 13, 81, 118, 195, 161, 114, 104, 97, 116, 195, 179, 32, 25, 66, 37, 48, 37, 91, 23, 71, 109, 37, 49, 47, 108, 47, 0, 13, 81, 98, 101, 105, 107, 116, 97, 116, 32, 26, 66, 37, 48, 37, 91, 23, 65, 109, 50, 109, 49, 111, 55, 0, 13, 81, 109, 101, 110, 101, 107, 195, 188, 108, 32, 20, 66, 37, 48, 37, 91, 23, 52, 115, 55, 108, 0, 13, 81, 114, 195, 179, 108, 97, 32, 38, 66, 37, 48, 37, 91, 23, 49, 37, 109, 81, 113, 89, 112, 47, 109, 47, 12, 109, 0, 13, 81, 107, 105, 101, 103, 195, 169, 115, 122, 195, 173, 116, 101, 116, 116, 101, 32, 16, 66, 37, 48, 37, 91, 23, 108, 88, 6, 0, 13, 81, 97, 122, 32, 33, 66, 37, 48, 37, 91, 23, 65, 109, 81, 65, 108, 52, 108, 79, 12, 39, 50, 0, 13, 81, 109, 101, 103, 109, 97, 114, 97, 100, 106, 111, 110, 32, 36, 66, 37, 48, 37, 91, 23, 83, 109, 57, 55, 109, 89, 47, 109, 47, 12, 109, 49, 0, 13, 81, 102, 101, 106, 108, 101, 115, 122, 116, 101, 116, 116, 101, 107, 32, 31, 66, 37, 48, 37, 91, 15, 107, 6, 108, 57, 55, 108, 50, 72, 115, 49, 0, 13, 81, 104, 97, 106, 108, 97, 110, 100, 195, 179, 107, 32, 10, 135, 195, 186, 19, 26, 20, 1, 13, 13, 24, 66, 37, 48, 37, 91, 23, 40, 79, 108, 50, 108, 88, 0, 13, 81, 117, 103, 121, 97, 110, 97, 122, 32, 40, 66, 37, 48, 37, 91, 23, 49, 108, 47, 108, 89, 47, 52, 115, 83, 114, 107, 39, 88, 0, 13, 81, 107, 97, 116, 97, 115, 122, 116, 114, 195, 179, 102, 195, 161, 104, 111, 122, 32, 16, 141, 6, 5, 12, 8, 197, 145, 20, 1, 11, 1, 18, 195, 179, 13, 33, 66, 37, 48, 37, 91, 23, 83, 39, 81, 55, 108, 55, 49, 39, 88, 39, 65, 0, 13, 81, 102, 111, 103, 108, 97, 108, 107, 111, 122, 111, 109, 32, 36, 66, 37, 48, 37, 91, 23, 109, 55, 118, 83, 39, 52, 72, 40, 55, 107, 108, 47, 0, 13, 81, 101, 108, 197, 145, 102, 111, 114, 100, 117, 108, 104, 97, 116, 32, 37, 66, 37, 48, 37, 91, 23, 49, 113, 48, 88, 118, 72, 107, 109, 47, 50, 109, 49, 0, 13, 81, 107, 195, 169, 112, 122, 197, 145, 100, 104, 101, 116, 110, 101, 107, 32, 21, 66, 37, 48, 37, 91, 23, 55, 109, 107, 109, 47, 0, 13, 81, 108, 101, 104, 101, 116, 32, 25, 66, 37, 48, 37, 91, 23, 49, 109, 88, 109, 55, 47, 109, 0, 13, 81, 107, 101, 122, 101, 108, 116, 101, 32, 29, 66, 37, 48, 37, 91, 23, 89, 111, 55, 109, 47, 109, 47, 12, 0, 13, 81, 115, 122, 195, 188, 108, 101, 116, 101, 116, 116, 32, 80, 66, 37, 48, 37, 91, 23, 49, 37, 47, 110, 55, 47, 107, 109, 47, 12, 113, 49, 23, 84, 39, 55, 50, 108, 23, 108, 23, 49, 113, 52, 72, 118, 112, 84, 109, 49, 109, 47, 0, 13, 84, 107, 105, 116, 195, 182, 108, 116, 104, 101, 116, 116, 195, 169, 107, 32, 118, 111, 108, 110, 97, 32, 97, 32, 107, 195, 169, 114, 100, 197, 145, 195, 173, 118, 101, 107, 101, 116, 32, 36, 66, 37, 48, 37, 91, 23, 108, 23, 49, 113, 52, 72, 118, 112, 84, 109, 47, 0, 13, 82, 97, 32, 107, 195, 169, 114, 100, 197, 145, 195, 173, 118, 101, 116, 32, 26, 66, 37, 48, 37, 91, 23, 83, 109, 50, 12, 114, 55, 12, 0, 13, 81, 102, 101, 110, 110, 195, 161, 108, 108, 32, 36, 66, 37, 48, 37, 91, 23, 109, 55, 118, 83, 39, 52, 72, 40, 55, 50, 108, 49, 0, 13, 81, 101, 108, 197, 145, 102, 111, 114, 100, 117, 108, 110, 97, 107, 32, 29, 66, 37, 48, 37, 91, 23, 83, 109, 55, 52, 108, 49, 47, 108, 65, 0, 13, 81, 102, 101, 108, 114, 97, 107, 116, 97, 109, 32, 35, 66, 37, 48, 37, 91, 15, 83, 109, 55, 109, 57, 47, 49, 109, 89, 47, 109, 65, 0, 13, 81, 102, 101, 108, 101, 106, 116, 107, 101, 122, 116, 101, 109, 32, 22, 66, 37, 48, 37, 91, 15, 52, 109, 76, 109, 81, 0, 13, 81, 114, 101, 99, 115, 101, 103, 32, 14, 139, 1, 11, 20, 9, 22, 195, 161, 12, 20, 1, 13, 13, 10, 135, 11, 5, 26, 195, 169, 2, 5, 13, 28, 66, 37, 48, 37, 91, 15, 84, 114, 55, 47, 39, 88, 37, 49, 0, 13, 81, 118, 195, 161, 108, 116, 111, 122, 105, 107, 32, 40, 66, 37, 48, 37, 91, 15, 49, 109, 55, 12, 15, 83, 37, 88, 109, 47, 50, 37, 111, 49, 0, 13, 82, 107, 101, 108, 108, 32, 102, 105, 122, 101, 116, 110, 105, 195, 188, 107, 32, 29, 66, 37, 48, 37, 91, 15, 109, 55, 37, 91, 65, 109, 52, 47, 109, 0, 13, 81, 101, 108, 105, 115, 109, 101, 114, 116, 101, 32, 23, 66, 37, 48, 37, 91, 10, 6, 15, 108, 49, 108, 47, 12, 0, 13, 81, 97, 107, 97, 100, 116, 32, 9, 198, 52, 20, 129, 16, 226, 64, 13, 9, 198, 44, 146, 149, 80, 226, 64, 13, 9, 198, 24, 150, 133, 80, 226, 64, 13, 9, 198, 52, 20, 129, 16, 226, 64, 13, 9, 198, 52, 243, 132, 80, 18, 192, 13, 9, 198, 36, 225, 21, 48, 226, 64, 13, 9, 134, 1, 2, 2, 195, 179, 12, 13, 5, 194, 37, 48, 13, 6, 195, 56, 82, 201, 13, 5, 194, 37, 48, 72, 0, 10, 199, 57, 147, 205, 61, 37, 76, 80, 13, 13, 138, 11, 195, 169, 16, 5, 26, 14, 195, 169, 11, 13, 49, 8, 3, 195, 169, 12, 15, 11, 18, 1, 119, 113, 55, 39, 49, 52, 108, 23, 107, 108, 89, 50, 114, 55, 107, 108, 47, 50, 114, 49, 0, 13, 81, 104, 97, 115, 122, 110, 195, 161, 108, 104, 97, 116, 110, 195, 161, 107, 32, 13, 138, 8, 1, 19, 26, 14, 195, 161, 12, 15, 11, 13, 0, 16, 141, 11, 9, 16, 18, 195, 179, 2, 195, 161, 12, 20, 1, 13, 13, 7, 196, 52, 20, 129, 16, 13, 9, 134, 20, 5, 18, 195, 169, 14, 13, 0, 13, 138, 20, 195, 182, 18, 20, 195, 169, 14, 14, 5, 13, 11, 136, 19, 26, 195, 179, 12, 20, 1, 11, 13, 13, 138, 8, 1, 19, 26, 14, 195, 161, 12, 15, 13, 13, 11, 135, 5, 12, 5, 10, 195, 169, 14, 20, 13, 0, 17, 142, 8, 1, 12, 12, 7, 1, 20, 195, 179, 11, 20, 195, 179, 12, 13, 9, 198, 21, 49, 84, 8, 83, 128, 13, 9, 198, 80, 83, 5, 24, 243, 128, 13, 14, 139, 6, 9, 7, 25, 5, 12, 13, 195, 169, 2, 5, 13, 10, 3, 95, 51, 5, 107, 114, 52, 65, 0, 0, 13, 138, 8, 197, 145, 2, 195, 182, 18, 195, 182, 7, 13, 28, 153, 1, 11, 1, 4, 195, 161, 12, 25, 13, 5, 14, 20, 5, 19, 195, 173, 20, 195, 169, 19, 195, 169, 8, 5, 26, 13, 11, 136, 5, 7, 25, 19, 195, 169, 7, 5, 13, 10, 199, 52, 20, 129, 17, 69, 78, 44, 13, 10, 199, 24, 244, 137, 57, 69, 78, 44, 13, 11, 136, 20, 195, 161, 18, 15, 12, 14, 9, 13, 0, 16, 141, 11, 9, 11, 195, 169, 18, 4, 5, 26, 14, 195, 169, 13, 13, 11, 136, 7, 25, 5, 14, 7, 195, 188, 12, 13, 8, 133, 20, 5, 22, 197, 145, 13, 0, 15, 140, 18, 5, 11, 12, 195, 161, 13, 3, 19, 195, 173, 11, 13, 8, 197, 80, 21, 129, 49, 144, 13, 0, 39, 6, 9, 19, 13, 195, 169, 20, 37, 91, 65, 113, 47, 10, 6, 15, 83, 109, 55, 65, 109, 52, 111, 55, 47, 0, 13, 81, 102, 101, 108, 109, 101, 114, 195, 188, 108, 116, 32, 22, 66, 20, 192, 109, 55, 23, 48, 113, 50, 89, 47, 0, 13, 81, 112, 195, 169, 110, 122, 116, 32, 27, 66, 20, 192, 109, 55, 23, 108, 6, 15, 83, 113, 52, 83, 37, 0, 13, 82, 97, 32, 102, 195, 169, 114, 102, 105, 32, 27, 66, 20, 192, 109, 55, 23, 65, 37, 50, 72, 109, 50, 49, 37, 0, 13, 81, 109, 105, 110, 100, 101, 110, 107, 105, 32, 25, 66, 20, 192, 109, 55, 10, 6, 15, 50, 109, 49, 47, 109, 49, 0, 13, 81, 110, 101, 107, 116, 101, 107, 32, 35, 66, 20, 192, 109, 55, 6, 23, 108, 6, 15, 52, 109, 50, 72, 118, 52, 110, 49, 0, 13, 82, 97, 32, 114, 101, 110, 100, 197, 145, 114, 195, 182, 107, 32, 30, 67, 25, 84, 129, 83, 40, 52, 108, 23, 72, 39, 55, 81, 39, 49, 108, 47, 0, 13, 81, 100, 111, 108, 103, 111, 107, 97, 116, 32, 30, 6, 9, 19, 13, 195, 169, 20, 37, 91, 65, 113, 47, 23, 109, 55, 109, 52, 109, 72, 0, 13, 81, 101, 108, 101, 114, 101, 100, 32, 6, 195, 25, 84, 129, 13, 14, 139, 22, 195, 161, 19, 195, 161, 18, 15, 12, 14, 9, 13, 5, 194, 20, 192, 13, 14, 66, 36, 64, 37, 72, 118, 91, 109, 71, 12, 0, 25, 9, 14, 3, 95, 54, 17, 107, 108, 47, 39, 72, 37, 49, 108, 0, 0, 15, 140, 5, 12, 12, 5, 14, 197, 145, 18, 9, 26, 14, 9, 13, 8, 133, 7, 18, 195, 179, 6, 13, 9, 3, 95, 50, 48, 107, 116, 89, 0, 0, 14, 139, 5, 12, 18, 5, 14, 4, 5, 26, 195, 169, 19, 13, 12, 137, 4, 15, 11, 20, 15, 18, 14, 197, 145, 13, 14, 139, 19, 5, 12, 5, 10, 20, 5, 26, 195, 169, 19, 13, 0, 13, 138, 14, 195, 169, 16, 19, 26, 5, 18, 197, 177, 13, 20, 145, 9, 14, 4, 195, 173, 20, 22, 195, 161, 14, 25, 15, 11, 18, 195, 179, 12, 13, 30, 69, 4, 192, 80, 84, 192, 108, 55, 108, 48, 40, 55, 23, 84, 109, 50, 12, 37, 109, 0, 13, 81, 118, 101, 110, 110, 105, 101, 32, 8, 197, 8, 83, 142, 20, 64, 13, 8, 197, 4, 192, 80, 84, 192, 13, 11, 136, 4, 195, 182, 14, 20, 195, 169, 19, 13, 0, 14, 139, 11, 195, 182, 19, 26, 195, 182, 14, 195, 182, 13, 13, 0, 9, 134, 195, 169, 18, 20, 9, 11, 13, 10, 199, 80, 84, 133, 53, 68, 197, 56, 13, 9, 134, 14, 195, 169, 26, 9, 11, 13, 0, 44, 11, 22, 9, 19, 19, 26, 1, 5, 19, 195, 169, 19, 84, 37, 89, 12, 108, 109, 91, 113, 91, 23, 107, 108, 47, 114, 91, 108, 37, 47, 0, 13, 81, 104, 97, 116, 195, 161, 115, 97, 105, 116, 32, 27, 7, 14, 25, 195, 173, 12, 9, 11, 67, 112, 55, 37, 49, 15, 108, 52, 52, 108, 0, 13, 81, 97, 114, 114, 97, 32, 11, 200, 36, 229, 5, 72, 225, 84, 20, 224, 13, 14, 68, 29, 148, 197, 88, 79, 109, 91, 109, 84, 0, 42, 42, 11, 5, 95, 35, 45, 1, 9, 108, 37, 0, 21, 12, 3, 95, 53, 15, 110, 47, 110, 72, 37, 49, 0, 0, 0, 9, 198, 80, 18, 193, 72, 160, 64, 13, 9, 198, 4, 212, 21, 48, 192, 64, 13, 9, 134, 14, 25, 195, 186, 10, 20, 13, 13, 4, 95, 13, 3, 14, 65, 108, 49, 52, 39, 50, 0, 14, 3, 95, 55, 17, 107, 109, 47, 109, 72, 37, 49, 109, 0, 0, 13, 138, 20, 195, 182, 18, 20, 195, 169, 14, 9, 11, 13, 0, 11, 200, 77, 161, 75, 80, 244, 146, 4, 192, 13, 10, 135, 18, 195, 169, 7, 9, 5, 11, 13, 0, 9, 134, 6, 197, 145, 26, 14, 9, 13, 23, 67, 37, 69, 0, 37, 47, 12, 23, 91, 109, 50, 49, 37, 0, 13, 81, 115, 101, 110, 107, 105, 32, 17, 67, 37, 69, 0, 37, 47, 12, 23, 37, 91, 0, 13, 81, 105, 115, 32, 29, 67, 37, 69, 0, 37, 47, 12, 23, 39, 55, 84, 108, 91, 47, 108, 65, 0, 13, 81, 111, 108, 118, 97, 115, 116, 97, 109, 32, 23, 67, 37, 69, 0, 37, 47, 12, 55, 114, 47, 12, 108, 0, 13, 81, 108, 195, 161, 116, 116, 97, 32, 9, 134, 14, 195, 169, 26, 14, 9, 13, 6, 195, 37, 69, 0, 13, 8, 133, 5, 12, 195, 182, 12, 13, 0, 0, 9, 134, 15, 12, 3, 19, 195, 179, 13, 14, 203, 60, 179, 211, 80, 83, 5, 24, 243, 142, 4, 192, 13, 12, 201, 52, 81, 212, 21, 68, 218, 21, 69, 0, 13, 0, 10, 135, 14, 25, 21, 7, 22, 195, 179, 13, 12, 201, 8, 83, 211, 105, 67, 212, 80, 160, 73, 13, 12, 137, 2, 15, 20, 18, 195, 161, 14, 25, 1, 13, 13, 3, 95, 54, 15, 107, 108, 47, 39, 72, 37, 49, 0, 0, 13, 138, 20, 195, 182, 18, 20, 195, 169, 14, 14, 9, 13, 40, 13, 11, 9, 1, 4, 195, 161, 19, 15, 11, 2, 195, 179, 12, 49, 37, 108, 72, 114, 91, 39, 49, 71, 115, 55, 23, 108, 107, 39, 88, 0, 13, 81, 97, 104, 104, 111, 122, 32, 13, 138, 20, 195, 182, 18, 20, 195, 169, 14, 14, 9, 13, 0, 17, 142, 16, 9, 12, 12, 1, 14, 1, 20, 15, 11, 2, 195, 179, 12, 13, 0, 9, 198, 32, 20, 141, 4, 66, 75, 13, 0, 6, 195, 24, 84, 211, 13, 0, 8, 197, 24, 241, 206, 4, 176, 76, 8, 197, 88, 149, 20, 20, 208, 13, 8, 197, 44, 83, 5, 80, 144, 13, 13, 138, 8, 195, 161, 20, 18, 195, 161, 14, 25, 1, 13, 8, 197, 60, 179, 218, 104, 16, 13, 8, 133, 4, 195, 186, 12, 20, 13, 0, 9, 198, 8, 195, 203, 44, 242, 192, 13, 6, 195, 44, 20, 0, 13, 0, 16, 141, 5, 19, 26, 11, 195, 182, 26, 195, 182, 11, 195, 182, 14, 13, 11, 136, 13, 5, 7, 25, 195, 169, 2, 5, 13, 10, 199, 32, 85, 9, 48, 20, 15, 44, 13, 6, 195, 24, 84, 212, 13, 0, 9, 198, 80, 84, 218, 80, 85, 0, 13, 7, 196, 44, 84, 133, 76, 13, 7, 196, 44, 84, 133, 76, 13, 13, 3, 95, 55, 15, 107, 109, 47, 109, 72, 37, 49, 0, 0, 12, 201, 72, 17, 193, 77, 162, 207, 16, 226, 64, 13, 13, 138, 8, 1, 19, 26, 14, 195, 161, 12, 10, 1, 13, 11, 136, 20, 195, 161, 18, 7, 25, 1, 11, 13, 8, 197, 84, 115, 210, 56, 144, 13, 6, 195, 60, 179, 218, 13, 0, 7, 66, 29, 144, 79, 113, 0, 14, 139, 16, 18, 5, 6, 5, 18, 195, 161, 12, 10, 1, 13, 9, 198, 32, 21, 129, 104, 146, 192, 13, 9, 198, 4, 176, 82, 56, 18, 192, 13, 9, 198, 44, 86, 133, 48, 226, 64, 13, 9, 198, 56, 85, 133, 104, 146, 192, 13, 9, 198, 24, 241, 193, 16, 226, 64, 13, 12, 137, 4, 15, 12, 7, 15, 26, 195, 179, 11, 13, 9, 134, 14, 25, 195, 186, 12, 20, 13, 14, 3, 95, 49, 17, 109, 79, 12, 109, 72, 37, 49, 109, 0, 0, 13, 138, 14, 195, 182, 22, 5, 11, 19, 26, 9, 11, 13, 11, 136, 3, 19, 5, 18, 195, 169, 2, 5, 13, 12, 201, 32, 20, 132, 88, 84, 133, 44, 85, 0, 13, 14, 203, 80, 20, 1, 77, 165, 1, 48, 21, 21, 56, 176, 13, 9, 198, 52, 241, 5, 48, 193, 75, 13, 17, 142, 195, 169, 18, 20, 5, 12, 13, 5, 26, 14, 195, 188, 14, 11, 13, 10, 199, 77, 161, 82, 21, 1, 76, 80, 13, 13, 138, 20, 195, 182, 18, 5, 11, 19, 26, 9, 11, 13, 10, 135, 12, 195, 179, 7, 15, 20, 20, 13, 10, 135, 19, 26, 195, 161, 12, 12, 20, 13, 0, 10, 135, 11, 12, 195, 179, 14, 15, 11, 13, 32, 6, 195, 186, 10, 1, 2, 2, 116, 57, 108, 71, 12, 23, 83, 109, 55, 108, 72, 108, 47, 0, 13, 81, 102, 101, 108, 97, 100, 97, 116, 32, 7, 196, 80, 84, 133, 80, 13, 12, 137, 3, 5, 12, 12, 195, 161, 11, 18, 1, 13, 16, 141, 195, 161, 12, 12, 195, 161, 19, 16, 15, 14, 20, 10, 1, 13, 8, 133, 22, 195, 169, 7, 5, 13, 0, 32, 10, 8, 1, 20, 195, 161, 18, 15, 26, 26, 1, 107, 108, 47, 114, 52, 39, 88, 88, 108, 23, 65, 109, 81, 0, 13, 81, 109, 101, 103, 32, 17, 142, 22, 9, 26, 19, 7, 195, 161, 12, 1, 20, 15, 11, 18, 1, 13, 13, 138, 11, 195, 173, 22, 195, 161, 14, 3, 19, 9, 13, 0, 14, 139, 12, 195, 182, 11, 195, 169, 19, 5, 11, 18, 5, 13, 52, 13, 13, 5, 7, 14, 195, 182, 22, 5, 11, 19, 26, 9, 11, 65, 109, 81, 50, 110, 84, 109, 49, 89, 37, 49, 23, 108, 23, 83, 109, 55, 107, 118, 88, 109, 47, 0, 13, 82, 97, 32, 102, 101, 108, 104, 197, 145, 122, 101, 116, 32, 9, 134, 195, 188, 7, 25, 5, 20, 13, 12, 137, 5, 12, 22, 195, 169, 7, 26, 9, 11, 13, 18, 143, 8, 15, 26, 26, 195, 161, 20, 1, 18, 20, 15, 26, 195, 179, 9, 13, 9, 134, 6, 195, 169, 14, 25, 20, 13, 9, 3, 95, 55, 5, 107, 109, 47, 0, 0, 13, 138, 5, 18, 197, 145, 19, 195, 182, 4, 9, 11, 13, 10, 199, 24, 83, 18, 4, 181, 1, 52, 13, 15, 140, 195, 169, 16, 195, 188, 12, 5, 20, 195, 169, 2, 5, 13, 15, 140, 11, 195, 169, 18, 4, 195, 169, 19, 5, 11, 18, 5, 13, 13, 138, 22, 195, 161, 18, 8, 1, 20, 195, 179, 11, 13, 0, 11, 200, 77, 1, 67, 36, 98, 75, 85, 48, 13, 60, 13, 8, 195, 161, 12, 195, 179, 26, 1, 20, 15, 11, 18, 1, 107, 114, 55, 115, 88, 108, 47, 39, 49, 52, 108, 23, 76, 108, 47, 55, 108, 49, 39, 88, 107, 108, 47, 40, 50, 49, 0, 13, 81, 99, 115, 97, 116, 108, 97, 107, 111, 122, 104, 97, 116, 117, 110, 107, 32, 7, 196, 32, 83, 25, 80, 13, 7, 196, 24, 243, 25, 80, 13, 15, 3, 95, 48, 15, 50, 6, 40, 55, 55, 108, 72, 37, 49, 0, 0, 22, 67, 20, 225, 0, 116, 57, 91, 4, 39, 52, 0, 44, 82, 111, 102, 32, 108, 105, 110, 101, 32, 17, 142, 5, 12, 22, 195, 169, 7, 26, 195, 169, 19, 195, 169, 2, 5, 13, 8, 195, 37, 5, 22, 17, 42, 42, 0, 18, 143, 195, 169, 12, 5, 12, 13, 9, 19, 26, 5, 18, 5, 11, 18, 5, 13, 14, 139, 22, 1, 18, 9, 195, 161, 14, 19, 19, 195, 161, 13, 5, 194, 44, 32, 13, 10, 135, 19, 26, 197, 177, 18, 197, 145, 13, 10, 135, 19, 26, 195, 179, 12, 14, 9, 13, 5, 194, 20, 224, 13, 5, 194, 20, 224, 72, 16, 66, 44, 32, 49, 110, 52, 111, 55, 71, 109, 55, 111, 55, 0, 25, 0, 10, 199, 4, 192, 80, 61, 165, 1, 52, 13, 10, 199, 28, 243, 132, 60, 197, 1, 52, 13, 14, 139, 19, 26, 1, 2, 2, 22, 195, 161, 14, 25, 20, 13, 15, 140, 6, 5, 12, 5, 12, 197, 145, 19, 195, 169, 7, 5, 13, 15, 4, 95, 48, 90, 53, 89, 114, 88, 109, 88, 52, 109, 72, 0, 13, 3, 95, 51, 88, 107, 108, 52, 65, 37, 50, 119, 0, 0, 16, 141, 12, 5, 22, 5, 26, 195, 169, 14, 25, 5, 12, 14, 9, 13, 7, 196, 20, 197, 133, 44, 13, 12, 137, 12, 5, 7, 25, 197, 145, 26, 14, 9, 13, 12, 137, 2, 1, 2, 18, 195, 161, 12, 14, 9, 13, 7, 196, 104, 21, 129, 72, 13, 7, 132, 20, 195, 169, 12, 20, 15, 4, 95, 48, 90, 52, 47, 112, 88, 109, 88, 52, 109, 72, 0, 9, 3, 95, 48, 67, 89, 114, 88, 0, 0, 10, 135, 195, 188, 12, 10, 195, 182, 14, 13, 9, 134, 22, 195, 169, 12, 20, 5, 13, 18, 4, 95, 48, 90, 55, 47, 112, 88, 65, 37, 55, 37, 39, 65, 39, 72, 0, 0, 14, 139, 22, 5, 19, 26, 20, 5, 19, 195, 169, 7, 5, 13, 9, 198, 52, 20, 129, 17, 96, 64, 13, 9, 198, 16, 20, 129, 9, 32, 64, 13, 15, 4, 95, 48, 90, 54, 65, 37, 55, 37, 39, 65, 39, 72, 0, 0, 15, 140, 11, 9, 16, 18, 195, 179, 2, 195, 161, 12, 14, 9, 13, 57, 15, 195, 161, 12, 12, 195, 161, 19, 16, 15, 14, 20, 15, 13, 1, 20, 114, 55, 12, 114, 91, 48, 39, 50, 47, 39, 65, 108, 47, 23, 107, 108, 50, 81, 39, 89, 47, 108, 47, 39, 65, 0, 13, 81, 104, 97, 110, 103, 111, 122, 116, 97, 116, 111, 109, 32, 15, 140, 12, 5, 8, 5, 20, 197, 145, 19, 195, 169, 7, 5, 13, 8, 133, 9, 4, 195, 169, 14, 22, 12, 4, 95, 48, 90, 49, 47, 37, 88, 109, 72, 0, 0, 10, 135, 13, 15, 19, 14, 195, 169, 11, 13, 9, 198, 52, 147, 132, 20, 229, 0, 13, 24, 5, 14, 195, 169, 8, 1, 50, 113, 107, 108, 15, 84, 109, 55, 109, 0, 13, 81, 118, 101, 108, 101, 32, 10, 135, 18, 195, 169, 19, 26, 5, 11, 13, 12, 137, 11, 9, 1, 2, 195, 161, 12, 20, 1, 13, 9, 198, 52, 147, 132, 20, 229, 0, 11, 16, 3, 95, 57, 15, 49, 37, 55, 109, 50, 119, 109, 72, 37, 49, 0, 0, 10, 135, 11, 195, 182, 26, 2, 5, 14, 13, 28, 7, 11, 195, 182, 26, 2, 5, 14, 49, 110, 88, 71, 109, 50, 10, 6, 15, 91, 109, 65, 0, 13, 81, 115, 101, 109, 32, 45, 70, 72, 81, 199, 20, 196, 133, 52, 109, 81, 12, 109, 55, 52, 36, 23, 113, 71, 52, 109, 72, 107, 109, 47, 111, 50, 49, 0, 13, 81, 195, 169, 98, 114, 101, 100, 104, 101, 116, 195, 188, 110, 107, 32, 35, 70, 72, 81, 199, 20, 196, 133, 52, 109, 81, 12, 109, 55, 52, 109, 23, 65, 109, 81, 107, 108, 55, 47, 0, 13, 81, 109, 101, 103, 104, 97, 108, 116, 32, 13, 138, 8, 9, 195, 161, 14, 25, 15, 12, 20, 1, 13, 12, 4, 95, 48, 90, 51, 109, 88, 52, 109, 72, 0, 0, 47, 9, 8, 5, 12, 25, 195, 169, 14, 5, 11, 107, 109, 57, 113, 50, 109, 49, 23, 65, 109, 81, 47, 108, 55, 114, 55, 114, 91, 108, 0, 13, 81, 109, 101, 103, 116, 97, 108, 195, 161, 108, 195, 161, 115, 97, 32, 14, 139, 22, 195, 161, 12, 1, 19, 26, 15, 12, 20, 1, 13, 17, 66, 37, 96, 50, 113, 79, 12, 109, 55, 0, 44, 42, 81, 101, 108, 32, 12, 4, 95, 48, 90, 50, 89, 114, 88, 108, 72, 0, 0, 7, 195, 88, 243, 20, 13, 22, 28, 67, 88, 243, 20, 84, 39, 55, 47, 10, 6, 15, 107, 108, 55, 39, 47, 12, 0, 13, 81, 104, 97, 108, 111, 116, 116, 32, 25, 67, 88, 243, 20, 84, 39, 55, 47, 10, 6, 15, 39, 57, 108, 50, 0, 13, 81, 111, 108, 121, 97, 110, 32, 36, 67, 88, 243, 20, 84, 39, 55, 47, 10, 6, 15, 109, 55, 83, 39, 81, 55, 108, 55, 84, 108, 0, 13, 81, 101, 108, 102, 111, 103, 108, 97, 108, 118, 97, 32, 9, 134, 14, 197, 145, 14, 5, 11, 13, 39, 71, 24, 241, 204, 4, 197, 1, 44, 83, 39, 81, 55, 108, 55, 47, 108, 49, 10, 6, 15, 114, 55, 12, 114, 91, 47, 0, 13, 81, 195, 161, 108, 108, 195, 161, 115, 116, 32, 22, 67, 88, 243, 20, 84, 39, 55, 47, 15, 109, 52, 52, 109, 0, 13, 81, 101, 114, 114, 101, 32, 15, 140, 11, 9, 6, 15, 7, 195, 161, 19, 15, 12, 20, 1, 13, 6, 195, 44, 81, 4, 20, 0, 14, 139, 9, 7, 195, 169, 14, 25, 5, 9, 14, 5, 11, 13, 11, 136, 8, 195, 161, 26, 2, 195, 179, 12, 13, 12, 137, 5, 12, 195, 161, 18, 21, 12, 20, 1, 13, 10, 135, 8, 9, 20, 20, 195, 169, 11, 13, 0, 14, 3, 226, 136, 158, 84, 109, 81, 47, 109, 55, 109, 50, 0, 38, 10, 12, 5, 8, 5, 20, 197, 145, 22, 195, 169, 55, 109, 107, 109, 47, 118, 84, 113, 23, 47, 113, 47, 109, 55, 109, 0, 13, 81, 116, 195, 169, 116, 101, 108, 101, 32, 14, 139, 4, 18, 195, 161, 7, 195, 161, 2, 2, 1, 14, 13, 8, 197, 72, 18, 207, 81, 64, 13, 36, 10, 12, 5, 8, 5, 20, 197, 145, 22, 195, 169, 55, 109, 107, 109, 47, 118, 84, 113, 23, 47, 109, 50, 12, 113, 0, 13, 81, 116, 101, 110, 110, 195, 169, 32, 23, 67, 88, 84, 218, 84, 109, 89, 23, 52, 113, 89, 47, 0, 13, 81, 114, 195, 169, 115, 122, 116, 32, 15, 140, 8, 1, 12, 12, 7, 1, 20, 195, 179, 14, 1, 11, 13, 28, 69, 4, 227, 153, 37, 64, 108, 67, 67, 37, 47, 47, 40, 72, 40, 50, 49, 0, 76, 81, 116, 117, 100, 117, 110, 107, 32, 13, 138, 15, 18, 4, 9, 2, 195, 161, 12, 20, 1, 13, 10, 135, 9, 4, 5, 10, 195, 169, 14, 13, 6, 195, 88, 84, 218, 13, 10, 135, 197, 145, 19, 26, 195, 169, 14, 20, 0, 14, 139, 195, 169, 18, 20, 195, 169, 11, 5, 12, 20, 5, 13, 0, 15, 3, 226, 137, 160, 50, 109, 65, 109, 79, 109, 50, 55, 118, 0, 19, 67, 9, 81, 192, 71, 40, 81, 23, 84, 108, 50, 0, 13, 81, 118, 97, 110, 32, 13, 138, 14, 25, 15, 13, 20, 1, 20, 195, 179, 11, 13, 10, 135, 13, 195, 182, 7, 195, 188, 12, 13, 0, 53, 11, 3, 19, 197, 145, 4, 10, 195, 169, 14, 5, 11, 76, 118, 79, 12, 113, 50, 109, 49, 23, 109, 55, 49, 109, 52, 111, 55, 113, 91, 113, 52, 109, 0, 13, 81, 101, 108, 107, 101, 114, 195, 188, 108, 195, 169, 115, 195, 169, 114, 101, 32, 13, 138, 195, 182, 22, 5, 26, 5, 20, 2, 5, 14, 13, 14, 139, 13, 5, 8, 5, 20, 14, 195, 169, 14, 5, 11, 13, 14, 139, 11, 195, 182, 26, 195, 182, 12, 20, 195, 169, 11, 13, 10, 135, 10, 195, 161, 18, 21, 14, 11, 13, 13, 138, 1, 4, 195, 179, 26, 195, 161, 19, 195, 186, 13, 11, 136, 14, 195, 169, 12, 11, 195, 188, 12, 13, 0, 12, 3, 226, 136, 154, 79, 110, 49, 57, 109, 55, 0, 8, 197, 8, 243, 20, 61, 64, 13, 18, 143, 15, 18, 19, 26, 195, 161, 7, 18, 195, 169, 19, 26, 2, 5, 14, 13, 9, 198, 44, 148, 129, 44, 21, 1, 13, 15, 140, 20, 1, 12, 195, 161, 12, 8, 1, 20, 195, 179, 11, 13, 6, 195, 32, 148, 218, 13, 0, 14, 139, 18, 195, 182, 7, 26, 195, 173, 20, 5, 14, 9, 13, 5, 194, 36, 112, 13, 14, 3, 95, 52, 17, 50, 109, 79, 109, 72, 37, 49, 109, 0, 0, 6, 195, 44, 83, 12, 13, 24, 67, 44, 83, 12, 49, 109, 55, 12, 23, 84, 109, 50, 12, 37, 0, 13, 81, 118, 101, 110, 110, 105, 32, 28, 67, 44, 83, 12, 49, 109, 55, 12, 23, 83, 39, 81, 108, 72, 50, 37, 0, 13, 81, 102, 111, 103, 97, 100, 110, 105, 32, 25, 67, 44, 83, 12, 49, 109, 55, 12, 23, 49, 110, 47, 50, 37, 0, 13, 81, 107, 195, 182, 116, 110, 105, 32, 32, 67, 44, 83, 12, 49, 109, 55, 12, 23, 39, 49, 47, 108, 47, 50, 37, 40, 49, 0, 13, 81, 111, 107, 116, 97, 116, 110, 105, 117, 107, 32, 32, 67, 44, 83, 12, 49, 109, 55, 12, 23, 107, 108, 52, 119, 39, 55, 50, 37, 108, 0, 13, 81, 104, 97, 114, 99, 111, 108, 110, 105, 97, 32, 17, 142, 5, 12, 4, 195, 182, 14, 20, 195, 182, 20, 20, 195, 169, 11, 13, 12, 201, 72, 16, 143, 76, 179, 196, 61, 69, 0, 13, 6, 195, 40, 83, 0, 13, 6, 195, 52, 244, 212, 13, 0, 12, 137, 2, 5, 19, 26, 195, 169, 12, 14, 9, 13, 7, 196, 48, 244, 14, 36, 13, 0, 8, 197, 8, 19, 139, 40, 16, 13, 17, 142, 20, 21, 12, 1, 10, 4, 15, 14, 195, 173, 20, 1, 14, 9, 13, 8, 197, 37, 51, 69, 72, 144, 13, 13, 138, 195, 161, 20, 16, 1, 11, 15, 12, 14, 9, 13, 9, 198, 28, 243, 132, 60, 195, 137, 13, 9, 198, 28, 243, 132, 60, 194, 129, 13, 8, 197, 77, 161, 82, 80, 80, 13, 7, 132, 6, 195, 161, 11, 13, 0, 31, 67, 48, 20, 0, 55, 108, 48, 9, 15, 47, 109, 47, 109, 57, 113, 52, 109, 0, 13, 81, 116, 101, 116, 101, 106, 195, 169, 114, 101, 32, 6, 195, 48, 20, 0, 13, 7, 132, 6, 195, 161, 10, 13, 7, 195, 56, 242, 1, 72, 8, 0, 15, 140, 19, 26, 1, 2, 195, 161, 12, 25, 15, 26, 14, 9, 13, 21, 146, 13, 5, 7, 22, 195, 161, 19, 195, 161, 18, 15, 12, 8, 1, 20, 195, 179, 11, 13, 15, 140, 18, 195, 161, 2, 5, 19, 26, 195, 169, 12, 14, 9, 13, 12, 201, 24, 83, 1, 16, 21, 15, 44, 21, 0, 13, 10, 199, 40, 21, 129, 76, 243, 10, 4, 13, 11, 136, 195, 161, 6, 1, 1, 58, 6, 1, 42, 0, 11, 200, 60, 197, 129, 76, 112, 84, 88, 16, 13, 22, 147, 13, 15, 2, 9, 12, 19, 26, 15, 12, 7, 195, 161, 12, 20, 1, 20, 195, 179, 11, 13, 9, 134, 11, 195, 161, 15, 19, 26, 13, 0, 11, 3, 226, 136, 146, 65, 37, 50, 40, 89, 0, 9, 198, 64, 244, 148, 60, 195, 137, 13, 8, 197, 20, 165, 5, 56, 144, 13, 0, 10, 135, 22, 195, 169, 7, 26, 5, 13, 13, 15, 140, 9, 14, 4, 195, 173, 20, 195, 161, 19, 11, 15, 18, 13, 13, 3, 95, 53, 17, 110, 47, 110, 72, 37, 49, 109, 0, 0, 9, 134, 6, 197, 145, 14, 5, 11, 13, 13, 138, 14, 25, 195, 186, 10, 20, 1, 14, 1, 11, 13, 10, 199, 52, 81, 205, 60, 225, 10, 4, 13, 8, 133, 9, 4, 195, 169, 26, 13, 10, 135, 3, 19, 9, 14, 195, 161, 12, 13, 9, 3, 95, 49, 48, 47, 112, 88, 0, 0, 11, 200, 76, 84, 139, 20, 229, 5, 56, 144, 13, 7, 196, 16, 149, 129, 80, 13, 7, 132, 8, 195, 169, 20, 13, 0, 15, 140, 11, 5, 18, 195, 188, 12, 14, 195, 169, 14, 5, 11, 13, 7, 132, 6, 197, 145, 19, 13, 11, 136, 10, 195, 161, 20, 19, 26, 9, 11, 13, 6, 195, 41, 85, 0, 13, 0, 11, 136, 13, 5, 13, 2, 18, 195, 161, 14, 13, 9, 134, 195, 169, 16, 195, 173, 20, 13, 12, 4, 8, 195, 169, 22, 107, 113, 84, 0, 42, 42, 0, 19, 71, 44, 147, 15, 29, 32, 77, 52, 107, 105, 108, 111, 103, 114, 97, 109, 0, 29, 27, 4, 5, 19, 197, 145, 109, 91, 118, 23, 52, 113, 89, 113, 47, 0, 13, 81, 114, 195, 169, 115, 122, 195, 169, 116, 32, 29, 4, 5, 19, 197, 145, 109, 91, 118, 23, 48, 39, 50, 80, 108, 37, 50, 0, 13, 81, 112, 111, 110, 116, 106, 97, 105, 110, 32, 11, 136, 20, 195, 161, 18, 8, 5, 12, 25, 13, 7, 132, 5, 19, 197, 145, 13, 0, 14, 139, 11, 15, 18, 13, 195, 161, 14, 25, 14, 1, 11, 13, 27, 4, 6, 197, 145, 20, 83, 118, 47, 23, 84, 114, 52, 40, 50, 49, 0, 13, 81, 118, 195, 161, 114, 117, 110, 107, 32, 15, 140, 18, 5, 14, 4, 19, 26, 5, 18, 18, 197, 145, 12, 13, 15, 140, 19, 26, 5, 13, 20, 1, 14, 195, 186, 22, 1, 12, 13, 7, 132, 12, 195, 169, 16, 13, 7, 132, 6, 197, 145, 20, 13, 7, 132, 6, 195, 161, 20, 13, 13, 3, 95, 52, 15, 50, 109, 79, 109, 72, 37, 49, 0, 18, 4, 95, 48, 90, 56, 89, 114, 88, 65, 37, 55, 37, 39, 65, 39, 72, 0, 0, 12, 137, 8, 1, 19, 15, 14, 12, 195, 173, 20, 13, 15, 140, 20, 1, 18, 20, 1, 12, 13, 195, 161, 14, 1, 11, 13, 9, 134, 12, 5, 12, 11, 197, 177, 13, 13, 138, 8, 1, 20, 195, 161, 18, 9, 4, 197, 145, 13, 0, 9, 198, 20, 195, 65, 72, 17, 20, 13, 13, 138, 18, 195, 169, 19, 26, 5, 19, 195, 188, 12, 13, 16, 141, 16, 18, 15, 7, 18, 1, 13, 10, 195, 161, 14, 1, 11, 13, 12, 201, 64, 19, 129, 77, 162, 207, 16, 224, 75, 13, 10, 135, 6, 195, 188, 7, 7, 197, 145, 13, 12, 137, 1, 11, 20, 21, 195, 161, 12, 9, 19, 13, 13, 138, 14, 25, 21, 7, 4, 195, 173, 10, 1, 20, 13, 0, 15, 140, 9, 18, 195, 161, 14, 25, 195, 173, 20, 1, 14, 9, 13, 9, 198, 16, 243, 7, 61, 162, 75, 13, 12, 3, 95, 55, 88, 107, 109, 47, 84, 109, 50, 0, 0, 22, 5, 195, 169, 12, 20, 5, 113, 55, 47, 109, 23, 65, 109, 81, 0, 13, 81, 109, 101, 103, 32, 10, 135, 18, 5, 195, 161, 12, 9, 19, 13, 7, 196, 64, 81, 9, 28, 13, 49, 70, 88, 148, 218, 60, 229, 0, 84, 37, 89, 39, 50, 47, 23, 109, 55, 109, 50, 81, 109, 72, 107, 109, 47, 109, 47, 55, 109, 50, 0, 13, 81, 101, 108, 101, 110, 103, 101, 100, 104, 101, 116, 101, 116, 108, 101, 110, 32, 23, 70, 88, 148, 218, 60, 229, 0, 84, 37, 89, 39, 50, 47, 23, 108, 88, 0, 13, 81, 97, 122, 32, 25, 150, 18, 5, 14, 4, 19, 26, 5, 18, 20, 5, 12, 5, 16, 195, 173, 20, 195, 169, 19, 11, 15, 18, 13, 50, 70, 88, 148, 218, 60, 229, 0, 84, 37, 89, 39, 50, 47, 23, 108, 89, 47, 23, 47, 108, 48, 108, 89, 47, 108, 55, 47, 108, 65, 0, 13, 82, 97, 122, 116, 32, 116, 97, 112, 97, 115, 122, 116, 97, 108, 116, 97, 109, 32, 9, 198, 88, 148, 218, 60, 229, 0, 13, 7, 196, 52, 20, 16, 4, 13, 7, 196, 44, 20, 20, 4, 13, 0, 17, 142, 6, 5, 12, 20, 5, 12, 5, 16, 195, 173, 20, 5, 14, 9, 13, 8, 197, 44, 20, 10, 60, 224, 13, 9, 198, 4, 192, 75, 84, 195, 137, 13, 0, 18, 143, 13, 5, 7, 22, 1, 12, 195, 179, 19, 195, 173, 20, 1, 14, 9, 13, 44, 7, 195, 161, 12, 12, 1, 13, 9, 114, 55, 12, 108, 65, 37, 10, 6, 15, 47, 114, 65, 39, 81, 108, 47, 114, 91, 108, 0, 13, 81, 116, 195, 161, 109, 111, 103, 97, 116, 195, 161, 115, 97, 32, 18, 4, 14, 195, 169, 26, 50, 113, 88, 23, 49, 37, 0, 13, 81, 107, 105, 32, 11, 136, 13, 195, 179, 4, 19, 26, 5, 18, 13, 10, 135, 7, 25, 195, 182, 18, 7, 25, 13, 9, 198, 88, 149, 1, 81, 64, 64, 13, 9, 198, 81, 81, 1, 81, 64, 64, 13, 7, 132, 14, 195, 169, 26, 13, 7, 132, 22, 195, 173, 26, 13, 0, 10, 199, 65, 35, 202, 20, 181, 10, 20, 13, 0, 22, 68, 81, 33, 78, 16, 47, 52, 109, 50, 72, 10, 6, 15, 108, 88, 0, 13, 81, 97, 122, 32, 0, 13, 138, 11, 195, 182, 22, 5, 20, 5, 12, 20, 5, 13, 9, 134, 6, 195, 182, 12, 195, 169, 13, 0, 20, 66, 37, 128, 49, 37, 55, 109, 50, 119, 12, 109, 55, 0, 44, 42, 81, 101, 108, 32, 9, 5, 95, 35, 45, 9, 11, 15, 0, 0, 6, 195, 44, 83, 20, 13, 6, 195, 24, 243, 20, 13, 0, 9, 198, 104, 18, 140, 61, 69, 0, 13, 0, 12, 137, 6, 5, 12, 195, 161, 18, 18, 1, 12, 13, 11, 136, 5, 18, 197, 145, 19, 26, 1, 11, 13, 11, 136, 13, 1, 7, 195, 161, 14, 1, 11, 13, 14, 139, 20, 5, 18, 195, 188, 12, 5, 20, 195, 169, 14, 13, 7, 132, 8, 195, 173, 7, 13, 8, 197, 44, 20, 15, 81, 64, 13, 0, 12, 137, 12, 1, 11, 14, 195, 161, 14, 1, 11, 13, 20, 145, 8, 1, 10, 12, 195, 169, 11, 20, 1, 12, 1, 14, 10, 1, 9, 14, 11, 13, 9, 198, 88, 85, 5, 81, 65, 64, 13, 12, 5, 95, 35, 45, 9, 7, 113, 37, 81, 0, 21, 0, 13, 138, 9, 4, 197, 145, 19, 26, 1, 11, 15, 11, 13, 0, 9, 198, 77, 162, 210, 37, 5, 0, 13, 9, 198, 77, 162, 210, 37, 5, 0, 13, 16, 141, 2, 5, 6, 15, 12, 25, 195, 161, 19, 15, 12, 20, 1, 13, 0, 15, 140, 4, 15, 12, 7, 15, 26, 14, 195, 161, 14, 1, 11, 13, 15, 140, 13, 5, 7, 15, 12, 4, 195, 161, 19, 14, 1, 11, 13, 11, 136, 12, 195, 161, 19, 26, 12, 195, 179, 13, 9, 198, 76, 244, 143, 104, 21, 1, 13, 13, 138, 13, 5, 7, 22, 195, 169, 4, 5, 14, 9, 13, 0, 20, 145, 6, 5, 12, 8, 1, 19, 26, 14, 195, 161, 12, 195, 179, 11, 14, 1, 11, 13, 29, 66, 52, 16, 65, 108, 15, 72, 113, 55, 109, 55, 118, 47, 12, 0, 13, 81, 100, 195, 169, 108, 101, 108, 197, 145, 116, 116, 32, 19, 144, 195, 161, 12, 12, 1, 13, 20, 9, 20, 11, 195, 161, 18, 2, 1, 14, 13, 27, 66, 52, 16, 65, 108, 15, 72, 113, 55, 40, 47, 114, 50, 0, 13, 81, 100, 195, 169, 108, 117, 116, 195, 161, 110, 32, 5, 194, 52, 16, 13, 19, 66, 36, 144, 49, 109, 47, 12, 118, 84, 109, 55, 0, 44, 42, 81, 101, 108, 32, 21, 2, 48, 48, 50, 40, 55, 12, 108, 50, 40, 55, 12, 114, 50, 0, 44, 81, 32, 110, 32, 26, 2, 48, 48, 50, 40, 55, 12, 108, 50, 40, 55, 12, 114, 47, 115, 55, 0, 44, 81, 32, 116, 195, 179, 108, 32, 21, 2, 48, 48, 50, 40, 55, 12, 108, 50, 40, 55, 12, 114, 91, 0, 44, 81, 32, 115, 32, 23, 2, 48, 48, 50, 40, 55, 12, 108, 50, 40, 55, 12, 114, 37, 81, 0, 44, 81, 32, 105, 103, 32, 15, 3, 95, 56, 17, 67, 39, 55, 119, 108, 72, 37, 49, 108, 0, 0, 22, 67, 52, 134, 128, 109, 101, 103, 97, 104, 101, 114, 99, 101, 110, 0, 44, 29, 81, 101, 110, 32, 23, 67, 52, 134, 128, 109, 101, 103, 97, 104, 101, 114, 99, 101, 110, 0, 44, 29, 42, 81, 101, 110, 32, 13, 138, 6, 9, 26, 5, 20, 14, 9, 195, 188, 11, 13, 11, 3, 95, 49, 88, 47, 37, 88, 109, 50, 0, 0, 8, 133, 195, 169, 12, 22, 5, 13, 10, 135, 1, 4, 8, 1, 20, 195, 179, 13, 0, 8, 197, 24, 241, 212, 60, 176, 76, 11, 136, 22, 195, 169, 7, 195, 169, 9, 7, 13, 8, 197, 45, 83, 3, 76, 16, 13, 68, 69, 29, 145, 78, 28, 80, 79, 109, 50, 81, 109, 15, 55, 113, 81, 65, 39, 88, 81, 114, 91, 52, 108, 23, 89, 114, 65, 112, 47, 107, 108, 47, 40, 50, 49, 0, 13, 82, 108, 195, 169, 103, 109, 111, 122, 103, 195, 161, 115, 114, 97, 32, 115, 122, 195, 161, 109, 195, 173, 116, 104, 97, 116, 117, 110, 107, 32, 19, 144, 5, 13, 2, 5, 18, 20, 195, 161, 18, 19, 1, 9, 11, 14, 1, 11, 13, 11, 136, 12, 195, 161, 20, 20, 21, 14, 11, 13, 0, 50, 9, 22, 195, 161, 18, 8, 1, 20, 195, 179, 84, 114, 52, 107, 108, 47, 115, 23, 108, 55, 108, 49, 40, 55, 114, 91, 114, 52, 115, 55, 0, 13, 81, 97, 108, 97, 107, 117, 108, 195, 161, 115, 195, 161, 114, 195, 179, 108, 32, 12, 137, 8, 1, 12, 12, 8, 1, 20, 195, 179, 13, 30, 9, 22, 195, 161, 18, 8, 1, 20, 195, 179, 84, 114, 52, 107, 108, 47, 115, 23, 109, 91, 118, 0, 13, 81, 101, 115, 197, 145, 32, 12, 137, 22, 195, 161, 18, 8, 1, 20, 195, 179, 13, 9, 198, 20, 208, 133, 73, 33, 76, 13, 9, 198, 32, 246, 142, 37, 82, 192, 13, 12, 137, 22, 195, 161, 18, 8, 1, 20, 195, 179, 13, 0, 23, 4, 195, 186, 7, 25, 116, 79, 10, 6, 15, 83, 109, 91, 47, 0, 13, 81, 102, 101, 115, 116, 32, 38, 4, 195, 186, 7, 25, 116, 79, 10, 6, 15, 113, 52, 47, 109, 55, 65, 109, 89, 47, 109, 65, 0, 13, 81, 195, 169, 114, 116, 101, 108, 109, 101, 122, 116, 101, 109, 32, 36, 4, 195, 186, 7, 25, 116, 79, 10, 6, 15, 113, 52, 47, 109, 55, 65, 109, 88, 109, 65, 0, 13, 81, 195, 169, 114, 116, 101, 108, 109, 101, 122, 101, 109, 32, 10, 199, 16, 243, 7, 61, 163, 212, 80, 13, 10, 199, 24, 83, 1, 16, 21, 15, 44, 13, 22, 4, 195, 186, 7, 25, 116, 79, 23, 107, 37, 89, 37, 0, 13, 81, 104, 105, 115, 122, 105, 32, 10, 199, 20, 211, 5, 28, 85, 14, 36, 13, 7, 132, 195, 186, 7, 25, 13, 0, 12, 137, 2, 5, 19, 26, 195, 169, 12, 22, 5, 13, 11, 200, 36, 225, 193, 80, 192, 78, 84, 176, 13, 9, 134, 195, 169, 12, 195, 169, 14, 13, 7, 132, 14, 195, 169, 12, 13, 0, 8, 197, 81, 33, 78, 16, 144, 13, 15, 140, 195, 161, 12, 12, 195, 173, 20, 8, 1, 20, 195, 179, 13, 8, 197, 81, 81, 14, 36, 16, 13, 8, 197, 44, 20, 20, 4, 176, 13, 0, 16, 141, 22, 9, 26, 19, 7, 195, 161, 12, 8, 1, 20, 195, 179, 13, 50, 9, 195, 161, 12, 12, 10, 1, 14, 1, 11, 114, 57, 57, 108, 50, 108, 49, 23, 52, 109, 50, 72, 109, 55, 49, 109, 88, 113, 91, 52, 109, 0, 13, 81, 114, 101, 110, 100, 101, 108, 107, 101, 122, 195, 169, 115, 114, 101, 32, 6, 131, 12, 197, 145, 13, 17, 2, 49, 48, 47, 112, 88, 88, 109, 55, 0, 44, 81, 32, 101, 108, 32, 15, 2, 49, 48, 47, 37, 88, 109, 47, 0, 44, 81, 32, 116, 32, 23, 2, 49, 48, 47, 112, 89, 12, 109, 52, 109, 91, 0, 44, 81, 32, 115, 122, 101, 114, 101, 115, 32, 19, 2, 49, 48, 47, 112, 89, 12, 109, 52, 0, 44, 81, 32, 115, 122, 101, 114, 32, 17, 3, 95, 57, 17, 49, 37, 55, 109, 50, 119, 109, 72, 37, 49, 109, 0, 0, 10, 199, 20, 194, 83, 52, 84, 148, 20, 13, 9, 134, 10, 195, 179, 14, 1, 11, 13, 8, 133, 195, 169, 12, 19, 26, 13, 30, 2, 49, 51, 116, 105, 122, 101, 110, 104, 97, 114, 109, 97, 100, 105, 107, 195, 161, 105, 103, 0, 44, 21, 29, 81, 32, 105, 103, 32, 11, 3, 95, 50, 88, 107, 40, 89, 39, 50, 0, 0, 11, 136, 2, 5, 19, 26, 195, 169, 12, 20, 13, 11, 136, 2, 5, 19, 26, 195, 169, 12, 20, 13, 10, 135, 12, 195, 161, 20, 20, 21, 11, 13, 11, 136, 2, 5, 19, 26, 195, 169, 12, 20, 13, 7, 132, 14, 195, 169, 16, 13, 7, 196, 29, 147, 210, 76, 13, 7, 132, 20, 195, 169, 20, 13, 0, 20, 67, 49, 53, 0, 101, 108, 101, 115, 116, 195, 169, 110, 0, 44, 29, 42, 81, 110, 32, 20, 67, 49, 53, 0, 101, 108, 101, 115, 116, 195, 169, 107, 0, 44, 29, 42, 81, 107, 32, 15, 140, 19, 26, 195, 188, 12, 5, 19, 19, 5, 14, 5, 11, 13, 7, 132, 18, 195, 169, 19, 13, 14, 67, 49, 53, 0, 109, 55, 109, 91, 47, 113, 0, 42, 42, 0, 13, 202, 88, 243, 129, 80, 179, 218, 104, 19, 129, 44, 13, 16, 141, 18, 5, 14, 4, 197, 145, 18, 195, 182, 11, 14, 5, 11, 13, 12, 137, 9, 20, 195, 169, 12, 20, 195, 169, 11, 13, 7, 132, 22, 195, 169, 18, 13, 0, 10, 199, 88, 19, 1, 52, 149, 133, 48, 13, 11, 136, 20, 5, 18, 10, 5, 4, 197, 145, 13, 12, 137, 19, 20, 195, 173, 12, 21, 19, 195, 186, 13, 11, 136, 2, 195, 161, 14, 20, 1, 14, 9, 13, 0, 11, 136, 8, 9, 20, 5, 12, 195, 169, 20, 13, 11, 136, 195, 169, 12, 5, 20, 195, 169, 20, 13, 10, 135, 19, 26, 195, 173, 14, 5, 19, 13, 8, 133, 22, 195, 169, 12, 9, 13, 8, 133, 22, 195, 169, 12, 9, 13, 29, 2, 49, 54, 116, 105, 122, 101, 110, 104, 97, 116, 111, 100, 105, 107, 195, 161, 105, 103, 0, 44, 21, 29, 81, 32, 105, 103, 32, 14, 3, 95, 56, 15, 67, 39, 55, 119, 108, 72, 37, 49, 0, 0, 14, 139, 9, 14, 20, 195, 169, 26, 5, 20, 2, 5, 14, 13, 46, 6, 6, 5, 12, 8, 197, 145, 83, 109, 55, 107, 118, 23, 55, 109, 89, 23, 83, 109, 55, 109, 47, 12, 111, 50, 49, 0, 13, 82, 108, 101, 115, 122, 32, 102, 101, 108, 101, 116, 116, 195, 188, 110, 107, 32, 38, 6, 6, 5, 12, 8, 197, 145, 83, 109, 55, 107, 118, 23, 84, 108, 55, 115, 89, 112, 50, 117, 0, 13, 81, 118, 97, 108, 195, 179, 115, 122, 195, 173, 110, 197, 177, 32, 16, 141, 195, 169, 19, 26, 18, 5, 22, 195, 169, 20, 5, 12, 20, 13, 13, 138, 19, 26, 195, 161, 14, 4, 195, 169, 11, 1, 13, 11, 136, 12, 5, 14, 14, 195, 169, 14, 11, 13, 6, 195, 9, 84, 218, 13, 0, 24, 66, 52, 32, 109, 101, 103, 97, 98, 195, 161, 106, 116, 116, 97, 108, 0, 44, 29, 42, 81, 97, 108, 32, 31, 7, 22, 5, 26, 5, 20, 197, 145, 84, 109, 88, 109, 47, 118, 23, 50, 118, 50, 109, 49, 0, 13, 81, 110, 197, 145, 110, 101, 107, 32, 15, 140, 5, 12, 12, 5, 14, 20, 195, 169, 20, 2, 5, 14, 13, 10, 135, 19, 26, 195, 188, 12, 197, 145, 13, 10, 135, 22, 5, 26, 5, 20, 197, 145, 13, 14, 139, 11, 5, 4, 22, 5, 26, 13, 195, 169, 14, 25, 13, 7, 132, 20, 195, 169, 18, 13, 7, 132, 14, 195, 169, 22, 13, 7, 132, 8, 195, 173, 18, 13, 15, 66, 52, 32, 65, 109, 81, 108, 71, 114, 57, 47, 0, 42, 42, 17, 2, 50, 48, 107, 116, 89, 12, 108, 55, 0, 44, 81, 32, 97, 108, 32, 25, 2, 50, 48, 104, 117, 115, 122, 97, 100, 105, 107, 195, 161, 105, 103, 0, 44, 21, 29, 81, 32, 105, 103, 32, 22, 2, 50, 48, 104, 117, 115, 122, 97, 100, 105, 107, 97, 105, 0, 44, 21, 29, 81, 32, 105, 32, 31, 2, 49, 56, 116, 105, 122, 101, 110, 110, 121, 111, 108, 99, 97, 100, 105, 107, 195, 161, 105, 103, 0, 44, 21, 29, 81, 32, 105, 103, 32, 0, 9, 198, 41, 85, 15, 81, 64, 75, 13, 22, 5, 16, 195, 169, 14, 26, 48, 113, 50, 88, 15, 84, 108, 50, 0, 13, 81, 118, 97, 110, 32, 17, 142, 5, 24, 16, 5, 4, 195, 173, 3, 9, 195, 179, 14, 1, 11, 13, 10, 135, 9, 4, 5, 10, 195, 169, 20, 13, 16, 141, 11, 195, 182, 18, 14, 25, 5, 26, 5, 20, 2, 5, 14, 13, 8, 133, 16, 195, 169, 14, 26, 13, 31, 2, 50, 51, 104, 117, 115, 122, 111, 110, 104, 97, 114, 109, 97, 100, 105, 107, 195, 161, 105, 103, 0, 44, 21, 29, 81, 32, 105, 103, 32, 0, 14, 139, 3, 19, 9, 14, 195, 161, 12, 10, 21, 14, 11, 13, 7, 196, 25, 35, 206, 80, 13, 7, 132, 20, 197, 145, 12, 13, 0, 12, 137, 22, 5, 26, 195, 169, 18, 195, 169, 20, 13, 13, 138, 14, 5, 22, 5, 26, 8, 5, 20, 197, 145, 13, 12, 137, 20, 1, 14, 4, 195, 173, 10, 1, 20, 13, 7, 195, 44, 101, 0, 13, 42, 8, 133, 19, 195, 169, 18, 20, 13, 0, 19, 144, 20, 21, 4, 1, 20, 195, 161, 12, 12, 1, 16, 15, 20, 2, 1, 14, 13, 34, 6, 6, 5, 12, 197, 145, 12, 83, 109, 55, 118, 55, 10, 6, 15, 50, 113, 88, 88, 111, 49, 0, 13, 81, 110, 195, 169, 122, 122, 195, 188, 107, 32, 16, 141, 9, 14, 20, 5, 18, 14, 5, 20, 5, 26, 195, 169, 19, 13, 7, 132, 20, 195, 161, 14, 13, 9, 134, 6, 5, 12, 197, 145, 12, 13, 12, 7, 95, 35, 45, 9, 11, 5, 9, 109, 37, 0, 0, 10, 135, 22, 15, 12, 20, 195, 161, 12, 72, 10, 199, 77, 163, 198, 81, 97, 82, 20, 13, 33, 71, 32, 149, 129, 80, 19, 15, 76, 107, 37, 84, 108, 47, 108, 55, 39, 91, 23, 55, 109, 50, 12, 109, 0, 13, 81, 108, 101, 110, 110, 101, 32, 10, 199, 60, 179, 218, 32, 21, 20, 4, 13, 7, 132, 18, 195, 161, 13, 13, 7, 132, 18, 195, 161, 13, 13, 14, 67, 77, 64, 128, 91, 108, 47, 110, 71, 12, 37, 0, 25, 0, 33, 6, 5, 7, 195, 169, 19, 26, 109, 81, 113, 89, 23, 49, 109, 55, 12, 109, 65, 109, 91, 0, 13, 81, 107, 101, 108, 108, 101, 109, 101, 115, 32, 7, 132, 18, 197, 145, 12, 13, 18, 3, 95, 63, 63, 49, 108, 52, 108, 49, 47, 109, 34, 15, 49, 115, 72, 0, 30, 2, 50, 54, 104, 117, 115, 122, 111, 110, 104, 97, 116, 111, 100, 105, 107, 195, 161, 105, 103, 0, 44, 21, 29, 81, 32, 105, 103, 32, 11, 6, 95, 35, 45, 195, 161, 14, 114, 50, 0, 0, 17, 142, 12, 195, 169, 20, 5, 19, 195, 173, 20, 13, 195, 169, 14, 25, 13, 11, 136, 12, 195, 169, 20, 5, 26, 9, 11, 13, 11, 136, 12, 195, 169, 20, 5, 26, 9, 11, 13, 0, 9, 198, 45, 34, 84, 36, 176, 64, 13, 13, 138, 195, 182, 20, 12, 5, 20, 20, 197, 145, 12, 13, 13, 138, 22, 1, 12, 12, 195, 179, 11, 11, 1, 12, 13, 13, 138, 16, 195, 161, 18, 20, 15, 11, 11, 1, 12, 13, 12, 137, 195, 169, 18, 20, 195, 169, 11, 5, 11, 13, 12, 66, 53, 32, 65, 37, 89, 47, 109, 52, 0, 25, 21, 2, 51, 48, 107, 108, 52, 65, 37, 50, 119, 12, 108, 55, 0, 44, 81, 32, 97, 108, 32, 22, 2, 51, 48, 107, 108, 52, 65, 37, 50, 119, 12, 108, 55, 0, 44, 81, 32, 99, 97, 108, 32, 25, 2, 51, 48, 104, 97, 114, 109, 105, 110, 99, 97, 100, 105, 107, 97, 105, 0, 44, 21, 29, 81, 32, 105, 32, 28, 2, 51, 48, 104, 97, 114, 109, 105, 110, 99, 97, 100, 105, 107, 195, 161, 105, 103, 0, 44, 21, 29, 81, 32, 105, 103, 32, 32, 2, 50, 56, 104, 117, 115, 122, 111, 110, 110, 121, 111, 108, 99, 97, 100, 105, 107, 195, 161, 105, 103, 0, 44, 21, 29, 81, 32, 105, 103, 32, 0, 20, 145, 3, 19, 1, 16, 1, 4, 195, 169, 11, 18, 5, 14, 4, 19, 26, 5, 18, 13, 12, 3, 95, 52, 88, 50, 109, 79, 84, 109, 50, 0, 0, 30, 70, 52, 83, 12, 21, 69, 0, 65, 109, 55, 12, 109, 47, 12, 23, 84, 39, 55, 50, 108, 0, 13, 81, 118, 111, 108, 110, 97, 32, 40, 11, 8, 21, 12, 12, 1, 4, 195, 169, 11, 15, 11, 107, 40, 55, 12, 108, 72, 113, 49, 39, 49, 23, 76, 40, 48, 114, 50, 0, 13, 81, 99, 115, 117, 112, 195, 161, 110, 32, 24, 70, 52, 83, 12, 21, 69, 0, 65, 109, 55, 12, 109, 47, 12, 23, 108, 88, 0, 13, 81, 97, 122, 32, 38, 6, 1, 12, 1, 16, 195, 186, 108, 55, 108, 48, 116, 10, 6, 15, 52, 109, 50, 119, 109, 52, 109, 50, 0, 13, 81, 114, 101, 110, 100, 115, 122, 101, 114, 101, 110, 32, 34, 9, 195, 169, 16, 195, 188, 12, 5, 20, 5, 113, 48, 111, 55, 109, 47, 109, 23, 109, 55, 118, 47, 12, 0, 13, 81, 101, 108, 197, 145, 116, 116, 32, 18, 143, 4, 9, 195, 161, 11, 20, 195, 188, 14, 20, 5, 20, 195, 169, 19, 13, 9, 134, 1, 12, 1, 16, 195, 186, 13, 12, 137, 195, 161, 12, 4, 15, 26, 1, 20, 1, 13, 6, 131, 12, 195, 179, 13, 9, 198, 52, 83, 12, 21, 69, 0, 13, 0, 19, 144, 8, 1, 12, 195, 161, 12, 2, 195, 188, 14, 20, 5, 20, 195, 169, 19, 13, 50, 8, 9, 19, 11, 15, 12, 195, 161, 11, 37, 91, 49, 39, 55, 114, 49, 23, 65, 111, 49, 110, 47, 12, 109, 47, 113, 91, 113, 47, 0, 13, 81, 109, 197, 177, 107, 195, 182, 100, 116, 101, 116, 195, 169, 115, 195, 169, 116, 32, 8, 197, 8, 195, 199, 61, 64, 13, 7, 132, 1, 4, 195, 179, 13, 7, 132, 8, 195, 161, 7, 13, 0, 11, 136, 13, 1, 7, 195, 161, 8, 15, 26, 13, 14, 139, 6, 15, 12, 25, 195, 179, 9, 18, 1, 20, 1, 13, 11, 136, 16, 15, 14, 20, 10, 195, 161, 14, 13, 13, 138, 11, 15, 18, 195, 186, 1, 11, 11, 1, 12, 13, 10, 135, 13, 195, 161, 19, 26, 14, 9, 13, 0, 70, 10, 19, 26, 5, 14, 22, 5, 4, 197, 145, 11, 89, 109, 50, 84, 109, 72, 118, 49, 23, 49, 110, 52, 113, 71, 109, 50, 23, 48, 52, 115, 71, 114, 55, 50, 114, 49, 23, 49, 37, 0, 13, 83, 107, 195, 182, 114, 195, 169, 98, 101, 110, 32, 112, 114, 195, 179, 98, 195, 161, 108, 110, 195, 161, 107, 32, 107, 105, 32, 11, 136, 11, 195, 188, 12, 4, 5, 14, 9, 13, 0, 14, 139, 11, 5, 18, 5, 19, 11, 5, 4, 197, 145, 11, 13, 7, 132, 18, 195, 161, 4, 13, 0, 53, 73, 80, 20, 148, 4, 195, 65, 44, 176, 76, 47, 108, 52, 47, 108, 55, 65, 108, 49, 12, 108, 55, 10, 6, 15, 49, 108, 48, 76, 39, 55, 108, 47, 71, 108, 50, 0, 13, 81, 107, 97, 112, 99, 115, 111, 108, 97, 116, 98, 97, 110, 32, 13, 138, 13, 5, 7, 195, 169, 18, 20, 5, 14, 9, 13, 11, 136, 13, 5, 14, 20, 195, 188, 14, 11, 13, 8, 197, 80, 21, 129, 77, 160, 20, 0, 27, 6, 18, 195, 182, 22, 9, 4, 52, 110, 84, 37, 72, 23, 108, 107, 39, 88, 0, 13, 81, 97, 104, 104, 111, 122, 32, 9, 134, 18, 195, 182, 22, 9, 4, 13, 26, 66, 48, 80, 55, 109, 10, 6, 15, 84, 39, 49, 91, 114, 47, 0, 13, 81, 118, 111, 107, 115, 195, 161, 116, 32, 19, 144, 7, 25, 195, 179, 7, 25, 21, 12, 195, 161, 19, 195, 161, 8, 15, 26, 13, 29, 66, 48, 80, 55, 109, 23, 83, 39, 81, 23, 83, 40, 47, 50, 37, 0, 13, 82, 102, 111, 103, 32, 102, 117, 116, 110, 105, 32, 6, 195, 5, 2, 129, 13, 22, 194, 48, 80, 13, 82, 107, 101, 108, 108, 32, 115, 122, 195, 182, 103, 101, 122, 110, 101, 109, 32, 17, 142, 16, 15, 12, 7, 195, 161, 18, 13, 5, 19, 20, 5, 18, 20, 13, 7, 132, 12, 195, 161, 2, 13, 5, 194, 56, 16, 72, 5, 194, 48, 80, 13, 5, 194, 36, 176, 13, 20, 2, 52, 48, 50, 109, 79, 84, 109, 50, 12, 109, 55, 0, 44, 81, 32, 101, 108, 32, 0, 22, 147, 16, 195, 169, 14, 26, 9, 14, 20, 195, 169, 26, 5, 20, 5, 11, 20, 197, 145, 12, 13, 11, 3, 95, 53, 88, 110, 47, 84, 109, 50, 0, 0, 10, 135, 15, 18, 19, 26, 195, 161, 7, 13, 30, 7, 15, 18, 19, 26, 195, 161, 7, 10, 39, 52, 89, 114, 81, 23, 83, 110, 55, 113, 0, 13, 81, 102, 195, 182, 108, 195, 169, 32, 8, 133, 20, 195, 169, 22, 5, 13, 7, 196, 32, 149, 20, 20, 13, 0, 8, 197, 76, 82, 148, 36, 176, 13, 11, 136, 8, 1, 19, 15, 14, 12, 195, 179, 13, 8, 197, 24, 241, 206, 36, 16, 13, 17, 142, 15, 16, 20, 9, 13, 1, 12, 9, 26, 195, 161, 12, 14, 9, 13, 0, 45, 67, 56, 20, 0, 50, 108, 48, 23, 108, 55, 108, 47, 12, 23, 47, 40, 72, 108, 47, 39, 91, 40, 55, 47, 0, 13, 82, 97, 108, 97, 116, 116, 32, 116, 117, 100, 97, 116, 111, 115, 117, 108, 116, 32, 50, 67, 56, 20, 0, 50, 108, 48, 23, 40, 47, 114, 50, 23, 89, 111, 55, 109, 47, 109, 47, 12, 23, 65, 109, 81, 0, 13, 83, 117, 116, 195, 161, 110, 32, 115, 122, 195, 188, 108, 101, 116, 101, 116, 116, 32, 109, 101, 103, 32, 19, 67, 56, 20, 0, 50, 108, 48, 10, 6, 15, 37, 91, 0, 13, 81, 105, 115, 32, 12, 137, 2, 9, 26, 1, 11, 15, 4, 195, 179, 13, 12, 137, 20, 195, 161, 18, 15, 12, 21, 14, 11, 13, 6, 195, 56, 20, 0, 13, 0, 12, 201, 37, 51, 69, 72, 85, 5, 44, 85, 0, 13, 22, 6, 20, 195, 161, 10, 1, 11, 47, 114, 57, 108, 49, 23, 37, 91, 0, 13, 81, 105, 115, 32, 9, 198, 28, 243, 132, 60, 195, 203, 13, 10, 199, 40, 21, 129, 76, 243, 14, 36, 13, 10, 199, 77, 160, 86, 5, 163, 212, 80, 13, 13, 138, 19, 195, 186, 10, 20, 8, 1, 20, 195, 179, 13, 13, 138, 7, 25, 1, 18, 1, 16, 15, 4, 195, 179, 13, 20, 67, 36, 146, 64, 107, 114, 52, 39, 65, 12, 108, 55, 0, 44, 42, 81, 97, 108, 32, 0, 25, 150, 20, 195, 182, 18, 22, 195, 169, 14, 25, 10, 1, 22, 1, 19, 12, 1, 20, 195, 161, 8, 15, 26, 13, 9, 198, 88, 243, 129, 48, 21, 0, 13, 11, 200, 44, 145, 137, 104, 85, 14, 36, 80, 13, 39, 11, 10, 195, 161, 18, 21, 12, 195, 169, 11, 15, 19, 57, 114, 52, 40, 55, 113, 49, 39, 91, 23, 109, 55, 109, 65, 109, 49, 0, 13, 81, 101, 108, 101, 109, 101, 107, 32, 54, 11, 13, 9, 12, 12, 9, 195, 161, 18, 4, 15, 19, 65, 37, 55, 37, 114, 52, 72, 39, 91, 23, 50, 113, 48, 89, 114, 65, 55, 114, 55, 114, 91, 0, 13, 81, 110, 195, 169, 112, 115, 122, 195, 161, 109, 108, 195, 161, 108, 195, 161, 115, 32, 23, 148, 195, 182, 14, 11, 15, 18, 13, 195, 161, 14, 25, 26, 1, 20, 15, 11, 14, 195, 161, 12, 13, 18, 6, 195, 161, 14, 20, 19, 26, 114, 109, 50, 47, 113, 109, 89, 0, 42, 42, 0, 12, 137, 195, 169, 18, 11, 5, 26, 5, 20, 20, 13, 9, 198, 28, 243, 132, 60, 195, 205, 13, 9, 134, 22, 195, 161, 12, 14, 1, 13, 9, 134, 13, 5, 12, 12, 195, 169, 13, 0, 7, 132, 12, 195, 161, 26, 13, 48, 70, 32, 149, 129, 80, 19, 0, 107, 37, 84, 108, 47, 108, 55, 23, 37, 55, 12, 109, 47, 113, 49, 109, 91, 113, 84, 109, 55, 0, 13, 81, 105, 108, 108, 101, 116, 195, 169, 107, 101, 115, 195, 169, 118, 101, 108, 32, 49, 15, 2, 197, 177, 14, 3, 19, 5, 12, 5, 11, 13, 195, 169, 14, 25, 71, 111, 50, 76, 109, 55, 109, 49, 65, 113, 67, 10, 6, 15, 79, 108, 50, 116, 57, 108, 0, 13, 81, 103, 121, 97, 110, 195, 186, 106, 97, 32, 16, 141, 8, 1, 19, 26, 14, 195, 161, 12, 8, 1, 20, 195, 179, 13, 13, 138, 5, 12, 197, 145, 6, 15, 18, 4, 21, 12, 13, 12, 137, 20, 5, 18, 13, 195, 169, 11, 5, 11, 13, 16, 141, 8, 1, 19, 26, 14, 195, 161, 12, 8, 1, 20, 195, 179, 13, 9, 198, 32, 149, 129, 80, 19, 0, 13, 19, 2, 53, 48, 110, 47, 84, 109, 50, 12, 109, 55, 0, 44, 81, 32, 101, 108, 32, 0, 34, 4, 9, 4, 197, 145, 37, 72, 118, 23, 84, 108, 55, 115, 89, 112, 50, 117, 0, 13, 81, 118, 97, 108, 195, 179, 115, 122, 195, 173, 110, 197, 177, 32, 30, 4, 9, 4, 197, 145, 37, 72, 118, 23, 84, 114, 52, 107, 108, 47, 115, 0, 13, 81, 118, 195, 161, 114, 104, 97, 116, 195, 179, 32, 13, 138, 16, 15, 14, 20, 10, 195, 161, 14, 1, 11, 13, 21, 4, 9, 4, 197, 145, 37, 72, 118, 23, 55, 109, 89, 0, 13, 81, 108, 101, 115, 122, 32, 15, 140, 11, 5, 18, 195, 188, 12, 5, 20, 5, 11, 2, 5, 13, 15, 140, 5, 12, 195, 169, 18, 195, 169, 19, 195, 169, 18, 5, 13, 15, 140, 7, 25, 197, 177, 10, 20, 197, 145, 14, 5, 22, 5, 13, 7, 132, 9, 4, 197, 145, 13, 12, 3, 95, 54, 88, 107, 108, 47, 84, 108, 50, 0, 0, 22, 4, 12, 195, 161, 20, 55, 114, 47, 23, 65, 108, 57, 72, 0, 13, 81, 109, 97, 106, 100, 32, 14, 139, 195, 182, 12, 20, 195, 182, 26, 14, 195, 169, 11, 13, 17, 142, 8, 1, 19, 26, 14, 195, 161, 12, 1, 20, 1, 11, 15, 18, 13, 7, 132, 12, 195, 161, 20, 13, 7, 132, 8, 195, 161, 20, 13, 0, 8, 197, 44, 21, 137, 13, 48, 13, 13, 138, 195, 188, 26, 12, 5, 20, 5, 11, 2, 5, 13, 16, 141, 18, 195, 161, 11, 195, 169, 18, 4, 5, 26, 5, 20, 20, 13, 0, 11, 136, 8, 1, 20, 195, 161, 19, 195, 186, 13, 13, 138, 10, 15, 7, 11, 195, 182, 18, 18, 5, 12, 13, 12, 137, 4, 195, 182, 14, 20, 5, 14, 5, 11, 13, 12, 137, 195, 182, 14, 195, 182, 11, 14, 5, 11, 13, 18, 143, 13, 5, 7, 9, 19, 13, 5, 18, 195, 169, 19, 195, 169, 18, 5, 13, 10, 135, 19, 26, 195, 161, 14, 14, 9, 13, 7, 132, 10, 195, 161, 18, 13, 0, 13, 138, 11, 195, 182, 22, 5, 20, 5, 12, 9, 11, 13, 26, 67, 76, 83, 64, 91, 109, 65, 23, 49, 109, 52, 111, 55, 47, 0, 13, 81, 107, 101, 114, 195, 188, 108, 116, 32, 12, 137, 3, 19, 9, 14, 195, 161, 12, 19, 26, 13, 19, 67, 76, 83, 64, 91, 109, 65, 23, 83, 39, 81, 0, 13, 81, 102, 111, 103, 32, 31, 67, 76, 83, 64, 91, 109, 65, 10, 6, 15, 71, 37, 89, 47, 39, 91, 108, 49, 0, 13, 81, 98, 105, 122, 116, 111, 115, 97, 107, 32, 19, 67, 76, 83, 64, 91, 109, 65, 10, 6, 15, 108, 88, 0, 13, 81, 97, 122, 32, 32, 67, 76, 83, 64, 91, 109, 65, 10, 6, 15, 65, 40, 47, 108, 80, 12, 114, 49, 0, 13, 81, 109, 117, 116, 97, 116, 106, 195, 161, 107, 32, 25, 67, 76, 83, 64, 91, 109, 65, 10, 6, 15, 65, 109, 52, 109, 49, 0, 13, 81, 109, 101, 114, 101, 107, 32, 42, 67, 76, 83, 64, 91, 109, 65, 10, 6, 15, 51, 37, 108, 72, 50, 108, 49, 23, 84, 37, 89, 12, 108, 0, 13, 82, 114, 105, 97, 100, 110, 97, 107, 32, 118, 105, 115, 115, 122, 97, 32, 40, 67, 76, 83, 64, 91, 109, 65, 23, 109, 65, 55, 112, 47, 109, 47, 12, 23, 108, 52, 52, 108, 0, 13, 82, 101, 109, 108, 195, 173, 116, 101, 116, 116, 32, 97, 114, 114, 97, 32, 54, 67, 76, 83, 64, 91, 109, 65, 23, 57, 109, 55, 109, 50, 47, 113, 49, 47, 109, 55, 109, 50, 23, 110, 89, 12, 109, 81, 0, 13, 82, 106, 101, 108, 101, 110, 116, 195, 169, 107, 116, 101, 108, 101, 110, 32, 195, 182, 115, 115, 122, 101, 103, 32, 23, 67, 76, 83, 64, 91, 109, 65, 23, 47, 40, 47, 12, 108, 0, 13, 81, 116, 117, 100, 116, 97, 32, 21, 67, 76, 83, 64, 91, 109, 65, 23, 49, 109, 55, 12, 0, 13, 81, 107, 101, 108, 108, 32, 26, 67, 76, 83, 64, 91, 109, 65, 23, 49, 37, 88, 114, 52, 47, 0, 13, 81, 107, 105, 122, 195, 161, 114, 116, 32, 26, 6, 8, 9, 2, 195, 161, 19, 107, 37, 71, 114, 91, 23, 84, 39, 55, 47, 0, 13, 81, 118, 111, 108, 116, 32, 41, 67, 76, 83, 64, 91, 109, 65, 23, 47, 40, 47, 12, 108, 49, 23, 65, 39, 50, 72, 108, 50, 37, 0, 13, 82, 116, 117, 100, 116, 97, 107, 32, 109, 111, 110, 100, 97, 110, 105, 32, 65, 67, 76, 83, 64, 91, 109, 65, 23, 83, 37, 79, 109, 55, 65, 109, 89, 47, 109, 47, 109, 47, 12, 23, 107, 108, 50, 81, 57, 109, 55, 88, 113, 91, 0, 13, 82, 102, 105, 103, 121, 101, 108, 109, 101, 122, 116, 101, 116, 101, 116, 116, 32, 104, 97, 110, 103, 106, 101, 108, 122, 195, 169, 115, 32, 66, 67, 76, 83, 64, 91, 109, 65, 23, 114, 55, 12, 23, 65, 115, 79, 12, 40, 49, 71, 108, 50, 23, 109, 55, 12, 109, 50, 118, 52, 37, 88, 50, 37, 0, 13, 83, 195, 161, 108, 108, 32, 109, 195, 179, 100, 106, 117, 107, 98, 97, 110, 32, 101, 108, 108, 101, 110, 197, 145, 114, 105, 122, 110, 105, 32, 19, 67, 76, 83, 64, 91, 109, 65, 65, 109, 79, 0, 13, 81, 109, 101, 103, 121, 32, 35, 67, 76, 83, 64, 91, 109, 65, 15, 108, 55, 49, 108, 55, 65, 108, 88, 50, 108, 49, 0, 13, 81, 97, 108, 107, 97, 108, 109, 97, 122, 110, 97, 107, 32, 24, 67, 76, 83, 64, 91, 109, 65, 15, 47, 110, 65, 37, 49, 0, 13, 81, 116, 195, 182, 109, 105, 107, 32, 15, 140, 195, 169, 16, 195, 188, 12, 5, 20, 5, 11, 2, 5, 13, 6, 195, 76, 83, 64, 13, 0, 7, 196, 32, 85, 5, 80, 13, 11, 136, 9, 14, 20, 195, 169, 26, 5, 20, 13, 32, 68, 32, 85, 5, 80, 107, 109, 47, 109, 47, 23, 107, 108, 89, 50, 114, 55, 47, 0, 13, 81, 104, 97, 115, 122, 110, 195, 161, 108, 116, 32, 11, 136, 11, 22, 195, 179, 20, 195, 161, 20, 13, 14, 139, 11, 5, 12, 12, 5, 14, 195, 169, 14, 5, 11, 13, 7, 196, 20, 197, 133, 80, 13, 7, 196, 20, 197, 133, 80, 13, 22, 147, 4, 9, 1, 7, 14, 15, 19, 26, 20, 9, 26, 195, 161, 12, 8, 1, 20, 195, 179, 13, 10, 134, 8, 1, 2, 195, 161, 18, 72, 8, 0, 17, 142, 16, 15, 12, 7, 195, 161, 18, 13, 5, 19, 20, 5, 18, 5, 13, 0, 22, 147, 22, 195, 169, 12, 5, 13, 195, 169, 14, 25, 5, 26, 195, 169, 19, 195, 169, 18, 5, 13, 53, 14, 11, 195, 182, 12, 20, 19, 195, 169, 7, 5, 11, 11, 5, 12, 49, 110, 55, 76, 113, 81, 109, 49, 12, 109, 55, 23, 83, 111, 81, 12, 23, 110, 89, 12, 109, 0, 13, 82, 102, 195, 188, 103, 103, 32, 195, 182, 115, 115, 122, 101, 32, 9, 198, 28, 243, 132, 60, 195, 196, 13, 20, 2, 54, 48, 107, 108, 47, 84, 108, 50, 12, 108, 55, 0, 44, 81, 32, 97, 108, 32, 0, 13, 138, 9, 12, 12, 5, 20, 195, 169, 11, 5, 19, 13, 15, 140, 3, 19, 195, 182, 11, 11, 5, 14, 195, 169, 19, 5, 13, 31, 67, 4, 131, 204, 108, 107, 39, 55, 23, 84, 108, 50, 23, 48, 113, 50, 88, 0, 13, 82, 118, 97, 110, 32, 112, 195, 169, 110, 122, 32, 11, 136, 13, 5, 7, 12, 5, 16, 197, 145, 13, 10, 135, 195, 173, 22, 5, 11, 5, 20, 13, 14, 67, 36, 195, 0, 37, 55, 55, 109, 47, 84, 109, 0, 25, 0, 11, 136, 16, 15, 14, 20, 10, 195, 161, 20, 13, 35, 7, 11, 9, 1, 4, 195, 161, 19, 49, 37, 108, 72, 114, 91, 23, 119, 113, 61, 57, 108, 37, 47, 0, 13, 81, 99, 195, 169, 108, 106, 97, 105, 116, 32, 12, 137, 11, 195, 182, 20, 8, 5, 20, 197, 145, 13, 26, 7, 11, 9, 1, 4, 195, 161, 19, 49, 37, 108, 72, 114, 91, 23, 55, 109, 89, 0, 81, 108, 101, 115, 122, 32, 12, 137, 3, 19, 9, 14, 195, 161, 12, 14, 9, 13, 12, 137, 195, 169, 18, 20, 8, 5, 20, 197, 145, 13, 16, 141, 6, 5, 12, 8, 1, 19, 26, 14, 195, 161, 12, 14, 9, 13, 10, 135, 11, 9, 1, 4, 195, 161, 19, 13, 12, 137, 11, 195, 182, 20, 8, 5, 20, 197, 145, 13, 12, 137, 11, 195, 169, 18, 8, 5, 20, 197, 145, 13, 7, 132, 4, 197, 145, 12, 13, 0, 44, 9, 20, 5, 18, 13, 195, 169, 11, 5, 20, 47, 109, 52, 65, 113, 49, 109, 47, 23, 84, 114, 91, 114, 52, 39, 55, 39, 49, 0, 13, 81, 118, 195, 161, 115, 195, 161, 114, 111, 108, 111, 107, 32, 37, 9, 22, 195, 161, 12, 20, 15, 26, 1, 20, 84, 114, 55, 47, 39, 88, 108, 47, 23, 109, 91, 109, 47, 113, 50, 0, 13, 81, 101, 115, 101, 116, 195, 169, 110, 32, 12, 201, 24, 241, 204, 4, 194, 207, 104, 243, 64, 13, 12, 137, 22, 195, 161, 12, 20, 15, 26, 1, 20, 13, 13, 138, 5, 12, 20, 195, 161, 18, 15, 12, 14, 9, 13, 13, 138, 5, 12, 195, 169, 18, 8, 5, 20, 197, 145, 13, 8, 133, 22, 195, 169, 18, 20, 13, 0, 14, 139, 5, 12, 197, 145, 195, 169, 12, 5, 20, 197, 177, 13, 12, 137, 14, 15, 18, 13, 195, 161, 12, 9, 19, 13, 17, 142, 5, 12, 197, 145, 195, 173, 18, 195, 161, 19, 15, 11, 1, 20, 13, 17, 142, 11, 195, 169, 18, 4, 197, 145, 195, 173, 22, 5, 11, 5, 20, 13, 12, 7, 95, 35, 45, 9, 11, 1, 9, 108, 37, 0, 0, 38, 10, 6, 5, 12, 195, 161, 12, 12, 195, 161, 19, 83, 109, 55, 114, 55, 12, 114, 91, 23, 89, 109, 52, 37, 50, 47, 0, 13, 81, 115, 122, 101, 114, 105, 110, 116, 32, 15, 140, 11, 9, 19, 26, 197, 177, 18, 8, 5, 20, 197, 145, 13, 10, 199, 80, 84, 141, 20, 195, 133, 44, 13, 10, 135, 13, 5, 12, 12, 197, 145, 12, 13, 0, 16, 141, 195, 182, 19, 26, 20, 195, 182, 14, 26, 195, 169, 19, 5, 13, 15, 140, 11, 195, 182, 26, 16, 15, 14, 20, 10, 195, 161, 20, 13, 28, 4, 195, 173, 18, 20, 112, 52, 47, 23, 49, 110, 67, 84, 109, 47, 0, 13, 81, 107, 195, 182, 110, 121, 118, 101, 116, 32, 40, 72, 60, 197, 129, 76, 21, 12, 4, 224, 39, 55, 84, 108, 91, 108, 47, 55, 108, 50, 23, 55, 109, 84, 113, 55, 52, 109, 0, 13, 81, 108, 101, 118, 195, 169, 108, 114, 101, 32, 16, 141, 5, 13, 12, 195, 169, 11, 5, 26, 20, 5, 20, 197, 145, 13, 11, 136, 2, 195, 169, 18, 195, 169, 18, 20, 13, 16, 141, 11, 195, 182, 19, 26, 195, 182, 14, 8, 5, 20, 197, 145, 13, 7, 132, 195, 173, 18, 20, 13, 7, 132, 2, 197, 145, 12, 72, 0, 47, 8, 20, 1, 18, 20, 10, 195, 161, 11, 47, 108, 52, 80, 114, 49, 23, 48, 52, 39, 71, 55, 113, 65, 114, 91, 50, 108, 49, 0, 13, 81, 112, 114, 111, 98, 108, 195, 169, 109, 195, 161, 115, 110, 97, 107, 32, 10, 135, 1, 26, 21, 20, 195, 161, 14, 13, 12, 137, 19, 26, 5, 18, 22, 20, 197, 145, 12, 13, 16, 141, 11, 195, 169, 18, 4, 197, 145, 195, 173, 22, 195, 169, 20, 13, 16, 141, 19, 26, 1, 2, 1, 4, 19, 195, 161, 7, 195, 161, 20, 13, 12, 137, 11, 1, 12, 11, 21, 12, 195, 161, 12, 13, 15, 140, 20, 195, 182, 18, 12, 5, 19, 26, 20, 195, 169, 19, 13, 9, 198, 16, 243, 7, 61, 163, 137, 13, 8, 133, 6, 195, 182, 12, 4, 13, 11, 136, 20, 1, 18, 20, 10, 195, 161, 11, 13, 0, 13, 138, 11, 5, 4, 22, 195, 169, 195, 169, 18, 20, 13, 13, 138, 22, 1, 12, 1, 13, 9, 195, 169, 18, 20, 13, 30, 6, 13, 9, 195, 169, 18, 20, 65, 37, 113, 52, 47, 15, 84, 108, 50, 15, 108, 88, 0, 13, 82, 118, 97, 110, 32, 97, 122, 32, 17, 142, 9, 14, 20, 5, 18, 6, 195, 169, 19, 26, 5, 11, 5, 20, 13, 24, 6, 13, 9, 195, 169, 18, 20, 65, 37, 113, 52, 47, 15, 50, 109, 65, 0, 13, 81, 110, 101, 109, 32, 13, 202, 57, 146, 76, 5, 66, 207, 104, 21, 15, 44, 13, 7, 132, 8, 195, 161, 26, 13, 9, 134, 5, 18, 18, 197, 145, 12, 13, 20, 2, 55, 48, 107, 109, 47, 84, 109, 50, 12, 109, 55, 0, 44, 81, 32, 101, 108, 32, 0, 30, 6, 22, 195, 161, 12, 9, 11, 84, 114, 55, 37, 49, 23, 108, 6, 15, 119, 113, 81, 0, 13, 82, 97, 32, 99, 195, 169, 103, 32, 13, 138, 11, 1, 16, 8, 1, 20, 10, 195, 161, 11, 13, 9, 134, 22, 195, 161, 12, 9, 11, 13, 8, 133, 22, 195, 169, 19, 26, 13, 9, 134, 22, 195, 169, 12, 9, 11, 13, 8, 133, 18, 195, 169, 19, 26, 13, 13, 3, 95, 56, 88, 67, 39, 55, 119, 84, 108, 50, 0, 0, 19, 144, 195, 161, 12, 12, 195, 161, 19, 16, 15, 14, 20, 10, 21, 11, 1, 20, 13, 12, 137, 13, 15, 14, 4, 1, 14, 195, 161, 13, 13, 11, 136, 20, 5, 18, 22, 18, 197, 145, 12, 13, 12, 137, 19, 26, 5, 18, 19, 26, 195, 161, 13, 13, 9, 198, 44, 86, 132, 21, 69, 0, 13, 15, 140, 12, 195, 169, 16, 195, 169, 19, 5, 11, 11, 5, 12, 13, 0, 19, 144, 3, 19, 1, 16, 1, 4, 195, 169, 11, 8, 21, 12, 12, 195, 161, 19, 13, 9, 134, 12, 195, 161, 14, 25, 1, 13, 11, 136, 195, 169, 18, 11, 5, 26, 9, 11, 13, 16, 141, 11, 195, 169, 16, 26, 195, 169, 19, 5, 11, 11, 5, 12, 13, 8, 133, 18, 195, 169, 19, 20, 13, 0, 17, 142, 195, 169, 12, 13, 195, 169, 14, 25, 195, 169, 20, 197, 145, 12, 13, 13, 138, 13, 15, 4, 5, 12, 12, 2, 197, 145, 12, 13, 10, 135, 19, 5, 7, 195, 173, 20, 9, 13, 10, 135, 11, 195, 161, 18, 20, 25, 1, 13, 13, 138, 8, 5, 12, 25, 195, 169, 18, 197, 145, 12, 13, 12, 136, 8, 195, 169, 20, 6, 197, 145, 14, 20, 22, 0, 16, 141, 20, 195, 182, 18, 22, 195, 169, 14, 25, 5, 11, 5, 14, 13, 16, 141, 12, 5, 10, 195, 161, 20, 19, 26, 195, 179, 8, 15, 26, 13, 16, 141, 19, 26, 15, 18, 195, 173, 20, 195, 161, 19, 195, 161, 14, 13, 14, 139, 16, 5, 20, 197, 145, 6, 9, 18, 197, 145, 12, 13, 14, 139, 8, 5, 12, 25, 26, 5, 20, 195, 169, 18, 20, 13, 14, 139, 18, 5, 14, 4, 10, 195, 169, 18, 197, 145, 12, 13, 0, 15, 140, 6, 5, 12, 195, 188, 12, 5, 20, 2, 197, 145, 12, 13, 14, 139, 11, 5, 26, 5, 12, 8, 5, 20, 197, 145, 11, 13, 18, 143, 8, 1, 19, 26, 14, 195, 161, 12, 8, 1, 20, 10, 195, 161, 11, 13, 13, 138, 1, 12, 11, 1, 20, 18, 195, 169, 19, 26, 13, 7, 196, 85, 64, 83, 80, 13, 0, 13, 138, 5, 18, 5, 4, 13, 195, 169, 14, 25, 5, 13, 8, 197, 44, 86, 132, 21, 64, 13, 15, 140, 19, 11, 195, 161, 12, 195, 161, 26, 20, 195, 161, 11, 13, 0, 30, 66, 44, 144, 49, 37, 23, 84, 39, 55, 47, 23, 112, 52, 84, 108, 0, 13, 82, 118, 111, 108, 116, 32, 195, 173, 114, 118, 97, 32, 39, 66, 44, 144, 49, 37, 23, 49, 109, 55, 12, 23, 47, 109, 52, 57, 109, 72, 50, 37, 109, 0, 13, 82, 107, 101, 108, 108, 32, 116, 101, 114, 106, 101, 100, 110, 105, 101, 32, 35, 66, 44, 144, 49, 37, 23, 49, 109, 55, 12, 23, 65, 39, 50, 72, 108, 50, 37, 0, 13, 82, 107, 101, 108, 108, 32, 109, 111, 110, 100, 97, 110, 105, 32, 32, 66, 44, 144, 49, 37, 10, 6, 15, 108, 88, 10, 6, 15, 110, 47, 55, 109, 47, 0, 13, 82, 97, 122, 32, 195, 182, 116, 108, 101, 116, 32, 29, 66, 44, 144, 10, 49, 37, 15, 83, 39, 81, 15, 112, 52, 50, 37, 0, 13, 82, 102, 111, 103, 32, 195, 173, 114, 110, 105, 32, 21, 66, 44, 144, 49, 37, 15, 47, 40, 79, 12, 108, 0, 13, 81, 116, 117, 100, 106, 97, 32, 25, 66, 44, 144, 49, 37, 55, 109, 107, 109, 47, 108, 88, 0, 13, 82, 108, 101, 104, 101, 116, 32, 97, 122, 32, 17, 142, 19, 26, 5, 13, 5, 20, 5, 19, 5, 11, 2, 197, 145, 12, 13, 17, 142, 18, 195, 169, 19, 26, 12, 5, 20, 5, 9, 18, 197, 145, 12, 13, 13, 138, 195, 169, 16, 195, 173, 20, 195, 169, 19, 20, 13, 5, 194, 44, 144, 13, 21, 2, 56, 48, 67, 39, 55, 119, 84, 108, 50, 12, 108, 55, 0, 44, 81, 32, 97, 108, 32, 0, 45, 16, 11, 195, 182, 12, 20, 19, 195, 169, 7, 22, 5, 20, 195, 169, 19, 9, 49, 110, 55, 76, 113, 81, 84, 109, 47, 113, 91, 37, 23, 91, 39, 52, 39, 50, 0, 13, 81, 115, 111, 114, 111, 110, 32, 37, 8, 195, 169, 18, 20, 5, 12, 13, 5, 113, 52, 47, 109, 55, 65, 109, 23, 83, 109, 55, 52, 115, 50, 37, 0, 13, 81, 102, 101, 108, 114, 195, 179, 110, 105, 32, 18, 143, 5, 12, 20, 197, 177, 14, 195, 169, 19, 195, 169, 18, 197, 145, 12, 13, 11, 136, 195, 169, 18, 20, 5, 12, 13, 5, 13, 15, 3, 95, 57, 88, 49, 37, 55, 109, 50, 119, 84, 109, 50, 0, 0, 7, 196, 56, 20, 10, 4, 13, 8, 133, 8, 195, 173, 18, 5, 13, 8, 133, 22, 195, 169, 22, 5, 13, 12, 5, 95, 35, 45, 18, 5, 113, 52, 109, 0, 21, 0, 11, 136, 12, 5, 19, 26, 195, 188, 14, 11, 72, 12, 137, 11, 5, 26, 5, 12, 195, 169, 19, 20, 13, 8, 197, 72, 18, 148, 4, 208, 13, 13, 138, 20, 195, 161, 18, 7, 25, 1, 12, 14, 9, 13, 16, 141, 195, 186, 10, 18, 1, 11, 5, 26, 4, 195, 169, 19, 20, 13, 8, 197, 8, 83, 142, 20, 208, 13, 0, 21, 146, 16, 15, 12, 7, 195, 161, 18, 13, 5, 19, 20, 5, 18, 5, 11, 11, 5, 12, 13, 0, 10, 199, 80, 84, 150, 21, 161, 84, 20, 13, 15, 7, 95, 35, 45, 20, 197, 145, 12, 113, 47, 118, 55, 0, 21, 0, 73, 21, 1, 11, 1, 4, 195, 161, 12, 25, 13, 5, 14, 20, 5, 19, 195, 173, 20, 195, 169, 19, 9, 108, 49, 108, 72, 114, 57, 65, 109, 50, 47, 109, 91, 112, 47, 113, 91, 37, 10, 6, 15, 109, 55, 84, 114, 52, 114, 91, 39, 49, 50, 108, 49, 0, 13, 81, 101, 108, 118, 195, 161, 114, 195, 161, 115, 111, 107, 110, 97, 107, 32, 7, 196, 44, 20, 19, 104, 13, 7, 132, 14, 195, 161, 12, 13, 12, 5, 95, 35, 45, 18, 1, 114, 52, 108, 0, 21, 0, 32, 8, 8, 1, 10, 20, 10, 195, 161, 11, 107, 108, 57, 80, 114, 49, 23, 84, 113, 81, 52, 109, 0, 13, 81, 118, 195, 169, 103, 114, 101, 32, 13, 138, 5, 12, 22, 195, 169, 7, 5, 26, 26, 5, 13, 23, 69, 80, 20, 148, 40, 16, 47, 108, 34, 80, 108, 10, 6, 15, 109, 55, 0, 13, 81, 101, 108, 32, 39, 69, 8, 243, 20, 60, 176, 71, 39, 55, 47, 39, 49, 10, 6, 15, 108, 57, 114, 50, 55, 108, 47, 108, 37, 0, 13, 81, 97, 106, 195, 161, 110, 108, 97, 116, 97, 105, 32, 40, 9, 22, 5, 22, 197, 145, 11, 11, 5, 12, 84, 109, 84, 118, 49, 12, 109, 55, 23, 49, 110, 47, 109, 50, 72, 118, 0, 13, 81, 107, 195, 182, 116, 101, 110, 100, 197, 145, 32, 31, 10, 20, 195, 161, 13, 1, 19, 26, 20, 10, 1, 47, 114, 65, 108, 89, 80, 108, 23, 108, 55, 114, 0, 13, 81, 97, 108, 195, 161, 32, 35, 10, 20, 195, 182, 2, 2, 14, 25, 9, 18, 5, 47, 110, 71, 67, 37, 52, 109, 23, 79, 109, 50, 81, 109, 0, 13, 81, 103, 121, 101, 110, 103, 101, 32, 15, 140, 20, 195, 182, 18, 5, 11, 19, 26, 195, 188, 14, 11, 13, 8, 197, 80, 20, 148, 40, 16, 13, 9, 198, 77, 161, 82, 21, 163, 137, 13, 8, 197, 48, 83, 142, 36, 80, 13, 0, 9, 198, 57, 147, 205, 84, 226, 192, 13, 13, 138, 22, 1, 12, 1, 11, 9, 20, 197, 145, 12, 13, 13, 138, 11, 195, 169, 18, 4, 5, 26, 5, 20, 20, 13, 12, 137, 19, 195, 186, 10, 20, 10, 195, 161, 11, 13, 23, 2, 57, 48, 49, 37, 55, 109, 50, 119, 84, 109, 50, 12, 109, 55, 0, 44, 81, 32, 101, 108, 32, 15, 8, 95, 35, 45, 195, 161, 8, 15, 26, 114, 107, 39, 88, 0, 13, 7, 95, 35, 45, 195, 169, 18, 5, 113, 52, 109, 0, 0, 15, 140, 8, 195, 169, 20, 22, 195, 169, 7, 195, 169, 18, 5, 13, 15, 140, 13, 195, 169, 18, 20, 195, 169, 11, 195, 169, 18, 5, 13, 9, 198, 24, 241, 193, 48, 213, 75, 13, 10, 135, 12, 5, 195, 161, 12, 12, 20, 13, 9, 198, 73, 81, 193, 48, 208, 83, 13, 14, 139, 22, 195, 169, 4, 5, 11, 5, 26, 5, 20, 20, 13, 13, 138, 19, 26, 195, 161, 18, 13, 1, 26, 9, 11, 13, 0, 11, 136, 16, 5, 18, 3, 18, 197, 145, 12, 22, 11, 136, 195, 169, 18, 4, 5, 11, 5, 12, 13, 35, 6, 19, 15, 18, 195, 161, 14, 91, 39, 52, 114, 50, 23, 49, 37, 72, 109, 52, 111, 55, 47, 0, 13, 81, 107, 105, 100, 101, 114, 195, 188, 108, 116, 32, 66, 7, 20, 21, 4, 20, 195, 161, 11, 47, 40, 47, 12, 114, 49, 23, 83, 39, 52, 72, 112, 47, 108, 50, 37, 23, 108, 23, 49, 113, 52, 72, 118, 112, 84, 109, 47, 0, 13, 83, 102, 111, 114, 100, 195, 173, 116, 97, 110, 105, 32, 97, 32, 107, 195, 169, 114, 100, 197, 145, 195, 173, 118, 101, 116, 32, 60, 6, 15, 18, 2, 195, 161, 14, 39, 52, 71, 114, 50, 23, 84, 37, 49, 47, 39, 52, 23, 65, 37, 50, 37, 89, 47, 109, 52, 109, 55, 50, 110, 49, 0, 13, 82, 118, 105, 107, 116, 111, 114, 32, 109, 105, 110, 105, 115, 122, 116, 101, 114, 101, 108, 110, 195, 182, 107, 32, 10, 135, 20, 21, 4, 20, 195, 161, 11, 13, 7, 196, 12, 149, 137, 48, 13, 9, 134, 19, 15, 18, 195, 161, 14, 13, 0, 13, 138, 195, 182, 18, 195, 182, 13, 195, 169, 18, 5, 13, 12, 137, 19, 5, 7, 195, 173, 20, 5, 20, 20, 13, 7, 132, 14, 197, 145, 19, 13, 9, 198, 44, 81, 22, 21, 163, 133, 13, 5, 130, 57, 53, 13, 15, 140, 8, 1, 19, 26, 14, 195, 161, 12, 10, 195, 161, 11, 13, 15, 140, 19, 26, 15, 12, 7, 195, 161, 12, 10, 195, 161, 11, 13, 12, 137, 4, 5, 18, 195, 173, 20, 5, 20, 20, 13, 8, 133, 197, 145, 11, 5, 20, 13, 8, 197, 32, 83, 25, 21, 48, 76, 0, 12, 137, 18, 5, 14, 4, 5, 12, 197, 145, 11, 13, 9, 134, 6, 15, 7, 195, 161, 20, 13, 10, 135, 8, 5, 22, 195, 173, 20, 9, 13, 13, 138, 19, 26, 195, 188, 12, 5, 20, 5, 20, 20, 13, 12, 137, 19, 26, 195, 161, 13, 12, 195, 161, 11, 13, 9, 134, 20, 5, 8, 195, 161, 20, 13, 7, 132, 26, 195, 161, 18, 13, 7, 132, 22, 195, 161, 18, 13, 12, 6, 95, 35, 45, 195, 161, 20, 114, 47, 0, 21, 0, 31, 8, 12, 195, 169, 16, 195, 169, 19, 5, 55, 113, 48, 113, 91, 109, 23, 109, 55, 12, 109, 50, 0, 13, 81, 101, 108, 108, 101, 110, 32, 46, 71, 77, 161, 82, 88, 86, 133, 80, 89, 109, 52, 84, 109, 88, 109, 47, 10, 6, 15, 65, 117, 49, 110, 47, 12, 109, 47, 12, 109, 0, 13, 81, 109, 197, 177, 107, 195, 182, 100, 116, 101, 116, 116, 101, 32, 37, 8, 2, 195, 169, 18, 12, 5, 20, 9, 71, 113, 52, 55, 109, 47, 37, 23, 72, 112, 57, 108, 49, 52, 108, 0, 13, 81, 100, 195, 173, 106, 97, 107, 114, 97, 32, 30, 71, 24, 244, 132, 84, 194, 1, 80, 83, 39, 52, 72, 40, 55, 107, 108, 47, 23, 109, 55, 118, 0, 13, 81, 101, 108, 197, 145, 32, 14, 139, 6, 18, 9, 19, 19, 195, 173, 20, 5, 20, 20, 13, 10, 199, 77, 161, 82, 88, 86, 133, 80, 13, 8, 133, 19, 26, 197, 145, 18, 13, 12, 137, 20, 1, 22, 1, 19, 26, 195, 161, 14, 20, 0, 12, 137, 11, 195, 169, 18, 4, 195, 169, 19, 5, 13, 11, 136, 195, 169, 12, 197, 145, 11, 5, 20, 13, 14, 139, 2, 195, 173, 18, 195, 161, 12, 20, 195, 161, 11, 13, 16, 141, 8, 195, 161, 12, 195, 179, 26, 1, 20, 15, 11, 2, 1, 13, 7, 132, 14, 197, 145, 20, 13, 0, 15, 140, 6, 9, 14, 15, 13, 195, 173, 20, 19, 195, 161, 11, 13, 16, 141, 13, 197, 177, 11, 195, 182, 4, 20, 5, 20, 5, 20, 20, 13, 0, 22, 67, 40, 240, 130, 57, 39, 71, 12, 23, 84, 39, 55, 47, 0, 13, 81, 118, 111, 108, 116, 32, 38, 67, 40, 240, 130, 57, 39, 71, 12, 10, 6, 15, 47, 114, 65, 39, 81, 108, 47, 114, 91, 108, 0, 13, 81, 116, 195, 161, 109, 111, 103, 97, 116, 195, 161, 115, 97, 32, 47, 70, 48, 82, 5, 80, 85, 20, 55, 109, 107, 109, 47, 109, 47, 12, 23, 84, 37, 90, 81, 114, 55, 50, 37, 23, 108, 89, 47, 0, 13, 82, 118, 105, 122, 115, 103, 195, 161, 108, 110, 105, 32, 97, 122, 116, 32, 36, 70, 48, 82, 5, 80, 85, 20, 55, 109, 107, 109, 47, 109, 47, 12, 23, 89, 114, 65, 114, 52, 108, 0, 13, 81, 115, 122, 195, 161, 109, 195, 161, 114, 97, 32, 17, 142, 20, 195, 182, 18, 20, 195, 169, 14, 8, 5, 20, 5, 20, 20, 13, 18, 143, 13, 5, 7, 5, 12, 197, 145, 26, 195, 169, 19, 195, 169, 18, 5, 13, 12, 137, 11, 195, 169, 18, 14, 195, 188, 14, 11, 13, 9, 198, 48, 82, 5, 80, 85, 20, 13, 6, 195, 40, 240, 130, 13, 0, 42, 11, 6, 21, 14, 11, 3, 9, 195, 179, 11, 1, 20, 83, 40, 50, 49, 119, 37, 115, 49, 108, 47, 23, 109, 55, 12, 114, 47, 115, 0, 13, 81, 101, 108, 108, 195, 161, 116, 195, 179, 32, 14, 139, 195, 161, 12, 12, 1, 16, 15, 20, 195, 161, 20, 13, 9, 134, 5, 13, 12, 197, 145, 19, 13, 14, 139, 6, 21, 14, 11, 3, 9, 195, 179, 11, 1, 20, 13, 14, 139, 10, 5, 12, 26, 195, 169, 19, 5, 11, 5, 20, 13, 10, 135, 195, 186, 20, 10, 195, 161, 20, 13, 10, 135, 195, 186, 20, 10, 195, 161, 20, 13, 14, 139, 195, 188, 26, 5, 14, 5, 20, 5, 11, 5, 20, 13, 17, 142, 11, 9, 6, 15, 7, 195, 161, 19, 15, 12, 20, 195, 161, 11, 13, 8, 133, 6, 195, 182, 14, 14, 13, 0, 16, 141, 20, 195, 182, 14, 11, 18, 5, 20, 5, 8, 5, 20, 9, 13, 14, 139, 1, 12, 11, 1, 12, 13, 1, 26, 195, 161, 19, 13, 12, 137, 11, 195, 169, 16, 26, 195, 169, 19, 5, 13, 12, 137, 6, 9, 26, 5, 20, 195, 169, 19, 5, 13, 11, 136, 11, 195, 179, 4, 15, 11, 1, 20, 13, 40, 7, 6, 5, 12, 8, 197, 145, 19, 83, 109, 55, 107, 118, 91, 23, 37, 72, 118, 89, 108, 49, 71, 108, 50, 0, 13, 81, 105, 100, 197, 145, 115, 122, 97, 107, 98, 97, 110, 32, 45, 7, 6, 5, 12, 8, 197, 145, 19, 83, 109, 55, 107, 118, 91, 23, 47, 109, 52, 111, 55, 109, 47, 109, 49, 23, 37, 91, 0, 13, 82, 116, 101, 114, 195, 188, 108, 101, 116, 101, 107, 32, 105, 115, 32, 12, 137, 22, 5, 26, 5, 20, 195, 169, 19, 5, 13, 15, 140, 20, 5, 18, 195, 188, 12, 5, 20, 5, 11, 5, 20, 13, 15, 140, 13, 197, 177, 22, 5, 12, 5, 20, 5, 11, 5, 20, 13, 10, 135, 6, 5, 12, 8, 197, 145, 19, 13, 12, 137, 11, 195, 169, 16, 26, 195, 169, 19, 5, 13, 0, 53, 15, 20, 5, 12, 5, 16, 195, 188, 12, 195, 169, 19, 5, 11, 5, 14, 47, 109, 55, 109, 48, 111, 55, 113, 91, 109, 49, 109, 50, 10, 6, 15, 72, 39, 55, 81, 39, 88, 37, 49, 0, 13, 81, 100, 111, 108, 103, 111, 122, 105, 107, 32, 48, 13, 195, 186, 10, 195, 173, 20, 195, 161, 19, 15, 11, 1, 20, 116, 57, 112, 47, 114, 91, 39, 49, 108, 47, 15, 71, 109, 84, 109, 88, 109, 47, 50, 37, 0, 13, 81, 98, 101, 118, 101, 122, 101, 116, 110, 105, 32, 12, 137, 4, 9, 195, 161, 11, 15, 11, 1, 20, 13, 16, 141, 8, 1, 19, 26, 14, 195, 161, 12, 195, 179, 11, 1, 20, 13, 11, 136, 9, 19, 11, 15, 12, 195, 161, 19, 13, 7, 196, 48, 20, 15, 44, 13, 15, 140, 19, 5, 7, 195, 173, 20, 5, 14, 195, 188, 14, 11, 13, 12, 137, 6, 195, 161, 10, 12, 10, 195, 161, 20, 13, 12, 137, 16, 15, 19, 26, 20, 10, 195, 161, 20, 13, 8, 133, 19, 26, 195, 169, 11, 13, 7, 196, 57, 145, 82, 80, 13, 11, 6, 95, 35, 45, 195, 169, 14, 113, 50, 0, 0, 14, 139, 7, 1, 18, 1, 14, 20, 195, 161, 12, 14, 9, 13, 22, 147, 11, 5, 26, 4, 5, 13, 195, 169, 14, 25, 5, 26, 195, 169, 19, 195, 169, 18, 5, 13, 22, 5, 20, 197, 177, 14, 20, 47, 117, 50, 47, 10, 6, 15, 49, 37, 0, 13, 81, 107, 105, 32, 20, 5, 20, 197, 177, 14, 20, 47, 117, 50, 47, 23, 109, 55, 0, 13, 81, 101, 108, 32, 14, 139, 13, 197, 177, 11, 195, 182, 4, 195, 169, 19, 5, 13, 8, 197, 32, 83, 25, 20, 64, 13, 8, 133, 20, 197, 177, 14, 20, 13, 12, 137, 10, 21, 20, 20, 1, 20, 195, 161, 19, 13, 12, 137, 195, 186, 10, 195, 173, 20, 195, 161, 19, 13, 8, 133, 20, 195, 169, 18, 20, 13, 8, 133, 8, 195, 173, 18, 20, 13, 8, 133, 20, 197, 177, 14, 20, 13, 0, 18, 143, 13, 195, 179, 4, 15, 19, 195, 173, 20, 195, 161, 19, 195, 161, 20, 13, 7, 132, 4, 195, 173, 10, 13, 14, 139, 3, 19, 15, 16, 15, 18, 20, 10, 195, 161, 20, 13, 15, 140, 6, 18, 9, 19, 19, 195, 173, 20, 195, 169, 19, 5, 13, 49, 11, 11, 9, 1, 4, 195, 161, 19, 15, 11, 1, 20, 49, 37, 108, 72, 114, 91, 39, 49, 108, 47, 23, 48, 52, 109, 83, 109, 52, 114, 61, 57, 108, 0, 13, 81, 112, 114, 101, 102, 101, 114, 195, 161, 108, 106, 97, 32, 18, 143, 6, 5, 10, 12, 5, 19, 26, 20, 195, 169, 19, 5, 11, 5, 20, 13, 14, 139, 12, 195, 169, 16, 195, 169, 19, 5, 11, 5, 20, 13, 18, 143, 6, 5, 12, 16, 21, 8, 195, 173, 20, 195, 161, 19, 195, 161, 20, 13, 19, 144, 11, 195, 182, 12, 20, 19, 195, 169, 7, 22, 5, 20, 195, 169, 19, 5, 13, 13, 138, 21, 20, 1, 19, 195, 173, 20, 195, 161, 19, 13, 9, 134, 16, 195, 169, 14, 26, 20, 13, 8, 133, 20, 197, 145, 12, 5, 13, 0, 15, 140, 11, 195, 169, 18, 4, 195, 169, 19, 5, 11, 5, 20, 13, 15, 140, 2, 5, 6, 15, 12, 25, 195, 161, 19, 195, 161, 20, 13, 52, 6, 11, 195, 169, 18, 20, 5, 49, 113, 52, 47, 109, 10, 6, 15, 83, 109, 55, 23, 65, 116, 55, 47, 10, 6, 15, 107, 113, 47, 109, 50, 0, 13, 83, 102, 101, 108, 32, 109, 195, 186, 108, 116, 32, 104, 195, 169, 116, 101, 110, 32, 19, 144, 13, 195, 179, 4, 15, 19, 195, 173, 20, 195, 161, 19, 15, 11, 1, 20, 13, 9, 134, 11, 195, 169, 18, 20, 5, 13, 13, 4, 95, 15, 7, 15, 107, 39, 52, 81, 39, 49, 0, 0, 34, 70, 80, 83, 10, 21, 49, 78, 47, 109, 55, 57, 109, 91, 109, 50, 23, 107, 111, 57, 113, 50, 0, 13, 81, 104, 195, 188, 108, 121, 195, 169, 110, 32, 16, 141, 11, 195, 169, 19, 26, 195, 188, 12, 195, 169, 11, 5, 20, 13, 10, 135, 2, 5, 12, 197, 145, 12, 5, 13, 11, 200, 5, 52, 218, 60, 227, 153, 4, 192, 13, 20, 145, 5, 12, 197, 145, 195, 161, 12, 12, 195, 173, 20, 195, 161, 19, 195, 161, 20, 13, 7, 196, 36, 65, 74, 20, 13, 16, 141, 19, 26, 195, 161, 14, 4, 195, 169, 11, 21, 11, 1, 20, 13, 15, 140, 2, 5, 195, 161, 12, 12, 195, 173, 20, 195, 161, 19, 13, 16, 141, 11, 195, 169, 19, 26, 195, 188, 12, 195, 169, 11, 5, 20, 13, 20, 145, 19, 26, 15, 12, 7, 195, 161, 12, 20, 1, 20, 195, 161, 19, 195, 161, 20, 13, 0, 17, 142, 9, 4, 197, 145, 10, 195, 161, 18, 195, 161, 19, 195, 161, 20, 13, 21, 146, 19, 26, 15, 12, 7, 195, 161, 12, 20, 1, 20, 195, 161, 19, 15, 11, 1, 20, 13, 44, 18, 19, 26, 15, 12, 7, 195, 161, 12, 20, 1, 20, 195, 161, 19, 15, 11, 1, 20, 89, 39, 55, 81, 114, 55, 47, 108, 47, 114, 91, 39, 49, 108, 47, 23, 37, 91, 0, 13, 81, 105, 115, 32, 11, 136, 195, 173, 7, 195, 169, 18, 20, 5, 13, 21, 146, 3, 19, 1, 20, 12, 1, 11, 15, 26, 20, 1, 20, 195, 161, 19, 195, 161, 20, 13, 11, 136, 195, 173, 7, 195, 169, 18, 20, 5, 13, 8, 133, 19, 26, 195, 169, 12, 13, 0, 18, 143, 22, 195, 161, 12, 1, 19, 26, 20, 195, 161, 19, 15, 11, 1, 20, 13, 22, 147, 13, 5, 7, 22, 195, 161, 12, 20, 15, 26, 20, 1, 20, 195, 161, 19, 195, 161, 20, 13, 18, 143, 11, 195, 182, 26, 22, 195, 169, 12, 5, 13, 195, 169, 14, 25, 20, 13, 9, 198, 52, 243, 137, 80, 244, 128, 13, 22, 147, 22, 9, 19, 19, 26, 1, 195, 161, 12, 12, 195, 173, 20, 195, 161, 19, 195, 161, 20, 13, 0, 10, 199, 77, 163, 198, 81, 97, 82, 80, 13, 10, 199, 28, 243, 132, 60, 197, 21, 44, 13, 10, 199, 32, 19, 135, 77, 161, 82, 80, 13, 11, 136, 22, 195, 169, 12, 9, 20, 5, 11, 13, 6, 195, 88, 243, 148, 13, 6, 195, 88, 243, 148, 13, 0, 19, 68, 57, 145, 76, 88, 67, 109, 55, 84, 23, 37, 91, 0, 13, 81, 105, 115, 32, 11, 200, 65, 35, 199, 72, 19, 77, 4, 192, 13, 12, 137, 8, 9, 20, 20, 195, 169, 20, 5, 11, 13, 7, 132, 20, 195, 186, 12, 13, 0, 8, 197, 32, 83, 25, 21, 64, 13, 8, 197, 77, 161, 77, 21, 64, 13, 9, 198, 4, 192, 84, 80, 144, 75, 13, 8, 197, 40, 21, 149, 49, 64, 13, 0, 19, 144, 22, 1, 12, 195, 179, 19, 26, 195, 173, 14, 197, 177, 20, 12, 5, 14, 13, 31, 7, 13, 9, 12, 12, 9, 195, 179, 65, 37, 55, 37, 115, 23, 83, 39, 52, 37, 50, 47, 0, 13, 81, 102, 111, 114, 105, 110, 116, 32, 12, 201, 36, 225, 193, 80, 192, 78, 84, 176, 129, 13, 0, 27, 152, 7, 25, 195, 179, 7, 25, 19, 26, 5, 18, 20, 195, 161, 13, 15, 7, 1, 20, 195, 161, 19, 195, 161, 20, 13, 9, 198, 20, 195, 79, 56, 69, 1, 13, 7, 195, 52, 147, 148, 102, 13, 7, 195, 52, 147, 148, 13, 23, 0, 10, 135, 13, 5, 7, 195, 169, 18, 9, 13, 0, 11, 136, 12, 195, 169, 20, 5, 26, 14, 9, 13, 13, 138, 19, 26, 5, 13, 20, 1, 14, 195, 186, 11, 13, 6, 131, 195, 161, 14, 72, 18, 69, 88, 68, 218, 77, 160, 84, 113, 72, 113, 109, 89, 109, 89, 0, 42, 42, 0, 20, 66, 56, 80, 50, 109, 23, 50, 113, 88, 88, 0, 13, 81, 110, 195, 169, 122, 122, 32, 24, 66, 56, 80, 50, 109, 10, 6, 15, 47, 109, 50, 12, 113, 0, 13, 81, 116, 101, 110, 110, 195, 169, 32, 14, 139, 11, 5, 18, 5, 19, 197, 145, 10, 195, 188, 11, 13, 9, 198, 85, 64, 90, 61, 69, 0, 13, 9, 198, 32, 83, 25, 21, 69, 0, 13, 5, 194, 56, 80, 13, 0, 22, 67, 52, 18, 132, 65, 108, 57, 72, 10, 6, 15, 65, 109, 81, 0, 13, 81, 109, 101, 103, 32, 32, 67, 52, 18, 132, 65, 108, 57, 72, 10, 6, 15, 65, 117, 49, 110, 72, 50, 37, 0, 13, 81, 109, 197, 177, 107, 195, 182, 100, 110, 105, 32, 34, 67, 52, 18, 132, 65, 108, 57, 72, 10, 6, 15, 55, 109, 107, 109, 47, 118, 84, 113, 0, 13, 81, 108, 101, 104, 101, 116, 197, 145, 118, 195, 169, 32, 40, 67, 52, 18, 132, 65, 108, 57, 72, 10, 6, 15, 65, 109, 81, 47, 109, 49, 37, 50, 47, 109, 50, 37, 0, 13, 81, 109, 101, 103, 116, 101, 107, 105, 110, 116, 101, 110, 105, 32, 33, 67, 52, 18, 132, 65, 108, 57, 72, 10, 6, 15, 107, 108, 55, 81, 108, 47, 50, 37, 0, 13, 81, 104, 97, 108, 108, 103, 97, 116, 110, 105, 32, 26, 67, 52, 18, 132, 65, 108, 57, 72, 10, 6, 15, 52, 108, 57, 47, 108, 0, 13, 81, 114, 97, 106, 116, 97, 32, 15, 140, 195, 169, 18, 4, 5, 11, 5, 19, 19, 195, 169, 7, 13, 6, 195, 52, 18, 132, 13, 0, 10, 135, 195, 161, 18, 21, 12, 14, 9, 13, 9, 134, 8, 195, 169, 20, 5, 14, 13, 7, 196, 44, 20, 14, 36, 13, 7, 196, 57, 145, 76, 80, 13, 6, 131, 195, 161, 13, 13, 15, 4, 95, 50, 17, 24, 65, 114, 91, 39, 72, 37, 49, 108, 0, 0, 40, 69, 20, 195, 5, 56, 144, 109, 55, 12, 109, 50, 37, 23, 83, 109, 55, 12, 113, 48, 113, 91, 52, 109, 0, 13, 81, 102, 101, 108, 108, 195, 169, 112, 195, 169, 115, 114, 101, 32, 8, 197, 88, 19, 1, 44, 144, 13, 10, 135, 6, 195, 169, 18, 6, 9, 14, 13, 8, 197, 28, 243, 66, 72, 16, 13, 0, 35, 5, 195, 169, 22, 18, 5, 113, 84, 52, 109, 10, 6, 15, 49, 113, 89, 111, 55, 50, 109, 0, 13, 81, 107, 195, 169, 115, 122, 195, 188, 108, 110, 101, 32, 8, 133, 195, 169, 22, 18, 5, 13, 11, 136, 3, 19, 195, 182, 11, 11, 5, 14, 13, 10, 135, 20, 21, 4, 10, 195, 161, 11, 13, 10, 135, 20, 21, 4, 10, 195, 161, 11, 13, 6, 131, 197, 145, 11, 13, 7, 131, 197, 145, 11, 13, 8, 0, 14, 139, 20, 195, 188, 14, 20, 5, 20, 195, 169, 19, 20, 13, 12, 201, 72, 83, 132, 20, 194, 197, 104, 83, 0, 13, 14, 139, 6, 5, 12, 12, 195, 169, 16, 195, 169, 19, 20, 13, 0, 10, 135, 195, 169, 12, 5, 20, 2, 5, 13, 9, 134, 10, 15, 7, 195, 161, 14, 13, 12, 137, 19, 26, 195, 161, 14, 10, 195, 161, 11, 13, 8, 133, 20, 195, 161, 14, 3, 13, 7, 132, 18, 195, 186, 4, 13, 7, 196, 77, 161, 80, 80, 20, 0, 20, 145, 8, 1, 12, 195, 161, 12, 2, 195, 188, 14, 20, 5, 20, 195, 169, 19, 20, 13, 13, 138, 7, 25, 195, 161, 18, 20, 10, 195, 161, 11, 13, 12, 201, 29, 145, 82, 52, 82, 197, 44, 85, 0, 13, 24, 149, 2, 197, 177, 14, 3, 19, 5, 12, 5, 11, 13, 195, 169, 14, 25, 5, 11, 195, 169, 18, 20, 13, 0, 15, 66, 49, 144, 109, 55, 55, 37, 48, 89, 37, 55, 39, 50, 0, 21, 146, 5, 7, 25, 195, 188, 20, 20, 13, 197, 177, 11, 195, 182, 4, 195, 169, 19, 20, 13, 11, 136, 12, 5, 12, 11, 195, 169, 19, 26, 13, 9, 198, 4, 64, 84, 60, 176, 84, 13, 9, 198, 88, 19, 1, 44, 149, 0, 13, 7, 132, 2, 197, 145, 18, 13, 5, 194, 61, 48, 72, 8, 132, 2, 195, 161, 18, 72, 8, 0, 34, 8, 12, 195, 161, 20, 19, 26, 9, 11, 55, 114, 119, 12, 37, 49, 10, 6, 15, 47, 109, 107, 114, 47, 0, 13, 81, 116, 101, 104, 195, 161, 116, 32, 31, 3, 195, 161, 20, 114, 47, 23, 108, 6, 23, 72, 52, 114, 84, 114, 47, 0, 13, 82, 97, 32, 100, 114, 195, 161, 118, 195, 161, 116, 32, 10, 135, 11, 195, 182, 26, 197, 177, 12, 13, 11, 136, 12, 195, 161, 20, 19, 26, 9, 11, 13, 6, 131, 197, 145, 20, 13, 6, 131, 195, 161, 20, 13, 15, 7, 95, 35, 45, 18, 197, 145, 12, 113, 52, 118, 55, 0, 21, 0, 12, 137, 19, 26, 195, 161, 14, 20, 195, 161, 11, 13, 24, 68, 36, 225, 21, 48, 37, 50, 72, 40, 55, 23, 65, 108, 57, 72, 0, 13, 81, 109, 97, 106, 100, 32, 11, 200, 32, 83, 25, 21, 69, 5, 76, 80, 13, 38, 68, 36, 225, 21, 48, 37, 50, 72, 40, 55, 23, 108, 6, 15, 83, 109, 55, 107, 118, 88, 109, 47, 0, 13, 82, 97, 32, 102, 101, 108, 104, 197, 145, 122, 101, 116, 32, 16, 141, 2, 9, 26, 20, 15, 19, 195, 173, 20, 10, 195, 161, 11, 13, 7, 196, 24, 150, 133, 80, 13, 12, 137, 10, 195, 161, 18, 1, 4, 195, 169, 11, 13, 11, 136, 8, 5, 12, 25, 18, 197, 145, 12, 13, 13, 4, 95, 48, 77, 52, 71, 37, 55, 55, 37, 115, 0, 0, 34, 9, 4, 195, 182, 14, 20, 195, 182, 20, 20, 72, 110, 50, 47, 110, 47, 12, 23, 108, 52, 52, 115, 55, 0, 13, 81, 97, 114, 114, 195, 179, 108, 32, 14, 139, 2, 5, 22, 195, 169, 20, 5, 12, 8, 5, 26, 13, 12, 137, 195, 169, 22, 5, 11, 2, 197, 145, 12, 13, 15, 140, 13, 21, 14, 11, 1, 20, 195, 161, 18, 19, 1, 9, 13, 12, 201, 40, 21, 129, 76, 192, 84, 60, 176, 84, 13, 12, 137, 195, 169, 22, 5, 11, 2, 197, 145, 12, 13, 6, 131, 197, 145, 18, 13, 12, 137, 4, 195, 182, 14, 20, 195, 182, 20, 20, 13, 0, 14, 139, 2, 195, 188, 14, 20, 5, 19, 19, 195, 169, 11, 13, 13, 138, 12, 5, 11, 195, 182, 20, 195, 182, 20, 20, 13, 10, 135, 6, 15, 18, 18, 195, 161, 19, 13, 13, 4, 95, 48, 77, 50, 65, 37, 55, 55, 37, 115, 0, 0, 14, 139, 22, 195, 169, 12, 5, 11, 5, 4, 5, 20, 20, 13, 10, 135, 6, 195, 169, 18, 6, 9, 20, 13, 10, 135, 8, 9, 195, 161, 14, 25, 20, 13, 6, 195, 88, 243, 128, 13, 6, 195, 52, 147, 132, 13, 15, 4, 95, 48, 77, 51, 65, 37, 55, 55, 37, 114, 52, 72, 0, 0, 9, 134, 13, 195, 169, 20, 5, 18, 13, 11, 136, 15, 12, 4, 1, 12, 195, 161, 20, 13, 12, 137, 20, 5, 8, 5, 20, 10, 195, 188, 11, 13, 11, 136, 11, 5, 18, 195, 188, 12, 5, 20, 13, 11, 136, 7, 195, 169, 16, 5, 11, 5, 20, 13, 9, 198, 24, 241, 193, 48, 208, 90, 13, 0, 45, 13, 5, 12, 12, 5, 14, 197, 145, 18, 26, 195, 182, 20, 20, 109, 55, 12, 109, 50, 110, 52, 88, 110, 47, 12, 23, 109, 79, 91, 113, 81, 109, 0, 13, 81, 101, 103, 121, 115, 195, 169, 103, 101, 32, 12, 137, 9, 4, 5, 7, 5, 19, 195, 173, 20, 13, 9, 134, 11, 195, 169, 16, 5, 19, 13, 11, 4, 95, 48, 77, 49, 109, 88, 109, 52, 0, 0, 9, 134, 10, 15, 7, 195, 161, 20, 13, 9, 134, 10, 195, 182, 8, 5, 20, 13, 61, 16, 16, 18, 15, 2, 12, 195, 169, 13, 195, 161, 10, 195, 161, 8, 15, 26, 48, 52, 39, 71, 55, 113, 65, 114, 57, 114, 107, 39, 88, 23, 107, 108, 91, 39, 50, 55, 112, 47, 39, 47, 12, 108, 0, 13, 81, 104, 97, 115, 111, 110, 108, 195, 173, 116, 111, 116, 116, 97, 32, 9, 134, 195, 161, 18, 195, 161, 20, 13, 10, 135, 20, 1, 18, 20, 195, 161, 19, 13, 13, 138, 195, 173, 7, 195, 169, 18, 5, 20, 5, 20, 13, 9, 134, 12, 195, 161, 14, 25, 20, 13, 13, 4, 95, 2, 18, 22, 83, 113, 55, 49, 110, 52, 0, 0, 8, 67, 17, 164, 192, 75, 113, 0, 14, 139, 10, 15, 7, 19, 195, 169, 18, 20, 197, 145, 20, 13, 18, 143, 20, 5, 12, 5, 16, 8, 5, 12, 25, 195, 169, 18, 197, 145, 12, 13, 22, 147, 19, 5, 7, 195, 169, 4, 5, 19, 26, 11, 195, 182, 26, 195, 182, 11, 11, 5, 12, 13, 18, 143, 10, 5, 12, 5, 14, 12, 195, 169, 20, 195, 169, 18, 197, 145, 12, 13, 6, 195, 8, 244, 128, 13, 0, 16, 141, 195, 169, 18, 20, 5, 12, 13, 5, 26, 26, 195, 188, 11, 13, 43, 11, 5, 7, 25, 5, 19, 195, 188, 12, 5, 20, 9, 109, 79, 12, 109, 91, 111, 55, 109, 47, 37, 23, 84, 109, 88, 109, 47, 118, 49, 0, 13, 81, 118, 101, 122, 101, 116, 197, 145, 107, 32, 9, 198, 48, 82, 5, 77, 49, 78, 13, 9, 198, 72, 244, 211, 104, 16, 130, 13, 15, 140, 22, 195, 161, 12, 20, 1, 11, 15, 26, 8, 1, 20, 13, 0, 12, 201, 29, 145, 82, 52, 82, 197, 36, 177, 84, 13, 16, 141, 9, 19, 13, 5, 18, 197, 145, 19, 5, 9, 11, 5, 20, 13, 10, 135, 19, 26, 195, 169, 16, 5, 14, 13, 0, 24, 70, 4, 192, 75, 84, 197, 0, 108, 55, 108, 49, 40, 55, 47, 23, 49, 37, 0, 13, 81, 107, 105, 32, 14, 139, 22, 195, 161, 12, 1, 19, 26, 20, 195, 161, 19, 13, 11, 136, 8, 195, 161, 2, 15, 18, 195, 186, 13, 13, 138, 9, 19, 11, 15, 12, 195, 161, 11, 1, 20, 13, 9, 134, 19, 26, 195, 161, 14, 20, 13, 11, 136, 19, 26, 195, 169, 12, 195, 169, 14, 13, 14, 139, 5, 7, 25, 5, 14, 18, 21, 8, 195, 161, 19, 22, 0, 22, 147, 20, 5, 22, 195, 169, 11, 5, 14, 25, 19, 195, 169, 7, 195, 169, 18, 197, 145, 12, 13, 14, 139, 195, 161, 12, 12, 15, 13, 195, 161, 14, 25, 20, 13, 18, 143, 2, 9, 12, 12, 5, 14, 20, 25, 197, 177, 26, 5, 20, 5, 20, 13, 14, 139, 11, 5, 4, 195, 169, 12, 25, 5, 11, 5, 20, 13, 10, 135, 22, 195, 161, 12, 12, 1, 12, 13, 7, 132, 8, 195, 186, 19, 13, 8, 133, 19, 26, 195, 173, 14, 13, 0, 7, 196, 24, 241, 207, 44, 76, 6, 195, 52, 148, 133, 13, 12, 137, 13, 15, 14, 4, 1, 14, 195, 169, 11, 13, 7, 196, 77, 161, 82, 80, 13, 0, 47, 13, 16, 18, 15, 2, 12, 195, 169, 13, 195, 161, 11, 1, 20, 48, 52, 39, 71, 55, 113, 65, 114, 49, 108, 47, 23, 49, 108, 48, 108, 52, 81, 108, 47, 0, 13, 81, 107, 97, 112, 97, 114, 103, 97, 116, 32, 26, 69, 4, 192, 75, 84, 192, 108, 55, 108, 49, 40, 55, 23, 65, 108, 57, 72, 0, 13, 81, 109, 97, 106, 100, 32, 16, 141, 16, 18, 15, 2, 12, 195, 169, 13, 195, 161, 11, 1, 20, 13, 16, 141, 8, 1, 14, 7, 13, 9, 14, 20, 195, 161, 11, 1, 20, 13, 16, 141, 195, 161, 12, 12, 195, 173, 20, 195, 161, 19, 195, 161, 20, 13, 8, 197, 4, 192, 75, 84, 192, 13, 16, 141, 6, 15, 18, 4, 195, 173, 20, 195, 161, 19, 195, 161, 20, 13, 12, 137, 6, 5, 12, 20, 195, 169, 20, 5, 12, 13, 0, 16, 141, 12, 195, 182, 22, 195, 182, 12, 4, 195, 182, 26, 197, 145, 13, 6, 131, 195, 169, 7, 13, 12, 201, 72, 83, 132, 77, 161, 82, 20, 180, 133, 13, 6, 131, 195, 169, 7, 13, 0, 19, 144, 13, 5, 7, 14, 25, 9, 12, 22, 195, 161, 14, 21, 12, 195, 161, 19, 13, 9, 198, 13, 51, 205, 4, 116, 129, 13, 0, 17, 142, 22, 9, 12, 195, 161, 7, 8, 195, 161, 2, 15, 18, 195, 186, 13, 11, 200, 29, 145, 82, 20, 177, 75, 20, 224, 13, 7, 196, 76, 83, 77, 36, 13, 0, 8, 197, 5, 163, 203, 5, 64, 13, 42, 69, 24, 83, 5, 81, 64, 83, 109, 55, 109, 47, 12, 23, 37, 91, 23, 65, 109, 81, 89, 117, 50, 37, 49, 0, 13, 82, 105, 115, 32, 109, 101, 103, 115, 122, 197, 177, 110, 105, 107, 32, 8, 197, 24, 83, 5, 81, 64, 13, 17, 9, 95, 35, 45, 195, 169, 14, 195, 169, 12, 113, 50, 113, 55, 0, 21, 0, 21, 146, 195, 182, 14, 11, 15, 18, 13, 195, 161, 14, 25, 26, 1, 20, 15, 11, 1, 20, 13, 12, 137, 11, 195, 169, 18, 4, 5, 26, 20, 5, 13, 9, 134, 19, 26, 195, 161, 12, 12, 13, 13, 67, 61, 68, 0, 115, 47, 113, 48, 113, 0, 42, 42, 7, 132, 10, 195, 186, 14, 20, 13, 7, 95, 35, 45, 195, 161, 9, 7, 114, 37, 81, 0, 0, 19, 67, 61, 69, 0, 39, 47, 12, 23, 84, 108, 50, 0, 13, 81, 118, 97, 110, 32, 13, 138, 7, 25, 195, 182, 20, 195, 182, 18, 20, 5, 13, 6, 195, 61, 69, 0, 13, 6, 195, 56, 245, 128, 20, 0, 7, 196, 24, 241, 207, 52, 13, 7, 196, 48, 20, 15, 80, 13, 7, 132, 10, 195, 186, 12, 20, 0, 0, 18, 66, 64, 48, 112, 195, 169, 99, 195, 169, 115, 0, 44, 29, 42, 81, 115, 32, 17, 66, 64, 48, 112, 195, 169, 99, 195, 169, 110, 0, 44, 29, 81, 110, 32, 18, 66, 64, 48, 112, 195, 169, 99, 195, 169, 110, 0, 44, 29, 42, 81, 110, 32, 18, 66, 64, 48, 112, 195, 169, 99, 195, 169, 107, 0, 44, 29, 42, 81, 107, 32, 32, 7, 22, 5, 20, 20, 195, 188, 11, 84, 109, 47, 12, 111, 49, 10, 6, 15, 113, 89, 52, 109, 0, 13, 81, 195, 169, 115, 122, 114, 101, 32, 7, 132, 2, 195, 173, 26, 13, 9, 198, 88, 82, 5, 77, 49, 64, 13, 5, 194, 52, 144, 13, 20, 66, 44, 208, 49, 37, 55, 115, 65, 113, 47, 109, 52, 47, 0, 44, 13, 81, 116, 32, 22, 66, 44, 208, 49, 37, 55, 115, 65, 113, 47, 109, 52, 109, 91, 0, 44, 13, 81, 101, 115, 32, 23, 66, 44, 208, 49, 37, 55, 115, 65, 113, 47, 109, 52, 67, 37, 0, 44, 13, 81, 110, 121, 105, 32, 27, 66, 44, 208, 49, 37, 55, 115, 65, 113, 47, 109, 52, 67, 37, 52, 109, 0, 44, 13, 81, 110, 121, 105, 114, 101, 32, 22, 66, 44, 208, 49, 37, 55, 115, 65, 113, 47, 109, 52, 52, 109, 0, 44, 13, 81, 114, 101, 32, 15, 66, 44, 208, 49, 37, 55, 115, 65, 113, 47, 109, 52, 0, 13, 0, 31, 6, 19, 26, 195, 161, 13, 1, 89, 114, 65, 108, 23, 76, 110, 49, 12, 109, 50, 0, 13, 81, 99, 115, 195, 182, 107, 107, 101, 110, 32, 36, 67, 44, 86, 132, 49, 109, 88, 72, 23, 108, 6, 23, 83, 109, 55, 107, 118, 88, 109, 47, 0, 13, 82, 97, 32, 102, 101, 108, 104, 197, 145, 122, 101, 116, 32, 9, 134, 19, 26, 195, 161, 13, 1, 13, 6, 195, 44, 86, 132, 13, 0, 11, 200, 44, 85, 133, 72, 81, 5, 81, 64, 13, 11, 200, 76, 146, 197, 72, 81, 5, 81, 64, 13, 0, 8, 197, 32, 21, 14, 4, 176, 13, 12, 201, 4, 194, 193, 48, 208, 90, 61, 69, 0, 13, 0, 43, 11, 12, 5, 8, 5, 20, 197, 145, 19, 195, 169, 7, 55, 109, 107, 109, 47, 118, 91, 113, 81, 15, 84, 108, 50, 15, 108, 52, 52, 108, 0, 13, 82, 118, 97, 110, 32, 97, 114, 114, 97, 32, 10, 135, 11, 195, 169, 18, 12, 5, 11, 13, 9, 198, 8, 150, 148, 61, 48, 84, 13, 14, 139, 12, 5, 8, 5, 20, 197, 145, 19, 195, 169, 7, 13, 10, 135, 12, 5, 14, 14, 195, 169, 11, 13, 0, 22, 67, 52, 149, 0, 65, 37, 47, 23, 109, 89, 109, 55, 0, 13, 81, 101, 115, 122, 101, 108, 32, 38, 67, 52, 149, 0, 65, 37, 47, 10, 6, 15, 84, 114, 55, 47, 39, 89, 47, 108, 47, 50, 37, 0, 13, 81, 118, 195, 161, 108, 116, 111, 122, 116, 97, 116, 110, 105, 32, 6, 195, 8, 244, 148, 13, 6, 195, 52, 149, 0, 13, 0, 7, 196, 24, 241, 206, 36, 13, 11, 200, 80, 20, 148, 32, 21, 14, 4, 176, 13, 31, 68, 24, 241, 202, 4, 83, 39, 81, 57, 108, 10, 6, 15, 113, 52, 47, 109, 50, 37, 0, 13, 81, 195, 169, 114, 116, 101, 110, 105, 32, 40, 68, 24, 241, 202, 4, 83, 39, 81, 57, 108, 23, 109, 52, 109, 72, 65, 113, 67, 109, 88, 50, 37, 0, 13, 81, 101, 114, 101, 100, 109, 195, 169, 110, 121, 101, 122, 110, 105, 32, 10, 135, 6, 195, 161, 10, 12, 2, 1, 13, 11, 200, 72, 83, 132, 77, 161, 82, 72, 80, 13, 7, 196, 24, 241, 202, 4, 13, 0, 8, 197, 44, 85, 25, 20, 112, 13, 8, 197, 8, 18, 129, 36, 208, 13, 8, 197, 77, 160, 86, 4, 176, 13, 0, 12, 137, 20, 1, 7, 195, 161, 12, 12, 1, 13, 13, 12, 137, 11, 5, 26, 5, 12, 197, 145, 10, 5, 13, 13, 138, 22, 195, 161, 19, 195, 161, 18, 15, 12, 20, 13, 7, 132, 2, 195, 173, 18, 13, 0, 14, 203, 20, 195, 85, 48, 20, 218, 80, 245, 20, 84, 176, 13, 14, 203, 24, 83, 15, 49, 96, 83, 32, 21, 14, 4, 176, 13, 10, 199, 80, 84, 150, 21, 161, 84, 80, 13, 10, 135, 12, 5, 14, 14, 195, 169, 12, 13, 11, 136, 22, 195, 169, 12, 20, 195, 169, 11, 13, 10, 135, 195, 169, 10, 6, 195, 169, 12, 22, 0, 11, 136, 11, 195, 182, 20, 195, 182, 20, 20, 13, 15, 140, 11, 15, 14, 3, 5, 14, 20, 18, 195, 161, 12, 20, 13, 6, 131, 14, 197, 145, 13, 0, 6, 131, 195, 173, 18, 13, 12, 137, 11, 195, 188, 12, 4, 195, 182, 20, 20, 13, 8, 133, 19, 26, 195, 169, 16, 13, 0, 12, 6, 95, 35, 45, 195, 169, 20, 113, 47, 0, 21, 0, 10, 135, 11, 195, 169, 16, 12, 5, 20, 13, 0, 15, 140, 14, 5, 22, 5, 12, 197, 145, 11, 14, 195, 169, 12, 13, 60, 8, 6, 5, 12, 195, 188, 12, 5, 20, 83, 109, 55, 111, 55, 109, 47, 23, 108, 49, 108, 72, 114, 57, 65, 109, 50, 47, 109, 91, 12, 113, 81, 113, 47, 0, 13, 81, 97, 107, 97, 100, 195, 161, 108, 121, 109, 101, 110, 116, 101, 115, 115, 195, 169, 103, 195, 169, 116, 32, 11, 136, 6, 5, 12, 195, 188, 12, 5, 20, 13, 28, 8, 6, 5, 12, 195, 188, 12, 5, 20, 83, 109, 55, 111, 55, 109, 47, 23, 84, 108, 50, 0, 13, 81, 118, 97, 110, 32, 9, 134, 6, 5, 8, 195, 169, 18, 13, 10, 135, 19, 26, 195, 179, 22, 195, 161, 13, 7, 132, 6, 195, 182, 12, 13, 0, 12, 137, 20, 5, 19, 20, 195, 188, 12, 5, 20, 13, 8, 133, 19, 26, 195, 169, 20, 13, 0, 13, 138, 195, 173, 20, 195, 169, 12, 5, 20, 5, 20, 13, 13, 138, 6, 5, 12, 195, 188, 12, 5, 20, 5, 20, 13, 9, 134, 19, 5, 7, 195, 173, 20, 13, 8, 133, 12, 195, 161, 14, 25, 13, 0, 11, 136, 11, 1, 16, 14, 195, 161, 14, 11, 13, 24, 3, 195, 182, 20, 110, 47, 23, 49, 110, 52, 111, 55, 0, 13, 81, 107, 195, 182, 114, 195, 188, 108, 32, 14, 139, 20, 5, 18, 22, 5, 26, 5, 20, 195, 169, 20, 13, 14, 139, 11, 195, 169, 20, 19, 195, 169, 7, 5, 9, 20, 13, 0, 18, 143, 11, 195, 169, 20, 19, 195, 169, 7, 2, 5, 5, 19, 20, 5, 13, 13, 12, 137, 9, 19, 13, 5, 18, 20, 195, 188, 11, 13, 14, 139, 11, 18, 9, 20, 9, 11, 21, 19, 19, 195, 161, 13, 11, 136, 1, 10, 195, 161, 14, 12, 1, 20, 13, 11, 4, 95, 49, 15, 24, 109, 55, 91, 118, 0, 0, 35, 8, 11, 15, 18, 13, 195, 161, 14, 25, 49, 39, 52, 65, 114, 67, 23, 49, 110, 88, 110, 47, 12, 0, 13, 81, 107, 195, 182, 122, 195, 182, 116, 116, 32, 15, 140, 5, 7, 25, 195, 169, 18, 20, 5, 12, 13, 197, 177, 13, 0, 6, 131, 195, 182, 19, 72, 0, 12, 137, 14, 1, 7, 25, 11, 15, 18, 195, 186, 13, 14, 139, 195, 169, 12, 5, 20, 195, 169, 22, 195, 169, 20, 13, 13, 138, 2, 1, 10, 11, 5, 22, 5, 18, 197, 145, 13, 8, 133, 195, 161, 18, 195, 186, 13, 0, 15, 140, 11, 195, 169, 14, 25, 19, 26, 5, 18, 195, 173, 20, 13, 0, 16, 141, 13, 1, 18, 1, 4, 22, 195, 161, 14, 25, 1, 9, 20, 13, 19, 144, 20, 5, 12, 10, 5, 19, 195, 173, 20, 13, 195, 169, 14, 25, 197, 177, 13, 8, 133, 4, 195, 182, 14, 20, 13, 0, 0, 11, 136, 10, 195, 161, 18, 1, 20, 15, 11, 13, 6, 195, 40, 241, 192, 13, 8, 133, 19, 26, 195, 179, 18, 72, 0, 22, 147, 8, 1, 19, 26, 14, 195, 161, 12, 8, 1, 20, 1, 20, 12, 1, 14, 14, 195, 161, 13, 6, 195, 40, 241, 193, 13, 0, 0, 0, 6, 195, 24, 241, 192, 13, 36, 67, 24, 241, 192, 83, 39, 81, 23, 108, 6, 15, 71, 37, 88, 39, 76, 12, 114, 81, 0, 13, 82, 97, 32, 98, 105, 122, 111, 116, 116, 115, 195, 161, 103, 32, 29, 67, 24, 241, 192, 83, 39, 81, 23, 107, 108, 34, 119, 39, 55, 50, 37, 0, 13, 81, 104, 97, 114, 99, 111, 108, 110, 105, 32, 0, 6, 195, 24, 241, 193, 13, 15, 140, 5, 21, 18, 195, 179, 16, 195, 161, 2, 195, 179, 12, 13, 8, 133, 18, 195, 161, 14, 11, 13, 6, 195, 52, 17, 193, 13, 0, 42, 3, 195, 169, 14, 113, 50, 15, 37, 91, 15, 65, 109, 81, 76, 37, 50, 114, 55, 47, 108, 65, 0, 13, 82, 105, 115, 32, 109, 101, 103, 99, 115, 105, 110, 195, 161, 108, 116, 97, 109, 32, 16, 3, 195, 169, 14, 113, 50, 15, 37, 91, 0, 13, 81, 105, 115, 32, 12, 137, 6, 21, 14, 11, 3, 9, 195, 179, 20, 13, 9, 134, 11, 9, 12, 195, 179, 19, 13, 6, 131, 195, 169, 14, 13, 8, 133, 19, 26, 195, 179, 20, 13, 6, 131, 195, 169, 14, 13, 0, 15, 140, 11, 195, 188, 12, 6, 195, 182, 12, 4, 195, 182, 14, 13, 9, 198, 40, 83, 26, 21, 69, 0, 13, 5, 194, 72, 16, 13, 0, 7, 132, 10, 195, 179, 11, 13, 6, 131, 195, 169, 12, 13, 0, 7, 132, 20, 195, 179, 12, 13, 0, 8, 197, 36, 195, 5, 80, 144, 13, 22, 5, 1, 12, 195, 179, 12, 108, 55, 115, 55, 10, 6, 15, 108, 88, 0, 13, 81, 97, 122, 32, 35, 69, 88, 19, 1, 52, 144, 84, 108, 55, 108, 65, 37, 15, 48, 52, 39, 71, 55, 113, 65, 108, 0, 13, 81, 112, 114, 111, 98, 108, 195, 169, 109, 97, 32, 8, 197, 88, 19, 1, 52, 144, 13, 8, 197, 25, 85, 14, 4, 176, 13, 8, 197, 64, 243, 148, 40, 16, 13, 8, 133, 1, 12, 195, 179, 12, 13, 0, 15, 140, 8, 195, 188, 12, 25, 195, 169, 19, 11, 5, 4, 10, 13, 9, 198, 24, 150, 133, 80, 82, 192, 13, 9, 198, 88, 84, 147, 20, 230, 64, 13, 9, 198, 60, 179, 218, 80, 18, 192, 13, 9, 198, 80, 17, 202, 4, 149, 0, 13, 9, 198, 88, 83, 5, 80, 82, 192, 13, 14, 67, 48, 212, 0, 109, 55, 109, 65, 48, 113, 0, 42, 42, 0, 23, 67, 24, 242, 192, 83, 39, 49, 23, 49, 110, 88, 113, 0, 13, 81, 107, 195, 182, 122, 195, 169, 32, 43, 67, 24, 242, 192, 83, 39, 49, 23, 49, 110, 88, 113, 23, 109, 65, 109, 55, 49, 109, 72, 37, 49, 0, 13, 82, 107, 195, 182, 122, 195, 169, 32, 101, 109, 101, 108, 107, 101, 100, 105, 107, 32, 46, 67, 24, 242, 192, 83, 39, 49, 23, 49, 110, 88, 110, 47, 12, 23, 89, 115, 52, 115, 72, 37, 49, 0, 13, 82, 107, 195, 182, 122, 195, 182, 116, 116, 32, 115, 122, 195, 179, 114, 195, 179, 100, 105, 107, 32, 70, 67, 24, 242, 192, 83, 39, 49, 23, 49, 110, 88, 113, 23, 76, 110, 49, 12, 109, 50, 23, 108, 23, 107, 118, 65, 113, 52, 91, 113, 49, 55, 109, 47, 0, 13, 84, 107, 195, 182, 122, 195, 169, 32, 99, 115, 195, 182, 107, 107, 101, 110, 32, 97, 32, 104, 197, 145, 109, 195, 169, 114, 115, 195, 169, 107, 108, 101, 116, 32, 41, 67, 24, 242, 192, 83, 39, 49, 23, 49, 110, 88, 110, 47, 12, 23, 108, 55, 108, 49, 40, 55, 0, 13, 82, 107, 195, 182, 122, 195, 182, 116, 116, 32, 97, 108, 97, 107, 117, 108, 32, 74, 67, 24, 242, 192, 83, 39, 49, 23, 83, 110, 55, 113, 23, 109, 65, 109, 55, 49, 109, 72, 37, 49, 23, 108, 23, 107, 118, 65, 113, 52, 91, 113, 49, 55, 109, 47, 0, 13, 84, 102, 195, 182, 108, 195, 169, 32, 101, 109, 101, 108, 107, 101, 100, 105, 107, 32, 97, 32, 104, 197, 145, 109, 195, 169, 114, 115, 195, 169, 107, 108, 101, 116, 32, 45, 67, 24, 242, 192, 83, 39, 49, 23, 49, 110, 88, 110, 47, 12, 23, 84, 114, 51, 107, 108, 47, 115, 0, 13, 82, 107, 195, 182, 122, 195, 182, 116, 116, 32, 118, 195, 161, 114, 104, 97, 116, 195, 179, 32, 6, 195, 24, 242, 192, 13, 15, 140, 3, 19, 195, 188, 20, 195, 182, 18, 20, 195, 182, 11, 20, 0, 16, 141, 6, 5, 12, 13, 15, 14, 4, 1, 14, 195, 161, 14, 11, 13, 6, 195, 24, 241, 217, 13, 10, 135, 20, 195, 182, 14, 11, 18, 5, 13, 12, 137, 1, 10, 195, 161, 14, 12, 10, 21, 11, 13, 7, 132, 10, 195, 179, 12, 13, 7, 132, 6, 195, 169, 12, 13, 6, 131, 195, 169, 9, 72, 7, 132, 18, 195, 179, 12, 13, 0, 24, 3, 195, 169, 22, 113, 84, 23, 109, 55, 47, 109, 55, 47, 0, 13, 81, 101, 108, 116, 101, 108, 116, 32, 22, 3, 195, 169, 22, 113, 84, 23, 108, 55, 108, 47, 12, 0, 13, 81, 97, 108, 97, 116, 116, 32, 31, 69, 77, 160, 86, 4, 208, 89, 108, 84, 108, 65, 15, 57, 114, 52, 114, 91, 108, 0, 13, 81, 106, 195, 161, 114, 195, 161, 115, 97, 32, 12, 201, 77, 161, 82, 21, 1, 76, 56, 82, 192, 13, 8, 197, 80, 17, 202, 4, 144, 13, 6, 131, 195, 169, 22, 13, 8, 133, 19, 26, 195, 179, 12, 13, 12, 137, 12, 195, 161, 20, 19, 26, 15, 20, 20, 13, 6, 131, 195, 182, 14, 13, 0, 7, 66, 57, 144, 109, 67, 0, 9, 198, 52, 20, 129, 16, 242, 192, 13, 10, 135, 22, 195, 161, 7, 195, 179, 11, 13, 41, 5, 195, 169, 7, 18, 5, 113, 81, 52, 109, 23, 89, 114, 65, 112, 47, 107, 108, 47, 40, 50, 49, 0, 13, 81, 115, 122, 195, 161, 109, 195, 173, 116, 104, 97, 116, 117, 110, 107, 32, 9, 198, 88, 19, 1, 52, 149, 0, 13, 9, 198, 24, 243, 25, 56, 18, 192, 13, 9, 134, 5, 14, 14, 195, 169, 12, 13, 0, 26, 71, 32, 83, 25, 21, 161, 84, 80, 107, 109, 57, 109, 88, 109, 47, 12, 23, 49, 37, 0, 13, 81, 107, 105, 32, 10, 199, 80, 145, 210, 37, 51, 133, 44, 13, 14, 139, 8, 1, 20, 195, 161, 18, 15, 26, 15, 20, 20, 13, 7, 132, 12, 195, 179, 7, 13, 9, 134, 11, 195, 182, 26, 195, 169, 13, 0, 15, 140, 7, 15, 14, 4, 15, 12, 1, 20, 20, 195, 179, 12, 13, 15, 140, 16, 195, 169, 12, 4, 195, 161, 11, 20, 195, 179, 12, 13, 13, 138, 12, 5, 7, 9, 14, 11, 195, 161, 2, 2, 13, 15, 140, 11, 15, 18, 12, 195, 161, 20, 15, 26, 15, 20, 20, 13, 15, 204, 40, 83, 5, 57, 66, 197, 104, 129, 84, 56, 82, 192, 13, 12, 136, 11, 195, 182, 26, 195, 182, 20, 20, 72, 22, 0, 23, 3, 195, 169, 18, 113, 52, 23, 84, 113, 81, 109, 47, 0, 13, 81, 118, 195, 169, 103, 101, 116, 32, 18, 3, 195, 169, 18, 113, 52, 10, 6, 15, 109, 55, 0, 13, 81, 101, 108, 32, 11, 136, 10, 195, 161, 18, 1, 20, 1, 9, 13, 12, 137, 11, 15, 18, 195, 161, 2, 195, 179, 12, 13, 12, 201, 72, 83, 132, 77, 161, 82, 56, 82, 192, 13, 11, 136, 195, 173, 18, 195, 161, 19, 18, 1, 13, 12, 137, 8, 9, 2, 195, 161, 26, 15, 20, 20, 13, 6, 131, 195, 169, 18, 13, 0, 42, 10, 4, 15, 12, 7, 15, 11, 18, 195, 179, 12, 72, 39, 55, 81, 39, 49, 52, 115, 55, 23, 71, 109, 89, 113, 55, 109, 49, 0, 13, 81, 98, 101, 115, 122, 195, 169, 108, 101, 107, 32, 17, 3, 195, 169, 19, 113, 91, 23, 57, 115, 0, 13, 81, 106, 195, 179, 32, 26, 3, 195, 169, 19, 113, 91, 23, 83, 108, 48, 108, 72, 39, 91, 0, 13, 81, 102, 97, 112, 97, 100, 111, 115, 32, 34, 3, 195, 169, 19, 113, 91, 23, 71, 39, 89, 12, 108, 50, 47, 115, 108, 49, 0, 13, 81, 98, 111, 115, 115, 122, 97, 110, 116, 195, 179, 97, 107, 32, 13, 138, 9, 14, 4, 9, 195, 161, 2, 195, 179, 12, 13, 19, 144, 22, 195, 161, 12, 20, 15, 26, 195, 169, 11, 15, 14, 25, 1, 2, 2, 13, 25, 3, 195, 169, 19, 113, 91, 65, 115, 79, 12, 114, 47, 0, 13, 81, 109, 195, 179, 100, 106, 195, 161, 116, 32, 9, 134, 9, 14, 4, 195, 173, 20, 13, 8, 131, 195, 169, 19, 72, 12, 22, 18, 4, 95, 3, 9, 18, 119, 37, 52, 49, 40, 65, 83, 55, 109, 49, 89, 0, 0, 19, 5, 19, 26, 195, 173, 22, 89, 112, 84, 23, 109, 55, 0, 13, 81, 101, 108, 32, 13, 138, 22, 195, 161, 18, 15, 19, 195, 161, 2, 1, 13, 9, 134, 8, 15, 26, 26, 195, 161, 13, 0, 54, 11, 3, 19, 1, 16, 1, 4, 195, 169, 11, 18, 1, 76, 108, 48, 108, 72, 113, 49, 52, 108, 23, 91, 37, 50, 76, 23, 49, 37, 55, 114, 47, 114, 91, 0, 13, 82, 115, 105, 110, 99, 115, 32, 107, 105, 108, 195, 161, 116, 195, 161, 115, 32, 15, 140, 195, 161, 12, 12, 1, 16, 15, 20, 18, 195, 179, 12, 13, 7, 196, 52, 81, 217, 20, 13, 7, 196, 53, 83, 139, 4, 13, 19, 144, 11, 1, 12, 195, 179, 26, 11, 15, 4, 195, 161, 19, 20, 195, 179, 12, 13, 0, 15, 140, 20, 1, 14, 195, 161, 3, 19, 1, 4, 195, 179, 9, 13, 12, 137, 22, 195, 169, 20, 5, 12, 195, 169, 20, 13, 16, 141, 6, 15, 7, 12, 1, 12, 20, 1, 11, 18, 195, 179, 12, 13, 6, 131, 195, 179, 14, 72, 0, 17, 3, 95, 194, 183, 49, 110, 88, 113, 48, 91, 118, 48, 39, 50, 47, 0, 9, 134, 11, 5, 26, 195, 169, 20, 13, 10, 135, 8, 9, 20, 20, 195, 188, 11, 13, 17, 142, 11, 1, 16, 1, 3, 9, 20, 195, 161, 19, 18, 195, 179, 12, 13, 8, 133, 14, 5, 22, 197, 177, 13, 10, 135, 8, 9, 20, 20, 195, 188, 11, 13, 0, 32, 7, 5, 19, 195, 169, 12, 25, 20, 109, 91, 113, 57, 47, 10, 6, 15, 55, 114, 47, 39, 49, 0, 13, 81, 108, 195, 161, 116, 111, 107, 32, 10, 135, 5, 18, 5, 10, 195, 169, 20, 13, 18, 143, 20, 195, 161, 18, 19, 1, 19, 8, 195, 161, 26, 2, 195, 179, 12, 13, 18, 143, 19, 26, 5, 13, 16, 15, 14, 20, 10, 195, 161, 2, 195, 179, 12, 13, 10, 199, 52, 243, 132, 4, 229, 78, 44, 13, 9, 134, 11, 195, 169, 18, 14, 9, 13, 8, 133, 19, 26, 195, 182, 18, 72, 0, 11, 136, 19, 26, 5, 18, 22, 195, 169, 20, 13, 0, 19, 3, 95, 194, 178, 65, 114, 91, 39, 72, 37, 49, 107, 108, 47, 84, 114, 67, 0, 19, 144, 11, 195, 182, 26, 195, 169, 16, 16, 15, 14, 20, 10, 195, 161, 2, 1, 13, 12, 137, 19, 26, 5, 13, 195, 169, 12, 25, 20, 13, 11, 136, 5, 12, 12, 195, 161, 20, 14, 9, 13, 9, 134, 2, 195, 161, 14, 9, 11, 13, 11, 136, 11, 5, 18, 195, 188, 12, 14, 9, 13, 0, 20, 3, 95, 194, 179, 107, 108, 34, 65, 108, 72, 37, 49, 107, 108, 47, 84, 114, 67, 0, 42, 8, 19, 26, 15, 13, 15, 18, 195, 186, 89, 39, 65, 39, 52, 116, 23, 84, 39, 55, 47, 23, 55, 114, 47, 50, 37, 0, 13, 82, 118, 111, 108, 116, 32, 108, 195, 161, 116, 110, 105, 32, 21, 146, 5, 12, 2, 15, 3, 19, 195, 161, 20, 195, 161, 19, 15, 11, 18, 195, 179, 12, 13, 12, 137, 5, 7, 25, 19, 26, 5, 18, 197, 177, 13, 14, 4, 195, 182, 26, 22, 110, 88, 84, 109, 79, 0, 25, 9, 0, 14, 139, 19, 26, 195, 161, 13, 195, 173, 20, 8, 1, 20, 13, 12, 137, 5, 12, 197, 145, 19, 26, 195, 182, 18, 13, 14, 139, 18, 5, 14, 4, 19, 26, 5, 18, 195, 169, 20, 13, 14, 139, 22, 195, 169, 12, 5, 13, 195, 169, 14, 25, 20, 13, 10, 199, 40, 21, 129, 76, 243, 20, 4, 13, 6, 195, 56, 244, 192, 72, 11, 67, 65, 54, 148, 48, 89, 12, 47, 0, 41, 0, 44, 12, 11, 195, 182, 26, 12, 5, 13, 195, 169, 14, 25, 20, 49, 110, 88, 55, 109, 65, 113, 67, 47, 23, 108, 72, 39, 47, 12, 23, 49, 37, 0, 13, 82, 97, 100, 111, 116, 116, 32, 107, 105, 32, 14, 139, 10, 15, 7, 19, 26, 1, 2, 195, 161, 12, 25, 13, 12, 137, 22, 195, 161, 12, 20, 15, 26, 9, 11, 13, 0, 9, 198, 48, 81, 217, 20, 225, 75, 13, 0, 16, 141, 19, 195, 169, 18, 195, 188, 12, 195, 169, 11, 5, 14, 25, 13, 9, 198, 52, 81, 212, 20, 197, 0, 13, 8, 133, 12, 195, 161, 7, 25, 13, 0, 10, 199, 77, 163, 210, 84, 194, 143, 56, 13, 9, 198, 48, 81, 143, 29, 147, 137, 13, 11, 136, 11, 5, 4, 22, 197, 177, 5, 11, 13, 10, 199, 24, 19, 129, 80, 146, 213, 76, 13, 14, 4, 95, 19, 20, 11, 114, 47, 107, 116, 88, 114, 91, 0, 15, 7, 95, 35, 45, 18, 195, 179, 12, 114, 52, 115, 55, 0, 21, 0, 16, 3, 95, 194, 173, 55, 114, 79, 49, 110, 47, 118, 57, 109, 55, 0, 63, 14, 5, 7, 25, 195, 169, 18, 20, 5, 12, 13, 197, 177, 5, 14, 109, 79, 12, 113, 52, 47, 109, 55, 65, 117, 109, 50, 23, 65, 109, 81, 114, 55, 12, 108, 48, 112, 47, 39, 47, 12, 108, 0, 13, 81, 109, 101, 103, 195, 161, 108, 108, 97, 112, 195, 173, 116, 111, 116, 116, 97, 32, 33, 72, 48, 82, 5, 80, 85, 12, 20, 224, 55, 109, 107, 109, 47, 109, 47, 55, 109, 50, 23, 84, 39, 55, 47, 0, 13, 81, 118, 111, 108, 116, 32, 12, 137, 7, 25, 195, 161, 18, 20, 195, 179, 11, 13, 7, 132, 20, 195, 182, 12, 13, 0, 8, 133, 1, 4, 195, 179, 20, 13, 11, 4, 95, 1, 3, 21, 113, 55, 109, 91, 0, 0, 22, 3, 95, 194, 171, 71, 109, 55, 91, 118, 71, 108, 55, 37, 72, 113, 88, 118, 57, 109, 55, 0, 44, 70, 52, 81, 5, 72, 33, 64, 65, 109, 72, 109, 52, 71, 109, 23, 47, 109, 52, 109, 55, 113, 91, 113, 71, 109, 50, 0, 13, 81, 116, 101, 114, 101, 108, 195, 169, 115, 195, 169, 98, 101, 110, 32, 9, 134, 11, 195, 179, 4, 15, 20, 13, 13, 138, 3, 5, 12, 12, 195, 161, 18, 195, 179, 12, 13, 6, 131, 195, 179, 19, 72, 0, 22, 4, 20, 195, 182, 11, 47, 110, 49, 23, 37, 81, 108, 88, 0, 13, 81, 105, 103, 97, 122, 32, 15, 140, 20, 1, 18, 20, 195, 179, 26, 11, 15, 4, 9, 11, 13, 11, 136, 8, 195, 179, 14, 1, 16, 9, 7, 13, 0, 40, 70, 40, 241, 207, 44, 32, 78, 57, 39, 81, 39, 49, 71, 108, 50, 23, 37, 55, 12, 109, 47, 113, 49, 109, 91, 0, 13, 81, 105, 108, 108, 101, 116, 195, 169, 107, 101, 115, 32, 15, 140, 8, 1, 12, 195, 161, 12, 195, 161, 18, 195, 179, 12, 13, 11, 136, 8, 195, 179, 14, 1, 16, 15, 20, 13, 7, 132, 10, 195, 179, 20, 13, 7, 132, 18, 195, 182, 12, 13, 0, 12, 137, 7, 25, 195, 161, 18, 20, 195, 179, 20, 13, 16, 141, 20, 1, 18, 20, 195, 161, 19, 195, 161, 18, 195, 179, 12, 13, 11, 136, 10, 5, 12, 195, 182, 12, 14, 9, 13, 0, 20, 66, 52, 208, 65, 37, 55, 37, 65, 113, 47, 109, 52, 47, 0, 44, 13, 81, 116, 32, 22, 66, 52, 208, 65, 37, 55, 37, 65, 113, 47, 109, 52, 109, 91, 0, 44, 13, 81, 101, 115, 32, 27, 66, 52, 208, 65, 37, 55, 37, 65, 113, 47, 109, 52, 67, 37, 52, 109, 0, 44, 13, 81, 110, 121, 105, 114, 101, 32, 23, 66, 52, 208, 65, 37, 55, 37, 65, 113, 47, 109, 52, 67, 37, 0, 44, 13, 81, 110, 121, 105, 32, 15, 66, 52, 208, 65, 37, 55, 37, 65, 113, 47, 109, 52, 0, 13, 0, 16, 3, 95, 194, 164, 48, 113, 50, 88, 50, 109, 65, 57, 109, 55, 0, 0, 19, 144, 5, 12, 6, 15, 7, 1, 4, 195, 161, 19, 195, 161, 18, 195, 179, 12, 13, 10, 135, 22, 195, 161, 12, 14, 9, 1, 13, 30, 67, 40, 241, 201, 57, 39, 81, 37, 23, 89, 110, 84, 109, 81, 109, 47, 0, 13, 81, 115, 122, 195, 182, 118, 101, 103, 101, 116, 32, 34, 67, 40, 241, 201, 57, 39, 81, 37, 15, 55, 113, 48, 113, 91, 109, 49, 109, 47, 0, 13, 81, 108, 195, 169, 112, 195, 169, 115, 101, 107, 101, 116, 32, 14, 139, 14, 25, 195, 186, 10, 20, 195, 179, 26, 14, 9, 13, 0, 8, 197, 76, 82, 148, 20, 208, 13, 8, 197, 32, 83, 25, 20, 176, 13, 16, 141, 6, 15, 18, 18, 195, 161, 19, 11, 195, 179, 4, 15, 20, 13, 8, 197, 56, 82, 212, 20, 176, 13, 0, 9, 198, 48, 84, 218, 56, 82, 192, 72, 9, 198, 44, 84, 133, 76, 146, 192, 13, 9, 198, 4, 230, 65, 28, 242, 192, 13, 9, 198, 24, 82, 211, 104, 146, 192, 13, 10, 135, 22, 195, 169, 7, 26, 9, 11, 13, 9, 198, 72, 244, 211, 104, 18, 192, 13, 0, 11, 3, 95, 194, 160, 89, 115, 49, 110, 88, 0, 10, 199, 21, 49, 84, 20, 176, 133, 56, 13, 10, 135, 12, 195, 161, 20, 15, 20, 20, 13, 10, 4, 95, 18, 14, 7, 49, 110, 52, 0, 0, 16, 3, 95, 194, 161, 108, 55, 91, 115, 37, 50, 72, 109, 49, 89, 0, 7, 3, 95, 195, 169, 113, 0, 14, 139, 195, 182, 19, 19, 26, 5, 22, 5, 20, 14, 9, 13, 8, 133, 19, 26, 195, 182, 7, 13, 7, 132, 2, 195, 179, 12, 72, 0, 8, 197, 52, 83, 148, 20, 208, 13, 12, 137, 7, 25, 195, 161, 18, 20, 15, 20, 20, 13, 8, 133, 11, 195, 188, 26, 4, 13, 0, 13, 138, 9, 18, 195, 161, 14, 25, 20, 195, 179, 12, 13, 11, 136, 9, 4, 197, 145, 19, 5, 2, 2, 13, 12, 137, 11, 195, 169, 18, 195, 169, 19, 18, 5, 13, 46, 10, 20, 1, 18, 11, 195, 173, 20, 15, 20, 20, 47, 108, 52, 49, 112, 47, 39, 47, 12, 15, 10, 37, 72, 118, 57, 114, 52, 114, 91, 0, 13, 81, 105, 100, 197, 145, 106, 195, 161, 114, 195, 161, 115, 32, 9, 198, 53, 85, 1, 80, 226, 64, 13, 10, 135, 1, 4, 195, 179, 4, 9, 11, 13, 9, 198, 52, 240, 137, 48, 242, 192, 13, 9, 134, 1, 18, 18, 195, 179, 12, 13, 9, 134, 1, 18, 18, 195, 179, 12, 13, 0, 12, 137, 4, 18, 195, 161, 7, 195, 161, 2, 2, 13, 50, 11, 20, 195, 161, 13, 15, 7, 1, 20, 15, 20, 20, 47, 114, 65, 39, 81, 108, 47, 39, 47, 12, 23, 49, 37, 108, 72, 114, 91, 23, 55, 109, 89, 0, 13, 82, 107, 105, 97, 100, 195, 161, 115, 32, 108, 101, 115, 122, 32, 14, 139, 20, 195, 161, 13, 15, 7, 1, 20, 15, 20, 20, 13, 10, 199, 77, 161, 82, 88, 86, 142, 36, 13, 0, 11, 200, 24, 241, 207, 73, 99, 211, 60, 208, 13, 16, 141, 9, 14, 20, 195, 169, 26, 13, 195, 169, 14, 25, 5, 11, 13, 12, 137, 20, 195, 161, 18, 15, 12, 195, 179, 11, 13, 7, 196, 72, 17, 193, 16, 13, 7, 196, 20, 225, 197, 52, 13, 0, 12, 201, 8, 150, 143, 57, 145, 193, 80, 226, 64, 13, 11, 136, 8, 195, 179, 14, 1, 16, 10, 1, 13, 12, 137, 11, 15, 18, 195, 161, 18, 195, 179, 12, 13, 11, 136, 5, 12, 195, 169, 7, 7, 195, 169, 13, 13, 138, 5, 18, 197, 145, 12, 20, 5, 20, 9, 11, 13, 12, 201, 60, 64, 70, 36, 118, 69, 48, 226, 64, 13, 9, 134, 5, 12, 14, 195, 182, 11, 13, 0, 15, 140, 12, 5, 7, 4, 18, 195, 161, 7, 195, 161, 2, 2, 13, 9, 134, 14, 195, 169, 14, 9, 20, 13, 13, 138, 20, 195, 169, 13, 195, 161, 18, 195, 179, 12, 13, 12, 137, 195, 161, 12, 12, 195, 173, 20, 10, 1, 13, 0, 9, 198, 77, 161, 82, 20, 195, 69, 13, 33, 11, 11, 1, 20, 15, 14, 195, 161, 18, 195, 179, 12, 49, 108, 47, 39, 50, 114, 52, 115, 55, 23, 84, 108, 50, 0, 13, 81, 118, 97, 110, 32, 14, 139, 11, 1, 20, 15, 14, 195, 161, 18, 195, 179, 12, 13, 17, 142, 4, 21, 16, 12, 9, 11, 195, 161, 3, 9, 195, 179, 18, 1, 13, 14, 139, 6, 15, 18, 18, 195, 161, 19, 2, 195, 179, 12, 13, 13, 138, 22, 9, 12, 195, 161, 7, 195, 161, 2, 1, 13, 0, 17, 142, 12, 5, 7, 6, 5, 12, 20, 197, 177, 14, 197, 145, 2, 2, 13, 26, 68, 44, 144, 211, 36, 49, 37, 76, 37, 10, 6, 15, 108, 107, 39, 88, 0, 13, 81, 97, 104, 104, 111, 122, 32, 19, 144, 8, 195, 161, 26, 19, 26, 1, 2, 195, 161, 12, 25, 20, 195, 179, 12, 13, 14, 139, 8, 1, 19, 26, 14, 195, 161, 12, 14, 15, 13, 13, 0, 20, 69, 84, 37, 78, 81, 80, 117, 98, 117, 110, 116, 117, 110, 0, 44, 29, 81, 110, 32, 56, 14, 6, 5, 12, 8, 1, 19, 26, 14, 195, 161, 12, 195, 179, 11, 83, 109, 55, 107, 108, 89, 50, 114, 55, 115, 49, 23, 55, 109, 47, 110, 55, 47, 113, 91, 109, 37, 47, 0, 13, 81, 108, 101, 116, 195, 182, 108, 116, 195, 169, 115, 101, 105, 116, 32, 12, 137, 195, 169, 12, 13, 195, 169, 14, 25, 20, 13, 45, 14, 6, 5, 12, 8, 1, 19, 26, 14, 195, 161, 12, 195, 179, 11, 83, 109, 55, 107, 108, 89, 50, 114, 55, 115, 49, 23, 57, 110, 50, 12, 109, 49, 0, 13, 81, 106, 195, 182, 110, 110, 101, 107, 32, 16, 141, 8, 15, 14, 12, 1, 16, 10, 195, 161, 18, 195, 179, 12, 13, 16, 141, 22, 195, 161, 12, 12, 1, 12, 1, 20, 2, 195, 179, 12, 13, 16, 141, 5, 12, 12, 195, 161, 20, 15, 7, 1, 20, 15, 20, 20, 13, 0, 6, 195, 21, 161, 75, 13, 17, 142, 16, 18, 15, 2, 12, 195, 169, 13, 195, 161, 18, 195, 179, 12, 13, 0, 10, 199, 32, 19, 12, 61, 69, 1, 52, 13, 13, 138, 11, 195, 182, 20, 5, 12, 5, 26, 14, 9, 13, 6, 195, 88, 19, 12, 13, 0, 14, 139, 11, 195, 182, 26, 12, 5, 11, 5, 4, 197, 145, 13, 43, 11, 14, 5, 13, 26, 5, 20, 11, 195, 182, 26, 9, 50, 109, 65, 88, 109, 47, 49, 110, 88, 37, 23, 89, 108, 71, 84, 114, 67, 0, 13, 81, 115, 122, 97, 98, 118, 195, 161, 110, 121, 32, 44, 11, 14, 5, 13, 26, 5, 20, 11, 195, 182, 26, 9, 50, 109, 65, 88, 109, 47, 49, 110, 88, 37, 23, 89, 108, 71, 84, 114, 67, 0, 13, 81, 115, 122, 97, 98, 98, 118, 195, 161, 110, 121, 32, 6, 195, 4, 32, 129, 13, 11, 136, 11, 195, 169, 19, 26, 195, 173, 20, 13, 9, 134, 195, 169, 18, 10, 5, 14, 13, 14, 4, 95, 50, 15, 24, 65, 114, 91, 39, 72, 37, 49, 0, 0, 19, 144, 14, 25, 21, 7, 195, 161, 12, 12, 15, 13, 195, 161, 14, 25, 2, 1, 13, 0, 37, 67, 13, 80, 195, 119, 40, 119, 12, 23, 49, 111, 55, 83, 110, 55, 72, 52, 118, 55, 0, 13, 81, 107, 195, 188, 108, 102, 195, 182, 108, 100, 114, 197, 145, 108, 32, 6, 195, 13, 80, 195, 13, 9, 198, 32, 21, 143, 57, 64, 64, 13, 11, 136, 22, 5, 18, 26, 9, 195, 179, 14, 13, 25, 7, 195, 182, 12, 10, 195, 169, 11, 110, 57, 57, 113, 49, 23, 65, 109, 81, 0, 13, 81, 109, 101, 103, 32, 10, 135, 13, 195, 169, 18, 14, 5, 11, 13, 9, 134, 195, 169, 10, 10, 5, 12, 13, 10, 135, 195, 161, 12, 12, 14, 1, 11, 13, 14, 6, 95, 35, 45, 22, 5, 12, 113, 84, 109, 55, 0, 21, 0, 12, 137, 11, 195, 169, 16, 5, 11, 2, 5, 14, 22, 15, 7, 95, 35, 45, 20, 195, 179, 12, 114, 47, 115, 55, 0, 21, 0, 19, 144, 2, 197, 177, 14, 3, 19, 5, 12, 5, 11, 13, 195, 169, 14, 25, 20, 13, 7, 196, 80, 244, 148, 4, 13, 7, 196, 80, 84, 150, 20, 13, 0, 10, 135, 195, 188, 7, 25, 2, 5, 14, 13, 13, 138, 19, 26, 195, 161, 13, 15, 12, 14, 1, 11, 13, 10, 135, 19, 26, 195, 161, 13, 15, 14, 13, 8, 197, 72, 144, 211, 4, 160, 13, 0, 9, 198, 32, 144, 130, 4, 229, 0, 13, 34, 7, 12, 195, 161, 20, 195, 179, 11, 55, 114, 47, 115, 49, 23, 89, 114, 65, 114, 52, 108, 0, 13, 81, 115, 122, 195, 161, 109, 195, 161, 114, 97, 32, 9, 198, 4, 35, 1, 45, 32, 64, 13, 11, 136, 20, 21, 4, 195, 161, 19, 195, 186, 13, 10, 135, 20, 5, 20, 20, 195, 169, 11, 13, 14, 139, 8, 1, 19, 26, 14, 195, 161, 12, 14, 1, 11, 13, 0, 9, 134, 7, 195, 161, 18, 4, 1, 13, 15, 140, 22, 195, 161, 19, 195, 161, 18, 15, 12, 14, 1, 11, 13, 10, 199, 53, 83, 139, 4, 129, 76, 100, 13, 10, 135, 19, 26, 195, 161, 13, 15, 12, 13, 12, 137, 22, 195, 182, 12, 7, 25, 2, 5, 14, 13, 19, 134, 12, 195, 161, 20, 20, 1, 13, 81, 112, 101, 116, 197, 145, 102, 105, 116, 32, 6, 195, 21, 33, 68, 13, 14, 139, 18, 1, 14, 7, 10, 1, 9, 20, 195, 179, 12, 13, 9, 134, 195, 169, 18, 26, 5, 13, 13, 9, 134, 12, 195, 161, 20, 20, 1, 13, 6, 131, 195, 188, 12, 13, 6, 195, 80, 83, 20, 13, 0, 11, 200, 9, 81, 1, 64, 84, 212, 20, 224, 13, 0, 12, 137, 16, 15, 19, 26, 20, 18, 195, 179, 12, 13, 12, 137, 13, 195, 186, 12, 20, 18, 195, 179, 12, 13, 16, 141, 11, 15, 12, 12, 195, 169, 7, 195, 161, 9, 22, 1, 12, 13, 13, 138, 18, 5, 14, 4, 197, 145, 18, 14, 5, 11, 13, 8, 197, 24, 241, 207, 81, 64, 13, 13, 138, 195, 173, 20, 195, 169, 12, 20, 195, 169, 11, 13, 0, 15, 140, 6, 5, 12, 2, 15, 14, 20, 195, 161, 19, 195, 186, 13, 17, 142, 195, 169, 18, 20, 5, 19, 195, 173, 20, 197, 145, 22, 5, 12, 13, 7, 132, 10, 195, 182, 14, 13, 7, 132, 8, 195, 182, 26, 13, 13, 4, 95, 1, 3, 50, 49, 109, 47, 12, 118, 91, 0, 0, 18, 143, 9, 12, 12, 5, 20, 195, 169, 11, 5, 19, 195, 169, 22, 5, 12, 13, 10, 135, 12, 195, 161, 20, 195, 179, 20, 13, 18, 143, 19, 5, 7, 195, 173, 20, 19, 195, 169, 7, 195, 169, 22, 5, 12, 13, 13, 138, 5, 12, 13, 5, 19, 195, 169, 12, 20, 5, 13, 6, 195, 88, 145, 4, 13, 0, 19, 144, 11, 195, 182, 26, 195, 182, 19, 19, 195, 169, 7, 195, 169, 22, 5, 12, 13, 14, 139, 11, 18, 9, 20, 9, 26, 195, 161, 12, 20, 1, 13, 0, 11, 136, 19, 26, 195, 161, 12, 12, 14, 9, 13, 9, 198, 4, 64, 75, 61, 162, 75, 13, 17, 142, 11, 15, 14, 3, 5, 14, 20, 18, 195, 161, 12, 14, 1, 11, 13, 17, 142, 8, 1, 10, 12, 195, 169, 11, 20, 1, 12, 1, 14, 15, 11, 13, 0, 9, 198, 77, 160, 66, 61, 69, 0, 13, 23, 148, 8, 15, 26, 26, 195, 161, 10, 195, 161, 18, 21, 12, 195, 161, 19, 15, 11, 2, 1, 14, 13, 9, 134, 195, 169, 18, 26, 5, 4, 13, 5, 194, 72, 80, 13, 9, 66, 60, 176, 39, 49, 0, 42, 42, 11, 67, 52, 148, 211, 65, 37, 89, 12, 0, 25, 0, 10, 135, 19, 26, 195, 161, 13, 15, 20, 13, 0, 16, 141, 195, 169, 18, 20, 195, 169, 11, 5, 12, 10, 195, 188, 11, 13, 6, 195, 76, 242, 1, 13, 15, 140, 22, 9, 26, 19, 7, 195, 161, 12, 1, 20, 15, 20, 13, 0, 8, 197, 81, 81, 20, 84, 176, 13, 20, 145, 11, 195, 169, 19, 26, 195, 188, 12, 195, 169, 11, 5, 11, 14, 195, 169, 12, 13, 10, 135, 13, 21, 19, 26, 195, 161, 10, 13, 15, 140, 2, 9, 26, 15, 14, 25, 195, 173, 20, 1, 14, 9, 13, 8, 197, 52, 20, 139, 60, 208, 13, 0, 9, 198, 80, 82, 5, 80, 82, 192, 13, 0, 6, 195, 60, 181, 0, 20, 0, 15, 140, 19, 26, 1, 2, 195, 161, 12, 25, 26, 195, 179, 20, 13, 0, 40, 69, 56, 85, 133, 104, 144, 50, 109, 84, 109, 88, 37, 23, 47, 40, 55, 108, 57, 72, 39, 50, 39, 91, 108, 0, 13, 81, 116, 117, 108, 97, 106, 100, 111, 110, 111, 115, 97, 32, 30, 67, 21, 161, 82, 109, 88, 109, 52, 23, 83, 39, 52, 37, 50, 47, 39, 47, 0, 13, 81, 102, 111, 114, 105, 110, 116, 111, 116, 32, 26, 67, 21, 161, 82, 109, 88, 109, 52, 23, 83, 39, 52, 37, 50, 47, 0, 13, 81, 102, 111, 114, 105, 110, 116, 32, 8, 197, 40, 81, 217, 20, 144, 13, 16, 141, 6, 195, 188, 7, 7, 5, 20, 12, 5, 14, 195, 188, 12, 13, 9, 198, 80, 82, 5, 80, 225, 75, 13, 9, 198, 48, 82, 5, 80, 225, 75, 13, 0, 15, 3, 95, 203, 135, 55, 109, 83, 109, 55, 113, 67, 112, 55, 0, 9, 198, 29, 144, 75, 61, 34, 64, 13, 0, 14, 139, 195, 169, 18, 4, 5, 11, 5, 9, 22, 5, 12, 13, 14, 139, 5, 12, 197, 145, 6, 15, 18, 4, 21, 12, 20, 13, 15, 140, 11, 195, 182, 22, 5, 20, 11, 5, 26, 14, 5, 11, 13, 18, 4, 95, 56, 48, 15, 67, 39, 55, 119, 84, 108, 50, 108, 72, 37, 49, 0, 0, 11, 200, 40, 83, 12, 20, 209, 90, 80, 80, 13, 33, 68, 52, 17, 193, 16, 65, 108, 81, 108, 72, 23, 109, 79, 109, 50, 109, 91, 109, 50, 0, 13, 81, 101, 103, 121, 101, 110, 101, 115, 101, 110, 32, 14, 139, 11, 9, 2, 195, 169, 11, 195, 188, 12, 22, 5, 13, 15, 140, 11, 9, 1, 4, 195, 161, 19, 195, 161, 22, 1, 12, 13, 11, 200, 77, 163, 198, 81, 97, 82, 20, 144, 13, 7, 196, 52, 17, 193, 16, 13, 0, 12, 3, 95, 194, 186, 91, 39, 34, 89, 114, 65, 0, 9, 134, 20, 15, 10, 195, 161, 19, 13, 0, 23, 3, 95, 194, 187, 71, 109, 55, 91, 118, 57, 39, 71, 71, 37, 72, 113, 88, 118, 57, 109, 55, 0, 17, 142, 20, 1, 18, 20, 15, 26, 195, 169, 11, 195, 161, 22, 1, 12, 13, 37, 9, 6, 15, 18, 4, 195, 173, 20, 22, 1, 83, 39, 52, 72, 112, 47, 84, 108, 23, 108, 6, 23, 89, 115, 47, 0, 13, 82, 97, 32, 115, 122, 195, 179, 116, 32, 13, 138, 22, 195, 161, 12, 20, 15, 26, 15, 20, 20, 13, 12, 137, 10, 195, 161, 20, 19, 26, 1, 14, 1, 13, 15, 140, 6, 15, 18, 13, 195, 161, 10, 195, 161, 2, 1, 14, 13, 0, 0, 16, 3, 95, 194, 185, 109, 55, 89, 118, 107, 108, 47, 84, 114, 67, 0, 17, 142, 20, 195, 161, 18, 19, 1, 4, 1, 12, 15, 13, 2, 1, 14, 13, 19, 144, 13, 5, 3, 8, 1, 14, 9, 26, 13, 21, 19, 195, 161, 22, 1, 12, 13, 0, 53, 10, 19, 26, 5, 13, 195, 169, 12, 25, 5, 19, 89, 109, 65, 113, 57, 109, 91, 23, 71, 109, 114, 55, 12, 37, 47, 114, 91, 39, 49, 108, 47, 0, 13, 81, 98, 101, 195, 161, 108, 108, 195, 173, 116, 195, 161, 115, 111, 107, 97, 116, 32, 15, 140, 22, 195, 169, 12, 5, 13, 195, 169, 14, 25, 5, 13, 13, 11, 136, 10, 5, 12, 12, 5, 7, 197, 177, 13, 9, 198, 53, 85, 1, 80, 224, 75, 13, 0, 10, 67, 56, 21, 15, 50, 114, 47, 115, 0, 21, 146, 22, 195, 169, 7, 18, 5, 8, 1, 10, 20, 195, 161, 19, 195, 161, 22, 1, 12, 13, 14, 139, 13, 5, 7, 14, 195, 169, 26, 26, 195, 188, 11, 13, 10, 135, 18, 195, 179, 12, 21, 14, 11, 13, 0, 7, 131, 195, 186, 20, 20, 13, 0, 6, 195, 32, 83, 25, 13, 23, 148, 8, 15, 26, 26, 195, 161, 10, 195, 161, 18, 21, 12, 195, 161, 19, 195, 161, 22, 1, 12, 13, 6, 195, 32, 83, 25, 13, 6, 195, 32, 83, 25, 13, 0, 45, 8, 195, 169, 18, 9, 14, 20, 197, 145, 113, 52, 37, 50, 47, 118, 23, 49, 113, 52, 72, 113, 91, 109, 49, 71, 109, 50, 0, 13, 81, 107, 195, 169, 114, 100, 195, 169, 115, 101, 107, 98, 101, 110, 32, 35, 69, 32, 83, 25, 20, 224, 107, 109, 57, 109, 50, 23, 49, 37, 107, 108, 79, 12, 114, 49, 0, 13, 81, 107, 105, 104, 97, 103, 121, 106, 195, 161, 107, 32, 45, 8, 195, 169, 18, 9, 14, 20, 197, 145, 113, 52, 37, 50, 47, 118, 23, 83, 52, 37, 91, 12, 112, 47, 113, 91, 109, 49, 0, 13, 81, 102, 114, 105, 115, 115, 195, 173, 116, 195, 169, 115, 101, 107, 32, 15, 140, 8, 9, 22, 1, 20, 1, 12, 15, 19, 19, 195, 161, 13, 11, 136, 195, 169, 18, 9, 14, 20, 197, 145, 13, 8, 197, 32, 83, 25, 20, 224, 13, 10, 135, 13, 5, 14, 20, 195, 169, 14, 13, 6, 131, 195, 186, 18, 13, 0, 12, 137, 11, 5, 22, 5, 18, 195, 169, 11, 5, 13, 14, 139, 14, 195, 182, 22, 5, 11, 5, 4, 195, 169, 19, 13, 14, 139, 14, 5, 21, 18, 15, 12, 195, 179, 7, 21, 19, 13, 10, 135, 22, 195, 161, 18, 14, 1, 11, 13, 10, 135, 10, 195, 161, 18, 14, 1, 11, 13, 10, 135, 14, 195, 169, 26, 14, 5, 11, 13, 8, 133, 18, 195, 179, 12, 1, 13, 14, 6, 95, 35, 45, 22, 1, 12, 114, 84, 108, 55, 0, 21, 0, 9, 198, 24, 83, 12, 20, 195, 137, 13, 17, 142, 10, 5, 12, 5, 14, 20, 197, 145, 19, 195, 169, 7, 197, 177, 13, 0, 13, 138, 197, 145, 19, 26, 9, 14, 20, 195, 169, 14, 13, 30, 10, 8, 1, 19, 26, 14, 195, 161, 12, 19, 26, 107, 108, 89, 50, 114, 55, 89, 15, 83, 109, 55, 0, 13, 81, 102, 101, 108, 32, 13, 138, 8, 1, 19, 26, 14, 195, 161, 12, 19, 26, 13, 14, 139, 195, 169, 16, 195, 173, 20, 195, 169, 19, 197, 177, 13, 7, 132, 195, 169, 10, 20, 13, 15, 8, 95, 35, 45, 195, 161, 22, 1, 12, 114, 84, 108, 55, 0, 15, 8, 95, 35, 45, 195, 169, 22, 5, 12, 113, 84, 109, 55, 0, 0, 11, 2, 195, 151, 47, 108, 55, 48, 108, 91, 0, 9, 198, 48, 85, 20, 21, 65, 75, 13, 10, 135, 20, 1, 14, 4, 195, 173, 10, 13, 8, 197, 24, 145, 217, 20, 192, 13, 12, 201, 57, 146, 76, 5, 66, 207, 105, 64, 64, 13, 14, 139, 195, 161, 12, 12, 1, 13, 15, 11, 2, 1, 14, 13, 0, 16, 141, 6, 5, 10, 12, 5, 19, 26, 20, 195, 169, 19, 197, 177, 13, 13, 138, 8, 15, 18, 4, 195, 161, 9, 22, 1, 12, 13, 47, 10, 9, 4, 197, 145, 14, 11, 195, 169, 14, 20, 37, 72, 118, 50, 49, 113, 50, 47, 23, 108, 6, 15, 83, 109, 55, 107, 118, 88, 109, 47, 0, 13, 82, 97, 32, 102, 101, 108, 104, 197, 145, 122, 101, 116, 32, 11, 136, 14, 5, 22, 195, 169, 2, 5, 14, 13, 14, 139, 20, 195, 182, 18, 5, 11, 5, 4, 14, 5, 11, 13, 10, 135, 22, 195, 161, 12, 14, 1, 11, 13, 0, 16, 141, 5, 12, 13, 195, 169, 12, 5, 20, 5, 11, 2, 5, 14, 13, 12, 137, 12, 1, 16, 10, 195, 161, 2, 1, 14, 13, 12, 137, 19, 26, 15, 2, 195, 161, 2, 1, 14, 13, 12, 137, 20, 195, 169, 13, 195, 161, 2, 1, 14, 13, 14, 139, 9, 18, 195, 161, 14, 25, 195, 161, 22, 1, 12, 13, 0, 6, 195, 88, 149, 1, 13, 15, 140, 19, 26, 195, 182, 22, 5, 7, 195, 169, 22, 5, 12, 13, 13, 138, 21, 4, 22, 1, 18, 195, 161, 2, 1, 14, 13, 12, 201, 40, 83, 5, 57, 66, 197, 105, 65, 75, 13, 7, 132, 4, 195, 186, 12, 13, 0, 14, 139, 5, 7, 195, 169, 19, 26, 195, 169, 2, 5, 14, 13, 16, 141, 11, 9, 22, 195, 169, 20, 5, 12, 195, 169, 22, 5, 12, 13, 0, 26, 70, 56, 85, 133, 105, 65, 64, 50, 109, 84, 109, 89, 47, 109, 23, 108, 89, 47, 0, 13, 81, 97, 122, 116, 32, 17, 142, 11, 195, 173, 14, 195, 161, 12, 1, 20, 195, 161, 22, 1, 12, 13, 26, 70, 56, 85, 133, 105, 65, 64, 50, 109, 84, 109, 89, 47, 109, 23, 65, 109, 81, 0, 13, 81, 109, 101, 103, 32, 19, 144, 20, 195, 161, 18, 7, 25, 1, 12, 195, 161, 19, 15, 11, 2, 1, 14, 13, 10, 135, 20, 1, 14, 21, 12, 195, 179, 13, 9, 198, 56, 85, 133, 105, 65, 64, 13, 9, 198, 8, 194, 75, 45, 33, 64, 13, 10, 135, 13, 195, 169, 12, 20, 195, 179, 13, 9, 198, 80, 20, 148, 61, 69, 0, 13, 8, 133, 6, 195, 169, 14, 25, 13, 0, 18, 143, 8, 1, 19, 26, 14, 195, 161, 12, 1, 20, 195, 161, 22, 1, 12, 13, 15, 140, 2, 9, 26, 15, 14, 25, 195, 173, 20, 195, 169, 11, 13, 18, 143, 2, 5, 13, 21, 20, 1, 20, 195, 161, 19, 195, 161, 22, 1, 12, 13, 11, 136, 195, 169, 18, 20, 10, 195, 188, 11, 13, 6, 195, 12, 243, 20, 13, 0, 12, 201, 57, 146, 76, 5, 66, 207, 105, 64, 75, 13, 19, 144, 5, 12, 15, 19, 26, 12, 1, 20, 195, 161, 19, 195, 161, 22, 1, 12, 13, 19, 144, 1, 12, 11, 1, 12, 13, 1, 26, 195, 161, 19, 195, 161, 22, 1, 12, 13, 32, 67, 32, 85, 5, 107, 109, 47, 109, 23, 107, 108, 89, 50, 114, 55, 39, 65, 0, 13, 81, 104, 97, 115, 122, 110, 195, 161, 108, 111, 109, 32, 11, 136, 6, 18, 9, 19, 19, 195, 188, 12, 13, 17, 142, 5, 12, 12, 195, 161, 20, 195, 161, 19, 195, 161, 2, 1, 14, 13, 15, 140, 12, 195, 169, 16, 195, 169, 19, 11, 195, 169, 14, 20, 13, 0, 11, 2, 194, 167, 89, 6, 108, 49, 108, 89, 0, 9, 2, 195, 159, 21, 100, 101, 0, 10, 32, 69, 81, 81, 15, 81, 64, 47, 40, 72, 39, 47, 12, 23, 48, 37, 107, 109, 50, 12, 37, 0, 13, 81, 112, 105, 104, 101, 110, 110, 105, 32, 18, 143, 20, 5, 19, 26, 20, 5, 12, 195, 169, 19, 195, 169, 2, 5, 14, 13, 20, 145, 11, 15, 18, 12, 195, 161, 20, 15, 26, 195, 161, 19, 195, 161, 22, 1, 12, 13, 9, 198, 20, 195, 69, 57, 66, 75, 13, 9, 198, 80, 82, 201, 57, 66, 75, 13, 8, 197, 81, 81, 15, 81, 64, 13, 0, 22, 66, 76, 80, 91, 109, 23, 71, 112, 52, 39, 65, 0, 13, 81, 98, 195, 173, 114, 111, 109, 32, 21, 66, 76, 80, 91, 109, 23, 49, 108, 48, 50, 37, 0, 13, 81, 107, 97, 112, 110, 105, 32, 29, 66, 76, 80, 91, 109, 23, 113, 52, 47, 109, 47, 12, 113, 49, 0, 13, 81, 195, 169, 114, 116, 101, 116, 116, 195, 169, 107, 32, 24, 66, 76, 80, 91, 109, 10, 6, 15, 47, 52, 113, 83, 108, 0, 13, 81, 116, 114, 195, 169, 102, 97, 32, 27, 66, 76, 80, 91, 109, 23, 76, 37, 50, 114, 55, 39, 49, 0, 13, 81, 99, 115, 105, 110, 195, 161, 108, 111, 107, 32, 23, 66, 76, 80, 91, 109, 23, 84, 109, 47, 12, 109, 65, 0, 13, 81, 118, 101, 116, 116, 101, 109, 32, 12, 137, 11, 195, 182, 26, 195, 182, 20, 20, 9, 13, 5, 194, 56, 240, 72, 5, 194, 76, 80, 13, 0, 0, 9, 198, 20, 209, 76, 21, 65, 78, 13, 11, 200, 40, 21, 129, 76, 192, 84, 61, 64, 13, 11, 200, 32, 20, 207, 56, 192, 84, 61, 64, 13, 0, 8, 197, 88, 243, 20, 4, 176, 13, 0, 12, 137, 10, 195, 161, 20, 19, 26, 1, 14, 9, 13, 13, 138, 8, 9, 18, 4, 5, 20, 14, 195, 169, 4, 13, 10, 135, 11, 195, 169, 18, 14, 5, 11, 13, 0, 10, 135, 9, 4, 197, 145, 22, 5, 12, 13, 10, 199, 72, 81, 201, 77, 165, 5, 72, 13, 9, 134, 12, 195, 169, 20, 18, 5, 13, 0, 14, 2, 194, 174, 71, 109, 57, 109, 79, 88, 109, 47, 12, 0, 5, 130, 195, 166, 43, 35, 68, 32, 246, 142, 4, 107, 39, 88, 50, 108, 23, 65, 109, 81, 39, 55, 72, 114, 91, 47, 0, 13, 81, 109, 101, 103, 111, 108, 100, 195, 161, 115, 116, 32, 12, 137, 195, 169, 12, 22, 5, 26, 14, 5, 11, 13, 28, 4, 195, 169, 12, 20, 113, 55, 47, 6, 23, 91, 39, 49, 114, 37, 81, 0, 13, 81, 115, 111, 107, 195, 161, 105, 103, 32, 12, 137, 11, 5, 18, 195, 188, 12, 14, 5, 11, 13, 9, 134, 6, 195, 169, 12, 19, 26, 13, 7, 132, 195, 169, 12, 20, 13, 0, 5, 130, 195, 167, 43, 29, 7, 19, 26, 195, 179, 12, 19, 26, 89, 115, 55, 89, 23, 107, 39, 88, 88, 114, 0, 13, 81, 104, 111, 122, 122, 195, 161, 32, 8, 197, 32, 17, 217, 88, 16, 13, 9, 198, 32, 148, 218, 37, 65, 75, 13, 10, 135, 19, 26, 195, 179, 12, 19, 26, 13, 17, 3, 21, 46, 14, 116, 79, 50, 109, 84, 109, 88, 109, 47, 12, 0, 25, 17, 3, 195, 186, 14, 116, 79, 50, 109, 84, 109, 88, 109, 47, 12, 0, 25, 0, 15, 2, 194, 172, 55, 39, 81, 37, 49, 108, 37, 50, 109, 65, 0, 5, 130, 195, 164, 43, 9, 134, 195, 169, 20, 5, 12, 20, 13, 43, 8, 195, 186, 10, 15, 14, 14, 1, 14, 116, 57, 39, 50, 12, 108, 50, 23, 47, 109, 55, 109, 48, 112, 47, 109, 47, 12, 0, 13, 81, 116, 101, 108, 101, 112, 195, 173, 116, 101, 116, 116, 32, 9, 198, 80, 84, 150, 21, 162, 64, 13, 9, 198, 32, 19, 12, 41, 82, 192, 13, 10, 135, 2, 195, 186, 10, 14, 1, 11, 13, 10, 135, 22, 5, 20, 20, 195, 169, 11, 13, 15, 140, 8, 1, 20, 195, 179, 1, 14, 25, 1, 7, 195, 186, 13, 10, 135, 22, 9, 20, 20, 195, 169, 11, 13, 9, 198, 80, 21, 129, 77, 162, 64, 20, 0, 9, 135, 5, 7, 25, 195, 188, 20, 20, 24, 67, 48, 85, 20, 55, 109, 47, 12, 23, 84, 39, 55, 50, 108, 0, 13, 81, 118, 111, 108, 110, 97, 32, 22, 67, 48, 85, 20, 55, 109, 47, 12, 23, 81, 39, 50, 72, 0, 13, 81, 103, 111, 110, 100, 32, 6, 195, 48, 85, 20, 13, 0, 7, 196, 72, 149, 11, 4, 13, 14, 139, 195, 173, 20, 195, 169, 12, 20, 5, 20, 22, 5, 13, 24, 68, 56, 82, 197, 16, 50, 109, 49, 109, 72, 15, 49, 109, 55, 12, 0, 13, 81, 107, 101, 108, 108, 32, 36, 72, 77, 163, 198, 81, 97, 82, 20, 176, 89, 39, 83, 47, 84, 109, 52, 109, 49, 15, 108, 52, 114, 67, 108, 0, 13, 81, 97, 114, 195, 161, 110, 121, 97, 32, 10, 135, 19, 26, 195, 179, 12, 22, 1, 13, 7, 196, 56, 82, 197, 16, 13, 0, 28, 3, 195, 186, 10, 116, 57, 10, 6, 15, 108, 71, 55, 108, 49, 39, 47, 0, 13, 81, 97, 98, 108, 97, 107, 111, 116, 32, 31, 3, 195, 186, 10, 116, 57, 23, 65, 109, 81, 39, 55, 72, 114, 91, 47, 0, 13, 81, 109, 101, 103, 111, 108, 100, 195, 161, 115, 116, 32, 31, 69, 8, 150, 148, 61, 48, 71, 37, 89, 47, 39, 91, 23, 89, 109, 52, 37, 50, 47, 0, 13, 81, 115, 122, 101, 114, 105, 110, 116, 32, 21, 3, 195, 186, 10, 116, 57, 15, 108, 57, 47, 115, 0, 13, 81, 97, 106, 116, 195, 179, 32, 8, 197, 8, 150, 148, 61, 48, 13, 8, 133, 195, 173, 22, 5, 20, 13, 6, 131, 195, 186, 10, 13, 0, 15, 140, 16, 15, 12, 9, 20, 9, 11, 195, 161, 2, 1, 14, 13, 14, 139, 8, 9, 195, 161, 14, 25, 15, 26, 14, 1, 11, 13, 13, 138, 22, 5, 18, 26, 9, 195, 179, 22, 1, 12, 13, 12, 138, 22, 5, 18, 26, 9, 195, 179, 22, 1, 12, 16, 141, 9, 14, 20, 15, 14, 195, 161, 3, 9, 195, 179, 10, 1, 13, 9, 198, 80, 84, 150, 21, 161, 84, 13, 11, 136, 9, 14, 1, 11, 20, 195, 173, 22, 13, 15, 140, 12, 9, 19, 20, 195, 161, 10, 195, 161, 2, 1, 14, 13, 15, 140, 8, 5, 12, 25, 19, 26, 195, 173, 14, 195, 169, 14, 13, 16, 141, 19, 26, 5, 13, 12, 195, 169, 12, 20, 5, 20, 22, 5, 13, 11, 136, 20, 5, 19, 20, 22, 195, 169, 18, 13, 0, 18, 2, 194, 169, 119, 39, 48, 37, 52, 37, 81, 107, 47, 20, 57, 109, 55, 0, 10, 199, 13, 51, 205, 4, 113, 193, 48, 13, 0, 13, 2, 194, 182, 71, 109, 49, 109, 88, 72, 113, 91, 0, 11, 136, 16, 21, 19, 26, 20, 195, 173, 20, 13, 7, 196, 52, 17, 193, 52, 13, 7, 132, 4, 195, 188, 8, 13, 0, 13, 138, 18, 5, 13, 195, 169, 12, 10, 195, 188, 11, 13, 44, 8, 11, 15, 18, 195, 161, 2, 2, 9, 49, 39, 52, 114, 71, 12, 37, 23, 109, 55, 49, 113, 48, 88, 109, 55, 113, 91, 0, 13, 81, 101, 108, 107, 195, 169, 112, 122, 101, 108, 195, 169, 115, 32, 12, 137, 13, 195, 169, 18, 5, 20, 195, 169, 20, 13, 0, 17, 142, 195, 169, 20, 5, 12, 8, 15, 18, 4, 195, 179, 22, 1, 12, 13, 14, 139, 8, 1, 14, 7, 10, 5, 12, 26, 195, 169, 19, 13, 10, 135, 12, 195, 169, 16, 195, 169, 19, 13, 12, 137, 13, 195, 169, 18, 20, 195, 169, 11, 5, 13, 9, 198, 56, 85, 133, 104, 85, 20, 13, 10, 135, 11, 5, 12, 20, 195, 169, 19, 13, 5, 194, 60, 224, 13, 13, 66, 64, 192, 48, 113, 55, 72, 114, 40, 55, 0, 25, 0, 7, 2, 194, 181, 65, 117, 0, 6, 195, 4, 176, 68, 13, 9, 134, 6, 195, 169, 18, 6, 9, 13, 11, 136, 11, 195, 169, 18, 4, 195, 169, 19, 13, 0, 16, 141, 5, 12, 197, 145, 18, 5, 10, 5, 12, 26, 195, 169, 19, 13, 7, 196, 8, 195, 203, 44, 13, 14, 139, 13, 9, 14, 197, 145, 19, 195, 169, 7, 197, 177, 13, 9, 134, 6, 1, 12, 195, 161, 14, 13, 8, 133, 19, 26, 197, 177, 11, 13, 9, 196, 33, 49, 16, 4, 17, 42, 42, 0, 15, 140, 13, 5, 14, 14, 25, 9, 19, 195, 169, 7, 197, 177, 13, 30, 5, 11, 195, 161, 18, 20, 49, 114, 52, 47, 10, 6, 15, 39, 49, 39, 88, 50, 108, 0, 13, 81, 111, 107, 111, 122, 110, 97, 32, 16, 141, 20, 195, 182, 18, 20, 195, 169, 14, 5, 20, 195, 169, 20, 13, 8, 133, 5, 12, 197, 145, 12, 13, 10, 135, 12, 9, 19, 20, 195, 161, 14, 13, 9, 134, 1, 4, 10, 195, 161, 11, 13, 8, 133, 5, 12, 197, 145, 12, 13, 8, 133, 11, 195, 161, 18, 20, 13, 8, 133, 6, 195, 186, 10, 20, 13, 8, 133, 5, 12, 197, 145, 12, 13, 0, 8, 2, 194, 176, 83, 39, 49, 0, 11, 2, 194, 176, 83, 39, 49, 57, 109, 55, 0, 0, 14, 2, 194, 177, 48, 55, 40, 89, 65, 37, 50, 40, 89, 0, 5, 130, 195, 169, 14, 38, 70, 24, 244, 137, 57, 64, 129, 83, 39, 52, 37, 50, 47, 71, 108, 23, 49, 109, 52, 111, 55, 50, 109, 49, 0, 13, 81, 107, 101, 114, 195, 188, 108, 110, 101, 107, 32, 12, 137, 16, 1, 12, 5, 20, 20, 195, 161, 14, 13, 9, 134, 12, 195, 161, 20, 15, 13, 13, 11, 136, 13, 15, 14, 4, 10, 195, 161, 11, 13, 5, 130, 195, 169, 72, 0, 15, 2, 194, 190, 107, 114, 52, 39, 65, 50, 109, 79, 109, 72, 0, 12, 137, 22, 9, 20, 1, 20, 10, 195, 161, 11, 13, 9, 134, 3, 195, 169, 12, 195, 186, 13, 7, 132, 195, 182, 14, 20, 13, 0, 10, 2, 195, 183, 39, 89, 47, 114, 91, 0, 13, 138, 9, 7, 1, 26, 15, 12, 10, 195, 161, 11, 13, 13, 138, 11, 9, 8, 1, 7, 25, 10, 195, 161, 11, 13, 12, 137, 19, 26, 195, 179, 12, 20, 195, 161, 12, 13, 13, 138, 20, 195, 161, 13, 1, 4, 10, 195, 161, 11, 13, 12, 137, 16, 21, 12, 195, 179, 22, 5, 18, 20, 13, 8, 133, 2, 195, 169, 18, 20, 13, 8, 197, 32, 149, 20, 20, 64, 13, 13, 138, 12, 195, 161, 20, 19, 26, 15, 20, 15, 11, 13, 0, 10, 2, 194, 188, 50, 109, 79, 109, 72, 0, 8, 133, 19, 26, 195, 161, 13, 13, 9, 134, 5, 2, 2, 197, 145, 12, 13, 0, 8, 2, 194, 189, 83, 113, 55, 0, 6, 195, 81, 81, 4, 13, 54, 71, 81, 83, 1, 40, 67, 206, 80, 47, 40, 55, 108, 57, 72, 39, 50, 47, 23, 84, 113, 72, 118, 23, 47, 110, 52, 84, 113, 67, 109, 49, 0, 13, 82, 118, 195, 169, 100, 197, 145, 32, 116, 195, 182, 114, 118, 195, 169, 110, 121, 101, 107, 32, 15, 140, 22, 9, 26, 19, 7, 195, 161, 12, 10, 195, 161, 11, 13, 15, 140, 1, 12, 11, 1, 12, 13, 1, 26, 26, 195, 161, 11, 13, 11, 136, 18, 195, 186, 7, 20, 195, 161, 11, 13, 11, 136, 13, 15, 14, 4, 20, 195, 161, 11, 13, 0, 46, 5, 195, 169, 22, 9, 7, 113, 84, 37, 81, 23, 55, 109, 89, 23, 47, 114, 65, 39, 81, 108, 47, 39, 47, 12, 0, 13, 82, 108, 101, 115, 122, 32, 116, 195, 161, 109, 111, 103, 97, 116, 111, 116, 116, 32, 13, 138, 12, 195, 169, 16, 8, 5, 19, 19, 5, 14, 13, 11, 136, 20, 5, 18, 22, 2, 197, 145, 12, 13, 8, 133, 19, 18, 195, 161, 3, 13, 14, 4, 95, 3, 5, 4, 119, 113, 72, 37, 55, 55, 109, 0, 19, 67, 88, 146, 73, 67, 39, 55, 119, 12, 108, 55, 0, 44, 42, 81, 97, 108, 32, 0, 37, 10, 8, 1, 10, 20, 15, 20, 20, 195, 161, 11, 107, 108, 57, 47, 39, 47, 12, 114, 49, 23, 84, 113, 81, 52, 109, 0, 13, 81, 118, 195, 169, 103, 114, 101, 32, 13, 138, 7, 15, 14, 4, 15, 12, 20, 195, 161, 11, 13, 47, 69, 20, 208, 133, 73, 64, 109, 65, 71, 109, 52, 47, 23, 49, 37, 65, 109, 50, 109, 49, 112, 47, 109, 47, 12, 109, 49, 0, 13, 81, 107, 105, 109, 101, 110, 101, 107, 195, 173, 116, 101, 116, 116, 101, 107, 32, 37, 6, 22, 9, 12, 195, 161, 7, 84, 37, 55, 114, 81, 15, 72, 37, 76, 118, 91, 113, 81, 109, 0, 13, 81, 100, 105, 99, 115, 197, 145, 115, 195, 169, 103, 101, 32, 13, 138, 20, 195, 161, 13, 1, 4, 20, 195, 161, 11, 13, 8, 197, 80, 149, 11, 61, 64, 13, 13, 138, 20, 1, 18, 20, 15, 20, 20, 195, 161, 11, 13, 0, 9, 198, 32, 149, 129, 80, 19, 20, 13, 0, 5, 130, 195, 177, 43, 22, 148, 1, 11, 1, 4, 195, 161, 12, 25, 13, 5, 14, 20, 5, 19, 195, 173, 20, 195, 169, 19, 13, 138, 7, 15, 13, 2, 15, 12, 14, 195, 161, 13, 13, 14, 139, 18, 195, 169, 19, 26, 195, 169, 2, 197, 145, 12, 13, 42, 8, 1, 12, 1, 16, 21, 12, 195, 179, 108, 55, 108, 48, 40, 55, 115, 23, 47, 110, 52, 47, 113, 50, 109, 47, 109, 0, 13, 81, 116, 195, 182, 114, 116, 195, 169, 110, 101, 116, 101, 32, 13, 138, 20, 9, 19, 26, 20, 5, 12, 197, 145, 9, 13, 14, 203, 80, 20, 1, 77, 165, 1, 48, 21, 20, 4, 192, 13, 9, 198, 80, 84, 150, 21, 165, 133, 13, 8, 133, 19, 20, 195, 161, 2, 13, 15, 4, 95, 12, 9, 7, 55, 37, 81, 108, 47, 116, 52, 108, 0, 0, 34, 8, 10, 5, 12, 26, 195, 169, 19, 20, 57, 109, 55, 88, 113, 91, 47, 10, 6, 15, 108, 72, 50, 108, 49, 0, 13, 81, 97, 100, 110, 97, 107, 32, 9, 134, 26, 195, 161, 16, 15, 18, 13, 10, 135, 195, 161, 12, 12, 14, 9, 1, 13, 0, 11, 136, 4, 195, 182, 14, 20, 5, 14, 9, 13, 9, 134, 19, 1, 10, 20, 195, 179, 13, 8, 133, 19, 26, 195, 161, 4, 13, 6, 195, 88, 19, 0, 13, 0, 40, 15, 195, 161, 12, 12, 1, 16, 195, 173, 20, 15, 20, 20, 195, 161, 11, 114, 55, 12, 108, 48, 112, 47, 39, 47, 12, 114, 49, 23, 65, 109, 81, 0, 13, 81, 109, 101, 103, 32, 9, 198, 64, 20, 129, 77, 165, 0, 13, 9, 198, 44, 83, 20, 21, 69, 0, 13, 9, 134, 20, 195, 169, 7, 5, 4, 13, 5, 194, 80, 80, 13, 0, 21, 5, 195, 169, 22, 5, 14, 113, 84, 109, 50, 23, 114, 47, 0, 13, 81, 195, 161, 116, 32, 13, 138, 5, 12, 4, 195, 182, 14, 20, 5, 14, 9, 13, 15, 140, 11, 9, 22, 5, 20, 14, 9, 22, 1, 12, 195, 179, 13, 18, 67, 88, 146, 64, 107, 113, 47, 12, 109, 55, 0, 44, 42, 81, 101, 108, 32, 0, 10, 135, 11, 195, 182, 20, 14, 9, 5, 13, 11, 200, 52, 147, 137, 77, 165, 5, 73, 64, 13, 0, 8, 197, 88, 243, 20, 4, 208, 72, 8, 197, 64, 84, 131, 72, 80, 22, 28, 67, 4, 176, 82, 108, 49, 108, 52, 23, 84, 108, 55, 108, 65, 37, 47, 0, 13, 81, 118, 97, 108, 97, 109, 105, 116, 32, 20, 145, 2, 5, 18, 5, 14, 4, 5, 26, 11, 5, 4, 195, 169, 19, 19, 5, 12, 13, 28, 69, 32, 18, 148, 40, 16, 107, 108, 57, 80, 108, 23, 84, 113, 81, 52, 109, 0, 13, 81, 118, 195, 169, 103, 114, 101, 32, 36, 13, 18, 5, 14, 4, 5, 12, 11, 5, 26, 195, 169, 19, 20, 51, 109, 50, 72, 109, 55, 49, 109, 88, 113, 91, 47, 23, 37, 91, 0, 13, 81, 105, 115, 32, 34, 67, 4, 176, 82, 108, 49, 108, 52, 10, 6, 15, 108, 6, 15, 79, 114, 52, 47, 115, 0, 13, 82, 97, 32, 103, 121, 195, 161, 114, 116, 195, 179, 32, 43, 69, 88, 243, 148, 4, 176, 84, 39, 50, 47, 108, 49, 23, 83, 109, 55, 109, 55, 118, 91, 113, 81, 51, 109, 0, 13, 81, 102, 101, 108, 101, 108, 197, 145, 115, 115, 195, 169, 103, 114, 101, 32, 29, 67, 4, 176, 82, 108, 6, 49, 108, 52, 23, 65, 108, 52, 108, 72, 50, 37, 0, 13, 81, 109, 97, 114, 97, 100, 110, 105, 32, 8, 197, 88, 243, 20, 4, 208, 13, 8, 197, 32, 20, 131, 60, 176, 13, 12, 201, 88, 148, 197, 48, 177, 68, 21, 69, 0, 13, 10, 135, 3, 5, 12, 12, 195, 161, 14, 13, 7, 132, 195, 169, 22, 1, 13, 8, 197, 40, 83, 26, 20, 208, 13, 6, 195, 4, 176, 82, 13, 8, 133, 12, 197, 145, 20, 20, 13, 0, 5, 130, 195, 184, 43, 9, 198, 40, 241, 213, 56, 176, 84, 13, 16, 141, 22, 195, 169, 7, 18, 5, 8, 1, 10, 20, 1, 14, 9, 13, 16, 141, 11, 195, 182, 26, 12, 5, 11, 5, 4, 20, 5, 20, 9, 13, 21, 146, 2, 5, 195, 161, 12, 12, 195, 173, 20, 195, 161, 19, 15, 11, 14, 195, 161, 12, 13, 11, 136, 15, 12, 3, 19, 195, 179, 2, 2, 13, 9, 198, 52, 17, 213, 56, 176, 84, 13, 0, 30, 71, 52, 147, 137, 77, 165, 5, 72, 65, 37, 50, 37, 89, 47, 109, 52, 15, 84, 39, 55, 47, 0, 13, 81, 118, 111, 108, 116, 32, 9, 134, 19, 26, 195, 179, 2, 1, 13, 14, 139, 20, 1, 18, 20, 8, 1, 20, 14, 195, 161, 4, 13, 10, 199, 65, 35, 199, 72, 19, 66, 4, 13, 10, 199, 52, 147, 137, 77, 165, 5, 72, 13, 0, 41, 68, 52, 17, 193, 76, 65, 108, 81, 108, 91, 23, 107, 118, 65, 113, 52, 91, 113, 49, 55, 109, 47, 0, 13, 81, 104, 197, 145, 109, 195, 169, 114, 115, 195, 169, 107, 108, 101, 116, 32, 12, 137, 20, 5, 8, 5, 20, 14, 195, 169, 11, 13, 7, 196, 52, 17, 193, 76, 13, 7, 196, 24, 241, 214, 4, 13, 7, 196, 32, 246, 142, 36, 13, 7, 196, 32, 246, 142, 36, 13, 0, 13, 138, 11, 9, 19, 6, 9, 195, 186, 14, 1, 11, 13, 32, 69, 81, 81, 20, 4, 176, 47, 40, 47, 12, 108, 49, 23, 65, 39, 50, 72, 108, 50, 37, 0, 13, 81, 109, 111, 110, 100, 97, 110, 105, 32, 7, 132, 195, 169, 22, 5, 13, 8, 133, 19, 195, 188, 12, 20, 13, 9, 134, 18, 195, 179, 12, 21, 11, 13, 8, 133, 6, 195, 169, 12, 20, 13, 0, 12, 137, 16, 5, 18, 5, 13, 195, 169, 18, 5, 13, 15, 140, 13, 195, 169, 12, 25, 19, 195, 169, 7, 2, 5, 14, 13, 14, 139, 22, 195, 161, 12, 12, 1, 12, 14, 9, 21, 11, 13, 8, 133, 2, 195, 169, 18, 5, 13, 11, 136, 19, 26, 195, 179, 12, 10, 15, 14, 13, 14, 139, 6, 18, 9, 19, 19, 195, 188, 12, 14, 5, 11, 13, 11, 136, 11, 15, 18, 195, 161, 2, 1, 14, 13, 9, 134, 19, 26, 195, 179, 12, 20, 13, 18, 4, 195, 186, 46, 14, 116, 79, 50, 109, 84, 109, 88, 109, 47, 12, 0, 25, 0, 6, 195, 81, 81, 0, 13, 13, 138, 16, 195, 169, 12, 4, 195, 161, 26, 26, 1, 13, 14, 139, 22, 195, 169, 20, 5, 12, 195, 169, 22, 5, 12, 13, 50, 9, 11, 195, 182, 18, 195, 169, 2, 5, 14, 49, 110, 52, 113, 71, 109, 50, 23, 48, 52, 115, 71, 114, 55, 50, 114, 49, 23, 49, 37, 0, 13, 82, 112, 114, 195, 179, 98, 195, 161, 108, 110, 195, 161, 107, 32, 107, 105, 32, 34, 67, 80, 85, 20, 47, 109, 47, 12, 23, 108, 88, 10, 6, 15, 111, 79, 71, 109, 50, 0, 13, 82, 97, 122, 32, 195, 188, 103, 121, 98, 101, 110, 32, 45, 9, 11, 195, 182, 18, 195, 169, 2, 5, 14, 49, 110, 52, 113, 71, 109, 50, 23, 37, 91, 23, 84, 37, 47, 108, 47, 39, 47, 12, 0, 13, 82, 105, 115, 32, 118, 105, 116, 97, 116, 111, 116, 116, 32, 12, 137, 11, 195, 182, 18, 195, 186, 20, 15, 14, 13, 34, 71, 48, 81, 129, 29, 147, 212, 80, 55, 109, 83, 108, 79, 39, 47, 12, 23, 65, 37, 50, 72, 109, 50, 0, 13, 81, 109, 105, 110, 100, 101, 110, 32, 9, 198, 4, 64, 75, 61, 163, 137, 13, 14, 139, 195, 182, 14, 13, 1, 7, 195, 161, 22, 1, 12, 13, 9, 134, 2, 195, 173, 18, 10, 1, 13, 6, 195, 81, 81, 0, 13, 6, 195, 80, 85, 20, 13, 11, 67, 72, 19, 64, 52, 108, 65, 0, 42, 42, 0, 12, 137, 22, 195, 161, 4, 15, 12, 14, 1, 11, 13, 44, 9, 7, 25, 197, 145, 26, 20, 195, 169, 11, 79, 118, 88, 47, 113, 49, 23, 83, 109, 55, 72, 39, 55, 81, 39, 88, 50, 37, 0, 13, 81, 102, 101, 108, 100, 111, 108, 103, 111, 122, 110, 105, 32, 10, 135, 22, 5, 26, 195, 169, 18, 5, 13, 7, 196, 24, 241, 193, 80, 13, 11, 200, 80, 243, 1, 44, 241, 20, 4, 176, 13, 7, 196, 24, 18, 193, 16, 13, 0, 11, 136, 19, 26, 5, 13, 195, 169, 18, 5, 13, 0, 54, 9, 5, 12, 12, 5, 14, 195, 169, 18, 5, 109, 55, 12, 109, 50, 113, 52, 109, 23, 37, 91, 23, 71, 37, 89, 47, 39, 91, 112, 47, 108, 50, 114, 0, 13, 82, 105, 115, 32, 98, 105, 122, 116, 111, 115, 195, 173, 116, 97, 110, 195, 161, 32, 12, 137, 9, 11, 15, 14, 10, 195, 161, 18, 1, 13, 12, 137, 13, 195, 179, 4, 10, 195, 161, 18, 1, 13, 0, 10, 199, 13, 48, 80, 60, 194, 1, 80, 13, 15, 140, 195, 188, 26, 5, 13, 5, 12, 20, 5, 20, 9, 11, 13, 10, 199, 20, 195, 153, 21, 35, 137, 20, 13, 10, 199, 80, 84, 218, 80, 82, 197, 80, 13, 6, 195, 88, 149, 20, 13, 11, 136, 13, 195, 161, 18, 3, 9, 21, 19, 20, 0, 28, 5, 195, 169, 22, 5, 19, 113, 84, 109, 91, 23, 109, 65, 71, 109, 52, 47, 0, 13, 81, 101, 109, 98, 101, 114, 116, 32, 26, 5, 195, 169, 22, 5, 19, 113, 84, 109, 91, 23, 109, 65, 71, 109, 52, 0, 13, 81, 101, 109, 98, 101, 114, 32, 29, 5, 195, 169, 22, 5, 19, 113, 84, 109, 91, 23, 49, 37, 91, 83, 37, 116, 0, 13, 81, 107, 105, 115, 102, 105, 195, 186, 32, 23, 5, 195, 169, 22, 5, 19, 113, 84, 109, 91, 23, 83, 37, 116, 0, 13, 81, 102, 105, 195, 186, 32, 30, 5, 195, 169, 22, 5, 19, 113, 84, 109, 91, 23, 49, 37, 91, 55, 114, 67, 0, 13, 81, 107, 105, 115, 108, 195, 161, 110, 121, 32, 24, 5, 195, 169, 22, 5, 19, 113, 84, 109, 91, 23, 55, 114, 67, 0, 13, 81, 108, 195, 161, 110, 121, 32, 21, 5, 195, 169, 22, 5, 19, 113, 84, 109, 91, 23, 50, 118, 0, 13, 81, 110, 197, 145, 32, 27, 5, 195, 169, 22, 5, 19, 113, 84, 109, 91, 23, 83, 113, 52, 83, 37, 0, 13, 81, 102, 195, 169, 114, 102, 105, 32, 31, 5, 195, 169, 22, 5, 19, 113, 84, 109, 91, 23, 49, 37, 91, 83, 37, 116, 47, 0, 13, 81, 107, 105, 115, 102, 105, 195, 186, 116, 32, 25, 5, 195, 169, 22, 5, 19, 113, 84, 109, 91, 23, 83, 37, 116, 47, 0, 13, 81, 102, 105, 195, 186, 116, 32, 32, 5, 195, 169, 22, 5, 19, 113, 84, 109, 91, 23, 49, 37, 91, 55, 114, 67, 47, 0, 13, 81, 107, 105, 115, 108, 195, 161, 110, 121, 116, 32, 26, 5, 195, 169, 22, 5, 19, 113, 84, 109, 91, 23, 55, 114, 67, 47, 0, 13, 81, 108, 195, 161, 110, 121, 116, 32, 25, 5, 195, 169, 22, 5, 19, 113, 84, 109, 91, 23, 50, 118, 52, 109, 0, 13, 81, 110, 197, 145, 114, 101, 32, 31, 5, 195, 169, 22, 5, 19, 113, 84, 109, 91, 23, 83, 113, 52, 83, 37, 52, 108, 0, 13, 81, 102, 195, 169, 114, 102, 105, 114, 97, 32, 31, 5, 195, 169, 22, 5, 19, 113, 84, 109, 91, 23, 49, 37, 91, 83, 37, 116, 47, 0, 13, 81, 107, 105, 115, 102, 105, 195, 186, 116, 32, 29, 5, 195, 169, 22, 5, 19, 113, 84, 109, 91, 23, 49, 37, 91, 83, 37, 116, 0, 13, 81, 107, 105, 115, 102, 105, 195, 186, 32, 17, 142, 11, 195, 182, 26, 16, 15, 14, 20, 10, 195, 161, 2, 1, 14, 13, 36, 5, 195, 169, 22, 5, 19, 113, 84, 109, 91, 23, 47, 114, 65, 39, 81, 108, 47, 114, 91, 0, 13, 81, 116, 195, 161, 109, 111, 103, 97, 116, 195, 161, 115, 32, 19, 144, 20, 5, 12, 5, 16, 195, 173, 20, 195, 169, 19, 195, 169, 22, 5, 12, 13, 32, 5, 195, 169, 22, 5, 19, 113, 84, 109, 91, 15, 49, 39, 52, 114, 71, 115, 55, 0, 13, 81, 107, 111, 114, 195, 161, 98, 195, 179, 108, 32, 31, 5, 195, 169, 22, 5, 19, 113, 84, 109, 91, 15, 79, 109, 52, 109, 49, 109, 47, 0, 13, 81, 103, 121, 101, 114, 101, 107, 101, 116, 32, 9, 198, 64, 243, 148, 40, 18, 78, 13, 8, 133, 9, 4, 197, 145, 19, 13, 8, 133, 195, 169, 22, 5, 19, 13, 7, 196, 56, 82, 197, 52, 13, 0, 12, 137, 8, 1, 4, 10, 195, 161, 18, 1, 20, 13, 37, 10, 6, 5, 12, 5, 20, 20, 195, 188, 14, 11, 83, 109, 55, 109, 47, 12, 111, 50, 49, 23, 108, 88, 23, 113, 81, 0, 13, 82, 97, 122, 32, 195, 169, 103, 32, 15, 140, 12, 5, 22, 5, 7, 197, 145, 10, 195, 169, 18, 5, 13, 0, 56, 11, 19, 26, 195, 188, 11, 19, 195, 169, 7, 5, 19, 89, 111, 49, 91, 113, 81, 109, 91, 23, 37, 50, 47, 113, 89, 49, 109, 72, 113, 91, 109, 49, 109, 47, 0, 13, 81, 105, 110, 116, 195, 169, 122, 107, 101, 100, 195, 169, 115, 101, 107, 101, 116, 32, 46, 9, 20, 195, 182, 18, 22, 195, 169, 14, 25, 47, 110, 52, 84, 113, 67, 10, 10, 47, 109, 52, 84, 109, 88, 109, 47, 113, 71, 109, 0, 13, 81, 116, 101, 114, 118, 101, 122, 101, 116, 195, 169, 98, 101, 32, 53, 9, 20, 195, 182, 18, 22, 195, 169, 14, 25, 47, 110, 52, 84, 113, 67, 23, 49, 39, 50, 119, 109, 48, 119, 37, 115, 57, 114, 52, 115, 55, 0, 13, 81, 107, 111, 110, 99, 101, 112, 99, 105, 195, 179, 106, 195, 161, 114, 195, 179, 108, 32, 12, 137, 11, 195, 169, 16, 26, 5, 12, 14, 9, 13, 14, 139, 12, 5, 8, 5, 20, 19, 195, 169, 7, 5, 19, 13, 12, 137, 20, 195, 182, 18, 22, 195, 169, 14, 25, 13, 9, 198, 77, 161, 82, 104, 85, 20, 13, 9, 134, 19, 195, 186, 12, 25, 20, 13, 0, 17, 142, 6, 9, 14, 1, 14, 19, 26, 195, 173, 18, 15, 26, 26, 1, 13, 10, 199, 52, 81, 198, 36, 118, 69, 48, 13, 27, 5, 21, 20, 195, 161, 14, 40, 47, 114, 50, 23, 50, 113, 88, 50, 37, 0, 13, 81, 110, 195, 169, 122, 110, 105, 32, 9, 134, 12, 195, 161, 20, 14, 9, 13, 9, 133, 21, 20, 195, 161, 14, 13, 22, 9, 134, 14, 25, 195, 161, 18, 9, 20, 0, 35, 67, 5, 36, 129, 108, 52, 52, 108, 10, 6, 15, 47, 110, 52, 109, 49, 109, 72, 50, 37, 0, 13, 81, 116, 195, 182, 114, 101, 107, 101, 100, 110, 105, 32, 30, 67, 5, 36, 129, 108, 52, 52, 108, 10, 6, 15, 49, 113, 52, 57, 111, 49, 0, 13, 81, 107, 195, 169, 114, 106, 195, 188, 107, 32, 36, 7, 19, 26, 9, 14, 20, 197, 177, 89, 37, 50, 47, 117, 23, 83, 109, 55, 107, 118, 88, 109, 47, 0, 13, 81, 102, 101, 108, 104, 197, 145, 122, 101, 116, 32, 30, 67, 5, 36, 129, 108, 52, 52, 108, 23, 57, 40, 47, 39, 47, 12, 108, 65, 0, 13, 81, 106, 117, 116, 111, 116, 116, 97, 109, 32, 37, 67, 5, 36, 129, 108, 52, 52, 108, 23, 84, 39, 50, 108, 47, 49, 39, 88, 115, 108, 50, 0, 13, 81, 118, 111, 110, 97, 116, 107, 111, 122, 195, 179, 97, 110, 32, 18, 67, 5, 36, 129, 108, 52, 52, 108, 23, 37, 91, 0, 13, 81, 105, 115, 32, 45, 67, 5, 36, 129, 108, 52, 52, 108, 23, 49, 109, 55, 12, 23, 39, 72, 108, 83, 37, 79, 109, 55, 50, 37, 0, 13, 82, 107, 101, 108, 108, 32, 111, 100, 97, 102, 105, 103, 121, 101, 108, 110, 105, 32, 7, 196, 80, 18, 193, 72, 13, 16, 141, 4, 195, 182, 14, 20, 195, 182, 20, 20, 195, 188, 14, 11, 13, 14, 139, 2, 5, 19, 26, 5, 18, 26, 195, 169, 19, 5, 13, 11, 136, 19, 5, 7, 195, 169, 12, 25, 20, 13, 6, 195, 21, 36, 133, 13, 6, 195, 5, 36, 129, 13, 0, 8, 197, 32, 20, 131, 60, 192, 13, 11, 136, 5, 12, 10, 195, 161, 18, 14, 9, 13, 9, 134, 195, 169, 18, 26, 9, 11, 13, 9, 134, 3, 195, 169, 7, 5, 11, 13, 8, 133, 10, 195, 161, 18, 20, 13, 0, 13, 138, 7, 25, 1, 14, 195, 186, 10, 195, 161, 20, 13, 46, 4, 195, 169, 18, 22, 113, 52, 84, 23, 108, 6, 15, 55, 37, 50, 40, 49, 89, 23, 65, 109, 55, 12, 109, 47, 12, 0, 13, 83, 97, 32, 108, 105, 110, 117, 120, 32, 109, 101, 108, 108, 101, 116, 116, 32, 26, 6, 1, 26, 195, 169, 18, 20, 108, 88, 113, 52, 47, 15, 84, 39, 55, 47, 0, 13, 81, 118, 111, 108, 116, 32, 14, 139, 20, 5, 19, 26, 20, 5, 12, 195, 188, 14, 11, 13, 7, 132, 195, 169, 18, 22, 13, 14, 139, 6, 5, 10, 12, 5, 19, 26, 20, 195, 169, 19, 13, 20, 145, 13, 5, 7, 2, 195, 188, 14, 20, 5, 20, 195, 169, 19, 195, 169, 18, 5, 13, 9, 134, 1, 26, 195, 169, 18, 20, 13, 0, 56, 11, 11, 195, 182, 12, 20, 19, 195, 169, 7, 5, 20, 49, 110, 55, 76, 113, 81, 109, 47, 23, 57, 109, 55, 109, 50, 47, 23, 89, 114, 65, 40, 49, 52, 108, 0, 13, 82, 106, 101, 108, 101, 110, 116, 32, 115, 122, 195, 161, 109, 117, 107, 114, 97, 32, 14, 139, 18, 195, 169, 19, 26, 12, 5, 20, 5, 9, 20, 13, 10, 199, 65, 35, 199, 72, 19, 79, 44, 13, 21, 146, 13, 5, 7, 19, 26, 195, 188, 14, 20, 5, 20, 195, 169, 19, 195, 169, 18, 5, 13, 0, 7, 196, 4, 176, 82, 80, 13, 15, 140, 22, 195, 161, 12, 20, 15, 26, 1, 20, 1, 9, 20, 13, 7, 196, 52, 245, 15, 72, 13, 7, 196, 32, 246, 148, 4, 13, 7, 132, 195, 169, 18, 20, 13, 7, 196, 56, 82, 201, 44, 13, 0, 10, 135, 9, 7, 1, 26, 195, 161, 14, 13, 13, 138, 7, 15, 14, 4, 15, 12, 10, 195, 161, 11, 13, 13, 138, 20, 1, 7, 12, 1, 12, 10, 195, 161, 11, 13, 10, 135, 14, 25, 1, 18, 195, 161, 14, 20, 0, 9, 134, 5, 26, 195, 169, 18, 20, 13, 13, 138, 3, 195, 173, 13, 195, 169, 20, 197, 145, 12, 13, 13, 138, 6, 15, 18, 9, 14, 20, 195, 169, 18, 20, 13, 43, 10, 6, 15, 18, 9, 14, 20, 195, 169, 18, 20, 83, 39, 52, 37, 50, 47, 113, 52, 47, 23, 109, 55, 84, 37, 107, 109, 47, 118, 0, 13, 81, 101, 108, 118, 105, 104, 101, 116, 197, 145, 32, 10, 135, 19, 26, 197, 177, 18, 9, 11, 13, 30, 6, 5, 26, 195, 169, 18, 20, 109, 88, 113, 52, 47, 15, 84, 108, 50, 15, 108, 88, 0, 13, 82, 118, 97, 110, 32, 97, 122, 32, 17, 142, 195, 188, 7, 25, 14, 195, 182, 11, 19, 195, 169, 7, 5, 20, 13, 0, 45, 15, 20, 5, 22, 195, 169, 11, 5, 14, 25, 19, 195, 169, 7, 5, 20, 47, 109, 84, 113, 49, 109, 67, 91, 113, 81, 109, 47, 23, 84, 113, 81, 109, 88, 0, 13, 81, 118, 195, 169, 103, 101, 122, 32, 9, 134, 2, 195, 161, 18, 11, 9, 13, 0, 39, 5, 22, 1, 12, 195, 179, 84, 108, 55, 115, 23, 47, 52, 111, 49, 12, 110, 88, 113, 91, 47, 0, 13, 81, 116, 114, 195, 188, 107, 107, 195, 182, 122, 195, 169, 115, 116, 32, 11, 136, 8, 1, 19, 26, 14, 195, 161, 12, 13, 8, 133, 22, 1, 12, 195, 179, 13, 6, 195, 21, 53, 5, 22, 0, 17, 142, 19, 26, 1, 2, 195, 161, 12, 25, 15, 26, 26, 195, 161, 11, 13, 13, 138, 1, 12, 1, 16, 15, 26, 20, 195, 161, 11, 13, 17, 142, 19, 26, 195, 182, 22, 5, 20, 20, 19, 195, 169, 7, 5, 11, 13, 13, 138, 11, 195, 182, 20, 8, 5, 20, 197, 145, 11, 13, 8, 133, 13, 195, 161, 19, 20, 13, 17, 9, 95, 35, 45, 195, 161, 14, 195, 161, 12, 114, 50, 114, 55, 0, 21, 0, 13, 138, 5, 7, 25, 13, 195, 161, 19, 19, 1, 12, 13, 0, 14, 139, 18, 195, 169, 19, 26, 195, 169, 18, 197, 145, 12, 13, 0, 10, 135, 12, 195, 169, 16, 14, 9, 5, 13, 10, 135, 1, 18, 195, 161, 14, 25, 1, 13, 16, 67, 44, 98, 201, 49, 114, 109, 83, 49, 114, 37, 0, 17, 42, 42, 0, 42, 6, 15, 16, 3, 9, 195, 179, 39, 48, 119, 37, 115, 23, 71, 109, 49, 108, 48, 76, 39, 55, 114, 91, 108, 0, 13, 81, 98, 101, 107, 97, 112, 99, 115, 111, 108, 195, 161, 115, 97, 32, 24, 6, 15, 16, 3, 9, 195, 179, 39, 48, 119, 37, 115, 15, 50, 109, 65, 0, 13, 81, 110, 101, 109, 32, 0, 36, 10, 5, 12, 14, 195, 169, 26, 195, 169, 19, 20, 109, 55, 50, 113, 88, 113, 91, 47, 23, 49, 113, 52, 109, 49, 0, 13, 81, 107, 195, 169, 114, 101, 107, 32, 10, 135, 14, 5, 11, 195, 188, 14, 11, 13, 11, 5, 95, 49, 77, 49, 5, 109, 88, 52, 0, 0, 14, 139, 8, 195, 161, 12, 195, 179, 26, 1, 20, 15, 20, 13, 0, 36, 68, 80, 85, 20, 20, 47, 109, 47, 12, 109, 23, 84, 37, 55, 114, 81, 39, 91, 12, 114, 0, 13, 81, 118, 105, 108, 195, 161, 103, 111, 115, 115, 195, 161, 32, 29, 68, 4, 192, 84, 80, 108, 55, 108, 47, 12, 23, 49, 113, 89, 111, 55, 0, 13, 81, 107, 195, 169, 115, 122, 195, 188, 108, 32, 34, 68, 4, 192, 84, 80, 108, 55, 108, 47, 12, 15, 72, 39, 55, 81, 39, 89, 47, 108, 49, 0, 13, 81, 100, 111, 108, 103, 111, 122, 116, 97, 107, 32, 10, 135, 11, 195, 169, 18, 14, 9, 5, 13, 19, 144, 8, 1, 19, 26, 14, 195, 161, 12, 1, 20, 195, 161, 195, 169, 18, 20, 13, 7, 196, 88, 85, 20, 20, 13, 7, 196, 80, 85, 20, 20, 13, 7, 196, 4, 192, 84, 80, 13, 0, 11, 136, 15, 4, 1, 195, 173, 18, 14, 9, 13, 10, 135, 8, 195, 161, 20, 195, 161, 14, 13, 13, 138, 16, 1, 18, 20, 195, 173, 3, 9, 195, 179, 13, 0, 21, 146, 13, 5, 7, 9, 14, 4, 195, 173, 20, 195, 161, 19, 195, 161, 195, 169, 18, 20, 13, 12, 137, 11, 195, 182, 22, 5, 20, 14, 9, 5, 13, 13, 138, 20, 1, 12, 195, 161, 12, 14, 195, 161, 4, 13, 9, 198, 24, 81, 5, 104, 85, 0, 13, 13, 138, 5, 12, 20, 195, 169, 18, 195, 169, 19, 20, 13, 11, 136, 12, 195, 161, 20, 20, 195, 161, 14, 13, 7, 132, 20, 197, 177, 26, 13, 10, 135, 11, 1, 16, 10, 195, 161, 11, 13, 0, 43, 6, 9, 4, 197, 145, 18, 5, 37, 72, 118, 52, 109, 23, 89, 114, 65, 112, 47, 107, 108, 47, 40, 50, 49, 0, 13, 81, 115, 122, 195, 161, 109, 195, 173, 116, 104, 97, 116, 117, 110, 107, 32, 42, 6, 9, 4, 197, 145, 18, 5, 37, 72, 118, 52, 109, 23, 84, 108, 50, 23, 49, 37, 55, 114, 47, 114, 91, 0, 13, 82, 118, 97, 110, 32, 107, 105, 108, 195, 161, 116, 195, 161, 115, 32, 9, 198, 25, 85, 20, 5, 67, 137, 13, 9, 198, 25, 85, 20, 5, 66, 129, 13, 0, 10, 135, 11, 9, 22, 195, 169, 22, 5, 13, 44, 6, 195, 179, 18, 195, 161, 14, 115, 52, 114, 50, 10, 6, 15, 71, 109, 55, 111, 55, 10, 6, 15, 65, 108, 52, 108, 72, 0, 13, 82, 98, 101, 108, 195, 188, 108, 32, 109, 97, 114, 97, 100, 32, 11, 200, 40, 83, 5, 57, 65, 84, 80, 80, 13, 7, 132, 195, 182, 12, 20, 13, 8, 133, 13, 195, 161, 18, 3, 20, 15, 5, 95, 49, 77, 49, 15, 109, 88, 52, 109, 72, 37, 49, 0, 0, 8, 197, 21, 54, 142, 20, 176, 13, 32, 6, 195, 169, 12, 197, 145, 11, 113, 55, 118, 49, 23, 107, 109, 57, 88, 109, 47, 109, 0, 13, 81, 104, 101, 108, 121, 122, 101, 116, 101, 32, 10, 135, 12, 195, 161, 2, 195, 161, 14, 13, 24, 69, 81, 81, 20, 4, 208, 47, 40, 47, 12, 108, 65, 23, 65, 109, 81, 0, 13, 81, 109, 101, 103, 32, 8, 197, 72, 80, 211, 20, 112, 13, 8, 197, 32, 17, 217, 80, 16, 13, 11, 136, 22, 9, 12, 195, 161, 7, 2, 1, 13, 17, 9, 95, 35, 45, 195, 169, 20, 197, 145, 12, 113, 47, 118, 55, 0, 21, 0, 9, 198, 88, 17, 217, 84, 226, 192, 13, 9, 198, 64, 144, 67, 60, 176, 84, 13, 9, 198, 88, 17, 217, 84, 226, 192, 13, 12, 137, 19, 26, 195, 161, 13, 15, 13, 18, 1, 13, 17, 142, 195, 188, 12, 4, 195, 182, 7, 195, 169, 12, 195, 169, 19, 20, 13, 14, 139, 195, 161, 12, 12, 195, 173, 20, 10, 195, 161, 11, 13, 0, 7, 2, 95, 1, 108, 12, 0, 9, 134, 22, 9, 20, 195, 161, 9, 13, 10, 199, 52, 81, 207, 48, 64, 78, 36, 13, 19, 144, 8, 195, 161, 20, 20, 195, 169, 18, 20, 195, 161, 18, 15, 12, 195, 179, 13, 9, 134, 2, 195, 173, 18, 14, 1, 13, 11, 136, 12, 195, 161, 20, 20, 195, 161, 11, 13, 11, 136, 18, 195, 179, 12, 1, 20, 15, 11, 13, 9, 134, 12, 195, 161, 20, 10, 1, 13, 0, 9, 134, 19, 15, 6, 197, 145, 18, 13, 7, 196, 76, 242, 193, 80, 13, 16, 141, 13, 1, 7, 25, 1, 18, 195, 161, 26, 26, 195, 161, 11, 13, 11, 200, 20, 208, 133, 72, 82, 206, 20, 176, 13, 8, 133, 5, 18, 197, 145, 19, 13, 0, 32, 9, 5, 13, 12, 195, 173, 20, 5, 20, 20, 109, 65, 55, 112, 47, 109, 47, 12, 23, 108, 52, 52, 108, 0, 13, 81, 97, 114, 114, 97, 32, 13, 138, 5, 12, 13, 15, 14, 4, 20, 195, 161, 11, 13, 37, 9, 5, 13, 12, 195, 173, 20, 5, 20, 20, 109, 65, 55, 112, 47, 109, 47, 12, 23, 119, 37, 49, 71, 109, 50, 0, 13, 81, 99, 105, 107, 107, 98, 101, 110, 32, 41, 9, 5, 13, 12, 195, 173, 20, 5, 20, 20, 109, 65, 55, 112, 47, 109, 47, 12, 23, 89, 109, 52, 84, 109, 88, 109, 47, 0, 13, 81, 115, 122, 101, 114, 118, 101, 122, 101, 116, 32, 11, 136, 12, 1, 11, 195, 161, 19, 2, 1, 13, 9, 134, 195, 179, 18, 195, 161, 19, 13, 0, 14, 139, 3, 19, 9, 14, 195, 161, 12, 20, 195, 161, 11, 13, 9, 198, 77, 163, 203, 80, 19, 64, 13, 17, 142, 6, 5, 12, 5, 19, 195, 169, 7, 195, 169, 20, 197, 145, 12, 13, 9, 134, 22, 9, 20, 195, 161, 20, 13, 14, 139, 10, 1, 22, 1, 19, 15, 12, 20, 195, 161, 11, 13, 0, 6, 2, 95, 5, 109, 0, 10, 199, 20, 208, 133, 72, 82, 197, 80, 13, 17, 142, 13, 5, 7, 13, 5, 14, 20, 195, 169, 19, 195, 169, 18, 5, 13, 28, 71, 8, 150, 143, 56, 230, 65, 48, 71, 37, 88, 39, 67, 67, 108, 55, 10, 6, 15, 108, 88, 0, 13, 81, 97, 122, 32, 10, 199, 16, 243, 7, 60, 178, 193, 48, 13, 10, 199, 20, 208, 133, 72, 82, 197, 80, 13, 0, 33, 9, 5, 12, 10, 195, 161, 18, 195, 161, 19, 109, 55, 57, 114, 52, 114, 91, 23, 37, 50, 72, 40, 55, 0, 13, 81, 105, 110, 100, 117, 108, 32, 16, 141, 19, 26, 195, 188, 11, 19, 195, 169, 7, 5, 19, 5, 11, 13, 12, 137, 5, 12, 10, 195, 161, 18, 195, 161, 19, 13, 18, 143, 6, 5, 10, 12, 5, 19, 26, 20, 195, 169, 19, 195, 169, 18, 5, 13, 0, 16, 141, 11, 195, 188, 12, 6, 195, 182, 12, 4, 18, 197, 145, 12, 13, 11, 136, 5, 13, 5, 12, 195, 169, 19, 5, 13, 17, 142, 18, 5, 14, 4, 5, 12, 11, 5, 26, 195, 169, 19, 5, 11, 13, 0, 18, 143, 5, 12, 21, 20, 1, 19, 195, 173, 20, 15, 20, 20, 195, 161, 11, 13, 47, 14, 19, 26, 15, 6, 20, 22, 5, 18, 5, 11, 18, 197, 145, 12, 89, 39, 83, 47, 84, 109, 52, 109, 49, 52, 118, 55, 23, 84, 108, 50, 23, 89, 115, 0, 13, 82, 118, 97, 110, 32, 115, 122, 195, 179, 32, 9, 134, 3, 195, 169, 7, 5, 20, 13, 28, 10, 20, 195, 182, 18, 22, 195, 169, 14, 25, 20, 47, 110, 52, 84, 113, 67, 47, 23, 37, 91, 0, 13, 81, 105, 115, 32, 13, 138, 20, 195, 182, 18, 22, 195, 169, 14, 25, 20, 13, 9, 198, 52, 243, 132, 40, 19, 64, 13, 14, 139, 195, 169, 19, 26, 10, 195, 161, 18, 195, 161, 19, 13, 46, 15, 19, 26, 195, 179, 11, 1, 16, 3, 19, 15, 12, 1, 20, 15, 11, 89, 115, 49, 108, 48, 76, 39, 55, 108, 47, 39, 49, 23, 84, 108, 50, 12, 108, 49, 0, 13, 81, 118, 97, 110, 110, 97, 107, 32, 56, 11, 9, 4, 197, 145, 10, 195, 161, 18, 195, 161, 19, 37, 72, 118, 57, 114, 52, 114, 91, 23, 55, 109, 89, 23, 108, 23, 57, 109, 55, 12, 109, 65, 88, 118, 0, 13, 83, 108, 101, 115, 122, 32, 97, 32, 106, 101, 108, 108, 101, 109, 122, 197, 145, 32, 10, 135, 18, 1, 2, 12, 195, 161, 19, 13, 13, 202, 64, 148, 218, 80, 243, 25, 60, 178, 193, 48, 13, 9, 134, 195, 179, 18, 195, 161, 20, 13, 16, 141, 6, 15, 18, 4, 21, 12, 1, 20, 19, 26, 195, 161, 13, 13, 0, 14, 139, 6, 15, 12, 25, 1, 13, 1, 20, 195, 161, 20, 13, 13, 138, 10, 5, 12, 5, 14, 20, 195, 169, 19, 5, 13, 25, 7, 19, 26, 1, 22, 195, 161, 20, 89, 108, 84, 114, 47, 23, 91, 109, 65, 0, 13, 81, 115, 101, 109, 32, 13, 138, 13, 5, 7, 7, 25, 197, 145, 26, 14, 9, 13, 13, 138, 14, 195, 182, 22, 5, 12, 195, 169, 19, 5, 13, 9, 134, 1, 4, 195, 161, 19, 1, 13, 0, 9, 198, 88, 243, 20, 5, 67, 203, 72, 12, 137, 5, 12, 12, 195, 161, 20, 195, 161, 19, 13, 11, 136, 18, 195, 169, 20, 5, 7, 5, 20, 13, 15, 140, 4, 195, 182, 14, 20, 195, 169, 19, 5, 11, 5, 20, 13, 11, 136, 16, 12, 195, 161, 26, 195, 161, 20, 13, 11, 136, 11, 1, 16, 21, 10, 195, 161, 20, 13, 0, 16, 205, 80, 20, 137, 24, 16, 211, 60, 208, 71, 60, 178, 193, 48, 13, 7, 196, 76, 244, 143, 56, 13, 12, 201, 32, 19, 135, 61, 165, 1, 80, 243, 64, 13, 11, 136, 11, 195, 182, 20, 195, 169, 19, 5, 13, 10, 135, 22, 195, 161, 18, 10, 21, 11, 13, 12, 201, 24, 83, 142, 4, 176, 68, 80, 19, 64, 13, 19, 144, 13, 5, 7, 19, 5, 7, 195, 173, 20, 195, 169, 19, 195, 169, 18, 5, 13, 32, 8, 11, 9, 1, 4, 195, 161, 19, 1, 49, 37, 108, 72, 114, 91, 108, 23, 55, 109, 107, 109, 47, 0, 13, 81, 108, 101, 104, 101, 116, 32, 12, 137, 22, 1, 7, 25, 15, 14, 195, 161, 20, 13, 0, 47, 70, 80, 17, 202, 4, 148, 129, 47, 108, 81, 57, 108, 37, 52, 108, 23, 84, 39, 50, 108, 47, 49, 39, 88, 12, 108, 50, 108, 49, 0, 13, 81, 118, 111, 110, 97, 116, 107, 111, 122, 122, 97, 110, 97, 107, 32, 14, 139, 7, 25, 15, 18, 19, 195, 173, 20, 195, 161, 19, 13, 10, 135, 22, 195, 161, 12, 1, 19, 26, 13, 14, 139, 20, 195, 161, 13, 15, 7, 1, 20, 195, 161, 19, 13, 0, 9, 134, 26, 195, 161, 18, 21, 12, 13, 0, 19, 67, 85, 48, 64, 117, 115, 195, 161, 98, 97, 0, 44, 29, 42, 81, 98, 97, 32, 21, 67, 85, 48, 64, 117, 115, 195, 161, 98, 97, 110, 0, 44, 29, 42, 81, 98, 97, 110, 32, 25, 67, 85, 48, 64, 117, 115, 195, 161, 195, 169, 118, 97, 108, 0, 44, 29, 42, 81, 195, 169, 118, 97, 108, 32, 21, 67, 85, 48, 64, 117, 115, 195, 161, 110, 97, 107, 0, 44, 29, 42, 81, 110, 97, 107, 32, 23, 67, 85, 48, 64, 117, 115, 195, 161, 98, 195, 179, 108, 0, 44, 29, 42, 81, 98, 195, 179, 108, 32, 7, 2, 95, 19, 109, 91, 0, 14, 139, 5, 12, 4, 195, 182, 14, 20, 195, 169, 19, 5, 13, 10, 199, 24, 83, 153, 20, 113, 84, 36, 13, 16, 141, 20, 195, 186, 12, 12, 195, 169, 16, 20, 195, 188, 14, 11, 13, 10, 199, 16, 243, 7, 61, 163, 129, 44, 13, 6, 195, 57, 146, 84, 13, 6, 195, 104, 18, 148, 13, 10, 4, 95, 50, 48, 5, 107, 40, 89, 0, 0, 9, 198, 32, 19, 65, 72, 16, 130, 13, 17, 142, 13, 5, 7, 195, 161, 12, 12, 1, 16, 15, 4, 195, 161, 19, 13, 49, 14, 13, 5, 7, 195, 161, 12, 12, 1, 16, 15, 4, 195, 161, 19, 65, 109, 81, 114, 55, 12, 108, 48, 39, 72, 114, 91, 23, 49, 110, 47, 107, 109, 47, 118, 0, 13, 81, 107, 195, 182, 116, 104, 101, 116, 197, 145, 32, 57, 14, 13, 5, 7, 195, 161, 12, 12, 1, 16, 15, 4, 195, 161, 19, 65, 109, 81, 114, 55, 12, 108, 48, 39, 72, 114, 91, 23, 37, 91, 23, 89, 111, 55, 109, 47, 109, 47, 12, 0, 13, 82, 105, 115, 32, 115, 122, 195, 188, 108, 101, 116, 101, 116, 116, 32, 16, 141, 11, 21, 12, 20, 195, 186, 18, 195, 161, 10, 195, 161, 20, 13, 12, 68, 65, 52, 218, 80, 48, 89, 12, 47, 0, 41, 0, 27, 152, 19, 1, 10, 20, 195, 179, 20, 195, 161, 10, 195, 169, 11, 15, 26, 20, 1, 20, 195, 179, 10, 195, 161, 14, 13, 9, 134, 26, 195, 161, 18, 20, 1, 13, 9, 134, 22, 195, 161, 18, 20, 1, 13, 0, 7, 66, 77, 160, 109, 89, 0, 0, 17, 142, 19, 1, 10, 195, 161, 20, 15, 19, 19, 195, 161, 7, 15, 11, 13, 0, 20, 145, 11, 195, 182, 20, 5, 12, 5, 26, 5, 20, 20, 19, 195, 169, 7, 5, 20, 13, 0, 21, 146, 11, 15, 14, 6, 9, 7, 21, 18, 195, 161, 3, 9, 195, 179, 10, 195, 161, 20, 13, 8, 197, 24, 18, 149, 49, 64, 13, 9, 198, 64, 192, 84, 24, 244, 141, 13, 8, 197, 52, 20, 129, 17, 64, 13, 0, 12, 137, 8, 195, 169, 20, 6, 197, 145, 9, 7, 22, 0, 6, 195, 88, 83, 0, 13, 0, 17, 142, 1, 4, 15, 20, 20, 19, 195, 161, 7, 1, 9, 8, 15, 26, 13, 12, 137, 22, 9, 7, 25, 195, 161, 26, 14, 9, 13, 10, 135, 20, 5, 7, 25, 195, 188, 11, 13, 0, 15, 140, 20, 5, 14, 14, 9, 22, 1, 12, 195, 179, 14, 11, 13, 11, 136, 195, 173, 18, 14, 195, 161, 14, 11, 13, 6, 195, 48, 83, 142, 13, 0, 35, 70, 80, 83, 69, 77, 49, 64, 47, 109, 65, 109, 91, 12, 109, 23, 109, 55, 23, 116, 57, 52, 108, 0, 13, 82, 101, 108, 32, 195, 186, 106, 114, 97, 32, 9, 134, 22, 195, 169, 4, 5, 4, 13, 13, 138, 10, 5, 12, 5, 14, 20, 195, 169, 19, 20, 13, 9, 198, 77, 161, 77, 52, 83, 0, 13, 7, 132, 195, 169, 19, 26, 13, 5, 194, 80, 144, 13, 11, 66, 92, 48, 84, 113, 119, 113, 0, 42, 42, 0, 21, 67, 8, 18, 128, 71, 108, 57, 10, 6, 15, 84, 108, 50, 0, 13, 81, 118, 97, 110, 32, 19, 67, 8, 18, 128, 71, 108, 57, 10, 6, 15, 108, 88, 0, 13, 81, 97, 122, 32, 47, 71, 65, 35, 199, 72, 19, 79, 80, 48, 52, 39, 81, 52, 108, 65, 39, 47, 23, 37, 50, 72, 112, 47, 108, 50, 114, 50, 108, 49, 0, 13, 81, 105, 110, 100, 195, 173, 116, 97, 110, 195, 161, 110, 97, 107, 32, 20, 67, 8, 18, 128, 71, 108, 57, 15, 84, 39, 55, 47, 0, 81, 118, 111, 108, 116, 32, 10, 135, 11, 195, 182, 26, 195, 188, 12, 13, 43, 71, 65, 35, 199, 72, 19, 79, 80, 48, 52, 39, 81, 52, 108, 65, 39, 47, 15, 47, 109, 89, 47, 109, 55, 111, 50, 49, 0, 13, 81, 116, 101, 115, 122, 116, 101, 108, 195, 188, 110, 107, 32, 6, 195, 8, 18, 128, 13, 10, 135, 11, 195, 182, 26, 195, 188, 12, 13, 15, 4, 95, 50, 48, 17, 107, 40, 89, 108, 72, 37, 49, 108, 0, 0, 11, 200, 24, 243, 25, 4, 208, 84, 61, 64, 13, 20, 68, 4, 178, 207, 72, 108, 49, 12, 39, 52, 23, 37, 91, 0, 13, 81, 105, 115, 32, 7, 196, 4, 178, 207, 72, 13, 0, 20, 5, 4, 197, 145, 12, 20, 72, 118, 55, 47, 23, 71, 109, 0, 13, 81, 98, 101, 32, 10, 135, 22, 195, 161, 7, 25, 19, 26, 13, 11, 136, 12, 195, 161, 20, 10, 195, 161, 11, 13, 12, 137, 4, 195, 182, 14, 20, 195, 169, 19, 20, 13, 11, 136, 12, 195, 161, 20, 10, 195, 161, 11, 13, 8, 133, 4, 197, 145, 12, 20, 13, 0, 13, 138, 10, 195, 179, 19, 26, 195, 161, 7, 15, 20, 13, 26, 70, 88, 86, 133, 80, 146, 192, 84, 109, 88, 109, 47, 37, 49, 10, 6, 15, 109, 55, 0, 13, 81, 101, 108, 32, 9, 198, 84, 118, 65, 56, 22, 128, 13, 12, 137, 6, 5, 10, 12, 197, 145, 4, 9, 11, 13, 12, 137, 11, 5, 26, 4, 197, 145, 4, 9, 11, 13, 0, 9, 198, 4, 194, 193, 48, 208, 83, 13, 17, 142, 3, 19, 195, 188, 20, 195, 182, 18, 20, 195, 182, 11, 9, 7, 22, 0, 13, 2, 95, 34, 37, 72, 113, 88, 118, 57, 109, 55, 0, 15, 140, 2, 195, 173, 18, 195, 179, 19, 195, 161, 7, 15, 20, 13, 14, 139, 10, 1, 22, 1, 19, 15, 12, 10, 195, 161, 11, 13, 10, 135, 6, 1, 10, 20, 195, 161, 11, 13, 10, 135, 8, 15, 26, 20, 195, 161, 11, 13, 15, 140, 2, 9, 26, 15, 20, 20, 19, 195, 161, 7, 15, 20, 13, 13, 138, 20, 21, 12, 1, 10, 4, 15, 14, 195, 186, 13, 7, 196, 52, 17, 213, 44, 13, 0, 17, 2, 95, 33, 83, 109, 55, 49, 37, 114, 55, 47, 115, 57, 109, 55, 0, 28, 69, 4, 176, 82, 60, 176, 108, 49, 108, 52, 39, 49, 23, 55, 109, 50, 12, 37, 0, 13, 81, 108, 101, 110, 110, 105, 32, 16, 141, 5, 12, 12, 5, 14, 197, 145, 18, 26, 195, 169, 19, 20, 13, 32, 69, 4, 176, 82, 40, 16, 108, 49, 108, 52, 57, 108, 23, 107, 108, 57, 47, 108, 50, 37, 0, 13, 81, 104, 97, 106, 116, 97, 110, 105, 32, 9, 134, 21, 20, 195, 161, 14, 1, 13, 8, 197, 4, 176, 82, 40, 16, 13, 11, 136, 22, 195, 161, 18, 20, 195, 161, 11, 13, 0, 7, 66, 81, 144, 80, 113, 0, 10, 135, 2, 5, 195, 173, 18, 22, 1, 13, 11, 136, 21, 4, 22, 1, 18, 195, 161, 14, 13, 17, 142, 8, 1, 19, 15, 14, 12, 195, 179, 19, 195, 161, 7, 15, 20, 13, 12, 137, 6, 195, 169, 14, 25, 5, 19, 5, 11, 13, 9, 134, 1, 14, 14, 195, 161, 12, 13, 10, 135, 12, 5, 195, 173, 18, 22, 1, 13, 0, 13, 2, 95, 39, 108, 48, 39, 89, 47, 52, 115, 83, 0, 28, 8, 20, 195, 169, 13, 195, 161, 10, 1, 47, 113, 65, 114, 57, 108, 23, 55, 109, 89, 0, 13, 81, 108, 101, 115, 122, 32, 16, 141, 20, 195, 161, 18, 7, 25, 1, 12, 195, 161, 19, 15, 14, 13, 11, 136, 20, 195, 169, 13, 195, 161, 10, 1, 13, 6, 195, 28, 243, 132, 13, 6, 195, 21, 49, 84, 13, 6, 195, 28, 243, 132, 13, 6, 195, 8, 19, 128, 72, 6, 195, 40, 19, 128, 20, 0, 28, 8, 6, 195, 182, 12, 195, 182, 20, 20, 83, 110, 55, 110, 47, 12, 23, 114, 55, 12, 0, 13, 81, 195, 161, 108, 108, 32, 7, 196, 12, 145, 201, 80, 13, 15, 140, 11, 22, 1, 12, 9, 6, 9, 11, 195, 161, 12, 20, 13, 20, 145, 13, 5, 7, 19, 26, 195, 161, 13, 12, 195, 161, 12, 20, 1, 20, 14, 9, 13, 25, 8, 6, 195, 182, 12, 195, 182, 20, 20, 83, 110, 55, 110, 47, 12, 23, 37, 91, 0, 13, 81, 105, 115, 32, 13, 138, 6, 5, 10, 22, 1, 4, 195, 161, 19, 26, 13, 6, 195, 21, 50, 75, 13, 11, 136, 6, 195, 182, 12, 195, 182, 20, 20, 13, 11, 136, 13, 195, 182, 7, 195, 182, 20, 20, 13, 10, 135, 10, 195, 186, 12, 9, 21, 19, 20, 0, 8, 197, 44, 243, 79, 49, 144, 13, 11, 136, 12, 5, 195, 173, 18, 195, 161, 19, 13, 20, 145, 20, 195, 161, 13, 15, 7, 1, 20, 15, 20, 20, 19, 195, 161, 7, 15, 20, 13, 16, 9, 95, 35, 45, 195, 169, 18, 197, 145, 12, 113, 52, 118, 55, 0, 14, 4, 95, 50, 48, 15, 107, 40, 89, 108, 72, 37, 49, 0, 0, 41, 74, 4, 192, 80, 4, 230, 65, 28, 242, 210, 4, 108, 55, 108, 48, 108, 67, 108, 81, 39, 49, 52, 108, 23, 49, 113, 67, 109, 91, 0, 13, 81, 107, 195, 169, 110, 121, 101, 115, 32, 16, 141, 20, 195, 161, 18, 7, 25, 1, 12, 195, 161, 19, 15, 11, 13, 50, 73, 20, 193, 75, 81, 35, 206, 36, 181, 83, 109, 55, 109, 49, 47, 52, 39, 50, 37, 49, 40, 91, 23, 84, 114, 55, 47, 39, 88, 108, 47, 114, 47, 0, 13, 81, 118, 195, 161, 108, 116, 111, 122, 97, 116, 195, 161, 116, 32, 14, 139, 195, 188, 26, 5, 13, 13, 195, 179, 4, 2, 1, 13, 16, 141, 2, 5, 18, 5, 14, 4, 5, 26, 195, 169, 19, 5, 11, 13, 9, 198, 5, 163, 206, 8, 19, 128, 13, 0, 7, 195, 88, 19, 128, 13, 22, 21, 67, 88, 19, 128, 84, 108, 50, 10, 6, 15, 37, 47, 12, 0, 13, 81, 105, 116, 116, 32, 32, 67, 88, 19, 128, 84, 108, 50, 23, 89, 111, 49, 91, 113, 81, 109, 65, 0, 13, 81, 115, 122, 195, 188, 107, 115, 195, 169, 103, 101, 109, 32, 18, 67, 88, 19, 128, 84, 108, 50, 23, 52, 114, 0, 13, 81, 114, 195, 161, 32, 23, 67, 88, 19, 128, 84, 108, 50, 23, 37, 72, 109, 57, 109, 0, 13, 81, 105, 100, 101, 106, 101, 32, 14, 139, 18, 195, 169, 19, 26, 5, 13, 18, 197, 145, 12, 13, 10, 135, 20, 15, 18, 20, 195, 161, 20, 13, 0, 18, 143, 8, 1, 14, 7, 19, 195, 186, 12, 25, 15, 26, 20, 195, 161, 11, 13, 27, 67, 8, 19, 139, 71, 108, 50, 49, 23, 91, 109, 81, 112, 47, 37, 0, 13, 81, 115, 101, 103, 195, 173, 116, 105, 32, 11, 136, 16, 195, 169, 12, 4, 195, 161, 20, 13, 9, 134, 16, 15, 8, 195, 161, 18, 13, 11, 136, 197, 145, 18, 195, 182, 11, 5, 20, 13, 15, 140, 20, 195, 169, 20, 5, 12, 195, 169, 18, 197, 145, 12, 13, 9, 134, 19, 26, 20, 195, 161, 18, 13, 6, 195, 64, 84, 131, 13, 12, 4, 95, 3, 1, 16, 50, 6, 108, 79, 23, 0, 10, 135, 10, 195, 186, 14, 9, 21, 19, 20, 0, 17, 2, 95, 41, 57, 6, 39, 71, 88, 114, 52, 115, 57, 109, 55, 0, 27, 38, 67, 5, 163, 206, 108, 88, 39, 50, 10, 6, 15, 81, 39, 50, 72, 39, 55, 49, 39, 72, 50, 37, 0, 13, 81, 103, 111, 110, 100, 111, 108, 107, 111, 100, 110, 105, 32, 12, 137, 8, 1, 12, 195, 161, 12, 195, 161, 20, 13, 6, 195, 5, 163, 206, 13, 9, 134, 3, 195, 173, 13, 197, 177, 13, 0, 17, 2, 95, 40, 71, 6, 108, 55, 88, 114, 52, 115, 57, 109, 55, 0, 27, 37, 70, 20, 208, 133, 72, 83, 128, 109, 65, 71, 109, 52, 109, 50, 23, 91, 109, 81, 112, 47, 107, 109, 47, 0, 13, 81, 115, 101, 103, 195, 173, 116, 104, 101, 116, 32, 6, 195, 44, 244, 129, 13, 34, 9, 13, 5, 7, 15, 12, 4, 195, 161, 19, 65, 109, 81, 39, 55, 72, 114, 91, 15, 48, 109, 72, 37, 81, 0, 13, 81, 112, 101, 100, 105, 103, 32, 12, 137, 13, 5, 7, 15, 12, 4, 195, 161, 19, 13, 9, 198, 20, 208, 133, 72, 83, 128, 13, 9, 198, 88, 86, 133, 80, 129, 84, 13, 0, 6, 195, 76, 244, 128, 13, 11, 67, 8, 20, 128, 71, 108, 52, 0, 42, 42, 0, 9, 2, 95, 46, 48, 39, 50, 47, 0, 11, 200, 24, 243, 25, 4, 208, 84, 61, 48, 13, 11, 136, 11, 1, 13, 5, 18, 195, 161, 20, 13, 15, 140, 20, 195, 182, 18, 20, 195, 169, 14, 5, 20, 5, 20, 13, 11, 136, 195, 182, 14, 195, 182, 11, 5, 20, 13, 15, 140, 5, 19, 26, 11, 195, 182, 26, 195, 182, 11, 5, 20, 13, 13, 138, 16, 1, 18, 1, 13, 195, 169, 20, 5, 18, 13, 8, 133, 195, 169, 18, 20, 5, 13, 15, 140, 9, 14, 4, 195, 173, 20, 22, 195, 161, 14, 25, 20, 13, 13, 138, 11, 195, 182, 14, 25, 22, 20, 195, 161, 18, 13, 6, 195, 5, 163, 203, 13, 11, 136, 20, 5, 18, 195, 188, 12, 5, 20, 13, 0, 12, 2, 95, 45, 65, 6, 37, 50, 40, 89, 0, 27, 20, 145, 12, 5, 8, 5, 20, 197, 145, 19, 195, 169, 7, 5, 9, 18, 197, 145, 12, 13, 19, 144, 19, 26, 5, 13, 195, 169, 12, 25, 12, 5, 195, 173, 18, 195, 161, 19, 13, 12, 201, 61, 69, 8, 60, 229, 1, 48, 19, 128, 13, 16, 140, 20, 5, 18, 13, 195, 169, 19, 26, 5, 20, 5, 19, 72, 65, 0, 10, 2, 95, 44, 84, 109, 89, 122, 118, 0, 15, 140, 8, 195, 161, 20, 20, 195, 169, 18, 20, 195, 161, 18, 13, 13, 138, 6, 15, 18, 13, 195, 161, 10, 195, 161, 20, 13, 0, 6, 195, 81, 68, 192, 13, 22, 147, 11, 1, 18, 12, 5, 14, 4, 195, 173, 20, 195, 169, 19, 5, 11, 2, 197, 145, 12, 13, 8, 133, 195, 173, 18, 19, 26, 13, 6, 195, 8, 18, 148, 13, 12, 67, 53, 36, 192, 65, 37, 89, 37, 89, 0, 25, 6, 195, 49, 68, 192, 20, 10, 2, 95, 51, 107, 114, 52, 39, 65, 0, 0, 15, 140, 18, 195, 161, 7, 25, 195, 186, 10, 20, 8, 1, 20, 13, 9, 198, 52, 17, 193, 76, 16, 130, 13, 14, 139, 8, 1, 19, 26, 14, 195, 161, 12, 10, 21, 11, 13, 9, 198, 29, 147, 210, 76, 16, 130, 13, 8, 133, 195, 173, 18, 20, 1, 13, 10, 2, 95, 50, 49, 109, 47, 12, 118, 0, 0, 12, 137, 8, 1, 19, 26, 14, 195, 161, 12, 4, 13, 11, 136, 195, 182, 20, 12, 5, 20, 5, 11, 13, 8, 197, 61, 69, 8, 60, 224, 13, 8, 133, 20, 195, 182, 18, 20, 13, 11, 136, 20, 197, 145, 12, 5, 20, 5, 11, 13, 7, 2, 95, 49, 109, 79, 0, 0, 17, 142, 11, 195, 188, 12, 195, 182, 14, 2, 19, 195, 169, 7, 5, 20, 13, 12, 137, 12, 5, 14, 14, 195, 169, 20, 5, 11, 13, 6, 195, 4, 69, 1, 13, 10, 2, 95, 48, 50, 40, 55, 55, 108, 0, 0, 9, 134, 15, 11, 15, 26, 195, 179, 13, 16, 141, 11, 195, 182, 18, 14, 25, 5, 26, 5, 20, 8, 5, 26, 13, 8, 2, 95, 55, 107, 113, 121, 0, 0, 8, 2, 95, 54, 107, 108, 121, 0, 0, 8, 197, 80, 84, 133, 53, 64, 13, 9, 198, 88, 19, 1, 32, 245, 129, 13, 8, 197, 76, 83, 139, 37, 64, 13, 7, 2, 95, 53, 110, 121, 0, 0, 21, 146, 11, 195, 182, 20, 5, 12, 5, 26, 5, 20, 20, 19, 195, 169, 7, 195, 169, 20, 13, 9, 198, 88, 86, 133, 77, 49, 64, 13, 19, 144, 8, 1, 19, 26, 14, 195, 161, 12, 8, 1, 20, 1, 20, 12, 1, 14, 13, 8, 2, 95, 52, 50, 113, 79, 0, 0, 16, 2, 95, 59, 48, 39, 50, 47, 39, 91, 84, 109, 89, 122, 118, 0, 9, 134, 195, 161, 20, 12, 1, 7, 13, 15, 140, 8, 9, 7, 1, 14, 25, 19, 26, 195, 161, 12, 1, 13, 0, 15, 2, 95, 58, 49, 109, 47, 12, 118, 91, 48, 39, 50, 47, 0, 0, 19, 144, 19, 26, 195, 161, 13, 195, 173, 20, 195, 179, 7, 195, 169, 16, 5, 11, 13, 11, 2, 95, 57, 49, 37, 55, 109, 50, 119, 0, 0, 23, 9, 5, 7, 25, 5, 26, 19, 195, 169, 7, 101, 103, 103, 121, 101, 115, 115, 195, 169, 103, 0, 29, 32, 70, 24, 244, 137, 57, 67, 212, 83, 39, 52, 37, 50, 47, 39, 47, 23, 113, 52, 50, 109, 49, 0, 13, 81, 195, 169, 114, 110, 101, 107, 32, 9, 198, 24, 244, 137, 57, 67, 212, 13, 9, 2, 95, 56, 67, 39, 55, 119, 0, 0, 13, 2, 95, 63, 49, 113, 52, 72, 118, 57, 109, 55, 0, 13, 138, 22, 5, 19, 26, 20, 5, 19, 195, 169, 7, 13, 10, 199, 57, 145, 82, 80, 84, 197, 36, 13, 6, 195, 32, 86, 128, 13, 0, 10, 2, 95, 62, 50, 108, 79, 39, 71, 0, 12, 137, 10, 195, 161, 18, 22, 195, 161, 14, 25, 13, 7, 196, 45, 83, 3, 76, 13, 7, 196, 41, 85, 14, 36, 13, 11, 200, 77, 161, 80, 80, 83, 66, 21, 32, 20, 0, 8, 197, 40, 83, 26, 36, 176, 13, 8, 197, 24, 83, 18, 4, 176, 13, 25, 6, 18, 195, 169, 19, 26, 5, 52, 113, 89, 109, 15, 84, 39, 55, 47, 0, 13, 81, 118, 111, 108, 116, 32, 9, 134, 18, 195, 169, 19, 26, 5, 13, 0, 11, 2, 95, 60, 49, 37, 91, 91, 109, 71, 0, 6, 195, 88, 150, 133, 13, 11, 136, 195, 188, 14, 14, 5, 16, 5, 14, 13, 53, 9, 20, 1, 14, 195, 161, 3, 19, 15, 11, 47, 108, 50, 114, 76, 39, 49, 23, 49, 113, 52, 72, 113, 91, 113, 52, 118, 55, 23, 37, 91, 0, 13, 82, 107, 195, 169, 114, 100, 195, 169, 115, 195, 169, 114, 197, 145, 108, 32, 105, 115, 32, 14, 139, 5, 12, 197, 145, 11, 5, 18, 5, 19, 14, 9, 13, 0, 17, 142, 4, 9, 19, 26, 20, 18, 9, 2, 195, 186, 3, 9, 195, 179, 13, 12, 201, 65, 35, 199, 72, 19, 79, 44, 21, 0, 13, 9, 198, 48, 20, 20, 61, 3, 203, 13, 6, 195, 57, 145, 76, 13, 0, 13, 138, 15, 19, 26, 20, 195, 161, 12, 25, 15, 14, 13, 8, 133, 8, 195, 161, 26, 1, 13, 11, 200, 44, 145, 15, 48, 115, 218, 80, 16, 13, 12, 137, 22, 5, 26, 5, 20, 197, 145, 10, 5, 13, 10, 135, 12, 195, 161, 20, 10, 21, 11, 13, 8, 133, 195, 173, 18, 22, 1, 13, 0, 8, 197, 80, 20, 148, 60, 176, 13, 44, 69, 56, 17, 217, 72, 16, 50, 108, 79, 52, 108, 10, 6, 15, 84, 108, 50, 10, 6, 15, 114, 55, 112, 47, 84, 108, 0, 13, 82, 118, 97, 110, 32, 195, 161, 108, 108, 195, 173, 116, 118, 97, 32, 12, 137, 9, 18, 195, 161, 14, 25, 21, 12, 20, 13, 9, 134, 20, 195, 161, 22, 18, 1, 13, 8, 197, 77, 161, 82, 16, 16, 20, 0, 26, 5, 6, 195, 188, 7, 7, 83, 111, 81, 12, 23, 110, 89, 12, 109, 0, 13, 81, 195, 182, 115, 115, 122, 101, 32, 22, 3, 18, 195, 161, 52, 114, 23, 37, 81, 113, 67, 0, 13, 81, 105, 103, 195, 169, 110, 121, 32, 31, 3, 18, 195, 161, 52, 114, 23, 89, 111, 49, 91, 113, 81, 109, 65, 0, 13, 81, 115, 122, 195, 188, 107, 115, 195, 169, 103, 101, 109, 32, 8, 133, 6, 195, 188, 7, 7, 13, 6, 131, 18, 195, 161, 13, 0, 30, 10, 20, 5, 18, 195, 188, 12, 5, 20, 5, 11, 47, 109, 52, 111, 55, 109, 47, 109, 49, 23, 37, 91, 0, 13, 81, 105, 115, 32, 24, 5, 5, 7, 195, 169, 18, 109, 81, 113, 52, 23, 84, 39, 55, 47, 0, 13, 81, 118, 111, 108, 116, 32, 15, 140, 19, 26, 1, 11, 195, 169, 18, 20, 197, 145, 10, 5, 13, 11, 136, 6, 15, 18, 13, 195, 161, 10, 1, 13, 15, 140, 13, 5, 7, 1, 12, 11, 15, 20, 195, 179, 10, 1, 13, 10, 199, 80, 85, 20, 20, 147, 133, 44, 13, 0, 12, 137, 18, 1, 11, 20, 195, 161, 18, 18, 1, 13, 0, 13, 138, 19, 5, 7, 195, 173, 20, 5, 14, 195, 169, 13, 12, 201, 13, 51, 205, 4, 115, 203, 32, 246, 128, 13, 0, 0, 10, 135, 12, 195, 169, 16, 8, 5, 20, 13, 15, 140, 16, 18, 15, 2, 12, 195, 169, 13, 195, 161, 10, 1, 13, 10, 135, 22, 195, 161, 12, 8, 1, 20, 13, 14, 139, 13, 197, 177, 11, 195, 182, 4, 195, 182, 20, 20, 13, 0, 20, 145, 6, 18, 1, 11, 3, 9, 195, 179, 22, 5, 26, 5, 20, 197, 145, 10, 5, 13, 40, 7, 22, 5, 7, 25, 195, 188, 11, 84, 109, 79, 111, 49, 10, 6, 15, 83, 37, 79, 109, 55, 109, 65, 71, 109, 0, 13, 81, 102, 105, 103, 121, 101, 108, 101, 109, 98, 101, 32, 6, 195, 88, 144, 195, 13, 0, 33, 4, 95, 226, 128, 163, 107, 114, 52, 39, 65, 89, 110, 81, 108, 55, 108, 49, 116, 83, 109, 55, 91, 39, 52, 39, 55, 114, 91, 57, 109, 55, 0, 12, 201, 37, 35, 196, 4, 195, 205, 8, 19, 128, 13, 9, 134, 20, 197, 177, 14, 197, 145, 13, 0, 15, 4, 95, 226, 128, 162, 55, 37, 91, 47, 108, 57, 109, 55, 0, 13, 138, 195, 169, 18, 20, 5, 12, 13, 195, 169, 20, 13, 13, 138, 11, 5, 18, 5, 19, 26, 20, 195, 188, 12, 13, 9, 134, 195, 182, 20, 12, 5, 20, 13, 9, 134, 195, 161, 12, 12, 1, 20, 13, 11, 136, 20, 195, 161, 14, 25, 195, 169, 18, 13, 10, 135, 8, 195, 169, 20, 6, 197, 145, 20, 0, 17, 142, 195, 182, 19, 19, 26, 5, 6, 195, 188, 7, 7, 195, 169, 19, 13, 25, 4, 195, 179, 20, 1, 115, 47, 108, 23, 47, 108, 52, 47, 115, 0, 13, 81, 116, 97, 114, 116, 195, 179, 32, 13, 138, 11, 9, 20, 195, 182, 12, 20, 195, 169, 19, 13, 16, 141, 16, 15, 12, 7, 195, 161, 18, 13, 5, 19, 20, 5, 18, 13, 10, 135, 195, 161, 12, 12, 8, 1, 20, 13, 10, 135, 11, 195, 169, 18, 8, 5, 20, 13, 9, 132, 195, 179, 20, 1, 13, 20, 22, 0, 7, 196, 24, 241, 211, 104, 76, 0, 43, 69, 32, 241, 217, 4, 224, 107, 39, 79, 108, 50, 23, 83, 39, 81, 23, 84, 113, 81, 88, 118, 72, 50, 37, 0, 13, 82, 102, 111, 103, 32, 118, 195, 169, 103, 122, 197, 145, 100, 110, 105, 32, 13, 138, 11, 195, 188, 12, 6, 195, 182, 12, 4, 9, 13, 8, 197, 77, 64, 66, 36, 192, 13, 12, 137, 10, 195, 161, 20, 19, 26, 8, 1, 20, 13, 12, 137, 11, 5, 18, 195, 188, 12, 8, 5, 20, 13, 16, 141, 5, 12, 197, 145, 6, 15, 18, 4, 21, 12, 8, 1, 20, 13, 8, 197, 37, 69, 8, 60, 224, 13, 0, 19, 4, 95, 226, 128, 166, 48, 39, 50, 47, 48, 39, 50, 47, 48, 39, 50, 47, 0, 13, 138, 5, 19, 26, 11, 195, 182, 26, 195, 169, 20, 13, 27, 6, 18, 195, 169, 19, 26, 20, 52, 113, 89, 47, 23, 84, 109, 50, 12, 37, 0, 13, 81, 118, 101, 110, 110, 105, 32, 24, 6, 18, 195, 169, 19, 26, 20, 52, 113, 89, 47, 23, 84, 109, 89, 0, 13, 81, 118, 101, 115, 122, 32, 13, 138, 22, 195, 161, 12, 20, 15, 26, 8, 1, 20, 13, 29, 6, 18, 195, 169, 19, 26, 20, 52, 113, 89, 47, 23, 84, 109, 47, 12, 109, 49, 0, 13, 81, 118, 101, 116, 116, 101, 107, 32, 14, 139, 18, 5, 14, 4, 5, 12, 11, 5, 26, 197, 145, 13, 9, 134, 9, 18, 195, 161, 14, 20, 13, 9, 134, 18, 195, 169, 19, 26, 20, 13, 0, 19, 67, 85, 48, 128, 195, 186, 101, 115, 98, 195, 169, 116, 0, 44, 29, 81, 116, 32, 19, 67, 85, 48, 128, 195, 186, 101, 115, 98, 195, 169, 110, 0, 44, 29, 81, 110, 32, 20, 67, 85, 48, 128, 195, 186, 101, 115, 98, 195, 169, 110, 0, 44, 29, 42, 81, 110, 32, 9, 134, 22, 1, 12, 195, 179, 11, 13, 6, 195, 16, 80, 192, 20, 0, 20, 145, 22, 9, 19, 19, 26, 1, 195, 161, 12, 12, 195, 173, 20, 1, 14, 195, 161, 13, 14, 139, 15, 16, 5, 18, 195, 161, 20, 15, 18, 15, 11, 13, 6, 131, 18, 195, 179, 13, 6, 195, 76, 242, 203, 13, 0, 15, 4, 95, 226, 128, 155, 37, 72, 113, 88, 118, 57, 109, 55, 0, 16, 141, 13, 5, 14, 14, 25, 9, 19, 195, 169, 7, 195, 169, 20, 13, 9, 134, 12, 195, 182, 11, 20, 5, 13, 7, 132, 19, 26, 195, 179, 13, 0, 15, 4, 95, 226, 128, 154, 37, 72, 113, 88, 118, 57, 109, 55, 0, 9, 198, 84, 118, 65, 56, 148, 192, 13, 34, 10, 20, 21, 4, 15, 13, 195, 161, 19, 21, 12, 47, 40, 72, 39, 65, 114, 91, 40, 55, 23, 49, 109, 55, 12, 0, 13, 81, 107, 101, 108, 108, 32, 30, 5, 1, 16, 18, 195, 179, 108, 48, 52, 115, 10, 6, 15, 72, 39, 55, 81, 39, 49, 0, 13, 81, 100, 111, 108, 103, 111, 107, 32, 56, 14, 19, 26, 5, 18, 5, 12, 22, 195, 169, 14, 25, 5, 9, 20, 89, 109, 52, 109, 55, 84, 113, 67, 109, 37, 47, 23, 65, 109, 81, 109, 52, 118, 91, 112, 47, 84, 109, 0, 13, 81, 109, 101, 103, 101, 114, 197, 145, 115, 195, 173, 116, 118, 101, 32, 11, 136, 2, 15, 12, 25, 7, 195, 179, 14, 13, 0, 25, 4, 95, 226, 128, 153, 57, 39, 71, 12, 39, 55, 72, 108, 55, 37, 37, 72, 113, 88, 118, 57, 109, 55, 0, 6, 195, 36, 65, 64, 13, 15, 140, 13, 1, 18, 1, 4, 22, 195, 161, 14, 25, 1, 9, 13, 13, 138, 20, 21, 4, 15, 13, 195, 161, 19, 21, 11, 13, 13, 138, 13, 195, 169, 18, 5, 20, 197, 177, 5, 11, 13, 6, 195, 36, 65, 64, 13, 0, 24, 4, 95, 226, 128, 152, 71, 108, 55, 39, 55, 72, 108, 55, 37, 37, 72, 113, 88, 118, 57, 109, 55, 0, 0, 15, 4, 95, 226, 128, 159, 37, 72, 113, 88, 118, 57, 109, 55, 0, 12, 137, 13, 195, 169, 18, 6, 195, 182, 12, 4, 13, 9, 198, 24, 148, 148, 5, 69, 1, 13, 0, 15, 4, 95, 226, 128, 158, 37, 72, 113, 88, 118, 57, 109, 55, 0, 0, 15, 4, 95, 226, 128, 157, 37, 72, 113, 88, 118, 57, 109, 55, 0, 19, 2, 95, 91, 67, 6, 37, 47, 115, 89, 110, 81, 55, 109, 47, 109, 91, 0, 27, 9, 134, 22, 195, 161, 18, 15, 19, 13, 0, 15, 4, 95, 226, 128, 156, 37, 72, 113, 88, 118, 57, 109, 55, 0, 20, 67, 4, 194, 71, 108, 55, 37, 81, 23, 84, 108, 50, 0, 13, 81, 118, 97, 110, 32, 10, 135, 8, 1, 26, 195, 161, 14, 11, 13, 18, 143, 6, 5, 12, 19, 26, 195, 179, 12, 1, 12, 195, 161, 19, 15, 11, 13, 6, 195, 76, 244, 147, 13, 0, 18, 4, 95, 226, 128, 147, 81, 39, 50, 72, 39, 55, 108, 47, 57, 109, 55, 0, 16, 141, 22, 195, 161, 12, 1, 19, 26, 1, 9, 2, 195, 179, 12, 13, 15, 140, 22, 195, 161, 12, 12, 1, 12, 11, 15, 26, 195, 179, 13, 9, 134, 22, 195, 161, 18, 14, 9, 13, 6, 195, 80, 84, 150, 13, 0, 35, 70, 21, 49, 84, 48, 81, 192, 109, 91, 109, 47, 55, 109, 81, 23, 109, 55, 113, 52, 107, 109, 47, 0, 13, 81, 101, 108, 195, 169, 114, 104, 101, 116, 32, 9, 198, 77, 161, 77, 64, 243, 148, 13, 9, 134, 12, 5, 7, 195, 179, 20, 13, 6, 195, 32, 81, 217, 13, 17, 66, 88, 144, 107, 108, 47, 12, 108, 55, 0, 44, 42, 81, 97, 108, 32, 0, 14, 2, 95, 95, 108, 55, 114, 107, 116, 88, 114, 91, 0, 27, 30, 67, 76, 242, 192, 91, 39, 49, 23, 47, 111, 52, 109, 55, 65, 109, 47, 0, 13, 81, 116, 195, 188, 114, 101, 108, 109, 101, 116, 32, 13, 138, 13, 15, 14, 4, 1, 14, 195, 161, 14, 11, 13, 6, 195, 76, 242, 192, 13, 20, 4, 95, 51, 48, 17, 107, 108, 52, 10, 65, 37, 50, 119, 108, 72, 37, 49, 108, 0, 0, 11, 200, 84, 118, 65, 56, 18, 203, 61, 32, 13, 41, 6, 7, 195, 169, 16, 5, 14, 81, 113, 48, 109, 50, 23, 89, 111, 49, 91, 113, 81, 109, 91, 109, 49, 0, 13, 81, 115, 122, 195, 188, 107, 115, 195, 169, 103, 101, 115, 101, 107, 32, 24, 6, 7, 195, 169, 16, 5, 14, 81, 113, 48, 109, 50, 15, 83, 40, 47, 0, 13, 81, 102, 117, 116, 32, 9, 134, 7, 195, 169, 16, 5, 14, 13, 7, 196, 25, 85, 14, 36, 13, 10, 135, 15, 12, 3, 19, 195, 179, 11, 13, 9, 134, 20, 195, 161, 22, 15, 14, 13, 0, 19, 2, 95, 93, 88, 6, 114, 52, 115, 89, 110, 81, 55, 109, 47, 109, 91, 0, 27, 9, 134, 22, 195, 161, 18, 15, 13, 13, 10, 135, 22, 195, 161, 12, 10, 15, 14, 13, 0, 38, 67, 56, 17, 217, 50, 108, 79, 10, 6, 15, 65, 109, 81, 55, 109, 48, 109, 47, 113, 91, 47, 0, 13, 81, 109, 101, 103, 108, 101, 112, 101, 116, 195, 169, 115, 116, 32, 9, 198, 8, 85, 5, 28, 82, 192, 13, 9, 198, 64, 147, 12, 4, 224, 84, 13, 9, 198, 20, 195, 69, 56, 226, 64, 13, 14, 139, 20, 1, 12, 195, 161, 12, 13, 195, 161, 14, 25, 13, 6, 195, 56, 17, 217, 13, 0, 6, 195, 4, 64, 84, 13, 6, 195, 64, 84, 148, 13, 9, 134, 13, 195, 186, 12, 9, 11, 13, 6, 195, 76, 244, 148, 13, 6, 195, 56, 18, 192, 13, 0, 17, 4, 95, 226, 128, 148, 49, 84, 37, 52, 47, 65, 112, 50, 40, 89, 0, 11, 200, 24, 83, 153, 20, 113, 84, 88, 80, 13, 12, 137, 8, 1, 20, 195, 161, 12, 25, 2, 1, 13, 10, 135, 195, 161, 12, 12, 195, 179, 11, 13, 9, 134, 10, 195, 161, 18, 19, 26, 13, 13, 138, 11, 195, 182, 22, 5, 20, 197, 145, 5, 14, 13, 0, 23, 69, 77, 163, 203, 80, 16, 89, 39, 49, 47, 108, 23, 65, 109, 81, 0, 13, 81, 109, 101, 103, 32, 41, 6, 13, 195, 179, 4, 10, 1, 65, 115, 79, 12, 108, 23, 65, 109, 81, 84, 114, 55, 47, 39, 88, 37, 49, 0, 13, 81, 109, 101, 103, 118, 195, 161, 108, 116, 111, 122, 105, 107, 32, 13, 138, 5, 12, 195, 169, 18, 195, 169, 19, 18, 5, 13, 38, 69, 44, 86, 133, 48, 144, 49, 109, 88, 109, 55, 37, 23, 108, 6, 23, 88, 109, 50, 113, 49, 109, 47, 0, 13, 82, 97, 32, 122, 101, 110, 195, 169, 107, 101, 116, 32, 13, 138, 5, 12, 11, 5, 18, 195, 188, 12, 10, 5, 13, 12, 137, 8, 1, 19, 26, 14, 195, 161, 12, 20, 13, 8, 197, 4, 176, 82, 80, 16, 13, 12, 201, 72, 83, 132, 20, 194, 197, 104, 146, 192, 13, 12, 201, 24, 145, 217, 20, 195, 69, 76, 82, 192, 13, 9, 134, 10, 195, 161, 18, 14, 1, 13, 8, 197, 80, 20, 148, 60, 208, 13, 8, 197, 32, 149, 20, 20, 208, 13, 9, 134, 22, 195, 182, 12, 7, 25, 13, 0, 10, 2, 95, 96, 47, 39, 65, 48, 108, 0, 6, 195, 8, 18, 201, 13, 35, 70, 20, 208, 133, 72, 82, 192, 109, 65, 71, 109, 52, 109, 49, 23, 89, 114, 65, 114, 52, 108, 0, 13, 81, 115, 122, 195, 161, 109, 195, 161, 114, 97, 32, 9, 198, 48, 85, 143, 56, 226, 64, 13, 11, 136, 18, 195, 169, 19, 26, 195, 169, 14, 13, 0, 13, 138, 18, 195, 169, 19, 26, 12, 5, 20, 5, 11, 13, 10, 199, 60, 181, 1, 80, 226, 85, 44, 13, 10, 199, 80, 83, 5, 24, 243, 143, 44, 13, 0, 11, 200, 44, 83, 5, 80, 177, 90, 36, 176, 13, 12, 137, 2, 195, 186, 10, 20, 1, 20, 10, 1, 13, 0, 9, 134, 4, 195, 182, 6, 197, 145, 13, 13, 138, 195, 188, 7, 25, 22, 195, 169, 4, 10, 5, 13, 11, 136, 22, 195, 169, 7, 26, 195, 169, 19, 13, 19, 4, 95, 51, 48, 15, 107, 108, 52, 10, 65, 37, 50, 119, 108, 72, 37, 49, 0, 0, 17, 142, 20, 21, 12, 1, 10, 4, 15, 14, 15, 19, 20, 195, 179, 12, 13, 9, 198, 61, 37, 143, 77, 48, 76, 13, 13, 138, 3, 19, 15, 13, 1, 7, 18, 195, 179, 12, 13, 0, 10, 199, 40, 83, 12, 20, 113, 197, 48, 13, 18, 143, 6, 5, 12, 195, 188, 12, 22, 9, 26, 19, 7, 195, 161, 12, 20, 13, 0, 45, 13, 11, 1, 20, 5, 7, 195, 179, 18, 9, 195, 161, 2, 1, 49, 108, 47, 109, 81, 115, 52, 37, 114, 71, 108, 23, 91, 39, 52, 39, 55, 39, 65, 0, 13, 81, 115, 111, 114, 111, 108, 111, 109, 32, 10, 135, 11, 195, 182, 20, 195, 169, 19, 13, 8, 133, 197, 145, 18, 26, 9, 13, 7, 196, 80, 81, 217, 20, 13, 43, 76, 36, 225, 143, 72, 208, 84, 36, 181, 83, 56, 18, 192, 37, 50, 83, 39, 52, 10, 65, 108, 47, 37, 49, 40, 91, 50, 108, 49, 15, 49, 109, 55, 12, 0, 13, 81, 107, 101, 108, 108, 32, 15, 140, 20, 1, 12, 195, 161, 12, 11, 15, 26, 15, 20, 20, 13, 8, 133, 195, 169, 18, 26, 9, 13, 0, 9, 134, 1, 18, 195, 161, 14, 25, 13, 36, 8, 14, 5, 22, 5, 12, 195, 169, 19, 50, 109, 84, 109, 55, 113, 91, 23, 47, 113, 65, 114, 57, 108, 0, 13, 81, 116, 195, 169, 109, 195, 161, 106, 97, 32, 9, 134, 10, 195, 161, 18, 14, 9, 13, 0, 10, 135, 2, 5, 195, 173, 18, 14, 9, 13, 18, 143, 195, 161, 12, 12, 1, 20, 20, 1, 18, 20, 195, 161, 19, 18, 1, 13, 13, 138, 18, 195, 169, 19, 26, 12, 5, 20, 5, 20, 13, 9, 134, 195, 182, 19, 195, 169, 20, 13, 12, 4, 95, 7, 18, 22, 47, 39, 65, 48, 108, 0, 0, 9, 198, 44, 83, 12, 20, 225, 75, 13, 18, 143, 19, 26, 195, 169, 11, 8, 195, 161, 26, 195, 161, 2, 195, 179, 12, 13, 10, 135, 11, 195, 182, 18, 195, 169, 20, 13, 11, 136, 12, 195, 169, 14, 25, 5, 7, 5, 13, 10, 135, 10, 195, 161, 18, 8, 1, 20, 13, 10, 135, 11, 195, 182, 18, 195, 169, 20, 13, 0, 9, 198, 72, 83, 132, 20, 197, 0, 13, 11, 136, 18, 195, 169, 19, 26, 195, 169, 20, 13, 12, 137, 19, 15, 11, 1, 19, 195, 161, 7, 1, 13, 12, 137, 10, 5, 12, 12, 5, 13, 26, 197, 145, 13, 9, 134, 13, 195, 179, 4, 15, 14, 13, 0, 10, 135, 8, 15, 19, 19, 26, 195, 186, 13, 20, 145, 9, 14, 20, 195, 169, 26, 13, 195, 169, 14, 25, 5, 11, 14, 195, 169, 12, 13, 15, 140, 5, 12, 11, 195, 169, 16, 26, 5, 12, 195, 169, 19, 13, 8, 197, 44, 81, 4, 20, 224, 22, 0, 6, 195, 88, 17, 217, 72, 17, 142, 7, 25, 197, 177, 18, 197, 145, 4, 195, 169, 19, 5, 9, 20, 13, 12, 201, 52, 147, 137, 77, 165, 5, 72, 225, 75, 13, 6, 195, 24, 17, 217, 13, 7, 195, 88, 17, 217, 76, 8, 0, 10, 135, 8, 195, 179, 2, 15, 18, 20, 13, 14, 139, 22, 5, 26, 5, 20, 195, 169, 19, 195, 169, 20, 13, 0, 13, 138, 19, 26, 195, 179, 12, 1, 12, 10, 15, 14, 13, 10, 135, 15, 16, 3, 9, 195, 179, 11, 13, 10, 135, 22, 9, 4, 5, 195, 179, 11, 13, 11, 200, 37, 51, 69, 72, 85, 12, 20, 224, 13, 7, 196, 21, 164, 133, 56, 13, 10, 135, 11, 195, 182, 4, 195, 182, 19, 13, 0, 16, 141, 13, 197, 177, 11, 195, 182, 4, 195, 169, 19, 195, 169, 20, 13, 0, 9, 198, 24, 20, 1, 16, 244, 192, 13, 13, 138, 5, 12, 1, 4, 195, 179, 20, 195, 179, 12, 13, 21, 66, 97, 96, 47, 37, 88, 109, 50, 110, 47, 12, 109, 55, 0, 44, 42, 81, 101, 108, 32, 0, 9, 198, 81, 81, 10, 4, 224, 75, 13, 48, 15, 10, 5, 12, 5, 14, 20, 11, 5, 26, 195, 169, 19, 195, 169, 20, 57, 109, 55, 109, 50, 47, 49, 109, 88, 113, 91, 113, 47, 23, 84, 114, 52, 57, 40, 49, 0, 13, 81, 118, 195, 161, 114, 106, 117, 107, 32, 18, 143, 20, 5, 12, 10, 5, 19, 195, 173, 20, 195, 169, 19, 195, 169, 20, 13, 10, 199, 36, 225, 15, 44, 243, 20, 4, 13, 12, 137, 19, 26, 195, 161, 12, 12, 10, 15, 14, 13, 0, 11, 200, 65, 35, 199, 72, 19, 66, 4, 224, 13, 10, 135, 12, 195, 169, 14, 25, 5, 7, 13, 0, 43, 73, 44, 20, 3, 76, 243, 1, 80, 244, 192, 49, 108, 48, 76, 39, 55, 108, 47, 39, 91, 23, 79, 108, 50, 116, 52, 115, 55, 0, 13, 81, 103, 121, 97, 110, 195, 186, 114, 195, 179, 108, 32, 45, 73, 44, 20, 3, 76, 243, 1, 80, 244, 192, 49, 108, 48, 76, 39, 55, 108, 47, 39, 91, 23, 47, 109, 52, 84, 109, 49, 52, 118, 55, 0, 13, 81, 116, 101, 114, 118, 101, 107, 114, 197, 145, 108, 32, 41, 73, 44, 20, 3, 76, 243, 1, 80, 244, 192, 49, 108, 48, 76, 39, 55, 108, 47, 39, 91, 23, 107, 112, 52, 109, 49, 109, 47, 0, 13, 81, 104, 195, 173, 114, 101, 107, 101, 116, 32, 58, 73, 44, 20, 3, 76, 243, 1, 80, 244, 192, 49, 108, 48, 76, 39, 55, 108, 47, 39, 91, 23, 71, 37, 88, 39, 67, 47, 108, 55, 108, 50, 91, 114, 81, 39, 49, 0, 13, 81, 98, 105, 122, 111, 110, 121, 116, 97, 108, 97, 110, 115, 195, 161, 103, 111, 107, 32, 12, 201, 44, 20, 3, 76, 243, 1, 80, 244, 192, 13, 8, 197, 76, 241, 15, 73, 64, 13, 0, 36, 6, 13, 195, 179, 4, 15, 20, 65, 115, 72, 39, 47, 23, 84, 114, 55, 108, 89, 47, 39, 65, 0, 13, 81, 118, 195, 161, 108, 97, 115, 122, 116, 111, 109, 32, 43, 70, 44, 83, 12, 20, 225, 64, 49, 109, 55, 12, 109, 50, 36, 23, 71, 37, 89, 47, 39, 89, 112, 47, 108, 50, 37, 0, 13, 81, 98, 105, 122, 116, 111, 115, 195, 173, 116, 97, 110, 105, 32, 34, 70, 44, 83, 12, 20, 225, 64, 49, 109, 55, 12, 109, 50, 109, 23, 83, 37, 88, 109, 47, 50, 37, 0, 13, 81, 102, 105, 122, 101, 116, 110, 105, 32, 39, 70, 44, 83, 12, 20, 225, 64, 49, 109, 55, 12, 109, 50, 109, 23, 108, 6, 15, 48, 52, 39, 81, 52, 108, 65, 0, 13, 82, 97, 32, 112, 114, 111, 103, 114, 97, 109, 32, 37, 70, 44, 83, 12, 20, 225, 64, 49, 109, 55, 12, 109, 50, 109, 15, 49, 110, 84, 109, 47, 50, 37, 109, 0, 13, 81, 107, 195, 182, 118, 101, 116, 110, 105, 101, 32, 13, 202, 4, 194, 193, 48, 208, 90, 61, 69, 1, 44, 13, 17, 142, 2, 9, 26, 15, 20, 20, 19, 195, 161, 7, 20, 195, 179, 12, 13, 9, 198, 44, 83, 12, 20, 225, 64, 13, 0, 18, 2, 95, 123, 49, 6, 109, 88, 72, 118, 49, 108, 48, 76, 39, 91, 0, 27, 12, 4, 95, 4, 9, 1, 47, 52, 113, 65, 108, 0, 0, 15, 140, 20, 195, 182, 18, 22, 195, 169, 14, 14, 25, 5, 12, 13, 0, 20, 4, 95, 226, 128, 179, 72, 40, 48, 55, 108, 108, 48, 39, 89, 47, 52, 115, 83, 0, 8, 197, 105, 82, 1, 57, 64, 13, 0, 15, 4, 95, 226, 128, 178, 108, 48, 39, 89, 47, 52, 115, 83, 0, 10, 135, 11, 9, 195, 173, 18, 14, 9, 13, 0, 10, 199, 28, 243, 132, 60, 197, 78, 44, 13, 7, 132, 195, 179, 18, 1, 13, 0, 14, 4, 95, 226, 128, 176, 109, 88, 52, 109, 55, 113, 49, 0, 22, 68, 36, 112, 90, 4, 37, 81, 108, 88, 108, 23, 84, 108, 50, 0, 13, 81, 118, 97, 110, 32, 15, 140, 11, 195, 188, 12, 195, 182, 14, 1, 4, 195, 179, 20, 13, 0, 16, 2, 95, 125, 84, 6, 113, 81, 49, 108, 48, 76, 39, 91, 0, 27, 35, 12, 7, 5, 14, 5, 18, 195, 161, 3, 9, 195, 179, 19, 81, 109, 50, 109, 52, 114, 119, 37, 115, 91, 10, 6, 15, 39, 49, 0, 13, 81, 111, 107, 32, 12, 137, 195, 182, 18, 195, 182, 11, 195, 182, 12, 13, 9, 134, 2, 195, 161, 3, 19, 9, 13, 15, 140, 7, 5, 14, 5, 18, 195, 161, 3, 9, 195, 179, 19, 13, 9, 134, 195, 161, 12, 12, 10, 1, 13, 8, 197, 48, 18, 206, 4, 176, 13, 8, 197, 44, 81, 4, 36, 112, 22, 0, 20, 2, 95, 124, 83, 111, 81, 12, 118, 55, 109, 81, 109, 91, 84, 39, 50, 108, 55, 0, 9, 198, 32, 145, 199, 100, 82, 192, 13, 9, 198, 44, 86, 133, 48, 146, 192, 13, 9, 198, 40, 21, 129, 76, 192, 84, 13, 9, 198, 77, 68, 133, 77, 54, 128, 13, 0, 13, 138, 22, 195, 169, 7, 26, 197, 145, 4, 9, 11, 13, 15, 140, 195, 182, 19, 19, 26, 5, 10, 195, 182, 14, 14, 9, 13, 0, 11, 200, 8, 84, 218, 21, 33, 90, 56, 144, 13, 33, 72, 53, 85, 1, 80, 179, 218, 36, 176, 65, 40, 47, 108, 47, 49, 39, 88, 37, 49, 10, 6, 15, 65, 109, 81, 0, 13, 81, 109, 101, 103, 32, 11, 200, 88, 243, 129, 80, 179, 218, 56, 16, 13, 11, 200, 4, 192, 75, 84, 195, 137, 84, 176, 13, 11, 136, 9, 7, 195, 169, 14, 25, 5, 12, 13, 11, 200, 88, 243, 129, 80, 179, 218, 36, 176, 13, 11, 200, 53, 85, 1, 80, 179, 218, 36, 176, 13, 0, 22, 6, 13, 195, 161, 19, 18, 1, 65, 114, 91, 52, 108, 23, 37, 91, 0, 13, 81, 105, 115, 32, 11, 136, 9, 7, 195, 169, 14, 25, 5, 11, 13, 9, 134, 22, 195, 161, 18, 10, 1, 13, 10, 135, 9, 14, 11, 195, 161, 2, 2, 13, 12, 137, 1, 7, 7, 195, 179, 4, 15, 20, 20, 13, 12, 137, 195, 173, 18, 195, 179, 4, 15, 20, 20, 13, 0, 7, 66, 105, 48, 90, 113, 0, 9, 198, 88, 17, 217, 80, 242, 192, 13, 14, 139, 1, 12, 10, 1, 19, 19, 195, 161, 7, 18, 1, 13, 10, 135, 22, 9, 20, 195, 161, 2, 1, 13, 9, 198, 60, 197, 129, 76, 226, 64, 13, 18, 70, 53, 97, 217, 61, 54, 128, 109, 65, 84, 113, 79, 113, 39, 109, 89, 0, 0, 10, 199, 48, 83, 79, 56, 64, 78, 36, 13, 10, 135, 10, 5, 12, 195, 182, 12, 20, 13, 11, 136, 5, 19, 26, 11, 195, 182, 26, 5, 13, 22, 147, 20, 195, 182, 18, 22, 195, 169, 14, 25, 10, 1, 22, 1, 19, 12, 1, 20, 15, 20, 13, 11, 136, 9, 18, 15, 4, 195, 161, 2, 1, 13, 15, 140, 2, 195, 173, 18, 195, 179, 19, 195, 161, 7, 18, 1, 13, 10, 135, 8, 195, 173, 22, 15, 20, 20, 13, 0, 27, 5, 5, 12, 19, 197, 145, 109, 55, 91, 118, 10, 6, 15, 113, 84, 109, 50, 0, 13, 81, 195, 169, 118, 101, 110, 32, 38, 5, 5, 12, 19, 197, 145, 109, 55, 91, 118, 23, 91, 39, 52, 71, 108, 50, 114, 55, 12, 115, 0, 13, 81, 115, 111, 114, 98, 97, 110, 195, 161, 108, 108, 195, 179, 32, 57, 72, 24, 83, 13, 85, 64, 84, 56, 144, 83, 109, 55, 65, 40, 47, 108, 47, 50, 37, 23, 108, 6, 15, 47, 114, 52, 79, 108, 55, 114, 91, 39, 49, 39, 50, 0, 13, 82, 97, 32, 116, 195, 161, 114, 103, 121, 97, 108, 195, 161, 115, 111, 107, 111, 110, 32, 8, 133, 5, 12, 19, 197, 145, 13, 11, 200, 81, 83, 1, 40, 242, 206, 4, 176, 13, 7, 196, 88, 148, 197, 48, 13, 0, 12, 137, 21, 14, 9, 195, 179, 2, 195, 179, 12, 13, 31, 10, 19, 26, 195, 161, 13, 21, 14, 11, 18, 1, 89, 114, 65, 40, 50, 49, 52, 108, 10, 6, 15, 108, 88, 0, 13, 81, 97, 122, 32, 12, 201, 24, 144, 84, 4, 195, 203, 56, 18, 192, 13, 12, 137, 9, 14, 4, 195, 173, 20, 15, 20, 20, 13, 13, 138, 19, 26, 195, 161, 13, 21, 14, 11, 18, 1, 13, 12, 201, 16, 243, 7, 61, 166, 129, 56, 18, 192, 13, 13, 138, 9, 18, 195, 161, 14, 25, 195, 161, 2, 1, 13, 0, 13, 138, 3, 19, 1, 12, 195, 179, 4, 15, 20, 20, 13, 59, 12, 10, 5, 12, 5, 14, 20, 197, 145, 19, 5, 2, 2, 57, 109, 55, 109, 50, 47, 118, 91, 109, 71, 12, 23, 76, 108, 48, 108, 72, 113, 49, 107, 40, 55, 12, 114, 91, 0, 13, 81, 99, 115, 97, 112, 97, 100, 195, 169, 107, 104, 117, 108, 108, 195, 161, 115, 32, 17, 198, 72, 244, 211, 105, 83, 0, 13, 81, 102, 117, 116, 111, 116, 116, 32, 15, 140, 6, 9, 14, 1, 14, 19, 26, 195, 173, 18, 15, 26, 13, 16, 141, 19, 26, 5, 18, 11, 5, 26, 5, 20, 197, 177, 5, 11, 13, 0, 19, 144, 14, 25, 9, 12, 22, 195, 161, 14, 15, 19, 19, 195, 161, 7, 18, 1, 13, 13, 138, 5, 19, 26, 11, 195, 182, 26, 195, 182, 11, 13, 14, 139, 11, 15, 18, 195, 161, 2, 2, 18, 195, 179, 12, 13, 14, 139, 19, 26, 195, 161, 13, 195, 173, 20, 15, 20, 20, 13, 0, 47, 13, 20, 195, 161, 13, 15, 7, 1, 20, 195, 161, 19, 18, 1, 47, 114, 65, 39, 81, 108, 47, 114, 91, 52, 108, 23, 57, 39, 81, 39, 91, 40, 55, 47, 0, 13, 81, 106, 111, 103, 111, 115, 117, 108, 116, 32, 21, 6, 11, 195, 182, 14, 25, 22, 49, 110, 67, 84, 23, 37, 91, 0, 13, 81, 105, 115, 32, 20, 145, 13, 5, 7, 11, 195, 182, 26, 5, 12, 195, 173, 20, 195, 169, 19, 18, 5, 13, 0, 9, 198, 80, 20, 148, 4, 195, 65, 13, 11, 136, 20, 5, 18, 22, 195, 188, 14, 11, 13, 7, 132, 11, 195, 169, 11, 13, 0, 41, 16, 12, 5, 7, 11, 195, 169, 14, 25, 5, 12, 13, 5, 19, 5, 2, 2, 55, 109, 81, 49, 113, 67, 109, 55, 65, 109, 91, 109, 71, 12, 23, 108, 88, 0, 13, 81, 97, 122, 32, 18, 143, 20, 1, 18, 20, 195, 179, 26, 11, 15, 4, 195, 161, 19, 18, 1, 13, 0, 9, 134, 20, 195, 182, 13, 9, 11, 13, 19, 144, 14, 25, 9, 12, 22, 195, 161, 14, 195, 173, 20, 195, 161, 19, 18, 1, 13, 0, 8, 133, 195, 188, 26, 5, 13, 13, 10, 135, 6, 195, 169, 12, 14, 5, 11, 13, 9, 134, 14, 195, 169, 22, 5, 14, 13, 9, 134, 20, 195, 169, 18, 5, 14, 13, 0, 24, 6, 8, 195, 173, 18, 5, 13, 107, 112, 52, 109, 65, 23, 84, 108, 50, 0, 13, 81, 118, 97, 110, 32, 10, 135, 12, 195, 169, 16, 10, 5, 14, 13, 0, 34, 9, 10, 195, 182, 8, 5, 20, 14, 5, 11, 57, 110, 107, 109, 47, 50, 109, 49, 23, 89, 115, 71, 108, 0, 13, 81, 115, 122, 195, 179, 98, 97, 32, 11, 136, 195, 169, 22, 5, 11, 2, 5, 14, 13, 12, 137, 13, 197, 177, 19, 15, 18, 14, 1, 11, 13, 9, 134, 13, 197, 177, 22, 5, 12, 13, 6, 195, 57, 147, 205, 13, 0, 16, 67, 53, 54, 144, 101, 109, 101, 115, 122, 112, 195, 169, 0, 29, 42, 9, 198, 44, 84, 133, 77, 65, 75, 13, 9, 134, 8, 195, 173, 18, 5, 11, 13, 13, 138, 13, 197, 177, 11, 195, 182, 4, 14, 5, 11, 13, 11, 136, 11, 195, 182, 22, 5, 20, 20, 5, 13, 9, 134, 197, 145, 18, 14, 5, 11, 13, 7, 132, 11, 195, 169, 13, 13, 6, 195, 53, 64, 64, 17, 0, 26, 5, 22, 195, 161, 7, 25, 84, 114, 79, 23, 113, 81, 109, 47, 12, 0, 13, 81, 195, 169, 103, 101, 116, 116, 32, 41, 10, 13, 5, 7, 25, 195, 169, 11, 2, 5, 14, 65, 109, 79, 113, 49, 71, 109, 50, 23, 84, 114, 52, 107, 108, 47, 115, 0, 13, 81, 118, 195, 161, 114, 104, 97, 116, 195, 179, 32, 10, 135, 20, 5, 18, 13, 195, 169, 11, 13, 15, 140, 20, 195, 161, 18, 19, 1, 4, 1, 12, 13, 1, 20, 13, 13, 138, 15, 18, 19, 26, 195, 161, 7, 2, 1, 14, 13, 8, 133, 22, 195, 161, 7, 25, 13, 7, 196, 48, 18, 201, 44, 13, 0, 9, 198, 32, 20, 131, 60, 195, 137, 13, 12, 137, 195, 186, 7, 25, 20, 197, 177, 14, 20, 13, 13, 138, 7, 25, 195, 161, 18, 20, 15, 20, 20, 1, 13, 6, 195, 88, 148, 218, 13, 9, 134, 20, 195, 161, 18, 7, 25, 13, 7, 132, 13, 195, 169, 7, 13, 18, 143, 3, 19, 195, 188, 20, 195, 182, 18, 20, 195, 182, 11, 195, 182, 14, 22, 0, 14, 139, 20, 1, 19, 26, 195, 173, 20, 15, 20, 20, 1, 13, 12, 137, 20, 21, 4, 10, 195, 161, 20, 15, 11, 13, 17, 66, 97, 128, 107, 116, 89, 12, 108, 55, 0, 44, 42, 81, 97, 108, 32, 23, 67, 97, 98, 73, 47, 37, 88, 109, 50, 107, 113, 47, 12, 109, 55, 0, 44, 42, 81, 101, 108, 32, 0, 34, 71, 32, 18, 148, 61, 69, 1, 44, 107, 108, 57, 47, 39, 47, 12, 108, 49, 23, 84, 113, 81, 52, 109, 0, 13, 81, 118, 195, 169, 103, 114, 101, 32, 13, 138, 19, 26, 195, 188, 12, 5, 20, 14, 5, 11, 13, 14, 203, 65, 35, 199, 72, 19, 74, 4, 146, 203, 4, 192, 13, 69, 13, 195, 186, 20, 13, 21, 20, 1, 20, 195, 179, 2, 1, 14, 116, 47, 65, 40, 47, 108, 47, 115, 71, 108, 50, 23, 37, 91, 23, 108, 89, 47, 23, 47, 108, 50, 114, 76, 39, 57, 57, 57, 114, 49, 0, 13, 83, 105, 115, 32, 97, 122, 116, 32, 116, 97, 110, 195, 161, 99, 115, 111, 108, 106, 195, 161, 107, 32, 16, 141, 12, 195, 161, 20, 15, 7, 1, 20, 195, 179, 2, 1, 14, 13, 10, 199, 16, 243, 7, 61, 165, 1, 44, 13, 6, 195, 85, 64, 76, 13, 0, 14, 139, 11, 195, 182, 22, 5, 20, 5, 12, 14, 5, 11, 13, 40, 14, 19, 26, 5, 18, 26, 197, 145, 4, 195, 169, 19, 2, 5, 14, 89, 109, 52, 88, 118, 72, 113, 91, 71, 109, 50, 23, 49, 109, 55, 12, 0, 13, 81, 107, 101, 108, 108, 32, 13, 138, 195, 169, 12, 5, 20, 195, 169, 2, 5, 14, 13, 13, 138, 20, 5, 13, 5, 20, 197, 145, 2, 5, 14, 13, 11, 136, 5, 19, 26, 11, 195, 182, 26, 20, 13, 22, 67, 97, 134, 0, 107, 108, 52, 65, 37, 50, 119, 12, 35, 55, 0, 44, 42, 81, 97, 108, 32, 0, 7, 195, 48, 84, 218, 72, 22, 30, 67, 48, 84, 218, 55, 109, 89, 23, 108, 57, 114, 50, 55, 39, 47, 12, 0, 13, 81, 97, 106, 195, 161, 110, 108, 111, 116, 116, 32, 25, 8, 8, 9, 19, 19, 26, 195, 188, 11, 107, 37, 89, 12, 111, 49, 23, 109, 55, 0, 13, 81, 101, 108, 32, 9, 134, 22, 195, 161, 7, 14, 9, 13, 13, 138, 20, 195, 161, 13, 15, 7, 1, 20, 20, 1, 13, 11, 136, 22, 195, 169, 12, 10, 195, 188, 11, 13, 8, 133, 6, 195, 188, 19, 20, 13, 0, 63, 14, 20, 5, 18, 22, 5, 26, 195, 169, 19, 195, 169, 22, 5, 12, 47, 109, 34, 84, 109, 88, 113, 91, 113, 84, 109, 55, 23, 83, 39, 81, 55, 108, 55, 49, 39, 88, 115, 23, 119, 113, 81, 0, 13, 82, 102, 111, 103, 108, 97, 108, 107, 111, 122, 195, 179, 32, 99, 195, 169, 103, 32, 9, 198, 37, 51, 69, 73, 97, 64, 13, 9, 198, 80, 83, 5, 57, 65, 64, 13, 12, 4, 95, 35, 51, 50, 89, 115, 49, 110, 88, 0, 0, 12, 201, 32, 149, 129, 80, 179, 218, 61, 69, 0, 13, 17, 142, 11, 195, 169, 16, 26, 197, 145, 4, 8, 5, 20, 14, 5, 11, 13, 16, 141, 20, 5, 18, 5, 12, 195, 169, 19, 195, 169, 2, 5, 14, 13, 16, 141, 13, 195, 169, 18, 20, 195, 169, 11, 195, 169, 2, 5, 14, 13, 0, 10, 135, 20, 197, 145, 12, 195, 188, 11, 13, 0, 18, 143, 20, 195, 182, 18, 20, 195, 169, 14, 5, 20, 195, 169, 2, 5, 14, 13, 18, 143, 13, 5, 7, 11, 195, 182, 20, 195, 169, 19, 195, 169, 2, 5, 14, 13, 18, 143, 19, 195, 188, 12, 12, 25, 5, 19, 26, 20, 197, 145, 2, 5, 14, 13, 11, 136, 9, 7, 1, 26, 19, 195, 161, 7, 13, 0, 21, 146, 22, 9, 19, 19, 26, 1, 20, 195, 169, 18, 195, 169, 19, 195, 169, 22, 5, 12, 13, 12, 137, 2, 5, 12, 197, 145, 12, 195, 188, 11, 13, 9, 198, 40, 83, 5, 105, 65, 64, 13, 9, 198, 44, 20, 3, 76, 243, 20, 13, 0, 9, 198, 8, 83, 69, 57, 65, 75, 13, 9, 134, 195, 169, 12, 14, 5, 11, 13, 13, 138, 8, 5, 12, 25, 26, 5, 20, 195, 188, 11, 13, 10, 135, 11, 195, 173, 22, 195, 188, 12, 13, 11, 136, 14, 195, 169, 8, 195, 161, 14, 25, 13, 23, 67, 97, 98, 64, 47, 37, 88, 109, 50, 107, 108, 47, 12, 108, 55, 0, 44, 42, 81, 97, 108, 32, 26, 67, 97, 98, 64, 47, 37, 88, 109, 50, 107, 108, 47, 39, 72, 37, 49, 37, 81, 0, 44, 42, 81, 105, 103, 32, 0, 7, 196, 21, 164, 133, 76, 13, 11, 200, 77, 160, 86, 5, 160, 84, 61, 64, 13, 18, 143, 13, 9, 14, 9, 19, 26, 20, 5, 18, 5, 12, 14, 195, 182, 11, 13, 12, 137, 2, 195, 188, 14, 20, 5, 20, 14, 9, 13, 26, 67, 96, 150, 0, 47, 37, 88, 109, 50, 49, 37, 55, 109, 50, 119, 12, 109, 55, 0, 44, 42, 81, 101, 108, 32, 0, 9, 134, 12, 195, 169, 16, 22, 5, 13, 12, 137, 15, 18, 19, 26, 195, 161, 7, 15, 20, 13, 8, 197, 64, 243, 148, 60, 176, 13, 0, 9, 198, 32, 83, 25, 21, 162, 64, 13, 9, 198, 40, 83, 5, 57, 66, 64, 13, 0, 11, 136, 6, 5, 8, 195, 169, 18, 2, 5, 13, 13, 138, 13, 21, 14, 11, 195, 161, 19, 14, 1, 11, 13, 15, 140, 22, 195, 161, 12, 20, 15, 26, 20, 1, 20, 14, 9, 13, 14, 139, 7, 1, 26, 4, 1, 19, 195, 161, 7, 15, 20, 13, 13, 138, 22, 195, 161, 12, 12, 1, 12, 14, 1, 11, 13, 10, 135, 20, 1, 12, 195, 161, 12, 20, 13, 8, 133, 6, 15, 11, 195, 186, 13, 10, 199, 20, 197, 5, 72, 161, 68, 80, 13, 6, 195, 64, 84, 212, 13, 8, 195, 53, 66, 64, 17, 42, 42, 0, 12, 137, 19, 26, 5, 18, 26, 197, 145, 10, 5, 13, 11, 136, 10, 15, 7, 195, 161, 22, 1, 12, 13, 18, 143, 18, 5, 14, 4, 5, 12, 12, 5, 14, 5, 19, 19, 195, 169, 7, 13, 0, 10, 135, 16, 15, 12, 3, 195, 161, 14, 13, 31, 9, 11, 195, 169, 19, 26, 195, 188, 12, 20, 49, 113, 89, 111, 55, 47, 23, 52, 115, 55, 108, 0, 13, 81, 114, 195, 179, 108, 97, 32, 12, 137, 20, 195, 169, 13, 195, 161, 22, 1, 12, 13, 8, 197, 28, 22, 132, 4, 112, 13, 9, 198, 52, 81, 212, 84, 66, 129, 13, 9, 198, 24, 241, 204, 4, 194, 129, 13, 16, 141, 13, 195, 169, 12, 20, 195, 179, 19, 195, 161, 7, 15, 20, 13, 11, 136, 20, 195, 173, 16, 21, 19, 15, 11, 13, 12, 137, 11, 9, 20, 1, 12, 195, 161, 12, 20, 13, 12, 137, 11, 195, 169, 19, 26, 195, 188, 12, 20, 13, 7, 132, 11, 195, 169, 19, 13, 9, 134, 195, 182, 19, 19, 26, 5, 13, 0, 64, 17, 195, 161, 12, 12, 1, 13, 20, 9, 20, 11, 195, 161, 18, 19, 195, 161, 7, 35, 55, 12, 108, 65, 47, 37, 47, 49, 114, 52, 91, 114, 81, 23, 47, 109, 34, 84, 109, 88, 109, 47, 113, 52, 118, 55, 0, 13, 81, 116, 101, 114, 118, 101, 122, 101, 116, 195, 169, 114, 197, 145, 108, 32, 6, 195, 4, 67, 129, 13, 9, 198, 32, 148, 132, 21, 66, 64, 13, 9, 198, 52, 243, 132, 81, 82, 192, 13, 7, 132, 11, 195, 169, 18, 13, 0, 12, 137, 20, 5, 18, 13, 195, 169, 2, 5, 14, 13, 9, 198, 40, 83, 5, 57, 66, 75, 13, 13, 138, 9, 19, 11, 15, 12, 195, 161, 19, 15, 11, 13, 13, 67, 5, 67, 64, 114, 47, 113, 109, 65, 0, 42, 42, 0, 9, 134, 195, 173, 7, 195, 169, 18, 13, 13, 138, 19, 5, 18, 5, 7, 195, 169, 2, 5, 14, 13, 10, 135, 2, 5, 14, 14, 195, 188, 11, 13, 17, 142, 11, 9, 195, 161, 12, 12, 195, 173, 20, 195, 161, 19, 15, 14, 13, 11, 136, 22, 1, 12, 195, 179, 19, 21, 12, 13, 15, 140, 20, 1, 18, 20, 1, 12, 13, 195, 161, 22, 1, 12, 13, 11, 136, 4, 18, 195, 161, 7, 21, 12, 20, 13, 7, 132, 11, 195, 169, 16, 13, 0, 17, 67, 80, 84, 218, 47, 109, 89, 15, 49, 37, 0, 13, 81, 107, 105, 32, 17, 142, 11, 195, 182, 18, 195, 188, 12, 13, 195, 169, 14, 25, 5, 9, 13, 6, 195, 80, 84, 218, 13, 0, 20, 145, 2, 9, 26, 15, 14, 25, 20, 1, 12, 1, 14, 19, 195, 161, 7, 15, 11, 13, 13, 138, 195, 182, 18, 195, 182, 11, 195, 182, 12, 20, 13, 13, 138, 11, 195, 182, 26, 20, 21, 4, 15, 20, 20, 13, 9, 198, 20, 118, 69, 80, 83, 64, 13, 0, 10, 199, 77, 162, 210, 37, 5, 5, 80, 13, 0, 18, 143, 13, 5, 7, 19, 26, 15, 18, 195, 173, 20, 195, 161, 19, 15, 11, 13, 19, 144, 20, 195, 161, 13, 15, 7, 1, 20, 195, 161, 19, 195, 161, 22, 1, 12, 13, 12, 137, 13, 197, 177, 11, 195, 182, 4, 197, 145, 13, 7, 132, 11, 195, 169, 20, 13, 0, 20, 145, 20, 1, 12, 195, 161, 12, 11, 15, 26, 195, 179, 10, 195, 161, 22, 1, 12, 13, 18, 143, 13, 1, 7, 25, 1, 18, 15, 18, 19, 26, 195, 161, 7, 15, 14, 13, 12, 137, 22, 1, 19, 195, 161, 18, 14, 1, 16, 20, 0, 21, 146, 195, 161, 12, 12, 1, 13, 20, 9, 20, 11, 195, 161, 18, 195, 161, 22, 1, 12, 13, 19, 144, 11, 195, 182, 26, 12, 5, 13, 195, 169, 14, 25, 195, 169, 2, 5, 14, 13, 7, 132, 7, 195, 161, 26, 13, 6, 195, 4, 67, 137, 13, 0, 11, 136, 9, 10, 5, 19, 26, 20, 197, 145, 13, 40, 8, 11, 195, 182, 18, 195, 188, 12, 9, 49, 110, 52, 111, 55, 37, 23, 110, 89, 12, 109, 81, 71, 118, 55, 0, 13, 81, 195, 182, 115, 115, 122, 101, 103, 98, 197, 145, 108, 32, 24, 4, 5, 12, 195, 169, 109, 55, 113, 23, 84, 109, 47, 37, 49, 0, 13, 81, 118, 101, 116, 105, 107, 32, 7, 132, 5, 12, 195, 169, 13, 0, 7, 196, 81, 81, 15, 44, 76, 44, 6, 18, 1, 14, 7, 195, 186, 52, 108, 50, 81, 116, 23, 47, 37, 89, 47, 84, 37, 91, 109, 55, 118, 57, 109, 0, 13, 81, 116, 105, 115, 122, 116, 118, 105, 115, 101, 108, 197, 145, 106, 101, 32, 11, 136, 22, 195, 161, 7, 25, 1, 9, 20, 13, 0, 12, 201, 24, 145, 217, 20, 195, 69, 105, 65, 84, 13, 16, 141, 22, 195, 169, 12, 5, 13, 195, 169, 14, 25, 195, 169, 20, 13, 0, 0, 10, 135, 2, 1, 14, 195, 161, 14, 20, 13, 9, 134, 195, 173, 18, 14, 1, 11, 13, 11, 136, 20, 195, 161, 13, 1, 4, 20, 1, 13, 6, 195, 9, 34, 84, 13, 10, 135, 6, 18, 195, 161, 19, 26, 20, 13, 0, 13, 138, 195, 161, 12, 12, 195, 161, 19, 2, 1, 14, 13, 8, 133, 14, 195, 161, 12, 1, 13, 0, 41, 8, 11, 195, 182, 14, 25, 22, 5, 11, 49, 110, 67, 84, 109, 49, 23, 55, 114, 47, 107, 108, 47, 39, 108, 49, 0, 13, 81, 108, 195, 161, 116, 104, 97, 116, 195, 179, 97, 107, 32, 26, 69, 44, 148, 197, 8, 32, 49, 37, 91, 12, 109, 71, 12, 23, 109, 91, 118, 0, 13, 81, 101, 115, 197, 145, 32, 13, 138, 5, 13, 12, 195, 173, 20, 5, 20, 20, 5, 13, 11, 136, 195, 161, 18, 21, 12, 14, 1, 11, 13, 11, 136, 11, 195, 182, 14, 25, 22, 5, 11, 13, 0, 11, 136, 22, 9, 20, 195, 161, 2, 1, 14, 13, 33, 70, 60, 193, 1, 49, 32, 64, 39, 55, 72, 108, 55, 52, 108, 6, 15, 71, 40, 49, 12, 108, 50, 0, 13, 81, 98, 117, 107, 107, 97, 110, 32, 14, 139, 8, 15, 26, 26, 195, 161, 20, 5, 20, 20, 5, 13, 13, 138, 20, 1, 18, 9, 6, 195, 161, 22, 1, 12, 13, 12, 137, 12, 195, 169, 20, 5, 26, 14, 5, 11, 13, 14, 139, 195, 161, 12, 12, 195, 173, 20, 15, 20, 20, 1, 13, 9, 198, 60, 193, 1, 49, 32, 64, 13, 0, 14, 139, 4, 15, 2, 195, 161, 19, 195, 161, 22, 1, 12, 13, 12, 137, 6, 15, 18, 13, 195, 161, 2, 1, 14, 13, 16, 141, 11, 195, 169, 18, 4, 195, 169, 19, 5, 11, 2, 5, 14, 13, 51, 9, 6, 15, 18, 13, 195, 161, 2, 1, 14, 83, 39, 52, 65, 114, 71, 108, 50, 23, 108, 6, 15, 47, 109, 52, 84, 109, 88, 109, 47, 71, 109, 50, 0, 13, 82, 97, 32, 116, 101, 114, 118, 101, 122, 101, 116, 98, 101, 110, 32, 6, 195, 20, 197, 128, 13, 9, 198, 29, 144, 76, 60, 115, 211, 13, 16, 141, 11, 21, 20, 1, 20, 195, 161, 19, 15, 11, 2, 1, 14, 13, 8, 4, 95, 35, 45, 5, 109, 0, 0, 32, 7, 19, 26, 195, 179, 12, 195, 179, 89, 115, 55, 115, 23, 72, 110, 50, 47, 113, 91, 0, 13, 81, 100, 195, 182, 110, 116, 195, 169, 115, 32, 14, 139, 20, 195, 161, 18, 7, 25, 1, 12, 14, 1, 11, 13, 38, 7, 19, 26, 195, 179, 12, 195, 179, 89, 115, 55, 115, 23, 57, 108, 84, 108, 91, 55, 108, 47, 39, 47, 0, 13, 81, 106, 97, 118, 97, 115, 108, 97, 116, 111, 116, 32, 13, 138, 11, 5, 18, 5, 20, 195, 169, 2, 5, 14, 13, 7, 196, 81, 81, 15, 52, 13, 10, 135, 19, 26, 195, 179, 12, 195, 179, 13, 0, 14, 139, 8, 1, 20, 195, 161, 19, 195, 161, 2, 1, 14, 13, 15, 140, 195, 182, 19, 19, 26, 5, 195, 188, 12, 14, 5, 11, 13, 8, 197, 20, 193, 71, 21, 64, 13, 8, 197, 40, 241, 193, 37, 64, 13, 16, 141, 18, 195, 169, 19, 26, 12, 5, 7, 195, 169, 22, 5, 12, 13, 8, 197, 57, 147, 205, 77, 160, 13, 9, 134, 20, 195, 182, 13, 14, 9, 13, 8, 197, 41, 85, 15, 81, 64, 13, 0, 15, 140, 195, 169, 18, 20, 5, 12, 13, 195, 169, 2, 5, 14, 13, 18, 143, 11, 9, 5, 7, 195, 169, 19, 26, 195, 173, 20, 5, 20, 20, 5, 13, 15, 140, 21, 20, 1, 12, 22, 195, 161, 14, 25, 2, 1, 14, 13, 12, 137, 19, 26, 5, 18, 4, 195, 161, 9, 7, 22, 0, 72, 73, 24, 83, 142, 80, 20, 148, 61, 69, 0, 83, 109, 50, 12, 47, 108, 52, 47, 39, 47, 12, 23, 37, 91, 49, 39, 55, 114, 49, 23, 65, 111, 49, 110, 47, 12, 109, 47, 113, 91, 113, 47, 0, 13, 82, 105, 115, 107, 111, 108, 195, 161, 107, 32, 109, 197, 177, 107, 195, 182, 100, 116, 101, 116, 195, 169, 115, 195, 169, 116, 32, 16, 141, 20, 5, 11, 9, 14, 20, 5, 20, 195, 169, 2, 5, 14, 13, 13, 138, 9, 7, 1, 26, 19, 195, 161, 7, 15, 19, 13, 16, 141, 2, 197, 177, 14, 20, 5, 20, 20, 195, 169, 2, 5, 14, 13, 9, 134, 22, 5, 12, 195, 188, 11, 13, 6, 195, 29, 5, 64, 17, 9, 4, 95, 35, 45, 1, 108, 0, 21, 0, 0, 8, 197, 4, 64, 84, 61, 64, 13, 11, 136, 14, 25, 195, 186, 10, 20, 195, 179, 13, 16, 141, 22, 195, 161, 12, 20, 15, 26, 1, 20, 2, 195, 179, 12, 13, 20, 145, 19, 20, 18, 1, 20, 195, 169, 7, 9, 195, 161, 10, 195, 161, 22, 1, 12, 13, 11, 136, 19, 26, 20, 18, 195, 161, 10, 11, 13, 0, 19, 144, 11, 195, 169, 16, 22, 9, 19, 5, 12, 5, 20, 195, 169, 2, 5, 14, 13, 19, 144, 1, 12, 11, 1, 12, 13, 1, 26, 195, 161, 19, 195, 161, 2, 1, 14, 13, 12, 137, 10, 5, 12, 5, 14, 19, 195, 169, 7, 13, 12, 137, 8, 5, 12, 25, 9, 19, 195, 169, 7, 13, 0, 28, 5, 20, 195, 182, 2, 2, 47, 110, 71, 12, 23, 39, 52, 89, 114, 81, 0, 13, 81, 111, 114, 115, 122, 195, 161, 103, 32, 79, 5, 20, 195, 182, 2, 2, 47, 110, 71, 12, 23, 107, 109, 57, 109, 50, 23, 89, 108, 49, 108, 72, 39, 88, 37, 49, 23, 83, 109, 55, 23, 108, 23, 83, 109, 55, 107, 118, 88, 109, 47, 0, 13, 85, 104, 101, 108, 121, 101, 110, 32, 115, 122, 97, 107, 97, 100, 111, 122, 105, 107, 32, 102, 101, 108, 32, 97, 32, 102, 101, 108, 104, 197, 145, 122, 101, 116, 32, 49, 5, 20, 195, 182, 2, 2, 47, 110, 71, 12, 23, 83, 109, 55, 107, 118, 23, 84, 108, 55, 115, 89, 112, 50, 117, 0, 13, 82, 102, 101, 108, 104, 197, 145, 32, 118, 97, 108, 195, 179, 115, 122, 195, 173, 110, 197, 177, 32, 26, 67, 85, 64, 84, 40, 47, 108, 47, 15, 49, 108, 48, 39, 47, 12, 0, 13, 81, 107, 97, 112, 111, 116, 116, 32, 8, 133, 20, 195, 182, 2, 2, 13, 0, 9, 198, 80, 17, 207, 104, 21, 0, 13, 6, 195, 85, 64, 83, 13, 7, 196, 4, 197, 68, 80, 13, 7, 196, 81, 81, 10, 4, 13, 9, 134, 14, 25, 1, 11, 195, 186, 13, 7, 196, 81, 81, 14, 36, 13, 0, 8, 197, 48, 84, 218, 20, 176, 72, 26, 5, 22, 195, 161, 12, 20, 84, 114, 55, 47, 23, 84, 39, 55, 50, 108, 0, 13, 81, 118, 111, 108, 110, 97, 32, 8, 197, 80, 81, 217, 20, 176, 13, 22, 133, 22, 195, 161, 12, 20, 13, 81, 104, 105, 118, 97, 116, 97, 108, 111, 115, 115, 195, 161, 32, 9, 134, 11, 195, 182, 26, 2, 5, 13, 8, 133, 22, 195, 161, 12, 20, 13, 0, 9, 198, 4, 176, 82, 41, 82, 192, 13, 0, 12, 137, 195, 179, 18, 195, 161, 11, 2, 1, 14, 13, 12, 137, 22, 9, 12, 195, 161, 7, 2, 1, 14, 13, 9, 134, 195, 182, 14, 14, 5, 11, 13, 6, 195, 32, 244, 16, 13, 10, 4, 95, 35, 45, 9, 109, 37, 0, 21, 0, 43, 68, 80, 17, 202, 4, 47, 108, 81, 57, 108, 23, 37, 91, 23, 76, 108, 47, 55, 108, 49, 39, 88, 37, 49, 0, 13, 82, 105, 115, 32, 99, 115, 97, 116, 108, 97, 107, 111, 122, 105, 107, 32, 7, 196, 80, 17, 202, 4, 13, 11, 200, 52, 243, 132, 32, 21, 10, 84, 176, 13, 0, 10, 135, 11, 195, 169, 18, 10, 5, 14, 13, 12, 137, 195, 169, 18, 4, 5, 11, 5, 12, 20, 13, 14, 139, 5, 12, 5, 13, 26, 197, 145, 11, 2, 5, 14, 13, 9, 134, 19, 195, 161, 22, 2, 1, 13, 12, 201, 28, 243, 132, 60, 192, 84, 80, 19, 0, 13, 15, 140, 20, 5, 19, 20, 195, 188, 12, 5, 20, 14, 5, 11, 13, 9, 134, 13, 195, 186, 12, 22, 1, 13, 8, 197, 88, 148, 211, 104, 16, 13, 0, 10, 135, 22, 9, 20, 195, 161, 10, 1, 13, 15, 140, 19, 26, 195, 182, 22, 5, 7, 5, 11, 2, 5, 14, 13, 42, 8, 6, 5, 12, 195, 169, 2, 5, 14, 83, 109, 55, 113, 71, 109, 50, 23, 114, 55, 107, 108, 47, 6, 15, 71, 6, 109, 0, 13, 82, 195, 161, 108, 108, 104, 97, 116, 32, 98, 101, 32, 0, 23, 7, 19, 26, 195, 179, 22, 1, 12, 89, 115, 84, 108, 55, 23, 108, 88, 0, 13, 81, 97, 122, 32, 16, 141, 11, 15, 14, 3, 5, 16, 3, 9, 195, 179, 2, 1, 14, 13, 10, 135, 19, 26, 195, 179, 22, 1, 12, 13, 16, 141, 8, 5, 12, 25, 19, 195, 169, 7, 5, 11, 2, 5, 14, 13, 10, 135, 19, 26, 195, 179, 22, 1, 12, 13, 7, 132, 1, 12, 195, 161, 13, 0, 31, 70, 77, 163, 198, 81, 97, 82, 89, 39, 83, 47, 84, 109, 52, 23, 50, 109, 84, 113, 47, 0, 13, 81, 110, 101, 118, 195, 169, 116, 32, 12, 137, 14, 1, 16, 20, 195, 161, 18, 2, 1, 13, 11, 200, 53, 85, 15, 28, 21, 10, 84, 176, 13, 11, 200, 24, 83, 11, 21, 33, 83, 56, 144, 13, 11, 200, 20, 193, 143, 28, 17, 20, 4, 176, 13, 0, 9, 134, 11, 5, 26, 4, 197, 145, 13, 0, 17, 142, 22, 195, 173, 22, 13, 195, 161, 14, 25, 1, 9, 22, 1, 12, 13, 19, 144, 10, 15, 7, 19, 26, 1, 2, 195, 161, 12, 25, 15, 11, 2, 1, 14, 13, 0, 14, 203, 57, 145, 82, 76, 19, 153, 4, 115, 203, 72, 16, 13, 10, 199, 24, 147, 13, 20, 178, 197, 48, 13, 10, 199, 77, 161, 82, 36, 229, 5, 52, 13, 9, 134, 20, 195, 173, 16, 21, 19, 13, 0, 12, 137, 11, 195, 182, 20, 5, 14, 4, 197, 145, 13, 11, 136, 6, 5, 8, 195, 169, 18, 5, 20, 13, 0, 13, 138, 6, 5, 12, 195, 188, 7, 25, 5, 12, 9, 13, 12, 201, 57, 146, 76, 5, 66, 207, 104, 245, 20, 13, 0, 13, 138, 22, 195, 169, 4, 5, 12, 13, 195, 169, 20, 13, 13, 138, 19, 26, 195, 161, 13, 12, 195, 161, 9, 20, 13, 9, 198, 4, 194, 207, 80, 245, 20, 13, 0, 0, 27, 68, 81, 81, 20, 4, 47, 40, 47, 12, 108, 6, 15, 84, 39, 55, 50, 108, 0, 13, 81, 118, 111, 108, 110, 97, 32, 47, 12, 11, 195, 169, 18, 4, 197, 145, 195, 173, 22, 5, 20, 49, 113, 52, 72, 118, 112, 84, 109, 47, 23, 49, 113, 89, 112, 47, 109, 50, 37, 0, 13, 81, 107, 195, 169, 115, 122, 195, 173, 116, 101, 110, 105, 32, 49, 12, 11, 195, 169, 18, 4, 197, 145, 195, 173, 22, 5, 20, 49, 113, 52, 72, 118, 112, 84, 109, 47, 23, 49, 113, 89, 112, 47, 109, 50, 109, 49, 0, 13, 81, 107, 195, 169, 115, 122, 195, 173, 116, 101, 110, 101, 107, 32, 9, 198, 12, 146, 204, 60, 229, 0, 13, 15, 140, 11, 195, 169, 18, 4, 197, 145, 195, 173, 22, 5, 20, 13, 7, 196, 81, 81, 20, 4, 13, 8, 133, 6, 5, 12, 195, 169, 13, 0, 8, 197, 48, 84, 218, 20, 192, 72, 9, 198, 24, 244, 132, 84, 195, 137, 13, 11, 136, 20, 1, 18, 20, 19, 195, 161, 11, 13, 24, 149, 195, 188, 7, 25, 6, 5, 12, 5, 11, 36, 21, 14, 19, 20, 18, 5, 19, 19, 5, 14, 4, 13, 9, 198, 24, 83, 20, 20, 227, 137, 13, 9, 198, 32, 83, 25, 21, 163, 137, 13, 9, 198, 24, 244, 132, 84, 195, 137, 13, 9, 198, 32, 83, 25, 21, 163, 137, 13, 13, 138, 19, 26, 1, 11, 195, 169, 18, 20, 197, 145, 13, 0, 36, 7, 5, 12, 14, 195, 182, 11, 9, 109, 55, 50, 110, 49, 37, 23, 48, 39, 89, 47, 52, 115, 55, 0, 13, 81, 112, 111, 115, 122, 116, 114, 195, 179, 108, 32, 27, 9, 2, 195, 161, 14, 20, 19, 195, 161, 11, 71, 114, 50, 76, 114, 49, 23, 118, 47, 0, 13, 81, 197, 145, 116, 32, 7, 132, 13, 195, 161, 10, 20, 0, 0, 13, 138, 195, 161, 12, 12, 1, 16, 15, 20, 195, 186, 13, 7, 196, 84, 118, 65, 56, 13, 23, 7, 195, 161, 19, 20, 195, 161, 11, 114, 91, 47, 114, 49, 23, 109, 55, 0, 13, 81, 101, 108, 32, 7, 196, 40, 241, 207, 44, 13, 0, 16, 141, 5, 7, 195, 169, 19, 26, 19, 195, 169, 7, 195, 169, 20, 13, 11, 136, 8, 195, 173, 22, 10, 195, 161, 11, 13, 38, 69, 12, 146, 204, 60, 224, 119, 37, 49, 55, 39, 50, 23, 47, 108, 55, 114, 55, 107, 108, 47, 115, 0, 13, 81, 116, 97, 108, 195, 161, 108, 104, 97, 116, 195, 179, 32, 13, 138, 11, 195, 169, 18, 4, 195, 169, 19, 5, 13, 13, 8, 197, 48, 81, 217, 20, 224, 13, 0, 12, 137, 11, 195, 173, 19, 195, 169, 18, 9, 11, 13, 17, 142, 5, 12, 8, 5, 12, 25, 5, 26, 195, 169, 19, 195, 169, 20, 13, 0, 16, 141, 5, 7, 25, 5, 26, 20, 5, 20, 195, 169, 19, 5, 14, 13, 16, 141, 5, 7, 25, 5, 26, 20, 5, 20, 195, 169, 19, 5, 14, 13, 36, 13, 5, 7, 25, 5, 26, 20, 5, 20, 195, 169, 19, 5, 14, 109, 79, 12, 109, 89, 47, 109, 47, 113, 91, 109, 50, 23, 37, 91, 0, 13, 81, 105, 115, 32, 13, 138, 10, 1, 22, 195, 173, 20, 10, 195, 161, 11, 13, 13, 138, 10, 1, 22, 195, 173, 20, 10, 195, 161, 11, 13, 0, 14, 139, 13, 15, 14, 4, 8, 1, 20, 14, 195, 161, 11, 13, 0, 9, 198, 24, 148, 148, 5, 69, 129, 13, 8, 197, 64, 144, 67, 61, 64, 13, 13, 138, 11, 195, 169, 18, 4, 195, 169, 19, 5, 9, 13, 0, 17, 142, 7, 25, 195, 179, 7, 25, 19, 26, 5, 18, 2, 197, 145, 12, 13, 16, 141, 20, 5, 12, 5, 16, 195, 188, 12, 195, 169, 19, 5, 11, 13, 0, 10, 135, 1, 12, 22, 195, 161, 19, 20, 13, 14, 139, 11, 195, 169, 18, 4, 195, 169, 19, 19, 5, 12, 13, 0, 7, 196, 40, 241, 207, 52, 13, 8, 133, 14, 197, 145, 14, 9, 13, 11, 136, 18, 195, 186, 7, 195, 161, 19, 20, 13, 0, 30, 10, 11, 1, 20, 5, 7, 195, 179, 18, 9, 1, 49, 108, 47, 109, 81, 115, 52, 37, 108, 23, 37, 91, 0, 13, 81, 105, 115, 32, 13, 138, 11, 1, 20, 5, 7, 195, 179, 18, 9, 1, 13, 19, 144, 20, 195, 161, 10, 195, 169, 11, 15, 26, 20, 1, 20, 20, 195, 161, 11, 13, 11, 136, 22, 15, 12, 14, 195, 161, 14, 11, 13, 0, 14, 139, 13, 5, 7, 7, 25, 197, 145, 26, 14, 9, 5, 13, 9, 198, 20, 194, 78, 17, 83, 20, 13, 13, 138, 5, 12, 10, 195, 161, 18, 195, 161, 19, 20, 13, 0, 13, 138, 8, 1, 19, 26, 14, 195, 161, 12, 195, 179, 13, 0, 9, 198, 40, 83, 5, 44, 85, 0, 13, 25, 68, 36, 198, 69, 56, 37, 57, 109, 50, 10, 6, 15, 71, 39, 55, 47, 0, 13, 81, 98, 111, 108, 116, 32, 31, 68, 60, 198, 65, 56, 39, 57, 108, 50, 10, 6, 15, 49, 113, 52, 72, 113, 91, 0, 13, 81, 107, 195, 169, 114, 100, 195, 169, 115, 32, 11, 136, 19, 20, 18, 195, 161, 6, 15, 20, 13, 23, 68, 36, 198, 69, 56, 37, 57, 109, 50, 15, 89, 113, 48, 0, 13, 81, 115, 122, 195, 169, 112, 32, 9, 134, 22, 195, 169, 7, 5, 26, 13, 7, 196, 60, 198, 65, 56, 13, 13, 4, 95, 49, 17, 24, 109, 55, 91, 109, 57, 109, 0, 0, 27, 69, 57, 146, 84, 56, 144, 67, 37, 47, 50, 37, 23, 108, 49, 12, 39, 52, 0, 13, 81, 97, 107, 107, 111, 114, 32, 8, 197, 57, 146, 84, 40, 16, 13, 8, 197, 88, 84, 218, 20, 208, 13, 43, 12, 11, 9, 19, 26, 15, 12, 7, 195, 161, 12, 195, 179, 49, 37, 89, 39, 55, 81, 114, 55, 115, 23, 57, 114, 52, 108, 47, 108, 37, 0, 13, 81, 106, 195, 161, 114, 97, 116, 97, 105, 32, 15, 140, 11, 9, 19, 26, 15, 12, 7, 195, 161, 12, 195, 179, 13, 0, 11, 136, 195, 188, 12, 195, 169, 19, 5, 14, 13, 8, 133, 4, 9, 195, 161, 11, 13, 9, 198, 16, 243, 7, 84, 176, 84, 13, 0, 12, 137, 12, 1, 11, 195, 161, 19, 2, 1, 14, 13, 29, 6, 13, 195, 161, 19, 9, 11, 65, 114, 91, 37, 49, 10, 6, 15, 47, 113, 65, 108, 0, 13, 81, 116, 195, 169, 109, 97, 32, 10, 199, 77, 160, 75, 61, 37, 143, 76, 13, 0, 40, 6, 18, 195, 169, 7, 5, 14, 52, 113, 81, 109, 50, 23, 49, 37, 47, 108, 55, 114, 55, 47, 114, 49, 0, 13, 81, 107, 105, 116, 97, 108, 195, 161, 108, 116, 195, 161, 107, 32, 13, 138, 195, 182, 19, 19, 26, 5, 7, 2, 5, 14, 13, 41, 68, 40, 241, 210, 4, 57, 39, 81, 52, 108, 23, 84, 114, 55, 47, 39, 89, 47, 108, 47, 39, 47, 12, 0, 13, 81, 118, 195, 161, 108, 116, 111, 122, 116, 97, 116, 111, 116, 116, 32, 11, 136, 5, 26, 5, 12, 197, 145, 20, 20, 13, 11, 200, 88, 148, 197, 48, 177, 68, 36, 176, 13, 11, 200, 88, 148, 197, 48, 177, 68, 36, 176, 13, 8, 133, 195, 173, 18, 10, 1, 13, 7, 196, 4, 67, 212, 80, 13, 0, 11, 136, 22, 195, 161, 18, 10, 195, 161, 11, 13, 13, 138, 13, 195, 169, 18, 14, 195, 182, 11, 5, 9, 13, 8, 197, 72, 82, 140, 36, 176, 13, 12, 137, 13, 9, 12, 12, 9, 195, 161, 18, 4, 13, 35, 9, 13, 9, 12, 12, 9, 195, 161, 18, 4, 65, 37, 55, 37, 114, 52, 72, 23, 83, 39, 52, 37, 50, 47, 0, 13, 81, 102, 111, 114, 105, 110, 116, 32, 8, 197, 52, 144, 84, 80, 16, 13, 8, 197, 81, 81, 10, 84, 176, 13, 8, 197, 44, 86, 132, 80, 80, 13, 8, 197, 52, 243, 132, 40, 16, 13, 0, 14, 139, 7, 25, 195, 179, 7, 25, 20, 15, 18, 14, 1, 13, 52, 8, 195, 161, 7, 195, 161, 2, 1, 14, 114, 81, 114, 71, 108, 50, 15, 91, 37, 50, 76, 15, 55, 109, 76, 109, 52, 113, 55, 50, 37, 0, 13, 82, 115, 105, 110, 99, 115, 32, 108, 101, 99, 115, 101, 114, 195, 169, 108, 110, 105, 32, 7, 132, 11, 195, 161, 18, 13, 12, 4, 13, 195, 161, 22, 65, 114, 84, 0, 42, 42, 0, 12, 137, 13, 21, 14, 11, 195, 161, 2, 1, 14, 13, 14, 139, 20, 5, 12, 5, 6, 15, 14, 195, 161, 12, 20, 13, 12, 137, 12, 9, 19, 20, 195, 161, 2, 1, 14, 13, 17, 142, 6, 15, 18, 18, 195, 161, 19, 11, 195, 179, 4, 14, 1, 11, 13, 7, 132, 5, 12, 197, 145, 13, 7, 132, 5, 12, 197, 145, 13, 0, 13, 138, 9, 19, 11, 15, 12, 195, 161, 2, 1, 14, 13, 7, 132, 19, 195, 173, 16, 13, 0, 11, 136, 20, 5, 19, 19, 26, 195, 188, 11, 13, 31, 11, 195, 182, 14, 13, 1, 7, 195, 161, 2, 1, 14, 110, 50, 65, 108, 81, 114, 71, 108, 50, 23, 108, 88, 0, 13, 81, 97, 122, 32, 49, 4, 13, 195, 161, 19, 65, 114, 91, 23, 89, 109, 65, 55, 113, 55, 109, 47, 109, 47, 23, 49, 110, 84, 109, 47, 0, 13, 82, 115, 122, 101, 109, 108, 195, 169, 108, 101, 116, 101, 116, 32, 107, 195, 182, 118, 101, 116, 32, 20, 4, 13, 195, 161, 19, 65, 114, 91, 23, 91, 109, 65, 0, 13, 81, 115, 101, 109, 32, 27, 4, 13, 195, 161, 19, 65, 114, 91, 23, 81, 113, 48, 12, 109, 55, 0, 13, 81, 103, 195, 169, 112, 112, 101, 108, 32, 14, 139, 195, 169, 18, 4, 5, 11, 195, 169, 2, 5, 14, 13, 14, 139, 195, 169, 18, 4, 5, 11, 195, 169, 2, 5, 14, 13, 7, 132, 13, 195, 161, 19, 13, 0, 25, 4, 13, 195, 161, 18, 65, 114, 52, 10, 6, 15, 108, 48, 52, 115, 0, 13, 81, 97, 112, 114, 195, 179, 32, 32, 4, 13, 195, 161, 18, 65, 114, 52, 10, 6, 15, 109, 55, 113, 52, 47, 113, 49, 0, 13, 81, 101, 108, 195, 169, 114, 116, 195, 169, 107, 32, 50, 4, 13, 195, 161, 18, 65, 114, 52, 10, 6, 15, 49, 109, 84, 113, 91, 71, 113, 10, 6, 15, 107, 108, 55, 12, 108, 50, 37, 0, 13, 82, 107, 101, 118, 195, 169, 115, 98, 195, 169, 32, 104, 97, 108, 108, 97, 110, 105, 32, 35, 4, 13, 195, 161, 18, 65, 114, 52, 23, 55, 109, 107, 109, 76, 12, 113, 81, 109, 91, 0, 13, 81, 108, 101, 104, 101, 116, 115, 195, 169, 103, 101, 115, 32, 33, 4, 13, 195, 161, 18, 65, 114, 52, 23, 65, 109, 81, 89, 39, 49, 39, 47, 12, 0, 13, 81, 109, 101, 103, 115, 122, 111, 107, 111, 116, 116, 32, 28, 6, 2, 5, 12, 195, 188, 12, 71, 109, 55, 111, 55, 23, 65, 108, 52, 108, 72, 0, 13, 81, 109, 97, 114, 97, 100, 32, 33, 4, 13, 195, 161, 18, 65, 114, 52, 23, 49, 39, 52, 114, 71, 52, 115, 55, 0, 13, 81, 107, 111, 114, 195, 161, 98, 98, 114, 195, 179, 108, 32, 24, 4, 13, 195, 161, 18, 65, 114, 52, 15, 91, 39, 49, 108, 47, 0, 13, 81, 115, 111, 107, 97, 116, 32, 9, 134, 6, 5, 12, 195, 188, 12, 13, 13, 138, 2, 5, 12, 5, 19, 26, 195, 179, 12, 20, 13, 9, 134, 2, 5, 12, 195, 188, 12, 13, 17, 142, 13, 197, 177, 11, 195, 182, 4, 195, 169, 19, 18, 197, 145, 12, 13, 7, 132, 13, 195, 161, 18, 13, 0, 18, 143, 2, 195, 182, 14, 7, 195, 169, 19, 26, 197, 145, 2, 197, 145, 12, 13, 10, 199, 13, 51, 206, 80, 242, 193, 80, 13, 0, 12, 137, 22, 5, 19, 26, 197, 145, 4, 14, 9, 13, 19, 144, 11, 195, 169, 19, 26, 195, 173, 20, 195, 169, 19, 195, 169, 22, 5, 12, 13, 11, 136, 11, 195, 182, 14, 25, 22, 5, 20, 13, 11, 136, 20, 195, 161, 13, 15, 7, 1, 20, 13, 16, 141, 6, 18, 1, 11, 3, 9, 195, 179, 10, 195, 161, 18, 1, 13, 7, 196, 53, 85, 1, 80, 13, 0, 9, 134, 12, 195, 169, 16, 14, 9, 13, 8, 133, 19, 26, 195, 188, 12, 13, 0, 25, 70, 32, 19, 135, 104, 245, 20, 107, 108, 50, 81, 88, 39, 47, 12, 23, 109, 55, 0, 13, 81, 101, 108, 32, 27, 70, 32, 19, 135, 104, 245, 20, 107, 108, 50, 81, 88, 39, 47, 12, 10, 6, 15, 109, 55, 0, 13, 81, 101, 108, 32, 9, 198, 77, 161, 76, 48, 83, 64, 13, 41, 7, 12, 1, 11, 195, 161, 19, 1, 55, 108, 49, 114, 91, 108, 23, 79, 40, 55, 12, 108, 47, 12, 23, 49, 37, 0, 13, 82, 103, 121, 117, 108, 108, 97, 100, 116, 32, 107, 105, 32, 10, 135, 5, 12, 14, 195, 182, 11, 5, 13, 23, 6, 22, 195, 169, 7, 5, 20, 84, 113, 81, 109, 47, 23, 113, 52, 0, 13, 81, 195, 169, 114, 32, 13, 138, 2, 1, 18, 195, 161, 20, 10, 195, 161, 20, 13, 9, 134, 22, 195, 169, 7, 5, 20, 13, 11, 136, 15, 11, 20, 195, 179, 2, 5, 18, 20, 0, 32, 67, 4, 210, 84, 108, 65, 37, 47, 23, 107, 108, 89, 50, 114, 55, 39, 49, 0, 13, 81, 104, 97, 115, 122, 110, 195, 161, 108, 111, 107, 32, 18, 143, 8, 1, 10, 12, 195, 169, 11, 20, 1, 12, 1, 14, 14, 1, 12, 13, 11, 136, 19, 26, 1, 2, 195, 161, 12, 25, 13, 14, 67, 16, 228, 192, 72, 113, 109, 50, 109, 91, 0, 42, 42, 0, 11, 136, 14, 195, 169, 26, 5, 7, 5, 20, 13, 11, 136, 13, 195, 179, 4, 10, 195, 161, 20, 13, 0, 13, 138, 20, 195, 161, 13, 15, 7, 1, 20, 14, 9, 13, 11, 136, 20, 195, 182, 13, 5, 7, 5, 11, 13, 9, 198, 44, 81, 22, 20, 224, 197, 13, 12, 137, 16, 195, 161, 18, 20, 10, 195, 161, 20, 13, 11, 136, 19, 26, 197, 177, 18, 197, 145, 11, 13, 8, 133, 22, 195, 161, 18, 20, 13, 0, 10, 135, 13, 195, 169, 4, 9, 21, 13, 13, 12, 137, 13, 21, 20, 1, 20, 10, 195, 161, 11, 13, 9, 198, 4, 192, 80, 40, 18, 84, 13, 0, 14, 139, 4, 195, 182, 14, 20, 195, 169, 19, 195, 169, 20, 13, 10, 199, 65, 35, 196, 84, 49, 82, 20, 13, 18, 143, 8, 1, 19, 15, 14, 12, 195, 173, 20, 7, 1, 20, 14, 15, 4, 13, 0, 16, 141, 11, 15, 18, 12, 195, 161, 20, 15, 26, 195, 161, 19, 1, 13, 14, 139, 22, 195, 161, 18, 8, 1, 20, 195, 179, 1, 11, 13, 14, 139, 12, 195, 161, 20, 8, 1, 20, 195, 179, 1, 11, 13, 10, 135, 195, 173, 18, 14, 195, 161, 11, 13, 11, 200, 32, 83, 25, 104, 85, 2, 20, 224, 13, 0, 15, 140, 20, 195, 161, 13, 15, 7, 1, 20, 14, 195, 161, 11, 13, 15, 140, 15, 12, 22, 1, 19, 8, 1, 20, 10, 195, 161, 11, 13, 16, 141, 6, 5, 12, 5, 12, 197, 145, 19, 195, 169, 7, 5, 20, 13, 14, 139, 22, 1, 19, 195, 161, 18, 14, 1, 16, 15, 14, 22, 0, 60, 14, 10, 5, 12, 5, 14, 20, 197, 145, 19, 195, 169, 7, 5, 20, 57, 109, 55, 109, 50, 47, 118, 91, 113, 81, 109, 47, 23, 47, 40, 55, 108, 57, 72, 39, 50, 112, 47, 108, 50, 37, 0, 13, 81, 116, 117, 108, 97, 106, 100, 111, 110, 195, 173, 116, 97, 110, 105, 32, 33, 11, 16, 18, 15, 2, 12, 195, 169, 13, 195, 161, 13, 48, 52, 39, 71, 55, 113, 65, 114, 65, 23, 84, 108, 50, 0, 13, 81, 118, 97, 110, 32, 16, 141, 19, 26, 195, 182, 22, 5, 20, 19, 195, 169, 7, 5, 11, 13, 42, 8, 1, 12, 1, 16, 10, 195, 161, 14, 108, 55, 108, 48, 57, 114, 50, 23, 112, 47, 113, 55, 49, 109, 88, 109, 55, 0, 13, 81, 195, 173, 116, 195, 169, 108, 107, 101, 122, 101, 108, 32, 37, 11, 16, 18, 15, 2, 12, 195, 169, 13, 195, 161, 13, 48, 52, 39, 71, 55, 113, 65, 114, 65, 15, 108, 49, 108, 47, 12, 0, 13, 81, 97, 107, 97, 100, 116, 32, 16, 141, 20, 1, 12, 195, 161, 12, 8, 1, 20, 195, 179, 1, 11, 13, 11, 136, 1, 12, 1, 16, 10, 195, 161, 14, 13, 0, 12, 137, 6, 9, 26, 9, 11, 21, 13, 195, 186, 13, 13, 138, 2, 15, 18, 195, 173, 20, 10, 195, 161, 11, 13, 18, 143, 5, 12, 12, 5, 14, 197, 145, 18, 26, 195, 169, 19, 195, 169, 20, 13, 0, 14, 139, 16, 18, 15, 2, 12, 195, 169, 13, 195, 161, 11, 13, 19, 144, 11, 9, 20, 5, 18, 10, 5, 19, 26, 20, 195, 169, 19, 195, 169, 20, 13, 7, 196, 40, 241, 207, 80, 13, 7, 196, 40, 241, 207, 80, 13, 0, 8, 197, 88, 242, 211, 61, 64, 13, 15, 140, 6, 5, 12, 12, 195, 169, 16, 195, 169, 19, 5, 11, 13, 0, 0, 12, 201, 52, 81, 212, 20, 129, 84, 21, 69, 0, 13, 11, 136, 11, 9, 10, 195, 182, 14, 14, 9, 13, 15, 67, 4, 68, 204, 114, 72, 113, 109, 91, 109, 55, 0, 42, 42, 0, 41, 70, 24, 82, 140, 21, 69, 0, 83, 109, 57, 55, 109, 47, 12, 10, 6, 15, 48, 52, 39, 119, 109, 89, 12, 39, 52, 0, 13, 81, 112, 114, 111, 99, 101, 115, 115, 122, 111, 114, 32, 49, 11, 20, 1, 14, 195, 173, 20, 1, 14, 4, 195, 179, 47, 108, 50, 112, 47, 108, 50, 72, 115, 23, 37, 91, 65, 109, 52, 109, 47, 109, 49, 109, 47, 0, 13, 81, 105, 115, 109, 101, 114, 101, 116, 101, 107, 101, 116, 32, 17, 142, 13, 5, 7, 2, 195, 173, 26, 8, 1, 20, 195, 179, 1, 14, 13, 11, 200, 32, 243, 20, 80, 84, 212, 21, 64, 13, 14, 139, 9, 14, 20, 15, 14, 195, 161, 3, 9, 195, 179, 13, 14, 139, 22, 1, 19, 195, 161, 18, 14, 1, 16, 9, 7, 22, 0, 8, 197, 56, 17, 217, 61, 64, 13, 13, 138, 20, 195, 182, 18, 197, 145, 4, 14, 9, 5, 13, 16, 141, 16, 18, 9, 15, 18, 9, 20, 195, 161, 19, 19, 1, 12, 13, 0, 13, 138, 20, 21, 4, 8, 1, 20, 14, 195, 161, 4, 13, 17, 142, 20, 195, 161, 13, 15, 7, 1, 20, 195, 161, 19, 19, 1, 12, 13, 17, 142, 1, 12, 11, 1, 12, 13, 1, 26, 195, 161, 19, 19, 1, 12, 13, 12, 137, 7, 1, 26, 4, 1, 19, 195, 161, 7, 13, 13, 138, 5, 12, 12, 195, 161, 20, 195, 161, 19, 20, 13, 0, 23, 7, 11, 195, 182, 18, 195, 188, 12, 49, 110, 52, 111, 55, 23, 37, 91, 0, 13, 81, 105, 115, 32, 13, 138, 6, 195, 161, 18, 1, 19, 26, 20, 195, 179, 13, 17, 142, 18, 5, 7, 9, 19, 26, 20, 18, 195, 161, 3, 9, 195, 179, 13, 13, 138, 1, 14, 9, 13, 195, 161, 3, 9, 195, 179, 13, 14, 139, 195, 161, 20, 195, 161, 12, 12, 195, 161, 19, 20, 13, 12, 135, 11, 195, 182, 18, 195, 188, 12, 13, 20, 22, 0, 52, 12, 20, 195, 161, 13, 15, 7, 1, 20, 195, 161, 19, 20, 47, 114, 65, 39, 81, 108, 47, 114, 91, 47, 23, 71, 37, 89, 47, 39, 91, 112, 47, 108, 50, 37, 0, 13, 81, 98, 105, 122, 116, 111, 115, 195, 173, 116, 97, 110, 105, 32, 15, 140, 1, 12, 11, 1, 12, 13, 1, 26, 195, 161, 19, 20, 13, 15, 140, 20, 195, 161, 13, 15, 7, 1, 20, 195, 161, 19, 20, 13, 11, 136, 11, 195, 169, 19, 26, 195, 188, 12, 13, 15, 140, 7, 25, 15, 18, 19, 195, 173, 20, 195, 161, 19, 20, 13, 11, 136, 11, 195, 169, 19, 26, 195, 188, 12, 13, 0, 8, 197, 88, 19, 12, 88, 16, 13, 10, 135, 9, 18, 15, 4, 195, 161, 14, 13, 16, 141, 19, 26, 9, 7, 15, 18, 195, 173, 20, 195, 161, 19, 20, 13, 8, 197, 24, 241, 202, 84, 176, 13, 16, 141, 13, 5, 7, 2, 195, 173, 26, 1, 20, 195, 161, 19, 20, 13, 8, 197, 20, 192, 68, 56, 144, 13, 15, 140, 9, 14, 6, 15, 18, 13, 195, 161, 3, 9, 195, 179, 13, 8, 133, 14, 197, 145, 20, 20, 13, 0, 9, 198, 88, 243, 20, 84, 226, 192, 72, 30, 6, 5, 12, 197, 145, 20, 20, 109, 55, 118, 47, 12, 23, 49, 110, 88, 110, 55, 0, 13, 81, 107, 195, 182, 122, 195, 182, 108, 32, 39, 6, 5, 12, 197, 145, 20, 20, 109, 55, 118, 47, 12, 23, 48, 40, 71, 55, 37, 49, 114, 55, 47, 108, 0, 13, 81, 112, 117, 98, 108, 105, 107, 195, 161, 108, 116, 97, 32, 8, 133, 195, 173, 18, 15, 11, 13, 17, 142, 19, 26, 1, 2, 195, 161, 12, 25, 15, 26, 195, 161, 19, 20, 13, 17, 142, 20, 1, 18, 20, 195, 179, 26, 11, 15, 4, 195, 161, 19, 20, 13, 17, 142, 10, 1, 22, 1, 4, 1, 12, 13, 1, 26, 195, 161, 19, 20, 13, 12, 137, 15, 12, 22, 1, 19, 19, 195, 161, 11, 13, 11, 136, 19, 26, 5, 18, 4, 195, 161, 14, 22, 11, 134, 5, 12, 197, 145, 20, 20, 20, 22, 13, 0, 18, 143, 13, 5, 7, 195, 161, 12, 12, 1, 16, 15, 4, 195, 161, 19, 20, 13, 17, 142, 11, 15, 14, 6, 9, 7, 21, 18, 195, 161, 3, 9, 195, 179, 13, 18, 143, 14, 25, 9, 12, 22, 195, 161, 14, 195, 173, 20, 195, 161, 19, 20, 13, 0, 14, 139, 8, 1, 12, 12, 7, 1, 20, 20, 195, 161, 11, 13, 30, 68, 52, 144, 84, 80, 65, 37, 108, 47, 12, 23, 84, 108, 50, 23, 112, 79, 0, 13, 82, 118, 97, 110, 32, 195, 173, 103, 121, 32, 11, 200, 53, 83, 139, 4, 145, 5, 40, 80, 13, 43, 7, 6, 15, 7, 10, 195, 161, 11, 83, 39, 81, 57, 114, 49, 23, 109, 55, 12, 109, 50, 118, 52, 37, 88, 50, 37, 0, 13, 81, 101, 108, 108, 101, 110, 197, 145, 114, 105, 122, 110, 105, 32, 34, 68, 52, 144, 84, 80, 65, 6, 37, 108, 47, 12, 15, 67, 39, 65, 39, 88, 50, 108, 49, 0, 13, 81, 110, 121, 111, 109, 111, 122, 110, 97, 107, 32, 38, 68, 52, 144, 84, 80, 65, 37, 108, 47, 12, 23, 47, 37, 55, 47, 108, 49, 39, 88, 50, 108, 49, 0, 13, 81, 116, 105, 108, 116, 97, 107, 111, 122, 110, 97, 107, 32, 11, 200, 32, 17, 19, 21, 33, 71, 8, 80, 13, 12, 137, 11, 195, 182, 12, 20, 197, 145, 18, 5, 13, 10, 135, 6, 15, 7, 10, 195, 161, 11, 13, 10, 135, 195, 173, 18, 10, 195, 161, 11, 13, 7, 196, 52, 144, 84, 80, 13, 0, 15, 140, 11, 195, 169, 16, 5, 19, 19, 195, 169, 7, 5, 11, 13, 30, 8, 13, 195, 161, 19, 15, 4, 9, 11, 65, 114, 91, 39, 72, 37, 49, 23, 109, 55, 109, 65, 0, 13, 81, 101, 108, 101, 109, 32, 8, 197, 52, 240, 211, 60, 176, 13, 11, 136, 11, 195, 169, 16, 5, 19, 5, 11, 13, 15, 140, 11, 195, 169, 16, 22, 9, 19, 5, 12, 197, 145, 11, 13, 10, 135, 195, 161, 12, 12, 10, 15, 14, 13, 0, 16, 141, 2, 9, 26, 15, 14, 25, 195, 173, 20, 10, 195, 161, 11, 13, 35, 70, 81, 81, 10, 84, 226, 192, 47, 40, 79, 12, 40, 50, 49, 23, 47, 110, 55, 47, 109, 50, 37, 0, 13, 81, 116, 195, 182, 108, 116, 101, 110, 105, 32, 11, 136, 11, 1, 16, 3, 19, 195, 161, 14, 13, 13, 7, 95, 35, 45, 195, 161, 18, 1, 114, 52, 108, 0, 0, 10, 135, 19, 16, 195, 179, 18, 15, 12, 13, 13, 138, 19, 26, 195, 179, 18, 195, 179, 4, 9, 11, 13, 11, 136, 9, 18, 15, 4, 195, 161, 18, 1, 13, 11, 136, 13, 1, 16, 16, 195, 161, 18, 1, 13, 16, 141, 6, 5, 10, 12, 5, 19, 26, 20, 195, 169, 19, 5, 14, 13, 13, 138, 20, 21, 4, 8, 1, 20, 10, 195, 161, 11, 13, 0, 11, 200, 52, 81, 214, 21, 54, 142, 20, 176, 13, 7, 196, 36, 198, 69, 80, 13, 14, 139, 10, 5, 12, 5, 14, 20, 195, 169, 19, 5, 11, 13, 15, 140, 6, 5, 12, 195, 188, 12, 5, 20, 18, 197, 145, 12, 13, 0, 6, 20, 244, 0, 0, 0, 81, 1, 0, 0, 251, 0, 0, 0, 113, 1, 0, 0, 0, 0, 0, 0, 6, 18, 66, 98, 0, 99, 0, 100, 0, 102, 0, 103, 0, 104, 0, 106, 0, 107, 0, 108, 0, 109, 0, 110, 0, 112, 0, 115, 0, 116, 0, 114, 0, 118, 0, 119, 0, 122, 0, 7, 6, 99, 104, 0, 4, 1, 169, 195, 122, 115, 3, 76, 0, 8, 105, 122, 2, 121, 0, 4, 101, 8, 169, 195, 122, 115, 2, 110, 121, 3, 76, 113, 0, 195, 169, 8, 169, 195, 122, 115, 2, 110, 121, 0, 1, 110, 188, 195, 109, 2, 101, 110, 3, 99, 0, 4, 1, 97, 99, 114, 97, 2, 111, 110, 3, 107, 0, 1, 97, 100, 108, 97, 98, 2, 105, 110, 0, 1, 97, 106, 2, 116, 0, 1, 97, 109, 2, 105, 97, 118, 101, 108, 108, 0, 1, 97, 109, 2, 105, 110, 195, 161, 0, 1, 97, 110, 97, 109, 108, 97, 0, 1, 101, 109, 2, 97, 0, 1, 101, 116, 0, 1, 105, 116, 122, 115, 105, 100, 2, 111, 110, 0, 1, 105, 116, 122, 115, 111, 110, 111, 114, 107, 2, 111, 110, 0, 1, 105, 122, 115, 112, 0, 1, 111, 115, 97, 109, 2, 105, 115, 116, 17, 65, 0, 1, 111, 122, 97, 109, 2, 105, 115, 0, 1, 111, 122, 97, 109, 2, 105, 122, 109, 0, 1, 114, 97, 2, 97, 105, 107, 117, 115, 0, 1, 114, 97, 2, 105, 116, 101, 107, 116, 195, 186, 0, 1, 114, 97, 2, 105, 118, 195, 161, 108, 0, 1, 114, 97, 2, 195, 173, 118, 0, 1, 114, 97, 103, 105, 108, 111, 0, 1, 114, 97, 110, 97, 2, 105, 0, 1, 114, 97, 110, 111, 109, 2, 105, 0, 1, 114, 97, 114, 101, 105, 104, 2, 105, 0, 1, 114, 111, 2, 195, 173, 100, 101, 97, 0, 1, 121, 122, 115, 112, 0, 8, 114, 97, 2, 105, 109, 195, 169, 0, 8, 114, 111, 2, 105, 100, 101, 0, 4, 1, 101, 99, 2, 101, 116, 3, 107, 12, 0, 1, 101, 112, 103, 101, 108, 2, 101, 115, 0, 1, 105, 114, 116, 115, 2, 101, 108, 0, 8, 101, 112, 0, 7, 6, 100, 122, 0, 4, 1, 97, 122, 161, 195, 122, 115, 2, 101, 110, 101, 3, 72, 88, 0, 1, 101, 114, 122, 101, 2, 101, 110, 101, 0, 1, 103, 97, 114, 97, 109, 115, 2, 195, 182, 108, 100, 0, 1, 169, 195, 118, 110, 111, 104, 2, 195, 161, 115, 122, 108, 195, 179, 0, 1, 169, 195, 122, 115, 101, 98, 2, 97, 118, 97, 114, 0, 4, 115, 3, 75, 0, 115, 1, 17, 67, 0, 115, 1, 97, 2, 17, 65, 0, 115, 2, 17, 67, 0, 4, 115, 1, 97, 114, 97, 104, 97, 109, 2, 17, 65, 3, 75, 12, 0, 115, 1, 101, 110, 101, 109, 2, 17, 65, 0, 115, 1, 105, 114, 98, 2, 17, 65, 0, 115, 5, 1, 1, 111, 98, 109, 97, 107, 2, 17, 65, 0, 115, 8, 111, 100, 2, 17, 65, 0, 4, 1, 145, 197, 108, 101, 100, 101, 122, 115, 3, 88, 0, 1, 145, 197, 108, 101, 116, 101, 118, 182, 195, 107, 0, 1, 145, 197, 114, 169, 195, 107, 0, 1, 145, 197, 116, 101, 103, 101, 116, 110, 101, 109, 0, 1, 145, 197, 116, 101, 103, 101, 121, 110, 101, 102, 0, 1, 177, 197, 114, 177, 197, 121, 103, 2, 105, 107, 0, 1, 179, 195, 103, 111, 102, 2, 195, 179, 0, 1, 179, 195, 108, 108, 105, 118, 0, 1, 179, 195, 108, 111, 107, 114, 117, 98, 0, 1, 179, 195, 108, 111, 107, 116, 105, 116, 0, 1, 179, 195, 108, 161, 195, 98, 109, 105, 104, 0, 1, 179, 195, 108, 161, 195, 98, 111, 100, 0, 1, 179, 195, 108, 161, 195, 112, 97, 107, 0, 1, 179, 195, 112, 97, 114, 97, 104, 0, 1, 179, 195, 112, 111, 108, 0, 1, 179, 195, 114, 97, 107, 97, 0, 1, 179, 195, 115, 114, 111, 98, 0, 1, 179, 195, 116, 97, 103, 108, 108, 97, 104, 0, 1, 179, 195, 116, 97, 103, 110, 105, 114, 0, 1, 179, 195, 116, 97, 103, 110, 161, 195, 114, 0, 1, 179, 195, 116, 97, 103, 111, 112, 97, 116, 0, 1, 145, 197, 108, 101, 100, 101, 122, 115, 2, 107, 195, 182, 3, 89, 0, 4, 1, 101, 114, 169, 195, 107, 3, 119, 0, 1, 101, 114, 169, 195, 109, 2, 107, 0, 1, 179, 195, 2, 107, 111, 100, 0, 1, 179, 195, 103, 111, 102, 2, 107, 111, 100, 0, 1, 179, 195, 122, 186, 195, 104, 0, 8, 179, 195, 2, 107, 111, 0, 4, 3, 120, 12, 0, 0, 1, 17, 65, 2, 17, 65, 0, 1, 101, 2, 195, 169, 115, 0, 1, 101, 2, 197, 145, 0, 7, 6, 103, 121, 0, 115, 3, 76, 0, 115, 1, 17, 65, 2, 17, 65, 3, 76, 12, 0, 4, 3, 79, 0, 1, 97, 2, 115, 101, 98, 195, 169, 115, 122, 0, 1, 97, 2, 115, 101, 106, 0, 1, 97, 2, 115, 195, 169, 114, 195, 188, 108, 0, 1, 97, 102, 2, 115, 195, 169, 114, 195, 188, 108, 0, 1, 97, 110, 2, 115, 97, 108, 108, 195, 179, 0, 1, 97, 110, 2, 115, 97, 114, 108, 195, 179, 0, 1, 97, 110, 2, 115, 101, 98, 101, 115, 0, 1, 97, 110, 2, 115, 105, 101, 116, 0, 1, 97, 110, 2, 115, 105, 107, 101, 114, 0, 1, 97, 110, 2, 115, 111, 107, 195, 161, 114, 97, 0, 1, 97, 110, 2, 115, 116, 114, 97, 116, 195, 169, 103, 105, 97, 0, 1, 97, 110, 2, 115, 116, 195, 173, 108, 0, 1, 97, 110, 2, 115, 195, 161, 103, 0, 1, 97, 110, 2, 115, 195, 161, 112, 0, 1, 101, 2, 101, 115, 45, 101, 103, 121, 101, 100, 195, 188, 108, 0, 1, 101, 2, 106, 101, 103, 121, 197, 177, 0, 1, 101, 2, 106, 101, 108, 101, 110, 116, 195, 169, 115, 197, 177, 0, 1, 101, 2, 115, 97, 114, 107, 195, 186, 0, 1, 101, 2, 115, 101, 106, 116, 197, 177, 0, 1, 101, 2, 115, 111, 114, 0, 1, 101, 2, 115, 195, 173, 110, 197, 177, 0, 1, 101, 104, 2, 115, 195, 169, 103, 0, 1, 101, 106, 2, 101, 110, 107, 195, 169, 110, 116, 0, 1, 101, 106, 2, 101, 122, 116, 101, 0, 1, 101, 106, 2, 195, 169, 114, 116, 0, 1, 101, 106, 100, 169, 195, 118, 2, 115, 116, 114, 97, 116, 195, 169, 0, 1, 110, 182, 195, 121, 103, 2, 115, 111, 114, 0, 1, 111, 104, 2, 115, 101, 0, 1, 111, 104, 101, 115, 2, 115, 101, 0, 1, 114, 161, 195, 116, 2, 106, 117, 116, 97, 108, 0, 1, 114, 161, 195, 116, 2, 115, 111, 114, 0, 1, 114, 161, 195, 116, 2, 115, 111, 114, 111, 122, 97, 116, 0, 1, 161, 195, 2, 115, 111, 114, 0, 1, 161, 195, 108, 2, 115, 195, 161, 0, 1, 161, 195, 118, 116, 169, 195, 2, 106, 97, 118, 195, 173, 116, 0, 1, 169, 195, 110, 2, 106, 101, 103, 121, 0, 1, 169, 195, 110, 2, 115, 97, 114, 111, 107, 0, 1, 169, 195, 110, 2, 115, 111, 114, 0, 1, 169, 195, 110, 2, 115, 195, 161, 118, 0, 1, 186, 195, 2, 115, 101, 109, 0, 1, 186, 195, 2, 115, 105, 110, 99, 115, 0, 8, 101, 2, 115, 101, 0, 8, 101, 100, 110, 105, 109, 2, 105, 107, 0, 8, 173, 195, 2, 106, 195, 161, 114, 0, 106, 1, 17, 67, 0, 4, 1, 101, 2, 45, 101, 103, 121, 3, 79, 12, 0, 1, 101, 2, 97, 114, 195, 161, 110, 116, 0, 1, 101, 2, 97, 122, 111, 110, 0, 1, 101, 2, 101, 108, 197, 145, 114, 101, 0, 1, 101, 2, 101, 109, 98, 101, 114, 0, 1, 101, 2, 101, 110, 107, 195, 169, 110, 116, 0, 1, 101, 2, 101, 110, 114, 97, 110, 103, 0, 1, 101, 2, 101, 110, 115, 195, 186, 108, 121, 0, 1, 101, 2, 101, 115, 195, 188, 108, 101, 116, 0, 1, 101, 2, 101, 116, 195, 169, 114, 116, 0, 1, 101, 2, 101, 122, 107, 101, 100, 0, 1, 101, 2, 101, 122, 116, 101, 116, 0, 1, 101, 2, 105, 100, 101, 106, 197, 177, 0, 1, 101, 2, 105, 114, 195, 161, 110, 121, 195, 186, 0, 1, 101, 2, 195, 161, 108, 116, 97, 108, 195, 161, 110, 0, 1, 101, 2, 195, 169, 106, 115, 122, 97, 107, 0, 1, 101, 2, 195, 169, 114, 116, 0, 1, 101, 2, 195, 169, 114, 116, 101, 108, 109, 197, 177, 0, 1, 101, 2, 195, 186, 116, 116, 97, 108, 0, 1, 101, 45, 109, 101, 110, 2, 101, 122, 0, 1, 101, 45, 109, 101, 110, 2, 105, 107, 0, 1, 101, 45, 109, 101, 110, 2, 195, 188, 116, 116, 0, 1, 101, 97, 114, 106, 186, 195, 2, 101, 115, 195, 173, 116, 0, 1, 101, 99, 110, 105, 109, 114, 97, 104, 2, 101, 100, 105, 107, 0, 1, 101, 101, 108, 101, 98, 2, 101, 122, 0, 1, 101, 101, 122, 115, 115, 182, 195, 2, 101, 115, 195, 173, 116, 0, 1, 101, 103, 101, 109, 108, 169, 195, 102, 2, 101, 122, 0, 1, 101, 105, 107, 2, 101, 122, 0, 1, 101, 110, 101, 122, 105, 116, 2, 101, 100, 105, 107, 0, 1, 101, 110, 101, 122, 105, 116, 2, 101, 100, 115, 122, 101, 114, 0, 1, 101, 110, 101, 122, 105, 116, 2, 101, 110, 0, 1, 101, 110, 101, 122, 105, 116, 2, 101, 115, 0, 1, 101, 110, 101, 122, 105, 116, 2, 101, 116, 0, 1, 101, 110, 111, 122, 115, 117, 104, 2, 101, 100, 0, 1, 101, 110, 111, 122, 115, 117, 104, 2, 101, 100, 105, 107, 0, 1, 101, 110, 111, 122, 115, 117, 104, 2, 101, 115, 0, 1, 101, 110, 111, 122, 115, 117, 104, 2, 101, 122, 0, 1, 101, 116, 101, 108, 188, 195, 112, 169, 195, 2, 195, 188, 116, 116, 0, 1, 101, 122, 161, 195, 122, 115, 2, 101, 100, 105, 107, 0, 1, 101, 122, 161, 195, 122, 115, 2, 101, 115, 0, 8, 101, 2, 97, 98, 108, 97, 107, 0, 8, 101, 2, 101, 108, 0, 8, 101, 2, 101, 115, 0, 8, 101, 2, 101, 116, 32, 0, 8, 101, 2, 101, 116, 108, 101, 110, 0, 8, 101, 2, 101, 122, 0, 8, 101, 2, 101, 122, 109, 195, 169, 110, 121, 0, 8, 101, 2, 105, 100, 197, 145, 0, 8, 101, 2, 105, 107, 0, 8, 101, 2, 111, 108, 100, 97, 108, 0, 8, 101, 2, 195, 161, 103, 121, 0, 8, 101, 2, 195, 169, 32, 0, 8, 101, 2, 195, 169, 118, 0, 8, 101, 2, 195, 179, 114, 195, 161, 0, 8, 101, 2, 195, 182, 110, 116, 101, 116, 0, 8, 101, 2, 195, 182, 115, 115, 122, 101, 103, 0, 8, 101, 2, 195, 188, 116, 0, 8, 101, 45, 116, 110, 105, 109, 2, 195, 169, 32, 0, 8, 101, 103, 101, 109, 2, 101, 122, 0, 8, 101, 107, 101, 122, 115, 105, 104, 2, 101, 0, 8, 101, 110, 111, 122, 115, 117, 104, 2, 101, 0, 8, 101, 114, 101, 122, 115, 121, 103, 101, 2, 101, 0, 106, 1, 17, 65, 2, 17, 65, 0, 106, 1, 97, 104, 0, 106, 1, 101, 2, 101, 108, 101, 110, 116, 195, 169, 115, 197, 177, 3, 79, 57, 0, 4, 115, 122, 3, 79, 89, 0, 115, 122, 1, 17, 65, 2, 17, 65, 0, 115, 122, 1, 97, 110, 2, 97, 0, 4, 115, 1, 101, 2, 195, 161, 118, 3, 79, 91, 0, 115, 1, 101, 2, 195, 169, 103, 0, 115, 1, 101, 2, 195, 173, 107, 0, 115, 1, 186, 195, 2, 101, 0, 115, 8, 173, 195, 2, 101, 0, 7, 6, 115, 115, 0, 4, 122, 1, 97, 2, 105, 115, 122, 116, 101, 110, 115, 3, 89, 0, 122, 1, 97, 2, 105, 115, 122, 116, 195, 161, 108, 0, 122, 1, 97, 107, 2, 195, 173, 114, 111, 122, 0, 122, 1, 97, 109, 2, 195, 173, 114, 111, 122, 0, 122, 1, 97, 112, 2, 195, 173, 114, 111, 122, 0, 122, 1, 111, 114, 105, 112, 2, 107, 97, 0, 122, 2, 18, 66, 0, 122, 2, 45, 18, 66, 0, 122, 8, 97, 2, 105, 115, 122, 116, 0, 122, 8, 101, 2, 101, 110, 99, 105, 0, 122, 8, 101, 122, 115, 101, 110, 2, 101, 114, 0, 4, 1, 117, 105, 98, 117, 110, 97, 100, 3, 89, 12, 0, 1, 117, 116, 110, 101, 118, 117, 106, 0, 8, 101, 107, 2, 101, 108, 114, 105, 110, 103, 0, 122, 1, 97, 118, 97, 116, 2, 97, 0, 122, 1, 97, 118, 107, 2, 105, 97, 107, 195, 169, 114, 0, 122, 1, 97, 118, 108, 111, 0, 122, 1, 97, 118, 109, 97, 104, 0, 122, 1, 97, 118, 114, 111, 115, 2, 195, 161, 107, 0, 122, 1, 97, 118, 117, 121, 110, 0, 122, 1, 97, 118, 121, 116, 111, 107, 0, 122, 1, 97, 118, 186, 195, 121, 110, 0, 122, 1, 101, 108, 169, 195, 108, 182, 195, 102, 2, 101, 109, 0, 122, 1, 117, 105, 98, 117, 110, 97, 100, 0, 122, 1, 117, 116, 110, 101, 118, 117, 106, 0, 122, 8, 97, 108, 101, 109, 2, 195, 173, 110, 0, 122, 8, 97, 118, 97, 114, 0, 122, 8, 97, 118, 114, 111, 115, 0, 122, 8, 97, 118, 117, 115, 2, 97, 0, 122, 8, 169, 195, 110, 101, 112, 2, 195, 173, 110, 0, 122, 114, 3, 89, 52, 0, 122, 98, 3, 89, 71, 0, 4, 1, 117, 109, 2, 111, 108, 105, 110, 3, 89, 122, 0, 122, 0, 4, 1, 117, 116, 108, 101, 2, 111, 108, 3, 91, 0, 1, 145, 197, 108, 101, 108, 101, 102, 2, 195, 169, 103, 0, 1, 188, 195, 108, 112, 2, 122, 115, 0, 2, 18, 66, 0, 2, 45, 18, 66, 0, 4, 1, 105, 114, 102, 2, 122, 195, 182, 108, 3, 91, 12, 0, 1, 161, 195, 110, 97, 98, 98, 111, 114, 0, 114, 3, 91, 52, 0, 98, 3, 91, 71, 0, 4, 122, 1, 97, 103, 97, 109, 2, 195, 161, 114, 195, 186, 3, 91, 89, 0, 122, 1, 97, 103, 111, 102, 2, 101, 103, 0, 122, 1, 97, 103, 117, 108, 2, 101, 114, 197, 177, 0, 122, 1, 97, 107, 2, 195, 169, 107, 0, 122, 1, 97, 107, 97, 107, 2, 195, 169, 107, 0, 122, 1, 97, 107, 114, 97, 102, 2, 101, 109, 0, 122, 1, 97, 107, 114, 97, 102, 2, 101, 114, 197, 177, 0, 122, 1, 97, 107, 114, 97, 102, 2, 117, 107, 0, 122, 1, 97, 107, 114, 97, 102, 2, 195, 188, 114, 107, 0, 122, 1, 97, 107, 114, 97, 102, 2, 197, 145, 108, 197, 145, 0, 122, 1, 97, 109, 114, 161, 195, 104, 2, 97, 98, 0, 122, 1, 97, 109, 114, 161, 195, 104, 2, 195, 161, 109, 0, 122, 1, 97, 109, 114, 161, 195, 104, 2, 195, 182, 0, 122, 1, 97, 115, 2, 101, 109, 0, 122, 1, 97, 115, 97, 118, 2, 97, 107, 0, 122, 1, 97, 116, 116, 111, 108, 97, 104, 0, 122, 1, 97, 116, 117, 2, 101, 114, 0, 122, 1, 97, 116, 117, 2, 105, 110, 116, 0, 122, 1, 97, 116, 117, 2, 111, 108, 103, 0, 122, 1, 97, 116, 117, 2, 195, 161, 108, 0, 122, 1, 97, 116, 117, 2, 195, 161, 109, 0, 122, 1, 97, 118, 109, 97, 104, 2, 197, 145, 107, 101, 0, 122, 1, 97, 122, 114, 111, 98, 2, 197, 145, 114, 0, 122, 1, 101, 98, 98, 182, 195, 116, 2, 195, 161, 109, 0, 122, 1, 101, 100, 101, 122, 105, 116, 2, 195, 161, 108, 108, 195, 161, 115, 0, 122, 1, 101, 100, 108, 182, 195, 122, 2, 195, 188, 114, 107, 0, 122, 1, 101, 100, 108, 182, 195, 122, 2, 195, 188, 114, 107, 101, 0, 122, 1, 101, 100, 169, 195, 2, 195, 161, 106, 0, 122, 1, 101, 100, 169, 195, 2, 195, 188, 108, 0, 122, 1, 101, 104, 169, 195, 2, 195, 161, 106, 0, 122, 1, 101, 104, 169, 195, 109, 0, 122, 1, 101, 107, 169, 195, 2, 195, 179, 0, 122, 1, 101, 107, 169, 195, 2, 195, 179, 108, 0, 122, 1, 101, 107, 169, 195, 107, 2, 195, 188, 114, 107, 0, 122, 1, 101, 108, 101, 100, 101, 102, 2, 195, 161, 114, 110, 121, 0, 122, 1, 101, 108, 101, 102, 106, 101, 116, 2, 195, 161, 106, 0, 122, 1, 101, 108, 169, 195, 2, 101, 109, 0, 122, 1, 101, 108, 182, 195, 107, 2, 101, 109, 0, 122, 1, 101, 109, 101, 110, 2, 195, 173, 118, 0, 122, 1, 101, 109, 101, 110, 2, 197, 145, 114, 109, 0, 122, 1, 101, 109, 121, 108, 101, 115, 2, 197, 145, 107, 101, 0, 122, 1, 101, 110, 101, 121, 103, 101, 0, 122, 1, 101, 110, 101, 121, 103, 101, 2, 195, 161, 108, 0, 122, 1, 101, 112, 101, 122, 115, 2, 111, 109, 98, 97, 116, 0, 122, 1, 101, 114, 100, 101, 109, 2, 195, 169, 107, 0, 122, 1, 101, 114, 101, 118, 2, 197, 145, 107, 101, 0, 122, 1, 101, 114, 101, 122, 115, 145, 197, 108, 0, 122, 1, 101, 114, 169, 195, 104, 101, 102, 2, 195, 188, 114, 107, 0, 122, 1, 101, 114, 169, 195, 104, 101, 102, 2, 197, 145, 107, 101, 0, 122, 1, 101, 114, 169, 195, 118, 2, 195, 161, 106, 0, 122, 1, 101, 115, 99, 169, 195, 109, 0, 122, 1, 101, 115, 182, 195, 114, 182, 195, 118, 2, 197, 145, 107, 101, 0, 122, 1, 101, 116, 101, 108, 101, 121, 103, 188, 195, 2, 111, 98, 0, 122, 1, 101, 116, 101, 122, 114, 101, 122, 115, 2, 101, 114, 0, 122, 1, 101, 116, 114, 169, 195, 118, 2, 195, 161, 122, 97, 100, 0, 122, 1, 101, 116, 114, 169, 195, 118, 2, 197, 145, 108, 197, 145, 0, 122, 1, 101, 118, 100, 101, 110, 2, 195, 188, 114, 107, 0, 122, 1, 101, 118, 101, 108, 2, 101, 100, 0, 122, 1, 101, 118, 121, 110, 182, 195, 107, 0, 122, 1, 101, 118, 121, 110, 182, 195, 107, 2, 101, 107, 0, 122, 1, 101, 121, 103, 101, 104, 2, 195, 182, 103, 0, 122, 1, 101, 121, 108, 101, 107, 107, 105, 112, 2, 195, 161, 114, 110, 121, 0, 122, 1, 101, 121, 110, 101, 104, 114, 182, 195, 118, 2, 197, 145, 107, 101, 0, 122, 1, 101, 122, 115, 145, 197, 0, 122, 1, 101, 122, 188, 195, 116, 2, 101, 109, 0, 122, 1, 105, 107, 2, 101, 98, 0, 122, 1, 105, 107, 2, 101, 100, 0, 122, 1, 105, 107, 2, 101, 107, 114, 195, 169, 110, 121, 0, 122, 1, 105, 107, 2, 101, 114, 197, 177, 0, 122, 1, 105, 107, 2, 111, 98, 0, 122, 1, 105, 107, 2, 195, 161, 109, 0, 122, 1, 105, 107, 2, 195, 169, 107, 0, 122, 1, 105, 107, 2, 195, 179, 116, 195, 161, 114, 0, 122, 1, 105, 109, 97, 114, 105, 112, 2, 101, 114, 197, 177, 0, 122, 1, 105, 115, 99, 111, 107, 2, 101, 114, 101, 112, 0, 122, 1, 105, 116, 169, 195, 102, 2, 101, 114, 197, 177, 0, 122, 1, 105, 118, 182, 195, 116, 0, 122, 1, 105, 118, 182, 195, 116, 2, 195, 186, 114, 0, 122, 1, 105, 122, 161, 195, 98, 0, 122, 1, 105, 122, 161, 195, 111, 2, 101, 114, 197, 177, 0, 122, 1, 105, 122, 161, 195, 114, 102, 2, 101, 114, 197, 177, 0, 122, 1, 110, 101, 105, 108, 107, 2, 111, 102, 116, 0, 122, 1, 111, 99, 114, 97, 104, 0, 122, 1, 111, 100, 108, 111, 115, 122, 0, 122, 1, 111, 103, 111, 108, 97, 121, 103, 0, 122, 1, 111, 103, 161, 195, 108, 105, 118, 0, 122, 1, 111, 103, 161, 195, 108, 105, 118, 2, 195, 188, 114, 107, 101, 0, 122, 1, 111, 103, 161, 195, 108, 105, 118, 2, 197, 145, 107, 101, 0, 122, 1, 111, 107, 2, 97, 114, 118, 0, 122, 1, 111, 107, 97, 108, 2, 195, 161, 109, 0, 122, 1, 111, 107, 116, 105, 116, 2, 111, 108, 103, 195, 161, 108, 0, 122, 1, 111, 107, 161, 195, 98, 117, 116, 2, 101, 108, 0, 122, 1, 111, 107, 179, 195, 105, 102, 2, 101, 107, 114, 0, 122, 1, 111, 108, 169, 195, 99, 110, 161, 195, 112, 0, 122, 1, 111, 109, 97, 108, 108, 105, 118, 0, 122, 1, 111, 109, 97, 108, 108, 105, 118, 2, 195, 169, 107, 0, 122, 1, 111, 109, 111, 108, 112, 109, 101, 116, 2, 97, 107, 0, 122, 1, 111, 109, 114, 111, 107, 0, 122, 1, 111, 112, 97, 108, 2, 195, 161, 114, 0, 122, 1, 111, 112, 186, 195, 112, 2, 195, 186, 110, 121, 111, 103, 0, 122, 1, 111, 114, 97, 107, 2, 195, 169, 107, 0, 122, 1, 111, 114, 97, 107, 2, 195, 169, 114, 105, 97, 0, 122, 1, 111, 114, 97, 107, 2, 195, 169, 114, 105, 195, 161, 0, 122, 1, 111, 114, 97, 107, 2, 195, 169, 114, 105, 195, 161, 106, 195, 186, 0, 122, 1, 111, 114, 97, 109, 0, 122, 1, 111, 114, 97, 118, 97, 122, 2, 195, 188, 114, 0, 122, 1, 111, 114, 97, 118, 117, 102, 2, 101, 107, 195, 169, 114, 0, 122, 1, 111, 114, 105, 112, 2, 101, 109, 0, 122, 1, 111, 114, 105, 112, 97, 112, 0, 122, 1, 111, 114, 111, 112, 145, 197, 108, 0, 122, 1, 111, 114, 111, 116, 111, 109, 2, 101, 109, 195, 188, 118, 101, 103, 0, 122, 1, 111, 114, 111, 116, 111, 109, 2, 195, 161, 110, 0, 122, 1, 111, 114, 111, 122, 115, 2, 101, 114, 197, 177, 0, 122, 1, 111, 114, 161, 195, 118, 2, 101, 114, 0, 122, 1, 111, 114, 161, 195, 118, 2, 105, 108, 117, 101, 116, 116, 0, 122, 1, 111, 114, 161, 195, 118, 2, 195, 169, 112, 101, 0, 122, 1, 111, 114, 173, 195, 115, 122, 2, 195, 161, 106, 0, 122, 1, 111, 114, 173, 195, 115, 122, 2, 195, 169, 110, 0, 122, 1, 111, 116, 108, 161, 195, 116, 2, 195, 161, 114, 110, 121, 0, 122, 1, 111, 118, 114, 111, 2, 97, 107, 195, 169, 114, 116, 197, 145, 0, 122, 1, 111, 118, 114, 111, 2, 101, 109, 195, 169, 108, 121, 0, 122, 1, 111, 118, 114, 111, 2, 101, 114, 0, 122, 1, 111, 118, 114, 111, 2, 101, 114, 0, 122, 1, 111, 118, 114, 111, 2, 195, 161, 122, 0, 122, 1, 111, 118, 114, 111, 2, 195, 182, 118, 101, 116, 115, 195, 169, 103, 0, 122, 1, 111, 121, 103, 97, 102, 2, 101, 110, 116, 0, 122, 1, 111, 121, 110, 97, 114, 97, 2, 197, 145, 107, 101, 0, 122, 1, 114, 101, 118, 2, 97, 107, 0, 122, 1, 114, 101, 118, 2, 101, 114, 122, 0, 122, 1, 114, 111, 98, 2, 101, 109, 0, 122, 1, 114, 111, 98, 2, 195, 179, 114, 0, 122, 1, 114, 111, 115, 2, 101, 114, 197, 177, 0, 122, 1, 114, 111, 121, 103, 2, 197, 177, 114, 0, 122, 1, 114, 145, 197, 145, 197, 108, 101, 2, 101, 114, 197, 177, 0, 122, 1, 114, 161, 195, 116, 2, 101, 107, 195, 169, 114, 0, 122, 1, 114, 161, 195, 116, 2, 101, 114, 0, 122, 1, 114, 161, 195, 116, 2, 111, 109, 115, 122, 195, 169, 100, 0, 122, 1, 114, 161, 195, 116, 2, 195, 182, 118, 101, 0, 122, 1, 117, 103, 179, 195, 103, 97, 100, 101, 112, 2, 111, 98, 0, 122, 1, 117, 103, 179, 195, 108, 97, 116, 97, 107, 2, 195, 161, 109, 0, 122, 1, 117, 107, 105, 115, 122, 117, 109, 0, 122, 1, 117, 109, 116, 105, 114, 2, 97, 98, 0, 122, 1, 117, 109, 122, 105, 107, 101, 116, 97, 107, 2, 101, 114, 197, 177, 0, 122, 1, 117, 110, 161, 195, 108, 117, 2, 195, 161, 122, 97, 100, 0, 122, 1, 117, 112, 97, 107, 0, 122, 1, 117, 112, 105, 116, 2, 195, 161, 109, 0, 122, 1, 117, 116, 105, 98, 97, 104, 2, 101, 114, 197, 177, 0, 122, 1, 117, 116, 110, 105, 114, 105, 98, 97, 108, 2, 101, 114, 0, 122, 1, 117, 116, 161, 195, 107, 105, 100, 110, 105, 122, 115, 0, 122, 1, 117, 120, 117, 108, 0, 122, 1, 117, 122, 108, 117, 112, 2, 195, 161, 109, 0, 122, 1, 145, 197, 2, 97, 114, 118, 0, 122, 1, 145, 197, 2, 195, 161, 114, 109, 0, 122, 1, 145, 197, 2, 195, 182, 114, 110, 121, 0, 122, 1, 145, 197, 2, 195, 188, 108, 101, 0, 122, 1, 145, 197, 2, 195, 188, 108, 197, 145, 0, 122, 1, 145, 197, 104, 2, 101, 114, 101, 108, 0, 122, 1, 145, 197, 104, 2, 101, 114, 101, 112, 0, 122, 1, 145, 197, 108, 188, 195, 112, 101, 114, 2, 116, 114, 195, 161, 106, 107, 0, 122, 1, 145, 197, 108, 188, 195, 112, 101, 114, 2, 195, 161, 114, 110, 121, 0, 122, 1, 145, 197, 112, 105, 99, 0, 122, 1, 161, 195, 100, 97, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 100, 97, 2, 195, 188, 110, 101, 116, 0, 122, 1, 161, 195, 100, 97, 122, 161, 195, 108, 0, 122, 1, 161, 195, 100, 111, 112, 97, 108, 108, 161, 195, 103, 101, 109, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 100, 111, 118, 2, 105, 110, 116, 0, 122, 1, 161, 195, 100, 114, 161, 195, 115, 99, 2, 195, 179, 108, 0, 122, 1, 161, 195, 100, 117, 116, 2, 105, 110, 116, 0, 122, 1, 161, 195, 100, 117, 116, 2, 111, 109, 106, 0, 122, 1, 161, 195, 100, 179, 195, 122, 115, 2, 105, 0, 122, 1, 161, 195, 101, 116, 2, 101, 114, 118, 0, 122, 1, 161, 195, 103, 108, 97, 115, 114, 161, 195, 116, 2, 195, 161, 109, 98, 97, 0, 122, 1, 161, 195, 103, 110, 111, 114, 111, 122, 115, 0, 122, 1, 161, 195, 103, 110, 111, 122, 114, 111, 98, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 103, 110, 161, 195, 114, 2, 101, 114, 0, 122, 1, 161, 195, 103, 111, 104, 117, 115, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 103, 111, 116, 116, 97, 107, 0, 122, 1, 161, 195, 103, 111, 118, 161, 195, 121, 110, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 103, 114, 161, 195, 115, 0, 122, 1, 161, 195, 103, 122, 111, 109, 0, 122, 1, 161, 195, 103, 186, 195, 114, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 104, 108, 161, 195, 109, 0, 122, 1, 161, 195, 104, 117, 114, 2, 101, 107, 101, 114, 101, 0, 122, 1, 161, 195, 104, 117, 114, 2, 101, 107, 114, 195, 169, 110, 121, 0, 122, 1, 161, 195, 104, 117, 114, 2, 111, 98, 0, 122, 1, 161, 195, 106, 161, 195, 102, 2, 101, 114, 0, 122, 1, 161, 195, 107, 97, 108, 2, 101, 110, 0, 122, 1, 161, 195, 107, 105, 114, 112, 97, 112, 0, 122, 1, 161, 195, 107, 110, 111, 115, 0, 122, 1, 161, 195, 107, 111, 122, 115, 2, 101, 114, 0, 122, 1, 161, 195, 107, 111, 122, 115, 2, 195, 161, 109, 0, 122, 1, 161, 195, 108, 97, 116, 117, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 108, 106, 97, 104, 2, 195, 182, 103, 0, 122, 1, 161, 195, 108, 107, 117, 115, 99, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 108, 108, 97, 118, 2, 97, 98, 0, 122, 1, 161, 195, 108, 108, 161, 195, 0, 122, 1, 161, 195, 108, 108, 161, 195, 2, 195, 182, 103, 0, 122, 1, 161, 195, 108, 108, 161, 195, 110, 101, 108, 108, 101, 2, 101, 107, 114, 195, 169, 110, 121, 0, 122, 1, 161, 195, 108, 109, 97, 122, 115, 117, 115, 99, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 108, 109, 111, 2, 97, 103, 0, 122, 1, 161, 195, 108, 109, 161, 195, 116, 2, 195, 169, 107, 0, 122, 1, 161, 195, 108, 114, 111, 116, 105, 118, 0, 122, 1, 161, 195, 108, 116, 179, 195, 112, 0, 122, 1, 161, 195, 108, 117, 100, 110, 161, 195, 114, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 108, 117, 103, 161, 195, 116, 2, 97, 98, 195, 161, 108, 121, 0, 122, 1, 161, 195, 108, 117, 106, 161, 195, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 108, 179, 195, 122, 115, 2, 97, 98, 97, 100, 0, 122, 1, 161, 195, 109, 2, 101, 114, 0, 122, 1, 161, 195, 109, 2, 111, 114, 0, 122, 1, 161, 195, 109, 2, 197, 145, 114, 0, 122, 1, 161, 195, 109, 108, 97, 2, 195, 188, 114, 107, 0, 122, 1, 161, 195, 109, 108, 97, 2, 195, 188, 114, 107, 101, 0, 122, 1, 161, 195, 109, 111, 116, 161, 195, 108, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 109, 111, 121, 110, 2, 97, 98, 0, 122, 1, 161, 195, 109, 111, 121, 110, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 110, 97, 98, 98, 111, 114, 2, 101, 114, 0, 122, 1, 161, 195, 110, 97, 98, 98, 111, 115, 99, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 110, 97, 104, 117, 122, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 110, 97, 107, 107, 105, 121, 110, 2, 101, 114, 0, 122, 1, 161, 195, 110, 97, 108, 108, 105, 118, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 110, 97, 116, 116, 97, 115, 99, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 110, 103, 161, 195, 109, 0, 122, 1, 161, 195, 110, 114, 97, 98, 2, 197, 145, 107, 0, 122, 1, 161, 195, 110, 114, 161, 195, 112, 2, 195, 169, 107, 0, 122, 1, 161, 195, 110, 169, 195, 122, 115, 2, 101, 107, 0, 122, 1, 161, 195, 112, 97, 115, 99, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 112, 97, 115, 99, 2, 195, 161, 109, 0, 122, 1, 161, 195, 114, 97, 112, 97, 107, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 114, 97, 118, 97, 107, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 114, 97, 118, 97, 115, 99, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 114, 103, 117, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 114, 161, 195, 106, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 114, 161, 195, 106, 2, 111, 108, 103, 195, 161, 108, 97, 116, 0, 122, 1, 161, 195, 114, 173, 195, 2, 97, 107, 195, 169, 114, 0, 122, 1, 161, 195, 114, 173, 195, 145, 197, 108, 101, 2, 101, 114, 0, 122, 1, 161, 195, 114, 186, 195, 122, 115, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 116, 97, 103, 117, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 116, 97, 104, 2, 195, 188, 110, 101, 0, 122, 1, 161, 195, 116, 97, 108, 108, 97, 118, 2, 101, 114, 0, 122, 1, 161, 195, 116, 97, 116, 122, 111, 107, 116, 97, 108, 105, 121, 110, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 116, 97, 118, 105, 104, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 116, 106, 97, 104, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 116, 106, 186, 195, 121, 103, 2, 97, 98, 195, 161, 108, 121, 0, 122, 1, 161, 195, 116, 108, 111, 107, 105, 115, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 116, 110, 161, 195, 114, 0, 122, 1, 161, 195, 116, 110, 161, 195, 114, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 116, 114, 105, 2, 195, 169, 108, 0, 122, 1, 161, 195, 116, 161, 195, 108, 2, 195, 182, 103, 0, 122, 1, 161, 195, 116, 161, 195, 108, 108, 101, 2, 101, 114, 0, 122, 1, 161, 195, 116, 173, 195, 115, 97, 116, 117, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 118, 108, 97, 2, 101, 103, 0, 122, 1, 161, 195, 118, 173, 195, 104, 105, 107, 0, 122, 1, 161, 195, 121, 110, 161, 195, 104, 2, 97, 103, 0, 122, 1, 161, 195, 121, 116, 114, 161, 195, 104, 2, 195, 161, 114, 110, 121, 0, 122, 1, 161, 195, 122, 97, 116, 117, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 122, 111, 107, 97, 114, 179, 195, 122, 115, 2, 195, 161, 109, 0, 122, 1, 161, 195, 122, 111, 107, 108, 97, 108, 103, 111, 102, 2, 101, 114, 197, 177, 0, 122, 1, 161, 195, 122, 114, 161, 195, 103, 117, 115, 0, 122, 1, 169, 195, 100, 145, 197, 122, 114, 101, 122, 115, 2, 101, 0, 122, 1, 169, 195, 103, 110, 101, 108, 2, 97, 98, 195, 161, 108, 121, 0, 122, 1, 169, 195, 103, 110, 101, 114, 2, 101, 114, 197, 177, 0, 122, 1, 169, 195, 103, 110, 101, 122, 103, 169, 195, 2, 101, 114, 197, 177, 0, 122, 1, 169, 195, 103, 114, 101, 112, 2, 101, 114, 197, 177, 0, 122, 1, 169, 195, 103, 114, 182, 195, 2, 101, 114, 197, 177, 0, 122, 1, 169, 195, 103, 114, 182, 195, 100, 0, 122, 1, 169, 195, 103, 114, 182, 195, 100, 121, 110, 110, 101, 109, 2, 101, 114, 197, 177, 0, 122, 1, 169, 195, 103, 122, 101, 114, 2, 195, 161, 109, 0, 122, 1, 169, 195, 103, 145, 197, 98, 2, 101, 114, 197, 177, 0, 122, 1, 169, 195, 103, 169, 195, 2, 97, 98, 195, 161, 108, 121, 0, 122, 1, 169, 195, 103, 169, 195, 2, 97, 103, 0, 122, 1, 169, 195, 103, 182, 195, 104, 182, 195, 107, 2, 101, 114, 197, 177, 0, 122, 1, 169, 195, 107, 2, 195, 186, 114, 195, 161, 115, 0, 122, 1, 169, 195, 107, 182, 195, 108, 2, 101, 114, 197, 177, 0, 122, 1, 169, 195, 107, 182, 195, 108, 2, 195, 161, 109, 0, 122, 1, 169, 195, 108, 101, 107, 169, 195, 122, 114, 169, 195, 2, 105, 110, 116, 0, 122, 1, 169, 195, 108, 101, 109, 101, 2, 101, 114, 0, 122, 1, 169, 195, 108, 101, 114, 101, 122, 115, 2, 101, 116, 116, 0, 122, 1, 169, 195, 108, 101, 115, 105, 118, 100, 110, 111, 103, 2, 101, 114, 0, 122, 1, 169, 195, 108, 107, 182, 195, 121, 110, 182, 195, 107, 2, 195, 169, 108, 0, 122, 1, 169, 195, 108, 108, 101, 103, 182, 195, 122, 115, 2, 101, 114, 197, 177, 0, 122, 1, 169, 195, 108, 121, 110, 169, 195, 118, 114, 182, 195, 2, 101, 114, 197, 177, 0, 122, 1, 169, 195, 108, 145, 197, 100, 2, 195, 182, 103, 0, 122, 1, 169, 195, 108, 169, 195, 98, 2, 97, 108, 97, 103, 0, 122, 1, 169, 195, 108, 169, 195, 98, 2, 195, 182, 118, 0, 122, 1, 169, 195, 108, 188, 195, 2, 97, 107, 0, 122, 1, 169, 195, 108, 188, 195, 107, 101, 110, 101, 109, 2, 101, 114, 197, 177, 0, 122, 1, 169, 195, 108, 188, 195, 112, 101, 108, 101, 116, 2, 101, 114, 0, 122, 1, 169, 195, 108, 188, 195, 112, 101, 114, 2, 101, 114, 0, 122, 1, 169, 195, 110, 101, 107, 107, 182, 195, 122, 2, 101, 114, 197, 177, 0, 122, 1, 169, 195, 110, 101, 108, 101, 106, 2, 101, 114, 197, 177, 0, 122, 1, 169, 195, 114, 112, 2, 101, 114, 0, 122, 1, 169, 195, 114, 169, 195, 107, 2, 101, 114, 197, 177, 0, 122, 1, 169, 195, 114, 182, 195, 116, 2, 195, 182, 103, 0, 122, 1, 169, 195, 114, 182, 195, 116, 105, 107, 2, 101, 114, 197, 177, 0, 122, 1, 169, 195, 115, 101, 2, 195, 182, 103, 0, 122, 1, 169, 195, 115, 101, 114, 101, 107, 0, 122, 1, 169, 195, 116, 101, 100, 114, 105, 104, 2, 101, 114, 118, 101, 0, 122, 1, 169, 195, 116, 101, 100, 114, 105, 104, 2, 195, 182, 118, 101, 103, 0, 122, 1, 169, 195, 116, 101, 103, 169, 195, 98, 2, 101, 114, 197, 177, 0, 122, 1, 169, 195, 116, 101, 107, 101, 102, 2, 195, 188, 114, 107, 0, 122, 1, 169, 195, 116, 101, 108, 188, 195, 122, 115, 2, 97, 98, 0, 122, 1, 169, 195, 116, 101, 112, 101, 108, 103, 101, 109, 2, 101, 114, 197, 177, 0, 122, 1, 169, 195, 116, 101, 116, 2, 101, 0, 122, 1, 169, 195, 116, 101, 116, 108, 101, 100, 110, 101, 114, 2, 101, 114, 0, 122, 1, 169, 195, 116, 106, 101, 108, 2, 195, 182, 103, 0, 122, 1, 169, 195, 116, 108, 182, 195, 116, 2, 97, 98, 0, 122, 1, 169, 195, 116, 108, 182, 195, 116, 2, 97, 98, 195, 161, 108, 121, 111, 122, 0, 122, 1, 169, 195, 116, 108, 182, 195, 116, 2, 101, 114, 197, 177, 0, 122, 1, 169, 195, 116, 108, 182, 195, 116, 2, 195, 161, 109, 0, 122, 1, 169, 195, 116, 110, 101, 108, 101, 106, 2, 105, 110, 116, 0, 122, 1, 169, 195, 116, 110, 105, 104, 182, 195, 107, 2, 101, 114, 197, 177, 0, 122, 1, 169, 195, 116, 114, 101, 115, 0, 122, 1, 169, 195, 116, 114, 169, 195, 115, 2, 195, 161, 109, 0, 122, 1, 169, 195, 116, 122, 115, 101, 118, 169, 195, 116, 2, 101, 114, 197, 177, 0, 122, 1, 169, 195, 116, 173, 195, 114, 101, 107, 0, 122, 1, 169, 195, 116, 173, 195, 114, 101, 121, 110, 2, 101, 114, 197, 177, 0, 122, 1, 169, 195, 116, 177, 197, 102, 2, 97, 103, 0, 122, 1, 169, 195, 116, 182, 195, 107, 0, 122, 1, 169, 195, 116, 188, 195, 2, 101, 114, 197, 177, 0, 122, 1, 169, 195, 116, 188, 195, 2, 195, 161, 109, 0, 122, 1, 169, 195, 116, 188, 195, 97, 116, 106, 97, 114, 2, 101, 114, 0, 122, 1, 169, 195, 118, 182, 195, 108, 2, 101, 114, 197, 177, 0, 122, 1, 169, 195, 118, 182, 195, 108, 121, 108, 111, 116, 122, 115, 105, 112, 2, 101, 114, 197, 177, 0, 122, 1, 169, 195, 122, 101, 107, 108, 101, 100, 110, 101, 114, 2, 101, 114, 0, 122, 1, 169, 195, 122, 108, 101, 106, 2, 101, 114, 197, 177, 0, 122, 1, 169, 195, 122, 145, 197, 116, 114, 101, 102, 2, 101, 114, 197, 177, 0, 122, 1, 179, 195, 100, 97, 2, 195, 161, 109, 108, 97, 0, 122, 1, 179, 195, 105, 99, 161, 195, 107, 105, 110, 117, 109, 109, 111, 107, 2, 111, 98, 0, 122, 1, 179, 195, 105, 100, 161, 195, 114, 2, 101, 114, 101, 112, 0, 122, 1, 179, 195, 105, 100, 161, 195, 114, 2, 111, 98, 0, 122, 1, 179, 195, 107, 105, 115, 99, 0, 122, 1, 179, 195, 107, 105, 115, 99, 2, 195, 161, 109, 0, 122, 1, 179, 195, 110, 111, 118, 2, 101, 114, 101, 110, 195, 161, 100, 0, 122, 1, 179, 195, 112, 109, 97, 107, 0, 122, 1, 179, 195, 114, 186, 195, 122, 115, 2, 101, 109, 0, 122, 1, 179, 195, 116, 117, 97, 2, 101, 109, 195, 188, 118, 101, 103, 0, 122, 1, 179, 195, 118, 186, 195, 102, 2, 101, 114, 115, 122, 0, 122, 1, 179, 195, 118, 186, 195, 102, 2, 105, 109, 0, 122, 1, 182, 195, 108, 182, 195, 102, 106, 101, 116, 2, 195, 161, 106, 0, 122, 1, 182, 195, 114, 107, 182, 195, 2, 101, 107, 195, 169, 114, 0, 122, 1, 182, 195, 114, 145, 197, 122, 115, 2, 195, 173, 118, 0, 122, 1, 182, 195, 114, 182, 195, 118, 2, 101, 109, 0, 122, 1, 182, 195, 116, 110, 182, 195, 107, 0, 122, 1, 182, 195, 116, 110, 182, 195, 107, 2, 101, 114, 197, 177, 0, 122, 1, 182, 195, 118, 177, 197, 104, 2, 101, 109, 197, 177, 0, 122, 1, 186, 195, 100, 2, 97, 107, 195, 161, 108, 108, 0, 122, 1, 186, 195, 104, 2, 97, 102, 116, 0, 122, 1, 186, 195, 104, 2, 101, 107, 114, 195, 169, 110, 121, 0, 122, 1, 186, 195, 104, 2, 101, 108, 101, 116, 0, 122, 1, 186, 195, 104, 2, 195, 161, 108, 108, 195, 173, 116, 0, 122, 1, 186, 195, 121, 103, 161, 195, 0, 122, 1, 188, 195, 108, 112, 2, 101, 114, 197, 177, 0, 122, 2, 195, 173, 110, 197, 177, 0, 122, 8, 97, 100, 114, 111, 0, 122, 8, 97, 107, 97, 107, 2, 195, 179, 0, 122, 8, 97, 107, 114, 97, 102, 2, 105, 103, 0, 122, 8, 97, 107, 114, 97, 102, 2, 195, 161, 106, 0, 122, 8, 97, 110, 105, 0, 122, 8, 97, 115, 2, 101, 103, 0, 122, 8, 97, 115, 2, 195, 161, 114, 110, 121, 0, 122, 8, 97, 116, 117, 115, 97, 118, 0, 122, 8, 97, 118, 109, 97, 104, 2, 195, 188, 114, 107, 101, 0, 122, 8, 101, 100, 169, 195, 2, 101, 115, 122, 116, 101, 115, 116, 0, 122, 8, 101, 103, 169, 195, 115, 99, 110, 101, 122, 115, 2, 197, 177, 122, 0, 122, 8, 101, 107, 101, 114, 101, 107, 2, 195, 169, 107, 0, 122, 8, 101, 109, 101, 110, 0, 122, 8, 101, 110, 101, 109, 101, 107, 0, 122, 8, 101, 110, 169, 195, 109, 0, 122, 8, 101, 114, 101, 118, 0, 122, 8, 101, 116, 110, 101, 104, 2, 97, 107, 0, 122, 8, 101, 122, 115, 101, 109, 2, 195, 188, 114, 0, 122, 8, 105, 102, 107, 97, 98, 0, 122, 8, 105, 107, 2, 195, 161, 108, 108, 195, 161, 0, 122, 8, 105, 112, 115, 161, 195, 106, 2, 111, 98, 0, 122, 8, 105, 114, 103, 105, 116, 0, 122, 8, 105, 114, 145, 197, 107, 0, 122, 8, 105, 115, 97, 104, 2, 97, 103, 0, 122, 8, 111, 98, 109, 111, 103, 0, 122, 8, 111, 103, 97, 121, 103, 97, 2, 101, 114, 103, 0, 122, 8, 111, 103, 161, 195, 108, 105, 118, 2, 101, 109, 0, 122, 8, 111, 107, 2, 101, 109, 0, 122, 8, 111, 107, 105, 109, 0, 122, 8, 111, 107, 122, 115, 105, 112, 0, 122, 8, 111, 109, 97, 122, 115, 0, 122, 8, 111, 109, 161, 195, 118, 0, 122, 8, 111, 112, 97, 107, 0, 122, 8, 111, 112, 97, 110, 2, 111, 98, 0, 122, 8, 111, 114, 161, 195, 118, 0, 122, 8, 111, 114, 161, 195, 118, 2, 195, 169, 108, 0, 122, 8, 111, 121, 103, 110, 111, 114, 0, 122, 8, 114, 101, 118, 2, 101, 114, 0, 122, 8, 114, 111, 115, 2, 101, 115, 122, 195, 169, 108, 121, 0, 122, 8, 114, 111, 121, 103, 0, 122, 8, 114, 161, 195, 104, 0, 122, 8, 114, 161, 195, 116, 2, 111, 98, 0, 122, 8, 114, 161, 195, 121, 110, 2, 101, 114, 197, 177, 0, 122, 8, 117, 100, 108, 111, 107, 2, 101, 0, 122, 8, 117, 103, 179, 195, 103, 97, 100, 101, 112, 2, 101, 114, 0, 122, 8, 117, 107, 101, 104, 2, 97, 103, 0, 122, 8, 117, 107, 179, 195, 109, 0, 122, 8, 117, 112, 173, 195, 116, 2, 195, 161, 109, 0, 122, 8, 117, 112, 173, 195, 116, 2, 195, 182, 118, 101, 103, 0, 122, 8, 117, 114, 173, 195, 118, 2, 101, 114, 0, 122, 8, 145, 197, 2, 101, 108, 108, 0, 122, 8, 145, 197, 2, 101, 114, 197, 177, 0, 122, 8, 145, 197, 2, 105, 0, 122, 8, 145, 197, 2, 111, 107, 195, 161, 0, 122, 8, 145, 197, 2, 195, 169, 107, 0, 122, 8, 145, 197, 104, 0, 122, 8, 161, 195, 102, 2, 195, 173, 110, 0, 122, 8, 161, 195, 103, 97, 99, 97, 107, 2, 101, 114, 0, 122, 8, 161, 195, 103, 114, 111, 102, 0, 122, 8, 161, 195, 107, 97, 108, 0, 122, 8, 161, 195, 107, 97, 114, 0, 122, 8, 161, 195, 108, 97, 2, 111, 108, 103, 0, 122, 8, 161, 195, 108, 179, 195, 122, 115, 0, 122, 8, 161, 195, 109, 2, 195, 179, 0, 122, 8, 161, 195, 109, 111, 108, 108, 97, 118, 0, 122, 8, 161, 195, 114, 114, 111, 102, 0, 122, 8, 161, 195, 115, 0, 122, 8, 161, 195, 115, 122, 179, 195, 114, 2, 197, 145, 107, 0, 122, 8, 161, 195, 116, 97, 104, 2, 101, 114, 0, 122, 8, 161, 195, 116, 110, 97, 107, 114, 111, 104, 2, 101, 114, 0, 122, 8, 161, 195, 116, 114, 111, 112, 0, 122, 8, 161, 195, 116, 161, 195, 108, 2, 195, 182, 103, 0, 122, 8, 161, 195, 118, 108, 105, 122, 115, 0, 122, 8, 169, 195, 99, 101, 114, 2, 195, 161, 114, 195, 186, 0, 122, 8, 169, 195, 100, 101, 107, 108, 101, 122, 173, 195, 104, 0, 122, 8, 169, 195, 103, 169, 195, 0, 122, 8, 169, 195, 107, 112, 105, 115, 99, 0, 122, 8, 169, 195, 107, 169, 195, 98, 0, 122, 8, 169, 195, 114, 2, 101, 114, 197, 177, 0, 122, 8, 169, 195, 116, 101, 100, 108, 188, 195, 107, 0, 122, 8, 169, 195, 116, 101, 116, 110, 188, 195, 116, 105, 107, 0, 122, 8, 169, 195, 116, 101, 118, 0, 122, 8, 169, 195, 116, 106, 101, 108, 0, 122, 8, 169, 195, 116, 173, 195, 114, 101, 107, 2, 97, 103, 0, 122, 8, 169, 195, 118, 101, 107, 0, 122, 8, 169, 195, 118, 101, 107, 2, 101, 114, 0, 122, 8, 169, 195, 122, 101, 100, 110, 101, 114, 101, 98, 2, 101, 0, 122, 8, 179, 195, 106, 0, 122, 8, 179, 195, 106, 97, 104, 0, 122, 8, 179, 195, 116, 173, 195, 114, 105, 112, 2, 101, 0, 122, 8, 182, 195, 114, 107, 182, 195, 2, 101, 103, 0, 122, 8, 182, 195, 114, 107, 182, 195, 2, 101, 107, 101, 114, 101, 0, 122, 8, 182, 195, 114, 107, 188, 195, 116, 0, 122, 8, 182, 195, 114, 182, 195, 107, 2, 105, 103, 0, 122, 8, 182, 195, 114, 182, 195, 118, 0, 122, 8, 186, 195, 104, 2, 97, 108, 111, 110, 110, 97, 0, 122, 8, 186, 195, 104, 2, 105, 103, 101, 116, 0, 122, 8, 186, 195, 104, 2, 195, 173, 110, 0, 7, 6, 115, 122, 0, 4, 3, 89, 0, 1, 97, 118, 97, 114, 2, 195, 161, 114, 0, 1, 97, 118, 97, 116, 2, 195, 161, 114, 97, 0, 1, 100, 110, 101, 114, 2, 101, 114, 101, 116, 197, 145, 0, 1, 100, 110, 101, 114, 2, 101, 114, 3, 89, 12, 0, 4, 116, 1, 97, 114, 97, 112, 2, 115, 101, 103, 103, 3, 89, 47, 0, 116, 1, 101, 98, 122, 97, 2, 115, 105, 115, 97, 107, 0, 116, 1, 101, 114, 101, 107, 2, 115, 111, 114, 0, 116, 1, 101, 114, 101, 107, 2, 115, 122, 101, 114, 0, 116, 1, 117, 121, 110, 2, 115, 195, 188, 118, 101, 103, 0, 4, 116, 115, 122, 3, 89, 47, 89, 0, 116, 115, 122, 1, 97, 114, 97, 112, 2, 97, 103, 0, 116, 115, 122, 1, 97, 114, 97, 112, 2, 97, 110, 100, 195, 161, 108, 0, 116, 115, 122, 1, 97, 114, 97, 112, 2, 101, 107, 0, 116, 115, 122, 1, 101, 114, 101, 107, 2, 101, 0, 116, 115, 122, 1, 105, 108, 2, 101, 114, 197, 177, 0, 116, 115, 122, 1, 105, 116, 97, 98, 2, 101, 114, 197, 177, 0, 116, 115, 122, 8, 97, 109, 97, 100, 0, 4, 116, 115, 122, 101, 1, 105, 116, 97, 98, 2, 103, 195, 169, 3, 89, 47, 89, 109, 0, 116, 115, 122, 101, 1, 105, 116, 101, 109, 97, 0, 116, 115, 122, 101, 1, 111, 114, 100, 2, 114, 122, 197, 145, 0, 116, 115, 122, 101, 8, 97, 107, 0, 4, 116, 115, 1, 97, 108, 97, 109, 2, 117, 103, 97, 108, 3, 89, 47, 91, 0, 116, 115, 1, 97, 114, 97, 112, 2, 105, 104, 101, 100, 0, 116, 115, 1, 97, 114, 97, 112, 2, 111, 110, 107, 0, 116, 115, 1, 97, 114, 97, 112, 2, 111, 114, 115, 0, 116, 115, 1, 97, 114, 97, 112, 2, 117, 104, 97, 110, 0, 116, 115, 1, 97, 114, 97, 112, 2, 195, 188, 116, 101, 0, 116, 115, 1, 101, 116, 2, 111, 114, 111, 122, 0, 116, 115, 8, 97, 109, 97, 100, 0, 116, 115, 3, 89, 76, 12, 0, 116, 115, 122, 97, 3, 89, 119, 108, 0, 116, 115, 122, 101, 3, 89, 119, 109, 0, 115, 1, 169, 195, 103, 101, 2, 195, 169, 103, 3, 91, 0, 4, 115, 1, 97, 103, 105, 2, 195, 161, 103, 111, 115, 3, 91, 12, 0, 115, 1, 169, 195, 107, 103, 101, 108, 2, 195, 169, 103, 101, 115, 0, 1, 97, 118, 2, 97, 98, 108, 3, 91, 15, 88, 0, 4, 1, 97, 118, 2, 195, 161, 112, 111, 114, 3, 91, 88, 0, 1, 97, 118, 2, 195, 161, 114, 0, 1, 111, 114, 97, 109, 2, 117, 103, 0, 1, 161, 195, 108, 108, 97, 104, 2, 97, 118, 97, 114, 0, 1, 161, 195, 121, 108, 107, 161, 195, 102, 2, 101, 110, 101, 0, 1, 169, 195, 118, 101, 2, 97, 118, 97, 114, 0, 1, 179, 195, 110, 111, 118, 2, 101, 110, 101, 0, 1, 182, 195, 114, 182, 195, 107, 2, 117, 103, 0, 2, 97, 99, 115, 107, 0, 2, 195, 182, 108, 100, 0, 4, 115, 1, 97, 118, 2, 97, 110, 195, 169, 114, 3, 91, 90, 0, 115, 1, 97, 118, 2, 195, 173, 114, 0, 115, 1, 101, 122, 105, 118, 2, 101, 109, 0, 115, 1, 161, 195, 107, 110, 111, 115, 2, 101, 109, 108, 0, 115, 1, 161, 195, 116, 2, 105, 110, 0, 115, 1, 169, 195, 116, 114, 101, 115, 2, 195, 173, 114, 0, 115, 2, 195, 161, 107, 0, 7, 6, 116, 106, 0, 4, 1, 97, 104, 2, 101, 103, 121, 197, 177, 3, 47, 57, 0, 1, 97, 108, 108, 161, 195, 2, 195, 179, 108, 195, 169, 116, 0, 1, 97, 108, 111, 100, 110, 111, 103, 2, 101, 108, 0, 1, 97, 108, 117, 103, 110, 97, 104, 2, 97, 118, 195, 173, 116, 0, 1, 97, 108, 117, 103, 110, 97, 104, 2, 101, 108, 0, 1, 97, 109, 97, 121, 108, 111, 102, 2, 101, 108, 0, 1, 97, 110, 111, 118, 2, 101, 103, 121, 0, 1, 97, 112, 97, 115, 99, 2, 101, 108, 0, 1, 97, 112, 97, 115, 99, 2, 195, 161, 116, 195, 169, 107, 0, 1, 97, 122, 111, 103, 108, 111, 100, 2, 97, 118, 195, 173, 116, 0, 1, 101, 108, 98, 98, 182, 195, 116, 2, 195, 182, 118, 101, 100, 101, 108, 0, 1, 101, 108, 101, 116, 122, 115, 105, 116, 2, 101, 103, 121, 0, 1, 101, 108, 114, 169, 195, 98, 2, 101, 103, 121, 0, 1, 101, 108, 169, 195, 2, 101, 108, 0, 1, 101, 108, 169, 195, 2, 195, 161, 114, 97, 100, 195, 169, 107, 0, 1, 101, 108, 188, 195, 114, 101, 116, 2, 101, 108, 195, 182, 108, 0, 1, 101, 109, 169, 195, 110, 2, 117, 104, 195, 161, 0, 1, 101, 110, 101, 109, 2, 101, 103, 103, 121, 0, 1, 101, 110, 101, 109, 2, 101, 103, 121, 0, 1, 101, 110, 101, 122, 188, 195, 2, 101, 108, 0, 1, 101, 110, 114, 101, 116, 110, 105, 2, 101, 103, 121, 0, 1, 101, 110, 188, 195, 122, 115, 2, 101, 108, 0, 1, 101, 115, 101, 2, 111, 103, 0, 1, 101, 122, 101, 106, 101, 102, 2, 101, 108, 0, 1, 101, 122, 114, 169, 195, 122, 182, 195, 107, 2, 97, 118, 195, 173, 0, 1, 101, 122, 115, 169, 195, 109, 114, 101, 116, 2, 111, 103, 0, 1, 101, 122, 115, 169, 195, 109, 114, 101, 116, 2, 195, 161, 114, 0, 1, 101, 122, 115, 169, 195, 109, 114, 101, 116, 2, 195, 161, 116, 195, 169, 107, 0, 1, 101, 122, 121, 108, 101, 104, 2, 101, 108, 0, 1, 101, 122, 177, 197, 121, 116, 110, 101, 108, 108, 105, 98, 2, 101, 108, 0, 1, 108, 111, 104, 2, 195, 161, 116, 195, 169, 107, 0, 1, 110, 97, 107, 107, 111, 114, 2, 195, 161, 114, 97, 100, 195, 169, 107, 0, 1, 110, 101, 122, 115, 2, 97, 107, 97, 98, 0, 1, 110, 101, 122, 115, 2, 195, 161, 110, 111, 115, 0, 1, 110, 111, 114, 102, 2, 195, 161, 114, 0, 1, 110, 111, 115, 99, 2, 195, 161, 116, 195, 169, 107, 0, 1, 111, 112, 97, 108, 108, 161, 195, 2, 97, 118, 117, 108, 0, 1, 111, 112, 97, 108, 108, 161, 195, 2, 101, 108, 0, 1, 114, 111, 112, 115, 2, 195, 161, 116, 195, 169, 107, 0, 1, 114, 188, 195, 107, 2, 101, 108, 0, 1, 115, 101, 116, 2, 195, 161, 116, 195, 169, 107, 0, 1, 115, 188, 195, 122, 101, 2, 101, 108, 118, 0, 1, 122, 115, 182, 195, 114, 182, 195, 107, 2, 195, 161, 114, 0, 1, 161, 195, 2, 117, 115, 115, 0, 1, 161, 195, 2, 117, 116, 0, 1, 161, 195, 2, 195, 161, 114, 0, 1, 161, 195, 2, 195, 182, 0, 1, 161, 195, 2, 195, 182, 104, 101, 0, 1, 161, 195, 2, 195, 182, 110, 0, 1, 161, 195, 2, 195, 182, 115, 115, 122, 0, 1, 161, 195, 2, 195, 182, 116, 0, 1, 169, 195, 104, 2, 101, 103, 121, 197, 177, 0, 1, 169, 195, 107, 2, 101, 103, 121, 197, 177, 0, 1, 169, 195, 107, 105, 112, 2, 195, 161, 116, 115, 122, 0, 1, 169, 195, 108, 2, 111, 103, 111, 115, 117, 108, 116, 115, 195, 161, 103, 0, 1, 169, 195, 110, 101, 122, 2, 195, 161, 116, 115, 122, 0, 1, 179, 195, 107, 115, 2, 117, 104, 195, 161, 115, 122, 0, 1, 179, 195, 112, 2, 101, 0, 1, 182, 195, 2, 101, 103, 121, 197, 177, 0, 1, 186, 195, 2, 97, 118, 195, 173, 0, 1, 186, 195, 2, 101, 108, 122, 195, 169, 115, 0, 1, 186, 195, 2, 101, 108, 122, 197, 145, 0, 1, 186, 195, 2, 111, 103, 0, 2, 101, 108, 0, 8, 97, 122, 161, 195, 108, 98, 161, 195, 116, 2, 101, 103, 121, 0, 8, 101, 108, 101, 116, 122, 115, 105, 116, 2, 101, 108, 0, 8, 101, 108, 122, 115, 169, 195, 107, 2, 101, 108, 101, 110, 0, 8, 110, 97, 122, 115, 101, 100, 2, 195, 161, 114, 109, 0, 8, 122, 115, 101, 114, 101, 107, 2, 195, 161, 0, 8, 122, 115, 169, 195, 118, 2, 195, 179, 115, 108, 0, 8, 161, 195, 2, 101, 108, 101, 110, 116, 107, 101, 122, 0, 8, 161, 195, 2, 117, 0, 8, 161, 195, 2, 195, 182, 106, 0, 4, 195, 161, 116, 115, 115, 122, 1, 161, 195, 3, 47, 57, 114, 119, 12, 0, 195, 161, 116, 115, 122, 1, 161, 195, 0, 4, 1, 17, 67, 3, 80, 0, 1, 110, 111, 115, 99, 0, 1, 114, 188, 195, 107, 0, 1, 115, 188, 195, 122, 101, 0, 4, 1, 17, 65, 2, 17, 65, 3, 80, 12, 0, 1, 101, 108, 122, 188, 195, 0, 1, 161, 195, 103, 2, 195, 161, 114, 0, 1, 161, 195, 104, 2, 195, 161, 114, 0, 1, 161, 195, 108, 114, 111, 107, 2, 195, 161, 114, 97, 0, 1, 161, 195, 114, 97, 98, 2, 195, 161, 114, 0, 7, 6, 116, 115, 0, 4, 122, 1, 97, 100, 97, 3, 47, 89, 0, 122, 1, 97, 100, 97, 2, 111, 108, 103, 195, 161, 108, 116, 97, 116, 0, 122, 1, 97, 104, 2, 195, 161, 122, 0, 122, 1, 97, 108, 117, 100, 110, 105, 2, 195, 179, 0, 122, 1, 101, 108, 98, 98, 182, 195, 116, 2, 111, 108, 0, 122, 1, 101, 108, 188, 195, 115, 99, 101, 98, 2, 195, 179, 0, 122, 1, 101, 110, 2, 111, 0, 122, 1, 101, 110, 101, 109, 2, 195, 169, 108, 0, 122, 1, 101, 116, 101, 114, 101, 122, 115, 2, 111, 108, 103, 195, 161, 108, 97, 116, 0, 122, 1, 101, 122, 109, 101, 110, 2, 111, 0, 122, 1, 105, 104, 2, 101, 0, 122, 1, 105, 104, 2, 195, 179, 0, 122, 1, 106, 101, 115, 2, 195, 182, 0, 122, 1, 110, 97, 108, 2, 195, 179, 0, 122, 1, 110, 101, 98, 2, 111, 114, 117, 108, 0, 122, 1, 110, 101, 122, 115, 2, 111, 98, 114, 111, 107, 0, 122, 1, 110, 101, 122, 115, 2, 195, 169, 107, 0, 122, 1, 110, 111, 114, 102, 2, 111, 108, 103, 195, 161, 108, 0, 122, 1, 110, 111, 115, 99, 2, 195, 169, 110, 0, 122, 1, 110, 161, 195, 112, 2, 195, 169, 108, 0, 122, 1, 111, 112, 97, 121, 103, 0, 122, 1, 114, 101, 107, 2, 111, 109, 115, 122, 195, 169, 100, 0, 122, 1, 114, 111, 112, 115, 2, 111, 108, 103, 195, 161, 108, 0, 122, 1, 114, 188, 195, 107, 2, 195, 179, 0, 122, 1, 161, 195, 2, 97, 0, 122, 1, 161, 195, 2, 101, 0, 122, 1, 161, 195, 2, 111, 107, 0, 122, 1, 161, 195, 2, 195, 182, 0, 122, 1, 161, 195, 2, 195, 186, 0, 122, 1, 161, 195, 2, 197, 145, 0, 122, 1, 161, 195, 2, 197, 177, 0, 122, 1, 161, 195, 98, 97, 107, 2, 195, 169, 0, 122, 1, 161, 195, 104, 2, 195, 169, 108, 0, 122, 1, 161, 195, 108, 2, 101, 0, 122, 1, 161, 195, 108, 2, 101, 114, 195, 169, 115, 122, 0, 122, 1, 161, 195, 122, 115, 115, 97, 112, 2, 195, 169, 108, 0, 122, 1, 169, 195, 104, 2, 195, 161, 122, 0, 122, 1, 169, 195, 107, 2, 101, 114, 101, 112, 0, 122, 1, 169, 195, 107, 2, 195, 161, 122, 0, 122, 1, 169, 195, 107, 2, 195, 173, 110, 0, 122, 1, 169, 195, 108, 2, 195, 161, 109, 0, 122, 1, 169, 195, 116, 182, 195, 115, 2, 197, 145, 107, 101, 0, 122, 1, 179, 195, 107, 115, 2, 111, 107, 110, 121, 0, 122, 1, 179, 195, 114, 100, 2, 197, 145, 114, 0, 122, 1, 182, 195, 2, 195, 161, 122, 0, 122, 1, 186, 195, 2, 111, 114, 111, 115, 0, 122, 1, 186, 195, 2, 195, 169, 108, 0, 122, 2, 97, 0, 122, 2, 101, 0, 122, 2, 195, 161, 0, 122, 8, 97, 104, 2, 111, 98, 0, 122, 8, 97, 104, 99, 2, 111, 98, 0, 122, 8, 161, 195, 2, 111, 108, 103, 195, 161, 108, 0, 122, 8, 161, 195, 2, 111, 114, 111, 110, 103, 0, 122, 8, 161, 195, 2, 111, 114, 117, 108, 116, 0, 122, 8, 161, 195, 2, 111, 114, 195, 173, 116, 0, 122, 8, 169, 195, 104, 2, 111, 98, 0, 122, 8, 169, 195, 107, 2, 111, 98, 0, 122, 8, 179, 195, 112, 2, 195, 169, 107, 0, 122, 8, 182, 195, 2, 111, 98, 0, 122, 195, 169, 1, 169, 195, 122, 115, 3, 47, 89, 113, 0, 4, 1, 97, 100, 97, 3, 47, 91, 0, 1, 97, 100, 97, 108, 101, 102, 2, 111, 114, 0, 1, 97, 104, 2, 195, 161, 118, 0, 1, 97, 108, 108, 161, 195, 2, 101, 114, 101, 103, 0, 1, 97, 108, 111, 100, 110, 111, 103, 2, 111, 114, 0, 1, 97, 108, 114, 111, 107, 97, 121, 103, 2, 111, 114, 111, 122, 0, 1, 97, 108, 117, 100, 122, 111, 109, 2, 111, 0, 1, 97, 108, 161, 195, 103, 115, 122, 105, 118, 2, 111, 114, 0, 1, 97, 108, 161, 195, 103, 115, 122, 105, 118, 2, 111, 114, 111, 122, 97, 0, 1, 97, 109, 97, 121, 108, 111, 102, 2, 195, 161, 118, 0, 1, 97, 110, 97, 103, 97, 100, 2, 101, 106, 0, 1, 97, 114, 105, 108, 101, 102, 2, 195, 161, 118, 0, 1, 97, 122, 161, 195, 108, 98, 161, 195, 116, 2, 111, 114, 0, 1, 101, 103, 105, 122, 115, 2, 111, 114, 0, 1, 101, 108, 101, 118, 177, 197, 109, 2, 111, 0, 1, 101, 108, 101, 118, 177, 197, 109, 2, 195, 161, 118, 0, 1, 101, 108, 101, 121, 103, 101, 107, 2, 195, 169, 114, 0, 1, 101, 108, 114, 169, 195, 115, 173, 195, 107, 2, 111, 114, 111, 122, 97, 116, 0, 1, 101, 108, 122, 188, 195, 2, 111, 114, 0, 1, 101, 108, 188, 195, 112, 169, 195, 2, 97, 114, 111, 107, 0, 1, 101, 108, 188, 195, 112, 169, 195, 2, 97, 114, 111, 107, 0, 1, 101, 108, 188, 195, 114, 101, 116, 2, 195, 161, 118, 0, 1, 101, 108, 188, 195, 115, 99, 101, 98, 2, 195, 169, 0, 1, 101, 110, 2, 101, 0, 1, 101, 110, 2, 195, 161, 116, 111, 114, 0, 1, 101, 110, 101, 109, 2, 111, 114, 0, 1, 101, 118, 182, 195, 122, 115, 2, 97, 112, 107, 0, 1, 101, 122, 109, 101, 110, 2, 116, 114, 97, 116, 195, 169, 0, 1, 101, 122, 188, 195, 102, 97, 107, 110, 117, 109, 2, 97, 98, 108, 0, 1, 105, 98, 2, 101, 98, 101, 115, 115, 195, 169, 103, 0, 1, 105, 109, 2, 101, 0, 1, 108, 97, 98, 111, 107, 2, 117, 103, 195, 161, 114, 0, 1, 108, 111, 104, 2, 195, 161, 112, 97, 100, 116, 0, 1, 110, 105, 109, 2, 101, 109, 0, 1, 110, 111, 115, 99, 2, 195, 169, 114, 0, 1, 110, 161, 195, 114, 111, 107, 2, 101, 0, 1, 111, 98, 111, 114, 2, 111, 102, 0, 1, 111, 111, 98, 2, 111, 114, 114, 101, 110, 100, 0, 1, 111, 112, 97, 108, 108, 161, 195, 2, 111, 114, 0, 1, 114, 97, 112, 2, 195, 161, 118, 0, 1, 114, 161, 195, 112, 2, 97, 106, 116, 195, 179, 0, 1, 114, 161, 195, 122, 2, 111, 114, 195, 186, 0, 1, 115, 101, 116, 2, 195, 169, 114, 0, 1, 117, 99, 110, 117, 104, 2, 195, 161, 103, 0, 1, 122, 115, 101, 116, 2, 111, 114, 0, 1, 161, 195, 2, 101, 103, 195, 173, 116, 0, 1, 161, 195, 2, 101, 106, 108, 101, 0, 1, 161, 195, 2, 111, 114, 0, 1, 161, 195, 2, 117, 103, 0, 1, 161, 195, 2, 117, 104, 0, 1, 161, 195, 2, 117, 114, 0, 1, 161, 195, 2, 195, 169, 0, 1, 161, 195, 2, 195, 182, 112, 114, 197, 145, 0, 1, 161, 195, 2, 195, 182, 112, 195, 182, 114, 0, 1, 161, 195, 2, 195, 188, 108, 116, 0, 1, 161, 195, 2, 195, 188, 116, 0, 1, 161, 195, 2, 195, 188, 118, 195, 173, 116, 0, 1, 161, 195, 103, 2, 195, 188, 108, 108, 121, 101, 100, 0, 1, 169, 195, 107, 2, 97, 114, 107, 195, 186, 0, 1, 169, 195, 107, 2, 97, 114, 111, 107, 0, 1, 169, 195, 107, 2, 101, 98, 101, 115, 115, 195, 169, 103, 101, 115, 0, 1, 169, 195, 107, 2, 111, 114, 0, 1, 169, 195, 107, 2, 195, 161, 118, 0, 1, 169, 195, 114, 182, 195, 115, 2, 101, 98, 0, 1, 179, 195, 107, 115, 2, 97, 112, 107, 97, 0, 1, 179, 195, 114, 100, 2, 195, 182, 118, 195, 169, 110, 110, 121, 0, 1, 179, 195, 114, 100, 2, 195, 182, 118, 195, 169, 110, 121, 0, 1, 179, 195, 122, 111, 98, 2, 111, 0, 1, 186, 195, 107, 2, 117, 103, 0, 8, 161, 195, 2, 111, 100, 111, 114, 0, 8, 186, 195, 2, 195, 161, 118, 0, 4, 1, 106, 3, 76, 0, 1, 110, 101, 109, 2, 118, 195, 161, 114, 0, 1, 110, 182, 195, 100, 2, 195, 182, 110, 0, 2, 32, 14, 128, 128, 130, 0, 2, 97, 0, 2, 101, 0, 2, 111, 0, 2, 117, 0, 2, 195, 161, 0, 2, 195, 169, 0, 4, 1, 97, 108, 108, 161, 195, 2, 195, 161, 103, 3, 76, 12, 0, 1, 97, 108, 117, 109, 0, 1, 101, 104, 101, 108, 2, 195, 169, 103, 0, 1, 101, 104, 101, 116, 2, 195, 169, 103, 0, 1, 101, 105, 115, 0, 1, 101, 107, 188, 195, 115, 2, 195, 169, 103, 0, 1, 101, 108, 106, 101, 102, 2, 195, 169, 103, 0, 1, 101, 109, 169, 195, 110, 2, 195, 169, 103, 0, 1, 101, 114, 101, 109, 115, 105, 2, 195, 169, 103, 0, 1, 101, 114, 169, 195, 2, 195, 169, 103, 0, 1, 101, 118, 101, 110, 2, 195, 169, 103, 0, 1, 101, 118, 182, 195, 107, 2, 195, 169, 103, 0, 1, 101, 118, 182, 195, 122, 115, 2, 195, 169, 103, 0, 1, 101, 122, 101, 108, 101, 116, 182, 195, 107, 2, 195, 169, 103, 0, 1, 101, 122, 105, 102, 2, 195, 169, 103, 0, 1, 101, 122, 109, 101, 110, 0, 1, 105, 103, 101, 115, 2, 195, 169, 0, 1, 111, 116, 97, 103, 111, 109, 161, 195, 116, 2, 195, 161, 103, 0, 1, 111, 122, 105, 98, 2, 195, 161, 103, 0, 1, 117, 99, 110, 117, 104, 2, 195, 161, 103, 0, 1, 161, 195, 2, 195, 179, 0, 1, 161, 195, 106, 97, 115, 2, 195, 161, 103, 0, 1, 161, 195, 112, 97, 2, 195, 161, 103, 0, 1, 161, 195, 114, 97, 98, 0, 1, 169, 195, 107, 2, 195, 169, 103, 0, 1, 169, 195, 109, 101, 122, 115, 2, 195, 169, 103, 0, 1, 169, 195, 114, 2, 195, 169, 103, 0, 1, 169, 195, 116, 182, 195, 115, 2, 195, 169, 103, 0, 1, 169, 195, 118, 2, 195, 169, 103, 0, 1, 173, 195, 103, 101, 115, 0, 1, 173, 195, 108, 108, 161, 195, 0, 1, 173, 195, 114, 111, 122, 115, 2, 97, 0, 1, 173, 195, 114, 188, 195, 2, 101, 0, 1, 177, 197, 102, 0, 1, 177, 197, 104, 0, 1, 182, 195, 116, 182, 195, 107, 2, 195, 169, 103, 0, 8, 161, 195, 104, 2, 195, 161, 103, 0, 100, 3, 76, 72, 0, 195, 182, 3, 76, 110, 0, 195, 188, 3, 76, 111, 0, 4, 122, 1, 101, 109, 2, 118, 101, 3, 119, 0, 122, 1, 101, 109, 101, 108, 2, 118, 195, 169, 110, 0, 122, 1, 161, 195, 106, 2, 104, 97, 115, 115, 0, 122, 1, 161, 195, 106, 2, 104, 97, 116, 0, 122, 1, 161, 195, 106, 2, 109, 0, 122, 1, 161, 195, 106, 2, 118, 0, 4, 115, 122, 1, 97, 108, 108, 97, 104, 2, 111, 110, 3, 119, 12, 0, 115, 122, 1, 101, 109, 2, 101, 0, 115, 122, 1, 101, 109, 2, 195, 188, 107, 0, 115, 122, 1, 161, 195, 106, 0, 115, 122, 1, 161, 195, 108, 2, 97, 110, 97, 107, 0, 115, 122, 1, 161, 195, 108, 2, 111, 110, 0, 115, 122, 8, 161, 195, 108, 2, 195, 169, 107, 0, 122, 1, 97, 108, 108, 97, 104, 2, 97, 0, 122, 1, 97, 108, 108, 97, 104, 2, 105, 107, 0, 122, 1, 101, 105, 115, 0, 122, 1, 101, 109, 2, 101, 0, 122, 1, 101, 109, 2, 101, 116, 0, 122, 1, 101, 109, 2, 105, 107, 0, 122, 1, 101, 116, 0, 122, 1, 161, 195, 106, 2, 17, 65, 0, 122, 1, 161, 195, 106, 2, 111, 107, 0, 122, 1, 161, 195, 108, 2, 17, 65, 0, 122, 1, 169, 195, 104, 2, 101, 114, 0, 122, 1, 169, 195, 107, 2, 101, 114, 0, 122, 1, 182, 195, 2, 195, 182, 114, 0, 122, 1, 182, 195, 112, 2, 101, 110, 0, 122, 2, 32, 14, 128, 128, 131, 0, 122, 2, 111, 0, 122, 2, 195, 169, 0, 122, 2, 197, 145, 0, 122, 195, 179, 2, 32, 14, 128, 128, 132, 3, 119, 12, 115, 0, 7, 6, 116, 116, 0, 4, 1, 97, 108, 97, 2, 106, 195, 161, 114, 3, 47, 0, 1, 101, 107, 105, 114, 107, 2, 106, 195, 161, 116, 0, 1, 101, 107, 105, 114, 107, 2, 106, 195, 161, 116, 0, 1, 111, 108, 97, 104, 2, 115, 195, 161, 112, 97, 100, 0, 1, 182, 195, 108, 188, 195, 122, 115, 110, 110, 101, 98, 2, 106, 101, 108, 109, 101, 122, 0, 4, 3, 47, 12, 0, 1, 101, 122, 101, 121, 108, 101, 104, 2, 114, 197, 145, 108, 0, 1, 122, 115, 101, 114, 101, 107, 2, 197, 177, 122, 0, 1, 169, 195, 122, 115, 2, 114, 97, 110, 99, 115, 195, 173, 114, 0, 103, 121, 3, 47, 12, 79, 0, 114, 3, 47, 52, 0, 4, 115, 2, 195, 161, 3, 76, 12, 0, 115, 2, 195, 169, 0, 4, 106, 3, 80, 12, 0, 121, 0, 121, 106, 0, 115, 122, 1, 101, 109, 2, 101, 116, 3, 119, 12, 0, 7, 6, 116, 121, 0, 1, 110, 101, 122, 115, 100, 110, 105, 109, 3, 47, 37, 0, 2, 97, 114, 100, 3, 47, 57, 0, 7, 6, 195, 161, 0, 3, 114, 0, 105, 103, 1, 21, 2, 32, 14, 128, 192, 131, 3, 114, 37, 81, 0, 116, 195, 179, 108, 1, 21, 2, 32, 14, 128, 192, 132, 3, 114, 47, 115, 55, 0, 110, 97, 107, 1, 21, 2, 32, 14, 128, 192, 132, 3, 114, 50, 108, 49, 0, 114, 97, 1, 21, 2, 32, 14, 128, 192, 131, 3, 114, 52, 108, 0, 98, 97, 110, 1, 21, 2, 32, 14, 128, 192, 132, 3, 114, 71, 108, 50, 0, 7, 6, 195, 169, 0, 3, 113, 0, 105, 2, 195, 169, 3, 113, 12, 112, 0, 105, 103, 1, 21, 2, 32, 14, 128, 192, 131, 3, 113, 37, 81, 0, 116, 197, 145, 108, 1, 21, 2, 32, 14, 128, 192, 132, 3, 113, 47, 118, 55, 0, 110, 101, 107, 1, 21, 2, 32, 14, 128, 192, 132, 3, 113, 50, 109, 49, 0, 114, 101, 1, 21, 2, 32, 14, 128, 192, 131, 3, 113, 52, 109, 0, 98, 101, 110, 1, 21, 2, 32, 14, 128, 192, 132, 3, 113, 71, 109, 50, 0, 104, 115, 195, 169, 103, 3, 113, 91, 113, 81, 0, 104, 115, 195, 169, 103, 103, 3, 113, 91, 113, 81, 12, 0, 7, 6, 195, 171, 0, 3, 110, 0, 7, 6, 195, 173, 0, 4, 1, 116, 2, 122, 101, 110, 3, 37, 0, 1, 116, 2, 122, 101, 115, 0, 1, 116, 2, 122, 101, 116, 0, 1, 118, 2, 122, 101, 110, 0, 1, 118, 2, 122, 195, 169, 114, 101, 0, 1, 122, 115, 2, 118, 97, 116, 110, 0, 1, 122, 115, 2, 118, 97, 116, 195, 161, 115, 0, 1, 122, 115, 2, 118, 101, 0, 8, 116, 2, 122, 195, 188, 107, 0, 8, 118, 2, 122, 105, 0, 8, 122, 115, 2, 110, 195, 169, 115, 115, 122, 0, 8, 122, 115, 2, 110, 195, 169, 115, 122, 0, 8, 122, 115, 2, 118, 97, 116, 116, 97, 107, 0, 8, 122, 115, 2, 118, 97, 116, 116, 195, 161, 107, 107, 0, 8, 122, 115, 2, 118, 97, 116, 195, 179, 0, 8, 122, 115, 103, 101, 109, 2, 118, 97, 116, 116, 97, 0, 116, 115, 122, 1, 100, 97, 98, 97, 122, 115, 3, 37, 119, 12, 0, 4, 3, 112, 0, 1, 116, 2, 122, 101, 115, 122, 0, 1, 122, 115, 2, 118, 101, 108, 0, 1, 122, 115, 2, 118, 101, 109, 195, 169, 115, 122, 116, 0, 1, 122, 115, 115, 101, 114, 103, 97, 2, 118, 0, 8, 118, 2, 122, 105, 195, 179, 0, 116, 115, 3, 112, 76, 12, 0, 116, 115, 100, 3, 112, 76, 72, 0, 116, 115, 122, 1, 122, 115, 101, 118, 3, 112, 119, 12, 0, 7, 6, 195, 179, 0, 3, 115, 0, 7, 6, 195, 182, 0, 3, 110, 0, 7, 6, 195, 186, 0, 4, 1, 104, 2, 103, 111, 109, 3, 40, 0, 1, 104, 2, 115, 122, 97, 110, 0, 1, 104, 2, 115, 122, 97, 115, 0, 1, 104, 2, 115, 122, 97, 116, 0, 8, 104, 2, 103, 103, 121, 0, 8, 104, 2, 103, 111, 99, 115, 0, 8, 104, 2, 103, 121, 0, 4, 3, 116, 0, 1, 104, 2, 115, 122, 97, 110, 110, 121, 0, 7, 6, 195, 188, 0, 3, 111, 0, 116, 116, 2, 18, 66, 3, 111, 47, 0, 116, 116, 3, 111, 47, 12, 0, 116, 116, 114, 3, 111, 47, 52, 0, 116, 116, 98, 3, 111, 47, 71, 0, 116, 116, 121, 2, 18, 66, 3, 111, 80, 0, 116, 116, 121, 3, 111, 80, 12, 0, 116, 116, 121, 114, 3, 111, 80, 52, 0, 116, 116, 121, 98, 3, 111, 80, 71, 0, 7, 6, 197, 145, 0, 3, 118, 0, 7, 6, 197, 177, 0, 4, 1, 116, 2, 122, 105, 106, 195, 161, 116, 195, 169, 107, 3, 111, 0, 8, 116, 2, 110, 106, 195, 182, 110, 0, 8, 116, 2, 110, 195, 169, 115, 0, 3, 117, 0, 7, 6, 97, 0, 8, 2, 32, 3, 2, 108, 0, 108, 1, 45, 32, 48, 48, 15, 2, 32, 3, 88, 108, 55, 0, 3, 108, 0, 108, 1, 45, 32, 48, 48, 48, 2, 32, 3, 108, 55, 0, 104, 104, 111, 122, 3, 108, 107, 39, 88, 0, 7, 6, 98, 0, 4, 1, 45, 98, 3, 0, 1, 45, 98, 98, 3, 0, 4, 3, 71, 0, 98, 2, 18, 66, 0, 98, 2, 45, 18, 66, 0, 4, 2, 45, 98, 3, 71, 12, 0, 98, 0, 98, 2, 45, 98, 0, 105, 122, 2, 17, 65, 3, 71, 37, 88, 4, 0, 98, 114, 3, 71, 52, 0, 98, 106, 3, 71, 57, 0, 97, 110, 1, 21, 2, 32, 14, 128, 192, 131, 3, 71, 108, 50, 0, 97, 116, 116, 104, 105, 195, 161, 110, 121, 8, 3, 71, 108, 80, 12, 114, 67, 37, 0, 101, 110, 1, 21, 2, 32, 14, 128, 128, 131, 3, 71, 109, 50, 0, 105, 101, 100, 101, 114, 109, 101, 105, 101, 114, 5, 1, 3, 71, 112, 72, 109, 52, 65, 114, 57, 109, 52, 0, 7, 6, 99, 0, 4, 1, 45, 99, 3, 0, 4, 1, 45, 99, 99, 3, 0, 4, 99, 115, 1, 45, 115, 99, 3, 0, 4, 99, 115, 1, 45, 115, 99, 99, 3, 0, 4, 115, 1, 45, 99, 3, 0, 4, 115, 1, 45, 115, 99, 3, 0, 115, 1, 45, 115, 99, 99, 3, 0, 107, 5, 1, 8, 111, 116, 115, 2, 104, 111, 108, 109, 3, 49, 0, 4, 99, 115, 1, 45, 99, 99, 3, 76, 0, 99, 115, 2, 18, 66, 0, 99, 115, 2, 45, 18, 66, 0, 115, 0, 115, 1, 45, 99, 99, 0, 115, 1, 105, 118, 97, 107, 2, 122, 0, 115, 1, 105, 118, 97, 107, 2, 122, 195, 161, 116, 111, 110, 121, 0, 115, 1, 108, 117, 107, 2, 122, 195, 182, 114, 103, 0, 115, 1, 108, 182, 195, 109, 188, 195, 121, 103, 2, 122, 115, 0, 115, 1, 110, 105, 108, 105, 98, 2, 122, 195, 182, 114, 0, 115, 1, 110, 105, 108, 105, 107, 2, 122, 195, 182, 114, 0, 115, 1, 110, 161, 195, 116, 2, 105, 99, 115, 0, 115, 1, 110, 161, 195, 116, 161, 195, 115, 2, 97, 112, 0, 115, 1, 114, 169, 195, 2, 195, 173, 112, 116, 101, 0, 115, 1, 117, 112, 97, 112, 0, 115, 1, 161, 195, 116, 114, 97, 107, 2, 122, 195, 161, 112, 111, 0, 4, 99, 115, 3, 76, 12, 0, 99, 115, 2, 45, 99, 99, 115, 0, 99, 115, 2, 45, 99, 115, 0, 115, 1, 161, 195, 114, 97, 98, 2, 195, 161, 103, 116, 97, 0, 115, 2, 45, 99, 99, 115, 0, 115, 2, 45, 99, 115, 0, 99, 115, 114, 3, 76, 52, 0, 115, 122, 1, 161, 195, 112, 97, 108, 97, 107, 2, 101, 110, 3, 76, 88, 0, 4, 99, 115, 2, 45, 115, 122, 3, 76, 89, 0, 115, 2, 45, 115, 122, 0, 115, 122, 115, 3, 76, 90, 0, 4, 3, 119, 0, 1, 97, 108, 97, 109, 2, 115, 195, 161, 0, 1, 97, 108, 97, 109, 2, 115, 195, 188, 108, 0, 1, 97, 122, 97, 108, 0, 1, 101, 114, 101, 112, 2, 99, 115, 0, 1, 101, 114, 101, 112, 2, 115, 195, 188, 116, 0, 1, 108, 105, 102, 2, 99, 115, 105, 122, 0, 1, 108, 111, 112, 2, 115, 111, 0, 1, 108, 111, 121, 110, 2, 115, 101, 98, 0, 1, 110, 97, 104, 117, 115, 0, 1, 110, 101, 99, 105, 108, 2, 115, 195, 169, 114, 116, 195, 169, 115, 0, 1, 110, 101, 108, 105, 107, 2, 99, 115, 97, 116, 111, 114, 110, 0, 1, 110, 101, 108, 105, 107, 2, 115, 99, 104, 105, 108, 108, 0, 1, 110, 101, 108, 105, 107, 2, 115, 195, 161, 118, 0, 1, 110, 101, 121, 103, 101, 102, 0, 1, 110, 101, 121, 110, 173, 195, 2, 115, 195, 169, 103, 0, 1, 110, 105, 114, 101, 103, 0, 1, 110, 111, 98, 97, 114, 97, 103, 2, 115, 101, 114, 0, 1, 110, 111, 103, 114, 97, 121, 110, 2, 99, 115, 0, 1, 110, 111, 114, 97, 118, 100, 117, 2, 115, 101, 114, 0, 1, 110, 161, 195, 108, 2, 99, 115, 0, 1, 110, 161, 195, 116, 2, 99, 115, 0, 1, 110, 161, 195, 116, 2, 115, 0, 1, 110, 182, 195, 108, 188, 195, 107, 2, 115, 195, 169, 0, 1, 111, 98, 114, 161, 195, 2, 99, 115, 195, 186, 99, 115, 0, 1, 111, 98, 114, 161, 195, 2, 115, 117, 100, 0, 1, 111, 122, 115, 2, 115, 101, 103, 195, 169, 108, 121, 0, 1, 114, 97, 2, 99, 115, 111, 110, 0, 1, 114, 97, 100, 117, 107, 2, 115, 111, 114, 111, 122, 97, 116, 0, 1, 114, 97, 104, 2, 99, 115, 101, 108, 101, 107, 0, 1, 114, 97, 104, 2, 99, 115, 111, 112, 111, 114, 116, 0, 1, 114, 101, 110, 2, 115, 116, 195, 179, 108, 97, 0, 1, 114, 111, 112, 2, 115, 122, 0, 1, 114, 111, 112, 2, 115, 195, 169, 0, 1, 114, 169, 195, 2, 115, 111, 100, 114, 0, 1, 114, 169, 195, 98, 2, 99, 115, 117, 116, 0, 1, 114, 169, 195, 98, 2, 115, 195, 188, 118, 101, 103, 0, 1, 161, 195, 112, 2, 115, 195, 179, 0, 1, 169, 195, 116, 105, 110, 97, 122, 115, 2, 99, 115, 0, 1, 179, 195, 98, 114, 161, 195, 2, 99, 115, 195, 186, 99, 115, 0, 1, 179, 195, 104, 111, 98, 2, 115, 97, 112, 107, 0, 1, 179, 195, 104, 111, 98, 2, 115, 105, 112, 107, 0, 1, 179, 195, 108, 97, 116, 114, 97, 109, 0, 1, 179, 195, 114, 107, 111, 112, 2, 99, 115, 0, 8, 97, 105, 112, 2, 99, 115, 97, 114, 110, 111, 107, 0, 8, 97, 108, 97, 109, 2, 115, 105, 118, 195, 173, 116, 0, 8, 101, 103, 101, 106, 0, 8, 108, 105, 102, 2, 99, 115, 195, 173, 107, 0, 8, 108, 111, 112, 2, 99, 115, 97, 116, 0, 8, 110, 97, 98, 97, 108, 0, 8, 110, 101, 106, 169, 195, 107, 0, 8, 110, 101, 108, 105, 107, 2, 99, 115, 111, 109, 195, 179, 0, 8, 110, 101, 108, 105, 107, 2, 99, 115, 195, 182, 118, 0, 8, 110, 105, 114, 112, 2, 115, 195, 169, 103, 0, 8, 110, 111, 103, 114, 105, 118, 2, 115, 195, 161, 103, 0, 8, 110, 111, 106, 186, 195, 0, 8, 110, 169, 195, 109, 108, 101, 2, 115, 195, 169, 103, 0, 8, 114, 97, 2, 115, 101, 98, 0, 8, 114, 97, 2, 115, 195, 169, 114, 195, 188, 108, 0, 8, 114, 101, 110, 2, 115, 116, 195, 179, 108, 195, 161, 0, 8, 114, 169, 195, 2, 99, 115, 0, 8, 114, 169, 195, 2, 115, 97, 108, 97, 107, 0, 8, 114, 169, 195, 2, 115, 97, 115, 0, 8, 114, 169, 195, 2, 115, 101, 108, 121, 0, 8, 114, 169, 195, 2, 115, 105, 115, 97, 107, 0, 8, 114, 169, 195, 2, 115, 195, 173, 112, 0, 8, 117, 114, 117, 107, 0, 8, 161, 195, 107, 97, 2, 115, 195, 182, 118, 0, 8, 161, 195, 107, 161, 195, 2, 115, 195, 182, 118, 0, 8, 161, 195, 114, 2, 115, 195, 161, 103, 0, 8, 169, 195, 108, 106, 101, 102, 0, 8, 179, 195, 104, 111, 98, 2, 115, 122, 0, 8, 179, 195, 107, 2, 99, 115, 111, 109, 195, 179, 0, 8, 179, 195, 108, 97, 112, 2, 115, 195, 161, 103, 0, 99, 2, 18, 66, 0, 99, 2, 45, 18, 66, 0, 99, 2, 45, 99, 99, 115, 0, 99, 2, 45, 99, 115, 0, 99, 8, 105, 118, 2, 115, 111, 114, 0, 122, 1, 19, 0, 122, 8, 110, 105, 2, 195, 169, 100, 0, 4, 2, 45, 99, 3, 119, 12, 0, 99, 0, 99, 2, 45, 99, 0, 99, 114, 3, 119, 52, 0, 4, 2, 45, 99, 115, 3, 119, 76, 0, 99, 115, 1, 110, 101, 99, 105, 108, 0, 115, 122, 3, 119, 89, 0, 115, 8, 179, 195, 104, 111, 98, 3, 119, 91, 0, 115, 111, 114, 8, 114, 97, 104, 3, 119, 91, 39, 52, 0, 7, 6, 100, 0, 4, 1, 45, 100, 3, 0, 4, 1, 45, 100, 100, 3, 0, 1, 114, 111, 107, 101, 114, 2, 115, 101, 98, 101, 115, 115, 195, 169, 103, 3, 0, 116, 1, 122, 101, 107, 3, 47, 0, 4, 116, 3, 47, 12, 0, 116, 2, 115, 122, 0, 116, 116, 0, 116, 116, 1, 101, 108, 108, 188, 195, 102, 2, 195, 169, 0, 116, 115, 122, 195, 169, 3, 47, 12, 89, 113, 0, 110, 121, 1, 110, 105, 109, 3, 67, 0, 4, 3, 72, 0, 1, 97, 98, 97, 122, 115, 2, 106, 101, 103, 0, 1, 97, 98, 97, 122, 115, 2, 115, 116, 114, 97, 110, 100, 0, 1, 97, 98, 97, 122, 115, 2, 115, 122, 101, 108, 108, 101, 0, 1, 97, 98, 97, 122, 115, 2, 115, 122, 101, 110, 116, 0, 1, 97, 98, 97, 122, 115, 2, 115, 122, 101, 114, 101, 108, 0, 1, 97, 98, 97, 122, 115, 2, 115, 122, 111, 102, 116, 0, 1, 97, 98, 97, 122, 115, 2, 115, 122, 111, 109, 98, 97, 116, 0, 1, 97, 98, 97, 122, 115, 2, 115, 122, 195, 161, 106, 195, 186, 0, 1, 97, 98, 97, 122, 115, 2, 115, 122, 195, 161, 108, 108, 195, 161, 115, 0, 1, 97, 98, 97, 122, 115, 2, 115, 122, 195, 179, 108, 0, 1, 97, 104, 2, 106, 195, 161, 114, 97, 116, 0, 1, 97, 104, 2, 115, 101, 103, 195, 169, 100, 0, 1, 97, 104, 2, 115, 111, 114, 0, 1, 97, 104, 2, 115, 122, 101, 114, 116, 195, 161, 0, 1, 97, 104, 2, 115, 122, 105, 110, 0, 1, 97, 104, 145, 197, 102, 2, 115, 101, 103, 195, 169, 100, 0, 1, 97, 109, 114, 97, 104, 2, 115, 111, 114, 0, 1, 97, 109, 114, 97, 104, 2, 115, 122, 105, 110, 116, 0, 1, 97, 109, 114, 97, 104, 2, 115, 122, 195, 161, 122, 0, 1, 97, 112, 2, 115, 111, 114, 0, 1, 97, 112, 2, 115, 122, 101, 114, 197, 177, 0, 1, 97, 112, 2, 115, 122, 197, 145, 110, 121, 0, 1, 97, 118, 2, 115, 122, 101, 100, 101, 114, 0, 1, 97, 118, 2, 115, 122, 101, 103, 102, 0, 1, 97, 118, 2, 115, 122, 101, 114, 197, 177, 0, 1, 97, 118, 2, 115, 122, 105, 108, 118, 0, 1, 97, 118, 2, 115, 122, 116, 114, 195, 161, 106, 107, 0, 1, 97, 118, 2, 115, 122, 195, 179, 106, 0, 1, 97, 118, 2, 115, 122, 197, 145, 0, 1, 97, 118, 2, 115, 195, 161, 102, 114, 0, 1, 97, 122, 161, 195, 122, 115, 2, 115, 122, 101, 109, 108, 101, 0, 1, 97, 122, 161, 195, 122, 115, 2, 115, 122, 105, 110, 116, 0, 1, 97, 122, 161, 195, 122, 115, 2, 115, 122, 195, 161, 109, 0, 1, 101, 101, 119, 116, 2, 115, 97, 112, 107, 0, 1, 101, 101, 119, 116, 2, 115, 122, 195, 182, 118, 101, 116, 0, 1, 101, 114, 122, 101, 2, 115, 101, 103, 195, 169, 0, 1, 101, 114, 122, 101, 2, 115, 122, 101, 109, 0, 1, 101, 114, 122, 101, 2, 115, 122, 101, 114, 116, 101, 0, 1, 101, 114, 122, 101, 2, 115, 122, 105, 110, 0, 1, 101, 114, 122, 101, 2, 115, 122, 195, 161, 0, 1, 101, 114, 122, 101, 2, 122, 195, 161, 115, 122, 108, 0, 1, 101, 121, 103, 101, 110, 2, 115, 122, 195, 161, 122, 0, 1, 101, 121, 103, 101, 110, 2, 115, 122, 195, 169, 108, 0, 1, 101, 122, 105, 116, 2, 115, 122, 195, 161, 109, 0, 1, 101, 122, 105, 116, 2, 115, 122, 195, 161, 122, 0, 1, 103, 97, 114, 97, 109, 115, 2, 115, 122, 195, 173, 110, 0, 1, 105, 118, 182, 195, 114, 2, 115, 111, 114, 111, 122, 0, 1, 105, 118, 182, 195, 114, 2, 122, 195, 161, 114, 0, 1, 105, 118, 182, 195, 114, 2, 122, 195, 161, 114, 108, 97, 116, 0, 1, 106, 97, 102, 2, 116, 121, 195, 186, 107, 0, 1, 108, 111, 98, 111, 107, 2, 115, 122, 195, 182, 103, 0, 1, 108, 111, 104, 2, 115, 195, 188, 0, 1, 108, 182, 195, 102, 2, 115, 122, 101, 103, 195, 169, 108, 121, 0, 1, 108, 182, 195, 102, 2, 115, 122, 101, 114, 107, 101, 0, 1, 108, 182, 195, 102, 2, 115, 122, 101, 114, 122, 195, 169, 0, 1, 108, 182, 195, 102, 2, 115, 122, 101, 114, 197, 177, 0, 1, 108, 182, 195, 102, 2, 115, 122, 111, 114, 111, 115, 0, 1, 108, 182, 195, 102, 2, 115, 122, 195, 173, 110, 101, 107, 0, 1, 108, 182, 195, 102, 2, 115, 122, 195, 173, 110, 195, 169, 0, 1, 108, 182, 195, 102, 2, 115, 122, 195, 173, 110, 197, 177, 0, 1, 108, 182, 195, 102, 2, 115, 122, 195, 182, 107, 197, 145, 0, 1, 108, 182, 195, 102, 2, 115, 122, 195, 188, 114, 107, 0, 1, 108, 182, 195, 102, 2, 115, 195, 161, 110, 99, 0, 1, 108, 182, 195, 102, 2, 115, 195, 161, 118, 0, 1, 108, 182, 195, 122, 2, 115, 97, 112, 107, 0, 1, 108, 182, 195, 122, 2, 115, 122, 101, 109, 0, 1, 108, 182, 195, 122, 2, 115, 122, 195, 173, 110, 0, 1, 108, 182, 195, 122, 2, 115, 195, 161, 118, 0, 1, 110, 97, 108, 97, 107, 2, 106, 195, 161, 116, 195, 169, 107, 0, 1, 110, 97, 108, 97, 107, 2, 115, 122, 101, 114, 0, 1, 110, 97, 108, 97, 107, 2, 115, 122, 101, 114, 101, 112, 0, 1, 110, 97, 114, 116, 115, 2, 115, 122, 101, 122, 111, 110, 0, 1, 110, 101, 114, 2, 115, 122, 97, 0, 1, 110, 101, 114, 2, 115, 122, 101, 114, 101, 116, 197, 145, 0, 1, 110, 101, 114, 2, 122, 97, 118, 97, 114, 0, 1, 110, 101, 115, 99, 2, 115, 195, 169, 114, 116, 195, 169, 115, 0, 1, 110, 105, 109, 2, 106, 111, 98, 98, 97, 110, 0, 1, 111, 115, 114, 111, 98, 2, 115, 122, 0, 1, 111, 115, 161, 195, 109, 2, 115, 111, 114, 0, 1, 111, 115, 161, 195, 109, 2, 115, 122, 97, 107, 195, 161, 0, 1, 111, 115, 161, 195, 109, 2, 115, 122, 101, 114, 101, 112, 0, 1, 111, 115, 161, 195, 109, 2, 115, 122, 105, 110, 0, 1, 111, 115, 161, 195, 109, 2, 115, 122, 195, 188, 108, 195, 182, 116, 116, 0, 1, 114, 97, 100, 110, 97, 116, 115, 2, 106, 101, 103, 121, 0, 1, 114, 97, 107, 2, 115, 117, 0, 1, 114, 97, 107, 2, 115, 122, 101, 114, 197, 177, 0, 1, 114, 97, 107, 2, 115, 122, 195, 173, 106, 0, 1, 114, 111, 102, 2, 106, 195, 161, 110, 111, 115, 0, 1, 114, 111, 104, 2, 115, 122, 195, 169, 107, 0, 1, 114, 111, 104, 2, 115, 122, 195, 173, 0, 1, 114, 111, 106, 102, 2, 115, 122, 101, 114, 197, 177, 0, 1, 114, 111, 107, 101, 114, 2, 115, 101, 98, 101, 115, 115, 195, 169, 103, 0, 1, 114, 111, 107, 101, 114, 2, 115, 117, 103, 195, 161, 114, 0, 1, 114, 111, 107, 101, 114, 2, 115, 122, 101, 114, 107, 101, 122, 0, 1, 114, 111, 107, 101, 114, 2, 115, 122, 105, 110, 116, 0, 1, 114, 161, 195, 105, 108, 105, 109, 2, 115, 122, 111, 114, 0, 1, 114, 161, 195, 122, 97, 104, 2, 106, 195, 161, 116, 195, 169, 107, 0, 1, 114, 161, 195, 122, 110, 97, 109, 2, 115, 122, 111, 98, 0, 1, 114, 169, 195, 116, 2, 115, 122, 111, 107, 110, 121, 0, 1, 114, 169, 195, 116, 2, 115, 122, 195, 173, 106, 0, 1, 114, 169, 195, 116, 2, 115, 195, 169, 114, 195, 188, 108, 0, 1, 145, 197, 114, 101, 2, 115, 122, 101, 114, 197, 177, 0, 1, 161, 195, 108, 97, 115, 99, 2, 106, 111, 103, 0, 1, 161, 195, 108, 97, 115, 99, 2, 115, 101, 103, 195, 173, 116, 0, 1, 161, 195, 108, 97, 115, 99, 2, 115, 122, 101, 114, 101, 116, 197, 145, 0, 1, 161, 195, 108, 97, 115, 99, 2, 115, 122, 111, 99, 105, 111, 108, 0, 1, 161, 195, 110, 0, 1, 161, 195, 110, 2, 115, 117, 104, 111, 103, 0, 1, 161, 195, 110, 2, 115, 122, 101, 114, 100, 0, 1, 161, 195, 110, 2, 115, 122, 105, 108, 195, 161, 110, 0, 1, 161, 195, 110, 2, 115, 122, 195, 169, 107, 0, 1, 161, 195, 110, 2, 115, 122, 195, 182, 118, 101, 0, 1, 161, 195, 110, 2, 115, 122, 197, 145, 110, 121, 101, 0, 1, 161, 195, 110, 2, 115, 195, 173, 112, 0, 1, 161, 195, 110, 114, 101, 104, 2, 115, 122, 0, 1, 161, 195, 112, 114, 161, 195, 2, 115, 195, 161, 118, 0, 1, 161, 195, 112, 114, 161, 195, 2, 115, 195, 161, 118, 0, 1, 161, 195, 112, 114, 161, 195, 2, 122, 195, 161, 115, 122, 108, 195, 179, 0, 1, 161, 195, 118, 2, 115, 122, 195, 179, 122, 97, 0, 1, 161, 195, 122, 115, 105, 108, 97, 112, 2, 115, 111, 114, 0, 1, 169, 195, 98, 101, 2, 106, 101, 103, 0, 1, 169, 195, 108, 101, 115, 99, 2, 115, 111, 0, 1, 169, 195, 118, 2, 106, 101, 103, 121, 0, 1, 169, 195, 118, 110, 111, 104, 2, 115, 101, 114, 101, 103, 0, 1, 169, 195, 118, 121, 103, 188, 195, 2, 106, 101, 108, 0, 1, 169, 195, 122, 115, 101, 98, 2, 106, 97, 118, 195, 173, 116, 0, 1, 169, 195, 122, 115, 101, 98, 2, 106, 101, 108, 0, 1, 169, 195, 122, 115, 101, 98, 2, 115, 101, 98, 101, 115, 115, 195, 169, 103, 0, 1, 169, 195, 122, 115, 101, 98, 2, 115, 116, 195, 173, 108, 117, 115, 0, 1, 169, 195, 122, 115, 101, 98, 2, 115, 122, 105, 110, 0, 1, 169, 195, 122, 115, 101, 98, 2, 122, 97, 103, 121, 0, 1, 169, 195, 122, 115, 109, 111, 122, 115, 2, 115, 111, 114, 0, 1, 173, 195, 104, 2, 115, 122, 101, 114, 0, 1, 173, 195, 104, 2, 115, 122, 101, 114, 107, 101, 122, 101, 116, 0, 1, 179, 195, 104, 2, 115, 122, 197, 145, 114, 0, 1, 179, 195, 106, 2, 115, 122, 105, 118, 195, 161, 114, 0, 1, 179, 195, 107, 2, 106, 101, 108, 0, 1, 179, 195, 107, 2, 115, 111, 114, 0, 1, 179, 195, 107, 2, 115, 122, 101, 114, 107, 101, 0, 1, 179, 195, 107, 2, 115, 122, 195, 179, 0, 1, 179, 195, 109, 2, 106, 97, 118, 97, 115, 108, 97, 116, 0, 1, 179, 195, 109, 2, 115, 111, 114, 0, 1, 179, 195, 114, 112, 97, 2, 115, 122, 0, 1, 179, 195, 116, 97, 107, 2, 115, 117, 103, 195, 161, 114, 0, 1, 179, 195, 116, 117, 2, 106, 101, 108, 195, 182, 108, 0, 1, 179, 195, 116, 117, 2, 115, 122, 101, 114, 118, 0, 1, 179, 195, 122, 105, 112, 101, 2, 115, 122, 101, 114, 0, 1, 179, 195, 122, 105, 112, 101, 2, 115, 122, 101, 114, 101, 112, 0, 1, 182, 195, 107, 2, 115, 122, 105, 114, 195, 169, 110, 0, 1, 182, 195, 107, 2, 115, 122, 105, 116, 195, 161, 108, 195, 161, 115, 0, 1, 182, 195, 116, 182, 195, 2, 115, 122, 195, 188, 108, 195, 182, 0, 1, 186, 195, 108, 2, 122, 115, 195, 173, 114, 0, 8, 97, 104, 2, 106, 195, 161, 116, 195, 169, 107, 0, 8, 97, 104, 2, 115, 122, 101, 114, 0, 8, 97, 104, 2, 115, 122, 195, 161, 108, 108, 0, 8, 97, 109, 114, 97, 104, 2, 115, 122, 195, 188, 108, 0, 8, 97, 118, 2, 115, 122, 97, 103, 0, 8, 97, 118, 2, 115, 122, 97, 109, 0, 8, 97, 118, 2, 115, 122, 195, 161, 114, 110, 121, 0, 8, 103, 97, 114, 97, 109, 115, 2, 115, 122, 0, 8, 108, 111, 104, 2, 115, 97, 114, 108, 195, 179, 0, 8, 108, 182, 195, 102, 2, 115, 122, 101, 108, 108, 101, 0, 8, 108, 182, 195, 102, 2, 115, 122, 101, 114, 122, 0, 8, 108, 182, 195, 102, 2, 115, 122, 105, 103, 101, 116, 0, 8, 108, 182, 195, 102, 2, 115, 122, 117, 114, 111, 107, 0, 8, 108, 182, 195, 102, 2, 115, 122, 195, 173, 110, 0, 8, 108, 182, 195, 102, 2, 115, 122, 195, 188, 108, 116, 0, 8, 110, 101, 114, 2, 106, 101, 108, 0, 8, 110, 111, 103, 2, 115, 122, 101, 114, 0, 8, 114, 97, 107, 2, 115, 122, 195, 186, 114, 0, 8, 114, 111, 104, 2, 115, 122, 101, 107, 0, 8, 114, 161, 195, 105, 108, 105, 98, 2, 115, 122, 111, 0, 8, 114, 169, 195, 116, 2, 122, 115, 101, 98, 0, 8, 122, 188, 195, 107, 2, 115, 122, 101, 108, 108, 0, 8, 161, 195, 110, 2, 115, 195, 182, 118, 0, 8, 161, 195, 114, 2, 115, 195, 179, 122, 0, 8, 179, 195, 107, 2, 115, 122, 111, 98, 0, 8, 182, 195, 107, 2, 115, 122, 101, 114, 197, 177, 0, 8, 182, 195, 107, 2, 115, 122, 195, 188, 114, 107, 0, 8, 186, 195, 108, 2, 115, 122, 111, 107, 195, 161, 115, 0, 100, 1, 97, 104, 2, 32, 14, 128, 128, 130, 0, 100, 2, 18, 66, 0, 100, 2, 45, 18, 66, 0, 4, 2, 45, 100, 3, 72, 12, 0, 100, 0, 100, 1, 161, 195, 110, 0, 100, 2, 45, 100, 0, 111, 98, 101, 114, 109, 97, 110, 110, 3, 72, 39, 71, 12, 109, 52, 65, 108, 50, 0, 100, 114, 3, 72, 52, 0, 100, 98, 3, 72, 71, 0, 122, 1, 101, 101, 119, 116, 2, 97, 107, 3, 72, 88, 0, 4, 115, 122, 1, 97, 2, 195, 173, 3, 72, 89, 0, 115, 122, 1, 101, 101, 119, 116, 2, 111, 107, 0, 115, 122, 1, 110, 101, 114, 2, 101, 114, 105, 110, 116, 0, 115, 122, 1, 110, 101, 114, 116, 101, 110, 101, 109, 2, 101, 114, 197, 177, 0, 115, 122, 1, 169, 195, 0, 115, 122, 2, 97, 0, 115, 122, 2, 195, 161, 0, 115, 122, 8, 110, 101, 114, 2, 101, 114, 101, 116, 101, 116, 0, 195, 188, 104, 116, 197, 145, 108, 3, 72, 111, 47, 118, 55, 0, 195, 188, 104, 98, 101, 3, 72, 111, 71, 109, 0, 195, 188, 104, 118, 101, 108, 3, 72, 111, 84, 109, 55, 0, 105, 101, 115, 101, 108, 5, 1, 3, 72, 112, 88, 109, 55, 0, 4, 100, 122, 115, 2, 18, 66, 3, 75, 0, 100, 122, 115, 2, 45, 18, 66, 0, 4, 100, 122, 115, 1, 105, 114, 98, 2, 101, 108, 3, 75, 12, 0, 122, 115, 1, 111, 98, 109, 97, 107, 0, 4, 115, 1, 17, 67, 3, 76, 0, 115, 2, 17, 67, 0, 4, 115, 1, 17, 65, 2, 17, 65, 3, 76, 12, 0, 115, 1, 169, 195, 108, 101, 115, 99, 2, 195, 169, 103, 0, 116, 115, 0, 106, 1, 17, 67, 3, 79, 0, 4, 106, 3, 79, 12, 0, 106, 1, 17, 65, 2, 17, 65, 0, 4, 115, 122, 3, 119, 0, 115, 122, 1, 110, 101, 114, 2, 101, 114, 105, 110, 116, 101, 103, 114, 195, 161, 99, 105, 195, 179, 0, 115, 122, 2, 17, 67, 0, 115, 122, 8, 110, 111, 109, 2, 97, 0, 4, 115, 122, 1, 97, 2, 17, 65, 3, 119, 12, 0, 115, 122, 1, 101, 2, 17, 65, 0, 115, 122, 1, 111, 2, 17, 65, 0, 115, 122, 1, 179, 195, 0, 115, 122, 1, 182, 195, 116, 182, 195, 2, 195, 182, 114, 0, 115, 122, 2, 32, 14, 128, 128, 131, 0, 100, 122, 2, 18, 66, 3, 120, 0, 7, 6, 101, 0, 108, 1, 45, 32, 48, 48, 48, 2, 32, 3, 51, 109, 55, 0, 3, 109, 0, 108, 1, 45, 32, 48, 48, 48, 48, 48, 48, 2, 32, 3, 109, 55, 0, 103, 121, 101, 122, 115, 195, 169, 103, 8, 3, 109, 79, 12, 109, 91, 91, 113, 81, 0, 103, 121, 101, 122, 115, 195, 169, 103, 103, 8, 3, 109, 79, 12, 109, 91, 91, 113, 81, 12, 0, 104, 104, 101, 122, 8, 3, 109, 107, 109, 88, 0, 7, 6, 102, 0, 4, 3, 83, 0, 102, 1, 97, 2, 195, 169, 108, 0, 102, 1, 101, 2, 97, 106, 116, 0, 102, 1, 101, 2, 195, 169, 108, 0, 102, 2, 18, 66, 0, 102, 2, 45, 18, 66, 0, 102, 114, 3, 83, 52, 0, 102, 98, 3, 83, 71, 0, 195, 188, 104, 114, 101, 114, 5, 1, 3, 83, 117, 52, 109, 52, 0, 7, 6, 103, 0, 4, 1, 45, 103, 3, 0, 4, 121, 1, 45, 103, 3, 0, 4, 121, 1, 45, 103, 103, 3, 0, 121, 1, 45, 121, 103, 3, 0, 107, 3, 49, 12, 0, 104, 1, 169, 195, 2, 97, 106, 108, 97, 3, 49, 107, 0, 4, 103, 121, 1, 101, 109, 2, 18, 66, 3, 79, 0, 103, 121, 1, 101, 109, 2, 45, 18, 66, 0, 103, 121, 1, 101, 109, 2, 109, 97, 103, 0, 103, 121, 2, 18, 66, 0, 103, 121, 2, 45, 18, 66, 0, 4, 103, 121, 3, 79, 12, 0, 103, 121, 1, 101, 108, 101, 2, 195, 169, 0, 103, 121, 1, 101, 109, 2, 32, 14, 128, 128, 131, 0, 103, 121, 1, 101, 109, 2, 45, 103, 121, 0, 103, 121, 1, 101, 109, 2, 101, 108, 0, 103, 121, 1, 101, 109, 2, 101, 109, 0, 103, 121, 1, 101, 109, 2, 101, 115, 0, 103, 121, 1, 101, 109, 2, 101, 116, 0, 103, 121, 1, 101, 109, 2, 195, 173, 122, 0, 103, 121, 8, 101, 109, 2, 101, 110, 32, 0, 103, 121, 106, 1, 111, 114, 2, 195, 169, 107, 0, 121, 2, 45, 103, 121, 0, 4, 103, 121, 114, 3, 79, 52, 0, 103, 121, 114, 1, 101, 109, 0, 4, 103, 121, 98, 3, 79, 71, 0, 103, 121, 98, 1, 101, 109, 0, 4, 3, 81, 0, 1, 97, 116, 2, 103, 121, 197, 177, 108, 0, 1, 97, 121, 108, 179, 195, 104, 2, 103, 121, 117, 108, 0, 1, 97, 121, 110, 97, 2, 103, 121, 195, 161, 114, 0, 1, 97, 121, 110, 97, 2, 103, 121, 197, 145, 122, 0, 1, 97, 121, 110, 97, 2, 103, 121, 197, 177, 106, 116, 0, 1, 97, 121, 110, 97, 105, 100, 97, 104, 2, 103, 121, 195, 161, 114, 0, 1, 101, 100, 105, 2, 103, 121, 0, 1, 101, 108, 2, 103, 121, 0, 1, 101, 109, 2, 103, 121, 0, 1, 101, 114, 101, 115, 2, 103, 121, 197, 177, 106, 0, 1, 101, 114, 101, 121, 110, 2, 103, 121, 0, 1, 101, 114, 169, 195, 109, 2, 103, 121, 0, 1, 101, 114, 188, 195, 99, 114, 97, 2, 103, 121, 117, 108, 108, 97, 100, 195, 161, 115, 0, 1, 101, 116, 101, 98, 2, 103, 121, 195, 179, 103, 121, 195, 161, 115, 122, 0, 1, 101, 118, 182, 195, 122, 115, 2, 103, 121, 197, 177, 106, 116, 0, 1, 101, 118, 188, 195, 2, 103, 121, 0, 1, 101, 121, 108, 169, 195, 98, 2, 103, 121, 197, 177, 106, 116, 0, 1, 105, 103, 169, 195, 118, 2, 103, 121, 97, 0, 1, 105, 103, 169, 195, 118, 2, 103, 121, 195, 182, 0, 1, 110, 97, 104, 2, 103, 121, 97, 107, 111, 114, 0, 1, 110, 117, 108, 112, 117, 107, 2, 103, 121, 195, 161, 114, 0, 1, 111, 100, 161, 195, 98, 2, 103, 121, 0, 1, 111, 102, 2, 103, 121, 97, 108, 117, 0, 1, 111, 102, 2, 103, 121, 195, 182, 0, 1, 111, 102, 2, 103, 121, 197, 177, 114, 197, 177, 0, 1, 111, 106, 2, 103, 121, 97, 107, 111, 114, 0, 1, 111, 108, 161, 195, 122, 2, 103, 121, 0, 1, 111, 114, 100, 2, 103, 121, 97, 110, 195, 186, 0, 1, 111, 114, 112, 2, 103, 121, 97, 107, 0, 1, 161, 195, 108, 105, 118, 2, 103, 121, 0, 1, 161, 195, 108, 105, 118, 2, 103, 121, 197, 177, 108, 195, 182, 108, 0, 1, 161, 195, 114, 2, 103, 121, 197, 177, 106, 116, 0, 1, 161, 195, 114, 105, 118, 2, 103, 121, 0, 1, 161, 195, 115, 97, 107, 116, 105, 114, 2, 103, 121, 197, 177, 106, 116, 0, 1, 161, 195, 115, 100, 161, 195, 109, 105, 2, 103, 121, 197, 177, 106, 116, 0, 1, 161, 195, 115, 115, 111, 103, 161, 195, 108, 105, 118, 2, 103, 121, 0, 1, 161, 195, 122, 115, 114, 111, 2, 103, 121, 97, 114, 97, 112, 111, 100, 0, 1, 161, 195, 122, 115, 114, 111, 2, 103, 121, 197, 177, 108, 195, 169, 115, 0, 1, 169, 195, 100, 110, 101, 118, 2, 103, 121, 0, 1, 169, 195, 106, 177, 197, 109, 2, 103, 121, 195, 161, 114, 0, 1, 169, 195, 108, 2, 103, 121, 195, 182, 107, 0, 1, 169, 195, 115, 101, 108, 101, 2, 103, 121, 0, 1, 169, 195, 115, 105, 103, 169, 195, 114, 2, 103, 121, 197, 177, 106, 116, 0, 1, 169, 195, 115, 108, 101, 102, 2, 103, 121, 0, 1, 169, 195, 115, 115, 101, 108, 101, 116, 182, 195, 107, 2, 103, 121, 97, 107, 0, 1, 169, 195, 115, 116, 110, 101, 122, 115, 2, 103, 121, 0, 1, 182, 195, 100, 2, 103, 121, 97, 112, 106, 195, 186, 0, 1, 182, 195, 122, 115, 2, 103, 121, 195, 161, 114, 0, 8, 97, 121, 103, 97, 2, 103, 121, 0, 8, 110, 161, 195, 108, 2, 103, 121, 0, 8, 111, 108, 2, 103, 121, 197, 177, 106, 116, 0, 8, 169, 195, 106, 2, 103, 121, 195, 161, 114, 0, 8, 169, 195, 115, 101, 108, 101, 102, 2, 103, 121, 105, 108, 107, 111, 115, 0, 103, 1, 117, 103, 2, 111, 108, 0, 103, 2, 18, 66, 0, 103, 2, 45, 18, 66, 0, 4, 2, 45, 103, 3, 81, 12, 0, 103, 0, 103, 1, 101, 108, 2, 114, 111, 116, 101, 115, 122, 107, 0, 103, 114, 3, 81, 52, 0, 103, 98, 3, 81, 71, 0, 4, 2, 45, 103, 121, 3, 81, 79, 0, 103, 2, 45, 103, 121, 0, 111, 101, 116, 104, 5, 1, 8, 3, 81, 118, 47, 109, 0, 7, 6, 104, 0, 4, 1, 101, 115, 99, 2, 98, 195, 161, 110, 121, 97, 3, 0, 4, 8, 101, 115, 99, 2, 111, 114, 115, 122, 195, 161, 103, 3, 0, 4, 8, 101, 115, 99, 2, 115, 122, 108, 111, 118, 195, 161, 107, 3, 0, 4, 8, 117, 106, 2, 107, 111, 108, 98, 3, 0, 4, 8, 117, 106, 2, 115, 97, 106, 116, 3, 0, 4, 8, 117, 106, 2, 115, 122, 195, 161, 114, 110, 121, 195, 169, 107, 3, 0, 8, 117, 106, 2, 116, 101, 110, 121, 195, 169, 115, 122, 3, 0, 4, 3, 107, 0, 104, 1, 101, 100, 110, 105, 109, 2, 101, 122, 0, 104, 2, 45, 18, 66, 0, 101, 114, 116, 122, 3, 107, 109, 52, 119, 0, 7, 6, 105, 0, 4, 3, 37, 0, 1, 21, 2, 32, 14, 128, 128, 129, 0, 103, 1, 21, 2, 32, 14, 128, 128, 130, 3, 37, 81, 0, 104, 111, 122, 1, 21, 2, 32, 14, 128, 192, 132, 3, 37, 107, 39, 88, 0, 7, 6, 106, 0, 4, 3, 57, 0, 106, 2, 18, 66, 0, 106, 2, 45, 18, 66, 0, 106, 114, 3, 57, 52, 0, 106, 98, 3, 57, 71, 0, 97, 118, 195, 173, 116, 115, 8, 3, 57, 108, 84, 112, 76, 12, 0, 97, 118, 195, 173, 116, 115, 100, 8, 3, 57, 108, 84, 112, 76, 72, 0, 195, 169, 105, 103, 1, 21, 2, 32, 14, 128, 128, 132, 3, 57, 113, 37, 81, 0, 195, 169, 116, 197, 145, 108, 1, 21, 2, 32, 14, 128, 128, 133, 3, 57, 113, 47, 118, 55, 0, 195, 169, 110, 101, 107, 1, 21, 2, 32, 14, 128, 128, 133, 3, 57, 113, 50, 109, 49, 0, 195, 169, 114, 101, 1, 21, 2, 32, 14, 128, 128, 132, 3, 57, 113, 52, 109, 0, 195, 169, 118, 101, 108, 1, 21, 2, 32, 14, 128, 128, 133, 3, 57, 113, 84, 109, 55, 0, 195, 161, 105, 103, 1, 21, 2, 32, 14, 128, 192, 132, 3, 57, 114, 37, 81, 0, 195, 161, 116, 195, 179, 108, 1, 21, 2, 32, 14, 128, 192, 133, 3, 57, 114, 47, 115, 55, 0, 195, 161, 110, 97, 107, 1, 21, 2, 32, 14, 128, 192, 133, 3, 57, 114, 50, 108, 49, 0, 195, 161, 114, 97, 1, 21, 2, 32, 14, 128, 192, 132, 3, 57, 114, 52, 108, 0, 195, 161, 98, 97, 110, 1, 21, 2, 32, 14, 128, 192, 133, 3, 57, 114, 71, 108, 50, 0, 195, 161, 118, 97, 108, 1, 21, 2, 32, 14, 128, 192, 133, 3, 57, 114, 84, 108, 55, 0, 7, 6, 107, 0, 4, 1, 45, 107, 3, 0, 1, 45, 107, 107, 3, 0, 4, 3, 49, 0, 107, 2, 18, 66, 0, 107, 2, 45, 18, 66, 0, 195, 182, 122, 116, 195, 161, 114, 115, 97, 115, 195, 161, 103, 8, 3, 49, 6, 110, 89, 47, 114, 52, 91, 108, 91, 114, 81, 0, 195, 182, 122, 116, 195, 161, 114, 115, 97, 115, 195, 161, 103, 103, 8, 3, 49, 6, 110, 89, 47, 114, 52, 91, 108, 91, 114, 81, 12, 0, 4, 2, 45, 107, 3, 49, 12, 0, 107, 0, 107, 2, 17, 67, 0, 107, 2, 45, 107, 0, 107, 8, 169, 195, 116, 161, 195, 106, 2, 108, 105, 101, 110, 115, 0, 111, 115, 115, 117, 116, 104, 3, 49, 39, 91, 116, 47, 0, 111, 115, 115, 117, 116, 104, 116, 3, 49, 39, 91, 116, 47, 12, 0, 111, 115, 115, 117, 116, 104, 106, 3, 49, 39, 91, 116, 80, 12, 0, 107, 114, 3, 49, 52, 0, 107, 106, 3, 49, 57, 0, 107, 98, 3, 49, 71, 0, 195, 182, 122, 8, 3, 49, 110, 88, 0, 195, 182, 122, 116, 8, 3, 49, 110, 89, 47, 0, 195, 182, 122, 112, 111, 110, 116, 3, 49, 110, 89, 48, 39, 50, 47, 0, 195, 182, 122, 112, 111, 110, 116, 116, 3, 49, 110, 89, 48, 39, 50, 47, 12, 0, 195, 182, 122, 112, 111, 110, 116, 106, 3, 49, 110, 89, 48, 39, 50, 80, 0, 195, 182, 122, 115, 195, 169, 103, 3, 49, 110, 91, 91, 113, 81, 0, 195, 169, 115, 122, 115, 195, 169, 103, 3, 49, 113, 91, 91, 113, 81, 0, 195, 169, 115, 122, 115, 195, 169, 103, 103, 3, 49, 113, 91, 91, 113, 81, 12, 0, 7, 6, 108, 0, 4, 3, 55, 0, 1, 101, 2, 106, 117, 115, 0, 1, 101, 2, 106, 117, 116, 0, 1, 101, 2, 106, 195, 161, 116, 115, 122, 0, 1, 101, 102, 2, 106, 97, 118, 195, 173, 116, 0, 1, 101, 102, 2, 106, 101, 103, 121, 0, 1, 101, 102, 2, 106, 101, 108, 101, 110, 0, 1, 101, 102, 2, 106, 111, 103, 111, 115, 195, 173, 116, 0, 1, 101, 102, 2, 106, 117, 0, 1, 101, 102, 2, 106, 195, 161, 114, 0, 1, 101, 102, 2, 106, 195, 182, 0, 1, 106, 161, 195, 102, 0, 1, 169, 195, 122, 115, 2, 106, 101, 103, 121, 0, 1, 169, 195, 122, 115, 2, 106, 195, 161, 114, 0, 1, 188, 195, 116, 122, 115, 101, 114, 101, 107, 2, 106, 0, 8, 169, 195, 102, 2, 106, 111, 98, 98, 0, 108, 1, 101, 2, 105, 112, 115, 122, 0, 108, 1, 101, 116, 97, 103, 97, 98, 2, 105, 122, 0, 108, 1, 101, 116, 110, 105, 2, 105, 103, 101, 0, 108, 1, 105, 109, 2, 105, 0, 108, 2, 18, 66, 0, 108, 2, 45, 18, 66, 0, 4, 1, 182, 195, 107, 182, 195, 2, 106, 111, 103, 3, 55, 12, 0, 1, 186, 195, 116, 2, 106, 0, 4, 121, 1, 17, 67, 2, 32, 3, 55, 37, 0, 121, 8, 104, 116, 169, 195, 107, 0, 108, 114, 3, 55, 52, 0, 4, 108, 121, 1, 101, 117, 109, 97, 122, 115, 3, 55, 55, 37, 0, 121, 1, 101, 117, 109, 97, 122, 115, 0, 4, 106, 1, 101, 2, 195, 161, 114, 3, 55, 57, 0, 106, 8, 97, 116, 2, 195, 161, 110, 0, 106, 8, 101, 2, 195, 182, 0, 108, 98, 3, 55, 71, 0, 4, 108, 1, 161, 195, 2, 106, 3, 57, 0, 108, 121, 2, 45, 18, 66, 0, 121, 0, 4, 1, 97, 108, 106, 161, 195, 102, 2, 106, 3, 57, 57, 0, 1, 169, 195, 99, 2, 106, 195, 161, 0, 106, 1, 101, 107, 0, 106, 1, 101, 114, 169, 195, 98, 0, 106, 1, 169, 195, 122, 115, 101, 98, 0, 108, 121, 0, 4, 106, 1, 111, 100, 110, 111, 103, 3, 57, 57, 57, 0, 106, 1, 161, 195, 110, 106, 97, 115, 0, 108, 106, 0, 4, 106, 3, 61, 57, 0, 106, 1, 17, 65, 2, 17, 65, 0, 7, 6, 109, 0, 4, 3, 65, 0, 109, 1, 111, 107, 2, 117, 110, 105, 0, 109, 2, 18, 66, 0, 109, 2, 45, 18, 66, 0, 7, 6, 110, 0, 4, 3, 50, 0, 1, 97, 108, 116, 97, 103, 110, 105, 2, 106, 111, 103, 0, 1, 101, 98, 121, 108, 101, 104, 2, 106, 195, 161, 114, 0, 1, 101, 98, 122, 182, 195, 107, 2, 106, 195, 161, 114, 0, 1, 101, 98, 145, 197, 102, 2, 106, 195, 161, 114, 0, 1, 101, 108, 108, 101, 2, 106, 97, 118, 97, 108, 108, 116, 0, 1, 101, 108, 108, 101, 2, 106, 97, 118, 97, 115, 108, 97, 116, 0, 1, 101, 108, 108, 101, 2, 106, 101, 103, 121, 0, 1, 101, 108, 108, 101, 2, 106, 195, 161, 116, 195, 169, 107, 0, 1, 101, 108, 108, 111, 112, 2, 106, 101, 108, 101, 110, 0, 1, 101, 108, 169, 195, 2, 106, 195, 161, 114, 0, 1, 101, 118, 116, 182, 195, 2, 121, 97, 114, 100, 0, 1, 101, 118, 121, 103, 101, 110, 2, 121, 97, 114, 100, 0, 1, 101, 121, 103, 101, 2, 106, 111, 103, 195, 186, 0, 1, 101, 121, 103, 110, 105, 0, 1, 105, 98, 97, 107, 2, 110, 121, 195, 173, 108, 0, 1, 111, 100, 106, 97, 108, 117, 116, 2, 106, 111, 103, 0, 1, 111, 102, 111, 114, 107, 105, 109, 2, 110, 121, 195, 173, 108, 195, 161, 115, 0, 1, 111, 114, 101, 112, 2, 106, 101, 103, 121, 0, 1, 111, 116, 101, 98, 2, 106, 195, 161, 114, 100, 97, 0, 1, 111, 121, 103, 97, 118, 2, 106, 111, 103, 0, 1, 111, 121, 103, 97, 118, 2, 110, 121, 105, 108, 97, 116, 107, 111, 122, 97, 116, 0, 1, 145, 197, 115, 169, 195, 107, 2, 106, 195, 182, 118, 197, 145, 0, 1, 161, 195, 101, 99, 179, 195, 2, 106, 195, 161, 114, 0, 1, 161, 195, 103, 97, 109, 2, 106, 101, 108, 108, 101, 103, 0, 1, 161, 195, 103, 97, 109, 2, 106, 111, 103, 0, 1, 161, 195, 103, 97, 109, 2, 110, 121, 101, 108, 0, 1, 161, 195, 108, 122, 115, 111, 114, 111, 2, 110, 121, 111, 109, 0, 1, 161, 195, 114, 103, 105, 108, 105, 102, 2, 110, 121, 101, 108, 0, 1, 161, 195, 116, 117, 2, 110, 121, 111, 109, 0, 1, 173, 195, 122, 115, 2, 106, 101, 108, 122, 195, 169, 115, 0, 1, 173, 195, 122, 115, 2, 106, 195, 161, 116, 0, 1, 173, 195, 122, 115, 2, 106, 195, 179, 122, 97, 110, 0, 1, 173, 195, 122, 115, 2, 110, 121, 111, 109, 0, 1, 177, 197, 98, 2, 106, 101, 108, 0, 1, 182, 195, 2, 106, 101, 108, 195, 182, 108, 0, 1, 182, 195, 2, 106, 195, 161, 114, 195, 179, 0, 1, 182, 195, 115, 99, 108, 182, 195, 107, 2, 106, 101, 103, 121, 122, 0, 2, 103, 0, 2, 107, 0, 8, 101, 108, 108, 101, 2, 106, 97, 118, 0, 8, 101, 108, 116, 101, 116, 101, 104, 100, 100, 101, 102, 2, 106, 101, 108, 108, 101, 0, 8, 105, 122, 115, 2, 106, 195, 161, 116, 115, 122, 0, 8, 177, 197, 98, 2, 110, 121, 111, 109, 0, 8, 182, 195, 2, 110, 121, 111, 109, 0, 110, 1, 111, 107, 2, 101, 107, 116, 111, 114, 0, 110, 2, 18, 66, 0, 110, 2, 45, 18, 66, 0, 110, 114, 3, 50, 52, 0, 106, 1, 105, 122, 110, 101, 98, 3, 50, 57, 0, 110, 121, 1, 161, 195, 103, 97, 109, 2, 117, 103, 100, 195, 173, 106, 3, 50, 67, 0, 110, 98, 3, 50, 71, 0, 121, 108, 111, 110, 5, 1, 8, 3, 50, 109, 57, 55, 39, 50, 0, 101, 109, 8, 2, 45, 3, 50, 109, 65, 0, 108, 1, 161, 195, 106, 97, 3, 55, 12, 0, 108, 106, 1, 161, 195, 106, 97, 3, 57, 12, 0, 2, 112, 3, 65, 0, 4, 106, 1, 101, 104, 105, 112, 2, 32, 14, 128, 128, 130, 3, 67, 0, 106, 1, 105, 2, 101, 107, 99, 105, 195, 179, 0, 110, 121, 1, 101, 109, 2, 111, 114, 115, 122, 195, 161, 103, 0, 110, 121, 1, 105, 2, 101, 107, 99, 105, 195, 179, 0, 110, 121, 2, 18, 66, 0, 110, 121, 2, 45, 18, 66, 0, 110, 121, 2, 99, 115, 0, 110, 121, 8, 101, 109, 2, 97, 115, 115, 122, 0, 121, 0, 121, 1, 101, 115, 114, 101, 118, 2, 106, 111, 103, 0, 121, 1, 101, 115, 114, 101, 118, 2, 106, 195, 161, 116, 195, 169, 107, 0, 121, 1, 145, 197, 122, 101, 109, 2, 106, 0, 121, 1, 161, 195, 105, 104, 2, 106, 0, 121, 1, 161, 195, 109, 111, 108, 108, 161, 195, 2, 106, 101, 108, 0, 121, 1, 161, 195, 109, 114, 111, 107, 2, 106, 97, 118, 97, 115, 108, 97, 116, 0, 121, 1, 161, 195, 109, 114, 111, 107, 2, 106, 101, 108, 101, 110, 116, 195, 169, 115, 0, 121, 1, 161, 195, 109, 116, 111, 107, 108, 97, 2, 106, 0, 121, 1, 161, 195, 114, 105, 2, 106, 101, 108, 0, 121, 1, 161, 195, 114, 116, 111, 98, 2, 106, 195, 161, 116, 195, 169, 107, 0, 121, 1, 161, 195, 118, 114, 161, 195, 118, 105, 122, 115, 2, 106, 195, 161, 116, 115, 122, 0, 121, 1, 169, 195, 100, 105, 2, 106, 101, 108, 0, 121, 1, 169, 195, 102, 2, 106, 101, 108, 0, 121, 1, 169, 195, 109, 100, 101, 114, 101, 2, 106, 0, 121, 1, 169, 195, 109, 101, 114, 101, 121, 110, 2, 106, 195, 161, 116, 195, 169, 107, 0, 121, 1, 169, 195, 109, 101, 115, 101, 2, 106, 101, 108, 0, 121, 1, 169, 195, 109, 116, 173, 195, 115, 101, 106, 108, 101, 116, 2, 106, 97, 118, 117, 0, 121, 1, 169, 195, 118, 114, 182, 195, 116, 2, 106, 97, 118, 97, 0, 121, 8, 101, 109, 2, 97, 115, 115, 122, 0, 110, 121, 114, 3, 67, 52, 0, 4, 106, 3, 67, 67, 0, 110, 121, 0, 121, 106, 0, 110, 121, 98, 3, 67, 71, 0, 118, 100, 97, 8, 2, 45, 3, 109, 50, 84, 113, 72, 113, 114, 0, 7, 6, 111, 0, 3, 39, 0, 7, 6, 112, 0, 4, 1, 45, 112, 3, 0, 1, 45, 112, 112, 3, 0, 4, 3, 48, 0, 112, 2, 18, 66, 0, 112, 2, 45, 18, 66, 0, 2, 118, 3, 48, 10, 0, 4, 2, 45, 112, 3, 48, 12, 0, 112, 0, 112, 2, 17, 67, 0, 111, 116, 115, 100, 97, 109, 5, 1, 8, 3, 48, 39, 119, 72, 114, 65, 0, 112, 114, 3, 48, 52, 0, 112, 98, 3, 48, 71, 0, 7, 6, 113, 0, 4, 3, 49, 84, 0, 117, 0, 7, 6, 114, 0, 4, 2, 99, 99, 3, 51, 0, 2, 114, 0, 101, 1, 21, 2, 32, 14, 128, 128, 130, 3, 51, 109, 0, 4, 3, 52, 0, 1, 114, 0, 114, 1, 97, 2, 111, 103, 195, 161, 110, 115, 0, 114, 1, 101, 116, 2, 105, 101, 114, 0, 114, 1, 101, 116, 2, 111, 114, 105, 0, 114, 1, 105, 2, 105, 116, 195, 161, 0, 114, 1, 111, 107, 2, 101, 112, 101, 116, 195, 161, 0, 114, 1, 117, 107, 110, 111, 107, 2, 101, 110, 0, 114, 2, 18, 66, 0, 114, 2, 45, 18, 66, 0, 114, 8, 97, 2, 111, 103, 97, 110, 99, 105, 0, 109, 3, 52, 10, 65, 0, 4, 105, 99, 104, 97, 5, 1, 8, 2, 114, 100, 3, 52, 37, 99, 114, 0, 105, 99, 104, 195, 161, 8, 2, 114, 100, 0, 114, 114, 3, 52, 52, 0, 114, 98, 3, 52, 71, 0, 97, 1, 21, 2, 32, 14, 128, 128, 130, 3, 52, 108, 0, 7, 6, 115, 0, 122, 1, 45, 115, 3, 0, 5, 1, 1, 108, 101, 104, 2, 105, 110, 107, 105, 3, 88, 0, 4, 1, 108, 101, 103, 110, 101, 3, 89, 0, 5, 1, 1, 117, 105, 98, 117, 110, 97, 100, 0, 5, 1, 1, 117, 116, 110, 101, 118, 117, 106, 0, 122, 1, 45, 115, 110, 100, 0, 2, 45, 115, 122, 3, 89, 12, 0, 4, 108, 111, 5, 1, 8, 111, 3, 89, 55, 115, 0, 108, 195, 179, 5, 1, 8, 111, 0, 4, 101, 109, 109, 101, 108, 119, 101, 105, 115, 8, 3, 89, 109, 65, 65, 109, 55, 84, 109, 57, 89, 0, 101, 109, 109, 101, 108, 119, 101, 105, 115, 115, 8, 0, 101, 109, 109, 101, 108, 119, 101, 105, 195, 159, 8, 0, 97, 97, 114, 5, 1, 8, 3, 89, 114, 52, 0, 4, 3, 91, 0, 1, 97, 107, 114, 97, 102, 2, 115, 122, 197, 145, 114, 0, 1, 97, 118, 2, 115, 0, 1, 100, 108, 182, 195, 102, 2, 195, 161, 110, 99, 0, 1, 101, 110, 103, 161, 195, 109, 0, 1, 101, 121, 110, 110, 101, 122, 115, 2, 122, 115, 195, 161, 0, 1, 101, 122, 110, 169, 195, 112, 0, 1, 105, 107, 2, 115, 122, 101, 110, 116, 0, 1, 105, 107, 2, 115, 122, 105, 103, 101, 116, 0, 1, 105, 107, 2, 115, 122, 197, 145, 108, 197, 145, 0, 1, 105, 107, 2, 122, 115, 105, 100, 195, 161, 0, 1, 105, 107, 2, 122, 115, 105, 100, 195, 179, 0, 1, 105, 120, 97, 108, 97, 103, 0, 1, 111, 103, 111, 108, 97, 121, 103, 2, 122, 195, 161, 115, 122, 108, 195, 179, 0, 1, 111, 107, 111, 116, 2, 122, 195, 161, 115, 122, 108, 0, 1, 111, 108, 169, 195, 99, 110, 161, 195, 112, 0, 1, 111, 114, 161, 195, 118, 2, 122, 97, 106, 0, 1, 111, 114, 161, 195, 118, 2, 122, 115, 0, 1, 111, 116, 161, 195, 110, 161, 195, 114, 103, 0, 1, 111, 121, 110, 111, 103, 97, 114, 100, 0, 1, 117, 100, 108, 111, 107, 0, 1, 117, 103, 179, 195, 103, 97, 100, 101, 112, 2, 115, 122, 116, 114, 195, 161, 106, 107, 0, 1, 117, 109, 116, 105, 114, 2, 122, 97, 106, 0, 1, 117, 109, 116, 105, 114, 2, 122, 97, 118, 97, 114, 0, 1, 117, 112, 173, 195, 116, 2, 122, 117, 98, 0, 1, 145, 197, 121, 110, 114, 101, 145, 197, 116, 106, 101, 0, 1, 161, 195, 100, 97, 104, 2, 115, 122, 97, 103, 0, 1, 161, 195, 102, 2, 115, 122, 195, 161, 114, 195, 186, 0, 1, 161, 195, 103, 122, 111, 109, 2, 122, 97, 118, 97, 0, 1, 161, 195, 105, 114, 179, 195, 0, 1, 161, 195, 106, 111, 116, 0, 1, 161, 195, 107, 115, 117, 112, 0, 1, 161, 195, 108, 100, 97, 112, 0, 1, 161, 195, 108, 108, 97, 104, 2, 122, 97, 118, 97, 114, 0, 1, 161, 195, 110, 97, 98, 98, 111, 114, 0, 1, 161, 195, 110, 97, 98, 98, 111, 114, 2, 122, 97, 106, 0, 1, 161, 195, 114, 114, 111, 102, 145, 197, 114, 101, 2, 122, 97, 98, 195, 161, 108, 0, 1, 161, 195, 116, 105, 116, 110, 101, 100, 105, 2, 122, 97, 118, 97, 114, 0, 1, 161, 195, 116, 114, 97, 116, 97, 103, 97, 109, 2, 122, 97, 118, 97, 114, 0, 1, 161, 195, 116, 161, 195, 108, 2, 122, 97, 118, 97, 114, 0, 1, 161, 195, 118, 108, 97, 2, 122, 97, 118, 97, 0, 1, 161, 195, 121, 108, 107, 161, 195, 102, 2, 122, 101, 110, 0, 1, 161, 195, 122, 97, 109, 108, 97, 107, 108, 97, 2, 115, 122, 101, 114, 118, 101, 114, 0, 1, 169, 195, 100, 101, 107, 108, 101, 115, 105, 118, 2, 122, 97, 118, 97, 0, 1, 169, 195, 100, 182, 195, 107, 177, 197, 109, 2, 122, 97, 118, 97, 0, 1, 169, 195, 103, 101, 107, 101, 114, 98, 0, 1, 169, 195, 108, 101, 109, 114, 101, 116, 0, 1, 169, 195, 112, 169, 195, 108, 0, 1, 169, 195, 116, 188, 195, 2, 122, 195, 161, 112, 0, 1, 169, 195, 122, 101, 100, 101, 102, 0, 1, 182, 195, 114, 182, 195, 107, 2, 115, 122, 101, 103, 0, 1, 186, 195, 104, 2, 115, 122, 97, 103, 0, 8, 101, 118, 177, 197, 109, 145, 197, 107, 2, 115, 122, 0, 8, 105, 107, 2, 122, 111, 109, 98, 111, 114, 0, 8, 105, 108, 105, 112, 0, 8, 111, 108, 97, 116, 122, 115, 97, 0, 8, 111, 114, 105, 112, 0, 8, 117, 103, 114, 161, 195, 0, 8, 161, 195, 100, 108, 161, 195, 0, 8, 161, 195, 107, 110, 117, 109, 0, 8, 161, 195, 108, 173, 195, 121, 110, 0, 8, 169, 195, 108, 182, 195, 107, 114, 182, 195, 112, 2, 115, 122, 0, 8, 169, 195, 114, 145, 197, 108, 2, 115, 122, 0, 8, 169, 195, 122, 112, 169, 195, 107, 0, 8, 169, 195, 122, 115, 116, 101, 116, 0, 8, 179, 195, 118, 186, 195, 102, 2, 122, 101, 110, 101, 0, 8, 182, 195, 114, 182, 195, 107, 2, 115, 122, 97, 107, 195, 161, 108, 0, 8, 182, 195, 114, 182, 195, 118, 0, 104, 5, 1, 8, 97, 119, 2, 105, 110, 103, 0, 4, 115, 122, 8, 161, 195, 110, 114, 97, 98, 2, 195, 188, 114, 107, 101, 3, 91, 89, 0, 115, 122, 8, 161, 195, 118, 108, 97, 2, 195, 188, 107, 115, 195, 169, 0, 1, 105, 107, 2, 101, 98, 98, 3, 91, 91, 0, 7, 6, 116, 0, 4, 1, 45, 116, 3, 0, 4, 1, 45, 116, 116, 3, 0, 4, 121, 1, 45, 116, 3, 0, 4, 121, 1, 45, 116, 116, 3, 0, 121, 1, 45, 121, 116, 3, 0, 4, 3, 47, 0, 1, 45, 2, 32, 0, 1, 97, 99, 117, 116, 2, 115, 122, 195, 169, 112, 0, 1, 97, 104, 2, 99, 101, 108, 108, 0, 1, 97, 108, 100, 97, 112, 2, 115, 122, 197, 145, 110, 121, 0, 1, 97, 108, 108, 161, 195, 2, 115, 101, 98, 195, 169, 115, 122, 0, 1, 97, 108, 108, 161, 195, 2, 115, 122, 197, 145, 114, 0, 1, 97, 108, 111, 121, 116, 97, 112, 2, 115, 101, 108, 121, 0, 1, 97, 112, 97, 115, 99, 2, 115, 122, 111, 108, 103, 0, 1, 97, 114, 161, 195, 106, 2, 115, 122, 111, 108, 103, 195, 161, 108, 0, 1, 97, 118, 105, 100, 2, 99, 105, 107, 107, 0, 1, 97, 118, 105, 100, 2, 115, 122, 195, 169, 112, 0, 1, 97, 122, 161, 195, 108, 98, 161, 195, 116, 2, 99, 101, 108, 108, 0, 1, 97, 122, 179, 195, 108, 161, 195, 104, 2, 115, 101, 109, 108, 101, 103, 101, 115, 0, 1, 101, 108, 101, 115, 99, 108, 182, 195, 98, 2, 115, 97, 118, 97, 0, 1, 101, 108, 103, 182, 195, 122, 115, 2, 115, 122, 111, 98, 0, 1, 101, 108, 121, 103, 188, 195, 2, 115, 122, 111, 98, 0, 1, 101, 108, 122, 188, 195, 2, 115, 122, 111, 98, 0, 1, 101, 108, 169, 195, 2, 115, 111, 114, 118, 97, 115, 122, 0, 1, 101, 108, 169, 195, 2, 115, 122, 111, 109, 106, 0, 1, 101, 108, 188, 195, 114, 101, 116, 2, 99, 195, 169, 108, 0, 1, 101, 109, 114, 101, 112, 2, 115, 122, 101, 114, 197, 177, 0, 1, 101, 110, 2, 99, 0, 1, 101, 116, 114, 169, 195, 115, 173, 195, 107, 2, 115, 122, 195, 161, 122, 97, 100, 0, 1, 101, 116, 182, 195, 107, 2, 115, 122, 195, 161, 109, 0, 1, 101, 118, 182, 195, 122, 115, 2, 115, 195, 161, 118, 0, 1, 101, 122, 101, 106, 101, 102, 2, 99, 195, 173, 109, 0, 1, 101, 122, 101, 106, 101, 102, 2, 115, 111, 114, 0, 1, 101, 122, 109, 101, 110, 2, 115, 122, 195, 173, 110, 0, 1, 101, 122, 121, 103, 169, 195, 110, 2, 99, 101, 110, 116, 105, 0, 1, 105, 102, 97, 114, 103, 2, 99, 101, 114, 117, 122, 0, 1, 105, 108, 101, 2, 115, 122, 111, 108, 103, 0, 1, 105, 112, 114, 161, 195, 107, 2, 115, 122, 197, 145, 110, 121, 0, 1, 105, 122, 105, 118, 2, 115, 122, 111, 98, 0, 1, 108, 97, 122, 115, 97, 2, 106, 101, 103, 0, 1, 108, 161, 195, 110, 122, 115, 97, 104, 2, 99, 105, 107, 107, 0, 1, 110, 97, 107, 107, 111, 114, 2, 115, 101, 103, 195, 173, 116, 0, 1, 110, 111, 106, 97, 118, 2, 115, 122, 111, 114, 111, 115, 0, 1, 110, 111, 114, 102, 2, 115, 101, 98, 195, 169, 115, 122, 0, 1, 110, 111, 115, 99, 2, 115, 111, 118, 195, 161, 110, 121, 0, 1, 110, 111, 115, 99, 2, 115, 195, 161, 114, 103, 97, 0, 1, 110, 161, 195, 102, 101, 108, 101, 2, 115, 122, 197, 145, 114, 0, 1, 110, 161, 195, 109, 169, 195, 121, 103, 2, 115, 122, 111, 108, 105, 0, 1, 111, 98, 111, 114, 2, 115, 122, 111, 110, 100, 0, 1, 114, 111, 112, 115, 2, 99, 101, 110, 116, 0, 1, 114, 161, 195, 112, 2, 115, 122, 195, 169, 107, 104, 195, 161, 122, 0, 1, 114, 161, 195, 122, 2, 115, 122, 195, 169, 107, 0, 1, 115, 188, 195, 122, 101, 2, 115, 97, 114, 107, 0, 1, 115, 188, 195, 122, 101, 2, 115, 122, 111, 98, 0, 1, 115, 188, 195, 122, 101, 2, 115, 122, 195, 169, 108, 0, 1, 115, 188, 195, 122, 101, 2, 115, 122, 197, 145, 107, 101, 0, 1, 115, 188, 195, 122, 101, 2, 115, 122, 197, 145, 114, 0, 1, 117, 109, 97, 109, 2, 115, 122, 197, 145, 114, 0, 1, 117, 109, 97, 112, 2, 99, 195, 169, 114, 0, 1, 117, 109, 97, 112, 2, 115, 122, 111, 107, 0, 1, 122, 115, 101, 116, 2, 99, 105, 107, 107, 0, 1, 122, 115, 101, 116, 2, 99, 195, 169, 108, 0, 1, 122, 115, 105, 108, 2, 99, 105, 112, 101, 108, 0, 1, 161, 195, 2, 99, 97, 112, 108, 97, 116, 0, 1, 161, 195, 2, 99, 105, 107, 195, 161, 122, 0, 1, 161, 195, 2, 99, 195, 173, 109, 0, 1, 161, 195, 106, 97, 115, 2, 115, 122, 101, 109, 195, 169, 0, 1, 161, 195, 106, 97, 115, 2, 115, 122, 101, 114, 197, 177, 0, 1, 161, 195, 107, 97, 108, 112, 2, 99, 195, 169, 103, 0, 1, 161, 195, 107, 111, 114, 98, 2, 115, 101, 108, 121, 0, 1, 161, 195, 107, 111, 114, 98, 2, 115, 122, 0, 1, 161, 195, 108, 114, 97, 107, 115, 2, 115, 122, 195, 173, 110, 0, 1, 161, 195, 118, 105, 118, 2, 115, 122, 195, 179, 0, 1, 169, 195, 107, 110, 101, 122, 105, 116, 2, 115, 122, 195, 169, 108, 0, 1, 169, 195, 116, 182, 195, 115, 2, 115, 122, 111, 98, 0, 1, 169, 195, 122, 115, 2, 115, 117, 103, 195, 161, 114, 0, 1, 169, 195, 122, 115, 2, 115, 122, 111, 114, 116, 195, 173, 114, 0, 1, 169, 195, 122, 115, 2, 115, 122, 111, 114, 195, 173, 116, 0, 1, 169, 195, 122, 115, 2, 115, 195, 182, 112, 195, 182, 114, 0, 1, 179, 195, 112, 2, 115, 101, 108, 101, 106, 116, 0, 1, 182, 195, 2, 121, 97, 114, 100, 0, 2, 99, 115, 0, 8, 97, 108, 108, 161, 195, 2, 115, 122, 111, 98, 0, 8, 101, 108, 103, 101, 122, 115, 2, 115, 122, 0, 8, 102, 97, 116, 2, 115, 101, 108, 121, 0, 8, 105, 115, 122, 161, 195, 112, 2, 115, 122, 0, 8, 106, 97, 115, 2, 115, 122, 195, 173, 110, 0, 8, 110, 111, 122, 115, 105, 118, 2, 115, 122, 111, 108, 103, 195, 161, 108, 0, 8, 111, 98, 111, 114, 2, 115, 122, 111, 102, 116, 118, 101, 0, 8, 114, 97, 112, 2, 115, 122, 195, 169, 108, 0, 8, 114, 111, 112, 115, 2, 99, 195, 169, 108, 0, 8, 115, 101, 2, 115, 122, 195, 169, 108, 0, 8, 115, 101, 116, 2, 115, 122, 197, 145, 114, 0, 8, 145, 197, 114, 2, 115, 122, 197, 145, 107, 0, 8, 161, 195, 2, 115, 122, 111, 108, 103, 195, 161, 108, 116, 97, 116, 0, 8, 169, 195, 104, 2, 99, 111, 108, 0, 8, 169, 195, 107, 2, 115, 122, 195, 169, 108, 0, 8, 169, 195, 116, 182, 195, 115, 2, 115, 122, 197, 145, 107, 0, 8, 179, 195, 112, 2, 115, 122, 111, 108, 103, 195, 161, 108, 0, 104, 1, 97, 2, 195, 169, 110, 0, 116, 1, 182, 195, 100, 108, 188, 195, 107, 2, 103, 121, 197, 177, 108, 0, 116, 2, 18, 66, 0, 116, 2, 45, 18, 66, 0, 116, 8, 111, 114, 102, 2, 195, 173, 114, 0, 4, 2, 45, 116, 3, 47, 12, 0, 116, 2, 45, 116, 0, 4, 121, 1, 114, 97, 109, 115, 182, 195, 114, 182, 195, 118, 3, 47, 37, 0, 121, 1, 122, 115, 111, 110, 0, 121, 8, 97, 107, 2, 110, 0, 116, 106, 8, 111, 2, 195, 161, 114, 3, 47, 57, 0, 115, 122, 8, 186, 195, 2, 195, 169, 107, 3, 47, 89, 0, 101, 114, 109, 195, 169, 115, 122, 101, 116, 101, 115, 3, 47, 109, 52, 65, 113, 89, 109, 47, 109, 91, 0, 104, 195, 182, 107, 195, 182, 108, 121, 3, 47, 110, 49, 110, 55, 37, 0, 8, 2, 32, 3, 47, 113, 0, 195, 179, 108, 1, 21, 2, 32, 14, 128, 192, 131, 3, 47, 115, 55, 0, 197, 145, 108, 1, 21, 2, 32, 14, 128, 192, 131, 3, 47, 118, 55, 0, 4, 115, 1, 105, 115, 97, 122, 161, 195, 104, 2, 97, 3, 76, 12, 0, 115, 1, 169, 195, 107, 169, 195, 98, 101, 122, 115, 115, 182, 195, 2, 101, 0, 115, 8, 105, 107, 97, 122, 115, 2, 111, 110, 0, 4, 116, 121, 2, 18, 66, 3, 80, 0, 121, 0, 121, 106, 1, 17, 67, 0, 4, 2, 45, 116, 121, 3, 80, 12, 0, 116, 2, 45, 116, 121, 0, 121, 2, 45, 116, 121, 0, 121, 106, 1, 17, 65, 2, 17, 65, 0, 4, 115, 122, 1, 101, 109, 2, 118, 195, 169, 110, 121, 3, 119, 0, 115, 122, 1, 101, 116, 2, 104, 0, 115, 122, 1, 161, 195, 106, 2, 100, 0, 115, 122, 1, 161, 195, 108, 2, 118, 97, 0, 115, 122, 2, 104, 0, 4, 99, 3, 119, 12, 0, 115, 115, 122, 1, 161, 195, 108, 105, 107, 2, 195, 169, 107, 0, 115, 122, 1, 97, 108, 108, 97, 104, 2, 195, 161, 110, 97, 107, 0, 115, 122, 1, 97, 108, 108, 97, 104, 2, 195, 179, 100, 0, 115, 122, 1, 101, 109, 2, 105, 116, 101, 107, 0, 115, 122, 8, 182, 195, 107, 2, 101, 114, 0, 7, 6, 117, 0, 3, 40, 0, 1, 116, 101, 106, 118, 111, 122, 115, 2, 110, 105, 195, 179, 3, 116, 0, 7, 6, 118, 0, 3, 84, 0, 101, 114, 115, 97, 105, 108, 108, 101, 115, 5, 1, 8, 3, 84, 109, 52, 89, 114, 57, 0, 8, 2, 32, 3, 84, 113, 0, 7, 6, 119, 0, 3, 84, 0, 7, 6, 120, 0, 8, 2, 32, 3, 37, 49, 89, 0, 3, 49, 89, 0, 7, 6, 121, 0, 4, 3, 37, 0, 1, 25, 2, 25, 0, 8, 3, 57, 0, 97, 114, 100, 3, 57, 108, 52, 72, 0, 97, 114, 100, 100, 3, 57, 108, 52, 72, 12, 0, 7, 6, 122, 0, 4, 3, 88, 0, 1, 97, 114, 161, 195, 122, 115, 2, 115, 195, 188, 108, 116, 0, 1, 101, 109, 101, 108, 2, 115, 116, 195, 186, 0, 1, 101, 109, 101, 108, 2, 115, 122, 101, 114, 122, 0, 1, 101, 109, 101, 110, 0, 1, 110, 169, 195, 112, 0, 1, 114, 111, 116, 2, 115, 195, 161, 103, 0, 1, 117, 97, 108, 97, 107, 2, 115, 195, 161, 103, 0, 1, 145, 197, 2, 115, 195, 182, 114, 195, 169, 116, 0, 1, 145, 197, 103, 2, 115, 117, 103, 195, 161, 114, 0, 1, 145, 197, 103, 2, 115, 195, 173, 112, 0, 1, 161, 195, 103, 2, 99, 115, 197, 145, 0, 1, 161, 195, 103, 2, 115, 112, 114, 97, 0, 1, 161, 195, 103, 2, 115, 117, 103, 0, 1, 161, 195, 104, 2, 115, 97, 114, 107, 111, 116, 0, 1, 161, 195, 104, 2, 115, 97, 114, 111, 107, 0, 1, 161, 195, 104, 2, 115, 111, 0, 1, 161, 195, 104, 114, 179, 195, 107, 2, 115, 195, 161, 0, 1, 161, 195, 112, 111, 116, 0, 1, 161, 195, 118, 116, 110, 111, 115, 99, 0, 1, 169, 195, 104, 101, 110, 2, 115, 195, 186, 108, 121, 0, 1, 169, 195, 104, 101, 110, 2, 115, 195, 186, 108, 121, 195, 186, 0, 1, 169, 195, 107, 2, 115, 101, 98, 0, 1, 169, 195, 107, 2, 115, 122, 0, 1, 169, 195, 107, 2, 115, 195, 169, 114, 195, 188, 108, 0, 1, 169, 195, 107, 2, 122, 115, 105, 98, 98, 97, 100, 195, 161, 115, 0, 1, 169, 195, 109, 2, 115, 195, 182, 114, 0, 1, 169, 195, 114, 2, 115, 97, 114, 107, 0, 1, 169, 195, 114, 2, 115, 97, 118, 0, 1, 169, 195, 114, 2, 115, 101, 114, 108, 101, 103, 0, 1, 169, 195, 114, 2, 115, 101, 114, 112, 101, 110, 121, 197, 145, 0, 1, 169, 195, 114, 2, 115, 105, 112, 107, 0, 1, 169, 195, 114, 2, 115, 105, 115, 97, 107, 0, 1, 169, 195, 114, 2, 115, 111, 100, 0, 1, 169, 195, 114, 2, 115, 111, 100, 114, 111, 110, 121, 0, 1, 169, 195, 114, 2, 115, 195, 161, 114, 107, 195, 161, 0, 1, 169, 195, 114, 2, 115, 195, 173, 112, 0, 1, 173, 195, 99, 101, 114, 112, 2, 115, 195, 169, 103, 0, 1, 173, 195, 116, 2, 115, 195, 161, 118, 0, 1, 173, 195, 118, 114, 161, 195, 2, 115, 195, 186, 106, 0, 1, 177, 197, 116, 0, 1, 177, 197, 116, 2, 122, 115, 195, 161, 107, 0, 1, 177, 197, 122, 115, 2, 115, 195, 188, 108, 116, 0, 1, 179, 195, 108, 97, 107, 0, 1, 179, 195, 114, 116, 97, 109, 2, 115, 97, 112, 107, 0, 1, 179, 195, 114, 116, 97, 109, 2, 115, 105, 112, 107, 0, 1, 179, 195, 114, 116, 97, 109, 2, 122, 115, 195, 161, 107, 0, 1, 182, 195, 107, 122, 101, 2, 115, 111, 114, 0, 1, 182, 195, 107, 122, 101, 2, 115, 195, 161, 118, 0, 1, 182, 195, 107, 122, 115, 101, 2, 115, 111, 114, 0, 1, 182, 195, 107, 122, 115, 101, 2, 115, 195, 161, 118, 0, 8, 110, 111, 114, 98, 0, 8, 114, 111, 98, 2, 122, 115, 195, 173, 114, 0, 8, 145, 197, 2, 115, 101, 98, 0, 8, 145, 197, 2, 115, 117, 116, 0, 8, 145, 197, 103, 0, 8, 145, 197, 103, 2, 115, 195, 188, 118, 195, 182, 108, 116, 0, 8, 161, 195, 108, 2, 115, 101, 98, 0, 8, 161, 195, 108, 2, 115, 195, 179, 104, 0, 8, 161, 195, 122, 115, 2, 115, 111, 114, 0, 8, 169, 195, 109, 2, 115, 101, 114, 0, 8, 169, 195, 109, 2, 115, 195, 161, 114, 103, 0, 8, 169, 195, 116, 105, 118, 0, 8, 173, 195, 116, 2, 115, 104, 105, 108, 108, 0, 8, 173, 195, 116, 2, 115, 111, 114, 0, 8, 173, 195, 116, 2, 115, 111, 117, 0, 8, 173, 195, 116, 2, 122, 115, 195, 161, 107, 0, 8, 173, 195, 118, 2, 115, 0, 8, 177, 197, 116, 2, 122, 115, 111, 110, 103, 108, 197, 145, 114, 0, 99, 1, 161, 195, 109, 2, 115, 122, 0, 99, 1, 169, 195, 109, 2, 115, 122, 0, 122, 1, 161, 195, 121, 103, 105, 118, 2, 195, 161, 108, 108, 0, 122, 2, 98, 0, 122, 2, 116, 0, 122, 2, 118, 0, 4, 115, 122, 3, 88, 89, 0, 115, 122, 8, 161, 195, 103, 2, 195, 161, 109, 108, 97, 0, 115, 122, 8, 161, 195, 103, 2, 195, 161, 109, 108, 195, 161, 0, 4, 115, 1, 97, 103, 2, 195, 161, 103, 3, 88, 91, 0, 115, 1, 145, 197, 2, 117, 116, 97, 0, 115, 8, 161, 195, 118, 2, 111, 114, 0, 115, 8, 169, 195, 104, 101, 110, 2, 101, 108, 121, 0, 115, 8, 169, 195, 114, 2, 195, 179, 0, 4, 1, 97, 2, 116, 3, 89, 0, 1, 97, 2, 116, 195, 161, 110, 0, 1, 97, 109, 108, 97, 107, 108, 97, 2, 107, 111, 0, 1, 101, 2, 116, 0, 1, 101, 100, 110, 101, 114, 2, 107, 101, 100, 0, 1, 101, 106, 101, 102, 101, 98, 2, 116, 101, 0, 1, 101, 106, 101, 102, 101, 108, 2, 116, 101, 0, 1, 101, 106, 101, 102, 101, 108, 2, 116, 195, 169, 107, 0, 1, 101, 107, 2, 100, 116, 0, 1, 101, 118, 114, 101, 122, 115, 2, 107, 101, 100, 0, 1, 101, 121, 103, 101, 2, 107, 101, 0, 1, 101, 121, 103, 101, 2, 116, 101, 0, 1, 101, 121, 108, 101, 104, 2, 107, 101, 0, 1, 101, 121, 108, 101, 104, 2, 107, 101, 100, 0, 1, 105, 98, 2, 116, 97, 116, 0, 1, 105, 98, 2, 116, 111, 110, 115, 0, 1, 105, 98, 2, 116, 111, 115, 0, 1, 110, 169, 195, 112, 2, 116, 0, 1, 110, 169, 195, 112, 2, 116, 195, 161, 114, 0, 1, 111, 98, 111, 100, 2, 116, 0, 1, 111, 98, 111, 107, 2, 116, 0, 1, 111, 102, 111, 112, 2, 107, 111, 100, 0, 1, 111, 103, 108, 111, 100, 2, 116, 0, 1, 111, 103, 110, 97, 104, 2, 116, 0, 1, 111, 103, 111, 98, 2, 116, 195, 161, 107, 0, 1, 111, 104, 2, 116, 97, 0, 1, 111, 104, 2, 116, 195, 161, 0, 1, 111, 107, 97, 108, 116, 97, 115, 99, 2, 116, 97, 0, 1, 111, 107, 97, 108, 116, 97, 115, 99, 2, 116, 111, 107, 0, 1, 111, 107, 108, 97, 108, 103, 111, 102, 2, 116, 0, 1, 111, 107, 108, 161, 195, 108, 97, 116, 2, 116, 0, 1, 111, 107, 111, 2, 116, 0, 1, 111, 107, 116, 97, 110, 111, 118, 2, 116, 97, 0, 1, 111, 107, 116, 97, 116, 105, 118, 2, 116, 0, 1, 111, 107, 169, 195, 100, 110, 161, 195, 106, 97, 2, 116, 0, 1, 111, 107, 169, 195, 106, 161, 195, 116, 2, 116, 97, 115, 115, 0, 1, 111, 107, 169, 195, 106, 161, 195, 116, 2, 116, 97, 116, 0, 1, 111, 114, 161, 195, 116, 97, 104, 2, 116, 0, 1, 111, 116, 108, 161, 195, 118, 2, 116, 97, 115, 115, 0, 1, 111, 116, 108, 161, 195, 118, 2, 116, 97, 116, 0, 1, 111, 116, 114, 97, 116, 2, 107, 0, 1, 111, 116, 114, 97, 116, 2, 116, 0, 1, 111, 116, 122, 115, 111, 2, 107, 111, 100, 0, 1, 111, 121, 110, 161, 195, 105, 104, 2, 116, 0, 1, 111, 121, 110, 161, 195, 109, 108, 117, 110, 97, 116, 2, 116, 0, 1, 145, 197, 108, 101, 100, 101, 122, 115, 2, 107, 195, 182, 0, 1, 145, 197, 108, 108, 101, 122, 115, 2, 116, 101, 116, 0, 1, 145, 197, 116, 106, 101, 114, 2, 107, 195, 182, 0, 1, 145, 197, 116, 106, 101, 114, 2, 116, 0, 1, 145, 197, 121, 103, 2, 107, 195, 182, 100, 0, 1, 145, 197, 121, 103, 2, 116, 0, 1, 161, 195, 98, 105, 104, 2, 116, 97, 116, 0, 1, 161, 195, 104, 2, 116, 97, 114, 116, 195, 161, 115, 0, 1, 161, 195, 107, 99, 111, 107, 2, 116, 97, 0, 1, 161, 195, 114, 2, 107, 195, 179, 100, 0, 1, 161, 195, 114, 97, 121, 103, 97, 109, 2, 107, 111, 100, 0, 1, 161, 195, 114, 97, 121, 103, 97, 109, 2, 116, 0, 1, 161, 195, 116, 122, 115, 105, 116, 2, 116, 0, 1, 169, 195, 116, 110, 105, 2, 107, 101, 100, 0, 1, 169, 195, 116, 110, 105, 2, 116, 0, 1, 173, 195, 118, 2, 115, 122, 105, 110, 116, 0, 1, 179, 195, 116, 106, 186, 195, 121, 110, 2, 107, 111, 0, 1, 179, 195, 116, 114, 97, 116, 2, 107, 0, 1, 179, 195, 116, 114, 97, 116, 2, 116, 0, 1, 182, 195, 98, 110, 182, 195, 108, 188, 195, 107, 2, 116, 101, 116, 0, 1, 182, 195, 100, 108, 188, 195, 2, 116, 0, 1, 182, 195, 107, 103, 101, 100, 105, 2, 112, 111, 110, 0, 1, 182, 195, 107, 109, 101, 122, 115, 2, 116, 0, 1, 182, 195, 107, 115, 99, 161, 195, 110, 97, 116, 2, 116, 195, 161, 114, 115, 97, 115, 195, 161, 103, 0, 1, 182, 195, 107, 122, 115, 101, 2, 116, 0, 1, 182, 195, 116, 108, 182, 195, 2, 107, 195, 182, 0, 1, 182, 195, 116, 108, 182, 195, 2, 116, 101, 0, 1, 182, 195, 116, 108, 182, 195, 107, 2, 107, 195, 182, 100, 0, 1, 182, 195, 116, 182, 195, 107, 2, 107, 195, 182, 0, 1, 182, 195, 116, 182, 195, 107, 2, 116, 0, 1, 186, 195, 115, 99, 186, 195, 98, 2, 107, 111, 0, 1, 186, 195, 115, 99, 186, 195, 98, 2, 107, 111, 100, 0, 1, 186, 195, 115, 99, 186, 195, 98, 2, 116, 0, 1, 186, 195, 115, 99, 186, 195, 98, 2, 116, 97, 116, 0, 4, 115, 122, 1, 161, 195, 122, 115, 2, 111, 114, 3, 89, 12, 0, 115, 122, 1, 173, 195, 116, 2, 101, 114, 0, 115, 122, 1, 173, 195, 118, 2, 105, 110, 116, 101, 115, 0, 115, 122, 1, 177, 197, 116, 2, 101, 114, 195, 169, 115, 115, 122, 0, 115, 122, 1, 177, 197, 116, 2, 101, 114, 195, 169, 115, 122, 0, 4, 115, 3, 90, 0, 115, 8, 110, 169, 195, 112, 2, 101, 100, 0, 115, 8, 111, 114, 2, 122, 97, 98, 195, 161, 108, 0, 4, 115, 122, 115, 1, 111, 114, 2, 101, 109, 3, 90, 12, 0, 122, 115, 0, 115, 122, 1, 114, 182, 195, 116, 2, 195, 161, 115, 122, 108, 195, 179, 3, 90, 88, 0, 4, 1, 169, 195, 104, 101, 110, 2, 115, 195, 169, 3, 91, 0, 115, 1, 105, 114, 2, 116, 0, 115, 1, 161, 195, 114, 97, 100, 2, 102, 195, 169, 115, 122, 101, 107, 0, 115, 1, 161, 195, 114, 97, 103, 2, 116, 195, 161, 114, 111, 108, 195, 179, 0, 4, 115, 1, 97, 103, 2, 195, 161, 103, 3, 91, 91, 0, 115, 1, 97, 103, 105, 2, 195, 161, 103, 0, 115, 8, 97, 114, 161, 195, 122, 115, 2, 195, 161, 103, 0, 4, 1, 108, 97, 119, 2, 101, 114, 3, 119, 0, 1, 179, 195, 103, 111, 102, 2, 107, 111, 100, 0, 4, 105, 112, 112, 122, 195, 161, 114, 3, 119, 37, 48, 88, 114, 52, 0, 105, 112, 122, 195, 161, 114, 0, 195, 188, 114, 105, 99, 104, 8, 3, 119, 111, 52, 37, 0, 7, 6, 0, 195, 177, 3, 67, 0, 36, 3, 72, 39, 55, 55, 114, 52, 0, 195, 167, 3, 76, 0, 195, 159, 3, 89, 0, 4, 195, 164, 3, 109, 0, 195, 166, 0, 195, 184, 3, 110, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts25 = FileInMemory_createWithData (112825, reinterpret_cast (&espeakdata_dicts25_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/hu_dict", U"hu"); Collection_addItem (me.peek(), espeakdata_dicts25.transfer()); static unsigned char espeakdata_dicts26_data[2436] = { 0, 4, 0, 0, 114, 6, 0, 0, 0, 0, 0, 0, 0, 5, 65, 4, 35, 0, 0, 0, 0, 0, 6, 65, 8, 71, 37, 0, 0, 0, 0, 0, 6, 65, 12, 89, 37, 0, 0, 0, 0, 0, 6, 65, 16, 72, 37, 0, 0, 0, 0, 0, 5, 65, 20, 36, 0, 0, 0, 0, 0, 6, 65, 24, 36, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 4, 95, 4, 16, 20, 10, 89, 47, 39, 69, 35, 49, 6, 36, 55, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 51, 88, 57, 36, 34, 36, 89, 6, 40, 50, 0, 0, 13, 3, 95, 48, 67, 107, 35, 34, 57, 6, 40, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 49, 48, 47, 6, 35, 89, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 3, 95, 55, 88, 57, 36, 39, 25, 35, 50, 35, 89, 6, 40, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 49, 88, 47, 35, 89, 50, 6, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 50, 88, 115, 89, 6, 35, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 95, 63, 63, 81, 4, 37, 51, 0, 0, 0, 0, 14, 3, 95, 52, 88, 115, 35, 69, 35, 89, 6, 40, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 53, 88, 107, 37, 89, 40, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 54, 88, 84, 35, 25, 89, 40, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 56, 88, 40, 25, 89, 6, 40, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 57, 88, 37, 50, 50, 35, 89, 6, 40, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 48, 77, 50, 65, 37, 55, 6, 39, 50, 0, 0, 0, 0, 13, 4, 95, 48, 77, 49, 107, 35, 88, 6, 35, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 95, 214, 133, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 3, 95, 213, 168, 6, 13, 25, 0, 0, 7, 3, 95, 213, 167, 36, 0, 0, 0, 0, 0, 0, 0, 8, 3, 95, 213, 161, 110, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 95, 3, 1, 16, 65, 4, 36, 117, 23, 0, 0, 0, 0, 0, 0, 0, 0, 11, 2, 95, 51, 57, 36, 34, 6, 36, 115, 0, 0, 11, 2, 95, 50, 57, 36, 34, 49, 6, 40, 0, 0, 9, 2, 95, 49, 65, 6, 36, 49, 0, 0, 10, 2, 95, 48, 88, 13, 69, 6, 39, 0, 0, 9, 2, 95, 55, 57, 6, 39, 25, 0, 0, 9, 2, 95, 54, 84, 6, 36, 114, 0, 0, 10, 2, 95, 53, 107, 6, 37, 50, 81, 0, 0, 10, 2, 95, 52, 76, 6, 39, 34, 89, 0, 0, 0, 7, 2, 214, 134, 83, 36, 0, 0, 9, 2, 95, 57, 6, 37, 50, 13, 0, 0, 8, 2, 95, 56, 6, 40, 25, 0, 7, 2, 214, 132, 115, 36, 0, 0, 8, 2, 214, 131, 113, 108, 34, 0, 0, 8, 2, 214, 130, 107, 108, 50, 0, 0, 7, 2, 214, 129, 117, 39, 0, 0, 7, 2, 214, 128, 34, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 213, 166, 88, 35, 0, 0, 8, 2, 213, 165, 57, 36, 76, 0, 0, 7, 2, 213, 164, 72, 35, 0, 0, 8, 2, 213, 163, 81, 37, 65, 0, 0, 8, 2, 213, 162, 71, 36, 50, 0, 0, 0, 0, 8, 2, 213, 175, 49, 36, 50, 0, 0, 7, 2, 213, 174, 117, 35, 0, 0, 7, 2, 213, 173, 106, 36, 0, 0, 8, 2, 213, 172, 55, 108, 50, 0, 0, 8, 2, 213, 171, 37, 50, 37, 0, 0, 7, 2, 213, 170, 90, 36, 0, 0, 7, 2, 213, 169, 25, 39, 0, 0, 0, 7, 2, 213, 183, 91, 35, 0, 0, 7, 2, 213, 182, 50, 40, 0, 0, 7, 2, 213, 181, 107, 37, 0, 0, 8, 2, 213, 180, 65, 36, 50, 0, 0, 7, 2, 213, 179, 80, 36, 0, 0, 8, 2, 213, 178, 54, 35, 72, 0, 0, 7, 2, 213, 177, 116, 35, 0, 0, 7, 2, 213, 176, 107, 39, 0, 0, 8, 2, 213, 191, 47, 108, 50, 0, 0, 8, 2, 213, 190, 84, 36, 84, 0, 0, 7, 2, 213, 189, 89, 36, 0, 0, 7, 2, 213, 188, 69, 35, 0, 0, 7, 2, 213, 187, 75, 36, 0, 0, 7, 2, 213, 186, 48, 36, 0, 0, 7, 2, 213, 185, 76, 35, 0, 0, 7, 2, 213, 184, 84, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 18, 66, 213, 162, 0, 213, 163, 0, 213, 169, 0, 213, 175, 0, 213, 186, 0, 213, 191, 0, 214, 132, 0, 7, 6, 18, 67, 213, 184, 214, 130, 0, 213, 161, 213, 181, 0, 213, 171, 214, 130, 0, 213, 171, 213, 181, 0, 213, 184, 213, 181, 0, 7, 6, 20, 0, 0, 135, 5, 0, 0, 101, 5, 130, 5, 0, 0, 0, 0, 6, 1, 50, 0, 4, 3, 35, 0, 213, 181, 2, 32, 0, 213, 181, 3, 110, 0, 7, 6, 1, 51, 0, 3, 71, 0, 8, 2, 17, 67, 3, 71, 13, 0, 7, 6, 1, 52, 0, 3, 81, 0, 8, 2, 17, 67, 3, 81, 13, 0, 7, 6, 1, 53, 0, 3, 72, 0, 8, 2, 17, 67, 3, 72, 13, 0, 7, 6, 1, 54, 0, 3, 36, 0, 213, 161, 3, 57, 35, 0, 8, 3, 57, 36, 0, 214, 133, 3, 57, 39, 0, 7, 6, 1, 55, 0, 8, 2, 18, 66, 3, 13, 88, 0, 3, 88, 0, 8, 2, 17, 67, 3, 88, 13, 0, 7, 6, 1, 56, 0, 3, 36, 0, 214, 133, 3, 109, 0, 213, 181, 3, 111, 0, 7, 6, 1, 57, 0, 3, 13, 0, 7, 6, 1, 58, 0, 3, 25, 0, 8, 2, 17, 67, 3, 25, 13, 0, 7, 6, 1, 59, 0, 3, 90, 0, 7, 6, 1, 60, 0, 3, 37, 0, 214, 130, 2, 32, 3, 37, 84, 0, 214, 130, 3, 108, 0, 213, 181, 3, 112, 0, 7, 6, 1, 61, 0, 3, 55, 0, 8, 2, 17, 67, 3, 55, 13, 0, 7, 6, 1, 62, 0, 3, 106, 0, 7, 6, 1, 63, 0, 3, 117, 0, 8, 2, 17, 67, 3, 117, 13, 0, 7, 6, 1, 64, 0, 3, 49, 0, 8, 2, 17, 67, 3, 49, 13, 0, 7, 6, 1, 65, 0, 3, 107, 0, 8, 2, 17, 67, 3, 107, 13, 0, 7, 6, 1, 66, 0, 3, 116, 0, 8, 2, 17, 67, 3, 116, 13, 0, 7, 6, 1, 67, 0, 3, 54, 0, 8, 2, 17, 67, 3, 54, 13, 0, 7, 6, 1, 68, 0, 3, 80, 0, 8, 2, 17, 67, 3, 80, 13, 0, 7, 6, 1, 69, 0, 1, 17, 67, 2, 32, 3, 13, 65, 0, 4, 3, 65, 0, 1, 18, 67, 2, 32, 0, 8, 2, 17, 67, 3, 65, 13, 0, 7, 6, 1, 70, 0, 3, 107, 0, 8, 2, 17, 67, 3, 107, 13, 0, 7, 6, 1, 71, 0, 1, 17, 67, 2, 32, 3, 13, 50, 0, 4, 3, 50, 0, 1, 18, 67, 2, 32, 0, 8, 2, 17, 67, 3, 50, 13, 0, 7, 6, 1, 72, 0, 8, 2, 213, 191, 3, 13, 91, 0, 3, 91, 0, 8, 2, 17, 67, 3, 91, 13, 0, 7, 6, 1, 73, 0, 4, 3, 39, 0, 213, 181, 2, 32, 0, 213, 181, 1, 17, 65, 3, 39, 57, 0, 214, 130, 3, 40, 0, 213, 181, 3, 40, 57, 0, 214, 130, 2, 17, 65, 3, 84, 0, 8, 3, 84, 39, 0, 7, 6, 1, 74, 0, 3, 76, 0, 8, 2, 17, 67, 3, 76, 13, 0, 7, 6, 1, 75, 0, 3, 48, 0, 8, 2, 17, 67, 3, 48, 13, 0, 7, 6, 1, 76, 0, 3, 75, 0, 8, 2, 17, 67, 3, 75, 13, 0, 7, 6, 1, 77, 0, 3, 69, 0, 8, 2, 17, 67, 3, 69, 13, 0, 7, 6, 1, 78, 0, 8, 2, 18, 66, 3, 13, 89, 0, 3, 89, 0, 8, 2, 17, 67, 3, 89, 13, 0, 7, 6, 1, 79, 0, 3, 84, 0, 8, 2, 17, 67, 3, 84, 13, 0, 7, 6, 1, 80, 0, 3, 47, 0, 8, 2, 17, 67, 3, 47, 13, 0, 7, 6, 1, 81, 0, 1, 17, 67, 2, 32, 3, 13, 34, 0, 4, 3, 34, 0, 1, 18, 67, 2, 32, 0, 8, 2, 17, 67, 3, 34, 13, 0, 7, 6, 1, 82, 0, 3, 114, 0, 8, 2, 17, 67, 3, 114, 13, 0, 7, 6, 1, 83, 0, 3, 84, 0, 8, 2, 17, 67, 3, 84, 13, 0, 7, 6, 1, 84, 0, 8, 2, 17, 67, 3, 48, 6, 13, 0, 3, 113, 0, 7, 6, 1, 85, 0, 3, 115, 0, 8, 2, 17, 67, 3, 115, 13, 0, 7, 6, 1, 86, 0, 3, 39, 0, 7, 6, 1, 87, 0, 3, 83, 0, 8, 2, 17, 67, 3, 83, 13, 0, 7, 6, 0, 36, 3, 72, 39, 55, 13, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts26 = FileInMemory_createWithData (2435, reinterpret_cast (&espeakdata_dicts26_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/hy_dict", U"hy"); Collection_addItem (me.peek(), espeakdata_dicts26.transfer()); static unsigned char espeakdata_dicts27_data[3083] = { 0, 4, 0, 0, 29, 10, 0, 0, 0, 0, 0, 0, 0, 5, 65, 4, 35, 0, 0, 0, 0, 0, 6, 65, 8, 71, 36, 0, 0, 0, 0, 0, 6, 65, 12, 76, 36, 0, 0, 0, 13, 4, 95, 8, 1, 3, 107, 6, 35, 76, 109, 49, 0, 0, 0, 6, 65, 16, 72, 36, 0, 0, 0, 0, 0, 5, 65, 20, 36, 0, 0, 0, 0, 0, 6, 65, 24, 109, 83, 0, 0, 0, 0, 0, 6, 65, 28, 81, 36, 0, 0, 6, 195, 76, 19, 135, 72, 0, 0, 0, 6, 65, 32, 107, 35, 0, 0, 0, 0, 11, 1, 35, 48, 6, 35, 81, 35, 51, 0, 27, 0, 5, 65, 36, 37, 0, 0, 12, 1, 37, 48, 13, 52, 89, 6, 109, 50, 0, 27, 0, 14, 1, 38, 47, 4, 35, 50, 72, 35, 72, 6, 35, 50, 0, 0, 12, 68, 8, 80, 133, 44, 71, 109, 71, 124, 19, 0, 0, 6, 65, 40, 75, 36, 0, 0, 0, 12, 1, 42, 71, 6, 37, 50, 47, 35, 68, 0, 27, 0, 12, 1, 43, 47, 6, 35, 65, 71, 35, 107, 0, 27, 0, 6, 65, 44, 49, 35, 0, 0, 0, 0, 18, 1, 47, 81, 4, 35, 52, 37, 89, 15, 65, 6, 37, 52, 37, 68, 0, 27, 0, 6, 65, 48, 109, 55, 0, 0, 0, 0, 0, 6, 65, 52, 109, 65, 0, 0, 0, 0, 0, 6, 65, 56, 109, 50, 0, 0, 0, 0, 0, 5, 65, 60, 39, 0, 0, 17, 1, 61, 89, 4, 35, 65, 35, 15, 72, 6, 109, 68, 35, 50, 0, 27, 0, 0, 0, 12, 1, 64, 35, 15, 49, 6, 109, 110, 50, 81, 0, 6, 65, 64, 48, 36, 0, 0, 0, 0, 0, 6, 65, 68, 49, 37, 0, 0, 0, 0, 0, 6, 65, 72, 109, 51, 0, 0, 0, 0, 0, 6, 65, 76, 109, 89, 0, 0, 0, 0, 0, 6, 65, 80, 47, 36, 0, 0, 0, 0, 0, 5, 65, 84, 40, 0, 0, 0, 0, 0, 6, 65, 88, 83, 36, 0, 0, 0, 0, 0, 12, 1, 92, 6, 71, 109, 49, 89, 55, 109, 91, 0, 6, 65, 92, 58, 36, 0, 0, 0, 15, 1, 94, 47, 4, 35, 50, 72, 35, 47, 6, 39, 48, 37, 0, 0, 0, 15, 4, 95, 49, 77, 49, 89, 13, 34, 6, 37, 71, 40, 10, 0, 7, 65, 96, 109, 49, 89, 0, 0, 15, 4, 95, 49, 77, 50, 89, 13, 75, 6, 40, 47, 35, 10, 0, 0, 16, 4, 95, 49, 77, 51, 89, 13, 65, 6, 37, 55, 57, 35, 51, 0, 0, 0, 6, 65, 100, 57, 36, 0, 0, 0, 0, 0, 7, 65, 104, 88, 109, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 1, 126, 47, 6, 37, 55, 72, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 64, 17, 1, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 4, 16, 20, 10, 49, 4, 39, 65, 35, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 20, 12, 4, 47, 6, 37, 55, 72, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 36, 19, 1, 32, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 16, 144, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 16, 19, 128, 72, 0, 6, 195, 32, 19, 135, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 16, 20, 137, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 8, 18, 23, 4, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 13, 3, 14, 65, 6, 35, 49, 52, 110, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 51, 88, 47, 6, 37, 81, 35, 48, 40, 55, 40, 107, 0, 0, 13, 3, 95, 48, 67, 51, 6, 35, 47, 40, 89, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 49, 67, 89, 13, 52, 6, 35, 47, 40, 89, 23, 0, 0, 0, 0, 0, 0, 0, 20, 3, 95, 49, 57, 89, 13, 65, 71, 6, 37, 55, 35, 50, 71, 13, 55, 35, 89, 0, 0, 19, 3, 95, 49, 56, 72, 13, 55, 6, 35, 48, 35, 50, 71, 13, 55, 35, 89, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 49, 49, 89, 6, 13, 71, 13, 55, 35, 89, 0, 0, 14, 3, 95, 49, 48, 89, 13, 48, 6, 40, 55, 40, 107, 0, 0, 16, 3, 95, 49, 51, 47, 6, 37, 81, 35, 71, 13, 55, 35, 89, 0, 0, 15, 3, 95, 49, 50, 72, 6, 40, 35, 71, 13, 55, 35, 89, 0, 0, 16, 3, 95, 49, 53, 55, 6, 37, 65, 35, 71, 13, 55, 35, 89, 0, 0, 17, 3, 95, 49, 52, 6, 13, 65, 48, 35, 47, 71, 13, 55, 35, 89, 0, 0, 17, 3, 95, 49, 55, 47, 6, 40, 75, 40, 107, 71, 13, 55, 35, 89, 0, 0, 16, 3, 95, 49, 54, 6, 13, 50, 35, 65, 71, 13, 55, 35, 89, 0, 0, 0, 17, 3, 95, 55, 88, 47, 6, 40, 75, 40, 107, 48, 40, 55, 40, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 66, 44, 80, 49, 13, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 50, 88, 72, 6, 40, 35, 48, 40, 55, 40, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 3, 95, 63, 63, 49, 4, 39, 72, 36, 107, 6, 40, 52, 40, 83, 0, 0, 0, 0, 17, 3, 95, 52, 88, 6, 109, 65, 48, 35, 47, 48, 40, 55, 40, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 53, 88, 55, 6, 37, 65, 35, 48, 40, 55, 40, 107, 0, 0, 0, 0, 9, 198, 76, 80, 129, 28, 18, 64, 72, 0, 0, 0, 0, 0, 16, 3, 95, 54, 88, 6, 109, 50, 35, 65, 48, 40, 55, 40, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 3, 95, 56, 88, 72, 13, 55, 6, 35, 48, 35, 50, 48, 40, 55, 40, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 3, 95, 57, 88, 89, 13, 65, 71, 6, 37, 55, 35, 50, 48, 40, 55, 40, 107, 0, 0, 0, 0, 0, 0, 7, 196, 77, 80, 84, 84, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 15, 7, 15, 6, 110, 81, 39, 50, 109, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 100, 19, 135, 72, 13, 4, 95, 48, 77, 50, 75, 6, 40, 47, 35, 10, 0, 0, 14, 4, 95, 48, 77, 51, 65, 6, 37, 55, 57, 35, 51, 0, 0, 0, 13, 4, 95, 48, 77, 49, 51, 6, 37, 71, 40, 10, 0, 0, 13, 4, 95, 2, 18, 22, 71, 52, 6, 37, 12, 84, 0, 0, 0, 0, 0, 0, 0, 12, 68, 8, 80, 197, 44, 71, 109, 76, 124, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 95, 3, 9, 18, 47, 6, 39, 48, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 19, 20, 11, 89, 47, 51, 6, 39, 49, 0, 0, 0, 13, 4, 95, 1, 3, 21, 35, 49, 57, 6, 40, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 95, 18, 14, 7, 52, 6, 37, 68, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 4, 95, 1, 3, 50, 72, 40, 71, 13, 55, 35, 49, 57, 6, 40, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 198, 16, 20, 137, 64, 17, 1, 72, 0, 0, 0, 0, 0, 0, 16, 2, 194, 163, 48, 39, 50, 89, 47, 6, 109, 52, 55, 37, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 3, 5, 4, 89, 13, 72, 6, 37, 55, 35, 0, 0, 0, 0, 14, 4, 95, 12, 9, 7, 72, 6, 117, 81, 51, 35, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 8, 82, 193, 76, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 76, 144, 72, 0, 0, 0, 8, 197, 64, 84, 129, 56, 112, 66, 0, 0, 0, 7, 196, 84, 229, 21, 44, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 2, 95, 34, 47, 4, 35, 50, 72, 35, 49, 6, 40, 47, 37, 48, 0, 0, 17, 2, 95, 33, 47, 4, 35, 50, 72, 35, 15, 89, 6, 109, 52, 40, 0, 0, 0, 19, 2, 95, 39, 49, 4, 40, 47, 37, 48, 15, 47, 6, 40, 68, 81, 35, 55, 0, 0, 0, 0, 0, 0, 13, 4, 95, 3, 1, 16, 71, 6, 109, 89, 35, 51, 0, 0, 18, 2, 95, 41, 49, 4, 40, 52, 40, 68, 15, 47, 6, 40, 47, 40, 48, 0, 0, 17, 2, 95, 40, 49, 4, 40, 52, 40, 68, 15, 71, 6, 40, 49, 35, 0, 0, 10, 67, 64, 84, 128, 48, 13, 34, 0, 72, 0, 11, 2, 95, 46, 47, 6, 37, 47, 37, 19, 0, 0, 17, 2, 95, 45, 47, 4, 35, 50, 72, 35, 107, 6, 40, 71, 40, 68, 0, 0, 10, 2, 95, 44, 49, 6, 39, 65, 35, 0, 0, 10, 2, 95, 51, 47, 6, 37, 81, 35, 0, 0, 9, 2, 95, 50, 72, 6, 40, 35, 0, 0, 10, 2, 95, 49, 89, 6, 35, 47, 40, 0, 0, 9, 2, 95, 48, 50, 6, 39, 55, 0, 0, 11, 2, 95, 55, 47, 6, 40, 75, 40, 107, 0, 0, 10, 2, 95, 54, 6, 13, 50, 35, 65, 0, 0, 10, 2, 95, 53, 55, 6, 37, 65, 35, 0, 0, 11, 2, 95, 52, 6, 13, 65, 48, 35, 47, 0, 0, 17, 2, 95, 59, 47, 4, 37, 47, 37, 19, 15, 49, 6, 39, 65, 35, 0, 0, 16, 2, 95, 58, 47, 4, 37, 47, 37, 19, 15, 72, 6, 40, 35, 0, 0, 14, 2, 95, 57, 89, 13, 65, 71, 6, 37, 55, 35, 50, 0, 0, 13, 2, 95, 56, 72, 13, 55, 6, 35, 48, 35, 50, 0, 0, 17, 2, 95, 63, 47, 4, 35, 50, 72, 35, 15, 47, 6, 35, 67, 35, 0, 0, 17, 2, 95, 62, 55, 4, 109, 71, 37, 107, 15, 72, 6, 35, 52, 37, 0, 0, 0, 17, 2, 95, 60, 49, 4, 40, 52, 35, 68, 15, 72, 6, 35, 52, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 95, 4, 15, 20, 72, 6, 110, 47, 0, 0, 0, 0, 17, 2, 95, 91, 49, 4, 40, 52, 40, 68, 15, 89, 6, 37, 49, 40, 0, 0, 0, 0, 0, 18, 2, 95, 95, 81, 4, 35, 52, 37, 89, 15, 71, 6, 35, 58, 35, 107, 0, 0, 0, 24, 2, 95, 93, 49, 4, 40, 52, 40, 68, 15, 89, 4, 37, 49, 40, 15, 47, 6, 40, 47, 40, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 95, 7, 18, 22, 81, 52, 6, 35, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 2, 95, 123, 49, 4, 40, 52, 40, 68, 15, 49, 40, 52, 6, 35, 58, 35, 55, 0, 13, 4, 95, 4, 9, 1, 6, 40, 65, 55, 114, 47, 0, 0, 0, 0, 0, 0, 0, 27, 2, 95, 125, 49, 4, 40, 52, 40, 68, 15, 49, 40, 52, 4, 35, 58, 35, 55, 15, 47, 6, 40, 47, 40, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 5, 64, 85, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 4, 64, 76, 4, 128, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 97, 0, 4, 1, 32, 17, 65, 3, 23, 35, 0, 1, 97, 0, 1, 117, 97, 0, 3, 35, 0, 117, 3, 114, 0, 105, 3, 117, 0, 7, 6, 98, 0, 3, 71, 0, 4, 101, 2, 110, 3, 71, 13, 0, 101, 8, 2, 21, 21, 0, 7, 6, 99, 0, 3, 76, 0, 104, 3, 106, 0, 7, 6, 100, 0, 3, 72, 0, 106, 3, 75, 0, 7, 6, 101, 0, 4, 1, 32, 17, 65, 3, 23, 109, 0, 1, 101, 0, 4, 3, 109, 0, 2, 32, 0, 7, 6, 102, 0, 4, 3, 83, 0, 102, 0, 7, 6, 103, 0, 3, 81, 0, 7, 6, 104, 0, 3, 107, 0, 7, 6, 105, 0, 4, 1, 32, 17, 65, 3, 23, 37, 0, 1, 105, 0, 4, 3, 37, 0, 101, 0, 7, 6, 106, 0, 3, 75, 0, 7, 6, 107, 0, 4, 3, 49, 0, 2, 32, 0, 4, 101, 2, 110, 3, 49, 13, 0, 101, 8, 2, 21, 21, 0, 104, 3, 101, 0, 7, 6, 108, 0, 4, 3, 55, 0, 108, 0, 7, 6, 109, 0, 3, 65, 0, 101, 8, 2, 21, 21, 3, 65, 13, 0, 101, 109, 112, 101, 8, 2, 21, 3, 65, 13, 65, 48, 13, 0, 7, 6, 110, 0, 3, 50, 0, 121, 3, 67, 0, 103, 3, 68, 0, 7, 6, 111, 0, 4, 1, 32, 17, 65, 3, 23, 39, 0, 1, 111, 0, 3, 39, 0, 101, 3, 40, 0, 2, 114, 3, 110, 0, 7, 6, 112, 0, 4, 3, 48, 0, 112, 0, 101, 8, 2, 21, 21, 3, 48, 13, 0, 104, 3, 83, 0, 7, 6, 113, 0, 3, 49, 0, 117, 3, 49, 58, 0, 7, 6, 114, 0, 4, 1, 101, 2, 25, 3, 51, 0, 2, 25, 0, 3, 52, 0, 7, 6, 115, 0, 4, 3, 89, 0, 115, 0, 101, 8, 2, 21, 21, 3, 89, 13, 0, 4, 106, 3, 99, 0, 121, 0, 7, 6, 116, 0, 3, 47, 0, 101, 114, 8, 2, 21, 21, 3, 47, 13, 51, 0, 101, 108, 8, 3, 47, 13, 55, 0, 106, 3, 76, 0, 7, 6, 117, 0, 4, 1, 32, 17, 65, 3, 23, 40, 0, 1, 117, 0, 3, 40, 0, 7, 6, 118, 0, 3, 84, 0, 7, 6, 119, 0, 3, 58, 0, 7, 6, 120, 0, 3, 49, 89, 0, 8, 3, 88, 0, 7, 6, 121, 0, 3, 57, 0, 7, 6, 122, 0, 3, 88, 0, 7, 6, 0, 4, 42, 1, 42, 2, 42, 3, 0, 42, 42, 3, 0, 42, 1, 42, 42, 2, 32, 3, 24, 0, 45, 8, 32, 2, 32, 15, 3, 47, 4, 35, 50, 72, 35, 49, 6, 40, 52, 35, 68, 0, 42, 3, 71, 6, 37, 50, 47, 35, 68, 0, 36, 3, 72, 110, 55, 35, 51, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts27 = FileInMemory_createWithData (3082, reinterpret_cast (&espeakdata_dicts27_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/id_dict", U"id"); Collection_addItem (me.peek(), espeakdata_dicts27.transfer()); static unsigned char espeakdata_dicts28_data[5469] = { 0, 4, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 0, 8, 132, 5, 195, 176, 1, 76, 8, 0, 0, 0, 8, 196, 25, 148, 137, 72, 76, 8, 0, 7, 65, 8, 71, 57, 112, 0, 0, 0, 9, 134, 13, 195, 173, 14, 21, 13, 76, 0, 0, 7, 65, 12, 89, 57, 112, 0, 0, 0, 0, 6, 195, 20, 225, 1, 8, 0, 7, 65, 16, 72, 57, 112, 0, 6, 195, 76, 147, 142, 76, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 24, 111, 83, 0, 8, 197, 28, 81, 206, 84, 208, 28, 0, 0, 0, 0, 7, 65, 28, 81, 57, 112, 0, 0, 0, 0, 0, 6, 65, 32, 107, 126, 0, 0, 0, 0, 9, 1, 35, 65, 109, 55, 55, 35, 0, 0, 0, 0, 9, 134, 8, 195, 182, 6, 21, 13, 72, 0, 0, 8, 65, 40, 57, 6, 115, 86, 0, 0, 0, 0, 9, 1, 43, 71, 55, 6, 116, 89, 0, 0, 7, 65, 44, 49, 6, 126, 0, 0, 0, 0, 12, 1, 47, 89, 49, 125, 89, 72, 138, 109, 81, 0, 0, 6, 65, 48, 111, 137, 0, 8, 133, 195, 190, 1, 195, 176, 76, 8, 133, 195, 190, 1, 195, 176, 72, 0, 9, 134, 5, 9, 7, 9, 195, 176, 76, 0, 10, 135, 21, 18, 195, 176, 21, 195, 176, 72, 0, 0, 6, 65, 52, 111, 65, 0, 12, 137, 8, 195, 182, 6, 195, 176, 21, 195, 176, 72, 8, 133, 5, 18, 21, 195, 176, 72, 0, 0, 0, 7, 196, 52, 147, 142, 4, 76, 10, 135, 195, 190, 5, 9, 18, 18, 1, 76, 0, 6, 65, 56, 111, 50, 0, 6, 131, 6, 195, 166, 76, 6, 131, 6, 195, 166, 76, 10, 5, 95, 48, 1, 14, 4, 115, 100, 0, 0, 0, 0, 0, 0, 19, 1, 61, 89, 6, 113, 65, 35, 89, 111, 65, 65, 4, 111, 34, 138, 49, 109, 0, 0, 0, 10, 135, 195, 190, 5, 9, 18, 18, 9, 76, 0, 7, 65, 64, 48, 57, 112, 0, 0, 0, 6, 195, 53, 83, 128, 76, 0, 7, 196, 52, 147, 12, 36, 8, 0, 6, 65, 68, 49, 116, 0, 0, 0, 0, 0, 7, 65, 72, 111, 34, 138, 0, 6, 195, 100, 98, 82, 28, 0, 0, 0, 6, 195, 53, 83, 137, 76, 0, 6, 65, 76, 111, 89, 0, 8, 197, 53, 147, 132, 37, 32, 76, 0, 0, 0, 8, 132, 13, 195, 179, 20, 76, 28, 0, 7, 65, 80, 47, 57, 112, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 52, 147, 142, 36, 76, 0, 7, 65, 88, 84, 35, 83, 0, 0, 0, 0, 0, 16, 65, 92, 47, 84, 6, 120, 84, 35, 55, 72, 84, 4, 35, 83, 0, 0, 0, 0, 0, 7, 65, 96, 112, 101, 89, 0, 0, 18, 4, 95, 49, 77, 50, 124, 50, 15, 65, 6, 109, 72, 55, 57, 127, 50, 0, 0, 0, 0, 16, 65, 100, 6, 117, 83, 89, 37, 55, 114, 50, 15, 4, 110, 0, 14, 0, 0, 9, 134, 195, 190, 5, 19, 19, 9, 76, 9, 134, 195, 190, 5, 19, 19, 9, 76, 0, 0, 8, 65, 104, 89, 112, 47, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 195, 190, 5, 19, 19, 21, 76, 0, 8, 196, 84, 225, 9, 72, 72, 28, 0, 0, 0, 6, 195, 53, 83, 148, 76, 0, 6, 195, 53, 83, 149, 76, 0, 0, 0, 0, 0, 0, 0, 6, 195, 28, 20, 212, 76, 9, 134, 195, 190, 5, 19, 19, 1, 76, 0, 9, 134, 13, 195, 173, 14, 9, 18, 76, 0, 0, 6, 194, 4, 96, 76, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 7, 195, 161, 20, 21, 13, 76, 0, 0, 0, 0, 10, 135, 22, 1, 18, 195, 176, 19, 20, 72, 0, 0, 0, 0, 10, 135, 6, 195, 169, 11, 11, 19, 20, 76, 0, 0, 0, 0, 6, 195, 5, 82, 192, 28, 0, 7, 196, 32, 147, 142, 4, 76, 0, 8, 197, 53, 83, 132, 84, 208, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 4, 95, 50, 77, 50, 47, 84, 6, 122, 34, 138, 15, 65, 6, 109, 72, 55, 57, 127, 50, 0, 0, 0, 12, 68, 8, 243, 12, 4, 71, 114, 55, 55, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 195, 190, 9, 14, 14, 76, 0, 7, 196, 77, 83, 85, 72, 76, 0, 0, 0, 0, 7, 196, 32, 147, 142, 36, 76, 0, 0, 0, 6, 195, 32, 149, 20, 76, 0, 0, 0, 0, 0, 9, 134, 13, 195, 173, 14, 1, 18, 76, 0, 0, 0, 0, 9, 134, 195, 161, 195, 176, 21, 18, 8, 0, 0, 0, 0, 0, 0, 5, 194, 21, 32, 72, 0, 0, 0, 0, 0, 6, 195, 21, 37, 0, 72, 0, 0, 8, 197, 32, 147, 142, 5, 32, 76, 0, 0, 6, 195, 56, 82, 64, 76, 0, 0, 0, 0, 0, 10, 135, 22, 5, 18, 195, 176, 21, 13, 72, 15, 4, 95, 4, 16, 20, 10, 49, 4, 114, 65, 65, 35, 10, 0, 0, 8, 133, 195, 190, 9, 20, 20, 76, 0, 0, 0, 6, 195, 56, 83, 65, 8, 0, 8, 197, 4, 227, 129, 73, 48, 8, 7, 132, 195, 190, 1, 21, 76, 7, 132, 195, 190, 1, 21, 72, 0, 0, 0, 0, 0, 9, 198, 56, 242, 203, 85, 35, 128, 76, 23, 4, 95, 51, 77, 50, 87, 138, 57, 6, 126, 34, 138, 15, 65, 6, 109, 72, 55, 57, 127, 50, 0, 0, 0, 7, 196, 32, 147, 137, 72, 76, 0, 10, 135, 22, 5, 18, 195, 176, 21, 18, 72, 0, 8, 133, 6, 195, 161, 21, 13, 76, 0, 0, 7, 196, 32, 19, 132, 4, 28, 0, 0, 0, 0, 7, 132, 8, 9, 195, 176, 76, 0, 0, 0, 7, 132, 195, 190, 9, 7, 76, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 28, 21, 0, 76, 0, 7, 132, 195, 161, 20, 20, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 20, 96, 76, 8, 0, 0, 8, 133, 13, 195, 173, 14, 21, 76, 0, 0, 0, 0, 0, 9, 134, 19, 195, 173, 14, 21, 13, 76, 0, 6, 195, 32, 17, 129, 72, 10, 135, 195, 190, 195, 173, 14, 21, 13, 76, 8, 133, 13, 195, 173, 14, 19, 76, 0, 0, 0, 0, 0, 10, 135, 6, 5, 14, 7, 21, 195, 176, 76, 0, 8, 132, 22, 9, 195, 176, 76, 28, 7, 132, 22, 9, 195, 176, 72, 0, 0, 0, 0, 8, 133, 7, 195, 161, 20, 21, 76, 0, 6, 195, 32, 147, 142, 76, 0, 0, 0, 8, 133, 13, 195, 173, 14, 1, 76, 0, 6, 195, 32, 19, 142, 72, 0, 6, 195, 32, 19, 129, 76, 0, 0, 0, 0, 6, 195, 32, 147, 129, 76, 0, 6, 195, 32, 147, 128, 76, 0, 0, 0, 6, 195, 88, 84, 129, 72, 0, 0, 7, 196, 32, 81, 149, 72, 72, 7, 196, 32, 147, 129, 72, 76, 0, 0, 0, 0, 0, 0, 6, 195, 32, 147, 149, 76, 0, 0, 0, 0, 0, 0, 11, 136, 22, 5, 18, 195, 176, 9, 195, 176, 72, 6, 195, 32, 147, 147, 76, 0, 0, 9, 134, 8, 1, 6, 9, 195, 176, 72, 0, 0, 0, 8, 197, 56, 242, 203, 72, 16, 76, 6, 195, 28, 85, 0, 76, 0, 0, 0, 8, 133, 19, 195, 173, 14, 1, 76, 0, 9, 134, 195, 190, 195, 173, 14, 1, 76, 0, 0, 8, 132, 8, 10, 195, 161, 76, 28, 0, 0, 0, 0, 0, 8, 133, 12, 195, 173, 11, 1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 24, 83, 135, 84, 76, 0, 10, 3, 95, 49, 6, 6, 123, 107, 72, 0, 0, 9, 134, 7, 5, 20, 9, 195, 176, 76, 0, 0, 8, 196, 20, 101, 9, 72, 76, 8, 0, 0, 0, 0, 0, 10, 3, 95, 50, 6, 47, 84, 6, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 51, 6, 87, 138, 57, 6, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 52, 6, 83, 57, 6, 120, 100, 117, 34, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 32, 147, 149, 52, 76, 0, 0, 6, 194, 20, 224, 76, 8, 0, 16, 3, 95, 51, 88, 87, 138, 57, 6, 126, 47, 37, 38, 4, 117, 0, 0, 15, 3, 95, 48, 67, 107, 6, 117, 50, 72, 14, 16, 117, 86, 0, 0, 9, 134, 195, 161, 20, 20, 21, 13, 76, 0, 0, 0, 0, 0, 0, 0, 20, 3, 95, 49, 67, 6, 123, 107, 72, 15, 107, 6, 117, 50, 72, 14, 51, 35, 86, 0, 0, 8, 197, 56, 242, 203, 85, 32, 76, 0, 0, 0, 9, 198, 56, 242, 203, 85, 37, 0, 76, 0, 0, 13, 3, 95, 49, 57, 50, 6, 108, 72, 57, 125, 50, 0, 0, 12, 3, 95, 49, 56, 6, 126, 72, 57, 125, 50, 0, 0, 7, 196, 88, 244, 129, 72, 76, 20, 3, 95, 50, 67, 47, 84, 6, 120, 15, 107, 6, 117, 50, 72, 14, 51, 117, 86, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 49, 49, 6, 111, 72, 55, 111, 84, 4, 117, 0, 0, 11, 3, 95, 49, 48, 47, 6, 108, 38, 117, 0, 0, 21, 3, 95, 51, 67, 87, 138, 57, 6, 116, 15, 107, 6, 117, 50, 72, 14, 51, 117, 86, 0, 14, 3, 95, 49, 51, 87, 138, 6, 111, 107, 72, 125, 50, 0, 0, 11, 3, 95, 49, 50, 47, 6, 127, 105, 83, 0, 0, 13, 3, 95, 49, 53, 83, 6, 109, 65, 47, 125, 50, 0, 0, 15, 3, 95, 49, 52, 83, 57, 6, 127, 34, 138, 47, 125, 50, 0, 0, 13, 3, 95, 49, 55, 89, 6, 130, 72, 57, 125, 50, 0, 0, 14, 3, 95, 49, 54, 89, 6, 111, 101, 89, 72, 125, 50, 0, 0, 11, 136, 195, 190, 5, 9, 18, 18, 1, 18, 76, 0, 15, 3, 95, 55, 88, 89, 57, 6, 120, 47, 37, 38, 4, 117, 0, 0, 9, 134, 195, 161, 20, 20, 9, 18, 76, 24, 3, 95, 52, 67, 83, 57, 6, 120, 100, 117, 34, 138, 15, 107, 6, 117, 50, 72, 14, 51, 117, 86, 0, 0, 0, 0, 0, 0, 0, 6, 195, 28, 85, 1, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 195, 190, 5, 9, 13, 76, 8, 133, 195, 190, 5, 9, 13, 76, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 50, 88, 47, 6, 117, 107, 72, 117, 100, 4, 117, 0, 0, 0, 0, 0, 0, 9, 134, 19, 195, 173, 14, 1, 18, 76, 0, 10, 135, 195, 190, 195, 173, 14, 1, 18, 76, 0, 0, 8, 133, 195, 190, 5, 9, 18, 76, 8, 133, 195, 190, 5, 9, 18, 72, 0, 7, 196, 33, 99, 210, 80, 8, 0, 0, 7, 132, 6, 195, 166, 18, 76, 0, 0, 12, 3, 95, 63, 63, 47, 6, 125, 81, 107, 134, 0, 0, 0, 0, 18, 3, 95, 52, 88, 83, 57, 6, 120, 16, 51, 117, 47, 4, 37, 38, 117, 0, 0, 0, 8, 197, 52, 147, 142, 5, 32, 76, 0, 0, 14, 6, 8, 1, 12, 12, 195, 179, 107, 35, 55, 55, 127, 0, 0, 0, 0, 0, 15, 3, 95, 53, 88, 83, 6, 109, 65, 47, 37, 38, 4, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 54, 88, 89, 6, 111, 101, 89, 72, 37, 38, 4, 117, 0, 0, 0, 0, 0, 7, 195, 76, 83, 64, 76, 28, 6, 195, 52, 149, 20, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 56, 88, 6, 125, 107, 72, 35, 47, 4, 37, 38, 117, 0, 0, 0, 0, 0, 10, 135, 14, 15, 11, 11, 21, 195, 176, 76, 0, 0, 0, 0, 16, 3, 95, 57, 88, 50, 6, 108, 38, 117, 47, 4, 37, 38, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 52, 147, 142, 76, 0, 0, 0, 9, 134, 13, 5, 195, 176, 1, 14, 8, 0, 0, 0, 0, 0, 0, 9, 134, 13, 21, 14, 9, 195, 176, 76, 9, 134, 22, 5, 18, 9, 195, 176, 72, 0, 0, 8, 133, 195, 190, 5, 19, 19, 76, 0, 7, 131, 195, 161, 14, 76, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 132, 8, 195, 186, 14, 72, 0, 0, 7, 196, 28, 85, 21, 52, 76, 0, 0, 15, 4, 95, 48, 77, 50, 65, 6, 109, 72, 55, 57, 127, 50, 0, 0, 0, 0, 14, 4, 95, 48, 77, 49, 87, 6, 116, 89, 117, 50, 72, 0, 0, 0, 0, 12, 68, 53, 147, 12, 4, 65, 109, 55, 55, 35, 0, 0, 0, 9, 198, 56, 242, 203, 72, 20, 128, 76, 0, 6, 195, 88, 244, 128, 76, 0, 7, 196, 28, 85, 21, 72, 76, 6, 195, 88, 244, 129, 76, 0, 0, 9, 198, 56, 242, 203, 72, 148, 128, 76, 6, 131, 195, 169, 7, 72, 0, 0, 8, 132, 13, 5, 195, 176, 76, 28, 0, 0, 0, 0, 0, 8, 133, 195, 190, 9, 195, 176, 72, 0, 0, 0, 6, 131, 14, 195, 169, 8, 0, 0, 0, 0, 7, 196, 88, 81, 206, 4, 8, 7, 196, 88, 81, 206, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 100, 178, 213, 72, 76, 7, 196, 60, 178, 213, 72, 76, 0, 6, 195, 28, 81, 206, 28, 0, 0, 0, 7, 196, 53, 83, 132, 36, 76, 0, 0, 0, 6, 195, 52, 145, 192, 76, 0, 6, 195, 20, 145, 193, 76, 0, 8, 197, 53, 83, 132, 37, 32, 76, 0, 0, 9, 134, 8, 1, 6, 195, 176, 9, 72, 0, 0, 8, 133, 22, 5, 18, 195, 176, 72, 0, 6, 194, 60, 112, 76, 8, 0, 6, 195, 88, 244, 148, 76, 0, 6, 195, 88, 244, 149, 72, 0, 0, 0, 0, 0, 6, 195, 88, 244, 142, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 3, 95, 195, 189, 6, 117, 83, 89, 37, 55, 114, 50, 15, 4, 108, 0, 0, 11, 136, 6, 18, 1, 13, 8, 10, 195, 161, 28, 0, 0, 9, 134, 22, 5, 18, 195, 176, 1, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 22, 1, 18, 195, 176, 72, 0, 0, 0, 7, 3, 95, 195, 173, 108, 0, 0, 0, 0, 0, 7, 196, 53, 83, 132, 84, 76, 0, 0, 8, 133, 21, 18, 195, 176, 21, 72, 0, 0, 6, 195, 21, 37, 21, 72, 0, 10, 135, 8, 1, 6, 195, 176, 9, 18, 72, 0, 0, 0, 7, 3, 95, 195, 161, 126, 0, 0, 0, 0, 0, 8, 133, 6, 195, 169, 11, 11, 76, 0, 0, 0, 0, 0, 0, 0, 9, 134, 195, 190, 5, 20, 20, 1, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 53, 83, 137, 72, 76, 0, 0, 0, 0, 0, 0, 0, 8, 133, 195, 190, 1, 14, 14, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 131, 195, 186, 18, 76, 28, 0, 0, 8, 133, 195, 190, 195, 173, 14, 76, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 21, 37, 64, 72, 0, 0, 0, 0, 0, 6, 195, 21, 37, 77, 72, 0, 10, 135, 195, 190, 5, 14, 14, 1, 14, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 195, 161, 126, 0, 14, 5, 130, 195, 161, 76, 6, 130, 195, 161, 76, 28, 0, 0, 0, 0, 7, 2, 195, 173, 108, 0, 14, 6, 130, 195, 173, 76, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 195, 176, 112, 86, 0, 0, 0, 11, 2, 195, 190, 87, 6, 114, 34, 72, 134, 0, 0, 0, 0, 17, 2, 195, 189, 6, 117, 83, 89, 37, 55, 114, 50, 15, 4, 108, 0, 14, 0, 0, 11, 136, 195, 190, 5, 19, 19, 1, 18, 9, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 88, 244, 149, 52, 72, 0, 0, 0, 8, 133, 195, 190, 195, 166, 18, 76, 12, 137, 195, 190, 5, 19, 19, 1, 18, 1, 18, 76, 8, 133, 195, 190, 195, 166, 18, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 88, 20, 147, 80, 72, 0, 0, 10, 135, 195, 190, 1, 14, 14, 9, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 195, 190, 5, 7, 1, 18, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 53, 147, 132, 36, 76, 0, 10, 135, 19, 195, 173, 195, 176, 1, 14, 8, 0, 0, 6, 195, 32, 81, 128, 72, 0, 0, 0, 0, 10, 135, 13, 25, 14, 4, 21, 195, 176, 76, 10, 135, 13, 21, 14, 4, 21, 195, 176, 76, 10, 135, 7, 195, 161, 20, 21, 195, 176, 76, 10, 135, 195, 161, 20, 20, 21, 195, 176, 76, 7, 195, 80, 147, 0, 76, 28, 7, 131, 1, 195, 176, 76, 28, 0, 0, 16, 2, 95, 25, 6, 117, 83, 89, 37, 55, 114, 50, 15, 4, 110, 0, 0, 0, 0, 0, 0, 0, 0, 13, 2, 95, 34, 79, 122, 89, 35, 55, 119, 107, 71, 0, 0, 23, 2, 95, 33, 6, 117, 107, 71, 138, 127, 48, 117, 50, 35, 51, 65, 4, 111, 34, 138, 49, 109, 0, 0, 0, 0, 13, 2, 95, 38, 115, 100, 65, 111, 34, 138, 49, 109, 0, 0, 10, 135, 195, 190, 5, 19, 19, 9, 18, 76, 0, 13, 2, 95, 36, 72, 6, 114, 72, 55, 35, 34, 138, 0, 24, 4, 95, 52, 77, 50, 83, 57, 6, 128, 16, 35, 34, 138, 15, 65, 6, 109, 72, 55, 57, 127, 50, 0, 0, 6, 195, 77, 99, 192, 8, 0, 14, 4, 95, 3, 1, 16, 89, 72, 6, 127, 34, 138, 72, 0, 0, 18, 2, 95, 41, 89, 84, 6, 110, 57, 109, 55, 6, 115, 49, 35, 89, 72, 0, 0, 10, 2, 95, 40, 89, 84, 110, 57, 109, 0, 0, 0, 15, 2, 95, 46, 48, 6, 40, 136, 107, 81, 72, 117, 34, 138, 0, 0, 15, 2, 95, 45, 71, 35, 50, 72, 89, 72, 34, 138, 109, 81, 0, 0, 11, 2, 95, 44, 49, 6, 114, 65, 65, 35, 0, 0, 6, 195, 88, 20, 128, 72, 11, 2, 95, 51, 87, 138, 6, 108, 34, 138, 0, 0, 11, 2, 95, 50, 72, 84, 6, 124, 34, 138, 0, 0, 9, 2, 95, 49, 6, 123, 72, 50, 0, 0, 9, 2, 95, 48, 50, 6, 40, 137, 0, 0, 9, 2, 95, 55, 89, 57, 6, 120, 0, 0, 10, 2, 95, 54, 89, 6, 112, 101, 89, 0, 0, 9, 2, 95, 53, 83, 6, 109, 65, 0, 0, 9, 134, 6, 195, 161, 9, 195, 176, 76, 14, 2, 95, 52, 83, 57, 6, 128, 16, 51, 109, 34, 138, 0, 0, 16, 2, 95, 59, 89, 6, 112, 65, 37, 49, 4, 114, 65, 65, 35, 0, 0, 18, 2, 95, 58, 72, 84, 6, 108, 48, 40, 136, 107, 81, 72, 117, 34, 138, 0, 0, 10, 2, 95, 57, 50, 6, 108, 38, 117, 0, 0, 9, 134, 13, 21, 14, 21, 195, 176, 76, 10, 2, 95, 56, 6, 125, 107, 72, 35, 0, 0, 23, 2, 95, 63, 89, 71, 6, 117, 34, 72, 134, 37, 68, 81, 4, 35, 65, 111, 34, 138, 49, 109, 0, 0, 20, 2, 95, 62, 6, 114, 72, 81, 55, 114, 84, 109, 55, 4, 115, 49, 35, 89, 72, 0, 0, 8, 197, 24, 83, 135, 84, 208, 76, 0, 12, 2, 95, 60, 114, 72, 81, 55, 114, 84, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 132, 6, 18, 195, 161, 76, 28, 0, 7, 196, 20, 145, 213, 52, 76, 0, 0, 7, 132, 195, 190, 195, 186, 72, 0, 0, 0, 0, 0, 0, 0, 7, 132, 195, 190, 195, 179, 8, 0, 0, 0, 0, 0, 0, 15, 2, 95, 91, 107, 114, 34, 72, 134, 81, 55, 114, 84, 109, 0, 0, 0, 0, 9, 134, 6, 195, 166, 18, 195, 176, 76, 0, 16, 2, 95, 95, 117, 50, 72, 109, 51, 89, 72, 34, 138, 109, 81, 0, 0, 0, 23, 2, 95, 93, 107, 6, 114, 34, 72, 134, 81, 55, 114, 84, 109, 55, 6, 115, 49, 35, 89, 72, 0, 0, 20, 2, 95, 92, 6, 120, 84, 117, 101, 72, 89, 49, 4, 125, 89, 72, 138, 109, 81, 0, 0, 0, 7, 196, 53, 147, 132, 84, 76, 0, 0, 0, 7, 132, 195, 190, 195, 161, 76, 7, 132, 195, 190, 195, 161, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 133, 195, 190, 22, 195, 173, 76, 8, 8, 133, 195, 190, 22, 195, 173, 76, 0, 0, 0, 0, 0, 0, 6, 195, 20, 178, 201, 76, 0, 0, 0, 0, 0, 15, 2, 95, 123, 89, 55, 130, 84, 117, 89, 84, 109, 57, 109, 0, 0, 0, 0, 6, 194, 84, 208, 76, 28, 0, 0, 0, 24, 2, 95, 125, 89, 55, 6, 130, 84, 117, 89, 84, 4, 109, 57, 109, 55, 6, 115, 49, 35, 89, 72, 0, 0, 0, 0, 0, 0, 10, 135, 8, 195, 182, 6, 195, 176, 21, 72, 6, 131, 19, 195, 161, 76, 10, 135, 195, 190, 5, 19, 19, 21, 13, 76, 0, 0, 0, 0, 0, 0, 0, 6, 131, 19, 195, 186, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 25, 32, 77, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 53, 147, 132, 84, 208, 76, 0, 0, 0, 0, 7, 195, 33, 97, 82, 76, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 132, 13, 195, 173, 14, 76, 0, 0, 0, 0, 7, 132, 19, 195, 173, 14, 76, 0, 0, 0, 0, 0, 11, 136, 8, 195, 182, 6, 195, 176, 21, 13, 72, 0, 0, 0, 0, 0, 8, 133, 195, 161, 20, 20, 9, 76, 0, 0, 0, 0, 8, 133, 195, 161, 20, 20, 21, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 21, 18, 195, 176, 21, 13, 72, 0, 0, 6, 195, 76, 149, 20, 76, 0, 0, 10, 135, 195, 190, 5, 19, 19, 1, 18, 76, 0, 0, 0, 7, 196, 53, 83, 149, 52, 76, 7, 196, 53, 83, 149, 52, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 22, 15, 18, 21, 195, 176, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 18, 66, 195, 173, 0, 195, 189, 0, 195, 166, 0, 101, 0, 105, 0, 121, 0, 106, 0, 7, 6, 18, 67, 195, 190, 0, 99, 0, 102, 0, 104, 0, 107, 0, 112, 0, 116, 0, 120, 0, 115, 0, 7, 6, 18, 68, 112, 0, 116, 0, 107, 0, 7, 6, 20, 0, 0, 0, 120, 0, 0, 0, 120, 0, 122, 0, 0, 0, 0, 0, 6, 195, 161, 0, 2, 17, 67, 17, 67, 3, 125, 0, 4, 3, 126, 0, 2, 17, 69, 17, 68, 0, 7, 6, 195, 166, 0, 2, 17, 67, 17, 67, 3, 121, 0, 4, 3, 122, 0, 2, 17, 69, 17, 68, 0, 7, 6, 195, 169, 0, 2, 17, 67, 17, 67, 3, 57, 111, 0, 4, 3, 57, 112, 0, 2, 17, 69, 17, 68, 0, 7, 6, 195, 173, 0, 2, 17, 67, 17, 67, 3, 37, 0, 4, 3, 108, 0, 2, 17, 69, 17, 68, 0, 7, 6, 195, 176, 0, 3, 86, 0, 4, 2, 17, 66, 3, 87, 0, 2, 32, 32, 0, 7, 6, 195, 179, 0, 2, 17, 67, 17, 67, 3, 127, 0, 4, 3, 128, 0, 2, 17, 69, 17, 68, 0, 7, 6, 195, 182, 0, 8, 2, 21, 14, 128, 132, 129, 3, 4, 120, 0, 2, 17, 67, 17, 67, 3, 119, 0, 4, 3, 120, 0, 2, 17, 69, 17, 68, 0, 4, 2, 110, 103, 3, 129, 0, 2, 110, 103, 0, 7, 6, 195, 186, 0, 2, 17, 67, 17, 67, 3, 40, 0, 4, 3, 116, 0, 2, 17, 69, 17, 68, 0, 7, 6, 195, 189, 0, 2, 17, 67, 17, 67, 3, 37, 0, 4, 3, 108, 0, 2, 17, 69, 17, 68, 0, 7, 6, 195, 190, 0, 3, 87, 0, 7, 6, 97, 0, 108, 8, 2, 21, 14, 128, 132, 130, 3, 4, 113, 55, 0, 4, 2, 17, 67, 17, 67, 3, 35, 0, 8, 2, 108, 108, 12, 0, 4, 3, 113, 0, 2, 17, 69, 17, 68, 0, 4, 2, 110, 103, 3, 125, 0, 2, 110, 107, 0, 117, 2, 17, 67, 17, 67, 3, 129, 0, 4, 117, 3, 130, 0, 117, 2, 17, 69, 17, 68, 0, 7, 6, 98, 0, 4, 3, 71, 0, 98, 0, 7, 6, 99, 0, 3, 49, 0, 4, 2, 101, 3, 89, 0, 2, 105, 0, 7, 6, 100, 0, 4, 3, 72, 0, 100, 0, 7, 6, 101, 0, 2, 17, 67, 17, 67, 3, 111, 0, 4, 3, 112, 0, 2, 17, 69, 17, 68, 0, 4, 2, 110, 103, 3, 123, 0, 2, 110, 107, 0, 105, 2, 17, 67, 17, 67, 0, 121, 2, 17, 67, 17, 67, 0, 4, 105, 3, 124, 0, 105, 2, 17, 69, 17, 68, 0, 121, 0, 121, 2, 17, 69, 17, 68, 0, 103, 105, 3, 124, 57, 109, 0, 7, 6, 102, 0, 110, 100, 3, 65, 47, 0, 4, 1, 21, 2, 108, 3, 71, 0, 1, 21, 2, 110, 0, 4, 3, 83, 0, 102, 0, 4, 1, 17, 65, 2, 17, 65, 3, 84, 0, 1, 108, 2, 17, 65, 0, 110, 116, 3, 133, 71, 47, 0, 7, 6, 103, 0, 4, 1, 161, 195, 2, 97, 3, 0, 4, 1, 161, 195, 2, 117, 3, 0, 4, 1, 179, 195, 2, 97, 3, 0, 4, 1, 179, 195, 2, 117, 3, 0, 4, 1, 186, 195, 2, 97, 3, 0, 1, 186, 195, 2, 117, 3, 0, 4, 1, 17, 65, 2, 105, 3, 57, 0, 1, 17, 65, 2, 106, 0, 4, 2, 105, 3, 79, 0, 8, 2, 101, 0, 8, 2, 105, 0, 8, 2, 195, 166, 0, 8, 2, 195, 173, 0, 106, 0, 106, 8, 0, 4, 3, 81, 0, 1, 17, 65, 2, 108, 0, 1, 17, 65, 2, 110, 0, 8, 0, 103, 0, 110, 2, 32, 3, 81, 134, 0, 4, 1, 17, 65, 2, 97, 3, 100, 0, 1, 17, 65, 2, 114, 0, 1, 17, 65, 2, 117, 0, 1, 17, 65, 2, 195, 176, 0, 4, 2, 32, 3, 101, 0, 2, 115, 0, 116, 3, 101, 72, 0, 7, 6, 104, 0, 118, 3, 49, 84, 0, 106, 3, 99, 0, 108, 3, 105, 0, 3, 107, 0, 110, 3, 107, 134, 0, 114, 3, 107, 138, 0, 7, 6, 105, 0, 4, 1, 25, 2, 110, 103, 3, 37, 0, 1, 25, 2, 110, 107, 0, 2, 17, 67, 17, 67, 3, 109, 0, 4, 3, 110, 0, 2, 17, 69, 17, 68, 0, 7, 6, 106, 0, 3, 57, 0, 7, 6, 107, 0, 2, 116, 3, 47, 0, 8, 3, 49, 0, 2, 18, 66, 3, 79, 0, 4, 8, 2, 18, 66, 3, 80, 0, 106, 0, 4, 3, 81, 0, 2, 25, 0, 2, 115, 3, 101, 0, 2, 107, 3, 107, 0, 7, 6, 108, 0, 3, 55, 0, 108, 3, 72, 55, 0, 4, 2, 17, 66, 29, 3, 105, 0, 2, 32, 0, 4, 108, 2, 17, 66, 29, 3, 137, 0, 108, 2, 32, 0, 7, 6, 109, 0, 4, 3, 65, 0, 109, 2, 25, 0, 1, 17, 66, 3, 107, 133, 0, 2, 18, 68, 3, 133, 0, 7, 6, 110, 0, 4, 3, 50, 0, 110, 2, 25, 0, 110, 3, 50, 12, 0, 2, 103, 105, 3, 67, 0, 2, 103, 3, 68, 0, 103, 2, 32, 3, 68, 81, 0, 4, 110, 1, 105, 101, 3, 72, 50, 0, 110, 1, 117, 97, 0, 110, 1, 121, 101, 0, 110, 1, 161, 195, 0, 110, 1, 166, 195, 0, 110, 1, 169, 195, 0, 110, 1, 173, 195, 0, 110, 1, 179, 195, 0, 110, 1, 186, 195, 0, 110, 1, 189, 195, 0, 1, 17, 66, 3, 107, 134, 0, 2, 18, 68, 3, 134, 0, 107, 2, 105, 3, 135, 79, 0, 2, 107, 3, 136, 0, 103, 116, 2, 25, 3, 136, 72, 0, 1, 17, 65, 2, 107, 3, 136, 107, 0, 7, 6, 111, 0, 2, 17, 67, 17, 67, 3, 114, 0, 4, 3, 115, 0, 2, 17, 69, 17, 68, 0, 4, 2, 110, 103, 3, 127, 0, 2, 110, 107, 0, 4, 2, 103, 105, 3, 131, 0, 2, 103, 106, 0, 7, 6, 112, 0, 8, 3, 48, 0, 3, 71, 0, 4, 2, 107, 3, 83, 0, 2, 115, 0, 2, 116, 0, 112, 3, 107, 71, 0, 7, 6, 113, 0, 3, 49, 84, 0, 7, 6, 114, 0, 1, 17, 67, 3, 14, 51, 0, 1, 17, 65, 2, 17, 65, 3, 16, 51, 0, 2, 32, 3, 23, 51, 0, 4, 3, 23, 52, 0, 8, 0, 2, 18, 67, 3, 34, 138, 0, 114, 3, 51, 16, 51, 0, 110, 3, 51, 72, 134, 0, 108, 2, 17, 66, 3, 51, 137, 0, 1, 108, 3, 69, 51, 0, 108, 3, 72, 55, 0, 7, 6, 115, 0, 3, 89, 0, 115, 3, 89, 139, 0, 4, 104, 2, 32, 3, 91, 0, 104, 8, 0, 7, 6, 116, 0, 8, 3, 47, 0, 3, 72, 0, 4, 104, 2, 32, 3, 87, 0, 104, 8, 0, 4, 2, 108, 3, 107, 72, 0, 2, 110, 0, 116, 0, 7, 6, 117, 0, 4, 1, 25, 2, 110, 103, 3, 40, 0, 1, 25, 2, 110, 107, 0, 1, 21, 2, 110, 117, 109, 32, 3, 114, 0, 2, 17, 67, 17, 67, 3, 117, 0, 4, 3, 118, 0, 2, 17, 69, 17, 68, 0, 4, 2, 103, 105, 3, 132, 0, 2, 103, 106, 0, 7, 6, 118, 0, 3, 84, 0, 7, 6, 119, 0, 3, 84, 0, 7, 6, 120, 0, 4, 3, 49, 89, 0, 122, 0, 7, 6, 121, 0, 4, 1, 25, 2, 110, 103, 3, 37, 0, 1, 25, 2, 110, 107, 0, 2, 17, 67, 17, 67, 3, 109, 0, 4, 3, 110, 0, 2, 17, 69, 17, 68, 0, 7, 6, 122, 0, 122, 3, 47, 89, 0, 3, 88, 0, 7, 6, 0, 36, 3, 72, 114, 55, 55, 35, 34, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts28 = FileInMemory_createWithData (5468, reinterpret_cast (&espeakdata_dicts28_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/is_dict", U"is"); Collection_addItem (me.peek(), espeakdata_dicts28.transfer()); static unsigned char espeakdata_dicts29_data[43393] = { 0, 4, 0, 0, 251, 159, 0, 0, 0, 9, 198, 5, 97, 86, 4, 227, 192, 72, 17, 70, 88, 16, 213, 60, 195, 192, 84, 35, 49, 6, 40, 110, 55, 39, 0, 0, 10, 199, 56, 80, 210, 60, 195, 199, 36, 20, 0, 6, 195, 52, 83, 128, 21, 0, 6, 195, 60, 35, 9, 66, 0, 7, 65, 4, 35, 12, 0, 14, 4, 193, 4, 72, 9, 197, 64, 244, 144, 61, 32, 65, 21, 9, 198, 8, 192, 83, 24, 83, 64, 20, 0, 9, 198, 80, 144, 149, 72, 243, 128, 67, 10, 198, 80, 83, 5, 28, 243, 128, 66, 20, 9, 198, 76, 147, 131, 72, 243, 128, 65, 9, 198, 5, 48, 193, 48, 17, 128, 66, 9, 198, 4, 229, 9, 24, 243, 128, 66, 0, 10, 199, 88, 243, 20, 4, 209, 84, 72, 66, 10, 199, 80, 84, 1, 56, 80, 200, 36, 20, 10, 199, 64, 192, 78, 36, 209, 84, 72, 66, 10, 199, 64, 83, 148, 4, 209, 84, 72, 66, 9, 198, 60, 211, 212, 80, 84, 137, 20, 10, 199, 52, 147, 12, 36, 209, 84, 72, 66, 6, 195, 48, 240, 128, 20, 9, 198, 37, 51, 212, 80, 84, 137, 20, 9, 198, 29, 32, 84, 80, 84, 137, 66, 10, 199, 12, 83, 148, 36, 209, 84, 72, 66, 0, 9, 198, 76, 245, 20, 61, 163, 206, 20, 7, 196, 72, 144, 133, 12, 20, 12, 200, 64, 84, 143, 56, 244, 208, 61, 32, 67, 20, 0, 6, 65, 8, 71, 37, 0, 13, 202, 16, 144, 201, 4, 227, 143, 88, 84, 201, 52, 20, 9, 197, 12, 243, 147, 60, 224, 65, 20, 8, 197, 12, 148, 205, 60, 224, 66, 9, 197, 12, 83, 148, 36, 224, 65, 20, 8, 197, 12, 20, 140, 36, 224, 66, 0, 9, 198, 72, 144, 207, 88, 84, 128, 66, 0, 9, 198, 65, 35, 211, 12, 83, 137, 20, 11, 199, 64, 84, 147, 20, 99, 206, 20, 66, 20, 0, 9, 198, 76, 241, 199, 36, 244, 142, 21, 9, 198, 4, 197, 15, 24, 244, 142, 21, 0, 6, 65, 12, 76, 37, 0, 8, 197, 88, 86, 154, 20, 224, 65, 8, 197, 72, 83, 132, 36, 224, 65, 8, 197, 12, 244, 142, 20, 240, 65, 8, 197, 12, 243, 15, 72, 224, 21, 8, 197, 12, 149, 137, 48, 80, 66, 8, 197, 8, 244, 142, 20, 240, 65, 0, 9, 198, 88, 144, 68, 61, 69, 0, 21, 9, 198, 52, 17, 199, 36, 244, 128, 21, 9, 198, 48, 21, 20, 61, 50, 64, 20, 9, 198, 12, 20, 9, 56, 84, 128, 21, 0, 13, 4, 95, 8, 1, 3, 107, 6, 35, 76, 36, 49, 0, 6, 195, 80, 241, 128, 20, 10, 199, 24, 147, 1, 80, 83, 9, 4, 68, 10, 199, 16, 148, 204, 21, 52, 201, 4, 67, 0, 11, 200, 64, 20, 133, 77, 65, 83, 36, 80, 68, 7, 196, 48, 145, 86, 20, 20, 7, 196, 40, 84, 207, 48, 20, 11, 200, 20, 211, 196, 36, 19, 9, 76, 144, 67, 11, 200, 13, 84, 150, 36, 194, 78, 20, 240, 67, 0, 6, 65, 16, 72, 37, 0, 12, 201, 76, 19, 148, 4, 32, 82, 8, 20, 128, 67, 8, 197, 69, 80, 76, 61, 32, 21, 9, 197, 64, 84, 137, 21, 32, 65, 21, 6, 195, 52, 83, 142, 21, 8, 197, 21, 2, 82, 61, 64, 20, 8, 197, 16, 148, 133, 81, 64, 20, 0, 6, 195, 77, 3, 211, 20, 9, 198, 76, 244, 130, 37, 67, 204, 67, 0, 12, 201, 81, 84, 130, 61, 97, 78, 80, 243, 0, 20, 10, 198, 61, 69, 5, 56, 84, 133, 67, 21, 10, 199, 56, 244, 141, 4, 225, 9, 4, 67, 9, 198, 52, 148, 197, 72, 84, 133, 67, 0, 11, 200, 52, 243, 148, 20, 51, 211, 5, 32, 67, 0, 7, 65, 20, 36, 12, 0, 14, 5, 193, 20, 72, 8, 6, 195, 80, 243, 142, 21, 8, 197, 36, 194, 5, 85, 48, 21, 16, 69, 29, 80, 73, 56, 16, 81, 58, 35, 6, 37, 12, 50, 35, 0, 8, 197, 16, 145, 83, 37, 48, 20, 12, 201, 12, 19, 80, 60, 64, 82, 76, 81, 192, 67, 0, 6, 195, 21, 0, 64, 20, 9, 198, 64, 19, 12, 5, 99, 204, 67, 10, 198, 36, 225, 5, 8, 149, 0, 66, 21, 9, 198, 24, 147, 15, 76, 241, 128, 66, 9, 198, 21, 0, 82, 12, 130, 65, 67, 9, 198, 21, 0, 71, 56, 85, 76, 65, 9, 198, 20, 227, 129, 28, 243, 128, 66, 0, 6, 195, 100, 241, 0, 20, 10, 199, 81, 32, 84, 4, 194, 65, 76, 67, 10, 199, 52, 83, 132, 20, 193, 86, 36, 20, 10, 199, 52, 19, 77, 36, 97, 82, 36, 66, 10, 199, 48, 144, 193, 57, 68, 143, 64, 66, 6, 195, 25, 35, 196, 20, 0, 11, 67, 69, 82, 65, 49, 58, 6, 37, 35, 0, 11, 200, 12, 243, 143, 76, 49, 82, 48, 16, 66, 6, 195, 80, 243, 137, 20, 7, 196, 72, 145, 83, 36, 20, 0, 8, 65, 24, 36, 83, 83, 36, 0, 8, 197, 88, 243, 19, 12, 144, 20, 8, 197, 77, 1, 67, 36, 80, 20, 8, 197, 76, 83, 137, 48, 80, 66, 8, 197, 52, 84, 211, 36, 16, 66, 8, 197, 52, 84, 143, 64, 80, 65, 8, 197, 48, 241, 199, 36, 16, 20, 8, 197, 48, 147, 79, 56, 80, 20, 9, 197, 44, 20, 129, 80, 80, 67, 20, 8, 197, 24, 241, 199, 36, 16, 20, 8, 197, 21, 67, 201, 48, 80, 65, 8, 197, 5, 64, 76, 36, 16, 67, 8, 197, 4, 229, 15, 56, 144, 20, 0, 9, 198, 77, 84, 16, 61, 53, 0, 21, 9, 198, 52, 17, 206, 21, 50, 64, 20, 9, 198, 12, 20, 147, 60, 194, 64, 66, 9, 198, 4, 224, 76, 37, 50, 64, 66, 0, 10, 198, 88, 19, 19, 21, 50, 65, 66, 20, 10, 198, 52, 17, 206, 21, 50, 65, 66, 20, 10, 199, 36, 212, 5, 72, 97, 84, 80, 20, 9, 198, 16, 148, 212, 60, 226, 65, 67, 9, 198, 12, 83, 143, 52, 19, 137, 66, 6, 195, 9, 35, 196, 20, 9, 198, 4, 208, 90, 104, 243, 137, 66, 0, 7, 196, 64, 193, 83, 36, 20, 9, 198, 21, 81, 197, 56, 243, 0, 68, 11, 200, 12, 20, 15, 48, 149, 133, 72, 144, 67, 0, 6, 65, 28, 75, 37, 0, 8, 197, 52, 243, 129, 16, 80, 65, 8, 197, 24, 244, 16, 60, 192, 20, 8, 197, 24, 19, 5, 12, 144, 20, 8, 197, 20, 195, 1, 16, 80, 65, 9, 198, 4, 229, 9, 17, 35, 199, 20, 0, 13, 202, 77, 3, 1, 56, 51, 143, 64, 193, 85, 72, 67, 6, 195, 48, 243, 135, 20, 10, 198, 37, 51, 208, 80, 84, 128, 66, 20, 9, 198, 4, 224, 66, 5, 50, 64, 66, 0, 14, 203, 88, 147, 12, 5, 96, 76, 48, 83, 15, 56, 112, 20, 10, 199, 81, 33, 78, 80, 84, 201, 52, 20, 6, 195, 80, 243, 128, 20, 10, 199, 80, 83, 5, 12, 19, 69, 72, 67, 6, 195, 16, 243, 128, 21, 10, 199, 12, 21, 5, 12, 129, 83, 36, 20, 9, 198, 4, 208, 90, 104, 243, 133, 66, 0, 11, 200, 77, 84, 5, 73, 53, 9, 80, 80, 66, 11, 200, 52, 147, 12, 20, 99, 199, 48, 144, 20, 6, 195, 16, 243, 129, 66, 11, 200, 12, 243, 148, 72, 17, 82, 20, 240, 67, 0, 8, 65, 32, 35, 49, 12, 35, 0, 12, 201, 12, 20, 212, 72, 243, 9, 8, 84, 128, 67, 0, 9, 198, 64, 243, 9, 28, 243, 128, 66, 9, 198, 52, 16, 195, 32, 147, 128, 65, 9, 198, 5, 4, 137, 12, 83, 128, 21, 0, 6, 195, 80, 244, 132, 21, 6, 195, 48, 244, 132, 21, 0, 8, 196, 56, 83, 12, 4, 72, 28, 15, 1, 35, 49, 35, 50, 76, 36, 55, 55, 36, 47, 12, 39, 0, 7, 196, 64, 243, 12, 36, 20, 7, 196, 56, 81, 213, 76, 20, 6, 195, 52, 84, 137, 66, 7, 196, 48, 147, 12, 4, 66, 6, 195, 5, 67, 205, 65, 0, 6, 195, 5, 67, 206, 65, 7, 65, 36, 37, 12, 0, 14, 5, 193, 36, 72, 9, 8, 197, 88, 147, 131, 37, 64, 65, 8, 197, 76, 147, 12, 4, 32, 65, 6, 195, 64, 246, 154, 21, 6, 195, 5, 67, 206, 66, 0, 15, 1, 37, 48, 36, 14, 16, 76, 6, 36, 50, 47, 39, 0, 27, 9, 198, 81, 34, 71, 48, 145, 128, 65, 9, 198, 8, 20, 207, 16, 147, 128, 66, 9, 198, 5, 32, 207, 76, 83, 128, 21, 0, 6, 1, 38, 10, 36, 0, 10, 199, 80, 16, 200, 36, 209, 84, 72, 66, 9, 198, 76, 98, 78, 80, 84, 133, 66, 10, 199, 65, 35, 211, 36, 81, 213, 60, 20, 0, 6, 195, 80, 244, 129, 66, 7, 196, 64, 83, 142, 20, 21, 0, 8, 65, 40, 75, 36, 12, 57, 0, 6, 195, 80, 244, 130, 21, 9, 198, 64, 83, 1, 88, 84, 135, 21, 8, 197, 12, 148, 15, 48, 192, 21, 8, 197, 4, 212, 15, 48, 192, 21, 0, 9, 198, 76, 115, 205, 8, 84, 128, 65, 10, 198, 72, 240, 149, 72, 83, 148, 67, 20, 9, 198, 72, 147, 66, 61, 36, 192, 21, 9, 198, 64, 20, 1, 88, 84, 128, 66, 7, 195, 12, 148, 143, 66, 20, 0, 14, 1, 42, 35, 89, 47, 36, 51, 37, 89, 49, 39, 0, 27, 10, 199, 77, 68, 129, 64, 147, 205, 8, 21, 9, 198, 60, 224, 207, 28, 83, 133, 67, 9, 198, 16, 148, 208, 20, 225, 9, 20, 0, 8, 1, 43, 48, 57, 40, 0, 27, 7, 196, 80, 19, 9, 4, 66, 7, 196, 64, 243, 9, 4, 66, 7, 196, 52, 81, 9, 4, 20, 0, 8, 197, 36, 225, 15, 48, 240, 66, 9, 65, 44, 49, 35, 48, 12, 35, 0, 8, 197, 80, 84, 133, 9, 32, 65, 9, 197, 76, 193, 83, 36, 16, 65, 20, 8, 197, 48, 148, 212, 60, 224, 66, 8, 197, 21, 51, 206, 21, 32, 66, 8, 197, 8, 246, 154, 60, 192, 20, 0, 6, 195, 48, 244, 143, 72, 7, 195, 48, 244, 143, 76, 9, 9, 198, 16, 83, 9, 8, 84, 128, 66, 0, 10, 1, 46, 48, 40, 50, 47, 39, 0, 27, 10, 199, 69, 80, 78, 80, 243, 69, 56, 21, 9, 198, 60, 224, 207, 28, 83, 137, 67, 0, 9, 1, 47, 89, 55, 35, 91, 0, 27, 7, 196, 80, 83, 137, 4, 20, 7, 196, 76, 145, 80, 20, 20, 8, 196, 76, 83, 142, 60, 66, 20, 7, 196, 76, 16, 133, 36, 66, 11, 200, 64, 21, 15, 28, 83, 133, 76, 144, 67, 11, 200, 53, 85, 1, 28, 83, 133, 76, 144, 67, 7, 196, 52, 17, 137, 4, 65, 11, 200, 25, 32, 84, 21, 35, 137, 80, 16, 68, 11, 200, 21, 52, 15, 76, 147, 69, 81, 32, 67, 11, 200, 12, 20, 18, 36, 99, 199, 48, 144, 20, 0, 8, 65, 48, 109, 55, 55, 36, 0, 8, 197, 36, 228, 197, 81, 64, 20, 0, 9, 198, 64, 20, 129, 8, 244, 132, 21, 0, 6, 195, 69, 81, 76, 72, 10, 199, 88, 83, 131, 21, 51, 1, 60, 67, 10, 199, 12, 243, 80, 4, 115, 137, 4, 67, 0, 8, 196, 56, 83, 12, 20, 72, 28, 11, 200, 16, 244, 16, 36, 244, 5, 81, 64, 20, 7, 196, 5, 32, 66, 36, 65, 0, 8, 65, 52, 109, 65, 65, 36, 0, 8, 197, 12, 195, 196, 36, 16, 20, 0, 9, 198, 53, 85, 1, 28, 83, 128, 66, 12, 201, 24, 244, 129, 52, 147, 137, 24, 84, 137, 68, 9, 198, 16, 148, 25, 48, 243, 128, 65, 0, 10, 199, 72, 150, 154, 36, 51, 206, 36, 66, 6, 195, 52, 83, 148, 21, 6, 195, 52, 83, 148, 21, 0, 10, 67, 69, 81, 73, 49, 122, 36, 57, 0, 7, 196, 72, 243, 154, 36, 66, 7, 196, 72, 240, 130, 36, 20, 7, 196, 72, 16, 130, 36, 66, 7, 196, 64, 193, 85, 72, 65, 7, 196, 52, 84, 197, 72, 65, 7, 196, 36, 225, 84, 80, 20, 10, 198, 16, 80, 197, 8, 19, 0, 66, 20, 7, 196, 8, 240, 130, 36, 20, 0, 8, 197, 24, 16, 197, 88, 144, 76, 8, 65, 56, 109, 50, 50, 36, 0, 8, 197, 64, 83, 15, 64, 80, 65, 0, 9, 198, 28, 197, 67, 61, 50, 64, 20, 9, 198, 13, 33, 77, 37, 50, 64, 65, 0, 14, 1, 58, 72, 4, 40, 36, 48, 6, 40, 50, 47, 37, 0, 10, 199, 77, 81, 4, 36, 16, 207, 56, 66, 10, 199, 65, 33, 68, 36, 193, 84, 80, 20, 9, 198, 5, 49, 137, 77, 50, 65, 67, 0, 11, 200, 28, 147, 143, 28, 83, 133, 76, 144, 67, 9, 198, 20, 193, 77, 61, 50, 78, 67, 0, 7, 65, 60, 110, 12, 0, 14, 9, 198, 64, 84, 148, 4, 229, 15, 8, 5, 193, 60, 72, 8, 9, 198, 81, 32, 83, 12, 244, 147, 21, 8, 197, 76, 99, 199, 28, 144, 20, 8, 197, 76, 83, 5, 56, 144, 20, 8, 197, 64, 147, 1, 16, 80, 65, 8, 197, 52, 145, 15, 48, 192, 21, 8, 197, 52, 19, 132, 20, 144, 66, 8, 197, 36, 229, 18, 36, 112, 66, 8, 197, 25, 80, 201, 48, 80, 66, 8, 197, 16, 83, 5, 8, 144, 20, 8, 197, 12, 147, 133, 76, 144, 20, 0, 11, 1, 61, 40, 81, 58, 35, 55, 36, 0, 27, 6, 195, 61, 0, 67, 66, 9, 198, 52, 243, 143, 24, 244, 128, 66, 9, 198, 48, 243, 137, 12, 84, 128, 66, 9, 198, 16, 144, 83, 64, 244, 128, 66, 0, 9, 198, 81, 34, 67, 21, 50, 77, 20, 10, 199, 12, 83, 148, 72, 243, 69, 72, 66, 0, 9, 198, 72, 85, 9, 56, 243, 0, 67, 11, 200, 24, 149, 15, 12, 83, 143, 76, 144, 21, 9, 198, 12, 192, 85, 76, 243, 0, 65, 9, 198, 5, 3, 211, 81, 35, 198, 66, 7, 196, 4, 192, 133, 16, 20, 0, 13, 1, 64, 49, 37, 6, 39, 76, 12, 39, 55, 35, 0, 13, 1, 64, 49, 37, 6, 39, 76, 12, 39, 55, 35, 0, 6, 65, 64, 48, 37, 0, 0, 9, 198, 64, 81, 1, 88, 83, 128, 21, 10, 198, 61, 33, 193, 56, 243, 128, 65, 21, 9, 198, 52, 21, 1, 64, 19, 128, 67, 9, 198, 37, 51, 211, 64, 147, 128, 67, 0, 9, 198, 4, 210, 76, 12, 20, 133, 66, 0, 0, 6, 65, 68, 49, 40, 0, 9, 198, 72, 80, 201, 65, 35, 195, 66, 6, 195, 52, 86, 154, 20, 8, 197, 9, 32, 68, 37, 0, 65, 0, 0, 7, 195, 84, 224, 64, 72, 9, 6, 195, 60, 34, 84, 65, 0, 8, 196, 76, 83, 15, 56, 66, 20, 7, 196, 61, 48, 193, 72, 20, 7, 196, 12, 240, 129, 76, 20, 7, 196, 4, 192, 133, 72, 65, 0, 8, 65, 72, 109, 51, 16, 36, 0, 8, 197, 64, 84, 132, 60, 224, 21, 8, 197, 52, 19, 16, 20, 192, 21, 0, 9, 198, 88, 19, 19, 20, 48, 192, 21, 6, 195, 80, 240, 195, 21, 9, 198, 64, 244, 201, 48, 194, 80, 66, 9, 198, 4, 229, 5, 72, 244, 192, 65, 0, 9, 198, 77, 1, 67, 84, 197, 77, 65, 10, 199, 76, 84, 150, 60, 100, 133, 56, 21, 10, 199, 72, 240, 195, 5, 49, 67, 12, 21, 10, 199, 52, 243, 143, 4, 192, 133, 72, 67, 10, 199, 24, 197, 77, 20, 225, 15, 76, 20, 0, 7, 196, 4, 32, 137, 4, 76, 12, 200, 80, 83, 5, 56, 49, 70, 4, 192, 67, 20, 7, 196, 76, 19, 13, 36, 66, 12, 200, 52, 84, 197, 56, 49, 70, 4, 192, 67, 20, 6, 195, 16, 241, 197, 20, 0, 8, 65, 76, 36, 89, 89, 36, 0, 9, 198, 77, 64, 77, 8, 80, 195, 21, 12, 201, 65, 35, 208, 20, 65, 85, 80, 144, 192, 67, 8, 197, 52, 20, 141, 61, 32, 65, 8, 197, 28, 85, 20, 37, 64, 65, 6, 195, 20, 97, 66, 20, 8, 197, 12, 83, 66, 4, 192, 65, 8, 197, 12, 19, 129, 4, 224, 65, 8, 197, 12, 19, 9, 9, 32, 65, 8, 197, 8, 21, 20, 37, 64, 65, 8, 197, 8, 20, 130, 21, 32, 65, 0, 8, 197, 77, 0, 84, 60, 192, 65, 8, 197, 77, 0, 76, 5, 64, 65, 9, 198, 77, 0, 71, 56, 243, 0, 66, 12, 201, 77, 0, 67, 12, 19, 129, 64, 243, 9, 67, 11, 200, 77, 0, 67, 12, 17, 143, 72, 224, 21, 9, 198, 65, 33, 70, 21, 69, 0, 20, 9, 198, 64, 147, 194, 8, 144, 192, 21, 7, 195, 20, 225, 71, 65, 20, 10, 198, 16, 145, 1, 12, 129, 64, 67, 20, 9, 198, 12, 83, 12, 60, 193, 64, 21, 9, 198, 4, 147, 15, 12, 129, 64, 20, 0, 6, 195, 80, 241, 192, 20, 6, 195, 48, 241, 192, 20, 6, 195, 36, 211, 204, 65, 10, 199, 12, 19, 80, 4, 115, 143, 48, 67, 0, 11, 200, 64, 84, 141, 4, 100, 143, 77, 64, 65, 7, 196, 61, 32, 201, 4, 21, 7, 196, 21, 100, 143, 76, 20, 7, 196, 12, 241, 15, 48, 21, 0, 6, 65, 80, 47, 37, 0, 10, 198, 80, 84, 143, 48, 65, 71, 66, 20, 8, 197, 80, 20, 148, 5, 32, 65, 8, 197, 77, 81, 5, 77, 64, 66, 6, 195, 76, 147, 206, 66, 8, 197, 72, 148, 15, 77, 64, 21, 8, 197, 65, 35, 212, 37, 32, 65, 8, 197, 64, 84, 146, 21, 32, 66, 9, 198, 52, 86, 154, 4, 225, 71, 66, 8, 197, 36, 229, 5, 29, 32, 65, 8, 197, 21, 100, 133, 85, 128, 65, 8, 197, 16, 84, 15, 77, 64, 21, 8, 197, 12, 244, 146, 21, 32, 66, 8, 197, 8, 148, 15, 77, 64, 21, 0, 9, 198, 81, 34, 80, 60, 65, 64, 65, 10, 198, 28, 147, 214, 4, 225, 64, 65, 21, 9, 198, 12, 243, 134, 36, 225, 64, 66, 9, 198, 12, 131, 210, 104, 245, 192, 66, 13, 202, 12, 130, 85, 76, 21, 133, 12, 50, 9, 4, 20, 13, 202, 8, 19, 14, 20, 245, 5, 72, 20, 9, 4, 70, 0, 6, 195, 76, 147, 192, 66, 10, 199, 76, 147, 131, 72, 243, 137, 4, 67, 9, 198, 64, 84, 195, 32, 144, 201, 20, 10, 199, 64, 19, 1, 28, 243, 137, 4, 68, 9, 198, 52, 240, 207, 56, 84, 201, 66, 6, 195, 21, 83, 128, 65, 9, 198, 20, 211, 211, 80, 20, 201, 66, 10, 199, 12, 147, 195, 36, 20, 137, 4, 67, 10, 199, 4, 225, 137, 28, 243, 137, 4, 68, 6, 195, 4, 224, 80, 65, 0, 7, 195, 76, 18, 197, 66, 20, 7, 196, 64, 83, 12, 20, 21, 0, 9, 197, 80, 83, 133, 72, 80, 66, 21, 12, 201, 28, 83, 133, 72, 22, 137, 60, 225, 64, 20, 8, 197, 12, 20, 1, 12, 80, 66, 12, 201, 5, 48, 204, 21, 2, 79, 16, 245, 0, 68, 0, 9, 198, 77, 1, 67, 12, 130, 64, 20, 9, 198, 65, 35, 211, 80, 21, 0, 65, 9, 198, 21, 32, 129, 12, 83, 192, 66, 9, 198, 5, 3, 211, 80, 21, 0, 66, 0, 9, 198, 77, 1, 67, 12, 130, 65, 20, 6, 195, 20, 226, 64, 66, 9, 198, 12, 19, 66, 60, 66, 65, 20, 0, 11, 200, 80, 85, 18, 5, 32, 200, 36, 16, 67, 7, 196, 76, 19, 148, 20, 66, 7, 196, 72, 80, 130, 36, 21, 11, 200, 65, 35, 195, 60, 228, 207, 48, 80, 20, 7, 196, 56, 83, 142, 36, 20, 9, 198, 20, 211, 212, 36, 51, 206, 66, 7, 195, 12, 147, 197, 66, 20, 0, 6, 65, 88, 84, 40, 0, 8, 197, 72, 149, 15, 12, 48, 21, 8, 197, 72, 85, 133, 72, 80, 21, 8, 197, 36, 225, 68, 36, 16, 20, 8, 197, 28, 16, 129, 48, 144, 65, 8, 197, 13, 84, 131, 84, 208, 65, 8, 197, 5, 4, 137, 48, 80, 66, 0, 6, 195, 80, 244, 147, 21, 12, 201, 76, 50, 9, 104, 241, 146, 20, 226, 65, 68, 9, 198, 52, 243, 15, 12, 130, 64, 20, 9, 198, 29, 32, 68, 60, 194, 64, 65, 9, 198, 12, 19, 142, 60, 34, 64, 20, 0, 9, 198, 81, 32, 71, 20, 66, 65, 20, 0, 8, 196, 56, 83, 12, 60, 72, 28, 17, 4, 95, 49, 77, 52, 40, 50, 71, 37, 55, 37, 6, 39, 50, 36, 0, 11, 200, 28, 192, 85, 12, 241, 129, 56, 80, 67, 11, 200, 12, 244, 142, 84, 51, 208, 36, 16, 20, 11, 200, 12, 244, 18, 60, 192, 76, 36, 16, 68, 7, 196, 12, 16, 129, 48, 65, 7, 196, 4, 208, 137, 80, 65, 0, 12, 1, 92, 71, 35, 49, 89, 55, 35, 91, 0, 27, 14, 65, 92, 72, 6, 39, 48, 12, 57, 35, 84, 6, 40, 0, 6, 195, 80, 244, 142, 21, 8, 197, 80, 130, 69, 76, 144, 20, 8, 197, 76, 148, 212, 20, 208, 20, 8, 197, 56, 243, 65, 16, 80, 65, 8, 197, 48, 243, 135, 32, 144, 20, 8, 197, 12, 20, 211, 60, 192, 66, 8, 197, 5, 69, 15, 72, 224, 21, 0, 9, 198, 76, 243, 15, 64, 16, 192, 67, 9, 198, 57, 83, 129, 80, 18, 192, 67, 9, 198, 56, 83, 199, 72, 80, 192, 20, 6, 195, 28, 147, 199, 21, 7, 195, 20, 97, 83, 65, 20, 0, 0, 7, 196, 64, 243, 148, 60, 20, 11, 200, 65, 35, 194, 61, 48, 201, 16, 80, 20, 0, 13, 4, 95, 49, 77, 49, 65, 6, 37, 55, 55, 36, 0, 8, 65, 96, 6, 37, 49, 89, 0, 8, 197, 28, 243, 142, 21, 48, 20, 8, 197, 20, 226, 201, 17, 80, 20, 6, 195, 16, 246, 154, 21, 9, 198, 4, 113, 83, 36, 192, 79, 68, 0, 6, 194, 4, 64, 72, 28, 17, 4, 95, 49, 77, 50, 40, 50, 65, 37, 55, 37, 6, 39, 50, 36, 0, 9, 198, 21, 81, 193, 56, 83, 192, 67, 0, 18, 4, 95, 49, 77, 51, 40, 50, 65, 37, 55, 37, 6, 35, 51, 72, 39, 0, 10, 199, 36, 224, 207, 53, 3, 5, 80, 20, 6, 195, 36, 98, 84, 65, 9, 198, 12, 130, 67, 32, 144, 137, 67, 9, 198, 12, 128, 77, 8, 84, 153, 21, 9, 198, 12, 21, 1, 48, 148, 201, 66, 0, 7, 196, 104, 81, 137, 72, 65, 7, 196, 80, 243, 22, 20, 20, 7, 196, 73, 83, 212, 36, 20, 7, 196, 64, 243, 9, 76, 21, 7, 195, 60, 20, 201, 65, 20, 7, 196, 48, 144, 133, 72, 65, 7, 196, 48, 144, 133, 72, 65, 7, 196, 48, 16, 129, 72, 65, 6, 195, 16, 244, 197, 20, 9, 198, 9, 32, 71, 4, 66, 78, 67, 9, 198, 8, 20, 130, 4, 225, 82, 21, 0, 12, 65, 100, 6, 37, 48, 89, 37, 55, 39, 50, 0, 7, 195, 4, 211, 210, 66, 21, 0, 9, 198, 52, 20, 129, 52, 19, 192, 67, 0, 10, 199, 64, 147, 142, 37, 1, 68, 36, 66, 9, 198, 64, 20, 129, 85, 37, 9, 67, 9, 198, 36, 225, 133, 48, 144, 197, 67, 9, 198, 24, 245, 15, 48, 148, 201, 66, 11, 199, 5, 48, 197, 57, 50, 79, 56, 68, 21, 6, 195, 4, 226, 84, 65, 0, 7, 196, 80, 19, 15, 72, 21, 7, 196, 65, 35, 214, 20, 20, 8, 196, 12, 17, 134, 20, 66, 20, 0, 10, 65, 104, 72, 88, 36, 12, 47, 35, 0, 8, 197, 24, 244, 131, 60, 192, 21, 8, 197, 12, 244, 146, 20, 64, 20, 12, 201, 12, 243, 134, 72, 21, 5, 72, 226, 84, 67, 8, 197, 12, 241, 207, 72, 224, 21, 8, 197, 12, 84, 131, 60, 192, 21, 8, 197, 5, 32, 71, 60, 224, 67, 8, 197, 4, 48, 197, 56, 224, 21, 0, 9, 198, 4, 211, 210, 28, 244, 192, 67, 0, 6, 195, 64, 244, 192, 20, 10, 199, 57, 84, 129, 52, 147, 137, 76, 66, 10, 199, 52, 19, 143, 16, 244, 5, 72, 67, 0, 7, 196, 21, 32, 78, 60, 72, 12, 201, 52, 81, 9, 80, 84, 146, 4, 225, 79, 68, 7, 196, 13, 80, 195, 84, 66, 15, 204, 5, 32, 201, 12, 243, 134, 72, 21, 5, 72, 226, 84, 69, 0, 8, 197, 92, 21, 20, 61, 32, 21, 8, 197, 88, 83, 132, 37, 64, 65, 8, 197, 80, 19, 77, 5, 32, 65, 9, 198, 76, 20, 131, 60, 96, 71, 66, 6, 195, 28, 147, 214, 21, 8, 197, 24, 84, 142, 21, 64, 66, 12, 201, 20, 194, 79, 12, 83, 148, 72, 144, 192, 20, 0, 9, 198, 48, 84, 85, 36, 193, 64, 20, 9, 198, 13, 84, 212, 60, 65, 64, 20, 9, 198, 12, 244, 146, 21, 69, 0, 20, 9, 198, 4, 225, 77, 60, 225, 64, 20, 9, 198, 4, 65, 76, 36, 225, 64, 21, 0, 10, 199, 81, 84, 130, 60, 113, 84, 80, 20, 9, 198, 81, 33, 83, 21, 69, 5, 20, 10, 199, 80, 240, 207, 24, 84, 143, 48, 68, 10, 199, 52, 84, 131, 4, 230, 137, 4, 67, 10, 199, 36, 229, 5, 72, 209, 90, 104, 20, 10, 199, 28, 84, 129, 72, 50, 9, 4, 67, 10, 199, 24, 83, 143, 12, 244, 9, 4, 20, 10, 199, 21, 51, 212, 72, 244, 9, 4, 68, 10, 199, 21, 2, 76, 21, 52, 201, 4, 68, 12, 201, 20, 225, 5, 12, 20, 201, 48, 192, 66, 68, 10, 199, 12, 20, 15, 12, 50, 9, 4, 20, 9, 198, 5, 69, 9, 88, 149, 1, 68, 10, 199, 5, 64, 82, 5, 52, 201, 4, 68, 0, 7, 196, 64, 243, 9, 64, 65, 7, 196, 64, 147, 15, 80, 20, 7, 196, 64, 83, 15, 80, 20, 0, 9, 198, 52, 145, 206, 4, 225, 71, 66, 12, 201, 52, 20, 131, 36, 20, 9, 20, 65, 64, 20, 8, 197, 36, 225, 68, 37, 64, 66, 8, 197, 12, 19, 80, 61, 32, 65, 0, 9, 198, 80, 84, 211, 36, 193, 64, 20, 9, 198, 80, 83, 198, 4, 225, 64, 66, 9, 198, 76, 84, 211, 36, 193, 64, 20, 9, 198, 28, 147, 214, 36, 225, 64, 21, 0, 10, 198, 65, 35, 199, 56, 244, 201, 65, 20, 10, 199, 8, 244, 135, 61, 35, 211, 20, 20, 9, 198, 4, 224, 67, 48, 20, 201, 66, 6, 195, 4, 81, 0, 20, 0, 7, 196, 77, 65, 67, 12, 21, 7, 196, 61, 33, 193, 56, 65, 7, 196, 21, 33, 68, 20, 20, 10, 198, 5, 53, 78, 12, 147, 206, 67, 21, 0, 9, 197, 88, 243, 5, 72, 80, 66, 21, 8, 197, 88, 84, 129, 12, 80, 66, 8, 197, 48, 21, 82, 20, 16, 65, 8, 197, 12, 244, 205, 36, 48, 20, 8, 197, 12, 244, 143, 56, 80, 20, 0, 9, 198, 81, 34, 80, 60, 194, 64, 65, 12, 201, 65, 50, 67, 61, 50, 78, 80, 84, 201, 67, 12, 201, 65, 50, 67, 60, 19, 129, 48, 148, 201, 68, 9, 198, 65, 33, 71, 4, 66, 64, 67, 9, 198, 64, 192, 84, 4, 226, 64, 65, 9, 198, 64, 81, 1, 28, 241, 192, 20, 0, 10, 199, 80, 83, 5, 88, 145, 5, 60, 67, 9, 198, 64, 192, 84, 4, 226, 65, 67, 9, 198, 52, 16, 195, 4, 33, 73, 67, 10, 199, 29, 80, 82, 16, 20, 143, 8, 20, 9, 198, 13, 84, 212, 60, 66, 65, 20, 9, 198, 12, 243, 77, 20, 66, 65, 20, 10, 199, 8, 144, 140, 36, 245, 5, 12, 20, 9, 198, 4, 227, 205, 4, 194, 65, 68, 6, 195, 4, 85, 0, 20, 0, 7, 196, 72, 147, 150, 36, 66, 11, 200, 64, 19, 147, 64, 84, 141, 36, 16, 67, 7, 196, 25, 33, 68, 16, 21, 11, 200, 21, 35, 212, 60, 208, 78, 36, 16, 69, 8, 196, 5, 32, 200, 20, 66, 20, 0, 9, 197, 76, 81, 5, 72, 80, 66, 21, 8, 197, 76, 80, 143, 72, 112, 21, 12, 201, 65, 32, 84, 61, 97, 67, 12, 130, 64, 20, 9, 197, 64, 245, 5, 72, 80, 66, 21, 9, 197, 64, 241, 5, 72, 80, 66, 21, 8, 197, 60, 32, 140, 36, 112, 20, 8, 197, 57, 80, 204, 20, 240, 65, 23, 73, 28, 84, 143, 28, 194, 70, 36, 51, 192, 75, 109, 51, 39, 61, 6, 37, 83, 37, 49, 39, 0, 8, 197, 21, 84, 143, 64, 144, 20, 8, 197, 20, 225, 193, 28, 80, 67, 12, 201, 12, 243, 12, 21, 97, 67, 12, 130, 64, 20, 0, 9, 198, 81, 34, 69, 56, 226, 64, 20, 9, 198, 76, 48, 80, 60, 194, 64, 65, 9, 198, 29, 80, 82, 4, 226, 64, 67, 9, 198, 20, 227, 133, 4, 66, 64, 66, 12, 201, 4, 229, 18, 61, 3, 211, 60, 98, 65, 69, 0, 9, 198, 80, 84, 148, 20, 226, 65, 67, 9, 198, 80, 83, 211, 60, 98, 65, 68, 6, 195, 52, 84, 192, 20, 9, 198, 36, 228, 207, 56, 226, 65, 20, 9, 198, 28, 20, 132, 20, 226, 65, 20, 0, 7, 196, 76, 16, 129, 80, 65, 7, 196, 65, 33, 67, 36, 20, 7, 196, 52, 243, 137, 80, 65, 7, 196, 52, 241, 5, 52, 20, 7, 196, 28, 80, 133, 48, 20, 0, 8, 197, 56, 80, 212, 60, 224, 20, 0, 6, 195, 60, 33, 83, 20, 13, 202, 12, 20, 212, 20, 197, 5, 72, 210, 78, 36, 67, 9, 198, 8, 148, 212, 20, 48, 192, 21, 0, 9, 1, 126, 47, 37, 55, 72, 36, 0, 6, 195, 80, 129, 84, 20, 0, 7, 196, 80, 83, 149, 20, 20, 11, 200, 64, 83, 15, 64, 243, 142, 21, 48, 20, 7, 196, 5, 144, 77, 20, 67, 0, 15, 204, 8, 21, 18, 4, 51, 205, 36, 243, 65, 12, 130, 65, 71, 0, 9, 198, 76, 145, 5, 72, 83, 192, 66, 9, 198, 56, 144, 207, 48, 19, 192, 67, 9, 198, 4, 192, 137, 72, 83, 192, 66, 0, 10, 199, 76, 16, 195, 5, 35, 211, 36, 20, 10, 199, 28, 19, 1, 81, 67, 211, 36, 20, 9, 198, 4, 224, 77, 56, 84, 201, 66, 0, 7, 196, 61, 69, 9, 12, 20, 9, 198, 8, 244, 195, 60, 225, 82, 21, 0, 8, 197, 81, 34, 79, 56, 96, 21, 0, 9, 198, 49, 80, 201, 25, 81, 192, 66, 29, 74, 12, 244, 148, 60, 50, 82, 13, 82, 84, 60, 49, 110, 14, 16, 47, 39, 76, 37, 14, 16, 49, 6, 40, 37, 47, 39, 0, 9, 198, 8, 16, 195, 5, 32, 64, 67, 0, 10, 199, 16, 80, 193, 52, 84, 143, 56, 66, 0, 7, 196, 88, 83, 148, 36, 21, 7, 196, 80, 241, 1, 72, 65, 7, 196, 77, 67, 210, 52, 21, 7, 196, 24, 241, 5, 72, 65, 7, 196, 4, 225, 143, 72, 65, 0, 8, 197, 84, 226, 83, 60, 224, 66, 6, 195, 61, 32, 70, 65, 8, 197, 52, 20, 131, 60, 224, 66, 0, 9, 198, 24, 147, 15, 9, 84, 192, 65, 9, 198, 16, 144, 129, 81, 66, 84, 66, 0, 10, 199, 77, 84, 5, 72, 99, 21, 60, 66, 6, 195, 69, 83, 212, 20, 10, 199, 65, 83, 148, 5, 49, 67, 12, 21, 9, 198, 56, 245, 133, 52, 36, 133, 20, 6, 195, 21, 97, 64, 20, 6, 195, 13, 33, 68, 20, 10, 199, 5, 33, 207, 77, 67, 204, 36, 67, 10, 199, 4, 48, 201, 64, 149, 5, 72, 66, 0, 7, 196, 88, 243, 20, 60, 21, 7, 196, 77, 67, 210, 56, 21, 11, 200, 8, 21, 20, 36, 32, 76, 20, 224, 21, 7, 196, 8, 17, 9, 4, 66, 0, 8, 197, 81, 85, 20, 61, 32, 21, 6, 195, 52, 243, 22, 20, 8, 197, 16, 19, 13, 5, 64, 65, 8, 197, 12, 243, 15, 56, 224, 21, 8, 197, 12, 19, 134, 61, 32, 65, 0, 10, 198, 65, 35, 212, 21, 84, 192, 65, 20, 12, 201, 48, 84, 15, 77, 3, 206, 16, 147, 9, 20, 9, 198, 33, 80, 72, 36, 225, 64, 67, 6, 195, 29, 33, 67, 20, 12, 201, 12, 147, 145, 84, 19, 148, 20, 227, 137, 20, 9, 198, 12, 20, 131, 5, 33, 64, 65, 0, 10, 199, 64, 20, 135, 32, 83, 9, 4, 67, 10, 199, 52, 144, 210, 60, 51, 211, 52, 20, 9, 198, 24, 83, 9, 12, 149, 1, 68, 10, 199, 8, 20, 137, 12, 83, 148, 72, 20, 0, 7, 196, 96, 83, 137, 4, 67, 11, 200, 81, 33, 68, 36, 49, 83, 36, 208, 20, 7, 196, 76, 243, 137, 4, 66, 7, 196, 61, 53, 9, 4, 65, 7, 196, 4, 33, 9, 4, 66, 0, 17, 70, 24, 18, 67, 12, 130, 79, 83, 35, 6, 37, 49, 12, 37, 39, 0, 9, 198, 20, 209, 82, 61, 65, 67, 20, 8, 197, 4, 197, 1, 37, 32, 66, 0, 9, 198, 4, 32, 137, 5, 65, 64, 76, 7, 194, 16, 16, 72, 9, 28, 9, 198, 81, 32, 77, 37, 65, 64, 65, 9, 198, 76, 244, 135, 21, 33, 64, 21, 9, 198, 52, 84, 211, 21, 33, 64, 66, 9, 198, 48, 81, 199, 21, 33, 64, 20, 9, 198, 8, 84, 135, 21, 33, 64, 66, 0, 9, 198, 88, 83, 15, 12, 149, 1, 68, 10, 199, 77, 68, 133, 81, 67, 201, 4, 21, 10, 199, 24, 245, 15, 28, 83, 137, 4, 68, 10, 199, 20, 194, 79, 24, 19, 137, 4, 69, 14, 203, 16, 144, 201, 5, 52, 197, 81, 65, 83, 36, 208, 20, 0, 10, 67, 20, 115, 9, 36, 61, 37, 0, 76, 11, 200, 88, 84, 143, 48, 19, 149, 61, 96, 20, 7, 196, 61, 37, 9, 12, 66, 7, 196, 44, 81, 137, 72, 20, 8, 196, 16, 80, 143, 72, 65, 20, 7, 196, 12, 241, 129, 56, 65, 11, 200, 12, 21, 5, 56, 19, 149, 61, 96, 20, 7, 196, 5, 33, 193, 56, 65, 0, 6, 195, 16, 19, 0, 72, 9, 197, 48, 84, 15, 72, 80, 65, 20, 9, 197, 24, 83, 79, 72, 80, 65, 20, 8, 197, 16, 241, 9, 12, 144, 21, 8, 197, 12, 83, 143, 8, 144, 20, 8, 197, 8, 244, 206, 36, 16, 20, 8, 197, 8, 19, 129, 72, 144, 65, 6, 195, 5, 97, 78, 21, 0, 11, 198, 12, 243, 12, 60, 66, 64, 66, 20, 9, 9, 198, 76, 148, 148, 61, 34, 64, 65, 12, 201, 69, 80, 84, 81, 35, 210, 84, 245, 5, 20, 9, 198, 24, 244, 195, 5, 34, 64, 65, 9, 198, 16, 84, 15, 76, 149, 0, 66, 9, 198, 12, 243, 12, 60, 66, 64, 20, 9, 198, 12, 19, 69, 17, 34, 64, 20, 10, 198, 4, 225, 68, 16, 245, 0, 66, 20, 0, 9, 198, 80, 83, 199, 60, 226, 65, 68, 10, 199, 72, 147, 80, 72, 245, 133, 72, 66, 10, 199, 52, 144, 210, 60, 98, 76, 52, 67, 10, 199, 28, 149, 76, 36, 19, 143, 88, 20, 11, 199, 28, 85, 19, 20, 208, 78, 36, 66, 20, 9, 198, 28, 83, 65, 81, 34, 65, 67, 10, 199, 12, 147, 143, 64, 149, 5, 12, 20, 6, 195, 8, 85, 0, 20, 9, 198, 8, 80, 195, 5, 34, 65, 67, 10, 199, 5, 64, 82, 28, 21, 9, 76, 66, 0, 7, 196, 88, 81, 15, 88, 65, 8, 196, 76, 81, 1, 56, 65, 20, 11, 200, 64, 244, 148, 4, 99, 199, 48, 144, 20, 6, 195, 61, 162, 65, 66, 7, 196, 56, 17, 9, 72, 66, 7, 196, 37, 81, 197, 72, 65, 0, 8, 197, 24, 16, 197, 88, 240, 76, 8, 197, 20, 32, 133, 72, 240, 72, 8, 197, 4, 192, 193, 48, 144, 65, 0, 10, 198, 76, 83, 142, 61, 34, 64, 65, 20, 9, 198, 64, 20, 129, 8, 149, 0, 66, 9, 198, 13, 33, 83, 12, 149, 0, 65, 9, 198, 12, 20, 131, 21, 34, 64, 65, 0, 9, 198, 81, 84, 135, 61, 98, 65, 20, 9, 198, 52, 244, 195, 61, 98, 65, 20, 9, 198, 52, 17, 83, 81, 34, 65, 67, 9, 198, 21, 131, 198, 61, 34, 65, 68, 9, 198, 20, 66, 84, 61, 34, 65, 68, 6, 195, 13, 33, 84, 20, 0, 7, 196, 65, 33, 71, 36, 20, 6, 195, 52, 243, 5, 20, 11, 200, 36, 51, 206, 61, 53, 1, 76, 144, 67, 9, 198, 8, 243, 142, 4, 224, 82, 66, 9, 198, 4, 210, 71, 16, 19, 0, 66, 0, 12, 201, 81, 34, 78, 37, 64, 80, 60, 194, 64, 67, 8, 197, 72, 147, 69, 16, 144, 20, 6, 195, 24, 81, 18, 20, 8, 197, 24, 19, 69, 16, 144, 20, 12, 201, 12, 20, 212, 20, 196, 197, 65, 34, 64, 20, 0, 13, 201, 81, 33, 66, 5, 49, 76, 20, 114, 5, 67, 21, 9, 198, 81, 32, 78, 76, 85, 20, 20, 6, 195, 29, 33, 83, 20, 0, 6, 195, 64, 244, 212, 21, 11, 199, 16, 145, 78, 12, 81, 129, 48, 66, 20, 6, 195, 13, 33, 80, 20, 0, 12, 201, 76, 245, 20, 60, 53, 84, 4, 225, 79, 68, 7, 196, 76, 50, 5, 16, 20, 7, 196, 5, 48, 197, 80, 20, 0, 0, 26, 73, 72, 240, 195, 5, 32, 73, 56, 243, 1, 14, 16, 39, 49, 12, 35, 51, 35, 6, 37, 50, 110, 55, 35, 0, 9, 198, 65, 35, 211, 64, 85, 20, 20, 9, 198, 65, 33, 80, 61, 53, 0, 21, 6, 195, 13, 33, 83, 20, 0, 9, 198, 104, 19, 132, 60, 32, 137, 20, 0, 7, 196, 88, 145, 5, 60, 65, 7, 196, 81, 34, 65, 12, 65, 7, 196, 77, 67, 208, 64, 21, 7, 196, 52, 148, 212, 4, 66, 9, 198, 52, 147, 137, 28, 243, 6, 67, 7, 196, 5, 33, 78, 20, 21, 0, 12, 201, 76, 19, 22, 4, 51, 206, 16, 245, 20, 21, 24, 73, 5, 85, 15, 88, 82, 67, 60, 195, 192, 35, 40, 47, 39, 84, 109, 6, 37, 49, 39, 55, 39, 0, 0, 9, 198, 64, 243, 9, 20, 68, 128, 20, 9, 198, 16, 144, 77, 21, 68, 128, 66, 0, 10, 199, 76, 83, 69, 77, 65, 78, 20, 66, 9, 198, 36, 224, 207, 57, 48, 201, 20, 0, 7, 195, 4, 115, 9, 72, 9, 7, 196, 12, 243, 15, 8, 65, 0, 8, 197, 88, 145, 206, 60, 192, 66, 8, 197, 24, 83, 19, 36, 224, 65, 9, 197, 9, 33, 71, 4, 224, 65, 20, 0, 0, 10, 199, 65, 33, 83, 8, 149, 5, 72, 66, 9, 198, 16, 144, 197, 52, 36, 133, 20, 10, 199, 12, 20, 193, 80, 244, 146, 20, 21, 0, 6, 195, 72, 85, 5, 21, 6, 195, 56, 84, 9, 20, 7, 196, 52, 19, 9, 4, 66, 7, 196, 28, 243, 9, 4, 66, 0, 8, 197, 80, 83, 196, 61, 64, 66, 9, 197, 76, 244, 150, 60, 192, 66, 21, 8, 197, 76, 195, 199, 4, 224, 20, 8, 197, 72, 149, 18, 61, 96, 20, 8, 197, 21, 35, 196, 61, 64, 66, 6, 195, 8, 83, 22, 21, 8, 197, 8, 17, 206, 60, 192, 66, 0, 9, 198, 24, 84, 212, 37, 96, 76, 65, 13, 202, 20, 193, 84, 81, 35, 212, 20, 51, 137, 12, 20, 9, 198, 12, 20, 212, 61, 33, 64, 65, 0, 10, 199, 48, 243, 66, 5, 33, 9, 4, 67, 0, 6, 195, 80, 21, 1, 66, 7, 196, 64, 243, 131, 20, 20, 6, 195, 64, 148, 9, 66, 11, 200, 52, 22, 154, 4, 48, 200, 21, 32, 66, 7, 196, 52, 19, 137, 4, 66, 7, 196, 44, 83, 137, 4, 20, 0, 9, 197, 80, 83, 80, 21, 32, 65, 20, 9, 197, 52, 85, 5, 61, 32, 66, 21, 0, 5, 194, 4, 144, 72, 9, 198, 48, 19, 131, 21, 69, 0, 21, 9, 198, 13, 35, 195, 21, 69, 0, 21, 9, 198, 8, 240, 195, 21, 69, 0, 21, 0, 10, 199, 24, 84, 146, 4, 115, 211, 80, 21, 9, 198, 4, 229, 9, 24, 21, 5, 66, 0, 7, 196, 76, 16, 137, 72, 66, 8, 196, 72, 243, 12, 20, 66, 20, 7, 196, 65, 34, 69, 28, 20, 0, 12, 201, 64, 243, 9, 52, 84, 212, 61, 33, 64, 67, 8, 197, 48, 16, 207, 56, 144, 65, 8, 197, 36, 225, 207, 72, 112, 21, 8, 197, 21, 2, 76, 60, 112, 66, 8, 197, 16, 147, 195, 48, 80, 65, 0, 9, 198, 104, 147, 135, 5, 34, 64, 65, 9, 198, 104, 145, 199, 85, 32, 84, 65, 9, 198, 16, 80, 213, 8, 149, 0, 66, 9, 198, 12, 243, 147, 84, 85, 0, 20, 0, 9, 198, 76, 81, 206, 5, 98, 65, 67, 9, 198, 76, 20, 148, 61, 34, 65, 67, 10, 199, 64, 243, 9, 13, 32, 84, 20, 66, 9, 198, 28, 84, 135, 61, 98, 65, 20, 6, 195, 12, 85, 0, 20, 9, 198, 12, 19, 148, 61, 34, 65, 67, 11, 199, 12, 17, 15, 56, 81, 200, 20, 66, 20, 0, 11, 200, 93, 80, 200, 21, 33, 82, 36, 16, 67, 11, 200, 80, 83, 73, 77, 67, 195, 48, 80, 66, 11, 200, 64, 243, 9, 80, 80, 206, 36, 48, 20, 11, 200, 37, 3, 195, 60, 225, 18, 36, 16, 68, 11, 200, 37, 1, 82, 81, 35, 198, 36, 16, 68, 7, 196, 36, 225, 133, 72, 65, 7, 196, 25, 35, 196, 20, 20, 11, 200, 16, 145, 76, 21, 69, 18, 36, 48, 20, 7, 196, 16, 17, 142, 36, 66, 11, 200, 12, 84, 131, 61, 2, 84, 20, 48, 20, 11, 200, 9, 84, 143, 13, 32, 90, 36, 16, 68, 10, 198, 9, 80, 197, 24, 19, 0, 66, 20, 0, 8, 197, 76, 147, 21, 72, 144, 65, 8, 197, 72, 245, 1, 72, 144, 65, 8, 197, 61, 99, 214, 36, 16, 67, 9, 198, 52, 18, 69, 85, 66, 67, 66, 8, 197, 28, 84, 146, 20, 144, 66, 8, 197, 12, 21, 1, 72, 144, 65, 0, 12, 201, 60, 67, 206, 80, 242, 65, 81, 34, 65, 70, 9, 198, 5, 48, 204, 21, 2, 64, 20, 0, 9, 198, 81, 85, 20, 5, 98, 65, 8, 9, 198, 81, 85, 20, 5, 98, 65, 67, 9, 198, 80, 147, 148, 61, 34, 65, 67, 9, 198, 76, 21, 18, 5, 2, 65, 67, 10, 199, 21, 21, 73, 48, 21, 5, 72, 67, 9, 198, 12, 244, 211, 21, 34, 65, 66, 9, 198, 5, 3, 195, 72, 149, 9, 66, 0, 7, 196, 76, 50, 5, 52, 20, 7, 196, 72, 244, 211, 36, 21, 7, 196, 65, 34, 65, 52, 65, 11, 200, 64, 193, 67, 61, 69, 5, 72, 144, 20, 7, 196, 61, 69, 9, 52, 20, 7, 196, 21, 49, 68, 72, 20, 9, 198, 16, 245, 129, 16, 243, 0, 66, 11, 200, 16, 148, 12, 60, 208, 90, 36, 16, 68, 8, 196, 12, 81, 129, 48, 65, 20, 11, 200, 4, 226, 83, 61, 69, 5, 72, 144, 20, 0, 8, 197, 80, 145, 80, 60, 192, 20, 8, 197, 64, 147, 154, 60, 192, 66, 0, 12, 201, 72, 17, 9, 61, 65, 82, 5, 2, 65, 70, 12, 201, 65, 50, 67, 61, 65, 82, 5, 2, 65, 69, 12, 201, 65, 32, 78, 61, 65, 82, 5, 2, 65, 69, 12, 201, 64, 84, 195, 5, 52, 197, 72, 243, 9, 67, 12, 201, 24, 148, 201, 61, 65, 82, 5, 2, 65, 70, 12, 201, 13, 35, 205, 61, 65, 82, 5, 2, 65, 69, 12, 201, 5, 35, 205, 5, 65, 82, 5, 2, 65, 70, 9, 198, 4, 208, 68, 21, 84, 192, 21, 0, 0, 10, 198, 80, 83, 5, 52, 85, 18, 66, 20, 9, 198, 16, 244, 201, 52, 85, 18, 66, 0, 15, 204, 13, 34, 83, 80, 19, 12, 61, 65, 82, 5, 2, 65, 70, 0, 0, 14, 203, 69, 80, 84, 80, 244, 132, 36, 49, 83, 36, 208, 20, 9, 198, 52, 20, 133, 81, 66, 77, 21, 9, 198, 12, 84, 142, 60, 32, 137, 20, 0, 7, 196, 80, 84, 208, 36, 20, 7, 196, 76, 147, 143, 72, 21, 7, 196, 72, 243, 12, 36, 66, 6, 195, 56, 83, 73, 20, 7, 196, 12, 243, 12, 36, 20, 0, 8, 197, 80, 19, 12, 20, 64, 66, 6, 195, 64, 131, 206, 20, 6, 195, 20, 35, 0, 20, 0, 9, 198, 81, 34, 77, 21, 68, 128, 65, 9, 198, 76, 240, 201, 21, 64, 64, 67, 9, 198, 64, 149, 5, 12, 144, 64, 20, 9, 198, 64, 20, 129, 88, 144, 64, 67, 9, 198, 36, 68, 143, 24, 240, 128, 66, 0, 12, 201, 64, 243, 148, 20, 192, 78, 16, 243, 6, 20, 6, 195, 52, 240, 64, 20, 0, 7, 196, 24, 83, 137, 76, 21, 0, 9, 198, 5, 97, 83, 76, 147, 79, 72, 12, 201, 56, 20, 131, 60, 193, 83, 76, 144, 64, 68, 6, 195, 52, 240, 66, 66, 12, 201, 48, 144, 193, 57, 68, 143, 64, 144, 64, 68, 8, 197, 21, 48, 200, 36, 192, 20, 9, 197, 16, 20, 137, 20, 224, 67, 21, 8, 197, 12, 194, 77, 20, 224, 65, 12, 201, 12, 21, 1, 64, 193, 83, 76, 144, 64, 68, 8, 197, 9, 37, 71, 60, 192, 65, 0, 9, 198, 88, 83, 129, 72, 144, 64, 67, 9, 198, 88, 19, 9, 28, 144, 64, 66, 9, 198, 84, 52, 143, 56, 144, 64, 67, 10, 198, 76, 147, 5, 76, 144, 64, 66, 20, 18, 70, 76, 81, 5, 12, 144, 64, 89, 36, 72, 36, 76, 6, 37, 12, 35, 0, 10, 198, 64, 243, 5, 76, 144, 64, 66, 20, 10, 198, 52, 19, 5, 76, 144, 64, 66, 20, 9, 198, 12, 243, 69, 16, 144, 64, 20, 0, 9, 198, 88, 83, 148, 20, 227, 137, 20, 10, 199, 64, 83, 148, 5, 3, 204, 36, 66, 10, 199, 52, 83, 16, 60, 209, 78, 20, 66, 10, 199, 52, 19, 5, 77, 49, 82, 20, 20, 6, 195, 21, 33, 0, 21, 10, 199, 8, 83, 133, 77, 49, 82, 20, 20, 0, 6, 195, 105, 83, 21, 66, 7, 196, 80, 244, 211, 20, 21, 8, 196, 76, 244, 201, 4, 65, 20, 7, 196, 4, 50, 5, 36, 66, 0, 8, 197, 61, 4, 15, 77, 64, 21, 8, 197, 52, 243, 135, 61, 160, 20, 12, 201, 28, 195, 211, 76, 243, 1, 48, 144, 64, 68, 8, 197, 24, 147, 195, 36, 224, 66, 8, 197, 21, 2, 84, 21, 64, 66, 12, 201, 12, 148, 195, 5, 80, 193, 76, 144, 64, 68, 8, 197, 8, 20, 130, 5, 32, 65, 8, 197, 4, 194, 77, 20, 224, 21, 0, 6, 195, 64, 145, 71, 20, 9, 198, 21, 2, 84, 60, 209, 64, 66, 0, 6, 195, 64, 145, 64, 20, 9, 198, 52, 17, 206, 20, 230, 137, 20, 0, 14, 68, 37, 48, 73, 4, 37, 88, 35, 6, 37, 12, 35, 0, 9, 198, 13, 35, 205, 60, 99, 210, 66, 8, 196, 12, 81, 15, 48, 65, 20, 7, 196, 5, 33, 79, 48, 66, 0, 8, 197, 72, 148, 207, 73, 64, 21, 8, 197, 64, 243, 9, 105, 160, 65, 0, 5, 194, 24, 16, 76, 6, 194, 16, 80, 72, 9, 9, 198, 80, 245, 82, 56, 81, 64, 21, 9, 198, 60, 193, 65, 12, 81, 64, 67, 13, 202, 53, 84, 201, 12, 245, 5, 72, 20, 9, 4, 70, 5, 194, 20, 48, 20, 13, 202, 12, 129, 77, 36, 245, 5, 72, 20, 9, 4, 70, 9, 198, 5, 65, 78, 60, 193, 128, 20, 0, 9, 67, 32, 18, 64, 35, 57, 0, 72, 7, 195, 56, 82, 64, 72, 28, 10, 199, 76, 81, 199, 36, 245, 137, 4, 67, 9, 198, 64, 19, 1, 52, 81, 5, 20, 10, 199, 24, 147, 15, 76, 241, 137, 4, 68, 9, 198, 12, 243, 80, 61, 53, 5, 21, 10, 199, 12, 16, 137, 56, 245, 137, 4, 68, 10, 199, 4, 229, 9, 52, 17, 137, 4, 67, 6, 195, 4, 112, 84, 65, 0, 7, 196, 64, 84, 212, 20, 20, 7, 196, 5, 97, 86, 4, 72, 7, 196, 5, 97, 84, 20, 72, 8, 196, 77, 66, 76, 20, 66, 20, 6, 195, 36, 229, 137, 66, 9, 198, 24, 244, 196, 36, 227, 214, 20, 7, 196, 8, 145, 143, 72, 65, 7, 196, 5, 96, 82, 36, 65, 7, 196, 5, 65, 76, 20, 65, 0, 7, 195, 16, 83, 0, 72, 9, 8, 197, 77, 3, 199, 48, 144, 20, 9, 198, 72, 82, 77, 64, 145, 71, 20, 8, 197, 65, 35, 195, 56, 80, 20, 12, 201, 29, 80, 82, 16, 19, 9, 56, 81, 64, 67, 9, 197, 12, 240, 204, 20, 16, 65, 20, 8, 197, 9, 35, 199, 48, 144, 20, 9, 197, 8, 243, 7, 36, 16, 65, 20, 8, 197, 4, 224, 78, 36, 16, 67, 9, 197, 4, 193, 82, 36, 16, 66, 21, 0, 9, 198, 9, 84, 195, 20, 210, 64, 20, 0, 6, 195, 16, 18, 64, 72, 10, 199, 88, 84, 195, 61, 98, 76, 20, 67, 0, 7, 196, 25, 83, 77, 60, 72, 16, 4, 95, 4, 16, 20, 10, 84, 6, 37, 51, 81, 39, 55, 35, 0, 7, 196, 76, 19, 132, 20, 66, 11, 200, 64, 81, 15, 28, 83, 133, 76, 144, 67, 11, 200, 61, 32, 200, 36, 64, 67, 20, 80, 67, 11, 200, 52, 85, 1, 24, 243, 133, 76, 144, 20, 0, 8, 197, 69, 81, 71, 48, 144, 72, 8, 197, 80, 83, 210, 36, 16, 67, 12, 201, 77, 66, 76, 61, 3, 201, 16, 82, 64, 69, 8, 197, 73, 85, 5, 56, 144, 20, 8, 197, 72, 80, 76, 80, 16, 67, 8, 197, 64, 20, 143, 16, 144, 66, 8, 197, 64, 20, 143, 16, 144, 20, 8, 197, 48, 245, 133, 72, 80, 21, 8, 197, 48, 85, 137, 80, 16, 67, 8, 197, 37, 3, 212, 20, 48, 20, 10, 198, 36, 115, 5, 76, 144, 83, 66, 20, 8, 197, 24, 83, 9, 12, 80, 66, 8, 197, 21, 48, 200, 36, 208, 20, 9, 197, 16, 245, 133, 72, 80, 66, 21, 9, 198, 12, 244, 144, 61, 33, 79, 66, 8, 197, 12, 83, 148, 72, 144, 20, 8, 197, 8, 245, 67, 48, 80, 67, 8, 197, 5, 85, 1, 72, 144, 65, 0, 9, 198, 65, 35, 208, 4, 227, 204, 67, 9, 198, 12, 243, 131, 72, 85, 0, 20, 9, 198, 12, 20, 133, 28, 114, 64, 21, 9, 198, 8, 19, 19, 4, 210, 64, 65, 9, 198, 4, 195, 15, 28, 114, 64, 20, 0, 9, 198, 76, 19, 79, 28, 114, 65, 20, 6, 195, 72, 85, 20, 20, 11, 199, 64, 20, 148, 20, 50, 80, 20, 66, 21, 9, 198, 48, 244, 133, 28, 114, 65, 20, 20, 70, 24, 20, 141, 4, 50, 65, 83, 35, 14, 16, 65, 35, 76, 6, 37, 12, 35, 0, 9, 198, 16, 240, 146, 84, 114, 65, 66, 0, 7, 196, 80, 20, 211, 36, 66, 7, 196, 69, 82, 69, 80, 20, 6, 195, 48, 19, 69, 66, 9, 198, 21, 84, 143, 64, 243, 0, 68, 8, 196, 16, 80, 137, 80, 65, 21, 11, 200, 12, 244, 205, 60, 115, 206, 36, 16, 68, 7, 196, 8, 144, 137, 80, 65, 11, 200, 5, 34, 83, 80, 241, 129, 56, 80, 67, 6, 195, 4, 227, 193, 20, 0, 9, 198, 24, 16, 195, 36, 19, 79, 76, 6, 195, 88, 85, 18, 21, 8, 197, 52, 243, 154, 60, 224, 66, 12, 201, 12, 20, 212, 20, 192, 201, 88, 149, 0, 67, 0, 9, 198, 76, 83, 73, 72, 85, 20, 20, 9, 198, 64, 20, 129, 64, 85, 20, 20, 9, 198, 20, 227, 133, 76, 147, 64, 20, 0, 6, 195, 21, 53, 0, 9, 6, 195, 84, 243, 64, 20, 10, 199, 64, 20, 129, 25, 32, 83, 36, 66, 10, 199, 52, 85, 1, 12, 83, 148, 72, 20, 6, 195, 21, 53, 0, 21, 6, 195, 16, 145, 84, 20, 0, 7, 196, 88, 84, 208, 72, 20, 7, 196, 77, 2, 69, 16, 20, 6, 195, 64, 21, 21, 66, 7, 195, 60, 35, 197, 65, 20, 7, 196, 52, 244, 212, 72, 21, 7, 196, 13, 80, 213, 48, 66, 10, 198, 13, 35, 199, 36, 243, 0, 65, 20, 7, 196, 12, 147, 133, 52, 65, 0, 8, 197, 72, 148, 207, 73, 48, 21, 8, 197, 72, 144, 207, 73, 48, 21, 6, 195, 8, 83, 66, 20, 0, 6, 194, 4, 192, 72, 9, 6, 194, 20, 64, 72, 8, 9, 198, 52, 243, 143, 64, 85, 20, 20, 10, 198, 4, 229, 9, 76, 243, 64, 67, 20, 0, 13, 201, 8, 20, 130, 4, 34, 69, 80, 243, 0, 67, 20, 0, 12, 68, 64, 244, 212, 4, 48, 110, 89, 47, 35, 0, 13, 4, 95, 20, 12, 4, 47, 6, 37, 55, 72, 36, 0, 7, 196, 88, 147, 143, 88, 20, 7, 196, 64, 83, 1, 28, 65, 7, 196, 16, 83, 5, 28, 65, 7, 196, 9, 33, 86, 20, 20, 0, 8, 197, 64, 21, 20, 36, 224, 65, 8, 197, 36, 229, 15, 72, 224, 21, 8, 197, 12, 243, 132, 36, 192, 20, 0, 9, 198, 104, 83, 143, 8, 144, 64, 20, 12, 201, 81, 33, 78, 80, 17, 21, 21, 50, 77, 20, 9, 198, 24, 21, 71, 48, 144, 64, 66, 9, 198, 12, 20, 143, 56, 144, 64, 67, 9, 198, 5, 64, 83, 76, 144, 64, 67, 9, 198, 5, 34, 84, 52, 144, 64, 67, 9, 198, 5, 32, 197, 88, 144, 64, 20, 9, 198, 4, 209, 71, 48, 144, 64, 20, 9, 198, 4, 84, 143, 88, 144, 64, 67, 0, 10, 199, 80, 83, 196, 61, 50, 65, 56, 69, 10, 199, 76, 83, 73, 9, 33, 86, 20, 20, 10, 198, 48, 147, 143, 48, 85, 77, 66, 20, 10, 199, 20, 195, 5, 77, 3, 206, 80, 20, 10, 199, 12, 20, 15, 48, 21, 143, 72, 21, 0, 7, 196, 80, 83, 5, 24, 65, 7, 196, 49, 83, 65, 12, 66, 7, 196, 12, 243, 15, 72, 21, 7, 196, 8, 243, 143, 76, 20, 7, 196, 4, 225, 18, 20, 66, 0, 12, 201, 80, 80, 206, 60, 52, 129, 104, 144, 64, 68, 9, 197, 76, 241, 199, 60, 192, 66, 21, 8, 197, 64, 84, 137, 60, 64, 66, 12, 201, 12, 20, 148, 60, 208, 78, 104, 144, 64, 68, 0, 9, 198, 61, 37, 9, 28, 144, 64, 66, 5, 194, 21, 64, 20, 10, 198, 12, 244, 141, 60, 228, 192, 66, 20, 9, 198, 8, 20, 143, 56, 144, 64, 67, 9, 198, 5, 33, 207, 88, 144, 64, 20, 0, 10, 199, 81, 35, 214, 5, 35, 194, 20, 20, 10, 199, 80, 84, 129, 64, 85, 84, 36, 67, 10, 199, 64, 20, 129, 64, 83, 132, 36, 68, 10, 199, 52, 19, 3, 21, 50, 78, 20, 21, 0, 11, 200, 76, 20, 132, 4, 224, 80, 4, 192, 67, 14, 68, 49, 80, 201, 4, 55, 40, 76, 6, 37, 12, 35, 0, 7, 196, 36, 115, 143, 80, 20, 7, 196, 24, 83, 143, 48, 66, 7, 196, 24, 83, 3, 20, 21, 0, 8, 197, 76, 49, 84, 81, 32, 20, 12, 201, 52, 148, 193, 57, 68, 143, 64, 144, 64, 68, 8, 197, 52, 83, 69, 57, 64, 20, 9, 198, 12, 147, 79, 48, 18, 83, 67, 12, 201, 12, 130, 82, 60, 208, 78, 104, 144, 64, 68, 12, 201, 4, 226, 83, 61, 68, 143, 64, 144, 64, 69, 0, 9, 198, 69, 80, 68, 73, 84, 12, 65, 9, 198, 65, 35, 212, 21, 69, 0, 20, 9, 198, 16, 148, 208, 21, 69, 0, 20, 0, 16, 67, 5, 101, 128, 97, 118, 118, 111, 99, 97, 116, 111, 0, 25, 29, 10, 199, 56, 21, 77, 4, 50, 9, 4, 68, 9, 198, 29, 32, 84, 84, 149, 1, 67, 6, 195, 24, 85, 68, 65, 0, 7, 196, 104, 83, 15, 80, 20, 7, 196, 88, 147, 133, 4, 65, 7, 196, 81, 34, 79, 16, 65, 11, 200, 81, 32, 80, 21, 163, 197, 17, 32, 20, 7, 196, 80, 147, 133, 4, 65, 9, 198, 80, 84, 146, 4, 227, 214, 20, 7, 196, 48, 147, 133, 4, 65, 7, 196, 24, 240, 137, 4, 66, 7, 196, 24, 147, 15, 80, 20, 11, 200, 12, 192, 77, 36, 67, 198, 61, 32, 67, 0, 8, 197, 72, 80, 204, 85, 64, 65, 8, 197, 28, 147, 206, 5, 64, 65, 8, 197, 13, 33, 77, 21, 32, 65, 0, 6, 194, 12, 144, 76, 9, 9, 198, 5, 52, 201, 20, 209, 64, 20, 0, 0, 7, 196, 5, 97, 86, 36, 72, 7, 196, 52, 19, 1, 28, 65, 9, 198, 28, 243, 5, 4, 67, 210, 68, 7, 196, 24, 243, 1, 28, 65, 7, 196, 24, 147, 143, 72, 21, 7, 196, 12, 81, 21, 60, 20, 0, 12, 201, 76, 245, 20, 60, 213, 76, 80, 148, 12, 67, 8, 197, 76, 83, 77, 4, 144, 66, 8, 197, 76, 51, 199, 48, 144, 20, 8, 197, 52, 85, 15, 16, 144, 20, 8, 197, 48, 21, 82, 36, 16, 67, 8, 197, 24, 84, 137, 80, 16, 67, 8, 197, 12, 245, 20, 36, 208, 20, 8, 197, 5, 81, 213, 72, 80, 65, 0, 9, 198, 56, 16, 129, 80, 82, 64, 67, 9, 198, 4, 48, 207, 48, 149, 0, 66, 0, 0, 7, 196, 85, 50, 78, 36, 65, 9, 198, 64, 147, 133, 72, 243, 0, 67, 9, 198, 64, 20, 129, 8, 243, 0, 66, 7, 196, 12, 243, 15, 56, 66, 11, 200, 12, 243, 12, 20, 224, 200, 36, 208, 20, 6, 195, 5, 101, 137, 66, 0, 9, 197, 64, 84, 15, 48, 144, 65, 20, 9, 198, 61, 69, 15, 80, 148, 0, 66, 8, 197, 12, 84, 193, 72, 80, 65, 8, 197, 12, 20, 207, 48, 144, 65, 8, 197, 12, 20, 148, 4, 208, 65, 0, 9, 198, 56, 149, 5, 72, 242, 64, 21, 9, 198, 52, 19, 133, 28, 114, 64, 67, 0, 6, 195, 64, 145, 84, 20, 9, 198, 52, 19, 137, 12, 243, 73, 20, 9, 198, 12, 243, 15, 76, 147, 73, 66, 0, 7, 196, 104, 83, 137, 80, 20, 7, 196, 96, 147, 5, 52, 20, 9, 198, 88, 144, 146, 4, 99, 206, 66, 8, 196, 80, 83, 133, 16, 65, 20, 7, 196, 28, 243, 7, 36, 20, 9, 198, 13, 34, 83, 76, 243, 0, 66, 8, 196, 12, 83, 133, 16, 65, 20, 7, 196, 12, 19, 129, 16, 65, 11, 200, 4, 192, 137, 28, 224, 83, 20, 112, 67, 0, 9, 198, 64, 84, 134, 84, 112, 83, 65, 19, 70, 29, 32, 84, 84, 149, 15, 81, 14, 16, 35, 47, 6, 40, 37, 47, 39, 0, 12, 201, 16, 147, 137, 81, 35, 198, 20, 227, 204, 69, 0, 10, 198, 4, 227, 205, 4, 195, 192, 66, 20, 9, 198, 5, 100, 129, 56, 227, 192, 72, 9, 198, 77, 3, 212, 61, 35, 128, 21, 9, 198, 36, 229, 5, 72, 147, 64, 65, 13, 201, 29, 80, 82, 16, 144, 82, 20, 114, 65, 67, 20, 13, 202, 12, 19, 15, 49, 162, 79, 12, 244, 148, 20, 21, 0, 6, 195, 48, 145, 84, 20, 10, 199, 36, 224, 207, 57, 53, 69, 80, 20, 9, 198, 21, 21, 65, 56, 147, 69, 66, 0, 12, 68, 32, 19, 142, 60, 35, 50, 50, 39, 0, 72, 6, 195, 89, 81, 21, 66, 7, 196, 76, 243, 9, 80, 65, 7, 196, 65, 35, 195, 36, 20, 7, 196, 64, 19, 129, 52, 65, 7, 196, 16, 147, 129, 52, 65, 7, 196, 16, 19, 129, 20, 65, 0, 0, 9, 198, 52, 243, 148, 72, 80, 76, 21, 9, 198, 12, 243, 148, 61, 35, 128, 21, 0, 6, 195, 61, 32, 193, 21, 10, 199, 77, 1, 82, 52, 144, 201, 16, 67, 6, 195, 61, 51, 73, 20, 6, 195, 36, 243, 137, 20, 10, 199, 4, 195, 15, 9, 35, 199, 36, 66, 0, 9, 198, 81, 34, 71, 20, 210, 78, 66, 9, 198, 76, 48, 76, 36, 113, 82, 66, 9, 198, 65, 33, 67, 4, 209, 82, 66, 6, 195, 56, 80, 128, 20, 6, 195, 24, 80, 128, 20, 0, 7, 196, 16, 83, 12, 4, 72, 7, 196, 16, 19, 12, 4, 72, 7, 196, 81, 34, 66, 84, 66, 8, 196, 80, 83, 133, 72, 65, 20, 7, 196, 76, 243, 129, 72, 20, 7, 196, 64, 147, 5, 60, 65, 7, 196, 36, 243, 1, 60, 67, 12, 201, 36, 225, 137, 56, 149, 5, 76, 147, 64, 20, 7, 196, 29, 33, 86, 20, 20, 7, 196, 16, 147, 129, 72, 65, 8, 196, 5, 97, 82, 20, 66, 21, 0, 13, 202, 64, 20, 148, 20, 227, 199, 20, 225, 83, 36, 68, 8, 197, 52, 16, 200, 36, 224, 65, 0, 9, 198, 81, 32, 83, 8, 244, 132, 21, 9, 198, 76, 99, 199, 48, 144, 64, 20, 6, 195, 72, 83, 137, 21, 9, 198, 64, 243, 9, 52, 84, 128, 66, 9, 198, 52, 85, 1, 52, 84, 128, 66, 9, 198, 4, 65, 83, 52, 144, 64, 67, 0, 6, 195, 73, 80, 64, 66, 10, 199, 12, 20, 144, 36, 225, 84, 36, 21, 0, 7, 196, 88, 148, 201, 72, 66, 12, 201, 65, 35, 212, 60, 208, 82, 80, 148, 133, 67, 7, 196, 64, 83, 132, 36, 66, 11, 200, 25, 32, 78, 12, 240, 143, 48, 192, 21, 11, 200, 12, 243, 5, 77, 65, 82, 60, 192, 68, 11, 200, 4, 192, 66, 5, 53, 18, 60, 224, 66, 0, 9, 198, 64, 243, 9, 56, 243, 73, 20, 8, 197, 64, 192, 84, 4, 224, 65, 8, 197, 64, 84, 137, 64, 192, 65, 9, 197, 8, 245, 133, 28, 224, 65, 20, 0, 9, 198, 80, 81, 15, 24, 244, 128, 66, 9, 198, 76, 51, 210, 64, 244, 128, 65, 9, 198, 52, 85, 1, 24, 244, 128, 66, 5, 194, 21, 96, 20, 9, 198, 4, 113, 78, 104, 144, 64, 67, 0, 6, 195, 61, 35, 208, 20, 10, 199, 36, 229, 18, 36, 228, 197, 12, 66, 10, 199, 21, 85, 9, 25, 35, 206, 20, 67, 10, 199, 16, 83, 9, 4, 229, 79, 88, 20, 10, 199, 5, 32, 207, 8, 19, 5, 56, 21, 0, 7, 196, 5, 97, 86, 60, 72, 7, 196, 76, 83, 3, 20, 21, 7, 196, 20, 208, 143, 48, 20, 7, 196, 12, 243, 5, 36, 66, 7, 196, 12, 19, 9, 4, 66, 7, 196, 8, 19, 9, 4, 66, 0, 0, 6, 195, 80, 16, 137, 66, 9, 198, 76, 240, 130, 61, 33, 192, 21, 9, 198, 60, 115, 137, 80, 83, 80, 20, 9, 198, 52, 19, 132, 61, 35, 0, 65, 13, 202, 12, 243, 148, 20, 212, 15, 72, 19, 133, 60, 68, 9, 198, 12, 20, 193, 56, 245, 128, 20, 0, 10, 199, 80, 85, 18, 4, 209, 84, 72, 66, 11, 199, 64, 243, 9, 56, 84, 201, 4, 67, 20, 11, 67, 9, 81, 64, 71, 6, 40, 12, 36, 0, 0, 11, 200, 64, 243, 1, 72, 147, 69, 81, 32, 67, 7, 196, 64, 147, 131, 20, 66, 7, 196, 52, 85, 15, 16, 20, 8, 196, 48, 19, 132, 60, 66, 20, 7, 196, 17, 33, 83, 16, 20, 11, 200, 13, 80, 143, 81, 64, 69, 17, 32, 20, 7, 196, 13, 35, 195, 20, 66, 9, 198, 12, 20, 131, 60, 99, 210, 66, 0, 8, 197, 81, 34, 69, 17, 32, 20, 12, 201, 12, 243, 148, 72, 244, 9, 20, 65, 64, 20, 8, 197, 4, 48, 197, 81, 64, 21, 0, 7, 66, 32, 16, 35, 0, 72, 7, 194, 16, 144, 72, 9, 28, 13, 202, 81, 32, 71, 36, 51, 205, 52, 81, 9, 4, 20, 5, 194, 20, 112, 20, 9, 198, 5, 3, 195, 72, 145, 128, 66, 0, 6, 195, 25, 82, 64, 72, 10, 199, 96, 83, 143, 24, 240, 137, 4, 68, 10, 199, 4, 229, 9, 4, 84, 133, 4, 67, 0, 7, 196, 16, 19, 12, 20, 72, 7, 196, 61, 98, 76, 20, 66, 9, 198, 12, 243, 80, 48, 85, 0, 20, 7, 196, 12, 19, 1, 60, 66, 0, 9, 197, 81, 35, 193, 16, 80, 65, 20, 8, 197, 77, 65, 82, 20, 240, 65, 8, 197, 64, 83, 70, 36, 112, 20, 8, 197, 56, 243, 131, 32, 80, 66, 6, 195, 24, 85, 0, 20, 9, 197, 21, 3, 195, 32, 80, 67, 20, 8, 197, 12, 19, 66, 72, 144, 66, 8, 197, 12, 19, 4, 20, 144, 66, 6, 195, 4, 245, 0, 20, 18, 70, 4, 195, 5, 49, 82, 65, 35, 55, 55, 109, 55, 6, 40, 37, 35, 0, 9, 197, 4, 193, 83, 36, 16, 66, 20, 0, 6, 195, 56, 85, 77, 65, 6, 195, 29, 35, 205, 21, 11, 67, 9, 82, 65, 71, 6, 40, 37, 35, 0, 0, 10, 199, 61, 37, 15, 81, 65, 82, 36, 20, 10, 199, 8, 148, 197, 77, 66, 76, 20, 67, 10, 199, 5, 85, 15, 24, 240, 213, 76, 20, 0, 7, 196, 81, 34, 79, 72, 21, 7, 196, 77, 67, 194, 36, 20, 11, 200, 76, 147, 85, 49, 64, 78, 20, 240, 67, 11, 200, 16, 144, 201, 4, 227, 143, 88, 80, 20, 7, 196, 12, 243, 132, 20, 66, 11, 200, 12, 19, 80, 36, 67, 199, 48, 144, 20, 12, 200, 8, 244, 135, 61, 49, 83, 36, 16, 67, 20, 7, 196, 4, 229, 9, 12, 66, 0, 8, 197, 104, 244, 16, 36, 16, 66, 8, 197, 76, 144, 129, 72, 144, 65, 8, 197, 76, 51, 210, 12, 144, 21, 10, 198, 64, 19, 132, 61, 50, 65, 66, 20, 8, 197, 52, 244, 137, 56, 144, 65, 8, 197, 24, 243, 12, 36, 16, 66, 8, 197, 12, 244, 16, 36, 16, 20, 8, 197, 8, 20, 137, 48, 80, 66, 10, 198, 4, 208, 146, 61, 50, 65, 66, 20, 0, 6, 195, 72, 83, 133, 20, 5, 194, 25, 80, 72, 9, 198, 104, 17, 193, 72, 243, 0, 67, 7, 195, 80, 19, 133, 66, 20, 9, 198, 61, 52, 197, 69, 82, 64, 20, 9, 198, 60, 211, 137, 80, 83, 0, 67, 9, 198, 21, 49, 71, 21, 50, 64, 20, 9, 198, 12, 147, 206, 16, 243, 0, 21, 9, 198, 4, 210, 76, 61, 50, 64, 20, 9, 198, 4, 208, 146, 61, 50, 64, 20, 0, 10, 199, 88, 84, 154, 20, 115, 137, 76, 20, 6, 195, 88, 83, 128, 21, 10, 199, 77, 3, 206, 80, 19, 133, 60, 66, 6, 195, 13, 35, 196, 20, 0, 6, 195, 104, 83, 135, 20, 7, 196, 80, 19, 1, 52, 65, 7, 196, 76, 83, 3, 36, 21, 7, 196, 76, 19, 1, 52, 66, 9, 198, 65, 35, 208, 61, 53, 0, 21, 23, 72, 52, 20, 195, 4, 197, 67, 36, 16, 65, 35, 89, 49, 35, 55, 40, 76, 6, 37, 12, 35, 0, 7, 196, 28, 243, 5, 52, 20, 11, 200, 25, 83, 210, 36, 193, 71, 28, 80, 21, 11, 200, 21, 32, 84, 61, 53, 5, 56, 80, 67, 12, 201, 16, 17, 200, 21, 36, 143, 80, 148, 0, 67, 9, 198, 12, 243, 80, 61, 53, 0, 21, 9, 198, 12, 243, 80, 61, 53, 0, 21, 11, 200, 12, 21, 1, 77, 68, 143, 24, 80, 66, 7, 196, 12, 19, 129, 48, 66, 11, 67, 9, 82, 79, 71, 6, 40, 37, 39, 0, 0, 9, 198, 64, 243, 5, 76, 147, 133, 21, 6, 195, 64, 21, 82, 66, 12, 201, 52, 85, 1, 52, 244, 134, 61, 50, 64, 67, 9, 198, 37, 4, 15, 52, 83, 133, 66, 0, 9, 198, 80, 84, 129, 64, 85, 84, 67, 6, 195, 36, 243, 133, 20, 18, 70, 25, 37, 83, 12, 147, 192, 83, 14, 16, 40, 91, 6, 37, 12, 39, 0, 0, 10, 199, 80, 20, 211, 4, 209, 84, 72, 66, 6, 195, 72, 83, 128, 21, 10, 199, 64, 20, 133, 56, 50, 9, 52, 20, 14, 203, 61, 98, 68, 21, 3, 211, 37, 162, 79, 56, 80, 20, 6, 195, 52, 243, 128, 20, 10, 199, 4, 229, 9, 13, 33, 83, 36, 20, 0, 7, 196, 28, 244, 135, 4, 21, 7, 196, 24, 243, 133, 52, 20, 7, 196, 16, 81, 9, 80, 65, 7, 196, 12, 19, 143, 4, 20, 0, 13, 201, 52, 144, 210, 61, 52, 15, 73, 83, 64, 66, 20, 9, 198, 4, 229, 9, 28, 243, 133, 66, 9, 198, 4, 229, 9, 21, 35, 197, 20, 0, 9, 198, 37, 51, 195, 72, 243, 128, 66, 9, 198, 28, 20, 143, 24, 19, 128, 66, 5, 194, 20, 128, 21, 7, 195, 16, 20, 133, 66, 20, 6, 195, 8, 84, 133, 21, 9, 198, 5, 53, 18, 4, 112, 76, 66, 0, 6, 195, 88, 84, 128, 21, 6, 195, 88, 84, 128, 21, 6, 195, 61, 36, 192, 21, 6, 195, 61, 36, 192, 21, 6, 195, 56, 84, 128, 21, 0, 7, 196, 80, 19, 129, 72, 65, 8, 196, 76, 243, 5, 60, 65, 20, 7, 196, 57, 83, 69, 72, 65, 9, 198, 48, 147, 73, 81, 35, 198, 66, 7, 196, 20, 195, 5, 72, 21, 7, 196, 12, 243, 133, 72, 65, 7, 196, 4, 229, 9, 24, 65, 0, 8, 197, 80, 244, 142, 60, 192, 21, 12, 201, 76, 19, 22, 4, 67, 210, 20, 115, 128, 20, 8, 197, 64, 17, 18, 60, 224, 66, 8, 197, 56, 17, 148, 60, 192, 66, 8, 197, 52, 22, 154, 60, 192, 66, 0, 6, 195, 104, 85, 137, 20, 6, 195, 64, 20, 133, 66, 9, 198, 28, 194, 67, 21, 35, 204, 67, 9, 198, 20, 97, 137, 52, 84, 128, 66, 9, 198, 16, 244, 137, 24, 244, 128, 66, 0, 10, 199, 76, 245, 133, 73, 161, 78, 20, 66, 11, 199, 64, 193, 88, 36, 115, 1, 76, 65, 20, 0, 6, 195, 88, 84, 135, 21, 7, 196, 88, 83, 5, 56, 21, 7, 196, 64, 19, 5, 56, 21, 7, 196, 8, 19, 5, 56, 21, 11, 200, 4, 52, 85, 4, 100, 133, 16, 64, 21, 0, 9, 198, 61, 69, 15, 8, 243, 137, 20, 9, 197, 20, 227, 149, 64, 192, 65, 20, 0, 9, 198, 36, 225, 197, 57, 80, 64, 20, 9, 198, 16, 82, 79, 80, 20, 128, 66, 9, 198, 5, 4, 9, 60, 208, 128, 21, 0, 10, 199, 16, 241, 5, 12, 19, 133, 76, 20, 10, 199, 4, 65, 77, 64, 145, 82, 20, 66, 0, 7, 196, 72, 148, 5, 36, 66, 9, 198, 28, 20, 196, 61, 69, 0, 21, 7, 196, 20, 36, 133, 36, 66, 11, 200, 12, 83, 133, 72, 83, 148, 60, 192, 20, 7, 196, 12, 19, 129, 64, 65, 7, 196, 12, 19, 129, 64, 65, 7, 196, 5, 52, 193, 36, 66, 11, 200, 5, 34, 83, 80, 244, 211, 20, 224, 67, 0, 8, 197, 48, 145, 86, 37, 64, 66, 8, 197, 16, 149, 137, 21, 64, 20, 6, 195, 13, 35, 214, 20, 8, 197, 4, 112, 68, 21, 160, 67, 0, 9, 198, 88, 145, 207, 56, 245, 128, 20, 6, 195, 80, 20, 137, 66, 6, 195, 64, 21, 133, 66, 6, 195, 52, 244, 137, 21, 18, 70, 4, 208, 133, 17, 81, 64, 35, 65, 71, 36, 72, 6, 40, 12, 36, 0, 0, 6, 195, 84, 245, 128, 20, 9, 198, 52, 20, 211, 5, 35, 211, 20, 0, 7, 196, 76, 20, 133, 36, 72, 6, 195, 13, 35, 211, 20, 7, 196, 12, 244, 133, 4, 65, 11, 200, 12, 19, 15, 72, 147, 69, 81, 32, 67, 7, 196, 8, 244, 133, 4, 65, 0, 9, 198, 76, 147, 129, 48, 81, 133, 20, 8, 197, 61, 37, 137, 21, 64, 20, 6, 195, 52, 246, 154, 21, 9, 197, 16, 243, 12, 5, 32, 65, 20, 8, 197, 5, 52, 197, 81, 64, 20, 8, 197, 5, 52, 5, 81, 64, 20, 8, 197, 4, 97, 133, 81, 64, 20, 0, 6, 66, 20, 144, 118, 0, 6, 195, 80, 16, 149, 66, 5, 194, 28, 80, 20, 18, 70, 12, 147, 65, 9, 81, 64, 76, 37, 65, 35, 71, 6, 40, 12, 36, 0, 9, 198, 8, 19, 131, 60, 227, 212, 20, 9, 198, 5, 161, 79, 81, 35, 208, 67, 0, 9, 198, 76, 147, 134, 61, 35, 211, 20, 10, 199, 20, 210, 67, 72, 19, 137, 4, 68, 12, 201, 20, 193, 84, 81, 35, 196, 61, 69, 0, 21, 6, 195, 8, 243, 0, 20, 0, 7, 196, 16, 83, 12, 20, 72, 8, 196, 20, 51, 15, 28, 65, 20, 7, 196, 9, 35, 204, 48, 21, 0, 8, 197, 88, 148, 137, 48, 80, 66, 8, 197, 85, 67, 208, 36, 16, 67, 8, 197, 84, 33, 82, 80, 16, 67, 8, 197, 64, 243, 12, 36, 48, 20, 8, 197, 52, 243, 12, 36, 48, 66, 6, 195, 28, 85, 0, 20, 8, 197, 21, 66, 79, 64, 80, 66, 8, 197, 17, 34, 79, 64, 80, 65, 8, 197, 5, 34, 69, 80, 80, 20, 0, 9, 198, 52, 20, 141, 37, 35, 204, 67, 9, 198, 36, 229, 5, 73, 3, 204, 67, 9, 198, 12, 20, 148, 61, 50, 64, 20, 9, 198, 4, 195, 15, 16, 243, 0, 66, 0, 10, 199, 4, 193, 5, 8, 20, 129, 56, 68, 0, 7, 196, 88, 84, 132, 20, 21, 11, 200, 88, 83, 15, 12, 148, 5, 16, 80, 67, 7, 196, 65, 34, 79, 72, 21, 9, 198, 5, 50, 78, 13, 35, 206, 66, 0, 6, 195, 104, 80, 146, 20, 12, 201, 88, 83, 148, 72, 147, 15, 69, 82, 64, 20, 8, 197, 72, 144, 143, 76, 144, 20, 8, 197, 64, 243, 80, 20, 144, 66, 8, 197, 60, 209, 76, 36, 16, 67, 8, 197, 24, 81, 5, 48, 80, 21, 8, 197, 12, 147, 137, 76, 144, 65, 8, 197, 5, 84, 207, 56, 144, 20, 9, 198, 4, 229, 9, 12, 148, 0, 66, 8, 197, 4, 209, 76, 36, 16, 67, 0, 9, 198, 76, 147, 80, 61, 50, 64, 20, 9, 198, 52, 19, 142, 61, 50, 64, 20, 9, 198, 12, 243, 131, 21, 50, 64, 20, 0, 10, 199, 48, 149, 15, 72, 19, 133, 60, 67, 15, 203, 12, 243, 80, 85, 64, 90, 36, 243, 129, 48, 80, 69, 21, 0, 7, 196, 16, 19, 12, 60, 72, 8, 196, 88, 83, 133, 80, 65, 20, 11, 200, 65, 32, 83, 76, 149, 5, 48, 80, 66, 11, 200, 64, 244, 212, 21, 34, 79, 72, 144, 21, 7, 196, 56, 85, 84, 72, 65, 11, 200, 52, 147, 12, 20, 98, 79, 72, 144, 21, 11, 200, 8, 192, 84, 80, 242, 68, 20, 144, 68, 11, 200, 5, 53, 5, 72, 242, 68, 20, 144, 69, 12, 201, 4, 225, 204, 61, 48, 83, 76, 243, 137, 67, 0, 9, 198, 80, 148, 201, 24, 243, 133, 66, 9, 198, 64, 244, 193, 52, 147, 133, 67, 8, 197, 28, 243, 129, 73, 48, 66, 0, 9, 198, 4, 48, 197, 81, 67, 192, 20, 9, 198, 20, 48, 197, 81, 67, 192, 8, 9, 198, 81, 34, 83, 76, 147, 128, 65, 9, 198, 64, 148, 143, 88, 19, 128, 66, 9, 198, 64, 84, 147, 36, 19, 128, 67, 9, 198, 52, 81, 193, 24, 243, 128, 66, 13, 202, 12, 243, 148, 72, 244, 207, 28, 113, 84, 80, 20, 9, 198, 4, 197, 1, 48, 83, 128, 21, 0, 10, 199, 4, 224, 76, 24, 16, 133, 80, 20, 0, 7, 196, 24, 244, 131, 4, 21, 7, 196, 88, 148, 201, 80, 65, 7, 196, 76, 244, 131, 36, 21, 8, 196, 72, 243, 132, 60, 66, 20, 9, 198, 21, 2, 67, 20, 229, 18, 20, 12, 201, 4, 225, 204, 61, 48, 83, 76, 243, 133, 67, 7, 196, 4, 211, 5, 80, 20, 0, 8, 197, 32, 83, 12, 5, 48, 66, 0, 9, 198, 24, 244, 211, 21, 35, 192, 72, 0, 6, 195, 76, 51, 204, 21, 0, 7, 196, 76, 84, 133, 56, 21, 0, 9, 198, 20, 97, 137, 12, 16, 197, 67, 0, 6, 195, 60, 195, 73, 20, 10, 198, 24, 193, 71, 36, 20, 192, 65, 20, 9, 198, 21, 21, 73, 88, 240, 192, 66, 0, 6, 195, 64, 19, 204, 65, 6, 195, 60, 192, 64, 66, 10, 199, 12, 19, 12, 36, 116, 129, 24, 66, 0, 13, 68, 4, 84, 133, 60, 35, 6, 109, 51, 36, 39, 0, 6, 195, 104, 80, 195, 21, 7, 196, 80, 84, 133, 76, 20, 7, 196, 76, 20, 129, 28, 65, 6, 195, 72, 80, 195, 21, 11, 200, 65, 33, 71, 4, 230, 137, 60, 192, 68, 7, 196, 52, 244, 133, 76, 20, 9, 198, 16, 84, 196, 20, 211, 206, 20, 7, 196, 16, 84, 143, 28, 65, 6, 195, 8, 80, 195, 21, 0, 8, 197, 80, 147, 137, 4, 224, 66, 12, 201, 24, 20, 141, 4, 49, 85, 80, 144, 192, 67, 8, 197, 8, 83, 148, 60, 224, 20, 0, 9, 198, 65, 35, 211, 20, 194, 84, 66, 9, 198, 65, 35, 211, 20, 48, 192, 21, 9, 198, 65, 35, 208, 61, 50, 84, 66, 9, 198, 12, 243, 80, 61, 50, 84, 66, 9, 198, 5, 69, 9, 52, 148, 192, 65, 0, 6, 195, 76, 51, 212, 20, 10, 199, 64, 244, 148, 4, 192, 133, 72, 66, 6, 195, 60, 65, 64, 20, 10, 199, 28, 245, 20, 5, 49, 67, 12, 21, 10, 199, 4, 229, 9, 4, 84, 133, 60, 67, 0, 7, 196, 61, 52, 201, 4, 66, 9, 198, 12, 16, 193, 76, 83, 142, 21, 0, 6, 195, 88, 84, 154, 21, 8, 197, 12, 84, 130, 21, 32, 65, 0, 0, 6, 195, 60, 193, 64, 66, 10, 199, 52, 243, 129, 72, 50, 9, 4, 67, 6, 195, 8, 81, 192, 20, 0, 7, 196, 76, 20, 129, 36, 72, 11, 200, 65, 33, 83, 85, 4, 15, 77, 64, 21, 7, 196, 64, 20, 137, 4, 66, 8, 196, 56, 20, 132, 60, 66, 20, 8, 196, 24, 245, 133, 4, 65, 20, 7, 196, 13, 33, 83, 80, 21, 7, 196, 12, 21, 133, 4, 65, 9, 198, 12, 20, 142, 37, 99, 210, 66, 7, 196, 5, 34, 83, 80, 65, 0, 9, 198, 73, 80, 197, 48, 192, 73, 67, 6, 195, 28, 193, 66, 20, 8, 197, 12, 20, 144, 5, 32, 65, 0, 9, 198, 76, 20, 133, 8, 33, 64, 72, 10, 198, 64, 192, 67, 12, 129, 64, 66, 20, 9, 198, 52, 148, 137, 4, 65, 64, 66, 6, 195, 9, 80, 149, 66, 0, 7, 195, 12, 243, 0, 72, 9, 10, 3, 226, 130, 164, 55, 37, 34, 35, 0, 10, 199, 77, 65, 82, 20, 245, 9, 64, 67, 9, 198, 72, 83, 9, 28, 147, 211, 21, 6, 195, 60, 66, 64, 20, 6, 195, 12, 194, 64, 65, 0, 7, 196, 28, 83, 133, 72, 65, 7, 196, 88, 20, 133, 56, 21, 7, 196, 61, 52, 197, 60, 65, 9, 198, 28, 144, 82, 4, 37, 66, 67, 0, 8, 197, 88, 241, 204, 36, 16, 20, 8, 197, 88, 83, 133, 72, 80, 20, 12, 201, 52, 243, 148, 21, 49, 71, 4, 193, 64, 67, 8, 197, 36, 212, 9, 20, 112, 20, 8, 197, 24, 241, 204, 36, 16, 20, 8, 197, 16, 144, 76, 60, 112, 66, 6, 195, 12, 245, 0, 20, 6, 195, 12, 245, 0, 20, 0, 9, 198, 60, 113, 197, 8, 34, 64, 20, 11, 67, 28, 194, 65, 61, 6, 37, 12, 35, 0, 10, 198, 20, 224, 197, 24, 19, 0, 66, 20, 9, 198, 12, 240, 195, 36, 66, 64, 20, 0, 10, 67, 28, 194, 64, 61, 37, 0, 9, 72, 10, 199, 76, 50, 9, 5, 98, 84, 84, 67, 6, 195, 52, 242, 192, 20, 0, 7, 196, 28, 83, 133, 76, 65, 7, 196, 64, 84, 133, 28, 65, 9, 198, 64, 83, 148, 4, 115, 206, 66, 11, 200, 48, 18, 71, 84, 81, 204, 36, 16, 20, 0, 8, 197, 61, 52, 9, 80, 80, 20, 12, 201, 61, 33, 129, 56, 245, 18, 60, 98, 64, 20, 8, 197, 52, 241, 204, 36, 16, 20, 8, 197, 52, 18, 79, 72, 144, 21, 8, 197, 13, 33, 77, 36, 16, 65, 9, 197, 8, 84, 212, 36, 16, 65, 21, 8, 197, 5, 33, 193, 48, 144, 67, 8, 197, 5, 32, 77, 20, 144, 67, 0, 9, 198, 85, 48, 133, 12, 130, 64, 20, 9, 198, 52, 20, 195, 4, 194, 64, 65, 0, 10, 199, 76, 147, 66, 36, 243, 148, 20, 21, 0, 7, 196, 16, 83, 12, 60, 72, 11, 200, 52, 244, 19, 84, 84, 212, 36, 16, 66, 7, 196, 52, 84, 137, 80, 65, 11, 200, 52, 19, 1, 88, 241, 204, 36, 16, 20, 7, 196, 12, 244, 133, 16, 65, 6, 195, 12, 193, 83, 20, 7, 196, 12, 19, 143, 64, 20, 0, 9, 198, 4, 229, 9, 88, 20, 137, 66, 0, 9, 198, 4, 32, 137, 4, 211, 192, 76, 9, 198, 4, 32, 137, 4, 211, 192, 72, 10, 198, 80, 83, 5, 24, 243, 128, 66, 20, 9, 198, 72, 19, 65, 16, 19, 128, 67, 9, 198, 25, 32, 83, 76, 147, 128, 65, 0, 10, 199, 72, 85, 18, 60, 116, 129, 16, 66, 10, 199, 29, 32, 86, 36, 209, 84, 72, 66, 6, 195, 12, 193, 84, 20, 0, 7, 196, 24, 19, 142, 60, 76, 7, 196, 64, 148, 129, 52, 65, 0, 12, 201, 76, 245, 20, 21, 36, 129, 56, 83, 192, 67, 9, 198, 4, 50, 5, 52, 83, 133, 66, 0, 15, 3, 95, 50, 49, 84, 6, 36, 50, 47, 6, 40, 50, 39, 0, 10, 198, 60, 197, 18, 20, 211, 196, 67, 20, 7, 195, 52, 244, 197, 66, 20, 9, 198, 20, 212, 9, 72, 83, 192, 66, 5, 194, 20, 192, 21, 0, 6, 195, 24, 84, 192, 20, 0, 7, 196, 76, 52, 143, 24, 20, 0, 8, 197, 65, 35, 198, 36, 192, 66, 8, 197, 64, 144, 68, 20, 224, 66, 8, 197, 16, 243, 6, 36, 224, 66, 0, 9, 198, 104, 20, 133, 88, 144, 192, 20, 9, 198, 72, 85, 18, 60, 98, 84, 65, 9, 198, 20, 229, 5, 72, 144, 192, 21, 9, 198, 20, 193, 71, 36, 16, 192, 67, 0, 6, 195, 72, 84, 192, 21, 0, 8, 196, 76, 86, 154, 20, 66, 20, 7, 196, 12, 244, 134, 84, 66, 8, 196, 12, 20, 142, 20, 66, 20, 7, 196, 8, 243, 148, 4, 66, 0, 8, 197, 76, 84, 150, 4, 192, 66, 9, 197, 24, 195, 210, 36, 224, 65, 21, 0, 15, 4, 95, 13, 3, 14, 65, 6, 35, 49, 14, 16, 39, 50, 0, 0, 6, 195, 100, 241, 192, 20, 10, 199, 12, 20, 9, 80, 19, 133, 60, 67, 6, 195, 8, 83, 212, 20, 0, 7, 196, 12, 21, 1, 36, 66, 7, 195, 9, 84, 143, 66, 20, 7, 196, 4, 148, 143, 48, 66, 0, 8, 197, 100, 241, 213, 73, 64, 20, 8, 197, 76, 145, 206, 61, 32, 21, 12, 201, 76, 80, 207, 56, 67, 199, 20, 226, 84, 68, 9, 198, 12, 20, 148, 60, 48, 201, 20, 0, 9, 198, 80, 244, 130, 60, 193, 64, 21, 9, 198, 76, 147, 129, 28, 241, 192, 20, 9, 198, 56, 21, 70, 72, 17, 192, 65, 9, 198, 16, 147, 205, 20, 65, 64, 20, 0, 10, 199, 72, 19, 143, 12, 50, 9, 4, 20, 10, 199, 69, 80, 82, 80, 148, 143, 48, 67, 10, 199, 52, 86, 154, 4, 68, 137, 4, 67, 10, 199, 4, 209, 84, 72, 244, 9, 4, 68, 0, 9, 198, 77, 65, 83, 36, 51, 210, 66, 9, 198, 64, 84, 134, 21, 69, 0, 20, 7, 196, 52, 244, 137, 4, 66, 9, 198, 36, 229, 5, 72, 147, 210, 21, 7, 196, 8, 245, 15, 48, 65, 7, 196, 8, 148, 15, 48, 66, 0, 15, 69, 80, 84, 211, 21, 32, 47, 36, 89, 89, 6, 109, 51, 0, 8, 197, 80, 84, 211, 21, 32, 65, 8, 197, 76, 84, 211, 21, 32, 20, 8, 197, 28, 147, 204, 37, 64, 65, 9, 198, 24, 19, 148, 60, 48, 201, 20, 6, 195, 16, 241, 0, 20, 8, 197, 16, 80, 210, 21, 64, 20, 0, 9, 198, 92, 147, 1, 56, 245, 192, 67, 9, 198, 80, 84, 146, 20, 211, 212, 20, 9, 198, 77, 68, 143, 48, 17, 192, 65, 10, 198, 76, 83, 133, 28, 129, 64, 65, 20, 9, 198, 64, 244, 131, 36, 193, 64, 66, 9, 198, 64, 83, 147, 36, 193, 64, 20, 9, 198, 61, 37, 15, 56, 245, 128, 20, 9, 198, 52, 83, 147, 36, 193, 64, 66, 10, 198, 52, 83, 78, 60, 225, 64, 65, 20, 5, 194, 20, 208, 20, 13, 202, 12, 149, 137, 80, 21, 133, 12, 50, 9, 4, 20, 0, 10, 199, 69, 80, 68, 72, 148, 15, 48, 67, 10, 199, 64, 244, 148, 61, 35, 211, 20, 20, 10, 199, 64, 20, 211, 5, 65, 77, 64, 20, 6, 195, 16, 243, 0, 20, 8, 197, 13, 34, 83, 61, 0, 20, 0, 11, 200, 81, 85, 20, 61, 52, 15, 73, 64, 67, 7, 196, 64, 245, 133, 72, 65, 7, 196, 21, 35, 201, 56, 67, 7, 196, 12, 19, 143, 88, 65, 0, 6, 195, 72, 81, 206, 21, 8, 197, 64, 243, 73, 12, 80, 21, 8, 197, 60, 225, 83, 80, 16, 67, 8, 197, 48, 145, 213, 72, 80, 65, 9, 197, 16, 161, 77, 8, 80, 66, 20, 9, 198, 12, 243, 148, 20, 212, 0, 20, 8, 197, 12, 83, 9, 8, 80, 65, 9, 198, 12, 20, 21, 48, 85, 9, 21, 8, 197, 4, 224, 76, 60, 112, 66, 0, 9, 198, 77, 81, 15, 88, 84, 212, 20, 9, 198, 8, 83, 133, 88, 243, 0, 20, 9, 198, 5, 165, 5, 12, 130, 64, 20, 0, 10, 199, 80, 21, 82, 36, 19, 143, 88, 20, 12, 201, 64, 192, 78, 80, 17, 197, 56, 85, 0, 20, 10, 199, 61, 38, 137, 57, 83, 214, 36, 20, 10, 199, 13, 34, 83, 80, 241, 143, 72, 66, 0, 7, 196, 85, 52, 193, 56, 65, 7, 196, 72, 245, 15, 72, 20, 9, 198, 72, 16, 129, 72, 32, 82, 66, 11, 200, 64, 145, 86, 21, 1, 76, 4, 112, 67, 7, 196, 64, 20, 5, 72, 65, 11, 200, 52, 149, 15, 12, 243, 132, 72, 144, 20, 6, 195, 16, 246, 0, 20, 9, 198, 16, 147, 199, 56, 85, 0, 20, 0, 8, 197, 88, 243, 20, 72, 144, 21, 12, 201, 64, 144, 195, 60, 195, 205, 36, 226, 64, 67, 8, 197, 20, 227, 210, 52, 80, 21, 8, 197, 20, 36, 137, 16, 144, 20, 8, 197, 16, 241, 193, 48, 144, 65, 8, 197, 12, 19, 210, 48, 80, 65, 8, 197, 5, 3, 212, 20, 208, 20, 8, 197, 4, 229, 5, 52, 144, 20, 0, 9, 198, 72, 150, 154, 60, 194, 64, 66, 0, 10, 199, 60, 226, 67, 60, 99, 210, 36, 67, 19, 70, 24, 244, 148, 84, 149, 15, 83, 110, 14, 16, 47, 6, 40, 37, 47, 39, 0, 0, 12, 200, 77, 68, 129, 64, 245, 5, 72, 80, 67, 21, 0, 9, 198, 36, 68, 143, 48, 148, 201, 66, 6, 195, 21, 133, 18, 20, 0, 6, 195, 40, 84, 201, 20, 9, 198, 13, 85, 1, 56, 83, 192, 66, 9, 198, 9, 35, 206, 104, 83, 192, 65, 0, 0, 9, 198, 72, 149, 133, 72, 33, 82, 66, 7, 196, 61, 52, 197, 80, 20, 7, 196, 52, 245, 5, 48, 66, 7, 196, 36, 212, 5, 80, 65, 7, 196, 29, 35, 211, 36, 20, 11, 200, 12, 144, 204, 60, 52, 143, 77, 48, 67, 7, 196, 12, 84, 129, 52, 65, 8, 196, 8, 244, 132, 60, 66, 20, 7, 196, 8, 85, 5, 48, 20, 7, 196, 5, 35, 211, 36, 20, 9, 198, 4, 197, 9, 52, 85, 18, 66, 0, 0, 6, 195, 72, 241, 9, 20, 9, 198, 5, 32, 143, 72, 83, 192, 66, 0, 14, 3, 95, 51, 88, 47, 14, 16, 6, 36, 50, 47, 35, 0, 6, 195, 61, 48, 192, 20, 0, 12, 3, 95, 48, 67, 76, 6, 36, 50, 47, 39, 0, 7, 196, 72, 148, 15, 76, 20, 7, 196, 64, 84, 133, 104, 21, 7, 196, 56, 245, 5, 76, 20, 7, 196, 8, 21, 129, 72, 65, 12, 201, 5, 3, 195, 5, 64, 83, 80, 20, 201, 68, 13, 201, 4, 211, 137, 60, 49, 78, 80, 84, 201, 68, 20, 0, 8, 197, 64, 192, 67, 20, 32, 20, 8, 197, 52, 243, 15, 12, 128, 20, 8, 197, 52, 22, 154, 36, 224, 66, 8, 197, 8, 243, 132, 20, 224, 21, 0, 17, 70, 12, 83, 19, 37, 84, 192, 123, 109, 55, 89, 57, 6, 40, 89, 0, 9, 198, 76, 244, 18, 4, 34, 84, 66, 9, 198, 24, 84, 143, 12, 144, 64, 20, 9, 198, 12, 147, 133, 80, 80, 192, 20, 9, 198, 5, 85, 15, 9, 84, 192, 65, 0, 0, 6, 195, 88, 241, 11, 20, 9, 198, 81, 34, 85, 53, 98, 82, 66, 7, 196, 64, 244, 143, 76, 21, 11, 200, 52, 86, 154, 60, 114, 79, 72, 224, 21, 7, 196, 52, 18, 15, 56, 66, 0, 17, 4, 95, 48, 90, 51, 65, 37, 55, 55, 6, 36, 88, 37, 65, 37, 0, 12, 201, 72, 16, 132, 60, 208, 78, 104, 144, 64, 68, 8, 197, 21, 64, 78, 60, 192, 67, 0, 17, 4, 95, 48, 90, 50, 76, 36, 50, 47, 6, 36, 88, 37, 65, 37, 0, 6, 195, 76, 81, 5, 20, 9, 198, 72, 19, 80, 60, 195, 0, 21, 0, 6, 195, 73, 83, 212, 20, 0, 9, 198, 88, 145, 9, 29, 32, 70, 66, 15, 204, 72, 243, 66, 36, 53, 66, 61, 69, 1, 20, 68, 128, 20, 7, 196, 52, 244, 143, 48, 66, 14, 68, 12, 243, 21, 36, 49, 39, 55, 6, 40, 12, 37, 0, 7, 196, 12, 83, 148, 72, 20, 7, 196, 8, 20, 143, 48, 66, 0, 6, 195, 88, 243, 22, 20, 6, 195, 76, 83, 22, 21, 8, 197, 48, 19, 135, 85, 32, 66, 9, 197, 24, 244, 198, 61, 32, 65, 20, 9, 197, 24, 244, 134, 61, 32, 65, 21, 8, 197, 12, 243, 132, 61, 32, 20, 0, 9, 198, 64, 19, 12, 5, 33, 64, 65, 9, 198, 52, 243, 132, 60, 193, 128, 20, 9, 198, 48, 19, 132, 60, 193, 128, 20, 9, 198, 24, 243, 7, 61, 33, 64, 65, 9, 198, 5, 85, 15, 29, 37, 64, 68, 9, 198, 4, 229, 9, 61, 1, 64, 66, 9, 198, 4, 195, 5, 28, 129, 64, 65, 0, 6, 195, 89, 83, 212, 20, 6, 195, 65, 33, 68, 20, 10, 199, 64, 81, 15, 24, 147, 9, 4, 68, 6, 195, 57, 83, 212, 20, 10, 199, 44, 19, 80, 84, 50, 5, 4, 21, 0, 7, 196, 65, 33, 90, 104, 20, 6, 195, 65, 33, 71, 20, 7, 196, 61, 33, 201, 4, 65, 0, 10, 198, 65, 33, 83, 8, 149, 5, 65, 20, 12, 201, 64, 244, 148, 61, 97, 78, 21, 33, 64, 20, 6, 195, 57, 83, 214, 20, 9, 198, 36, 225, 137, 56, 149, 1, 68, 8, 197, 28, 130, 79, 81, 64, 21, 8, 197, 12, 244, 211, 61, 96, 65, 0, 6, 194, 48, 16, 72, 9, 16, 3, 95, 49, 57, 72, 37, 76, 35, 50, 50, 6, 39, 84, 36, 0, 9, 198, 84, 224, 78, 36, 209, 64, 66, 13, 202, 77, 3, 5, 56, 243, 69, 28, 19, 9, 4, 69, 6, 195, 52, 18, 5, 66, 9, 198, 5, 3, 195, 61, 1, 64, 66, 0, 14, 3, 95, 49, 56, 72, 37, 76, 6, 110, 47, 12, 39, 0, 6, 195, 88, 243, 12, 21, 6, 195, 88, 84, 208, 20, 10, 199, 72, 240, 149, 77, 65, 90, 104, 20, 6, 195, 52, 244, 212, 21, 10, 199, 52, 148, 207, 28, 147, 137, 4, 68, 0, 7, 196, 28, 146, 143, 56, 66, 7, 196, 12, 147, 137, 72, 65, 7, 196, 4, 197, 133, 60, 65, 0, 8, 197, 76, 243, 65, 48, 144, 65, 8, 197, 76, 100, 133, 28, 144, 20, 8, 197, 57, 83, 69, 72, 144, 65, 12, 201, 20, 193, 84, 81, 35, 206, 88, 243, 20, 68, 8, 197, 12, 19, 129, 64, 80, 65, 0, 9, 198, 52, 19, 5, 88, 243, 0, 20, 9, 198, 8, 148, 197, 57, 162, 64, 20, 0, 10, 199, 88, 19, 16, 4, 229, 5, 56, 21, 10, 199, 76, 145, 206, 61, 34, 76, 20, 67, 10, 199, 72, 147, 143, 64, 149, 5, 12, 20, 10, 199, 64, 145, 84, 72, 20, 143, 40, 20, 6, 195, 8, 243, 12, 21, 0, 7, 196, 88, 148, 5, 72, 65, 7, 196, 80, 245, 1, 56, 65, 7, 196, 76, 21, 1, 56, 65, 7, 196, 64, 84, 140, 20, 66, 7, 196, 48, 21, 5, 72, 65, 7, 196, 12, 19, 148, 84, 66, 0, 8, 197, 4, 229, 5, 72, 16, 66, 8, 197, 69, 81, 76, 48, 16, 72, 8, 197, 88, 149, 133, 72, 144, 65, 9, 197, 88, 145, 193, 56, 240, 67, 20, 8, 197, 76, 81, 9, 12, 144, 21, 9, 197, 65, 35, 212, 20, 240, 65, 20, 8, 197, 52, 81, 9, 84, 208, 20, 8, 197, 17, 81, 207, 56, 112, 20, 8, 197, 12, 246, 79, 80, 80, 20, 9, 197, 12, 84, 193, 72, 240, 67, 20, 8, 197, 5, 32, 143, 72, 80, 67, 8, 197, 4, 225, 197, 48, 144, 65, 0, 13, 3, 95, 49, 49, 6, 40, 50, 72, 37, 76, 37, 0, 9, 198, 76, 20, 141, 5, 66, 64, 65, 9, 198, 64, 149, 20, 60, 226, 64, 65, 6, 195, 52, 19, 5, 20, 6, 195, 52, 19, 5, 66, 9, 198, 28, 84, 212, 85, 34, 64, 65, 9, 198, 8, 21, 20, 21, 34, 64, 66, 9, 198, 8, 17, 206, 60, 194, 64, 66, 0, 16, 3, 95, 50, 56, 84, 6, 36, 50, 47, 6, 110, 47, 12, 39, 0, 12, 3, 95, 49, 48, 72, 37, 6, 36, 76, 37, 0, 10, 199, 77, 80, 129, 13, 21, 69, 60, 66, 14, 203, 64, 144, 83, 81, 34, 78, 61, 1, 78, 36, 16, 70, 9, 198, 61, 37, 15, 81, 66, 67, 20, 9, 198, 20, 193, 84, 81, 34, 67, 20, 0, 15, 3, 95, 49, 51, 47, 14, 16, 6, 36, 72, 37, 76, 37, 0, 6, 195, 88, 243, 7, 20, 11, 200, 72, 17, 9, 12, 241, 129, 56, 144, 67, 7, 196, 64, 148, 143, 64, 20, 7, 196, 52, 19, 149, 48, 66, 11, 200, 12, 130, 82, 60, 112, 76, 20, 240, 67, 0, 13, 3, 95, 49, 50, 72, 6, 39, 72, 37, 76, 37, 0, 9, 198, 16, 147, 211, 13, 84, 137, 66, 9, 198, 4, 229, 9, 80, 84, 201, 66, 8, 197, 4, 35, 205, 5, 48, 66, 0, 15, 3, 95, 49, 53, 49, 122, 6, 37, 65, 72, 37, 76, 37, 0, 9, 198, 77, 68, 133, 57, 83, 192, 20, 6, 195, 40, 243, 5, 20, 12, 201, 36, 68, 143, 20, 193, 84, 81, 34, 67, 20, 0, 18, 3, 95, 49, 52, 49, 122, 35, 47, 12, 6, 110, 51, 72, 37, 76, 37, 0, 10, 199, 52, 84, 197, 56, 50, 9, 52, 20, 0, 7, 196, 12, 244, 147, 4, 21, 17, 3, 95, 49, 55, 72, 37, 76, 35, 89, 12, 6, 109, 47, 12, 36, 0, 9, 198, 72, 243, 66, 60, 81, 18, 20, 15, 204, 64, 244, 148, 4, 83, 9, 12, 245, 20, 21, 34, 64, 20, 8, 196, 64, 85, 1, 48, 65, 20, 7, 196, 64, 84, 137, 52, 66, 9, 198, 64, 84, 137, 52, 85, 18, 66, 7, 196, 28, 148, 5, 80, 20, 7, 196, 12, 244, 5, 80, 20, 16, 204, 12, 243, 148, 4, 50, 9, 48, 243, 69, 81, 34, 64, 68, 20, 9, 198, 12, 20, 146, 60, 64, 78, 66, 0, 13, 3, 95, 49, 54, 89, 6, 36, 72, 37, 76, 37, 0, 9, 198, 76, 244, 137, 76, 243, 5, 66, 9, 198, 25, 37, 77, 20, 230, 137, 20, 9, 198, 12, 20, 146, 60, 48, 201, 20, 9, 198, 12, 19, 12, 36, 51, 5, 65, 0, 6, 195, 61, 52, 193, 21, 9, 198, 12, 21, 1, 48, 85, 20, 20, 0, 15, 3, 95, 55, 88, 89, 36, 47, 12, 6, 35, 50, 47, 35, 0, 0, 7, 196, 77, 81, 204, 36, 72, 7, 196, 72, 21, 5, 60, 65, 7, 196, 52, 241, 15, 12, 20, 7, 196, 48, 84, 18, 20, 20, 7, 196, 8, 21, 133, 72, 65, 0, 9, 198, 64, 83, 133, 48, 244, 5, 66, 9, 198, 4, 229, 9, 48, 244, 5, 66, 8, 197, 4, 225, 84, 60, 192, 67, 0, 6, 195, 88, 245, 9, 20, 9, 198, 88, 20, 137, 21, 64, 64, 68, 9, 198, 76, 147, 149, 21, 52, 192, 20, 9, 198, 65, 35, 212, 61, 66, 80, 66, 9, 198, 65, 33, 84, 21, 34, 84, 66, 9, 198, 61, 69, 1, 20, 68, 128, 20, 0, 9, 198, 65, 84, 144, 85, 33, 79, 66, 0, 8, 196, 80, 85, 1, 56, 65, 20, 7, 196, 76, 149, 1, 72, 66, 7, 196, 32, 84, 150, 20, 66, 0, 8, 197, 64, 83, 148, 60, 64, 20, 8, 197, 52, 84, 212, 60, 192, 21, 9, 198, 28, 19, 132, 60, 193, 137, 20, 8, 197, 12, 83, 148, 60, 192, 20, 0, 10, 198, 80, 83, 5, 80, 86, 20, 67, 20, 13, 67, 65, 37, 65, 48, 14, 16, 6, 40, 12, 35, 0, 9, 198, 64, 19, 16, 20, 36, 128, 65, 13, 202, 28, 194, 80, 80, 241, 15, 57, 66, 68, 36, 20, 9, 198, 16, 83, 79, 13, 34, 84, 66, 0, 8, 197, 37, 51, 212, 61, 0, 66, 8, 197, 21, 83, 79, 49, 0, 20, 0, 10, 198, 80, 83, 5, 29, 32, 70, 66, 20, 7, 196, 76, 81, 9, 4, 20, 7, 196, 76, 52, 143, 80, 20, 11, 200, 65, 35, 212, 61, 53, 5, 48, 192, 21, 7, 196, 61, 36, 207, 48, 21, 7, 196, 56, 84, 143, 48, 65, 7, 196, 12, 20, 143, 80, 20, 0, 9, 198, 24, 16, 197, 88, 21, 5, 76, 9, 198, 80, 83, 199, 56, 145, 5, 20, 9, 198, 37, 51, 195, 72, 21, 5, 66, 0, 10, 198, 56, 85, 20, 5, 33, 64, 65, 20, 9, 198, 52, 19, 12, 5, 33, 64, 65, 9, 198, 36, 228, 213, 9, 33, 64, 65, 9, 198, 25, 83, 133, 9, 33, 64, 65, 0, 10, 199, 76, 245, 20, 61, 3, 211, 80, 21, 10, 199, 56, 144, 207, 52, 81, 9, 4, 20, 0, 7, 196, 8, 244, 146, 60, 21, 11, 200, 64, 246, 154, 4, 225, 200, 21, 32, 66, 7, 196, 24, 244, 147, 20, 21, 7, 196, 24, 83, 20, 72, 21, 9, 198, 24, 20, 195, 21, 69, 0, 21, 9, 198, 24, 16, 195, 21, 69, 0, 21, 9, 198, 12, 243, 132, 61, 69, 0, 21, 0, 9, 198, 52, 150, 20, 20, 50, 9, 20, 9, 198, 36, 65, 78, 80, 149, 1, 68, 12, 201, 16, 144, 201, 5, 52, 197, 81, 65, 64, 20, 8, 197, 4, 226, 67, 21, 64, 20, 0, 5, 194, 52, 16, 8, 9, 198, 89, 83, 20, 85, 33, 64, 65, 9, 198, 85, 33, 84, 21, 33, 64, 67, 9, 198, 77, 64, 84, 21, 33, 64, 66, 9, 198, 76, 147, 131, 61, 1, 64, 65, 9, 198, 52, 85, 20, 21, 33, 64, 20, 9, 198, 52, 85, 5, 61, 33, 64, 66, 9, 198, 13, 32, 84, 21, 33, 64, 66, 0, 10, 199, 76, 52, 137, 88, 19, 137, 4, 67, 10, 199, 65, 34, 71, 36, 243, 137, 4, 67, 10, 199, 64, 192, 78, 5, 33, 201, 4, 66, 10, 199, 52, 144, 83, 80, 83, 137, 4, 68, 6, 195, 24, 243, 0, 20, 10, 199, 13, 34, 79, 28, 83, 137, 4, 68, 10, 199, 12, 20, 15, 48, 147, 133, 4, 67, 0, 10, 198, 76, 50, 5, 81, 66, 78, 65, 21, 7, 196, 56, 245, 133, 72, 65, 9, 198, 52, 19, 147, 84, 85, 0, 20, 10, 198, 16, 81, 137, 12, 149, 0, 65, 20, 7, 196, 4, 229, 5, 72, 65, 0, 9, 198, 81, 34, 70, 60, 115, 9, 20, 9, 198, 80, 83, 5, 24, 147, 13, 67, 8, 197, 76, 49, 80, 76, 144, 20, 8, 197, 72, 240, 130, 36, 16, 20, 8, 197, 52, 147, 69, 76, 144, 20, 8, 197, 52, 81, 15, 48, 80, 65, 6, 195, 24, 245, 0, 20, 12, 201, 24, 243, 148, 4, 224, 70, 72, 81, 4, 21, 8, 197, 12, 194, 80, 20, 240, 65, 0, 10, 198, 81, 33, 86, 21, 34, 64, 65, 20, 9, 198, 36, 228, 213, 9, 34, 64, 65, 9, 198, 36, 228, 197, 81, 66, 64, 20, 9, 198, 12, 244, 129, 105, 160, 84, 66, 0, 10, 199, 77, 64, 84, 60, 193, 5, 72, 20, 10, 199, 52, 147, 132, 5, 81, 193, 76, 65, 10, 199, 24, 147, 15, 13, 32, 84, 20, 66, 10, 199, 21, 38, 133, 28, 245, 137, 56, 67, 6, 195, 12, 84, 16, 21, 10, 199, 8, 19, 131, 5, 35, 212, 80, 21, 0, 7, 196, 76, 83, 154, 4, 8, 7, 196, 80, 21, 1, 72, 65, 7, 196, 80, 20, 9, 72, 65, 7, 196, 77, 65, 76, 48, 21, 8, 196, 76, 85, 133, 76, 65, 20, 11, 200, 76, 20, 146, 4, 49, 78, 36, 16, 20, 7, 196, 65, 35, 218, 36, 66, 7, 196, 64, 21, 5, 72, 65, 7, 196, 52, 83, 148, 20, 21, 7, 196, 36, 229, 133, 72, 21, 11, 200, 24, 245, 15, 72, 149, 15, 12, 48, 21, 7, 196, 12, 21, 5, 56, 21, 7, 196, 5, 52, 207, 72, 65, 9, 198, 4, 229, 9, 16, 245, 0, 66, 0, 8, 197, 60, 211, 137, 84, 208, 20, 9, 198, 60, 208, 89, 100, 17, 9, 66, 9, 198, 52, 147, 149, 80, 243, 9, 66, 9, 198, 28, 20, 129, 57, 162, 65, 67, 8, 197, 24, 83, 20, 72, 80, 21, 8, 197, 12, 20, 212, 36, 112, 66, 8, 197, 8, 21, 78, 20, 144, 67, 0, 9, 198, 81, 33, 86, 37, 34, 64, 65, 9, 198, 64, 244, 212, 21, 34, 64, 65, 9, 198, 64, 84, 133, 80, 243, 0, 66, 9, 198, 52, 86, 133, 57, 162, 64, 20, 0, 12, 3, 95, 50, 88, 84, 6, 36, 50, 47, 57, 0, 10, 199, 81, 33, 78, 80, 83, 142, 36, 20, 10, 199, 12, 130, 82, 61, 3, 212, 20, 20, 0, 7, 196, 80, 245, 5, 52, 20, 11, 200, 77, 84, 18, 20, 208, 90, 36, 16, 68, 7, 196, 64, 20, 143, 64, 20, 11, 200, 56, 85, 82, 61, 69, 5, 72, 144, 20, 11, 200, 12, 21, 129, 48, 48, 86, 36, 16, 68, 0, 12, 201, 80, 148, 193, 56, 245, 20, 21, 34, 64, 20, 12, 201, 64, 20, 129, 12, 85, 1, 52, 243, 0, 69, 12, 201, 48, 84, 9, 16, 245, 20, 21, 34, 64, 20, 9, 198, 4, 227, 137, 8, 19, 5, 66, 0, 9, 198, 76, 51, 210, 72, 85, 20, 20, 0, 6, 195, 65, 33, 84, 20, 10, 199, 64, 84, 137, 77, 64, 83, 36, 66, 10, 199, 52, 85, 1, 77, 64, 83, 36, 66, 10, 199, 37, 4, 15, 64, 245, 1, 52, 67, 11, 199, 36, 68, 143, 12, 81, 129, 48, 67, 20, 6, 195, 28, 85, 20, 20, 9, 198, 8, 83, 12, 61, 97, 83, 20, 0, 6, 195, 81, 33, 83, 20, 6, 195, 81, 33, 83, 20, 9, 198, 76, 50, 5, 48, 85, 18, 65, 7, 196, 64, 245, 1, 48, 65, 7, 196, 60, 97, 137, 16, 20, 12, 200, 29, 32, 78, 60, 195, 5, 73, 48, 67, 21, 0, 12, 201, 88, 83, 148, 72, 147, 15, 69, 83, 192, 66, 9, 198, 80, 243, 20, 20, 50, 9, 20, 9, 198, 52, 19, 15, 12, 50, 9, 20, 9, 198, 36, 225, 133, 16, 83, 5, 21, 6, 195, 12, 85, 18, 21, 0, 6, 195, 52, 147, 73, 66, 9, 198, 36, 225, 197, 57, 83, 192, 20, 0, 6, 195, 52, 144, 64, 72, 12, 201, 12, 149, 15, 76, 50, 5, 48, 85, 18, 67, 12, 201, 12, 130, 85, 16, 147, 5, 81, 65, 82, 20, 6, 195, 8, 240, 64, 20, 0, 7, 196, 28, 245, 20, 4, 21, 7, 196, 12, 244, 20, 36, 20, 7, 196, 8, 22, 129, 72, 66, 0, 8, 197, 25, 32, 71, 60, 192, 65, 0, 9, 198, 88, 19, 5, 72, 144, 64, 66, 9, 198, 76, 84, 85, 4, 196, 192, 66, 6, 195, 56, 243, 73, 20, 9, 198, 52, 20, 207, 88, 144, 64, 20, 10, 198, 28, 83, 205, 21, 68, 128, 66, 20, 9, 198, 21, 48, 77, 21, 68, 128, 66, 9, 198, 8, 243, 129, 72, 48, 68, 66, 6, 195, 8, 241, 77, 20, 0, 10, 199, 88, 84, 208, 5, 50, 65, 56, 68, 10, 199, 76, 96, 82, 24, 19, 12, 36, 67, 6, 195, 44, 80, 64, 21, 10, 199, 12, 20, 212, 20, 195, 15, 56, 67, 0, 14, 3, 95, 63, 63, 89, 6, 37, 65, 71, 39, 55, 39, 0, 7, 196, 12, 20, 146, 20, 66, 11, 200, 4, 224, 84, 72, 240, 195, 60, 192, 20, 0, 12, 201, 21, 53, 5, 57, 50, 77, 21, 68, 128, 67, 0, 9, 198, 88, 144, 193, 72, 144, 64, 67, 9, 198, 88, 149, 15, 72, 144, 64, 21, 10, 198, 80, 148, 133, 76, 144, 64, 66, 20, 13, 202, 52, 20, 147, 36, 51, 214, 21, 65, 82, 20, 20, 9, 198, 28, 19, 5, 72, 144, 64, 66, 9, 198, 21, 81, 197, 56, 144, 64, 20, 9, 198, 21, 81, 143, 72, 144, 64, 68, 0, 6, 195, 52, 145, 64, 72, 15, 3, 95, 52, 88, 49, 122, 35, 51, 6, 35, 50, 47, 35, 0, 10, 199, 77, 2, 78, 21, 67, 204, 36, 66, 14, 203, 64, 20, 129, 48, 193, 76, 21, 2, 80, 20, 64, 69, 10, 199, 52, 81, 193, 12, 243, 15, 56, 20, 0, 9, 198, 76, 244, 208, 21, 69, 0, 20, 6, 195, 60, 209, 71, 20, 7, 196, 16, 85, 143, 80, 20, 7, 196, 12, 244, 9, 4, 20, 0, 8, 197, 77, 2, 82, 37, 64, 65, 8, 197, 64, 193, 84, 81, 32, 20, 9, 198, 64, 145, 15, 12, 50, 9, 20, 9, 198, 25, 83, 7, 20, 230, 137, 20, 12, 201, 12, 20, 16, 20, 195, 1, 56, 144, 64, 68, 12, 201, 5, 163, 207, 77, 1, 82, 52, 144, 64, 69, 12, 201, 5, 84, 212, 72, 19, 1, 76, 144, 64, 68, 0, 9, 198, 64, 243, 12, 36, 49, 64, 20, 0, 10, 199, 61, 2, 83, 80, 241, 15, 52, 67, 6, 195, 60, 193, 192, 20, 6, 195, 56, 241, 64, 20, 6, 195, 56, 241, 64, 66, 0, 15, 204, 81, 35, 205, 8, 240, 201, 80, 244, 5, 56, 144, 64, 70, 7, 196, 48, 241, 15, 48, 65, 9, 198, 36, 209, 78, 60, 99, 210, 67, 7, 196, 24, 84, 137, 4, 65, 9, 198, 12, 19, 12, 36, 49, 66, 20, 0, 12, 201, 76, 245, 20, 61, 52, 5, 12, 145, 64, 20, 12, 201, 64, 243, 148, 5, 52, 201, 21, 97, 64, 20, 8, 197, 53, 83, 148, 5, 160, 66, 9, 197, 48, 85, 129, 57, 64, 65, 20, 9, 197, 12, 243, 80, 85, 64, 65, 20, 8, 197, 4, 213, 76, 21, 64, 20, 0, 6, 194, 48, 80, 72, 9, 9, 198, 52, 17, 15, 56, 145, 64, 67, 9, 198, 36, 228, 201, 20, 209, 64, 20, 9, 198, 16, 149, 20, 60, 225, 192, 20, 13, 202, 16, 17, 200, 21, 36, 143, 80, 148, 9, 4, 69, 0, 16, 3, 95, 53, 88, 76, 37, 50, 49, 122, 6, 35, 50, 47, 35, 0, 10, 199, 88, 145, 5, 60, 51, 9, 64, 68, 10, 199, 52, 145, 204, 36, 244, 137, 4, 67, 6, 195, 52, 16, 84, 66, 6, 195, 28, 243, 0, 20, 10, 199, 9, 34, 83, 28, 245, 137, 4, 20, 0, 7, 196, 77, 33, 84, 20, 72, 9, 198, 81, 32, 78, 76, 149, 0, 65, 7, 196, 77, 70, 76, 20, 66, 11, 200, 65, 34, 77, 60, 113, 78, 37, 64, 67, 9, 198, 64, 19, 13, 4, 227, 214, 20, 9, 198, 60, 36, 207, 48, 85, 0, 20, 7, 196, 48, 84, 18, 36, 20, 7, 196, 24, 21, 9, 12, 66, 0, 6, 195, 72, 245, 26, 20, 8, 197, 72, 20, 1, 12, 80, 66, 9, 198, 56, 244, 207, 12, 243, 73, 20, 6, 195, 48, 85, 0, 20, 6, 195, 28, 245, 0, 20, 12, 201, 24, 21, 20, 37, 52, 5, 12, 145, 64, 20, 8, 197, 20, 193, 85, 76, 144, 66, 10, 198, 12, 147, 9, 20, 114, 65, 67, 20, 8, 197, 12, 19, 69, 72, 144, 65, 8, 197, 4, 115, 206, 36, 16, 67, 10, 198, 4, 48, 78, 80, 241, 9, 67, 20, 0, 9, 198, 81, 33, 68, 36, 50, 64, 21, 9, 198, 12, 147, 9, 20, 114, 64, 20, 9, 198, 8, 240, 66, 16, 147, 0, 67, 9, 198, 4, 211, 210, 72, 82, 64, 67, 0, 9, 198, 24, 16, 197, 88, 19, 79, 76, 6, 195, 76, 82, 64, 72, 7, 195, 88, 242, 64, 76, 9, 7, 195, 56, 242, 64, 76, 9, 10, 199, 16, 244, 15, 48, 21, 143, 72, 21, 10, 199, 5, 36, 15, 13, 32, 84, 20, 66, 0, 12, 200, 5, 69, 18, 5, 97, 82, 76, 240, 28, 67, 8, 196, 76, 245, 5, 72, 66, 21, 11, 200, 60, 229, 15, 28, 83, 133, 76, 144, 67, 11, 200, 52, 19, 135, 36, 21, 15, 36, 16, 21, 11, 200, 52, 19, 9, 56, 51, 206, 36, 16, 68, 9, 198, 48, 19, 80, 72, 81, 0, 20, 11, 200, 29, 32, 77, 36, 224, 67, 20, 80, 67, 11, 200, 13, 33, 86, 4, 192, 207, 72, 80, 20, 7, 196, 12, 244, 148, 20, 21, 7, 196, 8, 245, 133, 76, 20, 8, 196, 8, 85, 15, 56, 66, 20, 0, 8, 197, 69, 81, 76, 48, 80, 72, 8, 197, 72, 17, 9, 12, 80, 66, 9, 198, 64, 20, 129, 80, 242, 65, 21, 8, 197, 25, 80, 211, 36, 16, 65, 8, 197, 25, 34, 71, 36, 16, 65, 9, 198, 24, 19, 1, 76, 50, 65, 67, 9, 198, 21, 84, 137, 80, 210, 65, 68, 8, 197, 5, 32, 207, 72, 80, 65, 9, 198, 5, 3, 208, 81, 145, 205, 66, 8, 197, 4, 193, 78, 36, 16, 20, 0, 9, 198, 16, 244, 143, 80, 82, 64, 67, 7, 195, 4, 147, 69, 66, 20, 0, 15, 3, 95, 54, 88, 89, 36, 89, 89, 6, 35, 50, 47, 35, 0, 10, 199, 88, 19, 4, 37, 51, 212, 80, 21, 10, 199, 80, 85, 18, 5, 3, 196, 20, 66, 6, 195, 76, 85, 20, 20, 6, 195, 76, 85, 20, 20, 6, 195, 8, 243, 64, 20, 0, 11, 200, 77, 2, 65, 56, 21, 15, 36, 16, 21, 11, 200, 64, 192, 83, 52, 241, 5, 76, 208, 20, 7, 196, 56, 80, 149, 48, 21, 11, 200, 52, 83, 1, 56, 51, 206, 36, 16, 68, 0, 0, 9, 198, 4, 32, 137, 4, 227, 192, 76, 6, 195, 12, 195, 197, 20, 18, 70, 4, 32, 129, 36, 227, 192, 35, 71, 12, 35, 6, 37, 12, 50, 39, 0, 0, 6, 195, 85, 5, 80, 65, 6, 195, 72, 245, 20, 21, 10, 199, 64, 84, 137, 25, 32, 83, 36, 66, 10, 199, 61, 37, 15, 12, 83, 148, 72, 20, 14, 203, 36, 229, 5, 48, 194, 71, 32, 83, 154, 36, 16, 20, 9, 198, 8, 20, 201, 48, 85, 83, 21, 6, 195, 4, 131, 192, 66, 0, 9, 198, 64, 20, 129, 52, 85, 18, 66, 11, 200, 64, 16, 137, 48, 195, 206, 37, 48, 20, 7, 196, 21, 34, 90, 104, 65, 7, 196, 20, 54, 133, 52, 20, 7, 196, 12, 21, 5, 80, 20, 7, 196, 8, 85, 9, 48, 21, 0, 6, 195, 28, 195, 194, 20, 0, 6, 194, 36, 192, 72, 9, 9, 198, 56, 144, 207, 16, 83, 64, 20, 9, 198, 20, 225, 137, 80, 85, 84, 67, 0, 12, 201, 65, 35, 198, 60, 225, 9, 52, 85, 18, 67, 0, 9, 198, 72, 85, 143, 49, 97, 82, 20, 9, 198, 64, 243, 3, 21, 97, 82, 66, 11, 200, 16, 243, 85, 76, 227, 214, 5, 48, 20, 9, 198, 12, 243, 132, 60, 210, 78, 66, 0, 9, 197, 64, 243, 12, 36, 224, 65, 20, 8, 197, 9, 32, 68, 4, 224, 65, 0, 6, 195, 61, 68, 133, 21, 9, 198, 52, 148, 197, 72, 144, 64, 66, 9, 198, 25, 83, 137, 88, 144, 64, 67, 9, 198, 21, 81, 15, 12, 144, 64, 20, 9, 198, 16, 21, 1, 72, 144, 64, 67, 9, 198, 13, 84, 129, 104, 144, 64, 67, 9, 198, 12, 19, 15, 72, 144, 64, 67, 9, 198, 5, 37, 5, 72, 144, 64, 66, 9, 198, 5, 35, 79, 56, 144, 64, 67, 9, 198, 4, 192, 129, 56, 144, 64, 67, 9, 198, 4, 32, 129, 104, 144, 64, 67, 0, 10, 199, 64, 83, 148, 5, 65, 85, 12, 67, 9, 198, 5, 33, 78, 4, 49, 79, 67, 0, 12, 201, 56, 144, 193, 72, 17, 213, 20, 228, 197, 21, 12, 201, 16, 85, 84, 21, 35, 211, 80, 243, 73, 20, 0, 8, 197, 81, 32, 80, 4, 224, 65, 8, 197, 80, 244, 144, 20, 64, 20, 8, 197, 76, 84, 137, 60, 192, 66, 8, 197, 28, 144, 86, 20, 224, 21, 8, 197, 12, 244, 146, 36, 64, 66, 9, 198, 12, 19, 16, 21, 53, 9, 67, 8, 197, 4, 229, 5, 56, 224, 21, 0, 9, 198, 76, 51, 210, 16, 144, 64, 66, 9, 198, 64, 243, 9, 104, 144, 64, 67, 9, 198, 56, 145, 197, 72, 144, 64, 66, 9, 198, 52, 21, 5, 72, 144, 64, 66, 9, 198, 48, 149, 1, 56, 144, 64, 67, 9, 198, 48, 81, 193, 104, 144, 64, 67, 9, 198, 36, 212, 12, 36, 50, 84, 66, 0, 14, 3, 95, 56, 88, 39, 47, 12, 6, 35, 50, 47, 35, 0, 6, 195, 104, 241, 64, 20, 0, 11, 200, 88, 19, 2, 72, 85, 133, 56, 224, 21, 11, 200, 64, 244, 148, 36, 48, 201, 60, 192, 67, 11, 200, 64, 21, 76, 36, 192, 84, 36, 224, 68, 9, 198, 12, 244, 208, 21, 69, 0, 20, 0, 12, 201, 96, 83, 143, 28, 195, 211, 76, 144, 64, 68, 12, 201, 80, 84, 141, 60, 51, 208, 64, 144, 64, 20, 12, 201, 76, 84, 211, 84, 241, 143, 8, 144, 64, 68, 8, 197, 61, 68, 129, 57, 64, 65, 8, 197, 21, 48, 69, 17, 32, 20, 12, 201, 4, 229, 9, 52, 21, 5, 72, 144, 64, 68, 0, 9, 198, 65, 33, 67, 60, 49, 64, 20, 10, 198, 5, 85, 15, 56, 241, 64, 67, 20, 0, 10, 199, 37, 51, 212, 72, 244, 9, 4, 68, 0, 7, 196, 80, 240, 137, 4, 66, 7, 196, 77, 1, 79, 80, 20, 7, 196, 52, 84, 131, 20, 66, 0, 8, 197, 80, 83, 80, 61, 32, 65, 8, 197, 80, 83, 80, 61, 32, 20, 8, 197, 5, 52, 207, 73, 64, 21, 0, 5, 194, 32, 240, 72, 6, 195, 52, 145, 73, 72, 9, 198, 76, 81, 213, 4, 49, 64, 66, 9, 198, 61, 33, 70, 36, 49, 64, 21, 6, 195, 56, 241, 77, 20, 0, 14, 3, 95, 57, 88, 50, 39, 84, 6, 35, 50, 47, 35, 0, 10, 199, 81, 32, 84, 80, 244, 137, 4, 67, 9, 198, 60, 198, 78, 80, 131, 211, 65, 10, 199, 48, 81, 193, 80, 244, 137, 4, 68, 0, 7, 196, 65, 33, 84, 20, 20, 11, 200, 12, 20, 212, 20, 195, 149, 61, 96, 20, 9, 198, 4, 194, 81, 84, 245, 0, 66, 0, 8, 197, 88, 84, 143, 48, 144, 65, 8, 197, 80, 244, 129, 12, 80, 66, 8, 197, 52, 244, 134, 20, 208, 20, 8, 197, 28, 244, 135, 36, 16, 65, 8, 197, 28, 144, 67, 60, 208, 65, 8, 197, 24, 244, 135, 36, 16, 65, 8, 197, 13, 80, 133, 8, 80, 20, 8, 197, 5, 35, 79, 16, 144, 20, 0, 9, 198, 80, 245, 15, 28, 243, 0, 67, 0, 10, 199, 81, 33, 83, 76, 85, 20, 20, 20, 11, 199, 12, 84, 150, 21, 65, 82, 36, 66, 20, 0, 11, 200, 84, 226, 86, 21, 36, 201, 80, 16, 69, 9, 198, 37, 4, 15, 48, 149, 0, 66, 9, 198, 12, 244, 9, 48, 245, 0, 20, 9, 198, 5, 50, 78, 80, 245, 0, 66, 0, 9, 197, 88, 81, 5, 72, 80, 66, 21, 8, 197, 56, 245, 77, 20, 16, 21, 10, 198, 56, 244, 150, 20, 114, 65, 66, 20, 8, 197, 48, 148, 19, 36, 16, 65, 12, 201, 16, 85, 84, 21, 35, 206, 60, 210, 64, 20, 0, 15, 3, 95, 63, 65, 55, 36, 47, 12, 6, 36, 12, 51, 35, 0, 9, 198, 85, 50, 71, 56, 243, 0, 67, 10, 198, 12, 241, 199, 36, 243, 0, 65, 20, 9, 198, 12, 85, 14, 36, 50, 64, 20, 9, 198, 12, 20, 137, 56, 243, 0, 66, 9, 198, 5, 4, 15, 28, 114, 64, 20, 0, 10, 199, 12, 83, 148, 72, 145, 149, 28, 66, 0, 9, 198, 37, 51, 204, 4, 35, 206, 20, 7, 196, 9, 37, 83, 36, 66, 0, 12, 201, 52, 243, 148, 20, 114, 79, 72, 114, 64, 21, 8, 197, 45, 32, 75, 61, 112, 66, 0, 0, 0, 8, 196, 72, 81, 15, 96, 66, 20, 0, 6, 195, 60, 209, 82, 65, 0, 9, 198, 12, 20, 5, 48, 195, 192, 21, 13, 202, 57, 80, 204, 20, 244, 201, 57, 65, 83, 36, 68, 0, 7, 194, 36, 224, 72, 28, 9, 18, 66, 36, 224, 37, 50, 15, 49, 122, 4, 37, 0, 8, 81, 99, 117, 105, 32, 5, 194, 60, 32, 20, 12, 201, 20, 225, 15, 76, 50, 5, 48, 85, 18, 67, 0, 9, 67, 92, 80, 128, 58, 109, 71, 0, 15, 204, 88, 83, 148, 37, 21, 65, 81, 68, 133, 76, 147, 64, 20, 12, 201, 76, 245, 20, 60, 147, 147, 36, 83, 69, 20, 6, 195, 72, 240, 128, 20, 6, 195, 8, 240, 128, 20, 0, 7, 196, 77, 83, 12, 4, 72, 6, 195, 77, 67, 205, 20, 12, 201, 76, 84, 211, 4, 229, 5, 76, 147, 64, 20, 0, 8, 197, 21, 48, 71, 60, 224, 66, 8, 197, 8, 83, 9, 4, 192, 67, 8, 197, 4, 113, 82, 60, 192, 66, 0, 9, 198, 76, 50, 76, 36, 20, 128, 67, 9, 198, 21, 32, 137, 88, 244, 128, 66, 10, 198, 20, 48, 197, 80, 84, 128, 66, 20, 9, 198, 12, 243, 15, 56, 144, 64, 67, 0, 6, 195, 77, 80, 64, 72, 15, 4, 95, 15, 7, 15, 39, 81, 6, 39, 12, 50, 36, 49, 0, 6, 195, 76, 80, 128, 20, 6, 195, 12, 80, 128, 20, 10, 199, 12, 20, 212, 20, 195, 1, 72, 67, 10, 199, 5, 32, 201, 64, 83, 1, 28, 67, 0, 7, 196, 85, 48, 133, 12, 20, 7, 196, 84, 226, 84, 4, 67, 6, 195, 76, 83, 137, 20, 11, 200, 64, 243, 9, 77, 66, 82, 60, 192, 68, 7, 196, 60, 131, 73, 12, 20, 0, 6, 195, 81, 35, 214, 20, 8, 197, 81, 33, 77, 36, 192, 66, 8, 197, 80, 84, 146, 20, 224, 21, 8, 197, 80, 20, 144, 4, 224, 66, 8, 197, 72, 17, 204, 4, 224, 66, 8, 197, 64, 192, 84, 36, 224, 65, 6, 195, 61, 35, 0, 21, 8, 197, 12, 20, 212, 36, 224, 65, 0, 6, 195, 65, 35, 211, 20, 9, 198, 56, 144, 207, 80, 84, 128, 66, 9, 198, 41, 80, 90, 20, 148, 128, 65, 0, 6, 195, 81, 35, 212, 20, 0, 11, 200, 80, 244, 131, 32, 144, 82, 60, 192, 67, 7, 196, 53, 84, 197, 36, 66, 11, 200, 36, 228, 197, 81, 66, 67, 36, 64, 68, 8, 196, 24, 84, 143, 16, 66, 20, 0, 14, 73, 4, 48, 197, 48, 84, 129, 80, 244, 128, 21, 0, 10, 6, 195, 65, 35, 214, 20, 6, 195, 65, 35, 214, 20, 8, 197, 52, 20, 195, 5, 32, 65, 8, 197, 20, 194, 83, 37, 32, 67, 8, 197, 16, 147, 69, 81, 32, 65, 8, 197, 5, 162, 77, 85, 64, 65, 0, 9, 198, 13, 35, 206, 61, 67, 208, 66, 12, 201, 12, 20, 212, 20, 197, 133, 80, 84, 133, 20, 0, 6, 195, 77, 81, 64, 72, 6, 195, 77, 67, 208, 20, 6, 195, 65, 35, 212, 20, 10, 199, 52, 19, 5, 8, 243, 7, 20, 20, 10, 199, 5, 144, 84, 60, 195, 1, 32, 68, 11, 199, 4, 48, 193, 16, 83, 73, 4, 67, 20, 0, 11, 200, 77, 1, 83, 76, 147, 69, 81, 32, 66, 7, 196, 61, 97, 83, 80, 20, 9, 198, 16, 243, 9, 4, 227, 214, 20, 8, 196, 12, 241, 201, 4, 65, 20, 9, 198, 5, 85, 15, 52, 86, 154, 20, 0, 8, 195, 56, 83, 0, 72, 28, 9, 9, 197, 80, 244, 148, 61, 32, 65, 21, 8, 197, 72, 145, 197, 81, 64, 20, 6, 195, 56, 83, 0, 21, 8, 197, 16, 145, 133, 81, 64, 20, 8, 197, 12, 20, 211, 5, 32, 65, 8, 197, 5, 32, 137, 81, 32, 65, 0, 7, 194, 56, 80, 72, 28, 9, 9, 66, 48, 144, 55, 37, 0, 76, 9, 6, 194, 36, 240, 76, 9, 0, 6, 195, 76, 85, 76, 66, 10, 199, 52, 243, 143, 80, 243, 137, 4, 68, 14, 203, 36, 51, 211, 36, 67, 196, 20, 48, 69, 17, 32, 20, 0, 7, 196, 77, 83, 12, 20, 72, 15, 68, 104, 18, 82, 4, 72, 88, 35, 6, 37, 12, 51, 35, 0, 9, 198, 88, 147, 129, 88, 147, 0, 67, 7, 196, 65, 33, 86, 36, 20, 7, 196, 65, 33, 83, 76, 20, 7, 196, 56, 83, 73, 12, 66, 8, 196, 44, 20, 15, 44, 66, 20, 6, 195, 28, 83, 137, 20, 11, 200, 20, 224, 78, 80, 147, 205, 21, 32, 68, 11, 200, 12, 130, 69, 76, 19, 149, 61, 96, 20, 0, 9, 198, 24, 16, 197, 88, 19, 143, 76, 8, 197, 25, 84, 143, 56, 240, 72, 8, 197, 81, 32, 66, 20, 16, 65, 8, 197, 72, 240, 195, 36, 16, 20, 8, 197, 64, 84, 131, 32, 80, 66, 8, 197, 24, 80, 195, 36, 16, 20, 8, 197, 12, 244, 195, 36, 16, 20, 8, 197, 12, 240, 195, 36, 16, 20, 8, 197, 8, 240, 195, 36, 16, 20, 8, 197, 5, 32, 193, 16, 80, 65, 8, 197, 4, 194, 83, 20, 144, 67, 0, 17, 206, 72, 243, 66, 36, 51, 211, 36, 67, 196, 20, 48, 69, 17, 32, 20, 9, 198, 36, 228, 207, 48, 149, 0, 66, 10, 198, 12, 19, 21, 52, 85, 0, 67, 21, 0, 6, 195, 77, 82, 64, 72, 10, 199, 104, 145, 207, 81, 65, 82, 36, 20, 10, 199, 80, 144, 133, 72, 144, 68, 20, 67, 10, 199, 76, 21, 143, 72, 115, 129, 56, 67, 10, 199, 36, 225, 129, 57, 66, 76, 20, 67, 10, 199, 5, 32, 201, 65, 33, 84, 20, 20, 0, 9, 198, 64, 84, 140, 60, 209, 78, 21, 7, 196, 48, 84, 143, 76, 21, 11, 200, 21, 35, 69, 56, 85, 84, 36, 48, 67, 9, 198, 8, 84, 148, 36, 243, 0, 66, 9, 198, 4, 84, 143, 76, 243, 0, 67, 0, 8, 197, 104, 19, 143, 8, 144, 20, 8, 197, 88, 83, 148, 72, 80, 20, 8, 197, 76, 147, 143, 64, 80, 20, 8, 197, 72, 84, 213, 52, 80, 67, 6, 195, 65, 35, 194, 20, 8, 197, 64, 84, 147, 36, 16, 65, 8, 197, 61, 53, 9, 48, 80, 66, 9, 197, 48, 83, 85, 72, 80, 65, 20, 9, 197, 36, 67, 206, 20, 240, 66, 20, 6, 195, 29, 81, 82, 21, 9, 197, 20, 225, 129, 76, 144, 65, 20, 9, 198, 13, 33, 84, 4, 49, 79, 66, 9, 197, 12, 20, 201, 56, 240, 67, 20, 8, 197, 12, 20, 137, 80, 80, 67, 8, 197, 8, 145, 78, 56, 144, 20, 0, 9, 198, 65, 33, 83, 80, 149, 0, 65, 14, 202, 32, 84, 129, 12, 193, 79, 64, 243, 9, 76, 67, 21, 6, 195, 17, 35, 199, 20, 9, 198, 4, 211, 210, 61, 50, 64, 21, 0, 9, 198, 64, 243, 9, 13, 35, 205, 66, 14, 203, 20, 193, 84, 81, 35, 205, 4, 115, 133, 80, 80, 20, 6, 195, 8, 243, 128, 20, 10, 199, 5, 3, 204, 48, 147, 133, 60, 67, 0, 15, 4, 95, 48, 77, 52, 71, 37, 55, 37, 6, 39, 50, 37, 0, 11, 200, 61, 37, 15, 16, 244, 211, 36, 16, 68, 6, 195, 56, 243, 133, 20, 11, 200, 25, 32, 78, 12, 130, 71, 36, 16, 66, 7, 196, 12, 149, 137, 80, 65, 6, 195, 12, 83, 133, 21, 11, 200, 9, 83, 206, 5, 36, 143, 80, 144, 20, 0, 0, 15, 4, 95, 48, 77, 50, 65, 37, 55, 37, 6, 39, 50, 37, 0, 6, 195, 56, 245, 83, 66, 9, 198, 48, 20, 9, 16, 83, 192, 66, 7, 195, 21, 3, 195, 65, 20, 9, 198, 20, 193, 84, 81, 35, 196, 20, 0, 16, 4, 95, 48, 77, 51, 65, 37, 55, 37, 6, 35, 51, 72, 37, 0, 6, 195, 76, 83, 128, 21, 11, 199, 64, 20, 133, 57, 65, 83, 36, 66, 20, 9, 198, 64, 19, 5, 52, 243, 133, 20, 6, 195, 56, 243, 128, 20, 6, 195, 24, 243, 128, 20, 9, 198, 24, 147, 5, 52, 243, 133, 20, 9, 198, 12, 194, 83, 80, 83, 133, 65, 6, 195, 12, 83, 128, 21, 6, 195, 8, 243, 132, 20, 0, 7, 196, 8, 240, 195, 4, 21, 7, 196, 12, 20, 21, 80, 66, 0, 12, 4, 95, 48, 77, 49, 65, 6, 37, 55, 35, 0, 7, 195, 21, 3, 206, 65, 20, 6, 195, 12, 83, 142, 21, 0, 15, 4, 95, 2, 18, 22, 71, 14, 16, 6, 36, 12, 84, 36, 0, 9, 198, 61, 69, 1, 28, 243, 128, 66, 5, 194, 60, 64, 20, 9, 198, 52, 19, 1, 64, 83, 128, 21, 0, 9, 198, 76, 147, 132, 72, 243, 69, 65, 11, 199, 16, 148, 195, 72, 81, 9, 80, 66, 21, 9, 198, 12, 19, 12, 37, 35, 197, 66, 0, 7, 196, 12, 244, 137, 104, 65, 0, 8, 197, 64, 83, 132, 60, 192, 20, 8, 197, 52, 81, 15, 48, 192, 21, 8, 197, 32, 145, 82, 60, 224, 66, 0, 9, 198, 105, 80, 195, 32, 84, 128, 65, 9, 198, 72, 84, 208, 60, 228, 192, 20, 9, 198, 36, 68, 143, 88, 244, 128, 66, 6, 195, 12, 84, 131, 21, 6, 195, 12, 84, 131, 21, 6, 195, 8, 244, 135, 21, 0, 6, 195, 24, 244, 128, 21, 9, 198, 13, 34, 83, 4, 244, 133, 66, 6, 195, 12, 84, 128, 21, 6, 195, 12, 84, 128, 21, 0, 6, 195, 76, 84, 129, 21, 7, 196, 77, 65, 80, 64, 21, 6, 195, 72, 244, 133, 20, 7, 196, 64, 16, 197, 12, 20, 6, 195, 52, 20, 129, 66, 7, 196, 24, 241, 204, 36, 20, 9, 198, 24, 147, 15, 77, 49, 78, 66, 7, 196, 16, 241, 204, 36, 20, 6, 195, 8, 244, 133, 20, 0, 8, 197, 88, 83, 148, 60, 192, 20, 12, 201, 69, 80, 68, 72, 147, 1, 80, 84, 128, 67, 8, 197, 16, 243, 13, 4, 224, 20, 8, 197, 12, 22, 154, 60, 192, 66, 0, 5, 194, 61, 64, 20, 9, 198, 52, 243, 143, 52, 84, 128, 66, 9, 198, 48, 83, 208, 60, 193, 0, 20, 0, 6, 195, 8, 245, 128, 20, 6, 195, 8, 245, 128, 20, 0, 7, 196, 76, 147, 73, 4, 65, 8, 196, 72, 240, 143, 80, 66, 20, 6, 195, 56, 245, 133, 20, 0, 8, 197, 76, 245, 137, 21, 64, 66, 12, 201, 53, 83, 20, 37, 3, 5, 96, 84, 128, 20, 12, 201, 20, 210, 67, 72, 148, 20, 60, 98, 84, 68, 0, 13, 202, 88, 19, 4, 60, 32, 137, 4, 65, 78, 20, 67, 9, 198, 76, 19, 134, 72, 243, 148, 66, 6, 195, 21, 3, 211, 20, 0, 10, 199, 88, 19, 12, 20, 195, 206, 28, 20, 6, 195, 56, 245, 128, 20, 9, 198, 52, 147, 12, 21, 50, 77, 20, 10, 199, 37, 3, 212, 21, 35, 73, 4, 68, 10, 199, 28, 83, 212, 21, 35, 73, 4, 68, 9, 198, 21, 2, 71, 72, 17, 133, 66, 0, 7, 196, 16, 148, 15, 48, 66, 6, 195, 8, 245, 133, 20, 0, 9, 197, 80, 83, 133, 9, 32, 65, 20, 9, 197, 48, 85, 129, 57, 160, 65, 20, 8, 197, 36, 225, 133, 81, 64, 20, 8, 197, 20, 97, 133, 81, 64, 20, 8, 197, 16, 84, 213, 21, 64, 20, 8, 197, 8, 84, 207, 105, 160, 21, 0, 6, 194, 52, 144, 76, 9, 9, 198, 65, 35, 201, 21, 69, 0, 20, 9, 198, 65, 35, 196, 61, 69, 0, 21, 6, 195, 21, 21, 79, 20, 9, 198, 12, 81, 129, 48, 241, 128, 66, 6, 195, 8, 244, 147, 21, 0, 10, 199, 77, 2, 78, 5, 166, 143, 48, 67, 10, 199, 64, 148, 143, 52, 19, 137, 4, 68, 10, 199, 28, 244, 135, 60, 230, 143, 48, 67, 6, 195, 28, 86, 128, 21, 9, 198, 12, 130, 65, 88, 20, 137, 65, 10, 199, 12, 20, 148, 5, 1, 83, 80, 21, 9, 198, 4, 224, 71, 72, 17, 133, 66, 0, 7, 131, 14, 195, 169, 8, 9, 7, 196, 36, 209, 78, 36, 20, 9, 198, 28, 192, 68, 36, 243, 0, 66, 0, 8, 197, 88, 84, 195, 36, 48, 66, 8, 197, 77, 3, 5, 56, 144, 20, 8, 197, 64, 84, 195, 32, 80, 20, 6, 195, 24, 244, 146, 21, 8, 197, 21, 35, 69, 80, 80, 20, 8, 197, 8, 148, 5, 16, 80, 65, 0, 9, 198, 81, 32, 86, 21, 50, 64, 20, 9, 198, 21, 129, 82, 21, 50, 64, 66, 0, 20, 71, 60, 194, 77, 64, 144, 68, 20, 39, 55, 37, 65, 48, 6, 37, 35, 72, 36, 0, 14, 203, 64, 149, 67, 12, 129, 80, 21, 33, 133, 81, 64, 20, 9, 198, 52, 144, 210, 61, 67, 205, 66, 10, 199, 5, 32, 207, 12, 244, 197, 56, 21, 0, 7, 196, 84, 35, 204, 16, 20, 9, 198, 72, 81, 199, 37, 49, 78, 21, 7, 196, 65, 33, 84, 80, 20, 11, 200, 52, 243, 148, 20, 193, 80, 72, 80, 20, 8, 196, 52, 17, 207, 28, 66, 20, 6, 195, 21, 21, 73, 20, 9, 198, 9, 85, 1, 56, 243, 0, 67, 0, 8, 197, 81, 34, 65, 16, 80, 65, 8, 197, 80, 21, 1, 72, 144, 65, 8, 197, 76, 147, 132, 36, 16, 66, 8, 197, 36, 228, 207, 52, 208, 21, 8, 197, 36, 225, 133, 72, 144, 65, 6, 195, 24, 244, 142, 21, 8, 197, 17, 34, 65, 16, 80, 65, 8, 197, 4, 210, 68, 20, 144, 67, 0, 9, 198, 80, 83, 195, 72, 149, 0, 66, 6, 195, 52, 20, 143, 20, 6, 195, 52, 20, 143, 66, 9, 198, 16, 147, 195, 21, 50, 64, 66, 9, 198, 12, 19, 69, 72, 245, 0, 20, 0, 6, 195, 104, 243, 128, 20, 10, 199, 80, 19, 12, 60, 98, 84, 20, 66, 10, 199, 12, 243, 80, 61, 50, 84, 20, 66, 0, 7, 196, 76, 19, 79, 4, 20, 7, 196, 73, 80, 133, 48, 66, 11, 200, 64, 245, 1, 52, 241, 193, 48, 80, 67, 9, 198, 37, 3, 195, 20, 229, 18, 20, 11, 200, 36, 209, 78, 61, 69, 5, 72, 144, 20, 11, 200, 21, 65, 82, 61, 69, 5, 72, 144, 20, 9, 198, 16, 148, 208, 72, 86, 154, 20, 11, 200, 8, 147, 211, 36, 229, 5, 76, 144, 67, 11, 200, 5, 34, 83, 80, 245, 5, 48, 80, 67, 0, 12, 201, 72, 244, 208, 36, 115, 9, 61, 50, 64, 21, 6, 195, 8, 244, 142, 21, 12, 201, 5, 32, 201, 16, 147, 195, 21, 50, 64, 68, 0, 12, 201, 12, 243, 148, 72, 245, 133, 73, 50, 65, 67, 0, 10, 199, 52, 20, 129, 80, 243, 133, 80, 20, 9, 198, 48, 83, 211, 80, 83, 133, 66, 9, 198, 16, 147, 143, 52, 83, 133, 66, 9, 198, 8, 243, 7, 32, 84, 137, 65, 0, 6, 195, 104, 243, 133, 21, 7, 195, 24, 244, 137, 20, 9, 7, 196, 76, 240, 195, 36, 20, 6, 195, 24, 244, 137, 66, 0, 12, 201, 16, 83, 65, 72, 85, 5, 36, 243, 128, 21, 0, 10, 198, 88, 145, 197, 88, 19, 128, 66, 20, 9, 198, 24, 83, 143, 52, 83, 128, 66, 9, 198, 21, 69, 1, 28, 243, 128, 66, 10, 198, 21, 4, 201, 48, 243, 128, 65, 20, 9, 198, 8, 20, 137, 80, 243, 128, 66, 0, 6, 195, 28, 80, 192, 20, 0, 7, 196, 81, 80, 133, 72, 65, 7, 196, 52, 242, 82, 20, 67, 13, 68, 12, 144, 78, 20, 76, 6, 37, 35, 50, 36, 0, 0, 8, 197, 81, 32, 70, 36, 192, 66, 8, 197, 13, 33, 83, 60, 192, 66, 8, 197, 12, 243, 132, 60, 224, 21, 0, 6, 195, 76, 80, 195, 21, 9, 198, 64, 193, 85, 72, 144, 192, 65, 6, 195, 12, 80, 195, 21, 0, 10, 199, 80, 83, 5, 48, 21, 143, 72, 21, 10, 199, 36, 229, 5, 73, 50, 78, 16, 67, 0, 6, 195, 12, 80, 193, 20, 7, 196, 88, 81, 204, 36, 20, 7, 196, 76, 241, 204, 36, 20, 11, 200, 60, 197, 18, 20, 240, 197, 4, 224, 68, 7, 196, 53, 81, 148, 36, 66, 7, 196, 48, 147, 73, 56, 65, 0, 12, 201, 76, 83, 142, 4, 50, 5, 72, 144, 128, 68, 7, 195, 20, 32, 78, 65, 20, 12, 201, 12, 243, 80, 72, 21, 133, 56, 66, 84, 67, 0, 6, 195, 60, 225, 71, 20, 9, 198, 36, 65, 78, 80, 144, 192, 20, 9, 198, 21, 64, 77, 64, 84, 192, 65, 9, 198, 4, 229, 9, 48, 240, 192, 66, 9, 198, 4, 225, 18, 20, 148, 192, 66, 0, 9, 198, 76, 19, 80, 21, 148, 133, 66, 6, 195, 72, 241, 192, 20, 0, 7, 196, 77, 83, 12, 60, 72, 0, 8, 197, 104, 83, 154, 21, 32, 65, 9, 198, 88, 147, 12, 5, 35, 211, 20, 8, 197, 9, 84, 130, 21, 32, 65, 8, 197, 8, 84, 130, 21, 32, 65, 0, 10, 198, 24, 145, 83, 60, 193, 64, 65, 20, 9, 198, 24, 145, 78, 36, 193, 64, 66, 0, 14, 5, 19, 1, 18, 195, 178, 89, 108, 34, 6, 110, 0, 72, 10, 199, 21, 5, 1, 72, 50, 9, 4, 67, 0, 7, 196, 76, 83, 79, 48, 65, 6, 195, 72, 129, 65, 21, 7, 196, 48, 81, 199, 20, 21, 0, 8, 197, 76, 48, 80, 37, 64, 65, 6, 195, 64, 83, 0, 21, 6, 195, 64, 83, 0, 21, 9, 197, 52, 245, 13, 61, 64, 66, 20, 12, 201, 21, 2, 71, 48, 245, 20, 36, 65, 64, 20, 8, 197, 12, 19, 1, 9, 32, 65, 8, 197, 4, 112, 80, 37, 64, 66, 0, 9, 198, 5, 100, 133, 8, 33, 64, 72, 9, 198, 88, 84, 135, 36, 225, 64, 21, 9, 198, 76, 245, 20, 36, 193, 64, 66, 9, 198, 24, 149, 15, 24, 17, 192, 66, 9, 198, 16, 19, 79, 12, 193, 64, 65, 9, 198, 12, 84, 131, 36, 225, 64, 21, 9, 198, 12, 20, 205, 20, 225, 64, 65, 9, 198, 4, 227, 198, 20, 193, 64, 66, 0, 6, 195, 64, 81, 0, 20, 9, 198, 16, 144, 71, 56, 244, 201, 66, 0, 11, 200, 88, 84, 212, 20, 224, 78, 61, 96, 20, 7, 196, 76, 145, 193, 72, 65, 7, 196, 64, 145, 68, 20, 20, 11, 200, 12, 148, 131, 60, 49, 78, 81, 32, 20, 6, 195, 4, 34, 65, 66, 0, 8, 197, 5, 97, 83, 76, 80, 72, 9, 197, 88, 83, 133, 80, 144, 65, 20, 8, 197, 76, 241, 204, 36, 16, 20, 8, 197, 76, 19, 5, 52, 144, 20, 8, 197, 72, 144, 197, 72, 48, 21, 8, 197, 64, 244, 212, 84, 208, 65, 8, 197, 36, 208, 143, 12, 48, 21, 8, 197, 36, 68, 143, 64, 80, 65, 8, 197, 28, 83, 133, 88, 80, 20, 8, 197, 28, 19, 69, 80, 80, 20, 8, 197, 25, 81, 193, 12, 80, 66, 8, 197, 21, 34, 84, 20, 208, 20, 8, 197, 4, 193, 83, 76, 144, 20, 8, 197, 4, 115, 129, 80, 144, 65, 0, 9, 198, 88, 83, 133, 72, 66, 64, 67, 9, 198, 85, 52, 197, 28, 194, 64, 20, 9, 198, 80, 85, 84, 60, 226, 64, 65, 9, 198, 77, 3, 5, 56, 66, 68, 20, 9, 198, 28, 149, 71, 28, 147, 204, 65, 9, 198, 21, 2, 83, 60, 66, 64, 20, 9, 198, 5, 4, 15, 76, 149, 0, 66, 0, 9, 198, 104, 243, 198, 36, 194, 65, 68, 10, 199, 72, 144, 195, 60, 35, 206, 36, 20, 10, 199, 12, 83, 148, 85, 34, 80, 20, 66, 0, 8, 196, 64, 83, 206, 36, 65, 9, 11, 200, 80, 20, 132, 36, 116, 129, 16, 144, 66, 8, 196, 76, 83, 73, 56, 65, 21, 7, 196, 64, 19, 73, 72, 66, 6, 195, 56, 245, 137, 20, 7, 196, 56, 243, 73, 56, 65, 7, 196, 52, 16, 193, 12, 66, 11, 200, 8, 20, 137, 80, 243, 133, 76, 144, 20, 0, 8, 197, 76, 83, 80, 72, 80, 20, 6, 195, 72, 246, 154, 21, 8, 197, 65, 33, 77, 36, 16, 65, 9, 197, 48, 83, 85, 72, 144, 65, 20, 8, 197, 32, 243, 143, 72, 80, 67, 8, 197, 25, 84, 148, 20, 144, 66, 8, 197, 24, 83, 142, 20, 48, 20, 8, 197, 8, 20, 212, 36, 16, 65, 8, 197, 4, 194, 78, 20, 16, 66, 0, 9, 198, 64, 149, 5, 28, 194, 64, 20, 12, 201, 52, 144, 210, 60, 49, 70, 4, 194, 65, 69, 0, 6, 195, 52, 147, 192, 72, 9, 198, 76, 147, 148, 60, 226, 65, 67, 9, 198, 76, 19, 13, 60, 66, 65, 67, 10, 199, 20, 195, 5, 56, 144, 200, 20, 20, 0, 9, 198, 81, 33, 86, 37, 48, 78, 67, 12, 200, 16, 147, 143, 12, 81, 129, 48, 144, 67, 20, 0, 0, 22, 4, 95, 3, 9, 18, 76, 37, 38, 14, 16, 49, 39, 50, 83, 55, 6, 36, 89, 89, 39, 0, 0, 9, 198, 105, 80, 195, 32, 84, 137, 65, 10, 199, 77, 80, 131, 60, 228, 195, 36, 20, 9, 198, 8, 147, 1, 80, 84, 137, 66, 0, 7, 196, 64, 241, 199, 36, 20, 9, 198, 8, 240, 195, 4, 225, 82, 21, 0, 8, 133, 19, 1, 18, 195, 160, 72, 9, 198, 76, 20, 146, 4, 37, 83, 65, 0, 9, 198, 5, 100, 133, 52, 211, 192, 72, 9, 198, 76, 20, 133, 52, 211, 192, 72, 10, 198, 60, 210, 67, 72, 243, 128, 65, 20, 5, 194, 60, 128, 20, 6, 195, 8, 244, 195, 20, 0, 10, 67, 36, 20, 192, 37, 35, 88, 0, 65, 6, 195, 72, 244, 192, 20, 10, 199, 52, 85, 1, 8, 243, 9, 80, 67, 6, 195, 8, 244, 192, 20, 0, 7, 196, 52, 86, 9, 12, 21, 0, 8, 197, 24, 19, 3, 60, 224, 66, 0, 9, 198, 81, 34, 67, 32, 80, 192, 20, 9, 198, 13, 80, 213, 72, 34, 84, 66, 9, 198, 4, 229, 9, 28, 20, 192, 67, 0, 10, 199, 80, 148, 129, 64, 145, 68, 36, 20, 10, 199, 16, 241, 5, 12, 17, 207, 56, 67, 6, 195, 12, 84, 192, 20, 10, 199, 12, 20, 193, 48, 35, 210, 20, 66, 9, 198, 5, 37, 5, 24, 144, 197, 21, 6, 195, 4, 34, 84, 65, 0, 7, 196, 76, 51, 208, 4, 21, 6, 131, 95, 195, 185, 43, 7, 196, 84, 192, 197, 72, 65, 7, 196, 76, 16, 200, 4, 66, 6, 195, 72, 244, 197, 66, 7, 196, 72, 83, 79, 72, 65, 7, 196, 64, 193, 66, 20, 20, 7, 196, 60, 48, 200, 36, 20, 7, 196, 52, 16, 193, 60, 66, 7, 196, 12, 16, 193, 60, 66, 0, 8, 197, 64, 20, 212, 20, 224, 65, 9, 198, 60, 211, 199, 20, 225, 79, 67, 8, 197, 24, 16, 137, 60, 192, 66, 0, 9, 198, 76, 83, 65, 24, 244, 128, 66, 9, 198, 36, 115, 137, 80, 244, 128, 65, 0, 13, 4, 95, 19, 20, 11, 71, 6, 35, 51, 16, 35, 0, 12, 201, 9, 35, 195, 12, 244, 212, 20, 195, 0, 21, 0, 7, 196, 76, 80, 207, 48, 20, 7, 196, 64, 240, 207, 48, 66, 0, 14, 4, 95, 1, 3, 21, 35, 49, 6, 40, 12, 47, 39, 0, 6, 131, 95, 195, 178, 43, 8, 197, 64, 84, 132, 37, 64, 65, 6, 195, 28, 83, 214, 65, 0, 6, 131, 95, 195, 179, 43, 9, 198, 100, 19, 213, 56, 65, 64, 68, 9, 198, 21, 65, 79, 12, 193, 64, 66, 9, 198, 8, 21, 9, 12, 193, 64, 65, 0, 10, 199, 64, 81, 9, 5, 68, 137, 4, 67, 0, 9, 198, 81, 84, 130, 60, 96, 78, 67, 7, 196, 72, 83, 79, 80, 20, 6, 195, 12, 84, 201, 20, 7, 196, 5, 33, 5, 4, 65, 7, 196, 4, 225, 207, 48, 66, 0, 8, 197, 77, 64, 83, 21, 32, 21, 12, 201, 76, 83, 80, 72, 85, 133, 72, 65, 64, 21, 6, 195, 48, 243, 0, 20, 0, 6, 194, 48, 240, 72, 9, 9, 198, 77, 81, 134, 21, 69, 0, 20, 9, 198, 76, 147, 132, 60, 225, 64, 65, 9, 198, 12, 194, 77, 20, 225, 64, 65, 0, 6, 131, 95, 195, 172, 43, 10, 199, 80, 83, 195, 72, 22, 137, 4, 68, 6, 195, 48, 241, 0, 20, 9, 198, 25, 37, 84, 80, 244, 201, 20, 10, 198, 12, 147, 133, 8, 246, 0, 67, 20, 6, 195, 12, 84, 212, 21, 10, 199, 5, 84, 212, 72, 20, 201, 4, 67, 10, 199, 5, 37, 5, 52, 148, 201, 4, 67, 0, 12, 201, 88, 147, 12, 5, 52, 5, 12, 147, 211, 21, 7, 196, 52, 16, 197, 72, 65, 7, 196, 8, 16, 197, 56, 21, 0, 8, 197, 69, 81, 83, 80, 16, 72, 8, 197, 88, 149, 129, 12, 80, 66, 8, 197, 65, 35, 197, 52, 144, 20, 8, 197, 56, 80, 195, 32, 144, 20, 8, 197, 52, 83, 133, 12, 208, 20, 8, 197, 24, 148, 195, 32, 144, 66, 8, 197, 21, 52, 197, 72, 80, 20, 8, 197, 16, 144, 68, 20, 208, 20, 8, 197, 12, 240, 195, 32, 144, 20, 9, 197, 8, 241, 77, 36, 16, 66, 20, 8, 197, 5, 81, 1, 12, 80, 67, 8, 197, 5, 49, 80, 76, 144, 20, 8, 197, 4, 212, 5, 72, 80, 66, 8, 197, 4, 195, 21, 12, 80, 65, 0, 10, 198, 76, 84, 85, 4, 226, 64, 65, 20, 9, 198, 72, 83, 211, 80, 21, 0, 66, 9, 198, 64, 84, 20, 36, 66, 64, 20, 9, 198, 36, 225, 207, 8, 34, 64, 20, 0, 14, 4, 95, 18, 14, 7, 35, 50, 6, 36, 55, 55, 39, 0, 6, 131, 95, 195, 168, 43, 10, 199, 81, 33, 80, 64, 145, 68, 20, 20, 10, 199, 76, 16, 197, 72, 67, 212, 20, 20, 9, 198, 52, 84, 211, 20, 226, 65, 20, 6, 195, 48, 245, 0, 20, 9, 198, 36, 98, 71, 20, 226, 65, 68, 9, 198, 16, 144, 82, 12, 130, 65, 67, 10, 199, 12, 244, 148, 20, 229, 79, 88, 20, 10, 199, 8, 244, 195, 36, 208, 78, 36, 66, 10, 199, 5, 32, 200, 36, 209, 68, 20, 20, 0, 6, 131, 95, 195, 169, 43, 7, 196, 48, 147, 79, 56, 66, 6, 195, 28, 84, 213, 66, 12, 201, 12, 20, 148, 36, 192, 71, 36, 225, 79, 68, 9, 198, 5, 84, 212, 72, 19, 0, 67, 0, 8, 197, 4, 115, 211, 80, 16, 65, 8, 197, 88, 244, 212, 72, 16, 72, 8, 197, 56, 244, 212, 72, 16, 72, 9, 198, 80, 19, 135, 4, 226, 67, 67, 8, 197, 61, 33, 9, 56, 80, 21, 8, 197, 52, 242, 5, 48, 144, 21, 8, 197, 20, 195, 209, 84, 144, 20, 8, 197, 4, 227, 205, 20, 144, 67, 0, 9, 198, 72, 145, 15, 48, 98, 64, 20, 9, 198, 72, 85, 15, 72, 34, 68, 21, 9, 198, 5, 37, 5, 72, 147, 204, 67, 0, 29, 67, 33, 69, 16, 6, 35, 49, 12, 35, 47, 4, 37, 12, 47, 4, 37, 12, 48, 6, 37, 12, 10, 0, 81, 58, 47, 47, 32, 9, 198, 72, 20, 19, 60, 66, 65, 67, 9, 198, 24, 149, 15, 24, 17, 201, 66, 10, 199, 12, 20, 142, 37, 99, 210, 36, 66, 0, 7, 196, 72, 241, 201, 80, 65, 7, 196, 24, 16, 197, 80, 20, 7, 196, 16, 145, 67, 36, 20, 11, 200, 12, 83, 148, 61, 2, 69, 16, 144, 20, 6, 195, 8, 244, 201, 20, 7, 196, 4, 192, 193, 52, 65, 12, 200, 4, 112, 77, 20, 227, 143, 56, 80, 67, 20, 0, 0, 0, 6, 131, 95, 195, 160, 43, 9, 198, 76, 19, 21, 16, 80, 201, 20, 9, 198, 52, 85, 1, 80, 84, 201, 66, 0, 12, 68, 48, 81, 199, 36, 55, 36, 75, 6, 37, 0, 10, 198, 104, 84, 16, 20, 194, 78, 65, 20, 7, 196, 76, 81, 199, 36, 20, 7, 196, 72, 16, 197, 52, 20, 7, 196, 52, 241, 199, 36, 20, 0, 9, 197, 52, 82, 206, 21, 48, 66, 20, 6, 195, 5, 32, 66, 65, 0, 9, 198, 64, 148, 137, 80, 243, 192, 66, 9, 198, 56, 20, 195, 61, 53, 0, 21, 0, 10, 199, 64, 148, 201, 77, 68, 129, 80, 66, 10, 199, 24, 147, 15, 77, 68, 129, 80, 66, 9, 198, 9, 34, 78, 16, 148, 201, 65, 0, 6, 195, 20, 32, 133, 72, 7, 196, 104, 17, 193, 72, 65, 7, 196, 80, 83, 80, 36, 20, 6, 195, 76, 241, 9, 20, 9, 198, 64, 20, 129, 29, 32, 70, 66, 6, 195, 60, 115, 9, 20, 7, 196, 24, 145, 193, 72, 65, 6, 195, 4, 32, 129, 66, 0, 8, 197, 77, 2, 78, 60, 192, 65, 0, 9, 198, 8, 20, 130, 21, 32, 64, 66, 9, 198, 77, 3, 210, 60, 98, 84, 66, 12, 201, 64, 84, 132, 5, 49, 5, 24, 241, 213, 20, 9, 198, 48, 144, 133, 73, 64, 64, 67, 9, 198, 12, 148, 18, 21, 52, 192, 20, 0, 7, 195, 21, 32, 64, 72, 9, 9, 198, 88, 84, 148, 20, 36, 133, 65, 6, 195, 64, 83, 12, 21, 0, 6, 195, 77, 83, 201, 72, 9, 198, 64, 243, 9, 77, 65, 78, 66, 7, 196, 61, 33, 129, 56, 65, 7, 196, 60, 49, 65, 56, 66, 7, 196, 52, 240, 200, 36, 20, 7, 196, 28, 129, 68, 36, 20, 11, 200, 21, 33, 207, 77, 65, 82, 60, 192, 68, 8, 196, 8, 145, 206, 20, 66, 20, 7, 196, 4, 225, 207, 72, 65, 7, 196, 4, 192, 207, 88, 20, 0, 8, 197, 76, 48, 84, 60, 192, 65, 12, 201, 65, 35, 212, 60, 49, 82, 20, 36, 128, 67, 0, 9, 198, 88, 84, 148, 20, 36, 128, 65, 0, 10, 199, 52, 245, 15, 13, 35, 211, 76, 67, 0, 7, 196, 64, 145, 67, 20, 20, 7, 196, 61, 33, 133, 36, 66, 6, 195, 5, 33, 65, 65, 0, 12, 201, 52, 19, 5, 88, 243, 5, 57, 160, 64, 8, 8, 197, 88, 84, 195, 61, 96, 65, 6, 195, 21, 33, 66, 65, 9, 197, 8, 244, 198, 61, 32, 65, 20, 0, 23, 4, 95, 1, 3, 50, 72, 6, 39, 48, 12, 37, 38, 39, 23, 35, 49, 6, 40, 12, 47, 39, 0, 9, 198, 76, 83, 137, 61, 33, 64, 20, 9, 198, 52, 20, 141, 61, 33, 64, 65, 9, 198, 16, 243, 3, 21, 69, 0, 21, 9, 198, 16, 144, 66, 21, 65, 64, 20, 0, 10, 199, 61, 37, 15, 64, 81, 9, 4, 68, 0, 6, 195, 20, 32, 137, 72, 7, 196, 64, 145, 68, 72, 20, 11, 200, 5, 32, 201, 88, 84, 195, 61, 96, 67, 0, 6, 195, 52, 243, 0, 20, 6, 195, 52, 243, 0, 20, 8, 197, 52, 20, 141, 5, 32, 65, 8, 197, 13, 34, 67, 21, 64, 20, 0, 9, 198, 5, 100, 133, 77, 65, 64, 72, 9, 198, 17, 84, 129, 57, 65, 64, 8, 9, 198, 81, 32, 68, 61, 69, 0, 21, 6, 195, 72, 244, 211, 21, 6, 195, 72, 244, 211, 21, 0, 9, 198, 77, 66, 71, 52, 21, 5, 65, 6, 195, 72, 244, 208, 20, 6, 195, 52, 241, 0, 20, 6, 195, 52, 241, 0, 20, 10, 199, 37, 51, 208, 76, 81, 137, 4, 68, 9, 198, 20, 228, 195, 32, 81, 5, 67, 9, 198, 12, 243, 85, 56, 149, 1, 68, 0, 7, 196, 76, 144, 77, 60, 72, 8, 196, 76, 244, 18, 4, 76, 28, 7, 196, 80, 83, 80, 20, 20, 9, 198, 76, 243, 1, 72, 243, 0, 67, 9, 198, 64, 243, 9, 28, 19, 0, 66, 7, 196, 52, 241, 193, 56, 65, 6, 195, 21, 33, 77, 65, 0, 8, 197, 4, 195, 15, 72, 16, 21, 8, 197, 5, 97, 83, 76, 144, 72, 8, 197, 81, 32, 66, 36, 16, 66, 8, 197, 76, 83, 73, 16, 144, 67, 9, 197, 76, 19, 15, 52, 80, 67, 20, 8, 197, 65, 35, 206, 4, 240, 20, 6, 195, 20, 32, 146, 20, 8, 197, 12, 20, 129, 12, 240, 67, 6, 195, 5, 33, 78, 21, 9, 198, 4, 193, 197, 9, 34, 67, 20, 0, 9, 198, 76, 147, 5, 57, 162, 64, 20, 6, 195, 76, 84, 211, 20, 9, 198, 52, 243, 143, 64, 244, 212, 21, 9, 198, 36, 228, 85, 36, 85, 0, 20, 9, 198, 8, 84, 130, 21, 34, 64, 65, 0, 7, 195, 21, 34, 64, 72, 9, 10, 199, 56, 242, 67, 5, 69, 1, 72, 67, 6, 195, 52, 245, 0, 20, 6, 195, 52, 245, 0, 20, 6, 195, 12, 243, 12, 21, 6, 195, 12, 243, 12, 21, 10, 199, 12, 20, 193, 80, 83, 143, 88, 20, 9, 198, 12, 20, 135, 20, 114, 5, 20, 10, 199, 12, 20, 1, 56, 227, 210, 36, 66, 9, 198, 4, 225, 137, 64, 243, 9, 66, 0, 7, 196, 76, 147, 85, 56, 66, 7, 196, 72, 85, 143, 12, 65, 9, 198, 52, 85, 1, 56, 243, 0, 67, 7, 196, 8, 86, 154, 36, 20, 7, 196, 4, 192, 207, 72, 66, 0, 8, 197, 64, 84, 211, 36, 208, 20, 9, 198, 52, 20, 141, 61, 33, 79, 66, 8, 197, 12, 130, 69, 76, 80, 20, 8, 197, 5, 160, 82, 36, 16, 67, 8, 197, 5, 96, 82, 36, 16, 67, 8, 197, 5, 37, 5, 52, 144, 20, 8, 197, 4, 224, 84, 20, 208, 20, 0, 9, 198, 5, 100, 133, 77, 66, 64, 72, 9, 198, 77, 1, 84, 81, 34, 64, 20, 14, 202, 56, 16, 149, 12, 241, 15, 56, 244, 207, 72, 68, 20, 9, 198, 52, 243, 132, 61, 98, 64, 67, 0, 12, 201, 76, 19, 80, 36, 84, 132, 5, 33, 78, 21, 9, 198, 65, 35, 199, 20, 226, 69, 20, 9, 198, 13, 35, 195, 21, 98, 65, 67, 9, 198, 12, 244, 132, 60, 115, 9, 20, 0, 7, 196, 76, 144, 78, 60, 72, 11, 200, 52, 19, 9, 56, 53, 79, 72, 80, 20, 11, 200, 48, 84, 212, 72, 145, 207, 56, 144, 66, 12, 201, 24, 245, 15, 20, 193, 84, 81, 34, 67, 20, 7, 196, 24, 81, 193, 80, 65, 7, 196, 21, 81, 5, 52, 20, 6, 195, 12, 243, 1, 66, 13, 68, 12, 144, 78, 60, 76, 6, 37, 35, 50, 39, 0, 7, 196, 9, 81, 129, 48, 65, 0, 0, 0, 6, 195, 77, 83, 192, 72, 9, 198, 81, 34, 83, 12, 83, 5, 65, 6, 195, 76, 243, 4, 20, 9, 198, 52, 20, 211, 20, 230, 137, 20, 10, 198, 37, 51, 211, 12, 83, 5, 66, 20, 9, 198, 24, 80, 130, 72, 147, 5, 66, 10, 199, 20, 51, 211, 37, 53, 5, 52, 20, 9, 198, 5, 4, 18, 60, 48, 201, 20, 0, 7, 196, 76, 17, 193, 52, 65, 7, 196, 64, 81, 199, 36, 20, 7, 196, 61, 32, 137, 80, 65, 7, 196, 4, 225, 197, 48, 65, 7, 196, 4, 225, 197, 48, 65, 0, 0, 0, 10, 199, 65, 34, 86, 36, 193, 71, 36, 20, 9, 198, 64, 147, 143, 12, 50, 9, 20, 10, 199, 8, 17, 206, 61, 33, 71, 36, 20, 0, 7, 196, 88, 84, 18, 20, 20, 8, 196, 60, 96, 78, 80, 65, 20, 7, 196, 24, 147, 206, 16, 21, 7, 196, 20, 227, 206, 20, 20, 6, 195, 12, 245, 9, 20, 6, 195, 8, 19, 9, 66, 7, 196, 4, 112, 86, 20, 65, 0, 8, 197, 56, 83, 77, 20, 224, 21, 8, 197, 52, 21, 18, 60, 224, 20, 8, 197, 20, 117, 77, 20, 224, 66, 10, 198, 5, 33, 197, 57, 65, 79, 66, 20, 0, 9, 198, 64, 241, 5, 77, 64, 64, 67, 0, 10, 199, 76, 83, 5, 84, 50, 68, 36, 66, 9, 198, 52, 81, 193, 64, 241, 9, 20, 10, 199, 20, 194, 67, 61, 69, 5, 72, 20, 9, 198, 12, 243, 150, 60, 115, 9, 20, 0, 7, 196, 16, 81, 204, 36, 72, 7, 196, 16, 17, 204, 36, 72, 7, 196, 76, 21, 143, 12, 65, 7, 195, 72, 20, 5, 66, 20, 6, 195, 56, 21, 9, 66, 6, 195, 28, 245, 9, 20, 6, 195, 13, 83, 201, 20, 0, 8, 197, 88, 22, 154, 60, 192, 66, 8, 197, 61, 34, 71, 4, 224, 66, 8, 197, 24, 20, 147, 4, 192, 65, 8, 197, 12, 20, 211, 4, 192, 65, 0, 9, 198, 81, 34, 78, 37, 64, 64, 67, 9, 198, 24, 19, 13, 20, 229, 0, 20, 9, 198, 12, 243, 135, 20, 226, 84, 66, 9, 198, 12, 21, 20, 20, 68, 128, 65, 0, 9, 198, 24, 147, 9, 77, 65, 73, 67, 0, 6, 195, 24, 21, 5, 76, 6, 195, 88, 21, 5, 66, 7, 196, 76, 209, 71, 52, 20, 6, 195, 64, 84, 9, 20, 7, 196, 48, 19, 73, 4, 65, 0, 9, 198, 88, 145, 5, 61, 65, 67, 20, 8, 197, 52, 16, 193, 9, 32, 65, 9, 198, 28, 148, 19, 61, 65, 67, 20, 8, 197, 20, 193, 84, 81, 32, 20, 8, 197, 20, 193, 84, 81, 32, 20, 0, 9, 198, 52, 20, 148, 37, 33, 64, 65, 9, 198, 49, 81, 213, 9, 33, 64, 65, 9, 198, 12, 83, 5, 9, 33, 64, 65, 0, 10, 199, 76, 81, 206, 5, 3, 211, 80, 21, 9, 198, 65, 32, 83, 76, 81, 5, 20, 9, 198, 48, 144, 207, 52, 81, 5, 20, 10, 199, 20, 229, 21, 76, 144, 83, 52, 68, 10, 199, 16, 148, 212, 72, 241, 137, 4, 67, 9, 198, 12, 19, 148, 4, 36, 137, 65, 9, 198, 12, 19, 1, 52, 149, 1, 68, 0, 7, 196, 80, 83, 80, 72, 20, 12, 201, 72, 240, 195, 4, 115, 15, 72, 147, 211, 21, 6, 195, 72, 21, 5, 66, 9, 198, 20, 225, 15, 13, 34, 78, 66, 7, 196, 16, 145, 68, 72, 20, 6, 195, 12, 245, 5, 20, 7, 196, 12, 243, 79, 16, 65, 7, 196, 8, 145, 201, 4, 65, 7, 196, 4, 194, 67, 20, 66, 0, 8, 197, 77, 81, 200, 21, 32, 65, 8, 197, 72, 148, 18, 61, 96, 20, 8, 197, 72, 145, 15, 81, 64, 21, 12, 201, 64, 144, 90, 104, 21, 15, 73, 33, 64, 21, 6, 195, 56, 243, 0, 20, 8, 197, 37, 51, 194, 5, 32, 66, 8, 197, 12, 243, 12, 21, 32, 20, 0, 7, 66, 56, 240, 50, 110, 0, 9, 198, 5, 97, 86, 5, 65, 64, 72, 9, 198, 21, 32, 86, 5, 65, 64, 72, 5, 194, 76, 80, 8, 9, 198, 61, 69, 15, 9, 33, 64, 21, 5, 194, 60, 208, 20, 0, 9, 198, 65, 34, 78, 12, 148, 9, 65, 9, 198, 72, 19, 143, 12, 50, 9, 20, 9, 198, 65, 34, 78, 12, 148, 9, 66, 10, 199, 64, 243, 148, 20, 98, 67, 20, 21, 6, 195, 56, 241, 0, 20, 9, 198, 28, 195, 212, 80, 145, 5, 20, 10, 199, 16, 241, 5, 12, 17, 68, 72, 20, 10, 199, 12, 243, 147, 20, 194, 67, 20, 21, 9, 198, 12, 19, 69, 24, 149, 5, 66, 10, 199, 5, 4, 5, 56, 66, 67, 20, 67, 0, 7, 196, 72, 144, 201, 56, 65, 8, 196, 64, 80, 207, 72, 65, 20, 7, 196, 52, 242, 197, 56, 20, 8, 196, 20, 48, 84, 20, 65, 20, 7, 196, 12, 144, 197, 72, 65, 7, 196, 5, 33, 1, 72, 65, 7, 196, 4, 48, 82, 36, 65, 0, 9, 197, 88, 144, 193, 72, 144, 65, 9, 8, 197, 5, 97, 83, 80, 80, 72, 8, 197, 5, 97, 83, 80, 80, 72, 8, 197, 69, 81, 83, 80, 80, 72, 14, 2, 194, 163, 89, 47, 36, 34, 55, 6, 37, 50, 35, 0, 8, 197, 104, 145, 207, 80, 80, 20, 8, 197, 88, 240, 130, 36, 16, 20, 8, 197, 84, 226, 86, 60, 48, 66, 8, 197, 80, 19, 73, 28, 144, 66, 12, 201, 65, 33, 77, 36, 192, 213, 61, 33, 64, 20, 8, 197, 64, 84, 135, 4, 208, 65, 9, 197, 64, 80, 193, 72, 144, 65, 20, 8, 197, 37, 69, 9, 72, 144, 65, 8, 197, 5, 48, 193, 72, 144, 65, 0, 9, 198, 80, 147, 132, 5, 34, 64, 65, 9, 198, 80, 20, 148, 5, 34, 64, 65, 9, 198, 65, 33, 83, 21, 2, 64, 20, 9, 198, 36, 195, 5, 12, 149, 0, 66, 13, 202, 36, 51, 211, 37, 65, 84, 72, 17, 68, 72, 20, 10, 198, 17, 33, 78, 28, 245, 0, 66, 20, 9, 198, 16, 148, 208, 5, 34, 64, 65, 9, 198, 5, 52, 197, 57, 162, 64, 20, 0, 10, 198, 88, 84, 218, 65, 33, 77, 66, 21, 10, 199, 76, 83, 5, 84, 50, 68, 20, 66, 6, 195, 56, 245, 0, 20, 6, 195, 56, 245, 0, 20, 9, 198, 52, 243, 146, 61, 98, 65, 20, 9, 198, 37, 51, 212, 61, 2, 65, 68, 9, 198, 24, 84, 146, 61, 98, 65, 67, 6, 195, 12, 244, 20, 20, 9, 198, 12, 244, 5, 64, 241, 9, 20, 0, 16, 7, 3, 12, 9, 3, 8, 195, 169, 49, 55, 37, 12, 91, 36, 0, 7, 196, 80, 83, 80, 48, 20, 9, 198, 76, 50, 65, 8, 243, 0, 65, 11, 200, 72, 244, 1, 48, 240, 197, 72, 144, 67, 11, 200, 53, 83, 20, 36, 85, 14, 36, 48, 20, 11, 200, 37, 1, 82, 76, 243, 142, 36, 16, 68, 7, 196, 28, 83, 73, 56, 65, 0, 8, 197, 5, 97, 77, 52, 240, 72, 6, 195, 77, 83, 0, 72, 8, 197, 88, 244, 212, 72, 80, 72, 8, 197, 56, 244, 212, 72, 80, 72, 9, 198, 76, 243, 12, 21, 66, 67, 21, 8, 197, 37, 35, 206, 36, 16, 67, 8, 197, 4, 65, 15, 52, 80, 20, 0, 6, 194, 77, 80, 72, 9, 9, 198, 77, 68, 143, 57, 162, 64, 20, 12, 201, 64, 145, 84, 72, 20, 5, 73, 162, 65, 68, 12, 201, 52, 84, 137, 80, 240, 210, 5, 162, 65, 69, 12, 201, 37, 1, 82, 52, 85, 18, 61, 2, 65, 69, 9, 198, 25, 84, 142, 5, 34, 64, 65, 9, 198, 8, 148, 212, 85, 34, 64, 65, 12, 201, 5, 34, 83, 80, 240, 210, 5, 162, 65, 69, 0, 9, 198, 65, 35, 198, 21, 162, 65, 67, 9, 198, 64, 244, 134, 37, 34, 65, 67, 9, 198, 52, 241, 5, 77, 66, 65, 66, 6, 195, 48, 85, 20, 20, 9, 198, 20, 229, 1, 49, 2, 65, 67, 9, 198, 12, 20, 208, 21, 34, 65, 66, 9, 198, 4, 195, 5, 29, 34, 65, 67, 0, 7, 196, 80, 16, 201, 80, 65, 7, 196, 72, 80, 201, 80, 65, 9, 198, 36, 51, 211, 4, 81, 18, 20, 7, 196, 28, 227, 205, 20, 20, 0, 15, 204, 76, 240, 201, 4, 193, 5, 52, 240, 210, 5, 162, 65, 70, 9, 198, 12, 20, 15, 49, 83, 199, 20, 0, 9, 198, 36, 225, 9, 72, 85, 20, 20, 9, 198, 16, 148, 208, 61, 53, 0, 21, 9, 198, 9, 32, 67, 12, 85, 20, 21, 0, 13, 2, 194, 169, 49, 6, 39, 48, 37, 34, 117, 47, 0, 9, 198, 85, 65, 78, 76, 147, 5, 67, 9, 198, 52, 19, 143, 12, 50, 9, 20, 0, 0, 6, 195, 72, 16, 66, 66, 0, 12, 201, 72, 243, 80, 37, 48, 193, 80, 243, 5, 67, 9, 198, 60, 193, 79, 16, 245, 20, 21, 9, 198, 12, 19, 1, 76, 85, 20, 20, 0, 0, 7, 196, 64, 244, 16, 36, 21, 6, 195, 21, 32, 133, 66, 0, 8, 197, 100, 18, 23, 20, 128, 66, 8, 197, 12, 20, 131, 4, 224, 65, 0, 7, 2, 195, 168, 109, 0, 72, 9, 198, 76, 50, 79, 88, 144, 64, 66, 9, 198, 12, 84, 131, 32, 144, 64, 21, 9, 198, 4, 195, 5, 48, 144, 64, 67, 9, 198, 4, 193, 83, 76, 144, 64, 67, 0, 9, 198, 16, 80, 193, 64, 243, 9, 66, 0, 8, 196, 8, 17, 204, 36, 66, 9, 8, 196, 88, 84, 147, 60, 76, 28, 6, 195, 80, 83, 73, 20, 7, 196, 76, 21, 9, 72, 65, 7, 196, 64, 21, 9, 56, 65, 7, 196, 56, 147, 194, 20, 65, 8, 196, 24, 83, 73, 56, 65, 21, 7, 196, 12, 130, 78, 20, 66, 7, 196, 12, 130, 69, 76, 20, 12, 68, 8, 17, 204, 36, 71, 35, 61, 6, 37, 0, 0, 8, 197, 77, 2, 71, 60, 192, 65, 8, 197, 72, 20, 19, 60, 64, 66, 8, 197, 72, 20, 19, 60, 64, 20, 12, 201, 65, 50, 67, 32, 144, 84, 72, 144, 64, 67, 8, 197, 56, 245, 77, 20, 224, 66, 8, 197, 8, 19, 194, 4, 32, 67, 0, 9, 198, 80, 84, 129, 64, 144, 64, 67, 9, 198, 77, 3, 199, 48, 144, 64, 20, 9, 198, 76, 147, 79, 56, 144, 64, 67, 9, 198, 76, 19, 147, 13, 34, 84, 65, 9, 198, 76, 19, 65, 72, 144, 64, 67, 9, 198, 52, 243, 143, 16, 144, 64, 67, 9, 198, 21, 52, 12, 36, 50, 84, 66, 9, 198, 20, 208, 143, 48, 144, 64, 67, 9, 198, 5, 68, 143, 24, 144, 64, 67, 0, 8, 67, 4, 49, 64, 21, 0, 10, 10, 199, 76, 85, 20, 20, 208, 146, 20, 20, 9, 198, 36, 208, 146, 60, 115, 9, 20, 0, 14, 4, 95, 3, 5, 4, 76, 36, 72, 6, 37, 61, 35, 0, 9, 198, 88, 147, 12, 5, 51, 210, 67, 6, 195, 80, 83, 85, 66, 8, 196, 12, 130, 79, 16, 66, 20, 15, 204, 4, 229, 9, 65, 50, 67, 32, 144, 84, 72, 144, 64, 69, 0, 13, 201, 88, 19, 12, 20, 52, 143, 76, 144, 64, 67, 20, 8, 197, 80, 20, 129, 57, 64, 65, 8, 197, 77, 1, 84, 81, 32, 20, 12, 201, 56, 80, 210, 60, 208, 78, 104, 144, 64, 68, 12, 201, 36, 68, 143, 80, 84, 129, 64, 144, 64, 69, 12, 201, 24, 149, 15, 80, 84, 129, 64, 144, 64, 69, 12, 201, 16, 148, 208, 5, 33, 85, 56, 144, 64, 69, 12, 201, 12, 193, 80, 80, 243, 65, 56, 144, 64, 68, 8, 197, 12, 19, 148, 21, 32, 65, 8, 197, 12, 17, 134, 5, 32, 65, 12, 201, 5, 37, 5, 80, 84, 129, 64, 144, 64, 69, 0, 9, 198, 72, 148, 208, 21, 69, 0, 20, 9, 198, 16, 83, 148, 36, 49, 64, 20, 9, 198, 12, 243, 12, 21, 69, 0, 20, 0, 18, 4, 95, 12, 9, 7, 55, 4, 36, 81, 35, 47, 6, 40, 12, 51, 35, 0, 6, 195, 80, 83, 80, 20, 9, 198, 48, 21, 82, 20, 230, 137, 20, 10, 199, 36, 67, 204, 5, 68, 137, 4, 68, 9, 198, 28, 147, 143, 12, 50, 9, 20, 10, 199, 4, 227, 210, 21, 52, 201, 4, 68, 10, 199, 4, 208, 140, 36, 244, 9, 4, 68, 0, 7, 196, 76, 51, 210, 76, 21, 9, 198, 12, 84, 131, 60, 49, 66, 20, 8, 196, 12, 17, 206, 60, 66, 20, 0, 6, 195, 80, 83, 0, 21, 8, 197, 56, 81, 210, 5, 32, 66, 6, 195, 48, 83, 78, 20, 6, 195, 36, 48, 82, 65, 8, 197, 5, 65, 76, 21, 64, 20, 6, 195, 4, 48, 82, 65, 0, 5, 194, 80, 80, 20, 0, 7, 195, 12, 242, 64, 72, 9, 10, 199, 56, 245, 20, 21, 65, 77, 64, 20, 9, 198, 24, 147, 143, 12, 50, 9, 20, 10, 199, 20, 229, 21, 76, 144, 83, 80, 68, 10, 199, 12, 20, 142, 20, 98, 67, 20, 21, 0, 7, 196, 4, 224, 200, 20, 8, 11, 200, 80, 84, 154, 60, 113, 78, 37, 64, 67, 7, 196, 76, 85, 20, 20, 20, 7, 196, 76, 84, 18, 36, 20, 7, 196, 52, 81, 193, 72, 65, 6, 195, 28, 243, 77, 21, 6, 195, 28, 227, 205, 20, 14, 68, 24, 18, 78, 4, 83, 35, 6, 37, 12, 50, 35, 0, 0, 8, 197, 5, 100, 133, 52, 240, 72, 8, 197, 76, 20, 133, 52, 240, 72, 8, 197, 76, 21, 18, 5, 0, 65, 8, 197, 29, 32, 70, 20, 208, 20, 15, 69, 24, 197, 73, 16, 240, 83, 55, 6, 40, 37, 72, 39, 0, 8, 197, 20, 227, 212, 20, 48, 20, 8, 197, 12, 19, 143, 56, 80, 65, 8, 197, 12, 16, 195, 4, 208, 65, 0, 9, 198, 85, 38, 149, 48, 82, 64, 67, 13, 202, 81, 32, 78, 76, 48, 85, 12, 20, 201, 4, 68, 9, 198, 60, 195, 15, 48, 18, 64, 67, 9, 198, 56, 148, 195, 20, 210, 64, 20, 10, 198, 21, 52, 197, 72, 50, 64, 65, 20, 9, 198, 5, 51, 79, 56, 82, 64, 67, 0, 6, 195, 24, 18, 64, 76, 6, 195, 16, 82, 64, 72, 7, 195, 48, 82, 64, 76, 9, 10, 199, 64, 243, 9, 20, 68, 137, 12, 20, 10, 199, 24, 147, 15, 81, 65, 84, 20, 20, 10, 198, 12, 19, 66, 60, 114, 65, 66, 20, 0, 7, 196, 84, 197, 18, 4, 66, 6, 195, 76, 243, 77, 21, 7, 196, 60, 225, 193, 72, 65, 7, 196, 48, 19, 79, 56, 66, 7, 196, 16, 243, 73, 56, 65, 7, 196, 4, 194, 66, 36, 65, 0, 6, 195, 76, 227, 194, 20, 8, 197, 72, 245, 133, 72, 80, 21, 8, 197, 72, 81, 21, 12, 80, 65, 12, 201, 69, 80, 84, 80, 244, 132, 36, 50, 64, 21, 9, 198, 64, 19, 131, 72, 80, 83, 65, 8, 197, 21, 49, 77, 64, 144, 20, 9, 197, 16, 240, 204, 20, 16, 65, 20, 6, 195, 4, 49, 82, 65, 0, 8, 67, 4, 49, 83, 21, 0, 10, 6, 194, 81, 80, 76, 9, 9, 198, 64, 148, 133, 56, 82, 64, 67, 9, 198, 61, 35, 204, 60, 114, 64, 20, 9, 198, 52, 243, 143, 48, 149, 0, 66, 9, 198, 12, 19, 129, 104, 82, 64, 67, 9, 198, 12, 19, 79, 76, 50, 64, 20, 9, 198, 8, 148, 143, 12, 50, 64, 20, 9, 198, 4, 208, 146, 60, 114, 64, 20, 0, 10, 199, 77, 66, 76, 60, 32, 84, 20, 66, 6, 195, 76, 243, 64, 20, 9, 198, 24, 84, 137, 80, 242, 65, 21, 6, 195, 8, 145, 84, 20, 0, 11, 200, 80, 20, 129, 57, 64, 83, 36, 16, 67, 7, 196, 76, 84, 19, 36, 20, 11, 200, 76, 19, 9, 76, 49, 78, 16, 144, 21, 7, 196, 13, 80, 137, 80, 65, 9, 198, 4, 229, 9, 64, 21, 18, 66, 11, 200, 4, 229, 9, 56, 49, 78, 16, 144, 20, 9, 198, 4, 225, 18, 60, 114, 78, 66, 0, 7, 195, 20, 50, 74, 65, 21, 6, 195, 4, 50, 78, 65, 0, 10, 198, 48, 147, 134, 60, 227, 196, 67, 20, 0, 6, 195, 76, 227, 196, 20, 6, 195, 64, 85, 20, 20, 10, 199, 36, 65, 78, 80, 146, 201, 80, 68, 6, 195, 36, 49, 84, 65, 11, 199, 12, 244, 132, 20, 227, 206, 76, 67, 20, 10, 199, 12, 19, 142, 4, 195, 206, 28, 20, 10, 199, 4, 229, 9, 76, 84, 19, 36, 20, 0, 5, 195, 12, 243, 69, 9, 198, 88, 243, 20, 52, 85, 18, 65, 7, 196, 28, 83, 73, 80, 65, 0, 8, 197, 12, 244, 148, 21, 48, 66, 0, 9, 198, 20, 225, 137, 76, 83, 64, 20, 0, 9, 198, 88, 83, 12, 21, 68, 137, 21, 10, 199, 80, 84, 141, 61, 53, 1, 80, 66, 0, 7, 196, 80, 85, 20, 36, 20, 10, 198, 64, 148, 143, 76, 48, 70, 66, 20, 7, 196, 8, 243, 66, 20, 66, 0, 8, 197, 80, 244, 130, 36, 64, 21, 8, 197, 80, 147, 80, 4, 224, 65, 8, 197, 80, 19, 148, 4, 192, 65, 12, 201, 69, 82, 78, 16, 144, 197, 76, 147, 64, 20, 8, 197, 13, 35, 212, 4, 192, 65, 8, 197, 5, 84, 133, 60, 192, 67, 0, 9, 198, 76, 147, 143, 64, 144, 64, 20, 9, 198, 72, 149, 137, 56, 50, 84, 66, 9, 198, 65, 83, 9, 104, 144, 64, 67, 9, 198, 36, 225, 129, 52, 144, 64, 66, 9, 198, 21, 128, 197, 57, 68, 128, 20, 9, 198, 21, 84, 129, 76, 144, 64, 67, 9, 198, 21, 52, 5, 72, 144, 64, 66, 9, 198, 5, 53, 5, 72, 144, 64, 66, 10, 198, 5, 33, 5, 76, 144, 64, 66, 20, 0, 0, 7, 196, 72, 85, 9, 56, 65, 8, 196, 52, 22, 154, 20, 66, 20, 7, 196, 48, 19, 73, 56, 65, 0, 8, 197, 88, 19, 132, 4, 192, 65, 8, 197, 76, 19, 132, 4, 192, 65, 12, 201, 52, 84, 207, 64, 245, 1, 52, 144, 64, 68, 12, 201, 5, 85, 15, 12, 81, 129, 48, 144, 64, 70, 0, 9, 198, 73, 85, 5, 56, 144, 64, 20, 9, 198, 72, 147, 129, 76, 50, 84, 66, 9, 198, 65, 32, 83, 76, 80, 64, 65, 9, 198, 64, 20, 143, 16, 144, 64, 67, 9, 198, 24, 192, 77, 20, 224, 192, 21, 7, 195, 21, 36, 143, 66, 20, 10, 198, 16, 243, 15, 52, 144, 64, 66, 20, 9, 198, 5, 53, 5, 56, 144, 64, 67, 9, 198, 4, 193, 207, 88, 144, 64, 20, 0, 10, 199, 76, 53, 79, 48, 16, 149, 76, 67, 0, 9, 198, 24, 244, 211, 4, 227, 214, 20, 9, 198, 12, 20, 144, 60, 99, 210, 66, 7, 196, 4, 226, 68, 72, 65, 0, 8, 197, 81, 32, 70, 61, 32, 21, 12, 201, 80, 16, 200, 36, 48, 82, 16, 144, 64, 68, 12, 201, 52, 148, 195, 20, 195, 1, 56, 80, 64, 67, 7, 195, 20, 53, 66, 65, 20, 12, 201, 9, 32, 68, 36, 48, 82, 16, 144, 64, 68, 0, 6, 195, 48, 85, 67, 65, 0, 10, 199, 16, 145, 204, 61, 52, 201, 4, 67, 0, 6, 195, 64, 242, 0, 20, 7, 196, 8, 80, 82, 56, 21, 0, 8, 197, 81, 34, 77, 21, 32, 65, 8, 197, 81, 34, 70, 61, 32, 65, 6, 195, 64, 243, 0, 20, 8, 197, 37, 51, 205, 21, 32, 66, 8, 197, 16, 148, 208, 85, 64, 65, 8, 197, 9, 83, 7, 5, 32, 65, 0, 6, 194, 76, 144, 76, 9, 9, 198, 76, 241, 134, 36, 49, 64, 20, 9, 198, 64, 84, 142, 36, 49, 64, 66, 9, 198, 56, 20, 148, 20, 49, 64, 20, 9, 198, 52, 20, 211, 36, 209, 64, 65, 9, 198, 37, 53, 18, 36, 49, 64, 65, 9, 198, 24, 244, 142, 4, 49, 64, 66, 0, 10, 199, 76, 96, 67, 80, 84, 137, 4, 66, 10, 199, 29, 82, 68, 37, 166, 143, 48, 67, 10, 199, 29, 81, 82, 72, 18, 79, 48, 21, 0, 13, 68, 24, 145, 82, 36, 83, 6, 37, 36, 51, 37, 0, 7, 196, 64, 84, 149, 56, 66, 7, 196, 12, 243, 73, 76, 65, 7, 196, 12, 147, 69, 28, 65, 9, 198, 4, 100, 129, 28, 243, 0, 21, 0, 8, 197, 5, 97, 83, 80, 144, 72, 8, 197, 69, 81, 83, 80, 144, 72, 8, 197, 52, 243, 143, 52, 144, 20, 8, 197, 48, 84, 194, 36, 48, 20, 8, 197, 12, 83, 9, 56, 80, 21, 8, 197, 8, 244, 135, 36, 16, 65, 0, 9, 198, 76, 19, 85, 72, 18, 64, 67, 6, 195, 64, 244, 0, 20, 9, 198, 5, 69, 5, 56, 67, 204, 20, 0, 9, 198, 52, 147, 137, 52, 22, 0, 67, 10, 199, 25, 33, 67, 12, 85, 20, 20, 21, 9, 198, 5, 36, 143, 76, 50, 65, 20, 9, 198, 4, 225, 207, 76, 50, 65, 20, 0, 11, 200, 88, 83, 148, 37, 49, 84, 80, 80, 20, 7, 196, 80, 244, 142, 36, 21, 9, 198, 52, 20, 129, 80, 131, 206, 67, 7, 196, 24, 147, 79, 56, 66, 7, 196, 20, 66, 76, 20, 66, 0, 8, 197, 88, 244, 212, 72, 144, 72, 8, 197, 56, 244, 212, 72, 144, 72, 8, 197, 73, 80, 146, 36, 48, 66, 8, 197, 56, 84, 212, 48, 80, 66, 8, 197, 52, 20, 147, 36, 16, 65, 9, 197, 21, 69, 15, 72, 80, 65, 20, 8, 197, 21, 51, 198, 4, 112, 66, 8, 197, 12, 243, 12, 20, 112, 20, 8, 197, 12, 80, 201, 80, 16, 67, 9, 198, 12, 20, 148, 4, 49, 79, 66, 0, 9, 198, 72, 245, 133, 76, 50, 64, 20, 14, 202, 52, 243, 148, 20, 51, 205, 64, 21, 18, 36, 67, 20, 9, 198, 52, 19, 132, 36, 35, 204, 66, 9, 198, 21, 32, 67, 48, 149, 0, 66, 0, 7, 2, 95, 1, 35, 12, 0, 14, 203, 88, 147, 12, 4, 208, 83, 76, 20, 135, 36, 16, 68, 9, 198, 85, 53, 1, 76, 50, 65, 65, 9, 198, 72, 245, 133, 76, 50, 65, 20, 20, 71, 12, 20, 129, 36, 34, 67, 60, 49, 35, 51, 35, 6, 37, 71, 37, 49, 39, 0, 10, 199, 12, 19, 142, 36, 32, 76, 20, 66, 10, 199, 12, 19, 80, 4, 226, 76, 20, 67, 19, 70, 4, 195, 208, 20, 50, 65, 35, 55, 39, 48, 36, 76, 6, 37, 12, 35, 0, 0, 11, 200, 80, 83, 80, 61, 32, 78, 20, 240, 67, 7, 196, 24, 195, 197, 52, 20, 0, 12, 201, 52, 20, 148, 37, 35, 204, 60, 114, 64, 20, 0, 17, 70, 88, 82, 67, 60, 195, 192, 84, 109, 6, 37, 49, 39, 55, 39, 0, 9, 198, 65, 35, 194, 48, 83, 64, 20, 9, 198, 21, 48, 78, 80, 83, 64, 20, 0, 7, 2, 95, 5, 36, 12, 0, 10, 199, 20, 225, 137, 80, 85, 83, 36, 67, 0, 7, 196, 88, 243, 73, 80, 65, 7, 196, 76, 83, 69, 48, 20, 0, 8, 197, 16, 147, 206, 37, 48, 66, 0, 7, 2, 95, 9, 37, 12, 0, 9, 198, 64, 84, 137, 20, 113, 84, 20, 0, 10, 199, 61, 35, 199, 20, 225, 83, 36, 67, 6, 195, 36, 65, 9, 66, 6, 195, 8, 16, 129, 66, 0, 7, 2, 95, 15, 110, 12, 0, 6, 195, 44, 240, 128, 20, 6, 195, 12, 240, 128, 20, 0, 7, 196, 76, 35, 195, 12, 21, 7, 196, 56, 147, 69, 28, 20, 6, 195, 21, 48, 67, 20, 12, 201, 16, 144, 201, 61, 69, 5, 76, 147, 64, 20, 8, 196, 12, 131, 195, 60, 66, 20, 7, 196, 8, 147, 206, 16, 21, 0, 8, 197, 88, 242, 86, 60, 64, 20, 8, 197, 76, 244, 135, 60, 224, 65, 6, 195, 64, 83, 142, 21, 0, 9, 198, 72, 243, 65, 56, 144, 64, 67, 9, 198, 12, 243, 131, 61, 36, 192, 21, 0, 6, 195, 81, 80, 64, 72, 10, 199, 12, 192, 90, 60, 209, 78, 20, 66, 10, 198, 8, 243, 148, 20, 35, 203, 65, 20, 0, 7, 196, 88, 243, 69, 72, 65, 7, 196, 88, 84, 142, 20, 66, 8, 196, 80, 83, 69, 56, 65, 20, 7, 196, 76, 19, 65, 72, 65, 12, 200, 52, 243, 148, 20, 66, 83, 60, 224, 66, 20, 7, 196, 52, 81, 204, 36, 20, 7, 196, 13, 83, 133, 60, 65, 7, 196, 12, 19, 65, 72, 65, 0, 8, 197, 104, 244, 16, 60, 192, 20, 12, 201, 80, 80, 200, 56, 144, 207, 48, 244, 128, 20, 8, 197, 72, 149, 15, 72, 224, 21, 8, 197, 60, 210, 67, 36, 64, 67, 8, 197, 56, 84, 208, 60, 192, 20, 8, 197, 45, 84, 149, 52, 32, 65, 8, 197, 40, 244, 16, 60, 192, 20, 9, 198, 12, 243, 12, 61, 21, 73, 20, 8, 197, 12, 20, 144, 36, 224, 65, 0, 9, 198, 53, 83, 20, 37, 3, 0, 65, 9, 198, 52, 16, 207, 52, 84, 128, 67, 9, 198, 12, 243, 137, 24, 84, 128, 66, 10, 198, 12, 243, 135, 73, 80, 64, 65, 20, 9, 198, 4, 208, 82, 12, 244, 132, 67, 0, 10, 199, 104, 20, 15, 80, 80, 200, 36, 20, 10, 199, 9, 33, 78, 80, 243, 137, 12, 21, 10, 199, 4, 229, 9, 12, 19, 69, 72, 67, 0, 11, 200, 64, 144, 78, 80, 84, 146, 20, 224, 21, 0, 7, 2, 95, 21, 40, 12, 0, 9, 198, 88, 83, 148, 21, 50, 77, 20, 9, 197, 44, 84, 139, 101, 32, 65, 21, 9, 198, 12, 83, 148, 21, 50, 77, 20, 0, 9, 198, 12, 243, 137, 84, 113, 64, 65, 0, 6, 195, 81, 81, 64, 72, 6, 195, 88, 83, 0, 21, 6, 195, 88, 83, 0, 21, 10, 199, 12, 16, 200, 21, 52, 201, 4, 67, 0, 7, 196, 64, 84, 195, 20, 21, 8, 196, 52, 84, 201, 4, 65, 20, 0, 8, 197, 104, 147, 135, 5, 32, 65, 8, 197, 60, 113, 197, 81, 64, 20, 8, 197, 52, 20, 148, 61, 32, 65, 8, 197, 52, 19, 77, 85, 64, 66, 6, 195, 28, 243, 142, 21, 0, 6, 194, 80, 144, 76, 9, 9, 198, 72, 19, 69, 77, 49, 64, 20, 9, 198, 64, 83, 137, 76, 243, 0, 66, 6, 195, 61, 101, 137, 20, 9, 198, 24, 144, 193, 72, 243, 0, 67, 6, 195, 4, 65, 9, 66, 0, 10, 199, 5, 100, 133, 8, 33, 82, 60, 72, 10, 199, 28, 243, 9, 5, 33, 9, 4, 68, 10, 198, 8, 80, 84, 72, 150, 0, 65, 21, 11, 199, 5, 21, 73, 48, 81, 201, 4, 67, 20, 0, 6, 195, 76, 243, 143, 72, 6, 195, 76, 243, 143, 72, 7, 196, 4, 195, 69, 56, 21, 0, 6, 195, 88, 85, 0, 20, 8, 197, 80, 17, 4, 20, 144, 66, 6, 195, 76, 243, 142, 21, 9, 197, 76, 83, 143, 56, 144, 65, 20, 9, 198, 28, 19, 66, 85, 50, 65, 66, 8, 197, 16, 83, 79, 56, 80, 20, 6, 195, 12, 243, 142, 21, 8, 197, 12, 19, 137, 48, 80, 66, 9, 198, 5, 4, 129, 77, 50, 65, 67, 0, 6, 195, 28, 243, 137, 20, 9, 198, 16, 144, 76, 37, 50, 64, 66, 0, 7, 195, 49, 82, 64, 76, 9, 10, 199, 77, 64, 78, 37, 51, 1, 60, 67, 10, 199, 64, 20, 142, 5, 52, 207, 76, 67, 10, 199, 52, 20, 143, 8, 241, 21, 60, 20, 9, 198, 48, 148, 85, 36, 112, 83, 67, 9, 198, 21, 53, 18, 4, 225, 79, 66, 10, 199, 12, 243, 2, 72, 144, 207, 56, 67, 0, 15, 2, 95, 34, 84, 37, 51, 81, 39, 55, 36, 47, 12, 36, 0, 11, 200, 37, 53, 1, 57, 64, 78, 20, 16, 67, 7, 196, 28, 83, 196, 20, 20, 7, 196, 8, 193, 86, 36, 20, 0, 23, 2, 95, 33, 48, 4, 40, 50, 47, 39, 36, 89, 49, 55, 35, 65, 35, 47, 6, 37, 84, 39, 0, 8, 197, 88, 149, 18, 20, 240, 65, 8, 197, 88, 147, 137, 48, 80, 66, 12, 201, 80, 84, 141, 60, 113, 78, 21, 50, 64, 67, 8, 197, 69, 82, 69, 80, 80, 20, 12, 201, 61, 53, 5, 60, 113, 78, 21, 50, 64, 68, 9, 197, 52, 83, 79, 72, 80, 65, 20, 12, 201, 20, 193, 84, 81, 35, 204, 37, 50, 64, 67, 8, 197, 8, 242, 5, 52, 80, 20, 8, 197, 8, 144, 137, 80, 80, 65, 8, 197, 8, 19, 1, 4, 208, 65, 0, 6, 195, 64, 83, 129, 21, 6, 195, 4, 195, 5, 72, 11, 67, 20, 195, 1, 36, 55, 55, 35, 0, 76, 6, 195, 81, 85, 21, 66, 9, 198, 76, 147, 148, 21, 50, 64, 65, 9, 198, 37, 3, 198, 37, 50, 64, 66, 6, 195, 24, 19, 133, 66, 6, 195, 21, 35, 197, 20, 7, 195, 16, 83, 133, 66, 20, 9, 198, 5, 3, 198, 37, 50, 64, 66, 0, 8, 195, 12, 243, 128, 72, 8, 9, 15, 2, 95, 39, 35, 48, 6, 110, 89, 47, 51, 39, 83, 39, 0, 6, 195, 80, 85, 84, 65, 10, 199, 76, 21, 5, 48, 194, 84, 20, 66, 6, 195, 12, 240, 136, 21, 0, 12, 68, 40, 80, 78, 76, 75, 37, 12, 50, 88, 0, 7, 196, 72, 84, 197, 16, 20, 11, 200, 64, 243, 148, 72, 83, 79, 48, 144, 66, 11, 200, 64, 20, 146, 60, 48, 200, 36, 16, 20, 12, 200, 48, 84, 9, 48, 83, 85, 72, 80, 67, 20, 7, 196, 37, 51, 1, 52, 66, 11, 200, 21, 65, 82, 60, 113, 78, 20, 240, 68, 7, 196, 20, 195, 199, 36, 20, 6, 195, 12, 243, 135, 20, 0, 10, 198, 52, 16, 197, 16, 243, 133, 66, 20, 8, 197, 44, 18, 82, 61, 48, 66, 9, 198, 28, 19, 1, 80, 243, 133, 66, 12, 201, 24, 245, 15, 76, 147, 148, 21, 50, 64, 67, 9, 198, 16, 21, 80, 32, 147, 133, 68, 9, 198, 13, 81, 204, 36, 84, 137, 65, 9, 198, 12, 193, 79, 52, 83, 133, 66, 8, 197, 12, 21, 67, 5, 48, 65, 9, 198, 5, 52, 197, 52, 35, 5, 67, 6, 195, 5, 50, 78, 65, 0, 6, 195, 48, 83, 129, 21, 6, 195, 4, 195, 1, 72, 7, 195, 104, 19, 133, 66, 20, 6, 195, 20, 195, 5, 21, 0, 7, 195, 21, 35, 192, 72, 9, 6, 195, 64, 83, 132, 21, 6, 195, 5, 50, 76, 66, 0, 6, 195, 4, 195, 15, 72, 17, 4, 95, 3, 1, 16, 65, 35, 57, 6, 40, 89, 49, 39, 55, 35, 0, 7, 196, 76, 243, 65, 48, 65, 7, 196, 56, 83, 66, 72, 20, 8, 196, 28, 243, 73, 80, 65, 21, 7, 196, 20, 227, 195, 32, 20, 7, 196, 8, 241, 213, 20, 66, 9, 198, 4, 65, 78, 60, 209, 82, 67, 0, 21, 2, 95, 41, 49, 57, 4, 40, 88, 35, 48, 35, 51, 6, 36, 50, 47, 36, 88, 37, 0, 8, 197, 80, 131, 204, 61, 48, 21, 9, 198, 12, 21, 133, 16, 147, 133, 21, 0, 6, 195, 24, 20, 133, 76, 10, 198, 4, 48, 193, 57, 67, 192, 76, 28, 22, 2, 95, 40, 35, 48, 4, 36, 51, 47, 35, 48, 35, 51, 6, 36, 50, 47, 36, 88, 37, 0, 9, 198, 48, 244, 133, 16, 19, 128, 67, 9, 198, 44, 128, 77, 76, 147, 128, 66, 9, 198, 37, 4, 201, 48, 243, 128, 65, 13, 202, 20, 193, 84, 81, 35, 198, 61, 33, 83, 36, 20, 9, 198, 8, 20, 153, 80, 243, 128, 65, 0, 8, 195, 64, 84, 128, 72, 8, 9, 10, 199, 76, 81, 9, 12, 84, 201, 52, 20, 6, 195, 21, 50, 84, 65, 10, 199, 12, 243, 73, 57, 65, 82, 56, 67, 0, 7, 196, 77, 4, 133, 12, 20, 6, 195, 76, 244, 135, 21, 7, 196, 52, 16, 201, 56, 65, 7, 196, 21, 67, 137, 12, 20, 8, 196, 20, 35, 204, 36, 65, 20, 0, 14, 2, 95, 45, 47, 14, 16, 35, 47, 12, 37, 50, 39, 0, 12, 201, 84, 197, 18, 5, 65, 82, 72, 83, 128, 21, 8, 197, 81, 34, 84, 60, 224, 65, 8, 197, 64, 246, 154, 60, 192, 66, 0, 13, 2, 95, 44, 84, 6, 37, 51, 81, 39, 55, 35, 0, 9, 198, 76, 240, 195, 61, 36, 192, 21, 9, 198, 76, 50, 79, 64, 84, 128, 65, 9, 198, 76, 19, 79, 88, 20, 128, 67, 9, 198, 72, 147, 131, 61, 36, 192, 21, 13, 202, 65, 50, 67, 61, 65, 82, 5, 1, 85, 80, 69, 9, 198, 64, 84, 131, 61, 36, 192, 21, 9, 198, 61, 35, 5, 4, 228, 192, 21, 6, 195, 44, 244, 133, 66, 9, 198, 16, 148, 195, 61, 36, 192, 21, 6, 195, 12, 244, 133, 20, 9, 198, 12, 19, 15, 28, 84, 128, 66, 9, 198, 4, 193, 197, 56, 144, 128, 20, 0, 9, 2, 95, 51, 47, 51, 6, 36, 0, 6, 195, 76, 244, 132, 21, 10, 199, 12, 243, 12, 4, 113, 78, 20, 66, 0, 9, 2, 95, 50, 72, 6, 40, 36, 0, 7, 196, 76, 21, 21, 72, 65, 7, 196, 48, 147, 69, 56, 65, 6, 195, 12, 243, 147, 20, 7, 196, 12, 19, 69, 72, 65, 9, 198, 8, 84, 148, 60, 193, 0, 20, 0, 9, 2, 95, 49, 6, 40, 50, 39, 0, 8, 197, 77, 82, 67, 36, 64, 66, 6, 195, 64, 86, 154, 20, 8, 197, 52, 145, 206, 60, 192, 65, 8, 197, 24, 83, 77, 36, 224, 65, 8, 197, 16, 243, 142, 60, 192, 20, 12, 201, 8, 244, 135, 61, 48, 84, 60, 195, 0, 21, 9, 197, 5, 4, 18, 60, 64, 66, 20, 0, 11, 2, 95, 48, 72, 88, 6, 36, 51, 39, 0, 9, 198, 77, 64, 70, 24, 244, 128, 65, 6, 195, 48, 85, 133, 20, 10, 198, 12, 240, 207, 52, 84, 128, 66, 21, 0, 11, 2, 95, 55, 89, 6, 109, 47, 12, 36, 0, 10, 199, 24, 244, 141, 4, 194, 84, 4, 68, 6, 195, 5, 163, 212, 20, 0, 7, 196, 5, 100, 133, 36, 72, 9, 2, 95, 54, 89, 6, 109, 57, 0, 7, 196, 80, 148, 143, 48, 66, 7, 195, 64, 84, 143, 66, 20, 7, 196, 21, 67, 137, 4, 66, 7, 196, 17, 83, 9, 4, 66, 9, 198, 12, 244, 146, 61, 69, 0, 21, 0, 12, 2, 95, 53, 76, 6, 37, 50, 49, 122, 36, 0, 8, 197, 64, 192, 67, 37, 64, 65, 8, 197, 56, 20, 195, 37, 64, 65, 8, 197, 48, 20, 195, 37, 64, 65, 0, 13, 2, 95, 52, 49, 122, 6, 35, 47, 12, 51, 39, 0, 9, 198, 76, 48, 82, 64, 19, 148, 65, 13, 202, 8, 147, 212, 85, 32, 129, 104, 147, 206, 20, 20, 0, 9, 198, 5, 97, 83, 76, 84, 143, 72, 20, 2, 95, 59, 48, 4, 40, 50, 47, 39, 36, 84, 6, 37, 51, 81, 39, 55, 35, 0, 0, 7, 196, 52, 83, 66, 72, 20, 12, 201, 12, 147, 145, 84, 19, 148, 21, 50, 77, 20, 0, 10, 2, 95, 57, 50, 6, 110, 84, 36, 0, 8, 197, 64, 84, 141, 85, 64, 65, 8, 197, 28, 19, 66, 21, 32, 65, 8, 197, 12, 21, 20, 5, 32, 65, 0, 10, 2, 95, 56, 6, 110, 47, 12, 39, 0, 10, 198, 76, 241, 204, 36, 243, 0, 65, 20, 9, 198, 52, 85, 1, 64, 243, 148, 20, 10, 198, 5, 85, 15, 77, 67, 208, 68, 20, 0, 24, 2, 95, 63, 48, 4, 40, 50, 47, 39, 37, 50, 47, 36, 51, 39, 81, 35, 47, 6, 37, 84, 39, 0, 10, 199, 64, 20, 129, 16, 148, 197, 4, 67, 0, 18, 2, 95, 62, 49, 57, 4, 40, 88, 35, 6, 35, 50, 81, 39, 55, 39, 0, 11, 200, 81, 84, 130, 60, 19, 2, 21, 32, 67, 9, 198, 64, 148, 143, 77, 49, 78, 66, 11, 200, 12, 243, 148, 72, 19, 2, 21, 32, 66, 10, 198, 5, 85, 15, 13, 67, 206, 67, 20, 0, 9, 198, 77, 66, 80, 20, 225, 9, 20, 6, 195, 72, 245, 0, 20, 8, 197, 72, 16, 193, 48, 80, 65, 9, 197, 64, 144, 195, 32, 80, 66, 20, 10, 198, 61, 37, 5, 57, 50, 65, 66, 20, 8, 197, 52, 147, 9, 80, 80, 65, 8, 197, 48, 148, 1, 72, 144, 65, 9, 197, 48, 16, 195, 32, 80, 66, 20, 8, 197, 28, 83, 133, 76, 144, 20, 9, 197, 16, 80, 193, 16, 80, 65, 20, 8, 197, 12, 243, 147, 12, 144, 20, 9, 198, 12, 243, 80, 20, 225, 9, 20, 8, 197, 9, 83, 20, 20, 144, 66, 0, 19, 2, 95, 60, 35, 48, 4, 36, 51, 47, 35, 6, 35, 50, 81, 39, 55, 39, 0, 9, 198, 104, 19, 66, 21, 50, 64, 20, 9, 198, 61, 37, 5, 57, 50, 64, 20, 9, 198, 16, 145, 82, 21, 50, 64, 65, 0, 6, 195, 12, 244, 148, 21, 0, 7, 196, 80, 19, 65, 72, 65, 11, 200, 72, 85, 20, 36, 194, 78, 20, 240, 67, 9, 198, 56, 144, 197, 72, 21, 0, 66, 7, 196, 16, 147, 69, 72, 65, 11, 200, 16, 145, 1, 76, 48, 76, 36, 16, 68, 7, 196, 16, 19, 65, 72, 65, 11, 200, 9, 32, 67, 32, 144, 197, 72, 144, 66, 7, 196, 4, 211, 210, 36, 21, 0, 8, 197, 76, 81, 9, 48, 80, 66, 8, 197, 76, 19, 132, 36, 16, 66, 12, 201, 65, 50, 67, 60, 50, 78, 21, 50, 64, 20, 8, 197, 64, 20, 146, 60, 48, 65, 12, 201, 64, 19, 9, 56, 113, 78, 21, 50, 64, 67, 8, 197, 48, 244, 147, 36, 48, 21, 8, 197, 48, 145, 206, 20, 240, 65, 8, 197, 48, 84, 211, 36, 48, 20, 9, 198, 48, 21, 82, 5, 50, 65, 67, 8, 197, 36, 194, 65, 16, 80, 66, 8, 197, 21, 53, 1, 76, 144, 65, 8, 197, 12, 244, 142, 20, 16, 65, 8, 197, 12, 129, 79, 64, 80, 65, 8, 197, 8, 17, 9, 48, 80, 66, 12, 201, 4, 225, 201, 60, 113, 78, 21, 50, 64, 67, 0, 9, 198, 76, 147, 134, 37, 50, 64, 65, 9, 198, 65, 35, 212, 21, 50, 64, 65, 9, 198, 37, 3, 212, 21, 50, 64, 66, 9, 198, 16, 144, 84, 21, 50, 64, 66, 9, 198, 9, 34, 65, 57, 163, 204, 67, 0, 10, 199, 12, 244, 15, 48, 147, 69, 72, 67, 0, 9, 196, 76, 245, 20, 60, 76, 28, 21, 11, 200, 80, 244, 142, 4, 37, 79, 56, 144, 20, 15, 204, 61, 52, 201, 16, 244, 133, 17, 85, 20, 5, 50, 64, 65, 11, 200, 60, 194, 71, 5, 32, 200, 36, 16, 68, 11, 200, 12, 243, 5, 61, 69, 5, 72, 144, 20, 9, 198, 8, 243, 135, 36, 244, 142, 21, 11, 200, 5, 85, 5, 57, 66, 67, 32, 80, 20, 0, 9, 198, 64, 244, 137, 24, 84, 137, 66, 9, 198, 36, 224, 207, 49, 83, 69, 66, 0, 9, 198, 8, 20, 212, 36, 19, 128, 66, 0, 14, 203, 5, 48, 201, 84, 112, 67, 5, 1, 76, 48, 144, 21, 0, 7, 196, 88, 244, 199, 36, 20, 7, 196, 76, 147, 69, 80, 20, 12, 201, 72, 240, 195, 4, 114, 79, 88, 147, 133, 21, 12, 201, 52, 243, 148, 21, 97, 82, 28, 147, 133, 21, 6, 195, 36, 193, 79, 65, 7, 195, 28, 241, 207, 66, 20, 7, 196, 28, 19, 65, 48, 65, 12, 201, 5, 34, 83, 80, 241, 201, 80, 243, 133, 68, 0, 8, 133, 1, 22, 18, 195, 160, 72, 8, 197, 81, 33, 86, 21, 48, 20, 9, 198, 69, 80, 82, 21, 50, 77, 21, 8, 197, 60, 34, 68, 61, 48, 21, 9, 198, 52, 83, 15, 52, 19, 133, 66, 8, 197, 8, 147, 199, 5, 48, 67, 0, 10, 198, 8, 145, 78, 80, 147, 128, 65, 20, 9, 198, 8, 22, 65, 52, 243, 128, 67, 0, 10, 199, 76, 20, 133, 8, 33, 82, 60, 72, 10, 199, 84, 225, 9, 12, 84, 201, 52, 20, 6, 195, 80, 83, 204, 66, 10, 199, 52, 19, 12, 60, 96, 71, 36, 66, 0, 7, 196, 80, 84, 197, 72, 65, 7, 196, 77, 68, 133, 76, 20, 6, 195, 48, 80, 195, 21, 12, 201, 36, 229, 15, 56, 20, 149, 52, 244, 137, 21, 0, 8, 197, 48, 19, 80, 4, 64, 65, 8, 197, 16, 84, 205, 4, 224, 20, 6, 195, 12, 241, 206, 20, 9, 198, 5, 52, 197, 52, 147, 137, 66, 0, 9, 198, 60, 208, 133, 48, 144, 192, 67, 9, 198, 16, 243, 69, 56, 144, 192, 21, 0, 10, 199, 81, 34, 65, 80, 131, 15, 56, 65, 6, 195, 80, 80, 192, 20, 9, 198, 28, 243, 1, 76, 80, 195, 21, 6, 195, 16, 80, 192, 20, 10, 199, 12, 130, 76, 36, 17, 207, 56, 67, 0, 6, 195, 80, 80, 207, 21, 12, 200, 28, 195, 194, 36, 49, 70, 4, 192, 67, 20, 12, 200, 21, 65, 82, 60, 49, 70, 4, 192, 68, 20, 7, 196, 4, 224, 207, 72, 21, 0, 9, 198, 80, 19, 69, 72, 144, 197, 67, 8, 197, 52, 20, 146, 60, 224, 66, 8, 197, 28, 20, 154, 60, 224, 66, 8, 197, 16, 20, 147, 20, 224, 65, 8, 197, 12, 243, 77, 60, 64, 20, 9, 198, 8, 84, 135, 20, 113, 201, 21, 0, 13, 202, 80, 84, 141, 60, 83, 5, 81, 68, 137, 12, 20, 9, 198, 80, 83, 5, 52, 16, 192, 20, 9, 198, 21, 84, 137, 48, 240, 192, 67, 9, 198, 4, 225, 137, 48, 240, 192, 66, 0, 10, 199, 88, 19, 19, 5, 52, 201, 56, 66, 6, 195, 80, 80, 204, 20, 10, 199, 16, 148, 207, 72, 66, 78, 20, 21, 0, 7, 196, 5, 100, 129, 36, 72, 30, 4, 95, 4, 15, 20, 48, 6, 40, 50, 47, 39, 15, 89, 4, 39, 84, 14, 16, 35, 89, 49, 14, 16, 6, 37, 47, 12, 39, 0, 6, 195, 80, 80, 203, 20, 9, 198, 52, 19, 148, 36, 51, 210, 66, 9, 198, 12, 147, 133, 12, 197, 66, 67, 0, 8, 197, 77, 81, 4, 37, 64, 65, 8, 197, 76, 83, 137, 61, 32, 20, 8, 197, 76, 83, 137, 61, 32, 65, 8, 197, 72, 147, 142, 61, 96, 20, 8, 197, 72, 81, 4, 37, 64, 65, 8, 197, 65, 83, 16, 37, 64, 65, 8, 197, 64, 147, 214, 21, 32, 66, 8, 197, 52, 83, 136, 37, 32, 66, 9, 197, 13, 33, 68, 37, 64, 65, 21, 8, 197, 12, 243, 80, 37, 64, 65, 0, 10, 198, 76, 241, 143, 12, 193, 64, 65, 20, 6, 195, 20, 65, 65, 21, 6, 195, 16, 80, 201, 20, 6, 195, 8, 17, 197, 66, 6, 195, 4, 193, 65, 65, 0, 14, 5, 1, 22, 18, 195, 178, 108, 84, 34, 6, 110, 0, 72, 7, 195, 12, 129, 64, 72, 8, 20, 2, 95, 91, 35, 48, 6, 36, 51, 47, 35, 49, 122, 6, 35, 72, 14, 16, 35, 0, 10, 199, 64, 19, 12, 4, 229, 79, 80, 20, 9, 198, 52, 243, 143, 64, 16, 203, 67, 6, 195, 16, 81, 192, 20, 10, 199, 13, 34, 83, 61, 53, 15, 52, 66, 6, 195, 4, 193, 64, 66, 0, 9, 198, 77, 84, 5, 72, 147, 210, 21, 6, 195, 76, 244, 147, 21, 7, 196, 52, 148, 201, 4, 65, 7, 196, 12, 83, 66, 72, 20, 7, 196, 5, 36, 9, 4, 66, 12, 201, 4, 65, 78, 60, 148, 15, 24, 148, 201, 69, 0, 6, 195, 76, 241, 0, 20, 8, 197, 76, 50, 5, 73, 160, 21, 9, 198, 64, 148, 143, 48, 148, 201, 66, 8, 197, 64, 19, 132, 5, 32, 65, 6, 195, 48, 83, 206, 21, 8, 197, 20, 194, 88, 37, 32, 67, 6, 195, 20, 65, 78, 20, 9, 197, 16, 21, 150, 21, 32, 66, 21, 9, 197, 12, 243, 131, 5, 96, 65, 20, 6, 195, 4, 193, 78, 21, 0, 8, 198, 69, 80, 76, 12, 129, 64, 9, 66, 88, 144, 84, 37, 0, 76, 9, 9, 198, 76, 48, 78, 16, 19, 0, 65, 9, 198, 69, 80, 68, 72, 145, 192, 66, 9, 198, 64, 243, 12, 36, 225, 64, 20, 9, 198, 64, 84, 137, 12, 193, 64, 65, 9, 198, 56, 145, 86, 60, 193, 64, 20, 9, 198, 20, 113, 77, 60, 225, 64, 20, 9, 198, 12, 243, 147, 60, 193, 64, 20, 9, 198, 12, 243, 135, 72, 81, 192, 20, 6, 195, 8, 18, 193, 66, 9, 198, 5, 52, 1, 72, 17, 192, 66, 0, 8, 67, 12, 128, 84, 21, 0, 10, 16, 2, 95, 95, 6, 40, 50, 72, 36, 51, 89, 49, 39, 51, 36, 0, 10, 199, 65, 83, 3, 32, 84, 137, 4, 66, 9, 198, 64, 85, 20, 36, 225, 79, 66, 6, 195, 60, 130, 64, 20, 0, 13, 2, 95, 94, 49, 35, 48, 12, 40, 76, 12, 39, 0, 7, 196, 20, 193, 84, 80, 20, 10, 198, 8, 18, 129, 104, 85, 0, 67, 21, 7, 196, 5, 4, 5, 56, 21, 0, 8, 197, 5, 100, 133, 80, 80, 72, 8, 197, 69, 81, 83, 80, 240, 72, 19, 2, 95, 93, 49, 57, 4, 40, 88, 35, 49, 122, 6, 35, 72, 14, 16, 35, 0, 9, 198, 80, 148, 129, 56, 226, 65, 67, 9, 197, 64, 20, 133, 72, 80, 66, 21, 8, 197, 52, 147, 208, 36, 16, 67, 8, 197, 48, 147, 73, 80, 80, 65, 6, 195, 36, 51, 206, 20, 9, 198, 16, 144, 67, 60, 226, 65, 68, 8, 197, 16, 83, 79, 56, 144, 67, 8, 197, 12, 84, 131, 32, 144, 21, 8, 197, 8, 244, 135, 32, 144, 21, 0, 9, 198, 77, 65, 70, 4, 226, 64, 65, 6, 195, 64, 84, 149, 66, 9, 198, 36, 224, 197, 56, 66, 64, 20, 9, 198, 16, 80, 197, 56, 226, 64, 20, 9, 198, 12, 144, 204, 4, 66, 64, 65, 9, 198, 4, 48, 197, 28, 194, 64, 20, 0, 9, 198, 12, 243, 80, 72, 84, 211, 20, 6, 195, 4, 194, 64, 66, 0, 11, 200, 76, 83, 73, 12, 84, 131, 32, 144, 21, 12, 201, 76, 50, 9, 88, 83, 143, 28, 194, 65, 20, 12, 201, 69, 80, 76, 76, 149, 143, 28, 194, 65, 20, 11, 200, 64, 19, 142, 60, 48, 200, 36, 16, 20, 11, 200, 36, 229, 5, 73, 4, 133, 80, 80, 66, 8, 196, 20, 194, 84, 20, 65, 21, 7, 195, 12, 130, 79, 66, 20, 0, 8, 197, 88, 244, 212, 72, 240, 72, 8, 197, 56, 244, 212, 72, 240, 72, 6, 195, 76, 245, 146, 21, 9, 197, 56, 244, 212, 60, 144, 65, 21, 8, 197, 56, 18, 65, 16, 80, 65, 9, 198, 52, 19, 20, 20, 212, 0, 20, 8, 197, 24, 243, 79, 72, 144, 65, 8, 197, 21, 53, 15, 56, 144, 65, 8, 197, 21, 21, 73, 16, 144, 20, 9, 198, 20, 113, 77, 60, 226, 65, 68, 9, 198, 4, 226, 82, 36, 66, 65, 68, 0, 13, 2, 95, 96, 71, 35, 49, 48, 14, 16, 117, 65, 0, 12, 201, 60, 67, 206, 80, 245, 5, 12, 226, 67, 20, 9, 198, 52, 243, 135, 60, 194, 64, 20, 9, 198, 5, 96, 77, 64, 244, 212, 21, 0, 0, 11, 200, 80, 84, 129, 64, 85, 84, 36, 48, 67, 8, 196, 48, 80, 201, 80, 65, 21, 11, 200, 36, 229, 5, 72, 194, 78, 20, 16, 67, 7, 196, 21, 84, 137, 80, 65, 12, 201, 20, 224, 201, 12, 195, 208, 20, 66, 65, 69, 12, 201, 12, 147, 145, 84, 81, 143, 28, 194, 69, 20, 7, 196, 5, 67, 5, 80, 20, 6, 195, 4, 193, 83, 20, 7, 196, 4, 67, 69, 80, 20, 0, 8, 197, 65, 35, 212, 5, 48, 65, 6, 195, 28, 246, 154, 21, 8, 197, 24, 17, 68, 37, 48, 20, 6, 195, 20, 65, 82, 65, 0, 10, 198, 81, 34, 86, 20, 225, 84, 66, 20, 9, 198, 72, 245, 21, 48, 83, 192, 66, 9, 198, 52, 81, 9, 12, 83, 192, 66, 9, 198, 24, 244, 129, 56, 83, 192, 66, 0, 10, 199, 64, 83, 148, 5, 67, 5, 80, 20, 6, 195, 48, 83, 192, 21, 0, 12, 201, 65, 35, 211, 80, 17, 133, 72, 84, 201, 67, 6, 195, 64, 84, 195, 20, 6, 195, 64, 84, 195, 20, 6, 195, 12, 244, 195, 20, 7, 196, 5, 36, 133, 16, 20, 0, 9, 198, 72, 241, 9, 80, 244, 137, 21, 9, 198, 57, 85, 143, 48, 243, 133, 20, 0, 15, 4, 95, 7, 18, 22, 81, 14, 16, 6, 35, 12, 84, 36, 0, 6, 195, 12, 244, 193, 66, 10, 198, 12, 83, 1, 16, 243, 128, 65, 21, 0, 10, 199, 28, 194, 67, 60, 194, 83, 36, 66, 6, 195, 20, 66, 84, 65, 9, 198, 12, 241, 84, 4, 225, 79, 67, 9, 198, 12, 21, 20, 4, 225, 79, 66, 6, 195, 4, 194, 84, 65, 0, 11, 200, 12, 243, 69, 28, 194, 65, 57, 48, 67, 0, 8, 197, 104, 240, 195, 60, 192, 20, 8, 197, 88, 20, 133, 56, 224, 21, 8, 197, 72, 240, 195, 60, 192, 20, 8, 197, 64, 83, 132, 84, 192, 20, 8, 197, 52, 243, 20, 20, 224, 21, 6, 195, 48, 84, 194, 20, 8, 197, 16, 144, 67, 60, 224, 66, 8, 197, 12, 19, 73, 60, 224, 65, 8, 197, 9, 81, 134, 4, 192, 65, 0, 9, 198, 69, 80, 76, 12, 244, 192, 20, 7, 195, 65, 84, 133, 66, 20, 9, 198, 60, 198, 77, 64, 244, 192, 65, 9, 198, 52, 20, 137, 64, 244, 192, 20, 0, 6, 195, 20, 66, 80, 65, 10, 199, 17, 32, 71, 4, 210, 78, 20, 67, 0, 7, 196, 77, 68, 143, 24, 20, 8, 196, 72, 244, 197, 60, 65, 20, 9, 198, 72, 145, 146, 20, 65, 0, 21, 11, 200, 5, 32, 201, 16, 144, 67, 60, 224, 67, 0, 9, 198, 104, 84, 134, 4, 194, 85, 67, 8, 197, 52, 83, 147, 60, 192, 20, 9, 198, 12, 243, 80, 48, 144, 197, 20, 8, 197, 12, 243, 15, 28, 224, 20, 8, 197, 12, 19, 132, 20, 192, 21, 0, 6, 195, 65, 84, 137, 66, 6, 195, 64, 84, 201, 20, 9, 198, 64, 83, 148, 5, 67, 0, 20, 9, 198, 64, 83, 148, 5, 67, 0, 65, 9, 198, 12, 83, 148, 72, 144, 192, 20, 0, 0, 7, 196, 52, 84, 207, 48, 65, 13, 201, 16, 144, 207, 80, 147, 5, 16, 243, 137, 68, 20, 9, 198, 12, 243, 134, 21, 69, 0, 20, 0, 8, 197, 76, 148, 15, 57, 64, 20, 9, 198, 76, 128, 78, 28, 128, 73, 66, 9, 198, 64, 20, 129, 48, 148, 201, 66, 9, 197, 48, 84, 1, 57, 64, 65, 20, 0, 6, 195, 80, 84, 201, 20, 9, 198, 76, 84, 150, 36, 193, 64, 66, 10, 198, 52, 81, 193, 12, 193, 64, 65, 20, 9, 198, 21, 34, 71, 60, 225, 64, 66, 6, 195, 16, 84, 201, 20, 0, 20, 2, 95, 123, 35, 48, 4, 36, 51, 47, 35, 81, 14, 16, 6, 35, 83, 12, 35, 0, 16, 4, 95, 4, 9, 1, 72, 57, 36, 51, 6, 36, 12, 88, 126, 0, 10, 199, 76, 147, 135, 32, 147, 218, 104, 21, 10, 199, 5, 85, 15, 64, 147, 15, 80, 20, 9, 198, 5, 32, 200, 20, 192, 79, 67, 0, 8, 196, 76, 84, 201, 4, 65, 20, 7, 196, 72, 84, 201, 4, 65, 7, 196, 52, 84, 211, 20, 20, 0, 6, 195, 80, 241, 0, 20, 8, 197, 77, 83, 195, 21, 32, 65, 8, 197, 72, 83, 132, 37, 64, 65, 8, 197, 65, 35, 198, 21, 64, 20, 8, 197, 64, 20, 212, 61, 32, 21, 12, 201, 12, 20, 212, 20, 197, 133, 72, 65, 64, 21, 0, 9, 198, 77, 84, 146, 20, 225, 64, 21, 9, 198, 72, 85, 20, 36, 98, 76, 67, 9, 198, 64, 144, 90, 104, 243, 0, 67, 9, 198, 61, 53, 18, 60, 115, 212, 20, 9, 198, 28, 83, 148, 36, 193, 64, 66, 9, 198, 21, 48, 200, 36, 225, 64, 20, 9, 198, 16, 80, 201, 8, 83, 0, 67, 9, 198, 16, 80, 193, 48, 241, 192, 66, 9, 198, 12, 244, 148, 36, 193, 64, 66, 10, 198, 12, 86, 129, 56, 225, 64, 65, 21, 9, 198, 12, 21, 1, 48, 241, 192, 66, 9, 198, 4, 229, 5, 56, 225, 64, 21, 0, 0, 7, 196, 81, 84, 129, 56, 66, 7, 196, 72, 148, 193, 56, 65, 9, 198, 72, 80, 193, 72, 81, 0, 20, 7, 196, 52, 20, 197, 72, 66, 7, 196, 12, 244, 197, 56, 21, 7, 196, 5, 83, 15, 76, 67, 0, 19, 2, 95, 125, 49, 57, 4, 40, 88, 35, 81, 14, 16, 6, 35, 83, 12, 35, 0, 8, 197, 84, 36, 137, 4, 48, 67, 6, 195, 80, 245, 0, 20, 8, 197, 80, 84, 195, 32, 144, 20, 9, 197, 76, 20, 5, 72, 80, 66, 21, 9, 198, 52, 243, 133, 28, 194, 65, 20, 12, 201, 52, 81, 137, 77, 67, 198, 20, 193, 64, 67, 8, 197, 28, 19, 1, 80, 144, 65, 9, 198, 21, 2, 70, 4, 226, 65, 68, 8, 197, 5, 52, 197, 16, 144, 20, 9, 198, 4, 224, 82, 12, 130, 65, 67, 0, 6, 195, 80, 244, 0, 20, 9, 198, 52, 243, 5, 12, 243, 0, 20, 9, 198, 52, 148, 212, 72, 19, 0, 66, 6, 195, 20, 69, 73, 20, 0, 10, 199, 76, 245, 20, 60, 35, 211, 12, 20, 9, 198, 76, 244, 16, 72, 84, 211, 20, 10, 199, 64, 147, 129, 12, 245, 5, 12, 20, 11, 199, 64, 20, 148, 20, 227, 208, 20, 66, 20, 10, 199, 52, 243, 132, 4, 67, 210, 36, 21, 10, 199, 52, 20, 148, 36, 226, 84, 80, 67, 0, 8, 196, 21, 52, 5, 72, 65, 20, 11, 200, 61, 38, 137, 88, 80, 195, 32, 144, 20, 9, 198, 21, 2, 84, 72, 149, 0, 66, 9, 198, 12, 243, 80, 36, 85, 0, 20, 7, 196, 5, 165, 5, 12, 20, 7, 196, 4, 229, 65, 44, 66, 9, 198, 4, 193, 129, 8, 85, 0, 20, 7, 196, 4, 115, 210, 4, 67, 0, 8, 197, 80, 83, 129, 12, 80, 66, 9, 198, 76, 195, 214, 20, 226, 65, 20, 8, 197, 76, 50, 5, 72, 208, 21, 9, 198, 72, 243, 65, 56, 66, 65, 67, 9, 198, 65, 35, 211, 60, 66, 65, 67, 34, 77, 60, 194, 71, 60, 65, 78, 17, 35, 199, 48, 147, 205, 4, 110, 55, 37, 81, 39, 72, 36, 50, 72, 14, 16, 39, 61, 6, 37, 110, 65, 35, 0, 8, 197, 56, 21, 83, 20, 16, 65, 9, 198, 52, 243, 148, 60, 113, 201, 20, 8, 197, 52, 148, 212, 72, 16, 66, 8, 197, 48, 85, 20, 36, 112, 66, 8, 197, 20, 208, 140, 20, 208, 20, 0, 9, 198, 88, 19, 132, 4, 194, 64, 65, 6, 195, 80, 81, 213, 66, 6, 195, 76, 240, 201, 20, 6, 195, 48, 84, 205, 20, 9, 198, 29, 84, 208, 36, 226, 64, 65, 9, 198, 17, 84, 15, 56, 66, 64, 20, 6, 195, 12, 244, 201, 66, 9, 198, 12, 129, 82, 4, 66, 64, 65, 0, 10, 199, 24, 83, 77, 36, 226, 76, 20, 67, 10, 199, 13, 35, 211, 80, 16, 197, 60, 66, 0, 11, 200, 81, 84, 144, 36, 195, 209, 84, 144, 20, 9, 198, 72, 148, 208, 61, 53, 0, 21, 11, 200, 52, 243, 148, 21, 97, 82, 16, 80, 21, 11, 200, 37, 1, 82, 80, 84, 141, 36, 16, 68, 7, 196, 21, 84, 143, 64, 20, 0, 12, 201, 69, 80, 68, 72, 145, 143, 28, 194, 64, 20, 9, 198, 37, 3, 212, 4, 192, 77, 67, 0, 9, 198, 5, 97, 86, 4, 211, 192, 72, 9, 198, 21, 32, 86, 4, 211, 192, 72, 6, 195, 61, 4, 9, 20, 13, 202, 52, 20, 129, 12, 19, 1, 28, 243, 137, 76, 20, 6, 195, 12, 244, 205, 20, 6, 195, 12, 244, 205, 20, 0, 10, 199, 61, 34, 84, 80, 84, 143, 64, 67, 0, 9, 198, 81, 34, 80, 61, 53, 0, 21, 8, 196, 76, 84, 193, 52, 65, 20, 0, 8, 197, 76, 85, 146, 21, 48, 20, 9, 198, 16, 148, 208, 72, 244, 201, 20, 0, 9, 198, 24, 244, 211, 36, 211, 192, 72, 6, 194, 84, 224, 72, 9, 16, 70, 76, 49, 73, 12, 51, 192, 91, 109, 6, 37, 49, 12, 39, 0, 9, 198, 4, 229, 5, 48, 19, 192, 67, 0, 6, 195, 64, 243, 12, 21, 6, 195, 64, 243, 12, 21, 9, 198, 64, 84, 144, 21, 69, 79, 20, 19, 70, 12, 148, 131, 84, 149, 15, 76, 37, 14, 16, 49, 6, 40, 37, 47, 39, 0, 0, 7, 195, 76, 19, 15, 66, 20, 7, 196, 49, 85, 5, 60, 65, 9, 198, 4, 224, 67, 60, 225, 0, 20, 7, 196, 4, 115, 210, 16, 65, 0, 8, 197, 81, 84, 143, 48, 64, 20, 8, 197, 76, 19, 148, 20, 224, 65, 9, 197, 56, 147, 82, 60, 64, 66, 20, 9, 198, 52, 147, 12, 20, 227, 137, 20, 9, 197, 12, 244, 132, 60, 32, 65, 21, 0, 6, 195, 81, 83, 201, 72, 9, 198, 69, 80, 76, 37, 64, 64, 67, 6, 195, 52, 81, 9, 20, 6, 195, 5, 48, 197, 66, 0, 10, 199, 36, 229, 5, 72, 209, 68, 36, 20, 12, 201, 8, 245, 76, 21, 85, 5, 72, 147, 206, 21, 0, 0, 8, 197, 76, 50, 5, 72, 224, 21, 8, 197, 76, 48, 80, 60, 192, 65, 12, 201, 64, 244, 211, 36, 34, 76, 37, 64, 64, 69, 9, 198, 64, 80, 195, 36, 243, 9, 20, 10, 198, 56, 83, 65, 80, 241, 9, 67, 20, 8, 197, 12, 244, 16, 60, 192, 20, 0, 10, 198, 36, 224, 207, 28, 226, 84, 66, 20, 9, 198, 24, 20, 142, 21, 51, 204, 67, 9, 198, 5, 32, 200, 21, 66, 80, 66, 10, 198, 4, 48, 210, 20, 66, 84, 66, 21, 0, 10, 199, 80, 84, 212, 36, 211, 206, 20, 20, 10, 199, 61, 53, 18, 60, 115, 212, 36, 20, 10, 199, 52, 17, 206, 21, 68, 143, 56, 65, 10, 199, 16, 148, 207, 56, 84, 212, 4, 68, 9, 198, 16, 148, 195, 61, 65, 67, 20, 0, 7, 196, 104, 85, 71, 52, 65, 7, 196, 29, 85, 5, 36, 66, 0, 12, 201, 88, 147, 12, 5, 50, 77, 37, 84, 192, 68, 8, 197, 72, 148, 207, 49, 64, 20, 8, 197, 52, 244, 195, 61, 96, 20, 9, 197, 52, 243, 15, 81, 32, 65, 20, 8, 197, 17, 32, 71, 85, 64, 66, 8, 197, 13, 84, 195, 85, 64, 65, 0, 13, 202, 80, 83, 78, 61, 52, 15, 56, 66, 76, 36, 20, 9, 198, 76, 20, 211, 60, 225, 64, 65, 10, 198, 64, 144, 67, 21, 33, 64, 67, 21, 9, 198, 52, 17, 206, 21, 65, 64, 20, 7, 195, 48, 241, 5, 66, 20, 0, 10, 199, 9, 35, 206, 12, 130, 79, 48, 66, 6, 195, 9, 33, 68, 20, 8, 197, 8, 147, 212, 61, 0, 66, 9, 198, 4, 225, 137, 5, 32, 79, 67, 0, 7, 196, 61, 52, 143, 20, 65, 7, 196, 20, 194, 77, 36, 65, 7, 196, 13, 84, 15, 48, 65, 0, 9, 198, 64, 84, 144, 21, 69, 65, 20, 9, 198, 48, 245, 26, 61, 32, 73, 67, 6, 195, 25, 33, 78, 21, 0, 9, 198, 76, 20, 133, 77, 65, 64, 72, 9, 198, 88, 19, 12, 21, 97, 64, 20, 9, 198, 52, 144, 200, 36, 83, 0, 66, 14, 202, 12, 195, 210, 4, 209, 133, 56, 144, 207, 48, 69, 20, 9, 198, 12, 144, 204, 61, 1, 64, 20, 0, 10, 199, 69, 80, 68, 73, 84, 15, 48, 67, 10, 199, 64, 144, 195, 5, 33, 9, 4, 67, 10, 199, 52, 16, 210, 60, 51, 211, 52, 20, 0, 7, 196, 76, 148, 193, 72, 65, 7, 196, 72, 84, 201, 56, 65, 7, 196, 52, 148, 197, 72, 65, 7, 196, 12, 84, 193, 72, 65, 7, 195, 12, 17, 15, 66, 20, 6, 195, 5, 65, 79, 65, 7, 196, 4, 195, 208, 20, 65, 0, 6, 195, 104, 85, 0, 20, 15, 69, 80, 82, 83, 80, 16, 47, 109, 6, 37, 89, 47, 35, 0, 9, 198, 76, 145, 206, 61, 34, 65, 67, 8, 197, 64, 83, 15, 76, 144, 21, 9, 198, 56, 85, 83, 81, 34, 65, 65, 8, 197, 52, 147, 143, 72, 144, 21, 8, 197, 48, 144, 133, 72, 144, 65, 8, 197, 24, 80, 130, 72, 80, 20, 8, 197, 21, 81, 133, 52, 144, 20, 9, 198, 20, 229, 18, 61, 2, 65, 67, 9, 198, 20, 211, 198, 36, 194, 65, 68, 8, 197, 16, 80, 143, 48, 80, 65, 6, 195, 9, 33, 78, 21, 8, 197, 8, 19, 19, 4, 208, 65, 8, 197, 5, 48, 197, 76, 144, 20, 8, 197, 4, 148, 143, 48, 80, 20, 8, 197, 4, 32, 129, 100, 80, 67, 0, 6, 195, 84, 244, 0, 20, 9, 198, 76, 20, 211, 60, 226, 64, 65, 9, 198, 72, 147, 131, 61, 66, 64, 20, 9, 198, 20, 224, 207, 49, 2, 64, 20, 9, 198, 8, 243, 129, 77, 51, 204, 67, 0, 6, 195, 64, 84, 212, 21, 6, 195, 37, 51, 204, 65, 10, 199, 20, 48, 197, 57, 68, 137, 12, 20, 0, 11, 200, 80, 244, 142, 5, 33, 67, 12, 144, 20, 11, 200, 72, 81, 133, 72, 83, 132, 84, 208, 20, 11, 200, 61, 4, 18, 36, 209, 78, 80, 80, 20, 6, 195, 49, 83, 199, 20, 7, 196, 21, 84, 133, 44, 65, 10, 198, 4, 65, 5, 8, 149, 0, 66, 21, 9, 198, 4, 52, 143, 8, 21, 0, 66, 0, 8, 197, 77, 97, 86, 36, 16, 20, 8, 197, 72, 85, 15, 72, 80, 65, 10, 198, 61, 35, 211, 12, 244, 0, 66, 20, 8, 197, 24, 244, 141, 36, 48, 66, 9, 198, 24, 21, 20, 61, 34, 65, 67, 8, 197, 21, 21, 73, 64, 80, 65, 8, 197, 16, 243, 143, 72, 144, 67, 12, 201, 12, 192, 86, 36, 49, 77, 8, 19, 0, 67, 8, 197, 4, 53, 76, 20, 240, 66, 0, 9, 198, 76, 20, 133, 77, 66, 64, 72, 9, 198, 105, 80, 195, 5, 34, 64, 65, 13, 202, 80, 145, 204, 5, 68, 9, 48, 84, 197, 72, 20, 6, 195, 76, 244, 201, 20, 9, 198, 64, 147, 69, 57, 65, 76, 67, 9, 198, 28, 148, 143, 77, 64, 84, 66, 9, 198, 9, 80, 195, 5, 34, 64, 65, 0, 10, 198, 64, 19, 13, 5, 33, 83, 67, 20, 10, 199, 60, 211, 218, 36, 115, 212, 20, 20, 10, 199, 52, 148, 129, 24, 147, 210, 36, 21, 10, 199, 36, 229, 18, 60, 67, 212, 80, 21, 6, 195, 21, 51, 196, 20, 0, 6, 195, 64, 243, 3, 20, 7, 196, 64, 193, 90, 104, 20, 7, 196, 48, 85, 67, 36, 65, 12, 201, 37, 3, 195, 48, 244, 137, 17, 34, 65, 69, 11, 200, 16, 83, 79, 13, 32, 90, 36, 16, 68, 11, 200, 12, 21, 20, 37, 97, 82, 36, 16, 67, 11, 200, 8, 21, 20, 36, 53, 79, 72, 80, 20, 11, 200, 4, 116, 143, 76, 148, 212, 20, 208, 20, 0, 6, 195, 80, 243, 6, 20, 9, 198, 65, 33, 78, 76, 147, 5, 20, 6, 195, 61, 1, 82, 21, 9, 198, 28, 21, 68, 20, 230, 137, 20, 9, 198, 12, 84, 129, 56, 84, 201, 66, 0, 6, 195, 76, 19, 5, 66, 9, 198, 36, 227, 143, 13, 83, 192, 20, 6, 195, 28, 147, 5, 66, 10, 198, 20, 211, 69, 57, 64, 76, 65, 20, 0, 6, 195, 81, 83, 192, 72, 6, 195, 80, 243, 4, 20, 10, 199, 60, 113, 201, 28, 147, 210, 56, 21, 6, 195, 37, 64, 76, 65, 10, 199, 24, 147, 129, 48, 35, 210, 28, 21, 10, 199, 8, 243, 129, 12, 243, 19, 36, 20, 0, 7, 196, 36, 228, 201, 80, 65, 7, 196, 4, 67, 210, 56, 21, 0, 9, 198, 56, 240, 195, 36, 243, 1, 66, 9, 198, 52, 20, 195, 32, 147, 5, 66, 6, 195, 48, 241, 26, 21, 0, 11, 70, 36, 229, 5, 72, 225, 84, 21, 0, 10, 11, 67, 21, 52, 197, 36, 89, 89, 36, 0, 76, 6, 195, 64, 244, 5, 20, 6, 195, 17, 83, 205, 20, 10, 198, 12, 243, 135, 73, 83, 192, 65, 20, 0, 10, 199, 76, 16, 210, 36, 193, 71, 36, 20, 10, 199, 16, 241, 9, 12, 84, 201, 52, 20, 0, 6, 195, 80, 245, 15, 66, 6, 195, 80, 245, 15, 20, 7, 196, 44, 22, 65, 44, 66, 8, 196, 21, 69, 1, 72, 65, 20, 0, 9, 198, 64, 192, 83, 52, 241, 9, 20, 8, 197, 12, 147, 212, 60, 192, 65, 9, 198, 12, 19, 12, 36, 244, 5, 66, 8, 197, 9, 80, 195, 36, 224, 65, 0, 11, 67, 21, 52, 193, 36, 89, 89, 35, 0, 76, 9, 198, 88, 83, 149, 77, 64, 64, 67, 9, 198, 72, 17, 206, 5, 65, 76, 21, 10, 198, 48, 147, 65, 77, 51, 204, 67, 21, 13, 202, 21, 48, 67, 37, 51, 212, 80, 17, 68, 72, 20, 9, 198, 16, 148, 195, 5, 2, 84, 66, 0, 10, 199, 65, 35, 211, 21, 36, 9, 56, 66, 10, 199, 28, 19, 66, 4, 51, 210, 80, 21, 6, 195, 21, 52, 192, 21, 10, 199, 12, 243, 73, 56, 99, 210, 52, 67, 6, 195, 5, 51, 204, 65, 0, 7, 196, 24, 244, 212, 36, 72, 7, 196, 80, 85, 67, 72, 65, 7, 196, 48, 241, 204, 36, 20, 7, 196, 12, 244, 212, 4, 66, 0, 9, 198, 88, 19, 7, 60, 115, 9, 20, 8, 197, 52, 84, 195, 4, 192, 66, 8, 197, 16, 243, 13, 20, 224, 20, 8, 197, 12, 243, 135, 20, 64, 20, 0, 10, 198, 60, 211, 137, 9, 84, 192, 65, 20, 9, 198, 56, 81, 210, 37, 64, 64, 67, 9, 198, 12, 244, 148, 37, 51, 204, 67, 0, 15, 67, 93, 117, 192, 6, 84, 40, 6, 84, 40, 6, 84, 40, 0, 10, 199, 52, 243, 148, 61, 33, 129, 56, 66, 10, 199, 8, 192, 83, 80, 244, 15, 72, 66, 10, 199, 4, 116, 137, 24, 241, 204, 36, 20, 0, 7, 196, 80, 81, 207, 48, 65, 9, 198, 65, 35, 199, 21, 69, 0, 20, 9, 198, 64, 19, 131, 21, 69, 0, 21, 7, 196, 56, 241, 77, 36, 20, 7, 196, 28, 147, 210, 56, 21, 0, 8, 197, 53, 84, 212, 21, 32, 66, 9, 198, 48, 240, 193, 48, 149, 1, 68, 9, 198, 24, 147, 1, 72, 85, 5, 20, 9, 198, 12, 19, 3, 5, 33, 69, 66, 0, 11, 67, 21, 52, 201, 36, 89, 89, 37, 0, 76, 9, 198, 80, 84, 211, 21, 33, 64, 20, 9, 198, 56, 84, 212, 61, 33, 64, 65, 6, 195, 16, 245, 5, 20, 10, 198, 12, 80, 210, 61, 1, 64, 65, 20, 0, 12, 201, 36, 226, 78, 80, 84, 146, 61, 69, 0, 21, 6, 195, 21, 51, 208, 20, 10, 199, 12, 243, 12, 20, 195, 206, 28, 20, 0, 7, 196, 24, 244, 211, 20, 72, 11, 200, 52, 243, 148, 20, 97, 76, 81, 32, 21, 0, 8, 197, 76, 81, 213, 37, 64, 65, 8, 197, 64, 243, 4, 21, 32, 20, 9, 198, 61, 69, 15, 80, 148, 9, 66, 8, 197, 56, 148, 16, 85, 32, 66, 8, 197, 48, 85, 20, 21, 32, 20, 8, 197, 28, 19, 66, 5, 32, 65, 9, 197, 16, 84, 208, 61, 64, 65, 20, 0, 5, 194, 88, 240, 20, 6, 195, 60, 145, 9, 66, 9, 198, 48, 16, 200, 21, 65, 64, 20, 0, 11, 199, 29, 35, 211, 76, 243, 79, 16, 67, 20, 12, 201, 25, 32, 78, 12, 144, 67, 61, 37, 0, 21, 0, 7, 196, 76, 144, 84, 20, 72, 7, 196, 64, 17, 201, 56, 65, 11, 200, 24, 83, 137, 12, 245, 20, 21, 32, 20, 11, 200, 8, 19, 5, 56, 245, 20, 21, 32, 20, 7, 196, 5, 52, 18, 36, 66, 0, 8, 197, 24, 16, 197, 88, 16, 76, 6, 195, 88, 245, 0, 20, 8, 197, 76, 147, 148, 60, 208, 65, 8, 197, 72, 22, 154, 36, 16, 66, 8, 197, 64, 22, 154, 36, 16, 66, 9, 198, 52, 84, 137, 77, 65, 77, 20, 8, 197, 52, 20, 133, 52, 208, 21, 8, 197, 36, 212, 1, 72, 144, 65, 8, 197, 5, 3, 210, 36, 16, 67, 0, 6, 195, 64, 241, 9, 20, 9, 198, 64, 18, 12, 5, 98, 64, 65, 9, 198, 9, 33, 83, 4, 243, 0, 66, 0, 9, 198, 76, 20, 146, 60, 50, 0, 66, 9, 198, 5, 85, 5, 57, 66, 67, 20, 9, 198, 5, 85, 5, 57, 66, 67, 20, 0, 7, 196, 24, 244, 212, 20, 72, 9, 198, 76, 19, 79, 76, 21, 0, 66, 11, 200, 56, 147, 134, 60, 208, 78, 36, 16, 68, 7, 196, 36, 224, 213, 8, 65, 7, 196, 21, 53, 5, 72, 65, 9, 198, 4, 192, 193, 57, 64, 82, 66, 0, 9, 197, 12, 243, 148, 72, 240, 76, 28, 9, 197, 76, 51, 210, 104, 80, 66, 20, 8, 197, 72, 81, 9, 56, 144, 65, 9, 198, 60, 211, 212, 61, 2, 65, 68, 9, 197, 53, 81, 199, 36, 240, 66, 20, 8, 197, 28, 197, 84, 20, 240, 65, 8, 197, 28, 149, 82, 36, 16, 66, 9, 198, 24, 243, 7, 5, 34, 65, 67, 8, 197, 20, 113, 82, 36, 16, 66, 9, 198, 9, 83, 7, 5, 34, 65, 67, 8, 197, 4, 97, 143, 72, 144, 65, 8, 197, 4, 50, 5, 56, 144, 20, 0, 9, 198, 76, 147, 133, 17, 34, 64, 20, 9, 198, 9, 83, 7, 5, 34, 64, 65, 9, 198, 4, 84, 143, 77, 64, 84, 66, 0, 15, 203, 52, 243, 143, 12, 245, 9, 48, 81, 15, 56, 144, 69, 20, 10, 199, 4, 52, 85, 20, 67, 212, 80, 21, 0, 11, 200, 77, 68, 129, 56, 117, 82, 36, 16, 67, 11, 200, 52, 243, 148, 21, 97, 82, 16, 144, 21, 11, 200, 52, 243, 66, 5, 35, 195, 12, 144, 20, 7, 195, 44, 20, 15, 66, 20, 11, 200, 13, 80, 149, 49, 65, 82, 36, 16, 67, 11, 200, 4, 115, 210, 4, 99, 194, 36, 16, 69, 11, 200, 4, 34, 79, 81, 35, 198, 36, 16, 69, 0, 6, 195, 85, 65, 82, 65, 6, 195, 52, 85, 18, 21, 10, 198, 36, 83, 80, 76, 19, 5, 65, 20, 8, 197, 4, 64, 77, 5, 48, 67, 0, 0, 15, 204, 56, 85, 82, 61, 4, 201, 12, 130, 65, 81, 34, 65, 70, 14, 203, 36, 195, 21, 52, 147, 143, 80, 80, 206, 36, 48, 20, 0, 7, 196, 21, 53, 5, 80, 20, 7, 196, 5, 53, 1, 80, 65, 9, 198, 5, 32, 71, 61, 53, 0, 21, 0, 8, 197, 52, 17, 18, 5, 48, 66, 9, 198, 4, 65, 82, 8, 19, 5, 66, 0, 9, 198, 72, 144, 83, 76, 85, 20, 20, 0, 10, 199, 88, 19, 12, 20, 51, 210, 76, 21, 10, 199, 24, 147, 1, 57, 68, 143, 64, 66, 0, 7, 196, 76, 145, 86, 20, 20, 0, 8, 197, 77, 1, 67, 60, 192, 20, 12, 201, 76, 245, 20, 61, 4, 143, 16, 245, 20, 21, 8, 197, 24, 20, 195, 36, 224, 65, 8, 197, 12, 20, 195, 36, 224, 65, 8, 197, 8, 20, 142, 4, 32, 65, 8, 197, 4, 192, 207, 60, 192, 65, 0, 9, 198, 88, 80, 195, 32, 144, 64, 20, 9, 198, 81, 84, 131, 32, 144, 64, 66, 9, 198, 80, 85, 20, 60, 144, 64, 21, 9, 198, 72, 244, 193, 48, 144, 64, 67, 9, 198, 52, 19, 16, 20, 228, 192, 21, 9, 198, 24, 244, 195, 32, 144, 64, 66, 9, 198, 12, 240, 195, 32, 144, 64, 20, 9, 198, 12, 20, 137, 61, 66, 80, 67, 9, 198, 4, 48, 193, 16, 144, 64, 67, 9, 198, 4, 32, 129, 16, 144, 64, 67, 0, 6, 195, 76, 144, 64, 72, 10, 135, 2, 5, 14, 3, 8, 195, 168, 8, 10, 199, 65, 35, 208, 72, 145, 84, 4, 68, 12, 201, 65, 35, 195, 20, 66, 77, 20, 229, 0, 20, 0, 8, 196, 56, 81, 204, 36, 72, 28, 11, 200, 52, 243, 148, 21, 161, 77, 60, 192, 20, 9, 198, 16, 144, 80, 5, 51, 206, 66, 7, 196, 12, 244, 212, 36, 66, 9, 198, 4, 32, 129, 56, 67, 206, 21, 0, 8, 197, 76, 20, 147, 36, 224, 65, 8, 197, 52, 19, 135, 4, 224, 65, 12, 201, 4, 229, 15, 56, 243, 65, 76, 144, 64, 68, 0, 9, 198, 72, 244, 207, 48, 144, 64, 67, 9, 198, 64, 193, 83, 80, 144, 64, 65, 13, 202, 64, 145, 90, 60, 83, 5, 81, 68, 137, 12, 20, 0, 10, 198, 76, 179, 208, 20, 195, 211, 65, 21, 6, 195, 20, 209, 64, 20, 11, 199, 8, 83, 22, 20, 65, 82, 20, 67, 21, 0, 7, 196, 72, 81, 207, 48, 65, 7, 196, 64, 17, 207, 16, 20, 12, 200, 52, 243, 148, 20, 209, 83, 60, 192, 67, 20, 7, 196, 52, 241, 207, 48, 66, 9, 198, 16, 144, 76, 21, 69, 0, 20, 6, 195, 12, 145, 67, 20, 7, 196, 4, 228, 201, 4, 65, 7, 196, 4, 115, 211, 80, 21, 0, 9, 197, 104, 81, 134, 37, 32, 65, 20, 12, 201, 21, 51, 211, 12, 129, 76, 21, 68, 128, 67, 6, 195, 4, 209, 66, 20, 0, 9, 198, 21, 49, 81, 84, 145, 64, 20, 9, 198, 12, 240, 195, 36, 113, 64, 20, 0, 6, 195, 64, 241, 64, 20, 0, 7, 196, 76, 17, 207, 52, 65, 0, 8, 197, 88, 84, 148, 61, 96, 65, 8, 197, 80, 81, 84, 21, 64, 20, 8, 197, 80, 19, 129, 29, 32, 65, 8, 197, 48, 22, 154, 5, 32, 65, 12, 201, 24, 243, 148, 4, 225, 76, 36, 49, 64, 21, 8, 197, 20, 209, 82, 37, 64, 66, 9, 198, 12, 243, 3, 32, 145, 5, 20, 0, 9, 198, 88, 84, 142, 36, 49, 64, 66, 6, 195, 80, 243, 73, 20, 9, 198, 12, 244, 142, 36, 49, 64, 66, 9, 198, 4, 229, 9, 56, 241, 64, 66, 0, 10, 199, 81, 32, 77, 60, 113, 201, 4, 20, 12, 201, 24, 243, 148, 4, 226, 71, 61, 33, 0, 21, 9, 198, 12, 19, 3, 5, 33, 79, 66, 0, 7, 196, 73, 81, 137, 56, 65, 9, 198, 64, 19, 148, 4, 195, 206, 67, 7, 196, 52, 241, 207, 72, 65, 7, 196, 8, 21, 76, 20, 67, 0, 8, 197, 36, 229, 133, 12, 80, 8, 8, 197, 81, 83, 137, 76, 144, 65, 8, 197, 73, 81, 134, 36, 16, 66, 8, 197, 65, 35, 210, 60, 112, 65, 8, 197, 61, 32, 77, 4, 144, 67, 8, 197, 56, 147, 137, 88, 80, 65, 9, 198, 37, 51, 212, 72, 244, 0, 66, 8, 197, 12, 130, 83, 76, 16, 66, 8, 197, 5, 32, 197, 56, 80, 65, 10, 198, 4, 48, 68, 20, 210, 65, 67, 20, 0, 10, 135, 16, 5, 18, 3, 8, 195, 169, 8, 9, 198, 81, 33, 77, 21, 166, 128, 20, 9, 198, 80, 243, 13, 21, 166, 128, 20, 0, 6, 195, 64, 244, 16, 21, 11, 200, 28, 84, 211, 61, 0, 76, 20, 224, 21, 10, 199, 12, 243, 5, 61, 69, 5, 72, 20, 0, 7, 196, 76, 49, 76, 80, 21, 8, 196, 61, 101, 133, 72, 66, 21, 9, 198, 52, 20, 133, 52, 245, 0, 20, 10, 198, 36, 229, 143, 49, 80, 210, 66, 20, 7, 195, 20, 209, 83, 65, 20, 0, 8, 197, 84, 243, 73, 56, 144, 65, 9, 198, 76, 83, 5, 84, 50, 65, 66, 8, 197, 4, 52, 85, 20, 240, 65, 8, 197, 4, 32, 90, 36, 16, 67, 0, 6, 195, 16, 243, 65, 20, 6, 195, 4, 195, 197, 20, 0, 0, 12, 200, 52, 144, 210, 60, 225, 83, 36, 16, 67, 20, 11, 200, 36, 224, 213, 73, 50, 79, 56, 80, 20, 11, 200, 28, 83, 195, 20, 229, 18, 36, 48, 20, 11, 200, 12, 243, 131, 20, 229, 18, 36, 48, 20, 0, 0, 6, 195, 80, 243, 69, 66, 9, 198, 28, 84, 143, 48, 19, 64, 66, 13, 202, 12, 20, 212, 72, 245, 137, 48, 192, 82, 36, 67, 9, 198, 4, 208, 76, 28, 19, 64, 66, 0, 6, 195, 21, 67, 128, 20, 9, 198, 5, 32, 200, 36, 195, 195, 66, 7, 195, 4, 195, 192, 66, 20, 0, 7, 196, 24, 244, 211, 36, 72, 9, 198, 80, 85, 18, 4, 81, 18, 20, 0, 0, 9, 198, 76, 20, 129, 56, 227, 192, 72, 9, 198, 64, 243, 9, 24, 83, 64, 20, 9, 198, 52, 16, 193, 16, 19, 64, 67, 0, 6, 195, 20, 196, 192, 21, 6, 195, 20, 67, 204, 20, 9, 198, 4, 229, 8, 20, 210, 83, 65, 0, 7, 196, 64, 145, 86, 20, 20, 0, 9, 198, 8, 20, 149, 52, 147, 137, 66, 0, 9, 198, 81, 32, 78, 88, 144, 64, 66, 9, 198, 72, 81, 193, 48, 144, 64, 67, 9, 198, 36, 224, 197, 57, 68, 128, 20, 9, 198, 21, 161, 67, 32, 144, 64, 67, 0, 9, 198, 88, 147, 204, 4, 49, 79, 67, 10, 199, 76, 49, 71, 48, 145, 82, 20, 65, 10, 199, 5, 34, 83, 80, 17, 207, 72, 67, 0, 8, 196, 80, 145, 210, 20, 66, 20, 0, 12, 201, 76, 51, 210, 12, 144, 84, 60, 144, 64, 21, 9, 198, 4, 48, 213, 52, 243, 9, 66, 0, 9, 198, 52, 83, 15, 16, 144, 64, 67, 9, 198, 4, 227, 211, 52, 144, 64, 67, 9, 198, 4, 192, 149, 56, 80, 64, 66, 0, 10, 199, 72, 148, 18, 37, 53, 9, 56, 66, 10, 199, 64, 80, 197, 56, 81, 200, 36, 20, 10, 199, 36, 225, 197, 28, 225, 82, 20, 67, 6, 195, 20, 213, 64, 66, 10, 199, 12, 83, 148, 60, 48, 200, 36, 20, 0, 9, 198, 12, 149, 20, 4, 227, 214, 20, 0, 8, 197, 24, 84, 133, 81, 32, 65, 12, 201, 12, 148, 212, 36, 97, 76, 48, 80, 64, 67, 8, 197, 8, 20, 129, 81, 32, 65, 0, 0, 0, 0, 9, 198, 88, 147, 204, 4, 49, 69, 67, 0, 9, 198, 76, 85, 20, 36, 209, 64, 65, 9, 198, 76, 52, 143, 24, 243, 0, 65, 6, 195, 64, 241, 77, 20, 9, 198, 56, 240, 195, 36, 243, 0, 20, 9, 198, 25, 32, 84, 80, 83, 80, 20, 10, 198, 12, 21, 5, 12, 243, 0, 67, 20, 9, 198, 4, 84, 143, 28, 83, 0, 67, 0, 10, 199, 64, 84, 146, 20, 112, 85, 96, 66, 9, 198, 36, 68, 143, 12, 244, 147, 21, 10, 199, 4, 224, 83, 80, 20, 201, 4, 67, 0, 7, 196, 76, 145, 84, 20, 72, 9, 198, 36, 225, 15, 52, 149, 0, 66, 9, 198, 21, 49, 82, 12, 149, 0, 66, 7, 196, 12, 245, 80, 20, 67, 9, 198, 8, 144, 84, 32, 195, 206, 65, 0, 8, 197, 24, 16, 195, 36, 240, 76, 9, 198, 88, 148, 201, 28, 245, 9, 20, 8, 197, 80, 80, 206, 36, 48, 20, 8, 197, 72, 148, 15, 48, 144, 65, 8, 197, 64, 144, 206, 36, 48, 66, 8, 197, 61, 35, 211, 20, 144, 67, 9, 197, 8, 84, 143, 36, 16, 65, 21, 8, 197, 8, 16, 200, 20, 48, 20, 8, 197, 5, 161, 71, 48, 144, 20, 0, 9, 198, 81, 32, 77, 21, 166, 128, 20, 9, 198, 64, 20, 146, 36, 50, 68, 67, 9, 198, 48, 19, 149, 76, 82, 64, 67, 9, 198, 5, 32, 193, 56, 113, 76, 66, 0, 10, 199, 12, 129, 76, 36, 49, 82, 36, 66, 0, 11, 200, 76, 245, 20, 61, 33, 9, 56, 80, 21, 12, 201, 76, 51, 5, 72, 241, 5, 72, 210, 65, 68, 9, 198, 72, 80, 193, 64, 149, 0, 66, 11, 200, 52, 243, 69, 57, 64, 78, 20, 240, 67, 11, 200, 37, 53, 1, 57, 64, 78, 20, 240, 67, 0, 8, 197, 48, 83, 206, 104, 144, 20, 9, 198, 4, 192, 200, 36, 210, 65, 66, 0, 9, 198, 72, 243, 65, 28, 227, 204, 67, 9, 198, 12, 243, 12, 20, 114, 64, 20, 0, 6, 195, 64, 241, 84, 20, 11, 199, 20, 212, 5, 16, 240, 204, 20, 66, 20, 10, 199, 12, 20, 193, 80, 145, 76, 48, 21, 0, 9, 198, 77, 64, 82, 61, 53, 0, 65, 11, 200, 72, 83, 1, 80, 149, 137, 80, 16, 69, 11, 200, 64, 148, 143, 80, 80, 206, 36, 48, 20, 11, 200, 52, 81, 193, 21, 51, 198, 4, 112, 68, 12, 200, 24, 244, 211, 4, 49, 83, 36, 16, 67, 20, 11, 200, 20, 115, 195, 20, 229, 18, 36, 48, 20, 0, 6, 18, 66, 195, 160, 0, 195, 178, 0, 195, 179, 0, 195, 185, 0, 97, 0, 111, 0, 117, 0, 7, 6, 18, 67, 195, 169, 0, 195, 168, 0, 101, 0, 7, 6, 195, 160, 0, 3, 7, 35, 0, 117, 3, 7, 35, 2, 40, 0, 111, 2, 32, 24, 3, 7, 114, 0, 105, 2, 25, 3, 7, 117, 0, 7, 6, 97, 0, 4, 1, 21, 2, 98, 105, 108, 101, 32, 3, 6, 35, 0, 1, 21, 2, 103, 103, 105, 110, 101, 32, 0, 2, 116, 116, 101, 114, 17, 65, 32, 0, 118, 97, 110, 111, 1, 21, 2, 32, 14, 128, 128, 133, 3, 6, 35, 84, 35, 50, 39, 0, 4, 1, 21, 2, 99, 17, 65, 32, 3, 8, 35, 0, 1, 21, 2, 99, 104, 101, 32, 0, 4, 3, 35, 0, 1, 17, 67, 21, 2, 32, 14, 128, 192, 129, 0, 1, 105, 21, 2, 32, 14, 128, 192, 129, 0, 2, 105, 115, 109, 111, 32, 0, 2, 105, 115, 116, 17, 65, 32, 0, 117, 3, 35, 2, 40, 0, 111, 2, 32, 24, 3, 114, 0, 4, 101, 8, 2, 114, 3, 117, 0, 105, 2, 25, 0, 7, 6, 98, 0, 3, 71, 0, 98, 3, 71, 12, 0, 7, 6, 99, 0, 111, 1, 21, 2, 108, 17, 65, 32, 3, 8, 49, 39, 0, 4, 3, 49, 0, 104, 0, 4, 99, 3, 49, 12, 0, 99, 104, 0, 4, 2, 17, 71, 3, 76, 0, 2, 39, 0, 105, 2, 17, 65, 0, 4, 99, 2, 17, 71, 3, 76, 12, 0, 99, 105, 2, 17, 65, 0, 7, 6, 100, 0, 101, 114, 101, 1, 110, 3, 8, 72, 36, 51, 36, 0, 3, 72, 0, 100, 3, 72, 12, 0, 7, 6, 101, 0, 4, 1, 21, 2, 115, 105, 109, 111, 32, 3, 6, 36, 0, 1, 21, 2, 118, 111, 108, 17, 65, 32, 0, 2, 109, 111, 110, 17, 65, 32, 0, 4, 1, 17, 65, 2, 114, 32, 3, 6, 109, 0, 1, 21, 2, 114, 114, 105, 109, 111, 32, 0, 1, 21, 2, 99, 105, 32, 3, 8, 36, 0, 4, 1, 17, 67, 2, 114, 101, 32, 3, 8, 109, 0, 1, 17, 67, 11, 2, 114, 17, 65, 32, 0, 4, 3, 36, 0, 1, 17, 67, 21, 2, 32, 14, 128, 192, 129, 0, 1, 102, 2, 114, 109, 0, 1, 104, 2, 115, 115, 0, 1, 109, 2, 115, 115, 0, 1, 109, 21, 2, 110, 116, 17, 65, 32, 0, 1, 114, 17, 65, 21, 2, 32, 0, 2, 110, 103, 17, 65, 32, 0, 2, 114, 115, 105, 32, 24, 0, 2, 115, 115, 97, 32, 0, 2, 116, 116, 17, 65, 32, 0, 2, 122, 122, 17, 65, 32, 0, 8, 17, 67, 115, 2, 115, 115, 0, 4, 1, 99, 2, 116, 116, 17, 65, 32, 3, 109, 0, 1, 103, 2, 110, 101, 0, 1, 103, 103, 2, 114, 111, 32, 0, 1, 114, 2, 109, 0, 2, 17, 65, 0, 2, 17, 67, 11, 17, 65, 32, 0, 2, 17, 67, 32, 0, 2, 17, 67, 105, 17, 67, 17, 65, 32, 0, 2, 17, 67, 117, 108, 17, 65, 32, 0, 2, 108, 0, 2, 108, 108, 117, 0, 2, 110, 17, 65, 32, 0, 2, 110, 17, 67, 17, 65, 32, 0, 2, 114, 0, 2, 115, 116, 0, 2, 116, 105, 0, 2, 116, 114, 0, 2, 116, 116, 105, 21, 0, 2, 118, 105, 32, 0, 2, 118, 111, 32, 0, 2, 122, 17, 65, 0, 8, 114, 0, 105, 2, 25, 3, 109, 57, 0, 7, 6, 102, 0, 4, 1, 17, 65, 2, 101, 114, 111, 32, 3, 8, 83, 0, 1, 17, 65, 21, 2, 105, 108, 111, 32, 0, 3, 83, 0, 7, 6, 103, 0, 103, 101, 114, 1, 21, 2, 108, 111, 32, 3, 8, 75, 12, 36, 51, 0, 4, 108, 2, 105, 3, 61, 0, 108, 2, 195, 172, 0, 108, 105, 2, 17, 65, 0, 110, 3, 67, 0, 4, 2, 17, 71, 3, 75, 0, 105, 1, 110, 2, 97, 32, 0, 105, 2, 17, 65, 0, 4, 105, 2, 97, 32, 3, 75, 6, 125, 0, 195, 172, 2, 97, 32, 0, 4, 103, 2, 17, 71, 3, 75, 12, 0, 103, 105, 2, 17, 65, 0, 4, 3, 81, 0, 104, 0, 103, 3, 81, 12, 0, 108, 8, 3, 81, 55, 0, 117, 2, 17, 65, 3, 81, 58, 0, 7, 6, 104, 0, 3, 0, 4, 97, 8, 3, 107, 6, 35, 0, 195, 160, 8, 0, 7, 6, 105, 0, 4, 1, 108, 2, 17, 65, 3, 2, 37, 0, 1, 114, 2, 17, 65, 0, 4, 1, 21, 2, 98, 105, 108, 101, 32, 3, 6, 37, 0, 1, 21, 2, 100, 101, 114, 101, 32, 0, 2, 97, 99, 17, 65, 32, 0, 2, 97, 115, 105, 32, 0, 2, 103, 101, 110, 17, 65, 32, 0, 4, 97, 1, 29, 2, 32, 3, 6, 37, 35, 0, 97, 1, 102, 97, 2, 32, 0, 97, 1, 110, 111, 102, 2, 32, 0, 97, 1, 112, 111, 99, 115, 2, 32, 0, 97, 1, 114, 101, 2, 32, 0, 97, 1, 114, 111, 103, 2, 32, 0, 97, 1, 114, 116, 101, 109, 2, 32, 0, 97, 1, 116, 2, 32, 0, 110, 97, 115, 2, 32, 3, 6, 37, 50, 35, 89, 0, 115, 115, 101, 114, 111, 1, 21, 2, 32, 14, 128, 128, 134, 3, 6, 37, 89, 89, 36, 34, 39, 0, 115, 115, 105, 109, 97, 1, 21, 2, 32, 14, 128, 128, 134, 3, 6, 37, 89, 89, 37, 65, 35, 0, 115, 115, 105, 109, 101, 1, 21, 2, 32, 14, 128, 128, 134, 3, 6, 37, 89, 89, 37, 65, 36, 0, 115, 115, 105, 109, 105, 1, 21, 2, 32, 14, 128, 128, 134, 3, 6, 37, 89, 89, 37, 65, 37, 0, 115, 115, 105, 109, 111, 1, 21, 2, 32, 14, 128, 128, 134, 3, 6, 37, 89, 89, 37, 65, 39, 0, 4, 1, 21, 2, 99, 17, 65, 32, 3, 8, 37, 0, 1, 21, 2, 99, 104, 17, 65, 32, 0, 1, 21, 2, 100, 17, 65, 32, 0, 1, 21, 2, 103, 17, 65, 32, 0, 1, 21, 2, 109, 97, 32, 0, 1, 21, 2, 109, 111, 32, 0, 1, 98, 2, 108, 101, 32, 0, 1, 99, 2, 108, 17, 65, 32, 0, 1, 103, 2, 108, 17, 65, 32, 0, 1, 109, 2, 108, 101, 32, 0, 1, 112, 2, 116, 101, 32, 0, 1, 114, 17, 67, 97, 108, 2, 109, 97, 32, 0, 1, 115, 115, 2, 108, 17, 65, 32, 0, 2, 108, 17, 65, 32, 0, 2, 110, 101, 32, 0, 97, 1, 21, 2, 32, 3, 8, 37, 2, 35, 0, 111, 1, 21, 2, 32, 14, 128, 192, 129, 3, 8, 37, 2, 39, 0, 4, 3, 37, 0, 1, 17, 67, 21, 2, 32, 14, 128, 192, 129, 0, 1, 21, 2, 17, 65, 110, 116, 101, 32, 0, 1, 114, 2, 109, 97, 32, 0, 1, 114, 116, 2, 99, 101, 32, 0, 1, 116, 115, 2, 109, 97, 32, 0, 1, 122, 110, 101, 2, 109, 97, 32, 0, 2, 111, 0, 2, 195, 178, 0, 2, 195, 179, 0, 8, 17, 67, 2, 97, 0, 8, 17, 67, 2, 195, 160, 0, 195, 160, 1, 21, 2, 32, 3, 37, 6, 35, 0, 4, 101, 1, 21, 2, 114, 17, 65, 32, 3, 37, 6, 109, 0, 195, 168, 1, 21, 2, 114, 17, 65, 32, 0, 195, 169, 1, 21, 2, 114, 17, 65, 32, 0, 4, 1, 18, 67, 2, 12, 3, 57, 0, 1, 97, 2, 12, 0, 1, 111, 2, 12, 0, 1, 160, 195, 2, 12, 0, 2, 17, 65, 0, 7, 6, 106, 0, 3, 57, 0, 7, 6, 107, 0, 3, 49, 0, 107, 3, 49, 12, 0, 7, 6, 108, 0, 4, 3, 55, 0, 108, 2, 32, 0, 108, 2, 17, 67, 3, 55, 10, 0, 7, 6, 109, 0, 3, 65, 0, 105, 1, 17, 65, 2, 97, 32, 3, 65, 6, 37, 0, 7, 6, 110, 0, 4, 3, 50, 0, 2, 103, 17, 71, 0, 4, 2, 103, 3, 68, 0, 2, 107, 0, 7, 6, 111, 0, 4, 1, 21, 2, 103, 110, 111, 108, 111, 32, 3, 6, 39, 0, 1, 21, 2, 110, 122, 111, 108, 111, 32, 0, 4, 1, 21, 2, 102, 111, 110, 111, 32, 3, 6, 110, 0, 1, 21, 2, 103, 114, 97, 102, 111, 32, 0, 1, 21, 2, 108, 111, 103, 111, 32, 0, 1, 21, 2, 109, 101, 116, 114, 111, 32, 0, 1, 21, 2, 110, 111, 109, 111, 32, 0, 1, 108, 2, 103, 105, 99, 111, 32, 0, 2, 103, 101, 110, 17, 65, 32, 0, 2, 112, 111, 108, 17, 65, 32, 0, 2, 115, 116, 114, 97, 99, 17, 65, 32, 0, 4, 1, 21, 2, 100, 105, 32, 3, 8, 39, 0, 1, 21, 2, 100, 111, 32, 0, 1, 114, 100, 2, 109, 111, 32, 0, 1, 118, 2, 108, 17, 65, 32, 0, 4, 1, 17, 67, 17, 67, 2, 108, 17, 65, 32, 3, 8, 110, 0, 1, 21, 2, 108, 111, 32, 0, 1, 100, 110, 2, 108, 17, 65, 32, 0, 1, 105, 99, 2, 108, 17, 65, 32, 0, 1, 115, 110, 2, 108, 17, 65, 32, 0, 4, 3, 39, 0, 1, 17, 67, 21, 2, 32, 14, 128, 192, 129, 0, 1, 99, 115, 2, 108, 116, 17, 65, 32, 0, 1, 102, 2, 114, 109, 17, 65, 32, 0, 1, 105, 2, 110, 101, 0, 1, 105, 2, 115, 111, 32, 0, 1, 105, 21, 2, 32, 14, 128, 192, 129, 0, 1, 114, 17, 65, 2, 115, 115, 17, 65, 32, 0, 2, 110, 105, 32, 0, 2, 114, 101, 32, 0, 105, 2, 111, 32, 3, 39, 2, 126, 0, 105, 2, 115, 17, 67, 17, 65, 32, 3, 39, 6, 37, 0, 4, 1, 21, 2, 108, 97, 32, 3, 110, 0, 1, 21, 2, 108, 105, 17, 65, 32, 0, 1, 21, 2, 109, 97, 32, 0, 1, 21, 2, 109, 111, 32, 0, 1, 99, 2, 108, 116, 17, 65, 32, 0, 1, 99, 115, 2, 112, 0, 1, 105, 0, 1, 105, 2, 108, 17, 65, 32, 0, 1, 109, 2, 98, 105, 108, 101, 0, 1, 110, 103, 2, 108, 97, 32, 0, 1, 117, 2, 108, 17, 65, 32, 0, 1, 118, 2, 108, 116, 0, 2, 17, 67, 11, 17, 65, 32, 0, 2, 17, 67, 17, 65, 17, 67, 17, 65, 32, 0, 2, 17, 67, 17, 67, 32, 0, 2, 17, 67, 114, 0, 2, 99, 97, 32, 0, 2, 99, 111, 32, 0, 2, 108, 29, 0, 2, 108, 105, 0, 2, 110, 105, 0, 2, 110, 111, 32, 0, 2, 111, 0, 2, 114, 0, 2, 115, 105, 32, 0, 2, 115, 115, 0, 2, 115, 116, 0, 2, 116, 116, 111, 108, 0, 2, 122, 17, 65, 0, 105, 3, 110, 2, 126, 0, 7, 6, 112, 0, 1, 109, 21, 2, 101, 114, 101, 32, 3, 8, 48, 0, 3, 48, 0, 112, 3, 48, 12, 0, 110, 8, 2, 21, 21, 3, 50, 0, 115, 8, 2, 17, 65, 21, 3, 89, 0, 7, 6, 113, 0, 4, 3, 49, 122, 0, 117, 0, 7, 6, 114, 0, 4, 3, 14, 16, 0, 1, 17, 67, 0, 8, 0, 1, 17, 65, 2, 17, 65, 3, 51, 0, 114, 3, 51, 16, 0, 7, 6, 115, 0, 1, 17, 65, 2, 17, 65, 3, 88, 0, 105, 97, 1, 21, 3, 88, 6, 37, 35, 0, 105, 195, 160, 1, 21, 3, 88, 37, 6, 35, 0, 4, 3, 89, 0, 1, 21, 2, 32, 14, 128, 128, 129, 0, 1, 107, 0, 1, 108, 0, 1, 112, 0, 2, 99, 0, 2, 102, 0, 2, 107, 0, 2, 112, 0, 2, 113, 0, 2, 116, 0, 2, 120, 0, 8, 0, 105, 97, 1, 17, 67, 21, 3, 89, 6, 37, 35, 0, 99, 104, 2, 17, 71, 3, 89, 49, 0, 115, 3, 89, 89, 0, 4, 99, 2, 17, 71, 3, 91, 0, 99, 105, 2, 17, 65, 0, 104, 1, 25, 0, 104, 2, 25, 0, 4, 99, 105, 2, 105, 3, 91, 2, 37, 0, 99, 105, 2, 195, 172, 0, 7, 6, 116, 0, 3, 47, 0, 116, 3, 47, 12, 0, 7, 6, 117, 0, 4, 1, 21, 2, 99, 111, 108, 111, 32, 3, 6, 40, 0, 1, 21, 2, 100, 105, 110, 101, 32, 0, 2, 105, 116, 111, 32, 0, 1, 21, 2, 108, 17, 65, 32, 3, 8, 40, 0, 4, 3, 40, 0, 1, 108, 25, 2, 17, 65, 0, 1, 114, 25, 2, 17, 65, 0, 2, 17, 65, 3, 122, 0, 7, 6, 118, 0, 3, 84, 0, 7, 6, 119, 0, 3, 122, 0, 7, 6, 120, 0, 3, 49, 89, 0, 7, 6, 121, 0, 2, 25, 3, 37, 0, 3, 57, 0, 7, 6, 122, 0, 4, 2, 18, 66, 17, 65, 3, 72, 88, 0, 8, 2, 105, 0, 8, 2, 195, 172, 0, 3, 123, 0, 122, 1, 17, 65, 3, 123, 12, 0, 7, 6, 0, 33, 1, 19, 3, 0, 195, 169, 3, 7, 36, 0, 195, 172, 3, 7, 37, 0, 195, 179, 3, 7, 39, 0, 195, 179, 105, 3, 7, 39, 126, 0, 195, 185, 3, 7, 40, 0, 195, 168, 3, 7, 109, 0, 195, 168, 105, 2, 25, 3, 7, 109, 57, 0, 195, 178, 3, 7, 110, 0, 195, 178, 105, 3, 7, 110, 126, 0, 195, 169, 105, 2, 25, 3, 7, 118, 0, 4, 45, 1, 32, 17, 65, 2, 32, 15, 3, 10, 0, 45, 1, 32, 17, 67, 2, 32, 15, 0, 33, 3, 10, 48, 6, 40, 50, 47, 39, 36, 89, 49, 55, 35, 65, 35, 47, 6, 37, 84, 39, 10, 0, 45, 8, 32, 2, 32, 15, 3, 65, 36, 50, 39, 0, 36, 3, 72, 39, 55, 55, 35, 34, 39, 0, 44, 2, 15, 3, 84, 6, 37, 34, 81, 39, 55, 35, 0, 194, 167, 3, 89, 36, 123, 37, 6, 39, 50, 36, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts29 = FileInMemory_createWithData (43392, reinterpret_cast (&espeakdata_dicts29_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/it_dict", U"it"); Collection_addItem (me.peek(), espeakdata_dicts29.transfer()); static unsigned char espeakdata_dicts30_data[2058] = { 0, 4, 0, 0, 84, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 8, 71, 13, 0, 0, 0, 0, 0, 6, 65, 12, 91, 13, 0, 0, 0, 0, 0, 6, 65, 16, 72, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 24, 83, 13, 0, 0, 0, 0, 0, 6, 65, 28, 81, 13, 0, 0, 0, 0, 0, 10, 65, 32, 13, 107, 6, 13, 71, 40, 0, 0, 0, 0, 0, 7, 65, 36, 37, 9, 0, 72, 0, 0, 0, 0, 6, 65, 40, 90, 13, 0, 0, 0, 0, 0, 6, 65, 44, 49, 13, 0, 0, 0, 0, 0, 6, 65, 48, 55, 13, 0, 0, 0, 0, 0, 6, 65, 52, 65, 13, 0, 0, 0, 0, 0, 6, 65, 56, 50, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 64, 48, 13, 0, 0, 0, 0, 0, 9, 65, 68, 49, 6, 13, 71, 40, 0, 0, 0, 0, 0, 6, 65, 72, 51, 13, 0, 0, 0, 0, 0, 6, 65, 76, 89, 13, 0, 0, 0, 0, 0, 6, 65, 80, 47, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 88, 84, 13, 0, 0, 0, 0, 0, 9, 65, 92, 84, 6, 13, 71, 40, 0, 0, 0, 0, 0, 6, 65, 96, 101, 13, 0, 0, 0, 0, 0, 8, 65, 100, 6, 13, 71, 40, 0, 0, 0, 0, 0, 6, 65, 104, 88, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 3, 21, 39, 9, 91, 6, 40, 107, 37, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 95, 4, 16, 20, 48, 37, 10, 0, 0, 0, 0, 0, 0, 7, 132, 16, 15, 39, 5, 76, 0, 0, 0, 0, 7, 132, 26, 15, 39, 5, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 16, 15, 39, 21, 27, 48, 39, 107, 40, 0, 72, 0, 0, 0, 0, 13, 4, 14, 15, 39, 21, 27, 50, 39, 107, 40, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 69, 36, 163, 206, 4, 144, 27, 37, 90, 39, 50, 6, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 69, 36, 161, 78, 4, 144, 27, 37, 90, 36, 50, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 10, 1, 39, 1, 90, 6, 35, 107, 35, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 66, 45, 80, 49, 40, 24, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 66, 56, 16, 50, 6, 35, 11, 0, 0, 10, 67, 8, 242, 64, 71, 112, 24, 0, 72, 0, 0, 0, 0, 10, 67, 44, 82, 64, 49, 111, 24, 0, 72, 10, 67, 56, 242, 64, 27, 50, 112, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 67, 36, 160, 64, 27, 37, 90, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 67, 36, 161, 64, 27, 37, 90, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 68, 36, 224, 74, 4, 27, 37, 50, 35, 90, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 18, 21, 39, 5, 51, 6, 40, 107, 36, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 5, 9, 10, 5, 39, 9, 27, 37, 90, 36, 107, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 131, 5, 39, 15, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 67, 64, 82, 64, 48, 6, 111, 11, 0, 0, 0, 0, 0, 10, 67, 28, 242, 64, 27, 81, 112, 0, 72, 10, 67, 56, 18, 64, 50, 6, 110, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 67, 36, 163, 192, 27, 37, 90, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 67, 88, 21, 64, 84, 108, 24, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 2, 95, 1, 35, 71, 40, 0, 0, 0, 0, 0, 8, 2, 95, 5, 36, 71, 40, 0, 0, 0, 0, 8, 2, 95, 9, 37, 71, 40, 0, 0, 0, 8, 2, 95, 15, 39, 71, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 2, 95, 21, 40, 71, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 95, 51, 91, 37, 0, 0, 7, 2, 95, 50, 51, 36, 0, 0, 7, 2, 95, 49, 48, 35, 0, 0, 7, 2, 95, 48, 50, 39, 0, 0, 7, 2, 95, 55, 88, 36, 0, 0, 7, 2, 95, 54, 101, 35, 0, 0, 7, 2, 95, 53, 65, 40, 0, 0, 7, 2, 95, 52, 84, 39, 0, 0, 0, 0, 7, 2, 95, 57, 89, 39, 0, 0, 7, 2, 95, 56, 71, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 69, 36, 160, 78, 4, 144, 27, 37, 90, 35, 50, 6, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 66, 80, 240, 24, 47, 39, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 67, 80, 242, 64, 47, 112, 24, 0, 72, 10, 67, 76, 18, 64, 89, 6, 110, 11, 0, 10, 67, 12, 18, 64, 91, 6, 110, 11, 0, 0, 0, 0, 0, 10, 67, 64, 242, 64, 27, 48, 112, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 97, 0, 1, 29, 2, 32, 3, 4, 35, 0, 117, 1, 29, 2, 32, 3, 4, 108, 0, 105, 1, 29, 2, 32, 3, 4, 110, 0, 3, 35, 0, 117, 3, 108, 0, 105, 3, 110, 0, 7, 6, 98, 0, 3, 71, 0, 2, 17, 67, 3, 71, 10, 0, 7, 6, 99, 0, 3, 91, 0, 1, 25, 2, 17, 67, 3, 91, 11, 0, 7, 6, 100, 0, 3, 72, 0, 106, 3, 75, 0, 7, 6, 101, 0, 1, 29, 2, 32, 3, 4, 36, 0, 105, 1, 29, 2, 32, 3, 4, 111, 0, 3, 36, 0, 105, 3, 111, 0, 7, 6, 102, 0, 3, 83, 0, 7, 6, 103, 0, 105, 8, 2, 39, 17, 65, 32, 3, 27, 81, 37, 0, 3, 81, 0, 7, 6, 104, 0, 3, 107, 0, 7, 6, 105, 0, 1, 29, 2, 32, 3, 4, 37, 0, 1, 29, 2, 17, 65, 32, 3, 4, 57, 0, 3, 37, 0, 2, 17, 65, 3, 57, 0, 7, 6, 106, 0, 3, 90, 0, 7, 6, 107, 0, 3, 49, 0, 7, 6, 108, 0, 3, 45, 0, 4, 1, 17, 65, 3, 55, 0, 2, 17, 65, 0, 7, 6, 109, 0, 3, 65, 0, 7, 6, 110, 0, 3, 42, 0, 4, 1, 17, 65, 3, 50, 0, 2, 17, 65, 0, 4, 2, 103, 3, 68, 0, 2, 107, 0, 7, 6, 111, 0, 1, 29, 2, 32, 3, 4, 39, 0, 105, 1, 29, 2, 32, 3, 4, 112, 0, 3, 39, 0, 105, 3, 112, 0, 7, 6, 112, 0, 3, 48, 0, 7, 6, 113, 0, 3, 49, 58, 0, 7, 6, 114, 0, 3, 44, 0, 4, 1, 17, 65, 3, 51, 0, 2, 17, 65, 0, 2, 17, 67, 3, 51, 10, 0, 7, 6, 115, 0, 3, 89, 0, 7, 6, 116, 0, 3, 47, 0, 99, 3, 76, 0, 7, 6, 117, 0, 1, 29, 2, 32, 3, 4, 40, 0, 1, 29, 2, 17, 65, 32, 3, 4, 58, 0, 3, 40, 0, 2, 17, 65, 3, 58, 0, 7, 6, 118, 0, 3, 84, 0, 7, 6, 119, 0, 3, 58, 0, 7, 6, 120, 0, 3, 101, 0, 7, 6, 121, 0, 3, 13, 0, 7, 6, 122, 0, 3, 88, 0, 7, 6, 0, 203, 136, 3, 6, 0, 39, 8, 2, 32, 3, 6, 13, 107, 13, 0, 4, 46, 3, 11, 0, 46, 2, 32, 14, 128, 128, 129, 0, 46, 8, 2, 21, 14, 128, 132, 129, 0, 39, 3, 107, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts30 = FileInMemory_createWithData (2057, reinterpret_cast (&espeakdata_dicts30_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/jbo_dict", U"jbo"); Collection_addItem (me.peek(), espeakdata_dicts30.transfer()); static unsigned char espeakdata_dicts31_data[3163] = { 0, 4, 0, 0, 158, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 1, 33, 111, 6, 35, 101, 37, 55, 37, 89, 15, 50, 4, 37, 91, 35, 50, 37, 0, 0, 0, 12, 1, 35, 50, 6, 39, 65, 36, 34, 37, 0, 27, 0, 0, 13, 1, 37, 48, 34, 39, 109, 36, 50, 47, 37, 0, 27, 0, 6, 1, 38, 72, 35, 0, 0, 0, 0, 0, 16, 1, 42, 84, 35, 34, 84, 89, 49, 84, 55, 35, 84, 37, 0, 27, 0, 11, 1, 43, 48, 55, 37, 40, 89, 37, 0, 27, 0, 0, 0, 11, 1, 46, 112, 36, 34, 47, 37, 55, 37, 0, 0, 29, 1, 47, 65, 6, 35, 34, 109, 101, 50, 37, 84, 15, 72, 6, 35, 101, 34, 37, 55, 37, 15, 101, 6, 35, 88, 37, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 5, 95, 48, 1, 14, 4, 72, 2, 35, 0, 0, 0, 0, 0, 0, 11, 1, 61, 47, 39, 55, 39, 71, 35, 0, 27, 0, 0, 0, 11, 1, 64, 111, 35, 100, 55, 40, 49, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 95, 48, 67, 48, 35, 89, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 1, 92, 65, 6, 35, 34, 75, 84, 50, 37, 84, 15, 72, 6, 35, 101, 34, 37, 55, 37, 15, 101, 6, 35, 88, 37, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 134, 225, 131, 147, 225, 131, 144, 72, 28, 0, 0, 12, 4, 95, 50, 67, 48, 39, 34, 35, 89, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 4, 16, 20, 65, 25, 36, 55, 37, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 3, 225, 131, 156, 50, 6, 13, 0, 0, 7, 3, 225, 131, 157, 39, 0, 0, 9, 3, 225, 131, 158, 48, 6, 13, 0, 0, 9, 3, 225, 131, 159, 90, 6, 13, 0, 0, 7, 3, 225, 131, 152, 37, 0, 0, 9, 3, 225, 131, 153, 49, 6, 13, 0, 0, 9, 3, 225, 131, 154, 55, 6, 13, 0, 0, 9, 3, 225, 131, 155, 65, 6, 13, 0, 0, 0, 9, 3, 225, 131, 149, 84, 6, 13, 0, 0, 9, 3, 225, 131, 150, 88, 6, 13, 0, 16, 5, 95, 48, 77, 50, 24, 65, 6, 37, 55, 37, 39, 50, 37, 0, 0, 9, 3, 225, 131, 151, 25, 6, 13, 0, 0, 7, 3, 225, 131, 144, 35, 0, 0, 9, 3, 225, 131, 145, 71, 6, 13, 0, 0, 9, 3, 225, 131, 146, 81, 6, 13, 0, 0, 9, 3, 225, 131, 147, 72, 6, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 5, 95, 48, 77, 49, 24, 6, 35, 25, 35, 89, 37, 0, 0, 0, 11, 3, 225, 131, 184, 36, 55, 37, 83, 37, 0, 0, 0, 0, 9, 3, 225, 131, 181, 107, 39, 36, 0, 0, 9, 3, 225, 131, 180, 107, 35, 34, 0, 0, 10, 3, 225, 131, 183, 89, 107, 84, 35, 0, 0, 8, 3, 225, 131, 182, 83, 37, 0, 0, 8, 3, 225, 131, 177, 107, 36, 0, 0, 9, 3, 225, 131, 176, 107, 6, 13, 0, 0, 9, 3, 225, 131, 179, 84, 37, 36, 0, 13, 4, 95, 51, 67, 48, 89, 35, 65, 35, 89, 37, 0, 0, 9, 3, 225, 131, 178, 107, 37, 36, 0, 0, 9, 3, 225, 131, 173, 80, 6, 13, 0, 0, 9, 3, 225, 131, 172, 112, 6, 13, 0, 0, 9, 3, 225, 131, 175, 75, 6, 13, 0, 0, 9, 3, 225, 131, 174, 101, 6, 13, 0, 0, 9, 3, 225, 131, 169, 76, 6, 13, 0, 0, 9, 3, 225, 131, 168, 91, 6, 13, 0, 0, 9, 3, 225, 131, 171, 111, 6, 13, 0, 0, 9, 3, 225, 131, 170, 109, 6, 13, 0, 0, 9, 3, 225, 131, 165, 110, 6, 13, 0, 0, 9, 3, 225, 131, 164, 108, 6, 13, 0, 0, 9, 3, 225, 131, 167, 104, 6, 13, 0, 0, 9, 3, 225, 131, 166, 100, 6, 13, 0, 0, 9, 3, 225, 131, 161, 89, 6, 13, 0, 0, 9, 3, 225, 131, 160, 34, 6, 13, 0, 0, 7, 3, 225, 131, 163, 40, 0, 7, 3, 225, 131, 163, 40, 0, 0, 9, 3, 225, 131, 162, 47, 6, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 52, 67, 48, 39, 47, 101, 35, 89, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 95, 50, 48, 6, 39, 109, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 6, 95, 18, 15, 13, 1, 14, 65, 6, 36, 89, 35, 65, 36, 0, 0, 0, 0, 0, 0, 0, 0, 20, 4, 95, 48, 90, 53, 65, 36, 6, 35, 89, 37, 35, 25, 35, 89, 36, 72, 37, 0, 13, 3, 95, 54, 48, 89, 6, 35, 65, 39, 112, 37, 0, 0, 20, 4, 95, 48, 90, 52, 65, 36, 6, 35, 25, 37, 35, 25, 35, 89, 36, 72, 37, 0, 8, 3, 95, 48, 67, 35, 89, 0, 0, 0, 19, 4, 95, 48, 90, 54, 65, 36, 65, 6, 37, 55, 37, 39, 50, 36, 72, 37, 0, 0, 15, 4, 95, 48, 90, 49, 65, 36, 6, 35, 25, 36, 72, 37, 0, 0, 0, 17, 4, 95, 48, 90, 51, 65, 36, 6, 35, 25, 35, 89, 36, 72, 37, 0, 0, 15, 4, 95, 48, 90, 50, 65, 36, 6, 35, 89, 36, 72, 37, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 53, 67, 48, 101, 6, 40, 25, 35, 89, 37, 0, 0, 0, 15, 3, 95, 49, 57, 109, 101, 34, 6, 35, 65, 36, 47, 37, 0, 0, 15, 3, 95, 49, 56, 25, 84, 34, 6, 35, 65, 36, 47, 37, 0, 0, 10, 3, 95, 50, 67, 39, 34, 35, 89, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 49, 49, 25, 6, 36, 34, 25, 65, 36, 47, 37, 0, 0, 10, 3, 95, 49, 48, 6, 35, 25, 37, 0, 0, 11, 3, 95, 51, 67, 89, 35, 65, 35, 89, 0, 13, 3, 95, 49, 51, 109, 6, 35, 65, 36, 47, 37, 0, 0, 14, 3, 95, 49, 50, 25, 6, 39, 34, 65, 36, 47, 37, 0, 0, 15, 3, 95, 49, 53, 25, 101, 6, 40, 25, 65, 36, 47, 37, 0, 0, 15, 3, 95, 49, 52, 25, 6, 39, 25, 101, 65, 36, 47, 37, 0, 0, 15, 3, 95, 49, 55, 76, 84, 6, 37, 72, 65, 36, 47, 37, 0, 0, 16, 3, 95, 49, 54, 25, 6, 36, 110, 84, 89, 65, 36, 47, 37, 0, 0, 0, 0, 11, 3, 95, 52, 67, 39, 47, 101, 35, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 53, 67, 101, 6, 40, 25, 35, 89, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 52, 48, 6, 39, 34, 65, 39, 112, 37, 0, 0, 13, 3, 95, 54, 67, 6, 36, 110, 84, 89, 35, 89, 0, 0, 0, 0, 0, 0, 0, 0, 9, 3, 95, 50, 88, 6, 39, 109, 0, 0, 13, 3, 95, 55, 67, 91, 84, 6, 37, 72, 35, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 56, 67, 34, 84, 35, 35, 89, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 52, 88, 6, 39, 34, 65, 39, 112, 0, 0, 13, 3, 95, 57, 67, 109, 101, 34, 6, 35, 35, 89, 0, 0, 0, 0, 0, 15, 4, 95, 54, 67, 48, 6, 36, 110, 84, 89, 35, 89, 37, 0, 0, 0, 0, 14, 3, 95, 56, 48, 6, 39, 25, 101, 65, 39, 112, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 54, 88, 89, 6, 35, 65, 39, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 56, 88, 6, 39, 25, 101, 65, 39, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 4, 95, 55, 67, 48, 91, 84, 6, 37, 72, 35, 89, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 48, 77, 50, 65, 6, 37, 55, 37, 39, 50, 0, 0, 0, 0, 12, 4, 95, 48, 77, 49, 6, 35, 25, 35, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 56, 67, 48, 34, 84, 35, 35, 89, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 67, 33, 69, 16, 6, 36, 57, 76, 47, 37, 47, 37, 48, 107, 37, 10, 0, 81, 58, 47, 47, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 4, 95, 57, 67, 48, 109, 101, 34, 6, 35, 35, 89, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 95, 225, 131, 148, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 2, 95, 34, 71, 34, 14, 80, 104, 35, 55, 37, 0, 0, 0, 0, 14, 2, 95, 39, 35, 48, 39, 89, 47, 34, 39, 83, 37, 0, 0, 0, 0, 0, 0, 0, 34, 2, 95, 41, 65, 6, 35, 34, 75, 84, 36, 50, 35, 15, 65, 34, 14, 81, 84, 6, 35, 55, 37, 15, 108, 34, 14, 76, 101, 6, 37, 55, 37, 0, 35, 2, 95, 41, 65, 6, 35, 34, 75, 84, 36, 50, 35, 15, 108, 6, 37, 81, 40, 34, 4, 40, 55, 37, 15, 108, 34, 14, 76, 101, 6, 37, 55, 37, 0, 0, 34, 2, 95, 40, 65, 6, 35, 34, 109, 101, 36, 50, 35, 15, 65, 34, 14, 81, 84, 6, 35, 55, 37, 15, 108, 34, 14, 76, 101, 6, 37, 55, 37, 0, 35, 2, 95, 40, 65, 6, 35, 34, 109, 101, 36, 50, 35, 15, 108, 6, 37, 81, 40, 34, 4, 40, 55, 37, 15, 108, 34, 14, 76, 101, 6, 37, 55, 37, 0, 0, 0, 0, 9, 2, 95, 45, 47, 37, 34, 36, 0, 0, 10, 2, 95, 44, 65, 111, 37, 65, 36, 0, 0, 10, 2, 95, 51, 89, 6, 35, 65, 37, 0, 0, 9, 2, 95, 50, 6, 39, 34, 37, 0, 0, 10, 2, 95, 49, 6, 36, 34, 25, 37, 0, 0, 10, 2, 95, 48, 50, 6, 40, 55, 37, 0, 0, 11, 2, 95, 55, 91, 84, 6, 37, 72, 37, 0, 0, 11, 2, 95, 54, 6, 36, 110, 84, 89, 37, 0, 0, 10, 2, 95, 53, 101, 6, 40, 25, 37, 0, 0, 10, 2, 95, 52, 6, 39, 25, 101, 37, 0, 0, 16, 2, 95, 59, 112, 36, 34, 47, 37, 55, 65, 111, 37, 65, 36, 0, 0, 14, 2, 95, 58, 39, 34, 112, 36, 34, 47, 37, 55, 37, 0, 0, 10, 2, 95, 57, 109, 101, 34, 6, 35, 0, 0, 9, 2, 95, 56, 34, 84, 6, 35, 0, 0, 21, 2, 95, 63, 49, 6, 37, 25, 101, 84, 37, 89, 15, 50, 4, 37, 91, 35, 50, 37, 0, 0, 11, 2, 95, 62, 65, 36, 47, 39, 71, 35, 0, 0, 0, 14, 2, 95, 60, 50, 35, 49, 55, 36, 71, 39, 71, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 2, 95, 91, 65, 6, 35, 34, 109, 101, 36, 50, 35, 15, 49, 84, 6, 35, 72, 34, 35, 47, 4, 40, 55, 37, 15, 108, 34, 14, 76, 101, 6, 37, 55, 37, 0, 0, 0, 0, 0, 0, 0, 35, 2, 95, 93, 65, 6, 35, 34, 75, 84, 36, 50, 35, 15, 108, 6, 37, 81, 40, 34, 4, 40, 55, 37, 15, 108, 34, 14, 76, 101, 6, 37, 55, 37, 0, 0, 0, 0, 0, 0, 21, 2, 95, 96, 40, 49, 40, 100, 65, 35, 15, 35, 48, 39, 89, 47, 34, 39, 83, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 1, 81, 0, 1, 45, 2, 32, 3, 2, 35, 0, 3, 35, 0, 7, 6, 1, 82, 0, 3, 71, 0, 7, 6, 1, 83, 0, 3, 81, 0, 7, 6, 1, 84, 0, 3, 72, 0, 7, 6, 1, 85, 0, 1, 45, 2, 32, 3, 2, 36, 0, 3, 36, 0, 7, 6, 1, 86, 0, 3, 84, 0, 7, 6, 1, 87, 0, 3, 88, 0, 7, 6, 1, 88, 0, 3, 25, 0, 7, 6, 1, 89, 0, 1, 45, 2, 32, 3, 2, 37, 0, 3, 37, 0, 7, 6, 1, 90, 0, 3, 49, 0, 7, 6, 1, 91, 0, 3, 55, 0, 7, 6, 1, 92, 0, 3, 65, 0, 7, 6, 1, 93, 0, 3, 50, 0, 7, 6, 1, 94, 0, 1, 45, 2, 32, 3, 2, 39, 0, 3, 39, 0, 7, 6, 1, 95, 0, 3, 48, 0, 7, 6, 1, 96, 0, 3, 90, 0, 7, 6, 1, 97, 0, 3, 34, 0, 1, 25, 2, 17, 67, 17, 67, 3, 34, 14, 0, 7, 6, 1, 98, 0, 3, 89, 0, 7, 6, 1, 99, 0, 3, 47, 0, 7, 6, 1, 100, 0, 1, 45, 2, 32, 3, 2, 40, 0, 3, 40, 0, 7, 6, 1, 101, 0, 3, 108, 0, 7, 6, 1, 102, 0, 3, 110, 0, 7, 6, 1, 103, 0, 3, 100, 0, 7, 6, 1, 104, 0, 3, 104, 0, 7, 6, 1, 105, 0, 3, 91, 0, 7, 6, 1, 106, 0, 3, 76, 0, 7, 6, 1, 107, 0, 3, 109, 0, 7, 6, 1, 108, 0, 3, 111, 0, 7, 6, 1, 109, 0, 3, 112, 0, 7, 6, 1, 110, 0, 3, 80, 0, 7, 6, 1, 111, 0, 3, 101, 0, 7, 6, 1, 112, 0, 3, 75, 0, 7, 6, 1, 113, 0, 3, 107, 0, 7, 6, 1, 114, 0, 3, 36, 57, 0, 7, 6, 1, 115, 0, 3, 57, 0, 7, 6, 1, 116, 0, 3, 58, 0, 7, 6, 1, 117, 0, 3, 101, 0, 7, 6, 1, 118, 0, 3, 39, 12, 0, 7, 6, 1, 119, 0, 3, 83, 0, 7, 6, 1, 120, 0, 3, 13, 0, 7, 6, 1, 121, 0, 3, 19, 0, 7, 6, 1, 122, 0, 3, 0, 7, 6, 1, 123, 0, 3, 0, 7, 6, 208, 0, 3, 21, 114, 117, 0, 7, 6, 209, 0, 3, 21, 114, 117, 0, 7, 6, 210, 0, 3, 21, 114, 117, 0, 7, 6, 211, 0, 3, 21, 114, 117, 0, 7, 6, 0, 36, 3, 72, 39, 55, 35, 34, 37, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts31 = FileInMemory_createWithData (3162, reinterpret_cast (&espeakdata_dicts31_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/ka_dict", U"ka"); Collection_addItem (me.peek(), espeakdata_dicts31.transfer()); static unsigned char espeakdata_dicts32_data[2024] = { 0, 4, 0, 0, 132, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 4, 16, 20, 10, 71, 4, 110, 47, 108, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 4, 95, 48, 90, 53, 90, 6, 110, 88, 15, 65, 4, 109, 68, 50, 112, 50, 0, 11, 3, 95, 51, 88, 6, 39, 47, 109, 88, 0, 0, 18, 4, 95, 48, 90, 52, 6, 39, 50, 15, 65, 4, 109, 68, 50, 112, 50, 0, 10, 3, 95, 48, 67, 90, 6, 110, 88, 0, 0, 22, 4, 95, 48, 90, 55, 6, 39, 50, 15, 65, 37, 55, 55, 37, 4, 39, 50, 50, 112, 50, 0, 0, 18, 4, 95, 48, 90, 54, 65, 37, 55, 55, 37, 6, 39, 50, 50, 112, 50, 0, 0, 13, 4, 95, 48, 90, 49, 6, 39, 50, 50, 112, 50, 0, 0, 0, 14, 4, 95, 48, 90, 51, 65, 6, 109, 68, 50, 112, 50, 0, 0, 14, 4, 95, 48, 90, 50, 90, 6, 110, 88, 72, 36, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 4, 95, 48, 90, 57, 65, 37, 55, 55, 37, 6, 112, 34, 72, 47, 112, 50, 0, 0, 23, 4, 95, 48, 90, 56, 90, 6, 110, 88, 15, 65, 37, 55, 55, 37, 6, 39, 50, 50, 112, 50, 0, 0, 0, 0, 13, 3, 95, 55, 88, 90, 6, 36, 47, 48, 108, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 3, 95, 49, 88, 6, 39, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 50, 88, 90, 37, 6, 109, 34, 65, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 52, 88, 104, 6, 109, 34, 109, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 53, 88, 6, 36, 55, 38, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 54, 88, 6, 112, 55, 48, 109, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 56, 88, 89, 6, 36, 49, 89, 36, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 57, 88, 47, 6, 39, 104, 89, 112, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 4, 95, 48, 77, 50, 65, 37, 55, 55, 37, 6, 39, 50, 0, 0, 16, 4, 95, 48, 77, 51, 65, 37, 55, 55, 37, 6, 112, 34, 72, 0, 0, 0, 11, 4, 95, 48, 77, 49, 65, 6, 109, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 209, 135, 76, 36, 0, 0, 8, 2, 209, 134, 47, 89, 36, 0, 0, 7, 2, 209, 133, 106, 112, 0, 0, 7, 2, 209, 132, 114, 83, 0, 0, 0, 7, 2, 209, 130, 47, 36, 0, 0, 7, 2, 209, 129, 114, 89, 0, 0, 7, 2, 209, 128, 114, 34, 0, 0, 0, 0, 0, 15, 2, 209, 140, 90, 108, 68, 108, 91, 49, 36, 55, 108, 49, 0, 0, 0, 10, 2, 209, 138, 112, 57, 109, 34, 40, 0, 0, 8, 2, 209, 137, 91, 76, 35, 0, 0, 7, 2, 209, 136, 91, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 210, 147, 116, 36, 0, 0, 0, 0, 0, 7, 2, 95, 51, 110, 91, 0, 0, 9, 2, 95, 50, 36, 49, 6, 108, 0, 0, 9, 2, 95, 49, 71, 6, 108, 34, 0, 0, 9, 2, 95, 48, 50, 6, 115, 55, 0, 0, 11, 2, 95, 55, 90, 6, 36, 47, 6, 108, 0, 7, 2, 210, 155, 104, 112, 0, 0, 10, 2, 95, 54, 112, 55, 47, 6, 109, 0, 0, 9, 2, 95, 53, 71, 6, 36, 89, 0, 0, 10, 2, 95, 52, 47, 6, 115, 34, 47, 0, 0, 7, 2, 208, 183, 88, 36, 0, 0, 7, 2, 208, 182, 90, 36, 0, 0, 11, 2, 95, 57, 47, 39, 116, 6, 109, 88, 0, 0, 11, 2, 95, 56, 89, 36, 81, 6, 108, 88, 0, 7, 2, 208, 180, 72, 36, 0, 0, 7, 2, 210, 163, 114, 68, 0, 7, 2, 208, 179, 81, 36, 0, 0, 7, 2, 208, 178, 84, 36, 0, 0, 7, 2, 208, 177, 71, 36, 0, 0, 0, 7, 2, 208, 191, 48, 36, 0, 0, 0, 7, 2, 208, 189, 114, 50, 0, 0, 7, 2, 208, 188, 114, 65, 0, 0, 7, 2, 208, 187, 114, 55, 0, 0, 7, 2, 208, 186, 49, 112, 0, 0, 12, 2, 208, 185, 104, 109, 89, 104, 112, 6, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 210, 187, 107, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 1, 17, 0, 2, 208, 185, 3, 35, 0, 3, 112, 0, 7, 6, 1, 18, 0, 3, 71, 0, 7, 6, 1, 19, 0, 3, 84, 0, 7, 6, 1, 20, 0, 3, 81, 0, 7, 6, 1, 21, 0, 3, 72, 0, 7, 6, 1, 22, 0, 3, 36, 0, 7, 6, 1, 23, 0, 3, 90, 0, 7, 6, 1, 24, 0, 3, 88, 0, 7, 6, 1, 25, 0, 3, 37, 0, 7, 6, 1, 26, 0, 3, 57, 0, 7, 6, 1, 27, 0, 3, 49, 0, 7, 6, 1, 28, 0, 3, 55, 0, 7, 6, 1, 29, 0, 3, 65, 0, 7, 6, 1, 30, 0, 3, 50, 0, 7, 6, 1, 31, 0, 3, 39, 0, 7, 6, 1, 32, 0, 3, 48, 0, 7, 6, 1, 33, 0, 3, 34, 0, 7, 6, 1, 34, 0, 3, 89, 0, 7, 6, 1, 35, 0, 3, 47, 0, 7, 6, 1, 36, 0, 3, 40, 0, 4, 1, 17, 65, 3, 58, 0, 2, 17, 65, 0, 7, 6, 1, 37, 0, 3, 83, 0, 7, 6, 1, 38, 0, 3, 106, 0, 7, 6, 1, 39, 0, 3, 47, 89, 0, 7, 6, 1, 40, 0, 3, 76, 0, 7, 6, 1, 41, 0, 3, 91, 0, 7, 6, 1, 42, 0, 3, 91, 76, 0, 7, 6, 1, 44, 0, 3, 109, 0, 7, 6, 1, 46, 0, 3, 114, 0, 7, 6, 1, 47, 0, 3, 38, 40, 0, 7, 6, 1, 48, 0, 3, 38, 35, 0, 7, 6, 1, 50, 0, 3, 38, 39, 0, 7, 6, 1, 55, 0, 3, 108, 0, 7, 6, 1, 116, 0, 3, 116, 0, 7, 6, 1, 124, 0, 3, 104, 0, 7, 6, 210, 163, 0, 3, 68, 0, 7, 6, 210, 175, 0, 3, 110, 0, 7, 6, 210, 177, 0, 3, 111, 0, 7, 6, 210, 187, 0, 3, 107, 0, 7, 6, 211, 153, 0, 3, 113, 0, 7, 6, 211, 169, 0, 3, 115, 0, 7, 6, 0, 4, 209, 138, 3, 0, 209, 140, 3, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts32 = FileInMemory_createWithData (2023, reinterpret_cast (&espeakdata_dicts32_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/kk_dict", U"kk"); Collection_addItem (me.peek(), espeakdata_dicts32.transfer()); static unsigned char espeakdata_dicts33_data[1678] = { 0, 4, 0, 0, 44, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 8, 71, 36, 0, 0, 0, 0, 0, 6, 65, 12, 89, 36, 0, 0, 0, 0, 0, 6, 65, 16, 72, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 24, 36, 83, 0, 0, 0, 0, 0, 6, 65, 28, 81, 36, 0, 0, 0, 0, 0, 6, 65, 32, 107, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 40, 57, 36, 0, 0, 0, 0, 0, 6, 65, 44, 49, 35, 0, 0, 0, 0, 0, 6, 65, 48, 36, 55, 0, 0, 0, 0, 0, 6, 65, 52, 36, 65, 0, 0, 0, 0, 0, 6, 65, 56, 36, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 64, 48, 36, 0, 0, 0, 0, 0, 7, 65, 68, 104, 35, 12, 0, 0, 0, 0, 0, 6, 65, 72, 36, 34, 0, 0, 0, 0, 0, 6, 65, 76, 36, 89, 0, 0, 0, 0, 0, 6, 65, 80, 47, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 88, 84, 36, 0, 0, 0, 0, 0, 6, 65, 92, 58, 36, 0, 0, 0, 0, 0, 7, 65, 96, 37, 49, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 104, 88, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 95, 4, 16, 20, 49, 39, 65, 12, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 49, 48, 104, 6, 40, 37, 55, 37, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 2, 95, 51, 48, 6, 37, 68, 35, 89, 40, 47, 0, 0, 12, 2, 95, 50, 65, 6, 35, 34, 55, 40, 49, 0, 0, 13, 2, 95, 49, 35, 47, 6, 35, 12, 89, 36, 104, 0, 0, 11, 2, 95, 48, 50, 6, 40, 12, 55, 40, 0, 0, 19, 2, 95, 55, 35, 34, 83, 37, 50, 36, 104, 65, 6, 35, 34, 55, 40, 49, 0, 0, 15, 2, 95, 54, 35, 34, 83, 6, 37, 50, 37, 105, 37, 47, 0, 0, 13, 2, 95, 53, 47, 6, 35, 105, 37, 65, 35, 47, 0, 0, 13, 2, 95, 52, 89, 6, 37, 89, 35, 65, 35, 47, 0, 0, 0, 0, 16, 2, 95, 57, 104, 40, 55, 37, 68, 37, 55, 6, 40, 35, 47, 0, 0, 20, 2, 95, 56, 35, 34, 83, 37, 50, 36, 104, 48, 6, 37, 68, 35, 89, 40, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 165, 0, 3, 111, 0, 7, 6, 195, 166, 0, 3, 109, 0, 7, 6, 195, 184, 0, 3, 110, 0, 7, 6, 97, 0, 3, 35, 0, 97, 3, 35, 12, 0, 105, 2, 32, 3, 108, 0, 7, 6, 98, 0, 3, 71, 0, 7, 6, 99, 0, 3, 49, 0, 4, 2, 101, 3, 89, 0, 2, 105, 0, 7, 6, 100, 0, 3, 72, 0, 7, 6, 101, 0, 3, 36, 0, 101, 3, 36, 12, 0, 7, 6, 102, 0, 3, 83, 0, 102, 3, 83, 12, 0, 7, 6, 103, 0, 103, 3, 99, 12, 0, 3, 100, 0, 7, 6, 104, 0, 3, 107, 0, 104, 3, 107, 12, 0, 7, 6, 105, 0, 3, 37, 0, 105, 3, 37, 12, 0, 7, 6, 106, 0, 3, 57, 0, 106, 3, 57, 12, 0, 7, 6, 107, 0, 3, 49, 0, 107, 3, 49, 12, 0, 7, 6, 108, 0, 3, 55, 0, 108, 3, 105, 0, 7, 6, 109, 0, 3, 65, 0, 109, 3, 65, 12, 0, 7, 6, 110, 0, 3, 50, 0, 110, 3, 50, 12, 0, 103, 3, 68, 0, 110, 103, 3, 68, 12, 0, 7, 6, 111, 0, 3, 39, 0, 111, 3, 39, 12, 0, 7, 6, 112, 0, 3, 48, 0, 3, 48, 12, 0, 7, 6, 113, 0, 3, 104, 0, 113, 3, 104, 12, 0, 7, 6, 114, 0, 3, 34, 0, 114, 3, 106, 12, 0, 7, 6, 115, 0, 3, 89, 0, 115, 3, 89, 12, 0, 7, 6, 116, 0, 3, 47, 0, 116, 3, 47, 12, 0, 108, 3, 112, 0, 115, 3, 113, 0, 7, 6, 117, 0, 3, 40, 0, 117, 3, 40, 12, 0, 7, 6, 118, 0, 3, 84, 0, 118, 3, 84, 12, 0, 7, 6, 119, 0, 3, 58, 0, 7, 6, 120, 0, 3, 49, 89, 0, 7, 6, 121, 0, 1, 25, 2, 25, 3, 37, 0, 3, 57, 0, 7, 6, 122, 0, 3, 88, 0, 7, 6, 0, 36, 3, 72, 6, 39, 55, 35, 34, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts33 = FileInMemory_createWithData (1677, reinterpret_cast (&espeakdata_dicts33_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/kl_dict", U"kl"); Collection_addItem (me.peek(), espeakdata_dicts33.transfer()); static unsigned char espeakdata_dicts34_data[5368] = { 0, 4, 0, 0, 127, 17, 0, 0, 0, 0, 0, 0, 0, 6, 65, 4, 114, 57, 0, 0, 0, 0, 0, 6, 65, 8, 71, 112, 0, 0, 0, 0, 0, 6, 65, 12, 89, 112, 0, 0, 0, 0, 0, 6, 65, 16, 72, 112, 0, 0, 0, 11, 6, 224, 178, 149, 224, 179, 141, 37, 49, 0, 0, 0, 5, 65, 20, 112, 0, 0, 0, 0, 0, 6, 65, 24, 116, 83, 0, 0, 0, 0, 0, 6, 65, 28, 75, 112, 0, 0, 0, 0, 0, 6, 65, 32, 114, 76, 0, 0, 16, 1, 33, 118, 89, 144, 35, 34, 57, 35, 144, 37, 50, 107, 36, 0, 0, 0, 0, 6, 65, 36, 118, 57, 0, 0, 13, 1, 37, 48, 34, 35, 47, 37, 93, 35, 47, 35, 0, 0, 9, 1, 38, 65, 35, 47, 47, 40, 0, 0, 0, 7, 65, 40, 75, 114, 57, 0, 0, 0, 0, 0, 14, 1, 44, 35, 55, 48, 35, 84, 37, 34, 118, 65, 35, 0, 7, 65, 44, 49, 114, 57, 0, 0, 0, 15, 1, 46, 48, 123, 34, 66, 35, 84, 37, 34, 118, 65, 35, 0, 0, 0, 6, 65, 48, 116, 55, 0, 0, 13, 1, 49, 49, 118, 55, 40, 0, 82, 47, 32, 52, 32, 13, 1, 49, 35, 34, 139, 35, 0, 82, 47, 32, 50, 32, 0, 0, 16, 1, 51, 65, 40, 49, 49, 118, 55, 40, 0, 82, 47, 32, 52, 32, 0, 6, 65, 52, 116, 65, 0, 0, 0, 0, 0, 6, 65, 56, 116, 50, 0, 0, 0, 0, 0, 5, 65, 60, 119, 0, 0, 0, 0, 0, 6, 65, 64, 48, 112, 0, 0, 15, 140, 224, 178, 164, 224, 178, 174, 224, 179, 141, 224, 178, 174, 72, 0, 0, 0, 7, 65, 68, 49, 57, 123, 0, 0, 0, 0, 0, 15, 140, 224, 178, 135, 224, 178, 181, 224, 178, 168, 224, 179, 129, 72, 6, 65, 72, 118, 34, 0, 0, 0, 0, 0, 6, 65, 76, 116, 89, 0, 0, 0, 0, 12, 4, 95, 48, 67, 48, 50, 6, 123, 34, 40, 0, 0, 6, 65, 80, 138, 112, 0, 0, 0, 25, 149, 224, 178, 134, 224, 178, 166, 224, 178, 190, 224, 178, 151, 224, 179, 141, 224, 178, 175, 224, 179, 130, 72, 8, 0, 0, 6, 65, 84, 57, 123, 0, 0, 0, 0, 0, 6, 65, 88, 84, 112, 0, 0, 0, 0, 0, 11, 65, 92, 72, 35, 71, 35, 55, 57, 123, 0, 0, 0, 0, 0, 7, 65, 96, 116, 49, 89, 0, 0, 0, 0, 0, 7, 65, 100, 58, 118, 57, 0, 0, 0, 0, 0, 15, 140, 224, 178, 135, 224, 178, 181, 224, 178, 179, 224, 179, 129, 72, 7, 65, 104, 88, 116, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 140, 224, 178, 168, 224, 178, 168, 224, 179, 141, 224, 178, 168, 72, 0, 0, 0, 18, 143, 224, 178, 168, 224, 178, 191, 224, 178, 168, 224, 179, 141, 224, 178, 168, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 95, 49, 67, 48, 50, 123, 34, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 50, 67, 48, 6, 37, 50, 50, 123, 34, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 4, 95, 4, 16, 20, 10, 72, 6, 35, 93, 118, 65, 93, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 5, 95, 48, 77, 50, 24, 55, 6, 35, 49, 91, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 5, 95, 48, 77, 49, 24, 89, 6, 118, 84, 37, 34, 35, 0, 11, 6, 224, 178, 175, 224, 179, 141, 37, 57, 0, 0, 0, 0, 0, 11, 6, 224, 178, 173, 224, 179, 141, 37, 137, 0, 0, 0, 0, 0, 0, 0, 0, 15, 4, 95, 51, 67, 48, 65, 6, 40, 50, 50, 123, 34, 40, 0, 0, 0, 0, 0, 0, 11, 6, 224, 178, 179, 224, 179, 141, 37, 62, 0, 11, 6, 224, 178, 171, 224, 179, 141, 37, 136, 0, 0, 0, 0, 0, 11, 6, 224, 178, 177, 224, 179, 141, 37, 34, 0, 0, 0, 0, 0, 0, 0, 0, 12, 137, 224, 178, 133, 224, 178, 181, 224, 179, 129, 72, 0, 0, 0, 15, 140, 224, 178, 185, 224, 178, 178, 224, 178, 181, 224, 179, 129, 72, 15, 140, 224, 178, 164, 224, 178, 190, 224, 178, 181, 224, 179, 129, 72, 15, 140, 224, 178, 168, 224, 178, 190, 224, 178, 181, 224, 179, 129, 72, 0, 0, 11, 6, 224, 178, 159, 224, 179, 141, 37, 140, 0, 0, 18, 143, 224, 178, 149, 224, 179, 134, 224, 178, 178, 224, 178, 181, 224, 179, 129, 72, 0, 0, 0, 11, 6, 224, 178, 157, 224, 179, 141, 37, 145, 0, 0, 0, 15, 140, 224, 178, 133, 224, 178, 168, 224, 179, 135, 224, 178, 149, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 224, 178, 163, 224, 179, 141, 37, 66, 0, 11, 6, 224, 178, 155, 224, 179, 141, 37, 144, 0, 0, 0, 0, 0, 11, 6, 224, 178, 185, 224, 179, 141, 37, 107, 0, 11, 6, 224, 178, 161, 224, 179, 141, 37, 141, 0, 11, 6, 224, 178, 153, 224, 179, 141, 37, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 224, 178, 167, 224, 179, 141, 37, 141, 0, 0, 0, 0, 0, 12, 137, 224, 178, 133, 224, 178, 181, 224, 178, 176, 72, 11, 6, 224, 178, 165, 224, 179, 141, 37, 138, 0, 0, 12, 137, 224, 178, 133, 224, 178, 181, 224, 178, 179, 72, 0, 0, 0, 0, 0, 0, 0, 12, 137, 224, 178, 133, 224, 178, 181, 224, 178, 168, 72, 0, 0, 0, 18, 143, 224, 178, 135, 224, 178, 181, 224, 179, 129, 224, 178, 151, 224, 178, 179, 72, 18, 143, 224, 178, 133, 224, 178, 181, 224, 179, 129, 224, 178, 151, 224, 178, 179, 72, 0, 0, 0, 0, 0, 0, 15, 140, 224, 178, 168, 224, 178, 174, 224, 179, 141, 224, 178, 174, 72, 0, 0, 0, 18, 143, 224, 178, 168, 224, 178, 191, 224, 178, 174, 224, 179, 141, 224, 178, 174, 72, 0, 0, 0, 0, 0, 19, 3, 95, 51, 57, 65, 6, 39, 84, 35, 138, 39, 65, 71, 35, 138, 12, 40, 0, 18, 3, 95, 50, 49, 6, 113, 48, 12, 35, 6, 138, 12, 39, 50, 72, 40, 0, 0, 15, 140, 224, 178, 168, 224, 179, 128, 224, 178, 181, 224, 179, 129, 72, 16, 3, 95, 51, 56, 65, 6, 39, 84, 35, 138, 36, 50, 140, 40, 0, 0, 18, 3, 95, 50, 51, 113, 48, 12, 35, 6, 138, 12, 65, 6, 123, 34, 40, 0, 0, 18, 3, 95, 50, 50, 113, 48, 12, 35, 6, 138, 12, 36, 34, 35, 141, 40, 0, 11, 6, 224, 178, 183, 224, 179, 141, 37, 93, 0, 0, 17, 3, 95, 50, 53, 113, 48, 12, 35, 6, 138, 12, 6, 134, 72, 40, 0, 0, 15, 140, 224, 178, 133, 224, 178, 181, 224, 178, 179, 224, 179, 129, 72, 19, 3, 95, 50, 52, 113, 48, 12, 35, 6, 138, 12, 50, 6, 118, 55, 49, 40, 0, 0, 16, 3, 95, 50, 55, 113, 48, 12, 35, 6, 138, 12, 114, 62, 40, 0, 0, 16, 3, 95, 50, 54, 113, 48, 12, 35, 6, 138, 12, 118, 34, 40, 0, 11, 6, 224, 178, 181, 224, 179, 141, 37, 84, 0, 0, 17, 3, 95, 51, 49, 65, 6, 39, 84, 35, 138, 12, 39, 50, 72, 40, 0, 0, 0, 17, 3, 95, 51, 51, 65, 6, 39, 84, 35, 138, 65, 6, 123, 34, 40, 0, 0, 17, 3, 95, 51, 50, 65, 6, 39, 84, 35, 138, 36, 34, 35, 141, 40, 0, 0, 16, 3, 95, 51, 53, 65, 6, 39, 84, 35, 138, 6, 134, 72, 40, 0, 0, 18, 3, 95, 51, 52, 65, 6, 39, 84, 35, 138, 50, 6, 118, 55, 49, 40, 0, 0, 15, 3, 95, 51, 55, 65, 6, 39, 84, 35, 138, 114, 62, 40, 0, 0, 15, 3, 95, 51, 54, 65, 6, 39, 84, 35, 138, 118, 34, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 3, 95, 55, 57, 116, 48, 12, 35, 138, 39, 65, 71, 35, 138, 12, 40, 0, 17, 3, 95, 54, 49, 35, 34, 35, 84, 35, 138, 12, 39, 50, 72, 40, 0, 0, 15, 3, 95, 55, 56, 116, 48, 12, 35, 138, 36, 50, 140, 40, 0, 14, 3, 95, 51, 88, 65, 6, 39, 84, 35, 138, 12, 40, 0, 0, 11, 3, 95, 48, 67, 50, 6, 123, 34, 118, 0, 17, 3, 95, 54, 51, 35, 34, 35, 84, 35, 138, 65, 6, 123, 34, 40, 0, 0, 17, 3, 95, 54, 50, 35, 34, 35, 84, 35, 138, 36, 34, 35, 141, 40, 0, 0, 15, 3, 95, 54, 53, 35, 34, 35, 84, 35, 138, 134, 72, 40, 0, 0, 18, 3, 95, 54, 52, 35, 34, 35, 84, 35, 138, 50, 6, 118, 55, 49, 40, 0, 0, 15, 3, 95, 54, 55, 35, 34, 35, 84, 35, 138, 114, 62, 40, 0, 0, 15, 3, 95, 54, 54, 35, 34, 35, 84, 35, 138, 118, 34, 40, 0, 0, 16, 3, 95, 55, 49, 116, 48, 12, 35, 138, 12, 39, 50, 72, 40, 0, 0, 0, 10, 3, 95, 49, 67, 50, 123, 34, 118, 0, 16, 3, 95, 55, 51, 116, 48, 12, 35, 138, 65, 6, 123, 34, 40, 0, 0, 16, 3, 95, 55, 50, 116, 48, 12, 35, 138, 36, 34, 35, 141, 40, 0, 0, 14, 3, 95, 55, 53, 116, 48, 12, 35, 138, 134, 72, 40, 0, 0, 17, 3, 95, 55, 52, 116, 48, 12, 35, 138, 50, 6, 118, 55, 49, 40, 0, 0, 13, 4, 95, 53, 67, 48, 6, 134, 50, 123, 34, 40, 0, 14, 3, 95, 55, 55, 116, 48, 12, 35, 138, 114, 62, 40, 0, 0, 14, 3, 95, 55, 54, 116, 48, 12, 35, 138, 118, 34, 40, 0, 0, 19, 3, 95, 49, 57, 107, 35, 6, 138, 12, 6, 39, 65, 71, 35, 138, 12, 40, 0, 0, 16, 3, 95, 49, 56, 107, 35, 72, 37, 50, 6, 36, 50, 140, 40, 0, 0, 13, 3, 95, 50, 67, 6, 37, 50, 50, 123, 34, 118, 0, 0, 0, 0, 0, 0, 0, 20, 3, 95, 50, 57, 113, 48, 12, 35, 6, 138, 12, 39, 65, 71, 35, 138, 12, 40, 0, 15, 3, 95, 49, 49, 107, 35, 50, 50, 6, 39, 50, 72, 40, 0, 0, 17, 3, 95, 50, 56, 113, 48, 12, 35, 6, 138, 12, 36, 50, 140, 40, 0, 0, 14, 3, 95, 51, 67, 65, 6, 40, 50, 50, 123, 34, 118, 0, 15, 3, 95, 49, 51, 107, 35, 72, 37, 65, 6, 123, 34, 40, 0, 0, 15, 3, 95, 49, 50, 107, 35, 50, 12, 36, 34, 35, 141, 40, 0, 0, 14, 3, 95, 49, 53, 107, 35, 72, 37, 50, 134, 72, 40, 0, 0, 16, 3, 95, 49, 52, 107, 35, 72, 37, 50, 6, 118, 55, 49, 40, 0, 0, 15, 3, 95, 49, 55, 107, 35, 72, 37, 50, 6, 114, 62, 40, 0, 0, 14, 3, 95, 49, 54, 107, 35, 72, 37, 50, 118, 34, 40, 0, 0, 0, 14, 3, 95, 55, 88, 6, 116, 48, 12, 35, 138, 12, 40, 0, 0, 0, 0, 0, 0, 0, 0, 21, 3, 95, 52, 57, 50, 6, 35, 55, 35, 84, 35, 138, 39, 65, 71, 35, 138, 12, 40, 0, 0, 18, 3, 95, 52, 56, 50, 6, 35, 55, 35, 84, 35, 138, 36, 50, 140, 40, 0, 0, 12, 3, 95, 53, 67, 6, 134, 50, 123, 34, 118, 0, 0, 0, 0, 0, 0, 0, 17, 3, 95, 53, 57, 134, 84, 35, 138, 39, 65, 71, 35, 138, 12, 40, 0, 19, 3, 95, 52, 49, 50, 6, 35, 55, 35, 84, 35, 138, 12, 39, 50, 72, 40, 0, 0, 14, 3, 95, 53, 56, 134, 84, 35, 138, 36, 50, 140, 40, 0, 12, 3, 95, 49, 88, 107, 6, 35, 138, 12, 40, 0, 0, 19, 3, 95, 52, 51, 50, 6, 35, 55, 35, 84, 35, 138, 65, 6, 123, 34, 40, 0, 0, 19, 3, 95, 52, 50, 50, 6, 35, 55, 35, 84, 35, 138, 36, 34, 35, 141, 40, 0, 0, 17, 3, 95, 52, 53, 50, 6, 35, 55, 35, 84, 35, 138, 134, 72, 40, 0, 0, 20, 3, 95, 52, 52, 50, 6, 35, 55, 35, 84, 35, 138, 50, 6, 118, 55, 49, 40, 0, 0, 17, 3, 95, 52, 55, 50, 6, 35, 55, 35, 84, 35, 138, 114, 62, 40, 0, 0, 17, 3, 95, 52, 54, 50, 6, 35, 55, 35, 84, 35, 138, 118, 34, 40, 0, 0, 19, 3, 95, 54, 57, 35, 34, 35, 84, 35, 138, 39, 65, 71, 35, 138, 12, 40, 0, 15, 3, 95, 53, 49, 134, 84, 35, 138, 12, 39, 50, 72, 40, 0, 0, 16, 3, 95, 54, 56, 35, 34, 35, 84, 35, 138, 36, 50, 140, 40, 0, 13, 3, 95, 50, 88, 113, 48, 12, 35, 138, 12, 40, 0, 0, 15, 3, 95, 53, 51, 134, 84, 35, 138, 65, 6, 123, 34, 40, 0, 0, 15, 3, 95, 53, 50, 134, 84, 35, 138, 36, 34, 35, 141, 40, 0, 0, 14, 3, 95, 53, 53, 134, 84, 35, 138, 6, 134, 72, 40, 0, 0, 16, 3, 95, 53, 52, 134, 84, 35, 138, 50, 6, 118, 55, 49, 40, 0, 0, 13, 3, 95, 53, 55, 134, 84, 35, 138, 114, 62, 40, 0, 0, 13, 3, 95, 53, 54, 134, 84, 35, 138, 118, 34, 40, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 63, 63, 35, 49, 93, 35, 34, 35, 0, 0, 0, 18, 3, 95, 56, 57, 116, 65, 71, 35, 138, 39, 65, 71, 35, 138, 12, 40, 0, 0, 15, 3, 95, 56, 56, 116, 65, 71, 35, 138, 36, 50, 140, 40, 0, 16, 3, 95, 52, 88, 50, 6, 35, 55, 35, 84, 35, 138, 12, 40, 0, 0, 15, 3, 95, 57, 67, 39, 65, 71, 35, 37, 50, 123, 34, 118, 0, 0, 0, 0, 0, 0, 0, 20, 3, 95, 57, 57, 138, 6, 39, 65, 71, 35, 138, 39, 65, 71, 35, 138, 12, 40, 0, 16, 3, 95, 56, 49, 116, 65, 71, 35, 138, 12, 39, 50, 72, 40, 0, 0, 17, 3, 95, 57, 56, 138, 6, 39, 65, 71, 35, 138, 36, 50, 140, 40, 0, 13, 3, 95, 53, 88, 6, 134, 84, 35, 138, 12, 40, 0, 0, 16, 3, 95, 56, 51, 116, 65, 71, 35, 138, 65, 6, 123, 34, 40, 0, 0, 16, 3, 95, 56, 50, 116, 65, 71, 35, 138, 36, 34, 35, 141, 40, 0, 0, 14, 3, 95, 56, 53, 116, 65, 71, 35, 138, 134, 72, 40, 0, 0, 17, 3, 95, 56, 52, 116, 65, 71, 35, 138, 50, 6, 118, 55, 49, 40, 0, 0, 14, 3, 95, 56, 55, 116, 65, 71, 35, 138, 114, 62, 40, 0, 0, 14, 3, 95, 56, 54, 116, 65, 71, 35, 138, 118, 34, 40, 0, 0, 18, 3, 95, 57, 49, 138, 6, 39, 65, 71, 35, 138, 12, 39, 50, 72, 40, 0, 0, 15, 3, 95, 54, 88, 6, 35, 34, 35, 84, 35, 138, 12, 40, 0, 0, 18, 3, 95, 57, 51, 138, 6, 39, 65, 71, 35, 138, 65, 6, 123, 34, 40, 0, 0, 19, 3, 95, 57, 50, 138, 6, 39, 65, 71, 35, 138, 12, 36, 34, 35, 141, 40, 0, 0, 16, 3, 95, 57, 53, 138, 6, 39, 65, 71, 35, 138, 134, 72, 40, 0, 0, 19, 3, 95, 57, 52, 138, 6, 39, 65, 71, 35, 138, 50, 6, 118, 55, 49, 40, 0, 0, 12, 137, 224, 178, 135, 224, 178, 181, 224, 179, 129, 72, 16, 3, 95, 57, 55, 138, 6, 39, 65, 71, 35, 138, 114, 62, 40, 0, 0, 16, 3, 95, 57, 54, 138, 6, 39, 65, 71, 35, 138, 118, 34, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 224, 179, 158, 224, 179, 141, 37, 83, 0, 11, 6, 224, 178, 150, 224, 179, 141, 37, 146, 0, 0, 0, 14, 3, 95, 56, 88, 6, 116, 65, 71, 35, 138, 12, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 57, 88, 138, 6, 39, 65, 71, 35, 138, 12, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 137, 224, 178, 135, 224, 178, 181, 224, 178, 168, 72, 0, 0, 0, 0, 0, 0, 0, 0, 12, 137, 224, 178, 135, 224, 178, 181, 224, 178, 179, 72, 0, 12, 137, 224, 178, 135, 224, 178, 181, 224, 178, 176, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 48, 77, 52, 71, 6, 37, 55, 37, 39, 50, 0, 0, 0, 15, 4, 95, 48, 77, 50, 55, 6, 35, 49, 91, 35, 72, 35, 0, 0, 12, 4, 95, 48, 77, 51, 49, 6, 39, 140, 37, 0, 0, 0, 16, 4, 95, 48, 77, 49, 89, 6, 118, 84, 37, 34, 35, 72, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 131, 224, 178, 136, 76, 0, 0, 6, 131, 224, 178, 134, 76, 0, 0, 8, 3, 224, 179, 140, 148, 135, 0, 0, 11, 3, 224, 179, 141, 84, 35, 47, 47, 40, 0, 0, 8, 3, 224, 179, 138, 18, 39, 0, 8, 3, 224, 178, 130, 35, 65, 0, 0, 9, 3, 224, 179, 139, 148, 119, 12, 0, 8, 3, 224, 178, 131, 35, 107, 0, 0, 8, 3, 224, 179, 136, 148, 134, 0, 0, 0, 8, 3, 224, 179, 134, 18, 36, 0, 0, 9, 3, 224, 179, 135, 148, 114, 12, 0, 0, 9, 3, 224, 179, 132, 148, 44, 12, 0, 0, 0, 9, 3, 224, 179, 130, 148, 123, 12, 0, 0, 9, 3, 224, 179, 131, 18, 34, 40, 0, 0, 9, 3, 224, 179, 128, 148, 112, 12, 0, 0, 8, 3, 224, 179, 129, 18, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 140, 224, 178, 135, 224, 178, 181, 224, 178, 176, 224, 179, 129, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 67, 65, 101, 0, 48, 34, 134, 84, 35, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 3, 224, 178, 190, 148, 118, 12, 0, 0, 8, 3, 224, 178, 191, 18, 37, 0, 0, 21, 67, 33, 69, 16, 114, 76, 47, 112, 47, 112, 6, 48, 112, 10, 0, 81, 58, 47, 47, 32, 11, 3, 224, 178, 188, 50, 40, 49, 47, 35, 0, 0, 14, 3, 224, 178, 189, 35, 84, 35, 81, 34, 35, 107, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 4, 95, 57, 67, 48, 39, 65, 71, 35, 37, 50, 123, 34, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 2, 194, 190, 65, 40, 49, 49, 118, 55, 40, 0, 0, 13, 2, 195, 183, 137, 118, 81, 118, 49, 118, 34, 35, 0, 0, 9, 2, 194, 188, 49, 118, 55, 40, 0, 0, 9, 2, 194, 189, 35, 34, 139, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 224, 178, 136, 224, 178, 151, 72, 0, 0, 11, 6, 224, 178, 168, 224, 179, 141, 37, 50, 0, 0, 0, 0, 0, 11, 6, 224, 178, 174, 224, 179, 141, 37, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 224, 178, 172, 224, 179, 141, 37, 71, 0, 11, 6, 224, 178, 164, 224, 179, 141, 37, 47, 0, 0, 0, 0, 0, 11, 6, 224, 178, 178, 224, 179, 141, 37, 55, 0, 11, 6, 224, 178, 170, 224, 179, 141, 37, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 224, 178, 184, 224, 179, 141, 37, 89, 0, 11, 6, 224, 178, 176, 224, 179, 141, 37, 34, 0, 11, 6, 224, 178, 152, 224, 179, 141, 37, 147, 0, 0, 0, 15, 140, 224, 178, 133, 224, 178, 181, 224, 178, 168, 224, 179, 129, 72, 10, 2, 95, 51, 65, 6, 123, 34, 40, 0, 0, 11, 2, 95, 50, 6, 36, 34, 35, 141, 40, 0, 0, 21, 146, 224, 178, 175, 224, 178, 190, 224, 178, 181, 224, 179, 129, 224, 178, 166, 224, 179, 129, 72, 10, 2, 95, 49, 6, 39, 50, 72, 40, 0, 11, 6, 224, 178, 158, 224, 179, 141, 37, 67, 0, 0, 11, 2, 95, 48, 89, 6, 39, 50, 50, 36, 0, 0, 21, 146, 224, 178, 175, 224, 178, 190, 224, 178, 181, 224, 179, 129, 224, 178, 166, 224, 179, 135, 72, 9, 2, 95, 55, 6, 114, 62, 40, 0, 0, 9, 2, 95, 54, 6, 118, 34, 40, 0, 0, 12, 137, 224, 178, 135, 224, 178, 164, 224, 178, 176, 72, 9, 2, 95, 53, 6, 134, 72, 40, 0, 0, 11, 2, 95, 52, 50, 6, 118, 55, 49, 40, 0, 0, 0, 0, 13, 2, 95, 57, 6, 39, 65, 71, 35, 138, 12, 40, 0, 0, 10, 2, 95, 56, 6, 36, 50, 140, 40, 0, 0, 11, 2, 95, 63, 35, 49, 93, 35, 34, 35, 0, 0, 0, 11, 6, 224, 178, 156, 224, 179, 141, 37, 79, 0, 0, 0, 0, 14, 9, 224, 178, 156, 224, 178, 188, 224, 179, 141, 37, 88, 0, 14, 9, 224, 178, 171, 224, 178, 188, 224, 179, 141, 37, 83, 0, 0, 11, 6, 224, 178, 162, 224, 179, 141, 37, 143, 0, 11, 6, 224, 178, 154, 224, 179, 141, 37, 80, 0, 0, 0, 0, 0, 0, 0, 0, 12, 137, 224, 178, 135, 224, 178, 166, 224, 179, 129, 72, 12, 137, 224, 178, 133, 224, 178, 166, 224, 179, 129, 72, 0, 0, 16, 140, 224, 178, 134, 224, 178, 166, 224, 178, 176, 224, 179, 134, 72, 8, 0, 0, 0, 11, 6, 224, 178, 160, 224, 179, 141, 37, 142, 0, 0, 0, 15, 140, 224, 178, 133, 224, 178, 181, 224, 178, 176, 224, 179, 129, 72, 15, 140, 224, 178, 168, 224, 179, 128, 224, 178, 168, 224, 179, 129, 72, 15, 140, 224, 178, 168, 224, 178, 190, 224, 178, 168, 224, 179, 129, 72, 0, 0, 11, 6, 224, 178, 166, 224, 179, 141, 37, 72, 0, 0, 19, 143, 224, 178, 174, 224, 178, 164, 224, 179, 141, 224, 178, 164, 224, 179, 129, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 137, 224, 178, 135, 224, 178, 130, 224, 178, 166, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 137, 224, 178, 135, 224, 178, 166, 224, 178, 176, 72, 12, 137, 224, 178, 133, 224, 178, 166, 224, 178, 176, 72, 11, 6, 224, 178, 182, 224, 179, 141, 37, 97, 0, 0, 28, 152, 224, 178, 134, 224, 178, 166, 224, 179, 141, 224, 178, 166, 224, 178, 176, 224, 178, 191, 224, 178, 130, 224, 178, 166, 72, 8, 16, 70, 44, 19, 142, 4, 64, 64, 49, 35, 50, 50, 35, 141, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 224, 178, 151, 224, 179, 141, 37, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 20, 0, 0, 0, 230, 12, 0, 0, 48, 0, 0, 0, 231, 12, 0, 0, 49, 0, 0, 0, 232, 12, 0, 0, 50, 0, 0, 0, 233, 12, 0, 0, 51, 0, 0, 0, 234, 12, 0, 0, 52, 0, 0, 0, 235, 12, 0, 0, 53, 0, 0, 0, 236, 12, 0, 0, 54, 0, 0, 0, 237, 12, 0, 0, 55, 0, 0, 0, 238, 12, 0, 0, 56, 0, 0, 0, 239, 12, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 6, 1, 6, 0, 3, 35, 0, 7, 6, 1, 7, 0, 3, 118, 0, 7, 6, 1, 8, 0, 3, 37, 0, 7, 6, 1, 9, 0, 3, 112, 0, 7, 6, 1, 10, 0, 3, 40, 0, 7, 6, 1, 11, 0, 3, 123, 0, 7, 6, 1, 12, 0, 3, 34, 40, 0, 7, 6, 1, 15, 0, 3, 36, 0, 7, 6, 1, 16, 0, 3, 114, 0, 7, 6, 1, 17, 0, 3, 134, 0, 7, 6, 1, 19, 0, 3, 39, 0, 7, 6, 1, 20, 0, 3, 119, 0, 7, 6, 1, 21, 0, 3, 135, 0, 7, 6, 1, 22, 0, 2, 17, 66, 3, 49, 0, 3, 49, 35, 0, 7, 6, 1, 23, 0, 2, 17, 66, 3, 146, 0, 3, 146, 35, 0, 7, 6, 1, 24, 0, 2, 17, 66, 3, 81, 0, 3, 81, 35, 0, 7, 6, 1, 25, 0, 2, 17, 66, 3, 147, 0, 3, 147, 35, 0, 7, 6, 1, 26, 0, 2, 17, 66, 3, 68, 0, 3, 68, 35, 0, 7, 6, 1, 27, 0, 2, 17, 66, 3, 80, 0, 3, 80, 35, 0, 7, 6, 1, 28, 0, 2, 17, 66, 3, 144, 0, 3, 144, 35, 0, 7, 6, 1, 29, 0, 2, 17, 66, 3, 79, 0, 3, 79, 35, 0, 224, 178, 188, 2, 17, 66, 3, 88, 0, 224, 178, 188, 3, 88, 35, 0, 7, 6, 1, 30, 0, 2, 17, 66, 3, 145, 0, 3, 145, 35, 0, 7, 6, 1, 31, 0, 2, 17, 66, 3, 67, 0, 3, 67, 35, 0, 7, 6, 1, 32, 0, 2, 17, 66, 3, 140, 0, 3, 140, 35, 0, 7, 6, 1, 33, 0, 2, 17, 66, 3, 142, 0, 3, 142, 35, 0, 7, 6, 1, 34, 0, 2, 17, 66, 3, 141, 0, 3, 141, 35, 0, 7, 6, 1, 35, 0, 2, 17, 66, 3, 143, 0, 3, 143, 35, 0, 7, 6, 1, 36, 0, 2, 17, 66, 3, 66, 0, 3, 66, 35, 0, 7, 6, 1, 37, 0, 2, 17, 66, 3, 47, 0, 3, 47, 35, 0, 7, 6, 1, 38, 0, 2, 17, 66, 3, 138, 0, 3, 138, 35, 0, 7, 6, 1, 39, 0, 2, 17, 66, 3, 72, 0, 3, 72, 35, 0, 7, 6, 1, 40, 0, 2, 17, 66, 3, 139, 0, 3, 139, 35, 0, 7, 6, 1, 41, 0, 2, 17, 66, 3, 50, 0, 3, 50, 35, 0, 7, 6, 1, 43, 0, 2, 17, 66, 3, 48, 0, 3, 48, 35, 0, 7, 6, 1, 44, 0, 224, 178, 188, 2, 17, 66, 3, 83, 0, 224, 178, 188, 3, 83, 35, 0, 2, 17, 66, 3, 136, 0, 3, 136, 35, 0, 7, 6, 1, 45, 0, 2, 17, 66, 3, 71, 0, 3, 71, 35, 0, 7, 6, 1, 46, 0, 2, 17, 66, 3, 137, 0, 3, 137, 35, 0, 7, 6, 1, 47, 0, 2, 17, 66, 3, 65, 0, 3, 65, 35, 0, 7, 6, 1, 48, 0, 2, 17, 66, 3, 57, 0, 3, 57, 35, 0, 7, 6, 1, 49, 0, 2, 17, 66, 3, 34, 0, 3, 34, 35, 0, 7, 6, 1, 50, 0, 2, 17, 66, 3, 34, 0, 3, 34, 35, 0, 7, 6, 1, 51, 0, 2, 17, 66, 3, 55, 0, 3, 55, 35, 0, 7, 6, 1, 52, 0, 2, 17, 66, 3, 62, 0, 3, 62, 35, 0, 7, 6, 1, 54, 0, 2, 17, 66, 3, 84, 0, 3, 84, 35, 0, 7, 6, 1, 55, 0, 2, 17, 66, 3, 97, 0, 3, 97, 35, 0, 7, 6, 1, 56, 0, 2, 17, 66, 3, 93, 0, 3, 93, 35, 0, 7, 6, 1, 57, 0, 2, 17, 66, 3, 89, 0, 3, 89, 35, 0, 7, 6, 1, 58, 0, 2, 17, 66, 3, 107, 0, 3, 107, 35, 0, 7, 6, 1, 95, 0, 2, 17, 66, 3, 83, 0, 3, 83, 35, 0, 7, 6, 1, 97, 0, 3, 44, 0, 7, 6, 224, 164, 0, 3, 21, 104, 105, 0, 7, 6, 224, 165, 0, 3, 21, 104, 105, 0, 7, 6, 224, 178, 0, 191, 3, 37, 0, 130, 3, 65, 0, 131, 3, 107, 0, 190, 3, 118, 0, 7, 6, 224, 179, 0, 141, 3, 0, 4, 149, 3, 12, 0, 150, 0, 131, 3, 34, 40, 0, 134, 3, 36, 0, 138, 3, 39, 0, 129, 3, 40, 0, 132, 3, 44, 12, 0, 128, 3, 112, 0, 135, 3, 114, 0, 139, 3, 119, 0, 130, 3, 123, 0, 136, 3, 134, 0, 140, 3, 135, 0, 7, 6, 0, 36, 3, 72, 119, 62, 35, 34, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts34 = FileInMemory_createWithData (5367, reinterpret_cast (&espeakdata_dicts34_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/kn_dict", U"kn"); Collection_addItem (me.peek(), espeakdata_dicts34.transfer()); static unsigned char espeakdata_dicts35_data[6488] = { 0, 4, 0, 0, 75, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 21, 225, 132, 131, 225, 133, 177, 225, 134, 186, 225, 132, 134, 225, 133, 165, 225, 132, 133, 225, 133, 181, 225, 132, 131, 225, 133, 177, 225, 134, 171, 203, 144, 225, 132, 134, 225, 133, 165, 225, 132, 133, 225, 133, 181, 0, 29, 46, 21, 225, 132, 134, 225, 133, 169, 225, 134, 186, 225, 132, 140, 225, 133, 161, 225, 132, 133, 225, 133, 181, 225, 132, 134, 225, 133, 169, 225, 134, 174, 225, 132, 141, 225, 133, 161, 225, 132, 133, 225, 133, 181, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 18, 225, 132, 146, 225, 133, 174, 225, 134, 186, 225, 132, 130, 225, 133, 161, 225, 134, 175, 225, 132, 146, 225, 133, 174, 225, 134, 171, 203, 144, 225, 132, 130, 225, 133, 161, 225, 134, 175, 0, 29, 0, 0, 0, 0, 0, 0, 52, 24, 225, 132, 135, 225, 133, 174, 225, 132, 137, 225, 133, 181, 225, 134, 186, 225, 132, 131, 225, 133, 169, 225, 134, 175, 225, 132, 135, 225, 133, 174, 225, 132, 137, 225, 133, 181, 225, 134, 174, 225, 132, 132, 225, 133, 169, 225, 134, 175, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 95, 49, 77, 52, 81, 57, 6, 13, 68, 0, 0, 0, 0, 0, 13, 4, 95, 49, 77, 48, 76, 6, 107, 20, 13, 50, 0, 0, 11, 4, 95, 49, 77, 49, 65, 6, 35, 50, 0, 0, 10, 4, 95, 49, 77, 50, 6, 13, 104, 0, 0, 10, 4, 95, 49, 77, 51, 78, 6, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 3, 225, 132, 132, 6, 89, 20, 35, 68, 72, 4, 37, 104, 109, 72, 20, 0, 0, 13, 3, 225, 132, 133, 16, 37, 38, 6, 109, 34, 34, 0, 0, 12, 3, 225, 132, 134, 65, 37, 38, 6, 109, 65, 0, 0, 12, 3, 225, 132, 135, 48, 37, 38, 6, 109, 48, 0, 0, 12, 3, 225, 132, 128, 81, 37, 57, 6, 13, 104, 0, 0, 17, 3, 225, 132, 129, 6, 89, 20, 35, 68, 104, 4, 37, 57, 13, 104, 0, 0, 22, 6, 225, 132, 137, 225, 132, 135, 225, 132, 137, 225, 133, 181, 225, 132, 135, 225, 133, 161, 0, 29, 12, 3, 225, 132, 130, 50, 37, 38, 6, 109, 50, 0, 0, 13, 3, 225, 132, 131, 72, 37, 104, 6, 109, 72, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 225, 132, 144, 47, 107, 37, 38, 6, 109, 112, 0, 0, 12, 3, 225, 132, 145, 114, 37, 38, 6, 109, 48, 0, 0, 34, 15, 225, 132, 144, 225, 133, 165, 225, 134, 186, 225, 132, 137, 225, 133, 166, 225, 132, 144, 225, 133, 165, 225, 134, 174, 225, 132, 138, 225, 133, 166, 0, 29, 12, 3, 225, 132, 146, 107, 37, 38, 6, 109, 112, 0, 0, 0, 12, 3, 225, 132, 140, 78, 37, 38, 6, 109, 47, 0, 0, 17, 3, 225, 132, 141, 6, 89, 20, 35, 68, 77, 4, 37, 38, 109, 47, 0, 0, 39, 15, 225, 132, 131, 225, 133, 177, 225, 134, 186, 225, 133, 178, 225, 134, 190, 225, 132, 131, 225, 133, 177, 225, 134, 171, 203, 144, 225, 132, 130, 225, 133, 178, 225, 134, 174, 0, 29, 14, 3, 225, 132, 142, 76, 107, 20, 6, 37, 38, 109, 47, 0, 0, 12, 3, 225, 132, 143, 111, 37, 38, 6, 109, 49, 0, 0, 17, 3, 225, 132, 136, 6, 89, 20, 35, 68, 71, 4, 37, 38, 109, 48, 0, 0, 12, 3, 225, 132, 137, 89, 37, 38, 6, 39, 112, 0, 0, 17, 3, 225, 132, 138, 6, 89, 20, 35, 68, 89, 4, 37, 38, 39, 112, 0, 0, 52, 24, 225, 132, 140, 225, 133, 165, 225, 134, 171, 225, 132, 128, 225, 133, 181, 225, 134, 186, 225, 132, 137, 225, 133, 166, 225, 132, 140, 225, 133, 165, 225, 134, 171, 225, 132, 128, 225, 133, 181, 225, 134, 174, 225, 132, 138, 225, 133, 166, 0, 29, 11, 3, 225, 132, 139, 37, 38, 6, 109, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 18, 225, 132, 135, 225, 133, 169, 225, 134, 186, 225, 132, 131, 225, 133, 174, 225, 134, 168, 225, 132, 135, 225, 133, 169, 225, 134, 174, 225, 132, 132, 225, 133, 174, 225, 134, 168, 0, 29, 0, 0, 0, 46, 21, 225, 133, 181, 225, 134, 186, 225, 132, 140, 225, 133, 161, 225, 132, 128, 225, 133, 174, 225, 134, 168, 225, 133, 181, 225, 134, 174, 225, 132, 141, 225, 133, 161, 225, 132, 128, 225, 133, 174, 225, 134, 168, 0, 29, 0, 0, 0, 0, 40, 18, 225, 132, 144, 225, 133, 162, 225, 134, 186, 225, 132, 140, 225, 133, 174, 225, 134, 175, 225, 132, 144, 225, 133, 162, 225, 134, 174, 225, 132, 141, 225, 133, 174, 225, 134, 175, 0, 29, 0, 34, 15, 225, 132, 146, 225, 133, 162, 225, 134, 186, 225, 132, 137, 225, 133, 174, 225, 132, 146, 225, 133, 162, 225, 134, 174, 225, 132, 138, 225, 133, 174, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 34, 15, 225, 132, 146, 225, 133, 172, 225, 134, 186, 225, 132, 135, 225, 133, 162, 225, 132, 146, 225, 133, 176, 225, 134, 174, 225, 132, 136, 225, 133, 162, 0, 29, 0, 0, 40, 18, 225, 132, 144, 225, 133, 172, 225, 134, 186, 225, 132, 128, 225, 133, 161, 225, 134, 171, 225, 132, 144, 225, 133, 172, 225, 134, 174, 225, 132, 129, 225, 133, 161, 225, 134, 171, 0, 29, 40, 18, 225, 132, 142, 225, 133, 161, 225, 134, 186, 225, 132, 128, 225, 133, 161, 225, 134, 171, 225, 132, 142, 225, 133, 161, 225, 134, 174, 225, 132, 129, 225, 133, 161, 225, 134, 171, 0, 29, 40, 18, 225, 132, 128, 225, 133, 169, 225, 134, 186, 225, 132, 128, 225, 133, 161, 225, 134, 171, 225, 132, 128, 225, 133, 169, 225, 134, 174, 225, 132, 129, 225, 133, 161, 225, 134, 171, 0, 29, 0, 0, 0, 0, 40, 18, 225, 132, 135, 225, 133, 181, 225, 134, 186, 225, 132, 134, 225, 133, 174, 225, 134, 175, 225, 132, 135, 225, 133, 181, 225, 134, 171, 225, 132, 134, 225, 133, 174, 225, 134, 175, 0, 29, 0, 0, 0, 0, 46, 21, 225, 132, 130, 225, 133, 161, 225, 132, 133, 225, 133, 174, 225, 134, 186, 225, 132, 135, 225, 133, 162, 225, 132, 130, 225, 133, 161, 225, 132, 133, 225, 133, 174, 225, 134, 174, 225, 132, 136, 225, 133, 162, 0, 29, 0, 0, 52, 24, 225, 132, 134, 225, 133, 166, 225, 134, 186, 225, 132, 130, 225, 133, 161, 225, 132, 134, 225, 133, 174, 225, 134, 175, 225, 132, 134, 225, 133, 166, 225, 134, 171, 225, 132, 130, 225, 133, 161, 225, 132, 134, 225, 133, 174, 225, 134, 175, 0, 29, 0, 0, 46, 21, 225, 132, 146, 225, 133, 172, 225, 134, 186, 225, 132, 128, 225, 133, 161, 225, 132, 133, 225, 133, 174, 225, 132, 146, 225, 133, 176, 225, 134, 174, 225, 132, 129, 225, 133, 161, 225, 132, 133, 225, 133, 174, 0, 29, 0, 61, 27, 225, 132, 131, 225, 133, 169, 225, 132, 133, 225, 133, 181, 225, 132, 129, 225, 133, 162, 225, 134, 186, 225, 133, 167, 225, 134, 175, 225, 132, 131, 225, 133, 169, 225, 132, 133, 225, 133, 181, 225, 132, 129, 225, 133, 162, 225, 134, 171, 225, 132, 130, 225, 133, 167, 225, 134, 175, 0, 29, 0, 0, 0, 0, 46, 21, 225, 132, 135, 225, 133, 167, 225, 134, 186, 225, 132, 128, 225, 133, 161, 225, 132, 133, 225, 133, 181, 225, 132, 135, 225, 133, 167, 225, 134, 174, 225, 132, 129, 225, 133, 161, 225, 132, 133, 225, 133, 181, 0, 29, 46, 21, 225, 132, 131, 225, 133, 162, 225, 134, 186, 225, 132, 128, 225, 133, 161, 225, 132, 140, 225, 133, 181, 225, 132, 131, 225, 133, 162, 225, 134, 174, 225, 132, 129, 225, 133, 161, 225, 132, 140, 225, 133, 181, 0, 29, 0, 0, 0, 40, 18, 225, 132, 142, 225, 133, 161, 225, 134, 186, 225, 132, 140, 225, 133, 161, 225, 134, 171, 225, 132, 142, 225, 133, 161, 225, 134, 174, 225, 132, 141, 225, 133, 161, 225, 134, 171, 0, 29, 40, 18, 225, 132, 142, 225, 133, 161, 225, 134, 186, 225, 132, 140, 225, 133, 161, 225, 134, 171, 225, 132, 142, 225, 133, 161, 225, 134, 174, 225, 132, 141, 225, 133, 161, 225, 134, 171, 0, 29, 0, 0, 0, 58, 27, 225, 132, 130, 225, 133, 161, 225, 132, 134, 225, 133, 174, 225, 134, 186, 225, 132, 128, 225, 133, 161, 225, 132, 140, 225, 133, 181, 225, 132, 130, 225, 133, 161, 225, 132, 134, 225, 133, 174, 225, 134, 174, 225, 132, 129, 225, 133, 161, 225, 132, 140, 225, 133, 181, 0, 29, 0, 0, 0, 0, 0, 58, 27, 225, 133, 174, 225, 132, 133, 225, 133, 165, 225, 134, 188, 225, 133, 181, 225, 134, 186, 225, 132, 137, 225, 133, 169, 225, 134, 168, 225, 133, 174, 225, 132, 133, 225, 133, 165, 225, 134, 188, 225, 133, 181, 225, 134, 174, 225, 132, 138, 225, 133, 169, 225, 134, 168, 0, 29, 0, 0, 0, 40, 18, 225, 132, 129, 225, 133, 162, 225, 134, 186, 225, 132, 134, 225, 133, 174, 225, 134, 168, 225, 132, 129, 225, 133, 162, 225, 134, 171, 225, 132, 134, 225, 133, 174, 225, 134, 168, 0, 29, 0, 0, 0, 0, 0, 42, 18, 225, 132, 130, 225, 133, 162, 225, 134, 186, 225, 132, 134, 225, 133, 174, 225, 134, 175, 225, 132, 130, 225, 133, 162, 225, 134, 171, 203, 144, 225, 132, 134, 225, 133, 174, 225, 134, 175, 0, 29, 0, 0, 0, 0, 0, 0, 52, 24, 225, 133, 163, 225, 134, 188, 225, 132, 142, 225, 133, 181, 225, 134, 186, 225, 132, 134, 225, 133, 174, 225, 134, 175, 225, 133, 163, 225, 134, 188, 225, 132, 142, 225, 133, 181, 225, 134, 171, 225, 132, 134, 225, 133, 174, 225, 134, 175, 0, 29, 54, 24, 225, 132, 134, 225, 133, 169, 225, 132, 128, 225, 133, 181, 225, 134, 186, 225, 132, 135, 225, 133, 174, 225, 134, 175, 225, 132, 134, 225, 133, 169, 203, 144, 225, 132, 128, 225, 133, 181, 225, 134, 174, 225, 132, 136, 225, 133, 174, 225, 134, 175, 0, 29, 0, 0, 0, 0, 40, 18, 225, 132, 143, 225, 133, 181, 225, 134, 186, 225, 132, 128, 225, 133, 161, 225, 134, 185, 225, 132, 143, 225, 133, 181, 225, 134, 174, 225, 132, 129, 225, 133, 161, 225, 134, 184, 0, 29, 0, 0, 0, 46, 21, 225, 132, 142, 225, 133, 166, 225, 134, 186, 225, 132, 135, 225, 133, 161, 225, 132, 143, 225, 133, 177, 225, 132, 142, 225, 133, 166, 225, 134, 174, 225, 132, 136, 225, 133, 161, 225, 132, 143, 225, 133, 177, 0, 29, 0, 0, 42, 18, 225, 132, 137, 225, 133, 162, 225, 134, 186, 225, 132, 128, 225, 133, 161, 225, 134, 188, 225, 132, 137, 225, 133, 162, 225, 134, 174, 203, 144, 225, 132, 129, 225, 133, 161, 225, 134, 188, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 18, 225, 132, 142, 225, 133, 169, 225, 134, 186, 225, 132, 128, 225, 133, 174, 225, 134, 168, 225, 132, 142, 225, 133, 169, 225, 134, 174, 225, 132, 129, 225, 133, 174, 225, 134, 168, 0, 29, 0, 0, 0, 0, 0, 0, 46, 21, 225, 132, 140, 225, 133, 162, 225, 134, 186, 225, 132, 131, 225, 133, 165, 225, 132, 134, 225, 133, 181, 225, 132, 140, 225, 133, 162, 225, 134, 174, 225, 132, 132, 225, 133, 165, 225, 132, 134, 225, 133, 181, 0, 29, 0, 0, 0, 58, 27, 225, 132, 137, 225, 133, 165, 225, 134, 171, 225, 132, 140, 225, 133, 181, 225, 134, 186, 225, 132, 128, 225, 133, 174, 225, 134, 168, 225, 132, 137, 225, 133, 165, 225, 134, 171, 225, 132, 140, 225, 133, 181, 225, 134, 174, 225, 132, 129, 225, 133, 174, 225, 134, 168, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 3, 95, 51, 88, 89, 6, 35, 65, 11, 15, 89, 6, 37, 48, 11, 0, 0, 11, 3, 95, 48, 67, 48, 6, 108, 104, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 3, 95, 55, 88, 76, 6, 107, 6, 37, 51, 11, 89, 6, 37, 48, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 49, 88, 89, 6, 37, 48, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 50, 88, 6, 37, 11, 15, 89, 6, 37, 48, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 52, 88, 89, 6, 35, 11, 15, 89, 6, 37, 48, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 53, 88, 6, 39, 11, 15, 89, 6, 37, 48, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 3, 95, 54, 88, 57, 6, 40, 104, 11, 15, 89, 6, 37, 48, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 3, 95, 56, 88, 114, 6, 35, 51, 11, 15, 89, 6, 37, 48, 11, 0, 0, 0, 40, 18, 225, 133, 161, 225, 132, 133, 225, 133, 162, 225, 134, 186, 225, 132, 130, 225, 133, 181, 225, 133, 161, 225, 132, 133, 225, 133, 162, 225, 134, 171, 225, 132, 130, 225, 133, 181, 0, 29, 0, 0, 0, 0, 0, 0, 16, 3, 95, 57, 88, 81, 6, 40, 11, 15, 89, 6, 37, 48, 11, 0, 0, 0, 0, 0, 0, 0, 0, 36, 15, 225, 132, 130, 225, 133, 162, 225, 134, 186, 225, 132, 128, 225, 133, 161, 225, 132, 130, 225, 133, 162, 225, 134, 174, 203, 144, 225, 132, 129, 225, 133, 161, 0, 29, 0, 0, 0, 0, 0, 0, 46, 21, 225, 132, 135, 225, 133, 161, 225, 132, 131, 225, 133, 161, 225, 134, 186, 225, 132, 128, 225, 133, 161, 225, 132, 135, 225, 133, 161, 225, 132, 131, 225, 133, 161, 225, 134, 174, 225, 132, 129, 225, 133, 161, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 95, 48, 77, 52, 81, 57, 6, 13, 68, 0, 0, 0, 10, 4, 95, 48, 77, 50, 6, 13, 104, 0, 0, 10, 4, 95, 48, 77, 51, 78, 6, 39, 0, 0, 13, 4, 95, 48, 77, 48, 76, 6, 107, 20, 13, 50, 0, 0, 11, 4, 95, 48, 77, 49, 65, 6, 35, 50, 0, 0, 0, 0, 0, 0, 0, 0, 34, 15, 225, 132, 145, 225, 133, 181, 225, 134, 186, 225, 132, 128, 225, 133, 181, 225, 132, 145, 225, 133, 181, 225, 134, 174, 225, 132, 129, 225, 133, 181, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 15, 225, 132, 131, 225, 133, 162, 225, 134, 186, 225, 133, 181, 225, 135, 129, 225, 132, 131, 225, 133, 162, 225, 134, 171, 225, 132, 130, 225, 133, 181, 225, 134, 184, 0, 29, 37, 15, 225, 132, 129, 225, 133, 162, 225, 134, 186, 225, 133, 181, 225, 135, 129, 225, 132, 129, 225, 133, 162, 225, 134, 171, 225, 132, 130, 225, 133, 181, 225, 134, 184, 0, 29, 0, 34, 15, 225, 132, 146, 225, 133, 172, 225, 134, 186, 225, 132, 137, 225, 133, 174, 225, 132, 146, 225, 133, 172, 225, 134, 174, 225, 132, 138, 225, 133, 174, 0, 29, 0, 34, 15, 225, 133, 181, 225, 134, 186, 225, 132, 134, 225, 133, 169, 225, 134, 183, 225, 133, 181, 225, 134, 171, 225, 132, 134, 225, 133, 169, 225, 134, 183, 0, 29, 0, 0, 0, 0, 49, 21, 225, 132, 130, 225, 133, 161, 225, 132, 134, 225, 133, 174, 225, 134, 186, 225, 133, 181, 225, 135, 129, 225, 132, 130, 225, 133, 161, 225, 132, 134, 225, 133, 174, 225, 134, 171, 225, 132, 130, 225, 133, 181, 225, 134, 184, 0, 29, 0, 0, 0, 0, 31, 12, 225, 133, 173, 225, 134, 186, 225, 133, 181, 225, 134, 186, 225, 133, 173, 225, 134, 171, 225, 132, 130, 225, 133, 181, 225, 134, 174, 0, 29, 0, 0, 0, 0, 0, 46, 21, 225, 132, 140, 225, 133, 161, 225, 132, 133, 225, 133, 181, 225, 134, 186, 225, 132, 137, 225, 133, 166, 225, 132, 140, 225, 133, 161, 225, 132, 133, 225, 133, 181, 225, 134, 174, 225, 132, 138, 225, 133, 166, 0, 29, 0, 0, 0, 0, 49, 21, 225, 132, 135, 225, 133, 166, 225, 132, 128, 225, 133, 162, 225, 134, 186, 225, 133, 181, 225, 134, 186, 225, 132, 135, 225, 133, 166, 225, 132, 128, 225, 133, 162, 225, 134, 171, 225, 132, 130, 225, 133, 181, 225, 134, 174, 0, 29, 46, 21, 225, 132, 128, 225, 133, 169, 225, 132, 133, 225, 133, 162, 225, 134, 186, 225, 132, 140, 225, 133, 162, 225, 132, 128, 225, 133, 169, 225, 132, 133, 225, 133, 162, 225, 134, 174, 225, 132, 141, 225, 133, 162, 0, 29, 0, 0, 0, 0, 52, 24, 225, 133, 161, 225, 132, 133, 225, 133, 162, 225, 134, 186, 225, 132, 134, 225, 133, 161, 225, 133, 179, 225, 134, 175, 225, 133, 161, 225, 132, 133, 225, 133, 162, 225, 134, 171, 225, 132, 134, 225, 133, 161, 225, 133, 179, 225, 134, 175, 0, 29, 0, 0, 0, 39, 15, 225, 132, 146, 225, 133, 174, 225, 134, 186, 225, 133, 181, 225, 134, 175, 225, 132, 146, 225, 133, 174, 225, 134, 171, 203, 144, 225, 132, 130, 225, 133, 181, 225, 134, 175, 0, 29, 39, 15, 225, 132, 131, 225, 133, 177, 225, 134, 186, 225, 133, 181, 225, 134, 175, 225, 132, 131, 225, 133, 177, 225, 134, 171, 203, 144, 225, 132, 130, 225, 133, 181, 225, 134, 175, 0, 29, 0, 0, 0, 45, 18, 225, 133, 168, 225, 132, 137, 225, 133, 161, 225, 134, 186, 225, 133, 181, 225, 134, 175, 225, 133, 168, 203, 144, 225, 132, 137, 225, 133, 161, 225, 134, 171, 225, 132, 130, 225, 133, 181, 225, 134, 175, 0, 29, 65, 18, 225, 132, 128, 225, 133, 161, 225, 133, 172, 225, 134, 186, 225, 133, 181, 225, 134, 175, 225, 132, 128, 225, 133, 161, 225, 133, 172, 225, 134, 171, 225, 132, 130, 225, 133, 181, 225, 134, 175, 47, 225, 132, 128, 225, 133, 161, 225, 133, 176, 225, 134, 171, 225, 132, 130, 225, 133, 181, 225, 134, 175, 0, 29, 0, 40, 18, 225, 132, 146, 225, 133, 162, 225, 134, 186, 225, 132, 135, 225, 133, 167, 225, 135, 128, 225, 132, 146, 225, 133, 162, 225, 134, 174, 225, 132, 136, 225, 133, 167, 225, 134, 174, 0, 29, 0, 0, 49, 21, 225, 132, 137, 225, 133, 161, 225, 132, 137, 225, 133, 161, 225, 134, 186, 225, 133, 181, 225, 134, 175, 225, 132, 137, 225, 133, 161, 225, 132, 137, 225, 133, 161, 225, 134, 171, 225, 132, 130, 225, 133, 181, 225, 134, 175, 0, 29, 49, 21, 225, 132, 131, 225, 133, 174, 225, 132, 133, 225, 133, 166, 225, 134, 186, 225, 133, 181, 225, 134, 175, 225, 132, 131, 225, 133, 174, 225, 132, 133, 225, 133, 166, 225, 134, 171, 225, 132, 130, 225, 133, 181, 225, 134, 175, 0, 29, 0, 0, 0, 0, 0, 0, 0, 52, 24, 225, 132, 146, 225, 133, 167, 225, 134, 186, 225, 132, 135, 225, 133, 161, 225, 132, 130, 225, 133, 179, 225, 134, 175, 225, 132, 146, 225, 133, 167, 225, 134, 174, 225, 132, 136, 225, 133, 161, 225, 132, 130, 225, 133, 179, 225, 134, 175, 0, 29, 0, 0, 0, 0, 0, 40, 18, 225, 132, 135, 225, 133, 162, 225, 134, 186, 225, 132, 128, 225, 133, 181, 225, 134, 175, 225, 132, 135, 225, 133, 162, 225, 134, 174, 225, 132, 129, 225, 133, 181, 225, 134, 175, 0, 29, 40, 18, 225, 132, 134, 225, 133, 162, 225, 134, 186, 225, 132, 131, 225, 133, 169, 225, 134, 175, 225, 132, 134, 225, 133, 162, 225, 134, 174, 225, 132, 132, 225, 133, 169, 225, 134, 175, 0, 29, 0, 0, 0, 34, 15, 225, 132, 137, 225, 133, 174, 225, 134, 186, 225, 132, 140, 225, 133, 161, 225, 132, 137, 225, 133, 174, 225, 134, 174, 225, 132, 141, 225, 133, 161, 0, 29, 40, 18, 225, 132, 142, 225, 133, 161, 225, 134, 186, 225, 132, 140, 225, 133, 169, 225, 134, 188, 225, 132, 142, 225, 133, 161, 225, 134, 174, 225, 132, 141, 225, 133, 169, 225, 134, 188, 0, 29, 0, 0, 0, 46, 21, 225, 133, 161, 225, 132, 133, 225, 133, 162, 225, 134, 186, 225, 132, 135, 225, 133, 161, 225, 134, 188, 225, 133, 161, 225, 132, 133, 225, 133, 162, 225, 134, 174, 225, 132, 136, 225, 133, 161, 225, 134, 188, 0, 29, 52, 24, 225, 132, 140, 225, 133, 169, 225, 132, 128, 225, 133, 162, 225, 134, 186, 225, 132, 137, 225, 133, 161, 225, 134, 175, 225, 132, 140, 225, 133, 169, 225, 132, 128, 225, 133, 162, 225, 134, 174, 225, 132, 138, 225, 133, 161, 225, 134, 175, 0, 29, 0, 40, 18, 225, 132, 143, 225, 133, 169, 225, 134, 186, 225, 132, 135, 225, 133, 167, 225, 134, 188, 225, 132, 143, 225, 133, 169, 225, 134, 174, 225, 132, 136, 225, 133, 167, 225, 134, 188, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 2, 95, 51, 89, 6, 35, 65, 11, 0, 0, 8, 2, 95, 50, 6, 37, 11, 0, 0, 9, 2, 95, 49, 6, 37, 51, 11, 0, 0, 10, 2, 95, 48, 57, 6, 13, 68, 11, 0, 0, 12, 2, 95, 55, 76, 6, 107, 6, 37, 51, 11, 0, 0, 10, 2, 95, 54, 57, 6, 40, 104, 11, 0, 0, 8, 2, 95, 53, 6, 39, 11, 0, 0, 40, 18, 225, 132, 142, 225, 133, 161, 225, 134, 186, 225, 132, 140, 225, 133, 181, 225, 134, 184, 225, 132, 142, 225, 133, 161, 225, 134, 174, 225, 132, 141, 225, 133, 181, 225, 134, 184, 0, 29, 9, 2, 95, 52, 89, 6, 35, 11, 0, 0, 0, 0, 46, 21, 225, 133, 161, 225, 132, 133, 225, 133, 162, 225, 134, 186, 225, 132, 140, 225, 133, 181, 225, 134, 184, 225, 133, 161, 225, 132, 133, 225, 133, 162, 225, 134, 174, 225, 132, 141, 225, 133, 181, 225, 134, 184, 0, 29, 9, 2, 95, 57, 81, 6, 40, 11, 0, 0, 10, 2, 95, 56, 114, 6, 35, 51, 11, 0, 0, 0, 52, 24, 225, 132, 137, 225, 133, 172, 225, 134, 186, 225, 132, 140, 225, 133, 169, 225, 132, 128, 225, 133, 161, 225, 134, 168, 225, 132, 137, 225, 133, 176, 225, 134, 174, 225, 132, 141, 225, 133, 169, 225, 132, 128, 225, 133, 161, 225, 134, 168, 0, 29, 0, 0, 0, 63, 18, 225, 132, 128, 225, 133, 168, 225, 134, 186, 225, 132, 130, 225, 133, 161, 225, 134, 175, 225, 132, 128, 225, 133, 168, 225, 134, 171, 203, 144, 225, 132, 130, 225, 133, 161, 225, 134, 175, 47, 225, 132, 128, 225, 133, 166, 225, 134, 171, 203, 144, 225, 132, 130, 225, 133, 161, 225, 134, 175, 0, 29, 58, 27, 225, 132, 140, 225, 133, 165, 225, 134, 171, 225, 132, 137, 225, 133, 166, 225, 134, 186, 225, 132, 140, 225, 133, 181, 225, 134, 184, 225, 132, 140, 225, 133, 165, 225, 134, 171, 225, 132, 137, 225, 133, 166, 225, 134, 174, 225, 132, 141, 225, 133, 181, 225, 134, 184, 0, 29, 0, 0, 0, 0, 0, 0, 54, 24, 225, 132, 140, 225, 133, 166, 225, 132, 137, 225, 133, 161, 225, 134, 186, 225, 132, 130, 225, 133, 161, 225, 134, 175, 225, 132, 140, 225, 133, 166, 203, 144, 225, 132, 137, 225, 133, 161, 225, 134, 174, 225, 132, 130, 225, 133, 161, 225, 134, 175, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 18, 225, 132, 137, 225, 133, 166, 225, 134, 186, 225, 132, 135, 225, 133, 161, 225, 134, 188, 225, 132, 137, 225, 133, 166, 225, 134, 174, 225, 132, 136, 225, 133, 161, 225, 134, 188, 0, 29, 0, 0, 0, 0, 40, 18, 225, 132, 135, 225, 133, 162, 225, 134, 186, 225, 132, 135, 225, 133, 167, 225, 134, 188, 225, 132, 135, 225, 133, 162, 225, 134, 174, 225, 132, 136, 225, 133, 167, 225, 134, 188, 0, 29, 40, 18, 225, 132, 128, 225, 133, 177, 225, 134, 186, 225, 132, 135, 225, 133, 167, 225, 134, 188, 225, 132, 128, 225, 133, 177, 225, 134, 174, 225, 132, 136, 225, 133, 167, 225, 134, 188, 0, 29, 40, 18, 225, 132, 128, 225, 133, 177, 225, 134, 186, 225, 132, 135, 225, 133, 161, 225, 134, 184, 225, 132, 128, 225, 133, 177, 225, 134, 174, 225, 132, 136, 225, 133, 161, 225, 134, 184, 0, 29, 0, 0, 52, 24, 225, 132, 134, 225, 133, 165, 225, 132, 133, 225, 133, 181, 225, 134, 186, 225, 132, 135, 225, 133, 161, 225, 134, 188, 225, 132, 134, 225, 133, 165, 225, 132, 133, 225, 133, 181, 225, 134, 174, 225, 132, 136, 225, 133, 161, 225, 134, 188, 0, 29, 52, 24, 225, 132, 144, 225, 133, 165, 225, 134, 186, 225, 132, 134, 225, 133, 161, 225, 132, 131, 225, 133, 161, 225, 134, 188, 225, 132, 144, 225, 133, 165, 225, 134, 171, 225, 132, 134, 225, 133, 161, 225, 132, 131, 225, 133, 161, 225, 134, 188, 0, 29, 0, 0, 57, 24, 225, 132, 131, 225, 133, 177, 225, 134, 186, 225, 133, 181, 225, 134, 184, 225, 132, 134, 225, 133, 161, 225, 134, 186, 225, 132, 131, 225, 133, 177, 225, 134, 171, 203, 144, 225, 132, 130, 225, 133, 181, 225, 134, 183, 225, 132, 134, 225, 133, 161, 225, 134, 174, 0, 29, 0, 60, 27, 225, 132, 131, 225, 133, 177, 225, 134, 186, 225, 132, 128, 225, 133, 161, 225, 134, 175, 225, 132, 134, 225, 133, 161, 225, 134, 188, 225, 132, 131, 225, 133, 177, 225, 134, 174, 203, 144, 225, 132, 129, 225, 133, 161, 225, 134, 175, 225, 132, 134, 225, 133, 161, 225, 134, 188, 0, 29, 0, 54, 24, 225, 132, 137, 225, 133, 161, 225, 132, 140, 225, 133, 161, 225, 134, 186, 225, 132, 135, 225, 133, 161, 225, 134, 184, 225, 132, 137, 225, 133, 161, 203, 144, 225, 132, 140, 225, 133, 161, 225, 134, 174, 225, 132, 136, 225, 133, 161, 225, 134, 184, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 30, 225, 132, 134, 225, 133, 165, 225, 132, 133, 225, 133, 181, 225, 134, 186, 225, 132, 128, 225, 133, 181, 225, 132, 133, 225, 133, 179, 225, 134, 183, 225, 132, 134, 225, 133, 165, 225, 132, 133, 225, 133, 181, 225, 134, 174, 225, 132, 129, 225, 133, 181, 225, 132, 133, 225, 133, 181, 225, 134, 183, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 15, 225, 132, 145, 225, 133, 181, 225, 134, 186, 225, 132, 131, 225, 133, 162, 225, 132, 145, 225, 133, 181, 225, 134, 174, 225, 132, 132, 225, 133, 162, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 21, 225, 132, 144, 225, 133, 172, 225, 134, 186, 225, 132, 134, 225, 133, 161, 225, 132, 133, 225, 133, 174, 225, 132, 144, 225, 133, 172, 225, 134, 171, 203, 144, 225, 132, 134, 225, 133, 161, 225, 132, 133, 225, 133, 174, 47, 225, 132, 144, 225, 133, 176, 225, 134, 171, 203, 144, 225, 132, 134, 225, 133, 161, 225, 132, 133, 225, 133, 174, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 20, 0, 0, 0, 0, 0, 0, 0, 6, 18, 66, 225, 134, 168, 0, 225, 134, 169, 0, 225, 134, 191, 0, 225, 134, 174, 0, 225, 135, 128, 0, 225, 134, 184, 0, 225, 135, 129, 0, 225, 134, 186, 0, 225, 134, 187, 0, 225, 134, 189, 0, 225, 134, 190, 0, 225, 134, 170, 0, 225, 134, 185, 0, 225, 134, 172, 0, 225, 134, 176, 0, 225, 134, 177, 0, 225, 134, 178, 0, 225, 134, 179, 0, 225, 134, 180, 0, 225, 134, 181, 0, 7, 6, 18, 67, 225, 133, 181, 0, 225, 133, 163, 0, 225, 133, 164, 0, 225, 133, 167, 0, 225, 133, 168, 0, 225, 133, 173, 0, 225, 133, 178, 0, 7, 6, 18, 68, 225, 135, 130, 0, 225, 134, 173, 0, 225, 134, 182, 0, 7, 6, 1, 1, 0, 8, 3, 81, 0, 3, 104, 0, 1, 18, 66, 3, 110, 0, 1, 18, 68, 3, 111, 0, 7, 6, 1, 2, 0, 3, 104, 20, 0, 7, 6, 1, 3, 0, 3, 38, 50, 0, 7, 6, 1, 4, 0, 1, 18, 68, 3, 47, 107, 0, 4, 3, 72, 0, 8, 0, 1, 18, 66, 3, 112, 0, 7, 6, 1, 5, 0, 3, 112, 0, 7, 6, 1, 6, 0, 3, 16, 0, 2, 32, 3, 55, 0, 7, 6, 1, 7, 0, 3, 38, 65, 0, 7, 6, 1, 8, 0, 8, 3, 48, 0, 3, 71, 0, 1, 18, 66, 3, 113, 0, 1, 18, 68, 3, 114, 0, 7, 6, 1, 9, 0, 3, 113, 0, 7, 6, 1, 10, 0, 3, 89, 0, 1, 18, 66, 3, 89, 20, 0, 7, 6, 1, 11, 0, 3, 89, 20, 0, 7, 6, 1, 12, 0, 3, 37, 38, 6, 109, 68, 0, 7, 6, 1, 13, 0, 1, 18, 68, 3, 76, 107, 38, 0, 3, 77, 0, 8, 3, 78, 0, 1, 18, 66, 3, 78, 20, 0, 7, 6, 1, 14, 0, 3, 6, 78, 20, 0, 7, 6, 1, 15, 0, 3, 76, 107, 20, 0, 7, 6, 1, 16, 0, 3, 111, 0, 7, 6, 1, 17, 0, 3, 47, 107, 0, 7, 6, 1, 18, 0, 3, 114, 0, 7, 6, 1, 19, 0, 4, 3, 107, 0, 8, 0, 7, 6, 1, 98, 0, 3, 35, 0, 7, 6, 1, 99, 0, 3, 108, 0, 7, 6, 1, 100, 0, 3, 57, 35, 0, 7, 6, 1, 101, 0, 3, 57, 108, 0, 7, 6, 1, 102, 0, 3, 13, 0, 7, 6, 1, 103, 0, 3, 36, 0, 7, 6, 1, 104, 0, 3, 57, 13, 0, 7, 6, 1, 105, 0, 3, 57, 36, 0, 7, 6, 1, 106, 0, 3, 39, 0, 7, 6, 1, 107, 0, 3, 58, 35, 0, 7, 6, 1, 108, 0, 3, 58, 108, 0, 7, 6, 1, 109, 0, 3, 58, 36, 0, 7, 6, 1, 110, 0, 3, 57, 39, 0, 7, 6, 1, 111, 0, 3, 40, 0, 7, 6, 1, 112, 0, 3, 58, 13, 0, 7, 6, 1, 113, 0, 3, 58, 36, 0, 7, 6, 1, 114, 0, 3, 58, 37, 0, 7, 6, 1, 115, 0, 3, 57, 40, 0, 7, 6, 1, 116, 0, 3, 109, 0, 7, 6, 1, 117, 0, 1, 17, 67, 3, 37, 0, 3, 109, 57, 0, 7, 6, 1, 118, 0, 3, 37, 0, 7, 6, 225, 134, 0, 168, 3, 104, 0, 168, 225, 132, 146, 3, 111, 0, 170, 3, 49, 0, 170, 2, 17, 65, 3, 49, 89, 0, 170, 225, 132, 146, 3, 111, 0, 169, 3, 49, 0, 169, 2, 17, 65, 3, 110, 0, 169, 225, 132, 146, 3, 111, 0, 191, 3, 49, 0, 191, 2, 17, 65, 3, 111, 0, 174, 225, 132, 146, 3, 47, 107, 0, 174, 225, 132, 130, 3, 50, 50, 0, 174, 225, 132, 134, 3, 65, 65, 0, 174, 3, 72, 20, 0, 174, 2, 18, 67, 3, 77, 0, 184, 3, 48, 0, 184, 225, 132, 146, 3, 114, 0, 185, 3, 48, 0, 4, 185, 2, 17, 65, 3, 48, 89, 20, 0, 185, 225, 132, 146, 0, 186, 225, 132, 130, 3, 50, 50, 0, 186, 225, 132, 134, 3, 65, 65, 0, 186, 2, 17, 65, 3, 89, 0, 186, 225, 132, 146, 3, 89, 20, 0, 186, 3, 112, 0, 187, 225, 132, 130, 3, 50, 50, 0, 187, 225, 132, 134, 3, 65, 65, 0, 187, 2, 17, 65, 3, 89, 20, 0, 187, 3, 112, 0, 189, 3, 47, 0, 189, 225, 132, 130, 3, 50, 50, 0, 189, 225, 132, 134, 3, 65, 65, 0, 189, 2, 17, 65, 3, 78, 0, 190, 3, 47, 0, 190, 225, 132, 130, 3, 50, 50, 0, 190, 225, 132, 134, 3, 65, 65, 0, 190, 2, 17, 65, 3, 76, 107, 38, 0, 171, 3, 50, 0, 172, 3, 50, 0, 172, 2, 17, 65, 3, 50, 77, 0, 4, 173, 3, 50, 0, 173, 2, 17, 65, 0, 183, 3, 65, 0, 188, 3, 68, 0, 175, 2, 17, 65, 3, 16, 0, 175, 3, 34, 34, 0, 175, 225, 132, 133, 3, 55, 0, 176, 3, 49, 0, 176, 2, 17, 65, 3, 55, 81, 0, 177, 2, 17, 65, 3, 55, 65, 0, 177, 3, 65, 0, 178, 3, 48, 0, 178, 2, 17, 65, 3, 55, 71, 0, 179, 3, 55, 0, 179, 2, 17, 65, 3, 55, 89, 0, 180, 3, 55, 0, 180, 2, 17, 65, 3, 55, 47, 107, 0, 181, 3, 48, 0, 181, 2, 17, 65, 3, 55, 114, 0, 182, 2, 17, 65, 3, 16, 0, 182, 3, 55, 0, 7, 6, 225, 135, 0, 128, 2, 17, 65, 3, 47, 107, 0, 128, 225, 132, 130, 3, 50, 50, 0, 128, 225, 132, 134, 3, 65, 65, 0, 128, 2, 18, 67, 3, 76, 107, 38, 0, 128, 3, 112, 0, 129, 3, 48, 0, 129, 2, 17, 65, 3, 114, 0, 130, 2, 17, 65, 3, 0, 130, 3, 112, 0, 7, 6, 0, 4, 46, 3, 0, 203, 144, 3, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts35 = FileInMemory_createWithData (6487, reinterpret_cast (&espeakdata_dicts35_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/ko_dict", U"ko"); Collection_addItem (me.peek(), espeakdata_dicts35.transfer()); static unsigned char espeakdata_dicts36_data[2277] = { 0, 4, 0, 0, 124, 7, 0, 0, 0, 0, 0, 0, 0, 4, 193, 4, 76, 0, 0, 0, 0, 6, 65, 8, 71, 36, 0, 0, 0, 0, 0, 6, 65, 12, 75, 36, 0, 0, 0, 0, 0, 6, 65, 16, 72, 36, 0, 0, 0, 6, 195, 92, 19, 128, 76, 0, 0, 0, 0, 0, 0, 6, 65, 24, 83, 36, 0, 0, 0, 0, 0, 6, 65, 28, 81, 36, 0, 0, 0, 0, 0, 6, 65, 32, 107, 36, 0, 0, 0, 0, 0, 0, 8, 1, 37, 89, 109, 72, 36, 0, 0, 0, 0, 6, 65, 40, 90, 36, 0, 0, 0, 9, 1, 42, 89, 47, 36, 51, 49, 0, 0, 0, 6, 65, 44, 49, 36, 0, 0, 0, 0, 0, 6, 65, 48, 55, 36, 0, 0, 0, 0, 0, 6, 65, 52, 65, 36, 0, 0, 0, 0, 0, 6, 65, 56, 50, 36, 0, 10, 5, 95, 48, 1, 14, 4, 10, 40, 0, 0, 0, 6, 195, 44, 148, 128, 72, 0, 0, 0, 0, 0, 0, 6, 65, 64, 48, 36, 0, 0, 0, 0, 0, 6, 65, 68, 104, 36, 0, 0, 0, 0, 0, 6, 65, 72, 51, 36, 0, 0, 0, 0, 0, 6, 65, 76, 89, 36, 0, 0, 0, 0, 0, 6, 65, 80, 47, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 88, 84, 36, 0, 0, 0, 0, 0, 6, 65, 92, 58, 36, 0, 0, 0, 0, 0, 6, 65, 96, 101, 36, 0, 13, 4, 95, 49, 77, 49, 107, 109, 88, 6, 35, 34, 0, 0, 14, 4, 95, 49, 77, 50, 65, 124, 55, 6, 57, 39, 50, 0, 0, 0, 0, 6, 65, 100, 57, 36, 0, 0, 0, 0, 0, 6, 65, 104, 88, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 131, 23, 195, 174, 76, 0, 0, 0, 0, 6, 131, 23, 195, 170, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 4, 226, 137, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 16, 80, 72, 5, 194, 8, 144, 72, 0, 0, 0, 0, 0, 0, 11, 4, 95, 4, 16, 20, 10, 101, 35, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 131, 25, 195, 170, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 4, 224, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 16, 144, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 21, 160, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 8, 84, 192, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 14, 5, 2, 195, 187, 65, 0, 0, 0, 18, 67, 33, 113, 0, 107, 109, 34, 15, 58, 109, 49, 37, 15, 72, 124, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 3, 95, 51, 88, 89, 6, 37, 0, 0, 10, 3, 95, 48, 67, 89, 6, 109, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 95, 49, 67, 89, 6, 109, 72, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 49, 57, 50, 39, 88, 72, 6, 109, 107, 0, 0, 13, 3, 95, 49, 56, 107, 124, 90, 72, 6, 109, 107, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 49, 49, 57, 35, 88, 72, 6, 125, 0, 0, 10, 3, 95, 49, 48, 72, 6, 109, 107, 0, 0, 12, 3, 95, 49, 51, 89, 36, 88, 72, 6, 125, 0, 0, 13, 3, 95, 49, 50, 72, 35, 50, 88, 72, 6, 125, 0, 0, 13, 3, 95, 49, 53, 48, 35, 50, 88, 72, 6, 125, 0, 0, 12, 3, 95, 49, 52, 76, 35, 51, 72, 6, 125, 0, 0, 13, 3, 95, 49, 55, 107, 124, 84, 72, 6, 109, 107, 0, 0, 13, 3, 95, 49, 54, 91, 35, 50, 88, 72, 6, 125, 0, 0, 0, 12, 3, 95, 55, 88, 107, 109, 83, 47, 6, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 131, 12, 195, 170, 76, 0, 0, 0, 0, 0, 0, 11, 3, 95, 50, 88, 71, 6, 124, 89, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 95, 63, 63, 47, 37, 48, 35, 0, 0, 0, 0, 10, 3, 95, 52, 88, 76, 6, 124, 55, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 40, 144, 72, 0, 12, 3, 95, 53, 88, 48, 36, 50, 75, 6, 37, 0, 0, 0, 6, 195, 28, 245, 0, 72, 0, 0, 0, 0, 0, 0, 11, 3, 95, 54, 88, 91, 6, 36, 89, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 56, 88, 107, 36, 91, 47, 6, 36, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 52, 80, 76, 0, 10, 3, 95, 57, 88, 50, 6, 39, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 100, 19, 128, 72, 0, 0, 0, 14, 4, 95, 48, 77, 50, 65, 124, 55, 6, 57, 39, 50, 0, 0, 0, 0, 13, 4, 95, 48, 77, 49, 107, 109, 88, 6, 35, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 131, 195, 170, 14, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 95, 195, 187, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 95, 195, 174, 37, 0, 0, 0, 0, 0, 7, 3, 95, 195, 170, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 72, 80, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 195, 167, 76, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 197, 159, 91, 36, 0, 0, 0, 0, 5, 130, 195, 170, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 80, 80, 76, 0, 0, 0, 6, 130, 195, 187, 76, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 2, 95, 1, 35, 0, 0, 0, 0, 0, 6, 2, 95, 5, 109, 0, 0, 0, 0, 6, 2, 95, 9, 124, 0, 0, 0, 6, 2, 95, 15, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 2, 95, 21, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 2, 95, 33, 71, 35, 50, 109, 91, 6, 35, 50, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 95, 3, 1, 16, 65, 36, 88, 37, 50, 0, 0, 0, 0, 0, 8, 2, 95, 46, 101, 35, 55, 0, 0, 11, 2, 95, 45, 71, 109, 50, 72, 124, 49, 0, 0, 11, 2, 95, 44, 71, 36, 107, 50, 39, 49, 0, 0, 8, 2, 95, 51, 89, 6, 36, 0, 0, 8, 2, 95, 50, 72, 6, 111, 0, 0, 9, 2, 95, 49, 57, 6, 109, 49, 0, 0, 10, 2, 95, 48, 89, 6, 124, 83, 34, 0, 0, 10, 2, 95, 55, 107, 6, 109, 83, 47, 0, 0, 9, 2, 95, 54, 91, 6, 109, 91, 0, 0, 10, 2, 95, 53, 48, 6, 36, 50, 75, 0, 0, 9, 2, 95, 52, 75, 6, 35, 34, 0, 0, 14, 2, 95, 59, 101, 35, 55, 71, 36, 107, 50, 39, 49, 0, 0, 11, 2, 95, 58, 75, 39, 47, 101, 35, 55, 0, 0, 9, 2, 95, 57, 50, 6, 109, 107, 0, 0, 5, 194, 100, 16, 72, 5, 194, 92, 80, 76, 11, 2, 95, 56, 107, 6, 109, 57, 91, 47, 0, 0, 15, 2, 95, 63, 48, 124, 51, 89, 50, 37, 91, 6, 35, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 132, 25, 195, 170, 14, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 18, 66, 195, 174, 0, 105, 121, 0, 195, 170, 0, 101, 119, 0, 101, 121, 0, 7, 6, 195, 167, 0, 3, 76, 0, 7, 6, 195, 170, 0, 1, 21, 2, 32, 14, 128, 128, 129, 3, 2, 36, 0, 110, 1, 21, 2, 32, 14, 128, 128, 130, 3, 2, 36, 50, 0, 3, 36, 0, 7, 6, 195, 174, 0, 3, 37, 0, 7, 6, 195, 187, 0, 3, 40, 0, 7, 6, 197, 159, 0, 3, 91, 0, 7, 6, 97, 0, 1, 21, 2, 32, 14, 128, 128, 129, 3, 2, 35, 0, 110, 1, 21, 2, 32, 14, 128, 128, 130, 3, 2, 35, 50, 0, 3, 35, 0, 7, 6, 98, 0, 3, 71, 0, 7, 6, 99, 0, 3, 75, 0, 7, 6, 100, 0, 3, 72, 0, 7, 6, 101, 0, 3, 109, 0, 119, 3, 115, 0, 121, 3, 118, 0, 2, 32, 3, 125, 0, 7, 6, 102, 0, 3, 83, 0, 7, 6, 103, 0, 2, 18, 66, 3, 79, 0, 3, 81, 0, 7, 6, 104, 0, 3, 107, 0, 7, 6, 105, 0, 3, 124, 0, 7, 6, 106, 0, 3, 90, 0, 7, 6, 107, 0, 3, 49, 0, 2, 18, 66, 3, 80, 0, 7, 6, 108, 0, 3, 55, 0, 7, 6, 109, 0, 3, 65, 0, 7, 6, 110, 0, 3, 50, 0, 7, 6, 111, 0, 3, 39, 0, 7, 6, 112, 0, 3, 48, 0, 7, 6, 113, 0, 3, 104, 0, 7, 6, 114, 0, 1, 17, 65, 2, 17, 65, 3, 16, 0, 4, 3, 51, 0, 114, 0, 7, 6, 115, 0, 3, 89, 0, 7, 6, 116, 0, 3, 47, 0, 7, 6, 117, 0, 3, 111, 0, 7, 6, 118, 0, 3, 84, 0, 7, 6, 119, 0, 3, 58, 0, 7, 6, 120, 0, 3, 101, 0, 119, 101, 3, 101, 58, 126, 0, 7, 6, 121, 0, 3, 57, 0, 7, 6, 122, 0, 3, 88, 0, 7, 6, 0, 36, 3, 72, 111, 55, 35, 34, 0, 195, 188, 3, 112, 0, 195, 182, 3, 124, 12, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts36 = FileInMemory_createWithData (2276, reinterpret_cast (&espeakdata_dicts36_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/ku_dict", U"ku"); Collection_addItem (me.peek(), espeakdata_dicts36.transfer()); static unsigned char espeakdata_dicts37_data[3818] = { 0, 4, 0, 0, 55, 11, 0, 0, 11, 136, 6, 21, 196, 171, 19, 20, 9, 19, 72, 0, 0, 0, 0, 6, 195, 76, 144, 137, 72, 6, 195, 69, 80, 69, 72, 6, 195, 69, 80, 69, 72, 0, 4, 193, 4, 72, 5, 65, 4, 112, 0, 0, 6, 131, 5, 196, 171, 72, 0, 7, 132, 6, 21, 196, 171, 72, 0, 7, 196, 37, 86, 20, 4, 72, 0, 6, 65, 8, 71, 113, 0, 0, 0, 0, 6, 195, 69, 80, 77, 72, 0, 6, 65, 12, 49, 113, 0, 0, 0, 0, 0, 6, 65, 16, 72, 113, 0, 0, 0, 10, 199, 65, 35, 208, 80, 84, 133, 4, 8, 6, 195, 21, 83, 64, 72, 0, 0, 4, 193, 20, 72, 5, 65, 20, 113, 0, 0, 0, 0, 6, 195, 76, 147, 133, 72, 6, 195, 64, 243, 133, 72, 0, 6, 65, 24, 108, 83, 0, 0, 0, 0, 0, 6, 65, 28, 81, 113, 0, 0, 0, 0, 7, 196, 21, 53, 9, 76, 72, 0, 6, 65, 32, 107, 112, 0, 0, 0, 0, 6, 195, 21, 68, 201, 8, 0, 10, 65, 36, 6, 116, 50, 111, 89, 0, 41, 5, 65, 36, 114, 0, 0, 0, 0, 0, 0, 0, 0, 11, 136, 6, 21, 196, 147, 18, 21, 14, 20, 72, 0, 6, 65, 44, 49, 112, 0, 0, 0, 7, 132, 5, 196, 171, 19, 72, 0, 6, 195, 4, 229, 5, 72, 0, 6, 65, 48, 108, 55, 0, 0, 0, 10, 199, 65, 32, 69, 80, 84, 133, 4, 72, 0, 0, 6, 65, 52, 108, 65, 0, 0, 0, 0, 21, 2, 1, 46, 6, 35, 50, 47, 108, 15, 72, 6, 109, 38, 108, 65, 0, 81, 100, 46, 32, 29, 2, 1, 46, 35, 71, 15, 58, 51, 71, 4, 108, 15, 49, 110, 50, 72, 6, 114, 47, 35, 0, 82, 117, 46, 32, 99, 46, 32, 0, 6, 65, 56, 108, 50, 0, 0, 0, 0, 0, 5, 65, 60, 115, 0, 0, 0, 0, 0, 6, 65, 64, 48, 113, 0, 0, 10, 135, 6, 21, 5, 18, 196, 129, 19, 72, 5, 194, 4, 32, 72, 0, 0, 0, 7, 65, 68, 49, 58, 116, 0, 0, 0, 0, 0, 6, 65, 72, 108, 34, 0, 0, 0, 0, 0, 6, 65, 76, 108, 89, 0, 0, 0, 0, 22, 2, 4, 46, 72, 4, 114, 89, 15, 65, 6, 112, 50, 109, 71, 111, 89, 0, 81, 77, 46, 32, 0, 6, 65, 80, 47, 113, 0, 0, 5, 194, 4, 48, 72, 0, 0, 0, 5, 65, 84, 116, 0, 0, 0, 0, 0, 5, 65, 88, 116, 0, 0, 0, 0, 0, 8, 197, 69, 82, 66, 85, 48, 72, 0, 0, 0, 0, 7, 65, 96, 108, 49, 89, 0, 0, 9, 198, 36, 64, 201, 72, 51, 192, 8, 5, 194, 4, 64, 72, 0, 0, 0, 5, 65, 100, 114, 0, 0, 0, 0, 0, 9, 65, 104, 6, 88, 113, 47, 35, 0, 0, 5, 194, 5, 64, 8, 0, 0, 6, 195, 20, 226, 77, 8, 0, 0, 9, 198, 25, 81, 82, 21, 83, 148, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 65, 35, 208, 20, 72, 16, 2, 9, 46, 4, 109, 72, 15, 108, 89, 47, 0, 81, 101, 46, 32, 0, 0, 0, 0, 0, 0, 0, 6, 195, 5, 85, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 21, 32, 78, 80, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 69, 83, 196, 8, 6, 195, 69, 83, 196, 72, 0, 0, 0, 0, 6, 195, 64, 244, 212, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 198, 65, 35, 208, 37, 84, 192, 72, 0, 0, 7, 196, 81, 32, 78, 76, 72, 0, 0, 0, 0, 0, 0, 5, 194, 20, 16, 72, 0, 0, 0, 0, 0, 0, 7, 196, 77, 83, 85, 76, 72, 7, 196, 77, 84, 18, 4, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 16, 80, 72, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 21, 48, 72, 0, 0, 7, 196, 65, 35, 213, 80, 8, 0, 0, 0, 6, 195, 21, 53, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 21, 64, 72, 28, 0, 0, 0, 0, 0, 7, 132, 9, 196, 171, 19, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 21, 66, 65, 52, 8, 0, 0, 0, 0, 7, 196, 69, 83, 193, 16, 8, 0, 0, 0, 0, 0, 0, 9, 134, 6, 21, 5, 18, 197, 141, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 25, 82, 84, 72, 0, 8, 133, 5, 18, 196, 129, 13, 72, 7, 196, 64, 83, 133, 76, 72, 0, 0, 5, 194, 21, 128, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 80, 144, 137, 72, 0, 0, 0, 8, 197, 21, 34, 84, 37, 48, 72, 0, 8, 133, 5, 18, 196, 129, 19, 72, 0, 0, 0, 8, 133, 5, 18, 196, 129, 20, 72, 15, 67, 36, 33, 0, 6, 109, 71, 114, 15, 72, 4, 108, 65, 0, 0, 14, 66, 36, 32, 6, 109, 71, 114, 15, 72, 4, 108, 65, 0, 0, 6, 195, 56, 80, 192, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 132, 5, 18, 197, 141, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 12, 148, 131, 4, 72, 0, 0, 5, 194, 36, 64, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 51, 88, 47, 14, 16, 114, 81, 6, 109, 50, 47, 112, 0, 0, 13, 3, 95, 48, 67, 49, 6, 108, 50, 47, 111, 65, 0, 0, 0, 6, 195, 65, 32, 69, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 3, 95, 49, 57, 116, 50, 72, 108, 58, 109, 81, 6, 109, 50, 47, 109, 0, 0, 19, 3, 95, 49, 56, 72, 111, 110, 72, 108, 58, 109, 81, 6, 109, 50, 47, 109, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 49, 49, 6, 116, 50, 72, 108, 49, 109, 65, 0, 6, 195, 52, 146, 9, 72, 0, 12, 3, 95, 49, 48, 72, 6, 108, 49, 108, 65, 0, 0, 17, 3, 95, 49, 51, 47, 14, 16, 4, 113, 72, 6, 108, 49, 109, 65, 0, 0, 15, 3, 95, 49, 50, 72, 111, 6, 110, 72, 108, 49, 109, 65, 0, 0, 17, 3, 95, 49, 53, 49, 58, 4, 114, 50, 72, 6, 108, 49, 109, 65, 0, 0, 20, 3, 95, 49, 52, 49, 58, 35, 47, 12, 58, 6, 110, 51, 72, 108, 49, 109, 65, 0, 0, 18, 3, 95, 49, 55, 89, 108, 48, 47, 6, 108, 50, 72, 108, 49, 109, 65, 0, 0, 14, 3, 95, 49, 54, 89, 6, 108, 72, 108, 49, 109, 65, 0, 0, 0, 18, 3, 95, 55, 88, 89, 108, 48, 47, 111, 112, 81, 6, 109, 50, 47, 112, 0, 0, 6, 131, 19, 21, 63, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 5, 5, 68, 72, 0, 0, 11, 136, 6, 21, 196, 171, 19, 20, 196, 171, 72, 0, 10, 66, 36, 144, 72, 6, 111, 110, 0, 42, 7, 66, 36, 144, 109, 109, 0, 0, 0, 7, 196, 36, 229, 5, 72, 72, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 50, 88, 58, 114, 81, 6, 109, 50, 47, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 21, 37, 78, 80, 72, 0, 0, 0, 19, 3, 95, 52, 88, 49, 58, 35, 72, 14, 16, 112, 81, 6, 109, 50, 47, 112, 0, 0, 7, 196, 5, 68, 85, 36, 8, 0, 0, 0, 0, 0, 8, 197, 77, 80, 148, 21, 32, 72, 0, 0, 19, 3, 95, 53, 88, 49, 58, 114, 68, 49, 58, 112, 81, 6, 109, 50, 47, 112, 0, 0, 7, 196, 36, 225, 146, 4, 72, 0, 0, 0, 0, 0, 0, 0, 17, 3, 95, 54, 88, 89, 108, 49, 89, 112, 81, 6, 109, 50, 47, 112, 0, 0, 7, 196, 5, 68, 85, 20, 8, 0, 0, 9, 198, 88, 84, 212, 73, 83, 64, 72, 0, 6, 195, 20, 19, 64, 72, 0, 7, 196, 69, 80, 83, 36, 8, 0, 0, 0, 0, 6, 131, 20, 21, 63, 72, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 56, 88, 110, 49, 47, 115, 81, 6, 109, 50, 47, 112, 0, 0, 0, 7, 132, 13, 5, 196, 171, 72, 0, 0, 0, 0, 0, 0, 16, 3, 95, 57, 88, 50, 115, 50, 112, 81, 6, 109, 50, 47, 112, 0, 0, 6, 131, 13, 196, 147, 72, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 20, 149, 83, 72, 0, 8, 197, 21, 34, 77, 85, 48, 72, 0, 0, 0, 10, 135, 5, 18, 196, 129, 13, 21, 19, 72, 0, 7, 132, 17, 21, 196, 171, 72, 0, 12, 137, 6, 21, 5, 18, 196, 129, 13, 21, 19, 72, 0, 5, 194, 60, 32, 72, 5, 194, 36, 224, 72, 5, 194, 36, 224, 72, 0, 0, 0, 12, 137, 6, 21, 5, 18, 196, 171, 13, 21, 19, 72, 0, 9, 198, 65, 32, 69, 80, 84, 128, 72, 0, 0, 0, 0, 9, 198, 25, 81, 82, 84, 229, 0, 72, 0, 0, 0, 0, 10, 135, 6, 21, 5, 18, 196, 171, 19, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 65, 35, 192, 72, 0, 0, 0, 0, 6, 195, 77, 83, 64, 72, 6, 195, 13, 83, 64, 72, 5, 195, 56, 243, 128, 0, 8, 133, 17, 21, 197, 141, 19, 72, 0, 13, 4, 95, 48, 77, 49, 65, 6, 109, 55, 55, 108, 0, 8, 197, 25, 82, 77, 85, 48, 72, 0, 0, 0, 0, 12, 201, 69, 81, 77, 4, 67, 79, 17, 83, 64, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 198, 69, 80, 77, 69, 80, 77, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 12, 148, 131, 84, 208, 72, 0, 0, 0, 0, 0, 0, 0, 8, 133, 17, 21, 196, 129, 19, 72, 0, 0, 9, 198, 56, 244, 212, 73, 83, 64, 72, 0, 0, 0, 0, 0, 6, 195, 77, 80, 128, 72, 0, 0, 0, 0, 6, 195, 77, 83, 148, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 21, 65, 78, 36, 208, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 135, 14, 197, 141, 2, 196, 171, 19, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 198, 76, 80, 213, 56, 69, 77, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 77, 83, 148, 60, 72, 0, 0, 0, 6, 195, 21, 34, 84, 72, 0, 0, 0, 6, 195, 21, 34, 83, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 76, 80, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 84, 197, 18, 4, 72, 7, 196, 36, 229, 18, 4, 72, 0, 8, 197, 21, 53, 15, 80, 80, 72, 8, 197, 12, 243, 148, 72, 16, 72, 0, 0, 0, 0, 0, 0, 6, 195, 56, 19, 64, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 21, 53, 5, 72, 0, 0, 9, 198, 69, 80, 77, 16, 149, 64, 8, 10, 135, 22, 197, 141, 2, 196, 171, 19, 72, 0, 0, 0, 8, 197, 25, 81, 82, 5, 64, 72, 0, 6, 195, 21, 53, 15, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 5, 197, 141, 18, 21, 13, 72, 0, 0, 0, 0, 0, 9, 198, 65, 35, 208, 80, 84, 128, 72, 0, 0, 0, 0, 6, 195, 21, 33, 193, 72, 0, 0, 6, 195, 21, 33, 207, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 17, 83, 64, 8, 0, 0, 0, 0, 6, 195, 64, 84, 128, 72, 0, 0, 0, 10, 135, 17, 21, 196, 129, 18, 21, 13, 72, 0, 11, 2, 95, 51, 47, 14, 16, 4, 113, 89, 0, 0, 9, 2, 95, 50, 72, 6, 111, 110, 0, 0, 10, 2, 95, 49, 6, 116, 50, 111, 89, 0, 0, 11, 2, 95, 48, 50, 6, 111, 55, 55, 35, 0, 0, 12, 2, 95, 55, 89, 6, 108, 48, 47, 108, 65, 0, 0, 10, 2, 95, 54, 89, 4, 108, 49, 89, 0, 0, 13, 2, 95, 53, 49, 58, 6, 114, 68, 49, 58, 108, 0, 0, 14, 2, 95, 52, 49, 58, 6, 35, 47, 12, 111, 110, 51, 0, 0, 0, 0, 11, 2, 95, 57, 50, 6, 110, 58, 108, 65, 0, 0, 10, 2, 95, 56, 6, 110, 49, 47, 115, 0, 0, 0, 0, 0, 10, 135, 17, 21, 197, 141, 18, 21, 13, 72, 0, 0, 0, 8, 197, 56, 19, 81, 84, 80, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 36, 65, 79, 8, 0, 0, 0, 0, 7, 196, 77, 84, 5, 72, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 67, 36, 66, 66, 6, 114, 72, 109, 71, 111, 89, 0, 0, 11, 66, 88, 144, 89, 4, 108, 49, 89, 0, 42, 7, 66, 88, 144, 58, 109, 0, 0, 0, 0, 9, 134, 5, 196, 129, 18, 21, 13, 72, 0, 0, 0, 0, 0, 0, 0, 0, 7, 132, 5, 196, 129, 19, 72, 0, 12, 137, 6, 21, 5, 18, 196, 171, 20, 9, 19, 72, 0, 0, 0, 0, 12, 137, 6, 21, 5, 18, 196, 129, 20, 9, 19, 72, 0, 14, 67, 36, 68, 64, 114, 72, 6, 108, 65, 49, 58, 108, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 56, 148, 201, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 25, 81, 82, 4, 208, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 131, 20, 196, 147, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 5, 85, 5, 52, 8, 0, 7, 132, 5, 197, 141, 19, 72, 0, 0, 0, 0, 8, 197, 88, 84, 147, 85, 48, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 21, 133, 18, 4, 72, 0, 0, 0, 0, 0, 0, 0, 9, 198, 65, 35, 216, 36, 213, 83, 72, 0, 10, 135, 5, 18, 196, 129, 20, 9, 19, 72, 0, 0, 0, 0, 0, 0, 6, 131, 5, 196, 129, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 25, 81, 82, 37, 64, 72, 0, 6, 131, 5, 197, 141, 72, 0, 0, 0, 8, 197, 69, 80, 78, 16, 240, 8, 0, 0, 0, 0, 0, 0, 0, 0, 6, 20, 0, 0, 0, 226, 0, 0, 0, 1, 1, 0, 0, 234, 0, 0, 0, 19, 1, 0, 0, 238, 0, 0, 0, 43, 1, 0, 0, 244, 0, 0, 0, 77, 1, 0, 0, 251, 0, 0, 0, 107, 1, 0, 0, 119, 1, 0, 0, 121, 0, 121, 0, 0, 0, 0, 0, 6, 18, 66, 97, 101, 0, 97, 117, 0, 101, 117, 0, 111, 101, 0, 121, 121, 0, 196, 129, 0, 196, 147, 0, 196, 171, 0, 197, 141, 0, 197, 171, 0, 195, 171, 0, 195, 188, 0, 195, 169, 0, 195, 166, 0, 97, 0, 101, 0, 105, 0, 111, 0, 117, 0, 121, 0, 7, 6, 18, 67, 99, 104, 114, 0, 110, 103, 0, 113, 117, 0, 112, 114, 0, 116, 114, 0, 99, 114, 0, 98, 114, 0, 100, 114, 0, 103, 114, 0, 112, 108, 0, 99, 108, 0, 98, 108, 0, 103, 108, 0, 112, 104, 0, 116, 104, 0, 99, 104, 0, 7, 6, 113, 117, 0, 3, 49, 58, 0, 7, 6, 195, 166, 0, 3, 120, 0, 7, 6, 196, 129, 0, 3, 112, 0, 7, 6, 196, 147, 0, 3, 113, 0, 7, 6, 196, 171, 0, 3, 114, 0, 7, 6, 197, 141, 0, 3, 115, 0, 7, 6, 197, 171, 0, 3, 116, 0, 7, 6, 97, 0, 4, 2, 17, 67, 18, 66, 29, 3, 8, 35, 0, 2, 18, 66, 29, 0, 2, 18, 67, 18, 66, 29, 0, 2, 103, 117, 18, 66, 29, 0, 4, 3, 35, 0, 2, 120, 12, 0, 117, 2, 12, 12, 12, 3, 119, 0, 101, 2, 12, 12, 12, 3, 120, 0, 7, 6, 98, 0, 3, 71, 0, 98, 3, 71, 12, 0, 7, 6, 99, 0, 3, 49, 0, 99, 3, 49, 12, 0, 99, 104, 3, 49, 12, 124, 0, 104, 3, 49, 124, 0, 7, 6, 100, 0, 3, 72, 0, 100, 3, 72, 12, 0, 7, 6, 101, 0, 4, 2, 17, 67, 18, 66, 29, 3, 8, 108, 0, 2, 18, 66, 29, 0, 2, 18, 67, 18, 66, 29, 0, 2, 103, 117, 18, 66, 29, 0, 4, 3, 108, 0, 2, 120, 12, 0, 117, 2, 12, 12, 12, 3, 122, 0, 7, 6, 102, 0, 3, 83, 0, 102, 3, 83, 12, 0, 7, 6, 103, 0, 2, 110, 3, 68, 0, 3, 81, 0, 103, 3, 81, 12, 0, 103, 117, 2, 17, 65, 3, 81, 12, 58, 0, 117, 2, 17, 65, 3, 81, 58, 0, 7, 6, 104, 0, 3, 107, 0, 58, 3, 107, 12, 0, 7, 6, 105, 0, 4, 1, 117, 17, 65, 2, 18, 66, 29, 12, 12, 3, 8, 109, 0, 1, 117, 103, 2, 18, 66, 29, 12, 12, 0, 1, 117, 113, 2, 18, 66, 29, 12, 12, 0, 2, 17, 67, 18, 66, 29, 0, 2, 18, 66, 29, 0, 2, 18, 67, 18, 66, 29, 0, 2, 103, 117, 18, 66, 29, 0, 8, 117, 2, 18, 66, 29, 12, 12, 0, 2, 105, 29, 3, 8, 109, 19, 0, 8, 2, 17, 65, 3, 57, 0, 4, 1, 17, 65, 2, 17, 65, 12, 3, 57, 12, 0, 1, 117, 97, 2, 17, 65, 12, 12, 12, 0, 1, 117, 101, 2, 17, 65, 12, 12, 12, 0, 4, 3, 109, 0, 1, 117, 17, 65, 2, 17, 65, 12, 12, 0, 1, 117, 103, 2, 17, 65, 12, 12, 0, 1, 117, 113, 2, 17, 65, 12, 12, 0, 2, 120, 12, 0, 8, 117, 2, 17, 65, 12, 12, 0, 2, 105, 3, 109, 19, 0, 7, 6, 107, 0, 3, 49, 0, 107, 3, 49, 12, 0, 7, 6, 108, 0, 3, 55, 0, 108, 3, 55, 12, 0, 7, 6, 109, 0, 3, 65, 0, 109, 3, 65, 12, 0, 7, 6, 110, 0, 3, 50, 0, 110, 3, 50, 12, 0, 4, 2, 99, 3, 68, 0, 2, 103, 0, 2, 107, 0, 2, 113, 0, 2, 120, 0, 7, 6, 111, 0, 4, 2, 17, 67, 18, 66, 29, 3, 8, 110, 0, 2, 18, 66, 29, 0, 2, 18, 67, 18, 66, 29, 0, 2, 103, 117, 18, 66, 29, 0, 4, 3, 110, 0, 2, 120, 12, 0, 101, 2, 12, 12, 12, 3, 123, 0, 7, 6, 112, 0, 3, 48, 0, 112, 3, 48, 12, 0, 112, 104, 3, 48, 12, 124, 0, 104, 3, 48, 124, 0, 7, 6, 114, 0, 1, 17, 67, 3, 14, 16, 0, 4, 3, 51, 0, 1, 17, 65, 2, 17, 65, 0, 8, 0, 114, 3, 51, 16, 0, 7, 6, 115, 0, 3, 89, 0, 115, 3, 89, 12, 0, 7, 6, 116, 0, 3, 47, 0, 116, 3, 47, 12, 0, 116, 104, 3, 47, 12, 124, 0, 104, 3, 47, 124, 0, 7, 6, 117, 0, 4, 2, 17, 67, 18, 66, 29, 3, 8, 111, 0, 2, 18, 66, 29, 0, 2, 18, 67, 18, 66, 29, 0, 2, 103, 117, 18, 66, 29, 0, 4, 1, 17, 65, 2, 17, 65, 12, 12, 3, 58, 0, 8, 2, 17, 65, 12, 0, 4, 3, 111, 0, 2, 120, 12, 0, 7, 6, 118, 0, 4, 3, 58, 0, 8, 0, 118, 2, 12, 12, 12, 3, 58, 12, 0, 7, 6, 120, 0, 3, 49, 89, 0, 7, 6, 121, 0, 3, 117, 0, 121, 3, 118, 0, 7, 6, 122, 0, 3, 88, 0, 4, 1, 17, 65, 2, 17, 65, 3, 88, 12, 0, 122, 0, 7, 6, 0, 106, 3, 57, 0, 119, 3, 58, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts37 = FileInMemory_createWithData (3817, reinterpret_cast (&espeakdata_dicts37_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/la_dict", U"la"); Collection_addItem (me.peek(), espeakdata_dicts37.transfer()); static unsigned char espeakdata_dicts38_data[5185] = { 0, 4, 0, 0, 87, 12, 0, 0, 0, 0, 0, 0, 0, 5, 65, 4, 35, 0, 0, 0, 0, 0, 7, 65, 8, 71, 38, 112, 0, 0, 0, 0, 0, 7, 65, 12, 133, 38, 112, 0, 0, 0, 0, 0, 6, 65, 16, 135, 112, 0, 0, 0, 0, 0, 6, 65, 20, 36, 35, 0, 0, 0, 0, 0, 6, 65, 24, 36, 83, 0, 0, 0, 0, 0, 6, 65, 28, 81, 112, 0, 0, 0, 0, 0, 6, 65, 32, 107, 35, 0, 0, 0, 0, 0, 13, 1, 36, 72, 6, 117, 137, 36, 34, 38, 37, 89, 0, 5, 65, 36, 37, 0, 0, 13, 1, 37, 48, 34, 6, 116, 133, 36, 50, 47, 121, 0, 0, 0, 0, 7, 65, 40, 57, 39, 47, 0, 0, 0, 14, 1, 42, 90, 84, 121, 81, 90, 72, 6, 118, 47, 112, 0, 0, 10, 1, 43, 48, 38, 137, 6, 40, 89, 0, 13, 67, 76, 21, 133, 89, 35, 84, 38, 6, 110, 10, 0, 0, 6, 65, 44, 49, 35, 0, 0, 0, 0, 25, 1, 47, 135, 36, 91, 37, 136, 6, 114, 136, 37, 89, 10, 71, 34, 119, 49, 38, 97, 50, 6, 115, 89, 0, 0, 6, 65, 48, 36, 55, 0, 0, 0, 0, 0, 6, 65, 52, 36, 65, 0, 0, 11, 67, 53, 83, 83, 65, 118, 65, 89, 10, 0, 0, 0, 0, 6, 65, 56, 36, 50, 0, 0, 0, 0, 0, 5, 193, 60, 72, 8, 5, 65, 60, 117, 0, 0, 9, 1, 61, 137, 6, 115, 81, 40, 0, 0, 0, 0, 9, 1, 64, 6, 110, 47, 35, 9, 0, 7, 65, 64, 48, 38, 112, 0, 0, 0, 0, 0, 6, 65, 68, 49, 119, 0, 0, 0, 0, 0, 6, 65, 72, 36, 34, 0, 0, 0, 0, 0, 6, 65, 76, 36, 89, 0, 0, 0, 0, 0, 6, 65, 80, 134, 112, 0, 0, 0, 11, 70, 12, 243, 148, 36, 229, 69, 21, 0, 10, 0, 0, 5, 65, 84, 40, 0, 0, 0, 0, 0, 7, 65, 88, 84, 38, 112, 0, 0, 0, 0, 20, 4, 95, 49, 77, 52, 47, 34, 38, 37, 137, 37, 57, 6, 117, 50, 35, 89, 10, 0, 0, 24, 1, 92, 49, 121, 34, 38, 6, 114, 136, 37, 89, 10, 71, 34, 119, 49, 38, 97, 50, 6, 115, 89, 0, 16, 65, 92, 135, 84, 38, 6, 37, 81, 40, 71, 35, 10, 84, 112, 0, 0, 0, 0, 0, 19, 4, 95, 49, 77, 49, 47, 6, 119, 49, 89, 47, 35, 50, 134, 37, 89, 10, 0, 7, 65, 96, 37, 49, 89, 0, 0, 19, 4, 95, 49, 77, 50, 65, 38, 37, 137, 37, 57, 6, 117, 50, 35, 89, 10, 0, 0, 20, 4, 95, 49, 77, 51, 65, 38, 37, 137, 37, 57, 6, 109, 34, 72, 35, 89, 10, 0, 0, 0, 10, 65, 100, 115, 81, 34, 38, 36, 49, 0, 0, 0, 0, 0, 6, 65, 104, 94, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 52, 19, 137, 52, 144, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 8, 85, 0, 72, 8, 0, 7, 196, 53, 83, 73, 76, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 69, 72, 80, 68, 21, 32, 21, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 4, 95, 4, 16, 20, 10, 49, 35, 71, 137, 6, 36, 137, 37, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 41, 83, 73, 76, 66, 0, 0, 0, 0, 0, 0, 0, 6, 195, 9, 69, 128, 17, 10, 67, 80, 21, 64, 47, 108, 123, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 67, 48, 145, 84, 137, 127, 47, 6, 118, 84, 38, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 66, 29, 32, 81, 34, 6, 108, 37, 49, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 69, 53, 83, 89, 76, 80, 65, 40, 65, 38, 115, 95, 6, 110, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 69, 12, 19, 131, 20, 192, 21, 0, 10, 0, 0, 0, 0, 0, 13, 67, 80, 21, 133, 47, 35, 84, 38, 6, 110, 10, 0, 8, 66, 17, 160, 72, 88, 112, 0, 0, 0, 0, 0, 0, 0, 11, 67, 41, 83, 83, 57, 118, 65, 89, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 37, 32, 72, 8, 0, 12, 3, 226, 130, 172, 6, 110, 40, 34, 35, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 66, 20, 192, 36, 137, 36, 49, 47, 34, 39, 136, 37, 136, 37, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 19, 1, 22, 196, 153, 19, 66, 0, 0, 0, 0, 18, 3, 95, 51, 88, 47, 34, 38, 6, 114, 89, 135, 36, 97, 37, 65, 47, 0, 0, 19, 5, 95, 48, 77, 66, 49, 47, 6, 119, 49, 89, 47, 35, 50, 78, 40, 10, 0, 12, 3, 95, 48, 67, 97, 37, 65, 47, 121, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 49, 67, 97, 37, 65, 47, 35, 89, 10, 0, 0, 0, 0, 0, 0, 0, 18, 3, 95, 49, 57, 72, 36, 84, 38, 115, 136, 6, 117, 137, 37, 49, 35, 0, 0, 17, 3, 95, 49, 56, 35, 91, 47, 124, 136, 6, 117, 137, 37, 49, 35, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 49, 49, 84, 38, 127, 50, 6, 124, 137, 37, 49, 35, 0, 0, 13, 3, 95, 49, 48, 135, 6, 36, 97, 37, 65, 47, 0, 0, 15, 3, 95, 49, 51, 47, 34, 38, 6, 115, 137, 37, 49, 35, 0, 0, 15, 3, 95, 49, 50, 72, 84, 38, 6, 115, 137, 37, 49, 35, 0, 0, 18, 3, 95, 49, 53, 48, 38, 36, 50, 49, 38, 6, 117, 137, 37, 49, 35, 0, 0, 19, 3, 95, 49, 52, 49, 38, 36, 47, 40, 34, 38, 6, 117, 137, 37, 49, 35, 0, 0, 18, 3, 95, 49, 55, 95, 36, 48, 134, 115, 136, 6, 117, 137, 37, 49, 35, 0, 0, 15, 3, 95, 49, 54, 97, 36, 97, 6, 117, 137, 37, 49, 35, 0, 0, 0, 22, 3, 95, 55, 88, 95, 36, 48, 38, 134, 6, 115, 50, 36, 94, 135, 36, 97, 37, 65, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 49, 37, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 3, 95, 50, 88, 72, 84, 38, 6, 114, 135, 36, 97, 37, 65, 47, 0, 0, 20, 5, 95, 48, 77, 65, 49, 47, 6, 119, 49, 89, 47, 35, 50, 134, 37, 89, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 69, 76, 52, 133, 20, 224, 21, 0, 10, 0, 0, 0, 0, 0, 0, 22, 3, 95, 52, 88, 49, 38, 6, 113, 47, 40, 34, 38, 36, 94, 135, 36, 97, 37, 65, 47, 0, 0, 0, 0, 0, 0, 0, 0, 8, 66, 40, 144, 57, 114, 10, 0, 0, 22, 3, 95, 53, 88, 48, 38, 6, 110, 68, 38, 49, 38, 36, 94, 135, 36, 97, 37, 65, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 3, 95, 54, 88, 97, 6, 113, 97, 36, 94, 135, 36, 97, 37, 65, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 66, 57, 32, 50, 6, 40, 65, 38, 36, 34, 38, 37, 89, 0, 0, 21, 3, 95, 56, 88, 35, 91, 47, 6, 118, 39, 136, 36, 94, 135, 36, 97, 37, 65, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 3, 95, 57, 88, 135, 36, 84, 38, 6, 115, 136, 36, 94, 135, 36, 97, 37, 65, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 226, 153, 175, 72, 6, 127, 88, 35, 89, 0, 0, 0, 13, 3, 226, 153, 173, 71, 36, 65, 39, 55, 37, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 67, 52, 19, 133, 65, 35, 136, 6, 110, 10, 0, 19, 4, 95, 48, 77, 52, 47, 34, 38, 37, 137, 37, 57, 6, 117, 50, 121, 10, 0, 0, 0, 18, 4, 95, 48, 77, 50, 65, 38, 37, 137, 37, 57, 6, 117, 50, 121, 10, 0, 0, 11, 67, 52, 19, 128, 65, 108, 35, 50, 10, 0, 19, 4, 95, 48, 77, 51, 65, 38, 37, 137, 37, 57, 6, 109, 34, 72, 121, 10, 0, 0, 0, 18, 4, 95, 48, 77, 49, 47, 6, 119, 49, 89, 47, 35, 50, 78, 122, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 48, 179, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 3, 95, 194, 171, 55, 123, 90, 47, 6, 114, 50, 112, 89, 10, 49, 35, 71, 6, 118, 47, 112, 89, 0, 0, 0, 0, 0, 0, 0, 0, 18, 69, 80, 21, 153, 40, 80, 47, 35, 84, 38, 115, 57, 38, 6, 110, 10, 0, 0, 0, 13, 67, 48, 245, 0, 55, 39, 47, 6, 115, 50, 119, 0, 0, 0, 0, 0, 0, 0, 9, 134, 20, 1, 22, 196, 153, 19, 66, 9, 134, 13, 1, 14, 196, 153, 19, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 3, 95, 194, 187, 55, 123, 90, 47, 6, 114, 50, 112, 89, 10, 49, 35, 71, 6, 118, 47, 112, 89, 0, 0, 0, 0, 0, 0, 14, 2, 196, 133, 109, 10, 50, 117, 95, 6, 37, 136, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 196, 141, 78, 112, 0, 0, 0, 0, 0, 0, 0, 13, 2, 194, 167, 89, 6, 110, 49, 133, 37, 57, 35, 0, 6, 2, 196, 151, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 2, 194, 169, 123, 47, 39, 34, 6, 114, 50, 112, 89, 15, 47, 6, 122, 89, 112, 89, 0, 15, 2, 196, 153, 36, 35, 10, 50, 117, 95, 6, 37, 136, 112, 0, 0, 16, 2, 194, 182, 48, 35, 34, 35, 81, 34, 6, 109, 83, 35, 89, 0, 0, 0, 0, 0, 0, 0, 14, 2, 194, 176, 55, 6, 108, 121, 48, 89, 50, 37, 89, 0, 0, 15, 2, 194, 177, 48, 55, 40, 89, 10, 65, 37, 50, 40, 89, 0, 0, 26, 2, 194, 190, 47, 34, 6, 115, 89, 15, 49, 38, 36, 134, 84, 38, 37, 34, 47, 6, 35, 72, 35, 137, 122, 0, 0, 6, 2, 196, 175, 115, 0, 0, 21, 2, 194, 188, 49, 38, 36, 134, 84, 38, 37, 34, 47, 6, 35, 72, 35, 137, 37, 89, 0, 0, 10, 2, 194, 189, 48, 6, 118, 89, 112, 0, 0, 0, 0, 0, 7, 2, 197, 161, 36, 91, 0, 0, 0, 0, 0, 0, 0, 14, 2, 197, 171, 119, 10, 37, 55, 81, 6, 117, 57, 37, 0, 0, 0, 0, 0, 0, 8, 66, 81, 80, 47, 118, 10, 0, 0, 0, 0, 14, 2, 197, 179, 119, 10, 50, 117, 95, 6, 37, 136, 112, 0, 0, 0, 0, 7, 2, 197, 190, 96, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 49, 69, 128, 17, 0, 0, 0, 0, 0, 0, 18, 69, 76, 21, 153, 40, 80, 89, 35, 84, 38, 115, 57, 38, 6, 110, 10, 0, 0, 0, 12, 71, 52, 17, 206, 36, 98, 69, 72, 21, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 3, 1, 197, 161, 108, 91, 10, 0, 0, 0, 0, 0, 0, 14, 67, 72, 18, 128, 34, 35, 57, 6, 116, 50, 35, 89, 0, 0, 0, 0, 0, 0, 22, 2, 95, 34, 134, 6, 127, 95, 39, 95, 39, 89, 10, 49, 35, 71, 6, 118, 47, 112, 89, 0, 0, 14, 2, 95, 33, 91, 123, 49, 47, 6, 118, 49, 35, 89, 0, 0, 0, 16, 2, 95, 39, 35, 48, 39, 89, 47, 34, 6, 116, 83, 35, 89, 0, 0, 0, 0, 0, 0, 0, 16, 2, 95, 41, 95, 49, 38, 137, 6, 110, 58, 89, 47, 35, 89, 0, 0, 16, 2, 95, 40, 95, 49, 38, 137, 6, 110, 58, 89, 47, 35, 89, 0, 0, 0, 12, 2, 95, 46, 47, 6, 35, 91, 49, 35, 89, 0, 0, 11, 2, 95, 45, 65, 6, 114, 50, 40, 89, 0, 0, 14, 2, 95, 44, 49, 35, 71, 137, 6, 36, 137, 37, 89, 0, 0, 9, 2, 95, 51, 47, 34, 115, 89, 0, 0, 7, 2, 95, 50, 72, 40, 0, 0, 12, 2, 95, 49, 84, 38, 6, 127, 50, 35, 89, 0, 0, 11, 2, 95, 48, 50, 6, 40, 137, 37, 89, 0, 0, 13, 2, 95, 55, 95, 36, 48, 134, 115, 136, 6, 114, 0, 0, 10, 2, 95, 54, 97, 36, 91, 6, 114, 0, 0, 12, 2, 95, 53, 48, 38, 36, 50, 49, 6, 114, 0, 0, 13, 2, 95, 52, 49, 38, 36, 47, 40, 34, 6, 114, 0, 0, 19, 2, 95, 59, 49, 35, 71, 38, 137, 6, 36, 47, 35, 91, 49, 38, 37, 89, 0, 0, 17, 2, 95, 58, 135, 84, 38, 6, 114, 47, 35, 91, 49, 38, 37, 89, 0, 0, 12, 2, 95, 57, 135, 36, 84, 115, 136, 6, 114, 0, 0, 12, 2, 95, 56, 35, 91, 47, 124, 136, 6, 114, 0, 0, 15, 2, 95, 63, 49, 55, 123, 89, 47, 6, 118, 49, 35, 89, 0, 0, 0, 0, 0, 0, 0, 0, 9, 2, 95, 64, 6, 110, 47, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 4, 15, 20, 47, 6, 35, 91, 49, 35, 89, 0, 0, 0, 0, 27, 2, 95, 91, 55, 123, 90, 134, 6, 114, 38, 50, 37, 89, 10, 95, 49, 38, 137, 6, 110, 58, 89, 47, 35, 89, 0, 0, 0, 0, 0, 27, 2, 95, 95, 48, 35, 71, 34, 123, 49, 38, 6, 114, 65, 39, 10, 71, 34, 119, 49, 38, 97, 50, 6, 115, 89, 0, 0, 15, 2, 95, 94, 91, 35, 49, 50, 6, 114, 89, 10, 37, 91, 0, 0, 27, 2, 95, 93, 55, 123, 90, 134, 6, 114, 38, 50, 37, 89, 10, 95, 49, 38, 137, 6, 110, 58, 89, 47, 35, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 70, 92, 147, 132, 61, 116, 192, 21, 0, 10, 0, 10, 67, 40, 148, 192, 57, 114, 89, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 2, 95, 123, 34, 127, 89, 134, 6, 114, 38, 50, 37, 89, 10, 95, 49, 38, 137, 6, 110, 58, 89, 47, 35, 89, 0, 0, 0, 0, 0, 0, 11, 2, 95, 126, 47, 6, 114, 55, 72, 112, 0, 0, 27, 2, 95, 125, 34, 127, 89, 134, 6, 114, 38, 50, 37, 89, 10, 95, 49, 38, 137, 6, 110, 58, 89, 47, 35, 89, 0, 17, 69, 41, 83, 89, 76, 80, 57, 40, 65, 38, 115, 95, 6, 110, 10, 0, 0, 0, 11, 70, 24, 148, 133, 24, 246, 0, 21, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 76, 21, 137, 52, 144, 67, 8, 197, 80, 21, 137, 52, 144, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 48, 226, 192, 17, 0, 0, 17, 69, 52, 19, 153, 40, 80, 65, 35, 136, 115, 57, 38, 6, 110, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 3, 4, 197, 190, 75, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 67, 76, 21, 64, 89, 108, 123, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 18, 66, 100, 197, 190, 0, 197, 190, 0, 100, 122, 0, 98, 0, 100, 0, 103, 0, 122, 0, 104, 0, 7, 6, 18, 67, 197, 161, 0, 99, 104, 0, 196, 141, 0, 112, 0, 116, 0, 107, 0, 115, 0, 99, 0, 102, 0, 7, 6, 18, 69, 100, 197, 190, 0, 197, 190, 0, 100, 122, 0, 197, 161, 0, 99, 104, 0, 196, 141, 0, 98, 0, 100, 0, 103, 0, 122, 0, 104, 0, 112, 0, 116, 0, 107, 0, 115, 0, 99, 0, 102, 0, 108, 0, 109, 0, 110, 0, 114, 0, 106, 0, 118, 0, 7, 6, 18, 70, 196, 133, 0, 196, 153, 0, 196, 151, 0, 196, 175, 0, 197, 179, 0, 197, 171, 0, 97, 0, 101, 0, 105, 0, 121, 0, 111, 0, 117, 0, 7, 6, 18, 71, 196, 175, 0, 196, 153, 0, 196, 151, 0, 105, 0, 121, 0, 101, 0, 7, 6, 18, 75, 105, 117, 111, 115, 101, 0, 105, 97, 109, 115, 0, 105, 97, 105, 115, 0, 105, 117, 105, 0, 121, 106, 101, 0, 105, 97, 105, 0, 105, 197, 179, 0, 105, 117, 115, 0, 105, 115, 0, 105, 111, 0, 196, 175, 0, 105, 117, 0, 121, 106, 0, 121, 0, 7, 6, 18, 76, 105, 97, 109, 115, 0, 105, 97, 105, 115, 0, 105, 117, 111, 115, 0, 105, 97, 115, 0, 105, 117, 105, 0, 105, 196, 133, 0, 121, 106, 101, 0, 105, 97, 105, 0, 105, 197, 179, 0, 105, 117, 115, 0, 105, 111, 0, 105, 117, 0, 121, 106, 0, 121, 0, 7, 6, 18, 77, 117, 111, 115, 101, 0, 97, 109, 115, 0, 97, 105, 115, 0, 97, 115, 0, 117, 105, 0, 196, 133, 0, 97, 105, 0, 197, 179, 0, 117, 115, 0, 111, 0, 117, 0, 101, 0, 7, 6, 18, 78, 111, 109, 105, 115, 0, 111, 106, 101, 0, 111, 109, 115, 0, 111, 115, 101, 0, 111, 115, 0, 97, 105, 0, 196, 133, 0, 111, 106, 0, 111, 115, 0, 197, 179, 0, 97, 115, 0, 97, 0, 7, 6, 18, 79, 196, 151, 109, 105, 115, 0, 196, 151, 106, 101, 0, 196, 151, 109, 115, 0, 196, 151, 115, 101, 0, 196, 151, 115, 0, 196, 151, 106, 0, 105, 197, 179, 0, 196, 151, 109, 0, 196, 151, 0, 101, 105, 0, 196, 153, 0, 101, 0, 7, 6, 18, 86, 196, 141, 0, 116, 0, 7, 6, 18, 87, 100, 197, 190, 0, 100, 0, 7, 6, 196, 133, 0, 3, 109, 0, 7, 6, 196, 141, 0, 3, 76, 0, 2, 18, 71, 3, 78, 0, 7, 6, 196, 151, 0, 4, 3, 112, 0, 8, 112, 111, 107, 2, 196, 141, 105, 18, 78, 32, 0, 4, 1, 21, 2, 106, 18, 77, 32, 3, 112, 8, 0, 1, 21, 2, 106, 18, 78, 32, 0, 1, 21, 2, 110, 18, 77, 32, 0, 1, 21, 2, 110, 18, 79, 32, 0, 1, 21, 2, 196, 141, 105, 18, 78, 32, 0, 7, 6, 196, 153, 0, 3, 113, 0, 7, 6, 196, 175, 0, 3, 115, 0, 7, 6, 197, 161, 0, 2, 18, 66, 3, 90, 0, 4, 3, 91, 0, 197, 161, 0, 4, 2, 17, 67, 17, 67, 18, 71, 3, 97, 0, 2, 17, 67, 18, 71, 0, 2, 18, 71, 0, 7, 6, 197, 171, 0, 4, 1, 21, 2, 107, 197, 161, 18, 86, 18, 75, 32, 3, 118, 8, 40, 0, 1, 21, 2, 107, 197, 161, 18, 86, 18, 79, 32, 0, 3, 119, 0, 7, 6, 197, 179, 0, 3, 119, 0, 7, 6, 197, 190, 0, 115, 3, 89, 0, 4, 3, 90, 0, 197, 190, 0, 4, 2, 18, 67, 3, 91, 0, 2, 32, 0, 197, 161, 0, 4, 2, 17, 67, 17, 67, 18, 71, 3, 96, 0, 2, 17, 67, 18, 71, 0, 2, 18, 71, 0, 7, 6, 97, 0, 4, 3, 35, 0, 2, 105, 122, 109, 18, 77, 32, 0, 4, 105, 1, 21, 2, 18, 86, 18, 75, 32, 3, 35, 8, 114, 0, 105, 1, 21, 2, 18, 86, 18, 79, 32, 0, 4, 105, 1, 21, 2, 110, 18, 75, 32, 3, 108, 8, 37, 0, 105, 1, 21, 2, 110, 18, 79, 32, 0, 105, 8, 109, 101, 190, 197, 2, 18, 86, 18, 75, 32, 0, 105, 8, 109, 101, 190, 197, 2, 18, 86, 18, 79, 32, 0, 105, 8, 116, 161, 197, 107, 117, 97, 2, 18, 86, 18, 75, 32, 0, 105, 8, 116, 161, 197, 107, 117, 97, 2, 18, 86, 18, 79, 32, 0, 2, 105, 107, 18, 78, 32, 3, 109, 0, 4, 105, 2, 18, 69, 3, 121, 0, 105, 2, 32, 0, 4, 117, 2, 18, 69, 3, 123, 0, 117, 2, 32, 0, 7, 6, 98, 0, 2, 18, 67, 3, 48, 0, 3, 71, 0, 4, 2, 17, 67, 18, 71, 3, 71, 38, 0, 2, 18, 71, 0, 7, 6, 99, 0, 104, 3, 101, 0, 104, 2, 18, 71, 3, 101, 38, 0, 3, 133, 0, 2, 18, 71, 3, 133, 38, 0, 7, 6, 100, 0, 4, 2, 18, 67, 3, 47, 0, 2, 32, 0, 3, 72, 0, 122, 3, 72, 88, 0, 122, 2, 18, 71, 3, 72, 94, 0, 197, 190, 3, 75, 0, 197, 190, 2, 18, 71, 3, 77, 0, 2, 18, 71, 3, 135, 0, 7, 6, 101, 0, 3, 36, 0, 105, 1, 21, 2, 118, 18, 78, 32, 3, 36, 8, 114, 0, 105, 3, 38, 122, 0, 7, 6, 102, 0, 3, 83, 0, 7, 6, 103, 0, 4, 2, 18, 67, 3, 49, 0, 2, 32, 0, 4, 3, 81, 0, 103, 0, 7, 6, 104, 0, 3, 107, 0, 7, 6, 105, 0, 97, 3, 36, 0, 3, 37, 0, 4, 97, 1, 99, 2, 99, 105, 106, 18, 78, 32, 3, 37, 57, 35, 0, 97, 1, 99, 2, 108, 18, 77, 32, 0, 2, 17, 65, 3, 38, 0, 4, 1, 97, 2, 107, 18, 78, 32, 3, 57, 37, 0, 1, 97, 2, 122, 109, 18, 77, 32, 0, 1, 111, 2, 107, 18, 78, 32, 0, 4, 101, 2, 197, 161, 107, 3, 57, 127, 0, 101, 8, 2, 118, 0, 101, 8, 2, 197, 161, 109, 0, 101, 1, 21, 2, 110, 18, 78, 32, 3, 114, 8, 36, 0, 4, 101, 3, 127, 0, 101, 8, 116, 117, 97, 106, 2, 110, 18, 78, 32, 0, 7, 6, 106, 0, 3, 57, 0, 7, 6, 107, 0, 4, 3, 49, 0, 107, 0, 4, 2, 17, 67, 17, 67, 18, 71, 3, 49, 38, 0, 2, 17, 67, 18, 71, 0, 2, 18, 71, 0, 2, 18, 66, 3, 81, 0, 7, 6, 108, 0, 3, 55, 0, 4, 2, 17, 67, 17, 67, 18, 71, 3, 137, 0, 2, 17, 67, 18, 71, 0, 2, 18, 71, 0, 7, 6, 109, 0, 4, 3, 65, 0, 109, 0, 4, 2, 17, 67, 17, 67, 18, 71, 3, 65, 38, 0, 2, 17, 67, 18, 71, 0, 2, 18, 71, 0, 7, 6, 110, 0, 4, 3, 50, 0, 110, 0, 4, 2, 17, 67, 17, 67, 18, 71, 3, 136, 0, 2, 17, 67, 18, 71, 0, 2, 18, 71, 0, 7, 6, 111, 0, 1, 102, 2, 110, 18, 77, 32, 3, 116, 8, 0, 3, 117, 0, 2, 107, 197, 161, 110, 18, 75, 32, 3, 117, 8, 0, 7, 6, 112, 0, 4, 3, 48, 0, 112, 0, 4, 2, 17, 67, 17, 67, 18, 71, 3, 48, 38, 0, 2, 17, 67, 18, 71, 0, 2, 18, 71, 0, 2, 18, 66, 3, 71, 0, 7, 6, 113, 0, 2, 18, 71, 3, 49, 38, 84, 38, 0, 3, 49, 84, 0, 7, 6, 114, 0, 4, 3, 34, 0, 114, 0, 4, 2, 17, 67, 17, 67, 18, 71, 3, 34, 38, 0, 2, 17, 67, 18, 71, 0, 2, 18, 71, 0, 7, 6, 115, 0, 2, 18, 66, 3, 88, 0, 4, 3, 89, 0, 115, 0, 197, 161, 3, 91, 0, 4, 2, 17, 67, 17, 67, 18, 71, 3, 95, 0, 2, 17, 67, 18, 71, 0, 2, 18, 71, 0, 7, 6, 116, 0, 4, 3, 47, 0, 116, 0, 2, 18, 66, 3, 72, 0, 4, 2, 17, 67, 17, 67, 18, 71, 3, 134, 0, 2, 17, 67, 18, 71, 0, 2, 18, 71, 0, 7, 6, 117, 0, 3, 40, 0, 111, 1, 21, 2, 109, 101, 110, 18, 79, 32, 3, 118, 8, 39, 0, 111, 3, 124, 0, 105, 3, 126, 0, 7, 6, 118, 0, 3, 84, 0, 2, 18, 71, 3, 84, 38, 0, 7, 6, 119, 0, 3, 84, 0, 2, 18, 71, 3, 84, 38, 0, 7, 6, 120, 0, 2, 18, 71, 3, 49, 38, 95, 0, 3, 49, 89, 0, 7, 6, 121, 0, 3, 115, 0, 4, 1, 21, 2, 18, 86, 18, 75, 32, 3, 115, 8, 0, 1, 21, 2, 18, 86, 18, 79, 32, 0, 1, 21, 2, 98, 18, 78, 32, 0, 1, 21, 2, 98, 18, 79, 32, 0, 1, 109, 117, 21, 2, 110, 18, 77, 32, 0, 1, 110, 101, 21, 2, 98, 18, 79, 32, 0, 8, 112, 97, 2, 21, 0, 7, 6, 122, 0, 3, 88, 0, 2, 18, 67, 3, 89, 0, 2, 100, 197, 190, 3, 90, 0, 2, 196, 141, 3, 91, 0, 4, 2, 17, 67, 18, 71, 3, 94, 0, 2, 18, 71, 0, 7, 6, 206, 0, 177, 3, 6, 35, 55, 83, 35, 10, 0, 181, 3, 6, 36, 48, 95, 37, 55, 39, 50, 10, 0, 191, 3, 6, 39, 65, 38, 37, 49, 34, 39, 50, 10, 0, 183, 3, 36, 47, 35, 10, 0, 186, 3, 49, 6, 35, 48, 35, 10, 0, 190, 3, 49, 95, 6, 37, 10, 0, 185, 3, 57, 39, 47, 35, 10, 0, 188, 3, 65, 38, 6, 37, 10, 0, 178, 3, 71, 38, 6, 36, 47, 35, 10, 0, 179, 3, 81, 6, 109, 65, 35, 10, 0, 182, 3, 94, 6, 36, 47, 35, 10, 0, 184, 3, 134, 36, 47, 35, 10, 0, 180, 3, 135, 6, 36, 55, 47, 35, 10, 0, 189, 3, 136, 6, 37, 10, 0, 187, 3, 137, 6, 35, 65, 72, 35, 10, 0, 7, 6, 207, 0, 133, 3, 6, 37, 48, 95, 37, 55, 39, 50, 10, 0, 129, 3, 34, 6, 39, 10, 0, 137, 3, 39, 65, 6, 36, 81, 35, 10, 0, 132, 3, 47, 6, 128, 10, 0, 128, 3, 48, 38, 6, 115, 10, 0, 136, 3, 48, 95, 6, 37, 10, 0, 134, 3, 83, 38, 6, 37, 10, 0, 4, 130, 3, 95, 6, 37, 81, 65, 35, 10, 0, 131, 0, 135, 3, 101, 38, 6, 37, 10, 0, 7, 6, 0, 4, 33, 2, 33, 3, 0, 4, 35, 1, 35, 3, 0, 4, 39, 3, 0, 4, 46, 1, 46, 3, 0, 58, 1, 32, 15, 2, 32, 15, 15, 32, 3, 0, 46, 2, 46, 3, 9, 0, 46, 3, 9, 47, 6, 35, 91, 49, 35, 89, 0, 33, 3, 9, 91, 123, 49, 47, 6, 118, 49, 35, 89, 0, 4, 45, 1, 32, 17, 65, 2, 32, 15, 3, 10, 0, 45, 1, 32, 17, 67, 2, 32, 15, 0, 35, 1, 35, 35, 2, 32, 3, 24, 0, 60, 61, 3, 65, 35, 96, 6, 123, 10, 35, 34, 71, 6, 108, 10, 55, 115, 81, 40, 0, 45, 8, 32, 2, 32, 15, 3, 65, 37, 50, 40, 89, 0, 62, 61, 3, 72, 123, 81, 38, 6, 123, 10, 35, 34, 71, 6, 108, 10, 137, 115, 81, 40, 0, 58, 3, 135, 84, 38, 6, 114, 47, 35, 97, 49, 38, 37, 89, 0, 33, 61, 3, 136, 36, 137, 6, 115, 81, 40, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts38 = FileInMemory_createWithData (5184, reinterpret_cast (&espeakdata_dicts38_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/lt_dict", U"lt"); Collection_addItem (me.peek(), espeakdata_dicts38.transfer()); static unsigned char espeakdata_dicts39_data[12328] = { 0, 4, 0, 0, 72, 18, 0, 0, 0, 0, 11, 195, 44, 21, 84, 66, 81, 107, 196, 129, 32, 11, 195, 44, 21, 84, 66, 81, 99, 105, 107, 32, 0, 0, 0, 5, 65, 4, 35, 0, 0, 5, 194, 5, 0, 72, 0, 20, 67, 76, 16, 128, 89, 35, 71, 122, 72, 52, 108, 71, 35, 0, 44, 81, 98, 97, 32, 0, 0, 6, 65, 8, 71, 36, 0, 0, 0, 0, 0, 6, 65, 12, 124, 36, 0, 0, 0, 13, 4, 95, 8, 1, 3, 107, 6, 35, 76, 36, 49, 0, 0, 0, 6, 65, 16, 72, 36, 0, 0, 0, 0, 0, 5, 65, 20, 36, 0, 0, 0, 14, 4, 95, 48, 67, 15, 89, 6, 37, 65, 47, 116, 89, 0, 0, 0, 6, 65, 24, 36, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 32, 107, 35, 0, 0, 0, 0, 0, 10, 1, 36, 72, 39, 55, 113, 52, 37, 0, 5, 65, 36, 37, 0, 0, 13, 1, 37, 48, 52, 39, 124, 36, 50, 47, 37, 0, 27, 0, 6, 1, 38, 40, 50, 0, 8, 1, 38, 11, 2, 40, 50, 0, 0, 0, 6, 65, 40, 57, 36, 0, 0, 0, 9, 198, 64, 19, 1, 36, 176, 77, 66, 6, 195, 28, 20, 128, 72, 14, 1, 42, 88, 84, 116, 81, 88, 50, 108, 47, 36, 0, 27, 0, 10, 1, 43, 48, 55, 40, 89, 89, 0, 27, 0, 8, 197, 40, 80, 139, 4, 64, 66, 6, 65, 44, 49, 35, 0, 0, 0, 19, 67, 76, 21, 128, 89, 35, 84, 122, 50, 108, 71, 35, 0, 44, 81, 98, 97, 32, 0, 15, 1, 47, 89, 55, 108, 48, 89, 84, 108, 47, 51, 35, 0, 27, 0, 6, 65, 48, 36, 55, 0, 0, 9, 66, 49, 0, 55, 35, 48, 35, 0, 0, 0, 0, 6, 65, 52, 36, 65, 0, 0, 0, 0, 0, 6, 65, 56, 36, 50, 0, 0, 0, 0, 7, 196, 48, 16, 129, 16, 72, 0, 5, 65, 60, 119, 0, 0, 13, 1, 61, 10, 84, 122, 50, 113, 72, 89, 10, 0, 27, 0, 0, 0, 9, 134, 6, 15, 1, 10, 196, 147, 67, 7, 1, 64, 35, 47, 9, 0, 6, 65, 64, 48, 36, 0, 0, 0, 0, 0, 6, 65, 68, 49, 115, 0, 0, 0, 0, 0, 7, 65, 72, 36, 51, 52, 0, 0, 5, 194, 5, 32, 72, 0, 0, 0, 6, 65, 76, 36, 89, 0, 0, 0, 0, 0, 6, 65, 80, 47, 109, 0, 0, 0, 11, 136, 16, 9, 1, 14, 196, 171, 14, 15, 20, 0, 0, 5, 65, 84, 40, 0, 0, 0, 0, 0, 6, 65, 88, 84, 36, 0, 0, 0, 0, 0, 25, 1, 92, 6, 35, 48, 81, 52, 122, 88, 47, 113, 15, 89, 55, 6, 108, 48, 89, 84, 108, 47, 51, 35, 0, 13, 65, 92, 72, 40, 71, 40, 55, 47, 6, 84, 36, 0, 0, 0, 0, 0, 18, 4, 95, 49, 77, 49, 47, 6, 115, 49, 89, 47, 119, 12, 47, 37, 89, 0, 7, 65, 96, 37, 49, 89, 0, 0, 15, 4, 95, 49, 77, 50, 65, 6, 37, 55, 57, 114, 50, 89, 0, 0, 0, 0, 9, 65, 100, 37, 81, 52, 36, 49, 0, 0, 9, 198, 20, 208, 129, 72, 115, 192, 20, 0, 0, 0, 6, 65, 104, 88, 36, 0, 0, 9, 198, 37, 67, 133, 45, 84, 128, 67, 0, 0, 0, 8, 197, 80, 146, 208, 5, 64, 66, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 4, 197, 190, 21, 4, 15, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 64, 19, 142, 60, 20, 0, 0, 13, 67, 36, 84, 203, 122, 89, 49, 116, 47, 119, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 199, 21, 52, 5, 72, 19, 148, 60, 20, 9, 134, 1, 16, 1, 11, 197, 161, 72, 0, 10, 135, 16, 18, 9, 5, 11, 197, 161, 72, 0, 0, 0, 7, 195, 8, 85, 0, 72, 8, 0, 0, 0, 6, 195, 4, 227, 143, 20, 0, 0, 0, 8, 133, 4, 196, 147, 196, 188, 72, 0, 0, 0, 12, 137, 11, 15, 13, 21, 14, 9, 11, 196, 147, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 88, 85, 15, 20, 12, 66, 17, 32, 72, 39, 49, 47, 114, 52, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 67, 48, 21, 22, 55, 35, 47, 84, 122, 91, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 11, 15, 16, 197, 161, 72, 0, 6, 195, 64, 145, 64, 72, 0, 0, 0, 0, 0, 0, 0, 6, 195, 52, 245, 15, 20, 6, 195, 52, 245, 15, 20, 0, 0, 14, 4, 95, 4, 16, 20, 49, 6, 39, 65, 35, 124, 10, 0, 0, 0, 5, 194, 21, 48, 72, 0, 0, 7, 196, 32, 19, 12, 60, 20, 0, 0, 0, 6, 195, 84, 227, 192, 20, 6, 195, 104, 83, 64, 72, 0, 0, 0, 0, 0, 16, 3, 95, 35, 57, 47, 35, 71, 40, 55, 35, 47, 114, 52, 89, 0, 13, 4, 95, 20, 12, 4, 47, 6, 37, 55, 72, 36, 0, 0, 0, 0, 0, 7, 196, 8, 147, 135, 60, 20, 12, 137, 20, 21, 18, 16, 18, 5, 20, 196, 171, 66, 0, 0, 0, 0, 0, 9, 134, 18, 1, 14, 196, 141, 15, 20, 0, 0, 0, 0, 0, 0, 0, 7, 196, 81, 34, 77, 60, 20, 13, 67, 64, 145, 77, 48, 122, 65, 109, 52, 35, 65, 0, 0, 0, 0, 12, 67, 76, 176, 84, 89, 49, 35, 47, 108, 47, 0, 0, 0, 0, 10, 135, 7, 1, 12, 9, 6, 196, 147, 67, 0, 0, 7, 196, 9, 32, 86, 60, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 76, 243, 133, 72, 16, 20, 15, 67, 24, 80, 146, 83, 36, 71, 52, 40, 113, 52, 37, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 198, 80, 146, 214, 36, 83, 128, 66, 9, 198, 4, 150, 150, 36, 83, 128, 66, 0, 0, 0, 0, 9, 198, 52, 17, 83, 81, 35, 192, 20, 9, 198, 52, 17, 83, 81, 35, 192, 66, 0, 6, 195, 64, 20, 128, 72, 0, 7, 196, 81, 34, 75, 60, 20, 0, 0, 0, 0, 7, 196, 16, 147, 135, 60, 20, 0, 0, 11, 66, 17, 160, 72, 88, 37, 65, 37, 89, 0, 8, 66, 17, 160, 72, 88, 109, 0, 0, 0, 0, 9, 134, 22, 9, 197, 134, 197, 161, 72, 0, 0, 0, 0, 0, 0, 11, 195, 56, 86, 128, 66, 81, 107, 97, 100, 32, 0, 0, 0, 0, 6, 195, 8, 86, 128, 72, 0, 0, 8, 197, 72, 242, 207, 44, 240, 20, 0, 0, 0, 10, 135, 1, 20, 5, 12, 10, 196, 147, 67, 0, 0, 0, 0, 0, 0, 7, 132, 16, 196, 129, 18, 72, 0, 0, 0, 0, 0, 0, 13, 3, 95, 49, 15, 48, 6, 37, 52, 65, 116, 89, 0, 0, 0, 0, 12, 67, 64, 17, 192, 48, 35, 81, 35, 89, 124, 0, 9, 3, 226, 130, 172, 117, 52, 114, 0, 9, 3, 226, 130, 172, 117, 51, 39, 0, 0, 0, 0, 0, 13, 3, 226, 130, 168, 52, 115, 48, 108, 57, 35, 89, 0, 0, 12, 3, 95, 50, 15, 6, 39, 47, 52, 116, 89, 0, 0, 8, 197, 81, 84, 144, 5, 64, 66, 0, 0, 12, 67, 64, 18, 192, 48, 35, 49, 113, 48, 36, 0, 0, 0, 0, 0, 0, 13, 3, 95, 51, 15, 47, 51, 6, 36, 91, 116, 89, 0, 9, 4, 95, 15, 18, 4, 116, 89, 0, 0, 0, 0, 0, 0, 0, 8, 133, 197, 190, 1, 2, 15, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 53, 15, 48, 6, 122, 49, 47, 116, 89, 0, 0, 0, 14, 4, 95, 13, 3, 14, 65, 6, 35, 49, 52, 39, 50, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 54, 15, 89, 6, 36, 89, 47, 116, 89, 0, 0, 0, 0, 9, 134, 196, 141, 5, 12, 12, 15, 20, 0, 0, 0, 0, 0, 15, 3, 95, 55, 15, 89, 6, 36, 48, 47, 108, 47, 116, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 3, 95, 51, 88, 47, 51, 6, 108, 89, 72, 36, 89, 65, 37, 47, 0, 0, 9, 198, 64, 21, 12, 4, 32, 78, 66, 13, 3, 95, 48, 67, 89, 6, 37, 65, 47, 37, 10, 0, 0, 0, 0, 0, 7, 196, 64, 148, 141, 76, 72, 14, 3, 95, 57, 15, 72, 6, 36, 84, 108, 47, 116, 89, 0, 0, 0, 0, 0, 11, 3, 95, 49, 67, 89, 6, 37, 65, 124, 0, 0, 0, 0, 0, 0, 0, 19, 3, 95, 49, 57, 72, 6, 36, 84, 37, 67, 48, 35, 72, 89, 65, 37, 47, 0, 0, 19, 3, 95, 49, 56, 6, 35, 89, 47, 119, 67, 48, 35, 72, 89, 65, 37, 47, 0, 0, 0, 12, 67, 48, 21, 0, 55, 35, 47, 108, 67, 40, 0, 0, 0, 0, 0, 12, 3, 226, 136, 146, 65, 108, 50, 40, 89, 89, 0, 0, 17, 3, 95, 49, 49, 84, 6, 122, 50, 48, 35, 72, 89, 65, 37, 47, 0, 0, 13, 3, 95, 49, 48, 72, 6, 36, 89, 65, 37, 47, 0, 0, 18, 3, 95, 49, 51, 47, 51, 6, 108, 89, 48, 35, 72, 89, 65, 37, 47, 0, 0, 17, 3, 95, 49, 50, 72, 6, 37, 84, 48, 35, 72, 89, 65, 37, 47, 0, 0, 9, 198, 49, 83, 66, 4, 115, 192, 20, 17, 3, 95, 49, 53, 48, 6, 122, 124, 48, 35, 72, 89, 65, 37, 47, 0, 0, 18, 3, 95, 49, 52, 76, 6, 36, 47, 52, 48, 35, 72, 89, 65, 37, 47, 0, 0, 7, 196, 80, 84, 1, 80, 66, 15, 3, 95, 52, 15, 76, 6, 36, 47, 40, 51, 47, 116, 89, 0, 20, 3, 95, 49, 55, 89, 6, 36, 48, 47, 37, 67, 48, 35, 72, 89, 65, 37, 47, 0, 0, 7, 132, 16, 196, 147, 3, 72, 17, 3, 95, 49, 54, 89, 6, 36, 91, 48, 35, 72, 89, 65, 37, 47, 0, 0, 0, 19, 3, 95, 55, 88, 89, 6, 36, 48, 47, 37, 67, 72, 36, 89, 65, 37, 47, 0, 0, 6, 195, 24, 245, 15, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 66, 49, 48, 55, 35, 47, 37, 0, 41, 0, 16, 3, 95, 50, 88, 72, 6, 37, 84, 72, 36, 89, 65, 37, 47, 0, 0, 10, 135, 11, 1, 14, 1, 16, 196, 147, 67, 0, 0, 0, 6, 195, 65, 33, 84, 72, 0, 14, 3, 95, 56, 15, 6, 35, 89, 47, 39, 47, 116, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 63, 63, 52, 35, 49, 89, 47, 88, 108, 65, 36, 0, 0, 0, 5, 194, 37, 160, 72, 0, 17, 3, 95, 52, 88, 76, 6, 36, 47, 52, 72, 36, 89, 65, 37, 47, 0, 0, 12, 3, 1, 47, 19, 35, 49, 80, 37, 57, 40, 0, 0, 0, 0, 0, 0, 0, 0, 16, 67, 76, 84, 20, 89, 36, 48, 47, 36, 65, 71, 52, 37, 89, 0, 17, 3, 95, 53, 88, 48, 6, 122, 124, 72, 4, 36, 89, 65, 37, 47, 0, 0, 0, 8, 197, 4, 146, 201, 16, 240, 20, 0, 0, 0, 0, 0, 5, 194, 49, 80, 17, 0, 6, 195, 60, 67, 192, 20, 16, 3, 95, 54, 88, 89, 6, 36, 91, 72, 36, 89, 65, 37, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 67, 5, 4, 128, 35, 48, 52, 108, 55, 37, 89, 0, 0, 0, 0, 0, 0, 0, 0, 10, 66, 57, 32, 50, 40, 65, 40, 52, 0, 0, 18, 3, 95, 56, 88, 6, 35, 89, 47, 119, 67, 72, 36, 89, 65, 37, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 3, 95, 57, 88, 72, 6, 36, 84, 37, 67, 72, 36, 89, 65, 37, 47, 0, 0, 12, 196, 56, 86, 137, 56, 67, 81, 107, 117, 114, 32, 0, 0, 0, 0, 7, 196, 77, 64, 82, 64, 72, 0, 0, 10, 3, 95, 63, 65, 71, 40, 52, 124, 0, 0, 0, 7, 196, 9, 37, 78, 60, 20, 0, 0, 0, 0, 0, 0, 0, 11, 3, 226, 153, 175, 72, 122, 12, 88, 89, 0, 0, 0, 12, 3, 226, 153, 173, 71, 36, 65, 114, 55, 89, 0, 0, 0, 0, 14, 4, 95, 15, 7, 15, 6, 39, 81, 39, 50, 36, 49, 0, 0, 0, 0, 0, 10, 199, 52, 144, 210, 61, 51, 198, 80, 20, 0, 0, 0, 0, 0, 0, 0, 5, 194, 64, 16, 72, 0, 12, 67, 64, 17, 0, 48, 35, 72, 119, 65, 36, 0, 0, 0, 8, 197, 8, 243, 5, 72, 240, 20, 0, 13, 4, 10, 197, 171, 14, 57, 115, 50, 37, 57, 89, 0, 0, 12, 4, 197, 161, 196, 183, 91, 80, 37, 52, 35, 0, 0, 13, 4, 10, 197, 171, 12, 57, 115, 55, 37, 57, 89, 0, 0, 8, 197, 44, 22, 137, 56, 240, 20, 8, 197, 36, 225, 9, 28, 240, 20, 8, 197, 24, 144, 83, 44, 240, 20, 0, 5, 194, 57, 80, 72, 0, 6, 195, 61, 67, 192, 20, 21, 67, 52, 147, 128, 65, 37, 50, 37, 89, 47, 52, 37, 57, 35, 0, 44, 81, 106, 97, 32, 14, 67, 52, 147, 128, 65, 37, 50, 37, 65, 40, 65, 89, 0, 0, 0, 0, 15, 4, 95, 48, 77, 50, 65, 6, 37, 55, 57, 114, 50, 37, 0, 0, 0, 0, 17, 4, 95, 48, 77, 49, 47, 6, 115, 49, 89, 47, 119, 12, 91, 37, 0, 0, 13, 4, 95, 2, 18, 22, 6, 108, 89, 40, 65, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 132, 10, 197, 171, 19, 72, 0, 7, 196, 9, 37, 84, 60, 20, 0, 0, 0, 15, 67, 56, 245, 128, 50, 39, 84, 36, 65, 71, 52, 37, 89, 0, 0, 0, 0, 0, 0, 0, 0, 10, 135, 16, 15, 18, 20, 10, 196, 147, 66, 0, 6, 195, 4, 150, 128, 72, 0, 0, 0, 0, 0, 7, 196, 52, 85, 18, 60, 20, 0, 0, 10, 135, 2, 5, 14, 4, 197, 190, 15, 20, 10, 135, 2, 1, 14, 4, 197, 190, 15, 20, 0, 0, 0, 0, 6, 195, 72, 242, 211, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 137, 19, 15, 12, 6, 5, 4, 197, 190, 15, 20, 12, 137, 19, 15, 12, 6, 5, 4, 197, 190, 15, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 22, 9, 197, 134, 1, 72, 0, 0, 0, 0, 19, 4, 95, 3, 9, 18, 72, 6, 37, 35, 49, 52, 37, 47, 37, 89, 49, 113, 0, 0, 0, 0, 0, 8, 133, 22, 9, 197, 134, 9, 72, 0, 12, 3, 95, 194, 180, 35, 49, 124, 36, 50, 124, 0, 0, 7, 196, 56, 82, 213, 72, 66, 0, 0, 16, 67, 52, 18, 211, 65, 35, 49, 89, 37, 65, 113, 55, 116, 89, 0, 0, 14, 67, 56, 244, 192, 50, 119, 89, 118, 49, 40, 65, 89, 0, 0, 0, 0, 0, 13, 4, 95, 19, 20, 11, 89, 47, 34, 6, 114, 49, 0, 0, 0, 13, 4, 95, 1, 3, 21, 6, 35, 49, 57, 115, 47, 0, 0, 14, 3, 95, 194, 171, 48, 6, 109, 72, 37, 67, 35, 89, 0, 0, 9, 198, 64, 20, 9, 48, 224, 77, 66, 0, 0, 27, 3, 95, 194, 166, 89, 6, 35, 72, 35, 55, 108, 47, 35, 15, 89, 47, 6, 113, 84, 89, 84, 108, 47, 52, 35, 0, 0, 0, 0, 0, 0, 0, 12, 4, 95, 18, 14, 7, 52, 6, 37, 50, 81, 0, 0, 0, 0, 0, 11, 136, 6, 18, 9, 11, 1, 19, 196, 147, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 198, 5, 85, 15, 52, 245, 15, 20, 0, 0, 0, 7, 196, 64, 144, 78, 60, 66, 0, 8, 197, 40, 80, 139, 85, 32, 66, 0, 19, 4, 95, 1, 3, 50, 72, 6, 40, 71, 40, 55, 124, 35, 49, 57, 115, 47, 0, 0, 16, 5, 4, 26, 196, 171, 22, 72, 88, 108, 84, 119, 57, 37, 89, 0, 0, 0, 0, 6, 195, 65, 52, 147, 17, 0, 6, 195, 73, 2, 64, 17, 0, 0, 0, 0, 14, 67, 60, 181, 0, 39, 49, 47, 114, 71, 52, 37, 89, 0, 11, 136, 4, 5, 11, 15, 12, 20, 196, 147, 67, 0, 0, 0, 28, 3, 95, 194, 191, 6, 35, 48, 81, 52, 122, 88, 47, 113, 15, 57, 6, 118, 47, 113, 57, 40, 65, 88, 108, 65, 36, 0, 0, 0, 7, 196, 56, 82, 193, 16, 66, 0, 0, 19, 3, 95, 194, 187, 48, 6, 109, 72, 37, 67, 35, 89, 15, 124, 6, 122, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 2, 196, 129, 113, 0, 0, 7, 2, 197, 134, 36, 67, 0, 0, 8, 197, 5, 37, 137, 20, 224, 66, 8, 2, 195, 151, 52, 117, 88, 0, 0, 6, 195, 16, 84, 15, 20, 9, 66, 77, 64, 89, 35, 50, 47, 0, 0, 7, 2, 196, 141, 76, 36, 0, 0, 0, 0, 0, 0, 0, 12, 2, 194, 167, 89, 36, 49, 124, 37, 57, 35, 0, 0, 5, 194, 56, 240, 72, 0, 12, 67, 56, 241, 0, 50, 119, 72, 35, 61, 35, 0, 10, 2, 194, 165, 57, 109, 50, 35, 89, 0, 0, 10, 2, 194, 162, 124, 36, 50, 47, 37, 0, 0, 13, 2, 194, 163, 65, 113, 52, 124, 37, 67, 35, 89, 0, 6, 2, 196, 147, 109, 0, 0, 0, 0, 14, 2, 194, 174, 52, 36, 79, 37, 89, 47, 52, 109, 124, 0, 0, 7, 2, 197, 151, 36, 34, 0, 0, 0, 0, 0, 0, 0, 16, 2, 194, 169, 118, 47, 114, 52, 47, 122, 89, 108, 71, 35, 89, 0, 0, 14, 2, 194, 182, 48, 35, 52, 35, 81, 52, 113, 83, 89, 0, 0, 0, 0, 10, 2, 194, 181, 65, 37, 49, 51, 114, 0, 0, 0, 7, 2, 196, 163, 79, 36, 0, 0, 10, 2, 194, 176, 81, 52, 113, 72, 37, 0, 0, 15, 2, 194, 177, 48, 55, 40, 89, 65, 108, 50, 40, 89, 89, 0, 0, 23, 2, 194, 190, 47, 52, 6, 108, 89, 15, 124, 4, 36, 47, 40, 52, 47, 72, 35, 61, 35, 89, 0, 0, 10, 2, 195, 183, 72, 35, 55, 108, 124, 0, 0, 11, 66, 77, 96, 89, 84, 109, 47, 116, 89, 0, 17, 2, 194, 188, 124, 6, 36, 47, 40, 52, 47, 72, 4, 35, 61, 35, 0, 0, 9, 2, 194, 189, 48, 40, 89, 36, 0, 0, 14, 4, 95, 3, 5, 4, 89, 6, 36, 72, 108, 55, 35, 0, 0, 6, 2, 196, 171, 108, 0, 0, 10, 135, 1, 4, 1, 4, 197, 190, 15, 20, 10, 135, 1, 4, 1, 4, 197, 190, 15, 66, 0, 16, 4, 95, 12, 9, 7, 55, 6, 37, 81, 35, 47, 115, 52, 35, 0, 7, 2, 197, 161, 36, 91, 0, 0, 7, 196, 24, 16, 212, 60, 20, 17, 5, 16, 18, 45, 11, 19, 48, 52, 122, 49, 91, 50, 122, 49, 89, 0, 0, 7, 2, 196, 183, 80, 36, 0, 0, 0, 0, 0, 6, 2, 197, 171, 115, 0, 0, 0, 7, 195, 88, 18, 64, 72, 8, 0, 0, 0, 5, 194, 81, 80, 72, 7, 2, 196, 188, 36, 61, 0, 0, 0, 0, 9, 134, 22, 9, 197, 134, 1, 19, 72, 0, 0, 0, 7, 2, 197, 190, 90, 36, 0, 0, 0, 9, 198, 64, 20, 133, 80, 19, 64, 66, 0, 0, 0, 0, 0, 0, 7, 196, 44, 18, 193, 60, 20, 7, 196, 44, 18, 193, 60, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 198, 64, 21, 137, 76, 19, 64, 66, 0, 8, 133, 12, 196, 171, 4, 26, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 67, 72, 18, 128, 52, 35, 57, 119, 50, 89, 0, 0, 0, 0, 0, 13, 67, 8, 146, 128, 71, 37, 57, 40, 91, 116, 89, 0, 12, 2, 95, 35, 34, 36, 89, 47, 108, 47, 36, 0, 0, 12, 2, 95, 34, 48, 109, 72, 37, 67, 35, 89, 0, 0, 13, 138, 16, 1, 20, 9, 5, 197, 161, 196, 129, 13, 66, 16, 2, 95, 33, 37, 88, 89, 118, 49, 40, 65, 88, 108, 65, 36, 0, 0, 0, 14, 2, 95, 39, 35, 48, 39, 89, 47, 34, 114, 83, 89, 0, 0, 7, 196, 76, 19, 66, 60, 20, 0, 0, 9, 134, 20, 196, 129, 16, 1, 20, 66, 0, 0, 12, 4, 95, 3, 1, 16, 55, 122, 55, 116, 89, 0, 0, 16, 2, 95, 41, 6, 122, 49, 35, 84, 35, 15, 124, 6, 122, 47, 0, 0, 11, 2, 95, 40, 6, 122, 49, 35, 84, 35, 0, 0, 0, 10, 2, 95, 46, 48, 40, 50, 49, 124, 0, 0, 11, 2, 95, 45, 65, 108, 50, 40, 89, 89, 0, 0, 10, 2, 95, 44, 49, 39, 65, 35, 124, 0, 0, 9, 2, 95, 51, 47, 51, 108, 89, 0, 0, 10, 2, 95, 50, 72, 6, 37, 84, 37, 0, 0, 10, 2, 95, 49, 84, 6, 122, 50, 89, 0, 0, 11, 2, 95, 48, 50, 6, 40, 55, 55, 36, 0, 0, 13, 2, 95, 55, 89, 6, 36, 48, 47, 37, 67, 37, 0, 0, 7, 196, 72, 85, 18, 60, 20, 10, 2, 95, 54, 89, 6, 36, 91, 37, 0, 0, 14, 67, 40, 19, 150, 57, 35, 50, 84, 113, 52, 37, 89, 0, 10, 2, 95, 53, 48, 6, 122, 124, 37, 0, 0, 11, 2, 95, 52, 76, 6, 36, 47, 52, 37, 0, 0, 13, 2, 95, 59, 89, 36, 65, 37, 49, 114, 55, 89, 0, 0, 9, 2, 95, 58, 49, 114, 55, 89, 0, 0, 12, 2, 95, 57, 72, 6, 36, 84, 37, 67, 37, 0, 0, 12, 2, 95, 56, 6, 35, 89, 47, 119, 67, 37, 0, 0, 16, 2, 95, 63, 57, 118, 47, 113, 57, 40, 65, 88, 108, 65, 36, 0, 0, 17, 2, 95, 62, 55, 6, 122, 55, 113, 49, 89, 15, 48, 6, 35, 52, 0, 0, 0, 17, 2, 95, 60, 65, 6, 35, 88, 113, 49, 89, 15, 48, 6, 35, 52, 0, 0, 0, 0, 0, 12, 137, 16, 18, 15, 20, 5, 197, 190, 196, 147, 67, 7, 2, 95, 64, 35, 47, 0, 0, 0, 0, 0, 0, 0, 6, 195, 48, 81, 207, 20, 0, 0, 0, 0, 0, 0, 0, 15, 67, 16, 80, 192, 72, 36, 80, 36, 65, 71, 52, 37, 89, 0, 0, 0, 0, 5, 194, 85, 160, 72, 0, 0, 13, 4, 95, 4, 15, 20, 48, 6, 40, 50, 49, 124, 0, 0, 0, 0, 18, 2, 95, 91, 49, 84, 6, 35, 72, 52, 113, 47, 122, 49, 35, 84, 35, 0, 0, 6, 195, 88, 148, 147, 72, 0, 0, 15, 4, 95, 226, 128, 146, 72, 119, 65, 40, 88, 108, 65, 36, 0, 0, 20, 2, 95, 95, 48, 35, 89, 84, 108, 47, 52, 119, 57, 40, 65, 88, 108, 65, 36, 0, 0, 10, 2, 95, 94, 89, 35, 49, 50, 36, 0, 0, 23, 2, 95, 93, 49, 84, 6, 35, 72, 52, 113, 47, 122, 49, 35, 84, 35, 15, 124, 6, 122, 47, 0, 0, 27, 4, 95, 226, 128, 150, 72, 6, 40, 71, 40, 55, 124, 47, 113, 89, 47, 4, 113, 84, 89, 84, 108, 47, 52, 35, 0, 0, 15, 67, 24, 18, 192, 83, 35, 49, 40, 55, 47, 113, 47, 36, 0, 14, 4, 2, 45, 2, 1, 71, 122, 72, 52, 108, 71, 35, 0, 0, 0, 8, 197, 44, 20, 212, 72, 240, 20, 0, 26, 2, 95, 96, 6, 35, 48, 81, 52, 122, 88, 47, 116, 89, 15, 6, 35, 48, 39, 89, 47, 52, 39, 83, 89, 0, 0, 0, 0, 0, 9, 198, 56, 84, 1, 72, 179, 192, 67, 0, 0, 0, 0, 12, 4, 95, 7, 18, 22, 81, 52, 6, 113, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 9, 5, 11, 197, 161, 72, 0, 0, 0, 16, 2, 95, 123, 83, 6, 37, 81, 115, 52, 122, 49, 35, 84, 35, 0, 13, 4, 95, 4, 9, 1, 6, 40, 65, 55, 118, 124, 0, 0, 0, 0, 0, 10, 199, 36, 226, 207, 28, 226, 84, 60, 20, 0, 10, 2, 95, 126, 47, 37, 55, 72, 36, 0, 0, 21, 2, 95, 125, 83, 6, 37, 81, 115, 52, 122, 49, 35, 84, 35, 15, 124, 6, 122, 47, 0, 0, 15, 2, 95, 124, 89, 47, 113, 84, 89, 84, 108, 47, 52, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 84, 224, 72, 8, 0, 0, 6, 195, 33, 81, 207, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 35, 51, 50, 47, 40, 49, 91, 40, 65, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 199, 36, 229, 5, 72, 209, 67, 60, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 132, 13, 196, 147, 19, 72, 0, 0, 6, 195, 49, 101, 64, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 16, 243, 73, 56, 240, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 3, 4, 197, 190, 75, 109, 0, 0, 9, 198, 64, 17, 193, 48, 19, 64, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 12, 21, 82, 72, 0, 0, 0, 0, 6, 18, 66, 102, 0, 104, 0, 119, 0, 120, 0, 7, 6, 18, 67, 196, 141, 0, 196, 183, 0, 196, 188, 0, 197, 134, 0, 197, 190, 0, 7, 6, 18, 68, 105, 101, 109, 0, 97, 109, 0, 111, 115, 0, 196, 129, 0, 115, 0, 97, 0, 117, 0, 105, 0, 7, 6, 18, 69, 196, 129, 109, 0, 196, 129, 115, 0, 97, 115, 0, 97, 105, 0, 196, 129, 0, 117, 0, 97, 0, 7, 6, 18, 70, 105, 101, 109, 0, 105, 115, 0, 105, 109, 0, 111, 115, 0, 196, 171, 0, 105, 0, 7, 6, 18, 71, 196, 129, 0, 97, 0, 7, 6, 18, 72, 196, 147, 109, 0, 196, 147, 115, 0, 101, 115, 0, 101, 105, 0, 196, 147, 0, 101, 0, 105, 0, 117, 0, 7, 6, 18, 73, 97, 109, 105, 101, 115, 0, 97, 109, 196, 129, 115, 0, 97, 109, 97, 115, 0, 97, 109, 97, 0, 97, 109, 105, 0, 97, 109, 115, 0, 7, 6, 18, 74, 197, 161, 0, 115, 0, 7, 6, 18, 75, 116, 0, 100, 0, 106, 0, 7, 6, 18, 76, 105, 101, 109, 0, 111, 115, 0, 105, 0, 117, 0, 7, 6, 18, 77, 105, 101, 109, 0, 97, 109, 0, 111, 115, 0, 196, 129, 0, 115, 0, 7, 6, 18, 78, 196, 147, 0, 101, 0, 7, 6, 196, 129, 0, 3, 113, 0, 7, 6, 196, 141, 0, 3, 76, 0, 7, 6, 196, 147, 0, 3, 109, 0, 7, 6, 196, 163, 0, 3, 79, 0, 7, 6, 196, 171, 0, 3, 108, 0, 7, 6, 196, 183, 0, 3, 80, 0, 7, 6, 196, 188, 0, 4, 1, 107, 2, 117, 3, 55, 57, 0, 1, 107, 2, 117, 0, 3, 61, 0, 7, 6, 197, 134, 0, 3, 67, 0, 7, 6, 197, 141, 0, 3, 114, 0, 7, 6, 197, 151, 0, 3, 34, 0, 7, 6, 197, 161, 0, 3, 91, 0, 7, 6, 197, 171, 0, 3, 115, 0, 7, 6, 197, 190, 0, 3, 90, 0, 7, 6, 97, 0, 3, 35, 0, 112, 3, 35, 48, 0, 105, 3, 116, 0, 117, 3, 118, 0, 7, 6, 98, 0, 3, 71, 0, 7, 6, 99, 0, 104, 3, 76, 0, 3, 124, 0, 4, 104, 1, 105, 114, 100, 105, 114, 102, 2, 115, 3, 124, 107, 0, 104, 1, 114, 101, 2, 101, 114, 99, 111, 103, 115, 0, 7, 6, 100, 0, 3, 72, 0, 7, 6, 101, 0, 3, 36, 0, 105, 3, 117, 0, 7, 6, 102, 0, 3, 83, 0, 7, 6, 103, 0, 3, 81, 0, 8, 2, 32, 3, 81, 35, 0, 1, 32, 32, 15, 15, 2, 32, 3, 81, 35, 72, 35, 0, 7, 6, 104, 0, 3, 107, 0, 7, 6, 105, 0, 3, 37, 0, 101, 3, 122, 0, 117, 3, 123, 0, 7, 6, 106, 0, 3, 57, 0, 196, 129, 8, 3, 57, 113, 0, 196, 129, 110, 111, 8, 3, 57, 113, 50, 119, 0, 7, 6, 107, 0, 3, 49, 0, 7, 6, 108, 0, 3, 55, 0, 108, 3, 55, 55, 12, 0, 7, 6, 109, 0, 3, 65, 0, 97, 122, 8, 3, 65, 35, 88, 0, 109, 3, 65, 65, 12, 0, 7, 6, 110, 0, 3, 50, 0, 110, 3, 50, 50, 12, 0, 4, 2, 103, 3, 68, 0, 2, 107, 0, 7, 6, 111, 0, 4, 1, 97, 2, 114, 3, 39, 0, 1, 97, 104, 0, 1, 98, 2, 98, 0, 1, 98, 2, 106, 18, 69, 32, 0, 1, 98, 2, 107, 115, 0, 1, 98, 2, 109, 98, 0, 1, 98, 2, 110, 196, 147, 0, 1, 98, 2, 114, 97, 107, 0, 1, 98, 2, 114, 97, 116, 0, 1, 98, 2, 114, 116, 0, 1, 98, 2, 116, 196, 129, 110, 0, 1, 98, 2, 196, 188, 197, 161, 0, 1, 98, 97, 2, 110, 0, 1, 98, 97, 2, 114, 0, 1, 98, 97, 107, 2, 116, 0, 1, 98, 97, 108, 2, 114, 97, 0, 1, 98, 97, 115, 2, 116, 0, 1, 98, 105, 114, 2, 110, 117, 107, 0, 1, 98, 109, 111, 0, 1, 98, 114, 97, 107, 0, 1, 98, 114, 117, 116, 0, 1, 99, 2, 108, 108, 0, 1, 99, 101, 109, 0, 1, 100, 2, 99, 0, 1, 100, 2, 100, 101, 107, 0, 1, 100, 2, 103, 109, 0, 1, 100, 2, 107, 117, 0, 1, 100, 2, 109, 105, 110, 0, 1, 100, 2, 109, 110, 18, 69, 32, 0, 1, 100, 2, 110, 107, 0, 1, 100, 2, 110, 110, 0, 1, 100, 2, 112, 0, 1, 100, 2, 114, 105, 0, 1, 100, 2, 116, 196, 129, 99, 0, 1, 100, 2, 116, 196, 147, 0, 1, 100, 2, 122, 0, 1, 100, 97, 2, 107, 0, 1, 100, 97, 2, 112, 0, 1, 100, 105, 101, 115, 112, 0, 1, 100, 105, 112, 115, 0, 1, 100, 110, 97, 109, 2, 108, 0, 1, 100, 111, 116, 114, 111, 2, 107, 0, 1, 101, 0, 1, 101, 163, 196, 0, 1, 102, 0, 1, 102, 2, 110, 111, 0, 1, 102, 2, 116, 111, 0, 1, 103, 2, 98, 101, 0, 1, 103, 2, 107, 0, 1, 103, 2, 110, 0, 1, 103, 2, 114, 105, 108, 0, 1, 103, 2, 116, 102, 0, 1, 103, 97, 2, 110, 196, 129, 0, 1, 103, 97, 102, 0, 1, 103, 105, 122, 2, 116, 18, 68, 32, 0, 1, 103, 110, 105, 114, 0, 1, 104, 0, 1, 105, 0, 1, 105, 2, 103, 0, 1, 105, 98, 0, 1, 105, 99, 2, 110, 0, 1, 105, 114, 116, 0, 1, 105, 115, 0, 1, 106, 2, 100, 101, 0, 1, 106, 2, 103, 0, 1, 106, 2, 110, 105, 0, 1, 106, 97, 109, 0, 1, 106, 102, 0, 1, 107, 2, 97, 108, 0, 1, 107, 2, 100, 101, 107, 0, 1, 107, 2, 100, 105, 102, 0, 1, 107, 2, 100, 196, 147, 0, 1, 107, 2, 101, 0, 1, 107, 2, 103, 110, 0, 1, 107, 2, 107, 111, 0, 1, 107, 2, 108, 97, 98, 0, 1, 107, 2, 108, 101, 0, 1, 107, 2, 108, 104, 0, 1, 107, 2, 108, 105, 0, 1, 107, 2, 108, 111, 0, 1, 107, 2, 108, 112, 0, 1, 107, 2, 108, 196, 129, 0, 1, 107, 2, 108, 196, 147, 0, 1, 107, 2, 108, 196, 171, 0, 1, 107, 2, 112, 101, 110, 0, 1, 107, 2, 112, 105, 106, 0, 1, 107, 2, 112, 117, 108, 196, 129, 0, 1, 107, 2, 112, 117, 108, 196, 147, 0, 1, 107, 2, 112, 196, 147, 17, 67, 0, 1, 107, 2, 112, 196, 147, 32, 0, 1, 107, 2, 114, 17, 65, 102, 0, 1, 107, 2, 114, 97, 0, 1, 107, 2, 114, 101, 106, 0, 1, 107, 2, 114, 101, 107, 0, 1, 107, 2, 114, 101, 108, 0, 1, 107, 2, 114, 101, 115, 0, 1, 107, 2, 114, 112, 0, 1, 107, 2, 114, 116, 0, 1, 107, 2, 114, 117, 109, 0, 1, 107, 2, 114, 117, 110, 0, 1, 107, 2, 114, 117, 112, 0, 1, 107, 2, 114, 118, 0, 1, 107, 2, 115, 105, 110, 0, 1, 107, 2, 115, 109, 0, 1, 107, 2, 115, 116, 196, 171, 109, 0, 1, 107, 2, 116, 97, 110, 0, 1, 107, 2, 116, 101, 0, 1, 107, 2, 116, 108, 0, 1, 107, 2, 116, 196, 147, 0, 1, 107, 2, 118, 0, 1, 107, 2, 196, 183, 0, 1, 107, 97, 2, 114, 0, 1, 107, 101, 100, 0, 1, 107, 105, 101, 108, 0, 1, 107, 105, 110, 0, 1, 107, 108, 97, 0, 1, 107, 111, 107, 2, 115, 0, 1, 107, 111, 115, 0, 1, 107, 111, 161, 197, 0, 1, 107, 114, 97, 110, 0, 1, 107, 114, 97, 115, 0, 1, 108, 2, 103, 97, 114, 0, 1, 108, 2, 106, 18, 71, 108, 0, 1, 108, 2, 107, 97, 108, 0, 1, 108, 2, 114, 110, 0, 1, 108, 2, 115, 106, 0, 1, 108, 2, 116, 18, 72, 32, 0, 1, 108, 2, 196, 163, 105, 122, 12, 0, 1, 108, 98, 2, 107, 0, 1, 108, 98, 2, 110, 0, 1, 108, 98, 2, 196, 183, 0, 1, 108, 101, 109, 2, 100, 114, 0, 1, 108, 101, 109, 2, 109, 0, 1, 108, 101, 118, 0, 1, 108, 102, 0, 1, 108, 103, 2, 98, 0, 1, 108, 103, 2, 109, 0, 1, 108, 103, 2, 114, 105, 0, 1, 108, 104, 2, 114, 111, 0, 1, 108, 105, 102, 0, 1, 108, 105, 112, 2, 116, 0, 1, 108, 107, 2, 122, 101, 116, 0, 1, 108, 111, 104, 0, 1, 108, 111, 107, 0, 1, 108, 112, 2, 109, 0, 1, 108, 112, 2, 118, 18, 68, 32, 0, 1, 108, 112, 115, 107, 101, 0, 1, 108, 115, 2, 118, 0, 1, 108, 115, 105, 100, 0, 1, 109, 2, 98, 0, 1, 109, 2, 100, 97, 108, 0, 1, 109, 2, 100, 101, 0, 1, 109, 2, 100, 105, 102, 0, 1, 109, 2, 100, 117, 0, 1, 109, 2, 100, 196, 129, 108, 0, 1, 109, 2, 108, 100, 0, 1, 109, 2, 108, 101, 0, 1, 109, 2, 108, 105, 0, 1, 109, 2, 108, 117, 0, 1, 109, 2, 109, 101, 110, 116, 0, 1, 109, 2, 110, 97, 114, 104, 0, 1, 109, 2, 110, 105, 116, 0, 1, 109, 2, 110, 111, 0, 1, 109, 2, 110, 115, 116, 0, 1, 109, 2, 110, 116, 0, 1, 109, 2, 112, 0, 1, 109, 2, 114, 97, 0, 1, 109, 2, 114, 102, 0, 1, 109, 2, 114, 115, 0, 1, 109, 2, 114, 196, 129, 0, 1, 109, 2, 116, 105, 0, 1, 109, 2, 116, 196, 171, 0, 1, 109, 2, 197, 161, 101, 0, 1, 109, 97, 2, 110, 0, 1, 109, 97, 2, 114, 0, 1, 109, 101, 100, 0, 1, 109, 105, 2, 110, 0, 1, 109, 114, 97, 104, 2, 110, 105, 122, 196, 147, 0, 1, 109, 114, 97, 104, 2, 110, 196, 147, 0, 1, 109, 115, 2, 196, 188, 0, 1, 109, 115, 105, 101, 115, 0, 1, 109, 115, 111, 2, 103, 0, 1, 109, 116, 97, 2, 115, 0, 1, 109, 117, 104, 0, 1, 110, 2, 107, 18, 75, 0, 1, 110, 2, 109, 101, 110, 0, 1, 110, 2, 109, 105, 110, 18, 71, 0, 1, 110, 2, 109, 105, 110, 18, 78, 0, 1, 110, 2, 114, 98, 0, 1, 110, 2, 114, 100, 0, 1, 110, 2, 114, 109, 0, 1, 110, 2, 114, 118, 0, 1, 110, 2, 116, 97, 114, 0, 1, 110, 2, 116, 196, 129, 114, 0, 1, 110, 2, 118, 18, 69, 32, 0, 1, 110, 2, 118, 97, 116, 0, 1, 110, 2, 118, 101, 108, 18, 72, 32, 0, 1, 110, 2, 118, 111, 0, 1, 110, 2, 118, 196, 129, 99, 105, 0, 1, 110, 97, 2, 108, 0, 1, 110, 97, 2, 109, 0, 1, 110, 97, 2, 110, 0, 1, 110, 97, 2, 116, 0, 1, 110, 97, 101, 107, 111, 0, 1, 110, 97, 114, 97, 112, 0, 1, 110, 101, 99, 115, 0, 1, 110, 101, 100, 0, 1, 110, 101, 102, 0, 1, 110, 101, 103, 0, 1, 110, 101, 116, 115, 2, 103, 0, 1, 110, 103, 0, 1, 110, 103, 97, 0, 1, 110, 105, 97, 107, 0, 1, 110, 105, 108, 2, 116, 105, 112, 0, 1, 110, 105, 109, 97, 0, 1, 110, 105, 118, 107, 101, 0, 1, 110, 111, 0, 1, 110, 111, 103, 0, 1, 110, 111, 109, 0, 1, 110, 111, 115, 0, 1, 110, 112, 105, 104, 0, 1, 110, 114, 97, 0, 1, 110, 116, 101, 0, 1, 112, 2, 100, 101, 0, 1, 112, 2, 101, 0, 1, 112, 2, 108, 97, 0, 1, 112, 2, 108, 101, 109, 0, 1, 112, 2, 108, 105, 0, 1, 112, 2, 108, 111, 0, 1, 112, 2, 108, 115, 116, 0, 1, 112, 2, 108, 196, 129, 0, 1, 112, 2, 108, 196, 171, 0, 1, 112, 2, 109, 101, 114, 0, 1, 112, 2, 109, 112, 0, 1, 112, 2, 110, 99, 0, 1, 112, 2, 112, 0, 1, 112, 2, 114, 99, 0, 1, 112, 2, 114, 111, 0, 1, 112, 2, 114, 116, 0, 1, 112, 2, 115, 116, 97, 109, 0, 1, 112, 2, 115, 116, 101, 109, 0, 1, 112, 2, 115, 116, 101, 110, 0, 1, 112, 2, 115, 116, 101, 114, 0, 1, 112, 2, 115, 116, 109, 0, 1, 112, 2, 115, 116, 115, 111, 0, 1, 112, 2, 115, 116, 117, 108, 0, 1, 112, 2, 116, 101, 110, 0, 1, 112, 2, 122, 0, 1, 112, 2, 196, 147, 0, 1, 112, 97, 2, 107, 0, 1, 112, 97, 2, 108, 0, 1, 112, 97, 2, 115, 116, 114, 111, 102, 0, 1, 112, 101, 2, 108, 0, 1, 112, 101, 2, 115, 18, 68, 32, 0, 1, 112, 101, 100, 0, 1, 112, 105, 104, 0, 1, 112, 105, 116, 0, 1, 112, 105, 116, 110, 97, 0, 1, 112, 111, 0, 1, 112, 111, 114, 112, 0, 1, 112, 114, 101, 116, 110, 105, 0, 1, 112, 115, 2, 110, 0, 1, 112, 115, 2, 114, 116, 0, 1, 112, 115, 101, 100, 0, 1, 112, 115, 105, 100, 0, 1, 114, 2, 108, 0, 1, 114, 2, 109, 97, 0, 1, 114, 2, 109, 98, 0, 1, 114, 2, 109, 196, 129, 0, 1, 114, 2, 114, 0, 1, 114, 2, 115, 105, 106, 0, 1, 114, 2, 115, 116, 98, 0, 1, 114, 2, 116, 101, 114, 0, 1, 114, 2, 116, 196, 147, 0, 1, 114, 97, 108, 111, 112, 0, 1, 114, 97, 109, 0, 1, 114, 97, 112, 2, 100, 0, 1, 114, 98, 2, 109, 0, 1, 114, 98, 2, 110, 0, 1, 114, 98, 2, 197, 161, 0, 1, 114, 100, 105, 104, 0, 1, 114, 101, 2, 103, 0, 1, 114, 101, 97, 2, 100, 0, 1, 114, 101, 97, 2, 102, 111, 0, 1, 114, 101, 97, 2, 115, 111, 0, 1, 114, 101, 116, 115, 0, 1, 114, 102, 2, 110, 0, 1, 114, 102, 97, 0, 1, 114, 103, 97, 0, 1, 114, 104, 2, 109, 0, 1, 114, 104, 2, 110, 111, 0, 1, 114, 104, 110, 105, 115, 0, 1, 114, 105, 98, 0, 1, 114, 105, 101, 110, 0, 1, 114, 105, 112, 0, 1, 114, 105, 190, 197, 0, 1, 114, 107, 2, 110, 197, 161, 0, 1, 114, 107, 2, 115, 0, 1, 114, 107, 97, 0, 1, 114, 111, 108, 104, 0, 1, 114, 111, 112, 0, 1, 114, 112, 2, 98, 0, 1, 114, 112, 2, 99, 0, 1, 114, 112, 2, 100, 0, 1, 114, 112, 2, 103, 110, 0, 1, 114, 112, 2, 103, 114, 0, 1, 114, 112, 2, 106, 0, 1, 114, 112, 2, 107, 0, 1, 114, 112, 2, 108, 101, 0, 1, 114, 112, 2, 109, 0, 1, 114, 112, 2, 112, 0, 1, 114, 112, 2, 115, 112, 0, 1, 114, 112, 2, 115, 116, 0, 1, 114, 112, 2, 116, 101, 0, 1, 114, 112, 2, 116, 111, 0, 1, 114, 112, 2, 118, 105, 110, 0, 1, 114, 112, 2, 118, 105, 122, 0, 1, 114, 112, 2, 118, 196, 171, 122, 0, 1, 114, 112, 2, 197, 190, 0, 1, 114, 112, 101, 0, 1, 114, 112, 109, 105, 0, 1, 114, 116, 2, 109, 0, 1, 114, 116, 2, 116, 0, 1, 114, 116, 101, 109, 0, 1, 114, 116, 101, 114, 0, 1, 114, 116, 105, 0, 1, 114, 116, 110, 105, 0, 1, 114, 116, 115, 97, 2, 110, 0, 1, 114, 116, 115, 107, 111, 0, 1, 115, 2, 99, 105, 0, 1, 115, 2, 107, 111, 0, 1, 115, 2, 107, 114, 0, 1, 115, 2, 108, 97, 114, 0, 1, 115, 2, 108, 102, 0, 1, 115, 2, 108, 105, 100, 0, 1, 115, 2, 108, 111, 196, 163, 0, 1, 115, 2, 108, 115, 116, 0, 1, 115, 2, 108, 116, 0, 1, 115, 2, 108, 118, 0, 1, 115, 2, 108, 196, 129, 114, 0, 1, 115, 2, 108, 196, 171, 100, 18, 68, 32, 0, 1, 115, 2, 108, 196, 171, 100, 196, 129, 0, 1, 115, 2, 110, 111, 0, 1, 115, 2, 110, 196, 129, 0, 1, 115, 2, 112, 114, 0, 1, 115, 2, 114, 0, 1, 115, 2, 118, 0, 1, 115, 97, 107, 110, 105, 0, 1, 115, 97, 114, 2, 108, 0, 1, 115, 98, 97, 2, 108, 0, 1, 115, 105, 2, 110, 0, 1, 115, 107, 101, 0, 1, 115, 110, 111, 107, 0, 1, 116, 2, 107, 115, 0, 1, 116, 2, 108, 101, 114, 0, 1, 116, 2, 109, 97, 115, 0, 1, 116, 2, 110, 0, 1, 116, 2, 110, 105, 122, 0, 1, 116, 2, 110, 110, 0, 1, 116, 2, 114, 0, 1, 116, 2, 114, 97, 0, 1, 116, 2, 114, 111, 0, 1, 116, 2, 114, 196, 129, 0, 1, 116, 2, 116, 196, 147, 109, 0, 1, 116, 97, 100, 0, 1, 116, 97, 109, 101, 110, 105, 107, 0, 1, 116, 101, 98, 0, 1, 116, 101, 103, 0, 1, 116, 101, 109, 2, 100, 0, 1, 116, 101, 110, 0, 1, 116, 101, 116, 2, 118, 0, 1, 116, 105, 99, 0, 1, 116, 105, 108, 0, 1, 116, 110, 97, 2, 108, 0, 1, 116, 110, 97, 2, 110, 0, 1, 116, 110, 97, 112, 0, 1, 116, 110, 101, 0, 1, 116, 110, 111, 0, 1, 116, 111, 102, 2, 103, 114, 0, 1, 116, 111, 109, 2, 100, 114, 111, 0, 1, 116, 111, 114, 112, 0, 1, 116, 112, 101, 2, 21, 0, 1, 116, 112, 105, 114, 107, 0, 1, 116, 114, 97, 107, 0, 1, 116, 114, 111, 0, 1, 116, 115, 2, 107, 104, 0, 1, 116, 115, 2, 109, 97, 116, 0, 1, 116, 115, 101, 114, 104, 0, 1, 116, 115, 105, 104, 0, 1, 116, 115, 105, 114, 97, 0, 1, 116, 115, 111, 2, 112, 18, 68, 32, 0, 1, 116, 117, 97, 2, 109, 0, 1, 116, 117, 97, 2, 114, 105, 0, 1, 116, 117, 108, 112, 2, 107, 0, 1, 118, 2, 98, 0, 1, 118, 2, 107, 97, 0, 1, 118, 2, 108, 100, 0, 1, 118, 2, 108, 101, 106, 0, 1, 118, 2, 108, 102, 0, 1, 118, 2, 108, 116, 0, 1, 118, 2, 108, 117, 0, 1, 118, 2, 108, 118, 0, 1, 118, 97, 102, 0, 1, 118, 97, 108, 115, 0, 1, 118, 97, 114, 98, 0, 1, 118, 101, 2, 108, 0, 1, 118, 105, 0, 1, 118, 105, 97, 114, 2, 32, 0, 1, 118, 107, 0, 1, 118, 110, 111, 107, 0, 1, 118, 114, 101, 110, 0, 1, 119, 0, 1, 120, 0, 1, 122, 2, 106, 18, 68, 32, 12, 0, 1, 122, 2, 110, 17, 65, 116, 111, 0, 1, 122, 2, 110, 100, 0, 1, 122, 97, 114, 0, 1, 122, 101, 109, 0, 1, 122, 105, 2, 108, 0, 1, 122, 110, 101, 0, 1, 161, 197, 2, 107, 0, 1, 161, 197, 2, 115, 101, 106, 0, 1, 190, 197, 2, 107, 101, 106, 0, 1, 190, 197, 2, 110, 103, 0, 1, 190, 197, 97, 109, 0, 1, 190, 197, 100, 2, 117, 108, 0, 2, 18, 66, 0, 2, 18, 71, 0, 2, 28, 17, 12, 12, 12, 12, 0, 2, 98, 97, 109, 0, 2, 98, 106, 101, 0, 2, 100, 105, 97, 0, 2, 105, 0, 2, 107, 101, 0, 2, 107, 115, 105, 0, 2, 107, 115, 111, 108, 0, 2, 107, 116, 0, 2, 107, 116, 111, 0, 2, 107, 117, 108, 0, 2, 107, 117, 112, 0, 2, 107, 196, 129, 108, 0, 2, 108, 101, 111, 0, 2, 108, 105, 103, 0, 2, 108, 105, 109, 112, 0, 2, 108, 111, 103, 0, 2, 108, 111, 196, 163, 0, 2, 108, 196, 171, 118, 0, 2, 109, 110, 105, 98, 0, 2, 109, 196, 129, 114, 0, 2, 110, 103, 0, 2, 110, 107, 111, 0, 2, 110, 111, 0, 2, 110, 116, 111, 0, 2, 112, 99, 0, 2, 112, 101, 114, 97, 116, 0, 2, 112, 111, 0, 2, 112, 116, 105, 107, 0, 2, 112, 116, 105, 109, 0, 2, 112, 116, 105, 115, 0, 2, 112, 116, 105, 196, 183, 0, 2, 114, 97, 110, 12, 0, 2, 114, 97, 116, 0, 2, 114, 100, 0, 2, 114, 103, 0, 2, 114, 104, 105, 100, 0, 2, 114, 105, 101, 110, 0, 2, 114, 105, 103, 0, 2, 114, 105, 196, 163, 0, 2, 114, 107, 0, 2, 114, 110, 105, 116, 0, 2, 114, 116, 111, 0, 2, 114, 196, 129, 107, 0, 2, 114, 196, 129, 116, 0, 2, 114, 196, 183, 0, 2, 115, 99, 105, 108, 0, 2, 115, 109, 111, 0, 2, 117, 0, 2, 122, 111, 110, 0, 8, 2, 98, 108, 105, 103, 0, 8, 2, 98, 115, 0, 8, 2, 100, 101, 107, 0, 8, 2, 107, 115, 97, 110, 18, 69, 32, 0, 8, 2, 107, 115, 102, 0, 8, 2, 108, 97, 102, 18, 68, 32, 0, 8, 2, 108, 103, 18, 69, 32, 0, 8, 2, 110, 100, 97, 116, 114, 0, 8, 2, 112, 101, 114, 0, 8, 2, 115, 107, 97, 114, 18, 68, 32, 0, 8, 2, 118, 196, 129, 99, 0, 8, 2, 196, 188, 101, 103, 18, 68, 32, 0, 8, 98, 2, 108, 196, 171, 100, 18, 68, 32, 0, 8, 98, 2, 116, 18, 72, 32, 0, 8, 100, 2, 103, 18, 68, 32, 0, 8, 100, 2, 107, 18, 68, 32, 0, 8, 100, 110, 105, 0, 8, 100, 129, 196, 2, 108, 102, 18, 68, 0, 8, 106, 2, 116, 18, 69, 32, 0, 8, 107, 2, 106, 18, 69, 0, 8, 107, 2, 114, 196, 129, 0, 8, 107, 105, 112, 0, 8, 107, 115, 97, 2, 108, 100, 18, 68, 32, 0, 8, 108, 2, 108, 105, 116, 18, 69, 32, 0, 8, 108, 2, 110, 0, 8, 108, 2, 116, 105, 197, 134, 18, 69, 0, 8, 108, 97, 2, 116, 0, 8, 108, 97, 103, 2, 112, 18, 68, 0, 8, 108, 105, 107, 0, 8, 109, 2, 110, 0, 8, 110, 2, 97, 115, 18, 68, 32, 0, 8, 110, 2, 116, 18, 69, 32, 0, 8, 110, 2, 118, 101, 109, 98, 0, 8, 110, 97, 110, 0, 8, 110, 101, 116, 115, 0, 8, 112, 2, 108, 105, 101, 100, 0, 8, 112, 2, 110, 105, 106, 18, 68, 32, 0, 8, 112, 2, 116, 97, 197, 161, 18, 69, 0, 8, 114, 2, 98, 101, 114, 116, 0, 8, 114, 2, 100, 101, 114, 105, 107, 18, 68, 32, 0, 8, 114, 2, 107, 196, 129, 100, 18, 72, 32, 0, 8, 114, 2, 122, 101, 116, 18, 72, 32, 0, 8, 114, 2, 122, 196, 171, 110, 18, 72, 32, 0, 8, 114, 97, 98, 2, 107, 0, 8, 114, 97, 98, 2, 109, 0, 8, 114, 97, 98, 2, 110, 17, 65, 0, 8, 114, 98, 2, 107, 196, 129, 116, 18, 68, 32, 0, 8, 114, 98, 108, 117, 2, 107, 18, 69, 32, 0, 8, 114, 99, 105, 109, 0, 8, 114, 103, 2, 122, 110, 105, 106, 0, 8, 114, 107, 105, 109, 2, 12, 0, 8, 114, 116, 2, 106, 0, 8, 116, 2, 110, 105, 106, 18, 69, 32, 0, 8, 116, 2, 112, 98, 0, 8, 116, 2, 112, 105, 110, 97, 109, 0, 8, 116, 2, 112, 109, 0, 8, 116, 2, 112, 196, 129, 122, 18, 68, 32, 0, 8, 116, 2, 114, 101, 0, 8, 116, 2, 114, 112, 17, 65, 100, 0, 8, 116, 2, 114, 116, 18, 72, 32, 0, 8, 116, 105, 118, 2, 108, 100, 18, 68, 32, 0, 8, 116, 107, 101, 104, 0, 8, 116, 110, 97, 2, 197, 134, 105, 110, 18, 69, 32, 0, 8, 116, 117, 97, 0, 8, 122, 101, 2, 116, 0, 8, 122, 105, 0, 8, 161, 197, 2, 114, 116, 18, 76, 0, 114, 112, 111, 1, 107, 3, 39, 34, 48, 39, 0, 4, 116, 111, 1, 108, 2, 32, 3, 39, 47, 39, 0, 116, 111, 8, 0, 116, 111, 1, 109, 3, 39, 47, 114, 0, 4, 112, 111, 1, 114, 116, 110, 97, 3, 39, 48, 39, 0, 112, 111, 8, 116, 2, 103, 0, 112, 111, 8, 116, 2, 108, 0, 112, 111, 8, 116, 2, 110, 0, 112, 116, 111, 8, 3, 39, 48, 47, 39, 0, 107, 97, 107, 111, 1, 107, 2, 108, 3, 39, 49, 35, 49, 114, 0, 107, 111, 107, 2, 18, 68, 32, 3, 39, 49, 39, 49, 0, 107, 111, 109, 111, 1, 108, 3, 39, 49, 39, 65, 39, 0, 107, 111, 100, 1, 114, 107, 3, 39, 49, 39, 72, 0, 4, 107, 111, 1, 114, 2, 112, 101, 3, 39, 49, 114, 0, 107, 111, 1, 116, 111, 114, 112, 0, 4, 110, 1, 107, 3, 39, 50, 0, 110, 8, 108, 107, 0, 4, 110, 111, 1, 107, 3, 39, 50, 39, 0, 110, 111, 8, 109, 0, 4, 110, 111, 1, 100, 3, 39, 50, 114, 0, 110, 111, 1, 107, 101, 0, 110, 111, 1, 114, 116, 115, 97, 0, 114, 111, 1, 107, 3, 39, 52, 39, 0, 114, 110, 111, 1, 112, 3, 39, 52, 50, 39, 0, 109, 1, 107, 3, 39, 65, 0, 4, 109, 111, 1, 104, 3, 39, 65, 39, 0, 109, 111, 1, 107, 0, 109, 111, 1, 116, 0, 109, 111, 116, 2, 111, 3, 39, 65, 39, 47, 0, 109, 111, 110, 111, 115, 111, 1, 108, 3, 39, 65, 39, 50, 6, 39, 89, 39, 0, 109, 112, 111, 1, 107, 3, 39, 65, 48, 39, 0, 110, 103, 111, 108, 111, 1, 109, 3, 39, 68, 81, 39, 55, 39, 0, 110, 103, 111, 1, 109, 3, 39, 68, 81, 114, 0, 98, 1, 107, 3, 39, 71, 0, 98, 111, 1, 114, 2, 116, 3, 39, 71, 39, 0, 100, 105, 111, 8, 3, 39, 72, 37, 114, 0, 4, 100, 111, 1, 106, 3, 39, 72, 39, 0, 100, 111, 1, 114, 2, 100, 101, 110, 0, 100, 111, 8, 0, 103, 111, 1, 108, 3, 39, 81, 39, 0, 118, 111, 1, 114, 112, 3, 39, 84, 39, 0, 118, 103, 111, 114, 111, 100, 1, 110, 3, 39, 84, 81, 39, 34, 39, 72, 0, 122, 111, 1, 108, 105, 102, 3, 39, 88, 114, 0, 115, 116, 111, 106, 1, 100, 3, 39, 89, 47, 39, 57, 0, 115, 102, 111, 1, 102, 3, 39, 89, 83, 114, 0, 4, 115, 111, 1, 98, 105, 114, 3, 39, 89, 114, 0, 115, 111, 1, 108, 105, 102, 0, 111, 3, 39, 114, 0, 4, 1, 98, 2, 108, 3, 114, 0, 1, 98, 2, 114, 115, 0, 1, 99, 114, 101, 104, 2, 103, 0, 1, 100, 101, 104, 2, 110, 0, 1, 100, 107, 101, 110, 97, 0, 1, 100, 110, 2, 109, 18, 68, 32, 0, 1, 100, 110, 111, 103, 2, 108, 0, 1, 100, 114, 2, 109, 18, 68, 32, 0, 1, 101, 100, 105, 118, 0, 1, 102, 2, 110, 105, 0, 1, 103, 2, 103, 0, 1, 103, 2, 110, 105, 106, 0, 1, 103, 2, 114, 105, 106, 0, 1, 103, 2, 116, 105, 107, 0, 1, 103, 2, 116, 105, 115, 0, 1, 103, 2, 196, 163, 0, 1, 103, 97, 2, 110, 0, 1, 103, 101, 2, 110, 0, 1, 103, 101, 98, 2, 110, 105, 0, 1, 103, 101, 108, 97, 2, 114, 0, 1, 103, 101, 116, 97, 107, 2, 114, 0, 1, 103, 114, 101, 110, 101, 0, 1, 103, 114, 117, 102, 2, 110, 0, 1, 105, 2, 100, 18, 72, 32, 0, 1, 105, 2, 110, 18, 72, 32, 0, 1, 105, 100, 97, 114, 0, 1, 105, 100, 105, 0, 1, 105, 100, 117, 97, 0, 1, 105, 114, 116, 97, 112, 0, 1, 105, 118, 97, 0, 1, 106, 108, 0, 1, 107, 2, 100, 18, 77, 32, 0, 1, 107, 2, 109, 18, 69, 32, 12, 0, 1, 107, 97, 108, 2, 110, 0, 1, 107, 110, 105, 115, 0, 1, 107, 115, 2, 112, 18, 68, 32, 0, 1, 107, 115, 2, 112, 105, 106, 18, 69, 32, 0, 1, 107, 115, 2, 112, 105, 115, 0, 1, 108, 2, 103, 12, 0, 1, 108, 2, 110, 0, 1, 108, 2, 196, 163, 0, 1, 108, 2, 196, 163, 12, 0, 1, 108, 97, 2, 103, 0, 1, 108, 97, 107, 2, 114, 0, 1, 108, 104, 2, 114, 0, 1, 108, 105, 2, 103, 0, 1, 108, 107, 105, 99, 0, 1, 108, 107, 108, 111, 102, 0, 1, 108, 111, 2, 110, 105, 106, 0, 1, 108, 111, 2, 110, 105, 115, 116, 0, 1, 108, 111, 115, 0, 1, 109, 2, 99, 97, 114, 0, 1, 109, 2, 100, 18, 69, 32, 0, 1, 109, 97, 110, 105, 100, 0, 1, 109, 101, 2, 99, 105, 0, 1, 109, 105, 101, 110, 112, 0, 1, 109, 114, 97, 104, 2, 110, 0, 1, 109, 115, 111, 0, 1, 110, 2, 100, 18, 72, 32, 0, 1, 110, 2, 109, 18, 68, 32, 0, 1, 110, 2, 109, 18, 72, 32, 0, 1, 110, 2, 109, 105, 106, 18, 69, 32, 0, 1, 110, 97, 2, 100, 0, 1, 110, 105, 107, 0, 1, 110, 112, 105, 104, 2, 122, 18, 72, 32, 0, 1, 112, 2, 108, 18, 68, 32, 0, 1, 112, 2, 108, 18, 72, 32, 0, 1, 112, 109, 111, 112, 0, 1, 114, 100, 2, 109, 18, 68, 0, 1, 114, 101, 97, 0, 1, 114, 101, 108, 107, 115, 0, 1, 114, 104, 2, 110, 0, 1, 114, 105, 101, 0, 1, 114, 107, 97, 109, 0, 1, 114, 107, 105, 2, 110, 0, 1, 114, 116, 2, 102, 18, 69, 32, 0, 1, 114, 116, 2, 112, 0, 1, 114, 116, 105, 2, 110, 0, 1, 114, 116, 107, 101, 108, 101, 0, 1, 114, 116, 110, 111, 107, 0, 1, 114, 117, 107, 2, 114, 18, 72, 32, 0, 1, 115, 2, 108, 111, 0, 1, 115, 2, 114, 18, 68, 32, 12, 0, 1, 115, 2, 114, 18, 72, 32, 12, 12, 0, 1, 115, 111, 114, 101, 97, 2, 108, 0, 1, 115, 112, 97, 114, 0, 1, 115, 114, 101, 112, 2, 110, 0, 1, 116, 2, 100, 18, 72, 32, 12, 0, 1, 116, 2, 108, 18, 69, 32, 12, 0, 1, 116, 2, 110, 105, 107, 18, 69, 32, 0, 1, 116, 2, 110, 105, 115, 107, 0, 1, 116, 2, 114, 18, 72, 32, 12, 12, 0, 1, 116, 21, 2, 114, 0, 1, 116, 97, 2, 109, 0, 1, 116, 97, 114, 97, 109, 0, 1, 116, 97, 114, 111, 0, 1, 116, 107, 111, 0, 1, 116, 108, 97, 100, 2, 110, 0, 1, 116, 110, 97, 2, 110, 18, 68, 32, 0, 1, 116, 110, 111, 112, 2, 110, 0, 1, 116, 111, 2, 112, 18, 68, 32, 0, 1, 116, 111, 102, 0, 1, 116, 111, 110, 111, 109, 2, 110, 0, 1, 116, 112, 2, 109, 18, 68, 32, 0, 1, 116, 117, 2, 112, 105, 0, 1, 117, 108, 102, 2, 114, 0, 1, 122, 2, 110, 0, 1, 122, 2, 114, 18, 68, 32, 12, 0, 1, 122, 2, 114, 18, 72, 32, 12, 12, 0, 1, 122, 105, 112, 101, 2, 100, 0, 2, 32, 0, 2, 108, 18, 68, 32, 12, 0, 2, 110, 18, 68, 32, 12, 0, 2, 112, 18, 68, 32, 12, 0, 2, 114, 18, 68, 32, 12, 0, 2, 122, 18, 68, 32, 0, 2, 122, 18, 72, 32, 12, 0, 8, 2, 109, 105, 0, 8, 2, 109, 115, 0, 8, 2, 112, 101, 114, 18, 69, 32, 0, 8, 100, 2, 122, 18, 69, 32, 12, 12, 0, 8, 101, 114, 101, 116, 115, 0, 8, 102, 2, 108, 105, 106, 18, 69, 32, 0, 8, 103, 105, 2, 114, 18, 68, 32, 0, 8, 106, 2, 103, 18, 68, 32, 0, 8, 107, 101, 0, 8, 108, 2, 197, 190, 18, 69, 32, 0, 8, 108, 103, 2, 114, 105, 106, 18, 69, 32, 0, 8, 109, 2, 110, 105, 107, 18, 69, 32, 0, 8, 109, 2, 122, 117, 0, 8, 109, 97, 114, 2, 110, 18, 69, 32, 0, 8, 109, 115, 2, 103, 18, 68, 32, 0, 8, 114, 97, 98, 2, 110, 18, 68, 32, 0, 8, 115, 107, 111, 2, 108, 18, 68, 32, 0, 8, 116, 2, 110, 117, 115, 18, 68, 32, 0, 8, 116, 2, 114, 105, 106, 18, 68, 32, 0, 8, 116, 110, 97, 102, 2, 109, 18, 68, 32, 0, 8, 116, 114, 97, 107, 2, 110, 18, 68, 32, 0, 108, 111, 1, 112, 2, 32, 3, 114, 55, 114, 0, 115, 116, 111, 112, 1, 116, 117, 97, 3, 114, 89, 47, 39, 48, 0, 4, 3, 119, 0, 1, 98, 2, 32, 0, 1, 98, 2, 108, 111, 197, 161, 0, 1, 98, 2, 108, 196, 171, 100, 18, 73, 32, 0, 1, 98, 2, 108, 196, 171, 106, 0, 1, 98, 2, 108, 196, 171, 115, 0, 1, 98, 2, 108, 196, 171, 116, 0, 1, 98, 2, 108, 196, 171, 197, 161, 0, 1, 98, 97, 118, 2, 108, 18, 72, 32, 0, 1, 98, 129, 196, 2, 108, 0, 1, 99, 2, 32, 0, 1, 100, 2, 32, 0, 1, 100, 2, 122, 18, 72, 32, 12, 12, 0, 1, 102, 114, 147, 196, 115, 0, 1, 103, 2, 32, 0, 1, 103, 2, 114, 111, 0, 1, 103, 97, 109, 2, 110, 0, 1, 103, 97, 118, 2, 110, 0, 1, 103, 105, 97, 100, 2, 110, 0, 1, 103, 105, 97, 109, 2, 110, 0, 1, 103, 105, 97, 122, 0, 1, 103, 108, 105, 2, 110, 18, 70, 32, 0, 1, 103, 111, 108, 115, 0, 1, 103, 114, 97, 109, 2, 110, 0, 1, 103, 117, 97, 2, 110, 0, 1, 103, 171, 196, 108, 0, 1, 106, 2, 32, 0, 1, 106, 2, 110, 18, 70, 32, 0, 1, 107, 2, 32, 0, 1, 107, 2, 107, 111, 103, 0, 1, 107, 2, 107, 116, 196, 147, 108, 0, 1, 107, 2, 110, 18, 70, 32, 0, 1, 107, 2, 112, 106, 0, 1, 107, 2, 112, 196, 147, 106, 18, 68, 32, 0, 1, 107, 2, 112, 196, 147, 106, 18, 69, 32, 0, 1, 107, 2, 114, 18, 70, 32, 12, 0, 1, 107, 2, 197, 134, 18, 70, 32, 0, 1, 107, 97, 114, 116, 0, 1, 107, 101, 105, 110, 0, 1, 107, 107, 105, 116, 2, 32, 0, 1, 107, 108, 97, 109, 2, 18, 75, 0, 1, 107, 108, 97, 161, 197, 0, 1, 107, 114, 147, 196, 112, 2, 110, 0, 1, 107, 114, 147, 196, 112, 2, 197, 134, 0, 1, 107, 115, 2, 108, 0, 1, 107, 115, 2, 108, 18, 69, 32, 0, 1, 107, 115, 97, 118, 0, 1, 107, 171, 197, 107, 0, 1, 108, 2, 32, 0, 1, 108, 2, 122, 18, 72, 32, 0, 1, 108, 103, 97, 2, 110, 18, 69, 32, 0, 1, 108, 103, 97, 110, 0, 1, 108, 103, 101, 2, 110, 0, 1, 108, 105, 97, 100, 2, 110, 0, 1, 108, 105, 100, 2, 110, 0, 1, 108, 105, 100, 2, 197, 134, 0, 1, 108, 105, 122, 2, 110, 0, 1, 108, 105, 122, 2, 197, 134, 0, 1, 108, 111, 107, 115, 2, 18, 74, 0, 1, 108, 111, 107, 115, 2, 18, 75, 0, 1, 108, 111, 115, 2, 115, 32, 0, 1, 108, 111, 115, 2, 116, 0, 1, 108, 111, 115, 2, 116, 32, 0, 1, 108, 111, 115, 2, 197, 161, 0, 1, 108, 115, 2, 103, 18, 68, 32, 0, 1, 108, 115, 2, 103, 111, 0, 1, 108, 147, 196, 2, 32, 0, 1, 108, 147, 196, 99, 0, 1, 108, 161, 197, 2, 103, 18, 68, 32, 0, 1, 109, 2, 32, 0, 1, 109, 105, 97, 122, 0, 1, 109, 115, 2, 107, 0, 1, 109, 115, 114, 101, 118, 0, 1, 109, 122, 105, 118, 0, 1, 110, 2, 32, 0, 1, 110, 2, 108, 105, 107, 0, 1, 110, 2, 109, 18, 69, 32, 0, 1, 110, 97, 161, 197, 0, 1, 110, 101, 116, 115, 2, 18, 74, 0, 1, 110, 101, 116, 115, 2, 18, 75, 0, 1, 110, 110, 97, 118, 0, 1, 112, 2, 32, 0, 1, 112, 2, 114, 97, 0, 1, 112, 2, 115, 116, 111, 0, 1, 112, 2, 115, 116, 196, 171, 0, 1, 114, 2, 32, 0, 1, 114, 2, 98, 101, 197, 190, 0, 1, 114, 2, 107, 116, 117, 0, 1, 114, 2, 122, 18, 72, 32, 0, 1, 114, 97, 98, 2, 107, 108, 0, 1, 114, 97, 98, 2, 107, 196, 188, 0, 1, 114, 98, 2, 32, 0, 1, 114, 100, 2, 32, 0, 1, 114, 103, 2, 122, 12, 0, 1, 114, 107, 2, 103, 0, 1, 114, 107, 2, 107, 111, 0, 1, 114, 107, 2, 112, 196, 188, 111, 0, 1, 114, 112, 97, 2, 99, 18, 72, 32, 0, 1, 114, 112, 97, 2, 107, 0, 1, 114, 116, 171, 196, 118, 115, 0, 1, 115, 2, 32, 0, 1, 115, 2, 108, 18, 68, 32, 0, 1, 115, 2, 108, 18, 70, 32, 0, 1, 115, 2, 108, 111, 116, 0, 1, 115, 2, 108, 111, 197, 161, 0, 1, 115, 2, 108, 196, 171, 18, 75, 0, 1, 116, 2, 32, 0, 1, 116, 2, 110, 18, 70, 32, 0, 1, 116, 2, 114, 110, 12, 0, 1, 116, 2, 114, 197, 134, 12, 0, 1, 116, 101, 105, 99, 2, 107, 0, 1, 116, 110, 97, 107, 0, 1, 116, 114, 111, 107, 2, 115, 32, 0, 1, 116, 114, 111, 112, 115, 0, 1, 116, 115, 2, 112, 111, 0, 1, 116, 117, 97, 188, 196, 0, 1, 116, 129, 196, 2, 32, 0, 1, 116, 147, 196, 2, 32, 0, 1, 116, 171, 196, 118, 2, 108, 18, 68, 32, 0, 1, 118, 2, 32, 0, 1, 118, 97, 0, 1, 118, 101, 105, 114, 0, 1, 118, 108, 97, 0, 1, 118, 129, 196, 108, 98, 0, 1, 118, 171, 196, 114, 98, 0, 1, 122, 2, 32, 0, 1, 122, 105, 98, 2, 18, 75, 12, 0, 1, 134, 197, 0, 1, 141, 196, 0, 1, 161, 197, 2, 32, 0, 1, 161, 197, 111, 2, 32, 0, 1, 161, 197, 117, 2, 32, 0, 1, 163, 196, 2, 32, 0, 1, 183, 196, 0, 1, 188, 196, 0, 1, 190, 197, 0, 2, 18, 67, 0, 2, 100, 101, 114, 101, 0, 2, 100, 101, 114, 196, 147, 0, 2, 110, 97, 107, 116, 32, 0, 2, 115, 32, 0, 2, 115, 116, 32, 0, 2, 116, 32, 12, 12, 0, 2, 116, 105, 101, 115, 32, 12, 0, 2, 197, 161, 115, 32, 0, 2, 197, 161, 197, 134, 0, 8, 2, 108, 18, 69, 32, 12, 0, 8, 2, 114, 18, 70, 32, 0, 8, 98, 2, 108, 97, 32, 0, 8, 98, 2, 108, 117, 0, 8, 98, 2, 108, 196, 129, 109, 32, 0, 8, 98, 2, 122, 18, 72, 32, 12, 0, 8, 98, 2, 122, 97, 32, 0, 8, 100, 2, 110, 18, 69, 32, 12, 12, 0, 8, 100, 171, 196, 112, 115, 2, 108, 18, 69, 32, 0, 8, 103, 2, 114, 97, 32, 0, 8, 103, 2, 114, 111, 115, 32, 12, 0, 8, 106, 2, 32, 0, 8, 106, 2, 122, 97, 32, 0, 8, 107, 2, 100, 18, 72, 32, 0, 8, 107, 2, 112, 18, 69, 32, 0, 8, 107, 2, 112, 196, 129, 32, 0, 8, 107, 2, 114, 18, 72, 32, 0, 8, 107, 2, 114, 97, 32, 0, 8, 107, 2, 114, 100, 105, 114, 0, 8, 107, 2, 114, 100, 122, 0, 8, 107, 2, 118, 196, 129, 114, 110, 18, 70, 32, 0, 8, 107, 101, 110, 2, 32, 0, 8, 107, 115, 2, 112, 18, 68, 32, 0, 8, 107, 115, 97, 112, 2, 112, 18, 68, 32, 0, 8, 108, 2, 103, 18, 68, 32, 0, 8, 108, 2, 110, 18, 72, 32, 0, 8, 108, 105, 112, 2, 116, 32, 0, 8, 108, 147, 196, 116, 2, 116, 117, 32, 0, 8, 109, 2, 100, 18, 72, 32, 0, 8, 109, 105, 97, 108, 2, 110, 18, 70, 32, 0, 8, 109, 117, 107, 2, 100, 18, 72, 32, 0, 8, 110, 2, 12, 0, 8, 112, 2, 108, 18, 70, 32, 0, 8, 112, 2, 108, 105, 101, 0, 8, 112, 2, 108, 105, 106, 18, 69, 32, 0, 8, 112, 2, 112, 18, 72, 32, 0, 8, 112, 2, 196, 188, 0, 8, 112, 129, 196, 114, 2, 32, 0, 8, 114, 2, 109, 18, 69, 32, 0, 8, 114, 101, 116, 115, 2, 115, 32, 0, 8, 114, 112, 2, 106, 196, 129, 109, 32, 0, 8, 114, 112, 2, 109, 32, 0, 8, 114, 112, 2, 109, 98, 0, 8, 114, 112, 2, 109, 101, 115, 0, 8, 114, 116, 115, 2, 112, 18, 68, 32, 0, 8, 114, 116, 115, 97, 107, 2, 108, 18, 70, 32, 0, 8, 116, 2, 12, 0, 8, 116, 2, 114, 101, 105, 122, 32, 0, 8, 116, 2, 114, 117, 100, 0, 8, 116, 2, 122, 105, 101, 109, 32, 0, 8, 116, 97, 100, 2, 115, 32, 0, 8, 116, 110, 111, 107, 2, 115, 32, 0, 8, 116, 110, 111, 108, 98, 2, 115, 32, 0, 8, 116, 115, 2, 114, 18, 72, 32, 0, 8, 116, 115, 97, 115, 2, 112, 97, 109, 32, 0, 8, 134, 197, 161, 197, 2, 114, 18, 70, 32, 0, 8, 161, 197, 2, 122, 105, 101, 109, 32, 0, 8, 183, 196, 161, 197, 2, 114, 18, 70, 32, 0, 116, 111, 2, 32, 3, 119, 47, 119, 0, 112, 8, 114, 116, 2, 18, 68, 32, 3, 119, 48, 0, 4, 112, 111, 1, 107, 3, 119, 48, 119, 0, 112, 111, 1, 116, 2, 116, 0, 112, 111, 1, 116, 2, 197, 161, 0, 108, 1, 112, 171, 196, 115, 2, 18, 68, 32, 3, 119, 55, 0, 4, 108, 111, 1, 107, 115, 3, 119, 55, 119, 0, 108, 111, 1, 108, 2, 18, 75, 0, 108, 111, 8, 108, 2, 18, 74, 0, 98, 111, 8, 114, 2, 116, 32, 3, 119, 71, 119, 0, 4, 100, 111, 1, 107, 2, 108, 3, 119, 72, 119, 0, 100, 111, 8, 2, 115, 32, 0, 103, 1, 114, 112, 115, 3, 119, 81, 0, 122, 111, 2, 108, 18, 68, 32, 3, 119, 88, 119, 0, 115, 116, 1, 114, 112, 115, 3, 119, 89, 47, 0, 115, 116, 111, 2, 18, 75, 3, 119, 89, 47, 119, 0, 7, 6, 112, 0, 3, 48, 0, 117, 115, 8, 3, 48, 40, 89, 0, 7, 6, 113, 0, 3, 49, 84, 0, 7, 6, 114, 0, 3, 52, 0, 7, 6, 115, 0, 3, 89, 0, 7, 6, 116, 0, 3, 47, 0, 1, 115, 2, 115, 3, 47, 12, 0, 111, 8, 2, 32, 3, 47, 119, 0, 7, 6, 117, 0, 3, 40, 0, 105, 3, 121, 0, 7, 6, 118, 0, 3, 84, 0, 105, 115, 8, 3, 84, 37, 89, 0, 7, 6, 119, 0, 3, 84, 0, 7, 6, 120, 0, 3, 49, 89, 0, 7, 6, 121, 0, 3, 57, 0, 7, 6, 122, 0, 3, 88, 0, 7, 6, 0, 4, 33, 2, 33, 3, 0, 4, 35, 1, 35, 3, 0, 4, 39, 3, 0, 4, 46, 1, 46, 3, 0, 58, 1, 32, 15, 2, 32, 15, 15, 32, 3, 0, 46, 2, 46, 3, 9, 0, 33, 3, 9, 37, 88, 89, 118, 49, 40, 65, 88, 108, 65, 36, 9, 0, 4, 45, 1, 32, 17, 65, 2, 32, 15, 3, 10, 0, 45, 1, 32, 17, 67, 2, 32, 15, 0, 35, 1, 35, 35, 2, 32, 3, 24, 0, 58, 3, 49, 39, 55, 89, 0, 33, 61, 3, 50, 35, 84, 15, 84, 122, 50, 113, 72, 89, 0, 4, 35, 1, 32, 17, 65, 3, 52, 36, 89, 47, 108, 47, 36, 0, 35, 1, 32, 17, 67, 0, 62, 61, 3, 55, 6, 122, 55, 113, 49, 89, 15, 4, 84, 116, 15, 84, 6, 122, 50, 113, 72, 89, 0, 60, 61, 3, 65, 35, 88, 113, 49, 89, 15, 4, 84, 116, 15, 84, 6, 122, 50, 113, 72, 89, 0, 45, 8, 32, 2, 32, 15, 3, 65, 108, 50, 40, 89, 0, 36, 3, 72, 39, 55, 113, 34, 37, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts39 = FileInMemory_createWithData (12327, reinterpret_cast (&espeakdata_dicts39_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/lv_dict", U"lv"); Collection_addItem (me.peek(), espeakdata_dicts39.transfer()); static unsigned char espeakdata_dicts40_data[4946] = { 0, 4, 0, 0, 152, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 138, 208, 184, 208, 188, 208, 176, 208, 176, 209, 130, 76, 0, 0, 15, 140, 208, 189, 208, 181, 208, 188, 208, 176, 208, 176, 209, 130, 76, 0, 0, 0, 0, 0, 0, 0, 0, 13, 1, 33, 6, 37, 88, 84, 138, 76, 50, 138, 49, 0, 0, 0, 11, 1, 35, 71, 14, 16, 6, 39, 57, 10, 0, 0, 0, 10, 1, 37, 48, 6, 39, 89, 47, 39, 0, 0, 7, 1, 38, 10, 6, 37, 0, 0, 0, 0, 0, 0, 8, 1, 43, 48, 55, 40, 89, 0, 0, 0, 0, 0, 11, 1, 47, 49, 14, 16, 6, 39, 88, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 5, 95, 48, 1, 14, 4, 37, 0, 0, 0, 13, 1, 58, 72, 84, 36, 10, 47, 39, 76, 49, 37, 0, 0, 0, 0, 0, 0, 0, 8, 1, 64, 10, 6, 36, 47, 0, 0, 0, 0, 0, 7, 65, 68, 49, 84, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 49, 77, 52, 71, 37, 55, 37, 6, 39, 50, 0, 0, 17, 65, 92, 72, 84, 39, 89, 47, 14, 16, 40, 49, 39, 15, 84, 13, 0, 0, 0, 16, 1, 94, 117, 6, 37, 34, 49, 40, 65, 83, 55, 36, 49, 89, 0, 0, 0, 7, 65, 96, 37, 49, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 104, 88, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 1, 126, 47, 6, 37, 55, 72, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 208, 189, 208, 181, 208, 181, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 4, 95, 4, 16, 20, 9, 88, 6, 35, 48, 37, 16, 49, 122, 10, 0, 0, 0, 0, 9, 134, 209, 129, 209, 130, 208, 181, 72, 0, 0, 0, 0, 13, 138, 208, 189, 208, 181, 209, 129, 209, 130, 208, 181, 76, 0, 0, 15, 140, 208, 189, 208, 181, 208, 188, 208, 176, 209, 130, 208, 181, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 136, 208, 184, 208, 188, 208, 176, 209, 136, 76, 0, 0, 0, 0, 0, 0, 9, 134, 209, 129, 209, 131, 208, 188, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 138, 208, 189, 208, 181, 209, 129, 209, 131, 208, 188, 76, 0, 0, 0, 20, 3, 226, 132, 162, 48, 14, 16, 39, 37, 88, 84, 6, 39, 72, 37, 47, 36, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 136, 208, 189, 208, 181, 208, 179, 208, 190, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 136, 208, 186, 208, 190, 208, 179, 208, 190, 8, 0, 0, 0, 18, 3, 226, 128, 166, 47, 14, 16, 6, 37, 15, 47, 6, 39, 76, 49, 37, 0, 0, 19, 3, 226, 128, 161, 72, 84, 6, 39, 36, 50, 15, 49, 14, 16, 6, 89, 47, 0, 0, 11, 3, 226, 128, 160, 49, 14, 16, 89, 47, 0, 0, 0, 20, 3, 226, 128, 162, 81, 6, 39, 55, 36, 65, 35, 15, 47, 6, 39, 76, 49, 122, 0, 0, 0, 11, 3, 226, 130, 172, 6, 36, 84, 51, 39, 0, 0, 0, 0, 0, 0, 11, 136, 208, 184, 208, 188, 208, 176, 208, 188, 76, 0, 11, 3, 95, 49, 6, 6, 36, 72, 50, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 95, 50, 6, 72, 84, 6, 36, 0, 0, 0, 0, 0, 13, 138, 208, 184, 208, 188, 208, 176, 208, 188, 208, 181, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 226, 128, 176, 48, 14, 16, 6, 39, 65, 37, 55, 0, 0, 11, 136, 208, 189, 208, 181, 208, 188, 208, 176, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 51, 88, 47, 14, 16, 6, 37, 109, 89, 109, 47, 0, 0, 11, 3, 95, 48, 67, 89, 47, 6, 39, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 3, 95, 49, 57, 72, 109, 84, 109, 47, 50, 6, 35, 36, 89, 36, 47, 0, 0, 17, 3, 95, 49, 56, 39, 89, 40, 65, 50, 6, 35, 36, 89, 36, 47, 0, 0, 14, 3, 95, 50, 67, 72, 84, 6, 36, 89, 47, 6, 35, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 49, 49, 36, 72, 138, 50, 6, 35, 36, 89, 36, 47, 0, 0, 12, 3, 95, 49, 48, 72, 6, 109, 89, 109, 47, 0, 0, 17, 3, 95, 49, 51, 47, 14, 16, 37, 50, 6, 35, 36, 89, 36, 47, 0, 0, 16, 3, 95, 49, 50, 72, 84, 35, 50, 6, 35, 36, 89, 36, 47, 0, 0, 16, 3, 95, 49, 53, 48, 109, 47, 50, 6, 35, 36, 89, 36, 47, 0, 0, 19, 3, 95, 49, 52, 76, 109, 47, 37, 34, 37, 50, 6, 35, 36, 89, 36, 47, 0, 0, 18, 3, 95, 49, 55, 89, 109, 72, 40, 65, 50, 6, 35, 36, 89, 36, 47, 0, 0, 16, 3, 95, 49, 54, 91, 109, 89, 50, 6, 35, 36, 89, 36, 47, 0, 0, 0, 17, 3, 95, 55, 88, 89, 109, 72, 6, 40, 65, 72, 109, 89, 109, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 54, 67, 91, 6, 109, 89, 47, 6, 39, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 50, 88, 72, 84, 6, 35, 109, 89, 109, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 95, 63, 63, 88, 50, 35, 49, 0, 0, 0, 0, 17, 3, 95, 52, 88, 76, 109, 47, 37, 44, 6, 37, 109, 89, 109, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 53, 88, 48, 6, 109, 109, 89, 109, 47, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 208, 186, 208, 190, 209, 152, 76, 0, 13, 3, 95, 54, 88, 91, 6, 109, 109, 89, 109, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 56, 88, 39, 89, 6, 40, 65, 72, 109, 89, 109, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 57, 88, 72, 109, 84, 6, 109, 109, 89, 109, 47, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 63, 65, 71, 40, 49, 84, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 134, 208, 184, 208, 187, 208, 184, 72, 8, 9, 134, 208, 184, 208, 187, 208, 184, 8, 0, 0, 0, 0, 0, 0, 11, 136, 208, 177, 208, 184, 208, 187, 208, 176, 72, 0, 0, 0, 0, 15, 4, 95, 48, 77, 52, 71, 37, 55, 37, 6, 39, 50, 37, 0, 0, 0, 15, 4, 95, 48, 77, 50, 65, 37, 55, 37, 6, 39, 50, 37, 0, 0, 16, 4, 95, 48, 77, 51, 65, 6, 37, 55, 37, 35, 34, 72, 138, 0, 0, 7, 132, 208, 187, 208, 184, 72, 0, 14, 4, 95, 48, 77, 49, 6, 37, 55, 57, 35, 72, 37, 0, 0, 11, 136, 208, 177, 208, 184, 208, 187, 208, 190, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 208, 184, 208, 188, 208, 176, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 3, 95, 194, 173, 48, 14, 16, 6, 37, 84, 14, 16, 36, 65, 36, 50, 122, 15, 117, 6, 44, 47, 6, 37, 76, 49, 122, 0, 0, 0, 24, 3, 95, 194, 171, 6, 39, 47, 84, 39, 51, 36, 50, 15, 50, 6, 35, 84, 39, 72, 50, 138, 49, 0, 0, 0, 0, 9, 134, 208, 177, 208, 184, 208, 187, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 136, 208, 189, 208, 181, 209, 129, 208, 181, 76, 0, 25, 3, 95, 194, 187, 88, 6, 35, 47, 84, 39, 51, 36, 50, 15, 50, 6, 35, 84, 39, 72, 50, 138, 49, 0, 0, 0, 11, 136, 208, 189, 208, 181, 209, 129, 208, 184, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 2, 195, 151, 48, 6, 39, 0, 0, 0, 0, 20, 2, 197, 130, 55, 13, 15, 89, 122, 15, 117, 6, 44, 47, 6, 37, 117, 39, 65, 0, 0, 0, 0, 0, 0, 8, 2, 194, 167, 72, 36, 55, 0, 0, 12, 2, 194, 164, 84, 6, 35, 55, 40, 47, 122, 0, 0, 0, 0, 0, 0, 0, 19, 2, 194, 174, 51, 6, 36, 81, 37, 89, 47, 14, 16, 35, 117, 138, 57, 122, 0, 0, 0, 0, 0, 0, 0, 16, 2, 194, 168, 48, 14, 16, 6, 37, 57, 36, 81, 55, 122, 89, 0, 0, 13, 138, 208, 184, 208, 188, 208, 176, 209, 130, 208, 181, 76, 21, 2, 194, 169, 6, 35, 84, 47, 39, 51, 89, 49, 122, 15, 48, 14, 16, 35, 84, 122, 0, 0, 9, 2, 194, 182, 76, 55, 36, 50, 0, 0, 7, 2, 194, 183, 48, 39, 0, 0, 0, 12, 2, 194, 181, 65, 6, 37, 49, 14, 16, 39, 0, 0, 0, 0, 12, 2, 194, 176, 89, 47, 6, 36, 48, 36, 50, 0, 0, 0, 0, 15, 2, 195, 183, 48, 39, 72, 6, 36, 61, 4, 36, 50, 39, 0, 0, 0, 0, 0, 0, 12, 2, 194, 184, 89, 36, 72, 6, 37, 55, 122, 0, 0, 0, 9, 134, 209, 136, 209, 130, 208, 190, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 2, 203, 152, 71, 14, 16, 6, 36, 84, 37, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 209, 135, 76, 13, 0, 0, 7, 2, 209, 134, 117, 13, 0, 0, 7, 2, 209, 133, 101, 13, 0, 0, 7, 2, 209, 132, 83, 13, 0, 0, 0, 7, 2, 209, 130, 47, 13, 0, 0, 7, 2, 209, 129, 89, 13, 0, 0, 7, 2, 209, 128, 51, 13, 0, 0, 0, 0, 0, 0, 0, 8, 132, 208, 183, 208, 176, 72, 28, 0, 0, 7, 2, 209, 136, 91, 13, 0, 0, 0, 14, 2, 95, 34, 50, 6, 35, 84, 39, 72, 50, 138, 49, 0, 0, 7, 2, 209, 149, 118, 13, 0, 0, 0, 15, 2, 95, 39, 6, 35, 48, 39, 89, 47, 14, 16, 39, 83, 0, 7, 2, 209, 147, 77, 13, 0, 0, 18, 2, 95, 38, 47, 6, 44, 81, 6, 39, 84, 89, 49, 39, 15, 6, 37, 0, 0, 0, 11, 2, 95, 36, 72, 6, 39, 55, 122, 51, 0, 0, 7, 2, 209, 159, 75, 13, 0, 0, 15, 2, 95, 42, 118, 84, 6, 36, 88, 72, 37, 76, 49, 122, 0, 15, 2, 95, 42, 118, 84, 6, 36, 88, 72, 37, 76, 49, 13, 0, 0, 25, 2, 95, 41, 88, 6, 35, 47, 84, 39, 51, 36, 50, 122, 15, 88, 6, 35, 81, 14, 16, 35, 72, 122, 0, 0, 24, 2, 95, 40, 6, 39, 47, 84, 39, 51, 36, 50, 122, 15, 88, 6, 35, 81, 14, 16, 35, 72, 122, 0, 7, 2, 209, 156, 141, 13, 0, 0, 0, 11, 2, 95, 46, 47, 6, 39, 76, 49, 122, 0, 7, 2, 209, 154, 67, 13, 0, 0, 14, 2, 95, 45, 117, 6, 44, 47, 6, 37, 76, 49, 122, 0, 11, 2, 95, 45, 65, 6, 37, 50, 40, 89, 0, 7, 2, 209, 153, 61, 13, 0, 0, 13, 2, 95, 44, 88, 6, 35, 48, 37, 51, 49, 122, 0, 7, 2, 209, 152, 57, 136, 0, 0, 9, 2, 95, 51, 47, 51, 6, 37, 0, 0, 10, 2, 95, 50, 72, 6, 84, 6, 35, 0, 0, 10, 2, 95, 49, 6, 36, 72, 36, 50, 0, 0, 10, 2, 95, 48, 50, 6, 40, 55, 122, 0, 0, 11, 2, 95, 55, 89, 6, 109, 72, 40, 65, 0, 0, 10, 2, 95, 54, 91, 6, 109, 89, 47, 0, 0, 9, 2, 95, 53, 48, 6, 109, 47, 0, 0, 12, 2, 95, 52, 76, 6, 109, 47, 138, 16, 138, 0, 0, 19, 2, 95, 59, 47, 6, 39, 76, 49, 122, 88, 4, 35, 48, 37, 51, 49, 35, 0, 7, 2, 208, 183, 88, 13, 0, 0, 7, 2, 208, 182, 90, 13, 0, 0, 7, 2, 208, 181, 109, 0, 14, 6, 130, 208, 181, 72, 28, 11, 2, 95, 57, 72, 6, 109, 84, 109, 47, 0, 0, 10, 2, 95, 56, 6, 39, 89, 40, 65, 0, 7, 2, 208, 180, 72, 13, 0, 0, 15, 2, 95, 63, 48, 34, 6, 35, 91, 35, 55, 50, 37, 49, 0, 7, 2, 208, 179, 81, 13, 0, 0, 18, 2, 95, 62, 48, 39, 81, 6, 39, 55, 36, 65, 39, 15, 6, 39, 72, 0, 7, 2, 208, 178, 84, 13, 0, 0, 13, 2, 95, 61, 6, 36, 72, 50, 122, 49, 84, 39, 0, 13, 2, 95, 61, 6, 36, 72, 50, 122, 49, 84, 39, 0, 7, 2, 208, 177, 71, 13, 0, 0, 7, 2, 208, 176, 35, 0, 14, 8, 2, 208, 176, 35, 0, 72, 8, 16, 2, 95, 60, 48, 6, 39, 65, 35, 55, 39, 15, 6, 39, 72, 0, 0, 7, 2, 208, 191, 48, 13, 0, 0, 0, 7, 2, 208, 189, 50, 13, 0, 0, 13, 138, 208, 189, 208, 181, 208, 188, 208, 176, 209, 136, 76, 18, 2, 95, 64, 47, 6, 44, 81, 6, 39, 84, 89, 49, 39, 15, 6, 35, 0, 7, 2, 208, 188, 65, 13, 0, 0, 7, 2, 208, 187, 55, 13, 0, 0, 7, 2, 208, 186, 49, 13, 0, 0, 0, 8, 2, 208, 184, 37, 10, 0, 14, 9, 2, 208, 184, 37, 9, 0, 72, 8, 13, 2, 92, 92, 71, 6, 109, 49, 89, 55, 109, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 4, 95, 226, 128, 154, 6, 39, 47, 84, 39, 51, 36, 50, 15, 50, 6, 35, 84, 39, 72, 50, 138, 49, 0, 0, 26, 4, 95, 226, 128, 153, 6, 36, 72, 37, 50, 36, 76, 36, 50, 15, 50, 6, 35, 84, 39, 72, 50, 138, 49, 0, 0, 25, 4, 95, 226, 128, 152, 6, 39, 47, 84, 39, 51, 36, 50, 15, 50, 6, 35, 84, 39, 72, 50, 138, 49, 0, 0, 0, 25, 4, 95, 226, 128, 158, 88, 35, 47, 84, 39, 51, 36, 50, 15, 50, 6, 35, 84, 39, 72, 50, 138, 49, 0, 0, 32, 2, 95, 91, 6, 39, 47, 84, 39, 51, 36, 50, 122, 15, 89, 51, 6, 36, 72, 50, 122, 15, 88, 6, 35, 81, 14, 16, 35, 72, 122, 0, 26, 4, 95, 226, 128, 157, 88, 6, 35, 47, 84, 39, 51, 36, 50, 15, 50, 6, 35, 84, 39, 72, 50, 138, 49, 0, 0, 25, 4, 95, 226, 128, 156, 6, 39, 47, 84, 39, 51, 36, 50, 15, 50, 6, 35, 84, 39, 72, 50, 138, 49, 0, 0, 15, 4, 95, 226, 128, 147, 109, 50, 15, 117, 6, 44, 47, 122, 0, 0, 0, 10, 2, 95, 95, 117, 6, 44, 47, 122, 0, 0, 0, 33, 2, 95, 93, 88, 6, 35, 47, 84, 39, 51, 36, 50, 122, 15, 89, 51, 6, 36, 72, 50, 122, 15, 88, 6, 35, 81, 14, 16, 35, 72, 122, 0, 0, 0, 0, 15, 4, 95, 226, 128, 148, 109, 65, 15, 117, 6, 44, 47, 122, 0, 0, 13, 138, 208, 189, 208, 181, 209, 129, 208, 188, 208, 181, 76, 9, 134, 209, 129, 208, 188, 208, 181, 72, 0, 13, 2, 95, 96, 81, 14, 16, 6, 35, 84, 37, 89, 0, 0, 15, 140, 208, 189, 208, 181, 208, 188, 208, 176, 208, 188, 208, 181, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 138, 208, 189, 208, 181, 208, 188, 208, 176, 208, 188, 76, 0, 0, 0, 0, 0, 25, 4, 95, 226, 128, 185, 6, 39, 47, 84, 39, 51, 36, 50, 15, 50, 6, 35, 84, 39, 72, 50, 138, 49, 0, 0, 0, 0, 0, 32, 2, 95, 123, 6, 39, 47, 84, 39, 51, 36, 50, 122, 15, 81, 6, 39, 55, 36, 65, 122, 15, 88, 6, 35, 81, 14, 16, 35, 72, 122, 0, 0, 0, 0, 0, 0, 0, 34, 2, 95, 125, 88, 6, 35, 47, 84, 39, 51, 36, 50, 122, 15, 81, 6, 39, 55, 36, 65, 35, 122, 15, 88, 6, 35, 81, 14, 16, 35, 72, 122, 0, 0, 21, 2, 95, 124, 84, 36, 51, 47, 37, 49, 35, 55, 50, 122, 15, 117, 6, 44, 47, 122, 0, 0, 7, 132, 209, 129, 208, 181, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 132, 209, 129, 208, 184, 72, 0, 0, 10, 4, 209, 129, 208, 190, 89, 10, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 208, 177, 208, 181, 208, 176, 72, 0, 0, 0, 0, 17, 5, 95, 49, 77, 65, 51, 65, 6, 37, 55, 37, 35, 34, 72, 35, 0, 0, 15, 5, 95, 49, 77, 65, 50, 65, 37, 55, 37, 6, 39, 50, 0, 0, 15, 5, 95, 49, 77, 65, 49, 6, 37, 55, 57, 35, 72, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 132, 208, 178, 208, 190, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 20, 0, 0, 97, 0, 0, 0, 48, 4, 0, 0, 98, 0, 0, 0, 49, 4, 0, 0, 99, 0, 0, 0, 70, 4, 0, 0, 7, 1, 0, 0, 91, 4, 0, 0, 13, 1, 0, 0, 71, 4, 0, 0, 100, 0, 126, 1, 95, 4, 0, 0, 100, 0, 122, 0, 85, 4, 0, 0, 100, 0, 0, 0, 52, 4, 0, 0, 17, 1, 0, 0, 82, 4, 0, 0, 101, 0, 0, 0, 53, 4, 0, 0, 102, 0, 0, 0, 68, 4, 0, 0, 103, 0, 0, 0, 51, 4, 0, 0, 104, 0, 0, 0, 69, 4, 0, 0, 105, 0, 0, 0, 56, 4, 0, 0, 106, 0, 0, 0, 88, 4, 0, 0, 107, 0, 0, 0, 58, 4, 0, 0, 108, 0, 106, 0, 89, 4, 0, 0, 108, 0, 0, 0, 59, 4, 0, 0, 109, 0, 0, 0, 60, 4, 0, 0, 110, 0, 106, 0, 90, 4, 0, 0, 110, 0, 0, 0, 61, 4, 0, 0, 111, 0, 0, 0, 62, 4, 0, 0, 112, 0, 0, 0, 63, 4, 0, 0, 114, 0, 0, 0, 64, 4, 0, 0, 115, 0, 0, 0, 65, 4, 0, 0, 97, 1, 0, 0, 72, 4, 0, 0, 116, 0, 0, 0, 66, 4, 0, 0, 117, 0, 0, 0, 67, 4, 0, 0, 118, 0, 0, 0, 50, 4, 0, 0, 122, 0, 0, 0, 55, 4, 0, 0, 126, 1, 0, 0, 54, 4, 0, 0, 17, 1, 0, 0, 83, 4, 0, 0, 7, 1, 0, 0, 92, 4, 0, 0, 0, 0, 0, 0, 6, 196, 135, 0, 3, 78, 0, 7, 6, 196, 141, 0, 3, 76, 0, 7, 6, 196, 145, 0, 3, 77, 0, 7, 6, 197, 161, 0, 3, 91, 0, 7, 6, 197, 190, 0, 3, 90, 0, 7, 6, 208, 176, 0, 3, 35, 0, 7, 6, 208, 177, 0, 3, 71, 0, 7, 6, 208, 178, 0, 2, 32, 3, 83, 0, 3, 84, 0, 7, 6, 208, 179, 0, 3, 81, 0, 7, 6, 208, 180, 0, 3, 72, 0, 7, 6, 208, 181, 0, 3, 36, 0, 7, 6, 208, 182, 0, 3, 90, 0, 7, 6, 208, 183, 0, 3, 88, 0, 7, 6, 208, 184, 0, 3, 37, 0, 8, 3, 37, 10, 0, 7, 6, 208, 186, 0, 3, 49, 0, 7, 6, 208, 187, 0, 3, 55, 0, 7, 6, 208, 188, 0, 3, 65, 0, 7, 6, 208, 189, 0, 3, 50, 0, 7, 6, 208, 190, 0, 3, 39, 0, 7, 6, 208, 191, 0, 3, 48, 0, 7, 6, 209, 128, 0, 1, 17, 67, 2, 17, 67, 3, 6, 34, 0, 1, 25, 2, 25, 3, 6, 44, 0, 1, 25, 2, 17, 65, 3, 14, 16, 0, 4, 3, 51, 0, 1, 17, 65, 2, 17, 65, 0, 2, 32, 0, 209, 128, 0, 7, 6, 209, 129, 0, 3, 89, 0, 7, 6, 209, 130, 0, 3, 47, 0, 7, 6, 209, 131, 0, 3, 40, 0, 7, 6, 209, 132, 0, 3, 83, 0, 7, 6, 209, 133, 0, 3, 107, 0, 7, 6, 209, 134, 0, 3, 117, 0, 7, 6, 209, 135, 0, 3, 78, 0, 7, 6, 209, 136, 0, 3, 91, 0, 7, 6, 209, 147, 0, 3, 77, 0, 7, 6, 209, 149, 0, 3, 118, 0, 7, 6, 209, 152, 0, 3, 57, 0, 7, 6, 209, 153, 0, 3, 61, 0, 7, 6, 209, 154, 0, 3, 67, 0, 7, 6, 209, 156, 0, 3, 141, 0, 7, 6, 209, 159, 0, 3, 75, 0, 7, 6, 97, 0, 3, 35, 0, 4, 2, 106, 3, 137, 0, 2, 114, 0, 7, 6, 98, 0, 3, 71, 0, 7, 6, 99, 0, 3, 117, 0, 7, 6, 100, 0, 3, 72, 0, 197, 190, 3, 75, 0, 122, 3, 118, 0, 7, 6, 101, 0, 120, 101, 1, 32, 46, 3, 2, 36, 49, 89, 36, 0, 4, 1, 106, 3, 36, 0, 2, 106, 0, 3, 109, 0, 7, 6, 102, 0, 3, 83, 0, 7, 6, 103, 0, 3, 81, 0, 7, 6, 104, 0, 8, 3, 101, 0, 3, 107, 0, 7, 6, 105, 0, 110, 105, 1, 32, 46, 3, 2, 37, 50, 37, 0, 3, 37, 0, 7, 6, 106, 0, 3, 57, 0, 1, 17, 65, 29, 2, 32, 3, 57, 10, 0, 7, 6, 107, 0, 3, 49, 0, 7, 6, 108, 0, 1, 25, 2, 25, 3, 45, 0, 3, 55, 0, 106, 2, 12, 3, 61, 0, 7, 6, 109, 0, 3, 65, 0, 7, 6, 110, 0, 3, 50, 0, 106, 3, 67, 0, 4, 2, 103, 3, 68, 0, 2, 107, 0, 7, 6, 111, 0, 3, 39, 0, 117, 3, 129, 0, 7, 6, 112, 0, 3, 48, 0, 7, 6, 113, 0, 3, 49, 0, 117, 3, 49, 84, 0, 7, 6, 114, 0, 1, 25, 2, 25, 3, 6, 44, 0, 1, 25, 2, 17, 65, 3, 14, 16, 0, 4, 3, 51, 0, 1, 17, 65, 2, 17, 65, 0, 2, 32, 0, 114, 0, 7, 6, 115, 0, 3, 89, 0, 7, 6, 116, 0, 3, 47, 0, 7, 6, 117, 0, 3, 40, 0, 7, 6, 118, 0, 3, 84, 0, 7, 6, 119, 0, 3, 84, 0, 7, 6, 120, 0, 3, 49, 89, 0, 7, 6, 121, 0, 1, 25, 2, 25, 3, 37, 0, 3, 57, 0, 7, 6, 122, 0, 3, 88, 0, 7, 6, 206, 0, 177, 3, 6, 35, 55, 83, 122, 0, 172, 3, 6, 35, 55, 83, 122, 15, 47, 6, 39, 50, 39, 89, 0, 183, 3, 6, 36, 47, 122, 0, 174, 3, 6, 36, 47, 122, 15, 47, 6, 39, 50, 39, 89, 0, 181, 3, 6, 36, 48, 89, 138, 55, 39, 50, 0, 173, 3, 6, 36, 48, 89, 138, 55, 39, 50, 15, 47, 6, 39, 50, 39, 89, 0, 191, 3, 6, 39, 65, 138, 49, 14, 16, 39, 50, 10, 0, 184, 3, 47, 101, 6, 36, 47, 122, 0, 186, 3, 49, 6, 35, 48, 122, 0, 190, 3, 49, 89, 6, 37, 0, 189, 3, 50, 6, 37, 0, 187, 3, 55, 6, 35, 65, 72, 122, 0, 185, 3, 57, 6, 39, 47, 122, 0, 175, 3, 57, 6, 39, 47, 122, 15, 47, 6, 39, 50, 39, 89, 0, 188, 3, 65, 6, 37, 0, 178, 3, 71, 6, 36, 47, 122, 0, 180, 3, 72, 6, 36, 55, 47, 122, 0, 179, 3, 81, 6, 35, 65, 122, 0, 182, 3, 88, 6, 36, 47, 122, 0, 7, 6, 207, 0, 137, 3, 6, 39, 65, 36, 81, 122, 0, 142, 3, 6, 39, 65, 36, 81, 122, 15, 47, 6, 39, 50, 39, 89, 0, 140, 3, 6, 39, 65, 138, 49, 14, 16, 39, 50, 15, 47, 6, 39, 50, 39, 89, 0, 132, 3, 47, 6, 35, 40, 0, 128, 3, 48, 6, 37, 0, 136, 3, 48, 89, 6, 37, 0, 129, 3, 51, 6, 39, 0, 141, 3, 81, 44, 76, 49, 37, 15, 6, 37, 48, 89, 138, 55, 39, 50, 15, 47, 6, 39, 50, 39, 89, 0, 133, 3, 81, 44, 76, 49, 37, 23, 6, 37, 48, 89, 138, 55, 39, 50, 0, 130, 3, 81, 44, 76, 49, 39, 23, 88, 6, 35, 84, 44, 91, 50, 39, 23, 89, 6, 37, 81, 65, 122, 0, 134, 3, 83, 6, 37, 0, 131, 3, 89, 6, 37, 81, 65, 122, 0, 135, 3, 101, 6, 37, 0, 7, 6, 0, 4, 42, 1, 42, 2, 42, 3, 0, 4, 42, 42, 3, 0, 4, 45, 1, 45, 45, 3, 0, 4, 46, 1, 46, 3, 0, 4, 61, 1, 61, 2, 61, 3, 0, 61, 2, 61, 61, 3, 0, 61, 3, 6, 36, 72, 50, 122, 49, 84, 39, 0, 46, 2, 46, 3, 9, 0, 4, 45, 1, 32, 17, 65, 2, 32, 15, 3, 10, 0, 45, 1, 32, 17, 67, 2, 32, 15, 0, 4, 195, 159, 3, 21, 100, 101, 0, 195, 164, 0, 195, 182, 0, 195, 188, 0, 4, 42, 1, 42, 42, 2, 32, 3, 24, 0, 61, 1, 61, 61, 2, 32, 0, 46, 3, 47, 39, 76, 49, 122, 0, 45, 8, 32, 2, 32, 15, 3, 65, 37, 50, 40, 89, 0, 36, 3, 72, 6, 39, 55, 122, 51, 0, 42, 3, 118, 84, 6, 36, 88, 72, 37, 76, 49, 122, 0, 195, 173, 3, 121, 0, 195, 169, 3, 123, 0, 195, 161, 3, 124, 0, 195, 179, 3, 125, 0, 195, 186, 3, 126, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts40 = FileInMemory_createWithData (4945, reinterpret_cast (&espeakdata_dicts40_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/mk_dict", U"mk"); Collection_addItem (me.peek(), espeakdata_dicts40.transfer()); static unsigned char espeakdata_dicts41_data[3020] = { 0, 4, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 6, 65, 4, 114, 57, 0, 0, 0, 0, 0, 6, 65, 8, 71, 112, 0, 0, 0, 0, 0, 6, 65, 12, 89, 112, 0, 0, 0, 0, 0, 6, 65, 16, 72, 112, 0, 0, 0, 0, 0, 5, 65, 20, 112, 0, 0, 0, 0, 0, 6, 65, 24, 116, 83, 0, 0, 0, 0, 0, 6, 65, 28, 75, 112, 0, 0, 0, 0, 0, 6, 65, 32, 114, 76, 0, 0, 0, 0, 0, 6, 65, 36, 118, 57, 0, 0, 14, 1, 37, 97, 35, 47, 13, 65, 118, 50, 13, 65, 0, 27, 0, 14, 1, 38, 89, 35, 65, 40, 80, 80, 35, 57, 13, 65, 0, 0, 0, 7, 65, 40, 75, 114, 57, 0, 0, 0, 13, 1, 42, 35, 89, 47, 13, 34, 37, 89, 49, 0, 27, 0, 12, 1, 43, 49, 123, 140, 140, 13, 66, 13, 65, 0, 0, 7, 65, 44, 49, 114, 57, 0, 0, 0, 0, 0, 6, 65, 48, 116, 55, 0, 0, 0, 0, 0, 6, 65, 52, 116, 65, 0, 0, 0, 0, 0, 6, 65, 56, 116, 50, 0, 0, 0, 0, 0, 5, 65, 60, 119, 0, 0, 9, 1, 61, 89, 35, 65, 13, 65, 0, 0, 0, 0, 6, 65, 64, 48, 112, 0, 0, 0, 0, 0, 7, 65, 68, 49, 57, 123, 0, 0, 0, 0, 0, 6, 65, 72, 118, 51, 0, 0, 0, 0, 0, 6, 65, 76, 116, 89, 0, 0, 0, 0, 0, 6, 65, 80, 47, 112, 0, 0, 0, 0, 0, 6, 65, 84, 57, 123, 0, 0, 0, 0, 0, 6, 65, 88, 84, 112, 0, 0, 0, 0, 0, 11, 65, 92, 72, 109, 71, 109, 55, 57, 123, 0, 0, 0, 0, 0, 7, 65, 96, 116, 49, 89, 0, 0, 0, 0, 0, 7, 65, 100, 58, 118, 57, 0, 0, 0, 0, 0, 7, 65, 104, 88, 116, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 4, 95, 4, 16, 20, 10, 72, 6, 35, 97, 118, 65, 97, 13, 65, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 6, 224, 180, 179, 224, 181, 142, 10, 6, 149, 62, 0, 0, 0, 0, 0, 13, 6, 224, 180, 177, 224, 181, 142, 10, 6, 149, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 6, 224, 180, 149, 224, 181, 142, 10, 37, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 6, 224, 180, 163, 224, 181, 142, 10, 6, 149, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 51, 88, 65, 6, 40, 48, 48, 35, 47, 0, 0, 10, 3, 95, 48, 67, 50, 6, 123, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 3, 95, 49, 57, 48, 6, 35, 47, 47, 39, 65, 48, 35, 47, 40, 0, 0, 16, 3, 95, 49, 56, 48, 6, 35, 47, 37, 50, 114, 140, 140, 149, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 49, 49, 48, 6, 35, 47, 37, 50, 39, 50, 50, 149, 0, 0, 12, 3, 95, 49, 48, 48, 6, 35, 47, 47, 149, 0, 0, 0, 16, 3, 95, 49, 50, 48, 6, 35, 50, 47, 34, 35, 66, 140, 149, 0, 0, 16, 3, 95, 49, 53, 48, 6, 35, 47, 37, 50, 35, 67, 80, 149, 0, 0, 0, 15, 3, 95, 49, 55, 48, 6, 35, 47, 37, 50, 114, 52, 149, 0, 0, 15, 3, 95, 49, 54, 48, 6, 35, 47, 37, 50, 35, 52, 149, 0, 0, 0, 13, 3, 95, 55, 88, 6, 36, 70, 40, 48, 35, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 49, 88, 48, 6, 35, 47, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 50, 88, 6, 37, 34, 40, 48, 35, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 52, 88, 50, 6, 118, 55, 48, 48, 35, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 53, 88, 6, 35, 50, 48, 35, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 54, 88, 6, 35, 52, 40, 48, 35, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 56, 88, 6, 36, 66, 48, 35, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 57, 88, 47, 6, 39, 66, 66, 123, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 224, 181, 142, 144, 37, 62, 35, 144, 35, 34, 35, 65, 0, 0, 0, 8, 3, 224, 181, 140, 148, 135, 0, 0, 17, 3, 224, 181, 141, 144, 35, 50, 72, 34, 35, 49, 118, 34, 13, 65, 0, 0, 8, 3, 224, 181, 138, 18, 39, 0, 9, 3, 224, 180, 130, 6, 150, 65, 0, 0, 9, 3, 224, 181, 139, 148, 119, 12, 0, 14, 3, 224, 180, 131, 84, 37, 89, 35, 34, 81, 13, 65, 0, 0, 8, 3, 224, 181, 136, 148, 134, 0, 0, 0, 8, 3, 224, 181, 134, 18, 36, 0, 0, 9, 3, 224, 181, 135, 148, 114, 12, 0, 0, 10, 3, 224, 181, 132, 148, 34, 112, 12, 0, 0, 0, 9, 3, 224, 181, 130, 148, 123, 12, 0, 0, 9, 3, 224, 181, 131, 18, 34, 37, 0, 0, 9, 3, 224, 181, 128, 148, 112, 12, 0, 0, 8, 3, 224, 181, 129, 18, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 48, 77, 50, 55, 6, 35, 49, 93, 35, 65, 0, 0, 12, 4, 95, 48, 77, 51, 49, 6, 119, 140, 37, 0, 0, 0, 14, 4, 95, 48, 77, 49, 6, 118, 57, 37, 51, 35, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 3, 224, 181, 151, 148, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 3, 224, 180, 190, 148, 118, 12, 0, 0, 8, 3, 224, 180, 191, 18, 37, 0, 0, 0, 14, 3, 224, 180, 189, 35, 84, 35, 81, 34, 35, 107, 35, 0, 0, 0, 0, 0, 0, 10, 3, 224, 181, 190, 10, 6, 149, 62, 0, 0, 9, 3, 224, 181, 191, 10, 37, 49, 0, 0, 10, 3, 224, 181, 188, 10, 6, 149, 51, 0, 0, 9, 3, 224, 181, 189, 10, 37, 55, 0, 0, 10, 3, 224, 181, 186, 10, 6, 149, 66, 0, 0, 9, 3, 224, 181, 187, 10, 37, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 6, 224, 180, 178, 224, 181, 142, 10, 37, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 2, 95, 33, 118, 97, 80, 13, 34, 57, 35, 80, 37, 107, 50, 13, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 2, 95, 46, 71, 37, 50, 72, 40, 0, 0, 0, 12, 2, 95, 44, 35, 68, 49, 40, 97, 13, 65, 0, 0, 11, 2, 95, 51, 65, 6, 40, 50, 50, 149, 0, 0, 11, 2, 95, 50, 34, 6, 35, 66, 140, 149, 0, 0, 10, 2, 95, 49, 6, 39, 50, 50, 149, 0, 0, 12, 2, 95, 48, 48, 6, 123, 79, 57, 13, 65, 0, 0, 9, 2, 95, 55, 6, 114, 70, 149, 0, 0, 9, 2, 95, 54, 6, 35, 52, 149, 0, 0, 10, 2, 95, 53, 6, 35, 67, 80, 149, 0, 0, 10, 2, 95, 52, 50, 6, 118, 55, 149, 0, 0, 11, 2, 95, 59, 34, 119, 139, 37, 50, 37, 0, 0, 0, 12, 2, 95, 57, 6, 39, 50, 48, 35, 47, 149, 0, 0, 10, 2, 95, 56, 6, 36, 140, 140, 149, 0, 0, 16, 2, 95, 63, 80, 119, 72, 57, 13, 80, 37, 107, 50, 13, 65, 0, 0, 12, 6, 224, 180, 168, 224, 181, 142, 10, 37, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 20, 0, 0, 102, 13, 0, 0, 48, 0, 0, 0, 103, 13, 0, 0, 49, 0, 0, 0, 104, 13, 0, 0, 50, 0, 0, 0, 105, 13, 0, 0, 51, 0, 0, 0, 106, 13, 0, 0, 52, 0, 0, 0, 107, 13, 0, 0, 53, 0, 0, 0, 108, 13, 0, 0, 54, 0, 0, 0, 109, 13, 0, 0, 55, 0, 0, 0, 110, 13, 0, 0, 56, 0, 0, 0, 111, 13, 0, 0, 57, 0, 0, 0, 71, 13, 62, 13, 75, 13, 0, 0, 70, 13, 62, 13, 74, 13, 0, 0, 70, 13, 87, 13, 76, 13, 0, 0, 0, 0, 0, 0, 6, 1, 22, 0, 2, 17, 66, 3, 49, 0, 3, 49, 35, 0, 7, 6, 1, 23, 0, 2, 17, 66, 3, 146, 0, 3, 146, 35, 0, 7, 6, 1, 24, 0, 2, 17, 66, 3, 81, 0, 3, 81, 35, 0, 7, 6, 1, 25, 0, 2, 17, 66, 3, 147, 0, 3, 147, 35, 0, 7, 6, 1, 26, 0, 2, 17, 66, 3, 68, 0, 3, 68, 35, 0, 7, 6, 1, 27, 0, 2, 17, 66, 3, 80, 0, 3, 80, 35, 0, 7, 6, 1, 28, 0, 2, 17, 66, 3, 144, 0, 3, 144, 35, 0, 7, 6, 1, 29, 0, 2, 17, 66, 3, 79, 0, 3, 79, 35, 0, 7, 6, 1, 30, 0, 2, 17, 66, 3, 145, 0, 3, 145, 35, 0, 7, 6, 1, 31, 0, 2, 17, 66, 3, 67, 0, 3, 67, 35, 0, 7, 6, 1, 32, 0, 2, 17, 66, 3, 140, 0, 3, 140, 35, 0, 7, 6, 1, 33, 0, 2, 17, 66, 3, 142, 0, 3, 142, 35, 0, 7, 6, 1, 34, 0, 2, 17, 66, 3, 141, 0, 3, 141, 35, 0, 7, 6, 1, 35, 0, 2, 17, 66, 3, 143, 0, 3, 143, 35, 0, 7, 6, 1, 36, 0, 2, 17, 66, 3, 66, 0, 3, 66, 35, 0, 7, 6, 1, 37, 0, 2, 17, 66, 3, 47, 0, 3, 47, 35, 0, 7, 6, 1, 38, 0, 2, 17, 66, 3, 138, 0, 3, 138, 35, 0, 7, 6, 1, 39, 0, 2, 17, 66, 3, 72, 0, 3, 72, 35, 0, 7, 6, 1, 40, 0, 2, 17, 66, 3, 139, 0, 3, 139, 35, 0, 7, 6, 1, 41, 0, 2, 17, 66, 3, 50, 0, 3, 50, 35, 0, 7, 6, 1, 43, 0, 2, 17, 66, 3, 48, 0, 3, 48, 35, 0, 7, 6, 1, 44, 0, 2, 17, 66, 3, 48, 0, 8, 138, 181, 224, 176, 180, 224, 141, 181, 224, 170, 180, 224, 2, 224, 180, 184, 224, 180, 176, 224, 181, 141, 3, 83, 35, 0, 3, 136, 35, 0, 7, 6, 1, 45, 0, 2, 17, 66, 3, 71, 0, 3, 71, 35, 0, 7, 6, 1, 46, 0, 2, 17, 66, 3, 137, 0, 3, 137, 35, 0, 7, 6, 1, 47, 0, 2, 17, 66, 3, 65, 0, 3, 65, 35, 0, 7, 6, 1, 48, 0, 2, 17, 66, 3, 57, 0, 3, 57, 35, 0, 7, 6, 1, 49, 0, 2, 17, 66, 3, 34, 0, 3, 34, 35, 0, 7, 6, 1, 50, 0, 2, 17, 66, 3, 52, 0, 3, 52, 35, 0, 224, 181, 141, 224, 180, 177, 3, 140, 140, 0, 1, 141, 181, 224, 168, 180, 224, 3, 151, 0, 7, 6, 1, 51, 0, 2, 17, 66, 3, 55, 0, 3, 55, 35, 0, 7, 6, 1, 52, 0, 2, 17, 66, 3, 62, 0, 3, 62, 35, 0, 7, 6, 1, 53, 0, 2, 17, 66, 3, 70, 0, 3, 70, 35, 0, 7, 6, 1, 54, 0, 2, 17, 66, 3, 84, 0, 3, 84, 35, 0, 7, 6, 1, 55, 0, 2, 17, 66, 3, 97, 0, 3, 97, 35, 0, 7, 6, 1, 56, 0, 2, 17, 66, 3, 93, 0, 3, 93, 35, 0, 7, 6, 1, 57, 0, 2, 17, 66, 3, 89, 0, 3, 89, 35, 0, 7, 6, 1, 58, 0, 2, 17, 66, 3, 107, 0, 3, 107, 35, 0, 7, 6, 1, 123, 0, 3, 66, 0, 7, 6, 1, 124, 0, 3, 50, 0, 7, 6, 1, 125, 0, 3, 34, 0, 7, 6, 1, 126, 0, 3, 55, 0, 7, 6, 1, 127, 0, 3, 62, 0, 7, 6, 1, 128, 0, 3, 49, 0, 7, 6, 224, 164, 0, 3, 21, 104, 105, 0, 7, 6, 224, 165, 0, 3, 21, 104, 105, 0, 7, 6, 224, 180, 0, 189, 3, 0, 133, 3, 35, 0, 142, 3, 36, 0, 4, 135, 3, 37, 0, 191, 0, 142, 8, 3, 38, 36, 0, 143, 8, 3, 38, 114, 0, 146, 3, 39, 0, 137, 3, 40, 0, 139, 3, 51, 149, 0, 130, 3, 65, 0, 131, 3, 107, 0, 136, 3, 112, 0, 191, 2, 224, 180, 178, 224, 181, 141, 25, 3, 113, 0, 143, 3, 114, 0, 4, 134, 3, 118, 0, 190, 0, 147, 3, 119, 0, 138, 3, 123, 0, 144, 3, 134, 0, 148, 3, 135, 0, 7, 6, 224, 181, 0, 4, 141, 3, 0, 4, 141, 224, 181, 141, 3, 0, 142, 3, 0, 134, 3, 36, 0, 138, 3, 39, 0, 129, 3, 40, 0, 131, 3, 44, 0, 132, 3, 44, 12, 0, 160, 3, 51, 149, 12, 0, 161, 3, 55, 149, 12, 0, 128, 3, 112, 0, 135, 3, 114, 0, 139, 3, 119, 0, 130, 3, 123, 0, 136, 3, 134, 0, 4, 140, 3, 135, 0, 151, 0, 141, 2, 32, 3, 149, 0, 7, 6, 0, 36, 3, 72, 119, 62, 35, 34, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts41 = FileInMemory_createWithData (3019, reinterpret_cast (&espeakdata_dicts41_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/ml_dict", U"ml"); Collection_addItem (me.peek(), espeakdata_dicts41.transfer()); static unsigned char espeakdata_dicts42_data[4388] = { 0, 4, 0, 0, 189, 14, 0, 0, 0, 16, 70, 69, 81, 4, 36, 83, 64, 6, 13, 40, 72, 37, 12, 65, 0, 0, 0, 0, 0, 5, 65, 4, 35, 0, 0, 0, 0, 0, 10, 5, 7, 196, 167, 1, 24, 35, 91, 0, 6, 65, 8, 71, 13, 0, 0, 0, 0, 0, 6, 65, 12, 49, 35, 0, 0, 12, 5, 4, 9, 196, 161, 1, 72, 37, 75, 35, 0, 0, 0, 0, 7, 65, 16, 72, 36, 36, 0, 0, 0, 10, 67, 44, 145, 128, 99, 37, 12, 83, 0, 0, 0, 5, 65, 20, 36, 0, 0, 0, 0, 0, 8, 65, 24, 36, 83, 83, 36, 0, 0, 0, 0, 0, 6, 65, 28, 81, 126, 0, 0, 0, 10, 67, 92, 20, 84, 40, 35, 12, 47, 0, 0, 0, 8, 65, 32, 35, 49, 49, 35, 0, 0, 0, 0, 0, 19, 9, 20, 1, 7, 196, 167, 13, 9, 12, 24, 47, 35, 12, 65, 37, 55, 91, 0, 5, 65, 36, 37, 0, 0, 0, 0, 14, 7, 16, 15, 196, 161, 196, 161, 9, 39, 75, 37, 12, 0, 0, 17, 8, 20, 16, 15, 196, 161, 196, 161, 9, 47, 48, 39, 75, 37, 12, 0, 5, 65, 40, 126, 0, 0, 0, 11, 1, 42, 89, 47, 37, 55, 12, 35, 0, 27, 0, 10, 67, 92, 20, 129, 40, 35, 34, 35, 0, 10, 67, 92, 20, 129, 40, 35, 34, 35, 0, 16, 7, 20, 9, 5, 7, 196, 167, 9, 47, 37, 12, 112, 12, 0, 72, 9, 1, 43, 48, 55, 40, 89, 0, 27, 0, 7, 65, 44, 49, 6, 13, 0, 0, 0, 0, 16, 7, 20, 9, 5, 7, 196, 167, 21, 47, 37, 12, 40, 12, 0, 72, 9, 1, 47, 49, 118, 47, 12, 35, 0, 0, 8, 65, 48, 36, 55, 55, 36, 0, 0, 0, 0, 0, 8, 65, 52, 36, 65, 65, 36, 0, 0, 0, 0, 0, 8, 65, 56, 36, 50, 50, 36, 0, 0, 0, 0, 0, 5, 65, 60, 39, 0, 0, 12, 1, 61, 37, 12, 49, 58, 13, 55, 88, 0, 27, 0, 0, 0, 7, 1, 64, 10, 35, 47, 0, 6, 65, 64, 48, 36, 0, 0, 0, 0, 0, 6, 65, 68, 6, 13, 0, 0, 0, 0, 0, 8, 65, 72, 36, 34, 34, 36, 0, 0, 0, 0, 0, 14, 69, 44, 145, 78, 21, 64, 49, 37, 12, 50, 36, 47, 0, 8, 65, 76, 36, 89, 89, 36, 0, 0, 0, 0, 0, 6, 65, 80, 47, 36, 0, 0, 0, 0, 12, 67, 36, 229, 9, 37, 50, 47, 37, 12, 0, 72, 0, 5, 65, 84, 40, 0, 5, 65, 84, 40, 0, 0, 0, 0, 17, 6, 22, 9, 196, 139, 9, 14, 84, 37, 12, 91, 13, 37, 12, 50, 0, 0, 6, 65, 88, 84, 36, 0, 0, 0, 0, 0, 8, 1, 92, 49, 36, 50, 39, 0, 7, 65, 92, 40, 6, 13, 0, 0, 17, 70, 52, 147, 134, 48, 242, 192, 65, 37, 50, 83, 55, 39, 76, 36, 0, 0, 0, 0, 6, 132, 95, 49, 77, 49, 8, 65, 96, 36, 91, 91, 36, 0, 0, 0, 0, 0, 5, 65, 100, 111, 0, 0, 0, 0, 0, 8, 65, 104, 47, 89, 36, 36, 0, 0, 0, 15, 7, 1, 7, 196, 167, 13, 5, 12, 35, 12, 65, 36, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 67, 53, 84, 128, 65, 40, 12, 34, 0, 0, 11, 68, 68, 16, 133, 48, 35, 71, 36, 55, 0, 12, 68, 68, 16, 133, 48, 35, 12, 71, 36, 55, 0, 0, 0, 0, 9, 1, 126, 47, 37, 55, 72, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 70, 52, 147, 139, 20, 162, 129, 65, 37, 50, 76, 114, 12, 35, 0, 15, 70, 52, 147, 139, 20, 162, 129, 65, 37, 50, 99, 114, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 50, 77, 49, 36, 55, 83, 114, 40, 50, 0, 0, 0, 13, 4, 95, 50, 77, 51, 88, 6, 13, 120, 81, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 5, 5, 196, 139, 196, 139, 101, 116, 83, 101, 116, 114, 97, 0, 29, 0, 0, 0, 0, 0, 0, 15, 5, 1, 196, 167, 14, 1, 35, 107, 6, 13, 50, 35, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 70, 64, 84, 141, 21, 166, 128, 48, 36, 34, 65, 36, 47, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 95, 51, 77, 51, 47, 55, 36, 47, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 67, 32, 146, 129, 37, 12, 35, 0, 72, 0, 0, 0, 0, 0, 0, 16, 8, 7, 196, 167, 1, 13, 9, 12, 20, 35, 65, 37, 55, 47, 0, 0, 10, 67, 8, 82, 142, 71, 114, 12, 50, 0, 10, 67, 8, 82, 142, 71, 114, 12, 50, 0, 0, 0, 9, 67, 16, 19, 128, 72, 35, 50, 0, 0, 0, 0, 0, 10, 67, 25, 84, 64, 83, 40, 6, 13, 0, 0, 0, 0, 0, 0, 15, 5, 9, 197, 188, 4, 1, 37, 12, 88, 6, 13, 72, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 66, 12, 208, 116, 83, 101, 110, 116, 105, 109, 39, 101, 116, 114, 105, 0, 29, 0, 0, 0, 0, 0, 0, 13, 68, 16, 20, 130, 4, 72, 35, 34, 12, 71, 35, 0, 0, 0, 0, 19, 8, 6, 9, 12, 45, 13, 9, 10, 1, 83, 37, 12, 45, 65, 37, 12, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 7, 7, 196, 167, 1, 13, 5, 12, 35, 12, 65, 36, 55, 0, 15, 7, 7, 196, 167, 1, 13, 5, 12, 35, 12, 65, 36, 55, 0, 14, 7, 7, 196, 167, 1, 13, 5, 12, 35, 65, 36, 55, 0, 0, 0, 0, 0, 10, 3, 226, 130, 172, 36, 58, 34, 39, 0, 0, 0, 0, 0, 0, 0, 0, 8, 66, 24, 144, 83, 37, 12, 0, 0, 10, 67, 52, 244, 148, 65, 39, 34, 47, 0, 0, 0, 0, 0, 9, 67, 16, 18, 192, 72, 35, 49, 0, 0, 13, 68, 52, 147, 132, 84, 65, 37, 50, 72, 40, 12, 0, 0, 0, 0, 0, 13, 68, 76, 20, 133, 80, 89, 35, 12, 34, 36, 47, 0, 0, 0, 0, 0, 0, 14, 4, 95, 53, 77, 51, 107, 6, 13, 35, 65, 36, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 8, 10, 1, 7, 196, 167, 13, 5, 12, 37, 35, 12, 65, 36, 55, 0, 0, 0, 0, 9, 67, 40, 85, 192, 126, 40, 12, 0, 0, 9, 67, 40, 82, 203, 126, 76, 36, 0, 0, 0, 0, 0, 0, 10, 67, 16, 21, 206, 72, 118, 12, 50, 0, 0, 0, 17, 8, 20, 1, 7, 196, 167, 8, 15, 13, 47, 35, 107, 39, 65, 0, 72, 0, 10, 67, 16, 21, 203, 72, 118, 12, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 67, 52, 133, 88, 65, 40, 12, 91, 0, 9, 67, 52, 133, 88, 65, 40, 91, 0, 14, 3, 95, 51, 88, 47, 55, 6, 13, 47, 37, 12, 50, 0, 0, 10, 3, 95, 48, 67, 65, 37, 12, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 95, 49, 67, 65, 37, 12, 118, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 49, 57, 47, 89, 36, 47, 35, 91, 36, 0, 0, 14, 3, 95, 49, 56, 47, 65, 37, 50, 47, 35, 91, 36, 0, 0, 0, 0, 16, 7, 20, 1, 7, 196, 167, 14, 1, 47, 35, 50, 35, 12, 0, 72, 0, 0, 0, 0, 13, 3, 95, 49, 49, 107, 6, 13, 72, 35, 91, 36, 0, 0, 11, 3, 95, 49, 48, 35, 6, 13, 34, 35, 0, 0, 13, 3, 95, 49, 51, 47, 55, 36, 47, 35, 91, 36, 0, 0, 11, 3, 95, 49, 50, 47, 50, 35, 91, 36, 0, 0, 16, 3, 95, 49, 53, 107, 6, 13, 65, 37, 89, 47, 35, 91, 36, 0, 0, 14, 3, 95, 49, 52, 36, 34, 71, 35, 47, 35, 91, 36, 0, 0, 13, 3, 95, 49, 55, 89, 71, 35, 47, 35, 91, 36, 0, 0, 12, 3, 95, 49, 54, 89, 37, 47, 35, 91, 36, 0, 0, 0, 13, 3, 95, 55, 88, 89, 6, 13, 71, 114, 12, 50, 0, 0, 0, 0, 17, 7, 20, 1, 7, 196, 167, 8, 1, 47, 35, 107, 6, 13, 35, 0, 72, 0, 0, 0, 15, 8, 2, 226, 128, 153, 8, 5, 11, 11, 71, 36, 76, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 66, 52, 16, 57, 37, 89, 47, 35, 101, 0, 11, 66, 52, 16, 57, 34, 37, 72, 40, 101, 0, 10, 66, 52, 16, 49, 126, 50, 40, 101, 0, 9, 66, 52, 16, 49, 126, 50, 101, 0, 5, 194, 52, 16, 72, 0, 10, 67, 52, 19, 0, 65, 35, 55, 12, 0, 0, 0, 0, 14, 7, 7, 196, 167, 1, 14, 4, 21, 35, 50, 72, 40, 0, 0, 0, 0, 0, 0, 12, 3, 95, 50, 88, 39, 91, 36, 34, 37, 50, 0, 0, 0, 0, 20, 10, 13, 39, 7, 196, 167, 1, 14, 4, 21, 24, 65, 6, 35, 50, 72, 40, 91, 0, 0, 0, 0, 0, 14, 7, 7, 196, 167, 1, 14, 4, 9, 35, 50, 72, 37, 0, 0, 0, 15, 6, 196, 167, 4, 5, 10, 14, 107, 6, 13, 72, 114, 50, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 52, 88, 36, 34, 71, 112, 12, 50, 0, 0, 0, 0, 0, 0, 0, 0, 17, 66, 44, 112, 107, 105, 108, 111, 103, 114, 39, 97, 109, 58, 105, 0, 29, 0, 10, 67, 45, 83, 12, 80, 40, 55, 12, 0, 9, 67, 45, 83, 12, 65, 37, 50, 0, 11, 67, 45, 83, 12, 72, 35, 34, 71, 35, 0, 15, 3, 95, 53, 88, 107, 6, 13, 35, 65, 89, 37, 12, 50, 0, 0, 13, 8, 17, 9, 5, 7, 196, 167, 5, 4, 126, 72, 0, 0, 0, 0, 0, 0, 18, 8, 20, 9, 5, 7, 196, 167, 5, 11, 47, 37, 12, 35, 49, 36, 0, 72, 0, 0, 13, 3, 95, 54, 88, 89, 37, 47, 12, 37, 12, 50, 0, 0, 0, 0, 0, 9, 67, 68, 21, 20, 35, 47, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 67, 80, 181, 78, 101, 37, 0, 0, 0, 15, 8, 7, 196, 167, 1, 14, 4, 8, 1, 35, 50, 12, 35, 0, 13, 3, 95, 56, 88, 47, 65, 36, 50, 37, 12, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 3, 95, 57, 88, 72, 4, 111, 72, 37, 50, 6, 37, 89, 114, 12, 50, 0, 0, 0, 0, 0, 0, 16, 4, 52, 48, 48, 48, 36, 34, 71, 35, 47, 36, 55, 36, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 67, 52, 147, 142, 65, 37, 50, 12, 0, 10, 67, 52, 147, 142, 107, 36, 65, 65, 0, 10, 67, 52, 147, 142, 83, 36, 57, 50, 0, 10, 67, 52, 147, 142, 65, 37, 12, 50, 0, 0, 0, 0, 12, 68, 37, 52, 201, 72, 37, 89, 12, 37, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 67, 48, 147, 0, 107, 37, 50, 50, 0, 11, 67, 48, 147, 0, 55, 37, 12, 55, 12, 0, 0, 17, 66, 52, 112, 109, 105, 108, 105, 103, 114, 39, 97, 109, 58, 105, 0, 29, 0, 0, 12, 68, 40, 145, 78, 4, 121, 36, 50, 35, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 48, 77, 50, 65, 6, 37, 55, 121, 50, 0, 0, 15, 4, 95, 48, 77, 51, 71, 37, 6, 55, 37, 6, 40, 50, 0, 0, 0, 10, 4, 95, 48, 77, 49, 36, 55, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 9, 13, 9, 14, 7, 196, 167, 1, 10, 18, 65, 37, 12, 50, 112, 34, 0, 19, 9, 13, 9, 14, 7, 196, 167, 1, 10, 18, 65, 37, 12, 50, 112, 12, 34, 0, 0, 0, 0, 0, 0, 0, 0, 16, 66, 44, 208, 107, 105, 108, 111, 109, 39, 101, 116, 114, 105, 0, 29, 0, 0, 0, 0, 0, 0, 0, 17, 8, 20, 1, 7, 196, 167, 11, 15, 13, 47, 35, 49, 39, 65, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 68, 44, 145, 78, 84, 99, 126, 50, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 3, 196, 161, 15, 75, 36, 39, 0, 0, 0, 0, 0, 0, 0, 30, 76, 37, 36, 133, 77, 1, 84, 80, 149, 129, 52, 83, 148, 37, 34, 12, 36, 89, 48, 36, 47, 37, 84, 35, 65, 36, 50, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 66, 52, 192, 109, 105, 108, 105, 108, 39, 105, 116, 114, 105, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 66, 52, 208, 109, 105, 108, 105, 109, 39, 101, 116, 114, 105, 0, 29, 0, 10, 67, 24, 244, 212, 83, 39, 89, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 10, 9, 12, 45, 17, 21, 4, 4, 9, 5, 13, 37, 45, 72, 37, 12, 65, 12, 6, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 67, 69, 34, 66, 34, 37, 12, 48, 0, 0, 8, 66, 80, 16, 47, 35, 12, 0, 0, 15, 70, 52, 133, 77, 36, 86, 0, 40, 65, 40, 65, 37, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 2, 196, 139, 76, 13, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 2, 194, 163, 89, 47, 36, 34, 55, 37, 50, 35, 0, 0, 0, 0, 0, 0, 0, 0, 12, 68, 37, 49, 133, 48, 37, 89, 83, 36, 55, 0, 0, 0, 0, 0, 0, 8, 2, 196, 167, 107, 6, 13, 0, 0, 0, 0, 0, 0, 0, 7, 2, 196, 161, 75, 36, 0, 0, 0, 0, 0, 18, 70, 52, 147, 130, 5, 36, 129, 65, 37, 50, 71, 35, 12, 34, 35, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 67, 32, 83, 77, 36, 65, 12, 0, 0, 14, 69, 44, 243, 148, 72, 16, 80, 39, 50, 47, 34, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 67, 36, 181, 78, 37, 80, 40, 12, 50, 12, 0, 0, 15, 70, 16, 19, 23, 5, 21, 0, 72, 35, 55, 40, 35, 47, 0, 8, 2, 197, 188, 88, 6, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 68, 36, 229, 15, 52, 37, 12, 50, 47, 39, 65, 0, 72, 0, 15, 69, 52, 17, 23, 5, 32, 65, 35, 72, 40, 12, 35, 34, 0, 15, 69, 52, 17, 23, 5, 32, 65, 35, 72, 40, 35, 12, 34, 0, 0, 0, 0, 0, 0, 0, 0, 17, 70, 24, 194, 77, 44, 145, 78, 83, 55, 37, 50, 49, 37, 12, 65, 0, 17, 70, 24, 194, 77, 44, 145, 78, 83, 55, 37, 65, 49, 37, 50, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 68, 36, 180, 197, 8, 37, 12, 49, 89, 36, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 5, 20, 1, 196, 167, 20, 47, 35, 107, 47, 0, 12, 5, 20, 1, 196, 167, 20, 47, 35, 107, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 2, 95, 35, 107, 35, 89, 107, 0, 0, 11, 2, 95, 34, 49, 58, 39, 110, 47, 89, 0, 0, 10, 67, 80, 213, 82, 47, 65, 40, 34, 0, 9, 2, 95, 33, 48, 40, 50, 47, 0, 0, 9, 67, 33, 83, 65, 40, 65, 35, 0, 11, 67, 33, 83, 65, 40, 12, 65, 35, 0, 72, 0, 11, 2, 95, 39, 35, 80, 80, 36, 50, 47, 0, 0, 6, 2, 95, 38, 40, 0, 0, 11, 4, 95, 52, 77, 51, 36, 34, 71, 35, 0, 17, 2, 95, 37, 48, 34, 39, 80, 36, 50, 47, 40, 35, 55, 37, 12, 0, 0, 13, 2, 95, 36, 72, 39, 55, 55, 35, 34, 40, 12, 0, 0, 0, 0, 14, 2, 95, 41, 48, 35, 34, 36, 50, 47, 36, 88, 37, 0, 0, 14, 2, 95, 40, 48, 35, 34, 36, 50, 47, 36, 88, 37, 0, 0, 0, 9, 2, 95, 46, 48, 40, 50, 47, 0, 0, 11, 2, 95, 45, 107, 35, 108, 83, 13, 50, 0, 0, 9, 2, 95, 44, 49, 39, 65, 35, 0, 0, 12, 2, 95, 51, 47, 55, 37, 12, 36, 47, 35, 0, 0, 9, 2, 95, 50, 50, 114, 12, 50, 0, 0, 10, 67, 48, 82, 142, 55, 114, 50, 12, 0, 11, 2, 95, 49, 116, 12, 107, 6, 13, 72, 0, 0, 10, 2, 95, 48, 88, 6, 36, 16, 39, 0, 0, 10, 2, 95, 55, 89, 36, 71, 35, 12, 0, 0, 11, 2, 95, 54, 89, 37, 12, 47, 12, 35, 0, 0, 12, 2, 95, 53, 107, 6, 13, 35, 65, 89, 35, 0, 0, 9, 2, 95, 52, 36, 34, 71, 35, 0, 0, 16, 2, 95, 59, 89, 36, 65, 108, 49, 6, 39, 110, 55, 13, 50, 0, 0, 11, 2, 95, 58, 49, 39, 110, 55, 13, 50, 0, 0, 14, 2, 95, 57, 72, 111, 72, 37, 50, 6, 35, 89, 35, 0, 0, 13, 2, 95, 56, 47, 65, 37, 12, 50, 37, 12, 35, 0, 0, 15, 2, 95, 63, 65, 37, 89, 47, 39, 104, 89, 37, 57, 35, 0, 0, 10, 2, 95, 62, 35, 49, 71, 35, 34, 0, 0, 0, 9, 2, 95, 60, 37, 88, 6, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 2, 95, 91, 48, 35, 34, 36, 50, 47, 36, 88, 37, 0, 0, 0, 13, 69, 76, 82, 138, 21, 32, 89, 114, 12, 36, 34, 0, 0, 0, 13, 2, 95, 95, 35, 55, 35, 84, 37, 12, 84, 35, 0, 0, 0, 14, 2, 95, 93, 48, 35, 34, 36, 50, 47, 36, 88, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 68, 96, 244, 148, 4, 91, 39, 34, 47, 35, 0, 0, 0, 0, 0, 0, 0, 0, 14, 2, 95, 123, 35, 55, 49, 40, 35, 12, 55, 47, 39, 0, 0, 0, 0, 0, 0, 10, 67, 8, 148, 211, 71, 37, 89, 12, 0, 0, 15, 2, 95, 125, 55, 39, 48, 12, 40, 35, 12, 55, 47, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 69, 28, 128, 78, 17, 80, 57, 49, 39, 55, 55, 107, 39, 65, 0, 0, 0, 0, 0, 0, 0, 0, 11, 68, 40, 148, 212, 4, 37, 89, 47, 35, 0, 18, 9, 7, 196, 167, 1, 12, 11, 5, 13, 13, 35, 55, 76, 36, 65, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 66, 96, 144, 91, 37, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 67, 37, 52, 193, 37, 89, 12, 35, 0, 0, 0, 0, 0, 0, 0, 12, 68, 8, 244, 212, 4, 71, 39, 89, 47, 35, 0, 0, 0, 9, 67, 33, 85, 193, 40, 12, 35, 0, 9, 67, 33, 85, 193, 40, 35, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 67, 44, 145, 78, 99, 37, 12, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 9, 7, 196, 167, 1, 14, 4, 8, 15, 13, 35, 50, 72, 39, 65, 0, 0, 0, 0, 16, 7, 50, 48, 48, 48, 48, 48, 48, 88, 6, 13, 120, 81, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 51, 48, 48, 48, 47, 55, 36, 47, 12, 0, 0, 0, 0, 0, 0, 11, 5, 7, 196, 167, 1, 12, 35, 55, 12, 0, 0, 0, 0, 0, 6, 196, 139, 0, 3, 76, 13, 0, 97, 3, 76, 13, 35, 0, 101, 3, 76, 13, 36, 0, 105, 3, 76, 13, 37, 0, 119, 3, 76, 13, 40, 6, 13, 0, 7, 6, 196, 161, 0, 3, 75, 0, 111, 3, 75, 39, 0, 7, 6, 196, 167, 0, 3, 107, 0, 117, 3, 107, 12, 40, 12, 0, 116, 3, 107, 47, 0, 7, 6, 197, 188, 0, 3, 88, 6, 13, 0, 4, 97, 3, 88, 35, 0, 103, 196, 167, 0, 101, 3, 88, 36, 0, 105, 101, 3, 88, 37, 12, 36, 0, 7, 6, 97, 0, 3, 35, 0, 97, 3, 35, 12, 0, 120, 3, 35, 91, 0, 117, 3, 118, 0, 7, 6, 98, 0, 3, 71, 0, 101, 3, 71, 6, 13, 0, 98, 3, 71, 12, 0, 114, 3, 71, 34, 6, 13, 0, 105, 101, 3, 71, 37, 6, 13, 0, 105, 3, 71, 37, 12, 0, 7, 6, 99, 0, 3, 80, 0, 7, 6, 100, 0, 100, 3, 72, 12, 0, 3, 72, 36, 0, 7, 6, 101, 0, 3, 36, 0, 119, 3, 120, 0, 117, 3, 120, 12, 0, 7, 6, 102, 0, 3, 83, 0, 102, 3, 83, 12, 0, 111, 3, 83, 39, 0, 7, 6, 103, 0, 196, 167, 3, 12, 0, 3, 81, 0, 103, 3, 81, 12, 0, 105, 3, 81, 37, 12, 0, 101, 3, 81, 126, 0, 7, 6, 104, 0, 3, 12, 0, 7, 6, 105, 0, 101, 3, 37, 12, 0, 3, 108, 0, 117, 3, 108, 40, 0, 7, 6, 106, 0, 106, 3, 37, 12, 0, 97, 3, 37, 35, 0, 111, 3, 37, 39, 0, 3, 121, 0, 101, 3, 126, 0, 7, 6, 107, 0, 97, 3, 49, 35, 0, 4, 3, 49, 36, 0, 101, 0, 105, 3, 49, 37, 12, 0, 105, 101, 3, 49, 37, 12, 36, 0, 117, 3, 49, 40, 12, 0, 111, 3, 80, 39, 0, 7, 6, 108, 0, 3, 55, 0, 7, 6, 109, 0, 4, 2, 110, 3, 37, 65, 0, 2, 112, 0, 2, 114, 0, 3, 65, 0, 7, 6, 110, 0, 3, 50, 0, 117, 3, 50, 40, 12, 0, 7, 6, 111, 0, 3, 39, 0, 7, 6, 112, 0, 3, 48, 0, 4, 1, 109, 97, 104, 115, 2, 111, 3, 48, 12, 0, 1, 109, 97, 107, 2, 97, 110, 106, 0, 1, 109, 97, 115, 2, 111, 111, 0, 8, 97, 116, 111, 2, 97, 0, 8, 101, 108, 111, 2, 97, 0, 112, 0, 7, 6, 113, 0, 117, 3, 0, 3, 6, 13, 0, 97, 3, 35, 0, 101, 3, 36, 0, 111, 3, 39, 0, 7, 6, 114, 0, 3, 34, 0, 97, 3, 34, 35, 12, 0, 105, 101, 3, 34, 37, 12, 36, 0, 111, 3, 34, 39, 12, 0, 7, 6, 115, 0, 3, 89, 0, 4, 97, 113, 3, 89, 35, 0, 97, 113, 113, 0, 105, 101, 3, 89, 37, 12, 36, 0, 7, 6, 116, 0, 3, 47, 0, 116, 3, 47, 12, 0, 7, 6, 117, 0, 3, 40, 0, 120, 3, 40, 91, 0, 7, 6, 118, 0, 3, 84, 0, 7, 6, 119, 0, 3, 40, 0, 7, 6, 120, 0, 3, 91, 36, 0, 105, 101, 3, 91, 114, 12, 0, 7, 6, 121, 0, 3, 111, 0, 121, 3, 111, 12, 0, 105, 3, 117, 0, 195, 182, 3, 127, 0, 7, 6, 122, 0, 3, 47, 89, 36, 0, 104, 1, 25, 3, 90, 0, 7, 6, 0, 196, 139, 3, 76, 13, 0, 197, 188, 3, 88, 6, 13, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts42 = FileInMemory_createWithData (4387, reinterpret_cast (&espeakdata_dicts42_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/mt_dict", U"mt"); Collection_addItem (me.peek(), espeakdata_dicts42.transfer()); static unsigned char espeakdata_dicts43_data[1535] = { 0, 4, 0, 0, 251, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 3, 95, 50, 48, 89, 36, 65, 48, 110, 12, 58, 35, 55, 55, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 3, 95, 51, 48, 89, 36, 65, 48, 110, 12, 58, 35, 55, 55, 37, 39, 65, 65, 35, 19, 47, 55, 35, 49, 47, 55, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 3, 95, 51, 88, 89, 36, 65, 48, 110, 12, 58, 35, 55, 55, 37, 39, 65, 65, 35, 19, 47, 55, 35, 49, 47, 55, 37, 39, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 49, 48, 65, 35, 19, 47, 55, 35, 49, 47, 55, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 3, 95, 49, 88, 65, 35, 19, 47, 55, 35, 49, 47, 55, 37, 39, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 3, 95, 50, 88, 89, 36, 65, 48, 110, 12, 58, 35, 55, 55, 37, 39, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 2, 95, 51, 36, 12, 57, 37, 0, 0, 9, 2, 95, 50, 110, 12, 65, 36, 0, 0, 8, 2, 95, 49, 89, 36, 12, 0, 0, 10, 2, 95, 48, 35, 19, 47, 55, 36, 0, 0, 12, 2, 95, 55, 76, 37, 80, 110, 12, 65, 36, 0, 0, 13, 2, 95, 54, 76, 37, 49, 58, 35, 89, 36, 12, 0, 0, 15, 2, 95, 53, 65, 35, 12, 49, 58, 37, 12, 55, 55, 37, 0, 0, 10, 2, 95, 52, 50, 35, 12, 58, 37, 0, 0, 0, 0, 14, 2, 95, 57, 76, 37, 58, 49, 50, 35, 12, 58, 37, 0, 0, 13, 2, 95, 56, 76, 37, 58, 49, 36, 12, 57, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 18, 66, 196, 147, 0, 196, 171, 0, 101, 0, 105, 0, 7, 6, 196, 129, 0, 3, 35, 12, 0, 7, 6, 196, 147, 0, 2, 32, 3, 6, 36, 12, 0, 3, 36, 12, 0, 7, 6, 196, 171, 0, 3, 37, 12, 0, 7, 6, 197, 141, 0, 3, 39, 12, 0, 7, 6, 97, 0, 3, 35, 0, 7, 6, 99, 0, 3, 49, 0, 117, 3, 49, 58, 0, 104, 3, 76, 0, 2, 18, 66, 3, 89, 0, 7, 6, 101, 0, 3, 36, 0, 7, 6, 104, 0, 3, 19, 0, 117, 3, 58, 0, 7, 6, 105, 0, 3, 37, 0, 7, 6, 108, 0, 3, 55, 0, 7, 6, 109, 0, 3, 65, 0, 7, 6, 110, 0, 3, 50, 0, 7, 6, 111, 0, 3, 39, 0, 7, 6, 112, 0, 3, 48, 0, 7, 6, 113, 0, 117, 3, 49, 0, 7, 6, 116, 0, 3, 47, 0, 7, 6, 117, 0, 3, 39, 0, 113, 3, 49, 0, 4, 2, 17, 65, 3, 58, 0, 104, 0, 99, 3, 58, 49, 0, 7, 6, 120, 0, 3, 91, 0, 7, 6, 121, 0, 3, 57, 0, 7, 6, 122, 0, 3, 89, 0, 7, 6, 0, 35, 3, 9, 0, 107, 3, 49, 0, 114, 3, 51, 0, 119, 3, 58, 0, 98, 3, 71, 0, 100, 3, 72, 0, 103, 3, 81, 0, 102, 3, 83, 0, 118, 3, 84, 0, 4, 115, 3, 89, 0, 195, 167, 0, 106, 3, 101, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts43 = FileInMemory_createWithData (1534, reinterpret_cast (&espeakdata_dicts43_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/nci_dict", U"nci"); Collection_addItem (me.peek(), espeakdata_dicts43.transfer()); static unsigned char espeakdata_dicts44_data[10795] = { 0, 4, 0, 0, 22, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 129, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 6, 224, 164, 149, 224, 165, 135, 49, 6, 36, 4, 12, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 134, 224, 164, 185, 224, 165, 139, 72, 28, 0, 0, 0, 0, 0, 15, 6, 224, 164, 181, 224, 164, 168, 71, 6, 35, 6, 50, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 6, 224, 164, 181, 224, 164, 176, 58, 6, 35, 34, 13, 12, 0, 0, 0, 23, 12, 224, 164, 166, 224, 164, 191, 224, 164, 143, 224, 164, 168, 72, 6, 37, 57, 6, 36, 50, 111, 0, 0, 0, 0, 0, 0, 0, 11, 6, 224, 164, 151, 224, 164, 188, 100, 13, 0, 0, 0, 0, 0, 11, 6, 224, 164, 149, 224, 164, 188, 104, 13, 0, 0, 0, 9, 134, 224, 164, 181, 224, 164, 190, 8, 0, 0, 0, 0, 0, 0, 15, 140, 224, 164, 133, 224, 164, 165, 224, 164, 181, 224, 164, 190, 8, 0, 0, 0, 0, 11, 6, 224, 164, 171, 224, 164, 188, 83, 13, 0, 0, 0, 0, 18, 9, 224, 164, 185, 224, 165, 129, 224, 164, 168, 107, 6, 40, 6, 50, 13, 0, 0, 0, 0, 0, 20, 9, 224, 164, 151, 224, 164, 143, 224, 164, 168, 81, 6, 109, 57, 6, 36, 50, 111, 0, 0, 0, 0, 15, 4, 95, 4, 16, 20, 10, 138, 6, 119, 48, 55, 39, 10, 0, 0, 0, 0, 0, 0, 0, 0, 18, 9, 224, 164, 184, 224, 165, 129, 224, 164, 150, 89, 6, 40, 8, 146, 13, 0, 0, 14, 6, 224, 164, 137, 224, 164, 170, 40, 6, 48, 13, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 22, 12, 224, 164, 150, 224, 164, 190, 224, 164, 143, 224, 164, 168, 146, 35, 57, 6, 36, 50, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 224, 164, 161, 224, 164, 188, 70, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 9, 224, 164, 155, 224, 165, 129, 224, 164, 168, 144, 6, 40, 50, 6, 13, 0, 0, 0, 0, 0, 20, 9, 224, 164, 173, 224, 164, 143, 224, 164, 168, 137, 6, 109, 57, 6, 36, 50, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 6, 224, 164, 133, 224, 164, 172, 109, 6, 71, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 5, 95, 48, 77, 49, 48, 48, 13, 34, 6, 118, 34, 34, 72, 12, 139, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 3, 95, 51, 57, 122, 12, 50, 6, 35, 50, 6, 80, 6, 118, 55, 6, 112, 89, 0, 14, 3, 95, 50, 49, 114, 49, 12, 49, 6, 118, 112, 89, 0, 0, 12, 3, 95, 51, 56, 35, 34, 47, 6, 113, 89, 0, 10, 3, 95, 50, 48, 71, 6, 112, 89, 0, 0, 11, 3, 95, 50, 51, 47, 6, 114, 113, 89, 0, 0, 11, 3, 95, 50, 50, 71, 6, 118, 113, 89, 0, 0, 13, 3, 95, 50, 53, 48, 13, 80, 12, 6, 113, 89, 0, 0, 13, 3, 95, 50, 52, 80, 6, 120, 71, 6, 113, 89, 0, 0, 14, 3, 95, 50, 55, 89, 13, 47, 12, 6, 118, 113, 89, 0, 0, 14, 3, 95, 50, 54, 144, 13, 71, 6, 71, 6, 112, 89, 0, 0, 14, 3, 95, 51, 49, 114, 49, 13, 47, 12, 6, 113, 89, 0, 0, 10, 3, 95, 51, 48, 47, 6, 112, 89, 0, 0, 15, 3, 95, 51, 51, 47, 6, 114, 47, 6, 47, 6, 112, 89, 0, 0, 14, 3, 95, 51, 50, 71, 6, 35, 47, 12, 6, 113, 89, 0, 0, 12, 3, 95, 51, 53, 48, 127, 47, 6, 113, 89, 0, 0, 14, 3, 95, 51, 52, 80, 130, 4, 47, 6, 113, 12, 89, 0, 0, 12, 3, 95, 51, 55, 89, 127, 47, 6, 113, 89, 0, 0, 16, 3, 95, 51, 54, 144, 13, 12, 47, 6, 47, 6, 113, 12, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 12, 224, 164, 166, 224, 165, 129, 224, 164, 131, 224, 164, 150, 72, 6, 40, 5, 146, 13, 0, 0, 0, 0, 0, 14, 3, 95, 55, 57, 122, 6, 50, 6, 118, 89, 6, 112, 0, 16, 3, 95, 54, 49, 114, 49, 6, 35, 89, 13, 142, 6, 142, 112, 0, 0, 17, 3, 95, 55, 56, 35, 138, 107, 35, 47, 47, 12, 6, 109, 34, 12, 0, 11, 3, 95, 54, 48, 89, 6, 118, 142, 112, 0, 0, 11, 3, 95, 48, 67, 89, 6, 35, 57, 13, 0, 19, 3, 95, 54, 51, 47, 6, 34, 6, 112, 4, 89, 13, 142, 6, 142, 6, 112, 0, 0, 17, 3, 95, 54, 50, 71, 6, 115, 89, 13, 142, 6, 12, 142, 6, 112, 0, 0, 17, 3, 95, 54, 53, 48, 6, 127, 6, 89, 13, 142, 6, 142, 6, 112, 0, 0, 16, 3, 95, 54, 52, 80, 6, 120, 89, 13, 142, 6, 142, 6, 112, 0, 0, 18, 3, 95, 54, 55, 89, 6, 109, 47, 6, 89, 13, 142, 6, 142, 6, 112, 0, 0, 17, 3, 95, 54, 54, 144, 6, 116, 6, 89, 13, 142, 6, 142, 6, 112, 0, 0, 19, 3, 95, 55, 49, 114, 49, 6, 35, 107, 6, 35, 47, 12, 6, 109, 34, 12, 0, 0, 17, 3, 95, 55, 48, 89, 6, 35, 47, 6, 47, 13, 34, 6, 112, 12, 0, 0, 17, 3, 95, 55, 51, 47, 113, 57, 35, 47, 47, 12, 6, 109, 34, 12, 0, 0, 17, 3, 95, 55, 50, 71, 13, 107, 6, 35, 47, 47, 6, 109, 34, 12, 0, 0, 17, 3, 95, 55, 53, 48, 35, 144, 4, 35, 47, 12, 6, 109, 34, 12, 0, 0, 16, 3, 95, 55, 52, 80, 120, 107, 35, 47, 12, 6, 109, 34, 12, 0, 0, 19, 3, 95, 55, 55, 89, 13, 47, 13, 107, 35, 47, 47, 12, 6, 109, 34, 12, 0, 0, 22, 3, 95, 55, 54, 144, 13, 6, 57, 6, 35, 107, 6, 35, 47, 6, 47, 6, 109, 34, 12, 0, 0, 15, 3, 95, 49, 57, 122, 12, 50, 50, 6, 118, 37, 6, 89, 0, 0, 13, 3, 95, 49, 56, 35, 6, 142, 6, 118, 34, 111, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 50, 57, 122, 12, 50, 6, 109, 50, 47, 6, 113, 89, 0, 14, 3, 95, 49, 49, 114, 6, 147, 6, 118, 34, 6, 109, 0, 0, 13, 3, 95, 50, 56, 35, 138, 12, 6, 118, 113, 89, 0, 10, 3, 95, 49, 48, 72, 6, 109, 89, 0, 0, 12, 3, 95, 49, 51, 47, 6, 114, 107, 34, 13, 0, 0, 11, 3, 95, 49, 50, 71, 6, 118, 34, 111, 0, 0, 13, 3, 95, 49, 53, 48, 6, 109, 50, 72, 34, 111, 0, 0, 11, 3, 95, 49, 52, 144, 6, 120, 72, 111, 0, 0, 12, 3, 95, 49, 55, 89, 6, 109, 47, 34, 111, 0, 0, 11, 3, 95, 49, 54, 89, 6, 119, 34, 111, 0, 0, 8, 3, 224, 164, 165, 138, 13, 0, 0, 10, 3, 224, 164, 164, 47, 13, 4, 0, 8, 8, 3, 224, 164, 164, 47, 13, 0, 0, 8, 3, 224, 164, 167, 139, 13, 0, 0, 8, 3, 224, 164, 166, 72, 13, 0, 0, 8, 3, 224, 164, 161, 141, 13, 0, 0, 8, 3, 224, 164, 160, 142, 13, 0, 0, 8, 3, 224, 164, 163, 66, 13, 0, 0, 8, 3, 224, 164, 162, 143, 13, 0, 0, 8, 3, 224, 164, 157, 145, 13, 0, 17, 3, 95, 52, 57, 122, 6, 50, 6, 35, 50, 6, 80, 6, 118, 89, 0, 0, 8, 3, 224, 164, 156, 79, 13, 0, 6, 131, 224, 165, 164, 8, 17, 3, 95, 52, 56, 35, 6, 142, 6, 80, 6, 118, 55, 6, 113, 89, 0, 0, 8, 3, 224, 164, 159, 140, 13, 0, 0, 17, 9, 224, 164, 184, 224, 164, 191, 224, 164, 164, 89, 6, 37, 47, 13, 0, 8, 3, 224, 164, 158, 67, 13, 0, 0, 8, 3, 224, 164, 153, 68, 13, 0, 0, 8, 3, 224, 164, 152, 147, 13, 0, 0, 8, 3, 224, 164, 155, 144, 13, 0, 0, 8, 3, 224, 164, 154, 80, 13, 0, 0, 9, 3, 224, 165, 157, 107, 34, 13, 0, 8, 3, 224, 164, 149, 49, 13, 0, 18, 3, 95, 53, 57, 122, 6, 50, 6, 109, 50, 6, 89, 6, 118, 142, 112, 0, 17, 3, 95, 52, 49, 36, 6, 12, 49, 80, 6, 118, 55, 6, 37, 89, 0, 0, 8, 3, 224, 165, 156, 34, 13, 0, 21, 3, 95, 53, 56, 35, 6, 50, 138, 12, 6, 118, 58, 13, 50, 6, 50, 6, 12, 109, 0, 12, 3, 95, 52, 48, 80, 118, 55, 6, 113, 89, 0, 0, 8, 3, 224, 165, 159, 57, 13, 0, 8, 3, 224, 164, 151, 81, 13, 0, 17, 3, 95, 52, 51, 47, 6, 34, 112, 80, 6, 118, 55, 6, 112, 89, 0, 0, 8, 3, 224, 165, 158, 83, 13, 0, 8, 3, 224, 164, 150, 146, 13, 0, 13, 3, 95, 52, 50, 71, 134, 118, 55, 6, 113, 89, 0, 0, 8, 3, 224, 165, 153, 101, 13, 0, 16, 3, 95, 52, 53, 48, 134, 6, 50, 47, 118, 55, 6, 113, 89, 0, 0, 8, 3, 224, 165, 152, 104, 13, 0, 14, 3, 95, 52, 52, 80, 120, 58, 118, 55, 6, 113, 89, 0, 0, 8, 3, 224, 165, 155, 88, 13, 0, 17, 3, 95, 52, 55, 89, 13, 6, 141, 80, 47, 118, 55, 6, 113, 89, 0, 0, 8, 3, 224, 165, 154, 100, 13, 0, 15, 3, 95, 52, 54, 144, 107, 113, 57, 118, 55, 6, 113, 89, 0, 0, 23, 3, 95, 54, 57, 122, 12, 50, 6, 35, 50, 6, 89, 6, 109, 47, 47, 6, 35, 34, 6, 112, 0, 18, 3, 95, 53, 49, 114, 49, 6, 118, 58, 109, 50, 6, 50, 12, 6, 109, 0, 0, 17, 3, 95, 54, 56, 35, 6, 142, 4, 89, 13, 142, 6, 142, 6, 112, 0, 12, 3, 95, 53, 48, 48, 13, 80, 6, 118, 89, 0, 0, 18, 3, 95, 53, 51, 47, 6, 34, 113, 12, 48, 6, 35, 50, 6, 50, 109, 0, 0, 17, 3, 95, 53, 50, 71, 6, 118, 58, 109, 50, 6, 50, 12, 6, 109, 0, 0, 17, 3, 95, 53, 53, 48, 6, 35, 80, 6, 48, 109, 50, 6, 50, 109, 0, 0, 16, 3, 95, 53, 52, 80, 6, 121, 123, 58, 109, 50, 6, 50, 109, 0, 0, 23, 3, 95, 53, 55, 89, 6, 109, 50, 6, 47, 12, 6, 118, 58, 13, 50, 6, 50, 6, 12, 109, 0, 0, 17, 3, 95, 53, 54, 144, 107, 13, 48, 12, 6, 109, 50, 6, 50, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 3, 95, 56, 57, 123, 50, 6, 118, 50, 6, 35, 71, 6, 71, 6, 114, 0, 0, 14, 3, 95, 56, 56, 35, 6, 142, 12, 118, 89, 6, 112, 0, 0, 0, 0, 8, 3, 224, 164, 185, 108, 13, 0, 0, 8, 3, 224, 164, 184, 89, 13, 0, 0, 0, 0, 8, 3, 224, 164, 181, 58, 13, 0, 19, 3, 95, 57, 57, 122, 12, 50, 6, 50, 6, 118, 50, 89, 107, 13, 57, 114, 0, 13, 3, 95, 56, 49, 114, 49, 6, 118, 89, 6, 112, 0, 0, 20, 3, 95, 57, 56, 35, 6, 50, 6, 142, 6, 118, 50, 13, 71, 6, 71, 6, 114, 0, 13, 3, 95, 56, 48, 35, 6, 89, 6, 89, 6, 112, 0, 0, 8, 3, 224, 164, 183, 93, 13, 0, 15, 3, 95, 56, 51, 47, 34, 113, 57, 6, 118, 89, 6, 112, 0, 0, 8, 3, 224, 164, 182, 91, 13, 0, 12, 3, 95, 56, 50, 71, 134, 118, 89, 6, 112, 0, 0, 8, 3, 224, 164, 177, 34, 13, 0, 15, 3, 95, 56, 53, 48, 6, 35, 80, 6, 118, 89, 6, 112, 0, 0, 7, 131, 224, 164, 176, 72, 8, 8, 3, 224, 164, 176, 34, 13, 0, 13, 3, 95, 56, 52, 80, 120, 34, 118, 89, 6, 112, 0, 0, 8, 3, 224, 164, 179, 62, 13, 0, 16, 3, 95, 56, 55, 89, 6, 109, 12, 47, 6, 118, 89, 6, 112, 0, 0, 8, 3, 224, 164, 178, 55, 13, 0, 14, 3, 95, 56, 54, 144, 13, 57, 6, 118, 89, 6, 112, 0, 0, 8, 3, 224, 164, 173, 137, 13, 0, 17, 3, 95, 57, 49, 114, 49, 6, 118, 50, 13, 71, 6, 71, 6, 114, 0, 0, 8, 3, 224, 164, 172, 71, 13, 0, 13, 3, 95, 57, 48, 50, 13, 71, 6, 71, 6, 114, 0, 0, 8, 3, 224, 164, 175, 57, 13, 0, 19, 3, 95, 57, 51, 47, 34, 113, 57, 6, 118, 50, 13, 71, 6, 71, 6, 114, 0, 0, 11, 3, 224, 164, 174, 65, 111, 5, 0, 72, 28, 8, 3, 224, 164, 174, 65, 13, 0, 19, 3, 95, 57, 50, 71, 6, 35, 57, 6, 118, 50, 13, 71, 6, 71, 6, 114, 0, 0, 20, 3, 95, 57, 53, 48, 13, 50, 6, 80, 6, 118, 50, 13, 71, 6, 71, 6, 114, 0, 0, 8, 3, 224, 164, 168, 50, 13, 0, 18, 3, 95, 57, 52, 80, 120, 34, 6, 118, 50, 13, 71, 6, 71, 6, 114, 0, 0, 8, 3, 224, 164, 171, 136, 13, 0, 21, 3, 95, 57, 55, 89, 13, 50, 6, 47, 12, 6, 118, 50, 13, 71, 6, 71, 6, 114, 0, 0, 8, 3, 224, 164, 170, 48, 13, 0, 18, 3, 95, 57, 54, 144, 13, 57, 6, 118, 50, 13, 71, 6, 71, 6, 114, 0, 0, 0, 0, 0, 0, 0, 0, 42, 27, 224, 164, 176, 224, 164, 190, 224, 164, 183, 224, 165, 141, 224, 164, 159, 224, 165, 141, 224, 164, 176, 224, 164, 191, 224, 164, 175, 34, 6, 118, 91, 4, 140, 34, 113, 12, 57, 111, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 4, 95, 48, 77, 56, 89, 107, 6, 35, 50, 4, 146, 13, 0, 0, 21, 4, 95, 48, 77, 57, 65, 6, 35, 107, 6, 118, 4, 89, 107, 6, 35, 50, 146, 13, 0, 0, 12, 4, 95, 48, 77, 54, 50, 6, 112, 55, 6, 0, 0, 14, 4, 95, 48, 77, 55, 48, 6, 109, 72, 6, 65, 13, 0, 0, 12, 4, 95, 48, 77, 52, 6, 109, 34, 13, 71, 0, 0, 15, 4, 95, 48, 77, 53, 146, 6, 109, 34, 13, 71, 6, 109, 0, 0, 12, 4, 95, 48, 77, 50, 55, 6, 118, 146, 13, 0, 0, 15, 4, 95, 48, 77, 51, 49, 6, 35, 6, 34, 119, 141, 13, 0, 0, 0, 14, 4, 95, 48, 77, 49, 107, 13, 88, 6, 118, 34, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 134, 224, 164, 170, 224, 165, 139, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 131, 239, 187, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 224, 164, 150, 224, 164, 188, 101, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 6, 224, 164, 170, 224, 164, 176, 48, 6, 35, 34, 13, 4, 0, 0, 14, 6, 224, 164, 156, 224, 164, 181, 79, 6, 109, 84, 13, 0, 0, 0, 0, 16, 6, 224, 164, 164, 224, 164, 176, 47, 6, 35, 34, 13, 4, 0, 8, 0, 0, 0, 9, 134, 224, 164, 168, 224, 164, 191, 8, 0, 0, 0, 0, 0, 0, 0, 17, 9, 224, 164, 172, 224, 164, 190, 224, 164, 159, 71, 6, 118, 140, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 224, 164, 156, 224, 164, 188, 88, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 6, 224, 164, 134, 224, 164, 156, 118, 6, 79, 13, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 2, 95, 51, 47, 6, 112, 50, 0, 0, 10, 2, 95, 50, 72, 6, 123, 4, 112, 0, 0, 9, 2, 95, 49, 114, 6, 49, 6, 0, 0, 12, 2, 95, 48, 91, 6, 123, 50, 6, 50, 118, 0, 0, 9, 2, 95, 55, 89, 6, 118, 47, 0, 0, 8, 2, 95, 54, 144, 6, 111, 0, 0, 10, 2, 95, 53, 48, 6, 118, 50, 80, 0, 0, 10, 2, 95, 52, 80, 6, 118, 34, 12, 0, 0, 0, 0, 10, 2, 95, 57, 50, 6, 109, 6, 123, 0, 0, 8, 2, 95, 56, 6, 118, 142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 12, 224, 164, 185, 224, 165, 139, 224, 164, 135, 224, 164, 168, 107, 6, 39, 112, 50, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 140, 224, 164, 174, 224, 165, 135, 224, 164, 176, 224, 165, 139, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 20, 102, 9, 0, 0, 48, 0, 0, 0, 103, 9, 0, 0, 49, 0, 0, 0, 104, 9, 0, 0, 50, 0, 0, 0, 105, 9, 0, 0, 51, 0, 0, 0, 106, 9, 0, 0, 52, 0, 0, 0, 107, 9, 0, 0, 53, 0, 0, 0, 108, 9, 0, 0, 54, 0, 0, 0, 109, 9, 0, 0, 55, 0, 0, 0, 110, 9, 0, 0, 56, 0, 0, 0, 111, 9, 0, 0, 57, 0, 0, 0, 5, 9, 60, 9, 5, 9, 0, 0, 5, 9, 81, 9, 5, 9, 0, 0, 5, 9, 82, 9, 5, 9, 0, 0, 5, 9, 83, 9, 5, 9, 0, 0, 5, 9, 84, 9, 5, 9, 0, 0, 4, 9, 60, 9, 4, 9, 0, 0, 4, 9, 81, 9, 4, 9, 0, 0, 4, 9, 82, 9, 4, 9, 0, 0, 4, 9, 83, 9, 4, 9, 0, 0, 4, 9, 84, 9, 4, 9, 0, 0, 6, 9, 60, 9, 6, 9, 0, 0, 6, 9, 81, 9, 6, 9, 0, 0, 6, 9, 82, 9, 6, 9, 0, 0, 6, 9, 83, 9, 6, 9, 0, 0, 6, 9, 84, 9, 6, 9, 0, 0, 7, 9, 60, 9, 7, 9, 0, 0, 7, 9, 81, 9, 7, 9, 0, 0, 7, 9, 82, 9, 7, 9, 0, 0, 7, 9, 83, 9, 7, 9, 0, 0, 7, 9, 84, 9, 7, 9, 0, 0, 8, 9, 60, 9, 8, 9, 0, 0, 8, 9, 81, 9, 8, 9, 0, 0, 8, 9, 82, 9, 8, 9, 0, 0, 8, 9, 83, 9, 8, 9, 0, 0, 8, 9, 84, 9, 8, 9, 0, 0, 9, 9, 60, 9, 9, 9, 0, 0, 9, 9, 81, 9, 9, 9, 0, 0, 9, 9, 82, 9, 9, 9, 0, 0, 9, 9, 83, 9, 9, 9, 0, 0, 9, 9, 84, 9, 9, 9, 0, 0, 10, 9, 60, 9, 10, 9, 0, 0, 10, 9, 81, 9, 10, 9, 0, 0, 10, 9, 82, 9, 10, 9, 0, 0, 10, 9, 83, 9, 10, 9, 0, 0, 10, 9, 84, 9, 10, 9, 0, 0, 11, 9, 60, 9, 11, 9, 0, 0, 11, 9, 81, 9, 11, 9, 0, 0, 11, 9, 82, 9, 11, 9, 0, 0, 11, 9, 83, 9, 11, 9, 0, 0, 11, 9, 84, 9, 11, 9, 0, 0, 96, 9, 60, 9, 96, 9, 0, 0, 96, 9, 81, 9, 96, 9, 0, 0, 96, 9, 82, 9, 96, 9, 0, 0, 96, 9, 83, 9, 96, 9, 0, 0, 96, 9, 84, 9, 96, 9, 0, 0, 12, 9, 60, 9, 12, 9, 0, 0, 12, 9, 81, 9, 12, 9, 0, 0, 12, 9, 82, 9, 12, 9, 0, 0, 12, 9, 83, 9, 12, 9, 0, 0, 12, 9, 84, 9, 12, 9, 0, 0, 97, 9, 60, 9, 97, 9, 0, 0, 97, 9, 81, 9, 97, 9, 0, 0, 97, 9, 82, 9, 97, 9, 0, 0, 97, 9, 83, 9, 97, 9, 0, 0, 97, 9, 84, 9, 97, 9, 0, 0, 13, 9, 60, 9, 13, 9, 0, 0, 13, 9, 81, 9, 13, 9, 0, 0, 13, 9, 82, 9, 13, 9, 0, 0, 13, 9, 83, 9, 13, 9, 0, 0, 13, 9, 84, 9, 13, 9, 0, 0, 14, 9, 60, 9, 14, 9, 0, 0, 14, 9, 81, 9, 14, 9, 0, 0, 14, 9, 82, 9, 14, 9, 0, 0, 14, 9, 83, 9, 14, 9, 0, 0, 14, 9, 84, 9, 14, 9, 0, 0, 15, 9, 60, 9, 15, 9, 0, 0, 15, 9, 81, 9, 15, 9, 0, 0, 15, 9, 82, 9, 15, 9, 0, 0, 15, 9, 83, 9, 15, 9, 0, 0, 15, 9, 84, 9, 15, 9, 0, 0, 16, 9, 60, 9, 16, 9, 0, 0, 16, 9, 81, 9, 16, 9, 0, 0, 16, 9, 82, 9, 16, 9, 0, 0, 16, 9, 83, 9, 16, 9, 0, 0, 16, 9, 84, 9, 16, 9, 0, 0, 17, 9, 60, 9, 17, 9, 0, 0, 17, 9, 81, 9, 17, 9, 0, 0, 17, 9, 82, 9, 17, 9, 0, 0, 17, 9, 83, 9, 17, 9, 0, 0, 17, 9, 84, 9, 17, 9, 0, 0, 18, 9, 60, 9, 18, 9, 0, 0, 18, 9, 81, 9, 18, 9, 0, 0, 18, 9, 82, 9, 18, 9, 0, 0, 18, 9, 83, 9, 18, 9, 0, 0, 18, 9, 84, 9, 18, 9, 0, 0, 19, 9, 60, 9, 19, 9, 0, 0, 19, 9, 81, 9, 19, 9, 0, 0, 19, 9, 82, 9, 19, 9, 0, 0, 19, 9, 83, 9, 19, 9, 0, 0, 19, 9, 84, 9, 19, 9, 0, 0, 20, 9, 83, 9, 20, 9, 0, 0, 20, 9, 84, 9, 20, 9, 0, 0, 20, 9, 60, 9, 20, 9, 0, 0, 20, 9, 81, 9, 20, 9, 0, 0, 20, 9, 82, 9, 20, 9, 0, 0, 20, 9, 83, 9, 20, 9, 0, 0, 20, 9, 84, 9, 20, 9, 0, 0, 21, 9, 81, 9, 21, 9, 0, 0, 21, 9, 82, 9, 21, 9, 0, 0, 21, 9, 83, 9, 21, 9, 0, 0, 21, 9, 84, 9, 21, 9, 0, 0, 21, 9, 60, 9, 88, 9, 0, 0, 21, 9, 60, 9, 88, 9, 0, 0, 88, 9, 60, 9, 88, 9, 0, 0, 88, 9, 81, 9, 88, 9, 0, 0, 88, 9, 82, 9, 88, 9, 0, 0, 88, 9, 83, 9, 88, 9, 0, 0, 88, 9, 84, 9, 88, 9, 0, 0, 22, 9, 81, 9, 22, 9, 0, 0, 22, 9, 82, 9, 22, 9, 0, 0, 22, 9, 83, 9, 22, 9, 0, 0, 22, 9, 84, 9, 22, 9, 0, 0, 22, 9, 60, 9, 89, 9, 0, 0, 22, 9, 60, 9, 89, 9, 0, 0, 89, 9, 60, 9, 89, 9, 0, 0, 89, 9, 81, 9, 89, 9, 0, 0, 89, 9, 82, 9, 89, 9, 0, 0, 89, 9, 83, 9, 89, 9, 0, 0, 89, 9, 84, 9, 89, 9, 0, 0, 23, 9, 81, 9, 23, 9, 0, 0, 23, 9, 82, 9, 23, 9, 0, 0, 23, 9, 83, 9, 23, 9, 0, 0, 23, 9, 84, 9, 23, 9, 0, 0, 23, 9, 60, 9, 90, 9, 0, 0, 23, 9, 60, 9, 90, 9, 0, 0, 90, 9, 60, 9, 90, 9, 0, 0, 90, 9, 81, 9, 90, 9, 0, 0, 90, 9, 82, 9, 90, 9, 0, 0, 90, 9, 83, 9, 90, 9, 0, 0, 90, 9, 84, 9, 90, 9, 0, 0, 24, 9, 60, 9, 24, 9, 0, 0, 24, 9, 81, 9, 24, 9, 0, 0, 24, 9, 82, 9, 24, 9, 0, 0, 24, 9, 83, 9, 24, 9, 0, 0, 24, 9, 84, 9, 24, 9, 0, 0, 23, 9, 82, 9, 123, 9, 0, 0, 123, 9, 60, 9, 123, 9, 0, 0, 123, 9, 81, 9, 123, 9, 0, 0, 123, 9, 82, 9, 123, 9, 0, 0, 123, 9, 83, 9, 123, 9, 0, 0, 123, 9, 84, 9, 123, 9, 0, 0, 25, 9, 60, 9, 25, 9, 0, 0, 25, 9, 81, 9, 25, 9, 0, 0, 25, 9, 82, 9, 25, 9, 0, 0, 25, 9, 83, 9, 25, 9, 0, 0, 25, 9, 84, 9, 25, 9, 0, 0, 26, 9, 60, 9, 26, 9, 0, 0, 26, 9, 81, 9, 26, 9, 0, 0, 26, 9, 82, 9, 26, 9, 0, 0, 26, 9, 83, 9, 26, 9, 0, 0, 26, 9, 84, 9, 26, 9, 0, 0, 27, 9, 60, 9, 27, 9, 0, 0, 27, 9, 81, 9, 27, 9, 0, 0, 27, 9, 82, 9, 27, 9, 0, 0, 27, 9, 83, 9, 27, 9, 0, 0, 27, 9, 84, 9, 27, 9, 0, 0, 28, 9, 81, 9, 28, 9, 0, 0, 28, 9, 82, 9, 28, 9, 0, 0, 28, 9, 83, 9, 28, 9, 0, 0, 28, 9, 84, 9, 28, 9, 0, 0, 28, 9, 60, 9, 91, 9, 0, 0, 91, 9, 60, 9, 91, 9, 0, 0, 91, 9, 81, 9, 91, 9, 0, 0, 91, 9, 82, 9, 91, 9, 0, 0, 91, 9, 83, 9, 91, 9, 0, 0, 91, 9, 84, 9, 91, 9, 0, 0, 28, 9, 82, 9, 124, 9, 0, 0, 124, 9, 60, 9, 124, 9, 0, 0, 124, 9, 81, 9, 124, 9, 0, 0, 124, 9, 82, 9, 124, 9, 0, 0, 124, 9, 83, 9, 124, 9, 0, 0, 124, 9, 84, 9, 124, 9, 0, 0, 29, 9, 60, 9, 29, 9, 0, 0, 29, 9, 81, 9, 29, 9, 0, 0, 29, 9, 82, 9, 29, 9, 0, 0, 29, 9, 83, 9, 29, 9, 0, 0, 29, 9, 84, 9, 29, 9, 0, 0, 30, 9, 60, 9, 30, 9, 0, 0, 30, 9, 81, 9, 30, 9, 0, 0, 30, 9, 82, 9, 30, 9, 0, 0, 30, 9, 83, 9, 30, 9, 0, 0, 30, 9, 84, 9, 30, 9, 0, 0, 31, 9, 60, 9, 31, 9, 0, 0, 31, 9, 81, 9, 31, 9, 0, 0, 31, 9, 82, 9, 31, 9, 0, 0, 31, 9, 83, 9, 31, 9, 0, 0, 31, 9, 84, 9, 31, 9, 0, 0, 32, 9, 60, 9, 32, 9, 0, 0, 32, 9, 81, 9, 32, 9, 0, 0, 32, 9, 82, 9, 32, 9, 0, 0, 32, 9, 83, 9, 32, 9, 0, 0, 32, 9, 84, 9, 32, 9, 0, 0, 33, 9, 81, 9, 33, 9, 0, 0, 33, 9, 82, 9, 33, 9, 0, 0, 33, 9, 83, 9, 33, 9, 0, 0, 33, 9, 84, 9, 33, 9, 0, 0, 33, 9, 60, 9, 92, 9, 0, 0, 92, 9, 60, 9, 92, 9, 0, 0, 92, 9, 81, 9, 92, 9, 0, 0, 92, 9, 82, 9, 92, 9, 0, 0, 92, 9, 83, 9, 92, 9, 0, 0, 92, 9, 84, 9, 92, 9, 0, 0, 34, 9, 81, 9, 34, 9, 0, 0, 34, 9, 82, 9, 34, 9, 0, 0, 34, 9, 83, 9, 34, 9, 0, 0, 34, 9, 84, 9, 34, 9, 0, 0, 34, 9, 60, 9, 93, 9, 0, 0, 93, 9, 60, 9, 93, 9, 0, 0, 93, 9, 81, 9, 93, 9, 0, 0, 93, 9, 82, 9, 93, 9, 0, 0, 93, 9, 83, 9, 93, 9, 0, 0, 93, 9, 84, 9, 93, 9, 0, 0, 35, 9, 60, 9, 35, 9, 0, 0, 35, 9, 81, 9, 35, 9, 0, 0, 35, 9, 82, 9, 35, 9, 0, 0, 35, 9, 83, 9, 35, 9, 0, 0, 35, 9, 84, 9, 35, 9, 0, 0, 36, 9, 60, 9, 36, 9, 0, 0, 36, 9, 81, 9, 36, 9, 0, 0, 36, 9, 82, 9, 36, 9, 0, 0, 36, 9, 83, 9, 36, 9, 0, 0, 36, 9, 84, 9, 36, 9, 0, 0, 37, 9, 60, 9, 37, 9, 0, 0, 37, 9, 81, 9, 37, 9, 0, 0, 37, 9, 82, 9, 37, 9, 0, 0, 37, 9, 83, 9, 37, 9, 0, 0, 37, 9, 84, 9, 37, 9, 0, 0, 38, 9, 60, 9, 38, 9, 0, 0, 38, 9, 81, 9, 38, 9, 0, 0, 38, 9, 82, 9, 38, 9, 0, 0, 38, 9, 83, 9, 38, 9, 0, 0, 38, 9, 84, 9, 38, 9, 0, 0, 39, 9, 60, 9, 39, 9, 0, 0, 39, 9, 81, 9, 39, 9, 0, 0, 39, 9, 82, 9, 39, 9, 0, 0, 39, 9, 83, 9, 39, 9, 0, 0, 39, 9, 84, 9, 39, 9, 0, 0, 33, 9, 82, 9, 126, 9, 0, 0, 126, 9, 60, 9, 126, 9, 0, 0, 126, 9, 81, 9, 126, 9, 0, 0, 126, 9, 82, 9, 126, 9, 0, 0, 126, 9, 83, 9, 126, 9, 0, 0, 126, 9, 84, 9, 126, 9, 0, 0, 40, 9, 81, 9, 40, 9, 0, 0, 40, 9, 82, 9, 40, 9, 0, 0, 40, 9, 83, 9, 40, 9, 0, 0, 40, 9, 84, 9, 40, 9, 0, 0, 40, 9, 60, 9, 41, 9, 0, 0, 41, 9, 60, 9, 41, 9, 0, 0, 41, 9, 81, 9, 41, 9, 0, 0, 41, 9, 82, 9, 41, 9, 0, 0, 41, 9, 83, 9, 41, 9, 0, 0, 41, 9, 84, 9, 41, 9, 0, 0, 42, 9, 60, 9, 42, 9, 0, 0, 42, 9, 81, 9, 42, 9, 0, 0, 42, 9, 82, 9, 42, 9, 0, 0, 42, 9, 83, 9, 42, 9, 0, 0, 42, 9, 84, 9, 42, 9, 0, 0, 43, 9, 81, 9, 43, 9, 0, 0, 43, 9, 82, 9, 43, 9, 0, 0, 43, 9, 83, 9, 43, 9, 0, 0, 43, 9, 84, 9, 43, 9, 0, 0, 43, 9, 60, 9, 94, 9, 0, 0, 94, 9, 60, 9, 94, 9, 0, 0, 94, 9, 81, 9, 94, 9, 0, 0, 94, 9, 82, 9, 94, 9, 0, 0, 94, 9, 83, 9, 94, 9, 0, 0, 94, 9, 84, 9, 94, 9, 0, 0, 44, 9, 60, 9, 44, 9, 0, 0, 44, 9, 81, 9, 44, 9, 0, 0, 44, 9, 82, 9, 44, 9, 0, 0, 44, 9, 83, 9, 44, 9, 0, 0, 44, 9, 84, 9, 44, 9, 0, 0, 45, 9, 60, 9, 45, 9, 0, 0, 45, 9, 81, 9, 45, 9, 0, 0, 45, 9, 82, 9, 45, 9, 0, 0, 45, 9, 83, 9, 45, 9, 0, 0, 45, 9, 84, 9, 45, 9, 0, 0, 44, 9, 82, 9, 127, 9, 0, 0, 127, 9, 60, 9, 127, 9, 0, 0, 127, 9, 81, 9, 127, 9, 0, 0, 127, 9, 82, 9, 127, 9, 0, 0, 127, 9, 83, 9, 127, 9, 0, 0, 127, 9, 84, 9, 127, 9, 0, 0, 46, 9, 60, 9, 46, 9, 0, 0, 46, 9, 81, 9, 46, 9, 0, 0, 46, 9, 82, 9, 46, 9, 0, 0, 46, 9, 83, 9, 46, 9, 0, 0, 46, 9, 84, 9, 46, 9, 0, 0, 47, 9, 81, 9, 47, 9, 0, 0, 47, 9, 82, 9, 47, 9, 0, 0, 47, 9, 83, 9, 47, 9, 0, 0, 47, 9, 84, 9, 47, 9, 0, 0, 47, 9, 60, 9, 95, 9, 0, 0, 95, 9, 60, 9, 95, 9, 0, 0, 95, 9, 81, 9, 95, 9, 0, 0, 95, 9, 82, 9, 95, 9, 0, 0, 95, 9, 83, 9, 95, 9, 0, 0, 95, 9, 84, 9, 95, 9, 0, 0, 48, 9, 81, 9, 48, 9, 0, 0, 48, 9, 82, 9, 48, 9, 0, 0, 48, 9, 83, 9, 48, 9, 0, 0, 48, 9, 84, 9, 48, 9, 0, 0, 48, 9, 60, 9, 49, 9, 0, 0, 49, 9, 60, 9, 49, 9, 0, 0, 49, 9, 81, 9, 49, 9, 0, 0, 49, 9, 82, 9, 49, 9, 0, 0, 49, 9, 83, 9, 49, 9, 0, 0, 49, 9, 84, 9, 49, 9, 0, 0, 50, 9, 60, 9, 50, 9, 0, 0, 50, 9, 81, 9, 50, 9, 0, 0, 50, 9, 82, 9, 50, 9, 0, 0, 50, 9, 83, 9, 50, 9, 0, 0, 50, 9, 84, 9, 50, 9, 0, 0, 51, 9, 81, 9, 51, 9, 0, 0, 51, 9, 82, 9, 51, 9, 0, 0, 51, 9, 83, 9, 51, 9, 0, 0, 51, 9, 84, 9, 51, 9, 0, 0, 51, 9, 60, 9, 52, 9, 0, 0, 52, 9, 60, 9, 52, 9, 0, 0, 52, 9, 81, 9, 52, 9, 0, 0, 52, 9, 82, 9, 52, 9, 0, 0, 52, 9, 83, 9, 52, 9, 0, 0, 52, 9, 84, 9, 52, 9, 0, 0, 53, 9, 60, 9, 53, 9, 0, 0, 53, 9, 81, 9, 53, 9, 0, 0, 53, 9, 82, 9, 53, 9, 0, 0, 53, 9, 83, 9, 53, 9, 0, 0, 53, 9, 84, 9, 53, 9, 0, 0, 54, 9, 60, 9, 54, 9, 0, 0, 54, 9, 81, 9, 54, 9, 0, 0, 54, 9, 82, 9, 54, 9, 0, 0, 54, 9, 83, 9, 54, 9, 0, 0, 54, 9, 84, 9, 54, 9, 0, 0, 55, 9, 60, 9, 55, 9, 0, 0, 55, 9, 81, 9, 55, 9, 0, 0, 55, 9, 82, 9, 55, 9, 0, 0, 55, 9, 83, 9, 55, 9, 0, 0, 55, 9, 84, 9, 55, 9, 0, 0, 56, 9, 60, 9, 56, 9, 0, 0, 56, 9, 81, 9, 56, 9, 0, 0, 56, 9, 82, 9, 56, 9, 0, 0, 56, 9, 83, 9, 56, 9, 0, 0, 56, 9, 84, 9, 56, 9, 0, 0, 57, 9, 60, 9, 57, 9, 0, 0, 57, 9, 81, 9, 57, 9, 0, 0, 57, 9, 82, 9, 57, 9, 0, 0, 57, 9, 83, 9, 57, 9, 0, 0, 57, 9, 84, 9, 57, 9, 0, 0, 0, 0, 0, 0, 6, 1, 2, 0, 3, 80, 109, 50, 72, 34, 111, 58, 37, 6, 50, 6, 72, 40, 0, 7, 6, 1, 3, 0, 4, 1, 17, 65, 3, 50, 0, 1, 17, 67, 0, 4, 2, 224, 164, 170, 3, 65, 0, 2, 224, 164, 171, 0, 2, 224, 164, 172, 0, 2, 224, 164, 173, 0, 2, 224, 164, 174, 0, 4, 2, 224, 164, 159, 3, 66, 0, 2, 224, 164, 160, 0, 2, 224, 164, 161, 0, 2, 224, 164, 162, 0, 2, 224, 164, 163, 0, 4, 2, 224, 164, 154, 3, 67, 0, 2, 224, 164, 155, 0, 2, 224, 164, 156, 0, 2, 224, 164, 157, 0, 2, 224, 164, 158, 0, 2, 224, 164, 175, 0, 4, 2, 224, 164, 149, 3, 68, 0, 2, 224, 164, 150, 0, 2, 224, 164, 151, 0, 2, 224, 164, 152, 0, 2, 224, 164, 153, 0, 2, 224, 164, 156, 224, 165, 141, 224, 164, 158, 0, 2, 224, 164, 185, 0, 3, 89, 107, 113, 6, 34, 109, 4, 58, 6, 37, 50, 6, 72, 6, 40, 0, 7, 6, 1, 4, 0, 4, 3, 58, 112, 89, 6, 109, 34, 4, 81, 13, 0, 8, 0, 1, 17, 67, 2, 32, 3, 108, 0, 4, 1, 17, 65, 2, 17, 65, 3, 108, 4, 0, 1, 17, 65, 2, 17, 67, 0, 1, 17, 65, 2, 32, 0, 1, 17, 67, 2, 17, 65, 0, 1, 17, 67, 2, 17, 67, 0, 7, 6, 1, 5, 0, 3, 126, 6, 0, 7, 6, 1, 6, 0, 3, 109, 0, 224, 164, 129, 3, 129, 6, 0, 7, 6, 1, 7, 0, 3, 118, 0, 224, 164, 135, 3, 118, 113, 0, 224, 164, 137, 3, 118, 122, 0, 224, 164, 138, 3, 118, 122, 6, 0, 224, 164, 129, 3, 128, 7, 0, 7, 6, 1, 8, 0, 3, 113, 0, 224, 164, 129, 3, 124, 6, 0, 7, 6, 1, 9, 0, 2, 32, 3, 112, 0, 3, 113, 12, 0, 224, 164, 129, 3, 124, 7, 0, 7, 6, 1, 10, 0, 3, 122, 0, 224, 164, 129, 3, 133, 6, 0, 7, 6, 1, 11, 0, 3, 122, 0, 224, 164, 129, 3, 133, 6, 0, 7, 6, 1, 12, 0, 3, 34, 113, 0, 7, 6, 1, 13, 0, 3, 55, 34, 113, 0, 7, 6, 1, 14, 0, 3, 116, 0, 7, 6, 1, 15, 0, 3, 36, 0, 224, 164, 129, 3, 126, 6, 0, 7, 6, 1, 16, 0, 3, 114, 0, 224, 164, 129, 3, 126, 6, 4, 0, 7, 6, 1, 17, 0, 224, 164, 129, 3, 127, 6, 0, 5, 2, 3, 134, 0, 3, 152, 0, 7, 6, 1, 18, 0, 3, 121, 0, 7, 6, 1, 19, 0, 3, 39, 0, 7, 6, 1, 20, 0, 3, 119, 0, 224, 164, 129, 3, 131, 6, 0, 7, 6, 1, 21, 0, 224, 164, 129, 3, 130, 6, 0, 5, 3, 3, 135, 0, 3, 153, 0, 7, 6, 1, 22, 0, 5, 1, 2, 32, 107, 3, 0, 2, 17, 66, 3, 49, 0, 2, 224, 165, 141, 224, 164, 149, 3, 49, 4, 0, 2, 224, 165, 141, 224, 164, 175, 3, 49, 12, 0, 3, 49, 109, 0, 4, 224, 164, 129, 3, 49, 129, 6, 0, 224, 165, 133, 0, 1, 141, 165, 224, 2, 32, 3, 49, 149, 0, 7, 6, 1, 23, 0, 4, 2, 17, 66, 3, 146, 0, 5, 1, 2, 32, 0, 2, 224, 165, 141, 224, 164, 150, 3, 146, 4, 0, 3, 146, 109, 0, 4, 224, 164, 129, 3, 146, 129, 6, 0, 224, 165, 133, 0, 1, 141, 165, 224, 2, 32, 3, 146, 149, 0, 7, 6, 1, 24, 0, 4, 2, 17, 66, 3, 81, 0, 5, 1, 2, 32, 0, 2, 224, 165, 141, 224, 164, 151, 3, 81, 4, 0, 3, 81, 109, 0, 4, 224, 164, 129, 3, 81, 129, 6, 0, 224, 165, 133, 0, 1, 141, 165, 224, 2, 32, 3, 81, 149, 0, 7, 6, 1, 25, 0, 4, 2, 17, 66, 3, 147, 0, 5, 1, 2, 32, 0, 2, 224, 165, 141, 224, 164, 152, 3, 147, 4, 0, 3, 147, 109, 0, 4, 224, 164, 129, 3, 147, 129, 6, 0, 224, 165, 133, 0, 1, 141, 165, 224, 2, 32, 3, 147, 149, 0, 7, 6, 1, 26, 0, 4, 2, 17, 66, 3, 68, 0, 2, 32, 0, 3, 68, 109, 0, 1, 141, 165, 224, 2, 32, 3, 68, 149, 0, 7, 6, 1, 27, 0, 4, 2, 17, 66, 3, 80, 0, 5, 1, 2, 32, 0, 2, 224, 165, 141, 224, 164, 154, 3, 80, 4, 0, 2, 224, 165, 141, 224, 164, 175, 3, 80, 12, 0, 3, 80, 109, 0, 4, 224, 164, 129, 3, 80, 129, 6, 0, 224, 165, 133, 0, 1, 141, 165, 224, 2, 32, 3, 80, 149, 0, 7, 6, 1, 28, 0, 2, 17, 66, 3, 144, 0, 4, 1, 141, 165, 224, 2, 17, 67, 3, 144, 13, 0, 2, 32, 0, 3, 144, 109, 0, 4, 224, 164, 129, 3, 144, 129, 6, 0, 224, 165, 133, 0, 7, 6, 1, 29, 0, 4, 2, 17, 66, 3, 79, 0, 5, 1, 2, 32, 0, 2, 224, 165, 141, 224, 164, 156, 3, 79, 4, 0, 3, 79, 109, 0, 4, 224, 164, 129, 3, 79, 129, 6, 0, 224, 165, 133, 0, 1, 141, 165, 224, 2, 32, 3, 79, 149, 0, 7, 6, 1, 30, 0, 2, 224, 165, 141, 224, 164, 157, 3, 79, 4, 0, 4, 2, 17, 66, 3, 145, 0, 2, 32, 0, 3, 145, 109, 0, 4, 224, 164, 129, 3, 145, 129, 6, 0, 224, 165, 133, 0, 7, 6, 1, 31, 0, 2, 17, 66, 3, 67, 0, 2, 32, 3, 67, 13, 0, 1, 141, 165, 224, 156, 164, 224, 2, 32, 3, 67, 13, 12, 4, 0, 3, 67, 109, 0, 1, 141, 165, 224, 2, 32, 3, 67, 149, 0, 7, 6, 1, 32, 0, 4, 2, 17, 66, 3, 140, 0, 5, 1, 2, 32, 0, 4, 2, 224, 165, 141, 224, 164, 159, 3, 140, 4, 0, 2, 224, 165, 141, 224, 164, 160, 0, 2, 224, 165, 141, 224, 164, 175, 3, 140, 12, 0, 3, 140, 109, 0, 4, 224, 164, 129, 3, 140, 129, 6, 0, 224, 165, 133, 0, 1, 141, 165, 224, 2, 32, 3, 140, 149, 0, 7, 6, 1, 33, 0, 5, 1, 2, 32, 3, 140, 107, 0, 4, 224, 164, 129, 3, 140, 107, 129, 6, 0, 224, 165, 133, 0, 2, 17, 66, 3, 142, 0, 2, 224, 165, 141, 224, 164, 160, 3, 142, 4, 0, 3, 142, 109, 0, 1, 141, 165, 224, 2, 32, 3, 142, 149, 0, 7, 6, 1, 34, 0, 4, 2, 17, 66, 3, 141, 0, 5, 1, 2, 32, 0, 2, 224, 165, 141, 224, 164, 161, 3, 141, 4, 0, 4, 2, 224, 165, 141, 224, 164, 175, 3, 141, 12, 0, 224, 164, 188, 2, 17, 66, 0, 4, 224, 164, 188, 224, 164, 129, 3, 141, 12, 129, 6, 0, 224, 164, 188, 224, 165, 133, 0, 3, 141, 109, 0, 224, 164, 188, 3, 141, 109, 12, 0, 4, 224, 164, 129, 3, 141, 129, 6, 0, 224, 165, 133, 0, 1, 141, 165, 224, 2, 32, 3, 141, 149, 0, 7, 6, 1, 35, 0, 4, 5, 1, 2, 32, 3, 141, 107, 0, 224, 164, 188, 2, 17, 66, 0, 224, 164, 188, 3, 141, 107, 109, 12, 0, 4, 224, 164, 129, 3, 141, 107, 129, 6, 0, 224, 165, 133, 0, 2, 17, 66, 3, 143, 0, 3, 143, 109, 0, 1, 141, 165, 224, 2, 32, 3, 143, 149, 0, 7, 6, 1, 36, 0, 4, 2, 17, 66, 3, 66, 0, 5, 1, 2, 32, 0, 2, 17, 67, 3, 66, 13, 0, 3, 66, 109, 0, 1, 141, 165, 224, 2, 32, 3, 66, 149, 0, 7, 6, 1, 37, 0, 2, 17, 66, 3, 47, 0, 4, 2, 224, 165, 141, 224, 164, 164, 3, 47, 4, 0, 5, 1, 2, 32, 0, 2, 224, 165, 141, 224, 164, 175, 3, 47, 12, 0, 3, 47, 109, 0, 4, 224, 164, 129, 3, 47, 129, 6, 0, 224, 165, 133, 0, 1, 141, 165, 224, 2, 32, 3, 47, 149, 0, 7, 6, 1, 38, 0, 4, 2, 17, 66, 3, 138, 0, 5, 1, 2, 32, 0, 2, 224, 165, 141, 224, 164, 175, 3, 138, 4, 0, 3, 138, 109, 0, 4, 224, 164, 129, 3, 138, 129, 6, 0, 224, 165, 133, 0, 1, 141, 165, 224, 2, 32, 3, 138, 149, 0, 7, 6, 1, 39, 0, 4, 2, 17, 66, 3, 72, 0, 5, 1, 2, 32, 0, 2, 224, 165, 141, 224, 164, 166, 3, 72, 4, 0, 4, 2, 224, 165, 141, 224, 164, 167, 3, 72, 12, 0, 2, 224, 165, 141, 224, 164, 181, 0, 3, 72, 109, 0, 4, 224, 164, 129, 3, 72, 129, 6, 0, 224, 165, 133, 0, 1, 141, 165, 224, 2, 32, 3, 72, 149, 0, 7, 6, 1, 40, 0, 4, 2, 17, 66, 3, 139, 0, 5, 1, 2, 32, 0, 3, 139, 109, 0, 4, 224, 164, 129, 3, 139, 129, 6, 0, 224, 165, 133, 0, 1, 141, 165, 224, 2, 32, 3, 139, 149, 0, 7, 6, 1, 41, 0, 4, 2, 17, 66, 3, 50, 0, 5, 1, 2, 32, 0, 2, 224, 165, 141, 224, 164, 168, 3, 50, 4, 0, 4, 1, 136, 165, 224, 17, 67, 2, 32, 3, 50, 13, 0, 1, 143, 164, 224, 2, 32, 0, 1, 191, 164, 224, 166, 164, 224, 17, 66, 17, 67, 2, 32, 0, 1, 17, 66, 17, 67, 2, 224, 165, 129, 32, 3, 50, 40, 38, 0, 3, 50, 109, 0, 4, 224, 164, 129, 3, 50, 129, 6, 0, 224, 165, 133, 0, 1, 141, 165, 224, 2, 32, 3, 50, 149, 0, 7, 6, 1, 42, 0, 3, 50, 6, 35, 0, 7, 6, 1, 43, 0, 4, 2, 17, 66, 3, 48, 0, 5, 1, 2, 32, 0, 2, 224, 165, 141, 224, 164, 170, 3, 48, 4, 0, 2, 224, 165, 141, 224, 164, 175, 3, 48, 12, 0, 3, 48, 109, 0, 4, 224, 164, 129, 3, 48, 129, 6, 0, 224, 165, 133, 0, 1, 141, 165, 224, 2, 32, 3, 48, 149, 0, 7, 6, 1, 44, 0, 4, 2, 17, 66, 3, 136, 0, 5, 1, 2, 32, 0, 2, 224, 165, 141, 224, 164, 168, 3, 136, 12, 0, 3, 136, 109, 0, 4, 224, 164, 129, 3, 136, 129, 6, 0, 224, 165, 133, 0, 1, 141, 165, 224, 2, 32, 3, 136, 149, 0, 7, 6, 1, 45, 0, 4, 2, 17, 66, 3, 71, 0, 5, 1, 2, 32, 0, 2, 224, 165, 141, 224, 164, 172, 3, 71, 12, 0, 3, 71, 109, 0, 4, 224, 164, 129, 3, 71, 129, 6, 0, 224, 165, 133, 0, 1, 141, 165, 224, 2, 32, 3, 71, 149, 0, 7, 6, 1, 46, 0, 4, 2, 17, 66, 3, 137, 0, 5, 1, 2, 32, 0, 2, 224, 165, 141, 224, 164, 175, 3, 137, 4, 0, 3, 137, 109, 0, 4, 224, 164, 129, 3, 137, 129, 6, 0, 224, 165, 133, 0, 1, 141, 165, 224, 2, 32, 3, 137, 149, 0, 7, 6, 1, 47, 0, 2, 17, 66, 3, 65, 0, 2, 224, 165, 141, 224, 164, 174, 3, 65, 4, 0, 2, 224, 165, 141, 224, 164, 175, 3, 65, 12, 0, 3, 65, 109, 0, 4, 224, 164, 129, 3, 65, 129, 6, 0, 224, 165, 133, 0, 1, 141, 165, 224, 2, 32, 3, 65, 149, 0, 7, 6, 1, 48, 0, 2, 17, 66, 3, 57, 0, 3, 57, 109, 0, 5, 1, 2, 32, 3, 57, 111, 0, 4, 224, 164, 129, 3, 57, 129, 6, 0, 224, 165, 133, 0, 1, 141, 165, 224, 2, 32, 3, 57, 149, 0, 7, 6, 1, 49, 0, 2, 17, 66, 3, 34, 0, 224, 165, 141, 226, 128, 141, 3, 34, 6, 12, 0, 1, 141, 165, 224, 2, 99, 3, 34, 6, 84, 12, 0, 2, 224, 165, 141, 17, 67, 3, 34, 12, 0, 4, 1, 135, 165, 224, 17, 67, 2, 32, 3, 34, 13, 0, 1, 135, 165, 224, 17, 67, 2, 32, 0, 3, 34, 109, 0, 224, 164, 176, 2, 32, 3, 34, 110, 34, 111, 0, 4, 224, 164, 129, 3, 34, 129, 6, 0, 224, 165, 133, 0, 7, 6, 1, 50, 0, 2, 17, 66, 3, 34, 6, 0, 3, 34, 6, 109, 0, 1, 141, 165, 224, 2, 32, 3, 34, 149, 0, 7, 6, 1, 51, 0, 4, 2, 17, 66, 3, 55, 0, 5, 1, 2, 32, 0, 2, 224, 165, 141, 224, 164, 178, 3, 55, 12, 0, 3, 55, 109, 0, 4, 224, 164, 129, 3, 55, 129, 6, 0, 224, 165, 133, 0, 1, 141, 165, 224, 2, 32, 3, 55, 149, 0, 7, 6, 1, 52, 0, 2, 17, 66, 3, 62, 0, 1, 141, 165, 224, 2, 32, 3, 62, 13, 0, 3, 62, 109, 0, 7, 6, 1, 53, 0, 2, 17, 66, 3, 62, 0, 1, 141, 165, 224, 2, 32, 3, 62, 13, 0, 3, 62, 109, 0, 7, 6, 1, 54, 0, 1, 141, 165, 224, 167, 164, 224, 2, 32, 3, 6, 58, 109, 0, 8, 2, 17, 66, 3, 58, 0, 4, 1, 141, 165, 224, 17, 67, 3, 58, 6, 0, 1, 141, 165, 224, 167, 164, 224, 2, 17, 66, 0, 1, 141, 165, 224, 185, 164, 224, 0, 2, 17, 66, 0, 1, 141, 165, 224, 167, 164, 224, 2, 17, 67, 3, 58, 6, 109, 0, 4, 3, 58, 109, 0, 8, 0, 224, 164, 129, 8, 3, 58, 129, 6, 0, 8, 2, 224, 165, 141, 3, 84, 0, 4, 224, 164, 129, 3, 84, 129, 6, 0, 224, 165, 133, 0, 7, 6, 1, 55, 0, 4, 2, 17, 66, 3, 91, 0, 5, 1, 2, 32, 0, 2, 224, 165, 141, 224, 164, 154, 3, 91, 12, 0, 3, 91, 109, 0, 4, 224, 164, 129, 3, 91, 129, 6, 0, 224, 165, 133, 0, 1, 141, 165, 224, 2, 32, 3, 91, 149, 0, 7, 6, 1, 56, 0, 4, 2, 17, 66, 3, 93, 0, 5, 1, 2, 32, 0, 4, 2, 224, 165, 141, 224, 164, 159, 3, 93, 4, 0, 2, 224, 165, 141, 224, 164, 160, 0, 3, 93, 109, 0, 4, 224, 164, 129, 3, 93, 129, 6, 0, 224, 165, 133, 0, 1, 141, 165, 224, 2, 32, 3, 93, 149, 0, 7, 6, 1, 57, 0, 4, 2, 17, 66, 3, 89, 0, 5, 1, 2, 32, 0, 2, 224, 165, 141, 224, 164, 184, 3, 89, 4, 0, 3, 89, 109, 0, 1, 141, 165, 224, 2, 32, 3, 89, 149, 0, 4, 224, 164, 129, 3, 91, 129, 6, 0, 224, 165, 133, 0, 7, 6, 1, 58, 0, 2, 17, 66, 3, 107, 0, 3, 107, 109, 0, 4, 224, 164, 129, 3, 107, 129, 6, 0, 224, 165, 133, 0, 1, 141, 165, 224, 2, 32, 3, 107, 149, 0, 7, 6, 1, 62, 0, 4, 1, 17, 65, 3, 12, 8, 0, 1, 17, 67, 0, 3, 109, 6, 49, 6, 118, 34, 13, 0, 7, 6, 1, 63, 0, 1, 17, 67, 3, 118, 0, 3, 118, 4, 49, 6, 118, 12, 34, 13, 0, 224, 164, 129, 1, 17, 67, 3, 128, 6, 0, 224, 164, 181, 3, 135, 0, 7, 6, 1, 64, 0, 3, 37, 6, 49, 6, 118, 12, 34, 13, 0, 1, 17, 67, 3, 113, 0, 224, 164, 129, 1, 17, 67, 3, 124, 6, 0, 7, 6, 1, 65, 0, 1, 17, 67, 2, 32, 3, 112, 0, 3, 112, 4, 8, 49, 6, 118, 12, 34, 13, 0, 1, 17, 67, 3, 113, 12, 0, 224, 164, 129, 1, 17, 67, 3, 124, 6, 0, 7, 6, 1, 66, 0, 1, 17, 67, 3, 40, 0, 1, 168, 164, 224, 133, 164, 224, 3, 40, 4, 20, 0, 3, 122, 6, 49, 6, 118, 12, 34, 13, 0, 224, 164, 129, 1, 17, 67, 3, 133, 6, 0, 7, 6, 1, 67, 0, 3, 58, 123, 4, 8, 49, 6, 118, 12, 34, 13, 0, 1, 17, 67, 3, 123, 0, 224, 164, 129, 1, 17, 67, 3, 133, 6, 0, 7, 6, 1, 68, 0, 1, 17, 67, 3, 34, 6, 113, 0, 3, 34, 112, 4, 49, 6, 118, 34, 13, 0, 7, 6, 1, 69, 0, 1, 17, 67, 3, 34, 34, 6, 112, 4, 0, 3, 34, 34, 112, 4, 49, 6, 118, 34, 13, 0, 7, 6, 1, 70, 0, 3, 116, 4, 80, 112, 50, 6, 107, 13, 12, 0, 1, 17, 67, 3, 129, 6, 0, 7, 6, 1, 71, 0, 1, 17, 67, 3, 36, 0, 3, 36, 6, 49, 6, 118, 12, 34, 149, 0, 7, 6, 1, 72, 0, 1, 17, 67, 3, 114, 0, 3, 114, 6, 49, 6, 118, 12, 34, 13, 0, 224, 164, 129, 1, 17, 67, 3, 126, 6, 0, 7, 6, 1, 73, 0, 1, 17, 67, 3, 115, 0, 224, 164, 129, 1, 17, 67, 3, 127, 6, 0, 5, 2, 1, 17, 67, 3, 134, 0, 3, 152, 12, 6, 49, 6, 118, 12, 34, 13, 0, 7, 6, 1, 74, 0, 1, 17, 67, 3, 118, 50, 0, 3, 120, 0, 7, 6, 1, 75, 0, 1, 17, 67, 3, 39, 0, 3, 39, 49, 6, 118, 12, 34, 13, 0, 7, 6, 1, 76, 0, 1, 17, 67, 3, 119, 0, 3, 119, 4, 49, 6, 118, 12, 34, 13, 0, 224, 164, 129, 1, 17, 67, 3, 131, 6, 0, 7, 6, 1, 77, 0, 1, 17, 67, 3, 120, 0, 3, 120, 40, 49, 118, 12, 34, 13, 0, 224, 164, 129, 1, 17, 67, 3, 130, 6, 0, 5, 3, 1, 17, 67, 3, 135, 0, 7, 6, 1, 78, 0, 1, 17, 67, 3, 0, 1, 17, 67, 2, 17, 67, 32, 3, 8, 0, 3, 107, 6, 109, 55, 110, 50, 6, 47, 111, 0, 7, 6, 1, 81, 0, 3, 131, 7, 65, 0, 7, 6, 1, 89, 0, 2, 17, 66, 3, 104, 0, 3, 104, 109, 0, 7, 6, 1, 90, 0, 2, 17, 66, 3, 101, 0, 3, 101, 109, 0, 7, 6, 1, 91, 0, 2, 17, 66, 3, 100, 0, 3, 100, 109, 0, 7, 6, 1, 92, 0, 2, 17, 66, 3, 88, 0, 3, 88, 109, 0, 7, 6, 1, 93, 0, 2, 17, 66, 3, 70, 0, 3, 70, 109, 0, 7, 6, 1, 94, 0, 2, 17, 66, 3, 70, 107, 0, 3, 70, 107, 109, 0, 7, 6, 1, 95, 0, 2, 17, 66, 3, 83, 0, 3, 83, 109, 0, 7, 6, 1, 96, 0, 2, 17, 66, 3, 57, 0, 3, 57, 109, 0, 7, 6, 1, 97, 0, 3, 34, 34, 113, 12, 0, 7, 6, 1, 98, 0, 3, 55, 55, 34, 112, 0, 7, 6, 1, 99, 0, 3, 55, 6, 34, 112, 49, 6, 118, 12, 34, 13, 0, 7, 6, 1, 100, 0, 3, 55, 55, 6, 34, 112, 4, 49, 6, 118, 12, 34, 13, 12, 0, 7, 6, 1, 115, 0, 3, 129, 6, 0, 7, 6, 1, 124, 0, 2, 17, 66, 3, 100, 0, 3, 100, 109, 0, 7, 6, 1, 125, 0, 2, 17, 66, 3, 88, 0, 3, 88, 109, 0, 7, 6, 1, 127, 0, 2, 17, 66, 3, 70, 0, 3, 70, 109, 0, 7, 6, 1, 128, 0, 2, 17, 66, 3, 71, 0, 3, 71, 13, 0, 7, 6, 43, 0, 3, 48, 55, 109, 89, 0, 4, 1, 32, 17, 65, 3, 79, 6, 39, 72, 80, 6, 37, 50, 107, 111, 0, 1, 32, 17, 67, 0, 2, 32, 17, 65, 0, 2, 32, 17, 67, 0, 7, 6, 45, 0, 4, 1, 32, 12, 3, 65, 6, 35, 37, 50, 109, 8, 89, 0, 1, 32, 61, 0, 1, 32, 166, 165, 224, 0, 1, 32, 167, 165, 224, 0, 1, 32, 168, 165, 224, 0, 1, 32, 169, 165, 224, 0, 1, 32, 170, 165, 224, 0, 1, 32, 171, 165, 224, 0, 1, 32, 172, 165, 224, 0, 1, 32, 173, 165, 224, 0, 1, 32, 174, 165, 224, 0, 1, 32, 175, 165, 224, 0, 2, 32, 12, 0, 2, 32, 61, 0, 2, 32, 224, 165, 166, 0, 2, 32, 224, 165, 167, 0, 2, 32, 224, 165, 168, 0, 2, 32, 224, 165, 169, 0, 2, 32, 224, 165, 170, 0, 2, 32, 224, 165, 171, 0, 2, 32, 224, 165, 172, 0, 2, 32, 224, 165, 173, 0, 2, 32, 224, 165, 174, 0, 2, 32, 224, 165, 175, 0, 3, 141, 57, 118, 91, 0, 7, 6, 61, 0, 4, 1, 32, 17, 65, 3, 71, 109, 34, 6, 118, 71, 35, 8, 34, 0, 1, 32, 17, 67, 0, 1, 32, 166, 165, 224, 0, 1, 32, 167, 165, 224, 0, 1, 32, 168, 165, 224, 0, 1, 32, 169, 165, 224, 0, 1, 32, 170, 165, 224, 0, 1, 32, 171, 165, 224, 0, 1, 32, 172, 165, 224, 0, 1, 32, 173, 165, 224, 0, 1, 32, 174, 165, 224, 0, 1, 32, 175, 165, 224, 0, 2, 32, 17, 65, 0, 2, 32, 17, 67, 0, 2, 32, 224, 165, 166, 0, 2, 32, 224, 165, 167, 0, 2, 32, 224, 165, 168, 0, 2, 32, 224, 165, 169, 0, 2, 32, 224, 165, 170, 0, 2, 32, 224, 165, 171, 0, 2, 32, 224, 165, 172, 0, 2, 32, 224, 165, 173, 0, 2, 32, 224, 165, 174, 0, 2, 32, 224, 165, 175, 0, 3, 113, 6, 88, 4, 112, 49, 6, 58, 109, 6, 55, 0, 7, 6, 91, 0, 3, 55, 6, 36, 83, 47, 71, 34, 6, 35, 49, 6, 36, 47, 0, 4, 2, 32, 17, 65, 3, 138, 6, 40, 55, 6, 39, 49, 6, 39, 89, 107, 140, 111, 89, 40, 34, 40, 0, 2, 32, 17, 67, 0, 2, 32, 224, 165, 166, 0, 2, 32, 224, 165, 167, 0, 2, 32, 224, 165, 168, 0, 2, 32, 224, 165, 169, 0, 2, 32, 224, 165, 170, 0, 2, 32, 224, 165, 171, 0, 2, 32, 224, 165, 172, 0, 2, 32, 224, 165, 173, 0, 2, 32, 224, 165, 174, 0, 2, 32, 224, 165, 175, 0, 7, 6, 93, 0, 3, 34, 6, 35, 37, 47, 71, 34, 6, 35, 49, 6, 36, 47, 0, 4, 1, 32, 17, 65, 3, 138, 6, 40, 55, 6, 39, 49, 6, 39, 89, 107, 140, 111, 71, 6, 109, 50, 72, 111, 0, 1, 32, 17, 67, 0, 1, 32, 166, 165, 224, 0, 1, 32, 167, 165, 224, 0, 1, 32, 168, 165, 224, 0, 1, 32, 169, 165, 224, 0, 1, 32, 170, 165, 224, 0, 1, 32, 171, 165, 224, 0, 1, 32, 172, 165, 224, 0, 1, 32, 173, 165, 224, 0, 1, 32, 174, 165, 224, 0, 1, 32, 175, 165, 224, 0, 7, 6, 123, 0, 3, 55, 6, 36, 83, 47, 71, 34, 6, 150, 89, 0, 4, 2, 32, 17, 65, 3, 71, 6, 118, 68, 81, 6, 36, 49, 6, 39, 89, 107, 142, 111, 89, 40, 34, 40, 0, 2, 32, 17, 67, 0, 2, 32, 224, 165, 166, 0, 2, 32, 224, 165, 167, 0, 2, 32, 224, 165, 168, 0, 2, 32, 224, 165, 169, 0, 2, 32, 224, 165, 170, 0, 2, 32, 224, 165, 171, 0, 2, 32, 224, 165, 172, 0, 2, 32, 224, 165, 173, 0, 2, 32, 224, 165, 174, 0, 2, 32, 224, 165, 175, 0, 7, 6, 125, 0, 3, 34, 6, 134, 47, 71, 34, 6, 150, 89, 0, 4, 1, 32, 17, 65, 3, 71, 6, 118, 68, 81, 6, 36, 49, 6, 39, 89, 107, 142, 111, 71, 6, 109, 50, 72, 111, 0, 1, 32, 17, 67, 0, 1, 32, 166, 165, 224, 0, 1, 32, 167, 165, 224, 0, 1, 32, 168, 165, 224, 0, 1, 32, 169, 165, 224, 0, 1, 32, 170, 165, 224, 0, 1, 32, 171, 165, 224, 0, 1, 32, 172, 165, 224, 0, 1, 32, 173, 165, 224, 0, 1, 32, 174, 165, 224, 0, 1, 32, 175, 165, 224, 0, 7, 6, 0, 4, 224, 165, 145, 3, 0, 4, 224, 165, 147, 3, 0, 4, 224, 165, 148, 3, 0, 224, 165, 189, 3, 0, 37, 3, 48, 34, 109, 47, 37, 89, 107, 6, 84, 47, 0, 224, 165, 164, 3, 48, 40, 34, 6, 4, 66, 13, 4, 58, 6, 37, 34, 6, 118, 65, 0, 224, 164, 188, 3, 50, 6, 40, 6, 49, 6, 47, 6, 118, 0, 224, 165, 177, 3, 71, 6, 112, 50, 8, 72, 6, 123, 0, 224, 165, 165, 3, 72, 6, 39, 71, 6, 71, 111, 34, 111, 4, 58, 37, 34, 6, 118, 12, 65, 109, 0, 36, 3, 72, 121, 55, 109, 0, 224, 165, 176, 3, 109, 4, 50, 89, 107, 13, 0, 224, 165, 146, 3, 109, 72, 6, 119, 4, 34, 6, 36, 146, 6, 118, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts44 = FileInMemory_createWithData (10794, reinterpret_cast (&espeakdata_dicts44_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/ne_dict", U"ne"); Collection_addItem (me.peek(), espeakdata_dicts44.transfer()); static unsigned char espeakdata_dicts45_data[21599] = { 0, 4, 0, 0, 41, 59, 0, 0, 0, 0, 0, 0, 0, 8, 197, 104, 242, 69, 81, 48, 66, 0, 10, 199, 44, 20, 130, 60, 226, 197, 48, 20, 10, 199, 52, 21, 83, 60, 193, 85, 52, 20, 0, 11, 70, 32, 20, 132, 92, 20, 133, 21, 0, 10, 7, 195, 92, 19, 148, 72, 8, 0, 0, 8, 197, 92, 145, 71, 20, 192, 20, 8, 197, 61, 32, 75, 20, 192, 20, 8, 197, 8, 85, 71, 20, 192, 20, 8, 197, 45, 33, 71, 20, 192, 20, 6, 65, 8, 71, 119, 0, 0, 9, 198, 76, 193, 78, 80, 84, 128, 20, 9, 198, 64, 197, 78, 16, 84, 128, 20, 9, 198, 44, 224, 80, 64, 84, 128, 20, 9, 198, 44, 192, 80, 64, 84, 128, 20, 9, 198, 12, 128, 82, 80, 84, 128, 20, 9, 198, 92, 19, 142, 20, 84, 128, 8, 0, 0, 11, 67, 12, 17, 133, 49, 115, 83, 6, 119, 0, 7, 196, 89, 32, 71, 20, 20, 0, 13, 69, 16, 145, 83, 20, 192, 72, 37, 88, 13, 55, 0, 24, 73, 8, 245, 82, 28, 243, 132, 36, 84, 128, 71, 40, 34, 101, 6, 122, 50, 72, 37, 12, 13, 34, 0, 8, 197, 77, 82, 203, 20, 192, 20, 8, 197, 72, 149, 19, 20, 192, 20, 9, 197, 104, 243, 1, 56, 112, 66, 8, 6, 65, 12, 89, 119, 0, 0, 9, 198, 57, 80, 200, 80, 84, 128, 20, 0, 13, 4, 95, 8, 1, 3, 107, 6, 115, 76, 111, 49, 0, 0, 11, 200, 89, 35, 213, 92, 83, 135, 20, 176, 22, 0, 8, 197, 49, 82, 77, 21, 32, 20, 6, 65, 16, 72, 119, 0, 0, 13, 202, 60, 225, 197, 52, 18, 203, 20, 194, 74, 44, 67, 0, 9, 67, 20, 83, 128, 13, 50, 0, 9, 0, 0, 8, 197, 52, 20, 141, 21, 32, 20, 16, 65, 20, 37, 12, 65, 119, 55, 0, 44, 81, 109, 97, 105, 108, 32, 5, 65, 20, 119, 0, 0, 16, 70, 21, 0, 85, 48, 85, 0, 119, 48, 122, 55, 6, 111, 47, 0, 0, 9, 67, 92, 146, 128, 85, 2, 123, 0, 9, 67, 28, 146, 128, 100, 2, 123, 0, 18, 4, 95, 48, 67, 15, 107, 6, 113, 50, 72, 111, 34, 47, 89, 47, 13, 0, 0, 0, 6, 65, 24, 111, 83, 0, 0, 0, 0, 9, 198, 76, 227, 197, 104, 83, 0, 20, 9, 198, 45, 114, 83, 64, 83, 0, 20, 9, 198, 45, 34, 78, 44, 83, 0, 20, 0, 8, 197, 52, 85, 19, 20, 192, 20, 6, 65, 28, 100, 119, 0, 0, 17, 70, 16, 85, 197, 88, 84, 128, 72, 13, 6, 85, 119, 84, 13, 34, 0, 16, 70, 8, 245, 68, 60, 148, 128, 71, 40, 72, 58, 6, 115, 34, 0, 9, 198, 76, 194, 68, 16, 84, 128, 20, 9, 198, 44, 193, 68, 16, 84, 128, 20, 0, 6, 195, 44, 19, 128, 72, 0, 0, 12, 201, 36, 225, 197, 92, 146, 203, 20, 193, 0, 67, 6, 65, 32, 107, 115, 0, 0, 9, 198, 64, 20, 148, 36, 177, 76, 20, 9, 198, 81, 35, 203, 44, 83, 128, 20, 0, 0, 11, 1, 35, 107, 6, 111, 49, 57, 13, 0, 27, 0, 6, 65, 36, 37, 12, 0, 0, 9, 198, 52, 240, 200, 80, 83, 128, 72, 13, 1, 37, 48, 14, 16, 122, 89, 6, 111, 50, 47, 0, 0, 0, 0, 8, 197, 92, 19, 139, 20, 192, 20, 8, 197, 88, 193, 71, 20, 192, 20, 8, 197, 44, 147, 139, 20, 192, 20, 8, 197, 32, 18, 203, 20, 192, 20, 8, 197, 92, 242, 203, 20, 192, 20, 8, 197, 80, 80, 203, 20, 192, 20, 6, 65, 40, 57, 119, 0, 0, 9, 198, 88, 194, 78, 16, 84, 128, 20, 9, 198, 76, 226, 80, 64, 84, 128, 20, 9, 198, 64, 19, 1, 88, 84, 128, 20, 9, 198, 44, 226, 80, 64, 84, 128, 20, 9, 198, 44, 193, 80, 64, 84, 128, 20, 9, 198, 32, 84, 143, 88, 84, 128, 20, 9, 198, 28, 197, 78, 16, 84, 128, 20, 9, 198, 24, 194, 80, 64, 84, 128, 20, 9, 198, 8, 197, 78, 16, 84, 128, 20, 0, 15, 1, 42, 89, 47, 6, 111, 16, 34, 111, 47, 38, 13, 0, 27, 0, 7, 196, 49, 32, 71, 20, 20, 7, 196, 17, 32, 71, 20, 20, 10, 1, 43, 48, 55, 6, 110, 89, 0, 27, 0, 8, 197, 64, 147, 135, 20, 192, 20, 8, 197, 40, 83, 135, 20, 192, 20, 8, 197, 32, 83, 135, 20, 192, 20, 8, 197, 24, 18, 203, 20, 192, 20, 8, 197, 17, 82, 75, 20, 192, 20, 8, 197, 9, 83, 135, 20, 192, 20, 8, 197, 8, 146, 203, 20, 192, 20, 8, 197, 8, 83, 135, 20, 192, 20, 8, 197, 80, 82, 203, 20, 192, 20, 8, 197, 16, 243, 135, 20, 192, 20, 6, 65, 44, 49, 115, 0, 0, 9, 198, 44, 225, 84, 80, 84, 128, 20, 9, 198, 28, 194, 84, 80, 84, 128, 20, 9, 198, 24, 192, 68, 16, 84, 128, 20, 0, 9, 1, 46, 48, 110, 50, 47, 0, 27, 0, 9, 1, 47, 89, 55, 6, 111, 91, 0, 0, 6, 65, 48, 111, 55, 0, 0, 0, 0, 0, 6, 65, 52, 111, 65, 0, 0, 9, 198, 16, 243, 210, 16, 21, 0, 66, 6, 194, 104, 240, 9, 76, 0, 0, 0, 10, 5, 95, 48, 1, 14, 4, 111, 50, 0, 6, 65, 56, 111, 50, 0, 0, 9, 198, 8, 146, 154, 36, 83, 132, 66, 0, 0, 9, 198, 76, 227, 210, 44, 83, 0, 20, 14, 70, 76, 133, 70, 24, 83, 0, 91, 110, 83, 13, 55, 0, 7, 196, 76, 16, 133, 48, 20, 13, 68, 48, 16, 133, 48, 55, 119, 71, 13, 55, 0, 20, 7, 196, 44, 16, 133, 48, 20, 9, 198, 81, 37, 70, 24, 83, 0, 20, 7, 196, 80, 16, 133, 48, 66, 7, 196, 104, 243, 69, 72, 20, 0, 8, 197, 25, 85, 19, 20, 192, 20, 0, 9, 198, 52, 148, 211, 80, 19, 132, 65, 9, 198, 64, 193, 84, 80, 84, 128, 20, 9, 198, 44, 193, 84, 80, 84, 128, 20, 9, 198, 44, 192, 68, 16, 84, 128, 20, 9, 198, 8, 192, 68, 16, 84, 128, 20, 15, 70, 81, 113, 65, 44, 84, 128, 47, 85, 37, 49, 13, 34, 0, 7, 194, 61, 0, 9, 76, 28, 0, 20, 71, 36, 225, 197, 56, 145, 85, 72, 108, 50, 88, 57, 13, 50, 57, 6, 121, 34, 0, 10, 199, 44, 241, 75, 20, 195, 197, 72, 20, 0, 0, 19, 1, 64, 9, 6, 115, 48, 13, 50, 89, 47, 4, 115, 34, 47, 38, 13, 9, 0, 6, 65, 64, 48, 119, 0, 0, 14, 70, 12, 128, 78, 76, 243, 128, 91, 117, 89, 6, 118, 0, 9, 198, 28, 83, 79, 28, 83, 128, 72, 0, 12, 201, 76, 50, 1, 72, 210, 78, 44, 83, 0, 20, 0, 13, 68, 104, 244, 1, 76, 88, 122, 48, 6, 116, 89, 0, 0, 6, 65, 68, 49, 109, 0, 0, 0, 17, 8, 3, 18, 195, 168, 3, 8, 5, 19, 49, 34, 111, 91, 13, 89, 0, 0, 0, 8, 197, 104, 241, 68, 20, 192, 20, 8, 197, 92, 147, 80, 20, 192, 20, 8, 197, 72, 241, 4, 20, 192, 20, 8, 197, 64, 241, 68, 20, 192, 20, 8, 197, 64, 147, 80, 20, 192, 20, 14, 69, 64, 17, 4, 20, 192, 48, 111, 72, 13, 55, 0, 20, 8, 197, 16, 243, 80, 20, 192, 20, 8, 197, 72, 241, 68, 20, 192, 20, 8, 197, 52, 145, 4, 20, 192, 20, 8, 197, 8, 241, 68, 20, 192, 20, 6, 65, 72, 111, 34, 0, 0, 16, 70, 12, 245, 82, 21, 84, 128, 49, 40, 12, 34, 6, 121, 34, 0, 0, 18, 71, 4, 53, 9, 21, 5, 78, 80, 116, 49, 89, 37, 48, 110, 50, 47, 0, 8, 67, 80, 129, 64, 86, 13, 0, 0, 6, 195, 76, 17, 197, 20, 7, 196, 29, 32, 71, 20, 20, 0, 8, 197, 44, 145, 84, 20, 192, 20, 8, 197, 12, 146, 134, 21, 32, 20, 6, 65, 76, 111, 89, 0, 0, 9, 198, 77, 0, 82, 80, 83, 0, 20, 8, 197, 77, 0, 84, 20, 192, 20, 0, 9, 198, 56, 19, 1, 80, 145, 197, 66, 0, 0, 8, 197, 24, 195, 210, 21, 64, 66, 6, 65, 80, 47, 119, 0, 0, 9, 198, 56, 19, 1, 80, 145, 192, 66, 0, 16, 70, 52, 20, 85, 21, 69, 5, 65, 115, 49, 6, 111, 47, 13, 0, 16, 70, 12, 244, 85, 21, 69, 5, 49, 122, 49, 6, 111, 47, 13, 0, 0, 0, 6, 65, 84, 2, 109, 0, 0, 9, 198, 45, 114, 78, 80, 85, 0, 66, 7, 66, 85, 0, 21, 0, 10, 0, 0, 9, 198, 105, 113, 78, 16, 83, 0, 20, 9, 198, 64, 20, 129, 8, 83, 0, 20, 0, 6, 65, 88, 83, 119, 0, 0, 9, 198, 8, 18, 143, 56, 85, 0, 67, 0, 0, 7, 196, 92, 17, 133, 48, 20, 9, 198, 28, 145, 67, 32, 83, 0, 20, 7, 196, 24, 16, 133, 48, 20, 7, 196, 56, 240, 133, 48, 20, 7, 196, 48, 144, 133, 48, 66, 0, 8, 197, 32, 84, 141, 4, 224, 65, 8, 197, 4, 212, 212, 20, 192, 20, 8, 197, 92, 144, 200, 20, 192, 20, 8, 197, 72, 240, 200, 20, 192, 20, 8, 197, 44, 149, 20, 20, 192, 20, 8, 197, 8, 245, 20, 20, 192, 20, 12, 1, 92, 71, 6, 111, 49, 89, 55, 111, 91, 0, 6, 65, 92, 84, 119, 0, 0, 0, 0, 0, 7, 65, 96, 108, 49, 89, 0, 0, 15, 70, 40, 16, 209, 84, 85, 0, 90, 35, 49, 6, 111, 47, 0, 0, 10, 199, 76, 50, 18, 60, 212, 5, 48, 20, 18, 71, 12, 20, 146, 61, 84, 197, 48, 49, 115, 34, 40, 89, 6, 111, 55, 0, 0, 7, 196, 76, 240, 133, 72, 20, 9, 198, 76, 50, 15, 84, 65, 82, 20, 9, 68, 77, 1, 65, 44, 21, 0, 10, 9, 68, 37, 65, 77, 76, 21, 0, 10, 0, 12, 69, 5, 35, 65, 56, 64, 21, 102, 114, 0, 10, 5, 65, 100, 123, 0, 0, 0, 0, 11, 200, 28, 81, 146, 37, 69, 85, 72, 64, 67, 0, 8, 197, 80, 147, 148, 20, 192, 20, 8, 197, 52, 19, 148, 20, 192, 20, 8, 197, 32, 244, 212, 20, 192, 20, 8, 197, 104, 245, 68, 20, 224, 72, 8, 197, 32, 17, 4, 20, 224, 72, 7, 65, 104, 88, 111, 47, 0, 0, 0, 7, 195, 92, 20, 192, 72, 9, 0, 0, 8, 197, 88, 243, 132, 20, 192, 20, 8, 197, 88, 83, 132, 20, 192, 20, 8, 197, 81, 85, 20, 20, 192, 20, 8, 197, 80, 85, 84, 20, 192, 20, 8, 197, 56, 85, 84, 20, 192, 20, 8, 197, 44, 16, 200, 20, 192, 20, 8, 197, 32, 19, 132, 20, 192, 20, 8, 197, 8, 240, 200, 20, 192, 20, 8, 197, 28, 243, 132, 20, 192, 20, 8, 197, 52, 20, 141, 61, 64, 66, 8, 197, 76, 244, 130, 21, 64, 66, 0, 14, 70, 28, 245, 65, 12, 129, 64, 100, 40, 6, 116, 91, 0, 0, 9, 198, 56, 17, 5, 48, 145, 197, 66, 0, 0, 13, 69, 52, 148, 211, 21, 32, 65, 108, 89, 13, 34, 0, 8, 197, 76, 84, 150, 21, 64, 66, 8, 195, 16, 243, 210, 9, 76, 28, 0, 9, 198, 56, 17, 5, 48, 145, 192, 66, 9, 198, 52, 148, 211, 48, 17, 192, 65, 0, 0, 0, 0, 0, 20, 71, 72, 84, 197, 73, 99, 201, 72, 34, 119, 88, 111, 34, 84, 58, 6, 115, 34, 0, 0, 9, 198, 44, 229, 80, 64, 83, 0, 20, 9, 198, 29, 33, 80, 64, 83, 0, 20, 0, 0, 0, 0, 9, 198, 105, 114, 74, 52, 83, 0, 20, 7, 196, 80, 17, 133, 48, 20, 0, 8, 197, 64, 145, 80, 20, 192, 20, 8, 197, 44, 241, 80, 20, 192, 20, 8, 197, 76, 241, 80, 20, 192, 20, 8, 197, 49, 85, 20, 20, 192, 20, 6, 195, 60, 33, 82, 20, 0, 0, 0, 9, 198, 56, 245, 133, 52, 33, 82, 66, 9, 198, 16, 80, 197, 52, 33, 82, 66, 7, 196, 8, 81, 5, 48, 20, 0, 23, 73, 4, 48, 197, 77, 51, 201, 72, 84, 192, 35, 49, 89, 111, 89, 58, 6, 35, 34, 13, 89, 0, 11, 70, 4, 148, 140, 36, 225, 83, 21, 0, 10, 0, 9, 198, 52, 20, 137, 60, 225, 84, 68, 0, 0, 7, 196, 21, 33, 197, 72, 20, 0, 9, 3, 13, 39, 14, 65, 13, 50, 0, 0, 0, 0, 7, 196, 28, 17, 5, 72, 20, 0, 0, 9, 198, 105, 112, 67, 33, 65, 76, 20, 0, 0, 11, 68, 52, 148, 211, 20, 65, 108, 89, 13, 0, 0, 8, 197, 76, 18, 203, 21, 32, 20, 0, 9, 198, 44, 242, 197, 81, 65, 64, 66, 0, 0, 0, 8, 197, 33, 83, 139, 21, 32, 20, 0, 5, 194, 8, 80, 17, 0, 39, 79, 60, 225, 5, 72, 128, 78, 16, 83, 9, 56, 116, 206, 61, 64, 64, 4, 39, 50, 72, 13, 34, 6, 107, 116, 50, 72, 13, 55, 108, 68, 89, 4, 50, 122, 47, 115, 0, 0, 7, 196, 20, 225, 5, 72, 20, 0, 0, 0, 7, 195, 16, 21, 0, 72, 8, 6, 195, 16, 21, 0, 72, 0, 12, 67, 8, 82, 1, 71, 119, 10, 107, 6, 115, 0, 0, 8, 197, 49, 144, 197, 84, 208, 20, 0, 9, 198, 40, 19, 149, 5, 34, 64, 67, 9, 198, 76, 50, 15, 24, 97, 76, 20, 0, 12, 201, 65, 35, 202, 20, 53, 9, 20, 193, 78, 67, 0, 9, 198, 5, 3, 211, 80, 83, 0, 20, 7, 196, 36, 161, 5, 48, 20, 0, 0, 9, 198, 44, 192, 82, 36, 225, 84, 67, 0, 0, 7, 196, 72, 241, 5, 48, 20, 7, 196, 40, 241, 5, 48, 20, 9, 198, 36, 224, 149, 72, 113, 82, 20, 7, 196, 28, 82, 1, 16, 72, 0, 0, 9, 198, 64, 21, 18, 36, 245, 0, 67, 17, 70, 64, 148, 212, 60, 193, 84, 48, 37, 89, 47, 122, 55, 6, 111, 0, 0, 0, 9, 198, 92, 81, 9, 41, 97, 82, 20, 9, 198, 28, 83, 79, 20, 65, 82, 20, 7, 196, 60, 81, 133, 56, 20, 0, 0, 0, 0, 7, 196, 44, 17, 5, 72, 20, 7, 196, 20, 97, 133, 56, 20, 0, 14, 69, 52, 85, 5, 20, 224, 65, 111, 47, 6, 119, 50, 0, 8, 197, 53, 83, 77, 20, 192, 20, 0, 9, 198, 76, 210, 69, 77, 1, 76, 20, 0, 0, 0, 8, 197, 81, 82, 77, 20, 192, 20, 8, 197, 72, 146, 141, 20, 192, 20, 8, 197, 17, 82, 77, 20, 192, 20, 8, 197, 8, 19, 139, 21, 64, 66, 8, 197, 64, 147, 131, 21, 64, 66, 8, 197, 92, 147, 4, 21, 32, 20, 8, 197, 44, 243, 4, 21, 32, 20, 8, 197, 44, 145, 80, 21, 32, 20, 8, 197, 32, 83, 4, 21, 32, 20, 8, 197, 16, 245, 20, 21, 32, 20, 0, 13, 70, 48, 148, 197, 81, 65, 64, 21, 102, 114, 0, 10, 0, 0, 0, 22, 73, 77, 81, 134, 72, 17, 197, 81, 65, 64, 89, 109, 83, 34, 115, 90, 6, 111, 47, 13, 0, 8, 197, 12, 244, 147, 21, 64, 66, 8, 197, 80, 83, 80, 21, 32, 20, 8, 197, 48, 241, 4, 21, 32, 20, 8, 197, 24, 147, 20, 21, 32, 20, 8, 197, 8, 17, 4, 21, 32, 20, 0, 0, 0, 7, 196, 60, 225, 5, 72, 20, 7, 196, 4, 225, 5, 72, 20, 0, 0, 0, 14, 67, 20, 230, 128, 111, 50, 88, 122, 84, 122, 34, 47, 0, 0, 9, 198, 105, 113, 78, 28, 83, 0, 20, 9, 198, 45, 112, 78, 76, 83, 0, 20, 9, 198, 9, 32, 66, 8, 83, 0, 20, 9, 198, 45, 33, 85, 64, 83, 0, 20, 7, 196, 80, 81, 5, 72, 20, 7, 196, 56, 81, 5, 72, 20, 7, 196, 56, 17, 5, 72, 20, 7, 196, 48, 81, 5, 72, 20, 0, 0, 0, 0, 7, 196, 72, 17, 133, 48, 20, 9, 198, 28, 226, 70, 24, 83, 0, 20, 9, 198, 21, 2, 83, 80, 83, 0, 20, 7, 196, 40, 241, 133, 48, 20, 0, 16, 205, 4, 50, 20, 21, 34, 204, 20, 147, 139, 36, 225, 5, 72, 20, 0, 0, 0, 7, 196, 104, 17, 5, 48, 20, 9, 198, 76, 193, 67, 33, 65, 82, 20, 7, 196, 60, 209, 1, 80, 8, 0, 0, 21, 7, 19, 13, 19, 39, 10, 5, 19, 111, 89, 111, 65, 6, 111, 89, 10, 57, 13, 89, 0, 0, 0, 7, 196, 81, 82, 69, 72, 20, 7, 196, 49, 82, 69, 72, 20, 0, 8, 197, 65, 33, 86, 20, 192, 20, 8, 197, 93, 33, 86, 20, 192, 20, 8, 197, 76, 163, 198, 20, 192, 20, 0, 9, 198, 76, 50, 9, 52, 209, 76, 20, 0, 0, 12, 68, 56, 17, 148, 4, 50, 116, 83, 47, 115, 0, 0, 8, 197, 72, 241, 70, 20, 192, 20, 8, 197, 32, 82, 66, 20, 192, 20, 8, 197, 16, 241, 90, 20, 192, 20, 0, 9, 198, 76, 50, 15, 52, 209, 76, 20, 7, 66, 21, 32, 13, 34, 0, 0, 6, 195, 105, 83, 20, 72, 7, 195, 16, 145, 64, 72, 28, 0, 0, 8, 197, 76, 86, 20, 21, 64, 66, 8, 197, 104, 243, 132, 21, 32, 20, 8, 197, 73, 82, 84, 21, 32, 20, 8, 197, 64, 85, 84, 21, 32, 20, 8, 197, 52, 147, 132, 21, 32, 20, 8, 197, 16, 242, 212, 21, 32, 20, 10, 197, 104, 243, 132, 21, 32, 9, 76, 8, 0, 0, 0, 9, 67, 36, 225, 197, 108, 68, 13, 0, 11, 200, 76, 241, 5, 52, 145, 84, 21, 32, 20, 0, 8, 197, 76, 84, 20, 21, 64, 66, 15, 69, 80, 242, 76, 21, 64, 47, 85, 116, 55, 6, 111, 47, 0, 8, 197, 60, 209, 76, 21, 64, 67, 8, 197, 92, 146, 132, 21, 32, 20, 8, 197, 48, 20, 212, 21, 32, 20, 8, 197, 28, 148, 212, 21, 32, 20, 0, 7, 66, 16, 80, 72, 13, 0, 0, 0, 11, 68, 32, 83, 137, 56, 21, 102, 114, 0, 10, 7, 196, 104, 245, 133, 72, 8, 0, 6, 195, 32, 16, 82, 72, 0, 0, 19, 71, 64, 148, 143, 84, 85, 20, 20, 48, 37, 16, 40, 85, 6, 111, 47, 13, 0, 10, 199, 21, 53, 1, 24, 85, 20, 20, 67, 0, 7, 196, 72, 17, 5, 72, 20, 7, 196, 60, 97, 133, 72, 20, 13, 4, 95, 4, 16, 20, 10, 49, 6, 113, 65, 115, 0, 0, 0, 26, 74, 84, 197, 18, 5, 98, 79, 48, 85, 20, 20, 110, 55, 47, 34, 115, 84, 37, 122, 55, 6, 111, 47, 13, 0, 0, 0, 12, 68, 8, 83, 7, 4, 71, 111, 55, 100, 115, 0, 7, 196, 76, 18, 133, 80, 66, 0, 0, 0, 0, 7, 196, 45, 82, 197, 48, 20, 7, 196, 44, 17, 5, 80, 66, 7, 196, 12, 17, 5, 80, 66, 8, 67, 80, 147, 69, 21, 0, 10, 9, 68, 13, 32, 83, 32, 21, 0, 10, 8, 196, 56, 17, 1, 80, 74, 8, 6, 195, 88, 211, 65, 17, 0, 0, 22, 66, 4, 192, 116, 55, 9, 49, 6, 116, 57, 72, 116, 0, 44, 81, 113, 97, 101, 100, 97, 32, 9, 198, 53, 50, 210, 4, 19, 64, 65, 0, 0, 12, 68, 92, 19, 133, 56, 85, 115, 50, 13, 50, 0, 13, 4, 95, 20, 12, 4, 47, 6, 108, 55, 72, 13, 0, 0, 13, 69, 52, 241, 83, 20, 192, 65, 40, 88, 13, 55, 0, 8, 197, 104, 16, 130, 20, 192, 20, 8, 197, 81, 83, 142, 20, 192, 20, 8, 197, 64, 85, 90, 20, 192, 20, 8, 197, 28, 146, 154, 20, 192, 20, 8, 197, 17, 82, 86, 20, 192, 20, 8, 197, 8, 240, 130, 20, 192, 20, 8, 197, 8, 16, 130, 20, 192, 20, 8, 197, 52, 244, 154, 20, 192, 20, 8, 197, 37, 48, 66, 20, 192, 67, 0, 9, 198, 44, 192, 85, 80, 84, 128, 20, 0, 10, 198, 48, 147, 143, 48, 85, 77, 20, 66, 0, 0, 8, 197, 105, 112, 86, 20, 192, 20, 8, 197, 44, 244, 146, 20, 192, 20, 8, 197, 8, 244, 146, 20, 192, 20, 8, 197, 8, 20, 146, 20, 192, 20, 8, 197, 49, 82, 70, 20, 192, 20, 8, 197, 44, 84, 150, 20, 192, 20, 8, 197, 44, 83, 142, 20, 192, 20, 0, 9, 198, 81, 34, 65, 56, 113, 76, 20, 0, 0, 11, 200, 92, 19, 140, 84, 145, 5, 56, 64, 66, 0, 14, 69, 64, 240, 200, 21, 64, 48, 113, 91, 6, 111, 47, 0, 10, 69, 64, 192, 89, 21, 32, 21, 0, 10, 0, 0, 0, 7, 196, 76, 147, 132, 76, 8, 0, 15, 69, 72, 81, 204, 21, 64, 34, 119, 100, 55, 6, 111, 47, 0, 8, 197, 92, 16, 73, 21, 32, 20, 8, 197, 48, 19, 77, 21, 32, 20, 0, 0, 0, 7, 196, 45, 82, 69, 72, 20, 0, 0, 11, 70, 4, 225, 18, 60, 145, 0, 21, 0, 10, 0, 18, 71, 21, 66, 81, 84, 85, 20, 20, 119, 47, 37, 49, 6, 111, 47, 13, 0, 0, 22, 72, 52, 147, 137, 77, 65, 82, 36, 80, 65, 37, 50, 108, 89, 47, 6, 108, 12, 34, 37, 0, 9, 198, 9, 37, 83, 76, 83, 0, 20, 9, 198, 45, 112, 75, 44, 83, 0, 20, 9, 198, 29, 34, 69, 104, 83, 0, 20, 0, 8, 197, 52, 22, 9, 52, 16, 65, 0, 10, 66, 21, 80, 119, 10, 109, 12, 0, 17, 0, 0, 9, 198, 77, 66, 69, 24, 83, 0, 20, 9, 198, 45, 34, 69, 8, 83, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 68, 56, 16, 137, 40, 50, 35, 71, 6, 123, 0, 0, 8, 197, 44, 227, 203, 20, 192, 20, 8, 197, 29, 37, 87, 20, 192, 20, 8, 197, 32, 80, 130, 20, 224, 72, 0, 9, 198, 88, 195, 212, 80, 84, 128, 20, 9, 198, 76, 227, 212, 80, 84, 128, 20, 9, 198, 76, 177, 76, 80, 84, 128, 20, 9, 198, 76, 50, 5, 52, 84, 128, 20, 9, 198, 24, 195, 212, 80, 84, 128, 20, 9, 198, 24, 195, 196, 16, 84, 128, 20, 9, 198, 9, 35, 197, 16, 84, 128, 20, 0, 0, 11, 68, 4, 195, 5, 76, 116, 55, 13, 89, 0, 13, 68, 4, 193, 21, 76, 116, 55, 72, 6, 110, 89, 0, 0, 8, 197, 44, 20, 19, 20, 192, 20, 8, 197, 33, 84, 211, 20, 192, 20, 8, 197, 45, 83, 142, 20, 224, 72, 0, 9, 198, 60, 181, 15, 8, 84, 128, 66, 9, 198, 77, 66, 74, 25, 49, 76, 20, 9, 198, 88, 194, 69, 28, 84, 128, 20, 9, 198, 77, 2, 74, 44, 84, 128, 20, 9, 198, 76, 195, 197, 8, 84, 128, 20, 9, 198, 52, 243, 147, 80, 84, 128, 20, 9, 198, 52, 81, 82, 16, 84, 128, 20, 9, 198, 52, 80, 78, 16, 84, 128, 20, 9, 198, 44, 226, 75, 44, 84, 128, 20, 9, 198, 24, 194, 75, 44, 84, 128, 20, 9, 198, 8, 194, 75, 44, 84, 128, 20, 9, 198, 8, 81, 78, 16, 84, 128, 20, 0, 0, 0, 8, 197, 76, 197, 73, 21, 32, 20, 8, 197, 52, 146, 141, 21, 32, 20, 8, 197, 44, 241, 84, 21, 32, 20, 0, 0, 0, 0, 0, 11, 70, 72, 84, 197, 5, 32, 200, 21, 0, 10, 0, 0, 7, 196, 92, 147, 4, 20, 72, 0, 8, 197, 61, 3, 1, 28, 80, 20, 6, 195, 16, 149, 0, 72, 0, 9, 198, 17, 112, 82, 72, 83, 0, 20, 11, 70, 52, 81, 9, 12, 19, 0, 21, 0, 10, 0, 18, 71, 76, 245, 66, 72, 85, 20, 20, 89, 40, 71, 34, 6, 111, 47, 13, 0, 10, 199, 52, 18, 143, 72, 85, 20, 20, 67, 16, 71, 12, 245, 67, 32, 85, 20, 20, 49, 40, 91, 6, 111, 47, 0, 9, 67, 32, 146, 128, 107, 2, 123, 0, 0, 9, 198, 76, 50, 1, 88, 245, 0, 66, 16, 70, 12, 245, 80, 48, 85, 0, 49, 40, 48, 55, 6, 111, 47, 0, 16, 70, 52, 19, 131, 32, 85, 0, 65, 116, 50, 91, 6, 111, 47, 0, 15, 70, 13, 35, 195, 32, 85, 0, 49, 34, 113, 91, 6, 111, 0, 0, 0, 9, 198, 77, 68, 149, 36, 177, 76, 20, 0, 0, 0, 0, 0, 11, 199, 64, 85, 18, 60, 193, 85, 52, 20, 66, 7, 195, 8, 83, 128, 72, 9, 0, 0, 0, 0, 0, 9, 198, 8, 83, 5, 52, 209, 82, 20, 0, 8, 197, 56, 21, 143, 20, 192, 66, 8, 197, 80, 147, 135, 20, 192, 20, 8, 197, 52, 84, 135, 20, 192, 20, 8, 197, 44, 243, 139, 20, 192, 20, 8, 197, 28, 244, 135, 20, 192, 20, 8, 197, 52, 242, 203, 20, 192, 20, 11, 70, 76, 241, 148, 92, 20, 133, 21, 0, 10, 0, 9, 198, 105, 112, 66, 8, 84, 128, 20, 9, 198, 77, 5, 84, 80, 84, 128, 20, 9, 198, 77, 1, 84, 80, 84, 128, 20, 9, 198, 44, 82, 76, 16, 84, 128, 20, 0, 12, 201, 92, 19, 148, 72, 245, 87, 20, 225, 0, 66, 0, 0, 13, 69, 52, 148, 211, 20, 224, 65, 108, 89, 13, 50, 0, 8, 197, 92, 146, 203, 20, 192, 20, 8, 197, 80, 242, 203, 20, 192, 20, 13, 69, 80, 16, 203, 20, 192, 47, 111, 49, 13, 55, 0, 8, 197, 16, 145, 199, 20, 192, 20, 8, 197, 44, 225, 75, 20, 192, 20, 0, 9, 198, 105, 112, 75, 44, 84, 128, 20, 9, 198, 49, 82, 83, 80, 84, 128, 20, 9, 198, 32, 241, 78, 16, 84, 128, 20, 9, 198, 24, 192, 75, 44, 84, 128, 20, 9, 198, 17, 82, 83, 80, 84, 128, 20, 9, 198, 12, 245, 78, 80, 84, 128, 20, 0, 7, 195, 8, 83, 148, 72, 9, 0, 0, 0, 0, 10, 199, 92, 146, 201, 64, 81, 9, 4, 67, 0, 0, 9, 198, 104, 241, 15, 20, 225, 5, 66, 0, 7, 66, 28, 80, 81, 13, 0, 0, 0, 0, 16, 69, 16, 19, 137, 12, 16, 72, 35, 50, 6, 37, 47, 89, 35, 0, 0, 9, 198, 76, 224, 66, 8, 83, 0, 20, 9, 198, 76, 163, 197, 52, 83, 0, 20, 9, 198, 44, 224, 66, 8, 83, 0, 20, 9, 198, 29, 32, 66, 8, 83, 0, 20, 9, 198, 28, 243, 195, 32, 83, 0, 20, 9, 198, 17, 33, 85, 80, 83, 0, 20, 0, 0, 12, 68, 8, 83, 137, 28, 71, 119, 50, 13, 100, 0, 0, 0, 9, 198, 77, 65, 67, 32, 83, 0, 20, 9, 198, 44, 226, 66, 8, 83, 0, 20, 9, 198, 25, 35, 205, 52, 83, 0, 20, 9, 198, 76, 50, 5, 16, 83, 0, 20, 0, 0, 7, 196, 56, 243, 133, 80, 66, 10, 198, 28, 85, 197, 21, 53, 0, 72, 9, 0, 0, 16, 70, 76, 147, 8, 61, 81, 84, 89, 37, 55, 40, 6, 111, 47, 0, 0, 0, 7, 196, 64, 19, 5, 80, 66, 0, 15, 69, 16, 149, 133, 73, 48, 72, 37, 84, 6, 111, 34, 89, 0, 0, 9, 198, 44, 84, 147, 80, 83, 128, 20, 0, 10, 199, 76, 50, 14, 4, 32, 133, 48, 20, 0, 0, 14, 69, 8, 83, 129, 72, 64, 71, 13, 50, 116, 34, 47, 0, 8, 197, 32, 241, 80, 20, 192, 20, 8, 197, 8, 82, 84, 20, 192, 20, 14, 69, 9, 33, 84, 20, 192, 71, 34, 13, 47, 111, 55, 0, 0, 9, 198, 76, 50, 21, 36, 97, 76, 20, 0, 0, 15, 70, 48, 21, 82, 20, 229, 0, 55, 122, 34, 6, 116, 67, 0, 7, 196, 44, 84, 5, 72, 20, 13, 3, 95, 49, 15, 6, 108, 12, 34, 89, 47, 13, 0, 0, 8, 197, 80, 148, 16, 20, 192, 20, 8, 197, 80, 83, 80, 20, 192, 20, 8, 197, 72, 147, 80, 20, 192, 20, 8, 197, 48, 148, 208, 20, 192, 20, 8, 197, 32, 243, 80, 20, 192, 20, 8, 197, 24, 145, 68, 20, 192, 20, 8, 197, 76, 147, 80, 20, 192, 20, 0, 17, 70, 76, 52, 129, 8, 33, 76, 89, 49, 34, 111, 71, 13, 55, 0, 20, 6, 195, 48, 17, 197, 20, 6, 195, 57, 97, 1, 17, 0, 14, 139, 9, 14, 7, 18, 5, 4, 9, 195, 171, 14, 20, 68, 16, 3, 226, 130, 172, 6, 121, 16, 122, 47, 4, 119, 49, 13, 50, 0, 0, 0, 9, 198, 16, 148, 203, 21, 69, 5, 66, 9, 198, 12, 20, 211, 21, 69, 5, 66, 8, 197, 8, 147, 10, 21, 64, 66, 8, 197, 105, 82, 86, 21, 32, 20, 8, 197, 49, 80, 130, 21, 32, 20, 8, 197, 48, 80, 130, 21, 32, 20, 8, 197, 33, 82, 86, 21, 32, 20, 8, 197, 8, 144, 130, 21, 32, 20, 11, 70, 32, 243, 69, 64, 17, 197, 21, 0, 10, 0, 12, 67, 64, 17, 197, 21, 0, 10, 81, 117, 112, 32, 14, 67, 64, 17, 197, 21, 0, 10, 81, 100, 111, 119, 110, 32, 0, 19, 71, 13, 84, 133, 81, 64, 71, 20, 49, 109, 34, 13, 47, 6, 115, 90, 13, 0, 0, 12, 3, 95, 50, 15, 47, 85, 6, 119, 72, 13, 0, 0, 0, 0, 0, 13, 68, 8, 83, 137, 56, 71, 119, 50, 6, 37, 50, 0, 9, 198, 12, 16, 137, 56, 85, 0, 67, 0, 10, 67, 32, 85, 0, 107, 13, 47, 0, 9, 0, 9, 198, 45, 35, 197, 104, 83, 0, 20, 9, 198, 44, 194, 78, 28, 83, 0, 20, 0, 16, 70, 24, 16, 197, 8, 243, 203, 83, 111, 37, 89, 71, 40, 49, 0, 10, 199, 76, 84, 20, 20, 208, 133, 72, 66, 0, 9, 198, 44, 16, 137, 56, 85, 0, 67, 7, 196, 92, 20, 5, 56, 20, 12, 3, 95, 51, 15, 72, 6, 111, 34, 72, 13, 0, 9, 4, 95, 15, 18, 4, 72, 13, 0, 0, 8, 197, 4, 113, 78, 16, 16, 66, 8, 197, 36, 230, 129, 28, 80, 20, 0, 9, 198, 17, 35, 208, 64, 83, 0, 20, 9, 198, 77, 67, 208, 64, 83, 0, 20, 6, 194, 37, 48, 72, 9, 0, 0, 7, 196, 64, 20, 133, 48, 20, 0, 0, 0, 0, 7, 196, 56, 20, 5, 48, 20, 7, 196, 64, 244, 5, 48, 20, 7, 196, 48, 84, 5, 48, 20, 7, 196, 64, 148, 5, 80, 66, 12, 68, 28, 147, 5, 80, 90, 37, 55, 6, 111, 0, 12, 68, 24, 147, 5, 80, 83, 37, 55, 6, 119, 0, 9, 198, 76, 50, 9, 48, 65, 82, 20, 0, 0, 0, 0, 0, 8, 197, 64, 83, 132, 20, 192, 20, 8, 197, 56, 16, 200, 20, 192, 20, 8, 197, 9, 82, 84, 20, 192, 20, 8, 197, 32, 83, 132, 20, 192, 20, 8, 197, 92, 147, 4, 20, 224, 72, 0, 9, 198, 77, 68, 149, 8, 33, 76, 20, 9, 198, 76, 195, 196, 16, 84, 128, 20, 9, 198, 44, 195, 196, 16, 84, 128, 20, 0, 0, 7, 196, 44, 20, 5, 72, 20, 12, 3, 95, 53, 15, 84, 6, 123, 84, 72, 13, 0, 0, 8, 197, 92, 83, 148, 20, 192, 20, 8, 197, 80, 244, 148, 20, 192, 20, 8, 197, 44, 20, 148, 20, 192, 20, 8, 197, 32, 20, 208, 20, 192, 20, 8, 197, 16, 20, 148, 20, 192, 20, 8, 197, 52, 244, 148, 20, 192, 20, 8, 197, 9, 82, 68, 20, 192, 20, 8, 197, 105, 83, 12, 20, 224, 72, 0, 15, 4, 95, 13, 3, 14, 65, 6, 116, 49, 14, 16, 113, 50, 0, 0, 8, 67, 56, 85, 192, 50, 127, 0, 0, 0, 17, 70, 4, 226, 83, 21, 69, 5, 115, 50, 37, 88, 6, 111, 47, 13, 0, 14, 69, 88, 145, 206, 21, 64, 84, 108, 67, 6, 111, 47, 0, 8, 197, 92, 241, 75, 21, 32, 20, 0, 0, 0, 12, 3, 95, 54, 15, 88, 6, 111, 89, 72, 13, 0, 0, 13, 69, 36, 225, 205, 5, 32, 108, 68, 65, 116, 34, 0, 8, 197, 12, 244, 150, 21, 64, 66, 8, 197, 76, 243, 142, 21, 64, 66, 8, 197, 64, 82, 71, 21, 32, 20, 8, 197, 40, 241, 75, 21, 32, 20, 0, 0, 0, 7, 196, 92, 244, 132, 80, 72, 0, 0, 16, 70, 73, 80, 146, 36, 82, 192, 34, 109, 71, 34, 6, 37, 49, 0, 9, 198, 44, 227, 203, 44, 83, 0, 20, 0, 19, 71, 92, 83, 9, 77, 112, 65, 72, 85, 111, 55, 108, 89, 58, 6, 115, 34, 0, 0, 13, 68, 8, 84, 137, 28, 71, 108, 12, 34, 13, 100, 0, 7, 196, 32, 20, 5, 72, 20, 7, 196, 44, 85, 5, 56, 20, 14, 3, 95, 55, 15, 88, 6, 119, 84, 13, 50, 72, 13, 0, 0, 8, 197, 41, 83, 12, 36, 80, 72, 8, 197, 41, 83, 12, 36, 80, 72, 0, 0, 0, 7, 196, 44, 21, 133, 48, 20, 0, 0, 0, 11, 199, 72, 81, 5, 44, 21, 133, 48, 20, 65, 0, 7, 196, 104, 85, 5, 48, 20, 7, 196, 44, 85, 5, 48, 20, 9, 68, 64, 21, 3, 32, 21, 0, 10, 0, 0, 9, 198, 12, 244, 147, 20, 193, 84, 67, 6, 194, 20, 224, 72, 8, 0, 13, 3, 95, 51, 88, 72, 6, 111, 34, 47, 13, 101, 0, 0, 7, 196, 104, 85, 133, 72, 20, 7, 196, 48, 85, 133, 72, 20, 7, 196, 16, 21, 133, 72, 20, 9, 68, 76, 149, 5, 76, 21, 0, 10, 14, 3, 95, 48, 67, 107, 6, 113, 50, 72, 111, 34, 47, 0, 0, 8, 197, 52, 243, 77, 20, 192, 20, 8, 197, 44, 243, 132, 20, 224, 72, 0, 0, 0, 21, 72, 60, 225, 193, 77, 69, 146, 36, 160, 113, 50, 100, 116, 89, 47, 84, 34, 6, 123, 0, 7, 196, 92, 21, 5, 72, 20, 7, 196, 104, 85, 5, 56, 20, 0, 8, 197, 64, 145, 77, 20, 192, 20, 0, 0, 17, 71, 72, 240, 200, 20, 99, 210, 80, 34, 39, 91, 6, 83, 39, 34, 0, 10, 199, 44, 19, 5, 24, 21, 5, 72, 20, 0, 0, 8, 197, 53, 84, 203, 21, 64, 66, 8, 197, 8, 241, 75, 21, 64, 66, 8, 197, 44, 144, 203, 21, 32, 20, 0, 9, 198, 53, 84, 197, 81, 65, 64, 66, 0, 0, 0, 21, 73, 52, 18, 83, 60, 227, 133, 81, 65, 64, 65, 111, 88, 113, 50, 6, 111, 47, 13, 0, 8, 197, 92, 18, 203, 21, 32, 20, 8, 197, 52, 82, 203, 21, 32, 20, 0, 7, 66, 40, 80, 57, 13, 0, 15, 3, 95, 49, 57, 50, 6, 119, 100, 13, 50, 47, 37, 50, 0, 0, 12, 3, 95, 49, 56, 6, 116, 101, 47, 37, 50, 0, 0, 14, 68, 8, 84, 137, 56, 71, 108, 12, 34, 6, 108, 50, 0, 7, 196, 80, 245, 133, 72, 20, 7, 196, 44, 21, 133, 72, 20, 7, 196, 20, 229, 5, 72, 20, 0, 0, 9, 198, 81, 33, 85, 104, 83, 0, 20, 9, 198, 45, 112, 66, 8, 83, 0, 20, 9, 198, 45, 33, 78, 28, 83, 0, 20, 9, 198, 44, 229, 84, 76, 83, 0, 20, 9, 198, 17, 37, 80, 64, 83, 0, 20, 0, 0, 9, 198, 64, 19, 70, 48, 85, 0, 66, 7, 196, 80, 21, 5, 72, 20, 7, 196, 64, 84, 5, 72, 20, 7, 196, 44, 244, 5, 72, 20, 7, 196, 8, 85, 5, 72, 20, 0, 0, 9, 198, 81, 114, 74, 24, 83, 0, 20, 9, 198, 76, 211, 203, 44, 83, 0, 20, 10, 3, 95, 49, 49, 6, 111, 55, 83, 0, 0, 10, 3, 95, 49, 48, 47, 6, 37, 50, 0, 0, 7, 196, 56, 85, 133, 48, 20, 7, 196, 44, 85, 133, 48, 20, 7, 196, 56, 21, 133, 48, 20, 7, 196, 8, 20, 133, 80, 66, 13, 3, 95, 49, 51, 72, 6, 111, 34, 47, 37, 50, 0, 0, 12, 3, 95, 49, 50, 47, 85, 6, 115, 55, 83, 0, 0, 13, 3, 95, 49, 53, 84, 6, 123, 83, 47, 37, 50, 0, 0, 14, 3, 95, 49, 52, 83, 6, 108, 12, 34, 47, 37, 50, 0, 0, 12, 68, 76, 84, 137, 20, 89, 108, 12, 34, 37, 0, 7, 196, 80, 149, 5, 48, 20, 7, 196, 56, 85, 5, 48, 20, 7, 196, 52, 85, 5, 48, 20, 7, 196, 52, 245, 5, 80, 66, 7, 196, 104, 241, 1, 80, 66, 12, 3, 95, 52, 15, 84, 6, 37, 34, 72, 13, 0, 15, 3, 95, 49, 55, 88, 6, 119, 84, 13, 50, 47, 37, 50, 0, 0, 13, 3, 95, 49, 54, 88, 6, 111, 89, 47, 37, 50, 0, 0, 0, 10, 199, 64, 19, 148, 60, 97, 133, 48, 20, 15, 3, 95, 55, 88, 88, 6, 119, 84, 13, 50, 47, 13, 101, 0, 0, 13, 68, 12, 245, 133, 72, 49, 110, 84, 13, 34, 0, 20, 8, 196, 92, 20, 133, 56, 72, 9, 0, 0, 0, 0, 7, 196, 8, 245, 5, 72, 20, 0, 8, 197, 104, 245, 133, 20, 192, 66, 8, 197, 104, 241, 207, 20, 64, 66, 0, 0, 0, 0, 0, 16, 70, 88, 81, 5, 81, 65, 64, 84, 13, 72, 6, 111, 47, 13, 0, 11, 70, 92, 80, 147, 37, 65, 64, 21, 0, 10, 0, 0, 0, 8, 197, 92, 148, 16, 21, 32, 20, 8, 197, 65, 84, 144, 21, 32, 20, 8, 197, 52, 244, 16, 21, 32, 20, 0, 0, 0, 13, 68, 60, 213, 133, 72, 122, 65, 84, 6, 111, 34, 0, 9, 198, 44, 243, 80, 48, 245, 0, 66, 0, 9, 198, 76, 83, 4, 21, 34, 69, 65, 15, 70, 72, 85, 129, 56, 50, 5, 34, 13, 84, 117, 50, 91, 0, 18, 70, 53, 148, 212, 21, 34, 69, 65, 108, 89, 47, 6, 108, 12, 34, 37, 0, 9, 198, 52, 148, 203, 60, 244, 0, 65, 18, 70, 33, 148, 212, 21, 34, 69, 107, 108, 89, 47, 108, 12, 34, 6, 37, 0, 0, 9, 198, 76, 50, 15, 80, 83, 0, 20, 0, 10, 199, 77, 84, 16, 61, 37, 5, 72, 20, 0, 9, 198, 64, 244, 148, 72, 85, 0, 66, 7, 196, 36, 165, 133, 72, 20, 0, 16, 70, 64, 148, 212, 4, 50, 5, 48, 37, 89, 47, 6, 116, 91, 0, 0, 9, 198, 45, 83, 147, 80, 83, 0, 20, 9, 198, 44, 20, 9, 81, 65, 76, 20, 0, 10, 69, 48, 20, 20, 61, 0, 21, 0, 10, 14, 3, 95, 50, 88, 47, 85, 6, 108, 50, 47, 13, 101, 0, 0, 7, 196, 32, 85, 133, 48, 20, 12, 68, 28, 85, 133, 48, 100, 119, 84, 13, 55, 0, 0, 9, 198, 12, 243, 148, 72, 243, 5, 66, 0, 0, 0, 7, 196, 72, 21, 5, 48, 20, 7, 196, 60, 53, 5, 80, 66, 9, 198, 76, 50, 21, 81, 65, 82, 20, 9, 198, 76, 50, 9, 81, 65, 82, 20, 13, 3, 95, 56, 15, 6, 116, 101, 47, 89, 47, 13, 0, 0, 0, 0, 0, 7, 196, 48, 22, 133, 72, 20, 9, 198, 28, 194, 78, 77, 65, 82, 20, 0, 0, 0, 16, 67, 9, 96, 128, 71, 123, 84, 6, 122, 34, 71, 119, 55, 47, 0, 0, 13, 3, 95, 63, 63, 89, 6, 37, 65, 71, 122, 55, 0, 0, 8, 197, 44, 145, 90, 20, 192, 20, 0, 0, 8, 67, 40, 241, 64, 75, 122, 0, 6, 195, 104, 245, 64, 72, 14, 3, 95, 52, 88, 83, 6, 108, 12, 34, 47, 13, 101, 0, 0, 0, 15, 69, 76, 177, 76, 21, 64, 89, 49, 13, 55, 6, 111, 47, 0, 8, 197, 88, 244, 132, 21, 32, 20, 8, 197, 44, 147, 132, 21, 32, 20, 8, 197, 8, 192, 68, 21, 32, 20, 0, 0, 0, 0, 8, 197, 4, 213, 76, 21, 64, 67, 8, 197, 44, 192, 84, 21, 32, 20, 0, 7, 194, 56, 16, 9, 76, 8, 8, 66, 36, 176, 2, 108, 49, 0, 0, 7, 195, 44, 210, 64, 17, 42, 13, 3, 95, 53, 88, 84, 6, 123, 83, 47, 13, 101, 0, 0, 7, 196, 104, 241, 18, 4, 66, 0, 0, 9, 198, 44, 225, 85, 44, 83, 0, 20, 9, 198, 52, 148, 129, 8, 83, 0, 67, 0, 17, 71, 12, 245, 82, 28, 85, 20, 20, 49, 40, 34, 90, 6, 111, 47, 0, 0, 9, 198, 52, 147, 129, 72, 85, 0, 67, 17, 70, 44, 194, 78, 44, 85, 0, 49, 55, 108, 68, 49, 6, 111, 47, 0, 11, 70, 21, 132, 12, 60, 149, 0, 21, 0, 10, 0, 7, 195, 52, 16, 82, 72, 8, 0, 9, 198, 105, 114, 69, 8, 83, 0, 20, 9, 198, 65, 34, 69, 28, 83, 0, 20, 0, 13, 3, 95, 54, 88, 88, 6, 111, 89, 47, 13, 101, 0, 0, 7, 196, 88, 86, 133, 48, 20, 7, 196, 24, 86, 133, 48, 20, 7, 196, 52, 22, 133, 48, 20, 7, 196, 56, 246, 133, 48, 20, 0, 6, 195, 20, 145, 82, 20, 0, 0, 11, 70, 92, 80, 147, 37, 65, 83, 21, 0, 10, 0, 7, 196, 36, 166, 133, 48, 20, 9, 198, 76, 50, 5, 81, 65, 82, 20, 0, 0, 10, 67, 40, 241, 89, 75, 122, 58, 37, 0, 0, 0, 0, 8, 197, 72, 144, 130, 20, 192, 20, 8, 197, 56, 85, 90, 20, 192, 20, 8, 197, 17, 80, 130, 20, 192, 20, 8, 197, 105, 82, 86, 20, 192, 20, 0, 9, 198, 80, 84, 212, 36, 177, 76, 20, 9, 198, 81, 33, 73, 80, 84, 128, 20, 0, 0, 0, 8, 197, 92, 84, 150, 20, 192, 20, 8, 197, 45, 113, 90, 20, 192, 20, 8, 197, 76, 224, 86, 20, 192, 20, 8, 197, 32, 244, 154, 20, 192, 20, 9, 198, 41, 80, 137, 48, 85, 77, 20, 0, 10, 66, 57, 32, 50, 110, 65, 13, 34, 0, 0, 10, 199, 92, 81, 215, 36, 166, 133, 72, 20, 13, 3, 95, 56, 88, 47, 6, 116, 101, 47, 13, 101, 0, 0, 0, 0, 0, 7, 195, 104, 240, 76, 66, 9, 0, 0, 8, 197, 44, 20, 144, 21, 64, 66, 8, 197, 80, 147, 77, 21, 32, 20, 8, 197, 48, 83, 77, 21, 32, 20, 0, 16, 70, 52, 21, 5, 72, 145, 64, 65, 115, 47, 6, 119, 34, 37, 0, 10, 198, 28, 84, 212, 4, 113, 64, 20, 66, 7, 66, 52, 80, 65, 13, 0, 0, 15, 3, 95, 57, 88, 50, 6, 119, 81, 13, 50, 47, 13, 101, 0, 0, 16, 70, 12, 148, 131, 84, 149, 0, 89, 108, 34, 49, 40, 6, 37, 0, 0, 14, 69, 8, 83, 137, 28, 80, 71, 119, 50, 13, 100, 13, 0, 8, 195, 52, 85, 0, 9, 76, 28, 0, 14, 70, 76, 133, 84, 80, 83, 0, 91, 110, 47, 13, 55, 0, 16, 70, 12, 83, 129, 44, 83, 0, 89, 13, 50, 115, 49, 13, 55, 0, 0, 10, 199, 12, 128, 82, 48, 245, 20, 20, 66, 10, 199, 9, 83, 12, 16, 246, 133, 72, 20, 0, 7, 196, 36, 166, 133, 72, 20, 0, 0, 9, 198, 77, 68, 133, 56, 113, 76, 20, 12, 3, 95, 63, 65, 55, 6, 111, 47, 13, 34, 0, 0, 0, 7, 196, 8, 22, 133, 48, 20, 13, 72, 20, 229, 5, 73, 4, 137, 76, 80, 21, 0, 10, 0, 6, 195, 84, 145, 82, 20, 0, 0, 0, 0, 0, 0, 7, 194, 36, 224, 9, 76, 28, 0, 0, 0, 16, 70, 36, 225, 197, 8, 244, 135, 108, 68, 119, 71, 113, 34, 101, 0, 0, 9, 198, 64, 19, 148, 76, 84, 128, 20, 9, 198, 44, 194, 69, 16, 84, 128, 20, 9, 198, 24, 195, 206, 44, 84, 128, 20, 0, 14, 4, 95, 15, 7, 15, 6, 122, 101, 122, 50, 111, 49, 0, 0, 0, 8, 197, 36, 164, 211, 20, 192, 20, 8, 197, 64, 241, 75, 20, 192, 20, 8, 197, 40, 241, 75, 20, 192, 20, 0, 9, 198, 105, 112, 78, 28, 84, 128, 20, 9, 198, 72, 243, 211, 80, 84, 128, 20, 9, 198, 28, 194, 66, 8, 84, 128, 20, 9, 198, 8, 243, 19, 80, 84, 128, 20, 0, 0, 0, 9, 198, 52, 148, 194, 73, 82, 75, 65, 8, 197, 57, 83, 77, 21, 32, 20, 0, 0, 10, 199, 36, 225, 197, 88, 243, 7, 20, 67, 0, 0, 0, 0, 29, 75, 20, 193, 147, 80, 81, 5, 57, 67, 195, 33, 64, 4, 111, 55, 83, 6, 89, 47, 119, 72, 13, 50, 47, 39, 100, 47, 0, 0, 12, 201, 60, 225, 197, 48, 243, 198, 48, 146, 139, 67, 9, 198, 81, 35, 197, 80, 83, 0, 20, 9, 198, 77, 112, 70, 24, 83, 0, 20, 9, 198, 65, 37, 84, 80, 83, 0, 20, 20, 72, 80, 245, 82, 56, 148, 85, 21, 64, 47, 40, 34, 50, 37, 49, 6, 111, 47, 0, 0, 0, 0, 10, 199, 52, 241, 9, 56, 85, 20, 20, 67, 0, 9, 198, 33, 82, 67, 32, 83, 0, 20, 9, 198, 29, 82, 67, 32, 83, 0, 20, 9, 198, 17, 33, 77, 52, 83, 0, 20, 9, 198, 77, 65, 78, 28, 83, 0, 20, 20, 72, 12, 128, 77, 9, 33, 84, 80, 80, 91, 35, 65, 71, 34, 6, 111, 47, 13, 0, 0, 8, 197, 52, 148, 211, 36, 80, 65, 0, 14, 139, 1, 12, 5, 24, 1, 14, 4, 18, 9, 195, 171, 67, 0, 23, 67, 88, 243, 132, 84, 113, 50, 10, 47, 116, 10, 47, 13, 0, 82, 100, 97, 116, 32, 100, 101, 32, 8, 195, 4, 19, 128, 9, 76, 28, 0, 7, 196, 72, 246, 133, 80, 66, 14, 4, 95, 48, 77, 52, 71, 6, 37, 55, 57, 40, 50, 0, 0, 6, 195, 52, 146, 142, 72, 0, 9, 198, 48, 243, 195, 32, 83, 128, 20, 6, 195, 104, 246, 143, 66, 6, 195, 40, 245, 87, 72, 14, 4, 95, 48, 77, 50, 65, 6, 37, 55, 57, 40, 50, 0, 0, 10, 199, 81, 32, 86, 21, 53, 9, 20, 67, 15, 4, 95, 48, 77, 51, 65, 6, 37, 55, 57, 116, 34, 47, 0, 0, 0, 14, 4, 95, 48, 77, 49, 72, 6, 124, 88, 111, 50, 47, 0, 0, 14, 4, 95, 2, 18, 22, 71, 14, 16, 6, 119, 84, 13, 0, 0, 19, 71, 12, 16, 146, 36, 243, 5, 80, 49, 115, 71, 34, 37, 39, 55, 6, 111, 0, 0, 12, 68, 8, 85, 20, 100, 71, 111, 12, 47, 37, 0, 24, 73, 36, 212, 18, 20, 115, 133, 72, 147, 135, 108, 65, 48, 34, 4, 111, 100, 50, 6, 119, 108, 68, 0, 0, 8, 197, 56, 20, 193, 4, 192, 66, 8, 197, 76, 145, 80, 20, 192, 20, 8, 197, 72, 147, 139, 20, 192, 20, 8, 197, 32, 18, 211, 20, 192, 20, 8, 197, 12, 148, 139, 20, 192, 20, 0, 9, 198, 76, 160, 67, 32, 84, 128, 20, 9, 198, 44, 226, 83, 64, 84, 128, 20, 9, 198, 44, 225, 85, 80, 84, 128, 20, 9, 198, 44, 193, 85, 80, 84, 128, 20, 9, 198, 8, 197, 66, 8, 84, 128, 20, 11, 70, 92, 81, 75, 20, 225, 0, 21, 0, 10, 0, 6, 195, 92, 84, 132, 72, 0, 20, 72, 12, 128, 77, 64, 145, 206, 60, 224, 91, 116, 65, 48, 37, 57, 6, 113, 50, 0, 0, 8, 197, 92, 18, 203, 20, 192, 20, 8, 197, 80, 147, 139, 20, 192, 20, 8, 197, 76, 146, 203, 20, 192, 20, 8, 197, 24, 243, 139, 20, 192, 20, 8, 197, 16, 148, 211, 20, 192, 20, 8, 197, 88, 83, 139, 20, 192, 20, 0, 9, 198, 44, 226, 83, 80, 84, 128, 20, 9, 198, 12, 197, 83, 80, 84, 128, 20, 0, 0, 0, 8, 197, 104, 147, 22, 21, 32, 20, 8, 197, 8, 82, 82, 21, 32, 20, 0, 0, 0, 7, 196, 44, 20, 15, 80, 66, 0, 15, 69, 52, 83, 149, 21, 64, 65, 119, 50, 109, 6, 111, 47, 0, 8, 197, 76, 243, 66, 21, 32, 20, 0, 0, 19, 71, 25, 32, 78, 12, 130, 83, 20, 83, 34, 116, 6, 91, 37, 12, 88, 13, 0, 0, 9, 198, 77, 64, 70, 24, 83, 0, 20, 9, 198, 76, 193, 85, 80, 83, 0, 20, 9, 198, 45, 32, 66, 8, 83, 0, 20, 9, 198, 25, 37, 84, 76, 83, 0, 20, 0, 16, 205, 64, 20, 148, 36, 165, 143, 61, 38, 137, 81, 65, 82, 76, 66, 10, 69, 16, 83, 5, 80, 80, 21, 0, 10, 0, 9, 198, 44, 245, 5, 48, 85, 0, 67, 0, 0, 9, 198, 45, 34, 66, 8, 83, 0, 20, 9, 198, 9, 33, 73, 16, 83, 0, 20, 0, 0, 0, 0, 12, 68, 52, 85, 18, 60, 65, 119, 47, 34, 122, 0, 7, 196, 28, 22, 133, 80, 66, 7, 196, 41, 80, 133, 48, 20, 0, 0, 0, 18, 70, 24, 80, 146, 84, 20, 137, 83, 119, 71, 34, 109, 6, 115, 34, 37, 0, 19, 71, 12, 20, 212, 4, 115, 133, 80, 49, 116, 89, 47, 116, 67, 6, 111, 47, 0, 0, 0, 0, 9, 198, 76, 50, 5, 64, 83, 128, 20, 6, 194, 60, 96, 72, 8, 6, 194, 60, 96, 72, 8, 0, 0, 7, 195, 44, 227, 73, 17, 42, 0, 8, 197, 81, 34, 80, 20, 192, 20, 0, 9, 198, 48, 21, 133, 56, 65, 76, 20, 9, 198, 44, 22, 149, 36, 97, 76, 20, 0, 0, 0, 14, 69, 52, 148, 208, 20, 192, 65, 108, 89, 48, 13, 55, 0, 8, 197, 77, 64, 80, 20, 192, 20, 8, 197, 76, 20, 16, 20, 192, 20, 8, 197, 56, 84, 212, 20, 192, 20, 8, 197, 52, 148, 208, 20, 192, 20, 8, 197, 44, 244, 16, 20, 192, 20, 8, 197, 33, 84, 16, 20, 192, 20, 8, 197, 64, 84, 16, 20, 192, 20, 8, 197, 44, 84, 16, 20, 192, 20, 9, 3, 4, 39, 18, 72, 13, 34, 0, 0, 16, 70, 12, 243, 148, 61, 84, 128, 49, 122, 50, 47, 6, 40, 34, 0, 9, 198, 77, 68, 137, 8, 33, 76, 20, 0, 0, 0, 8, 197, 73, 80, 130, 21, 32, 20, 8, 197, 48, 240, 130, 21, 32, 20, 8, 197, 48, 16, 130, 21, 32, 20, 8, 197, 28, 144, 130, 21, 32, 20, 8, 197, 16, 240, 130, 21, 32, 20, 8, 197, 16, 16, 130, 21, 32, 20, 8, 195, 88, 243, 210, 9, 76, 8, 0, 0, 6, 195, 52, 17, 192, 72, 0, 0, 8, 197, 44, 192, 86, 21, 32, 20, 9, 3, 195, 169, 14, 111, 50, 0, 8, 0, 0, 17, 70, 61, 1, 82, 21, 69, 5, 122, 48, 13, 34, 6, 111, 47, 13, 0, 9, 198, 9, 37, 78, 21, 69, 5, 66, 18, 70, 4, 212, 5, 72, 17, 197, 116, 65, 48, 13, 34, 6, 115, 90, 13, 0, 0, 0, 0, 12, 201, 32, 81, 5, 57, 65, 78, 16, 17, 197, 20, 0, 9, 198, 56, 17, 18, 84, 178, 197, 66, 0, 9, 198, 36, 225, 197, 88, 19, 0, 67, 9, 198, 29, 35, 206, 16, 83, 0, 20, 0, 0, 0, 6, 195, 44, 211, 192, 17, 0, 0, 0, 20, 4, 95, 3, 9, 18, 89, 6, 108, 34, 49, 113, 50, 83, 55, 119, 49, 89, 13, 0, 0, 0, 0, 0, 0, 0, 7, 196, 65, 80, 133, 72, 20, 0, 8, 197, 76, 147, 148, 20, 192, 20, 8, 197, 28, 244, 132, 20, 192, 20, 0, 9, 198, 76, 50, 1, 80, 84, 128, 20, 0, 10, 199, 56, 21, 149, 48, 32, 65, 72, 66, 0, 15, 67, 52, 148, 197, 65, 37, 88, 117, 0, 44, 81, 101, 110, 32, 0, 8, 197, 92, 244, 148, 20, 192, 20, 8, 197, 92, 19, 132, 20, 192, 20, 8, 197, 52, 20, 148, 20, 192, 20, 8, 197, 28, 148, 208, 20, 192, 20, 8, 197, 105, 112, 84, 20, 192, 20, 8, 197, 16, 244, 144, 20, 192, 20, 8, 197, 16, 148, 212, 20, 192, 20, 0, 0, 6, 195, 45, 83, 148, 72, 14, 4, 95, 19, 20, 11, 89, 47, 14, 16, 6, 119, 48, 0, 0, 0, 13, 4, 95, 1, 3, 21, 6, 115, 37, 101, 4, 109, 0, 0, 9, 198, 104, 241, 1, 56, 145, 192, 66, 0, 16, 70, 72, 245, 76, 21, 69, 5, 34, 40, 55, 6, 111, 47, 13, 0, 17, 70, 17, 32, 73, 56, 17, 197, 72, 34, 111, 50, 6, 115, 90, 13, 0, 0, 0, 8, 197, 88, 243, 11, 21, 32, 20, 8, 197, 64, 145, 75, 21, 32, 20, 0, 0, 0, 9, 198, 76, 225, 85, 88, 83, 0, 20, 9, 198, 44, 194, 80, 64, 83, 0, 20, 9, 198, 29, 33, 78, 16, 83, 0, 20, 7, 196, 104, 81, 197, 56, 20, 7, 196, 72, 81, 197, 56, 20, 7, 196, 40, 81, 197, 56, 20, 7, 196, 52, 241, 197, 56, 72, 0, 9, 198, 88, 243, 12, 20, 66, 71, 66, 9, 198, 52, 148, 211, 80, 20, 0, 65, 0, 15, 70, 56, 85, 2, 60, 242, 192, 50, 111, 47, 71, 40, 49, 0, 0, 14, 4, 95, 18, 14, 7, 49, 6, 122, 16, 122, 50, 115, 0, 0, 7, 196, 61, 32, 133, 72, 20, 0, 0, 9, 198, 52, 148, 207, 60, 116, 212, 65, 0, 0, 11, 200, 36, 225, 143, 72, 208, 84, 36, 80, 67, 7, 196, 104, 81, 197, 48, 20, 7, 196, 72, 81, 197, 48, 20, 7, 196, 24, 16, 197, 80, 66, 9, 198, 88, 192, 65, 56, 65, 82, 20, 0, 0, 0, 0, 7, 196, 20, 225, 197, 48, 20, 0, 18, 69, 84, 37, 78, 81, 80, 40, 12, 6, 71, 40, 12, 50, 47, 40, 12, 0, 0, 0, 0, 7, 196, 48, 81, 197, 72, 20, 7, 196, 48, 17, 197, 72, 20, 0, 8, 197, 8, 241, 77, 20, 192, 20, 8, 197, 28, 19, 77, 20, 192, 20, 8, 197, 92, 244, 132, 20, 224, 72, 0, 9, 198, 28, 84, 5, 85, 1, 76, 20, 0, 0, 9, 198, 80, 84, 151, 36, 163, 0, 8, 0, 8, 197, 72, 243, 77, 20, 192, 20, 8, 197, 32, 243, 77, 20, 192, 20, 0, 0, 0, 11, 200, 92, 19, 147, 12, 128, 80, 20, 224, 66, 0, 8, 197, 40, 18, 203, 21, 32, 20, 8, 197, 32, 243, 135, 21, 32, 20, 8, 197, 9, 83, 139, 21, 32, 20, 14, 69, 104, 245, 193, 5, 32, 88, 122, 85, 6, 115, 34, 0, 0, 18, 4, 95, 1, 3, 50, 72, 6, 110, 71, 111, 55, 6, 115, 37, 101, 109, 0, 0, 0, 0, 8, 197, 9, 34, 75, 21, 64, 66, 8, 197, 44, 19, 139, 21, 32, 20, 8, 197, 16, 243, 139, 21, 32, 20, 0, 16, 70, 104, 83, 26, 5, 65, 64, 88, 36, 55, 88, 35, 47, 13, 0, 0, 0, 9, 198, 88, 16, 78, 16, 83, 0, 20, 9, 198, 4, 208, 78, 16, 83, 0, 20, 0, 0, 0, 0, 15, 70, 60, 194, 69, 76, 83, 0, 122, 55, 37, 89, 13, 55, 0, 10, 68, 12, 129, 67, 44, 76, 111, 49, 0, 11, 68, 12, 128, 79, 76, 101, 115, 113, 89, 0, 9, 198, 8, 244, 147, 80, 83, 0, 20, 9, 198, 77, 67, 198, 24, 83, 0, 20, 0, 0, 9, 198, 52, 148, 196, 73, 82, 192, 65, 9, 198, 81, 35, 205, 64, 85, 0, 66, 0, 15, 70, 28, 19, 65, 76, 50, 5, 100, 115, 65, 6, 116, 91, 0, 0, 7, 196, 88, 241, 197, 48, 20, 7, 196, 80, 81, 197, 48, 20, 7, 196, 56, 17, 197, 48, 20, 7, 196, 44, 81, 197, 48, 20, 7, 196, 32, 17, 197, 48, 20, 0, 0, 0, 0, 7, 196, 4, 225, 197, 48, 20, 9, 198, 64, 193, 73, 77, 65, 82, 20, 7, 196, 57, 81, 1, 80, 8, 0, 8, 197, 65, 35, 195, 21, 48, 66, 0, 0, 0, 0, 8, 197, 53, 84, 141, 20, 192, 20, 0, 9, 198, 76, 50, 1, 73, 33, 76, 20, 0, 0, 7, 196, 61, 81, 5, 72, 20, 7, 196, 32, 81, 70, 80, 72, 0, 8, 197, 49, 83, 77, 20, 192, 20, 8, 197, 45, 83, 77, 20, 192, 20, 0, 12, 6, 95, 15, 18, 4, 50, 48, 89, 47, 13, 0, 0, 0, 11, 68, 8, 82, 71, 20, 71, 111, 90, 13, 0, 0, 8, 197, 88, 241, 68, 21, 32, 20, 8, 197, 77, 81, 4, 21, 32, 20, 8, 197, 72, 81, 4, 21, 32, 20, 8, 197, 52, 241, 68, 21, 32, 20, 8, 197, 52, 241, 4, 21, 32, 20, 8, 197, 24, 243, 20, 21, 32, 20, 8, 197, 4, 50, 20, 21, 32, 20, 0, 9, 198, 8, 82, 1, 49, 97, 64, 8, 0, 0, 7, 196, 56, 19, 205, 36, 66, 0, 8, 197, 92, 147, 139, 21, 64, 66, 8, 197, 45, 35, 203, 21, 64, 66, 8, 197, 92, 84, 212, 21, 32, 20, 8, 197, 92, 20, 16, 21, 32, 20, 8, 197, 72, 20, 212, 21, 32, 20, 8, 197, 64, 145, 84, 21, 32, 20, 8, 197, 48, 84, 16, 21, 32, 20, 8, 197, 44, 85, 84, 21, 32, 20, 8, 197, 44, 85, 20, 21, 32, 20, 8, 197, 24, 243, 4, 21, 32, 20, 8, 197, 24, 241, 84, 21, 32, 20, 8, 197, 9, 83, 4, 21, 32, 20, 0, 7, 194, 60, 208, 9, 76, 28, 0, 0, 11, 200, 81, 35, 205, 64, 85, 20, 21, 32, 20, 7, 196, 52, 17, 197, 72, 20, 7, 196, 36, 210, 197, 72, 20, 7, 196, 72, 82, 197, 56, 20, 7, 196, 52, 240, 200, 80, 72, 6, 195, 60, 230, 133, 72, 0, 8, 197, 53, 84, 197, 84, 208, 20, 0, 0, 18, 70, 8, 16, 212, 21, 34, 69, 71, 116, 49, 47, 6, 108, 12, 34, 37, 0, 0, 9, 198, 77, 65, 77, 64, 83, 0, 20, 9, 198, 77, 2, 74, 8, 83, 0, 20, 9, 198, 45, 35, 206, 44, 83, 0, 20, 9, 198, 29, 34, 70, 24, 83, 0, 20, 9, 198, 17, 34, 66, 8, 83, 0, 20, 9, 198, 17, 33, 77, 64, 83, 0, 20, 0, 6, 195, 61, 97, 82, 20, 8, 195, 61, 97, 82, 9, 76, 8, 0, 9, 198, 77, 68, 143, 53, 1, 76, 20, 0, 10, 199, 20, 84, 135, 37, 53, 5, 72, 20, 0, 9, 198, 44, 17, 1, 77, 65, 82, 66, 7, 196, 80, 18, 197, 48, 20, 7, 196, 64, 81, 197, 48, 20, 7, 196, 44, 241, 197, 48, 20, 7, 196, 44, 18, 197, 48, 20, 7, 196, 104, 245, 197, 48, 66, 7, 196, 104, 245, 193, 80, 66, 0, 0, 0, 0, 7, 196, 16, 145, 69, 80, 66, 7, 196, 20, 226, 197, 48, 20, 9, 198, 77, 3, 9, 57, 65, 82, 20, 20, 70, 12, 243, 80, 85, 65, 82, 49, 113, 65, 48, 57, 6, 40, 47, 13, 34, 0, 20, 0, 17, 70, 5, 81, 213, 77, 69, 83, 125, 100, 6, 110, 89, 47, 110, 89, 0, 0, 9, 198, 104, 242, 149, 37, 53, 0, 66, 0, 0, 12, 68, 8, 82, 197, 72, 71, 119, 49, 13, 34, 0, 7, 196, 104, 82, 197, 72, 20, 7, 196, 52, 242, 197, 72, 20, 0, 8, 197, 92, 145, 66, 20, 192, 20, 8, 197, 28, 145, 66, 20, 192, 20, 0, 18, 70, 8, 83, 8, 4, 209, 76, 71, 6, 111, 55, 107, 115, 65, 13, 55, 0, 0, 0, 7, 196, 52, 82, 69, 72, 20, 0, 8, 197, 92, 82, 70, 20, 192, 20, 8, 197, 24, 241, 90, 20, 192, 20, 14, 69, 29, 32, 86, 20, 192, 100, 34, 111, 84, 13, 55, 0, 0, 0, 0, 7, 196, 24, 17, 207, 80, 66, 14, 4, 95, 3, 5, 4, 89, 6, 119, 72, 108, 55, 13, 0, 0, 8, 197, 8, 19, 12, 21, 64, 66, 8, 197, 92, 147, 148, 21, 32, 20, 0, 0, 15, 4, 95, 12, 9, 7, 55, 6, 37, 101, 115, 47, 109, 34, 0, 0, 0, 8, 197, 76, 224, 84, 21, 32, 20, 8, 197, 73, 83, 132, 21, 32, 20, 8, 197, 64, 21, 80, 21, 32, 20, 8, 197, 48, 245, 84, 21, 32, 20, 8, 197, 32, 147, 132, 21, 32, 20, 8, 197, 16, 243, 132, 21, 32, 20, 8, 197, 8, 20, 212, 21, 32, 20, 0, 9, 198, 64, 243, 9, 28, 195, 212, 67, 7, 194, 80, 80, 9, 76, 28, 0, 0, 7, 196, 80, 82, 197, 56, 20, 0, 21, 73, 72, 83, 129, 37, 52, 193, 56, 49, 64, 34, 111, 50, 119, 89, 6, 117, 89, 13, 0, 7, 195, 56, 16, 82, 9, 76, 0, 0, 0, 9, 198, 77, 2, 69, 28, 83, 0, 20, 9, 198, 76, 50, 1, 44, 83, 0, 20, 9, 198, 9, 35, 196, 16, 83, 0, 20, 9, 198, 16, 81, 77, 77, 64, 82, 20, 0, 0, 0, 0, 7, 196, 64, 146, 197, 80, 66, 7, 196, 48, 242, 197, 80, 66, 9, 198, 44, 197, 73, 77, 65, 82, 20, 0, 0, 0, 0, 9, 198, 76, 50, 1, 53, 1, 82, 20, 0, 14, 69, 8, 83, 132, 21, 48, 71, 111, 50, 72, 13, 89, 0, 0, 0, 0, 7, 196, 44, 242, 197, 72, 20, 7, 196, 8, 18, 197, 72, 20, 0, 8, 197, 92, 17, 134, 20, 192, 20, 8, 197, 76, 16, 130, 20, 192, 20, 8, 197, 72, 145, 134, 20, 192, 20, 8, 197, 72, 85, 90, 20, 192, 20, 8, 197, 72, 80, 130, 20, 192, 20, 8, 197, 65, 86, 154, 20, 192, 20, 8, 197, 44, 16, 130, 20, 192, 20, 8, 197, 28, 17, 134, 20, 192, 20, 8, 197, 16, 240, 130, 20, 192, 20, 8, 197, 9, 80, 130, 20, 192, 20, 8, 197, 8, 85, 90, 20, 192, 20, 8, 197, 72, 85, 90, 20, 192, 20, 8, 197, 17, 81, 134, 20, 192, 20, 0, 9, 198, 60, 36, 212, 4, 177, 76, 20, 0, 6, 195, 60, 228, 192, 72, 0, 0, 8, 197, 88, 146, 154, 20, 192, 20, 8, 197, 52, 244, 146, 20, 192, 20, 8, 197, 4, 20, 154, 20, 192, 20, 0, 9, 198, 77, 4, 143, 44, 177, 76, 20, 0, 0, 0, 8, 197, 80, 16, 140, 21, 64, 66, 8, 197, 48, 243, 77, 21, 32, 20, 8, 197, 44, 243, 77, 21, 32, 20, 0, 0, 6, 195, 92, 245, 64, 72, 0, 18, 72, 20, 208, 143, 84, 50, 21, 85, 32, 117, 71, 40, 91, 6, 109, 34, 0, 0, 8, 197, 88, 147, 204, 21, 64, 67, 8, 197, 64, 241, 73, 21, 32, 20, 8, 197, 40, 19, 77, 21, 32, 20, 0, 10, 198, 76, 243, 77, 36, 113, 64, 9, 76, 0, 0, 9, 198, 52, 148, 129, 44, 83, 0, 20, 7, 196, 8, 18, 197, 56, 20, 0, 8, 197, 52, 147, 137, 52, 16, 65, 0, 9, 198, 80, 83, 148, 4, 177, 76, 20, 0, 18, 71, 4, 211, 213, 72, 85, 20, 20, 115, 65, 40, 16, 6, 111, 47, 13, 0, 6, 195, 92, 21, 0, 72, 0, 7, 196, 72, 243, 65, 56, 66, 11, 200, 52, 148, 211, 37, 52, 201, 64, 144, 67, 11, 68, 24, 144, 200, 20, 83, 37, 91, 13, 0, 7, 196, 4, 226, 197, 72, 20, 0, 0, 9, 198, 76, 145, 193, 72, 85, 0, 67, 0, 0, 7, 196, 72, 18, 197, 48, 20, 7, 196, 64, 82, 197, 48, 20, 7, 196, 32, 82, 197, 48, 20, 7, 196, 20, 146, 197, 48, 20, 12, 68, 77, 82, 133, 80, 89, 109, 90, 6, 111, 0, 0, 0, 0, 10, 199, 8, 19, 133, 56, 114, 68, 76, 22, 10, 199, 76, 50, 18, 36, 178, 197, 48, 20, 22, 67, 56, 145, 84, 10, 50, 6, 37, 47, 15, 65, 4, 119, 34, 0, 81, 109, 101, 101, 114, 32, 11, 67, 56, 145, 84, 50, 4, 37, 47, 0, 11, 0, 7, 196, 104, 83, 69, 48, 20, 0, 0, 0, 0, 6, 195, 32, 80, 128, 72, 0, 0, 8, 197, 80, 85, 71, 20, 192, 20, 8, 197, 45, 33, 75, 20, 192, 20, 8, 197, 32, 82, 75, 20, 192, 20, 8, 197, 28, 85, 201, 48, 64, 72, 0, 9, 198, 76, 194, 78, 28, 84, 128, 20, 9, 198, 76, 177, 69, 48, 84, 128, 20, 9, 198, 36, 226, 193, 16, 84, 128, 20, 9, 198, 28, 194, 77, 52, 84, 128, 20, 0, 7, 2, 95, 19, 111, 89, 0, 0, 0, 8, 197, 92, 148, 211, 20, 192, 20, 8, 197, 33, 85, 19, 20, 192, 20, 8, 197, 9, 84, 211, 20, 192, 20, 8, 197, 77, 65, 75, 20, 192, 20, 8, 197, 65, 82, 203, 20, 192, 20, 6, 195, 104, 146, 142, 72, 8, 197, 32, 241, 87, 20, 192, 8, 6, 195, 104, 146, 142, 72, 0, 9, 198, 81, 114, 84, 80, 84, 128, 20, 9, 198, 77, 69, 77, 64, 84, 128, 20, 9, 198, 77, 67, 212, 80, 84, 128, 20, 9, 198, 77, 65, 75, 44, 84, 128, 20, 9, 198, 77, 65, 73, 28, 84, 128, 20, 9, 198, 76, 195, 194, 8, 84, 128, 20, 9, 198, 32, 19, 83, 80, 84, 128, 20, 0, 0, 0, 0, 7, 2, 95, 20, 47, 119, 0, 0, 0, 0, 8, 197, 104, 246, 133, 21, 32, 66, 0, 9, 198, 45, 37, 73, 52, 83, 0, 20, 0, 0, 0, 0, 9, 198, 93, 34, 69, 52, 83, 0, 20, 9, 198, 44, 197, 78, 28, 83, 0, 20, 9, 198, 25, 37, 77, 52, 83, 0, 20, 9, 198, 25, 34, 69, 52, 83, 0, 20, 9, 198, 5, 37, 9, 44, 83, 0, 20, 9, 198, 76, 50, 1, 52, 83, 0, 20, 0, 6, 195, 32, 80, 148, 72, 8, 195, 8, 146, 128, 9, 76, 8, 9, 67, 104, 146, 128, 88, 2, 123, 0, 9, 67, 40, 146, 128, 57, 2, 123, 0, 0, 11, 200, 92, 20, 211, 21, 33, 84, 80, 80, 67, 20, 2, 95, 34, 6, 115, 50, 107, 115, 55, 108, 50, 101, 89, 47, 119, 49, 13, 50, 0, 0, 18, 2, 95, 33, 6, 124, 47, 14, 16, 40, 48, 47, 4, 119, 49, 13, 50, 0, 0, 5, 194, 85, 112, 72, 0, 11, 67, 17, 81, 84, 72, 109, 6, 111, 47, 0, 6, 195, 44, 243, 128, 72, 10, 67, 32, 83, 128, 107, 2, 111, 50, 0, 0, 7, 196, 4, 210, 78, 60, 65, 7, 196, 72, 18, 197, 80, 66, 7, 196, 44, 242, 197, 80, 66, 0, 0, 0, 7, 195, 88, 19, 128, 9, 76, 0, 7, 196, 92, 83, 69, 48, 20, 17, 4, 95, 3, 1, 16, 107, 6, 122, 83, 72, 55, 111, 47, 13, 34, 0, 0, 12, 201, 12, 20, 130, 60, 194, 78, 21, 83, 64, 20, 18, 2, 95, 41, 107, 6, 115, 49, 57, 13, 89, 55, 6, 124, 47, 13, 50, 0, 0, 19, 2, 95, 40, 107, 6, 115, 49, 57, 13, 23, 6, 122, 48, 119, 50, 13, 50, 0, 0, 21, 71, 64, 84, 137, 24, 84, 137, 20, 48, 108, 12, 34, 37, 83, 108, 12, 34, 6, 37, 0, 10, 199, 52, 20, 141, 60, 193, 85, 52, 20, 0, 0, 8, 197, 92, 17, 199, 20, 192, 20, 8, 197, 72, 243, 147, 20, 192, 20, 8, 197, 72, 19, 147, 20, 192, 20, 8, 197, 64, 147, 139, 20, 192, 20, 8, 197, 52, 243, 139, 20, 192, 20, 8, 197, 52, 83, 135, 20, 192, 20, 8, 197, 33, 82, 75, 20, 192, 20, 8, 197, 8, 145, 199, 20, 192, 20, 8, 197, 76, 242, 203, 20, 192, 20, 17, 2, 95, 45, 49, 6, 113, 48, 111, 55, 47, 4, 119, 49, 13, 50, 0, 0, 9, 198, 76, 197, 73, 52, 84, 128, 20, 9, 198, 64, 195, 197, 80, 84, 128, 20, 9, 198, 44, 241, 83, 80, 84, 128, 20, 10, 2, 95, 44, 49, 6, 113, 65, 115, 0, 0, 6, 195, 48, 84, 128, 20, 9, 2, 95, 51, 72, 34, 6, 37, 0, 0, 11, 68, 76, 18, 78, 80, 21, 102, 114, 0, 10, 7, 196, 20, 211, 69, 72, 20, 9, 2, 95, 50, 47, 85, 6, 119, 0, 0, 8, 197, 92, 147, 139, 20, 192, 20, 8, 197, 92, 21, 87, 20, 192, 20, 8, 197, 76, 147, 135, 20, 192, 20, 8, 197, 72, 147, 135, 20, 192, 20, 8, 197, 56, 146, 203, 20, 192, 20, 8, 197, 52, 19, 135, 20, 192, 20, 8, 197, 32, 147, 139, 20, 192, 20, 8, 197, 80, 83, 135, 20, 192, 20, 8, 197, 44, 242, 203, 20, 192, 20, 12, 201, 12, 243, 147, 84, 210, 78, 16, 84, 128, 20, 8, 2, 95, 49, 6, 119, 50, 0, 0, 9, 198, 80, 82, 83, 80, 84, 128, 20, 9, 198, 52, 81, 83, 80, 84, 128, 20, 9, 198, 45, 113, 84, 80, 84, 128, 20, 9, 198, 44, 194, 78, 44, 84, 128, 20, 9, 198, 28, 81, 83, 80, 84, 128, 20, 9, 2, 95, 48, 50, 6, 110, 55, 0, 0, 11, 2, 95, 55, 88, 6, 119, 84, 13, 50, 0, 0, 9, 2, 95, 54, 88, 6, 111, 89, 0, 0, 8, 197, 65, 83, 22, 21, 32, 20, 8, 197, 44, 19, 22, 21, 32, 20, 9, 2, 95, 53, 84, 6, 123, 83, 0, 0, 9, 2, 95, 52, 84, 6, 37, 34, 0, 0, 15, 2, 95, 59, 48, 6, 110, 50, 47, 49, 113, 65, 4, 115, 0, 0, 17, 2, 95, 58, 72, 6, 110, 71, 13, 55, 13, 48, 4, 110, 50, 47, 0, 0, 8, 197, 52, 19, 135, 5, 64, 22, 8, 197, 44, 19, 70, 21, 32, 20, 11, 2, 95, 57, 50, 6, 119, 100, 13, 50, 0, 0, 9, 198, 88, 84, 132, 21, 35, 208, 67, 9, 198, 81, 35, 205, 52, 83, 0, 20, 9, 198, 77, 67, 205, 52, 83, 0, 20, 9, 198, 17, 35, 205, 52, 83, 0, 20, 6, 195, 16, 86, 133, 72, 7, 66, 92, 80, 85, 13, 0, 9, 2, 95, 56, 6, 116, 101, 47, 0, 0, 18, 71, 61, 85, 9, 48, 192, 71, 20, 40, 47, 37, 57, 6, 115, 90, 13, 0, 16, 2, 95, 63, 84, 14, 16, 6, 115, 101, 47, 119, 49, 13, 50, 0, 0, 7, 196, 64, 242, 197, 72, 20, 0, 8, 197, 76, 19, 15, 52, 240, 65, 8, 195, 84, 149, 0, 9, 76, 28, 0, 9, 198, 81, 114, 78, 44, 83, 0, 20, 9, 198, 93, 35, 206, 28, 83, 0, 20, 0, 0, 7, 196, 32, 19, 69, 72, 20, 9, 198, 88, 243, 210, 16, 21, 0, 8, 0, 0, 0, 0, 0, 0, 0, 14, 203, 92, 16, 82, 76, 50, 9, 40, 227, 9, 40, 176, 66, 10, 199, 52, 148, 194, 4, 180, 197, 48, 65, 0, 7, 196, 104, 19, 69, 48, 20, 7, 196, 32, 83, 69, 48, 20, 0, 0, 12, 201, 60, 225, 197, 72, 145, 70, 48, 146, 139, 67, 24, 73, 16, 145, 148, 60, 225, 197, 72, 147, 135, 72, 108, 83, 47, 4, 113, 68, 6, 119, 34, 108, 68, 0, 15, 70, 12, 130, 70, 24, 243, 128, 91, 37, 83, 6, 113, 50, 0, 0, 10, 199, 12, 243, 15, 77, 49, 85, 52, 20, 0, 7, 196, 48, 20, 197, 72, 20, 0, 8, 197, 72, 243, 80, 20, 192, 20, 8, 197, 28, 82, 213, 56, 64, 72, 0, 8, 67, 72, 16, 197, 21, 0, 10, 0, 0, 7, 196, 4, 196, 207, 24, 8, 0, 17, 70, 44, 147, 147, 32, 20, 193, 49, 108, 50, 91, 6, 115, 89, 115, 0, 13, 69, 92, 19, 135, 20, 224, 85, 116, 68, 13, 50, 0, 8, 197, 52, 84, 16, 20, 192, 20, 8, 197, 76, 85, 20, 20, 192, 20, 8, 197, 44, 85, 84, 20, 192, 20, 8, 197, 80, 83, 154, 36, 160, 8, 0, 0, 0, 12, 4, 95, 4, 15, 20, 48, 6, 110, 50, 47, 0, 0, 22, 73, 20, 83, 147, 28, 83, 9, 40, 180, 192, 119, 50, 89, 100, 13, 55, 6, 123, 49, 89, 0, 9, 198, 88, 147, 204, 21, 69, 5, 67, 9, 198, 72, 16, 204, 21, 69, 5, 66, 8, 197, 44, 241, 134, 21, 32, 20, 8, 197, 44, 17, 134, 21, 32, 20, 8, 197, 28, 16, 130, 21, 32, 20, 8, 197, 9, 81, 134, 21, 32, 20, 8, 197, 80, 245, 4, 5, 64, 8, 0, 15, 74, 20, 229, 5, 73, 64, 73, 56, 209, 78, 80, 21, 0, 10, 0, 6, 195, 104, 19, 0, 72, 0, 0, 15, 69, 9, 33, 86, 21, 64, 71, 34, 13, 84, 6, 111, 47, 0, 8, 197, 77, 2, 78, 21, 64, 66, 17, 70, 12, 245, 82, 80, 17, 197, 49, 40, 34, 47, 6, 115, 90, 13, 0, 8, 3, 201, 153, 14, 14, 50, 0, 0, 9, 198, 77, 65, 71, 28, 83, 0, 20, 9, 198, 76, 210, 83, 64, 83, 0, 20, 9, 198, 76, 197, 78, 28, 83, 0, 20, 0, 9, 67, 12, 128, 84, 76, 111, 47, 0, 6, 195, 20, 65, 76, 20, 8, 67, 24, 16, 212, 21, 0, 10, 21, 2, 95, 95, 55, 6, 108, 81, 111, 50, 47, 89, 47, 14, 16, 6, 119, 48, 57, 13, 0, 0, 9, 198, 45, 112, 82, 80, 85, 0, 66, 9, 198, 48, 22, 129, 72, 85, 0, 67, 0, 10, 69, 60, 227, 9, 56, 80, 21, 0, 10, 0, 17, 70, 56, 18, 82, 60, 34, 64, 50, 116, 57, 34, 6, 122, 71, 37, 0, 15, 70, 44, 83, 142, 20, 70, 64, 49, 111, 50, 13, 72, 111, 0, 9, 198, 45, 112, 82, 80, 83, 0, 20, 9, 198, 45, 32, 85, 92, 83, 0, 20, 9, 198, 44, 227, 194, 8, 83, 0, 20, 0, 6, 195, 4, 65, 76, 20, 7, 195, 60, 242, 192, 9, 76, 0, 0, 8, 197, 72, 81, 201, 52, 80, 66, 6, 195, 4, 65, 82, 20, 0, 0, 6, 195, 33, 83, 128, 72, 7, 3, 201, 153, 20, 47, 0, 0, 21, 72, 8, 194, 84, 104, 180, 137, 20, 112, 71, 55, 108, 47, 89, 49, 34, 37, 12, 81, 0, 7, 196, 5, 4, 5, 48, 20, 9, 198, 32, 84, 137, 56, 225, 82, 20, 0, 0, 0, 0, 0, 0, 14, 4, 95, 7, 18, 22, 100, 14, 16, 6, 115, 84, 13, 0, 0, 0, 0, 8, 197, 76, 146, 144, 20, 192, 20, 8, 197, 44, 19, 148, 20, 192, 20, 0, 9, 198, 77, 69, 73, 80, 84, 128, 20, 8, 67, 8, 20, 197, 21, 0, 10, 0, 0, 11, 200, 36, 225, 210, 36, 164, 5, 56, 64, 66, 0, 13, 69, 8, 82, 76, 20, 224, 71, 123, 55, 13, 50, 0, 14, 69, 52, 148, 212, 20, 224, 65, 108, 89, 47, 13, 50, 0, 8, 197, 80, 144, 200, 20, 192, 20, 8, 197, 72, 85, 84, 20, 192, 20, 8, 197, 44, 193, 80, 20, 192, 20, 8, 197, 32, 16, 200, 20, 192, 20, 8, 197, 9, 83, 132, 20, 192, 20, 8, 197, 24, 148, 212, 20, 192, 20, 8, 197, 92, 147, 12, 20, 224, 72, 0, 0, 0, 0, 12, 201, 80, 81, 197, 56, 224, 84, 85, 84, 128, 68, 15, 70, 64, 240, 200, 21, 69, 5, 48, 113, 91, 6, 111, 47, 0, 14, 69, 9, 81, 134, 21, 64, 71, 109, 83, 6, 111, 47, 0, 8, 197, 44, 244, 142, 21, 64, 66, 8, 197, 12, 20, 142, 21, 64, 66, 18, 70, 41, 83, 69, 48, 17, 197, 90, 109, 65, 13, 55, 6, 115, 90, 13, 0, 0, 0, 6, 195, 92, 147, 0, 72, 18, 2, 95, 123, 84, 6, 37, 34, 49, 116, 50, 47, 13, 107, 4, 115, 49, 0, 13, 4, 95, 4, 9, 1, 6, 110, 65, 55, 125, 47, 0, 0, 0, 9, 198, 4, 211, 210, 21, 69, 5, 67, 17, 70, 21, 21, 73, 64, 17, 197, 119, 49, 37, 48, 6, 115, 90, 13, 0, 8, 197, 48, 21, 87, 21, 32, 20, 0, 16, 70, 41, 84, 212, 36, 225, 64, 90, 109, 89, 47, 6, 37, 50, 0, 9, 198, 12, 128, 82, 4, 65, 64, 66, 9, 198, 81, 34, 80, 64, 83, 0, 20, 9, 198, 77, 66, 80, 64, 83, 0, 20, 9, 198, 9, 35, 203, 44, 83, 0, 20, 9, 198, 64, 84, 137, 44, 83, 0, 20, 16, 70, 16, 80, 201, 8, 83, 0, 72, 119, 89, 37, 71, 111, 55, 0, 11, 70, 60, 97, 140, 36, 225, 64, 21, 0, 10, 0, 0, 0, 8, 195, 80, 245, 0, 9, 76, 8, 25, 2, 95, 125, 84, 6, 37, 34, 49, 116, 50, 47, 13, 107, 4, 115, 49, 89, 55, 6, 124, 47, 13, 50, 0, 0, 17, 70, 52, 148, 212, 72, 19, 0, 65, 37, 89, 47, 34, 6, 116, 55, 0, 9, 198, 81, 32, 80, 64, 83, 0, 20, 9, 198, 17, 33, 78, 80, 83, 0, 20, 0, 0, 8, 67, 40, 21, 211, 21, 0, 10, 0, 0, 0, 0, 13, 68, 28, 84, 197, 48, 100, 119, 89, 13, 55, 0, 20, 0, 0, 10, 67, 56, 20, 201, 50, 116, 89, 37, 0, 0, 10, 67, 104, 144, 200, 88, 2, 108, 101, 0, 0, 13, 68, 5, 4, 137, 48, 115, 48, 34, 6, 108, 55, 0, 0, 6, 195, 61, 1, 78, 20, 0, 17, 70, 64, 192, 78, 12, 129, 84, 48, 55, 116, 50, 91, 6, 111, 47, 0, 0, 0, 7, 196, 21, 69, 5, 72, 20, 0, 8, 197, 92, 145, 77, 20, 192, 20, 8, 197, 77, 64, 77, 20, 192, 20, 8, 197, 72, 19, 77, 20, 192, 20, 0, 18, 70, 16, 148, 195, 37, 1, 76, 72, 108, 89, 6, 37, 48, 13, 55, 0, 20, 0, 10, 199, 56, 17, 5, 72, 128, 78, 16, 67, 0, 0, 8, 197, 16, 243, 77, 20, 192, 20, 0, 0, 0, 0, 14, 69, 9, 81, 7, 21, 64, 71, 110, 75, 6, 111, 47, 0, 8, 197, 24, 19, 19, 21, 64, 66, 15, 69, 12, 195, 211, 21, 64, 49, 55, 122, 88, 6, 111, 47, 0, 8, 197, 48, 82, 203, 21, 32, 20, 8, 197, 8, 17, 199, 21, 32, 20, 0, 0, 6, 195, 92, 147, 20, 72, 0, 0, 8, 197, 21, 66, 75, 21, 64, 67, 8, 197, 88, 147, 135, 21, 32, 20, 8, 197, 77, 82, 75, 21, 32, 20, 8, 197, 44, 84, 139, 21, 32, 20, 8, 197, 40, 243, 135, 21, 32, 20, 8, 197, 8, 192, 75, 21, 32, 20, 0, 9, 198, 45, 113, 66, 8, 83, 0, 20, 9, 198, 45, 34, 78, 28, 83, 0, 20, 11, 70, 52, 19, 23, 5, 33, 64, 21, 0, 10, 7, 66, 104, 80, 88, 13, 0, 0, 0, 0, 0, 9, 198, 88, 193, 85, 28, 83, 0, 20, 9, 198, 77, 69, 78, 80, 83, 0, 20, 0, 0, 11, 200, 52, 148, 214, 5, 69, 9, 56, 112, 65, 12, 68, 8, 84, 212, 20, 71, 111, 89, 47, 13, 0, 16, 70, 16, 245, 66, 48, 85, 0, 72, 40, 71, 55, 6, 111, 47, 0, 0, 9, 198, 17, 147, 129, 77, 66, 69, 67, 0, 0, 0, 7, 196, 17, 85, 133, 48, 20, 9, 198, 76, 50, 9, 65, 1, 82, 20, 0, 0, 0, 0, 0, 0, 0, 16, 67, 57, 148, 192, 50, 123, 89, 72, 6, 124, 88, 111, 50, 47, 0, 0, 7, 196, 20, 227, 210, 52, 66, 0, 9, 197, 56, 17, 9, 20, 224, 66, 9, 8, 197, 65, 83, 77, 20, 192, 20, 8, 197, 52, 244, 141, 20, 192, 20, 0, 14, 70, 12, 128, 83, 76, 148, 192, 91, 116, 89, 6, 37, 0, 0, 7, 195, 17, 84, 192, 72, 8, 0, 13, 72, 53, 83, 20, 37, 67, 213, 12, 128, 21, 0, 10, 0, 8, 197, 33, 83, 77, 20, 192, 20, 0, 8, 67, 76, 149, 5, 21, 0, 10, 0, 18, 71, 12, 128, 77, 64, 17, 206, 20, 91, 116, 65, 48, 6, 116, 67, 13, 0, 0, 0, 8, 197, 64, 20, 139, 21, 64, 66, 8, 197, 76, 145, 4, 21, 32, 20, 8, 197, 72, 145, 4, 21, 32, 20, 8, 197, 64, 241, 68, 21, 32, 20, 8, 197, 48, 145, 68, 21, 32, 20, 8, 197, 32, 19, 20, 21, 32, 20, 8, 197, 28, 241, 68, 21, 32, 20, 11, 70, 84, 197, 9, 52, 21, 5, 21, 0, 10, 0, 0, 0, 0, 8, 197, 64, 18, 203, 21, 64, 66, 8, 197, 104, 243, 4, 21, 32, 20, 8, 197, 80, 85, 20, 21, 32, 20, 8, 197, 64, 243, 4, 21, 32, 20, 8, 197, 52, 145, 84, 21, 32, 20, 8, 197, 48, 85, 84, 21, 32, 20, 8, 197, 48, 85, 20, 21, 32, 20, 8, 197, 8, 243, 4, 21, 32, 20, 8, 197, 8, 149, 20, 21, 32, 20, 0, 9, 198, 76, 229, 70, 24, 83, 0, 20, 9, 198, 44, 229, 70, 24, 83, 0, 20, 16, 70, 60, 228, 218, 20, 193, 128, 113, 50, 89, 6, 111, 55, 83, 0, 0, 0, 11, 200, 52, 147, 12, 36, 209, 84, 21, 32, 20, 0, 9, 198, 36, 225, 21, 13, 66, 69, 66, 9, 198, 4, 211, 133, 77, 66, 69, 67, 10, 69, 21, 48, 193, 64, 80, 21, 0, 10, 0, 9, 198, 92, 244, 147, 80, 83, 0, 20, 9, 198, 92, 20, 133, 53, 1, 76, 20, 0, 0, 0, 14, 69, 28, 243, 199, 48, 80, 81, 40, 12, 81, 13, 55, 0, 0, 17, 70, 40, 20, 146, 21, 65, 76, 90, 35, 34, 13, 47, 6, 111, 55, 0, 0, 0, 8, 196, 104, 240, 76, 76, 66, 8, 0, 0, 0, 10, 199, 77, 1, 75, 80, 18, 197, 48, 66, 10, 199, 77, 1, 75, 80, 18, 197, 48, 20, 0, 9, 198, 76, 229, 73, 77, 65, 82, 20, 9, 198, 64, 147, 139, 77, 65, 82, 20, 9, 198, 24, 197, 73, 77, 65, 82, 20, 0, 9, 3, 26, 39, 14, 88, 13, 50, 0, 0, 0, 0, 0, 14, 69, 8, 85, 133, 56, 64, 71, 119, 84, 13, 50, 72, 0, 8, 197, 24, 241, 70, 20, 192, 20, 8, 197, 72, 241, 66, 20, 192, 20, 8, 197, 52, 85, 66, 20, 192, 20, 9, 198, 5, 66, 5, 56, 85, 77, 20, 6, 195, 80, 241, 78, 8, 0, 0, 0, 0, 14, 69, 36, 225, 210, 36, 64, 108, 68, 14, 16, 108, 47, 0, 8, 197, 44, 85, 86, 20, 192, 20, 8, 197, 17, 33, 86, 20, 192, 20, 8, 197, 32, 85, 86, 20, 192, 20, 0, 9, 198, 77, 4, 129, 56, 177, 76, 20, 0, 0, 0, 8, 197, 48, 19, 80, 21, 64, 66, 8, 197, 44, 83, 148, 21, 32, 20, 8, 197, 9, 83, 80, 21, 32, 20, 0, 0, 0, 0, 8, 197, 52, 148, 218, 37, 64, 65, 23, 73, 16, 19, 65, 76, 49, 82, 36, 225, 192, 72, 35, 65, 116, 38, 89, 6, 119, 34, 108, 68, 0, 8, 197, 104, 147, 132, 21, 32, 20, 8, 197, 92, 243, 132, 21, 32, 20, 8, 197, 81, 85, 20, 21, 32, 20, 8, 197, 80, 85, 84, 21, 32, 20, 8, 197, 17, 112, 84, 21, 32, 20, 8, 197, 16, 83, 132, 21, 32, 20, 0, 9, 198, 88, 82, 9, 44, 83, 0, 20, 0, 0, 0, 12, 201, 21, 80, 200, 5, 34, 83, 80, 145, 64, 68, 0, 9, 198, 77, 2, 75, 44, 83, 0, 20, 9, 198, 65, 34, 75, 44, 83, 0, 20, 9, 198, 45, 33, 85, 44, 83, 0, 20, 9, 198, 81, 35, 197, 8, 83, 0, 20, 0, 0, 16, 70, 12, 16, 129, 72, 85, 0, 49, 115, 71, 115, 34, 6, 111, 0, 0, 14, 69, 12, 19, 129, 16, 16, 49, 116, 50, 115, 72, 115, 0, 0, 8, 67, 28, 19, 69, 21, 0, 10, 8, 67, 32, 243, 69, 21, 0, 10, 0, 34, 79, 104, 145, 75, 20, 226, 21, 37, 48, 133, 88, 19, 12, 36, 225, 192, 88, 37, 12, 49, 13, 50, 107, 124, 89, 71, 13, 84, 116, 55, 108, 68, 0, 0, 9, 198, 12, 128, 80, 37, 65, 82, 66, 0, 0, 0, 10, 199, 76, 16, 210, 37, 53, 9, 20, 67, 0, 0, 0, 0, 0, 0, 8, 197, 77, 82, 90, 20, 192, 20, 8, 197, 72, 241, 134, 20, 192, 20, 8, 197, 72, 17, 134, 20, 192, 20, 8, 197, 52, 241, 134, 20, 192, 20, 8, 197, 17, 82, 90, 20, 192, 20, 8, 197, 9, 81, 134, 20, 192, 20, 0, 0, 7, 195, 4, 196, 192, 72, 8, 0, 0, 8, 197, 92, 20, 146, 20, 192, 20, 8, 197, 52, 22, 154, 20, 192, 20, 8, 197, 44, 225, 86, 20, 192, 20, 8, 197, 44, 144, 130, 20, 192, 20, 8, 197, 32, 240, 130, 20, 192, 20, 8, 197, 77, 65, 86, 20, 224, 20, 0, 0, 0, 0, 12, 69, 12, 128, 76, 21, 64, 91, 115, 55, 111, 0, 13, 69, 12, 16, 200, 21, 64, 49, 116, 91, 6, 111, 0, 0, 0, 0, 0, 14, 69, 80, 245, 80, 21, 64, 47, 40, 48, 6, 111, 47, 0, 14, 69, 64, 245, 76, 21, 64, 48, 40, 55, 6, 111, 47, 0, 0, 9, 198, 76, 211, 197, 104, 83, 0, 20, 9, 198, 76, 210, 75, 44, 83, 0, 20, 9, 198, 29, 37, 73, 104, 83, 0, 20, 17, 70, 89, 34, 74, 4, 113, 64, 84, 34, 119, 57, 6, 115, 90, 13, 0, 17, 70, 52, 85, 18, 4, 113, 64, 65, 119, 47, 34, 6, 115, 90, 13, 0, 0, 12, 71, 52, 147, 11, 76, 128, 75, 20, 21, 0, 10, 0, 0, 15, 69, 8, 84, 137, 28, 80, 71, 108, 12, 34, 13, 100, 13, 0, 6, 195, 92, 16, 82, 8, 0, 9, 198, 81, 35, 199, 28, 83, 0, 20, 0, 0, 0, 0, 9, 198, 77, 4, 133, 56, 177, 76, 20, 0, 0, 21, 72, 4, 48, 197, 77, 51, 201, 72, 80, 35, 49, 89, 111, 89, 58, 6, 35, 34, 13, 0, 21, 72, 12, 19, 79, 84, 99, 1, 28, 80, 49, 115, 65, 40, 83, 55, 6, 115, 90, 13, 0, 0, 6, 18, 66, 103, 0, 107, 0, 7, 6, 98, 101, 0, 8, 2, 21, 14, 128, 132, 130, 3, 71, 13, 0, 8, 2, 114, 101, 110, 3, 71, 108, 12, 0, 4, 2, 108, 103, 3, 71, 111, 0, 8, 2, 17, 67, 11, 0, 8, 2, 17, 67, 17, 67, 101, 32, 0, 8, 2, 17, 67, 17, 67, 101, 110, 32, 0, 8, 2, 17, 67, 106, 101, 25, 0, 8, 2, 99, 17, 67, 0, 8, 2, 110, 103, 101, 108, 0, 8, 2, 114, 109, 0, 8, 2, 115, 116, 105, 97, 0, 105, 101, 8, 2, 114, 3, 71, 111, 37, 13, 0, 4, 8, 2, 17, 67, 101, 114, 32, 3, 71, 119, 0, 8, 2, 100, 101, 108, 0, 8, 2, 116, 101, 114, 0, 8, 2, 118, 101, 110, 32, 0, 8, 2, 122, 101, 109, 0, 8, 2, 122, 105, 103, 0, 101, 8, 2, 12, 0, 118, 101, 114, 8, 3, 71, 119, 84, 13, 34, 0, 117, 8, 3, 71, 121, 0, 4, 105, 8, 2, 100, 101, 3, 71, 123, 0, 105, 8, 2, 116, 101, 108, 0, 7, 6, 99, 104, 0, 101, 1, 10, 2, 32, 3, 8, 91, 0, 4, 8, 2, 97, 100, 111, 114, 3, 76, 0, 8, 2, 97, 114, 116, 101, 114, 0, 8, 2, 105, 112, 0, 101, 114, 114, 121, 8, 3, 76, 111, 34, 37, 0, 4, 1, 97, 116, 101, 100, 3, 91, 0, 1, 110, 97, 108, 98, 0, 1, 110, 97, 118, 101, 114, 2, 101, 0, 1, 110, 117, 114, 98, 0, 1, 111, 114, 98, 2, 101, 0, 1, 111, 114, 98, 2, 117, 0, 1, 114, 97, 109, 0, 2, 195, 169, 0, 8, 0, 8, 111, 112, 2, 101, 0, 105, 8, 2, 99, 97, 110, 101, 3, 91, 2, 37, 0, 97, 117, 8, 2, 102, 102, 101, 3, 91, 2, 122, 0, 97, 112, 101, 114, 111, 110, 8, 3, 91, 4, 116, 48, 13, 34, 118, 50, 0, 97, 117, 8, 2, 118, 105, 110, 3, 91, 4, 122, 0, 101, 113, 117, 101, 8, 3, 91, 111, 49, 0, 111, 8, 2, 113, 117, 101, 3, 91, 113, 0, 97, 114, 103, 8, 2, 21, 3, 91, 116, 34, 90, 0, 97, 110, 103, 8, 2, 101, 3, 91, 117, 90, 0, 4, 3, 101, 0, 8, 2, 97, 111, 0, 8, 2, 97, 114, 105, 0, 8, 2, 101, 109, 105, 0, 8, 2, 108, 111, 0, 8, 2, 111, 108, 101, 0, 8, 2, 111, 114, 0, 8, 2, 114, 0, 7, 6, 101, 114, 0, 4, 1, 21, 2, 105, 110, 103, 32, 3, 6, 108, 12, 34, 0, 1, 21, 2, 105, 110, 103, 101, 110, 32, 0, 101, 110, 2, 32, 3, 6, 108, 12, 34, 13, 50, 0, 4, 1, 10, 2, 32, 28, 33, 3, 8, 13, 34, 0, 1, 10, 2, 100, 32, 28, 33, 0, 1, 10, 2, 100, 101, 32, 28, 33, 0, 1, 10, 2, 100, 101, 110, 32, 28, 33, 0, 1, 10, 2, 101, 32, 28, 33, 0, 1, 10, 2, 101, 110, 32, 28, 33, 0, 1, 10, 2, 101, 110, 100, 32, 28, 33, 0, 1, 10, 2, 101, 110, 100, 101, 32, 28, 33, 0, 1, 10, 2, 105, 110, 103, 32, 28, 33, 0, 1, 10, 2, 105, 110, 103, 101, 110, 32, 28, 33, 0, 1, 10, 2, 116, 32, 28, 33, 0, 4, 1, 10, 2, 32, 3, 13, 34, 0, 1, 10, 2, 101, 110, 32, 28, 33, 0, 1, 21, 2, 97, 97, 114, 32, 0, 1, 108, 111, 116, 2, 97, 98, 101, 108, 0, 1, 115, 105, 109, 2, 97, 98, 101, 108, 0, 2, 105, 106, 32, 0, 105, 101, 2, 32, 3, 13, 34, 6, 37, 0, 101, 1, 10, 2, 32, 3, 13, 34, 13, 0, 97, 1, 10, 2, 32, 3, 13, 34, 115, 0, 8, 2, 21, 14, 128, 132, 130, 3, 111, 34, 0, 103, 101, 114, 8, 3, 111, 34, 100, 13, 34, 0, 1, 10, 2, 17, 67, 21, 3, 112, 34, 0, 7, 6, 111, 110, 0, 4, 103, 8, 2, 97, 97, 114, 110, 3, 4, 113, 50, 100, 6, 0, 103, 8, 2, 97, 110, 115, 0, 103, 8, 2, 114, 105, 106, 112, 98, 97, 97, 114, 0, 103, 8, 2, 114, 111, 110, 100, 0, 103, 8, 2, 117, 110, 115, 116, 105, 103, 0, 103, 8, 2, 117, 117, 114, 0, 103, 101, 8, 2, 21, 14, 128, 132, 132, 3, 4, 113, 50, 100, 13, 0, 100, 101, 114, 8, 2, 21, 14, 128, 132, 133, 3, 6, 113, 50, 72, 13, 34, 0, 8, 2, 116, 101, 21, 14, 128, 132, 130, 3, 113, 50, 0, 97, 97, 110, 8, 2, 21, 14, 128, 132, 133, 3, 113, 50, 6, 115, 50, 0, 116, 8, 2, 21, 14, 128, 132, 131, 3, 113, 50, 47, 0, 100, 101, 114, 8, 3, 113, 50, 72, 13, 34, 0, 4, 103, 101, 8, 2, 100, 105, 101, 114, 116, 3, 113, 50, 100, 13, 0, 103, 101, 8, 2, 108, 111, 111, 102, 0, 103, 101, 8, 2, 108, 117, 107, 0, 103, 101, 8, 2, 109, 97, 107, 0, 103, 101, 8, 2, 110, 97, 100, 101, 0, 103, 101, 8, 2, 114, 105, 101, 102, 0, 103, 101, 8, 2, 118, 97, 108, 0, 7, 6, 114, 101, 0, 4, 8, 2, 99, 101, 110, 116, 3, 34, 13, 0, 8, 2, 99, 101, 112, 116, 0, 8, 2, 99, 108, 97, 109, 0, 8, 2, 103, 101, 101, 114, 0, 8, 2, 103, 101, 114, 101, 110, 0, 8, 2, 115, 101, 114, 118, 101, 32, 0, 8, 2, 99, 111, 114, 100, 3, 34, 36, 6, 0, 8, 2, 99, 101, 112, 116, 105, 101, 102, 3, 34, 119, 0, 112, 114, 101, 2, 115, 97, 105, 108, 108, 3, 34, 119, 48, 34, 119, 0, 7, 6, 116, 101, 0, 103, 101, 110, 8, 2, 14, 128, 132, 133, 3, 47, 6, 119, 100, 13, 50, 0, 4, 8, 2, 103, 101, 108, 105, 106, 107, 14, 128, 132, 130, 3, 47, 13, 0, 8, 2, 103, 101, 109, 111, 101, 116, 14, 128, 132, 130, 0, 8, 2, 103, 111, 101, 100, 0, 8, 2, 104, 117, 105, 0, 8, 2, 107, 101, 101, 114, 0, 8, 2, 107, 111, 114, 116, 0, 8, 2, 108, 101, 117, 114, 0, 8, 2, 108, 111, 111, 114, 0, 8, 2, 109, 101, 101, 114, 0, 8, 2, 109, 105, 100, 100, 0, 8, 2, 110, 97, 0, 8, 2, 110, 101, 101, 114, 0, 8, 2, 114, 101, 99, 104, 116, 0, 8, 2, 115, 97, 109, 0, 8, 2, 118, 101, 101, 108, 0, 8, 2, 118, 101, 114, 103, 101, 101, 102, 14, 128, 132, 130, 0, 8, 2, 118, 111, 111, 114, 115, 99, 104, 105, 106, 110, 0, 8, 2, 118, 111, 114, 0, 8, 2, 118, 114, 101, 100, 0, 8, 2, 119, 101, 114, 107, 0, 114, 117, 103, 8, 2, 14, 128, 132, 133, 3, 47, 13, 34, 6, 110, 101, 0, 119, 101, 101, 103, 8, 2, 14, 128, 132, 134, 3, 47, 13, 85, 6, 119, 101, 0, 7, 6, 97, 0, 99, 104, 1, 109, 2, 105, 110, 3, 2, 115, 91, 0, 102, 102, 105, 99, 104, 8, 3, 2, 116, 83, 37, 91, 0, 105, 114, 101, 2, 32, 3, 6, 111, 12, 34, 13, 0, 105, 114, 2, 32, 3, 6, 111, 34, 0, 4, 1, 21, 2, 100, 101, 32, 3, 6, 115, 0, 1, 21, 2, 116, 97, 32, 0, 2, 116, 111, 114, 32, 0, 97, 2, 17, 67, 32, 0, 97, 2, 114, 100, 32, 0, 114, 105, 115, 2, 32, 3, 6, 115, 34, 108, 89, 0, 114, 105, 115, 115, 101, 110, 2, 32, 3, 6, 115, 34, 108, 89, 13, 50, 0, 97, 110, 8, 2, 21, 14, 128, 132, 131, 3, 6, 115, 50, 0, 98, 101, 108, 1, 21, 2, 32, 3, 6, 115, 71, 13, 55, 0, 98, 101, 108, 101, 1, 21, 2, 32, 3, 6, 115, 71, 13, 55, 13, 0, 103, 101, 2, 32, 24, 3, 6, 115, 90, 13, 0, 4, 110, 116, 1, 21, 2, 32, 3, 6, 116, 50, 47, 0, 110, 116, 1, 21, 2, 101, 32, 0, 110, 116, 1, 21, 2, 101, 110, 32, 0, 110, 116, 1, 21, 2, 101, 114, 32, 0, 105, 108, 108, 101, 2, 32, 3, 6, 116, 57, 13, 0, 105, 108, 108, 101, 115, 2, 32, 3, 6, 116, 57, 13, 89, 0, 103, 110, 101, 1, 21, 2, 32, 3, 6, 116, 67, 13, 0, 102, 8, 2, 17, 67, 21, 14, 128, 132, 130, 3, 6, 116, 83, 0, 1, 17, 67, 21, 21, 2, 32, 3, 8, 115, 0, 103, 101, 115, 2, 32, 14, 128, 128, 129, 3, 89, 0, 105, 8, 2, 109, 97, 98, 101, 108, 3, 111, 0, 4, 3, 115, 0, 1, 116, 2, 98, 108, 101, 97, 117, 0, 97, 0, 97, 1, 122, 2, 109, 32, 0, 101, 0, 97, 114, 1, 21, 2, 32, 14, 128, 128, 131, 3, 115, 34, 0, 97, 114, 100, 1, 21, 2, 32, 14, 128, 128, 132, 3, 115, 34, 47, 0, 4, 97, 105, 3, 115, 57, 0, 121, 0, 103, 101, 2, 32, 28, 17, 3, 115, 100, 13, 0, 4, 2, 17, 67, 25, 3, 116, 0, 2, 120, 0, 4, 1, 98, 2, 98, 121, 3, 119, 0, 105, 1, 100, 2, 115, 121, 0, 105, 108, 1, 109, 3, 119, 108, 55, 0, 4, 117, 3, 125, 0, 117, 119, 0, 7, 6, 98, 0, 1, 98, 3, 0, 97, 97, 114, 1, 10, 2, 32, 14, 128, 128, 132, 3, 8, 71, 115, 34, 0, 97, 114, 101, 1, 10, 2, 32, 14, 128, 128, 132, 3, 8, 71, 115, 34, 13, 0, 8, 111, 2, 115, 116, 97, 107, 3, 48, 0, 115, 2, 32, 24, 3, 48, 89, 0, 3, 71, 0, 105, 106, 2, 122, 111, 110, 100, 3, 71, 2, 37, 0, 105, 110, 110, 101, 110, 8, 2, 14, 128, 132, 134, 3, 71, 6, 108, 50, 13, 50, 0, 117, 117, 114, 116, 8, 2, 21, 21, 14, 128, 132, 133, 3, 71, 6, 109, 34, 47, 0, 111, 118, 101, 110, 8, 2, 14, 128, 132, 133, 3, 71, 6, 122, 84, 13, 50, 0, 105, 106, 8, 2, 17, 67, 21, 14, 128, 132, 131, 3, 71, 6, 123, 0, 117, 105, 116, 101, 110, 8, 2, 14, 128, 132, 134, 3, 71, 6, 124, 47, 13, 50, 0, 114, 97, 110, 100, 8, 3, 71, 34, 6, 116, 50, 72, 0, 97, 97, 110, 3, 71, 115, 50, 0, 7, 6, 99, 0, 4, 3, 49, 0, 107, 0, 111, 2, 110, 99, 101, 114, 116, 3, 49, 2, 113, 0, 111, 110, 103, 114, 101, 115, 8, 3, 49, 113, 50, 100, 34, 6, 111, 89, 0, 111, 97, 99, 104, 3, 49, 122, 76, 0, 4, 2, 101, 3, 89, 0, 2, 105, 0, 2, 121, 0, 4, 105, 1, 21, 2, 101, 101, 108, 3, 91, 0, 105, 1, 21, 2, 101, 117, 115, 0, 105, 1, 21, 2, 101, 117, 122, 0, 105, 1, 21, 2, 195, 171, 0, 105, 2, 97, 0, 105, 2, 111, 0, 7, 6, 100, 0, 1, 100, 3, 0, 4, 2, 115, 116, 3, 47, 0, 116, 0, 106, 3, 47, 57, 0, 115, 2, 32, 24, 3, 47, 89, 0, 3, 72, 0, 4, 101, 8, 2, 103, 101, 101, 110, 3, 72, 13, 0, 101, 8, 2, 122, 101, 108, 102, 0, 106, 8, 3, 75, 0, 7, 6, 101, 0, 117, 109, 1, 115, 117, 109, 21, 2, 32, 3, 4, 119, 110, 65, 0, 4, 1, 21, 2, 114, 101, 110, 100, 101, 32, 3, 6, 108, 0, 1, 21, 2, 114, 101, 110, 100, 101, 110, 32, 0, 101, 1, 21, 2, 114, 32, 0, 101, 1, 21, 2, 114, 100, 32, 0, 101, 1, 21, 2, 114, 100, 101, 32, 0, 101, 1, 21, 2, 114, 100, 101, 110, 32, 0, 101, 1, 21, 2, 114, 116, 32, 0, 4, 110, 116, 1, 21, 2, 32, 3, 6, 111, 50, 47, 0, 110, 116, 1, 21, 2, 101, 32, 0, 110, 116, 1, 21, 2, 101, 110, 32, 0, 110, 116, 1, 21, 2, 101, 114, 32, 0, 110, 116, 1, 21, 2, 101, 114, 101, 32, 0, 110, 116, 1, 21, 2, 115, 116, 32, 0, 110, 116, 1, 21, 2, 115, 116, 101, 32, 0, 110, 116, 1, 103, 97, 0, 108, 1, 21, 2, 32, 3, 6, 111, 55, 0, 115, 1, 21, 2, 32, 14, 128, 208, 130, 3, 6, 111, 89, 0, 115, 115, 101, 110, 1, 21, 2, 32, 14, 128, 208, 133, 3, 6, 111, 89, 13, 50, 0, 4, 101, 1, 21, 2, 29, 32, 3, 6, 119, 0, 101, 1, 21, 2, 32, 0, 108, 101, 1, 10, 2, 32, 3, 6, 119, 55, 13, 0, 108, 101, 110, 1, 21, 2, 32, 3, 6, 119, 55, 13, 50, 0, 117, 109, 2, 32, 28, 17, 3, 6, 119, 110, 65, 0, 97, 2, 32, 3, 6, 119, 115, 0, 117, 114, 1, 21, 2, 32, 3, 6, 121, 34, 0, 117, 122, 101, 1, 105, 2, 32, 3, 6, 121, 88, 13, 0, 117, 122, 101, 114, 1, 105, 2, 32, 3, 6, 121, 88, 13, 34, 0, 117, 122, 101, 114, 101, 1, 105, 2, 32, 3, 6, 121, 88, 13, 34, 13, 0, 117, 115, 1, 105, 2, 32, 3, 6, 121, 89, 0, 117, 115, 116, 1, 105, 2, 32, 3, 6, 121, 89, 47, 0, 117, 115, 116, 101, 1, 105, 2, 32, 3, 6, 121, 89, 47, 13, 0, 97, 117, 2, 32, 3, 6, 122, 0, 105, 116, 1, 116, 105, 2, 32, 3, 6, 123, 47, 0, 110, 1, 10, 2, 101, 32, 28, 33, 14, 128, 129, 131, 3, 8, 13, 50, 13, 0, 110, 1, 10, 2, 101, 110, 32, 28, 33, 14, 128, 129, 132, 3, 8, 13, 50, 13, 50, 0, 110, 1, 10, 2, 116, 32, 28, 33, 14, 128, 129, 131, 3, 8, 13, 50, 47, 0, 4, 108, 1, 10, 2, 32, 28, 33, 3, 8, 13, 55, 0, 108, 1, 10, 2, 100, 101, 32, 28, 33, 0, 108, 1, 10, 2, 100, 101, 110, 32, 28, 33, 0, 108, 1, 10, 2, 101, 32, 28, 33, 0, 108, 1, 10, 2, 101, 110, 32, 28, 33, 0, 108, 1, 10, 2, 101, 110, 100, 32, 28, 33, 0, 108, 1, 10, 2, 105, 110, 103, 32, 28, 33, 0, 108, 1, 10, 2, 105, 110, 103, 101, 110, 32, 28, 33, 0, 108, 1, 10, 2, 116, 32, 28, 33, 0, 4, 1, 10, 2, 109, 101, 110, 116, 3, 13, 0, 1, 10, 2, 110, 105, 115, 115, 101, 110, 32, 0, 1, 17, 67, 10, 2, 32, 14, 128, 208, 129, 0, 1, 17, 67, 17, 65, 25, 2, 32, 14, 128, 129, 129, 0, 1, 103, 105, 2, 32, 12, 14, 128, 208, 129, 0, 1, 106, 17, 65, 25, 2, 32, 14, 128, 128, 129, 0, 1, 108, 101, 2, 32, 12, 14, 128, 208, 129, 0, 1, 114, 101, 2, 32, 12, 14, 128, 208, 129, 0, 1, 115, 2, 99, 111, 110, 100, 0, 1, 115, 2, 99, 117, 117, 114, 0, 2, 32, 0, 110, 100, 101, 1, 10, 2, 32, 14, 128, 128, 129, 0, 117, 105, 108, 108, 101, 3, 13, 6, 109, 0, 195, 175, 2, 12, 3, 13, 10, 108, 0, 114, 101, 115, 1, 21, 2, 32, 14, 128, 208, 132, 3, 13, 34, 6, 111, 89, 0, 114, 101, 115, 115, 101, 110, 1, 21, 2, 32, 14, 128, 192, 135, 3, 13, 34, 6, 111, 89, 13, 50, 0, 4, 110, 1, 10, 2, 32, 14, 128, 208, 130, 3, 13, 50, 0, 110, 1, 17, 67, 17, 65, 25, 2, 32, 14, 128, 129, 130, 0, 110, 1, 100, 110, 97, 2, 32, 14, 128, 128, 130, 0, 110, 1, 106, 17, 65, 25, 2, 32, 14, 128, 128, 130, 0, 110, 1, 108, 101, 2, 32, 12, 14, 128, 208, 130, 0, 110, 1, 108, 108, 2, 32, 14, 128, 128, 131, 0, 110, 1, 114, 101, 2, 32, 12, 14, 128, 208, 130, 0, 110, 100, 101, 110, 1, 10, 2, 32, 14, 128, 128, 130, 0, 116, 116, 101, 110, 1, 21, 2, 32, 14, 128, 128, 131, 0, 110, 100, 1, 10, 2, 32, 3, 13, 50, 72, 0, 110, 115, 1, 10, 2, 32, 14, 128, 192, 131, 3, 13, 50, 89, 0, 108, 105, 106, 107, 115, 1, 10, 3, 13, 55, 13, 49, 89, 0, 108, 100, 1, 10, 2, 32, 3, 13, 55, 72, 0, 109, 1, 10, 2, 32, 3, 13, 65, 0, 4, 115, 1, 17, 67, 17, 65, 25, 2, 32, 14, 128, 129, 130, 3, 13, 89, 0, 115, 1, 21, 2, 32, 28, 33, 0, 115, 1, 106, 21, 2, 32, 0, 4, 2, 114, 3, 108, 12, 0, 101, 2, 114, 0, 4, 1, 99, 2, 110, 116, 114, 117, 109, 3, 111, 0, 1, 100, 105, 2, 110, 116, 0, 1, 115, 101, 114, 112, 2, 110, 116, 0, 2, 17, 67, 25, 0, 2, 114, 116, 115, 15, 0, 2, 120, 0, 120, 112, 111, 115, 105, 116, 105, 101, 8, 3, 111, 49, 89, 48, 122, 88, 6, 37, 47, 89, 37, 0, 1, 10, 2, 110, 17, 66, 21, 3, 112, 0, 4, 1, 29, 3, 119, 0, 1, 99, 111, 114, 112, 2, 100, 117, 0, 8, 112, 2, 110, 105, 98, 101, 108, 0, 101, 0, 100, 101, 110, 3, 119, 72, 13, 50, 0, 3, 120, 0, 117, 3, 121, 0, 97, 117, 3, 122, 0, 105, 2, 12, 3, 123, 0, 101, 117, 119, 3, 126, 0, 7, 6, 102, 0, 1, 102, 3, 0, 3, 83, 0, 7, 6, 103, 0, 4, 105, 1, 21, 2, 101, 117, 115, 3, 90, 0, 105, 1, 21, 2, 101, 117, 122, 0, 4, 3, 100, 0, 103, 0, 101, 110, 101, 114, 2, 97, 97, 108, 3, 100, 4, 119, 50, 13, 34, 0, 4, 101, 2, 98, 105, 101, 100, 3, 100, 13, 0, 101, 2, 115, 112, 114, 101, 107, 0, 101, 2, 118, 97, 108, 0, 101, 8, 2, 21, 14, 128, 132, 130, 0, 101, 108, 105, 106, 107, 8, 3, 100, 13, 55, 123, 49, 0, 105, 1, 105, 108, 101, 114, 2, 101, 117, 3, 100, 37, 57, 0, 101, 8, 2, 114, 17, 67, 3, 100, 111, 0, 4, 101, 8, 2, 118, 101, 110, 3, 100, 119, 0, 101, 8, 2, 118, 101, 114, 0, 101, 8, 2, 118, 105, 110, 103, 0, 101, 101, 8, 0, 101, 117, 8, 3, 100, 121, 0, 1, 115, 3, 101, 0, 7, 6, 104, 0, 1, 17, 67, 2, 25, 3, 0, 3, 107, 0, 101, 114, 105, 110, 110, 8, 3, 107, 2, 111, 34, 108, 50, 0, 101, 114, 115, 101, 110, 8, 3, 107, 6, 111, 34, 89, 13, 50, 0, 101, 114, 8, 2, 101, 110, 3, 107, 108, 12, 34, 0, 101, 114, 8, 2, 21, 14, 128, 132, 131, 3, 107, 111, 34, 0, 101, 105, 100, 1, 10, 2, 32, 14, 128, 128, 132, 3, 107, 123, 47, 0, 7, 6, 105, 0, 4, 101, 1, 100, 2, 32, 3, 6, 37, 0, 101, 1, 103, 2, 32, 0, 101, 1, 109, 2, 32, 0, 101, 1, 112, 2, 32, 0, 101, 2, 17, 67, 101, 32, 0, 101, 2, 17, 67, 101, 110, 32, 0, 101, 2, 17, 67, 101, 114, 32, 0, 101, 2, 17, 67, 101, 114, 101, 32, 0, 101, 2, 17, 67, 106, 101, 29, 32, 0, 101, 2, 17, 67, 115, 116, 101, 32, 0, 101, 2, 17, 67, 116, 106, 101, 29, 32, 0, 101, 2, 29, 0, 101, 2, 114, 100, 32, 0, 101, 2, 114, 101, 110, 32, 0, 98, 101, 108, 1, 21, 2, 32, 3, 6, 37, 71, 13, 55, 0, 98, 101, 108, 101, 1, 21, 2, 32, 3, 6, 37, 71, 13, 55, 13, 0, 110, 110, 8, 2, 21, 14, 128, 132, 130, 3, 6, 108, 0, 110, 8, 2, 17, 67, 21, 14, 128, 132, 130, 3, 6, 108, 50, 0, 115, 116, 1, 21, 2, 32, 3, 6, 108, 89, 47, 0, 115, 116, 101, 110, 1, 21, 2, 32, 3, 6, 108, 89, 47, 13, 50, 0, 115, 109, 101, 1, 21, 2, 32, 3, 6, 108, 89, 65, 13, 0, 4, 106, 1, 21, 2, 110, 32, 3, 6, 123, 0, 106, 2, 32, 0, 106, 2, 101, 32, 0, 106, 2, 101, 110, 0, 106, 2, 116, 106, 101, 29, 0, 103, 101, 1, 21, 2, 32, 14, 128, 208, 131, 3, 8, 13, 100, 13, 0, 103, 101, 114, 1, 21, 2, 32, 3, 8, 13, 100, 13, 34, 0, 103, 101, 114, 101, 1, 21, 2, 32, 3, 8, 13, 100, 13, 34, 13, 0, 103, 101, 110, 1, 21, 2, 32, 3, 8, 13, 100, 13, 50, 0, 103, 115, 116, 1, 21, 2, 32, 3, 8, 13, 100, 89, 47, 0, 103, 115, 116, 101, 1, 21, 2, 32, 3, 8, 13, 100, 89, 47, 13, 0, 103, 1, 21, 2, 32, 14, 128, 208, 130, 3, 8, 13, 101, 0, 99, 117, 115, 1, 10, 2, 32, 3, 8, 37, 49, 110, 89, 0, 4, 99, 97, 1, 10, 2, 32, 3, 8, 37, 49, 115, 0, 107, 97, 1, 10, 2, 32, 0, 4, 99, 111, 1, 10, 2, 32, 3, 8, 37, 49, 122, 0, 107, 111, 1, 10, 2, 32, 0, 115, 99, 104, 1, 21, 2, 32, 3, 8, 37, 89, 0, 115, 99, 104, 101, 1, 21, 2, 32, 3, 8, 37, 89, 13, 0, 99, 105, 1, 10, 2, 32, 3, 8, 37, 89, 37, 0, 4, 3, 37, 0, 2, 99, 104, 101, 32, 0, 101, 0, 101, 117, 122, 101, 2, 32, 3, 37, 57, 6, 121, 88, 13, 0, 101, 117, 122, 101, 114, 2, 32, 3, 37, 57, 6, 121, 88, 13, 34, 0, 101, 117, 122, 101, 114, 101, 2, 32, 3, 37, 57, 6, 121, 88, 13, 34, 13, 0, 101, 117, 115, 2, 32, 3, 37, 57, 6, 121, 89, 0, 101, 117, 115, 116, 2, 32, 3, 37, 57, 6, 121, 89, 47, 0, 101, 117, 115, 116, 101, 2, 32, 3, 37, 57, 6, 121, 89, 47, 13, 0, 101, 117, 119, 3, 37, 58, 0, 111, 2, 110, 97, 103, 101, 3, 37, 113, 0, 101, 101, 3, 37, 119, 0, 4, 2, 17, 67, 25, 3, 108, 0, 2, 120, 0, 106, 2, 12, 3, 123, 0, 7, 6, 106, 0, 3, 57, 0, 111, 117, 2, 114, 110, 97, 3, 90, 40, 0, 7, 6, 107, 0, 1, 107, 3, 0, 3, 49, 0, 111, 110, 105, 110, 103, 8, 3, 49, 6, 122, 50, 108, 68, 0, 111, 107, 107, 101, 114, 101, 108, 3, 49, 113, 49, 13, 34, 6, 111, 55, 0, 97, 108, 101, 8, 2, 110, 100, 101, 3, 49, 115, 55, 6, 111, 0, 111, 110, 105, 110, 103, 105, 110, 8, 3, 49, 122, 50, 108, 100, 6, 108, 50, 0, 7, 6, 108, 0, 1, 108, 3, 0, 3, 55, 0, 105, 106, 107, 1, 10, 2, 32, 14, 128, 128, 132, 3, 55, 13, 49, 0, 105, 106, 107, 101, 1, 10, 2, 32, 14, 128, 128, 133, 3, 55, 13, 49, 13, 0, 105, 106, 107, 101, 114, 1, 10, 2, 32, 14, 128, 128, 134, 3, 55, 13, 49, 13, 34, 0, 105, 106, 107, 101, 114, 101, 1, 10, 2, 32, 14, 128, 128, 135, 3, 55, 13, 49, 13, 34, 13, 0, 105, 106, 107, 101, 110, 1, 10, 2, 32, 14, 128, 128, 134, 3, 55, 13, 49, 13, 50, 0, 105, 106, 107, 115, 116, 1, 10, 2, 32, 14, 128, 128, 134, 3, 55, 13, 49, 89, 47, 0, 105, 106, 107, 115, 116, 101, 1, 10, 2, 32, 14, 128, 128, 135, 3, 55, 13, 49, 89, 47, 13, 0, 105, 106, 107, 104, 101, 105, 100, 1, 10, 2, 32, 14, 128, 128, 136, 3, 55, 13, 49, 107, 123, 47, 0, 97, 110, 103, 101, 8, 2, 21, 14, 128, 132, 133, 3, 55, 35, 68, 13, 0, 97, 97, 110, 1, 10, 2, 32, 14, 128, 128, 132, 3, 55, 115, 50, 0, 111, 122, 101, 1, 21, 2, 32, 14, 128, 128, 132, 3, 55, 122, 88, 13, 0, 111, 122, 101, 110, 1, 21, 2, 32, 14, 128, 128, 133, 3, 55, 122, 88, 13, 50, 0, 111, 111, 115, 1, 21, 2, 32, 14, 128, 128, 132, 3, 55, 122, 89, 0, 111, 111, 103, 1, 21, 2, 32, 3, 55, 122, 101, 0, 7, 6, 109, 0, 1, 109, 3, 0, 3, 65, 0, 105, 8, 2, 115, 21, 3, 65, 2, 108, 0, 105, 115, 8, 2, 103, 117, 110, 3, 65, 2, 108, 89, 0, 4, 105, 115, 8, 2, 99, 111, 109, 109, 14, 128, 132, 131, 3, 65, 6, 108, 89, 0, 105, 115, 8, 2, 100, 97, 14, 128, 132, 131, 0, 105, 115, 8, 2, 103, 21, 14, 128, 132, 131, 0, 105, 115, 8, 2, 103, 101, 21, 14, 128, 132, 131, 0, 105, 115, 8, 2, 105, 110, 21, 14, 128, 132, 131, 0, 105, 115, 8, 2, 107, 108, 101, 117, 14, 128, 132, 131, 0, 105, 115, 8, 2, 108, 105, 101, 112, 14, 128, 132, 131, 0, 105, 115, 8, 2, 108, 111, 14, 128, 132, 131, 0, 105, 115, 8, 2, 116, 17, 65, 0, 105, 115, 118, 101, 114, 8, 2, 21, 3, 65, 6, 108, 89, 83, 13, 34, 0, 101, 101, 8, 2, 21, 14, 128, 132, 131, 3, 65, 6, 119, 0, 101, 110, 117, 2, 32, 3, 65, 13, 50, 109, 0, 4, 105, 115, 8, 2, 97, 110, 17, 67, 3, 65, 37, 88, 0, 105, 115, 8, 2, 195, 168, 0, 97, 110, 97, 103, 101, 109, 101, 110, 116, 3, 65, 115, 50, 108, 75, 65, 13, 50, 47, 0, 7, 6, 110, 0, 1, 110, 3, 0, 4, 3, 50, 0, 2, 103, 28, 19, 0, 2, 107, 28, 19, 0, 4, 97, 2, 116, 117, 114, 3, 50, 2, 115, 0, 97, 2, 118, 105, 103, 0, 97, 8, 2, 112, 111, 108, 17, 65, 0, 97, 8, 2, 118, 111, 108, 103, 21, 0, 97, 112, 111, 108, 101, 111, 110, 3, 50, 2, 115, 48, 122, 55, 13, 57, 113, 50, 0, 97, 8, 2, 114, 99, 3, 50, 2, 116, 0, 97, 114, 99, 105, 8, 2, 115, 3, 50, 2, 116, 34, 89, 108, 0, 105, 101, 117, 119, 115, 8, 2, 21, 14, 128, 132, 134, 3, 50, 6, 37, 58, 89, 0, 4, 97, 8, 2, 17, 67, 21, 21, 14, 128, 132, 130, 3, 50, 6, 115, 0, 97, 8, 2, 17, 67, 21, 24, 0, 97, 110, 111, 8, 2, 21, 14, 128, 132, 132, 3, 50, 6, 115, 50, 122, 0, 105, 115, 1, 21, 21, 2, 32, 14, 128, 128, 131, 3, 50, 108, 89, 0, 105, 115, 101, 110, 1, 21, 21, 2, 32, 14, 128, 128, 133, 3, 50, 108, 89, 13, 50, 0, 4, 97, 8, 2, 100, 101, 114, 3, 50, 115, 0, 97, 8, 2, 116, 105, 111, 110, 0, 97, 8, 2, 118, 114, 0, 97, 116, 117, 117, 114, 8, 3, 50, 115, 47, 6, 109, 34, 0, 4, 97, 8, 2, 17, 67, 11, 3, 50, 116, 0, 97, 8, 2, 99, 104, 116, 0, 111, 111, 114, 100, 8, 2, 21, 14, 128, 132, 133, 3, 50, 122, 34, 72, 0, 106, 3, 67, 0, 4, 2, 107, 3, 68, 0, 103, 0, 7, 6, 111, 0, 110, 8, 2, 21, 14, 128, 132, 130, 3, 2, 113, 50, 0, 118, 101, 114, 8, 2, 21, 14, 128, 132, 132, 3, 4, 122, 84, 13, 34, 0, 101, 2, 29, 32, 3, 6, 40, 0, 105, 114, 2, 32, 3, 6, 85, 115, 34, 0, 112, 8, 2, 21, 21, 14, 128, 132, 130, 3, 6, 113, 48, 0, 4, 111, 2, 17, 67, 32, 3, 6, 122, 0, 111, 2, 29, 0, 112, 8, 2, 101, 114, 97, 3, 6, 122, 48, 0, 112, 101, 110, 8, 2, 21, 14, 128, 132, 132, 3, 6, 122, 48, 13, 50, 0, 112, 101, 110, 105, 110, 103, 115, 8, 2, 14, 128, 132, 136, 3, 6, 122, 48, 13, 50, 108, 68, 89, 0, 111, 110, 3, 6, 122, 50, 0, 1, 17, 67, 21, 21, 2, 32, 3, 8, 122, 0, 98, 115, 99, 2, 117, 3, 39, 48, 89, 49, 0, 4, 101, 3, 40, 0, 117, 1, 99, 2, 112, 117, 0, 117, 1, 100, 2, 98, 108, 117, 0, 117, 1, 114, 116, 2, 118, 97, 105, 108, 0, 117, 2, 99, 104, 101, 32, 0, 117, 2, 114, 97, 103, 101, 0, 117, 1, 116, 2, 114, 3, 40, 12, 0, 101, 105, 3, 40, 57, 0, 117, 118, 101, 2, 114, 116, 117, 3, 40, 84, 111, 0, 117, 99, 104, 2, 101, 110, 32, 3, 40, 91, 0, 4, 105, 1, 99, 2, 102, 102, 117, 3, 85, 116, 0, 105, 1, 108, 112, 2, 116, 0, 4, 2, 17, 67, 25, 3, 113, 0, 2, 120, 0, 112, 8, 2, 116, 105, 111, 110, 3, 113, 48, 0, 111, 2, 114, 3, 114, 0, 4, 3, 122, 0, 1, 114, 112, 2, 103, 114, 97, 109, 0, 2, 114, 0, 111, 0, 111, 105, 3, 122, 57, 0, 111, 115, 116, 8, 2, 21, 14, 128, 132, 132, 3, 122, 89, 47, 0, 4, 117, 3, 125, 0, 117, 119, 0, 7, 6, 112, 0, 1, 112, 3, 0, 3, 48, 0, 97, 114, 97, 99, 104, 2, 117, 116, 3, 48, 4, 115, 34, 115, 91, 0, 111, 108, 105, 116, 105, 101, 8, 2, 21, 3, 48, 122, 55, 6, 37, 47, 89, 37, 0, 111, 108, 105, 116, 105, 101, 107, 8, 3, 48, 122, 55, 37, 47, 6, 37, 49, 0, 4, 104, 2, 25, 3, 83, 0, 104, 8, 0, 114, 111, 103, 114, 97, 109, 109, 97, 1, 21, 2, 32, 14, 128, 128, 135, 3, 122, 100, 34, 116, 65, 65, 35, 0, 7, 6, 113, 0, 4, 3, 49, 0, 117, 1, 21, 2, 101, 101, 114, 0, 117, 1, 21, 2, 101, 114, 101, 110, 32, 0, 117, 101, 1, 21, 2, 32, 0, 117, 3, 49, 84, 0, 7, 6, 114, 0, 114, 3, 16, 34, 0, 4, 3, 34, 0, 1, 17, 65, 2, 17, 65, 0, 1, 17, 67, 2, 17, 65, 0, 101, 118, 97, 110, 99, 104, 3, 34, 13, 84, 117, 50, 91, 0, 101, 99, 104, 101, 114, 99, 104, 3, 34, 13, 91, 111, 34, 91, 0, 111, 117, 116, 101, 3, 34, 40, 47, 13, 0, 7, 6, 115, 0, 2, 115, 3, 0, 101, 108, 1, 10, 2, 32, 3, 8, 89, 13, 55, 0, 101, 108, 101, 110, 1, 10, 2, 32, 3, 8, 89, 13, 55, 13, 50, 0, 4, 1, 17, 65, 2, 17, 65, 3, 88, 0, 2, 98, 0, 2, 100, 0, 4, 3, 89, 0, 1, 21, 2, 32, 14, 128, 128, 129, 0, 8, 101, 114, 118, 2, 101, 0, 99, 0, 99, 104, 2, 32, 0, 99, 104, 2, 101, 32, 0, 116, 97, 110, 100, 97, 97, 114, 100, 8, 2, 21, 14, 128, 132, 137, 3, 89, 47, 6, 116, 50, 72, 115, 34, 47, 0, 116, 114, 97, 97, 116, 1, 21, 2, 32, 14, 128, 128, 134, 3, 89, 47, 34, 115, 47, 0, 4, 99, 2, 111, 111, 112, 3, 89, 49, 0, 99, 2, 111, 112, 105, 0, 106, 101, 1, 21, 2, 32, 3, 89, 57, 13, 0, 99, 104, 3, 89, 101, 0, 105, 1, 17, 65, 2, 111, 3, 90, 0, 4, 99, 104, 8, 2, 110, 3, 91, 0, 104, 2, 25, 0, 104, 8, 0, 105, 1, 21, 2, 111, 0, 106, 0, 115, 105, 1, 21, 2, 111, 0, 7, 6, 116, 0, 1, 116, 3, 0, 105, 101, 1, 115, 2, 32, 3, 8, 47, 37, 0, 105, 101, 2, 32, 3, 8, 47, 89, 37, 0, 4, 105, 101, 1, 99, 2, 32, 3, 8, 89, 37, 0, 105, 101, 1, 107, 2, 32, 0, 105, 101, 1, 112, 2, 32, 0, 4, 3, 47, 0, 1, 115, 2, 105, 12, 12, 0, 2, 104, 97, 97, 114, 0, 2, 104, 97, 118, 0, 100, 0, 104, 0, 104, 8, 0, 101, 97, 109, 8, 3, 47, 6, 37, 12, 65, 0, 111, 101, 8, 2, 21, 14, 128, 132, 131, 3, 47, 6, 40, 0, 114, 97, 110, 115, 8, 2, 21, 14, 128, 132, 133, 3, 47, 34, 4, 116, 50, 89, 0, 114, 97, 105, 110, 8, 3, 47, 34, 119, 50, 0, 101, 97, 109, 2, 32, 3, 47, 37, 12, 65, 0, 106, 3, 47, 38, 0, 111, 117, 99, 104, 2, 101, 3, 47, 40, 91, 0, 105, 101, 1, 97, 114, 99, 2, 32, 3, 47, 89, 6, 37, 0, 115, 106, 3, 76, 0, 4, 105, 1, 21, 2, 97, 3, 91, 0, 105, 1, 21, 2, 101, 117, 115, 0, 105, 1, 21, 2, 101, 117, 122, 0, 105, 1, 21, 2, 111, 110, 0, 105, 1, 21, 2, 195, 171, 0, 4, 105, 101, 101, 2, 108, 32, 3, 91, 6, 119, 0, 105, 195, 171, 2, 108, 101, 32, 0, 7, 6, 117, 0, 4, 2, 115, 105, 101, 32, 3, 6, 109, 0, 117, 2, 114, 32, 0, 116, 101, 1, 21, 2, 32, 3, 6, 109, 47, 0, 105, 116, 8, 2, 21, 14, 128, 132, 131, 3, 6, 124, 47, 0, 4, 3, 109, 0, 117, 0, 4, 2, 17, 67, 25, 3, 110, 0, 2, 120, 0, 105, 3, 124, 0, 4, 119, 3, 127, 0, 119, 2, 32, 0, 7, 6, 118, 0, 1, 115, 3, 83, 0, 3, 84, 0, 97, 110, 8, 2, 21, 14, 128, 132, 131, 3, 84, 2, 116, 50, 0, 111, 111, 114, 116, 8, 2, 21, 14, 128, 132, 133, 3, 84, 6, 114, 34, 47, 0, 101, 114, 8, 2, 21, 14, 128, 132, 131, 3, 84, 13, 34, 0, 101, 114, 103, 101, 8, 2, 108, 101, 3, 84, 13, 34, 100, 6, 119, 0, 101, 114, 8, 2, 115, 105, 101, 32, 3, 84, 111, 34, 0, 101, 114, 100, 101, 114, 8, 3, 84, 111, 34, 72, 13, 34, 0, 97, 110, 122, 101, 108, 102, 8, 2, 21, 14, 128, 132, 135, 3, 84, 116, 50, 88, 4, 111, 55, 83, 0, 97, 110, 103, 8, 3, 84, 116, 68, 0, 7, 6, 119, 0, 4, 2, 17, 67, 25, 3, 58, 0, 2, 29, 0, 114, 8, 3, 84, 34, 0, 3, 85, 0, 101, 103, 8, 2, 21, 14, 128, 132, 131, 3, 85, 6, 111, 100, 0, 97, 110, 8, 2, 21, 14, 128, 132, 131, 3, 85, 6, 116, 50, 0, 97, 110, 8, 2, 18, 66, 21, 14, 128, 132, 131, 3, 85, 6, 116, 68, 0, 101, 115, 116, 8, 2, 21, 14, 128, 132, 132, 3, 85, 111, 89, 47, 0, 4, 97, 110, 8, 2, 100, 101, 108, 3, 85, 116, 50, 0, 97, 110, 110, 8, 2, 101, 101, 114, 0, 97, 110, 111, 114, 100, 101, 108, 105, 106, 107, 8, 3, 85, 116, 50, 23, 6, 113, 34, 72, 13, 55, 13, 49, 0, 97, 110, 116, 114, 111, 117, 119, 105, 103, 8, 3, 85, 116, 50, 47, 34, 6, 125, 13, 100, 0, 97, 110, 118, 111, 101, 103, 108, 105, 106, 107, 8, 3, 85, 116, 50, 84, 6, 40, 101, 55, 13, 49, 0, 97, 110, 115, 116, 97, 108, 116, 105, 103, 8, 3, 85, 116, 50, 89, 47, 6, 116, 55, 47, 13, 100, 0, 97, 110, 115, 109, 97, 107, 101, 108, 105, 106, 107, 8, 3, 85, 116, 50, 89, 65, 6, 115, 49, 13, 55, 13, 49, 0, 97, 110, 104, 111, 112, 105, 103, 8, 3, 85, 116, 50, 107, 6, 122, 48, 13, 100, 0, 97, 110, 8, 2, 107, 101, 108, 3, 85, 116, 68, 0, 4, 101, 103, 8, 2, 101, 32, 3, 85, 119, 100, 0, 101, 103, 8, 2, 101, 110, 0, 7, 6, 120, 0, 3, 49, 89, 0, 7, 6, 121, 0, 3, 37, 0, 8, 2, 17, 65, 3, 57, 0, 4, 2, 17, 67, 25, 3, 108, 0, 2, 120, 0, 7, 6, 122, 0, 4, 1, 115, 3, 0, 2, 122, 3, 0, 3, 88, 0, 111, 103, 101, 8, 2, 21, 14, 128, 132, 132, 3, 88, 4, 39, 81, 13, 0, 101, 108, 101, 2, 32, 14, 128, 128, 132, 3, 88, 119, 55, 13, 0, 117, 105, 100, 8, 2, 21, 14, 128, 132, 132, 3, 88, 124, 47, 0, 101, 108, 102, 1, 21, 2, 32, 14, 128, 128, 132, 3, 89, 6, 111, 55, 83, 0, 7, 6, 0, 195, 168, 114, 101, 2, 32, 3, 6, 111, 34, 13, 0, 195, 169, 2, 32, 3, 6, 119, 0, 195, 171, 110, 1, 101, 105, 114, 101, 2, 32, 14, 128, 128, 130, 3, 13, 50, 0, 44, 2, 15, 3, 49, 6, 113, 65, 115, 0, 45, 8, 32, 2, 32, 15, 3, 65, 6, 108, 50, 0, 36, 3, 72, 6, 113, 55, 116, 34, 0, 39, 115, 1, 21, 2, 32, 14, 128, 128, 130, 3, 89, 0, 4, 195, 169, 3, 119, 0, 195, 169, 195, 169, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts45 = FileInMemory_createWithData (21598, reinterpret_cast (&espeakdata_dicts45_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/nl_dict", U"nl"); Collection_addItem (me.peek(), espeakdata_dicts45.transfer()); static unsigned char espeakdata_dicts46_data[4198] = { 0, 4, 0, 0, 246, 12, 0, 0, 0, 0, 0, 7, 195, 52, 83, 128, 72, 8, 0, 0, 5, 65, 4, 120, 0, 0, 0, 0, 0, 6, 65, 8, 71, 117, 0, 0, 0, 0, 0, 6, 65, 12, 89, 117, 0, 0, 0, 0, 0, 6, 65, 16, 72, 117, 0, 0, 0, 6, 195, 76, 147, 128, 76, 0, 0, 0, 0, 16, 4, 95, 48, 67, 15, 107, 6, 125, 50, 72, 51, 13, 72, 108, 0, 0, 6, 195, 76, 147, 133, 76, 0, 6, 65, 24, 115, 83, 0, 0, 0, 0, 0, 6, 65, 28, 81, 117, 0, 0, 0, 6, 195, 44, 19, 128, 76, 0, 0, 6, 65, 32, 107, 122, 0, 0, 0, 0, 15, 1, 35, 50, 125, 65, 65, 13, 51, 47, 115, 68, 50, 0, 27, 0, 6, 65, 36, 110, 0, 14, 5, 193, 36, 72, 28, 0, 14, 1, 37, 48, 51, 6, 124, 89, 6, 115, 50, 47, 0, 27, 0, 7, 1, 38, 121, 12, 81, 0, 0, 0, 6, 65, 40, 57, 117, 0, 0, 0, 11, 1, 42, 89, 95, 35, 51, 50, 108, 0, 27, 0, 9, 1, 43, 48, 55, 125, 89, 0, 27, 0, 6, 65, 44, 49, 122, 0, 0, 0, 0, 14, 1, 47, 89, 49, 51, 121, 89, 47, 51, 13, 49, 0, 27, 0, 6, 65, 48, 115, 55, 0, 0, 0, 0, 0, 6, 65, 52, 115, 65, 0, 0, 6, 195, 52, 83, 147, 8, 7, 195, 52, 83, 147, 72, 8, 0, 0, 0, 10, 5, 95, 48, 1, 14, 4, 124, 81, 0, 6, 65, 56, 115, 50, 0, 0, 0, 0, 0, 0, 10, 1, 61, 35, 51, 55, 110, 49, 0, 27, 0, 0, 0, 13, 1, 64, 49, 51, 113, 55, 55, 119, 55, 83, 119, 0, 6, 65, 64, 48, 117, 0, 0, 0, 0, 0, 6, 65, 68, 49, 126, 0, 0, 0, 0, 0, 6, 65, 72, 116, 51, 0, 0, 0, 6, 195, 8, 193, 64, 76, 0, 0, 6, 65, 76, 115, 89, 0, 0, 0, 0, 0, 6, 65, 80, 47, 117, 0, 0, 0, 11, 70, 12, 243, 148, 36, 229, 69, 21, 0, 10, 6, 195, 52, 81, 192, 76, 0, 0, 0, 0, 0, 0, 6, 65, 88, 84, 117, 0, 0, 0, 0, 0, 22, 1, 92, 121, 65, 84, 115, 50, 72, 47, 15, 89, 49, 51, 121, 89, 47, 51, 13, 49, 0, 27, 14, 65, 92, 72, 6, 121, 71, 12, 115, 55, 4, 84, 117, 0, 0, 0, 15, 1, 94, 89, 109, 51, 49, 125, 65, 83, 55, 115, 49, 89, 0, 0, 0, 17, 4, 95, 49, 77, 49, 6, 115, 47, 15, 47, 6, 126, 89, 13, 50, 0, 7, 65, 96, 115, 49, 89, 0, 0, 21, 4, 95, 49, 77, 50, 6, 117, 50, 15, 65, 6, 109, 55, 55, 110, 38, 4, 124, 50, 0, 0, 0, 0, 6, 195, 8, 194, 82, 76, 0, 0, 0, 0, 7, 65, 104, 89, 115, 47, 0, 0, 6, 194, 5, 64, 72, 8, 0, 0, 0, 0, 0, 0, 0, 8, 197, 45, 83, 142, 21, 64, 76, 0, 0, 0, 7, 196, 32, 17, 4, 20, 72, 0, 0, 0, 0, 0, 0, 0, 7, 195, 32, 244, 192, 72, 8, 0, 0, 15, 69, 77, 148, 212, 20, 208, 89, 111, 89, 47, 6, 117, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 4, 95, 49, 57, 15, 50, 6, 109, 47, 12, 13, 50, 72, 108, 0, 0, 0, 0, 6, 194, 5, 96, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 84, 225, 5, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 20, 227, 128, 72, 8, 15, 4, 95, 49, 56, 15, 6, 119, 47, 12, 13, 50, 72, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 32, 83, 142, 20, 76, 0, 0, 0, 0, 0, 10, 69, 72, 80, 68, 21, 32, 21, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 32, 21, 20, 72, 6, 195, 16, 149, 20, 76, 0, 0, 0, 0, 0, 0, 0, 0, 15, 4, 95, 49, 49, 15, 6, 115, 55, 55, 115, 84, 47, 108, 0, 0, 0, 0, 8, 66, 21, 32, 4, 116, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 66, 16, 80, 72, 110, 0, 76, 0, 0, 0, 0, 0, 9, 67, 16, 85, 0, 72, 117, 0, 76, 17, 4, 95, 49, 51, 15, 47, 51, 6, 115, 47, 12, 13, 50, 72, 108, 0, 0, 12, 4, 95, 4, 16, 20, 49, 121, 65, 65, 119, 0, 0, 0, 5, 194, 17, 80, 76, 0, 6, 195, 32, 19, 64, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 20, 12, 4, 47, 6, 109, 55, 72, 108, 0, 0, 0, 0, 16, 4, 95, 49, 53, 15, 83, 6, 115, 65, 47, 13, 50, 72, 108, 0, 0, 0, 0, 8, 66, 21, 64, 115, 47, 0, 72, 0, 0, 0, 0, 0, 14, 4, 95, 49, 50, 15, 47, 6, 121, 55, 84, 47, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 4, 95, 49, 55, 15, 89, 6, 111, 47, 12, 13, 50, 72, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 76, 176, 76, 76, 17, 4, 95, 49, 52, 15, 83, 57, 6, 123, 51, 47, 13, 65, 72, 108, 0, 0, 0, 0, 10, 67, 4, 225, 0, 108, 50, 72, 0, 9, 0, 0, 0, 0, 0, 0, 0, 7, 196, 16, 83, 142, 20, 76, 0, 0, 0, 0, 0, 17, 4, 95, 49, 54, 15, 89, 6, 115, 49, 89, 47, 13, 50, 72, 108, 0, 0, 0, 0, 0, 0, 5, 194, 32, 16, 76, 5, 194, 16, 144, 76, 0, 0, 0, 0, 0, 0, 8, 196, 48, 19, 135, 76, 72, 8, 0, 0, 16, 5, 95, 48, 77, 49, 15, 47, 6, 126, 89, 13, 50, 72, 108, 0, 0, 6, 195, 16, 147, 128, 76, 6, 195, 32, 19, 128, 76, 0, 0, 0, 6, 195, 16, 147, 133, 76, 0, 0, 0, 0, 0, 6, 195, 32, 20, 128, 72, 0, 8, 196, 20, 195, 5, 72, 72, 8, 0, 10, 69, 12, 19, 131, 20, 192, 21, 0, 10, 0, 0, 0, 7, 196, 24, 244, 132, 36, 8, 7, 196, 36, 227, 133, 56, 8, 0, 0, 0, 0, 6, 195, 32, 19, 147, 76, 0, 0, 0, 0, 0, 0, 5, 194, 20, 144, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 16, 84, 133, 76, 76, 13, 3, 95, 49, 15, 83, 6, 113, 51, 89, 47, 108, 0, 0, 0, 0, 0, 0, 0, 0, 10, 67, 40, 81, 192, 57, 116, 109, 0, 76, 0, 12, 3, 95, 50, 15, 6, 119, 50, 72, 51, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 51, 15, 47, 51, 6, 115, 72, 57, 108, 0, 11, 4, 95, 15, 18, 4, 13, 50, 72, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 32, 83, 142, 21, 48, 76, 0, 0, 0, 7, 196, 24, 244, 129, 56, 8, 0, 0, 0, 0, 12, 3, 95, 53, 15, 83, 6, 115, 65, 47, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 54, 15, 91, 6, 115, 47, 12, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 20, 224, 72, 0, 13, 3, 95, 51, 88, 47, 51, 6, 115, 47, 12, 110, 0, 0, 13, 3, 95, 48, 67, 107, 6, 125, 50, 72, 51, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 3, 95, 49, 67, 6, 115, 47, 15, 107, 6, 125, 50, 72, 51, 108, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 49, 57, 50, 6, 109, 47, 12, 13, 50, 0, 0, 12, 3, 95, 49, 56, 6, 119, 47, 12, 13, 50, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 49, 49, 6, 115, 55, 84, 108, 0, 0, 9, 3, 95, 49, 48, 47, 6, 110, 0, 0, 14, 3, 95, 49, 51, 47, 51, 6, 115, 47, 12, 13, 50, 0, 0, 11, 3, 95, 49, 50, 47, 6, 121, 55, 84, 0, 0, 13, 3, 95, 49, 53, 83, 6, 115, 65, 47, 13, 50, 0, 0, 14, 3, 95, 49, 52, 83, 57, 6, 123, 51, 47, 13, 50, 0, 0, 12, 3, 95, 52, 15, 83, 57, 6, 118, 51, 108, 0, 13, 3, 95, 49, 55, 89, 6, 111, 47, 12, 13, 50, 0, 0, 14, 3, 95, 49, 54, 89, 6, 115, 49, 89, 47, 13, 50, 0, 0, 0, 6, 195, 61, 52, 192, 76, 12, 3, 95, 55, 88, 89, 6, 111, 47, 12, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 95, 50, 88, 95, 6, 126, 108, 0, 0, 0, 0, 0, 0, 14, 3, 95, 56, 15, 6, 121, 47, 12, 13, 50, 72, 108, 0, 0, 0, 0, 0, 0, 10, 69, 76, 52, 133, 20, 224, 21, 0, 10, 0, 0, 0, 0, 0, 0, 12, 3, 95, 52, 88, 83, 6, 114, 51, 47, 110, 0, 0, 0, 0, 0, 10, 67, 56, 241, 64, 50, 123, 12, 108, 0, 0, 0, 0, 0, 12, 3, 95, 53, 88, 83, 6, 115, 65, 47, 110, 0, 0, 0, 0, 0, 0, 0, 13, 69, 60, 97, 137, 12, 80, 121, 83, 83, 110, 89, 0, 0, 0, 13, 3, 95, 54, 88, 89, 6, 115, 49, 89, 47, 110, 0, 0, 0, 14, 4, 95, 50, 88, 15, 95, 6, 126, 13, 50, 72, 108, 0, 0, 7, 132, 22, 195, 165, 18, 76, 0, 6, 195, 52, 149, 20, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 56, 88, 6, 121, 47, 12, 110, 0, 0, 0, 0, 0, 0, 0, 7, 195, 52, 81, 0, 72, 8, 0, 0, 12, 3, 95, 57, 88, 50, 6, 109, 47, 12, 110, 0, 0, 7, 196, 16, 85, 20, 20, 76, 0, 11, 67, 56, 241, 78, 50, 123, 12, 13, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 36, 224, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 56, 81, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 52, 147, 128, 76, 0, 0, 0, 19, 4, 95, 48, 77, 50, 65, 6, 109, 55, 55, 110, 38, 4, 124, 50, 13, 51, 0, 0, 0, 6, 195, 52, 147, 133, 76, 7, 196, 60, 246, 13, 48, 17, 0, 13, 4, 95, 48, 77, 49, 47, 6, 126, 89, 13, 50, 0, 0, 0, 0, 0, 0, 0, 12, 67, 24, 244, 128, 83, 121, 34, 12, 0, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 52, 144, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 60, 112, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 4, 95, 3, 9, 18, 89, 6, 109, 51, 49, 125, 65, 83, 55, 115, 49, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 1, 3, 21, 120, 6, 49, 125, 47, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 95, 195, 165, 122, 0, 0, 0, 0, 0, 0, 0, 8, 133, 15, 7, 19, 195, 165, 28, 0, 0, 0, 0, 0, 0, 7, 196, 45, 83, 142, 20, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 52, 245, 0, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 60, 208, 72, 28, 0, 0, 0, 0, 0, 0, 0, 6, 195, 61, 97, 82, 28, 0, 0, 7, 2, 195, 165, 122, 0, 14, 6, 130, 195, 165, 72, 28, 0, 0, 0, 0, 0, 7, 131, 16, 195, 165, 72, 28, 0, 0, 0, 0, 0, 0, 0, 5, 130, 195, 169, 43, 0, 0, 0, 0, 0, 15, 4, 95, 3, 5, 4, 89, 6, 117, 72, 109, 55, 55, 108, 0, 0, 0, 0, 0, 0, 0, 7, 132, 2, 195, 184, 18, 76, 7, 132, 6, 195, 184, 18, 8, 5, 130, 195, 188, 43, 0, 0, 0, 0, 8, 133, 22, 195, 165, 18, 5, 76, 0, 0, 0, 0, 0, 9, 67, 44, 243, 64, 49, 121, 65, 0, 7, 195, 76, 243, 64, 72, 8, 0, 0, 0, 0, 6, 195, 16, 83, 64, 76, 0, 0, 0, 0, 0, 0, 8, 133, 22, 195, 165, 18, 20, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 76, 144, 76, 0, 0, 0, 0, 0, 12, 71, 52, 17, 206, 36, 98, 69, 72, 21, 0, 10, 0, 0, 8, 197, 16, 84, 147, 60, 208, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 2, 95, 9, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 80, 147, 0, 72, 28, 0, 0, 0, 0, 0, 8, 133, 22, 195, 166, 18, 5, 76, 0, 8, 197, 76, 181, 76, 48, 80, 76, 0, 0, 0, 9, 198, 76, 181, 76, 48, 85, 0, 76, 13, 2, 95, 34, 119, 50, 83, 114, 51, 91, 13, 55, 0, 0, 8, 197, 52, 83, 12, 60, 208, 8, 15, 2, 95, 33, 126, 47, 51, 124, 48, 89, 47, 115, 68, 50, 0, 0, 0, 14, 2, 95, 39, 119, 48, 123, 89, 47, 51, 6, 124, 83, 0, 0, 0, 0, 11, 2, 95, 36, 72, 121, 55, 55, 120, 51, 0, 0, 6, 195, 16, 83, 128, 76, 0, 11, 2, 95, 42, 89, 95, 35, 51, 50, 108, 0, 0, 21, 2, 95, 41, 48, 35, 51, 35, 68, 47, 6, 117, 89, 15, 91, 55, 6, 125, 47, 12, 0, 0, 6, 195, 16, 84, 133, 76, 6, 195, 16, 84, 133, 76, 24, 2, 95, 40, 48, 35, 51, 35, 68, 47, 6, 117, 89, 15, 71, 13, 57, 6, 111, 50, 50, 13, 51, 0, 0, 9, 67, 32, 84, 128, 107, 116, 51, 0, 0, 12, 2, 95, 46, 48, 125, 68, 49, 47, 126, 65, 0, 0, 8, 133, 22, 195, 166, 18, 20, 72, 10, 2, 95, 45, 89, 47, 51, 117, 49, 0, 0, 6, 195, 8, 20, 133, 72, 10, 2, 95, 44, 49, 121, 65, 65, 119, 0, 0, 9, 67, 16, 84, 128, 72, 116, 51, 0, 6, 195, 88, 20, 128, 72, 9, 2, 95, 51, 47, 51, 6, 117, 0, 0, 8, 2, 95, 50, 47, 6, 124, 0, 0, 8, 2, 95, 49, 6, 117, 50, 0, 0, 9, 2, 95, 48, 50, 6, 125, 55, 0, 0, 8, 2, 95, 55, 91, 6, 126, 0, 0, 10, 2, 95, 54, 89, 6, 115, 49, 89, 0, 0, 9, 2, 95, 53, 83, 6, 115, 65, 0, 0, 10, 2, 95, 52, 83, 6, 110, 51, 115, 0, 0, 14, 2, 95, 59, 89, 117, 65, 110, 49, 124, 55, 121, 50, 0, 0, 10, 2, 95, 58, 49, 124, 55, 121, 50, 0, 0, 8, 2, 95, 57, 50, 6, 110, 0, 0, 10, 2, 95, 56, 6, 121, 47, 12, 108, 0, 0, 18, 2, 95, 63, 89, 48, 113, 51, 91, 65, 121, 55, 89, 47, 115, 68, 50, 0, 0, 13, 2, 95, 62, 89, 47, 113, 51, 13, 15, 115, 50, 0, 0, 10, 2, 95, 61, 35, 51, 55, 110, 49, 0, 0, 14, 2, 95, 60, 65, 109, 50, 72, 51, 108, 15, 115, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 88, 147, 0, 76, 6, 195, 16, 81, 192, 76, 28, 2, 95, 91, 84, 6, 115, 50, 89, 47, 51, 108, 15, 107, 6, 120, 49, 117, 48, 35, 51, 35, 68, 47, 6, 117, 89, 0, 0, 0, 0, 6, 195, 36, 178, 197, 72, 5, 194, 88, 144, 76, 0, 6, 195, 8, 18, 192, 8, 15, 2, 95, 95, 125, 50, 72, 35, 51, 91, 47, 51, 13, 49, 0, 0, 0, 25, 2, 95, 93, 107, 6, 131, 51, 108, 15, 107, 6, 120, 49, 117, 48, 35, 51, 35, 68, 47, 6, 117, 89, 0, 0, 22, 2, 95, 92, 121, 65, 84, 115, 50, 72, 47, 15, 89, 49, 51, 121, 89, 47, 51, 13, 49, 0, 0, 0, 0, 0, 23, 2, 95, 96, 6, 121, 65, 84, 115, 50, 72, 47, 15, 119, 48, 123, 89, 47, 51, 6, 124, 83, 0, 0, 6, 195, 33, 83, 128, 76, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 7, 18, 22, 81, 51, 6, 120, 84, 110, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 4, 9, 1, 47, 51, 6, 117, 65, 119, 0, 0, 0, 0, 0, 0, 7, 196, 8, 194, 84, 80, 76, 0, 0, 0, 11, 70, 24, 148, 133, 24, 246, 0, 21, 0, 10, 0, 0, 0, 0, 0, 0, 0, 7, 131, 19, 195, 165, 72, 8, 0, 10, 4, 95, 35, 48, 57, 47, 120, 71, 0, 0, 0, 0, 0, 0, 8, 196, 21, 69, 5, 72, 72, 8, 0, 0, 0, 7, 195, 25, 32, 64, 72, 8, 0, 0, 0, 0, 0, 0, 0, 16, 4, 95, 35, 51, 50, 65, 115, 55, 55, 121, 65, 51, 124, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 33, 98, 83, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 16, 148, 211, 20, 76, 0, 6, 195, 85, 65, 78, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 67, 48, 241, 64, 55, 124, 0, 41, 0, 0, 0, 0, 7, 195, 76, 19, 84, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 76, 149, 20, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 164, 0, 2, 17, 67, 17, 67, 3, 115, 0, 3, 116, 0, 7, 6, 195, 165, 0, 2, 17, 67, 17, 67, 3, 121, 0, 3, 122, 0, 101, 3, 122, 108, 0, 7, 6, 195, 166, 0, 2, 17, 67, 17, 67, 3, 35, 0, 3, 116, 0, 2, 114, 3, 118, 0, 7, 6, 195, 182, 0, 2, 17, 67, 17, 67, 3, 113, 0, 3, 114, 0, 7, 6, 195, 184, 0, 2, 17, 67, 17, 67, 3, 113, 0, 3, 114, 0, 121, 3, 131, 0, 7, 6, 97, 0, 4, 2, 17, 67, 3, 35, 0, 101, 2, 17, 67, 17, 67, 0, 101, 3, 118, 0, 4, 2, 17, 67, 17, 67, 3, 119, 0, 2, 32, 0, 3, 120, 0, 97, 2, 17, 67, 17, 67, 3, 121, 0, 97, 3, 122, 0, 105, 3, 127, 0, 117, 3, 132, 0, 7, 6, 98, 0, 3, 71, 0, 98, 3, 71, 12, 0, 101, 8, 2, 21, 3, 71, 13, 0, 7, 6, 99, 0, 3, 49, 0, 99, 3, 49, 12, 0, 4, 2, 101, 105, 3, 89, 0, 2, 105, 0, 2, 121, 0, 2, 195, 184, 121, 0, 8, 2, 101, 0, 104, 3, 91, 0, 7, 6, 100, 0, 1, 114, 2, 32, 3, 0, 3, 72, 0, 100, 3, 72, 12, 0, 101, 116, 1, 10, 2, 32, 3, 72, 108, 0, 7, 6, 101, 0, 1, 10, 2, 17, 67, 32, 3, 13, 0, 116, 1, 10, 2, 32, 3, 13, 47, 0, 110, 1, 10, 2, 32, 3, 13, 50, 0, 110, 115, 1, 10, 2, 32, 3, 13, 50, 89, 0, 115, 1, 10, 2, 32, 3, 13, 89, 0, 2, 114, 17, 67, 3, 35, 0, 1, 10, 2, 32, 3, 108, 0, 4, 1, 29, 2, 109, 32, 3, 115, 0, 2, 17, 67, 17, 67, 0, 110, 101, 1, 10, 2, 32, 3, 115, 50, 108, 0, 3, 117, 0, 105, 3, 128, 0, 7, 6, 102, 0, 3, 83, 0, 7, 6, 103, 0, 4, 2, 101, 105, 3, 57, 0, 2, 105, 0, 2, 121, 0, 2, 195, 184, 121, 0, 106, 0, 2, 110, 3, 68, 0, 3, 81, 0, 103, 3, 81, 12, 0, 7, 6, 104, 0, 106, 3, 57, 0, 118, 3, 84, 0, 3, 107, 0, 7, 6, 105, 0, 4, 2, 17, 67, 17, 67, 3, 109, 0, 103, 1, 10, 2, 32, 0, 3, 110, 0, 7, 6, 106, 0, 3, 57, 0, 7, 6, 107, 0, 3, 49, 0, 107, 3, 49, 12, 0, 4, 2, 101, 105, 3, 101, 0, 2, 105, 0, 2, 121, 0, 2, 195, 184, 121, 0, 106, 0, 7, 6, 108, 0, 4, 3, 55, 0, 108, 2, 25, 0, 100, 3, 55, 55, 0, 106, 3, 57, 0, 7, 6, 109, 0, 4, 3, 65, 0, 109, 2, 25, 0, 7, 6, 110, 0, 4, 3, 50, 0, 110, 2, 25, 0, 100, 3, 50, 50, 0, 4, 2, 107, 3, 68, 0, 103, 0, 7, 6, 111, 0, 2, 17, 67, 17, 67, 3, 121, 0, 101, 3, 121, 108, 0, 4, 2, 110, 100, 3, 123, 0, 2, 114, 116, 0, 2, 115, 116, 0, 4, 3, 124, 0, 1, 98, 2, 114, 100, 0, 101, 1, 98, 21, 2, 32, 0, 105, 3, 129, 0, 7, 6, 112, 0, 3, 48, 0, 112, 3, 48, 12, 0, 7, 6, 113, 0, 3, 49, 0, 113, 3, 49, 12, 0, 117, 3, 49, 58, 0, 7, 6, 114, 0, 3, 51, 0, 115, 2, 32, 3, 91, 0, 7, 6, 115, 0, 4, 3, 89, 0, 1, 17, 65, 2, 108, 17, 65, 0, 115, 2, 32, 0, 115, 3, 89, 89, 0, 4, 1, 114, 3, 91, 0, 2, 108, 0, 99, 104, 0, 106, 0, 107, 2, 101, 105, 0, 107, 2, 105, 0, 107, 2, 121, 0, 107, 2, 195, 184, 121, 0, 107, 106, 0, 7, 6, 116, 0, 3, 47, 0, 116, 3, 47, 12, 0, 105, 2, 111, 110, 3, 91, 0, 106, 3, 95, 0, 7, 6, 117, 0, 2, 17, 67, 17, 67, 3, 125, 0, 3, 126, 0, 105, 3, 130, 0, 7, 6, 118, 0, 4, 3, 84, 0, 118, 2, 32, 0, 7, 6, 119, 0, 3, 84, 0, 7, 6, 120, 0, 2, 120, 3, 0, 3, 49, 89, 0, 8, 3, 89, 0, 7, 6, 121, 0, 2, 17, 67, 17, 67, 3, 111, 0, 3, 112, 0, 7, 6, 122, 0, 4, 122, 3, 88, 0, 122, 2, 32, 0, 3, 89, 0, 7, 6, 0, 4, 33, 1, 19, 3, 0, 46, 1, 46, 3, 0, 195, 169, 3, 6, 117, 0, 46, 2, 46, 3, 9, 0, 33, 3, 9, 6, 126, 47, 51, 124, 48, 89, 47, 115, 68, 50, 9, 0, 4, 45, 1, 32, 17, 65, 2, 32, 15, 3, 10, 0, 45, 1, 32, 17, 67, 2, 32, 15, 0, 46, 3, 48, 125, 68, 49, 47, 126, 65, 0, 45, 8, 32, 2, 32, 15, 3, 65, 110, 50, 126, 89, 0, 36, 3, 72, 121, 55, 55, 120, 51, 0, 195, 188, 3, 112, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts46 = FileInMemory_createWithData (4197, reinterpret_cast (&espeakdata_dicts46_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/no_dict", U"no"); Collection_addItem (me.peek(), espeakdata_dicts46.transfer()); static unsigned char espeakdata_dicts47_data[3416] = { 0, 4, 0, 0, 113, 11, 0, 0, 0, 0, 0, 0, 0, 22, 4, 95, 56, 77, 49, 72, 37, 49, 6, 36, 47, 36, 89, 37, 89, 58, 6, 35, 12, 37, 0, 5, 65, 4, 35, 0, 0, 33, 4, 95, 56, 77, 50, 72, 37, 49, 6, 36, 47, 36, 76, 36, 65, 35, 49, 106, 6, 39, 12, 55, 39, 89, 37, 89, 58, 6, 35, 12, 37, 0, 0, 0, 0, 9, 65, 8, 71, 37, 12, 37, 12, 0, 0, 0, 0, 0, 9, 65, 12, 89, 37, 12, 37, 12, 0, 0, 0, 0, 7, 196, 100, 16, 78, 36, 8, 0, 9, 65, 16, 72, 37, 12, 37, 12, 0, 0, 0, 0, 0, 8, 65, 20, 37, 12, 37, 12, 0, 0, 0, 0, 0, 8, 65, 24, 36, 12, 83, 40, 0, 0, 0, 0, 0, 9, 197, 12, 129, 78, 100, 80, 72, 28, 6, 65, 28, 111, 13, 0, 0, 0, 0, 6, 195, 100, 83, 129, 76, 0, 8, 65, 32, 36, 37, 76, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 65, 40, 75, 6, 36, 37, 0, 0, 0, 0, 0, 7, 65, 44, 49, 36, 37, 0, 0, 0, 0, 0, 8, 65, 48, 36, 12, 55, 37, 0, 0, 0, 0, 0, 8, 65, 52, 6, 36, 65, 40, 0, 0, 0, 0, 0, 8, 65, 56, 6, 36, 50, 37, 0, 0, 0, 0, 0, 8, 65, 60, 39, 12, 39, 12, 0, 0, 0, 0, 8, 196, 104, 83, 153, 20, 72, 28, 8, 196, 100, 83, 153, 20, 72, 28, 8, 196, 92, 83, 153, 20, 72, 28, 0, 10, 65, 64, 48, 6, 37, 12, 37, 12, 0, 0, 0, 0, 0, 7, 65, 68, 49, 57, 40, 0, 0, 0, 0, 0, 7, 65, 72, 35, 53, 36, 0, 0, 0, 0, 0, 9, 65, 76, 6, 36, 12, 89, 37, 0, 0, 0, 0, 0, 10, 65, 80, 47, 6, 37, 12, 37, 12, 0, 0, 0, 6, 195, 92, 19, 192, 76, 0, 0, 8, 65, 84, 40, 12, 40, 12, 0, 0, 0, 0, 7, 195, 80, 242, 193, 72, 28, 0, 10, 65, 88, 84, 6, 37, 12, 37, 12, 0, 0, 0, 0, 0, 16, 69, 76, 82, 207, 48, 240, 89, 36, 49, 6, 108, 12, 55, 108, 0, 11, 65, 92, 72, 35, 71, 35, 55, 57, 40, 0, 0, 0, 0, 6, 195, 92, 18, 197, 76, 0, 17, 4, 95, 49, 77, 49, 23, 6, 89, 20, 6, 37, 49, 36, 47, 36, 0, 10, 65, 96, 36, 49, 6, 36, 89, 36, 0, 0, 25, 4, 95, 49, 77, 50, 72, 37, 49, 6, 36, 47, 36, 76, 36, 55, 36, 49, 106, 6, 39, 12, 55, 39, 0, 0, 0, 6, 195, 76, 148, 201, 76, 0, 8, 65, 100, 58, 6, 35, 37, 0, 0, 0, 0, 0, 10, 65, 104, 88, 6, 36, 12, 47, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 5, 80, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 32, 17, 9, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 32, 147, 15, 76, 0, 0, 0, 0, 0, 0, 0, 8, 197, 45, 112, 86, 100, 240, 8, 0, 0, 0, 0, 19, 4, 95, 50, 77, 49, 72, 37, 49, 6, 36, 47, 36, 48, 6, 36, 72, 37, 0, 0, 30, 4, 95, 50, 77, 50, 72, 37, 49, 6, 36, 47, 36, 76, 36, 65, 35, 49, 106, 6, 39, 12, 55, 39, 48, 6, 36, 72, 37, 0, 0, 0, 7, 196, 4, 145, 8, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 32, 21, 1, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 8, 144, 72, 28, 0, 0, 0, 0, 0, 6, 195, 32, 146, 64, 72, 0, 19, 4, 95, 4, 16, 20, 83, 36, 12, 106, 36, 55, 40, 6, 35, 12, 50, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 4, 95, 51, 77, 49, 72, 37, 49, 6, 36, 47, 36, 47, 6, 35, 12, 53, 39, 0, 0, 31, 4, 95, 51, 77, 50, 72, 37, 49, 6, 36, 47, 36, 76, 36, 65, 35, 49, 106, 6, 39, 12, 55, 39, 47, 6, 35, 12, 53, 39, 0, 0, 0, 0, 0, 0, 0, 8, 196, 64, 147, 132, 36, 76, 8, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 37, 112, 80, 60, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 197, 89, 145, 78, 100, 80, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 53, 112, 64, 72, 28, 0, 0, 0, 13, 67, 80, 16, 129, 47, 10, 6, 35, 12, 71, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 45, 112, 76, 60, 8, 0, 0, 6, 194, 4, 240, 72, 8, 0, 0, 0, 9, 197, 53, 113, 78, 100, 80, 72, 28, 9, 197, 44, 21, 9, 44, 16, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 72, 83, 129, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 198, 92, 19, 1, 44, 147, 137, 8, 0, 0, 0, 0, 0, 0, 17, 67, 41, 85, 64, 79, 4, 40, 12, 57, 35, 0, 8, 81, 121, 97, 32, 0, 8, 196, 80, 20, 129, 4, 76, 8, 10, 68, 80, 19, 135, 84, 91, 40, 0, 28, 0, 0, 0, 0, 0, 8, 197, 64, 19, 129, 64, 240, 8, 0, 0, 0, 0, 8, 197, 48, 18, 201, 56, 144, 8, 8, 197, 36, 225, 193, 92, 16, 8, 0, 6, 195, 100, 243, 129, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 56, 224, 64, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 133, 49, 5, 14, 25, 5, 72, 28, 0, 0, 6, 194, 24, 144, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 4, 95, 53, 77, 49, 72, 37, 49, 6, 36, 47, 36, 105, 6, 35, 12, 50, 39, 0, 0, 0, 0, 30, 4, 95, 53, 77, 50, 72, 37, 49, 6, 36, 47, 36, 76, 36, 65, 35, 49, 106, 6, 39, 12, 55, 39, 105, 6, 35, 50, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 3, 95, 51, 88, 65, 35, 89, 6, 39, 12, 65, 36, 47, 6, 35, 12, 53, 39, 0, 0, 14, 3, 95, 48, 67, 55, 36, 49, 106, 6, 39, 55, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 48, 16, 72, 28, 0, 0, 19, 3, 95, 50, 67, 23, 65, 35, 49, 106, 6, 39, 55, 39, 48, 36, 72, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 3, 95, 51, 67, 23, 65, 35, 49, 106, 6, 39, 55, 39, 47, 6, 35, 12, 53, 39, 0, 0, 0, 0, 21, 4, 95, 54, 77, 49, 72, 37, 49, 6, 36, 47, 36, 47, 89, 6, 36, 12, 55, 35, 0, 0, 7, 196, 45, 112, 89, 20, 8, 0, 0, 32, 4, 95, 54, 77, 50, 72, 37, 49, 6, 36, 47, 36, 76, 36, 65, 35, 49, 106, 6, 39, 12, 55, 39, 47, 89, 6, 36, 12, 55, 35, 0, 0, 20, 3, 95, 55, 88, 65, 35, 89, 6, 39, 12, 65, 36, 91, 6, 40, 12, 48, 35, 0, 0, 19, 3, 95, 52, 67, 23, 65, 35, 49, 106, 6, 39, 55, 39, 6, 42, 50, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 3, 95, 53, 67, 23, 65, 35, 49, 106, 6, 39, 55, 39, 105, 6, 35, 12, 50, 39, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 49, 88, 55, 36, 89, 6, 39, 12, 65, 36, 0, 0, 22, 3, 95, 54, 67, 23, 65, 35, 49, 106, 6, 39, 55, 39, 47, 89, 6, 36, 12, 55, 35, 0, 0, 0, 0, 0, 0, 0, 0, 18, 3, 95, 50, 88, 65, 35, 89, 6, 39, 12, 65, 36, 48, 36, 72, 37, 0, 0, 20, 3, 95, 55, 67, 65, 35, 49, 106, 6, 39, 55, 39, 91, 6, 40, 12, 48, 35, 0, 0, 0, 0, 0, 0, 0, 6, 195, 52, 147, 73, 76, 0, 0, 22, 3, 95, 56, 67, 65, 35, 49, 106, 6, 39, 55, 39, 89, 37, 89, 58, 6, 35, 12, 37, 0, 0, 0, 0, 0, 0, 0, 0, 18, 3, 95, 52, 88, 65, 35, 89, 6, 39, 12, 65, 36, 6, 42, 50, 36, 0, 0, 21, 3, 95, 57, 67, 65, 35, 49, 106, 6, 39, 55, 39, 89, 36, 67, 6, 35, 50, 36, 0, 0, 0, 0, 0, 0, 0, 6, 194, 56, 16, 72, 8, 0, 20, 3, 95, 53, 88, 65, 35, 89, 6, 39, 12, 65, 36, 105, 6, 35, 12, 50, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 3, 95, 54, 88, 65, 35, 89, 6, 39, 12, 65, 36, 47, 89, 6, 36, 12, 55, 35, 0, 0, 0, 0, 0, 19, 4, 95, 55, 77, 49, 72, 37, 49, 6, 36, 47, 36, 91, 40, 12, 48, 35, 0, 0, 0, 0, 30, 4, 95, 55, 77, 50, 72, 37, 49, 6, 36, 47, 36, 76, 36, 65, 35, 49, 106, 6, 39, 12, 55, 39, 91, 40, 12, 48, 35, 0, 0, 10, 199, 36, 160, 80, 60, 181, 87, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 22, 3, 95, 56, 88, 65, 35, 89, 6, 39, 12, 65, 36, 89, 37, 89, 58, 6, 35, 12, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 3, 95, 57, 88, 65, 35, 89, 6, 39, 12, 65, 36, 89, 36, 67, 6, 35, 50, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 64, 16, 72, 28, 6, 194, 64, 16, 72, 28, 0, 0, 0, 17, 69, 72, 19, 15, 44, 16, 53, 2, 35, 55, 6, 108, 12, 49, 35, 0, 0, 0, 0, 13, 68, 80, 128, 66, 4, 47, 6, 35, 12, 71, 35, 0, 0, 9, 197, 45, 112, 77, 8, 16, 72, 8, 0, 0, 7, 195, 52, 147, 128, 72, 28, 0, 6, 195, 92, 83, 129, 76, 6, 195, 8, 243, 129, 72, 16, 4, 95, 48, 77, 52, 23, 71, 37, 55, 37, 6, 39, 50, 37, 0, 0, 0, 0, 16, 4, 95, 48, 77, 51, 23, 65, 37, 55, 37, 6, 39, 50, 37, 0, 0, 0, 16, 4, 95, 48, 77, 49, 6, 89, 20, 6, 37, 49, 36, 47, 36, 0, 0, 0, 0, 8, 196, 8, 16, 68, 4, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 100, 18, 197, 76, 0, 0, 0, 0, 0, 0, 12, 4, 95, 3, 9, 18, 49, 6, 36, 83, 35, 0, 32, 4, 95, 57, 77, 50, 72, 37, 49, 6, 36, 47, 36, 76, 36, 65, 35, 49, 106, 6, 39, 12, 55, 39, 89, 36, 67, 6, 35, 50, 36, 0, 0, 0, 0, 21, 4, 95, 57, 77, 49, 72, 37, 49, 6, 36, 47, 36, 89, 36, 67, 6, 35, 50, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 92, 85, 197, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 45, 84, 213, 16, 144, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 4, 225, 193, 60, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 8, 147, 1, 72, 8, 0, 0, 0, 0, 7, 195, 8, 19, 9, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 45, 85, 193, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 40, 20, 15, 8, 0, 0, 0, 0, 0, 0, 0, 0, 9, 198, 45, 80, 78, 104, 144, 64, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 92, 16, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 36, 160, 80, 60, 8, 0, 0, 0, 0, 7, 195, 89, 144, 64, 72, 28, 0, 0, 0, 0, 22, 67, 45, 112, 64, 49, 58, 35, 15, 49, 4, 40, 58, 35, 0, 8, 81, 107, 117, 119, 97, 32, 7, 195, 45, 112, 64, 72, 28, 7, 195, 45, 112, 64, 72, 28, 0, 7, 196, 44, 148, 200, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 45, 112, 79, 8, 0, 0, 0, 0, 0, 0, 6, 195, 48, 83, 129, 76, 28, 4, 95, 52, 77, 50, 72, 37, 49, 6, 36, 47, 36, 76, 36, 65, 35, 49, 106, 6, 39, 12, 55, 39, 42, 50, 36, 0, 0, 17, 4, 95, 52, 77, 49, 72, 37, 49, 6, 36, 47, 36, 42, 50, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 2, 95, 51, 47, 6, 35, 12, 53, 39, 0, 0, 10, 2, 95, 50, 48, 6, 36, 72, 37, 0, 0, 8, 2, 95, 49, 47, 36, 36, 0, 0, 13, 2, 95, 48, 55, 36, 83, 6, 36, 12, 55, 35, 0, 0, 11, 2, 95, 55, 91, 6, 40, 12, 48, 35, 0, 0, 12, 2, 95, 54, 47, 89, 6, 36, 12, 55, 35, 0, 0, 11, 2, 95, 53, 105, 6, 35, 12, 50, 39, 0, 0, 9, 2, 95, 52, 6, 42, 50, 36, 0, 0, 0, 0, 12, 2, 95, 57, 89, 36, 67, 6, 35, 50, 36, 0, 0, 6, 194, 100, 16, 72, 28, 13, 2, 95, 56, 89, 37, 89, 58, 6, 35, 12, 37, 0, 0, 0, 0, 8, 197, 57, 146, 78, 100, 144, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 67, 8, 160, 64, 84, 84, 79, 6, 35, 0, 6, 195, 36, 192, 64, 8, 7, 195, 12, 128, 64, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 104, 16, 72, 28, 0, 0, 0, 8, 197, 64, 19, 79, 40, 16, 8, 0, 6, 195, 104, 18, 197, 76, 0, 7, 195, 36, 194, 64, 76, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 8, 20, 201, 76, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 92, 19, 1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 33, 82, 207, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 45, 112, 67, 32, 240, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 4, 208, 64, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 199, 36, 194, 75, 92, 19, 66, 4, 8, 0, 0, 9, 198, 8, 17, 1, 48, 22, 65, 8, 0, 7, 195, 44, 19, 65, 76, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 100, 86, 69, 76, 0, 0, 0, 0, 0, 0, 0, 6, 97, 0, 4, 3, 35, 0, 2, 32, 0, 8, 2, 17, 67, 0, 8, 17, 67, 0, 2, 115, 3, 35, 12, 0, 7, 6, 98, 0, 3, 82, 0, 7, 6, 99, 0, 3, 49, 0, 104, 3, 76, 0, 7, 6, 100, 0, 3, 72, 0, 104, 3, 86, 0, 7, 6, 101, 0, 3, 36, 0, 1, 115, 3, 37, 0, 101, 3, 37, 38, 36, 12, 0, 7, 6, 102, 0, 3, 83, 0, 7, 6, 103, 0, 104, 3, 100, 0, 3, 106, 0, 8, 107, 3, 111, 0, 7, 6, 104, 0, 108, 3, 105, 0, 3, 107, 0, 7, 6, 105, 0, 3, 37, 0, 105, 3, 37, 12, 0, 7, 6, 106, 0, 3, 79, 0, 7, 6, 107, 0, 3, 49, 0, 104, 3, 101, 0, 7, 6, 108, 0, 3, 55, 0, 7, 6, 109, 0, 4, 1, 25, 2, 21, 21, 3, 23, 65, 0, 1, 25, 2, 98, 21, 21, 0, 1, 25, 2, 118, 21, 21, 0, 1, 25, 2, 119, 21, 21, 0, 4, 1, 25, 2, 17, 67, 3, 41, 0, 8, 0, 4, 3, 65, 0, 2, 17, 65, 0, 7, 6, 110, 0, 8, 3, 42, 0, 4, 8, 2, 103, 3, 43, 0, 8, 2, 103, 21, 21, 0, 8, 2, 107, 0, 8, 2, 107, 21, 21, 0, 4, 3, 50, 0, 2, 17, 65, 0, 2, 21, 21, 0, 4, 2, 99, 104, 3, 67, 0, 2, 106, 0, 121, 0, 4, 2, 103, 3, 68, 0, 2, 107, 0, 103, 0, 103, 39, 0, 7, 6, 111, 0, 111, 3, 39, 12, 0, 3, 108, 0, 7, 6, 112, 0, 3, 48, 0, 7, 6, 113, 0, 3, 49, 0, 7, 6, 114, 0, 3, 53, 0, 7, 6, 115, 0, 3, 89, 0, 2, 101, 3, 89, 20, 0, 101, 8, 116, 3, 89, 37, 12, 0, 7, 6, 116, 0, 3, 47, 0, 115, 101, 110, 3, 47, 89, 6, 36, 12, 50, 0, 104, 3, 47, 107, 0, 108, 3, 105, 0, 108, 104, 3, 110, 0, 7, 6, 117, 0, 3, 40, 0, 4, 8, 100, 3, 40, 12, 0, 117, 0, 7, 6, 118, 0, 3, 84, 0, 7, 6, 119, 0, 3, 58, 0, 7, 6, 120, 0, 3, 49, 89, 0, 7, 6, 121, 0, 3, 57, 0, 7, 6, 122, 0, 3, 88, 0, 7, 6, 0, 4, 42, 1, 42, 2, 42, 3, 0, 42, 42, 3, 0, 42, 1, 42, 42, 2, 32, 3, 24, 0, 37, 3, 35, 89, 37, 55, 37, 65, 37, 35, 0, 195, 180, 3, 39, 0, 42, 3, 67, 39, 47, 35, 0, 36, 3, 72, 39, 55, 35, 0, 197, 161, 8, 116, 3, 76, 0, 4, 197, 161, 3, 91, 0, 197, 161, 8, 112, 2, 104, 0, 195, 170, 3, 109, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts47 = FileInMemory_createWithData (3415, reinterpret_cast (&espeakdata_dicts47_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/nso_dict", U"nso"); Collection_addItem (me.peek(), espeakdata_dicts47.transfer()); static unsigned char espeakdata_dicts48_data[5257] = { 0, 4, 0, 0, 113, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 18, 224, 168, 149, 224, 169, 128, 224, 168, 172, 224, 169, 139, 224, 168, 176, 224, 168, 161, 49, 6, 112, 71, 39, 51, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 24, 224, 168, 184, 224, 169, 139, 224, 168, 171, 224, 168, 159, 224, 168, 181, 224, 168, 191, 224, 168, 133, 224, 168, 176, 89, 6, 121, 83, 47, 58, 116, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 95, 4, 16, 20, 10, 72, 121, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 51, 57, 122, 50, 13, 47, 6, 35, 55, 37, 0, 10, 3, 95, 50, 49, 113, 49, 12, 37, 0, 0, 13, 3, 95, 51, 56, 109, 142, 6, 109, 47, 12, 37, 0, 10, 3, 95, 50, 48, 84, 6, 37, 108, 0, 0, 10, 3, 95, 50, 51, 47, 6, 36, 37, 0, 0, 19, 4, 95, 224, 168, 135, 6, 113, 51, 113, 15, 89, 113, 107, 6, 35, 51, 37, 0, 10, 3, 95, 50, 50, 71, 6, 35, 37, 0, 0, 18, 4, 95, 224, 168, 134, 6, 116, 51, 109, 15, 49, 109, 50, 50, 6, 35, 0, 12, 3, 95, 50, 53, 48, 6, 109, 50, 145, 37, 0, 0, 11, 3, 95, 50, 52, 80, 6, 121, 84, 37, 0, 0, 12, 3, 95, 50, 55, 89, 13, 47, 6, 35, 37, 0, 0, 12, 3, 95, 50, 54, 144, 6, 109, 71, 12, 37, 0, 0, 13, 3, 95, 51, 49, 113, 49, 6, 109, 47, 12, 37, 0, 0, 10, 3, 95, 51, 48, 47, 6, 37, 108, 0, 0, 11, 3, 95, 51, 51, 47, 6, 36, 47, 37, 0, 0, 12, 3, 95, 51, 50, 71, 6, 109, 47, 12, 37, 0, 0, 11, 3, 95, 51, 53, 48, 6, 127, 47, 37, 0, 0, 11, 3, 95, 51, 52, 80, 6, 130, 47, 37, 0, 0, 11, 3, 95, 51, 55, 89, 6, 127, 47, 37, 0, 0, 12, 3, 95, 51, 54, 144, 6, 109, 47, 12, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 226, 130, 185, 34, 40, 48, 37, 0, 0, 0, 0, 0, 12, 3, 95, 55, 57, 122, 66, 6, 35, 89, 37, 0, 11, 3, 95, 54, 49, 113, 49, 6, 35, 142, 0, 0, 14, 3, 95, 55, 56, 109, 142, 6, 109, 47, 12, 13, 51, 0, 11, 3, 95, 54, 48, 89, 6, 109, 142, 12, 0, 0, 9, 3, 95, 48, 67, 89, 6, 121, 0, 13, 3, 95, 54, 51, 47, 13, 51, 6, 36, 142, 108, 0, 0, 11, 3, 95, 54, 50, 71, 6, 35, 142, 108, 0, 0, 10, 3, 95, 54, 53, 48, 6, 127, 142, 0, 0, 11, 3, 95, 54, 52, 80, 6, 121, 142, 108, 0, 0, 14, 3, 95, 54, 55, 89, 13, 47, 6, 35, 108, 13, 142, 0, 0, 11, 3, 95, 54, 54, 144, 113, 6, 35, 142, 0, 0, 15, 3, 95, 55, 49, 113, 49, 108, 6, 109, 47, 12, 13, 51, 0, 0, 11, 3, 224, 165, 132, 35, 72, 72, 35, 49, 0, 13, 3, 95, 55, 48, 89, 6, 109, 47, 12, 13, 51, 0, 0, 15, 3, 95, 55, 51, 47, 13, 108, 6, 109, 47, 12, 13, 51, 0, 0, 15, 3, 95, 55, 50, 71, 13, 108, 6, 109, 47, 12, 13, 51, 0, 0, 16, 3, 95, 55, 53, 48, 13, 50, 79, 6, 109, 47, 12, 13, 51, 0, 0, 15, 3, 95, 55, 52, 80, 121, 108, 6, 109, 47, 12, 13, 51, 0, 0, 15, 3, 95, 55, 55, 89, 13, 47, 6, 109, 47, 12, 13, 51, 0, 0, 15, 3, 95, 55, 54, 144, 113, 108, 6, 109, 47, 12, 13, 51, 0, 0, 10, 3, 95, 49, 57, 6, 122, 50, 37, 0, 0, 12, 3, 95, 49, 56, 109, 142, 6, 35, 51, 128, 0, 0, 19, 4, 95, 224, 168, 148, 6, 116, 51, 109, 15, 49, 109, 50, 121, 51, 6, 35, 0, 0, 0, 0, 0, 20, 4, 95, 224, 168, 144, 6, 116, 51, 109, 15, 72, 122, 55, 6, 35, 84, 35, 65, 0, 0, 17, 4, 95, 224, 168, 147, 6, 122, 51, 109, 15, 107, 39, 51, 6, 35, 0, 0, 13, 3, 95, 50, 57, 122, 50, 6, 109, 47, 12, 37, 0, 12, 3, 95, 49, 49, 81, 113, 6, 35, 51, 128, 0, 0, 11, 3, 95, 50, 56, 109, 142, 6, 35, 37, 0, 10, 3, 95, 49, 48, 72, 6, 109, 89, 0, 0, 11, 3, 95, 49, 51, 47, 6, 36, 51, 128, 0, 0, 18, 4, 95, 224, 168, 143, 6, 113, 51, 113, 15, 55, 6, 35, 84, 35, 65, 0, 11, 3, 95, 49, 50, 71, 6, 35, 51, 128, 0, 0, 14, 3, 95, 49, 53, 48, 6, 109, 50, 72, 13, 51, 128, 0, 0, 18, 4, 95, 224, 168, 137, 6, 122, 51, 109, 15, 6, 121, 50, 49, 35, 51, 0, 11, 3, 95, 49, 52, 80, 6, 121, 72, 128, 0, 0, 19, 4, 95, 224, 168, 136, 6, 113, 51, 113, 15, 71, 113, 107, 6, 35, 51, 37, 0, 13, 3, 95, 49, 55, 89, 13, 47, 6, 35, 51, 128, 0, 0, 11, 3, 95, 49, 54, 89, 6, 39, 62, 128, 0, 0, 20, 12, 224, 168, 136, 224, 168, 174, 224, 169, 135, 224, 168, 178, 6, 112, 65, 150, 55, 0, 21, 4, 95, 224, 168, 138, 6, 122, 51, 109, 15, 72, 122, 55, 6, 116, 50, 49, 35, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 52, 57, 6, 122, 66, 125, 79, 35, 0, 0, 12, 3, 224, 165, 164, 141, 6, 109, 50, 141, 37, 0, 15, 3, 95, 52, 56, 109, 142, 12, 13, 47, 6, 35, 55, 37, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 53, 57, 122, 66, 6, 35, 142, 0, 14, 3, 95, 52, 49, 113, 49, 13, 47, 6, 35, 55, 37, 0, 0, 15, 3, 95, 53, 56, 6, 109, 142, 12, 13, 84, 125, 79, 35, 0, 11, 3, 95, 52, 48, 80, 6, 35, 55, 37, 0, 0, 15, 3, 95, 52, 51, 47, 13, 51, 13, 47, 6, 35, 55, 37, 0, 0, 13, 3, 95, 52, 50, 71, 13, 47, 6, 35, 55, 37, 0, 0, 16, 3, 95, 52, 53, 48, 13, 50, 79, 13, 47, 6, 35, 55, 37, 0, 0, 13, 3, 95, 52, 52, 80, 121, 47, 6, 35, 55, 37, 0, 0, 14, 3, 95, 52, 55, 89, 13, 50, 47, 6, 35, 55, 37, 0, 0, 12, 3, 95, 52, 54, 144, 113, 6, 35, 55, 37, 0, 0, 14, 3, 95, 54, 57, 122, 66, 6, 109, 47, 12, 13, 51, 0, 14, 3, 95, 53, 49, 6, 113, 49, 13, 84, 125, 79, 35, 0, 0, 12, 3, 95, 54, 56, 109, 142, 12, 6, 35, 142, 0, 13, 3, 95, 53, 48, 48, 13, 50, 79, 6, 35, 108, 0, 0, 15, 3, 95, 53, 51, 47, 6, 109, 51, 13, 84, 125, 79, 35, 0, 0, 13, 3, 95, 53, 50, 71, 6, 109, 84, 125, 79, 35, 0, 0, 15, 3, 95, 53, 53, 48, 6, 109, 80, 13, 84, 125, 79, 35, 0, 0, 13, 3, 95, 53, 52, 80, 6, 109, 51, 125, 79, 35, 0, 0, 15, 3, 95, 53, 55, 89, 6, 109, 47, 13, 84, 125, 79, 35, 0, 0, 13, 3, 95, 53, 54, 144, 6, 109, 48, 125, 79, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 56, 57, 122, 66, 128, 50, 13, 84, 6, 36, 68, 0, 0, 12, 3, 95, 56, 56, 109, 142, 6, 35, 89, 37, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 57, 57, 50, 113, 51, 6, 109, 50, 50, 13, 84, 126, 0, 12, 3, 95, 56, 49, 113, 49, 6, 35, 89, 37, 0, 0, 14, 3, 95, 57, 56, 109, 142, 6, 35, 50, 13, 84, 126, 0, 11, 3, 95, 56, 48, 6, 109, 89, 89, 37, 0, 0, 14, 3, 95, 56, 51, 47, 13, 51, 13, 6, 35, 89, 37, 0, 0, 12, 3, 95, 56, 50, 71, 113, 6, 35, 89, 37, 0, 0, 14, 3, 95, 56, 53, 48, 13, 50, 79, 6, 35, 89, 37, 0, 0, 13, 3, 95, 56, 52, 80, 13, 51, 6, 35, 89, 37, 0, 0, 13, 3, 95, 56, 55, 89, 13, 47, 6, 35, 89, 37, 0, 0, 12, 3, 95, 56, 54, 144, 113, 6, 35, 89, 37, 0, 0, 16, 3, 95, 57, 49, 113, 49, 13, 6, 35, 50, 13, 84, 4, 126, 0, 0, 12, 3, 95, 57, 48, 50, 6, 109, 71, 12, 36, 0, 0, 16, 3, 95, 57, 51, 47, 13, 51, 13, 6, 35, 50, 13, 84, 126, 0, 0, 16, 3, 95, 57, 50, 71, 113, 38, 6, 35, 50, 13, 84, 4, 126, 0, 0, 15, 3, 95, 57, 53, 48, 13, 80, 6, 35, 50, 13, 84, 126, 0, 0, 15, 3, 95, 57, 52, 80, 13, 51, 6, 35, 50, 13, 84, 126, 0, 0, 15, 3, 95, 57, 55, 89, 13, 47, 6, 35, 50, 13, 84, 126, 0, 0, 14, 3, 95, 57, 54, 144, 113, 6, 35, 50, 13, 84, 126, 0, 0, 10, 3, 224, 168, 133, 6, 116, 51, 109, 0, 12, 3, 224, 169, 141, 107, 109, 55, 109, 50, 47, 0, 0, 13, 3, 224, 169, 140, 49, 109, 50, 6, 121, 51, 35, 0, 0, 0, 0, 0, 13, 3, 224, 169, 136, 72, 13, 55, 6, 35, 84, 128, 0, 0, 11, 3, 224, 169, 139, 107, 39, 51, 6, 35, 0, 12, 3, 224, 168, 131, 84, 37, 89, 35, 51, 81, 0, 0, 12, 3, 224, 168, 130, 71, 113, 50, 72, 6, 37, 0, 0, 0, 0, 11, 3, 224, 169, 135, 55, 6, 35, 84, 128, 0, 0, 0, 11, 3, 224, 169, 129, 121, 50, 49, 35, 51, 0, 0, 13, 3, 224, 169, 128, 71, 113, 107, 6, 35, 51, 37, 0, 0, 0, 15, 3, 224, 169, 130, 72, 122, 55, 6, 116, 50, 49, 35, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 95, 48, 77, 52, 6, 109, 51, 13, 71, 0, 0, 13, 4, 95, 48, 77, 53, 146, 6, 109, 51, 13, 71, 0, 0, 12, 4, 95, 48, 77, 50, 55, 6, 109, 146, 12, 0, 0, 13, 4, 95, 48, 77, 51, 49, 6, 109, 51, 39, 51, 0, 0, 0, 13, 4, 95, 48, 77, 49, 108, 13, 79, 6, 35, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 224, 168, 190, 49, 109, 50, 50, 6, 35, 0, 0, 13, 3, 224, 168, 191, 89, 113, 107, 6, 35, 51, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 224, 169, 178, 6, 113, 51, 113, 0, 0, 10, 3, 224, 169, 179, 6, 122, 51, 109, 0, 0, 12, 3, 224, 169, 176, 47, 113, 48, 48, 6, 37, 0, 0, 11, 3, 224, 169, 177, 109, 72, 72, 109, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 18, 224, 168, 181, 224, 169, 136, 224, 168, 172, 224, 168, 170, 224, 169, 135, 224, 168, 156, 58, 6, 116, 71, 48, 150, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 15, 224, 168, 184, 224, 168, 176, 224, 168, 149, 224, 168, 190, 224, 168, 176, 89, 51, 13, 49, 6, 35, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 18, 224, 168, 184, 224, 168, 176, 224, 168, 149, 224, 168, 190, 224, 168, 176, 224, 169, 128, 89, 51, 13, 49, 6, 35, 51, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 2, 95, 51, 47, 6, 125, 50, 0, 0, 8, 2, 95, 50, 72, 6, 39, 0, 0, 9, 2, 95, 49, 6, 113, 49, 12, 0, 0, 10, 2, 95, 48, 88, 6, 37, 51, 39, 0, 0, 10, 2, 95, 55, 89, 6, 109, 47, 12, 0, 0, 8, 2, 95, 54, 144, 6, 36, 0, 0, 10, 2, 95, 53, 48, 6, 109, 50, 79, 0, 0, 9, 2, 95, 52, 80, 6, 35, 51, 0, 0, 0, 0, 8, 2, 95, 57, 50, 6, 130, 0, 0, 9, 2, 95, 56, 6, 109, 142, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 20, 0, 102, 10, 0, 0, 48, 0, 0, 0, 103, 10, 0, 0, 49, 0, 0, 0, 104, 10, 0, 0, 50, 0, 0, 0, 105, 10, 0, 0, 51, 0, 0, 0, 106, 10, 0, 0, 52, 0, 0, 0, 107, 10, 0, 0, 53, 0, 0, 0, 108, 10, 0, 0, 54, 0, 0, 0, 109, 10, 0, 0, 55, 0, 0, 0, 110, 10, 0, 0, 56, 0, 0, 0, 111, 10, 0, 0, 57, 0, 0, 0, 230, 10, 0, 0, 48, 0, 0, 0, 231, 10, 0, 0, 49, 0, 0, 0, 232, 10, 0, 0, 50, 0, 0, 0, 233, 10, 0, 0, 51, 0, 0, 0, 234, 10, 0, 0, 52, 0, 0, 0, 235, 10, 0, 0, 53, 0, 0, 0, 236, 10, 0, 0, 54, 0, 0, 0, 237, 10, 0, 0, 55, 0, 0, 0, 238, 10, 0, 0, 56, 0, 0, 0, 239, 10, 0, 0, 57, 0, 0, 0, 56, 10, 60, 10, 54, 10, 0, 0, 50, 10, 60, 10, 51, 10, 0, 0, 22, 10, 60, 10, 89, 10, 0, 0, 23, 10, 60, 10, 90, 10, 0, 0, 28, 10, 60, 10, 91, 10, 0, 0, 43, 10, 60, 10, 94, 10, 0, 0, 5, 10, 72, 10, 16, 10, 0, 0, 5, 10, 62, 10, 6, 10, 0, 0, 5, 10, 76, 10, 20, 10, 0, 0, 114, 10, 64, 10, 8, 10, 0, 0, 114, 10, 63, 10, 7, 10, 0, 0, 114, 10, 71, 10, 15, 10, 0, 0, 115, 10, 65, 10, 9, 10, 0, 0, 115, 10, 66, 10, 10, 10, 0, 0, 0, 0, 0, 0, 6, 1, 3, 0, 3, 68, 0, 7, 6, 1, 4, 0, 3, 107, 0, 7, 6, 1, 6, 0, 3, 4, 109, 0, 4, 224, 168, 130, 3, 129, 0, 224, 169, 176, 0, 7, 6, 1, 7, 0, 3, 35, 0, 4, 224, 168, 130, 3, 128, 0, 224, 169, 176, 0, 7, 6, 1, 8, 0, 3, 113, 0, 4, 224, 168, 130, 3, 125, 0, 224, 169, 176, 0, 7, 6, 1, 9, 0, 3, 37, 0, 4, 224, 168, 130, 3, 124, 0, 224, 169, 176, 0, 7, 6, 1, 10, 0, 3, 122, 0, 4, 224, 168, 130, 3, 132, 0, 224, 169, 176, 0, 7, 6, 1, 11, 0, 3, 40, 0, 4, 224, 168, 130, 3, 133, 0, 224, 169, 176, 0, 7, 6, 1, 16, 0, 3, 36, 0, 4, 224, 168, 130, 3, 126, 0, 224, 169, 176, 0, 7, 6, 1, 17, 0, 3, 116, 0, 4, 224, 168, 130, 3, 127, 0, 224, 169, 176, 0, 7, 6, 1, 20, 0, 3, 39, 0, 4, 224, 168, 130, 3, 131, 0, 224, 169, 176, 0, 7, 6, 1, 21, 0, 3, 121, 0, 4, 224, 168, 130, 3, 130, 0, 224, 169, 176, 0, 7, 6, 1, 22, 0, 4, 1, 21, 2, 32, 3, 49, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 49, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 49, 12, 109, 0, 3, 49, 109, 0, 7, 6, 1, 23, 0, 4, 1, 21, 2, 32, 3, 146, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 146, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 146, 12, 109, 0, 3, 146, 109, 0, 7, 6, 1, 24, 0, 4, 1, 21, 2, 32, 3, 81, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 81, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 81, 12, 109, 0, 3, 81, 109, 0, 7, 6, 1, 25, 0, 8, 2, 17, 66, 3, 49, 149, 0, 8, 3, 49, 149, 109, 0, 4, 1, 21, 2, 32, 3, 147, 0, 2, 17, 66, 0, 3, 147, 109, 0, 7, 6, 1, 26, 0, 4, 1, 21, 2, 32, 3, 68, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 68, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 68, 12, 109, 0, 3, 68, 109, 0, 7, 6, 1, 27, 0, 4, 1, 21, 2, 32, 3, 80, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 80, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 80, 12, 109, 0, 3, 80, 109, 0, 7, 6, 1, 28, 0, 4, 1, 21, 2, 32, 3, 144, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 144, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 144, 12, 109, 0, 3, 144, 109, 0, 7, 6, 1, 29, 0, 4, 1, 21, 2, 32, 3, 79, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 79, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 79, 12, 109, 0, 3, 79, 109, 0, 7, 6, 1, 30, 0, 8, 2, 17, 66, 3, 80, 149, 0, 8, 3, 80, 149, 109, 0, 4, 1, 21, 2, 32, 3, 145, 0, 2, 17, 66, 0, 3, 145, 109, 0, 7, 6, 1, 31, 0, 4, 1, 21, 2, 32, 3, 67, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 67, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 67, 12, 109, 0, 3, 67, 109, 0, 7, 6, 1, 32, 0, 4, 1, 21, 2, 32, 3, 140, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 140, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 140, 12, 109, 0, 3, 140, 109, 0, 7, 6, 1, 33, 0, 4, 1, 21, 2, 32, 3, 142, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 142, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 142, 12, 109, 0, 3, 142, 109, 0, 7, 6, 1, 34, 0, 4, 1, 21, 2, 32, 3, 141, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 141, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 141, 12, 109, 0, 3, 141, 109, 0, 7, 6, 1, 35, 0, 8, 2, 17, 66, 3, 140, 0, 8, 3, 140, 149, 109, 0, 4, 1, 21, 2, 32, 3, 143, 0, 2, 17, 66, 0, 3, 143, 109, 0, 7, 6, 1, 36, 0, 4, 1, 21, 2, 32, 3, 66, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 66, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 66, 12, 109, 0, 3, 66, 109, 0, 7, 6, 1, 37, 0, 4, 1, 21, 2, 32, 3, 47, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 47, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 47, 12, 109, 0, 3, 47, 109, 0, 7, 6, 1, 38, 0, 4, 1, 21, 2, 32, 3, 138, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 138, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 138, 12, 109, 0, 3, 138, 109, 0, 7, 6, 1, 39, 0, 4, 1, 21, 2, 32, 3, 72, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 72, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 72, 12, 109, 0, 3, 72, 109, 0, 7, 6, 1, 40, 0, 8, 2, 17, 66, 3, 47, 149, 0, 8, 3, 47, 149, 109, 0, 4, 1, 21, 2, 32, 3, 139, 0, 2, 17, 66, 0, 3, 139, 109, 0, 7, 6, 1, 41, 0, 4, 1, 21, 2, 32, 3, 50, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 50, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 50, 12, 109, 0, 3, 50, 109, 0, 7, 6, 1, 43, 0, 4, 1, 21, 2, 32, 3, 48, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 48, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 48, 12, 109, 0, 3, 48, 109, 0, 7, 6, 1, 44, 0, 4, 1, 21, 2, 32, 3, 136, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 136, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 136, 12, 109, 0, 3, 136, 109, 0, 7, 6, 1, 45, 0, 4, 1, 21, 2, 32, 3, 71, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 71, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 71, 12, 109, 0, 3, 71, 109, 0, 7, 6, 1, 46, 0, 8, 2, 17, 66, 3, 48, 149, 0, 8, 3, 48, 149, 109, 0, 4, 1, 21, 2, 32, 3, 137, 0, 2, 17, 66, 0, 3, 137, 109, 0, 7, 6, 1, 47, 0, 4, 1, 21, 2, 32, 3, 65, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 65, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 65, 12, 109, 0, 3, 65, 109, 0, 7, 6, 1, 48, 0, 4, 1, 21, 2, 32, 3, 57, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 57, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 57, 12, 109, 0, 3, 57, 109, 0, 7, 6, 1, 49, 0, 4, 1, 21, 2, 32, 3, 51, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 51, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 51, 12, 109, 0, 3, 51, 109, 0, 7, 6, 1, 51, 0, 4, 1, 21, 2, 32, 3, 55, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 55, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 55, 12, 109, 0, 3, 55, 109, 0, 7, 6, 1, 52, 0, 4, 1, 21, 2, 32, 3, 62, 0, 2, 17, 66, 0, 3, 62, 109, 0, 7, 6, 1, 54, 0, 4, 1, 21, 2, 32, 3, 84, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 84, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 84, 12, 109, 0, 3, 84, 109, 0, 7, 6, 1, 55, 0, 4, 1, 21, 2, 32, 3, 91, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 91, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 91, 12, 109, 0, 3, 91, 109, 0, 7, 6, 1, 57, 0, 4, 1, 21, 2, 32, 3, 89, 0, 2, 17, 66, 0, 4, 1, 177, 169, 224, 2, 17, 66, 3, 89, 12, 0, 1, 177, 169, 224, 2, 32, 0, 1, 177, 169, 224, 3, 89, 12, 109, 0, 3, 89, 109, 0, 7, 6, 1, 58, 0, 4, 1, 21, 2, 32, 3, 108, 0, 2, 17, 66, 0, 3, 108, 109, 0, 7, 6, 1, 61, 0, 3, 0, 7, 6, 1, 63, 0, 3, 35, 0, 4, 224, 168, 130, 3, 128, 0, 224, 169, 176, 0, 7, 6, 1, 64, 0, 3, 113, 0, 4, 224, 168, 130, 3, 125, 0, 224, 169, 176, 0, 7, 6, 1, 65, 0, 3, 37, 0, 4, 224, 168, 130, 3, 124, 0, 224, 169, 176, 0, 7, 6, 1, 66, 0, 3, 122, 0, 4, 224, 168, 130, 3, 132, 0, 224, 169, 176, 0, 7, 6, 1, 67, 0, 3, 40, 0, 4, 224, 168, 130, 3, 133, 0, 224, 169, 176, 0, 7, 6, 1, 72, 0, 3, 36, 0, 4, 224, 168, 130, 3, 126, 0, 224, 169, 176, 0, 7, 6, 1, 73, 0, 3, 116, 0, 4, 224, 168, 130, 3, 127, 0, 224, 169, 176, 0, 7, 6, 1, 76, 0, 3, 39, 0, 4, 224, 168, 130, 3, 131, 0, 224, 169, 176, 0, 7, 6, 1, 77, 0, 3, 121, 0, 4, 224, 168, 130, 3, 130, 0, 224, 169, 176, 0, 7, 6, 1, 78, 0, 3, 0, 7, 6, 1, 90, 0, 4, 1, 21, 2, 32, 3, 101, 0, 2, 17, 66, 0, 3, 101, 109, 0, 7, 6, 1, 91, 0, 4, 1, 21, 2, 32, 3, 100, 0, 2, 17, 66, 0, 3, 100, 109, 0, 7, 6, 1, 92, 0, 4, 1, 21, 2, 32, 3, 88, 0, 2, 17, 66, 0, 3, 88, 109, 0, 7, 6, 1, 93, 0, 4, 1, 21, 2, 32, 3, 52, 0, 2, 17, 66, 0, 3, 52, 109, 0, 7, 6, 1, 95, 0, 4, 1, 21, 2, 32, 3, 83, 0, 2, 17, 66, 0, 3, 83, 109, 0, 7, 6, 1, 113, 0, 3, 50, 0, 7, 6, 1, 114, 0, 3, 0, 7, 6, 1, 115, 0, 3, 37, 0, 7, 6, 1, 116, 0, 3, 40, 0, 7, 6, 224, 171, 0, 160, 3, 44, 0, 7, 6, 0, 37, 3, 48, 109, 89, 116, 50, 47, 0, 36, 3, 72, 121, 55, 109, 51, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts48 = FileInMemory_createWithData (5256, reinterpret_cast (&espeakdata_dicts48_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/pa_dict", U"pa"); Collection_addItem (me.peek(), espeakdata_dicts48.transfer()); static unsigned char espeakdata_dicts49_data[2134] = { 0, 4, 0, 0, 163, 6, 0, 0, 0, 0, 0, 0, 0, 4, 193, 4, 76, 0, 0, 0, 0, 6, 65, 8, 71, 36, 0, 0, 0, 0, 0, 6, 65, 12, 89, 36, 0, 0, 0, 0, 0, 6, 65, 16, 72, 36, 0, 0, 0, 0, 0, 4, 193, 20, 76, 0, 0, 0, 0, 6, 65, 24, 109, 83, 0, 0, 0, 0, 0, 6, 65, 28, 81, 36, 0, 0, 0, 0, 0, 6, 65, 32, 107, 35, 0, 0, 0, 0, 0, 5, 193, 36, 76, 8, 0, 0, 0, 0, 6, 65, 40, 57, 36, 0, 0, 0, 6, 195, 64, 244, 128, 76, 0, 0, 6, 65, 44, 49, 35, 0, 0, 0, 0, 0, 6, 65, 48, 109, 55, 0, 0, 0, 0, 0, 6, 65, 52, 109, 65, 0, 0, 0, 0, 0, 6, 65, 56, 109, 50, 0, 0, 0, 0, 0, 5, 193, 60, 76, 8, 0, 0, 0, 0, 6, 65, 64, 48, 36, 0, 0, 0, 0, 0, 6, 65, 68, 49, 112, 0, 0, 0, 0, 0, 6, 65, 72, 109, 51, 0, 0, 0, 0, 0, 6, 65, 76, 109, 89, 0, 0, 0, 0, 0, 6, 65, 80, 47, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 88, 84, 36, 0, 0, 0, 0, 0, 6, 65, 92, 58, 36, 0, 0, 0, 0, 0, 7, 65, 96, 109, 49, 89, 0, 0, 0, 0, 0, 11, 65, 100, 37, 81, 51, 6, 109, 49, 0, 14, 5, 193, 100, 72, 8, 0, 0, 0, 0, 7, 65, 104, 88, 109, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 95, 4, 16, 20, 10, 49, 110, 65, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 16, 144, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 8, 240, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 20, 192, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 51, 88, 47, 51, 6, 37, 50, 47, 35, 0, 0, 11, 3, 95, 48, 67, 89, 57, 6, 36, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 49, 49, 72, 57, 36, 89, 6, 40, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 55, 88, 89, 36, 47, 6, 36, 50, 47, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 52, 16, 8, 0, 11, 3, 95, 49, 88, 72, 57, 6, 36, 89, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 45, 80, 76, 28, 0, 12, 3, 95, 50, 88, 71, 6, 37, 50, 47, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 52, 88, 49, 58, 35, 51, 6, 36, 50, 47, 35, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 56, 16, 76, 0, 16, 3, 95, 53, 88, 89, 37, 50, 49, 58, 6, 36, 50, 47, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 54, 88, 89, 36, 89, 6, 36, 50, 47, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 56, 88, 39, 76, 6, 36, 50, 47, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 57, 88, 50, 39, 71, 6, 36, 50, 47, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 95, 48, 77, 50, 65, 37, 6, 39, 50, 0, 0, 11, 195, 44, 83, 128, 72, 28, 81, 115, 117, 32, 0, 0, 11, 4, 95, 48, 77, 49, 65, 6, 37, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 52, 144, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 56, 244, 192, 76, 0, 0, 0, 0, 0, 0, 13, 4, 95, 1, 3, 21, 89, 49, 109, 51, 48, 37, 0, 0, 0, 0, 0, 7, 131, 195, 178, 6, 76, 8, 0, 5, 194, 48, 240, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 8, 244, 207, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 80, 16, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 77, 80, 76, 0, 0, 0, 0, 0, 5, 130, 195, 161, 43, 0, 0, 0, 0, 5, 130, 195, 173, 43, 0, 0, 0, 0, 5, 130, 195, 169, 43, 0, 0, 0, 0, 0, 0, 5, 130, 195, 179, 43, 0, 0, 8, 2, 195, 177, 36, 67, 36, 0, 0, 0, 0, 0, 0, 5, 130, 195, 186, 43, 0, 0, 0, 0, 0, 0, 0, 6, 195, 4, 35, 192, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 2, 95, 1, 35, 0, 0, 0, 0, 0, 6, 2, 95, 5, 36, 0, 0, 0, 0, 6, 2, 95, 9, 37, 0, 0, 0, 6, 2, 95, 15, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 2, 95, 25, 37, 81, 51, 6, 109, 49, 0, 14, 0, 0, 0, 0, 0, 0, 0, 7, 196, 4, 193, 213, 56, 76, 0, 0, 0, 0, 0, 0, 0, 6, 195, 16, 83, 128, 76, 6, 195, 56, 19, 128, 76, 0, 0, 0, 0, 0, 0, 0, 0, 10, 2, 95, 51, 47, 51, 6, 36, 89, 0, 0, 9, 2, 95, 50, 72, 6, 39, 89, 0, 0, 9, 2, 95, 49, 6, 40, 50, 40, 0, 0, 10, 2, 95, 48, 88, 6, 36, 51, 39, 0, 0, 10, 2, 95, 55, 91, 6, 36, 47, 36, 0, 0, 10, 2, 95, 54, 89, 6, 109, 57, 89, 0, 0, 11, 2, 95, 53, 89, 6, 37, 50, 49, 40, 0, 0, 12, 2, 95, 52, 49, 58, 35, 47, 6, 36, 51, 0, 0, 0, 0, 11, 2, 95, 57, 50, 58, 6, 36, 71, 36, 0, 0, 9, 2, 95, 56, 6, 39, 76, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 95, 7, 18, 22, 81, 51, 35, 84, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 194, 80, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 84, 224, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 80, 16, 129, 80, 16, 76, 0, 0, 6, 195, 4, 210, 64, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 168, 0, 3, 6, 109, 0, 7, 6, 195, 177, 0, 3, 67, 0, 7, 6, 195, 178, 0, 3, 6, 110, 0, 7, 6, 195, 185, 0, 3, 113, 0, 105, 3, 113, 57, 0, 7, 6, 195, 188, 0, 3, 112, 0, 105, 3, 112, 57, 0, 7, 6, 97, 0, 3, 35, 0, 97, 3, 35, 12, 0, 105, 3, 117, 0, 7, 6, 98, 0, 3, 71, 0, 7, 6, 99, 0, 3, 49, 0, 104, 3, 76, 0, 2, 17, 71, 3, 89, 0, 7, 6, 100, 0, 3, 72, 0, 106, 3, 75, 0, 7, 6, 101, 0, 3, 36, 0, 101, 3, 36, 12, 0, 117, 3, 36, 58, 0, 105, 3, 118, 0, 7, 6, 102, 0, 3, 83, 0, 7, 6, 103, 0, 4, 3, 81, 0, 117, 2, 17, 71, 0, 2, 17, 71, 3, 101, 0, 7, 6, 104, 0, 3, 107, 0, 7, 6, 105, 0, 3, 37, 0, 4, 1, 17, 65, 2, 25, 3, 57, 0, 2, 17, 65, 0, 106, 3, 118, 0, 7, 6, 106, 0, 3, 57, 0, 7, 6, 107, 0, 3, 49, 0, 7, 6, 108, 0, 3, 55, 0, 7, 6, 109, 0, 3, 65, 0, 7, 6, 110, 0, 3, 50, 0, 97, 110, 1, 10, 2, 32, 3, 50, 2, 35, 50, 0, 2, 32, 3, 68, 0, 7, 6, 111, 0, 3, 39, 0, 111, 3, 39, 12, 0, 117, 3, 39, 58, 0, 101, 3, 40, 0, 7, 6, 112, 0, 3, 48, 0, 7, 6, 113, 0, 3, 49, 0, 117, 2, 17, 65, 3, 49, 58, 0, 117, 105, 3, 49, 58, 37, 0, 7, 6, 114, 0, 3, 51, 0, 7, 6, 115, 0, 3, 89, 0, 104, 3, 91, 0, 7, 6, 116, 0, 3, 47, 0, 7, 6, 117, 0, 3, 40, 0, 105, 3, 40, 57, 0, 2, 17, 65, 3, 58, 0, 117, 3, 112, 0, 7, 6, 118, 0, 3, 84, 0, 7, 6, 119, 0, 3, 58, 0, 7, 6, 120, 0, 3, 49, 89, 0, 8, 2, 17, 65, 3, 88, 0, 7, 6, 121, 0, 1, 25, 2, 25, 3, 37, 0, 3, 57, 0, 7, 6, 122, 0, 3, 88, 0, 106, 3, 90, 0, 7, 6, 0, 195, 161, 3, 7, 35, 0, 195, 169, 3, 7, 36, 0, 195, 173, 3, 7, 37, 0, 195, 179, 3, 7, 39, 0, 195, 186, 3, 7, 40, 0, 39, 3, 19, 0, 36, 3, 72, 110, 55, 110, 0, 195, 167, 3, 89, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts49 = FileInMemory_createWithData (2133, reinterpret_cast (&espeakdata_dicts49_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/pap_dict", U"pap"); Collection_addItem (me.peek(), espeakdata_dicts49.transfer()); static unsigned char espeakdata_dicts50_data[39426] = { 0, 4, 0, 0, 34, 121, 0, 0, 0, 0, 0, 0, 0, 7, 132, 196, 135, 13, 9, 20, 12, 65, 4, 35, 55, 6, 35, 0, 81, 108, 97, 32, 5, 193, 4, 72, 28, 13, 138, 16, 9, 196, 153, 3, 9, 21, 19, 5, 20, 65, 0, 8, 133, 196, 135, 16, 15, 13, 20, 0, 0, 7, 196, 104, 194, 67, 104, 20, 10, 135, 4, 197, 186, 7, 14, 196, 133, 20, 0, 17, 142, 4, 26, 9, 5, 23, 9, 196, 153, 3, 9, 21, 19, 5, 20, 66, 6, 65, 8, 71, 109, 0, 0, 12, 137, 23, 3, 8, 18, 26, 3, 26, 196, 133, 20, 0, 7, 132, 4, 21, 197, 155, 20, 17, 71, 12, 128, 82, 52, 85, 83, 20, 91, 35, 51, 65, 109, 88, 0, 66, 15, 67, 21, 64, 192, 109, 117, 6, 109, 47, 109, 51, 35, 0, 24, 0, 7, 196, 92, 145, 83, 104, 20, 11, 67, 12, 17, 133, 49, 35, 83, 109, 0, 66, 16, 141, 4, 26, 9, 5, 23, 9, 196, 153, 196, 135, 19, 5, 20, 65, 0, 10, 135, 12, 197, 155, 14, 9, 19, 26, 20, 6, 65, 12, 117, 109, 0, 0, 9, 198, 76, 180, 154, 100, 54, 128, 20, 7, 132, 12, 5, 197, 186, 20, 0, 16, 71, 12, 130, 72, 84, 18, 21, 4, 76, 37, 58, 35, 58, 35, 0, 13, 4, 95, 8, 1, 3, 107, 6, 35, 76, 109, 49, 0, 0, 8, 133, 19, 16, 1, 197, 155, 20, 8, 133, 13, 18, 196, 133, 3, 20, 7, 132, 12, 5, 197, 188, 20, 0, 15, 69, 64, 242, 82, 61, 64, 48, 40, 58, 35, 51, 6, 111, 0, 6, 65, 16, 72, 109, 0, 0, 9, 134, 26, 4, 196, 133, 197, 188, 20, 10, 135, 20, 18, 26, 196, 133, 197, 155, 20, 10, 135, 19, 11, 18, 26, 196, 133, 3, 20, 10, 135, 18, 197, 188, 14, 196, 133, 3, 20, 9, 134, 4, 18, 196, 133, 197, 188, 20, 0, 9, 134, 19, 26, 3, 26, 196, 133, 20, 11, 136, 16, 19, 20, 18, 26, 196, 133, 3, 20, 0, 7, 196, 92, 145, 82, 104, 20, 7, 196, 76, 176, 77, 48, 20, 11, 68, 13, 84, 146, 100, 49, 35, 51, 112, 0, 0, 13, 138, 23, 3, 8, 18, 26, 3, 26, 196, 133, 3, 20, 8, 197, 53, 38, 133, 77, 160, 20, 8, 197, 29, 38, 133, 77, 160, 20, 11, 136, 3, 8, 18, 26, 3, 26, 196, 133, 20, 21, 65, 20, 37, 65, 109, 57, 55, 111, 84, 109, 0, 81, 109, 97, 105, 108, 111, 119, 101, 32, 25, 65, 20, 37, 65, 109, 57, 55, 111, 84, 109, 81, 111, 0, 81, 109, 97, 105, 108, 111, 119, 101, 103, 111, 32, 21, 65, 20, 37, 65, 109, 57, 55, 111, 84, 112, 0, 81, 109, 97, 105, 108, 111, 119, 121, 32, 19, 65, 20, 37, 65, 109, 57, 55, 111, 65, 0, 81, 109, 97, 105, 108, 111, 109, 32, 17, 65, 20, 37, 65, 109, 57, 55, 37, 0, 81, 109, 97, 105, 108, 105, 32, 17, 65, 20, 37, 65, 109, 57, 55, 109, 0, 81, 109, 97, 105, 108, 101, 32, 19, 65, 20, 37, 65, 109, 57, 55, 109, 65, 0, 81, 109, 97, 105, 108, 101, 109, 32, 17, 65, 20, 37, 65, 109, 57, 55, 35, 0, 81, 109, 97, 105, 108, 97, 32, 15, 65, 20, 37, 65, 109, 57, 55, 0, 81, 109, 97, 105, 108, 32, 5, 65, 20, 109, 0, 0, 0, 6, 195, 92, 146, 128, 20, 8, 133, 196, 135, 13, 9, 10, 20, 25, 67, 69, 82, 64, 49, 84, 37, 48, 51, 111, 49, 84, 111, 0, 67, 82, 112, 114, 111, 32, 113, 117, 111, 32, 0, 12, 137, 2, 197, 188, 4, 197, 188, 196, 133, 3, 20, 9, 198, 4, 33, 82, 16, 81, 78, 65, 12, 68, 72, 145, 200, 80, 51, 35, 57, 47, 0, 17, 0, 6, 65, 24, 109, 83, 0, 0, 11, 136, 26, 23, 9, 195, 179, 26, 197, 130, 20, 0, 8, 133, 26, 18, 1, 197, 186, 20, 8, 133, 23, 196, 153, 19, 26, 20, 0, 7, 196, 93, 160, 137, 40, 20, 7, 196, 44, 195, 137, 20, 20, 20, 68, 65, 38, 133, 104, 48, 91, 6, 109, 88, 67, 38, 109, 0, 81, 110, 105, 101, 32, 21, 68, 65, 38, 133, 104, 48, 91, 6, 109, 88, 67, 37, 107, 0, 81, 110, 105, 99, 104, 32, 20, 68, 65, 38, 133, 104, 48, 91, 6, 109, 88, 84, 35, 89, 0, 81, 119, 97, 115, 32, 21, 68, 65, 38, 133, 104, 48, 91, 6, 109, 89, 47, 112, 107, 0, 81, 116, 121, 99, 104, 32, 18, 68, 65, 38, 133, 104, 48, 91, 6, 109, 89, 47, 111, 0, 81, 116, 111, 32, 18, 68, 65, 38, 133, 104, 48, 91, 6, 109, 89, 47, 109, 0, 81, 116, 101, 32, 19, 68, 65, 38, 133, 104, 48, 91, 6, 109, 89, 47, 114, 0, 81, 116, 196, 133, 32, 21, 68, 65, 38, 133, 104, 48, 91, 6, 109, 88, 67, 38, 114, 0, 81, 110, 105, 196, 133, 32, 20, 68, 65, 38, 133, 104, 48, 91, 6, 109, 88, 50, 35, 89, 0, 81, 110, 97, 115, 32, 0, 7, 132, 197, 188, 7, 1, 20, 10, 135, 197, 155, 13, 9, 5, 19, 26, 20, 7, 65, 28, 81, 57, 109, 0, 0, 10, 135, 11, 18, 26, 20, 21, 197, 155, 20, 10, 135, 2, 25, 197, 130, 1, 197, 155, 76, 0, 11, 136, 13, 9, 1, 197, 130, 1, 197, 155, 76, 0, 7, 196, 104, 64, 82, 104, 20, 9, 134, 18, 197, 188, 14, 9, 10, 20, 0, 6, 65, 32, 101, 35, 0, 0, 8, 133, 13, 11, 14, 196, 133, 20, 0, 9, 134, 4, 18, 23, 9, 196, 153, 20, 9, 134, 3, 26, 3, 26, 196, 133, 20, 0, 10, 135, 13, 19, 26, 3, 26, 196, 133, 20, 7, 196, 52, 179, 137, 40, 20, 8, 1, 35, 107, 35, 91, 0, 27, 0, 8, 197, 104, 36, 143, 13, 160, 20, 8, 197, 76, 53, 75, 73, 160, 20, 5, 193, 36, 72, 28, 0, 8, 133, 197, 188, 18, 196, 133, 20, 21, 6, 4, 195, 169, 10, 195, 160, 72, 109, 90, 35, 84, 6, 37, 0, 81, 118, 117, 101, 32, 20, 6, 4, 195, 169, 10, 195, 160, 72, 109, 90, 35, 84, 6, 37, 0, 81, 118, 117, 32, 12, 1, 37, 48, 51, 6, 111, 117, 109, 50, 47, 0, 0, 9, 134, 197, 188, 7, 14, 196, 133, 20, 6, 195, 105, 54, 80, 20, 7, 1, 38, 35, 50, 72, 0, 0, 9, 134, 26, 12, 1, 26, 197, 130, 20, 7, 196, 104, 64, 83, 104, 20, 7, 196, 44, 195, 137, 40, 20, 0, 9, 134, 26, 9, 197, 155, 196, 135, 20, 7, 65, 40, 57, 111, 47, 0, 0, 10, 135, 26, 12, 5, 197, 186, 196, 135, 20, 10, 135, 23, 12, 5, 197, 186, 196, 135, 20, 0, 9, 67, 76, 148, 128, 89, 109, 51, 0, 14, 1, 42, 81, 84, 38, 6, 35, 89, 47, 49, 35, 0, 27, 0, 12, 137, 23, 19, 9, 196, 133, 197, 155, 196, 135, 20, 9, 1, 43, 48, 55, 40, 89, 0, 27, 0, 8, 197, 80, 50, 14, 36, 160, 20, 8, 197, 76, 50, 14, 36, 160, 20, 6, 195, 28, 20, 130, 20, 12, 201, 12, 132, 137, 77, 67, 208, 32, 84, 128, 65, 6, 65, 44, 49, 35, 0, 0, 9, 134, 26, 23, 196, 133, 20, 16, 20, 0, 8, 133, 23, 18, 196, 133, 2, 20, 8, 133, 20, 18, 196, 133, 2, 20, 12, 137, 19, 20, 23, 9, 5, 18, 4, 197, 186, 20, 10, 199, 28, 83, 148, 48, 83, 65, 56, 65, 12, 1, 46, 49, 51, 6, 111, 48, 49, 35, 0, 27, 0, 8, 133, 20, 18, 196, 133, 3, 20, 8, 133, 20, 14, 196, 133, 3, 20, 8, 133, 16, 18, 196, 133, 3, 20, 8, 133, 16, 14, 196, 133, 3, 20, 9, 67, 76, 148, 133, 89, 37, 51, 0, 9, 1, 47, 89, 55, 109, 91, 0, 27, 0, 8, 197, 93, 50, 207, 13, 160, 20, 8, 133, 13, 18, 21, 197, 188, 20, 7, 132, 7, 14, 196, 133, 20, 6, 65, 48, 109, 55, 0, 0, 10, 135, 23, 16, 18, 26, 196, 133, 3, 20, 9, 134, 19, 197, 130, 21, 197, 188, 20, 8, 133, 12, 7, 14, 196, 133, 20, 9, 134, 11, 18, 196, 133, 197, 188, 20, 0, 10, 135, 16, 18, 26, 196, 133, 197, 188, 20, 0, 11, 136, 23, 16, 18, 26, 196, 133, 197, 188, 20, 8, 133, 23, 13, 195, 179, 23, 20, 8, 133, 20, 12, 196, 133, 3, 20, 10, 135, 4, 197, 186, 7, 14, 196, 153, 20, 0, 8, 197, 104, 65, 80, 13, 160, 20, 9, 134, 13, 4, 12, 196, 133, 3, 20, 9, 134, 12, 197, 188, 196, 133, 3, 20, 9, 134, 7, 197, 188, 196, 133, 3, 20, 6, 65, 52, 109, 65, 0, 0, 12, 137, 23, 3, 8, 18, 26, 3, 26, 196, 153, 20, 8, 133, 13, 11, 14, 196, 153, 20, 0, 9, 134, 19, 26, 3, 26, 196, 153, 20, 9, 134, 3, 26, 3, 26, 196, 153, 20, 0, 7, 196, 104, 211, 195, 104, 20, 10, 135, 13, 19, 26, 3, 26, 196, 153, 20, 7, 196, 9, 38, 141, 36, 20, 0, 11, 136, 3, 8, 18, 26, 3, 26, 196, 153, 20, 6, 65, 56, 109, 50, 0, 0, 9, 198, 92, 145, 83, 104, 54, 128, 20, 16, 66, 57, 0, 50, 35, 48, 91, 6, 112, 49, 58, 35, 72, 0, 24, 0, 8, 133, 23, 18, 1, 197, 186, 20, 0, 6, 195, 44, 20, 141, 20, 19, 67, 64, 246, 129, 48, 111, 88, 6, 35, 67, 37, 65, 0, 81, 110, 105, 109, 32, 20, 67, 64, 246, 129, 48, 111, 88, 6, 35, 67, 38, 114, 0, 81, 110, 105, 196, 133, 32, 20, 67, 64, 246, 129, 48, 111, 88, 6, 35, 65, 50, 114, 0, 81, 109, 110, 196, 133, 32, 30, 7, 13, 1, 9, 20, 18, 195, 169, 65, 109, 47, 51, 109, 72, 111, 47, 6, 109, 55, 0, 81, 100, 39, 104, 111, 116, 101, 108, 32, 0, 14, 65, 60, 6, 111, 84, 35, 89, 0, 81, 119, 97, 115, 32, 15, 65, 60, 6, 111, 47, 112, 65, 10, 0, 81, 116, 121, 109, 32, 15, 65, 60, 6, 111, 47, 112, 107, 0, 81, 116, 121, 99, 104, 32, 12, 65, 60, 6, 111, 47, 111, 0, 81, 116, 111, 32, 12, 65, 60, 6, 111, 47, 109, 0, 81, 116, 101, 32, 13, 65, 60, 6, 111, 47, 114, 0, 81, 116, 196, 133, 32, 15, 65, 60, 6, 111, 67, 38, 114, 0, 81, 110, 105, 196, 133, 32, 14, 65, 60, 6, 111, 67, 38, 109, 0, 81, 110, 105, 101, 32, 14, 65, 60, 6, 111, 67, 37, 65, 0, 81, 110, 105, 109, 32, 16, 65, 60, 6, 111, 67, 38, 109, 57, 0, 81, 110, 105, 101, 106, 32, 14, 65, 60, 6, 111, 50, 35, 89, 0, 81, 110, 97, 115, 32, 16, 65, 60, 6, 111, 65, 67, 38, 109, 0, 81, 109, 110, 105, 101, 32, 4, 193, 60, 76, 0, 14, 1, 61, 51, 6, 40, 84, 50, 35, 15, 97, 109, 0, 27, 0, 0, 7, 196, 52, 179, 137, 20, 20, 0, 8, 133, 19, 20, 196, 133, 16, 20, 10, 1, 64, 65, 6, 35, 58, 48, 35, 0, 6, 65, 64, 48, 109, 0, 0, 9, 134, 23, 19, 20, 196, 133, 16, 20, 15, 70, 12, 128, 78, 76, 243, 128, 91, 35, 50, 89, 114, 0, 66, 0, 0, 0, 8, 197, 105, 114, 69, 77, 160, 20, 8, 197, 73, 114, 69, 77, 160, 20, 8, 197, 28, 226, 69, 77, 160, 20, 6, 65, 68, 49, 40, 0, 0, 0, 14, 67, 16, 240, 192, 72, 6, 111, 117, 109, 50, 47, 0, 24, 0, 9, 134, 23, 9, 12, 7, 197, 130, 20, 9, 134, 4, 14, 9, 15, 197, 130, 20, 0, 10, 135, 197, 155, 13, 9, 15, 197, 130, 20, 10, 135, 19, 20, 197, 130, 21, 3, 26, 20, 9, 134, 19, 16, 19, 15, 196, 135, 20, 10, 135, 19, 16, 197, 130, 21, 3, 26, 20, 9, 134, 197, 130, 7, 15, 196, 135, 20, 6, 65, 72, 109, 51, 0, 0, 10, 135, 23, 4, 26, 9, 15, 196, 135, 20, 9, 134, 197, 155, 3, 9, 5, 12, 20, 10, 135, 4, 197, 186, 7, 15, 196, 135, 20, 17, 70, 16, 85, 137, 12, 84, 192, 72, 37, 84, 35, 57, 89, 37, 89, 0, 0, 0, 0, 10, 135, 23, 196, 135, 23, 9, 3, 26, 20, 6, 195, 92, 34, 74, 20, 6, 65, 76, 109, 91, 0, 0, 7, 196, 77, 0, 82, 104, 20, 6, 195, 77, 0, 76, 20, 9, 198, 76, 180, 154, 101, 54, 128, 20, 0, 0, 21, 72, 13, 84, 146, 36, 53, 76, 84, 208, 49, 40, 51, 6, 37, 49, 40, 55, 40, 65, 0, 0, 8, 197, 80, 181, 201, 77, 160, 20, 9, 134, 197, 155, 3, 9, 5, 3, 20, 8, 197, 77, 161, 77, 73, 160, 20, 6, 65, 80, 47, 109, 0, 0, 0, 9, 134, 197, 188, 7, 14, 196, 153, 20, 7, 132, 13, 195, 179, 23, 20, 8, 133, 13, 9, 15, 197, 130, 20, 7, 195, 4, 226, 64, 76, 8, 0, 10, 135, 19, 26, 197, 130, 1, 2, 25, 20, 9, 198, 104, 208, 82, 77, 160, 218, 20, 6, 195, 77, 163, 9, 20, 7, 132, 19, 195, 179, 12, 20, 7, 196, 52, 145, 82, 104, 20, 9, 134, 197, 130, 7, 15, 197, 130, 20, 6, 195, 52, 226, 69, 72, 0, 7, 132, 26, 23, 196, 153, 20, 10, 135, 23, 12, 195, 179, 11, 197, 130, 20, 10, 135, 23, 4, 26, 9, 15, 197, 130, 20, 7, 132, 7, 14, 196, 153, 20, 10, 135, 4, 197, 186, 7, 15, 197, 130, 20, 10, 135, 3, 8, 3, 9, 15, 197, 130, 20, 0, 10, 135, 197, 155, 13, 9, 15, 196, 135, 20, 8, 133, 19, 26, 197, 130, 1, 20, 8, 133, 12, 7, 14, 196, 153, 20, 0, 6, 195, 93, 146, 128, 20, 12, 137, 23, 197, 155, 3, 9, 5, 11, 197, 130, 20, 0, 7, 196, 104, 161, 83, 104, 20, 9, 134, 16, 12, 23, 15, 197, 130, 20, 9, 198, 13, 162, 206, 36, 84, 218, 20, 0, 7, 65, 88, 83, 35, 58, 0, 0, 11, 136, 26, 23, 12, 195, 179, 11, 197, 130, 20, 7, 132, 11, 195, 179, 10, 20, 0, 14, 67, 52, 80, 192, 65, 109, 117, 109, 50, 35, 89, 0, 24, 0, 9, 134, 26, 4, 23, 195, 179, 10, 20, 15, 4, 95, 49, 77, 52, 71, 38, 6, 37, 55, 57, 111, 50, 0, 0, 12, 69, 40, 16, 203, 36, 80, 75, 109, 49, 37, 0, 13, 1, 92, 71, 6, 109, 49, 89, 55, 109, 91, 0, 27, 8, 65, 92, 84, 112, 0, 72, 14, 0, 8, 197, 93, 0, 84, 73, 160, 20, 0, 10, 1, 94, 72, 6, 35, 91, 109, 49, 0, 0, 7, 196, 104, 65, 82, 104, 20, 7, 196, 48, 115, 137, 20, 20, 0, 7, 132, 18, 23, 196, 133, 20, 6, 195, 52, 226, 74, 20, 16, 7, 4, 39, 1, 13, 15, 21, 18, 72, 35, 65, 40, 51, 0, 66, 11, 1, 96, 6, 35, 49, 117, 109, 50, 47, 0, 7, 65, 96, 37, 49, 89, 0, 14, 4, 95, 49, 77, 49, 47, 6, 112, 97, 111, 50, 117, 0, 0, 8, 133, 197, 188, 18, 196, 153, 20, 22, 66, 4, 64, 35, 72, 6, 111, 49, 40, 55, 111, 89, 0, 81, 111, 99, 117, 108, 111, 115, 32, 16, 66, 4, 64, 35, 72, 107, 6, 111, 49, 0, 81, 104, 111, 99, 32, 15, 4, 95, 49, 77, 50, 65, 38, 6, 37, 55, 57, 111, 50, 0, 0, 16, 4, 95, 49, 77, 51, 65, 38, 6, 37, 55, 57, 35, 51, 72, 0, 0, 22, 5, 16, 16, 197, 130, 11, 48, 111, 47, 48, 40, 58, 49, 6, 111, 84, 50, 37, 49, 0, 24, 0, 9, 134, 16, 12, 23, 15, 196, 135, 20, 9, 134, 13, 15, 197, 155, 196, 135, 20, 8, 197, 17, 33, 80, 13, 160, 20, 7, 132, 196, 135, 16, 1, 20, 10, 65, 100, 6, 37, 81, 51, 109, 49, 0, 0, 0, 0, 7, 132, 7, 15, 197, 132, 20, 22, 72, 13, 83, 66, 21, 35, 1, 56, 64, 49, 6, 35, 65, 71, 109, 51, 55, 109, 50, 72, 0, 0, 9, 134, 197, 188, 7, 15, 196, 135, 20, 10, 135, 26, 12, 196, 133, 11, 197, 130, 20, 9, 134, 23, 19, 9, 15, 196, 135, 20, 9, 134, 10, 5, 197, 155, 196, 135, 20, 8, 65, 104, 88, 112, 0, 72, 14, 0, 9, 134, 26, 13, 25, 197, 155, 12, 20, 10, 135, 26, 1, 10, 197, 155, 196, 135, 20, 10, 135, 23, 25, 10, 197, 155, 196, 135, 20, 11, 136, 23, 19, 9, 196, 133, 11, 197, 130, 20, 10, 135, 16, 12, 5, 197, 155, 196, 135, 20, 11, 136, 2, 18, 26, 13, 9, 15, 197, 130, 20, 0, 19, 67, 12, 148, 192, 117, 37, 89, 65, 6, 111, 55, 0, 81, 109, 111, 108, 108, 32, 18, 67, 12, 148, 192, 117, 37, 89, 72, 6, 40, 51, 0, 81, 100, 117, 114, 32, 0, 9, 134, 197, 155, 13, 9, 5, 10, 20, 14, 68, 5, 48, 201, 36, 6, 35, 89, 49, 109, 57, 0, 17, 0, 0, 0, 0, 0, 6, 195, 80, 240, 218, 20, 9, 134, 19, 3, 8, 197, 130, 15, 20, 0, 9, 198, 104, 210, 69, 73, 165, 192, 20, 10, 135, 19, 26, 3, 26, 196, 133, 3, 20, 0, 0, 9, 134, 197, 188, 7, 15, 197, 130, 20, 8, 133, 26, 13, 195, 179, 23, 20, 9, 134, 23, 19, 9, 15, 197, 130, 20, 7, 196, 48, 115, 137, 40, 20, 12, 137, 3, 8, 18, 26, 3, 26, 196, 133, 3, 20, 9, 134, 2, 12, 1, 11, 197, 130, 20, 16, 4, 9, 14, 197, 188, 37, 50, 90, 6, 112, 67, 109, 51, 0, 24, 0, 8, 197, 104, 210, 69, 73, 160, 20, 6, 195, 104, 193, 74, 20, 10, 135, 26, 2, 12, 1, 11, 197, 130, 20, 7, 132, 18, 23, 196, 153, 20, 0, 8, 133, 26, 197, 130, 15, 13, 20, 10, 135, 23, 5, 10, 197, 155, 196, 135, 20, 0, 10, 199, 92, 50, 18, 104, 50, 83, 104, 20, 11, 136, 20, 197, 130, 21, 197, 155, 196, 135, 20, 0, 9, 134, 26, 23, 9, 15, 197, 130, 20, 9, 134, 20, 197, 130, 21, 3, 26, 20, 7, 196, 77, 2, 83, 104, 20, 9, 134, 12, 196, 133, 11, 197, 130, 20, 9, 198, 17, 33, 206, 36, 84, 218, 20, 0, 6, 195, 104, 70, 66, 20, 13, 138, 19, 20, 18, 26, 196, 133, 197, 155, 196, 135, 20, 13, 138, 19, 16, 18, 26, 196, 133, 197, 155, 196, 135, 20, 13, 138, 3, 8, 18, 26, 196, 153, 197, 155, 196, 135, 20, 13, 69, 40, 19, 137, 12, 80, 75, 109, 67, 37, 89, 0, 0, 9, 198, 104, 116, 154, 21, 54, 128, 20, 9, 198, 76, 180, 154, 21, 54, 128, 20, 0, 9, 134, 19, 3, 8, 197, 130, 1, 20, 0, 6, 195, 104, 64, 77, 20, 9, 134, 196, 135, 23, 9, 3, 26, 20, 7, 196, 13, 161, 77, 84, 76, 0, 20, 1, 124, 49, 51, 4, 109, 89, 49, 35, 15, 48, 38, 111, 50, 6, 111, 84, 35, 0, 0, 8, 133, 19, 26, 197, 130, 25, 20, 9, 198, 44, 195, 137, 21, 54, 128, 20, 0, 10, 1, 126, 47, 6, 112, 55, 72, 35, 0, 0, 8, 133, 26, 13, 195, 179, 3, 20, 7, 132, 19, 196, 153, 16, 20, 0, 7, 132, 26, 23, 196, 133, 20, 6, 195, 104, 64, 74, 20, 0, 0, 0, 0, 9, 134, 26, 23, 9, 15, 196, 135, 20, 8, 197, 76, 50, 18, 85, 0, 20, 9, 134, 16, 1, 197, 155, 196, 135, 20, 0, 10, 135, 26, 5, 10, 197, 155, 196, 135, 20, 10, 135, 7, 18, 26, 13, 15, 196, 135, 20, 10, 135, 4, 15, 10, 197, 155, 196, 135, 20, 0, 11, 136, 23, 26, 5, 10, 197, 155, 196, 135, 20, 11, 136, 19, 9, 196, 133, 197, 155, 196, 135, 20, 0, 7, 196, 77, 162, 204, 36, 20, 12, 137, 16, 18, 26, 5, 10, 197, 155, 196, 135, 20, 7, 196, 17, 162, 65, 8, 20, 0, 8, 197, 104, 70, 137, 20, 192, 20, 8, 197, 77, 4, 201, 20, 160, 20, 0, 8, 133, 19, 20, 12, 196, 133, 20, 0, 0, 0, 0, 7, 132, 23, 15, 197, 186, 20, 0, 0, 9, 134, 26, 10, 1, 4, 197, 130, 20, 9, 134, 19, 26, 5, 4, 197, 130, 20, 7, 196, 29, 38, 141, 36, 20, 0, 11, 136, 23, 9, 12, 7, 197, 130, 2, 25, 20, 11, 136, 4, 14, 9, 15, 197, 130, 2, 25, 20, 10, 135, 23, 19, 26, 5, 4, 197, 130, 20, 8, 197, 76, 96, 74, 13, 160, 20, 10, 135, 16, 12, 195, 179, 20, 197, 130, 20, 0, 12, 137, 197, 155, 13, 9, 15, 197, 130, 2, 25, 20, 11, 136, 26, 2, 18, 26, 25, 4, 197, 130, 20, 11, 136, 23, 16, 12, 195, 179, 20, 197, 130, 20, 11, 136, 19, 16, 12, 195, 179, 20, 197, 130, 20, 11, 136, 7, 14, 9, 195, 179, 20, 197, 130, 20, 0, 0, 9, 134, 20, 23, 195, 179, 18, 26, 20, 0, 11, 136, 16, 12, 23, 15, 197, 130, 2, 25, 20, 10, 135, 11, 18, 26, 5, 16, 197, 130, 20, 0, 11, 136, 26, 23, 9, 195, 179, 4, 197, 130, 20, 0, 13, 138, 26, 23, 12, 195, 179, 11, 197, 130, 2, 25, 20, 0, 7, 196, 93, 2, 83, 104, 20, 0, 6, 195, 40, 81, 26, 20, 0, 0, 0, 33, 7, 3, 8, 1, 18, 7, 195, 169, 91, 35, 51, 90, 109, 72, 35, 83, 109, 51, 0, 68, 81, 100, 39, 97, 102, 102, 97, 105, 114, 101, 115, 32, 0, 8, 197, 76, 50, 12, 60, 208, 20, 6, 195, 29, 32, 74, 20, 6, 195, 13, 160, 74, 20, 0, 8, 133, 19, 20, 12, 196, 153, 20, 0, 0, 6, 195, 29, 32, 77, 20, 18, 72, 8, 80, 85, 40, 243, 1, 37, 48, 71, 111, 90, 111, 55, 6, 109, 0, 0, 0, 0, 9, 134, 19, 3, 8, 197, 130, 25, 20, 20, 71, 13, 80, 137, 13, 83, 21, 52, 49, 40, 71, 6, 37, 49, 40, 55, 40, 65, 0, 0, 7, 196, 77, 2, 69, 12, 20, 7, 196, 13, 162, 193, 40, 20, 0, 6, 195, 13, 165, 74, 20, 8, 197, 8, 16, 129, 12, 128, 66, 0, 0, 0, 7, 196, 64, 50, 1, 40, 20, 7, 196, 45, 32, 67, 104, 20, 0, 6, 195, 93, 165, 74, 20, 0, 13, 66, 17, 32, 72, 6, 111, 49, 47, 111, 51, 0, 24, 0, 0, 8, 133, 23, 4, 15, 196, 135, 20, 7, 196, 77, 162, 207, 48, 20, 8, 133, 11, 15, 16, 196, 135, 20, 0, 6, 195, 93, 38, 74, 20, 6, 195, 77, 166, 74, 20, 9, 134, 19, 11, 15, 16, 196, 135, 20, 8, 197, 9, 161, 21, 73, 160, 20, 0, 10, 135, 23, 26, 14, 9, 5, 196, 135, 20, 11, 136, 23, 26, 7, 1, 18, 4, 197, 186, 20, 11, 136, 197, 155, 23, 9, 19, 26, 3, 26, 20, 0, 8, 133, 23, 4, 15, 197, 130, 20, 8, 133, 16, 1, 4, 197, 130, 20, 7, 132, 11, 15, 197, 155, 20, 0, 9, 134, 19, 20, 25, 7, 197, 130, 20, 7, 196, 64, 197, 207, 52, 20, 7, 196, 17, 33, 207, 52, 20, 9, 134, 2, 12, 1, 4, 197, 130, 20, 0, 15, 140, 19, 3, 8, 197, 130, 25, 2, 25, 197, 155, 13, 25, 20, 10, 135, 26, 2, 12, 1, 4, 197, 130, 20, 10, 135, 23, 9, 196, 133, 4, 197, 130, 20, 8, 197, 12, 131, 85, 73, 160, 20, 21, 73, 88, 147, 129, 36, 116, 133, 81, 65, 64, 58, 37, 50, 109, 81, 34, 109, 47, 0, 67, 0, 11, 136, 26, 23, 9, 196, 133, 4, 197, 130, 20, 11, 136, 26, 13, 9, 195, 179, 20, 197, 130, 20, 11, 136, 23, 13, 9, 195, 179, 20, 197, 130, 20, 8, 133, 12, 197, 155, 14, 9, 20, 0, 6, 195, 13, 166, 64, 72, 0, 7, 196, 77, 4, 149, 40, 20, 9, 134, 11, 23, 9, 20, 197, 130, 20, 7, 196, 17, 38, 153, 40, 20, 7, 196, 17, 33, 193, 40, 20, 0, 10, 135, 197, 155, 12, 5, 16, 197, 130, 20, 0, 0, 13, 138, 26, 23, 9, 195, 179, 26, 197, 130, 2, 25, 20, 8, 133, 18, 1, 4, 197, 186, 20, 9, 134, 4, 197, 186, 7, 15, 13, 20, 0, 9, 134, 26, 10, 5, 4, 197, 186, 20, 0, 0, 12, 137, 2, 25, 197, 130, 25, 197, 155, 13, 25, 76, 0, 13, 138, 19, 26, 12, 9, 2, 25, 197, 155, 13, 25, 20, 13, 138, 13, 9, 1, 197, 130, 25, 197, 155, 13, 25, 76, 0, 13, 138, 19, 3, 8, 197, 130, 15, 19, 26, 3, 26, 20, 7, 196, 64, 50, 1, 52, 20, 0, 10, 135, 26, 23, 195, 179, 4, 197, 186, 20, 10, 135, 19, 26, 11, 15, 4, 197, 186, 20, 7, 195, 61, 32, 90, 72, 28, 0, 11, 136, 26, 197, 130, 21, 19, 26, 3, 26, 20, 0, 0, 7, 196, 80, 179, 137, 20, 20, 7, 196, 17, 33, 193, 52, 20, 7, 196, 13, 162, 193, 52, 20, 0, 11, 136, 26, 12, 1, 26, 197, 130, 2, 25, 20, 0, 12, 137, 26, 12, 196, 133, 11, 197, 130, 2, 25, 20, 0, 13, 138, 23, 19, 9, 196, 133, 11, 197, 130, 2, 25, 20, 13, 138, 2, 18, 26, 13, 9, 15, 197, 130, 2, 25, 20, 0, 7, 196, 93, 50, 69, 40, 20, 7, 196, 76, 50, 12, 4, 20, 0, 11, 136, 26, 23, 9, 15, 197, 130, 2, 25, 20, 11, 136, 12, 196, 133, 11, 197, 130, 2, 25, 20, 8, 197, 76, 50, 12, 5, 0, 20, 0, 8, 133, 7, 26, 9, 196, 133, 20, 6, 195, 60, 35, 203, 76, 0, 8, 133, 197, 155, 14, 9, 10, 20, 9, 134, 4, 197, 186, 7, 1, 13, 20, 0, 9, 134, 23, 196, 153, 4, 197, 186, 20, 9, 134, 19, 26, 25, 4, 197, 186, 20, 8, 133, 7, 26, 9, 196, 135, 20, 9, 134, 196, 135, 16, 1, 19, 26, 20, 10, 135, 11, 20, 195, 179, 18, 25, 13, 76, 0, 9, 134, 26, 19, 26, 25, 196, 135, 20, 10, 135, 26, 4, 18, 1, 4, 197, 186, 20, 9, 134, 26, 2, 9, 5, 197, 155, 20, 8, 197, 77, 162, 204, 36, 160, 20, 9, 134, 19, 11, 18, 25, 196, 135, 20, 9, 134, 16, 12, 23, 1, 196, 135, 20, 9, 134, 13, 197, 188, 25, 196, 135, 20, 9, 134, 13, 4, 12, 9, 196, 135, 20, 9, 134, 197, 130, 7, 1, 196, 135, 20, 0, 8, 133, 197, 188, 7, 15, 13, 20, 10, 135, 23, 26, 14, 9, 5, 197, 155, 20, 9, 134, 11, 18, 5, 197, 155, 12, 20, 10, 135, 4, 197, 186, 7, 1, 196, 135, 20, 11, 66, 13, 96, 89, 37, 84, 6, 37, 0, 17, 0, 9, 134, 197, 155, 16, 9, 196, 133, 20, 6, 195, 76, 48, 76, 20, 7, 132, 18, 25, 196, 135, 20, 7, 132, 16, 9, 196, 135, 20, 13, 138, 14, 9, 5, 11, 20, 195, 179, 18, 25, 13, 76, 0, 8, 133, 26, 13, 21, 197, 155, 20, 8, 133, 16, 19, 21, 196, 135, 20, 8, 133, 11, 18, 25, 196, 135, 20, 9, 134, 4, 197, 186, 7, 1, 10, 20, 0, 9, 134, 26, 197, 188, 25, 196, 135, 20, 10, 135, 26, 7, 195, 179, 4, 197, 186, 20, 9, 134, 23, 19, 26, 25, 196, 135, 20, 8, 197, 13, 160, 201, 77, 160, 20, 10, 135, 3, 8, 195, 179, 4, 197, 186, 20, 7, 195, 13, 166, 74, 72, 12, 0, 10, 135, 23, 4, 26, 9, 1, 196, 135, 20, 11, 136, 23, 3, 8, 195, 179, 4, 197, 186, 20, 10, 135, 197, 155, 13, 9, 1, 196, 135, 20, 11, 136, 19, 26, 11, 195, 179, 4, 197, 186, 20, 10, 135, 19, 16, 19, 9, 5, 196, 135, 20, 9, 134, 19, 197, 130, 25, 197, 132, 20, 11, 136, 19, 3, 8, 195, 179, 4, 197, 186, 20, 7, 132, 18, 25, 197, 130, 20, 7, 132, 16, 9, 197, 130, 20, 11, 136, 2, 197, 186, 4, 26, 9, 19, 26, 20, 0, 8, 133, 16, 19, 21, 197, 130, 20, 8, 133, 13, 9, 1, 197, 130, 20, 8, 133, 11, 18, 25, 197, 130, 20, 8, 133, 13, 9, 1, 197, 130, 76, 12, 137, 2, 196, 153, 4, 26, 9, 5, 19, 26, 76, 0, 9, 134, 26, 197, 188, 25, 197, 130, 20, 9, 134, 23, 19, 26, 25, 197, 130, 20, 9, 134, 197, 155, 3, 9, 21, 2, 20, 9, 134, 4, 14, 9, 1, 197, 130, 20, 6, 195, 13, 166, 77, 77, 0, 8, 133, 23, 19, 21, 197, 132, 20, 10, 135, 23, 4, 26, 9, 1, 197, 130, 20, 10, 135, 197, 155, 13, 9, 1, 197, 130, 20, 6, 195, 45, 38, 74, 20, 8, 133, 3, 26, 25, 197, 132, 20, 10, 135, 3, 8, 3, 9, 1, 197, 130, 20, 0, 9, 134, 26, 13, 9, 5, 197, 132, 20, 9, 134, 23, 20, 18, 25, 197, 132, 20, 7, 132, 20, 25, 197, 130, 20, 23, 66, 16, 80, 72, 109, 84, 111, 55, 6, 35, 57, 0, 81, 118, 111, 108, 97, 105, 108, 108, 101, 32, 25, 66, 16, 80, 72, 109, 55, 35, 65, 109, 88, 6, 114, 0, 82, 108, 97, 32, 109, 97, 105, 115, 111, 110, 32, 17, 66, 16, 80, 72, 109, 57, 40, 51, 109, 0, 81, 105, 117, 114, 101, 32, 19, 66, 16, 80, 72, 109, 83, 35, 49, 47, 111, 0, 81, 102, 97, 99, 116, 111, 32, 14, 70, 52, 21, 82, 36, 49, 64, 65, 111, 51, 37, 89, 0, 0, 0, 7, 196, 105, 114, 69, 40, 20, 9, 134, 26, 19, 26, 25, 197, 130, 20, 6, 195, 104, 67, 205, 20, 7, 196, 80, 179, 137, 40, 20, 7, 196, 77, 68, 149, 40, 20, 9, 134, 19, 11, 18, 25, 197, 130, 20, 9, 134, 16, 12, 23, 1, 197, 130, 20, 9, 134, 13, 197, 188, 25, 197, 130, 20, 9, 134, 13, 4, 12, 9, 197, 130, 20, 9, 134, 197, 130, 7, 1, 197, 130, 20, 0, 8, 197, 64, 50, 14, 36, 80, 20, 10, 135, 4, 197, 186, 7, 1, 197, 130, 20, 0, 0, 8, 133, 197, 188, 7, 1, 10, 20, 8, 133, 23, 9, 4, 197, 186, 20, 8, 133, 23, 1, 4, 197, 186, 20, 8, 133, 19, 1, 4, 197, 186, 20, 0, 9, 134, 26, 2, 21, 4, 197, 186, 20, 9, 134, 20, 18, 21, 4, 197, 186, 20, 9, 134, 19, 3, 5, 4, 197, 186, 20, 18, 4, 95, 4, 16, 20, 10, 48, 91, 109, 119, 6, 37, 50, 109, 49, 10, 0, 0, 10, 135, 19, 16, 196, 153, 4, 197, 186, 20, 10, 135, 19, 9, 196, 133, 4, 197, 186, 20, 0, 8, 133, 197, 188, 7, 1, 13, 20, 11, 136, 26, 2, 18, 26, 25, 4, 197, 186, 20, 9, 198, 104, 20, 19, 81, 38, 128, 20, 11, 136, 23, 19, 9, 196, 133, 4, 197, 186, 20, 9, 198, 77, 2, 69, 65, 38, 128, 20, 9, 198, 64, 244, 19, 81, 38, 128, 20, 0, 8, 133, 26, 197, 188, 21, 10, 20, 0, 7, 196, 40, 80, 149, 80, 66, 0, 7, 132, 13, 197, 188, 25, 20, 0, 11, 136, 19, 16, 18, 1, 23, 4, 197, 186, 20, 22, 67, 16, 145, 83, 116, 6, 37, 57, 109, 89, 6, 37, 51, 109, 0, 81, 105, 114, 97, 101, 32, 0, 6, 195, 104, 214, 76, 20, 9, 134, 197, 155, 16, 9, 196, 153, 20, 12, 137, 19, 11, 18, 26, 25, 23, 4, 197, 186, 20, 6, 195, 52, 243, 64, 20, 6, 195, 40, 83, 64, 20, 6, 195, 16, 19, 64, 20, 0, 7, 196, 105, 114, 69, 52, 20, 7, 196, 17, 162, 69, 48, 20, 0, 0, 0, 0, 7, 196, 76, 50, 12, 36, 20, 7, 196, 52, 67, 5, 40, 20, 7, 196, 40, 242, 131, 104, 20, 7, 196, 13, 160, 201, 40, 20, 7, 196, 12, 131, 5, 40, 20, 14, 4, 95, 20, 12, 4, 88, 47, 6, 112, 55, 72, 114, 0, 9, 3, 95, 35, 57, 47, 35, 71, 0, 0, 6, 195, 76, 181, 74, 20, 0, 0, 9, 134, 197, 155, 14, 9, 196, 133, 20, 6, 195, 76, 181, 76, 20, 8, 133, 14, 21, 4, 197, 186, 20, 7, 132, 2, 9, 196, 135, 20, 0, 7, 196, 93, 54, 153, 40, 20, 9, 134, 197, 155, 3, 9, 19, 26, 20, 8, 133, 19, 13, 21, 196, 135, 20, 8, 133, 7, 14, 9, 196, 135, 20, 8, 133, 3, 14, 9, 196, 135, 20, 12, 68, 5, 32, 213, 76, 35, 34, 49, 40, 89, 0, 0, 9, 134, 197, 188, 7, 1, 196, 135, 20, 10, 135, 26, 197, 130, 21, 4, 197, 186, 20, 6, 195, 92, 181, 74, 20, 9, 134, 197, 155, 14, 9, 196, 135, 20, 8, 197, 77, 68, 154, 21, 0, 20, 10, 135, 19, 20, 18, 21, 4, 197, 186, 20, 9, 134, 19, 20, 12, 9, 196, 135, 20, 9, 134, 11, 18, 196, 153, 196, 135, 20, 0, 10, 135, 23, 11, 18, 196, 153, 196, 135, 20, 10, 135, 19, 11, 18, 196, 153, 196, 135, 20, 8, 133, 11, 16, 9, 196, 133, 20, 0, 7, 132, 2, 25, 196, 135, 20, 14, 6, 3, 15, 21, 16, 195, 169, 49, 40, 48, 6, 109, 0, 7, 132, 2, 25, 196, 135, 76, 14, 67, 17, 97, 0, 72, 37, 84, 37, 72, 6, 37, 0, 17, 0, 8, 133, 23, 11, 21, 196, 135, 20, 8, 133, 19, 11, 21, 196, 135, 20, 8, 133, 14, 196, 153, 196, 135, 20, 8, 133, 11, 16, 9, 196, 135, 20, 7, 196, 29, 112, 82, 104, 20, 8, 133, 3, 12, 9, 196, 135, 20, 6, 195, 40, 83, 85, 72, 0, 9, 134, 26, 23, 9, 1, 196, 135, 20, 9, 134, 23, 19, 9, 1, 196, 135, 20, 8, 197, 77, 65, 82, 13, 160, 20, 6, 195, 76, 181, 66, 20, 8, 197, 64, 148, 218, 13, 160, 20, 0, 7, 132, 2, 25, 197, 130, 20, 7, 132, 2, 25, 197, 130, 76, 0, 8, 133, 23, 11, 21, 197, 130, 20, 8, 133, 19, 11, 21, 197, 130, 20, 8, 133, 11, 16, 9, 197, 130, 20, 11, 136, 7, 18, 26, 13, 9, 5, 196, 135, 20, 8, 133, 3, 12, 9, 197, 130, 20, 0, 12, 137, 16, 9, 15, 197, 130, 2, 25, 197, 155, 20, 9, 134, 26, 23, 9, 1, 197, 130, 20, 9, 134, 23, 19, 9, 1, 197, 130, 20, 12, 137, 11, 19, 26, 20, 1, 197, 130, 196, 135, 20, 0, 8, 133, 26, 19, 21, 197, 132, 20, 9, 134, 13, 11, 14, 196, 133, 3, 20, 0, 10, 135, 3, 26, 3, 26, 196, 133, 3, 20, 11, 136, 2, 18, 26, 13, 9, 1, 197, 130, 20, 7, 132, 2, 9, 197, 130, 20, 21, 66, 12, 144, 89, 37, 72, 109, 84, 6, 35, 68, 0, 81, 100, 101, 118, 97, 110, 116, 32, 6, 194, 12, 144, 72, 12, 0, 6, 195, 64, 145, 76, 20, 11, 136, 13, 19, 26, 3, 26, 196, 133, 3, 20, 8, 133, 7, 14, 9, 197, 130, 20, 8, 133, 3, 14, 9, 197, 130, 20, 0, 9, 134, 197, 188, 7, 1, 197, 130, 20, 7, 196, 104, 115, 137, 40, 20, 9, 134, 197, 155, 14, 9, 197, 130, 20, 9, 134, 19, 20, 12, 9, 197, 130, 20, 0, 0, 6, 195, 28, 20, 0, 20, 0, 0, 6, 195, 93, 38, 133, 20, 7, 196, 92, 179, 5, 40, 20, 9, 134, 16, 196, 153, 4, 197, 186, 20, 9, 134, 196, 135, 13, 9, 19, 26, 20, 0, 10, 135, 23, 16, 196, 153, 4, 197, 186, 20, 6, 195, 64, 145, 74, 20, 8, 197, 13, 162, 206, 36, 80, 20, 8, 197, 52, 22, 9, 52, 16, 65, 0, 8, 133, 13, 197, 155, 3, 9, 20, 0, 8, 133, 23, 197, 188, 25, 10, 20, 19, 71, 12, 244, 25, 72, 145, 200, 80, 49, 6, 111, 48, 112, 51, 35, 57, 47, 0, 0, 0, 10, 135, 197, 155, 16, 9, 5, 19, 26, 20, 0, 0, 0, 9, 198, 92, 50, 18, 104, 50, 74, 20, 0, 0, 0, 10, 67, 61, 32, 193, 111, 51, 49, 35, 0, 0, 7, 132, 13, 18, 196, 133, 20, 16, 70, 12, 128, 82, 52, 85, 82, 91, 35, 51, 65, 109, 51, 0, 66, 20, 67, 32, 16, 128, 107, 35, 71, 37, 55, 37, 47, 111, 84, 6, 35, 50, 112, 0, 24, 10, 135, 11, 20, 195, 179, 18, 26, 25, 76, 0, 7, 132, 23, 1, 197, 188, 20, 7, 196, 12, 131, 1, 40, 20, 0, 9, 134, 19, 11, 18, 26, 196, 133, 20, 0, 8, 133, 19, 11, 21, 197, 155, 20, 10, 135, 16, 19, 20, 18, 26, 196, 133, 20, 7, 132, 12, 9, 197, 186, 20, 8, 133, 11, 1, 18, 196, 135, 20, 13, 138, 14, 9, 5, 11, 20, 195, 179, 18, 26, 25, 76, 0, 7, 132, 23, 18, 196, 133, 20, 9, 134, 23, 9, 5, 18, 196, 135, 20, 7, 132, 197, 155, 12, 5, 20, 8, 133, 7, 18, 25, 197, 186, 20, 0, 9, 134, 23, 7, 18, 25, 197, 186, 20, 7, 132, 13, 1, 197, 188, 20, 7, 132, 12, 9, 197, 188, 20, 7, 196, 29, 32, 83, 104, 20, 0, 8, 197, 29, 38, 141, 36, 160, 20, 7, 132, 7, 1, 197, 155, 20, 0, 8, 133, 23, 13, 21, 197, 155, 20, 0, 0, 10, 135, 20, 18, 26, 196, 153, 197, 155, 20, 8, 133, 11, 16, 9, 196, 153, 20, 0, 13, 69, 77, 68, 133, 21, 64, 89, 47, 51, 37, 47, 0, 19, 67, 65, 3, 210, 48, 111, 72, 48, 111, 51, 6, 40, 76, 67, 37, 49, 0, 24, 0, 0, 9, 134, 197, 188, 18, 196, 133, 3, 20, 9, 134, 2, 18, 14, 196, 133, 3, 20, 0, 10, 135, 197, 188, 7, 14, 196, 133, 3, 20, 7, 196, 92, 179, 5, 64, 20, 10, 135, 20, 3, 8, 14, 196, 133, 3, 20, 16, 70, 24, 244, 151, 5, 33, 0, 83, 111, 51, 58, 109, 51, 72, 0, 0, 9, 134, 197, 155, 14, 9, 196, 153, 20, 10, 135, 19, 197, 130, 1, 2, 197, 130, 20, 0, 8, 133, 3, 12, 196, 133, 3, 20, 7, 195, 81, 147, 73, 72, 12, 0, 9, 134, 197, 155, 12, 196, 133, 3, 20, 0, 9, 198, 104, 211, 137, 20, 164, 218, 20, 10, 135, 197, 130, 197, 188, 196, 133, 3, 20, 7, 196, 45, 114, 67, 104, 20, 10, 135, 4, 18, 197, 188, 196, 133, 3, 20, 0, 8, 133, 23, 196, 133, 20, 16, 20, 24, 69, 65, 38, 133, 104, 80, 48, 91, 109, 88, 6, 109, 65, 67, 38, 109, 0, 81, 109, 110, 105, 101, 32, 20, 73, 72, 21, 1, 80, 245, 73, 48, 193, 64, 34, 35, 47, 35, 47, 40, 57, 0, 67, 0, 6, 195, 29, 35, 205, 20, 0, 8, 133, 23, 9, 5, 197, 186, 20, 6, 195, 64, 146, 128, 20, 6, 195, 16, 18, 128, 20, 6, 195, 40, 82, 128, 72, 0, 7, 196, 105, 54, 153, 40, 20, 7, 196, 76, 179, 5, 40, 20, 0, 14, 69, 52, 17, 1, 52, 80, 65, 35, 72, 6, 35, 65, 0, 12, 137, 16, 15, 14, 9, 5, 23, 1, 197, 188, 8, 0, 9, 198, 93, 54, 133, 64, 54, 128, 20, 6, 195, 13, 160, 201, 20, 0, 7, 132, 197, 155, 14, 9, 20, 9, 134, 19, 11, 23, 1, 197, 155, 20, 7, 195, 81, 147, 64, 72, 12, 18, 67, 57, 83, 64, 50, 40, 65, 55, 111, 49, 0, 81, 108, 111, 99, 107, 32, 0, 9, 134, 12, 197, 188, 25, 19, 26, 20, 0, 0, 0, 6, 195, 92, 181, 80, 20, 7, 132, 13, 18, 196, 153, 20, 18, 67, 52, 243, 128, 65, 114, 91, 109, 51, 0, 66, 81, 99, 104, 101, 114, 32, 18, 67, 52, 243, 128, 65, 111, 50, 35, 65, 37, 0, 67, 81, 97, 109, 105, 32, 0, 8, 133, 3, 14, 9, 196, 153, 20, 0, 6, 195, 77, 50, 74, 20, 0, 0, 17, 8, 3, 15, 12, 12, 195, 168, 7, 5, 49, 111, 55, 109, 90, 0, 66, 16, 67, 52, 116, 128, 65, 35, 81, 6, 37, 89, 47, 109, 51, 0, 24, 0, 7, 196, 93, 67, 195, 104, 20, 7, 196, 92, 116, 129, 40, 20, 22, 73, 52, 17, 5, 52, 242, 83, 20, 195, 5, 65, 35, 72, 65, 40, 35, 88, 6, 109, 55, 0, 12, 68, 17, 34, 86, 20, 72, 34, 35, 57, 84, 0, 0, 8, 197, 64, 50, 14, 36, 160, 20, 0, 9, 134, 23, 19, 11, 1, 197, 188, 20, 9, 134, 18, 26, 196, 153, 197, 188, 20, 0, 0, 9, 134, 23, 23, 9, 5, 197, 186, 20, 10, 135, 23, 23, 9, 5, 18, 196, 135, 20, 10, 135, 23, 7, 9, 196, 153, 196, 135, 20, 0, 9, 134, 19, 3, 8, 14, 196, 133, 20, 10, 135, 7, 12, 196, 153, 4, 197, 186, 20, 16, 3, 226, 132, 162, 47, 51, 6, 109, 57, 72, 65, 35, 51, 49, 0, 0, 8, 133, 26, 12, 15, 196, 135, 20, 9, 134, 16, 18, 196, 153, 197, 188, 20, 8, 133, 11, 15, 18, 196, 135, 20, 0, 11, 136, 23, 19, 26, 3, 26, 14, 196, 133, 20, 7, 132, 23, 18, 196, 153, 20, 9, 134, 19, 13, 196, 153, 196, 135, 20, 9, 134, 19, 11, 15, 18, 196, 135, 20, 8, 133, 18, 15, 4, 197, 186, 20, 9, 134, 12, 5, 197, 186, 196, 135, 20, 0, 9, 134, 18, 26, 196, 153, 197, 186, 20, 7, 196, 64, 50, 15, 52, 20, 7, 196, 12, 131, 1, 64, 20, 0, 0, 7, 132, 18, 196, 133, 2, 20, 12, 137, 7, 18, 26, 196, 133, 197, 186, 196, 135, 20, 0, 8, 133, 26, 12, 15, 197, 130, 20, 9, 134, 11, 12, 14, 196, 133, 3, 20, 13, 138, 4, 197, 186, 7, 14, 9, 196, 153, 196, 135, 20, 0, 7, 196, 104, 37, 82, 104, 20, 9, 198, 77, 3, 204, 77, 160, 218, 20, 9, 198, 76, 181, 201, 21, 32, 218, 20, 10, 135, 19, 3, 8, 14, 196, 133, 3, 20, 0, 9, 134, 19, 11, 18, 26, 196, 153, 20, 14, 6, 13, 195, 188, 19, 12, 9, 65, 40, 89, 55, 37, 0, 0, 10, 135, 16, 19, 20, 18, 26, 196, 153, 20, 5, 194, 8, 240, 8, 0, 8, 133, 26, 14, 15, 197, 130, 20, 9, 134, 18, 197, 188, 196, 133, 3, 20, 9, 134, 13, 197, 188, 196, 133, 3, 20, 0, 9, 134, 26, 23, 1, 18, 197, 130, 20, 9, 134, 26, 20, 1, 18, 197, 130, 20, 9, 134, 23, 20, 1, 18, 197, 130, 20, 9, 134, 23, 16, 1, 18, 197, 130, 20, 7, 132, 11, 1, 197, 188, 20, 0, 12, 69, 12, 130, 76, 48, 144, 76, 37, 55, 37, 0, 0, 0, 0, 7, 196, 52, 147, 3, 104, 20, 22, 72, 77, 1, 67, 36, 19, 9, 80, 80, 89, 48, 109, 89, 57, 35, 55, 37, 47, 6, 109, 0, 0, 0, 0, 0, 9, 134, 11, 15, 197, 132, 3, 26, 20, 12, 137, 13, 9, 5, 12, 9, 197, 155, 13, 25, 76, 0, 0, 9, 198, 4, 195, 9, 76, 243, 128, 65, 0, 0, 7, 196, 76, 181, 82, 92, 20, 0, 8, 197, 77, 163, 9, 9, 144, 20, 0, 9, 134, 26, 19, 20, 196, 133, 16, 20, 0, 6, 195, 92, 64, 64, 20, 6, 195, 17, 144, 128, 20, 0, 7, 196, 92, 54, 149, 40, 20, 7, 196, 81, 35, 195, 104, 20, 7, 196, 77, 67, 195, 104, 20, 0, 0, 6, 195, 77, 67, 9, 20, 8, 133, 16, 18, 15, 196, 135, 20, 0, 9, 134, 26, 7, 18, 15, 196, 135, 20, 7, 132, 19, 19, 196, 133, 20, 8, 133, 19, 196, 133, 3, 26, 20, 6, 195, 76, 64, 64, 17, 0, 9, 134, 26, 197, 130, 195, 179, 10, 20, 9, 134, 23, 11, 18, 195, 179, 10, 20, 9, 134, 19, 11, 18, 195, 179, 10, 20, 7, 196, 13, 161, 83, 104, 20, 0, 6, 195, 92, 193, 74, 20, 8, 197, 13, 162, 206, 36, 160, 20, 0, 8, 133, 26, 14, 15, 197, 155, 20, 8, 133, 26, 4, 15, 196, 135, 20, 8, 133, 19, 20, 15, 196, 135, 20, 6, 195, 16, 32, 77, 20, 16, 67, 57, 97, 1, 109, 50, 83, 35, 58, 72, 109, 6, 35, 0, 17, 0, 9, 134, 7, 15, 197, 155, 196, 135, 20, 0, 7, 196, 61, 53, 18, 104, 20, 10, 135, 11, 197, 130, 195, 179, 196, 135, 20, 0, 8, 197, 17, 37, 201, 77, 160, 20, 0, 12, 137, 16, 18, 26, 25, 10, 197, 155, 196, 135, 20, 21, 67, 64, 17, 197, 48, 109, 57, 75, 72, 6, 35, 58, 50, 0, 81, 100, 111, 119, 110, 32, 17, 67, 64, 17, 197, 48, 109, 57, 75, 6, 35, 48, 0, 81, 117, 112, 32, 0, 8, 133, 26, 4, 15, 197, 130, 20, 11, 136, 23, 19, 26, 3, 26, 14, 196, 153, 20, 6, 195, 92, 179, 208, 20, 8, 133, 20, 12, 15, 197, 130, 20, 8, 133, 19, 20, 15, 197, 130, 20, 0, 6, 195, 92, 193, 67, 20, 7, 196, 92, 68, 129, 64, 20, 0, 10, 135, 26, 18, 195, 179, 19, 197, 130, 20, 8, 197, 104, 116, 129, 77, 160, 20, 10, 135, 23, 18, 195, 179, 19, 197, 130, 20, 10, 135, 14, 9, 195, 179, 19, 197, 130, 20, 6, 195, 16, 32, 74, 20, 0, 11, 136, 23, 26, 18, 195, 179, 19, 197, 130, 20, 11, 136, 19, 20, 18, 26, 5, 7, 197, 130, 20, 5, 194, 40, 16, 76, 0, 9, 134, 26, 197, 130, 195, 179, 23, 20, 12, 137, 23, 26, 14, 9, 195, 179, 19, 197, 130, 20, 6, 195, 81, 146, 128, 20, 8, 133, 16, 18, 15, 197, 130, 20, 8, 133, 7, 1, 19, 197, 130, 20, 6, 195, 12, 194, 64, 20, 0, 13, 138, 26, 197, 188, 195, 179, 197, 130, 11, 197, 130, 20, 9, 134, 26, 7, 18, 15, 197, 130, 20, 7, 196, 104, 116, 129, 8, 20, 11, 136, 23, 3, 8, 197, 130, 15, 197, 132, 20, 7, 196, 53, 35, 195, 104, 20, 6, 195, 36, 50, 0, 72, 0, 0, 9, 198, 76, 50, 12, 36, 38, 64, 20, 9, 198, 80, 179, 137, 21, 54, 128, 20, 0, 0, 7, 196, 92, 19, 3, 104, 20, 7, 196, 77, 160, 218, 4, 20, 0, 0, 8, 133, 16, 18, 15, 197, 155, 20, 9, 198, 29, 38, 141, 37, 54, 128, 20, 0, 0, 12, 68, 40, 19, 133, 80, 75, 35, 50, 109, 47, 0, 0, 9, 134, 19, 3, 8, 14, 196, 153, 20, 6, 195, 64, 20, 154, 20, 13, 69, 16, 147, 135, 33, 144, 116, 37, 68, 81, 37, 0, 0, 6, 195, 80, 18, 201, 76, 0, 11, 136, 11, 20, 195, 179, 18, 5, 13, 21, 76, 10, 199, 12, 19, 129, 88, 84, 129, 48, 66, 0, 9, 198, 93, 38, 133, 77, 160, 218, 20, 7, 196, 92, 181, 82, 92, 20, 7, 196, 92, 116, 129, 52, 20, 12, 68, 12, 148, 131, 4, 117, 37, 51, 49, 35, 0, 0, 6, 195, 8, 80, 218, 20, 18, 4, 16, 197, 130, 11, 48, 40, 58, 49, 6, 111, 84, 50, 37, 49, 0, 24, 0, 14, 139, 14, 9, 5, 11, 20, 195, 179, 18, 5, 13, 21, 76, 9, 198, 61, 50, 69, 53, 49, 84, 65, 0, 0, 7, 196, 9, 35, 195, 104, 20, 0, 8, 133, 7, 4, 25, 197, 188, 8, 0, 0, 9, 134, 19, 11, 1, 18, 196, 135, 20, 9, 134, 16, 197, 130, 15, 196, 135, 20, 0, 10, 135, 23, 16, 197, 130, 15, 196, 135, 20, 10, 135, 19, 26, 3, 26, 15, 196, 135, 20, 10, 135, 19, 16, 197, 130, 15, 196, 135, 20, 0, 10, 135, 26, 197, 130, 196, 133, 3, 26, 20, 8, 197, 12, 128, 201, 20, 160, 20, 18, 70, 4, 225, 197, 48, 144, 193, 35, 50, 81, 109, 55, 37, 49, 35, 0, 66, 18, 67, 37, 65, 0, 37, 15, 47, 35, 49, 15, 72, 35, 55, 109, 57, 0, 24, 0, 8, 133, 23, 12, 15, 196, 135, 20, 15, 70, 29, 32, 69, 12, 20, 192, 81, 51, 109, 49, 35, 89, 0, 19, 4, 95, 13, 3, 14, 50, 35, 72, 49, 51, 109, 97, 55, 6, 111, 50, 109, 0, 0, 9, 134, 23, 18, 195, 179, 196, 135, 20, 7, 132, 197, 155, 16, 9, 20, 9, 67, 56, 85, 192, 67, 38, 40, 0, 19, 71, 21, 99, 204, 85, 66, 79, 56, 109, 84, 111, 55, 6, 40, 91, 112, 50, 0, 0, 10, 135, 26, 23, 18, 195, 179, 196, 135, 20, 10, 135, 23, 16, 1, 197, 155, 196, 135, 20, 7, 196, 92, 181, 82, 104, 20, 10, 135, 19, 16, 1, 197, 155, 196, 135, 20, 10, 135, 19, 11, 18, 195, 179, 196, 135, 20, 10, 135, 13, 197, 130, 195, 179, 196, 135, 20, 7, 196, 12, 131, 9, 64, 20, 0, 6, 195, 104, 224, 74, 20, 11, 136, 26, 13, 197, 130, 195, 179, 196, 135, 20, 11, 136, 23, 16, 12, 5, 197, 155, 196, 135, 20, 11, 136, 19, 16, 12, 5, 197, 155, 196, 135, 20, 11, 136, 19, 11, 197, 130, 195, 179, 196, 135, 20, 11, 136, 16, 195, 179, 10, 197, 155, 196, 135, 20, 6, 195, 12, 194, 74, 20, 15, 67, 45, 5, 0, 49, 35, 48, 6, 37, 47, 35, 50, 0, 24, 0, 6, 195, 104, 224, 77, 20, 12, 137, 20, 18, 26, 196, 133, 197, 155, 196, 135, 20, 12, 137, 16, 18, 26, 196, 133, 197, 155, 196, 135, 20, 8, 133, 7, 14, 196, 133, 3, 20, 21, 67, 37, 68, 0, 37, 15, 47, 109, 65, 40, 15, 48, 111, 72, 111, 71, 50, 109, 0, 24, 13, 67, 76, 52, 201, 89, 49, 6, 35, 88, 37, 0, 17, 0, 10, 135, 23, 26, 2, 18, 15, 197, 132, 20, 13, 138, 23, 16, 18, 26, 196, 133, 197, 155, 196, 135, 20, 8, 133, 23, 12, 15, 197, 130, 20, 8, 133, 19, 16, 15, 197, 130, 20, 10, 135, 19, 16, 197, 130, 15, 197, 132, 20, 9, 134, 12, 7, 14, 196, 133, 3, 20, 0, 9, 134, 26, 7, 1, 4, 197, 130, 20, 7, 196, 104, 68, 129, 64, 20, 9, 134, 18, 195, 179, 19, 197, 130, 20, 9, 134, 12, 196, 133, 7, 197, 130, 20, 7, 196, 12, 132, 129, 64, 20, 12, 68, 12, 148, 131, 20, 49, 37, 51, 49, 109, 0, 0, 10, 135, 26, 2, 9, 5, 7, 197, 130, 20, 10, 135, 23, 2, 9, 5, 7, 197, 130, 20, 0, 5, 194, 16, 240, 76, 0, 6, 195, 44, 192, 80, 20, 8, 133, 11, 9, 19, 197, 130, 20, 6, 195, 40, 84, 212, 76, 0, 9, 134, 26, 23, 9, 19, 197, 130, 20, 9, 134, 26, 14, 9, 11, 197, 130, 20, 9, 134, 26, 13, 25, 19, 197, 130, 20, 7, 196, 104, 116, 129, 40, 20, 9, 134, 19, 16, 1, 19, 197, 130, 20, 9, 134, 19, 11, 9, 19, 197, 130, 20, 9, 134, 13, 1, 18, 26, 197, 130, 20, 13, 5, 10, 15, 19, 195, 169, 107, 111, 88, 6, 109, 0, 0, 10, 135, 19, 26, 3, 26, 15, 197, 130, 20, 6, 195, 44, 193, 74, 20, 0, 11, 136, 20, 18, 26, 196, 133, 19, 197, 130, 20, 9, 198, 52, 179, 137, 21, 54, 128, 20, 9, 198, 48, 115, 137, 21, 54, 128, 20, 9, 198, 9, 35, 137, 21, 54, 128, 20, 0, 12, 137, 197, 188, 195, 179, 197, 130, 11, 197, 130, 20, 10, 135, 23, 197, 155, 3, 9, 5, 12, 20, 12, 137, 19, 20, 18, 26, 196, 133, 19, 197, 130, 20, 0, 9, 134, 197, 130, 196, 133, 3, 26, 20, 7, 196, 45, 2, 83, 104, 20, 7, 196, 17, 162, 79, 8, 20, 0, 10, 135, 23, 197, 130, 196, 133, 3, 26, 20, 11, 136, 11, 20, 195, 179, 18, 5, 7, 15, 76, 15, 69, 16, 85, 137, 12, 80, 72, 37, 84, 6, 35, 57, 89, 0, 0, 8, 133, 26, 18, 15, 197, 155, 20, 0, 8, 133, 26, 197, 188, 25, 10, 20, 9, 134, 23, 26, 14, 15, 197, 155, 20, 7, 132, 19, 19, 196, 153, 20, 0, 9, 134, 16, 197, 130, 1, 3, 26, 20, 9, 134, 12, 197, 155, 14, 9, 10, 20, 14, 139, 14, 9, 5, 11, 20, 195, 179, 18, 5, 7, 15, 76, 0, 6, 195, 92, 64, 74, 20, 10, 135, 19, 16, 197, 130, 1, 3, 26, 20, 6, 195, 48, 144, 218, 20, 0, 6, 195, 92, 64, 77, 20, 0, 9, 134, 23, 26, 13, 195, 179, 3, 20, 6, 195, 92, 193, 80, 20, 0, 7, 196, 104, 116, 129, 52, 20, 0, 6, 195, 52, 240, 218, 20, 6, 195, 16, 20, 218, 20, 0, 0, 11, 136, 19, 3, 8, 197, 130, 1, 2, 25, 20, 16, 3, 95, 51, 88, 47, 91, 112, 120, 6, 109, 97, 80, 38, 37, 0, 0, 0, 6, 195, 81, 32, 70, 20, 0, 7, 132, 197, 188, 21, 10, 20, 0, 7, 132, 20, 12, 196, 133, 20, 0, 8, 133, 13, 4, 12, 196, 133, 20, 7, 196, 16, 84, 3, 104, 20, 11, 200, 52, 21, 20, 21, 34, 15, 72, 224, 65, 0, 0, 8, 133, 23, 14, 15, 197, 155, 20, 0, 10, 135, 23, 197, 130, 195, 179, 197, 188, 20, 0, 7, 196, 12, 131, 21, 64, 20, 10, 3, 95, 49, 67, 89, 47, 6, 111, 0, 0, 0, 0, 8, 133, 10, 1, 4, 197, 130, 20, 0, 9, 134, 19, 9, 1, 4, 197, 130, 20, 9, 134, 18, 26, 5, 4, 197, 130, 20, 9, 134, 11, 18, 1, 4, 197, 130, 20, 9, 134, 3, 8, 21, 4, 197, 130, 20, 0, 10, 135, 26, 18, 26, 5, 4, 197, 130, 20, 10, 135, 23, 11, 18, 1, 4, 197, 130, 20, 10, 135, 19, 11, 18, 1, 4, 197, 130, 20, 10, 135, 19, 3, 8, 21, 4, 197, 130, 20, 10, 135, 11, 197, 130, 1, 4, 197, 130, 20, 6, 195, 40, 84, 218, 20, 10, 135, 2, 18, 26, 25, 4, 197, 130, 20, 0, 11, 136, 26, 7, 196, 153, 19, 20, 197, 130, 20, 6, 195, 64, 50, 1, 20, 5, 194, 40, 80, 20, 18, 3, 95, 49, 57, 120, 109, 84, 38, 109, 47, 50, 6, 35, 97, 119, 109, 0, 0, 12, 137, 26, 7, 14, 9, 195, 179, 20, 197, 130, 20, 12, 137, 23, 7, 14, 9, 195, 179, 20, 197, 130, 20, 16, 3, 95, 49, 56, 111, 97, 109, 65, 50, 6, 35, 97, 119, 109, 0, 0, 9, 134, 19, 9, 15, 4, 197, 130, 20, 9, 134, 2, 195, 179, 4, 197, 130, 20, 15, 3, 95, 50, 67, 72, 84, 38, 6, 109, 97, 80, 38, 109, 0, 0, 10, 135, 23, 19, 9, 15, 4, 197, 130, 20, 10, 135, 3, 8, 18, 25, 16, 197, 130, 20, 0, 11, 136, 19, 11, 18, 26, 5, 16, 197, 130, 20, 11, 136, 19, 3, 8, 18, 25, 16, 197, 130, 20, 0, 6, 195, 17, 32, 80, 20, 0, 9, 134, 18, 26, 5, 197, 186, 2, 20, 26, 68, 12, 20, 148, 20, 49, 35, 51, 47, 71, 55, 6, 35, 50, 91, 0, 81, 98, 108, 97, 110, 99, 104, 101, 32, 0, 8, 197, 40, 84, 212, 20, 208, 76, 0, 16, 3, 95, 49, 49, 57, 109, 72, 109, 50, 6, 35, 97, 119, 109, 0, 0, 13, 3, 95, 49, 48, 120, 6, 109, 97, 109, 67, 119, 0, 0, 8, 133, 13, 4, 12, 196, 153, 20, 8, 133, 4, 197, 186, 7, 1, 20, 13, 3, 95, 51, 67, 47, 91, 6, 112, 89, 47, 35, 0, 15, 3, 95, 49, 51, 47, 91, 112, 50, 6, 35, 97, 119, 109, 0, 0, 15, 3, 95, 49, 50, 72, 84, 35, 50, 6, 35, 97, 119, 109, 0, 0, 11, 136, 26, 23, 9, 196, 153, 11, 19, 26, 20, 16, 3, 95, 49, 53, 48, 57, 109, 47, 50, 6, 35, 97, 119, 109, 0, 0, 16, 3, 95, 49, 52, 76, 47, 109, 51, 50, 6, 35, 97, 119, 109, 0, 0, 17, 3, 95, 49, 55, 97, 109, 72, 109, 65, 50, 6, 35, 97, 119, 109, 0, 0, 15, 3, 95, 49, 54, 91, 109, 89, 50, 6, 35, 97, 119, 109, 0, 0, 0, 13, 67, 81, 148, 192, 47, 112, 97, 113, 117, 112, 0, 24, 18, 3, 95, 55, 88, 97, 109, 72, 109, 65, 120, 6, 109, 97, 111, 50, 47, 0, 0, 15, 3, 95, 52, 67, 76, 47, 6, 109, 51, 112, 89, 47, 35, 0, 0, 0, 9, 134, 19, 11, 1, 18, 197, 188, 20, 0, 6, 195, 93, 69, 76, 20, 10, 199, 13, 165, 5, 73, 148, 212, 4, 65, 0, 10, 135, 19, 11, 18, 26, 25, 196, 135, 20, 0, 0, 0, 10, 135, 26, 197, 130, 195, 179, 197, 188, 20, 0, 10, 135, 26, 7, 14, 9, 5, 196, 135, 20, 15, 3, 95, 53, 67, 48, 38, 6, 109, 67, 119, 89, 109, 47, 0, 0, 13, 138, 19, 3, 8, 197, 130, 25, 197, 155, 13, 25, 20, 8, 197, 64, 145, 80, 73, 160, 20, 0, 11, 136, 7, 197, 130, 1, 19, 26, 3, 26, 20, 0, 12, 137, 19, 16, 197, 130, 1, 19, 26, 3, 26, 20, 0, 9, 134, 19, 16, 1, 4, 197, 130, 20, 7, 196, 13, 162, 207, 52, 20, 0, 10, 135, 26, 19, 9, 1, 4, 197, 130, 20, 10, 135, 23, 19, 9, 1, 4, 197, 130, 20, 8, 197, 77, 2, 69, 13, 160, 20, 10, 135, 13, 9, 195, 179, 20, 197, 130, 20, 0, 11, 136, 19, 20, 18, 26, 25, 7, 197, 130, 20, 11, 136, 16, 18, 26, 196, 133, 4, 197, 130, 20, 5, 194, 52, 16, 20, 5, 194, 52, 16, 76, 0, 12, 137, 23, 16, 18, 26, 196, 133, 4, 197, 130, 20, 12, 137, 19, 16, 18, 26, 196, 133, 4, 197, 130, 20, 0, 7, 196, 81, 37, 193, 40, 20, 13, 3, 95, 54, 67, 91, 6, 109, 97, 89, 109, 47, 0, 0, 10, 135, 26, 19, 9, 15, 4, 197, 130, 20, 10, 135, 19, 11, 18, 26, 25, 197, 130, 20, 0, 11, 136, 23, 23, 9, 195, 179, 4, 197, 130, 20, 0, 7, 132, 197, 188, 18, 5, 20, 8, 197, 77, 160, 218, 101, 0, 20, 12, 137, 3, 8, 197, 130, 195, 179, 4, 197, 130, 20, 0, 9, 134, 23, 10, 5, 4, 197, 186, 20, 7, 196, 77, 160, 218, 100, 20, 9, 134, 19, 20, 21, 4, 197, 186, 20, 7, 196, 45, 37, 193, 92, 20, 0, 10, 135, 26, 23, 196, 153, 4, 197, 186, 20, 8, 197, 77, 160, 218, 60, 208, 20, 10, 135, 11, 197, 130, 1, 4, 197, 186, 20, 10, 135, 7, 197, 130, 1, 4, 197, 186, 20, 0, 14, 139, 19, 26, 197, 130, 25, 2, 25, 197, 155, 13, 25, 20, 14, 139, 19, 3, 8, 12, 9, 2, 25, 197, 155, 13, 25, 20, 11, 136, 26, 7, 197, 130, 1, 4, 197, 186, 20, 9, 134, 23, 18, 195, 179, 197, 188, 20, 0, 11, 136, 19, 26, 12, 9, 197, 155, 13, 25, 20, 7, 132, 20, 12, 196, 153, 20, 12, 137, 19, 26, 3, 26, 196, 153, 4, 197, 186, 20, 12, 137, 3, 8, 197, 130, 15, 19, 26, 3, 26, 20, 7, 195, 81, 144, 200, 72, 12, 15, 3, 95, 50, 88, 72, 84, 35, 120, 6, 109, 97, 119, 35, 0, 0, 16, 5, 95, 48, 77, 65, 49, 47, 112, 97, 6, 111, 50, 117, 109, 0, 15, 3, 95, 55, 67, 97, 6, 109, 72, 109, 65, 89, 109, 47, 0, 0, 0, 11, 136, 2, 197, 130, 25, 19, 26, 3, 26, 20, 18, 5, 95, 48, 77, 65, 51, 65, 38, 37, 55, 57, 6, 35, 51, 72, 112, 0, 0, 17, 70, 88, 20, 137, 21, 65, 83, 84, 35, 34, 57, 109, 47, 109, 0, 67, 17, 5, 95, 48, 77, 65, 50, 65, 38, 37, 55, 57, 6, 111, 50, 112, 0, 0, 7, 196, 81, 37, 193, 52, 20, 0, 17, 5, 95, 48, 77, 65, 52, 71, 38, 37, 55, 57, 6, 111, 50, 112, 0, 0, 0, 6, 195, 80, 176, 64, 20, 0, 14, 3, 95, 56, 67, 6, 111, 97, 109, 65, 89, 109, 47, 0, 0, 27, 69, 76, 52, 133, 20, 224, 89, 49, 51, 37, 50, 51, 6, 37, 72, 109, 34, 0, 81, 114, 101, 97, 100, 101, 114, 32, 0, 8, 133, 26, 2, 9, 196, 135, 20, 8, 133, 23, 2, 9, 196, 135, 20, 0, 9, 134, 23, 197, 188, 25, 196, 135, 20, 9, 134, 23, 26, 2, 9, 196, 135, 20, 8, 133, 11, 196, 133, 19, 26, 20, 8, 133, 10, 5, 4, 197, 186, 20, 9, 134, 4, 18, 7, 1, 196, 135, 20, 9, 134, 3, 26, 11, 1, 196, 135, 20, 0, 7, 196, 53, 37, 67, 104, 20, 9, 134, 197, 130, 1, 4, 197, 186, 20, 9, 134, 2, 18, 5, 4, 197, 186, 20, 12, 137, 10, 5, 19, 20, 5, 197, 155, 13, 25, 76, 12, 3, 95, 63, 63, 89, 112, 65, 71, 111, 55, 0, 0, 10, 135, 26, 23, 9, 5, 4, 197, 186, 20, 8, 197, 77, 160, 218, 84, 160, 20, 7, 132, 11, 21, 196, 135, 20, 0, 8, 133, 26, 9, 1, 196, 135, 20, 8, 133, 26, 2, 25, 196, 135, 20, 8, 133, 23, 18, 25, 196, 135, 20, 8, 133, 20, 12, 9, 196, 135, 20, 8, 133, 19, 26, 25, 196, 135, 20, 12, 137, 18, 197, 188, 14, 9, 196, 153, 196, 135, 20, 8, 133, 13, 9, 5, 196, 135, 20, 10, 135, 12, 197, 155, 14, 9, 196, 133, 20, 8, 133, 13, 9, 5, 196, 135, 76, 0, 12, 137, 19, 16, 18, 26, 196, 153, 4, 197, 186, 20, 9, 134, 12, 197, 188, 25, 196, 135, 20, 9, 134, 7, 14, 9, 5, 196, 135, 20, 9, 134, 4, 26, 9, 1, 196, 135, 20, 9, 134, 4, 14, 9, 5, 196, 135, 20, 17, 3, 95, 52, 88, 76, 47, 109, 51, 120, 6, 109, 97, 80, 38, 37, 0, 0, 10, 135, 23, 7, 14, 9, 5, 196, 135, 20, 10, 135, 197, 155, 13, 9, 5, 196, 135, 20, 10, 135, 19, 26, 11, 12, 9, 196, 135, 20, 10, 135, 19, 16, 197, 130, 25, 196, 135, 20, 7, 196, 76, 54, 133, 64, 20, 10, 135, 12, 197, 155, 14, 9, 196, 135, 20, 10, 135, 3, 8, 23, 9, 1, 196, 135, 20, 9, 134, 3, 8, 15, 4, 197, 186, 20, 10, 135, 3, 8, 3, 9, 5, 196, 135, 20, 9, 134, 2, 195, 179, 4, 197, 186, 20, 17, 3, 95, 57, 67, 120, 6, 109, 84, 38, 109, 67, 119, 89, 109, 47, 0, 0, 9, 134, 197, 188, 7, 14, 9, 5, 20, 10, 135, 26, 18, 195, 179, 4, 197, 186, 20, 8, 133, 26, 7, 1, 197, 132, 20, 10, 135, 19, 13, 18, 15, 4, 197, 186, 20, 10, 135, 19, 197, 130, 15, 4, 197, 186, 20, 11, 136, 16, 19, 20, 18, 26, 25, 196, 135, 20, 11, 136, 2, 197, 186, 4, 26, 9, 196, 135, 20, 10, 135, 2, 18, 195, 179, 4, 197, 186, 20, 0, 11, 136, 19, 13, 18, 195, 179, 4, 197, 186, 20, 7, 132, 11, 21, 197, 130, 20, 11, 136, 7, 197, 130, 195, 179, 4, 197, 186, 20, 0, 8, 133, 26, 9, 1, 197, 130, 20, 8, 133, 26, 2, 25, 197, 130, 20, 8, 133, 23, 18, 25, 197, 130, 20, 8, 133, 20, 12, 9, 197, 130, 20, 8, 133, 19, 26, 25, 197, 130, 20, 0, 7, 132, 19, 21, 197, 132, 20, 9, 134, 12, 197, 188, 25, 197, 130, 20, 9, 134, 4, 26, 9, 1, 197, 130, 20, 7, 196, 12, 132, 149, 64, 20, 0, 10, 135, 19, 26, 11, 12, 9, 197, 130, 20, 10, 135, 19, 16, 19, 9, 1, 197, 130, 20, 10, 135, 12, 197, 155, 14, 9, 197, 130, 20, 10, 135, 3, 8, 23, 9, 1, 197, 130, 20, 18, 67, 56, 17, 0, 50, 6, 35, 72, 84, 35, 89, 0, 81, 119, 97, 115, 32, 18, 67, 56, 17, 0, 50, 6, 35, 47, 47, 112, 65, 0, 81, 116, 121, 109, 32, 16, 67, 56, 17, 0, 50, 6, 35, 47, 47, 111, 0, 81, 116, 111, 32, 16, 67, 56, 17, 0, 50, 6, 35, 47, 47, 109, 0, 81, 116, 101, 32, 17, 67, 56, 17, 0, 50, 6, 35, 47, 47, 114, 0, 81, 116, 196, 133, 32, 18, 67, 56, 17, 0, 50, 6, 35, 72, 67, 38, 109, 0, 81, 110, 105, 101, 32, 19, 67, 56, 17, 0, 50, 6, 35, 72, 67, 37, 107, 0, 81, 110, 105, 99, 104, 32, 18, 67, 56, 17, 0, 50, 6, 35, 72, 67, 37, 65, 0, 81, 110, 105, 109, 32, 19, 67, 56, 17, 0, 50, 6, 35, 72, 67, 38, 114, 0, 81, 110, 105, 196, 133, 32, 18, 67, 56, 17, 0, 50, 6, 35, 72, 50, 35, 89, 0, 81, 110, 97, 115, 32, 6, 195, 56, 17, 0, 76, 0, 11, 136, 16, 19, 20, 18, 26, 25, 197, 130, 20, 11, 136, 2, 197, 186, 4, 26, 9, 197, 130, 20, 16, 66, 56, 16, 50, 6, 35, 84, 35, 89, 0, 81, 119, 97, 115, 32, 17, 66, 56, 16, 50, 6, 35, 47, 112, 65, 10, 0, 81, 116, 121, 109, 32, 17, 66, 56, 16, 50, 6, 35, 47, 112, 107, 0, 81, 116, 121, 99, 104, 32, 14, 66, 56, 16, 50, 6, 35, 47, 111, 0, 81, 116, 111, 32, 14, 66, 56, 16, 50, 6, 35, 47, 109, 0, 81, 116, 101, 32, 15, 66, 56, 16, 50, 6, 35, 47, 114, 0, 81, 116, 196, 133, 32, 17, 66, 56, 16, 50, 6, 35, 67, 38, 114, 0, 81, 110, 105, 196, 133, 32, 16, 66, 56, 16, 50, 6, 35, 67, 38, 109, 0, 81, 110, 105, 101, 32, 17, 66, 56, 16, 50, 6, 35, 67, 37, 107, 0, 81, 110, 105, 99, 104, 32, 16, 66, 56, 16, 50, 6, 35, 67, 37, 65, 0, 81, 110, 105, 109, 32, 18, 66, 56, 16, 50, 6, 35, 67, 38, 109, 57, 0, 81, 110, 105, 101, 106, 32, 16, 66, 56, 16, 50, 6, 35, 50, 35, 89, 0, 81, 110, 97, 115, 32, 18, 66, 56, 16, 50, 6, 35, 65, 67, 38, 109, 0, 81, 109, 110, 105, 101, 32, 5, 194, 56, 16, 76, 0, 8, 133, 26, 2, 9, 197, 130, 20, 10, 135, 23, 16, 197, 130, 25, 197, 132, 20, 8, 133, 23, 2, 9, 197, 130, 20, 6, 195, 77, 69, 76, 20, 10, 135, 19, 16, 197, 130, 25, 197, 132, 20, 6, 195, 28, 243, 0, 20, 16, 71, 12, 128, 76, 48, 83, 135, 20, 76, 109, 55, 109, 50, 75, 0, 17, 3, 95, 53, 88, 48, 38, 109, 67, 120, 6, 109, 97, 111, 50, 47, 0, 0, 9, 134, 23, 197, 188, 25, 197, 130, 20, 9, 134, 23, 26, 2, 9, 197, 130, 20, 9, 134, 4, 18, 7, 1, 197, 130, 20, 9, 134, 3, 26, 11, 1, 197, 130, 20, 0, 6, 195, 65, 37, 74, 20, 0, 6, 195, 92, 67, 205, 20, 8, 133, 13, 9, 5, 197, 155, 20, 0, 0, 9, 134, 26, 14, 21, 4, 197, 186, 20, 7, 196, 77, 160, 82, 64, 20, 9, 134, 197, 130, 21, 4, 197, 186, 20, 9, 134, 2, 196, 133, 4, 197, 186, 20, 0, 10, 135, 26, 2, 18, 21, 4, 197, 186, 20, 10, 135, 23, 19, 20, 25, 4, 197, 186, 20, 6, 195, 81, 37, 74, 20, 10, 135, 19, 23, 196, 153, 4, 197, 186, 20, 10, 135, 197, 130, 1, 19, 26, 3, 26, 20, 10, 135, 2, 18, 26, 25, 4, 197, 186, 20, 12, 69, 60, 97, 137, 12, 80, 111, 83, 37, 89, 0, 0, 11, 136, 26, 18, 26, 196, 153, 4, 197, 186, 20, 11, 136, 16, 18, 26, 196, 153, 4, 197, 186, 20, 0, 12, 137, 23, 16, 18, 26, 196, 153, 4, 197, 186, 20, 12, 137, 19, 16, 18, 26, 196, 133, 4, 197, 186, 20, 15, 67, 81, 163, 128, 47, 111, 15, 88, 50, 35, 76, 112, 0, 24, 16, 3, 95, 54, 88, 91, 109, 96, 120, 6, 109, 97, 111, 50, 47, 0, 0, 9, 134, 197, 188, 7, 14, 9, 10, 20, 9, 134, 26, 18, 15, 4, 197, 186, 20, 9, 134, 23, 18, 15, 4, 197, 186, 20, 0, 10, 135, 23, 3, 8, 15, 4, 197, 186, 20, 0, 0, 6, 195, 52, 19, 64, 20, 6, 195, 52, 19, 64, 76, 0, 15, 70, 52, 243, 147, 36, 85, 82, 65, 109, 89, 57, 6, 109, 0, 0, 0, 6, 195, 16, 35, 205, 20, 0, 0, 0, 8, 133, 26, 14, 9, 197, 188, 20, 7, 132, 11, 21, 197, 155, 20, 0, 7, 132, 197, 188, 25, 10, 20, 8, 133, 26, 23, 1, 196, 135, 20, 8, 133, 20, 11, 1, 196, 135, 20, 8, 133, 19, 19, 1, 196, 135, 20, 8, 133, 18, 23, 1, 196, 135, 20, 6, 195, 52, 19, 89, 76, 0, 8, 133, 26, 12, 9, 197, 186, 20, 9, 134, 26, 7, 14, 9, 196, 135, 20, 9, 134, 20, 18, 23, 1, 196, 135, 20, 10, 135, 19, 20, 18, 26, 25, 197, 188, 20, 8, 133, 10, 21, 4, 197, 186, 20, 0, 9, 134, 26, 23, 9, 4, 197, 186, 20, 9, 134, 19, 196, 133, 4, 197, 186, 20, 10, 135, 13, 11, 14, 196, 133, 196, 135, 20, 9, 134, 2, 18, 21, 4, 197, 186, 20, 0, 8, 133, 26, 13, 1, 197, 188, 20, 10, 135, 26, 2, 196, 133, 4, 197, 186, 20, 11, 136, 197, 155, 23, 9, 196, 153, 196, 135, 20, 10, 135, 18, 26, 196, 133, 4, 197, 186, 20, 7, 132, 3, 21, 196, 135, 20, 0, 8, 133, 26, 18, 25, 196, 135, 20, 8, 133, 26, 7, 1, 197, 155, 20, 8, 133, 23, 16, 9, 196, 135, 20, 8, 133, 23, 9, 1, 196, 135, 20, 8, 133, 19, 16, 9, 196, 135, 20, 8, 133, 19, 9, 1, 196, 135, 20, 11, 136, 16, 18, 26, 196, 133, 4, 197, 186, 20, 8, 133, 16, 9, 1, 196, 135, 20, 12, 137, 4, 197, 188, 4, 197, 188, 25, 196, 135, 20, 11, 136, 2, 197, 130, 196, 133, 4, 197, 186, 20, 18, 67, 65, 38, 153, 48, 91, 6, 112, 84, 35, 89, 0, 81, 119, 97, 115, 32, 18, 67, 65, 38, 153, 48, 91, 6, 112, 47, 112, 65, 0, 81, 116, 121, 109, 32, 19, 67, 65, 38, 153, 48, 91, 6, 112, 47, 112, 107, 0, 81, 116, 121, 99, 104, 32, 18, 67, 65, 38, 153, 48, 91, 6, 112, 47, 109, 57, 0, 81, 116, 101, 106, 32, 18, 67, 65, 38, 153, 48, 91, 6, 112, 67, 37, 65, 0, 81, 110, 105, 109, 32, 20, 67, 65, 38, 153, 48, 91, 6, 112, 67, 38, 109, 57, 0, 81, 110, 105, 101, 106, 32, 19, 67, 65, 38, 153, 48, 91, 6, 112, 67, 37, 107, 0, 81, 110, 105, 99, 104, 32, 18, 67, 65, 38, 153, 48, 91, 6, 112, 50, 35, 89, 0, 81, 110, 97, 115, 32, 20, 67, 65, 38, 153, 48, 91, 6, 112, 65, 67, 38, 109, 0, 81, 109, 110, 105, 101, 32, 6, 195, 65, 38, 153, 76, 0, 12, 137, 26, 2, 197, 130, 196, 133, 4, 197, 186, 20, 12, 137, 23, 16, 18, 26, 196, 133, 4, 197, 186, 20, 15, 67, 13, 68, 140, 49, 6, 111, 50, 47, 51, 111, 55, 0, 17, 17, 3, 95, 56, 88, 111, 97, 109, 65, 120, 6, 109, 97, 111, 50, 47, 0, 0, 9, 134, 26, 13, 18, 15, 197, 186, 20, 10, 135, 197, 155, 23, 9, 5, 196, 135, 20, 10, 135, 19, 26, 3, 26, 25, 196, 135, 20, 10, 135, 12, 7, 14, 9, 5, 196, 135, 20, 10, 135, 12, 7, 14, 196, 133, 196, 135, 20, 0, 11, 136, 26, 7, 23, 1, 197, 130, 196, 135, 20, 11, 136, 20, 3, 8, 14, 9, 5, 196, 135, 20, 10, 135, 13, 197, 155, 3, 9, 19, 26, 20, 0, 12, 137, 23, 19, 26, 3, 26, 196, 133, 196, 135, 20, 9, 134, 3, 8, 3, 5, 197, 132, 20, 9, 67, 12, 195, 213, 49, 55, 40, 0, 0, 8, 133, 26, 18, 25, 197, 130, 20, 8, 133, 23, 16, 9, 197, 130, 20, 8, 133, 23, 9, 1, 197, 130, 20, 8, 133, 19, 16, 9, 197, 130, 20, 8, 133, 19, 9, 1, 197, 130, 20, 8, 133, 16, 9, 1, 197, 130, 20, 26, 12, 19, 16, 195, 169, 3, 9, 1, 12, 9, 20, 195, 169, 89, 48, 109, 89, 57, 35, 55, 37, 47, 6, 109, 0, 0, 0, 10, 135, 12, 7, 14, 196, 133, 197, 130, 20, 0, 11, 136, 7, 18, 26, 13, 9, 1, 197, 130, 20, 5, 194, 36, 208, 72, 0, 8, 133, 197, 188, 25, 197, 130, 20, 8, 133, 26, 23, 1, 197, 130, 20, 12, 137, 23, 19, 26, 3, 26, 196, 133, 197, 130, 20, 8, 133, 20, 11, 1, 197, 130, 20, 8, 133, 19, 19, 1, 197, 130, 20, 8, 133, 18, 23, 1, 197, 130, 20, 19, 3, 95, 57, 88, 120, 109, 84, 38, 109, 67, 120, 6, 109, 97, 111, 50, 47, 0, 0, 9, 134, 26, 7, 14, 9, 197, 130, 20, 9, 134, 20, 18, 23, 1, 197, 130, 20, 7, 196, 17, 37, 201, 40, 20, 0, 10, 135, 13, 11, 14, 196, 133, 197, 130, 20, 6, 195, 52, 145, 74, 20, 13, 69, 24, 243, 132, 84, 80, 83, 114, 72, 6, 37, 0, 12, 69, 88, 243, 196, 60, 240, 84, 40, 72, 40, 0, 0, 9, 198, 65, 38, 153, 45, 38, 128, 20, 8, 133, 14, 9, 5, 197, 155, 20, 7, 132, 9, 4, 197, 186, 20, 0, 11, 136, 16, 9, 15, 197, 130, 2, 25, 13, 20, 6, 195, 52, 145, 76, 20, 12, 137, 4, 197, 188, 4, 197, 188, 25, 197, 130, 20, 0, 9, 134, 197, 155, 12, 5, 19, 26, 20, 0, 8, 197, 17, 33, 206, 36, 80, 20, 0, 5, 194, 53, 80, 72, 12, 3, 95, 63, 65, 55, 37, 47, 109, 51, 35, 0, 0, 0, 9, 134, 18, 195, 179, 4, 197, 186, 20, 0, 10, 135, 23, 18, 195, 179, 4, 197, 186, 20, 6, 195, 80, 176, 74, 20, 10, 135, 19, 3, 8, 15, 4, 197, 186, 20, 10, 135, 7, 18, 195, 179, 4, 197, 186, 20, 0, 6, 195, 80, 176, 77, 20, 11, 136, 19, 197, 130, 195, 179, 4, 197, 186, 20, 11, 136, 16, 197, 130, 195, 179, 4, 197, 186, 20, 10, 135, 12, 197, 155, 14, 9, 196, 153, 20, 0, 12, 137, 19, 16, 197, 130, 195, 179, 4, 197, 186, 20, 12, 137, 19, 3, 8, 197, 130, 15, 4, 197, 186, 20, 12, 137, 3, 8, 197, 130, 195, 179, 4, 197, 186, 20, 0, 13, 138, 19, 3, 8, 197, 130, 195, 179, 4, 197, 186, 20, 7, 196, 52, 20, 148, 92, 20, 0, 0, 0, 0, 0, 9, 134, 26, 7, 18, 25, 197, 186, 20, 0, 9, 134, 26, 23, 9, 5, 197, 155, 20, 6, 195, 105, 112, 66, 20, 10, 135, 19, 11, 15, 197, 132, 3, 26, 20, 0, 7, 132, 23, 5, 197, 186, 20, 0, 11, 136, 19, 20, 18, 26, 196, 153, 197, 155, 20, 9, 134, 18, 197, 188, 14, 196, 133, 20, 17, 4, 95, 15, 7, 15, 88, 111, 81, 6, 111, 50, 80, 38, 109, 65, 0, 0, 9, 134, 197, 188, 18, 5, 19, 26, 20, 6, 195, 104, 227, 205, 20, 0, 7, 132, 16, 14, 196, 133, 20, 0, 10, 135, 7, 23, 1, 197, 130, 196, 135, 20, 0, 6, 195, 93, 67, 208, 20, 10, 199, 52, 144, 210, 61, 51, 198, 80, 65, 0, 10, 135, 11, 20, 195, 179, 18, 196, 133, 76, 0, 6, 195, 105, 114, 74, 20, 8, 197, 92, 144, 200, 73, 160, 20, 13, 137, 16, 18, 26, 5, 3, 9, 5, 197, 188, 76, 8, 0, 11, 136, 23, 16, 5, 197, 130, 26, 197, 130, 20, 11, 136, 19, 16, 5, 197, 130, 26, 197, 130, 20, 0, 13, 138, 14, 9, 5, 11, 20, 195, 179, 18, 196, 133, 76, 0, 9, 134, 26, 13, 1, 18, 197, 130, 20, 6, 195, 17, 33, 193, 20, 0, 10, 135, 16, 5, 197, 130, 26, 197, 130, 20, 6, 195, 64, 19, 0, 20, 8, 197, 12, 128, 82, 13, 160, 20, 0, 0, 11, 136, 7, 18, 26, 13, 9, 196, 133, 3, 20, 0, 6, 195, 105, 114, 69, 20, 6, 195, 73, 114, 69, 20, 0, 8, 133, 19, 11, 1, 197, 188, 20, 0, 9, 198, 104, 226, 69, 52, 54, 128, 20, 11, 136, 26, 13, 9, 196, 153, 11, 3, 26, 20, 9, 198, 81, 35, 211, 104, 54, 128, 20, 0, 8, 133, 19, 11, 1, 197, 186, 20, 10, 199, 13, 165, 5, 73, 148, 212, 84, 65, 0, 7, 196, 9, 166, 67, 104, 20, 12, 68, 40, 84, 146, 100, 75, 109, 51, 112, 0, 9, 10, 68, 40, 84, 146, 100, 75, 109, 51, 0, 0, 0, 9, 134, 26, 2, 12, 9, 197, 188, 20, 15, 67, 65, 35, 195, 48, 34, 6, 111, 117, 109, 50, 47, 0, 24, 0, 0, 7, 196, 105, 112, 82, 104, 20, 7, 196, 76, 147, 210, 8, 20, 17, 4, 95, 48, 77, 52, 71, 38, 37, 55, 57, 6, 111, 50, 40, 83, 0, 0, 6, 195, 73, 114, 74, 20, 16, 67, 65, 35, 198, 48, 51, 111, 83, 6, 109, 89, 111, 51, 0, 24, 0, 9, 198, 52, 147, 137, 53, 83, 64, 65, 15, 70, 52, 21, 82, 20, 83, 128, 65, 111, 51, 6, 37, 50, 0, 17, 4, 95, 48, 77, 50, 65, 38, 37, 55, 57, 6, 111, 50, 40, 83, 0, 0, 9, 67, 88, 243, 128, 83, 111, 50, 0, 18, 4, 95, 48, 77, 51, 65, 38, 37, 55, 57, 6, 35, 51, 72, 40, 83, 0, 0, 0, 15, 4, 95, 48, 77, 49, 47, 112, 97, 6, 109, 50, 117, 112, 0, 0, 5, 194, 60, 64, 72, 14, 4, 95, 2, 18, 22, 71, 51, 6, 109, 84, 37, 89, 0, 0, 8, 133, 23, 12, 9, 197, 186, 20, 8, 133, 3, 5, 4, 197, 186, 20, 0, 9, 134, 26, 23, 9, 5, 197, 186, 20, 9, 134, 26, 19, 1, 4, 197, 186, 20, 9, 134, 23, 19, 1, 4, 197, 186, 20, 0, 8, 133, 26, 23, 1, 197, 188, 20, 9, 134, 197, 130, 11, 1, 196, 135, 20, 0, 8, 133, 2, 18, 14, 196, 133, 20, 0, 9, 134, 20, 3, 8, 14, 196, 133, 20, 9, 134, 19, 11, 12, 14, 196, 133, 20, 18, 71, 13, 35, 201, 77, 48, 78, 80, 49, 51, 40, 35, 89, 6, 35, 68, 0, 0, 6, 195, 104, 116, 129, 20, 9, 134, 7, 18, 15, 4, 197, 186, 20, 9, 134, 2, 18, 15, 4, 197, 186, 20, 0, 8, 133, 19, 13, 1, 197, 188, 20, 17, 8, 4, 5, 12, 39, 1, 18, 20, 5, 72, 109, 55, 6, 35, 51, 0, 0, 8, 133, 197, 130, 197, 188, 5, 20, 8, 133, 11, 12, 14, 196, 133, 20, 14, 3, 197, 155, 23, 97, 84, 38, 109, 50, 47, 112, 0, 24, 0, 9, 134, 16, 3, 8, 14, 196, 133, 20, 17, 70, 24, 16, 201, 20, 225, 9, 83, 35, 89, 57, 109, 50, 72, 37, 0, 0, 8, 133, 19, 19, 196, 133, 3, 20, 0, 7, 132, 16, 14, 196, 153, 20, 0, 11, 136, 26, 26, 9, 196, 133, 2, 197, 130, 20, 9, 134, 197, 130, 11, 1, 197, 132, 20, 0, 24, 3, 197, 155, 16, 97, 84, 38, 109, 50, 47, 109, 57, 15, 48, 35, 65, 38, 109, 67, 119, 37, 0, 24, 0, 9, 134, 26, 4, 1, 18, 197, 130, 20, 9, 134, 23, 4, 1, 18, 197, 130, 20, 6, 195, 81, 37, 193, 20, 9, 134, 197, 130, 11, 1, 197, 130, 20, 0, 10, 135, 26, 13, 1, 18, 26, 197, 130, 20, 0, 10, 135, 197, 155, 16, 9, 196, 133, 3, 20, 5, 194, 52, 144, 72, 0, 9, 134, 18, 197, 188, 14, 196, 153, 20, 11, 136, 12, 197, 155, 14, 9, 196, 133, 3, 20, 0, 0, 10, 135, 14, 9, 15, 197, 132, 3, 26, 20, 15, 69, 16, 83, 5, 80, 80, 72, 37, 55, 6, 109, 57, 47, 0, 0, 0, 0, 7, 196, 77, 1, 83, 104, 20, 0, 14, 69, 12, 194, 67, 32, 80, 49, 55, 37, 91, 6, 109, 0, 11, 136, 2, 25, 12, 9, 197, 155, 13, 25, 76, 0, 12, 137, 19, 3, 8, 12, 9, 197, 155, 13, 25, 20, 12, 137, 19, 26, 197, 130, 25, 197, 155, 13, 25, 20, 5, 194, 53, 144, 76, 0, 6, 195, 105, 112, 76, 20, 10, 135, 19, 16, 18, 196, 153, 197, 188, 20, 0, 0, 8, 133, 19, 11, 196, 133, 16, 20, 0, 9, 198, 52, 22, 9, 53, 83, 64, 65, 0, 9, 67, 61, 85, 0, 35, 58, 47, 0, 0, 0, 8, 197, 76, 180, 154, 101, 112, 20, 8, 133, 19, 9, 196, 133, 16, 20, 0, 0, 6, 195, 16, 192, 64, 72, 6, 195, 32, 64, 64, 17, 0, 7, 196, 77, 67, 9, 40, 20, 9, 134, 4, 18, 197, 188, 25, 10, 20, 13, 68, 88, 242, 76, 4, 84, 40, 35, 55, 35, 0, 67, 0, 9, 134, 26, 14, 9, 5, 197, 155, 20, 9, 134, 23, 14, 9, 5, 197, 155, 20, 9, 134, 23, 7, 18, 15, 196, 135, 20, 9, 134, 196, 135, 16, 15, 196, 135, 20, 9, 134, 3, 8, 12, 15, 196, 135, 20, 8, 197, 9, 38, 141, 36, 160, 20, 0, 10, 135, 19, 3, 8, 12, 15, 196, 135, 20, 7, 132, 16, 195, 179, 10, 20, 0, 7, 132, 12, 15, 196, 135, 20, 6, 195, 28, 224, 64, 20, 10, 135, 4, 26, 9, 5, 18, 197, 188, 20, 6, 195, 60, 224, 64, 76, 0, 9, 134, 26, 8, 1, 197, 132, 2, 20, 11, 136, 26, 4, 26, 9, 5, 18, 197, 188, 20, 0, 10, 135, 26, 13, 9, 5, 18, 197, 186, 20, 9, 134, 26, 197, 130, 15, 196, 135, 20, 8, 197, 77, 160, 218, 100, 160, 20, 9, 134, 19, 20, 18, 15, 196, 135, 20, 9, 134, 19, 16, 18, 15, 196, 135, 20, 8, 197, 76, 180, 154, 100, 160, 20, 8, 197, 17, 33, 206, 36, 160, 20, 9, 134, 2, 197, 130, 15, 196, 135, 20, 0, 7, 132, 12, 15, 197, 130, 20, 0, 0, 9, 134, 19, 16, 18, 15, 197, 130, 20, 7, 132, 18, 15, 197, 132, 20, 0, 6, 195, 52, 20, 154, 20, 0, 11, 136, 26, 14, 9, 195, 179, 19, 197, 130, 20, 11, 136, 23, 14, 9, 195, 179, 19, 197, 130, 20, 0, 6, 195, 60, 225, 64, 76, 0, 9, 134, 23, 7, 18, 15, 197, 130, 20, 7, 132, 20, 15, 197, 132, 20, 7, 196, 77, 3, 15, 52, 20, 9, 134, 18, 197, 188, 15, 197, 130, 20, 9, 134, 13, 9, 12, 11, 197, 130, 20, 9, 134, 13, 4, 12, 15, 197, 130, 20, 8, 133, 197, 130, 195, 179, 23, 20, 9, 134, 196, 135, 16, 15, 197, 130, 20, 9, 134, 3, 8, 12, 15, 197, 130, 20, 9, 198, 40, 243, 129, 80, 128, 78, 65, 0, 10, 135, 26, 13, 195, 179, 7, 197, 130, 20, 10, 135, 26, 13, 9, 12, 11, 197, 130, 20, 10, 135, 19, 3, 8, 12, 15, 197, 130, 20, 6, 195, 65, 53, 74, 20, 8, 197, 45, 2, 79, 73, 160, 20, 10, 135, 11, 12, 196, 153, 19, 197, 130, 20, 0, 11, 136, 23, 26, 13, 195, 179, 7, 197, 130, 20, 9, 134, 19, 20, 18, 15, 197, 132, 20, 11, 136, 19, 11, 12, 196, 153, 19, 197, 130, 20, 9, 134, 11, 197, 130, 15, 197, 132, 20, 9, 134, 3, 8, 18, 15, 197, 132, 20, 8, 133, 2, 18, 14, 196, 153, 20, 6, 194, 56, 144, 72, 23, 0, 6, 195, 104, 115, 204, 20, 6, 195, 80, 194, 64, 20, 10, 135, 19, 11, 197, 130, 15, 197, 132, 20, 9, 134, 19, 11, 12, 14, 196, 153, 20, 10, 135, 19, 3, 8, 18, 15, 197, 132, 20, 6, 195, 53, 146, 128, 20, 15, 70, 40, 80, 78, 21, 69, 5, 90, 35, 50, 6, 109, 47, 0, 0, 9, 134, 20, 1, 197, 132, 3, 26, 20, 6, 195, 28, 226, 69, 20, 0, 0, 9, 198, 76, 50, 12, 5, 54, 128, 20, 13, 5, 3, 1, 6, 195, 169, 49, 35, 83, 109, 0, 66, 0, 8, 133, 19, 20, 195, 179, 10, 20, 6, 195, 45, 82, 128, 20, 6, 195, 60, 226, 64, 76, 10, 199, 16, 148, 195, 61, 97, 82, 100, 66, 0, 6, 195, 80, 179, 205, 20, 0, 24, 69, 65, 38, 133, 16, 80, 48, 91, 109, 72, 6, 109, 65, 67, 38, 109, 0, 81, 109, 110, 105, 101, 32, 23, 69, 65, 38, 133, 16, 80, 48, 91, 109, 72, 6, 109, 65, 50, 114, 0, 81, 109, 110, 196, 133, 32, 0, 7, 132, 18, 195, 179, 2, 20, 11, 136, 3, 8, 197, 130, 5, 16, 3, 26, 20, 0, 8, 133, 23, 18, 195, 179, 2, 20, 0, 6, 195, 28, 224, 77, 20, 0, 8, 197, 65, 53, 18, 105, 144, 20, 6, 195, 28, 224, 74, 20, 0, 8, 133, 11, 12, 14, 196, 153, 20, 16, 4, 95, 3, 9, 18, 88, 72, 6, 35, 91, 80, 38, 109, 65, 0, 0, 8, 133, 26, 4, 195, 179, 2, 20, 9, 134, 16, 3, 8, 14, 196, 153, 20, 10, 199, 76, 145, 68, 20, 212, 197, 80, 65, 0, 7, 196, 92, 145, 76, 8, 20, 9, 198, 81, 38, 133, 77, 160, 218, 20, 0, 6, 195, 76, 229, 74, 20, 0, 0, 9, 134, 20, 3, 8, 14, 196, 153, 20, 7, 132, 2, 15, 196, 135, 20, 15, 67, 52, 193, 0, 65, 37, 55, 57, 35, 51, 72, 40, 83, 0, 0, 9, 134, 23, 18, 196, 153, 3, 26, 20, 6, 195, 80, 181, 201, 20, 7, 196, 76, 180, 153, 40, 20, 8, 133, 11, 14, 15, 196, 135, 20, 8, 133, 7, 18, 15, 196, 135, 20, 8, 133, 7, 14, 15, 196, 135, 20, 8, 133, 4, 2, 15, 196, 135, 20, 8, 133, 2, 18, 15, 196, 135, 20, 11, 68, 76, 48, 78, 20, 89, 49, 35, 50, 0, 0, 9, 134, 11, 197, 130, 15, 197, 155, 20, 9, 134, 7, 18, 26, 15, 196, 135, 20, 0, 0, 8, 133, 23, 16, 195, 179, 10, 20, 8, 133, 19, 16, 195, 179, 10, 20, 7, 132, 14, 15, 197, 155, 20, 7, 132, 4, 15, 196, 135, 20, 18, 71, 12, 128, 78, 80, 147, 12, 100, 91, 35, 50, 47, 37, 57, 37, 0, 67, 0, 7, 196, 45, 37, 83, 104, 20, 19, 67, 13, 84, 129, 49, 37, 51, 35, 89, 35, 111, 0, 81, 195, 167, 97, 111, 32, 11, 67, 40, 244, 197, 107, 111, 88, 6, 109, 0, 0, 9, 134, 23, 19, 20, 15, 196, 135, 20, 9, 134, 23, 16, 18, 15, 197, 155, 20, 9, 134, 19, 197, 130, 15, 196, 135, 20, 9, 134, 19, 11, 14, 15, 196, 135, 20, 9, 134, 16, 3, 8, 15, 196, 135, 20, 6, 195, 12, 226, 74, 20, 6, 195, 8, 240, 218, 20, 0, 10, 135, 26, 7, 197, 130, 15, 197, 155, 20, 7, 132, 4, 15, 197, 130, 20, 15, 70, 12, 128, 66, 48, 148, 192, 91, 35, 71, 55, 37, 0, 66, 0, 8, 133, 12, 5, 7, 197, 130, 20, 9, 134, 2, 196, 153, 4, 196, 133, 76, 17, 4, 95, 19, 20, 11, 89, 49, 51, 109, 97, 55, 6, 111, 50, 109, 0, 0, 9, 134, 23, 19, 20, 15, 197, 130, 20, 9, 134, 19, 197, 130, 15, 197, 130, 20, 9, 134, 16, 3, 8, 15, 197, 130, 20, 0, 10, 135, 23, 9, 196, 153, 4, 197, 130, 20, 6, 195, 28, 226, 74, 20, 8, 133, 2, 18, 15, 197, 132, 20, 14, 4, 95, 1, 3, 21, 10, 6, 111, 89, 47, 51, 109, 0, 0, 11, 136, 16, 18, 26, 196, 133, 7, 197, 130, 20, 20, 3, 95, 195, 179, 4, 40, 10, 49, 51, 109, 89, 49, 111, 84, 6, 35, 50, 109, 0, 0, 12, 137, 23, 16, 18, 26, 196, 133, 7, 197, 130, 20, 12, 137, 19, 16, 18, 26, 196, 133, 7, 197, 130, 20, 8, 133, 16, 1, 19, 197, 130, 20, 8, 133, 7, 18, 15, 197, 130, 20, 8, 133, 7, 14, 15, 197, 130, 20, 8, 133, 4, 2, 15, 197, 130, 20, 0, 9, 134, 26, 7, 1, 19, 197, 130, 20, 9, 134, 13, 195, 179, 7, 197, 130, 20, 9, 134, 7, 18, 26, 15, 197, 130, 20, 10, 135, 4, 197, 186, 7, 14, 9, 5, 20, 0, 10, 135, 23, 13, 1, 18, 26, 197, 130, 20, 10, 135, 4, 18, 197, 188, 15, 197, 130, 20, 0, 7, 132, 2, 195, 179, 10, 20, 0, 10, 135, 19, 16, 5, 197, 130, 197, 132, 20, 8, 133, 18, 196, 153, 3, 26, 20, 8, 133, 13, 196, 153, 3, 26, 20, 8, 133, 10, 196, 153, 3, 26, 20, 9, 134, 2, 197, 186, 4, 26, 9, 20, 9, 134, 13, 9, 1, 197, 130, 25, 76, 0, 9, 134, 26, 7, 14, 195, 179, 10, 20, 0, 9, 134, 19, 16, 18, 15, 197, 155, 20, 14, 69, 88, 149, 129, 12, 80, 84, 37, 84, 35, 76, 109, 0, 0, 11, 136, 23, 4, 26, 9, 196, 153, 3, 26, 20, 7, 132, 4, 195, 179, 10, 20, 0, 12, 137, 4, 197, 186, 23, 9, 196, 153, 3, 26, 20, 16, 4, 95, 18, 14, 7, 88, 49, 6, 40, 58, 80, 38, 109, 65, 0, 0, 9, 134, 4, 18, 196, 153, 3, 26, 20, 0, 9, 134, 7, 197, 130, 15, 197, 155, 20, 10, 135, 4, 197, 186, 7, 14, 9, 10, 20, 10, 135, 2, 18, 26, 196, 153, 3, 26, 20, 17, 70, 12, 243, 5, 76, 192, 87, 49, 111, 55, 109, 89, 55, 111, 58, 0, 0, 9, 67, 72, 240, 203, 34, 111, 49, 0, 17, 70, 4, 229, 8, 60, 230, 64, 109, 50, 47, 111, 50, 112, 0, 65, 9, 14, 70, 4, 229, 8, 60, 230, 64, 109, 50, 47, 111, 50, 0, 0, 8, 133, 26, 18, 195, 179, 2, 20, 0, 7, 196, 13, 166, 73, 52, 76, 0, 0, 0, 9, 134, 2, 196, 153, 4, 196, 153, 76, 0, 7, 132, 20, 196, 153, 16, 20, 10, 67, 64, 192, 89, 48, 55, 109, 57, 0, 0, 8, 197, 76, 180, 151, 5, 112, 20, 0, 0, 0, 10, 135, 19, 26, 197, 130, 25, 2, 25, 20, 7, 196, 93, 51, 149, 40, 20, 9, 198, 5, 32, 200, 37, 33, 74, 67, 0, 9, 134, 16, 9, 3, 8, 196, 135, 20, 0, 0, 0, 7, 196, 76, 176, 67, 104, 20, 0, 11, 136, 2, 197, 188, 4, 197, 188, 196, 133, 20, 0, 9, 134, 13, 14, 195, 179, 197, 188, 20, 8, 133, 11, 197, 130, 1, 13, 20, 0, 10, 135, 20, 18, 23, 195, 179, 197, 188, 20, 8, 133, 7, 14, 196, 153, 2, 20, 9, 134, 2, 25, 197, 130, 5, 13, 76, 0, 21, 67, 56, 17, 5, 50, 35, 72, 6, 109, 65, 67, 38, 109, 0, 81, 109, 110, 105, 101, 32, 20, 67, 56, 17, 5, 50, 35, 72, 6, 109, 65, 50, 114, 0, 81, 109, 110, 196, 133, 32, 11, 136, 11, 20, 195, 179, 18, 25, 3, 8, 76, 14, 68, 52, 144, 77, 36, 65, 35, 57, 6, 35, 65, 37, 0, 13, 68, 20, 161, 67, 80, 37, 90, 6, 109, 49, 47, 0, 0, 10, 135, 26, 4, 5, 3, 8, 197, 130, 20, 6, 195, 52, 20, 218, 76, 0, 11, 136, 197, 155, 3, 9, 3, 8, 197, 130, 20, 21, 4, 95, 1, 3, 50, 101, 4, 40, 68, 81, 35, 51, 6, 40, 65, 55, 35, 58, 47, 0, 0, 9, 134, 12, 15, 197, 130, 2, 25, 20, 14, 139, 14, 9, 5, 11, 20, 195, 179, 18, 25, 3, 8, 76, 0, 10, 135, 26, 9, 15, 197, 130, 2, 25, 20, 10, 135, 26, 4, 15, 197, 130, 2, 25, 20, 10, 135, 20, 12, 15, 197, 130, 2, 25, 20, 10, 135, 19, 20, 15, 197, 130, 2, 25, 20, 10, 135, 14, 9, 11, 197, 130, 2, 25, 20, 0, 11, 136, 19, 16, 18, 15, 197, 130, 2, 25, 20, 11, 136, 4, 18, 7, 15, 197, 130, 2, 25, 20, 11, 136, 3, 26, 11, 15, 197, 130, 2, 25, 20, 8, 197, 104, 115, 210, 77, 160, 20, 6, 195, 44, 229, 74, 20, 10, 135, 3, 9, 5, 18, 16, 197, 130, 20, 0, 15, 66, 64, 144, 48, 109, 37, 38, 6, 109, 89, 0, 81, 115, 32, 12, 137, 26, 18, 195, 179, 19, 197, 130, 2, 25, 20, 12, 137, 23, 18, 195, 179, 19, 197, 130, 2, 25, 20, 12, 137, 19, 16, 19, 9, 15, 197, 130, 2, 25, 20, 12, 137, 19, 16, 9, 5, 11, 197, 130, 2, 25, 20, 12, 137, 14, 9, 195, 179, 19, 197, 130, 2, 25, 20, 12, 137, 3, 8, 23, 9, 15, 197, 130, 2, 25, 20, 11, 66, 60, 176, 111, 49, 6, 109, 57, 0, 42, 11, 66, 60, 176, 111, 49, 111, 58, 111, 0, 24, 6, 194, 80, 16, 72, 12, 0, 13, 138, 26, 14, 9, 195, 179, 19, 197, 130, 2, 25, 20, 13, 138, 23, 26, 18, 195, 179, 19, 197, 130, 2, 25, 20, 13, 138, 23, 14, 9, 195, 179, 19, 197, 130, 2, 25, 20, 13, 138, 19, 20, 18, 26, 5, 7, 197, 130, 2, 25, 20, 12, 137, 197, 155, 3, 9, 5, 18, 16, 197, 130, 20, 12, 137, 16, 9, 5, 18, 26, 3, 8, 197, 130, 20, 0, 14, 139, 23, 26, 14, 9, 195, 179, 19, 197, 130, 2, 25, 20, 9, 198, 93, 53, 18, 104, 83, 0, 20, 0, 15, 140, 26, 197, 188, 195, 179, 197, 130, 11, 197, 130, 2, 25, 20, 6, 195, 64, 197, 74, 20, 0, 0, 8, 133, 13, 18, 15, 197, 186, 20, 8, 133, 12, 197, 188, 25, 10, 20, 13, 138, 2, 196, 153, 4, 26, 9, 5, 3, 9, 5, 76, 0, 18, 72, 40, 16, 209, 84, 83, 9, 56, 80, 90, 35, 49, 55, 6, 37, 50, 0, 0, 6, 195, 65, 147, 0, 20, 12, 69, 12, 128, 82, 52, 80, 91, 35, 51, 65, 0, 19, 71, 8, 16, 203, 77, 0, 67, 20, 71, 6, 109, 49, 89, 48, 109, 57, 89, 0, 0, 9, 134, 26, 13, 195, 179, 197, 188, 20, 0, 10, 135, 23, 4, 18, 195, 179, 197, 188, 20, 0, 10, 67, 12, 243, 1, 49, 111, 55, 35, 0, 0, 10, 135, 19, 20, 23, 195, 179, 18, 26, 20, 0, 11, 136, 19, 20, 3, 8, 195, 179, 18, 26, 20, 9, 134, 3, 26, 197, 130, 1, 16, 20, 0, 0, 7, 196, 104, 36, 153, 48, 20, 0, 7, 2, 196, 135, 119, 110, 0, 0, 0, 13, 67, 52, 164, 128, 65, 6, 35, 57, 111, 51, 0, 24, 6, 2, 196, 133, 114, 0, 0, 0, 0, 8, 133, 197, 155, 12, 196, 133, 20, 0, 0, 7, 196, 104, 34, 69, 12, 20, 0, 8, 197, 76, 50, 12, 4, 160, 20, 9, 134, 197, 130, 11, 15, 196, 135, 20, 10, 2, 195, 151, 51, 6, 35, 88, 112, 0, 0, 10, 135, 14, 9, 5, 197, 155, 196, 135, 20, 11, 136, 11, 18, 26, 25, 23, 4, 197, 186, 20, 7, 2, 197, 132, 109, 67, 0, 0, 10, 135, 23, 26, 13, 195, 179, 197, 188, 20, 11, 136, 19, 3, 26, 25, 197, 155, 196, 135, 20, 11, 136, 7, 14, 9, 5, 197, 155, 196, 135, 20, 9, 134, 2, 25, 197, 130, 1, 13, 76, 10, 199, 5, 32, 200, 36, 66, 65, 44, 67, 5, 130, 196, 141, 43, 5, 130, 196, 141, 43, 0, 12, 137, 23, 7, 14, 9, 5, 197, 155, 196, 135, 20, 9, 134, 197, 130, 11, 15, 197, 130, 20, 9, 134, 3, 9, 3, 8, 197, 130, 20, 7, 2, 197, 130, 109, 58, 0, 0, 8, 197, 12, 128, 197, 77, 160, 20, 0, 11, 136, 7, 197, 130, 21, 3, 8, 197, 130, 20, 0, 9, 134, 23, 25, 197, 130, 2, 25, 20, 9, 134, 18, 25, 197, 130, 2, 25, 20, 9, 134, 16, 9, 197, 130, 2, 25, 20, 9, 134, 11, 21, 197, 130, 2, 25, 20, 0, 10, 135, 26, 9, 1, 197, 130, 2, 25, 20, 10, 135, 26, 2, 25, 197, 130, 2, 25, 20, 10, 135, 23, 18, 25, 197, 130, 2, 25, 20, 10, 135, 20, 12, 9, 197, 130, 2, 25, 20, 10, 135, 19, 26, 25, 197, 130, 2, 25, 20, 10, 135, 16, 19, 21, 197, 130, 2, 25, 20, 10, 135, 16, 18, 1, 197, 130, 2, 25, 20, 10, 135, 16, 12, 21, 197, 130, 2, 25, 20, 10, 135, 13, 9, 1, 197, 130, 2, 25, 20, 10, 135, 11, 18, 25, 197, 130, 2, 25, 20, 9, 134, 23, 197, 155, 3, 9, 2, 20, 7, 196, 81, 37, 207, 52, 20, 11, 68, 4, 194, 67, 20, 109, 55, 37, 89, 0, 0, 11, 136, 26, 197, 188, 25, 197, 130, 2, 25, 20, 11, 136, 26, 197, 188, 21, 197, 130, 2, 25, 20, 11, 136, 26, 7, 18, 1, 197, 130, 2, 25, 20, 11, 136, 23, 19, 26, 25, 197, 130, 2, 25, 20, 11, 136, 23, 7, 18, 1, 197, 130, 2, 25, 20, 11, 136, 19, 16, 18, 1, 197, 130, 2, 25, 20, 11, 136, 12, 197, 188, 25, 197, 130, 2, 25, 20, 11, 136, 4, 26, 9, 1, 197, 130, 2, 25, 20, 11, 136, 4, 14, 9, 1, 197, 130, 2, 25, 20, 11, 136, 3, 26, 3, 9, 197, 130, 2, 25, 20, 8, 197, 105, 115, 5, 13, 160, 20, 8, 197, 81, 38, 133, 77, 160, 20, 10, 135, 20, 196, 153, 3, 8, 197, 130, 20, 8, 197, 64, 50, 1, 77, 160, 20, 14, 2, 194, 167, 48, 35, 51, 6, 35, 81, 51, 35, 83, 0, 16, 2, 195, 159, 91, 4, 35, 34, 83, 109, 89, 10, 6, 109, 89, 0, 0, 12, 137, 23, 4, 26, 9, 1, 197, 130, 2, 25, 20, 12, 137, 197, 155, 13, 9, 1, 197, 130, 2, 25, 20, 12, 137, 19, 26, 11, 12, 9, 197, 130, 2, 25, 20, 12, 137, 19, 16, 19, 9, 1, 197, 130, 2, 25, 20, 12, 137, 19, 197, 130, 1, 2, 197, 130, 2, 25, 20, 12, 137, 12, 197, 155, 14, 9, 197, 130, 2, 25, 20, 12, 137, 3, 8, 23, 9, 1, 197, 130, 2, 25, 20, 12, 137, 3, 8, 3, 9, 1, 197, 130, 2, 25, 20, 12, 2, 194, 164, 84, 35, 55, 6, 40, 47, 35, 0, 0, 13, 138, 23, 16, 5, 197, 130, 26, 197, 130, 2, 25, 20, 13, 138, 19, 16, 5, 197, 130, 26, 197, 130, 2, 25, 20, 13, 138, 16, 19, 20, 18, 26, 25, 197, 130, 2, 25, 20, 13, 138, 3, 8, 18, 26, 3, 9, 197, 130, 2, 25, 20, 13, 138, 2, 197, 186, 4, 26, 9, 197, 130, 2, 25, 20, 8, 133, 21, 10, 4, 197, 186, 20, 8, 2, 194, 165, 57, 109, 50, 0, 0, 9, 134, 14, 1, 10, 4, 197, 186, 20, 33, 68, 12, 144, 197, 72, 117, 4, 37, 117, 109, 51, 49, 40, 65, 49, 6, 35, 58, 55, 109, 0, 82, 99, 117, 109, 32, 99, 97, 117, 108, 101, 32, 9, 2, 194, 162, 117, 109, 50, 47, 0, 0, 11, 136, 2, 197, 188, 4, 197, 188, 196, 153, 20, 9, 2, 194, 163, 83, 40, 50, 47, 0, 0, 15, 70, 12, 245, 78, 81, 38, 64, 49, 35, 50, 47, 51, 112, 0, 0, 25, 2, 194, 161, 111, 72, 84, 51, 4, 111, 47, 50, 112, 15, 84, 112, 49, 91, 6, 112, 49, 67, 37, 49, 0, 0, 7, 196, 92, 34, 69, 12, 20, 7, 196, 76, 180, 154, 100, 20, 11, 136, 13, 9, 1, 197, 188, 4, 197, 188, 20, 16, 7, 3, 12, 9, 3, 8, 195, 169, 49, 55, 37, 91, 6, 109, 0, 15, 2, 194, 174, 88, 35, 89, 76, 109, 90, 6, 111, 50, 112, 0, 5, 130, 195, 166, 43, 5, 130, 195, 166, 43, 0, 12, 137, 26, 13, 9, 15, 197, 188, 4, 197, 188, 20, 8, 197, 76, 180, 154, 101, 0, 20, 17, 2, 194, 175, 50, 35, 72, 49, 51, 109, 97, 55, 6, 109, 67, 109, 0, 0, 15, 70, 12, 130, 65, 57, 66, 64, 49, 57, 35, 50, 47, 37, 0, 13, 2, 194, 172, 50, 109, 81, 6, 35, 117, 57, 35, 0, 5, 130, 195, 164, 43, 5, 130, 195, 164, 43, 0, 5, 130, 195, 165, 43, 5, 130, 195, 165, 43, 0, 10, 135, 13, 9, 1, 197, 130, 5, 13, 76, 0, 8, 133, 11, 197, 130, 1, 16, 20, 25, 2, 194, 171, 83, 51, 35, 50, 117, 4, 40, 89, 80, 37, 15, 117, 40, 118, 6, 112, 89, 58, 40, 83, 0, 0, 12, 2, 194, 168, 6, 40, 65, 55, 35, 58, 47, 0, 0, 9, 134, 4, 15, 197, 130, 2, 25, 20, 13, 2, 195, 161, 35, 55, 6, 35, 0, 81, 108, 97, 32, 6, 2, 196, 153, 113, 0, 0, 10, 135, 26, 12, 15, 197, 130, 2, 25, 20, 10, 135, 23, 12, 15, 197, 130, 2, 25, 20, 10, 135, 23, 9, 15, 197, 130, 2, 25, 20, 10, 135, 19, 16, 15, 197, 130, 2, 25, 20, 10, 135, 19, 9, 15, 197, 130, 2, 25, 20, 10, 135, 16, 9, 15, 197, 130, 2, 25, 20, 10, 135, 12, 5, 7, 197, 130, 2, 25, 20, 12, 2, 194, 182, 35, 49, 6, 35, 48, 37, 47, 0, 0, 11, 136, 26, 7, 1, 4, 197, 130, 2, 25, 20, 11, 136, 23, 19, 20, 15, 197, 130, 2, 25, 20, 11, 136, 23, 12, 5, 11, 197, 130, 2, 25, 20, 11, 136, 20, 18, 23, 15, 197, 130, 2, 25, 20, 11, 136, 19, 197, 130, 15, 197, 130, 2, 25, 20, 11, 136, 18, 195, 179, 19, 197, 130, 2, 25, 20, 11, 136, 16, 9, 5, 11, 197, 130, 2, 25, 20, 11, 136, 16, 3, 8, 15, 197, 130, 2, 25, 20, 11, 136, 12, 196, 133, 7, 197, 130, 2, 25, 20, 9, 134, 26, 4, 197, 130, 1, 23, 20, 9, 134, 23, 19, 197, 130, 1, 23, 20, 15, 69, 64, 17, 197, 85, 0, 48, 109, 57, 75, 6, 35, 48, 0, 0, 12, 137, 26, 23, 12, 5, 11, 197, 130, 2, 25, 20, 12, 137, 26, 2, 9, 5, 7, 197, 130, 2, 25, 20, 12, 137, 23, 9, 196, 153, 4, 197, 130, 2, 25, 20, 12, 137, 23, 2, 9, 5, 7, 197, 130, 2, 25, 20, 5, 194, 60, 224, 76, 19, 2, 194, 180, 4, 111, 89, 47, 51, 112, 10, 6, 35, 49, 117, 109, 50, 47, 0, 0, 13, 138, 26, 26, 9, 196, 133, 2, 197, 130, 2, 25, 20, 13, 138, 23, 23, 9, 195, 179, 26, 197, 130, 2, 25, 20, 13, 138, 19, 20, 197, 130, 21, 11, 197, 130, 2, 25, 20, 13, 138, 16, 18, 26, 196, 133, 7, 197, 130, 2, 25, 20, 13, 138, 7, 18, 26, 13, 9, 15, 197, 130, 2, 25, 20, 7, 132, 23, 9, 196, 135, 20, 7, 132, 13, 25, 196, 135, 20, 9, 67, 88, 144, 64, 84, 37, 35, 0, 5, 130, 195, 173, 43, 5, 130, 195, 173, 43, 0, 14, 139, 23, 16, 18, 26, 196, 133, 7, 197, 130, 2, 25, 20, 14, 139, 197, 155, 13, 9, 5, 18, 4, 197, 130, 2, 25, 20, 14, 139, 19, 16, 18, 26, 196, 133, 7, 197, 130, 2, 25, 20, 7, 196, 105, 115, 5, 12, 20, 8, 133, 26, 12, 5, 196, 135, 20, 9, 134, 26, 5, 10, 4, 197, 186, 20, 9, 134, 26, 1, 10, 4, 197, 186, 20, 8, 133, 23, 26, 21, 196, 135, 20, 9, 134, 23, 25, 10, 4, 197, 186, 20, 9, 134, 23, 5, 10, 4, 197, 186, 20, 8, 133, 20, 18, 21, 196, 135, 20, 9, 134, 197, 155, 16, 9, 19, 26, 20, 8, 133, 16, 18, 21, 196, 135, 20, 7, 196, 16, 226, 69, 40, 20, 8, 133, 4, 196, 133, 196, 135, 20, 13, 2, 194, 178, 49, 84, 6, 35, 72, 51, 35, 47, 0, 0, 10, 135, 26, 14, 1, 10, 4, 197, 186, 20, 9, 134, 26, 13, 196, 133, 196, 135, 20, 6, 195, 104, 145, 74, 20, 9, 134, 23, 26, 12, 5, 196, 135, 20, 10, 135, 23, 26, 5, 10, 4, 197, 186, 20, 10, 135, 23, 20, 197, 130, 15, 3, 26, 20, 10, 135, 23, 197, 130, 195, 179, 3, 26, 20, 9, 134, 23, 3, 26, 21, 196, 135, 20, 10, 135, 19, 20, 197, 130, 15, 3, 26, 20, 9, 134, 11, 12, 196, 133, 196, 135, 20, 10, 135, 7, 18, 1, 14, 4, 197, 186, 20, 9, 134, 7, 9, 196, 133, 196, 135, 20, 9, 134, 3, 9, 196, 133, 196, 135, 20, 9, 134, 3, 8, 23, 25, 196, 135, 20, 21, 10, 22, 1, 18, 9, 195, 169, 20, 195, 169, 19, 84, 35, 34, 57, 109, 47, 109, 0, 67, 12, 2, 194, 179, 91, 6, 109, 97, 78, 35, 50, 0, 7, 2, 197, 155, 97, 37, 0, 0, 11, 136, 26, 23, 197, 130, 195, 179, 3, 26, 20, 11, 136, 26, 7, 18, 1, 14, 4, 197, 186, 20, 10, 135, 26, 7, 9, 196, 133, 196, 135, 20, 10, 135, 23, 26, 9, 196, 133, 196, 135, 20, 10, 135, 23, 7, 9, 196, 133, 196, 135, 20, 10, 135, 23, 3, 9, 196, 133, 196, 135, 20, 10, 135, 19, 11, 12, 196, 133, 196, 135, 20, 10, 135, 19, 3, 8, 23, 25, 196, 135, 20, 13, 2, 194, 176, 89, 47, 6, 111, 48, 38, 109, 67, 0, 0, 8, 133, 197, 188, 18, 25, 10, 20, 7, 132, 23, 25, 196, 135, 20, 11, 136, 197, 155, 3, 9, 196, 133, 196, 135, 20, 7, 132, 19, 25, 196, 135, 20, 15, 2, 194, 177, 48, 55, 40, 89, 65, 6, 37, 50, 40, 89, 0, 5, 130, 197, 153, 43, 5, 130, 197, 153, 43, 0, 8, 133, 16, 12, 21, 196, 135, 20, 10, 135, 7, 18, 26, 13, 9, 196, 133, 20, 16, 2, 194, 190, 47, 15, 91, 112, 76, 83, 6, 35, 51, 47, 109, 0, 5, 130, 195, 182, 43, 5, 130, 195, 182, 43, 0, 9, 134, 23, 7, 18, 1, 196, 135, 20, 9, 134, 20, 18, 26, 5, 196, 135, 20, 9, 134, 19, 20, 18, 1, 196, 135, 20, 9, 134, 19, 16, 18, 1, 196, 135, 20, 9, 134, 16, 18, 26, 5, 196, 135, 20, 13, 67, 85, 35, 0, 40, 109, 51, 6, 109, 55, 0, 17, 23, 2, 194, 191, 111, 72, 84, 51, 4, 111, 47, 50, 112, 15, 48, 112, 47, 35, 57, 67, 37, 49, 0, 13, 2, 195, 183, 120, 109, 55, 6, 109, 67, 38, 109, 0, 0, 7, 132, 23, 25, 197, 130, 20, 17, 2, 194, 188, 57, 109, 72, 50, 35, 76, 83, 6, 35, 51, 47, 35, 0, 0, 8, 133, 16, 12, 21, 197, 130, 20, 7, 195, 56, 145, 64, 72, 23, 6, 195, 56, 145, 64, 76, 16, 2, 194, 189, 57, 109, 72, 50, 35, 72, 51, 6, 40, 81, 35, 0, 0, 7, 132, 23, 9, 197, 132, 20, 9, 134, 23, 7, 18, 1, 197, 130, 20, 9, 134, 19, 16, 18, 1, 197, 130, 20, 7, 195, 80, 83, 85, 72, 12, 15, 4, 95, 3, 5, 4, 88, 117, 109, 116, 6, 37, 55, 114, 0, 0, 8, 197, 92, 116, 129, 77, 160, 20, 7, 132, 18, 197, 188, 25, 20, 32, 2, 194, 187, 48, 51, 6, 35, 84, 112, 15, 83, 51, 35, 50, 117, 4, 40, 89, 80, 37, 15, 117, 40, 118, 6, 112, 89, 58, 40, 83, 0, 0, 9, 134, 23, 197, 188, 5, 197, 132, 20, 7, 132, 23, 9, 197, 130, 20, 7, 132, 13, 25, 197, 130, 20, 13, 2, 194, 184, 117, 109, 116, 6, 37, 55, 55, 35, 0, 0, 8, 133, 23, 26, 21, 197, 130, 20, 8, 133, 20, 18, 21, 197, 130, 20, 8, 133, 16, 18, 21, 197, 130, 20, 8, 133, 4, 196, 133, 197, 130, 20, 16, 2, 194, 185, 57, 109, 72, 109, 50, 81, 6, 40, 51, 50, 109, 0, 5, 130, 195, 177, 43, 5, 130, 197, 161, 43, 5, 130, 195, 177, 43, 5, 130, 197, 161, 43, 16, 4, 95, 12, 9, 7, 55, 37, 81, 35, 47, 6, 40, 51, 35, 0, 0, 10, 135, 10, 1, 4, 197, 130, 2, 25, 20, 9, 134, 23, 3, 26, 21, 197, 130, 20, 9, 134, 18, 197, 188, 1, 197, 130, 20, 7, 132, 18, 1, 197, 132, 20, 7, 132, 13, 9, 197, 132, 20, 9, 134, 11, 12, 196, 133, 197, 130, 20, 9, 134, 7, 9, 196, 133, 197, 130, 20, 0, 11, 136, 26, 10, 1, 4, 197, 130, 2, 25, 20, 11, 136, 19, 26, 5, 4, 197, 130, 2, 25, 20, 11, 136, 19, 9, 1, 4, 197, 130, 2, 25, 20, 11, 136, 18, 26, 5, 4, 197, 130, 2, 25, 20, 11, 136, 11, 18, 1, 4, 197, 130, 2, 25, 20, 11, 136, 3, 8, 21, 4, 197, 130, 2, 25, 20, 10, 135, 26, 7, 9, 196, 133, 197, 130, 20, 8, 197, 93, 164, 149, 77, 160, 20, 10, 135, 23, 26, 9, 196, 133, 197, 130, 20, 10, 135, 23, 7, 9, 196, 133, 197, 130, 20, 10, 135, 23, 3, 9, 196, 133, 197, 130, 20, 8, 197, 77, 50, 69, 77, 160, 20, 10, 135, 19, 11, 12, 196, 133, 197, 130, 20, 8, 197, 76, 54, 133, 77, 160, 20, 8, 197, 64, 226, 69, 77, 160, 20, 8, 133, 16, 12, 21, 197, 132, 20, 7, 132, 12, 197, 188, 25, 20, 8, 197, 45, 2, 65, 73, 160, 20, 8, 197, 13, 162, 193, 77, 160, 20, 12, 201, 80, 133, 78, 16, 84, 130, 37, 33, 0, 65, 0, 12, 137, 26, 18, 26, 5, 4, 197, 130, 2, 25, 20, 12, 137, 26, 4, 5, 3, 8, 197, 130, 2, 25, 20, 12, 137, 23, 19, 26, 5, 4, 197, 130, 2, 25, 20, 12, 137, 23, 11, 18, 1, 4, 197, 130, 2, 25, 20, 12, 137, 19, 11, 18, 1, 4, 197, 130, 2, 25, 20, 12, 137, 19, 3, 8, 21, 4, 197, 130, 2, 25, 20, 12, 137, 16, 12, 195, 179, 20, 197, 130, 2, 25, 20, 12, 137, 11, 197, 130, 1, 4, 197, 130, 2, 25, 20, 12, 137, 2, 18, 26, 25, 4, 197, 130, 2, 25, 20, 8, 133, 197, 155, 12, 196, 153, 20, 11, 136, 197, 155, 3, 9, 196, 133, 197, 130, 20, 20, 66, 88, 16, 84, 35, 71, 6, 35, 68, 49, 0, 81, 98, 97, 110, 113, 117, 101, 32, 6, 194, 80, 80, 72, 12, 5, 130, 195, 188, 43, 5, 130, 195, 188, 43, 0, 13, 138, 26, 7, 196, 153, 19, 20, 197, 130, 2, 25, 20, 13, 138, 26, 2, 18, 26, 25, 4, 197, 130, 2, 25, 20, 13, 138, 23, 16, 12, 195, 179, 20, 197, 130, 2, 25, 20, 13, 138, 197, 155, 3, 9, 3, 8, 197, 130, 2, 25, 20, 13, 138, 19, 20, 196, 153, 3, 8, 197, 130, 2, 25, 20, 13, 138, 19, 16, 12, 195, 179, 20, 197, 130, 2, 25, 20, 13, 138, 7, 14, 9, 195, 179, 20, 197, 130, 2, 25, 20, 0, 14, 139, 26, 7, 14, 9, 195, 179, 20, 197, 130, 2, 25, 20, 14, 139, 23, 7, 14, 9, 195, 179, 20, 197, 130, 2, 25, 20, 14, 139, 197, 155, 13, 9, 15, 18, 4, 197, 130, 2, 25, 20, 7, 196, 92, 193, 67, 104, 20, 6, 195, 28, 227, 205, 20, 9, 134, 4, 15, 10, 4, 197, 186, 20, 7, 196, 81, 147, 11, 60, 76, 0, 15, 140, 19, 16, 9, 5, 18, 26, 3, 8, 197, 130, 2, 25, 20, 8, 197, 77, 68, 154, 100, 48, 20, 13, 69, 53, 81, 83, 48, 144, 65, 40, 89, 55, 37, 0, 12, 69, 28, 83, 210, 28, 80, 75, 111, 34, 75, 0, 0, 11, 136, 19, 16, 9, 5, 18, 4, 197, 186, 20, 11, 136, 16, 18, 26, 5, 10, 4, 197, 186, 20, 5, 130, 195, 184, 43, 5, 130, 195, 184, 43, 0, 0, 7, 196, 76, 145, 67, 104, 20, 0, 8, 197, 76, 179, 14, 36, 80, 20, 8, 197, 76, 50, 12, 4, 208, 20, 11, 2, 203, 135, 49, 6, 35, 51, 111, 50, 0, 0, 0, 0, 7, 196, 104, 161, 68, 104, 20, 0, 6, 195, 77, 84, 218, 20, 0, 0, 9, 134, 4, 21, 197, 130, 2, 25, 20, 9, 134, 2, 25, 197, 130, 2, 25, 20, 6, 195, 60, 227, 192, 76, 0, 10, 135, 197, 188, 21, 197, 130, 2, 25, 20, 10, 135, 26, 18, 25, 197, 130, 2, 25, 20, 10, 135, 26, 14, 1, 197, 130, 2, 25, 20, 10, 135, 23, 16, 9, 197, 130, 2, 25, 20, 10, 135, 23, 11, 21, 197, 130, 2, 25, 20, 10, 135, 23, 9, 1, 197, 130, 2, 25, 20, 10, 135, 23, 4, 15, 197, 130, 2, 25, 20, 10, 135, 19, 16, 9, 197, 130, 2, 25, 20, 10, 135, 19, 11, 21, 197, 130, 2, 25, 20, 10, 135, 19, 9, 1, 197, 130, 2, 25, 20, 10, 135, 16, 9, 1, 197, 130, 2, 25, 20, 10, 135, 16, 1, 4, 197, 130, 2, 25, 20, 10, 135, 11, 16, 9, 197, 130, 2, 25, 20, 10, 135, 7, 18, 1, 197, 130, 2, 25, 20, 10, 135, 7, 14, 1, 197, 130, 2, 25, 20, 10, 135, 4, 2, 1, 197, 130, 2, 25, 20, 10, 135, 3, 12, 9, 197, 130, 2, 25, 20, 7, 196, 92, 50, 69, 48, 20, 5, 130, 197, 190, 43, 5, 130, 197, 190, 43, 0, 11, 136, 26, 23, 9, 1, 197, 130, 2, 25, 20, 11, 136, 23, 19, 9, 1, 197, 130, 2, 25, 20, 11, 136, 20, 11, 23, 9, 197, 130, 2, 25, 20, 11, 136, 19, 20, 25, 7, 197, 130, 2, 25, 20, 11, 136, 19, 16, 1, 4, 197, 130, 2, 25, 20, 11, 136, 19, 197, 130, 1, 197, 130, 2, 25, 20, 11, 136, 197, 130, 11, 15, 197, 130, 2, 25, 20, 11, 136, 7, 18, 26, 1, 197, 130, 2, 25, 20, 11, 136, 4, 18, 23, 9, 197, 130, 2, 25, 20, 11, 136, 3, 9, 3, 8, 197, 130, 2, 25, 20, 11, 136, 2, 12, 1, 4, 197, 130, 2, 25, 20, 0, 12, 137, 26, 19, 9, 1, 4, 197, 130, 2, 25, 20, 12, 137, 26, 2, 12, 1, 4, 197, 130, 2, 25, 20, 12, 137, 23, 19, 9, 1, 4, 197, 130, 2, 25, 20, 12, 137, 23, 9, 196, 133, 4, 197, 130, 2, 25, 20, 12, 137, 19, 26, 3, 26, 1, 197, 130, 2, 25, 20, 12, 137, 13, 197, 155, 3, 9, 197, 130, 2, 25, 20, 12, 137, 13, 9, 195, 179, 20, 197, 130, 2, 25, 20, 12, 137, 12, 7, 14, 196, 133, 197, 130, 2, 25, 20, 9, 198, 92, 147, 133, 29, 33, 84, 67, 11, 66, 76, 128, 109, 89, 6, 101, 35, 0, 17, 8, 2, 197, 188, 96, 109, 47, 0, 0, 13, 138, 26, 23, 9, 196, 133, 4, 197, 130, 2, 25, 20, 13, 138, 26, 13, 9, 195, 179, 20, 197, 130, 2, 25, 20, 13, 138, 23, 13, 9, 195, 179, 20, 197, 130, 2, 25, 20, 13, 138, 19, 20, 18, 26, 25, 7, 197, 130, 2, 25, 20, 13, 138, 16, 18, 26, 196, 133, 4, 197, 130, 2, 25, 20, 13, 138, 7, 18, 26, 13, 9, 1, 197, 130, 2, 25, 20, 13, 138, 7, 197, 130, 21, 3, 8, 197, 130, 2, 25, 20, 13, 138, 2, 18, 26, 13, 9, 1, 197, 130, 2, 25, 20, 7, 132, 12, 1, 196, 135, 20, 7, 132, 4, 1, 196, 135, 20, 0, 14, 139, 23, 19, 26, 3, 26, 196, 133, 197, 130, 2, 25, 20, 14, 139, 23, 16, 18, 26, 196, 133, 4, 197, 130, 2, 25, 20, 14, 139, 197, 155, 13, 9, 1, 18, 4, 197, 130, 2, 25, 20, 14, 139, 19, 16, 18, 26, 196, 133, 4, 197, 130, 2, 25, 20, 8, 133, 26, 26, 21, 196, 135, 20, 8, 133, 26, 4, 21, 197, 155, 20, 8, 133, 23, 12, 5, 196, 135, 20, 8, 133, 19, 14, 21, 196, 135, 20, 8, 133, 18, 26, 21, 196, 135, 20, 8, 133, 16, 12, 5, 196, 135, 20, 8, 2, 197, 186, 90, 109, 47, 0, 0, 9, 134, 23, 19, 20, 1, 196, 135, 20, 9, 134, 19, 26, 16, 5, 196, 135, 20, 9, 134, 16, 3, 8, 1, 196, 135, 20, 10, 135, 197, 130, 197, 188, 5, 19, 26, 20, 9, 134, 196, 135, 16, 1, 196, 135, 20, 9, 134, 196, 135, 13, 9, 196, 135, 20, 9, 134, 3, 8, 12, 1, 196, 135, 20, 0, 10, 135, 23, 20, 18, 196, 133, 196, 135, 20, 10, 135, 20, 11, 14, 196, 133, 196, 135, 20, 10, 135, 19, 26, 3, 26, 21, 196, 135, 20, 10, 135, 19, 20, 18, 196, 133, 196, 135, 20, 10, 135, 19, 3, 8, 12, 1, 196, 135, 20, 10, 135, 2, 18, 14, 196, 133, 196, 135, 20, 0, 11, 136, 197, 188, 7, 14, 196, 133, 196, 135, 20, 7, 132, 23, 9, 197, 155, 20, 11, 136, 20, 3, 8, 14, 196, 133, 196, 135, 20, 11, 136, 19, 3, 8, 197, 130, 5, 197, 155, 20, 10, 199, 76, 50, 12, 5, 54, 131, 104, 20, 11, 136, 18, 197, 188, 14, 196, 133, 196, 135, 20, 7, 132, 16, 1, 197, 155, 20, 9, 134, 196, 135, 13, 9, 196, 133, 20, 7, 132, 2, 1, 196, 135, 20, 9, 198, 52, 18, 211, 36, 213, 77, 65, 0, 8, 133, 197, 188, 21, 196, 135, 20, 8, 133, 7, 18, 1, 196, 135, 20, 8, 133, 7, 14, 1, 196, 135, 20, 12, 137, 4, 197, 186, 7, 14, 196, 133, 196, 135, 20, 8, 133, 4, 2, 1, 196, 135, 20, 10, 135, 2, 18, 26, 13, 9, 196, 133, 20, 8, 133, 2, 18, 1, 196, 135, 20, 32, 68, 12, 130, 76, 36, 76, 4, 37, 55, 37, 49, 111, 50, 49, 6, 35, 34, 50, 109, 0, 82, 99, 111, 110, 32, 99, 97, 114, 110, 101, 32, 11, 68, 12, 130, 76, 36, 76, 37, 55, 37, 0, 6, 195, 9, 147, 9, 76, 0, 9, 134, 20, 11, 23, 9, 196, 135, 20, 9, 134, 19, 197, 130, 1, 196, 135, 20, 9, 134, 13, 18, 26, 5, 196, 135, 20, 9, 134, 7, 18, 26, 1, 196, 135, 20, 9, 134, 4, 18, 26, 5, 196, 135, 20, 6, 195, 16, 210, 74, 20, 0, 10, 135, 19, 26, 3, 26, 5, 196, 135, 20, 0, 8, 133, 197, 188, 21, 197, 130, 20, 9, 134, 20, 11, 23, 9, 196, 133, 20, 9, 134, 19, 26, 11, 12, 196, 133, 20, 8, 133, 7, 18, 1, 197, 130, 20, 8, 133, 7, 14, 1, 197, 130, 20, 8, 133, 4, 2, 1, 197, 130, 20, 0, 9, 134, 20, 11, 23, 9, 197, 130, 20, 9, 134, 19, 197, 130, 1, 197, 130, 20, 8, 133, 18, 23, 196, 133, 3, 20, 9, 134, 7, 18, 26, 1, 197, 130, 20, 7, 132, 7, 9, 197, 132, 20, 0, 8, 133, 16, 12, 5, 197, 132, 20, 0, 9, 134, 23, 19, 20, 1, 197, 132, 20, 9, 134, 197, 155, 23, 9, 197, 132, 20, 7, 132, 12, 1, 197, 130, 20, 7, 132, 4, 1, 197, 130, 20, 0, 8, 133, 26, 26, 21, 197, 130, 20, 8, 133, 19, 14, 21, 197, 130, 20, 0, 7, 196, 104, 116, 143, 52, 20, 9, 134, 23, 19, 20, 1, 197, 130, 20, 6, 195, 64, 197, 193, 20, 9, 134, 16, 3, 8, 1, 197, 130, 20, 9, 134, 13, 4, 12, 1, 197, 130, 20, 9, 134, 196, 135, 16, 1, 197, 130, 20, 9, 134, 196, 135, 13, 9, 197, 130, 20, 9, 134, 3, 8, 12, 1, 197, 130, 20, 0, 6, 195, 92, 19, 0, 20, 10, 135, 20, 11, 14, 196, 133, 197, 130, 20, 8, 197, 77, 161, 80, 13, 160, 20, 10, 135, 19, 26, 3, 26, 21, 197, 130, 20, 6, 195, 76, 147, 0, 20, 10, 135, 19, 3, 8, 12, 1, 197, 130, 20, 8, 197, 56, 148, 218, 13, 160, 20, 8, 133, 13, 195, 179, 4, 12, 20, 10, 135, 4, 18, 197, 188, 1, 197, 130, 20, 10, 135, 2, 18, 14, 196, 133, 197, 130, 20, 7, 132, 19, 9, 196, 153, 72, 0, 11, 136, 197, 188, 7, 14, 196, 133, 197, 130, 20, 11, 136, 20, 3, 8, 14, 196, 133, 197, 130, 20, 11, 136, 18, 197, 188, 14, 196, 133, 197, 130, 20, 7, 132, 18, 1, 197, 186, 20, 16, 66, 64, 240, 48, 6, 111, 84, 35, 89, 0, 81, 119, 97, 115, 32, 16, 66, 64, 240, 48, 6, 111, 47, 112, 65, 0, 81, 116, 121, 109, 32, 14, 66, 64, 240, 48, 6, 111, 47, 111, 0, 81, 116, 111, 32, 14, 66, 64, 240, 48, 6, 111, 47, 109, 0, 81, 116, 101, 32, 15, 66, 64, 240, 48, 6, 111, 47, 114, 0, 81, 116, 196, 133, 32, 16, 66, 64, 240, 48, 6, 111, 67, 38, 109, 0, 81, 110, 105, 101, 32, 17, 66, 64, 240, 48, 6, 111, 67, 37, 107, 0, 81, 110, 105, 99, 104, 32, 16, 66, 64, 240, 48, 6, 111, 67, 37, 65, 0, 81, 110, 105, 109, 32, 18, 66, 64, 240, 48, 6, 111, 67, 38, 109, 57, 0, 81, 110, 105, 101, 106, 32, 16, 66, 64, 240, 48, 6, 111, 50, 35, 89, 0, 81, 110, 97, 115, 32, 18, 66, 64, 240, 48, 6, 111, 65, 67, 38, 109, 0, 81, 109, 110, 105, 101, 32, 5, 194, 64, 240, 76, 0, 12, 137, 4, 197, 186, 7, 14, 196, 133, 197, 130, 20, 18, 67, 64, 241, 0, 48, 6, 111, 72, 84, 35, 89, 0, 81, 119, 97, 115, 32, 18, 67, 64, 241, 0, 48, 6, 111, 47, 47, 112, 65, 0, 81, 116, 121, 109, 32, 16, 67, 64, 241, 0, 48, 6, 111, 47, 47, 111, 0, 81, 116, 111, 32, 16, 67, 64, 241, 0, 48, 6, 111, 47, 47, 109, 0, 81, 116, 101, 32, 17, 67, 64, 241, 0, 48, 6, 111, 47, 47, 114, 0, 81, 116, 196, 133, 32, 18, 67, 64, 241, 0, 48, 6, 111, 72, 67, 38, 109, 0, 81, 110, 105, 101, 32, 19, 67, 64, 241, 0, 48, 6, 111, 72, 67, 37, 107, 0, 81, 110, 105, 99, 104, 32, 18, 67, 64, 241, 0, 48, 6, 111, 72, 67, 37, 65, 0, 81, 110, 105, 109, 32, 19, 67, 64, 241, 0, 48, 6, 111, 72, 67, 38, 114, 0, 81, 110, 105, 196, 133, 32, 18, 67, 64, 241, 0, 48, 6, 111, 72, 50, 35, 89, 0, 81, 110, 97, 115, 32, 6, 195, 64, 241, 0, 76, 19, 2, 203, 157, 101, 4, 40, 68, 81, 35, 51, 6, 40, 65, 55, 35, 58, 47, 0, 0, 9, 134, 20, 197, 130, 15, 3, 26, 20, 7, 196, 76, 180, 143, 8, 20, 6, 195, 53, 38, 133, 20, 9, 134, 197, 130, 197, 188, 25, 10, 20, 10, 135, 7, 18, 26, 13, 9, 196, 153, 20, 0, 8, 133, 4, 196, 133, 197, 188, 20, 12, 2, 203, 155, 111, 81, 6, 111, 50, 109, 49, 0, 0, 12, 2, 203, 152, 71, 51, 6, 109, 84, 37, 89, 0, 0, 19, 2, 203, 153, 81, 6, 40, 51, 50, 35, 10, 49, 51, 6, 111, 48, 49, 35, 0, 0, 9, 134, 197, 188, 7, 1, 19, 26, 20, 9, 134, 197, 155, 14, 9, 19, 26, 20, 10, 68, 8, 241, 85, 24, 71, 109, 83, 0, 0, 0, 0, 6, 2, 95, 1, 35, 0, 0, 0, 0, 9, 67, 88, 145, 87, 84, 38, 40, 0, 0, 9, 134, 19, 26, 11, 12, 196, 153, 20, 0, 7, 196, 92, 145, 68, 104, 20, 0, 11, 136, 19, 3, 8, 197, 130, 15, 2, 25, 20, 12, 137, 15, 197, 155, 13, 9, 21, 19, 5, 20, 65, 13, 69, 40, 84, 147, 21, 144, 75, 109, 51, 88, 37, 0, 0, 6, 2, 95, 9, 37, 0, 0, 9, 134, 196, 135, 13, 9, 196, 153, 20, 14, 139, 19, 26, 5, 197, 155, 3, 9, 21, 19, 5, 20, 65, 0, 6, 2, 95, 15, 111, 0, 0, 9, 134, 26, 197, 130, 1, 197, 186, 20, 9, 134, 23, 197, 130, 1, 197, 186, 20, 7, 196, 28, 224, 83, 104, 20, 0, 8, 197, 4, 194, 83, 60, 224, 65, 0, 9, 134, 23, 9, 196, 133, 197, 188, 20, 0, 7, 132, 20, 18, 196, 133, 20, 7, 132, 16, 18, 196, 133, 20, 0, 18, 9, 4, 5, 12, 12, 39, 1, 18, 20, 5, 72, 109, 55, 6, 35, 51, 0, 10, 135, 10, 5, 19, 20, 5, 197, 155, 76, 0, 11, 136, 19, 20, 18, 26, 196, 133, 197, 155, 20, 9, 134, 4, 18, 7, 14, 196, 133, 20, 9, 134, 3, 26, 11, 14, 196, 133, 20, 0, 16, 70, 8, 16, 203, 92, 20, 132, 71, 109, 49, 58, 109, 51, 72, 0, 0, 9, 134, 19, 20, 197, 130, 21, 3, 20, 8, 133, 4, 197, 130, 21, 2, 20, 9, 134, 3, 8, 3, 196, 133, 3, 20, 7, 2, 95, 23, 84, 40, 0, 0, 0, 9, 134, 20, 11, 23, 9, 196, 153, 20, 6, 2, 95, 21, 40, 0, 0, 0, 0, 7, 196, 92, 116, 143, 52, 20, 10, 135, 197, 155, 14, 9, 196, 133, 3, 20, 10, 135, 196, 135, 13, 9, 196, 133, 3, 20, 8, 2, 95, 26, 88, 109, 47, 0, 0, 8, 197, 105, 112, 76, 13, 160, 20, 10, 135, 26, 7, 18, 25, 26, 197, 130, 20, 11, 136, 2, 18, 26, 13, 9, 196, 133, 3, 20, 13, 138, 10, 5, 19, 20, 5, 197, 155, 3, 9, 5, 76, 0, 8, 133, 11, 18, 1, 197, 155, 20, 10, 135, 2, 18, 26, 13, 9, 196, 153, 20, 0, 8, 133, 196, 135, 16, 1, 10, 20, 0, 7, 196, 92, 194, 67, 104, 20, 7, 196, 16, 32, 83, 104, 20, 10, 135, 2, 25, 197, 130, 5, 197, 155, 76, 11, 200, 52, 19, 132, 20, 192, 146, 61, 64, 65, 0, 10, 135, 26, 7, 197, 130, 21, 19, 26, 20, 0, 11, 136, 197, 188, 7, 14, 9, 5, 19, 26, 20, 9, 134, 26, 13, 18, 21, 197, 188, 20, 6, 195, 52, 67, 9, 20, 18, 67, 16, 82, 129, 72, 109, 90, 35, 84, 6, 37, 0, 81, 118, 117, 101, 32, 17, 67, 16, 82, 129, 72, 109, 90, 35, 84, 6, 37, 0, 81, 118, 117, 32, 9, 134, 11, 15, 12, 1, 197, 188, 66, 0, 10, 135, 26, 23, 9, 196, 133, 197, 188, 20, 8, 133, 26, 12, 5, 197, 186, 20, 8, 133, 23, 12, 5, 197, 186, 20, 6, 195, 48, 82, 128, 20, 6, 195, 8, 146, 128, 20, 7, 195, 80, 82, 128, 72, 12, 0, 7, 196, 104, 36, 143, 40, 20, 9, 134, 13, 197, 188, 25, 19, 26, 20, 8, 133, 196, 135, 16, 1, 13, 20, 14, 2, 95, 34, 117, 40, 118, 6, 112, 89, 58, 40, 83, 0, 0, 9, 198, 93, 54, 131, 104, 226, 69, 20, 10, 135, 4, 197, 186, 7, 1, 19, 26, 20, 11, 69, 69, 82, 67, 32, 80, 49, 37, 91, 0, 15, 2, 95, 33, 84, 112, 49, 91, 6, 112, 49, 67, 37, 49, 0, 0, 9, 198, 93, 64, 83, 104, 54, 128, 20, 9, 198, 44, 192, 83, 104, 54, 128, 20, 5, 194, 81, 144, 76, 0, 10, 135, 19, 20, 18, 26, 5, 197, 188, 20, 9, 67, 12, 243, 128, 49, 111, 50, 0, 14, 2, 95, 39, 35, 48, 6, 111, 89, 47, 51, 111, 83, 0, 0, 9, 198, 93, 54, 131, 104, 226, 74, 20, 7, 196, 92, 180, 143, 64, 20, 0, 0, 16, 67, 52, 195, 5, 65, 35, 72, 65, 40, 35, 88, 6, 109, 55, 0, 10, 67, 40, 19, 133, 75, 109, 57, 50, 0, 11, 2, 95, 36, 72, 6, 111, 55, 35, 51, 0, 0, 7, 195, 80, 83, 128, 72, 12, 0, 7, 196, 77, 3, 1, 52, 20, 12, 68, 4, 66, 69, 84, 35, 72, 57, 6, 109, 0, 7, 196, 52, 16, 201, 20, 76, 13, 4, 95, 3, 1, 16, 72, 6, 40, 90, 109, 10, 0, 0, 23, 73, 12, 147, 145, 84, 80, 197, 57, 67, 192, 76, 37, 50, 49, 58, 109, 76, 109, 50, 47, 111, 0, 15, 2, 95, 41, 48, 111, 50, 35, 84, 38, 6, 35, 97, 109, 0, 0, 6, 195, 92, 116, 129, 20, 11, 2, 95, 40, 50, 35, 84, 38, 35, 89, 0, 0, 8, 133, 11, 197, 130, 21, 10, 20, 0, 8, 133, 20, 11, 14, 196, 133, 20, 10, 135, 7, 18, 25, 197, 186, 196, 135, 20, 0, 11, 136, 26, 23, 9, 5, 197, 186, 196, 135, 20, 8, 133, 26, 14, 21, 197, 188, 20, 11, 136, 26, 7, 18, 25, 197, 186, 196, 135, 20, 11, 136, 23, 23, 9, 5, 197, 186, 196, 135, 20, 10, 135, 23, 9, 5, 197, 132, 3, 26, 20, 11, 136, 23, 7, 18, 25, 197, 186, 196, 135, 20, 8, 133, 13, 25, 197, 155, 12, 20, 13, 2, 95, 45, 65, 6, 112, 97, 55, 50, 37, 49, 0, 0, 11, 136, 26, 23, 9, 5, 197, 132, 3, 26, 20, 8, 133, 9, 197, 155, 196, 135, 20, 14, 2, 95, 44, 48, 91, 109, 119, 6, 37, 50, 109, 49, 0, 0, 7, 132, 4, 18, 196, 133, 20, 19, 71, 12, 19, 69, 52, 33, 82, 80, 49, 35, 65, 109, 65, 71, 6, 109, 51, 0, 9, 2, 95, 51, 47, 91, 6, 112, 0, 0, 10, 135, 26, 10, 5, 197, 155, 196, 135, 20, 10, 135, 23, 9, 5, 197, 186, 196, 135, 20, 11, 136, 19, 16, 18, 26, 196, 133, 197, 188, 20, 7, 196, 9, 35, 137, 40, 20, 8, 133, 13, 1, 10, 196, 133, 76, 27, 68, 76, 245, 78, 16, 89, 35, 58, 50, 72, 15, 75, 6, 40, 89, 109, 51, 0, 81, 106, 117, 105, 99, 101, 114, 32, 9, 2, 95, 50, 72, 84, 6, 35, 0, 0, 8, 197, 76, 179, 14, 36, 160, 20, 8, 197, 76, 50, 12, 20, 160, 20, 11, 2, 95, 49, 57, 6, 109, 72, 109, 50, 0, 0, 11, 136, 197, 155, 23, 9, 15, 4, 3, 26, 20, 11, 2, 95, 48, 88, 6, 109, 51, 111, 12, 0, 0, 7, 132, 16, 18, 196, 153, 20, 6, 195, 45, 114, 76, 20, 11, 2, 95, 55, 97, 6, 109, 72, 109, 65, 0, 0, 10, 2, 95, 54, 91, 6, 109, 97, 119, 0, 0, 9, 134, 3, 26, 11, 14, 196, 153, 20, 11, 2, 95, 53, 48, 38, 6, 109, 67, 119, 0, 0, 11, 136, 23, 23, 9, 195, 179, 26, 197, 130, 20, 8, 133, 4, 13, 196, 133, 3, 20, 11, 2, 95, 52, 76, 47, 6, 109, 51, 112, 0, 0, 8, 133, 12, 1, 26, 197, 130, 20, 9, 134, 11, 16, 9, 196, 133, 3, 20, 13, 2, 95, 59, 97, 51, 6, 109, 72, 67, 37, 49, 0, 0, 9, 134, 23, 12, 1, 26, 197, 130, 20, 10, 135, 20, 11, 23, 9, 196, 133, 3, 20, 10, 135, 197, 155, 13, 9, 196, 133, 3, 20, 10, 135, 19, 26, 11, 12, 196, 133, 3, 20, 9, 134, 7, 18, 25, 26, 197, 130, 20, 10, 135, 4, 18, 23, 9, 196, 133, 3, 20, 9, 198, 12, 131, 1, 77, 160, 218, 20, 15, 2, 95, 58, 72, 84, 40, 49, 51, 6, 111, 48, 109, 49, 0, 0, 10, 135, 23, 9, 195, 179, 26, 197, 130, 20, 10, 135, 23, 7, 18, 25, 26, 197, 130, 20, 8, 197, 64, 197, 193, 77, 160, 20, 13, 2, 95, 57, 120, 6, 109, 84, 38, 109, 67, 119, 0, 0, 14, 139, 19, 3, 8, 197, 130, 25, 197, 155, 3, 9, 5, 20, 18, 66, 92, 80, 84, 6, 109, 65, 67, 38, 109, 0, 81, 109, 110, 105, 101, 32, 16, 70, 12, 128, 82, 52, 19, 148, 91, 35, 51, 65, 35, 50, 0, 66, 5, 194, 92, 80, 72, 10, 2, 95, 56, 6, 111, 97, 109, 65, 0, 0, 19, 71, 12, 243, 131, 36, 84, 135, 20, 49, 111, 50, 89, 57, 6, 109, 51, 90, 0, 20, 2, 95, 63, 88, 50, 4, 35, 49, 15, 88, 35, 48, 112, 47, 6, 35, 67, 35, 0, 0, 9, 134, 26, 23, 196, 153, 197, 186, 20, 7, 196, 76, 179, 195, 104, 20, 13, 2, 95, 62, 58, 38, 6, 109, 68, 49, 91, 109, 0, 0, 12, 137, 26, 2, 197, 130, 1, 197, 186, 197, 132, 20, 0, 11, 136, 197, 155, 23, 9, 1, 4, 3, 26, 20, 9, 198, 64, 197, 83, 104, 54, 128, 20, 9, 198, 52, 20, 147, 104, 54, 128, 20, 12, 2, 95, 60, 65, 67, 6, 109, 57, 91, 109, 0, 0, 0, 7, 196, 105, 37, 83, 104, 20, 7, 196, 104, 35, 195, 104, 20, 7, 196, 12, 145, 82, 64, 20, 0, 0, 9, 198, 104, 226, 83, 104, 54, 128, 20, 9, 198, 12, 132, 154, 12, 146, 128, 20, 0, 7, 132, 20, 18, 196, 153, 20, 0, 7, 196, 76, 180, 143, 64, 20, 7, 132, 11, 196, 133, 16, 20, 7, 196, 9, 35, 137, 20, 20, 0, 9, 134, 4, 18, 7, 14, 196, 153, 20, 0, 9, 198, 61, 5, 9, 53, 83, 64, 65, 0, 6, 195, 93, 112, 76, 20, 0, 7, 196, 64, 21, 18, 104, 20, 0, 0, 6, 195, 104, 161, 77, 20, 8, 133, 23, 4, 21, 197, 155, 20, 8, 133, 16, 19, 15, 196, 135, 20, 10, 135, 4, 197, 188, 4, 197, 188, 25, 20, 10, 67, 12, 240, 193, 49, 111, 49, 35, 0, 0, 9, 134, 13, 1, 197, 155, 196, 135, 20, 9, 134, 4, 26, 9, 15, 196, 135, 20, 0, 10, 135, 3, 26, 25, 197, 155, 196, 135, 20, 0, 11, 136, 26, 13, 9, 5, 197, 155, 196, 135, 20, 11, 136, 26, 7, 196, 153, 197, 155, 196, 135, 20, 11, 136, 23, 13, 9, 5, 197, 155, 196, 135, 20, 11, 136, 23, 11, 18, 1, 197, 155, 196, 135, 20, 11, 136, 19, 20, 18, 5, 197, 155, 196, 135, 20, 11, 136, 19, 11, 18, 1, 197, 155, 196, 135, 20, 0, 8, 133, 26, 9, 15, 196, 135, 20, 12, 137, 26, 7, 14, 9, 5, 197, 155, 196, 135, 20, 12, 137, 23, 26, 14, 9, 5, 197, 155, 196, 135, 20, 10, 67, 88, 144, 197, 84, 37, 117, 109, 0, 9, 198, 4, 225, 197, 48, 84, 192, 65, 0, 9, 134, 16, 21, 197, 155, 196, 135, 20, 8, 133, 8, 1, 197, 132, 2, 20, 9, 134, 4, 18, 7, 15, 196, 135, 20, 9, 134, 3, 26, 11, 15, 196, 135, 20, 13, 67, 85, 48, 128, 40, 109, 89, 71, 6, 109, 0, 17, 0, 10, 135, 18, 195, 179, 197, 155, 196, 135, 20, 10, 135, 13, 9, 5, 197, 155, 196, 135, 20, 10, 135, 3, 8, 23, 9, 15, 196, 135, 20, 10, 135, 2, 195, 179, 197, 155, 196, 135, 20, 0, 11, 136, 26, 18, 195, 179, 197, 155, 196, 135, 20, 6, 195, 104, 34, 74, 20, 11, 136, 23, 18, 195, 179, 197, 155, 196, 135, 20, 0, 0, 8, 133, 26, 9, 15, 197, 130, 20, 8, 133, 14, 9, 11, 197, 130, 20, 14, 67, 20, 177, 192, 109, 49, 35, 81, 38, 6, 109, 0, 17, 19, 71, 25, 32, 78, 12, 148, 195, 60, 83, 51, 35, 50, 89, 37, 89, 49, 111, 0, 0, 9, 198, 77, 4, 154, 100, 180, 154, 20, 8, 133, 4, 18, 197, 188, 25, 20, 9, 134, 4, 18, 7, 15, 197, 130, 20, 9, 134, 3, 26, 11, 15, 197, 130, 20, 14, 4, 95, 4, 15, 20, 88, 49, 51, 111, 48, 49, 114, 0, 0, 10, 135, 19, 16, 19, 9, 15, 197, 130, 20, 10, 135, 19, 16, 9, 5, 11, 197, 130, 20, 10, 135, 3, 8, 23, 9, 15, 197, 130, 20, 0, 0, 6, 195, 104, 161, 64, 20, 7, 195, 4, 193, 64, 76, 28, 24, 2, 95, 91, 50, 4, 35, 84, 38, 35, 89, 15, 49, 84, 35, 72, 51, 35, 47, 6, 111, 84, 112, 0, 0, 9, 134, 26, 23, 25, 11, 197, 130, 20, 8, 133, 20, 11, 14, 196, 153, 20, 9, 134, 18, 26, 5, 11, 197, 130, 20, 9, 134, 4, 26, 9, 15, 197, 130, 20, 9, 134, 2, 18, 1, 11, 197, 130, 20, 0, 10, 135, 26, 18, 26, 5, 11, 197, 130, 20, 10, 135, 26, 2, 18, 1, 11, 197, 130, 20, 8, 197, 93, 160, 149, 73, 160, 20, 8, 197, 92, 180, 143, 13, 160, 20, 8, 197, 81, 37, 193, 77, 160, 20, 8, 197, 17, 33, 193, 77, 160, 20, 0, 6, 195, 64, 226, 69, 20, 16, 66, 104, 16, 88, 6, 35, 67, 38, 109, 0, 81, 110, 105, 101, 32, 17, 66, 104, 16, 88, 6, 35, 67, 37, 107, 0, 81, 110, 105, 99, 104, 32, 16, 66, 104, 16, 88, 6, 35, 84, 35, 89, 0, 81, 119, 97, 115, 32, 16, 66, 104, 16, 88, 6, 35, 47, 112, 65, 0, 81, 116, 121, 109, 32, 14, 66, 104, 16, 88, 6, 35, 47, 111, 0, 81, 116, 111, 32, 14, 66, 104, 16, 88, 6, 35, 47, 109, 0, 81, 116, 101, 32, 15, 66, 104, 16, 88, 6, 35, 47, 114, 0, 81, 116, 196, 133, 32, 16, 66, 104, 16, 88, 6, 35, 67, 37, 65, 0, 81, 110, 105, 109, 32, 17, 66, 104, 16, 88, 6, 35, 67, 38, 114, 0, 81, 110, 105, 196, 133, 32, 16, 66, 104, 16, 88, 6, 35, 50, 35, 89, 0, 81, 110, 97, 115, 32, 18, 66, 104, 16, 88, 6, 35, 65, 67, 38, 109, 0, 81, 109, 110, 105, 101, 32, 5, 194, 104, 16, 76, 0, 8, 133, 11, 18, 195, 179, 10, 20, 17, 2, 95, 95, 48, 111, 72, 49, 51, 109, 97, 55, 6, 109, 67, 109, 0, 0, 9, 134, 23, 11, 197, 130, 21, 10, 20, 7, 196, 80, 181, 201, 40, 20, 9, 134, 19, 11, 197, 130, 21, 10, 20, 18, 70, 64, 17, 197, 16, 245, 206, 48, 109, 57, 75, 72, 6, 35, 58, 50, 0, 0, 10, 135, 14, 9, 1, 197, 132, 3, 26, 20, 28, 69, 52, 18, 84, 72, 80, 65, 109, 47, 51, 109, 72, 111, 47, 6, 109, 55, 0, 81, 100, 39, 104, 111, 116, 101, 108, 32, 30, 2, 95, 93, 48, 51, 35, 84, 112, 15, 50, 4, 35, 84, 38, 35, 89, 15, 49, 84, 35, 72, 51, 35, 47, 6, 111, 84, 112, 0, 0, 9, 198, 77, 162, 204, 37, 54, 128, 20, 9, 198, 65, 53, 18, 105, 146, 128, 20, 10, 67, 40, 18, 197, 75, 109, 57, 49, 0, 0, 6, 195, 73, 146, 128, 20, 6, 195, 17, 82, 128, 20, 9, 67, 12, 243, 204, 49, 40, 55, 0, 0, 7, 196, 12, 145, 83, 104, 20, 12, 137, 2, 196, 153, 4, 26, 9, 5, 13, 25, 76, 8, 133, 2, 25, 197, 130, 1, 76, 0, 6, 195, 8, 16, 218, 20, 31, 69, 12, 128, 82, 28, 80, 91, 35, 51, 90, 109, 72, 35, 83, 109, 51, 0, 68, 81, 100, 39, 97, 102, 102, 97, 105, 114, 101, 115, 32, 0, 9, 198, 77, 160, 218, 101, 54, 128, 20, 8, 133, 2, 25, 197, 130, 15, 76, 0, 7, 132, 4, 18, 196, 153, 20, 0, 0, 6, 195, 64, 226, 74, 20, 0, 0, 0, 0, 0, 8, 133, 26, 23, 15, 196, 135, 20, 8, 133, 20, 11, 15, 196, 135, 20, 8, 133, 19, 19, 15, 196, 135, 20, 8, 133, 18, 23, 15, 196, 135, 20, 16, 70, 13, 84, 129, 12, 19, 192, 49, 37, 51, 35, 89, 35, 111, 0, 26, 67, 12, 244, 193, 49, 4, 111, 88, 35, 50, 6, 111, 89, 47, 51, 35, 0, 81, 110, 111, 115, 116, 114, 97, 32, 14, 4, 95, 7, 18, 22, 119, 6, 113, 91, 80, 38, 109, 0, 0, 9, 134, 21, 10, 197, 155, 196, 135, 20, 20, 67, 88, 148, 192, 84, 37, 88, 35, 84, 37, 0, 67, 82, 97, 32, 118, 105, 115, 32, 21, 67, 88, 148, 192, 84, 37, 88, 35, 84, 37, 0, 67, 82, 195, 160, 32, 118, 105, 115, 32, 0, 9, 134, 26, 13, 196, 153, 3, 26, 20, 7, 196, 12, 226, 83, 104, 20, 8, 133, 3, 8, 3, 196, 133, 20, 12, 68, 13, 83, 16, 4, 49, 40, 55, 48, 35, 0, 0, 11, 136, 26, 23, 9, 5, 197, 155, 196, 135, 20, 11, 136, 26, 14, 9, 5, 197, 155, 196, 135, 20, 11, 136, 23, 14, 9, 5, 197, 155, 196, 135, 20, 8, 197, 92, 70, 137, 20, 160, 20, 0, 12, 137, 23, 26, 18, 195, 179, 197, 155, 196, 135, 20, 8, 133, 23, 9, 15, 196, 135, 20, 8, 133, 19, 9, 15, 196, 135, 20, 8, 133, 16, 9, 15, 196, 135, 20, 6, 131, 19, 196, 133, 76, 0, 8, 133, 197, 188, 25, 3, 26, 20, 9, 134, 20, 18, 23, 15, 196, 135, 20, 9, 134, 16, 15, 197, 155, 196, 135, 20, 0, 10, 135, 23, 16, 21, 197, 155, 196, 135, 20, 10, 135, 19, 16, 21, 197, 155, 196, 135, 20, 10, 135, 16, 9, 5, 197, 155, 196, 135, 20, 10, 135, 14, 1, 10, 197, 155, 196, 135, 20, 10, 135, 11, 18, 1, 197, 155, 196, 135, 20, 0, 11, 136, 11, 197, 130, 1, 197, 155, 196, 135, 20, 8, 197, 12, 133, 201, 20, 160, 20, 0, 10, 135, 19, 3, 8, 197, 130, 15, 13, 20, 0, 8, 133, 23, 9, 15, 197, 130, 20, 8, 133, 19, 9, 15, 197, 130, 20, 8, 133, 16, 9, 15, 197, 130, 20, 6, 195, 8, 21, 192, 20, 0, 9, 134, 26, 13, 195, 179, 18, 26, 20, 9, 134, 23, 12, 5, 11, 197, 130, 20, 9, 134, 20, 18, 23, 15, 197, 130, 20, 9, 134, 16, 9, 5, 11, 197, 130, 20, 0, 10, 135, 26, 23, 12, 5, 11, 197, 130, 20, 6, 195, 48, 80, 218, 20, 0, 11, 136, 19, 20, 197, 130, 21, 11, 197, 130, 20, 11, 136, 7, 18, 26, 13, 9, 15, 197, 130, 20, 0, 8, 133, 26, 23, 15, 197, 130, 20, 8, 133, 20, 11, 15, 197, 130, 20, 12, 137, 197, 155, 13, 9, 5, 18, 4, 197, 130, 20, 8, 133, 19, 19, 15, 197, 130, 20, 8, 133, 18, 23, 15, 197, 130, 20, 21, 2, 95, 123, 50, 4, 35, 84, 38, 35, 89, 15, 49, 55, 35, 65, 51, 111, 84, 112, 0, 15, 4, 95, 4, 9, 1, 10, 6, 40, 65, 55, 35, 58, 47, 0, 0, 9, 198, 80, 50, 14, 36, 84, 218, 20, 9, 134, 19, 9, 5, 11, 197, 130, 20, 9, 198, 76, 50, 14, 36, 84, 218, 20, 9, 134, 13, 195, 179, 11, 197, 130, 20, 9, 134, 3, 9, 5, 11, 197, 130, 20, 9, 198, 12, 132, 154, 12, 148, 218, 20, 8, 133, 2, 25, 197, 130, 25, 76, 7, 195, 80, 81, 207, 72, 12, 0, 10, 135, 26, 13, 195, 179, 11, 197, 130, 20, 10, 135, 23, 3, 9, 5, 11, 197, 130, 20, 10, 135, 20, 197, 130, 21, 11, 197, 130, 20, 0, 9, 134, 20, 18, 23, 15, 197, 132, 20, 11, 136, 197, 155, 3, 9, 5, 11, 197, 130, 20, 9, 134, 4, 26, 23, 15, 197, 132, 20, 10, 135, 2, 196, 153, 4, 26, 9, 5, 76, 5, 194, 80, 240, 72, 0, 10, 135, 19, 20, 18, 23, 15, 197, 132, 20, 0, 7, 196, 104, 224, 67, 104, 20, 6, 195, 104, 32, 87, 20, 7, 196, 77, 4, 129, 92, 20, 7, 196, 25, 84, 131, 104, 20, 7, 196, 12, 194, 83, 104, 20, 0, 8, 197, 77, 160, 218, 4, 208, 20, 23, 73, 12, 130, 80, 64, 83, 132, 4, 193, 64, 76, 37, 48, 109, 50, 72, 109, 57, 55, 0, 65, 9, 21, 73, 12, 130, 80, 64, 83, 132, 4, 193, 64, 76, 37, 48, 109, 50, 72, 109, 57, 55, 0, 9, 134, 11, 20, 195, 179, 18, 1, 76, 28, 2, 95, 125, 48, 51, 35, 84, 112, 15, 50, 4, 35, 84, 38, 35, 89, 15, 49, 55, 35, 65, 51, 6, 111, 84, 112, 0, 0, 8, 133, 19, 11, 15, 197, 155, 20, 0, 0, 8, 133, 11, 197, 130, 15, 13, 20, 12, 137, 14, 9, 5, 11, 20, 195, 179, 18, 1, 76, 12, 67, 40, 21, 211, 75, 6, 109, 58, 89, 0, 17, 0, 10, 135, 19, 20, 18, 196, 153, 3, 26, 20, 10, 135, 19, 16, 197, 130, 15, 19, 26, 20, 6, 195, 72, 16, 218, 20, 9, 134, 11, 20, 195, 179, 18, 5, 76, 0, 9, 198, 77, 160, 218, 5, 54, 128, 20, 9, 198, 9, 38, 141, 37, 54, 128, 20, 5, 194, 93, 144, 76, 0, 6, 195, 12, 134, 76, 20, 0, 12, 137, 14, 9, 5, 11, 20, 195, 179, 18, 5, 76, 0, 0, 0, 0, 9, 198, 76, 179, 14, 36, 84, 218, 20, 9, 198, 64, 50, 14, 36, 84, 218, 20, 8, 133, 3, 8, 3, 196, 153, 20, 0, 0, 17, 70, 12, 16, 133, 72, 225, 84, 49, 35, 71, 109, 51, 50, 6, 109, 0, 0, 8, 133, 26, 197, 130, 1, 10, 20, 0, 9, 134, 23, 20, 18, 195, 179, 10, 20, 9, 134, 19, 20, 18, 195, 179, 10, 20, 0, 15, 70, 12, 243, 84, 21, 52, 197, 49, 114, 47, 6, 109, 89, 0, 0, 0, 8, 133, 23, 23, 15, 197, 186, 20, 0, 8, 133, 26, 197, 130, 1, 13, 20, 8, 133, 23, 197, 130, 1, 13, 20, 11, 136, 19, 20, 18, 23, 195, 179, 197, 188, 20, 8, 133, 12, 197, 188, 196, 133, 20, 7, 196, 17, 84, 3, 104, 20, 6, 195, 9, 32, 75, 20, 0, 0, 21, 67, 64, 241, 5, 48, 111, 72, 6, 109, 65, 67, 38, 109, 0, 81, 109, 110, 105, 101, 32, 20, 67, 64, 241, 5, 48, 111, 72, 6, 109, 65, 50, 114, 0, 81, 109, 110, 196, 133, 32, 0, 8, 133, 11, 195, 179, 18, 26, 20, 0, 0, 0, 10, 135, 16, 18, 15, 197, 130, 2, 25, 20, 10, 135, 13, 9, 15, 197, 130, 2, 25, 20, 10, 135, 7, 1, 19, 197, 130, 2, 25, 20, 11, 136, 19, 20, 196, 153, 3, 8, 197, 130, 20, 13, 4, 95, 35, 51, 50, 89, 48, 35, 117, 57, 35, 0, 0, 11, 136, 26, 23, 25, 11, 197, 130, 2, 25, 20, 11, 136, 26, 7, 18, 15, 197, 130, 2, 25, 20, 11, 136, 23, 7, 18, 15, 197, 130, 2, 25, 20, 11, 136, 18, 197, 188, 15, 197, 130, 2, 25, 20, 11, 136, 18, 26, 5, 11, 197, 130, 2, 25, 20, 11, 136, 13, 9, 12, 11, 197, 130, 2, 25, 20, 11, 136, 13, 4, 12, 15, 197, 130, 2, 25, 20, 11, 136, 197, 130, 7, 15, 197, 130, 2, 25, 20, 11, 136, 4, 26, 9, 15, 197, 130, 2, 25, 20, 11, 136, 196, 135, 16, 15, 197, 130, 2, 25, 20, 11, 136, 3, 8, 12, 15, 197, 130, 2, 25, 20, 11, 136, 2, 18, 1, 11, 197, 130, 2, 25, 20, 9, 134, 23, 26, 14, 195, 179, 23, 20, 12, 137, 197, 155, 13, 9, 15, 18, 4, 197, 130, 20, 15, 67, 85, 49, 192, 40, 10, 109, 89, 81, 38, 6, 109, 0, 17, 0, 12, 137, 26, 18, 26, 5, 11, 197, 130, 2, 25, 20, 12, 137, 26, 13, 195, 179, 7, 197, 130, 2, 25, 20, 12, 137, 26, 13, 9, 12, 11, 197, 130, 2, 25, 20, 12, 137, 26, 2, 18, 1, 11, 197, 130, 2, 25, 20, 12, 137, 23, 12, 195, 179, 11, 197, 130, 2, 25, 20, 12, 137, 23, 4, 26, 9, 15, 197, 130, 2, 25, 20, 12, 137, 19, 3, 8, 12, 15, 197, 130, 2, 25, 20, 12, 137, 11, 12, 196, 153, 19, 197, 130, 2, 25, 20, 12, 137, 4, 197, 186, 7, 15, 197, 130, 2, 25, 20, 12, 137, 3, 8, 3, 9, 15, 197, 130, 2, 25, 20, 13, 138, 19, 16, 9, 5, 18, 26, 3, 8, 197, 130, 20, 9, 134, 19, 5, 3, 8, 197, 130, 20, 9, 134, 16, 21, 3, 8, 197, 130, 20, 12, 137, 2, 25, 12, 9, 197, 155, 3, 9, 5, 76, 0, 13, 138, 19, 3, 8, 12, 9, 197, 155, 3, 9, 5, 20, 13, 138, 19, 26, 197, 130, 25, 197, 155, 3, 9, 5, 20, 13, 138, 23, 26, 13, 195, 179, 7, 197, 130, 2, 25, 20, 13, 138, 19, 11, 12, 196, 153, 19, 197, 130, 2, 25, 20, 8, 197, 92, 65, 80, 13, 160, 20, 13, 138, 2, 25, 197, 130, 25, 197, 155, 3, 9, 5, 76, 0, 14, 139, 19, 26, 12, 9, 2, 25, 197, 155, 3, 9, 5, 20, 14, 139, 23, 197, 155, 3, 9, 5, 11, 197, 130, 2, 25, 20, 17, 66, 104, 80, 88, 6, 109, 65, 50, 114, 0, 81, 109, 110, 196, 133, 32, 18, 66, 104, 80, 88, 6, 109, 65, 67, 38, 109, 0, 81, 109, 110, 105, 101, 32, 14, 139, 13, 9, 1, 197, 130, 25, 197, 155, 3, 9, 5, 76, 0, 15, 140, 19, 26, 197, 130, 25, 2, 25, 197, 155, 3, 9, 5, 20, 15, 140, 19, 8, 197, 130, 25, 2, 25, 197, 155, 3, 9, 5, 20, 15, 140, 19, 3, 8, 12, 9, 2, 25, 197, 155, 3, 9, 5, 20, 11, 136, 19, 3, 8, 197, 130, 25, 2, 25, 20, 6, 195, 45, 2, 64, 20, 0, 13, 138, 26, 13, 9, 5, 18, 26, 3, 8, 197, 130, 20, 7, 196, 93, 4, 129, 92, 20, 10, 68, 12, 243, 84, 20, 49, 114, 47, 0, 11, 200, 76, 145, 68, 52, 149, 83, 21, 64, 65, 0, 10, 135, 197, 155, 12, 196, 153, 3, 26, 20, 0, 0, 0, 0, 6, 195, 77, 2, 74, 20, 0, 10, 135, 19, 3, 8, 197, 130, 5, 13, 20, 0, 14, 67, 52, 195, 128, 65, 37, 55, 57, 111, 50, 40, 83, 0, 0, 0, 8, 133, 26, 197, 130, 1, 16, 20, 6, 195, 93, 2, 74, 20, 6, 195, 9, 144, 218, 20, 9, 134, 11, 20, 195, 179, 18, 25, 76, 0, 0, 0, 12, 137, 14, 9, 5, 11, 20, 195, 179, 18, 25, 76, 0, 14, 69, 4, 225, 18, 21, 112, 109, 50, 72, 34, 57, 40, 0, 0, 0, 7, 132, 3, 12, 196, 133, 20, 0, 7, 196, 105, 38, 133, 12, 20, 7, 196, 93, 53, 1, 92, 20, 0, 6, 195, 105, 165, 74, 20, 9, 134, 197, 130, 197, 188, 196, 133, 20, 9, 134, 4, 18, 197, 188, 196, 133, 20, 10, 135, 11, 20, 195, 179, 18, 5, 10, 76, 0, 7, 131, 20, 196, 133, 72, 12, 0, 8, 133, 26, 23, 15, 197, 186, 20, 0, 8, 133, 18, 197, 188, 196, 133, 20, 8, 133, 13, 197, 188, 196, 133, 20, 10, 135, 13, 197, 155, 3, 9, 196, 135, 20, 13, 138, 14, 9, 5, 11, 20, 195, 179, 18, 5, 10, 76, 0, 6, 195, 105, 38, 74, 20, 6, 195, 45, 2, 74, 20, 6, 195, 33, 80, 218, 20, 0, 0, 8, 133, 26, 14, 1, 197, 130, 20, 0, 8, 133, 12, 197, 188, 196, 153, 20, 0, 9, 134, 23, 9, 197, 130, 2, 25, 20, 9, 134, 20, 25, 197, 130, 2, 25, 20, 9, 134, 13, 25, 197, 130, 2, 25, 20, 10, 135, 26, 13, 196, 133, 4, 18, 26, 20, 8, 197, 92, 145, 84, 73, 160, 20, 8, 197, 77, 68, 129, 77, 160, 20, 10, 135, 13, 197, 155, 3, 9, 197, 130, 20, 0, 10, 135, 26, 12, 1, 197, 130, 2, 25, 20, 10, 135, 26, 4, 1, 197, 130, 2, 25, 20, 10, 135, 26, 2, 9, 197, 130, 2, 25, 20, 10, 135, 23, 26, 21, 197, 130, 2, 25, 20, 10, 135, 23, 4, 1, 197, 130, 2, 25, 20, 10, 135, 23, 2, 9, 197, 130, 2, 25, 20, 10, 135, 20, 18, 21, 197, 130, 2, 25, 20, 10, 135, 16, 18, 21, 197, 130, 2, 25, 20, 10, 135, 4, 196, 133, 197, 130, 2, 25, 20, 10, 135, 3, 26, 21, 197, 130, 2, 25, 20, 0, 11, 136, 26, 19, 26, 25, 197, 130, 2, 25, 20, 11, 136, 26, 13, 1, 18, 197, 130, 2, 25, 20, 11, 136, 23, 197, 188, 25, 197, 130, 2, 25, 20, 11, 136, 23, 26, 2, 9, 197, 130, 2, 25, 20, 11, 136, 23, 3, 26, 21, 197, 130, 2, 25, 20, 11, 136, 19, 20, 18, 21, 197, 130, 2, 25, 20, 11, 136, 19, 16, 18, 21, 197, 130, 2, 25, 20, 11, 136, 19, 11, 18, 25, 197, 130, 2, 25, 20, 11, 136, 18, 197, 188, 1, 197, 130, 2, 25, 20, 11, 136, 16, 12, 23, 1, 197, 130, 2, 25, 20, 11, 136, 13, 197, 188, 25, 197, 130, 2, 25, 20, 11, 136, 13, 9, 196, 133, 197, 130, 2, 25, 20, 11, 136, 13, 4, 12, 9, 197, 130, 2, 25, 20, 11, 136, 197, 130, 7, 1, 197, 130, 2, 25, 20, 11, 136, 11, 12, 196, 133, 197, 130, 2, 25, 20, 11, 136, 7, 9, 196, 133, 197, 130, 2, 25, 20, 11, 136, 4, 18, 7, 1, 197, 130, 2, 25, 20, 11, 136, 3, 26, 11, 1, 197, 130, 2, 25, 20, 0, 12, 137, 19, 26, 12, 9, 197, 155, 3, 9, 5, 20, 12, 137, 26, 197, 188, 196, 133, 197, 130, 2, 25, 20, 12, 137, 26, 13, 9, 196, 133, 197, 130, 2, 25, 20, 12, 137, 26, 7, 18, 25, 26, 197, 130, 2, 25, 20, 12, 137, 26, 7, 9, 196, 133, 197, 130, 2, 25, 20, 12, 137, 23, 197, 188, 196, 133, 197, 130, 2, 25, 20, 12, 137, 23, 26, 9, 196, 133, 197, 130, 2, 25, 20, 12, 137, 23, 26, 4, 196, 133, 197, 130, 2, 25, 20, 12, 137, 23, 16, 9, 196, 133, 197, 130, 2, 25, 20, 12, 137, 23, 7, 9, 196, 133, 197, 130, 2, 25, 20, 12, 137, 23, 3, 9, 196, 133, 197, 130, 2, 25, 20, 12, 137, 19, 16, 9, 196, 133, 197, 130, 2, 25, 20, 12, 137, 19, 11, 12, 196, 133, 197, 130, 2, 25, 20, 12, 137, 16, 5, 197, 130, 26, 197, 130, 2, 25, 20, 12, 137, 4, 197, 186, 7, 1, 197, 130, 2, 25, 20, 10, 67, 12, 149, 15, 117, 37, 47, 111, 0, 19, 67, 12, 20, 19, 49, 35, 48, 89, 55, 111, 49, 0, 81, 108, 111, 99, 107, 32, 0, 13, 138, 23, 19, 16, 9, 196, 133, 197, 130, 2, 25, 20, 13, 138, 197, 155, 3, 9, 196, 133, 197, 130, 2, 25, 20, 8, 197, 104, 34, 69, 73, 160, 20, 8, 197, 77, 2, 69, 77, 160, 20, 13, 138, 13, 9, 5, 12, 9, 197, 155, 3, 9, 5, 76, 0, 14, 139, 23, 3, 8, 18, 26, 3, 9, 197, 130, 2, 25, 20, 0, 0, 8, 133, 197, 130, 11, 15, 13, 20, 0, 15, 69, 21, 48, 193, 64, 80, 109, 89, 49, 6, 109, 57, 48, 0, 0, 11, 136, 26, 10, 5, 197, 186, 4, 197, 186, 20, 0, 12, 137, 7, 14, 9, 5, 197, 186, 4, 197, 186, 20, 0, 7, 196, 64, 197, 193, 40, 20, 9, 134, 13, 197, 155, 3, 9, 10, 20, 0, 0, 10, 135, 19, 3, 8, 197, 130, 1, 13, 20, 0, 0, 7, 196, 64, 197, 193, 52, 20, 9, 134, 13, 196, 133, 4, 18, 26, 20, 7, 132, 197, 130, 1, 16, 20, 9, 198, 4, 195, 9, 77, 65, 82, 65, 0, 6, 195, 73, 144, 218, 20, 0, 10, 135, 26, 23, 15, 197, 130, 2, 25, 20, 10, 135, 26, 14, 15, 197, 130, 2, 25, 20, 10, 135, 20, 11, 15, 197, 130, 2, 25, 20, 10, 135, 19, 19, 15, 197, 130, 2, 25, 20, 10, 135, 18, 23, 15, 197, 130, 2, 25, 20, 10, 135, 16, 1, 19, 197, 130, 2, 25, 20, 10, 135, 12, 1, 26, 197, 130, 2, 25, 20, 10, 135, 11, 9, 19, 197, 130, 2, 25, 20, 10, 135, 7, 18, 15, 197, 130, 2, 25, 20, 10, 135, 7, 14, 15, 197, 130, 2, 25, 20, 10, 135, 4, 2, 15, 197, 130, 2, 25, 20, 8, 133, 197, 130, 26, 1, 23, 20, 15, 6, 22, 15, 9, 12, 195, 160, 84, 40, 35, 55, 35, 0, 67, 0, 11, 136, 197, 188, 7, 15, 197, 130, 2, 25, 20, 11, 136, 26, 23, 9, 19, 197, 130, 2, 25, 20, 11, 136, 26, 23, 1, 18, 197, 130, 2, 25, 20, 11, 136, 26, 20, 1, 18, 197, 130, 2, 25, 20, 11, 136, 26, 14, 9, 11, 197, 130, 2, 25, 20, 11, 136, 26, 13, 25, 19, 197, 130, 2, 25, 20, 11, 136, 26, 7, 1, 19, 197, 130, 2, 25, 20, 11, 136, 26, 4, 1, 18, 197, 130, 2, 25, 20, 11, 136, 23, 20, 1, 18, 197, 130, 2, 25, 20, 11, 136, 23, 19, 9, 15, 197, 130, 2, 25, 20, 11, 136, 23, 16, 1, 18, 197, 130, 2, 25, 20, 11, 136, 23, 12, 1, 26, 197, 130, 2, 25, 20, 11, 136, 23, 4, 1, 18, 197, 130, 2, 25, 20, 11, 136, 19, 16, 1, 19, 197, 130, 2, 25, 20, 11, 136, 19, 11, 9, 19, 197, 130, 2, 25, 20, 11, 136, 19, 9, 5, 11, 197, 130, 2, 25, 20, 11, 136, 13, 195, 179, 11, 197, 130, 2, 25, 20, 11, 136, 13, 195, 179, 7, 197, 130, 2, 25, 20, 11, 136, 13, 1, 18, 26, 197, 130, 2, 25, 20, 11, 136, 197, 130, 11, 1, 197, 130, 2, 25, 20, 11, 136, 7, 18, 26, 15, 197, 130, 2, 25, 20, 11, 136, 7, 18, 25, 26, 197, 130, 2, 25, 20, 11, 136, 3, 9, 5, 11, 197, 130, 2, 25, 20, 11, 136, 2, 12, 1, 11, 197, 130, 2, 25, 20, 0, 12, 137, 26, 13, 195, 179, 11, 197, 130, 2, 25, 20, 12, 137, 26, 13, 1, 18, 26, 197, 130, 2, 25, 20, 12, 137, 26, 2, 12, 1, 11, 197, 130, 2, 25, 20, 12, 137, 23, 13, 1, 18, 26, 197, 130, 2, 25, 20, 12, 137, 23, 9, 195, 179, 26, 197, 130, 2, 25, 20, 12, 137, 23, 7, 18, 25, 26, 197, 130, 2, 25, 20, 12, 137, 23, 3, 9, 5, 11, 197, 130, 2, 25, 20, 12, 137, 20, 197, 130, 21, 11, 197, 130, 2, 25, 20, 12, 137, 19, 26, 3, 26, 15, 197, 130, 2, 25, 20, 12, 137, 4, 18, 197, 188, 15, 197, 130, 2, 25, 20, 9, 134, 10, 196, 133, 20, 18, 26, 20, 7, 196, 12, 133, 193, 48, 20, 20, 68, 65, 38, 133, 16, 48, 91, 6, 109, 72, 67, 38, 109, 0, 81, 110, 105, 101, 32, 21, 68, 65, 38, 133, 16, 48, 91, 6, 109, 72, 67, 37, 107, 0, 81, 110, 105, 99, 104, 32, 20, 68, 65, 38, 133, 16, 48, 91, 6, 109, 72, 84, 35, 89, 0, 81, 119, 97, 115, 32, 20, 68, 65, 38, 133, 16, 48, 91, 6, 109, 47, 47, 112, 65, 0, 81, 116, 121, 109, 32, 21, 68, 65, 38, 133, 16, 48, 91, 6, 109, 47, 47, 112, 107, 0, 81, 116, 121, 99, 104, 32, 18, 68, 65, 38, 133, 16, 48, 91, 6, 109, 47, 47, 111, 0, 81, 116, 111, 32, 18, 68, 65, 38, 133, 16, 48, 91, 6, 109, 47, 47, 109, 0, 81, 116, 101, 32, 19, 68, 65, 38, 133, 16, 48, 91, 6, 109, 47, 47, 114, 0, 81, 116, 196, 133, 32, 20, 68, 65, 38, 133, 16, 48, 91, 6, 109, 72, 67, 37, 65, 0, 81, 110, 105, 109, 32, 21, 68, 65, 38, 133, 16, 48, 91, 6, 109, 72, 67, 38, 114, 0, 81, 110, 105, 196, 133, 32, 20, 68, 65, 38, 133, 16, 48, 91, 6, 109, 72, 50, 35, 89, 0, 81, 110, 97, 115, 32, 7, 196, 65, 38, 133, 16, 76, 0, 13, 138, 20, 18, 26, 196, 133, 19, 197, 130, 2, 25, 20, 13, 138, 197, 155, 3, 9, 5, 11, 197, 130, 2, 25, 20, 8, 197, 104, 208, 82, 81, 112, 20, 6, 195, 92, 145, 74, 20, 7, 132, 14, 21, 196, 135, 20, 0, 14, 139, 197, 188, 195, 179, 197, 130, 11, 197, 130, 2, 25, 20, 14, 139, 19, 20, 18, 26, 196, 133, 19, 197, 130, 2, 25, 20, 8, 133, 26, 12, 1, 196, 135, 20, 8, 133, 26, 4, 1, 196, 135, 20, 8, 133, 23, 4, 1, 196, 135, 20, 11, 136, 19, 16, 9, 196, 153, 20, 18, 26, 20, 8, 133, 13, 12, 5, 196, 135, 20, 8, 133, 13, 196, 133, 196, 135, 20, 6, 195, 12, 128, 197, 20, 0, 9, 134, 19, 20, 18, 21, 196, 135, 20, 9, 134, 19, 16, 18, 21, 196, 135, 20, 9, 134, 18, 197, 188, 5, 196, 135, 20, 9, 134, 16, 9, 196, 133, 196, 135, 20, 10, 199, 4, 212, 212, 21, 33, 1, 52, 65, 0, 10, 135, 26, 197, 188, 196, 133, 196, 135, 20, 10, 135, 26, 13, 9, 196, 133, 196, 135, 20, 10, 135, 23, 26, 4, 196, 133, 196, 135, 20, 10, 135, 23, 16, 9, 196, 133, 196, 135, 20, 10, 135, 19, 16, 9, 196, 133, 196, 135, 20, 8, 133, 197, 130, 11, 1, 13, 20, 7, 196, 52, 145, 76, 36, 76, 9, 198, 4, 194, 83, 80, 18, 82, 65, 0, 11, 136, 23, 19, 16, 9, 196, 133, 196, 135, 20, 10, 135, 10, 5, 197, 186, 4, 197, 186, 20, 0, 6, 195, 92, 145, 77, 20, 12, 137, 23, 3, 8, 18, 26, 3, 9, 196, 135, 20, 8, 133, 16, 18, 1, 196, 135, 20, 10, 67, 12, 149, 25, 117, 37, 47, 112, 0, 0, 9, 134, 197, 188, 18, 5, 196, 135, 20, 9, 134, 26, 197, 188, 21, 196, 135, 20, 9, 134, 26, 7, 18, 1, 196, 135, 20, 12, 137, 26, 2, 18, 21, 197, 186, 4, 197, 186, 20, 9, 134, 23, 18, 26, 5, 196, 135, 20, 8, 133, 197, 130, 11, 1, 10, 20, 12, 137, 4, 197, 186, 7, 14, 9, 5, 19, 26, 20, 9, 134, 3, 26, 3, 9, 196, 135, 20, 10, 67, 48, 240, 68, 55, 111, 58, 72, 0, 0, 9, 134, 19, 197, 130, 25, 19, 26, 20, 11, 136, 13, 9, 15, 197, 188, 4, 197, 188, 20, 13, 68, 24, 246, 69, 72, 83, 40, 35, 57, 6, 109, 0, 10, 67, 12, 144, 79, 76, 57, 35, 58, 0, 0, 11, 136, 3, 8, 18, 26, 3, 9, 196, 135, 20, 0, 0, 6, 195, 92, 145, 64, 20, 8, 133, 16, 18, 1, 197, 130, 20, 0, 9, 134, 26, 197, 188, 21, 197, 130, 20, 9, 134, 26, 7, 18, 1, 197, 130, 20, 8, 133, 18, 197, 188, 196, 153, 20, 9, 134, 3, 26, 3, 9, 197, 130, 20, 6, 195, 12, 145, 67, 20, 0, 8, 133, 26, 7, 9, 197, 132, 20, 8, 197, 77, 67, 9, 77, 160, 20, 0, 11, 136, 3, 8, 18, 26, 3, 9, 197, 130, 20, 0, 11, 136, 19, 9, 15, 4, 197, 130, 2, 25, 20, 11, 136, 19, 5, 3, 8, 197, 130, 2, 25, 20, 11, 136, 16, 21, 3, 8, 197, 130, 2, 25, 20, 11, 136, 2, 195, 179, 4, 197, 130, 2, 25, 20, 8, 133, 26, 12, 1, 197, 130, 20, 8, 133, 26, 4, 1, 197, 130, 20, 8, 133, 23, 4, 1, 197, 130, 20, 8, 133, 3, 26, 21, 197, 130, 20, 7, 132, 3, 12, 196, 153, 20, 0, 12, 137, 23, 19, 9, 15, 4, 197, 130, 2, 25, 20, 12, 137, 11, 18, 26, 5, 16, 197, 130, 2, 25, 20, 12, 137, 3, 9, 5, 18, 16, 197, 130, 2, 25, 20, 12, 137, 3, 8, 18, 25, 16, 197, 130, 2, 25, 20, 7, 196, 104, 112, 82, 8, 20, 7, 196, 81, 38, 133, 64, 20, 9, 134, 19, 20, 18, 21, 197, 130, 20, 9, 134, 19, 16, 18, 21, 197, 130, 20, 9, 134, 13, 9, 196, 133, 197, 130, 20, 7, 196, 45, 38, 133, 64, 20, 0, 13, 138, 26, 23, 9, 195, 179, 4, 197, 130, 2, 25, 20, 13, 138, 19, 11, 18, 26, 5, 16, 197, 130, 2, 25, 20, 13, 138, 19, 3, 8, 18, 25, 16, 197, 130, 2, 25, 20, 10, 135, 26, 197, 188, 196, 133, 197, 130, 20, 10, 135, 26, 13, 9, 196, 133, 197, 130, 20, 10, 135, 23, 197, 188, 196, 133, 197, 130, 20, 10, 135, 23, 26, 4, 196, 133, 197, 130, 20, 10, 135, 23, 16, 9, 196, 133, 197, 130, 20, 8, 197, 77, 2, 69, 73, 160, 20, 10, 135, 19, 16, 9, 196, 133, 197, 130, 20, 8, 197, 76, 180, 149, 77, 160, 20, 8, 197, 52, 67, 9, 77, 160, 20, 8, 197, 45, 38, 153, 13, 160, 20, 9, 134, 4, 18, 197, 188, 196, 153, 20, 0, 14, 139, 197, 155, 3, 9, 5, 18, 16, 197, 130, 2, 25, 20, 14, 139, 16, 9, 5, 18, 26, 3, 8, 197, 130, 2, 25, 20, 11, 136, 23, 19, 16, 9, 196, 133, 197, 130, 20, 0, 15, 140, 26, 13, 9, 5, 18, 26, 3, 8, 197, 130, 2, 25, 20, 12, 137, 23, 3, 8, 18, 26, 3, 9, 197, 130, 20, 10, 135, 3, 8, 18, 26, 1, 197, 132, 20, 0, 11, 200, 93, 54, 131, 104, 226, 69, 77, 160, 20, 11, 136, 19, 3, 8, 18, 26, 1, 197, 132, 20, 0, 10, 135, 19, 9, 5, 18, 4, 197, 186, 20, 18, 8, 3, 21, 18, 1, 195, 167, 1, 15, 49, 37, 51, 35, 89, 35, 111, 0, 0, 11, 136, 20, 23, 9, 5, 18, 4, 197, 186, 20, 0, 0, 0, 12, 137, 26, 13, 9, 1, 197, 188, 4, 197, 188, 20, 8, 197, 80, 50, 14, 36, 80, 20, 8, 197, 76, 50, 14, 36, 80, 20, 8, 197, 12, 132, 154, 12, 144, 20, 0, 9, 198, 105, 114, 67, 33, 38, 128, 20, 9, 198, 93, 160, 137, 21, 38, 128, 20, 10, 67, 32, 243, 69, 101, 111, 58, 65, 0, 0, 6, 195, 16, 243, 64, 20, 0, 9, 198, 65, 53, 18, 105, 148, 218, 20, 0, 9, 134, 12, 1, 197, 130, 2, 25, 20, 9, 134, 4, 1, 197, 130, 2, 25, 20, 9, 134, 2, 9, 197, 130, 2, 25, 20, 0, 10, 135, 197, 188, 25, 197, 130, 2, 25, 20, 10, 135, 26, 26, 21, 197, 130, 2, 25, 20, 10, 135, 26, 23, 1, 197, 130, 2, 25, 20, 10, 135, 26, 13, 25, 197, 130, 2, 25, 20, 10, 135, 23, 12, 1, 197, 130, 2, 25, 20, 10, 135, 20, 12, 1, 197, 130, 2, 25, 20, 10, 135, 20, 11, 1, 197, 130, 2, 25, 20, 10, 135, 19, 20, 1, 197, 130, 2, 25, 20, 10, 135, 19, 19, 1, 197, 130, 2, 25, 20, 10, 135, 19, 16, 1, 197, 130, 2, 25, 20, 10, 135, 19, 14, 21, 197, 130, 2, 25, 20, 10, 135, 18, 23, 1, 197, 130, 2, 25, 20, 10, 135, 11, 14, 21, 197, 130, 2, 25, 20, 10, 135, 10, 196, 133, 197, 130, 2, 25, 20, 10, 135, 7, 14, 9, 197, 130, 2, 25, 20, 10, 135, 3, 14, 9, 197, 130, 2, 25, 20, 0, 11, 136, 197, 188, 7, 1, 197, 130, 2, 25, 20, 11, 136, 26, 7, 14, 9, 197, 130, 2, 25, 20, 11, 136, 23, 19, 20, 1, 197, 130, 2, 25, 20, 11, 136, 23, 19, 14, 21, 197, 130, 2, 25, 20, 11, 136, 20, 18, 23, 1, 197, 130, 2, 25, 20, 11, 136, 197, 155, 14, 9, 197, 130, 2, 25, 20, 11, 136, 19, 20, 12, 9, 197, 130, 2, 25, 20, 11, 136, 16, 3, 8, 1, 197, 130, 2, 25, 20, 11, 136, 13, 4, 12, 1, 197, 130, 2, 25, 20, 11, 136, 11, 23, 9, 20, 197, 130, 2, 25, 20, 11, 136, 11, 197, 130, 21, 197, 130, 2, 25, 20, 11, 136, 196, 135, 16, 1, 197, 130, 2, 25, 20, 11, 136, 196, 135, 13, 9, 197, 130, 2, 25, 20, 11, 136, 3, 8, 12, 1, 197, 130, 2, 25, 20, 6, 195, 92, 19, 64, 72, 0, 12, 137, 26, 19, 9, 15, 4, 197, 130, 2, 25, 20, 12, 137, 26, 4, 10, 196, 133, 197, 130, 2, 25, 20, 12, 137, 23, 11, 197, 130, 21, 197, 130, 2, 25, 20, 12, 137, 20, 11, 14, 196, 133, 197, 130, 2, 25, 20, 12, 137, 20, 196, 153, 3, 8, 197, 130, 2, 25, 20, 12, 137, 197, 155, 12, 5, 16, 197, 130, 2, 25, 20, 12, 137, 19, 26, 3, 26, 21, 197, 130, 2, 25, 20, 12, 137, 19, 11, 18, 26, 25, 197, 130, 2, 25, 20, 12, 137, 19, 11, 197, 130, 21, 197, 130, 2, 25, 20, 12, 137, 19, 3, 8, 12, 1, 197, 130, 2, 25, 20, 12, 137, 13, 11, 14, 196, 133, 197, 130, 2, 25, 20, 12, 137, 4, 18, 197, 188, 1, 197, 130, 2, 25, 20, 12, 137, 2, 18, 14, 196, 133, 197, 130, 2, 25, 20, 0, 13, 138, 197, 188, 7, 14, 196, 133, 197, 130, 2, 25, 20, 13, 138, 23, 23, 9, 195, 179, 4, 197, 130, 2, 25, 20, 13, 138, 20, 3, 8, 14, 196, 133, 197, 130, 2, 25, 20, 13, 138, 18, 197, 188, 14, 196, 133, 197, 130, 2, 25, 20, 13, 138, 16, 3, 8, 14, 196, 133, 197, 130, 2, 25, 20, 13, 138, 4, 18, 7, 14, 196, 133, 197, 130, 2, 25, 20, 13, 138, 3, 26, 11, 14, 196, 133, 197, 130, 2, 25, 20, 9, 134, 197, 130, 197, 188, 196, 153, 20, 7, 132, 12, 5, 196, 135, 20, 0, 14, 139, 4, 197, 188, 4, 197, 188, 25, 197, 130, 2, 25, 20, 14, 139, 4, 197, 186, 7, 14, 196, 133, 197, 130, 2, 25, 20, 14, 139, 3, 8, 197, 130, 195, 179, 4, 197, 130, 2, 25, 20, 8, 133, 26, 23, 9, 196, 135, 20, 8, 133, 26, 13, 25, 196, 135, 20, 8, 133, 23, 12, 1, 196, 135, 20, 8, 133, 19, 20, 1, 196, 135, 20, 8, 133, 11, 14, 21, 196, 135, 20, 8, 133, 11, 12, 5, 196, 135, 20, 8, 133, 10, 196, 133, 196, 135, 20, 0, 9, 134, 26, 18, 26, 21, 196, 135, 20, 9, 134, 23, 19, 14, 21, 196, 135, 20, 9, 134, 23, 18, 26, 21, 196, 135, 20, 9, 134, 23, 16, 12, 5, 196, 135, 20, 9, 134, 19, 16, 12, 5, 196, 135, 20, 9, 134, 19, 11, 12, 5, 196, 135, 20, 9, 134, 16, 14, 196, 133, 196, 135, 20, 9, 134, 13, 4, 12, 5, 196, 135, 20, 9, 134, 11, 197, 130, 21, 196, 135, 20, 13, 67, 45, 4, 128, 49, 35, 48, 51, 35, 55, 0, 24, 0, 10, 135, 26, 4, 10, 196, 133, 196, 135, 20, 10, 135, 23, 11, 197, 130, 21, 196, 135, 20, 8, 133, 19, 19, 9, 196, 133, 20, 10, 135, 19, 11, 197, 130, 21, 196, 135, 20, 10, 135, 4, 18, 197, 188, 5, 196, 135, 20, 9, 198, 4, 192, 83, 80, 18, 82, 65, 0, 11, 136, 19, 20, 197, 130, 1, 13, 197, 155, 20, 11, 136, 19, 3, 8, 14, 196, 133, 196, 135, 20, 11, 136, 19, 3, 8, 197, 130, 1, 197, 155, 20, 10, 135, 16, 195, 179, 10, 4, 197, 186, 20, 11, 136, 16, 3, 8, 14, 196, 133, 196, 135, 20, 7, 132, 4, 21, 196, 135, 20, 11, 136, 4, 18, 7, 14, 196, 133, 196, 135, 20, 11, 136, 3, 26, 11, 14, 196, 133, 196, 135, 20, 0, 11, 136, 18, 197, 188, 14, 9, 5, 19, 26, 20, 11, 136, 16, 18, 26, 25, 10, 4, 197, 186, 20, 0, 10, 135, 197, 155, 3, 9, 5, 18, 16, 20, 9, 134, 16, 197, 130, 1, 196, 135, 20, 9, 134, 4, 18, 23, 9, 196, 135, 20, 0, 10, 135, 23, 16, 197, 130, 1, 196, 135, 20, 10, 135, 19, 26, 3, 26, 1, 196, 135, 20, 10, 135, 19, 16, 197, 130, 1, 196, 135, 20, 9, 134, 197, 130, 11, 1, 19, 26, 20, 11, 136, 7, 23, 9, 197, 188, 4, 197, 188, 20, 19, 67, 12, 131, 215, 76, 35, 58, 76, 35, 40, 0, 66, 81, 99, 104, 111, 119, 32, 0, 8, 197, 77, 68, 154, 20, 192, 20, 9, 134, 4, 18, 23, 9, 196, 133, 20, 0, 8, 133, 26, 23, 196, 133, 3, 20, 7, 132, 4, 21, 197, 130, 20, 0, 0, 9, 134, 4, 18, 23, 9, 197, 130, 20, 0, 8, 133, 26, 23, 9, 197, 132, 20, 10, 135, 19, 26, 3, 26, 1, 197, 130, 20, 8, 133, 19, 20, 1, 197, 132, 20, 9, 134, 18, 197, 188, 14, 9, 5, 20, 0, 9, 134, 197, 188, 197, 130, 15, 16, 20, 9, 134, 19, 6, 18, 21, 197, 132, 20, 14, 70, 12, 245, 20, 4, 113, 64, 49, 111, 47, 112, 75, 0, 15, 70, 12, 243, 12, 4, 113, 64, 49, 111, 55, 6, 35, 90, 0, 10, 135, 13, 9, 196, 153, 4, 26, 25, 76, 0, 8, 133, 26, 13, 25, 197, 130, 20, 8, 133, 23, 12, 1, 197, 130, 20, 8, 133, 20, 12, 1, 197, 130, 20, 12, 137, 197, 155, 13, 9, 1, 18, 4, 197, 130, 20, 8, 133, 19, 20, 1, 197, 130, 20, 8, 133, 19, 16, 1, 197, 130, 20, 8, 133, 11, 14, 21, 197, 130, 20, 8, 133, 10, 196, 133, 197, 130, 20, 18, 67, 12, 131, 208, 76, 111, 48, 89, 40, 37, 0, 81, 115, 117, 101, 121, 32, 0, 9, 134, 23, 19, 14, 21, 197, 130, 20, 7, 196, 93, 38, 133, 64, 20, 9, 134, 11, 197, 130, 21, 197, 130, 20, 0, 8, 133, 26, 18, 1, 197, 132, 20, 8, 197, 104, 210, 76, 13, 160, 20, 10, 135, 26, 4, 10, 196, 133, 197, 130, 20, 10, 135, 23, 11, 197, 130, 21, 197, 130, 20, 10, 135, 19, 11, 197, 130, 21, 197, 130, 20, 8, 197, 52, 150, 132, 73, 160, 20, 8, 197, 29, 86, 132, 73, 160, 20, 0, 9, 134, 19, 16, 12, 21, 197, 132, 20, 11, 136, 16, 3, 8, 14, 196, 133, 197, 130, 20, 11, 136, 4, 18, 7, 14, 196, 133, 197, 130, 20, 11, 136, 3, 26, 11, 14, 196, 133, 197, 130, 20, 14, 70, 12, 243, 12, 20, 113, 64, 49, 111, 55, 109, 75, 0, 0, 8, 197, 105, 54, 129, 73, 0, 20, 0, 7, 196, 104, 224, 83, 104, 20, 7, 196, 92, 64, 83, 104, 20, 12, 68, 12, 245, 80, 20, 49, 40, 48, 6, 109, 0, 7, 132, 20, 5, 197, 188, 8, 0, 9, 198, 93, 54, 131, 104, 84, 0, 20, 11, 136, 23, 19, 11, 18, 26, 5, 197, 155, 20, 6, 195, 76, 145, 74, 20, 10, 135, 4, 18, 197, 188, 25, 19, 26, 20, 0, 11, 136, 2, 18, 21, 197, 186, 4, 197, 186, 20, 0, 0, 8, 133, 23, 197, 130, 15, 13, 20, 7, 196, 80, 176, 83, 104, 20, 0, 8, 133, 16, 18, 1, 197, 188, 20, 0, 0, 7, 132, 197, 130, 11, 1, 20, 0, 0, 6, 18, 66, 107, 97, 99, 104, 0, 107, 196, 153, 0, 107, 196, 133, 0, 107, 111, 109, 0, 107, 97, 0, 107, 105, 0, 99, 101, 0, 107, 111, 0, 7, 6, 100, 103, 0, 4, 1, 101, 122, 114, 112, 3, 72, 81, 0, 8, 97, 110, 0, 8, 97, 110, 101, 105, 110, 0, 8, 97, 110, 111, 112, 0, 8, 97, 110, 111, 112, 101, 105, 110, 0, 8, 111, 0, 8, 111, 101, 105, 110, 0, 8, 111, 111, 112, 0, 8, 111, 111, 112, 101, 105, 110, 0, 8, 111, 112, 0, 8, 111, 112, 101, 105, 110, 0, 8, 111, 112, 111, 112, 0, 8, 111, 112, 111, 112, 101, 105, 110, 0, 4, 3, 75, 0, 101, 2, 32, 0, 7, 6, 111, 101, 0, 4, 1, 106, 2, 114, 3, 109, 0, 1, 106, 108, 0, 1, 115, 2, 114, 0, 1, 106, 99, 3, 111, 109, 0, 7, 6, 112, 104, 0, 3, 83, 0, 7, 6, 115, 104, 0, 4, 8, 105, 102, 2, 97, 114, 109, 111, 110, 3, 89, 101, 0, 8, 107, 101, 0, 8, 121, 100, 0, 3, 91, 0, 105, 114, 101, 3, 91, 35, 57, 109, 51, 0, 7, 6, 116, 104, 0, 4, 8, 3, 47, 0, 8, 101, 2, 97, 110, 97, 107, 0, 101, 8, 2, 32, 3, 72, 109, 0, 101, 119, 3, 83, 57, 40, 0, 117, 110, 100, 101, 114, 98, 105, 8, 2, 114, 100, 3, 83, 109, 50, 72, 109, 51, 71, 109, 0, 97, 110, 107, 8, 3, 83, 109, 68, 49, 0, 3, 89, 0, 2, 105, 101, 32, 3, 95, 0, 7, 6, 116, 122, 0, 2, 197, 130, 3, 47, 88, 0, 3, 117, 0, 7, 6, 195, 164, 0, 3, 109, 0, 7, 6, 195, 165, 0, 3, 111, 0, 7, 6, 195, 166, 0, 3, 109, 0, 7, 6, 195, 173, 0, 3, 37, 0, 2, 17, 65, 3, 37, 57, 0, 7, 6, 195, 177, 0, 3, 67, 0, 2, 17, 65, 3, 67, 38, 0, 7, 6, 195, 179, 0, 4, 1, 21, 2, 17, 67, 197, 130, 98, 121, 32, 3, 8, 40, 0, 1, 21, 2, 17, 67, 197, 130, 98, 121, 109, 32, 0, 1, 21, 2, 17, 67, 197, 130, 98, 121, 197, 155, 32, 0, 3, 40, 0, 7, 6, 195, 182, 0, 3, 109, 0, 7, 6, 195, 184, 0, 3, 109, 0, 7, 6, 195, 188, 0, 3, 37, 0, 7, 6, 196, 133, 0, 4, 2, 108, 3, 111, 0, 2, 197, 130, 0, 4, 2, 99, 3, 111, 50, 0, 2, 100, 0, 2, 116, 0, 4, 2, 98, 3, 111, 65, 0, 2, 112, 0, 4, 2, 99, 105, 3, 111, 67, 0, 2, 100, 122, 105, 0, 2, 100, 197, 186, 0, 2, 196, 135, 0, 4, 2, 103, 3, 111, 68, 0, 2, 107, 0, 3, 114, 0, 4, 2, 32, 3, 114, 10, 0, 2, 32, 17, 65, 0, 7, 6, 196, 135, 0, 3, 119, 0, 4, 2, 98, 3, 120, 0, 2, 103, 0, 7, 6, 196, 141, 0, 3, 76, 0, 7, 6, 196, 153, 0, 4, 1, 105, 2, 116, 110, 97, 3, 109, 0, 2, 32, 0, 2, 108, 0, 2, 197, 130, 0, 2, 32, 17, 65, 3, 109, 10, 0, 4, 2, 99, 3, 109, 50, 0, 2, 100, 0, 2, 116, 0, 4, 2, 98, 3, 109, 65, 0, 2, 112, 0, 4, 2, 99, 105, 3, 109, 67, 0, 2, 100, 122, 105, 0, 2, 100, 197, 186, 0, 2, 115, 105, 0, 2, 196, 135, 0, 2, 197, 155, 0, 196, 135, 2, 100, 122, 105, 101, 0, 4, 2, 103, 3, 109, 68, 0, 2, 107, 0, 3, 113, 0, 7, 6, 197, 130, 0, 2, 32, 3, 0, 3, 58, 0, 4, 1, 17, 65, 2, 32, 3, 58, 10, 0, 1, 115, 121, 109, 2, 32, 0, 98, 121, 109, 1, 21, 2, 32, 14, 128, 128, 129, 3, 65, 0, 98, 121, 197, 155, 1, 21, 2, 32, 14, 128, 128, 129, 3, 97, 0, 7, 6, 197, 132, 0, 3, 67, 0, 7, 6, 197, 153, 0, 3, 90, 0, 7, 6, 197, 155, 0, 196, 135, 2, 100, 122, 105, 101, 3, 96, 0, 3, 97, 0, 7, 6, 197, 161, 0, 3, 91, 0, 7, 6, 197, 186, 0, 3, 96, 0, 2, 32, 3, 97, 0, 7, 6, 197, 188, 0, 3, 90, 0, 2, 32, 3, 91, 0, 7, 6, 197, 190, 0, 3, 90, 0, 7, 6, 97, 0, 108, 108, 111, 119, 101, 101, 1, 104, 2, 110, 32, 3, 6, 35, 55, 111, 58, 112, 0, 4, 1, 21, 2, 197, 130, 98, 121, 32, 3, 8, 35, 0, 1, 21, 2, 197, 130, 98, 121, 109, 32, 0, 1, 21, 2, 197, 130, 98, 121, 197, 155, 32, 0, 1, 130, 197, 21, 2, 98, 121, 32, 0, 1, 130, 197, 21, 2, 98, 121, 109, 32, 0, 1, 130, 197, 21, 2, 98, 121, 197, 155, 32, 0, 3, 35, 0, 2, 32, 3, 35, 10, 0, 4, 105, 8, 107, 2, 114, 3, 35, 37, 0, 105, 8, 116, 108, 97, 2, 114, 0, 114, 99, 121, 8, 2, 21, 14, 129, 132, 132, 3, 35, 51, 117, 112, 0, 108, 108, 111, 119, 101, 101, 1, 104, 2, 110, 3, 35, 55, 111, 58, 112, 0, 101, 8, 2, 114, 17, 65, 3, 35, 109, 0, 4, 101, 2, 32, 3, 109, 0, 101, 8, 0, 105, 1, 17, 67, 2, 114, 0, 99, 107, 117, 2, 112, 3, 109, 49, 35, 0, 114, 99, 104, 105, 101, 8, 3, 109, 51, 76, 37, 0, 114, 99, 104, 105, 101, 8, 2, 17, 67, 3, 109, 51, 76, 38, 109, 0, 108, 8, 104, 2, 108, 3, 111, 0, 7, 6, 98, 0, 4, 2, 32, 3, 48, 0, 197, 130, 1, 97, 106, 2, 107, 17, 65, 0, 3, 71, 0, 2, 105, 3, 71, 38, 0, 105, 2, 17, 65, 3, 71, 38, 57, 0, 4, 101, 114, 103, 1, 21, 21, 2, 32, 14, 129, 128, 132, 3, 71, 109, 34, 81, 0, 195, 182, 114, 103, 1, 21, 21, 2, 32, 14, 129, 128, 132, 0, 195, 184, 114, 103, 1, 21, 21, 2, 32, 14, 129, 128, 132, 0, 111, 114, 103, 1, 21, 21, 2, 32, 14, 129, 128, 132, 3, 71, 111, 34, 81, 0, 7, 6, 99, 0, 104, 97, 2, 109, 112, 105, 3, 47, 90, 109, 0, 4, 1, 17, 65, 118, 3, 49, 0, 1, 101, 115, 111, 99, 2, 97, 110, 115, 0, 1, 105, 100, 2, 116, 17, 65, 0, 2, 97, 99, 105, 101, 32, 0, 2, 97, 108, 118, 0, 2, 97, 116, 32, 0, 2, 97, 116, 97, 32, 0, 2, 97, 116, 97, 109, 105, 32, 0, 2, 97, 116, 101, 109, 32, 0, 2, 97, 116, 111, 32, 0, 2, 97, 116, 111, 109, 32, 0, 2, 108, 105, 112, 0, 2, 111, 115, 101, 99, 97, 110, 115, 0, 2, 111, 115, 105, 110, 0, 2, 111, 116, 97, 110, 103, 0, 2, 115, 0, 8, 2, 97, 98, 101, 114, 110, 101, 116, 0, 8, 2, 97, 108, 101, 110, 100, 0, 8, 2, 97, 110, 0, 8, 2, 97, 112, 112, 0, 8, 2, 97, 112, 115, 32, 0, 8, 2, 97, 112, 115, 108, 111, 0, 8, 2, 97, 114, 97, 118, 0, 8, 2, 97, 114, 108, 0, 8, 2, 97, 114, 112, 0, 8, 2, 97, 114, 116, 0, 8, 2, 97, 114, 118, 0, 8, 2, 108, 17, 65, 0, 8, 2, 111, 109, 0, 8, 2, 111, 110, 17, 67, 0, 8, 2, 111, 114, 17, 67, 0, 8, 2, 111, 119, 98, 111, 0, 8, 2, 114, 0, 8, 2, 117, 109, 117, 108, 0, 8, 101, 100, 2, 111, 114, 0, 8, 110, 105, 108, 2, 111, 108, 110, 0, 8, 114, 97, 2, 97, 100, 105, 97, 32, 0, 8, 114, 97, 2, 97, 100, 105, 105, 32, 0, 8, 114, 97, 2, 97, 100, 105, 111, 32, 0, 8, 114, 97, 2, 97, 100, 105, 196, 133, 32, 0, 8, 114, 97, 2, 97, 100, 105, 196, 153, 32, 0, 8, 115, 105, 100, 2, 111, 0, 99, 2, 97, 99, 105, 101, 32, 0, 99, 2, 97, 116, 17, 65, 0, 99, 2, 97, 116, 32, 0, 99, 2, 97, 116, 97, 32, 0, 99, 2, 97, 116, 97, 109, 105, 32, 0, 99, 2, 97, 116, 101, 109, 32, 0, 99, 2, 97, 116, 111, 32, 0, 99, 2, 97, 116, 111, 109, 32, 0, 99, 8, 111, 109, 2, 17, 65, 0, 104, 8, 2, 114, 105, 115, 116, 111, 0, 107, 1, 17, 65, 118, 0, 107, 1, 111, 108, 2, 32, 0, 107, 1, 111, 108, 2, 97, 32, 0, 107, 1, 111, 108, 2, 105, 101, 109, 32, 0, 107, 1, 111, 108, 2, 117, 32, 0, 107, 8, 101, 100, 0, 107, 8, 111, 114, 2, 17, 65, 0, 4, 8, 2, 97, 109, 101, 109, 98, 101, 114, 116, 3, 49, 35, 0, 97, 108, 2, 108, 17, 65, 0, 97, 108, 121, 2, 112, 115, 3, 49, 35, 55, 37, 0, 97, 115, 99, 3, 49, 35, 89, 49, 0, 117, 114, 105, 101, 8, 3, 49, 37, 51, 37, 0, 114, 111, 105, 115, 115, 8, 3, 49, 51, 34, 40, 35, 89, 0, 114, 97, 99, 107, 3, 49, 51, 35, 49, 0, 114, 101, 101, 110, 114, 101, 97, 8, 115, 2, 100, 3, 49, 51, 37, 50, 51, 37, 0, 114, 101, 115, 99, 2, 101, 110, 100, 3, 49, 51, 109, 91, 76, 0, 108, 111, 119, 8, 2, 110, 3, 49, 55, 35, 58, 0, 108, 101, 97, 8, 2, 17, 67, 3, 49, 55, 37, 0, 108, 111, 105, 115, 8, 2, 111, 3, 49, 55, 40, 35, 88, 0, 108, 111, 99, 104, 8, 2, 97, 114, 100, 3, 49, 55, 111, 91, 0, 4, 97, 8, 2, 109, 3, 49, 109, 0, 117, 8, 2, 114, 108, 105, 0, 97, 108, 2, 108, 3, 49, 111, 0, 111, 112, 121, 119, 114, 105, 8, 2, 116, 3, 49, 111, 48, 112, 51, 35, 57, 0, 111, 99, 107, 8, 3, 49, 111, 49, 0, 111, 110, 99, 8, 2, 101, 114, 116, 3, 49, 111, 50, 76, 0, 111, 97, 99, 104, 8, 3, 49, 111, 58, 76, 0, 4, 99, 2, 105, 32, 3, 76, 0, 99, 2, 105, 97, 32, 0, 99, 2, 105, 99, 104, 32, 0, 99, 2, 105, 101, 103, 111, 32, 0, 99, 2, 105, 101, 109, 32, 0, 99, 2, 105, 101, 109, 117, 32, 0, 99, 2, 105, 105, 101, 32, 0, 99, 2, 105, 109, 32, 0, 99, 2, 105, 109, 105, 32, 0, 99, 2, 105, 110, 97, 32, 0, 99, 2, 105, 110, 101, 109, 32, 0, 99, 2, 105, 110, 105, 101, 32, 0, 99, 2, 105, 110, 111, 32, 0, 99, 2, 105, 111, 32, 0, 104, 1, 17, 65, 118, 0, 104, 8, 2, 105, 112, 0, 122, 0, 104, 97, 110, 2, 110, 101, 108, 3, 76, 35, 0, 104, 97, 114, 108, 101, 8, 2, 115, 3, 76, 35, 51, 55, 89, 0, 104, 111, 119, 8, 2, 100, 101, 114, 3, 76, 35, 58, 0, 104, 105, 101, 8, 2, 102, 3, 76, 37, 0, 104, 105, 112, 112, 101, 110, 100, 97, 108, 8, 2, 17, 65, 3, 76, 37, 48, 109, 50, 72, 109, 57, 55, 0, 105, 99, 8, 2, 101, 114, 111, 110, 3, 76, 37, 76, 0, 104, 97, 108, 108, 101, 110, 103, 8, 2, 101, 114, 3, 76, 109, 55, 109, 50, 75, 0, 8, 2, 105, 110, 101, 114, 3, 89, 0, 4, 105, 1, 114, 97, 2, 97, 32, 3, 89, 37, 57, 0, 105, 1, 114, 97, 2, 105, 32, 0, 105, 1, 114, 97, 2, 111, 32, 0, 105, 1, 114, 97, 2, 196, 133, 32, 0, 105, 1, 114, 97, 2, 196, 153, 32, 0, 4, 105, 1, 17, 65, 2, 97, 110, 97, 32, 3, 89, 57, 0, 105, 1, 17, 65, 2, 97, 110, 101, 109, 32, 0, 105, 1, 17, 65, 2, 97, 110, 105, 101, 32, 0, 105, 1, 17, 65, 2, 97, 110, 111, 32, 0, 105, 1, 17, 65, 2, 97, 110, 111, 119, 105, 32, 0, 105, 1, 105, 108, 2, 97, 32, 0, 105, 1, 105, 108, 2, 105, 32, 0, 105, 1, 105, 108, 2, 111, 32, 0, 105, 1, 105, 108, 2, 196, 133, 32, 0, 105, 1, 105, 108, 2, 196, 153, 32, 0, 4, 104, 2, 101, 114, 114, 3, 91, 0, 104, 2, 101, 118, 0, 104, 105, 99, 8, 2, 97, 103, 17, 65, 3, 91, 37, 49, 0, 104, 111, 112, 105, 8, 2, 110, 3, 91, 111, 48, 109, 0, 104, 2, 105, 3, 99, 0, 104, 3, 107, 0, 104, 105, 1, 121, 115, 112, 2, 97, 3, 107, 37, 0, 104, 105, 2, 17, 65, 3, 107, 57, 0, 4, 3, 117, 0, 1, 105, 118, 2, 101, 0, 8, 2, 105, 114, 0, 8, 2, 111, 109, 98, 101, 114, 0, 8, 2, 111, 109, 98, 114, 17, 65, 0, 8, 2, 111, 109, 105, 101, 115, 0, 8, 2, 111, 109, 105, 110, 117, 0, 4, 2, 105, 3, 119, 0, 105, 2, 17, 65, 0, 7, 6, 100, 0, 2, 32, 3, 47, 0, 3, 72, 0, 105, 2, 17, 65, 3, 72, 57, 0, 4, 197, 188, 8, 97, 110, 3, 72, 90, 0, 197, 188, 8, 97, 110, 111, 112, 0, 197, 188, 8, 111, 0, 197, 188, 8, 111, 112, 0, 4, 122, 105, 8, 97, 110, 2, 101, 109, 3, 72, 96, 0, 122, 105, 8, 111, 112, 2, 101, 109, 0, 197, 188, 3, 75, 0, 197, 188, 2, 32, 3, 76, 0, 2, 105, 3, 116, 0, 4, 105, 101, 115, 2, 101, 108, 3, 116, 37, 88, 0, 105, 101, 115, 2, 108, 17, 65, 0, 122, 2, 32, 3, 117, 0, 122, 3, 118, 0, 197, 186, 2, 32, 3, 119, 0, 4, 122, 2, 105, 3, 120, 0, 122, 105, 2, 17, 65, 0, 197, 186, 0, 7, 6, 101, 0, 4, 1, 21, 2, 17, 67, 197, 130, 98, 121, 32, 3, 8, 109, 0, 1, 21, 2, 17, 67, 197, 130, 98, 121, 109, 32, 0, 1, 21, 2, 17, 67, 197, 130, 98, 121, 197, 155, 32, 0, 4, 105, 8, 2, 17, 67, 3, 35, 57, 0, 105, 8, 108, 107, 2, 110, 0, 4, 97, 1, 100, 2, 108, 101, 114, 3, 37, 0, 97, 1, 112, 115, 2, 107, 0, 97, 1, 116, 0, 97, 8, 17, 67, 2, 32, 0, 97, 8, 104, 2, 108, 101, 0, 97, 8, 108, 2, 100, 0, 101, 2, 110, 0, 101, 8, 17, 67, 2, 32, 0, 97, 108, 105, 116, 121, 1, 114, 2, 32, 3, 37, 6, 109, 55, 37, 47, 112, 0, 109, 97, 105, 108, 8, 3, 37, 65, 109, 57, 55, 0, 97, 115, 1, 108, 2, 105, 110, 3, 37, 88, 0, 4, 3, 109, 0, 97, 1, 114, 2, 103, 97, 110, 0, 97, 8, 104, 2, 100, 0, 2, 32, 17, 65, 3, 109, 10, 0, 97, 1, 116, 2, 116, 114, 3, 109, 35, 0, 97, 118, 121, 1, 104, 2, 25, 3, 109, 84, 37, 0, 1, 105, 2, 32, 3, 110, 0, 117, 2, 116, 115, 99, 104, 3, 111, 57, 0, 7, 6, 102, 0, 3, 83, 0, 105, 2, 17, 65, 3, 83, 38, 57, 0, 7, 6, 103, 0, 2, 32, 3, 49, 0, 101, 110, 116, 108, 101, 109, 97, 110, 8, 3, 75, 109, 50, 47, 109, 55, 65, 109, 50, 0, 4, 101, 111, 114, 103, 105, 8, 2, 97, 32, 3, 75, 111, 51, 75, 57, 0, 101, 111, 114, 103, 105, 8, 2, 105, 32, 0, 101, 111, 114, 103, 105, 8, 2, 111, 32, 0, 101, 111, 114, 103, 105, 8, 2, 196, 133, 32, 0, 101, 111, 114, 103, 105, 8, 2, 196, 153, 32, 0, 4, 3, 81, 0, 104, 0, 2, 105, 3, 81, 38, 0, 105, 1, 105, 104, 2, 101, 3, 81, 57, 0, 197, 130, 2, 32, 3, 81, 58, 0, 97, 116, 101, 2, 115, 3, 81, 109, 57, 47, 0, 7, 6, 104, 0, 2, 105, 3, 99, 0, 3, 101, 0, 105, 2, 17, 65, 3, 101, 57, 0, 7, 6, 105, 0, 114, 101, 8, 102, 2, 102, 111, 120, 32, 3, 6, 35, 57, 109, 51, 0, 4, 1, 21, 2, 98, 121, 197, 155, 99, 105, 101, 32, 3, 8, 37, 0, 1, 21, 2, 98, 121, 197, 155, 109, 121, 32, 0, 1, 97, 100, 117, 21, 2, 18, 66, 32, 0, 1, 97, 104, 99, 21, 2, 18, 66, 32, 0, 1, 97, 122, 111, 21, 2, 18, 66, 32, 0, 1, 98, 97, 108, 21, 2, 18, 66, 32, 0, 1, 102, 97, 114, 21, 2, 18, 66, 32, 0, 1, 102, 105, 108, 21, 2, 18, 66, 32, 0, 1, 102, 111, 114, 21, 2, 18, 66, 32, 0, 1, 102, 121, 99, 21, 2, 18, 66, 32, 0, 1, 103, 97, 114, 21, 2, 18, 66, 32, 0, 1, 103, 111, 103, 21, 2, 18, 66, 32, 0, 1, 103, 111, 108, 2, 18, 66, 32, 0, 1, 103, 114, 117, 21, 2, 18, 66, 32, 0, 1, 104, 99, 121, 21, 2, 18, 66, 32, 0, 1, 108, 21, 2, 98, 121, 32, 0, 1, 108, 21, 2, 197, 155, 99, 105, 101, 32, 0, 1, 108, 21, 2, 197, 155, 109, 121, 32, 0, 1, 108, 97, 116, 21, 2, 18, 66, 32, 0, 1, 108, 98, 117, 21, 2, 18, 66, 32, 0, 1, 108, 107, 121, 21, 2, 18, 66, 32, 0, 1, 108, 111, 98, 21, 2, 18, 66, 32, 0, 1, 108, 111, 104, 21, 2, 18, 66, 32, 0, 1, 108, 112, 101, 21, 2, 18, 66, 32, 0, 1, 108, 117, 97, 21, 2, 18, 66, 32, 0, 1, 109, 97, 110, 21, 2, 18, 66, 32, 0, 1, 109, 97, 114, 21, 2, 18, 66, 32, 0, 1, 109, 101, 108, 21, 2, 18, 66, 32, 0, 1, 109, 101, 110, 21, 2, 18, 66, 32, 0, 1, 109, 101, 115, 21, 2, 18, 66, 32, 0, 1, 109, 105, 109, 2, 18, 66, 32, 0, 1, 109, 105, 110, 21, 2, 18, 66, 32, 0, 1, 109, 108, 97, 21, 2, 18, 66, 32, 0, 1, 109, 111, 107, 21, 2, 18, 66, 32, 0, 1, 109, 111, 110, 21, 2, 18, 66, 32, 0, 1, 109, 111, 114, 21, 2, 18, 66, 32, 0, 1, 109, 114, 101, 21, 2, 18, 66, 32, 0, 1, 109, 114, 111, 21, 2, 18, 66, 32, 0, 1, 109, 115, 106, 21, 2, 18, 66, 32, 0, 1, 109, 116, 121, 21, 2, 18, 66, 32, 0, 1, 110, 21, 2, 98, 121, 32, 0, 1, 110, 21, 2, 197, 155, 99, 105, 101, 32, 0, 1, 110, 97, 103, 21, 2, 18, 66, 32, 0, 1, 110, 97, 104, 21, 2, 18, 66, 32, 0, 1, 110, 97, 116, 21, 2, 18, 66, 32, 0, 1, 110, 97, 117, 21, 2, 18, 66, 32, 0, 1, 110, 101, 103, 21, 2, 18, 66, 32, 0, 1, 110, 104, 99, 21, 2, 18, 66, 32, 0, 1, 110, 105, 108, 21, 2, 18, 66, 32, 0, 1, 110, 111, 101, 21, 2, 18, 66, 32, 0, 1, 110, 111, 102, 21, 2, 18, 66, 32, 0, 1, 110, 111, 105, 21, 2, 18, 66, 32, 0, 1, 110, 111, 109, 21, 2, 18, 66, 32, 0, 1, 110, 111, 110, 21, 2, 18, 66, 32, 0, 1, 110, 111, 112, 21, 2, 18, 66, 32, 0, 1, 110, 111, 114, 21, 2, 18, 66, 32, 0, 1, 110, 111, 116, 2, 99, 101, 32, 0, 1, 110, 111, 116, 2, 107, 111, 32, 0, 1, 110, 111, 116, 2, 107, 196, 133, 32, 0, 1, 110, 111, 116, 2, 107, 196, 153, 32, 0, 1, 110, 111, 116, 97, 116, 2, 107, 97, 32, 0, 1, 110, 111, 116, 97, 116, 2, 107, 97, 99, 104, 32, 0, 1, 110, 111, 116, 97, 116, 2, 107, 105, 32, 0, 1, 110, 111, 116, 107, 101, 116, 2, 107, 97, 32, 0, 1, 110, 111, 116, 107, 101, 116, 2, 107, 97, 99, 104, 32, 0, 1, 110, 111, 116, 107, 101, 116, 2, 107, 105, 32, 0, 1, 110, 117, 109, 21, 2, 18, 66, 32, 0, 1, 111, 114, 101, 21, 2, 18, 66, 32, 0, 1, 112, 111, 114, 21, 2, 18, 66, 32, 0, 1, 112, 112, 105, 21, 2, 18, 66, 32, 0, 1, 119, 97, 108, 21, 2, 18, 66, 32, 0, 2, 197, 130, 98, 121, 32, 0, 2, 197, 130, 98, 121, 109, 32, 0, 2, 197, 130, 98, 121, 197, 155, 32, 0, 8, 109, 114, 101, 116, 2, 18, 66, 32, 0, 8, 109, 116, 121, 114, 2, 18, 66, 32, 0, 8, 110, 111, 116, 2, 107, 97, 32, 0, 8, 110, 111, 116, 2, 107, 97, 99, 104, 32, 0, 8, 110, 111, 116, 2, 107, 105, 32, 0, 8, 112, 101, 2, 18, 66, 0, 4, 97, 1, 17, 67, 21, 2, 197, 130, 121, 98, 121, 32, 3, 8, 38, 35, 0, 97, 1, 17, 67, 21, 2, 197, 130, 121, 98, 121, 197, 155, 99, 105, 101, 32, 0, 97, 1, 17, 67, 21, 2, 197, 130, 121, 98, 121, 197, 155, 109, 121, 32, 0, 4, 101, 1, 17, 67, 21, 2, 108, 105, 98, 121, 32, 3, 8, 38, 109, 0, 101, 1, 17, 67, 21, 2, 108, 105, 98, 121, 197, 155, 99, 105, 101, 32, 0, 101, 1, 17, 67, 21, 2, 108, 105, 98, 121, 197, 155, 109, 121, 32, 0, 8, 114, 100, 2, 118, 3, 35, 57, 0, 99, 8, 109, 2, 114, 111, 3, 35, 57, 49, 0, 109, 101, 8, 116, 3, 35, 57, 65, 0, 109, 101, 8, 116, 2, 114, 3, 35, 57, 65, 109, 0, 114, 101, 8, 102, 2, 102, 111, 3, 35, 57, 109, 51, 0, 4, 3, 37, 0, 8, 110, 105, 109, 111, 100, 2, 99, 101, 32, 12, 12, 0, 8, 110, 105, 109, 111, 100, 2, 107, 97, 32, 12, 12, 0, 8, 110, 105, 109, 111, 100, 2, 107, 97, 99, 104, 32, 12, 12, 0, 8, 110, 105, 109, 111, 100, 2, 107, 105, 32, 12, 12, 0, 8, 110, 105, 109, 111, 100, 2, 107, 111, 32, 12, 12, 0, 8, 110, 105, 109, 111, 100, 2, 107, 111, 109, 32, 12, 12, 0, 8, 110, 105, 109, 111, 100, 2, 107, 196, 133, 32, 12, 12, 0, 8, 110, 105, 109, 111, 100, 2, 107, 196, 153, 32, 12, 12, 0, 8, 110, 111, 114, 101, 119, 2, 99, 101, 32, 12, 12, 0, 8, 110, 111, 114, 101, 119, 2, 107, 97, 32, 12, 12, 0, 8, 110, 111, 114, 101, 119, 2, 107, 97, 99, 104, 32, 12, 12, 0, 8, 110, 111, 114, 101, 119, 2, 107, 105, 32, 12, 12, 0, 8, 110, 111, 114, 101, 119, 2, 107, 111, 32, 12, 12, 0, 8, 110, 111, 114, 101, 119, 2, 107, 111, 109, 32, 12, 12, 0, 8, 110, 111, 114, 101, 119, 2, 107, 196, 133, 32, 12, 12, 0, 8, 110, 111, 114, 101, 119, 2, 107, 196, 153, 32, 12, 12, 0, 4, 105, 1, 107, 97, 114, 2, 32, 3, 37, 57, 37, 0, 105, 1, 109, 188, 197, 2, 32, 0, 1, 17, 67, 2, 17, 65, 3, 38, 0, 8, 108, 107, 2, 101, 3, 38, 37, 57, 0, 101, 1, 17, 67, 2, 32, 3, 38, 110, 0, 4, 1, 17, 65, 2, 17, 65, 3, 57, 0, 2, 17, 65, 32, 12, 0, 7, 6, 106, 0, 3, 57, 0, 8, 2, 105, 109, 3, 75, 0, 101, 97, 2, 110, 115, 3, 75, 37, 0, 4, 97, 99, 107, 8, 2, 32, 3, 75, 109, 49, 0, 97, 99, 107, 8, 2, 115, 0, 97, 99, 107, 8, 2, 121, 0, 97, 99, 107, 121, 8, 2, 32, 3, 75, 109, 49, 37, 0, 97, 109, 101, 115, 8, 3, 75, 109, 57, 65, 89, 0, 97, 109, 101, 115, 105, 8, 2, 101, 32, 3, 75, 109, 57, 65, 97, 0, 101, 102, 102, 8, 3, 75, 109, 83, 0, 97, 122, 122, 3, 75, 109, 88, 0, 97, 122, 122, 2, 32, 3, 75, 109, 89, 0, 111, 104, 110, 8, 3, 75, 111, 50, 0, 111, 110, 97, 116, 104, 8, 3, 75, 111, 50, 35, 47, 0, 111, 104, 110, 105, 8, 2, 101, 3, 75, 111, 67, 38, 0, 97, 99, 113, 117, 101, 115, 8, 3, 90, 35, 49, 0, 8, 2, 105, 109, 101, 110, 3, 107, 0, 7, 6, 107, 0, 3, 49, 0, 108, 111, 119, 8, 2, 110, 3, 49, 55, 35, 58, 0, 197, 130, 2, 32, 3, 49, 58, 0, 7, 6, 108, 0, 3, 55, 0, 2, 32, 3, 55, 10, 0, 105, 8, 111, 112, 2, 17, 65, 3, 55, 37, 0, 105, 2, 17, 65, 3, 55, 57, 0, 7, 6, 109, 0, 3, 65, 0, 2, 32, 3, 65, 10, 0, 106, 8, 2, 114, 17, 65, 3, 65, 35, 57, 111, 0, 105, 8, 101, 105, 122, 2, 17, 65, 3, 65, 38, 0, 105, 1, 17, 65, 2, 17, 65, 3, 65, 57, 0, 99, 8, 2, 14, 129, 132, 130, 3, 65, 109, 49, 0, 7, 6, 110, 0, 3, 50, 0, 2, 32, 3, 50, 10, 0, 116, 111, 110, 1, 17, 65, 21, 2, 32, 14, 129, 128, 132, 3, 50, 47, 111, 50, 0, 103, 1, 97, 2, 101, 108, 3, 50, 75, 0, 4, 111, 102, 102, 2, 32, 14, 129, 128, 132, 3, 50, 111, 84, 0, 111, 102, 102, 2, 97, 32, 0, 111, 102, 102, 2, 97, 99, 104, 32, 0, 111, 102, 102, 2, 97, 109, 105, 32, 0, 111, 102, 102, 2, 101, 109, 32, 0, 111, 102, 102, 2, 105, 101, 32, 0, 111, 102, 102, 2, 111, 109, 32, 0, 111, 102, 102, 2, 111, 119, 105, 32, 0, 111, 102, 102, 2, 117, 32, 0, 4, 2, 99, 105, 3, 67, 0, 2, 100, 122, 105, 0, 2, 100, 197, 186, 0, 2, 105, 0, 2, 196, 135, 0, 4, 105, 2, 17, 65, 3, 67, 38, 0, 121, 2, 39, 101, 103, 111, 32, 0, 121, 2, 39, 101, 109, 117, 32, 0, 4, 2, 103, 3, 68, 0, 2, 107, 0, 103, 116, 111, 110, 1, 17, 65, 21, 2, 32, 14, 129, 128, 133, 3, 68, 81, 47, 111, 50, 0, 7, 6, 111, 0, 117, 116, 8, 103, 97, 114, 2, 32, 3, 6, 40, 0, 119, 8, 100, 2, 110, 3, 35, 58, 0, 117, 116, 115, 105, 100, 8, 3, 35, 58, 117, 35, 57, 72, 0, 105, 8, 112, 2, 114, 111, 116, 17, 65, 3, 40, 58, 35, 0, 101, 116, 104, 3, 109, 47, 0, 3, 111, 0, 2, 32, 17, 65, 3, 111, 12, 10, 0, 116, 101, 98, 111, 111, 8, 110, 2, 17, 67, 3, 111, 58, 47, 71, 40, 0, 7, 6, 112, 0, 3, 48, 0, 4, 197, 130, 8, 2, 99, 3, 48, 40, 58, 49, 111, 84, 50, 37, 0, 197, 130, 8, 2, 107, 0, 4, 105, 8, 111, 107, 2, 17, 65, 3, 48, 57, 0, 105, 8, 111, 107, 111, 116, 111, 102, 2, 17, 65, 0, 4, 112, 197, 130, 8, 2, 99, 3, 48, 111, 47, 48, 40, 58, 49, 111, 84, 50, 37, 0, 112, 197, 130, 8, 2, 107, 0, 7, 6, 113, 0, 3, 49, 0, 117, 2, 17, 65, 3, 49, 84, 0, 7, 6, 114, 0, 4, 3, 51, 0, 1, 17, 65, 2, 122, 197, 130, 0, 1, 25, 2, 17, 65, 0, 1, 32, 17, 65, 2, 17, 65, 0, 1, 97, 109, 2, 122, 108, 105, 110, 0, 1, 97, 109, 2, 122, 110, 0, 1, 97, 109, 100, 111, 2, 122, 97, 0, 2, 122, 105, 0, 8, 97, 109, 97, 122, 2, 122, 97, 0, 8, 97, 109, 122, 2, 122, 97, 0, 8, 111, 98, 2, 122, 111, 106, 0, 114, 1, 17, 65, 2, 17, 65, 0, 121, 39, 2, 101, 0, 105, 2, 17, 65, 3, 51, 57, 0, 4, 122, 8, 105, 109, 2, 97, 32, 12, 12, 12, 3, 51, 88, 0, 122, 8, 105, 109, 2, 97, 99, 104, 32, 12, 12, 12, 0, 122, 8, 105, 109, 2, 97, 109, 105, 32, 12, 12, 12, 0, 122, 8, 105, 109, 2, 111, 32, 12, 12, 12, 0, 122, 8, 105, 109, 2, 111, 119, 105, 101, 32, 12, 12, 12, 0, 122, 8, 105, 109, 2, 121, 32, 12, 12, 12, 0, 122, 8, 105, 109, 2, 195, 179, 119, 32, 12, 12, 12, 0, 122, 8, 105, 109, 2, 196, 133, 32, 12, 12, 12, 0, 122, 8, 105, 109, 2, 196, 153, 32, 12, 12, 12, 0, 122, 8, 117, 109, 2, 97, 32, 12, 12, 12, 0, 122, 8, 117, 109, 2, 97, 99, 104, 32, 12, 12, 12, 0, 122, 8, 117, 109, 2, 97, 109, 105, 32, 12, 12, 12, 0, 122, 8, 117, 109, 2, 97, 115, 105, 99, 104, 108, 0, 122, 8, 117, 109, 2, 111, 32, 12, 12, 12, 0, 122, 8, 117, 109, 2, 111, 119, 105, 101, 32, 12, 12, 12, 0, 122, 8, 117, 109, 2, 121, 32, 12, 12, 12, 0, 122, 8, 117, 109, 2, 195, 179, 119, 32, 12, 12, 12, 0, 122, 8, 117, 109, 2, 196, 133, 32, 12, 12, 12, 0, 122, 8, 117, 109, 2, 196, 153, 32, 12, 12, 12, 0, 4, 122, 2, 97, 110, 100, 3, 51, 117, 0, 122, 2, 105, 110, 105, 32, 0, 122, 2, 105, 110, 105, 99, 104, 32, 0, 122, 2, 105, 110, 105, 101, 103, 111, 32, 0, 122, 2, 105, 110, 105, 101, 109, 117, 32, 0, 122, 2, 105, 110, 105, 109, 32, 0, 122, 2, 105, 110, 105, 109, 105, 32, 0, 122, 2, 111, 110, 105, 32, 0, 122, 2, 111, 110, 105, 99, 104, 32, 0, 122, 2, 111, 110, 105, 101, 103, 111, 32, 0, 122, 2, 111, 110, 105, 101, 109, 117, 32, 0, 122, 2, 111, 110, 105, 109, 32, 0, 122, 2, 111, 110, 105, 109, 105, 32, 0, 122, 3, 90, 0, 4, 122, 1, 99, 2, 17, 65, 3, 91, 0, 122, 1, 102, 2, 17, 65, 0, 122, 1, 104, 0, 122, 1, 107, 0, 122, 1, 112, 0, 122, 1, 115, 2, 17, 65, 0, 122, 1, 116, 0, 122, 1, 122, 99, 2, 17, 65, 0, 122, 1, 122, 115, 2, 17, 65, 0, 122, 1, 135, 196, 2, 17, 65, 0, 122, 1, 155, 197, 2, 17, 65, 0, 122, 2, 32, 0, 7, 6, 115, 0, 4, 105, 1, 115, 2, 109, 97, 32, 3, 8, 37, 0, 105, 1, 115, 2, 109, 101, 109, 32, 0, 105, 1, 115, 2, 109, 105, 101, 32, 0, 105, 1, 115, 2, 109, 111, 32, 0, 4, 111, 110, 8, 101, 99, 108, 97, 115, 2, 32, 12, 12, 3, 8, 89, 111, 50, 0, 111, 110, 8, 105, 116, 97, 112, 2, 32, 12, 12, 0, 8, 97, 117, 113, 2, 105, 3, 88, 0, 3, 89, 0, 4, 105, 1, 107, 101, 108, 112, 2, 32, 3, 89, 37, 0, 105, 2, 98, 0, 105, 2, 99, 0, 105, 2, 100, 0, 105, 2, 102, 0, 105, 2, 103, 0, 105, 2, 104, 0, 105, 2, 108, 105, 107, 111, 0, 105, 2, 108, 108, 0, 105, 2, 108, 111, 115, 0, 105, 2, 108, 118, 0, 105, 2, 109, 0, 105, 2, 110, 103, 0, 105, 2, 110, 117, 115, 0, 105, 2, 113, 0, 105, 2, 114, 0, 105, 2, 116, 0, 105, 2, 118, 0, 105, 2, 120, 0, 105, 8, 107, 97, 109, 2, 32, 0, 116, 101, 105, 110, 1, 121, 3, 89, 47, 109, 37, 50, 0, 99, 104, 101, 114, 122, 3, 89, 49, 109, 51, 117, 0, 4, 105, 8, 97, 116, 115, 97, 110, 97, 2, 97, 32, 3, 89, 57, 0, 105, 8, 97, 116, 115, 97, 110, 97, 2, 105, 32, 0, 105, 8, 97, 116, 115, 97, 110, 97, 2, 111, 32, 0, 105, 8, 97, 116, 115, 97, 110, 97, 2, 196, 133, 32, 0, 105, 8, 97, 116, 115, 97, 110, 97, 2, 196, 153, 32, 0, 4, 99, 104, 1, 97, 112, 2, 97, 3, 89, 101, 0, 99, 104, 1, 101, 2, 97, 116, 111, 0, 99, 104, 2, 97, 98, 17, 65, 32, 0, 99, 104, 2, 97, 98, 32, 0, 99, 104, 2, 97, 98, 97, 109, 105, 32, 0, 99, 104, 2, 97, 98, 101, 109, 32, 0, 99, 104, 2, 97, 98, 105, 101, 32, 0, 99, 104, 2, 97, 98, 111, 109, 0, 99, 104, 2, 97, 98, 111, 115, 122, 0, 99, 104, 2, 97, 98, 111, 119, 17, 65, 0, 99, 104, 2, 97, 98, 195, 179, 0, 99, 104, 2, 97, 100, 122, 17, 65, 0, 99, 104, 2, 97, 100, 122, 107, 0, 99, 104, 2, 97, 109, 32, 0, 99, 104, 2, 97, 109, 105, 0, 99, 104, 2, 97, 109, 105, 17, 65, 0, 99, 104, 2, 97, 114, 97, 107, 116, 0, 99, 104, 2, 101, 100, 17, 65, 0, 99, 104, 2, 101, 100, 32, 0, 99, 104, 2, 101, 109, 97, 116, 0, 99, 104, 2, 105, 122, 109, 17, 65, 0, 99, 104, 2, 105, 122, 109, 32, 0, 99, 104, 2, 105, 122, 111, 0, 99, 104, 2, 108, 97, 108, 105, 0, 99, 104, 2, 108, 97, 110, 17, 65, 0, 99, 104, 2, 108, 97, 196, 135, 0, 99, 104, 2, 108, 97, 197, 130, 0, 99, 104, 2, 108, 101, 108, 105, 0, 99, 104, 2, 108, 117, 100, 110, 17, 65, 0, 99, 104, 2, 110, 105, 101, 32, 0, 99, 104, 2, 110, 105, 196, 153, 0, 99, 104, 2, 110, 196, 133, 0, 99, 104, 2, 110, 196, 153, 0, 99, 104, 2, 111, 100, 97, 99, 104, 32, 0, 99, 104, 2, 111, 100, 97, 109, 105, 32, 0, 99, 104, 2, 111, 100, 101, 107, 32, 0, 99, 104, 2, 111, 100, 107, 97, 0, 99, 104, 2, 111, 100, 107, 105, 0, 99, 104, 2, 111, 100, 107, 105, 101, 109, 32, 0, 99, 104, 2, 111, 100, 107, 111, 119, 0, 99, 104, 2, 111, 100, 107, 111, 119, 105, 32, 0, 99, 104, 2, 111, 100, 107, 117, 32, 0, 99, 104, 2, 111, 100, 107, 195, 179, 0, 99, 104, 2, 111, 100, 111, 119, 0, 99, 104, 2, 111, 100, 121, 32, 0, 99, 104, 2, 111, 100, 122, 105, 0, 99, 104, 2, 111, 100, 122, 196, 133, 0, 99, 104, 2, 111, 100, 122, 196, 153, 0, 99, 104, 2, 111, 100, 195, 179, 0, 99, 104, 2, 111, 114, 111, 119, 97, 0, 99, 104, 2, 111, 114, 122, 101, 0, 99, 104, 2, 111, 119, 17, 65, 0, 99, 104, 2, 111, 119, 97, 0, 99, 104, 2, 114, 111, 110, 17, 65, 0, 99, 104, 2, 114, 111, 110, 32, 0, 99, 104, 2, 114, 117, 112, 32, 0, 99, 104, 2, 114, 117, 112, 97, 108, 105, 0, 99, 104, 2, 114, 117, 112, 97, 110, 17, 65, 0, 99, 104, 2, 114, 117, 112, 97, 196, 135, 32, 0, 99, 104, 2, 114, 117, 112, 97, 197, 130, 0, 99, 104, 2, 114, 117, 112, 105, 17, 65, 0, 99, 104, 2, 114, 121, 112, 17, 65, 0, 99, 104, 2, 114, 121, 112, 108, 0, 99, 104, 2, 114, 121, 112, 197, 130, 0, 99, 104, 2, 114, 122, 17, 65, 0, 99, 104, 2, 117, 100, 110, 0, 99, 104, 2, 119, 121, 99, 105, 0, 99, 104, 2, 119, 121, 116, 17, 65, 0, 99, 104, 2, 121, 108, 17, 65, 0, 99, 104, 2, 121, 197, 130, 0, 99, 104, 2, 195, 179, 0, 99, 104, 2, 196, 133, 0, 99, 104, 2, 196, 153, 0, 99, 104, 2, 197, 130, 0, 99, 104, 8, 2, 101, 116, 121, 0, 99, 104, 8, 2, 101, 116, 121, 110, 0, 99, 104, 8, 2, 108, 101, 98, 32, 0, 99, 104, 8, 2, 108, 101, 98, 105, 0, 99, 104, 8, 2, 121, 108, 32, 0, 99, 104, 8, 119, 2, 111, 100, 0, 101, 110, 1, 21, 2, 32, 14, 129, 128, 131, 3, 89, 109, 50, 0, 111, 110, 1, 21, 2, 32, 14, 129, 128, 131, 3, 89, 111, 50, 0, 4, 99, 104, 3, 91, 0, 107, 106, 2, 17, 65, 0, 122, 0, 4, 116, 101, 105, 110, 3, 91, 47, 35, 57, 50, 0, 116, 101, 105, 110, 2, 32, 14, 129, 128, 133, 0, 99, 104, 119, 97, 114, 122, 3, 91, 84, 35, 51, 117, 0, 99, 104, 111, 101, 3, 91, 109, 0, 4, 101, 97, 8, 2, 110, 32, 3, 91, 111, 0, 101, 97, 8, 2, 110, 97, 32, 0, 101, 97, 8, 2, 110, 101, 109, 32, 0, 101, 97, 8, 2, 110, 105, 101, 32, 0, 101, 97, 8, 2, 110, 111, 119, 105, 32, 0, 101, 97, 8, 2, 110, 117, 32, 0, 4, 2, 105, 3, 97, 0, 105, 2, 17, 65, 0, 4, 105, 1, 117, 100, 2, 103, 114, 3, 97, 37, 0, 105, 2, 98, 114, 122, 0, 105, 2, 99, 17, 65, 0, 105, 2, 99, 104, 0, 105, 2, 99, 122, 0, 105, 2, 100, 108, 17, 65, 0, 105, 2, 100, 108, 32, 0, 105, 2, 100, 197, 130, 0, 105, 8, 2, 116, 17, 65, 0, 105, 8, 2, 116, 32, 0, 105, 8, 2, 116, 107, 0, 7, 6, 116, 0, 4, 3, 47, 0, 2, 114, 122, 0, 2, 115, 0, 111, 119, 110, 2, 32, 14, 129, 128, 132, 3, 47, 35, 58, 50, 0, 105, 2, 17, 65, 3, 47, 57, 0, 116, 104, 101, 119, 3, 89, 57, 40, 0, 2, 105, 3, 115, 0, 7, 6, 117, 0, 4, 1, 21, 2, 197, 130, 98, 121, 32, 3, 8, 40, 0, 1, 21, 2, 197, 130, 98, 121, 109, 32, 0, 1, 21, 2, 197, 130, 98, 121, 197, 155, 32, 0, 110, 99, 104, 8, 108, 3, 35, 50, 76, 0, 4, 3, 40, 0, 1, 97, 110, 2, 99, 122, 0, 1, 97, 110, 2, 107, 0, 1, 97, 114, 97, 112, 0, 1, 97, 116, 101, 109, 0, 1, 101, 17, 67, 2, 109, 32, 0, 1, 101, 17, 67, 2, 115, 0, 8, 97, 122, 0, 8, 101, 105, 110, 0, 8, 101, 122, 114, 112, 0, 2, 32, 17, 65, 3, 40, 10, 0, 101, 116, 111, 111, 116, 104, 8, 108, 98, 3, 40, 47, 40, 83, 0, 115, 105, 99, 8, 109, 2, 97, 108, 32, 3, 57, 6, 40, 88, 37, 49, 0, 115, 105, 99, 8, 109, 2, 97, 108, 3, 57, 40, 88, 37, 49, 0, 4, 1, 97, 3, 58, 0, 1, 101, 0, 8, 97, 122, 2, 116, 111, 0, 105, 99, 107, 8, 98, 3, 58, 37, 49, 0, 7, 6, 118, 0, 105, 99, 101, 8, 2, 21, 14, 129, 132, 132, 3, 58, 37, 117, 109, 0, 4, 1, 102, 2, 17, 65, 3, 83, 0, 1, 104, 2, 17, 65, 0, 1, 107, 2, 17, 65, 0, 1, 112, 2, 17, 65, 0, 1, 115, 2, 17, 65, 0, 1, 116, 2, 17, 65, 0, 2, 111, 108, 107, 115, 0, 3, 84, 0, 105, 108, 108, 101, 2, 32, 14, 129, 128, 133, 3, 84, 37, 55, 0, 7, 6, 119, 0, 2, 115, 107, 3, 10, 84, 0, 4, 114, 105, 103, 104, 3, 51, 35, 57, 0, 114, 105, 103, 104, 1, 17, 67, 0, 8, 2, 32, 3, 58, 0, 101, 101, 2, 107, 3, 58, 37, 0, 4, 8, 2, 32, 102, 3, 58, 109, 0, 8, 2, 32, 109, 110, 0, 97, 115, 104, 105, 8, 3, 58, 111, 91, 37, 0, 105, 110, 100, 111, 119, 8, 3, 58, 112, 50, 72, 111, 58, 0, 4, 1, 99, 2, 17, 65, 3, 83, 0, 1, 102, 2, 17, 65, 0, 1, 104, 2, 17, 65, 0, 1, 107, 2, 17, 65, 0, 1, 112, 2, 17, 65, 0, 1, 115, 2, 17, 65, 0, 1, 116, 2, 17, 65, 0, 1, 122, 99, 2, 17, 65, 0, 1, 122, 115, 2, 17, 65, 0, 1, 135, 196, 2, 17, 65, 0, 1, 155, 197, 2, 17, 65, 0, 2, 32, 0, 8, 2, 32, 99, 0, 8, 2, 32, 104, 0, 8, 2, 32, 107, 0, 8, 2, 32, 112, 0, 8, 2, 32, 115, 0, 8, 2, 32, 116, 0, 3, 84, 0, 105, 99, 101, 8, 2, 21, 14, 129, 132, 132, 3, 84, 37, 117, 109, 0, 115, 122, 1, 114, 101, 105, 2, 17, 65, 3, 91, 0, 7, 6, 120, 0, 3, 49, 89, 0, 7, 6, 121, 0, 4, 39, 1, 114, 2, 101, 103, 111, 32, 3, 0, 39, 1, 114, 2, 101, 109, 117, 32, 3, 0, 4, 1, 21, 2, 197, 130, 98, 121, 32, 3, 8, 112, 0, 1, 21, 2, 197, 130, 98, 121, 109, 32, 0, 1, 21, 2, 197, 130, 98, 121, 197, 155, 32, 0, 1, 98, 101, 2, 197, 155, 99, 105, 101, 32, 0, 1, 98, 101, 2, 197, 155, 109, 121, 32, 0, 1, 100, 108, 97, 21, 2, 18, 66, 32, 0, 1, 100, 111, 108, 21, 2, 18, 66, 32, 0, 1, 100, 111, 116, 21, 2, 18, 66, 32, 0, 1, 100, 114, 111, 21, 2, 18, 66, 32, 0, 1, 114, 101, 109, 21, 2, 18, 66, 32, 0, 1, 114, 101, 116, 21, 2, 18, 66, 32, 0, 1, 114, 111, 102, 21, 2, 18, 66, 32, 0, 1, 114, 111, 103, 21, 2, 18, 66, 32, 0, 1, 114, 111, 116, 21, 2, 18, 66, 32, 0, 1, 114, 116, 101, 21, 2, 18, 66, 32, 0, 1, 114, 116, 107, 21, 2, 18, 66, 32, 0, 1, 114, 116, 112, 21, 2, 18, 66, 32, 0, 1, 115, 97, 108, 21, 2, 18, 66, 32, 0, 1, 115, 107, 101, 21, 2, 18, 66, 32, 0, 1, 116, 97, 98, 21, 2, 18, 66, 32, 0, 1, 116, 97, 105, 21, 2, 18, 66, 32, 0, 1, 116, 97, 109, 21, 2, 18, 66, 32, 0, 1, 116, 97, 114, 21, 2, 18, 66, 32, 0, 1, 116, 97, 116, 21, 2, 18, 66, 32, 0, 1, 116, 101, 97, 21, 2, 18, 66, 32, 0, 1, 116, 101, 99, 21, 2, 18, 66, 32, 0, 1, 116, 101, 100, 21, 2, 18, 66, 32, 0, 1, 116, 101, 103, 21, 2, 18, 66, 32, 0, 1, 116, 101, 104, 21, 2, 18, 66, 32, 0, 1, 116, 101, 108, 21, 2, 18, 66, 32, 0, 1, 116, 101, 109, 21, 2, 18, 66, 32, 0, 1, 116, 101, 110, 21, 2, 18, 66, 32, 0, 1, 116, 101, 111, 21, 2, 18, 66, 32, 0, 1, 116, 101, 114, 21, 2, 18, 66, 32, 0, 1, 116, 101, 116, 21, 2, 18, 66, 32, 0, 1, 116, 105, 108, 21, 2, 18, 66, 32, 0, 1, 116, 107, 97, 21, 2, 18, 66, 32, 0, 1, 116, 107, 101, 21, 2, 18, 66, 32, 0, 1, 116, 107, 114, 21, 2, 18, 66, 32, 0, 1, 116, 108, 97, 21, 2, 18, 66, 32, 0, 1, 116, 110, 97, 21, 2, 18, 66, 32, 0, 1, 116, 110, 101, 21, 2, 18, 66, 32, 0, 1, 116, 111, 98, 21, 2, 18, 66, 32, 0, 1, 116, 111, 105, 21, 2, 18, 66, 32, 0, 1, 116, 111, 110, 21, 2, 18, 66, 32, 0, 1, 116, 111, 114, 21, 2, 18, 66, 32, 0, 1, 116, 111, 122, 21, 2, 18, 66, 32, 0, 1, 116, 112, 101, 21, 2, 18, 66, 32, 0, 1, 116, 112, 105, 21, 2, 18, 66, 32, 0, 1, 116, 112, 111, 2, 18, 66, 32, 0, 1, 116, 115, 97, 21, 2, 18, 66, 32, 0, 1, 116, 115, 101, 21, 2, 18, 66, 32, 0, 1, 116, 115, 105, 21, 2, 18, 66, 32, 0, 1, 116, 115, 111, 21, 2, 18, 66, 32, 0, 1, 116, 115, 117, 21, 2, 18, 66, 32, 0, 1, 116, 115, 121, 21, 2, 18, 66, 32, 0, 1, 116, 117, 97, 21, 2, 18, 66, 32, 0, 1, 116, 117, 101, 21, 2, 18, 66, 32, 0, 1, 116, 121, 114, 21, 2, 18, 66, 32, 0, 1, 122, 101, 110, 21, 2, 18, 66, 32, 0, 1, 122, 105, 102, 2, 18, 66, 32, 0, 1, 130, 197, 21, 2, 98, 121, 32, 0, 1, 130, 197, 21, 2, 98, 121, 197, 155, 99, 105, 101, 32, 0, 1, 130, 197, 21, 2, 98, 121, 197, 155, 109, 121, 32, 0, 8, 98, 97, 2, 197, 155, 99, 105, 101, 32, 0, 8, 98, 97, 2, 197, 155, 109, 121, 32, 0, 8, 115, 97, 108, 107, 2, 18, 66, 32, 0, 8, 116, 97, 116, 115, 2, 18, 66, 32, 0, 8, 116, 101, 2, 18, 66, 32, 0, 8, 116, 107, 97, 114, 112, 2, 18, 66, 32, 0, 8, 116, 115, 105, 109, 2, 18, 66, 0, 8, 116, 121, 114, 107, 2, 18, 66, 32, 0, 4, 39, 1, 17, 67, 2, 101, 103, 111, 32, 3, 38, 0, 39, 1, 17, 67, 2, 101, 109, 117, 32, 0, 4, 1, 17, 65, 2, 17, 65, 3, 57, 0, 1, 17, 65, 2, 32, 0, 8, 2, 17, 65, 0, 4, 3, 112, 0, 8, 114, 111, 116, 115, 105, 104, 2, 107, 97, 12, 12, 0, 8, 114, 111, 116, 115, 105, 104, 2, 107, 111, 109, 12, 12, 0, 8, 114, 116, 101, 116, 2, 107, 97, 12, 12, 0, 8, 114, 116, 101, 116, 2, 107, 111, 109, 12, 12, 0, 8, 116, 97, 112, 2, 12, 12, 0, 2, 32, 17, 65, 3, 112, 10, 0, 7, 6, 122, 0, 4, 3, 88, 0, 8, 2, 32, 0, 8, 111, 114, 2, 105, 17, 67, 0, 4, 105, 8, 2, 17, 67, 3, 88, 10, 37, 0, 105, 8, 101, 105, 110, 2, 17, 67, 0, 122, 8, 2, 97, 32, 3, 88, 10, 88, 0, 4, 105, 1, 111, 109, 2, 108, 108, 3, 88, 37, 0, 105, 2, 17, 67, 0, 8, 2, 32, 109, 110, 3, 88, 109, 0, 4, 2, 32, 3, 89, 0, 8, 2, 32, 99, 0, 8, 2, 32, 102, 0, 8, 2, 32, 104, 0, 8, 2, 32, 107, 0, 8, 2, 32, 112, 0, 8, 2, 32, 115, 0, 8, 2, 32, 116, 0, 4, 2, 105, 3, 96, 0, 105, 2, 17, 65, 0, 4, 105, 2, 109, 12, 3, 96, 37, 0, 105, 8, 2, 112, 0, 4, 2, 105, 110, 105, 32, 3, 117, 0, 2, 105, 110, 105, 99, 104, 32, 0, 2, 105, 110, 105, 101, 103, 111, 32, 0, 2, 105, 110, 105, 101, 109, 117, 32, 0, 2, 105, 110, 105, 109, 32, 0, 2, 105, 110, 105, 109, 105, 32, 0, 122, 2, 97, 32, 0, 122, 2, 97, 99, 104, 32, 0, 122, 2, 97, 109, 105, 32, 0, 122, 2, 97, 110, 105, 32, 0, 122, 2, 97, 110, 105, 99, 104, 32, 0, 122, 2, 97, 110, 105, 101, 103, 111, 32, 0, 122, 2, 97, 110, 105, 101, 109, 117, 32, 0, 122, 2, 97, 110, 105, 109, 32, 0, 122, 2, 97, 110, 105, 109, 105, 32, 0, 122, 2, 105, 110, 105, 32, 0, 122, 2, 105, 110, 105, 99, 104, 32, 0, 122, 2, 105, 110, 105, 101, 103, 111, 32, 0, 122, 2, 105, 110, 105, 101, 109, 117, 32, 0, 122, 2, 105, 110, 105, 109, 32, 0, 122, 2, 105, 110, 105, 109, 105, 32, 0, 122, 2, 111, 32, 0, 122, 2, 111, 110, 105, 32, 0, 122, 2, 111, 110, 105, 99, 104, 32, 0, 122, 2, 111, 110, 105, 101, 103, 111, 32, 0, 122, 2, 111, 110, 105, 101, 109, 117, 32, 0, 122, 2, 111, 110, 105, 109, 32, 0, 122, 2, 111, 110, 105, 109, 105, 32, 0, 122, 2, 121, 32, 0, 122, 2, 195, 179, 119, 32, 0, 122, 2, 196, 153, 32, 0, 122, 8, 17, 65, 109, 2, 17, 65, 0, 122, 8, 105, 112, 0, 117, 114, 105, 8, 2, 99, 104, 3, 117, 40, 51, 112, 0, 7, 6, 126, 0, 3, 0, 7, 6, 0, 39, 97, 2, 32, 14, 128, 128, 130, 3, 35, 0, 39, 117, 2, 32, 14, 128, 128, 130, 3, 40, 0, 36, 3, 72, 111, 55, 35, 51, 0, 39, 101, 109, 2, 32, 14, 128, 128, 131, 3, 109, 65, 0, 39, 101, 109, 117, 2, 32, 14, 128, 128, 132, 3, 109, 65, 40, 0, 39, 101, 103, 111, 2, 32, 14, 128, 128, 132, 3, 109, 81, 111, 0, 39, 111, 119, 105, 2, 32, 14, 128, 128, 132, 3, 111, 84, 37, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts50 = FileInMemory_createWithData (39425, reinterpret_cast (&espeakdata_dicts50_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/pl_dict", U"pl"); Collection_addItem (me.peek(), espeakdata_dicts50.transfer()); static unsigned char espeakdata_dicts51_data[2570] = { 0, 4, 0, 0, 12, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 5, 95, 48, 1, 14, 4, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 3, 95, 51, 88, 89, 6, 37, 0, 0, 10, 3, 95, 48, 67, 89, 6, 109, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 55, 88, 107, 6, 109, 83, 47, 109, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 95, 49, 88, 72, 6, 109, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 50, 88, 71, 6, 37, 89, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 52, 88, 76, 6, 108, 107, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 53, 88, 48, 6, 37, 50, 75, 109, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 54, 88, 91, 6, 109, 89, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 56, 88, 107, 6, 109, 91, 47, 109, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 57, 88, 50, 109, 84, 6, 109, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 2, 95, 51, 89, 6, 108, 12, 107, 0, 0, 9, 2, 95, 50, 72, 6, 40, 12, 0, 0, 9, 2, 95, 49, 57, 6, 109, 49, 0, 0, 11, 2, 95, 48, 89, 108, 6, 83, 108, 34, 0, 0, 10, 2, 95, 55, 107, 6, 109, 83, 47, 0, 0, 9, 2, 95, 54, 91, 108, 6, 91, 0, 0, 10, 2, 95, 53, 48, 109, 6, 50, 75, 0, 0, 10, 2, 95, 52, 76, 6, 109, 107, 34, 0, 0, 0, 0, 8, 2, 95, 57, 50, 6, 39, 0, 0, 10, 2, 95, 56, 107, 6, 109, 91, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 217, 135, 107, 6, 108, 12, 72, 39, 76, 109, 91, 65, 0, 0, 9, 2, 217, 134, 50, 6, 40, 50, 0, 0, 9, 2, 217, 133, 65, 6, 37, 65, 0, 0, 9, 2, 217, 132, 55, 6, 109, 65, 0, 0, 0, 9, 2, 217, 130, 51, 6, 109, 83, 0, 0, 9, 2, 217, 129, 83, 6, 108, 12, 0, 0, 0, 0, 9, 2, 218, 134, 76, 6, 108, 12, 0, 0, 0, 0, 0, 0, 0, 10, 2, 217, 136, 58, 6, 39, 12, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 2, 216, 167, 109, 55, 6, 108, 83, 0, 0, 0, 0, 9, 2, 219, 140, 57, 6, 109, 12, 0, 0, 0, 0, 12, 2, 216, 161, 107, 109, 65, 88, 6, 108, 12, 0, 0, 0, 9, 2, 216, 175, 72, 6, 109, 55, 0, 0, 9, 2, 216, 174, 106, 6, 108, 12, 0, 0, 9, 2, 216, 173, 107, 6, 108, 12, 0, 0, 9, 2, 216, 172, 75, 6, 37, 65, 0, 0, 9, 2, 216, 171, 89, 6, 108, 12, 0, 0, 9, 2, 216, 170, 47, 6, 108, 12, 0, 0, 0, 9, 2, 216, 168, 71, 6, 108, 12, 0, 0, 9, 2, 216, 183, 47, 6, 109, 12, 0, 0, 9, 2, 216, 182, 88, 6, 109, 72, 0, 0, 9, 2, 216, 181, 89, 6, 109, 72, 0, 0, 9, 2, 216, 180, 91, 6, 37, 50, 0, 0, 9, 2, 216, 179, 89, 6, 37, 50, 0, 0, 9, 2, 216, 178, 88, 6, 108, 12, 0, 0, 9, 2, 216, 177, 34, 6, 108, 12, 0, 0, 9, 2, 216, 176, 88, 6, 109, 55, 0, 0, 9, 2, 218, 175, 81, 6, 109, 83, 0, 0, 0, 0, 0, 0, 9, 2, 216, 186, 51, 6, 110, 50, 0, 0, 9, 2, 218, 169, 49, 6, 109, 83, 0, 8, 2, 216, 185, 6, 110, 50, 0, 0, 9, 2, 216, 184, 88, 6, 109, 12, 0, 0, 0, 9, 2, 217, 190, 48, 6, 108, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 20, 0, 0, 96, 6, 0, 0, 48, 0, 0, 0, 97, 6, 0, 0, 49, 0, 0, 0, 98, 6, 0, 0, 50, 0, 0, 0, 99, 6, 0, 0, 51, 0, 0, 0, 100, 6, 0, 0, 52, 0, 0, 0, 101, 6, 0, 0, 53, 0, 0, 0, 102, 6, 0, 0, 54, 0, 0, 0, 103, 6, 0, 0, 55, 0, 0, 0, 104, 6, 0, 0, 56, 0, 0, 0, 105, 6, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 6, 18, 66, 217, 142, 0, 217, 144, 0, 217, 143, 0, 217, 139, 0, 217, 141, 0, 217, 136, 0, 216, 167, 0, 217, 135, 0, 219, 140, 0, 216, 169, 0, 217, 138, 0, 7, 6, 18, 67, 217, 142, 0, 217, 144, 0, 217, 143, 0, 7, 6, 18, 68, 216, 167, 0, 216, 168, 0, 217, 190, 0, 216, 170, 0, 216, 171, 0, 216, 172, 0, 218, 134, 0, 216, 173, 0, 216, 174, 0, 216, 175, 0, 216, 176, 0, 216, 177, 0, 216, 178, 0, 218, 152, 0, 216, 179, 0, 216, 180, 0, 216, 181, 0, 216, 182, 0, 216, 183, 0, 216, 184, 0, 216, 185, 0, 216, 186, 0, 217, 129, 0, 217, 130, 0, 218, 169, 0, 218, 175, 0, 217, 132, 0, 217, 133, 0, 217, 134, 0, 217, 136, 0, 217, 135, 0, 219, 140, 0, 7, 6, 1, 34, 0, 2, 18, 66, 3, 0, 3, 13, 0, 7, 6, 1, 35, 0, 3, 109, 0, 7, 6, 1, 40, 0, 8, 2, 18, 66, 3, 0, 217, 141, 3, 108, 50, 0, 4, 3, 109, 0, 2, 32, 0, 217, 139, 3, 109, 50, 0, 7, 6, 1, 41, 0, 4, 1, 18, 68, 2, 18, 68, 3, 71, 0, 2, 18, 66, 0, 2, 32, 0, 3, 71, 109, 0, 7, 6, 1, 42, 0, 2, 32, 3, 13, 0, 2, 18, 66, 3, 107, 0, 3, 107, 109, 0, 7, 6, 1, 43, 0, 4, 2, 18, 66, 3, 47, 0, 2, 32, 0, 3, 47, 109, 0, 7, 6, 1, 44, 0, 4, 2, 18, 66, 3, 89, 0, 2, 32, 0, 3, 89, 109, 0, 7, 6, 1, 45, 0, 4, 2, 18, 66, 3, 75, 0, 2, 32, 0, 3, 75, 109, 0, 7, 6, 1, 46, 0, 4, 2, 18, 66, 3, 107, 0, 2, 32, 0, 3, 107, 109, 0, 7, 6, 1, 47, 0, 4, 2, 18, 66, 3, 106, 0, 2, 32, 0, 3, 106, 109, 0, 7, 6, 1, 48, 0, 4, 2, 18, 66, 3, 72, 0, 2, 32, 0, 3, 72, 109, 0, 7, 6, 1, 49, 0, 4, 2, 18, 66, 3, 88, 0, 2, 32, 0, 3, 88, 109, 0, 7, 6, 1, 50, 0, 4, 2, 18, 66, 3, 51, 0, 2, 32, 0, 3, 51, 109, 0, 7, 6, 1, 51, 0, 4, 2, 18, 66, 3, 88, 0, 2, 32, 0, 3, 88, 109, 0, 7, 6, 1, 52, 0, 4, 1, 18, 67, 2, 18, 68, 3, 89, 0, 1, 18, 68, 2, 18, 68, 0, 2, 18, 66, 0, 2, 32, 0, 3, 89, 109, 0, 7, 6, 1, 53, 0, 4, 2, 18, 66, 3, 91, 0, 2, 32, 0, 3, 91, 109, 0, 7, 6, 1, 54, 0, 4, 2, 18, 66, 3, 89, 0, 2, 32, 0, 3, 89, 109, 0, 7, 6, 1, 55, 0, 4, 2, 18, 66, 3, 88, 0, 2, 32, 0, 3, 88, 109, 0, 7, 6, 1, 56, 0, 4, 2, 18, 66, 3, 47, 0, 2, 32, 0, 3, 47, 109, 0, 7, 6, 1, 57, 0, 4, 2, 18, 66, 3, 88, 0, 2, 32, 0, 3, 88, 109, 0, 7, 6, 1, 58, 0, 2, 18, 66, 3, 0, 2, 32, 3, 13, 9, 0, 3, 109, 0, 7, 6, 1, 59, 0, 4, 2, 18, 66, 3, 51, 0, 2, 32, 0, 3, 51, 109, 0, 7, 6, 1, 65, 0, 3, 0, 7, 6, 1, 66, 0, 4, 2, 18, 66, 3, 83, 0, 2, 32, 0, 3, 83, 109, 0, 7, 6, 1, 67, 0, 4, 2, 18, 66, 3, 51, 0, 2, 32, 0, 3, 51, 109, 0, 7, 6, 1, 69, 0, 4, 2, 18, 66, 3, 55, 0, 2, 32, 0, 3, 55, 109, 0, 7, 6, 1, 70, 0, 4, 2, 18, 66, 3, 65, 0, 2, 32, 0, 3, 65, 109, 0, 7, 6, 1, 71, 0, 4, 1, 18, 67, 2, 18, 68, 3, 50, 0, 1, 18, 68, 2, 18, 68, 0, 2, 18, 66, 0, 2, 32, 0, 3, 50, 109, 0, 7, 6, 1, 72, 0, 2, 32, 3, 13, 0, 2, 18, 66, 3, 107, 0, 3, 107, 109, 0, 7, 6, 1, 73, 0, 4, 1, 18, 68, 2, 18, 68, 3, 40, 0, 2, 32, 0, 2, 18, 66, 3, 84, 0, 3, 84, 109, 0, 7, 6, 1, 75, 0, 3, 37, 0, 8, 3, 57, 109, 0, 7, 6, 1, 79, 0, 3, 109, 0, 7, 6, 1, 80, 0, 3, 39, 0, 7, 6, 1, 81, 0, 3, 108, 0, 7, 6, 1, 82, 0, 3, 12, 0, 7, 6, 1, 127, 0, 4, 1, 18, 68, 2, 18, 68, 3, 48, 0, 2, 18, 66, 0, 2, 32, 0, 3, 48, 109, 0, 7, 6, 218, 134, 0, 4, 2, 18, 66, 3, 76, 0, 2, 32, 0, 3, 76, 109, 0, 7, 6, 218, 152, 0, 4, 2, 18, 66, 3, 90, 0, 2, 32, 0, 3, 90, 109, 0, 7, 6, 218, 169, 0, 4, 1, 18, 67, 2, 18, 68, 3, 49, 0, 1, 18, 68, 2, 18, 68, 0, 2, 18, 66, 0, 2, 32, 0, 3, 49, 109, 0, 7, 6, 218, 175, 0, 4, 2, 18, 66, 3, 81, 0, 2, 32, 0, 3, 81, 109, 0, 7, 6, 219, 140, 0, 3, 37, 0, 8, 3, 57, 109, 0, 7, 6, 0, 36, 3, 72, 39, 55, 13, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts51 = FileInMemory_createWithData (2569, reinterpret_cast (&espeakdata_dicts51_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/prs_dict", U"prs"); Collection_addItem (me.peek(), espeakdata_dicts51.transfer()); static unsigned char espeakdata_dicts52_data[18253] = { 0, 4, 0, 0, 160, 47, 0, 0, 22, 69, 16, 84, 15, 37, 48, 72, 36, 48, 6, 136, 89, 49, 135, 0, 102, 81, 113, 117, 101, 32, 0, 9, 198, 52, 20, 148, 20, 195, 192, 20, 0, 0, 0, 0, 9, 198, 77, 81, 197, 72, 83, 64, 20, 8, 197, 12, 244, 150, 61, 48, 20, 9, 198, 12, 130, 78, 20, 195, 192, 20, 10, 135, 3, 1, 2, 5, 195, 167, 1, 21, 18, 70, 28, 245, 133, 72, 227, 192, 81, 39, 84, 6, 36, 34, 50, 111, 0, 37, 6, 65, 4, 35, 0, 14, 9, 198, 12, 243, 148, 84, 67, 192, 102, 8, 65, 4, 132, 0, 101, 76, 34, 5, 193, 4, 76, 34, 0, 0, 18, 70, 32, 20, 132, 92, 20, 133, 107, 6, 35, 34, 72, 58, 36, 14, 0, 102, 19, 70, 32, 20, 132, 92, 20, 133, 6, 35, 34, 72, 4, 58, 6, 109, 44, 0, 101, 0, 12, 68, 37, 48, 65, 12, 37, 88, 6, 132, 49, 0, 7, 196, 52, 147, 136, 4, 76, 0, 0, 17, 70, 8, 16, 203, 85, 4, 192, 71, 109, 49, 6, 132, 48, 89, 0, 102, 0, 9, 67, 53, 82, 64, 65, 58, 37, 0, 6, 195, 21, 80, 64, 17, 16, 67, 21, 64, 192, 4, 36, 123, 6, 109, 47, 36, 16, 132, 0, 102, 16, 67, 21, 64, 192, 4, 36, 123, 6, 109, 47, 12, 16, 132, 0, 101, 0, 0, 0, 0, 6, 195, 69, 81, 64, 72, 13, 4, 95, 8, 1, 3, 49, 35, 16, 6, 39, 68, 0, 0, 11, 68, 28, 21, 83, 76, 81, 6, 114, 89, 0, 6, 195, 32, 242, 133, 21, 0, 0, 0, 10, 199, 21, 53, 1, 72, 83, 79, 76, 72, 0, 0, 8, 197, 52, 243, 133, 72, 16, 20, 6, 65, 20, 109, 0, 14, 7, 65, 20, 37, 0, 102, 72, 7, 65, 20, 37, 0, 101, 72, 0, 9, 198, 16, 80, 129, 37, 131, 192, 102, 0, 16, 4, 95, 48, 67, 15, 89, 118, 68, 47, 6, 109, 88, 37, 65, 0, 0, 0, 0, 0, 0, 7, 196, 56, 81, 210, 60, 21, 7, 196, 40, 241, 213, 20, 20, 0, 8, 197, 64, 84, 209, 84, 80, 20, 0, 0, 16, 4, 95, 51, 88, 15, 47, 51, 37, 90, 6, 109, 88, 37, 65, 0, 0, 0, 0, 10, 198, 21, 128, 71, 21, 35, 192, 20, 36, 0, 0, 0, 0, 14, 1, 37, 48, 39, 34, 89, 6, 118, 68, 47, 111, 0, 27, 0, 8, 1, 38, 10, 6, 36, 10, 0, 0, 0, 14, 73, 64, 192, 89, 77, 64, 84, 36, 243, 128, 21, 0, 10, 0, 0, 7, 195, 64, 244, 128, 102, 72, 6, 195, 64, 244, 128, 72, 15, 1, 42, 132, 89, 47, 36, 16, 6, 37, 89, 49, 111, 0, 27, 0, 15, 68, 52, 81, 9, 4, 65, 6, 109, 72, 4, 37, 132, 0, 101, 8, 1, 43, 65, 117, 138, 0, 27, 0, 17, 69, 92, 17, 206, 21, 32, 84, 6, 35, 81, 124, 50, 36, 34, 0, 103, 15, 69, 92, 17, 206, 21, 32, 84, 6, 35, 81, 50, 36, 34, 0, 0, 0, 11, 1, 46, 48, 6, 39, 68, 47, 111, 0, 27, 0, 0, 0, 0, 0, 0, 8, 197, 28, 19, 5, 72, 16, 20, 13, 138, 5, 19, 20, 195, 161, 22, 1, 13, 15, 19, 72, 0, 9, 198, 77, 84, 15, 73, 67, 192, 20, 10, 135, 195, 169, 18, 1, 13, 15, 19, 72, 0, 0, 11, 67, 52, 83, 149, 65, 36, 50, 40, 0, 101, 0, 11, 69, 24, 81, 15, 72, 16, 21, 0, 101, 10, 8, 197, 76, 84, 137, 4, 208, 72, 9, 5, 95, 48, 1, 14, 4, 37, 0, 0, 0, 0, 0, 6, 65, 60, 110, 0, 14, 5, 193, 60, 76, 34, 0, 14, 1, 61, 10, 10, 37, 81, 58, 6, 132, 55, 10, 0, 27, 0, 0, 0, 6, 195, 69, 81, 82, 102, 10, 1, 64, 132, 101, 6, 39, 71, 132, 0, 0, 17, 70, 32, 19, 9, 76, 243, 128, 132, 55, 6, 37, 89, 132, 68, 0, 101, 0, 0, 6, 195, 16, 240, 197, 21, 0, 0, 0, 11, 67, 16, 240, 192, 72, 6, 110, 49, 0, 101, 0, 7, 196, 69, 81, 68, 4, 20, 0, 15, 69, 16, 80, 137, 4, 224, 72, 6, 109, 71, 57, 129, 68, 0, 0, 9, 198, 4, 193, 133, 72, 84, 192, 20, 0, 0, 0, 14, 69, 65, 149, 8, 60, 224, 48, 6, 117, 87, 129, 68, 0, 0, 14, 68, 77, 0, 67, 20, 89, 48, 6, 118, 89, 112, 0, 101, 0, 0, 6, 195, 80, 241, 193, 20, 0, 0, 11, 67, 48, 240, 203, 55, 6, 110, 49, 0, 101, 9, 198, 21, 53, 18, 60, 97, 64, 20, 0, 0, 24, 72, 21, 52, 5, 4, 177, 68, 37, 64, 37, 89, 48, 6, 37, 12, 49, 109, 72, 4, 37, 47, 0, 101, 7, 196, 13, 33, 68, 20, 21, 0, 16, 69, 92, 147, 132, 61, 112, 58, 6, 37, 68, 72, 39, 58, 0, 102, 17, 69, 92, 147, 132, 61, 112, 58, 6, 37, 68, 72, 6, 39, 40, 0, 101, 8, 197, 28, 83, 5, 36, 16, 20, 8, 197, 13, 33, 83, 12, 80, 20, 8, 197, 8, 243, 5, 36, 16, 20, 0, 8, 66, 85, 0, 132, 48, 0, 101, 0, 16, 4, 95, 49, 67, 15, 89, 118, 68, 47, 6, 109, 88, 37, 65, 0, 0, 21, 72, 61, 1, 78, 60, 97, 137, 12, 80, 6, 39, 48, 118, 68, 6, 110, 83, 37, 89, 0, 0, 6, 65, 88, 84, 36, 0, 0, 6, 194, 5, 48, 76, 34, 0, 0, 8, 196, 52, 243, 8, 60, 21, 37, 17, 4, 95, 49, 77, 52, 6, 128, 50, 47, 34, 37, 55, 57, 6, 130, 0, 0, 15, 69, 72, 243, 131, 32, 144, 34, 6, 110, 50, 99, 37, 12, 0, 8, 197, 52, 147, 136, 5, 48, 76, 0, 0, 0, 11, 200, 52, 19, 148, 37, 97, 82, 21, 48, 20, 0, 12, 4, 95, 49, 77, 49, 65, 6, 116, 10, 0, 102, 13, 4, 95, 49, 77, 49, 65, 6, 37, 55, 10, 0, 101, 7, 65, 96, 91, 37, 138, 0, 0, 6, 195, 84, 229, 19, 17, 15, 4, 95, 49, 77, 50, 6, 128, 65, 37, 55, 57, 6, 130, 0, 0, 16, 4, 95, 49, 77, 51, 6, 128, 65, 71, 37, 55, 57, 6, 130, 0, 0, 12, 68, 77, 1, 65, 44, 89, 48, 37, 12, 49, 0, 7, 196, 64, 83, 15, 76, 72, 0, 13, 67, 16, 245, 206, 72, 6, 35, 4, 58, 50, 0, 101, 0, 0, 11, 67, 100, 84, 192, 57, 6, 109, 89, 0, 101, 6, 195, 16, 244, 192, 72, 6, 195, 48, 244, 192, 72, 0, 12, 137, 20, 9, 22, 195, 169, 18, 5, 9, 19, 72, 0, 0, 0, 10, 199, 64, 241, 5, 72, 83, 79, 76, 76, 0, 0, 0, 9, 198, 4, 193, 213, 52, 20, 192, 72, 6, 195, 12, 20, 207, 102, 0, 0, 6, 195, 64, 244, 197, 21, 7, 196, 80, 83, 136, 60, 72, 0, 0, 9, 198, 56, 20, 85, 20, 193, 64, 21, 18, 70, 16, 20, 85, 20, 193, 64, 72, 132, 49, 6, 36, 55, 112, 0, 76, 34, 5, 194, 4, 80, 17, 0, 0, 0, 0, 12, 67, 48, 241, 207, 55, 6, 110, 81, 111, 0, 102, 19, 67, 48, 241, 207, 55, 6, 110, 81, 40, 49, 135, 0, 102, 81, 113, 117, 101, 32, 0, 0, 0, 0, 0, 0, 15, 68, 21, 128, 197, 48, 4, 109, 49, 89, 6, 109, 55, 0, 101, 14, 68, 25, 32, 77, 20, 83, 51, 6, 118, 65, 37, 0, 102, 14, 68, 25, 32, 77, 20, 83, 34, 6, 118, 65, 112, 0, 101, 0, 9, 198, 64, 244, 148, 4, 229, 15, 102, 0, 0, 14, 67, 84, 226, 88, 57, 6, 40, 50, 37, 49, 89, 0, 102, 15, 67, 84, 226, 88, 4, 40, 12, 50, 6, 37, 49, 89, 0, 101, 0, 7, 196, 76, 240, 133, 52, 20, 0, 16, 69, 64, 147, 210, 21, 48, 48, 37, 6, 110, 16, 37, 89, 0, 102, 0, 10, 198, 20, 212, 18, 20, 115, 192, 21, 37, 9, 198, 12, 128, 77, 20, 115, 192, 21, 0, 0, 0, 0, 0, 7, 195, 77, 32, 64, 102, 24, 18, 67, 77, 32, 64, 4, 109, 95, 6, 109, 34, 34, 57, 6, 35, 0, 101, 24, 0, 7, 196, 64, 241, 5, 72, 76, 7, 196, 80, 147, 136, 4, 72, 0, 0, 19, 70, 21, 132, 18, 21, 52, 192, 4, 109, 49, 89, 48, 34, 6, 109, 89, 0, 101, 9, 198, 16, 84, 195, 61, 96, 64, 21, 0, 9, 198, 20, 229, 77, 21, 33, 77, 20, 0, 6, 195, 72, 81, 5, 21, 0, 0, 0, 9, 198, 21, 66, 81, 84, 85, 1, 21, 0, 11, 4, 95, 49, 67, 48, 89, 6, 118, 68, 0, 0, 10, 198, 72, 81, 146, 21, 48, 207, 20, 36, 0, 6, 194, 16, 16, 72, 34, 0, 0, 0, 8, 197, 21, 53, 9, 88, 80, 72, 0, 7, 195, 104, 83, 15, 20, 36, 0, 11, 67, 16, 21, 0, 72, 6, 35, 47, 0, 101, 9, 198, 81, 32, 81, 84, 82, 65, 20, 18, 4, 95, 50, 67, 15, 72, 40, 89, 118, 68, 47, 6, 109, 88, 37, 65, 0, 0, 7, 196, 104, 244, 146, 4, 21, 0, 0, 0, 0, 7, 196, 64, 241, 5, 52, 76, 0, 0, 19, 70, 36, 229, 18, 4, 225, 84, 37, 68, 47, 51, 35, 50, 6, 109, 47, 0, 102, 0, 0, 11, 67, 56, 83, 5, 50, 36, 55, 112, 0, 77, 0, 8, 197, 21, 53, 1, 37, 48, 72, 0, 9, 198, 72, 83, 79, 73, 51, 192, 20, 0, 0, 13, 68, 100, 18, 15, 60, 37, 35, 107, 6, 40, 0, 102, 15, 68, 100, 18, 15, 60, 6, 37, 4, 35, 107, 6, 40, 0, 101, 7, 196, 5, 1, 71, 60, 21, 0, 0, 10, 198, 76, 83, 136, 61, 32, 64, 101, 21, 9, 198, 12, 19, 148, 61, 32, 64, 21, 6, 195, 8, 83, 15, 20, 0, 13, 67, 56, 86, 20, 50, 6, 109, 49, 89, 47, 0, 101, 0, 7, 196, 24, 80, 146, 20, 20, 0, 12, 201, 21, 52, 9, 72, 244, 85, 21, 64, 64, 21, 0, 9, 198, 76, 147, 131, 21, 32, 64, 20, 5, 194, 17, 32, 24, 0, 0, 13, 68, 56, 84, 211, 20, 50, 6, 36, 89, 112, 0, 76, 0, 15, 69, 32, 149, 12, 21, 32, 107, 6, 37, 47, 55, 36, 34, 0, 16, 69, 72, 80, 68, 21, 32, 34, 6, 37, 72, 4, 132, 44, 0, 101, 0, 0, 0, 0, 0, 0, 0, 7, 196, 29, 33, 71, 60, 21, 16, 68, 56, 84, 212, 20, 50, 6, 36, 89, 76, 37, 0, 102, 76, 34, 0, 0, 6, 195, 52, 241, 15, 20, 0, 10, 199, 64, 17, 5, 12, 84, 212, 20, 21, 0, 0, 16, 69, 36, 229, 133, 40, 16, 37, 68, 84, 6, 109, 90, 132, 0, 102, 0, 0, 0, 6, 131, 8, 195, 161, 76, 20, 68, 76, 19, 22, 60, 89, 6, 35, 55, 84, 40, 89, 135, 0, 102, 81, 115, 101, 32, 14, 68, 56, 244, 211, 4, 50, 6, 110, 89, 132, 0, 102, 76, 0, 0, 0, 0, 10, 135, 5, 24, 16, 5, 195, 167, 1, 21, 0, 0, 0, 0, 14, 68, 52, 83, 143, 72, 65, 36, 50, 6, 110, 34, 0, 102, 14, 68, 52, 83, 143, 72, 65, 112, 50, 6, 110, 44, 0, 101, 0, 0, 0, 9, 198, 12, 16, 200, 61, 36, 129, 21, 0, 7, 196, 12, 241, 146, 20, 20, 0, 0, 19, 70, 16, 245, 206, 48, 240, 68, 72, 35, 128, 68, 55, 6, 39, 58, 72, 0, 103, 18, 70, 16, 245, 206, 48, 240, 68, 72, 114, 68, 55, 6, 39, 58, 72, 0, 102, 21, 70, 16, 245, 206, 48, 240, 68, 72, 6, 35, 4, 58, 50, 55, 6, 39, 40, 72, 0, 101, 0, 0, 15, 68, 48, 147, 149, 96, 55, 6, 37, 50, 111, 49, 89, 0, 102, 16, 68, 48, 147, 149, 96, 55, 4, 37, 50, 6, 40, 49, 89, 0, 101, 0, 0, 15, 70, 8, 16, 130, 4, 113, 64, 71, 6, 35, 71, 37, 75, 0, 10, 135, 5, 24, 16, 5, 195, 167, 15, 21, 0, 0, 7, 196, 5, 1, 68, 88, 17, 0, 0, 5, 194, 16, 80, 72, 0, 0, 0, 0, 0, 9, 198, 60, 66, 83, 76, 82, 65, 20, 19, 4, 95, 51, 67, 15, 47, 51, 37, 89, 118, 68, 47, 6, 109, 88, 37, 65, 0, 0, 17, 70, 32, 245, 13, 4, 147, 0, 107, 39, 47, 65, 6, 118, 55, 0, 102, 18, 70, 32, 245, 13, 4, 147, 0, 107, 6, 110, 47, 65, 6, 118, 55, 0, 101, 16, 4, 95, 4, 16, 20, 10, 84, 6, 37, 34, 81, 40, 55, 132, 0, 0, 0, 0, 0, 7, 196, 24, 243, 7, 4, 20, 0, 0, 9, 198, 21, 48, 210, 61, 67, 192, 21, 0, 0, 12, 67, 80, 147, 69, 47, 6, 117, 65, 112, 0, 101, 11, 200, 21, 53, 9, 88, 84, 132, 21, 48, 20, 7, 196, 17, 35, 199, 4, 20, 0, 8, 197, 64, 244, 131, 61, 48, 20, 0, 0, 0, 9, 3, 95, 35, 57, 47, 35, 71, 0, 11, 4, 95, 20, 12, 4, 47, 37, 55, 0, 101, 10, 4, 95, 20, 12, 4, 76, 6, 116, 0, 0, 0, 6, 195, 20, 68, 0, 17, 0, 19, 71, 48, 21, 143, 37, 50, 69, 72, 55, 35, 84, 58, 35, 88, 57, 6, 36, 0, 11, 67, 4, 197, 0, 6, 35, 55, 47, 0, 101, 10, 199, 12, 20, 129, 13, 65, 82, 20, 20, 10, 199, 12, 17, 5, 72, 225, 84, 4, 21, 7, 195, 84, 228, 192, 72, 34, 0, 0, 0, 25, 12, 19, 3, 8, 18, 195, 182, 4, 9, 14, 7, 5, 18, 91, 34, 6, 36, 72, 37, 50, 81, 36, 34, 0, 9, 198, 21, 52, 5, 72, 208, 64, 20, 0, 0, 0, 15, 69, 64, 192, 89, 21, 32, 48, 55, 6, 118, 132, 44, 0, 101, 0, 0, 11, 136, 1, 4, 5, 18, 5, 195, 167, 15, 21, 0, 14, 68, 64, 21, 83, 20, 48, 6, 35, 40, 12, 88, 0, 101, 13, 137, 18, 5, 3, 15, 13, 5, 195, 167, 15, 21, 37, 8, 196, 16, 240, 146, 60, 21, 37, 0, 0, 0, 0, 8, 196, 56, 244, 211, 60, 102, 76, 0, 8, 197, 64, 83, 5, 28, 240, 21, 8, 197, 52, 19, 5, 80, 16, 21, 0, 9, 198, 21, 53, 1, 72, 82, 64, 72, 0, 9, 198, 12, 81, 129, 48, 82, 65, 20, 0, 11, 68, 48, 245, 73, 76, 21, 102, 114, 0, 10, 0, 8, 197, 76, 244, 18, 20, 208, 20, 9, 197, 21, 52, 5, 80, 240, 21, 37, 8, 197, 80, 147, 136, 4, 208, 72, 0, 17, 7, 1, 12, 13, 15, 195, 167, 15, 114, 65, 6, 110, 89, 111, 0, 36, 6, 194, 21, 80, 76, 32, 0, 0, 0, 9, 134, 16, 18, 5, 195, 167, 15, 21, 8, 197, 4, 193, 213, 57, 48, 72, 0, 10, 135, 1, 16, 18, 5, 195, 167, 15, 21, 9, 198, 80, 149, 133, 72, 19, 64, 72, 9, 198, 80, 149, 133, 72, 19, 64, 72, 0, 0, 12, 68, 25, 33, 85, 16, 83, 34, 6, 136, 72, 0, 18, 70, 20, 147, 147, 80, 82, 78, 11, 6, 117, 50, 91, 47, 4, 117, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 67, 80, 16, 128, 47, 6, 35, 71, 0, 101, 6, 195, 5, 96, 192, 17, 0, 7, 196, 52, 244, 132, 4, 21, 7, 196, 48, 84, 132, 4, 20, 7, 196, 28, 244, 132, 4, 21, 7, 196, 57, 83, 65, 76, 72, 0, 16, 69, 76, 52, 143, 48, 192, 89, 49, 12, 34, 6, 39, 55, 0, 101, 0, 0, 9, 67, 61, 33, 192, 110, 34, 81, 0, 0, 0, 0, 0, 10, 199, 21, 52, 85, 20, 193, 84, 60, 21, 0, 13, 68, 52, 245, 83, 20, 65, 6, 114, 88, 37, 0, 102, 0, 0, 5, 194, 4, 240, 72, 0, 6, 195, 25, 82, 64, 72, 6, 195, 61, 50, 64, 17, 0, 7, 196, 64, 244, 211, 60, 76, 0, 15, 69, 21, 52, 5, 4, 176, 37, 89, 48, 6, 37, 12, 49, 0, 8, 197, 20, 208, 143, 72, 16, 102, 22, 4, 95, 52, 67, 15, 49, 58, 35, 72, 16, 37, 90, 118, 68, 47, 6, 109, 88, 37, 65, 0, 0, 17, 70, 48, 82, 66, 56, 150, 128, 55, 6, 117, 71, 50, 37, 12, 123, 0, 0, 0, 0, 9, 198, 9, 35, 205, 20, 194, 1, 20, 8, 197, 80, 149, 133, 72, 16, 72, 0, 19, 70, 72, 146, 142, 16, 17, 76, 101, 6, 35, 37, 50, 38, 72, 6, 35, 55, 0, 6, 195, 57, 83, 65, 72, 16, 5, 95, 48, 77, 49, 15, 65, 37, 55, 6, 109, 88, 37, 65, 0, 0, 6, 195, 57, 83, 64, 72, 0, 7, 196, 25, 33, 86, 60, 21, 12, 67, 60, 194, 15, 6, 39, 61, 111, 0, 104, 37, 13, 67, 60, 194, 15, 6, 39, 55, 57, 111, 0, 102, 37, 0, 19, 4, 95, 55, 88, 15, 89, 36, 48, 47, 58, 35, 90, 6, 109, 88, 37, 65, 0, 0, 12, 67, 48, 147, 133, 55, 6, 35, 37, 50, 0, 101, 9, 198, 64, 84, 209, 84, 83, 64, 20, 18, 70, 72, 85, 15, 72, 227, 192, 101, 36, 47, 6, 110, 34, 50, 111, 0, 36, 0, 0, 6, 195, 17, 3, 195, 17, 0, 0, 17, 70, 77, 65, 80, 32, 83, 128, 89, 47, 6, 37, 12, 84, 13, 50, 0, 13, 66, 16, 160, 72, 4, 37, 12, 75, 6, 118, 0, 101, 6, 195, 24, 84, 129, 20, 19, 67, 64, 20, 129, 48, 4, 35, 16, 132, 49, 135, 0, 102, 81, 113, 117, 101, 32, 6, 195, 64, 20, 129, 72, 0, 0, 0, 16, 70, 88, 243, 20, 4, 148, 133, 84, 110, 55, 47, 6, 109, 34, 0, 16, 69, 85, 3, 15, 4, 64, 132, 48, 55, 6, 39, 40, 72, 0, 101, 18, 70, 76, 241, 148, 92, 20, 133, 89, 6, 110, 83, 47, 58, 36, 14, 0, 102, 20, 70, 76, 241, 148, 92, 20, 133, 89, 6, 110, 83, 47, 4, 58, 6, 109, 44, 0, 101, 17, 69, 12, 19, 131, 20, 192, 49, 6, 132, 50, 89, 6, 109, 55, 0, 101, 9, 198, 4, 194, 67, 21, 32, 197, 20, 0, 17, 70, 8, 84, 142, 32, 20, 132, 71, 36, 34, 50, 6, 35, 34, 72, 0, 6, 195, 24, 84, 133, 20, 0, 0, 7, 196, 17, 83, 65, 76, 72, 0, 0, 18, 70, 21, 53, 9, 88, 84, 128, 36, 89, 76, 37, 84, 6, 109, 34, 0, 72, 0, 0, 0, 0, 12, 67, 48, 149, 133, 55, 6, 35, 37, 84, 0, 101, 6, 195, 80, 149, 133, 72, 0, 6, 195, 32, 149, 128, 17, 0, 12, 67, 56, 84, 143, 50, 6, 109, 34, 40, 0, 101, 7, 196, 80, 84, 133, 36, 72, 7, 196, 76, 84, 133, 36, 72, 0, 11, 136, 6, 195, 180, 13, 1, 13, 15, 19, 72, 0, 0, 0, 15, 68, 64, 83, 1, 76, 48, 6, 36, 55, 132, 89, 0, 102, 72, 7, 196, 16, 83, 5, 76, 76, 0, 9, 198, 29, 35, 211, 20, 194, 1, 20, 9, 197, 4, 49, 82, 80, 240, 21, 37, 0, 0, 0, 8, 196, 81, 35, 195, 60, 21, 37, 0, 9, 197, 4, 35, 210, 80, 240, 20, 36, 0, 0, 0, 0, 8, 197, 64, 244, 148, 61, 48, 20, 0, 0, 20, 70, 77, 3, 210, 80, 147, 135, 89, 48, 6, 110, 34, 47, 4, 37, 50, 81, 0, 101, 0, 7, 196, 24, 244, 131, 4, 21, 8, 196, 12, 84, 131, 4, 20, 36, 12, 137, 1, 14, 15, 9, 20, 5, 195, 167, 1, 21, 0, 11, 136, 20, 195, 173, 14, 8, 5, 9, 19, 72, 0, 9, 198, 76, 147, 131, 21, 35, 192, 20, 10, 135, 5, 19, 20, 1, 18, 195, 161, 72, 0, 0, 14, 68, 20, 197, 15, 56, 6, 109, 55, 47, 132, 68, 0, 101, 10, 135, 6, 195, 180, 18, 5, 9, 19, 72, 0, 0, 17, 70, 52, 18, 79, 72, 84, 192, 65, 117, 6, 110, 16, 37, 89, 0, 102, 9, 198, 5, 68, 143, 104, 84, 192, 20, 0, 0, 27, 11, 20, 5, 12, 5, 13, 195, 179, 22, 5, 9, 19, 47, 4, 109, 55, 4, 109, 65, 6, 110, 84, 118, 138, 0, 101, 8, 196, 5, 3, 201, 60, 20, 36, 13, 3, 95, 49, 15, 48, 51, 37, 65, 6, 118, 16, 0, 0, 0, 6, 195, 57, 97, 1, 17, 0, 10, 199, 21, 53, 9, 88, 84, 133, 76, 20, 10, 3, 226, 130, 172, 6, 115, 16, 111, 0, 0, 6, 195, 8, 80, 207, 21, 6, 195, 57, 83, 147, 72, 0, 0, 10, 67, 64, 17, 197, 48, 6, 118, 75, 0, 12, 137, 1, 14, 15, 9, 20, 5, 195, 167, 15, 21, 0, 0, 7, 196, 48, 84, 132, 60, 20, 13, 3, 95, 50, 15, 89, 36, 81, 6, 128, 68, 72, 0, 0, 12, 67, 64, 147, 210, 48, 37, 6, 110, 34, 0, 102, 0, 12, 137, 20, 195, 173, 14, 8, 1, 13, 15, 19, 72, 0, 0, 7, 196, 16, 83, 1, 76, 76, 20, 6, 16, 18, 15, 6, 194, 170, 48, 51, 4, 39, 83, 36, 89, 6, 39, 16, 132, 0, 0, 8, 197, 64, 244, 145, 84, 80, 102, 19, 4, 95, 53, 67, 15, 49, 37, 68, 90, 118, 68, 47, 6, 109, 88, 37, 65, 0, 0, 0, 0, 7, 196, 64, 84, 132, 20, 20, 11, 200, 12, 243, 136, 20, 49, 83, 80, 80, 21, 14, 3, 95, 51, 15, 47, 36, 16, 14, 89, 6, 118, 16, 0, 8, 4, 95, 15, 18, 4, 39, 0, 0, 0, 0, 0, 6, 195, 104, 84, 143, 20, 0, 0, 0, 0, 7, 196, 88, 84, 130, 60, 20, 8, 196, 29, 35, 218, 60, 20, 36, 7, 196, 24, 84, 133, 52, 20, 0, 0, 0, 10, 199, 21, 53, 9, 88, 84, 129, 52, 72, 6, 195, 4, 244, 192, 72, 0, 7, 196, 48, 244, 5, 76, 20, 0, 0, 9, 198, 12, 243, 69, 72, 84, 192, 21, 0, 6, 195, 16, 20, 192, 72, 6, 195, 48, 20, 192, 72, 0, 11, 3, 95, 53, 15, 49, 6, 37, 68, 47, 0, 0, 16, 69, 56, 83, 19, 60, 224, 50, 6, 109, 55, 89, 132, 68, 0, 101, 0, 14, 4, 95, 13, 3, 14, 65, 35, 49, 51, 6, 39, 68, 0, 0, 0, 0, 12, 201, 52, 19, 148, 37, 97, 82, 16, 84, 192, 20, 0, 0, 0, 7, 196, 76, 84, 137, 4, 72, 11, 3, 95, 54, 15, 89, 6, 36, 89, 47, 0, 0, 0, 17, 70, 9, 32, 73, 48, 193, 64, 71, 51, 6, 35, 37, 55, 37, 0, 102, 18, 70, 9, 32, 73, 48, 193, 64, 71, 12, 34, 6, 35, 37, 55, 112, 0, 101, 5, 194, 20, 208, 72, 6, 194, 16, 240, 72, 34, 0, 0, 0, 8, 197, 52, 244, 133, 36, 16, 20, 0, 0, 0, 7, 196, 24, 244, 133, 76, 21, 8, 196, 12, 84, 131, 60, 20, 36, 12, 3, 95, 55, 15, 89, 6, 109, 76, 37, 65, 0, 0, 0, 0, 0, 0, 8, 197, 4, 211, 210, 21, 48, 21, 0, 0, 0, 7, 196, 8, 244, 132, 60, 20, 11, 200, 4, 192, 129, 81, 35, 218, 21, 48, 20, 12, 68, 24, 244, 129, 52, 83, 39, 16, 130, 0, 73, 0, 11, 67, 20, 225, 0, 6, 36, 50, 72, 0, 101, 0, 0, 6, 195, 65, 32, 64, 72, 13, 3, 95, 51, 88, 47, 51, 6, 37, 68, 47, 132, 0, 0, 7, 195, 76, 83, 15, 20, 36, 19, 6, 16, 18, 15, 6, 194, 186, 48, 51, 4, 39, 83, 36, 89, 6, 39, 34, 0, 14, 3, 95, 48, 67, 89, 6, 118, 68, 47, 111, 138, 0, 102, 14, 3, 95, 48, 67, 89, 6, 118, 68, 47, 40, 138, 0, 101, 0, 0, 0, 21, 71, 12, 193, 86, 21, 36, 207, 56, 49, 55, 6, 109, 84, 36, 34, 89, 39, 68, 0, 102, 21, 71, 12, 193, 86, 21, 36, 207, 56, 49, 55, 6, 109, 84, 112, 34, 89, 132, 68, 0, 101, 6, 195, 17, 32, 64, 24, 0, 8, 196, 76, 240, 146, 20, 101, 21, 14, 68, 76, 240, 146, 20, 89, 6, 39, 71, 51, 112, 0, 102, 10, 3, 95, 57, 15, 50, 6, 39, 50, 0, 0, 17, 69, 16, 84, 201, 28, 224, 72, 4, 37, 88, 6, 35, 37, 50, 0, 101, 0, 0, 18, 71, 76, 192, 67, 45, 112, 82, 20, 89, 55, 6, 35, 49, 58, 36, 14, 0, 7, 132, 20, 195, 170, 13, 72, 0, 13, 67, 53, 1, 71, 4, 109, 65, 48, 6, 109, 81, 0, 12, 3, 95, 49, 67, 89, 6, 118, 68, 47, 40, 0, 0, 9, 198, 21, 48, 207, 64, 85, 1, 21, 0, 0, 10, 199, 76, 80, 143, 73, 33, 73, 4, 20, 0, 0, 0, 9, 198, 12, 20, 197, 9, 33, 64, 20, 5, 194, 48, 16, 72, 8, 4, 95, 35, 194, 170, 132, 0, 16, 3, 95, 49, 57, 72, 36, 88, 36, 50, 6, 110, 84, 112, 0, 102, 16, 3, 95, 49, 57, 72, 112, 88, 132, 50, 6, 110, 84, 112, 0, 101, 0, 14, 3, 95, 49, 56, 72, 36, 88, 6, 120, 47, 40, 0, 102, 15, 3, 95, 49, 56, 72, 112, 88, 6, 110, 37, 47, 40, 0, 101, 0, 16, 3, 95, 50, 67, 72, 40, 88, 6, 118, 68, 47, 111, 88, 0, 102, 16, 3, 95, 50, 67, 72, 40, 88, 6, 118, 68, 47, 40, 138, 0, 101, 0, 8, 197, 40, 241, 213, 20, 208, 20, 18, 4, 95, 54, 67, 15, 89, 118, 89, 118, 68, 47, 6, 109, 88, 37, 65, 0, 0, 0, 0, 7, 195, 28, 83, 15, 20, 36, 6, 195, 8, 243, 15, 21, 0, 8, 197, 29, 35, 211, 76, 240, 21, 16, 69, 21, 53, 5, 88, 80, 36, 89, 47, 36, 84, 112, 0, 102, 74, 0, 11, 3, 95, 49, 49, 6, 39, 68, 88, 112, 0, 0, 10, 3, 95, 49, 48, 72, 6, 109, 138, 0, 0, 7, 196, 5, 52, 201, 52, 102, 17, 3, 95, 51, 67, 47, 51, 36, 88, 6, 36, 68, 47, 111, 88, 0, 102, 17, 3, 95, 51, 67, 47, 34, 112, 88, 6, 36, 68, 47, 40, 138, 0, 101, 13, 3, 95, 49, 51, 47, 51, 6, 36, 88, 37, 0, 102, 13, 3, 95, 49, 51, 47, 34, 6, 36, 88, 112, 0, 101, 0, 8, 197, 80, 84, 133, 37, 48, 72, 8, 197, 76, 84, 133, 37, 48, 72, 13, 4, 95, 49, 88, 15, 72, 6, 109, 89, 37, 65, 0, 11, 3, 95, 49, 50, 72, 6, 39, 88, 112, 0, 0, 12, 3, 95, 49, 53, 49, 6, 37, 68, 88, 112, 0, 0, 15, 3, 95, 49, 52, 49, 35, 47, 6, 39, 34, 88, 112, 0, 102, 15, 3, 95, 49, 52, 49, 132, 47, 6, 39, 34, 88, 112, 0, 101, 0, 6, 195, 4, 145, 19, 17, 13, 3, 95, 52, 15, 49, 58, 6, 35, 16, 14, 47, 0, 17, 3, 95, 49, 55, 72, 4, 36, 88, 36, 89, 6, 109, 76, 112, 0, 102, 16, 3, 95, 49, 55, 72, 112, 88, 132, 89, 6, 109, 47, 112, 0, 101, 0, 16, 3, 95, 49, 54, 72, 4, 36, 88, 36, 89, 6, 118, 138, 0, 102, 16, 3, 95, 49, 54, 72, 112, 88, 132, 89, 6, 36, 37, 138, 0, 101, 0, 8, 4, 95, 35, 194, 186, 111, 0, 0, 15, 3, 95, 55, 88, 89, 36, 47, 6, 118, 68, 47, 132, 0, 102, 15, 3, 95, 55, 88, 89, 112, 47, 6, 118, 68, 47, 132, 0, 101, 0, 7, 196, 80, 149, 133, 72, 20, 0, 0, 9, 198, 64, 148, 149, 21, 64, 64, 21, 9, 198, 4, 193, 207, 104, 84, 192, 20, 0, 0, 0, 0, 9, 198, 13, 32, 84, 21, 32, 64, 20, 9, 198, 5, 84, 212, 21, 32, 64, 20, 0, 0, 7, 196, 64, 241, 9, 4, 76, 16, 3, 95, 53, 67, 49, 37, 67, 6, 118, 68, 47, 111, 88, 0, 102, 16, 3, 95, 53, 67, 49, 37, 67, 6, 118, 68, 47, 40, 138, 0, 101, 0, 0, 0, 0, 6, 195, 61, 52, 207, 21, 0, 14, 69, 48, 22, 79, 85, 64, 55, 6, 118, 4, 114, 47, 0, 16, 69, 12, 243, 8, 21, 32, 49, 39, 61, 6, 109, 34, 0, 104, 37, 17, 69, 12, 243, 8, 21, 32, 49, 39, 55, 57, 6, 109, 34, 0, 102, 37, 0, 9, 198, 72, 84, 207, 49, 97, 64, 20, 12, 137, 16, 15, 4, 195, 173, 1, 13, 15, 19, 76, 0, 13, 138, 20, 9, 22, 195, 169, 18, 1, 13, 15, 19, 72, 6, 195, 52, 19, 0, 102, 6, 195, 4, 20, 16, 17, 0, 6, 195, 65, 32, 83, 72, 11, 3, 1, 46, 3, 6, 35, 89, 6, 36, 0, 0, 9, 198, 72, 84, 207, 49, 97, 77, 20, 0, 12, 137, 19, 5, 18, 195, 173, 1, 13, 15, 19, 72, 0, 21, 71, 44, 193, 86, 21, 36, 207, 56, 49, 55, 6, 109, 84, 36, 34, 89, 132, 68, 0, 101, 8, 132, 1, 20, 195, 169, 102, 72, 0, 11, 200, 5, 4, 133, 56, 65, 83, 80, 80, 21, 21, 68, 4, 229, 5, 76, 6, 129, 68, 76, 37, 89, 49, 135, 0, 102, 81, 113, 117, 101, 32, 0, 9, 198, 12, 245, 66, 21, 33, 77, 20, 21, 69, 21, 128, 197, 80, 240, 36, 89, 6, 109, 47, 40, 89, 135, 0, 102, 81, 115, 101, 32, 0, 0, 13, 3, 95, 50, 88, 84, 6, 37, 68, 76, 112, 0, 102, 13, 3, 95, 50, 88, 84, 6, 37, 68, 47, 112, 0, 101, 0, 0, 0, 16, 70, 72, 145, 77, 4, 227, 128, 34, 6, 37, 12, 65, 35, 50, 0, 0, 9, 198, 12, 245, 66, 21, 33, 83, 20, 0, 11, 3, 95, 56, 15, 120, 47, 6, 35, 84, 0, 0, 8, 197, 5, 1, 78, 5, 48, 102, 17, 69, 56, 84, 212, 21, 48, 50, 6, 36, 89, 76, 37, 89, 0, 102, 76, 0, 0, 19, 71, 25, 34, 69, 17, 34, 67, 32, 83, 34, 6, 37, 12, 72, 34, 37, 91, 0, 0, 14, 68, 25, 35, 206, 80, 83, 34, 6, 39, 50, 47, 0, 101, 7, 196, 24, 22, 133, 72, 76, 0, 0, 0, 0, 7, 196, 76, 241, 146, 20, 20, 15, 3, 95, 63, 63, 89, 6, 37, 65, 71, 39, 55, 111, 10, 0, 0, 11, 4, 14, 195, 163, 15, 50, 4, 130, 0, 11, 0, 5, 194, 53, 32, 24, 0, 14, 5, 22, 15, 3, 195, 170, 84, 39, 89, 6, 36, 0, 76, 16, 3, 95, 52, 88, 49, 58, 35, 16, 6, 118, 68, 47, 132, 0, 102, 16, 3, 95, 52, 88, 49, 58, 132, 16, 6, 36, 68, 47, 132, 0, 101, 0, 0, 0, 0, 0, 8, 196, 24, 244, 146, 60, 20, 36, 0, 0, 5, 194, 56, 16, 72, 0, 16, 3, 95, 53, 88, 89, 37, 68, 49, 58, 6, 118, 68, 47, 132, 0, 0, 7, 196, 64, 81, 18, 4, 20, 0, 9, 197, 20, 228, 133, 16, 240, 20, 36, 21, 4, 95, 55, 67, 15, 89, 36, 48, 76, 37, 90, 118, 68, 47, 6, 109, 88, 37, 65, 0, 0, 0, 6, 195, 24, 242, 64, 72, 0, 0, 15, 69, 60, 97, 137, 12, 80, 6, 110, 83, 4, 37, 89, 0, 101, 9, 198, 21, 34, 84, 72, 82, 65, 20, 8, 197, 5, 21, 69, 48, 16, 76, 0, 0, 15, 3, 95, 54, 88, 89, 36, 89, 6, 118, 68, 47, 132, 0, 102, 15, 3, 95, 54, 88, 89, 112, 89, 6, 118, 68, 47, 132, 0, 101, 0, 0, 15, 4, 95, 50, 88, 15, 84, 37, 90, 6, 109, 88, 37, 65, 0, 0, 0, 6, 195, 76, 83, 64, 102, 0, 7, 196, 24, 22, 133, 52, 76, 0, 17, 7, 11, 18, 195, 188, 7, 5, 18, 49, 51, 6, 37, 90, 36, 34, 0, 0, 0, 9, 198, 53, 83, 8, 21, 33, 83, 20, 0, 13, 68, 77, 65, 86, 20, 89, 47, 6, 37, 12, 84, 0, 7, 196, 65, 33, 84, 4, 21, 7, 196, 52, 241, 15, 76, 20, 0, 0, 9, 198, 21, 3, 208, 20, 144, 64, 20, 9, 198, 80, 241, 1, 88, 144, 64, 102, 0, 0, 14, 68, 53, 82, 84, 4, 65, 58, 6, 37, 68, 47, 132, 0, 7, 196, 52, 84, 132, 4, 20, 7, 196, 24, 86, 133, 76, 20, 0, 0, 18, 70, 36, 228, 212, 4, 195, 0, 4, 37, 50, 89, 47, 6, 35, 55, 0, 101, 0, 10, 67, 52, 18, 76, 65, 6, 118, 55, 0, 17, 67, 13, 68, 140, 49, 6, 39, 68, 47, 12, 34, 4, 110, 55, 0, 101, 9, 134, 20, 5, 18, 195, 163, 15, 72, 13, 3, 95, 56, 88, 120, 47, 6, 118, 68, 47, 132, 0, 0, 0, 11, 136, 16, 15, 4, 5, 18, 195, 163, 15, 76, 0, 0, 6, 195, 88, 245, 64, 76, 7, 195, 76, 85, 64, 76, 34, 0, 7, 196, 12, 244, 148, 60, 20, 0, 12, 5, 11, 195, 188, 8, 12, 49, 6, 37, 55, 0, 0, 5, 194, 52, 80, 72, 0, 15, 3, 95, 57, 88, 50, 39, 84, 6, 118, 68, 47, 132, 0, 102, 15, 3, 95, 57, 88, 50, 40, 84, 6, 118, 68, 47, 132, 0, 101, 0, 0, 17, 69, 72, 80, 68, 52, 80, 34, 6, 37, 12, 72, 65, 37, 12, 0, 101, 8, 197, 88, 19, 5, 80, 16, 21, 8, 197, 53, 84, 133, 80, 16, 21, 0, 0, 0, 7, 196, 88, 246, 133, 76, 20, 0, 8, 197, 77, 81, 197, 72, 80, 20, 0, 12, 137, 5, 14, 4, 5, 18, 5, 195, 167, 15, 21, 13, 3, 95, 63, 65, 55, 6, 36, 47, 51, 132, 10, 0, 0, 0, 0, 12, 136, 5, 19, 6, 15, 18, 195, 167, 15, 20, 36, 11, 136, 5, 19, 20, 1, 18, 195, 163, 15, 72, 0, 0, 0, 0, 8, 197, 24, 244, 212, 21, 48, 72, 16, 69, 56, 244, 211, 5, 48, 50, 6, 110, 89, 132, 89, 0, 102, 76, 0, 0, 0, 11, 67, 92, 80, 128, 58, 6, 109, 71, 0, 102, 0, 0, 13, 69, 28, 82, 83, 20, 192, 81, 6, 117, 88, 137, 0, 0, 0, 7, 132, 22, 195, 163, 15, 76, 6, 195, 77, 80, 64, 76, 14, 4, 95, 15, 7, 15, 39, 81, 39, 50, 6, 36, 49, 0, 0, 14, 68, 77, 64, 82, 80, 89, 47, 6, 35, 34, 47, 0, 101, 7, 196, 20, 229, 18, 20, 102, 0, 9, 198, 20, 228, 85, 4, 229, 15, 102, 0, 6, 195, 65, 35, 211, 72, 0, 23, 71, 52, 144, 210, 61, 51, 198, 80, 65, 6, 117, 49, 51, 39, 58, 89, 6, 110, 83, 47, 0, 102, 24, 71, 52, 144, 210, 61, 51, 198, 80, 65, 4, 37, 49, 12, 34, 6, 39, 89, 4, 110, 83, 47, 0, 101, 0, 7, 195, 60, 225, 5, 102, 72, 0, 0, 0, 0, 7, 196, 36, 65, 73, 4, 20, 0, 0, 0, 20, 4, 95, 56, 67, 15, 39, 49, 76, 37, 90, 118, 68, 47, 6, 109, 88, 37, 65, 0, 0, 0, 8, 197, 64, 20, 133, 16, 80, 21, 8, 197, 28, 19, 69, 80, 16, 21, 8, 197, 24, 20, 143, 24, 16, 20, 9, 197, 5, 1, 82, 80, 240, 21, 37, 0, 10, 3, 195, 160, 19, 4, 35, 12, 89, 0, 0, 0, 0, 15, 69, 81, 84, 137, 56, 112, 47, 6, 40, 16, 37, 68, 81, 0, 8, 197, 64, 241, 9, 4, 208, 76, 16, 69, 5, 21, 69, 48, 80, 132, 49, 6, 36, 55, 112, 0, 76, 34, 0, 11, 67, 21, 145, 83, 6, 35, 37, 88, 0, 101, 6, 194, 61, 48, 76, 34, 0, 7, 195, 65, 35, 192, 72, 34, 0, 7, 196, 81, 33, 86, 60, 21, 17, 4, 95, 48, 77, 52, 47, 34, 37, 55, 57, 6, 127, 57, 88, 0, 102, 17, 4, 95, 48, 77, 52, 47, 34, 37, 55, 57, 6, 127, 57, 138, 0, 101, 0, 9, 134, 20, 5, 18, 195, 161, 19, 72, 12, 67, 65, 35, 198, 48, 34, 6, 110, 83, 0, 24, 0, 6, 195, 76, 85, 83, 76, 16, 4, 95, 48, 77, 50, 65, 37, 55, 57, 6, 127, 57, 88, 0, 102, 16, 4, 95, 48, 77, 50, 65, 37, 55, 57, 6, 127, 57, 138, 0, 101, 0, 10, 67, 88, 243, 128, 83, 2, 110, 50, 0, 11, 199, 16, 84, 197, 77, 1, 82, 60, 21, 37, 16, 4, 95, 48, 77, 51, 71, 37, 55, 57, 6, 127, 57, 88, 0, 102, 16, 4, 95, 48, 77, 51, 71, 37, 55, 57, 6, 127, 57, 138, 0, 101, 0, 14, 68, 53, 82, 84, 60, 65, 58, 6, 37, 68, 47, 111, 0, 7, 196, 28, 84, 141, 20, 20, 0, 12, 4, 95, 48, 77, 49, 65, 6, 116, 10, 0, 102, 13, 4, 95, 48, 77, 49, 65, 6, 37, 55, 10, 0, 101, 0, 9, 198, 20, 229, 143, 49, 67, 192, 21, 13, 4, 95, 2, 18, 22, 71, 51, 6, 109, 84, 37, 0, 0, 0, 0, 16, 69, 56, 85, 212, 60, 224, 50, 6, 37, 38, 40, 47, 39, 68, 0, 0, 0, 6, 195, 76, 84, 128, 72, 0, 6, 195, 24, 244, 129, 72, 0, 0, 0, 0, 7, 196, 65, 33, 84, 60, 21, 0, 8, 197, 12, 245, 66, 21, 32, 20, 0, 0, 0, 0, 0, 0, 0, 0, 16, 69, 16, 83, 5, 80, 80, 72, 6, 37, 55, 6, 37, 47, 0, 101, 8, 197, 29, 33, 76, 32, 16, 20, 0, 6, 195, 77, 80, 83, 76, 0, 0, 0, 0, 6, 194, 61, 80, 102, 72, 0, 0, 0, 8, 197, 12, 244, 142, 61, 48, 20, 0, 17, 70, 24, 86, 78, 52, 19, 128, 83, 6, 35, 37, 50, 65, 13, 50, 0, 9, 198, 8, 86, 133, 73, 35, 192, 21, 0, 0, 0, 8, 197, 80, 244, 148, 61, 48, 20, 0, 10, 198, 80, 83, 80, 21, 35, 192, 20, 36, 10, 198, 20, 229, 5, 73, 35, 192, 21, 37, 9, 198, 5, 84, 212, 21, 35, 192, 20, 8, 133, 20, 5, 18, 195, 161, 72, 0, 0, 7, 196, 52, 241, 68, 4, 20, 6, 195, 8, 240, 193, 21, 7, 196, 88, 19, 79, 76, 76, 10, 135, 16, 15, 4, 5, 18, 195, 161, 79, 7, 196, 80, 83, 79, 76, 72, 0, 10, 198, 16, 84, 193, 64, 81, 207, 21, 37, 0, 0, 0, 7, 196, 24, 241, 207, 76, 20, 7, 196, 12, 129, 70, 20, 20, 0, 9, 134, 22, 15, 3, 195, 170, 19, 76, 0, 7, 195, 76, 80, 207, 21, 37, 9, 198, 64, 241, 5, 52, 244, 192, 76, 0, 7, 132, 14, 195, 179, 19, 76, 6, 195, 12, 225, 64, 17, 0, 6, 195, 40, 241, 193, 20, 0, 0, 0, 0, 0, 10, 198, 16, 84, 208, 72, 86, 143, 20, 36, 0, 0, 19, 4, 95, 57, 67, 15, 50, 39, 68, 90, 118, 68, 47, 6, 109, 88, 37, 65, 0, 0, 0, 8, 197, 16, 84, 195, 20, 208, 20, 0, 0, 0, 0, 8, 197, 24, 244, 211, 20, 208, 21, 8, 197, 21, 53, 1, 88, 16, 72, 23, 69, 76, 83, 80, 72, 80, 89, 6, 36, 68, 48, 34, 37, 49, 135, 0, 102, 81, 113, 117, 101, 32, 0, 0, 19, 4, 95, 52, 88, 15, 49, 58, 35, 72, 16, 35, 90, 6, 109, 88, 37, 65, 0, 0, 0, 0, 9, 3, 195, 169, 19, 109, 89, 0, 72, 20, 4, 95, 3, 9, 18, 89, 37, 34, 49, 128, 68, 83, 55, 6, 109, 49, 89, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 52, 20, 192, 102, 72, 11, 67, 56, 244, 192, 50, 40, 138, 0, 102, 72, 6, 195, 56, 244, 192, 72, 6, 195, 60, 212, 192, 17, 0, 0, 0, 0, 12, 4, 95, 19, 20, 11, 71, 6, 35, 101, 132, 0, 0, 0, 12, 3, 95, 194, 170, 35, 88, 6, 37, 67, 111, 0, 13, 4, 95, 1, 3, 21, 132, 81, 6, 40, 72, 111, 0, 0, 0, 6, 195, 60, 229, 64, 65, 0, 0, 0, 5, 194, 48, 240, 72, 12, 66, 76, 16, 4, 109, 89, 57, 6, 35, 0, 101, 12, 3, 4, 46, 3, 72, 4, 36, 89, 6, 36, 0, 0, 0, 7, 196, 4, 209, 66, 4, 20, 0, 8, 197, 12, 244, 133, 36, 16, 20, 0, 12, 67, 40, 241, 207, 90, 6, 110, 81, 111, 0, 36, 0, 13, 4, 95, 18, 14, 7, 129, 50, 6, 109, 55, 0, 101, 11, 4, 95, 18, 14, 7, 129, 50, 6, 137, 0, 0, 28, 3, 95, 194, 161, 4, 36, 89, 49, 55, 132, 65, 35, 89, 4, 130, 4, 37, 68, 84, 36, 34, 76, 6, 37, 72, 132, 0, 6, 131, 95, 195, 169, 43, 0, 9, 198, 16, 148, 195, 61, 33, 15, 20, 9, 198, 16, 84, 195, 61, 33, 15, 20, 0, 0, 23, 67, 33, 69, 16, 35, 81, 4, 35, 47, 36, 47, 36, 6, 48, 36, 10, 0, 81, 58, 47, 47, 32, 0, 0, 0, 14, 5, 5, 19, 20, 195, 161, 36, 89, 47, 6, 35, 0, 72, 0, 6, 131, 95, 195, 160, 43, 0, 7, 196, 52, 147, 204, 60, 21, 0, 15, 69, 84, 37, 78, 81, 80, 40, 71, 6, 40, 50, 47, 40, 0, 8, 197, 80, 244, 146, 21, 48, 21, 0, 10, 198, 76, 244, 211, 20, 115, 192, 21, 37, 14, 5, 19, 5, 18, 195, 161, 89, 36, 16, 35, 0, 102, 74, 0, 0, 7, 196, 76, 244, 18, 20, 20, 0, 9, 198, 60, 36, 207, 48, 85, 15, 21, 0, 6, 195, 64, 83, 15, 72, 0, 10, 67, 21, 32, 64, 109, 16, 132, 0, 73, 0, 0, 0, 9, 198, 64, 19, 8, 21, 64, 64, 21, 5, 194, 77, 32, 24, 0, 7, 132, 22, 195, 179, 19, 76, 0, 10, 67, 21, 32, 77, 109, 16, 130, 0, 73, 0, 10, 67, 77, 83, 210, 89, 58, 110, 34, 0, 0, 15, 67, 41, 1, 71, 90, 4, 110, 47, 132, 48, 6, 109, 81, 0, 19, 4, 95, 1, 3, 50, 132, 81, 6, 40, 72, 111, 72, 6, 40, 48, 55, 111, 0, 0, 0, 0, 15, 69, 8, 16, 203, 85, 0, 71, 109, 49, 6, 132, 48, 0, 102, 0, 9, 66, 60, 176, 110, 49, 6, 118, 0, 9, 198, 12, 243, 69, 77, 65, 64, 21, 9, 198, 8, 147, 8, 21, 65, 64, 21, 9, 198, 17, 84, 129, 57, 65, 64, 102, 0, 9, 198, 60, 36, 207, 48, 85, 1, 21, 0, 0, 0, 0, 0, 0, 0, 30, 3, 95, 194, 191, 4, 37, 68, 47, 36, 101, 4, 39, 81, 35, 89, 4, 130, 4, 37, 68, 84, 36, 34, 76, 6, 37, 72, 132, 0, 0, 19, 4, 95, 53, 88, 15, 49, 37, 68, 49, 58, 35, 90, 6, 109, 88, 37, 65, 0, 0, 14, 68, 88, 241, 197, 48, 83, 6, 39, 12, 81, 13, 55, 0, 14, 68, 76, 51, 213, 80, 89, 49, 6, 35, 40, 47, 0, 101, 13, 67, 64, 83, 1, 48, 6, 36, 55, 132, 0, 102, 72, 11, 67, 16, 83, 5, 72, 36, 55, 112, 0, 77, 7, 196, 4, 32, 68, 88, 17, 0, 12, 3, 95, 194, 186, 110, 88, 6, 37, 67, 111, 0, 0, 0, 11, 136, 19, 5, 18, 195, 173, 5, 9, 19, 72, 0, 7, 196, 40, 241, 193, 52, 20, 6, 195, 16, 83, 1, 76, 0, 9, 198, 81, 32, 86, 21, 52, 207, 21, 8, 197, 12, 244, 144, 61, 48, 20, 0, 0, 0, 12, 67, 77, 84, 197, 88, 6, 40, 12, 123, 13, 0, 6, 195, 12, 244, 1, 20, 0, 0, 9, 198, 61, 1, 82, 21, 64, 64, 21, 9, 198, 53, 85, 18, 21, 64, 64, 21, 6, 195, 12, 245, 15, 21, 0, 0, 0, 0, 9, 198, 60, 36, 212, 21, 32, 64, 20, 0, 10, 199, 76, 245, 66, 21, 33, 5, 76, 20, 9, 198, 65, 35, 198, 21, 33, 77, 20, 10, 199, 12, 245, 66, 21, 33, 5, 76, 20, 0, 8, 196, 76, 244, 18, 60, 20, 36, 0, 0, 9, 198, 65, 35, 198, 21, 33, 64, 20, 0, 10, 199, 28, 243, 143, 73, 33, 73, 4, 20, 0, 6, 195, 80, 85, 1, 21, 0, 15, 69, 53, 83, 8, 21, 32, 65, 40, 61, 6, 109, 34, 0, 104, 16, 69, 53, 83, 8, 21, 32, 65, 40, 55, 57, 6, 109, 34, 0, 102, 15, 2, 194, 167, 48, 132, 16, 6, 35, 81, 51, 35, 83, 111, 0, 9, 2, 195, 159, 21, 100, 101, 0, 10, 0, 5, 194, 76, 80, 72, 9, 66, 56, 240, 50, 40, 0, 72, 34, 9, 2, 194, 164, 6, 115, 16, 111, 0, 0, 9, 198, 81, 35, 205, 8, 85, 1, 21, 0, 0, 0, 0, 6, 195, 60, 213, 0, 17, 0, 12, 67, 24, 150, 5, 83, 6, 37, 91, 112, 0, 101, 7, 196, 72, 241, 193, 76, 20, 11, 67, 72, 150, 1, 101, 6, 37, 91, 132, 0, 0, 10, 4, 1, 24, 195, 169, 35, 91, 109, 0, 5, 130, 195, 167, 43, 0, 0, 9, 134, 16, 15, 18, 195, 169, 13, 102, 0, 5, 130, 195, 162, 43, 0, 5, 130, 195, 163, 43, 0, 15, 70, 56, 85, 77, 4, 227, 128, 50, 6, 136, 65, 35, 50, 0, 6, 195, 12, 244, 15, 20, 7, 130, 195, 160, 14, 15, 43, 8, 2, 195, 160, 4, 35, 12, 0, 0, 5, 130, 195, 161, 43, 0, 13, 68, 52, 245, 137, 20, 65, 6, 40, 84, 37, 0, 101, 0, 8, 197, 52, 244, 148, 61, 48, 20, 0, 6, 195, 76, 242, 83, 72, 0, 19, 71, 28, 245, 20, 25, 34, 69, 16, 81, 6, 110, 47, 83, 34, 37, 12, 47, 0, 11, 136, 12, 195, 173, 4, 5, 18, 5, 19, 21, 6, 195, 4, 32, 192, 17, 5, 130, 195, 173, 43, 0, 14, 68, 4, 67, 194, 20, 132, 72, 6, 110, 71, 112, 0, 101, 13, 68, 76, 130, 70, 80, 91, 6, 37, 83, 47, 0, 101, 5, 130, 195, 170, 43, 0, 0, 9, 2, 194, 176, 81, 51, 6, 114, 0, 0, 7, 130, 195, 169, 14, 15, 43, 7, 2, 195, 169, 109, 0, 72, 0, 7, 196, 56, 245, 143, 76, 20, 0, 15, 69, 16, 20, 151, 36, 224, 72, 6, 134, 34, 58, 37, 50, 0, 0, 9, 198, 64, 193, 66, 20, 144, 64, 20, 5, 130, 195, 180, 43, 0, 5, 130, 195, 181, 43, 0, 15, 4, 95, 3, 5, 4, 89, 112, 72, 6, 37, 61, 132, 0, 101, 15, 4, 95, 3, 5, 4, 89, 36, 75, 6, 37, 55, 57, 132, 0, 0, 5, 130, 195, 179, 43, 0, 9, 198, 12, 21, 15, 73, 161, 64, 21, 0, 16, 4, 95, 12, 9, 7, 55, 37, 81, 35, 72, 6, 40, 16, 132, 0, 0, 6, 195, 65, 81, 5, 76, 0, 0, 17, 70, 32, 21, 203, 36, 225, 192, 107, 6, 39, 12, 49, 37, 50, 81, 0, 5, 194, 80, 80, 72, 5, 130, 195, 188, 43, 0, 9, 198, 76, 241, 146, 21, 53, 5, 21, 9, 198, 12, 244, 146, 21, 53, 5, 21, 0, 7, 196, 24, 243, 79, 76, 72, 5, 130, 195, 186, 43, 0, 23, 73, 52, 243, 148, 21, 52, 85, 36, 85, 64, 65, 4, 39, 68, 47, 36, 89, 49, 57, 6, 36, 0, 8, 197, 12, 243, 69, 72, 16, 21, 8, 197, 12, 20, 133, 80, 16, 21, 0, 7, 195, 12, 243, 79, 102, 72, 0, 6, 195, 88, 18, 64, 76, 0, 7, 196, 65, 81, 5, 72, 20, 7, 196, 64, 244, 146, 4, 21, 0, 0, 19, 70, 65, 35, 196, 84, 53, 0, 48, 12, 34, 6, 132, 72, 132, 49, 47, 0, 101, 5, 194, 81, 80, 76, 0, 10, 67, 12, 243, 64, 49, 39, 65, 0, 101, 11, 199, 5, 36, 133, 52, 84, 211, 60, 21, 37, 6, 195, 12, 243, 64, 72, 18, 4, 95, 54, 88, 15, 89, 36, 49, 89, 35, 90, 6, 109, 88, 37, 65, 0, 0, 0, 0, 9, 198, 13, 33, 83, 12, 83, 64, 20, 0, 6, 195, 80, 83, 64, 72, 0, 0, 9, 134, 195, 169, 18, 5, 9, 19, 72, 0, 0, 0, 7, 196, 76, 243, 79, 76, 72, 0, 0, 9, 198, 64, 192, 84, 20, 144, 64, 20, 9, 198, 12, 243, 13, 20, 144, 64, 20, 0, 0, 0, 16, 69, 44, 84, 142, 20, 192, 49, 6, 109, 34, 50, 13, 55, 0, 102, 17, 69, 44, 84, 142, 20, 192, 49, 6, 109, 34, 50, 4, 109, 55, 0, 101, 0, 7, 195, 21, 36, 143, 21, 37, 0, 6, 195, 76, 245, 64, 72, 0, 14, 67, 21, 53, 5, 6, 36, 89, 76, 37, 0, 102, 76, 34, 0, 0, 0, 7, 195, 80, 85, 64, 76, 34, 0, 14, 67, 21, 53, 1, 6, 109, 89, 47, 132, 0, 102, 76, 34, 0, 8, 197, 5, 1, 83, 5, 32, 102, 0, 5, 194, 84, 80, 17, 0, 0, 14, 68, 52, 18, 197, 72, 65, 6, 118, 49, 132, 44, 0, 101, 8, 133, 16, 18, 195, 160, 19, 72, 0, 8, 197, 76, 19, 5, 80, 16, 21, 0, 0, 10, 199, 65, 34, 77, 5, 97, 82, 4, 20, 9, 198, 16, 144, 82, 72, 82, 65, 20, 9, 198, 4, 192, 193, 80, 82, 65, 20, 0, 16, 5, 95, 49, 77, 49, 15, 65, 37, 55, 6, 109, 88, 37, 65, 0, 0, 8, 197, 88, 145, 82, 20, 208, 20, 8, 197, 76, 241, 146, 20, 208, 20, 0, 0, 6, 2, 95, 1, 35, 0, 0, 0, 0, 9, 198, 5, 53, 1, 88, 19, 64, 72, 0, 6, 2, 95, 5, 109, 0, 0, 7, 196, 88, 84, 141, 20, 20, 0, 0, 9, 198, 72, 80, 207, 72, 67, 192, 20, 9, 198, 4, 208, 82, 20, 195, 192, 20, 9, 198, 65, 81, 5, 72, 19, 64, 76, 0, 0, 6, 2, 95, 15, 110, 0, 6, 195, 76, 240, 128, 102, 0, 12, 68, 64, 17, 88, 4, 48, 35, 36, 91, 35, 0, 0, 16, 69, 4, 194, 83, 60, 224, 132, 55, 6, 37, 89, 132, 68, 0, 101, 0, 9, 198, 88, 19, 133, 77, 48, 64, 21, 6, 195, 76, 240, 133, 20, 0, 6, 195, 81, 80, 64, 76, 0, 14, 68, 64, 242, 78, 80, 48, 6, 39, 37, 50, 47, 0, 101, 6, 195, 61, 99, 211, 20, 8, 133, 16, 195, 180, 4, 5, 76, 0, 0, 17, 70, 76, 48, 78, 56, 84, 128, 89, 49, 6, 109, 50, 132, 34, 0, 101, 0, 0, 6, 195, 80, 83, 147, 72, 0, 0, 0, 0, 15, 68, 76, 85, 21, 64, 89, 6, 109, 47, 6, 132, 48, 0, 101, 0, 0, 13, 4, 95, 226, 136, 146, 65, 6, 36, 50, 111, 89, 0, 0, 0, 13, 68, 76, 182, 80, 20, 89, 49, 6, 117, 48, 0, 102, 14, 68, 76, 182, 80, 20, 89, 49, 6, 35, 37, 48, 0, 101, 0, 8, 197, 64, 84, 133, 16, 80, 21, 16, 69, 4, 51, 210, 16, 240, 132, 49, 6, 110, 34, 72, 111, 0, 36, 0, 0, 15, 2, 95, 35, 49, 4, 35, 34, 75, 37, 50, 6, 114, 0, 102, 16, 2, 95, 35, 49, 4, 35, 34, 72, 37, 50, 6, 35, 55, 0, 101, 0, 24, 2, 95, 34, 6, 35, 71, 51, 37, 38, 6, 35, 89, 48, 132, 15, 72, 6, 40, 48, 55, 132, 138, 0, 11, 2, 95, 34, 6, 35, 89, 48, 132, 138, 0, 0, 16, 2, 95, 33, 4, 36, 89, 49, 55, 132, 65, 35, 89, 6, 130, 0, 0, 0, 11, 67, 61, 99, 192, 6, 39, 84, 40, 0, 101, 16, 2, 95, 39, 132, 48, 6, 110, 89, 47, 51, 39, 83, 111, 0, 102, 17, 2, 95, 39, 35, 48, 6, 110, 89, 47, 34, 4, 39, 83, 112, 0, 101, 0, 6, 195, 80, 85, 83, 76, 7, 2, 95, 38, 6, 36, 0, 0, 0, 6, 195, 17, 83, 65, 72, 12, 2, 95, 36, 89, 4, 37, 83, 51, 6, 130, 0, 0, 6, 195, 17, 83, 64, 72, 0, 14, 68, 28, 208, 73, 48, 90, 36, 65, 6, 118, 55, 0, 102, 15, 68, 28, 208, 73, 48, 81, 4, 36, 65, 6, 118, 55, 0, 101, 15, 2, 95, 42, 132, 89, 47, 36, 16, 6, 37, 89, 49, 111, 0, 16, 4, 95, 3, 1, 16, 65, 117, 6, 40, 89, 49, 40, 55, 111, 0, 0, 20, 2, 95, 41, 83, 4, 109, 91, 132, 48, 35, 16, 6, 118, 68, 47, 36, 88, 112, 0, 0, 20, 2, 95, 40, 4, 35, 71, 51, 37, 48, 35, 16, 6, 118, 68, 47, 36, 88, 112, 0, 0, 10, 2, 95, 47, 71, 6, 35, 100, 132, 0, 0, 0, 10, 2, 95, 45, 6, 37, 83, 118, 68, 0, 0, 16, 70, 45, 37, 69, 28, 84, 128, 49, 51, 6, 37, 90, 36, 34, 0, 13, 2, 95, 44, 84, 6, 37, 34, 81, 40, 55, 132, 0, 0, 6, 195, 16, 84, 128, 20, 6, 195, 80, 84, 128, 72, 6, 195, 53, 36, 192, 24, 10, 2, 95, 51, 47, 51, 6, 36, 138, 0, 0, 9, 2, 95, 50, 72, 6, 120, 138, 0, 0, 24, 73, 61, 4, 5, 56, 129, 73, 52, 84, 128, 11, 6, 110, 48, 13, 50, 107, 4, 117, 65, 35, 34, 0, 9, 2, 95, 49, 6, 128, 68, 0, 102, 9, 2, 95, 49, 6, 40, 65, 0, 101, 0, 15, 70, 53, 81, 76, 48, 84, 128, 65, 6, 37, 55, 36, 34, 0, 11, 67, 80, 85, 133, 47, 36, 84, 112, 0, 73, 11, 2, 95, 48, 88, 6, 109, 16, 111, 0, 102, 11, 2, 95, 48, 88, 6, 109, 16, 40, 0, 101, 0, 11, 2, 95, 55, 89, 6, 109, 76, 112, 0, 102, 11, 2, 95, 55, 89, 6, 109, 47, 112, 0, 101, 0, 9, 2, 95, 54, 89, 6, 118, 138, 0, 0, 11, 2, 95, 53, 89, 6, 37, 68, 49, 40, 0, 0, 6, 195, 16, 85, 129, 21, 13, 2, 95, 52, 49, 58, 6, 35, 47, 51, 40, 0, 102, 13, 2, 95, 52, 49, 58, 6, 35, 47, 34, 40, 0, 101, 0, 21, 2, 95, 59, 48, 4, 39, 68, 47, 40, 10, 37, 84, 6, 37, 34, 81, 40, 55, 132, 0, 0, 6, 195, 16, 85, 143, 21, 7, 196, 16, 84, 195, 20, 20, 16, 2, 95, 58, 72, 4, 120, 89, 48, 6, 39, 68, 47, 40, 89, 0, 0, 10, 2, 95, 57, 50, 6, 110, 84, 112, 0, 0, 9, 2, 95, 56, 6, 120, 47, 40, 0, 0, 18, 2, 95, 63, 4, 37, 68, 47, 36, 101, 4, 39, 81, 35, 89, 6, 130, 0, 0, 6, 195, 81, 80, 83, 76, 10, 2, 95, 62, 65, 117, 6, 110, 34, 0, 0, 8, 197, 80, 20, 5, 80, 80, 21, 8, 197, 12, 16, 197, 80, 80, 21, 8, 197, 4, 35, 210, 16, 240, 20, 11, 2, 95, 61, 37, 81, 58, 6, 114, 0, 102, 12, 2, 95, 61, 37, 81, 58, 6, 35, 55, 0, 101, 0, 11, 2, 95, 60, 65, 36, 50, 6, 110, 34, 0, 0, 6, 195, 16, 86, 128, 20, 6, 195, 24, 22, 128, 76, 0, 17, 70, 88, 243, 11, 52, 19, 142, 83, 6, 110, 55, 49, 65, 35, 50, 0, 21, 68, 16, 84, 196, 20, 72, 6, 36, 89, 75, 37, 49, 135, 0, 102, 81, 113, 117, 101, 32, 8, 196, 16, 84, 196, 20, 102, 72, 0, 0, 0, 0, 15, 6, 13, 195, 188, 12, 5, 18, 65, 6, 37, 55, 36, 34, 0, 0, 0, 0, 0, 0, 0, 9, 198, 72, 80, 207, 73, 67, 192, 20, 10, 198, 20, 230, 5, 73, 67, 192, 21, 37, 8, 133, 16, 18, 195, 178, 19, 72, 0, 6, 195, 20, 192, 64, 76, 6, 195, 36, 48, 192, 17, 0, 7, 196, 4, 67, 210, 20, 20, 0, 0, 18, 70, 52, 83, 143, 72, 84, 192, 65, 36, 50, 6, 110, 16, 37, 89, 0, 102, 9, 198, 80, 149, 133, 72, 84, 192, 20, 0, 6, 195, 85, 48, 128, 17, 6, 195, 56, 32, 64, 17, 0, 14, 68, 64, 18, 78, 80, 48, 6, 35, 37, 50, 47, 0, 101, 11, 67, 8, 16, 203, 71, 6, 109, 49, 0, 101, 7, 196, 64, 245, 143, 76, 20, 7, 195, 28, 246, 143, 20, 36, 0, 11, 67, 4, 192, 78, 6, 35, 55, 13, 50, 0, 0, 9, 198, 65, 81, 5, 52, 244, 192, 76, 9, 198, 24, 22, 133, 52, 244, 192, 76, 9, 198, 80, 149, 133, 52, 244, 192, 72, 9, 198, 21, 53, 1, 52, 244, 192, 72, 0, 11, 67, 20, 193, 64, 6, 36, 55, 112, 0, 76, 0, 16, 70, 72, 144, 200, 5, 33, 0, 101, 6, 37, 91, 132, 34, 72, 0, 13, 4, 95, 4, 15, 20, 48, 6, 39, 68, 47, 111, 0, 0, 0, 0, 6, 195, 20, 49, 192, 17, 18, 2, 95, 91, 4, 35, 71, 51, 37, 49, 39, 58, 91, 6, 36, 76, 37, 0, 0, 6, 195, 20, 192, 83, 76, 0, 14, 69, 20, 194, 88, 37, 32, 36, 55, 37, 91, 37, 34, 0, 0, 7, 66, 88, 144, 84, 37, 0, 0, 16, 2, 95, 95, 89, 4, 40, 71, 55, 37, 67, 6, 35, 72, 40, 0, 0, 19, 2, 95, 94, 89, 4, 37, 34, 49, 128, 68, 83, 55, 6, 109, 49, 89, 40, 0, 0, 14, 69, 60, 227, 9, 56, 80, 39, 68, 55, 117, 68, 0, 102, 18, 2, 95, 93, 83, 4, 109, 91, 132, 49, 39, 58, 91, 6, 36, 76, 37, 0, 0, 21, 2, 95, 92, 71, 4, 35, 101, 132, 4, 37, 68, 84, 36, 34, 76, 6, 37, 72, 132, 0, 0, 6, 195, 24, 34, 64, 17, 0, 6, 195, 20, 193, 83, 76, 0, 16, 69, 4, 115, 211, 80, 240, 132, 81, 6, 39, 89, 47, 111, 0, 102, 17, 4, 95, 56, 88, 15, 39, 49, 47, 39, 90, 6, 109, 88, 37, 65, 0, 0, 11, 2, 95, 96, 81, 51, 6, 35, 84, 37, 0, 0, 0, 6, 195, 12, 240, 207, 21, 7, 132, 16, 18, 195, 160, 72, 0, 16, 7, 13, 195, 188, 12, 12, 5, 18, 65, 6, 37, 55, 36, 34, 0, 0, 9, 198, 20, 225, 143, 72, 51, 192, 20, 0, 0, 7, 196, 64, 84, 193, 52, 20, 0, 0, 6, 195, 64, 84, 193, 20, 9, 198, 52, 244, 131, 20, 115, 192, 21, 13, 4, 95, 7, 18, 22, 81, 51, 6, 35, 84, 37, 0, 0, 16, 67, 76, 244, 192, 4, 109, 89, 57, 4, 110, 6, 109, 89, 0, 101, 0, 0, 0, 18, 70, 92, 147, 132, 61, 116, 192, 58, 6, 37, 68, 72, 39, 58, 89, 0, 102, 20, 70, 92, 147, 132, 61, 116, 192, 58, 6, 37, 68, 72, 6, 39, 40, 12, 88, 0, 101, 0, 10, 199, 21, 53, 9, 88, 83, 79, 76, 72, 6, 195, 56, 20, 192, 72, 0, 0, 0, 9, 198, 80, 84, 133, 52, 244, 192, 72, 9, 198, 76, 84, 133, 52, 244, 192, 72, 7, 132, 16, 18, 195, 178, 72, 0, 0, 7, 195, 64, 84, 207, 21, 37, 6, 195, 64, 84, 207, 20, 6, 195, 17, 83, 147, 72, 12, 67, 8, 147, 211, 71, 6, 37, 4, 110, 91, 0, 0, 0, 0, 15, 2, 95, 123, 4, 35, 71, 51, 37, 91, 6, 35, 84, 37, 0, 13, 4, 95, 4, 9, 1, 47, 51, 6, 36, 65, 132, 0, 0, 0, 15, 69, 52, 83, 8, 61, 32, 65, 36, 61, 6, 110, 34, 0, 104, 16, 69, 52, 83, 8, 61, 32, 65, 36, 55, 57, 6, 110, 34, 0, 102, 0, 16, 70, 60, 97, 140, 36, 225, 64, 110, 83, 55, 6, 117, 68, 0, 102, 6, 194, 84, 208, 72, 34, 0, 0, 13, 68, 64, 245, 197, 72, 48, 6, 114, 132, 44, 0, 101, 9, 2, 95, 126, 76, 6, 116, 0, 102, 10, 2, 95, 126, 47, 6, 37, 55, 0, 101, 0, 8, 197, 64, 84, 132, 20, 208, 20, 15, 2, 95, 125, 83, 4, 109, 91, 132, 91, 6, 35, 84, 37, 0, 0, 20, 2, 95, 124, 71, 4, 35, 101, 132, 84, 4, 36, 34, 76, 37, 49, 6, 114, 0, 102, 21, 2, 95, 124, 71, 4, 35, 101, 132, 84, 4, 36, 34, 76, 37, 49, 6, 35, 55, 0, 101, 0, 19, 70, 24, 148, 133, 24, 246, 0, 83, 6, 35, 37, 13, 83, 110, 49, 89, 0, 102, 20, 70, 24, 148, 133, 24, 246, 0, 83, 6, 35, 37, 132, 34, 83, 110, 49, 89, 0, 101, 0, 13, 67, 40, 21, 211, 75, 6, 35, 40, 12, 88, 0, 101, 0, 0, 0, 9, 198, 65, 84, 197, 72, 65, 83, 20, 0, 7, 195, 76, 240, 207, 20, 36, 6, 195, 76, 240, 207, 21, 11, 200, 5, 52, 197, 52, 35, 5, 36, 16, 20, 0, 16, 69, 4, 48, 197, 77, 48, 6, 35, 49, 89, 4, 109, 89, 0, 101, 0, 0, 0, 0, 0, 0, 0, 15, 68, 8, 194, 78, 16, 71, 55, 6, 35, 37, 50, 72, 0, 101, 7, 196, 21, 36, 143, 76, 21, 0, 0, 0, 12, 67, 21, 48, 192, 6, 109, 89, 49, 124, 0, 103, 11, 67, 21, 48, 192, 6, 109, 89, 49, 0, 102, 0, 7, 196, 8, 84, 212, 4, 21, 0, 0, 9, 198, 65, 83, 136, 21, 64, 64, 20, 6, 195, 64, 241, 5, 76, 0, 0, 0, 0, 18, 70, 88, 84, 130, 21, 65, 64, 84, 36, 34, 71, 6, 36, 76, 37, 0, 102, 9, 198, 8, 80, 133, 77, 65, 64, 21, 14, 4, 95, 35, 51, 50, 91, 48, 6, 35, 89, 111, 0, 101, 14, 4, 95, 35, 51, 50, 36, 89, 48, 6, 35, 89, 111, 0, 0, 0, 0, 20, 8, 19, 195, 173, 13, 2, 15, 12, 15, 89, 6, 37, 68, 71, 39, 55, 111, 0, 104, 19, 8, 19, 195, 173, 13, 2, 15, 12, 15, 89, 6, 37, 65, 71, 39, 55, 111, 0, 0, 0, 0, 11, 5, 5, 46, 21, 46, 1, 109, 40, 35, 0, 0, 0, 16, 70, 4, 32, 67, 5, 130, 64, 35, 71, 35, 49, 35, 91, 112, 0, 0, 0, 21, 72, 32, 82, 83, 20, 224, 133, 72, 112, 107, 6, 117, 88, 109, 50, 71, 36, 34, 81, 0, 13, 68, 52, 18, 79, 72, 65, 117, 6, 110, 34, 0, 102, 15, 68, 52, 18, 79, 72, 65, 4, 132, 57, 6, 110, 44, 0, 101, 0, 17, 4, 95, 57, 88, 15, 50, 39, 50, 35, 90, 6, 109, 88, 37, 65, 0, 0, 17, 70, 61, 85, 12, 60, 242, 192, 4, 114, 47, 55, 6, 40, 49, 0, 102, 18, 70, 61, 85, 12, 60, 242, 192, 6, 35, 40, 47, 55, 6, 40, 49, 0, 101, 0, 19, 70, 88, 84, 130, 21, 65, 83, 84, 36, 34, 71, 6, 36, 76, 37, 89, 0, 102, 0, 12, 68, 52, 18, 76, 76, 65, 6, 118, 55, 89, 0, 20, 70, 21, 132, 12, 61, 33, 82, 36, 49, 89, 48, 55, 6, 110, 16, 36, 34, 0, 102, 22, 70, 21, 132, 12, 61, 33, 82, 4, 36, 49, 89, 48, 55, 6, 110, 12, 16, 132, 44, 0, 101, 0, 0, 0, 9, 198, 16, 84, 198, 20, 50, 15, 21, 0, 0, 0, 19, 70, 36, 229, 5, 72, 225, 84, 37, 68, 47, 36, 34, 50, 6, 109, 47, 0, 102, 13, 67, 21, 52, 197, 6, 36, 89, 37, 0, 102, 76, 34, 0, 6, 195, 37, 52, 192, 17, 0, 0, 0, 9, 198, 76, 20, 138, 21, 64, 64, 20, 9, 198, 64, 20, 212, 61, 32, 64, 21, 9, 198, 52, 20, 146, 21, 64, 64, 21, 9, 198, 12, 244, 142, 21, 64, 64, 21, 9, 198, 12, 20, 146, 21, 64, 64, 21, 11, 67, 21, 52, 193, 6, 109, 89, 132, 0, 76, 0, 0, 6, 195, 13, 5, 67, 17, 0, 0, 12, 67, 76, 149, 5, 89, 6, 117, 76, 37, 0, 102, 11, 67, 76, 149, 5, 89, 6, 117, 47, 0, 101, 13, 67, 76, 20, 9, 89, 4, 35, 48, 6, 37, 0, 101, 9, 198, 88, 147, 204, 21, 64, 64, 21, 0, 6, 195, 13, 5, 64, 17, 0, 0, 9, 198, 12, 19, 73, 76, 85, 1, 21, 0, 26, 10, 20, 5, 12, 5, 13, 195, 179, 22, 5, 12, 47, 4, 109, 55, 4, 109, 65, 6, 110, 84, 109, 55, 0, 101, 9, 198, 76, 244, 150, 21, 65, 64, 21, 9, 198, 64, 244, 146, 21, 65, 64, 21, 9, 198, 80, 149, 133, 77, 65, 64, 72, 0, 0, 12, 67, 12, 20, 19, 49, 6, 35, 48, 89, 0, 101, 7, 196, 24, 244, 211, 20, 21, 13, 68, 16, 84, 211, 20, 72, 6, 36, 89, 112, 0, 76, 0, 0, 12, 137, 18, 5, 6, 15, 18, 195, 167, 15, 19, 20, 0, 0, 12, 68, 44, 193, 73, 56, 49, 55, 6, 117, 50, 0, 16, 68, 21, 53, 5, 76, 6, 36, 89, 76, 37, 89, 0, 102, 76, 34, 0, 15, 69, 21, 48, 193, 64, 80, 91, 49, 6, 118, 48, 112, 0, 101, 0, 11, 67, 64, 246, 1, 48, 6, 39, 91, 132, 0, 11, 67, 52, 86, 1, 65, 6, 36, 91, 132, 0, 0, 0, 7, 196, 24, 244, 212, 20, 21, 7, 196, 24, 244, 212, 20, 72, 0, 15, 69, 28, 243, 199, 48, 80, 81, 6, 40, 81, 39, 55, 0, 102, 16, 69, 28, 243, 199, 48, 80, 81, 6, 40, 12, 81, 132, 55, 0, 101, 8, 197, 52, 81, 197, 72, 16, 20, 0, 0, 9, 198, 80, 149, 133, 77, 65, 83, 72, 0, 8, 196, 12, 131, 210, 60, 21, 37, 0, 0, 0, 0, 0, 16, 69, 56, 244, 211, 61, 48, 50, 6, 110, 89, 111, 89, 0, 102, 76, 0, 0, 7, 195, 84, 208, 64, 72, 34, 0, 6, 195, 64, 242, 83, 102, 0, 12, 136, 20, 18, 15, 16, 5, 195, 167, 15, 21, 37, 0, 12, 137, 1, 13, 1, 14, 8, 5, 195, 167, 15, 21, 0, 9, 134, 5, 19, 20, 195, 163, 15, 72, 0, 11, 67, 52, 86, 15, 65, 6, 36, 91, 111, 0, 0, 19, 70, 16, 146, 139, 77, 68, 129, 72, 6, 37, 57, 49, 89, 47, 34, 134, 12, 0, 0, 9, 198, 64, 19, 135, 20, 144, 64, 20, 0, 0, 7, 196, 21, 53, 15, 84, 72, 0, 0, 11, 67, 52, 86, 9, 65, 36, 91, 6, 37, 0, 6, 195, 36, 81, 69, 17, 0, 0, 14, 68, 28, 244, 212, 60, 81, 6, 110, 89, 47, 111, 0, 36, 0, 14, 69, 53, 81, 76, 21, 32, 65, 6, 37, 55, 36, 34, 0, 0, 12, 137, 5, 19, 6, 15, 18, 195, 167, 15, 19, 20, 0, 0, 0, 11, 136, 3, 15, 14, 8, 5, 195, 167, 15, 21, 7, 132, 19, 195, 163, 15, 72, 0, 0, 0, 7, 196, 76, 241, 210, 4, 20, 7, 196, 28, 84, 211, 60, 21, 7, 196, 21, 53, 1, 72, 72, 0, 14, 70, 72, 245, 83, 76, 80, 85, 51, 40, 89, 6, 39, 0, 8, 197, 5, 85, 15, 72, 16, 21, 0, 13, 67, 32, 243, 69, 107, 6, 39, 58, 65, 37, 0, 102, 11, 67, 32, 243, 69, 6, 39, 65, 112, 0, 101, 0, 20, 71, 52, 84, 211, 20, 225, 197, 72, 65, 6, 109, 89, 132, 50, 75, 132, 44, 0, 101, 18, 70, 52, 83, 8, 61, 33, 83, 65, 36, 61, 6, 110, 16, 37, 89, 0, 104, 19, 70, 52, 83, 8, 61, 33, 83, 65, 36, 55, 57, 6, 110, 16, 37, 89, 0, 102, 0, 0, 0, 9, 198, 20, 225, 207, 72, 67, 192, 20, 0, 0, 0, 8, 197, 80, 83, 132, 21, 48, 72, 0, 8, 133, 6, 1, 195, 167, 15, 76, 0, 0, 12, 137, 1, 13, 1, 14, 8, 5, 195, 167, 1, 21, 0, 0, 0, 9, 134, 19, 5, 18, 195, 163, 15, 72, 0, 14, 68, 76, 208, 82, 80, 89, 65, 6, 35, 34, 47, 0, 101, 7, 196, 40, 241, 207, 76, 20, 0, 0, 0, 21, 71, 65, 80, 140, 37, 50, 5, 72, 48, 6, 132, 71, 55, 4, 37, 91, 132, 44, 0, 101, 10, 199, 8, 244, 130, 60, 193, 84, 4, 21, 0, 0, 0, 0, 7, 195, 52, 85, 64, 76, 34, 6, 195, 4, 68, 204, 17, 0, 7, 195, 84, 208, 83, 72, 34, 0, 0, 0, 0, 11, 135, 3, 15, 13, 5, 195, 167, 15, 21, 37, 18, 7, 3, 15, 13, 5, 195, 167, 15, 49, 39, 65, 6, 109, 89, 111, 0, 36, 0, 17, 70, 76, 83, 22, 4, 113, 77, 89, 115, 84, 6, 35, 90, 118, 68, 0, 8, 197, 69, 80, 78, 16, 240, 102, 0, 9, 198, 64, 241, 5, 72, 82, 64, 79, 0, 0, 0, 0, 0, 10, 199, 5, 67, 79, 76, 97, 82, 4, 20, 0, 6, 195, 52, 85, 83, 76, 0, 6, 18, 66, 97, 109, 0, 97, 0, 7, 6, 18, 67, 101, 109, 0, 101, 0, 7, 6, 18, 68, 97, 109, 0, 97, 0, 111, 0, 7, 6, 18, 69, 117, 101, 109, 0, 97, 109, 0, 101, 109, 0, 117, 101, 0, 97, 0, 101, 0, 111, 0, 7, 6, 18, 70, 114, 100, 101, 115, 0, 114, 97, 109, 0, 114, 101, 109, 0, 114, 97, 0, 114, 101, 0, 114, 0, 7, 6, 195, 160, 0, 3, 35, 0, 8, 2, 115, 32, 3, 117, 0, 4, 2, 109, 3, 129, 0, 2, 110, 0, 109, 2, 25, 3, 129, 65, 0, 110, 104, 2, 17, 65, 3, 129, 67, 0, 110, 2, 25, 3, 129, 68, 0, 7, 6, 195, 161, 0, 4, 3, 7, 35, 0, 2, 105, 17, 67, 25, 0, 2, 117, 17, 67, 25, 0, 4, 117, 3, 7, 114, 0, 117, 2, 115, 0, 4, 105, 3, 7, 117, 0, 105, 2, 115, 0, 121, 0, 108, 5, 1, 3, 7, 134, 55, 0, 7, 6, 195, 162, 0, 4, 2, 109, 3, 7, 129, 0, 2, 110, 0, 109, 2, 25, 3, 7, 129, 65, 0, 110, 104, 3, 7, 129, 67, 0, 110, 2, 25, 3, 7, 129, 68, 0, 3, 7, 132, 0, 7, 6, 195, 163, 0, 3, 129, 0, 111, 3, 130, 0, 7, 6, 195, 169, 0, 4, 3, 7, 109, 0, 2, 105, 17, 67, 25, 0, 2, 117, 17, 67, 25, 0, 121, 3, 7, 118, 0, 4, 109, 2, 32, 3, 7, 118, 68, 0, 109, 2, 115, 32, 0, 110, 2, 32, 0, 110, 2, 115, 32, 0, 4, 105, 3, 7, 119, 0, 105, 2, 115, 0, 4, 117, 3, 7, 137, 0, 117, 2, 115, 0, 7, 6, 195, 170, 0, 3, 7, 36, 0, 110, 104, 3, 7, 36, 67, 0, 109, 2, 17, 67, 3, 7, 118, 65, 0, 4, 109, 2, 32, 3, 7, 118, 68, 0, 109, 2, 32, 0, 110, 2, 25, 0, 7, 6, 195, 173, 0, 4, 3, 7, 37, 0, 2, 109, 0, 2, 110, 0, 109, 2, 17, 67, 3, 7, 37, 65, 0, 110, 104, 3, 7, 37, 67, 0, 4, 109, 2, 32, 3, 7, 37, 68, 0, 110, 2, 25, 0, 7, 6, 195, 179, 0, 4, 3, 7, 110, 0, 2, 105, 17, 67, 25, 0, 117, 3, 7, 110, 58, 0, 4, 105, 3, 7, 136, 0, 105, 2, 115, 0, 121, 0, 7, 6, 195, 180, 0, 3, 7, 39, 0, 109, 2, 17, 67, 3, 7, 39, 65, 0, 110, 104, 3, 7, 39, 67, 0, 4, 109, 2, 32, 3, 7, 39, 68, 0, 110, 2, 25, 0, 7, 6, 195, 181, 0, 3, 127, 0, 101, 3, 127, 57, 0, 7, 6, 195, 186, 0, 3, 7, 40, 0, 109, 2, 17, 67, 3, 7, 128, 65, 0, 110, 104, 3, 7, 128, 67, 0, 4, 109, 2, 32, 3, 7, 128, 68, 0, 109, 5, 4, 2, 17, 67, 0, 110, 2, 25, 0, 7, 6, 97, 0, 5, 1, 2, 108, 25, 3, 4, 134, 0, 4, 2, 114, 32, 3, 6, 35, 0, 5, 1, 2, 122, 32, 0, 8, 2, 32, 31, 0, 99, 195, 167, 5, 1, 1, 17, 67, 3, 6, 35, 6, 89, 0, 5, 1, 2, 108, 32, 3, 6, 134, 0, 5, 1, 1, 112, 2, 100, 32, 3, 8, 109, 0, 109, 2, 32, 3, 8, 129, 68, 0, 109, 2, 32, 3, 8, 130, 0, 4, 1, 10, 2, 32, 3, 8, 132, 0, 1, 10, 2, 115, 32, 0, 5, 1, 2, 32, 0, 5, 1, 2, 115, 32, 0, 4, 1, 10, 2, 32, 97, 3, 8, 133, 0, 1, 10, 2, 32, 195, 160, 0, 5, 1, 2, 32, 97, 0, 5, 1, 2, 32, 195, 160, 0, 4, 3, 35, 0, 2, 105, 17, 67, 25, 0, 2, 105, 117, 32, 0, 2, 108, 104, 12, 0, 2, 117, 17, 67, 25, 0, 8, 2, 32, 0, 4, 108, 5, 2, 2, 25, 3, 114, 0, 111, 2, 32, 0, 117, 0, 117, 2, 115, 0, 4, 105, 3, 117, 0, 105, 2, 115, 0, 121, 0, 4, 2, 109, 3, 129, 0, 2, 110, 0, 109, 2, 17, 67, 3, 129, 65, 0, 110, 104, 2, 17, 65, 3, 129, 67, 0, 4, 109, 5, 4, 2, 17, 67, 3, 129, 68, 0, 110, 2, 25, 12, 0, 4, 2, 17, 67, 17, 67, 32, 3, 132, 0, 2, 17, 67, 32, 0, 2, 109, 17, 65, 21, 0, 2, 109, 17, 65, 114, 32, 0, 2, 110, 17, 65, 21, 0, 2, 110, 17, 65, 114, 32, 0, 7, 6, 98, 0, 2, 98, 3, 0, 4, 3, 71, 0, 5, 3, 2, 115, 0, 5, 3, 2, 32, 17, 67, 3, 71, 10, 0, 8, 2, 32, 3, 71, 36, 0, 5, 3, 2, 17, 66, 3, 71, 124, 0, 7, 6, 99, 0, 5, 1, 2, 99, 3, 0, 116, 5, 1, 1, 17, 65, 3, 47, 0, 4, 3, 49, 0, 5, 3, 2, 115, 0, 5, 3, 2, 116, 0, 107, 0, 5, 3, 2, 32, 17, 67, 3, 49, 10, 0, 116, 5, 1, 1, 97, 116, 110, 111, 99, 2, 17, 65, 3, 49, 47, 0, 5, 3, 2, 17, 66, 3, 49, 124, 0, 4, 2, 17, 71, 3, 89, 0, 195, 167, 5, 1, 1, 17, 65, 0, 8, 2, 32, 3, 89, 36, 0, 104, 3, 91, 0, 7, 6, 100, 0, 2, 100, 3, 0, 3, 72, 0, 5, 3, 2, 32, 17, 67, 3, 72, 10, 0, 8, 2, 32, 3, 72, 36, 0, 4, 5, 2, 2, 101, 32, 3, 75, 0, 5, 2, 2, 105, 0, 5, 2, 2, 195, 173, 0, 5, 3, 2, 17, 66, 3, 75, 124, 0, 7, 6, 101, 0, 4, 5, 1, 1, 100, 2, 110, 17, 67, 17, 65, 17, 65, 3, 4, 36, 0, 5, 1, 1, 100, 2, 110, 17, 67, 17, 65, 17, 67, 17, 65, 0, 5, 1, 1, 100, 2, 110, 17, 67, 17, 65, 17, 67, 17, 67, 17, 65, 0, 4, 5, 1, 1, 17, 67, 2, 99, 17, 67, 3, 4, 109, 0, 5, 1, 1, 112, 105, 104, 2, 114, 0, 5, 1, 1, 112, 117, 115, 2, 114, 0, 5, 1, 1, 114, 2, 108, 118, 97, 0, 5, 1, 1, 118, 2, 108, 32, 0, 5, 1, 8, 109, 2, 103, 97, 0, 5, 1, 8, 116, 110, 105, 2, 114, 110, 0, 5, 1, 1, 17, 67, 2, 111, 3, 6, 37, 0, 4, 5, 1, 1, 108, 2, 116, 97, 3, 6, 109, 0, 5, 1, 1, 110, 2, 116, 0, 5, 1, 2, 108, 32, 0, 5, 1, 2, 108, 97, 32, 0, 99, 195, 167, 5, 1, 1, 17, 67, 3, 6, 109, 6, 89, 0, 4, 5, 2, 1, 108, 10, 2, 32, 17, 65, 24, 3, 8, 37, 0, 5, 2, 1, 114, 10, 2, 32, 17, 65, 24, 0, 4, 2, 32, 3, 8, 112, 0, 2, 115, 32, 0, 4, 109, 2, 32, 3, 8, 118, 68, 0, 109, 2, 115, 32, 0, 110, 2, 32, 0, 110, 2, 115, 32, 0, 4, 5, 1, 2, 32, 105, 24, 3, 8, 135, 0, 5, 2, 2, 32, 17, 65, 24, 0, 4, 3, 36, 0, 1, 100, 101, 2, 114, 17, 65, 109, 32, 0, 1, 100, 111, 112, 2, 114, 17, 65, 32, 0, 1, 104, 2, 103, 17, 65, 32, 0, 1, 104, 2, 103, 17, 65, 109, 32, 0, 1, 110, 17, 65, 2, 116, 17, 65, 32, 0, 1, 114, 2, 99, 104, 111, 32, 0, 1, 116, 2, 118, 101, 32, 0, 1, 122, 97, 103, 2, 116, 97, 32, 0, 2, 105, 17, 67, 25, 0, 2, 108, 104, 12, 0, 2, 108, 111, 32, 0, 2, 117, 17, 67, 25, 0, 2, 118, 105, 32, 0, 2, 118, 195, 170, 32, 0, 8, 100, 97, 112, 2, 195, 167, 18, 68, 32, 0, 8, 100, 101, 98, 111, 2, 195, 167, 18, 68, 32, 0, 8, 100, 105, 97, 118, 110, 101, 2, 195, 167, 18, 68, 32, 0, 8, 102, 2, 114, 118, 18, 68, 32, 0, 8, 104, 110, 111, 99, 101, 114, 2, 195, 167, 18, 68, 32, 0, 8, 108, 101, 98, 109, 101, 2, 122, 18, 66, 32, 0, 8, 109, 2, 116, 18, 68, 32, 0, 8, 109, 98, 117, 115, 2, 116, 18, 68, 32, 0, 8, 109, 101, 114, 2, 116, 18, 68, 32, 0, 8, 109, 111, 99, 2, 116, 18, 68, 32, 0, 8, 109, 111, 114, 112, 2, 116, 18, 68, 32, 0, 8, 109, 111, 114, 112, 109, 111, 99, 2, 116, 18, 68, 32, 0, 8, 111, 100, 97, 2, 195, 167, 18, 68, 32, 0, 8, 114, 97, 99, 2, 195, 167, 18, 68, 32, 0, 8, 114, 97, 108, 99, 115, 101, 2, 195, 167, 18, 68, 32, 0, 8, 114, 97, 112, 97, 101, 114, 2, 195, 167, 18, 68, 32, 0, 8, 114, 97, 112, 97, 115, 101, 100, 2, 195, 167, 18, 68, 32, 0, 8, 114, 97, 112, 109, 111, 99, 2, 195, 167, 18, 68, 32, 0, 8, 114, 99, 115, 101, 2, 118, 18, 68, 32, 0, 8, 114, 99, 115, 101, 100, 2, 118, 18, 68, 32, 0, 8, 114, 101, 102, 111, 2, 195, 167, 18, 68, 32, 0, 8, 114, 101, 109, 2, 195, 167, 18, 68, 32, 0, 8, 114, 101, 112, 2, 195, 167, 18, 68, 32, 0, 8, 114, 114, 101, 100, 2, 116, 18, 68, 32, 0, 8, 114, 114, 111, 98, 97, 2, 195, 167, 18, 68, 32, 0, 8, 114, 116, 97, 2, 118, 18, 68, 32, 0, 8, 116, 110, 111, 99, 97, 2, 195, 167, 18, 66, 32, 0, 8, 117, 113, 97, 2, 195, 167, 18, 68, 32, 0, 8, 117, 113, 97, 114, 102, 110, 101, 2, 195, 167, 18, 68, 32, 0, 8, 117, 113, 105, 114, 110, 101, 2, 195, 167, 18, 68, 32, 0, 8, 117, 113, 115, 101, 2, 195, 167, 18, 68, 32, 0, 8, 118, 110, 105, 2, 114, 116, 18, 68, 32, 0, 101, 120, 8, 114, 2, 17, 65, 3, 36, 36, 88, 0, 110, 104, 3, 36, 67, 0, 4, 5, 1, 1, 17, 67, 2, 97, 3, 37, 0, 5, 1, 1, 17, 67, 2, 195, 163, 0, 5, 1, 1, 17, 67, 2, 195, 186, 0, 5, 1, 2, 101, 0, 5, 1, 8, 2, 102, 0, 5, 1, 8, 110, 2, 110, 104, 117, 0, 5, 1, 1, 163, 195, 17, 67, 3, 57, 0, 115, 5, 1, 8, 2, 17, 67, 21, 21, 3, 91, 0, 4, 1, 98, 105, 2, 114, 17, 65, 32, 3, 109, 0, 1, 98, 105, 2, 114, 17, 65, 109, 32, 0, 1, 100, 2, 114, 17, 65, 32, 0, 1, 100, 2, 114, 17, 65, 109, 32, 0, 1, 105, 2, 114, 32, 0, 1, 106, 2, 116, 17, 65, 32, 0, 1, 106, 2, 116, 17, 65, 109, 32, 0, 1, 109, 2, 114, 17, 65, 32, 0, 1, 112, 115, 2, 114, 17, 65, 32, 0, 1, 112, 115, 2, 114, 17, 65, 109, 32, 0, 1, 115, 21, 2, 114, 17, 65, 32, 0, 1, 115, 21, 2, 114, 17, 65, 109, 32, 0, 1, 115, 21, 2, 114, 32, 0, 1, 117, 2, 114, 32, 0, 1, 117, 113, 2, 98, 114, 18, 69, 32, 0, 1, 118, 2, 108, 104, 17, 65, 32, 0, 1, 118, 105, 2, 114, 17, 65, 109, 32, 0, 2, 98, 101, 32, 0, 2, 98, 101, 109, 32, 0, 2, 99, 97, 32, 0, 2, 99, 101, 32, 0, 2, 99, 101, 109, 32, 0, 2, 99, 104, 17, 65, 32, 0, 2, 99, 104, 17, 65, 109, 32, 0, 2, 99, 108, 17, 65, 32, 0, 2, 99, 108, 17, 65, 109, 32, 0, 2, 99, 111, 32, 0, 2, 99, 116, 17, 65, 32, 0, 2, 99, 116, 17, 65, 109, 32, 0, 2, 100, 101, 32, 0, 2, 100, 101, 109, 32, 0, 2, 102, 97, 32, 0, 2, 103, 17, 65, 32, 0, 2, 103, 17, 65, 109, 32, 0, 2, 103, 114, 17, 65, 32, 0, 2, 103, 114, 17, 65, 109, 32, 0, 2, 103, 117, 101, 32, 0, 2, 103, 117, 101, 109, 32, 0, 2, 108, 17, 65, 32, 0, 2, 108, 17, 65, 109, 32, 0, 2, 114, 103, 17, 65, 32, 0, 2, 114, 103, 17, 65, 109, 32, 0, 2, 114, 110, 17, 65, 32, 0, 2, 114, 110, 17, 65, 109, 32, 0, 2, 114, 114, 17, 65, 32, 0, 2, 114, 114, 17, 65, 109, 32, 0, 2, 114, 114, 17, 65, 115, 32, 0, 2, 114, 115, 17, 65, 32, 0, 2, 114, 115, 17, 65, 109, 32, 0, 2, 114, 116, 17, 65, 32, 0, 2, 114, 116, 17, 65, 109, 32, 0, 2, 114, 118, 17, 65, 32, 0, 2, 114, 118, 17, 65, 109, 32, 0, 2, 115, 101, 32, 0, 2, 115, 101, 109, 32, 0, 2, 115, 115, 17, 65, 32, 0, 2, 115, 115, 17, 65, 109, 32, 0, 2, 115, 116, 17, 65, 32, 0, 2, 115, 116, 17, 65, 109, 32, 0, 2, 115, 116, 114, 17, 65, 32, 0, 2, 116, 17, 65, 32, 0, 2, 116, 17, 65, 109, 32, 0, 2, 118, 17, 65, 32, 0, 2, 118, 17, 65, 109, 32, 0, 2, 120, 17, 65, 32, 0, 2, 120, 17, 65, 109, 32, 0, 2, 120, 32, 0, 2, 195, 167, 17, 65, 32, 0, 2, 195, 167, 17, 65, 109, 32, 0, 5, 2, 8, 110, 2, 116, 0, 8, 2, 32, 0, 8, 98, 117, 111, 115, 2, 18, 70, 32, 0, 8, 99, 101, 100, 2, 112, 18, 69, 32, 0, 8, 103, 2, 114, 18, 69, 32, 0, 8, 103, 97, 120, 101, 2, 18, 70, 32, 0, 8, 108, 111, 115, 2, 116, 114, 18, 68, 32, 0, 8, 109, 2, 115, 99, 108, 18, 69, 32, 0, 8, 112, 2, 115, 99, 18, 68, 32, 0, 8, 112, 111, 2, 114, 18, 69, 32, 0, 8, 112, 115, 111, 104, 2, 100, 18, 68, 32, 0, 8, 114, 112, 2, 122, 18, 69, 32, 0, 8, 116, 108, 97, 2, 114, 18, 69, 32, 0, 8, 117, 113, 2, 114, 18, 69, 32, 0, 8, 118, 110, 105, 2, 106, 18, 69, 32, 0, 8, 118, 117, 111, 104, 2, 18, 70, 32, 0, 8, 122, 105, 102, 2, 18, 70, 32, 0, 4, 5, 1, 1, 99, 2, 114, 101, 97, 3, 112, 0, 5, 1, 1, 100, 2, 17, 67, 17, 65, 17, 65, 0, 5, 1, 1, 100, 2, 17, 67, 17, 65, 17, 67, 17, 65, 17, 65, 0, 5, 1, 1, 100, 2, 17, 67, 17, 65, 17, 67, 17, 65, 17, 67, 0, 5, 1, 1, 100, 2, 17, 67, 17, 65, 17, 67, 17, 67, 0, 5, 1, 1, 100, 2, 17, 67, 17, 67, 17, 65, 17, 65, 0, 5, 1, 1, 100, 2, 17, 67, 17, 67, 17, 65, 17, 67, 17, 65, 0, 5, 1, 1, 100, 2, 17, 67, 17, 67, 17, 65, 17, 67, 17, 67, 17, 65, 0, 5, 1, 1, 100, 2, 102, 105, 99, 105, 0, 5, 1, 1, 112, 2, 115, 115, 111, 97, 0, 5, 1, 1, 114, 2, 99, 111, 114, 0, 5, 1, 1, 114, 2, 108, 117, 122, 0, 5, 1, 1, 114, 2, 115, 109, 117, 110, 103, 0, 5, 1, 1, 114, 2, 115, 115, 0, 5, 1, 1, 114, 2, 118, 101, 108, 0, 5, 1, 1, 114, 2, 118, 111, 108, 118, 0, 5, 1, 1, 114, 112, 2, 99, 105, 115, 0, 5, 1, 1, 114, 112, 2, 102, 0, 5, 1, 8, 100, 2, 102, 105, 110, 105, 0, 5, 1, 8, 100, 2, 115, 108, 105, 103, 0, 5, 1, 8, 100, 2, 115, 108, 111, 99, 0, 5, 1, 8, 102, 2, 99, 104, 0, 5, 1, 8, 102, 2, 114, 114, 97, 109, 101, 110, 116, 97, 0, 5, 1, 8, 112, 2, 114, 99, 101, 110, 116, 97, 103, 0, 5, 1, 8, 112, 2, 115, 113, 117, 0, 5, 1, 8, 114, 2, 99, 105, 99, 108, 0, 5, 1, 8, 116, 2, 114, 109, 105, 110, 0, 5, 1, 8, 118, 2, 108, 111, 99, 105, 0, 4, 117, 3, 115, 0, 117, 2, 115, 0, 4, 105, 3, 118, 0, 105, 2, 115, 0, 121, 0, 109, 2, 17, 67, 3, 118, 65, 0, 110, 2, 25, 3, 118, 68, 0, 4, 105, 2, 28, 17, 3, 119, 0, 105, 8, 114, 116, 115, 101, 2, 18, 68, 32, 0, 108, 5, 2, 2, 25, 3, 137, 0, 7, 6, 102, 0, 2, 102, 3, 0, 8, 2, 32, 3, 6, 109, 83, 36, 0, 3, 83, 0, 5, 3, 2, 32, 17, 67, 3, 83, 10, 0, 5, 3, 2, 17, 66, 3, 83, 124, 0, 5, 1, 8, 2, 32, 3, 109, 83, 0, 5, 1, 8, 2, 32, 31, 3, 109, 83, 38, 0, 7, 6, 103, 0, 2, 103, 3, 0, 4, 3, 81, 0, 117, 2, 17, 71, 0, 117, 5, 1, 1, 110, 97, 109, 2, 101, 105, 0, 117, 5, 1, 2, 195, 169, 109, 32, 0, 5, 3, 2, 32, 17, 67, 3, 81, 10, 0, 5, 1, 8, 2, 32, 3, 81, 36, 0, 117, 5, 1, 1, 110, 2, 17, 65, 3, 81, 58, 0, 117, 101, 110, 5, 1, 2, 17, 67, 3, 81, 58, 6, 118, 68, 0, 5, 3, 2, 17, 66, 3, 81, 124, 0, 2, 17, 71, 3, 90, 0, 4, 5, 1, 8, 2, 32, 31, 3, 90, 36, 0, 8, 2, 32, 0, 7, 6, 104, 0, 3, 0, 8, 2, 32, 3, 35, 81, 6, 35, 0, 7, 6, 105, 0, 4, 2, 17, 65, 32, 3, 6, 37, 0, 2, 32, 0, 2, 97, 109, 32, 0, 5, 1, 8, 2, 110, 116, 101, 114, 110, 0, 4, 110, 103, 5, 1, 1, 21, 2, 32, 3, 21, 0, 110, 103, 115, 5, 1, 1, 21, 2, 32, 0, 4, 3, 37, 0, 1, 108, 17, 67, 0, 1, 114, 17, 67, 0, 2, 108, 104, 12, 0, 2, 111, 0, 2, 111, 17, 67, 25, 0, 2, 117, 17, 67, 25, 0, 8, 2, 32, 0, 109, 2, 17, 67, 3, 37, 65, 0, 110, 104, 3, 37, 67, 0, 4, 109, 2, 32, 3, 37, 68, 0, 109, 5, 4, 2, 17, 67, 0, 110, 2, 17, 67, 0, 110, 2, 103, 0, 110, 2, 107, 0, 4, 1, 17, 67, 17, 67, 161, 195, 2, 17, 65, 32, 3, 57, 0, 1, 17, 67, 17, 67, 162, 195, 2, 17, 65, 32, 0, 1, 17, 67, 17, 67, 169, 195, 2, 17, 65, 32, 0, 1, 17, 67, 17, 67, 170, 195, 2, 17, 65, 32, 0, 1, 17, 67, 17, 67, 173, 195, 2, 17, 65, 32, 0, 1, 17, 67, 17, 67, 179, 195, 2, 17, 65, 32, 0, 1, 17, 67, 17, 67, 180, 195, 2, 17, 65, 32, 0, 1, 17, 67, 17, 67, 186, 195, 2, 17, 65, 32, 0, 1, 17, 67, 161, 195, 2, 17, 65, 32, 0, 1, 17, 67, 162, 195, 2, 17, 65, 32, 0, 1, 17, 67, 169, 195, 2, 17, 65, 32, 0, 1, 17, 67, 170, 195, 2, 17, 65, 32, 0, 1, 17, 67, 173, 195, 2, 17, 65, 32, 0, 1, 17, 67, 179, 195, 2, 17, 65, 32, 0, 1, 17, 67, 180, 195, 2, 17, 65, 32, 0, 1, 17, 67, 186, 195, 2, 17, 65, 32, 0, 2, 17, 65, 0, 4, 108, 5, 2, 2, 25, 3, 116, 0, 111, 2, 32, 0, 111, 2, 115, 32, 0, 117, 2, 32, 0, 117, 2, 115, 32, 0, 7, 6, 106, 0, 3, 90, 0, 8, 2, 32, 3, 90, 6, 110, 47, 132, 0, 5, 3, 2, 32, 17, 67, 3, 90, 10, 0, 5, 3, 2, 17, 66, 3, 90, 124, 0, 7, 6, 107, 0, 2, 107, 3, 0, 4, 3, 49, 0, 5, 3, 2, 115, 0, 5, 3, 2, 116, 0, 5, 1, 8, 2, 32, 3, 49, 6, 35, 48, 132, 0, 5, 3, 2, 32, 17, 67, 3, 49, 10, 0, 5, 2, 8, 2, 32, 3, 49, 35, 0, 5, 3, 2, 17, 66, 3, 49, 124, 0, 7, 6, 108, 0, 1, 108, 3, 0, 8, 2, 32, 3, 6, 109, 55, 36, 0, 3, 55, 0, 104, 1, 17, 65, 3, 55, 57, 0, 4, 104, 3, 61, 0, 104, 5, 1, 1, 17, 65, 0, 104, 5, 4, 1, 17, 65, 0, 5, 1, 8, 2, 32, 3, 109, 55, 0, 5, 1, 8, 2, 32, 31, 3, 109, 55, 38, 0, 7, 6, 109, 0, 2, 109, 3, 0, 8, 2, 32, 3, 6, 36, 65, 36, 0, 3, 65, 0, 5, 3, 2, 32, 17, 67, 3, 65, 10, 0, 5, 3, 2, 17, 66, 3, 65, 124, 0, 5, 1, 8, 2, 32, 3, 109, 65, 0, 5, 1, 8, 2, 32, 31, 3, 109, 65, 38, 0, 7, 6, 110, 0, 2, 110, 3, 0, 8, 2, 32, 3, 6, 36, 50, 36, 0, 4, 3, 50, 0, 110, 5, 1, 1, 17, 65, 0, 5, 3, 2, 32, 17, 67, 3, 50, 10, 0, 5, 3, 2, 17, 66, 3, 50, 124, 0, 104, 3, 67, 0, 5, 1, 8, 2, 32, 3, 109, 50, 0, 5, 1, 8, 2, 32, 31, 3, 109, 50, 38, 0, 7, 6, 111, 0, 110, 1, 115, 21, 2, 32, 3, 2, 39, 68, 0, 5, 1, 2, 108, 32, 3, 6, 110, 0, 4, 1, 21, 2, 32, 3, 8, 111, 0, 2, 115, 32, 0, 4, 3, 39, 0, 1, 21, 21, 2, 114, 17, 65, 32, 0, 1, 98, 2, 114, 101, 32, 0, 1, 99, 2, 114, 101, 32, 0, 1, 99, 2, 114, 114, 18, 66, 32, 0, 1, 100, 2, 114, 101, 32, 0, 1, 108, 2, 114, 101, 32, 0, 1, 109, 2, 118, 97, 32, 0, 1, 109, 2, 118, 97, 109, 32, 0, 1, 116, 2, 100, 17, 65, 32, 0, 1, 116, 2, 114, 101, 32, 0, 1, 118, 2, 114, 101, 32, 0, 2, 105, 17, 67, 25, 0, 2, 108, 104, 0, 2, 109, 97, 32, 0, 2, 110, 97, 32, 0, 2, 114, 17, 67, 111, 32, 0, 2, 115, 111, 32, 24, 0, 2, 115, 116, 111, 32, 0, 8, 109, 2, 114, 114, 18, 66, 32, 0, 4, 111, 5, 1, 1, 17, 67, 2, 32, 3, 39, 58, 0, 117, 0, 109, 2, 17, 67, 3, 39, 65, 0, 110, 104, 3, 39, 67, 0, 4, 109, 2, 32, 3, 39, 68, 0, 109, 5, 4, 2, 17, 67, 0, 110, 2, 25, 0, 4, 5, 1, 1, 102, 2, 114, 109, 97, 116, 3, 40, 0, 5, 1, 1, 102, 2, 114, 109, 117, 108, 195, 161, 0, 5, 1, 1, 114, 112, 2, 102, 0, 5, 1, 1, 114, 114, 101, 116, 110, 105, 2, 103, 0, 5, 1, 8, 17, 67, 2, 17, 67, 17, 65, 17, 67, 17, 65, 17, 67, 0, 5, 1, 8, 112, 2, 114, 116, 117, 17, 67, 0, 5, 1, 8, 115, 2, 108, 117, 0, 4, 1, 98, 2, 114, 17, 65, 32, 3, 110, 0, 1, 112, 2, 100, 17, 65, 32, 0, 1, 112, 2, 100, 17, 65, 109, 32, 0, 2, 98, 114, 17, 65, 32, 0, 2, 98, 114, 17, 65, 109, 32, 0, 2, 99, 17, 65, 32, 0, 2, 99, 17, 65, 109, 32, 0, 2, 100, 17, 65, 32, 0, 2, 100, 17, 65, 109, 32, 0, 2, 103, 32, 0, 2, 103, 101, 32, 0, 2, 103, 101, 109, 32, 0, 2, 103, 115, 32, 0, 2, 106, 17, 65, 32, 0, 2, 106, 17, 65, 109, 32, 0, 2, 108, 17, 65, 32, 0, 2, 108, 17, 65, 109, 32, 0, 2, 108, 100, 17, 65, 32, 0, 2, 108, 100, 17, 65, 109, 32, 0, 2, 108, 116, 17, 65, 32, 0, 2, 108, 116, 17, 65, 109, 32, 0, 2, 112, 32, 0, 2, 113, 117, 101, 32, 0, 2, 113, 117, 101, 109, 32, 0, 2, 114, 17, 65, 32, 0, 2, 114, 17, 65, 109, 32, 0, 2, 114, 17, 67, 17, 65, 32, 0, 2, 114, 17, 67, 17, 65, 109, 32, 0, 2, 115, 17, 65, 32, 0, 2, 115, 17, 65, 109, 32, 0, 2, 115, 115, 17, 65, 32, 0, 2, 115, 115, 17, 65, 109, 32, 0, 2, 115, 116, 17, 65, 32, 0, 2, 115, 116, 17, 65, 109, 32, 0, 2, 115, 116, 114, 17, 65, 32, 0, 2, 115, 116, 114, 17, 65, 109, 32, 0, 2, 116, 17, 65, 32, 0, 2, 116, 17, 65, 109, 32, 0, 2, 118, 17, 65, 109, 32, 0, 2, 118, 97, 32, 0, 2, 118, 101, 17, 67, 115, 32, 0, 2, 118, 101, 32, 0, 2, 122, 101, 115, 32, 0, 5, 1, 1, 118, 2, 108, 116, 0, 5, 1, 8, 2, 17, 67, 0, 5, 2, 2, 120, 32, 0, 5, 2, 8, 2, 108, 104, 17, 65, 32, 0, 5, 2, 8, 2, 108, 104, 17, 65, 109, 32, 0, 8, 102, 101, 114, 2, 103, 18, 69, 32, 0, 8, 108, 103, 110, 101, 2, 98, 18, 66, 32, 0, 8, 109, 2, 108, 104, 18, 69, 32, 0, 8, 114, 2, 103, 18, 69, 32, 0, 8, 115, 98, 97, 2, 108, 118, 18, 67, 32, 0, 8, 118, 100, 97, 2, 103, 18, 69, 32, 0, 8, 118, 110, 101, 2, 108, 118, 18, 67, 32, 0, 108, 5, 2, 2, 32, 3, 110, 58, 0, 122, 5, 2, 2, 32, 3, 110, 88, 0, 115, 116, 111, 115, 1, 112, 2, 32, 3, 110, 89, 47, 8, 111, 138, 0, 122, 5, 1, 2, 32, 3, 110, 138, 0, 4, 105, 3, 120, 0, 105, 2, 115, 0, 4, 105, 2, 28, 17, 3, 136, 0, 105, 2, 97, 32, 0, 105, 2, 99, 17, 65, 32, 0, 105, 2, 100, 101, 32, 0, 105, 8, 112, 97, 2, 18, 66, 32, 0, 121, 0, 7, 6, 112, 0, 2, 112, 3, 0, 108, 101, 5, 1, 2, 32, 3, 21, 0, 4, 3, 48, 0, 5, 3, 2, 115, 0, 5, 3, 2, 116, 0, 5, 3, 2, 32, 17, 67, 3, 48, 10, 0, 8, 2, 32, 3, 48, 36, 0, 5, 3, 2, 17, 66, 3, 48, 124, 0, 104, 5, 1, 3, 83, 0, 7, 6, 113, 0, 4, 3, 49, 0, 117, 2, 17, 71, 0, 117, 101, 105, 5, 1, 8, 2, 17, 67, 3, 49, 6, 118, 0, 4, 8, 2, 32, 3, 49, 36, 0, 117, 101, 5, 1, 1, 17, 65, 2, 110, 17, 65, 32, 0, 117, 101, 5, 1, 2, 108, 0, 117, 101, 5, 1, 8, 0, 117, 101, 5, 2, 8, 2, 32, 25, 0, 117, 195, 170, 5, 1, 1, 17, 67, 2, 32, 0, 4, 117, 101, 99, 5, 1, 3, 49, 36, 89, 0, 117, 101, 195, 167, 5, 1, 0, 117, 105, 5, 1, 3, 49, 37, 0, 117, 2, 25, 3, 49, 40, 0, 117, 105, 5, 1, 1, 110, 97, 114, 116, 3, 49, 40, 37, 0, 117, 105, 110, 100, 5, 1, 8, 3, 49, 40, 37, 50, 72, 0, 117, 111, 5, 1, 8, 3, 49, 40, 39, 0, 4, 117, 3, 49, 58, 0, 195, 188, 0, 4, 117, 101, 110, 5, 1, 1, 17, 65, 2, 17, 67, 3, 49, 58, 6, 118, 68, 0, 117, 101, 110, 5, 1, 1, 17, 67, 2, 17, 67, 0, 117, 97, 5, 1, 8, 3, 49, 58, 35, 0, 117, 101, 5, 1, 2, 114, 32, 3, 49, 109, 0, 117, 101, 8, 2, 32, 3, 49, 112, 0, 5, 3, 2, 17, 66, 3, 49, 124, 0, 7, 6, 114, 0, 5, 1, 8, 2, 32, 3, 6, 109, 34, 34, 0, 5, 1, 8, 2, 32, 31, 3, 6, 109, 34, 34, 38, 0, 8, 2, 32, 3, 6, 109, 101, 36, 0, 4, 3, 16, 0, 1, 17, 65, 2, 17, 65, 0, 1, 17, 65, 2, 32, 17, 65, 0, 1, 17, 67, 2, 17, 65, 0, 2, 17, 67, 3, 16, 14, 0, 2, 32, 3, 34, 0, 5, 1, 1, 17, 65, 2, 32, 3, 44, 0, 1, 17, 67, 29, 2, 17, 65, 3, 51, 0, 4, 1, 108, 3, 101, 0, 1, 110, 2, 12, 0, 1, 115, 0, 8, 0, 114, 0, 8, 2, 32, 36, 3, 101, 36, 6, 114, 0, 7, 6, 115, 0, 5, 2, 8, 2, 32, 3, 6, 109, 89, 36, 0, 4, 1, 17, 65, 2, 17, 65, 3, 88, 0, 1, 17, 65, 2, 32, 17, 65, 14, 128, 128, 129, 0, 1, 21, 2, 32, 17, 65, 0, 5, 36, 1, 17, 65, 2, 32, 17, 70, 14, 128, 128, 129, 0, 5, 36, 1, 21, 2, 32, 17, 70, 0, 4, 3, 89, 0, 1, 17, 65, 2, 32, 14, 128, 128, 129, 0, 1, 101, 115, 101, 2, 32, 0, 99, 2, 17, 71, 0, 115, 0, 115, 5, 1, 1, 17, 65, 0, 195, 167, 0, 111, 98, 114, 101, 8, 2, 21, 14, 128, 132, 133, 3, 89, 39, 71, 16, 36, 0, 4, 5, 1, 1, 17, 65, 2, 17, 70, 12, 3, 90, 0, 5, 1, 1, 17, 65, 2, 32, 17, 70, 12, 14, 128, 128, 129, 0, 104, 3, 91, 0, 5, 1, 8, 2, 32, 3, 109, 89, 0, 5, 1, 8, 2, 32, 31, 3, 109, 89, 38, 0, 5, 4, 8, 2, 17, 67, 3, 124, 89, 0, 4, 5, 1, 1, 17, 65, 2, 17, 67, 3, 138, 0, 5, 1, 1, 17, 65, 2, 32, 25, 14, 128, 128, 129, 0, 5, 1, 1, 21, 2, 32, 0, 5, 2, 2, 32, 0, 7, 6, 116, 0, 2, 116, 3, 0, 4, 104, 5, 1, 3, 21, 0, 105, 111, 110, 5, 1, 2, 32, 0, 3, 47, 0, 5, 3, 2, 32, 17, 67, 3, 47, 10, 0, 8, 2, 32, 3, 47, 36, 0, 4, 5, 2, 2, 101, 32, 3, 76, 0, 5, 2, 2, 105, 0, 5, 2, 2, 195, 173, 0, 5, 3, 2, 17, 66, 3, 76, 124, 0, 7, 6, 117, 0, 1, 103, 2, 17, 71, 3, 0, 2, 17, 65, 32, 3, 6, 40, 0, 4, 3, 40, 0, 1, 114, 2, 17, 65, 0, 1, 114, 2, 32, 17, 65, 0, 2, 105, 17, 67, 25, 0, 8, 2, 32, 0, 4, 2, 17, 65, 3, 58, 0, 2, 32, 17, 65, 0, 2, 105, 117, 0, 4, 105, 3, 121, 0, 121, 0, 109, 2, 17, 67, 3, 128, 65, 0, 110, 104, 3, 128, 67, 0, 4, 109, 2, 32, 3, 128, 68, 0, 109, 5, 4, 2, 17, 67, 0, 110, 2, 25, 0, 7, 6, 118, 0, 2, 118, 3, 0, 3, 84, 0, 5, 3, 2, 32, 17, 67, 3, 84, 10, 0, 5, 3, 2, 17, 66, 3, 84, 124, 0, 7, 6, 119, 0, 5, 1, 2, 32, 3, 21, 0, 5, 4, 8, 3, 40, 0, 3, 58, 0, 5, 2, 8, 2, 32, 3, 72, 6, 35, 71, 55, 57, 40, 0, 5, 1, 8, 2, 32, 3, 72, 6, 132, 71, 55, 4, 37, 40, 0, 7, 6, 120, 0, 2, 115, 3, 0, 4, 1, 17, 65, 2, 17, 65, 3, 49, 89, 0, 1, 101, 2, 17, 65, 0, 2, 32, 0, 8, 111, 2, 105, 0, 8, 114, 97, 109, 0, 4, 2, 195, 179, 32, 3, 88, 0, 8, 101, 2, 17, 65, 0, 8, 101, 104, 2, 17, 65, 0, 8, 101, 110, 105, 2, 17, 65, 0, 8, 101, 111, 99, 2, 17, 65, 0, 8, 170, 195, 2, 17, 65, 0, 4, 1, 17, 65, 114, 112, 2, 105, 3, 89, 0, 1, 161, 195, 109, 2, 105, 109, 0, 2, 17, 67, 0, 8, 117, 97, 0, 8, 117, 111, 114, 116, 2, 101, 0, 99, 2, 17, 71, 0, 101, 8, 117, 111, 114, 116, 2, 21, 3, 89, 109, 0, 4, 1, 17, 65, 114, 98, 2, 17, 65, 3, 91, 0, 1, 17, 65, 120, 2, 17, 65, 0, 1, 17, 71, 98, 2, 17, 65, 0, 1, 97, 2, 97, 0, 1, 97, 2, 97, 114, 0, 1, 97, 2, 101, 105, 0, 1, 97, 2, 195, 161, 0, 1, 97, 108, 101, 114, 2, 17, 65, 0, 1, 97, 114, 103, 2, 17, 65, 0, 1, 101, 108, 97, 2, 97, 0, 1, 101, 109, 2, 17, 65, 0, 1, 105, 97, 2, 17, 65, 0, 1, 105, 101, 2, 17, 65, 0, 1, 105, 112, 2, 17, 65, 0, 1, 105, 114, 2, 17, 65, 0, 1, 105, 117, 113, 2, 17, 65, 0, 1, 111, 109, 2, 97, 0, 1, 117, 2, 105, 0, 1, 117, 97, 98, 2, 17, 65, 0, 1, 117, 111, 2, 12, 0, 1, 117, 112, 2, 17, 65, 0, 2, 17, 65, 0, 2, 17, 65, 120, 17, 65, 0, 2, 105, 113, 117, 0, 5, 1, 1, 101, 2, 17, 67, 17, 65, 0, 5, 1, 1, 105, 2, 97, 32, 0, 5, 1, 1, 105, 2, 97, 115, 32, 0, 8, 97, 99, 2, 17, 65, 0, 8, 97, 102, 2, 105, 0, 8, 97, 114, 112, 2, 17, 65, 0, 8, 101, 108, 102, 2, 97, 0, 8, 101, 118, 2, 17, 65, 0, 8, 105, 108, 2, 17, 65, 0, 8, 105, 120, 2, 17, 65, 0, 8, 111, 2, 17, 65, 0, 8, 111, 99, 2, 17, 65, 0, 8, 111, 114, 2, 17, 65, 0, 8, 111, 114, 112, 2, 17, 65, 0, 8, 117, 108, 2, 17, 65, 0, 8, 169, 195, 109, 2, 105, 0, 7, 6, 121, 0, 2, 32, 3, 2, 37, 0, 5, 1, 8, 2, 32, 3, 6, 37, 48, 89, 4, 37, 55, 110, 68, 0, 5, 2, 8, 2, 32, 3, 6, 37, 48, 89, 37, 55, 39, 68, 0, 3, 37, 0, 2, 17, 65, 3, 57, 0, 7, 6, 122, 0, 2, 122, 3, 0, 4, 3, 88, 0, 1, 21, 2, 32, 17, 65, 0, 1, 21, 2, 32, 17, 70, 0, 5, 3, 2, 32, 17, 67, 3, 88, 10, 0, 8, 2, 32, 3, 88, 36, 0, 5, 3, 2, 17, 66, 3, 88, 124, 0, 5, 2, 1, 21, 2, 32, 3, 89, 0, 4, 5, 1, 1, 17, 65, 2, 17, 70, 12, 3, 90, 0, 5, 1, 1, 17, 65, 2, 32, 17, 70, 12, 0, 4, 5, 1, 1, 17, 65, 2, 17, 67, 3, 91, 0, 5, 1, 1, 17, 65, 2, 32, 17, 67, 0, 5, 1, 1, 21, 2, 32, 0, 7, 6, 0, 36, 8, 32, 114, 3, 0, 194, 170, 1, 32, 15, 3, 2, 35, 0, 194, 186, 1, 32, 15, 3, 2, 39, 0, 4, 45, 1, 32, 17, 65, 2, 32, 15, 3, 10, 0, 45, 1, 32, 17, 67, 2, 32, 15, 0, 195, 188, 3, 40, 0, 45, 8, 32, 2, 32, 15, 3, 65, 6, 36, 50, 111, 89, 0, 44, 2, 15, 3, 84, 6, 37, 34, 81, 40, 55, 132, 0, 4, 195, 159, 3, 89, 0, 195, 167, 0, 36, 3, 89, 37, 83, 51, 6, 130, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts52 = FileInMemory_createWithData (18252, reinterpret_cast (&espeakdata_dicts52_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/pt_dict", U"pt"); Collection_addItem (me.peek(), espeakdata_dicts52.transfer()); static unsigned char espeakdata_dicts53_data[26886] = { 0, 4, 0, 0, 207, 91, 0, 0, 13, 138, 195, 174, 14, 3, 8, 5, 9, 5, 20, 21, 68, 13, 138, 195, 174, 14, 3, 1, 18, 3, 5, 18, 1, 68, 0, 17, 7, 20, 195, 162, 18, 26, 9, 21, 47, 112, 34, 88, 6, 37, 40, 0, 9, 134, 18, 196, 131, 7, 5, 20, 65, 6, 195, 61, 4, 137, 66, 9, 4, 95, 48, 15, 6, 72, 36, 0, 0, 0, 9, 198, 16, 85, 5, 72, 210, 78, 66, 0, 0, 13, 65, 4, 35, 123, 124, 0, 72, 81, 197, 163, 105, 32, 13, 65, 4, 35, 97, 124, 0, 72, 81, 197, 159, 105, 32, 6, 193, 4, 72, 28, 32, 0, 20, 71, 56, 144, 201, 16, 80, 213, 52, 50, 37, 76, 124, 72, 36, 49, 6, 40, 65, 0, 0, 0, 0, 21, 65, 8, 98, 117, 108, 101, 118, 97, 114, 100, 117, 108, 0, 44, 29, 81, 100, 117, 108, 32, 6, 65, 8, 71, 36, 0, 0, 12, 137, 195, 174, 14, 20, 9, 14, 4, 5, 13, 66, 0, 15, 67, 21, 64, 192, 101, 116, 99, 101, 116, 101, 114, 97, 0, 29, 0, 11, 67, 53, 82, 65, 65, 6, 40, 57, 35, 0, 7, 196, 77, 80, 197, 4, 66, 7, 196, 49, 80, 197, 4, 66, 7, 196, 17, 80, 197, 4, 66, 6, 195, 84, 225, 5, 28, 0, 8, 197, 88, 150, 129, 88, 144, 67, 8, 197, 36, 81, 148, 36, 224, 65, 8, 197, 16, 144, 86, 60, 192, 65, 8, 197, 12, 149, 137, 48, 80, 66, 12, 65, 12, 49, 35, 34, 0, 72, 81, 97, 114, 32, 10, 65, 12, 49, 39, 0, 72, 81, 111, 32, 6, 65, 12, 76, 36, 0, 0, 12, 201, 65, 33, 84, 85, 66, 78, 16, 83, 137, 67, 9, 198, 4, 115, 206, 37, 50, 64, 68, 0, 11, 136, 16, 196, 131, 19, 20, 18, 196, 131, 66, 11, 136, 9, 13, 1, 7, 9, 14, 196, 131, 67, 9, 198, 16, 84, 198, 84, 225, 1, 67, 9, 198, 16, 81, 197, 56, 84, 129, 68, 9, 198, 12, 243, 134, 84, 225, 1, 67, 11, 136, 22, 15, 1, 19, 20, 18, 196, 131, 76, 11, 136, 14, 15, 1, 19, 20, 18, 196, 131, 77, 11, 136, 22, 15, 1, 19, 20, 18, 196, 131, 77, 13, 4, 95, 8, 1, 3, 107, 6, 35, 76, 36, 49, 0, 0, 11, 200, 65, 35, 212, 60, 51, 193, 48, 80, 67, 11, 67, 53, 82, 69, 65, 6, 40, 57, 36, 0, 0, 18, 8, 195, 174, 14, 3, 8, 5, 9, 1, 112, 50, 49, 36, 6, 57, 35, 0, 6, 65, 16, 72, 36, 0, 0, 21, 9, 22, 5, 197, 159, 14, 9, 3, 9, 5, 84, 36, 91, 50, 37, 76, 6, 37, 36, 0, 10, 135, 16, 195, 162, 14, 20, 5, 3, 65, 20, 9, 195, 174, 14, 1, 9, 14, 20, 5, 1, 112, 50, 35, 6, 37, 50, 47, 135, 0, 21, 9, 8, 196, 131, 18, 14, 9, 3, 9, 5, 107, 13, 34, 50, 37, 76, 6, 37, 36, 0, 0, 23, 10, 6, 9, 5, 11, 196, 131, 18, 21, 9, 1, 83, 57, 36, 80, 6, 13, 34, 121, 35, 0, 76, 0, 9, 134, 26, 1, 8, 196, 131, 18, 65, 12, 137, 3, 12, 196, 131, 20, 9, 14, 196, 131, 67, 14, 139, 195, 174, 14, 7, 8, 9, 15, 14, 20, 5, 1, 67, 10, 135, 7, 195, 162, 14, 4, 5, 1, 66, 0, 8, 197, 12, 147, 133, 88, 16, 67, 6, 65, 20, 36, 0, 14, 7, 65, 20, 57, 36, 0, 72, 17, 142, 4, 21, 13, 14, 5, 1, 22, 15, 1, 19, 20, 18, 196, 131, 79, 0, 14, 5, 20, 18, 196, 131, 9, 47, 14, 16, 13, 6, 37, 0, 29, 13, 16, 18, 5, 197, 159, 5, 4, 9, 14, 197, 163, 9, 5, 48, 14, 16, 36, 91, 36, 72, 37, 50, 123, 6, 37, 36, 0, 0, 9, 198, 76, 84, 150, 36, 50, 73, 66, 10, 199, 5, 34, 9, 80, 80, 212, 84, 68, 9, 198, 4, 197, 3, 84, 149, 129, 67, 9, 198, 4, 115, 206, 37, 49, 65, 68, 9, 134, 1, 197, 159, 5, 26, 1, 67, 0, 14, 139, 1, 12, 1, 12, 20, 196, 131, 9, 5, 18, 9, 66, 10, 135, 19, 5, 13, 196, 131, 14, 1, 67, 0, 8, 197, 72, 85, 133, 56, 144, 67, 6, 65, 24, 83, 36, 0, 0, 0, 9, 134, 3, 5, 18, 197, 159, 9, 66, 0, 11, 200, 65, 35, 198, 21, 51, 210, 36, 144, 66, 7, 196, 5, 64, 67, 4, 67, 0, 8, 197, 89, 82, 69, 80, 80, 65, 8, 197, 76, 83, 69, 56, 80, 65, 8, 197, 16, 81, 137, 56, 144, 67, 16, 69, 61, 34, 67, 84, 208, 39, 16, 124, 49, 4, 40, 65, 0, 76, 8, 132, 1, 197, 159, 1, 66, 28, 6, 65, 28, 75, 36, 0, 0, 12, 137, 5, 24, 16, 12, 15, 18, 196, 131, 13, 67, 0, 13, 138, 3, 15, 12, 1, 2, 15, 18, 196, 131, 13, 68, 9, 198, 72, 81, 197, 56, 84, 129, 68, 0, 7, 196, 64, 19, 9, 16, 65, 11, 67, 4, 99, 1, 35, 83, 55, 6, 35, 0, 0, 7, 65, 32, 107, 35, 91, 0, 0, 12, 137, 195, 174, 14, 22, 195, 162, 18, 20, 9, 67, 0, 19, 70, 76, 84, 150, 36, 50, 85, 89, 36, 34, 84, 6, 37, 76, 6, 57, 40, 0, 0, 15, 67, 12, 20, 133, 49, 35, 34, 36, 55, 0, 72, 81, 108, 32, 7, 195, 12, 20, 133, 73, 28, 10, 1, 35, 72, 57, 6, 36, 88, 0, 27, 0, 11, 65, 36, 57, 117, 0, 72, 81, 97, 105, 32, 12, 65, 36, 57, 35, 65, 0, 72, 81, 97, 109, 32, 13, 65, 36, 37, 35, 91, 0, 72, 81, 97, 197, 159, 32, 12, 65, 36, 57, 35, 34, 0, 72, 81, 97, 114, 32, 0, 0, 10, 67, 4, 84, 128, 6, 117, 36, 34, 0, 6, 195, 48, 244, 128, 76, 13, 1, 38, 35, 65, 48, 36, 34, 89, 35, 50, 72, 0, 0, 10, 135, 15, 2, 197, 163, 9, 14, 21, 67, 10, 135, 7, 196, 131, 12, 2, 21, 9, 66, 10, 67, 4, 99, 9, 35, 83, 55, 37, 0, 0, 6, 65, 40, 90, 36, 0, 0, 17, 70, 52, 19, 129, 28, 84, 128, 65, 6, 36, 50, 36, 75, 13, 34, 0, 6, 131, 22, 196, 131, 72, 9, 198, 4, 49, 83, 80, 244, 128, 78, 0, 9, 198, 88, 240, 201, 24, 84, 129, 68, 15, 6, 4, 196, 131, 18, 21, 9, 72, 13, 16, 58, 6, 37, 0, 9, 198, 4, 49, 83, 80, 244, 129, 78, 13, 1, 42, 35, 89, 47, 36, 16, 37, 89, 49, 0, 27, 0, 14, 139, 4, 5, 19, 3, 8, 9, 4, 5, 197, 163, 9, 66, 9, 1, 43, 48, 55, 40, 89, 0, 27, 0, 15, 140, 3, 21, 14, 15, 1, 197, 159, 20, 5, 197, 163, 9, 66, 6, 65, 44, 49, 35, 0, 0, 10, 135, 4, 15, 13, 9, 14, 196, 131, 65, 12, 137, 3, 15, 14, 3, 21, 18, 196, 131, 13, 67, 16, 70, 8, 195, 199, 28, 84, 128, 71, 55, 6, 39, 81, 13, 34, 0, 0, 11, 136, 5, 12, 9, 13, 9, 14, 196, 131, 66, 15, 6, 16, 196, 131, 12, 5, 1, 48, 35, 55, 36, 6, 35, 0, 9, 198, 48, 81, 201, 24, 84, 129, 68, 9, 198, 16, 83, 9, 8, 84, 129, 68, 10, 1, 46, 48, 40, 50, 49, 47, 0, 27, 0, 9, 134, 19, 21, 6, 196, 131, 18, 65, 8, 1, 47, 89, 55, 36, 91, 0, 0, 10, 135, 20, 195, 162, 14, 196, 131, 18, 65, 13, 65, 48, 55, 35, 91, 0, 72, 81, 97, 197, 159, 32, 12, 65, 48, 55, 35, 34, 0, 72, 81, 97, 114, 32, 12, 65, 48, 55, 39, 34, 0, 72, 81, 111, 114, 32, 11, 65, 48, 55, 117, 0, 72, 81, 97, 105, 32, 15, 65, 48, 55, 35, 141, 124, 0, 72, 81, 97, 197, 163, 105, 32, 12, 65, 48, 55, 35, 65, 0, 72, 81, 97, 109, 32, 11, 65, 48, 55, 114, 0, 72, 81, 97, 117, 32, 10, 65, 48, 55, 35, 0, 72, 81, 97, 32, 18, 8, 14, 15, 21, 196, 131, 12, 5, 1, 50, 6, 39, 40, 13, 55, 135, 0, 0, 10, 135, 4, 196, 131, 21, 14, 196, 131, 67, 10, 135, 3, 195, 162, 14, 20, 5, 3, 65, 12, 137, 18, 196, 131, 19, 3, 15, 12, 5, 1, 67, 0, 11, 136, 13, 9, 197, 159, 21, 14, 196, 131, 65, 10, 199, 24, 147, 15, 104, 241, 137, 36, 68, 13, 138, 195, 174, 14, 22, 195, 162, 18, 20, 5, 1, 67, 0, 9, 198, 16, 148, 133, 13, 67, 210, 66, 0, 8, 197, 48, 245, 137, 81, 80, 67, 12, 65, 52, 65, 35, 91, 0, 72, 81, 97, 83, 32, 12, 65, 52, 65, 35, 34, 0, 72, 81, 97, 114, 32, 12, 65, 52, 65, 39, 34, 0, 72, 81, 111, 114, 32, 8, 197, 72, 81, 201, 104, 16, 67, 0, 12, 137, 197, 159, 1, 16, 20, 5, 12, 5, 1, 65, 0, 13, 138, 195, 174, 14, 6, 12, 15, 18, 9, 20, 21, 68, 12, 137, 4, 5, 19, 3, 15, 16, 196, 131, 18, 66, 0, 10, 135, 6, 18, 195, 162, 14, 20, 21, 66, 0, 8, 197, 72, 84, 5, 104, 144, 65, 8, 197, 64, 19, 9, 104, 144, 65, 8, 197, 56, 85, 5, 16, 80, 65, 8, 197, 52, 241, 5, 48, 80, 66, 12, 65, 56, 50, 39, 34, 0, 72, 81, 111, 114, 32, 12, 65, 56, 50, 39, 34, 0, 72, 81, 111, 114, 32, 10, 65, 56, 50, 35, 0, 72, 81, 97, 32, 13, 65, 56, 50, 35, 91, 0, 72, 81, 97, 197, 159, 32, 10, 65, 56, 50, 39, 0, 72, 81, 111, 32, 8, 197, 16, 81, 197, 72, 16, 67, 8, 197, 13, 80, 197, 72, 144, 67, 11, 136, 195, 174, 14, 19, 21, 197, 159, 9, 77, 11, 5, 95, 48, 1, 14, 4, 10, 91, 37, 0, 0, 8, 133, 21, 18, 196, 131, 13, 66, 11, 136, 197, 163, 5, 1, 16, 196, 131, 14, 65, 0, 9, 198, 48, 240, 193, 48, 150, 129, 68, 0, 0, 8, 197, 53, 81, 197, 80, 80, 65, 11, 136, 2, 21, 3, 21, 18, 196, 131, 13, 67, 11, 136, 1, 4, 13, 9, 18, 196, 131, 13, 67, 18, 8, 14, 9, 13, 196, 131, 14, 21, 9, 50, 37, 65, 13, 50, 6, 121, 0, 4, 193, 60, 72, 4, 193, 60, 72, 0, 11, 136, 26, 4, 18, 1, 22, 196, 131, 14, 65, 12, 137, 195, 174, 14, 3, 21, 18, 1, 10, 1, 68, 10, 1, 61, 36, 81, 6, 35, 55, 0, 27, 0, 13, 138, 1, 12, 196, 131, 20, 21, 18, 196, 131, 13, 68, 0, 6, 195, 16, 244, 137, 66, 0, 11, 136, 14, 196, 131, 22, 196, 131, 12, 9, 67, 9, 134, 8, 15, 12, 2, 196, 131, 66, 10, 1, 64, 35, 16, 6, 39, 50, 72, 0, 6, 65, 64, 48, 36, 0, 0, 0, 9, 198, 5, 98, 67, 84, 197, 21, 68, 0, 7, 196, 21, 64, 76, 4, 67, 0, 7, 65, 68, 49, 57, 40, 0, 0, 8, 133, 19, 196, 131, 16, 1, 66, 9, 198, 12, 19, 3, 84, 192, 64, 67, 0, 9, 134, 3, 195, 162, 18, 13, 9, 66, 18, 70, 16, 83, 193, 72, 80, 197, 72, 36, 138, 34, 36, 76, 6, 36, 0, 8, 6, 195, 84, 224, 64, 77, 0, 7, 196, 61, 48, 193, 72, 65, 7, 196, 36, 193, 143, 88, 65, 6, 195, 84, 225, 73, 73, 0, 8, 197, 80, 84, 141, 36, 224, 65, 8, 197, 24, 245, 2, 4, 192, 65, 8, 197, 8, 20, 141, 4, 224, 65, 11, 136, 6, 18, 5, 13, 196, 131, 20, 1, 67, 6, 65, 72, 34, 36, 0, 0, 12, 137, 195, 174, 14, 7, 8, 9, 197, 163, 9, 67, 6, 194, 5, 32, 76, 32, 0, 0, 7, 196, 64, 241, 5, 4, 66, 7, 196, 77, 81, 197, 4, 66, 0, 8, 197, 72, 81, 213, 48, 144, 65, 11, 136, 4, 9, 19, 20, 18, 196, 131, 13, 66, 8, 197, 12, 195, 195, 61, 64, 65, 10, 65, 76, 89, 39, 0, 72, 81, 111, 32, 12, 65, 76, 89, 39, 34, 0, 72, 81, 111, 114, 32, 12, 65, 76, 89, 35, 34, 0, 72, 81, 97, 114, 32, 0, 18, 70, 77, 0, 78, 36, 243, 5, 89, 48, 35, 50, 37, 6, 39, 55, 36, 0, 12, 137, 16, 196, 131, 19, 20, 18, 196, 131, 13, 66, 9, 134, 3, 1, 16, 196, 131, 20, 65, 17, 70, 5, 4, 143, 64, 244, 192, 35, 48, 14, 16, 39, 48, 6, 39, 0, 0, 10, 199, 77, 80, 133, 77, 66, 77, 4, 68, 10, 199, 65, 33, 76, 84, 225, 197, 4, 67, 18, 70, 12, 243, 148, 36, 229, 65, 49, 39, 50, 47, 37, 50, 58, 6, 35, 0, 0, 7, 196, 12, 17, 133, 4, 66, 7, 196, 89, 35, 201, 4, 66, 0, 11, 136, 26, 1, 18, 26, 196, 131, 18, 9, 65, 8, 197, 76, 84, 150, 21, 32, 65, 11, 136, 16, 196, 131, 19, 196, 131, 18, 9, 65, 6, 65, 80, 47, 36, 0, 0, 9, 198, 25, 32, 71, 20, 65, 64, 65, 0, 0, 7, 196, 65, 34, 86, 36, 67, 0, 0, 12, 67, 85, 0, 192, 40, 48, 36, 76, 6, 36, 0, 0, 12, 137, 16, 196, 131, 19, 20, 18, 196, 131, 22, 65, 16, 141, 195, 174, 14, 3, 196, 131, 16, 5, 18, 9, 12, 15, 18, 67, 9, 134, 196, 131, 12, 15, 18, 1, 77, 0, 10, 135, 20, 1, 2, 196, 131, 18, 1, 65, 6, 195, 48, 245, 137, 66, 0, 19, 8, 19, 16, 21, 14, 5, 197, 163, 9, 89, 48, 6, 40, 50, 36, 123, 124, 0, 16, 69, 21, 131, 212, 36, 48, 36, 81, 88, 6, 39, 47, 37, 49, 0, 13, 65, 88, 84, 35, 91, 0, 72, 81, 97, 197, 159, 32, 12, 65, 88, 84, 35, 34, 0, 72, 81, 97, 114, 32, 7, 193, 88, 72, 81, 111, 32, 12, 65, 88, 84, 35, 65, 0, 72, 81, 97, 109, 32, 11, 65, 88, 84, 114, 0, 72, 81, 97, 117, 32, 15, 65, 88, 84, 35, 141, 124, 0, 72, 81, 97, 197, 163, 105, 32, 8, 197, 81, 33, 67, 20, 16, 66, 8, 197, 12, 243, 147, 80, 16, 66, 11, 136, 16, 196, 131, 18, 196, 131, 19, 9, 67, 11, 136, 195, 174, 14, 19, 21, 197, 163, 9, 77, 6, 65, 88, 84, 36, 0, 0, 8, 133, 16, 196, 131, 20, 21, 65, 9, 198, 16, 83, 211, 20, 34, 64, 67, 6, 194, 5, 48, 76, 32, 0, 9, 134, 20, 196, 131, 18, 9, 9, 65, 13, 138, 18, 5, 197, 163, 9, 14, 5, 197, 163, 9, 66, 10, 199, 17, 84, 133, 72, 147, 15, 72, 66, 0, 14, 139, 18, 196, 131, 13, 195, 162, 14, 5, 197, 163, 9, 66, 7, 196, 52, 243, 9, 52, 65, 10, 135, 12, 1, 7, 196, 131, 18, 5, 65, 14, 68, 29, 33, 79, 36, 81, 14, 16, 36, 6, 39, 57, 0, 7, 196, 17, 80, 197, 52, 65, 10, 135, 3, 196, 131, 18, 15, 18, 1, 73, 10, 135, 3, 196, 131, 18, 15, 18, 1, 73, 17, 4, 95, 49, 77, 52, 6, 40, 50, 71, 37, 55, 6, 57, 39, 50, 0, 0, 9, 198, 76, 147, 66, 60, 194, 67, 66, 8, 197, 13, 33, 83, 13, 80, 66, 18, 4, 95, 49, 77, 53, 6, 40, 50, 71, 37, 55, 6, 57, 35, 34, 72, 0, 12, 65, 92, 72, 40, 71, 55, 40, 6, 84, 36, 0, 0, 12, 137, 1, 12, 5, 18, 7, 196, 131, 20, 21, 68, 0, 0, 7, 196, 52, 147, 137, 52, 65, 14, 139, 195, 174, 14, 6, 21, 14, 4, 196, 131, 20, 21, 68, 14, 139, 195, 174, 14, 3, 21, 18, 3, 196, 131, 20, 21, 68, 0, 13, 4, 95, 49, 77, 49, 4, 39, 65, 6, 37, 36, 0, 7, 65, 96, 37, 49, 89, 0, 0, 11, 136, 197, 159, 13, 5, 3, 8, 5, 18, 65, 17, 4, 95, 49, 77, 50, 6, 40, 50, 65, 37, 55, 6, 57, 39, 50, 0, 0, 9, 198, 52, 146, 140, 60, 16, 197, 65, 6, 195, 84, 229, 76, 77, 18, 4, 95, 49, 77, 51, 6, 40, 50, 65, 37, 55, 6, 57, 35, 34, 72, 0, 0, 7, 196, 48, 144, 133, 72, 65, 7, 196, 65, 33, 68, 4, 66, 11, 67, 53, 84, 137, 65, 40, 34, 6, 37, 0, 0, 11, 136, 16, 195, 162, 14, 20, 5, 3, 5, 65, 10, 65, 100, 6, 37, 81, 34, 36, 49, 0, 0, 0, 6, 195, 5, 84, 128, 65, 9, 134, 8, 196, 131, 3, 21, 9, 67, 0, 7, 196, 80, 83, 137, 76, 65, 12, 68, 80, 19, 148, 36, 47, 35, 50, 47, 37, 0, 6, 195, 84, 229, 73, 73, 0, 11, 136, 1, 12, 5, 7, 5, 197, 163, 9, 66, 7, 65, 104, 88, 36, 47, 0, 0, 12, 137, 19, 195, 162, 13, 2, 196, 131, 20, 1, 65, 9, 198, 64, 243, 9, 80, 144, 192, 66, 8, 133, 2, 15, 197, 163, 9, 66, 8, 133, 196, 131, 19, 20, 1, 77, 0, 9, 198, 77, 68, 133, 13, 84, 129, 67, 0, 7, 196, 76, 17, 5, 4, 66, 7, 196, 88, 81, 5, 4, 66, 7, 196, 25, 81, 197, 4, 66, 0, 11, 136, 197, 159, 15, 1, 18, 5, 3, 9, 65, 8, 197, 25, 83, 7, 21, 32, 65, 0, 16, 141, 195, 174, 14, 197, 163, 5, 12, 5, 7, 5, 197, 163, 9, 67, 12, 137, 195, 174, 13, 2, 195, 162, 3, 19, 9, 67, 0, 0, 0, 8, 197, 53, 83, 20, 61, 32, 73, 0, 9, 198, 64, 20, 148, 20, 225, 64, 67, 14, 5, 5, 197, 159, 20, 9, 57, 36, 91, 47, 124, 0, 76, 5, 194, 12, 16, 72, 0, 15, 140, 195, 174, 14, 20, 195, 162, 13, 16, 9, 14, 196, 131, 66, 0, 7, 196, 76, 19, 22, 4, 66, 10, 135, 1, 3, 5, 197, 159, 20, 9, 72, 0, 8, 197, 48, 147, 135, 20, 16, 66, 8, 132, 1, 197, 163, 9, 76, 32, 0, 9, 198, 65, 35, 214, 20, 226, 64, 67, 12, 137, 1, 4, 196, 131, 16, 15, 19, 20, 9, 68, 0, 10, 199, 77, 84, 5, 73, 98, 90, 4, 68, 0, 7, 196, 53, 81, 213, 72, 65, 10, 135, 6, 1, 3, 5, 197, 163, 9, 65, 10, 135, 4, 21, 3, 5, 197, 163, 9, 65, 0, 11, 136, 20, 18, 1, 7, 5, 197, 163, 9, 65, 11, 136, 15, 1, 19, 16, 5, 197, 163, 9, 65, 11, 136, 8, 1, 9, 4, 5, 197, 163, 9, 65, 11, 136, 3, 18, 5, 4, 5, 197, 163, 9, 65, 11, 136, 1, 4, 21, 3, 5, 197, 163, 9, 66, 11, 136, 195, 174, 14, 3, 1, 18, 14, 1, 67, 11, 136, 195, 174, 14, 20, 5, 197, 163, 9, 67, 11, 136, 19, 21, 14, 20, 5, 197, 163, 9, 77, 0, 12, 137, 197, 163, 1, 14, 4, 196, 131, 18, 1, 65, 12, 137, 4, 5, 4, 21, 3, 5, 197, 163, 9, 66, 5, 194, 5, 80, 76, 0, 13, 138, 16, 18, 15, 1, 19, 16, 5, 197, 163, 9, 65, 13, 138, 16, 18, 5, 6, 1, 3, 5, 197, 163, 9, 66, 13, 138, 3, 18, 5, 197, 159, 20, 5, 197, 163, 9, 65, 0, 13, 68, 88, 243, 21, 52, 84, 39, 55, 6, 40, 65, 0, 0, 11, 136, 12, 21, 3, 18, 196, 131, 20, 21, 67, 0, 8, 133, 16, 196, 131, 19, 1, 66, 0, 13, 138, 22, 9, 14, 15, 22, 196, 131, 197, 163, 9, 20, 13, 138, 14, 21, 13, 196, 131, 18, 196, 131, 20, 21, 68, 0, 14, 139, 22, 196, 131, 20, 196, 131, 13, 196, 131, 20, 21, 68, 11, 200, 64, 244, 148, 60, 48, 76, 37, 80, 68, 9, 134, 16, 196, 131, 3, 21, 18, 65, 15, 139, 3, 21, 13, 16, 196, 131, 18, 196, 131, 20, 21, 67, 18, 0, 15, 140, 26, 4, 18, 21, 14, 3, 9, 14, 196, 131, 20, 21, 68, 11, 136, 197, 159, 15, 1, 18, 5, 3, 5, 65, 15, 140, 16, 9, 5, 16, 20, 196, 131, 14, 196, 131, 20, 21, 68, 11, 136, 195, 174, 14, 3, 8, 5, 7, 1, 67, 0, 0, 9, 134, 18, 195, 162, 14, 10, 9, 66, 0, 11, 67, 48, 147, 9, 55, 6, 37, 55, 37, 0, 7, 196, 80, 84, 212, 4, 66, 10, 135, 1, 7, 196, 131, 197, 163, 1, 67, 0, 8, 197, 25, 32, 71, 20, 64, 65, 0, 20, 145, 195, 174, 14, 20, 18, 5, 4, 5, 19, 3, 8, 9, 26, 196, 131, 20, 21, 70, 9, 198, 24, 197, 73, 21, 32, 64, 67, 9, 198, 20, 229, 77, 21, 32, 64, 68, 0, 0, 0, 0, 8, 133, 16, 196, 131, 18, 21, 66, 9, 198, 52, 244, 195, 61, 96, 64, 65, 9, 198, 65, 35, 205, 61, 96, 64, 67, 9, 198, 12, 243, 131, 85, 32, 64, 67, 0, 11, 136, 3, 18, 9, 22, 196, 131, 197, 163, 65, 0, 14, 139, 19, 21, 19, 197, 163, 9, 14, 5, 197, 163, 9, 66, 14, 139, 13, 5, 14, 197, 163, 9, 14, 5, 197, 163, 9, 66, 8, 133, 4, 21, 16, 196, 131, 28, 0, 8, 197, 76, 147, 135, 85, 32, 65, 8, 197, 12, 19, 131, 21, 32, 65, 0, 14, 139, 9, 14, 20, 5, 18, 19, 5, 3, 20, 196, 131, 67, 9, 198, 36, 81, 148, 36, 225, 64, 65, 9, 198, 24, 197, 73, 21, 33, 64, 65, 12, 137, 195, 174, 14, 19, 196, 131, 197, 159, 9, 77, 0, 13, 138, 20, 15, 22, 1, 18, 196, 131, 197, 159, 9, 66, 11, 136, 3, 195, 162, 14, 5, 16, 196, 131, 65, 9, 134, 3, 196, 131, 26, 14, 9, 66, 0, 12, 67, 13, 33, 65, 49, 14, 16, 36, 6, 35, 0, 6, 195, 5, 97, 65, 78, 10, 135, 196, 131, 19, 20, 5, 9, 1, 77, 0, 0, 9, 198, 76, 147, 135, 85, 33, 64, 65, 0, 13, 138, 197, 163, 196, 131, 14, 4, 196, 131, 18, 9, 65, 13, 138, 3, 196, 131, 19, 196, 131, 20, 15, 18, 9, 68, 7, 195, 61, 34, 64, 72, 8, 0, 7, 196, 92, 80, 133, 72, 65, 11, 200, 56, 244, 212, 36, 210, 76, 61, 32, 65, 6, 195, 5, 97, 77, 76, 0, 8, 197, 52, 84, 135, 20, 16, 66, 0, 9, 198, 16, 144, 86, 60, 194, 64, 65, 0, 6, 195, 37, 98, 64, 66, 17, 6, 3, 196, 131, 20, 18, 5, 49, 6, 13, 47, 14, 16, 36, 0, 28, 0, 12, 137, 20, 15, 22, 1, 18, 196, 131, 197, 159, 66, 11, 200, 64, 20, 148, 20, 225, 82, 20, 144, 67, 0, 8, 197, 76, 19, 20, 20, 16, 66, 16, 69, 61, 32, 78, 28, 80, 6, 39, 14, 16, 37, 50, 75, 124, 0, 8, 197, 53, 86, 137, 12, 16, 65, 8, 197, 77, 83, 148, 20, 208, 77, 0, 0, 10, 199, 16, 83, 79, 57, 53, 18, 4, 67, 0, 12, 137, 197, 163, 1, 14, 197, 163, 15, 197, 159, 65, 10, 135, 16, 9, 3, 196, 131, 20, 21, 67, 13, 68, 52, 81, 9, 84, 65, 6, 36, 72, 57, 40, 0, 10, 135, 12, 5, 7, 196, 131, 20, 21, 67, 6, 195, 80, 19, 5, 77, 0, 8, 197, 24, 145, 82, 81, 80, 66, 11, 136, 1, 16, 21, 3, 196, 131, 20, 21, 68, 8, 197, 37, 160, 149, 80, 144, 67, 12, 137, 3, 5, 12, 196, 131, 12, 1, 12, 20, 79, 0, 12, 137, 21, 18, 26, 9, 3, 196, 131, 20, 21, 68, 12, 137, 1, 18, 21, 14, 3, 196, 131, 20, 21, 68, 0, 13, 138, 8, 21, 18, 4, 21, 3, 196, 131, 20, 21, 68, 13, 138, 1, 12, 21, 14, 5, 3, 196, 131, 20, 21, 68, 9, 134, 16, 18, 196, 131, 10, 9, 66, 0, 10, 135, 14, 5, 3, 196, 131, 10, 9, 67, 14, 139, 195, 174, 14, 18, 5, 7, 9, 19, 20, 18, 1, 68, 0, 15, 140, 195, 174, 14, 3, 18, 5, 14, 7, 196, 131, 20, 21, 68, 15, 140, 195, 174, 14, 3, 196, 131, 18, 3, 196, 131, 20, 21, 68, 11, 136, 195, 174, 13, 16, 12, 9, 14, 9, 67, 0, 0, 0, 12, 68, 100, 18, 15, 60, 57, 35, 107, 6, 40, 0, 9, 134, 197, 159, 21, 9, 5, 18, 65, 9, 198, 64, 20, 148, 20, 225, 82, 67, 7, 196, 65, 84, 148, 4, 66, 7, 196, 5, 1, 76, 4, 67, 17, 7, 22, 15, 197, 159, 20, 18, 9, 84, 39, 91, 47, 16, 37, 0, 77, 17, 7, 14, 15, 197, 159, 20, 18, 9, 50, 39, 91, 47, 16, 37, 0, 77, 0, 19, 70, 36, 229, 5, 73, 5, 83, 37, 50, 47, 36, 14, 16, 48, 6, 40, 89, 0, 0, 9, 198, 60, 36, 197, 73, 96, 64, 67, 9, 198, 53, 84, 141, 85, 32, 64, 67, 0, 9, 198, 81, 34, 77, 37, 65, 77, 66, 9, 134, 7, 18, 5, 197, 159, 9, 66, 0, 0, 0, 9, 198, 21, 129, 67, 85, 64, 64, 68, 9, 198, 5, 50, 71, 85, 32, 64, 68, 0, 0, 12, 137, 6, 15, 14, 5, 20, 9, 3, 196, 131, 66, 16, 7, 1, 18, 196, 131, 197, 163, 9, 35, 34, 6, 13, 123, 124, 0, 6, 195, 48, 148, 9, 66, 14, 68, 61, 34, 67, 20, 39, 16, 124, 76, 4, 36, 0, 75, 0, 8, 197, 21, 128, 77, 20, 224, 66, 11, 136, 195, 174, 14, 6, 21, 14, 4, 1, 67, 0, 9, 198, 52, 20, 148, 61, 33, 64, 65, 9, 198, 16, 240, 212, 61, 33, 64, 65, 0, 6, 195, 5, 101, 64, 66, 0, 12, 137, 16, 18, 5, 15, 3, 21, 16, 196, 131, 68, 0, 8, 197, 13, 32, 84, 21, 32, 65, 0, 8, 133, 20, 196, 131, 9, 5, 66, 6, 194, 4, 144, 76, 32, 5, 194, 12, 80, 76, 6, 194, 4, 144, 72, 28, 8, 66, 20, 16, 57, 35, 0, 76, 0, 9, 198, 88, 144, 212, 61, 34, 73, 66, 10, 135, 197, 159, 21, 2, 18, 5, 4, 65, 13, 138, 3, 5, 20, 196, 131, 197, 163, 21, 9, 5, 67, 0, 7, 196, 53, 86, 137, 44, 65, 16, 7, 3, 5, 1, 21, 197, 159, 21, 76, 135, 6, 40, 91, 40, 0, 0, 8, 197, 84, 212, 12, 20, 16, 66, 11, 136, 4, 5, 197, 163, 9, 14, 5, 1, 67, 15, 140, 195, 174, 14, 22, 196, 131, 18, 20, 5, 10, 5, 1, 68, 6, 195, 12, 83, 0, 76, 0, 9, 198, 52, 20, 148, 61, 34, 64, 65, 0, 13, 138, 3, 196, 131, 12, 196, 131, 21, 26, 5, 1, 68, 10, 199, 56, 144, 201, 84, 225, 76, 20, 77, 0, 7, 196, 88, 81, 5, 72, 66, 7, 196, 72, 17, 1, 72, 65, 7, 196, 48, 145, 5, 72, 65, 11, 135, 20, 15, 20, 21, 197, 159, 9, 65, 28, 0, 8, 197, 36, 224, 77, 36, 48, 67, 8, 197, 32, 242, 15, 80, 80, 65, 11, 136, 3, 195, 162, 20, 21, 197, 159, 9, 65, 8, 197, 52, 241, 5, 72, 16, 67, 8, 197, 13, 85, 133, 56, 144, 67, 13, 69, 16, 242, 76, 20, 16, 72, 6, 120, 55, 135, 0, 0, 9, 198, 64, 144, 212, 61, 34, 64, 65, 9, 198, 24, 16, 212, 61, 34, 64, 65, 5, 194, 13, 80, 72, 0, 0, 0, 11, 136, 2, 15, 13, 2, 196, 131, 14, 5, 65, 0, 17, 70, 77, 84, 144, 49, 84, 192, 89, 40, 16, 48, 55, 6, 40, 89, 0, 12, 137, 13, 5, 14, 197, 163, 9, 14, 5, 13, 66, 0, 10, 199, 16, 84, 195, 32, 145, 5, 52, 66, 0, 12, 67, 80, 22, 9, 47, 6, 35, 49, 89, 37, 0, 13, 68, 64, 149, 73, 20, 48, 6, 37, 40, 37, 36, 0, 7, 196, 13, 81, 197, 80, 65, 14, 139, 3, 12, 196, 131, 14, 197, 163, 196, 131, 14, 5, 65, 0, 11, 136, 195, 174, 14, 7, 18, 9, 10, 9, 67, 0, 0, 9, 198, 64, 144, 212, 61, 34, 73, 65, 0, 7, 196, 72, 244, 212, 36, 66, 0, 0, 9, 198, 56, 147, 69, 72, 80, 64, 67, 9, 198, 16, 245, 133, 16, 80, 64, 67, 0, 0, 7, 196, 9, 80, 213, 72, 65, 7, 196, 60, 53, 80, 4, 67, 0, 8, 197, 80, 84, 141, 20, 224, 65, 0, 12, 137, 19, 20, 18, 195, 162, 14, 7, 5, 13, 65, 9, 198, 12, 19, 129, 64, 80, 64, 67, 0, 11, 67, 72, 80, 76, 34, 36, 6, 35, 55, 0, 10, 199, 36, 228, 208, 20, 53, 15, 72, 66, 13, 138, 195, 174, 14, 20, 195, 162, 13, 16, 12, 1, 67, 0, 7, 196, 81, 33, 67, 84, 66, 7, 196, 48, 147, 149, 96, 65, 0, 0, 9, 198, 60, 34, 67, 20, 149, 64, 67, 0, 0, 11, 200, 36, 224, 77, 36, 50, 76, 61, 32, 67, 10, 135, 18, 5, 21, 197, 159, 5, 1, 67, 7, 196, 28, 243, 133, 4, 66, 10, 135, 3, 5, 18, 197, 159, 5, 1, 66, 13, 68, 5, 32, 213, 36, 35, 34, 49, 40, 6, 37, 0, 0, 8, 197, 72, 240, 133, 73, 64, 65, 6, 195, 84, 227, 210, 73, 0, 11, 66, 16, 80, 72, 135, 0, 72, 81, 97, 32, 25, 66, 16, 80, 72, 2, 36, 15, 35, 47, 6, 40, 50, 76, 124, 0, 8, 81, 97, 116, 117, 110, 99, 105, 32, 14, 66, 16, 80, 72, 36, 55, 35, 0, 72, 81, 108, 97, 32, 5, 194, 16, 80, 72, 0, 7, 195, 88, 82, 64, 76, 32, 0, 7, 196, 72, 84, 212, 84, 65, 7, 196, 104, 37, 82, 4, 66, 0, 8, 197, 4, 210, 78, 80, 144, 67, 0, 9, 198, 20, 225, 82, 28, 146, 64, 20, 8, 133, 18, 196, 131, 3, 9, 66, 0, 10, 199, 65, 35, 193, 77, 1, 84, 20, 65, 19, 70, 24, 20, 141, 4, 50, 69, 83, 35, 14, 16, 65, 35, 76, 6, 37, 36, 0, 9, 134, 1, 13, 196, 131, 7, 9, 67, 0, 11, 67, 80, 21, 9, 47, 6, 35, 47, 37, 0, 16, 4, 95, 4, 16, 20, 10, 84, 6, 37, 34, 81, 40, 55, 13, 0, 0, 15, 69, 64, 20, 143, 16, 144, 48, 35, 16, 39, 72, 6, 37, 0, 0, 8, 133, 16, 196, 131, 4, 21, 66, 0, 0, 8, 196, 36, 228, 213, 48, 65, 18, 6, 195, 32, 147, 69, 66, 0, 15, 69, 77, 84, 208, 85, 48, 89, 40, 89, 48, 6, 40, 89, 0, 14, 69, 32, 147, 132, 85, 48, 37, 50, 72, 6, 40, 89, 0, 0, 0, 0, 22, 72, 76, 83, 73, 65, 35, 196, 85, 48, 89, 36, 65, 37, 48, 16, 39, 72, 6, 40, 89, 0, 6, 195, 73, 83, 1, 66, 7, 196, 21, 99, 195, 4, 67, 13, 68, 61, 53, 15, 36, 39, 89, 47, 39, 6, 37, 0, 0, 0, 9, 198, 64, 145, 82, 16, 83, 64, 65, 6, 194, 4, 192, 72, 28, 0, 0, 7, 196, 76, 148, 212, 4, 66, 10, 3, 95, 35, 57, 47, 6, 35, 71, 0, 13, 4, 95, 20, 12, 4, 47, 6, 37, 55, 72, 13, 0, 0, 0, 9, 198, 80, 82, 135, 32, 80, 64, 66, 9, 198, 65, 85, 5, 72, 80, 64, 66, 12, 201, 36, 225, 146, 5, 53, 18, 84, 53, 21, 68, 18, 70, 16, 148, 212, 73, 84, 192, 72, 37, 89, 47, 14, 16, 6, 40, 89, 0, 0, 14, 67, 72, 68, 192, 6, 36, 34, 72, 36, 6, 36, 89, 0, 10, 199, 12, 20, 129, 13, 65, 82, 20, 67, 0, 13, 5, 14, 15, 21, 196, 131, 50, 6, 39, 40, 13, 0, 13, 68, 12, 243, 15, 72, 49, 39, 55, 6, 39, 16, 0, 7, 196, 76, 53, 84, 36, 66, 0, 11, 136, 18, 195, 162, 14, 10, 5, 20, 5, 65, 12, 201, 77, 84, 18, 4, 84, 212, 36, 208, 64, 69, 0, 9, 198, 65, 35, 214, 60, 48, 64, 67, 18, 70, 5, 4, 143, 64, 144, 64, 35, 48, 14, 16, 39, 48, 37, 6, 35, 0, 0, 10, 199, 52, 85, 1, 24, 244, 137, 12, 67, 15, 6, 3, 196, 131, 21, 20, 1, 49, 13, 40, 47, 6, 35, 0, 0, 7, 196, 24, 83, 137, 96, 65, 0, 13, 6, 3, 1, 21, 20, 196, 131, 49, 114, 47, 13, 0, 0, 9, 198, 88, 144, 212, 36, 209, 64, 65, 9, 198, 77, 64, 84, 84, 145, 64, 66, 0, 11, 136, 6, 12, 1, 13, 21, 18, 196, 131, 65, 9, 134, 7, 18, 196, 131, 2, 9, 68, 0, 7, 196, 57, 83, 65, 36, 65, 7, 196, 24, 83, 9, 96, 65, 7, 196, 88, 83, 133, 4, 66, 7, 196, 57, 83, 69, 4, 66, 0, 0, 9, 198, 88, 149, 18, 20, 113, 64, 65, 9, 198, 12, 243, 150, 36, 225, 192, 66, 6, 194, 4, 208, 76, 32, 0, 0, 7, 196, 85, 66, 76, 20, 66, 9, 198, 4, 210, 67, 36, 195, 210, 66, 7, 196, 32, 243, 2, 4, 66, 0, 8, 197, 29, 85, 21, 36, 80, 66, 8, 197, 12, 240, 201, 56, 80, 65, 11, 136, 16, 12, 195, 162, 14, 7, 5, 1, 66, 8, 197, 60, 66, 72, 56, 144, 67, 7, 132, 195, 174, 13, 9, 72, 0, 9, 198, 4, 100, 137, 12, 146, 64, 65, 0, 0, 13, 68, 77, 84, 21, 76, 89, 40, 48, 6, 40, 89, 0, 7, 196, 25, 83, 69, 28, 65, 0, 8, 197, 64, 20, 134, 84, 208, 66, 16, 69, 13, 34, 83, 80, 144, 49, 14, 16, 6, 37, 89, 47, 37, 0, 11, 136, 19, 195, 162, 14, 7, 5, 18, 1, 67, 11, 136, 18, 196, 131, 20, 196, 131, 3, 9, 67, 11, 136, 18, 196, 131, 20, 196, 131, 3, 9, 67, 8, 197, 32, 242, 15, 80, 144, 67, 19, 8, 3, 195, 162, 197, 163, 9, 22, 1, 49, 112, 123, 124, 84, 6, 35, 0, 78, 0, 9, 198, 88, 149, 18, 20, 114, 64, 65, 9, 198, 48, 16, 210, 36, 210, 64, 65, 8, 66, 21, 80, 57, 115, 0, 76, 0, 0, 7, 196, 89, 82, 69, 80, 65, 10, 135, 197, 159, 21, 9, 5, 18, 1, 67, 0, 19, 8, 3, 195, 174, 197, 163, 9, 22, 1, 49, 112, 123, 124, 84, 6, 35, 0, 78, 0, 12, 137, 195, 174, 14, 4, 21, 18, 5, 18, 1, 68, 0, 0, 7, 196, 53, 81, 197, 80, 65, 16, 70, 20, 147, 147, 80, 82, 78, 6, 117, 50, 91, 47, 117, 50, 0, 7, 196, 77, 67, 195, 4, 66, 0, 8, 197, 25, 34, 80, 81, 80, 66, 0, 9, 134, 18, 195, 162, 19, 5, 20, 65, 0, 24, 73, 25, 32, 78, 44, 83, 147, 80, 82, 78, 83, 34, 6, 35, 50, 49, 36, 50, 91, 47, 117, 50, 0, 6, 195, 57, 83, 73, 66, 0, 0, 7, 196, 29, 32, 86, 84, 66, 0, 8, 197, 72, 243, 129, 48, 64, 65, 11, 4, 15, 18, 196, 131, 6, 39, 34, 13, 0, 9, 198, 52, 85, 1, 24, 244, 133, 66, 9, 198, 24, 147, 15, 104, 241, 137, 20, 9, 134, 19, 16, 196, 131, 12, 1, 66, 9, 198, 65, 35, 211, 64, 84, 129, 67, 0, 13, 138, 195, 174, 14, 4, 18, 196, 131, 26, 14, 9, 67, 0, 10, 199, 64, 20, 148, 20, 225, 82, 20, 67, 19, 8, 195, 174, 14, 1, 9, 14, 20, 5, 112, 50, 35, 6, 37, 50, 47, 36, 0, 15, 6, 6, 196, 131, 18, 196, 131, 83, 4, 13, 34, 13, 0, 8, 0, 7, 196, 80, 19, 135, 60, 66, 8, 133, 3, 196, 131, 26, 21, 66, 12, 201, 16, 84, 195, 60, 228, 201, 16, 84, 129, 69, 0, 9, 198, 76, 80, 213, 72, 144, 197, 67, 9, 198, 52, 84, 193, 28, 84, 129, 67, 9, 198, 36, 224, 201, 56, 84, 129, 68, 9, 198, 16, 84, 195, 85, 32, 193, 67, 0, 9, 198, 52, 85, 1, 24, 244, 128, 66, 10, 135, 12, 21, 3, 18, 196, 131, 13, 66, 0, 11, 136, 195, 174, 14, 1, 9, 14, 20, 1, 67, 9, 134, 16, 195, 162, 14, 196, 131, 8, 7, 132, 20, 196, 131, 21, 76, 0, 10, 135, 12, 1, 20, 21, 18, 196, 131, 65, 7, 196, 65, 34, 77, 36, 66, 0, 11, 136, 22, 196, 131, 4, 21, 22, 196, 131, 65, 11, 136, 20, 18, 5, 13, 21, 18, 196, 131, 65, 11, 136, 16, 196, 131, 20, 21, 18, 196, 131, 65, 11, 136, 13, 196, 131, 20, 21, 18, 196, 131, 65, 11, 136, 5, 12, 9, 2, 5, 18, 196, 131, 68, 13, 138, 3, 21, 13, 16, 196, 131, 18, 196, 131, 13, 67, 0, 10, 135, 3, 196, 131, 18, 21, 9, 1, 73, 0, 13, 138, 3, 21, 20, 18, 5, 13, 21, 18, 196, 131, 66, 0, 8, 133, 20, 196, 131, 3, 21, 66, 7, 196, 16, 244, 133, 4, 66, 7, 196, 12, 84, 133, 4, 66, 14, 68, 4, 116, 133, 4, 35, 81, 14, 16, 36, 6, 35, 0, 7, 196, 12, 84, 133, 4, 66, 12, 137, 197, 159, 196, 131, 19, 5, 12, 5, 1, 65, 0, 13, 138, 14, 5, 22, 196, 131, 19, 20, 21, 9, 5, 67, 9, 134, 18, 195, 162, 4, 5, 1, 66, 23, 10, 15, 18, 9, 3, 196, 131, 18, 21, 9, 1, 39, 16, 124, 49, 13, 34, 40, 37, 35, 0, 79, 0, 6, 195, 88, 83, 137, 66, 10, 135, 1, 197, 163, 9, 14, 20, 9, 67, 10, 135, 3, 196, 131, 18, 5, 9, 1, 73, 0, 10, 135, 4, 196, 131, 18, 196, 131, 20, 66, 26, 4, 197, 159, 46, 1, 91, 37, 11, 35, 91, 4, 35, 15, 65, 117, 15, 72, 36, 48, 6, 35, 34, 47, 36, 0, 0, 0, 8, 197, 48, 16, 207, 52, 144, 65, 8, 197, 36, 226, 77, 36, 144, 65, 13, 138, 3, 196, 131, 18, 196, 131, 18, 21, 9, 5, 68, 8, 197, 88, 83, 133, 72, 16, 67, 8, 197, 4, 193, 82, 28, 16, 67, 23, 10, 15, 18, 9, 3, 196, 131, 18, 5, 9, 1, 39, 16, 124, 49, 13, 34, 36, 37, 35, 0, 79, 0, 13, 138, 195, 174, 14, 4, 196, 131, 18, 196, 131, 20, 67, 14, 139, 6, 12, 196, 131, 3, 196, 131, 18, 21, 9, 5, 67, 0, 10, 199, 64, 20, 148, 20, 225, 82, 36, 67, 10, 199, 12, 19, 132, 36, 64, 84, 84, 68, 7, 132, 20, 196, 131, 9, 76, 0, 12, 137, 26, 7, 195, 162, 18, 9, 5, 20, 21, 68, 11, 200, 64, 20, 148, 20, 225, 82, 36, 144, 67, 7, 196, 13, 82, 86, 4, 66, 11, 200, 65, 33, 83, 85, 5, 78, 20, 16, 68, 0, 8, 197, 84, 225, 5, 88, 16, 67, 8, 197, 81, 33, 67, 20, 208, 65, 9, 134, 4, 5, 197, 163, 9, 9, 66, 9, 198, 5, 68, 137, 9, 82, 65, 68, 13, 138, 19, 196, 131, 22, 195, 162, 18, 197, 159, 9, 67, 8, 197, 16, 85, 133, 56, 144, 67, 0, 10, 135, 2, 196, 131, 20, 196, 131, 9, 66, 0, 7, 195, 16, 147, 128, 72, 28, 0, 7, 196, 5, 66, 78, 28, 66, 0, 9, 198, 12, 243, 210, 16, 243, 129, 68, 0, 14, 139, 195, 174, 14, 7, 8, 9, 197, 163, 9, 20, 21, 68, 0, 20, 71, 76, 84, 150, 36, 50, 85, 48, 89, 36, 34, 84, 6, 37, 76, 57, 40, 55, 0, 11, 136, 22, 5, 197, 159, 20, 5, 10, 9, 67, 0, 7, 196, 21, 3, 195, 36, 65, 0, 9, 134, 3, 196, 131, 12, 3, 1, 66, 14, 3, 3, 6, 46, 99, 111, 110, 102, 111, 114, 109, 0, 29, 0, 16, 7, 19, 16, 1, 197, 163, 9, 21, 89, 48, 35, 123, 57, 40, 0, 17, 70, 56, 144, 201, 13, 83, 64, 50, 37, 76, 124, 49, 6, 40, 65, 0, 0, 0, 7, 196, 5, 34, 80, 36, 65, 7, 196, 37, 34, 84, 4, 67, 7, 196, 21, 98, 84, 4, 67, 0, 13, 138, 195, 174, 14, 7, 8, 9, 15, 14, 20, 9, 67, 0, 9, 198, 72, 81, 201, 104, 244, 128, 66, 11, 136, 16, 12, 195, 162, 14, 7, 5, 18, 65, 11, 67, 13, 35, 201, 49, 34, 39, 6, 37, 0, 0, 9, 134, 20, 21, 18, 14, 196, 131, 66, 7, 195, 16, 20, 128, 72, 8, 0, 0, 11, 136, 18, 5, 16, 12, 9, 3, 196, 131, 65, 11, 136, 9, 13, 16, 12, 9, 3, 196, 131, 66, 9, 198, 4, 115, 15, 52, 84, 129, 68, 0, 10, 135, 26, 2, 21, 18, 196, 131, 13, 66, 12, 137, 20, 196, 131, 22, 9, 197, 163, 196, 131, 66, 0, 11, 136, 18, 5, 16, 1, 18, 196, 131, 13, 67, 7, 132, 196, 131, 9, 1, 77, 0, 12, 137, 3, 15, 13, 16, 1, 18, 196, 131, 13, 67, 10, 135, 1, 18, 20, 5, 18, 196, 131, 66, 0, 13, 138, 22, 195, 162, 14, 196, 131, 20, 196, 131, 9, 67, 13, 138, 19, 20, 18, 5, 3, 21, 18, 196, 131, 13, 67, 13, 138, 18, 5, 3, 21, 16, 5, 18, 196, 131, 13, 68, 11, 136, 16, 1, 14, 20, 5, 18, 196, 131, 66, 0, 14, 139, 22, 195, 162, 12, 22, 196, 131, 20, 196, 131, 9, 67, 10, 135, 1, 19, 20, 196, 131, 26, 9, 65, 10, 135, 22, 195, 162, 19, 12, 5, 1, 66, 0, 11, 4, 2, 196, 131, 21, 71, 13, 6, 40, 0, 0, 9, 134, 12, 1, 26, 196, 131, 18, 65, 16, 141, 195, 174, 14, 6, 196, 131, 197, 159, 21, 18, 196, 131, 13, 68, 7, 196, 24, 84, 133, 4, 66, 0, 13, 138, 195, 174, 14, 22, 196, 131, 18, 20, 5, 1, 67, 0, 8, 66, 20, 144, 57, 118, 0, 76, 16, 66, 12, 208, 99, 101, 110, 116, 105, 109, 101, 116, 114, 105, 0, 29, 0, 0, 13, 68, 16, 81, 21, 76, 72, 36, 72, 6, 40, 89, 0, 0, 8, 197, 72, 84, 5, 16, 80, 65, 8, 197, 64, 19, 9, 16, 80, 65, 8, 197, 52, 243, 137, 12, 16, 66, 8, 197, 12, 243, 132, 20, 144, 66, 9, 134, 3, 196, 131, 12, 4, 21, 66, 10, 135, 1, 3, 15, 16, 196, 131, 18, 66, 8, 197, 88, 244, 130, 20, 16, 66, 8, 197, 80, 243, 5, 72, 16, 67, 8, 197, 72, 83, 5, 88, 16, 67, 8, 197, 72, 81, 149, 104, 16, 67, 8, 197, 60, 35, 9, 28, 16, 67, 8, 197, 16, 84, 208, 72, 80, 28, 0, 14, 139, 1, 12, 2, 196, 131, 19, 20, 18, 21, 9, 5, 67, 0, 10, 135, 20, 195, 162, 18, 3, 15, 12, 66, 0, 0, 8, 197, 77, 5, 78, 20, 16, 66, 8, 197, 12, 243, 147, 84, 208, 66, 8, 197, 12, 20, 5, 80, 80, 65, 13, 138, 18, 5, 1, 3, 197, 163, 9, 15, 14, 1, 67, 8, 197, 16, 145, 197, 72, 16, 67, 8, 197, 52, 21, 1, 48, 80, 78, 0, 10, 135, 19, 16, 5, 18, 196, 131, 13, 66, 10, 135, 15, 16, 5, 18, 196, 131, 13, 67, 6, 195, 24, 84, 137, 66, 0, 11, 136, 19, 20, 18, 15, 16, 197, 159, 9, 66, 0, 0, 17, 70, 88, 241, 1, 24, 243, 133, 84, 6, 39, 72, 35, 83, 39, 50, 0, 9, 198, 64, 20, 193, 28, 84, 137, 67, 0, 14, 139, 18, 5, 3, 5, 16, 197, 163, 9, 15, 14, 5, 68, 14, 139, 5, 3, 8, 9, 12, 9, 2, 18, 196, 131, 13, 68, 0, 11, 136, 18, 196, 131, 19, 3, 15, 12, 9, 67, 0, 0, 0, 0, 0, 0, 0, 9, 134, 20, 1, 20, 196, 131, 12, 65, 9, 198, 16, 84, 201, 29, 84, 128, 66, 10, 67, 4, 128, 65, 35, 107, 6, 35, 0, 9, 198, 81, 34, 85, 52, 96, 64, 67, 9, 198, 21, 128, 77, 36, 224, 64, 68, 9, 198, 5, 48, 213, 49, 64, 64, 67, 10, 135, 18, 5, 7, 196, 131, 19, 9, 67, 12, 67, 16, 16, 193, 72, 35, 49, 13, 0, 72, 8, 0, 6, 195, 60, 51, 204, 66, 10, 67, 4, 128, 64, 35, 107, 6, 35, 0, 11, 136, 3, 196, 131, 16, 196, 131, 20, 1, 67, 10, 199, 72, 244, 212, 60, 115, 204, 36, 68, 0, 10, 135, 18, 9, 4, 9, 3, 196, 131, 66, 7, 196, 52, 19, 148, 4, 66, 0, 11, 136, 13, 195, 162, 14, 5, 3, 196, 131, 65, 11, 136, 9, 14, 20, 18, 9, 7, 196, 131, 65, 11, 136, 5, 24, 16, 12, 9, 3, 196, 131, 66, 9, 134, 14, 9, 197, 159, 20, 5, 73, 0, 10, 135, 9, 14, 20, 18, 196, 131, 13, 66, 0, 13, 138, 195, 174, 14, 22, 196, 131, 197, 163, 196, 131, 67, 10, 3, 226, 130, 172, 6, 115, 16, 39, 0, 0, 14, 139, 16, 196, 131, 18, 20, 9, 3, 9, 3, 196, 131, 67, 12, 137, 3, 15, 14, 6, 9, 197, 159, 20, 5, 66, 0, 14, 69, 8, 19, 142, 21, 32, 71, 6, 36, 50, 13, 34, 0, 9, 134, 16, 12, 196, 131, 20, 9, 66, 0, 6, 195, 72, 80, 201, 65, 0, 13, 138, 195, 174, 13, 2, 18, 196, 131, 3, 196, 131, 67, 0, 12, 137, 6, 12, 196, 131, 3, 196, 131, 18, 9, 65, 0, 13, 5, 1, 18, 196, 131, 20, 35, 34, 6, 13, 47, 0, 0, 9, 198, 80, 16, 129, 12, 129, 64, 67, 9, 198, 65, 35, 195, 20, 69, 64, 67, 0, 0, 7, 196, 81, 33, 90, 36, 66, 0, 8, 197, 60, 19, 69, 56, 144, 65, 8, 197, 52, 84, 135, 20, 208, 65, 8, 197, 28, 83, 69, 56, 144, 65, 8, 197, 16, 19, 66, 48, 16, 66, 8, 197, 12, 244, 212, 84, 208, 66, 8, 197, 16, 148, 197, 12, 16, 67, 0, 6, 195, 72, 85, 137, 66, 0, 0, 12, 137, 6, 12, 196, 131, 3, 196, 131, 18, 1, 65, 7, 196, 13, 83, 86, 4, 66, 7, 196, 88, 244, 130, 36, 66, 7, 196, 64, 244, 142, 36, 66, 0, 9, 134, 19, 20, 196, 131, 20, 21, 66, 8, 197, 37, 53, 15, 88, 144, 67, 11, 3, 95, 50, 6, 72, 6, 39, 40, 13, 0, 0, 10, 135, 16, 1, 19, 196, 131, 18, 5, 65, 9, 198, 36, 208, 71, 36, 226, 64, 66, 0, 11, 136, 21, 13, 6, 12, 196, 131, 20, 21, 67, 10, 199, 77, 64, 78, 16, 20, 132, 20, 65, 25, 11, 195, 174, 14, 196, 131, 21, 14, 20, 18, 21, 12, 112, 50, 13, 6, 40, 50, 47, 14, 16, 40, 55, 0, 11, 136, 2, 196, 131, 20, 196, 131, 20, 21, 67, 0, 7, 196, 52, 84, 137, 80, 65, 12, 137, 3, 18, 196, 131, 16, 196, 131, 20, 21, 67, 12, 137, 1, 12, 9, 14, 20, 196, 131, 20, 21, 68, 11, 200, 36, 229, 5, 73, 162, 67, 20, 16, 68, 11, 200, 36, 229, 5, 73, 49, 67, 80, 16, 68, 7, 196, 5, 5, 67, 4, 67, 0, 0, 9, 198, 44, 83, 5, 52, 83, 128, 65, 14, 139, 195, 174, 14, 22, 196, 131, 20, 196, 131, 20, 21, 68, 31, 14, 4, 9, 14, 195, 174, 14, 196, 131, 21, 14, 20, 18, 21, 12, 72, 37, 50, 112, 50, 13, 6, 40, 50, 47, 14, 16, 40, 55, 0, 0, 15, 140, 195, 174, 14, 3, 18, 21, 14, 20, 196, 131, 20, 21, 68, 11, 136, 16, 196, 131, 3, 196, 131, 12, 9, 67, 0, 7, 196, 84, 197, 9, 52, 65, 7, 196, 17, 82, 85, 52, 66, 12, 137, 19, 6, 195, 162, 18, 20, 5, 3, 1, 67, 0, 9, 198, 28, 80, 77, 4, 225, 21, 67, 0, 9, 66, 20, 192, 57, 36, 55, 0, 76, 0, 11, 136, 3, 195, 162, 14, 20, 5, 3, 5, 65, 15, 3, 95, 50, 48, 72, 39, 40, 13, 88, 6, 36, 76, 124, 0, 0, 11, 200, 52, 17, 201, 77, 68, 129, 81, 80, 68, 0, 9, 198, 17, 83, 73, 56, 144, 193, 66, 0, 9, 198, 25, 33, 68, 60, 224, 64, 67, 9, 133, 4, 1, 3, 196, 131, 72, 8, 0, 11, 136, 197, 159, 21, 2, 18, 5, 4, 5, 65, 9, 134, 16, 12, 5, 3, 196, 131, 66, 10, 134, 1, 4, 9, 3, 196, 131, 66, 28, 0, 10, 135, 16, 9, 19, 9, 3, 196, 131, 66, 10, 135, 1, 16, 12, 5, 3, 196, 131, 67, 7, 196, 12, 243, 148, 4, 66, 10, 135, 5, 24, 9, 19, 20, 196, 131, 72, 0, 11, 136, 6, 15, 18, 6, 15, 20, 196, 131, 65, 11, 136, 1, 3, 5, 1, 19, 20, 196, 131, 76, 0, 9, 198, 65, 35, 212, 60, 51, 204, 67, 9, 198, 80, 19, 80, 60, 224, 64, 67, 15, 4, 95, 13, 3, 14, 65, 35, 49, 14, 16, 6, 39, 50, 0, 0, 9, 134, 19, 20, 15, 3, 196, 131, 66, 15, 3, 95, 51, 48, 47, 14, 16, 118, 88, 6, 36, 76, 124, 0, 0, 12, 137, 19, 20, 18, 9, 7, 196, 131, 20, 5, 65, 7, 196, 52, 21, 5, 36, 66, 22, 11, 7, 196, 131, 7, 196, 131, 21, 197, 163, 196, 131, 81, 13, 81, 13, 6, 40, 123, 13, 0, 0, 11, 136, 3, 5, 18, 3, 5, 20, 196, 131, 67, 0, 9, 198, 5, 99, 195, 5, 69, 64, 68, 0, 11, 136, 16, 18, 5, 7, 196, 131, 20, 9, 67, 0, 8, 133, 13, 196, 131, 19, 21, 66, 0, 9, 198, 12, 147, 131, 36, 193, 65, 65, 0, 18, 70, 61, 34, 67, 36, 225, 64, 39, 16, 124, 76, 4, 37, 50, 36, 0, 79, 0, 0, 12, 137, 13, 21, 12, 197, 163, 21, 13, 5, 1, 67, 8, 133, 195, 174, 197, 163, 9, 72, 0, 8, 197, 88, 147, 132, 20, 208, 65, 8, 197, 84, 212, 12, 20, 208, 65, 0, 0, 10, 199, 65, 35, 198, 21, 51, 210, 36, 66, 10, 199, 12, 83, 5, 48, 19, 20, 20, 79, 0, 0, 14, 69, 37, 2, 15, 56, 80, 35, 37, 83, 6, 130, 50, 0, 0, 10, 135, 2, 15, 18, 196, 131, 20, 21, 67, 0, 11, 136, 3, 196, 131, 26, 196, 131, 20, 21, 67, 11, 136, 195, 174, 14, 20, 18, 5, 2, 1, 67, 0, 8, 133, 12, 196, 131, 19, 1, 66, 0, 13, 138, 195, 174, 14, 10, 21, 18, 196, 131, 20, 21, 68, 0, 0, 11, 136, 3, 196, 131, 19, 196, 131, 16, 9, 67, 0, 7, 196, 56, 85, 5, 16, 65, 9, 198, 12, 243, 147, 36, 65, 82, 66, 7, 196, 48, 19, 147, 4, 66, 7, 196, 16, 19, 147, 4, 66, 0, 17, 142, 195, 174, 14, 6, 196, 131, 197, 159, 21, 18, 196, 131, 20, 21, 69, 9, 134, 195, 174, 14, 5, 3, 1, 67, 0, 0, 9, 134, 13, 9, 197, 159, 20, 15, 66, 18, 70, 36, 229, 18, 60, 69, 83, 37, 50, 47, 34, 39, 72, 6, 40, 89, 0, 15, 3, 95, 51, 88, 47, 14, 16, 6, 118, 88, 36, 76, 124, 0, 13, 3, 95, 54, 48, 91, 117, 88, 6, 36, 76, 124, 0, 0, 7, 196, 76, 17, 9, 12, 65, 20, 9, 15, 1, 18, 5, 197, 159, 9, 3, 5, 39, 35, 16, 36, 91, 76, 36, 0, 68, 7, 196, 13, 33, 90, 84, 66, 11, 3, 95, 48, 67, 89, 6, 40, 47, 36, 0, 0, 0, 6, 195, 41, 80, 193, 66, 9, 198, 25, 84, 142, 37, 160, 64, 67, 0, 0, 0, 12, 4, 95, 48, 90, 51, 65, 6, 132, 65, 37, 0, 0, 9, 198, 72, 80, 76, 37, 160, 64, 68, 9, 198, 16, 148, 195, 85, 64, 64, 67, 9, 198, 12, 84, 131, 21, 64, 64, 67, 14, 4, 95, 48, 90, 50, 89, 6, 40, 47, 37, 65, 37, 0, 0, 11, 136, 18, 5, 197, 163, 9, 14, 5, 13, 66, 16, 3, 95, 55, 48, 91, 35, 48, 47, 36, 88, 6, 36, 76, 124, 0, 0, 10, 135, 22, 9, 26, 9, 20, 196, 131, 65, 10, 135, 3, 196, 131, 21, 20, 196, 131, 67, 13, 3, 95, 49, 67, 4, 39, 89, 6, 40, 47, 13, 0, 0, 9, 198, 16, 84, 15, 104, 149, 5, 66, 0, 9, 198, 36, 224, 213, 49, 69, 64, 67, 6, 195, 12, 81, 1, 66, 0, 11, 136, 26, 21, 7, 18, 196, 131, 22, 9, 67, 0, 7, 196, 32, 242, 15, 80, 65, 0, 8, 197, 76, 147, 131, 21, 32, 65, 9, 198, 72, 84, 208, 20, 53, 1, 67, 0, 9, 198, 9, 80, 149, 37, 69, 64, 68, 9, 198, 4, 101, 77, 5, 69, 64, 68, 6, 194, 48, 16, 72, 28, 9, 198, 88, 240, 83, 81, 33, 64, 76, 9, 198, 56, 240, 83, 81, 33, 64, 77, 9, 198, 4, 229, 77, 37, 65, 64, 75, 20, 3, 95, 49, 57, 50, 6, 131, 13, 89, 48, 14, 16, 36, 88, 4, 36, 76, 36, 0, 0, 6, 195, 72, 84, 212, 65, 11, 136, 1, 13, 196, 131, 18, 21, 9, 5, 67, 19, 3, 95, 49, 56, 6, 39, 48, 123, 48, 14, 16, 36, 88, 4, 36, 76, 36, 0, 0, 13, 68, 20, 229, 5, 72, 36, 50, 47, 13, 34, 0, 65, 16, 3, 95, 50, 67, 72, 6, 39, 40, 13, 89, 6, 40, 47, 36, 0, 0, 13, 138, 16, 196, 131, 19, 196, 131, 18, 21, 9, 5, 67, 8, 197, 29, 83, 5, 72, 80, 65, 13, 138, 6, 18, 9, 7, 196, 131, 18, 21, 9, 5, 67, 13, 138, 3, 196, 131, 13, 196, 131, 18, 21, 9, 5, 67, 8, 197, 12, 240, 143, 72, 16, 67, 8, 197, 37, 161, 207, 56, 144, 67, 0, 0, 11, 136, 19, 6, 195, 162, 18, 197, 159, 9, 66, 0, 7, 196, 36, 225, 9, 12, 66, 7, 196, 16, 19, 148, 84, 66, 7, 196, 88, 144, 146, 4, 66, 0, 8, 197, 64, 20, 143, 48, 80, 66, 8, 197, 52, 19, 143, 48, 80, 66, 0, 10, 135, 21, 19, 3, 196, 131, 20, 21, 67, 6, 195, 12, 83, 5, 77, 19, 3, 95, 49, 49, 6, 40, 50, 89, 48, 14, 16, 36, 88, 4, 36, 76, 36, 0, 0, 11, 136, 195, 174, 14, 19, 5, 13, 14, 1, 67, 11, 3, 95, 49, 48, 88, 6, 36, 76, 36, 0, 0, 12, 137, 22, 196, 131, 18, 19, 196, 131, 20, 21, 67, 12, 67, 81, 34, 79, 47, 14, 16, 6, 37, 39, 0, 12, 137, 20, 18, 196, 131, 19, 196, 131, 20, 21, 67, 12, 137, 16, 9, 197, 159, 3, 196, 131, 20, 21, 67, 12, 137, 3, 196, 131, 12, 3, 196, 131, 20, 21, 67, 21, 3, 95, 49, 51, 47, 14, 16, 6, 118, 89, 48, 14, 16, 36, 88, 4, 36, 76, 36, 0, 0, 9, 198, 48, 149, 5, 72, 21, 21, 68, 13, 138, 195, 174, 13, 2, 21, 3, 196, 131, 20, 21, 68, 9, 134, 22, 18, 196, 131, 10, 9, 66, 9, 198, 76, 51, 9, 24, 244, 201, 67, 19, 3, 95, 49, 50, 72, 6, 120, 89, 48, 14, 16, 36, 88, 4, 36, 76, 36, 0, 0, 14, 139, 195, 174, 14, 20, 15, 18, 19, 196, 131, 20, 21, 68, 14, 139, 1, 13, 5, 19, 20, 5, 3, 196, 131, 20, 21, 69, 20, 3, 95, 49, 53, 76, 6, 37, 50, 89, 48, 14, 16, 36, 88, 4, 36, 76, 36, 0, 0, 15, 140, 195, 174, 13, 16, 21, 197, 159, 3, 196, 131, 20, 21, 68, 19, 3, 95, 49, 52, 48, 6, 117, 89, 48, 14, 16, 36, 88, 4, 36, 76, 36, 0, 0, 22, 3, 95, 49, 55, 91, 6, 35, 48, 47, 36, 89, 48, 14, 16, 36, 88, 4, 36, 76, 36, 0, 0, 9, 198, 16, 81, 197, 72, 21, 21, 68, 7, 195, 65, 34, 78, 72, 28, 19, 3, 95, 49, 54, 91, 6, 117, 89, 48, 14, 16, 36, 88, 4, 36, 76, 36, 0, 0, 0, 19, 70, 77, 84, 18, 5, 5, 83, 89, 40, 48, 14, 16, 35, 48, 6, 40, 89, 0, 16, 3, 95, 55, 88, 91, 6, 35, 48, 47, 36, 88, 36, 76, 124, 0, 0, 7, 196, 25, 34, 90, 84, 66, 0, 0, 9, 198, 72, 84, 208, 37, 32, 64, 67, 9, 198, 65, 33, 80, 5, 32, 64, 67, 9, 198, 65, 33, 70, 21, 32, 64, 67, 0, 11, 136, 21, 3, 9, 4, 5, 197, 163, 9, 66, 0, 10, 135, 1, 18, 196, 131, 20, 196, 131, 67, 0, 18, 70, 28, 147, 78, 5, 162, 85, 75, 37, 65, 50, 6, 35, 88, 57, 40, 0, 0, 12, 137, 13, 15, 4, 9, 6, 9, 3, 196, 131, 66, 14, 139, 195, 174, 14, 3, 8, 9, 4, 5, 197, 163, 9, 66, 9, 198, 85, 66, 76, 37, 160, 64, 68, 6, 195, 84, 149, 1, 66, 9, 198, 80, 83, 80, 21, 32, 64, 67, 0, 0, 7, 196, 8, 149, 143, 48, 65, 0, 9, 198, 17, 83, 78, 20, 21, 1, 79, 0, 6, 195, 88, 245, 1, 66, 0, 10, 199, 36, 229, 5, 73, 162, 67, 20, 67, 10, 199, 12, 144, 193, 81, 34, 67, 20, 67, 10, 199, 8, 16, 212, 21, 34, 69, 36, 66, 10, 199, 4, 69, 133, 57, 66, 67, 20, 67, 0, 7, 196, 48, 21, 5, 96, 65, 12, 137, 19, 21, 19, 197, 163, 9, 14, 5, 1, 67, 13, 68, 16, 85, 137, 4, 72, 36, 84, 37, 6, 35, 0, 0, 8, 197, 89, 83, 20, 85, 32, 65, 9, 134, 197, 163, 9, 14, 5, 1, 66, 9, 198, 64, 84, 141, 37, 65, 65, 67, 9, 134, 16, 196, 131, 26, 5, 1, 66, 0, 11, 67, 17, 37, 77, 72, 34, 6, 40, 65, 0, 9, 198, 13, 32, 84, 21, 33, 64, 65, 0, 17, 3, 95, 52, 48, 48, 35, 47, 14, 16, 40, 88, 6, 36, 76, 124, 0, 0, 9, 198, 16, 84, 15, 104, 149, 0, 66, 12, 137, 3, 15, 14, 197, 163, 9, 14, 5, 1, 67, 0, 9, 198, 65, 35, 205, 37, 65, 77, 66, 9, 198, 64, 84, 141, 37, 65, 77, 66, 8, 197, 56, 147, 73, 12, 16, 66, 9, 197, 80, 245, 21, 76, 144, 65, 28, 0, 9, 198, 12, 20, 129, 12, 19, 0, 66, 0, 0, 7, 196, 12, 83, 148, 84, 66, 11, 200, 77, 84, 144, 72, 147, 132, 20, 16, 67, 11, 200, 77, 1, 67, 36, 19, 9, 104, 16, 68, 0, 15, 69, 44, 245, 133, 76, 144, 49, 6, 39, 84, 36, 91, 37, 0, 8, 197, 28, 150, 143, 72, 144, 65, 8, 197, 77, 81, 197, 72, 16, 67, 8, 197, 52, 148, 143, 76, 144, 67, 0, 9, 198, 89, 83, 20, 85, 34, 64, 65, 10, 135, 3, 195, 162, 14, 4, 22, 1, 66, 0, 10, 199, 20, 50, 9, 48, 144, 146, 4, 68, 15, 3, 95, 50, 88, 72, 6, 39, 40, 13, 88, 36, 76, 124, 0, 14, 3, 95, 53, 48, 76, 37, 50, 88, 6, 36, 76, 124, 0, 0, 12, 137, 19, 21, 19, 197, 163, 9, 14, 5, 13, 66, 11, 200, 24, 84, 133, 77, 68, 149, 36, 80, 67, 7, 196, 16, 21, 137, 16, 65, 7, 196, 8, 21, 5, 52, 65, 11, 67, 5, 5, 83, 35, 48, 6, 40, 89, 0, 17, 68, 16, 147, 148, 72, 72, 37, 50, 47, 14, 34, 39, 0, 81, 111, 32, 0, 8, 197, 12, 244, 205, 61, 48, 65, 0, 0, 10, 135, 18, 196, 131, 3, 14, 5, 20, 65, 0, 0, 9, 198, 12, 243, 148, 72, 243, 1, 67, 0, 13, 138, 19, 3, 18, 195, 162, 197, 159, 14, 5, 20, 65, 11, 67, 52, 147, 73, 65, 6, 37, 65, 37, 0, 10, 135, 195, 174, 14, 22, 5, 12, 9, 67, 0, 10, 67, 52, 144, 64, 65, 6, 37, 35, 0, 0, 0, 9, 198, 65, 33, 70, 4, 49, 77, 66, 13, 138, 16, 196, 131, 9, 1, 14, 10, 5, 14, 9, 66, 0, 13, 5, 4, 15, 21, 196, 131, 72, 6, 39, 40, 13, 0, 9, 198, 72, 84, 12, 36, 48, 64, 67, 9, 198, 21, 132, 12, 36, 48, 64, 67, 9, 198, 104, 80, 197, 48, 80, 64, 65, 9, 198, 61, 5, 21, 48, 80, 64, 65, 0, 11, 136, 18, 196, 131, 3, 14, 5, 20, 5, 65, 6, 195, 12, 80, 64, 76, 0, 15, 3, 95, 63, 63, 49, 35, 16, 35, 49, 47, 6, 36, 34, 0, 0, 0, 14, 139, 19, 3, 18, 195, 162, 197, 159, 14, 5, 20, 5, 65, 18, 70, 5, 4, 133, 12, 144, 64, 35, 48, 14, 16, 36, 76, 57, 6, 35, 0, 0, 10, 67, 52, 145, 64, 65, 6, 37, 36, 0, 17, 3, 95, 52, 88, 48, 6, 35, 47, 14, 16, 40, 88, 36, 76, 124, 0, 0, 8, 133, 16, 196, 131, 26, 9, 66, 0, 8, 197, 77, 2, 82, 37, 64, 65, 0, 9, 198, 21, 132, 12, 36, 49, 64, 66, 10, 67, 12, 80, 73, 76, 6, 135, 57, 0, 6, 195, 77, 81, 1, 66, 10, 135, 19, 20, 195, 162, 18, 14, 9, 67, 7, 195, 12, 81, 65, 72, 28, 0, 0, 0, 9, 198, 89, 83, 20, 85, 34, 73, 65, 9, 198, 65, 33, 90, 36, 49, 65, 67, 0, 10, 135, 16, 196, 131, 18, 5, 18, 9, 66, 17, 7, 8, 195, 162, 18, 20, 9, 5, 107, 112, 34, 47, 6, 37, 36, 0, 11, 66, 48, 80, 55, 135, 0, 72, 81, 97, 32, 13, 66, 48, 80, 55, 135, 34, 0, 72, 81, 97, 114, 32, 16, 66, 48, 80, 55, 135, 123, 124, 0, 72, 81, 97, 197, 163, 105, 32, 13, 66, 48, 80, 55, 135, 57, 0, 72, 81, 97, 105, 32, 13, 66, 48, 80, 55, 135, 65, 0, 72, 81, 97, 109, 32, 11, 66, 48, 80, 55, 135, 0, 72, 81, 97, 32, 5, 194, 48, 80, 72, 15, 66, 44, 112, 107, 105, 108, 111, 103, 114, 97, 109, 101, 0, 29, 0, 14, 3, 95, 53, 88, 76, 6, 37, 50, 88, 36, 76, 124, 0, 14, 3, 95, 56, 48, 39, 48, 47, 88, 6, 36, 76, 124, 0, 0, 9, 198, 81, 35, 211, 56, 85, 0, 65, 7, 196, 72, 145, 9, 12, 66, 7, 196, 77, 1, 82, 4, 66, 12, 137, 195, 174, 14, 22, 9, 14, 7, 5, 1, 67, 0, 9, 134, 197, 163, 9, 14, 5, 13, 65, 8, 197, 52, 83, 129, 40, 80, 67, 8, 197, 48, 21, 9, 12, 80, 66, 8, 197, 56, 147, 69, 56, 144, 77, 0, 10, 135, 22, 196, 131, 4, 21, 22, 5, 65, 10, 135, 16, 196, 131, 18, 5, 18, 5, 66, 11, 67, 52, 19, 73, 65, 6, 35, 65, 37, 0, 6, 195, 88, 242, 65, 66, 0, 7, 195, 88, 242, 64, 76, 32, 6, 195, 52, 18, 64, 72, 6, 195, 88, 242, 64, 76, 6, 195, 56, 242, 64, 76, 6, 195, 12, 82, 64, 76, 0, 12, 137, 195, 174, 14, 3, 9, 14, 7, 5, 13, 66, 8, 133, 4, 196, 131, 4, 21, 66, 12, 137, 1, 4, 195, 162, 14, 3, 9, 20, 21, 68, 11, 200, 12, 243, 131, 72, 85, 9, 104, 16, 68, 0, 8, 197, 56, 244, 212, 36, 208, 65, 8, 197, 13, 32, 84, 36, 208, 65, 8, 197, 8, 149, 143, 48, 144, 65, 13, 138, 195, 174, 14, 22, 15, 12, 2, 21, 18, 1, 68, 8, 197, 5, 69, 78, 12, 144, 8, 0, 10, 135, 197, 159, 5, 4, 5, 18, 5, 66, 9, 198, 17, 84, 133, 72, 146, 64, 66, 17, 70, 16, 148, 208, 48, 22, 64, 72, 37, 89, 48, 55, 6, 36, 57, 0, 0, 10, 199, 12, 243, 131, 20, 229, 18, 4, 67, 11, 136, 1, 12, 196, 131, 20, 21, 18, 1, 68, 13, 3, 95, 54, 88, 91, 6, 117, 88, 36, 76, 124, 0, 14, 3, 95, 57, 48, 50, 131, 13, 88, 6, 36, 76, 124, 0, 0, 0, 13, 138, 195, 174, 14, 3, 196, 131, 16, 5, 18, 5, 67, 9, 198, 12, 20, 137, 12, 21, 21, 68, 0, 9, 198, 76, 51, 193, 80, 83, 64, 65, 0, 7, 195, 88, 243, 64, 76, 32, 0, 0, 15, 69, 65, 35, 208, 85, 48, 48, 34, 39, 48, 6, 40, 89, 0, 8, 197, 36, 229, 133, 73, 48, 65, 15, 69, 36, 224, 204, 85, 48, 37, 50, 49, 55, 6, 40, 89, 0, 15, 69, 12, 243, 80, 85, 48, 49, 39, 65, 48, 6, 40, 89, 0, 9, 198, 8, 193, 83, 80, 83, 65, 67, 0, 0, 12, 136, 1, 12, 196, 131, 20, 21, 18, 9, 66, 28, 0, 6, 131, 13, 196, 131, 72, 0, 8, 197, 88, 148, 195, 60, 192, 65, 0, 9, 198, 16, 80, 201, 16, 80, 64, 67, 16, 70, 81, 33, 73, 48, 80, 64, 47, 14, 16, 6, 118, 55, 135, 0, 0, 0, 13, 68, 84, 208, 140, 36, 6, 40, 65, 71, 55, 37, 0, 7, 196, 12, 83, 154, 84, 66, 0, 0, 11, 136, 3, 18, 195, 162, 14, 3, 5, 14, 65, 0, 18, 7, 15, 18, 9, 3, 195, 162, 20, 39, 16, 124, 49, 4, 112, 47, 0, 76, 14, 3, 95, 56, 88, 6, 39, 48, 47, 88, 36, 76, 124, 0, 0, 0, 12, 201, 64, 20, 193, 28, 84, 137, 48, 244, 128, 67, 11, 136, 13, 21, 18, 13, 21, 18, 196, 131, 65, 0, 9, 198, 76, 19, 83, 84, 225, 192, 65, 6, 195, 28, 83, 85, 66, 0, 11, 136, 195, 174, 13, 16, 12, 5, 20, 9, 67, 0, 0, 8, 197, 77, 81, 140, 21, 64, 65, 13, 138, 18, 196, 131, 19, 16, 21, 20, 5, 18, 9, 67, 9, 198, 17, 32, 71, 61, 53, 5, 65, 8, 197, 13, 33, 73, 21, 32, 65, 9, 134, 9, 5, 197, 159, 5, 1, 66, 0, 10, 135, 197, 159, 15, 6, 5, 18, 9, 66, 10, 66, 48, 112, 36, 55, 75, 6, 37, 0, 9, 198, 36, 224, 77, 36, 49, 64, 67, 18, 70, 16, 21, 15, 72, 145, 64, 72, 35, 47, 39, 14, 16, 6, 37, 36, 0, 10, 135, 12, 196, 131, 18, 7, 5, 1, 66, 0, 10, 199, 64, 20, 193, 28, 84, 137, 36, 67, 11, 136, 4, 5, 19, 6, 196, 131, 3, 21, 67, 14, 3, 95, 57, 88, 50, 6, 131, 13, 88, 36, 76, 124, 0, 0, 13, 138, 197, 159, 15, 6, 5, 18, 9, 12, 15, 18, 66, 13, 138, 3, 196, 131, 4, 5, 18, 9, 12, 15, 18, 66, 0, 14, 139, 19, 3, 196, 131, 4, 5, 18, 9, 12, 15, 18, 66, 8, 197, 5, 53, 80, 72, 16, 28, 0, 10, 135, 8, 195, 162, 18, 20, 9, 9, 66, 10, 135, 3, 195, 162, 20, 5, 22, 1, 67, 10, 135, 1, 20, 195, 162, 18, 14, 1, 67, 0, 11, 136, 197, 159, 20, 5, 18, 7, 5, 13, 65, 10, 199, 64, 84, 147, 21, 97, 82, 4, 68, 10, 199, 16, 84, 195, 61, 1, 82, 36, 68, 0, 0, 8, 197, 88, 81, 5, 72, 80, 66, 8, 197, 77, 5, 78, 20, 208, 65, 13, 138, 195, 174, 14, 20, 15, 1, 18, 3, 5, 13, 66, 8, 197, 72, 86, 133, 52, 16, 67, 8, 197, 72, 148, 201, 64, 144, 67, 0, 10, 135, 3, 196, 131, 4, 5, 18, 5, 66, 9, 198, 76, 51, 212, 60, 50, 64, 67, 0, 11, 136, 19, 3, 196, 131, 4, 5, 18, 5, 66, 11, 136, 22, 195, 162, 14, 20, 21, 18, 1, 67, 0, 8, 133, 2, 196, 131, 7, 1, 66, 0, 9, 134, 13, 9, 197, 159, 3, 1, 66, 0, 0, 15, 140, 3, 8, 5, 12, 196, 131, 12, 196, 131, 9, 20, 21, 69, 0, 0, 0, 0, 6, 194, 36, 224, 72, 28, 0, 11, 67, 77, 82, 84, 89, 40, 6, 37, 47, 0, 12, 137, 195, 174, 13, 16, 21, 197, 159, 3, 1, 67, 0, 13, 68, 76, 81, 21, 76, 89, 36, 72, 6, 40, 89, 0, 0, 0, 9, 198, 64, 130, 76, 37, 4, 192, 65, 9, 198, 36, 229, 18, 36, 112, 64, 65, 0, 9, 198, 21, 128, 83, 64, 84, 129, 68, 9, 198, 4, 48, 197, 48, 84, 129, 68, 14, 4, 95, 15, 7, 15, 39, 81, 39, 50, 6, 36, 49, 0, 0, 12, 137, 195, 174, 14, 20, 18, 5, 2, 196, 131, 67, 13, 3, 197, 159, 9, 91, 124, 35, 0, 72, 81, 97, 32, 6, 131, 197, 159, 9, 72, 0, 9, 134, 15, 6, 5, 18, 196, 131, 66, 0, 18, 70, 21, 35, 201, 48, 244, 128, 36, 34, 34, 6, 39, 37, 55, 39, 34, 0, 9, 198, 12, 129, 76, 56, 84, 128, 65, 0, 11, 136, 19, 3, 21, 20, 21, 18, 196, 131, 65, 21, 71, 52, 144, 210, 61, 51, 198, 80, 65, 6, 117, 80, 14, 16, 39, 89, 39, 83, 47, 0, 9, 198, 72, 80, 213, 64, 84, 129, 68, 0, 12, 137, 22, 195, 162, 14, 20, 21, 18, 196, 131, 67, 0, 15, 140, 195, 174, 14, 3, 196, 131, 16, 5, 18, 9, 12, 5, 67, 8, 197, 24, 197, 73, 21, 32, 65, 0, 12, 137, 3, 196, 131, 4, 5, 18, 9, 12, 5, 66, 0, 8, 133, 21, 13, 196, 131, 18, 65, 13, 138, 19, 3, 196, 131, 4, 5, 18, 9, 12, 5, 66, 9, 198, 4, 197, 3, 84, 213, 129, 67, 0, 7, 196, 104, 144, 197, 4, 66, 7, 196, 37, 80, 133, 4, 66, 9, 198, 4, 229, 77, 37, 67, 210, 75, 0, 8, 197, 16, 240, 212, 61, 32, 65, 0, 14, 66, 56, 80, 50, 135, 89, 0, 72, 81, 97, 197, 159, 32, 13, 66, 56, 80, 50, 135, 34, 0, 72, 81, 97, 114, 32, 13, 66, 56, 80, 50, 135, 65, 0, 72, 81, 97, 109, 32, 12, 137, 14, 196, 131, 16, 21, 19, 20, 5, 1, 67, 5, 194, 56, 80, 72, 15, 66, 52, 112, 109, 105, 108, 105, 103, 114, 97, 109, 101, 0, 29, 0, 10, 199, 37, 3, 195, 72, 150, 137, 36, 68, 0, 11, 136, 20, 18, 5, 1, 3, 196, 131, 20, 65, 7, 196, 12, 20, 20, 84, 66, 7, 196, 76, 83, 78, 4, 66, 14, 139, 4, 9, 19, 16, 18, 5, 197, 163, 21, 9, 1, 68, 0, 8, 197, 81, 32, 71, 20, 208, 65, 8, 197, 52, 146, 140, 60, 48, 65, 10, 67, 13, 82, 66, 49, 6, 121, 71, 0, 8, 197, 81, 33, 90, 20, 16, 66, 8, 197, 65, 34, 86, 20, 16, 66, 0, 9, 198, 36, 229, 18, 36, 114, 64, 65, 0, 0, 26, 11, 19, 21, 16, 18, 5, 13, 1, 197, 163, 9, 5, 89, 40, 48, 14, 16, 36, 65, 35, 123, 6, 37, 36, 0, 7, 196, 84, 225, 76, 20, 73, 0, 8, 197, 60, 34, 67, 20, 144, 67, 8, 197, 56, 149, 133, 48, 80, 66, 8, 197, 36, 225, 9, 28, 240, 67, 11, 136, 3, 195, 162, 20, 15, 18, 22, 1, 67, 11, 136, 3, 196, 131, 197, 159, 21, 14, 1, 67, 8, 197, 16, 147, 148, 72, 80, 28, 7, 131, 195, 174, 14, 72, 28, 0, 12, 66, 57, 80, 50, 40, 37, 0, 72, 81, 105, 32, 9, 198, 4, 101, 82, 37, 50, 64, 68, 5, 194, 57, 80, 76, 0, 6, 131, 195, 174, 12, 72, 0, 6, 195, 52, 146, 137, 66, 15, 4, 95, 48, 77, 52, 71, 37, 55, 6, 57, 138, 50, 36, 0, 0, 11, 136, 195, 174, 14, 4, 15, 9, 20, 21, 68, 16, 140, 4, 5, 19, 16, 196, 131, 18, 197, 163, 9, 20, 21, 68, 18, 16, 4, 95, 48, 77, 53, 71, 37, 55, 6, 57, 35, 34, 72, 36, 0, 0, 6, 195, 21, 3, 195, 65, 15, 4, 95, 48, 77, 50, 65, 37, 55, 6, 57, 138, 50, 36, 0, 0, 6, 195, 13, 83, 64, 8, 16, 4, 95, 48, 77, 51, 65, 37, 55, 6, 57, 35, 34, 72, 36, 0, 0, 6, 131, 195, 174, 9, 72, 0, 8, 197, 4, 52, 137, 81, 80, 67, 10, 4, 95, 48, 77, 49, 65, 6, 132, 0, 0, 12, 137, 16, 18, 15, 14, 21, 14, 197, 163, 1, 67, 14, 4, 95, 2, 18, 22, 49, 13, 76, 6, 40, 55, 13, 0, 0, 6, 195, 36, 20, 128, 8, 0, 6, 195, 5, 3, 201, 66, 6, 195, 52, 148, 129, 66, 0, 0, 0, 9, 198, 16, 80, 197, 48, 84, 129, 68, 7, 195, 88, 244, 128, 76, 32, 0, 7, 196, 37, 4, 207, 76, 65, 0, 0, 9, 198, 77, 64, 78, 16, 20, 132, 65, 17, 70, 20, 97, 67, 81, 80, 64, 36, 83, 36, 49, 47, 58, 6, 35, 0, 0, 11, 136, 12, 9, 14, 7, 21, 18, 196, 131, 65, 0, 6, 195, 60, 101, 1, 66, 0, 13, 5, 15, 13, 196, 131, 20, 39, 65, 6, 13, 47, 0, 0, 0, 13, 138, 3, 21, 14, 15, 1, 197, 159, 20, 5, 13, 66, 0, 6, 195, 12, 85, 129, 66, 10, 135, 19, 20, 196, 131, 20, 5, 1, 66, 10, 135, 195, 174, 14, 4, 15, 9, 1, 67, 7, 196, 84, 225, 73, 4, 77, 0, 0, 9, 194, 52, 144, 72, 81, 97, 114, 32, 9, 194, 52, 144, 72, 81, 97, 105, 32, 9, 194, 52, 144, 72, 81, 97, 109, 32, 13, 66, 52, 144, 65, 37, 4, 36, 0, 72, 81, 101, 32, 5, 194, 52, 144, 72, 29, 66, 44, 208, 49, 37, 55, 39, 65, 6, 36, 47, 14, 16, 37, 11, 48, 36, 15, 6, 39, 34, 13, 0, 82, 47, 32, 104, 32, 15, 66, 44, 208, 107, 105, 108, 111, 109, 101, 116, 114, 105, 0, 29, 0, 9, 134, 4, 196, 131, 4, 5, 1, 66, 0, 7, 196, 56, 147, 73, 12, 66, 6, 195, 12, 84, 149, 66, 0, 8, 197, 85, 35, 5, 80, 80, 65, 8, 197, 81, 83, 133, 80, 80, 65, 8, 197, 77, 83, 133, 80, 80, 65, 8, 197, 88, 19, 15, 72, 16, 67, 15, 69, 77, 64, 71, 56, 16, 89, 47, 35, 81, 50, 6, 35, 0, 8, 197, 64, 244, 142, 20, 16, 66, 0, 9, 198, 72, 81, 197, 49, 82, 64, 65, 0, 17, 5, 195, 174, 14, 20, 18, 112, 50, 47, 14, 16, 39, 0, 81, 111, 32, 9, 134, 4, 196, 131, 21, 14, 1, 67, 0, 10, 135, 13, 9, 197, 159, 21, 14, 1, 67, 0, 8, 197, 88, 81, 5, 72, 144, 66, 8, 197, 88, 20, 201, 48, 80, 66, 8, 197, 65, 35, 208, 84, 144, 66, 24, 73, 65, 34, 69, 80, 83, 149, 49, 82, 64, 48, 14, 16, 57, 6, 36, 47, 36, 50, 40, 55, 121, 0, 8, 197, 64, 149, 9, 12, 144, 66, 11, 136, 13, 195, 162, 14, 5, 3, 9, 9, 66, 8, 197, 48, 145, 5, 72, 144, 65, 8, 197, 32, 18, 1, 48, 80, 67, 8, 197, 16, 81, 197, 80, 80, 65, 8, 197, 17, 82, 14, 20, 16, 66, 8, 197, 9, 80, 213, 72, 16, 67, 8, 197, 76, 100, 137, 40, 144, 66, 0, 6, 195, 52, 20, 143, 66, 8, 133, 20, 195, 162, 18, 1, 66, 21, 9, 6, 9, 5, 3, 196, 131, 18, 21, 9, 83, 57, 36, 49, 6, 13, 34, 121, 0, 72, 0, 0, 0, 15, 69, 76, 84, 135, 37, 80, 89, 6, 36, 34, 75, 57, 40, 0, 11, 136, 3, 12, 196, 131, 20, 9, 14, 1, 67, 0, 11, 5, 95, 15, 6, 77, 49, 65, 6, 132, 0, 0, 0, 7, 196, 20, 97, 77, 20, 67, 0, 8, 197, 29, 32, 84, 37, 48, 65, 8, 197, 13, 33, 65, 81, 80, 67, 0, 0, 0, 13, 68, 88, 242, 76, 4, 84, 40, 35, 55, 6, 35, 0, 0, 0, 9, 198, 28, 84, 141, 36, 224, 64, 67, 0, 9, 134, 19, 3, 196, 131, 16, 1, 66, 6, 195, 77, 80, 128, 28, 0, 7, 196, 61, 32, 129, 56, 65, 7, 196, 24, 150, 137, 12, 65, 7, 196, 60, 51, 204, 36, 67, 0, 0, 9, 198, 64, 243, 15, 56, 144, 192, 67, 9, 198, 8, 148, 197, 72, 144, 192, 66, 9, 198, 16, 84, 197, 52, 224, 64, 67, 0, 13, 138, 6, 12, 196, 131, 3, 196, 131, 18, 9, 9, 65, 13, 138, 195, 174, 13, 16, 196, 131, 18, 197, 163, 9, 67, 6, 195, 77, 83, 148, 76, 6, 195, 77, 83, 148, 76, 0, 7, 196, 64, 195, 213, 4, 66, 0, 0, 13, 5, 197, 159, 20, 9, 1, 91, 47, 6, 57, 35, 0, 0, 0, 11, 67, 4, 144, 201, 35, 6, 37, 76, 124, 0, 10, 135, 26, 7, 195, 162, 18, 9, 1, 67, 0, 0, 13, 5, 197, 159, 20, 9, 5, 91, 47, 6, 37, 36, 0, 9, 198, 48, 147, 80, 20, 65, 64, 65, 5, 194, 56, 144, 72, 12, 137, 195, 174, 14, 20, 195, 162, 12, 14, 9, 67, 6, 194, 64, 80, 72, 28, 0, 9, 198, 64, 21, 18, 84, 193, 65, 65, 0, 11, 67, 4, 34, 65, 35, 71, 57, 6, 35, 0, 0, 12, 201, 64, 20, 148, 20, 225, 82, 20, 193, 64, 67, 8, 197, 28, 83, 69, 80, 80, 65, 9, 198, 16, 84, 203, 80, 244, 0, 65, 0, 9, 198, 77, 3, 5, 56, 66, 68, 65, 12, 137, 13, 195, 162, 14, 7, 195, 162, 9, 1, 67, 9, 198, 72, 245, 21, 56, 162, 64, 67, 0, 10, 199, 28, 147, 78, 5, 53, 9, 12, 66, 0, 0, 8, 197, 36, 229, 9, 52, 80, 65, 8, 197, 60, 97, 82, 20, 16, 67, 8, 197, 4, 37, 82, 20, 16, 66, 8, 197, 77, 68, 137, 88, 144, 66, 0, 9, 198, 76, 20, 131, 36, 226, 64, 65, 9, 198, 52, 20, 135, 36, 226, 64, 65, 0, 10, 199, 88, 150, 149, 4, 194, 90, 4, 68, 13, 138, 4, 5, 19, 16, 196, 131, 18, 197, 163, 9, 67, 9, 134, 1, 22, 5, 197, 163, 9, 76, 0, 10, 135, 21, 9, 20, 196, 131, 20, 21, 67, 0, 0, 18, 70, 65, 34, 69, 80, 83, 128, 48, 14, 16, 57, 6, 36, 47, 36, 50, 0, 12, 137, 18, 196, 131, 19, 20, 21, 18, 14, 1, 67, 19, 4, 95, 3, 9, 18, 76, 37, 34, 49, 40, 65, 83, 55, 6, 36, 49, 89, 0, 0, 13, 138, 22, 196, 131, 9, 5, 20, 196, 131, 20, 21, 68, 6, 195, 4, 34, 76, 66, 0, 7, 196, 48, 147, 73, 80, 65, 14, 139, 195, 174, 14, 197, 163, 5, 16, 196, 131, 20, 21, 68, 7, 196, 24, 16, 197, 52, 65, 6, 195, 85, 35, 1, 66, 6, 195, 77, 83, 129, 66, 10, 135, 1, 14, 21, 14, 197, 163, 1, 67, 0, 15, 69, 61, 98, 68, 37, 80, 39, 84, 6, 37, 72, 57, 40, 0, 19, 8, 5, 24, 39, 15, 20, 9, 3, 5, 36, 81, 88, 39, 47, 37, 76, 36, 0, 0, 15, 66, 52, 192, 109, 105, 108, 105, 108, 105, 116, 114, 105, 0, 29, 0, 9, 198, 52, 20, 135, 36, 226, 73, 65, 9, 134, 18, 195, 162, 6, 14, 9, 66, 0, 0, 9, 134, 12, 196, 131, 19, 196, 131, 66, 11, 136, 14, 196, 131, 16, 21, 19, 20, 9, 67, 0, 9, 198, 80, 84, 141, 36, 224, 64, 67, 9, 198, 65, 35, 212, 20, 160, 64, 67, 12, 137, 195, 174, 14, 196, 131, 12, 197, 163, 1, 67, 9, 198, 20, 194, 77, 36, 224, 64, 68, 9, 198, 12, 192, 88, 60, 224, 64, 67, 8, 3, 95, 196, 131, 6, 13, 0, 0, 9, 198, 5, 37, 5, 24, 144, 197, 67, 9, 134, 1, 18, 196, 131, 20, 1, 67, 0, 12, 137, 4, 15, 13, 14, 9, 197, 163, 196, 131, 66, 15, 3, 197, 163, 9, 123, 57, 39, 57, 0, 72, 81, 111, 105, 32, 15, 3, 197, 163, 9, 123, 57, 35, 34, 0, 72, 81, 97, 114, 32, 15, 3, 197, 163, 9, 123, 57, 35, 65, 0, 72, 81, 97, 109, 32, 14, 3, 197, 163, 9, 123, 6, 57, 36, 0, 72, 81, 101, 32, 14, 3, 197, 163, 9, 123, 57, 117, 0, 72, 81, 97, 105, 32, 14, 3, 197, 163, 9, 123, 57, 114, 0, 72, 81, 97, 117, 32, 15, 3, 197, 163, 9, 123, 57, 35, 34, 0, 72, 81, 97, 114, 32, 15, 3, 197, 163, 9, 123, 57, 35, 65, 0, 72, 81, 97, 109, 32, 6, 131, 197, 163, 9, 72, 0, 9, 134, 2, 196, 131, 7, 196, 131, 66, 13, 138, 1, 13, 5, 14, 9, 14, 197, 163, 196, 131, 66, 0, 9, 198, 56, 144, 201, 84, 224, 64, 77, 0, 9, 198, 52, 241, 9, 24, 144, 193, 68, 12, 4, 95, 19, 20, 11, 89, 55, 6, 36, 91, 0, 0, 7, 196, 76, 80, 207, 48, 65, 0, 11, 136, 16, 196, 131, 18, 5, 18, 9, 9, 66, 8, 197, 8, 19, 9, 57, 64, 65, 8, 197, 4, 192, 133, 73, 64, 65, 15, 4, 95, 1, 3, 21, 35, 89, 49, 40, 123, 6, 37, 47, 0, 0, 9, 198, 80, 84, 141, 36, 225, 64, 65, 0, 10, 199, 12, 129, 82, 21, 53, 5, 4, 67, 9, 134, 13, 195, 162, 14, 10, 9, 66, 0, 7, 196, 5, 33, 5, 4, 66, 0, 8, 197, 104, 115, 205, 61, 64, 65, 13, 3, 95, 195, 174, 4, 112, 72, 37, 50, 6, 37, 0, 0, 5, 194, 76, 16, 76, 15, 66, 52, 208, 109, 105, 108, 105, 109, 101, 116, 114, 105, 0, 29, 0, 9, 198, 5, 49, 77, 20, 225, 65, 66, 9, 198, 4, 194, 77, 20, 229, 1, 68, 6, 195, 24, 244, 212, 76, 0, 6, 195, 76, 80, 213, 66, 9, 198, 72, 245, 15, 12, 243, 0, 67, 7, 196, 84, 227, 210, 4, 77, 0, 8, 197, 17, 84, 133, 72, 80, 66, 12, 201, 12, 20, 129, 13, 65, 82, 20, 193, 64, 67, 8, 197, 72, 83, 1, 96, 16, 67, 15, 140, 195, 174, 13, 16, 18, 196, 131, 197, 159, 20, 9, 1, 67, 0, 9, 198, 56, 144, 201, 84, 229, 76, 77, 9, 198, 56, 144, 201, 84, 229, 76, 77, 0, 9, 134, 1, 16, 196, 131, 18, 1, 67, 0, 10, 135, 19, 21, 16, 196, 131, 18, 1, 67, 0, 8, 197, 88, 244, 19, 20, 16, 66, 8, 197, 84, 50, 68, 20, 208, 66, 8, 197, 64, 21, 9, 52, 144, 65, 8, 197, 61, 33, 9, 56, 80, 65, 8, 197, 32, 18, 68, 20, 208, 65, 8, 197, 24, 84, 137, 12, 80, 65, 9, 198, 21, 2, 83, 12, 244, 0, 66, 11, 136, 3, 21, 13, 16, 196, 131, 18, 1, 67, 0, 9, 198, 80, 84, 141, 20, 226, 64, 65, 0, 9, 134, 21, 18, 196, 131, 20, 21, 67, 0, 16, 70, 84, 225, 200, 37, 83, 0, 6, 40, 50, 81, 57, 40, 55, 0, 14, 139, 195, 174, 14, 22, 18, 5, 4, 14, 9, 3, 9, 68, 0, 11, 136, 1, 4, 21, 14, 196, 131, 20, 21, 68, 13, 3, 95, 195, 162, 4, 112, 72, 37, 50, 6, 35, 0, 0, 12, 137, 21, 19, 20, 21, 18, 196, 131, 20, 21, 68, 0, 13, 138, 13, 196, 131, 20, 21, 18, 196, 131, 20, 21, 68, 9, 134, 1, 16, 196, 131, 19, 1, 67, 0, 14, 139, 4, 196, 131, 18, 195, 162, 13, 196, 131, 20, 21, 68, 7, 196, 64, 193, 67, 4, 66, 0, 11, 136, 18, 5, 14, 21, 14, 197, 163, 1, 67, 0, 12, 137, 1, 13, 5, 14, 9, 14, 197, 163, 1, 68, 0, 9, 198, 56, 144, 201, 84, 226, 73, 77, 0, 0, 0, 12, 137, 3, 195, 162, 197, 159, 20, 9, 7, 1, 67, 0, 11, 67, 21, 32, 64, 57, 36, 16, 35, 0, 78, 0, 0, 11, 136, 4, 5, 16, 196, 131, 197, 159, 9, 67, 0, 17, 70, 56, 84, 213, 65, 84, 192, 50, 36, 89, 40, 48, 6, 40, 89, 0, 9, 198, 64, 19, 148, 21, 32, 64, 66, 9, 198, 4, 197, 3, 21, 96, 64, 67, 9, 198, 76, 53, 84, 85, 32, 64, 67, 9, 198, 12, 243, 5, 13, 64, 64, 67, 0, 6, 195, 5, 33, 64, 76, 0, 12, 137, 3, 21, 22, 195, 162, 14, 20, 196, 131, 67, 12, 137, 3, 15, 14, 20, 18, 15, 12, 196, 131, 67, 12, 67, 21, 32, 77, 57, 36, 16, 35, 65, 0, 78, 9, 134, 3, 196, 131, 18, 15, 18, 73, 0, 9, 134, 13, 195, 162, 14, 5, 3, 65, 16, 69, 9, 35, 203, 21, 32, 71, 14, 16, 6, 39, 49, 13, 34, 0, 0, 9, 198, 80, 20, 212, 5, 69, 64, 67, 9, 198, 13, 33, 68, 37, 65, 64, 65, 9, 198, 12, 195, 195, 61, 65, 64, 65, 16, 70, 8, 19, 142, 21, 33, 64, 71, 6, 36, 50, 13, 16, 36, 0, 21, 4, 95, 1, 3, 50, 72, 6, 40, 71, 55, 40, 35, 89, 49, 40, 6, 123, 37, 47, 0, 0, 9, 198, 81, 35, 211, 56, 85, 5, 65, 9, 198, 12, 243, 147, 80, 21, 1, 67, 0, 7, 196, 20, 194, 67, 20, 66, 7, 196, 12, 129, 77, 4, 66, 6, 195, 77, 80, 201, 66, 11, 67, 21, 32, 73, 57, 36, 16, 117, 0, 78, 0, 8, 197, 76, 83, 154, 61, 32, 65, 8, 197, 64, 144, 212, 61, 32, 65, 8, 197, 24, 16, 212, 61, 32, 65, 14, 69, 8, 16, 203, 85, 0, 71, 6, 36, 49, 35, 48, 0, 0, 9, 198, 77, 2, 82, 37, 65, 64, 65, 9, 66, 60, 176, 39, 49, 6, 118, 0, 12, 137, 18, 196, 131, 13, 195, 162, 14, 5, 1, 67, 12, 137, 195, 174, 13, 2, 21, 12, 26, 5, 1, 67, 5, 194, 80, 16, 76, 0, 10, 199, 72, 80, 213, 56, 244, 195, 84, 67, 9, 198, 77, 84, 208, 20, 53, 1, 67, 13, 138, 19, 20, 196, 131, 16, 195, 162, 14, 5, 1, 67, 9, 134, 16, 195, 162, 14, 4, 9, 66, 0, 7, 196, 88, 146, 84, 84, 66, 7, 196, 84, 209, 68, 20, 65, 6, 195, 24, 147, 9, 66, 11, 67, 21, 32, 85, 57, 36, 16, 114, 0, 78, 0, 11, 136, 16, 196, 131, 18, 5, 18, 5, 1, 66, 8, 197, 28, 83, 133, 72, 16, 67, 8, 197, 13, 33, 68, 20, 16, 67, 0, 0, 19, 71, 80, 245, 4, 20, 21, 78, 4, 47, 39, 47, 72, 135, 6, 40, 50, 35, 0, 13, 138, 195, 174, 14, 3, 196, 131, 12, 26, 5, 1, 67, 13, 138, 18, 196, 131, 19, 16, 195, 162, 14, 4, 9, 67, 9, 134, 16, 196, 131, 197, 159, 9, 66, 0, 7, 196, 56, 144, 201, 60, 77, 0, 8, 197, 88, 149, 18, 20, 112, 65, 8, 197, 36, 225, 201, 56, 80, 67, 8, 197, 72, 244, 212, 20, 16, 66, 8, 197, 72, 145, 9, 12, 16, 67, 8, 197, 16, 81, 9, 12, 16, 67, 16, 69, 81, 33, 66, 84, 144, 47, 14, 16, 36, 71, 58, 6, 37, 0, 8, 197, 4, 197, 15, 72, 16, 77, 0, 17, 70, 72, 20, 133, 61, 34, 64, 34, 35, 16, 36, 6, 39, 145, 124, 0, 0, 18, 70, 24, 20, 134, 85, 34, 69, 83, 35, 34, 83, 40, 16, 6, 37, 36, 0, 9, 134, 1, 12, 5, 197, 159, 9, 66, 0, 7, 196, 52, 22, 9, 52, 65, 0, 0, 12, 201, 64, 20, 148, 20, 225, 82, 84, 197, 73, 67, 0, 13, 138, 1, 4, 195, 162, 14, 3, 196, 131, 20, 21, 68, 0, 0, 0, 12, 137, 195, 174, 14, 3, 196, 131, 18, 3, 1, 67, 12, 137, 3, 196, 131, 12, 196, 131, 21, 26, 9, 68, 0, 6, 195, 5, 34, 80, 65, 11, 136, 195, 174, 14, 3, 15, 20, 18, 15, 67, 0, 8, 133, 18, 21, 12, 196, 131, 66, 7, 196, 28, 150, 143, 72, 65, 0, 8, 197, 36, 208, 71, 36, 224, 66, 8, 2, 196, 131, 6, 13, 0, 14, 0, 9, 198, 20, 194, 66, 21, 32, 64, 68, 0, 0, 8, 133, 15, 6, 20, 196, 131, 66, 12, 137, 195, 174, 14, 3, 5, 18, 3, 196, 131, 67, 0, 8, 197, 65, 34, 67, 36, 224, 65, 0, 8, 133, 22, 196, 131, 26, 21, 66, 8, 133, 197, 163, 9, 14, 21, 66, 9, 198, 72, 240, 133, 73, 64, 64, 66, 9, 198, 16, 148, 208, 21, 32, 64, 67, 9, 198, 16, 84, 9, 77, 64, 64, 67, 9, 198, 16, 83, 5, 13, 64, 64, 67, 21, 9, 15, 18, 9, 3, 196, 131, 18, 5, 9, 39, 16, 124, 49, 13, 34, 36, 37, 0, 79, 9, 198, 4, 49, 65, 77, 64, 64, 76, 0, 11, 136, 22, 9, 18, 7, 21, 12, 196, 131, 65, 9, 198, 65, 34, 67, 21, 1, 77, 66, 9, 134, 18, 196, 131, 2, 4, 1, 66, 0, 12, 137, 16, 18, 5, 26, 5, 14, 20, 196, 131, 67, 7, 196, 4, 210, 67, 20, 66, 0, 12, 201, 20, 98, 67, 36, 83, 148, 37, 160, 64, 69, 12, 201, 72, 81, 67, 32, 147, 9, 9, 32, 64, 69, 0, 0, 23, 10, 195, 174, 14, 196, 131, 21, 14, 20, 18, 21, 112, 50, 13, 6, 40, 50, 47, 14, 16, 40, 0, 24, 10, 4, 9, 14, 196, 131, 21, 14, 20, 18, 21, 72, 37, 50, 13, 6, 40, 50, 47, 14, 16, 40, 0, 9, 134, 19, 196, 131, 18, 5, 1, 66, 9, 134, 197, 159, 15, 16, 20, 9, 66, 0, 6, 195, 5, 35, 85, 66, 0, 15, 69, 24, 243, 4, 21, 32, 83, 6, 39, 55, 72, 13, 34, 0, 0, 5, 194, 76, 80, 72, 0, 9, 198, 4, 48, 197, 57, 69, 65, 67, 0, 7, 196, 64, 149, 9, 12, 66, 6, 195, 13, 84, 213, 66, 0, 8, 197, 72, 18, 15, 88, 16, 65, 8, 197, 64, 84, 132, 20, 16, 66, 8, 197, 17, 84, 133, 72, 144, 66, 11, 136, 19, 20, 195, 162, 18, 14, 5, 1, 66, 8, 197, 72, 84, 5, 72, 16, 67, 0, 0, 9, 198, 8, 16, 212, 21, 34, 69, 66, 0, 14, 139, 195, 174, 14, 3, 196, 131, 16, 5, 18, 5, 1, 67, 11, 200, 36, 65, 78, 80, 145, 137, 12, 16, 69, 7, 196, 76, 84, 150, 36, 66, 0, 8, 197, 5, 37, 5, 72, 16, 66, 8, 197, 12, 194, 78, 80, 144, 66, 0, 9, 198, 4, 36, 207, 49, 98, 64, 68, 0, 12, 137, 16, 196, 131, 9, 1, 14, 10, 5, 14, 66, 0, 7, 196, 64, 21, 9, 52, 65, 7, 196, 48, 148, 19, 36, 66, 7, 196, 16, 81, 197, 80, 65, 11, 200, 16, 84, 208, 72, 147, 132, 20, 16, 67, 13, 2, 195, 162, 4, 112, 72, 37, 50, 6, 35, 0, 14, 0, 16, 69, 81, 32, 68, 85, 48, 47, 14, 16, 35, 72, 6, 40, 89, 0, 15, 6, 18, 196, 131, 16, 21, 19, 34, 13, 48, 6, 40, 89, 0, 16, 69, 17, 32, 68, 85, 48, 47, 14, 16, 35, 72, 6, 40, 89, 0, 11, 136, 1, 3, 5, 9, 1, 197, 159, 9, 66, 0, 12, 137, 18, 196, 131, 13, 195, 162, 14, 5, 13, 66, 0, 9, 198, 12, 192, 86, 36, 21, 21, 67, 9, 134, 13, 195, 162, 14, 3, 1, 66, 13, 2, 194, 169, 49, 6, 35, 48, 37, 34, 117, 47, 0, 0, 7, 196, 36, 229, 9, 52, 65, 19, 70, 12, 243, 80, 85, 65, 82, 49, 39, 65, 48, 6, 57, 40, 47, 13, 34, 0, 7, 196, 5, 33, 5, 52, 65, 13, 2, 195, 174, 4, 112, 72, 37, 50, 6, 37, 0, 14, 0, 8, 197, 88, 244, 212, 73, 80, 76, 8, 197, 56, 244, 212, 73, 80, 77, 7, 2, 197, 159, 91, 36, 0, 0, 0, 9, 198, 64, 148, 212, 60, 19, 5, 66, 9, 198, 8, 16, 212, 21, 34, 73, 66, 0, 0, 0, 9, 198, 40, 20, 15, 56, 144, 64, 66, 11, 2, 194, 176, 81, 14, 16, 35, 72, 36, 0, 0, 0, 11, 200, 64, 20, 148, 20, 225, 82, 84, 192, 67, 6, 195, 85, 35, 137, 66, 5, 130, 195, 182, 43, 0, 8, 197, 56, 144, 201, 84, 224, 77, 0, 9, 198, 4, 209, 82, 36, 48, 64, 66, 9, 198, 72, 85, 133, 56, 80, 64, 67, 0, 10, 67, 88, 145, 64, 84, 6, 37, 36, 0, 10, 199, 16, 86, 143, 72, 66, 78, 20, 66, 10, 199, 12, 243, 132, 84, 53, 15, 72, 66, 9, 198, 65, 33, 79, 13, 84, 1, 67, 11, 67, 24, 145, 64, 83, 6, 37, 36, 0, 72, 0, 10, 135, 197, 163, 9, 16, 5, 20, 5, 65, 7, 196, 80, 83, 69, 4, 66, 6, 195, 4, 49, 65, 78, 14, 4, 95, 3, 5, 4, 89, 36, 72, 6, 37, 55, 13, 0, 0, 7, 2, 197, 163, 123, 36, 0, 0, 9, 198, 65, 35, 208, 36, 49, 64, 66, 0, 16, 4, 95, 12, 9, 7, 55, 37, 81, 35, 47, 6, 40, 34, 13, 0, 0, 14, 139, 195, 174, 14, 3, 196, 131, 16, 5, 18, 9, 9, 67, 0, 11, 136, 195, 174, 14, 6, 9, 7, 5, 1, 67, 0, 9, 198, 52, 21, 18, 36, 49, 64, 66, 9, 198, 12, 84, 130, 36, 49, 64, 66, 14, 66, 80, 80, 47, 135, 91, 0, 72, 81, 97, 197, 159, 32, 13, 66, 80, 80, 47, 135, 34, 0, 72, 81, 97, 114, 32, 13, 66, 80, 80, 47, 135, 57, 0, 72, 81, 97, 105, 32, 13, 66, 80, 80, 47, 135, 65, 0, 72, 81, 97, 109, 32, 6, 194, 88, 16, 76, 32, 5, 194, 80, 80, 72, 0, 10, 67, 4, 50, 64, 35, 76, 6, 37, 0, 13, 138, 19, 20, 18, 196, 131, 12, 21, 3, 5, 1, 67, 9, 198, 65, 35, 212, 21, 53, 1, 67, 9, 198, 65, 35, 196, 84, 49, 65, 67, 13, 138, 195, 174, 14, 3, 18, 5, 197, 163, 5, 1, 67, 9, 198, 12, 243, 132, 84, 49, 65, 67, 8, 67, 88, 146, 64, 84, 132, 0, 0, 7, 196, 4, 49, 76, 20, 78, 6, 195, 4, 49, 73, 76, 0, 8, 197, 76, 51, 212, 20, 16, 66, 8, 197, 52, 84, 137, 80, 16, 67, 0, 9, 198, 60, 227, 198, 72, 82, 64, 67, 9, 198, 60, 19, 69, 56, 146, 64, 65, 9, 198, 56, 21, 21, 72, 146, 64, 67, 0, 18, 70, 88, 19, 5, 56, 50, 65, 84, 35, 55, 6, 36, 50, 89, 57, 35, 0, 10, 199, 4, 116, 137, 13, 83, 20, 84, 68, 10, 199, 13, 85, 18, 20, 145, 82, 4, 68, 13, 138, 195, 174, 13, 16, 196, 131, 20, 21, 18, 9, 69, 6, 195, 4, 49, 76, 76, 0, 10, 135, 197, 163, 196, 131, 18, 9, 9, 65, 9, 198, 12, 20, 9, 80, 243, 0, 66, 7, 196, 4, 130, 76, 20, 66, 7, 196, 4, 65, 82, 4, 67, 14, 139, 18, 5, 195, 174, 14, 20, 195, 162, 12, 14, 9, 68, 0, 8, 197, 72, 145, 9, 12, 80, 66, 11, 136, 16, 18, 196, 131, 10, 9, 20, 21, 67, 8, 197, 16, 83, 154, 36, 48, 66, 8, 197, 52, 83, 79, 72, 16, 67, 8, 197, 16, 243, 73, 56, 16, 67, 8, 197, 16, 84, 149, 48, 16, 67, 8, 197, 60, 52, 143, 80, 144, 67, 11, 136, 13, 21, 12, 197, 163, 21, 13, 9, 67, 0, 9, 198, 80, 84, 129, 64, 146, 64, 67, 5, 194, 81, 80, 76, 0, 10, 199, 4, 197, 21, 56, 65, 86, 4, 68, 9, 198, 4, 49, 83, 80, 82, 65, 78, 0, 9, 198, 88, 82, 9, 13, 83, 0, 66, 7, 196, 4, 210, 67, 36, 66, 7, 196, 8, 195, 195, 4, 67, 11, 200, 8, 192, 71, 61, 51, 15, 88, 144, 68, 0, 15, 69, 65, 35, 196, 85, 48, 48, 16, 39, 72, 6, 40, 89, 0, 15, 69, 21, 128, 204, 85, 48, 36, 101, 49, 55, 6, 40, 89, 0, 15, 69, 12, 243, 132, 85, 48, 49, 39, 50, 72, 6, 40, 89, 0, 0, 0, 9, 198, 88, 82, 9, 13, 83, 5, 66, 9, 134, 3, 196, 131, 19, 3, 1, 66, 0, 12, 68, 56, 85, 143, 36, 50, 36, 84, 6, 120, 0, 13, 68, 48, 149, 137, 84, 55, 6, 37, 84, 57, 40, 0, 6, 195, 37, 160, 137, 66, 0, 15, 140, 19, 20, 18, 196, 131, 6, 21, 12, 7, 5, 18, 1, 68, 0, 0, 10, 135, 26, 195, 162, 13, 2, 5, 20, 65, 9, 198, 4, 209, 82, 36, 50, 73, 66, 0, 0, 9, 197, 4, 197, 6, 20, 192, 65, 28, 0, 9, 198, 77, 84, 21, 56, 80, 64, 67, 9, 198, 77, 5, 77, 20, 112, 64, 68, 9, 198, 72, 81, 133, 72, 80, 64, 67, 17, 70, 56, 81, 207, 12, 144, 64, 50, 36, 81, 39, 76, 37, 6, 35, 0, 12, 137, 195, 174, 13, 2, 18, 196, 131, 3, 1, 67, 12, 137, 195, 174, 14, 3, 196, 131, 12, 26, 9, 67, 0, 21, 71, 65, 33, 68, 37, 52, 21, 76, 48, 14, 16, 36, 72, 37, 89, 48, 6, 40, 89, 0, 11, 136, 7, 195, 162, 4, 9, 12, 196, 131, 65, 0, 7, 196, 36, 229, 18, 20, 28, 11, 67, 17, 84, 1, 72, 40, 48, 13, 0, 28, 0, 11, 136, 26, 195, 162, 13, 2, 5, 20, 5, 65, 13, 138, 195, 174, 14, 4, 18, 5, 16, 20, 196, 131, 67, 0, 9, 198, 24, 243, 15, 76, 80, 64, 67, 9, 198, 16, 85, 133, 56, 80, 64, 67, 9, 198, 4, 165, 78, 28, 80, 64, 67, 0, 0, 12, 67, 21, 53, 5, 57, 36, 89, 47, 36, 0, 76, 6, 195, 5, 53, 1, 76, 0, 0, 9, 198, 37, 53, 5, 72, 145, 64, 67, 0, 9, 134, 197, 159, 15, 19, 5, 1, 66, 12, 201, 64, 20, 148, 20, 225, 82, 36, 195, 210, 67, 9, 134, 7, 196, 131, 19, 5, 1, 66, 0, 11, 67, 104, 149, 65, 88, 6, 37, 122, 35, 0, 11, 200, 56, 244, 212, 36, 209, 76, 61, 32, 65, 14, 139, 195, 174, 14, 197, 163, 5, 12, 5, 7, 5, 13, 67, 7, 196, 36, 226, 77, 4, 65, 7, 196, 12, 130, 77, 36, 20, 10, 135, 19, 9, 13, 197, 163, 5, 1, 66, 0, 11, 136, 18, 196, 131, 19, 21, 3, 5, 1, 67, 0, 17, 70, 88, 84, 154, 84, 145, 64, 84, 36, 34, 88, 6, 40, 57, 36, 0, 18, 70, 65, 35, 211, 80, 145, 64, 48, 14, 16, 39, 89, 47, 6, 37, 36, 0, 9, 198, 56, 244, 212, 36, 209, 64, 65, 8, 133, 6, 196, 131, 3, 21, 66, 9, 198, 16, 83, 154, 36, 49, 64, 66, 9, 198, 13, 32, 84, 36, 209, 64, 65, 0, 12, 201, 64, 20, 148, 20, 225, 82, 20, 195, 210, 67, 9, 134, 26, 196, 131, 3, 5, 1, 66, 9, 134, 18, 196, 131, 3, 5, 1, 66, 9, 134, 6, 196, 131, 3, 5, 1, 66, 0, 10, 135, 195, 174, 14, 20, 195, 162, 9, 66, 7, 196, 33, 83, 143, 72, 65, 7, 196, 20, 112, 76, 20, 66, 14, 139, 195, 174, 14, 197, 163, 5, 12, 5, 7, 5, 1, 68, 14, 139, 195, 174, 13, 16, 196, 131, 18, 197, 163, 5, 1, 67, 7, 196, 17, 82, 14, 36, 66, 0, 14, 69, 52, 242, 83, 20, 144, 65, 39, 37, 89, 6, 118, 0, 8, 197, 5, 4, 137, 28, 80, 65, 8, 197, 72, 84, 5, 80, 16, 67, 0, 9, 198, 65, 85, 5, 72, 146, 64, 66, 12, 137, 16, 18, 5, 6, 196, 131, 3, 5, 1, 67, 0, 9, 198, 40, 20, 15, 56, 145, 73, 66, 20, 71, 16, 84, 195, 60, 212, 21, 76, 72, 36, 89, 49, 39, 65, 48, 6, 40, 89, 0, 9, 198, 12, 243, 132, 84, 49, 77, 66, 10, 199, 4, 209, 82, 36, 50, 76, 20, 66, 7, 195, 64, 245, 0, 76, 32, 0, 11, 200, 28, 20, 212, 72, 243, 143, 52, 144, 20, 7, 196, 24, 16, 212, 84, 66, 0, 8, 197, 12, 147, 133, 52, 16, 65, 8, 197, 5, 4, 143, 64, 240, 67, 11, 136, 195, 174, 14, 6, 9, 5, 18, 1, 67, 8, 197, 16, 244, 141, 20, 16, 66, 0, 9, 198, 64, 20, 143, 16, 146, 64, 67, 0, 6, 2, 95, 1, 35, 0, 0, 14, 139, 195, 174, 14, 6, 196, 131, 197, 159, 21, 18, 1, 68, 7, 196, 12, 195, 195, 36, 66, 0, 0, 10, 67, 88, 145, 87, 84, 6, 57, 40, 0, 0, 21, 10, 6, 196, 131, 7, 196, 131, 4, 21, 21, 9, 83, 13, 81, 13, 72, 40, 6, 37, 0, 6, 2, 95, 5, 36, 0, 0, 14, 139, 195, 174, 14, 7, 18, 196, 131, 4, 9, 20, 21, 68, 6, 195, 85, 38, 137, 66, 0, 15, 69, 16, 148, 208, 85, 48, 72, 37, 89, 48, 6, 40, 89, 0, 0, 9, 198, 16, 81, 21, 12, 83, 64, 66, 9, 198, 4, 165, 78, 28, 83, 64, 66, 6, 2, 95, 9, 37, 0, 0, 0, 6, 2, 95, 15, 39, 0, 0, 13, 68, 84, 212, 12, 36, 6, 40, 65, 48, 55, 37, 0, 7, 196, 4, 114, 84, 4, 67, 7, 2, 95, 14, 50, 36, 0, 0, 8, 197, 28, 84, 129, 48, 64, 65, 11, 136, 6, 21, 18, 14, 9, 26, 196, 131, 67, 9, 198, 77, 5, 76, 8, 84, 129, 67, 9, 134, 3, 195, 162, 14, 20, 1, 66, 7, 2, 95, 13, 65, 36, 0, 0, 15, 70, 88, 245, 67, 32, 84, 128, 84, 6, 114, 76, 13, 34, 0, 10, 135, 197, 159, 5, 14, 9, 12, 5, 66, 6, 195, 85, 32, 193, 66, 9, 198, 8, 19, 1, 57, 48, 64, 67, 7, 2, 95, 12, 55, 36, 0, 0, 11, 136, 195, 174, 14, 3, 5, 16, 5, 13, 66, 10, 199, 64, 20, 148, 36, 50, 80, 4, 68, 7, 2, 95, 19, 89, 36, 0, 0, 0, 11, 136, 197, 163, 5, 12, 9, 14, 196, 131, 65, 8, 197, 12, 192, 84, 36, 224, 65, 0, 16, 70, 76, 48, 78, 56, 84, 128, 89, 49, 6, 36, 50, 13, 34, 0, 9, 198, 32, 19, 83, 80, 84, 128, 65, 0, 11, 136, 3, 18, 5, 197, 159, 20, 5, 13, 65, 11, 136, 3, 21, 22, 195, 162, 14, 20, 1, 67, 11, 136, 195, 174, 14, 197, 159, 5, 12, 1, 67, 0, 9, 134, 12, 1, 7, 196, 131, 18, 65, 7, 196, 24, 83, 69, 36, 66, 0, 6, 2, 95, 21, 40, 0, 0, 0, 11, 136, 14, 196, 131, 197, 159, 20, 5, 1, 66, 11, 136, 3, 18, 5, 197, 159, 20, 5, 1, 66, 18, 8, 1, 20, 195, 162, 197, 163, 9, 1, 35, 47, 6, 112, 123, 57, 35, 0, 7, 132, 19, 196, 131, 21, 76, 0, 9, 134, 14, 21, 13, 196, 131, 18, 65, 7, 196, 48, 16, 207, 52, 65, 7, 196, 36, 226, 77, 36, 65, 7, 196, 17, 84, 133, 4, 66, 12, 137, 3, 21, 14, 15, 197, 159, 20, 5, 1, 67, 7, 196, 4, 49, 83, 80, 76, 0, 8, 197, 52, 20, 148, 61, 32, 65, 0, 0, 14, 203, 12, 20, 129, 13, 65, 82, 20, 193, 76, 61, 32, 67, 7, 132, 19, 196, 131, 9, 76, 0, 7, 196, 12, 240, 201, 56, 65, 0, 8, 197, 52, 243, 9, 52, 80, 65, 8, 197, 12, 20, 133, 88, 16, 67, 13, 138, 195, 174, 14, 4, 5, 16, 12, 9, 14, 9, 68, 0, 6, 195, 16, 82, 129, 66, 6, 195, 28, 243, 137, 66, 0, 11, 136, 3, 195, 162, 18, 16, 9, 20, 21, 67, 6, 195, 49, 82, 64, 76, 0, 12, 137, 3, 18, 195, 162, 14, 3, 5, 14, 5, 65, 15, 2, 95, 34, 81, 107, 37, 55, 37, 65, 6, 36, 55, 36, 0, 0, 8, 197, 88, 144, 212, 36, 208, 65, 8, 197, 65, 85, 5, 72, 80, 66, 9, 198, 64, 85, 18, 20, 49, 77, 66, 8, 197, 56, 245, 137, 12, 80, 66, 13, 138, 195, 174, 14, 20, 196, 131, 18, 9, 20, 21, 68, 8, 197, 24, 243, 15, 76, 144, 67, 8, 197, 16, 243, 73, 56, 80, 65, 8, 197, 36, 229, 137, 80, 16, 67, 8, 197, 16, 243, 79, 48, 144, 67, 8, 197, 80, 240, 205, 4, 144, 73, 9, 198, 4, 49, 83, 81, 82, 65, 78, 16, 2, 95, 33, 36, 49, 89, 49, 55, 35, 65, 6, 35, 16, 36, 0, 0, 0, 24, 7, 19, 46, 1, 46, 13, 46, 4, 91, 36, 35, 91, 35, 65, 117, 72, 36, 48, 35, 34, 47, 36, 0, 15, 2, 95, 39, 35, 48, 39, 89, 47, 14, 16, 6, 39, 83, 0, 0, 7, 196, 80, 83, 69, 52, 65, 12, 137, 195, 174, 14, 7, 18, 5, 21, 14, 1, 68, 0, 0, 6, 195, 65, 85, 21, 66, 0, 0, 17, 4, 95, 3, 1, 16, 65, 35, 90, 40, 89, 49, 6, 40, 55, 13, 0, 0, 9, 197, 64, 83, 148, 73, 80, 72, 28, 22, 2, 95, 41, 48, 35, 16, 35, 50, 47, 4, 36, 88, 13, 112, 50, 49, 6, 37, 89, 13, 0, 0, 9, 198, 77, 4, 137, 40, 147, 128, 65, 6, 195, 88, 148, 129, 66, 23, 2, 95, 40, 48, 35, 16, 35, 50, 47, 4, 36, 88, 13, 72, 36, 89, 49, 6, 37, 89, 13, 0, 0, 9, 134, 9, 14, 9, 13, 196, 131, 65, 0, 0, 10, 135, 7, 5, 1, 13, 196, 131, 14, 65, 14, 2, 95, 45, 49, 14, 16, 6, 35, 47, 37, 65, 13, 0, 0, 9, 198, 12, 129, 83, 80, 244, 128, 65, 12, 67, 24, 20, 129, 83, 4, 13, 34, 13, 0, 8, 13, 2, 95, 44, 84, 6, 37, 34, 81, 40, 55, 13, 0, 0, 11, 136, 6, 5, 14, 9, 3, 197, 159, 9, 65, 10, 2, 95, 51, 47, 14, 16, 6, 118, 0, 0, 7, 196, 29, 83, 5, 72, 65, 10, 135, 1, 197, 159, 5, 26, 196, 131, 67, 7, 196, 12, 194, 80, 36, 66, 21, 9, 15, 18, 9, 3, 196, 131, 18, 21, 9, 39, 16, 124, 49, 13, 34, 40, 37, 0, 79, 8, 2, 95, 50, 72, 6, 120, 0, 0, 11, 136, 16, 18, 15, 20, 5, 10, 196, 131, 67, 9, 134, 18, 5, 21, 197, 159, 9, 67, 9, 2, 95, 49, 6, 40, 50, 40, 0, 0, 10, 2, 95, 48, 88, 6, 36, 16, 39, 0, 0, 15, 140, 2, 9, 14, 5, 3, 21, 22, 195, 162, 14, 20, 1, 69, 11, 136, 4, 5, 19, 12, 21, 197, 159, 9, 67, 11, 2, 95, 55, 91, 6, 35, 48, 47, 36, 0, 0, 12, 137, 195, 174, 14, 3, 8, 9, 4, 5, 13, 66, 10, 2, 95, 54, 91, 6, 35, 89, 36, 0, 0, 12, 137, 1, 4, 5, 22, 196, 131, 18, 21, 12, 67, 11, 2, 95, 53, 76, 6, 37, 50, 76, 124, 0, 0, 6, 195, 85, 36, 201, 66, 12, 2, 95, 52, 48, 6, 35, 47, 14, 16, 40, 0, 0, 10, 135, 7, 5, 1, 13, 196, 131, 20, 65, 12, 4, 197, 163, 9, 5, 123, 6, 57, 36, 0, 72, 12, 4, 197, 163, 9, 5, 123, 6, 37, 36, 0, 76, 22, 2, 95, 59, 48, 6, 40, 50, 49, 47, 15, 91, 37, 84, 6, 37, 34, 81, 40, 55, 13, 0, 0, 7, 196, 76, 244, 197, 4, 66, 12, 137, 16, 18, 5, 7, 196, 131, 20, 5, 1, 67, 7, 196, 84, 229, 73, 4, 77, 17, 2, 95, 58, 72, 39, 6, 40, 13, 48, 6, 40, 50, 49, 47, 36, 0, 0, 9, 198, 65, 33, 90, 20, 229, 1, 67, 9, 134, 3, 196, 131, 4, 5, 1, 66, 9, 2, 95, 57, 50, 6, 131, 13, 0, 0, 9, 2, 95, 56, 6, 39, 48, 47, 0, 0, 16, 2, 95, 63, 112, 50, 47, 14, 16, 36, 71, 6, 35, 16, 36, 0, 0, 11, 136, 19, 20, 18, 9, 7, 196, 131, 20, 65, 12, 137, 3, 18, 195, 162, 14, 3, 5, 14, 9, 65, 7, 196, 4, 35, 206, 4, 67, 13, 2, 95, 62, 65, 117, 15, 65, 6, 35, 16, 36, 0, 0, 8, 197, 84, 197, 9, 52, 80, 65, 8, 197, 81, 84, 133, 48, 80, 66, 12, 137, 16, 18, 15, 1, 19, 16, 196, 131, 20, 65, 8, 197, 8, 244, 132, 20, 144, 66, 8, 197, 5, 4, 137, 28, 144, 65, 8, 197, 77, 68, 137, 12, 16, 66, 9, 198, 64, 20, 129, 48, 150, 129, 68, 0, 6, 195, 5, 36, 213, 66, 12, 2, 95, 60, 65, 117, 15, 65, 6, 37, 49, 0, 0, 10, 199, 28, 130, 76, 36, 209, 76, 20, 67, 0, 7, 196, 12, 240, 207, 76, 65, 7, 196, 76, 197, 74, 36, 66, 30, 8, 197, 159, 46, 1, 46, 13, 46, 4, 91, 37, 11, 35, 91, 4, 35, 15, 65, 117, 15, 72, 36, 48, 6, 35, 34, 47, 36, 0, 0, 8, 197, 56, 85, 5, 104, 144, 65, 14, 139, 13, 5, 19, 1, 7, 5, 18, 196, 131, 36, 50, 66, 8, 197, 104, 34, 69, 72, 16, 66, 0, 0, 11, 136, 1, 3, 5, 5, 1, 197, 159, 9, 66, 0, 7, 196, 85, 35, 5, 80, 65, 7, 196, 81, 83, 133, 80, 65, 7, 196, 77, 83, 133, 80, 65, 12, 137, 3, 196, 131, 16, 20, 21, 197, 159, 9, 67, 0, 8, 197, 52, 20, 137, 85, 48, 65, 0, 0, 26, 12, 195, 174, 14, 20, 15, 20, 4, 5, 1, 21, 14, 1, 112, 50, 47, 39, 47, 72, 135, 6, 40, 50, 35, 0, 0, 7, 196, 65, 83, 133, 52, 65, 7, 196, 72, 148, 195, 4, 66, 0, 8, 197, 4, 192, 137, 81, 80, 67, 0, 6, 195, 84, 193, 73, 66, 6, 195, 24, 16, 197, 76, 0, 21, 71, 65, 34, 69, 80, 83, 137, 20, 48, 14, 16, 57, 36, 47, 36, 50, 6, 37, 36, 0, 0, 7, 196, 48, 20, 197, 72, 65, 9, 133, 16, 15, 197, 163, 9, 76, 32, 0, 9, 134, 13, 196, 131, 18, 9, 9, 65, 0, 9, 198, 4, 53, 77, 84, 192, 64, 68, 17, 7, 22, 9, 5, 197, 163, 21, 9, 84, 57, 36, 123, 40, 6, 37, 0, 0, 9, 134, 195, 174, 14, 19, 196, 131, 8, 0, 7, 196, 77, 84, 5, 72, 65, 0, 9, 198, 36, 229, 5, 72, 84, 193, 68, 16, 6, 5, 18, 1, 197, 163, 9, 57, 36, 16, 35, 141, 124, 0, 78, 11, 136, 6, 9, 9, 14, 4, 3, 196, 131, 8, 0, 10, 135, 16, 21, 14, 5, 197, 163, 9, 65, 9, 198, 4, 209, 83, 80, 80, 192, 66, 9, 198, 76, 50, 9, 52, 32, 64, 66, 6, 195, 56, 144, 201, 8, 0, 11, 136, 3, 196, 131, 4, 5, 18, 9, 9, 66, 11, 136, 12, 9, 14, 7, 21, 197, 159, 9, 67, 11, 67, 20, 193, 64, 57, 36, 55, 36, 0, 76, 0, 12, 137, 19, 3, 196, 131, 4, 5, 18, 9, 9, 66, 12, 137, 195, 174, 14, 3, 18, 5, 197, 163, 9, 67, 12, 4, 95, 4, 15, 20, 48, 40, 50, 49, 47, 0, 0, 8, 197, 13, 33, 68, 37, 64, 65, 15, 67, 84, 67, 82, 117, 100, 101, 109, 101, 114, 39, 101, 0, 29, 0, 6, 195, 16, 80, 201, 8, 0, 7, 195, 4, 193, 64, 72, 28, 24, 2, 95, 91, 48, 35, 16, 35, 50, 47, 4, 36, 88, 13, 48, 13, 47, 14, 16, 6, 35, 47, 13, 0, 0, 0, 0, 11, 67, 36, 194, 69, 37, 55, 6, 37, 36, 0, 7, 66, 88, 144, 84, 37, 0, 0, 15, 2, 95, 95, 89, 40, 71, 55, 37, 50, 57, 6, 35, 47, 0, 0, 7, 196, 5, 4, 137, 28, 65, 8, 133, 7, 196, 131, 19, 9, 66, 0, 8, 197, 77, 69, 68, 36, 80, 66, 8, 197, 64, 244, 9, 12, 80, 66, 8, 197, 64, 148, 201, 12, 16, 66, 8, 197, 48, 147, 73, 80, 80, 65, 8, 197, 13, 33, 68, 20, 208, 65, 8, 197, 4, 193, 71, 20, 208, 66, 8, 197, 4, 69, 67, 20, 208, 66, 8, 197, 4, 98, 82, 52, 16, 67, 8, 197, 16, 245, 133, 16, 144, 67, 31, 2, 95, 93, 48, 35, 16, 35, 50, 47, 4, 36, 88, 13, 48, 13, 47, 14, 16, 6, 35, 47, 13, 112, 50, 49, 6, 37, 89, 13, 0, 0, 9, 198, 37, 53, 1, 52, 37, 76, 67, 10, 135, 18, 196, 131, 19, 21, 3, 9, 67, 14, 2, 95, 92, 71, 4, 36, 49, 89, 55, 6, 36, 91, 0, 0, 0, 7, 196, 16, 83, 79, 56, 65, 9, 133, 22, 5, 197, 163, 9, 76, 32, 0, 8, 197, 65, 85, 5, 72, 144, 66, 13, 138, 1, 16, 196, 131, 18, 196, 131, 18, 9, 9, 67, 8, 197, 5, 3, 5, 12, 16, 67, 9, 134, 1, 13, 5, 197, 163, 9, 67, 0, 9, 134, 22, 196, 131, 18, 21, 12, 65, 10, 135, 20, 5, 13, 5, 197, 163, 9, 65, 9, 198, 65, 33, 86, 20, 226, 64, 67, 10, 135, 196, 131, 19, 20, 15, 18, 1, 77, 0, 11, 136, 197, 163, 9, 14, 5, 197, 163, 9, 65, 0, 7, 196, 88, 84, 197, 48, 65, 20, 72, 8, 194, 84, 104, 180, 137, 20, 112, 71, 55, 6, 37, 123, 49, 34, 37, 81, 0, 11, 200, 72, 84, 18, 21, 161, 78, 80, 16, 68, 0, 8, 197, 37, 160, 137, 81, 80, 67, 9, 134, 26, 195, 162, 13, 2, 9, 66, 0, 6, 195, 24, 145, 213, 66, 0, 11, 136, 20, 196, 131, 22, 9, 197, 163, 5, 66, 0, 15, 3, 19, 196, 131, 89, 13, 126, 124, 0, 72, 81, 109, 105, 32, 16, 3, 19, 196, 131, 89, 13, 97, 124, 0, 72, 81, 197, 159, 105, 32, 12, 3, 19, 196, 131, 89, 129, 0, 72, 81, 105, 32, 13, 3, 19, 196, 131, 89, 13, 55, 0, 72, 81, 108, 32, 6, 131, 19, 196, 131, 72, 0, 0, 6, 195, 88, 148, 193, 66, 13, 4, 95, 7, 18, 22, 81, 14, 16, 6, 35, 84, 0, 0, 6, 195, 20, 66, 84, 65, 0, 24, 73, 16, 147, 148, 61, 65, 5, 5, 83, 129, 72, 37, 50, 47, 39, 47, 72, 135, 6, 40, 50, 35, 0, 10, 135, 12, 195, 162, 14, 7, 196, 131, 28, 6, 131, 3, 196, 131, 76, 0, 0, 16, 70, 92, 147, 132, 61, 116, 192, 6, 58, 37, 50, 72, 130, 89, 0, 9, 198, 49, 81, 15, 88, 144, 192, 65, 16, 70, 12, 80, 73, 56, 144, 192, 76, 6, 135, 57, 50, 37, 49, 0, 6, 195, 17, 84, 129, 66, 0, 6, 195, 4, 193, 88, 65, 0, 7, 196, 64, 148, 201, 12, 65, 14, 68, 24, 146, 78, 16, 83, 37, 6, 37, 50, 72, 0, 8, 0, 9, 198, 12, 243, 80, 48, 144, 197, 66, 9, 198, 12, 243, 85, 56, 144, 193, 68, 0, 10, 135, 3, 1, 16, 5, 197, 163, 9, 65, 10, 135, 2, 1, 20, 5, 197, 163, 9, 65, 10, 135, 1, 18, 4, 5, 197, 163, 9, 65, 9, 198, 36, 228, 212, 4, 192, 64, 67, 11, 135, 16, 21, 20, 5, 197, 163, 9, 76, 32, 0, 11, 136, 22, 9, 14, 4, 5, 197, 163, 9, 65, 11, 136, 21, 13, 16, 12, 5, 197, 163, 9, 65, 11, 136, 20, 196, 131, 3, 5, 18, 9, 9, 66, 10, 67, 4, 69, 64, 35, 72, 6, 40, 0, 0, 12, 137, 16, 9, 5, 18, 4, 5, 197, 163, 9, 65, 7, 196, 65, 85, 5, 4, 78, 0, 13, 138, 20, 18, 9, 13, 9, 20, 5, 197, 163, 9, 66, 13, 138, 16, 18, 15, 13, 9, 20, 5, 197, 163, 9, 66, 13, 138, 16, 18, 9, 3, 5, 16, 5, 197, 163, 9, 66, 13, 138, 195, 174, 14, 3, 5, 16, 5, 197, 163, 9, 66, 0, 14, 139, 195, 174, 14, 20, 9, 14, 4, 5, 197, 163, 9, 66, 9, 198, 24, 80, 146, 36, 193, 64, 66, 9, 198, 12, 20, 148, 20, 193, 64, 66, 0, 10, 199, 17, 32, 71, 61, 53, 5, 4, 65, 11, 136, 1, 3, 5, 197, 159, 20, 9, 1, 72, 23, 2, 95, 123, 48, 35, 16, 35, 50, 47, 4, 36, 88, 13, 35, 49, 39, 55, 6, 35, 72, 13, 0, 14, 4, 95, 4, 9, 1, 47, 14, 16, 6, 36, 65, 13, 0, 0, 12, 137, 3, 196, 131, 12, 3, 195, 162, 9, 5, 66, 0, 8, 197, 56, 148, 212, 61, 32, 65, 9, 198, 28, 19, 2, 20, 226, 73, 65, 9, 198, 5, 48, 213, 56, 65, 65, 67, 0, 9, 198, 28, 19, 2, 20, 225, 64, 65, 0, 0, 11, 68, 16, 242, 78, 4, 72, 120, 50, 35, 0, 12, 137, 19, 6, 196, 131, 18, 195, 162, 13, 1, 67, 11, 2, 95, 126, 47, 6, 37, 55, 72, 13, 0, 0, 8, 197, 64, 84, 5, 56, 80, 65, 8, 197, 21, 130, 83, 80, 16, 67, 8, 197, 16, 80, 207, 48, 16, 67, 9, 134, 16, 196, 131, 197, 163, 9, 66, 9, 133, 3, 195, 162, 14, 4, 72, 8, 8, 197, 4, 197, 5, 36, 16, 77, 30, 2, 95, 125, 48, 35, 16, 35, 50, 47, 4, 36, 88, 13, 35, 49, 39, 55, 6, 35, 72, 13, 112, 50, 49, 6, 37, 89, 13, 0, 0, 20, 2, 95, 124, 71, 6, 35, 34, 13, 84, 36, 34, 47, 37, 49, 6, 35, 55, 13, 0, 0, 0, 11, 67, 4, 69, 83, 35, 72, 6, 40, 89, 0, 20, 8, 15, 18, 9, 3, 195, 162, 14, 4, 39, 16, 124, 49, 4, 112, 50, 72, 0, 76, 0, 8, 197, 64, 17, 213, 8, 80, 65, 8, 197, 4, 210, 67, 36, 144, 66, 9, 134, 1, 13, 21, 197, 163, 9, 67, 0, 9, 198, 28, 19, 2, 20, 226, 64, 65, 10, 135, 3, 21, 7, 5, 197, 163, 9, 65, 0, 27, 12, 19, 21, 16, 18, 1, 22, 9, 5, 197, 163, 21, 9, 89, 40, 48, 34, 35, 84, 57, 36, 123, 40, 6, 37, 0, 0, 12, 137, 19, 3, 15, 1, 20, 5, 197, 163, 9, 65, 11, 200, 12, 243, 148, 72, 22, 137, 12, 80, 67, 11, 200, 4, 67, 73, 56, 148, 212, 72, 16, 68, 0, 13, 138, 16, 5, 18, 13, 9, 20, 5, 197, 163, 9, 66, 9, 198, 24, 19, 129, 80, 144, 201, 66, 17, 142, 195, 174, 13, 2, 21, 14, 196, 131, 20, 196, 131, 197, 163, 9, 69, 0, 14, 139, 4, 9, 19, 20, 9, 14, 7, 5, 197, 163, 9, 66, 14, 139, 4, 5, 19, 3, 8, 9, 26, 196, 131, 20, 21, 68, 0, 11, 136, 195, 174, 14, 6, 12, 15, 18, 9, 67, 0, 12, 137, 16, 196, 131, 4, 21, 18, 9, 3, 5, 67, 7, 196, 61, 5, 9, 52, 65, 0, 8, 197, 5, 97, 78, 81, 80, 67, 0, 19, 9, 22, 9, 19, 45, 1, 45, 22, 9, 19, 84, 37, 88, 35, 84, 6, 37, 0, 5, 194, 84, 224, 72, 0, 11, 136, 7, 196, 131, 21, 18, 9, 3, 5, 66, 0, 10, 135, 4, 5, 3, 15, 12, 196, 131, 67, 0, 9, 134, 15, 2, 197, 163, 9, 9, 66, 13, 138, 7, 195, 162, 7, 195, 162, 12, 9, 3, 5, 67, 0, 9, 198, 72, 86, 137, 77, 64, 64, 67, 9, 198, 25, 83, 7, 21, 32, 64, 67, 9, 198, 21, 132, 12, 61, 32, 64, 67, 9, 198, 21, 128, 71, 21, 32, 64, 68, 9, 198, 12, 243, 69, 57, 64, 64, 67, 0, 12, 136, 9, 1, 18, 196, 131, 197, 159, 9, 65, 8, 0, 0, 0, 10, 135, 7, 195, 162, 4, 9, 12, 1, 67, 10, 135, 13, 15, 12, 5, 197, 159, 9, 67, 0, 11, 136, 20, 18, 5, 3, 5, 197, 163, 9, 65, 11, 136, 13, 5, 18, 7, 5, 197, 163, 9, 65, 10, 199, 16, 80, 207, 56, 80, 212, 4, 68, 0, 12, 137, 1, 10, 21, 14, 7, 5, 197, 163, 9, 66, 12, 137, 195, 174, 14, 4, 18, 5, 16, 20, 1, 67, 0, 13, 138, 197, 159, 20, 5, 18, 7, 5, 197, 163, 9, 65, 13, 138, 16, 5, 20, 18, 5, 3, 5, 197, 163, 9, 66, 15, 140, 195, 174, 14, 4, 5, 16, 196, 131, 18, 20, 196, 131, 68, 13, 138, 4, 5, 19, 6, 1, 3, 5, 197, 163, 9, 66, 13, 138, 3, 15, 14, 4, 21, 3, 5, 197, 163, 9, 66, 9, 198, 24, 16, 201, 48, 149, 1, 68, 0, 14, 139, 19, 20, 18, 195, 162, 14, 7, 5, 197, 163, 9, 65, 14, 139, 195, 174, 14, 3, 9, 14, 7, 5, 197, 163, 9, 66, 9, 198, 25, 83, 7, 21, 33, 64, 65, 13, 4, 95, 35, 51, 50, 89, 48, 6, 35, 123, 116, 0, 0, 15, 140, 195, 174, 14, 20, 15, 1, 18, 3, 5, 197, 163, 9, 66, 0, 7, 196, 5, 86, 133, 4, 66, 12, 137, 1, 197, 159, 20, 5, 18, 14, 5, 1, 67, 0, 8, 197, 88, 144, 212, 61, 32, 65, 15, 69, 52, 20, 139, 21, 32, 65, 6, 35, 34, 49, 13, 34, 0, 9, 134, 2, 18, 15, 197, 159, 21, 66, 8, 197, 5, 50, 71, 85, 32, 66, 9, 198, 64, 245, 18, 37, 97, 65, 67, 9, 134, 7, 195, 162, 14, 4, 9, 66, 0, 9, 198, 77, 68, 149, 13, 69, 64, 66, 9, 198, 60, 20, 208, 21, 65, 64, 65, 9, 198, 9, 81, 142, 37, 69, 64, 67, 0, 11, 136, 20, 196, 131, 3, 5, 18, 5, 1, 66, 11, 136, 195, 174, 14, 7, 18, 15, 26, 9, 67, 0, 11, 200, 36, 228, 212, 73, 80, 212, 61, 32, 66, 10, 135, 4, 18, 1, 7, 15, 197, 159, 65, 7, 196, 13, 83, 20, 84, 66, 0, 8, 197, 4, 100, 137, 12, 16, 65, 8, 197, 65, 33, 68, 20, 16, 66, 0, 9, 198, 76, 195, 194, 61, 162, 64, 67, 9, 198, 16, 84, 197, 73, 98, 64, 67, 0, 11, 136, 195, 174, 14, 18, 15, 197, 159, 9, 67, 11, 136, 195, 174, 14, 18, 15, 197, 159, 9, 67, 0, 7, 196, 36, 66, 76, 20, 66, 8, 133, 2, 21, 197, 159, 9, 66, 9, 133, 4, 5, 197, 159, 9, 66, 8, 0, 8, 197, 48, 16, 210, 36, 208, 65, 15, 69, 77, 1, 82, 36, 16, 89, 48, 36, 16, 6, 57, 35, 0, 0, 6, 195, 28, 19, 5, 66, 6, 195, 76, 244, 201, 66, 9, 198, 64, 245, 18, 37, 98, 64, 67, 10, 198, 64, 245, 133, 77, 66, 64, 67, 9, 6, 195, 52, 83, 5, 77, 0, 19, 8, 195, 174, 14, 12, 15, 3, 21, 9, 112, 50, 55, 39, 49, 40, 6, 37, 0, 0, 12, 67, 9, 34, 79, 71, 14, 16, 6, 37, 39, 0, 12, 137, 16, 18, 196, 131, 2, 21, 197, 159, 9, 67, 0, 0, 14, 139, 195, 174, 14, 16, 21, 14, 19, 196, 131, 20, 21, 68, 6, 195, 12, 19, 5, 65, 6, 195, 76, 19, 5, 77, 0, 10, 199, 16, 148, 212, 36, 225, 197, 52, 66, 0, 0, 8, 197, 4, 113, 78, 81, 80, 67, 0, 10, 135, 6, 21, 18, 9, 197, 159, 1, 67, 0, 10, 135, 18, 195, 162, 14, 10, 5, 20, 65, 11, 136, 195, 174, 14, 3, 21, 18, 3, 1, 67, 10, 199, 12, 192, 83, 36, 98, 67, 4, 68, 0, 10, 135, 1, 12, 5, 18, 7, 196, 131, 66, 0, 0, 12, 137, 14, 5, 18, 5, 7, 21, 12, 196, 131, 66, 9, 198, 12, 243, 133, 13, 64, 64, 67, 9, 198, 53, 83, 20, 61, 32, 64, 77, 10, 135, 195, 174, 14, 19, 21, 13, 9, 77, 0, 0, 13, 68, 12, 244, 212, 4, 49, 39, 89, 47, 6, 35, 0, 0, 0, 6, 195, 64, 245, 5, 66, 9, 198, 60, 34, 69, 13, 64, 64, 67, 9, 198, 4, 49, 76, 61, 32, 64, 78, 0, 11, 136, 1, 197, 159, 20, 5, 16, 20, 1, 67, 0, 9, 198, 65, 35, 198, 21, 51, 210, 66, 13, 68, 13, 85, 9, 4, 49, 40, 47, 6, 37, 35, 0, 0, 9, 134, 16, 196, 131, 18, 5, 1, 66, 12, 201, 21, 132, 5, 72, 147, 69, 57, 64, 64, 69, 0, 9, 198, 104, 115, 205, 61, 65, 64, 65, 9, 198, 12, 244, 133, 13, 69, 64, 67, 10, 135, 1, 16, 196, 131, 18, 5, 1, 67, 0, 0, 12, 137, 26, 21, 7, 18, 196, 131, 22, 5, 1, 67, 12, 137, 4, 9, 19, 16, 196, 131, 18, 5, 1, 67, 0, 0, 9, 198, 77, 81, 140, 21, 65, 64, 65, 9, 198, 64, 240, 206, 37, 69, 64, 67, 9, 198, 64, 16, 207, 77, 65, 64, 65, 10, 135, 195, 174, 14, 3, 21, 9, 5, 66, 9, 198, 28, 20, 142, 37, 69, 64, 67, 18, 70, 61, 34, 67, 5, 33, 64, 39, 16, 124, 49, 4, 35, 16, 36, 0, 76, 0, 11, 136, 4, 5, 21, 14, 196, 131, 26, 9, 68, 11, 136, 3, 196, 131, 4, 5, 18, 5, 1, 66, 0, 7, 196, 84, 209, 90, 36, 65, 12, 137, 19, 3, 196, 131, 4, 5, 18, 5, 1, 66, 7, 196, 64, 17, 201, 56, 65, 8, 196, 64, 240, 84, 20, 76, 32, 0, 8, 197, 76, 80, 207, 48, 80, 65, 8, 197, 64, 84, 5, 56, 144, 65, 8, 197, 24, 20, 207, 48, 80, 66, 8, 197, 72, 84, 1, 72, 16, 67, 8, 197, 4, 67, 210, 52, 144, 67, 0, 10, 135, 16, 196, 131, 19, 20, 18, 1, 66, 6, 195, 12, 149, 9, 66, 0, 0, 7, 196, 48, 241, 201, 12, 65, 7, 196, 4, 69, 78, 4, 67, 0, 14, 69, 28, 243, 199, 48, 80, 81, 6, 40, 81, 13, 55, 0, 8, 197, 12, 130, 77, 36, 48, 65, 8, 197, 4, 225, 18, 20, 144, 66, 8, 197, 64, 194, 77, 8, 16, 66, 8, 197, 61, 33, 15, 56, 16, 67, 15, 69, 21, 99, 204, 84, 16, 36, 84, 39, 55, 58, 6, 35, 0, 0, 14, 139, 22, 9, 14, 15, 22, 196, 131, 197, 163, 9, 9, 68, 0, 11, 136, 18, 196, 131, 7, 21, 197, 159, 9, 67, 0, 11, 67, 61, 5, 83, 39, 48, 6, 40, 89, 0, 13, 68, 13, 85, 9, 20, 49, 40, 47, 6, 37, 36, 0, 8, 196, 65, 85, 5, 52, 76, 32, 12, 137, 1, 3, 5, 12, 5, 1, 197, 159, 9, 66, 0, 9, 198, 52, 16, 213, 48, 21, 21, 68, 8, 197, 25, 32, 67, 81, 80, 66, 0, 14, 139, 195, 174, 14, 20, 195, 162, 13, 16, 9, 14, 1, 68, 0, 0, 12, 68, 5, 84, 137, 84, 35, 40, 16, 6, 116, 0, 7, 196, 80, 144, 211, 36, 66, 0, 0, 0, 10, 199, 4, 212, 212, 21, 33, 1, 52, 65, 11, 136, 195, 174, 14, 3, 5, 18, 3, 1, 67, 0, 10, 135, 18, 5, 26, 5, 13, 196, 131, 67, 7, 196, 61, 33, 9, 56, 65, 0, 8, 197, 76, 20, 131, 36, 224, 65, 8, 197, 28, 84, 129, 72, 64, 65, 9, 197, 5, 53, 6, 20, 192, 65, 8, 0, 10, 135, 18, 196, 131, 7, 5, 20, 5, 65, 9, 198, 21, 132, 5, 16, 144, 64, 67, 9, 198, 17, 84, 133, 72, 80, 64, 66, 0, 6, 195, 52, 80, 64, 76, 0, 7, 196, 81, 81, 15, 72, 65, 7, 196, 60, 97, 82, 20, 66, 7, 196, 28, 192, 90, 84, 66, 7, 196, 4, 165, 84, 4, 67, 0, 0, 12, 137, 3, 15, 14, 20, 9, 14, 21, 196, 131, 66, 9, 198, 56, 147, 73, 12, 80, 64, 67, 0, 23, 11, 20, 18, 9, 39, 21, 14, 7, 8, 9, 21, 12, 47, 16, 37, 40, 50, 81, 57, 40, 55, 0, 0, 7, 196, 13, 85, 9, 36, 66, 0, 9, 198, 77, 64, 82, 61, 53, 5, 65, 0, 17, 70, 12, 192, 85, 16, 149, 64, 49, 55, 35, 6, 40, 72, 57, 40, 0, 9, 198, 8, 17, 10, 60, 53, 64, 67, 10, 135, 1, 13, 21, 197, 163, 5, 1, 67, 0, 6, 195, 84, 209, 68, 65, 11, 136, 18, 15, 13, 195, 174, 14, 9, 1, 67, 0, 0, 8, 197, 48, 81, 148, 21, 32, 65, 13, 138, 195, 174, 13, 2, 195, 162, 3, 19, 5, 1, 67, 0, 10, 135, 18, 196, 131, 13, 195, 162, 9, 66, 9, 198, 52, 84, 212, 20, 49, 64, 65, 0, 9, 67, 36, 82, 64, 6, 57, 118, 0, 0, 21, 9, 13, 21, 18, 4, 196, 131, 18, 9, 5, 65, 40, 34, 72, 13, 16, 6, 37, 36, 0, 13, 68, 48, 21, 90, 36, 55, 6, 35, 40, 88, 124, 0, 6, 195, 4, 210, 67, 66, 10, 135, 1, 3, 5, 12, 1, 197, 159, 66, 0, 8, 197, 80, 84, 129, 64, 144, 20, 8, 197, 64, 148, 201, 12, 144, 66, 9, 198, 16, 84, 198, 4, 49, 77, 66, 8, 197, 36, 228, 197, 72, 16, 67, 8, 197, 4, 225, 193, 40, 16, 67, 0, 14, 139, 13, 196, 131, 18, 20, 21, 18, 9, 19, 5, 1, 68, 0, 6, 195, 52, 82, 64, 76, 0, 0, 9, 198, 56, 84, 133, 29, 83, 9, 66, 8, 197, 8, 83, 7, 36, 16, 65, 8, 197, 4, 38, 137, 12, 80, 66, 8, 197, 16, 80, 149, 80, 16, 67, 14, 69, 61, 34, 67, 84, 144, 39, 16, 124, 49, 121, 0, 79, 0, 6, 195, 80, 244, 9, 66, 10, 135, 195, 174, 14, 19, 5, 18, 1, 67, 0, 10, 199, 4, 197, 3, 36, 225, 86, 4, 68, 10, 199, 72, 85, 133, 72, 33, 82, 4, 68, 6, 195, 12, 19, 64, 72, 0, 0, 0, 9, 198, 52, 20, 137, 80, 147, 64, 66, 0, 0, 0, 9, 198, 104, 68, 133, 48, 149, 21, 67, 0, 9, 198, 16, 147, 131, 60, 195, 192, 65, 0, 10, 199, 65, 85, 5, 72, 226, 67, 36, 66, 10, 67, 32, 242, 84, 107, 6, 120, 47, 0, 10, 199, 12, 21, 1, 16, 144, 211, 36, 68, 0, 7, 196, 64, 17, 213, 8, 65, 0, 24, 10, 5, 24, 5, 18, 3, 9, 197, 163, 9, 21, 36, 81, 88, 36, 34, 76, 6, 37, 123, 57, 40, 0, 0, 10, 135, 18, 195, 162, 19, 5, 20, 5, 65, 17, 70, 12, 192, 85, 16, 144, 64, 49, 55, 35, 6, 40, 72, 57, 35, 0, 6, 195, 77, 4, 133, 28, 0, 0, 14, 68, 21, 132, 21, 76, 36, 49, 89, 48, 6, 40, 89, 0, 0, 8, 197, 28, 19, 2, 20, 224, 65, 0, 9, 198, 77, 81, 133, 72, 80, 64, 67, 17, 7, 18, 196, 131, 19, 6, 15, 9, 34, 13, 89, 83, 39, 6, 37, 0, 0, 10, 199, 77, 80, 143, 72, 66, 78, 20, 66, 7, 195, 76, 21, 64, 72, 8, 0, 0, 15, 6, 197, 159, 5, 6, 9, 1, 91, 36, 83, 6, 37, 35, 0, 0, 9, 198, 24, 16, 212, 36, 49, 64, 66, 0, 6, 195, 52, 85, 64, 76, 0, 7, 196, 53, 84, 133, 4, 66, 12, 137, 195, 174, 14, 20, 5, 197, 163, 5, 1, 67, 12, 137, 4, 5, 16, 196, 131, 197, 159, 5, 1, 67, 0, 22, 10, 3, 5, 1, 21, 197, 159, 5, 19, 3, 21, 76, 135, 40, 91, 6, 36, 89, 49, 40, 0, 8, 197, 4, 49, 76, 61, 32, 74, 0, 10, 135, 20, 196, 131, 3, 5, 18, 9, 66, 9, 198, 65, 33, 76, 36, 225, 192, 66, 10, 135, 20, 18, 196, 131, 7, 5, 1, 66, 10, 135, 16, 12, 196, 131, 3, 5, 1, 66, 0, 11, 136, 16, 12, 196, 131, 3, 5, 18, 9, 66, 11, 136, 195, 174, 14, 4, 5, 19, 5, 1, 67, 0, 12, 68, 104, 243, 66, 36, 88, 39, 65, 71, 37, 0, 7, 196, 76, 145, 213, 72, 65, 0, 8, 197, 52, 241, 5, 48, 16, 67, 0, 10, 135, 20, 196, 131, 3, 5, 18, 5, 66, 10, 135, 195, 174, 14, 3, 5, 16, 21, 67, 0, 11, 136, 16, 12, 196, 131, 3, 5, 18, 5, 66, 10, 199, 4, 53, 80, 84, 224, 212, 84, 68, 10, 199, 16, 85, 5, 72, 210, 78, 4, 68, 10, 199, 13, 85, 18, 20, 213, 82, 4, 68, 0, 7, 196, 36, 148, 213, 76, 66, 8, 133, 22, 195, 162, 14, 1, 66, 7, 196, 60, 97, 82, 36, 67, 0, 9, 134, 2, 196, 131, 21, 20, 21, 67, 13, 138, 195, 174, 14, 3, 196, 131, 9, 5, 18, 1, 68, 8, 197, 21, 53, 9, 52, 16, 67, 8, 197, 16, 148, 212, 72, 16, 66, 13, 138, 26, 196, 131, 4, 196, 131, 18, 14, 9, 9, 68, 0, 0, 10, 199, 81, 32, 78, 76, 97, 82, 4, 68, 10, 199, 36, 229, 5, 72, 97, 82, 4, 68, 0, 11, 136, 197, 159, 14, 9, 197, 163, 5, 12, 65, 7, 196, 72, 81, 213, 48, 65, 7, 196, 52, 144, 213, 48, 65, 0, 6, 20, 0, 0, 0, 25, 2, 0, 0, 95, 1, 0, 0, 27, 2, 0, 0, 99, 1, 0, 0, 24, 2, 0, 0, 95, 1, 0, 0, 26, 2, 0, 0, 99, 1, 0, 0, 0, 0, 0, 0, 6, 195, 162, 0, 105, 101, 1, 21, 2, 32, 3, 8, 133, 36, 0, 3, 112, 0, 105, 3, 133, 0, 117, 3, 134, 0, 7, 6, 195, 174, 0, 1, 21, 2, 32, 3, 6, 112, 0, 3, 112, 0, 7, 6, 196, 131, 0, 117, 2, 32, 3, 6, 130, 0, 1, 21, 2, 17, 67, 196, 131, 32, 3, 8, 13, 0, 105, 101, 1, 21, 2, 32, 3, 8, 129, 36, 0, 4, 3, 13, 0, 1, 10, 2, 32, 14, 128, 192, 129, 0, 1, 17, 67, 131, 196, 21, 2, 32, 0, 1, 99, 101, 10, 2, 32, 0, 1, 114, 101, 21, 2, 32, 0, 1, 163, 197, 105, 21, 2, 32, 0, 4, 114, 105, 2, 17, 65, 17, 65, 32, 3, 13, 16, 6, 37, 0, 114, 105, 2, 17, 65, 32, 0, 114, 105, 105, 2, 32, 3, 13, 16, 6, 132, 0, 4, 117, 1, 99, 2, 116, 3, 13, 40, 0, 117, 8, 98, 2, 116, 0, 117, 8, 100, 2, 110, 0, 117, 8, 108, 2, 100, 0, 116, 196, 131, 1, 21, 2, 32, 14, 129, 128, 131, 3, 13, 47, 13, 0, 116, 101, 1, 21, 2, 32, 14, 129, 128, 131, 3, 13, 47, 36, 0, 116, 101, 108, 101, 1, 21, 2, 32, 14, 129, 128, 133, 3, 13, 47, 36, 55, 36, 0, 116, 101, 108, 111, 114, 1, 21, 2, 32, 14, 129, 128, 134, 3, 13, 47, 36, 55, 39, 34, 0, 116, 117, 108, 1, 21, 2, 32, 14, 129, 128, 132, 3, 13, 47, 40, 55, 0, 116, 117, 108, 117, 105, 1, 21, 2, 32, 14, 129, 128, 134, 3, 13, 47, 40, 55, 121, 0, 105, 2, 32, 3, 129, 0, 117, 3, 130, 0, 7, 6, 197, 159, 0, 3, 91, 0, 110, 105, 1, 21, 2, 32, 3, 91, 50, 6, 37, 0, 105, 1, 45, 2, 32, 3, 91, 124, 0, 1, 21, 2, 105, 32, 3, 97, 0, 7, 6, 197, 163, 0, 3, 123, 0, 1, 21, 2, 105, 32, 3, 141, 0, 105, 1, 45, 2, 32, 3, 141, 128, 0, 7, 6, 97, 0, 4, 1, 21, 26, 2, 24, 32, 3, 6, 35, 0, 1, 105, 131, 196, 2, 32, 0, 1, 110, 111, 105, 21, 2, 32, 0, 117, 8, 108, 2, 100, 3, 6, 35, 40, 0, 108, 101, 1, 21, 2, 32, 3, 6, 35, 55, 36, 0, 98, 105, 108, 1, 21, 2, 32, 3, 6, 35, 71, 37, 55, 0, 117, 2, 32, 3, 6, 114, 0, 105, 2, 32, 3, 6, 117, 0, 4, 3, 35, 0, 1, 10, 2, 32, 14, 128, 192, 129, 0, 1, 105, 103, 2, 32, 14, 128, 192, 129, 0, 2, 17, 65, 17, 65, 17, 65, 0, 105, 1, 110, 2, 118, 3, 35, 37, 0, 4, 117, 1, 99, 2, 116, 3, 35, 40, 0, 117, 2, 100, 0, 117, 2, 114, 0, 117, 2, 115, 116, 0, 117, 2, 122, 0, 110, 116, 105, 8, 2, 21, 14, 128, 132, 132, 3, 35, 50, 47, 37, 0, 105, 2, 97, 3, 35, 57, 0, 117, 3, 114, 0, 105, 3, 117, 0, 7, 6, 98, 0, 4, 1, 21, 2, 105, 108, 32, 3, 8, 71, 0, 1, 21, 2, 105, 108, 97, 32, 0, 1, 21, 2, 105, 108, 105, 32, 0, 1, 21, 2, 105, 108, 105, 105, 32, 0, 1, 21, 2, 105, 108, 105, 108, 101, 32, 0, 1, 21, 2, 105, 108, 105, 108, 111, 114, 32, 0, 1, 21, 2, 105, 108, 117, 108, 117, 105, 32, 0, 4, 3, 71, 0, 98, 0, 105, 108, 1, 111, 109, 2, 32, 3, 71, 6, 37, 55, 0, 1, 21, 2, 105, 32, 3, 143, 0, 7, 6, 99, 0, 111, 108, 1, 21, 21, 2, 32, 3, 8, 49, 39, 55, 0, 111, 108, 105, 1, 21, 21, 2, 32, 14, 129, 128, 129, 3, 8, 124, 0, 111, 108, 101, 1, 21, 21, 2, 32, 14, 129, 128, 129, 3, 36, 0, 4, 3, 49, 0, 104, 0, 110, 105, 1, 21, 2, 32, 3, 49, 50, 6, 37, 0, 110, 101, 97, 1, 21, 2, 32, 3, 49, 50, 36, 6, 35, 0, 4, 2, 101, 3, 76, 0, 2, 105, 0, 105, 2, 111, 0, 105, 105, 3, 76, 132, 0, 7, 6, 100, 0, 4, 3, 72, 0, 100, 0, 1, 21, 2, 105, 32, 3, 144, 0, 7, 6, 101, 0, 1, 17, 67, 10, 2, 114, 101, 32, 3, 2, 36, 0, 117, 1, 21, 2, 108, 32, 3, 6, 36, 40, 0, 117, 1, 21, 2, 32, 24, 3, 6, 115, 0, 105, 1, 114, 2, 101, 114, 32, 3, 6, 118, 0, 4, 1, 21, 2, 114, 97, 32, 3, 8, 36, 0, 1, 21, 2, 114, 101, 32, 0, 1, 21, 2, 114, 101, 97, 32, 0, 1, 21, 2, 114, 101, 105, 32, 0, 1, 21, 2, 114, 105, 32, 0, 1, 21, 2, 114, 105, 105, 32, 0, 1, 21, 2, 114, 196, 131, 32, 0, 197, 159, 1, 21, 2, 32, 3, 8, 36, 91, 0, 197, 159, 105, 108, 111, 114, 1, 21, 2, 32, 3, 8, 36, 91, 37, 55, 39, 34, 0, 197, 159, 117, 108, 1, 21, 2, 32, 3, 8, 36, 91, 40, 55, 0, 197, 159, 117, 108, 117, 105, 1, 21, 2, 32, 3, 8, 36, 91, 40, 55, 121, 0, 197, 159, 105, 1, 21, 2, 32, 3, 8, 36, 91, 124, 0, 4, 3, 36, 0, 1, 102, 21, 2, 114, 97, 32, 0, 1, 102, 21, 2, 114, 97, 32, 0, 1, 105, 2, 114, 97, 32, 0, 1, 105, 2, 114, 101, 32, 0, 1, 105, 2, 114, 101, 97, 32, 0, 1, 105, 2, 114, 105, 32, 0, 1, 105, 2, 114, 105, 105, 32, 0, 1, 105, 2, 114, 196, 131, 32, 0, 2, 17, 65, 17, 65, 17, 65, 0, 111, 1, 100, 2, 115, 101, 98, 3, 36, 39, 0, 117, 1, 21, 2, 32, 3, 36, 40, 0, 99, 1, 116, 17, 65, 21, 2, 105, 105, 32, 3, 36, 76, 0, 4, 101, 8, 99, 97, 2, 97, 3, 118, 0, 105, 2, 32, 0, 105, 8, 0, 4, 97, 3, 135, 0, 97, 1, 10, 2, 32, 14, 128, 192, 130, 0, 83, 105, 1, 10, 3, 135, 57, 0, 97, 117, 3, 135, 58, 0, 111, 3, 136, 0, 111, 97, 3, 136, 6, 35, 0, 7, 6, 102, 0, 4, 3, 83, 0, 102, 0, 1, 21, 2, 105, 32, 3, 142, 0, 7, 6, 103, 0, 4, 2, 101, 3, 75, 0, 2, 105, 0, 105, 105, 1, 10, 2, 32, 3, 75, 6, 132, 0, 105, 1, 10, 2, 17, 65, 32, 3, 75, 37, 0, 105, 105, 3, 75, 132, 0, 4, 3, 81, 0, 104, 0, 7, 6, 104, 0, 1, 21, 2, 105, 32, 3, 99, 0, 3, 107, 0, 7, 6, 105, 0, 1, 99, 2, 117, 17, 67, 3, 0, 110, 103, 1, 10, 2, 32, 3, 2, 37, 68, 81, 0, 4, 101, 105, 1, 108, 105, 102, 2, 32, 3, 6, 36, 37, 0, 101, 105, 1, 109, 111, 110, 2, 32, 0, 4, 1, 10, 26, 2, 24, 32, 3, 6, 37, 0, 1, 114, 99, 115, 2, 101, 0, 2, 116, 32, 0, 4, 97, 1, 17, 67, 131, 196, 2, 32, 3, 6, 37, 35, 0, 97, 1, 17, 67, 162, 195, 2, 32, 0, 97, 1, 102, 97, 114, 103, 2, 32, 0, 97, 1, 108, 105, 102, 2, 32, 0, 97, 1, 109, 111, 110, 2, 32, 0, 97, 1, 110, 111, 2, 32, 0, 97, 1, 112, 111, 99, 115, 2, 32, 0, 97, 1, 114, 101, 2, 32, 0, 97, 1, 159, 197, 117, 2, 32, 0, 4, 101, 1, 17, 67, 131, 196, 2, 32, 3, 6, 37, 36, 0, 101, 1, 17, 67, 162, 195, 2, 32, 0, 101, 1, 102, 97, 114, 103, 2, 32, 0, 101, 1, 108, 105, 102, 2, 32, 0, 101, 1, 109, 111, 110, 2, 32, 0, 101, 1, 110, 111, 2, 32, 0, 101, 1, 112, 111, 99, 115, 2, 32, 0, 101, 1, 159, 197, 117, 2, 32, 0, 4, 101, 105, 1, 102, 97, 114, 103, 2, 32, 3, 6, 37, 118, 0, 101, 105, 1, 110, 111, 2, 32, 0, 101, 105, 1, 114, 101, 2, 32, 0, 101, 105, 1, 159, 197, 117, 2, 32, 0, 101, 105, 2, 32, 0, 4, 105, 1, 102, 97, 114, 103, 2, 32, 3, 6, 132, 0, 105, 1, 112, 111, 99, 115, 2, 32, 0, 4, 1, 21, 2, 197, 163, 101, 32, 3, 8, 37, 0, 1, 21, 2, 197, 163, 101, 105, 32, 0, 1, 21, 2, 197, 163, 101, 108, 101, 32, 0, 1, 21, 2, 197, 163, 101, 108, 111, 114, 32, 0, 1, 21, 2, 197, 163, 196, 131, 32, 12, 12, 12, 12, 12, 12, 12, 12, 0, 1, 103, 2, 110, 101, 32, 0, 1, 103, 2, 110, 101, 97, 32, 0, 101, 1, 163, 197, 99, 2, 32, 3, 8, 37, 36, 0, 99, 1, 10, 2, 32, 3, 8, 37, 49, 0, 99, 97, 1, 10, 2, 32, 3, 8, 37, 49, 35, 0, 99, 101, 1, 10, 2, 32, 3, 8, 37, 76, 36, 0, 99, 105, 108, 101, 1, 10, 2, 32, 3, 8, 37, 76, 37, 55, 36, 0, 99, 105, 108, 111, 114, 1, 10, 2, 32, 3, 8, 37, 76, 37, 55, 39, 34, 0, 99, 101, 105, 1, 21, 2, 32, 3, 8, 37, 76, 118, 0, 99, 105, 105, 1, 21, 2, 32, 3, 8, 37, 76, 132, 0, 197, 159, 116, 101, 1, 21, 2, 32, 3, 8, 37, 91, 47, 36, 0, 197, 159, 116, 101, 97, 1, 21, 2, 32, 3, 8, 37, 91, 47, 135, 0, 101, 105, 1, 163, 197, 99, 2, 32, 3, 8, 37, 118, 0, 97, 1, 163, 197, 99, 2, 32, 3, 8, 57, 35, 0, 1, 45, 105, 163, 197, 2, 32, 3, 10, 0, 4, 3, 37, 0, 1, 10, 2, 32, 24, 14, 128, 192, 129, 0, 1, 10, 2, 45, 24, 14, 128, 192, 129, 0, 1, 39, 10, 2, 32, 0, 1, 114, 17, 67, 2, 32, 12, 12, 12, 0, 1, 163, 197, 2, 45, 17, 67, 105, 0, 1, 163, 197, 2, 45, 17, 67, 196, 131, 0, 1, 163, 197, 2, 45, 108, 0, 1, 163, 197, 2, 45, 110, 101, 0, 105, 105, 3, 37, 57, 37, 0, 101, 105, 1, 112, 111, 99, 115, 2, 32, 3, 37, 118, 0, 4, 1, 21, 2, 101, 32, 3, 57, 0, 1, 45, 2, 32, 0, 2, 17, 65, 0, 117, 3, 57, 40, 0, 111, 97, 3, 57, 110, 6, 35, 0, 117, 2, 32, 3, 116, 0, 1, 17, 67, 10, 2, 32, 24, 14, 128, 192, 129, 3, 128, 0, 4, 105, 3, 132, 0, 105, 1, 10, 2, 32, 14, 128, 192, 130, 0, 7, 6, 106, 0, 3, 90, 0, 1, 21, 2, 105, 32, 3, 96, 0, 7, 6, 107, 0, 3, 49, 0, 7, 6, 108, 0, 4, 3, 55, 0, 1, 45, 2, 32, 0, 1, 117, 105, 2, 32, 14, 129, 128, 129, 0, 108, 0, 4, 8, 2, 32, 3, 55, 36, 0, 101, 1, 10, 2, 32, 14, 129, 128, 130, 0, 111, 114, 1, 10, 2, 32, 14, 129, 128, 131, 3, 55, 39, 34, 0, 117, 105, 1, 10, 2, 32, 14, 129, 128, 131, 3, 55, 121, 0, 1, 21, 2, 105, 32, 3, 125, 0, 7, 6, 109, 0, 4, 3, 65, 0, 8, 2, 45, 97, 0, 109, 0, 8, 2, 32, 3, 65, 36, 0, 105, 1, 45, 2, 32, 3, 65, 128, 0, 1, 21, 2, 105, 32, 3, 126, 0, 7, 6, 110, 0, 4, 1, 21, 2, 105, 99, 32, 3, 8, 50, 0, 1, 21, 2, 116, 105, 99, 32, 0, 4, 3, 50, 0, 1, 45, 2, 32, 0, 8, 2, 45, 97, 0, 4, 8, 2, 32, 3, 50, 36, 0, 101, 1, 105, 100, 117, 116, 105, 21, 2, 32, 14, 129, 128, 130, 0, 105, 1, 105, 100, 117, 116, 105, 21, 2, 32, 14, 129, 128, 130, 3, 50, 37, 0, 105, 108, 101, 1, 105, 100, 117, 116, 105, 21, 2, 32, 14, 129, 128, 132, 3, 50, 37, 55, 36, 0, 105, 108, 111, 114, 1, 105, 100, 117, 116, 105, 21, 2, 32, 14, 129, 128, 133, 3, 50, 37, 55, 39, 34, 0, 105, 105, 1, 105, 100, 117, 116, 105, 21, 2, 32, 14, 129, 128, 131, 3, 50, 132, 0, 101, 97, 1, 105, 100, 117, 116, 105, 21, 2, 32, 14, 129, 128, 131, 3, 50, 135, 0, 4, 2, 103, 3, 68, 0, 2, 107, 0, 1, 21, 2, 105, 32, 3, 127, 0, 7, 6, 111, 0, 1, 17, 67, 21, 2, 114, 105, 105, 105, 32, 3, 6, 39, 0, 105, 2, 32, 3, 6, 39, 57, 0, 117, 2, 32, 24, 3, 6, 131, 0, 4, 3, 39, 0, 2, 17, 65, 17, 65, 17, 65, 0, 117, 2, 32, 3, 39, 40, 0, 105, 8, 3, 39, 57, 0, 117, 3, 131, 0, 97, 3, 138, 0, 97, 105, 3, 138, 57, 0, 7, 6, 112, 0, 4, 3, 48, 0, 112, 0, 104, 3, 83, 0, 1, 21, 2, 105, 32, 3, 139, 0, 7, 6, 113, 0, 3, 49, 0, 117, 3, 49, 58, 0, 7, 6, 114, 0, 1, 17, 67, 2, 17, 65, 3, 14, 16, 0, 105, 1, 17, 67, 2, 32, 3, 14, 16, 37, 0, 4, 1, 17, 65, 2, 17, 65, 3, 16, 0, 2, 196, 131, 32, 0, 196, 131, 197, 163, 105, 1, 21, 2, 32, 14, 129, 128, 132, 3, 16, 13, 123, 124, 0, 114, 3, 16, 34, 0, 101, 1, 117, 21, 2, 32, 14, 129, 128, 130, 3, 16, 36, 0, 4, 3, 34, 0, 114, 0, 4, 101, 8, 2, 21, 14, 128, 132, 130, 3, 34, 36, 0, 101, 8, 2, 103, 117, 108, 0, 105, 108, 101, 1, 117, 21, 2, 32, 14, 129, 128, 132, 3, 34, 37, 55, 36, 0, 105, 108, 111, 114, 1, 117, 21, 2, 32, 14, 129, 128, 133, 3, 34, 37, 55, 39, 34, 0, 105, 1, 117, 21, 2, 32, 24, 14, 129, 128, 130, 3, 34, 124, 0, 105, 105, 1, 117, 21, 2, 32, 14, 129, 128, 131, 3, 34, 132, 0, 196, 131, 109, 1, 21, 2, 32, 14, 129, 128, 129, 3, 65, 0, 1, 17, 65, 2, 105, 32, 3, 145, 0, 7, 6, 115, 0, 101, 114, 196, 131, 1, 21, 2, 32, 14, 129, 128, 130, 3, 16, 13, 0, 101, 114, 196, 131, 109, 1, 21, 2, 32, 14, 129, 128, 131, 3, 16, 13, 65, 0, 101, 114, 196, 131, 197, 163, 105, 1, 21, 2, 32, 14, 129, 128, 132, 3, 16, 13, 123, 124, 0, 101, 109, 1, 21, 2, 32, 14, 129, 128, 129, 3, 65, 0, 4, 3, 89, 0, 1, 45, 2, 32, 0, 8, 2, 45, 97, 0, 115, 0, 8, 2, 32, 3, 89, 36, 0, 112, 114, 101, 122, 101, 99, 101, 1, 10, 2, 32, 14, 129, 128, 136, 3, 89, 48, 14, 16, 36, 88, 4, 36, 76, 36, 0, 110, 105, 1, 21, 2, 32, 3, 89, 50, 6, 37, 0, 104, 3, 91, 0, 101, 197, 159, 105, 1, 21, 2, 32, 14, 129, 128, 130, 3, 91, 124, 0, 7, 6, 116, 0, 4, 3, 47, 0, 116, 0, 116, 2, 32, 0, 4, 115, 3, 123, 0, 122, 0, 1, 21, 2, 105, 32, 3, 140, 0, 7, 6, 117, 0, 1, 17, 67, 131, 196, 21, 2, 24, 32, 3, 6, 40, 0, 105, 2, 32, 3, 6, 121, 0, 105, 101, 1, 21, 2, 32, 3, 8, 58, 37, 36, 0, 3, 40, 0, 105, 1, 10, 26, 2, 32, 24, 3, 40, 6, 37, 0, 114, 105, 108, 101, 1, 99, 105, 21, 2, 32, 14, 128, 128, 133, 3, 40, 34, 37, 55, 36, 0, 114, 105, 1, 99, 105, 21, 2, 32, 14, 128, 128, 131, 3, 40, 34, 124, 0, 105, 1, 114, 2, 110, 3, 40, 37, 0, 4, 108, 1, 10, 2, 32, 14, 129, 128, 130, 3, 40, 55, 0, 108, 1, 99, 105, 21, 2, 32, 14, 129, 128, 130, 0, 108, 1, 116, 115, 101, 100, 0, 108, 101, 1, 99, 105, 21, 2, 32, 14, 129, 128, 131, 3, 40, 55, 36, 0, 4, 108, 117, 105, 1, 10, 2, 32, 14, 129, 128, 132, 3, 40, 55, 121, 0, 108, 117, 105, 1, 99, 105, 21, 2, 32, 14, 129, 128, 132, 0, 105, 97, 2, 32, 3, 40, 57, 6, 35, 0, 4, 109, 1, 21, 2, 32, 14, 128, 192, 130, 3, 40, 65, 0, 109, 1, 99, 2, 32, 0, 109, 117, 114, 105, 1, 21, 2, 32, 14, 129, 128, 133, 3, 40, 65, 40, 34, 37, 0, 109, 117, 114, 105, 108, 101, 1, 21, 2, 32, 14, 129, 128, 135, 3, 40, 65, 40, 34, 37, 55, 36, 0, 109, 117, 114, 105, 108, 111, 114, 1, 21, 2, 32, 14, 129, 128, 136, 3, 40, 65, 40, 34, 37, 55, 39, 34, 0, 109, 117, 108, 1, 21, 2, 32, 14, 129, 128, 132, 3, 40, 65, 40, 55, 0, 109, 117, 108, 117, 105, 1, 21, 2, 32, 14, 129, 128, 134, 3, 40, 65, 40, 55, 121, 0, 115, 1, 21, 2, 32, 14, 129, 128, 130, 3, 40, 89, 0, 115, 117, 114, 105, 1, 21, 2, 32, 14, 129, 128, 133, 3, 40, 89, 40, 34, 37, 0, 115, 117, 114, 105, 108, 101, 1, 21, 2, 32, 14, 129, 128, 135, 3, 40, 89, 40, 34, 37, 55, 36, 0, 115, 117, 114, 105, 108, 111, 114, 1, 21, 2, 32, 14, 129, 128, 136, 3, 40, 89, 40, 34, 37, 55, 39, 34, 0, 115, 117, 108, 1, 21, 2, 32, 14, 129, 128, 132, 3, 40, 89, 40, 55, 0, 115, 117, 108, 117, 105, 1, 21, 2, 32, 14, 129, 128, 134, 3, 40, 89, 40, 55, 121, 0, 2, 17, 65, 3, 58, 0, 105, 2, 101, 3, 58, 37, 0, 105, 8, 3, 121, 0, 7, 6, 118, 0, 3, 84, 0, 1, 21, 2, 105, 32, 3, 146, 0, 7, 6, 119, 0, 3, 58, 0, 7, 6, 120, 0, 4, 3, 49, 89, 0, 1, 101, 2, 17, 65, 103, 0, 1, 101, 2, 105, 17, 65, 32, 0, 1, 101, 2, 105, 117, 0, 1, 101, 108, 2, 12, 0, 1, 101, 109, 2, 105, 99, 0, 2, 101, 32, 0, 8, 101, 108, 97, 0, 4, 1, 101, 2, 97, 3, 81, 88, 0, 1, 101, 2, 101, 0, 1, 101, 2, 105, 0, 7, 6, 121, 0, 3, 37, 0, 2, 17, 65, 3, 57, 0, 7, 6, 122, 0, 4, 3, 88, 0, 122, 0, 1, 21, 2, 105, 32, 3, 94, 0, 7, 6, 0, 4, 45, 1, 32, 17, 65, 2, 32, 15, 3, 10, 0, 45, 1, 32, 17, 67, 2, 32, 15, 0, 37, 3, 48, 14, 16, 39, 76, 36, 50, 47, 0, 37, 1, 32, 15, 3, 55, 35, 10, 89, 40, 47, 13, 0, 45, 8, 32, 2, 32, 15, 3, 65, 6, 37, 50, 40, 89, 0, 36, 3, 72, 39, 55, 35, 34, 0, 44, 2, 15, 3, 84, 6, 37, 34, 81, 40, 55, 13, 0, 195, 182, 3, 113, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts53 = FileInMemory_createWithData (26885, reinterpret_cast (&espeakdata_dicts53_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/ro_dict", U"ro"); Collection_addItem (me.peek(), espeakdata_dicts53.transfer()); static unsigned char espeakdata_dicts54_data[6158] = { 0, 4, 0, 0, 140, 10, 0, 0, 0, 0, 0, 0, 0, 4, 193, 4, 14, 5, 193, 4, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 7, 65, 12, 84, 121, 0, 14, 6, 65, 12, 84, 0, 72, 0, 0, 0, 0, 0, 0, 0, 11, 4, 95, 100, 112, 116, 9, 6, 37, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 1, 35, 34, 36, 91, 6, 121, 47, 49, 35, 0, 27, 0, 8, 197, 64, 240, 156, 77, 208, 74, 7, 65, 36, 37, 0, 72, 8, 11, 1, 36, 72, 6, 39, 55, 55, 35, 34, 0, 0, 13, 1, 37, 48, 34, 126, 110, 6, 121, 50, 47, 0, 27, 0, 14, 1, 38, 35, 65, 48, 36, 34, 89, 6, 35, 50, 72, 0, 0, 0, 0, 0, 12, 1, 42, 88, 84, 36, 88, 72, 6, 35, 0, 27, 0, 10, 1, 43, 48, 55, 6, 131, 89, 0, 27, 0, 0, 0, 0, 10, 1, 47, 89, 55, 6, 121, 91, 0, 27, 0, 6, 195, 25, 36, 198, 73, 0, 0, 0, 0, 0, 0, 0, 6, 195, 25, 36, 221, 73, 0, 0, 0, 0, 0, 0, 9, 198, 64, 240, 148, 21, 68, 192, 74, 11, 1, 61, 34, 35, 84, 50, 6, 39, 0, 27, 0, 0, 0, 11, 1, 64, 89, 39, 71, 6, 35, 49, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 65, 72, 121, 89, 0, 14, 6, 65, 72, 89, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 80, 40, 0, 72, 0, 0, 0, 6, 195, 9, 195, 9, 73, 0, 0, 0, 0, 0, 0, 6, 195, 9, 195, 15, 73, 0, 0, 0, 8, 197, 72, 211, 199, 25, 48, 73, 13, 1, 92, 71, 121, 49, 89, 55, 6, 121, 91, 0, 27, 0, 0, 11, 1, 94, 49, 34, 6, 115, 91, 49, 35, 0, 0, 13, 1, 95, 48, 39, 72, 78, 6, 128, 34, 49, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 1, 126, 47, 6, 37, 55, 72, 35, 0, 0, 0, 4, 193, 128, 72, 0, 0, 0, 7, 196, 9, 65, 70, 52, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 193, 144, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 9, 65, 84, 73, 0, 7, 196, 9, 65, 70, 76, 73, 0, 0, 0, 0, 0, 4, 193, 160, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 52, 246, 29, 72, 0, 0, 0, 0, 0, 0, 6, 195, 52, 241, 35, 74, 0, 0, 0, 0, 0, 17, 5, 95, 100, 112, 116, 50, 10, 112, 117, 95, 6, 35, 47, 135, 101, 0, 0, 0, 0, 0, 6, 195, 52, 241, 20, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 72, 211, 199, 24, 208, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 9, 195, 0, 73, 0, 7, 196, 9, 65, 84, 76, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 198, 64, 240, 148, 20, 99, 64, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 97, 51, 194, 112, 8, 0, 8, 197, 9, 65, 70, 76, 96, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 72, 211, 196, 48, 144, 74, 12, 3, 226, 132, 150, 50, 6, 39, 65, 36, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 9, 196, 221, 73, 0, 0, 0, 9, 198, 64, 240, 148, 20, 102, 93, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 73, 68, 221, 73, 0, 0, 0, 0, 0, 6, 195, 72, 211, 196, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 20, 200, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 51, 88, 47, 34, 38, 6, 37, 47, 110, 126, 111, 0, 0, 10, 3, 95, 48, 67, 89, 47, 6, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 3, 95, 49, 57, 112, 123, 84, 38, 117, 47, 50, 6, 134, 47, 110, 126, 111, 0, 0, 18, 3, 95, 49, 56, 84, 127, 95, 117, 65, 50, 6, 134, 47, 110, 126, 111, 0, 0, 14, 3, 95, 50, 67, 72, 84, 38, 6, 36, 95, 111, 117, 0, 0, 8, 197, 72, 211, 196, 48, 240, 74, 0, 0, 0, 0, 0, 17, 3, 95, 49, 49, 127, 112, 6, 37, 50, 50, 126, 47, 110, 126, 111, 0, 0, 12, 3, 95, 49, 48, 112, 6, 36, 95, 117, 111, 0, 0, 14, 3, 95, 51, 67, 47, 34, 38, 6, 37, 89, 47, 35, 0, 17, 3, 95, 49, 51, 47, 51, 38, 117, 50, 6, 134, 47, 110, 126, 111, 0, 0, 17, 3, 95, 49, 50, 72, 84, 38, 117, 50, 6, 134, 47, 110, 126, 111, 0, 0, 17, 3, 95, 49, 53, 48, 38, 117, 47, 50, 6, 134, 47, 110, 126, 111, 0, 0, 20, 3, 95, 49, 52, 110, 38, 117, 47, 6, 115, 14, 16, 50, 126, 47, 110, 126, 111, 0, 0, 16, 3, 95, 49, 55, 95, 117, 65, 50, 6, 134, 47, 110, 126, 111, 0, 0, 17, 3, 95, 49, 54, 91, 122, 89, 47, 50, 6, 134, 47, 110, 126, 111, 0, 0, 0, 15, 3, 95, 55, 88, 95, 6, 36, 65, 112, 123, 95, 126, 47, 0, 0, 7, 196, 52, 241, 12, 36, 74, 18, 3, 95, 52, 67, 110, 38, 117, 47, 6, 115, 34, 38, 123, 89, 47, 35, 0, 0, 0, 9, 198, 64, 240, 148, 20, 100, 192, 74, 0, 0, 0, 0, 0, 0, 9, 198, 64, 240, 148, 20, 100, 198, 74, 15, 3, 95, 53, 67, 48, 38, 4, 117, 111, 89, 6, 39, 47, 0, 0, 0, 0, 0, 0, 11, 3, 95, 49, 102, 39, 72, 50, 6, 35, 0, 0, 0, 0, 15, 3, 95, 54, 67, 91, 4, 122, 95, 111, 89, 6, 39, 47, 0, 0, 0, 0, 0, 0, 11, 3, 95, 50, 102, 72, 84, 38, 6, 36, 0, 0, 0, 14, 3, 95, 50, 88, 72, 84, 6, 134, 47, 110, 126, 111, 0, 0, 7, 196, 52, 241, 12, 60, 74, 16, 5, 95, 48, 77, 65, 49, 47, 6, 115, 95, 117, 110, 38, 37, 0, 14, 3, 95, 55, 67, 95, 4, 117, 65, 89, 6, 39, 47, 0, 0, 0, 19, 5, 95, 48, 77, 65, 51, 113, 4, 117, 55, 117, 38, 6, 35, 34, 72, 35, 0, 0, 18, 5, 95, 48, 77, 65, 50, 113, 4, 117, 55, 117, 38, 6, 39, 50, 35, 0, 0, 0, 0, 0, 0, 15, 3, 95, 56, 67, 84, 127, 95, 117, 65, 89, 6, 39, 47, 0, 0, 0, 0, 0, 0, 8, 197, 52, 241, 198, 76, 96, 73, 0, 0, 13, 3, 95, 52, 88, 89, 6, 39, 14, 16, 127, 49, 0, 0, 15, 3, 95, 57, 67, 72, 36, 84, 38, 126, 110, 6, 39, 47, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 53, 88, 48, 38, 126, 112, 112, 117, 95, 6, 120, 47, 0, 0, 7, 196, 64, 240, 156, 48, 73, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 54, 88, 91, 123, 94, 112, 112, 117, 95, 6, 120, 47, 0, 0, 0, 8, 197, 72, 211, 196, 81, 48, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 3, 95, 56, 88, 84, 6, 39, 95, 123, 65, 112, 123, 95, 126, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 3, 95, 57, 88, 112, 123, 84, 38, 117, 50, 6, 39, 89, 47, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 52, 241, 20, 76, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 61, 48, 72, 0, 0, 0, 0, 18, 4, 95, 48, 77, 50, 113, 4, 117, 55, 117, 38, 6, 39, 50, 39, 83, 0, 0, 19, 4, 95, 48, 77, 51, 113, 4, 117, 55, 117, 38, 6, 35, 34, 72, 39, 83, 0, 0, 0, 14, 4, 95, 48, 77, 49, 47, 6, 115, 95, 126, 110, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 64, 240, 156, 140, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 198, 72, 211, 199, 25, 151, 64, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 9, 65, 70, 101, 208, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 194, 171, 6, 39, 47, 49, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 72, 211, 216, 116, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 88, 244, 224, 66, 8, 0, 7, 196, 52, 241, 198, 52, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 52, 241, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 11, 67, 97, 51, 192, 91, 47, 39, 0, 72, 8, 0, 0, 0, 11, 3, 95, 194, 187, 88, 6, 35, 49, 34, 0, 0, 0, 0, 8, 197, 52, 241, 198, 101, 208, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 52, 241, 198, 76, 73, 0, 0, 6, 194, 56, 240, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 36, 35, 192, 72, 8, 7, 195, 36, 35, 192, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 95, 3, 84, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 95, 18, 121, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 2, 95, 34, 49, 126, 84, 6, 115, 78, 49, 35, 0, 0, 8, 197, 64, 240, 156, 48, 144, 74, 12, 2, 95, 33, 84, 6, 39, 89, 49, 55, 38, 0, 0, 0, 14, 2, 95, 39, 35, 48, 6, 39, 89, 47, 34, 126, 83, 0, 0, 0, 0, 0, 0, 0, 14, 2, 95, 41, 88, 6, 35, 49, 34, 49, 34, 40, 81, 0, 0, 14, 2, 95, 40, 6, 39, 47, 49, 34, 49, 34, 40, 81, 0, 0, 0, 11, 2, 95, 46, 47, 6, 39, 78, 49, 35, 0, 0, 11, 2, 95, 45, 72, 36, 83, 6, 37, 89, 0, 0, 13, 2, 95, 44, 88, 126, 48, 37, 47, 6, 35, 120, 0, 0, 10, 2, 95, 51, 47, 51, 38, 6, 37, 0, 0, 9, 2, 95, 50, 72, 84, 6, 134, 0, 0, 11, 2, 95, 49, 39, 57, 112, 6, 37, 50, 0, 0, 10, 2, 95, 48, 50, 6, 39, 57, 61, 0, 0, 10, 2, 95, 55, 95, 6, 36, 57, 65, 0, 0, 10, 2, 95, 54, 91, 6, 121, 95, 111, 0, 0, 10, 2, 95, 53, 48, 38, 6, 120, 111, 0, 0, 13, 2, 95, 52, 78, 117, 47, 6, 115, 51, 38, 117, 0, 0, 13, 2, 95, 59, 47, 6, 39, 78, 49, 88, 35, 48, 0, 0, 15, 2, 95, 58, 72, 84, 126, 36, 47, 6, 39, 78, 37, 36, 0, 0, 11, 2, 95, 57, 112, 6, 36, 84, 119, 111, 0, 0, 11, 2, 95, 56, 84, 6, 39, 95, 123, 65, 0, 0, 12, 2, 95, 63, 84, 39, 48, 34, 6, 39, 89, 0, 0, 7, 196, 72, 211, 196, 80, 73, 12, 2, 95, 62, 71, 6, 39, 55, 38, 91, 121, 0, 0, 0, 12, 2, 95, 60, 65, 6, 36, 50, 38, 91, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 198, 72, 211, 199, 25, 49, 128, 73, 0, 17, 2, 95, 91, 6, 39, 47, 49, 34, 49, 84, 35, 72, 34, 35, 47, 0, 0, 0, 0, 0, 0, 0, 17, 2, 95, 93, 88, 6, 35, 49, 34, 49, 84, 35, 72, 34, 35, 47, 0, 0, 0, 0, 0, 0, 12, 2, 95, 96, 35, 49, 110, 6, 121, 50, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 95, 123, 6, 39, 47, 49, 34, 83, 37, 81, 40, 34, 0, 0, 0, 0, 0, 0, 0, 15, 2, 95, 125, 88, 6, 35, 49, 34, 83, 37, 81, 40, 34, 0, 0, 10, 2, 95, 124, 84, 6, 36, 34, 47, 0, 0, 0, 0, 8, 197, 64, 240, 156, 48, 240, 74, 0, 0, 0, 0, 0, 0, 0, 7, 196, 72, 211, 196, 140, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 25, 34, 64, 74, 0, 0, 0, 18, 5, 95, 49, 77, 65, 51, 113, 4, 117, 55, 117, 38, 6, 35, 34, 47, 0, 0, 17, 5, 95, 49, 77, 65, 50, 113, 4, 117, 55, 117, 38, 6, 39, 50, 0, 0, 16, 5, 95, 49, 77, 65, 49, 47, 6, 115, 95, 117, 110, 38, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 25, 35, 93, 73, 0, 6, 195, 25, 35, 92, 73, 0, 13, 68, 68, 17, 73, 60, 34, 6, 35, 112, 117, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 64, 240, 148, 21, 64, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 1, 17, 0, 4, 2, 32, 3, 35, 0, 8, 0, 8, 2, 32, 0, 4, 3, 126, 0, 1, 17, 66, 2, 32, 0, 7, 6, 1, 18, 0, 4, 2, 32, 3, 48, 0, 2, 208, 186, 17, 71, 0, 2, 208, 186, 209, 140, 0, 2, 209, 129, 17, 71, 0, 2, 209, 129, 209, 140, 0, 2, 209, 130, 17, 71, 0, 2, 209, 130, 209, 140, 0, 2, 209, 133, 17, 71, 0, 2, 209, 133, 208, 186, 17, 71, 0, 2, 209, 133, 208, 186, 209, 140, 0, 2, 209, 133, 209, 140, 0, 2, 209, 135, 0, 2, 209, 137, 0, 4, 2, 208, 191, 17, 71, 3, 48, 38, 0, 2, 208, 191, 209, 140, 0, 2, 209, 132, 17, 71, 0, 2, 209, 132, 209, 132, 17, 71, 0, 2, 209, 132, 209, 132, 209, 140, 0, 2, 209, 132, 209, 140, 0, 2, 209, 140, 32, 0, 3, 71, 0, 4, 2, 17, 71, 3, 71, 38, 0, 2, 208, 177, 17, 71, 0, 2, 208, 177, 208, 178, 17, 71, 0, 2, 208, 177, 208, 178, 209, 140, 0, 2, 208, 177, 208, 188, 17, 71, 0, 2, 208, 177, 208, 188, 209, 140, 0, 2, 208, 177, 209, 140, 0, 2, 208, 178, 17, 71, 0, 2, 208, 178, 209, 140, 0, 2, 208, 188, 17, 71, 0, 2, 208, 188, 209, 140, 0, 2, 209, 140, 0, 8, 2, 32, 3, 71, 121, 0, 7, 6, 1, 19, 0, 4, 2, 32, 3, 83, 0, 2, 208, 186, 17, 71, 0, 2, 208, 186, 209, 140, 0, 2, 209, 129, 17, 71, 0, 2, 209, 129, 209, 140, 0, 2, 209, 130, 17, 71, 0, 2, 209, 130, 209, 140, 0, 2, 209, 133, 17, 71, 0, 2, 209, 133, 208, 186, 17, 71, 0, 2, 209, 133, 208, 186, 209, 140, 0, 2, 209, 133, 209, 140, 0, 2, 209, 135, 0, 2, 209, 137, 0, 4, 2, 208, 191, 39, 3, 83, 38, 0, 2, 209, 132, 39, 0, 2, 209, 140, 32, 0, 3, 84, 0, 4, 2, 17, 71, 3, 84, 38, 0, 2, 208, 177, 17, 71, 0, 2, 208, 177, 209, 140, 0, 2, 208, 178, 17, 71, 0, 2, 208, 178, 208, 177, 17, 71, 0, 2, 208, 178, 208, 177, 209, 140, 0, 2, 208, 178, 208, 188, 17, 71, 0, 2, 208, 178, 208, 188, 209, 140, 0, 2, 208, 178, 209, 140, 0, 2, 208, 188, 17, 71, 0, 2, 208, 188, 209, 140, 0, 2, 209, 140, 0, 8, 2, 32, 3, 84, 121, 0, 7, 6, 1, 20, 0, 4, 2, 32, 3, 49, 0, 2, 208, 191, 17, 71, 0, 2, 208, 191, 209, 140, 0, 2, 209, 129, 17, 71, 0, 2, 209, 129, 209, 140, 0, 2, 209, 130, 17, 71, 0, 2, 209, 130, 209, 140, 0, 2, 209, 132, 17, 71, 0, 2, 209, 132, 209, 132, 17, 71, 0, 2, 209, 132, 209, 132, 209, 140, 0, 2, 209, 132, 209, 140, 0, 2, 209, 133, 17, 71, 0, 2, 209, 133, 208, 186, 17, 71, 0, 2, 209, 133, 208, 186, 209, 140, 0, 2, 209, 133, 209, 140, 0, 4, 3, 81, 0, 8, 190, 208, 189, 208, 188, 208, 2, 208, 190, 32, 0, 4, 2, 17, 71, 3, 81, 38, 0, 2, 209, 140, 0, 8, 2, 32, 3, 81, 121, 0, 4, 1, 181, 208, 2, 208, 190, 209, 129, 209, 143, 32, 3, 84, 0, 1, 181, 208, 17, 67, 2, 208, 190, 32, 0, 1, 190, 208, 17, 67, 2, 208, 190, 32, 0, 8, 181, 208, 2, 208, 190, 32, 0, 8, 181, 208, 129, 209, 2, 208, 190, 0, 8, 181, 208, 129, 209, 178, 208, 2, 208, 190, 32, 0, 8, 181, 208, 189, 208, 2, 208, 190, 32, 0, 8, 181, 208, 190, 208, 178, 208, 130, 209, 2, 208, 190, 32, 0, 8, 181, 208, 190, 208, 188, 208, 2, 208, 190, 32, 0, 2, 208, 186, 3, 101, 0, 7, 6, 1, 21, 0, 4, 2, 32, 3, 47, 0, 2, 208, 186, 17, 71, 0, 2, 208, 186, 209, 140, 0, 2, 208, 191, 17, 71, 0, 2, 208, 191, 209, 140, 0, 2, 209, 132, 17, 71, 0, 2, 209, 132, 209, 132, 17, 71, 0, 2, 209, 132, 209, 132, 209, 140, 0, 2, 209, 132, 209, 140, 0, 2, 209, 133, 17, 71, 0, 2, 209, 133, 208, 186, 17, 71, 0, 2, 209, 133, 208, 186, 209, 140, 0, 2, 209, 133, 209, 140, 0, 3, 72, 0, 8, 2, 32, 3, 72, 121, 0, 4, 2, 209, 129, 17, 71, 3, 111, 0, 2, 209, 129, 209, 140, 0, 2, 209, 130, 17, 71, 0, 2, 209, 130, 209, 140, 0, 2, 209, 140, 32, 0, 4, 2, 17, 66, 3, 112, 0, 2, 17, 71, 0, 2, 208, 180, 17, 71, 0, 2, 208, 180, 209, 140, 0, 2, 208, 183, 17, 71, 0, 2, 208, 183, 209, 140, 0, 2, 208, 189, 209, 140, 0, 2, 209, 140, 0, 7, 6, 1, 22, 0, 3, 36, 0, 4, 1, 17, 65, 3, 57, 36, 0, 1, 138, 209, 0, 1, 140, 209, 0, 8, 2, 32, 0, 4, 1, 17, 65, 2, 32, 3, 57, 119, 0, 1, 138, 209, 2, 32, 0, 1, 140, 209, 2, 32, 0, 8, 0, 4, 1, 130, 209, 2, 209, 129, 209, 130, 3, 125, 0, 1, 130, 209, 128, 209, 176, 208, 177, 208, 2, 209, 128, 0, 1, 130, 209, 142, 209, 140, 209, 191, 208, 188, 208, 190, 208, 186, 208, 2, 209, 128, 0, 1, 130, 209, 186, 208, 176, 208, 177, 208, 2, 209, 128, 0, 1, 130, 209, 189, 208, 184, 208, 2, 209, 128, 0, 7, 6, 1, 23, 0, 3, 90, 0, 8, 2, 32, 3, 90, 121, 0, 4, 2, 32, 3, 91, 0, 2, 208, 186, 17, 71, 0, 2, 208, 186, 209, 140, 0, 2, 208, 191, 17, 71, 0, 2, 208, 191, 209, 140, 0, 2, 209, 129, 17, 71, 0, 2, 209, 129, 209, 140, 0, 2, 209, 130, 17, 71, 0, 2, 209, 130, 209, 140, 0, 2, 209, 132, 17, 71, 0, 2, 209, 132, 209, 132, 17, 71, 0, 2, 209, 132, 209, 132, 209, 140, 0, 2, 209, 132, 209, 140, 0, 2, 209, 133, 17, 71, 0, 2, 209, 133, 208, 186, 17, 71, 0, 2, 209, 133, 208, 186, 209, 140, 0, 2, 209, 133, 209, 140, 0, 209, 135, 3, 97, 0, 7, 6, 1, 24, 0, 3, 88, 0, 8, 2, 32, 3, 88, 121, 0, 4, 2, 32, 3, 89, 0, 2, 208, 186, 17, 71, 0, 2, 208, 186, 209, 140, 0, 2, 208, 191, 17, 71, 0, 2, 208, 191, 209, 140, 0, 2, 209, 132, 17, 71, 0, 2, 209, 132, 209, 132, 17, 71, 0, 2, 209, 132, 209, 132, 209, 140, 0, 2, 209, 132, 209, 140, 0, 2, 209, 133, 17, 71, 0, 2, 209, 133, 208, 186, 17, 71, 0, 2, 209, 133, 208, 186, 209, 140, 0, 2, 209, 133, 209, 140, 0, 2, 209, 137, 0, 2, 208, 182, 3, 90, 0, 2, 209, 136, 3, 91, 0, 4, 2, 17, 71, 3, 94, 0, 2, 208, 180, 17, 71, 0, 2, 208, 180, 209, 140, 0, 2, 208, 183, 17, 71, 0, 2, 208, 183, 208, 180, 17, 71, 0, 2, 208, 183, 208, 180, 209, 140, 0, 2, 208, 183, 208, 189, 17, 66, 0, 2, 208, 183, 208, 189, 17, 71, 0, 2, 208, 183, 208, 189, 209, 140, 0, 2, 208, 183, 209, 140, 0, 2, 208, 189, 17, 66, 0, 2, 208, 189, 17, 71, 0, 2, 208, 189, 209, 140, 0, 2, 209, 140, 0, 4, 2, 208, 183, 17, 71, 32, 3, 95, 0, 2, 208, 183, 208, 180, 17, 71, 32, 0, 2, 208, 183, 208, 180, 209, 140, 32, 0, 2, 208, 183, 208, 189, 17, 66, 32, 0, 2, 208, 183, 208, 189, 17, 71, 32, 0, 2, 208, 183, 208, 189, 209, 140, 32, 0, 2, 208, 183, 209, 140, 32, 0, 2, 209, 129, 17, 71, 0, 2, 209, 129, 209, 140, 0, 2, 209, 130, 17, 71, 0, 2, 209, 130, 209, 140, 0, 4, 209, 135, 3, 97, 0, 209, 137, 0, 7, 6, 1, 25, 0, 4, 3, 37, 0, 8, 2, 32, 0, 4, 1, 17, 68, 3, 115, 0, 1, 136, 209, 0, 1, 182, 208, 0, 4, 2, 32, 3, 117, 0, 8, 0, 7, 6, 1, 26, 0, 8, 2, 32, 3, 4, 37, 6, 49, 14, 16, 6, 134, 47, 49, 127, 57, 117, 0, 3, 57, 0, 7, 6, 1, 27, 0, 3, 49, 0, 4, 2, 17, 71, 3, 49, 38, 0, 2, 209, 140, 0, 8, 2, 32, 3, 49, 134, 0, 4, 2, 208, 177, 3, 81, 0, 2, 208, 177, 17, 71, 0, 2, 208, 177, 209, 140, 0, 2, 208, 179, 0, 2, 208, 179, 17, 71, 0, 2, 208, 179, 209, 140, 0, 2, 208, 180, 0, 2, 208, 180, 17, 66, 0, 2, 208, 180, 17, 71, 0, 2, 208, 180, 209, 140, 0, 2, 208, 182, 0, 2, 208, 183, 0, 2, 208, 183, 17, 71, 0, 2, 208, 183, 209, 140, 0, 7, 6, 1, 28, 0, 3, 55, 0, 2, 17, 71, 3, 61, 0, 8, 2, 32, 3, 121, 61, 0, 7, 6, 1, 29, 0, 3, 65, 0, 4, 2, 17, 71, 3, 113, 0, 2, 208, 177, 17, 71, 0, 2, 208, 177, 209, 140, 0, 2, 208, 178, 17, 71, 0, 2, 208, 178, 209, 140, 0, 2, 208, 191, 17, 71, 0, 2, 208, 191, 209, 140, 0, 2, 209, 132, 17, 71, 0, 2, 209, 132, 209, 132, 17, 71, 0, 2, 209, 132, 209, 132, 209, 140, 0, 2, 209, 132, 209, 140, 0, 2, 209, 140, 0, 8, 2, 32, 3, 121, 65, 0, 7, 6, 1, 30, 0, 3, 50, 0, 208, 181, 1, 183, 208, 184, 208, 177, 208, 2, 209, 129, 3, 50, 125, 0, 2, 32, 3, 108, 0, 8, 2, 32, 3, 121, 108, 0, 7, 6, 1, 31, 0, 3, 39, 0, 7, 6, 1, 32, 0, 3, 48, 0, 4, 2, 17, 71, 3, 48, 38, 0, 2, 208, 188, 17, 71, 0, 2, 208, 188, 209, 140, 0, 2, 208, 191, 17, 71, 0, 2, 208, 191, 208, 188, 17, 71, 0, 2, 208, 191, 208, 188, 209, 140, 0, 2, 208, 191, 209, 132, 17, 71, 0, 2, 208, 191, 209, 132, 209, 140, 0, 2, 208, 191, 209, 140, 0, 2, 209, 132, 17, 71, 0, 2, 209, 132, 209, 132, 17, 71, 0, 2, 209, 132, 209, 132, 209, 140, 0, 2, 209, 132, 209, 140, 0, 2, 209, 140, 0, 8, 2, 32, 3, 48, 121, 0, 4, 2, 208, 177, 3, 71, 0, 2, 208, 179, 0, 2, 208, 179, 17, 71, 0, 2, 208, 179, 209, 140, 0, 2, 208, 180, 0, 2, 208, 180, 17, 66, 0, 2, 208, 180, 17, 71, 0, 2, 208, 180, 209, 140, 0, 2, 208, 182, 0, 2, 208, 183, 0, 2, 208, 183, 17, 71, 0, 2, 208, 183, 209, 140, 0, 2, 208, 177, 39, 3, 71, 38, 0, 7, 6, 1, 33, 0, 3, 34, 0, 4, 2, 17, 66, 3, 34, 38, 0, 2, 17, 71, 0, 2, 209, 140, 3, 34, 114, 0, 8, 2, 32, 3, 121, 34, 0, 7, 6, 1, 34, 0, 4, 2, 208, 177, 3, 88, 0, 2, 208, 179, 0, 2, 208, 180, 0, 2, 208, 182, 0, 2, 208, 183, 0, 4, 3, 89, 0, 2, 209, 130, 209, 140, 0, 2, 208, 182, 3, 90, 0, 2, 209, 136, 3, 91, 0, 4, 2, 208, 180, 17, 66, 3, 94, 0, 2, 208, 180, 17, 71, 0, 2, 208, 180, 209, 140, 0, 2, 208, 183, 17, 71, 0, 2, 208, 183, 209, 140, 0, 4, 2, 17, 71, 3, 95, 0, 2, 208, 189, 17, 66, 0, 2, 208, 189, 17, 71, 0, 2, 208, 189, 209, 140, 0, 2, 209, 129, 17, 71, 0, 2, 209, 129, 209, 140, 0, 2, 209, 130, 17, 71, 0, 2, 209, 140, 0, 2, 209, 137, 3, 95, 95, 0, 209, 135, 3, 97, 0, 8, 2, 32, 3, 121, 89, 0, 7, 6, 1, 35, 0, 3, 47, 0, 8, 2, 32, 3, 47, 121, 0, 4, 2, 208, 177, 3, 72, 0, 2, 208, 179, 0, 2, 208, 180, 0, 2, 208, 182, 0, 2, 208, 182, 0, 2, 208, 183, 0, 209, 129, 1, 17, 71, 3, 110, 0, 4, 2, 17, 71, 3, 111, 0, 2, 208, 189, 17, 66, 0, 2, 208, 189, 17, 71, 0, 2, 208, 189, 209, 140, 0, 2, 209, 129, 17, 71, 0, 2, 209, 129, 209, 140, 0, 2, 209, 130, 17, 71, 0, 2, 209, 130, 209, 140, 0, 2, 209, 140, 0, 4, 2, 208, 180, 17, 66, 3, 112, 0, 2, 208, 180, 17, 71, 0, 2, 208, 180, 209, 140, 0, 2, 208, 183, 17, 71, 0, 2, 208, 183, 209, 140, 0, 7, 6, 1, 36, 0, 4, 3, 40, 0, 8, 2, 32, 0, 1, 17, 66, 3, 129, 0, 7, 6, 1, 37, 0, 3, 83, 0, 4, 2, 17, 71, 3, 83, 38, 0, 2, 208, 188, 17, 71, 0, 2, 208, 188, 209, 140, 0, 2, 208, 191, 17, 71, 0, 2, 208, 191, 208, 188, 17, 71, 0, 2, 208, 191, 208, 188, 209, 140, 0, 2, 208, 191, 209, 132, 17, 71, 0, 2, 208, 191, 209, 132, 209, 140, 0, 2, 208, 191, 209, 140, 0, 2, 209, 132, 17, 71, 0, 2, 209, 132, 209, 140, 0, 2, 209, 140, 0, 4, 2, 208, 177, 3, 84, 0, 2, 208, 179, 0, 2, 208, 179, 17, 71, 0, 2, 208, 179, 209, 140, 0, 2, 208, 180, 0, 2, 208, 180, 17, 66, 0, 2, 208, 180, 17, 71, 0, 2, 208, 180, 209, 140, 0, 2, 208, 182, 0, 2, 208, 183, 0, 2, 208, 183, 17, 71, 0, 2, 208, 183, 209, 140, 0, 2, 208, 177, 39, 3, 84, 38, 0, 8, 2, 32, 3, 121, 83, 0, 7, 6, 1, 38, 0, 4, 3, 101, 0, 2, 17, 71, 0, 2, 32, 208, 177, 209, 139, 0, 2, 208, 177, 0, 2, 208, 177, 17, 71, 0, 2, 208, 177, 208, 178, 17, 71, 0, 2, 208, 177, 208, 178, 209, 140, 0, 2, 208, 177, 208, 188, 17, 71, 0, 2, 208, 177, 208, 188, 209, 140, 0, 2, 208, 177, 209, 140, 0, 2, 208, 179, 0, 2, 208, 179, 17, 71, 0, 2, 208, 179, 209, 140, 0, 2, 208, 180, 0, 2, 208, 180, 17, 66, 0, 2, 208, 180, 17, 71, 0, 2, 208, 180, 209, 140, 0, 2, 208, 182, 0, 2, 208, 183, 0, 2, 208, 183, 17, 71, 0, 2, 208, 183, 209, 140, 0, 2, 208, 186, 17, 71, 0, 2, 208, 186, 209, 140, 0, 2, 209, 140, 0, 8, 2, 32, 3, 101, 134, 0, 7, 6, 1, 39, 0, 4, 2, 208, 177, 3, 72, 88, 0, 2, 208, 177, 17, 71, 0, 2, 208, 177, 208, 178, 17, 71, 0, 2, 208, 177, 208, 178, 209, 140, 0, 2, 208, 177, 208, 188, 17, 71, 0, 2, 208, 177, 208, 188, 209, 140, 0, 2, 208, 177, 209, 140, 0, 2, 208, 179, 0, 2, 208, 179, 17, 71, 0, 2, 208, 179, 209, 140, 0, 2, 208, 180, 0, 2, 208, 180, 17, 66, 0, 2, 208, 180, 17, 71, 0, 2, 208, 180, 209, 140, 0, 2, 208, 182, 0, 2, 208, 183, 0, 2, 208, 183, 17, 71, 0, 2, 208, 183, 209, 140, 0, 3, 110, 0, 8, 2, 32, 3, 110, 121, 0, 7, 6, 1, 40, 0, 1, 131, 209, 187, 208, 2, 209, 136, 208, 181, 3, 47, 0, 4, 2, 208, 177, 3, 77, 0, 2, 208, 177, 17, 71, 0, 2, 208, 177, 208, 178, 17, 71, 0, 2, 208, 177, 208, 178, 209, 140, 0, 2, 208, 177, 208, 188, 17, 71, 0, 2, 208, 177, 208, 188, 209, 140, 0, 2, 208, 177, 209, 140, 0, 2, 208, 179, 0, 2, 208, 179, 17, 71, 0, 2, 208, 179, 209, 140, 0, 2, 208, 180, 0, 2, 208, 180, 17, 66, 0, 2, 208, 180, 17, 71, 0, 2, 208, 180, 209, 140, 0, 2, 208, 182, 0, 2, 208, 183, 0, 2, 208, 183, 17, 71, 0, 2, 208, 183, 209, 140, 0, 3, 78, 0, 8, 2, 32, 3, 78, 36, 0, 4, 1, 131, 209, 186, 208, 129, 209, 2, 208, 189, 3, 91, 0, 1, 143, 209, 130, 209, 129, 209, 131, 209, 191, 208, 2, 208, 189, 0, 1, 181, 208, 128, 209, 190, 208, 178, 208, 186, 208, 129, 209, 2, 208, 189, 0, 1, 181, 208, 189, 208, 190, 208, 186, 208, 2, 208, 189, 208, 190, 0, 1, 184, 208, 143, 209, 2, 208, 189, 208, 184, 0, 1, 184, 208, 178, 208, 181, 208, 180, 208, 2, 208, 189, 0, 2, 208, 189, 208, 176, 32, 0, 2, 208, 189, 208, 181, 32, 0, 2, 208, 189, 208, 190, 208, 185, 32, 0, 2, 208, 189, 209, 131, 32, 0, 2, 208, 189, 209, 139, 32, 0, 8, 2, 209, 130, 208, 190, 0, 7, 6, 1, 41, 0, 4, 2, 208, 177, 3, 90, 0, 2, 208, 177, 17, 71, 0, 2, 208, 177, 208, 178, 17, 71, 0, 2, 208, 177, 208, 178, 209, 140, 0, 2, 208, 177, 208, 188, 17, 71, 0, 2, 208, 177, 208, 188, 209, 140, 0, 2, 208, 177, 209, 140, 0, 2, 208, 179, 0, 2, 208, 179, 17, 71, 0, 2, 208, 179, 209, 140, 0, 2, 208, 180, 0, 2, 208, 180, 17, 66, 0, 2, 208, 180, 17, 71, 0, 2, 208, 180, 209, 140, 0, 2, 208, 182, 0, 2, 208, 183, 0, 2, 208, 183, 17, 71, 0, 2, 208, 183, 209, 140, 0, 3, 91, 0, 8, 2, 32, 3, 91, 134, 0, 7, 6, 1, 42, 0, 4, 2, 208, 177, 3, 96, 0, 2, 208, 177, 17, 71, 0, 2, 208, 177, 208, 178, 17, 71, 0, 2, 208, 177, 208, 178, 209, 140, 0, 2, 208, 177, 208, 188, 17, 71, 0, 2, 208, 177, 208, 188, 209, 140, 0, 2, 208, 177, 209, 140, 0, 2, 208, 179, 0, 2, 208, 179, 17, 71, 0, 2, 208, 179, 209, 140, 0, 2, 208, 180, 0, 2, 208, 180, 17, 66, 0, 2, 208, 180, 17, 71, 0, 2, 208, 180, 209, 140, 0, 2, 208, 182, 0, 2, 208, 183, 0, 2, 208, 183, 17, 71, 0, 2, 208, 183, 209, 140, 0, 3, 97, 0, 8, 2, 32, 3, 97, 120, 0, 7, 6, 1, 43, 0, 3, 0, 8, 2, 32, 3, 47, 84, 38, 6, 128, 14, 16, 72, 115, 57, 88, 50, 6, 134, 49, 0, 2, 17, 71, 3, 57, 0, 7, 6, 1, 44, 0, 4, 3, 115, 0, 8, 2, 32, 0, 7, 6, 1, 45, 0, 3, 0, 2, 17, 71, 3, 57, 0, 8, 2, 32, 3, 113, 6, 120, 49, 38, 116, 57, 88, 50, 6, 134, 49, 0, 7, 6, 1, 46, 0, 8, 2, 32, 3, 36, 0, 4, 2, 32, 3, 122, 0, 8, 0, 3, 123, 0, 7, 6, 1, 47, 0, 1, 131, 209, 180, 208, 181, 208, 187, 208, 129, 209, 2, 209, 137, 3, 0, 3, 130, 0, 4, 1, 17, 65, 3, 131, 0, 1, 138, 209, 0, 1, 140, 209, 0, 8, 0, 8, 2, 32, 0, 7, 6, 1, 48, 0, 4, 1, 17, 65, 3, 120, 0, 1, 17, 65, 2, 32, 0, 1, 138, 209, 0, 1, 138, 209, 2, 32, 0, 1, 140, 209, 0, 1, 140, 209, 2, 32, 0, 8, 0, 8, 2, 32, 0, 4, 3, 126, 0, 2, 32, 0, 7, 6, 1, 50, 0, 8, 3, 6, 57, 128, 0, 4, 1, 136, 209, 3, 6, 127, 0, 1, 182, 208, 0, 3, 6, 128, 0, 8, 2, 32, 3, 57, 128, 0, 7, 6, 0, 36, 3, 72, 39, 55, 35, 34, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts54 = FileInMemory_createWithData (6157, reinterpret_cast (&espeakdata_dicts54_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/ru_dict", U"ru"); Collection_addItem (me.peek(), espeakdata_dicts54.transfer()); static unsigned char espeakdata_dicts55_data[2251] = { 0, 4, 0, 0, 171, 7, 0, 0, 0, 0, 0, 0, 0, 6, 65, 4, 35, 12, 0, 0, 0, 0, 0, 7, 65, 8, 71, 35, 12, 0, 0, 0, 0, 0, 7, 65, 12, 80, 35, 12, 0, 0, 0, 0, 0, 7, 65, 16, 72, 35, 12, 0, 0, 0, 0, 0, 6, 65, 20, 36, 12, 0, 0, 0, 0, 0, 7, 65, 24, 83, 35, 12, 0, 0, 0, 0, 0, 7, 65, 28, 81, 35, 12, 0, 0, 0, 0, 0, 7, 65, 32, 107, 35, 12, 0, 0, 0, 0, 0, 6, 65, 36, 37, 12, 0, 0, 0, 0, 0, 7, 65, 40, 75, 35, 12, 0, 0, 0, 0, 0, 7, 65, 44, 49, 35, 12, 0, 0, 0, 0, 0, 7, 65, 48, 55, 35, 12, 0, 0, 0, 0, 0, 7, 65, 52, 65, 35, 12, 0, 0, 0, 0, 0, 10, 5, 95, 48, 1, 14, 4, 50, 35, 0, 7, 65, 56, 50, 35, 12, 0, 0, 0, 0, 0, 6, 65, 60, 39, 12, 0, 0, 0, 0, 0, 7, 65, 64, 48, 35, 12, 0, 0, 0, 0, 0, 8, 65, 68, 49, 58, 35, 12, 0, 0, 0, 0, 0, 7, 65, 72, 16, 35, 12, 0, 0, 0, 0, 0, 7, 65, 76, 89, 35, 12, 0, 0, 0, 0, 0, 7, 65, 80, 47, 35, 12, 0, 0, 0, 0, 0, 6, 65, 84, 40, 12, 0, 0, 0, 0, 0, 7, 65, 88, 84, 35, 12, 0, 0, 0, 0, 0, 7, 65, 92, 58, 35, 12, 0, 0, 0, 0, 0, 16, 4, 95, 49, 77, 49, 37, 79, 37, 107, 6, 40, 65, 71, 37, 0, 7, 65, 96, 36, 49, 89, 0, 0, 20, 4, 95, 49, 77, 50, 65, 37, 55, 37, 57, 6, 39, 50, 6, 37, 65, 58, 36, 0, 0, 0, 0, 7, 65, 100, 57, 35, 12, 0, 0, 0, 0, 0, 7, 65, 104, 88, 35, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 4, 95, 50, 77, 49, 37, 82, 37, 107, 6, 40, 65, 71, 37, 71, 37, 82, 6, 37, 16, 37, 0, 0, 22, 4, 95, 50, 77, 50, 65, 37, 55, 37, 57, 6, 39, 50, 36, 82, 57, 6, 37, 16, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 4, 95, 4, 16, 20, 10, 50, 37, 82, 6, 37, 76, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 4, 95, 51, 77, 49, 37, 82, 37, 107, 6, 40, 65, 71, 37, 71, 37, 47, 6, 35, 47, 40, 0, 0, 21, 4, 95, 51, 77, 50, 65, 37, 55, 37, 57, 6, 39, 50, 36, 91, 6, 35, 47, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 4, 95, 53, 77, 49, 37, 82, 37, 107, 6, 40, 65, 71, 37, 71, 37, 47, 6, 35, 50, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 3, 95, 51, 88, 65, 37, 16, 4, 39, 68, 81, 58, 37, 47, 6, 35, 47, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 49, 67, 37, 75, 6, 35, 50, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 3, 95, 50, 67, 65, 35, 81, 4, 35, 50, 35, 82, 6, 37, 16, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 3, 95, 51, 67, 65, 35, 81, 4, 35, 50, 35, 47, 6, 35, 47, 40, 0, 0, 0, 0, 26, 4, 95, 54, 77, 49, 37, 82, 37, 107, 6, 40, 65, 71, 37, 71, 37, 47, 35, 50, 72, 6, 35, 47, 40, 0, 0, 0, 0, 0, 22, 3, 95, 55, 88, 65, 37, 16, 4, 39, 68, 81, 58, 37, 16, 6, 37, 50, 72, 58, 37, 0, 0, 16, 3, 95, 52, 67, 65, 35, 81, 4, 35, 50, 6, 35, 50, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 3, 95, 53, 67, 65, 35, 81, 4, 35, 50, 35, 47, 6, 35, 50, 40, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 49, 88, 37, 76, 6, 40, 65, 37, 0, 0, 21, 3, 95, 54, 67, 65, 35, 81, 4, 35, 50, 35, 47, 35, 50, 72, 6, 35, 47, 40, 0, 0, 0, 0, 0, 0, 0, 0, 18, 3, 95, 50, 88, 65, 35, 49, 40, 65, 57, 35, 82, 6, 37, 16, 37, 0, 0, 20, 3, 95, 55, 67, 65, 35, 81, 4, 35, 50, 35, 16, 6, 37, 50, 72, 58, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 3, 95, 56, 67, 65, 35, 81, 4, 35, 50, 37, 50, 6, 35, 50, 37, 0, 0, 0, 0, 0, 0, 0, 0, 18, 3, 95, 52, 88, 65, 37, 16, 4, 39, 68, 81, 58, 6, 37, 50, 36, 0, 0, 20, 3, 95, 57, 67, 65, 35, 81, 4, 35, 50, 35, 49, 57, 6, 36, 50, 72, 35, 0, 0, 0, 0, 0, 0, 0, 0, 20, 3, 95, 53, 88, 65, 37, 16, 4, 39, 68, 81, 58, 37, 47, 6, 35, 50, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 3, 95, 54, 88, 65, 37, 16, 4, 39, 68, 81, 37, 47, 35, 50, 72, 6, 35, 47, 40, 0, 0, 0, 0, 0, 25, 4, 95, 55, 77, 49, 37, 82, 37, 107, 6, 40, 65, 71, 37, 71, 37, 16, 6, 37, 50, 72, 58, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 3, 95, 56, 88, 65, 37, 16, 4, 39, 68, 81, 58, 37, 50, 6, 35, 50, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 3, 95, 57, 88, 65, 37, 16, 4, 39, 68, 81, 58, 36, 57, 6, 36, 50, 72, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 4, 95, 48, 77, 50, 65, 37, 55, 37, 57, 6, 39, 50, 37, 0, 0, 0, 0, 16, 4, 95, 48, 77, 49, 37, 82, 37, 107, 6, 40, 65, 71, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 4, 95, 52, 77, 50, 65, 4, 37, 55, 37, 57, 6, 39, 50, 6, 36, 67, 36, 0, 0, 21, 4, 95, 52, 77, 49, 37, 82, 37, 107, 6, 40, 65, 71, 37, 71, 6, 37, 50, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 2, 95, 51, 81, 35, 47, 6, 35, 47, 40, 0, 0, 12, 2, 95, 50, 49, 35, 82, 6, 37, 16, 37, 0, 0, 11, 2, 95, 49, 51, 6, 37, 65, 58, 36, 0, 0, 10, 2, 95, 48, 88, 6, 36, 16, 40, 0, 0, 14, 2, 95, 55, 49, 35, 16, 6, 37, 50, 72, 58, 37, 0, 0, 15, 2, 95, 54, 81, 35, 47, 35, 50, 72, 6, 35, 47, 40, 0, 0, 12, 2, 95, 53, 81, 35, 47, 6, 35, 50, 40, 0, 0, 10, 2, 95, 52, 49, 6, 35, 50, 36, 0, 0, 0, 0, 13, 2, 95, 57, 37, 49, 57, 6, 36, 50, 72, 35, 0, 0, 13, 2, 95, 56, 40, 65, 40, 50, 6, 35, 50, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 97, 0, 3, 35, 0, 7, 6, 98, 0, 4, 1, 109, 3, 71, 0, 8, 0, 3, 82, 0, 7, 6, 99, 0, 121, 3, 49, 57, 0, 3, 76, 0, 7, 6, 100, 0, 3, 72, 0, 7, 6, 101, 0, 3, 36, 0, 7, 6, 102, 0, 3, 83, 0, 7, 6, 103, 0, 4, 2, 101, 3, 79, 0, 2, 105, 0, 3, 81, 0, 7, 6, 104, 0, 3, 107, 0, 7, 6, 105, 0, 3, 37, 0, 7, 6, 106, 0, 3, 75, 0, 121, 3, 79, 57, 0, 7, 6, 107, 0, 3, 49, 0, 4, 2, 101, 3, 80, 0, 2, 105, 0, 7, 6, 108, 0, 3, 55, 0, 7, 6, 109, 0, 3, 65, 0, 112, 3, 65, 107, 0, 7, 6, 110, 0, 3, 50, 0, 116, 3, 50, 107, 0, 4, 2, 103, 101, 3, 67, 0, 2, 103, 105, 0, 121, 0, 2, 103, 3, 68, 0, 107, 3, 68, 101, 0, 7, 6, 111, 0, 3, 39, 0, 7, 6, 112, 0, 3, 48, 0, 7, 6, 113, 0, 3, 104, 0, 7, 6, 114, 0, 3, 16, 0, 8, 3, 51, 0, 7, 6, 115, 0, 3, 89, 0, 104, 3, 91, 0, 104, 121, 3, 97, 0, 7, 6, 116, 0, 3, 47, 0, 7, 6, 117, 0, 3, 40, 0, 7, 6, 118, 0, 3, 80, 0, 7, 6, 119, 0, 3, 58, 0, 1, 98, 3, 81, 0, 7, 6, 120, 0, 3, 49, 89, 0, 8, 3, 88, 0, 7, 6, 121, 0, 3, 57, 0, 7, 6, 122, 0, 3, 88, 0, 7, 6, 0, 36, 3, 72, 39, 55, 35, 16, 35, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts55 = FileInMemory_createWithData (2250, reinterpret_cast (&espeakdata_dicts55_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/rw_dict", U"rw"); Collection_addItem (me.peek(), espeakdata_dicts55.transfer()); static unsigned char espeakdata_dicts56_data[2455] = { 0, 4, 0, 0, 253, 5, 0, 0, 0, 0, 0, 0, 0, 6, 65, 4, 114, 57, 0, 0, 0, 0, 0, 6, 65, 8, 71, 112, 0, 0, 0, 0, 0, 6, 65, 12, 89, 112, 0, 0, 0, 0, 0, 6, 65, 16, 72, 112, 0, 0, 0, 0, 0, 5, 65, 20, 112, 0, 0, 0, 0, 0, 6, 65, 24, 116, 83, 0, 0, 0, 0, 0, 6, 65, 28, 75, 112, 0, 0, 0, 0, 0, 6, 65, 32, 114, 76, 0, 0, 0, 0, 0, 6, 65, 36, 118, 57, 0, 0, 13, 1, 37, 89, 37, 57, 13, 57, 13, 140, 13, 0, 27, 0, 0, 0, 7, 65, 40, 75, 114, 57, 0, 0, 0, 16, 1, 42, 149, 89, 140, 13, 34, 37, 89, 49, 13, 57, 13, 0, 27, 0, 0, 7, 65, 44, 49, 114, 57, 0, 0, 0, 0, 0, 6, 65, 48, 116, 55, 0, 0, 0, 0, 0, 6, 65, 52, 116, 65, 0, 0, 0, 0, 0, 6, 65, 56, 116, 50, 0, 0, 0, 0, 0, 5, 65, 60, 119, 0, 0, 0, 0, 0, 6, 65, 64, 48, 112, 0, 0, 0, 0, 0, 7, 65, 68, 49, 57, 123, 0, 0, 0, 0, 0, 6, 65, 72, 118, 34, 0, 0, 0, 0, 0, 6, 65, 76, 116, 89, 0, 0, 0, 0, 0, 6, 65, 80, 138, 112, 0, 0, 0, 0, 0, 6, 65, 84, 57, 123, 0, 0, 0, 0, 0, 6, 65, 88, 84, 112, 0, 0, 0, 0, 0, 11, 65, 92, 72, 35, 71, 35, 55, 57, 123, 0, 0, 0, 0, 0, 7, 65, 96, 116, 49, 89, 0, 0, 0, 0, 0, 7, 65, 100, 58, 118, 57, 0, 0, 0, 0, 0, 7, 65, 104, 88, 116, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 48, 67, 89, 37, 57, 13, 57, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 49, 57, 72, 35, 107, 13, 50, 35, 84, 13, 57, 13, 0, 0, 13, 3, 95, 49, 56, 72, 35, 107, 13, 35, 140, 13, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 49, 49, 36, 49, 39, 62, 13, 107, 13, 0, 0, 12, 3, 95, 49, 48, 72, 35, 107, 13, 57, 13, 0, 0, 14, 3, 95, 49, 51, 72, 35, 107, 13, 47, 40, 50, 13, 0, 0, 12, 3, 95, 49, 50, 72, 39, 62, 13, 107, 13, 0, 0, 14, 3, 95, 49, 53, 48, 35, 107, 13, 62, 39, 84, 13, 0, 0, 16, 3, 95, 49, 52, 72, 35, 107, 13, 107, 35, 47, 13, 34, 13, 0, 0, 14, 3, 95, 49, 55, 72, 35, 107, 13, 107, 35, 47, 13, 0, 0, 14, 3, 95, 49, 54, 72, 35, 107, 13, 89, 35, 57, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 50, 88, 84, 37, 89, 89, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 4, 95, 48, 77, 50, 65, 37, 55, 37, 57, 13, 50, 13, 57, 13, 0, 0, 17, 4, 95, 48, 77, 51, 71, 37, 55, 37, 57, 13, 50, 13, 57, 13, 0, 0, 0, 13, 4, 95, 48, 77, 49, 72, 35, 107, 13, 89, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 2, 95, 51, 47, 123, 50, 13, 0, 0, 9, 2, 95, 50, 72, 36, 49, 13, 0, 0, 8, 2, 95, 49, 36, 49, 13, 0, 0, 0, 9, 2, 95, 55, 107, 35, 47, 13, 0, 0, 9, 2, 95, 54, 107, 35, 57, 13, 0, 0, 9, 2, 95, 53, 48, 35, 107, 13, 0, 0, 11, 2, 95, 52, 107, 35, 47, 13, 34, 13, 0, 0, 16, 2, 95, 59, 47, 6, 37, 47, 49, 4, 39, 65, 118, 84, 13, 0, 0, 0, 11, 2, 95, 57, 50, 35, 84, 13, 57, 13, 0, 0, 8, 2, 95, 56, 35, 140, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 1, 6, 0, 3, 35, 0, 7, 6, 1, 7, 0, 3, 118, 0, 7, 6, 1, 8, 0, 3, 149, 0, 7, 6, 1, 9, 0, 3, 117, 0, 7, 6, 1, 10, 0, 3, 37, 0, 7, 6, 1, 11, 0, 3, 112, 0, 7, 6, 1, 12, 0, 3, 40, 0, 7, 6, 1, 13, 0, 3, 123, 0, 7, 6, 1, 14, 0, 3, 34, 40, 0, 7, 6, 1, 15, 0, 3, 34, 123, 0, 7, 6, 1, 16, 0, 3, 55, 37, 0, 7, 6, 1, 17, 0, 3, 55, 112, 0, 7, 6, 1, 18, 0, 3, 36, 0, 7, 6, 1, 19, 0, 3, 114, 0, 7, 6, 1, 20, 0, 3, 134, 0, 7, 6, 1, 21, 0, 3, 39, 0, 7, 6, 1, 22, 0, 3, 119, 0, 7, 6, 1, 23, 0, 3, 135, 0, 7, 6, 1, 27, 0, 2, 17, 66, 3, 49, 0, 3, 49, 35, 0, 7, 6, 1, 28, 0, 2, 17, 66, 3, 49, 0, 3, 49, 35, 0, 7, 6, 1, 29, 0, 2, 17, 66, 3, 81, 0, 3, 81, 35, 0, 7, 6, 1, 30, 0, 2, 17, 66, 3, 81, 0, 3, 81, 35, 0, 7, 6, 1, 31, 0, 2, 17, 66, 3, 68, 0, 3, 68, 35, 0, 7, 6, 1, 32, 0, 2, 17, 66, 3, 154, 81, 0, 3, 154, 81, 35, 0, 7, 6, 1, 33, 0, 2, 17, 66, 3, 76, 0, 3, 76, 35, 0, 7, 6, 1, 34, 0, 2, 17, 66, 3, 76, 0, 3, 76, 35, 0, 7, 6, 1, 35, 0, 2, 17, 66, 3, 75, 0, 3, 75, 35, 0, 7, 6, 1, 36, 0, 3, 75, 35, 0, 2, 17, 66, 3, 75, 107, 0, 7, 6, 1, 37, 0, 2, 17, 66, 3, 67, 0, 3, 67, 35, 0, 7, 6, 1, 38, 0, 2, 17, 66, 3, 81, 50, 0, 3, 81, 50, 35, 0, 7, 6, 1, 39, 0, 2, 17, 66, 3, 153, 75, 0, 3, 153, 75, 35, 0, 7, 6, 1, 40, 0, 2, 17, 66, 3, 140, 0, 3, 140, 35, 0, 7, 6, 1, 41, 0, 2, 17, 66, 3, 140, 0, 3, 140, 35, 0, 7, 6, 1, 42, 0, 2, 17, 66, 3, 141, 0, 3, 141, 35, 0, 7, 6, 1, 43, 0, 2, 17, 66, 3, 141, 0, 3, 141, 35, 0, 7, 6, 1, 44, 0, 2, 17, 66, 3, 66, 0, 3, 66, 35, 0, 7, 6, 1, 45, 0, 2, 17, 66, 3, 152, 141, 0, 3, 152, 141, 35, 0, 7, 6, 1, 46, 0, 2, 17, 66, 3, 47, 0, 3, 47, 35, 0, 7, 6, 1, 47, 0, 2, 17, 66, 3, 47, 0, 3, 47, 35, 0, 7, 6, 1, 48, 0, 2, 17, 66, 3, 72, 0, 3, 72, 35, 0, 7, 6, 1, 49, 0, 2, 17, 66, 3, 72, 0, 3, 72, 35, 0, 7, 6, 1, 50, 0, 2, 17, 66, 3, 50, 0, 3, 50, 35, 0, 7, 6, 1, 52, 0, 2, 17, 66, 3, 151, 72, 0, 3, 151, 72, 35, 0, 7, 6, 1, 53, 0, 2, 17, 66, 3, 48, 0, 3, 48, 35, 0, 7, 6, 1, 54, 0, 2, 17, 66, 3, 48, 0, 3, 48, 35, 0, 7, 6, 1, 55, 0, 2, 17, 66, 3, 71, 0, 3, 71, 35, 0, 7, 6, 1, 56, 0, 2, 17, 66, 3, 71, 0, 3, 71, 35, 0, 7, 6, 1, 57, 0, 2, 17, 66, 3, 65, 0, 3, 65, 35, 0, 7, 6, 1, 58, 0, 2, 17, 66, 3, 150, 71, 0, 3, 150, 71, 35, 0, 7, 6, 1, 59, 0, 2, 17, 66, 3, 57, 0, 3, 57, 35, 0, 7, 6, 1, 60, 0, 2, 17, 66, 3, 34, 0, 3, 34, 35, 0, 7, 6, 1, 62, 0, 2, 17, 66, 3, 55, 0, 3, 55, 35, 0, 7, 6, 1, 65, 0, 2, 17, 66, 3, 84, 0, 3, 84, 35, 0, 7, 6, 1, 66, 0, 2, 17, 66, 3, 91, 0, 3, 91, 35, 0, 7, 6, 1, 67, 0, 2, 17, 66, 3, 91, 0, 3, 91, 35, 0, 7, 6, 1, 68, 0, 2, 17, 66, 3, 89, 0, 3, 89, 35, 0, 7, 6, 1, 69, 0, 2, 17, 66, 3, 107, 0, 3, 107, 35, 0, 7, 6, 1, 70, 0, 2, 17, 66, 3, 62, 0, 3, 62, 35, 0, 7, 6, 1, 71, 0, 2, 17, 66, 3, 83, 0, 3, 83, 35, 0, 7, 6, 224, 164, 0, 3, 21, 104, 105, 0, 7, 6, 224, 165, 0, 3, 21, 104, 105, 0, 7, 6, 224, 174, 0, 3, 21, 116, 97, 0, 7, 6, 224, 175, 0, 3, 21, 116, 97, 0, 7, 6, 224, 182, 0, 131, 3, 50, 0, 130, 3, 65, 0, 7, 6, 224, 183, 0, 138, 3, 0, 152, 3, 34, 40, 0, 178, 3, 34, 123, 0, 153, 3, 36, 0, 146, 3, 37, 0, 156, 3, 39, 0, 148, 3, 40, 0, 159, 3, 55, 37, 0, 179, 3, 55, 112, 0, 147, 3, 112, 0, 154, 3, 114, 0, 145, 3, 117, 0, 143, 3, 118, 0, 157, 3, 119, 0, 150, 3, 123, 0, 155, 3, 134, 0, 158, 3, 135, 0, 144, 3, 149, 0, 7, 6, 0, 36, 3, 72, 119, 62, 35, 34, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts56 = FileInMemory_createWithData (2454, reinterpret_cast (&espeakdata_dicts56_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/si_dict", U"si"); Collection_addItem (me.peek(), espeakdata_dicts56.transfer()); static unsigned char espeakdata_dicts57_data[8715] = { 0, 4, 0, 0, 105, 18, 0, 0, 0, 10, 135, 197, 190, 9, 1, 4, 14, 9, 20, 0, 0, 0, 0, 6, 65, 4, 124, 0, 14, 5, 193, 4, 72, 8, 0, 0, 0, 0, 11, 136, 26, 18, 21, 196, 141, 14, 195, 173, 20, 6, 65, 8, 71, 123, 0, 0, 0, 0, 14, 139, 22, 197, 161, 5, 20, 5, 196, 141, 14, 195, 173, 20, 0, 6, 65, 12, 117, 123, 0, 0, 0, 18, 4, 95, 8, 1, 3, 89, 10, 65, 6, 36, 49, 76, 36, 67, 39, 65, 0, 0, 0, 6, 65, 16, 72, 123, 0, 0, 0, 0, 0, 5, 65, 20, 123, 0, 0, 0, 0, 7, 196, 80, 145, 84, 60, 20, 0, 6, 65, 24, 36, 83, 0, 0, 0, 0, 0, 6, 65, 28, 81, 123, 0, 0, 0, 0, 0, 6, 65, 32, 107, 124, 0, 0, 0, 0, 11, 1, 35, 49, 51, 121, 90, 37, 49, 0, 27, 0, 5, 65, 36, 121, 0, 0, 0, 13, 1, 38, 35, 65, 48, 36, 51, 89, 35, 50, 72, 0, 0, 0, 6, 65, 40, 57, 123, 0, 0, 0, 12, 1, 42, 107, 84, 37, 36, 88, 72, 35, 0, 27, 0, 9, 1, 43, 48, 55, 40, 89, 0, 27, 0, 7, 65, 44, 49, 124, 0, 14, 6, 65, 44, 49, 0, 28, 0, 0, 0, 12, 137, 12, 15, 7, 9, 19, 20, 195, 173, 11, 20, 0, 6, 65, 48, 36, 55, 0, 0, 0, 0, 7, 196, 32, 241, 14, 36, 20, 0, 7, 132, 9, 14, 195, 173, 20, 6, 65, 52, 36, 65, 0, 0, 0, 0, 0, 6, 65, 56, 36, 50, 0, 0, 0, 0, 0, 6, 65, 60, 125, 0, 14, 9, 65, 60, 39, 10, 0, 72, 28, 23, 0, 16, 141, 16, 18, 5, 19, 22, 5, 4, 196, 141, 5, 14, 195, 173, 20, 12, 1, 61, 51, 39, 84, 50, 124, 89, 35, 0, 27, 0, 0, 0, 11, 1, 64, 88, 35, 84, 37, 50, 124, 76, 0, 6, 65, 64, 48, 123, 0, 0, 0, 0, 0, 7, 65, 68, 49, 84, 123, 0, 0, 0, 6, 195, 36, 226, 84, 20, 0, 0, 6, 65, 72, 36, 51, 0, 0, 0, 0, 0, 15, 140, 21, 11, 18, 9, 197, 190, 15, 22, 1, 14, 195, 173, 20, 7, 65, 76, 36, 89, 0, 14, 7, 65, 76, 89, 10, 0, 8, 0, 7, 195, 36, 224, 75, 72, 8, 0, 0, 7, 196, 80, 82, 148, 60, 20, 0, 6, 65, 80, 47, 123, 0, 0, 0, 9, 134, 16, 5, 11, 14, 195, 173, 20, 0, 0, 5, 65, 84, 126, 0, 0, 12, 137, 22, 195, 161, 197, 190, 5, 14, 195, 173, 20, 0, 13, 138, 19, 195, 186, 196, 141, 1, 19, 14, 195, 173, 20, 0, 0, 7, 65, 88, 84, 123, 0, 14, 7, 65, 88, 84, 10, 0, 28, 0, 0, 0, 14, 4, 95, 49, 77, 52, 71, 6, 37, 55, 37, 125, 50, 0, 0, 15, 65, 92, 72, 84, 6, 39, 57, 37, 47, 123, 4, 84, 123, 0, 0, 0, 0, 16, 1, 95, 47, 84, 44, 72, 124, 65, 6, 36, 118, 36, 51, 35, 0, 0, 13, 4, 95, 49, 77, 49, 115, 6, 37, 89, 121, 117, 0, 7, 65, 96, 37, 49, 89, 0, 0, 14, 4, 95, 49, 77, 50, 65, 6, 37, 55, 37, 125, 50, 0, 0, 16, 4, 95, 49, 77, 51, 65, 6, 37, 55, 57, 35, 51, 72, 35, 0, 0, 0, 11, 65, 100, 37, 48, 89, 37, 55, 39, 50, 0, 0, 0, 0, 0, 8, 65, 104, 88, 36, 47, 0, 14, 7, 65, 104, 88, 10, 0, 28, 0, 0, 0, 0, 0, 0, 9, 134, 13, 195, 161, 14, 9, 1, 20, 0, 0, 7, 132, 15, 14, 195, 173, 20, 0, 0, 9, 134, 13, 195, 161, 14, 9, 5, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 40, 81, 5, 56, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 4, 95, 50, 77, 49, 72, 84, 6, 36, 115, 6, 37, 89, 121, 117, 0, 0, 0, 9, 134, 13, 195, 161, 14, 9, 21, 20, 20, 4, 95, 50, 77, 51, 72, 84, 6, 36, 65, 6, 37, 55, 57, 35, 51, 72, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 137, 22, 195, 173, 14, 5, 196, 141, 11, 15, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 13, 12, 1, 4, 195, 173, 20, 0, 0, 0, 0, 0, 0, 0, 6, 194, 4, 160, 72, 8, 0, 0, 7, 196, 89, 65, 68, 100, 20, 0, 0, 0, 0, 0, 0, 0, 6, 195, 80, 145, 64, 20, 0, 0, 0, 0, 0, 10, 135, 13, 195, 161, 14, 9, 15, 21, 20, 0, 0, 0, 0, 0, 0, 0, 9, 67, 88, 194, 192, 84, 45, 49, 0, 0, 16, 4, 95, 4, 16, 20, 9, 76, 57, 4, 35, 34, 49, 35, 10, 0, 0, 11, 136, 16, 18, 9, 10, 1, 20, 195, 173, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 95, 35, 57, 47, 6, 35, 71, 0, 17, 4, 95, 20, 12, 4, 89, 10, 84, 6, 45, 50, 39, 84, 49, 129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 132, 2, 25, 197, 165, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 135, 11, 1, 197, 190, 4, 5, 10, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 141, 9, 14, 20, 5, 12, 9, 7, 5, 14, 20, 14, 195, 173, 20, 0, 0, 0, 0, 0, 0, 0, 6, 195, 8, 243, 0, 76, 0, 7, 196, 88, 147, 133, 56, 20, 0, 0, 0, 7, 195, 8, 86, 128, 8, 23, 0, 0, 0, 0, 11, 136, 19, 1, 13, 15, 20, 14, 195, 173, 20, 15, 140, 9, 14, 20, 18, 15, 22, 5, 18, 20, 14, 195, 173, 20, 0, 7, 195, 8, 86, 143, 8, 23, 0, 0, 0, 0, 7, 196, 60, 180, 133, 52, 8, 0, 0, 0, 0, 9, 67, 16, 194, 0, 72, 45, 107, 0, 0, 0, 0, 0, 0, 9, 134, 22, 9, 14, 14, 195, 173, 20, 0, 0, 10, 3, 226, 130, 172, 36, 40, 51, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 95, 50, 6, 72, 84, 6, 36, 0, 0, 9, 198, 52, 21, 11, 36, 226, 64, 20, 0, 0, 16, 141, 9, 14, 4, 9, 22, 9, 4, 21, 195, 161, 12, 14, 5, 20, 9, 133, 19, 195, 173, 3, 5, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 4, 95, 13, 3, 14, 89, 10, 65, 6, 35, 49, 51, 39, 50, 39, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 131, 196, 141, 15, 72, 8, 0, 0, 0, 13, 3, 226, 128, 176, 48, 51, 39, 65, 37, 55, 36, 0, 0, 0, 13, 138, 20, 5, 12, 5, 22, 195, 173, 26, 14, 5, 20, 0, 0, 0, 8, 133, 10, 195, 186, 14, 9, 20, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 51, 88, 47, 14, 16, 6, 37, 72, 89, 35, 115, 0, 0, 7, 196, 80, 84, 129, 104, 20, 10, 3, 95, 48, 67, 89, 47, 6, 39, 0, 0, 0, 0, 0, 0, 13, 138, 16, 18, 9, 5, 13, 5, 18, 14, 195, 173, 20, 0, 0, 0, 0, 0, 0, 6, 195, 77, 65, 64, 72, 0, 0, 0, 5, 194, 40, 80, 72, 16, 3, 95, 49, 57, 116, 6, 36, 84, 122, 47, 50, 124, 89, 115, 0, 0, 7, 195, 65, 34, 64, 8, 23, 15, 3, 95, 49, 56, 6, 39, 89, 36, 65, 50, 124, 89, 115, 0, 0, 7, 196, 20, 229, 5, 72, 20, 14, 3, 95, 50, 67, 72, 84, 6, 36, 89, 47, 6, 39, 0, 0, 0, 0, 0, 0, 11, 3, 226, 136, 146, 65, 121, 50, 40, 89, 0, 0, 15, 3, 95, 49, 49, 57, 6, 36, 72, 36, 50, 124, 89, 115, 0, 0, 12, 3, 95, 49, 48, 116, 6, 36, 89, 35, 115, 0, 0, 15, 3, 95, 49, 51, 47, 14, 16, 6, 37, 50, 124, 89, 115, 0, 0, 14, 3, 95, 49, 50, 72, 84, 6, 35, 50, 124, 89, 115, 0, 0, 14, 3, 95, 49, 53, 48, 6, 122, 47, 50, 124, 89, 115, 0, 0, 14, 3, 95, 49, 52, 91, 47, 44, 50, 6, 124, 89, 115, 0, 0, 16, 3, 95, 49, 55, 89, 6, 36, 116, 36, 65, 50, 124, 89, 115, 0, 0, 15, 3, 95, 49, 54, 91, 6, 36, 89, 47, 50, 124, 89, 115, 0, 0, 0, 18, 3, 95, 55, 88, 89, 6, 36, 116, 36, 65, 116, 36, 89, 57, 35, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 16, 12, 197, 165, 48, 45, 115, 0, 0, 0, 9, 134, 195, 173, 4, 5, 15, 21, 20, 0, 6, 195, 52, 145, 9, 20, 0, 0, 0, 0, 0, 0, 0, 0, 24, 11, 16, 15, 19, 20, 9, 8, 14, 21, 20, 195, 173, 48, 39, 89, 115, 37, 107, 50, 40, 47, 121, 0, 0, 14, 3, 95, 50, 88, 72, 84, 6, 35, 72, 89, 35, 115, 0, 0, 0, 0, 17, 5, 95, 48, 77, 65, 51, 65, 6, 37, 55, 57, 35, 51, 72, 37, 0, 0, 16, 5, 95, 48, 77, 65, 50, 65, 6, 37, 55, 37, 125, 50, 37, 0, 0, 0, 16, 5, 95, 48, 77, 65, 52, 71, 6, 37, 55, 37, 125, 50, 37, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 52, 147, 79, 8, 12, 3, 95, 63, 63, 89, 37, 65, 71, 39, 55, 0, 0, 0, 0, 6, 195, 76, 209, 64, 72, 16, 3, 95, 52, 88, 91, 47, 6, 37, 16, 37, 72, 89, 35, 115, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 56, 16, 72, 23, 0, 16, 3, 95, 53, 88, 48, 6, 122, 115, 116, 36, 89, 57, 35, 47, 0, 0, 0, 0, 0, 11, 136, 15, 11, 15, 12, 9, 20, 195, 173, 20, 0, 7, 196, 64, 85, 5, 72, 20, 0, 0, 0, 17, 3, 95, 54, 88, 91, 6, 36, 89, 115, 116, 36, 89, 57, 35, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 6, 195, 169, 14, 9, 24, 20, 0, 17, 3, 95, 56, 88, 6, 39, 89, 36, 65, 116, 36, 89, 57, 35, 47, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 32, 240, 76, 0, 18, 3, 95, 57, 88, 72, 6, 36, 84, 122, 115, 116, 36, 89, 57, 35, 47, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 95, 63, 65, 88, 50, 35, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 4, 95, 15, 7, 15, 89, 10, 6, 39, 81, 39, 67, 49, 39, 65, 0, 0, 0, 8, 197, 52, 20, 148, 36, 224, 20, 0, 0, 0, 0, 11, 136, 15, 19, 20, 1, 20, 14, 195, 173, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 4, 95, 48, 77, 52, 71, 6, 37, 55, 37, 125, 50, 39, 40, 0, 0, 0, 16, 4, 95, 48, 77, 50, 65, 6, 37, 55, 37, 125, 50, 39, 40, 0, 0, 15, 4, 95, 48, 77, 51, 65, 6, 37, 55, 57, 35, 51, 47, 0, 0, 0, 13, 4, 95, 48, 77, 49, 115, 6, 37, 89, 121, 117, 0, 0, 13, 4, 95, 2, 18, 22, 71, 51, 6, 36, 84, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 195, 173, 4, 5, 1, 20, 0, 0, 0, 0, 8, 133, 195, 173, 4, 5, 5, 20, 0, 0, 0, 0, 8, 133, 195, 173, 4, 5, 9, 20, 0, 0, 0, 11, 136, 19, 3, 8, 15, 16, 14, 195, 173, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 195, 173, 4, 5, 21, 20, 0, 0, 0, 0, 8, 133, 195, 173, 4, 5, 25, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 136, 15, 16, 1, 20, 18, 14, 195, 173, 20, 0, 0, 13, 138, 16, 18, 195, 173, 2, 21, 26, 14, 195, 173, 20, 0, 0, 0, 20, 4, 95, 3, 9, 18, 89, 6, 39, 89, 47, 51, 37, 38, 4, 36, 91, 49, 129, 0, 0, 0, 14, 139, 13, 9, 13, 15, 22, 12, 195, 161, 4, 14, 5, 20, 14, 139, 6, 12, 5, 24, 9, 2, 9, 12, 14, 195, 173, 20, 0, 0, 24, 3, 95, 194, 183, 71, 39, 72, 49, 35, 6, 84, 48, 51, 39, 89, 47, 51, 57, 36, 72, 49, 40, 0, 0, 11, 3, 95, 194, 180, 72, 135, 90, 36, 67, 0, 0, 0, 13, 3, 95, 194, 178, 50, 35, 72, 51, 40, 107, 126, 0, 0, 14, 3, 95, 194, 179, 50, 35, 47, 51, 36, 47, 57, 40, 0, 0, 0, 0, 0, 0, 24, 4, 95, 19, 20, 11, 89, 39, 10, 91, 6, 37, 49, 65, 121, 65, 72, 6, 135, 90, 67, 39, 65, 0, 0, 18, 3, 95, 194, 173, 65, 36, 49, 49, 124, 48, 39, 65, 45, 76, 49, 35, 0, 0, 19, 3, 95, 194, 170, 107, 39, 51, 50, 121, 37, 50, 72, 36, 49, 89, 6, 124, 0, 16, 4, 95, 1, 3, 21, 89, 10, 72, 6, 135, 90, 67, 39, 65, 0, 0, 28, 3, 95, 194, 171, 72, 84, 39, 57, 37, 47, 124, 55, 39, 65, 36, 50, 124, 15, 88, 124, 47, 84, 39, 51, 49, 35, 0, 0, 0, 0, 6, 195, 60, 225, 78, 20, 11, 136, 14, 1, 4, 195, 173, 19, 197, 165, 20, 21, 3, 95, 194, 166, 48, 51, 36, 51, 40, 91, 36, 50, 124, 6, 76, 37, 35, 51, 35, 0, 0, 12, 137, 16, 18, 5, 4, 195, 173, 19, 197, 165, 20, 5, 194, 76, 16, 76, 0, 0, 0, 0, 0, 17, 4, 95, 18, 14, 7, 89, 10, 49, 51, 6, 126, 91, 49, 39, 65, 0, 0, 24, 3, 95, 194, 161, 39, 71, 34, 124, 115, 36, 50, 121, 84, 6, 121, 49, 51, 37, 76, 67, 121, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 80, 81, 1, 20, 10, 135, 15, 4, 195, 173, 19, 197, 165, 20, 0, 11, 136, 16, 15, 4, 195, 173, 19, 197, 165, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 3, 95, 194, 191, 39, 71, 51, 124, 115, 36, 50, 121, 6, 39, 47, 124, 88, 67, 37, 49, 0, 0, 0, 0, 0, 28, 3, 95, 194, 187, 72, 84, 39, 57, 37, 47, 124, 55, 39, 65, 36, 50, 124, 15, 88, 35, 47, 84, 39, 51, 37, 115, 0, 0, 12, 3, 95, 194, 184, 117, 36, 72, 37, 55, 35, 0, 0, 12, 3, 95, 194, 185, 50, 35, 48, 51, 84, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 2, 195, 151, 49, 51, 124, 47, 0, 7, 2, 196, 143, 116, 123, 0, 0, 0, 7, 2, 196, 141, 76, 123, 0, 0, 0, 0, 0, 0, 0, 13, 2, 194, 167, 48, 35, 51, 35, 81, 51, 35, 83, 0, 0, 15, 2, 194, 164, 88, 50, 35, 76, 49, 35, 65, 36, 50, 37, 0, 0, 0, 11, 2, 194, 162, 117, 36, 50, 47, 39, 40, 0, 0, 11, 2, 194, 163, 55, 37, 71, 57, 36, 51, 0, 0, 7, 2, 197, 136, 36, 67, 0, 0, 0, 8, 2, 195, 166, 35, 6, 123, 0, 0, 0, 15, 2, 194, 172, 55, 39, 81, 37, 117, 49, 123, 50, 39, 47, 0, 19, 2, 195, 164, 6, 124, 48, 51, 36, 107, 55, 35, 89, 39, 84, 35, 50, 123, 0, 0, 0, 0, 5, 130, 196, 155, 43, 0, 0, 12, 2, 195, 161, 72, 4, 45, 107, 123, 6, 124, 0, 0, 8, 196, 4, 193, 66, 60, 72, 8, 0, 0, 0, 7, 2, 194, 181, 65, 126, 0, 12, 2, 195, 173, 72, 4, 45, 107, 123, 6, 121, 0, 0, 0, 0, 12, 2, 194, 176, 89, 47, 40, 48, 67, 39, 40, 0, 0, 15, 2, 194, 177, 48, 55, 40, 89, 6, 65, 121, 50, 40, 89, 0, 7, 2, 197, 153, 36, 133, 0, 12, 2, 195, 169, 72, 4, 45, 107, 123, 6, 123, 0, 0, 17, 2, 194, 190, 47, 34, 37, 10, 91, 47, 84, 44, 47, 37, 50, 37, 0, 0, 11, 2, 195, 183, 116, 36, 55, 36, 50, 39, 0, 0, 13, 2, 194, 188, 91, 47, 84, 44, 47, 37, 50, 35, 0, 16, 2, 195, 180, 6, 125, 89, 84, 4, 39, 49, 124, 67, 39, 65, 0, 0, 6, 195, 56, 145, 64, 72, 13, 2, 194, 189, 48, 39, 55, 39, 84, 37, 117, 35, 0, 7, 2, 197, 165, 115, 123, 0, 0, 17, 4, 95, 3, 5, 4, 89, 10, 117, 6, 36, 116, 37, 55, 55, 129, 0, 0, 12, 2, 195, 179, 72, 4, 45, 107, 123, 6, 125, 0, 0, 0, 9, 67, 64, 192, 200, 48, 45, 101, 0, 22, 4, 95, 12, 9, 7, 55, 6, 37, 81, 35, 47, 4, 126, 51, 39, 84, 4, 35, 50, 123, 0, 7, 2, 197, 161, 36, 91, 0, 0, 15, 2, 195, 190, 48, 39, 65, 45, 76, 49, 35, 50, 35, 72, 0, 0, 17, 2, 197, 175, 6, 126, 89, 10, 49, 51, 6, 126, 90, 49, 39, 65, 0, 0, 0, 18, 2, 195, 189, 72, 4, 45, 107, 123, 6, 37, 48, 89, 37, 55, 39, 50, 0, 0, 11, 2, 195, 186, 72, 45, 107, 123, 6, 126, 0, 0, 0, 0, 0, 7, 2, 196, 190, 36, 61, 0, 0, 0, 0, 9, 134, 18, 195, 180, 26, 14, 5, 20, 6, 195, 76, 243, 64, 72, 0, 8, 133, 20, 195, 173, 20, 15, 20, 13, 2, 196, 186, 72, 4, 45, 107, 123, 6, 36, 55, 0, 0, 0, 0, 0, 8, 2, 197, 190, 90, 36, 47, 0, 0, 0, 6, 195, 16, 83, 79, 20, 0, 0, 0, 0, 0, 0, 0, 12, 5, 19, 20, 196, 186, 16, 89, 47, 135, 48, 0, 0, 8, 133, 195, 186, 14, 9, 9, 20, 0, 0, 0, 0, 8, 133, 195, 186, 14, 9, 5, 20, 0, 0, 0, 0, 8, 133, 195, 186, 14, 9, 1, 20, 5, 194, 76, 144, 72, 6, 194, 64, 240, 8, 23, 5, 194, 76, 144, 76, 0, 7, 195, 64, 241, 0, 8, 23, 0, 0, 0, 0, 0, 0, 0, 0, 13, 138, 14, 5, 7, 1, 20, 195, 173, 22, 14, 5, 20, 6, 2, 95, 1, 124, 0, 0, 0, 0, 8, 133, 195, 186, 14, 9, 21, 20, 0, 0, 7, 2, 95, 11, 49, 124, 0, 0, 0, 0, 0, 6, 2, 95, 15, 125, 0, 0, 0, 0, 0, 7, 2, 95, 19, 36, 89, 0, 0, 0, 0, 0, 0, 7, 2, 95, 22, 84, 123, 0, 0, 0, 0, 0, 8, 2, 95, 26, 88, 36, 47, 0, 0, 0, 7, 131, 197, 190, 5, 72, 8, 0, 11, 136, 1, 11, 20, 195, 173, 22, 14, 9, 20, 0, 0, 0, 14, 139, 4, 5, 16, 18, 5, 19, 195, 173, 22, 14, 9, 20, 0, 0, 13, 2, 95, 34, 126, 84, 39, 118, 39, 84, 49, 37, 0, 0, 14, 2, 95, 33, 84, 121, 49, 51, 37, 76, 67, 121, 49, 0, 0, 0, 10, 135, 16, 18, 5, 4, 5, 197, 136, 20, 13, 2, 95, 39, 35, 48, 39, 89, 47, 51, 39, 83, 0, 0, 0, 0, 10, 2, 95, 36, 72, 39, 55, 124, 51, 0, 0, 6, 195, 80, 83, 128, 20, 0, 12, 4, 95, 3, 1, 16, 84, 36, 61, 49, 123, 0, 0, 13, 2, 95, 41, 88, 35, 47, 84, 39, 51, 37, 115, 0, 0, 13, 2, 95, 40, 88, 124, 47, 84, 39, 51, 49, 35, 0, 0, 11, 2, 95, 47, 55, 39, 65, 36, 50, 39, 0, 0, 10, 2, 95, 46, 71, 39, 72, 49, 35, 0, 0, 12, 2, 95, 45, 48, 39, 65, 45, 76, 49, 35, 0, 0, 11, 2, 95, 44, 76, 37, 35, 51, 49, 35, 0, 0, 10, 2, 95, 51, 47, 6, 14, 16, 37, 0, 0, 9, 2, 95, 50, 72, 84, 6, 35, 0, 0, 11, 2, 95, 49, 57, 6, 36, 72, 36, 50, 0, 0, 10, 2, 95, 48, 50, 6, 40, 55, 35, 0, 0, 11, 2, 95, 55, 89, 6, 36, 116, 36, 65, 0, 0, 10, 2, 95, 54, 91, 6, 36, 89, 115, 0, 0, 9, 2, 95, 53, 48, 6, 122, 115, 0, 0, 11, 2, 95, 52, 91, 47, 6, 37, 16, 37, 0, 0, 16, 2, 95, 59, 71, 39, 72, 49, 39, 76, 37, 35, 51, 49, 35, 0, 0, 14, 2, 95, 58, 72, 84, 39, 57, 71, 39, 72, 49, 35, 0, 0, 11, 2, 95, 57, 116, 6, 36, 84, 122, 115, 0, 0, 10, 2, 95, 56, 6, 39, 89, 36, 65, 0, 0, 12, 2, 95, 63, 39, 47, 124, 88, 67, 37, 49, 0, 0, 10, 2, 95, 62, 84, 36, 76, 91, 121, 0, 0, 0, 10, 2, 95, 60, 65, 36, 50, 91, 121, 0, 0, 0, 7, 196, 80, 83, 69, 72, 20, 0, 0, 0, 13, 138, 15, 11, 9, 5, 14, 5, 196, 141, 11, 15, 20, 0, 24, 11, 4, 9, 1, 7, 14, 15, 19, 20, 195, 173, 11, 72, 37, 35, 81, 50, 39, 89, 47, 121, 49, 0, 0, 0, 0, 0, 0, 29, 4, 95, 226, 128, 163, 47, 51, 39, 57, 40, 107, 39, 55, 50, 121, 49, 39, 84, 124, 6, 39, 72, 51, 124, 90, 49, 35, 0, 0, 14, 4, 95, 226, 128, 162, 39, 72, 51, 124, 90, 49, 35, 0, 0, 18, 4, 95, 226, 128, 161, 72, 84, 39, 57, 37, 47, 121, 49, 51, 121, 90, 0, 0, 0, 8, 197, 52, 192, 68, 20, 160, 20, 0, 0, 0, 0, 0, 0, 21, 4, 95, 226, 128, 153, 48, 34, 35, 84, 124, 6, 126, 84, 39, 118, 39, 84, 49, 35, 0, 0, 20, 4, 95, 226, 128, 152, 61, 35, 84, 124, 6, 126, 84, 39, 118, 39, 84, 49, 35, 0, 15, 4, 95, 4, 15, 20, 89, 10, 71, 6, 39, 47, 49, 129, 0, 0, 10, 4, 20, 196, 186, 11, 47, 135, 49, 0, 0, 14, 139, 16, 18, 9, 16, 18, 1, 22, 5, 14, 195, 173, 20, 0, 6, 195, 4, 193, 64, 8, 21, 4, 95, 226, 128, 157, 72, 39, 55, 50, 123, 6, 126, 84, 39, 118, 39, 84, 49, 37, 0, 21, 2, 95, 91, 107, 51, 35, 50, 35, 47, 124, 15, 88, 124, 47, 84, 39, 51, 49, 35, 0, 0, 21, 4, 95, 226, 128, 156, 107, 39, 34, 50, 123, 6, 126, 84, 39, 118, 39, 84, 49, 37, 0, 0, 19, 4, 95, 226, 128, 147, 72, 45, 107, 124, 6, 48, 39, 65, 45, 76, 49, 35, 0, 0, 6, 194, 76, 240, 8, 23, 0, 18, 2, 95, 95, 48, 39, 72, 76, 37, 35, 51, 49, 50, 40, 47, 37, 36, 0, 0, 13, 2, 95, 94, 89, 47, 51, 37, 36, 90, 49, 35, 0, 0, 21, 2, 95, 93, 107, 51, 35, 50, 35, 47, 124, 15, 88, 35, 47, 84, 39, 51, 37, 115, 0, 0, 18, 2, 95, 92, 39, 48, 35, 76, 50, 123, 15, 55, 39, 65, 36, 50, 39, 0, 0, 0, 0, 0, 11, 2, 95, 96, 35, 49, 117, 36, 50, 47, 0, 0, 11, 136, 13, 1, 20, 11, 9, 14, 195, 173, 20, 0, 12, 137, 16, 15, 22, 5, 18, 5, 14, 195, 173, 20, 16, 141, 12, 5, 7, 9, 19, 12, 1, 20, 195, 173, 22, 14, 5, 20, 0, 0, 0, 7, 195, 4, 179, 192, 72, 8, 0, 0, 0, 27, 4, 95, 7, 18, 22, 89, 10, 6, 39, 71, 51, 124, 115, 4, 36, 50, 121, 65, 72, 6, 135, 90, 67, 39, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 137, 16, 15, 21, 196, 141, 5, 14, 195, 173, 20, 0, 0, 0, 21, 2, 95, 123, 88, 55, 39, 90, 36, 50, 124, 15, 88, 124, 47, 84, 39, 51, 49, 35, 0, 19, 4, 95, 4, 9, 1, 89, 10, 48, 51, 6, 36, 107, 55, 124, 89, 49, 129, 0, 0, 0, 0, 8, 133, 22, 197, 161, 1, 11, 8, 0, 0, 12, 2, 95, 126, 84, 45, 50, 39, 84, 49, 35, 0, 0, 21, 2, 95, 125, 88, 55, 39, 90, 36, 50, 124, 15, 88, 35, 47, 84, 39, 51, 37, 115, 0, 0, 17, 2, 95, 124, 88, 84, 37, 89, 55, 124, 15, 76, 37, 35, 51, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 131, 19, 195, 186, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 35, 51, 50, 6, 65, 36, 118, 36, 51, 35, 0, 0, 0, 0, 0, 0, 0, 0, 9, 198, 64, 146, 129, 80, 146, 193, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 196, 141, 12, 14, 76, 45, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 77, 97, 84, 21, 32, 20, 0, 0, 0, 0, 0, 6, 131, 20, 195, 173, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 15, 4, 5, 197, 136, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 140, 197, 161, 20, 1, 20, 21, 20, 195, 161, 18, 14, 9, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 9, 4, 5, 195, 173, 20, 0, 0, 0, 0, 12, 137, 16, 15, 197, 190, 9, 1, 18, 14, 5, 20, 0, 0, 9, 134, 16, 15, 4, 5, 197, 136, 20, 0, 15, 140, 4, 5, 6, 9, 14, 9, 20, 195, 173, 22, 14, 5, 20, 0, 0, 6, 116, 101, 0, 4, 1, 97, 105, 2, 32, 3, 47, 36, 0, 1, 97, 105, 118, 97, 122, 0, 1, 101, 100, 2, 107, 0, 1, 101, 100, 2, 114, 109, 0, 1, 101, 109, 2, 114, 32, 0, 1, 110, 105, 2, 114, 0, 1, 110, 105, 2, 114, 110, 101, 0, 1, 115, 2, 114, 0, 1, 115, 2, 114, 32, 0, 1, 115, 161, 195, 110, 2, 32, 0, 1, 118, 2, 100, 97, 106, 197, 161, 0, 1, 120, 101, 2, 114, 0, 2, 104, 111, 32, 0, 2, 106, 32, 0, 2, 109, 97, 116, 105, 0, 2, 114, 97, 106, 197, 161, 0, 2, 114, 97, 122, 0, 2, 114, 109, 0, 2, 115, 32, 0, 2, 115, 116, 0, 2, 120, 0, 8, 2, 99, 104, 0, 8, 2, 100, 97, 106, 197, 161, 0, 8, 2, 108, 101, 99, 0, 8, 2, 108, 101, 102, 0, 8, 2, 108, 101, 103, 0, 8, 2, 108, 101, 107, 0, 8, 2, 108, 101, 109, 0, 8, 2, 108, 101, 111, 0, 8, 2, 108, 101, 112, 0, 8, 2, 108, 101, 114, 0, 8, 2, 108, 101, 115, 101, 110, 0, 8, 2, 108, 101, 115, 107, 0, 8, 2, 108, 101, 116, 101, 114, 0, 8, 2, 108, 101, 116, 101, 120, 116, 0, 8, 2, 108, 101, 118, 0, 8, 2, 108, 101, 120, 0, 8, 2, 109, 112, 0, 8, 2, 110, 100, 0, 8, 2, 110, 105, 115, 0, 8, 2, 110, 116, 111, 0, 8, 2, 111, 0, 8, 2, 114, 97, 112, 0, 8, 2, 114, 97, 115, 0, 8, 2, 114, 101, 122, 0, 8, 2, 114, 195, 169, 110, 0, 8, 2, 114, 195, 169, 122, 0, 8, 2, 114, 196, 141, 0, 8, 2, 120, 0, 8, 2, 195, 179, 0, 8, 97, 107, 2, 99, 104, 0, 8, 97, 107, 2, 100, 0, 8, 97, 107, 2, 103, 0, 8, 97, 109, 2, 109, 97, 116, 105, 0, 8, 97, 109, 2, 114, 105, 97, 0, 8, 97, 109, 2, 114, 105, 195, 161, 0, 8, 97, 112, 2, 110, 116, 0, 8, 97, 114, 116, 115, 2, 103, 0, 8, 101, 100, 2, 107, 116, 195, 173, 0, 8, 101, 108, 101, 116, 2, 114, 0, 8, 101, 112, 109, 111, 107, 2, 110, 0, 8, 101, 161, 197, 118, 2, 196, 141, 0, 8, 105, 104, 99, 114, 97, 2, 107, 0, 8, 105, 108, 2, 114, 0, 8, 107, 97, 114, 97, 104, 99, 2, 114, 0, 8, 107, 97, 114, 97, 104, 99, 2, 114, 0, 8, 108, 97, 2, 114, 0, 8, 108, 97, 2, 114, 110, 0, 8, 108, 97, 2, 114, 110, 97, 116, 195, 173, 118, 0, 8, 108, 97, 119, 2, 114, 0, 8, 110, 105, 2, 108, 0, 8, 110, 105, 2, 110, 0, 8, 110, 105, 101, 100, 0, 8, 110, 121, 115, 0, 8, 110, 121, 115, 2, 116, 105, 0, 8, 111, 104, 2, 108, 0, 8, 111, 112, 2, 110, 0, 8, 112, 101, 115, 2, 109, 98, 0, 8, 115, 2, 112, 0, 8, 115, 97, 112, 0, 8, 115, 105, 115, 97, 2, 110, 0, 8, 115, 105, 120, 101, 2, 110, 0, 8, 115, 121, 115, 2, 109, 0, 8, 169, 195, 2, 114, 0, 7, 6, 195, 161, 0, 3, 124, 0, 7, 6, 195, 164, 0, 3, 36, 0, 7, 6, 195, 169, 0, 3, 123, 0, 7, 6, 195, 173, 0, 3, 121, 0, 7, 6, 195, 179, 0, 3, 125, 0, 7, 6, 195, 180, 0, 3, 40, 39, 0, 7, 6, 195, 186, 0, 3, 126, 0, 7, 6, 195, 189, 0, 3, 121, 0, 7, 6, 196, 141, 0, 3, 76, 0, 7, 6, 196, 143, 0, 2, 32, 3, 115, 0, 4, 3, 116, 0, 2, 32, 17, 70, 0, 7, 6, 196, 186, 0, 3, 135, 0, 7, 6, 196, 190, 0, 3, 61, 0, 7, 6, 197, 136, 0, 3, 67, 0, 7, 6, 197, 149, 0, 3, 132, 0, 7, 6, 197, 153, 0, 3, 133, 0, 4, 1, 102, 3, 134, 0, 1, 107, 0, 1, 112, 0, 1, 116, 0, 7, 6, 197, 161, 0, 3, 91, 0, 7, 6, 197, 165, 0, 3, 115, 0, 7, 6, 197, 190, 0, 4, 3, 90, 0, 2, 32, 17, 70, 0, 2, 32, 3, 91, 0, 7, 6, 97, 0, 3, 35, 0, 7, 6, 98, 0, 101, 122, 111, 8, 2, 45, 14, 128, 132, 133, 3, 6, 71, 36, 88, 39, 0, 101, 122, 8, 2, 45, 14, 128, 132, 132, 3, 6, 71, 36, 89, 0, 2, 32, 3, 48, 0, 4, 3, 71, 0, 2, 32, 17, 70, 0, 7, 6, 99, 0, 104, 3, 101, 0, 3, 117, 0, 7, 6, 100, 0, 2, 32, 3, 47, 0, 4, 3, 72, 0, 1, 97, 2, 101, 0, 1, 97, 114, 116, 2, 105, 0, 1, 101, 109, 2, 105, 0, 1, 101, 114, 107, 2, 105, 0, 1, 101, 114, 107, 115, 105, 100, 2, 105, 0, 1, 105, 2, 101, 110, 0, 1, 105, 2, 101, 111, 0, 1, 110, 97, 109, 2, 105, 116, 0, 1, 110, 105, 2, 105, 0, 1, 111, 2, 105, 99, 0, 1, 111, 2, 105, 107, 0, 1, 111, 108, 101, 109, 2, 105, 0, 1, 111, 109, 2, 101, 114, 0, 1, 114, 111, 2, 105, 0, 1, 169, 195, 109, 2, 105, 0, 1, 179, 195, 108, 101, 109, 2, 105, 0, 2, 32, 17, 70, 0, 2, 101, 28, 17, 0, 2, 101, 99, 105, 0, 2, 101, 102, 0, 2, 101, 116, 101, 107, 0, 2, 101, 116, 101, 114, 109, 0, 2, 105, 28, 17, 0, 2, 105, 99, 107, 0, 2, 105, 100, 97, 107, 116, 105, 0, 2, 105, 102, 0, 2, 105, 107, 32, 0, 2, 105, 107, 116, 0, 2, 105, 111, 0, 2, 105, 114, 0, 2, 105, 115, 107, 114, 101, 0, 2, 105, 115, 107, 117, 0, 2, 105, 115, 112, 0, 2, 105, 115, 116, 0, 2, 105, 115, 116, 105, 99, 0, 2, 105, 122, 109, 117, 115, 0, 2, 105, 195, 179, 0, 2, 195, 173, 28, 17, 0, 8, 2, 101, 99, 101, 0, 8, 2, 101, 102, 105, 110, 105, 116, 195, 173, 118, 0, 8, 2, 101, 105, 110, 116, 101, 0, 8, 2, 101, 107, 111, 114, 0, 8, 2, 101, 107, 114, 101, 109, 101, 110, 116, 0, 8, 2, 101, 107, 114, 195, 169, 116, 0, 8, 2, 101, 107, 195, 161, 100, 0, 8, 2, 101, 107, 195, 179, 114, 0, 8, 2, 101, 108, 101, 103, 0, 8, 2, 101, 108, 105, 109, 0, 8, 2, 101, 112, 114, 101, 115, 0, 8, 2, 101, 115, 105, 103, 0, 8, 2, 101, 115, 116, 105, 0, 8, 2, 101, 116, 97, 105, 108, 0, 8, 2, 101, 116, 101, 107, 116, 195, 173, 0, 8, 2, 101, 118, 105, 122, 0, 8, 2, 101, 118, 195, 173, 122, 0, 8, 2, 101, 122, 0, 8, 2, 105, 97, 0, 8, 2, 105, 101, 99, 0, 8, 2, 105, 101, 116, 0, 8, 2, 105, 102, 116, 195, 173, 110, 0, 8, 2, 105, 103, 0, 8, 2, 105, 109, 101, 110, 0, 8, 2, 105, 112, 0, 8, 2, 105, 115, 0, 8, 2, 105, 115, 107, 0, 8, 2, 105, 118, 195, 173, 122, 0, 8, 2, 105, 195, 161, 0, 8, 2, 105, 195, 169, 0, 8, 97, 107, 2, 101, 116, 0, 8, 97, 110, 2, 195, 173, 100, 0, 8, 97, 110, 2, 195, 173, 196, 143, 0, 8, 97, 114, 2, 105, 107, 195, 161, 108, 0, 8, 97, 114, 116, 2, 195, 173, 0, 8, 97, 116, 161, 197, 2, 105, 0, 8, 101, 2, 105, 116, 0, 8, 101, 102, 2, 101, 114, 0, 8, 101, 112, 120, 101, 2, 105, 0, 8, 101, 114, 112, 2, 105, 122, 98, 0, 8, 101, 114, 112, 2, 105, 197, 161, 0, 8, 101, 114, 112, 2, 195, 173, 100, 0, 8, 101, 114, 112, 2, 195, 173, 196, 143, 0, 8, 105, 2, 101, 97, 0, 8, 105, 2, 101, 110, 116, 105, 0, 8, 105, 2, 101, 195, 161, 0, 8, 105, 2, 105, 108, 0, 8, 105, 2, 105, 111, 0, 8, 105, 108, 97, 118, 110, 105, 2, 105, 116, 0, 8, 105, 108, 97, 118, 110, 105, 2, 105, 122, 0, 8, 105, 118, 2, 101, 97, 0, 8, 105, 118, 2, 101, 111, 0, 8, 105, 118, 2, 101, 117, 0, 8, 105, 118, 101, 2, 101, 110, 0, 8, 105, 122, 101, 114, 112, 2, 101, 110, 116, 0, 8, 110, 97, 104, 2, 105, 0, 8, 110, 97, 107, 115, 2, 105, 0, 8, 110, 101, 112, 105, 116, 161, 197, 2, 105, 0, 8, 110, 105, 2, 101, 120, 0, 8, 110, 111, 112, 161, 197, 101, 114, 111, 107, 2, 101, 110, 0, 8, 111, 2, 105, 110, 0, 8, 111, 2, 105, 115, 0, 8, 111, 2, 105, 197, 161, 0, 8, 111, 2, 195, 173, 196, 143, 0, 8, 111, 107, 2, 105, 102, 105, 0, 8, 111, 109, 2, 101, 108, 0, 8, 111, 109, 2, 101, 109, 0, 8, 111, 109, 2, 105, 0, 8, 111, 112, 2, 195, 173, 100, 0, 8, 111, 112, 2, 195, 173, 196, 143, 0, 8, 111, 116, 101, 109, 2, 105, 0, 8, 114, 97, 100, 110, 97, 116, 161, 197, 2, 105, 122, 0, 8, 117, 97, 2, 105, 0, 8, 117, 97, 2, 105, 0, 8, 117, 116, 161, 197, 2, 101, 110, 0, 8, 117, 116, 161, 197, 2, 105, 0, 8, 161, 195, 116, 161, 197, 2, 105, 0, 8, 186, 195, 116, 161, 197, 2, 105, 0, 4, 197, 190, 3, 75, 0, 197, 190, 2, 32, 17, 70, 0, 197, 190, 2, 32, 3, 76, 0, 4, 2, 101, 3, 116, 0, 2, 105, 0, 2, 195, 173, 0, 122, 2, 32, 3, 117, 0, 4, 122, 3, 118, 0, 122, 2, 32, 17, 70, 0, 7, 6, 101, 0, 3, 36, 0, 7, 6, 102, 0, 3, 83, 0, 7, 6, 103, 0, 2, 32, 3, 49, 0, 4, 3, 81, 0, 2, 32, 17, 70, 0, 7, 6, 104, 0, 2, 32, 3, 101, 0, 4, 3, 107, 0, 2, 32, 17, 70, 0, 7, 6, 105, 0, 97, 3, 2, 37, 35, 0, 101, 3, 2, 37, 36, 0, 117, 3, 2, 37, 40, 0, 3, 37, 0, 7, 6, 106, 0, 3, 57, 0, 7, 6, 107, 0, 3, 49, 0, 7, 6, 108, 0, 1, 25, 2, 25, 3, 45, 0, 3, 55, 0, 7, 6, 109, 0, 3, 65, 0, 7, 6, 110, 0, 97, 8, 2, 45, 14, 128, 132, 131, 3, 6, 50, 35, 0, 4, 3, 50, 0, 1, 17, 67, 21, 2, 101, 106, 32, 0, 1, 97, 2, 105, 109, 0, 1, 97, 103, 114, 111, 2, 105, 122, 0, 1, 97, 109, 2, 105, 0, 1, 97, 118, 122, 2, 101, 106, 32, 0, 1, 100, 97, 105, 114, 2, 101, 0, 1, 101, 103, 2, 101, 0, 1, 101, 108, 111, 118, 2, 195, 173, 0, 1, 103, 97, 109, 2, 101, 0, 1, 104, 99, 2, 105, 99, 0, 1, 104, 99, 2, 105, 107, 0, 1, 105, 2, 105, 99, 105, 0, 1, 108, 161, 195, 2, 105, 0, 1, 108, 161, 195, 105, 99, 111, 115, 2, 101, 0, 1, 108, 161, 195, 109, 114, 111, 102, 2, 101, 0, 1, 111, 2, 105, 99, 0, 1, 111, 2, 105, 107, 0, 1, 111, 2, 105, 115, 0, 1, 111, 102, 2, 105, 99, 0, 1, 111, 103, 2, 105, 0, 1, 111, 103, 97, 116, 2, 105, 115, 0, 1, 111, 109, 114, 97, 104, 2, 105, 0, 1, 111, 114, 2, 105, 99, 0, 1, 111, 114, 2, 105, 107, 0, 1, 111, 114, 100, 110, 101, 2, 105, 0, 1, 111, 114, 116, 2, 105, 0, 1, 114, 101, 116, 110, 105, 2, 101, 0, 1, 116, 161, 195, 116, 161, 197, 2, 101, 32, 0, 1, 117, 109, 2, 105, 107, 0, 1, 117, 109, 2, 105, 115, 0, 1, 118, 161, 195, 114, 112, 115, 2, 101, 0, 1, 118, 173, 195, 116, 97, 110, 2, 101, 0, 1, 122, 180, 195, 114, 2, 101, 0, 1, 169, 195, 114, 116, 2, 105, 0, 1, 173, 195, 108, 2, 105, 0, 1, 179, 195, 102, 2, 105, 0, 1, 179, 195, 103, 2, 105, 0, 1, 179, 195, 109, 114, 97, 104, 2, 105, 0, 2, 101, 28, 17, 0, 2, 101, 104, 111, 32, 0, 2, 101, 110, 116, 0, 2, 105, 28, 17, 0, 2, 105, 115, 116, 0, 2, 105, 122, 109, 117, 115, 32, 0, 2, 195, 173, 28, 17, 0, 8, 2, 101, 103, 0, 8, 2, 101, 103, 97, 116, 195, 173, 118, 0, 8, 2, 101, 103, 195, 161, 99, 0, 8, 2, 101, 111, 107, 108, 97, 115, 0, 8, 2, 101, 111, 112, 114, 195, 169, 110, 0, 8, 2, 101, 111, 114, 101, 0, 8, 2, 101, 114, 118, 0, 8, 2, 101, 117, 116, 114, 195, 161, 108, 0, 8, 2, 101, 120, 116, 0, 8, 2, 101, 195, 179, 110, 0, 8, 2, 105, 107, 111, 116, 0, 8, 97, 104, 99, 101, 109, 2, 105, 0, 8, 97, 112, 2, 101, 108, 0, 8, 97, 116, 111, 98, 2, 105, 0, 8, 100, 97, 105, 190, 197, 2, 101, 0, 8, 100, 122, 161, 195, 114, 112, 2, 101, 0, 8, 101, 2, 101, 114, 103, 0, 8, 101, 98, 2, 101, 102, 0, 8, 101, 103, 2, 105, 0, 8, 101, 109, 2, 101, 197, 190, 0, 8, 101, 114, 2, 101, 115, 0, 8, 101, 116, 2, 105, 115, 0, 8, 103, 105, 115, 2, 105, 0, 8, 104, 99, 101, 116, 2, 105, 0, 8, 105, 102, 101, 100, 2, 105, 116, 195, 173, 118, 0, 8, 105, 102, 101, 100, 2, 195, 173, 99, 0, 8, 105, 107, 116, 97, 109, 2, 101, 0, 8, 105, 108, 2, 101, 0, 8, 105, 109, 2, 105, 0, 8, 105, 109, 100, 97, 2, 105, 115, 116, 0, 8, 108, 161, 195, 101, 114, 2, 101, 0, 8, 108, 161, 195, 105, 99, 101, 112, 161, 197, 2, 101, 0, 8, 108, 161, 195, 110, 111, 115, 114, 101, 112, 2, 101, 0, 8, 108, 161, 195, 117, 116, 107, 97, 2, 101, 0, 8, 110, 105, 118, 2, 101, 0, 8, 111, 102, 2, 101, 0, 8, 111, 108, 111, 107, 2, 105, 0, 8, 111, 109, 2, 105, 0, 8, 114, 186, 195, 116, 108, 117, 107, 2, 101, 0, 8, 116, 114, 97, 112, 2, 101, 114, 0, 8, 116, 115, 101, 105, 109, 2, 101, 0, 8, 116, 161, 195, 116, 161, 197, 2, 101, 0, 8, 116, 169, 195, 114, 107, 110, 111, 107, 2, 101, 0, 8, 117, 2, 105, 0, 8, 117, 109, 2, 105, 0, 8, 117, 109, 105, 2, 105, 0, 8, 117, 109, 111, 107, 2, 105, 0, 8, 117, 116, 2, 105, 115, 0, 8, 118, 173, 195, 116, 97, 114, 116, 115, 105, 110, 105, 109, 100, 97, 2, 101, 0, 8, 169, 195, 103, 2, 105, 0, 8, 169, 195, 114, 116, 2, 101, 114, 0, 8, 179, 195, 108, 111, 107, 2, 105, 0, 8, 190, 197, 161, 195, 118, 2, 101, 0, 4, 2, 101, 3, 67, 0, 2, 105, 0, 2, 195, 173, 0, 4, 2, 103, 3, 68, 0, 2, 107, 0, 7, 6, 111, 0, 3, 39, 0, 117, 3, 129, 0, 7, 6, 112, 0, 111, 8, 2, 45, 14, 128, 132, 131, 3, 6, 48, 39, 0, 111, 100, 8, 2, 45, 14, 128, 132, 132, 3, 6, 48, 39, 47, 0, 114, 105, 8, 2, 45, 14, 128, 132, 132, 3, 6, 48, 51, 37, 0, 3, 48, 0, 111, 118, 8, 2, 115, 116, 97, 17, 67, 3, 48, 39, 83, 0, 7, 6, 113, 0, 3, 49, 0, 117, 3, 49, 84, 0, 7, 6, 114, 0, 1, 25, 2, 25, 3, 44, 0, 4, 3, 51, 0, 114, 0, 7, 6, 115, 0, 111, 8, 2, 45, 14, 128, 132, 131, 3, 6, 89, 39, 0, 3, 89, 0, 7, 6, 116, 0, 4, 3, 47, 0, 1, 97, 2, 105, 99, 107, 0, 1, 97, 2, 105, 107, 195, 161, 0, 1, 97, 2, 105, 110, 0, 1, 97, 2, 105, 122, 0, 1, 97, 104, 99, 2, 105, 99, 0, 1, 97, 104, 99, 2, 105, 107, 0, 1, 97, 109, 2, 105, 99, 107, 0, 1, 97, 109, 2, 105, 107, 0, 1, 97, 109, 97, 2, 105, 99, 0, 1, 97, 109, 97, 2, 105, 107, 0, 1, 97, 109, 101, 2, 105, 0, 1, 97, 109, 101, 116, 2, 105, 0, 1, 101, 2, 105, 99, 0, 1, 101, 2, 105, 107, 0, 1, 101, 108, 112, 109, 111, 107, 2, 105, 122, 0, 1, 105, 2, 105, 99, 0, 1, 105, 2, 105, 107, 0, 1, 105, 108, 2, 105, 99, 0, 1, 107, 97, 2, 105, 0, 1, 107, 97, 2, 105, 107, 0, 1, 107, 97, 100, 105, 100, 2, 105, 0, 1, 107, 101, 2, 105, 0, 1, 107, 101, 2, 195, 173, 0, 1, 107, 114, 2, 105, 0, 1, 110, 2, 105, 99, 0, 1, 110, 2, 105, 110, 0, 1, 110, 97, 2, 105, 0, 1, 110, 101, 2, 105, 110, 0, 1, 110, 101, 118, 2, 105, 108, 0, 1, 111, 2, 105, 99, 0, 1, 111, 2, 105, 107, 0, 1, 111, 109, 2, 105, 118, 0, 1, 111, 114, 2, 105, 99, 0, 1, 111, 114, 2, 105, 107, 0, 1, 112, 101, 2, 105, 99, 0, 1, 112, 101, 2, 105, 107, 0, 1, 112, 111, 2, 105, 0, 1, 114, 97, 112, 2, 105, 0, 1, 115, 2, 105, 99, 0, 1, 115, 97, 2, 105, 99, 0, 1, 115, 101, 114, 112, 2, 105, 197, 190, 0, 1, 115, 101, 118, 110, 105, 2, 105, 0, 1, 115, 111, 2, 105, 99, 0, 1, 189, 195, 2, 105, 99, 0, 2, 101, 28, 17, 0, 2, 105, 28, 17, 0, 2, 105, 99, 107, 0, 2, 105, 107, 32, 0, 2, 105, 110, 103, 0, 2, 105, 115, 116, 0, 2, 105, 122, 109, 117, 115, 32, 0, 2, 195, 173, 28, 17, 0, 8, 2, 101, 114, 101, 115, 116, 114, 105, 0, 8, 2, 105, 109, 111, 116, 101, 106, 0, 8, 2, 105, 114, 97, 110, 0, 8, 2, 105, 116, 97, 110, 0, 8, 2, 105, 116, 117, 108, 0, 8, 97, 109, 101, 116, 97, 109, 2, 105, 0, 8, 97, 109, 111, 116, 117, 97, 2, 105, 0, 8, 97, 112, 97, 2, 105, 0, 8, 97, 112, 105, 116, 110, 97, 2, 105, 0, 8, 97, 115, 2, 105, 114, 0, 8, 97, 115, 2, 105, 115, 0, 8, 97, 116, 161, 197, 2, 105, 0, 8, 101, 109, 114, 101, 104, 2, 105, 0, 8, 101, 109, 122, 111, 107, 2, 105, 0, 8, 101, 110, 103, 97, 109, 2, 105, 0, 8, 101, 110, 111, 102, 2, 105, 0, 8, 101, 114, 107, 110, 111, 107, 2, 105, 122, 0, 8, 101, 116, 110, 121, 115, 2, 105, 0, 8, 105, 114, 107, 2, 105, 99, 0, 8, 105, 114, 107, 2, 105, 107, 0, 8, 105, 114, 107, 2, 105, 122, 0, 8, 105, 115, 110, 101, 115, 2, 105, 0, 8, 107, 97, 2, 105, 118, 0, 8, 107, 117, 100, 111, 114, 112, 2, 105, 0, 8, 108, 117, 107, 2, 105, 0, 8, 108, 117, 109, 2, 105, 0, 8, 110, 97, 2, 105, 0, 8, 110, 97, 108, 116, 97, 2, 105, 0, 8, 110, 101, 99, 2, 105, 0, 8, 110, 101, 100, 105, 2, 105, 0, 8, 110, 101, 118, 101, 114, 112, 2, 195, 173, 118, 0, 8, 110, 111, 107, 2, 105, 0, 8, 111, 97, 104, 99, 2, 105, 99, 0, 8, 111, 97, 104, 99, 2, 105, 107, 0, 8, 111, 107, 105, 110, 2, 105, 0, 8, 111, 120, 101, 2, 105, 0, 8, 114, 101, 99, 2, 105, 0, 8, 114, 101, 118, 2, 105, 0, 8, 115, 2, 105, 109, 117, 108, 0, 8, 115, 98, 97, 2, 105, 0, 8, 115, 101, 100, 2, 105, 0, 8, 115, 105, 108, 97, 98, 2, 105, 0, 8, 115, 105, 114, 101, 116, 107, 97, 114, 97, 104, 99, 2, 105, 0, 8, 115, 105, 114, 101, 116, 107, 97, 114, 97, 104, 99, 2, 195, 173, 107, 0, 8, 115, 105, 116, 97, 116, 161, 197, 2, 105, 0, 8, 115, 110, 105, 2, 105, 0, 8, 115, 110, 111, 107, 2, 105, 0, 8, 115, 111, 110, 103, 97, 105, 100, 2, 105, 0, 8, 115, 117, 106, 2, 105, 0, 8, 117, 101, 99, 97, 109, 114, 97, 102, 2, 105, 0, 8, 117, 112, 2, 105, 107, 0, 8, 120, 101, 116, 2, 105, 108, 0, 8, 161, 197, 2, 105, 112, 101, 110, 100, 105, 0, 8, 161, 197, 101, 114, 2, 105, 0, 8, 161, 197, 110, 105, 2, 105, 0, 8, 161, 197, 110, 105, 101, 100, 2, 105, 0, 8, 161, 197, 110, 111, 107, 2, 105, 0, 4, 195, 173, 1, 97, 2, 118, 3, 47, 121, 0, 195, 173, 1, 105, 2, 118, 0, 195, 173, 1, 107, 101, 112, 115, 2, 118, 0, 195, 173, 1, 111, 109, 2, 118, 0, 195, 173, 1, 114, 111, 2, 109, 0, 195, 173, 1, 115, 101, 108, 97, 2, 116, 0, 195, 173, 1, 117, 110, 107, 105, 118, 0, 195, 173, 8, 2, 109, 111, 118, 0, 195, 173, 8, 97, 103, 101, 110, 2, 118, 0, 195, 173, 8, 97, 110, 114, 101, 116, 108, 97, 2, 118, 0, 195, 173, 8, 102, 105, 100, 2, 110, 0, 195, 173, 8, 105, 100, 117, 97, 2, 118, 0, 195, 173, 8, 105, 110, 105, 102, 101, 100, 2, 118, 0, 195, 173, 8, 105, 115, 110, 101, 115, 0, 195, 173, 8, 107, 97, 2, 118, 0, 195, 173, 8, 107, 101, 116, 101, 100, 0, 195, 173, 8, 107, 117, 100, 111, 114, 112, 2, 118, 0, 195, 173, 8, 107, 117, 114, 116, 161, 197, 110, 111, 107, 2, 118, 0, 195, 173, 8, 115, 101, 108, 97, 112, 0, 195, 173, 8, 115, 117, 106, 0, 4, 2, 101, 3, 115, 0, 2, 105, 0, 2, 195, 173, 0, 7, 6, 117, 0, 3, 40, 0, 7, 6, 118, 0, 121, 8, 2, 21, 14, 128, 132, 130, 3, 6, 84, 37, 0, 1, 17, 65, 2, 25, 3, 58, 0, 4, 3, 84, 0, 1, 17, 65, 2, 108, 25, 0, 1, 17, 65, 2, 110, 0, 1, 17, 65, 2, 196, 186, 0, 1, 17, 65, 2, 197, 136, 0, 7, 6, 119, 0, 1, 17, 65, 2, 25, 3, 58, 0, 4, 3, 84, 0, 104, 2, 12, 0, 7, 6, 120, 0, 3, 49, 89, 0, 7, 6, 121, 0, 3, 37, 0, 7, 6, 122, 0, 4, 3, 88, 0, 2, 32, 17, 70, 0, 2, 32, 3, 89, 0, 7, 6, 0, 196, 155, 3, 36, 0, 37, 1, 32, 15, 3, 48, 36, 51, 117, 36, 50, 47, 0, 37, 3, 48, 36, 51, 117, 36, 50, 47, 39, 0, 36, 3, 72, 39, 55, 124, 51, 0, 197, 175, 3, 126, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts57 = FileInMemory_createWithData (8714, reinterpret_cast (&espeakdata_dicts57_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/sk_dict", U"sk"); Collection_addItem (me.peek(), espeakdata_dicts57.transfer()); static unsigned char espeakdata_dicts58_data[2691] = { 0, 4, 0, 0, 110, 8, 0, 0, 0, 0, 0, 0, 0, 6, 65, 4, 35, 0, 14, 4, 193, 4, 72, 0, 0, 0, 0, 6, 65, 8, 71, 13, 0, 0, 0, 0, 0, 6, 65, 12, 117, 13, 0, 0, 0, 0, 0, 6, 65, 16, 72, 13, 0, 0, 0, 0, 0, 5, 65, 20, 36, 0, 0, 0, 0, 0, 6, 65, 24, 83, 13, 0, 0, 0, 0, 0, 6, 65, 28, 81, 13, 0, 0, 0, 0, 0, 6, 65, 32, 107, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 40, 57, 13, 0, 0, 0, 0, 0, 7, 65, 44, 49, 13, 0, 14, 5, 65, 44, 49, 0, 0, 0, 0, 0, 6, 65, 48, 55, 13, 0, 0, 0, 0, 0, 6, 65, 52, 65, 13, 0, 0, 0, 0, 0, 10, 5, 95, 48, 1, 14, 4, 37, 50, 0, 6, 65, 56, 50, 13, 0, 0, 0, 0, 0, 6, 65, 60, 39, 0, 14, 4, 193, 60, 72, 0, 0, 0, 0, 6, 65, 64, 48, 13, 0, 0, 0, 0, 0, 6, 65, 68, 49, 40, 0, 0, 0, 0, 0, 6, 65, 72, 51, 13, 0, 0, 0, 0, 0, 7, 65, 76, 89, 13, 0, 14, 5, 65, 76, 89, 0, 0, 0, 0, 0, 6, 65, 80, 47, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 65, 88, 84, 13, 0, 14, 6, 65, 88, 58, 0, 23, 0, 0, 0, 18, 4, 95, 49, 77, 52, 6, 36, 50, 71, 37, 55, 37, 57, 6, 39, 50, 0, 0, 14, 65, 92, 72, 84, 6, 39, 57, 50, 37, 84, 4, 13, 0, 0, 0, 0, 0, 13, 4, 95, 49, 77, 49, 47, 6, 37, 89, 39, 76, 0, 7, 65, 96, 37, 49, 89, 0, 0, 18, 4, 95, 49, 77, 50, 6, 36, 50, 65, 37, 55, 37, 57, 6, 39, 50, 0, 0, 21, 4, 95, 49, 77, 51, 6, 36, 50, 35, 65, 37, 55, 37, 57, 6, 35, 51, 72, 35, 0, 0, 0, 12, 65, 100, 6, 37, 48, 89, 37, 55, 39, 50, 0, 0, 0, 0, 0, 7, 65, 104, 88, 13, 0, 14, 6, 65, 104, 88, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 4, 95, 50, 77, 52, 72, 84, 6, 35, 71, 37, 55, 37, 57, 6, 39, 50, 35, 0, 0, 0, 0, 0, 0, 0, 20, 4, 95, 50, 77, 50, 72, 84, 6, 35, 65, 37, 55, 37, 57, 6, 39, 50, 35, 0, 0, 21, 4, 95, 50, 77, 51, 72, 84, 6, 36, 65, 37, 55, 37, 57, 6, 35, 51, 72, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 8, 147, 0, 72, 0, 0, 0, 13, 4, 95, 4, 16, 20, 10, 117, 36, 55, 37, 107, 0, 0, 0, 0, 0, 22, 4, 95, 51, 77, 52, 47, 51, 6, 37, 57, 36, 71, 37, 55, 37, 57, 6, 39, 50, 37, 0, 0, 0, 0, 0, 0, 0, 22, 4, 95, 51, 77, 50, 47, 51, 6, 37, 57, 36, 65, 37, 55, 37, 57, 6, 39, 50, 37, 0, 0, 21, 4, 95, 51, 77, 51, 47, 51, 6, 37, 65, 37, 55, 37, 57, 6, 35, 51, 72, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 51, 88, 47, 51, 6, 37, 72, 36, 89, 36, 47, 0, 0, 9, 3, 95, 48, 67, 89, 47, 39, 0, 0, 0, 0, 6, 195, 77, 64, 64, 72, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 77, 65, 64, 72, 0, 0, 0, 5, 194, 40, 80, 72, 17, 3, 95, 49, 57, 72, 6, 36, 84, 36, 47, 50, 35, 57, 89, 47, 0, 0, 16, 3, 95, 49, 56, 6, 39, 89, 36, 65, 50, 35, 57, 89, 47, 0, 0, 13, 3, 95, 50, 67, 72, 84, 6, 36, 89, 47, 39, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 49, 49, 6, 36, 6, 50, 35, 57, 89, 47, 0, 0, 12, 3, 95, 49, 48, 72, 6, 36, 89, 36, 47, 0, 0, 15, 3, 95, 49, 51, 47, 51, 6, 37, 50, 35, 57, 89, 47, 0, 0, 15, 3, 95, 49, 50, 72, 84, 6, 35, 50, 35, 57, 89, 47, 0, 0, 15, 3, 95, 49, 53, 48, 6, 36, 47, 50, 35, 57, 89, 47, 0, 0, 17, 3, 95, 49, 52, 91, 47, 6, 37, 51, 37, 50, 35, 57, 89, 47, 0, 0, 17, 3, 95, 49, 55, 89, 6, 36, 72, 36, 65, 50, 35, 57, 89, 47, 0, 0, 16, 3, 95, 49, 54, 91, 6, 36, 89, 47, 50, 35, 57, 89, 47, 0, 0, 0, 17, 3, 95, 55, 88, 89, 6, 36, 72, 36, 65, 72, 36, 89, 36, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 50, 88, 72, 84, 6, 35, 57, 89, 36, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 3, 95, 52, 88, 91, 47, 6, 37, 51, 37, 72, 36, 89, 36, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 53, 88, 48, 6, 36, 47, 72, 36, 89, 36, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 54, 88, 91, 6, 36, 89, 47, 72, 36, 89, 36, 47, 0, 0, 0, 0, 0, 6, 195, 76, 83, 64, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 56, 88, 6, 39, 89, 36, 65, 72, 36, 89, 36, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 3, 95, 57, 88, 72, 6, 36, 84, 36, 47, 72, 36, 89, 36, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 4, 95, 48, 77, 52, 71, 37, 55, 37, 57, 6, 39, 50, 39, 58, 0, 0, 0, 17, 4, 95, 48, 77, 50, 65, 37, 55, 37, 57, 6, 39, 50, 39, 58, 0, 0, 16, 4, 95, 48, 77, 51, 65, 37, 55, 37, 57, 6, 35, 51, 72, 0, 0, 0, 13, 4, 95, 48, 77, 49, 47, 6, 37, 89, 39, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 76, 211, 192, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 77, 96, 64, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 8, 147, 1, 72, 0, 14, 2, 196, 135, 65, 6, 36, 107, 49, 37, 76, 4, 13, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 8, 147, 9, 72, 0, 0, 0, 7, 2, 196, 141, 76, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 2, 196, 145, 65, 6, 36, 107, 49, 37, 75, 4, 13, 0, 0, 0, 0, 5, 130, 195, 164, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 130, 195, 171, 43, 0, 0, 0, 5, 130, 195, 182, 43, 0, 0, 0, 0, 0, 0, 0, 7, 2, 197, 161, 91, 13, 0, 0, 0, 0, 5, 130, 195, 188, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 197, 190, 90, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 76, 144, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 95, 11, 49, 13, 0, 0, 0, 0, 0, 6, 2, 95, 15, 39, 0, 0, 0, 0, 0, 7, 2, 95, 19, 89, 13, 0, 0, 0, 0, 0, 0, 7, 2, 95, 22, 84, 13, 0, 0, 0, 0, 0, 7, 2, 95, 26, 88, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 4, 95, 52, 77, 52, 91, 47, 6, 37, 51, 37, 57, 36, 71, 37, 55, 37, 57, 6, 39, 50, 37, 0, 0, 23, 4, 95, 52, 77, 51, 91, 47, 6, 37, 51, 37, 65, 37, 55, 37, 57, 6, 35, 51, 72, 36, 0, 0, 24, 4, 95, 52, 77, 50, 91, 47, 6, 37, 51, 37, 57, 36, 65, 37, 55, 37, 57, 6, 39, 50, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 2, 95, 51, 47, 51, 6, 37, 0, 0, 9, 2, 95, 50, 72, 84, 6, 35, 0, 0, 9, 2, 95, 49, 6, 36, 50, 35, 0, 0, 9, 2, 95, 48, 50, 6, 37, 76, 0, 0, 11, 2, 95, 55, 89, 6, 36, 72, 36, 65, 0, 0, 10, 2, 95, 54, 91, 6, 36, 89, 47, 0, 0, 9, 2, 95, 53, 48, 6, 36, 47, 0, 0, 11, 2, 95, 52, 91, 47, 6, 37, 51, 37, 0, 0, 0, 0, 11, 2, 95, 57, 72, 6, 36, 84, 36, 47, 0, 0, 10, 2, 95, 56, 6, 39, 89, 36, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 76, 240, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 4, 9, 1, 6, 40, 65, 55, 35, 58, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 18, 66, 197, 190, 0, 98, 0, 100, 0, 103, 0, 106, 0, 108, 0, 109, 0, 110, 0, 118, 0, 122, 0, 7, 6, 196, 141, 0, 3, 76, 0, 7, 6, 197, 161, 0, 3, 91, 0, 7, 6, 197, 190, 0, 3, 90, 0, 7, 6, 97, 0, 3, 35, 0, 7, 6, 98, 0, 3, 71, 0, 7, 6, 99, 0, 3, 117, 0, 7, 6, 100, 0, 3, 72, 0, 197, 190, 3, 75, 0, 122, 3, 118, 0, 7, 6, 101, 0, 3, 36, 0, 2, 32, 3, 109, 0, 7, 6, 102, 0, 3, 83, 0, 7, 6, 103, 0, 3, 81, 0, 7, 6, 104, 0, 3, 101, 0, 4, 1, 105, 3, 107, 0, 2, 17, 69, 0, 7, 6, 105, 0, 3, 37, 0, 4, 2, 17, 65, 3, 57, 0, 2, 114, 0, 7, 6, 106, 0, 3, 57, 0, 7, 6, 107, 0, 3, 49, 0, 7, 6, 108, 0, 1, 25, 2, 25, 3, 13, 55, 0, 3, 55, 0, 106, 2, 17, 65, 3, 55, 57, 0, 2, 25, 3, 58, 0, 4, 106, 3, 61, 0, 106, 2, 105, 0, 7, 6, 109, 0, 1, 25, 2, 25, 3, 2, 13, 65, 0, 3, 65, 0, 4, 2, 103, 3, 68, 0, 2, 107, 0, 7, 6, 110, 0, 1, 25, 2, 25, 3, 2, 13, 50, 0, 3, 50, 0, 106, 2, 17, 65, 3, 50, 57, 0, 4, 106, 3, 67, 0, 106, 2, 105, 0, 4, 2, 103, 3, 68, 0, 2, 107, 0, 7, 6, 111, 0, 3, 39, 0, 7, 6, 112, 0, 3, 48, 0, 7, 6, 113, 0, 3, 49, 0, 117, 3, 49, 84, 0, 7, 6, 114, 0, 1, 25, 2, 25, 3, 13, 51, 0, 4, 3, 51, 0, 114, 0, 7, 6, 115, 0, 3, 89, 0, 7, 6, 116, 0, 3, 47, 0, 7, 6, 117, 0, 4, 3, 40, 0, 2, 114, 0, 4, 1, 17, 65, 2, 25, 3, 58, 0, 2, 17, 65, 0, 7, 6, 118, 0, 1, 25, 2, 25, 3, 2, 40, 0, 4, 1, 17, 65, 2, 25, 3, 58, 0, 1, 18, 66, 2, 17, 65, 0, 4, 3, 84, 0, 2, 45, 17, 65, 12, 0, 7, 6, 119, 0, 1, 17, 65, 2, 25, 3, 58, 0, 3, 84, 0, 7, 6, 120, 0, 3, 49, 89, 0, 7, 6, 121, 0, 1, 25, 2, 25, 3, 37, 0, 3, 57, 0, 7, 6, 122, 0, 3, 88, 0, 7, 6, 0, 195, 170, 3, 6, 109, 12, 0, 195, 180, 3, 6, 111, 12, 0, 195, 173, 3, 6, 121, 0, 195, 169, 3, 6, 123, 0, 195, 161, 3, 6, 124, 0, 195, 179, 3, 6, 125, 0, 195, 186, 3, 6, 126, 0, 195, 182, 3, 13, 12, 0, 195, 159, 3, 21, 100, 101, 0, 36, 3, 72, 6, 39, 55, 35, 51, 0, 196, 145, 3, 75, 0, 196, 135, 3, 76, 0, 4, 195, 164, 3, 109, 0, 195, 168, 0, 195, 178, 3, 111, 0, 195, 188, 3, 112, 0, 197, 153, 3, 133, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts58 = FileInMemory_createWithData (2690, reinterpret_cast (&espeakdata_dicts58_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/sl_dict", U"sl"); Collection_addItem (me.peek(), espeakdata_dicts58.transfer()); static unsigned char espeakdata_dicts59_data[3215] = { 0, 4, 0, 0, 114, 9, 0, 0, 0, 0, 0, 0, 0, 9, 67, 53, 80, 74, 65, 40, 118, 0, 0, 0, 0, 0, 6, 65, 8, 71, 13, 0, 0, 0, 0, 0, 6, 65, 12, 124, 13, 0, 0, 0, 0, 0, 6, 65, 16, 72, 13, 0, 0, 0, 0, 0, 6, 65, 20, 36, 0, 14, 5, 193, 20, 76, 28, 0, 0, 0, 0, 6, 65, 24, 83, 13, 0, 0, 0, 0, 0, 6, 65, 28, 81, 13, 0, 0, 0, 0, 0, 6, 65, 32, 107, 13, 0, 0, 15, 1, 33, 48, 37, 49, 76, 40, 72, 6, 37, 124, 113, 0, 27, 0, 0, 7, 1, 35, 107, 35, 91, 0, 0, 17, 65, 36, 37, 10, 124, 6, 37, 64, 37, 0, 81, 99, 105, 108, 105, 32, 4, 193, 36, 76, 0, 13, 1, 37, 48, 13, 76, 37, 50, 72, 57, 35, 0, 27, 0, 7, 1, 38, 10, 86, 113, 0, 0, 0, 6, 65, 40, 57, 13, 0, 0, 0, 8, 1, 42, 116, 123, 37, 0, 27, 0, 9, 1, 43, 48, 123, 40, 89, 0, 27, 0, 6, 65, 44, 49, 13, 0, 0, 0, 8, 1, 46, 48, 37, 49, 0, 27, 0, 12, 1, 47, 48, 57, 6, 113, 89, 47, 37, 65, 0, 0, 6, 65, 48, 55, 13, 0, 0, 0, 0, 0, 6, 65, 52, 65, 13, 0, 0, 0, 0, 13, 68, 53, 80, 74, 36, 65, 6, 40, 118, 38, 37, 0, 0, 10, 5, 95, 48, 1, 14, 4, 2, 113, 0, 6, 65, 56, 50, 13, 0, 0, 0, 0, 0, 0, 13, 1, 61, 71, 35, 51, 35, 71, 6, 35, 51, 47, 0, 0, 0, 0, 9, 1, 64, 65, 35, 50, 49, 37, 0, 6, 65, 64, 48, 13, 0, 0, 0, 0, 0, 6, 65, 68, 80, 13, 0, 0, 0, 0, 0, 6, 65, 72, 51, 13, 0, 0, 0, 7, 195, 16, 129, 64, 76, 8, 0, 0, 6, 65, 76, 89, 13, 0, 0, 0, 0, 0, 6, 65, 80, 47, 13, 0, 0, 0, 0, 0, 4, 193, 84, 76, 0, 0, 0, 0, 6, 65, 88, 84, 13, 0, 0, 0, 0, 8, 133, 10, 1, 14, 195, 171, 76, 0, 6, 65, 92, 58, 13, 0, 0, 9, 133, 14, 195, 171, 19, 5, 76, 8, 0, 16, 1, 94, 89, 6, 37, 51, 49, 40, 65, 83, 123, 113, 49, 89, 0, 0, 0, 6, 65, 96, 125, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 104, 88, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, 126, 47, 37, 55, 72, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 4, 95, 4, 16, 20, 10, 48, 51, 6, 36, 89, 57, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 3, 95, 35, 57, 47, 35, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 66, 16, 128, 86, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 61, 49, 64, 76, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 226, 130, 172, 113, 40, 51, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 44, 16, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 66, 28, 160, 77, 13, 0, 0, 16, 3, 95, 51, 88, 47, 51, 6, 37, 86, 57, 36, 47, 2, 108, 0, 0, 11, 3, 95, 48, 67, 80, 4, 37, 50, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 132, 16, 195, 171, 18, 76, 20, 3, 95, 49, 57, 50, 6, 109, 50, 47, 13, 65, 71, 108, 86, 57, 36, 47, 108, 0, 0, 19, 3, 95, 49, 56, 47, 6, 113, 47, 13, 65, 71, 108, 86, 57, 36, 47, 108, 0, 0, 0, 0, 0, 0, 0, 0, 17, 3, 95, 49, 49, 67, 6, 110, 65, 71, 108, 86, 57, 36, 47, 108, 0, 0, 12, 3, 95, 49, 48, 86, 57, 6, 113, 47, 108, 0, 0, 18, 3, 95, 49, 51, 47, 51, 6, 113, 65, 71, 108, 86, 57, 36, 47, 108, 0, 0, 17, 3, 95, 49, 50, 72, 6, 116, 65, 71, 108, 86, 57, 36, 47, 108, 0, 0, 19, 3, 95, 49, 53, 48, 6, 113, 89, 13, 65, 71, 108, 86, 57, 36, 47, 108, 0, 0, 20, 3, 95, 49, 52, 49, 6, 35, 47, 13, 34, 65, 71, 108, 86, 57, 36, 47, 108, 0, 0, 20, 3, 95, 49, 55, 91, 47, 6, 35, 47, 13, 65, 71, 108, 86, 57, 36, 47, 108, 0, 0, 20, 3, 95, 49, 54, 77, 6, 35, 91, 47, 13, 65, 71, 108, 86, 57, 36, 47, 108, 0, 0, 0, 18, 3, 95, 55, 88, 91, 47, 6, 35, 47, 108, 86, 57, 36, 47, 2, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 50, 88, 67, 6, 110, 88, 113, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 56, 112, 64, 76, 0, 0, 0, 0, 0, 13, 3, 95, 63, 63, 91, 49, 51, 6, 117, 67, 35, 0, 0, 0, 0, 12, 3, 95, 52, 88, 72, 6, 116, 88, 113, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 3, 95, 53, 88, 48, 6, 113, 89, 108, 86, 57, 36, 47, 2, 108, 0, 0, 0, 0, 10, 135, 11, 195, 171, 19, 8, 20, 21, 66, 0, 0, 0, 0, 0, 18, 3, 95, 54, 88, 77, 6, 35, 91, 47, 108, 86, 57, 36, 47, 2, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 3, 95, 56, 88, 47, 6, 113, 47, 108, 86, 57, 36, 47, 2, 108, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 52, 80, 76, 0, 18, 3, 95, 57, 88, 50, 6, 109, 50, 47, 108, 86, 57, 36, 47, 2, 108, 0, 0, 6, 131, 13, 195, 171, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 48, 77, 50, 65, 37, 64, 37, 6, 117, 50, 0, 0, 15, 4, 95, 48, 77, 51, 65, 37, 64, 37, 6, 35, 34, 72, 0, 0, 0, 12, 4, 95, 48, 77, 49, 65, 4, 37, 57, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 131, 14, 195, 171, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 66, 48, 192, 123, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 135, 13, 9, 18, 195, 171, 16, 15, 76, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 66, 56, 160, 67, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 66, 73, 32, 51, 52, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 66, 76, 16, 89, 35, 65, 65, 0, 81, 109, 195, 171, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 76, 80, 76, 0, 0, 8, 196, 76, 146, 213, 72, 76, 8, 0, 0, 0, 0, 0, 7, 2, 195, 167, 76, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 66, 76, 128, 91, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 131, 17, 195, 171, 76, 6, 194, 76, 144, 76, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 2, 95, 1, 35, 0, 0, 0, 0, 0, 6, 2, 95, 5, 36, 0, 0, 0, 0, 6, 2, 95, 9, 37, 0, 0, 7, 66, 80, 128, 87, 13, 0, 0, 6, 2, 95, 15, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 67, 81, 80, 74, 47, 40, 118, 0, 6, 2, 95, 21, 40, 0, 0, 0, 0, 0, 6, 2, 95, 25, 116, 0, 0, 0, 0, 0, 0, 0, 0, 13, 2, 95, 34, 35, 48, 117, 89, 47, 51, 117, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 3, 1, 16, 10, 113, 65, 6, 35, 86, 113, 0, 0, 27, 2, 95, 41, 49, 123, 6, 35, 48, 35, 113, 15, 84, 6, 117, 81, 13, 55, 113, 15, 72, 57, 6, 35, 87, 47, 0, 0, 19, 2, 95, 40, 49, 123, 6, 35, 48, 35, 113, 15, 84, 6, 117, 81, 13, 55, 0, 0, 0, 0, 11, 2, 95, 45, 65, 6, 37, 50, 40, 89, 0, 0, 11, 2, 95, 44, 48, 51, 36, 89, 57, 111, 0, 0, 9, 2, 95, 51, 47, 51, 6, 113, 0, 0, 8, 2, 95, 50, 72, 6, 116, 0, 0, 8, 2, 95, 49, 67, 6, 110, 0, 0, 10, 2, 95, 48, 88, 6, 113, 69, 117, 0, 0, 11, 2, 95, 55, 91, 47, 6, 35, 47, 108, 0, 0, 11, 2, 95, 54, 77, 6, 35, 91, 47, 108, 0, 0, 10, 2, 95, 53, 48, 6, 113, 89, 108, 0, 0, 11, 2, 95, 52, 49, 6, 35, 47, 13, 51, 0, 0, 14, 2, 95, 59, 48, 37, 49, 48, 51, 36, 89, 57, 111, 0, 0, 12, 2, 95, 58, 72, 116, 15, 48, 37, 49, 111, 0, 0, 11, 2, 95, 57, 50, 6, 109, 50, 47, 108, 0, 0, 10, 2, 95, 56, 47, 6, 113, 47, 108, 0, 0, 13, 2, 95, 63, 48, 37, 49, 48, 116, 47, 57, 113, 0, 0, 14, 2, 95, 62, 65, 6, 13, 113, 65, 6, 35, 86, 113, 0, 0, 0, 16, 2, 95, 60, 65, 6, 13, 113, 15, 84, 4, 117, 81, 113, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 2, 95, 91, 49, 123, 6, 35, 48, 35, 113, 15, 65, 6, 35, 86, 113, 0, 0, 0, 0, 0, 14, 2, 95, 95, 50, 4, 109, 50, 15, 84, 6, 37, 88, 0, 0, 0, 26, 2, 95, 93, 49, 123, 6, 35, 48, 35, 113, 15, 65, 6, 35, 86, 113, 113, 15, 72, 57, 6, 35, 87, 47, 0, 0, 17, 2, 95, 92, 84, 37, 88, 113, 65, 118, 47, 87, 6, 121, 89, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 2, 95, 123, 49, 123, 6, 35, 48, 35, 113, 15, 65, 6, 113, 89, 65, 113, 0, 0, 6, 131, 19, 195, 171, 76, 0, 0, 0, 0, 0, 27, 2, 95, 125, 49, 123, 6, 35, 48, 35, 113, 15, 65, 6, 113, 89, 65, 113, 113, 15, 72, 57, 6, 35, 87, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 66, 96, 128, 75, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 95, 35, 51, 50, 89, 48, 119, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 12, 147, 1, 76, 8, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 12, 147, 9, 76, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 131, 20, 195, 171, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 66, 104, 128, 90, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 18, 67, 103, 106, 0, 120, 104, 0, 98, 0, 100, 0, 103, 0, 7, 6, 18, 68, 100, 104, 0, 103, 106, 0, 108, 108, 0, 110, 106, 0, 114, 114, 0, 115, 104, 0, 116, 104, 0, 120, 104, 0, 122, 104, 0, 7, 6, 195, 167, 0, 3, 76, 0, 7, 6, 195, 171, 0, 1, 21, 2, 29, 3, 2, 109, 0, 116, 97, 1, 21, 2, 32, 3, 8, 13, 47, 35, 0, 118, 105, 1, 21, 2, 32, 3, 8, 13, 84, 37, 0, 118, 101, 1, 21, 2, 32, 3, 8, 13, 84, 113, 0, 115, 105, 1, 21, 2, 32, 3, 8, 13, 89, 37, 0, 115, 101, 1, 21, 2, 32, 3, 8, 13, 89, 113, 0, 115, 105, 115, 104, 116, 1, 21, 2, 32, 3, 8, 89, 115, 91, 47, 0, 4, 1, 17, 67, 17, 65, 2, 32, 3, 108, 0, 1, 17, 67, 106, 17, 65, 2, 32, 0, 1, 17, 67, 114, 17, 65, 2, 32, 0, 1, 18, 68, 17, 65, 2, 32, 0, 1, 116, 104, 17, 65, 2, 32, 0, 1, 116, 115, 17, 65, 2, 32, 0, 3, 109, 0, 1, 94, 110, 3, 110, 0, 7, 6, 97, 0, 116, 1, 21, 2, 32, 3, 8, 35, 47, 0, 110, 105, 1, 21, 2, 113, 32, 3, 8, 35, 50, 37, 0, 114, 195, 171, 118, 101, 1, 21, 2, 32, 3, 8, 35, 51, 13, 84, 113, 0, 118, 101, 1, 21, 2, 32, 3, 8, 35, 84, 113, 0, 3, 35, 0, 4, 2, 32, 3, 112, 0, 2, 114, 25, 0, 106, 3, 118, 0, 7, 6, 98, 0, 3, 71, 0, 7, 6, 99, 0, 3, 124, 0, 7, 6, 100, 0, 3, 72, 0, 104, 3, 86, 0, 7, 6, 101, 0, 116, 1, 21, 2, 32, 3, 8, 113, 47, 0, 110, 1, 21, 2, 32, 3, 8, 113, 50, 0, 118, 105, 1, 21, 2, 113, 32, 3, 8, 113, 84, 37, 0, 118, 101, 1, 21, 2, 32, 3, 8, 113, 84, 113, 0, 115, 1, 21, 2, 32, 3, 8, 113, 89, 0, 4, 1, 94, 110, 3, 36, 0, 1, 104, 115, 0, 1, 106, 0, 1, 108, 0, 1, 113, 0, 2, 106, 0, 2, 115, 104, 0, 2, 115, 106, 0, 4, 3, 113, 0, 1, 108, 108, 0, 106, 2, 25, 3, 119, 0, 7, 6, 102, 0, 3, 83, 0, 7, 6, 103, 0, 106, 3, 77, 0, 3, 81, 0, 7, 6, 104, 0, 3, 107, 0, 2, 25, 3, 107, 107, 0, 7, 6, 105, 0, 4, 1, 99, 105, 21, 2, 32, 3, 6, 37, 0, 1, 114, 171, 195, 21, 2, 32, 0, 2, 117, 110, 32, 0, 1, 21, 2, 113, 32, 3, 8, 37, 0, 109, 1, 21, 2, 32, 3, 8, 37, 65, 0, 1, 21, 2, 116, 32, 3, 8, 115, 0, 110, 1, 21, 2, 32, 3, 8, 115, 50, 0, 3, 37, 0, 106, 2, 25, 3, 37, 12, 0, 101, 3, 57, 36, 0, 7, 6, 106, 0, 3, 57, 0, 7, 6, 107, 0, 3, 49, 0, 7, 6, 108, 0, 3, 64, 0, 108, 3, 123, 0, 7, 6, 109, 0, 3, 65, 0, 7, 6, 110, 0, 3, 50, 0, 106, 3, 67, 0, 7, 6, 111, 0, 118, 105, 2, 113, 32, 3, 8, 117, 84, 37, 0, 3, 117, 0, 4, 105, 2, 108, 32, 3, 120, 0, 106, 2, 25, 0, 7, 6, 112, 0, 3, 48, 0, 7, 6, 113, 0, 3, 80, 0, 7, 6, 114, 0, 114, 8, 3, 13, 52, 0, 114, 101, 8, 2, 103, 117, 108, 108, 97, 3, 13, 52, 6, 36, 0, 4, 3, 51, 0, 2, 25, 0, 114, 3, 51, 52, 0, 7, 6, 115, 0, 3, 89, 0, 104, 3, 91, 0, 7, 6, 116, 0, 3, 47, 0, 104, 3, 87, 0, 7, 6, 117, 0, 4, 1, 116, 2, 97, 110, 32, 3, 6, 40, 0, 2, 97, 114, 32, 0, 2, 97, 114, 97, 32, 0, 2, 101, 115, 118, 101, 32, 0, 4, 1, 21, 2, 110, 32, 3, 8, 40, 0, 1, 21, 2, 114, 32, 0, 3, 40, 0, 2, 97, 106, 25, 3, 58, 0, 97, 3, 58, 112, 0, 7, 6, 118, 0, 3, 84, 0, 7, 6, 119, 0, 3, 58, 0, 7, 6, 120, 0, 2, 32, 3, 49, 89, 0, 104, 3, 75, 0, 3, 125, 0, 7, 6, 121, 0, 3, 116, 0, 101, 3, 121, 0, 7, 6, 122, 0, 3, 88, 0, 104, 3, 90, 0, 7, 6, 0, 36, 3, 72, 117, 123, 35, 34, 37, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts59 = FileInMemory_createWithData (3214, reinterpret_cast (&espeakdata_dicts59_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/sq_dict", U"sq"); Collection_addItem (me.peek(), espeakdata_dicts59.transfer()); static unsigned char espeakdata_dicts60_data[9702] = { 0, 4, 0, 0, 211, 17, 0, 0, 10, 69, 25, 32, 77, 21, 48, 21, 0, 10, 0, 0, 11, 70, 32, 80, 68, 36, 225, 211, 21, 0, 10, 0, 9, 67, 52, 83, 128, 65, 111, 50, 0, 10, 67, 32, 243, 128, 107, 125, 50, 0, 72, 0, 0, 5, 65, 4, 122, 0, 0, 0, 0, 0, 6, 65, 8, 71, 110, 0, 0, 11, 70, 9, 35, 215, 76, 84, 128, 21, 0, 10, 0, 18, 70, 28, 83, 69, 57, 48, 77, 57, 111, 65, 6, 110, 50, 89, 35, 65, 0, 12, 67, 21, 64, 192, 110, 47, 110, 89, 6, 110, 0, 0, 0, 6, 65, 12, 89, 110, 0, 0, 0, 12, 4, 95, 8, 1, 3, 107, 6, 122, 49, 112, 0, 0, 0, 6, 65, 16, 72, 110, 0, 0, 0, 10, 67, 76, 147, 128, 89, 109, 50, 0, 76, 0, 6, 195, 76, 147, 129, 76, 0, 5, 65, 20, 110, 0, 0, 0, 0, 0, 6, 65, 24, 111, 83, 0, 0, 0, 0, 0, 6, 65, 28, 81, 110, 0, 0, 0, 11, 67, 44, 19, 128, 49, 6, 35, 50, 0, 72, 0, 0, 6, 65, 32, 107, 124, 0, 0, 0, 0, 0, 7, 65, 36, 108, 0, 72, 28, 5, 65, 36, 108, 0, 0, 0, 0, 0, 6, 65, 40, 57, 108, 0, 0, 0, 0, 0, 6, 65, 44, 49, 124, 0, 0, 0, 0, 0, 6, 65, 48, 111, 55, 0, 0, 15, 1, 49, 83, 6, 119, 93, 47, 112, 0, 82, 58, 32, 101, 32, 15, 1, 49, 83, 6, 119, 93, 47, 35, 0, 82, 58, 32, 97, 32, 0, 14, 1, 50, 35, 50, 72, 51, 35, 0, 82, 58, 32, 97, 32, 0, 15, 1, 51, 47, 51, 110, 72, 57, 112, 0, 82, 58, 32, 101, 32, 0, 15, 1, 52, 83, 57, 113, 51, 72, 112, 0, 82, 58, 32, 101, 32, 6, 65, 52, 111, 65, 0, 0, 14, 1, 53, 83, 111, 65, 47, 112, 0, 82, 58, 32, 101, 32, 0, 14, 1, 54, 127, 111, 47, 12, 112, 0, 82, 58, 32, 101, 32, 0, 14, 1, 55, 127, 120, 50, 72, 112, 0, 82, 58, 32, 101, 32, 0, 15, 69, 81, 33, 68, 40, 80, 47, 51, 6, 110, 72, 57, 112, 0, 16, 1, 56, 123, 47, 12, 123, 50, 72, 112, 0, 82, 58, 32, 101, 32, 6, 65, 56, 111, 50, 0, 0, 15, 1, 57, 50, 108, 123, 50, 72, 112, 0, 82, 58, 32, 101, 32, 0, 0, 0, 0, 0, 0, 0, 6, 65, 64, 48, 110, 0, 0, 11, 70, 64, 20, 211, 92, 244, 132, 21, 0, 10, 0, 9, 67, 76, 145, 192, 89, 111, 57, 0, 0, 0, 6, 65, 68, 49, 117, 0, 0, 8, 67, 80, 130, 83, 21, 0, 10, 0, 0, 0, 6, 65, 72, 111, 51, 0, 0, 11, 70, 52, 246, 137, 48, 192, 64, 21, 0, 10, 0, 0, 0, 6, 65, 76, 111, 89, 0, 0, 0, 10, 67, 48, 241, 192, 55, 6, 126, 81, 0, 0, 0, 6, 65, 80, 47, 110, 0, 0, 0, 0, 0, 0, 0, 0, 9, 68, 80, 16, 140, 20, 21, 0, 10, 9, 68, 48, 147, 139, 76, 21, 0, 10, 0, 14, 69, 8, 20, 143, 12, 176, 71, 35, 51, 6, 123, 49, 0, 6, 65, 88, 84, 110, 0, 0, 0, 0, 0, 12, 65, 92, 72, 6, 120, 71, 13, 55, 84, 110, 0, 0, 0, 0, 0, 7, 65, 96, 111, 49, 89, 0, 0, 14, 4, 95, 49, 77, 50, 65, 109, 55, 57, 6, 126, 50, 0, 0, 14, 4, 95, 49, 77, 51, 71, 109, 55, 57, 6, 126, 50, 0, 0, 21, 72, 80, 244, 147, 16, 17, 197, 57, 48, 47, 6, 126, 91, 72, 122, 81, 111, 50, 89, 0, 0, 5, 65, 100, 115, 0, 0, 16, 70, 77, 84, 193, 56, 224, 64, 89, 120, 89, 6, 35, 50, 35, 0, 0, 0, 0, 9, 65, 104, 89, 6, 113, 47, 35, 0, 0, 0, 11, 67, 20, 211, 212, 111, 65, 6, 126, 47, 0, 0, 0, 0, 15, 70, 77, 84, 193, 56, 225, 64, 89, 120, 89, 6, 35, 50, 0, 9, 198, 9, 37, 75, 4, 65, 64, 72, 0, 7, 195, 5, 69, 0, 72, 8, 0, 0, 0, 16, 70, 80, 244, 147, 16, 17, 192, 47, 6, 126, 91, 72, 122, 81, 0, 11, 66, 12, 16, 89, 6, 109, 51, 49, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 6, 14, 195, 165, 7, 18, 1, 50, 6, 124, 81, 51, 35, 0, 72, 0, 9, 68, 25, 32, 77, 20, 21, 0, 10, 0, 14, 69, 8, 245, 20, 20, 224, 71, 6, 123, 47, 111, 50, 0, 0, 0, 20, 71, 28, 83, 69, 57, 48, 77, 80, 57, 111, 65, 6, 110, 50, 89, 35, 65, 47, 0, 0, 0, 0, 11, 67, 80, 241, 211, 47, 6, 126, 81, 89, 0, 0, 0, 0, 0, 0, 0, 12, 68, 17, 81, 197, 72, 72, 117, 81, 111, 51, 0, 0, 0, 8, 66, 5, 96, 122, 84, 0, 72, 5, 194, 5, 96, 72, 0, 0, 0, 0, 0, 0, 11, 67, 32, 17, 5, 107, 35, 72, 111, 0, 72, 0, 0, 0, 0, 7, 196, 84, 225, 5, 72, 28, 0, 0, 0, 9, 67, 8, 85, 0, 71, 110, 47, 0, 7, 195, 80, 147, 12, 72, 28, 0, 12, 68, 4, 225, 1, 76, 35, 50, 72, 35, 89, 0, 0, 0, 0, 10, 67, 29, 33, 80, 81, 51, 110, 48, 0, 0, 0, 10, 69, 9, 85, 20, 60, 224, 21, 0, 10, 0, 0, 0, 9, 67, 4, 227, 133, 35, 50, 50, 0, 0, 0, 0, 0, 12, 68, 77, 67, 210, 80, 89, 47, 126, 51, 47, 0, 12, 68, 76, 17, 5, 76, 89, 122, 72, 111, 89, 0, 0, 17, 70, 80, 244, 147, 16, 17, 211, 47, 6, 126, 91, 72, 35, 81, 89, 0, 0, 0, 0, 14, 5, 21, 19, 1, 58, 19, 117, 111, 89, 6, 122, 89, 0, 13, 68, 72, 17, 5, 56, 51, 122, 72, 2, 111, 50, 0, 0, 0, 0, 0, 0, 10, 69, 72, 80, 68, 21, 32, 21, 0, 10, 0, 0, 0, 12, 68, 32, 243, 143, 52, 107, 123, 50, 123, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 52, 81, 1, 56, 8, 0, 0, 0, 0, 0, 0, 0, 6, 195, 16, 149, 20, 76, 0, 0, 0, 0, 8, 67, 72, 80, 68, 21, 0, 10, 10, 67, 76, 176, 64, 89, 49, 122, 0, 72, 10, 67, 76, 176, 64, 89, 49, 122, 0, 72, 0, 0, 0, 0, 0, 10, 67, 36, 227, 205, 109, 50, 123, 65, 0, 0, 10, 67, 20, 113, 78, 110, 81, 111, 50, 0, 0, 5, 194, 21, 32, 76, 0, 0, 0, 0, 0, 10, 67, 21, 37, 0, 110, 51, 47, 0, 76, 0, 10, 67, 4, 225, 197, 35, 50, 57, 110, 0, 7, 196, 28, 83, 143, 52, 28, 0, 0, 5, 194, 16, 80, 72, 0, 0, 7, 196, 88, 147, 12, 20, 72, 0, 0, 0, 10, 67, 16, 85, 0, 72, 110, 47, 0, 72, 0, 13, 68, 72, 17, 5, 72, 51, 122, 72, 2, 111, 51, 0, 13, 4, 95, 4, 16, 20, 48, 6, 120, 68, 49, 47, 0, 0, 0, 5, 194, 17, 80, 72, 0, 9, 67, 88, 83, 64, 84, 111, 65, 0, 9, 67, 24, 83, 64, 83, 111, 65, 0, 0, 0, 0, 17, 70, 65, 35, 199, 72, 19, 64, 48, 51, 125, 81, 51, 6, 35, 65, 0, 0, 8, 133, 195, 182, 22, 5, 18, 28, 0, 0, 0, 0, 16, 7, 6, 18, 1, 13, 195, 165, 20, 83, 51, 35, 65, 123, 47, 0, 0, 13, 4, 95, 20, 12, 4, 47, 6, 109, 55, 72, 112, 0, 9, 3, 95, 35, 57, 47, 35, 71, 0, 0, 0, 0, 0, 10, 67, 4, 228, 197, 35, 50, 89, 110, 0, 0, 0, 0, 0, 0, 0, 0, 9, 67, 21, 69, 0, 6, 111, 47, 0, 6, 195, 21, 69, 0, 72, 0, 0, 8, 197, 9, 37, 75, 5, 32, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 67, 61, 32, 193, 123, 51, 49, 35, 0, 0, 0, 8, 67, 48, 147, 139, 21, 0, 10, 0, 0, 0, 0, 7, 196, 36, 227, 129, 56, 28, 0, 0, 0, 0, 12, 68, 29, 33, 80, 76, 81, 51, 110, 48, 89, 0, 0, 0, 0, 0, 0, 0, 7, 66, 32, 16, 107, 122, 0, 0, 0, 0, 0, 0, 0, 11, 70, 12, 129, 67, 44, 81, 0, 21, 0, 10, 0, 14, 69, 25, 32, 77, 52, 80, 83, 51, 6, 35, 65, 111, 0, 0, 10, 67, 20, 115, 129, 110, 81, 50, 35, 0, 6, 195, 16, 147, 129, 76, 0, 10, 67, 16, 147, 128, 72, 109, 50, 0, 76, 10, 67, 32, 19, 128, 107, 35, 50, 0, 72, 0, 0, 0, 0, 9, 67, 16, 19, 128, 72, 122, 50, 0, 0, 0, 0, 0, 9, 67, 64, 20, 128, 48, 122, 51, 0, 10, 67, 32, 20, 128, 107, 122, 51, 0, 72, 6, 195, 32, 20, 128, 72, 0, 8, 196, 20, 195, 5, 72, 72, 8, 0, 11, 70, 76, 241, 148, 92, 20, 133, 21, 0, 10, 10, 69, 12, 19, 131, 20, 192, 21, 0, 10, 0, 0, 9, 67, 80, 20, 128, 47, 122, 51, 0, 0, 0, 0, 0, 0, 6, 195, 32, 19, 147, 76, 0, 0, 0, 0, 0, 16, 69, 8, 85, 1, 49, 64, 71, 6, 111, 47, 6, 122, 55, 47, 0, 0, 0, 0, 12, 68, 76, 243, 133, 56, 89, 124, 50, 111, 50, 0, 13, 68, 5, 34, 201, 88, 6, 35, 51, 49, 108, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 6, 2, 195, 164, 19, 20, 5, 71, 6, 111, 89, 47, 111, 0, 0, 0, 0, 0, 0, 13, 67, 57, 97, 1, 111, 50, 84, 110, 72, 110, 122, 0, 0, 9, 67, 16, 145, 192, 72, 111, 57, 0, 0, 0, 0, 8, 67, 64, 17, 197, 21, 0, 10, 0, 0, 0, 0, 7, 66, 40, 16, 57, 122, 0, 0, 0, 0, 0, 0, 0, 14, 68, 8, 244, 132, 20, 71, 6, 126, 51, 72, 111, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 10, 67, 16, 17, 211, 72, 35, 49, 89, 0, 0, 8, 197, 32, 83, 142, 21, 48, 76, 0, 0, 8, 67, 32, 20, 192, 21, 0, 10, 0, 0, 14, 69, 77, 64, 68, 20, 224, 89, 47, 122, 72, 111, 50, 0, 0, 0, 9, 67, 80, 20, 192, 47, 122, 89, 0, 0, 13, 68, 16, 84, 129, 76, 72, 110, 51, 35, 89, 0, 76, 0, 0, 13, 4, 95, 13, 3, 14, 89, 47, 51, 6, 111, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 67, 44, 192, 83, 49, 55, 122, 89, 0, 0, 8, 67, 16, 245, 0, 21, 0, 10, 10, 67, 44, 192, 82, 49, 55, 122, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 66, 20, 224, 111, 50, 0, 72, 0, 10, 67, 77, 64, 68, 89, 47, 122, 72, 0, 12, 3, 95, 51, 88, 47, 51, 6, 111, 47, 109, 0, 0, 13, 3, 95, 48, 67, 107, 6, 120, 50, 72, 51, 35, 0, 0, 0, 0, 9, 67, 17, 32, 64, 72, 51, 122, 0, 0, 0, 0, 0, 0, 0, 10, 67, 77, 64, 78, 89, 47, 122, 50, 0, 0, 0, 0, 0, 0, 12, 3, 95, 49, 57, 50, 6, 109, 47, 123, 50, 0, 0, 12, 3, 95, 49, 56, 6, 122, 51, 47, 123, 50, 0, 0, 0, 0, 0, 0, 10, 67, 17, 32, 83, 72, 51, 122, 89, 0, 0, 10, 67, 17, 32, 82, 72, 51, 122, 51, 0, 0, 11, 3, 95, 49, 49, 6, 111, 55, 84, 35, 0, 0, 11, 3, 95, 49, 48, 47, 6, 108, 38, 126, 0, 0, 9, 68, 48, 85, 133, 48, 21, 0, 10, 13, 3, 95, 49, 51, 47, 51, 6, 111, 47, 123, 50, 0, 0, 11, 3, 95, 49, 50, 47, 6, 123, 55, 84, 0, 0, 13, 3, 95, 49, 53, 83, 6, 111, 65, 47, 123, 50, 0, 0, 14, 3, 95, 49, 52, 83, 57, 6, 126, 51, 47, 123, 50, 0, 0, 12, 3, 95, 49, 55, 127, 6, 120, 47, 123, 50, 0, 0, 14, 3, 95, 49, 54, 89, 6, 111, 49, 89, 47, 123, 50, 0, 0, 0, 11, 3, 95, 55, 88, 127, 6, 120, 47, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 20, 101, 5, 72, 28, 0, 9, 67, 52, 21, 0, 65, 122, 47, 0, 0, 0, 0, 0, 15, 2, 49, 49, 111, 55, 83, 47, 112, 0, 82, 58, 32, 101, 32, 0, 16, 2, 49, 48, 47, 108, 123, 50, 72, 112, 0, 82, 58, 32, 101, 32, 0, 11, 3, 95, 50, 88, 97, 6, 117, 81, 123, 0, 0, 16, 2, 49, 50, 47, 123, 55, 83, 47, 112, 0, 82, 58, 32, 101, 32, 0, 0, 8, 67, 81, 32, 89, 21, 0, 10, 0, 10, 67, 8, 245, 20, 71, 6, 125, 47, 0, 0, 0, 0, 0, 0, 0, 10, 69, 76, 52, 133, 20, 224, 21, 0, 10, 0, 0, 0, 15, 3, 95, 63, 63, 89, 6, 116, 65, 71, 126, 55, 112, 50, 0, 0, 0, 11, 70, 12, 243, 21, 52, 228, 192, 21, 0, 10, 0, 15, 5, 6, 18, 195, 165, 14, 83, 51, 6, 124, 50, 0, 72, 28, 12, 3, 95, 52, 88, 83, 6, 119, 51, 47, 109, 0, 0, 0, 9, 3, 195, 164, 14, 111, 50, 0, 72, 0, 0, 0, 0, 0, 0, 12, 3, 95, 53, 88, 83, 6, 111, 65, 47, 109, 0, 0, 0, 0, 0, 0, 0, 10, 69, 60, 97, 137, 12, 80, 21, 0, 10, 0, 0, 13, 3, 95, 54, 88, 89, 6, 111, 49, 89, 47, 109, 0, 0, 0, 0, 7, 132, 22, 195, 165, 18, 76, 0, 6, 195, 52, 149, 20, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 67, 52, 18, 76, 21, 0, 10, 10, 3, 95, 56, 88, 6, 123, 47, 109, 0, 0, 0, 0, 0, 0, 0, 7, 195, 52, 81, 0, 72, 28, 0, 0, 11, 3, 95, 57, 88, 50, 6, 109, 47, 109, 0, 0, 0, 14, 69, 29, 34, 80, 56, 16, 81, 51, 108, 48, 50, 35, 0, 0, 0, 0, 0, 10, 3, 195, 164, 18, 6, 113, 51, 0, 72, 0, 16, 3, 95, 63, 65, 71, 6, 126, 49, 89, 47, 35, 84, 112, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 66, 36, 224, 109, 50, 0, 0, 8, 67, 92, 80, 128, 21, 0, 10, 0, 0, 0, 0, 13, 4, 95, 15, 7, 15, 89, 84, 6, 35, 50, 89, 0, 0, 0, 15, 69, 76, 179, 204, 4, 224, 89, 49, 6, 126, 55, 35, 50, 0, 17, 7, 13, 195, 165, 19, 20, 5, 14, 65, 6, 123, 89, 47, 13, 50, 0, 0, 0, 12, 71, 52, 144, 210, 61, 51, 198, 80, 21, 0, 10, 10, 67, 76, 83, 148, 89, 110, 50, 47, 0, 0, 9, 68, 36, 208, 71, 20, 21, 0, 10, 0, 10, 67, 77, 67, 210, 89, 47, 126, 51, 0, 0, 0, 0, 11, 67, 60, 50, 0, 6, 123, 49, 0, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 67, 52, 147, 128, 65, 109, 50, 0, 76, 0, 6, 195, 52, 147, 129, 76, 0, 0, 16, 4, 95, 48, 77, 50, 65, 109, 55, 57, 6, 126, 50, 111, 51, 0, 0, 9, 67, 61, 53, 0, 125, 89, 47, 0, 10, 67, 52, 19, 128, 65, 35, 50, 0, 72, 16, 4, 95, 48, 77, 51, 71, 109, 55, 57, 6, 126, 50, 111, 51, 0, 0, 0, 13, 4, 95, 48, 77, 49, 47, 6, 117, 89, 111, 50, 0, 0, 14, 4, 95, 2, 18, 22, 71, 51, 6, 110, 84, 108, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 67, 8, 244, 148, 71, 123, 51, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 66, 60, 96, 21, 0, 10, 7, 132, 2, 195, 182, 18, 72, 8, 132, 6, 195, 182, 18, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 67, 52, 145, 192, 65, 111, 57, 0, 0, 0, 0, 0, 8, 67, 60, 225, 64, 21, 0, 10, 0, 0, 0, 11, 70, 77, 80, 141, 20, 229, 64, 21, 0, 10, 5, 194, 56, 144, 72, 0, 9, 67, 72, 17, 0, 51, 122, 72, 0, 0, 0, 11, 70, 16, 84, 203, 80, 244, 0, 21, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 4, 95, 3, 9, 18, 89, 6, 109, 51, 49, 120, 65, 83, 55, 111, 49, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 8, 4, 195, 164, 18, 6, 195, 182, 18, 72, 6, 111, 51, 83, 118, 51, 0, 0, 0, 0, 0, 11, 70, 29, 32, 80, 32, 144, 192, 21, 0, 10, 0, 8, 67, 72, 245, 192, 21, 0, 10, 17, 4, 95, 19, 20, 11, 89, 50, 6, 110, 72, 89, 47, 51, 112, 49, 0, 0, 0, 12, 4, 95, 1, 3, 21, 6, 122, 49, 117, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 95, 18, 14, 7, 51, 6, 109, 68, 0, 0, 6, 131, 95, 195, 169, 43, 0, 11, 70, 29, 32, 80, 32, 144, 211, 21, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 21, 32, 64, 76, 0, 0, 17, 7, 20, 25, 22, 195, 164, 18, 18, 47, 2, 116, 84, 6, 113, 51, 0, 11, 67, 21, 32, 78, 113, 51, 35, 50, 0, 76, 0, 0, 10, 67, 88, 19, 20, 84, 122, 55, 47, 0, 0, 0, 0, 18, 4, 95, 1, 3, 50, 72, 6, 120, 71, 112, 55, 6, 122, 49, 117, 47, 0, 0, 0, 0, 9, 134, 12, 195, 164, 14, 7, 19, 28, 0, 7, 66, 80, 16, 47, 122, 0, 0, 11, 67, 21, 32, 84, 113, 51, 35, 47, 0, 76, 0, 0, 10, 67, 45, 96, 82, 49, 84, 122, 51, 0, 0, 0, 6, 195, 88, 147, 12, 72, 7, 195, 52, 245, 0, 72, 28, 0, 0, 0, 8, 67, 72, 245, 211, 21, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 69, 12, 243, 21, 52, 224, 21, 0, 10, 0, 0, 0, 10, 67, 32, 85, 1, 107, 110, 47, 35, 0, 0, 0, 0, 10, 67, 32, 83, 20, 107, 110, 55, 47, 0, 0, 0, 0, 7, 66, 56, 240, 21, 0, 10, 6, 194, 60, 208, 72, 8, 6, 194, 60, 208, 72, 28, 0, 0, 11, 67, 76, 86, 0, 89, 6, 111, 49, 89, 0, 12, 68, 4, 225, 197, 76, 35, 50, 57, 110, 89, 0, 0, 10, 67, 77, 96, 82, 89, 84, 122, 51, 0, 0, 0, 0, 12, 68, 4, 225, 197, 72, 35, 50, 57, 110, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 131, 16, 195, 165, 72, 0, 0, 0, 0, 9, 68, 4, 67, 194, 20, 21, 0, 10, 0, 0, 0, 9, 67, 60, 229, 0, 125, 50, 47, 0, 0, 0, 0, 0, 0, 14, 4, 95, 3, 5, 4, 89, 6, 110, 72, 109, 55, 57, 0, 0, 0, 0, 16, 4, 95, 12, 9, 7, 55, 6, 108, 81, 35, 47, 4, 117, 51, 0, 0, 0, 0, 0, 10, 67, 88, 17, 0, 84, 122, 72, 0, 72, 0, 0, 0, 0, 0, 0, 0, 20, 8, 13, 15, 14, 5, 20, 195, 164, 18, 65, 4, 123, 50, 111, 47, 6, 113, 51, 0, 8, 133, 22, 195, 165, 18, 1, 76, 0, 7, 195, 76, 243, 64, 72, 8, 0, 8, 67, 56, 19, 69, 21, 0, 10, 0, 10, 69, 80, 16, 140, 21, 48, 21, 0, 10, 0, 0, 9, 67, 16, 83, 64, 72, 111, 65, 0, 0, 0, 14, 69, 4, 225, 18, 5, 48, 35, 50, 72, 51, 35, 89, 0, 0, 0, 0, 0, 8, 133, 22, 195, 165, 18, 20, 76, 0, 0, 0, 0, 0, 0, 0, 13, 72, 84, 228, 197, 48, 80, 212, 20, 64, 21, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 45, 83, 132, 20, 72, 0, 0, 0, 0, 0, 0, 8, 67, 88, 145, 87, 21, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 67, 85, 48, 64, 117, 111, 89, 6, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 67, 32, 82, 128, 107, 111, 57, 0, 0, 0, 8, 197, 76, 181, 76, 48, 80, 72, 0, 0, 0, 0, 0, 0, 9, 67, 76, 243, 128, 89, 124, 50, 0, 9, 67, 40, 19, 128, 57, 122, 50, 0, 0, 0, 0, 0, 10, 67, 16, 83, 128, 72, 111, 50, 0, 72, 0, 9, 68, 20, 208, 73, 48, 21, 0, 10, 13, 4, 95, 3, 1, 16, 89, 47, 6, 126, 51, 47, 0, 0, 0, 11, 67, 88, 20, 133, 84, 122, 51, 111, 0, 72, 0, 8, 67, 92, 244, 132, 21, 0, 10, 9, 67, 64, 84, 128, 48, 113, 51, 0, 0, 11, 2, 95, 46, 48, 6, 120, 68, 49, 47, 0, 0, 0, 0, 10, 67, 88, 20, 128, 84, 122, 51, 0, 72, 9, 67, 24, 20, 128, 83, 122, 51, 0, 10, 67, 88, 20, 128, 84, 122, 51, 0, 72, 9, 2, 95, 51, 47, 51, 6, 110, 0, 0, 9, 2, 95, 50, 47, 84, 6, 124, 0, 0, 8, 2, 95, 49, 6, 111, 47, 0, 0, 9, 2, 95, 48, 50, 6, 123, 55, 0, 0, 8, 2, 95, 55, 127, 6, 117, 0, 0, 10, 2, 95, 54, 89, 6, 111, 49, 89, 0, 0, 9, 2, 95, 53, 83, 6, 111, 65, 0, 0, 10, 2, 95, 52, 83, 6, 115, 51, 35, 0, 0, 0, 0, 9, 2, 95, 57, 50, 6, 108, 126, 0, 0, 9, 2, 95, 56, 6, 123, 47, 35, 0, 0, 0, 12, 67, 85, 48, 83, 117, 111, 89, 6, 122, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 67, 85, 49, 82, 21, 0, 10, 0, 0, 0, 0, 0, 0, 0, 11, 67, 36, 64, 71, 109, 72, 4, 122, 81, 0, 0, 15, 6, 13, 195, 165, 19, 20, 5, 65, 6, 123, 89, 47, 13, 0, 0, 0, 0, 0, 0, 0, 10, 67, 40, 17, 192, 57, 122, 81, 0, 72, 0, 13, 4, 95, 4, 15, 20, 48, 6, 120, 68, 49, 47, 0, 0, 0, 0, 0, 0, 7, 195, 88, 145, 0, 72, 28, 0, 5, 194, 88, 144, 72, 0, 0, 0, 10, 69, 60, 227, 9, 56, 80, 21, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 95, 7, 18, 22, 81, 51, 6, 122, 84, 0, 0, 8, 67, 20, 66, 84, 21, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 4, 9, 1, 6, 123, 65, 57, 117, 72, 0, 0, 0, 0, 0, 0, 12, 68, 4, 228, 197, 76, 35, 50, 89, 110, 89, 0, 6, 195, 16, 84, 211, 76, 0, 0, 0, 11, 70, 24, 148, 133, 24, 246, 0, 21, 0, 10, 0, 8, 67, 40, 21, 211, 21, 0, 10, 12, 68, 4, 228, 197, 72, 35, 50, 89, 110, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 67, 9, 32, 64, 71, 51, 122, 0, 0, 0, 0, 0, 19, 71, 80, 244, 147, 16, 17, 197, 56, 47, 6, 126, 91, 72, 122, 81, 111, 50, 0, 0, 0, 0, 11, 67, 25, 32, 77, 83, 51, 6, 35, 65, 0, 0, 0, 0, 0, 10, 67, 76, 17, 5, 89, 122, 72, 111, 0, 13, 4, 95, 35, 51, 50, 71, 55, 6, 35, 68, 49, 0, 0, 0, 0, 0, 16, 6, 14, 195, 165, 7, 15, 20, 50, 4, 124, 81, 123, 47, 0, 72, 0, 0, 0, 0, 0, 0, 16, 6, 14, 195, 165, 7, 15, 14, 50, 4, 124, 81, 123, 50, 0, 72, 0, 0, 0, 0, 11, 70, 21, 132, 12, 61, 33, 82, 21, 0, 10, 0, 0, 0, 0, 0, 0, 11, 70, 36, 229, 5, 72, 225, 84, 21, 0, 10, 0, 8, 67, 92, 149, 8, 21, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 69, 28, 243, 199, 48, 80, 21, 0, 10, 0, 7, 131, 4, 195, 165, 72, 28, 0, 0, 0, 0, 0, 12, 71, 84, 224, 200, 20, 50, 197, 16, 21, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 67, 80, 243, 84, 47, 6, 125, 65, 47, 0, 0, 0, 0, 11, 70, 32, 80, 68, 36, 225, 192, 21, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 8, 67, 28, 18, 77, 21, 0, 10, 0, 12, 71, 52, 84, 211, 20, 225, 197, 72, 21, 0, 10, 10, 67, 80, 243, 64, 47, 6, 125, 65, 0, 6, 195, 76, 149, 20, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 70, 77, 64, 68, 20, 228, 192, 89, 47, 122, 72, 111, 50, 89, 0, 0, 0, 0, 0, 0, 0, 0, 10, 135, 6, 1, 19, 20, 195, 164, 14, 8, 0, 11, 70, 48, 80, 86, 36, 225, 192, 21, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 164, 0, 4, 1, 102, 102, 3, 6, 113, 0, 1, 110, 111, 105, 2, 114, 0, 1, 116, 2, 114, 0, 114, 108, 2, 100, 3, 6, 113, 51, 0, 4, 1, 110, 2, 116, 116, 3, 111, 0, 1, 118, 2, 120, 0, 2, 17, 67, 17, 67, 0, 4, 3, 113, 0, 1, 98, 2, 114, 0, 1, 102, 2, 114, 100, 0, 1, 107, 115, 2, 114, 103, 0, 1, 108, 2, 115, 110, 0, 1, 108, 2, 115, 116, 0, 1, 110, 2, 116, 0, 1, 114, 2, 107, 0, 1, 114, 116, 2, 100, 0, 1, 118, 2, 108, 107, 0, 1, 118, 2, 114, 100, 0, 2, 114, 0, 2, 114, 100, 0, 7, 6, 195, 165, 0, 1, 108, 2, 115, 115, 3, 6, 123, 0, 4, 1, 104, 2, 114, 3, 6, 124, 0, 1, 108, 2, 115, 0, 1, 114, 116, 2, 100, 0, 1, 118, 2, 114, 0, 4, 1, 104, 2, 108, 108, 3, 123, 0, 2, 17, 67, 11, 0, 2, 110, 103, 0, 4, 3, 124, 0, 1, 104, 2, 108, 0, 1, 107, 115, 2, 108, 0, 1, 109, 2, 108, 0, 1, 110, 2, 108, 0, 1, 114, 2, 107, 0, 2, 17, 67, 17, 67, 0, 7, 6, 195, 182, 0, 1, 102, 2, 114, 107, 3, 2, 119, 0, 4, 1, 102, 2, 114, 100, 3, 6, 118, 0, 1, 102, 102, 0, 1, 108, 2, 115, 110, 0, 1, 108, 2, 115, 116, 0, 2, 118, 114, 0, 4, 1, 114, 2, 109, 3, 6, 119, 0, 2, 17, 67, 17, 67, 0, 3, 118, 0, 7, 6, 97, 0, 4, 1, 107, 2, 116, 97, 3, 2, 35, 0, 1, 107, 105, 0, 1, 108, 112, 2, 110, 101, 114, 97, 0, 1, 110, 2, 116, 105, 0, 1, 112, 101, 2, 114, 0, 1, 115, 2, 116, 105, 0, 1, 116, 2, 116, 105, 0, 8, 2, 114, 116, 0, 110, 115, 1, 21, 2, 32, 3, 6, 35, 50, 89, 0, 4, 1, 102, 2, 114, 108, 3, 6, 122, 0, 1, 102, 2, 114, 116, 0, 1, 107, 105, 2, 110, 115, 0, 1, 110, 2, 108, 32, 0, 1, 116, 2, 108, 32, 0, 1, 116, 2, 108, 32, 0, 1, 116, 111, 116, 2, 108, 0, 4, 1, 10, 3, 35, 0, 1, 98, 0, 1, 98, 2, 107, 116, 101, 0, 1, 98, 2, 114, 11, 0, 1, 98, 98, 2, 114, 32, 0, 1, 100, 2, 100, 0, 1, 100, 2, 103, 11, 0, 1, 100, 2, 110, 0, 1, 100, 100, 2, 17, 67, 0, 1, 100, 110, 2, 114, 0, 1, 100, 112, 112, 2, 116, 0, 1, 103, 101, 2, 110, 0, 1, 103, 110, 2, 100, 0, 1, 103, 165, 195, 2, 110, 0, 1, 106, 2, 110, 0, 1, 107, 2, 110, 0, 1, 107, 2, 110, 105, 0, 1, 107, 2, 115, 32, 0, 1, 108, 2, 103, 103, 0, 1, 108, 101, 2, 100, 0, 1, 108, 103, 2, 100, 11, 0, 1, 108, 103, 2, 115, 11, 0, 1, 108, 107, 105, 2, 114, 32, 0, 1, 108, 108, 2, 100, 101, 0, 1, 108, 108, 101, 109, 2, 110, 0, 1, 109, 2, 106, 0, 1, 109, 2, 110, 0, 1, 109, 2, 116, 101, 114, 0, 1, 109, 114, 111, 102, 2, 116, 105, 0, 1, 110, 2, 100, 0, 1, 110, 110, 2, 110, 0, 1, 112, 2, 100, 32, 0, 1, 112, 2, 110, 101, 108, 0, 1, 114, 2, 98, 97, 0, 1, 114, 100, 2, 100, 0, 1, 114, 100, 2, 116, 0, 1, 114, 101, 2, 100, 0, 1, 114, 101, 2, 116, 0, 1, 114, 101, 2, 116, 0, 1, 114, 103, 2, 109, 0, 1, 114, 116, 115, 0, 1, 115, 2, 100, 0, 1, 115, 2, 109, 97, 17, 67, 0, 1, 115, 2, 115, 0, 1, 115, 107, 2, 109, 0, 1, 115, 115, 97, 0, 1, 115, 116, 2, 109, 0, 1, 116, 2, 103, 11, 0, 1, 116, 2, 108, 11, 0, 1, 116, 2, 110, 0, 1, 116, 97, 0, 1, 116, 115, 2, 116, 32, 0, 1, 118, 2, 114, 105, 97, 0, 1, 118, 115, 2, 114, 116, 0, 2, 17, 67, 11, 0, 2, 17, 67, 17, 67, 0, 2, 32, 0, 2, 98, 111, 0, 2, 100, 101, 0, 2, 114, 32, 0, 2, 114, 101, 0, 2, 114, 110, 97, 0, 2, 115, 32, 0, 2, 116, 32, 0, 2, 117, 116, 111, 0, 2, 118, 97, 0, 2, 120, 0, 8, 107, 2, 21, 0, 110, 97, 108, 121, 3, 35, 50, 35, 55, 115, 0, 114, 98, 101, 116, 3, 35, 51, 71, 110, 47, 0, 108, 107, 111, 104, 111, 108, 3, 35, 55, 49, 125, 107, 124, 55, 0, 108, 108, 118, 97, 114, 3, 35, 55, 55, 84, 122, 51, 0, 109, 101, 114, 105, 107, 3, 35, 65, 111, 51, 109, 49, 0, 103, 101, 114, 97, 3, 35, 81, 110, 51, 35, 0, 115, 116, 3, 35, 89, 47, 0, 4, 3, 122, 0, 1, 98, 2, 107, 0, 1, 98, 2, 114, 0, 1, 98, 2, 114, 32, 0, 1, 100, 2, 103, 0, 1, 102, 2, 114, 101, 110, 0, 1, 107, 2, 107, 0, 1, 107, 115, 2, 100, 97, 0, 1, 107, 115, 2, 100, 101, 0, 1, 107, 115, 2, 112, 0, 1, 108, 2, 103, 0, 1, 108, 2, 114, 115, 0, 1, 108, 98, 2, 100, 0, 1, 108, 103, 2, 100, 0, 1, 108, 107, 2, 114, 0, 1, 108, 112, 109, 101, 120, 2, 114, 0, 1, 109, 111, 2, 116, 0, 1, 109, 115, 2, 114, 116, 0, 1, 114, 2, 116, 0, 1, 114, 100, 101, 2, 103, 0, 1, 114, 100, 101, 2, 114, 0, 1, 114, 100, 105, 0, 1, 115, 2, 107, 101, 0, 1, 115, 2, 107, 110, 0, 1, 115, 2, 107, 115, 0, 1, 116, 2, 103, 0, 1, 116, 2, 108, 17, 67, 0, 1, 116, 2, 108, 115, 0, 1, 116, 101, 114, 2, 103, 0, 1, 116, 108, 2, 116, 0, 1, 116, 108, 101, 100, 0, 1, 116, 110, 101, 2, 114, 0, 1, 116, 115, 2, 114, 116, 0, 1, 116, 116, 2, 103, 97, 0, 1, 116, 116, 2, 103, 101, 116, 0, 1, 116, 116, 2, 103, 105, 116, 0, 1, 118, 2, 108, 100, 0, 1, 118, 2, 108, 102, 0, 1, 118, 2, 114, 100, 0, 1, 118, 115, 2, 114, 0, 1, 118, 115, 110, 97, 2, 114, 0, 2, 114, 110, 0, 2, 114, 116, 32, 0, 2, 118, 98, 0, 2, 118, 100, 0, 2, 118, 103, 0, 2, 118, 115, 0, 8, 98, 2, 107, 0, 8, 107, 115, 2, 100, 0, 8, 108, 103, 2, 115, 0, 8, 118, 2, 110, 108, 0, 118, 116, 97, 8, 3, 122, 84, 47, 122, 0, 118, 103, 101, 8, 3, 122, 84, 57, 6, 110, 0, 117, 8, 2, 17, 67, 3, 123, 0, 117, 1, 104, 99, 2, 17, 67, 17, 67, 3, 124, 0, 7, 6, 98, 0, 2, 98, 3, 0, 3, 71, 0, 101, 116, 97, 108, 3, 71, 2, 111, 47, 6, 122, 55, 0, 114, 101, 100, 98, 97, 110, 100, 3, 71, 51, 110, 72, 71, 35, 50, 72, 0, 101, 103, 114, 105, 112, 3, 71, 111, 81, 51, 6, 108, 48, 0, 101, 103, 114, 97, 118, 3, 71, 111, 81, 51, 122, 84, 0, 101, 118, 97, 107, 110, 3, 71, 111, 84, 122, 49, 50, 0, 101, 115, 108, 97, 103, 3, 71, 111, 89, 55, 6, 122, 81, 0, 101, 115, 108, 97, 103, 116, 97, 3, 71, 111, 89, 55, 6, 122, 81, 47, 122, 0, 7, 6, 99, 0, 4, 108, 105, 99, 107, 3, 21, 0, 111, 109, 112, 117, 116, 101, 114, 0, 4, 3, 49, 0, 107, 0, 107, 2, 17, 65, 3, 49, 12, 0, 4, 99, 3, 49, 89, 0, 99, 2, 17, 65, 0, 4, 2, 101, 3, 89, 0, 2, 105, 0, 2, 121, 0, 2, 195, 164, 0, 2, 195, 182, 0, 104, 3, 91, 0, 104, 2, 101, 102, 3, 127, 0, 7, 6, 100, 0, 2, 100, 3, 0, 4, 101, 115, 105, 103, 110, 3, 21, 0, 111, 119, 110, 108, 111, 97, 100, 0, 106, 117, 3, 57, 6, 117, 0, 106, 117, 110, 103, 3, 57, 6, 120, 68, 0, 3, 72, 0, 97, 116, 111, 114, 101, 114, 3, 72, 35, 47, 6, 126, 51, 111, 51, 0, 114, 111, 103, 101, 110, 3, 72, 51, 124, 81, 111, 50, 0, 114, 111, 103, 101, 114, 3, 72, 51, 124, 81, 111, 51, 0, 105, 115, 107, 101, 3, 72, 109, 89, 49, 111, 0, 117, 109, 3, 72, 120, 65, 0, 97, 116, 97, 3, 72, 122, 47, 35, 0, 97, 116, 97, 98, 97, 115, 3, 72, 122, 47, 35, 71, 122, 89, 0, 97, 116, 111, 114, 3, 72, 122, 47, 123, 51, 0, 97, 103, 108, 105, 103, 3, 72, 122, 81, 55, 109, 81, 0, 97, 103, 101, 110, 3, 72, 122, 81, 111, 50, 0, 7, 6, 101, 0, 4, 1, 10, 3, 2, 111, 0, 1, 10, 2, 32, 0, 1, 98, 2, 102, 0, 1, 98, 2, 103, 0, 1, 98, 2, 104, 0, 1, 98, 2, 107, 0, 1, 98, 2, 108, 0, 1, 98, 2, 114, 0, 1, 98, 2, 115, 0, 1, 98, 2, 116, 0, 1, 98, 2, 118, 0, 1, 100, 2, 108, 115, 101, 0, 1, 103, 2, 110, 0, 1, 112, 109, 2, 108, 0, 1, 112, 115, 2, 99, 0, 1, 114, 2, 103, 0, 1, 114, 2, 116, 117, 114, 0, 1, 114, 112, 2, 99, 0, 1, 114, 112, 2, 110, 0, 1, 115, 2, 107, 0, 1, 115, 2, 112, 0, 2, 120, 101, 109, 112, 0, 116, 1, 10, 2, 32, 14, 128, 128, 130, 3, 2, 111, 47, 0, 110, 1, 10, 2, 32, 3, 2, 111, 50, 0, 110, 115, 1, 10, 2, 32, 3, 2, 111, 50, 89, 0, 114, 1, 10, 2, 32, 3, 2, 111, 51, 0, 115, 1, 10, 2, 32, 3, 2, 111, 89, 0, 110, 115, 1, 114, 101, 3, 6, 35, 50, 89, 0, 1, 116, 115, 2, 109, 17, 67, 3, 6, 110, 0, 107, 111, 110, 111, 109, 3, 6, 111, 49, 126, 50, 4, 123, 12, 65, 0, 110, 115, 1, 114, 101, 118, 182, 195, 3, 6, 111, 50, 89, 0, 108, 101, 107, 3, 6, 111, 55, 111, 49, 0, 109, 98, 101, 114, 3, 6, 111, 65, 71, 111, 51, 0, 115, 112, 101, 97, 107, 3, 21, 0, 4, 3, 110, 0, 1, 99, 2, 114, 0, 1, 100, 2, 108, 110, 0, 1, 100, 2, 108, 115, 0, 1, 100, 2, 108, 116, 0, 1, 100, 2, 108, 118, 0, 1, 100, 2, 114, 97, 0, 1, 102, 2, 114, 97, 0, 1, 103, 2, 110, 111, 109, 0, 1, 103, 2, 114, 97, 0, 1, 104, 2, 116, 101, 110, 0, 1, 104, 103, 2, 116, 0, 1, 104, 121, 110, 2, 116, 0, 1, 108, 2, 100, 97, 0, 1, 108, 2, 100, 110, 0, 1, 108, 2, 114, 97, 0, 1, 108, 2, 116, 97, 0, 1, 109, 2, 100, 100, 101, 0, 1, 109, 2, 100, 101, 108, 0, 1, 109, 2, 114, 97, 0, 1, 110, 2, 100, 115, 0, 1, 110, 2, 114, 97, 0, 1, 114, 2, 100, 110, 0, 1, 114, 2, 114, 97, 0, 1, 114, 2, 116, 97, 0, 1, 114, 98, 2, 118, 0, 1, 114, 116, 120, 2, 109, 0, 1, 115, 2, 114, 97, 0, 1, 116, 2, 114, 97, 0, 1, 116, 105, 2, 116, 0, 1, 116, 105, 2, 116, 32, 0, 1, 116, 111, 105, 108, 2, 107, 0, 1, 116, 115, 2, 107, 0, 1, 116, 115, 121, 2, 109, 0, 1, 118, 2, 107, 0, 1, 118, 2, 116, 97, 0, 2, 110, 98, 97, 114, 0, 2, 110, 108, 105, 0, 2, 114, 105, 110, 0, 2, 114, 115, 97, 116, 116, 0, 2, 114, 115, 195, 164, 0, 8, 104, 2, 116, 97, 0, 116, 1, 104, 2, 32, 3, 110, 47, 0, 110, 104, 101, 116, 3, 110, 50, 107, 110, 47, 0, 4, 1, 97, 107, 2, 108, 3, 111, 0, 1, 98, 2, 108, 32, 0, 1, 100, 2, 98, 97, 116, 0, 1, 100, 2, 99, 0, 1, 100, 101, 109, 2, 108, 0, 1, 104, 2, 109, 0, 1, 109, 2, 110, 121, 0, 1, 109, 2, 116, 111, 100, 0, 1, 112, 2, 100, 97, 0, 1, 112, 2, 114, 105, 0, 1, 114, 2, 99, 101, 0, 1, 114, 2, 100, 97, 107, 0, 1, 114, 2, 115, 117, 108, 0, 1, 114, 2, 115, 117, 114, 0, 1, 116, 2, 108, 101, 102, 0, 1, 118, 115, 2, 114, 0, 2, 17, 67, 17, 67, 0, 2, 103, 101, 110, 116, 0, 2, 106, 0, 2, 116, 97, 0, 2, 118, 101, 0, 2, 120, 0, 8, 2, 116, 105, 107, 0, 115, 101, 110, 116, 3, 111, 89, 6, 111, 50, 47, 0, 1, 104, 99, 2, 102, 3, 113, 0, 7, 6, 102, 0, 2, 102, 3, 0, 97, 99, 101, 3, 21, 0, 3, 83, 0, 97, 109, 105, 108, 106, 3, 83, 35, 65, 6, 109, 55, 57, 0, 111, 114, 109, 97, 100, 3, 83, 123, 51, 65, 35, 72, 0, 7, 6, 103, 0, 114, 111, 117, 112, 3, 21, 0, 2, 116, 3, 49, 0, 4, 1, 114, 111, 2, 97, 114, 3, 57, 0, 1, 114, 111, 2, 101, 110, 0, 2, 101, 0, 2, 105, 0, 2, 121, 0, 2, 195, 164, 0, 2, 195, 182, 0, 106, 0, 106, 111, 114, 3, 57, 126, 51, 0, 2, 110, 3, 68, 0, 4, 3, 81, 0, 1, 97, 2, 101, 0, 1, 97, 2, 105, 0, 1, 97, 108, 115, 0, 1, 105, 2, 105, 0, 1, 111, 108, 2, 105, 0, 1, 121, 2, 97, 0, 1, 121, 2, 101, 0, 1, 121, 2, 111, 0, 1, 164, 195, 108, 2, 101, 0, 1, 164, 195, 118, 0, 103, 0, 97, 114, 97, 110, 116, 3, 81, 2, 35, 51, 6, 35, 50, 47, 0, 117, 105, 100, 2, 101, 3, 81, 6, 35, 57, 72, 0, 97, 110, 105, 3, 81, 35, 50, 6, 109, 0, 97, 114, 97, 103, 101, 3, 81, 35, 51, 6, 122, 91, 0, 108, 195, 182, 109, 3, 81, 55, 119, 65, 0, 97, 116, 97, 3, 81, 122, 47, 35, 0, 7, 6, 104, 0, 2, 104, 3, 0, 101, 97, 100, 105, 110, 103, 3, 21, 0, 106, 3, 57, 0, 106, 195, 164, 108, 112, 3, 57, 111, 55, 48, 0, 3, 107, 0, 195, 182, 103, 3, 107, 118, 81, 0, 111, 110, 8, 2, 14, 128, 132, 131, 3, 107, 124, 68, 0, 7, 6, 105, 0, 4, 1, 108, 17, 67, 2, 107, 97, 17, 67, 3, 2, 109, 0, 2, 110, 102, 0, 2, 110, 115, 116, 114, 0, 4, 2, 110, 32, 3, 6, 108, 0, 2, 110, 101, 110, 0, 2, 110, 101, 114, 0, 4, 109, 97, 103, 3, 21, 0, 116, 101, 109, 0, 4, 3, 108, 0, 1, 99, 2, 115, 32, 0, 1, 108, 2, 107, 110, 97, 0, 1, 114, 100, 2, 118, 0, 1, 114, 107, 2, 115, 0, 1, 114, 107, 2, 115, 116, 0, 1, 114, 107, 115, 2, 118, 0, 1, 116, 2, 100, 0, 1, 116, 105, 114, 107, 2, 107, 32, 0, 1, 118, 2, 115, 110, 0, 8, 108, 102, 2, 107, 0, 4, 1, 99, 3, 109, 0, 1, 100, 2, 114, 0, 1, 107, 2, 103, 0, 1, 108, 2, 99, 0, 1, 114, 107, 2, 116, 101, 0, 1, 114, 107, 2, 116, 105, 0, 1, 115, 2, 116, 0, 1, 116, 2, 115, 0, 2, 17, 67, 17, 67, 0, 2, 103, 32, 0, 116, 117, 116, 2, 32, 3, 109, 47, 117, 47, 0, 107, 111, 110, 3, 109, 49, 6, 124, 50, 0, 98, 105, 108, 105, 3, 109, 71, 109, 55, 109, 0, 7, 6, 106, 0, 3, 57, 0, 97, 118, 97, 3, 57, 122, 84, 35, 0, 2, 117, 115, 116, 101, 114, 3, 127, 0, 111, 117, 2, 114, 3, 127, 125, 0, 7, 6, 107, 0, 4, 3, 49, 0, 8, 2, 105, 17, 67, 11, 0, 97, 116, 101, 103, 111, 114, 105, 3, 49, 35, 47, 111, 81, 4, 126, 51, 108, 0, 97, 108, 101, 110, 100, 3, 49, 35, 55, 6, 111, 50, 72, 0, 97, 114, 116, 97, 3, 49, 122, 51, 47, 35, 0, 111, 110, 116, 111, 114, 3, 49, 123, 50, 47, 6, 126, 51, 0, 111, 109, 109, 117, 110, 3, 49, 123, 65, 6, 117, 50, 0, 111, 109, 109, 117, 110, 105, 107, 97, 3, 49, 123, 65, 120, 50, 109, 49, 35, 0, 4, 2, 195, 164, 110, 100, 3, 97, 0, 2, 195, 164, 110, 110, 0, 2, 195, 164, 110, 116, 0, 2, 195, 182, 112, 0, 8, 2, 101, 0, 8, 2, 105, 0, 8, 2, 121, 0, 8, 2, 195, 164, 0, 8, 2, 195, 182, 0, 106, 0, 195, 164, 110, 115, 108, 3, 97, 111, 50, 89, 55, 0, 7, 6, 108, 0, 2, 108, 3, 0, 3, 55, 0, 195, 165, 103, 3, 55, 6, 124, 81, 0, 103, 2, 32, 3, 55, 57, 0, 105, 103, 101, 110, 3, 55, 109, 81, 111, 50, 0, 97, 103, 101, 114, 3, 55, 122, 81, 111, 51, 0, 106, 8, 3, 57, 0, 106, 117, 3, 57, 6, 117, 0, 7, 6, 109, 0, 2, 109, 3, 0, 101, 110, 117, 3, 21, 0, 3, 65, 0, 97, 114, 105, 101, 3, 65, 2, 35, 51, 6, 108, 0, 97, 114, 105, 97, 3, 65, 2, 35, 51, 6, 108, 35, 0, 101, 100, 108, 3, 65, 6, 110, 72, 55, 0, 195, 164, 110, 110, 105, 115, 107, 3, 65, 6, 111, 50, 109, 127, 4, 0, 111, 116, 111, 114, 101, 114, 3, 65, 6, 123, 47, 126, 51, 111, 51, 0, 111, 116, 111, 114, 3, 65, 6, 126, 47, 123, 51, 0, 97, 120, 105, 109, 101, 114, 97, 3, 65, 35, 49, 89, 108, 65, 6, 110, 51, 35, 0, 97, 103, 97, 3, 65, 35, 81, 35, 0, 97, 115, 107, 101, 114, 97, 3, 65, 35, 89, 49, 110, 51, 35, 0, 97, 115, 107, 101, 110, 3, 65, 35, 89, 49, 111, 50, 0, 97, 115, 107, 101, 114, 3, 65, 35, 89, 49, 111, 51, 0, 106, 117, 107, 3, 65, 57, 117, 49, 0, 105, 110, 105, 109, 101, 114, 97, 3, 65, 109, 50, 108, 65, 6, 110, 51, 35, 0, 101, 100, 98, 111, 114, 103, 3, 65, 110, 72, 71, 123, 51, 57, 0, 101, 100, 118, 101, 116, 3, 65, 110, 72, 84, 6, 110, 47, 0, 101, 110, 121, 3, 65, 111, 50, 6, 115, 0, 117, 115, 105, 107, 3, 65, 117, 89, 6, 108, 49, 0, 111, 98, 105, 108, 3, 65, 123, 71, 108, 55, 0, 111, 100, 101, 108, 3, 65, 123, 72, 6, 111, 55, 0, 111, 100, 101, 109, 3, 65, 123, 72, 110, 65, 0, 7, 6, 110, 0, 2, 110, 3, 0, 101, 116, 119, 111, 114, 107, 3, 21, 0, 3, 50, 0, 97, 118, 105, 103, 3, 50, 2, 35, 84, 2, 109, 81, 0, 97, 116, 117, 114, 3, 50, 6, 35, 47, 6, 117, 51, 0, 97, 108, 105, 3, 50, 35, 55, 109, 0, 103, 1, 117, 102, 2, 101, 114, 3, 50, 81, 0, 111, 114, 109, 97, 108, 3, 50, 123, 51, 65, 122, 55, 0, 4, 2, 107, 3, 68, 0, 103, 0, 7, 6, 111, 0, 4, 1, 102, 110, 105, 2, 114, 109, 97, 116, 105, 3, 2, 123, 0, 1, 107, 2, 108, 117, 0, 1, 110, 2, 118, 101, 108, 108, 0, 1, 112, 2, 108, 105, 115, 0, 1, 114, 112, 2, 98, 0, 1, 114, 112, 2, 99, 101, 110, 116, 0, 1, 114, 112, 2, 100, 0, 4, 1, 108, 2, 107, 3, 2, 125, 0, 1, 114, 112, 2, 99, 0, 1, 115, 2, 99, 105, 0, 4, 1, 98, 2, 120, 3, 6, 123, 0, 1, 102, 2, 114, 109, 0, 1, 107, 2, 112, 105, 0, 1, 108, 2, 103, 103, 0, 1, 110, 2, 114, 109, 0, 1, 115, 2, 114, 0, 99, 104, 3, 6, 123, 49, 0, 4, 1, 102, 2, 110, 3, 6, 124, 0, 1, 108, 2, 103, 0, 1, 108, 2, 118, 0, 2, 110, 105, 0, 4, 1, 107, 2, 107, 3, 6, 126, 0, 1, 108, 98, 2, 100, 0, 1, 109, 2, 116, 0, 4, 1, 17, 67, 2, 114, 115, 3, 123, 0, 1, 98, 2, 114, 116, 0, 1, 100, 2, 107, 0, 1, 100, 2, 110, 0, 1, 103, 2, 110, 0, 1, 103, 110, 2, 110, 0, 1, 107, 2, 110, 115, 0, 1, 107, 2, 114, 116, 0, 1, 107, 2, 114, 118, 0, 1, 108, 2, 110, 0, 1, 108, 108, 2, 110, 0, 1, 110, 2, 114, 32, 0, 1, 110, 110, 2, 110, 115, 0, 1, 112, 2, 112, 117, 0, 1, 112, 112, 2, 114, 116, 0, 1, 112, 115, 2, 114, 116, 0, 1, 114, 116, 114, 2, 110, 0, 1, 115, 2, 114, 32, 0, 1, 115, 115, 2, 110, 0, 1, 116, 2, 114, 32, 0, 1, 116, 115, 2, 114, 109, 0, 2, 17, 67, 17, 67, 0, 2, 98, 98, 0, 2, 99, 107, 0, 2, 100, 100, 0, 2, 102, 102, 0, 2, 108, 108, 0, 2, 109, 32, 0, 2, 109, 109, 0, 2, 112, 112, 0, 2, 114, 103, 0, 2, 114, 107, 0, 2, 114, 114, 0, 2, 115, 115, 0, 2, 116, 116, 0, 8, 2, 106, 0, 112, 101, 114, 97, 116, 3, 123, 48, 111, 51, 35, 47, 0, 106, 1, 114, 112, 3, 123, 127, 6, 0, 4, 1, 107, 2, 100, 3, 124, 0, 1, 107, 108, 2, 114, 0, 1, 112, 112, 117, 2, 114, 116, 0, 2, 114, 100, 101, 0, 4, 1, 103, 2, 114, 3, 125, 0, 2, 17, 67, 11, 0, 2, 110, 115, 0, 4, 3, 126, 0, 1, 98, 2, 107, 0, 1, 98, 2, 115, 116, 0, 1, 102, 2, 116, 98, 0, 1, 103, 2, 100, 0, 1, 114, 107, 2, 103, 0, 1, 114, 107, 2, 107, 0, 1, 114, 107, 2, 110, 0, 1, 114, 112, 2, 118, 0, 1, 115, 114, 2, 114, 100, 0, 2, 114, 17, 67, 0, 115, 112, 97, 114, 97, 116, 3, 126, 89, 48, 122, 51, 35, 47, 0, 7, 6, 112, 0, 2, 112, 3, 0, 3, 48, 0, 97, 107, 101, 116, 3, 48, 35, 49, 6, 110, 47, 0, 97, 114, 101, 110, 116, 101, 115, 3, 48, 35, 51, 13, 50, 47, 4, 110, 89, 0, 114, 105, 118, 97, 116, 3, 48, 51, 109, 84, 122, 47, 0, 105, 111, 110, 3, 48, 109, 38, 6, 126, 50, 0, 111, 116, 97, 116, 105, 115, 3, 48, 123, 47, 6, 122, 47, 109, 89, 0, 195, 165, 115, 116, 195, 165, 3, 48, 124, 89, 47, 124, 0, 7, 6, 113, 0, 2, 113, 3, 0, 3, 49, 0, 117, 3, 49, 58, 0, 7, 6, 114, 0, 4, 1, 114, 3, 0, 2, 116, 3, 0, 3, 51, 0, 101, 100, 105, 103, 101, 114, 3, 51, 2, 111, 72, 109, 127, 6, 110, 51, 0, 101, 115, 111, 114, 3, 51, 6, 110, 89, 123, 51, 0, 97, 100, 101, 114, 97, 3, 51, 35, 72, 6, 110, 51, 35, 0, 97, 102, 105, 107, 3, 51, 35, 83, 6, 108, 49, 0, 103, 2, 32, 3, 51, 57, 0, 105, 115, 107, 3, 51, 109, 89, 49, 0, 101, 103, 101, 108, 3, 51, 110, 81, 111, 55, 0, 101, 107, 111, 114, 100, 3, 51, 111, 49, 6, 124, 51, 72, 0, 117, 98, 114, 105, 107, 3, 51, 120, 71, 51, 6, 108, 49, 0, 115, 107, 2, 105, 3, 51, 127, 0, 115, 105, 2, 111, 3, 51, 127, 6, 0, 4, 115, 3, 93, 0, 115, 115, 0, 115, 107, 3, 93, 49, 0, 7, 6, 115, 0, 4, 101, 108, 101, 99, 116, 3, 21, 0, 119, 101, 100, 101, 110, 0, 4, 3, 89, 0, 1, 105, 102, 2, 107, 0, 1, 117, 102, 2, 107, 0, 2, 107, 105, 103, 0, 115, 0, 195, 164, 107, 101, 114, 104, 101, 116, 3, 89, 6, 113, 49, 13, 51, 107, 4, 110, 47, 0, 116, 195, 165, 116, 116, 3, 89, 47, 123, 47, 0, 112, 101, 108, 3, 89, 48, 110, 55, 0, 112, 101, 103, 108, 97, 3, 89, 48, 110, 81, 55, 35, 0, 112, 101, 103, 101, 108, 3, 89, 48, 110, 81, 111, 55, 0, 112, 97, 114, 97, 3, 89, 48, 122, 51, 35, 0, 107, 121, 112, 101, 3, 89, 49, 6, 35, 57, 48, 0, 107, 111, 108, 111, 114, 3, 89, 49, 126, 55, 123, 51, 0, 110, 101, 103, 108, 97, 3, 89, 50, 110, 81, 55, 35, 0, 108, 111, 103, 3, 89, 55, 6, 126, 81, 0, 106, 97, 99, 107, 3, 89, 57, 35, 49, 0, 118, 101, 114, 105, 103, 101, 3, 89, 84, 111, 51, 57, 111, 0, 118, 97, 114, 97, 3, 89, 84, 122, 51, 35, 0, 105, 111, 110, 105, 115, 116, 8, 3, 89, 108, 124, 50, 6, 109, 89, 47, 0, 101, 103, 108, 97, 3, 89, 110, 81, 55, 35, 0, 101, 103, 101, 108, 3, 89, 110, 81, 111, 55, 0, 195, 164, 103, 3, 89, 111, 57, 0, 101, 109, 101, 115, 116, 3, 89, 111, 65, 6, 111, 89, 47, 0, 101, 114, 118, 105, 99, 101, 3, 89, 118, 51, 84, 108, 89, 0, 99, 104, 3, 91, 0, 107, 106, 3, 97, 0, 4, 104, 8, 3, 127, 0, 106, 0, 107, 2, 101, 0, 107, 2, 105, 0, 107, 2, 121, 0, 107, 2, 195, 164, 0, 107, 2, 195, 182, 0, 116, 106, 0, 107, 195, 164, 114, 109, 3, 127, 6, 111, 51, 65, 0, 4, 105, 111, 2, 110, 3, 127, 6, 126, 0, 115, 105, 111, 2, 110, 0, 7, 6, 116, 0, 97, 115, 107, 3, 21, 0, 4, 3, 47, 0, 116, 0, 97, 108, 115, 121, 110, 116, 101, 115, 3, 47, 6, 122, 55, 89, 116, 50, 47, 4, 110, 89, 0, 97, 103, 105, 116, 3, 47, 6, 122, 81, 109, 47, 0, 116, 2, 17, 65, 3, 47, 12, 0, 97, 110, 103, 101, 110, 116, 3, 47, 35, 50, 57, 111, 50, 47, 0, 97, 98, 101, 108, 108, 3, 47, 35, 71, 6, 111, 55, 0, 101, 1, 17, 67, 10, 2, 32, 14, 128, 128, 130, 3, 47, 111, 0, 101, 107, 110, 105, 107, 3, 47, 111, 49, 50, 6, 108, 49, 0, 106, 3, 97, 0, 105, 2, 111, 110, 3, 127, 6, 0, 7, 6, 117, 0, 4, 1, 110, 105, 108, 2, 120, 3, 2, 120, 0, 2, 107, 116, 105, 0, 2, 110, 107, 17, 67, 0, 116, 109, 195, 164, 114, 107, 3, 6, 117, 47, 65, 13, 51, 49, 0, 112, 108, 111, 97, 100, 3, 21, 0, 4, 3, 117, 0, 1, 106, 2, 108, 0, 1, 106, 2, 110, 105, 0, 1, 106, 115, 2, 107, 0, 2, 116, 98, 0, 2, 116, 102, 0, 2, 116, 103, 0, 2, 116, 108, 0, 2, 116, 110, 0, 2, 116, 114, 0, 2, 116, 114, 0, 2, 116, 115, 0, 2, 116, 118, 0, 4, 1, 98, 2, 116, 105, 107, 3, 120, 0, 1, 116, 97, 100, 2, 109, 0, 1, 118, 2, 120, 0, 2, 17, 67, 17, 67, 0, 2, 110, 0, 2, 110, 103, 0, 1, 114, 2, 109, 32, 3, 120, 12, 0, 112, 112, 103, 101, 3, 120, 48, 57, 110, 0, 7, 6, 118, 0, 2, 118, 3, 0, 3, 84, 0, 97, 114, 97, 110, 100, 114, 97, 3, 84, 35, 51, 35, 50, 72, 51, 35, 0, 97, 108, 105, 3, 84, 35, 55, 109, 0, 101, 114, 107, 3, 84, 111, 51, 49, 0, 101, 114, 107, 116, 121, 103, 3, 84, 111, 51, 49, 47, 115, 81, 0, 97, 114, 97, 110, 3, 84, 122, 51, 35, 50, 0, 97, 114, 110, 3, 84, 122, 51, 50, 0, 7, 6, 119, 0, 4, 105, 110, 100, 111, 119, 3, 21, 0, 105, 114, 101, 0, 105, 115, 101, 0, 3, 84, 0, 7, 6, 120, 0, 2, 120, 3, 0, 3, 49, 89, 0, 7, 6, 121, 0, 1, 115, 2, 115, 3, 2, 116, 0, 4, 1, 116, 2, 100, 3, 6, 115, 0, 1, 116, 2, 103, 0, 4, 3, 115, 0, 1, 115, 2, 110, 115, 107, 97, 0, 2, 17, 67, 17, 67, 3, 116, 0, 7, 6, 122, 0, 122, 3, 88, 0, 3, 89, 0, 7, 6, 0, 4, 42, 1, 42, 2, 42, 3, 0, 4, 42, 42, 3, 0, 4, 45, 1, 45, 45, 3, 0, 46, 1, 46, 3, 0, 195, 169, 3, 6, 110, 0, 226, 130, 172, 3, 6, 111, 84, 51, 126, 0, 46, 2, 46, 3, 9, 0, 38, 3, 9, 6, 123, 49, 0, 4, 45, 1, 32, 17, 65, 2, 32, 15, 3, 10, 0, 45, 1, 32, 17, 67, 2, 32, 15, 0, 42, 1, 42, 42, 2, 32, 3, 24, 0, 46, 3, 48, 6, 120, 68, 47, 0, 37, 3, 48, 51, 123, 89, 6, 111, 50, 47, 0, 43, 3, 48, 55, 120, 89, 0, 45, 8, 32, 2, 32, 15, 3, 65, 6, 108, 50, 120, 89, 0, 36, 3, 72, 6, 123, 55, 35, 51, 0, 47, 3, 89, 50, 6, 110, 72, 89, 47, 51, 111, 49, 0, 64, 3, 89, 50, 6, 122, 71, 111, 55, 122, 0, 42, 3, 127, 6, 113, 51, 50, 35, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts60 = FileInMemory_createWithData (9701, reinterpret_cast (&espeakdata_dicts60_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/sv_dict", U"sv"); Collection_addItem (me.peek(), espeakdata_dicts60.transfer()); static unsigned char espeakdata_dicts61_data[3005] = { 0, 4, 0, 0, 32, 10, 0, 0, 0, 0, 0, 0, 0, 17, 4, 95, 56, 77, 49, 4, 36, 55, 83, 40, 50, 6, 35, 50, 36, 0, 0, 17, 4, 95, 56, 77, 50, 55, 6, 35, 49, 37, 50, 6, 35, 50, 36, 0, 0, 0, 0, 6, 65, 8, 71, 37, 0, 0, 0, 0, 0, 6, 65, 12, 89, 37, 0, 0, 0, 0, 7, 196, 100, 16, 78, 36, 8, 0, 6, 65, 16, 72, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 24, 36, 83, 0, 0, 0, 0, 0, 9, 197, 12, 129, 78, 100, 80, 72, 28, 6, 65, 28, 79, 37, 0, 0, 0, 0, 0, 7, 65, 32, 36, 76, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 40, 79, 36, 0, 0, 0, 0, 0, 6, 65, 44, 49, 36, 0, 0, 0, 0, 0, 6, 65, 48, 36, 55, 0, 0, 0, 0, 0, 7, 65, 52, 36, 65, 0, 14, 4, 193, 52, 76, 0, 0, 0, 0, 11, 5, 95, 48, 1, 14, 4, 23, 50, 35, 0, 6, 65, 56, 36, 50, 0, 0, 0, 0, 0, 0, 0, 0, 8, 196, 104, 83, 153, 20, 72, 28, 8, 196, 100, 83, 153, 20, 72, 28, 8, 196, 92, 83, 153, 20, 72, 28, 0, 6, 65, 64, 48, 37, 0, 0, 0, 0, 0, 7, 65, 68, 49, 57, 40, 0, 0, 0, 0, 0, 6, 65, 72, 35, 51, 0, 0, 0, 0, 0, 6, 65, 76, 36, 89, 0, 0, 0, 0, 0, 6, 65, 80, 47, 37, 0, 0, 0, 6, 195, 92, 19, 192, 76, 0, 0, 4, 193, 84, 76, 0, 0, 0, 7, 195, 80, 242, 193, 72, 28, 0, 6, 65, 88, 84, 37, 0, 0, 0, 0, 0, 11, 65, 92, 72, 35, 71, 35, 55, 57, 40, 0, 0, 0, 0, 6, 195, 92, 18, 197, 76, 0, 17, 4, 95, 49, 77, 49, 4, 36, 55, 83, 40, 65, 6, 39, 79, 35, 0, 7, 65, 96, 36, 49, 89, 0, 0, 17, 4, 95, 49, 77, 50, 55, 6, 35, 49, 37, 65, 6, 39, 79, 35, 0, 0, 0, 6, 195, 76, 148, 201, 76, 0, 7, 65, 100, 57, 35, 37, 0, 0, 0, 0, 0, 8, 65, 104, 88, 36, 72, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 5, 80, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 32, 17, 9, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 32, 147, 15, 76, 0, 0, 0, 0, 0, 0, 0, 8, 197, 45, 112, 86, 100, 240, 8, 0, 0, 0, 0, 19, 4, 95, 50, 77, 49, 4, 36, 55, 83, 40, 23, 65, 71, 6, 37, 55, 37, 0, 0, 19, 4, 95, 50, 77, 50, 55, 6, 35, 49, 37, 23, 65, 71, 6, 37, 55, 37, 0, 0, 0, 7, 196, 4, 145, 8, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 32, 21, 1, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 8, 144, 72, 28, 0, 0, 0, 0, 0, 6, 195, 32, 146, 64, 72, 0, 13, 4, 95, 4, 16, 20, 10, 50, 40, 49, 47, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 4, 95, 51, 77, 49, 4, 36, 55, 83, 40, 47, 6, 35, 47, 40, 0, 0, 17, 4, 95, 51, 77, 50, 55, 6, 35, 49, 37, 47, 6, 35, 47, 40, 0, 0, 0, 0, 0, 0, 0, 8, 196, 64, 147, 132, 36, 76, 8, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 37, 112, 80, 60, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 197, 89, 145, 78, 100, 80, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 53, 112, 64, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 45, 112, 76, 60, 8, 0, 0, 6, 194, 4, 240, 72, 8, 0, 0, 0, 9, 197, 53, 113, 78, 100, 80, 72, 28, 9, 197, 44, 21, 9, 44, 16, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 198, 92, 19, 1, 44, 147, 137, 8, 0, 0, 0, 0, 0, 0, 17, 67, 41, 85, 64, 79, 4, 40, 12, 57, 108, 0, 8, 81, 121, 97, 32, 0, 8, 196, 80, 20, 129, 4, 76, 8, 10, 68, 80, 19, 135, 84, 91, 40, 0, 28, 0, 0, 0, 0, 0, 8, 197, 64, 19, 129, 64, 240, 8, 0, 0, 0, 0, 8, 197, 48, 18, 201, 56, 144, 8, 8, 197, 36, 225, 193, 92, 16, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 133, 49, 5, 14, 25, 5, 72, 28, 7, 196, 56, 19, 153, 36, 76, 0, 0, 6, 194, 24, 144, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 4, 95, 53, 77, 49, 4, 36, 55, 83, 40, 47, 6, 35, 50, 39, 0, 0, 0, 0, 17, 4, 95, 53, 77, 50, 55, 6, 35, 49, 37, 47, 6, 35, 50, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 51, 88, 87, 36, 55, 36, 87, 6, 37, 50, 37, 0, 0, 10, 3, 95, 48, 67, 65, 6, 37, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 49, 67, 65, 4, 37, 35, 65, 6, 39, 79, 35, 0, 0, 0, 0, 0, 0, 0, 6, 194, 48, 16, 72, 28, 0, 0, 17, 3, 95, 50, 67, 65, 4, 37, 35, 23, 65, 71, 6, 37, 55, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 51, 67, 65, 4, 37, 35, 47, 6, 35, 47, 40, 0, 0, 0, 0, 17, 4, 95, 54, 77, 49, 4, 36, 55, 83, 40, 89, 6, 37, 47, 35, 0, 0, 7, 196, 45, 112, 89, 20, 8, 0, 0, 17, 4, 95, 54, 77, 50, 55, 6, 35, 49, 37, 89, 6, 37, 47, 35, 0, 0, 13, 3, 95, 55, 88, 89, 35, 71, 6, 37, 50, 37, 0, 0, 14, 3, 95, 52, 67, 65, 4, 37, 35, 6, 42, 50, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 53, 67, 65, 4, 37, 35, 47, 6, 35, 50, 39, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 49, 88, 49, 6, 40, 65, 37, 0, 0, 15, 3, 95, 54, 67, 65, 4, 37, 35, 89, 6, 37, 47, 35, 0, 0, 0, 0, 0, 0, 0, 5, 194, 45, 80, 76, 0, 14, 3, 95, 50, 88, 37, 91, 37, 51, 6, 37, 50, 37, 0, 0, 15, 3, 95, 55, 67, 65, 4, 37, 35, 89, 6, 35, 71, 35, 0, 0, 0, 0, 0, 0, 0, 6, 195, 52, 147, 73, 76, 0, 0, 15, 3, 95, 56, 67, 65, 4, 37, 35, 50, 6, 35, 50, 36, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 52, 88, 35, 51, 39, 71, 35, 6, 37, 50, 37, 0, 0, 15, 3, 95, 57, 67, 65, 4, 37, 35, 47, 6, 37, 89, 35, 0, 0, 0, 0, 0, 0, 0, 6, 194, 56, 16, 72, 8, 0, 14, 3, 95, 53, 88, 107, 35, 65, 89, 6, 37, 50, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 54, 88, 89, 37, 47, 6, 37, 50, 37, 0, 0, 0, 0, 0, 17, 4, 95, 55, 77, 49, 4, 36, 55, 83, 40, 89, 6, 35, 71, 35, 0, 0, 0, 0, 17, 4, 95, 55, 77, 50, 55, 6, 35, 49, 37, 89, 6, 35, 71, 35, 0, 0, 10, 199, 36, 160, 80, 60, 181, 87, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 56, 88, 87, 36, 65, 35, 50, 6, 37, 50, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 57, 88, 47, 37, 89, 6, 37, 50, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 64, 16, 72, 28, 6, 194, 64, 16, 72, 28, 5, 194, 48, 144, 72, 0, 0, 0, 0, 0, 0, 0, 9, 197, 45, 112, 77, 8, 16, 72, 8, 0, 0, 7, 195, 52, 147, 128, 72, 28, 0, 16, 4, 95, 48, 77, 52, 23, 71, 37, 55, 37, 6, 39, 50, 37, 0, 0, 0, 0, 16, 4, 95, 48, 77, 51, 23, 65, 37, 55, 37, 6, 39, 50, 37, 0, 0, 0, 12, 4, 95, 48, 77, 49, 6, 36, 55, 83, 40, 0, 0, 0, 0, 8, 196, 8, 16, 68, 4, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 56, 144, 76, 0, 0, 0, 0, 0, 0, 6, 195, 100, 18, 197, 76, 0, 0, 0, 0, 0, 0, 17, 4, 95, 57, 77, 50, 55, 6, 35, 49, 37, 47, 6, 37, 89, 35, 0, 0, 0, 0, 17, 4, 95, 57, 77, 49, 4, 36, 55, 83, 40, 47, 6, 37, 89, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 92, 85, 197, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 45, 84, 213, 16, 144, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 4, 225, 193, 60, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 8, 147, 1, 72, 8, 0, 0, 0, 0, 7, 195, 8, 19, 9, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 45, 85, 193, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 40, 20, 15, 8, 0, 0, 0, 0, 0, 0, 0, 0, 9, 198, 45, 80, 78, 104, 144, 64, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 56, 19, 73, 76, 0, 0, 5, 194, 81, 80, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 92, 16, 72, 28, 5, 194, 76, 144, 72, 0, 0, 6, 195, 56, 22, 69, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 36, 160, 80, 60, 8, 0, 0, 0, 0, 7, 195, 89, 144, 64, 72, 28, 0, 0, 7, 2, 95, 13, 36, 65, 0, 0, 0, 22, 67, 45, 112, 64, 49, 58, 35, 15, 49, 4, 40, 58, 108, 0, 8, 81, 107, 117, 119, 97, 32, 7, 195, 45, 112, 64, 72, 28, 7, 195, 45, 112, 64, 72, 28, 0, 7, 196, 44, 148, 200, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 45, 112, 79, 8, 0, 0, 0, 0, 0, 0, 16, 4, 95, 52, 77, 50, 55, 6, 35, 49, 37, 6, 42, 50, 36, 0, 0, 16, 4, 95, 52, 77, 49, 4, 36, 55, 83, 40, 6, 42, 50, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 2, 95, 51, 47, 6, 35, 47, 40, 0, 0, 12, 2, 95, 50, 23, 65, 71, 6, 37, 55, 37, 0, 0, 10, 2, 95, 49, 65, 6, 39, 79, 35, 0, 0, 12, 2, 95, 48, 89, 37, 83, 6, 40, 51, 37, 0, 0, 10, 2, 95, 55, 89, 6, 35, 71, 35, 0, 0, 10, 2, 95, 54, 89, 6, 37, 47, 35, 0, 0, 10, 2, 95, 53, 47, 6, 35, 50, 39, 0, 0, 9, 2, 95, 52, 6, 42, 50, 36, 0, 0, 0, 0, 10, 2, 95, 57, 47, 6, 37, 89, 35, 0, 0, 6, 194, 100, 16, 72, 28, 10, 2, 95, 56, 50, 6, 35, 50, 36, 0, 0, 0, 0, 8, 197, 57, 146, 78, 100, 144, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 36, 192, 64, 8, 7, 195, 12, 128, 64, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 104, 16, 72, 28, 0, 0, 0, 8, 197, 64, 19, 79, 40, 16, 8, 0, 6, 195, 104, 18, 197, 76, 0, 7, 195, 36, 194, 64, 76, 8, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 56, 19, 192, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 8, 20, 201, 76, 8, 6, 195, 56, 21, 197, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 101, 80, 72, 0, 0, 0, 0, 6, 195, 56, 20, 201, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 92, 19, 1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 33, 82, 207, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 45, 112, 67, 32, 240, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 4, 208, 64, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 194, 104, 144, 72, 0, 0, 0, 0, 0, 10, 199, 36, 194, 75, 92, 19, 66, 4, 8, 0, 0, 9, 198, 8, 17, 1, 48, 22, 65, 8, 0, 7, 195, 44, 19, 65, 76, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 100, 86, 69, 76, 0, 0, 0, 0, 0, 0, 0, 6, 97, 0, 3, 35, 0, 97, 3, 35, 12, 0, 7, 6, 98, 0, 3, 71, 0, 7, 6, 99, 0, 3, 49, 0, 104, 3, 76, 0, 7, 6, 100, 0, 3, 72, 0, 104, 3, 86, 0, 7, 6, 101, 0, 3, 36, 0, 101, 3, 36, 12, 0, 7, 6, 102, 0, 3, 83, 0, 7, 6, 103, 0, 3, 81, 0, 104, 3, 100, 0, 7, 6, 104, 0, 3, 107, 0, 7, 6, 105, 0, 3, 37, 0, 105, 3, 37, 12, 0, 7, 6, 106, 0, 3, 79, 0, 7, 6, 107, 0, 3, 49, 0, 104, 3, 101, 0, 7, 6, 108, 0, 3, 55, 0, 7, 6, 109, 0, 4, 1, 25, 2, 21, 21, 3, 23, 65, 0, 1, 25, 2, 98, 21, 21, 0, 1, 25, 2, 118, 21, 21, 0, 1, 25, 2, 119, 21, 21, 0, 4, 1, 25, 2, 17, 67, 3, 41, 0, 8, 0, 4, 3, 65, 0, 2, 17, 65, 0, 7, 6, 110, 0, 8, 3, 42, 0, 4, 8, 2, 103, 3, 43, 0, 8, 2, 103, 21, 21, 0, 8, 2, 107, 0, 8, 2, 107, 21, 21, 0, 4, 3, 50, 0, 2, 17, 65, 0, 2, 21, 21, 0, 4, 2, 99, 104, 3, 67, 0, 2, 106, 0, 121, 0, 4, 2, 103, 3, 68, 0, 2, 107, 0, 103, 39, 0, 7, 6, 111, 0, 3, 39, 0, 111, 3, 39, 12, 0, 7, 6, 112, 0, 3, 48, 0, 7, 6, 113, 0, 3, 49, 0, 7, 6, 114, 0, 1, 17, 67, 2, 17, 65, 3, 14, 16, 0, 4, 3, 51, 0, 1, 17, 65, 2, 17, 65, 0, 114, 3, 51, 51, 0, 7, 6, 115, 0, 3, 89, 0, 104, 3, 91, 0, 7, 6, 116, 0, 3, 47, 0, 104, 3, 87, 0, 7, 6, 117, 0, 3, 40, 0, 117, 3, 40, 12, 0, 7, 6, 118, 0, 3, 84, 0, 7, 6, 119, 0, 3, 58, 0, 7, 6, 120, 0, 3, 49, 89, 0, 7, 6, 121, 0, 3, 57, 0, 7, 6, 122, 0, 3, 88, 0, 7, 6, 0, 4, 42, 1, 42, 2, 42, 3, 0, 42, 42, 3, 0, 42, 1, 42, 42, 2, 32, 3, 24, 0, 37, 3, 35, 89, 37, 55, 37, 65, 37, 35, 0, 42, 3, 67, 39, 47, 35, 0, 36, 3, 72, 39, 55, 35, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts61 = FileInMemory_createWithData (3004, reinterpret_cast (&espeakdata_dicts61_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/sw_dict", U"sw"); Collection_addItem (me.peek(), espeakdata_dicts61.transfer()); static unsigned char espeakdata_dicts62_data[88228] = { 0, 4, 0, 0, 29, 37, 0, 0, 9, 134, 224, 174, 164, 224, 174, 169, 20, 0, 18, 143, 224, 174, 154, 224, 174, 176, 224, 175, 141, 224, 174, 154, 224, 175, 141, 20, 0, 0, 0, 0, 6, 65, 4, 114, 57, 0, 0, 20, 12, 95, 35, 45, 224, 174, 181, 224, 174, 164, 224, 175, 129, 118, 84, 109, 72, 122, 0, 0, 24, 149, 224, 174, 154, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 169, 224, 175, 141, 20, 9, 134, 224, 174, 164, 224, 174, 181, 20, 0, 21, 146, 224, 174, 164, 224, 174, 174, 224, 175, 141, 224, 174, 174, 224, 174, 174, 224, 175, 141, 20, 0, 6, 65, 8, 71, 112, 0, 0, 0, 0, 0, 21, 6, 224, 174, 170, 224, 174, 191, 71, 37, 57, 114, 0, 24, 82, 46, 32, 224, 174, 143, 32, 6, 65, 12, 89, 112, 0, 0, 27, 152, 224, 174, 170, 224, 175, 139, 224, 174, 169, 224, 175, 141, 224, 174, 184, 224, 174, 190, 224, 174, 175, 224, 175, 141, 20, 0, 0, 0, 6, 65, 16, 72, 112, 0, 0, 0, 15, 140, 224, 174, 149, 224, 175, 129, 224, 174, 164, 224, 174, 191, 20, 15, 140, 224, 174, 170, 224, 175, 139, 224, 174, 169, 224, 174, 191, 20, 9, 134, 224, 174, 170, 224, 174, 181, 20, 11, 6, 224, 174, 178, 224, 175, 141, 37, 55, 0, 0, 0, 18, 143, 224, 174, 170, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 190, 20, 5, 65, 20, 112, 0, 0, 12, 137, 224, 174, 149, 224, 174, 190, 224, 174, 169, 20, 0, 0, 13, 6, 224, 174, 170, 224, 174, 170, 48, 109, 48, 109, 0, 0, 15, 140, 224, 174, 170, 224, 175, 130, 224, 174, 174, 224, 175, 141, 20, 6, 65, 24, 116, 83, 0, 0, 0, 0, 18, 143, 224, 174, 170, 224, 175, 139, 224, 174, 149, 224, 174, 174, 224, 175, 141, 20, 0, 6, 65, 28, 75, 112, 0, 0, 0, 13, 4, 95, 54, 48, 15, 35, 51, 122, 71, 109, 72, 0, 0, 0, 6, 65, 32, 114, 76, 0, 0, 11, 1, 33, 84, 37, 57, 109, 48, 48, 122, 0, 0, 0, 8, 1, 35, 38, 36, 66, 0, 27, 0, 27, 152, 224, 174, 170, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 154, 224, 175, 141, 20, 6, 65, 36, 118, 57, 0, 0, 14, 1, 37, 84, 37, 92, 122, 49, 49, 118, 141, 122, 0, 27, 0, 10, 1, 38, 65, 109, 140, 51, 122, 65, 0, 0, 30, 155, 224, 174, 170, 224, 174, 178, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 190, 224, 174, 178, 224, 174, 190, 224, 174, 169, 20, 0, 7, 65, 40, 75, 114, 57, 0, 0, 0, 13, 1, 42, 48, 36, 34, 122, 49, 49, 109, 55, 0, 27, 0, 11, 1, 43, 49, 123, 140, 140, 109, 55, 0, 27, 0, 7, 65, 44, 49, 114, 57, 0, 0, 0, 0, 9, 1, 47, 89, 118, 57, 84, 122, 0, 0, 6, 65, 48, 116, 55, 0, 0, 15, 140, 224, 174, 170, 224, 175, 130, 224, 174, 174, 224, 174, 190, 20, 0, 15, 140, 224, 174, 170, 224, 175, 139, 224, 174, 149, 224, 174, 191, 20, 0, 0, 6, 65, 52, 116, 65, 0, 0, 0, 0, 33, 158, 224, 174, 170, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 174, 224, 174, 190, 20, 0, 6, 65, 56, 116, 50, 0, 0, 0, 0, 0, 10, 1, 60, 49, 40, 51, 134, 84, 122, 0, 5, 65, 60, 119, 0, 0, 14, 1, 61, 89, 35, 65, 109, 50, 48, 118, 141, 122, 0, 27, 0, 10, 1, 62, 65, 37, 81, 122, 72, 37, 0, 0, 0, 6, 65, 64, 48, 112, 0, 0, 0, 0, 0, 7, 65, 68, 49, 57, 123, 0, 0, 0, 15, 140, 224, 174, 149, 224, 175, 139, 224, 174, 178, 224, 174, 191, 20, 0, 0, 6, 65, 72, 118, 51, 0, 0, 15, 9, 224, 174, 149, 224, 174, 170, 224, 175, 141, 49, 109, 48, 0, 0, 0, 0, 15, 140, 224, 174, 149, 224, 174, 190, 224, 174, 159, 224, 175, 141, 20, 15, 140, 224, 174, 164, 224, 175, 138, 224, 174, 170, 224, 175, 141, 20, 18, 12, 224, 174, 170, 224, 175, 128, 224, 174, 170, 224, 175, 141, 71, 112, 48, 0, 6, 65, 76, 116, 89, 0, 0, 0, 0, 0, 6, 65, 80, 138, 112, 0, 0, 0, 11, 6, 224, 174, 185, 224, 175, 141, 37, 99, 0, 0, 0, 6, 65, 84, 57, 123, 0, 0, 0, 10, 4, 95, 49, 67, 15, 50, 123, 51, 0, 0, 0, 6, 65, 88, 84, 112, 0, 0, 12, 137, 224, 174, 149, 224, 174, 174, 224, 175, 141, 20, 0, 0, 19, 11, 95, 35, 224, 174, 181, 224, 174, 164, 224, 175, 129, 118, 84, 109, 72, 122, 0, 0, 15, 1, 92, 48, 6, 37, 50, 15, 89, 4, 118, 57, 84, 122, 0, 11, 65, 92, 72, 109, 71, 109, 55, 57, 123, 0, 0, 0, 14, 4, 95, 55, 48, 15, 38, 36, 92, 122, 71, 109, 72, 0, 0, 18, 143, 224, 174, 170, 224, 175, 135, 224, 174, 149, 224, 174, 174, 224, 175, 141, 20, 18, 143, 224, 174, 170, 224, 174, 190, 224, 174, 177, 224, 174, 174, 224, 175, 141, 20, 0, 7, 65, 96, 116, 49, 89, 0, 0, 18, 4, 95, 49, 77, 50, 39, 34, 122, 55, 109, 141, 76, 109, 47, 47, 122, 0, 0, 21, 146, 224, 174, 170, 224, 174, 178, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 129, 20, 15, 4, 95, 49, 77, 51, 39, 34, 122, 49, 119, 141, 37, 114, 0, 0, 0, 7, 65, 100, 58, 118, 57, 0, 0, 0, 0, 0, 15, 140, 224, 174, 149, 224, 174, 191, 224, 174, 159, 224, 175, 129, 20, 7, 65, 104, 88, 116, 72, 0, 0, 0, 11, 67, 21, 84, 128, 57, 123, 34, 119, 88, 0, 0, 0, 15, 140, 224, 174, 149, 224, 174, 191, 224, 174, 163, 224, 175, 141, 20, 15, 140, 224, 174, 149, 224, 175, 129, 224, 174, 176, 224, 175, 129, 20, 15, 140, 224, 174, 170, 224, 175, 128, 224, 174, 154, 224, 175, 141, 20, 0, 0, 0, 0, 0, 0, 11, 6, 224, 174, 180, 224, 175, 141, 37, 92, 0, 0, 12, 137, 224, 174, 164, 224, 174, 191, 224, 174, 159, 20, 0, 0, 21, 146, 224, 174, 164, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 174, 163, 224, 175, 136, 20, 0, 0, 0, 15, 140, 224, 174, 149, 224, 174, 191, 224, 174, 169, 224, 175, 141, 20, 15, 140, 224, 174, 170, 224, 174, 149, 224, 174, 164, 224, 175, 141, 20, 0, 0, 24, 67, 5, 81, 0, 39, 89, 47, 34, 6, 36, 113, 55, 113, 109, 50, 15, 72, 6, 39, 55, 109, 88, 0, 0, 0, 13, 1, 124, 89, 36, 68, 81, 122, 47, 47, 122, 0, 27, 0, 0, 0, 0, 0, 30, 21, 224, 174, 170, 224, 174, 191, 224, 174, 176, 224, 174, 154, 224, 174, 190, 224, 174, 176, 224, 175, 141, 48, 34, 109, 89, 118, 34, 0, 0, 0, 0, 0, 0, 16, 4, 95, 49, 57, 15, 48, 35, 47, 47, 39, 50, 71, 109, 72, 0, 0, 0, 0, 0, 0, 30, 155, 224, 174, 149, 224, 174, 174, 224, 175, 141, 224, 174, 174, 224, 175, 134, 224, 174, 169, 224, 175, 141, 224, 174, 177, 224, 175, 129, 20, 0, 21, 146, 224, 174, 170, 224, 174, 176, 224, 175, 141, 224, 174, 174, 224, 174, 191, 224, 174, 175, 20, 0, 0, 21, 146, 224, 174, 170, 224, 175, 128, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 175, 129, 20, 0, 12, 137, 224, 174, 149, 224, 174, 164, 224, 174, 191, 20, 11, 4, 95, 49, 67, 48, 50, 123, 51, 122, 0, 0, 0, 0, 0, 0, 18, 143, 224, 174, 164, 224, 175, 135, 224, 174, 181, 224, 174, 164, 224, 174, 190, 20, 0, 0, 13, 4, 95, 50, 67, 15, 37, 34, 122, 50, 123, 51, 0, 0, 0, 21, 146, 224, 174, 149, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 191, 20, 0, 21, 146, 224, 174, 170, 224, 175, 136, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 136, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 67, 36, 228, 128, 6, 113, 50, 72, 113, 109, 50, 15, 34, 6, 123, 48, 112, 88, 0, 0, 0, 0, 15, 140, 224, 174, 154, 224, 174, 190, 224, 174, 175, 224, 174, 190, 20, 12, 137, 224, 174, 164, 224, 174, 191, 224, 174, 169, 20, 0, 15, 140, 224, 174, 149, 224, 175, 139, 224, 174, 170, 224, 174, 191, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 140, 224, 174, 170, 224, 175, 141, 224, 174, 176, 224, 174, 190, 20, 15, 140, 224, 174, 170, 224, 174, 159, 224, 174, 181, 224, 174, 190, 20, 0, 0, 0, 0, 18, 143, 224, 174, 164, 224, 174, 176, 224, 174, 190, 224, 174, 181, 224, 174, 191, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 140, 224, 174, 170, 224, 174, 191, 224, 174, 149, 224, 175, 129, 20, 0, 0, 15, 4, 95, 49, 49, 15, 48, 35, 47, 37, 50, 39, 50, 51, 0, 11, 6, 224, 174, 183, 224, 175, 141, 37, 93, 0, 0, 0, 9, 134, 224, 174, 149, 224, 175, 139, 20, 0, 0, 9, 134, 224, 174, 149, 224, 174, 149, 20, 11, 6, 224, 174, 181, 224, 175, 141, 37, 84, 0, 11, 6, 224, 174, 149, 224, 175, 141, 37, 49, 0, 0, 15, 9, 224, 174, 147, 224, 174, 149, 224, 175, 139, 119, 108, 119, 0, 0, 0, 0, 0, 14, 4, 95, 50, 67, 48, 37, 34, 122, 50, 123, 51, 122, 0, 0, 15, 140, 224, 174, 164, 224, 174, 181, 224, 174, 149, 224, 175, 141, 20, 15, 140, 224, 174, 164, 224, 174, 159, 224, 174, 149, 224, 175, 141, 20, 0, 0, 0, 0, 9, 134, 224, 174, 149, 224, 174, 159, 20, 0, 0, 33, 158, 224, 174, 164, 224, 175, 138, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 134, 224, 174, 169, 224, 175, 141, 224, 174, 177, 224, 175, 129, 20, 21, 146, 224, 174, 170, 224, 175, 128, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 175, 141, 20, 13, 4, 95, 51, 67, 15, 65, 40, 50, 50, 123, 51, 0, 0, 13, 4, 95, 4, 16, 20, 10, 48, 40, 62, 62, 37, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 224, 174, 149, 224, 174, 169, 20, 11, 4, 95, 49, 48, 15, 48, 35, 47, 47, 0, 0, 0, 0, 0, 0, 9, 134, 224, 174, 149, 224, 174, 174, 20, 0, 0, 24, 149, 224, 174, 164, 224, 174, 159, 224, 174, 191, 224, 174, 175, 224, 174, 190, 224, 174, 175, 224, 175, 141, 20, 21, 146, 224, 174, 170, 224, 174, 181, 224, 175, 129, 224, 174, 164, 224, 175, 141, 224, 174, 164, 20, 0, 0, 18, 143, 224, 174, 149, 224, 174, 174, 224, 175, 141, 224, 174, 169, 224, 175, 129, 20, 0, 0, 0, 0, 0, 27, 152, 224, 174, 149, 224, 175, 135, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 169, 224, 175, 141, 20, 27, 152, 224, 174, 164, 224, 174, 181, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 169, 224, 175, 141, 20, 14, 5, 95, 48, 77, 50, 24, 55, 109, 141, 76, 109, 65, 0, 0, 24, 149, 224, 174, 149, 224, 174, 174, 224, 175, 141, 224, 174, 174, 224, 175, 129, 224, 174, 169, 224, 175, 129, 20, 0, 16, 4, 95, 49, 50, 15, 48, 109, 50, 50, 37, 34, 109, 66, 141, 0, 0, 0, 23, 15, 224, 174, 170, 224, 175, 139, 224, 174, 169, 224, 175, 141, 224, 174, 178, 83, 119, 50, 55, 109, 0, 0, 0, 0, 0, 30, 6, 224, 174, 149, 224, 174, 191, 49, 37, 55, 119, 65, 112, 140, 140, 109, 34, 0, 24, 82, 46, 32, 224, 174, 174, 224, 175, 128, 32, 0, 0, 33, 158, 224, 174, 149, 224, 175, 129, 224, 174, 174, 224, 175, 141, 224, 174, 174, 224, 175, 129, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 175, 129, 20, 21, 146, 224, 174, 164, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 20, 0, 0, 0, 15, 140, 224, 174, 164, 224, 174, 176, 224, 175, 129, 224, 174, 174, 20, 24, 149, 224, 174, 170, 224, 174, 190, 224, 174, 181, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 20, 0, 27, 152, 224, 174, 164, 224, 175, 128, 224, 174, 176, 224, 174, 174, 224, 175, 129, 224, 174, 179, 224, 175, 141, 224, 174, 179, 20, 0, 12, 137, 224, 174, 149, 224, 175, 129, 224, 174, 163, 20, 0, 0, 0, 0, 24, 149, 224, 174, 164, 224, 175, 128, 224, 174, 170, 224, 174, 190, 224, 174, 181, 224, 174, 179, 224, 174, 191, 20, 0, 0, 0, 0, 0, 0, 14, 5, 95, 48, 77, 49, 24, 118, 57, 37, 34, 109, 65, 0, 0, 21, 146, 224, 174, 170, 224, 175, 139, 224, 174, 175, 224, 174, 191, 224, 174, 153, 224, 175, 141, 20, 20, 67, 28, 36, 0, 71, 34, 6, 37, 47, 37, 91, 15, 48, 6, 135, 50, 72, 88, 0, 0, 0, 15, 140, 224, 174, 164, 224, 174, 191, 224, 174, 159, 224, 175, 129, 20, 0, 0, 15, 140, 224, 174, 170, 224, 174, 190, 224, 174, 181, 224, 175, 135, 20, 0, 42, 167, 224, 174, 170, 224, 174, 178, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 190, 224, 174, 169, 224, 175, 141, 20, 0, 27, 152, 224, 174, 170, 224, 174, 178, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 169, 224, 175, 141, 20, 0, 0, 21, 146, 224, 174, 149, 224, 174, 190, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 175, 129, 20, 0, 15, 140, 224, 174, 149, 224, 174, 153, 224, 175, 141, 224, 174, 149, 20, 0, 27, 152, 224, 174, 149, 224, 175, 139, 224, 174, 170, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 20, 27, 152, 224, 174, 149, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 175, 129, 20, 14, 4, 95, 51, 67, 48, 65, 40, 50, 50, 123, 51, 122, 0, 0, 0, 0, 0, 0, 12, 4, 95, 52, 67, 15, 50, 118, 50, 123, 51, 0, 12, 5, 95, 48, 77, 51, 24, 49, 119, 141, 37, 0, 0, 0, 24, 149, 224, 174, 170, 224, 175, 136, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 178, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 12, 224, 174, 137, 224, 174, 170, 224, 175, 141, 224, 174, 170, 40, 71, 71, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 140, 224, 174, 170, 224, 174, 190, 224, 174, 183, 224, 174, 190, 20, 0, 20, 67, 73, 80, 128, 34, 6, 109, 91, 109, 50, 15, 34, 6, 123, 71, 109, 55, 88, 0, 0, 9, 3, 95, 49, 15, 39, 50, 51, 0, 0, 0, 0, 18, 12, 224, 174, 170, 224, 174, 191, 224, 174, 159, 224, 175, 141, 71, 37, 140, 0, 15, 140, 224, 174, 170, 224, 174, 191, 224, 174, 159, 224, 175, 141, 20, 0, 0, 0, 0, 0, 11, 3, 95, 50, 15, 37, 34, 109, 66, 141, 0, 13, 4, 95, 52, 67, 48, 50, 118, 50, 123, 51, 122, 0, 0, 0, 0, 0, 0, 27, 152, 224, 174, 164, 224, 175, 129, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 175, 129, 224, 174, 181, 224, 174, 191, 20, 11, 4, 95, 53, 67, 15, 134, 50, 123, 51, 0, 0, 0, 0, 10, 3, 95, 51, 15, 65, 123, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 140, 224, 174, 164, 224, 174, 190, 224, 174, 169, 224, 175, 129, 20, 13, 3, 95, 50, 48, 37, 34, 122, 71, 109, 72, 122, 0, 0, 0, 0, 0, 27, 152, 224, 174, 170, 224, 175, 139, 224, 174, 169, 224, 175, 141, 224, 174, 154, 224, 174, 190, 224, 174, 175, 224, 175, 141, 20, 0, 9, 3, 95, 53, 15, 134, 50, 72, 0, 0, 0, 0, 18, 12, 224, 174, 154, 224, 175, 134, 224, 174, 159, 224, 175, 141, 89, 36, 140, 0, 27, 152, 224, 174, 170, 224, 175, 134, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 169, 224, 175, 141, 20, 13, 3, 95, 51, 48, 65, 40, 48, 48, 109, 72, 122, 0, 0, 0, 0, 0, 15, 140, 224, 174, 149, 224, 175, 140, 224, 174, 169, 224, 175, 141, 20, 0, 8, 3, 95, 54, 15, 118, 51, 0, 0, 0, 18, 143, 224, 174, 164, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 181, 20, 0, 0, 0, 0, 0, 0, 9, 3, 95, 55, 15, 38, 114, 92, 0, 0, 0, 0, 0, 0, 0, 0, 18, 143, 224, 174, 170, 224, 175, 139, 224, 174, 164, 224, 174, 169, 224, 175, 136, 20, 0, 0, 0, 21, 146, 224, 174, 164, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 169, 224, 175, 136, 20, 0, 14, 3, 95, 51, 88, 65, 40, 48, 48, 109, 47, 47, 122, 0, 13, 3, 95, 54, 48, 35, 51, 122, 71, 109, 72, 122, 0, 0, 0, 0, 21, 146, 224, 174, 164, 224, 175, 128, 224, 174, 149, 224, 175, 141, 224, 174, 183, 224, 175, 136, 20, 0, 0, 11, 3, 95, 57, 15, 39, 50, 71, 109, 141, 0, 0, 15, 140, 224, 174, 164, 224, 174, 190, 224, 174, 181, 224, 175, 135, 20, 0, 0, 14, 3, 95, 55, 48, 38, 36, 92, 122, 71, 109, 72, 122, 0, 0, 24, 149, 224, 174, 170, 224, 174, 178, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 20, 12, 3, 95, 49, 67, 50, 123, 140, 140, 51, 37, 0, 0, 0, 0, 0, 12, 4, 95, 53, 67, 48, 134, 50, 123, 51, 122, 0, 0, 18, 143, 224, 174, 170, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 178, 20, 0, 16, 3, 95, 49, 57, 48, 35, 47, 47, 39, 50, 71, 109, 72, 122, 0, 0, 0, 15, 3, 95, 50, 67, 37, 34, 122, 50, 123, 140, 140, 51, 37, 0, 0, 13, 4, 95, 54, 67, 15, 35, 51, 122, 50, 123, 51, 0, 0, 0, 0, 0, 24, 149, 224, 174, 149, 224, 175, 139, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 20, 15, 140, 224, 174, 170, 224, 174, 181, 224, 174, 169, 224, 174, 191, 20, 0, 15, 3, 95, 49, 49, 48, 35, 47, 37, 50, 39, 50, 51, 122, 0, 0, 11, 3, 95, 49, 48, 48, 35, 47, 47, 122, 0, 0, 15, 3, 95, 51, 67, 65, 40, 50, 50, 123, 140, 140, 51, 37, 0, 0, 13, 4, 95, 52, 48, 15, 50, 118, 51, 48, 109, 72, 0, 16, 3, 95, 49, 50, 48, 109, 50, 50, 37, 34, 109, 66, 141, 122, 0, 0, 0, 0, 10, 3, 95, 52, 15, 50, 118, 50, 81, 0, 0, 0, 0, 15, 3, 95, 55, 88, 38, 36, 92, 122, 71, 109, 47, 47, 122, 0, 0, 14, 3, 95, 52, 67, 50, 118, 50, 123, 140, 140, 51, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 53, 67, 134, 50, 123, 140, 140, 51, 37, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 52, 48, 50, 118, 51, 48, 109, 72, 122, 0, 11, 3, 95, 49, 88, 48, 35, 72, 37, 50, 0, 0, 15, 3, 95, 54, 67, 35, 51, 122, 50, 123, 140, 140, 51, 37, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 50, 88, 37, 34, 122, 71, 109, 47, 47, 122, 0, 12, 3, 95, 53, 48, 134, 65, 71, 109, 72, 122, 0, 0, 16, 3, 95, 55, 67, 38, 36, 92, 122, 50, 123, 140, 140, 51, 37, 0, 0, 0, 0, 0, 10, 3, 95, 56, 15, 38, 36, 140, 140, 0, 0, 0, 0, 0, 19, 12, 224, 174, 154, 224, 175, 128, 224, 174, 154, 224, 175, 128, 76, 112, 76, 112, 0, 15, 3, 95, 56, 67, 38, 36, 66, 66, 123, 140, 140, 51, 37, 0, 0, 0, 0, 0, 16, 3, 95, 63, 63, 49, 40, 51, 37, 57, 4, 112, 141, 122, 10, 0, 0, 0, 18, 143, 224, 174, 164, 224, 174, 175, 224, 174, 190, 224, 174, 179, 224, 175, 129, 20, 0, 28, 18, 224, 174, 159, 224, 174, 191, 224, 174, 170, 224, 175, 129, 224, 174, 159, 224, 174, 191, 141, 116, 48, 57, 122, 140, 37, 0, 14, 3, 95, 52, 88, 50, 118, 51, 48, 109, 47, 47, 122, 0, 0, 18, 3, 95, 57, 67, 47, 39, 62, 62, 118, 57, 37, 34, 109, 47, 47, 122, 0, 8, 3, 224, 174, 143, 57, 114, 0, 0, 0, 0, 18, 12, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 72, 37, 49, 0, 15, 140, 224, 174, 149, 224, 175, 135, 224, 174, 159, 224, 175, 141, 20, 15, 140, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 20, 15, 140, 224, 174, 170, 224, 174, 159, 224, 175, 129, 224, 174, 149, 20, 0, 14, 4, 95, 54, 67, 48, 35, 51, 122, 50, 123, 51, 122, 0, 0, 21, 146, 224, 174, 170, 224, 174, 190, 224, 174, 175, 224, 175, 141, 224, 174, 184, 224, 175, 141, 20, 0, 18, 143, 224, 174, 149, 224, 174, 179, 224, 174, 191, 224, 174, 178, 224, 175, 141, 20, 18, 143, 224, 174, 170, 224, 174, 178, 224, 174, 191, 224, 174, 149, 224, 175, 141, 20, 10, 3, 224, 175, 141, 39, 140, 51, 122, 0, 0, 13, 3, 95, 53, 88, 134, 65, 71, 109, 47, 47, 122, 0, 13, 3, 95, 56, 48, 38, 36, 66, 71, 109, 72, 122, 0, 8, 3, 224, 175, 140, 148, 135, 0, 0, 0, 14, 4, 95, 55, 67, 15, 38, 36, 92, 122, 50, 123, 51, 0, 11, 6, 224, 174, 159, 224, 175, 141, 37, 140, 0, 0, 0, 8, 3, 224, 175, 136, 148, 134, 0, 0, 9, 3, 224, 175, 139, 148, 119, 12, 0, 9, 3, 224, 174, 131, 109, 81, 108, 0, 0, 8, 3, 224, 175, 138, 18, 39, 0, 14, 3, 224, 174, 130, 109, 50, 122, 89, 84, 109, 51, 109, 0, 12, 6, 224, 174, 153, 224, 175, 141, 37, 68, 81, 0, 0, 0, 15, 140, 224, 174, 149, 224, 174, 191, 224, 174, 176, 224, 175, 141, 20, 33, 24, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 72, 37, 81, 72, 37, 81, 0, 14, 3, 95, 54, 88, 35, 51, 122, 71, 109, 47, 47, 122, 0, 13, 3, 95, 57, 48, 47, 39, 66, 66, 123, 51, 122, 0, 0, 9, 3, 224, 175, 135, 148, 114, 12, 0, 0, 12, 4, 95, 53, 48, 15, 134, 65, 71, 109, 72, 0, 8, 3, 224, 175, 134, 18, 36, 0, 0, 18, 143, 224, 174, 170, 224, 175, 139, 224, 174, 169, 224, 174, 184, 224, 175, 141, 20, 8, 3, 224, 175, 129, 18, 40, 0, 0, 9, 3, 224, 175, 128, 148, 112, 12, 0, 0, 0, 9, 3, 224, 175, 130, 148, 123, 12, 0, 0, 0, 18, 143, 224, 174, 149, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 20, 18, 143, 224, 174, 170, 224, 174, 178, 224, 174, 164, 224, 175, 141, 224, 174, 164, 20, 0, 0, 18, 12, 224, 174, 149, 224, 174, 191, 224, 174, 176, 224, 175, 135, 81, 34, 114, 0, 11, 6, 224, 174, 163, 224, 175, 141, 37, 66, 0, 0, 11, 3, 224, 175, 185, 34, 123, 71, 118, 57, 0, 0, 0, 0, 21, 146, 224, 174, 164, 224, 175, 138, 224, 174, 170, 224, 175, 141, 224, 174, 169, 224, 175, 129, 20, 0, 0, 27, 152, 224, 174, 154, 224, 174, 191, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 190, 224, 174, 175, 224, 175, 141, 20, 15, 140, 224, 174, 170, 224, 175, 130, 224, 174, 159, 224, 175, 141, 20, 14, 3, 95, 56, 88, 38, 36, 66, 71, 109, 47, 47, 122, 0, 0, 0, 0, 18, 143, 224, 174, 170, 224, 174, 178, 224, 174, 149, 224, 175, 141, 224, 174, 149, 20, 0, 18, 12, 224, 174, 170, 224, 175, 136, 224, 174, 149, 224, 175, 141, 71, 134, 49, 0, 0, 0, 26, 18, 224, 174, 164, 224, 174, 190, 224, 174, 153, 224, 175, 141, 224, 174, 184, 224, 175, 141, 87, 118, 68, 49, 89, 0, 0, 18, 143, 224, 174, 149, 224, 174, 181, 224, 175, 129, 224, 174, 169, 224, 175, 141, 20, 30, 155, 224, 174, 164, 224, 175, 128, 224, 174, 176, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 139, 224, 174, 159, 224, 175, 129, 20, 18, 143, 224, 174, 170, 224, 174, 178, 224, 175, 141, 224, 174, 170, 224, 175, 141, 20, 0, 27, 152, 224, 174, 149, 224, 175, 129, 224, 174, 174, 224, 175, 141, 224, 174, 174, 224, 175, 129, 224, 174, 169, 224, 175, 129, 20, 15, 3, 95, 57, 88, 47, 39, 66, 66, 123, 140, 140, 51, 122, 0, 0, 0, 11, 6, 224, 174, 175, 224, 175, 141, 37, 57, 0, 0, 0, 15, 9, 224, 174, 134, 224, 174, 149, 224, 174, 190, 118, 108, 118, 0, 0, 0, 15, 140, 224, 174, 149, 224, 174, 191, 224, 174, 178, 224, 174, 191, 20, 19, 12, 224, 174, 159, 224, 174, 191, 224, 174, 181, 224, 174, 191, 140, 37, 84, 37, 0, 11, 6, 224, 174, 177, 224, 175, 141, 37, 51, 0, 11, 6, 224, 174, 169, 224, 175, 141, 37, 50, 0, 0, 15, 140, 224, 174, 164, 224, 175, 135, 224, 174, 181, 224, 174, 190, 20, 0, 36, 24, 224, 174, 170, 224, 174, 190, 224, 174, 164, 224, 174, 176, 224, 175, 129, 224, 174, 159, 224, 174, 169, 224, 175, 141, 83, 118, 72, 109, 34, 122, 141, 109, 50, 0, 0, 0, 0, 0, 0, 0, 27, 152, 224, 174, 164, 224, 174, 191, 224, 174, 176, 224, 175, 129, 224, 174, 183, 224, 175, 141, 224, 174, 159, 224, 174, 191, 20, 0, 18, 143, 224, 174, 164, 224, 174, 178, 224, 174, 190, 224, 174, 175, 224, 175, 141, 20, 0, 0, 0, 21, 146, 224, 174, 164, 224, 174, 159, 224, 174, 191, 224, 174, 175, 224, 174, 169, 224, 175, 141, 20, 0, 0, 15, 140, 224, 174, 154, 224, 174, 190, 224, 174, 176, 224, 175, 129, 20, 0, 24, 149, 224, 174, 164, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 181, 224, 174, 174, 224, 175, 141, 20, 11, 6, 224, 174, 179, 224, 175, 141, 37, 62, 0, 0, 0, 0, 33, 24, 224, 174, 170, 224, 175, 136, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 178, 224, 175, 141, 71, 134, 49, 49, 113, 55, 0, 0, 0, 21, 146, 224, 174, 170, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 20, 0, 0, 21, 146, 224, 174, 149, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 181, 224, 175, 135, 20, 0, 24, 149, 224, 174, 149, 224, 174, 179, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 20, 0, 15, 4, 95, 55, 67, 48, 38, 36, 92, 122, 50, 123, 51, 122, 0, 0, 24, 149, 224, 174, 149, 224, 174, 179, 224, 174, 191, 224, 174, 178, 224, 175, 135, 224, 174, 175, 224, 175, 135, 20, 0, 0, 13, 4, 95, 56, 67, 15, 38, 36, 66, 66, 123, 51, 0, 0, 18, 143, 224, 174, 170, 224, 175, 136, 224, 174, 149, 224, 175, 141, 224, 174, 149, 20, 0, 0, 24, 149, 224, 174, 170, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 176, 224, 175, 141, 20, 0, 0, 33, 158, 224, 174, 149, 224, 175, 135, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 20, 33, 158, 224, 174, 149, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 181, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 20, 33, 158, 224, 174, 170, 224, 175, 130, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 20, 0, 9, 3, 224, 174, 190, 148, 118, 12, 0, 0, 18, 143, 224, 174, 170, 224, 174, 190, 224, 174, 178, 224, 174, 191, 224, 174, 175, 20, 8, 3, 224, 174, 191, 18, 37, 0, 0, 0, 0, 11, 6, 224, 174, 159, 224, 174, 191, 140, 37, 0, 0, 15, 4, 95, 48, 77, 50, 55, 109, 141, 76, 109, 47, 47, 122, 0, 0, 27, 152, 224, 174, 170, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 169, 224, 174, 191, 20, 12, 4, 95, 48, 77, 51, 49, 119, 141, 37, 114, 0, 0, 0, 21, 146, 224, 174, 170, 224, 175, 128, 224, 174, 176, 224, 174, 190, 224, 174, 174, 224, 174, 163, 20, 15, 4, 95, 48, 77, 49, 118, 57, 37, 34, 109, 47, 47, 122, 0, 0, 0, 15, 140, 224, 174, 149, 224, 174, 191, 224, 174, 176, 224, 174, 191, 20, 0, 0, 18, 143, 224, 174, 164, 224, 174, 159, 224, 174, 191, 224, 174, 175, 224, 174, 190, 20, 0, 0, 0, 0, 0, 0, 0, 24, 149, 224, 174, 149, 224, 174, 190, 224, 174, 175, 224, 174, 164, 224, 175, 141, 224, 174, 176, 224, 174, 191, 20, 0, 18, 143, 224, 174, 170, 224, 175, 136, 224, 174, 149, 224, 175, 141, 224, 174, 178, 20, 0, 0, 12, 137, 224, 174, 170, 224, 174, 159, 224, 174, 190, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 146, 224, 174, 170, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 140, 224, 174, 154, 224, 174, 191, 224, 174, 178, 224, 174, 191, 20, 11, 6, 224, 174, 184, 224, 175, 141, 37, 89, 0, 0, 0, 18, 143, 224, 174, 170, 224, 174, 159, 224, 175, 129, 224, 174, 181, 224, 174, 190, 20, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 56, 67, 48, 38, 36, 66, 66, 123, 51, 122, 0, 0, 0, 0, 0, 23, 15, 224, 174, 154, 224, 174, 191, 224, 174, 176, 224, 174, 174, 224, 175, 141, 89, 37, 34, 109, 65, 0, 0, 0, 0, 0, 0, 32, 20, 95, 35, 224, 174, 181, 224, 174, 164, 224, 175, 129, 224, 174, 174, 224, 174, 190, 224, 174, 149, 118, 84, 109, 72, 122, 65, 118, 81, 109, 0, 0, 0, 0, 0, 0, 0, 0, 23, 68, 80, 19, 73, 48, 224, 174, 164, 224, 174, 174, 224, 174, 191, 224, 174, 180, 224, 175, 141, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 24, 224, 174, 170, 224, 174, 190, 224, 174, 164, 224, 174, 176, 224, 174, 191, 224, 174, 159, 224, 174, 174, 224, 175, 141, 83, 118, 72, 109, 34, 37, 141, 109, 65, 0, 27, 152, 224, 174, 164, 224, 175, 129, 224, 174, 181, 224, 174, 174, 224, 175, 141, 224, 174, 154, 224, 174, 174, 224, 175, 141, 20, 27, 152, 224, 174, 170, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 170, 224, 175, 141, 20, 0, 0, 0, 0, 27, 152, 224, 174, 164, 224, 175, 138, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 129, 224, 174, 169, 224, 175, 129, 20, 0, 0, 18, 67, 12, 230, 64, 76, 6, 134, 50, 112, 88, 15, 57, 6, 40, 109, 50, 0, 0, 0, 0, 0, 21, 146, 224, 174, 164, 224, 174, 176, 224, 175, 129, 224, 174, 174, 224, 174, 174, 224, 175, 141, 20, 21, 146, 224, 174, 170, 224, 174, 163, 224, 175, 141, 224, 174, 164, 224, 174, 174, 224, 175, 141, 20, 21, 146, 224, 174, 170, 224, 174, 190, 224, 174, 176, 224, 174, 164, 224, 174, 174, 224, 175, 141, 20, 0, 0, 0, 0, 0, 19, 12, 224, 174, 170, 224, 175, 136, 224, 174, 178, 224, 175, 136, 83, 134, 55, 134, 0, 0, 18, 12, 224, 174, 170, 224, 175, 129, 224, 174, 159, 224, 175, 141, 83, 40, 141, 0, 15, 140, 224, 174, 149, 224, 175, 129, 224, 174, 159, 224, 175, 141, 20, 0, 14, 9, 95, 35, 45, 224, 174, 178, 224, 175, 141, 37, 55, 0, 0, 0, 18, 143, 224, 174, 170, 224, 174, 149, 224, 174, 181, 224, 174, 164, 224, 175, 141, 20, 0, 18, 12, 224, 174, 170, 224, 175, 136, 224, 174, 178, 224, 175, 141, 83, 134, 55, 0, 15, 140, 224, 174, 164, 224, 174, 169, 224, 174, 174, 224, 175, 141, 20, 15, 140, 224, 174, 170, 224, 175, 129, 224, 174, 149, 224, 175, 141, 20, 0, 0, 0, 18, 143, 224, 174, 164, 224, 175, 134, 224, 174, 169, 224, 174, 174, 224, 175, 141, 20, 12, 137, 224, 174, 170, 224, 174, 178, 224, 175, 135, 20, 0, 0, 15, 140, 224, 174, 164, 224, 174, 174, 224, 175, 141, 224, 174, 174, 20, 24, 149, 224, 174, 170, 224, 175, 141, 224, 174, 175, 224, 175, 130, 224, 174, 169, 224, 174, 184, 224, 175, 141, 20, 0, 25, 18, 224, 174, 170, 224, 174, 191, 224, 174, 176, 224, 175, 135, 224, 174, 149, 224, 175, 141, 71, 34, 114, 49, 0, 27, 18, 95, 35, 45, 224, 174, 181, 224, 174, 164, 224, 175, 129, 224, 174, 174, 224, 175, 141, 118, 84, 109, 72, 122, 65, 0, 0, 0, 27, 152, 224, 174, 170, 224, 175, 141, 224, 174, 176, 224, 174, 190, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 175, 141, 20, 27, 152, 224, 174, 170, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 164, 224, 175, 141, 20, 0, 0, 0, 0, 23, 15, 224, 174, 170, 224, 175, 135, 224, 174, 169, 224, 175, 141, 224, 174, 178, 83, 114, 50, 55, 109, 0, 0, 0, 0, 17, 4, 95, 57, 67, 48, 47, 39, 62, 62, 118, 57, 37, 34, 109, 65, 0, 0, 0, 0, 0, 12, 137, 224, 174, 170, 224, 174, 178, 224, 174, 191, 20, 0, 0, 0, 0, 0, 21, 146, 224, 174, 170, 224, 175, 130, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 191, 20, 12, 137, 224, 174, 170, 224, 174, 176, 224, 174, 164, 20, 21, 146, 224, 174, 170, 224, 175, 129, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 20, 0, 24, 149, 224, 174, 170, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 20, 0, 13, 4, 95, 56, 48, 15, 38, 36, 66, 71, 109, 72, 0, 0, 0, 0, 0, 12, 137, 224, 174, 149, 224, 174, 175, 224, 174, 190, 20, 0, 0, 0, 12, 137, 224, 174, 164, 224, 174, 190, 224, 174, 169, 20, 0, 0, 0, 0, 0, 12, 137, 224, 174, 170, 224, 174, 190, 224, 174, 178, 20, 0, 0, 12, 137, 224, 174, 170, 224, 174, 190, 224, 174, 176, 20, 0, 0, 0, 0, 0, 0, 12, 137, 224, 174, 170, 224, 174, 190, 224, 174, 170, 20, 0, 0, 0, 12, 137, 224, 174, 170, 224, 174, 190, 224, 174, 169, 20, 0, 19, 67, 41, 6, 64, 75, 6, 118, 48, 109, 50, 112, 88, 15, 57, 6, 36, 50, 0, 0, 0, 0, 24, 149, 224, 174, 164, 224, 175, 128, 224, 174, 176, 224, 174, 174, 224, 174, 177, 224, 175, 141, 224, 174, 177, 20, 0, 0, 0, 27, 152, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 177, 224, 175, 141, 224, 174, 177, 20, 0, 18, 143, 224, 174, 170, 224, 174, 190, 224, 174, 178, 224, 175, 141, 224, 174, 175, 20, 0, 0, 0, 0, 0, 0, 0, 0, 15, 140, 224, 174, 170, 224, 175, 128, 224, 174, 159, 224, 174, 190, 20, 0, 15, 140, 224, 174, 170, 224, 175, 128, 224, 174, 159, 224, 174, 191, 20, 15, 140, 224, 174, 170, 224, 175, 139, 224, 174, 164, 224, 174, 191, 20, 0, 0, 15, 140, 224, 174, 170, 224, 174, 190, 224, 174, 178, 224, 175, 129, 20, 0, 0, 0, 11, 2, 194, 190, 65, 40, 49, 49, 118, 55, 0, 0, 26, 18, 224, 174, 176, 224, 175, 134, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 34, 36, 141, 141, 37, 0, 18, 143, 224, 174, 170, 224, 174, 159, 224, 175, 129, 224, 174, 149, 224, 174, 190, 20, 13, 2, 195, 183, 84, 109, 81, 122, 47, 47, 109, 55, 0, 0, 8, 2, 194, 188, 49, 118, 55, 0, 0, 8, 2, 194, 189, 35, 34, 134, 0, 11, 6, 224, 174, 182, 224, 175, 141, 37, 91, 0, 0, 21, 146, 224, 174, 170, 224, 174, 190, 224, 174, 181, 224, 175, 141, 224, 174, 178, 224, 174, 190, 20, 0, 13, 8, 95, 35, 224, 174, 174, 224, 175, 141, 118, 65, 0, 0, 0, 0, 0, 15, 140, 224, 174, 164, 224, 174, 190, 224, 174, 178, 224, 175, 141, 20, 18, 12, 224, 174, 170, 224, 175, 128, 224, 174, 178, 224, 175, 141, 83, 112, 55, 0, 0, 0, 0, 18, 143, 224, 174, 170, 224, 174, 190, 224, 174, 163, 224, 174, 174, 224, 175, 141, 20, 0, 0, 0, 0, 0, 0, 24, 149, 224, 174, 170, 224, 174, 190, 224, 174, 149, 224, 174, 181, 224, 174, 164, 224, 174, 174, 224, 175, 141, 20, 33, 21, 95, 35, 45, 224, 174, 181, 224, 174, 164, 224, 175, 129, 224, 174, 174, 224, 174, 190, 224, 174, 149, 118, 84, 109, 72, 122, 65, 118, 81, 109, 0, 0, 13, 4, 95, 57, 48, 15, 47, 39, 66, 66, 123, 51, 0, 18, 67, 85, 49, 0, 57, 6, 40, 36, 89, 15, 72, 6, 39, 55, 109, 88, 0, 0, 0, 0, 14, 9, 224, 174, 134, 224, 174, 170, 224, 175, 141, 118, 83, 0, 0, 0, 0, 15, 140, 224, 174, 149, 224, 174, 169, 224, 174, 174, 224, 175, 141, 20, 0, 0, 21, 146, 224, 174, 170, 224, 175, 134, 224, 174, 169, 224, 175, 141, 224, 174, 184, 224, 175, 141, 20, 0, 0, 0, 26, 17, 95, 35, 224, 174, 181, 224, 174, 164, 224, 175, 129, 224, 174, 174, 224, 175, 141, 118, 84, 109, 72, 122, 65, 0, 0, 0, 12, 137, 224, 174, 164, 224, 175, 138, 224, 174, 179, 20, 0, 51, 36, 224, 174, 170, 224, 174, 190, 224, 174, 164, 224, 174, 176, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 190, 224, 174, 174, 224, 174, 178, 224, 175, 141, 83, 118, 72, 109, 34, 37, 55, 55, 118, 65, 109, 55, 0, 0, 24, 149, 224, 174, 149, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 174, 224, 175, 141, 20, 0, 0, 0, 27, 152, 224, 174, 170, 224, 174, 178, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 129, 224, 174, 174, 224, 175, 141, 20, 27, 152, 224, 174, 170, 224, 174, 181, 224, 175, 129, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 174, 224, 175, 141, 20, 0, 0, 0, 0, 0, 0, 15, 140, 224, 174, 170, 224, 174, 191, 224, 174, 184, 224, 174, 191, 20, 0, 18, 143, 224, 174, 164, 224, 174, 190, 224, 174, 175, 224, 174, 174, 224, 175, 141, 20, 0, 0, 15, 140, 224, 174, 170, 224, 174, 190, 224, 174, 178, 224, 174, 190, 20, 0, 25, 18, 224, 174, 159, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 154, 224, 175, 141, 140, 118, 34, 76, 0, 0, 0, 0, 0, 0, 0, 21, 146, 224, 174, 149, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 191, 20, 21, 146, 224, 174, 170, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 178, 224, 174, 191, 20, 13, 8, 95, 35, 224, 174, 178, 224, 175, 141, 37, 55, 0, 0, 0, 0, 0, 15, 140, 224, 174, 170, 224, 174, 191, 224, 174, 178, 224, 175, 141, 20, 0, 0, 33, 158, 224, 174, 164, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 174, 163, 224, 175, 141, 224, 174, 175, 224, 174, 174, 224, 175, 141, 20, 0, 18, 143, 224, 174, 170, 224, 174, 190, 224, 174, 149, 224, 174, 174, 224, 175, 141, 20, 0, 15, 140, 224, 174, 170, 224, 174, 190, 224, 174, 170, 224, 175, 129, 20, 0, 0, 26, 18, 224, 174, 170, 224, 175, 135, 224, 174, 169, 224, 174, 191, 224, 174, 178, 224, 175, 141, 83, 114, 50, 37, 55, 0, 26, 18, 224, 174, 170, 224, 175, 139, 224, 174, 169, 224, 174, 191, 224, 174, 178, 224, 175, 141, 83, 119, 50, 37, 55, 0, 0, 33, 158, 224, 174, 170, 224, 175, 139, 224, 174, 176, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 190, 224, 174, 174, 20, 0, 0, 24, 149, 224, 174, 154, 224, 175, 134, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 174, 224, 175, 141, 20, 0, 0, 0, 27, 152, 224, 174, 149, 224, 175, 135, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 178, 224, 175, 141, 20, 27, 152, 224, 174, 164, 224, 174, 181, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 178, 224, 175, 141, 20, 27, 152, 224, 174, 170, 224, 174, 178, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 178, 224, 175, 141, 20, 0, 17, 5, 95, 49, 77, 50, 24, 39, 34, 122, 55, 109, 141, 76, 109, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 5, 95, 49, 77, 51, 24, 39, 34, 122, 49, 119, 141, 37, 0, 0, 19, 12, 224, 174, 170, 224, 174, 190, 224, 174, 170, 224, 174, 190, 71, 118, 71, 118, 0, 15, 140, 224, 174, 170, 224, 174, 190, 224, 174, 170, 224, 174, 190, 20, 0, 0, 39, 164, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 134, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 175, 129, 224, 174, 174, 224, 175, 141, 20, 11, 2, 95, 34, 65, 114, 51, 81, 119, 62, 0, 0, 0, 0, 17, 2, 95, 39, 39, 140, 51, 134, 15, 65, 6, 114, 51, 81, 119, 62, 0, 0, 0, 13, 4, 95, 50, 48, 15, 37, 34, 122, 71, 109, 72, 0, 0, 0, 0, 14, 4, 95, 3, 1, 16, 49, 35, 48, 37, 140, 109, 55, 0, 0, 14, 2, 95, 41, 84, 109, 55, 109, 15, 48, 37, 51, 134, 0, 0, 13, 2, 95, 40, 37, 141, 109, 15, 48, 37, 51, 134, 0, 0, 0, 16, 2, 95, 46, 65, 40, 140, 51, 122, 15, 48, 40, 62, 62, 37, 0, 0, 12, 2, 95, 45, 37, 66, 134, 48, 48, 122, 81, 0, 0, 14, 2, 95, 44, 49, 118, 55, 15, 48, 40, 62, 62, 37, 0, 0, 10, 2, 95, 51, 65, 123, 50, 51, 122, 0, 0, 11, 2, 95, 50, 37, 34, 109, 66, 141, 122, 0, 0, 9, 2, 95, 49, 39, 50, 51, 122, 0, 0, 12, 2, 95, 48, 89, 40, 92, 37, 57, 109, 65, 0, 0, 9, 2, 95, 55, 38, 114, 92, 122, 0, 0, 8, 2, 95, 54, 118, 51, 122, 0, 0, 9, 2, 95, 53, 134, 50, 72, 122, 0, 0, 10, 2, 95, 52, 50, 118, 50, 81, 122, 0, 0, 15, 2, 95, 59, 118, 34, 134, 71, 15, 48, 40, 62, 62, 37, 0, 0, 17, 2, 95, 58, 65, 40, 49, 49, 118, 55, 15, 48, 40, 62, 62, 37, 0, 0, 11, 2, 95, 57, 39, 50, 71, 109, 141, 122, 0, 0, 18, 12, 224, 174, 170, 224, 174, 191, 224, 174, 176, 224, 174, 190, 71, 34, 118, 0, 10, 2, 95, 56, 38, 36, 140, 140, 122, 0, 0, 10, 2, 95, 63, 49, 114, 62, 84, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 140, 224, 174, 170, 224, 174, 190, 224, 174, 174, 224, 174, 190, 20, 0, 0, 0, 0, 24, 149, 224, 174, 164, 224, 174, 175, 224, 174, 190, 224, 174, 168, 224, 174, 191, 224, 174, 164, 224, 174, 191, 20, 0, 0, 0, 0, 0, 15, 140, 224, 174, 164, 224, 174, 191, 224, 174, 174, 224, 175, 141, 20, 16, 2, 95, 91, 37, 141, 109, 15, 89, 35, 72, 122, 34, 109, 65, 0, 0, 0, 0, 18, 143, 224, 174, 170, 224, 174, 178, 224, 174, 174, 224, 174, 190, 224, 174, 149, 20, 0, 14, 2, 95, 95, 35, 141, 37, 81, 15, 49, 119, 141, 122, 0, 0, 0, 17, 2, 95, 93, 84, 109, 55, 109, 15, 89, 35, 72, 122, 34, 109, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 51, 48, 15, 65, 40, 48, 48, 109, 72, 0, 0, 0, 15, 140, 224, 174, 170, 224, 174, 178, 224, 174, 174, 224, 175, 141, 20, 0, 0, 15, 140, 224, 174, 149, 224, 175, 141, 224, 174, 176, 224, 175, 135, 20, 0, 0, 0, 0, 21, 146, 224, 174, 170, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 174, 224, 175, 141, 20, 21, 146, 224, 174, 170, 224, 174, 190, 224, 174, 164, 224, 174, 190, 224, 174, 174, 224, 175, 141, 20, 0, 0, 0, 24, 149, 224, 174, 164, 224, 174, 176, 224, 174, 191, 224, 174, 154, 224, 174, 169, 224, 174, 174, 224, 175, 141, 20, 0, 0, 21, 146, 224, 174, 154, 224, 175, 128, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 175, 128, 20, 0, 0, 0, 33, 158, 224, 174, 170, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 174, 179, 224, 174, 191, 224, 174, 174, 224, 174, 190, 224, 174, 184, 224, 175, 141, 20, 0, 0, 18, 12, 224, 174, 164, 224, 175, 128, 224, 174, 170, 224, 175, 141, 72, 112, 48, 0, 15, 140, 224, 174, 149, 224, 174, 159, 224, 174, 174, 224, 175, 141, 20, 14, 2, 95, 123, 37, 141, 109, 15, 81, 109, 66, 109, 65, 0, 0, 0, 0, 18, 143, 224, 174, 170, 224, 174, 176, 224, 174, 164, 224, 174, 174, 224, 175, 141, 20, 0, 0, 0, 21, 146, 224, 174, 149, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 174, 224, 175, 141, 20, 15, 2, 95, 125, 84, 109, 55, 109, 15, 81, 109, 66, 109, 65, 0, 0, 0, 0, 0, 0, 0, 35, 24, 224, 174, 170, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 224, 174, 170, 224, 175, 141, 71, 109, 47, 47, 37, 34, 109, 48, 0, 15, 140, 224, 174, 170, 224, 174, 176, 224, 174, 164, 224, 175, 141, 20, 0, 0, 0, 0, 15, 140, 224, 174, 164, 224, 174, 191, 224, 174, 178, 224, 175, 141, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 152, 224, 174, 170, 224, 175, 128, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 174, 191, 224, 174, 178, 224, 175, 141, 20, 27, 152, 224, 174, 170, 224, 175, 134, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 178, 224, 175, 141, 20, 0, 24, 149, 224, 174, 149, 224, 175, 129, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 190, 224, 174, 169, 20, 0, 0, 23, 15, 224, 174, 170, 224, 174, 190, 224, 174, 164, 224, 174, 176, 224, 175, 141, 83, 118, 72, 109, 34, 0, 0, 27, 152, 224, 174, 170, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 129, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 146, 224, 174, 170, 224, 175, 130, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 174, 190, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 140, 224, 174, 170, 224, 174, 191, 224, 174, 154, 224, 174, 191, 20, 0, 15, 140, 224, 174, 170, 224, 174, 178, 224, 174, 174, 224, 174, 190, 20, 0, 0, 0, 0, 0, 0, 0, 0, 24, 149, 224, 174, 149, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 174, 190, 224, 174, 174, 224, 174, 191, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 224, 174, 154, 224, 175, 141, 37, 76, 0, 0, 0, 9, 134, 224, 174, 154, 224, 175, 139, 20, 0, 0, 11, 6, 224, 174, 156, 224, 175, 141, 37, 75, 0, 0, 0, 0, 0, 0, 0, 15, 140, 224, 174, 149, 224, 175, 129, 224, 174, 170, 224, 175, 141, 20, 15, 140, 224, 174, 170, 224, 175, 135, 224, 174, 183, 224, 175, 141, 20, 0, 0, 21, 146, 224, 174, 170, 224, 174, 190, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 175, 141, 20, 0, 0, 0, 0, 21, 146, 224, 174, 164, 224, 175, 136, 224, 174, 181, 224, 174, 164, 224, 174, 174, 224, 175, 141, 20, 11, 6, 224, 174, 158, 224, 175, 141, 37, 67, 0, 0, 0, 0, 14, 9, 95, 35, 45, 224, 174, 174, 224, 175, 141, 118, 65, 0, 0, 0, 0, 18, 12, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 175, 141, 140, 37, 49, 0, 18, 12, 224, 174, 154, 224, 174, 191, 224, 174, 149, 224, 175, 141, 76, 37, 49, 0, 9, 134, 224, 174, 154, 224, 175, 135, 20, 0, 0, 0, 18, 143, 224, 174, 170, 224, 175, 135, 224, 174, 164, 224, 174, 174, 224, 175, 141, 20, 0, 15, 140, 224, 174, 149, 224, 175, 129, 224, 174, 174, 224, 175, 141, 20, 0, 0, 33, 158, 224, 174, 164, 224, 174, 181, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 169, 224, 174, 190, 224, 174, 178, 224, 175, 141, 20, 25, 18, 224, 174, 170, 224, 175, 141, 224, 174, 176, 224, 175, 135, 224, 174, 149, 224, 175, 141, 71, 34, 114, 49, 0, 0, 9, 134, 224, 174, 154, 224, 175, 128, 20, 0, 9, 134, 224, 174, 164, 224, 175, 139, 20, 0, 0, 11, 6, 224, 174, 170, 224, 175, 141, 37, 48, 0, 0, 0, 0, 24, 149, 224, 174, 149, 224, 174, 179, 224, 174, 191, 224, 174, 178, 224, 175, 129, 224, 174, 174, 224, 175, 141, 20, 24, 149, 224, 174, 164, 224, 175, 134, 224, 174, 169, 224, 174, 174, 224, 175, 129, 224, 174, 174, 224, 175, 141, 20, 24, 149, 224, 174, 164, 224, 175, 128, 224, 174, 176, 224, 174, 174, 224, 175, 129, 224, 174, 174, 224, 175, 141, 20, 0, 11, 6, 224, 174, 164, 224, 175, 141, 37, 47, 0, 0, 0, 18, 12, 224, 174, 170, 224, 175, 139, 224, 174, 169, 224, 175, 141, 83, 119, 50, 0, 21, 146, 224, 174, 154, 224, 175, 135, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 175, 135, 20, 27, 152, 224, 174, 164, 224, 174, 176, 224, 175, 129, 224, 174, 174, 224, 174, 174, 224, 175, 129, 224, 174, 174, 224, 175, 141, 20, 27, 152, 224, 174, 170, 224, 175, 130, 224, 174, 149, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 174, 174, 224, 175, 141, 20, 0, 0, 0, 18, 143, 224, 174, 170, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 175, 141, 20, 0, 9, 134, 224, 174, 164, 224, 174, 159, 20, 15, 140, 224, 174, 170, 224, 175, 129, 224, 174, 184, 224, 175, 141, 20, 0, 0, 21, 146, 224, 174, 170, 224, 175, 128, 224, 174, 176, 224, 174, 191, 224, 174, 169, 224, 175, 141, 20, 18, 143, 224, 174, 170, 224, 175, 134, 224, 174, 159, 224, 175, 141, 224, 174, 178, 20, 0, 0, 0, 0, 11, 6, 224, 174, 174, 224, 175, 141, 37, 65, 0, 0, 0, 32, 24, 224, 174, 159, 224, 174, 191, 224, 174, 176, 224, 175, 135, 224, 174, 175, 224, 174, 191, 224, 174, 169, 224, 175, 141, 140, 34, 114, 57, 50, 0, 0, 0, 33, 158, 224, 174, 149, 224, 175, 129, 224, 174, 174, 224, 175, 141, 224, 174, 174, 224, 175, 134, 224, 174, 169, 224, 175, 141, 224, 174, 177, 224, 175, 129, 20, 12, 137, 224, 174, 170, 224, 175, 130, 224, 174, 164, 20, 11, 6, 224, 174, 176, 224, 175, 141, 37, 34, 0, 11, 6, 224, 174, 168, 224, 175, 141, 37, 50, 0, 0, 0, 0, 16, 6, 224, 174, 176, 224, 175, 130, 34, 123, 71, 118, 57, 0, 24, 9, 0, 6, 20, 0, 230, 11, 0, 0, 48, 0, 0, 0, 231, 11, 0, 0, 49, 0, 0, 0, 232, 11, 0, 0, 50, 0, 0, 0, 233, 11, 0, 0, 51, 0, 0, 0, 234, 11, 0, 0, 52, 0, 0, 0, 235, 11, 0, 0, 53, 0, 0, 0, 236, 11, 0, 0, 54, 0, 0, 0, 237, 11, 0, 0, 55, 0, 0, 0, 238, 11, 0, 0, 56, 0, 0, 0, 239, 11, 0, 0, 57, 0, 0, 0, 198, 11, 190, 11, 202, 11, 0, 0, 199, 11, 190, 11, 203, 11, 0, 0, 198, 11, 215, 11, 204, 11, 0, 0, 0, 0, 0, 0, 6, 18, 66, 224, 174, 183, 224, 175, 141, 0, 224, 174, 184, 224, 175, 141, 0, 224, 174, 159, 224, 175, 141, 0, 7, 6, 18, 67, 224, 174, 159, 224, 175, 141, 0, 224, 174, 177, 224, 175, 141, 0, 224, 174, 183, 224, 175, 141, 0, 224, 174, 184, 224, 175, 141, 0, 7, 6, 18, 68, 224, 174, 135, 0, 224, 174, 142, 0, 224, 174, 133, 0, 7, 6, 18, 69, 224, 174, 154, 0, 224, 174, 184, 0, 7, 6, 18, 70, 224, 174, 176, 0, 224, 174, 177, 0, 7, 6, 18, 71, 224, 174, 149, 0, 224, 174, 185, 0, 7, 6, 18, 72, 224, 175, 134, 224, 174, 179, 0, 224, 175, 140, 0, 7, 6, 18, 73, 224, 174, 191, 0, 224, 175, 128, 0, 7, 6, 18, 74, 224, 174, 168, 0, 224, 174, 169, 0, 7, 6, 18, 75, 224, 174, 178, 0, 224, 174, 179, 0, 7, 6, 18, 76, 224, 174, 170, 0, 224, 174, 164, 0, 224, 174, 149, 0, 7, 6, 18, 77, 224, 174, 170, 224, 174, 191, 224, 174, 179, 224, 174, 190, 224, 174, 184, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 175, 141, 0, 224, 174, 170, 224, 175, 141, 224, 174, 179, 224, 174, 190, 224, 174, 184, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 175, 141, 0, 224, 174, 170, 224, 174, 191, 224, 174, 176, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 191, 0, 224, 174, 164, 224, 174, 163, 224, 175, 141, 224, 174, 163, 224, 175, 128, 224, 174, 176, 224, 175, 141, 0, 224, 174, 181, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 176, 224, 175, 141, 0, 224, 174, 149, 224, 174, 163, 224, 175, 141, 224, 174, 163, 224, 174, 190, 224, 174, 159, 224, 174, 191, 0, 224, 174, 174, 224, 174, 176, 224, 175, 129, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 175, 129, 0, 224, 174, 138, 224, 174, 177, 224, 175, 129, 224, 174, 149, 224, 174, 190, 224, 174, 175, 224, 175, 141, 0, 224, 174, 181, 224, 174, 191, 224, 174, 184, 224, 175, 141, 224, 174, 149, 224, 174, 191, 0, 224, 174, 149, 224, 174, 191, 224, 174, 179, 224, 174, 190, 224, 174, 184, 224, 175, 141, 0, 224, 174, 149, 224, 175, 141, 224, 174, 179, 224, 174, 190, 224, 174, 184, 224, 175, 141, 0, 224, 174, 154, 224, 174, 190, 224, 174, 176, 224, 174, 190, 224, 174, 175, 0, 224, 174, 164, 224, 174, 163, 224, 175, 141, 224, 174, 163, 224, 174, 191, 0, 224, 174, 138, 224, 174, 177, 224, 175, 129, 224, 174, 149, 224, 174, 190, 0, 224, 174, 170, 224, 175, 128, 224, 174, 176, 224, 175, 141, 0, 224, 174, 149, 224, 174, 178, 224, 174, 176, 224, 175, 141, 0, 224, 174, 154, 224, 175, 139, 224, 174, 159, 224, 174, 190, 0, 224, 174, 174, 224, 174, 164, 224, 175, 129, 0, 7, 6, 18, 78, 224, 174, 181, 224, 174, 190, 224, 174, 180, 224, 175, 141, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 136, 0, 224, 174, 181, 224, 174, 191, 224, 174, 176, 224, 175, 129, 224, 174, 168, 224, 175, 141, 224, 174, 164, 0, 224, 174, 174, 224, 174, 169, 224, 174, 191, 224, 174, 164, 224, 174, 169, 0, 224, 174, 170, 224, 175, 130, 224, 174, 174, 224, 174, 191, 0, 7, 6, 18, 79, 224, 174, 168, 224, 175, 134, 224, 174, 176, 224, 175, 129, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 129, 224, 174, 170, 224, 175, 141, 0, 224, 174, 168, 224, 175, 134, 224, 174, 176, 224, 175, 129, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 129, 0, 224, 174, 164, 224, 175, 128, 224, 174, 170, 224, 175, 141, 0, 224, 174, 164, 224, 175, 128, 0, 7, 6, 18, 80, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 134, 224, 174, 159, 224, 175, 141, 0, 224, 174, 170, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 178, 0, 224, 174, 174, 224, 175, 128, 224, 174, 178, 224, 175, 141, 224, 174, 184, 0, 224, 174, 149, 224, 174, 191, 224, 174, 179, 224, 174, 190, 224, 174, 184, 0, 224, 174, 159, 224, 174, 190, 224, 174, 184, 0, 7, 6, 18, 81, 224, 174, 174, 224, 175, 135, 224, 174, 177, 224, 175, 141, 0, 224, 174, 149, 224, 175, 129, 224, 174, 177, 224, 175, 136, 0, 224, 174, 174, 224, 175, 135, 224, 174, 178, 0, 7, 6, 18, 82, 224, 174, 149, 224, 175, 129, 224, 174, 180, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 175, 136, 0, 224, 174, 149, 224, 175, 129, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 0, 224, 174, 149, 224, 175, 129, 224, 174, 164, 224, 174, 191, 224, 174, 176, 224, 175, 136, 0, 224, 174, 149, 224, 175, 129, 224, 174, 176, 224, 174, 153, 224, 175, 141, 224, 174, 149, 0, 224, 174, 149, 224, 174, 180, 224, 175, 129, 224, 174, 164, 224, 175, 136, 0, 224, 174, 149, 224, 174, 191, 224, 174, 179, 224, 174, 191, 0, 7, 6, 18, 83, 224, 174, 170, 224, 174, 191, 224, 174, 179, 224, 175, 141, 224, 174, 179, 224, 175, 136, 0, 224, 174, 170, 224, 175, 134, 224, 174, 163, 224, 175, 141, 0, 224, 174, 170, 224, 175, 136, 224, 174, 175, 224, 174, 169, 0, 7, 6, 18, 84, 224, 174, 164, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 174, 191, 0, 224, 174, 164, 224, 174, 153, 224, 175, 141, 224, 174, 149, 0, 7, 6, 18, 85, 224, 174, 170, 224, 174, 178, 224, 175, 141, 0, 224, 174, 170, 224, 174, 177, 224, 175, 141, 0, 224, 174, 170, 224, 175, 139, 224, 174, 176, 0, 224, 174, 170, 224, 175, 139, 224, 174, 176, 0, 7, 6, 18, 86, 224, 174, 176, 224, 174, 190, 224, 174, 149, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 179, 224, 174, 191, 224, 174, 169, 224, 175, 141, 0, 224, 174, 174, 224, 175, 129, 224, 174, 149, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 169, 224, 175, 141, 0, 224, 174, 176, 224, 174, 190, 224, 174, 149, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 169, 224, 175, 141, 0, 224, 174, 154, 224, 174, 174, 224, 174, 168, 224, 174, 191, 224, 174, 178, 224, 175, 136, 0, 224, 174, 154, 224, 174, 149, 224, 175, 139, 224, 174, 164, 224, 174, 176, 0, 224, 174, 154, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 0, 224, 174, 154, 224, 174, 191, 224, 174, 168, 224, 175, 135, 224, 174, 149, 0, 224, 174, 154, 224, 174, 191, 224, 174, 169, 224, 175, 135, 224, 174, 149, 0, 224, 174, 154, 224, 174, 174, 224, 174, 174, 224, 174, 190, 224, 174, 169, 0, 224, 174, 154, 224, 174, 174, 224, 174, 174, 224, 174, 190, 224, 174, 149, 0, 224, 174, 168, 224, 175, 135, 224, 174, 175, 0, 224, 174, 176, 224, 174, 190, 224, 174, 149, 0, 224, 174, 174, 224, 175, 129, 224, 174, 149, 0, 224, 174, 154, 224, 174, 174, 0, 7, 6, 18, 87, 224, 174, 149, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 159, 0, 224, 174, 164, 224, 174, 168, 224, 175, 141, 224, 174, 164, 0, 224, 174, 149, 224, 175, 138, 224, 174, 159, 0, 224, 174, 133, 224, 174, 179, 224, 174, 191, 0, 7, 6, 18, 88, 224, 174, 181, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 176, 224, 175, 141, 0, 224, 174, 164, 224, 174, 163, 224, 175, 141, 224, 174, 163, 224, 175, 128, 224, 174, 176, 224, 175, 141, 0, 224, 174, 149, 224, 174, 190, 224, 174, 131, 224, 174, 170, 224, 174, 191, 0, 224, 174, 164, 224, 174, 163, 224, 175, 141, 224, 174, 163, 224, 174, 191, 0, 224, 174, 149, 224, 174, 190, 224, 174, 170, 224, 174, 191, 0, 224, 174, 143, 224, 174, 176, 224, 175, 141, 0, 7, 6, 18, 89, 224, 174, 170, 224, 174, 191, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 224, 174, 170, 224, 174, 191, 224, 174, 159, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 224, 174, 170, 224, 174, 191, 224, 174, 159, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 0, 224, 174, 133, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 224, 174, 133, 224, 174, 159, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 224, 174, 133, 224, 174, 159, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 0, 224, 174, 142, 224, 174, 159, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 224, 174, 142, 224, 174, 159, 224, 175, 129, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 224, 174, 142, 224, 174, 159, 224, 175, 129, 224, 174, 170, 224, 175, 141, 224, 174, 170, 0, 7, 6, 18, 90, 224, 174, 168, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 175, 0, 224, 174, 159, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 184, 0, 224, 174, 168, 224, 174, 159, 224, 174, 169, 0, 7, 6, 18, 91, 224, 174, 154, 224, 174, 191, 224, 174, 178, 224, 174, 191, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 176, 0, 224, 174, 184, 224, 175, 141, 224, 174, 159, 224, 174, 181, 224, 175, 141, 0, 224, 174, 149, 224, 174, 169, 224, 175, 134, 224, 174, 149, 224, 175, 141, 0, 7, 6, 1, 4, 0, 224, 174, 149, 2, 17, 66, 3, 81, 100, 0, 224, 174, 149, 3, 81, 100, 109, 0, 224, 174, 170, 2, 17, 66, 3, 83, 0, 224, 174, 170, 3, 83, 109, 0, 224, 174, 164, 2, 17, 66, 3, 100, 72, 0, 224, 174, 164, 3, 100, 72, 109, 0, 3, 107, 0, 7, 6, 1, 8, 0, 4, 2, 224, 174, 175, 224, 175, 135, 224, 174, 154, 3, 0, 4, 2, 224, 174, 176, 224, 174, 149, 224, 174, 154, 224, 174, 191, 224, 174, 175, 3, 0, 4, 2, 224, 174, 176, 224, 174, 149, 224, 175, 129, 3, 0, 4, 2, 224, 174, 176, 224, 174, 149, 224, 175, 129, 224, 174, 176, 224, 174, 190, 224, 174, 174, 3, 0, 4, 2, 224, 174, 176, 224, 174, 154, 3, 0, 4, 2, 224, 174, 176, 224, 174, 154, 224, 174, 169, 224, 175, 136, 3, 0, 4, 2, 224, 174, 176, 224, 174, 154, 224, 174, 190, 224, 174, 175, 224, 174, 169, 3, 0, 4, 2, 224, 174, 176, 224, 174, 154, 224, 174, 191, 224, 174, 149, 3, 0, 4, 2, 224, 174, 176, 224, 174, 154, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 3, 0, 4, 2, 224, 174, 176, 224, 174, 154, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 3, 0, 4, 2, 224, 174, 176, 224, 174, 163, 224, 174, 153, 224, 175, 141, 3, 0, 4, 2, 224, 174, 176, 224, 174, 163, 224, 174, 164, 224, 175, 141, 3, 0, 4, 2, 224, 174, 176, 224, 174, 163, 224, 174, 174, 3, 0, 4, 2, 224, 174, 176, 224, 174, 164, 32, 3, 0, 4, 2, 224, 174, 176, 224, 174, 164, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 179, 3, 0, 4, 2, 224, 174, 176, 224, 174, 164, 224, 174, 164, 224, 175, 141, 224, 174, 164, 3, 0, 4, 2, 224, 174, 176, 224, 174, 164, 224, 174, 174, 3, 0, 4, 2, 224, 174, 176, 224, 174, 164, 224, 175, 141, 224, 174, 164, 3, 0, 4, 2, 224, 174, 176, 224, 174, 174, 224, 175, 141, 224, 174, 174, 224, 174, 191, 224, 174, 175, 3, 0, 4, 2, 224, 174, 176, 224, 174, 175, 224, 174, 191, 224, 174, 178, 3, 0, 4, 2, 224, 174, 176, 224, 174, 181, 224, 175, 128, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 3, 0, 4, 2, 224, 174, 176, 224, 174, 181, 224, 175, 136, 224, 174, 149, 224, 174, 179, 3, 0, 4, 2, 224, 174, 176, 224, 174, 181, 224, 175, 136, 224, 174, 175, 224, 175, 136, 3, 0, 4, 2, 224, 174, 176, 224, 174, 190, 224, 174, 149, 3, 0, 4, 2, 224, 174, 176, 224, 174, 190, 224, 174, 154, 3, 0, 4, 2, 224, 174, 176, 224, 174, 190, 224, 174, 156, 3, 0, 4, 2, 224, 174, 176, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 174, 164, 3, 0, 4, 2, 224, 174, 176, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 174, 183, 3, 0, 4, 2, 224, 174, 176, 224, 174, 190, 224, 174, 163, 224, 174, 191, 3, 0, 4, 2, 224, 174, 176, 224, 174, 190, 224, 174, 163, 224, 175, 129, 224, 174, 181, 3, 0, 4, 2, 224, 174, 176, 224, 174, 190, 224, 174, 164, 224, 174, 190, 224, 174, 149, 224, 174, 191, 3, 0, 4, 2, 224, 174, 176, 224, 174, 190, 224, 174, 164, 224, 174, 190, 224, 174, 181, 3, 0, 4, 2, 224, 174, 176, 224, 174, 190, 224, 174, 164, 224, 175, 141, 224, 174, 164, 3, 0, 4, 2, 224, 174, 176, 224, 174, 190, 224, 174, 170, 224, 175, 141, 32, 3, 0, 4, 2, 224, 174, 176, 224, 174, 190, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 191, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 175, 136, 3, 0, 4, 2, 224, 174, 176, 224, 174, 190, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 138, 224, 174, 180, 224, 175, 129, 3, 0, 4, 2, 224, 174, 176, 224, 174, 190, 224, 174, 174, 3, 0, 4, 2, 224, 174, 176, 224, 174, 190, 224, 174, 175, 3, 0, 4, 2, 224, 174, 176, 224, 174, 190, 224, 174, 175, 224, 174, 170, 224, 175, 129, 224, 174, 176, 3, 0, 4, 2, 224, 174, 176, 224, 174, 190, 224, 174, 181, 224, 174, 163, 3, 0, 4, 2, 224, 174, 176, 224, 174, 190, 224, 174, 181, 224, 175, 129, 224, 174, 164, 224, 175, 141, 224, 174, 164, 3, 0, 4, 2, 224, 174, 176, 224, 174, 190, 224, 174, 183, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 176, 3, 0, 4, 2, 224, 174, 178, 224, 174, 149, 224, 175, 129, 3, 0, 4, 2, 224, 174, 178, 224, 174, 149, 224, 175, 141, 224, 174, 183, 224, 175, 141, 224, 174, 174, 224, 174, 163, 3, 0, 4, 2, 224, 174, 178, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 174, 149, 224, 175, 141, 3, 0, 4, 2, 224, 174, 178, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 174, 153, 224, 175, 141, 3, 0, 4, 2, 224, 174, 178, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 174, 163, 3, 0, 4, 2, 224, 174, 178, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 174, 164, 224, 175, 141, 3, 0, 4, 2, 224, 174, 178, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 174, 174, 3, 0, 4, 2, 224, 174, 178, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 174, 190, 3, 0, 4, 2, 224, 174, 178, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 174, 191, 224, 174, 175, 3, 0, 4, 2, 224, 174, 178, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 175, 129, 224, 174, 174, 224, 174, 163, 3, 0, 4, 2, 224, 174, 178, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 175, 129, 224, 174, 174, 224, 174, 191, 3, 0, 4, 2, 224, 174, 178, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 169, 3, 0, 4, 2, 224, 174, 178, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 128, 224, 174, 169, 3, 0, 4, 2, 224, 174, 178, 224, 174, 174, 224, 175, 130, 224, 174, 176, 224, 174, 191, 224, 174, 175, 3, 0, 4, 2, 224, 174, 178, 224, 174, 175, 224, 174, 191, 3, 0, 4, 2, 224, 174, 178, 224, 174, 181, 224, 174, 153, 224, 175, 141, 224, 174, 149, 3, 0, 4, 2, 224, 174, 178, 224, 174, 190, 224, 174, 149, 224, 174, 181, 3, 0, 4, 2, 224, 174, 178, 224, 174, 190, 224, 174, 170, 3, 0, 4, 2, 224, 174, 178, 224, 174, 190, 224, 174, 181, 224, 174, 163, 224, 175, 141, 224, 174, 175, 3, 0, 2, 224, 174, 178, 224, 175, 135, 224, 174, 154, 3, 0, 224, 174, 176, 224, 174, 170, 224, 175, 141, 224, 174, 170, 2, 224, 174, 176, 3, 34, 109, 71, 71, 109, 0, 224, 174, 176, 224, 174, 190, 224, 174, 158, 224, 175, 141, 224, 174, 154, 3, 34, 118, 67, 76, 149, 0, 4, 3, 37, 0, 2, 224, 174, 176, 224, 174, 190, 224, 174, 174, 224, 174, 178, 224, 175, 141, 32, 0, 224, 174, 178, 224, 175, 135, 224, 174, 149, 224, 175, 141, 224, 174, 149, 2, 224, 174, 191, 224, 174, 175, 3, 55, 114, 81, 81, 0, 7, 6, 1, 10, 0, 2, 224, 174, 176, 224, 175, 139, 224, 174, 174, 3, 0, 224, 174, 176, 224, 175, 129, 224, 174, 164, 224, 175, 141, 224, 174, 164, 2, 224, 174, 191, 224, 174, 176, 224, 174, 190, 3, 34, 122, 72, 72, 0, 3, 40, 0, 7, 6, 1, 19, 0, 3, 39, 0, 4, 224, 174, 179, 2, 224, 174, 159, 224, 174, 164, 3, 135, 0, 224, 174, 179, 2, 224, 174, 176, 224, 174, 153, 224, 175, 141, 224, 174, 149, 0, 224, 174, 179, 2, 224, 174, 181, 224, 175, 136, 0, 224, 174, 179, 2, 224, 174, 183, 224, 174, 164, 0, 7, 6, 1, 22, 0, 1, 141, 175, 224, 177, 174, 224, 2, 17, 66, 3, 10, 49, 0, 1, 141, 175, 224, 177, 174, 224, 3, 10, 49, 109, 0, 4, 1, 18, 66, 2, 17, 66, 3, 49, 0, 1, 128, 175, 224, 174, 174, 224, 141, 175, 224, 178, 174, 224, 190, 174, 224, 181, 174, 224, 2, 224, 174, 191, 0, 1, 129, 175, 224, 164, 174, 224, 18, 68, 2, 224, 175, 129, 224, 174, 177, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 1, 129, 175, 224, 180, 174, 224, 133, 174, 224, 2, 224, 175, 129, 224, 174, 176, 224, 174, 178, 0, 1, 133, 174, 224, 2, 224, 174, 190, 224, 174, 178, 224, 174, 191, 0, 1, 133, 174, 224, 2, 224, 174, 191, 224, 174, 178, 224, 175, 135, 224, 174, 183, 0, 1, 133, 174, 224, 2, 224, 175, 141, 224, 174, 159, 224, 175, 139, 224, 174, 170, 224, 174, 176, 0, 1, 134, 174, 224, 2, 224, 174, 190, 224, 174, 183, 0, 1, 134, 174, 224, 2, 224, 175, 141, 224, 174, 176, 224, 175, 139, 224, 174, 183, 0, 1, 135, 175, 224, 178, 174, 224, 176, 174, 224, 191, 174, 224, 164, 174, 224, 141, 175, 224, 164, 174, 224, 191, 174, 224, 154, 174, 224, 2, 224, 174, 190, 0, 1, 135, 175, 224, 181, 174, 224, 191, 174, 224, 181, 174, 224, 2, 224, 174, 190, 224, 174, 169, 224, 174, 168, 224, 175, 141, 224, 174, 164, 0, 1, 136, 175, 224, 176, 174, 224, 133, 174, 224, 2, 224, 175, 129, 224, 174, 177, 224, 175, 136, 0, 1, 136, 175, 224, 177, 174, 224, 133, 174, 224, 2, 224, 175, 130, 224, 174, 181, 0, 1, 141, 175, 224, 153, 174, 224, 133, 174, 224, 2, 224, 174, 190, 224, 174, 176, 224, 174, 190, 0, 1, 141, 175, 224, 153, 174, 224, 133, 174, 224, 2, 224, 174, 191, 224, 174, 179, 0, 1, 141, 175, 224, 163, 174, 224, 128, 175, 224, 181, 174, 224, 2, 224, 175, 139, 224, 174, 170, 0, 1, 141, 175, 224, 169, 174, 224, 134, 175, 224, 164, 174, 224, 2, 224, 174, 191, 224, 174, 180, 0, 1, 141, 175, 224, 176, 174, 224, 128, 175, 224, 154, 174, 224, 2, 224, 175, 135, 224, 174, 159, 0, 1, 141, 175, 224, 178, 174, 224, 138, 175, 224, 164, 174, 224, 2, 224, 174, 190, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 191, 0, 1, 141, 175, 224, 178, 174, 224, 191, 174, 224, 175, 174, 224, 139, 175, 224, 149, 174, 224, 2, 224, 174, 190, 224, 174, 179, 224, 175, 136, 0, 1, 141, 175, 224, 179, 174, 224, 129, 175, 224, 176, 174, 224, 133, 174, 224, 2, 224, 175, 130, 224, 174, 176, 0, 1, 154, 174, 224, 176, 174, 224, 133, 174, 224, 2, 224, 175, 129, 224, 174, 178, 0, 1, 156, 174, 224, 190, 174, 224, 176, 174, 224, 2, 224, 175, 129, 224, 174, 178, 0, 1, 159, 174, 224, 141, 175, 224, 183, 174, 224, 133, 174, 224, 2, 224, 175, 139, 224, 174, 163, 224, 174, 178, 0, 1, 170, 174, 224, 133, 174, 224, 2, 224, 175, 128, 224, 174, 176, 224, 175, 141, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 0, 1, 174, 174, 224, 190, 174, 224, 176, 174, 224, 2, 224, 174, 190, 224, 174, 181, 224, 174, 191, 224, 174, 175, 0, 1, 174, 174, 224, 190, 174, 224, 176, 174, 224, 135, 174, 224, 2, 224, 174, 190, 224, 174, 164, 224, 175, 136, 0, 1, 174, 174, 224, 191, 174, 224, 164, 174, 224, 141, 175, 224, 168, 174, 224, 133, 174, 224, 2, 224, 174, 190, 224, 174, 178, 0, 1, 175, 174, 224, 191, 174, 224, 176, 174, 224, 133, 174, 224, 2, 224, 175, 129, 224, 174, 159, 224, 174, 191, 0, 1, 178, 174, 224, 128, 175, 224, 168, 174, 224, 2, 224, 175, 135, 224, 174, 154, 224, 174, 191, 0, 1, 178, 174, 224, 130, 175, 224, 174, 174, 224, 2, 224, 174, 190, 224, 174, 176, 224, 174, 163, 0, 1, 178, 174, 224, 159, 174, 224, 141, 175, 224, 163, 174, 224, 129, 175, 224, 149, 174, 224, 2, 224, 175, 135, 224, 174, 154, 224, 174, 191, 0, 1, 190, 174, 224, 178, 174, 224, 135, 174, 224, 2, 224, 174, 190, 0, 1, 191, 174, 224, 164, 174, 224, 134, 174, 224, 2, 224, 175, 129, 224, 174, 159, 224, 174, 191, 0, 1, 191, 174, 224, 169, 174, 224, 130, 175, 224, 175, 174, 224, 2, 224, 175, 139, 224, 174, 159, 0, 1, 191, 174, 224, 174, 174, 224, 190, 174, 224, 169, 174, 224, 133, 174, 224, 2, 224, 174, 190, 0, 1, 191, 174, 224, 178, 174, 224, 129, 175, 224, 170, 174, 224, 2, 224, 175, 135, 224, 174, 154, 224, 174, 191, 0, 1, 191, 174, 224, 181, 174, 224, 2, 224, 175, 141, 224, 174, 176, 224, 174, 174, 0, 1, 191, 174, 224, 183, 174, 224, 134, 174, 224, 2, 224, 174, 190, 0, 2, 224, 174, 190, 224, 174, 176, 224, 174, 169, 0, 2, 224, 174, 191, 224, 174, 176, 224, 175, 129, 0, 2, 224, 175, 129, 224, 174, 174, 224, 174, 176, 224, 174, 169, 0, 2, 224, 175, 129, 224, 174, 174, 224, 174, 190, 224, 174, 176, 0, 2, 224, 175, 130, 224, 174, 159, 0, 2, 224, 175, 138, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 2, 224, 175, 138, 224, 174, 179, 224, 175, 141, 0, 8, 2, 17, 66, 0, 8, 2, 224, 175, 128, 224, 174, 164, 224, 174, 178, 0, 8, 2, 224, 175, 128, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 175, 129, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 175, 129, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 175, 129, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 174, 0, 8, 2, 224, 175, 129, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 178, 0, 8, 2, 224, 175, 129, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 191, 0, 8, 2, 224, 175, 129, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 149, 224, 175, 129, 224, 174, 164, 224, 174, 191, 0, 8, 2, 224, 175, 134, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 32, 0, 8, 2, 224, 175, 134, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 169, 224, 175, 129, 224, 174, 174, 0, 8, 2, 224, 175, 134, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 0, 8, 2, 224, 175, 134, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 176, 224, 175, 129, 0, 8, 2, 224, 175, 139, 224, 174, 170, 224, 174, 170, 224, 175, 141, 0, 8, 2, 224, 175, 139, 224, 174, 176, 32, 224, 174, 174, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 175, 139, 224, 174, 176, 32, 224, 174, 174, 224, 175, 129, 224, 174, 159, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 175, 139, 224, 174, 176, 32, 224, 174, 181, 224, 175, 135, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 8, 129, 175, 224, 163, 174, 224, 135, 175, 224, 176, 174, 224, 2, 224, 174, 190, 0, 8, 129, 175, 224, 174, 174, 224, 2, 224, 175, 135, 224, 174, 183, 0, 8, 129, 175, 224, 176, 174, 224, 129, 175, 224, 149, 174, 224, 2, 224, 175, 129, 224, 174, 178, 0, 8, 129, 175, 224, 178, 174, 224, 190, 174, 224, 164, 174, 224, 2, 224, 174, 190, 0, 8, 129, 175, 224, 181, 174, 224, 136, 175, 224, 169, 174, 224, 191, 174, 224, 168, 174, 224, 2, 224, 175, 130, 224, 174, 176, 0, 8, 129, 175, 224, 181, 174, 224, 175, 174, 224, 164, 174, 224, 2, 224, 175, 130, 224, 174, 176, 0, 8, 130, 175, 224, 170, 174, 224, 2, 224, 174, 190, 224, 174, 176, 224, 174, 176, 0, 8, 130, 175, 224, 170, 174, 224, 2, 224, 174, 190, 224, 174, 176, 224, 174, 191, 0, 8, 130, 175, 224, 178, 174, 224, 190, 174, 224, 164, 174, 224, 2, 224, 174, 190, 0, 8, 135, 175, 224, 176, 174, 224, 2, 224, 174, 190, 0, 8, 135, 175, 224, 176, 174, 224, 129, 175, 224, 154, 174, 224, 2, 224, 174, 190, 0, 8, 135, 175, 224, 176, 174, 224, 129, 175, 224, 175, 174, 224, 2, 224, 174, 190, 0, 8, 135, 175, 224, 178, 174, 224, 176, 174, 224, 191, 174, 224, 164, 174, 224, 141, 175, 224, 168, 174, 224, 154, 174, 224, 2, 224, 174, 190, 0, 8, 136, 175, 224, 159, 174, 224, 149, 174, 224, 2, 224, 174, 190, 224, 174, 176, 224, 174, 176, 0, 8, 136, 175, 224, 159, 174, 224, 149, 174, 224, 2, 224, 174, 190, 224, 174, 176, 224, 174, 191, 0, 8, 136, 175, 224, 175, 174, 224, 164, 174, 224, 2, 224, 175, 130, 224, 174, 176, 0, 8, 136, 175, 224, 177, 174, 224, 129, 175, 224, 149, 174, 224, 2, 224, 175, 130, 224, 174, 177, 0, 8, 136, 175, 224, 178, 174, 224, 181, 174, 224, 2, 224, 174, 190, 224, 174, 170, 224, 175, 141, 0, 8, 136, 175, 224, 179, 174, 224, 181, 174, 224, 2, 224, 174, 190, 224, 174, 170, 224, 175, 141, 224, 174, 170, 0, 8, 136, 175, 224, 181, 174, 224, 2, 224, 175, 139, 0, 8, 138, 175, 224, 178, 174, 224, 2, 224, 175, 135, 224, 174, 183, 224, 174, 169, 0, 8, 139, 175, 224, 149, 174, 224, 2, 224, 175, 129, 224, 174, 178, 0, 8, 141, 175, 224, 153, 174, 224, 178, 174, 224, 2, 224, 174, 190, 0, 8, 141, 175, 224, 153, 174, 224, 178, 174, 224, 128, 175, 224, 176, 174, 224, 141, 175, 224, 184, 174, 224, 2, 224, 174, 190, 0, 8, 141, 175, 224, 153, 174, 224, 190, 174, 224, 185, 174, 224, 2, 224, 174, 190, 224, 174, 153, 224, 175, 141, 0, 8, 141, 175, 224, 156, 174, 224, 190, 174, 224, 176, 174, 224, 2, 224, 174, 191, 224, 174, 176, 224, 174, 163, 0, 8, 141, 175, 224, 163, 174, 224, 149, 174, 224, 2, 224, 174, 190, 224, 174, 163, 224, 174, 190, 0, 8, 141, 175, 224, 169, 174, 224, 134, 175, 224, 164, 174, 224, 2, 224, 174, 190, 224, 174, 154, 224, 174, 191, 0, 8, 141, 175, 224, 176, 174, 224, 134, 175, 224, 174, 174, 224, 2, 224, 175, 129, 224, 174, 176, 224, 174, 191, 0, 8, 141, 175, 224, 176, 174, 224, 135, 175, 224, 168, 174, 224, 2, 224, 174, 190, 224, 174, 163, 224, 174, 178, 0, 8, 141, 175, 224, 176, 174, 224, 149, 174, 224, 190, 174, 224, 168, 174, 224, 2, 224, 175, 139, 224, 174, 175, 224, 174, 191, 224, 174, 178, 0, 8, 141, 175, 224, 176, 174, 224, 154, 174, 224, 2, 224, 174, 191, 224, 174, 179, 0, 8, 141, 175, 224, 176, 174, 224, 169, 174, 224, 141, 175, 224, 169, 174, 224, 174, 174, 224, 2, 224, 175, 129, 224, 174, 178, 0, 8, 141, 175, 224, 178, 174, 224, 135, 175, 224, 174, 174, 224, 2, 224, 175, 129, 224, 174, 178, 0, 8, 141, 175, 224, 178, 174, 224, 149, 174, 224, 2, 224, 174, 191, 0, 8, 141, 175, 224, 178, 174, 224, 170, 174, 224, 2, 224, 175, 129, 0, 8, 141, 175, 224, 178, 174, 224, 175, 174, 224, 136, 175, 224, 164, 174, 224, 2, 224, 174, 190, 224, 174, 176, 224, 174, 176, 0, 8, 141, 175, 224, 178, 174, 224, 175, 174, 224, 136, 175, 224, 174, 174, 224, 154, 174, 224, 2, 224, 174, 190, 224, 174, 176, 224, 174, 191, 0, 8, 141, 175, 224, 178, 174, 224, 190, 174, 224, 170, 174, 224, 2, 224, 174, 190, 224, 174, 176, 224, 174, 176, 0, 8, 141, 175, 224, 178, 174, 224, 190, 174, 224, 170, 174, 224, 2, 224, 174, 190, 224, 174, 176, 224, 174, 191, 0, 8, 141, 175, 224, 178, 174, 224, 190, 174, 224, 170, 174, 224, 2, 224, 175, 129, 224, 174, 159, 0, 8, 141, 175, 224, 180, 174, 224, 128, 175, 224, 149, 174, 224, 2, 224, 175, 129, 224, 174, 178, 0, 8, 147, 174, 224, 2, 224, 175, 135, 0, 8, 159, 174, 224, 181, 174, 224, 2, 224, 174, 191, 224, 174, 180, 0, 8, 164, 174, 224, 135, 175, 224, 181, 174, 224, 2, 224, 175, 129, 224, 174, 178, 0, 8, 164, 174, 224, 141, 175, 224, 149, 174, 224, 170, 174, 224, 2, 224, 175, 139, 224, 174, 159, 224, 174, 191, 0, 8, 164, 174, 224, 141, 175, 224, 164, 174, 224, 130, 175, 224, 174, 174, 224, 2, 224, 175, 129, 224, 174, 159, 224, 174, 191, 0, 8, 164, 174, 224, 191, 174, 224, 169, 174, 224, 174, 174, 224, 2, 224, 175, 129, 224, 174, 178, 0, 8, 174, 174, 224, 141, 175, 224, 169, 174, 224, 138, 175, 224, 164, 174, 224, 2, 224, 174, 190, 224, 174, 178, 0, 8, 174, 174, 224, 154, 174, 224, 2, 224, 174, 190, 224, 174, 178, 0, 8, 174, 174, 224, 176, 174, 224, 170, 174, 224, 2, 224, 175, 129, 224, 174, 159, 224, 174, 191, 0, 8, 174, 174, 224, 190, 174, 224, 176, 174, 224, 2, 224, 174, 190, 224, 174, 164, 224, 175, 136, 0, 8, 181, 174, 224, 128, 175, 224, 156, 174, 224, 2, 224, 175, 139, 224, 174, 159, 224, 174, 191, 0, 8, 181, 174, 224, 135, 175, 224, 164, 174, 224, 2, 224, 175, 139, 224, 174, 159, 224, 175, 141, 224, 174, 159, 0, 8, 181, 174, 224, 141, 175, 224, 176, 174, 224, 130, 175, 224, 170, 174, 224, 2, 224, 175, 129, 224, 174, 159, 224, 174, 191, 0, 8, 190, 174, 224, 170, 174, 224, 2, 224, 174, 191, 224, 174, 184, 224, 175, 141, 224, 174, 164, 224, 174, 190, 224, 174, 169, 0, 8, 190, 174, 224, 175, 174, 224, 191, 174, 224, 163, 174, 224, 141, 175, 224, 163, 174, 224, 149, 174, 224, 2, 224, 175, 129, 224, 174, 174, 224, 174, 176, 224, 174, 191, 0, 8, 190, 174, 224, 176, 174, 224, 2, 224, 175, 135, 224, 174, 183, 0, 8, 190, 174, 224, 176, 174, 224, 141, 175, 224, 159, 174, 224, 2, 224, 175, 129, 224, 174, 178, 224, 174, 190, 0, 8, 190, 174, 224, 176, 174, 224, 191, 174, 224, 159, 174, 224, 2, 224, 175, 129, 224, 174, 178, 224, 174, 190, 0, 8, 191, 174, 224, 18, 69, 141, 175, 224, 169, 174, 224, 185, 174, 224, 2, 224, 174, 190, 0, 8, 191, 174, 224, 159, 174, 224, 134, 175, 224, 154, 174, 224, 2, 224, 175, 138, 224, 174, 159, 224, 174, 191, 0, 8, 191, 174, 224, 159, 174, 224, 141, 175, 224, 163, 174, 224, 181, 174, 224, 2, 224, 174, 190, 224, 174, 176, 224, 174, 176, 0, 8, 191, 174, 224, 164, 174, 224, 141, 175, 224, 164, 174, 224, 129, 175, 224, 176, 174, 224, 191, 174, 224, 149, 174, 224, 2, 224, 174, 190, 0, 8, 191, 174, 224, 164, 174, 224, 141, 175, 224, 164, 174, 224, 141, 175, 224, 176, 174, 224, 128, 175, 224, 149, 174, 224, 2, 224, 174, 190, 0, 8, 191, 174, 224, 164, 174, 224, 141, 175, 224, 164, 174, 224, 141, 175, 224, 176, 174, 224, 190, 174, 224, 149, 174, 224, 2, 224, 174, 190, 0, 8, 191, 174, 224, 164, 174, 224, 190, 174, 224, 176, 174, 224, 2, 224, 174, 190, 0, 8, 191, 174, 224, 168, 174, 224, 2, 224, 175, 139, 0, 8, 191, 174, 224, 169, 174, 224, 139, 175, 224, 174, 174, 224, 2, 224, 174, 190, 0, 8, 191, 174, 224, 169, 174, 224, 140, 175, 224, 174, 174, 224, 2, 224, 174, 190, 0, 8, 191, 174, 224, 176, 174, 224, 141, 175, 224, 164, 174, 224, 129, 175, 224, 174, 174, 224, 190, 174, 224, 154, 174, 224, 2, 224, 174, 190, 0, 8, 191, 174, 224, 176, 174, 224, 185, 174, 224, 128, 175, 224, 176, 174, 224, 141, 175, 224, 184, 174, 224, 2, 224, 175, 139, 224, 174, 159, 224, 175, 141, 224, 174, 159, 0, 8, 191, 174, 224, 176, 174, 224, 191, 174, 224, 164, 174, 224, 141, 175, 224, 168, 174, 224, 154, 174, 224, 2, 224, 174, 190, 0, 8, 191, 174, 224, 178, 174, 224, 134, 175, 224, 185, 174, 224, 2, 224, 174, 190, 224, 174, 170, 224, 175, 141, 224, 174, 159, 224, 174, 176, 0, 8, 191, 174, 224, 181, 174, 224, 135, 175, 224, 164, 174, 224, 2, 224, 174, 190, 0, 8, 191, 174, 224, 181, 174, 224, 135, 175, 224, 164, 174, 224, 2, 224, 175, 139, 224, 174, 159, 224, 175, 141, 224, 174, 159, 0, 8, 191, 174, 224, 181, 174, 224, 179, 174, 224, 190, 174, 224, 174, 174, 224, 2, 224, 174, 190, 0, 8, 191, 174, 224, 183, 174, 224, 2, 224, 175, 139, 0, 8, 191, 174, 224, 183, 174, 224, 135, 175, 224, 149, 174, 224, 2, 224, 174, 190, 0, 224, 174, 191, 1, 141, 175, 224, 184, 174, 224, 141, 175, 224, 149, 174, 224, 142, 174, 224, 2, 224, 174, 175, 224, 175, 130, 224, 174, 184, 0, 224, 174, 191, 1, 141, 175, 224, 184, 174, 224, 144, 174, 224, 2, 224, 174, 176, 224, 175, 128, 224, 174, 174, 0, 224, 174, 191, 2, 224, 174, 178, 224, 175, 135, 224, 174, 154, 0, 224, 174, 191, 8, 2, 224, 174, 175, 224, 175, 130, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 175, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 190, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 164, 224, 174, 149, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 174, 224, 175, 141, 224, 174, 170, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 174, 224, 174, 191, 224, 174, 169, 224, 174, 178, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 174, 190, 32, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 184, 224, 175, 141, 224, 174, 159, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 128, 224, 174, 159, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 128, 224, 174, 174, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 135, 224, 174, 175, 0, 224, 174, 191, 8, 2, 224, 174, 177, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 224, 174, 191, 8, 2, 224, 174, 177, 224, 174, 191, 224, 174, 184, 224, 175, 141, 224, 174, 159, 224, 174, 178, 0, 224, 174, 191, 8, 2, 224, 174, 177, 224, 174, 191, 224, 174, 184, 224, 175, 141, 224, 174, 164, 0, 224, 174, 191, 8, 2, 224, 174, 179, 224, 174, 170, 224, 175, 141, 32, 0, 224, 174, 191, 8, 2, 224, 174, 179, 224, 174, 190, 18, 69, 224, 174, 191, 0, 224, 174, 191, 8, 2, 224, 174, 179, 224, 174, 190, 18, 69, 224, 175, 129, 0, 224, 174, 191, 8, 2, 224, 174, 179, 224, 174, 190, 18, 69, 224, 175, 136, 0, 224, 174, 191, 8, 2, 224, 174, 179, 224, 174, 190, 224, 174, 184, 224, 175, 141, 32, 224, 174, 174, 224, 175, 135, 224, 174, 159, 0, 224, 174, 191, 8, 2, 224, 174, 179, 224, 174, 191, 224, 174, 169, 224, 174, 191, 224, 174, 149, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 179, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 191, 224, 174, 178, 0, 224, 174, 191, 8, 2, 224, 174, 179, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 136, 0, 224, 174, 191, 8, 2, 224, 174, 179, 224, 174, 191, 224, 174, 175, 224, 174, 176, 0, 224, 174, 191, 8, 2, 224, 174, 179, 224, 175, 128, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 179, 224, 175, 135, 224, 174, 154, 0, 224, 174, 191, 8, 2, 224, 174, 179, 224, 175, 136, 224, 174, 174, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 184, 0, 224, 174, 191, 8, 2, 224, 174, 179, 224, 175, 140, 0, 224, 175, 129, 8, 2, 224, 174, 176, 224, 175, 139, 224, 174, 164, 0, 224, 175, 141, 1, 140, 175, 224, 154, 174, 224, 133, 174, 224, 2, 224, 174, 175, 0, 224, 175, 141, 2, 32, 224, 174, 149, 0, 224, 175, 141, 2, 224, 174, 149, 0, 224, 175, 141, 2, 224, 174, 184, 0, 224, 175, 141, 8, 128, 175, 224, 154, 174, 224, 2, 224, 174, 176, 224, 174, 174, 0, 224, 175, 141, 8, 128, 175, 224, 170, 174, 224, 141, 175, 224, 184, 174, 224, 136, 174, 224, 2, 32, 0, 224, 175, 141, 8, 129, 175, 224, 176, 174, 224, 2, 224, 174, 174, 224, 174, 163, 224, 174, 191, 0, 224, 175, 141, 8, 134, 175, 224, 168, 174, 224, 2, 224, 174, 178, 224, 174, 184, 0, 224, 175, 141, 8, 135, 175, 224, 181, 174, 224, 191, 174, 224, 181, 174, 224, 2, 32, 0, 224, 175, 141, 8, 136, 175, 224, 170, 174, 224, 2, 224, 174, 178, 32, 0, 224, 175, 141, 8, 136, 175, 224, 174, 174, 224, 0, 224, 175, 141, 8, 139, 175, 224, 156, 174, 224, 2, 32, 0, 224, 175, 141, 8, 140, 175, 224, 154, 174, 224, 2, 224, 174, 175, 0, 224, 175, 141, 8, 159, 174, 224, 0, 224, 175, 141, 8, 178, 174, 224, 2, 224, 174, 169, 224, 175, 139, 0, 224, 175, 141, 8, 190, 174, 224, 154, 174, 224, 2, 224, 174, 176, 224, 174, 159, 224, 175, 128, 224, 174, 184, 0, 224, 175, 141, 8, 190, 174, 224, 183, 174, 224, 2, 32, 0, 4, 224, 174, 191, 224, 174, 176, 224, 175, 129, 2, 224, 174, 183, 224, 175, 141, 3, 49, 34, 37, 0, 224, 174, 191, 224, 174, 176, 224, 175, 129, 8, 2, 224, 174, 184, 224, 175, 141, 224, 174, 164, 0, 4, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 184, 224, 175, 141, 224, 174, 159, 224, 175, 139, 224, 174, 170, 8, 2, 224, 174, 176, 3, 49, 34, 37, 89, 140, 119, 83, 109, 0, 224, 175, 141, 224, 174, 176, 224, 174, 191, 224, 174, 184, 224, 175, 141, 224, 174, 159, 224, 175, 139, 224, 174, 170, 8, 2, 224, 174, 176, 0, 224, 175, 141, 224, 174, 176, 224, 174, 170, 8, 154, 174, 224, 2, 224, 174, 190, 224, 174, 163, 224, 174, 191, 3, 49, 34, 109, 48, 0, 224, 174, 191, 224, 174, 176, 224, 174, 190, 224, 174, 170, 224, 175, 141, 8, 3, 49, 34, 118, 48, 0, 224, 175, 141, 224, 174, 176, 224, 175, 130, 224, 174, 159, 224, 175, 141, 8, 134, 175, 224, 176, 174, 224, 3, 49, 34, 152, 140, 0, 224, 175, 134, 224, 174, 159, 224, 175, 141, 8, 141, 175, 224, 176, 174, 224, 190, 174, 224, 174, 174, 224, 3, 49, 36, 140, 0, 4, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 163, 224, 174, 191, 3, 49, 37, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 163, 224, 175, 141, 32, 0, 224, 175, 141, 224, 174, 170, 8, 139, 175, 224, 178, 174, 224, 2, 224, 174, 190, 224, 174, 178, 3, 49, 48, 0, 224, 175, 141, 224, 174, 149, 224, 175, 134, 224, 174, 159, 224, 175, 141, 8, 141, 175, 224, 176, 174, 224, 190, 174, 224, 174, 174, 224, 3, 49, 49, 36, 140, 0, 224, 175, 141, 224, 174, 149, 8, 141, 175, 224, 176, 174, 224, 190, 174, 224, 174, 174, 224, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 175, 135, 224, 174, 175, 3, 49, 49, 109, 0, 224, 174, 191, 224, 174, 179, 224, 174, 191, 224, 174, 163, 224, 175, 141, 224, 174, 159, 8, 2, 224, 174, 169, 3, 49, 55, 37, 50, 140, 109, 0, 224, 174, 191, 224, 174, 179, 224, 174, 191, 224, 174, 175, 224, 175, 139, 224, 174, 170, 224, 174, 190, 224, 174, 159, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 190, 3, 49, 55, 37, 57, 119, 48, 118, 47, 0, 224, 174, 191, 224, 174, 179, 224, 174, 176, 224, 175, 141, 224, 174, 149, 224, 175, 141, 8, 3, 49, 55, 109, 34, 49, 0, 224, 174, 191, 224, 174, 179, 224, 174, 170, 224, 175, 141, 224, 174, 170, 8, 2, 224, 175, 129, 224, 174, 149, 224, 174, 179, 3, 49, 55, 109, 71, 71, 0, 224, 175, 141, 224, 174, 178, 224, 175, 139, 224, 174, 170, 1, 136, 175, 224, 154, 174, 224, 141, 175, 224, 169, 174, 224, 142, 174, 224, 2, 224, 175, 128, 224, 174, 159, 224, 174, 191, 224, 174, 175, 224, 174, 190, 3, 49, 55, 119, 48, 0, 224, 174, 191, 224, 174, 179, 224, 175, 136, 224, 174, 175, 224, 174, 163, 224, 175, 141, 224, 174, 159, 8, 3, 49, 55, 134, 57, 109, 66, 140, 149, 0, 224, 175, 141, 224, 174, 175, 224, 175, 130, 224, 174, 176, 224, 174, 191, 224, 174, 159, 8, 134, 175, 224, 154, 174, 224, 2, 224, 174, 191, 3, 49, 57, 152, 34, 37, 140, 0, 4, 224, 175, 129, 224, 174, 181, 8, 2, 224, 174, 190, 224, 174, 178, 224, 174, 191, 224, 174, 170, 224, 174, 191, 224, 174, 149, 224, 175, 135, 224, 174, 183, 224, 174, 169, 3, 49, 58, 0, 224, 175, 141, 224, 174, 181, 8, 2, 17, 65, 0, 224, 175, 129, 224, 174, 181, 224, 174, 190, 224, 174, 178, 224, 174, 191, 224, 174, 159, 8, 2, 224, 174, 191, 3, 49, 58, 118, 55, 37, 140, 0, 4, 224, 174, 191, 224, 174, 179, 224, 174, 191, 224, 174, 170, 224, 175, 141, 8, 2, 32, 3, 49, 62, 37, 48, 0, 224, 174, 191, 224, 174, 179, 224, 174, 191, 224, 174, 170, 224, 175, 141, 8, 2, 224, 174, 178, 0, 224, 174, 191, 224, 174, 179, 224, 174, 191, 224, 174, 159, 8, 3, 49, 62, 37, 140, 149, 0, 4, 224, 174, 191, 224, 174, 179, 224, 174, 170, 224, 175, 141, 224, 174, 170, 8, 2, 224, 174, 191, 224, 174, 178, 3, 49, 62, 109, 71, 71, 0, 224, 174, 191, 224, 174, 179, 224, 174, 170, 224, 175, 141, 224, 174, 170, 8, 2, 224, 175, 129, 224, 174, 149, 224, 175, 141, 0, 224, 174, 191, 224, 174, 179, 224, 174, 170, 224, 175, 141, 224, 174, 170, 8, 2, 224, 175, 136, 0, 224, 175, 141, 224, 174, 154, 1, 134, 174, 224, 2, 224, 175, 129, 224, 174, 181, 224, 174, 178, 3, 49, 76, 0, 4, 224, 175, 141, 224, 174, 154, 8, 134, 175, 224, 178, 174, 224, 2, 224, 174, 176, 3, 49, 76, 109, 0, 224, 175, 141, 224, 174, 154, 8, 191, 174, 224, 170, 174, 224, 2, 224, 174, 176, 0, 224, 175, 141, 224, 174, 154, 8, 191, 174, 224, 174, 174, 224, 2, 224, 174, 176, 0, 224, 175, 141, 224, 174, 149, 8, 136, 175, 224, 149, 174, 224, 2, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 174, 190, 224, 174, 176, 3, 49, 81, 109, 0, 4, 224, 175, 141, 224, 174, 154, 224, 174, 191, 224, 174, 149, 8, 134, 175, 224, 174, 174, 224, 2, 224, 175, 139, 3, 49, 89, 37, 49, 0, 224, 175, 141, 224, 174, 184, 224, 174, 191, 224, 174, 149, 8, 134, 175, 224, 174, 174, 224, 2, 224, 175, 139, 0, 224, 175, 141, 224, 174, 183, 2, 17, 66, 3, 49, 93, 0, 4, 224, 175, 141, 224, 174, 154, 8, 191, 174, 224, 181, 174, 224, 2, 224, 174, 169, 224, 174, 176, 224, 174, 191, 3, 49, 93, 109, 0, 224, 175, 141, 224, 174, 183, 0, 4, 1, 18, 66, 3, 49, 109, 0, 1, 129, 175, 224, 164, 174, 224, 174, 174, 224, 2, 224, 174, 176, 0, 1, 129, 175, 224, 176, 174, 224, 146, 174, 224, 2, 224, 174, 159, 224, 175, 141, 224, 174, 159, 0, 1, 129, 175, 224, 177, 174, 224, 174, 174, 224, 2, 224, 174, 159, 224, 175, 141, 224, 174, 159, 0, 1, 136, 175, 224, 178, 174, 224, 133, 174, 224, 2, 224, 174, 159, 224, 174, 178, 0, 1, 140, 175, 224, 154, 174, 224, 133, 174, 224, 2, 224, 174, 176, 224, 174, 191, 224, 174, 175, 0, 1, 141, 175, 224, 153, 174, 224, 183, 174, 224, 2, 224, 174, 176, 0, 1, 141, 175, 224, 163, 174, 224, 128, 175, 224, 181, 174, 224, 2, 224, 174, 164, 224, 175, 136, 0, 1, 141, 175, 224, 163, 174, 224, 128, 175, 224, 181, 174, 224, 2, 224, 174, 181, 224, 174, 178, 224, 175, 136, 0, 1, 141, 175, 224, 163, 174, 224, 128, 175, 224, 181, 174, 224, 2, 224, 174, 183, 224, 175, 141, 224, 174, 159, 0, 1, 141, 175, 224, 178, 174, 224, 138, 175, 224, 149, 174, 224, 2, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 190, 0, 1, 141, 175, 224, 178, 174, 224, 175, 174, 224, 136, 175, 224, 174, 174, 224, 154, 174, 224, 2, 224, 174, 159, 224, 175, 141, 0, 1, 141, 175, 224, 179, 174, 224, 137, 174, 224, 2, 224, 174, 159, 224, 175, 141, 224, 174, 159, 0, 1, 154, 174, 224, 141, 175, 224, 154, 174, 224, 137, 174, 224, 2, 224, 174, 159, 224, 175, 141, 224, 174, 159, 0, 1, 154, 174, 224, 141, 175, 224, 158, 174, 224, 170, 174, 224, 2, 224, 174, 178, 224, 175, 141, 224, 174, 175, 224, 174, 190, 224, 174, 163, 0, 1, 154, 174, 224, 141, 175, 224, 158, 174, 224, 170, 174, 224, 2, 224, 174, 181, 224, 175, 141, 224, 174, 175, 0, 1, 159, 174, 224, 149, 174, 224, 191, 174, 224, 181, 174, 224, 2, 224, 174, 181, 224, 174, 191, 0, 1, 164, 174, 224, 141, 175, 224, 168, 174, 224, 136, 175, 224, 174, 174, 224, 133, 174, 224, 2, 224, 174, 176, 224, 175, 136, 0, 1, 169, 174, 224, 191, 174, 224, 164, 174, 224, 2, 224, 174, 176, 0, 1, 170, 174, 224, 141, 175, 224, 174, 174, 224, 176, 174, 224, 134, 174, 224, 2, 224, 174, 159, 224, 175, 141, 224, 174, 159, 0, 1, 178, 174, 224, 149, 174, 224, 154, 174, 224, 2, 224, 174, 178, 224, 174, 190, 0, 1, 181, 174, 224, 141, 175, 224, 184, 174, 224, 191, 174, 224, 181, 174, 224, 2, 224, 174, 176, 224, 175, 141, 224, 174, 174, 224, 174, 190, 0, 1, 190, 174, 224, 149, 174, 224, 174, 174, 224, 2, 224, 174, 181, 224, 174, 191, 0, 1, 190, 174, 224, 164, 174, 224, 129, 175, 224, 154, 174, 224, 2, 224, 174, 176, 224, 174, 191, 224, 174, 159, 0, 1, 190, 174, 224, 164, 174, 224, 129, 175, 224, 154, 174, 224, 2, 224, 174, 176, 224, 174, 191, 224, 174, 169, 0, 1, 190, 174, 224, 164, 174, 224, 129, 175, 224, 154, 174, 224, 2, 224, 174, 176, 224, 175, 141, 32, 0, 1, 190, 174, 224, 170, 174, 224, 176, 174, 224, 191, 174, 224, 170, 174, 224, 2, 224, 174, 176, 0, 1, 190, 174, 224, 181, 174, 224, 191, 174, 224, 164, 174, 224, 2, 224, 174, 176, 0, 1, 190, 174, 224, 185, 174, 224, 174, 174, 224, 2, 224, 174, 181, 224, 174, 191, 0, 2, 224, 174, 181, 224, 174, 191, 224, 174, 158, 0, 2, 224, 174, 181, 224, 174, 191, 224, 174, 176, 224, 174, 190, 224, 174, 175, 0, 8, 0, 8, 2, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 190, 224, 174, 176, 224, 175, 129, 0, 8, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 139, 175, 224, 178, 174, 224, 2, 224, 174, 178, 0, 8, 140, 175, 224, 154, 174, 224, 2, 224, 174, 176, 224, 174, 191, 224, 174, 175, 0, 8, 141, 175, 224, 153, 174, 224, 191, 174, 224, 178, 174, 224, 2, 224, 174, 169, 0, 8, 141, 175, 224, 163, 174, 224, 128, 175, 224, 181, 174, 224, 2, 224, 174, 169, 224, 174, 181, 0, 8, 141, 175, 224, 163, 174, 224, 191, 174, 224, 181, 174, 224, 2, 224, 174, 177, 224, 175, 141, 0, 8, 141, 175, 224, 163, 174, 224, 191, 174, 224, 181, 174, 224, 2, 224, 174, 179, 0, 8, 141, 175, 224, 169, 174, 224, 129, 175, 224, 174, 174, 224, 2, 224, 174, 159, 224, 175, 141, 224, 174, 159, 0, 8, 141, 175, 224, 169, 174, 224, 191, 174, 224, 170, 174, 224, 2, 224, 174, 159, 224, 175, 141, 224, 174, 159, 0, 8, 141, 175, 224, 178, 174, 224, 129, 175, 224, 149, 174, 224, 2, 224, 174, 176, 224, 175, 141, 224, 174, 169, 224, 174, 191, 0, 8, 141, 175, 224, 178, 174, 224, 134, 175, 224, 181, 174, 224, 2, 224, 174, 174, 0, 8, 141, 175, 224, 178, 174, 224, 149, 174, 224, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 8, 141, 175, 224, 178, 174, 224, 149, 174, 224, 2, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 190, 0, 8, 163, 174, 224, 176, 174, 224, 2, 224, 174, 179, 0, 8, 174, 174, 224, 141, 175, 224, 176, 174, 224, 164, 174, 224, 2, 224, 174, 176, 224, 175, 141, 224, 174, 164, 0, 8, 175, 174, 224, 141, 175, 224, 164, 174, 224, 154, 174, 224, 2, 224, 174, 178, 224, 174, 190, 0, 8, 175, 174, 224, 191, 174, 224, 164, 174, 224, 141, 175, 224, 164, 174, 224, 154, 174, 224, 2, 224, 174, 178, 224, 174, 190, 0, 8, 175, 174, 224, 191, 174, 224, 176, 174, 224, 130, 175, 224, 154, 174, 224, 2, 224, 174, 178, 224, 174, 190, 0, 8, 176, 174, 224, 191, 174, 224, 164, 174, 224, 141, 175, 224, 164, 174, 224, 191, 174, 224, 154, 174, 224, 2, 224, 174, 178, 224, 174, 190, 0, 8, 176, 174, 224, 191, 174, 224, 164, 174, 224, 141, 175, 224, 168, 174, 224, 154, 174, 224, 2, 224, 174, 178, 224, 174, 190, 0, 8, 178, 174, 224, 190, 174, 224, 149, 174, 224, 2, 224, 174, 159, 224, 175, 141, 224, 174, 159, 0, 8, 181, 174, 224, 128, 175, 224, 156, 174, 224, 2, 224, 174, 178, 224, 175, 136, 0, 8, 191, 174, 224, 154, 174, 224, 154, 174, 224, 2, 224, 174, 178, 224, 174, 190, 0, 8, 191, 174, 224, 159, 174, 224, 134, 175, 224, 174, 174, 224, 2, 224, 174, 178, 0, 8, 191, 174, 224, 159, 174, 224, 141, 175, 224, 149, 174, 224, 190, 174, 224, 176, 174, 224, 141, 175, 224, 170, 174, 224, 2, 224, 174, 178, 0, 224, 174, 178, 224, 175, 141, 224, 174, 170, 8, 175, 174, 224, 190, 174, 224, 149, 174, 224, 3, 49, 109, 55, 48, 149, 0, 224, 174, 159, 8, 141, 175, 224, 153, 174, 224, 134, 175, 224, 181, 174, 224, 3, 49, 109, 140, 149, 0, 224, 175, 135, 224, 174, 159, 8, 138, 175, 224, 178, 174, 224, 3, 49, 114, 140, 149, 0, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 159, 8, 156, 174, 224, 3, 49, 118, 34, 140, 149, 0, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 8, 128, 175, 224, 176, 174, 224, 141, 175, 224, 184, 174, 224, 3, 49, 118, 50, 47, 149, 0, 224, 175, 139, 224, 174, 170, 8, 2, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 129, 3, 49, 119, 71, 0, 224, 175, 129, 224, 174, 174, 224, 175, 134, 224, 174, 163, 224, 175, 141, 224, 174, 159, 8, 190, 174, 224, 159, 174, 224, 3, 49, 122, 65, 36, 66, 47, 149, 0, 224, 175, 140, 224, 174, 154, 224, 174, 191, 224, 174, 149, 8, 3, 49, 135, 89, 37, 49, 149, 0, 224, 175, 141, 224, 174, 159, 224, 175, 141, 3, 49, 140, 0, 224, 175, 141, 224, 174, 159, 224, 175, 141, 224, 174, 176, 224, 174, 191, 224, 174, 149, 8, 134, 175, 224, 178, 174, 224, 142, 174, 224, 2, 224, 174, 178, 3, 49, 140, 34, 37, 49, 109, 0, 224, 175, 141, 224, 174, 159, 3, 49, 140, 149, 0, 4, 1, 141, 175, 224, 149, 174, 224, 3, 49, 149, 0, 8, 141, 175, 224, 175, 174, 224, 190, 174, 224, 174, 174, 224, 156, 174, 224, 0, 8, 190, 174, 224, 159, 174, 224, 141, 175, 224, 184, 174, 224, 0, 8, 191, 174, 224, 170, 174, 224, 139, 175, 224, 149, 174, 224, 0, 4, 224, 175, 129, 1, 141, 175, 224, 163, 174, 224, 174, 174, 224, 133, 174, 224, 2, 224, 174, 159, 224, 174, 191, 3, 49, 151, 0, 224, 175, 129, 1, 141, 175, 224, 169, 174, 224, 174, 174, 224, 141, 175, 224, 174, 174, 224, 133, 174, 224, 2, 224, 174, 159, 224, 174, 191, 0, 224, 175, 129, 1, 141, 175, 224, 176, 174, 224, 190, 174, 224, 169, 174, 224, 141, 175, 224, 169, 174, 224, 174, 174, 224, 2, 224, 174, 159, 224, 174, 191, 0, 224, 175, 129, 1, 141, 175, 224, 176, 174, 224, 190, 174, 224, 175, 174, 224, 136, 175, 224, 159, 174, 224, 137, 174, 224, 2, 224, 174, 159, 224, 174, 191, 0, 224, 175, 129, 1, 175, 174, 224, 191, 174, 224, 176, 174, 224, 133, 174, 224, 2, 224, 174, 159, 224, 174, 191, 0, 224, 175, 129, 8, 174, 174, 224, 176, 174, 224, 170, 174, 224, 2, 224, 174, 159, 224, 174, 191, 0, 4, 1, 141, 175, 224, 149, 174, 224, 136, 175, 224, 178, 174, 224, 174, 174, 224, 2, 224, 175, 129, 224, 174, 149, 224, 175, 136, 3, 81, 0, 1, 141, 175, 224, 149, 174, 224, 191, 174, 224, 177, 174, 224, 143, 174, 224, 2, 224, 175, 129, 224, 174, 164, 224, 174, 191, 0, 1, 141, 175, 224, 153, 174, 224, 2, 224, 174, 191, 224, 174, 176, 224, 175, 129, 0, 1, 141, 175, 224, 153, 174, 224, 133, 174, 224, 2, 224, 175, 138, 0, 1, 141, 175, 224, 153, 174, 224, 135, 174, 224, 2, 224, 175, 138, 0, 1, 141, 175, 224, 177, 174, 224, 168, 174, 224, 2, 224, 175, 129, 224, 174, 163, 0, 2, 17, 66, 0, 2, 224, 175, 128, 224, 174, 164, 0, 8, 2, 17, 66, 28, 17, 12, 0, 8, 2, 224, 174, 190, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 190, 224, 174, 174, 224, 174, 191, 224, 174, 176, 224, 175, 129, 224, 174, 149, 0, 8, 2, 224, 174, 190, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 175, 128, 224, 174, 170, 0, 8, 2, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 149, 224, 175, 141, 0, 8, 2, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 170, 224, 175, 141, 0, 8, 2, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 174, 224, 174, 190, 0, 8, 2, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 190, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 169, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 174, 190, 224, 174, 169, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 174, 190, 224, 174, 169, 224, 174, 174, 0, 8, 2, 224, 174, 190, 224, 174, 169, 224, 174, 181, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 136, 0, 8, 2, 224, 174, 190, 224, 174, 169, 224, 174, 190, 0, 8, 2, 224, 174, 190, 224, 174, 175, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 159, 224, 174, 169, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 175, 224, 174, 169, 0, 8, 2, 224, 174, 191, 224, 174, 131, 224, 174, 170, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 174, 191, 224, 174, 159, 224, 175, 129, 224, 174, 149, 224, 174, 191, 224, 174, 159, 224, 175, 129, 0, 8, 2, 224, 174, 191, 224, 174, 163, 224, 175, 141, 224, 174, 163, 224, 175, 134, 224, 174, 169, 224, 175, 141, 224, 174, 177, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 174, 184, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 175, 134, 224, 174, 169, 224, 175, 141, 224, 174, 177, 0, 8, 2, 224, 174, 191, 224, 174, 175, 224, 174, 176, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 190, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 156, 224, 174, 190, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 164, 224, 174, 176, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 164, 224, 174, 190, 224, 174, 176, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 174, 190, 224, 174, 149, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 174, 190, 224, 174, 178, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 174, 191, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 175, 129, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 181, 224, 174, 178, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 175, 128, 224, 174, 183, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 175, 129, 224, 174, 149, 224, 174, 184, 224, 175, 141, 224, 174, 164, 224, 174, 176, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 175, 129, 224, 174, 149, 224, 174, 191, 224, 174, 176, 224, 175, 129, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 175, 129, 224, 174, 185, 224, 174, 184, 224, 175, 141, 224, 174, 164, 224, 174, 176, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 175, 141, 224, 174, 176, 224, 175, 134, 0, 8, 2, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 174, 224, 174, 190, 0, 8, 2, 224, 175, 129, 224, 174, 149, 224, 174, 168, 224, 174, 190, 224, 174, 164, 0, 8, 2, 224, 175, 129, 224, 174, 149, 224, 174, 169, 0, 8, 2, 224, 175, 129, 224, 174, 149, 224, 174, 176, 224, 174, 190, 224, 174, 156, 0, 8, 2, 224, 175, 129, 224, 174, 149, 224, 175, 136, 0, 8, 2, 224, 175, 129, 224, 174, 156, 224, 174, 176, 224, 174, 190, 224, 174, 164, 0, 8, 2, 224, 175, 129, 224, 174, 156, 224, 174, 190, 224, 174, 178, 0, 8, 2, 224, 175, 129, 224, 174, 159, 224, 174, 191, 224, 174, 175, 224, 174, 190, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 175, 129, 224, 174, 159, 224, 175, 129, 224, 174, 149, 224, 175, 129, 224, 174, 159, 224, 175, 129, 0, 8, 2, 224, 175, 129, 224, 174, 163, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 175, 129, 224, 174, 163, 224, 174, 154, 224, 175, 128, 224, 174, 178, 0, 8, 2, 224, 175, 129, 224, 174, 163, 224, 174, 154, 224, 175, 135, 224, 174, 149, 224, 174, 176, 0, 8, 2, 224, 175, 129, 224, 174, 163, 224, 174, 154, 224, 175, 141, 0, 8, 2, 224, 175, 129, 224, 174, 163, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 175, 129, 224, 174, 163, 224, 174, 168, 224, 174, 178, 0, 8, 2, 224, 175, 129, 224, 174, 163, 224, 174, 170, 224, 174, 176, 0, 8, 2, 224, 175, 129, 224, 174, 163, 224, 174, 170, 224, 174, 190, 224, 174, 178, 0, 8, 2, 224, 175, 129, 224, 174, 163, 224, 174, 170, 224, 175, 130, 224, 174, 183, 0, 8, 2, 224, 175, 129, 224, 174, 163, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 159, 0, 8, 2, 224, 175, 129, 224, 174, 163, 224, 174, 174, 0, 8, 2, 224, 175, 129, 224, 174, 163, 224, 174, 181, 224, 174, 164, 224, 174, 191, 0, 8, 2, 224, 175, 129, 224, 174, 163, 224, 174, 181, 224, 174, 190, 224, 174, 169, 0, 8, 2, 224, 175, 129, 224, 174, 163, 224, 174, 190, 0, 8, 2, 224, 175, 129, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 175, 129, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 0, 8, 2, 224, 175, 129, 224, 174, 164, 224, 174, 191, 224, 174, 154, 224, 175, 141, 0, 8, 2, 224, 175, 129, 224, 174, 164, 224, 174, 191, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 175, 129, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 0, 8, 2, 224, 175, 129, 224, 174, 170, 224, 175, 128, 224, 174, 176, 0, 8, 2, 224, 175, 129, 224, 174, 170, 224, 175, 129, 224, 174, 149, 224, 175, 129, 224, 174, 170, 224, 175, 129, 0, 8, 2, 224, 175, 129, 224, 174, 170, 224, 175, 129, 224, 174, 149, 224, 175, 141, 0, 8, 2, 224, 175, 129, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 129, 224, 174, 169, 0, 8, 2, 224, 175, 129, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 134, 224, 174, 169, 224, 175, 141, 224, 174, 177, 0, 8, 2, 224, 175, 129, 224, 174, 174, 224, 174, 190, 224, 174, 184, 224, 175, 141, 224, 174, 164, 224, 174, 190, 0, 8, 2, 224, 175, 129, 224, 174, 174, 224, 175, 129, 224, 174, 149, 224, 175, 129, 224, 174, 174, 224, 175, 129, 0, 8, 2, 224, 175, 129, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 174, 178, 0, 8, 2, 224, 175, 129, 224, 174, 174, 224, 175, 141, 224, 174, 174, 224, 174, 169, 224, 174, 190, 224, 174, 158, 224, 175, 141, 224, 174, 154, 224, 174, 190, 224, 174, 181, 224, 174, 159, 224, 174, 191, 0, 8, 2, 224, 175, 129, 224, 174, 174, 224, 175, 141, 224, 174, 174, 224, 174, 190, 224, 174, 179, 0, 8, 2, 224, 175, 129, 224, 174, 174, 224, 175, 141, 224, 174, 174, 224, 174, 191, 224, 174, 159, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 130, 224, 174, 163, 224, 175, 141, 0, 8, 2, 224, 175, 129, 224, 174, 174, 224, 175, 141, 224, 174, 174, 224, 174, 191, 224, 174, 176, 224, 175, 129, 224, 174, 159, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 175, 129, 224, 174, 174, 224, 175, 141, 224, 174, 174, 224, 175, 129, 224, 174, 169, 0, 8, 2, 224, 175, 129, 224, 174, 174, 224, 175, 141, 224, 174, 174, 224, 175, 134, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 149, 224, 175, 129, 224, 174, 178, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 179, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 178, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 154, 224, 174, 190, 224, 174, 174, 224, 174, 191, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 156, 224, 174, 191, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 164, 224, 175, 135, 224, 174, 181, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 168, 224, 174, 190, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 170, 224, 174, 149, 224, 174, 181, 224, 174, 190, 224, 174, 169, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 170, 224, 175, 130, 224, 174, 156, 224, 175, 136, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 134, 224, 174, 175, 224, 174, 176, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 174, 224, 174, 190, 224, 174, 176, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 174, 224, 175, 130, 224, 174, 176, 224, 175, 141, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 176, 224, 174, 190, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 181, 224, 174, 159, 224, 174, 191, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 181, 224, 174, 190, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 181, 224, 174, 190, 224, 174, 175, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 181, 224, 174, 191, 224, 174, 159, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 181, 224, 174, 191, 224, 174, 169, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 181, 224, 175, 129, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 181, 224, 175, 129, 224, 174, 159, 224, 175, 136, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 181, 224, 175, 136, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 181, 224, 175, 139, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 181, 224, 175, 139, 224, 174, 159, 0, 8, 2, 224, 175, 129, 224, 174, 178, 224, 174, 190, 224, 174, 170, 0, 8, 2, 224, 175, 129, 224, 174, 178, 224, 174, 190, 224, 174, 174, 0, 8, 2, 224, 175, 129, 224, 174, 178, 224, 175, 135, 224, 174, 170, 224, 174, 190, 0, 8, 2, 224, 175, 129, 224, 174, 178, 224, 175, 141, 224, 174, 174, 224, 175, 139, 18, 71, 224, 174, 176, 0, 8, 2, 224, 175, 129, 224, 174, 181, 224, 174, 185, 224, 174, 190, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 0, 8, 2, 224, 175, 129, 224, 174, 184, 224, 175, 141, 224, 174, 164, 224, 174, 191, 0, 8, 2, 224, 175, 130, 224, 174, 149, 224, 174, 191, 224, 174, 179, 0, 8, 2, 224, 175, 130, 224, 174, 149, 224, 175, 129, 224, 174, 179, 0, 8, 2, 224, 175, 130, 224, 174, 159, 224, 174, 178, 224, 175, 130, 224, 174, 176, 0, 8, 2, 224, 175, 130, 224, 174, 176, 224, 175, 141, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 176, 0, 8, 2, 224, 175, 130, 224, 174, 176, 224, 175, 141, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 190, 0, 8, 2, 224, 175, 134, 224, 174, 156, 0, 8, 2, 224, 175, 134, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 0, 8, 2, 224, 175, 134, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 175, 134, 224, 174, 184, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 175, 135, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 175, 136, 0, 8, 2, 224, 175, 135, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 178, 224, 174, 191, 224, 174, 176, 224, 175, 129, 224, 174, 168, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 175, 135, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 175, 129, 224, 174, 149, 224, 174, 179, 0, 8, 2, 224, 175, 135, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 176, 224, 175, 129, 224, 174, 149, 0, 8, 2, 224, 175, 135, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 170, 224, 175, 141, 0, 8, 2, 224, 175, 135, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 175, 136, 224, 174, 149, 224, 175, 141, 0, 8, 2, 224, 175, 135, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 175, 136, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 175, 135, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 175, 136, 224, 174, 170, 224, 175, 141, 0, 8, 2, 224, 175, 135, 224, 174, 178, 224, 174, 191, 0, 8, 2, 224, 175, 135, 224, 174, 184, 224, 175, 141, 32, 18, 91, 0, 8, 2, 224, 175, 136, 224, 174, 159, 0, 8, 2, 224, 175, 136, 224, 174, 169, 224, 174, 149, 0, 8, 2, 224, 175, 138, 224, 174, 163, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 175, 138, 224, 174, 163, 224, 174, 174, 0, 8, 2, 224, 175, 138, 224, 174, 176, 224, 174, 191, 224, 174, 178, 0, 8, 2, 224, 175, 139, 224, 174, 149, 224, 175, 129, 224, 174, 178, 0, 8, 2, 224, 175, 139, 224, 174, 154, 224, 174, 190, 224, 174, 178, 224, 175, 136, 0, 8, 2, 224, 175, 139, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 175, 129, 32, 224, 174, 181, 224, 174, 190, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 175, 139, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 175, 129, 0, 8, 2, 224, 175, 139, 224, 174, 164, 224, 174, 190, 224, 174, 181, 224, 174, 176, 224, 174, 191, 0, 8, 2, 224, 175, 139, 224, 174, 164, 224, 175, 129, 224, 174, 174, 224, 175, 136, 0, 8, 2, 224, 175, 139, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 175, 139, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 175, 139, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 224, 174, 174, 0, 8, 2, 224, 175, 139, 224, 174, 164, 224, 175, 141, 224, 174, 176, 224, 174, 190, 0, 8, 2, 224, 175, 139, 224, 174, 164, 224, 175, 141, 224, 174, 176, 224, 175, 135, 224, 174, 156, 224, 175, 141, 0, 8, 2, 224, 175, 139, 224, 174, 168, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 175, 139, 224, 174, 170, 224, 174, 191, 224, 174, 149, 224, 175, 136, 0, 8, 2, 224, 175, 139, 224, 174, 170, 224, 174, 191, 224, 174, 154, 224, 175, 134, 224, 174, 159, 224, 175, 141, 0, 8, 2, 224, 175, 139, 224, 174, 170, 224, 174, 191, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 175, 134, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 0, 8, 2, 224, 175, 139, 224, 174, 170, 224, 174, 191, 224, 174, 168, 224, 174, 190, 0, 8, 2, 224, 175, 139, 224, 174, 170, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 175, 139, 224, 174, 170, 224, 175, 129, 224, 174, 176, 0, 8, 2, 224, 175, 139, 224, 174, 174, 224, 174, 164, 224, 174, 191, 0, 8, 2, 224, 175, 139, 224, 174, 174, 224, 174, 164, 224, 175, 135, 224, 174, 184, 224, 175, 141, 224, 174, 181, 224, 174, 176, 0, 8, 2, 224, 175, 139, 224, 174, 174, 224, 174, 190, 224, 174, 164, 224, 174, 190, 0, 8, 2, 224, 175, 139, 224, 174, 174, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 175, 139, 224, 174, 174, 224, 175, 129, 224, 174, 149, 0, 8, 2, 224, 175, 139, 224, 174, 174, 224, 175, 130, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 0, 8, 2, 224, 175, 139, 224, 174, 175, 224, 174, 178, 0, 8, 2, 224, 175, 139, 224, 174, 176, 32, 0, 8, 2, 224, 175, 139, 224, 174, 176, 224, 174, 149, 0, 8, 2, 224, 175, 139, 224, 174, 176, 224, 174, 164, 224, 175, 141, 32, 224, 174, 164, 224, 174, 190, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 175, 139, 224, 174, 176, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 190, 224, 174, 178, 0, 8, 2, 224, 175, 139, 224, 174, 176, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 136, 0, 8, 2, 224, 175, 139, 224, 174, 176, 224, 174, 170, 224, 175, 141, 32, 18, 85, 0, 8, 2, 224, 175, 139, 224, 174, 176, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 177, 224, 175, 141, 0, 8, 2, 224, 175, 139, 224, 174, 176, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 178, 224, 175, 141, 0, 8, 2, 224, 175, 139, 224, 174, 176, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 139, 224, 174, 176, 0, 8, 2, 224, 175, 139, 224, 174, 176, 224, 174, 174, 0, 8, 2, 224, 175, 139, 224, 174, 176, 224, 175, 141, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 190, 224, 174, 178, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 175, 139, 224, 174, 178, 224, 174, 191, 224, 174, 149, 0, 8, 2, 224, 175, 139, 224, 174, 178, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 175, 139, 224, 174, 178, 224, 175, 141, 224, 174, 149, 224, 175, 138, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 190, 0, 8, 2, 224, 175, 139, 224, 174, 178, 224, 175, 141, 224, 174, 174, 224, 174, 190, 224, 174, 178, 0, 8, 2, 224, 175, 139, 224, 174, 181, 224, 174, 190, 0, 8, 2, 224, 175, 139, 224, 174, 181, 224, 174, 191, 224, 174, 168, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 175, 139, 224, 174, 183, 0, 8, 2, 224, 175, 140, 224, 174, 159, 0, 8, 2, 224, 175, 140, 224, 174, 169, 224, 175, 136, 0, 8, 2, 224, 175, 140, 224, 174, 169, 224, 175, 141, 224, 174, 149, 224, 174, 179, 0, 8, 2, 224, 175, 140, 224, 174, 176, 224, 174, 181, 0, 8, 2, 224, 175, 140, 224, 174, 176, 224, 174, 191, 0, 8, 2, 224, 175, 140, 224, 174, 179, 224, 174, 191, 0, 8, 2, 224, 175, 140, 224, 174, 179, 224, 175, 136, 0, 8, 129, 175, 224, 176, 174, 224, 134, 175, 224, 174, 174, 224, 2, 224, 175, 130, 224, 174, 159, 224, 175, 141, 224, 174, 159, 0, 8, 141, 175, 224, 149, 174, 224, 164, 174, 224, 174, 174, 224, 141, 175, 224, 169, 174, 224, 174, 174, 224, 2, 224, 175, 129, 224, 174, 149, 224, 175, 136, 0, 8, 141, 175, 224, 153, 174, 224, 149, 174, 224, 2, 224, 175, 129, 224, 174, 178, 224, 174, 191, 0, 8, 141, 175, 224, 177, 174, 224, 154, 174, 224, 2, 224, 175, 129, 224, 174, 163, 0, 224, 174, 191, 1, 141, 175, 224, 153, 174, 224, 135, 174, 224, 2, 224, 174, 178, 224, 175, 128, 224, 174, 183, 224, 175, 141, 0, 224, 174, 191, 1, 141, 175, 224, 177, 174, 224, 138, 175, 224, 170, 174, 224, 2, 224, 174, 176, 224, 174, 163, 0, 224, 174, 191, 2, 224, 174, 176, 224, 174, 163, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 149, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 149, 224, 174, 163, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 168, 224, 175, 141, 224, 174, 164, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 181, 224, 175, 129, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 185, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 174, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 149, 224, 175, 139, 224, 174, 176, 224, 174, 191, 224, 174, 175, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 178, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 128, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 128, 224, 174, 169, 224, 175, 141, 224, 174, 178, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 128, 224, 174, 184, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 135, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 136, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 176, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 140, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 224, 174, 191, 8, 2, 224, 174, 179, 224, 174, 190, 224, 174, 184, 224, 175, 141, 32, 0, 224, 175, 129, 8, 2, 224, 174, 178, 224, 175, 139, 224, 174, 170, 224, 174, 178, 0, 224, 175, 129, 8, 2, 224, 174, 179, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 139, 224, 174, 184, 0, 224, 175, 129, 8, 2, 224, 174, 181, 224, 174, 190, 224, 174, 178, 224, 174, 191, 224, 174, 175, 224, 174, 176, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 181, 224, 175, 129, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 149, 224, 175, 139, 224, 174, 176, 224, 174, 191, 224, 174, 175, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 175, 128, 224, 174, 169, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 175, 130, 224, 174, 170, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 175, 140, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 224, 175, 141, 8, 2, 224, 174, 179, 224, 174, 190, 224, 174, 184, 224, 175, 141, 32, 0, 224, 175, 141, 8, 2, 224, 174, 181, 224, 174, 190, 224, 174, 178, 224, 174, 191, 224, 174, 175, 224, 174, 176, 0, 224, 175, 141, 8, 142, 174, 224, 2, 224, 174, 184, 224, 174, 190, 224, 174, 174, 0, 224, 174, 191, 224, 174, 176, 224, 174, 190, 224, 174, 163, 224, 175, 136, 224, 174, 159, 8, 3, 81, 34, 118, 50, 134, 140, 149, 0, 4, 224, 174, 191, 224, 174, 176, 224, 174, 190, 224, 174, 131, 224, 174, 170, 224, 175, 136, 224, 174, 159, 8, 3, 81, 34, 118, 83, 134, 140, 149, 0, 224, 174, 191, 224, 174, 176, 224, 174, 190, 224, 174, 170, 224, 175, 136, 224, 174, 159, 8, 0, 224, 174, 191, 224, 174, 170, 224, 175, 141, 8, 2, 224, 174, 159, 3, 81, 37, 83, 0, 224, 174, 191, 224, 174, 159, 8, 2, 224, 174, 190, 224, 174, 176, 3, 81, 37, 140, 0, 4, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 170, 8, 2, 224, 174, 190, 224, 174, 164, 3, 81, 40, 34, 40, 48, 0, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 170, 8, 2, 224, 175, 128, 224, 174, 159, 0, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 170, 8, 2, 224, 175, 130, 0, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 170, 8, 2, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 169, 224, 174, 191, 3, 81, 40, 34, 40, 48, 109, 0, 224, 175, 129, 224, 174, 170, 224, 175, 141, 8, 2, 224, 174, 164, 3, 81, 40, 48, 0, 224, 175, 129, 224, 174, 178, 224, 175, 141, 224, 174, 149, 8, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 3, 81, 40, 55, 49, 109, 0, 224, 175, 129, 224, 174, 163, 224, 174, 154, 8, 2, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 3, 81, 40, 66, 109, 76, 0, 4, 224, 175, 129, 224, 174, 163, 224, 175, 141, 224, 174, 159, 8, 2, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 178, 3, 81, 40, 66, 140, 149, 0, 224, 175, 129, 224, 174, 163, 224, 175, 141, 224, 174, 159, 8, 2, 224, 175, 130, 224, 174, 176, 0, 224, 175, 129, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 8, 2, 224, 174, 159, 224, 174, 191, 3, 81, 40, 66, 141, 118, 50, 47, 109, 0, 4, 224, 175, 141, 224, 174, 149, 1, 18, 68, 2, 224, 175, 129, 224, 174, 149, 224, 175, 136, 3, 81, 81, 0, 224, 175, 141, 224, 174, 149, 1, 18, 68, 2, 224, 175, 129, 224, 174, 163, 0, 224, 175, 141, 224, 174, 149, 1, 18, 68, 2, 224, 175, 139, 224, 174, 170, 224, 175, 129, 224, 174, 176, 0, 224, 175, 141, 224, 174, 149, 1, 18, 68, 2, 224, 175, 139, 224, 174, 183, 0, 224, 175, 141, 224, 174, 149, 1, 129, 175, 224, 163, 174, 224, 133, 174, 224, 2, 224, 175, 129, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 224, 175, 141, 224, 174, 149, 1, 133, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 174, 191, 0, 224, 175, 141, 224, 174, 149, 1, 134, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 175, 136, 0, 224, 175, 141, 224, 174, 149, 1, 139, 175, 224, 175, 174, 224, 133, 174, 224, 2, 224, 174, 191, 224, 174, 175, 0, 224, 175, 141, 224, 174, 149, 1, 139, 175, 224, 176, 174, 224, 134, 174, 224, 2, 224, 174, 191, 224, 174, 175, 0, 224, 175, 141, 224, 174, 149, 1, 141, 175, 224, 176, 174, 224, 128, 175, 224, 164, 174, 224, 2, 224, 174, 190, 224, 174, 178, 224, 175, 139, 224, 174, 154, 224, 174, 168, 224, 175, 136, 0, 224, 175, 141, 224, 174, 149, 1, 169, 174, 224, 156, 174, 224, 2, 224, 175, 129, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 174, 178, 0, 224, 175, 141, 224, 174, 149, 1, 190, 174, 224, 156, 174, 224, 190, 174, 224, 176, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 175, 136, 0, 224, 175, 141, 224, 174, 149, 1, 190, 174, 224, 170, 174, 224, 139, 175, 224, 149, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 174, 191, 0, 224, 175, 141, 224, 174, 149, 1, 190, 174, 224, 176, 174, 224, 136, 175, 224, 181, 174, 224, 2, 224, 174, 191, 224, 174, 175, 0, 224, 175, 141, 224, 174, 149, 1, 190, 174, 224, 181, 174, 224, 141, 175, 224, 175, 174, 224, 134, 175, 224, 164, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 175, 136, 0, 224, 175, 141, 224, 174, 149, 8, 129, 175, 224, 174, 174, 224, 2, 224, 175, 129, 224, 174, 163, 0, 224, 175, 141, 224, 174, 149, 8, 135, 175, 224, 178, 174, 224, 2, 224, 174, 191, 224, 174, 175, 0, 224, 175, 141, 224, 174, 149, 8, 139, 175, 224, 175, 174, 224, 2, 224, 174, 191, 224, 174, 175, 0, 224, 175, 141, 224, 174, 149, 8, 141, 175, 224, 176, 174, 224, 139, 175, 224, 170, 174, 224, 2, 224, 175, 129, 224, 174, 163, 0, 224, 175, 141, 224, 174, 149, 8, 141, 175, 224, 176, 174, 224, 191, 174, 224, 168, 174, 224, 2, 224, 175, 129, 224, 174, 163, 0, 224, 175, 141, 224, 174, 149, 8, 178, 174, 224, 2, 224, 174, 191, 224, 174, 169, 0, 224, 175, 141, 224, 174, 149, 8, 178, 174, 224, 2, 224, 175, 135, 224, 174, 156, 0, 224, 175, 141, 224, 174, 149, 8, 190, 174, 224, 164, 174, 224, 135, 175, 224, 181, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 174, 191, 0, 224, 175, 141, 224, 174, 149, 8, 190, 174, 224, 164, 174, 224, 191, 174, 224, 181, 174, 224, 149, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 174, 191, 0, 224, 175, 141, 224, 174, 149, 8, 190, 174, 224, 181, 174, 224, 135, 175, 224, 164, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 175, 136, 0, 224, 175, 141, 224, 174, 149, 8, 191, 174, 224, 149, 174, 224, 141, 175, 224, 149, 174, 224, 190, 174, 224, 170, 174, 224, 141, 175, 224, 170, 174, 224, 129, 175, 224, 164, 174, 224, 2, 224, 175, 129, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 224, 175, 141, 224, 174, 149, 8, 191, 174, 224, 159, 174, 224, 134, 175, 224, 181, 174, 224, 2, 224, 175, 129, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 224, 175, 141, 224, 174, 149, 8, 191, 174, 224, 178, 174, 224, 139, 175, 224, 149, 174, 224, 2, 224, 175, 129, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 224, 175, 141, 224, 174, 149, 8, 191, 174, 224, 181, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 174, 153, 224, 175, 141, 0, 224, 175, 141, 224, 174, 149, 8, 191, 174, 224, 181, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 174, 174, 0, 224, 175, 141, 224, 174, 149, 8, 191, 174, 224, 181, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 174, 174, 224, 175, 141, 32, 0, 224, 175, 141, 224, 174, 149, 8, 191, 174, 224, 181, 174, 224, 2, 224, 174, 191, 224, 174, 176, 224, 174, 149, 0, 224, 175, 141, 224, 174, 149, 224, 174, 191, 1, 18, 68, 2, 224, 174, 176, 224, 174, 149, 0, 224, 175, 141, 224, 174, 149, 224, 174, 191, 1, 18, 68, 2, 224, 174, 176, 224, 174, 185, 0, 224, 175, 141, 224, 174, 149, 224, 174, 191, 1, 129, 175, 224, 149, 174, 224, 2, 224, 174, 176, 224, 174, 190, 224, 174, 174, 0, 224, 175, 141, 224, 174, 149, 224, 174, 191, 1, 129, 175, 224, 168, 174, 224, 133, 174, 224, 2, 224, 174, 176, 0, 224, 175, 141, 224, 174, 149, 224, 174, 191, 1, 129, 175, 224, 169, 174, 224, 133, 174, 224, 2, 224, 174, 176, 0, 224, 175, 141, 224, 174, 149, 224, 174, 191, 1, 133, 174, 224, 2, 224, 174, 176, 224, 174, 190, 224, 174, 174, 0, 224, 175, 141, 224, 174, 149, 224, 174, 191, 1, 135, 174, 224, 2, 224, 174, 176, 224, 174, 190, 224, 174, 174, 0, 224, 175, 141, 224, 174, 149, 224, 174, 191, 1, 190, 174, 224, 175, 174, 224, 191, 174, 224, 164, 174, 224, 141, 175, 224, 164, 174, 224, 154, 174, 224, 2, 224, 174, 176, 224, 174, 149, 0, 224, 175, 141, 224, 174, 149, 224, 174, 191, 8, 170, 174, 224, 141, 175, 224, 170, 174, 224, 141, 175, 224, 176, 174, 224, 149, 174, 224, 2, 224, 174, 176, 0, 224, 175, 141, 224, 174, 149, 224, 174, 191, 8, 179, 174, 224, 190, 174, 224, 154, 174, 224, 2, 224, 174, 176, 224, 174, 190, 224, 174, 174, 0, 224, 175, 141, 224, 174, 149, 224, 174, 191, 8, 181, 174, 224, 168, 174, 224, 2, 224, 174, 176, 18, 71, 0, 224, 175, 141, 224, 174, 149, 224, 174, 191, 8, 191, 174, 224, 178, 174, 224, 190, 174, 224, 154, 174, 224, 2, 224, 174, 176, 224, 174, 190, 224, 174, 174, 0, 4, 224, 175, 141, 224, 174, 149, 1, 18, 68, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 3, 81, 81, 109, 0, 224, 175, 141, 224, 174, 149, 1, 141, 175, 224, 176, 174, 224, 191, 174, 224, 168, 174, 224, 2, 224, 174, 164, 224, 174, 191, 0, 224, 175, 141, 224, 174, 149, 8, 129, 175, 224, 180, 174, 224, 129, 175, 224, 174, 174, 224, 2, 224, 174, 181, 224, 174, 169, 0, 224, 175, 141, 224, 174, 149, 8, 136, 175, 224, 163, 174, 224, 129, 175, 224, 164, 174, 224, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 224, 175, 141, 224, 174, 149, 8, 141, 175, 224, 176, 174, 224, 128, 175, 224, 164, 174, 224, 2, 32, 224, 174, 154, 224, 175, 129, 224, 174, 174, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 178, 224, 174, 191, 0, 224, 175, 141, 224, 174, 149, 8, 141, 175, 224, 176, 174, 224, 128, 175, 224, 164, 174, 224, 2, 224, 174, 174, 224, 174, 190, 224, 174, 149, 0, 224, 175, 141, 224, 174, 149, 8, 141, 175, 224, 176, 174, 224, 128, 175, 224, 164, 174, 224, 2, 224, 174, 174, 224, 174, 190, 224, 174, 169, 0, 224, 175, 141, 224, 174, 149, 8, 191, 174, 224, 169, 174, 224, 164, 174, 224, 2, 224, 174, 181, 224, 174, 169, 0, 4, 224, 175, 141, 224, 174, 149, 1, 141, 175, 224, 176, 174, 224, 129, 175, 224, 164, 174, 224, 3, 81, 81, 149, 0, 224, 175, 141, 224, 174, 149, 1, 141, 175, 224, 176, 174, 224, 130, 175, 224, 174, 174, 224, 0, 224, 175, 141, 224, 174, 149, 1, 141, 175, 224, 176, 174, 224, 190, 174, 224, 174, 174, 224, 0, 224, 175, 141, 224, 174, 149, 8, 141, 175, 224, 176, 174, 224, 138, 175, 224, 154, 174, 224, 0, 224, 175, 141, 224, 174, 149, 8, 141, 175, 224, 176, 174, 224, 181, 174, 224, 0, 224, 175, 141, 224, 174, 149, 8, 141, 175, 224, 176, 174, 224, 181, 174, 224, 141, 175, 224, 184, 174, 224, 0, 224, 175, 141, 224, 174, 149, 8, 156, 174, 224, 0, 4, 3, 81, 109, 0, 2, 224, 174, 156, 0, 8, 2, 28, 17, 0, 8, 2, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 170, 224, 174, 190, 224, 174, 159, 224, 174, 191, 0, 8, 2, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 176, 0, 8, 2, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 190, 0, 8, 2, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 178, 224, 174, 191, 0, 8, 2, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 175, 130, 224, 174, 178, 224, 174, 191, 0, 8, 2, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 175, 136, 0, 8, 2, 224, 174, 158, 224, 175, 141, 224, 174, 154, 224, 174, 190, 0, 8, 2, 224, 174, 159, 224, 174, 149, 224, 174, 159, 0, 8, 2, 224, 174, 159, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 178, 0, 8, 2, 224, 174, 159, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 174, 159, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 136, 0, 8, 2, 224, 174, 159, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 190, 224, 174, 176, 224, 175, 136, 0, 8, 2, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 174, 190, 224, 174, 176, 0, 8, 2, 224, 174, 159, 224, 175, 139, 224, 174, 164, 224, 175, 141, 224, 174, 149, 224, 174, 156, 0, 8, 2, 224, 174, 163, 224, 174, 170, 224, 174, 164, 224, 174, 191, 0, 8, 2, 224, 174, 163, 224, 175, 128, 224, 174, 176, 0, 8, 2, 224, 174, 163, 224, 175, 135, 0, 8, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 174, 164, 224, 174, 190, 224, 174, 175, 224, 175, 129, 224, 174, 164, 0, 8, 2, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 174, 178, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 0, 8, 2, 224, 174, 164, 224, 174, 191, 224, 174, 164, 224, 174, 190, 0, 8, 2, 224, 174, 164, 224, 174, 191, 224, 174, 174, 224, 175, 139, 224, 174, 159, 224, 175, 141, 224, 174, 154, 0, 8, 2, 224, 174, 164, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 174, 164, 224, 174, 191, 224, 174, 175, 224, 174, 191, 224, 174, 178, 224, 175, 141, 0, 8, 2, 224, 174, 164, 224, 174, 191, 224, 174, 175, 224, 175, 136, 0, 8, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 149, 0, 8, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 176, 224, 175, 141, 224, 174, 181, 0, 8, 2, 224, 174, 169, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 174, 169, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 174, 169, 224, 174, 170, 224, 174, 190, 224, 174, 159, 224, 174, 191, 0, 8, 2, 224, 174, 169, 224, 174, 174, 0, 8, 2, 224, 174, 169, 224, 174, 176, 224, 174, 149, 0, 8, 2, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 129, 224, 174, 169, 0, 8, 2, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 134, 0, 8, 2, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 134, 224, 174, 169, 224, 175, 141, 224, 174, 176, 0, 8, 2, 224, 174, 174, 224, 174, 149, 224, 174, 174, 0, 8, 2, 224, 174, 174, 224, 174, 181, 224, 175, 134, 224, 174, 169, 224, 175, 141, 224, 174, 177, 0, 8, 2, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 175, 128, 224, 174, 176, 0, 8, 2, 224, 174, 174, 224, 175, 141, 224, 174, 174, 224, 175, 129, 224, 174, 169, 0, 8, 2, 224, 174, 174, 224, 175, 141, 224, 174, 174, 224, 175, 134, 224, 174, 169, 0, 8, 2, 224, 174, 175, 224, 174, 190, 224, 174, 154, 224, 175, 129, 224, 174, 176, 0, 8, 2, 224, 174, 175, 224, 174, 190, 224, 174, 169, 224, 174, 190, 0, 8, 2, 224, 174, 175, 224, 174, 190, 224, 174, 181, 0, 8, 2, 224, 174, 175, 224, 175, 136, 0, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 156, 0, 8, 2, 224, 174, 176, 224, 175, 129, 224, 174, 159, 0, 8, 2, 224, 174, 176, 224, 175, 141, 224, 174, 156, 0, 8, 2, 224, 174, 176, 224, 175, 141, 224, 174, 170, 0, 8, 2, 224, 174, 176, 224, 175, 141, 224, 174, 181, 0, 8, 2, 224, 174, 178, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 190, 0, 8, 2, 224, 174, 178, 224, 174, 191, 224, 174, 178, 18, 73, 224, 174, 175, 224, 175, 139, 0, 8, 2, 224, 174, 178, 224, 175, 128, 224, 174, 154, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 174, 178, 224, 175, 128, 224, 174, 176, 0, 8, 2, 224, 174, 178, 224, 175, 128, 224, 174, 178, 0, 8, 2, 224, 174, 178, 224, 175, 128, 224, 174, 183, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 174, 179, 224, 175, 129, 224, 174, 149, 224, 175, 141, 0, 8, 2, 224, 174, 181, 224, 174, 163, 0, 8, 2, 224, 174, 181, 224, 174, 169, 0, 8, 2, 224, 174, 181, 224, 174, 176, 224, 175, 141, 224, 174, 169, 224, 174, 176, 0, 8, 2, 224, 174, 181, 224, 174, 176, 224, 175, 141, 224, 174, 169, 224, 175, 141, 224, 174, 174, 224, 175, 134, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 174, 181, 224, 174, 190, 224, 174, 184, 224, 175, 141, 224, 174, 149, 224, 174, 176, 0, 8, 2, 224, 174, 181, 224, 175, 129, 224, 174, 169, 224, 175, 136, 0, 8, 2, 224, 174, 181, 224, 175, 129, 224, 174, 169, 224, 175, 141, 224, 174, 149, 224, 174, 179, 0, 8, 2, 224, 174, 181, 224, 175, 129, 224, 174, 176, 0, 8, 141, 175, 224, 149, 174, 224, 136, 175, 224, 178, 174, 224, 164, 174, 224, 2, 224, 174, 169, 0, 8, 141, 175, 224, 177, 174, 224, 168, 174, 224, 2, 224, 174, 164, 224, 174, 191, 0, 224, 174, 170, 224, 175, 141, 8, 2, 18, 69, 224, 174, 190, 3, 81, 109, 48, 0, 224, 174, 170, 224, 175, 141, 224, 174, 154, 8, 2, 224, 174, 191, 224, 174, 170, 224, 175, 141, 3, 81, 109, 48, 76, 0, 224, 174, 169, 224, 174, 149, 8, 2, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 174, 191, 224, 174, 164, 3, 81, 109, 50, 109, 49, 109, 0, 224, 174, 181, 224, 174, 176, 224, 175, 141, 224, 174, 174, 224, 175, 134, 224, 174, 163, 224, 175, 141, 224, 174, 159, 8, 3, 81, 109, 84, 109, 34, 65, 36, 66, 140, 149, 0, 224, 175, 135, 224, 174, 176, 224, 174, 163, 224, 175, 141, 224, 174, 159, 8, 3, 81, 114, 34, 109, 66, 140, 149, 0, 224, 174, 190, 224, 174, 176, 224, 174, 163, 224, 175, 141, 224, 174, 159, 8, 3, 81, 118, 34, 109, 66, 140, 149, 0, 224, 174, 190, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 175, 135, 224, 174, 149, 8, 2, 224, 174, 176, 3, 81, 118, 66, 141, 114, 49, 109, 0, 224, 174, 190, 224, 174, 154, 8, 2, 224, 174, 191, 224, 174, 175, 224, 174, 190, 224, 174, 170, 224, 174, 190, 224, 174, 164, 3, 81, 118, 88, 0, 4, 224, 175, 139, 224, 174, 170, 2, 224, 174, 190, 224, 174, 178, 3, 81, 119, 48, 0, 224, 175, 139, 224, 174, 170, 8, 2, 224, 174, 191, 224, 174, 149, 224, 174, 190, 12, 0, 224, 175, 139, 224, 174, 149, 8, 2, 224, 174, 191, 224, 174, 178, 3, 81, 119, 49, 0, 224, 175, 139, 224, 174, 149, 8, 2, 224, 174, 176, 3, 81, 119, 49, 109, 0, 224, 175, 139, 224, 174, 174, 224, 174, 164, 224, 175, 135, 224, 174, 154, 224, 175, 129, 8, 2, 224, 174, 181, 224, 174, 176, 3, 81, 119, 65, 109, 72, 114, 89, 0, 224, 175, 139, 224, 174, 159, 224, 175, 141, 224, 174, 154, 8, 2, 224, 175, 135, 3, 81, 119, 141, 89, 0, 224, 175, 130, 224, 174, 176, 224, 175, 141, 224, 174, 149, 8, 2, 224, 174, 190, 3, 81, 123, 34, 49, 0, 4, 224, 175, 134, 224, 174, 179, 8, 2, 224, 174, 164, 224, 174, 174, 3, 81, 135, 0, 224, 175, 134, 224, 174, 179, 8, 2, 224, 174, 176, 224, 174, 181, 0, 224, 175, 134, 224, 174, 179, 8, 2, 224, 174, 176, 224, 174, 191, 0, 224, 175, 140, 224, 174, 164, 8, 3, 81, 135, 47, 149, 0, 4, 224, 175, 141, 224, 174, 159, 1, 142, 174, 224, 2, 224, 175, 135, 3, 81, 141, 0, 224, 175, 141, 224, 174, 159, 8, 134, 175, 224, 185, 174, 224, 2, 224, 175, 135, 32, 0, 224, 175, 141, 224, 174, 159, 8, 134, 175, 224, 185, 174, 224, 2, 224, 175, 135, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 224, 175, 141, 224, 174, 159, 8, 134, 175, 224, 185, 174, 224, 2, 224, 175, 135, 224, 174, 175, 0, 224, 175, 141, 224, 174, 159, 8, 134, 175, 224, 185, 174, 224, 2, 224, 175, 135, 224, 174, 181, 0, 4, 1, 139, 175, 224, 174, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 174, 191, 3, 108, 0, 1, 174, 174, 224, 2, 224, 174, 190, 0, 1, 174, 174, 224, 2, 224, 175, 135, 224, 174, 154, 224, 175, 129, 224, 174, 181, 224, 174, 176, 0, 1, 174, 174, 224, 2, 224, 175, 135, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 0, 1, 174, 174, 224, 2, 224, 175, 135, 224, 174, 183, 224, 175, 141, 224, 174, 181, 0, 1, 174, 174, 224, 2, 224, 175, 135, 224, 174, 184, 224, 175, 141, 224, 174, 181, 224, 174, 176, 0, 8, 174, 174, 224, 2, 224, 174, 191, 224, 174, 168, 224, 175, 141, 224, 174, 164, 0, 8, 174, 174, 224, 2, 224, 174, 191, 224, 174, 174, 224, 175, 136, 0, 1, 139, 175, 224, 174, 174, 224, 2, 224, 174, 169, 3, 108, 109, 0, 224, 174, 190, 224, 174, 170, 1, 178, 174, 224, 133, 174, 224, 2, 224, 174, 190, 224, 174, 164, 224, 175, 141, 3, 108, 118, 71, 0, 7, 6, 1, 26, 0, 2, 17, 66, 3, 68, 0, 3, 68, 109, 0, 7, 6, 1, 27, 0, 1, 141, 175, 224, 158, 174, 224, 2, 17, 66, 3, 75, 0, 1, 141, 175, 224, 158, 174, 224, 3, 75, 109, 0, 4, 1, 32, 141, 175, 224, 154, 174, 224, 2, 17, 66, 3, 76, 0, 1, 134, 174, 224, 2, 224, 174, 190, 224, 174, 176, 32, 0, 1, 134, 174, 224, 2, 224, 174, 190, 224, 174, 176, 224, 174, 164, 224, 175, 141, 0, 1, 134, 174, 224, 2, 224, 174, 190, 224, 174, 176, 224, 174, 174, 0, 1, 141, 175, 224, 159, 174, 224, 2, 17, 66, 0, 1, 141, 175, 224, 177, 174, 224, 2, 17, 66, 0, 1, 170, 174, 224, 133, 174, 224, 2, 224, 174, 190, 224, 174, 176, 0, 1, 170, 174, 224, 137, 174, 224, 2, 224, 174, 190, 224, 174, 176, 0, 1, 170, 174, 224, 139, 175, 224, 156, 174, 224, 190, 174, 224, 176, 174, 224, 2, 224, 174, 190, 224, 174, 176, 0, 1, 170, 174, 224, 191, 174, 224, 181, 174, 224, 2, 224, 174, 190, 224, 174, 176, 0, 1, 190, 174, 224, 174, 174, 224, 154, 174, 224, 2, 224, 174, 190, 224, 174, 176, 0, 1, 190, 174, 224, 178, 174, 224, 149, 174, 224, 2, 224, 174, 190, 224, 174, 176, 0, 1, 191, 174, 224, 181, 174, 224, 2, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 0, 2, 224, 175, 134, 224, 174, 184, 224, 175, 141, 224, 174, 159, 224, 174, 176, 0, 8, 2, 17, 66, 28, 17, 0, 8, 2, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 163, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 175, 129, 0, 8, 2, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 175, 136, 0, 8, 2, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 184, 0, 8, 2, 224, 174, 190, 224, 174, 170, 224, 175, 141, 224, 174, 159, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 174, 224, 175, 129, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 174, 190, 224, 174, 175, 224, 174, 190, 224, 174, 181, 0, 8, 2, 224, 174, 190, 224, 174, 175, 224, 175, 141, 224, 174, 184, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 175, 129, 224, 174, 181, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 156, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 156, 224, 175, 136, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 174, 224, 174, 191, 224, 174, 169, 224, 174, 190, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 178, 224, 174, 184, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 178, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 179, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 169, 224, 175, 129, 0, 8, 2, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 169, 224, 175, 136, 0, 8, 2, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 174, 190, 0, 8, 2, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 190, 224, 174, 149, 224, 175, 139, 0, 8, 2, 224, 174, 191, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 190, 224, 174, 149, 0, 8, 2, 224, 174, 191, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 174, 191, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 170, 224, 174, 190, 224, 174, 170, 224, 175, 129, 0, 8, 2, 224, 174, 191, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 175, 129, 0, 8, 2, 224, 174, 191, 224, 174, 159, 224, 175, 141, 224, 174, 178, 0, 8, 2, 224, 174, 191, 224, 174, 164, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 174, 176, 0, 8, 2, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 169, 0, 8, 2, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 190, 0, 8, 2, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 0, 8, 2, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 224, 174, 181, 224, 174, 164, 224, 175, 136, 0, 8, 2, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 130, 224, 174, 176, 0, 8, 2, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 176, 224, 174, 181, 224, 174, 164, 224, 175, 136, 0, 8, 2, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 176, 224, 174, 190, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 0, 8, 2, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 129, 0, 8, 2, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 136, 0, 8, 2, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 184, 0, 8, 2, 224, 174, 191, 224, 174, 178, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 177, 0, 8, 2, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 177, 224, 175, 136, 0, 8, 2, 224, 174, 191, 224, 174, 179, 224, 175, 141, 224, 174, 177, 0, 8, 2, 224, 175, 128, 224, 174, 169, 32, 0, 8, 2, 224, 175, 128, 224, 174, 169, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 129, 0, 8, 2, 224, 175, 128, 224, 174, 169, 224, 174, 170, 224, 175, 141, 0, 8, 2, 224, 175, 128, 224, 174, 169, 224, 174, 190, 0, 8, 2, 224, 175, 128, 224, 174, 169, 224, 174, 190, 224, 174, 181, 0, 8, 2, 224, 175, 128, 224, 174, 184, 224, 175, 129, 0, 8, 2, 224, 175, 128, 224, 174, 184, 224, 175, 136, 0, 8, 2, 224, 175, 128, 224, 174, 184, 224, 175, 141, 32, 0, 8, 2, 224, 175, 129, 224, 174, 159, 224, 174, 191, 224, 174, 164, 224, 174, 190, 224, 174, 176, 0, 8, 2, 224, 175, 129, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 170, 224, 175, 141, 0, 8, 2, 224, 175, 130, 224, 174, 175, 224, 174, 191, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 175, 130, 224, 174, 176, 224, 174, 163, 0, 8, 2, 224, 175, 134, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 175, 134, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 139, 18, 69, 0, 8, 2, 224, 175, 134, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 184, 0, 8, 2, 224, 175, 134, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 168, 224, 174, 190, 224, 174, 159, 0, 8, 2, 224, 175, 134, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 190, 224, 174, 179, 224, 175, 136, 224, 174, 175, 0, 8, 2, 224, 175, 134, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 175, 224, 174, 190, 224, 174, 176, 0, 8, 2, 224, 175, 134, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 174, 191, 0, 8, 2, 224, 175, 134, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 175, 136, 0, 8, 2, 224, 175, 134, 224, 174, 175, 224, 174, 191, 224, 174, 169, 0, 8, 2, 224, 175, 134, 224, 174, 175, 224, 175, 141, 224, 174, 169, 0, 8, 2, 224, 175, 134, 224, 174, 176, 224, 175, 141, 224, 174, 169, 224, 175, 139, 224, 174, 170, 224, 174, 191, 224, 174, 178, 0, 8, 2, 224, 175, 134, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 149, 224, 175, 141, 32, 18, 82, 0, 8, 2, 224, 175, 134, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 179, 224, 174, 191, 0, 8, 2, 224, 175, 134, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 0, 8, 2, 224, 175, 134, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 180, 224, 174, 168, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 175, 134, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 164, 224, 175, 141, 32, 18, 84, 0, 8, 2, 224, 175, 134, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 0, 8, 2, 224, 175, 134, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 136, 0, 8, 2, 224, 175, 134, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 170, 224, 175, 141, 32, 18, 83, 0, 8, 2, 224, 175, 134, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 169, 0, 8, 2, 224, 175, 134, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 190, 0, 8, 2, 224, 175, 134, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 191, 224, 174, 179, 224, 175, 141, 224, 174, 179, 224, 175, 136, 0, 8, 2, 224, 175, 134, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 134, 224, 174, 163, 224, 175, 141, 0, 8, 2, 224, 175, 134, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 136, 224, 174, 175, 224, 174, 169, 0, 8, 2, 224, 175, 134, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 174, 224, 174, 190, 0, 8, 2, 224, 175, 134, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 174, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 178, 0, 8, 2, 224, 175, 134, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 174, 224, 175, 135, 32, 0, 8, 2, 224, 175, 134, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 175, 136, 224, 174, 175, 224, 174, 190, 0, 8, 2, 224, 175, 134, 224, 174, 184, 224, 175, 141, 0, 8, 2, 224, 175, 135, 224, 174, 158, 224, 175, 141, 224, 174, 154, 0, 8, 2, 224, 175, 135, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 169, 0, 8, 2, 224, 175, 135, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 176, 224, 175, 141, 224, 174, 156, 224, 174, 191, 0, 8, 2, 224, 175, 135, 224, 174, 169, 224, 174, 178, 0, 8, 2, 224, 175, 135, 224, 174, 176, 224, 174, 191, 0, 8, 2, 224, 175, 135, 224, 174, 176, 224, 175, 141, 224, 174, 149, 224, 174, 179, 0, 8, 2, 224, 175, 135, 224, 174, 176, 224, 175, 141, 224, 174, 174, 224, 175, 135, 224, 174, 169, 0, 8, 2, 224, 175, 135, 224, 174, 178, 224, 174, 158, 224, 175, 141, 0, 8, 2, 224, 175, 135, 224, 174, 183, 224, 175, 141, 224, 174, 159, 224, 175, 136, 0, 8, 2, 224, 175, 136, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 175, 136, 224, 174, 169, 224, 174, 190, 0, 8, 2, 224, 175, 136, 224, 174, 169, 224, 174, 190, 224, 174, 181, 0, 8, 2, 224, 175, 136, 224, 174, 169, 224, 175, 128, 224, 174, 184, 0, 8, 2, 224, 175, 139, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 190, 0, 8, 2, 224, 175, 139, 224, 174, 169, 224, 175, 141, 224, 174, 169, 0, 8, 2, 224, 175, 139, 224, 174, 181, 224, 175, 129, 0, 8, 2, 224, 175, 139, 224, 174, 181, 224, 175, 134, 0, 8, 2, 224, 175, 140, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 164, 224, 174, 190, 224, 174, 176, 0, 8, 2, 224, 175, 140, 224, 174, 164, 224, 174, 176, 224, 174, 191, 0, 8, 2, 224, 175, 140, 224, 174, 164, 224, 174, 191, 224, 174, 176, 224, 174, 191, 0, 8, 2, 224, 175, 140, 224, 174, 185, 224, 174, 190, 224, 174, 169, 0, 8, 18, 71, 176, 174, 224, 191, 174, 224, 149, 174, 224, 2, 224, 174, 190, 224, 174, 176, 0, 8, 128, 175, 224, 176, 174, 224, 2, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 156, 0, 8, 129, 175, 224, 154, 174, 224, 2, 224, 175, 128, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 0, 8, 141, 175, 224, 184, 174, 224, 191, 174, 224, 159, 174, 224, 2, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 156, 0, 8, 154, 174, 224, 2, 224, 174, 191, 224, 174, 169, 0, 8, 175, 174, 224, 190, 174, 224, 176, 174, 224, 191, 174, 224, 170, 174, 224, 2, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 190, 174, 224, 163, 174, 224, 129, 175, 224, 149, 174, 224, 2, 224, 174, 190, 224, 174, 176, 0, 8, 191, 174, 224, 170, 174, 224, 139, 175, 224, 149, 174, 224, 2, 224, 175, 134, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 0, 224, 175, 141, 2, 32, 24, 0, 224, 175, 141, 224, 174, 154, 2, 17, 66, 3, 76, 12, 0, 224, 175, 141, 224, 174, 154, 3, 76, 12, 109, 0, 224, 175, 134, 224, 174, 149, 224, 175, 141, 8, 2, 32, 3, 76, 36, 49, 0, 224, 175, 134, 224, 174, 154, 224, 175, 141, 8, 2, 224, 174, 169, 224, 174, 191, 224, 174, 175, 224, 174, 190, 3, 76, 36, 76, 0, 4, 224, 175, 134, 224, 174, 154, 8, 2, 224, 174, 169, 224, 174, 191, 224, 174, 175, 224, 174, 190, 3, 76, 36, 76, 109, 0, 224, 175, 134, 224, 174, 154, 8, 2, 224, 174, 169, 224, 175, 141, 224, 174, 175, 224, 174, 190, 0, 224, 175, 134, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 170, 8, 2, 224, 174, 190, 224, 174, 179, 224, 175, 136, 224, 174, 175, 3, 76, 36, 140, 140, 37, 48, 0, 224, 174, 191, 224, 174, 164, 1, 129, 175, 224, 154, 174, 224, 2, 224, 175, 141, 224, 174, 176, 224, 174, 190, 3, 76, 37, 47, 0, 224, 174, 191, 224, 174, 170, 224, 175, 141, 8, 2, 224, 174, 149, 224, 174, 179, 3, 76, 37, 48, 0, 4, 224, 174, 191, 224, 174, 149, 8, 2, 224, 174, 190, 224, 174, 149, 224, 175, 139, 3, 76, 37, 49, 0, 224, 174, 191, 224, 174, 149, 224, 175, 141, 8, 2, 224, 174, 174, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 179, 224, 175, 130, 224, 174, 176, 0, 224, 174, 191, 224, 174, 149, 224, 175, 141, 8, 2, 224, 174, 178, 224, 175, 134, 224, 174, 159, 224, 175, 141, 0, 224, 175, 141, 224, 174, 174, 224, 175, 130, 224, 174, 154, 8, 190, 174, 224, 149, 174, 224, 3, 76, 65, 123, 76, 149, 0, 4, 1, 32, 141, 175, 224, 154, 174, 224, 3, 76, 109, 0, 1, 141, 175, 224, 159, 174, 224, 0, 1, 141, 175, 224, 177, 174, 224, 0, 1, 190, 174, 224, 159, 174, 224, 149, 174, 224, 141, 175, 224, 153, 174, 224, 134, 175, 224, 181, 174, 224, 2, 224, 174, 178, 0, 1, 190, 174, 224, 159, 174, 224, 149, 174, 224, 141, 175, 224, 153, 174, 224, 135, 175, 224, 181, 174, 224, 2, 224, 174, 178, 0, 1, 190, 174, 224, 163, 174, 224, 129, 175, 224, 176, 174, 224, 133, 174, 224, 2, 224, 174, 178, 0, 1, 190, 174, 224, 164, 174, 224, 129, 175, 224, 176, 174, 224, 174, 174, 224, 2, 224, 174, 178, 0, 1, 190, 174, 224, 164, 174, 224, 135, 175, 224, 181, 174, 224, 2, 224, 174, 178, 0, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 176, 0, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 0, 8, 2, 28, 17, 0, 8, 2, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 176, 224, 174, 181, 224, 174, 176, 224, 175, 141, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 0, 8, 2, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 178, 224, 174, 191, 0, 8, 2, 224, 174, 159, 224, 175, 141, 224, 174, 159, 18, 73, 224, 174, 184, 224, 175, 141, 224, 174, 149, 224, 174, 176, 0, 8, 2, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 169, 224, 174, 191, 0, 8, 2, 224, 174, 159, 224, 175, 141, 224, 174, 169, 224, 174, 191, 0, 8, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 190, 224, 174, 179, 0, 8, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 191, 32, 0, 8, 2, 224, 174, 164, 224, 175, 129, 224, 174, 176, 224, 175, 141, 0, 8, 2, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 0, 8, 2, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 128, 224, 174, 184, 224, 175, 141, 0, 8, 2, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 129, 224, 174, 176, 224, 175, 129, 0, 8, 2, 224, 174, 164, 224, 175, 141, 224, 174, 176, 224, 174, 170, 224, 174, 164, 224, 174, 191, 0, 8, 2, 224, 174, 164, 224, 175, 141, 224, 174, 176, 224, 175, 129, 0, 8, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 175, 129, 224, 174, 176, 224, 175, 129, 0, 8, 2, 224, 174, 170, 224, 175, 141, 224, 174, 170, 18, 76, 224, 175, 141, 0, 8, 2, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 190, 0, 8, 2, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 191, 0, 8, 2, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 129, 0, 8, 2, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 134, 0, 8, 2, 224, 174, 176, 224, 175, 141, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 174, 191, 224, 174, 178, 0, 8, 2, 224, 174, 176, 224, 175, 141, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 175, 129, 0, 8, 2, 224, 174, 178, 224, 175, 139, 0, 8, 2, 224, 174, 181, 224, 174, 190, 224, 174, 169, 0, 8, 139, 175, 224, 174, 174, 224, 191, 174, 224, 181, 174, 224, 2, 224, 174, 169, 0, 8, 139, 175, 224, 174, 174, 224, 191, 174, 224, 181, 174, 224, 170, 174, 224, 190, 174, 224, 154, 174, 224, 2, 224, 174, 169, 0, 8, 139, 175, 224, 174, 174, 224, 191, 174, 224, 181, 174, 224, 181, 174, 224, 190, 174, 224, 170, 174, 224, 2, 224, 174, 169, 0, 8, 139, 175, 224, 178, 174, 224, 2, 224, 174, 169, 224, 174, 190, 0, 8, 139, 175, 224, 178, 174, 224, 169, 174, 224, 128, 175, 224, 174, 174, 224, 2, 224, 174, 169, 224, 174, 191, 0, 8, 139, 175, 224, 178, 174, 224, 178, 174, 224, 128, 175, 224, 168, 174, 224, 2, 224, 174, 169, 224, 174, 191, 0, 8, 141, 175, 224, 153, 174, 224, 170, 174, 224, 2, 224, 174, 176, 0, 8, 141, 175, 224, 169, 174, 224, 170, 174, 224, 2, 224, 174, 176, 0, 8, 141, 175, 224, 169, 174, 224, 191, 174, 224, 159, 174, 224, 2, 224, 174, 176, 0, 8, 190, 174, 224, 149, 174, 224, 191, 174, 224, 163, 174, 224, 164, 174, 224, 2, 224, 174, 178, 0, 8, 190, 174, 224, 183, 174, 224, 135, 175, 224, 154, 174, 224, 2, 224, 174, 178, 0, 224, 174, 176, 224, 175, 141, 224, 174, 154, 8, 2, 224, 174, 191, 3, 76, 109, 34, 76, 0, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 224, 174, 170, 8, 2, 224, 174, 164, 224, 174, 191, 3, 76, 109, 47, 47, 37, 34, 109, 48, 109, 0, 224, 174, 149, 224, 175, 141, 8, 170, 174, 224, 3, 76, 109, 49, 0, 4, 224, 174, 190, 8, 2, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 176, 224, 175, 141, 224, 174, 156, 224, 174, 191, 3, 76, 114, 0, 224, 174, 190, 8, 2, 224, 174, 169, 224, 174, 178, 0, 224, 174, 190, 224, 174, 176, 224, 175, 129, 224, 174, 178, 224, 174, 164, 8, 2, 224, 174, 190, 3, 76, 118, 34, 122, 55, 109, 47, 0, 224, 174, 190, 224, 174, 170, 224, 175, 141, 8, 2, 224, 174, 179, 224, 174, 191, 224, 174, 169, 3, 76, 118, 48, 0, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 170, 8, 2, 224, 175, 128, 18, 69, 3, 76, 118, 49, 48, 0, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 178, 224, 175, 135, 224, 174, 159, 224, 175, 141, 8, 3, 76, 118, 49, 55, 114, 140, 0, 4, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 8, 2, 224, 174, 191, 224, 174, 169, 224, 175, 136, 3, 76, 118, 50, 72, 0, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 8, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 32, 0, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 8, 2, 224, 174, 191, 224, 174, 178, 0, 224, 174, 190, 224, 174, 174, 224, 175, 141, 224, 174, 170, 8, 2, 224, 174, 191, 224, 174, 175, 224, 174, 169, 3, 76, 118, 65, 48, 0, 8, 141, 175, 224, 158, 174, 224, 190, 174, 224, 176, 174, 224, 3, 76, 149, 0, 4, 1, 133, 174, 224, 2, 224, 174, 190, 224, 174, 176, 224, 175, 129, 224, 174, 164, 224, 175, 128, 224, 174, 169, 3, 88, 0, 1, 134, 174, 224, 2, 224, 174, 190, 224, 174, 164, 224, 175, 141, 0, 1, 135, 175, 224, 174, 174, 224, 133, 174, 224, 2, 224, 174, 190, 224, 174, 169, 0, 1, 147, 174, 224, 2, 224, 175, 139, 224, 174, 169, 0, 8, 130, 175, 224, 175, 174, 224, 191, 174, 224, 168, 174, 224, 2, 224, 174, 191, 224, 174, 178, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 0, 8, 138, 175, 224, 174, 174, 224, 2, 224, 174, 190, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 174, 191, 0, 8, 141, 175, 224, 174, 174, 224, 176, 174, 224, 2, 224, 174, 190, 224, 174, 169, 0, 8, 168, 174, 224, 2, 224, 175, 128, 224, 174, 174, 0, 8, 168, 174, 224, 2, 224, 175, 128, 224, 174, 176, 0, 8, 185, 174, 224, 2, 224, 174, 190, 224, 174, 176, 224, 175, 135, 0, 8, 185, 174, 224, 2, 224, 175, 128, 224, 174, 174, 0, 8, 190, 174, 224, 170, 174, 224, 2, 224, 174, 191, 224, 174, 178, 0, 8, 190, 174, 224, 170, 174, 224, 131, 174, 224, 2, 224, 174, 191, 224, 174, 178, 0, 4, 1, 133, 174, 224, 2, 224, 174, 176, 224, 175, 141, 224, 174, 170, 224, 175, 136, 3, 88, 109, 0, 1, 141, 175, 224, 170, 174, 224, 131, 174, 224, 133, 174, 224, 2, 224, 174, 178, 0, 8, 2, 224, 174, 176, 224, 175, 141, 224, 174, 164, 224, 174, 190, 224, 174, 176, 224, 174, 191, 32, 0, 8, 2, 224, 174, 176, 224, 175, 141, 224, 174, 164, 224, 174, 190, 224, 174, 176, 224, 174, 191, 224, 174, 175, 0, 8, 135, 175, 224, 176, 174, 224, 2, 224, 174, 176, 0, 8, 190, 174, 224, 168, 174, 224, 2, 224, 174, 176, 0, 4, 2, 17, 66, 3, 89, 0, 8, 2, 17, 66, 0, 8, 2, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 191, 224, 174, 176, 224, 174, 174, 224, 175, 136, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 190, 224, 174, 178, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 169, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 178, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 136, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 174, 174, 224, 174, 190, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 174, 174, 224, 175, 141, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 174, 174, 224, 175, 141, 224, 174, 164, 224, 174, 190, 224, 174, 169, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 224, 174, 185, 224, 174, 190, 0, 8, 2, 224, 175, 128, 224, 174, 169, 224, 174, 191, 224, 174, 181, 224, 174, 190, 0, 8, 2, 224, 175, 136, 224, 174, 169, 224, 174, 190, 32, 224, 174, 168, 224, 175, 135, 224, 174, 181, 224, 174, 190, 224, 174, 178, 0, 8, 135, 175, 224, 164, 174, 224, 2, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 0, 224, 174, 191, 2, 224, 174, 176, 224, 174, 174, 0, 224, 174, 191, 8, 2, 224, 174, 168, 224, 175, 135, 0, 224, 174, 191, 8, 2, 224, 174, 169, 224, 175, 135, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 224, 174, 191, 8, 2, 224, 174, 178, 224, 174, 190, 224, 174, 149, 224, 174, 191, 0, 224, 174, 191, 8, 2, 224, 174, 178, 224, 175, 135, 224, 174, 159, 0, 224, 175, 129, 1, 128, 175, 224, 176, 174, 224, 190, 174, 224, 169, 174, 224, 164, 174, 224, 141, 175, 224, 164, 174, 224, 141, 175, 224, 176, 174, 224, 133, 174, 224, 2, 224, 174, 181, 0, 224, 175, 129, 1, 135, 174, 224, 2, 224, 174, 178, 224, 174, 190, 0, 224, 175, 129, 1, 135, 175, 224, 149, 174, 224, 2, 224, 174, 181, 0, 224, 175, 129, 1, 135, 175, 224, 156, 174, 224, 190, 174, 224, 176, 174, 224, 2, 224, 174, 181, 224, 174, 176, 0, 224, 175, 129, 1, 135, 175, 224, 159, 174, 224, 141, 175, 224, 163, 174, 224, 190, 174, 224, 178, 174, 224, 191, 174, 224, 149, 174, 224, 133, 174, 224, 2, 224, 174, 181, 224, 174, 176, 0, 224, 175, 129, 1, 135, 175, 224, 163, 174, 224, 181, 174, 224, 190, 174, 224, 176, 174, 224, 2, 224, 174, 181, 224, 174, 176, 0, 224, 175, 129, 1, 135, 175, 224, 163, 174, 224, 181, 174, 224, 190, 174, 224, 176, 174, 224, 135, 174, 224, 2, 224, 174, 181, 224, 174, 176, 0, 224, 175, 129, 1, 135, 175, 224, 174, 174, 224, 2, 224, 174, 181, 0, 224, 175, 129, 1, 191, 174, 224, 181, 174, 224, 2, 224, 174, 181, 0, 224, 175, 129, 2, 224, 174, 181, 224, 174, 190, 224, 174, 164, 224, 175, 128, 224, 174, 169, 0, 224, 175, 129, 2, 224, 174, 181, 224, 174, 190, 224, 174, 174, 224, 174, 191, 0, 224, 175, 129, 2, 224, 174, 181, 224, 174, 190, 224, 174, 176, 224, 174, 184, 224, 175, 141, 224, 174, 175, 0, 224, 175, 129, 8, 2, 224, 174, 176, 224, 175, 129, 224, 174, 164, 224, 174, 191, 0, 224, 175, 129, 8, 2, 224, 174, 178, 224, 175, 139, 224, 174, 149, 0, 224, 175, 129, 8, 2, 224, 174, 181, 224, 174, 176, 224, 175, 141, 224, 174, 163, 0, 224, 175, 129, 8, 2, 224, 174, 181, 224, 174, 190, 224, 174, 154, 0, 224, 175, 129, 8, 2, 224, 174, 181, 224, 174, 191, 224, 174, 159, 224, 175, 141, 224, 174, 154, 0, 224, 175, 129, 8, 2, 224, 174, 181, 224, 174, 191, 224, 174, 184, 0, 224, 175, 129, 8, 2, 224, 174, 181, 224, 175, 128, 224, 174, 159, 0, 224, 175, 129, 8, 128, 175, 224, 169, 174, 224, 154, 174, 224, 2, 224, 174, 181, 224, 174, 176, 0, 224, 175, 129, 8, 128, 175, 224, 178, 174, 224, 190, 174, 224, 170, 174, 224, 149, 174, 224, 2, 224, 174, 181, 0, 224, 175, 129, 8, 135, 175, 224, 159, 174, 224, 141, 175, 224, 163, 174, 224, 149, 174, 224, 178, 174, 224, 156, 174, 224, 2, 224, 174, 181, 0, 224, 175, 129, 8, 135, 175, 224, 179, 174, 224, 149, 174, 224, 141, 175, 224, 153, 174, 224, 174, 174, 224, 2, 224, 174, 181, 224, 174, 176, 0, 224, 175, 129, 8, 136, 174, 224, 0, 4, 224, 174, 191, 224, 174, 176, 224, 175, 129, 8, 2, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 190, 224, 174, 176, 3, 89, 34, 37, 0, 224, 174, 191, 224, 174, 176, 224, 175, 129, 8, 2, 224, 174, 183, 224, 175, 141, 224, 174, 159, 224, 174, 191, 0, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 178, 224, 174, 153, 224, 175, 141, 224, 174, 149, 8, 2, 224, 174, 190, 3, 89, 34, 37, 55, 109, 68, 49, 0, 224, 174, 191, 224, 174, 176, 224, 174, 164, 224, 175, 141, 8, 32, 191, 174, 224, 164, 174, 224, 141, 175, 224, 149, 174, 224, 170, 174, 224, 2, 224, 174, 164, 224, 175, 136, 3, 89, 34, 109, 72, 0, 4, 224, 174, 191, 224, 174, 176, 224, 174, 164, 224, 175, 141, 224, 174, 164, 8, 2, 224, 175, 136, 224, 174, 175, 224, 175, 129, 224, 174, 159, 224, 174, 169, 3, 89, 34, 109, 72, 72, 0, 224, 174, 191, 224, 174, 176, 224, 174, 164, 224, 175, 141, 224, 174, 164, 8, 2, 224, 175, 136, 224, 174, 175, 224, 175, 136, 0, 224, 175, 128, 2, 224, 174, 169, 224, 174, 191, 224, 174, 181, 224, 174, 190, 224, 174, 154, 3, 89, 34, 112, 0, 224, 175, 134, 224, 174, 175, 224, 174, 191, 224, 174, 169, 224, 175, 141, 224, 174, 159, 8, 3, 89, 36, 57, 37, 50, 140, 0, 224, 175, 134, 224, 174, 175, 224, 175, 141, 224, 174, 169, 224, 175, 141, 224, 174, 159, 8, 3, 89, 36, 57, 50, 140, 0, 224, 175, 129, 224, 174, 181, 224, 174, 176, 224, 175, 141, 224, 174, 149, 224, 175, 141, 224, 174, 149, 8, 2, 224, 175, 139, 224, 174, 180, 224, 174, 191, 3, 89, 40, 84, 109, 34, 49, 49, 0, 224, 175, 129, 224, 174, 170, 1, 134, 174, 224, 2, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 224, 174, 191, 3, 89, 48, 109, 0, 224, 175, 129, 224, 174, 181, 224, 174, 176, 224, 175, 141, 224, 174, 149, 224, 175, 141, 224, 174, 149, 8, 3, 89, 84, 109, 34, 81, 81, 149, 0, 4, 224, 175, 129, 224, 174, 181, 224, 174, 190, 224, 174, 176, 224, 174, 154, 224, 174, 191, 1, 133, 174, 224, 2, 224, 174, 175, 3, 89, 84, 118, 34, 109, 89, 0, 224, 175, 129, 224, 174, 181, 224, 174, 190, 224, 174, 176, 224, 174, 154, 224, 174, 191, 8, 2, 224, 174, 175, 0, 4, 3, 89, 109, 0, 1, 133, 174, 224, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 176, 224, 175, 141, 224, 174, 170, 0, 8, 0, 8, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 176, 224, 175, 141, 224, 174, 170, 0, 8, 141, 175, 224, 159, 174, 224, 185, 174, 224, 2, 224, 174, 169, 0, 8, 141, 175, 224, 159, 174, 224, 190, 174, 224, 181, 174, 224, 2, 224, 174, 169, 0, 8, 141, 175, 224, 159, 174, 224, 191, 174, 224, 181, 174, 224, 135, 175, 224, 159, 174, 224, 2, 224, 174, 169, 0, 224, 174, 176, 224, 174, 154, 224, 175, 129, 8, 2, 224, 174, 181, 224, 174, 164, 224, 174, 191, 3, 89, 109, 34, 109, 89, 0, 4, 1, 135, 175, 224, 169, 174, 224, 139, 175, 224, 164, 174, 224, 141, 175, 224, 168, 174, 224, 135, 174, 224, 2, 224, 174, 191, 224, 174, 175, 3, 93, 0, 2, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 191, 0, 2, 224, 175, 134, 224, 174, 163, 224, 175, 141, 224, 174, 170, 224, 174, 149, 0, 8, 135, 175, 224, 178, 174, 224, 174, 174, 224, 2, 224, 174, 191, 224, 174, 175, 0, 4, 2, 224, 174, 163, 224, 175, 141, 224, 174, 170, 224, 174, 149, 3, 93, 109, 0, 2, 224, 174, 163, 224, 175, 141, 224, 174, 174, 224, 175, 129, 0, 8, 2, 224, 174, 176, 224, 175, 141, 224, 174, 174, 224, 174, 191, 224, 174, 179, 224, 174, 190, 0, 224, 174, 153, 224, 175, 141, 224, 174, 149, 2, 224, 174, 176, 3, 93, 109, 68, 49, 109, 0, 7, 6, 1, 29, 0, 4, 2, 17, 66, 3, 75, 0, 224, 175, 129, 8, 2, 224, 174, 181, 224, 174, 190, 224, 174, 178, 0, 3, 75, 109, 0, 8, 141, 175, 224, 169, 174, 224, 191, 174, 224, 159, 174, 224, 2, 224, 174, 176, 3, 76, 109, 0, 4, 1, 133, 174, 224, 2, 224, 174, 190, 224, 174, 176, 224, 175, 129, 224, 174, 164, 224, 175, 128, 224, 174, 169, 3, 88, 0, 8, 2, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 128, 224, 174, 176, 0, 8, 2, 224, 174, 191, 224, 174, 175, 224, 174, 190, 0, 8, 2, 224, 175, 129, 224, 174, 178, 224, 175, 141, 224, 174, 131, 224, 174, 170, 224, 174, 191, 0, 8, 2, 224, 175, 129, 224, 174, 178, 224, 175, 141, 224, 174, 170, 224, 174, 191, 0, 8, 141, 175, 224, 174, 174, 224, 176, 174, 224, 2, 224, 174, 190, 224, 174, 169, 0, 8, 170, 174, 224, 2, 224, 174, 190, 224, 174, 176, 0, 8, 190, 174, 224, 168, 174, 224, 2, 224, 174, 191, 0, 4, 8, 2, 224, 174, 176, 224, 175, 141, 224, 174, 164, 224, 174, 190, 224, 174, 176, 224, 174, 191, 3, 88, 109, 0, 8, 149, 174, 224, 2, 224, 174, 178, 224, 174, 190, 0, 8, 149, 174, 224, 2, 224, 174, 178, 224, 174, 191, 0, 8, 149, 174, 224, 2, 224, 174, 178, 224, 175, 136, 0, 8, 149, 174, 224, 2, 224, 174, 178, 224, 175, 141, 0, 224, 174, 190, 224, 174, 149, 8, 2, 224, 175, 128, 224, 174, 176, 3, 88, 118, 49, 0, 7, 6, 1, 31, 0, 4, 224, 175, 141, 224, 174, 154, 224, 175, 141, 1, 135, 174, 224, 3, 50, 76, 0, 224, 175, 141, 224, 174, 154, 224, 175, 141, 8, 191, 174, 224, 181, 174, 224, 0, 4, 224, 175, 141, 224, 174, 154, 8, 170, 174, 224, 2, 224, 174, 176, 3, 50, 76, 109, 0, 224, 175, 141, 224, 174, 154, 8, 190, 174, 224, 149, 174, 224, 2, 224, 174, 169, 0, 2, 17, 66, 3, 67, 0, 3, 67, 109, 0, 7, 6, 1, 32, 0, 4, 224, 174, 191, 1, 141, 175, 224, 184, 174, 224, 178, 174, 224, 138, 175, 224, 149, 174, 224, 2, 224, 174, 176, 224, 174, 190, 224, 174, 178, 3, 23, 140, 0, 224, 175, 141, 1, 141, 175, 224, 184, 174, 224, 2, 224, 174, 176, 0, 4, 224, 175, 141, 224, 174, 154, 224, 175, 129, 1, 178, 174, 224, 2, 224, 174, 174, 224, 174, 163, 3, 49, 93, 0, 224, 175, 141, 224, 174, 154, 224, 175, 129, 1, 178, 174, 224, 2, 224, 174, 174, 224, 174, 191, 0, 4, 1, 32, 141, 175, 224, 178, 174, 224, 129, 175, 224, 170, 174, 224, 2, 224, 174, 190, 224, 174, 184, 3, 140, 0, 1, 129, 175, 224, 179, 174, 224, 2, 224, 175, 139, 224, 174, 169, 224, 174, 191, 224, 174, 175, 0, 1, 141, 175, 224, 163, 174, 224, 135, 174, 224, 2, 224, 175, 134, 0, 1, 141, 175, 224, 178, 174, 224, 133, 174, 224, 2, 224, 174, 190, 0, 1, 141, 175, 224, 178, 174, 224, 137, 174, 224, 2, 224, 174, 190, 0, 1, 141, 175, 224, 183, 174, 224, 2, 17, 66, 0, 1, 141, 175, 224, 184, 174, 224, 2, 17, 66, 0, 8, 2, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 154, 224, 174, 190, 224, 174, 169, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 156, 224, 174, 190, 224, 174, 169, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 174, 190, 224, 174, 174, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 174, 174, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 175, 141, 224, 174, 184, 224, 175, 141, 224, 174, 159, 224, 174, 190, 224, 174, 175, 0, 8, 2, 224, 174, 190, 224, 174, 184, 224, 175, 141, 224, 174, 174, 224, 174, 190, 224, 174, 149, 224, 175, 141, 0, 8, 2, 224, 174, 191, 224, 174, 131, 224, 174, 170, 224, 174, 169, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 0, 8, 2, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 184, 0, 8, 2, 224, 174, 191, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 174, 176, 0, 8, 2, 224, 174, 191, 224, 174, 181, 224, 174, 191, 224, 174, 149, 0, 8, 2, 224, 174, 191, 224, 174, 181, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 174, 191, 224, 174, 181, 224, 174, 191, 224, 174, 178, 0, 8, 2, 224, 174, 191, 224, 174, 183, 224, 175, 141, 224, 174, 175, 0, 8, 2, 224, 175, 128, 0, 8, 2, 224, 175, 129, 224, 174, 169, 224, 174, 191, 224, 174, 154, 224, 174, 191, 224, 174, 175, 224, 174, 190, 0, 8, 2, 224, 175, 129, 224, 174, 169, 224, 174, 191, 224, 174, 184, 0, 8, 2, 224, 175, 129, 224, 174, 169, 224, 175, 128, 18, 69, 0, 8, 2, 224, 175, 129, 224, 174, 169, 224, 175, 128, 224, 174, 183, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 175, 130, 32, 224, 174, 181, 224, 175, 128, 224, 174, 178, 0, 8, 2, 224, 175, 130, 224, 174, 176, 0, 8, 2, 224, 175, 134, 224, 174, 149, 224, 175, 141, 224, 174, 184, 224, 174, 190, 224, 174, 184, 0, 8, 2, 224, 175, 134, 224, 174, 149, 224, 175, 141, 224, 174, 184, 224, 175, 141, 0, 8, 2, 224, 175, 134, 224, 174, 154, 224, 175, 139, 0, 8, 2, 224, 175, 134, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 176, 0, 8, 2, 224, 175, 134, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 175, 129, 224, 174, 178, 224, 175, 141, 224, 174, 149, 224, 174, 176, 0, 8, 2, 224, 175, 134, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 174, 191, 224, 174, 184, 0, 8, 2, 224, 175, 134, 224, 174, 169, 224, 175, 141, 224, 174, 183, 224, 174, 169, 0, 8, 2, 224, 175, 134, 224, 174, 175, 224, 175, 141, 224, 174, 178, 224, 174, 176, 0, 8, 2, 224, 175, 134, 224, 174, 176, 0, 8, 2, 224, 175, 134, 224, 174, 178, 224, 174, 191, 224, 174, 131, 224, 174, 170, 224, 175, 139, 224, 174, 169, 0, 8, 2, 224, 175, 134, 224, 174, 178, 224, 174, 191, 224, 174, 181, 224, 174, 191, 224, 174, 183, 224, 174, 169, 0, 8, 2, 224, 175, 134, 224, 174, 178, 224, 175, 141, 32, 224, 174, 133, 224, 174, 181, 224, 175, 128, 224, 174, 181, 0, 8, 2, 224, 175, 135, 224, 174, 170, 0, 8, 2, 224, 175, 135, 224, 174, 184, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 175, 136, 224, 174, 174, 224, 175, 141, 32, 0, 8, 2, 224, 175, 139, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 169, 0, 8, 2, 224, 175, 139, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 175, 224, 175, 139, 0, 8, 2, 224, 175, 139, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 178, 0, 8, 2, 224, 175, 139, 224, 174, 169, 0, 8, 2, 224, 175, 141, 224, 174, 176, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 154, 224, 174, 191, 224, 174, 184, 224, 175, 141, 224, 174, 159, 224, 174, 176, 0, 8, 32, 141, 175, 224, 169, 174, 224, 190, 174, 224, 178, 174, 224, 2, 224, 175, 134, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 174, 191, 224, 174, 184, 0, 8, 32, 141, 175, 224, 179, 174, 224, 191, 174, 224, 170, 174, 224, 135, 175, 224, 159, 174, 224, 2, 224, 175, 134, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 174, 191, 224, 174, 184, 0, 8, 130, 175, 224, 175, 174, 224, 141, 175, 224, 159, 174, 224, 2, 224, 174, 191, 0, 8, 130, 175, 224, 175, 174, 224, 191, 174, 224, 159, 174, 224, 2, 224, 174, 191, 0, 8, 140, 175, 224, 149, 174, 224, 2, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 175, 0, 8, 141, 175, 224, 163, 174, 224, 135, 175, 224, 149, 174, 224, 2, 224, 175, 128, 224, 174, 169, 0, 8, 141, 175, 224, 163, 174, 224, 135, 175, 224, 170, 174, 224, 2, 224, 174, 191, 0, 8, 141, 175, 224, 163, 174, 224, 190, 174, 224, 149, 174, 224, 2, 224, 175, 128, 224, 174, 169, 0, 8, 141, 175, 224, 170, 174, 224, 131, 174, 224, 135, 175, 224, 154, 174, 224, 2, 224, 174, 191, 0, 8, 141, 175, 224, 176, 174, 224, 139, 175, 224, 170, 174, 224, 2, 224, 174, 191, 224, 174, 149, 224, 175, 139, 0, 8, 141, 175, 224, 176, 174, 224, 190, 174, 224, 149, 174, 224, 2, 224, 175, 130, 224, 174, 169, 0, 8, 141, 175, 224, 176, 174, 224, 190, 174, 224, 174, 174, 224, 2, 224, 174, 191, 224, 174, 169, 0, 8, 141, 175, 224, 178, 174, 224, 175, 174, 224, 190, 174, 224, 176, 174, 224, 2, 224, 174, 191, 0, 8, 141, 175, 224, 178, 174, 224, 181, 174, 224, 190, 174, 224, 168, 174, 224, 2, 224, 174, 191, 0, 8, 141, 175, 224, 178, 174, 224, 190, 174, 224, 174, 174, 224, 2, 224, 174, 190, 0, 8, 149, 174, 224, 134, 175, 224, 168, 174, 224, 2, 224, 174, 191, 224, 174, 181, 0, 8, 191, 174, 224, 156, 174, 224, 134, 175, 224, 181, 174, 224, 2, 224, 175, 135, 0, 8, 191, 174, 224, 176, 174, 224, 141, 175, 224, 170, 174, 224, 2, 224, 175, 139, 224, 174, 176, 224, 174, 191, 224, 174, 175, 0, 8, 191, 174, 224, 178, 174, 224, 190, 174, 224, 181, 174, 224, 141, 175, 224, 149, 174, 224, 2, 224, 174, 191, 0, 224, 174, 191, 1, 141, 175, 224, 163, 174, 224, 135, 174, 224, 2, 224, 174, 176, 224, 175, 134, 224, 174, 184, 224, 175, 141, 224, 174, 159, 0, 224, 174, 191, 1, 141, 175, 224, 163, 174, 224, 149, 174, 224, 2, 224, 174, 176, 224, 175, 139, 224, 174, 178, 0, 224, 174, 191, 8, 2, 224, 174, 175, 224, 175, 130, 224, 174, 154, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 175, 224, 175, 130, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 175, 224, 175, 130, 224, 174, 170, 0, 224, 174, 191, 8, 2, 224, 174, 175, 224, 175, 130, 224, 174, 183, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 153, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 175, 129, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 170, 224, 174, 191, 224, 174, 179, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 156, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 154, 224, 174, 191, 224, 174, 184, 224, 175, 141, 224, 174, 159, 224, 174, 176, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 184, 224, 175, 141, 224, 174, 131, 224, 174, 170, 224, 174, 176, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 184, 224, 175, 141, 224, 174, 170, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 184, 224, 175, 141, 224, 174, 174, 224, 175, 128, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 176, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 184, 224, 175, 141, 224, 174, 178, 224, 175, 135, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 184, 224, 175, 141, 224, 174, 181, 224, 175, 135, 224, 174, 178, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 174, 224, 174, 191, 224, 174, 178, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 174, 224, 175, 136, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 174, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 178, 224, 174, 191, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 181, 224, 174, 178, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 181, 224, 175, 134, 224, 174, 178, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 174, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 191, 224, 174, 175, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 134, 224, 174, 163, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 134, 224, 174, 175, 224, 174, 191, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 134, 224, 174, 175, 224, 175, 141, 224, 174, 178, 224, 174, 176, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 135, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 136, 32, 224, 174, 154, 224, 175, 134, 224, 174, 158, 224, 175, 141, 224, 174, 154, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 136, 32, 224, 174, 154, 224, 175, 134, 224, 174, 175, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 136, 32, 224, 174, 170, 224, 174, 163, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 136, 224, 174, 175, 224, 174, 178, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 136, 224, 174, 178, 224, 174, 176, 0, 224, 174, 191, 8, 141, 175, 224, 163, 174, 224, 190, 174, 224, 149, 174, 224, 2, 224, 174, 176, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 159, 224, 174, 176, 0, 224, 175, 141, 1, 134, 174, 224, 2, 224, 174, 176, 224, 174, 190, 0, 224, 175, 141, 1, 134, 174, 224, 2, 224, 174, 177, 224, 174, 190, 0, 224, 175, 141, 1, 134, 175, 224, 168, 174, 224, 141, 175, 224, 176, 174, 224, 159, 174, 224, 141, 175, 224, 163, 174, 224, 135, 174, 224, 0, 224, 175, 141, 1, 135, 174, 224, 2, 224, 174, 178, 224, 174, 176, 0, 224, 175, 141, 1, 141, 175, 224, 163, 174, 224, 134, 175, 224, 174, 174, 224, 21, 0, 224, 175, 141, 1, 141, 175, 224, 163, 174, 224, 135, 174, 224, 2, 224, 174, 176, 224, 175, 135, 224, 174, 184, 224, 175, 141, 224, 174, 159, 0, 224, 175, 141, 1, 141, 175, 224, 163, 174, 224, 142, 174, 224, 2, 224, 174, 176, 224, 174, 191, 0, 224, 175, 141, 1, 141, 175, 224, 163, 174, 224, 149, 174, 224, 2, 224, 174, 176, 224, 175, 139, 224, 174, 178, 0, 224, 175, 141, 8, 2, 224, 174, 175, 224, 175, 130, 224, 174, 154, 224, 174, 169, 0, 224, 175, 141, 8, 2, 224, 174, 175, 224, 175, 130, 224, 174, 169, 0, 224, 175, 141, 8, 2, 224, 174, 175, 224, 175, 130, 224, 174, 170, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 153, 224, 175, 141, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 175, 129, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 170, 224, 174, 191, 224, 174, 179, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 184, 224, 175, 141, 224, 174, 159, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 156, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 184, 224, 175, 141, 224, 174, 131, 224, 174, 170, 224, 174, 176, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 184, 224, 175, 141, 224, 174, 170, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 184, 224, 175, 141, 224, 174, 170, 224, 174, 190, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 176, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 184, 224, 175, 141, 224, 174, 174, 224, 175, 128, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 176, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 184, 224, 175, 141, 224, 174, 178, 224, 175, 135, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 184, 224, 175, 141, 224, 174, 181, 224, 175, 135, 224, 174, 178, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 174, 224, 174, 191, 224, 174, 178, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 174, 224, 175, 136, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 174, 224, 175, 141, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 178, 224, 174, 191, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 181, 224, 174, 178, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 181, 224, 175, 134, 224, 174, 178, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 174, 224, 175, 141, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 191, 224, 174, 175, 224, 174, 169, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 175, 134, 224, 174, 163, 224, 175, 141, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 175, 134, 224, 174, 175, 224, 175, 141, 224, 174, 178, 224, 174, 176, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 175, 135, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 175, 136, 32, 224, 174, 154, 224, 175, 134, 224, 174, 158, 224, 175, 141, 224, 174, 154, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 175, 136, 32, 224, 174, 154, 224, 175, 134, 224, 174, 175, 224, 175, 141, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 175, 136, 32, 224, 174, 170, 224, 174, 163, 224, 175, 141, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 175, 136, 224, 174, 175, 224, 174, 178, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 175, 136, 224, 174, 178, 224, 174, 176, 0, 224, 175, 141, 8, 128, 175, 224, 168, 174, 224, 2, 224, 174, 176, 224, 174, 190, 0, 224, 175, 141, 8, 128, 175, 224, 168, 174, 224, 2, 224, 174, 177, 224, 174, 190, 0, 224, 175, 141, 8, 128, 175, 224, 181, 174, 224, 2, 224, 174, 178, 0, 224, 175, 141, 8, 128, 175, 224, 181, 174, 224, 129, 175, 224, 159, 174, 224, 168, 174, 224, 2, 224, 174, 178, 0, 224, 175, 141, 8, 130, 175, 224, 149, 174, 224, 2, 224, 174, 178, 0, 224, 175, 141, 8, 130, 175, 224, 175, 174, 224, 191, 174, 224, 168, 174, 224, 2, 224, 174, 176, 224, 174, 190, 224, 174, 169, 0, 224, 175, 141, 8, 130, 175, 224, 175, 174, 224, 191, 174, 224, 168, 174, 224, 2, 224, 174, 176, 224, 174, 191, 224, 174, 169, 0, 224, 175, 141, 8, 130, 175, 224, 176, 174, 224, 2, 224, 174, 178, 0, 224, 175, 141, 8, 134, 175, 224, 170, 174, 224, 2, 224, 174, 176, 224, 175, 139, 0, 224, 175, 141, 8, 134, 175, 224, 174, 174, 224, 2, 224, 174, 176, 224, 175, 139, 0, 224, 175, 141, 8, 134, 175, 224, 174, 174, 224, 141, 175, 224, 178, 174, 224, 134, 175, 224, 185, 174, 224, 0, 224, 175, 141, 8, 135, 175, 224, 149, 174, 224, 2, 224, 174, 176, 224, 175, 129, 0, 224, 175, 141, 8, 135, 175, 224, 174, 174, 224, 2, 224, 174, 178, 0, 224, 175, 141, 8, 135, 175, 224, 178, 174, 224, 0, 224, 175, 141, 8, 139, 175, 224, 168, 174, 224, 2, 224, 174, 178, 0, 224, 175, 141, 8, 139, 175, 224, 170, 174, 224, 2, 224, 174, 176, 224, 175, 129, 0, 224, 175, 141, 8, 139, 175, 224, 176, 174, 224, 2, 224, 174, 178, 0, 224, 175, 141, 8, 139, 175, 224, 176, 174, 224, 129, 175, 224, 159, 174, 224, 168, 174, 224, 2, 224, 174, 178, 0, 224, 175, 141, 8, 141, 175, 224, 163, 174, 224, 135, 175, 224, 170, 174, 224, 0, 224, 175, 141, 8, 141, 175, 224, 163, 174, 224, 190, 174, 224, 149, 174, 224, 2, 224, 174, 176, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 159, 224, 174, 176, 0, 224, 175, 141, 8, 164, 174, 224, 2, 224, 174, 176, 224, 174, 190, 0, 224, 175, 141, 8, 164, 174, 224, 2, 224, 174, 177, 224, 174, 190, 0, 224, 175, 141, 8, 164, 174, 224, 2, 224, 174, 178, 0, 224, 175, 141, 8, 190, 174, 224, 149, 174, 224, 2, 224, 174, 178, 0, 224, 175, 141, 8, 190, 174, 224, 149, 174, 224, 129, 175, 224, 159, 174, 224, 168, 174, 224, 2, 224, 174, 178, 0, 224, 175, 141, 8, 190, 174, 224, 168, 174, 224, 2, 224, 174, 178, 0, 224, 175, 141, 8, 190, 174, 224, 170, 174, 224, 2, 224, 174, 178, 0, 224, 175, 141, 8, 191, 174, 224, 181, 174, 224, 2, 224, 174, 176, 224, 175, 129, 0, 224, 175, 141, 8, 191, 174, 224, 185, 174, 224, 2, 224, 174, 178, 224, 174, 176, 0, 4, 224, 174, 191, 224, 174, 176, 224, 175, 134, 224, 174, 175, 224, 174, 191, 8, 2, 224, 174, 178, 224, 174, 176, 3, 140, 34, 36, 57, 0, 224, 175, 141, 224, 174, 176, 224, 175, 134, 224, 174, 175, 224, 174, 191, 8, 2, 224, 174, 178, 224, 174, 176, 0, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 170, 224, 175, 141, 8, 3, 140, 34, 37, 48, 0, 4, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 149, 224, 175, 141, 8, 3, 140, 34, 37, 49, 0, 224, 175, 141, 224, 174, 176, 224, 174, 191, 224, 174, 149, 224, 175, 141, 8, 0, 4, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 149, 8, 2, 224, 174, 176, 3, 140, 34, 37, 81, 81, 109, 0, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 8, 2, 224, 174, 176, 0, 224, 175, 141, 224, 174, 176, 224, 174, 191, 224, 174, 149, 8, 2, 224, 174, 176, 0, 224, 175, 141, 224, 174, 176, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 8, 2, 224, 174, 176, 0, 224, 174, 191, 224, 174, 176, 8, 2, 224, 174, 184, 224, 175, 141, 224, 174, 159, 3, 140, 34, 109, 0, 4, 224, 174, 191, 224, 174, 176, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 175, 134, 224, 174, 159, 224, 175, 141, 8, 3, 140, 34, 109, 65, 48, 36, 140, 0, 224, 175, 141, 224, 174, 176, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 175, 134, 224, 174, 159, 224, 175, 141, 8, 0, 4, 224, 174, 191, 224, 174, 176, 224, 175, 128, 224, 174, 159, 224, 175, 141, 8, 3, 140, 34, 112, 140, 0, 224, 175, 141, 224, 174, 176, 224, 175, 128, 224, 174, 159, 224, 175, 141, 8, 0, 224, 174, 191, 224, 174, 176, 224, 175, 135, 224, 174, 175, 224, 174, 191, 224, 174, 169, 8, 2, 224, 175, 136, 3, 140, 34, 114, 57, 50, 0, 224, 174, 191, 224, 174, 176, 224, 174, 190, 224, 174, 170, 224, 175, 141, 8, 3, 140, 34, 118, 48, 0, 4, 224, 174, 191, 224, 174, 176, 224, 174, 190, 224, 174, 149, 224, 175, 141, 8, 3, 140, 34, 118, 49, 0, 224, 175, 141, 224, 174, 176, 224, 174, 190, 224, 174, 149, 224, 175, 141, 1, 133, 174, 224, 0, 224, 175, 141, 224, 174, 176, 224, 174, 190, 224, 174, 149, 224, 175, 141, 8, 0, 224, 174, 191, 224, 174, 176, 224, 174, 190, 224, 174, 169, 224, 175, 141, 8, 2, 224, 174, 184, 224, 175, 141, 224, 174, 170, 224, 174, 176, 224, 174, 163, 224, 175, 141, 224, 174, 159, 12, 12, 12, 3, 140, 34, 118, 50, 0, 224, 175, 141, 224, 174, 176, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 184, 224, 175, 141, 224, 174, 170, 224, 174, 191, 224, 174, 176, 224, 174, 163, 224, 175, 141, 224, 174, 159, 8, 3, 140, 34, 118, 50, 89, 48, 37, 34, 109, 66, 140, 149, 0, 224, 175, 141, 224, 174, 176, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 184, 224, 175, 141, 224, 174, 170, 8, 2, 224, 174, 176, 224, 174, 163, 224, 175, 141, 224, 174, 159, 3, 140, 34, 118, 50, 89, 48, 109, 0, 4, 224, 174, 191, 224, 174, 176, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 184, 224, 175, 141, 224, 174, 170, 8, 2, 224, 174, 176, 3, 140, 34, 118, 50, 89, 83, 109, 0, 224, 175, 141, 224, 174, 176, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 184, 224, 175, 141, 224, 174, 170, 8, 2, 224, 174, 176, 0, 4, 224, 174, 191, 224, 174, 176, 224, 174, 190, 224, 174, 131, 224, 174, 170, 224, 174, 191, 224, 174, 149, 224, 175, 141, 8, 3, 140, 34, 118, 83, 37, 49, 0, 224, 174, 191, 224, 174, 176, 224, 174, 190, 224, 174, 170, 224, 174, 191, 224, 174, 149, 224, 175, 141, 8, 0, 224, 175, 141, 224, 174, 176, 224, 174, 190, 224, 174, 131, 224, 174, 170, 224, 174, 191, 224, 174, 149, 224, 175, 141, 8, 0, 224, 175, 141, 224, 174, 176, 224, 174, 190, 224, 174, 170, 224, 174, 191, 224, 174, 149, 224, 175, 141, 8, 0, 4, 224, 175, 134, 224, 174, 149, 8, 2, 224, 175, 141, 224, 174, 154, 224, 174, 190, 224, 174, 184, 3, 140, 36, 49, 0, 224, 175, 134, 224, 174, 149, 224, 175, 141, 8, 2, 224, 174, 169, 224, 174, 190, 224, 174, 178, 224, 174, 156, 224, 174, 191, 0, 224, 175, 134, 224, 174, 149, 224, 175, 141, 224, 174, 169, 224, 174, 191, 224, 174, 149, 8, 3, 140, 36, 49, 50, 37, 49, 149, 0, 224, 175, 134, 224, 174, 169, 224, 175, 141, 224, 174, 154, 8, 2, 224, 174, 169, 3, 140, 36, 50, 93, 109, 0, 224, 175, 134, 224, 174, 169, 224, 175, 141, 224, 174, 159, 224, 175, 129, 224, 174, 178, 224, 175, 141, 224, 174, 149, 8, 2, 224, 174, 176, 3, 140, 36, 50, 140, 122, 55, 49, 109, 0, 224, 175, 134, 224, 174, 178, 224, 174, 191, 224, 174, 170, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 163, 224, 175, 141, 224, 174, 159, 8, 2, 224, 174, 176, 3, 140, 36, 55, 37, 48, 34, 37, 50, 140, 109, 0, 224, 175, 134, 224, 174, 178, 224, 174, 191, 224, 174, 170, 224, 174, 164, 8, 2, 224, 174, 191, 3, 140, 36, 55, 37, 48, 109, 47, 0, 224, 175, 134, 224, 174, 178, 224, 174, 191, 224, 174, 149, 224, 175, 128, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 174, 3, 140, 36, 55, 37, 81, 0, 224, 175, 134, 224, 174, 178, 224, 174, 191, 224, 174, 170, 2, 224, 175, 139, 224, 174, 169, 3, 140, 36, 55, 37, 83, 0, 224, 175, 134, 224, 174, 178, 224, 174, 184, 224, 175, 141, 224, 174, 149, 224, 175, 139, 224, 174, 170, 224, 175, 141, 8, 3, 140, 36, 55, 109, 89, 49, 119, 48, 0, 224, 175, 134, 224, 174, 174, 224, 175, 141, 224, 174, 170, 8, 2, 224, 175, 139, 3, 140, 36, 65, 48, 0, 224, 175, 134, 224, 174, 174, 224, 175, 141, 224, 174, 170, 8, 2, 224, 174, 176, 3, 140, 36, 65, 48, 109, 0, 224, 175, 134, 224, 174, 184, 224, 175, 141, 224, 174, 159, 8, 3, 140, 36, 89, 140, 149, 0, 224, 174, 191, 224, 174, 149, 224, 175, 141, 1, 141, 175, 224, 176, 174, 224, 134, 174, 224, 3, 140, 37, 49, 0, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 134, 224, 174, 159, 224, 175, 141, 8, 3, 140, 37, 49, 49, 36, 140, 0, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 159, 224, 175, 141, 8, 3, 140, 37, 49, 49, 109, 140, 0, 224, 174, 191, 224, 174, 169, 224, 175, 134, 224, 174, 169, 224, 175, 141, 224, 174, 159, 1, 141, 175, 224, 169, 174, 224, 190, 174, 224, 149, 174, 224, 2, 224, 174, 178, 3, 140, 37, 50, 36, 50, 140, 109, 0, 224, 174, 191, 224, 174, 169, 224, 175, 134, 224, 174, 163, 224, 175, 141, 224, 174, 159, 1, 141, 175, 224, 163, 174, 224, 190, 174, 224, 149, 174, 224, 2, 224, 174, 178, 3, 140, 37, 50, 36, 66, 140, 109, 0, 224, 174, 191, 224, 174, 169, 224, 175, 141, 224, 174, 149, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 153, 224, 175, 141, 3, 140, 37, 50, 49, 109, 0, 224, 174, 191, 224, 174, 174, 224, 175, 134, 224, 174, 163, 224, 175, 141, 224, 174, 159, 8, 141, 175, 224, 163, 174, 224, 134, 175, 224, 154, 174, 224, 3, 140, 37, 65, 36, 66, 140, 149, 0, 224, 174, 191, 224, 174, 170, 224, 174, 191, 224, 174, 149, 224, 175, 135, 224, 174, 159, 8, 141, 175, 224, 176, 174, 224, 154, 174, 224, 3, 140, 37, 83, 37, 81, 114, 140, 149, 0, 224, 174, 191, 224, 174, 170, 8, 2, 224, 174, 169, 3, 140, 37, 83, 109, 0, 224, 174, 191, 224, 174, 159, 8, 2, 224, 175, 139, 3, 140, 37, 140, 0, 224, 175, 138, 224, 174, 149, 224, 175, 141, 8, 3, 140, 39, 49, 0, 224, 175, 129, 224, 174, 159, 8, 2, 224, 175, 139, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 174, 178, 3, 140, 40, 140, 0, 224, 175, 141, 224, 174, 178, 224, 174, 190, 224, 174, 163, 224, 175, 141, 224, 174, 159, 1, 133, 174, 224, 3, 140, 55, 118, 66, 140, 149, 0, 4, 224, 175, 129, 224, 174, 181, 8, 2, 224, 174, 191, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 176, 3, 140, 58, 0, 224, 175, 141, 224, 174, 181, 8, 2, 224, 174, 191, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 176, 0, 4, 224, 174, 191, 224, 174, 181, 224, 174, 191, 224, 174, 153, 224, 175, 141, 224, 174, 149, 8, 2, 224, 174, 191, 224, 174, 179, 3, 140, 58, 37, 68, 49, 0, 224, 175, 129, 224, 174, 181, 224, 174, 191, 224, 174, 153, 224, 175, 141, 224, 174, 149, 8, 2, 224, 174, 191, 224, 174, 179, 0, 224, 175, 141, 224, 174, 181, 224, 174, 191, 224, 174, 153, 224, 175, 141, 224, 174, 149, 8, 2, 224, 174, 191, 224, 174, 179, 0, 224, 175, 141, 224, 174, 174, 224, 175, 134, 224, 174, 163, 224, 175, 141, 224, 174, 159, 1, 141, 175, 224, 163, 174, 224, 191, 174, 224, 175, 174, 224, 190, 174, 224, 170, 174, 224, 141, 175, 224, 170, 174, 224, 133, 174, 224, 3, 140, 65, 36, 66, 140, 149, 0, 4, 1, 135, 175, 224, 159, 174, 224, 141, 175, 224, 184, 174, 224, 2, 224, 174, 184, 3, 140, 109, 0, 1, 141, 175, 224, 153, 174, 224, 2, 224, 174, 169, 0, 1, 141, 175, 224, 163, 174, 224, 129, 175, 224, 181, 174, 224, 149, 174, 224, 141, 175, 224, 169, 174, 224, 142, 174, 224, 2, 224, 174, 176, 0, 1, 141, 175, 224, 163, 174, 224, 135, 174, 224, 2, 224, 174, 176, 224, 175, 141, 0, 1, 141, 175, 224, 163, 174, 224, 140, 175, 224, 149, 174, 224, 141, 175, 224, 169, 174, 224, 142, 174, 224, 2, 224, 174, 176, 0, 1, 141, 175, 224, 178, 174, 224, 191, 174, 224, 170, 174, 224, 131, 174, 224, 2, 224, 174, 176, 0, 1, 141, 175, 224, 183, 174, 224, 0, 1, 141, 175, 224, 184, 174, 224, 0, 1, 191, 174, 224, 169, 174, 224, 190, 174, 224, 154, 174, 224, 2, 224, 174, 176, 224, 174, 191, 0, 8, 2, 224, 174, 131, 224, 174, 170, 224, 175, 141, 0, 8, 2, 224, 174, 149, 224, 175, 141, 32, 0, 8, 2, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 176, 0, 8, 2, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 0, 8, 2, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 134, 0, 8, 2, 224, 174, 149, 224, 175, 141, 224, 174, 169, 0, 8, 2, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 174, 191, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 174, 169, 224, 174, 178, 0, 8, 2, 224, 174, 169, 224, 175, 141, 0, 8, 2, 224, 174, 170, 224, 175, 141, 32, 0, 8, 2, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 134, 0, 8, 2, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 175, 141, 224, 174, 178, 224, 174, 176, 0, 8, 2, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 175, 141, 224, 174, 179, 224, 174, 176, 0, 8, 2, 224, 174, 174, 224, 175, 141, 224, 174, 179, 224, 174, 176, 0, 8, 2, 224, 174, 175, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 174, 175, 224, 174, 174, 0, 8, 2, 224, 174, 175, 224, 174, 176, 224, 174, 191, 224, 174, 178, 0, 8, 2, 224, 174, 175, 224, 174, 176, 224, 175, 129, 0, 8, 2, 224, 174, 175, 224, 174, 176, 224, 175, 136, 0, 8, 2, 224, 174, 175, 224, 174, 176, 224, 175, 139, 0, 8, 2, 224, 174, 175, 224, 174, 176, 224, 175, 141, 0, 8, 2, 224, 174, 181, 224, 174, 176, 0, 8, 2, 224, 174, 181, 224, 174, 178, 0, 8, 2, 224, 174, 181, 224, 175, 129, 224, 174, 169, 0, 8, 130, 175, 224, 149, 174, 224, 141, 175, 224, 184, 174, 224, 2, 224, 174, 176, 0, 8, 130, 175, 224, 175, 174, 224, 191, 174, 224, 168, 174, 224, 2, 224, 174, 169, 0, 8, 141, 175, 224, 163, 174, 224, 134, 175, 224, 154, 174, 224, 2, 224, 174, 176, 0, 8, 141, 175, 224, 163, 174, 224, 134, 175, 224, 174, 174, 224, 2, 224, 174, 178, 0, 8, 141, 175, 224, 163, 174, 224, 191, 174, 224, 176, 174, 224, 141, 175, 224, 170, 174, 224, 2, 224, 174, 176, 0, 8, 141, 175, 224, 178, 174, 224, 134, 175, 224, 183, 174, 224, 2, 224, 174, 176, 0, 8, 141, 175, 224, 178, 174, 224, 191, 174, 224, 174, 174, 224, 2, 224, 174, 169, 0, 8, 178, 174, 224, 191, 174, 224, 174, 174, 224, 2, 224, 174, 176, 224, 174, 191, 0, 8, 191, 174, 224, 178, 174, 224, 191, 174, 224, 174, 174, 224, 2, 224, 174, 176, 224, 174, 191, 0, 224, 174, 176, 224, 175, 141, 224, 174, 170, 224, 174, 191, 1, 141, 175, 224, 163, 174, 224, 142, 174, 224, 2, 224, 174, 176, 224, 175, 136, 18, 69, 3, 140, 109, 34, 48, 0, 224, 174, 176, 224, 175, 141, 224, 174, 170, 224, 174, 163, 224, 175, 141, 224, 174, 159, 8, 2, 224, 175, 136, 224, 174, 169, 3, 140, 109, 34, 48, 109, 66, 140, 0, 224, 174, 170, 224, 175, 141, 224, 174, 170, 8, 2, 224, 174, 191, 224, 174, 178, 3, 140, 109, 71, 71, 0, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 174, 170, 224, 175, 141, 8, 3, 140, 109, 76, 12, 109, 48, 0, 224, 175, 135, 224, 174, 149, 224, 175, 141, 8, 3, 140, 114, 49, 0, 224, 175, 135, 224, 174, 153, 224, 175, 141, 224, 174, 149, 8, 2, 224, 174, 176, 3, 140, 114, 68, 49, 109, 0, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 149, 1, 141, 175, 224, 163, 174, 224, 133, 174, 224, 3, 140, 118, 34, 140, 37, 49, 149, 0, 224, 174, 190, 224, 174, 170, 224, 175, 141, 8, 3, 140, 118, 48, 0, 224, 174, 190, 224, 174, 170, 224, 174, 191, 224, 174, 149, 224, 175, 141, 8, 3, 140, 118, 48, 37, 49, 0, 4, 224, 174, 190, 224, 174, 149, 8, 2, 224, 175, 141, 224, 174, 184, 224, 174, 191, 3, 140, 118, 49, 0, 224, 174, 190, 224, 174, 149, 224, 175, 141, 8, 2, 32, 0, 224, 174, 190, 224, 174, 169, 224, 174, 191, 224, 174, 149, 224, 175, 141, 8, 3, 140, 118, 50, 37, 49, 0, 224, 174, 190, 224, 174, 175, 224, 175, 141, 224, 174, 178, 224, 175, 134, 224, 174, 159, 224, 175, 141, 8, 3, 140, 118, 57, 55, 36, 140, 0, 224, 174, 190, 224, 174, 175, 224, 175, 141, 224, 174, 178, 224, 174, 159, 224, 175, 141, 8, 3, 140, 118, 57, 55, 109, 140, 0, 224, 174, 190, 224, 174, 153, 224, 175, 141, 224, 174, 149, 8, 2, 224, 174, 191, 3, 140, 118, 68, 49, 0, 224, 174, 190, 224, 174, 153, 224, 175, 141, 224, 174, 149, 8, 2, 224, 174, 176, 3, 140, 118, 68, 49, 109, 0, 224, 174, 190, 224, 174, 184, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 175, 141, 1, 141, 175, 224, 163, 174, 224, 134, 175, 224, 170, 174, 224, 3, 140, 118, 89, 140, 37, 49, 0, 224, 174, 190, 224, 174, 159, 8, 2, 224, 174, 190, 3, 140, 118, 140, 0, 224, 175, 139, 224, 174, 176, 224, 175, 141, 224, 174, 169, 224, 174, 174, 224, 175, 134, 224, 174, 163, 224, 175, 141, 224, 174, 159, 8, 3, 140, 119, 34, 50, 109, 65, 36, 66, 140, 149, 0, 224, 175, 139, 224, 174, 176, 224, 174, 163, 224, 175, 141, 224, 174, 159, 8, 2, 224, 175, 139, 3, 140, 119, 34, 109, 66, 140, 0, 4, 224, 175, 130, 8, 32, 141, 175, 224, 184, 174, 224, 179, 174, 224, 141, 175, 224, 170, 174, 224, 3, 140, 123, 0, 224, 175, 130, 8, 32, 141, 175, 224, 184, 174, 224, 179, 174, 224, 191, 174, 224, 170, 174, 224, 0, 224, 175, 130, 224, 174, 164, 224, 175, 141, 8, 3, 140, 123, 47, 0, 224, 175, 136, 224, 174, 170, 224, 175, 141, 8, 3, 140, 134, 48, 0, 224, 175, 136, 224, 174, 159, 8, 2, 224, 174, 191, 224, 174, 178, 3, 140, 134, 140, 0, 224, 175, 141, 224, 174, 159, 2, 17, 66, 3, 140, 140, 0, 224, 175, 141, 224, 174, 159, 3, 140, 140, 109, 0, 4, 1, 135, 175, 224, 175, 174, 224, 191, 174, 224, 159, 174, 224, 128, 175, 224, 174, 174, 224, 141, 175, 224, 176, 174, 224, 159, 174, 224, 141, 175, 224, 163, 174, 224, 135, 174, 224, 3, 140, 149, 0, 1, 141, 175, 224, 163, 174, 224, 134, 175, 224, 156, 174, 224, 141, 175, 224, 176, 174, 224, 133, 174, 224, 0, 1, 141, 175, 224, 163, 174, 224, 134, 175, 224, 174, 174, 224, 128, 175, 224, 176, 174, 224, 141, 175, 224, 149, 174, 224, 133, 174, 224, 0, 1, 141, 175, 224, 163, 174, 224, 156, 174, 224, 141, 175, 224, 176, 174, 224, 133, 174, 224, 0, 1, 141, 175, 224, 163, 174, 224, 176, 174, 224, 134, 175, 224, 170, 174, 224, 141, 175, 224, 184, 174, 224, 141, 175, 224, 169, 174, 224, 0, 1, 141, 175, 224, 163, 174, 224, 176, 174, 224, 170, 174, 224, 141, 175, 224, 184, 174, 224, 141, 175, 224, 169, 174, 224, 0, 1, 141, 175, 224, 178, 174, 224, 190, 174, 224, 18, 69, 133, 174, 224, 0, 8, 135, 175, 224, 159, 174, 224, 0, 8, 141, 175, 224, 163, 174, 224, 134, 175, 224, 174, 174, 224, 149, 174, 224, 0, 8, 141, 175, 224, 163, 174, 224, 135, 175, 224, 170, 174, 224, 0, 8, 141, 175, 224, 163, 174, 224, 175, 174, 224, 136, 175, 224, 179, 174, 224, 141, 175, 224, 149, 174, 224, 0, 8, 141, 175, 224, 163, 174, 224, 183, 174, 224, 135, 175, 224, 170, 174, 224, 0, 8, 141, 175, 224, 170, 174, 224, 131, 174, 224, 191, 174, 224, 183, 174, 224, 0, 8, 141, 175, 224, 176, 174, 224, 139, 175, 224, 170, 174, 224, 141, 175, 224, 170, 174, 224, 191, 174, 224, 176, 174, 224, 0, 8, 141, 175, 224, 178, 174, 224, 139, 175, 224, 181, 174, 224, 0, 8, 141, 175, 224, 178, 174, 224, 190, 174, 224, 181, 174, 224, 0, 4, 2, 17, 66, 3, 141, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 174, 176, 0, 8, 2, 224, 175, 128, 224, 174, 154, 224, 174, 178, 0, 8, 2, 224, 175, 128, 224, 174, 178, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 149, 224, 175, 129, 224, 174, 178, 224, 174, 190, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 174, 224, 174, 190, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 175, 224, 174, 191, 224, 174, 153, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 134, 224, 174, 184, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 136, 32, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 136, 224, 174, 181, 0, 224, 174, 191, 224, 174, 176, 8, 2, 224, 174, 184, 3, 141, 34, 36, 0, 224, 174, 191, 224, 174, 175, 224, 175, 130, 224, 174, 159, 8, 2, 224, 174, 191, 3, 141, 57, 152, 140, 0, 4, 3, 141, 109, 0, 8, 2, 224, 174, 181, 224, 175, 129, 224, 174, 169, 224, 175, 141, 224, 174, 178, 224, 175, 139, 224, 174, 159, 0, 224, 175, 128, 224, 174, 154, 224, 174, 163, 224, 175, 141, 224, 174, 159, 8, 3, 141, 112, 89, 109, 66, 140, 149, 0, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 174, 224, 175, 134, 224, 174, 163, 224, 175, 141, 224, 174, 159, 8, 3, 141, 118, 49, 49, 122, 65, 36, 66, 140, 149, 0, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 159, 8, 2, 224, 174, 176, 3, 141, 118, 49, 140, 109, 0, 4, 224, 175, 141, 224, 174, 159, 1, 135, 174, 224, 2, 224, 174, 191, 224, 174, 178, 224, 174, 191, 3, 141, 141, 0, 224, 175, 141, 224, 174, 159, 8, 134, 175, 224, 176, 174, 224, 2, 224, 174, 191, 224, 174, 175, 0, 224, 175, 141, 224, 174, 159, 8, 178, 174, 224, 3, 141, 141, 149, 0, 7, 6, 1, 36, 0, 2, 17, 66, 3, 66, 0, 3, 66, 109, 0, 7, 6, 1, 37, 0, 4, 1, 141, 175, 224, 149, 174, 224, 2, 17, 66, 3, 47, 0, 1, 141, 175, 224, 163, 174, 224, 128, 175, 224, 181, 174, 224, 2, 224, 175, 135, 224, 174, 181, 224, 175, 136, 0, 1, 141, 175, 224, 163, 174, 224, 128, 175, 224, 181, 174, 224, 2, 224, 175, 138, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 175, 136, 0, 1, 141, 175, 224, 168, 174, 224, 154, 174, 224, 190, 174, 224, 181, 174, 224, 2, 224, 174, 191, 0, 1, 141, 175, 224, 168, 174, 224, 175, 174, 224, 134, 175, 224, 156, 174, 224, 2, 224, 174, 191, 0, 1, 141, 175, 224, 170, 174, 224, 2, 17, 66, 0, 1, 141, 175, 224, 180, 174, 224, 134, 174, 224, 2, 224, 175, 129, 224, 174, 179, 224, 175, 136, 0, 1, 141, 175, 224, 184, 174, 224, 2, 17, 66, 0, 1, 142, 174, 224, 2, 224, 174, 191, 224, 174, 175, 224, 175, 139, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 191, 224, 174, 175, 0, 1, 154, 174, 224, 2, 224, 175, 141, 224, 174, 175, 0, 1, 154, 174, 224, 2, 224, 175, 141, 224, 174, 176, 224, 175, 129, 0, 1, 159, 174, 224, 141, 175, 224, 159, 174, 224, 154, 174, 224, 2, 224, 174, 191, 224, 174, 159, 224, 175, 141, 224, 174, 159, 0, 1, 164, 174, 224, 2, 224, 175, 141, 224, 174, 176, 224, 175, 130, 224, 174, 170, 0, 1, 178, 174, 224, 174, 174, 224, 135, 175, 224, 176, 174, 224, 191, 174, 224, 170, 174, 224, 2, 224, 174, 190, 0, 1, 181, 174, 224, 190, 174, 224, 170, 174, 224, 176, 174, 224, 191, 174, 224, 170, 174, 224, 2, 224, 174, 191, 0, 1, 190, 174, 224, 156, 174, 224, 129, 175, 224, 154, 174, 224, 2, 224, 174, 190, 0, 1, 190, 174, 224, 170, 174, 224, 2, 224, 175, 141, 224, 174, 176, 224, 175, 130, 224, 174, 174, 0, 1, 191, 174, 224, 154, 174, 224, 2, 224, 175, 141, 224, 174, 176, 224, 174, 190, 0, 1, 191, 174, 224, 164, 174, 224, 133, 174, 224, 2, 224, 174, 191, 0, 1, 191, 174, 224, 168, 174, 224, 2, 224, 175, 141, 224, 174, 175, 0, 1, 191, 174, 224, 169, 174, 224, 133, 174, 224, 2, 224, 174, 190, 0, 1, 191, 174, 224, 178, 174, 224, 178, 174, 224, 2, 224, 174, 190, 0, 1, 191, 174, 224, 181, 174, 224, 170, 174, 224, 2, 224, 175, 141, 224, 174, 176, 224, 174, 190, 0, 2, 224, 175, 129, 224, 174, 177, 224, 175, 136, 0, 2, 224, 175, 130, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 8, 2, 17, 66, 0, 8, 2, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 190, 224, 174, 164, 0, 8, 2, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 190, 224, 174, 174, 0, 8, 2, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 190, 224, 174, 181, 224, 174, 191, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 190, 0, 8, 2, 224, 174, 190, 224, 174, 154, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 164, 224, 174, 190, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 169, 224, 174, 191, 224, 174, 175, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 191, 0, 8, 2, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 32, 224, 174, 174, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 32, 224, 174, 181, 224, 174, 190, 224, 174, 175, 0, 8, 2, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 174, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 190, 0, 8, 2, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 175, 129, 32, 224, 174, 174, 224, 175, 129, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 175, 129, 0, 8, 2, 224, 175, 128, 224, 174, 169, 224, 174, 191, 0, 8, 2, 224, 175, 128, 224, 174, 169, 224, 175, 141, 0, 8, 2, 224, 175, 128, 224, 174, 170, 224, 175, 141, 224, 174, 170, 0, 8, 2, 224, 175, 128, 224, 174, 176, 224, 175, 141, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 159, 224, 174, 190, 0, 8, 2, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 190, 0, 8, 2, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 139, 0, 8, 2, 224, 175, 130, 224, 174, 176, 224, 174, 164, 224, 175, 141, 32, 0, 8, 2, 224, 175, 130, 224, 174, 176, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 129, 224, 174, 181, 0, 8, 2, 224, 175, 130, 224, 174, 176, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 138, 224, 174, 159, 0, 8, 2, 224, 175, 130, 224, 174, 176, 224, 174, 169, 0, 8, 2, 224, 175, 130, 224, 174, 176, 224, 174, 178, 0, 8, 2, 224, 175, 130, 224, 174, 176, 224, 174, 191, 224, 174, 149, 224, 175, 136, 0, 8, 2, 224, 175, 130, 224, 174, 176, 224, 175, 141, 32, 0, 8, 2, 224, 175, 130, 224, 174, 176, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 175, 130, 224, 174, 176, 224, 175, 141, 224, 174, 168, 224, 175, 141, 0, 8, 2, 224, 175, 130, 224, 174, 176, 224, 175, 141, 224, 174, 181, 0, 8, 2, 224, 175, 135, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 175, 135, 224, 174, 154, 224, 175, 141, 224, 174, 154, 0, 8, 2, 224, 175, 135, 224, 174, 181, 224, 174, 159, 224, 174, 191, 224, 174, 175, 224, 174, 190, 0, 8, 2, 224, 175, 135, 224, 174, 181, 224, 174, 176, 224, 174, 191, 224, 174, 159, 0, 8, 2, 224, 175, 135, 224, 174, 181, 224, 174, 176, 224, 175, 129, 0, 8, 2, 224, 175, 135, 224, 174, 181, 224, 174, 176, 224, 175, 136, 0, 8, 2, 224, 175, 135, 224, 174, 181, 224, 174, 176, 224, 175, 141, 32, 0, 8, 2, 224, 175, 135, 224, 174, 181, 224, 174, 178, 32, 0, 8, 2, 224, 175, 135, 224, 174, 181, 224, 174, 178, 224, 174, 190, 224, 174, 174, 0, 8, 2, 224, 175, 135, 224, 174, 181, 224, 174, 178, 224, 175, 135, 0, 8, 2, 224, 175, 135, 224, 174, 181, 224, 174, 178, 224, 175, 136, 0, 8, 2, 224, 175, 135, 224, 174, 181, 224, 174, 191, 224, 174, 159, 224, 174, 191, 224, 174, 175, 224, 174, 190, 0, 8, 2, 224, 175, 135, 224, 174, 181, 224, 174, 191, 224, 174, 159, 224, 174, 191, 224, 174, 175, 224, 174, 190, 0, 8, 2, 224, 175, 135, 224, 174, 181, 224, 175, 136, 0, 8, 128, 175, 224, 149, 174, 224, 2, 224, 174, 190, 0, 8, 128, 175, 224, 154, 174, 224, 2, 224, 174, 190, 0, 8, 128, 175, 224, 170, 174, 224, 154, 174, 224, 2, 224, 174, 190, 0, 8, 135, 175, 224, 168, 174, 224, 2, 224, 174, 190, 224, 174, 156, 224, 174, 191, 0, 8, 141, 175, 224, 168, 174, 224, 149, 174, 224, 129, 175, 224, 154, 174, 224, 2, 224, 174, 191, 0, 8, 141, 175, 224, 168, 174, 224, 154, 174, 224, 181, 174, 224, 2, 224, 174, 191, 0, 8, 141, 175, 224, 168, 174, 224, 156, 174, 224, 174, 174, 224, 2, 224, 174, 190, 0, 8, 141, 175, 224, 168, 174, 224, 175, 174, 224, 141, 175, 224, 183, 174, 224, 129, 175, 224, 164, 174, 224, 2, 224, 174, 191, 0, 8, 141, 175, 224, 168, 174, 224, 190, 174, 224, 154, 174, 224, 2, 224, 174, 191, 0, 8, 141, 175, 224, 169, 174, 224, 190, 174, 224, 164, 174, 224, 2, 224, 175, 139, 224, 174, 169, 224, 175, 141, 224, 174, 177, 0, 8, 141, 175, 224, 174, 174, 224, 129, 175, 224, 174, 174, 224, 2, 224, 174, 190, 224, 174, 156, 0, 8, 141, 175, 224, 174, 174, 224, 174, 174, 224, 2, 224, 174, 190, 0, 8, 141, 175, 224, 178, 174, 224, 129, 175, 224, 154, 174, 224, 2, 224, 174, 190, 224, 174, 169, 0, 8, 141, 175, 224, 178, 174, 224, 129, 175, 224, 174, 174, 224, 2, 224, 174, 190, 224, 174, 169, 0, 8, 149, 174, 224, 2, 18, 73, 224, 174, 156, 224, 174, 190, 0, 8, 154, 174, 224, 2, 224, 175, 128, 224, 174, 183, 0, 8, 174, 174, 224, 129, 175, 224, 154, 174, 224, 2, 224, 174, 191, 0, 8, 174, 174, 224, 139, 175, 224, 149, 174, 224, 2, 224, 174, 191, 0, 8, 176, 174, 224, 190, 174, 224, 170, 174, 224, 32, 141, 175, 224, 176, 174, 224, 190, 174, 224, 154, 174, 224, 176, 174, 224, 191, 174, 224, 170, 174, 224, 2, 224, 174, 191, 0, 8, 176, 174, 224, 191, 174, 224, 170, 174, 224, 2, 224, 175, 128, 0, 8, 178, 174, 224, 2, 224, 174, 190, 0, 8, 178, 174, 224, 170, 174, 224, 141, 175, 224, 183, 174, 224, 129, 175, 224, 170, 174, 224, 2, 224, 174, 190, 0, 8, 181, 174, 224, 135, 175, 224, 176, 174, 224, 2, 224, 174, 191, 0, 8, 181, 174, 224, 141, 175, 224, 176, 174, 224, 190, 174, 224, 170, 174, 224, 2, 224, 174, 191, 0, 8, 191, 174, 224, 154, 174, 224, 2, 224, 174, 190, 224, 174, 176, 0, 8, 191, 174, 224, 164, 174, 224, 135, 175, 224, 181, 174, 224, 191, 174, 224, 168, 174, 224, 2, 224, 174, 190, 0, 8, 191, 174, 224, 164, 174, 224, 135, 175, 224, 181, 174, 224, 191, 174, 224, 168, 174, 224, 2, 224, 175, 136, 0, 8, 191, 174, 224, 168, 174, 224, 2, 224, 175, 128, 224, 174, 183, 0, 8, 191, 174, 224, 168, 174, 224, 2, 224, 175, 135, 224, 174, 183, 0, 8, 191, 174, 224, 169, 174, 224, 129, 175, 224, 154, 174, 224, 2, 224, 174, 190, 0, 8, 191, 174, 224, 169, 174, 224, 181, 174, 224, 2, 224, 174, 190, 0, 8, 191, 174, 224, 169, 174, 224, 191, 174, 224, 181, 174, 224, 2, 224, 174, 190, 0, 8, 191, 174, 224, 170, 174, 224, 154, 174, 224, 2, 224, 174, 190, 0, 8, 191, 174, 224, 176, 174, 224, 185, 174, 224, 2, 224, 174, 190, 0, 224, 174, 191, 8, 2, 224, 174, 175, 224, 174, 190, 224, 174, 149, 0, 224, 174, 191, 8, 2, 224, 174, 175, 224, 175, 135, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 176, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 163, 224, 174, 191, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 178, 224, 175, 139, 224, 174, 149, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 178, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 181, 224, 175, 135, 224, 174, 164, 224, 174, 191, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 140, 224, 174, 170, 224, 174, 164, 224, 174, 191, 0, 224, 175, 129, 8, 2, 224, 174, 176, 224, 175, 139, 224, 174, 163, 0, 224, 175, 141, 1, 135, 174, 224, 2, 224, 174, 175, 224, 174, 190, 224, 174, 164, 224, 174, 191, 0, 224, 175, 141, 1, 191, 174, 224, 164, 174, 224, 134, 174, 224, 2, 224, 174, 175, 0, 224, 175, 141, 2, 32, 224, 174, 164, 0, 224, 175, 141, 8, 130, 175, 224, 154, 174, 224, 174, 174, 224, 190, 174, 224, 149, 174, 224, 2, 224, 174, 176, 0, 224, 175, 141, 8, 130, 175, 224, 174, 174, 224, 2, 224, 174, 176, 0, 224, 175, 141, 8, 134, 175, 224, 156, 174, 224, 2, 224, 174, 174, 224, 174, 178, 224, 174, 190, 224, 174, 169, 224, 174, 191, 0, 224, 175, 141, 8, 136, 175, 224, 174, 174, 224, 2, 224, 174, 176, 224, 175, 135, 224, 174, 175, 0, 224, 175, 141, 8, 170, 174, 224, 2, 224, 174, 176, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 179, 0, 224, 175, 141, 8, 170, 174, 224, 2, 224, 174, 176, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 224, 175, 141, 8, 170, 174, 224, 2, 224, 174, 176, 224, 174, 174, 0, 224, 175, 141, 8, 175, 174, 224, 191, 174, 224, 181, 174, 224, 139, 175, 224, 154, 174, 224, 0, 224, 175, 141, 8, 190, 174, 224, 170, 174, 224, 2, 224, 174, 176, 0, 224, 175, 141, 8, 190, 174, 224, 174, 174, 224, 2, 224, 174, 176, 0, 224, 175, 141, 8, 190, 174, 224, 181, 174, 224, 2, 224, 174, 154, 224, 174, 178, 224, 175, 141, 224, 174, 175, 0, 224, 175, 141, 8, 191, 174, 224, 174, 174, 224, 2, 224, 174, 176, 0, 4, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 170, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 3, 47, 34, 37, 48, 0, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 170, 8, 2, 224, 175, 139, 224, 174, 178, 224, 174, 191, 0, 224, 175, 141, 224, 174, 176, 224, 174, 170, 224, 174, 164, 224, 174, 191, 1, 154, 174, 224, 3, 47, 34, 109, 48, 109, 47, 37, 0, 224, 175, 141, 224, 174, 176, 224, 174, 178, 224, 175, 135, 224, 174, 149, 8, 191, 174, 224, 154, 174, 224, 2, 224, 174, 190, 3, 47, 34, 109, 55, 114, 49, 0, 4, 224, 174, 191, 224, 174, 149, 8, 139, 175, 224, 156, 174, 224, 2, 224, 174, 190, 3, 47, 37, 49, 0, 224, 174, 191, 224, 174, 149, 224, 175, 141, 8, 141, 175, 224, 176, 174, 224, 190, 174, 224, 149, 174, 224, 0, 224, 174, 191, 224, 174, 175, 224, 175, 139, 224, 174, 170, 1, 142, 174, 224, 2, 224, 174, 191, 224, 174, 175, 3, 47, 37, 57, 119, 48, 0, 4, 224, 175, 141, 224, 174, 164, 1, 18, 68, 2, 224, 174, 191, 224, 174, 169, 224, 174, 191, 12, 3, 47, 47, 0, 224, 175, 141, 224, 174, 164, 1, 129, 175, 224, 170, 174, 224, 2, 224, 174, 191, 224, 174, 176, 0, 224, 175, 141, 224, 174, 164, 2, 17, 66, 0, 224, 175, 141, 224, 174, 164, 8, 190, 174, 224, 154, 174, 224, 2, 224, 174, 191, 224, 174, 175, 224, 174, 191, 224, 174, 176, 224, 175, 129, 0, 224, 175, 141, 8, 191, 174, 224, 154, 174, 224, 2, 224, 174, 176, 224, 174, 190, 3, 47, 47, 37, 0, 224, 175, 141, 224, 174, 164, 3, 47, 47, 109, 0, 224, 175, 141, 224, 174, 149, 1, 135, 175, 224, 170, 174, 224, 141, 175, 224, 174, 174, 224, 133, 174, 224, 3, 47, 49, 149, 0, 224, 175, 141, 224, 174, 164, 224, 175, 129, 8, 154, 174, 224, 135, 175, 224, 164, 174, 224, 2, 224, 174, 176, 224, 175, 139, 224, 174, 149, 224, 174, 191, 3, 47, 72, 0, 4, 1, 136, 175, 224, 179, 174, 224, 141, 175, 224, 179, 174, 224, 191, 174, 224, 170, 174, 224, 2, 224, 174, 169, 3, 47, 109, 0, 1, 141, 175, 224, 149, 174, 224, 0, 1, 141, 175, 224, 170, 174, 224, 0, 1, 141, 175, 224, 179, 174, 224, 190, 174, 224, 159, 174, 224, 141, 175, 224, 159, 174, 224, 129, 175, 224, 174, 174, 224, 2, 224, 174, 169, 0, 1, 141, 175, 224, 184, 174, 224, 0, 8, 0, 8, 2, 224, 174, 176, 224, 175, 129, 224, 174, 174, 224, 174, 191, 224, 174, 159, 0, 8, 129, 175, 224, 159, 174, 224, 168, 174, 224, 2, 224, 174, 159, 224, 175, 141, 224, 174, 159, 0, 8, 140, 175, 224, 149, 174, 224, 2, 224, 174, 174, 0, 8, 140, 175, 224, 149, 174, 224, 2, 224, 174, 174, 224, 174, 191, 0, 8, 141, 175, 224, 163, 174, 224, 174, 174, 224, 2, 224, 174, 176, 224, 175, 136, 0, 8, 141, 175, 224, 168, 174, 224, 190, 174, 224, 154, 174, 224, 2, 32, 0, 8, 141, 175, 224, 178, 174, 224, 129, 175, 224, 170, 174, 224, 2, 224, 174, 176, 224, 175, 136, 0, 8, 141, 175, 224, 178, 174, 224, 135, 175, 224, 174, 174, 224, 2, 224, 174, 159, 224, 175, 141, 224, 174, 159, 0, 8, 141, 175, 224, 178, 174, 224, 170, 174, 224, 2, 224, 174, 159, 0, 8, 141, 175, 224, 180, 174, 224, 128, 175, 224, 149, 174, 224, 2, 224, 174, 159, 224, 175, 141, 224, 174, 159, 0, 8, 170, 174, 224, 2, 224, 174, 158, 224, 175, 141, 224, 174, 154, 224, 174, 178, 224, 174, 191, 0, 4, 1, 141, 175, 224, 168, 174, 224, 169, 174, 224, 133, 174, 224, 3, 47, 149, 0, 8, 141, 175, 224, 168, 174, 224, 154, 174, 224, 181, 174, 224, 0, 8, 141, 175, 224, 168, 174, 224, 190, 174, 224, 154, 174, 224, 2, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 141, 175, 224, 168, 174, 224, 190, 174, 224, 154, 174, 224, 2, 224, 174, 174, 0, 8, 141, 175, 224, 168, 174, 224, 190, 174, 224, 154, 174, 224, 2, 224, 174, 178, 224, 174, 191, 224, 174, 153, 224, 175, 141, 224, 174, 149, 0, 8, 141, 175, 224, 168, 174, 224, 190, 174, 224, 154, 174, 224, 2, 224, 174, 190, 224, 174, 169, 224, 175, 129, 0, 4, 2, 17, 66, 3, 72, 0, 8, 2, 17, 66, 28, 17, 12, 0, 8, 2, 18, 73, 224, 174, 169, 224, 174, 190, 0, 8, 2, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 190, 0, 8, 2, 224, 174, 190, 224, 174, 154, 0, 8, 2, 224, 174, 190, 224, 174, 159, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 174, 163, 224, 175, 141, 224, 174, 175, 0, 8, 2, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 174, 190, 224, 174, 175, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 190, 0, 8, 2, 224, 174, 190, 224, 174, 169, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 174, 190, 224, 174, 169, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 174, 190, 224, 174, 169, 224, 174, 170, 224, 175, 141, 0, 8, 2, 224, 174, 190, 224, 174, 169, 224, 174, 174, 0, 8, 2, 224, 174, 190, 224, 174, 169, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 174, 190, 224, 174, 169, 224, 175, 129, 224, 174, 181, 0, 8, 2, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 175, 0, 8, 2, 224, 174, 190, 224, 174, 174, 224, 175, 139, 224, 174, 164, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 174, 224, 175, 141, 32, 224, 174, 164, 224, 175, 130, 224, 174, 174, 0, 8, 2, 224, 174, 190, 224, 174, 175, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 179, 0, 8, 2, 224, 174, 190, 224, 174, 175, 224, 174, 174, 224, 174, 190, 0, 8, 2, 224, 174, 190, 224, 174, 175, 224, 174, 174, 224, 175, 129, 0, 8, 2, 224, 174, 190, 224, 174, 175, 224, 174, 190, 224, 174, 164, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 174, 163, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 174, 190, 32, 224, 174, 154, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 139, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 174, 190, 32, 224, 174, 154, 224, 174, 191, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 174, 190, 32, 224, 174, 183, 224, 174, 191, 224, 174, 149, 224, 175, 139, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 174, 190, 224, 174, 154, 224, 175, 129, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 174, 190, 224, 174, 170, 224, 175, 129, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 174, 190, 224, 174, 179, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 174, 190, 224, 174, 181, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 181, 224, 174, 163, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 181, 224, 174, 190, 0, 8, 2, 224, 174, 190, 224, 174, 181, 224, 175, 135, 224, 174, 175, 0, 8, 2, 224, 174, 190, 224, 174, 184, 0, 8, 2, 224, 174, 191, 224, 174, 149, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 174, 176, 0, 8, 2, 224, 174, 191, 224, 174, 149, 224, 174, 191, 224, 174, 178, 0, 8, 2, 224, 174, 191, 224, 174, 149, 224, 175, 129, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 129, 0, 8, 2, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 178, 0, 8, 2, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 0, 8, 2, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 134, 224, 174, 169, 0, 8, 2, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 135, 0, 8, 2, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 136, 0, 8, 2, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 181, 224, 174, 191, 224, 174, 156, 224, 174, 175, 0, 8, 2, 224, 174, 191, 224, 174, 154, 224, 175, 136, 0, 8, 2, 224, 174, 191, 224, 174, 159, 224, 174, 149, 224, 174, 190, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 0, 8, 2, 224, 174, 191, 224, 174, 159, 224, 174, 154, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 174, 191, 224, 174, 159, 224, 174, 170, 0, 8, 2, 224, 174, 191, 224, 174, 159, 224, 174, 174, 0, 8, 2, 224, 174, 191, 224, 174, 159, 224, 175, 128, 0, 8, 2, 224, 174, 191, 224, 174, 159, 224, 175, 128, 224, 174, 176, 0, 8, 2, 224, 174, 191, 224, 174, 159, 224, 175, 129, 224, 174, 149, 224, 175, 141, 0, 8, 2, 224, 174, 191, 224, 174, 159, 224, 175, 129, 224, 174, 164, 224, 174, 191, 224, 174, 159, 224, 175, 129, 0, 8, 2, 224, 174, 191, 224, 174, 159, 224, 175, 129, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 0, 8, 2, 224, 174, 191, 224, 174, 159, 224, 175, 129, 224, 174, 174, 0, 8, 2, 224, 174, 191, 224, 174, 159, 224, 175, 129, 224, 174, 181, 224, 175, 134, 0, 8, 2, 224, 174, 191, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 181, 224, 174, 169, 0, 8, 2, 224, 174, 191, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 178, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 174, 149, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 174, 154, 224, 174, 176, 224, 174, 191, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 174, 168, 224, 175, 141, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 159, 224, 174, 191, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 174, 174, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 175, 129, 224, 174, 154, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 175, 135, 224, 174, 183, 0, 8, 2, 224, 174, 191, 224, 174, 170, 224, 175, 129, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 129, 0, 8, 2, 224, 174, 191, 224, 174, 174, 224, 175, 141, 224, 174, 174, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 174, 181, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 174, 181, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 174, 190, 224, 174, 174, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 175, 140, 224, 174, 170, 224, 174, 164, 224, 174, 191, 0, 8, 2, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 190, 224, 174, 149, 0, 8, 2, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 191, 0, 8, 2, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 175, 129, 32, 0, 8, 2, 224, 174, 191, 224, 174, 181, 224, 174, 154, 0, 8, 2, 224, 174, 191, 224, 174, 181, 224, 174, 190, 224, 174, 149, 224, 174, 176, 0, 8, 2, 224, 174, 191, 224, 174, 181, 224, 174, 190, 224, 174, 169, 0, 8, 2, 224, 174, 191, 224, 174, 181, 224, 174, 190, 224, 174, 178, 0, 8, 2, 224, 174, 191, 224, 174, 181, 224, 175, 141, 224, 174, 175, 0, 8, 2, 224, 174, 191, 224, 174, 181, 224, 175, 141, 224, 174, 181, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 175, 128, 224, 174, 149, 224, 175, 141, 224, 174, 183, 224, 174, 191, 224, 174, 164, 224, 174, 176, 0, 8, 2, 224, 175, 128, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 174, 163, 224, 175, 141, 224, 174, 175, 0, 8, 2, 224, 175, 128, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 174, 191, 224, 174, 164, 0, 8, 2, 224, 175, 128, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 175, 136, 0, 8, 2, 224, 175, 128, 224, 174, 169, 0, 8, 2, 224, 175, 128, 224, 174, 170, 0, 8, 2, 224, 175, 128, 224, 174, 176, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 180, 224, 174, 181, 0, 8, 2, 224, 175, 128, 224, 174, 176, 224, 174, 154, 224, 175, 141, 0, 8, 2, 224, 175, 128, 224, 174, 176, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 129, 224, 174, 159, 0, 8, 2, 224, 175, 128, 224, 174, 176, 224, 174, 169, 0, 8, 2, 224, 175, 128, 224, 174, 176, 224, 174, 174, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 178, 0, 8, 2, 224, 175, 128, 224, 174, 176, 224, 174, 174, 224, 175, 129, 224, 174, 159, 0, 8, 2, 224, 175, 128, 224, 174, 176, 224, 174, 174, 224, 175, 141, 224, 174, 174, 224, 174, 191, 224, 174, 149, 0, 8, 2, 224, 175, 128, 224, 174, 176, 224, 174, 176, 0, 8, 2, 224, 175, 128, 224, 174, 176, 224, 174, 176, 224, 175, 136, 0, 8, 2, 224, 175, 128, 224, 174, 176, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 175, 128, 224, 174, 176, 224, 175, 141, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 174, 224, 174, 190, 0, 8, 2, 224, 175, 128, 224, 174, 181, 224, 174, 190, 224, 174, 179, 224, 174, 191, 0, 8, 2, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 175, 129, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 174, 174, 0, 8, 2, 224, 175, 129, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 174, 190, 224, 174, 164, 224, 174, 169, 224, 174, 169, 0, 8, 2, 224, 175, 129, 224, 174, 156, 224, 174, 184, 224, 175, 141, 0, 8, 2, 224, 175, 129, 224, 174, 159, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 175, 129, 224, 174, 169, 224, 175, 141, 224, 174, 174, 224, 174, 164, 224, 174, 191, 0, 8, 2, 224, 175, 129, 224, 174, 170, 224, 174, 190, 224, 174, 175, 0, 8, 2, 224, 175, 129, 224, 174, 170, 224, 174, 190, 224, 174, 183, 224, 174, 191, 0, 8, 2, 224, 175, 129, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 190, 0, 8, 2, 224, 175, 129, 224, 174, 174, 224, 174, 179, 224, 174, 191, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 174, 164, 224, 174, 191, 224, 174, 176, 224, 175, 129, 224, 174, 183, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 174, 164, 224, 174, 191, 224, 174, 176, 224, 175, 141, 224, 174, 183, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 174, 164, 224, 174, 191, 224, 174, 183, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 174, 190, 224, 174, 154, 224, 175, 136, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 175, 139, 224, 174, 164, 224, 174, 169, 224, 174, 169, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 175, 139, 224, 174, 164, 224, 174, 169, 224, 174, 190, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 181, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 181, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 181, 224, 174, 169, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 181, 224, 174, 170, 224, 175, 141, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 136, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 141, 0, 8, 2, 224, 175, 129, 224, 174, 183, 224, 175, 141, 0, 8, 2, 224, 175, 130, 224, 174, 154, 0, 8, 2, 224, 175, 130, 224, 174, 154, 224, 174, 191, 0, 8, 2, 224, 175, 130, 224, 174, 170, 0, 8, 2, 224, 175, 130, 224, 174, 174, 0, 8, 2, 224, 175, 130, 224, 174, 176, 0, 8, 2, 224, 175, 130, 224, 174, 176, 224, 175, 141, 224, 174, 164, 224, 174, 176, 224, 175, 141, 224, 174, 183, 224, 174, 169, 0, 8, 2, 224, 175, 130, 224, 174, 179, 224, 175, 141, 32, 224, 174, 149, 224, 174, 191, 224, 174, 179, 0, 8, 2, 224, 175, 130, 224, 174, 179, 224, 175, 141, 32, 224, 174, 170, 224, 174, 177, 0, 8, 2, 224, 175, 130, 224, 174, 183, 0, 8, 2, 224, 175, 130, 224, 174, 183, 224, 174, 163, 224, 175, 136, 0, 8, 2, 224, 175, 130, 224, 174, 183, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 175, 134, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 175, 134, 224, 174, 175, 224, 175, 141, 224, 174, 181, 0, 8, 2, 224, 175, 135, 224, 174, 149, 0, 8, 2, 224, 175, 135, 224, 174, 154, 0, 8, 2, 224, 175, 135, 224, 174, 181, 0, 8, 2, 224, 175, 135, 224, 174, 181, 224, 175, 135, 224, 174, 168, 224, 175, 141, 0, 8, 2, 224, 175, 136, 224, 174, 176, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 175, 138, 224, 174, 169, 224, 174, 191, 0, 8, 2, 224, 175, 138, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 175, 136, 0, 8, 2, 224, 175, 138, 224, 174, 170, 224, 174, 164, 224, 175, 138, 224, 174, 170, 0, 8, 2, 224, 175, 138, 224, 174, 170, 224, 175, 129, 224, 174, 149, 224, 175, 141, 0, 8, 2, 224, 175, 138, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 129, 224, 174, 169, 0, 8, 2, 224, 175, 138, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 134, 0, 8, 2, 224, 175, 138, 224, 174, 174, 224, 175, 141, 0, 8, 2, 224, 175, 138, 224, 174, 179, 224, 174, 164, 224, 175, 138, 224, 174, 179, 0, 8, 2, 224, 175, 138, 224, 174, 179, 224, 174, 181, 224, 175, 134, 0, 8, 2, 224, 175, 139, 224, 174, 154, 224, 175, 136, 0, 8, 2, 224, 175, 139, 224, 174, 183, 0, 8, 2, 224, 175, 139, 224, 174, 184, 224, 175, 141, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 175, 139, 224, 174, 185, 224, 174, 190, 0, 8, 2, 224, 175, 141, 224, 174, 176, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 175, 136, 0, 224, 174, 191, 8, 2, 224, 174, 175, 224, 174, 190, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 175, 136, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 181, 224, 174, 191, 224, 174, 159, 0, 224, 175, 129, 8, 2, 224, 174, 176, 224, 175, 139, 224, 174, 149, 0, 224, 175, 129, 8, 2, 224, 174, 176, 224, 175, 139, 224, 174, 163, 0, 224, 175, 129, 8, 2, 224, 174, 181, 224, 174, 168, 224, 175, 141, 224, 174, 164, 32, 0, 224, 175, 129, 8, 2, 224, 174, 181, 224, 174, 174, 224, 175, 141, 224, 174, 154, 0, 224, 175, 129, 8, 2, 224, 174, 181, 224, 175, 135, 224, 174, 154, 0, 224, 175, 129, 8, 2, 224, 174, 181, 224, 175, 135, 224, 174, 183, 0, 224, 175, 141, 224, 174, 164, 224, 175, 129, 1, 133, 174, 224, 2, 224, 174, 181, 224, 174, 190, 224, 174, 169, 0, 224, 175, 141, 224, 174, 164, 224, 175, 129, 1, 191, 174, 224, 181, 174, 224, 2, 224, 174, 181, 224, 174, 190, 224, 174, 169, 0, 224, 175, 141, 224, 174, 164, 224, 175, 129, 8, 191, 174, 224, 176, 174, 224, 185, 174, 224, 2, 224, 174, 181, 224, 174, 190, 224, 174, 176, 0, 4, 224, 174, 191, 224, 174, 176, 224, 175, 129, 8, 2, 224, 174, 164, 224, 174, 191, 224, 174, 176, 224, 174, 190, 3, 72, 34, 37, 0, 224, 174, 191, 224, 174, 176, 224, 175, 129, 8, 2, 224, 174, 183, 224, 175, 141, 224, 174, 159, 224, 174, 191, 0, 224, 174, 191, 224, 174, 178, 224, 174, 191, 224, 174, 170, 224, 175, 141, 8, 3, 72, 37, 55, 37, 48, 0, 224, 174, 191, 224, 174, 178, 224, 175, 128, 224, 174, 170, 224, 175, 141, 8, 3, 72, 37, 55, 112, 48, 0, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 170, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 174, 224, 175, 136, 3, 72, 37, 81, 71, 0, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 164, 8, 2, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 175, 224, 175, 134, 3, 72, 37, 81, 72, 0, 224, 174, 191, 224, 174, 159, 224, 174, 154, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 178, 224, 175, 141, 224, 174, 170, 8, 3, 72, 37, 141, 109, 89, 109, 68, 81, 109, 55, 48, 149, 0, 4, 224, 175, 141, 224, 174, 164, 1, 18, 68, 2, 224, 174, 191, 224, 174, 154, 224, 175, 136, 3, 72, 72, 0, 224, 175, 141, 224, 174, 164, 1, 18, 68, 2, 224, 174, 191, 224, 174, 169, 0, 224, 175, 141, 224, 174, 164, 1, 18, 68, 2, 224, 175, 129, 224, 174, 176, 224, 175, 141, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 224, 175, 141, 224, 174, 164, 1, 18, 68, 2, 224, 175, 130, 224, 174, 154, 0, 224, 175, 141, 224, 174, 164, 1, 18, 68, 2, 224, 175, 130, 224, 174, 176, 224, 174, 164, 224, 175, 141, 0, 224, 175, 141, 224, 174, 164, 1, 18, 68, 2, 224, 175, 130, 224, 174, 176, 224, 174, 174, 0, 224, 175, 141, 224, 174, 164, 1, 18, 68, 2, 224, 175, 134, 224, 174, 175, 224, 175, 141, 224, 174, 181, 0, 224, 175, 141, 224, 174, 164, 1, 18, 68, 2, 224, 175, 135, 224, 174, 154, 0, 224, 175, 141, 224, 174, 164, 1, 18, 68, 2, 224, 175, 135, 224, 174, 181, 224, 174, 164, 0, 224, 175, 141, 224, 174, 164, 1, 18, 68, 2, 224, 175, 135, 224, 174, 181, 224, 174, 169, 0, 224, 175, 141, 224, 174, 164, 1, 18, 68, 2, 224, 175, 135, 224, 174, 181, 224, 174, 176, 0, 224, 175, 141, 224, 174, 164, 1, 129, 175, 224, 159, 174, 224, 141, 175, 224, 159, 174, 224, 142, 174, 224, 2, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 224, 175, 141, 224, 174, 164, 1, 129, 175, 224, 170, 174, 224, 2, 224, 174, 191, 0, 224, 175, 141, 224, 174, 164, 1, 129, 175, 224, 170, 174, 224, 2, 224, 174, 191, 224, 174, 175, 224, 174, 191, 0, 224, 175, 141, 224, 174, 164, 1, 129, 175, 224, 174, 174, 224, 154, 174, 224, 2, 224, 174, 191, 224, 174, 176, 0, 224, 175, 141, 224, 174, 164, 1, 129, 175, 224, 181, 174, 224, 141, 175, 224, 181, 174, 224, 18, 68, 2, 224, 174, 191, 224, 174, 175, 224, 175, 139, 224, 174, 149, 0, 224, 175, 141, 224, 174, 164, 1, 133, 174, 224, 2, 224, 174, 190, 224, 174, 154, 224, 174, 191, 0, 224, 175, 141, 224, 174, 164, 1, 133, 174, 224, 2, 224, 175, 134, 224, 174, 175, 224, 175, 141, 224, 174, 181, 0, 224, 175, 141, 224, 174, 164, 1, 136, 175, 224, 181, 174, 224, 2, 224, 174, 191, 224, 174, 175, 0, 224, 175, 141, 224, 174, 164, 1, 137, 174, 224, 2, 224, 174, 191, 224, 174, 175, 224, 175, 139, 224, 174, 149, 0, 224, 175, 141, 224, 174, 164, 1, 137, 174, 224, 2, 224, 175, 135, 224, 174, 154, 0, 224, 175, 141, 224, 174, 164, 1, 139, 175, 224, 175, 174, 224, 133, 174, 224, 2, 224, 174, 191, 0, 224, 175, 141, 224, 174, 164, 1, 141, 175, 224, 176, 174, 224, 181, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 174, 191, 0, 224, 175, 141, 224, 174, 164, 1, 174, 174, 224, 2, 224, 174, 191, 224, 174, 175, 0, 224, 175, 141, 224, 174, 164, 1, 176, 174, 224, 191, 174, 224, 154, 174, 224, 133, 174, 224, 2, 224, 175, 136, 0, 224, 175, 141, 224, 174, 164, 1, 178, 174, 224, 129, 175, 224, 149, 174, 224, 2, 224, 175, 134, 224, 174, 175, 224, 175, 141, 224, 174, 181, 0, 224, 175, 141, 224, 174, 164, 1, 178, 174, 224, 170, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 174, 153, 224, 175, 141, 0, 224, 175, 141, 224, 174, 164, 1, 178, 174, 224, 191, 174, 224, 154, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 174, 153, 224, 175, 141, 0, 224, 175, 141, 224, 174, 164, 1, 190, 174, 224, 154, 174, 224, 133, 174, 224, 2, 224, 174, 191, 224, 174, 175, 0, 224, 175, 141, 224, 174, 164, 1, 190, 174, 224, 170, 174, 224, 137, 174, 224, 2, 224, 174, 191, 224, 174, 175, 0, 224, 175, 141, 224, 174, 164, 1, 190, 174, 224, 181, 174, 224, 2, 224, 174, 191, 224, 174, 175, 0, 224, 175, 141, 224, 174, 164, 1, 191, 174, 224, 154, 174, 224, 2, 224, 174, 190, 224, 174, 176, 224, 175, 141, 0, 224, 175, 141, 224, 174, 164, 1, 191, 174, 224, 181, 174, 224, 2, 224, 175, 136, 224, 174, 175, 224, 174, 190, 224, 174, 149, 0, 224, 175, 141, 224, 174, 164, 1, 191, 174, 224, 181, 174, 224, 2, 224, 175, 136, 224, 174, 175, 224, 174, 190, 224, 174, 178, 224, 175, 141, 32, 0, 224, 175, 141, 224, 174, 164, 1, 191, 174, 224, 181, 174, 224, 2, 224, 175, 136, 224, 174, 175, 224, 174, 191, 0, 224, 175, 141, 224, 174, 164, 1, 191, 174, 224, 181, 174, 224, 2, 224, 175, 136, 224, 174, 175, 224, 175, 136, 0, 224, 175, 141, 224, 174, 164, 8, 129, 175, 224, 176, 174, 224, 2, 224, 174, 191, 224, 174, 176, 0, 224, 175, 141, 224, 174, 164, 8, 129, 175, 224, 176, 174, 224, 169, 174, 224, 129, 175, 224, 170, 174, 224, 2, 224, 174, 190, 224, 174, 176, 224, 174, 163, 0, 224, 175, 141, 224, 174, 164, 8, 129, 175, 224, 176, 174, 224, 191, 174, 224, 181, 174, 224, 2, 224, 174, 191, 0, 224, 175, 141, 224, 174, 164, 8, 130, 175, 224, 154, 174, 224, 2, 224, 174, 191, 224, 174, 176, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 174, 191, 0, 224, 175, 141, 224, 174, 164, 8, 130, 175, 224, 154, 174, 224, 2, 224, 174, 191, 224, 174, 176, 224, 174, 169, 0, 224, 175, 141, 224, 174, 164, 8, 130, 175, 224, 154, 174, 224, 2, 224, 174, 191, 224, 174, 176, 224, 174, 176, 224, 174, 191, 0, 224, 175, 141, 224, 174, 164, 8, 130, 175, 224, 154, 174, 224, 2, 224, 174, 191, 224, 174, 176, 224, 174, 176, 224, 175, 141, 0, 224, 175, 141, 224, 174, 164, 8, 135, 175, 224, 181, 174, 224, 136, 175, 224, 168, 174, 224, 2, 224, 174, 191, 224, 174, 175, 0, 224, 175, 141, 224, 174, 164, 8, 136, 175, 224, 181, 174, 224, 2, 224, 174, 191, 32, 0, 224, 175, 141, 224, 174, 164, 8, 136, 175, 224, 181, 174, 224, 2, 224, 175, 128, 224, 174, 184, 224, 175, 141, 224, 174, 181, 0, 224, 175, 141, 224, 174, 164, 8, 140, 175, 224, 176, 174, 224, 2, 224, 174, 191, 224, 174, 176, 0, 224, 175, 141, 224, 174, 164, 8, 141, 175, 224, 176, 174, 224, 191, 174, 224, 168, 174, 224, 2, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 174, 163, 224, 175, 141, 224, 174, 175, 0, 224, 175, 141, 224, 174, 164, 8, 170, 174, 224, 129, 175, 224, 154, 174, 224, 2, 224, 174, 191, 224, 174, 176, 0, 224, 175, 141, 224, 174, 164, 8, 170, 174, 224, 137, 174, 224, 2, 224, 174, 191, 224, 174, 176, 0, 224, 175, 141, 224, 174, 164, 8, 174, 174, 224, 2, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 0, 224, 175, 141, 224, 174, 164, 8, 190, 174, 224, 154, 174, 224, 2, 224, 174, 191, 224, 174, 175, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 130, 224, 174, 177, 0, 224, 175, 141, 224, 174, 164, 8, 190, 174, 224, 154, 174, 224, 2, 224, 174, 191, 224, 174, 175, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 179, 0, 224, 175, 141, 224, 174, 164, 8, 190, 174, 224, 154, 174, 224, 2, 224, 174, 191, 224, 174, 175, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 224, 175, 141, 224, 174, 164, 8, 190, 174, 224, 154, 174, 224, 2, 224, 174, 191, 224, 174, 175, 224, 174, 168, 224, 175, 141, 0, 224, 175, 141, 224, 174, 164, 8, 190, 174, 224, 154, 174, 224, 2, 224, 174, 191, 224, 174, 175, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 159, 0, 224, 175, 141, 224, 174, 164, 8, 190, 174, 224, 154, 174, 224, 2, 224, 174, 191, 224, 174, 175, 224, 174, 174, 0, 224, 175, 141, 224, 174, 164, 8, 191, 174, 224, 181, 174, 224, 2, 224, 174, 191, 224, 174, 175, 224, 174, 190, 224, 174, 176, 224, 175, 141, 0, 224, 175, 141, 224, 174, 164, 8, 191, 174, 224, 181, 174, 224, 2, 224, 175, 136, 224, 174, 149, 224, 174, 179, 0, 224, 175, 141, 224, 174, 164, 8, 191, 174, 224, 181, 174, 224, 2, 224, 175, 136, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 190, 224, 174, 149, 0, 224, 175, 141, 224, 174, 164, 8, 191, 174, 224, 181, 174, 224, 2, 224, 175, 136, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 0, 224, 175, 141, 224, 174, 164, 8, 191, 174, 224, 181, 174, 224, 32, 141, 175, 224, 178, 174, 224, 191, 174, 224, 181, 174, 224, 2, 224, 175, 136, 0, 224, 175, 141, 224, 174, 164, 8, 191, 174, 224, 181, 174, 224, 141, 175, 224, 178, 174, 224, 191, 174, 224, 181, 174, 224, 2, 224, 175, 136, 0, 224, 175, 141, 224, 174, 164, 224, 174, 191, 1, 191, 174, 224, 164, 174, 224, 134, 174, 224, 2, 224, 174, 176, 224, 174, 190, 224, 174, 181, 224, 174, 191, 224, 174, 159, 0, 224, 175, 141, 224, 174, 164, 224, 175, 129, 1, 18, 68, 2, 224, 174, 181, 224, 174, 190, 224, 174, 176, 0, 224, 175, 141, 224, 174, 164, 224, 175, 129, 1, 156, 174, 224, 190, 174, 224, 176, 174, 224, 2, 224, 174, 176, 224, 175, 139, 224, 174, 149, 0, 224, 175, 141, 224, 174, 164, 224, 175, 129, 8, 149, 174, 224, 129, 175, 224, 174, 174, 224, 2, 224, 174, 181, 224, 174, 190, 224, 174, 176, 0, 4, 224, 175, 141, 224, 174, 164, 1, 129, 175, 224, 170, 174, 224, 2, 224, 174, 169, 3, 72, 72, 109, 0, 224, 175, 141, 224, 174, 164, 1, 129, 175, 224, 170, 174, 224, 2, 224, 174, 176, 0, 224, 175, 141, 224, 174, 164, 1, 141, 175, 224, 176, 174, 224, 133, 174, 224, 2, 18, 74, 224, 174, 190, 224, 174, 176, 0, 224, 175, 141, 224, 174, 164, 8, 129, 175, 224, 159, 174, 224, 141, 175, 224, 159, 174, 224, 176, 174, 224, 129, 175, 224, 174, 174, 224, 2, 224, 174, 159, 224, 174, 191, 224, 174, 175, 224, 174, 169, 0, 224, 175, 141, 224, 174, 164, 8, 129, 175, 224, 159, 174, 224, 141, 175, 224, 159, 174, 224, 176, 174, 224, 129, 175, 224, 174, 174, 224, 2, 224, 174, 159, 224, 174, 191, 224, 174, 175, 224, 174, 176, 0, 224, 175, 141, 224, 174, 164, 8, 136, 175, 224, 177, 174, 224, 191, 174, 224, 154, 174, 224, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 169, 224, 175, 136, 0, 224, 175, 141, 224, 174, 164, 8, 141, 175, 224, 176, 174, 224, 168, 174, 224, 2, 224, 174, 169, 0, 224, 175, 141, 224, 174, 164, 8, 141, 175, 224, 176, 174, 224, 181, 174, 224, 2, 224, 174, 174, 224, 174, 190, 224, 174, 169, 0, 224, 175, 141, 224, 174, 164, 8, 141, 175, 224, 176, 174, 224, 181, 174, 224, 191, 174, 224, 176, 174, 224, 170, 174, 224, 2, 224, 174, 169, 0, 224, 175, 141, 224, 174, 164, 8, 141, 175, 224, 176, 174, 224, 190, 174, 224, 169, 174, 224, 156, 174, 224, 2, 224, 174, 169, 0, 224, 175, 141, 224, 174, 164, 224, 174, 176, 224, 174, 190, 224, 174, 164, 224, 175, 141, 224, 174, 164, 1, 141, 175, 224, 176, 174, 224, 133, 174, 224, 2, 224, 174, 191, 224, 174, 176, 224, 174, 191, 3, 72, 72, 109, 34, 118, 72, 72, 0, 224, 175, 141, 224, 174, 164, 224, 175, 128, 224, 174, 154, 224, 175, 129, 8, 136, 175, 224, 181, 174, 224, 2, 224, 174, 181, 3, 72, 72, 112, 89, 0, 224, 175, 141, 224, 174, 164, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 8, 191, 174, 224, 154, 174, 224, 3, 72, 72, 118, 50, 47, 149, 0, 224, 175, 141, 224, 174, 164, 224, 174, 190, 224, 174, 154, 8, 129, 175, 224, 176, 174, 224, 191, 174, 224, 181, 174, 224, 2, 224, 174, 178, 3, 72, 72, 118, 76, 109, 0, 4, 224, 175, 141, 224, 174, 164, 1, 129, 175, 224, 175, 174, 224, 3, 72, 72, 149, 0, 224, 175, 141, 224, 174, 164, 8, 141, 175, 224, 176, 174, 224, 190, 174, 224, 176, 174, 224, 141, 175, 224, 184, 174, 224, 0, 224, 175, 141, 224, 174, 164, 8, 141, 175, 224, 176, 174, 224, 190, 174, 224, 176, 174, 224, 191, 174, 224, 154, 174, 224, 0, 4, 224, 175, 129, 224, 174, 181, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 154, 224, 174, 191, 3, 72, 84, 0, 224, 175, 129, 224, 174, 181, 8, 2, 224, 174, 190, 224, 174, 176, 0, 224, 175, 129, 224, 174, 181, 8, 2, 224, 175, 136, 224, 174, 164, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 224, 175, 129, 224, 174, 181, 224, 174, 190, 224, 174, 170, 8, 2, 224, 174, 176, 3, 72, 84, 118, 48, 109, 0, 4, 224, 175, 129, 224, 174, 181, 224, 175, 136, 224, 174, 164, 8, 2, 32, 3, 72, 84, 134, 47, 109, 0, 224, 175, 129, 224, 174, 181, 224, 175, 136, 224, 174, 164, 8, 2, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 178, 0, 224, 175, 129, 224, 174, 181, 224, 175, 136, 224, 174, 164, 8, 2, 224, 174, 174, 0, 4, 3, 72, 109, 0, 8, 2, 18, 69, 224, 174, 190, 0, 8, 2, 28, 17, 0, 8, 2, 224, 174, 149, 224, 174, 164, 224, 174, 149, 0, 8, 2, 224, 174, 149, 224, 174, 169, 0, 8, 2, 224, 174, 149, 224, 174, 191, 0, 8, 2, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 141, 224, 174, 183, 224, 174, 191, 224, 174, 163, 0, 8, 2, 224, 174, 149, 224, 175, 141, 224, 174, 183, 224, 174, 191, 224, 174, 163, 0, 8, 2, 224, 174, 149, 224, 175, 141, 224, 174, 183, 224, 174, 191, 224, 174, 163, 224, 174, 190, 0, 8, 2, 224, 174, 154, 224, 174, 149, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 174, 154, 224, 174, 174, 224, 174, 191, 0, 8, 2, 224, 174, 154, 224, 174, 176, 224, 174, 164, 0, 8, 2, 224, 174, 154, 224, 174, 176, 224, 174, 164, 224, 174, 176, 0, 8, 2, 224, 174, 154, 224, 174, 176, 224, 174, 190, 0, 8, 2, 224, 174, 154, 224, 174, 190, 224, 174, 170, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 174, 154, 224, 175, 136, 0, 8, 2, 224, 174, 159, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 174, 159, 224, 174, 164, 224, 174, 159, 0, 8, 2, 224, 174, 159, 224, 174, 170, 224, 175, 129, 224, 174, 159, 0, 8, 2, 224, 174, 159, 224, 174, 181, 224, 175, 134, 0, 8, 2, 224, 174, 159, 224, 174, 181, 224, 175, 136, 0, 8, 2, 224, 174, 159, 224, 174, 190, 224, 174, 178, 0, 8, 2, 224, 174, 159, 224, 174, 191, 23, 32, 224, 174, 170, 224, 174, 175, 224, 174, 178, 0, 8, 2, 224, 174, 159, 224, 174, 191, 23, 32, 224, 174, 170, 224, 175, 129, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 149, 0, 8, 2, 224, 174, 159, 224, 174, 191, 23, 32, 224, 174, 174, 224, 174, 190, 224, 174, 159, 0, 8, 2, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 190, 224, 174, 174, 0, 8, 2, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 174, 0, 8, 2, 224, 174, 159, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 174, 159, 224, 174, 191, 224, 174, 170, 224, 175, 141, 0, 8, 2, 224, 174, 159, 224, 174, 191, 224, 174, 174, 224, 174, 169, 0, 8, 2, 224, 174, 159, 224, 174, 191, 224, 174, 174, 224, 174, 190, 224, 174, 159, 0, 8, 2, 224, 174, 159, 224, 174, 191, 224, 174, 175, 224, 174, 169, 0, 8, 2, 224, 174, 159, 224, 174, 191, 224, 174, 175, 224, 174, 176, 0, 8, 2, 224, 174, 159, 224, 174, 191, 224, 174, 175, 224, 174, 190, 224, 174, 169, 0, 8, 2, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 174, 154, 224, 175, 128, 224, 174, 178, 0, 8, 2, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 174, 169, 0, 8, 2, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 174, 191, 224, 174, 163, 0, 8, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 149, 224, 175, 141, 0, 8, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 175, 139, 224, 174, 177, 0, 8, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 169, 0, 8, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 170, 224, 174, 190, 224, 174, 163, 224, 174, 191, 0, 8, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 174, 0, 8, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 190, 224, 174, 175, 224, 175, 129, 224, 174, 164, 224, 174, 170, 224, 174, 190, 224, 174, 163, 224, 174, 191, 0, 8, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 0, 8, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 190, 0, 8, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 175, 224, 175, 129, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 179, 0, 8, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 175, 128, 224, 174, 184, 224, 175, 141, 224, 174, 181, 224, 174, 176, 0, 8, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 175, 139, 224, 174, 176, 224, 174, 190, 0, 8, 2, 224, 174, 169, 224, 174, 149, 224, 175, 139, 224, 174, 159, 224, 174, 191, 0, 8, 2, 224, 174, 169, 224, 174, 154, 224, 175, 135, 224, 174, 149, 224, 174, 176, 224, 174, 169, 0, 8, 2, 224, 174, 169, 224, 174, 169, 224, 175, 141, 224, 174, 156, 224, 175, 134, 224, 174, 175, 224, 174, 169, 0, 8, 2, 224, 174, 169, 224, 174, 170, 224, 174, 190, 224, 174, 178, 0, 8, 2, 224, 174, 169, 224, 174, 176, 224, 174, 190, 224, 174, 154, 0, 8, 2, 224, 174, 169, 224, 174, 176, 224, 174, 190, 224, 174, 156, 0, 8, 2, 224, 174, 169, 224, 174, 178, 224, 174, 149, 224, 175, 141, 224, 174, 183, 224, 175, 141, 224, 174, 174, 224, 174, 191, 0, 8, 2, 224, 174, 169, 224, 174, 178, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 175, 129, 224, 174, 174, 224, 174, 191, 0, 8, 2, 224, 174, 169, 224, 174, 181, 224, 174, 168, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 174, 169, 224, 175, 129, 224, 174, 154, 0, 8, 2, 224, 174, 169, 224, 175, 129, 224, 174, 183, 0, 8, 2, 224, 174, 169, 224, 175, 141, 224, 174, 174, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 224, 174, 191, 0, 8, 2, 224, 174, 169, 224, 175, 141, 224, 174, 176, 224, 174, 190, 224, 174, 156, 0, 8, 2, 224, 174, 169, 224, 175, 141, 224, 174, 181, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 176, 224, 174, 191, 0, 8, 2, 224, 174, 174, 224, 174, 175, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 191, 0, 8, 2, 224, 174, 174, 224, 175, 141, 32, 18, 89, 0, 8, 2, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 174, 159, 224, 174, 191, 0, 8, 2, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 174, 164, 224, 174, 191, 0, 8, 2, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 174, 191, 224, 174, 159, 224, 174, 191, 0, 8, 2, 224, 174, 174, 224, 175, 141, 224, 174, 174, 224, 174, 159, 224, 174, 191, 18, 76, 224, 175, 141, 0, 8, 2, 224, 174, 175, 224, 174, 181, 0, 8, 2, 224, 174, 175, 224, 174, 190, 224, 174, 163, 224, 174, 168, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 174, 175, 224, 174, 190, 224, 174, 169, 0, 8, 2, 224, 174, 175, 224, 174, 190, 224, 174, 178, 0, 8, 2, 224, 174, 175, 224, 174, 190, 224, 174, 179, 0, 8, 2, 224, 174, 175, 224, 175, 136, 0, 8, 2, 224, 174, 176, 224, 174, 163, 224, 174, 191, 0, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 181, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 154, 224, 174, 169, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 154, 224, 174, 169, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 154, 224, 174, 191, 0, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 224, 174, 174, 0, 8, 2, 224, 174, 176, 224, 175, 129, 224, 174, 174, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 174, 176, 224, 175, 129, 224, 174, 174, 224, 174, 154, 224, 175, 135, 224, 174, 169, 0, 8, 2, 224, 174, 176, 224, 175, 129, 224, 174, 174, 224, 174, 154, 224, 175, 141, 0, 8, 2, 224, 174, 176, 224, 175, 129, 224, 174, 174, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 174, 176, 224, 175, 129, 224, 174, 174, 224, 174, 169, 0, 8, 2, 224, 174, 176, 224, 175, 129, 224, 174, 174, 224, 174, 170, 224, 175, 129, 224, 174, 176, 0, 8, 2, 224, 174, 176, 224, 175, 129, 224, 174, 174, 224, 174, 170, 224, 175, 141, 0, 8, 2, 224, 174, 176, 224, 175, 129, 224, 174, 174, 224, 174, 174, 0, 8, 2, 224, 174, 176, 224, 175, 129, 224, 174, 174, 224, 174, 176, 0, 8, 2, 224, 174, 176, 224, 175, 129, 224, 174, 174, 224, 174, 191, 0, 8, 2, 224, 174, 176, 224, 175, 141, 224, 174, 149, 224, 174, 190, 0, 8, 2, 224, 174, 176, 224, 175, 141, 224, 174, 170, 224, 174, 190, 224, 174, 176, 0, 8, 2, 224, 174, 176, 224, 175, 141, 224, 174, 170, 224, 175, 130, 224, 174, 154, 0, 8, 2, 224, 174, 176, 224, 175, 141, 224, 174, 170, 224, 175, 136, 0, 8, 2, 224, 174, 176, 224, 175, 141, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 136, 0, 8, 2, 224, 174, 176, 224, 175, 141, 224, 174, 174, 0, 8, 2, 224, 174, 178, 224, 174, 191, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 174, 181, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 190, 224, 174, 178, 0, 8, 2, 224, 174, 181, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 139, 224, 174, 178, 0, 8, 2, 224, 174, 181, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 174, 181, 224, 174, 170, 224, 175, 141, 0, 8, 2, 224, 174, 181, 224, 174, 174, 0, 8, 32, 191, 174, 224, 178, 174, 224, 190, 174, 224, 149, 174, 224, 133, 174, 224, 2, 224, 174, 179, 0, 8, 141, 175, 224, 170, 174, 224, 154, 174, 224, 2, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 179, 0, 8, 141, 175, 224, 170, 174, 224, 154, 174, 224, 2, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 141, 175, 224, 170, 174, 224, 154, 174, 224, 2, 224, 174, 174, 0, 4, 224, 174, 176, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 8, 2, 224, 174, 191, 224, 174, 176, 32, 3, 72, 109, 34, 37, 72, 72, 0, 224, 174, 176, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 8, 2, 224, 174, 191, 224, 174, 176, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 224, 174, 176, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 8, 2, 224, 174, 191, 224, 174, 176, 224, 174, 174, 224, 175, 141, 0, 224, 174, 176, 224, 175, 129, 224, 174, 174, 224, 174, 170, 8, 2, 224, 174, 190, 224, 174, 178, 3, 72, 109, 34, 40, 65, 109, 71, 0, 224, 174, 176, 224, 175, 129, 224, 174, 174, 224, 174, 170, 8, 2, 224, 175, 129, 224, 174, 176, 224, 174, 191, 3, 72, 109, 34, 122, 65, 109, 48, 0, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 175, 128, 224, 174, 154, 224, 175, 129, 8, 2, 224, 174, 181, 224, 174, 176, 3, 72, 109, 66, 141, 112, 89, 0, 224, 174, 170, 224, 174, 164, 224, 174, 170, 8, 3, 72, 109, 71, 109, 72, 109, 71, 149, 0, 224, 174, 164, 224, 175, 141, 224, 174, 164, 8, 2, 224, 174, 191, 224, 174, 175, 224, 174, 190, 3, 72, 109, 72, 72, 0, 224, 174, 176, 224, 175, 141, 224, 174, 149, 224, 175, 141, 224, 174, 149, 8, 2, 224, 174, 190, 3, 72, 109, 81, 81, 0, 224, 174, 181, 224, 175, 129, 224, 174, 178, 224, 174, 164, 224, 174, 190, 224, 174, 170, 8, 2, 224, 174, 190, 224, 174, 164, 3, 72, 109, 84, 122, 55, 109, 72, 118, 71, 0, 4, 224, 175, 128, 224, 174, 176, 224, 175, 141, 224, 174, 149, 224, 175, 141, 224, 174, 149, 8, 2, 224, 174, 164, 224, 174, 176, 224, 174, 191, 224, 174, 154, 3, 72, 112, 34, 81, 81, 109, 0, 224, 175, 128, 224, 174, 176, 224, 175, 141, 224, 174, 149, 224, 175, 141, 224, 174, 149, 8, 2, 224, 174, 174, 224, 174, 191, 0, 224, 175, 128, 224, 174, 176, 224, 175, 141, 224, 174, 149, 224, 175, 141, 224, 174, 149, 8, 2, 224, 174, 174, 224, 175, 141, 32, 0, 4, 224, 175, 128, 224, 174, 176, 224, 175, 141, 224, 174, 149, 224, 175, 141, 224, 174, 149, 8, 2, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 129, 224, 174, 159, 224, 174, 169, 3, 72, 112, 34, 81, 81, 149, 0, 224, 175, 128, 224, 174, 176, 224, 175, 141, 224, 174, 149, 224, 175, 141, 224, 174, 149, 8, 2, 224, 174, 174, 224, 175, 129, 224, 174, 179, 224, 175, 141, 224, 174, 179, 0, 224, 175, 128, 224, 174, 176, 224, 175, 141, 224, 174, 149, 224, 175, 141, 224, 174, 149, 8, 2, 224, 174, 190, 224, 174, 175, 224, 175, 129, 0, 224, 175, 140, 224, 174, 178, 224, 174, 164, 224, 174, 190, 224, 174, 170, 8, 2, 224, 174, 190, 224, 174, 164, 3, 72, 135, 55, 109, 141, 118, 71, 0, 8, 141, 175, 224, 170, 174, 224, 154, 174, 224, 191, 174, 224, 168, 174, 224, 3, 72, 149, 0, 7, 6, 1, 41, 0, 4, 2, 17, 66, 3, 50, 0, 224, 174, 191, 8, 2, 224, 174, 175, 224, 174, 190, 224, 174, 175, 0, 224, 174, 191, 8, 2, 224, 174, 175, 224, 175, 130, 0, 3, 50, 109, 0, 7, 6, 1, 42, 0, 2, 17, 66, 3, 50, 0, 3, 50, 109, 0, 7, 6, 1, 43, 0, 1, 141, 175, 224, 174, 174, 224, 146, 174, 224, 2, 224, 175, 139, 224, 174, 164, 224, 175, 129, 3, 10, 0, 8, 141, 175, 224, 170, 174, 224, 141, 175, 224, 180, 174, 224, 191, 174, 224, 174, 174, 224, 164, 174, 224, 2, 224, 174, 190, 224, 174, 183, 3, 10, 71, 0, 4, 1, 21, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 32, 3, 48, 0, 1, 21, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 224, 174, 168, 224, 174, 190, 224, 174, 178, 224, 175, 129, 224, 174, 174, 224, 175, 141, 32, 0, 1, 21, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 174, 176, 224, 175, 141, 32, 0, 1, 21, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 174, 190, 224, 174, 178, 224, 175, 141, 32, 0, 1, 128, 175, 224, 169, 174, 224, 2, 224, 174, 190, 0, 1, 128, 175, 224, 176, 174, 224, 2, 224, 174, 190, 0, 1, 129, 175, 224, 159, 174, 224, 136, 174, 224, 2, 224, 174, 190, 224, 174, 159, 0, 1, 129, 175, 224, 159, 174, 224, 141, 175, 224, 163, 174, 224, 149, 174, 224, 2, 224, 174, 191, 224, 174, 159, 224, 174, 191, 0, 1, 129, 175, 224, 164, 174, 224, 129, 175, 224, 180, 174, 224, 138, 175, 224, 170, 174, 224, 2, 224, 175, 139, 224, 174, 149, 224, 175, 141, 0, 1, 129, 175, 224, 175, 174, 224, 190, 174, 224, 181, 174, 224, 2, 224, 175, 129, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 0, 1, 129, 175, 224, 176, 174, 224, 135, 174, 224, 2, 224, 174, 190, 224, 174, 178, 0, 1, 129, 175, 224, 176, 174, 224, 146, 174, 224, 2, 224, 174, 190, 224, 174, 164, 0, 1, 129, 175, 224, 176, 174, 224, 146, 174, 224, 2, 224, 174, 190, 224, 174, 178, 0, 1, 129, 175, 224, 176, 174, 224, 146, 174, 224, 2, 224, 175, 135, 224, 174, 154, 224, 175, 141, 224, 174, 154, 0, 1, 129, 175, 224, 177, 174, 224, 191, 174, 224, 154, 174, 224, 2, 224, 174, 191, 224, 174, 179, 224, 175, 141, 224, 174, 179, 224, 175, 136, 0, 1, 133, 174, 224, 2, 224, 174, 190, 224, 174, 169, 0, 1, 136, 175, 224, 154, 174, 224, 133, 174, 224, 2, 224, 175, 139, 224, 174, 159, 0, 1, 136, 175, 224, 154, 174, 224, 135, 174, 224, 2, 224, 174, 190, 224, 174, 159, 0, 1, 136, 175, 224, 159, 174, 224, 142, 174, 224, 2, 224, 175, 139, 224, 174, 159, 0, 1, 136, 175, 224, 178, 174, 224, 133, 174, 224, 2, 224, 174, 190, 224, 174, 175, 0, 1, 136, 175, 224, 178, 174, 224, 133, 174, 224, 2, 224, 175, 135, 224, 174, 154, 224, 174, 191, 0, 1, 136, 175, 224, 178, 174, 224, 138, 175, 224, 164, 174, 224, 2, 224, 175, 135, 224, 174, 154, 224, 174, 191, 0, 1, 137, 174, 224, 2, 224, 174, 190, 224, 174, 154, 224, 174, 169, 224, 175, 136, 0, 1, 141, 175, 224, 163, 174, 224, 128, 175, 224, 181, 174, 224, 2, 224, 174, 190, 224, 174, 181, 0, 1, 141, 175, 224, 163, 174, 224, 128, 175, 224, 181, 174, 224, 2, 224, 175, 135, 224, 174, 154, 224, 175, 141, 224, 174, 154, 0, 1, 141, 175, 224, 163, 174, 224, 128, 175, 224, 181, 174, 224, 2, 224, 175, 138, 224, 174, 180, 224, 175, 129, 224, 174, 164, 0, 1, 141, 175, 224, 163, 174, 224, 134, 174, 224, 2, 224, 174, 190, 224, 174, 178, 0, 1, 141, 175, 224, 163, 174, 224, 134, 174, 224, 2, 224, 174, 191, 224, 174, 179, 224, 175, 141, 224, 174, 179, 224, 175, 136, 0, 1, 141, 175, 224, 163, 174, 224, 134, 175, 224, 170, 174, 224, 2, 224, 174, 191, 224, 174, 179, 224, 175, 141, 224, 174, 179, 224, 175, 136, 0, 1, 141, 175, 224, 163, 174, 224, 149, 174, 224, 2, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 181, 224, 175, 136, 0, 1, 141, 175, 224, 163, 174, 224, 174, 174, 224, 2, 224, 175, 129, 224, 174, 180, 224, 175, 129, 0, 1, 141, 175, 224, 169, 174, 224, 159, 174, 224, 137, 174, 224, 2, 224, 174, 190, 224, 174, 159, 0, 1, 141, 175, 224, 169, 174, 224, 159, 174, 224, 137, 174, 224, 2, 224, 174, 191, 224, 174, 177, 0, 1, 141, 175, 224, 169, 174, 224, 164, 174, 224, 18, 68, 2, 224, 174, 190, 224, 174, 178, 0, 1, 141, 175, 224, 169, 174, 224, 174, 174, 224, 154, 174, 224, 2, 224, 174, 190, 224, 174, 159, 0, 1, 141, 175, 224, 169, 174, 224, 176, 174, 224, 129, 175, 224, 174, 174, 224, 2, 224, 174, 190, 224, 174, 159, 0, 1, 141, 175, 224, 170, 174, 224, 2, 17, 66, 0, 1, 141, 175, 224, 174, 174, 224, 133, 174, 224, 2, 224, 175, 136, 224, 174, 175, 224, 174, 176, 0, 1, 141, 175, 224, 174, 174, 224, 135, 174, 224, 2, 224, 175, 128, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 174, 178, 0, 1, 141, 175, 224, 174, 174, 224, 135, 174, 224, 2, 224, 175, 139, 224, 174, 154, 224, 174, 191, 224, 174, 183, 224, 174, 169, 0, 1, 141, 175, 224, 174, 174, 224, 142, 174, 224, 2, 224, 175, 139, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 174, 178, 0, 1, 141, 175, 224, 174, 174, 224, 143, 174, 224, 2, 224, 174, 190, 32, 0, 1, 141, 175, 224, 174, 174, 224, 159, 174, 224, 135, 174, 224, 2, 224, 175, 134, 224, 174, 175, 224, 174, 176, 0, 1, 141, 175, 224, 174, 174, 224, 179, 174, 224, 135, 174, 224, 2, 224, 175, 134, 224, 174, 163, 224, 175, 141, 0, 1, 141, 175, 224, 174, 174, 224, 190, 174, 224, 176, 174, 224, 2, 224, 175, 130, 224, 174, 176, 0, 1, 141, 175, 224, 175, 174, 224, 135, 175, 224, 164, 174, 224, 2, 224, 174, 191, 224, 174, 177, 224, 175, 136, 0, 1, 141, 175, 224, 176, 174, 224, 179, 174, 224, 181, 174, 224, 2, 224, 174, 191, 224, 174, 177, 224, 175, 136, 0, 1, 141, 175, 224, 176, 174, 224, 191, 174, 224, 164, 174, 224, 142, 174, 224, 2, 224, 174, 190, 224, 174, 176, 0, 1, 141, 175, 224, 176, 174, 224, 191, 174, 224, 174, 174, 224, 191, 174, 224, 164, 174, 224, 2, 224, 174, 191, 224, 174, 159, 224, 174, 191, 0, 1, 141, 175, 224, 178, 174, 224, 133, 174, 224, 2, 224, 174, 190, 224, 174, 175, 224, 175, 129, 0, 1, 141, 175, 224, 178, 174, 224, 181, 174, 224, 190, 174, 224, 176, 174, 224, 2, 224, 174, 191, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 191, 0, 1, 141, 175, 224, 179, 174, 224, 134, 174, 224, 2, 224, 174, 191, 224, 174, 159, 224, 174, 191, 0, 1, 141, 175, 224, 184, 174, 224, 141, 175, 224, 169, 174, 224, 135, 174, 224, 2, 224, 175, 134, 224, 174, 149, 224, 175, 141, 224, 174, 159, 224, 174, 176, 0, 1, 146, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 174, 191, 224, 174, 175, 224, 174, 169, 0, 1, 149, 174, 224, 2, 224, 174, 190, 0, 1, 154, 174, 224, 141, 175, 224, 158, 174, 224, 170, 174, 224, 2, 224, 174, 190, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 1, 156, 174, 224, 190, 174, 224, 176, 174, 224, 2, 224, 175, 129, 224, 174, 164, 224, 174, 169, 0, 1, 156, 174, 224, 190, 174, 224, 176, 174, 224, 2, 224, 175, 129, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 0, 1, 159, 174, 224, 133, 174, 224, 2, 224, 174, 190, 224, 174, 181, 0, 1, 159, 174, 224, 141, 175, 224, 163, 174, 224, 164, 174, 224, 2, 224, 174, 190, 224, 174, 163, 224, 174, 191, 0, 1, 164, 174, 224, 2, 224, 174, 190, 0, 1, 170, 174, 224, 137, 174, 224, 2, 224, 175, 128, 224, 174, 159, 0, 1, 174, 174, 224, 2, 224, 174, 190, 0, 1, 174, 174, 224, 2, 224, 174, 190, 0, 1, 190, 174, 224, 149, 174, 224, 2, 224, 174, 190, 0, 1, 190, 174, 224, 154, 174, 224, 2, 224, 174, 190, 0, 1, 190, 174, 224, 164, 174, 224, 2, 224, 174, 190, 0, 1, 190, 174, 224, 164, 174, 224, 190, 174, 224, 181, 174, 224, 2, 224, 174, 191, 0, 1, 190, 174, 224, 174, 174, 224, 2, 224, 174, 190, 0, 1, 191, 174, 224, 18, 75, 146, 174, 224, 2, 224, 175, 134, 0, 1, 191, 174, 224, 149, 174, 224, 141, 175, 224, 149, 174, 224, 191, 174, 224, 181, 174, 224, 2, 224, 175, 128, 224, 174, 159, 224, 174, 191, 224, 174, 175, 224, 174, 190, 0, 1, 191, 174, 224, 159, 174, 224, 133, 174, 224, 2, 224, 174, 190, 224, 174, 181, 224, 174, 191, 0, 1, 191, 174, 224, 159, 174, 224, 134, 175, 224, 181, 174, 224, 2, 224, 175, 138, 224, 174, 176, 224, 175, 129, 0, 1, 191, 174, 224, 159, 174, 224, 135, 174, 224, 2, 224, 174, 190, 224, 174, 159, 0, 1, 191, 174, 224, 164, 174, 224, 129, 175, 224, 177, 174, 224, 137, 174, 224, 2, 224, 175, 130, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 1, 191, 174, 224, 169, 174, 224, 2, 224, 174, 190, 0, 1, 191, 174, 224, 169, 174, 224, 141, 175, 224, 149, 174, 224, 133, 174, 224, 2, 224, 175, 129, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 0, 1, 191, 174, 224, 169, 174, 224, 191, 174, 224, 149, 174, 224, 141, 175, 224, 149, 174, 224, 133, 174, 224, 2, 224, 175, 129, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 0, 1, 191, 174, 224, 176, 174, 224, 142, 174, 224, 2, 224, 175, 138, 224, 174, 176, 224, 175, 129, 0, 1, 191, 174, 224, 178, 174, 224, 141, 175, 224, 178, 174, 224, 191, 174, 224, 181, 174, 224, 2, 224, 175, 129, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 130, 224, 174, 176, 0, 1, 191, 174, 224, 178, 174, 224, 159, 174, 224, 190, 174, 224, 170, 174, 224, 2, 224, 175, 129, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 0, 1, 191, 174, 224, 180, 174, 224, 138, 175, 224, 174, 174, 224, 2, 224, 175, 134, 224, 174, 175, 224, 174, 176, 224, 175, 141, 0, 2, 224, 174, 190, 224, 174, 159, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 175, 136, 0, 2, 224, 174, 190, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 191, 0, 2, 224, 174, 190, 224, 174, 179, 224, 175, 136, 224, 174, 175, 0, 2, 224, 174, 191, 224, 174, 177, 224, 174, 149, 224, 175, 129, 12, 0, 2, 224, 174, 191, 224, 174, 179, 224, 175, 141, 224, 174, 179, 224, 175, 136, 0, 2, 224, 175, 129, 224, 174, 176, 0, 2, 224, 175, 129, 224, 174, 177, 25, 0, 2, 224, 175, 130, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 174, 191, 0, 2, 224, 175, 130, 224, 174, 176, 0, 2, 224, 175, 134, 224, 174, 177, 0, 2, 224, 175, 135, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 175, 136, 0, 2, 224, 175, 135, 224, 174, 176, 224, 174, 191, 224, 174, 178, 224, 175, 141, 32, 0, 2, 224, 175, 135, 224, 174, 176, 224, 175, 141, 32, 0, 2, 224, 175, 138, 224, 174, 180, 224, 175, 129, 224, 174, 164, 224, 174, 191, 224, 174, 178, 224, 174, 190, 32, 12, 0, 2, 224, 175, 138, 224, 174, 180, 224, 175, 129, 224, 174, 164, 224, 174, 191, 224, 174, 178, 224, 175, 129, 224, 174, 174, 224, 175, 141, 32, 12, 0, 2, 224, 175, 138, 224, 174, 180, 224, 175, 129, 224, 174, 164, 224, 174, 191, 224, 174, 178, 224, 175, 141, 32, 12, 0, 2, 224, 175, 138, 224, 174, 180, 224, 175, 129, 224, 174, 164, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 190, 224, 174, 174, 224, 174, 178, 224, 175, 141, 32, 12, 0, 2, 224, 175, 138, 224, 174, 180, 224, 175, 129, 224, 174, 164, 224, 175, 129, 32, 12, 0, 2, 224, 175, 138, 224, 174, 180, 224, 175, 129, 224, 174, 164, 224, 175, 129, 224, 174, 174, 224, 175, 135, 32, 12, 0, 2, 224, 175, 138, 224, 174, 180, 224, 175, 129, 224, 174, 164, 224, 175, 129, 224, 174, 174, 224, 175, 141, 32, 12, 0, 2, 224, 175, 138, 224, 174, 180, 224, 175, 129, 224, 174, 164, 224, 175, 135, 32, 12, 0, 2, 224, 175, 138, 224, 174, 180, 224, 175, 129, 224, 174, 164, 224, 175, 139, 32, 12, 0, 2, 224, 175, 139, 224, 174, 149, 32, 0, 2, 224, 175, 139, 224, 174, 149, 224, 174, 181, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 175, 136, 32, 0, 2, 224, 175, 139, 224, 174, 149, 224, 174, 191, 224, 174, 169, 224, 175, 141, 224, 174, 177, 0, 2, 224, 175, 139, 224, 174, 149, 224, 174, 191, 224, 174, 177, 0, 2, 224, 175, 139, 224, 174, 149, 224, 175, 129, 224, 174, 174, 224, 175, 141, 32, 0, 2, 224, 175, 139, 224, 174, 164, 224, 174, 191, 224, 174, 178, 224, 175, 129, 224, 174, 174, 224, 175, 135, 32, 12, 0, 2, 224, 175, 139, 224, 174, 164, 224, 174, 191, 224, 174, 178, 224, 175, 129, 224, 174, 174, 224, 175, 141, 12, 0, 2, 224, 175, 139, 224, 174, 164, 224, 175, 129, 12, 0, 2, 224, 175, 139, 224, 174, 164, 224, 175, 129, 224, 174, 174, 224, 175, 141, 12, 0, 2, 224, 175, 139, 224, 174, 164, 224, 175, 129, 224, 174, 174, 224, 175, 141, 32, 12, 0, 2, 224, 175, 139, 224, 174, 164, 224, 175, 134, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 190, 224, 174, 174, 224, 175, 141, 32, 0, 2, 224, 175, 139, 224, 174, 164, 224, 175, 135, 32, 12, 0, 2, 224, 175, 139, 224, 174, 164, 224, 175, 139, 32, 12, 0, 2, 224, 175, 139, 224, 174, 169, 32, 0, 2, 224, 175, 139, 224, 174, 169, 224, 174, 164, 224, 175, 129, 32, 0, 2, 224, 175, 139, 224, 174, 169, 224, 174, 190, 0, 2, 224, 175, 139, 224, 174, 169, 224, 175, 141, 224, 174, 177, 12, 0, 2, 224, 175, 139, 224, 174, 175, 224, 174, 191, 224, 174, 176, 224, 175, 129, 0, 2, 224, 175, 139, 224, 174, 175, 224, 175, 141, 0, 2, 224, 175, 139, 224, 174, 178, 32, 0, 2, 224, 175, 139, 224, 174, 178, 224, 174, 149, 224, 175, 141, 32, 0, 2, 224, 175, 139, 224, 174, 178, 224, 174, 154, 224, 175, 141, 32, 0, 2, 224, 175, 139, 224, 174, 178, 224, 174, 164, 224, 175, 141, 32, 0, 2, 224, 175, 139, 224, 174, 178, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 190, 224, 174, 169, 224, 175, 141, 32, 12, 0, 2, 224, 175, 139, 224, 174, 178, 224, 174, 170, 224, 175, 141, 32, 0, 2, 224, 175, 139, 224, 174, 178, 224, 174, 181, 224, 175, 129, 224, 174, 174, 224, 175, 141, 32, 0, 2, 224, 175, 139, 224, 174, 178, 224, 174, 181, 224, 175, 135, 32, 0, 2, 224, 175, 139, 224, 174, 178, 224, 175, 129, 224, 174, 174, 224, 175, 141, 32, 0, 2, 224, 175, 139, 224, 174, 178, 224, 175, 141, 32, 12, 0, 2, 224, 175, 139, 224, 174, 181, 224, 174, 164, 0, 8, 2, 17, 66, 0, 8, 2, 224, 174, 190, 224, 174, 154, 224, 175, 129, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 163, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 163, 224, 175, 141, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 190, 224, 174, 178, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 32, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 174, 224, 175, 141, 32, 18, 81, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 174, 224, 175, 141, 32, 224, 174, 149, 224, 175, 129, 224, 174, 177, 224, 175, 136, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 174, 224, 175, 141, 32, 224, 174, 174, 224, 175, 135, 224, 174, 177, 224, 175, 141, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 174, 224, 175, 141, 32, 224, 174, 174, 224, 175, 135, 224, 174, 177, 224, 175, 141, 224, 174, 170, 224, 174, 159, 224, 175, 141, 224, 174, 159, 32, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 174, 224, 175, 141, 32, 224, 174, 174, 224, 175, 135, 224, 174, 178, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 135, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 174, 176, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 174, 149, 224, 175, 141, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 190, 224, 174, 159, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 174, 190, 224, 174, 170, 224, 174, 191, 224, 174, 183, 224, 175, 135, 224, 174, 149, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 174, 191, 224, 174, 169, 224, 175, 141, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 175, 129, 224, 174, 159, 224, 174, 169, 224, 175, 141, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 175, 129, 224, 174, 174, 224, 175, 141, 32, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 175, 136, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 175, 141, 0, 8, 2, 224, 175, 128, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 175, 136, 0, 8, 2, 224, 175, 128, 224, 174, 159, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 175, 128, 224, 174, 176, 224, 174, 191, 224, 174, 159, 0, 8, 2, 224, 175, 128, 224, 174, 176, 224, 175, 141, 32, 224, 174, 174, 224, 175, 129, 224, 174, 149, 224, 174, 174, 224, 174, 164, 0, 8, 2, 224, 175, 128, 224, 174, 176, 224, 175, 141, 32, 224, 174, 174, 224, 175, 129, 224, 174, 185, 224, 174, 174, 224, 174, 164, 0, 8, 2, 224, 175, 128, 224, 174, 176, 224, 175, 141, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 190, 0, 8, 2, 224, 175, 128, 224, 174, 176, 224, 175, 141, 224, 174, 174, 224, 175, 135, 224, 174, 159, 0, 8, 2, 224, 175, 135, 224, 174, 176, 224, 174, 178, 224, 175, 136, 0, 8, 2, 224, 175, 135, 224, 174, 183, 224, 174, 169, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 175, 138, 224, 174, 174, 224, 175, 141, 224, 174, 174, 224, 174, 169, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 0, 8, 2, 224, 175, 139, 224, 174, 149, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 190, 224, 174, 169, 0, 8, 2, 224, 175, 139, 224, 174, 184, 224, 175, 141, 32, 18, 87, 0, 8, 2, 224, 175, 139, 224, 174, 184, 224, 175, 141, 224, 174, 159, 0, 8, 32, 129, 175, 224, 159, 174, 224, 134, 174, 224, 2, 224, 174, 190, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 175, 135, 0, 8, 32, 129, 175, 224, 159, 174, 224, 190, 174, 224, 175, 174, 224, 136, 175, 224, 179, 174, 224, 191, 174, 224, 181, 174, 224, 2, 224, 174, 190, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 175, 135, 0, 8, 128, 175, 224, 159, 174, 224, 2, 224, 174, 190, 224, 174, 175, 224, 175, 141, 0, 8, 128, 175, 224, 164, 174, 224, 2, 224, 174, 190, 0, 8, 128, 175, 224, 176, 174, 224, 141, 175, 224, 184, 174, 224, 2, 224, 175, 134, 224, 174, 176, 224, 175, 129, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 175, 129, 224, 174, 164, 224, 175, 130, 224, 174, 176, 0, 8, 129, 175, 224, 159, 174, 224, 141, 175, 224, 159, 174, 224, 149, 174, 224, 2, 224, 174, 190, 224, 174, 159, 0, 8, 129, 175, 224, 159, 174, 224, 170, 174, 224, 2, 224, 174, 190, 224, 174, 164, 0, 8, 129, 175, 224, 159, 174, 224, 191, 174, 224, 181, 174, 224, 164, 174, 224, 2, 224, 175, 138, 224, 174, 159, 224, 174, 191, 0, 8, 129, 175, 224, 177, 174, 224, 135, 175, 224, 181, 174, 224, 2, 224, 174, 190, 224, 174, 159, 0, 8, 129, 175, 224, 177, 174, 224, 174, 174, 224, 2, 224, 174, 190, 224, 174, 164, 0, 8, 129, 175, 224, 177, 174, 224, 174, 174, 224, 2, 224, 174, 191, 224, 174, 177, 0, 8, 129, 175, 224, 177, 174, 224, 174, 174, 224, 2, 224, 175, 135, 224, 174, 154, 224, 175, 141, 224, 174, 154, 0, 8, 129, 175, 224, 177, 174, 224, 191, 174, 224, 154, 174, 224, 2, 224, 174, 190, 224, 174, 164, 224, 175, 136, 0, 8, 130, 175, 224, 170, 174, 224, 2, 224, 174, 190, 224, 174, 179, 224, 174, 174, 224, 175, 141, 32, 0, 8, 135, 175, 224, 159, 174, 224, 2, 224, 175, 141, 0, 8, 135, 175, 224, 168, 174, 224, 2, 224, 174, 190, 224, 174, 179, 0, 8, 136, 175, 224, 149, 174, 224, 2, 224, 175, 135, 224, 174, 154, 224, 174, 191, 0, 8, 136, 175, 224, 149, 174, 224, 2, 224, 175, 139, 224, 174, 159, 0, 8, 136, 175, 224, 154, 174, 224, 181, 174, 224, 2, 224, 174, 190, 224, 174, 159, 0, 8, 136, 175, 224, 159, 174, 224, 149, 174, 224, 2, 224, 174, 191, 224, 174, 159, 224, 174, 191, 0, 8, 136, 175, 224, 159, 174, 224, 164, 174, 224, 2, 224, 175, 139, 224, 174, 159, 0, 8, 136, 175, 224, 174, 174, 224, 2, 224, 175, 139, 224, 174, 159, 0, 8, 136, 175, 224, 177, 174, 224, 129, 175, 224, 149, 174, 224, 2, 224, 174, 190, 224, 174, 159, 0, 8, 136, 175, 224, 177, 174, 224, 191, 174, 224, 154, 174, 224, 2, 224, 174, 191, 224, 174, 159, 224, 174, 191, 0, 8, 141, 175, 224, 149, 174, 224, 191, 174, 224, 170, 174, 224, 2, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 12, 0, 8, 141, 175, 224, 163, 174, 224, 128, 175, 224, 181, 174, 224, 2, 224, 175, 139, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 8, 141, 175, 224, 163, 174, 224, 134, 175, 224, 170, 174, 224, 2, 224, 174, 190, 224, 174, 178, 0, 8, 141, 175, 224, 169, 174, 224, 129, 175, 224, 174, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 32, 0, 8, 141, 175, 224, 169, 174, 224, 134, 175, 224, 164, 174, 224, 2, 224, 175, 134, 224, 174, 163, 224, 175, 141, 224, 174, 163, 224, 175, 136, 0, 8, 141, 175, 224, 169, 174, 224, 134, 175, 224, 174, 174, 224, 2, 224, 175, 138, 224, 174, 176, 224, 175, 129, 0, 8, 141, 175, 224, 169, 174, 224, 181, 174, 224, 2, 224, 175, 138, 224, 174, 176, 224, 175, 129, 0, 8, 141, 175, 224, 174, 174, 224, 129, 175, 224, 164, 174, 224, 139, 175, 224, 170, 174, 224, 2, 224, 174, 190, 0, 8, 141, 175, 224, 174, 174, 224, 135, 175, 224, 176, 174, 224, 164, 174, 224, 2, 224, 174, 190, 32, 0, 8, 141, 175, 224, 174, 174, 224, 135, 175, 224, 176, 174, 224, 181, 174, 224, 2, 224, 174, 190, 32, 0, 8, 141, 175, 224, 174, 174, 224, 135, 175, 224, 177, 174, 224, 139, 175, 224, 170, 174, 224, 2, 224, 174, 190, 32, 0, 8, 141, 175, 224, 174, 174, 224, 149, 174, 224, 2, 224, 174, 190, 224, 174, 178, 224, 174, 190, 0, 8, 141, 175, 224, 174, 174, 224, 149, 174, 224, 2, 224, 175, 134, 224, 174, 169, 224, 174, 191, 0, 8, 141, 175, 224, 174, 174, 224, 149, 174, 224, 2, 224, 175, 139, 224, 174, 154, 0, 8, 141, 175, 224, 174, 174, 224, 149, 174, 224, 2, 224, 175, 139, 224, 174, 184, 0, 8, 141, 175, 224, 174, 174, 224, 149, 174, 224, 2, 224, 175, 140, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 8, 141, 175, 224, 174, 174, 224, 164, 174, 224, 141, 175, 224, 164, 174, 224, 154, 174, 224, 2, 224, 175, 139, 224, 174, 159, 0, 8, 141, 175, 224, 174, 174, 224, 178, 174, 224, 2, 224, 175, 130, 224, 174, 176, 0, 8, 141, 175, 224, 174, 174, 224, 178, 174, 224, 129, 175, 224, 170, 174, 224, 2, 224, 175, 134, 224, 174, 175, 224, 174, 176, 0, 8, 141, 175, 224, 174, 174, 224, 178, 174, 224, 190, 174, 224, 178, 174, 224, 139, 175, 224, 149, 174, 224, 2, 224, 175, 130, 224, 174, 176, 0, 8, 141, 175, 224, 174, 174, 224, 180, 174, 224, 170, 174, 224, 2, 224, 175, 138, 224, 174, 176, 224, 175, 129, 224, 174, 179, 0, 8, 141, 175, 224, 174, 174, 224, 190, 174, 224, 149, 174, 224, 2, 224, 175, 139, 224, 174, 154, 224, 174, 191, 224, 174, 183, 224, 174, 169, 0, 8, 141, 175, 224, 174, 174, 224, 190, 174, 224, 149, 174, 224, 2, 224, 175, 140, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 8, 141, 175, 224, 174, 174, 224, 190, 174, 224, 159, 174, 224, 141, 175, 224, 163, 174, 224, 135, 175, 224, 181, 174, 224, 2, 224, 174, 190, 0, 8, 141, 175, 224, 174, 174, 224, 190, 174, 224, 178, 174, 224, 139, 175, 224, 170, 174, 224, 2, 224, 174, 190, 0, 8, 141, 175, 224, 174, 174, 224, 191, 174, 224, 154, 174, 224, 2, 224, 174, 191, 224, 174, 179, 0, 8, 141, 175, 224, 174, 174, 224, 191, 174, 224, 164, 174, 224, 2, 224, 175, 129, 0, 8, 141, 175, 224, 175, 174, 224, 134, 175, 224, 174, 174, 224, 2, 224, 174, 191, 0, 8, 141, 175, 224, 175, 174, 224, 138, 175, 224, 170, 174, 224, 2, 224, 174, 191, 0, 8, 141, 175, 224, 178, 174, 224, 134, 175, 224, 154, 174, 224, 2, 224, 175, 135, 224, 174, 154, 224, 174, 191, 0, 8, 141, 175, 224, 178, 174, 224, 138, 175, 224, 164, 174, 224, 2, 224, 175, 138, 224, 174, 176, 224, 175, 129, 224, 174, 179, 0, 8, 141, 175, 224, 178, 174, 224, 149, 174, 224, 2, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 8, 141, 175, 224, 178, 174, 224, 191, 174, 224, 154, 174, 224, 2, 224, 174, 190, 0, 8, 141, 175, 224, 178, 174, 224, 191, 174, 224, 183, 174, 224, 2, 224, 174, 190, 0, 8, 141, 175, 224, 180, 174, 224, 190, 174, 224, 164, 174, 224, 2, 224, 174, 190, 224, 174, 179, 0, 8, 141, 175, 224, 180, 174, 224, 190, 174, 224, 175, 174, 224, 2, 224, 174, 190, 224, 174, 163, 0, 8, 154, 174, 224, 141, 175, 224, 158, 174, 224, 170, 174, 224, 2, 224, 174, 190, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 0, 8, 159, 174, 224, 141, 175, 224, 159, 174, 224, 170, 174, 224, 2, 224, 174, 190, 224, 174, 159, 0, 8, 159, 174, 224, 141, 175, 224, 159, 174, 224, 170, 174, 224, 2, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 159, 0, 8, 159, 174, 224, 141, 175, 224, 159, 174, 224, 191, 174, 224, 181, 174, 224, 2, 224, 174, 190, 224, 174, 159, 224, 174, 190, 224, 174, 149, 0, 8, 159, 174, 224, 181, 174, 224, 2, 224, 175, 134, 224, 174, 163, 224, 175, 141, 224, 174, 163, 224, 175, 136, 0, 8, 164, 174, 224, 135, 175, 224, 181, 174, 224, 2, 224, 175, 129, 224, 174, 176, 224, 174, 190, 224, 174, 163, 0, 8, 174, 174, 224, 141, 175, 224, 176, 174, 224, 164, 174, 224, 2, 224, 175, 129, 224, 174, 176, 224, 174, 191, 0, 8, 175, 174, 224, 191, 174, 224, 178, 174, 224, 149, 174, 224, 2, 224, 175, 134, 224, 174, 176, 224, 175, 129, 224, 174, 174, 224, 174, 190, 224, 174, 179, 0, 8, 176, 174, 224, 128, 175, 224, 181, 174, 224, 2, 224, 175, 134, 224, 174, 176, 224, 175, 129, 224, 174, 174, 224, 174, 190, 224, 174, 179, 0, 8, 176, 174, 224, 190, 174, 224, 174, 174, 224, 129, 175, 224, 149, 174, 224, 2, 224, 174, 190, 224, 174, 179, 224, 175, 136, 224, 174, 175, 0, 8, 176, 174, 224, 191, 174, 224, 149, 174, 224, 141, 175, 224, 149, 174, 224, 154, 174, 224, 2, 224, 174, 190, 224, 174, 163, 224, 174, 191, 0, 8, 178, 174, 224, 170, 174, 224, 2, 224, 175, 135, 224, 174, 176, 0, 8, 178, 174, 224, 191, 174, 224, 154, 174, 224, 2, 224, 175, 135, 224, 174, 176, 0, 8, 181, 174, 224, 168, 174, 224, 2, 224, 174, 190, 224, 174, 183, 0, 8, 190, 174, 224, 169, 174, 224, 141, 175, 224, 169, 174, 224, 149, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 174, 190, 0, 8, 190, 174, 224, 170, 174, 224, 2, 224, 175, 129, 224, 174, 178, 224, 174, 176, 0, 8, 191, 174, 224, 154, 174, 224, 141, 175, 224, 169, 174, 224, 191, 174, 224, 176, 174, 224, 141, 175, 224, 170, 174, 224, 2, 224, 174, 190, 224, 174, 178, 0, 8, 191, 174, 224, 176, 174, 224, 154, 174, 224, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 0, 8, 191, 174, 224, 176, 174, 224, 154, 174, 224, 2, 224, 174, 190, 224, 174, 176, 0, 8, 191, 174, 224, 177, 174, 224, 134, 175, 224, 181, 174, 224, 2, 224, 174, 191, 224, 174, 159, 224, 174, 191, 0, 8, 191, 174, 224, 180, 174, 224, 181, 174, 224, 2, 224, 174, 190, 224, 174, 159, 0, 8, 191, 174, 224, 183, 174, 224, 191, 174, 224, 176, 174, 224, 2, 224, 174, 191, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 224, 174, 191, 1, 139, 175, 224, 176, 174, 224, 143, 174, 224, 2, 224, 174, 179, 224, 175, 135, 224, 174, 169, 0, 224, 174, 191, 1, 141, 175, 224, 159, 174, 224, 137, 174, 224, 2, 224, 174, 176, 224, 174, 149, 224, 174, 190, 224, 174, 176, 0, 224, 174, 191, 1, 141, 175, 224, 170, 174, 224, 129, 175, 224, 154, 174, 224, 176, 174, 224, 133, 174, 224, 2, 224, 174, 176, 224, 174, 164, 224, 174, 191, 224, 174, 168, 224, 174, 191, 224, 174, 164, 224, 174, 191, 0, 224, 174, 191, 1, 141, 175, 224, 170, 174, 224, 156, 174, 224, 190, 174, 224, 176, 174, 224, 2, 224, 174, 176, 224, 174, 164, 224, 174, 191, 224, 174, 168, 224, 174, 191, 224, 174, 164, 224, 174, 191, 0, 224, 174, 191, 1, 141, 175, 224, 170, 174, 224, 164, 174, 224, 141, 175, 224, 168, 174, 224, 18, 68, 2, 224, 174, 176, 224, 174, 179, 224, 174, 175, 0, 224, 174, 191, 1, 141, 175, 224, 170, 174, 224, 164, 174, 224, 141, 175, 224, 168, 174, 224, 18, 68, 2, 224, 174, 176, 224, 174, 190, 224, 174, 175, 0, 224, 174, 191, 1, 141, 175, 224, 170, 174, 224, 169, 174, 224, 156, 174, 224, 139, 175, 224, 170, 174, 224, 2, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 174, 176, 0, 224, 174, 191, 1, 141, 175, 224, 183, 174, 224, 129, 175, 224, 164, 174, 224, 2, 224, 174, 176, 224, 174, 175, 224, 175, 139, 224, 174, 149, 0, 224, 174, 191, 2, 224, 174, 176, 224, 174, 190, 224, 174, 175, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 149, 224, 174, 159, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 149, 224, 174, 178, 224, 174, 190, 224, 174, 164, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 149, 224, 174, 190, 224, 174, 154, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 149, 224, 174, 190, 224, 174, 176, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 149, 224, 175, 141, 224, 174, 158, 224, 175, 136, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 154, 224, 174, 153, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 154, 224, 174, 169, 224, 175, 141, 224, 174, 168, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 154, 224, 174, 169, 224, 175, 141, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 154, 224, 174, 181, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 154, 224, 174, 190, 224, 174, 164, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 154, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 191, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 154, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 154, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 154, 224, 175, 129, 224, 174, 176, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 174, 169, 224, 175, 136, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 174, 190, 224, 174, 176, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 174, 191, 224, 174, 169, 224, 175, 136, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 156, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 163, 224, 174, 181, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 163, 224, 174, 190, 224, 174, 170, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 164, 224, 174, 149, 224, 175, 141, 224, 174, 183, 224, 174, 163, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 164, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 174, 163, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 164, 224, 174, 174, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 164, 224, 174, 190, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 164, 224, 174, 190, 224, 174, 170, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 164, 224, 174, 191, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 164, 224, 175, 128, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 164, 224, 175, 135, 224, 174, 154, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 164, 224, 175, 135, 224, 174, 183, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 164, 224, 175, 139, 224, 174, 183, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 175, 224, 175, 135, 224, 174, 149, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 169, 224, 174, 190, 224, 174, 170, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 170, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 174, 224, 174, 190, 224, 174, 163, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 174, 224, 174, 190, 224, 174, 164, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 174, 224, 174, 190, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 174, 224, 175, 129, 224, 174, 149, 224, 174, 176, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 174, 224, 175, 139, 224, 174, 183, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 175, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 175, 224, 174, 190, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 175, 224, 175, 139, 224, 174, 149, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 175, 224, 175, 139, 224, 174, 154, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 175, 224, 175, 139, 224, 174, 156, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 178, 224, 174, 175, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 179, 224, 174, 175, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 181, 224, 174, 190, 224, 174, 149, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 181, 224, 175, 128, 224, 174, 163, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 181, 224, 175, 128, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 181, 224, 175, 135, 224, 174, 154, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 181, 224, 175, 135, 224, 174, 154, 224, 174, 191, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 183, 224, 175, 141, 224, 174, 159, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 184, 224, 174, 190, 224, 174, 164, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 184, 224, 175, 141, 224, 174, 164, 224, 174, 190, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 185, 224, 174, 178, 224, 174, 190, 224, 174, 164, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 149, 224, 174, 190, 224, 174, 176, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 149, 224, 174, 191, 224, 174, 176, 224, 175, 129, 224, 174, 164, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 163, 32, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 163, 224, 174, 164, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 163, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 163, 224, 174, 191, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 164, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 175, 224, 174, 153, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 175, 224, 174, 164, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 175, 224, 174, 174, 224, 175, 141, 32, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 170, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 174, 224, 174, 191, 224, 174, 184, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 164, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 164, 224, 174, 191, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 175, 139, 224, 174, 176, 224, 174, 191, 224, 174, 175, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 174, 224, 174, 191, 224, 174, 175, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 174, 164, 224, 174, 176, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 159, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 174, 174, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 174, 176, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 174, 190, 32, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 174, 190, 224, 174, 174, 224, 174, 163, 224, 174, 191, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 174, 190, 224, 174, 181, 224, 174, 191, 224, 174, 159, 224, 174, 174, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 174, 190, 224, 174, 181, 224, 174, 191, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 174, 190, 224, 174, 181, 224, 175, 129, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 174, 190, 224, 174, 181, 224, 175, 136, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 135, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 139, 224, 174, 149, 224, 174, 191, 224, 174, 164, 224, 174, 176, 0, 224, 174, 191, 8, 2, 224, 174, 179, 224, 174, 184, 0, 224, 174, 191, 8, 2, 224, 174, 179, 224, 174, 184, 224, 175, 141, 32, 0, 224, 174, 191, 8, 2, 224, 174, 179, 224, 174, 190, 0, 224, 174, 191, 8, 2, 224, 174, 179, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 170, 224, 174, 190, 224, 174, 176, 0, 224, 174, 191, 8, 2, 224, 174, 179, 224, 175, 128, 224, 174, 184, 0, 224, 174, 191, 8, 2, 224, 174, 179, 224, 175, 135, 0, 224, 174, 191, 8, 128, 175, 224, 176, 174, 224, 141, 175, 224, 184, 174, 224, 2, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 174, 190, 0, 224, 174, 191, 8, 141, 175, 224, 170, 174, 224, 169, 174, 224, 190, 174, 224, 164, 174, 224, 2, 224, 174, 176, 224, 174, 170, 0, 224, 174, 191, 8, 141, 175, 224, 170, 174, 224, 174, 174, 224, 141, 175, 224, 176, 174, 224, 164, 174, 224, 2, 224, 174, 176, 224, 174, 170, 0, 224, 174, 191, 8, 141, 175, 224, 170, 174, 224, 176, 174, 224, 181, 174, 224, 2, 224, 174, 176, 18, 69, 224, 174, 190, 224, 174, 164, 0, 224, 174, 191, 8, 141, 175, 224, 170, 174, 224, 190, 174, 224, 18, 71, 174, 174, 224, 2, 224, 174, 176, 224, 174, 170, 0, 224, 175, 129, 8, 2, 224, 174, 176, 224, 175, 139, 224, 174, 149, 224, 174, 191, 224, 174, 164, 0, 224, 175, 129, 8, 2, 224, 174, 176, 224, 175, 139, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 190, 224, 174, 169, 0, 224, 175, 129, 8, 2, 224, 174, 179, 224, 175, 129, 224, 174, 159, 224, 175, 139, 224, 174, 169, 224, 174, 191, 224, 174, 175, 0, 224, 175, 141, 1, 139, 175, 224, 176, 174, 224, 143, 174, 224, 2, 224, 174, 179, 224, 175, 135, 224, 174, 169, 0, 224, 175, 141, 1, 141, 175, 224, 174, 174, 224, 135, 174, 224, 2, 224, 174, 176, 224, 175, 134, 224, 174, 184, 0, 224, 175, 141, 2, 32, 224, 174, 170, 0, 224, 175, 141, 2, 224, 174, 170, 0, 224, 175, 141, 2, 224, 174, 184, 0, 224, 175, 141, 8, 128, 175, 224, 176, 174, 224, 141, 175, 224, 184, 174, 224, 2, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 174, 190, 0, 224, 175, 141, 8, 129, 175, 224, 154, 174, 224, 2, 224, 174, 176, 224, 175, 128, 224, 174, 174, 0, 224, 175, 141, 8, 135, 175, 224, 149, 174, 224, 2, 224, 174, 174, 224, 174, 190, 224, 174, 176, 224, 174, 191, 0, 224, 175, 141, 8, 139, 175, 224, 170, 174, 224, 0, 224, 175, 141, 8, 141, 175, 224, 174, 174, 224, 149, 174, 224, 2, 224, 174, 176, 224, 175, 134, 224, 174, 184, 0, 224, 175, 141, 8, 149, 174, 224, 190, 174, 224, 178, 174, 224, 0, 224, 175, 141, 8, 190, 174, 224, 159, 174, 224, 141, 175, 224, 149, 174, 224, 141, 175, 224, 184, 174, 224, 134, 175, 224, 159, 174, 224, 0, 224, 175, 141, 8, 190, 174, 224, 174, 174, 224, 2, 224, 174, 179, 0, 224, 174, 191, 224, 174, 176, 1, 141, 175, 224, 184, 174, 224, 141, 175, 224, 149, 174, 224, 142, 174, 224, 2, 224, 174, 184, 3, 48, 34, 36, 0, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 169, 224, 175, 141, 224, 174, 154, 224, 174, 191, 224, 174, 170, 8, 2, 224, 174, 190, 224, 174, 178, 3, 48, 34, 37, 50, 89, 37, 48, 0, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 174, 153, 224, 175, 141, 224, 174, 149, 8, 2, 224, 174, 190, 3, 48, 34, 37, 57, 109, 68, 49, 0, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 163, 224, 175, 141, 224, 174, 159, 8, 2, 224, 174, 176, 3, 48, 34, 37, 66, 140, 109, 0, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 163, 224, 175, 141, 224, 174, 159, 8, 3, 48, 34, 37, 66, 140, 149, 0, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 159, 8, 2, 224, 175, 139, 224, 174, 176, 224, 174, 191, 224, 174, 175, 3, 48, 34, 37, 140, 0, 4, 224, 175, 129, 224, 174, 176, 224, 174, 131, 224, 174, 170, 8, 2, 18, 69, 224, 174, 176, 3, 48, 34, 39, 83, 109, 0, 224, 175, 129, 224, 174, 176, 224, 174, 170, 8, 2, 18, 69, 224, 174, 176, 0, 224, 175, 129, 224, 174, 176, 224, 174, 170, 224, 175, 138, 8, 2, 224, 174, 154, 224, 174, 176, 0, 224, 175, 129, 224, 174, 176, 224, 175, 138, 224, 174, 170, 8, 2, 224, 174, 154, 224, 174, 176, 0, 224, 175, 129, 224, 174, 176, 224, 175, 138, 224, 174, 170, 224, 175, 138, 8, 2, 224, 174, 154, 224, 174, 176, 0, 224, 175, 141, 224, 174, 176, 224, 174, 170, 224, 175, 138, 8, 2, 224, 174, 154, 224, 174, 176, 0, 224, 175, 141, 224, 174, 176, 224, 175, 138, 224, 174, 170, 8, 2, 224, 174, 154, 224, 174, 176, 0, 224, 175, 141, 224, 174, 176, 224, 175, 138, 224, 174, 170, 224, 175, 138, 8, 2, 224, 174, 154, 224, 174, 176, 0, 224, 174, 191, 224, 174, 176, 224, 174, 164, 224, 175, 141, 8, 2, 224, 174, 175, 224, 175, 135, 224, 174, 149, 3, 48, 34, 109, 47, 0, 4, 224, 174, 191, 224, 174, 176, 224, 174, 149, 2, 224, 174, 190, 224, 174, 183, 3, 48, 34, 109, 49, 0, 224, 174, 191, 224, 174, 176, 224, 174, 149, 8, 141, 175, 224, 170, 174, 224, 169, 174, 224, 190, 174, 224, 158, 174, 224, 2, 224, 174, 190, 0, 224, 174, 191, 224, 174, 176, 224, 174, 149, 8, 169, 174, 224, 190, 174, 224, 158, 174, 224, 2, 224, 174, 190, 0, 4, 224, 174, 191, 224, 174, 176, 224, 174, 154, 1, 141, 175, 224, 170, 174, 224, 164, 174, 224, 174, 174, 224, 2, 224, 174, 190, 224, 174, 176, 3, 48, 34, 109, 76, 0, 224, 174, 191, 224, 174, 176, 224, 174, 154, 8, 2, 224, 174, 190, 224, 174, 176, 0, 224, 174, 191, 224, 174, 176, 224, 174, 154, 224, 175, 141, 8, 2, 224, 174, 169, 224, 175, 136, 3, 48, 34, 109, 76, 12, 37, 0, 224, 174, 191, 224, 174, 176, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 149, 8, 2, 224, 174, 178, 3, 48, 34, 118, 49, 140, 37, 49, 109, 0, 224, 174, 191, 224, 174, 176, 224, 174, 190, 224, 174, 181, 224, 174, 191, 224, 174, 159, 224, 174, 163, 224, 175, 141, 224, 174, 159, 8, 3, 48, 34, 118, 84, 37, 141, 109, 66, 140, 149, 0, 224, 175, 141, 224, 174, 176, 224, 175, 139, 224, 174, 159, 8, 2, 224, 174, 190, 224, 174, 169, 3, 48, 34, 119, 47, 0, 224, 175, 129, 224, 174, 176, 224, 175, 139, 224, 174, 159, 8, 2, 224, 174, 190, 224, 174, 169, 3, 48, 34, 119, 140, 0, 224, 175, 129, 224, 174, 176, 224, 175, 130, 224, 174, 170, 8, 3, 48, 34, 123, 83, 149, 0, 224, 174, 191, 224, 174, 176, 224, 175, 136, 224, 174, 181, 224, 175, 135, 224, 174, 159, 8, 3, 48, 34, 134, 84, 114, 140, 149, 0, 224, 175, 134, 224, 174, 163, 224, 175, 141, 224, 174, 159, 8, 141, 175, 224, 176, 174, 224, 190, 174, 224, 149, 174, 224, 2, 224, 174, 176, 3, 48, 36, 66, 140, 109, 0, 4, 224, 175, 134, 224, 174, 158, 224, 175, 141, 224, 174, 154, 8, 2, 224, 174, 190, 32, 3, 48, 36, 67, 75, 0, 224, 175, 134, 224, 174, 158, 224, 175, 141, 224, 174, 154, 8, 2, 224, 174, 190, 224, 174, 178, 224, 175, 129, 224, 174, 174, 0, 224, 174, 191, 224, 174, 149, 8, 128, 175, 224, 164, 174, 224, 2, 224, 174, 190, 3, 48, 37, 49, 0, 224, 174, 191, 224, 174, 159, 8, 190, 174, 224, 149, 174, 224, 2, 224, 174, 178, 3, 48, 37, 140, 109, 0, 224, 175, 129, 224, 174, 164, 224, 175, 141, 8, 2, 224, 174, 164, 23, 32, 224, 174, 170, 224, 175, 129, 224, 174, 164, 12, 3, 48, 40, 47, 0, 4, 224, 175, 129, 224, 174, 164, 224, 175, 141, 224, 174, 164, 8, 2, 224, 174, 149, 3, 48, 40, 47, 47, 109, 0, 224, 175, 129, 224, 174, 164, 224, 175, 141, 224, 174, 164, 8, 2, 224, 174, 174, 224, 175, 141, 32, 224, 174, 170, 224, 175, 129, 224, 174, 164, 224, 174, 191, 224, 174, 175, 0, 224, 175, 129, 224, 174, 164, 224, 175, 141, 224, 174, 164, 8, 2, 224, 174, 174, 224, 175, 141, 32, 224, 174, 170, 224, 175, 129, 224, 174, 164, 224, 175, 129, 0, 224, 175, 129, 224, 174, 164, 224, 175, 141, 224, 174, 164, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 154, 224, 174, 191, 0, 224, 175, 129, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 174, 224, 175, 141, 224, 174, 170, 8, 2, 224, 175, 129, 224, 174, 164, 3, 48, 40, 47, 47, 109, 65, 48, 0, 4, 224, 175, 141, 224, 174, 170, 224, 174, 191, 1, 18, 68, 2, 224, 174, 176, 224, 174, 149, 224, 174, 190, 224, 174, 176, 3, 48, 48, 0, 224, 175, 141, 224, 174, 170, 224, 174, 191, 1, 18, 68, 2, 224, 174, 176, 224, 174, 181, 224, 174, 190, 224, 174, 149, 0, 224, 175, 141, 224, 174, 170, 224, 174, 191, 1, 149, 174, 224, 133, 174, 224, 2, 224, 174, 176, 224, 174, 181, 224, 174, 190, 224, 174, 149, 0, 224, 175, 141, 224, 174, 170, 224, 174, 191, 1, 149, 174, 224, 191, 174, 224, 164, 174, 224, 133, 174, 224, 2, 224, 174, 176, 224, 174, 154, 224, 174, 153, 224, 175, 141, 224, 174, 149, 0, 224, 175, 141, 224, 174, 170, 224, 174, 191, 1, 154, 174, 224, 135, 175, 224, 164, 174, 224, 2, 224, 174, 176, 224, 174, 183, 224, 175, 141, 224, 174, 159, 0, 224, 175, 141, 224, 174, 170, 224, 174, 191, 1, 164, 174, 224, 141, 175, 224, 164, 174, 224, 176, 174, 224, 135, 174, 224, 2, 224, 174, 176, 224, 174, 181, 224, 174, 190, 224, 174, 149, 0, 224, 175, 141, 224, 174, 170, 224, 174, 191, 8, 164, 174, 224, 141, 175, 224, 164, 174, 224, 176, 174, 224, 2, 224, 174, 176, 224, 174, 181, 224, 174, 190, 224, 174, 149, 0, 224, 175, 141, 224, 174, 170, 224, 174, 191, 8, 169, 174, 224, 174, 174, 224, 2, 224, 174, 176, 224, 174, 181, 224, 174, 190, 224, 174, 149, 0, 224, 175, 141, 224, 174, 170, 224, 174, 191, 8, 178, 174, 224, 156, 174, 224, 2, 224, 174, 176, 224, 174, 181, 224, 174, 190, 224, 174, 149, 0, 224, 175, 141, 224, 174, 170, 224, 174, 191, 8, 178, 174, 224, 191, 174, 224, 168, 174, 224, 2, 224, 174, 176, 224, 174, 170, 224, 175, 129, 0, 224, 175, 141, 224, 174, 170, 224, 174, 191, 8, 181, 174, 224, 164, 174, 224, 190, 174, 224, 175, 174, 224, 2, 224, 174, 176, 224, 174, 149, 224, 174, 190, 224, 174, 154, 0, 224, 175, 141, 224, 174, 170, 224, 174, 191, 8, 181, 174, 224, 191, 174, 224, 154, 174, 224, 2, 224, 174, 176, 224, 174, 149, 224, 174, 190, 0, 224, 175, 141, 224, 174, 170, 224, 174, 191, 8, 191, 174, 224, 18, 75, 146, 174, 224, 2, 224, 174, 176, 224, 174, 181, 224, 174, 190, 224, 174, 149, 0, 224, 175, 141, 224, 174, 170, 224, 174, 191, 8, 191, 174, 224, 163, 174, 224, 174, 174, 224, 2, 224, 174, 176, 224, 174, 181, 224, 174, 190, 0, 224, 175, 141, 224, 174, 170, 224, 174, 191, 8, 191, 174, 224, 164, 174, 224, 168, 174, 224, 2, 224, 174, 176, 224, 174, 181, 224, 174, 190, 224, 174, 149, 0, 224, 175, 141, 224, 174, 170, 224, 174, 191, 8, 191, 174, 224, 179, 174, 224, 134, 175, 224, 181, 174, 224, 2, 224, 174, 176, 224, 174, 149, 224, 174, 190, 224, 174, 176, 0, 224, 175, 141, 224, 174, 149, 8, 190, 174, 224, 170, 174, 224, 2, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 169, 3, 48, 49, 0, 224, 175, 141, 224, 174, 175, 224, 175, 130, 224, 174, 159, 1, 141, 175, 224, 174, 174, 224, 149, 174, 224, 2, 224, 174, 176, 3, 48, 57, 152, 140, 109, 0, 224, 175, 141, 224, 174, 170, 224, 174, 191, 8, 176, 174, 224, 170, 174, 224, 2, 224, 174, 176, 224, 174, 174, 224, 175, 141, 224, 174, 174, 3, 48, 71, 0, 224, 175, 141, 224, 174, 154, 8, 176, 174, 224, 2, 224, 174, 176, 3, 48, 76, 109, 0, 4, 1, 21, 2, 224, 174, 159, 224, 175, 141, 224, 174, 154, 12, 3, 48, 109, 0, 1, 128, 175, 224, 169, 174, 224, 2, 25, 0, 1, 128, 175, 224, 176, 174, 224, 2, 25, 0, 1, 129, 175, 224, 169, 174, 224, 133, 174, 224, 2, 224, 174, 174, 224, 174, 190, 0, 1, 129, 175, 224, 169, 174, 224, 133, 174, 224, 2, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 181, 224, 174, 191, 0, 1, 129, 175, 224, 176, 174, 224, 135, 174, 224, 2, 224, 174, 149, 0, 1, 129, 175, 224, 176, 174, 224, 146, 174, 224, 2, 224, 174, 149, 0, 1, 129, 175, 224, 176, 174, 224, 191, 174, 224, 168, 174, 224, 2, 224, 174, 174, 224, 174, 190, 0, 1, 134, 174, 224, 2, 224, 174, 176, 224, 175, 135, 224, 174, 154, 224, 174, 169, 0, 1, 134, 174, 224, 2, 224, 174, 176, 224, 175, 135, 224, 174, 183, 224, 174, 169, 0, 1, 136, 175, 224, 164, 174, 224, 170, 174, 224, 2, 224, 174, 164, 224, 175, 136, 0, 1, 137, 174, 224, 2, 224, 174, 168, 224, 174, 191, 224, 174, 183, 0, 1, 137, 174, 224, 2, 224, 174, 168, 224, 175, 141, 224, 174, 168, 224, 174, 191, 224, 174, 175, 224, 174, 190, 224, 174, 154, 0, 1, 139, 175, 224, 159, 174, 224, 141, 175, 224, 149, 174, 224, 134, 174, 224, 2, 224, 174, 184, 0, 1, 139, 175, 224, 175, 174, 224, 191, 174, 224, 174, 174, 224, 2, 224, 174, 164, 224, 174, 191, 0, 1, 139, 175, 224, 178, 174, 224, 133, 174, 224, 2, 224, 174, 164, 224, 174, 191, 0, 1, 140, 175, 224, 176, 174, 224, 191, 174, 224, 164, 174, 224, 2, 224, 174, 164, 224, 174, 191, 0, 1, 141, 175, 224, 163, 174, 224, 128, 175, 224, 181, 174, 224, 2, 224, 174, 180, 224, 174, 191, 0, 1, 141, 175, 224, 169, 174, 224, 129, 175, 224, 174, 174, 224, 2, 224, 174, 149, 224, 174, 178, 0, 1, 141, 175, 224, 169, 174, 224, 134, 175, 224, 164, 174, 224, 2, 224, 174, 149, 224, 175, 129, 224, 174, 164, 224, 174, 191, 0, 1, 141, 175, 224, 169, 174, 224, 168, 174, 224, 2, 224, 174, 149, 224, 174, 178, 0, 1, 141, 175, 224, 169, 174, 224, 191, 174, 224, 170, 174, 224, 2, 224, 174, 149, 224, 174, 178, 0, 1, 141, 175, 224, 169, 174, 224, 191, 174, 224, 174, 174, 224, 2, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 12, 0, 1, 141, 175, 224, 170, 174, 224, 0, 1, 141, 175, 224, 174, 174, 224, 176, 174, 224, 149, 174, 224, 2, 224, 174, 159, 0, 1, 141, 175, 224, 174, 174, 224, 176, 174, 224, 149, 174, 224, 2, 224, 174, 177, 224, 175, 141, 0, 1, 141, 175, 224, 178, 174, 224, 133, 174, 224, 2, 224, 174, 164, 224, 175, 141, 0, 1, 141, 175, 224, 178, 174, 224, 133, 174, 224, 2, 224, 174, 174, 0, 1, 141, 175, 224, 178, 174, 224, 149, 174, 224, 2, 224, 174, 169, 224, 174, 190, 0, 1, 147, 174, 224, 2, 224, 174, 169, 0, 1, 149, 174, 224, 2, 25, 0, 1, 159, 174, 224, 181, 174, 224, 2, 224, 174, 149, 224, 175, 129, 224, 174, 164, 224, 174, 191, 0, 1, 159, 174, 224, 181, 174, 224, 2, 224, 174, 180, 0, 1, 164, 174, 224, 0, 1, 174, 174, 224, 0, 1, 174, 174, 224, 2, 25, 0, 1, 176, 174, 224, 128, 175, 224, 181, 174, 224, 2, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 169, 224, 174, 191, 0, 1, 176, 174, 224, 128, 175, 224, 181, 174, 224, 2, 224, 174, 176, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 176, 224, 174, 174, 0, 1, 176, 174, 224, 191, 174, 224, 159, 174, 224, 141, 175, 224, 183, 174, 224, 190, 174, 224, 176, 174, 224, 135, 174, 224, 2, 224, 174, 164, 224, 174, 191, 0, 1, 190, 174, 224, 149, 174, 224, 2, 25, 0, 1, 190, 174, 224, 164, 174, 224, 2, 25, 0, 1, 190, 174, 224, 174, 174, 224, 2, 25, 0, 1, 190, 174, 224, 176, 174, 224, 191, 174, 224, 164, 174, 224, 141, 175, 224, 164, 174, 224, 137, 174, 224, 2, 224, 174, 164, 224, 174, 191, 0, 1, 191, 174, 224, 159, 174, 224, 133, 174, 224, 2, 224, 174, 163, 224, 174, 191, 0, 1, 191, 174, 224, 169, 174, 224, 2, 25, 0, 2, 224, 174, 149, 224, 175, 141, 224, 174, 149, 25, 0, 2, 224, 174, 159, 0, 2, 224, 174, 159, 224, 174, 191, 0, 2, 224, 174, 177, 224, 175, 141, 224, 174, 177, 224, 174, 191, 32, 0, 8, 0, 8, 2, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 169, 32, 0, 8, 2, 224, 174, 175, 224, 174, 164, 224, 175, 141, 224, 174, 164, 32, 0, 8, 2, 224, 174, 175, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 158, 224, 175, 141, 0, 8, 2, 224, 174, 175, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 174, 224, 175, 141, 32, 0, 8, 2, 224, 174, 175, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 164, 0, 8, 2, 224, 174, 175, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 169, 0, 8, 2, 224, 174, 175, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 181, 224, 175, 136, 0, 8, 2, 224, 174, 176, 224, 175, 141, 224, 174, 174, 224, 174, 191, 224, 174, 159, 0, 8, 2, 224, 174, 176, 224, 175, 141, 224, 174, 174, 224, 174, 191, 224, 174, 183, 0, 8, 32, 18, 79, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 179, 0, 8, 32, 18, 79, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 164, 224, 175, 141, 0, 8, 32, 18, 79, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 174, 0, 8, 128, 175, 224, 164, 174, 224, 2, 224, 174, 177, 224, 175, 141, 224, 174, 177, 0, 8, 129, 175, 224, 149, 174, 224, 129, 175, 224, 170, 174, 224, 2, 224, 174, 164, 224, 174, 191, 0, 8, 129, 175, 224, 149, 174, 224, 129, 175, 224, 170, 174, 224, 2, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 136, 0, 8, 129, 175, 224, 159, 174, 224, 130, 175, 224, 174, 174, 224, 2, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 149, 224, 175, 141, 0, 8, 129, 175, 224, 159, 174, 224, 138, 174, 224, 2, 224, 174, 175, 224, 174, 191, 224, 174, 176, 0, 8, 129, 175, 224, 164, 174, 224, 141, 175, 224, 164, 174, 224, 129, 175, 224, 174, 174, 224, 2, 224, 174, 181, 224, 174, 179, 0, 8, 129, 175, 224, 177, 174, 224, 174, 174, 224, 2, 224, 174, 149, 224, 175, 129, 224, 174, 164, 224, 174, 191, 0, 8, 129, 175, 224, 177, 174, 224, 174, 174, 224, 2, 224, 174, 176, 224, 174, 191, 224, 174, 154, 224, 175, 128, 224, 174, 178, 224, 174, 169, 224, 175, 136, 0, 8, 136, 175, 224, 159, 174, 224, 168, 174, 224, 2, 224, 174, 175, 224, 174, 191, 224, 174, 177, 224, 175, 141, 224, 174, 154, 224, 174, 191, 0, 8, 141, 175, 224, 169, 174, 224, 129, 175, 224, 174, 174, 224, 2, 224, 174, 164, 224, 174, 191, 224, 174, 181, 0, 8, 141, 175, 224, 169, 174, 224, 178, 174, 224, 168, 174, 224, 2, 224, 174, 175, 0, 8, 141, 175, 224, 169, 174, 224, 191, 174, 224, 164, 174, 224, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 8, 141, 175, 224, 169, 174, 224, 191, 174, 224, 174, 174, 224, 2, 224, 174, 177, 224, 175, 141, 224, 174, 177, 0, 8, 141, 175, 224, 174, 174, 224, 149, 174, 224, 2, 224, 174, 169, 224, 174, 191, 32, 0, 8, 141, 175, 224, 174, 174, 224, 149, 174, 224, 2, 224, 174, 169, 224, 174, 191, 224, 174, 149, 224, 174, 179, 0, 8, 141, 175, 224, 174, 174, 224, 149, 174, 224, 2, 224, 174, 169, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 8, 141, 175, 224, 174, 174, 224, 149, 174, 224, 2, 224, 174, 169, 224, 174, 191, 224, 174, 175, 0, 8, 141, 175, 224, 174, 174, 224, 149, 174, 224, 2, 224, 174, 178, 224, 175, 141, 0, 8, 141, 175, 224, 174, 174, 224, 170, 174, 224, 2, 224, 174, 176, 224, 175, 141, 32, 0, 8, 141, 175, 224, 176, 174, 224, 190, 174, 224, 149, 174, 224, 2, 224, 174, 176, 224, 175, 135, 224, 174, 183, 224, 174, 169, 0, 8, 141, 175, 224, 176, 174, 224, 191, 174, 224, 179, 174, 224, 129, 175, 224, 149, 174, 224, 2, 224, 174, 164, 224, 174, 169, 0, 8, 141, 175, 224, 178, 174, 224, 149, 174, 224, 2, 224, 174, 164, 224, 174, 176, 224, 175, 129, 0, 8, 141, 175, 224, 178, 174, 224, 190, 174, 224, 149, 174, 224, 2, 224, 174, 164, 224, 174, 191, 0, 8, 141, 175, 224, 178, 174, 224, 190, 174, 224, 149, 174, 224, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 0, 8, 149, 174, 224, 190, 174, 224, 168, 174, 224, 2, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 169, 0, 8, 154, 174, 224, 190, 174, 224, 178, 174, 224, 136, 175, 224, 149, 174, 224, 2, 224, 174, 164, 224, 174, 191, 0, 8, 176, 174, 224, 191, 174, 224, 159, 174, 224, 141, 175, 224, 183, 174, 224, 190, 174, 224, 176, 174, 224, 2, 224, 174, 164, 224, 174, 191, 0, 8, 181, 174, 224, 191, 174, 224, 154, 174, 224, 2, 224, 174, 164, 0, 8, 190, 174, 224, 181, 174, 224, 2, 224, 174, 184, 0, 8, 191, 174, 224, 154, 174, 224, 191, 174, 224, 169, 174, 224, 129, 175, 224, 174, 174, 224, 2, 224, 174, 178, 0, 8, 191, 174, 224, 163, 174, 224, 174, 174, 224, 2, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 181, 0, 8, 191, 174, 224, 178, 174, 224, 146, 174, 224, 2, 224, 174, 176, 224, 174, 170, 224, 175, 141, 0, 8, 191, 174, 224, 179, 174, 224, 146, 174, 224, 2, 224, 174, 176, 224, 174, 170, 224, 175, 141, 0, 8, 191, 174, 224, 183, 174, 224, 191, 174, 224, 176, 174, 224, 2, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 169, 224, 174, 191, 0, 4, 224, 174, 164, 1, 129, 175, 224, 154, 174, 224, 170, 174, 224, 2, 224, 174, 191, 3, 48, 109, 47, 0, 224, 174, 164, 1, 190, 174, 224, 156, 174, 224, 176, 174, 224, 191, 174, 224, 170, 174, 224, 2, 224, 174, 191, 0, 224, 174, 164, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 4, 224, 174, 164, 224, 174, 191, 1, 129, 175, 224, 149, 174, 224, 176, 174, 224, 3, 48, 109, 47, 37, 0, 224, 174, 164, 224, 174, 191, 1, 129, 175, 224, 164, 174, 224, 135, 175, 224, 154, 174, 224, 0, 224, 174, 164, 224, 174, 191, 1, 141, 175, 224, 184, 174, 224, 149, 174, 224, 176, 174, 224, 191, 174, 224, 170, 174, 224, 0, 224, 174, 164, 224, 174, 191, 1, 156, 174, 224, 149, 174, 224, 0, 224, 174, 164, 224, 174, 191, 1, 159, 174, 224, 129, 175, 224, 149, 174, 224, 174, 174, 224, 0, 224, 174, 164, 224, 174, 191, 1, 159, 174, 224, 149, 174, 224, 141, 175, 224, 153, 174, 224, 135, 175, 224, 181, 174, 224, 0, 224, 174, 164, 224, 174, 191, 1, 163, 174, 224, 149, 174, 224, 0, 224, 174, 164, 224, 174, 191, 1, 190, 174, 224, 149, 174, 224, 191, 174, 224, 170, 174, 224, 141, 175, 224, 174, 174, 224, 133, 174, 224, 0, 224, 174, 164, 224, 174, 191, 1, 190, 174, 224, 164, 174, 224, 128, 175, 224, 154, 174, 224, 0, 224, 174, 164, 224, 174, 191, 1, 190, 174, 224, 175, 174, 224, 136, 175, 224, 179, 174, 224, 181, 174, 224, 0, 224, 174, 164, 224, 174, 191, 1, 190, 174, 224, 175, 174, 224, 141, 175, 224, 164, 174, 224, 191, 174, 224, 181, 174, 224, 0, 224, 174, 164, 224, 174, 191, 1, 191, 174, 224, 163, 174, 224, 176, 174, 224, 164, 174, 224, 0, 224, 174, 164, 224, 174, 191, 1, 191, 174, 224, 174, 174, 224, 141, 175, 224, 183, 174, 224, 141, 175, 224, 149, 174, 224, 178, 174, 224, 0, 224, 174, 164, 8, 141, 175, 224, 156, 174, 224, 178, 174, 224, 3, 48, 109, 47, 149, 0, 4, 224, 174, 170, 2, 224, 174, 190, 3, 48, 109, 48, 0, 224, 174, 170, 224, 175, 141, 1, 141, 175, 224, 178, 174, 224, 133, 174, 224, 0, 224, 174, 170, 2, 25, 3, 48, 109, 48, 109, 0, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 174, 224, 175, 134, 224, 174, 163, 224, 175, 141, 224, 174, 159, 1, 133, 174, 224, 3, 48, 118, 34, 65, 36, 50, 140, 149, 0, 224, 174, 190, 224, 174, 170, 2, 224, 174, 190, 3, 48, 118, 48, 0, 224, 174, 190, 224, 174, 170, 2, 25, 3, 48, 118, 48, 109, 0, 224, 174, 190, 224, 174, 175, 224, 174, 191, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 175, 141, 224, 174, 174, 224, 175, 134, 224, 174, 163, 224, 175, 141, 224, 174, 159, 1, 133, 174, 224, 3, 48, 118, 57, 37, 66, 140, 65, 36, 50, 140, 149, 0, 4, 224, 174, 190, 224, 174, 163, 224, 174, 191, 224, 174, 149, 224, 174, 191, 8, 2, 224, 174, 176, 3, 48, 118, 66, 37, 81, 0, 224, 174, 190, 224, 174, 163, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 8, 2, 224, 174, 176, 0, 4, 224, 174, 190, 224, 174, 170, 8, 2, 224, 174, 153, 224, 175, 141, 3, 48, 118, 71, 109, 0, 224, 174, 190, 224, 174, 170, 8, 2, 224, 174, 164, 224, 175, 141, 0, 224, 174, 190, 224, 174, 170, 8, 2, 224, 174, 168, 224, 174, 190, 224, 174, 154, 0, 224, 174, 190, 224, 174, 170, 8, 2, 224, 174, 174, 0, 224, 174, 190, 224, 174, 170, 224, 174, 181, 224, 174, 191, 224, 174, 174, 224, 175, 139, 224, 174, 154, 224, 174, 169, 8, 3, 48, 118, 71, 109, 84, 37, 65, 119, 76, 109, 0, 224, 174, 190, 224, 174, 154, 224, 174, 191, 224, 174, 159, 8, 134, 175, 224, 159, 174, 224, 3, 48, 118, 89, 37, 140, 149, 0, 224, 174, 190, 224, 174, 154, 224, 175, 129, 224, 174, 170, 8, 2, 224, 174, 164, 3, 48, 118, 89, 122, 48, 109, 0, 224, 175, 139, 224, 174, 176, 224, 175, 141, 224, 174, 159, 1, 141, 175, 224, 176, 174, 224, 143, 174, 224, 3, 48, 119, 34, 140, 149, 0, 224, 175, 141, 224, 174, 159, 1, 21, 3, 48, 140, 149, 0, 4, 1, 18, 67, 3, 48, 149, 0, 1, 136, 175, 224, 159, 174, 224, 168, 174, 224, 0, 1, 141, 175, 224, 174, 174, 224, 191, 174, 224, 178, 174, 224, 146, 174, 224, 0, 1, 141, 175, 224, 176, 174, 224, 159, 174, 224, 135, 174, 224, 0, 1, 141, 175, 224, 178, 174, 224, 133, 174, 224, 2, 32, 0, 1, 141, 175, 224, 178, 174, 224, 149, 174, 224, 141, 175, 224, 153, 174, 224, 154, 174, 224, 0, 8, 128, 175, 224, 164, 174, 224, 176, 174, 224, 191, 174, 224, 170, 174, 224, 0, 8, 136, 175, 224, 178, 174, 224, 191, 174, 224, 168, 174, 224, 0, 8, 141, 175, 224, 169, 174, 224, 175, 174, 224, 170, 174, 224, 0, 8, 141, 175, 224, 174, 174, 224, 135, 175, 224, 149, 174, 224, 0, 8, 141, 175, 224, 178, 174, 224, 138, 175, 224, 154, 174, 224, 0, 8, 141, 175, 224, 178, 174, 224, 149, 174, 224, 191, 174, 224, 181, 174, 224, 0, 8, 141, 175, 224, 178, 174, 224, 175, 174, 224, 134, 175, 224, 154, 174, 224, 0, 4, 1, 32, 46, 32, 191, 174, 224, 170, 174, 224, 2, 224, 174, 191, 32, 46, 32, 224, 174, 154, 224, 174, 191, 3, 71, 0, 1, 32, 129, 175, 224, 164, 174, 224, 141, 175, 224, 168, 174, 224, 129, 175, 224, 176, 174, 224, 191, 174, 224, 178, 174, 224, 191, 174, 224, 164, 174, 224, 141, 175, 224, 164, 174, 224, 149, 174, 224, 129, 175, 224, 174, 174, 224, 2, 224, 174, 190, 224, 174, 181, 0, 1, 32, 129, 175, 224, 164, 174, 224, 141, 175, 224, 168, 174, 224, 129, 175, 224, 176, 174, 224, 191, 174, 224, 178, 174, 224, 191, 174, 224, 179, 174, 224, 149, 174, 224, 141, 175, 224, 153, 174, 224, 149, 174, 224, 129, 175, 224, 174, 174, 224, 2, 224, 174, 190, 224, 174, 181, 0, 1, 32, 141, 175, 224, 169, 174, 224, 191, 174, 224, 179, 174, 224, 149, 174, 224, 141, 175, 224, 153, 174, 224, 149, 174, 224, 129, 175, 224, 174, 174, 224, 2, 224, 174, 190, 224, 174, 181, 0, 1, 32, 164, 174, 224, 141, 175, 224, 168, 174, 224, 129, 175, 224, 176, 174, 224, 191, 174, 224, 178, 174, 224, 191, 174, 224, 164, 174, 224, 141, 175, 224, 164, 174, 224, 149, 174, 224, 129, 175, 224, 174, 174, 224, 2, 224, 174, 190, 224, 174, 181, 0, 1, 32, 164, 174, 224, 141, 175, 224, 168, 174, 224, 129, 175, 224, 176, 174, 224, 191, 174, 224, 178, 174, 224, 191, 174, 224, 179, 174, 224, 149, 174, 224, 141, 175, 224, 153, 174, 224, 149, 174, 224, 129, 175, 224, 174, 174, 224, 2, 224, 174, 190, 224, 174, 181, 0, 1, 32, 175, 174, 224, 136, 175, 224, 159, 174, 224, 129, 175, 224, 169, 174, 224, 191, 174, 224, 164, 174, 224, 141, 175, 224, 164, 174, 224, 149, 174, 224, 129, 175, 224, 174, 174, 224, 2, 224, 174, 190, 224, 174, 181, 0, 1, 32, 175, 174, 224, 136, 175, 224, 159, 174, 224, 129, 175, 224, 169, 174, 224, 191, 174, 224, 179, 174, 224, 149, 174, 224, 141, 175, 224, 153, 174, 224, 149, 174, 224, 129, 175, 224, 174, 174, 224, 2, 224, 174, 190, 224, 174, 181, 0, 1, 128, 175, 224, 154, 174, 224, 149, 174, 224, 141, 175, 224, 153, 174, 224, 176, 174, 224, 129, 175, 224, 181, 174, 224, 133, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 0, 1, 128, 175, 224, 154, 174, 224, 149, 174, 224, 141, 175, 224, 153, 174, 224, 176, 174, 224, 148, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 0, 1, 133, 174, 224, 2, 224, 175, 130, 224, 174, 176, 224, 175, 141, 224, 174, 181, 0, 1, 141, 175, 224, 169, 174, 224, 133, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 0, 1, 141, 175, 224, 169, 174, 224, 135, 174, 224, 2, 224, 175, 129, 224, 174, 177, 0, 1, 141, 175, 224, 170, 174, 224, 191, 174, 224, 176, 174, 224, 191, 174, 224, 164, 174, 224, 137, 174, 224, 2, 224, 174, 190, 224, 174, 149, 0, 1, 141, 175, 224, 174, 174, 224, 2, 17, 66, 224, 174, 159, 0, 1, 141, 175, 224, 174, 174, 224, 2, 224, 174, 190, 0, 1, 141, 175, 224, 174, 174, 224, 2, 224, 174, 190, 224, 174, 179, 224, 175, 136, 224, 174, 175, 0, 1, 141, 175, 224, 174, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 32, 0, 1, 141, 175, 224, 174, 174, 224, 2, 224, 175, 129, 224, 174, 176, 224, 174, 190, 0, 1, 141, 175, 224, 174, 174, 224, 2, 224, 175, 129, 224, 174, 176, 224, 174, 191, 0, 1, 141, 175, 224, 174, 174, 224, 2, 224, 175, 130, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 174, 191, 0, 1, 141, 175, 224, 174, 174, 224, 2, 224, 175, 130, 224, 174, 176, 0, 1, 141, 175, 224, 174, 174, 224, 2, 224, 175, 135, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 175, 136, 0, 1, 141, 175, 224, 174, 174, 224, 146, 174, 224, 2, 224, 175, 139, 224, 174, 164, 224, 175, 129, 224, 174, 174, 224, 175, 141, 0, 1, 141, 175, 224, 174, 174, 224, 191, 174, 224, 164, 174, 224, 141, 175, 224, 164, 174, 224, 133, 174, 224, 2, 224, 175, 135, 224, 174, 176, 224, 175, 141, 0, 1, 141, 175, 224, 176, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 32, 0, 1, 141, 175, 224, 177, 174, 224, 164, 174, 224, 129, 175, 224, 174, 174, 224, 2, 224, 174, 190, 224, 174, 149, 0, 1, 141, 175, 224, 177, 174, 224, 175, 174, 224, 135, 174, 224, 2, 224, 174, 191, 224, 174, 175, 224, 174, 178, 0, 1, 141, 175, 224, 183, 174, 224, 129, 175, 224, 149, 174, 224, 2, 224, 175, 129, 0, 1, 149, 174, 224, 129, 175, 224, 174, 174, 224, 2, 224, 174, 190, 224, 174, 181, 0, 1, 149, 174, 224, 141, 175, 224, 149, 174, 224, 18, 68, 2, 224, 174, 190, 224, 174, 178, 224, 174, 191, 0, 1, 156, 174, 224, 190, 174, 224, 176, 174, 224, 2, 224, 175, 139, 224, 174, 149, 0, 1, 164, 174, 224, 2, 17, 66, 0, 1, 174, 174, 224, 2, 17, 66, 0, 1, 174, 174, 224, 190, 174, 224, 176, 174, 224, 2, 224, 174, 190, 224, 174, 163, 0, 1, 190, 174, 224, 149, 174, 224, 141, 175, 224, 153, 174, 224, 176, 174, 224, 148, 174, 224, 2, 224, 174, 190, 224, 174, 164, 0, 1, 190, 174, 224, 149, 174, 224, 141, 175, 224, 153, 174, 224, 176, 174, 224, 179, 174, 224, 146, 174, 224, 2, 224, 174, 190, 224, 174, 164, 0, 1, 190, 174, 224, 149, 174, 224, 174, 174, 224, 2, 224, 174, 190, 224, 174, 176, 224, 174, 164, 0, 1, 190, 174, 224, 164, 174, 224, 141, 175, 224, 168, 174, 224, 191, 174, 224, 156, 174, 224, 2, 224, 174, 190, 224, 174, 164, 224, 175, 141, 0, 1, 190, 174, 224, 164, 174, 224, 174, 174, 224, 18, 71, 133, 174, 224, 2, 224, 174, 190, 224, 174, 164, 0, 1, 190, 174, 224, 164, 174, 224, 174, 174, 224, 134, 174, 224, 2, 224, 174, 190, 224, 174, 164, 0, 1, 190, 174, 224, 174, 174, 224, 190, 174, 224, 178, 174, 224, 141, 175, 224, 184, 174, 224, 135, 174, 224, 2, 224, 174, 190, 224, 174, 164, 0, 1, 190, 174, 224, 181, 174, 224, 168, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 32, 0, 2, 17, 66, 0, 8, 2, 17, 66, 28, 17, 12, 0, 8, 2, 18, 72, 224, 174, 178, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 149, 224, 174, 153, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 174, 190, 224, 174, 149, 224, 174, 164, 0, 8, 2, 224, 174, 190, 224, 174, 149, 224, 174, 170, 224, 175, 141, 0, 8, 2, 224, 174, 190, 224, 174, 149, 224, 174, 174, 0, 8, 2, 224, 174, 190, 224, 174, 149, 224, 174, 181, 224, 174, 164, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 149, 224, 175, 128, 224, 174, 176, 224, 174, 164, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 149, 224, 175, 141, 0, 8, 2, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 175, 0, 8, 2, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 184, 0, 8, 2, 224, 174, 190, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 178, 0, 8, 2, 224, 174, 190, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 175, 141, 0, 8, 2, 224, 174, 190, 224, 174, 154, 224, 175, 129, 0, 8, 2, 224, 174, 190, 224, 174, 159, 224, 174, 191, 32, 224, 174, 170, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 159, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 159, 224, 174, 191, 32, 224, 174, 170, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 174, 190, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 0, 8, 2, 224, 174, 190, 224, 174, 159, 224, 174, 191, 224, 174, 175, 224, 175, 136, 0, 8, 2, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 178, 224, 174, 191, 224, 174, 175, 224, 174, 169, 0, 8, 2, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 178, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 178, 224, 175, 129, 224, 174, 149, 224, 175, 141, 0, 8, 2, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 178, 224, 175, 129, 224, 174, 159, 224, 174, 169, 0, 8, 2, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 178, 224, 175, 136, 0, 8, 2, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 149, 224, 174, 179, 0, 8, 2, 224, 174, 190, 224, 174, 163, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 174, 190, 224, 174, 163, 224, 174, 174, 224, 175, 129, 0, 8, 2, 224, 174, 190, 224, 174, 163, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 163, 224, 174, 190, 224, 174, 154, 224, 175, 129, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 163, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 175, 135, 224, 174, 156, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 130, 224, 174, 159, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 159, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 159, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 178, 224, 174, 190, 224, 174, 174, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 181, 224, 174, 190, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 181, 224, 174, 191, 224, 174, 178, 224, 175, 141, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 190, 224, 174, 164, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 169, 224, 175, 141, 224, 174, 177, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 177, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 174, 224, 174, 190, 224, 174, 169, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 174, 224, 174, 190, 224, 174, 177, 224, 175, 129, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 174, 224, 174, 190, 224, 174, 181, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 174, 224, 175, 134, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 174, 224, 175, 141, 32, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 159, 224, 175, 136, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 159, 224, 175, 136, 224, 174, 149, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 159, 224, 175, 136, 224, 174, 175, 224, 175, 129, 224, 174, 174, 224, 175, 134, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 159, 224, 175, 136, 224, 174, 181, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 164, 224, 174, 190, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 164, 224, 175, 136, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 190, 224, 174, 149, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 190, 224, 174, 149, 224, 174, 191, 224, 174, 177, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 190, 224, 174, 149, 224, 175, 129, 224, 174, 174, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 190, 224, 174, 178, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 191, 224, 174, 169, 224, 174, 190, 224, 174, 178, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 191, 224, 174, 177, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 191, 224, 174, 178, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 129, 224, 174, 149, 224, 174, 179, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 129, 224, 174, 149, 224, 175, 141, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 129, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 129, 224, 174, 174, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 129, 224, 174, 179, 224, 175, 141, 224, 174, 179, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 136, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 175, 129, 224, 174, 183, 224, 174, 190, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 175, 141, 224, 174, 175, 224, 174, 164, 224, 175, 136, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 175, 141, 224, 174, 176, 224, 175, 130, 224, 174, 174, 0, 8, 2, 224, 174, 190, 224, 174, 169, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 179, 0, 8, 2, 224, 174, 190, 224, 174, 169, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 174, 190, 224, 174, 169, 224, 174, 174, 0, 8, 2, 224, 174, 190, 224, 174, 169, 224, 174, 174, 224, 175, 129, 0, 8, 2, 224, 174, 190, 224, 174, 169, 224, 174, 176, 224, 175, 141, 224, 174, 156, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 169, 224, 174, 190, 224, 174, 154, 224, 175, 129, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 169, 224, 175, 129, 0, 8, 2, 224, 174, 190, 224, 174, 169, 224, 175, 134, 224, 174, 159, 224, 175, 141, 0, 8, 2, 224, 174, 190, 224, 174, 170, 224, 174, 191, 224, 174, 178, 224, 175, 139, 224, 174, 169, 0, 8, 2, 224, 174, 190, 224, 174, 170, 224, 175, 129, 224, 174, 181, 0, 8, 2, 224, 174, 190, 224, 174, 174, 224, 174, 190, 224, 174, 181, 0, 8, 2, 224, 174, 190, 224, 174, 174, 224, 174, 191, 224, 174, 169, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 175, 135, 0, 8, 2, 224, 174, 190, 224, 174, 175, 224, 175, 141, 224, 174, 178, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 179, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 174, 164, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 174, 164, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 174, 174, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 174, 181, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 174, 190, 224, 174, 174, 224, 175, 129, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 190, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 174, 191, 224, 174, 184, 224, 175, 141, 224, 174, 159, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 175, 141, 18, 69, 224, 174, 178, 224, 175, 139, 224, 174, 169, 224, 174, 190, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 149, 224, 174, 181, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 159, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 170, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 178, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 174, 149, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 174, 154, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 174, 164, 224, 174, 163, 224, 175, 141, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 174, 169, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 190, 224, 174, 159, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 174, 174, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 174, 174, 224, 175, 129, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 174, 174, 224, 175, 141, 224, 174, 174, 224, 174, 190, 224, 174, 179, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 174, 175, 224, 175, 141, 224, 174, 175, 224, 174, 190, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 174, 183, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 174, 190, 224, 174, 154, 224, 175, 130, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 174, 190, 224, 174, 156, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 174, 190, 224, 174, 174, 224, 174, 163, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 174, 190, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 174, 190, 224, 174, 179, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 174, 190, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 174, 191, 224, 174, 149, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 174, 190, 224, 174, 181, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 174, 191, 224, 174, 175, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 174, 191, 224, 174, 181, 224, 175, 129, 224, 174, 159, 224, 175, 141, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 175, 129, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 177, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 175, 129, 224, 174, 154, 224, 174, 190, 224, 174, 174, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 175, 129, 224, 174, 154, 224, 175, 129, 224, 174, 181, 224, 174, 190, 224, 174, 174, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 175, 129, 224, 174, 174, 224, 174, 149, 224, 175, 135, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 175, 129, 224, 174, 181, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 175, 135, 32, 18, 90, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 175, 141, 32, 224, 174, 164, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 176, 224, 175, 135, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 175, 141, 224, 174, 175, 0, 8, 2, 224, 174, 190, 224, 174, 178, 224, 175, 141, 224, 174, 184, 0, 8, 2, 224, 174, 190, 224, 174, 181, 224, 174, 169, 224, 174, 190, 0, 8, 2, 224, 174, 190, 224, 174, 181, 224, 174, 169, 224, 175, 136, 0, 8, 2, 224, 174, 190, 224, 174, 181, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 159, 0, 8, 2, 224, 174, 190, 224, 174, 181, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 178, 0, 8, 2, 224, 174, 190, 224, 174, 181, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 181, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 178, 0, 8, 2, 224, 174, 190, 224, 174, 181, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 169, 224, 175, 141, 224, 174, 177, 0, 8, 2, 224, 174, 190, 224, 174, 181, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 177, 0, 8, 2, 224, 174, 190, 224, 174, 181, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 174, 224, 174, 190, 224, 174, 177, 0, 8, 2, 224, 174, 190, 224, 174, 181, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 174, 224, 175, 134, 0, 8, 2, 224, 174, 190, 224, 174, 181, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 175, 139, 224, 174, 164, 0, 8, 2, 224, 174, 190, 224, 174, 181, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 174, 190, 224, 174, 181, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 164, 0, 8, 2, 224, 174, 190, 224, 174, 181, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 164, 224, 174, 190, 0, 8, 2, 224, 174, 190, 224, 174, 181, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 164, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 181, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 164, 224, 175, 129, 0, 8, 2, 224, 174, 190, 224, 174, 181, 224, 175, 135, 224, 174, 175, 0, 8, 2, 224, 174, 190, 224, 174, 181, 224, 175, 141, 224, 174, 168, 224, 174, 149, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 183, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 179, 0, 8, 2, 224, 174, 190, 224, 174, 183, 224, 174, 190, 224, 174, 181, 0, 8, 2, 224, 174, 190, 224, 174, 183, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 174, 190, 224, 174, 183, 224, 175, 136, 0, 8, 2, 224, 174, 190, 224, 174, 183, 224, 175, 141, 224, 174, 175, 0, 8, 2, 224, 174, 190, 224, 174, 184, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 184, 224, 175, 141, 224, 174, 149, 224, 174, 176, 0, 8, 2, 224, 174, 190, 224, 174, 184, 224, 175, 141, 224, 174, 149, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 184, 224, 175, 141, 224, 174, 159, 224, 174, 169, 0, 8, 2, 224, 174, 190, 224, 174, 184, 224, 175, 141, 224, 174, 174, 224, 174, 164, 224, 174, 191, 0, 8, 2, 224, 174, 191, 32, 46, 32, 224, 174, 170, 224, 174, 191, 32, 46, 32, 224, 174, 154, 224, 174, 191, 0, 8, 2, 224, 174, 191, 224, 174, 149, 224, 174, 191, 224, 174, 178, 0, 8, 2, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 0, 8, 2, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 183, 224, 175, 129, 0, 8, 2, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 183, 224, 175, 130, 0, 8, 2, 224, 174, 191, 224, 174, 154, 224, 174, 191, 224, 174, 169, 224, 174, 184, 0, 8, 2, 224, 174, 191, 224, 174, 154, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 174, 191, 224, 174, 156, 224, 174, 191, 224, 174, 178, 224, 174, 191, 0, 8, 2, 224, 174, 191, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 175, 129, 0, 8, 2, 224, 174, 191, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 159, 224, 174, 191, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 174, 190, 224, 174, 174, 224, 174, 191, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 32, 224, 174, 178, 224, 175, 135, 224, 174, 159, 224, 174, 169, 0, 8, 2, 224, 174, 191, 224, 174, 170, 224, 174, 191, 224, 174, 154, 224, 174, 191, 0, 8, 2, 224, 174, 191, 224, 174, 174, 224, 175, 141, 224, 174, 170, 0, 8, 2, 224, 174, 191, 224, 174, 175, 224, 174, 176, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 174, 149, 224, 174, 164, 224, 175, 128, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 174, 149, 224, 174, 184, 224, 175, 141, 224, 174, 170, 224, 174, 164, 224, 174, 191, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 174, 174, 224, 175, 141, 224, 174, 174, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 174, 174, 224, 175, 141, 224, 174, 174, 224, 175, 136, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 190, 224, 174, 169, 224, 174, 191, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 174, 190, 224, 174, 163, 224, 174, 191, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 175, 129, 224, 174, 149, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 191, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 175, 129, 224, 174, 149, 224, 174, 168, 224, 174, 179, 0, 8, 2, 224, 174, 191, 224, 174, 176, 224, 175, 129, 224, 174, 183, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 174, 191, 224, 174, 178, 224, 174, 190, 224, 174, 184, 224, 175, 141, 224, 174, 170, 224, 175, 130, 224, 174, 176, 0, 8, 2, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 149, 224, 174, 179, 0, 8, 2, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 159, 224, 174, 170, 224, 175, 141, 0, 8, 2, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 159, 224, 174, 176, 32, 224, 174, 170, 224, 174, 190, 224, 174, 159, 224, 174, 191, 32, 0, 8, 2, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 190, 0, 8, 2, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 191, 0, 8, 2, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 175, 129, 0, 8, 2, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 175, 136, 0, 8, 2, 224, 174, 191, 224, 174, 184, 224, 174, 191, 224, 174, 169, 224, 174, 184, 0, 8, 2, 224, 174, 191, 224, 174, 184, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 174, 191, 224, 174, 184, 224, 175, 141, 224, 174, 149, 224, 174, 159, 224, 175, 141, 0, 8, 2, 224, 174, 191, 224, 174, 184, 224, 175, 141, 224, 174, 149, 224, 175, 134, 224, 174, 159, 224, 175, 141, 0, 8, 2, 224, 174, 191, 224, 174, 184, 224, 175, 141, 224, 174, 149, 224, 175, 139, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 174, 191, 224, 174, 184, 224, 175, 141, 224, 174, 174, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 149, 224, 175, 141, 0, 8, 2, 224, 174, 191, 224, 174, 184, 224, 175, 141, 224, 174, 174, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 190, 0, 8, 2, 224, 174, 191, 224, 174, 184, 224, 175, 141, 224, 174, 178, 224, 174, 176, 224, 174, 191, 0, 8, 2, 224, 174, 191, 224, 174, 184, 224, 175, 141, 224, 174, 181, 224, 174, 190, 224, 174, 184, 0, 8, 2, 224, 175, 128, 224, 174, 149, 224, 174, 190, 224, 174, 176, 0, 8, 2, 224, 175, 128, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 174, 191, 224, 174, 178, 0, 8, 2, 224, 175, 128, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 175, 128, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 175, 129, 224, 174, 178, 0, 8, 2, 224, 175, 128, 224, 174, 156, 0, 8, 2, 224, 175, 128, 224, 174, 156, 224, 174, 191, 224, 174, 153, 0, 8, 2, 224, 175, 128, 224, 174, 159, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 175, 128, 224, 174, 159, 224, 174, 190, 224, 174, 181, 0, 8, 2, 224, 175, 128, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 174, 179, 0, 8, 2, 224, 175, 128, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 159, 224, 175, 136, 0, 8, 2, 224, 175, 128, 224, 174, 159, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 129, 224, 174, 149, 224, 175, 136, 0, 8, 2, 224, 175, 128, 224, 174, 159, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 175, 128, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 184, 0, 8, 2, 224, 175, 128, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 139, 224, 174, 181, 224, 174, 169, 0, 8, 2, 224, 175, 128, 224, 174, 169, 224, 175, 141, 224, 174, 184, 0, 8, 2, 224, 175, 128, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 175, 138, 224, 174, 178, 224, 174, 191, 0, 8, 2, 224, 175, 128, 224, 174, 174, 0, 8, 2, 224, 175, 128, 224, 174, 176, 0, 8, 2, 224, 175, 128, 224, 174, 176, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 191, 0, 8, 2, 224, 175, 128, 224, 174, 176, 224, 174, 190, 224, 174, 174, 224, 174, 163, 224, 174, 176, 0, 8, 2, 224, 175, 128, 224, 174, 176, 224, 175, 139, 0, 8, 2, 224, 175, 128, 224, 174, 176, 224, 175, 141, 224, 174, 170, 224, 174, 190, 224, 174, 178, 0, 8, 2, 224, 175, 128, 224, 174, 183, 224, 175, 141, 224, 174, 174, 0, 8, 2, 224, 175, 128, 224, 174, 185, 224, 174, 190, 224, 174, 176, 0, 8, 2, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 190, 224, 174, 149, 0, 8, 2, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 178, 0, 8, 2, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 134, 224, 174, 169, 224, 175, 141, 224, 174, 177, 0, 8, 2, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 136, 0, 8, 2, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 164, 224, 174, 191, 0, 8, 2, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 178, 0, 8, 2, 224, 175, 129, 224, 174, 156, 0, 8, 2, 224, 175, 129, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 0, 8, 2, 224, 175, 129, 224, 174, 164, 224, 174, 169, 0, 8, 2, 224, 175, 129, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 0, 8, 2, 224, 175, 129, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 154, 224, 174, 190, 224, 174, 178, 224, 174, 191, 0, 8, 2, 224, 175, 129, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 129, 224, 174, 159, 224, 174, 190, 0, 8, 2, 224, 175, 129, 224, 174, 176, 224, 175, 139, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 176, 0, 8, 2, 224, 175, 129, 224, 174, 178, 224, 175, 141, 224, 174, 159, 224, 175, 139, 224, 174, 154, 224, 174, 176, 0, 8, 2, 224, 175, 129, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 159, 224, 175, 141, 0, 8, 2, 224, 175, 129, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 175, 129, 224, 174, 181, 224, 174, 169, 0, 8, 2, 224, 175, 129, 224, 174, 184, 224, 175, 141, 224, 174, 181, 224, 174, 190, 224, 174, 169, 0, 8, 2, 224, 175, 129, 224, 174, 184, 224, 175, 141, 224, 174, 184, 224, 175, 134, 0, 8, 2, 224, 175, 130, 224, 174, 149, 224, 174, 174, 224, 175, 141, 224, 174, 170, 0, 8, 2, 224, 175, 130, 224, 174, 149, 224, 175, 139, 224, 174, 178, 0, 8, 2, 224, 175, 130, 224, 174, 149, 224, 175, 139, 224, 174, 179, 0, 8, 2, 224, 175, 130, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 174, 190, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 191, 0, 8, 2, 224, 175, 130, 224, 174, 159, 224, 175, 141, 224, 174, 184, 0, 8, 2, 224, 175, 130, 224, 174, 164, 224, 174, 149, 224, 174, 163, 0, 8, 2, 224, 175, 130, 224, 174, 164, 224, 174, 149, 224, 174, 163, 224, 174, 153, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 175, 130, 224, 174, 164, 224, 174, 149, 224, 175, 141, 0, 8, 2, 224, 175, 130, 224, 174, 164, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 175, 130, 224, 174, 164, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 175, 130, 224, 174, 164, 224, 174, 170, 224, 174, 190, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 175, 130, 224, 174, 164, 224, 174, 174, 0, 8, 2, 224, 175, 130, 224, 174, 164, 224, 174, 181, 224, 175, 129, 224, 174, 159, 224, 174, 174, 224, 175, 141, 224, 174, 170, 0, 8, 2, 224, 175, 130, 224, 174, 164, 224, 174, 190, 224, 174, 149, 224, 174, 176, 0, 8, 2, 224, 175, 130, 224, 174, 164, 224, 174, 190, 224, 174, 149, 224, 174, 190, 224, 174, 176, 0, 8, 2, 224, 175, 130, 224, 174, 164, 224, 174, 190, 224, 174, 169, 0, 8, 2, 224, 175, 130, 224, 174, 164, 224, 175, 135, 224, 174, 181, 224, 174, 191, 0, 8, 2, 224, 175, 130, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 178, 0, 8, 2, 224, 175, 130, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 129, 224, 174, 149, 224, 174, 179, 0, 8, 2, 224, 175, 130, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 190, 0, 8, 2, 224, 175, 130, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 159, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 175, 130, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 170, 224, 175, 141, 0, 8, 2, 224, 175, 130, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 136, 0, 8, 2, 224, 175, 130, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 174, 179, 0, 8, 2, 224, 175, 130, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 175, 130, 224, 174, 170, 224, 174, 169, 224, 175, 135, 0, 8, 2, 224, 175, 130, 224, 174, 170, 224, 174, 190, 224, 174, 179, 0, 8, 2, 224, 175, 130, 224, 174, 174, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 175, 130, 224, 174, 174, 224, 174, 190, 224, 174, 164, 224, 174, 190, 0, 8, 2, 224, 175, 130, 224, 174, 174, 224, 174, 190, 224, 174, 164, 224, 175, 135, 224, 174, 181, 224, 174, 191, 0, 8, 2, 224, 175, 130, 224, 174, 174, 224, 174, 190, 224, 174, 181, 0, 8, 2, 224, 175, 130, 224, 174, 174, 224, 174, 191, 0, 8, 2, 224, 175, 130, 224, 174, 176, 224, 175, 141, 224, 174, 183, 0, 8, 2, 224, 175, 130, 224, 174, 178, 224, 175, 139, 224, 174, 149, 0, 8, 2, 224, 175, 130, 224, 174, 183, 224, 174, 169, 0, 8, 2, 224, 175, 134, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 179, 224, 175, 130, 224, 174, 176, 0, 8, 2, 224, 175, 134, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 190, 224, 174, 178, 0, 8, 2, 224, 175, 134, 224, 174, 158, 224, 175, 141, 224, 174, 154, 224, 174, 174, 224, 174, 191, 224, 174, 169, 0, 8, 2, 224, 175, 134, 224, 174, 159, 224, 175, 141, 224, 174, 176, 224, 175, 130, 224, 174, 174, 0, 8, 2, 224, 175, 134, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 178, 0, 8, 2, 224, 175, 134, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 149, 224, 175, 139, 224, 174, 184, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 175, 134, 224, 174, 169, 224, 174, 154, 224, 175, 128, 224, 174, 176, 0, 8, 2, 224, 175, 134, 224, 174, 176, 224, 175, 141, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 175, 134, 224, 174, 176, 224, 175, 141, 224, 174, 169, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 183, 224, 174, 190, 0, 8, 2, 224, 175, 134, 224, 174, 176, 224, 175, 141, 224, 174, 169, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 175, 134, 224, 174, 176, 224, 175, 141, 224, 174, 174, 224, 175, 129, 224, 174, 159, 224, 174, 190, 0, 8, 2, 224, 175, 134, 224, 174, 176, 224, 175, 141, 224, 174, 178, 224, 174, 191, 224, 174, 153, 0, 8, 2, 224, 175, 134, 224, 174, 176, 224, 175, 141, 224, 174, 178, 224, 174, 191, 224, 174, 169, 0, 8, 2, 224, 175, 134, 224, 174, 178, 224, 175, 141, 0, 8, 2, 224, 175, 134, 224, 174, 179, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 175, 134, 224, 174, 184, 224, 175, 141, 224, 174, 159, 224, 175, 141, 0, 8, 2, 224, 175, 135, 224, 174, 149, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 175, 135, 224, 174, 149, 224, 174, 174, 0, 8, 2, 224, 175, 135, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 176, 224, 174, 191, 0, 8, 2, 224, 175, 135, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 175, 141, 0, 8, 2, 224, 175, 135, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 174, 178, 224, 174, 176, 0, 8, 2, 224, 175, 135, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 174, 191, 224, 174, 178, 224, 174, 176, 0, 8, 2, 224, 175, 135, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 175, 129, 224, 174, 178, 224, 174, 176, 0, 8, 2, 224, 175, 135, 224, 174, 156, 224, 174, 190, 224, 174, 176, 0, 8, 2, 224, 175, 135, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 176, 224, 174, 191, 0, 8, 2, 224, 175, 135, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 190, 0, 8, 2, 224, 175, 135, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 175, 135, 224, 174, 164, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 175, 135, 224, 174, 164, 224, 174, 174, 224, 174, 191, 0, 8, 2, 224, 175, 135, 224, 174, 164, 224, 174, 174, 224, 175, 129, 0, 8, 2, 224, 175, 135, 224, 174, 164, 224, 174, 178, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 175, 135, 224, 174, 164, 224, 174, 191, 0, 8, 2, 224, 175, 135, 224, 174, 169, 224, 174, 176, 0, 8, 2, 224, 175, 135, 224, 174, 170, 224, 174, 191, 0, 8, 2, 224, 175, 135, 224, 174, 174, 224, 174, 190, 224, 174, 169, 224, 174, 191, 0, 8, 2, 224, 175, 135, 224, 174, 176, 224, 174, 178, 0, 8, 2, 224, 175, 135, 224, 174, 176, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 190, 0, 8, 2, 224, 175, 135, 224, 174, 178, 224, 174, 169, 224, 175, 141, 224, 174, 184, 0, 8, 2, 224, 175, 135, 224, 174, 178, 224, 175, 141, 0, 8, 2, 224, 175, 135, 224, 174, 183, 224, 174, 190, 0, 8, 2, 224, 175, 136, 32, 224, 174, 170, 224, 175, 136, 0, 8, 2, 224, 175, 136, 224, 174, 149, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 0, 8, 2, 224, 175, 136, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 169, 0, 8, 2, 224, 175, 136, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 177, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 175, 136, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 149, 224, 174, 179, 0, 8, 2, 224, 175, 136, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 174, 0, 8, 2, 224, 175, 136, 224, 174, 154, 224, 174, 169, 0, 8, 2, 224, 175, 136, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 175, 136, 224, 174, 169, 224, 174, 190, 224, 174, 149, 0, 8, 2, 224, 175, 136, 224, 174, 169, 224, 174, 190, 224, 174, 174, 224, 174, 191, 0, 8, 2, 224, 175, 136, 224, 174, 170, 224, 174, 191, 224, 174, 179, 0, 8, 2, 224, 175, 136, 224, 174, 176, 224, 174, 169, 0, 8, 2, 224, 175, 136, 224, 174, 176, 224, 174, 181, 0, 8, 2, 224, 175, 136, 224, 174, 176, 224, 174, 190, 224, 174, 149, 224, 174, 191, 0, 8, 2, 224, 175, 138, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 135, 0, 8, 2, 224, 175, 138, 224, 174, 174, 224, 175, 141, 224, 174, 174, 224, 174, 169, 0, 8, 2, 224, 175, 138, 224, 174, 174, 224, 175, 141, 224, 174, 174, 224, 174, 178, 0, 8, 2, 224, 175, 138, 224, 174, 174, 224, 175, 141, 224, 174, 174, 224, 175, 136, 0, 8, 2, 224, 175, 139, 224, 174, 131, 224, 174, 170, 224, 175, 139, 224, 174, 176, 224, 175, 141, 0, 8, 2, 224, 175, 139, 224, 174, 149, 32, 18, 78, 0, 8, 2, 224, 175, 139, 224, 174, 149, 224, 174, 153, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 175, 139, 224, 174, 149, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 175, 139, 224, 174, 149, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 177, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 175, 139, 224, 174, 149, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 178, 0, 8, 2, 224, 175, 139, 224, 174, 149, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 175, 139, 224, 174, 149, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 136, 0, 8, 2, 224, 175, 139, 224, 174, 149, 224, 174, 169, 224, 175, 141, 224, 174, 181, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 190, 0, 8, 2, 224, 175, 139, 224, 174, 149, 224, 174, 176, 0, 8, 2, 224, 175, 139, 224, 174, 149, 224, 174, 191, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 175, 139, 224, 174, 149, 224, 174, 191, 224, 174, 170, 224, 175, 141, 0, 8, 2, 224, 175, 139, 224, 174, 149, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 175, 139, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 190, 0, 8, 2, 224, 175, 139, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 175, 129, 0, 8, 2, 224, 175, 139, 224, 174, 156, 0, 8, 2, 224, 175, 139, 224, 174, 159, 224, 175, 139, 0, 8, 2, 224, 175, 139, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 190, 0, 8, 2, 224, 175, 139, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 191, 0, 8, 2, 224, 175, 139, 224, 174, 164, 224, 174, 149, 224, 174, 169, 0, 8, 2, 224, 175, 139, 224, 174, 164, 224, 174, 149, 224, 174, 176, 0, 8, 2, 224, 175, 139, 224, 174, 164, 224, 174, 169, 0, 8, 2, 224, 175, 139, 224, 174, 164, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 175, 139, 224, 174, 164, 224, 174, 191, 224, 174, 154, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 175, 139, 224, 174, 164, 224, 174, 191, 224, 174, 154, 224, 174, 164, 224, 175, 141, 224, 174, 181, 0, 8, 2, 224, 175, 139, 224, 174, 164, 224, 174, 191, 224, 174, 164, 224, 174, 176, 224, 175, 141, 224, 174, 174, 0, 8, 2, 224, 175, 139, 224, 174, 164, 224, 174, 191, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 175, 139, 224, 174, 164, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 0, 8, 2, 224, 175, 139, 224, 174, 164, 224, 174, 191, 224, 174, 175, 224, 174, 191, 0, 8, 2, 224, 175, 139, 224, 174, 164, 224, 174, 191, 224, 174, 175, 224, 175, 136, 0, 8, 2, 224, 175, 139, 224, 174, 164, 224, 175, 136, 0, 8, 2, 224, 175, 139, 224, 174, 169, 224, 174, 191, 224, 174, 175, 224, 174, 190, 224, 174, 149, 0, 8, 2, 224, 175, 139, 224, 174, 169, 224, 174, 191, 224, 174, 175, 224, 175, 136, 0, 8, 2, 224, 175, 139, 224, 174, 169, 224, 175, 141, 224, 174, 184, 224, 175, 141, 224, 174, 178, 224, 175, 135, 0, 8, 2, 224, 175, 139, 224, 174, 176, 224, 174, 159, 224, 174, 191, 0, 8, 2, 224, 175, 139, 224, 174, 176, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 190, 224, 174, 174, 224, 174, 178, 224, 174, 190, 0, 8, 2, 224, 175, 139, 224, 174, 176, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 164, 0, 8, 2, 224, 175, 139, 224, 174, 176, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 174, 0, 8, 2, 224, 175, 139, 224, 174, 176, 224, 175, 129, 224, 174, 174, 224, 175, 141, 32, 224, 174, 133, 224, 174, 159, 224, 174, 191, 0, 8, 2, 224, 175, 139, 224, 174, 176, 224, 175, 141, 32, 224, 174, 133, 224, 174, 159, 224, 174, 191, 0, 8, 2, 224, 175, 139, 224, 174, 176, 224, 175, 141, 224, 174, 164, 224, 174, 190, 224, 174, 169, 224, 175, 141, 32, 224, 174, 133, 224, 174, 159, 224, 174, 191, 0, 8, 2, 224, 175, 139, 224, 174, 176, 224, 175, 141, 224, 174, 181, 224, 175, 134, 224, 174, 178, 224, 175, 141, 0, 8, 2, 224, 175, 139, 224, 174, 183, 224, 174, 191, 0, 8, 2, 224, 175, 139, 224, 174, 184, 0, 8, 2, 224, 175, 139, 224, 174, 184, 224, 174, 191, 224, 174, 159, 0, 8, 2, 224, 175, 140, 224, 174, 164, 224, 174, 191, 224, 174, 149, 0, 8, 2, 224, 175, 140, 224, 174, 164, 224, 175, 128, 224, 174, 149, 0, 8, 2, 224, 175, 140, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 175, 140, 224, 174, 176, 224, 174, 190, 224, 174, 163, 224, 174, 191, 0, 8, 2, 224, 175, 140, 224, 174, 178, 224, 174, 191, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 175, 140, 224, 174, 179, 224, 174, 191, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 175, 140, 224, 174, 183, 0, 8, 32, 18, 77, 2, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 178, 0, 8, 32, 18, 86, 2, 224, 174, 190, 224, 174, 181, 0, 8, 32, 136, 175, 224, 170, 174, 224, 2, 224, 175, 136, 0, 8, 32, 141, 175, 224, 159, 174, 224, 134, 175, 224, 159, 174, 224, 2, 224, 174, 190, 224, 174, 159, 224, 174, 191, 0, 8, 32, 141, 175, 224, 174, 174, 224, 130, 175, 224, 176, 174, 224, 2, 224, 174, 190, 224, 174, 175, 0, 8, 32, 141, 175, 224, 176, 174, 224, 128, 175, 224, 154, 174, 224, 169, 174, 224, 134, 175, 224, 170, 174, 224, 2, 224, 175, 129, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 175, 139, 0, 8, 32, 191, 174, 224, 159, 174, 224, 190, 174, 224, 170, 174, 224, 2, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 159, 224, 174, 176, 0, 8, 133, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 32, 0, 8, 141, 175, 224, 163, 174, 224, 170, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 0, 8, 141, 175, 224, 169, 174, 224, 129, 175, 224, 164, 174, 224, 2, 224, 175, 129, 224, 174, 177, 0, 8, 141, 175, 224, 169, 174, 224, 133, 174, 224, 2, 224, 175, 129, 224, 174, 159, 0, 8, 141, 175, 224, 169, 174, 224, 176, 174, 224, 135, 175, 224, 170, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 0, 8, 141, 175, 224, 170, 174, 224, 191, 174, 224, 179, 174, 224, 134, 175, 224, 181, 174, 224, 2, 224, 174, 190, 224, 174, 149, 0, 8, 141, 175, 224, 176, 174, 224, 190, 174, 224, 174, 174, 224, 2, 224, 175, 129, 224, 174, 159, 0, 8, 141, 175, 224, 176, 174, 224, 190, 174, 224, 174, 174, 224, 2, 224, 175, 139, 224, 174, 159, 0, 8, 141, 175, 224, 184, 174, 224, 134, 175, 224, 178, 174, 224, 2, 224, 174, 191, 224, 174, 175, 224, 174, 169, 0, 8, 141, 175, 224, 184, 174, 224, 142, 174, 224, 129, 175, 224, 175, 174, 224, 2, 224, 174, 191, 0, 8, 149, 174, 224, 2, 224, 174, 190, 224, 174, 159, 224, 174, 170, 224, 175, 129, 224, 174, 176, 12, 0, 8, 149, 174, 224, 2, 224, 174, 190, 224, 174, 178, 0, 8, 149, 174, 224, 143, 174, 224, 2, 224, 175, 139, 224, 174, 149, 0, 8, 164, 174, 224, 2, 224, 174, 190, 224, 174, 178, 0, 8, 174, 174, 224, 154, 174, 224, 2, 224, 174, 190, 224, 174, 149, 0, 8, 176, 174, 224, 174, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 0, 8, 176, 174, 224, 174, 174, 224, 2, 224, 175, 129, 224, 174, 176, 224, 174, 191, 224, 174, 174, 224, 175, 136, 0, 8, 181, 174, 224, 191, 174, 224, 154, 174, 224, 2, 224, 174, 190, 224, 174, 178, 224, 174, 169, 0, 8, 190, 174, 224, 149, 174, 224, 2, 224, 174, 190, 224, 174, 178, 224, 174, 191, 0, 8, 190, 174, 224, 154, 174, 224, 141, 175, 224, 158, 174, 224, 170, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 0, 8, 190, 174, 224, 176, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 32, 0, 8, 190, 174, 224, 178, 174, 224, 129, 175, 224, 149, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 0, 8, 190, 174, 224, 181, 174, 224, 156, 174, 224, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 0, 224, 174, 191, 1, 134, 174, 224, 2, 224, 174, 176, 224, 174, 149, 224, 174, 190, 224, 174, 174, 0, 224, 174, 191, 1, 134, 174, 224, 2, 224, 174, 176, 224, 174, 185, 224, 174, 190, 224, 174, 174, 0, 224, 174, 191, 1, 141, 175, 224, 163, 174, 224, 128, 175, 224, 181, 174, 224, 2, 224, 174, 176, 224, 174, 174, 224, 175, 136, 0, 224, 174, 191, 1, 141, 175, 224, 170, 174, 224, 164, 174, 224, 141, 175, 224, 164, 174, 224, 191, 174, 224, 154, 174, 224, 2, 224, 174, 176, 224, 174, 174, 224, 175, 136, 0, 224, 174, 191, 1, 141, 175, 224, 170, 174, 224, 169, 174, 224, 174, 174, 224, 2, 224, 174, 176, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 191, 0, 224, 174, 191, 1, 141, 175, 224, 170, 174, 224, 175, 174, 224, 170, 174, 224, 2, 224, 174, 176, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 191, 0, 224, 174, 191, 2, 224, 174, 176, 224, 174, 164, 224, 174, 176, 0, 224, 174, 191, 8, 2, 224, 174, 175, 224, 175, 130, 224, 174, 169, 224, 174, 184, 224, 175, 141, 32, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 149, 224, 174, 164, 224, 175, 128, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 149, 224, 174, 184, 224, 175, 141, 224, 174, 170, 224, 174, 164, 224, 174, 191, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 154, 224, 174, 178, 224, 175, 141, 224, 174, 184, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 164, 224, 174, 176, 224, 175, 141, 32, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 164, 224, 174, 176, 224, 175, 141, 32, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 174, 224, 174, 190, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 174, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 174, 224, 174, 191, 224, 174, 164, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 174, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 174, 224, 175, 136, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 174, 224, 175, 141, 224, 174, 174, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 174, 224, 175, 141, 224, 174, 174, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 174, 224, 175, 141, 224, 174, 174, 224, 175, 136, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 181, 224, 175, 129, 224, 174, 154, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 183, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 184, 224, 174, 178, 224, 175, 141, 224, 174, 184, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 185, 224, 174, 164, 224, 175, 128, 224, 174, 154, 224, 175, 129, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 185, 224, 174, 164, 224, 175, 128, 224, 174, 184, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 185, 224, 174, 184, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 179, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 184, 224, 175, 141, 224, 174, 178, 224, 174, 190, 224, 174, 181, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 181, 224, 175, 135, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 175, 141, 32, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 178, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 191, 32, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 175, 224, 175, 129, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 175, 224, 175, 136, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 164, 224, 174, 191, 32, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 174, 224, 174, 163, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 174, 224, 174, 163, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 174, 224, 174, 191, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 174, 224, 174, 191, 224, 174, 149, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 174, 224, 174, 191, 224, 174, 169, 224, 175, 141, 32, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 175, 224, 175, 141, 224, 174, 178, 224, 174, 176, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 181, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 181, 224, 174, 191, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 181, 224, 174, 191, 224, 174, 177, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 181, 224, 174, 191, 224, 174, 178, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 181, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 181, 224, 175, 136, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 149, 224, 175, 135, 224, 174, 159, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 159, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 190, 224, 174, 169, 224, 174, 191, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 184, 224, 175, 141, 224, 174, 159, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 184, 224, 175, 141, 224, 174, 159, 224, 174, 178, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 129, 224, 174, 149, 224, 175, 129, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 134, 224, 174, 159, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 134, 224, 174, 175, 224, 174, 191, 224, 174, 178, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 134, 224, 174, 175, 224, 175, 141, 224, 174, 178, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 135, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 136, 224, 174, 178, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 140, 224, 174, 154, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 140, 224, 174, 169, 0, 224, 174, 191, 8, 2, 224, 174, 179, 224, 174, 181, 224, 175, 129, 224, 174, 184, 0, 224, 174, 191, 8, 2, 224, 174, 179, 224, 175, 140, 224, 174, 184, 0, 224, 174, 191, 8, 141, 175, 224, 174, 174, 224, 154, 174, 224, 2, 224, 174, 176, 224, 174, 164, 224, 174, 190, 224, 174, 175, 0, 224, 175, 128, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 174, 224, 174, 163, 0, 224, 175, 129, 8, 2, 224, 174, 176, 224, 174, 181, 224, 175, 129, 224, 174, 154, 0, 224, 175, 129, 8, 2, 224, 174, 176, 224, 175, 129, 224, 174, 169, 224, 174, 190, 224, 174, 175, 0, 224, 175, 129, 8, 2, 224, 174, 176, 224, 175, 139, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 176, 0, 224, 175, 129, 8, 2, 224, 174, 176, 224, 175, 140, 224, 174, 154, 0, 224, 175, 129, 8, 2, 224, 174, 179, 224, 175, 130, 224, 174, 184, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 154, 224, 174, 178, 224, 175, 141, 224, 174, 184, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 174, 224, 175, 141, 224, 174, 174, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 181, 224, 175, 129, 224, 174, 154, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 183, 224, 175, 141, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 184, 224, 174, 178, 224, 175, 141, 224, 174, 184, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 178, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 181, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 175, 129, 224, 174, 169, 224, 174, 190, 224, 174, 175, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 175, 134, 224, 174, 159, 224, 175, 141, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 175, 134, 224, 174, 175, 224, 174, 191, 224, 174, 178, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 175, 134, 224, 174, 175, 224, 175, 141, 224, 174, 178, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 175, 135, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 175, 135, 224, 174, 154, 224, 174, 191, 224, 174, 178, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 175, 136, 224, 174, 178, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 175, 139, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 176, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 175, 140, 224, 174, 154, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 175, 140, 224, 174, 169, 0, 224, 175, 141, 8, 2, 224, 174, 179, 224, 174, 181, 224, 175, 129, 224, 174, 184, 0, 224, 175, 141, 8, 2, 224, 174, 179, 224, 175, 130, 224, 174, 184, 0, 224, 175, 141, 8, 2, 224, 174, 179, 224, 175, 140, 224, 174, 184, 0, 224, 175, 141, 224, 174, 170, 224, 174, 191, 1, 129, 175, 224, 154, 174, 224, 2, 224, 174, 176, 224, 174, 174, 224, 174, 163, 224, 174, 191, 0, 4, 224, 174, 191, 224, 174, 176, 224, 175, 129, 8, 2, 224, 174, 149, 224, 174, 169, 224, 175, 141, 224, 174, 168, 224, 174, 179, 224, 175, 136, 3, 71, 34, 37, 0, 224, 174, 191, 224, 174, 176, 224, 175, 129, 8, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 190, 0, 4, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 184, 224, 175, 141, 224, 174, 170, 8, 2, 224, 175, 135, 224, 174, 169, 3, 71, 34, 37, 89, 71, 0, 224, 175, 141, 224, 174, 176, 224, 174, 191, 224, 174, 184, 224, 175, 141, 224, 174, 170, 8, 2, 224, 175, 135, 224, 174, 169, 0, 224, 174, 191, 224, 174, 176, 224, 175, 129, 8, 2, 224, 174, 174, 224, 174, 190, 224, 174, 163, 224, 175, 141, 224, 174, 159, 3, 71, 34, 109, 65, 0, 224, 174, 191, 224, 174, 176, 224, 174, 174, 8, 2, 224, 174, 169, 3, 71, 34, 109, 65, 65, 109, 0, 224, 174, 191, 224, 174, 176, 224, 175, 135, 224, 174, 154, 8, 2, 224, 174, 191, 224, 174, 178, 3, 71, 34, 114, 88, 0, 224, 174, 191, 224, 174, 176, 224, 174, 190, 224, 174, 158, 224, 175, 141, 224, 174, 154, 8, 3, 71, 34, 118, 67, 76, 0, 224, 175, 134, 224, 174, 176, 224, 175, 141, 224, 174, 159, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 163, 224, 175, 141, 224, 174, 159, 3, 71, 36, 34, 140, 0, 224, 175, 134, 224, 174, 164, 224, 175, 141, 8, 2, 224, 174, 178, 3, 71, 36, 47, 0, 224, 175, 134, 224, 174, 169, 224, 174, 190, 224, 174, 154, 8, 2, 224, 175, 128, 224, 174, 176, 3, 71, 36, 50, 118, 88, 0, 224, 175, 134, 224, 174, 158, 224, 175, 141, 224, 174, 154, 8, 2, 224, 174, 174, 224, 174, 191, 224, 174, 169, 3, 71, 36, 67, 75, 109, 0, 224, 175, 134, 224, 174, 158, 224, 175, 141, 224, 174, 154, 8, 3, 71, 36, 67, 76, 149, 0, 224, 175, 134, 224, 174, 170, 224, 175, 141, 224, 174, 170, 8, 2, 224, 175, 135, 3, 71, 36, 71, 71, 0, 224, 175, 134, 224, 174, 154, 224, 174, 163, 224, 175, 141, 224, 174, 159, 8, 3, 71, 36, 89, 109, 66, 140, 149, 0, 224, 175, 134, 224, 174, 159, 224, 175, 141, 224, 174, 183, 224, 175, 128, 224, 174, 159, 224, 175, 141, 8, 3, 71, 36, 141, 93, 112, 140, 0, 224, 175, 134, 224, 174, 159, 224, 175, 141, 224, 174, 159, 8, 2, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 3, 71, 36, 141, 141, 0, 224, 174, 191, 224, 174, 170, 8, 2, 224, 174, 191, 3, 71, 37, 48, 0, 224, 174, 191, 224, 174, 183, 224, 174, 170, 224, 175, 141, 8, 3, 71, 37, 93, 109, 48, 0, 224, 175, 129, 224, 174, 149, 8, 2, 224, 174, 190, 224, 174, 176, 224, 175, 134, 224, 174, 184, 224, 175, 141, 224, 174, 159, 3, 71, 40, 49, 0, 224, 175, 129, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 175, 134, 224, 174, 159, 224, 175, 141, 8, 3, 71, 40, 55, 55, 36, 140, 0, 224, 175, 129, 224, 174, 164, 224, 175, 141, 224, 174, 164, 8, 2, 25, 3, 71, 40, 72, 72, 109, 0, 224, 175, 129, 224, 174, 159, 224, 174, 190, 224, 174, 170, 8, 2, 224, 175, 134, 224, 174, 184, 224, 175, 141, 224, 174, 159, 3, 71, 40, 141, 118, 48, 0, 224, 174, 191, 224, 174, 179, 224, 174, 190, 224, 174, 149, 224, 175, 141, 8, 3, 71, 55, 118, 49, 0, 4, 224, 175, 141, 224, 174, 170, 1, 18, 68, 2, 224, 175, 130, 224, 174, 164, 224, 174, 164, 224, 175, 141, 3, 71, 71, 0, 224, 175, 141, 224, 174, 170, 1, 18, 68, 2, 224, 175, 130, 224, 174, 164, 224, 174, 174, 0, 224, 175, 141, 224, 174, 170, 1, 129, 175, 224, 154, 174, 224, 2, 224, 174, 191, 224, 174, 176, 224, 174, 174, 224, 174, 163, 224, 174, 191, 224, 174, 175, 0, 224, 175, 141, 224, 174, 170, 1, 133, 174, 224, 2, 224, 174, 190, 224, 174, 184, 0, 224, 175, 141, 224, 174, 170, 1, 133, 174, 224, 2, 224, 174, 191, 224, 174, 175, 224, 174, 190, 224, 174, 154, 0, 224, 175, 141, 224, 174, 170, 1, 135, 174, 224, 2, 224, 175, 130, 224, 174, 174, 224, 174, 191, 0, 224, 175, 141, 224, 174, 170, 1, 137, 174, 224, 2, 224, 174, 191, 32, 0, 224, 175, 141, 224, 174, 170, 1, 137, 174, 224, 2, 224, 174, 191, 224, 174, 169, 32, 0, 224, 175, 141, 224, 174, 170, 1, 137, 174, 224, 2, 224, 174, 191, 224, 174, 170, 224, 175, 141, 0, 224, 175, 141, 224, 174, 170, 1, 137, 174, 224, 2, 224, 174, 191, 224, 174, 175, 0, 224, 175, 141, 224, 174, 170, 1, 137, 174, 224, 2, 224, 175, 129, 224, 174, 154, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 224, 175, 141, 224, 174, 170, 1, 137, 174, 224, 2, 224, 175, 129, 224, 174, 154, 224, 174, 174, 0, 224, 175, 141, 224, 174, 170, 1, 141, 175, 224, 176, 174, 224, 129, 175, 224, 164, 174, 224, 2, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 175, 0, 224, 175, 141, 224, 174, 170, 1, 141, 175, 224, 176, 174, 224, 129, 175, 224, 164, 174, 224, 2, 224, 175, 139, 224, 174, 164, 224, 174, 169, 224, 175, 136, 0, 224, 175, 141, 224, 174, 170, 1, 141, 175, 224, 176, 174, 224, 134, 174, 224, 2, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 159, 0, 224, 175, 141, 224, 174, 170, 1, 191, 174, 224, 159, 174, 224, 133, 174, 224, 2, 224, 174, 190, 224, 174, 149, 0, 224, 175, 141, 224, 174, 170, 1, 191, 174, 224, 164, 174, 224, 129, 175, 224, 177, 174, 224, 135, 174, 224, 2, 224, 174, 190, 224, 174, 149, 0, 224, 175, 141, 224, 174, 170, 8, 141, 175, 224, 176, 174, 224, 164, 174, 224, 2, 224, 175, 136, 0, 224, 175, 141, 224, 174, 170, 8, 149, 174, 224, 135, 175, 224, 164, 174, 224, 141, 175, 224, 168, 174, 224, 154, 174, 224, 2, 224, 175, 129, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 0, 224, 175, 141, 224, 174, 170, 8, 156, 174, 224, 2, 224, 174, 190, 224, 174, 176, 0, 224, 175, 141, 224, 174, 170, 8, 156, 174, 224, 149, 174, 224, 2, 224, 174, 191, 224, 174, 176, 224, 175, 129, 224, 174, 183, 224, 175, 141, 224, 174, 159, 0, 224, 175, 141, 224, 174, 170, 8, 159, 174, 224, 2, 224, 174, 190, 0, 224, 175, 141, 224, 174, 170, 8, 159, 174, 224, 2, 224, 174, 191, 224, 174, 153, 224, 175, 141, 0, 224, 175, 141, 224, 174, 170, 8, 178, 174, 224, 2, 224, 175, 136, 0, 224, 175, 141, 224, 174, 170, 8, 179, 174, 224, 141, 175, 224, 149, 174, 224, 2, 224, 175, 129, 224, 174, 149, 224, 174, 179, 0, 224, 175, 141, 224, 174, 170, 8, 185, 174, 224, 2, 224, 174, 191, 224, 174, 179, 0, 224, 175, 141, 224, 174, 170, 224, 174, 191, 1, 169, 174, 224, 174, 174, 224, 2, 224, 174, 176, 224, 174, 174, 224, 175, 136, 0, 4, 224, 175, 141, 224, 174, 170, 1, 18, 68, 2, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 179, 224, 174, 190, 3, 71, 71, 109, 0, 224, 175, 141, 224, 174, 170, 1, 18, 68, 2, 224, 174, 164, 224, 174, 191, 224, 174, 178, 0, 224, 175, 141, 224, 174, 170, 1, 18, 68, 2, 224, 174, 184, 0, 224, 175, 141, 224, 174, 170, 1, 133, 174, 224, 2, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 174, 224, 174, 190, 0, 224, 175, 141, 224, 174, 170, 1, 137, 174, 224, 2, 224, 174, 178, 224, 174, 190, 224, 174, 149, 0, 224, 175, 141, 224, 174, 170, 1, 137, 174, 224, 2, 224, 174, 178, 224, 174, 190, 224, 174, 169, 0, 224, 175, 141, 224, 174, 170, 1, 141, 175, 224, 176, 174, 224, 191, 174, 224, 168, 174, 224, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 0, 224, 175, 141, 224, 174, 170, 1, 141, 175, 224, 176, 174, 224, 191, 174, 224, 168, 174, 224, 2, 224, 174, 175, 0, 224, 175, 141, 224, 174, 170, 1, 141, 175, 224, 176, 174, 224, 191, 174, 224, 175, 174, 224, 137, 174, 224, 2, 224, 174, 178, 224, 174, 191, 0, 224, 175, 141, 224, 174, 170, 8, 137, 174, 224, 2, 224, 174, 178, 224, 175, 141, 32, 0, 224, 175, 141, 224, 174, 170, 8, 176, 174, 224, 2, 224, 174, 176, 0, 224, 175, 141, 224, 174, 170, 8, 179, 174, 224, 149, 174, 224, 2, 224, 174, 178, 224, 174, 191, 0, 224, 175, 141, 224, 174, 170, 8, 191, 174, 224, 176, 174, 224, 2, 224, 174, 169, 0, 4, 224, 175, 141, 224, 174, 170, 1, 141, 175, 224, 176, 174, 224, 149, 174, 224, 3, 71, 71, 149, 0, 224, 175, 141, 224, 174, 170, 8, 129, 175, 224, 154, 174, 224, 0, 224, 175, 141, 224, 174, 170, 8, 129, 175, 224, 154, 174, 224, 174, 174, 224, 190, 174, 224, 176, 174, 224, 0, 224, 175, 141, 224, 174, 170, 8, 190, 174, 224, 181, 174, 224, 168, 174, 224, 0, 4, 3, 71, 109, 0, 1, 129, 175, 224, 177, 174, 224, 174, 174, 224, 2, 224, 174, 159, 224, 174, 191, 0, 1, 141, 175, 224, 170, 174, 224, 136, 175, 224, 159, 174, 224, 170, 174, 224, 2, 224, 174, 178, 0, 1, 141, 175, 224, 170, 174, 224, 136, 175, 224, 178, 174, 224, 135, 175, 224, 181, 174, 224, 2, 224, 174, 179, 224, 175, 129, 0, 1, 141, 175, 224, 170, 174, 224, 164, 174, 224, 129, 175, 224, 175, 174, 224, 134, 174, 224, 2, 224, 174, 178, 0, 1, 141, 175, 224, 174, 174, 224, 2, 224, 174, 159, 0, 1, 141, 175, 224, 174, 174, 224, 149, 174, 224, 141, 175, 224, 149, 174, 224, 133, 174, 224, 2, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 1, 141, 175, 224, 184, 174, 224, 133, 174, 224, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 1, 149, 174, 224, 2, 224, 174, 159, 0, 1, 164, 174, 224, 2, 224, 174, 184, 0, 1, 174, 174, 224, 141, 175, 224, 164, 174, 224, 134, 174, 224, 2, 224, 174, 178, 0, 1, 174, 174, 224, 141, 175, 224, 169, 174, 224, 134, 174, 224, 2, 224, 174, 178, 0, 1, 174, 174, 224, 176, 174, 224, 170, 174, 224, 2, 224, 174, 149, 224, 175, 141, 224, 174, 164, 0, 1, 174, 174, 224, 190, 174, 224, 176, 174, 224, 2, 224, 174, 149, 224, 175, 141, 224, 174, 164, 0, 1, 175, 174, 224, 191, 174, 224, 176, 174, 224, 134, 174, 224, 2, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 190, 0, 1, 190, 174, 224, 149, 174, 224, 2, 224, 174, 176, 0, 1, 190, 174, 224, 149, 174, 224, 190, 174, 224, 168, 174, 224, 2, 224, 174, 176, 224, 174, 163, 0, 1, 190, 174, 224, 164, 174, 224, 2, 224, 174, 174, 224, 175, 141, 0, 1, 190, 174, 224, 164, 174, 224, 141, 175, 224, 184, 174, 224, 2, 224, 174, 163, 0, 1, 190, 174, 224, 164, 174, 224, 176, 174, 224, 191, 174, 224, 170, 174, 224, 2, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 179, 0, 1, 190, 174, 224, 164, 174, 224, 176, 174, 224, 191, 174, 224, 170, 174, 224, 2, 224, 174, 174, 0, 1, 191, 174, 224, 169, 174, 224, 2, 224, 174, 149, 224, 174, 181, 224, 174, 190, 224, 174, 169, 224, 175, 141, 0, 2, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 176, 0, 8, 2, 18, 71, 224, 175, 129, 224, 174, 149, 224, 175, 129, 224, 174, 163, 224, 174, 190, 0, 8, 2, 18, 71, 224, 175, 129, 224, 174, 156, 0, 8, 2, 28, 17, 12, 0, 8, 2, 224, 174, 131, 224, 174, 170, 224, 175, 130, 224, 174, 169, 0, 8, 2, 224, 174, 149, 224, 174, 164, 224, 175, 130, 224, 174, 176, 0, 8, 2, 224, 174, 149, 224, 174, 164, 224, 175, 141, 224, 174, 154, 224, 174, 191, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 174, 149, 224, 174, 181, 224, 174, 164, 224, 174, 191, 0, 8, 2, 224, 174, 149, 224, 174, 181, 224, 174, 164, 224, 175, 141, 224, 174, 168, 224, 174, 190, 224, 174, 174, 0, 8, 2, 224, 174, 149, 224, 174, 181, 224, 174, 169, 0, 8, 2, 224, 174, 149, 224, 174, 181, 224, 174, 190, 224, 174, 169, 0, 8, 2, 224, 174, 149, 224, 174, 190, 224, 174, 154, 224, 175, 129, 224, 174, 176, 0, 8, 2, 224, 174, 149, 224, 174, 190, 224, 174, 154, 224, 175, 130, 224, 174, 176, 224, 174, 169, 0, 8, 2, 224, 174, 149, 224, 174, 190, 224, 174, 175, 0, 8, 2, 224, 174, 149, 224, 174, 191, 224, 174, 176, 224, 174, 153, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 174, 149, 224, 174, 191, 224, 174, 183, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 174, 149, 224, 175, 128, 224, 174, 176, 0, 8, 2, 224, 174, 149, 224, 175, 129, 224, 174, 179, 0, 8, 2, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 191, 224, 174, 153, 224, 175, 141, 18, 71, 224, 174, 190, 224, 174, 174, 0, 8, 2, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 134, 224, 174, 159, 224, 175, 141, 0, 8, 2, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 134, 224, 174, 169, 224, 175, 141, 224, 174, 177, 0, 8, 2, 224, 174, 149, 224, 175, 141, 224, 174, 183, 224, 174, 163, 0, 8, 2, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 174, 0, 8, 2, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 179, 224, 174, 190, 0, 8, 2, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 190, 224, 174, 176, 0, 8, 2, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 175, 141, 0, 8, 2, 224, 174, 154, 224, 174, 181, 224, 174, 149, 224, 174, 178, 224, 175, 141, 224, 174, 175, 224, 174, 190, 224, 174, 163, 0, 8, 2, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 174, 169, 0, 8, 2, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 174, 190, 224, 174, 169, 0, 8, 2, 224, 174, 156, 0, 8, 2, 224, 174, 159, 224, 175, 129, 224, 174, 149, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 179, 0, 8, 2, 224, 174, 159, 224, 175, 129, 224, 174, 149, 224, 174, 190, 224, 174, 181, 0, 8, 2, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 174, 163, 0, 8, 2, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 170, 0, 8, 2, 224, 174, 159, 224, 175, 141, 224, 174, 156, 224, 174, 159, 0, 8, 2, 224, 174, 159, 224, 175, 141, 224, 174, 156, 224, 175, 134, 224, 174, 159, 224, 175, 141, 0, 8, 2, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 149, 224, 175, 141, 224, 174, 184, 0, 8, 2, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 169, 0, 8, 2, 224, 174, 164, 224, 174, 191, 224, 174, 178, 0, 8, 2, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 159, 0, 8, 2, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 176, 224, 174, 174, 224, 174, 190, 0, 8, 2, 224, 174, 164, 224, 175, 141, 224, 174, 176, 224, 174, 191, 0, 8, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 32, 224, 174, 170, 224, 174, 190, 224, 174, 154, 0, 8, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 179, 0, 8, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 170, 224, 175, 141, 0, 8, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 174, 0, 8, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 190, 224, 174, 181, 0, 8, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 179, 0, 8, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 175, 129, 224, 174, 181, 0, 8, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 175, 139, 224, 174, 170, 224, 174, 184, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 174, 169, 224, 174, 190, 224, 174, 176, 224, 174, 154, 0, 8, 2, 224, 174, 169, 224, 174, 190, 224, 174, 176, 224, 174, 184, 0, 8, 2, 224, 174, 169, 224, 174, 191, 224, 174, 175, 224, 174, 169, 0, 8, 2, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 174, 190, 224, 174, 176, 224, 174, 191, 0, 8, 2, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 175, 129, 224, 174, 174, 224, 175, 141, 32, 224, 174, 159, 224, 175, 128, 224, 174, 175, 224, 175, 129, 224, 174, 174, 224, 175, 141, 0, 8, 2, 224, 174, 169, 224, 175, 141, 224, 174, 176, 224, 175, 129, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 0, 8, 2, 224, 174, 170, 224, 174, 191, 224, 174, 179, 224, 175, 141, 224, 174, 149, 224, 174, 174, 224, 175, 141, 0, 8, 2, 224, 174, 170, 224, 175, 130, 224, 174, 169, 0, 8, 2, 224, 174, 170, 224, 175, 141, 224, 174, 179, 224, 174, 191, 224, 174, 174, 224, 174, 190, 224, 174, 184, 0, 8, 2, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 174, 176, 0, 8, 2, 224, 174, 174, 224, 175, 141, 224, 174, 170, 224, 174, 190, 224, 174, 175, 0, 8, 2, 224, 174, 175, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 174, 175, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 176, 0, 8, 2, 224, 174, 175, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 174, 175, 224, 174, 168, 224, 175, 141, 0, 8, 2, 224, 174, 175, 224, 174, 170, 224, 174, 149, 224, 175, 141, 224, 174, 164, 224, 174, 191, 0, 8, 2, 224, 174, 175, 224, 174, 170, 224, 175, 141, 0, 8, 2, 224, 174, 175, 224, 174, 174, 0, 8, 2, 224, 174, 175, 224, 174, 190, 224, 174, 178, 224, 174, 156, 224, 174, 191, 0, 8, 2, 224, 174, 175, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 181, 224, 174, 190, 224, 174, 169, 0, 8, 2, 224, 174, 176, 224, 174, 163, 224, 175, 128, 224, 174, 164, 224, 174, 176, 0, 8, 2, 224, 174, 176, 224, 174, 164, 224, 174, 149, 224, 175, 141, 0, 8, 2, 224, 174, 176, 224, 174, 164, 224, 174, 168, 224, 174, 190, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 174, 176, 224, 174, 164, 224, 174, 169, 0, 8, 2, 224, 174, 176, 224, 174, 164, 224, 174, 176, 0, 8, 2, 224, 174, 176, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 159, 0, 8, 2, 224, 174, 176, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 159, 224, 174, 174, 0, 8, 2, 224, 174, 176, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 169, 0, 8, 2, 224, 174, 176, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 129, 0, 8, 2, 224, 174, 176, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 139, 224, 174, 159, 0, 8, 2, 224, 174, 176, 224, 174, 164, 224, 175, 141, 224, 174, 170, 224, 175, 130, 224, 174, 176, 0, 8, 2, 224, 174, 176, 224, 174, 164, 224, 175, 141, 224, 174, 181, 224, 174, 190, 224, 174, 156, 0, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 149, 224, 175, 141, 32, 224, 174, 146, 224, 174, 170, 224, 174, 190, 224, 174, 174, 224, 174, 190, 0, 8, 2, 224, 174, 176, 224, 175, 139, 224, 174, 159, 0, 8, 2, 224, 174, 176, 224, 175, 141, 224, 174, 131, 224, 174, 170, 224, 174, 191, 0, 8, 2, 224, 174, 176, 224, 175, 141, 224, 174, 149, 224, 174, 176, 0, 8, 2, 224, 174, 176, 224, 175, 141, 224, 174, 164, 224, 175, 141, 0, 8, 2, 224, 174, 176, 224, 175, 141, 224, 174, 169, 224, 174, 190, 224, 174, 178, 224, 174, 190, 0, 8, 2, 224, 174, 176, 224, 175, 141, 224, 174, 174, 0, 8, 2, 224, 174, 178, 224, 174, 149, 224, 175, 128, 224, 174, 169, 0, 8, 2, 224, 174, 178, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 174, 178, 224, 174, 154, 224, 174, 190, 224, 174, 178, 224, 174, 191, 0, 8, 2, 224, 174, 178, 224, 174, 164, 224, 175, 135, 224, 174, 181, 0, 8, 2, 224, 174, 178, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 190, 224, 174, 178, 0, 8, 2, 224, 174, 178, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 169, 224, 174, 190, 0, 8, 2, 224, 174, 178, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 169, 224, 175, 129, 224, 174, 159, 0, 8, 2, 224, 174, 178, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 129, 224, 174, 149, 224, 175, 141, 0, 8, 2, 224, 174, 178, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 129, 224, 174, 154, 224, 175, 141, 0, 8, 2, 224, 174, 178, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 129, 224, 174, 159, 0, 8, 2, 224, 174, 178, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 136, 0, 8, 2, 224, 174, 178, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 139, 224, 174, 159, 224, 175, 129, 0, 8, 2, 224, 174, 178, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 179, 0, 8, 2, 224, 174, 178, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 159, 0, 8, 2, 224, 174, 178, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 159, 224, 175, 129, 0, 8, 2, 224, 174, 178, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 174, 178, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 174, 0, 8, 2, 224, 174, 178, 224, 174, 170, 224, 175, 141, 224, 174, 170, 224, 174, 176, 224, 175, 128, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 175, 136, 0, 8, 2, 224, 174, 178, 224, 174, 174, 224, 174, 163, 224, 175, 136, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 174, 178, 224, 174, 174, 224, 174, 177, 224, 175, 141, 224, 174, 177, 0, 8, 2, 224, 174, 178, 224, 174, 174, 224, 174, 190, 224, 174, 149, 17, 67, 224, 175, 141, 0, 8, 2, 224, 174, 178, 224, 174, 174, 224, 174, 190, 224, 174, 149, 224, 174, 181, 0, 8, 2, 224, 174, 178, 224, 174, 174, 224, 174, 190, 224, 174, 149, 224, 174, 181, 224, 175, 135, 0, 8, 2, 224, 174, 178, 224, 174, 174, 224, 174, 190, 224, 174, 149, 224, 174, 191, 0, 8, 2, 224, 174, 178, 224, 174, 174, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 174, 178, 224, 174, 174, 224, 174, 190, 224, 174, 154, 224, 175, 141, 224, 174, 154, 0, 8, 2, 224, 174, 178, 224, 174, 174, 224, 174, 190, 224, 174, 169, 0, 8, 2, 224, 174, 178, 224, 174, 174, 224, 174, 190, 224, 174, 175, 224, 175, 141, 0, 8, 2, 224, 174, 178, 224, 174, 174, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 178, 0, 8, 2, 224, 174, 178, 224, 174, 174, 224, 174, 191, 224, 174, 180, 0, 8, 2, 224, 174, 178, 224, 174, 174, 224, 175, 129, 224, 174, 159, 224, 174, 169, 0, 8, 2, 224, 174, 178, 224, 174, 174, 224, 175, 129, 224, 174, 159, 224, 175, 136, 224, 174, 168, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 174, 178, 224, 174, 174, 224, 175, 129, 224, 174, 159, 224, 175, 136, 224, 174, 175, 0, 8, 2, 224, 174, 178, 224, 174, 174, 224, 175, 129, 224, 174, 174, 0, 8, 2, 224, 174, 178, 224, 174, 174, 224, 175, 129, 224, 174, 177, 224, 175, 129, 0, 8, 2, 224, 174, 178, 224, 174, 174, 224, 175, 129, 224, 174, 177, 224, 175, 141, 224, 174, 177, 0, 8, 2, 224, 174, 178, 224, 174, 174, 224, 175, 129, 224, 174, 179, 224, 175, 141, 224, 174, 179, 0, 8, 2, 224, 174, 178, 224, 174, 174, 224, 175, 130, 224, 174, 159, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 174, 178, 224, 174, 176, 224, 174, 190, 224, 174, 174, 0, 8, 2, 224, 174, 178, 224, 174, 181, 224, 174, 168, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 174, 178, 224, 174, 181, 224, 174, 190, 224, 174, 169, 0, 8, 2, 224, 174, 178, 224, 174, 181, 224, 175, 128, 224, 174, 169, 0, 8, 2, 224, 174, 178, 224, 174, 185, 224, 175, 128, 224, 174, 169, 0, 8, 2, 224, 174, 178, 224, 174, 191, 224, 174, 149, 224, 174, 159, 224, 174, 190, 0, 8, 2, 224, 174, 178, 224, 174, 191, 224, 174, 149, 224, 175, 138, 0, 8, 2, 224, 174, 178, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 159, 224, 174, 190, 0, 8, 2, 224, 174, 178, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 224, 174, 154, 224, 175, 141, 0, 8, 2, 224, 174, 178, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 138, 0, 8, 2, 224, 174, 178, 224, 174, 191, 224, 174, 156, 224, 174, 190, 0, 8, 2, 224, 174, 178, 224, 174, 191, 224, 174, 170, 224, 175, 128, 224, 174, 159, 0, 8, 2, 224, 174, 178, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 174, 178, 224, 175, 128, 224, 174, 156, 224, 174, 190, 0, 8, 2, 224, 174, 178, 224, 175, 130, 224, 174, 169, 0, 8, 2, 224, 174, 178, 224, 175, 141, 224, 174, 149, 224, 175, 135, 224, 174, 176, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 174, 178, 224, 175, 141, 224, 174, 170, 224, 175, 129, 0, 8, 2, 224, 174, 178, 224, 175, 141, 224, 174, 170, 224, 175, 136, 0, 8, 2, 224, 174, 179, 224, 175, 129, 0, 8, 2, 224, 174, 181, 224, 174, 168, 224, 174, 149, 224, 174, 176, 0, 8, 2, 224, 174, 181, 224, 174, 169, 0, 8, 2, 224, 174, 181, 224, 174, 190, 224, 174, 163, 224, 174, 191, 0, 8, 2, 224, 174, 181, 224, 174, 190, 224, 174, 169, 224, 174, 191, 0, 8, 2, 224, 174, 181, 224, 175, 129, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 178, 0, 8, 2, 224, 174, 181, 224, 175, 129, 224, 174, 178, 224, 174, 176, 0, 8, 2, 224, 174, 181, 224, 175, 129, 224, 174, 178, 224, 174, 191, 224, 174, 153, 224, 175, 141, 0, 8, 2, 224, 174, 181, 224, 175, 135, 224, 174, 176, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 174, 181, 224, 175, 141, 224, 174, 175, 0, 8, 2, 224, 174, 183, 224, 175, 128, 224, 174, 176, 0, 8, 2, 224, 174, 184, 0, 8, 2, 224, 174, 185, 224, 174, 164, 224, 175, 130, 224, 174, 176, 0, 8, 2, 224, 174, 185, 224, 174, 190, 224, 174, 174, 224, 174, 190, 224, 174, 184, 0, 8, 2, 224, 174, 185, 224, 174, 190, 224, 174, 175, 0, 8, 2, 224, 174, 185, 224, 174, 191, 224, 174, 176, 224, 174, 153, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 174, 185, 224, 174, 191, 224, 174, 176, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 174, 185, 224, 175, 141, 224, 174, 176, 224, 175, 134, 224, 174, 175, 0, 8, 32, 141, 175, 224, 174, 174, 224, 129, 175, 224, 175, 174, 224, 128, 175, 224, 159, 174, 224, 2, 224, 174, 169, 224, 175, 141, 224, 174, 169, 224, 175, 129, 224, 174, 174, 224, 175, 141, 32, 0, 8, 32, 164, 174, 224, 141, 175, 224, 168, 174, 224, 138, 175, 224, 154, 174, 224, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 0, 8, 129, 175, 224, 149, 174, 224, 190, 174, 224, 154, 174, 224, 2, 224, 174, 159, 224, 174, 191, 0, 8, 141, 175, 224, 163, 174, 224, 175, 174, 224, 170, 174, 224, 2, 224, 174, 159, 0, 8, 141, 175, 224, 170, 174, 224, 149, 174, 224, 141, 175, 224, 149, 174, 224, 170, 174, 224, 2, 224, 174, 178, 0, 8, 141, 175, 224, 178, 174, 224, 138, 175, 224, 154, 174, 224, 2, 224, 174, 181, 0, 8, 141, 175, 224, 184, 174, 224, 185, 174, 224, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 8, 141, 175, 224, 184, 174, 224, 191, 174, 224, 178, 174, 224, 2, 224, 174, 169, 0, 8, 149, 174, 224, 2, 224, 174, 164, 224, 175, 141, 0, 8, 149, 174, 224, 2, 224, 174, 174, 224, 175, 141, 32, 0, 8, 149, 174, 224, 2, 224, 174, 179, 224, 174, 191, 224, 174, 149, 224, 174, 176, 0, 8, 149, 174, 224, 135, 175, 224, 164, 174, 224, 2, 224, 174, 178, 0, 8, 149, 174, 224, 141, 175, 224, 149, 174, 224, 170, 174, 224, 2, 224, 174, 178, 0, 8, 159, 174, 224, 170, 174, 224, 2, 224, 174, 159, 0, 8, 164, 174, 224, 2, 224, 174, 154, 0, 8, 164, 174, 224, 141, 175, 224, 168, 174, 224, 138, 175, 224, 154, 174, 224, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 0, 8, 190, 174, 224, 149, 174, 224, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 175, 129, 0, 8, 190, 174, 224, 149, 174, 224, 174, 174, 224, 2, 224, 174, 178, 224, 174, 191, 0, 8, 190, 174, 224, 164, 174, 224, 2, 32, 0, 8, 190, 174, 224, 164, 174, 224, 2, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 179, 0, 8, 190, 174, 224, 164, 174, 224, 2, 224, 174, 164, 224, 175, 141, 224, 174, 164, 0, 8, 190, 174, 224, 164, 174, 224, 2, 224, 174, 168, 224, 175, 141, 224, 174, 164, 224, 174, 190, 224, 174, 169, 0, 8, 190, 174, 224, 164, 174, 224, 2, 224, 174, 174, 0, 224, 175, 129, 8, 2, 224, 174, 176, 224, 175, 139, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 190, 0, 224, 174, 176, 224, 175, 141, 224, 174, 170, 8, 2, 224, 174, 191, 3, 71, 109, 34, 83, 0, 224, 174, 176, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 175, 129, 8, 2, 224, 174, 181, 224, 174, 190, 224, 174, 156, 3, 71, 109, 34, 109, 47, 0, 4, 224, 174, 149, 224, 175, 141, 8, 2, 224, 174, 164, 3, 71, 109, 49, 0, 224, 174, 149, 224, 175, 141, 8, 2, 224, 174, 176, 224, 175, 128, 224, 174, 164, 0, 224, 174, 168, 224, 175, 141, 224, 174, 164, 8, 2, 224, 175, 129, 224, 174, 178, 224, 175, 129, 3, 71, 109, 50, 47, 0, 224, 174, 178, 224, 174, 190, 224, 174, 164, 224, 175, 141, 224, 174, 149, 8, 2, 224, 174, 190, 224, 174, 176, 3, 71, 109, 55, 118, 72, 49, 0, 224, 174, 178, 224, 175, 129, 224, 174, 154, 8, 2, 224, 174, 191, 224, 174, 184, 224, 175, 141, 224, 174, 164, 224, 174, 190, 224, 174, 169, 3, 71, 109, 55, 122, 76, 0, 224, 174, 178, 224, 175, 141, 224, 174, 159, 8, 2, 224, 174, 191, 3, 71, 109, 55, 140, 0, 224, 174, 175, 224, 174, 190, 224, 174, 184, 224, 175, 141, 224, 174, 149, 224, 175, 139, 224, 174, 170, 224, 175, 141, 8, 3, 71, 109, 57, 118, 89, 49, 119, 48, 0, 224, 174, 153, 224, 175, 141, 224, 174, 149, 8, 2, 224, 174, 176, 3, 71, 109, 68, 49, 109, 0, 224, 174, 164, 1, 141, 175, 224, 163, 174, 224, 190, 174, 224, 149, 174, 224, 2, 224, 174, 191, 224, 174, 178, 3, 71, 109, 72, 0, 4, 224, 174, 164, 224, 175, 141, 224, 174, 164, 8, 2, 224, 174, 191, 224, 174, 176, 224, 174, 149, 224, 174, 190, 224, 174, 179, 224, 174, 191, 3, 71, 109, 72, 72, 0, 224, 174, 164, 224, 175, 141, 224, 174, 164, 8, 2, 224, 174, 191, 224, 174, 176, 224, 174, 191, 32, 0, 224, 174, 164, 224, 175, 141, 224, 174, 164, 8, 2, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 175, 129, 0, 224, 174, 164, 224, 175, 141, 224, 174, 164, 8, 2, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 175, 0, 224, 174, 149, 8, 2, 224, 174, 191, 224, 174, 176, 224, 174, 163, 224, 175, 141, 224, 174, 159, 3, 71, 109, 81, 0, 224, 174, 149, 8, 2, 224, 174, 190, 224, 174, 174, 224, 174, 190, 224, 174, 184, 3, 71, 109, 108, 0, 224, 174, 159, 8, 2, 224, 174, 190, 224, 174, 178, 224, 174, 191, 224, 174, 175, 224, 174, 169, 3, 71, 109, 140, 0, 224, 175, 128, 224, 174, 164, 8, 2, 224, 175, 139, 224, 174, 181, 224, 174, 169, 3, 71, 112, 47, 0, 224, 175, 128, 224, 174, 154, 224, 175, 141, 8, 2, 224, 174, 178, 3, 71, 112, 76, 0, 224, 175, 128, 224, 174, 159, 224, 175, 141, 224, 174, 176, 224, 175, 130, 224, 174, 159, 224, 175, 141, 8, 3, 71, 112, 140, 34, 123, 140, 0, 4, 224, 174, 190, 8, 2, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 176, 224, 174, 191, 3, 71, 114, 0, 224, 174, 190, 8, 2, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 153, 224, 175, 141, 0, 224, 175, 135, 224, 174, 169, 224, 174, 159, 224, 175, 141, 8, 3, 71, 114, 50, 109, 140, 0, 224, 175, 139, 8, 2, 224, 174, 184, 224, 175, 141, 224, 174, 159, 224, 174, 169, 3, 71, 118, 0, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 170, 8, 2, 224, 174, 159, 224, 174, 190, 3, 71, 118, 34, 71, 109, 0, 224, 174, 190, 224, 174, 170, 224, 174, 164, 224, 174, 191, 1, 154, 174, 224, 3, 71, 118, 48, 109, 47, 37, 0, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 159, 8, 2, 224, 175, 128, 224, 174, 176, 224, 174, 191, 224, 174, 175, 224, 174, 190, 3, 71, 118, 49, 140, 0, 224, 174, 190, 224, 174, 178, 224, 175, 141, 224, 174, 149, 8, 2, 224, 174, 169, 224, 174, 191, 3, 71, 118, 55, 49, 109, 0, 224, 174, 190, 224, 174, 178, 224, 174, 170, 8, 2, 224, 174, 190, 224, 174, 159, 3, 71, 118, 55, 109, 48, 0, 224, 174, 190, 224, 174, 178, 224, 175, 141, 224, 174, 159, 8, 2, 224, 174, 191, 224, 174, 174, 224, 175, 139, 224, 174, 176, 3, 71, 118, 55, 140, 0, 224, 174, 190, 224, 174, 178, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 175, 141, 8, 3, 71, 118, 55, 140, 37, 49, 0, 224, 174, 190, 224, 174, 153, 224, 175, 141, 224, 174, 149, 8, 2, 224, 174, 190, 224, 174, 149, 224, 175, 141, 3, 71, 118, 68, 49, 0, 4, 224, 174, 190, 224, 174, 170, 8, 2, 224, 174, 190, 224, 174, 154, 224, 174, 190, 224, 174, 149, 224, 175, 135, 224, 174, 170, 224, 175, 141, 3, 71, 118, 71, 0, 224, 174, 190, 224, 174, 170, 8, 2, 224, 174, 190, 224, 174, 154, 224, 174, 190, 224, 174, 185, 224, 175, 135, 224, 174, 170, 224, 175, 141, 0, 224, 174, 190, 224, 174, 170, 8, 2, 224, 174, 190, 224, 174, 181, 0, 224, 174, 190, 224, 174, 170, 8, 141, 175, 224, 175, 174, 224, 190, 174, 224, 154, 174, 224, 2, 224, 174, 190, 0, 224, 174, 190, 224, 174, 170, 8, 191, 174, 224, 175, 174, 224, 190, 174, 224, 154, 174, 224, 2, 224, 174, 190, 0, 224, 174, 190, 224, 174, 170, 8, 2, 224, 174, 176, 3, 71, 118, 71, 109, 0, 4, 224, 174, 190, 224, 174, 164, 224, 175, 141, 224, 174, 164, 8, 2, 224, 174, 191, 224, 174, 175, 224, 174, 164, 224, 175, 136, 3, 71, 118, 72, 72, 0, 224, 174, 190, 224, 174, 164, 224, 175, 141, 224, 174, 164, 8, 2, 224, 174, 191, 224, 174, 175, 224, 174, 174, 224, 175, 141, 32, 0, 224, 174, 190, 224, 174, 149, 224, 175, 141, 224, 174, 164, 8, 2, 224, 174, 190, 224, 174, 164, 3, 71, 118, 81, 72, 0, 224, 175, 139, 224, 174, 170, 8, 2, 224, 174, 190, 224, 174, 178, 3, 71, 119, 48, 0, 224, 175, 139, 224, 174, 170, 8, 2, 224, 175, 139, 224, 174, 176, 224, 175, 141, 3, 71, 119, 83, 0, 224, 175, 130, 224, 174, 164, 224, 175, 141, 8, 2, 32, 3, 71, 123, 47, 0, 224, 175, 130, 224, 174, 170, 8, 2, 224, 174, 164, 224, 174, 191, 3, 71, 123, 48, 109, 0, 224, 175, 130, 224, 174, 159, 8, 2, 224, 174, 190, 224, 174, 169, 3, 71, 123, 140, 0, 224, 175, 136, 224, 174, 170, 8, 2, 224, 174, 190, 224, 174, 184, 3, 71, 134, 48, 0, 4, 1, 190, 174, 224, 164, 174, 224, 129, 175, 224, 168, 174, 224, 133, 174, 224, 2, 12, 3, 71, 149, 0, 1, 190, 174, 224, 164, 174, 224, 129, 175, 224, 169, 174, 224, 133, 174, 224, 2, 12, 0, 1, 190, 174, 224, 164, 174, 224, 141, 175, 224, 184, 174, 224, 169, 174, 224, 174, 174, 224, 2, 12, 0, 1, 190, 174, 224, 164, 174, 224, 141, 175, 224, 184, 174, 224, 176, 174, 224, 191, 174, 224, 170, 174, 224, 2, 12, 0, 1, 190, 174, 224, 164, 174, 224, 190, 174, 224, 154, 174, 224, 141, 175, 224, 159, 174, 224, 170, 174, 224, 2, 25, 0, 1, 190, 174, 224, 164, 174, 224, 190, 174, 224, 154, 174, 224, 141, 175, 224, 159, 174, 224, 170, 174, 224, 175, 174, 224, 129, 175, 224, 154, 174, 224, 2, 25, 0, 1, 190, 174, 224, 164, 174, 224, 191, 174, 224, 176, 174, 224, 170, 174, 224, 2, 12, 0, 8, 190, 174, 224, 164, 174, 224, 141, 175, 224, 184, 174, 224, 2, 12, 0, 8, 190, 174, 224, 164, 174, 224, 149, 174, 224, 176, 174, 224, 191, 174, 224, 181, 174, 224, 2, 12, 0, 8, 190, 174, 224, 164, 174, 224, 190, 174, 224, 154, 174, 224, 141, 175, 224, 154, 174, 224, 170, 174, 224, 2, 12, 0, 4, 1, 134, 174, 224, 2, 224, 174, 191, 224, 174, 176, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 3, 83, 0, 1, 139, 175, 224, 176, 174, 224, 141, 175, 224, 149, 174, 224, 136, 175, 224, 174, 174, 224, 2, 224, 175, 139, 224, 174, 169, 0, 1, 141, 175, 224, 169, 174, 224, 135, 174, 224, 2, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 174, 0, 1, 141, 175, 224, 174, 174, 224, 135, 174, 224, 2, 224, 174, 190, 224, 174, 178, 0, 1, 141, 175, 224, 178, 174, 224, 133, 174, 224, 2, 224, 175, 139, 224, 174, 169, 224, 175, 141, 224, 174, 184, 0, 1, 141, 175, 224, 178, 174, 224, 134, 174, 224, 2, 224, 174, 190, 0, 1, 144, 174, 224, 2, 224, 175, 139, 224, 174, 169, 0, 1, 174, 174, 224, 190, 174, 224, 176, 174, 224, 191, 174, 224, 149, 174, 224, 2, 224, 175, 139, 224, 174, 169, 0, 1, 190, 174, 224, 154, 174, 224, 141, 175, 224, 154, 174, 224, 133, 174, 224, 2, 224, 175, 128, 0, 1, 191, 174, 224, 178, 174, 224, 149, 174, 224, 2, 224, 175, 139, 224, 174, 176, 224, 175, 141, 224, 174, 169, 224, 174, 191, 224, 174, 175, 0, 8, 2, 224, 174, 190, 224, 174, 149, 224, 174, 191, 224, 174, 175, 224, 174, 190, 224, 174, 169, 0, 8, 2, 224, 174, 190, 224, 174, 154, 224, 174, 191, 224, 174, 178, 0, 8, 2, 224, 174, 190, 224, 174, 164, 224, 175, 141, 224, 174, 164, 224, 174, 191, 224, 174, 174, 224, 174, 190, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 174, 159, 224, 175, 135, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 174, 18, 69, 224, 174, 191, 0, 8, 2, 224, 174, 190, 224, 174, 176, 224, 175, 141, 224, 174, 174, 224, 175, 129, 224, 174, 178, 0, 8, 2, 224, 174, 190, 224, 174, 185, 224, 174, 191, 224, 174, 175, 224, 174, 190, 224, 174, 169, 0, 8, 2, 224, 174, 191, 224, 174, 149, 224, 174, 176, 0, 8, 2, 224, 174, 191, 224, 174, 153, 224, 175, 141, 224, 174, 149, 224, 174, 176, 224, 175, 141, 32, 0, 8, 2, 224, 174, 191, 224, 174, 154, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 184, 0, 8, 2, 224, 174, 191, 224, 174, 159, 224, 174, 191, 224, 174, 178, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 174, 191, 224, 174, 183, 0, 8, 2, 224, 174, 191, 224, 174, 169, 224, 175, 141, 224, 174, 178, 224, 174, 190, 224, 174, 168, 224, 175, 141, 224, 174, 164, 0, 8, 2, 224, 174, 191, 224, 174, 170, 224, 175, 141, 224, 174, 176, 224, 174, 181, 224, 174, 176, 224, 174, 191, 0, 8, 2, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 174, 0, 8, 2, 224, 174, 191, 224, 174, 183, 224, 175, 141, 0, 8, 2, 224, 175, 129, 224, 174, 178, 224, 175, 141, 32, 18, 80, 0, 8, 2, 224, 175, 129, 224, 174, 178, 224, 175, 141, 224, 174, 178, 224, 174, 190, 32, 0, 8, 2, 224, 175, 134, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 174, 190, 224, 174, 184, 224, 175, 141, 224, 174, 159, 224, 174, 191, 224, 174, 149, 224, 175, 141, 0, 8, 2, 224, 175, 134, 224, 174, 164, 224, 174, 176, 0, 8, 2, 224, 175, 134, 224, 174, 170, 224, 175, 141, 224, 174, 176, 224, 174, 181, 224, 174, 176, 224, 174, 191, 0, 8, 2, 224, 175, 134, 224, 174, 175, 224, 174, 191, 224, 174, 178, 0, 8, 2, 224, 175, 134, 224, 174, 176, 224, 175, 141, 224, 174, 169, 224, 174, 190, 224, 174, 163, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 175, 134, 224, 174, 176, 224, 175, 141, 224, 174, 169, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 159, 0, 8, 2, 224, 175, 135, 224, 174, 149, 224, 175, 141, 224, 174, 159, 224, 174, 176, 0, 8, 2, 224, 175, 135, 224, 174, 174, 224, 174, 191, 224, 174, 178, 224, 174, 191, 0, 8, 2, 224, 175, 135, 224, 174, 183, 224, 174, 169, 0, 8, 2, 224, 175, 136, 224, 174, 170, 224, 174, 176, 0, 8, 2, 224, 175, 136, 224, 174, 178, 224, 174, 191, 224, 174, 178, 0, 8, 2, 224, 175, 136, 224, 174, 178, 224, 175, 129, 0, 8, 2, 224, 175, 136, 224, 174, 178, 224, 175, 141, 224, 174, 149, 224, 174, 179, 0, 8, 2, 224, 175, 139, 224, 174, 149, 224, 175, 141, 224, 174, 149, 224, 174, 184, 0, 8, 2, 224, 175, 139, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 175, 139, 32, 0, 8, 2, 224, 175, 139, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 175, 139, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 175, 139, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 175, 139, 224, 174, 164, 224, 174, 190, 224, 174, 169, 0, 8, 2, 224, 175, 139, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 175, 139, 224, 174, 181, 0, 8, 2, 224, 175, 139, 224, 174, 169, 224, 174, 191, 224, 174, 169, 224, 175, 141, 32, 0, 8, 2, 224, 175, 139, 224, 174, 169, 224, 174, 191, 224, 174, 178, 0, 8, 2, 224, 175, 139, 224, 174, 169, 224, 174, 191, 224, 174, 178, 224, 175, 129, 224, 174, 174, 224, 175, 141, 0, 8, 2, 224, 175, 139, 224, 174, 169, 224, 175, 129, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 8, 2, 224, 175, 139, 224, 174, 169, 224, 175, 129, 224, 174, 159, 224, 175, 136, 224, 174, 175, 0, 8, 2, 224, 175, 139, 224, 174, 169, 224, 175, 129, 224, 174, 178, 0, 8, 2, 224, 175, 139, 224, 174, 169, 224, 175, 136, 0, 8, 2, 224, 175, 139, 224, 174, 169, 224, 175, 141, 224, 174, 149, 224, 174, 179, 0, 8, 2, 224, 175, 139, 224, 174, 176, 224, 175, 141, 224, 174, 156, 224, 174, 176, 224, 174, 191, 0, 8, 2, 224, 175, 139, 224, 174, 176, 224, 175, 141, 224, 174, 174, 224, 175, 135, 224, 174, 169, 0, 8, 128, 175, 224, 178, 174, 224, 149, 174, 224, 2, 224, 174, 190, 0, 8, 134, 174, 224, 2, 224, 174, 191, 224, 174, 154, 0, 8, 134, 174, 224, 2, 224, 174, 191, 224, 174, 184, 0, 8, 134, 174, 224, 2, 224, 175, 128, 224, 174, 154, 0, 8, 134, 174, 224, 2, 224, 175, 128, 224, 174, 184, 0, 8, 136, 175, 224, 176, 174, 224, 2, 224, 174, 191, 224, 174, 179, 0, 8, 139, 175, 224, 154, 174, 224, 2, 224, 174, 190, 0, 8, 141, 175, 224, 159, 174, 224, 190, 174, 224, 179, 174, 224, 191, 174, 224, 170, 174, 224, 2, 224, 174, 190, 224, 174, 176, 0, 8, 141, 175, 224, 169, 174, 224, 149, 174, 224, 2, 224, 174, 191, 224, 174, 149, 224, 174, 176, 0, 8, 141, 175, 224, 178, 174, 224, 129, 175, 224, 149, 174, 224, 2, 224, 174, 191, 0, 8, 141, 175, 224, 178, 174, 224, 129, 175, 224, 156, 174, 224, 2, 224, 174, 191, 0, 8, 141, 175, 224, 178, 174, 224, 134, 175, 224, 154, 174, 224, 2, 224, 175, 139, 224, 174, 169, 0, 8, 141, 175, 224, 178, 174, 224, 134, 175, 224, 170, 174, 224, 2, 224, 174, 190, 224, 174, 184, 224, 175, 141, 224, 174, 159, 0, 8, 141, 175, 224, 178, 174, 224, 134, 175, 224, 181, 174, 224, 2, 224, 175, 135, 224, 174, 176, 0, 8, 141, 175, 224, 178, 174, 224, 190, 174, 224, 159, 174, 224, 2, 224, 174, 191, 224, 174, 169, 0, 8, 149, 174, 224, 2, 224, 175, 135, 0, 8, 164, 174, 224, 141, 175, 224, 184, 174, 224, 129, 175, 224, 174, 174, 224, 2, 224, 174, 190, 0, 8, 190, 174, 224, 149, 174, 224, 2, 224, 174, 191, 0, 8, 190, 174, 224, 149, 174, 224, 134, 175, 224, 174, 174, 224, 2, 224, 175, 139, 224, 174, 169, 0, 8, 190, 174, 224, 159, 174, 224, 149, 174, 224, 2, 224, 174, 191, 0, 8, 191, 174, 224, 154, 174, 224, 170, 174, 224, 2, 224, 174, 191, 224, 174, 149, 224, 175, 141, 0, 8, 191, 174, 224, 178, 174, 224, 149, 174, 224, 2, 224, 174, 190, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 153, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 159, 224, 174, 190, 224, 174, 149, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 159, 224, 175, 141, 32, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 154, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 184, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 128, 224, 174, 175, 224, 174, 190, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 134, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 175, 141, 224, 174, 184, 0, 224, 174, 191, 8, 2, 224, 174, 176, 224, 175, 134, 224, 174, 183, 224, 175, 141, 0, 224, 174, 191, 8, 2, 224, 174, 178, 224, 175, 134, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 174, 176, 0, 224, 174, 191, 8, 2, 224, 174, 179, 224, 174, 190, 224, 174, 184, 224, 175, 141, 224, 174, 149, 224, 175, 141, 0, 224, 175, 129, 8, 2, 224, 174, 179, 224, 175, 139, 224, 174, 176, 224, 174, 169, 224, 175, 141, 224, 174, 184, 0, 224, 175, 129, 8, 2, 224, 174, 179, 224, 175, 139, 224, 174, 176, 224, 174, 191, 224, 174, 159, 224, 174, 190, 0, 224, 175, 141, 1, 134, 174, 224, 2, 224, 174, 149, 224, 174, 190, 224, 174, 169, 224, 174, 191, 224, 174, 175, 0, 224, 175, 141, 1, 134, 174, 224, 2, 224, 174, 149, 224, 174, 190, 224, 174, 169, 224, 174, 191, 224, 174, 184, 224, 175, 141, 224, 174, 164, 224, 174, 190, 224, 174, 169, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 153, 224, 175, 141, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 159, 224, 174, 190, 224, 174, 149, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 159, 224, 175, 141, 32, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 154, 224, 174, 191, 224, 174, 184, 224, 175, 141, 224, 174, 149, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 174, 190, 224, 174, 169, 224, 175, 141, 224, 174, 184, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 175, 128, 224, 174, 175, 224, 174, 190, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 175, 134, 224, 174, 158, 224, 175, 141, 224, 174, 154, 224, 175, 141, 0, 224, 175, 141, 8, 2, 224, 174, 176, 224, 175, 134, 224, 174, 183, 224, 175, 141, 0, 224, 175, 141, 8, 2, 224, 174, 178, 224, 175, 134, 224, 174, 159, 224, 175, 141, 224, 174, 154, 224, 174, 176, 0, 224, 175, 141, 8, 2, 224, 174, 179, 224, 175, 139, 224, 174, 176, 224, 174, 169, 224, 175, 141, 224, 174, 184, 0, 224, 175, 141, 8, 2, 224, 174, 179, 224, 175, 139, 224, 174, 176, 224, 174, 191, 224, 174, 159, 224, 174, 190, 0, 224, 175, 141, 8, 190, 174, 224, 154, 174, 224, 139, 175, 224, 176, 174, 224, 141, 175, 224, 149, 174, 224, 136, 175, 224, 174, 174, 224, 2, 224, 174, 159, 0, 224, 175, 141, 8, 191, 174, 224, 178, 174, 224, 2, 224, 174, 159, 0, 224, 175, 141, 224, 174, 170, 224, 174, 191, 1, 134, 174, 224, 2, 224, 174, 176, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 224, 174, 191, 224, 174, 176, 8, 2, 224, 174, 163, 224, 175, 141, 224, 174, 159, 224, 175, 141, 224, 174, 184, 3, 83, 34, 36, 0, 224, 174, 191, 224, 174, 176, 224, 175, 134, 224, 174, 158, 224, 175, 141, 224, 174, 154, 8, 3, 83, 34, 36, 67, 76, 149, 0, 4, 224, 174, 191, 224, 174, 176, 224, 175, 134, 224, 174, 159, 224, 175, 141, 224, 174, 176, 224, 174, 191, 224, 174, 149, 224, 175, 141, 8, 3, 83, 34, 36, 141, 34, 37, 49, 0, 224, 175, 141, 224, 174, 176, 224, 175, 134, 224, 174, 159, 224, 175, 141, 224, 174, 176, 224, 174, 191, 224, 174, 149, 224, 175, 141, 8, 0, 224, 175, 141, 224, 174, 176, 224, 174, 159, 8, 130, 175, 224, 175, 174, 224, 2, 224, 175, 128, 224, 174, 184, 3, 83, 34, 109, 140, 0, 224, 174, 191, 224, 174, 149, 1, 191, 174, 224, 178, 174, 224, 190, 174, 224, 181, 174, 224, 2, 224, 175, 135, 224, 174, 183, 224, 174, 169, 3, 83, 37, 49, 0, 224, 174, 191, 224, 174, 178, 224, 174, 191, 224, 174, 170, 8, 3, 83, 37, 55, 37, 48, 149, 0, 224, 174, 191, 224, 174, 178, 224, 174, 191, 224, 174, 159, 224, 175, 134, 224, 174, 178, 224, 175, 141, 224, 174, 170, 8, 2, 224, 174, 191, 224, 174, 175, 3, 83, 37, 55, 37, 72, 36, 55, 83, 0, 224, 174, 191, 224, 174, 178, 224, 174, 191, 224, 174, 174, 8, 3, 83, 37, 55, 65, 149, 0, 4, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 159, 8, 2, 224, 174, 176, 224, 175, 141, 32, 18, 88, 3, 83, 37, 55, 140, 109, 0, 224, 174, 191, 224, 174, 178, 224, 175, 141, 224, 174, 159, 8, 32, 18, 88, 2, 224, 174, 176, 0, 224, 175, 129, 224, 174, 159, 224, 175, 141, 224, 174, 170, 8, 2, 224, 174, 190, 224, 174, 178, 3, 83, 40, 140, 71, 0, 224, 175, 141, 224, 174, 159, 224, 175, 141, 8, 190, 174, 224, 154, 174, 224, 2, 224, 174, 181, 224, 175, 135, 224, 174, 176, 3, 83, 47, 0, 224, 174, 191, 224, 174, 179, 8, 2, 224, 175, 136, 224, 174, 159, 224, 175, 141, 3, 83, 62, 0, 4, 224, 174, 191, 224, 174, 179, 224, 174, 190, 224, 174, 170, 224, 175, 141, 8, 3, 83, 62, 118, 48, 0, 224, 175, 141, 224, 174, 179, 224, 174, 190, 224, 174, 170, 224, 175, 141, 8, 0, 224, 175, 141, 224, 174, 154, 1, 133, 174, 224, 2, 224, 174, 178, 3, 83, 88, 109, 0, 4, 8, 2, 224, 174, 149, 224, 175, 141, 224, 174, 176, 224, 175, 129, 224, 174, 164, 224, 175, 128, 224, 174, 169, 3, 83, 109, 0, 8, 2, 224, 174, 169, 224, 174, 178, 0, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 164, 224, 174, 190, 32, 0, 8, 2, 224, 174, 176, 224, 174, 191, 224, 174, 164, 224, 174, 190, 224, 174, 181, 0, 8, 2, 224, 174, 176, 224, 175, 141, 224, 174, 169, 224, 174, 191, 224, 174, 154, 224, 175, 141, 224, 174, 154, 224, 174, 176, 0, 8, 2, 224, 174, 176, 224, 175, 141, 224, 174, 178, 224, 174, 190, 224, 174, 153, 224, 175, 141, 0, 8, 141, 175, 224, 169, 174, 224, 149, 174, 224, 2, 224, 174, 176, 224, 175, 141, 224, 174, 174, 0, 224, 175, 141, 224, 174, 170, 1, 134, 174, 224, 2, 224, 174, 176, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 224, 175, 141, 224, 174, 170, 1, 190, 174, 224, 169, 174, 224, 141, 175, 224, 169, 174, 224, 134, 175, 224, 164, 174, 224, 2, 224, 174, 176, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 224, 175, 141, 224, 174, 170, 224, 174, 191, 1, 190, 174, 224, 169, 174, 224, 141, 175, 224, 169, 174, 224, 134, 175, 224, 164, 174, 224, 2, 224, 174, 176, 224, 174, 191, 224, 174, 149, 224, 175, 141, 224, 174, 149, 0, 224, 174, 176, 224, 175, 141, 224, 174, 169, 224, 174, 191, 224, 174, 154, 8, 2, 224, 174, 176, 3, 83, 109, 34, 50, 37, 76, 109, 0, 224, 174, 176, 224, 175, 130, 224, 174, 149, 224, 175, 141, 8, 3, 83, 109, 34, 152, 49, 0, 224, 174, 190, 224, 174, 164, 8, 2, 224, 174, 191, 224, 174, 174, 224, 174, 190, 3, 83, 118, 47, 0, 224, 174, 190, 224, 174, 178, 224, 175, 141, 224, 174, 159, 8, 191, 174, 224, 159, 174, 224, 3, 83, 118, 55, 140, 149, 0, 224, 175, 139, 224, 174, 149, 8, 2, 224, 174, 184, 3, 83, 119, 49, 109, 0, 4, 224, 175, 139, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 175, 139, 224, 174, 149, 224, 174, 191, 224, 174, 176, 224, 174, 190, 224, 174, 170, 8, 2, 224, 174, 176, 3, 83, 119, 140, 140, 119, 81, 34, 118, 83, 109, 0, 224, 175, 139, 224, 174, 159, 224, 175, 141, 224, 174, 159, 224, 175, 139, 224, 174, 149, 224, 175, 141, 224, 174, 176, 224, 174, 190, 224, 174, 170, 8, 2, 224, 174, 176, 0, 4, 224, 174, 181, 224, 175, 129, 224, 174, 163, 224, 175, 141, 224, 174, 159, 8, 2, 224, 174, 169, 3, 83, 135, 66, 140, 109, 0, 224, 175, 140, 224, 174, 163, 224, 175, 141, 224, 174, 159, 8, 2, 224, 174, 169, 0, 4, 1, 141, 175, 224, 178, 174, 224, 190, 174, 224, 159, 174, 224, 133, 174, 224, 3, 83, 149, 0, 8, 128, 175, 224, 176, 174, 224, 134, 175, 224, 183, 174, 224, 2, 12, 0, 8, 128, 175, 224, 176, 174, 224, 183, 174, 224, 2, 12, 0, 8, 130, 175, 224, 176, 174, 224, 141, 175, 224, 170, 174, 224, 0, 8, 141, 175, 224, 178, 174, 224, 190, 174, 224, 159, 174, 224, 129, 175, 224, 176, 174, 224, 0, 7, 6, 1, 47, 0, 4, 2, 17, 66, 3, 65, 0, 224, 174, 191, 8, 2, 224, 174, 175, 224, 175, 130, 0, 224, 174, 191, 8, 18, 72, 154, 174, 224, 2, 224, 174, 175, 0, 3, 65, 109, 0, 7, 6, 1, 48, 0, 2, 17, 66, 3, 57, 0, 3, 57, 109, 0, 7, 6, 1, 49, 0, 4, 2, 17, 66, 3, 34, 0, 224, 174, 191, 8, 164, 174, 224, 191, 174, 224, 168, 174, 224, 2, 224, 174, 154, 224, 174, 169, 0, 224, 174, 191, 8, 174, 174, 224, 191, 174, 224, 181, 174, 224, 2, 224, 174, 154, 0, 224, 175, 129, 1, 191, 174, 224, 164, 174, 224, 133, 174, 224, 2, 224, 174, 183, 224, 175, 141, 224, 174, 159, 0, 224, 175, 129, 8, 191, 174, 224, 164, 174, 224, 176, 174, 224, 129, 175, 224, 164, 174, 224, 2, 224, 174, 183, 224, 175, 141, 224, 174, 159, 0, 3, 34, 109, 0, 7, 6, 1, 50, 0, 2, 17, 66, 3, 51, 0, 3, 51, 109, 0, 224, 175, 141, 224, 174, 154, 3, 76, 12, 149, 0, 224, 175, 141, 2, 224, 174, 177, 3, 140, 0, 7, 6, 1, 51, 0, 4, 2, 17, 66, 3, 55, 0, 224, 174, 191, 8, 149, 174, 224, 2, 224, 174, 175, 224, 174, 190, 224, 174, 163, 0, 3, 55, 109, 0, 224, 175, 141, 8, 181, 174, 224, 190, 174, 224, 149, 174, 224, 2, 224, 174, 164, 224, 175, 129, 224, 174, 177, 224, 175, 136, 3, 140, 0, 7, 6, 1, 52, 0, 2, 17, 66, 3, 62, 0, 3, 62, 109, 0, 224, 175, 141, 1, 137, 174, 224, 2, 224, 174, 164, 224, 175, 129, 224, 174, 177, 224, 175, 136, 3, 140, 0, 224, 175, 141, 224, 174, 164, 8, 149, 174, 224, 141, 175, 224, 149, 174, 224, 174, 174, 224, 2, 224, 175, 138, 224, 174, 149, 224, 175, 136, 3, 140, 47, 0, 7, 6, 1, 53, 0, 2, 17, 66, 3, 92, 0, 3, 92, 109, 0, 7, 6, 1, 54, 0, 4, 2, 17, 66, 3, 84, 0, 224, 174, 191, 2, 224, 174, 175, 224, 175, 130, 224, 174, 149, 0, 224, 174, 191, 8, 2, 224, 174, 175, 224, 174, 190, 0, 3, 84, 109, 0, 7, 6, 1, 55, 0, 2, 17, 66, 3, 91, 0, 3, 91, 109, 0, 7, 6, 1, 56, 0, 2, 17, 66, 3, 93, 0, 3, 93, 109, 0, 7, 6, 1, 57, 0, 2, 17, 66, 3, 89, 0, 3, 89, 109, 0, 7, 6, 1, 58, 0, 2, 17, 66, 3, 108, 0, 3, 108, 109, 0, 7, 6, 1, 78, 0, 4, 3, 150, 0, 2, 32, 0, 7, 6, 224, 164, 0, 3, 21, 104, 105, 0, 7, 6, 224, 165, 0, 3, 21, 104, 105, 0, 7, 6, 224, 174, 0, 130, 3, 0, 133, 3, 35, 0, 142, 3, 36, 0, 191, 3, 37, 0, 142, 8, 3, 38, 36, 0, 143, 8, 3, 38, 114, 0, 142, 224, 174, 170, 2, 224, 175, 141, 224, 174, 176, 224, 174, 178, 3, 38, 114, 48, 0, 148, 224, 174, 191, 3, 39, 62, 37, 0, 136, 3, 112, 0, 143, 3, 114, 0, 4, 134, 3, 118, 0, 190, 0, 147, 3, 119, 0, 138, 3, 123, 0, 144, 3, 134, 0, 148, 3, 135, 0, 7, 6, 224, 175, 0, 151, 3, 12, 0, 134, 3, 36, 0, 4, 140, 224, 174, 191, 1, 181, 174, 224, 3, 36, 62, 37, 0, 140, 224, 174, 191, 8, 164, 174, 224, 0, 138, 3, 39, 0, 129, 3, 40, 0, 128, 3, 112, 0, 135, 3, 114, 0, 139, 3, 119, 0, 130, 3, 123, 0, 136, 3, 134, 0, 4, 134, 224, 174, 179, 8, 154, 174, 224, 3, 135, 0, 134, 224, 174, 179, 8, 170, 174, 224, 0, 134, 224, 174, 179, 8, 174, 174, 224, 2, 224, 174, 169, 0, 134, 224, 174, 179, 8, 174, 174, 224, 2, 224, 174, 184, 0, 134, 224, 174, 179, 8, 181, 174, 224, 2, 224, 174, 181, 224, 174, 190, 224, 174, 178, 0, 140, 0, 7, 6, 0, 224, 175, 141, 3, 0, 4, 45, 1, 32, 17, 65, 2, 32, 15, 3, 10, 0, 45, 1, 32, 17, 67, 2, 32, 15, 0, 46, 1, 15, 2, 15, 12, 3, 10, 48, 40, 62, 62, 37, 0, 114, 115, 1, 19, 2, 32, 46, 15, 3, 34, 123, 48, 112, 88, 0, 45, 8, 32, 2, 32, 15, 3, 49, 109, 92, 37, 47, 47, 109, 55, 0, 36, 3, 72, 39, 55, 109, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts62 = FileInMemory_createWithData (88227, reinterpret_cast (&espeakdata_dicts62_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/ta_dict", U"ta"); Collection_addItem (me.peek(), espeakdata_dicts62.transfer()); static unsigned char espeakdata_dicts63_data[3365] = { 0, 4, 0, 0, 164, 9, 0, 0, 0, 0, 0, 0, 0, 6, 65, 4, 114, 57, 0, 0, 0, 0, 0, 6, 65, 8, 71, 112, 0, 0, 0, 0, 0, 6, 65, 12, 89, 112, 0, 0, 0, 0, 0, 6, 65, 16, 72, 112, 0, 0, 0, 0, 0, 5, 65, 20, 112, 0, 0, 0, 0, 0, 6, 65, 24, 116, 83, 0, 0, 0, 0, 0, 6, 65, 28, 75, 112, 0, 0, 0, 0, 0, 6, 65, 32, 114, 76, 0, 0, 0, 0, 0, 6, 65, 36, 118, 57, 0, 0, 9, 1, 37, 97, 118, 47, 35, 65, 0, 0, 0, 0, 7, 65, 40, 75, 114, 57, 0, 0, 0, 12, 1, 42, 50, 35, 49, 93, 35, 47, 34, 35, 0, 0, 10, 1, 43, 49, 123, 141, 37, 49, 35, 0, 0, 7, 65, 44, 49, 114, 57, 0, 0, 0, 0, 8, 1, 47, 89, 55, 118, 93, 0, 0, 6, 65, 48, 116, 55, 0, 0, 0, 0, 0, 6, 65, 52, 116, 65, 0, 0, 0, 0, 0, 6, 65, 56, 116, 50, 0, 0, 0, 0, 0, 5, 65, 60, 119, 0, 0, 0, 0, 0, 6, 65, 64, 48, 112, 0, 0, 0, 0, 0, 7, 65, 68, 49, 57, 123, 0, 0, 0, 0, 0, 6, 65, 72, 118, 34, 0, 0, 0, 0, 0, 6, 65, 76, 116, 89, 0, 0, 0, 0, 14, 4, 95, 48, 67, 48, 84, 35, 50, 72, 35, 55, 40, 0, 0, 6, 65, 80, 138, 112, 0, 0, 0, 0, 0, 6, 65, 84, 57, 123, 0, 0, 0, 0, 0, 6, 65, 88, 84, 112, 0, 0, 0, 0, 0, 13, 1, 92, 71, 57, 118, 49, 35, 89, 55, 118, 93, 0, 11, 65, 92, 72, 109, 71, 109, 55, 57, 123, 0, 0, 0, 0, 0, 15, 4, 95, 49, 77, 49, 39, 49, 35, 84, 36, 57, 57, 37, 0, 7, 65, 96, 116, 49, 89, 0, 0, 12, 4, 95, 49, 77, 50, 55, 35, 49, 93, 35, 0, 0, 11, 4, 95, 49, 77, 51, 49, 39, 47, 37, 0, 0, 0, 7, 65, 100, 58, 118, 57, 0, 0, 0, 0, 0, 7, 65, 104, 88, 116, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 4, 95, 4, 16, 20, 10, 72, 4, 35, 97, 118, 65, 49, 35, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 5, 95, 48, 77, 50, 24, 55, 35, 49, 93, 35, 55, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 224, 176, 163, 224, 177, 141, 37, 66, 0, 11, 6, 224, 176, 155, 224, 177, 141, 37, 144, 0, 12, 5, 95, 48, 77, 49, 24, 84, 36, 55, 40, 0, 0, 0, 0, 0, 11, 6, 224, 176, 185, 224, 177, 141, 37, 107, 0, 11, 6, 224, 176, 161, 224, 177, 141, 37, 141, 0, 11, 6, 224, 176, 153, 224, 177, 141, 37, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 5, 95, 48, 77, 51, 24, 49, 39, 47, 55, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 224, 176, 179, 224, 177, 141, 37, 62, 0, 11, 6, 224, 176, 171, 224, 177, 141, 37, 136, 0, 0, 0, 0, 0, 12, 6, 224, 177, 153, 224, 177, 141, 37, 72, 88, 0, 11, 6, 224, 176, 177, 224, 177, 141, 37, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 224, 176, 183, 224, 177, 141, 37, 93, 0, 11, 6, 224, 176, 159, 224, 177, 141, 37, 140, 0, 11, 6, 224, 176, 151, 224, 177, 141, 37, 81, 0, 0, 0, 0, 0, 11, 6, 224, 176, 181, 224, 177, 141, 37, 84, 0, 11, 6, 224, 176, 157, 224, 177, 141, 37, 145, 0, 11, 6, 224, 176, 149, 224, 177, 141, 37, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 3, 95, 49, 1, 39, 49, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 224, 176, 175, 224, 177, 141, 37, 57, 0, 11, 6, 224, 176, 167, 224, 177, 141, 37, 139, 0, 0, 0, 0, 0, 11, 6, 224, 176, 173, 224, 177, 141, 37, 137, 0, 11, 6, 224, 176, 165, 224, 177, 141, 37, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 51, 88, 65, 40, 48, 48, 134, 0, 0, 13, 3, 95, 48, 67, 84, 35, 50, 72, 35, 55, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 49, 67, 39, 49, 35, 84, 35, 50, 72, 35, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 49, 57, 48, 35, 65, 72, 39, 65, 65, 35, 72, 37, 0, 0, 17, 3, 95, 49, 56, 48, 35, 72, 139, 36, 50, 37, 65, 37, 72, 37, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 49, 49, 48, 35, 72, 35, 49, 39, 50, 141, 40, 0, 0, 0, 14, 3, 95, 49, 51, 48, 35, 72, 35, 65, 123, 141, 123, 0, 0, 14, 3, 95, 49, 50, 48, 35, 50, 50, 36, 65, 141, 40, 0, 0, 14, 3, 95, 49, 53, 48, 35, 72, 37, 107, 114, 50, 40, 0, 0, 15, 3, 95, 49, 52, 48, 35, 139, 50, 118, 55, 40, 81, 40, 0, 0, 14, 3, 95, 49, 55, 48, 35, 72, 37, 107, 114, 141, 40, 0, 0, 14, 3, 95, 49, 54, 48, 35, 72, 35, 107, 118, 34, 40, 0, 0, 0, 11, 3, 95, 55, 88, 141, 36, 137, 71, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 95, 49, 88, 48, 35, 72, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 50, 88, 37, 34, 35, 84, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 63, 63, 35, 49, 93, 35, 34, 35, 65, 0, 0, 0, 0, 12, 3, 95, 52, 88, 50, 35, 55, 40, 137, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 95, 53, 88, 57, 118, 137, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 54, 88, 35, 34, 35, 84, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 56, 88, 57, 36, 50, 35, 137, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 57, 88, 47, 39, 65, 137, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 48, 77, 50, 55, 35, 49, 93, 35, 55, 35, 0, 0, 12, 4, 95, 48, 77, 51, 49, 39, 47, 55, 35, 0, 0, 0, 6, 131, 224, 176, 134, 76, 11, 4, 95, 48, 77, 49, 84, 36, 55, 35, 0, 0, 0, 8, 3, 224, 177, 140, 148, 135, 0, 0, 11, 3, 224, 177, 141, 84, 39, 47, 47, 40, 0, 6, 131, 224, 176, 133, 76, 0, 8, 3, 224, 177, 138, 18, 39, 0, 8, 3, 224, 176, 130, 35, 50, 0, 0, 9, 3, 224, 177, 139, 148, 119, 12, 0, 8, 3, 224, 176, 131, 35, 107, 0, 0, 8, 3, 224, 177, 136, 148, 134, 0, 0, 8, 3, 224, 176, 129, 35, 65, 0, 0, 8, 3, 224, 177, 134, 18, 36, 0, 0, 9, 3, 224, 177, 135, 148, 114, 12, 0, 0, 9, 3, 224, 177, 132, 148, 34, 123, 0, 0, 0, 9, 3, 224, 177, 130, 148, 123, 12, 0, 0, 9, 3, 224, 177, 131, 18, 34, 40, 0, 0, 9, 3, 224, 177, 128, 148, 112, 12, 0, 0, 8, 3, 224, 177, 129, 18, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 131, 224, 176, 166, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 3, 224, 176, 190, 148, 118, 12, 0, 0, 8, 3, 224, 176, 191, 18, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 2, 194, 169, 49, 118, 48, 112, 34, 134, 140, 0, 0, 9, 2, 194, 182, 84, 114, 34, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 224, 176, 156, 224, 177, 141, 37, 79, 0, 0, 0, 0, 0, 11, 6, 224, 176, 162, 224, 177, 141, 37, 143, 0, 11, 6, 224, 176, 154, 224, 177, 141, 37, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 224, 176, 160, 224, 177, 141, 37, 142, 0, 0, 0, 0, 0, 17, 2, 95, 33, 118, 97, 80, 35, 34, 57, 118, 34, 138, 35, 49, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 6, 224, 176, 172, 224, 177, 141, 37, 71, 0, 11, 6, 224, 176, 164, 224, 177, 141, 37, 47, 0, 10, 2, 95, 45, 107, 134, 83, 35, 50, 0, 0, 9, 2, 95, 44, 49, 118, 65, 118, 0, 0, 9, 2, 95, 51, 65, 123, 141, 40, 0, 0, 10, 2, 95, 50, 34, 36, 50, 141, 40, 0, 0, 11, 6, 224, 176, 178, 224, 177, 141, 37, 55, 0, 11, 6, 224, 176, 170, 224, 177, 141, 37, 48, 0, 10, 2, 95, 49, 39, 49, 35, 140, 37, 0, 0, 10, 2, 95, 48, 89, 40, 50, 50, 35, 0, 0, 8, 2, 95, 55, 114, 141, 40, 0, 0, 8, 2, 95, 54, 118, 34, 40, 0, 0, 8, 2, 95, 53, 134, 72, 40, 0, 0, 10, 2, 95, 52, 50, 118, 55, 81, 40, 0, 0, 14, 2, 95, 59, 89, 36, 65, 112, 49, 119, 55, 35, 50, 0, 0, 10, 2, 95, 58, 49, 119, 55, 35, 50, 0, 0, 12, 2, 95, 57, 47, 39, 65, 65, 37, 72, 37, 0, 0, 13, 2, 95, 56, 38, 36, 50, 37, 65, 37, 72, 37, 0, 0, 16, 2, 95, 63, 48, 34, 35, 97, 50, 118, 34, 138, 35, 49, 35, 0, 0, 0, 12, 6, 224, 177, 152, 224, 177, 141, 37, 47, 89, 0, 11, 6, 224, 176, 184, 224, 177, 141, 37, 89, 0, 11, 6, 224, 176, 176, 224, 177, 141, 37, 34, 0, 11, 6, 224, 176, 152, 224, 177, 141, 37, 147, 0, 0, 0, 0, 0, 11, 6, 224, 176, 182, 224, 177, 141, 37, 97, 0, 11, 6, 224, 176, 158, 224, 177, 141, 37, 67, 0, 11, 6, 224, 176, 150, 224, 177, 141, 37, 146, 0, 9, 134, 224, 176, 146, 224, 176, 149, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 95, 95, 35, 65, 141, 35, 34, 15, 89, 49, 119, 34, 0, 0, 0, 11, 6, 224, 176, 168, 224, 177, 141, 37, 50, 0, 0, 0, 0, 0, 11, 6, 224, 176, 174, 224, 177, 141, 37, 65, 0, 11, 6, 224, 176, 166, 224, 177, 141, 37, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 20, 0, 0, 102, 12, 0, 0, 48, 0, 0, 0, 103, 12, 0, 0, 49, 0, 0, 0, 104, 12, 0, 0, 50, 0, 0, 0, 105, 12, 0, 0, 51, 0, 0, 0, 106, 12, 0, 0, 52, 0, 0, 0, 107, 12, 0, 0, 53, 0, 0, 0, 108, 12, 0, 0, 54, 0, 0, 0, 109, 12, 0, 0, 55, 0, 0, 0, 110, 12, 0, 0, 56, 0, 0, 0, 111, 12, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 6, 1, 6, 0, 3, 35, 0, 7, 6, 1, 7, 0, 3, 118, 0, 7, 6, 1, 8, 0, 3, 37, 0, 7, 6, 1, 9, 0, 3, 112, 0, 7, 6, 1, 10, 0, 3, 40, 0, 7, 6, 1, 11, 0, 3, 123, 0, 7, 6, 1, 12, 0, 3, 34, 40, 0, 7, 6, 1, 13, 0, 3, 45, 0, 7, 6, 1, 15, 0, 3, 36, 0, 8, 3, 38, 36, 0, 7, 6, 1, 16, 0, 3, 114, 0, 7, 6, 1, 17, 0, 3, 134, 0, 7, 6, 1, 19, 0, 3, 39, 0, 7, 6, 1, 20, 0, 3, 119, 0, 7, 6, 1, 21, 0, 3, 135, 0, 7, 6, 1, 22, 0, 2, 17, 66, 3, 49, 0, 3, 49, 35, 0, 7, 6, 1, 23, 0, 2, 17, 66, 3, 146, 0, 3, 146, 35, 0, 7, 6, 1, 24, 0, 2, 17, 66, 3, 81, 0, 3, 81, 35, 0, 7, 6, 1, 25, 0, 2, 17, 66, 3, 147, 0, 3, 147, 35, 0, 7, 6, 1, 26, 0, 2, 17, 66, 3, 68, 0, 3, 68, 35, 0, 7, 6, 1, 27, 0, 2, 17, 66, 3, 80, 0, 3, 80, 35, 0, 7, 6, 1, 28, 0, 2, 17, 66, 3, 144, 0, 3, 144, 35, 0, 7, 6, 1, 29, 0, 2, 17, 66, 3, 79, 0, 3, 79, 35, 0, 7, 6, 1, 30, 0, 2, 17, 66, 3, 145, 0, 3, 145, 35, 0, 7, 6, 1, 31, 0, 2, 17, 66, 3, 67, 0, 3, 67, 35, 0, 7, 6, 1, 32, 0, 2, 17, 66, 3, 140, 0, 3, 140, 35, 0, 7, 6, 1, 33, 0, 2, 17, 66, 3, 142, 0, 3, 142, 35, 0, 7, 6, 1, 34, 0, 2, 17, 66, 3, 141, 0, 3, 141, 35, 0, 7, 6, 1, 35, 0, 2, 17, 66, 3, 143, 0, 3, 143, 35, 0, 7, 6, 1, 36, 0, 2, 17, 66, 3, 66, 0, 3, 66, 35, 0, 7, 6, 1, 37, 0, 2, 17, 66, 3, 47, 0, 3, 47, 35, 0, 7, 6, 1, 38, 0, 2, 17, 66, 3, 138, 0, 3, 138, 35, 0, 7, 6, 1, 39, 0, 2, 17, 66, 3, 72, 0, 3, 72, 35, 0, 7, 6, 1, 40, 0, 2, 17, 66, 3, 139, 0, 3, 139, 35, 0, 7, 6, 1, 41, 0, 2, 17, 66, 3, 50, 0, 3, 50, 35, 0, 7, 6, 1, 43, 0, 2, 17, 66, 3, 48, 0, 3, 48, 35, 0, 7, 6, 1, 44, 0, 2, 17, 66, 3, 136, 0, 3, 136, 35, 0, 7, 6, 1, 45, 0, 2, 17, 66, 3, 71, 0, 3, 71, 35, 0, 7, 6, 1, 46, 0, 2, 17, 66, 3, 137, 0, 3, 137, 35, 0, 7, 6, 1, 47, 0, 2, 17, 66, 3, 65, 0, 3, 65, 35, 0, 7, 6, 1, 48, 0, 2, 17, 66, 3, 57, 0, 3, 57, 35, 0, 7, 6, 1, 49, 0, 2, 17, 66, 3, 34, 0, 3, 34, 35, 0, 7, 6, 1, 50, 0, 2, 17, 66, 3, 34, 0, 3, 34, 35, 0, 7, 6, 1, 51, 0, 2, 17, 66, 3, 55, 0, 3, 55, 35, 0, 7, 6, 1, 52, 0, 2, 17, 66, 3, 62, 0, 3, 62, 35, 0, 7, 6, 1, 54, 0, 2, 17, 66, 3, 84, 0, 3, 84, 35, 0, 7, 6, 1, 55, 0, 2, 17, 66, 3, 97, 0, 3, 97, 35, 0, 7, 6, 1, 56, 0, 2, 17, 66, 3, 93, 0, 3, 93, 35, 0, 7, 6, 1, 57, 0, 2, 17, 66, 3, 89, 0, 3, 89, 35, 0, 7, 6, 1, 58, 0, 2, 17, 66, 3, 107, 0, 3, 107, 35, 0, 7, 6, 1, 89, 0, 2, 17, 66, 3, 47, 89, 0, 3, 47, 89, 35, 0, 7, 6, 1, 90, 0, 2, 17, 66, 3, 72, 88, 0, 3, 72, 88, 35, 0, 7, 6, 1, 97, 0, 3, 34, 40, 0, 7, 6, 1, 98, 0, 3, 45, 0, 7, 6, 224, 164, 0, 3, 21, 104, 105, 0, 7, 6, 224, 165, 0, 3, 21, 104, 105, 0, 7, 6, 224, 176, 0, 191, 3, 37, 0, 130, 3, 65, 0, 131, 3, 107, 0, 190, 3, 118, 0, 7, 6, 224, 177, 0, 141, 3, 0, 4, 149, 3, 12, 0, 150, 0, 131, 3, 34, 40, 0, 134, 3, 36, 0, 138, 3, 39, 0, 129, 3, 40, 0, 132, 3, 44, 12, 0, 128, 3, 112, 0, 135, 3, 114, 0, 139, 3, 119, 0, 130, 3, 123, 0, 136, 3, 134, 0, 140, 3, 135, 0, 7, 6, 0, 36, 3, 141, 118, 55, 35, 34, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts63 = FileInMemory_createWithData (3364, reinterpret_cast (&espeakdata_dicts63_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/te_dict", U"te"); Collection_addItem (me.peek(), espeakdata_dicts63.transfer()); static unsigned char espeakdata_dicts64_data[3073] = { 0, 4, 0, 0, 24, 10, 0, 0, 0, 0, 0, 0, 0, 32, 4, 95, 56, 77, 49, 72, 37, 49, 6, 36, 47, 36, 6, 115, 36, 6, 71, 39, 6, 34, 39, 71, 35, 6, 71, 39, 71, 36, 72, 37, 0, 5, 65, 4, 35, 0, 0, 41, 4, 95, 56, 77, 50, 72, 37, 49, 6, 36, 47, 36, 76, 36, 65, 35, 49, 106, 6, 39, 12, 55, 39, 6, 71, 39, 6, 34, 39, 71, 35, 6, 71, 39, 71, 36, 72, 37, 12, 0, 0, 0, 0, 9, 65, 8, 71, 37, 12, 37, 12, 0, 0, 0, 0, 0, 9, 65, 12, 89, 37, 12, 37, 12, 0, 0, 0, 0, 0, 9, 65, 16, 72, 37, 12, 37, 12, 0, 0, 0, 0, 0, 8, 65, 20, 37, 12, 37, 12, 0, 0, 0, 0, 0, 8, 65, 24, 36, 12, 83, 39, 0, 0, 0, 0, 0, 8, 65, 28, 81, 37, 12, 37, 0, 0, 0, 0, 7, 195, 44, 19, 129, 72, 8, 6, 195, 48, 243, 129, 76, 0, 8, 65, 32, 36, 37, 76, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 65, 40, 75, 6, 36, 37, 0, 0, 0, 0, 0, 7, 65, 44, 49, 36, 37, 0, 0, 0, 0, 0, 8, 65, 48, 36, 12, 55, 37, 0, 0, 0, 0, 0, 8, 65, 52, 6, 36, 65, 40, 0, 0, 0, 0, 0, 11, 5, 95, 48, 1, 14, 4, 23, 50, 35, 0, 8, 65, 56, 6, 36, 50, 37, 0, 0, 0, 0, 0, 8, 65, 60, 39, 12, 39, 12, 0, 0, 0, 0, 0, 10, 65, 64, 48, 6, 37, 12, 37, 12, 0, 0, 0, 0, 0, 7, 65, 68, 49, 57, 40, 0, 0, 0, 0, 0, 7, 65, 72, 35, 53, 36, 0, 0, 0, 0, 0, 9, 65, 76, 6, 36, 12, 89, 37, 0, 0, 0, 7, 195, 20, 225, 64, 76, 28, 0, 0, 10, 65, 80, 47, 6, 37, 12, 37, 12, 0, 0, 0, 0, 0, 8, 65, 84, 40, 12, 40, 12, 0, 0, 0, 0, 0, 10, 65, 88, 84, 6, 37, 12, 37, 12, 0, 0, 0, 0, 6, 195, 28, 18, 193, 76, 6, 195, 92, 18, 193, 76, 0, 11, 65, 92, 72, 35, 71, 39, 55, 57, 40, 0, 0, 0, 0, 0, 17, 4, 95, 49, 77, 49, 23, 6, 89, 20, 6, 37, 49, 36, 47, 36, 0, 10, 65, 96, 36, 49, 6, 36, 89, 36, 0, 0, 25, 4, 95, 49, 77, 50, 72, 37, 49, 6, 36, 47, 36, 76, 36, 55, 36, 49, 106, 6, 39, 12, 55, 39, 0, 0, 0, 0, 8, 65, 100, 58, 6, 35, 37, 0, 0, 0, 0, 0, 10, 65, 104, 88, 6, 36, 12, 47, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 4, 95, 49, 67, 48, 55, 36, 49, 106, 6, 39, 55, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 196, 44, 243, 148, 20, 72, 8, 7, 196, 48, 83, 142, 4, 76, 0, 0, 6, 195, 16, 147, 15, 76, 0, 0, 6, 195, 52, 243, 5, 76, 0, 0, 0, 0, 0, 19, 4, 95, 50, 77, 49, 72, 37, 49, 6, 36, 47, 36, 48, 6, 36, 72, 37, 0, 0, 30, 4, 95, 50, 77, 50, 72, 37, 49, 6, 36, 47, 36, 76, 36, 65, 35, 49, 106, 6, 39, 12, 55, 39, 48, 6, 36, 72, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 45, 112, 76, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 24, 16, 72, 28, 6, 194, 24, 16, 72, 28, 0, 0, 0, 0, 0, 0, 19, 4, 95, 4, 16, 20, 83, 36, 12, 106, 36, 55, 40, 6, 35, 12, 50, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 4, 95, 51, 77, 49, 72, 37, 49, 6, 36, 47, 36, 47, 6, 35, 12, 53, 39, 0, 0, 31, 4, 95, 51, 77, 50, 72, 37, 49, 6, 36, 47, 36, 76, 36, 65, 35, 49, 106, 6, 39, 12, 55, 39, 47, 6, 35, 12, 53, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 4, 240, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 100, 243, 129, 76, 28, 7, 195, 100, 243, 129, 76, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 56, 224, 64, 76, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 4, 95, 53, 77, 49, 72, 37, 49, 6, 36, 47, 36, 105, 6, 35, 12, 50, 39, 0, 0, 0, 0, 30, 4, 95, 53, 77, 50, 72, 37, 49, 6, 36, 47, 36, 76, 36, 65, 35, 49, 106, 6, 39, 12, 55, 39, 105, 6, 35, 50, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 3, 95, 51, 88, 65, 35, 89, 6, 39, 12, 65, 36, 6, 35, 65, 35, 12, 53, 39, 0, 0, 14, 3, 95, 48, 67, 55, 36, 49, 106, 6, 39, 55, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 48, 16, 72, 28, 0, 0, 19, 3, 95, 50, 67, 23, 65, 35, 49, 106, 6, 39, 55, 39, 48, 36, 72, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 3, 95, 51, 67, 23, 65, 35, 49, 106, 6, 39, 55, 39, 47, 6, 35, 12, 53, 39, 0, 0, 0, 0, 26, 4, 95, 54, 77, 49, 72, 37, 49, 6, 36, 47, 36, 115, 6, 36, 6, 47, 107, 6, 35, 47, 35, 34, 39, 0, 0, 0, 0, 35, 4, 95, 54, 77, 50, 72, 37, 49, 6, 36, 47, 36, 76, 36, 65, 35, 49, 106, 6, 39, 12, 55, 39, 6, 47, 107, 6, 35, 6, 47, 35, 34, 39, 0, 0, 23, 3, 95, 55, 88, 65, 35, 89, 6, 39, 12, 65, 36, 6, 35, 6, 91, 6, 40, 12, 48, 35, 0, 0, 19, 3, 95, 52, 67, 23, 65, 35, 49, 106, 6, 39, 55, 39, 6, 42, 50, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 3, 95, 53, 67, 23, 65, 35, 49, 106, 6, 39, 55, 39, 105, 6, 35, 12, 50, 39, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 49, 88, 55, 36, 89, 6, 39, 12, 65, 36, 0, 0, 24, 3, 95, 54, 67, 23, 65, 35, 49, 106, 6, 39, 55, 39, 6, 47, 107, 6, 35, 47, 35, 34, 39, 0, 0, 0, 0, 0, 0, 0, 0, 18, 3, 95, 50, 88, 65, 35, 89, 6, 39, 12, 65, 36, 48, 36, 72, 37, 0, 0, 20, 3, 95, 55, 67, 65, 35, 49, 106, 6, 39, 55, 39, 91, 6, 40, 12, 48, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 3, 95, 56, 67, 65, 35, 49, 106, 6, 39, 55, 39, 6, 35, 6, 65, 35, 6, 34, 39, 71, 35, 6, 71, 39, 71, 36, 72, 37, 12, 0, 0, 0, 0, 0, 0, 0, 0, 21, 3, 95, 52, 88, 65, 35, 89, 6, 39, 12, 65, 36, 6, 35, 65, 35, 12, 50, 36, 0, 0, 34, 3, 95, 57, 67, 65, 35, 49, 106, 6, 39, 55, 39, 6, 35, 6, 65, 35, 6, 34, 39, 71, 35, 6, 71, 39, 6, 50, 6, 50, 81, 58, 36, 0, 0, 0, 0, 0, 0, 0, 6, 194, 48, 80, 72, 8, 0, 24, 3, 95, 53, 88, 65, 35, 89, 6, 39, 12, 65, 36, 6, 35, 65, 35, 105, 6, 35, 12, 50, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 3, 95, 54, 88, 65, 35, 89, 6, 39, 12, 65, 36, 6, 35, 47, 107, 6, 35, 47, 35, 34, 39, 0, 0, 0, 0, 0, 19, 4, 95, 55, 77, 49, 72, 37, 49, 6, 36, 47, 36, 91, 40, 12, 48, 35, 0, 0, 0, 0, 30, 4, 95, 55, 77, 50, 72, 37, 49, 6, 36, 47, 36, 76, 36, 65, 35, 49, 106, 6, 39, 12, 55, 39, 91, 40, 12, 48, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 3, 95, 56, 88, 65, 35, 89, 6, 39, 12, 65, 36, 6, 35, 71, 39, 6, 34, 39, 71, 35, 6, 71, 36, 72, 37, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 3, 95, 57, 88, 65, 35, 89, 6, 39, 12, 65, 36, 6, 35, 6, 34, 39, 71, 35, 6, 71, 39, 6, 50, 81, 58, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 72, 243, 129, 76, 7, 195, 92, 83, 129, 76, 28, 7, 195, 8, 243, 129, 72, 28, 16, 4, 95, 48, 77, 52, 23, 71, 37, 55, 37, 6, 39, 50, 37, 0, 0, 0, 0, 16, 4, 95, 48, 77, 51, 23, 65, 37, 55, 37, 6, 39, 50, 37, 0, 0, 0, 16, 4, 95, 48, 77, 49, 6, 89, 20, 6, 37, 49, 36, 47, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 81, 50, 1, 44, 16, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 4, 95, 3, 9, 18, 49, 6, 36, 83, 35, 0, 41, 4, 95, 57, 77, 50, 72, 37, 49, 6, 36, 47, 36, 76, 36, 65, 35, 49, 106, 6, 39, 12, 55, 39, 6, 71, 39, 6, 34, 39, 71, 35, 6, 71, 39, 6, 50, 81, 58, 36, 0, 0, 0, 0, 33, 4, 95, 57, 77, 49, 72, 37, 49, 6, 36, 47, 36, 6, 115, 36, 6, 71, 39, 6, 34, 39, 71, 35, 6, 71, 39, 6, 50, 81, 58, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 52, 240, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 45, 85, 193, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 196, 57, 68, 215, 4, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 196, 44, 115, 204, 60, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 92, 16, 72, 28, 0, 0, 0, 0, 0, 0, 6, 195, 56, 22, 65, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 45, 112, 64, 72, 28, 7, 195, 45, 112, 64, 72, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 4, 95, 52, 77, 50, 72, 37, 49, 6, 36, 47, 36, 76, 36, 65, 35, 49, 106, 6, 39, 12, 55, 39, 42, 50, 36, 0, 0, 17, 4, 95, 52, 77, 49, 72, 37, 49, 6, 36, 47, 36, 42, 50, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 2, 95, 51, 47, 6, 35, 12, 53, 39, 0, 0, 10, 2, 95, 50, 48, 6, 36, 72, 37, 0, 0, 12, 2, 95, 49, 50, 6, 50, 81, 58, 36, 12, 0, 0, 13, 2, 95, 48, 55, 36, 83, 6, 36, 12, 55, 35, 0, 0, 11, 2, 95, 55, 89, 6, 40, 12, 48, 35, 0, 0, 13, 2, 95, 54, 47, 107, 6, 35, 47, 35, 34, 39, 0, 0, 11, 2, 95, 53, 105, 6, 35, 12, 50, 39, 0, 0, 9, 2, 95, 52, 6, 42, 50, 36, 0, 0, 0, 0, 16, 2, 95, 57, 34, 39, 71, 35, 6, 50, 6, 50, 81, 58, 36, 0, 0, 6, 194, 100, 16, 72, 28, 16, 2, 95, 56, 34, 39, 71, 35, 6, 71, 39, 71, 36, 72, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 52, 209, 64, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 97, 0, 4, 3, 35, 0, 2, 32, 0, 8, 2, 17, 67, 0, 8, 17, 67, 0, 4, 2, 115, 3, 35, 12, 0, 97, 0, 7, 6, 98, 0, 3, 71, 0, 3, 82, 0, 7, 6, 99, 0, 3, 49, 0, 104, 3, 76, 0, 7, 6, 100, 0, 3, 72, 0, 104, 3, 86, 0, 7, 6, 101, 0, 3, 36, 0, 101, 3, 36, 12, 0, 1, 115, 3, 37, 0, 7, 6, 102, 0, 3, 83, 0, 7, 6, 103, 0, 4, 3, 81, 0, 8, 107, 0, 104, 3, 100, 0, 7, 6, 104, 0, 108, 3, 105, 0, 3, 107, 0, 7, 6, 105, 0, 3, 37, 0, 105, 3, 37, 12, 0, 7, 6, 106, 0, 3, 79, 0, 7, 6, 107, 0, 3, 49, 0, 104, 3, 101, 0, 7, 6, 108, 0, 3, 55, 0, 7, 6, 109, 0, 4, 1, 25, 2, 21, 21, 3, 23, 65, 0, 1, 25, 2, 98, 21, 21, 0, 1, 25, 2, 118, 21, 21, 0, 1, 25, 2, 119, 21, 21, 0, 4, 1, 25, 2, 17, 67, 3, 41, 0, 8, 0, 4, 3, 65, 0, 2, 17, 65, 0, 7, 6, 110, 0, 8, 3, 42, 0, 4, 8, 2, 103, 3, 43, 0, 8, 2, 103, 21, 21, 0, 8, 2, 107, 0, 8, 2, 107, 21, 21, 0, 4, 3, 50, 0, 2, 17, 65, 0, 2, 21, 21, 0, 4, 2, 99, 104, 3, 67, 0, 2, 106, 0, 121, 0, 4, 2, 103, 3, 68, 0, 2, 107, 0, 103, 39, 0, 7, 6, 111, 0, 3, 39, 0, 111, 3, 39, 12, 0, 7, 6, 112, 0, 3, 48, 0, 7, 6, 113, 0, 3, 49, 0, 7, 6, 114, 0, 1, 17, 67, 2, 17, 65, 3, 14, 16, 0, 3, 34, 0, 4, 3, 51, 0, 1, 17, 65, 2, 17, 65, 0, 114, 3, 51, 51, 0, 3, 53, 0, 7, 6, 115, 0, 3, 89, 0, 2, 101, 3, 89, 20, 0, 101, 8, 116, 3, 89, 37, 12, 0, 104, 3, 91, 0, 7, 6, 116, 0, 3, 47, 0, 104, 3, 87, 0, 108, 3, 105, 0, 115, 101, 110, 3, 115, 6, 36, 12, 50, 0, 108, 104, 3, 118, 0, 7, 6, 117, 0, 3, 40, 0, 4, 8, 100, 3, 40, 12, 0, 117, 0, 7, 6, 118, 0, 3, 84, 0, 7, 6, 119, 0, 3, 58, 0, 7, 6, 120, 0, 3, 49, 89, 0, 7, 6, 121, 0, 3, 57, 0, 7, 6, 122, 0, 3, 88, 0, 7, 6, 0, 4, 42, 1, 42, 2, 42, 3, 0, 42, 42, 3, 0, 42, 1, 42, 42, 2, 32, 3, 24, 0, 37, 3, 35, 89, 37, 55, 37, 65, 37, 35, 0, 42, 3, 67, 39, 47, 35, 0, 36, 3, 72, 39, 55, 35, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts64 = FileInMemory_createWithData (3072, reinterpret_cast (&espeakdata_dicts64_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/tn_dict", U"tn"); Collection_addItem (me.peek(), espeakdata_dicts64.transfer()); static unsigned char espeakdata_dicts65_data[5978] = { 0, 4, 0, 0, 77, 13, 0, 0, 0, 0, 0, 10, 135, 9, 19, 19, 22, 5, 195, 167, 65, 0, 0, 5, 65, 4, 35, 0, 0, 6, 194, 5, 0, 17, 9, 0, 10, 199, 44, 20, 212, 4, 211, 206, 84, 65, 0, 0, 6, 65, 8, 71, 36, 0, 0, 9, 198, 52, 19, 1, 81, 144, 64, 66, 0, 0, 0, 6, 65, 12, 75, 109, 0, 0, 0, 18, 4, 95, 8, 1, 3, 47, 6, 109, 51, 89, 91, 35, 48, 49, 6, 35, 0, 0, 0, 6, 65, 16, 72, 109, 0, 0, 0, 6, 195, 36, 209, 128, 17, 0, 0, 5, 65, 20, 109, 0, 0, 0, 0, 7, 196, 4, 102, 79, 56, 65, 0, 6, 65, 24, 83, 109, 0, 0, 0, 0, 8, 196, 100, 242, 211, 4, 72, 28, 0, 6, 65, 28, 79, 109, 0, 0, 0, 0, 0, 6, 65, 32, 107, 109, 0, 0, 0, 0, 0, 5, 65, 36, 37, 0, 0, 10, 1, 37, 57, 113, 88, 72, 109, 0, 27, 0, 8, 1, 38, 11, 84, 6, 109, 0, 0, 0, 6, 65, 40, 90, 109, 0, 0, 0, 12, 1, 42, 57, 6, 13, 55, 72, 13, 88, 0, 27, 0, 9, 1, 43, 35, 51, 47, 13, 0, 27, 0, 6, 65, 44, 49, 35, 0, 0, 0, 0, 0, 6, 65, 48, 55, 109, 0, 0, 0, 0, 0, 6, 65, 52, 65, 109, 0, 0, 0, 0, 0, 8, 197, 20, 66, 82, 56, 80, 66, 6, 65, 56, 50, 109, 0, 0, 0, 7, 195, 76, 150, 128, 76, 9, 0, 0, 5, 193, 60, 76, 9, 0, 9, 1, 61, 109, 91, 124, 47, 0, 27, 0, 0, 0, 6, 65, 64, 48, 109, 0, 0, 9, 198, 76, 147, 83, 37, 144, 72, 65, 6, 194, 4, 32, 17, 9, 0, 7, 195, 4, 33, 0, 17, 9, 0, 0, 7, 65, 68, 49, 84, 109, 0, 0, 0, 0, 0, 6, 65, 72, 51, 109, 0, 0, 0, 0, 0, 7, 132, 197, 159, 20, 9, 17, 6, 195, 36, 210, 194, 17, 6, 195, 36, 210, 194, 17, 6, 65, 76, 89, 109, 0, 0, 0, 0, 0, 6, 65, 80, 47, 109, 0, 0, 6, 195, 81, 0, 79, 17, 0, 0, 0, 5, 65, 84, 40, 0, 0, 0, 0, 0, 6, 65, 88, 84, 109, 0, 0, 7, 132, 1, 195, 182, 6, 17, 0, 0, 0, 12, 65, 92, 72, 40, 71, 109, 55, 84, 6, 109, 0, 0, 0, 0, 0, 7, 65, 96, 109, 49, 89, 0, 0, 0, 0, 0, 6, 65, 100, 57, 109, 0, 0, 0, 0, 0, 6, 65, 104, 88, 109, 0, 0, 0, 0, 0, 0, 0, 10, 135, 2, 9, 14, 7, 195, 182, 12, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 61, 33, 21, 65, 0, 0, 0, 0, 6, 195, 25, 64, 65, 17, 0, 0, 6, 195, 4, 100, 0, 17, 0, 0, 0, 6, 195, 80, 146, 22, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 16, 16, 72, 9, 0, 0, 0, 0, 9, 198, 32, 18, 203, 5, 34, 64, 65, 0, 0, 0, 0, 9, 198, 44, 22, 83, 21, 34, 64, 65, 6, 194, 9, 80, 76, 9, 0, 0, 0, 0, 0, 6, 195, 5, 99, 64, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 32, 149, 12, 21, 32, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 76, 147, 143, 64, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 52, 84, 147, 36, 224, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 16, 80, 72, 9, 0, 0, 0, 0, 6, 195, 4, 180, 0, 17, 0, 0, 16, 4, 95, 4, 16, 20, 10, 84, 37, 51, 81, 4, 113, 55, 23, 0, 0, 0, 0, 0, 11, 200, 36, 227, 135, 36, 197, 5, 72, 80, 67, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 44, 147, 9, 76, 65, 7, 196, 64, 244, 212, 4, 65, 13, 4, 95, 20, 12, 4, 47, 124, 55, 72, 6, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 88, 86, 65, 72, 28, 0, 8, 197, 4, 208, 83, 100, 16, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 195, 8, 83, 128, 76, 9, 0, 7, 196, 8, 19, 139, 4, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 76, 19, 83, 84, 224, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 8, 149, 12, 37, 48, 65, 0, 0, 6, 195, 61, 48, 128, 17, 0, 7, 196, 72, 17, 25, 60, 65, 0, 0, 0, 0, 0, 0, 0, 10, 3, 226, 130, 172, 35, 84, 51, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 76, 149, 129, 76, 65, 6, 195, 21, 1, 11, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 5, 37, 22, 36, 224, 65, 0, 0, 0, 0, 0, 17, 4, 95, 13, 3, 14, 40, 88, 6, 35, 47, 65, 35, 37, 65, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 51, 88, 39, 47, 6, 40, 88, 0, 0, 10, 3, 95, 48, 67, 6, 57, 112, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 44, 243, 153, 4, 65, 0, 0, 0, 0, 13, 3, 95, 50, 67, 6, 37, 80, 37, 57, 112, 88, 0, 0, 0, 9, 198, 81, 83, 131, 20, 194, 64, 65, 14, 139, 11, 196, 177, 18, 11, 12, 1, 18, 5, 12, 9, 65, 0, 0, 0, 0, 6, 195, 4, 146, 13, 17, 12, 3, 95, 49, 49, 6, 39, 50, 71, 37, 51, 0, 0, 9, 3, 95, 49, 48, 6, 39, 50, 0, 0, 0, 12, 3, 95, 49, 50, 6, 39, 50, 37, 80, 37, 0, 0, 0, 0, 0, 6, 195, 36, 129, 0, 17, 0, 0, 13, 3, 95, 55, 88, 57, 36, 47, 65, 6, 37, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 32, 21, 1, 100, 65, 14, 139, 11, 196, 177, 19, 11, 196, 177, 22, 18, 1, 11, 65, 0, 0, 6, 195, 8, 243, 21, 65, 0, 0, 0, 0, 0, 9, 3, 95, 49, 88, 6, 39, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 50, 88, 57, 37, 51, 65, 6, 37, 0, 0, 0, 0, 0, 0, 12, 137, 16, 195, 188, 20, 195, 188, 18, 7, 5, 66, 0, 0, 0, 8, 133, 196, 177, 13, 11, 2, 17, 0, 0, 10, 135, 9, 196, 159, 4, 196, 177, 18, 65, 0, 9, 198, 76, 18, 193, 73, 144, 64, 66, 0, 0, 13, 3, 95, 63, 63, 89, 109, 65, 71, 6, 110, 55, 0, 0, 0, 0, 11, 3, 95, 52, 88, 49, 6, 13, 51, 49, 0, 0, 0, 0, 0, 11, 136, 11, 195, 188, 20, 1, 8, 25, 1, 66, 0, 0, 0, 0, 11, 3, 95, 53, 88, 36, 55, 55, 6, 37, 0, 0, 0, 8, 197, 8, 241, 18, 84, 208, 65, 0, 0, 0, 0, 0, 0, 13, 3, 95, 54, 88, 35, 55, 47, 65, 6, 13, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 199, 37, 52, 212, 4, 224, 149, 48, 66, 0, 0, 0, 0, 0, 0, 0, 8, 133, 21, 197, 159, 1, 11, 65, 0, 13, 3, 95, 56, 88, 89, 36, 49, 89, 6, 109, 50, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 44, 144, 72, 28, 0, 13, 3, 95, 57, 88, 72, 39, 49, 89, 6, 35, 50, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 53, 80, 72, 9, 10, 3, 95, 63, 65, 107, 35, 51, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 52, 20, 132, 36, 224, 65, 0, 9, 198, 4, 195, 65, 57, 144, 64, 66, 0, 7, 131, 13, 195, 188, 72, 9, 14, 4, 95, 15, 7, 15, 39, 81, 39, 50, 6, 109, 49, 0, 0, 0, 0, 0, 0, 7, 131, 197, 159, 21, 76, 9, 0, 0, 0, 6, 195, 81, 49, 64, 17, 0, 0, 0, 0, 0, 7, 131, 13, 196, 177, 72, 9, 0, 0, 0, 6, 195, 81, 50, 64, 17, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 48, 77, 50, 65, 37, 55, 57, 6, 39, 50, 0, 0, 7, 195, 76, 83, 128, 76, 9, 14, 4, 95, 48, 77, 51, 65, 37, 55, 57, 6, 35, 34, 0, 0, 9, 198, 8, 83, 66, 21, 144, 90, 65, 0, 11, 4, 95, 48, 77, 49, 71, 6, 37, 50, 0, 0, 19, 4, 95, 2, 18, 22, 49, 13, 89, 6, 35, 55, 47, 65, 35, 37, 65, 124, 0, 0, 0, 0, 0, 0, 0, 0, 8, 197, 8, 21, 13, 4, 224, 65, 0, 0, 13, 138, 195, 167, 1, 14, 1, 11, 11, 1, 12, 5, 66, 7, 132, 195, 182, 19, 19, 17, 0, 0, 0, 9, 198, 8, 22, 66, 85, 37, 0, 65, 0, 0, 0, 8, 197, 100, 246, 135, 5, 64, 65, 0, 6, 194, 52, 144, 72, 9, 0, 6, 195, 81, 54, 68, 17, 0, 0, 0, 7, 132, 195, 182, 20, 22, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 136, 4, 195, 188, 13, 4, 195, 188, 26, 65, 0, 0, 0, 0, 9, 198, 52, 84, 136, 4, 32, 64, 65, 0, 6, 195, 60, 80, 196, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 1, 196, 159, 18, 196, 177, 65, 0, 0, 0, 0, 0, 0, 11, 136, 19, 1, 16, 19, 1, 18, 196, 177, 65, 0, 13, 4, 95, 3, 9, 18, 91, 35, 48, 49, 6, 35, 0, 0, 13, 138, 195, 167, 1, 14, 11, 196, 177, 18, 196, 177, 65, 0, 0, 0, 0, 0, 0, 0, 9, 198, 84, 180, 129, 100, 224, 64, 66, 0, 0, 7, 196, 76, 146, 82, 80, 65, 0, 0, 0, 0, 7, 196, 29, 54, 73, 32, 17, 0, 16, 4, 95, 1, 3, 21, 84, 111, 51, 81, 6, 111, 37, 65, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 18, 14, 7, 107, 35, 55, 49, 6, 35, 0, 0, 0, 0, 9, 198, 16, 83, 137, 104, 194, 64, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 1, 25, 4, 196, 177, 14, 65, 0, 0, 0, 0, 0, 0, 0, 9, 134, 13, 21, 196, 159, 12, 1, 65, 8, 133, 195, 182, 196, 177, 2, 17, 0, 0, 0, 21, 4, 95, 1, 3, 50, 76, 6, 124, 83, 47, 84, 111, 51, 81, 6, 111, 37, 65, 124, 0, 0, 0, 0, 0, 6, 194, 80, 16, 72, 9, 0, 7, 132, 195, 182, 25, 11, 17, 0, 0, 0, 0, 0, 0, 8, 197, 5, 100, 149, 64, 16, 65, 0, 0, 7, 132, 195, 182, 6, 11, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 80, 211, 79, 8, 17, 0, 0, 0, 11, 136, 197, 159, 196, 177, 18, 14, 1, 11, 65, 0, 0, 0, 0, 0, 0, 12, 2, 194, 167, 76, 109, 50, 79, 6, 109, 55, 0, 0, 0, 0, 7, 132, 195, 182, 4, 16, 17, 0, 0, 0, 0, 0, 17, 2, 196, 159, 57, 40, 65, 40, 91, 6, 35, 49, 15, 79, 6, 109, 0, 7, 2, 195, 167, 76, 109, 0, 0, 9, 198, 52, 20, 205, 5, 98, 64, 65, 8, 133, 195, 182, 19, 25, 13, 17, 0, 0, 0, 0, 0, 0, 14, 2, 194, 182, 48, 35, 16, 35, 81, 51, 6, 35, 83, 0, 0, 7, 2, 197, 159, 91, 109, 0, 0, 0, 0, 0, 0, 6, 195, 84, 36, 0, 17, 12, 2, 194, 176, 72, 36, 16, 36, 75, 6, 109, 0, 0, 9, 134, 14, 9, 196, 159, 4, 5, 65, 0, 6, 2, 195, 182, 125, 0, 0, 0, 0, 0, 12, 4, 95, 3, 5, 4, 107, 6, 35, 51, 83, 0, 0, 8, 197, 9, 84, 132, 85, 32, 65, 0, 0, 0, 6, 195, 85, 33, 129, 65, 0, 0, 6, 194, 80, 80, 72, 9, 6, 2, 195, 188, 112, 0, 0, 0, 0, 10, 135, 2, 1, 18, 20, 196, 177, 14, 65, 0, 0, 6, 2, 196, 177, 13, 0, 0, 0, 8, 197, 4, 226, 193, 72, 16, 65, 0, 6, 195, 4, 33, 211, 17, 0, 6, 195, 85, 49, 0, 17, 0, 0, 0, 0, 6, 195, 100, 179, 64, 17, 6, 195, 4, 179, 64, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 132, 195, 182, 9, 2, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 80, 242, 193, 80, 65, 12, 137, 11, 21, 18, 20, 21, 12, 21, 197, 159, 65, 0, 0, 0, 0, 0, 0, 0, 0, 6, 2, 95, 15, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 194, 88, 80, 72, 28, 0, 0, 0, 0, 0, 11, 2, 95, 35, 72, 37, 57, 6, 109, 88, 0, 0, 20, 2, 95, 34, 47, 13, 51, 50, 6, 35, 49, 37, 91, 35, 16, 36, 47, 6, 124, 0, 0, 19, 2, 95, 33, 113, 50, 55, 6, 109, 65, 37, 91, 35, 16, 36, 47, 4, 124, 0, 0, 0, 14, 2, 95, 39, 35, 48, 110, 89, 47, 51, 6, 110, 83, 0, 0, 16, 2, 95, 38, 84, 6, 109, 37, 91, 35, 16, 36, 47, 6, 124, 0, 0, 0, 7, 132, 195, 182, 9, 22, 17, 0, 0, 13, 4, 95, 3, 1, 16, 71, 112, 57, 6, 113, 49, 0, 0, 18, 2, 95, 41, 49, 35, 48, 35, 48, 35, 16, 35, 50, 47, 6, 109, 88, 0, 0, 16, 2, 95, 40, 35, 76, 48, 35, 16, 35, 50, 47, 6, 109, 88, 0, 0, 16, 2, 95, 47, 36, 57, 6, 124, 49, 76, 124, 88, 81, 6, 124, 0, 0, 11, 2, 95, 46, 50, 110, 49, 47, 6, 35, 0, 0, 16, 2, 95, 45, 49, 6, 13, 89, 35, 76, 124, 88, 81, 6, 124, 0, 0, 9, 198, 53, 81, 1, 57, 144, 64, 66, 9, 198, 4, 229, 1, 49, 144, 64, 66, 12, 2, 95, 44, 84, 124, 51, 79, 6, 113, 55, 0, 0, 7, 195, 8, 148, 128, 76, 9, 8, 2, 95, 51, 6, 112, 76, 0, 0, 9, 2, 95, 50, 37, 80, 6, 37, 0, 0, 9, 134, 195, 167, 15, 18, 21, 13, 65, 9, 198, 64, 84, 208, 20, 208, 133, 65, 9, 2, 95, 49, 71, 6, 37, 51, 0, 0, 11, 2, 95, 48, 89, 13, 83, 6, 13, 51, 0, 0, 10, 2, 95, 55, 57, 36, 72, 6, 37, 0, 0, 10, 2, 95, 54, 35, 55, 47, 6, 13, 0, 0, 9, 2, 95, 53, 71, 6, 109, 91, 0, 0, 10, 2, 95, 52, 72, 6, 125, 51, 47, 0, 0, 20, 2, 95, 59, 50, 110, 49, 47, 35, 55, 6, 13, 84, 124, 51, 79, 6, 113, 55, 0, 0, 15, 2, 95, 58, 37, 49, 6, 124, 50, 110, 49, 47, 6, 35, 0, 0, 11, 2, 95, 57, 72, 6, 39, 49, 40, 88, 0, 0, 6, 195, 72, 150, 133, 65, 11, 2, 95, 56, 89, 36, 80, 6, 124, 88, 0, 0, 18, 2, 95, 63, 89, 39, 51, 6, 111, 37, 91, 35, 16, 36, 47, 4, 124, 0, 0, 0, 0, 0, 7, 195, 8, 150, 128, 76, 9, 0, 0, 0, 16, 2, 95, 64, 49, 111, 57, 51, 111, 49, 55, 6, 111, 6, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 4, 95, 226, 128, 166, 6, 113, 76, 50, 110, 49, 47, 6, 35, 0, 0, 0, 0, 0, 0, 6, 195, 20, 177, 192, 17, 17, 4, 95, 226, 128, 153, 47, 109, 49, 47, 13, 51, 50, 6, 35, 49, 0, 0, 12, 137, 4, 15, 19, 4, 15, 196, 159, 18, 21, 65, 17, 4, 95, 226, 128, 152, 47, 109, 49, 47, 13, 51, 50, 6, 35, 49, 0, 16, 4, 95, 4, 15, 20, 113, 89, 47, 50, 110, 49, 47, 6, 35, 0, 0, 0, 0, 7, 195, 36, 193, 64, 72, 9, 0, 0, 18, 4, 95, 226, 128, 147, 6, 40, 88, 111, 50, 76, 124, 88, 81, 6, 124, 0, 0, 0, 15, 2, 95, 95, 4, 35, 55, 47, 76, 124, 88, 81, 6, 124, 0, 0, 22, 2, 95, 94, 124, 50, 75, 6, 109, 55, 47, 65, 109, 37, 91, 35, 16, 36, 47, 6, 124, 0, 0, 0, 22, 2, 95, 92, 47, 6, 109, 51, 89, 15, 36, 57, 4, 124, 49, 76, 124, 88, 81, 6, 124, 0, 0, 0, 0, 0, 0, 6, 195, 80, 211, 192, 17, 0, 0, 17, 142, 11, 196, 177, 16, 11, 196, 177, 18, 13, 196, 177, 26, 196, 177, 65, 0, 0, 0, 0, 0, 16, 4, 95, 7, 18, 22, 6, 35, 49, 89, 35, 50, 37, 65, 124, 0, 0, 6, 195, 60, 116, 192, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 4, 95, 4, 9, 1, 111, 65, 55, 35, 6, 111, 47, 0, 0, 0, 0, 0, 0, 14, 2, 95, 126, 57, 35, 49, 55, 35, 91, 6, 13, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 201, 37, 52, 203, 20, 225, 5, 73, 83, 128, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 198, 37, 52, 1, 73, 64, 64, 66, 0, 0, 0, 8, 197, 37, 166, 141, 37, 32, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 5, 67, 64, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 196, 9, 84, 147, 4, 65, 0, 9, 134, 4, 195, 188, 26, 3, 5, 65, 0, 0, 0, 0, 0, 0, 7, 195, 4, 208, 64, 28, 65, 0, 0, 0, 0, 0, 0, 8, 197, 52, 244, 205, 61, 32, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 137, 20, 5, 11, 9, 18, 4, 1, 196, 159, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 138, 19, 196, 177, 13, 19, 196, 177, 3, 1, 11, 65, 0, 0, 0, 0, 6, 195, 5, 69, 128, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 18, 66, 195, 167, 0, 197, 159, 0, 102, 0, 104, 0, 107, 0, 112, 0, 113, 0, 115, 0, 116, 0, 7, 6, 20, 0, 96, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 6, 195, 167, 0, 3, 76, 0, 7, 6, 195, 182, 0, 3, 125, 0, 7, 6, 195, 188, 0, 110, 195, 188, 122, 1, 21, 2, 32, 14, 128, 128, 132, 3, 2, 112, 50, 112, 88, 0, 109, 1, 21, 2, 32, 14, 128, 128, 130, 3, 2, 112, 65, 0, 122, 1, 21, 2, 32, 14, 128, 128, 130, 3, 2, 112, 88, 0, 4, 3, 112, 0, 1, 21, 2, 32, 14, 128, 128, 129, 0, 110, 1, 21, 2, 32, 14, 128, 128, 130, 3, 112, 50, 0, 121, 111, 114, 1, 21, 2, 32, 14, 128, 128, 132, 3, 112, 57, 2, 39, 51, 0, 7, 6, 196, 159, 0, 1, 17, 65, 3, 12, 15, 0, 4, 1, 101, 3, 57, 0, 1, 105, 0, 3, 100, 0, 5, 1, 1, 17, 65, 3, 126, 0, 7, 6, 196, 177, 0, 110, 196, 177, 122, 1, 21, 2, 32, 14, 128, 128, 132, 3, 2, 13, 50, 13, 88, 0, 109, 1, 21, 2, 32, 14, 128, 128, 130, 3, 2, 13, 65, 0, 122, 1, 21, 2, 32, 14, 128, 128, 130, 3, 2, 13, 88, 0, 4, 3, 13, 0, 1, 21, 2, 32, 14, 128, 128, 129, 0, 110, 1, 21, 2, 32, 14, 128, 128, 130, 3, 13, 50, 0, 121, 111, 114, 1, 21, 2, 32, 14, 128, 128, 132, 3, 13, 57, 2, 39, 51, 0, 7, 6, 197, 159, 0, 3, 91, 0, 7, 6, 97, 0, 4, 3, 35, 0, 1, 21, 2, 32, 14, 128, 128, 129, 0, 108, 196, 177, 109, 1, 21, 2, 32, 14, 128, 128, 132, 3, 35, 55, 13, 65, 0, 121, 196, 177, 109, 1, 21, 2, 32, 14, 128, 128, 132, 3, 35, 57, 13, 65, 0, 99, 97, 107, 1, 21, 2, 32, 14, 128, 128, 132, 3, 35, 75, 35, 49, 0, 99, 97, 107, 109, 196, 177, 197, 159, 1, 21, 2, 32, 14, 128, 128, 135, 3, 35, 75, 35, 49, 65, 2, 13, 91, 0, 118, 114, 117, 1, 21, 2, 112, 97, 3, 35, 84, 34, 6, 40, 0, 115, 196, 177, 110, 1, 21, 2, 32, 14, 128, 128, 132, 3, 35, 89, 13, 50, 0, 7, 6, 98, 0, 3, 71, 0, 7, 6, 99, 0, 3, 75, 0, 7, 6, 100, 0, 196, 177, 114, 2, 32, 14, 128, 128, 131, 3, 2, 72, 13, 51, 0, 105, 114, 2, 32, 14, 128, 128, 131, 3, 2, 72, 37, 51, 0, 117, 114, 2, 32, 14, 128, 128, 131, 3, 2, 72, 40, 51, 0, 195, 188, 114, 2, 32, 14, 128, 128, 131, 3, 2, 72, 112, 51, 0, 8, 2, 101, 196, 159, 105, 108, 3, 6, 72, 0, 3, 72, 0, 196, 177, 2, 32, 14, 128, 128, 130, 3, 72, 13, 0, 196, 177, 107, 2, 32, 14, 128, 128, 131, 3, 72, 13, 49, 0, 196, 177, 110, 2, 32, 14, 128, 128, 131, 3, 72, 13, 50, 0, 196, 177, 110, 196, 177, 122, 2, 32, 14, 128, 128, 133, 3, 72, 13, 50, 13, 88, 0, 196, 177, 108, 97, 114, 2, 32, 14, 128, 128, 133, 3, 72, 13, 55, 35, 51, 0, 196, 177, 109, 2, 32, 14, 128, 128, 131, 3, 72, 13, 65, 0, 97, 2, 32, 14, 128, 128, 130, 3, 72, 35, 0, 97, 110, 2, 32, 14, 128, 128, 131, 3, 72, 35, 50, 0, 101, 2, 32, 14, 128, 128, 130, 3, 72, 36, 0, 101, 110, 2, 32, 14, 128, 128, 131, 3, 72, 36, 50, 0, 105, 2, 32, 14, 128, 128, 130, 3, 72, 37, 0, 105, 107, 2, 32, 14, 128, 128, 131, 3, 72, 37, 49, 0, 105, 110, 2, 32, 14, 128, 128, 131, 3, 72, 37, 50, 0, 105, 110, 105, 122, 2, 32, 14, 128, 128, 133, 3, 72, 37, 50, 37, 88, 0, 105, 108, 101, 114, 2, 32, 14, 128, 128, 133, 3, 72, 37, 55, 36, 51, 0, 105, 109, 2, 32, 14, 128, 128, 131, 3, 72, 37, 65, 0, 117, 2, 32, 14, 128, 128, 130, 3, 72, 40, 0, 117, 107, 2, 32, 14, 128, 128, 131, 3, 72, 40, 49, 0, 117, 110, 2, 32, 14, 128, 128, 131, 3, 72, 40, 50, 0, 117, 110, 117, 122, 2, 32, 14, 128, 128, 133, 3, 72, 40, 50, 40, 88, 0, 117, 108, 97, 114, 2, 32, 14, 128, 128, 133, 3, 72, 40, 55, 35, 34, 0, 117, 109, 2, 32, 14, 128, 128, 131, 3, 72, 40, 65, 0, 195, 188, 2, 32, 14, 128, 128, 130, 3, 72, 112, 0, 195, 188, 107, 2, 32, 14, 128, 128, 131, 3, 72, 112, 49, 0, 195, 188, 110, 2, 32, 14, 128, 128, 131, 3, 72, 112, 50, 0, 195, 188, 110, 195, 188, 122, 2, 32, 14, 128, 128, 133, 3, 72, 112, 50, 112, 88, 0, 195, 188, 108, 101, 114, 2, 32, 14, 128, 128, 133, 3, 72, 112, 55, 36, 34, 0, 195, 188, 109, 2, 32, 14, 128, 128, 131, 3, 72, 112, 65, 0, 7, 6, 101, 0, 4, 3, 36, 0, 1, 21, 2, 32, 14, 128, 128, 129, 0, 108, 105, 109, 1, 21, 2, 32, 14, 128, 128, 132, 3, 36, 55, 37, 65, 0, 121, 105, 109, 1, 21, 2, 32, 14, 128, 128, 132, 3, 36, 57, 37, 65, 0, 99, 101, 107, 1, 21, 2, 32, 14, 128, 128, 132, 3, 36, 75, 36, 49, 0, 99, 101, 107, 109, 105, 197, 159, 1, 21, 2, 32, 14, 128, 128, 135, 3, 36, 75, 36, 49, 65, 2, 37, 91, 0, 115, 105, 110, 1, 21, 2, 32, 14, 128, 128, 132, 3, 36, 89, 37, 50, 0, 7, 6, 102, 0, 3, 83, 0, 7, 6, 103, 0, 4, 2, 101, 3, 79, 0, 2, 105, 0, 2, 195, 182, 0, 2, 195, 188, 0, 3, 81, 0, 7, 6, 104, 0, 3, 107, 0, 7, 6, 105, 0, 110, 105, 122, 1, 21, 2, 32, 14, 128, 128, 132, 3, 2, 37, 50, 37, 88, 0, 109, 1, 21, 2, 32, 14, 128, 128, 130, 3, 2, 37, 65, 0, 122, 1, 21, 2, 32, 14, 128, 128, 130, 3, 2, 37, 88, 0, 4, 3, 37, 0, 1, 21, 2, 32, 14, 128, 128, 129, 0, 110, 1, 21, 2, 32, 14, 128, 128, 130, 3, 37, 50, 0, 121, 111, 114, 1, 21, 2, 32, 14, 128, 128, 132, 3, 37, 57, 2, 39, 51, 0, 7, 6, 106, 0, 3, 90, 0, 7, 6, 107, 0, 101, 110, 2, 32, 14, 128, 128, 131, 3, 2, 80, 36, 50, 0, 3, 49, 0, 4, 2, 101, 3, 80, 0, 2, 105, 0, 2, 195, 182, 0, 2, 195, 188, 0, 7, 6, 108, 0, 97, 2, 32, 14, 128, 128, 130, 3, 2, 55, 35, 0, 101, 2, 32, 14, 128, 128, 130, 3, 2, 55, 36, 0, 3, 55, 0, 196, 177, 2, 32, 14, 128, 128, 130, 3, 55, 13, 0, 196, 177, 107, 2, 32, 14, 128, 128, 131, 3, 55, 13, 49, 0, 97, 114, 2, 32, 14, 128, 128, 131, 3, 55, 35, 51, 0, 101, 114, 2, 32, 14, 128, 128, 131, 3, 55, 36, 51, 0, 105, 2, 32, 14, 128, 128, 130, 3, 55, 37, 0, 105, 107, 2, 32, 14, 128, 128, 131, 3, 55, 37, 49, 0, 117, 2, 32, 14, 128, 128, 130, 3, 55, 40, 0, 117, 107, 2, 32, 14, 128, 128, 131, 3, 55, 40, 49, 0, 195, 188, 2, 32, 14, 128, 128, 130, 3, 55, 112, 0, 195, 188, 107, 2, 32, 14, 128, 128, 131, 3, 55, 112, 49, 0, 7, 6, 109, 0, 97, 2, 32, 14, 128, 128, 130, 3, 2, 65, 35, 0, 101, 2, 32, 14, 128, 128, 130, 3, 2, 65, 36, 0, 3, 65, 0, 7, 6, 110, 0, 3, 50, 0, 196, 177, 110, 2, 32, 14, 128, 128, 131, 3, 50, 13, 50, 0, 105, 110, 2, 32, 14, 128, 128, 131, 3, 50, 37, 50, 0, 117, 110, 2, 32, 14, 128, 128, 131, 3, 50, 40, 50, 0, 100, 97, 8, 2, 32, 3, 50, 72, 35, 0, 100, 97, 110, 8, 2, 32, 3, 50, 72, 35, 50, 0, 100, 101, 8, 2, 32, 3, 50, 72, 36, 0, 100, 101, 110, 8, 2, 32, 3, 50, 72, 36, 50, 0, 195, 188, 110, 2, 32, 14, 128, 128, 131, 3, 50, 112, 50, 0, 7, 6, 111, 0, 3, 39, 0, 7, 6, 112, 0, 3, 48, 0, 7, 6, 113, 0, 3, 49, 0, 7, 6, 114, 0, 97, 2, 32, 14, 128, 128, 130, 3, 2, 51, 35, 0, 101, 2, 32, 14, 128, 128, 130, 3, 2, 51, 36, 0, 1, 17, 65, 2, 17, 65, 3, 16, 0, 3, 51, 0, 97, 2, 32, 24, 3, 51, 35, 0, 101, 2, 32, 24, 3, 51, 36, 0, 7, 6, 115, 0, 196, 177, 110, 196, 177, 122, 2, 32, 14, 128, 128, 133, 3, 2, 89, 13, 50, 13, 88, 0, 97, 2, 32, 14, 128, 128, 130, 3, 2, 89, 35, 0, 97, 107, 2, 32, 14, 128, 128, 131, 3, 2, 89, 35, 49, 0, 97, 110, 2, 32, 14, 128, 128, 131, 3, 2, 89, 35, 50, 0, 97, 110, 196, 177, 122, 2, 32, 14, 128, 128, 133, 3, 2, 89, 35, 50, 13, 88, 0, 97, 109, 2, 32, 14, 128, 128, 131, 3, 2, 89, 35, 65, 0, 101, 2, 32, 14, 128, 128, 130, 3, 2, 89, 36, 0, 101, 107, 2, 32, 14, 128, 128, 131, 3, 2, 89, 36, 49, 0, 101, 110, 2, 32, 14, 128, 128, 131, 3, 2, 89, 36, 50, 0, 101, 110, 105, 122, 2, 32, 14, 128, 128, 133, 3, 2, 89, 36, 50, 37, 88, 0, 101, 109, 2, 32, 14, 128, 128, 131, 3, 2, 89, 36, 65, 0, 105, 110, 105, 122, 2, 32, 14, 128, 128, 133, 3, 2, 89, 37, 50, 37, 88, 0, 117, 110, 117, 122, 2, 32, 14, 128, 128, 133, 3, 2, 89, 40, 50, 40, 88, 0, 195, 188, 110, 195, 188, 122, 2, 32, 14, 128, 128, 133, 3, 2, 89, 112, 50, 112, 88, 0, 3, 89, 0, 7, 6, 116, 0, 196, 177, 114, 1, 18, 66, 2, 32, 14, 128, 128, 131, 3, 2, 47, 13, 51, 0, 105, 114, 1, 18, 66, 2, 32, 14, 128, 128, 131, 3, 2, 47, 37, 51, 0, 117, 114, 1, 18, 66, 2, 32, 14, 128, 128, 131, 3, 2, 47, 40, 51, 0, 195, 188, 114, 1, 18, 66, 2, 32, 14, 128, 128, 131, 3, 2, 47, 112, 51, 0, 3, 47, 0, 97, 2, 32, 14, 128, 128, 130, 3, 47, 35, 0, 97, 110, 2, 32, 14, 128, 128, 131, 3, 47, 35, 50, 0, 101, 2, 32, 14, 128, 128, 130, 3, 47, 36, 0, 101, 110, 2, 32, 14, 128, 128, 131, 3, 47, 36, 50, 0, 7, 6, 117, 0, 110, 117, 122, 1, 21, 2, 32, 14, 128, 128, 132, 3, 2, 40, 50, 40, 88, 0, 109, 1, 21, 2, 32, 14, 128, 128, 130, 3, 2, 40, 65, 0, 122, 1, 21, 2, 32, 14, 128, 128, 130, 3, 2, 40, 88, 0, 4, 3, 40, 0, 1, 21, 2, 32, 14, 128, 128, 129, 0, 110, 1, 21, 2, 32, 14, 128, 128, 130, 3, 40, 50, 0, 121, 111, 114, 1, 21, 2, 32, 14, 128, 128, 132, 3, 40, 57, 2, 39, 51, 0, 7, 6, 118, 0, 3, 84, 0, 7, 6, 119, 0, 3, 58, 0, 7, 6, 120, 0, 3, 49, 89, 0, 1, 25, 3, 88, 0, 7, 6, 121, 0, 196, 177, 110, 196, 177, 122, 2, 32, 14, 128, 128, 133, 3, 2, 57, 13, 50, 13, 88, 0, 196, 177, 109, 2, 32, 14, 128, 128, 131, 3, 2, 57, 13, 65, 0, 196, 177, 122, 2, 32, 14, 128, 128, 131, 3, 2, 57, 13, 88, 0, 105, 110, 105, 122, 2, 32, 14, 128, 128, 133, 3, 2, 57, 37, 50, 37, 88, 0, 105, 109, 2, 32, 14, 128, 128, 131, 3, 2, 57, 37, 65, 0, 105, 122, 2, 32, 14, 128, 128, 131, 3, 2, 57, 37, 88, 0, 117, 110, 117, 122, 2, 32, 14, 128, 128, 133, 3, 2, 57, 40, 50, 40, 88, 0, 117, 109, 2, 32, 14, 128, 128, 131, 3, 2, 57, 40, 65, 0, 117, 122, 2, 32, 14, 128, 128, 131, 3, 2, 57, 40, 88, 0, 108, 97, 2, 32, 14, 128, 128, 131, 3, 2, 57, 55, 35, 0, 108, 101, 2, 32, 14, 128, 128, 131, 3, 2, 57, 55, 36, 0, 195, 188, 110, 195, 188, 122, 2, 32, 14, 128, 128, 133, 3, 2, 57, 112, 50, 112, 88, 0, 195, 188, 109, 2, 32, 14, 128, 128, 131, 3, 2, 57, 112, 65, 0, 195, 188, 122, 2, 32, 14, 128, 128, 131, 3, 2, 57, 112, 88, 0, 3, 57, 0, 196, 177, 2, 32, 14, 128, 128, 130, 3, 57, 13, 0, 97, 2, 32, 14, 128, 128, 130, 3, 57, 35, 0, 97, 108, 196, 177, 109, 2, 32, 14, 128, 128, 133, 3, 57, 35, 55, 13, 65, 0, 97, 121, 196, 177, 109, 2, 32, 14, 128, 128, 133, 3, 57, 35, 57, 13, 65, 0, 97, 99, 97, 107, 2, 32, 14, 128, 128, 133, 3, 57, 35, 75, 35, 49, 0, 97, 99, 97, 107, 109, 196, 177, 197, 159, 2, 32, 14, 128, 128, 136, 3, 57, 35, 75, 35, 49, 65, 2, 13, 91, 0, 97, 115, 196, 177, 110, 2, 32, 14, 128, 128, 133, 3, 57, 35, 89, 13, 50, 0, 101, 2, 32, 14, 128, 128, 130, 3, 57, 36, 0, 101, 108, 105, 109, 2, 32, 14, 128, 128, 133, 3, 57, 36, 55, 37, 65, 0, 101, 121, 105, 109, 2, 32, 14, 128, 128, 133, 3, 57, 36, 57, 37, 65, 0, 101, 99, 101, 107, 2, 32, 14, 128, 128, 133, 3, 57, 36, 75, 36, 49, 0, 101, 99, 101, 107, 109, 105, 197, 159, 2, 32, 14, 128, 128, 136, 3, 57, 36, 75, 36, 49, 65, 2, 37, 91, 0, 101, 115, 105, 110, 2, 32, 14, 128, 128, 133, 3, 57, 36, 89, 37, 50, 0, 105, 2, 32, 14, 128, 128, 130, 3, 57, 37, 0, 117, 2, 32, 14, 128, 128, 130, 3, 57, 40, 0, 107, 101, 110, 2, 32, 14, 128, 128, 132, 3, 57, 80, 2, 36, 50, 0, 195, 188, 2, 32, 14, 128, 128, 130, 3, 57, 112, 0, 7, 6, 122, 0, 3, 88, 0, 7, 6, 0, 39, 2, 14, 130, 132, 128, 3, 0, 36, 3, 72, 39, 55, 35, 34, 0, 4, 195, 164, 3, 109, 0, 201, 153, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts65 = FileInMemory_createWithData (5977, reinterpret_cast (&espeakdata_dicts65_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/tr_dict", U"tr"); Collection_addItem (me.peek(), espeakdata_dicts65.transfer()); static unsigned char espeakdata_dicts66_data[2122] = { 0, 4, 0, 0, 204, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 8, 71, 36, 0, 0, 0, 0, 0, 6, 65, 12, 58, 36, 0, 0, 0, 0, 0, 6, 65, 16, 81, 36, 0, 0, 0, 0, 14, 4, 95, 100, 112, 116, 10, 71, 109, 47, 4, 36, 50, 0, 0, 6, 65, 20, 72, 36, 0, 0, 0, 0, 0, 6, 65, 24, 57, 36, 0, 0, 0, 0, 0, 6, 65, 28, 90, 36, 0, 0, 0, 0, 0, 6, 65, 32, 88, 36, 0, 0, 0, 0, 0, 5, 65, 36, 37, 0, 0, 0, 0, 0, 12, 65, 40, 49, 110, 89, 49, 4, 112, 6, 37, 0, 0, 0, 0, 0, 6, 65, 44, 49, 112, 0, 0, 0, 0, 0, 6, 65, 48, 36, 55, 0, 0, 0, 0, 0, 6, 65, 52, 36, 65, 0, 0, 0, 0, 0, 6, 65, 56, 36, 50, 0, 0, 0, 0, 0, 6, 65, 60, 39, 12, 0, 0, 0, 0, 0, 6, 65, 64, 48, 36, 0, 0, 0, 0, 0, 6, 65, 68, 36, 34, 0, 0, 0, 0, 0, 6, 65, 72, 36, 89, 0, 0, 0, 0, 0, 6, 65, 76, 47, 36, 0, 0, 0, 0, 0, 5, 65, 80, 40, 0, 0, 0, 0, 0, 6, 65, 84, 36, 83, 0, 0, 0, 0, 0, 6, 65, 88, 101, 112, 0, 0, 0, 0, 15, 4, 95, 49, 77, 52, 71, 37, 55, 55, 37, 6, 39, 50, 0, 0, 7, 65, 92, 47, 89, 36, 0, 0, 0, 0, 0, 6, 65, 96, 97, 36, 0, 0, 15, 4, 95, 49, 77, 50, 65, 37, 55, 55, 37, 6, 39, 50, 0, 0, 16, 4, 95, 49, 77, 51, 65, 37, 55, 55, 37, 6, 112, 34, 72, 0, 0, 0, 6, 65, 100, 91, 112, 0, 0, 0, 0, 0, 7, 65, 104, 91, 97, 112, 0, 0, 0, 0, 0, 21, 65, 108, 49, 112, 55, 110, 50, 55, 4, 110, 104, 71, 37, 55, 81, 36, 89, 6, 36, 0, 0, 0, 0, 0, 6, 65, 112, 110, 12, 0, 0, 0, 0, 0, 21, 65, 116, 50, 36, 97, 49, 111, 55, 4, 36, 49, 71, 37, 55, 81, 36, 89, 6, 36, 0, 0, 0, 0, 0, 6, 65, 120, 36, 12, 0, 0, 0, 0, 0, 6, 65, 124, 57, 40, 0, 0, 0, 0, 0, 6, 65, 128, 57, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 136, 57, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 51, 88, 40, 47, 6, 110, 88, 0, 0, 10, 3, 95, 48, 67, 57, 6, 109, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 49, 57, 40, 50, 47, 40, 81, 6, 110, 88, 0, 0, 14, 3, 95, 49, 56, 40, 50, 89, 37, 81, 6, 36, 88, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 49, 49, 40, 50, 71, 6, 36, 34, 0, 0, 9, 3, 95, 49, 48, 6, 40, 50, 0, 0, 11, 3, 95, 49, 51, 40, 50, 6, 109, 97, 0, 0, 12, 3, 95, 49, 50, 40, 50, 37, 49, 6, 36, 0, 0, 12, 3, 95, 49, 53, 40, 50, 71, 6, 37, 91, 0, 0, 13, 3, 95, 49, 52, 40, 50, 72, 6, 108, 34, 47, 0, 0, 13, 3, 95, 49, 55, 40, 50, 96, 37, 72, 6, 36, 0, 0, 13, 3, 95, 49, 54, 40, 50, 112, 55, 47, 6, 110, 0, 0, 0, 13, 3, 95, 55, 88, 96, 37, 47, 65, 6, 36, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 50, 88, 36, 81, 36, 34, 65, 6, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 52, 88, 49, 110, 34, 6, 110, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 53, 88, 37, 55, 55, 6, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 54, 88, 112, 55, 47, 65, 6, 110, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 56, 88, 89, 37, 49, 89, 6, 111, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 57, 88, 47, 40, 49, 89, 6, 112, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 4, 95, 48, 77, 52, 71, 37, 55, 55, 37, 6, 39, 50, 0, 0, 0, 15, 4, 95, 48, 77, 50, 65, 37, 55, 55, 37, 6, 39, 50, 0, 0, 16, 4, 95, 48, 77, 51, 65, 37, 55, 55, 37, 6, 112, 34, 72, 0, 0, 0, 11, 4, 95, 48, 77, 49, 65, 6, 36, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 210, 151, 96, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 2, 95, 51, 6, 109, 97, 0, 0, 9, 2, 95, 50, 37, 49, 6, 36, 0, 0, 9, 2, 95, 49, 71, 6, 36, 34, 0, 0, 10, 2, 95, 48, 50, 6, 40, 55, 19, 0, 0, 10, 2, 95, 55, 96, 37, 72, 6, 36, 0, 0, 10, 2, 95, 54, 112, 55, 47, 6, 110, 0, 0, 9, 2, 95, 53, 71, 6, 37, 91, 0, 0, 10, 2, 95, 52, 72, 6, 108, 34, 47, 0, 0, 0, 0, 11, 2, 95, 57, 47, 40, 81, 6, 110, 88, 0, 0, 11, 2, 95, 56, 89, 37, 81, 6, 36, 88, 0, 0, 7, 2, 210, 163, 36, 68, 0, 0, 0, 0, 0, 6, 2, 210, 175, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 211, 169, 109, 12, 0, 0, 0, 0, 0, 0, 0, 7, 2, 210, 187, 107, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 1, 17, 0, 3, 112, 0, 7, 6, 1, 18, 0, 3, 71, 0, 7, 6, 1, 19, 0, 3, 58, 0, 7, 6, 1, 20, 0, 3, 81, 0, 7, 6, 1, 21, 0, 3, 72, 0, 7, 6, 1, 22, 0, 3, 36, 0, 8, 3, 57, 117, 0, 7, 6, 1, 23, 0, 3, 90, 0, 7, 6, 1, 24, 0, 3, 88, 0, 7, 6, 1, 25, 0, 3, 37, 0, 1, 17, 65, 3, 57, 0, 7, 6, 1, 26, 0, 3, 57, 0, 1, 25, 2, 25, 3, 115, 0, 7, 6, 1, 27, 0, 3, 49, 0, 7, 6, 1, 28, 0, 3, 55, 0, 7, 6, 1, 29, 0, 3, 65, 0, 7, 6, 1, 30, 0, 3, 50, 0, 4, 2, 208, 179, 3, 68, 0, 2, 209, 133, 0, 7, 6, 1, 31, 0, 3, 39, 0, 7, 6, 1, 32, 0, 3, 48, 0, 7, 6, 1, 33, 0, 3, 34, 0, 7, 6, 1, 34, 0, 3, 89, 0, 7, 6, 1, 35, 0, 3, 47, 0, 7, 6, 1, 36, 0, 3, 40, 0, 1, 17, 65, 3, 58, 0, 7, 6, 1, 37, 0, 3, 83, 0, 7, 6, 1, 38, 0, 3, 101, 0, 7, 6, 1, 39, 0, 3, 47, 89, 0, 7, 6, 1, 40, 0, 3, 97, 0, 7, 6, 1, 41, 0, 3, 91, 0, 7, 6, 1, 42, 0, 3, 91, 97, 0, 7, 6, 1, 43, 0, 3, 19, 0, 7, 6, 1, 44, 0, 3, 110, 0, 208, 185, 3, 110, 57, 0, 7, 6, 1, 45, 0, 3, 19, 0, 7, 6, 1, 46, 0, 3, 36, 0, 7, 6, 1, 47, 0, 3, 57, 116, 0, 7, 6, 1, 48, 0, 3, 57, 35, 0, 7, 6, 1, 50, 0, 3, 57, 39, 0, 7, 6, 1, 120, 0, 3, 96, 0, 7, 6, 210, 163, 0, 3, 68, 0, 7, 6, 210, 175, 0, 1, 17, 65, 3, 58, 0, 3, 108, 0, 7, 6, 210, 187, 0, 3, 107, 0, 7, 6, 211, 153, 0, 3, 111, 0, 208, 181, 3, 114, 0, 7, 6, 211, 169, 0, 3, 109, 0, 7, 6, 0, 36, 3, 72, 39, 55, 112, 51, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts66 = FileInMemory_createWithData (2121, reinterpret_cast (&espeakdata_dicts66_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/tt_dict", U"tt"); Collection_addItem (me.peek(), espeakdata_dicts66.transfer()); static unsigned char espeakdata_dicts67_data[3431] = { 0, 4, 0, 0, 202, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 4, 95, 4, 16, 20, 10, 113, 91, 35, 51, 113, 6, 113, 35, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 51, 57, 122, 50, 47, 118, 55, 6, 112, 89, 0, 12, 3, 95, 50, 49, 113, 49, 49, 6, 112, 89, 0, 0, 12, 3, 95, 51, 56, 35, 51, 47, 6, 112, 89, 0, 10, 3, 95, 50, 48, 71, 6, 112, 89, 0, 0, 11, 3, 95, 50, 51, 47, 114, 6, 112, 89, 0, 0, 11, 3, 95, 50, 50, 71, 118, 6, 112, 89, 0, 0, 13, 3, 95, 50, 53, 48, 35, 80, 80, 6, 112, 89, 0, 0, 12, 3, 95, 50, 52, 80, 135, 71, 6, 112, 89, 0, 0, 14, 3, 95, 50, 55, 89, 35, 47, 12, 118, 6, 112, 89, 0, 0, 13, 3, 95, 50, 54, 144, 35, 71, 71, 6, 112, 89, 0, 0, 12, 3, 95, 51, 49, 37, 49, 47, 6, 112, 89, 0, 0, 10, 3, 95, 51, 48, 47, 6, 112, 89, 0, 0, 13, 3, 95, 51, 51, 47, 134, 68, 47, 6, 112, 89, 0, 0, 13, 3, 95, 51, 50, 71, 35, 47, 12, 6, 112, 89, 0, 0, 13, 3, 95, 51, 53, 48, 134, 68, 47, 6, 112, 89, 0, 0, 13, 3, 95, 51, 52, 80, 135, 68, 47, 6, 112, 89, 0, 0, 13, 3, 95, 51, 55, 89, 134, 68, 47, 6, 112, 89, 0, 0, 13, 3, 95, 51, 54, 144, 35, 47, 12, 6, 112, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 55, 57, 122, 50, 50, 118, 89, 6, 112, 0, 12, 3, 95, 54, 49, 6, 113, 49, 89, 35, 138, 0, 0, 15, 3, 95, 55, 56, 35, 138, 108, 35, 47, 12, 6, 35, 51, 0, 10, 3, 95, 54, 48, 89, 6, 118, 138, 0, 0, 9, 3, 95, 48, 67, 89, 6, 135, 0, 13, 3, 95, 54, 51, 47, 6, 113, 51, 89, 35, 138, 0, 0, 12, 3, 95, 54, 50, 71, 6, 118, 89, 35, 138, 0, 0, 13, 3, 95, 54, 53, 48, 6, 134, 68, 89, 35, 138, 0, 0, 12, 3, 95, 54, 52, 80, 6, 135, 89, 35, 138, 0, 0, 13, 3, 95, 54, 55, 89, 6, 35, 51, 89, 35, 138, 0, 0, 14, 3, 95, 54, 54, 144, 113, 57, 6, 118, 89, 35, 138, 0, 0, 15, 3, 95, 55, 49, 113, 49, 108, 35, 47, 12, 6, 35, 51, 0, 0, 13, 3, 95, 55, 48, 89, 35, 47, 12, 6, 35, 51, 0, 0, 15, 3, 95, 55, 51, 47, 113, 108, 35, 47, 12, 6, 35, 51, 0, 0, 15, 3, 95, 55, 50, 71, 35, 108, 35, 47, 12, 6, 35, 51, 0, 0, 15, 3, 95, 55, 53, 48, 35, 144, 35, 47, 12, 6, 35, 51, 0, 0, 15, 3, 95, 55, 52, 80, 135, 108, 35, 47, 12, 6, 35, 51, 0, 0, 15, 3, 95, 55, 55, 89, 35, 138, 35, 47, 12, 6, 35, 51, 0, 0, 15, 3, 95, 55, 54, 144, 113, 108, 35, 47, 12, 6, 35, 51, 0, 0, 12, 3, 95, 49, 57, 6, 122, 50, 50, 112, 89, 0, 0, 13, 3, 95, 49, 56, 35, 138, 6, 118, 51, 35, 108, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 50, 57, 122, 50, 47, 6, 112, 89, 0, 13, 3, 95, 49, 49, 81, 57, 6, 118, 51, 35, 108, 0, 0, 12, 3, 95, 50, 56, 89, 138, 118, 6, 112, 89, 0, 10, 3, 95, 49, 48, 72, 6, 35, 89, 0, 0, 12, 3, 95, 49, 51, 47, 6, 114, 51, 35, 108, 0, 0, 12, 3, 95, 49, 50, 71, 6, 118, 51, 35, 108, 0, 0, 14, 3, 95, 49, 53, 48, 6, 35, 50, 72, 51, 35, 108, 0, 0, 12, 3, 95, 49, 52, 80, 6, 135, 72, 35, 108, 0, 0, 13, 3, 95, 49, 55, 89, 6, 35, 47, 51, 35, 108, 0, 0, 12, 3, 95, 49, 54, 89, 6, 119, 55, 35, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 52, 57, 122, 50, 80, 6, 118, 89, 0, 0, 14, 3, 95, 52, 56, 35, 51, 47, 118, 55, 6, 112, 89, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 53, 57, 122, 50, 89, 6, 35, 138, 0, 14, 3, 95, 52, 49, 113, 49, 47, 118, 55, 6, 112, 89, 0, 0, 13, 3, 95, 53, 56, 35, 138, 6, 118, 84, 35, 50, 0, 12, 3, 95, 52, 48, 80, 118, 55, 6, 112, 89, 0, 0, 15, 3, 95, 52, 51, 47, 114, 68, 47, 118, 55, 6, 112, 89, 0, 0, 14, 3, 95, 52, 50, 71, 35, 57, 118, 55, 6, 112, 89, 0, 0, 15, 3, 95, 52, 53, 48, 134, 68, 47, 118, 55, 6, 112, 89, 0, 0, 14, 3, 95, 52, 52, 80, 35, 84, 118, 55, 6, 112, 89, 0, 0, 15, 3, 95, 52, 55, 89, 134, 68, 47, 118, 55, 6, 112, 89, 0, 0, 14, 3, 95, 52, 54, 144, 113, 57, 118, 55, 6, 112, 89, 0, 0, 16, 3, 95, 54, 57, 122, 50, 108, 4, 35, 47, 12, 6, 35, 51, 0, 13, 3, 95, 53, 49, 113, 49, 6, 118, 84, 35, 50, 0, 0, 12, 3, 95, 54, 56, 6, 35, 51, 89, 35, 138, 0, 12, 3, 95, 53, 48, 48, 35, 80, 6, 118, 89, 0, 0, 13, 3, 95, 53, 51, 47, 6, 113, 51, 48, 35, 50, 0, 0, 12, 3, 95, 53, 50, 71, 6, 118, 84, 35, 50, 0, 0, 13, 3, 95, 53, 53, 48, 6, 35, 80, 48, 35, 50, 0, 0, 12, 3, 95, 53, 52, 80, 6, 135, 84, 35, 50, 0, 0, 15, 3, 95, 53, 55, 89, 35, 47, 12, 6, 118, 84, 35, 50, 0, 0, 13, 3, 95, 53, 54, 144, 6, 35, 48, 48, 35, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 95, 56, 57, 50, 35, 84, 118, 89, 6, 112, 0, 0, 12, 3, 95, 56, 56, 35, 138, 118, 89, 6, 112, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 57, 57, 50, 113, 50, 57, 6, 118, 50, 84, 114, 0, 12, 3, 95, 56, 49, 113, 49, 118, 89, 6, 112, 0, 0, 14, 3, 95, 57, 56, 35, 138, 12, 6, 118, 50, 84, 114, 0, 11, 3, 95, 56, 48, 35, 89, 89, 6, 112, 0, 0, 13, 3, 95, 56, 51, 47, 113, 51, 118, 89, 6, 112, 0, 0, 13, 3, 95, 56, 50, 71, 35, 57, 118, 89, 6, 112, 0, 0, 13, 3, 95, 56, 53, 48, 35, 80, 118, 89, 6, 112, 0, 0, 13, 3, 95, 56, 52, 80, 135, 51, 118, 89, 6, 112, 0, 0, 14, 3, 95, 56, 55, 89, 35, 47, 12, 118, 89, 6, 112, 0, 0, 13, 3, 95, 56, 54, 144, 113, 57, 118, 89, 6, 112, 0, 0, 14, 3, 95, 57, 49, 113, 49, 57, 6, 118, 50, 84, 114, 0, 0, 12, 3, 95, 57, 48, 50, 35, 84, 84, 6, 114, 0, 0, 14, 3, 95, 57, 51, 47, 113, 87, 6, 118, 50, 84, 114, 0, 0, 12, 3, 95, 57, 50, 71, 6, 118, 50, 84, 114, 0, 0, 14, 3, 95, 57, 53, 48, 35, 80, 6, 118, 50, 84, 114, 0, 0, 14, 3, 95, 57, 52, 80, 135, 51, 6, 118, 50, 84, 114, 0, 0, 15, 3, 95, 57, 55, 89, 35, 47, 12, 6, 118, 50, 84, 114, 0, 0, 14, 3, 95, 57, 54, 144, 113, 57, 6, 118, 50, 84, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 3, 239, 174, 168, 144, 119, 47, 112, 15, 108, 114, 0, 0, 12, 4, 95, 48, 77, 52, 6, 35, 51, 35, 71, 0, 0, 0, 11, 4, 95, 48, 77, 50, 55, 6, 118, 146, 0, 0, 13, 4, 95, 48, 77, 51, 49, 35, 51, 6, 119, 51, 0, 0, 0, 13, 4, 95, 48, 77, 49, 108, 35, 88, 6, 118, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 70, 40, 243, 129, 80, 128, 78, 75, 6, 121, 50, 35, 138, 35, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 2, 95, 51, 47, 6, 112, 50, 0, 0, 8, 2, 95, 50, 6, 72, 119, 0, 0, 8, 2, 95, 49, 6, 114, 49, 0, 0, 11, 2, 95, 48, 89, 6, 113, 83, 35, 51, 0, 0, 9, 2, 95, 55, 89, 6, 118, 47, 0, 0, 8, 2, 95, 54, 144, 6, 134, 0, 0, 10, 2, 95, 53, 48, 6, 118, 68, 80, 0, 0, 9, 2, 95, 52, 80, 6, 118, 51, 0, 0, 0, 0, 8, 2, 95, 57, 50, 6, 135, 0, 0, 8, 2, 95, 56, 6, 118, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 2, 217, 134, 50, 123, 50, 0, 0, 8, 2, 217, 133, 65, 112, 65, 0, 0, 8, 2, 217, 132, 55, 118, 65, 0, 0, 0, 8, 2, 217, 130, 104, 118, 83, 0, 0, 7, 2, 217, 129, 83, 114, 0, 0, 0, 8, 2, 217, 143, 48, 114, 91, 0, 0, 10, 2, 217, 142, 88, 13, 71, 13, 51, 0, 7, 2, 218, 134, 80, 114, 0, 0, 0, 0, 0, 0, 0, 8, 2, 217, 136, 84, 118, 121, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 219, 129, 108, 114, 0, 0, 8, 2, 217, 144, 88, 114, 51, 0, 8, 2, 218, 136, 141, 118, 55, 0, 0, 9, 2, 216, 167, 35, 55, 113, 83, 0, 0, 11, 2, 216, 166, 107, 6, 35, 65, 88, 35, 0, 0, 0, 12, 2, 219, 140, 144, 119, 140, 112, 15, 57, 114, 0, 0, 0, 0, 11, 2, 216, 161, 108, 35, 65, 88, 35, 108, 0, 7, 2, 218, 145, 70, 114, 0, 0, 0, 8, 2, 216, 175, 72, 118, 55, 0, 0, 7, 2, 216, 174, 101, 114, 0, 0, 12, 2, 216, 173, 71, 35, 70, 112, 15, 108, 114, 0, 0, 8, 2, 216, 172, 79, 112, 65, 0, 0, 7, 2, 216, 171, 89, 114, 0, 0, 12, 2, 219, 146, 71, 35, 70, 112, 15, 57, 114, 0, 7, 2, 216, 170, 47, 114, 0, 0, 0, 7, 2, 218, 152, 90, 114, 0, 7, 2, 216, 168, 71, 114, 0, 0, 8, 2, 216, 183, 47, 121, 114, 0, 0, 9, 2, 216, 182, 88, 122, 118, 72, 0, 0, 9, 2, 216, 181, 89, 122, 118, 72, 0, 0, 8, 2, 216, 180, 91, 112, 50, 0, 0, 8, 2, 216, 179, 89, 112, 50, 0, 0, 7, 2, 216, 178, 88, 114, 0, 0, 7, 2, 216, 177, 51, 114, 0, 0, 8, 2, 216, 176, 88, 118, 55, 0, 0, 8, 2, 218, 175, 81, 118, 83, 0, 0, 0, 0, 0, 0, 8, 2, 216, 186, 100, 134, 50, 0, 0, 8, 2, 218, 169, 49, 118, 83, 0, 7, 2, 216, 185, 134, 50, 0, 0, 8, 2, 216, 184, 88, 121, 114, 0, 0, 0, 7, 2, 217, 190, 48, 114, 0, 0, 0, 0, 0, 0, 7, 2, 217, 185, 140, 114, 0, 0, 0, 0, 16, 2, 218, 190, 72, 121, 15, 80, 35, 91, 65, 112, 15, 108, 114, 0, 0, 0, 0, 0, 10, 2, 218, 186, 147, 122, 50, 50, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 20, 96, 6, 0, 0, 48, 0, 0, 0, 97, 6, 0, 0, 49, 0, 0, 0, 98, 6, 0, 0, 50, 0, 0, 0, 99, 6, 0, 0, 51, 0, 0, 0, 100, 6, 0, 0, 52, 0, 0, 0, 101, 6, 0, 0, 53, 0, 0, 0, 102, 6, 0, 0, 54, 0, 0, 0, 103, 6, 0, 0, 55, 0, 0, 0, 104, 6, 0, 0, 56, 0, 0, 0, 105, 6, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 6, 18, 66, 217, 142, 0, 217, 144, 0, 217, 143, 0, 217, 136, 0, 219, 140, 0, 216, 185, 0, 216, 167, 0, 7, 6, 1, 34, 0, 3, 0, 7, 6, 1, 35, 0, 3, 118, 0, 7, 6, 1, 36, 0, 3, 0, 7, 6, 1, 37, 0, 3, 135, 0, 7, 6, 1, 39, 0, 3, 0, 7, 6, 1, 40, 0, 8, 2, 18, 66, 3, 0, 8, 3, 35, 0, 219, 140, 8, 3, 112, 0, 3, 118, 0, 217, 136, 8, 3, 123, 0, 7, 6, 1, 41, 0, 3, 71, 0, 218, 190, 3, 137, 0, 7, 6, 1, 43, 0, 3, 47, 0, 218, 190, 3, 138, 0, 7, 6, 1, 44, 0, 3, 89, 0, 7, 6, 1, 45, 0, 3, 79, 0, 218, 190, 3, 145, 0, 7, 6, 1, 46, 0, 3, 108, 0, 7, 6, 1, 47, 0, 3, 101, 0, 7, 6, 1, 48, 0, 3, 72, 0, 218, 190, 3, 139, 0, 7, 6, 1, 49, 0, 3, 86, 0, 7, 6, 1, 50, 0, 3, 51, 0, 7, 6, 1, 51, 0, 3, 88, 0, 7, 6, 1, 52, 0, 3, 89, 0, 7, 6, 1, 53, 0, 3, 91, 0, 7, 6, 1, 54, 0, 3, 93, 0, 7, 6, 1, 55, 0, 3, 88, 0, 7, 6, 1, 56, 0, 3, 47, 0, 218, 190, 3, 138, 0, 7, 6, 1, 57, 0, 3, 92, 0, 7, 6, 1, 58, 0, 8, 3, 35, 0, 4, 3, 118, 0, 216, 167, 0, 7, 6, 1, 59, 0, 3, 100, 0, 7, 6, 1, 66, 0, 3, 83, 0, 7, 6, 1, 67, 0, 3, 104, 0, 7, 6, 1, 69, 0, 3, 55, 0, 7, 6, 1, 70, 0, 3, 65, 0, 7, 6, 1, 71, 0, 3, 50, 0, 7, 6, 1, 73, 0, 4, 2, 18, 66, 3, 84, 0, 8, 0, 3, 119, 0, 4, 217, 143, 3, 123, 0, 217, 151, 0, 7, 6, 1, 79, 0, 3, 35, 0, 4, 219, 140, 3, 116, 0, 219, 146, 0, 216, 185, 3, 118, 0, 217, 136, 3, 121, 0, 7, 6, 1, 80, 0, 216, 185, 3, 121, 0, 3, 122, 0, 217, 136, 3, 123, 0, 7, 6, 1, 81, 0, 4, 216, 185, 3, 112, 0, 219, 140, 0, 3, 113, 0, 7, 6, 1, 122, 0, 3, 140, 0, 218, 190, 3, 142, 0, 7, 6, 1, 127, 0, 3, 48, 0, 218, 190, 3, 136, 0, 7, 6, 218, 134, 0, 3, 80, 0, 218, 190, 3, 144, 0, 7, 6, 218, 136, 0, 3, 141, 0, 218, 190, 3, 143, 0, 7, 6, 218, 145, 0, 3, 70, 0, 7, 6, 218, 152, 0, 3, 90, 0, 7, 6, 218, 169, 0, 3, 49, 0, 218, 190, 3, 146, 0, 7, 6, 218, 175, 0, 3, 81, 0, 218, 190, 3, 147, 0, 7, 6, 218, 186, 0, 3, 50, 0, 7, 6, 218, 190, 0, 3, 108, 0, 7, 6, 219, 129, 0, 2, 32, 3, 35, 0, 3, 108, 0, 7, 6, 219, 140, 0, 4, 2, 18, 66, 3, 57, 0, 8, 0, 2, 32, 3, 112, 0, 3, 114, 0, 7, 6, 219, 146, 0, 3, 114, 0, 7, 6, 224, 164, 0, 3, 21, 104, 105, 0, 7, 6, 224, 165, 0, 3, 21, 104, 105, 0, 7, 6, 0, 36, 3, 72, 119, 55, 13, 51, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts67 = FileInMemory_createWithData (3430, reinterpret_cast (&espeakdata_dicts67_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/ur_dict", U"ur"); Collection_addItem (me.peek(), espeakdata_dicts67.transfer()); static unsigned char espeakdata_dicts68_data[5837] = { 0, 4, 0, 0, 100, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 8, 71, 36, 0, 0, 0, 0, 0, 6, 65, 12, 89, 36, 0, 0, 0, 0, 0, 6, 65, 16, 72, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 65, 24, 115, 109, 48, 0, 0, 0, 0, 0, 8, 65, 28, 86, 6, 36, 113, 0, 0, 0, 0, 0, 8, 65, 32, 107, 35, 109, 47, 0, 0, 0, 7, 132, 196, 145, 195, 163, 72, 0, 14, 1, 35, 79, 6, 134, 109, 47, 6, 35, 113, 68, 0, 27, 0, 17, 1, 36, 79, 6, 134, 109, 10, 72, 6, 39, 17, 55, 6, 114, 113, 0, 0, 15, 1, 37, 83, 6, 13, 108, 50, 80, 34, 6, 35, 113, 65, 0, 0, 12, 1, 38, 79, 6, 134, 109, 84, 4, 114, 108, 0, 0, 0, 6, 65, 40, 81, 37, 0, 0, 0, 13, 1, 42, 79, 6, 134, 109, 93, 6, 130, 113, 0, 27, 0, 14, 1, 43, 79, 6, 134, 109, 49, 6, 39, 112, 68, 0, 27, 0, 6, 65, 44, 49, 114, 0, 0, 0, 0, 0, 8, 65, 48, 115, 55, 118, 108, 0, 0, 0, 6, 131, 22, 195, 172, 72, 0, 0, 8, 65, 52, 115, 65, 118, 108, 0, 0, 0, 0, 0, 12, 5, 95, 48, 1, 14, 4, 55, 4, 37, 67, 0, 8, 65, 56, 115, 50, 118, 108, 0, 0, 0, 0, 0, 0, 15, 1, 61, 79, 6, 134, 109, 10, 71, 6, 35, 108, 68, 0, 27, 0, 6, 131, 22, 195, 160, 72, 0, 0, 11, 1, 64, 114, 17, 49, 6, 116, 108, 68, 0, 6, 65, 64, 48, 36, 0, 0, 0, 0, 0, 7, 65, 68, 49, 58, 37, 0, 0, 8, 133, 13, 225, 187, 151, 9, 72, 0, 0, 0, 8, 65, 72, 115, 92, 118, 108, 0, 0, 0, 0, 0, 7, 65, 76, 115, 109, 89, 0, 0, 0, 0, 0, 6, 65, 80, 47, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 65, 88, 84, 36, 0, 0, 0, 0, 0, 12, 65, 92, 84, 6, 36, 49, 4, 115, 109, 48, 0, 0, 0, 12, 1, 94, 79, 6, 134, 109, 65, 6, 40, 111, 0, 0, 0, 14, 1, 96, 79, 6, 134, 109, 107, 58, 6, 136, 108, 50, 0, 7, 65, 96, 37, 109, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 65, 104, 88, 115, 109, 47, 0, 0, 0, 0, 0, 7, 132, 19, 225, 186, 189, 72, 0, 7, 132, 3, 195, 178, 14, 72, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 13, 225, 187, 141, 9, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 1, 126, 79, 6, 134, 109, 68, 6, 114, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 135, 14, 8, 225, 187, 175, 14, 7, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 132, 20, 8, 195, 172, 72, 7, 132, 14, 8, 198, 176, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 4, 16, 20, 10, 83, 4, 121, 110, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 8, 15, 225, 186, 183, 3, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 135, 3, 8, 225, 186, 179, 14, 7, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 14, 8, 198, 176, 14, 7, 72, 0, 0, 0, 0, 0, 0, 0, 21, 3, 95, 50, 49, 107, 6, 120, 15, 65, 6, 137, 113, 57, 15, 65, 6, 39, 109, 74, 0, 0, 0, 0, 0, 21, 3, 95, 50, 53, 107, 6, 120, 15, 65, 6, 137, 113, 57, 15, 55, 6, 35, 113, 65, 0, 0, 0, 0, 0, 22, 3, 95, 51, 49, 10, 71, 6, 114, 15, 65, 6, 137, 113, 57, 15, 65, 6, 39, 109, 74, 0, 0, 0, 0, 0, 22, 3, 95, 51, 53, 10, 71, 6, 114, 15, 65, 6, 137, 113, 57, 15, 55, 6, 35, 113, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 3, 95, 54, 49, 93, 6, 129, 109, 15, 65, 6, 137, 113, 57, 15, 65, 6, 39, 109, 74, 0, 0, 16, 3, 95, 51, 88, 10, 71, 6, 114, 15, 65, 6, 137, 113, 57, 0, 0, 11, 3, 95, 48, 67, 80, 34, 6, 35, 65, 0, 0, 0, 22, 3, 95, 54, 53, 93, 6, 129, 109, 15, 65, 6, 137, 113, 57, 15, 55, 6, 35, 113, 65, 0, 0, 0, 0, 0, 23, 3, 95, 55, 49, 10, 71, 6, 119, 110, 15, 65, 6, 137, 113, 57, 15, 65, 6, 39, 109, 74, 0, 0, 0, 0, 0, 23, 3, 95, 55, 53, 10, 71, 6, 119, 110, 15, 65, 6, 137, 113, 57, 15, 55, 6, 35, 113, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 132, 14, 195, 170, 14, 72, 0, 17, 3, 95, 55, 88, 10, 71, 6, 119, 110, 15, 65, 6, 137, 113, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 3, 95, 52, 49, 10, 71, 6, 39, 109, 50, 15, 65, 6, 137, 113, 57, 15, 65, 6, 39, 109, 74, 0, 0, 11, 3, 95, 49, 88, 65, 6, 137, 108, 57, 0, 0, 0, 9, 134, 16, 8, 225, 186, 163, 9, 72, 0, 24, 3, 95, 52, 53, 10, 71, 6, 39, 109, 50, 15, 65, 6, 137, 113, 57, 15, 55, 6, 35, 113, 65, 0, 0, 0, 0, 0, 22, 3, 95, 53, 49, 50, 6, 35, 65, 15, 65, 6, 137, 113, 57, 15, 65, 6, 39, 109, 74, 0, 0, 6, 131, 12, 195, 160, 72, 15, 3, 95, 50, 88, 107, 6, 120, 15, 65, 6, 137, 113, 57, 0, 0, 0, 0, 8, 133, 196, 145, 225, 187, 131, 72, 22, 3, 95, 53, 53, 50, 6, 35, 65, 15, 65, 6, 137, 113, 57, 15, 55, 6, 35, 113, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 3, 95, 52, 88, 10, 71, 6, 39, 109, 50, 15, 65, 6, 137, 113, 57, 0, 0, 0, 0, 0, 0, 0, 0, 23, 3, 95, 56, 49, 74, 6, 114, 109, 65, 15, 65, 6, 137, 113, 57, 15, 65, 6, 39, 109, 74, 0, 0, 16, 3, 95, 53, 88, 50, 6, 35, 65, 15, 65, 6, 137, 113, 57, 0, 0, 0, 0, 23, 3, 95, 56, 53, 74, 6, 114, 109, 65, 15, 65, 6, 137, 113, 57, 15, 55, 6, 35, 113, 65, 0, 0, 0, 0, 0, 23, 3, 95, 57, 49, 80, 6, 37, 109, 50, 15, 65, 6, 137, 113, 57, 15, 65, 6, 39, 109, 74, 0, 0, 16, 3, 95, 54, 88, 93, 6, 129, 109, 15, 65, 6, 137, 113, 57, 0, 0, 0, 0, 23, 3, 95, 57, 53, 80, 6, 37, 109, 50, 15, 65, 6, 137, 113, 57, 15, 55, 6, 35, 113, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 3, 95, 56, 88, 74, 6, 114, 109, 65, 15, 65, 6, 137, 113, 57, 0, 0, 0, 0, 0, 0, 8, 133, 4, 225, 186, 171, 21, 72, 0, 0, 0, 17, 3, 95, 57, 88, 80, 6, 37, 109, 50, 15, 65, 6, 137, 113, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 131, 13, 195, 160, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 22, 225, 187, 155, 9, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 132, 12, 195, 186, 3, 72, 0, 0, 0, 0, 0, 0, 0, 13, 4, 95, 48, 77, 50, 80, 34, 6, 136, 112, 58, 0, 0, 11, 4, 95, 48, 77, 51, 74, 6, 37, 110, 0, 0, 0, 12, 4, 95, 48, 77, 49, 68, 6, 114, 108, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 136, 11, 8, 15, 225, 186, 163, 14, 7, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 11, 8, 195, 180, 14, 7, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 132, 20, 225, 187, 171, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 20, 225, 187, 155, 9, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 196, 145, 72, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 132, 2, 225, 187, 139, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 14, 225, 186, 191, 21, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 196, 145, 1, 14, 7, 72, 0, 0, 0, 19, 2, 95, 33, 79, 6, 134, 109, 80, 6, 13, 109, 65, 47, 6, 114, 113, 50, 0, 0, 0, 6, 195, 12, 243, 128, 72, 17, 2, 95, 39, 68, 58, 6, 35, 112, 139, 10, 72, 6, 118, 113, 50, 0, 0, 0, 11, 136, 196, 145, 198, 176, 225, 187, 163, 3, 72, 0, 0, 0, 0, 17, 2, 95, 41, 10, 72, 6, 116, 109, 68, 68, 58, 6, 35, 112, 139, 0, 0, 15, 2, 95, 40, 65, 6, 118, 110, 68, 58, 6, 35, 112, 139, 0, 0, 14, 2, 95, 47, 89, 6, 39, 110, 80, 34, 6, 120, 109, 0, 0, 10, 2, 95, 46, 80, 6, 13, 109, 65, 0, 0, 15, 2, 95, 45, 100, 6, 114, 112, 80, 68, 6, 114, 113, 68, 0, 0, 9, 2, 95, 44, 83, 6, 121, 110, 0, 0, 9, 2, 95, 51, 10, 71, 6, 114, 0, 0, 8, 133, 3, 8, 198, 176, 1, 72, 8, 2, 95, 50, 107, 6, 120, 0, 0, 10, 2, 95, 49, 65, 6, 39, 112, 74, 0, 0, 10, 2, 95, 48, 101, 4, 39, 17, 68, 0, 0, 10, 2, 95, 55, 10, 71, 6, 119, 110, 0, 0, 9, 2, 95, 54, 93, 6, 129, 109, 0, 0, 9, 2, 95, 53, 50, 6, 35, 65, 0, 0, 11, 2, 95, 52, 10, 71, 6, 39, 109, 50, 0, 0, 14, 2, 95, 59, 80, 6, 13, 109, 65, 83, 6, 121, 110, 0, 0, 14, 2, 95, 58, 107, 6, 120, 17, 80, 6, 13, 109, 65, 0, 0, 10, 2, 95, 57, 80, 6, 37, 109, 50, 0, 0, 10, 2, 95, 56, 74, 6, 114, 109, 65, 0, 0, 14, 2, 95, 63, 107, 6, 125, 110, 80, 6, 13, 109, 65, 0, 0, 15, 2, 95, 62, 55, 6, 118, 109, 50, 107, 6, 118, 113, 50, 0, 0, 0, 14, 2, 95, 60, 67, 6, 116, 110, 107, 6, 118, 113, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 133, 22, 225, 186, 171, 14, 72, 0, 0, 0, 0, 0, 0, 0, 0, 20, 2, 95, 91, 65, 6, 118, 110, 68, 58, 6, 35, 112, 139, 84, 6, 138, 113, 68, 0, 0, 18, 4, 95, 226, 128, 156, 68, 58, 6, 35, 112, 139, 49, 6, 115, 109, 48, 0, 0, 0, 0, 15, 2, 95, 95, 100, 6, 114, 112, 80, 79, 6, 137, 109, 57, 0, 0, 0, 22, 2, 95, 93, 10, 72, 6, 116, 109, 68, 68, 58, 6, 35, 112, 139, 84, 6, 138, 113, 68, 0, 0, 13, 2, 95, 92, 89, 6, 39, 110, 83, 4, 120, 110, 0, 0, 6, 195, 44, 130, 64, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 2, 95, 123, 65, 6, 118, 110, 68, 58, 6, 35, 112, 139, 67, 6, 116, 112, 50, 0, 0, 0, 0, 0, 0, 0, 22, 2, 95, 125, 10, 72, 6, 116, 109, 68, 68, 58, 6, 35, 112, 139, 67, 6, 116, 112, 50, 0, 0, 14, 2, 95, 124, 89, 6, 39, 110, 47, 6, 35, 110, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 70, 36, 229, 5, 72, 225, 84, 37, 50, 47, 118, 50, 6, 115, 109, 47, 0, 0, 0, 0, 0, 0, 0, 8, 133, 2, 225, 187, 159, 9, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 131, 4, 195, 185, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 12, 131, 192, 72, 0, 8, 133, 3, 225, 187, 167, 1, 72, 0, 0, 0, 7, 132, 3, 195, 161, 9, 72, 0, 0, 0, 0, 0, 0, 7, 132, 3, 195, 161, 3, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 134, 196, 145, 225, 186, 191, 14, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 20, 0, 0, 97, 0, 0, 3, 224, 0, 0, 0, 97, 0, 1, 3, 225, 0, 0, 0, 97, 0, 9, 3, 163, 30, 0, 0, 97, 0, 3, 3, 227, 0, 0, 0, 97, 0, 35, 3, 161, 30, 0, 0, 3, 1, 0, 3, 177, 30, 0, 0, 3, 1, 1, 3, 175, 30, 0, 0, 3, 1, 9, 3, 179, 30, 0, 0, 3, 1, 3, 3, 181, 30, 0, 0, 3, 1, 35, 3, 183, 30, 0, 0, 226, 0, 0, 3, 167, 30, 0, 0, 226, 0, 1, 3, 165, 30, 0, 0, 226, 0, 9, 3, 169, 30, 0, 0, 226, 0, 3, 3, 171, 30, 0, 0, 226, 0, 35, 3, 173, 30, 0, 0, 101, 0, 0, 3, 232, 0, 0, 0, 101, 0, 1, 3, 233, 0, 0, 0, 101, 0, 9, 3, 187, 30, 0, 0, 101, 0, 3, 3, 189, 30, 0, 0, 101, 0, 35, 3, 185, 30, 0, 0, 234, 0, 0, 3, 193, 30, 0, 0, 234, 0, 1, 3, 191, 30, 0, 0, 234, 0, 9, 3, 195, 30, 0, 0, 234, 0, 3, 3, 197, 30, 0, 0, 234, 0, 35, 3, 199, 30, 0, 0, 105, 0, 0, 3, 236, 0, 0, 0, 105, 0, 1, 3, 237, 0, 0, 0, 105, 0, 9, 3, 201, 30, 0, 0, 105, 0, 3, 3, 41, 1, 0, 0, 105, 0, 35, 3, 203, 30, 0, 0, 111, 0, 0, 3, 242, 0, 0, 0, 111, 0, 1, 3, 243, 0, 0, 0, 111, 0, 9, 3, 207, 30, 0, 0, 111, 0, 3, 3, 245, 0, 0, 0, 111, 0, 35, 3, 205, 30, 0, 0, 244, 0, 0, 3, 211, 30, 0, 0, 244, 0, 1, 3, 209, 30, 0, 0, 244, 0, 9, 3, 213, 30, 0, 0, 244, 0, 3, 3, 215, 30, 0, 0, 244, 0, 35, 3, 217, 30, 0, 0, 161, 1, 0, 3, 221, 30, 0, 0, 161, 1, 1, 3, 219, 30, 0, 0, 161, 1, 9, 3, 223, 30, 0, 0, 161, 1, 3, 3, 225, 30, 0, 0, 161, 1, 35, 3, 227, 30, 0, 0, 117, 0, 0, 3, 249, 0, 0, 0, 117, 0, 1, 3, 250, 0, 0, 0, 117, 0, 9, 3, 231, 30, 0, 0, 117, 0, 3, 3, 105, 1, 0, 0, 117, 0, 35, 3, 229, 30, 0, 0, 176, 1, 0, 3, 235, 30, 0, 0, 176, 1, 1, 3, 233, 30, 0, 0, 176, 1, 9, 3, 237, 30, 0, 0, 176, 1, 3, 3, 239, 30, 0, 0, 176, 1, 35, 3, 241, 30, 0, 0, 121, 0, 0, 3, 243, 30, 0, 0, 121, 0, 1, 3, 253, 0, 0, 0, 121, 0, 9, 3, 247, 30, 0, 0, 121, 0, 3, 3, 249, 30, 0, 0, 121, 0, 35, 3, 245, 30, 0, 0, 0, 0, 0, 0, 6, 195, 160, 0, 3, 114, 108, 0, 121, 3, 119, 108, 0, 105, 3, 120, 108, 0, 117, 3, 129, 108, 0, 111, 3, 130, 108, 0, 7, 6, 195, 161, 0, 3, 114, 109, 0, 121, 3, 119, 109, 0, 105, 3, 120, 109, 0, 117, 3, 129, 109, 0, 111, 3, 130, 109, 0, 7, 6, 195, 162, 0, 3, 13, 0, 121, 3, 121, 0, 117, 3, 134, 0, 7, 6, 195, 163, 0, 3, 114, 111, 0, 121, 3, 119, 111, 0, 105, 3, 120, 111, 0, 117, 3, 129, 111, 0, 111, 3, 130, 111, 0, 7, 6, 195, 168, 0, 3, 115, 108, 0, 111, 3, 132, 108, 0, 7, 6, 195, 169, 0, 3, 115, 109, 0, 111, 3, 132, 109, 0, 7, 6, 195, 170, 0, 3, 36, 0, 117, 3, 131, 0, 7, 6, 195, 172, 0, 3, 37, 108, 0, 2, 17, 65, 3, 57, 108, 0, 117, 3, 133, 108, 0, 97, 3, 136, 108, 0, 7, 6, 195, 173, 0, 3, 37, 109, 0, 2, 17, 65, 3, 57, 109, 0, 117, 3, 133, 109, 0, 97, 3, 136, 109, 0, 7, 6, 195, 177, 0, 3, 67, 0, 7, 6, 195, 178, 0, 2, 17, 65, 3, 58, 108, 0, 3, 116, 108, 0, 105, 3, 125, 108, 0, 7, 6, 195, 179, 0, 2, 17, 65, 3, 58, 109, 0, 3, 116, 109, 0, 105, 3, 125, 109, 0, 7, 6, 195, 180, 0, 3, 39, 0, 105, 3, 126, 0, 7, 6, 195, 181, 0, 2, 17, 65, 3, 58, 111, 0, 3, 116, 111, 0, 105, 3, 125, 111, 0, 7, 6, 195, 185, 0, 3, 40, 108, 0, 2, 17, 65, 3, 58, 108, 0, 105, 3, 127, 108, 0, 97, 3, 138, 108, 0, 7, 6, 195, 186, 0, 3, 40, 109, 0, 2, 17, 65, 3, 58, 109, 0, 105, 3, 127, 109, 0, 97, 3, 138, 109, 0, 7, 6, 195, 189, 0, 3, 37, 109, 0, 2, 17, 65, 3, 57, 109, 0, 97, 3, 136, 109, 0, 7, 6, 196, 131, 0, 3, 35, 0, 7, 6, 196, 145, 0, 8, 3, 10, 72, 0, 3, 72, 0, 7, 6, 196, 169, 0, 3, 37, 111, 0, 2, 17, 65, 3, 57, 111, 0, 117, 3, 133, 111, 0, 97, 3, 136, 111, 0, 7, 6, 197, 169, 0, 3, 40, 111, 0, 2, 17, 65, 3, 58, 111, 0, 105, 3, 127, 111, 0, 97, 3, 138, 111, 0, 7, 6, 198, 161, 0, 3, 118, 0, 105, 3, 122, 0, 117, 3, 135, 0, 7, 6, 198, 176, 0, 3, 117, 0, 117, 3, 117, 58, 0, 105, 3, 128, 0, 4, 97, 3, 137, 0, 198, 161, 0, 198, 161, 105, 3, 137, 57, 0, 225, 187, 157, 105, 3, 137, 57, 108, 0, 225, 187, 155, 105, 3, 137, 57, 109, 0, 225, 187, 159, 105, 3, 137, 57, 110, 0, 225, 187, 161, 105, 3, 137, 57, 111, 0, 225, 187, 163, 105, 3, 137, 57, 112, 0, 198, 161, 117, 3, 137, 58, 0, 225, 187, 157, 117, 3, 137, 58, 108, 0, 225, 187, 155, 117, 3, 137, 58, 109, 0, 225, 187, 159, 117, 3, 137, 58, 110, 0, 225, 187, 161, 117, 3, 137, 58, 111, 0, 225, 187, 163, 117, 3, 137, 58, 112, 0, 225, 187, 157, 3, 137, 108, 0, 225, 187, 155, 3, 137, 109, 0, 225, 187, 159, 3, 137, 110, 0, 225, 187, 161, 3, 137, 111, 0, 225, 187, 163, 3, 137, 112, 0, 7, 6, 225, 186, 0, 163, 3, 114, 110, 0, 163, 121, 3, 119, 110, 0, 163, 105, 3, 120, 110, 0, 163, 117, 3, 129, 110, 0, 163, 111, 3, 130, 110, 0, 161, 3, 114, 112, 0, 161, 121, 3, 119, 112, 0, 161, 105, 3, 120, 112, 0, 161, 117, 3, 129, 112, 0, 161, 111, 3, 130, 112, 0, 177, 3, 35, 108, 0, 175, 3, 35, 109, 0, 179, 3, 35, 110, 0, 181, 3, 35, 111, 0, 183, 3, 35, 112, 0, 167, 3, 13, 108, 0, 167, 121, 3, 121, 108, 0, 167, 117, 3, 134, 108, 0, 165, 3, 13, 109, 0, 165, 121, 3, 121, 109, 0, 165, 117, 3, 134, 109, 0, 169, 3, 13, 110, 0, 169, 121, 3, 121, 110, 0, 169, 117, 3, 134, 110, 0, 171, 3, 13, 111, 0, 171, 121, 3, 121, 111, 0, 171, 117, 3, 134, 111, 0, 173, 3, 13, 112, 0, 173, 121, 3, 121, 112, 0, 173, 117, 3, 134, 112, 0, 187, 3, 115, 110, 0, 187, 111, 3, 132, 110, 0, 189, 3, 115, 111, 0, 189, 111, 3, 132, 111, 0, 185, 3, 115, 112, 0, 185, 111, 3, 132, 112, 0, 191, 3, 36, 109, 0, 191, 117, 3, 131, 109, 0, 7, 6, 225, 187, 0, 129, 3, 36, 108, 0, 129, 117, 3, 131, 108, 0, 131, 3, 36, 110, 0, 131, 117, 3, 131, 110, 0, 133, 3, 36, 111, 0, 133, 117, 3, 131, 111, 0, 135, 3, 36, 112, 0, 135, 117, 3, 131, 112, 0, 137, 3, 37, 110, 0, 137, 2, 17, 65, 3, 57, 110, 0, 137, 117, 3, 133, 110, 0, 137, 97, 3, 136, 110, 0, 139, 3, 37, 112, 0, 139, 2, 17, 65, 3, 57, 112, 0, 139, 117, 3, 133, 112, 0, 139, 97, 3, 136, 112, 0, 143, 2, 17, 65, 3, 58, 110, 0, 143, 3, 116, 110, 0, 143, 105, 3, 125, 110, 0, 141, 2, 17, 65, 3, 58, 112, 0, 141, 3, 116, 112, 0, 141, 105, 3, 125, 112, 0, 147, 3, 39, 108, 0, 147, 105, 3, 126, 108, 0, 145, 3, 39, 109, 0, 145, 105, 3, 126, 109, 0, 149, 3, 39, 110, 0, 149, 105, 3, 126, 110, 0, 151, 3, 39, 111, 0, 151, 105, 3, 126, 111, 0, 153, 3, 39, 112, 0, 153, 105, 3, 126, 112, 0, 157, 3, 118, 108, 0, 157, 105, 3, 122, 108, 0, 157, 117, 3, 135, 108, 0, 155, 3, 118, 109, 0, 155, 105, 3, 122, 109, 0, 155, 117, 3, 135, 109, 0, 159, 3, 118, 110, 0, 159, 105, 3, 122, 110, 0, 159, 117, 3, 135, 110, 0, 161, 3, 118, 111, 0, 161, 105, 3, 122, 111, 0, 161, 117, 3, 135, 111, 0, 163, 3, 118, 112, 0, 163, 105, 3, 122, 112, 0, 163, 117, 3, 135, 112, 0, 167, 3, 40, 110, 0, 167, 2, 17, 65, 3, 58, 110, 0, 167, 105, 3, 127, 110, 0, 167, 97, 3, 138, 110, 0, 165, 3, 40, 112, 0, 165, 2, 17, 65, 3, 58, 112, 0, 165, 105, 3, 127, 112, 0, 165, 97, 3, 138, 112, 0, 171, 117, 3, 117, 58, 108, 0, 171, 3, 117, 108, 0, 171, 105, 3, 128, 108, 0, 171, 97, 3, 137, 108, 0, 169, 117, 3, 117, 58, 109, 0, 169, 3, 117, 109, 0, 169, 105, 3, 128, 109, 0, 169, 97, 3, 137, 109, 0, 173, 117, 3, 117, 58, 110, 0, 173, 3, 117, 110, 0, 173, 105, 3, 128, 110, 0, 173, 97, 3, 137, 110, 0, 175, 117, 3, 117, 58, 111, 0, 175, 3, 117, 111, 0, 175, 105, 3, 128, 111, 0, 175, 97, 3, 137, 111, 0, 177, 117, 3, 117, 58, 112, 0, 177, 3, 117, 112, 0, 177, 105, 3, 128, 112, 0, 177, 97, 3, 137, 112, 0, 179, 3, 37, 108, 0, 179, 2, 17, 65, 3, 57, 108, 0, 179, 97, 3, 136, 108, 0, 183, 3, 37, 110, 0, 183, 2, 17, 65, 3, 57, 110, 0, 183, 97, 3, 136, 110, 0, 185, 3, 37, 111, 0, 185, 2, 17, 65, 3, 57, 111, 0, 185, 97, 3, 136, 111, 0, 181, 3, 37, 112, 0, 181, 2, 17, 65, 3, 57, 112, 0, 181, 97, 3, 136, 112, 0, 7, 6, 97, 0, 3, 114, 0, 121, 3, 119, 0, 225, 187, 179, 3, 119, 108, 0, 195, 189, 3, 119, 109, 0, 225, 187, 183, 3, 119, 110, 0, 225, 187, 185, 3, 119, 111, 0, 225, 187, 181, 3, 119, 112, 0, 105, 3, 120, 0, 195, 172, 3, 120, 108, 0, 195, 173, 3, 120, 109, 0, 225, 187, 137, 3, 120, 110, 0, 196, 169, 3, 120, 111, 0, 225, 187, 139, 3, 120, 112, 0, 117, 3, 129, 0, 195, 185, 3, 129, 108, 0, 195, 186, 3, 129, 109, 0, 225, 187, 167, 3, 129, 110, 0, 197, 169, 3, 129, 111, 0, 225, 187, 165, 3, 129, 112, 0, 111, 3, 130, 0, 195, 178, 3, 130, 108, 0, 195, 179, 3, 130, 109, 0, 225, 187, 143, 3, 130, 110, 0, 195, 181, 3, 130, 111, 0, 225, 187, 141, 3, 130, 112, 0, 7, 6, 98, 0, 8, 3, 10, 71, 0, 3, 71, 0, 7, 6, 99, 0, 3, 49, 0, 104, 3, 80, 0, 2, 32, 3, 139, 0, 7, 6, 100, 0, 3, 79, 0, 7, 6, 101, 0, 3, 115, 0, 111, 3, 132, 0, 195, 178, 3, 132, 108, 0, 195, 179, 3, 132, 109, 0, 225, 187, 143, 3, 132, 110, 0, 225, 187, 151, 3, 132, 111, 0, 225, 187, 141, 3, 132, 112, 0, 7, 6, 102, 0, 3, 83, 0, 7, 6, 103, 0, 4, 2, 105, 3, 86, 0, 2, 195, 172, 0, 2, 195, 173, 0, 2, 196, 169, 0, 2, 225, 187, 137, 0, 2, 225, 187, 139, 0, 105, 0, 4, 3, 100, 0, 104, 0, 7, 6, 104, 0, 3, 107, 0, 7, 6, 105, 0, 3, 37, 0, 2, 17, 65, 3, 57, 0, 117, 3, 133, 0, 195, 185, 3, 133, 108, 0, 195, 186, 3, 133, 109, 0, 225, 187, 167, 3, 133, 110, 0, 197, 169, 3, 133, 111, 0, 225, 187, 165, 3, 133, 112, 0, 4, 97, 3, 136, 0, 195, 170, 0, 4, 195, 160, 3, 136, 108, 0, 225, 187, 129, 0, 4, 195, 161, 3, 136, 109, 0, 225, 186, 191, 0, 4, 225, 186, 163, 3, 136, 110, 0, 225, 187, 131, 0, 4, 195, 163, 3, 136, 111, 0, 225, 187, 133, 0, 4, 225, 186, 161, 3, 136, 112, 0, 225, 187, 135, 0, 7, 6, 106, 0, 3, 90, 0, 7, 6, 107, 0, 3, 49, 0, 104, 3, 101, 0, 2, 32, 3, 139, 0, 7, 6, 108, 0, 3, 55, 0, 7, 6, 109, 0, 3, 65, 0, 7, 6, 110, 0, 3, 50, 0, 104, 3, 67, 0, 4, 103, 3, 68, 0, 103, 104, 0, 7, 6, 111, 0, 2, 17, 65, 3, 58, 0, 3, 116, 0, 105, 3, 125, 0, 195, 172, 3, 125, 108, 0, 195, 173, 3, 125, 109, 0, 225, 187, 137, 3, 125, 110, 0, 196, 169, 3, 125, 111, 0, 225, 187, 139, 3, 125, 112, 0, 7, 6, 112, 0, 3, 48, 0, 104, 3, 83, 0, 7, 6, 113, 0, 3, 49, 0, 117, 3, 49, 58, 0, 2, 32, 3, 139, 0, 7, 6, 114, 0, 3, 92, 0, 7, 6, 115, 0, 3, 93, 0, 7, 6, 116, 0, 104, 3, 47, 0, 3, 74, 0, 114, 3, 80, 34, 0, 7, 6, 117, 0, 3, 40, 0, 4, 1, 17, 65, 3, 58, 0, 2, 17, 65, 0, 105, 3, 127, 0, 195, 172, 3, 127, 108, 0, 195, 173, 3, 127, 109, 0, 225, 187, 137, 3, 127, 110, 0, 196, 169, 3, 127, 111, 0, 225, 187, 139, 3, 127, 112, 0, 4, 97, 3, 138, 0, 195, 180, 0, 195, 180, 105, 3, 138, 57, 0, 225, 187, 147, 105, 3, 138, 57, 108, 0, 225, 187, 145, 105, 3, 138, 57, 109, 0, 225, 187, 149, 105, 3, 138, 57, 110, 0, 225, 187, 151, 105, 3, 138, 57, 111, 0, 225, 187, 153, 105, 3, 138, 57, 112, 0, 4, 195, 160, 3, 138, 108, 0, 225, 187, 147, 0, 4, 195, 161, 3, 138, 109, 0, 225, 187, 145, 0, 4, 225, 186, 163, 3, 138, 110, 0, 225, 187, 149, 0, 4, 195, 163, 3, 138, 111, 0, 225, 187, 151, 0, 4, 225, 186, 161, 3, 138, 112, 0, 225, 187, 153, 0, 7, 6, 118, 0, 3, 84, 0, 7, 6, 119, 0, 3, 58, 0, 7, 6, 120, 0, 3, 89, 0, 7, 6, 121, 0, 3, 37, 0, 2, 17, 65, 3, 57, 0, 4, 97, 3, 136, 0, 195, 170, 0, 4, 195, 160, 3, 136, 108, 0, 225, 187, 129, 0, 4, 195, 161, 3, 136, 109, 0, 225, 186, 191, 0, 4, 225, 186, 163, 3, 136, 110, 0, 225, 187, 131, 0, 4, 195, 163, 3, 136, 111, 0, 225, 187, 133, 0, 4, 225, 186, 161, 3, 136, 112, 0, 225, 187, 135, 0, 7, 6, 122, 0, 3, 88, 0, 7, 6, 206, 0, 4, 174, 3, 36, 17, 23, 74, 6, 114, 17, 0, 183, 0, 4, 175, 3, 37, 17, 23, 6, 39, 17, 23, 74, 6, 114, 17, 0, 185, 0, 191, 3, 39, 17, 23, 65, 6, 37, 17, 23, 49, 92, 6, 116, 113, 50, 0, 184, 3, 47, 6, 36, 17, 23, 74, 6, 114, 17, 0, 186, 3, 49, 6, 114, 17, 48, 23, 48, 6, 114, 17, 0, 189, 3, 50, 58, 6, 37, 17, 0, 187, 3, 55, 6, 35, 17, 65, 23, 10, 72, 6, 114, 17, 0, 188, 3, 65, 58, 6, 37, 17, 0, 178, 3, 71, 6, 36, 17, 23, 74, 6, 114, 17, 0, 180, 3, 79, 6, 115, 17, 50, 23, 74, 6, 114, 17, 0, 182, 3, 86, 6, 36, 17, 23, 74, 6, 114, 17, 0, 190, 3, 89, 6, 37, 113, 0, 179, 3, 100, 6, 114, 17, 23, 65, 6, 114, 17, 0, 4, 172, 3, 114, 17, 50, 23, 83, 6, 114, 17, 0, 177, 0, 4, 173, 3, 115, 17, 48, 23, 89, 6, 37, 17, 23, 55, 6, 116, 17, 50, 0, 181, 0, 7, 6, 207, 0, 4, 137, 3, 39, 17, 23, 65, 6, 36, 17, 23, 100, 6, 114, 113, 0, 142, 0, 140, 3, 39, 17, 23, 65, 6, 37, 17, 23, 49, 92, 6, 116, 113, 50, 0, 4, 133, 3, 40, 17, 48, 23, 89, 6, 37, 17, 23, 55, 6, 116, 17, 50, 0, 141, 0, 128, 3, 48, 6, 37, 17, 0, 136, 3, 48, 89, 6, 37, 17, 0, 132, 3, 74, 6, 39, 17, 0, 135, 3, 80, 6, 37, 17, 0, 134, 3, 83, 6, 37, 17, 0, 4, 130, 3, 89, 6, 37, 109, 80, 23, 65, 6, 114, 17, 0, 131, 0, 129, 3, 92, 6, 39, 17, 0, 7, 6, 0, 4, 33, 2, 33, 3, 0, 46, 1, 46, 3, 0, 46, 2, 46, 3, 9, 0, 33, 3, 9, 80, 6, 13, 109, 65, 23, 47, 6, 114, 113, 50, 9, 0, 4, 45, 1, 32, 17, 65, 2, 32, 15, 3, 10, 0, 45, 1, 32, 17, 67, 2, 32, 15, 0, 62, 61, 3, 55, 6, 118, 109, 50, 23, 107, 6, 118, 17, 50, 23, 107, 58, 4, 35, 112, 139, 10, 71, 6, 35, 108, 68, 0, 60, 61, 3, 67, 6, 116, 110, 23, 107, 6, 118, 17, 50, 23, 107, 58, 4, 35, 112, 139, 10, 71, 6, 35, 108, 68, 0, 36, 3, 72, 6, 39, 15, 55, 6, 35, 0, 46, 3, 80, 6, 13, 109, 65, 10, 0, 45, 8, 32, 2, 32, 15, 3, 80, 34, 6, 117, 108, 0, 37, 3, 83, 6, 13, 108, 50, 15, 78, 6, 35, 65, 0, 104, 1, 32, 15, 2, 32, 15, 15, 32, 3, 86, 6, 118, 108, 0, 33, 61, 3, 101, 4, 39, 17, 68, 23, 10, 71, 6, 35, 108, 68, 10, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts68 = FileInMemory_createWithData (5836, reinterpret_cast (&espeakdata_dicts68_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/vi_dict", U"vi"); Collection_addItem (me.peek(), espeakdata_dicts68.transfer()); static unsigned char espeakdata_dicts69_data[1735] = { 0, 4, 0, 0, 85, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 5, 95, 48, 1, 14, 4, 2, 35, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 51, 88, 67, 6, 111, 47, 12, 83, 40, 49, 12, 0, 0, 12, 3, 95, 48, 67, 47, 6, 110, 65, 110, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 95, 49, 67, 47, 6, 110, 65, 110, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 3, 95, 55, 88, 79, 6, 40, 52, 116, 65, 67, 113, 52, 83, 40, 49, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 95, 49, 88, 83, 6, 40, 49, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 95, 50, 88, 67, 6, 113, 52, 83, 40, 49, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 95, 52, 88, 67, 6, 112, 50, 47, 83, 40, 49, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 3, 95, 53, 88, 79, 6, 40, 52, 116, 65, 83, 40, 49, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 3, 95, 54, 88, 79, 6, 40, 52, 116, 65, 71, 111, 50, 12, 83, 40, 49, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 3, 95, 56, 88, 79, 6, 40, 52, 116, 65, 67, 111, 47, 12, 83, 40, 49, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 3, 95, 57, 88, 79, 6, 40, 52, 116, 65, 67, 112, 50, 47, 83, 40, 49, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 4, 95, 48, 77, 50, 47, 6, 35, 65, 50, 72, 35, 52, 112, 47, 0, 0, 0, 0, 13, 4, 95, 48, 77, 49, 79, 6, 40, 50, 12, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 2, 95, 51, 67, 6, 111, 47, 12, 0, 0, 9, 2, 95, 50, 67, 6, 113, 52, 0, 0, 10, 2, 95, 49, 71, 6, 111, 50, 12, 0, 0, 9, 2, 95, 48, 47, 6, 40, 89, 0, 0, 14, 2, 95, 55, 79, 6, 40, 52, 116, 65, 67, 113, 52, 0, 0, 15, 2, 95, 54, 79, 6, 40, 52, 116, 65, 71, 111, 50, 12, 0, 0, 11, 2, 95, 53, 79, 6, 40, 52, 116, 65, 0, 0, 10, 2, 95, 52, 67, 6, 112, 50, 47, 0, 0, 0, 0, 15, 2, 95, 57, 79, 6, 40, 52, 116, 65, 67, 112, 50, 47, 0, 0, 15, 2, 95, 56, 79, 6, 40, 52, 116, 65, 67, 111, 47, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 195, 169, 0, 3, 36, 0, 4, 101, 3, 110, 0, 195, 169, 0, 7, 6, 195, 171, 0, 3, 13, 0, 4, 101, 3, 108, 0, 195, 171, 0, 7, 6, 195, 177, 0, 3, 67, 0, 7, 6, 195, 179, 0, 3, 39, 0, 4, 111, 3, 116, 0, 195, 179, 0, 7, 6, 197, 139, 0, 1, 25, 2, 25, 3, 43, 0, 3, 68, 0, 197, 139, 3, 68, 12, 0, 7, 6, 97, 0, 3, 35, 0, 97, 3, 113, 0, 7, 6, 98, 0, 3, 71, 0, 98, 3, 71, 12, 0, 7, 6, 99, 0, 3, 80, 0, 99, 3, 80, 12, 0, 7, 6, 100, 0, 3, 72, 0, 100, 3, 72, 12, 0, 7, 6, 101, 0, 3, 111, 0, 101, 3, 112, 0, 7, 6, 102, 0, 3, 83, 0, 7, 6, 103, 0, 3, 81, 0, 103, 3, 81, 12, 0, 7, 6, 104, 0, 3, 107, 0, 7, 6, 105, 0, 3, 37, 0, 105, 3, 109, 0, 7, 6, 106, 0, 3, 79, 0, 3, 79, 12, 0, 7, 6, 107, 0, 3, 49, 0, 107, 3, 49, 12, 0, 7, 6, 108, 0, 3, 55, 0, 7, 6, 109, 0, 1, 25, 2, 25, 3, 41, 0, 3, 65, 0, 109, 3, 65, 12, 0, 7, 6, 110, 0, 1, 25, 2, 25, 3, 42, 0, 3, 50, 0, 110, 3, 50, 12, 0, 7, 6, 111, 0, 3, 114, 0, 111, 3, 115, 0, 7, 6, 112, 0, 3, 48, 0, 112, 3, 48, 12, 0, 7, 6, 113, 0, 3, 104, 0, 113, 3, 104, 12, 0, 7, 6, 114, 0, 2, 114, 3, 51, 0, 3, 52, 0, 7, 6, 115, 0, 3, 89, 0, 115, 3, 89, 118, 0, 7, 6, 116, 0, 3, 47, 0, 116, 3, 47, 12, 0, 7, 6, 117, 0, 3, 40, 0, 117, 3, 117, 0, 7, 6, 118, 0, 3, 84, 0, 7, 6, 119, 0, 3, 58, 0, 7, 6, 120, 0, 3, 101, 0, 7, 6, 121, 0, 3, 57, 0, 7, 6, 122, 0, 3, 88, 0, 7, 6, 0, 36, 3, 72, 114, 55, 35, 52, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts69 = FileInMemory_createWithData (1734, reinterpret_cast (&espeakdata_dicts69_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/wo_dict", U"wo"); Collection_addItem (me.peek(), espeakdata_dicts69.transfer()); static unsigned char espeakdata_dicts70_data[41828] = { 0, 4, 0, 0, 94, 157, 0, 0, 10, 3, 229, 185, 178, 103, 97, 110, 49, 0, 12, 3, 232, 172, 138, 104, 117, 97, 110, 103, 51, 0, 10, 3, 233, 165, 146, 114, 97, 111, 50, 0, 10, 3, 232, 175, 162, 120, 117, 110, 50, 0, 11, 3, 233, 164, 138, 121, 97, 110, 103, 51, 0, 0, 10, 3, 230, 178, 185, 121, 111, 117, 50, 0, 10, 3, 232, 175, 161, 103, 117, 105, 51, 0, 9, 3, 230, 189, 145, 112, 111, 53, 0, 12, 3, 233, 166, 153, 120, 105, 97, 110, 103, 49, 0, 0, 10, 3, 231, 181, 144, 106, 105, 101, 50, 0, 9, 3, 233, 154, 184, 108, 105, 52, 0, 9, 3, 230, 176, 168, 97, 110, 49, 0, 11, 3, 229, 186, 184, 121, 111, 110, 103, 49, 0, 10, 3, 233, 153, 176, 121, 105, 110, 49, 0, 10, 3, 230, 177, 176, 116, 97, 105, 52, 0, 9, 3, 231, 183, 160, 100, 105, 52, 0, 10, 3, 230, 178, 184, 102, 101, 105, 52, 0, 12, 3, 232, 161, 176, 115, 104, 117, 97, 105, 49, 0, 0, 9, 3, 232, 179, 128, 104, 101, 52, 0, 11, 3, 231, 189, 144, 103, 117, 97, 110, 52, 0, 0, 9, 3, 232, 183, 161, 106, 105, 49, 0, 10, 3, 231, 178, 185, 99, 117, 105, 52, 0, 10, 3, 230, 184, 169, 119, 101, 110, 49, 0, 11, 3, 231, 189, 145, 119, 97, 110, 103, 51, 0, 10, 3, 232, 169, 177, 104, 117, 97, 52, 0, 0, 10, 3, 232, 169, 178, 103, 97, 105, 49, 0, 11, 3, 232, 168, 170, 102, 97, 110, 103, 51, 0, 10, 3, 232, 180, 138, 122, 97, 110, 52, 0, 7, 65, 4, 131, 115, 0, 29, 0, 11, 3, 231, 187, 131, 108, 105, 97, 110, 52, 0, 12, 3, 232, 169, 179, 120, 105, 97, 110, 103, 50, 0, 11, 3, 231, 176, 171, 120, 105, 97, 111, 49, 0, 9, 3, 231, 177, 179, 109, 105, 51, 0, 0, 9, 3, 233, 173, 148, 109, 111, 50, 0, 9, 3, 232, 170, 188, 121, 105, 52, 0, 10, 3, 232, 181, 148, 112, 101, 105, 50, 0, 9, 3, 231, 187, 132, 122, 117, 51, 0, 9, 3, 230, 184, 172, 99, 101, 52, 0, 0, 11, 3, 231, 187, 133, 115, 104, 101, 110, 49, 0, 10, 3, 232, 168, 173, 115, 104, 101, 52, 0, 9, 3, 233, 161, 181, 121, 101, 52, 0, 10, 3, 233, 160, 173, 116, 111, 117, 50, 0, 0, 11, 3, 233, 161, 182, 100, 105, 110, 103, 51, 0, 11, 3, 231, 178, 190, 106, 105, 110, 103, 49, 0, 9, 3, 231, 187, 134, 120, 105, 52, 0, 10, 3, 232, 181, 150, 108, 97, 105, 52, 0, 11, 3, 231, 188, 142, 100, 117, 97, 110, 52, 0, 8, 65, 8, 48, 37, 115, 0, 29, 0, 11, 3, 232, 182, 159, 116, 97, 110, 103, 52, 0, 9, 3, 232, 179, 135, 122, 105, 49, 0, 10, 3, 231, 187, 135, 122, 104, 105, 49, 0, 11, 3, 232, 170, 191, 100, 105, 97, 111, 52, 0, 11, 3, 230, 184, 175, 103, 97, 110, 103, 51, 0, 11, 3, 233, 161, 183, 113, 105, 110, 103, 51, 0, 0, 12, 3, 231, 187, 136, 122, 104, 111, 110, 103, 49, 0, 10, 3, 232, 183, 168, 107, 117, 97, 52, 0, 10, 3, 233, 160, 176, 106, 105, 97, 50, 0, 11, 3, 233, 175, 168, 106, 105, 110, 103, 49, 0, 0, 11, 3, 231, 190, 161, 120, 105, 97, 110, 52, 0, 9, 3, 232, 168, 177, 120, 117, 51, 0, 12, 3, 233, 161, 185, 120, 105, 97, 110, 103, 52, 0, 0, 12, 3, 232, 181, 154, 122, 104, 117, 97, 110, 52, 0, 11, 3, 233, 161, 186, 115, 104, 117, 110, 52, 0, 10, 3, 232, 179, 138, 122, 101, 105, 50, 0, 9, 3, 233, 173, 154, 121, 117, 50, 0, 9, 3, 233, 170, 130, 109, 97, 52, 0, 10, 3, 232, 183, 170, 103, 117, 105, 52, 0, 9, 3, 231, 189, 154, 102, 97, 50, 0, 8, 65, 12, 89, 131, 117, 0, 29, 0, 11, 3, 231, 188, 147, 104, 117, 97, 110, 51, 0, 9, 3, 233, 161, 187, 120, 117, 49, 0, 10, 3, 231, 177, 187, 108, 101, 105, 52, 0, 9, 3, 232, 182, 163, 113, 117, 52, 0, 10, 3, 232, 181, 155, 115, 97, 105, 52, 0, 0, 9, 3, 230, 184, 180, 107, 101, 51, 0, 10, 3, 231, 190, 164, 113, 117, 110, 50, 0, 9, 3, 231, 188, 148, 100, 105, 52, 0, 9, 3, 232, 168, 180, 115, 117, 53, 0, 11, 3, 233, 170, 132, 106, 105, 97, 111, 49, 0, 0, 10, 3, 233, 161, 189, 119, 97, 110, 50, 0, 9, 3, 231, 177, 189, 122, 105, 51, 0, 11, 3, 231, 187, 141, 115, 104, 97, 111, 52, 0, 9, 3, 231, 188, 149, 108, 118, 51, 0, 0, 10, 3, 232, 181, 158, 122, 97, 110, 52, 0, 11, 3, 231, 188, 150, 98, 105, 97, 110, 49, 0, 10, 3, 230, 185, 190, 119, 97, 110, 49, 0, 9, 3, 233, 161, 190, 103, 117, 52, 0, 10, 3, 233, 170, 134, 108, 117, 111, 52, 0, 8, 65, 16, 47, 37, 115, 0, 29, 0, 11, 3, 231, 187, 143, 106, 105, 110, 103, 49, 0, 9, 3, 232, 183, 175, 108, 117, 52, 0, 10, 3, 233, 161, 191, 100, 117, 110, 52, 0, 10, 3, 230, 185, 191, 115, 104, 105, 49, 0, 0, 9, 3, 232, 182, 168, 113, 117, 49, 0, 11, 3, 231, 188, 152, 121, 117, 97, 110, 50, 0, 11, 3, 233, 160, 184, 106, 105, 110, 103, 51, 0, 9, 3, 231, 176, 184, 98, 111, 51, 0, 10, 3, 230, 184, 184, 121, 111, 117, 50, 0, 11, 3, 231, 190, 168, 120, 105, 97, 110, 52, 0, 0, 9, 3, 231, 190, 169, 121, 105, 52, 0, 11, 3, 231, 187, 145, 98, 97, 110, 103, 51, 0, 10, 3, 232, 177, 129, 104, 117, 111, 49, 0, 10, 3, 231, 185, 129, 102, 97, 110, 50, 0, 0, 9, 3, 231, 188, 154, 102, 117, 52, 0, 9, 3, 231, 189, 162, 98, 97, 53, 0, 11, 3, 230, 184, 186, 109, 105, 97, 111, 51, 0, 11, 3, 232, 168, 186, 122, 104, 101, 110, 51, 0, 11, 3, 231, 187, 146, 114, 111, 110, 103, 50, 0, 8, 65, 20, 57, 37, 115, 0, 29, 0, 10, 3, 231, 187, 147, 106, 105, 101, 50, 0, 11, 3, 232, 183, 179, 116, 105, 97, 111, 52, 0, 11, 3, 231, 185, 131, 98, 101, 110, 103, 51, 0, 10, 3, 233, 160, 187, 112, 105, 110, 50, 0, 10, 3, 232, 179, 147, 98, 105, 110, 49, 0, 0, 10, 3, 233, 170, 140, 121, 97, 110, 52, 0, 9, 3, 231, 186, 140, 120, 117, 52, 0, 10, 3, 232, 178, 140, 109, 97, 111, 52, 0, 12, 3, 232, 168, 188, 122, 104, 101, 110, 103, 52, 0, 9, 3, 233, 171, 148, 116, 105, 51, 0, 10, 3, 232, 181, 164, 99, 104, 105, 52, 0, 0, 10, 3, 231, 187, 149, 114, 97, 111, 52, 0, 9, 3, 233, 169, 133, 113, 117, 49, 0, 11, 3, 231, 188, 157, 102, 101, 110, 103, 52, 0, 10, 3, 232, 180, 157, 98, 101, 105, 52, 0, 11, 3, 231, 176, 189, 113, 105, 97, 110, 49, 0, 11, 3, 232, 183, 181, 106, 105, 97, 110, 52, 0, 0, 11, 3, 233, 174, 174, 120, 105, 97, 110, 49, 0, 10, 3, 232, 177, 134, 100, 111, 117, 52, 0, 10, 3, 230, 184, 190, 104, 117, 110, 50, 0, 8, 65, 24, 127, 113, 83, 0, 29, 0, 11, 3, 231, 186, 143, 99, 104, 97, 110, 50, 0, 9, 3, 232, 180, 159, 102, 117, 52, 0, 0, 9, 3, 232, 177, 136, 113, 105, 51, 0, 10, 3, 233, 171, 152, 103, 97, 111, 49, 0, 10, 3, 231, 187, 152, 104, 117, 105, 52, 0, 11, 3, 231, 188, 160, 99, 104, 97, 110, 50, 0, 0, 11, 3, 232, 176, 129, 115, 104, 117, 105, 50, 0, 11, 3, 231, 189, 169, 122, 104, 97, 111, 52, 0, 11, 3, 231, 191, 185, 113, 105, 97, 111, 52, 0, 9, 3, 233, 170, 145, 113, 105, 50, 0, 11, 3, 232, 180, 161, 103, 111, 110, 103, 52, 0, 10, 3, 231, 187, 153, 103, 101, 105, 51, 0, 0, 11, 3, 231, 187, 154, 120, 117, 97, 110, 52, 0, 10, 3, 232, 180, 162, 99, 97, 105, 50, 0, 10, 3, 232, 183, 186, 100, 117, 111, 52, 0, 10, 3, 231, 189, 170, 122, 117, 105, 52, 0, 8, 65, 28, 124, 37, 115, 0, 29, 0, 11, 3, 232, 176, 131, 100, 105, 97, 111, 52, 0, 9, 3, 232, 180, 163, 122, 101, 50, 0, 9, 3, 232, 182, 179, 122, 117, 50, 0, 10, 3, 232, 178, 147, 109, 97, 111, 49, 0, 10, 3, 231, 191, 187, 102, 97, 110, 49, 0, 0, 10, 3, 231, 187, 156, 108, 117, 111, 52, 0, 9, 3, 232, 182, 180, 112, 97, 49, 0, 10, 3, 232, 177, 140, 119, 97, 110, 49, 0, 9, 3, 231, 191, 188, 121, 105, 52, 0, 0, 10, 3, 232, 180, 165, 98, 97, 105, 52, 0, 12, 3, 232, 176, 133, 108, 105, 97, 110, 103, 52, 0, 10, 3, 231, 187, 157, 106, 117, 101, 50, 0, 0, 12, 3, 232, 179, 158, 115, 104, 97, 110, 103, 51, 0, 11, 3, 231, 186, 150, 120, 105, 97, 110, 49, 0, 10, 3, 232, 177, 142, 115, 104, 117, 52, 0, 10, 3, 231, 189, 174, 122, 104, 105, 52, 0, 8, 65, 32, 131, 113, 125, 0, 29, 0, 11, 3, 233, 170, 151, 112, 105, 97, 110, 52, 0, 11, 3, 231, 187, 159, 116, 111, 110, 103, 51, 0, 10, 3, 232, 180, 167, 104, 117, 111, 52, 0, 10, 3, 233, 172, 167, 110, 97, 111, 52, 0, 0, 10, 3, 231, 182, 184, 108, 117, 110, 50, 0, 9, 3, 232, 173, 176, 121, 105, 52, 0, 11, 3, 231, 178, 152, 122, 104, 97, 110, 49, 0, 9, 3, 233, 160, 136, 120, 117, 49, 0, 9, 3, 233, 162, 152, 116, 105, 50, 0, 10, 3, 230, 189, 176, 107, 117, 105, 52, 0, 10, 3, 233, 165, 176, 115, 104, 105, 52, 0, 9, 3, 232, 168, 136, 106, 105, 52, 0, 10, 3, 232, 170, 152, 121, 111, 117, 52, 0, 11, 3, 233, 164, 168, 103, 117, 97, 110, 51, 0, 9, 3, 232, 174, 184, 120, 117, 51, 0, 0, 10, 3, 233, 165, 177, 98, 97, 111, 51, 0, 11, 3, 231, 181, 177, 116, 111, 110, 103, 51, 0, 10, 3, 230, 187, 161, 109, 97, 110, 51, 0, 11, 3, 231, 191, 129, 119, 101, 110, 103, 49, 0, 11, 3, 230, 188, 169, 120, 117, 97, 110, 50, 0, 0, 9, 3, 233, 163, 162, 106, 105, 49, 0, 9, 3, 233, 165, 178, 115, 105, 52, 0, 10, 3, 232, 168, 138, 120, 117, 110, 52, 0, 10, 3, 232, 174, 186, 108, 117, 110, 52, 0, 9, 3, 231, 181, 178, 115, 105, 49, 0, 7, 65, 36, 127, 115, 0, 29, 0, 10, 3, 230, 188, 171, 109, 97, 110, 52, 0, 10, 3, 232, 183, 131, 121, 117, 101, 52, 0, 9, 3, 231, 180, 171, 122, 105, 51, 0, 0, 11, 3, 232, 174, 188, 115, 111, 110, 103, 52, 0, 11, 3, 232, 173, 180, 113, 105, 97, 110, 51, 0, 11, 3, 233, 160, 140, 115, 111, 110, 103, 52, 0, 10, 3, 230, 186, 156, 108, 105, 117, 49, 0, 10, 3, 233, 162, 156, 121, 97, 110, 50, 0, 10, 3, 232, 172, 172, 109, 105, 117, 52, 0, 11, 3, 231, 178, 156, 116, 105, 97, 111, 52, 0, 0, 10, 3, 230, 187, 165, 108, 97, 110, 52, 0, 11, 3, 232, 169, 149, 112, 105, 110, 103, 50, 0, 10, 3, 231, 191, 133, 99, 104, 105, 52, 0, 8, 3, 233, 162, 157, 101, 50, 0, 10, 3, 230, 186, 157, 103, 111, 117, 49, 0, 11, 3, 232, 174, 189, 102, 101, 110, 103, 51, 0, 0, 10, 3, 232, 174, 190, 115, 104, 101, 52, 0, 9, 3, 232, 170, 158, 121, 117, 51, 0, 10, 3, 233, 165, 182, 114, 97, 111, 50, 0, 10, 3, 232, 168, 142, 116, 97, 111, 51, 0, 9, 3, 230, 185, 150, 104, 117, 50, 0, 8, 65, 40, 124, 131, 115, 0, 29, 0, 9, 3, 232, 173, 183, 104, 117, 52, 0, 12, 3, 231, 179, 167, 108, 105, 97, 110, 103, 50, 0, 11, 3, 231, 182, 191, 109, 105, 97, 110, 50, 0, 11, 3, 232, 174, 191, 102, 97, 110, 103, 51, 0, 10, 3, 231, 180, 175, 108, 101, 105, 52, 0, 0, 9, 3, 231, 180, 176, 120, 105, 52, 0, 12, 3, 232, 170, 160, 99, 104, 101, 110, 103, 50, 0, 11, 3, 230, 184, 144, 106, 105, 97, 110, 52, 0, 10, 3, 230, 187, 168, 98, 105, 110, 49, 0, 9, 3, 233, 160, 144, 121, 117, 52, 0, 11, 3, 233, 162, 160, 100, 105, 97, 110, 49, 0, 0, 11, 3, 232, 182, 129, 99, 104, 101, 110, 52, 0, 10, 3, 233, 160, 145, 119, 97, 110, 50, 0, 10, 3, 232, 170, 161, 106, 105, 101, 52, 0, 9, 3, 233, 175, 137, 108, 105, 51, 0, 11, 3, 231, 181, 185, 106, 117, 97, 110, 52, 0, 10, 3, 230, 187, 169, 116, 97, 110, 49, 0, 0, 11, 3, 233, 165, 186, 106, 105, 97, 111, 51, 0, 12, 3, 230, 188, 178, 122, 104, 97, 110, 103, 51, 0, 10, 3, 233, 160, 146, 98, 97, 110, 49, 0, 8, 65, 44, 120, 131, 115, 0, 29, 0, 10, 3, 233, 160, 147, 100, 117, 110, 52, 0, 9, 3, 232, 170, 163, 119, 117, 49, 0, 11, 3, 231, 180, 179, 115, 104, 101, 110, 49, 0, 10, 3, 232, 168, 147, 120, 117, 110, 52, 0, 11, 3, 233, 161, 155, 100, 105, 97, 110, 49, 0, 0, 9, 3, 230, 184, 148, 121, 117, 50, 0, 11, 3, 233, 162, 164, 99, 104, 97, 110, 52, 0, 11, 3, 233, 165, 188, 98, 105, 110, 103, 51, 0, 9, 3, 232, 170, 164, 119, 117, 52, 0, 10, 3, 232, 183, 140, 100, 105, 101, 49, 0, 0, 11, 3, 232, 182, 133, 99, 104, 97, 111, 49, 0, 9, 3, 232, 173, 189, 121, 117, 52, 0, 11, 3, 231, 178, 165, 122, 104, 111, 117, 49, 0, 0, 9, 3, 232, 169, 158, 99, 105, 50, 0, 10, 3, 233, 161, 158, 108, 101, 105, 52, 0, 11, 3, 232, 170, 166, 115, 111, 110, 103, 52, 0, 8, 65, 48, 127, 113, 55, 0, 29, 0, 8, 3, 233, 165, 191, 101, 52, 0, 11, 3, 230, 184, 151, 115, 104, 101, 110, 52, 0, 10, 3, 233, 163, 175, 102, 97, 110, 52, 0, 9, 3, 233, 160, 151, 112, 111, 49, 0, 0, 11, 3, 233, 160, 152, 108, 105, 110, 103, 51, 0, 11, 3, 230, 188, 184, 106, 105, 97, 110, 52, 0, 11, 3, 233, 162, 168, 102, 101, 110, 103, 49, 0, 11, 3, 231, 177, 160, 108, 111, 110, 103, 50, 0, 9, 3, 232, 168, 152, 106, 105, 52, 0, 0, 11, 3, 231, 180, 185, 115, 104, 97, 111, 52, 0, 10, 3, 232, 183, 145, 112, 97, 111, 51, 0, 10, 3, 232, 172, 185, 106, 105, 110, 51, 0, 0, 10, 3, 233, 173, 130, 104, 117, 110, 50, 0, 11, 3, 232, 170, 170, 115, 104, 117, 111, 49, 0, 9, 3, 231, 191, 146, 120, 105, 50, 0, 10, 3, 232, 169, 162, 120, 117, 110, 50, 0, 9, 3, 230, 186, 170, 120, 105, 49, 0, 10, 3, 233, 163, 178, 121, 105, 110, 51, 0, 10, 3, 232, 182, 138, 121, 117, 101, 52, 0, 11, 3, 231, 190, 138, 121, 97, 110, 103, 50, 0, 11, 3, 230, 187, 178, 115, 104, 101, 110, 52, 0, 10, 3, 231, 178, 170, 102, 101, 110, 52, 0, 8, 65, 52, 127, 113, 65, 0, 29, 0, 11, 3, 230, 184, 155, 106, 105, 97, 110, 51, 0, 9, 3, 232, 182, 139, 113, 117, 49, 0, 10, 3, 230, 186, 171, 119, 101, 110, 49, 0, 0, 9, 3, 233, 173, 132, 112, 111, 52, 0, 9, 3, 232, 181, 132, 122, 105, 49, 0, 9, 3, 230, 187, 180, 100, 105, 49, 0, 12, 3, 231, 191, 148, 120, 105, 97, 110, 103, 50, 0, 0, 9, 3, 232, 168, 157, 121, 97, 52, 0, 0, 10, 3, 231, 190, 142, 109, 101, 105, 51, 0, 11, 3, 230, 188, 190, 121, 97, 110, 103, 52, 0, 10, 3, 232, 169, 166, 115, 104, 105, 52, 0, 12, 3, 231, 178, 174, 108, 105, 97, 110, 103, 50, 0, 11, 3, 231, 179, 182, 116, 105, 97, 111, 52, 0, 8, 65, 56, 13, 50, 117, 0, 29, 0, 12, 3, 230, 188, 191, 106, 105, 97, 110, 103, 49, 0, 9, 3, 233, 161, 167, 103, 117, 52, 0, 11, 3, 232, 171, 183, 102, 101, 110, 103, 51, 0, 11, 3, 232, 168, 159, 115, 111, 110, 103, 52, 0, 0, 10, 3, 232, 171, 184, 122, 104, 117, 49, 0, 9, 3, 230, 184, 160, 113, 117, 50, 0, 11, 3, 231, 188, 128, 122, 104, 117, 105, 53, 0, 11, 3, 231, 191, 152, 113, 105, 97, 111, 52, 0, 11, 3, 232, 170, 176, 115, 104, 117, 105, 50, 0, 0, 10, 3, 232, 169, 169, 115, 104, 105, 49, 0, 11, 3, 231, 176, 161, 106, 105, 97, 110, 51, 0, 9, 3, 230, 184, 161, 100, 117, 52, 0, 0, 9, 3, 232, 170, 178, 107, 101, 52, 0, 7, 65, 60, 140, 117, 0, 29, 0, 9, 3, 232, 183, 155, 98, 111, 51, 0, 9, 3, 231, 179, 187, 120, 105, 52, 0, 11, 3, 233, 161, 171, 99, 104, 97, 110, 52, 0, 10, 3, 230, 184, 163, 122, 104, 97, 49, 0, 10, 3, 232, 169, 171, 99, 104, 97, 52, 0, 0, 9, 3, 232, 181, 140, 100, 117, 51, 0, 10, 3, 231, 190, 148, 103, 97, 111, 49, 0, 9, 3, 233, 163, 188, 115, 105, 52, 0, 9, 3, 231, 177, 172, 108, 105, 50, 0, 0, 9, 3, 232, 183, 157, 106, 117, 52, 0, 10, 3, 232, 182, 149, 103, 97, 110, 51, 0, 10, 3, 232, 169, 173, 103, 117, 105, 51, 0, 10, 3, 233, 163, 189, 98, 97, 111, 51, 0, 0, 10, 3, 233, 163, 190, 115, 104, 105, 52, 0, 9, 3, 230, 184, 166, 119, 111, 49, 0, 10, 3, 231, 179, 190, 106, 105, 117, 49, 0, 11, 3, 230, 186, 182, 114, 111, 110, 103, 50, 0, 10, 3, 230, 187, 190, 103, 117, 110, 51, 0, 10, 3, 231, 177, 174, 108, 117, 111, 50, 0, 8, 65, 64, 118, 37, 115, 0, 29, 0, 10, 3, 230, 187, 191, 109, 97, 110, 51, 0, 10, 3, 232, 183, 159, 103, 101, 110, 49, 0, 11, 3, 233, 161, 175, 120, 105, 97, 110, 51, 0, 11, 3, 230, 185, 175, 116, 97, 110, 103, 49, 0, 12, 3, 232, 181, 143, 115, 104, 97, 110, 103, 51, 0, 0, 10, 3, 232, 176, 168, 106, 105, 110, 51, 0, 10, 3, 231, 186, 184, 122, 104, 105, 51, 0, 10, 3, 233, 169, 176, 99, 104, 105, 50, 0, 9, 3, 232, 187, 128, 113, 117, 49, 0, 0, 11, 3, 233, 181, 145, 106, 117, 97, 110, 49, 0, 9, 3, 233, 180, 137, 121, 97, 49, 0, 9, 3, 233, 169, 177, 113, 117, 49, 0, 10, 3, 231, 186, 185, 119, 101, 110, 50, 0, 10, 3, 232, 188, 137, 122, 97, 105, 52, 0, 0, 11, 3, 231, 186, 186, 102, 97, 110, 103, 51, 0, 8, 65, 68, 120, 138, 117, 0, 29, 0, 10, 3, 232, 178, 187, 102, 101, 105, 52, 0, 11, 3, 231, 184, 171, 102, 101, 110, 103, 52, 0, 9, 3, 233, 169, 179, 98, 111, 50, 0, 11, 3, 231, 185, 179, 106, 105, 97, 111, 51, 0, 10, 3, 232, 190, 155, 120, 105, 110, 49, 0, 0, 10, 3, 232, 176, 172, 109, 105, 117, 52, 0, 8, 3, 233, 179, 132, 101, 52, 0, 9, 3, 233, 170, 188, 103, 101, 50, 0, 9, 3, 233, 169, 180, 108, 118, 50, 0, 9, 3, 232, 190, 156, 103, 117, 49, 0, 10, 3, 232, 178, 188, 116, 105, 101, 49, 0, 0, 10, 3, 231, 186, 189, 110, 105, 117, 51, 0, 0, 9, 3, 232, 190, 158, 99, 105, 50, 0, 10, 3, 231, 184, 174, 115, 117, 111, 49, 0, 10, 3, 233, 169, 182, 115, 104, 105, 51, 0, 7, 65, 72, 129, 113, 0, 29, 0, 10, 3, 232, 178, 191, 109, 97, 111, 52, 0, 9, 3, 232, 190, 159, 112, 105, 52, 0, 11, 3, 231, 186, 191, 120, 105, 97, 110, 52, 0, 0, 11, 3, 233, 168, 176, 116, 101, 110, 103, 50, 0, 0, 9, 3, 233, 169, 185, 106, 117, 49, 0, 10, 3, 232, 186, 129, 122, 97, 111, 52, 0, 10, 3, 232, 177, 185, 98, 97, 111, 52, 0, 11, 3, 231, 184, 177, 122, 111, 110, 103, 52, 0, 0, 10, 3, 232, 187, 138, 99, 104, 101, 49, 0, 11, 3, 232, 177, 186, 99, 104, 97, 105, 50, 0, 8, 65, 76, 127, 113, 89, 0, 29, 0, 9, 3, 232, 191, 171, 112, 111, 52, 0, 10, 3, 233, 169, 187, 122, 104, 117, 52, 0, 9, 3, 232, 190, 163, 108, 97, 52, 0, 9, 3, 232, 187, 139, 121, 97, 52, 0, 0, 10, 3, 233, 169, 188, 116, 117, 111, 53, 0, 9, 3, 232, 188, 148, 102, 117, 51, 0, 9, 3, 231, 185, 188, 106, 105, 52, 0, 10, 3, 232, 187, 140, 103, 117, 105, 51, 0, 11, 3, 232, 176, 180, 113, 105, 97, 110, 51, 0, 0, 11, 3, 232, 188, 149, 113, 105, 110, 103, 49, 0, 10, 3, 232, 187, 141, 106, 117, 110, 49, 0, 8, 3, 233, 181, 157, 101, 50, 0, 0, 10, 3, 233, 169, 190, 106, 105, 97, 52, 0, 10, 3, 232, 190, 166, 98, 97, 110, 52, 0, 8, 65, 80, 119, 37, 115, 0, 29, 0, 11, 3, 232, 189, 159, 104, 111, 110, 103, 49, 0, 9, 3, 231, 184, 183, 108, 118, 51, 0, 10, 3, 232, 186, 135, 99, 104, 117, 50, 0, 9, 3, 232, 176, 183, 103, 117, 51, 0, 0, 10, 3, 232, 191, 176, 115, 104, 117, 52, 0, 11, 3, 232, 190, 168, 98, 105, 97, 110, 52, 0, 0, 11, 3, 232, 190, 169, 98, 105, 97, 110, 52, 0, 0, 11, 3, 232, 186, 138, 99, 104, 111, 117, 50, 0, 8, 65, 84, 57, 138, 117, 0, 29, 0, 12, 3, 232, 188, 155, 108, 105, 97, 110, 103, 52, 0, 11, 3, 232, 190, 171, 98, 105, 97, 110, 52, 0, 0, 9, 3, 232, 185, 132, 116, 105, 50, 0, 0, 10, 3, 232, 188, 157, 104, 117, 105, 49, 0, 11, 3, 231, 184, 189, 122, 111, 110, 103, 51, 0, 10, 3, 232, 186, 141, 121, 117, 101, 52, 0, 9, 3, 232, 190, 173, 99, 105, 50, 0, 0, 11, 3, 232, 190, 174, 98, 105, 97, 110, 52, 0, 10, 3, 233, 168, 190, 108, 117, 111, 50, 0, 9, 3, 231, 184, 190, 106, 105, 49, 0, 10, 3, 232, 189, 166, 99, 104, 101, 49, 0, 8, 65, 88, 84, 131, 117, 0, 29, 0, 9, 3, 232, 191, 183, 109, 105, 50, 0, 11, 3, 232, 190, 175, 98, 105, 97, 110, 52, 0, 9, 3, 232, 189, 167, 121, 97, 52, 0, 0, 10, 3, 232, 185, 136, 100, 97, 111, 51, 0, 10, 3, 232, 189, 168, 103, 117, 105, 51, 0, 0, 11, 3, 233, 183, 185, 121, 105, 110, 103, 49, 0, 9, 3, 232, 191, 185, 106, 105, 49, 0, 9, 3, 232, 190, 177, 114, 117, 51, 0, 0, 9, 3, 233, 181, 170, 97, 110, 49, 0, 11, 3, 232, 190, 178, 110, 111, 110, 103, 50, 0, 11, 65, 92, 47, 35, 113, 48, 55, 138, 0, 29, 0, 9, 3, 232, 185, 139, 116, 97, 52, 0, 0, 12, 3, 232, 189, 172, 122, 104, 117, 97, 110, 51, 0, 0, 11, 3, 232, 191, 189, 122, 104, 117, 105, 49, 0, 0, 10, 3, 232, 189, 174, 108, 117, 110, 50, 0, 9, 65, 96, 127, 113, 49, 89, 0, 29, 0, 11, 3, 232, 187, 159, 114, 117, 97, 110, 51, 0, 11, 3, 232, 189, 175, 114, 117, 97, 110, 51, 0, 0, 10, 3, 232, 179, 160, 112, 101, 105, 50, 0, 10, 3, 232, 176, 136, 116, 97, 110, 50, 0, 9, 3, 231, 189, 176, 102, 97, 50, 0, 10, 3, 232, 181, 176, 122, 111, 117, 51, 0, 10, 3, 232, 180, 168, 122, 104, 105, 52, 0, 0, 10, 3, 232, 180, 169, 102, 97, 110, 52, 0, 10, 3, 231, 188, 169, 115, 117, 111, 49, 0, 11, 3, 232, 191, 129, 113, 105, 97, 110, 49, 0, 0, 9, 3, 232, 176, 138, 121, 105, 52, 0, 10, 3, 231, 189, 178, 115, 104, 117, 51, 0, 11, 3, 231, 187, 162, 106, 117, 97, 110, 52, 0, 10, 3, 232, 180, 170, 116, 97, 110, 49, 0, 8, 65, 100, 58, 144, 115, 0, 29, 0, 10, 3, 231, 187, 163, 120, 105, 117, 52, 0, 10, 3, 232, 176, 139, 109, 111, 117, 50, 0, 10, 3, 232, 180, 171, 112, 105, 110, 50, 0, 10, 3, 232, 179, 163, 109, 97, 105, 52, 0, 0, 10, 3, 231, 185, 148, 122, 104, 105, 49, 0, 11, 3, 232, 179, 164, 106, 105, 97, 110, 52, 0, 9, 3, 232, 181, 180, 102, 117, 52, 0, 0, 10, 3, 232, 191, 133, 120, 117, 110, 52, 0, 11, 3, 233, 169, 149, 106, 105, 97, 111, 49, 0, 10, 3, 232, 178, 157, 98, 101, 105, 52, 0, 10, 3, 232, 180, 173, 103, 111, 117, 52, 0, 9, 3, 231, 189, 181, 109, 97, 52, 0, 9, 3, 231, 190, 189, 121, 117, 51, 0, 0, 10, 3, 233, 171, 166, 109, 97, 111, 50, 0, 12, 3, 232, 176, 142, 104, 117, 97, 110, 103, 51, 0, 10, 3, 232, 181, 182, 103, 97, 110, 51, 0, 9, 3, 233, 168, 142, 113, 105, 50, 0, 8, 65, 104, 88, 37, 115, 0, 29, 0, 10, 3, 233, 169, 151, 121, 97, 110, 52, 0, 9, 3, 231, 189, 183, 98, 97, 53, 0, 10, 3, 232, 191, 135, 103, 117, 111, 52, 0, 9, 3, 232, 181, 183, 113, 105, 51, 0, 9, 3, 231, 187, 167, 106, 105, 52, 0, 11, 3, 232, 180, 175, 103, 117, 97, 110, 52, 0, 0, 10, 3, 231, 186, 160, 106, 105, 117, 49, 0, 12, 3, 231, 188, 176, 106, 105, 97, 110, 103, 49, 0, 9, 3, 232, 178, 160, 102, 117, 52, 0, 10, 3, 232, 191, 136, 109, 97, 105, 52, 0, 0, 10, 3, 233, 170, 161, 108, 117, 111, 50, 0, 10, 3, 232, 178, 161, 99, 97, 105, 50, 0, 11, 3, 232, 180, 177, 106, 105, 97, 110, 52, 0, 9, 3, 231, 187, 169, 106, 105, 49, 0, 0, 9, 3, 231, 187, 170, 120, 117, 52, 0, 11, 3, 232, 178, 162, 103, 111, 110, 103, 52, 0, 11, 3, 233, 169, 154, 106, 105, 110, 103, 49, 0, 11, 3, 231, 186, 162, 104, 111, 110, 103, 50, 0, 10, 3, 232, 179, 170, 122, 104, 105, 52, 0, 0, 10, 3, 232, 176, 147, 119, 101, 105, 52, 0, 11, 3, 232, 190, 131, 106, 105, 97, 111, 52, 0, 0, 11, 3, 231, 188, 180, 106, 105, 97, 111, 51, 0, 11, 3, 233, 170, 164, 122, 104, 111, 117, 52, 0, 10, 3, 232, 180, 180, 116, 105, 101, 49, 0, 11, 3, 231, 186, 164, 120, 105, 97, 110, 49, 0, 0, 10, 3, 232, 180, 181, 103, 117, 105, 52, 0, 9, 3, 231, 187, 173, 120, 117, 52, 0, 9, 3, 232, 179, 173, 100, 117, 51, 0, 9, 3, 232, 190, 133, 102, 117, 51, 0, 0, 11, 3, 232, 191, 142, 121, 105, 110, 103, 50, 0, 10, 3, 231, 185, 158, 114, 97, 111, 52, 0, 10, 3, 231, 186, 166, 121, 117, 101, 49, 0, 12, 3, 232, 190, 134, 108, 105, 97, 110, 103, 52, 0, 0, 9, 3, 231, 186, 167, 106, 105, 50, 0, 11, 3, 233, 169, 159, 122, 104, 111, 117, 52, 0, 10, 3, 232, 178, 167, 112, 105, 110, 50, 0, 0, 11, 3, 231, 188, 184, 103, 97, 110, 103, 49, 0, 10, 3, 232, 178, 168, 104, 117, 111, 52, 0, 10, 3, 232, 191, 144, 121, 117, 110, 52, 0, 10, 3, 232, 190, 136, 98, 101, 105, 52, 0, 9, 3, 233, 170, 168, 103, 117, 51, 0, 10, 3, 232, 180, 184, 109, 97, 111, 52, 0, 0, 10, 3, 232, 190, 137, 104, 117, 105, 49, 0, 11, 3, 233, 168, 153, 112, 105, 97, 110, 52, 0, 10, 3, 232, 178, 169, 102, 97, 110, 52, 0, 10, 3, 232, 180, 185, 102, 101, 105, 52, 0, 12, 3, 232, 177, 161, 120, 105, 97, 110, 103, 52, 0, 11, 3, 233, 182, 137, 99, 104, 117, 110, 53, 0, 10, 3, 231, 185, 161, 120, 105, 117, 52, 0, 10, 3, 232, 191, 145, 106, 105, 110, 52, 0, 0, 9, 3, 232, 180, 186, 104, 101, 52, 0, 9, 3, 233, 169, 162, 108, 118, 50, 0, 9, 3, 231, 186, 170, 106, 105, 52, 0, 10, 3, 232, 178, 170, 116, 97, 110, 49, 0, 10, 3, 231, 188, 186, 113, 117, 101, 49, 0, 0, 9, 3, 231, 184, 155, 102, 117, 52, 0, 11, 3, 232, 178, 171, 103, 117, 97, 110, 52, 0, 12, 3, 231, 187, 179, 115, 104, 101, 110, 103, 50, 0, 0, 10, 3, 231, 186, 172, 119, 101, 105, 51, 0, 10, 3, 232, 180, 188, 122, 101, 105, 50, 0, 10, 3, 232, 179, 180, 108, 97, 105, 52, 0, 10, 3, 233, 172, 188, 103, 117, 105, 51, 0, 10, 3, 232, 191, 148, 102, 97, 110, 51, 0, 10, 3, 231, 187, 180, 119, 101, 105, 50, 0, 9, 3, 232, 178, 172, 122, 101, 50, 0, 0, 11, 3, 231, 187, 181, 109, 105, 97, 110, 50, 0, 0, 0, 11, 3, 231, 186, 175, 99, 104, 117, 110, 50, 0, 9, 3, 233, 183, 151, 111, 117, 49, 0, 11, 3, 231, 187, 183, 98, 101, 110, 103, 51, 0, 0, 9, 3, 232, 190, 144, 102, 117, 50, 0, 11, 3, 231, 187, 184, 99, 104, 111, 117, 50, 0, 10, 3, 232, 191, 152, 104, 97, 105, 50, 0, 0, 12, 3, 231, 185, 169, 115, 104, 101, 110, 103, 50, 0, 12, 3, 232, 189, 137, 122, 104, 117, 97, 110, 51, 0, 10, 3, 232, 191, 153, 122, 104, 101, 52, 0, 10, 3, 231, 186, 177, 115, 104, 97, 49, 0, 9, 3, 232, 190, 145, 106, 105, 53, 0, 0, 10, 3, 232, 177, 170, 104, 97, 111, 50, 0, 10, 3, 232, 176, 162, 120, 105, 101, 52, 0, 10, 3, 231, 185, 170, 104, 117, 105, 52, 0, 12, 3, 232, 179, 186, 122, 104, 117, 97, 110, 52, 0, 11, 3, 231, 186, 178, 103, 97, 110, 103, 49, 0, 0, 9, 3, 232, 177, 171, 121, 117, 52, 0, 11, 3, 232, 188, 131, 106, 105, 97, 111, 52, 0, 10, 3, 232, 176, 163, 121, 97, 111, 50, 0, 9, 3, 231, 186, 179, 110, 97, 52, 0, 11, 3, 231, 184, 163, 120, 105, 97, 110, 52, 0, 10, 3, 232, 191, 155, 106, 105, 110, 52, 0, 10, 3, 232, 190, 147, 115, 104, 117, 49, 0, 0, 11, 3, 232, 191, 156, 121, 117, 97, 110, 51, 0, 9, 3, 233, 169, 172, 109, 97, 51, 0, 11, 3, 231, 187, 188, 122, 111, 110, 103, 49, 0, 10, 3, 232, 178, 180, 103, 117, 105, 52, 0, 10, 3, 232, 177, 172, 122, 104, 117, 49, 0, 10, 3, 232, 179, 188, 103, 111, 117, 52, 0, 0, 11, 3, 231, 186, 181, 122, 111, 110, 103, 52, 0, 10, 3, 232, 191, 157, 119, 101, 105, 50, 0, 10, 3, 232, 179, 189, 115, 97, 105, 52, 0, 11, 3, 231, 185, 173, 106, 105, 97, 110, 51, 0, 0, 10, 3, 233, 169, 174, 116, 117, 111, 50, 0, 11, 3, 232, 191, 158, 108, 105, 97, 110, 50, 0, 10, 3, 231, 186, 182, 108, 117, 110, 50, 0, 11, 3, 232, 176, 166, 113, 105, 97, 110, 49, 0, 11, 3, 232, 189, 142, 106, 105, 97, 111, 52, 0, 0, 10, 3, 231, 186, 183, 102, 101, 110, 49, 0, 9, 3, 231, 187, 191, 108, 118, 52, 0, 10, 3, 232, 178, 183, 109, 97, 105, 51, 0, 10, 3, 232, 191, 159, 99, 104, 105, 50, 0, 0, 11, 3, 233, 178, 184, 106, 105, 110, 103, 49, 0, 0, 10, 3, 232, 184, 169, 99, 97, 105, 51, 0, 0, 11, 3, 232, 186, 186, 116, 97, 110, 103, 51, 0, 10, 3, 232, 185, 178, 100, 117, 110, 49, 0, 11, 3, 232, 184, 170, 122, 111, 110, 103, 49, 0, 0, 0, 0, 0, 11, 3, 232, 184, 174, 100, 105, 97, 110, 51, 0, 0, 8, 3, 233, 177, 183, 101, 52, 0, 0, 0, 10, 3, 232, 184, 177, 100, 117, 111, 50, 0, 0, 0, 0, 9, 3, 233, 177, 188, 121, 117, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 232, 189, 176, 104, 111, 110, 103, 49, 0, 9, 3, 233, 180, 168, 121, 97, 49, 0, 0, 11, 3, 232, 190, 185, 98, 105, 97, 110, 49, 0, 10, 3, 232, 188, 169, 98, 101, 105, 52, 0, 0, 10, 3, 232, 188, 170, 108, 117, 110, 50, 0, 10, 3, 233, 181, 178, 113, 117, 101, 53, 0, 0, 0, 11, 3, 232, 189, 180, 122, 104, 111, 117, 50, 0, 11, 3, 233, 178, 156, 120, 105, 97, 110, 49, 0, 11, 3, 232, 184, 140, 99, 104, 111, 117, 50, 0, 0, 11, 3, 232, 190, 189, 108, 105, 97, 111, 50, 0, 11, 3, 233, 179, 165, 110, 105, 97, 111, 51, 0, 0, 9, 3, 232, 190, 190, 100, 97, 50, 0, 0, 9, 3, 233, 179, 167, 102, 117, 50, 0, 9, 3, 232, 184, 143, 116, 97, 52, 0, 9, 3, 232, 188, 175, 106, 105, 53, 0, 0, 11, 3, 232, 184, 144, 106, 105, 97, 110, 52, 0, 0, 0, 0, 11, 3, 232, 189, 187, 113, 105, 110, 103, 49, 0, 0, 9, 3, 233, 178, 164, 108, 105, 51, 0, 0, 10, 3, 232, 189, 189, 122, 97, 105, 52, 0, 0, 0, 11, 3, 232, 189, 191, 106, 105, 97, 111, 52, 0, 0, 10, 3, 232, 188, 184, 115, 104, 117, 49, 0, 0, 0, 0, 9, 3, 232, 188, 187, 102, 117, 50, 0, 11, 3, 232, 186, 171, 115, 104, 101, 110, 49, 0, 11, 3, 233, 179, 179, 102, 101, 110, 103, 52, 0, 0, 11, 3, 233, 179, 180, 109, 105, 110, 103, 50, 0, 11, 3, 232, 186, 172, 103, 111, 110, 103, 49, 0, 11, 3, 232, 185, 164, 122, 111, 110, 103, 49, 0, 0, 0, 11, 3, 232, 185, 166, 98, 101, 110, 103, 52, 0, 0, 9, 3, 232, 188, 191, 121, 117, 50, 0, 9, 3, 232, 186, 175, 113, 117, 49, 0, 9, 3, 233, 180, 191, 103, 101, 49, 0, 0, 11, 3, 232, 187, 184, 122, 104, 111, 117, 50, 0, 0, 0, 9, 3, 232, 184, 162, 116, 105, 49, 0, 10, 3, 232, 186, 178, 100, 117, 111, 51, 0, 0, 0, 11, 3, 232, 185, 172, 100, 101, 110, 103, 49, 0, 0, 11, 3, 232, 185, 173, 99, 101, 110, 103, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 3, 233, 185, 130, 108, 105, 50, 0, 0, 11, 3, 233, 185, 131, 106, 117, 97, 110, 49, 0, 0, 0, 8, 3, 233, 185, 133, 101, 50, 0, 0, 0, 0, 0, 0, 10, 3, 233, 185, 138, 113, 117, 101, 53, 0, 0, 0, 9, 3, 233, 185, 140, 97, 110, 49, 0, 0, 0, 0, 0, 0, 11, 3, 233, 185, 145, 99, 104, 117, 110, 53, 0, 0, 0, 12, 3, 233, 187, 131, 104, 117, 97, 110, 103, 50, 0, 0, 12, 3, 233, 187, 132, 104, 117, 97, 110, 103, 50, 0, 0, 9, 3, 233, 184, 157, 108, 105, 50, 0, 0, 0, 11, 3, 233, 184, 159, 110, 105, 97, 111, 51, 0, 0, 0, 9, 3, 233, 184, 161, 106, 105, 49, 0, 0, 0, 11, 3, 233, 184, 163, 109, 105, 110, 103, 50, 0, 0, 0, 9, 3, 233, 184, 165, 111, 117, 49, 0, 0, 9, 3, 233, 187, 142, 108, 105, 50, 0, 9, 3, 233, 184, 166, 121, 97, 49, 0, 0, 11, 3, 233, 187, 143, 110, 105, 97, 110, 50, 0, 9, 3, 233, 186, 151, 108, 105, 52, 0, 0, 0, 10, 3, 233, 187, 145, 104, 101, 105, 49, 0, 0, 0, 0, 0, 9, 3, 233, 184, 173, 121, 97, 49, 0, 0, 0, 0, 9, 3, 233, 187, 152, 109, 111, 52, 0, 0, 0, 9, 3, 233, 189, 138, 113, 105, 50, 0, 0, 9, 3, 233, 188, 147, 103, 117, 51, 0, 0, 11, 3, 233, 190, 132, 108, 105, 110, 103, 50, 0, 0, 10, 3, 233, 186, 165, 109, 97, 105, 52, 0, 0, 11, 3, 233, 187, 158, 100, 105, 97, 110, 51, 0, 10, 3, 233, 186, 166, 109, 97, 105, 52, 0, 0, 0, 11, 3, 233, 185, 176, 121, 105, 110, 103, 49, 0, 9, 3, 233, 189, 144, 113, 105, 50, 0, 0, 0, 10, 3, 233, 189, 146, 99, 104, 105, 51, 0, 0, 0, 0, 11, 3, 233, 190, 141, 108, 111, 110, 103, 50, 0, 9, 3, 233, 184, 189, 103, 101, 49, 0, 0, 0, 0, 0, 11, 3, 233, 190, 144, 112, 97, 110, 103, 50, 0, 11, 3, 233, 187, 168, 100, 97, 110, 103, 51, 0, 10, 3, 233, 188, 160, 115, 104, 117, 51, 0, 0, 0, 0, 10, 3, 233, 185, 189, 121, 97, 110, 50, 0, 0, 11, 3, 233, 185, 188, 106, 105, 97, 110, 51, 0, 0, 9, 3, 233, 187, 175, 97, 110, 52, 0, 9, 3, 233, 185, 191, 108, 117, 52, 0, 0, 0, 11, 3, 233, 190, 153, 108, 111, 110, 103, 50, 0, 11, 3, 233, 189, 161, 108, 105, 110, 103, 50, 0, 0, 0, 9, 3, 233, 186, 187, 109, 97, 50, 0, 0, 0, 0, 9, 3, 233, 186, 188, 109, 101, 53, 0, 10, 3, 233, 190, 156, 103, 117, 105, 49, 0, 10, 3, 233, 187, 180, 109, 101, 105, 50, 0, 0, 10, 3, 233, 190, 159, 103, 117, 105, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 3, 233, 188, 187, 98, 105, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 233, 189, 191, 99, 104, 105, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 227, 132, 133, 48, 39, 117, 0, 29, 0, 0, 10, 3, 227, 132, 135, 65, 39, 117, 0, 29, 0, 10, 3, 227, 132, 134, 118, 39, 117, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 227, 132, 165, 13, 68, 117, 0, 29, 0, 10, 3, 227, 132, 164, 126, 68, 117, 0, 29, 0, 10, 3, 227, 132, 167, 57, 37, 117, 0, 29, 0, 9, 3, 227, 132, 166, 129, 117, 0, 29, 0, 9, 3, 227, 132, 161, 140, 117, 0, 29, 0, 9, 3, 227, 132, 160, 128, 117, 0, 29, 0, 10, 3, 227, 132, 163, 13, 50, 117, 0, 29, 0, 10, 3, 227, 132, 162, 35, 50, 117, 0, 29, 0, 9, 3, 227, 132, 157, 130, 117, 0, 29, 0, 9, 3, 227, 132, 156, 139, 117, 0, 29, 0, 9, 3, 227, 132, 159, 131, 117, 0, 29, 0, 9, 3, 227, 132, 158, 127, 117, 0, 29, 0, 10, 3, 227, 132, 153, 89, 132, 117, 0, 29, 0, 10, 3, 227, 132, 152, 123, 132, 117, 0, 29, 0, 9, 3, 227, 132, 155, 39, 117, 0, 29, 0, 9, 3, 227, 132, 154, 126, 117, 0, 29, 0, 10, 3, 227, 132, 149, 93, 133, 117, 0, 29, 0, 10, 3, 227, 132, 148, 125, 133, 117, 0, 29, 0, 10, 3, 227, 132, 151, 122, 132, 117, 0, 29, 0, 10, 3, 227, 132, 150, 92, 133, 117, 0, 29, 0, 10, 3, 227, 132, 145, 121, 37, 117, 0, 29, 0, 10, 3, 227, 132, 144, 78, 37, 117, 0, 29, 0, 10, 3, 227, 132, 147, 124, 133, 117, 0, 29, 0, 10, 3, 227, 132, 146, 97, 37, 117, 0, 29, 0, 10, 3, 227, 132, 141, 49, 139, 117, 0, 29, 0, 10, 3, 227, 132, 140, 55, 13, 117, 0, 29, 0, 10, 3, 227, 132, 143, 101, 139, 117, 0, 29, 0, 10, 3, 227, 132, 142, 120, 139, 117, 0, 29, 0, 10, 3, 227, 132, 137, 47, 13, 117, 0, 29, 0, 10, 3, 227, 132, 136, 83, 39, 117, 0, 29, 0, 10, 3, 227, 132, 139, 50, 13, 117, 0, 29, 0, 10, 3, 227, 132, 138, 119, 13, 117, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 3, 227, 132, 169, 148, 117, 0, 29, 0, 10, 3, 227, 132, 168, 58, 40, 117, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 3, 229, 135, 157, 110, 105, 110, 103, 50, 0, 11, 3, 229, 133, 141, 109, 105, 97, 110, 51, 0, 0, 9, 3, 229, 132, 132, 121, 105, 52, 0, 0, 0, 0, 12, 3, 229, 133, 137, 103, 117, 97, 110, 103, 49, 0, 0, 9, 3, 229, 132, 128, 121, 105, 50, 0, 11, 3, 229, 133, 136, 120, 105, 97, 110, 49, 0, 0, 9, 3, 229, 133, 139, 107, 101, 52, 0, 10, 3, 95, 63, 63, 13, 12, 108, 0, 29, 0, 10, 3, 229, 134, 146, 109, 97, 111, 52, 0, 0, 12, 3, 229, 133, 133, 99, 104, 111, 110, 103, 49, 0, 10, 3, 229, 134, 141, 122, 97, 105, 52, 0, 0, 9, 3, 229, 134, 140, 99, 101, 52, 0, 12, 3, 229, 133, 132, 120, 105, 111, 110, 103, 49, 0, 0, 0, 0, 10, 3, 229, 135, 145, 99, 111, 117, 52, 0, 10, 3, 229, 133, 129, 121, 117, 110, 51, 0, 0, 11, 3, 229, 134, 136, 103, 97, 110, 103, 49, 0, 0, 11, 3, 229, 133, 131, 121, 117, 97, 110, 50, 0, 0, 9, 3, 229, 134, 138, 99, 101, 52, 0, 0, 10, 3, 229, 134, 133, 110, 101, 105, 52, 0, 11, 3, 229, 135, 141, 100, 111, 110, 103, 52, 0, 0, 0, 11, 3, 229, 135, 143, 106, 105, 97, 110, 51, 0, 0, 0, 12, 3, 229, 135, 137, 108, 105, 97, 110, 103, 50, 0, 0, 0, 0, 0, 0, 9, 3, 229, 135, 132, 113, 105, 49, 0, 0, 0, 11, 3, 229, 135, 134, 122, 104, 117, 110, 51, 0, 0, 0, 11, 3, 229, 135, 128, 106, 105, 110, 103, 52, 0, 0, 0, 0, 10, 3, 229, 133, 173, 108, 105, 117, 52, 0, 12, 3, 229, 134, 181, 107, 117, 97, 110, 103, 52, 0, 0, 11, 3, 229, 133, 172, 103, 111, 110, 103, 49, 0, 0, 10, 3, 229, 135, 191, 122, 97, 111, 50, 0, 11, 3, 229, 129, 143, 112, 105, 97, 110, 49, 0, 11, 3, 229, 134, 183, 108, 101, 110, 103, 51, 0, 0, 9, 3, 229, 134, 182, 121, 101, 51, 0, 10, 3, 229, 128, 134, 108, 105, 97, 51, 0, 10, 3, 229, 129, 142, 119, 101, 105, 49, 0, 0, 9, 3, 229, 135, 185, 97, 111, 49, 0, 10, 3, 229, 129, 137, 119, 101, 105, 51, 0, 12, 3, 229, 133, 169, 108, 105, 97, 110, 103, 51, 0, 0, 9, 3, 229, 135, 184, 116, 117, 49, 0, 11, 3, 229, 133, 168, 113, 117, 97, 110, 50, 0, 11, 3, 229, 134, 176, 98, 105, 110, 103, 49, 0, 0, 10, 3, 229, 134, 179, 106, 117, 101, 50, 0, 9, 3, 229, 135, 187, 106, 105, 49, 0, 9, 3, 229, 133, 171, 98, 97, 49, 0, 0, 11, 3, 229, 131, 154, 108, 105, 97, 111, 50, 0, 12, 3, 229, 134, 178, 99, 104, 111, 110, 103, 49, 0, 10, 3, 229, 135, 186, 99, 104, 117, 49, 0, 0, 9, 3, 229, 133, 165, 114, 117, 52, 0, 11, 3, 229, 130, 141, 98, 97, 110, 103, 52, 0, 0, 11, 3, 229, 134, 172, 100, 111, 110, 103, 49, 0, 0, 10, 3, 229, 133, 167, 110, 101, 105, 52, 0, 12, 3, 229, 132, 159, 99, 104, 97, 110, 103, 50, 0, 10, 3, 229, 129, 135, 106, 105, 97, 51, 0, 0, 12, 3, 229, 135, 182, 120, 105, 111, 110, 103, 49, 0, 0, 0, 12, 3, 229, 135, 176, 104, 117, 97, 110, 103, 50, 0, 0, 11, 3, 229, 135, 179, 100, 101, 110, 103, 52, 0, 0, 0, 11, 3, 229, 135, 173, 112, 105, 110, 103, 50, 0, 9, 3, 229, 130, 133, 102, 117, 53, 0, 0, 10, 3, 229, 133, 156, 100, 111, 117, 49, 0, 11, 3, 229, 134, 164, 121, 117, 97, 110, 49, 0, 0, 12, 3, 229, 131, 143, 120, 105, 97, 110, 103, 52, 0, 0, 0, 0, 0, 9, 3, 229, 135, 171, 102, 117, 50, 0, 0, 11, 3, 229, 133, 154, 100, 97, 110, 103, 51, 0, 0, 10, 3, 229, 131, 133, 106, 105, 110, 51, 0, 0, 11, 3, 229, 134, 156, 110, 111, 110, 103, 50, 0, 11, 3, 229, 135, 164, 102, 101, 110, 103, 52, 0, 9, 3, 229, 133, 148, 116, 117, 52, 0, 0, 0, 0, 11, 3, 229, 132, 137, 106, 105, 97, 110, 51, 0, 10, 3, 229, 135, 161, 102, 97, 110, 50, 0, 10, 3, 229, 134, 153, 120, 105, 101, 51, 0, 0, 9, 3, 229, 135, 160, 106, 105, 51, 0, 0, 10, 3, 229, 134, 155, 106, 117, 110, 49, 0, 0, 8, 3, 229, 133, 146, 114, 53, 0, 0, 11, 3, 230, 133, 142, 115, 104, 101, 110, 52, 0, 11, 3, 229, 140, 134, 99, 111, 110, 103, 49, 0, 10, 3, 229, 141, 142, 104, 117, 97, 50, 0, 11, 3, 229, 128, 166, 106, 117, 97, 110, 52, 0, 0, 10, 3, 229, 141, 143, 120, 105, 101, 50, 0, 12, 3, 229, 130, 183, 115, 104, 97, 110, 103, 49, 0, 0, 12, 3, 230, 133, 140, 104, 117, 97, 110, 103, 49, 0, 0, 11, 3, 229, 130, 181, 122, 104, 97, 105, 52, 0, 9, 3, 229, 142, 149, 99, 101, 52, 0, 10, 3, 229, 140, 133, 98, 97, 111, 49, 0, 0, 9, 3, 229, 130, 178, 97, 111, 52, 0, 10, 3, 229, 141, 138, 98, 97, 110, 52, 0, 0, 10, 3, 229, 143, 155, 112, 97, 110, 52, 0, 12, 3, 229, 130, 179, 99, 104, 117, 97, 110, 50, 0, 10, 3, 230, 133, 139, 116, 97, 105, 52, 0, 0, 9, 3, 229, 141, 136, 119, 117, 51, 0, 10, 3, 229, 140, 128, 121, 117, 110, 50, 0, 11, 3, 229, 143, 152, 98, 105, 97, 110, 52, 0, 9, 3, 230, 133, 136, 99, 105, 50, 0, 11, 3, 230, 134, 144, 108, 105, 97, 110, 50, 0, 0, 10, 3, 229, 131, 185, 106, 105, 97, 52, 0, 9, 3, 229, 143, 153, 120, 117, 52, 0, 11, 3, 230, 134, 145, 112, 105, 110, 103, 50, 0, 12, 3, 229, 128, 161, 99, 104, 97, 110, 103, 52, 0, 11, 3, 230, 132, 129, 99, 104, 111, 117, 50, 0, 0, 9, 3, 229, 143, 150, 113, 117, 51, 0, 0, 11, 3, 229, 143, 151, 115, 104, 111, 117, 52, 0, 10, 3, 229, 128, 159, 106, 105, 101, 52, 0, 9, 3, 229, 132, 191, 101, 114, 50, 0, 12, 3, 229, 141, 135, 115, 104, 101, 110, 103, 49, 0, 0, 10, 3, 229, 130, 172, 99, 117, 105, 49, 0, 10, 3, 229, 142, 140, 121, 97, 110, 52, 0, 10, 3, 229, 143, 148, 115, 104, 117, 49, 0, 0, 12, 3, 229, 131, 181, 106, 105, 97, 110, 103, 49, 0, 11, 3, 229, 129, 165, 106, 105, 97, 110, 52, 0, 0, 9, 3, 229, 128, 154, 121, 105, 51, 0, 10, 3, 230, 135, 146, 108, 97, 110, 51, 0, 0, 9, 3, 229, 142, 139, 121, 97, 49, 0, 10, 3, 230, 134, 139, 98, 105, 101, 49, 0, 11, 3, 229, 141, 131, 113, 105, 97, 110, 49, 0, 0, 10, 3, 229, 130, 168, 99, 104, 117, 51, 0, 11, 3, 229, 128, 152, 116, 97, 110, 103, 51, 0, 9, 3, 229, 141, 128, 113, 117, 49, 0, 0, 9, 3, 229, 142, 137, 108, 105, 52, 0, 9, 3, 229, 131, 177, 103, 117, 52, 0, 9, 3, 229, 143, 145, 102, 97, 49, 0, 10, 3, 229, 141, 129, 115, 104, 105, 50, 0, 10, 3, 229, 128, 153, 104, 111, 117, 52, 0, 0, 9, 3, 229, 142, 134, 108, 105, 52, 0, 0, 0, 11, 3, 229, 133, 188, 106, 105, 97, 110, 49, 0, 13, 3, 229, 143, 140, 115, 104, 117, 97, 110, 103, 49, 0, 11, 3, 229, 129, 156, 116, 105, 110, 103, 50, 0, 0, 11, 3, 229, 142, 133, 116, 105, 110, 103, 49, 0, 11, 3, 229, 133, 189, 115, 104, 111, 117, 52, 0, 10, 3, 229, 143, 141, 102, 97, 110, 51, 0, 0, 12, 3, 229, 142, 130, 99, 104, 97, 110, 103, 51, 0, 10, 3, 229, 129, 154, 122, 117, 111, 52, 0, 10, 3, 230, 134, 130, 121, 111, 117, 49, 0, 9, 3, 229, 143, 138, 106, 105, 50, 0, 10, 3, 229, 132, 178, 99, 104, 117, 51, 0, 10, 3, 229, 128, 146, 100, 97, 111, 52, 0, 0, 11, 3, 229, 133, 187, 121, 97, 110, 103, 51, 0, 10, 3, 229, 143, 139, 121, 111, 117, 53, 0, 0, 11, 3, 229, 133, 184, 100, 105, 97, 110, 51, 0, 10, 3, 229, 143, 136, 121, 111, 117, 52, 0, 0, 10, 3, 229, 128, 145, 109, 101, 110, 53, 0, 11, 3, 230, 135, 137, 121, 105, 110, 103, 49, 0, 0, 9, 3, 229, 133, 182, 113, 105, 50, 0, 0, 10, 3, 230, 135, 135, 107, 101, 110, 51, 0, 9, 3, 229, 133, 183, 106, 117, 52, 0, 0, 11, 3, 229, 133, 180, 120, 105, 110, 103, 52, 0, 0, 11, 3, 229, 133, 181, 98, 105, 110, 103, 49, 0, 10, 3, 229, 128, 141, 98, 101, 105, 52, 0, 0, 10, 3, 229, 143, 130, 99, 97, 110, 49, 0, 10, 3, 229, 132, 170, 121, 111, 117, 49, 0, 11, 3, 230, 135, 130, 100, 111, 110, 103, 51, 0, 0, 11, 3, 229, 133, 179, 103, 117, 97, 110, 49, 0, 10, 3, 229, 143, 131, 99, 97, 110, 49, 0, 11, 3, 229, 134, 187, 100, 111, 110, 103, 52, 0, 9, 3, 229, 128, 139, 103, 101, 53, 0, 0, 10, 3, 229, 130, 152, 115, 97, 110, 51, 0, 0, 10, 3, 229, 130, 153, 98, 101, 105, 52, 0, 11, 3, 229, 133, 177, 103, 111, 110, 103, 52, 0, 11, 3, 229, 128, 137, 99, 97, 110, 103, 49, 0, 0, 10, 3, 229, 136, 134, 102, 101, 110, 49, 0, 9, 3, 230, 133, 174, 108, 118, 52, 0, 10, 3, 229, 137, 142, 115, 104, 97, 49, 0, 9, 3, 230, 134, 182, 121, 105, 52, 0, 10, 3, 229, 139, 158, 108, 97, 111, 50, 0, 0, 10, 3, 230, 132, 167, 107, 117, 105, 52, 0, 10, 3, 229, 136, 135, 113, 105, 101, 52, 0, 10, 3, 230, 131, 159, 119, 101, 105, 50, 0, 0, 10, 3, 230, 130, 148, 104, 117, 105, 51, 0, 11, 3, 229, 143, 188, 100, 105, 97, 111, 49, 0, 9, 3, 230, 131, 156, 120, 105, 49, 0, 10, 3, 230, 132, 164, 102, 101, 110, 52, 0, 9, 3, 230, 135, 188, 106, 117, 52, 0, 0, 12, 3, 230, 129, 141, 104, 117, 97, 110, 103, 51, 0, 12, 3, 229, 139, 157, 115, 104, 101, 110, 103, 52, 0, 11, 3, 229, 137, 141, 113, 105, 97, 110, 50, 0, 0, 9, 3, 229, 142, 178, 108, 105, 52, 0, 10, 3, 229, 137, 138, 120, 117, 101, 49, 0, 9, 3, 230, 131, 154, 104, 117, 49, 0, 11, 3, 230, 134, 178, 120, 105, 97, 110, 52, 0, 0, 10, 3, 229, 141, 171, 119, 101, 105, 52, 0, 11, 3, 230, 132, 163, 108, 101, 110, 103, 52, 0, 11, 3, 230, 129, 139, 108, 105, 97, 110, 52, 0, 0, 11, 3, 230, 135, 184, 120, 117, 97, 110, 50, 0, 10, 3, 230, 133, 168, 107, 97, 105, 51, 0, 10, 3, 229, 136, 128, 100, 97, 111, 49, 0, 10, 3, 229, 139, 152, 107, 97, 110, 49, 0, 12, 3, 229, 140, 160, 106, 105, 97, 110, 103, 53, 0, 9, 3, 229, 143, 184, 115, 105, 49, 0, 11, 3, 230, 128, 128, 104, 117, 97, 105, 50, 0, 0, 10, 3, 230, 128, 129, 116, 97, 105, 52, 0, 9, 3, 229, 138, 145, 106, 105, 52, 0, 10, 3, 229, 143, 185, 116, 97, 110, 52, 0, 9, 3, 229, 139, 153, 119, 117, 53, 0, 0, 10, 3, 230, 135, 182, 108, 97, 110, 51, 0, 11, 3, 230, 129, 134, 104, 101, 110, 103, 50, 0, 9, 3, 229, 143, 182, 121, 101, 52, 0, 11, 3, 229, 128, 190, 113, 105, 110, 103, 49, 0, 0, 10, 3, 230, 133, 167, 104, 117, 105, 52, 0, 10, 3, 229, 143, 183, 104, 97, 111, 52, 0, 9, 3, 229, 137, 135, 122, 101, 50, 0, 10, 3, 230, 132, 159, 103, 97, 110, 51, 0, 11, 3, 230, 135, 183, 104, 117, 97, 105, 50, 0, 9, 3, 229, 141, 167, 119, 111, 52, 0, 0, 10, 3, 229, 128, 188, 122, 104, 105, 50, 0, 11, 3, 230, 134, 172, 106, 105, 110, 103, 51, 0, 0, 11, 3, 229, 139, 149, 100, 111, 110, 103, 52, 0, 9, 3, 230, 131, 149, 116, 105, 52, 0, 10, 3, 229, 142, 173, 121, 97, 110, 52, 0, 11, 3, 229, 138, 141, 106, 105, 97, 110, 52, 0, 0, 9, 3, 229, 137, 130, 106, 105, 52, 0, 11, 3, 229, 128, 186, 122, 104, 97, 105, 52, 0, 12, 3, 230, 135, 178, 99, 104, 101, 110, 103, 50, 0, 9, 3, 230, 132, 154, 121, 117, 50, 0, 10, 3, 229, 143, 178, 115, 104, 105, 51, 0, 10, 3, 230, 133, 162, 109, 97, 110, 52, 0, 9, 3, 229, 139, 146, 108, 101, 52, 0, 0, 10, 3, 229, 143, 179, 121, 111, 117, 52, 0, 11, 3, 230, 133, 163, 103, 117, 97, 110, 52, 0, 9, 3, 230, 132, 155, 97, 105, 52, 0, 0, 10, 3, 229, 143, 176, 116, 97, 105, 50, 0, 11, 3, 229, 141, 160, 122, 104, 97, 110, 52, 0, 9, 3, 229, 138, 136, 112, 105, 49, 0, 10, 3, 229, 142, 168, 99, 104, 117, 50, 0, 0, 10, 3, 229, 140, 153, 115, 104, 105, 53, 0, 9, 3, 230, 130, 137, 120, 105, 49, 0, 9, 3, 229, 141, 161, 107, 97, 51, 0, 10, 3, 230, 131, 145, 104, 117, 111, 52, 0, 0, 11, 3, 229, 143, 174, 100, 105, 110, 103, 49, 0, 10, 3, 229, 140, 150, 104, 117, 97, 52, 0, 10, 3, 229, 142, 166, 115, 104, 97, 52, 0, 0, 9, 3, 229, 138, 135, 106, 117, 52, 0, 12, 3, 229, 129, 191, 99, 104, 97, 110, 103, 50, 0, 10, 3, 229, 140, 151, 98, 101, 105, 51, 0, 9, 3, 229, 143, 175, 107, 101, 51, 0, 12, 3, 230, 134, 167, 99, 104, 111, 110, 103, 49, 0, 0, 11, 3, 229, 143, 172, 122, 104, 97, 111, 52, 0, 11, 3, 230, 130, 132, 113, 105, 97, 111, 49, 0, 9, 3, 229, 141, 156, 98, 111, 53, 0, 10, 3, 230, 134, 164, 102, 101, 110, 52, 0, 0, 8, 3, 230, 132, 149, 101, 52, 0, 10, 3, 229, 129, 189, 119, 101, 105, 51, 0, 9, 3, 229, 143, 173, 98, 97, 53, 0, 10, 3, 230, 130, 133, 121, 117, 101, 52, 0, 0, 12, 3, 229, 142, 162, 120, 105, 97, 110, 103, 49, 0, 10, 3, 229, 143, 170, 122, 104, 105, 51, 0, 10, 3, 230, 133, 154, 99, 97, 110, 50, 0, 9, 3, 229, 141, 154, 98, 111, 50, 0, 11, 3, 230, 131, 138, 106, 105, 110, 103, 49, 0, 0, 10, 3, 230, 131, 139, 119, 97, 110, 51, 0, 11, 3, 229, 143, 171, 106, 105, 97, 111, 52, 0, 0, 10, 3, 230, 133, 152, 99, 97, 110, 51, 0, 0, 11, 3, 229, 139, 137, 109, 105, 97, 110, 51, 0, 0, 10, 3, 229, 141, 150, 109, 97, 105, 52, 0, 9, 3, 229, 129, 182, 111, 117, 51, 0, 11, 3, 229, 143, 166, 108, 105, 110, 103, 52, 0, 11, 3, 229, 130, 190, 113, 105, 110, 103, 49, 0, 0, 10, 3, 229, 129, 183, 116, 111, 117, 49, 0, 10, 3, 229, 141, 151, 110, 97, 110, 50, 0, 11, 3, 229, 139, 135, 121, 111, 110, 103, 51, 0, 11, 3, 229, 142, 159, 121, 117, 97, 110, 50, 0, 9, 3, 230, 132, 143, 121, 105, 52, 0, 0, 9, 3, 229, 129, 180, 99, 101, 52, 0, 10, 3, 229, 141, 148, 120, 105, 101, 50, 0, 9, 3, 229, 143, 164, 103, 117, 51, 0, 0, 9, 3, 230, 133, 149, 109, 117, 52, 0, 9, 3, 229, 143, 165, 106, 117, 52, 0, 10, 3, 229, 141, 149, 100, 97, 110, 49, 0, 11, 3, 230, 131, 133, 113, 105, 110, 103, 50, 0, 11, 3, 229, 129, 181, 122, 104, 101, 110, 49, 0, 0, 10, 3, 229, 142, 154, 104, 111, 117, 52, 0, 11, 3, 229, 143, 162, 99, 111, 110, 103, 50, 0, 0, 9, 3, 229, 139, 131, 98, 111, 50, 0, 10, 3, 229, 143, 163, 107, 111, 117, 51, 0, 10, 3, 229, 130, 187, 115, 104, 97, 51, 0, 0, 10, 3, 229, 143, 160, 100, 105, 101, 50, 0, 9, 3, 230, 132, 136, 121, 117, 52, 0, 9, 3, 229, 142, 152, 108, 105, 50, 0, 0, 9, 3, 230, 132, 137, 121, 117, 50, 0, 10, 3, 229, 139, 129, 106, 105, 110, 52, 0, 10, 3, 229, 141, 145, 98, 101, 105, 49, 0, 0, 11, 3, 231, 133, 142, 106, 105, 97, 110, 49, 0, 10, 3, 230, 130, 182, 109, 101, 110, 52, 0, 11, 3, 230, 141, 142, 115, 104, 97, 111, 49, 0, 11, 3, 230, 128, 166, 112, 101, 110, 103, 49, 0, 10, 3, 229, 139, 190, 103, 111, 117, 49, 0, 0, 9, 3, 230, 129, 175, 120, 105, 53, 0, 11, 3, 231, 135, 159, 121, 105, 110, 103, 50, 0, 10, 3, 230, 141, 143, 110, 105, 101, 49, 0, 11, 3, 229, 148, 135, 99, 104, 117, 110, 50, 0, 9, 3, 229, 137, 175, 102, 117, 52, 0, 10, 3, 229, 149, 143, 119, 101, 110, 52, 0, 11, 3, 230, 128, 167, 120, 105, 110, 103, 52, 0, 10, 3, 230, 140, 135, 122, 104, 105, 51, 0, 0, 10, 3, 229, 136, 164, 112, 97, 110, 52, 0, 12, 3, 231, 133, 140, 104, 117, 97, 110, 103, 50, 0, 11, 3, 231, 134, 148, 114, 111, 110, 103, 50, 0, 8, 3, 229, 150, 148, 111, 49, 0, 10, 3, 229, 148, 132, 98, 101, 105, 53, 0, 0, 10, 3, 230, 141, 141, 104, 97, 110, 52, 0, 9, 3, 230, 128, 165, 106, 105, 50, 0, 10, 3, 229, 136, 165, 98, 105, 101, 50, 0, 0, 10, 3, 230, 142, 146, 112, 97, 105, 50, 0, 8, 3, 229, 149, 138, 97, 53, 0, 11, 3, 230, 143, 154, 121, 97, 110, 103, 50, 0, 10, 3, 230, 130, 178, 98, 101, 105, 49, 0, 10, 3, 230, 140, 130, 103, 117, 97, 52, 0, 11, 3, 229, 137, 170, 106, 105, 97, 110, 51, 0, 9, 3, 229, 151, 154, 119, 117, 49, 0, 10, 3, 229, 138, 178, 106, 105, 110, 52, 0, 0, 10, 3, 229, 138, 179, 108, 97, 111, 50, 0, 10, 3, 229, 139, 187, 121, 117, 110, 50, 0, 11, 3, 230, 143, 155, 104, 117, 97, 110, 52, 0, 0, 10, 3, 230, 129, 168, 104, 101, 110, 52, 0, 10, 3, 230, 142, 144, 113, 105, 97, 49, 0, 11, 3, 229, 139, 184, 113, 117, 97, 110, 52, 0, 0, 9, 3, 230, 131, 185, 114, 101, 51, 0, 12, 3, 229, 137, 169, 115, 104, 101, 110, 103, 52, 0, 10, 3, 230, 140, 129, 99, 104, 105, 50, 0, 9, 3, 229, 138, 177, 108, 105, 52, 0, 11, 3, 230, 141, 137, 122, 104, 117, 111, 49, 0, 11, 3, 231, 135, 153, 116, 97, 110, 103, 52, 0, 11, 3, 231, 133, 137, 108, 105, 97, 110, 52, 0, 0, 10, 3, 230, 141, 134, 107, 117, 110, 51, 0, 12, 3, 229, 149, 134, 115, 104, 97, 110, 103, 49, 0, 11, 3, 229, 140, 190, 98, 105, 97, 110, 51, 0, 12, 3, 230, 131, 182, 104, 117, 97, 110, 103, 50, 0, 0, 10, 3, 231, 134, 143, 120, 117, 110, 49, 0, 9, 3, 229, 137, 167, 106, 117, 52, 0, 11, 3, 230, 132, 191, 121, 117, 97, 110, 52, 0, 10, 3, 230, 142, 143, 116, 97, 111, 49, 0, 0, 11, 3, 230, 128, 156, 108, 105, 97, 110, 50, 0, 11, 3, 230, 130, 172, 120, 117, 97, 110, 50, 0, 12, 3, 230, 142, 140, 122, 104, 97, 110, 103, 51, 0, 11, 3, 229, 149, 132, 122, 104, 117, 111, 50, 0, 0, 10, 3, 229, 136, 157, 99, 104, 117, 49, 0, 9, 3, 229, 137, 165, 98, 111, 49, 0, 9, 3, 230, 128, 157, 115, 105, 49, 0, 9, 3, 229, 139, 181, 108, 105, 52, 0, 10, 3, 230, 129, 165, 99, 104, 105, 51, 0, 10, 3, 231, 135, 149, 121, 97, 110, 52, 0, 0, 12, 3, 231, 134, 138, 120, 105, 111, 110, 103, 50, 0, 10, 3, 229, 150, 138, 104, 97, 110, 51, 0, 10, 3, 230, 143, 146, 99, 104, 97, 49, 0, 9, 3, 229, 138, 170, 110, 117, 51, 0, 9, 3, 230, 141, 130, 119, 117, 51, 0, 10, 3, 230, 129, 162, 104, 117, 105, 49, 0, 11, 3, 231, 135, 146, 115, 104, 97, 111, 49, 0, 9, 3, 229, 140, 186, 113, 117, 49, 0, 11, 3, 229, 136, 154, 103, 97, 110, 103, 49, 0, 0, 13, 3, 229, 136, 155, 99, 104, 117, 97, 110, 103, 52, 0, 9, 3, 229, 140, 187, 121, 105, 49, 0, 10, 3, 229, 149, 131, 107, 101, 110, 51, 0, 12, 3, 230, 131, 179, 120, 105, 97, 110, 103, 51, 0, 11, 3, 229, 151, 147, 115, 97, 110, 103, 51, 0, 0, 9, 3, 230, 143, 144, 116, 105, 50, 0, 10, 3, 230, 130, 168, 110, 105, 110, 50, 0, 10, 3, 229, 151, 144, 104, 97, 105, 52, 0, 11, 3, 229, 138, 168, 100, 111, 110, 103, 52, 0, 11, 3, 230, 142, 136, 115, 104, 111, 117, 52, 0, 0, 9, 3, 229, 136, 153, 122, 101, 50, 0, 11, 3, 230, 142, 137, 100, 105, 97, 111, 52, 0, 10, 3, 230, 131, 177, 110, 97, 111, 51, 0, 9, 3, 229, 140, 185, 112, 105, 51, 0, 10, 3, 229, 138, 169, 122, 104, 117, 52, 0, 10, 3, 229, 150, 137, 104, 111, 117, 50, 0, 0, 10, 3, 230, 130, 166, 121, 117, 101, 52, 0, 9, 3, 230, 128, 150, 98, 117, 52, 0, 9, 3, 229, 151, 142, 109, 97, 53, 0, 0, 10, 3, 229, 136, 151, 108, 105, 101, 52, 0, 11, 3, 230, 143, 143, 109, 105, 97, 111, 50, 0, 9, 3, 229, 150, 135, 108, 97, 51, 0, 11, 3, 230, 131, 175, 103, 117, 97, 110, 52, 0, 0, 10, 3, 230, 142, 132, 108, 117, 110, 49, 0, 12, 3, 230, 128, 148, 122, 104, 101, 110, 103, 49, 0, 9, 3, 231, 134, 132, 120, 105, 49, 0, 11, 3, 229, 150, 132, 115, 104, 97, 110, 52, 0, 0, 9, 3, 230, 128, 149, 112, 97, 52, 0, 9, 3, 229, 137, 157, 98, 111, 49, 0, 10, 3, 230, 131, 173, 99, 97, 110, 50, 0, 10, 3, 230, 143, 141, 122, 111, 117, 52, 0, 0, 10, 3, 229, 136, 146, 104, 117, 97, 52, 0, 10, 3, 229, 150, 130, 119, 101, 105, 52, 0, 9, 3, 230, 128, 146, 110, 117, 52, 0, 0, 10, 3, 229, 150, 131, 110, 97, 110, 50, 0, 10, 3, 229, 141, 187, 113, 117, 101, 52, 0, 11, 3, 229, 137, 155, 103, 97, 110, 103, 49, 0, 10, 3, 229, 138, 163, 108, 105, 101, 52, 0, 10, 3, 230, 142, 131, 115, 97, 111, 51, 0, 11, 3, 230, 130, 163, 104, 117, 97, 110, 52, 0, 0, 11, 3, 231, 135, 136, 100, 101, 110, 103, 49, 0, 10, 3, 229, 138, 160, 106, 105, 97, 49, 0, 11, 3, 230, 142, 128, 120, 105, 97, 110, 49, 0, 10, 3, 230, 130, 160, 121, 111, 117, 49, 0, 10, 3, 229, 141, 184, 120, 105, 101, 52, 0, 10, 3, 230, 131, 168, 99, 97, 110, 51, 0, 0, 10, 3, 230, 143, 137, 114, 111, 117, 50, 0, 9, 3, 229, 138, 161, 119, 117, 53, 0, 12, 3, 230, 131, 169, 99, 104, 101, 110, 103, 50, 0, 11, 3, 229, 136, 145, 120, 105, 110, 103, 50, 0, 0, 10, 3, 229, 138, 158, 98, 97, 110, 52, 0, 10, 3, 230, 128, 142, 122, 101, 110, 51, 0, 11, 3, 230, 133, 182, 113, 105, 110, 103, 52, 0, 11, 3, 230, 131, 166, 100, 105, 97, 110, 52, 0, 10, 3, 230, 134, 190, 104, 97, 110, 52, 0, 10, 3, 229, 137, 150, 112, 111, 117, 49, 0, 0, 10, 3, 229, 140, 175, 104, 117, 105, 52, 0, 9, 3, 230, 130, 159, 119, 117, 52, 0, 9, 3, 230, 131, 167, 106, 117, 52, 0, 11, 3, 229, 141, 183, 106, 117, 97, 110, 51, 0, 11, 3, 229, 138, 159, 103, 111, 110, 103, 49, 0, 11, 3, 230, 133, 183, 107, 97, 110, 103, 49, 0, 11, 3, 229, 142, 191, 120, 105, 97, 110, 52, 0, 0, 10, 3, 229, 141, 180, 113, 117, 101, 52, 0, 9, 3, 229, 137, 148, 116, 105, 49, 0, 10, 3, 229, 139, 164, 113, 105, 110, 50, 0, 0, 11, 3, 229, 138, 157, 113, 117, 97, 110, 52, 0, 11, 3, 229, 141, 181, 108, 117, 97, 110, 51, 0, 10, 3, 229, 151, 133, 120, 105, 117, 52, 0, 0, 10, 3, 229, 140, 170, 102, 101, 105, 51, 0, 11, 3, 230, 129, 146, 104, 101, 110, 103, 50, 0, 10, 3, 229, 139, 162, 115, 104, 105, 52, 0, 10, 3, 229, 136, 138, 107, 97, 110, 49, 0, 0, 9, 3, 229, 142, 187, 113, 117, 52, 0, 9, 3, 229, 141, 179, 106, 105, 50, 0, 10, 3, 231, 135, 131, 114, 97, 110, 50, 0, 9, 3, 229, 138, 155, 108, 105, 52, 0, 0, 11, 3, 230, 143, 128, 106, 105, 97, 110, 51, 0, 10, 3, 229, 141, 176, 121, 105, 110, 52, 0, 10, 3, 230, 133, 176, 119, 101, 105, 52, 0, 11, 3, 230, 129, 144, 107, 111, 110, 103, 51, 0, 0, 11, 3, 229, 137, 145, 106, 105, 97, 110, 52, 0, 10, 3, 229, 141, 177, 119, 101, 105, 49, 0, 8, 3, 230, 131, 161, 101, 52, 0, 0, 9, 3, 229, 146, 150, 107, 97, 49, 0, 10, 3, 231, 133, 174, 122, 104, 117, 51, 0, 10, 3, 230, 137, 142, 122, 104, 97, 49, 0, 10, 3, 230, 138, 150, 100, 111, 117, 51, 0, 10, 3, 229, 144, 134, 121, 97, 111, 49, 0, 9, 3, 230, 141, 174, 106, 117, 52, 0, 11, 3, 231, 132, 166, 106, 105, 97, 111, 49, 0, 0, 11, 3, 230, 138, 151, 107, 97, 110, 103, 52, 0, 9, 3, 230, 139, 159, 110, 105, 51, 0, 10, 3, 230, 142, 183, 122, 104, 105, 52, 0, 9, 3, 229, 147, 159, 121, 111, 49, 0, 10, 3, 231, 131, 159, 121, 97, 110, 49, 0, 10, 3, 229, 150, 183, 112, 101, 110, 49, 0, 0, 10, 3, 230, 139, 156, 98, 97, 105, 52, 0, 11, 3, 231, 129, 140, 103, 117, 97, 110, 52, 0, 9, 3, 230, 140, 164, 106, 105, 51, 0, 9, 3, 229, 144, 132, 103, 101, 52, 0, 11, 3, 229, 148, 164, 104, 117, 97, 110, 52, 0, 0, 10, 3, 229, 151, 189, 115, 111, 117, 53, 0, 10, 3, 230, 138, 149, 116, 111, 117, 50, 0, 10, 3, 230, 137, 141, 99, 97, 105, 50, 0, 10, 3, 230, 140, 165, 104, 117, 105, 49, 0, 9, 3, 229, 146, 149, 103, 117, 53, 0, 11, 3, 231, 130, 149, 107, 97, 110, 103, 52, 0, 0, 10, 3, 229, 145, 138, 103, 97, 111, 52, 0, 11, 3, 231, 130, 146, 99, 104, 97, 111, 51, 0, 11, 3, 229, 146, 146, 122, 104, 111, 117, 52, 0, 9, 3, 229, 149, 170, 112, 97, 49, 0, 9, 3, 229, 150, 178, 121, 111, 49, 0, 0, 10, 3, 231, 131, 155, 122, 104, 117, 50, 0, 11, 3, 230, 137, 139, 115, 104, 111, 117, 51, 0, 11, 3, 230, 138, 147, 122, 104, 117, 97, 49, 0, 10, 3, 229, 144, 131, 99, 104, 105, 49, 0, 11, 3, 230, 139, 155, 122, 104, 97, 111, 49, 0, 12, 3, 230, 140, 163, 122, 104, 101, 110, 103, 49, 0, 0, 10, 3, 230, 142, 176, 98, 97, 105, 49, 0, 11, 3, 230, 136, 128, 108, 105, 97, 110, 52, 0, 12, 3, 229, 145, 136, 99, 104, 101, 110, 103, 50, 0, 9, 3, 230, 139, 152, 106, 117, 49, 0, 9, 3, 229, 146, 144, 102, 117, 53, 0, 11, 3, 231, 131, 152, 104, 111, 110, 103, 49, 0, 0, 9, 3, 231, 134, 177, 114, 101, 52, 0, 11, 3, 230, 140, 161, 100, 97, 110, 103, 51, 0, 9, 3, 229, 144, 129, 120, 117, 49, 0, 9, 3, 231, 132, 161, 119, 117, 50, 0, 9, 3, 230, 138, 145, 121, 105, 52, 0, 10, 3, 231, 133, 169, 102, 97, 110, 50, 0, 0, 10, 3, 229, 145, 134, 100, 97, 105, 49, 0, 10, 3, 230, 139, 150, 116, 117, 111, 49, 0, 10, 3, 231, 130, 142, 121, 97, 110, 50, 0, 9, 3, 229, 149, 166, 108, 97, 53, 0, 10, 3, 229, 150, 174, 100, 97, 110, 49, 0, 0, 10, 3, 230, 140, 159, 120, 105, 101, 50, 0, 11, 3, 231, 133, 167, 122, 104, 97, 111, 52, 0, 10, 3, 229, 147, 151, 104, 117, 97, 49, 0, 11, 3, 230, 137, 135, 115, 104, 97, 110, 52, 0, 11, 3, 230, 141, 167, 112, 101, 110, 103, 51, 0, 0, 10, 3, 231, 133, 164, 109, 101, 105, 50, 0, 9, 3, 230, 139, 148, 98, 97, 50, 0, 9, 3, 229, 149, 164, 112, 105, 50, 0, 9, 3, 231, 134, 172, 97, 111, 50, 0, 11, 3, 230, 143, 180, 121, 117, 97, 110, 50, 0, 9, 3, 229, 146, 140, 104, 101, 50, 0, 0, 10, 3, 229, 149, 165, 115, 104, 97, 52, 0, 0, 11, 3, 229, 150, 170, 115, 97, 110, 103, 52, 0, 9, 3, 230, 138, 138, 98, 97, 51, 0, 11, 3, 230, 141, 162, 104, 117, 97, 110, 52, 0, 10, 3, 230, 142, 170, 99, 117, 111, 52, 0, 9, 3, 229, 136, 186, 99, 105, 52, 0, 11, 3, 231, 130, 138, 99, 104, 117, 105, 49, 0, 9, 3, 230, 139, 146, 106, 117, 52, 0, 0, 9, 3, 229, 136, 187, 107, 101, 52, 0, 8, 3, 229, 145, 131, 101, 52, 0, 9, 3, 229, 146, 139, 122, 97, 51, 0, 11, 3, 230, 128, 187, 122, 111, 110, 103, 51, 0, 10, 3, 230, 141, 163, 100, 97, 111, 51, 0, 0, 10, 3, 230, 137, 128, 115, 117, 111, 51, 0, 11, 3, 230, 139, 144, 103, 117, 97, 105, 51, 0, 9, 3, 229, 145, 128, 121, 97, 53, 0, 10, 3, 230, 142, 168, 116, 117, 105, 49, 0, 0, 10, 3, 230, 142, 169, 121, 97, 110, 51, 0, 10, 3, 229, 149, 161, 102, 101, 105, 49, 0, 10, 3, 229, 136, 185, 115, 104, 97, 49, 0, 11, 3, 230, 137, 129, 98, 105, 97, 110, 51, 0, 9, 3, 231, 130, 137, 108, 117, 50, 0, 11, 3, 230, 141, 161, 106, 105, 97, 110, 51, 0, 9, 3, 229, 147, 145, 121, 97, 51, 0, 0, 10, 3, 229, 146, 134, 112, 97, 111, 50, 0, 10, 3, 230, 143, 174, 104, 117, 105, 49, 0, 10, 3, 231, 133, 158, 115, 104, 97, 52, 0, 9, 3, 229, 149, 158, 121, 97, 51, 0, 9, 3, 230, 140, 150, 119, 97, 49, 0, 10, 3, 230, 141, 158, 108, 97, 111, 49, 0, 9, 3, 229, 147, 142, 97, 105, 49, 0, 10, 3, 229, 136, 182, 122, 104, 105, 52, 0, 0, 9, 3, 229, 151, 175, 110, 103, 50, 0, 10, 3, 230, 141, 159, 115, 117, 110, 51, 0, 11, 3, 229, 136, 183, 115, 104, 117, 97, 49, 0, 11, 3, 230, 142, 167, 107, 111, 110, 103, 52, 0, 11, 3, 229, 137, 191, 106, 105, 97, 111, 51, 0, 9, 3, 229, 149, 159, 113, 105, 51, 0, 9, 3, 231, 131, 143, 119, 117, 49, 0, 10, 3, 229, 147, 143, 103, 101, 110, 50, 0, 0, 10, 3, 230, 139, 140, 98, 97, 110, 52, 0, 10, 3, 230, 129, 188, 110, 97, 111, 51, 0, 9, 3, 229, 151, 172, 104, 101, 49, 0, 11, 3, 230, 138, 132, 99, 104, 97, 111, 49, 0, 0, 10, 3, 231, 135, 173, 122, 104, 117, 50, 0, 12, 3, 229, 147, 141, 120, 105, 97, 110, 103, 51, 0, 10, 3, 230, 142, 165, 106, 105, 101, 49, 0, 10, 3, 230, 143, 173, 106, 105, 101, 49, 0, 10, 3, 230, 139, 141, 112, 97, 105, 49, 0, 0, 10, 3, 230, 142, 162, 116, 97, 110, 52, 0, 10, 3, 230, 143, 170, 106, 105, 117, 49, 0, 9, 3, 229, 146, 130, 122, 97, 49, 0, 0, 10, 3, 230, 139, 139, 112, 97, 111, 49, 0, 0, 9, 3, 230, 138, 128, 106, 105, 52, 0, 10, 3, 229, 151, 168, 104, 97, 105, 49, 0, 10, 3, 229, 136, 176, 100, 97, 111, 52, 0, 10, 3, 230, 142, 160, 108, 118, 101, 52, 0, 9, 3, 229, 146, 128, 106, 117, 51, 0, 9, 3, 229, 147, 136, 104, 97, 49, 0, 10, 3, 231, 131, 136, 108, 105, 101, 52, 0, 0, 11, 3, 230, 140, 145, 116, 105, 97, 111, 49, 0, 10, 3, 230, 143, 169, 107, 97, 105, 49, 0, 10, 3, 231, 133, 153, 121, 97, 110, 49, 0, 9, 3, 230, 139, 137, 108, 97, 49, 0, 0, 10, 3, 231, 135, 166, 99, 97, 110, 52, 0, 10, 3, 229, 151, 166, 115, 117, 111, 53, 0, 10, 3, 229, 147, 134, 100, 117, 111, 49, 0, 10, 3, 229, 136, 174, 103, 117, 97, 49, 0, 8, 3, 230, 129, 182, 101, 52, 0, 11, 3, 230, 139, 134, 99, 104, 97, 105, 49, 0, 10, 3, 230, 140, 142, 107, 117, 97, 52, 0, 0, 9, 3, 229, 147, 135, 119, 97, 53, 0, 10, 3, 230, 128, 175, 113, 105, 101, 52, 0, 10, 3, 231, 134, 159, 115, 104, 117, 50, 0, 10, 3, 229, 138, 191, 115, 104, 105, 52, 0, 9, 3, 230, 139, 135, 109, 117, 53, 0, 0, 11, 3, 229, 147, 132, 104, 111, 110, 103, 49, 0, 9, 3, 229, 150, 156, 120, 105, 51, 0, 10, 3, 230, 130, 188, 100, 97, 111, 52, 0, 10, 3, 230, 139, 132, 122, 104, 117, 51, 0, 0, 10, 3, 230, 139, 133, 100, 97, 110, 49, 0, 9, 3, 229, 150, 157, 104, 101, 49, 0, 13, 3, 229, 137, 181, 99, 104, 117, 97, 110, 103, 52, 0, 9, 3, 230, 141, 149, 98, 117, 51, 0, 10, 3, 231, 135, 165, 122, 97, 111, 52, 0, 0, 11, 3, 229, 150, 154, 104, 117, 97, 110, 52, 0, 9, 3, 229, 137, 178, 103, 101, 49, 0, 11, 3, 230, 128, 170, 103, 117, 97, 105, 52, 0, 10, 3, 231, 131, 130, 108, 97, 110, 52, 0, 10, 3, 231, 132, 138, 104, 97, 110, 52, 0, 0, 10, 3, 229, 136, 171, 98, 105, 101, 50, 0, 10, 3, 230, 142, 155, 103, 117, 97, 52, 0, 12, 3, 230, 143, 163, 99, 104, 117, 97, 105, 49, 0, 10, 3, 230, 129, 179, 107, 101, 110, 51, 0, 0, 9, 3, 229, 147, 128, 97, 105, 49, 0, 11, 3, 230, 128, 168, 121, 117, 97, 110, 52, 0, 12, 3, 229, 150, 152, 99, 104, 117, 97, 110, 51, 0, 10, 3, 230, 129, 176, 113, 105, 97, 52, 0, 11, 3, 230, 141, 144, 106, 117, 97, 110, 49, 0, 10, 3, 229, 136, 168, 112, 97, 111, 50, 0, 10, 3, 230, 142, 152, 106, 117, 101, 50, 0, 0, 12, 3, 230, 142, 153, 122, 104, 101, 110, 103, 49, 0, 11, 3, 229, 151, 161, 119, 101, 110, 103, 49, 0, 9, 3, 229, 136, 169, 108, 105, 52, 0, 9, 3, 230, 140, 137, 97, 110, 52, 0, 9, 3, 230, 143, 161, 119, 111, 52, 0, 11, 3, 231, 131, 129, 115, 104, 117, 111, 52, 0, 10, 3, 229, 147, 129, 112, 105, 110, 51, 0, 0, 11, 3, 229, 156, 134, 121, 117, 97, 110, 50, 0, 10, 3, 230, 137, 174, 98, 97, 110, 53, 0, 10, 3, 229, 157, 142, 107, 97, 110, 51, 0, 10, 3, 232, 132, 134, 99, 117, 105, 52, 0, 12, 3, 231, 141, 142, 106, 105, 97, 110, 103, 51, 0, 10, 3, 229, 144, 166, 102, 111, 117, 51, 0, 10, 3, 230, 139, 190, 115, 104, 105, 53, 0, 11, 3, 230, 148, 134, 110, 105, 97, 110, 51, 0, 0, 11, 3, 231, 129, 175, 100, 101, 110, 103, 49, 0, 11, 3, 229, 157, 143, 104, 117, 97, 105, 52, 0, 9, 3, 230, 139, 191, 110, 97, 50, 0, 11, 3, 232, 135, 159, 122, 97, 110, 103, 52, 0, 9, 3, 229, 159, 159, 121, 117, 52, 0, 10, 3, 230, 137, 175, 99, 104, 101, 51, 0, 10, 3, 230, 149, 143, 109, 105, 110, 51, 0, 9, 3, 229, 144, 167, 98, 97, 53, 0, 10, 3, 230, 150, 151, 100, 111, 117, 52, 0, 0, 10, 3, 230, 139, 188, 112, 105, 110, 49, 0, 11, 3, 230, 137, 172, 121, 97, 110, 103, 50, 0, 9, 3, 230, 149, 140, 100, 105, 50, 0, 11, 3, 229, 147, 188, 104, 101, 110, 103, 49, 0, 0, 9, 3, 230, 138, 181, 100, 105, 51, 0, 10, 3, 232, 132, 133, 120, 105, 101, 50, 0, 10, 3, 231, 129, 173, 109, 105, 101, 52, 0, 11, 3, 229, 147, 189, 103, 101, 110, 103, 51, 0, 10, 3, 230, 137, 173, 110, 105, 117, 51, 0, 0, 10, 3, 229, 158, 146, 108, 101, 105, 51, 0, 10, 3, 232, 132, 130, 122, 104, 105, 49, 0, 9, 3, 229, 147, 186, 98, 117, 51, 0, 11, 3, 229, 157, 138, 102, 97, 110, 103, 53, 0, 0, 10, 3, 231, 129, 171, 104, 117, 111, 51, 0, 10, 3, 230, 137, 171, 115, 97, 111, 51, 0, 10, 3, 229, 146, 179, 104, 97, 105, 49, 0, 0, 10, 3, 230, 148, 128, 112, 97, 110, 49, 0, 11, 3, 229, 145, 168, 122, 104, 111, 117, 49, 0, 11, 3, 230, 149, 136, 120, 105, 97, 111, 52, 0, 11, 3, 232, 133, 136, 106, 105, 110, 103, 49, 0, 0, 10, 3, 230, 137, 169, 107, 117, 111, 52, 0, 10, 3, 230, 138, 177, 98, 97, 111, 52, 0, 10, 3, 229, 146, 177, 122, 97, 110, 50, 0, 0, 10, 3, 229, 148, 190, 116, 117, 111, 52, 0, 10, 3, 229, 144, 158, 116, 117, 110, 49, 0, 10, 3, 230, 140, 190, 120, 105, 101, 50, 0, 10, 3, 231, 130, 174, 112, 97, 111, 52, 0, 0, 10, 3, 232, 134, 143, 103, 97, 111, 49, 0, 12, 3, 231, 130, 175, 106, 105, 111, 110, 103, 51, 0, 10, 3, 229, 144, 159, 121, 105, 110, 50, 0, 10, 3, 230, 137, 167, 122, 104, 105, 50, 0, 9, 3, 230, 151, 151, 113, 105, 50, 0, 10, 3, 229, 157, 135, 106, 117, 110, 49, 0, 0, 10, 3, 230, 138, 172, 116, 97, 105, 50, 0, 9, 3, 231, 141, 132, 121, 117, 52, 0, 10, 3, 229, 146, 172, 121, 97, 111, 51, 0, 12, 3, 230, 139, 180, 115, 104, 117, 97, 110, 49, 0, 0, 9, 3, 230, 149, 133, 103, 117, 52, 0, 10, 3, 231, 130, 173, 116, 97, 110, 52, 0, 10, 3, 230, 140, 189, 119, 97, 110, 51, 0, 10, 3, 231, 141, 133, 115, 104, 105, 49, 0, 9, 3, 231, 128, 157, 108, 105, 52, 0, 0, 10, 3, 229, 147, 178, 122, 104, 101, 50, 0, 9, 3, 232, 134, 138, 98, 111, 53, 0, 9, 3, 229, 145, 162, 110, 101, 53, 0, 11, 3, 230, 140, 186, 116, 105, 110, 103, 51, 0, 9, 3, 230, 136, 154, 113, 105, 53, 0, 0, 11, 3, 229, 158, 139, 120, 105, 110, 103, 50, 0, 11, 3, 231, 142, 139, 119, 97, 110, 103, 50, 0, 11, 3, 230, 139, 179, 113, 117, 97, 110, 50, 0, 10, 3, 231, 129, 163, 119, 97, 110, 49, 0, 10, 3, 229, 144, 155, 106, 117, 110, 49, 0, 10, 3, 230, 137, 163, 107, 111, 117, 52, 0, 9, 3, 230, 138, 171, 112, 105, 49, 0, 0, 10, 3, 229, 157, 128, 122, 104, 105, 51, 0, 11, 3, 230, 136, 152, 122, 104, 97, 110, 52, 0, 0, 11, 3, 230, 139, 177, 103, 111, 110, 103, 51, 0, 9, 3, 231, 142, 137, 121, 117, 52, 0, 11, 3, 231, 143, 145, 108, 111, 110, 103, 50, 0, 0, 9, 3, 229, 146, 166, 121, 105, 50, 0, 10, 3, 229, 149, 190, 106, 105, 117, 49, 0, 10, 3, 230, 136, 150, 104, 117, 111, 52, 0, 11, 3, 229, 147, 174, 120, 105, 97, 111, 49, 0, 12, 3, 229, 159, 142, 99, 104, 101, 110, 103, 50, 0, 10, 3, 231, 132, 182, 114, 97, 110, 50, 0, 0, 9, 3, 230, 151, 143, 122, 117, 50, 0, 9, 3, 231, 142, 135, 108, 118, 52, 0, 10, 3, 229, 146, 167, 108, 105, 101, 53, 0, 9, 3, 229, 144, 151, 109, 97, 53, 0, 10, 3, 230, 150, 135, 119, 101, 110, 50, 0, 0, 9, 3, 229, 149, 188, 116, 105, 50, 0, 11, 3, 229, 158, 132, 108, 111, 110, 103, 51, 0, 10, 3, 230, 139, 172, 107, 117, 111, 52, 0, 9, 3, 229, 145, 156, 119, 117, 49, 0, 9, 3, 230, 138, 164, 104, 117, 52, 0, 0, 10, 3, 230, 138, 165, 98, 97, 111, 52, 0, 10, 3, 230, 139, 173, 115, 104, 105, 52, 0, 9, 3, 231, 131, 173, 114, 101, 52, 0, 9, 3, 229, 147, 173, 107, 117, 49, 0, 11, 3, 231, 143, 141, 122, 104, 101, 110, 49, 0, 0, 11, 3, 229, 158, 130, 99, 104, 117, 105, 50, 0, 10, 3, 230, 136, 146, 106, 105, 101, 52, 0, 9, 3, 229, 147, 170, 110, 97, 51, 0, 11, 3, 231, 143, 138, 115, 104, 97, 110, 49, 0, 12, 3, 230, 138, 162, 113, 105, 97, 110, 103, 51, 0, 0, 11, 3, 230, 141, 187, 110, 105, 97, 110, 51, 0, 9, 3, 230, 150, 131, 98, 105, 52, 0, 11, 3, 231, 131, 171, 116, 97, 110, 103, 52, 0, 11, 3, 230, 137, 155, 107, 97, 110, 103, 50, 0, 11, 3, 230, 151, 139, 120, 117, 97, 110, 50, 0, 10, 3, 229, 144, 147, 120, 105, 97, 52, 0, 9, 3, 229, 158, 131, 108, 97, 49, 0, 10, 3, 229, 159, 139, 109, 97, 105, 50, 0, 0, 10, 3, 231, 129, 152, 116, 97, 110, 49, 0, 11, 3, 229, 145, 152, 121, 117, 97, 110, 50, 0, 10, 3, 231, 132, 176, 121, 97, 110, 52, 0, 11, 3, 229, 148, 176, 115, 104, 117, 97, 49, 0, 12, 3, 230, 136, 144, 99, 104, 101, 110, 103, 50, 0, 11, 3, 229, 149, 184, 120, 105, 97, 111, 52, 0, 9, 3, 230, 139, 168, 98, 111, 49, 0, 10, 3, 230, 137, 152, 116, 117, 111, 49, 0, 11, 3, 232, 134, 128, 98, 97, 110, 103, 51, 0, 9, 3, 229, 144, 144, 116, 117, 51, 0, 11, 3, 229, 147, 168, 115, 104, 97, 111, 52, 0, 0, 10, 3, 230, 138, 161, 108, 117, 110, 49, 0, 12, 3, 229, 144, 145, 120, 105, 97, 110, 103, 52, 0, 9, 3, 231, 128, 145, 112, 117, 52, 0, 9, 3, 229, 147, 169, 108, 105, 53, 0, 12, 3, 229, 148, 177, 99, 104, 97, 110, 103, 52, 0, 9, 3, 230, 136, 145, 119, 111, 51, 0, 11, 3, 232, 135, 137, 108, 105, 97, 110, 51, 0, 9, 3, 230, 139, 169, 122, 101, 50, 0, 0, 11, 3, 229, 148, 174, 115, 104, 111, 117, 52, 0, 11, 3, 230, 141, 182, 99, 104, 117, 105, 50, 0, 10, 3, 229, 144, 142, 104, 111, 117, 52, 0, 10, 3, 230, 139, 166, 108, 97, 110, 50, 0, 10, 3, 231, 131, 166, 102, 97, 110, 50, 0, 8, 3, 229, 147, 166, 111, 50, 0, 0, 11, 3, 230, 140, 175, 122, 104, 101, 110, 52, 0, 9, 3, 230, 136, 143, 120, 105, 52, 0, 10, 3, 230, 141, 183, 106, 105, 101, 50, 0, 10, 3, 229, 147, 167, 99, 104, 105, 49, 0, 11, 3, 231, 131, 167, 115, 104, 97, 111, 49, 0, 10, 3, 229, 148, 175, 119, 101, 105, 50, 0, 11, 3, 230, 139, 167, 110, 105, 110, 103, 50, 0, 10, 3, 229, 145, 151, 98, 101, 105, 53, 0, 0, 11, 3, 229, 144, 140, 116, 111, 110, 103, 50, 0, 10, 3, 231, 131, 164, 107, 97, 111, 51, 0, 11, 3, 230, 137, 148, 114, 101, 110, 103, 49, 0, 9, 3, 229, 148, 172, 104, 117, 53, 0, 0, 11, 3, 230, 139, 165, 121, 111, 110, 103, 49, 0, 10, 3, 229, 150, 189, 108, 111, 117, 53, 0, 11, 3, 229, 144, 141, 109, 105, 110, 103, 50, 0, 9, 3, 229, 147, 165, 103, 101, 49, 0, 9, 3, 230, 151, 133, 108, 118, 51, 0, 0, 9, 3, 230, 137, 146, 98, 97, 49, 0, 9, 3, 230, 138, 154, 102, 117, 51, 0, 11, 3, 229, 144, 138, 100, 105, 97, 111, 52, 0, 11, 3, 230, 139, 162, 108, 111, 110, 103, 51, 0, 9, 3, 232, 135, 130, 98, 105, 52, 0, 0, 11, 3, 230, 139, 163, 106, 105, 97, 110, 51, 0, 9, 3, 229, 159, 131, 97, 105, 49, 0, 10, 3, 230, 140, 171, 99, 117, 111, 52, 0, 11, 3, 229, 146, 155, 110, 105, 110, 103, 50, 0, 9, 3, 230, 137, 147, 100, 97, 51, 0, 10, 3, 230, 138, 155, 112, 97, 111, 49, 0, 0, 9, 3, 230, 140, 168, 97, 105, 49, 0, 9, 3, 229, 144, 136, 104, 101, 50, 0, 10, 3, 230, 138, 152, 122, 104, 101, 50, 0, 9, 3, 229, 145, 144, 110, 101, 53, 0, 0, 11, 3, 230, 151, 129, 112, 97, 110, 103, 50, 0, 11, 3, 229, 146, 153, 108, 111, 110, 103, 50, 0, 9, 3, 230, 137, 145, 112, 117, 49, 0, 9, 3, 229, 144, 137, 106, 105, 50, 0, 11, 3, 229, 147, 161, 121, 117, 97, 110, 50, 0, 0, 11, 3, 231, 143, 190, 120, 105, 97, 110, 52, 0, 10, 3, 231, 136, 134, 98, 97, 111, 52, 0, 10, 3, 229, 152, 134, 116, 97, 110, 52, 0, 10, 3, 232, 131, 158, 98, 97, 111, 49, 0, 10, 3, 232, 133, 174, 115, 97, 105, 49, 0, 11, 3, 232, 130, 150, 120, 105, 97, 111, 52, 0, 10, 3, 229, 155, 158, 104, 117, 105, 50, 0, 0, 9, 3, 229, 157, 175, 112, 105, 49, 0, 11, 3, 230, 150, 183, 100, 117, 97, 110, 52, 0, 0, 11, 3, 230, 149, 172, 106, 105, 110, 103, 52, 0, 10, 3, 232, 129, 140, 122, 104, 105, 50, 0, 10, 3, 231, 137, 140, 112, 97, 105, 50, 0, 10, 3, 230, 148, 164, 116, 97, 110, 49, 0, 12, 3, 232, 131, 156, 115, 104, 101, 110, 103, 52, 0, 0, 11, 3, 230, 144, 133, 106, 105, 97, 111, 51, 0, 11, 3, 230, 148, 165, 122, 117, 97, 110, 52, 0, 10, 3, 232, 128, 133, 122, 104, 101, 51, 0, 9, 3, 230, 146, 149, 115, 105, 49, 0, 0, 10, 3, 230, 145, 138, 116, 97, 110, 49, 0, 11, 3, 231, 142, 178, 108, 105, 110, 103, 50, 0, 10, 3, 230, 148, 162, 122, 97, 110, 51, 0, 9, 3, 230, 146, 146, 115, 97, 49, 0, 9, 3, 229, 159, 186, 106, 105, 49, 0, 11, 3, 232, 129, 138, 108, 105, 97, 111, 50, 0, 9, 3, 230, 147, 154, 106, 117, 52, 0, 11, 3, 230, 151, 186, 119, 97, 110, 103, 52, 0, 10, 3, 230, 144, 130, 108, 111, 117, 51, 0, 0, 10, 3, 232, 128, 131, 107, 97, 111, 51, 0, 9, 3, 229, 155, 155, 115, 105, 52, 0, 12, 3, 229, 156, 163, 115, 104, 101, 110, 103, 52, 0, 12, 3, 232, 133, 171, 122, 104, 111, 110, 103, 51, 0, 0, 11, 3, 231, 142, 176, 120, 105, 97, 110, 52, 0, 9, 3, 229, 152, 128, 100, 105, 50, 0, 10, 3, 230, 150, 176, 120, 105, 110, 49, 0, 12, 3, 230, 146, 144, 99, 104, 101, 110, 103, 49, 0, 10, 3, 232, 128, 128, 121, 97, 111, 52, 0, 9, 3, 231, 141, 168, 100, 117, 50, 0, 11, 3, 230, 144, 128, 99, 104, 97, 110, 49, 0, 10, 3, 231, 137, 136, 98, 97, 110, 51, 0, 0, 10, 3, 232, 128, 129, 108, 97, 111, 51, 0, 12, 3, 230, 146, 145, 99, 104, 101, 110, 103, 49, 0, 9, 3, 230, 144, 129, 103, 101, 49, 0, 10, 3, 229, 159, 185, 112, 101, 105, 50, 0, 0, 10, 3, 230, 151, 182, 115, 104, 105, 50, 0, 10, 3, 229, 157, 166, 116, 97, 110, 51, 0, 10, 3, 230, 145, 134, 98, 97, 105, 51, 0, 10, 3, 229, 158, 174, 107, 117, 97, 51, 0, 11, 3, 232, 131, 150, 112, 97, 110, 103, 52, 0, 12, 3, 231, 137, 134, 113, 105, 97, 110, 103, 50, 0, 10, 3, 232, 133, 166, 110, 97, 111, 51, 0, 0, 9, 3, 229, 156, 159, 116, 117, 51, 0, 10, 3, 229, 159, 183, 122, 104, 105, 50, 0, 11, 3, 231, 137, 135, 112, 105, 97, 110, 52, 0, 9, 3, 230, 150, 175, 115, 105, 49, 0, 12, 3, 230, 151, 183, 107, 117, 97, 110, 103, 52, 0, 11, 3, 230, 136, 191, 102, 97, 110, 103, 50, 0, 10, 3, 231, 139, 151, 103, 111, 117, 51, 0, 10, 3, 230, 145, 135, 121, 97, 111, 50, 0, 11, 3, 231, 142, 175, 104, 117, 97, 110, 50, 0, 0, 10, 3, 232, 135, 180, 122, 104, 105, 52, 0, 10, 3, 230, 147, 148, 100, 97, 110, 49, 0, 10, 3, 229, 144, 188, 104, 111, 117, 51, 0, 10, 3, 230, 148, 156, 120, 105, 101, 50, 0, 9, 3, 232, 130, 140, 106, 105, 49, 0, 10, 3, 230, 145, 132, 115, 104, 101, 52, 0, 10, 3, 231, 140, 156, 99, 97, 105, 49, 0, 0, 11, 3, 230, 150, 173, 100, 117, 97, 110, 52, 0, 11, 3, 232, 133, 165, 120, 105, 110, 103, 49, 0, 10, 3, 230, 148, 157, 115, 104, 101, 52, 0, 0, 11, 3, 232, 132, 154, 106, 105, 97, 111, 51, 0, 10, 3, 230, 149, 162, 103, 97, 110, 51, 0, 0, 11, 3, 229, 158, 171, 100, 105, 97, 110, 52, 0, 11, 3, 231, 140, 155, 109, 101, 110, 103, 51, 0, 10, 3, 230, 149, 163, 115, 97, 110, 52, 0, 10, 3, 229, 144, 187, 119, 101, 110, 51, 0, 10, 3, 232, 135, 179, 122, 104, 105, 52, 0, 0, 11, 3, 232, 134, 168, 112, 101, 110, 103, 50, 0, 11, 3, 229, 156, 152, 116, 117, 97, 110, 50, 0, 10, 3, 230, 146, 136, 108, 97, 111, 49, 0, 11, 3, 229, 157, 160, 122, 104, 117, 105, 52, 0, 9, 3, 229, 144, 184, 120, 105, 49, 0, 9, 3, 231, 139, 144, 104, 117, 50, 0, 0, 10, 3, 231, 142, 169, 119, 97, 110, 50, 0, 11, 3, 230, 148, 153, 99, 104, 97, 110, 49, 0, 10, 3, 229, 155, 145, 122, 104, 117, 51, 0, 10, 3, 232, 130, 137, 114, 111, 117, 52, 0, 10, 3, 230, 151, 177, 104, 97, 110, 52, 0, 9, 3, 229, 157, 161, 112, 111, 49, 0, 11, 3, 229, 144, 185, 99, 104, 117, 105, 49, 0, 0, 12, 3, 230, 149, 158, 99, 104, 97, 110, 103, 53, 0, 9, 3, 229, 144, 182, 110, 101, 53, 0, 9, 3, 229, 156, 150, 116, 117, 50, 0, 11, 3, 230, 137, 190, 122, 104, 97, 111, 51, 0, 9, 3, 232, 132, 150, 98, 111, 50, 0, 10, 3, 232, 131, 142, 116, 97, 105, 49, 0, 9, 3, 230, 136, 182, 104, 117, 52, 0, 10, 3, 229, 158, 166, 107, 101, 110, 51, 0, 10, 3, 231, 129, 190, 122, 97, 105, 49, 0, 0, 10, 3, 229, 154, 135, 120, 105, 97, 52, 0, 10, 3, 231, 129, 191, 99, 97, 110, 52, 0, 10, 3, 229, 157, 159, 102, 101, 110, 50, 0, 9, 3, 230, 136, 183, 104, 117, 52, 0, 12, 3, 230, 137, 191, 99, 104, 101, 110, 103, 50, 0, 9, 3, 230, 150, 167, 102, 117, 51, 0, 0, 10, 3, 230, 136, 180, 100, 97, 105, 52, 0, 10, 3, 230, 150, 164, 106, 105, 110, 49, 0, 10, 3, 230, 148, 148, 108, 97, 110, 50, 0, 9, 3, 229, 145, 188, 104, 117, 49, 0, 10, 3, 232, 131, 140, 98, 101, 105, 52, 0, 10, 3, 230, 151, 172, 120, 117, 110, 50, 0, 0, 9, 3, 229, 157, 157, 98, 97, 52, 0, 11, 3, 229, 144, 181, 99, 104, 97, 111, 51, 0, 10, 3, 230, 147, 141, 99, 97, 111, 49, 0, 10, 3, 231, 129, 189, 122, 97, 105, 49, 0, 11, 3, 229, 145, 189, 109, 105, 110, 103, 52, 0, 11, 3, 232, 135, 173, 99, 104, 111, 117, 52, 0, 10, 3, 231, 143, 173, 98, 97, 110, 49, 0, 9, 3, 232, 130, 133, 115, 117, 52, 0, 10, 3, 230, 150, 165, 99, 104, 105, 52, 0, 10, 3, 230, 146, 133, 106, 117, 101, 49, 0, 0, 9, 3, 230, 136, 178, 120, 105, 52, 0, 10, 3, 230, 148, 146, 122, 97, 110, 51, 0, 11, 3, 230, 146, 130, 108, 105, 97, 111, 52, 0, 9, 3, 232, 135, 170, 122, 105, 52, 0, 11, 3, 229, 156, 146, 121, 117, 97, 110, 50, 0, 11, 3, 229, 157, 154, 106, 105, 97, 110, 49, 0, 9, 3, 230, 147, 138, 106, 105, 49, 0, 0, 11, 3, 230, 147, 139, 100, 97, 110, 103, 51, 0, 11, 3, 229, 156, 147, 121, 117, 97, 110, 50, 0, 11, 3, 229, 145, 187, 115, 104, 101, 110, 49, 0, 9, 3, 232, 130, 131, 115, 117, 52, 0, 0, 10, 3, 229, 145, 184, 112, 101, 105, 49, 0, 9, 3, 231, 138, 128, 120, 105, 49, 0, 11, 3, 229, 154, 128, 110, 105, 110, 103, 50, 0, 9, 3, 230, 149, 152, 120, 117, 52, 0, 10, 3, 231, 139, 136, 98, 101, 105, 52, 0, 10, 3, 232, 135, 168, 108, 105, 110, 50, 0, 11, 3, 230, 136, 176, 122, 104, 97, 110, 52, 0, 11, 3, 232, 134, 160, 106, 105, 97, 111, 49, 0, 0, 9, 3, 230, 137, 185, 112, 105, 49, 0, 10, 3, 230, 151, 169, 122, 97, 111, 51, 0, 9, 3, 231, 138, 129, 108, 105, 50, 0, 11, 3, 230, 149, 153, 106, 105, 97, 111, 52, 0, 10, 3, 232, 132, 145, 110, 97, 111, 51, 0, 0, 10, 3, 230, 151, 166, 100, 97, 110, 52, 0, 10, 3, 232, 131, 134, 100, 97, 110, 51, 0, 10, 3, 231, 129, 182, 122, 97, 111, 52, 0, 10, 3, 231, 140, 142, 108, 105, 101, 52, 0, 9, 3, 230, 137, 182, 102, 117, 50, 0, 0, 10, 3, 230, 149, 151, 98, 97, 105, 52, 0, 9, 3, 229, 144, 175, 113, 105, 51, 0, 9, 3, 230, 147, 135, 122, 101, 50, 0, 11, 3, 232, 132, 143, 122, 97, 110, 103, 52, 0, 10, 3, 230, 151, 167, 106, 105, 117, 52, 0, 11, 3, 229, 157, 151, 107, 117, 97, 105, 52, 0, 10, 3, 230, 138, 191, 109, 105, 110, 51, 0, 11, 3, 230, 148, 143, 108, 111, 110, 103, 51, 0, 0, 9, 3, 230, 138, 188, 121, 97, 49, 0, 11, 3, 229, 144, 172, 116, 105, 110, 103, 49, 0, 10, 3, 230, 150, 156, 120, 105, 101, 50, 0, 9, 3, 232, 134, 156, 109, 111, 50, 0, 12, 3, 232, 133, 148, 113, 105, 97, 110, 103, 49, 0, 11, 3, 231, 130, 188, 108, 105, 97, 110, 52, 0, 0, 10, 3, 229, 146, 189, 121, 97, 110, 52, 0, 9, 3, 232, 134, 157, 120, 105, 49, 0, 10, 3, 229, 156, 141, 119, 101, 105, 50, 0, 9, 3, 232, 135, 165, 119, 111, 52, 0, 11, 3, 230, 138, 189, 99, 104, 111, 117, 49, 0, 11, 3, 229, 144, 173, 107, 101, 110, 103, 49, 0, 11, 3, 231, 129, 181, 108, 105, 110, 103, 50, 0, 8, 3, 229, 145, 181, 97, 49, 0, 9, 3, 230, 151, 165, 114, 105, 52, 0, 0, 9, 3, 230, 151, 162, 106, 105, 52, 0, 9, 3, 232, 134, 154, 102, 117, 49, 0, 9, 3, 232, 132, 138, 106, 105, 50, 0, 10, 3, 231, 130, 186, 119, 101, 105, 52, 0, 10, 3, 230, 136, 170, 106, 105, 101, 50, 0, 12, 3, 231, 139, 130, 107, 117, 97, 110, 103, 50, 0, 0, 10, 3, 230, 137, 179, 98, 97, 110, 49, 0, 10, 3, 229, 144, 171, 104, 97, 110, 50, 0, 11, 3, 232, 135, 163, 99, 104, 101, 110, 50, 0, 10, 3, 229, 156, 139, 103, 117, 111, 50, 0, 10, 3, 229, 145, 179, 119, 101, 105, 52, 0, 11, 3, 232, 134, 155, 116, 97, 110, 103, 50, 0, 10, 3, 232, 131, 131, 119, 101, 105, 52, 0, 0, 11, 3, 229, 156, 136, 113, 117, 97, 110, 49, 0, 10, 3, 230, 137, 176, 114, 97, 111, 51, 0, 10, 3, 231, 143, 160, 122, 104, 117, 49, 0, 12, 3, 232, 131, 128, 122, 104, 97, 110, 103, 52, 0, 9, 3, 229, 159, 160, 98, 117, 52, 0, 9, 3, 232, 133, 144, 102, 117, 51, 0, 10, 3, 229, 144, 168, 100, 117, 110, 49, 0, 10, 3, 231, 129, 176, 104, 117, 105, 49, 0, 9, 3, 230, 151, 160, 119, 117, 50, 0, 10, 3, 229, 157, 144, 122, 117, 111, 52, 0, 10, 3, 231, 130, 184, 122, 104, 97, 52, 0, 13, 3, 231, 139, 128, 122, 104, 117, 97, 110, 103, 52, 0, 11, 3, 229, 146, 184, 120, 105, 97, 110, 50, 0, 10, 3, 232, 132, 136, 109, 97, 105, 52, 0, 0, 10, 3, 230, 149, 145, 106, 105, 117, 52, 0, 11, 3, 231, 130, 185, 100, 105, 97, 110, 51, 0, 10, 3, 232, 132, 137, 109, 97, 105, 52, 0, 11, 3, 230, 150, 153, 108, 105, 97, 111, 52, 0, 10, 3, 232, 131, 129, 120, 105, 101, 50, 0, 9, 3, 230, 138, 185, 109, 111, 51, 0, 11, 3, 229, 157, 145, 107, 101, 110, 103, 49, 0, 11, 3, 230, 147, 129, 121, 111, 110, 103, 49, 0, 10, 3, 229, 144, 169, 102, 101, 110, 49, 0, 0, 10, 3, 230, 147, 190, 114, 97, 111, 51, 0, 9, 3, 230, 157, 142, 108, 105, 51, 0, 13, 3, 231, 138, 182, 122, 104, 117, 97, 110, 103, 52, 0, 11, 3, 232, 142, 150, 106, 105, 110, 103, 49, 0, 9, 3, 229, 155, 190, 116, 117, 50, 0, 0, 11, 3, 229, 154, 183, 114, 97, 110, 103, 51, 0, 10, 3, 229, 164, 135, 98, 101, 105, 52, 0, 10, 3, 230, 158, 151, 108, 105, 110, 50, 0, 11, 3, 232, 129, 175, 108, 105, 97, 110, 50, 0, 10, 3, 231, 149, 143, 119, 101, 105, 52, 0, 10, 3, 229, 165, 143, 122, 111, 117, 52, 0, 11, 3, 231, 150, 151, 108, 105, 97, 111, 50, 0, 0, 10, 3, 232, 143, 156, 99, 97, 105, 52, 0, 11, 3, 231, 139, 188, 108, 97, 110, 103, 50, 0, 10, 3, 232, 140, 132, 106, 105, 97, 49, 0, 10, 3, 230, 159, 156, 103, 117, 105, 52, 0, 10, 3, 231, 149, 140, 106, 105, 101, 52, 0, 10, 3, 229, 154, 180, 121, 97, 110, 50, 0, 10, 3, 229, 164, 132, 99, 104, 117, 52, 0, 12, 3, 229, 167, 156, 106, 105, 97, 110, 103, 49, 0, 0, 11, 3, 233, 135, 157, 122, 104, 101, 110, 49, 0, 10, 3, 231, 139, 189, 98, 101, 105, 52, 0, 10, 3, 229, 155, 189, 103, 117, 111, 50, 0, 11, 3, 230, 146, 181, 110, 105, 97, 110, 51, 0, 10, 3, 232, 140, 133, 109, 97, 111, 50, 0, 11, 3, 232, 131, 189, 110, 101, 110, 103, 50, 0, 11, 3, 230, 158, 149, 122, 104, 101, 110, 51, 0, 10, 3, 233, 133, 141, 112, 101, 105, 52, 0, 0, 9, 3, 229, 155, 186, 103, 117, 52, 0, 9, 3, 232, 130, 178, 121, 117, 52, 0, 11, 3, 232, 129, 170, 99, 111, 110, 103, 49, 0, 9, 3, 230, 146, 178, 112, 117, 49, 0, 10, 3, 230, 147, 186, 98, 97, 105, 51, 0, 10, 3, 229, 153, 170, 122, 97, 111, 52, 0, 10, 3, 232, 140, 130, 109, 97, 111, 52, 0, 11, 3, 233, 134, 146, 120, 105, 110, 103, 51, 0, 0, 10, 3, 230, 156, 131, 104, 117, 105, 52, 0, 10, 3, 232, 140, 131, 102, 97, 110, 52, 0, 11, 3, 231, 151, 155, 116, 111, 110, 103, 52, 0, 10, 3, 229, 165, 139, 102, 101, 110, 52, 0, 0, 11, 3, 233, 135, 152, 100, 105, 110, 103, 49, 0, 9, 3, 230, 158, 144, 120, 105, 49, 0, 9, 3, 231, 139, 184, 108, 105, 53, 0, 12, 3, 232, 131, 184, 120, 105, 111, 110, 103, 49, 0, 10, 3, 230, 156, 128, 122, 117, 105, 52, 0, 9, 3, 229, 153, 168, 113, 105, 52, 0, 10, 3, 229, 165, 136, 110, 97, 105, 52, 0, 0, 9, 3, 231, 137, 169, 119, 117, 52, 0, 10, 3, 232, 141, 137, 99, 97, 111, 51, 0, 11, 3, 230, 157, 137, 115, 104, 97, 110, 49, 0, 11, 3, 232, 140, 129, 122, 104, 117, 111, 50, 0, 9, 3, 231, 150, 145, 121, 105, 50, 0, 10, 3, 231, 139, 185, 120, 105, 97, 50, 0, 9, 3, 230, 145, 169, 109, 111, 50, 0, 11, 3, 229, 165, 137, 102, 101, 110, 103, 52, 0, 0, 11, 3, 230, 148, 190, 102, 97, 110, 103, 52, 0, 10, 3, 230, 157, 134, 103, 97, 110, 49, 0, 10, 3, 230, 144, 158, 103, 97, 111, 51, 0, 9, 3, 232, 132, 190, 112, 105, 50, 0, 10, 3, 231, 140, 190, 104, 117, 97, 50, 0, 9, 3, 229, 156, 190, 106, 105, 49, 0, 11, 3, 232, 131, 182, 106, 105, 97, 111, 49, 0, 10, 3, 231, 137, 166, 109, 97, 111, 50, 0, 0, 11, 3, 231, 140, 191, 121, 117, 97, 110, 50, 0, 9, 3, 229, 165, 135, 113, 105, 50, 0, 10, 3, 232, 130, 175, 107, 101, 110, 51, 0, 10, 3, 231, 150, 143, 115, 104, 117, 49, 0, 9, 3, 231, 137, 167, 109, 117, 52, 0, 12, 3, 230, 148, 191, 122, 104, 101, 110, 103, 52, 0, 10, 3, 231, 138, 175, 102, 97, 110, 52, 0, 10, 3, 230, 145, 167, 99, 117, 105, 49, 0, 0, 11, 3, 231, 138, 172, 113, 117, 97, 110, 51, 0, 10, 3, 230, 144, 156, 115, 111, 117, 49, 0, 10, 3, 230, 147, 180, 107, 117, 111, 52, 0, 10, 3, 229, 167, 148, 119, 101, 105, 51, 0, 10, 3, 229, 155, 180, 119, 101, 105, 50, 0, 10, 3, 230, 159, 148, 114, 111, 117, 50, 0, 0, 12, 3, 231, 149, 133, 99, 104, 97, 110, 103, 52, 0, 9, 3, 230, 146, 173, 98, 111, 49, 0, 10, 3, 231, 151, 149, 104, 101, 110, 50, 0, 0, 10, 3, 231, 150, 138, 100, 105, 101, 50, 0, 10, 3, 230, 147, 178, 122, 104, 105, 52, 0, 10, 3, 231, 137, 162, 108, 97, 111, 50, 0, 8, 3, 229, 153, 162, 111, 49, 0, 9, 3, 230, 157, 130, 122, 97, 50, 0, 11, 3, 232, 130, 170, 102, 97, 110, 103, 50, 0, 11, 3, 231, 151, 146, 121, 97, 110, 103, 51, 0, 12, 3, 229, 156, 186, 99, 104, 97, 110, 103, 51, 0, 13, 3, 232, 142, 138, 122, 104, 117, 97, 110, 103, 49, 0, 0, 10, 3, 231, 136, 155, 108, 97, 110, 52, 0, 9, 3, 229, 152, 155, 109, 97, 53, 0, 10, 3, 230, 159, 147, 114, 97, 110, 51, 0, 9, 3, 230, 146, 171, 102, 117, 51, 0, 11, 3, 230, 148, 187, 103, 111, 110, 103, 49, 0, 9, 3, 232, 131, 179, 103, 101, 49, 0, 11, 3, 229, 167, 147, 120, 105, 110, 103, 52, 0, 11, 3, 230, 157, 131, 113, 117, 97, 110, 50, 0, 9, 3, 233, 134, 139, 99, 117, 52, 0, 0, 10, 3, 230, 159, 144, 109, 111, 117, 51, 0, 9, 3, 229, 166, 136, 109, 97, 49, 0, 11, 3, 230, 147, 176, 110, 105, 110, 103, 50, 0, 10, 3, 229, 167, 144, 106, 105, 101, 53, 0, 11, 3, 229, 154, 168, 108, 111, 110, 103, 50, 0, 10, 3, 230, 157, 128, 115, 104, 97, 49, 0, 9, 3, 229, 152, 152, 120, 117, 49, 0, 11, 3, 232, 132, 184, 108, 105, 97, 110, 51, 0, 10, 3, 229, 155, 176, 107, 117, 110, 52, 0, 0, 9, 3, 231, 139, 177, 121, 117, 52, 0, 11, 3, 229, 155, 177, 99, 111, 110, 103, 49, 0, 11, 3, 232, 130, 169, 106, 105, 97, 110, 49, 0, 10, 3, 230, 148, 185, 103, 97, 105, 51, 0, 9, 3, 229, 167, 145, 103, 117, 49, 0, 11, 3, 230, 146, 169, 108, 105, 97, 111, 49, 0, 12, 3, 232, 132, 185, 122, 104, 97, 110, 103, 52, 0, 10, 3, 233, 135, 145, 106, 105, 110, 49, 0, 11, 3, 230, 158, 137, 119, 97, 110, 103, 53, 0, 10, 3, 233, 134, 137, 122, 117, 105, 52, 0, 9, 3, 230, 147, 177, 103, 101, 49, 0, 9, 3, 231, 137, 161, 109, 117, 51, 0, 0, 10, 3, 231, 140, 182, 121, 111, 117, 50, 0, 12, 3, 231, 150, 134, 106, 105, 97, 110, 103, 49, 0, 11, 3, 232, 133, 190, 116, 101, 110, 103, 50, 0, 11, 3, 230, 148, 182, 115, 104, 111, 117, 49, 0, 9, 3, 233, 135, 142, 121, 101, 51, 0, 10, 3, 232, 129, 158, 119, 101, 110, 50, 0, 10, 3, 230, 144, 150, 121, 97, 111, 50, 0, 10, 3, 231, 139, 174, 115, 104, 105, 49, 0, 0, 9, 3, 231, 138, 167, 120, 105, 49, 0, 10, 3, 232, 133, 191, 116, 117, 105, 51, 0, 12, 3, 229, 152, 151, 99, 104, 97, 110, 103, 50, 0, 10, 3, 230, 145, 159, 108, 111, 117, 51, 0, 12, 3, 233, 135, 143, 108, 105, 97, 110, 103, 52, 0, 10, 3, 230, 159, 143, 98, 97, 105, 51, 0, 10, 3, 232, 128, 151, 104, 97, 111, 52, 0, 9, 3, 229, 166, 135, 102, 117, 52, 0, 10, 3, 230, 144, 151, 100, 97, 111, 51, 0, 0, 9, 3, 232, 130, 164, 102, 117, 49, 0, 10, 3, 232, 143, 140, 106, 117, 110, 49, 0, 10, 3, 230, 158, 132, 103, 111, 117, 52, 0, 9, 3, 231, 139, 172, 100, 117, 50, 0, 10, 3, 231, 140, 180, 104, 111, 117, 50, 0, 10, 3, 230, 146, 164, 99, 104, 101, 52, 0, 10, 3, 230, 144, 148, 115, 97, 111, 49, 0, 9, 3, 233, 135, 140, 108, 105, 51, 0, 11, 3, 229, 166, 132, 119, 97, 110, 103, 52, 0, 9, 3, 230, 147, 172, 110, 105, 51, 0, 0, 12, 3, 233, 135, 141, 122, 104, 111, 110, 103, 52, 0, 10, 3, 231, 139, 173, 120, 105, 97, 50, 0, 11, 3, 229, 155, 173, 121, 117, 97, 110, 50, 0, 11, 3, 232, 128, 149, 103, 101, 110, 103, 49, 0, 9, 3, 230, 146, 165, 98, 111, 49, 0, 10, 3, 232, 130, 165, 102, 101, 105, 50, 0, 0, 11, 3, 229, 155, 170, 99, 111, 110, 103, 49, 0, 9, 3, 229, 167, 138, 122, 105, 51, 0, 10, 3, 232, 130, 162, 122, 104, 105, 49, 0, 10, 3, 233, 135, 138, 115, 104, 105, 52, 0, 9, 3, 232, 129, 154, 106, 117, 52, 0, 9, 3, 229, 166, 130, 114, 117, 50, 0, 9, 3, 232, 143, 138, 106, 117, 50, 0, 0, 11, 3, 231, 141, 187, 120, 105, 97, 110, 52, 0, 10, 3, 231, 137, 155, 110, 105, 117, 50, 0, 10, 3, 233, 135, 139, 115, 104, 105, 52, 0, 10, 3, 229, 167, 139, 115, 104, 105, 51, 0, 10, 3, 230, 144, 147, 99, 117, 111, 49, 0, 0, 11, 3, 230, 145, 152, 122, 104, 97, 105, 49, 0, 12, 3, 232, 133, 184, 99, 104, 97, 110, 103, 50, 0, 9, 3, 231, 136, 144, 108, 117, 50, 0, 10, 3, 230, 149, 184, 115, 104, 117, 52, 0, 9, 3, 229, 156, 176, 100, 101, 53, 0, 10, 3, 232, 128, 144, 110, 97, 105, 52, 0, 12, 3, 232, 130, 160, 99, 104, 97, 110, 103, 50, 0, 11, 3, 231, 141, 184, 115, 104, 111, 117, 52, 0, 0, 9, 3, 231, 137, 153, 121, 97, 50, 0, 9, 3, 232, 133, 185, 102, 117, 52, 0, 9, 3, 232, 130, 161, 103, 117, 51, 0, 10, 3, 232, 132, 177, 116, 117, 111, 49, 0, 9, 3, 230, 158, 129, 106, 105, 50, 0, 0, 12, 3, 232, 129, 150, 115, 104, 101, 110, 103, 52, 0, 9, 3, 229, 167, 134, 109, 117, 51, 0, 11, 3, 231, 140, 174, 120, 105, 97, 110, 52, 0, 13, 3, 230, 146, 158, 122, 104, 117, 97, 110, 103, 52, 0, 9, 3, 230, 147, 166, 99, 97, 49, 0, 0, 11, 3, 232, 131, 167, 108, 111, 110, 103, 50, 0, 9, 3, 232, 143, 135, 103, 117, 53, 0, 12, 3, 231, 151, 135, 122, 104, 101, 110, 103, 52, 0, 10, 3, 230, 148, 175, 122, 104, 105, 49, 0, 9, 3, 230, 144, 143, 98, 111, 50, 0, 9, 3, 230, 149, 183, 102, 117, 49, 0, 9, 3, 232, 132, 175, 112, 117, 50, 0, 10, 3, 233, 135, 135, 99, 97, 105, 51, 0, 0, 9, 3, 232, 128, 140, 101, 114, 50, 0, 12, 3, 230, 149, 180, 122, 104, 101, 110, 103, 51, 0, 12, 3, 230, 145, 148, 115, 104, 117, 97, 105, 49, 0, 11, 3, 232, 129, 148, 108, 105, 97, 110, 50, 0, 11, 3, 230, 159, 132, 98, 105, 110, 103, 51, 0, 10, 3, 231, 140, 172, 119, 101, 105, 53, 0, 0, 10, 3, 229, 152, 141, 108, 111, 117, 53, 0, 11, 3, 231, 136, 141, 115, 104, 117, 111, 52, 0, 10, 3, 232, 134, 189, 100, 97, 110, 51, 0, 9, 3, 230, 149, 181, 100, 105, 50, 0, 10, 3, 230, 150, 189, 115, 104, 105, 49, 0, 10, 3, 232, 130, 157, 103, 97, 110, 49, 0, 10, 3, 230, 144, 141, 115, 117, 110, 51, 0, 10, 3, 231, 141, 181, 108, 105, 101, 52, 0, 11, 3, 232, 128, 141, 115, 104, 117, 97, 51, 0, 11, 3, 231, 151, 133, 98, 105, 110, 103, 52, 0, 0, 10, 3, 231, 140, 170, 122, 104, 117, 49, 0, 10, 3, 231, 141, 178, 104, 117, 111, 52, 0, 11, 3, 229, 155, 162, 116, 117, 97, 110, 50, 0, 9, 3, 232, 130, 154, 100, 117, 52, 0, 11, 3, 230, 148, 170, 106, 105, 97, 111, 51, 0, 11, 3, 230, 149, 178, 113, 105, 97, 111, 49, 0, 0, 9, 3, 231, 142, 187, 98, 111, 49, 0, 10, 3, 231, 140, 171, 109, 97, 111, 49, 0, 11, 3, 232, 133, 179, 106, 105, 97, 111, 51, 0, 10, 3, 232, 132, 171, 116, 117, 111, 49, 0, 9, 3, 229, 153, 147, 120, 117, 49, 0, 10, 3, 231, 138, 155, 109, 97, 111, 50, 0, 0, 10, 3, 229, 156, 168, 122, 97, 105, 52, 0, 9, 3, 230, 147, 160, 106, 105, 51, 0, 10, 3, 232, 133, 176, 121, 97, 111, 49, 0, 10, 3, 229, 152, 136, 99, 97, 111, 50, 0, 10, 3, 230, 149, 176, 115, 104, 117, 52, 0, 12, 3, 233, 135, 128, 110, 105, 97, 110, 103, 52, 0, 10, 3, 231, 139, 160, 104, 101, 110, 51, 0, 10, 3, 229, 155, 160, 121, 105, 110, 49, 0, 0, 11, 3, 231, 139, 161, 106, 105, 97, 111, 51, 0, 9, 3, 232, 131, 161, 104, 117, 50, 0, 11, 3, 230, 150, 185, 102, 97, 110, 103, 49, 0, 11, 3, 231, 140, 169, 120, 105, 110, 103, 49, 0, 0, 10, 3, 229, 165, 174, 102, 101, 110, 52, 0, 10, 3, 230, 152, 134, 107, 117, 110, 49, 0, 11, 3, 229, 163, 158, 104, 117, 97, 105, 52, 0, 9, 3, 232, 136, 134, 121, 117, 50, 0, 11, 3, 230, 156, 166, 109, 101, 110, 103, 50, 0, 11, 3, 230, 154, 150, 110, 117, 97, 110, 51, 0, 9, 3, 231, 144, 134, 108, 105, 51, 0, 10, 3, 233, 129, 142, 103, 117, 111, 52, 0, 10, 3, 229, 160, 134, 100, 117, 105, 49, 0, 10, 3, 230, 158, 182, 106, 105, 97, 52, 0, 0, 10, 3, 232, 142, 183, 104, 117, 111, 52, 0, 9, 3, 229, 164, 167, 100, 97, 52, 0, 9, 3, 230, 154, 151, 97, 110, 52, 0, 9, 3, 229, 167, 191, 122, 105, 49, 0, 11, 3, 230, 156, 167, 108, 111, 110, 103, 50, 0, 10, 3, 232, 141, 175, 121, 97, 111, 52, 0, 11, 3, 229, 163, 159, 108, 111, 110, 103, 51, 0, 9, 3, 232, 136, 135, 121, 117, 51, 0, 10, 3, 230, 157, 175, 98, 101, 105, 49, 0, 11, 3, 232, 140, 167, 106, 105, 97, 110, 51, 0, 0, 9, 3, 229, 161, 140, 116, 97, 49, 0, 11, 3, 233, 133, 172, 99, 104, 111, 117, 53, 0, 10, 3, 231, 147, 156, 103, 117, 97, 49, 0, 12, 3, 230, 153, 140, 115, 104, 97, 110, 103, 51, 0, 0, 11, 3, 229, 160, 133, 106, 105, 97, 110, 49, 0, 11, 3, 233, 129, 141, 98, 105, 97, 110, 52, 0, 10, 3, 232, 136, 133, 106, 105, 117, 52, 0, 0, 11, 3, 229, 161, 138, 107, 117, 97, 105, 52, 0, 11, 3, 229, 164, 162, 109, 101, 110, 103, 52, 0, 11, 3, 231, 148, 162, 99, 104, 97, 110, 51, 0, 10, 3, 231, 149, 170, 102, 97, 110, 49, 0, 10, 3, 230, 152, 130, 97, 110, 103, 50, 0, 10, 3, 229, 165, 170, 100, 117, 111, 50, 0, 10, 3, 233, 128, 130, 115, 104, 105, 52, 0, 9, 3, 231, 150, 178, 112, 105, 50, 0, 11, 3, 232, 138, 146, 109, 97, 110, 103, 50, 0, 9, 3, 231, 151, 186, 98, 105, 52, 0, 11, 3, 229, 160, 130, 116, 97, 110, 103, 50, 0, 0, 10, 3, 233, 128, 131, 116, 97, 111, 50, 0, 10, 3, 231, 144, 131, 113, 105, 117, 50, 0, 10, 3, 229, 167, 187, 121, 105, 110, 49, 0, 10, 3, 231, 149, 171, 104, 117, 97, 52, 0, 9, 3, 229, 162, 147, 109, 117, 52, 0, 10, 3, 233, 129, 139, 121, 117, 110, 52, 0, 0, 10, 3, 229, 164, 160, 103, 111, 117, 52, 0, 10, 3, 232, 136, 128, 121, 97, 111, 51, 0, 10, 3, 233, 128, 128, 116, 117, 105, 52, 0, 11, 3, 230, 157, 168, 121, 97, 110, 103, 50, 0, 10, 3, 229, 163, 152, 108, 101, 105, 51, 0, 0, 11, 3, 233, 128, 129, 115, 111, 110, 103, 52, 0, 9, 3, 231, 151, 185, 98, 105, 52, 0, 10, 3, 230, 154, 145, 115, 104, 117, 51, 0, 0, 9, 3, 231, 136, 190, 101, 114, 51, 0, 0, 9, 3, 230, 156, 159, 113, 105, 49, 0, 11, 3, 232, 137, 135, 116, 105, 110, 103, 51, 0, 10, 3, 233, 130, 143, 108, 117, 111, 50, 0, 11, 3, 231, 150, 175, 102, 101, 110, 103, 49, 0, 12, 3, 231, 148, 159, 115, 104, 101, 110, 103, 49, 0, 9, 3, 233, 129, 135, 121, 117, 52, 0, 10, 3, 229, 164, 159, 103, 111, 117, 52, 0, 11, 3, 232, 139, 151, 109, 105, 97, 111, 50, 0, 10, 3, 229, 152, 191, 104, 101, 105, 49, 0, 9, 3, 230, 158, 175, 107, 117, 49, 0, 0, 9, 3, 229, 164, 156, 121, 101, 52, 0, 11, 3, 231, 148, 156, 116, 105, 97, 110, 50, 0, 12, 3, 233, 134, 172, 106, 105, 97, 110, 103, 52, 0, 11, 3, 230, 159, 180, 99, 104, 97, 105, 50, 0, 0, 10, 3, 231, 149, 165, 108, 118, 101, 52, 0, 13, 3, 231, 136, 189, 115, 104, 117, 97, 110, 103, 51, 0, 11, 3, 230, 156, 157, 99, 104, 97, 111, 50, 0, 10, 3, 230, 157, 165, 108, 97, 105, 50, 0, 10, 3, 229, 163, 149, 104, 97, 111, 50, 0, 10, 3, 232, 128, 189, 100, 97, 110, 49, 0, 0, 10, 3, 230, 144, 186, 120, 105, 101, 50, 0, 10, 3, 230, 153, 130, 115, 104, 105, 50, 0, 9, 3, 231, 136, 186, 121, 101, 53, 0, 12, 3, 230, 158, 170, 113, 105, 97, 110, 103, 49, 0, 10, 3, 229, 164, 154, 100, 117, 111, 49, 0, 11, 3, 233, 130, 138, 98, 105, 97, 110, 49, 0, 11, 3, 231, 148, 154, 115, 104, 101, 110, 50, 0, 11, 3, 229, 162, 138, 100, 105, 97, 110, 52, 0, 9, 3, 231, 149, 162, 98, 105, 52, 0, 0, 9, 3, 229, 152, 187, 120, 105, 49, 0, 11, 3, 230, 156, 155, 119, 97, 110, 103, 52, 0, 9, 3, 232, 142, 171, 109, 111, 52, 0, 10, 3, 230, 159, 179, 108, 105, 117, 51, 0, 11, 3, 232, 141, 163, 114, 111, 110, 103, 50, 0, 9, 3, 229, 163, 147, 121, 97, 49, 0, 12, 3, 230, 153, 131, 104, 117, 97, 110, 103, 53, 0, 9, 3, 231, 150, 171, 121, 105, 52, 0, 9, 3, 233, 134, 171, 121, 105, 49, 0, 10, 3, 232, 128, 187, 99, 104, 105, 51, 0, 0, 11, 3, 232, 128, 184, 115, 111, 110, 103, 51, 0, 11, 3, 229, 166, 168, 102, 97, 110, 103, 50, 0, 10, 3, 231, 148, 152, 103, 97, 110, 49, 0, 10, 3, 230, 154, 136, 121, 117, 110, 49, 0, 10, 3, 231, 151, 176, 116, 97, 110, 50, 0, 11, 3, 229, 165, 160, 100, 105, 97, 110, 52, 0, 9, 3, 231, 136, 184, 98, 97, 52, 0, 0, 10, 3, 230, 159, 177, 122, 104, 117, 52, 0, 9, 3, 233, 132, 153, 98, 105, 51, 0, 10, 3, 231, 136, 185, 100, 105, 101, 49, 0, 12, 3, 233, 131, 145, 122, 104, 101, 110, 103, 52, 0, 11, 3, 232, 141, 161, 100, 97, 110, 103, 52, 0, 11, 3, 230, 157, 161, 116, 105, 97, 111, 50, 0, 0, 12, 3, 230, 144, 182, 113, 105, 97, 110, 103, 51, 0, 9, 3, 231, 136, 182, 102, 117, 52, 0, 9, 3, 229, 152, 182, 115, 105, 49, 0, 10, 3, 229, 164, 150, 119, 97, 105, 52, 0, 0, 9, 3, 232, 139, 143, 115, 117, 49, 0, 10, 3, 230, 157, 159, 115, 104, 117, 52, 0, 9, 3, 231, 136, 183, 121, 101, 53, 0, 11, 3, 230, 156, 151, 108, 97, 110, 103, 51, 0, 9, 3, 232, 128, 183, 100, 97, 49, 0, 11, 3, 231, 147, 143, 108, 111, 110, 103, 50, 0, 10, 3, 232, 143, 175, 104, 117, 97, 50, 0, 0, 10, 3, 231, 149, 156, 99, 104, 117, 52, 0, 10, 3, 233, 130, 132, 104, 97, 105, 50, 0, 10, 3, 229, 152, 180, 122, 117, 105, 51, 0, 9, 3, 230, 157, 156, 100, 117, 52, 0, 11, 3, 230, 154, 132, 120, 117, 97, 110, 49, 0, 0, 11, 3, 232, 129, 189, 116, 105, 110, 103, 49, 0, 9, 3, 229, 164, 149, 120, 105, 49, 0, 9, 3, 231, 149, 157, 109, 117, 51, 0, 11, 3, 232, 139, 141, 99, 97, 110, 103, 49, 0, 10, 3, 229, 166, 165, 116, 117, 111, 51, 0, 11, 3, 231, 137, 189, 113, 105, 97, 110, 49, 0, 0, 11, 3, 229, 152, 178, 99, 104, 97, 111, 50, 0, 10, 3, 230, 158, 162, 115, 104, 117, 49, 0, 11, 3, 233, 131, 138, 106, 105, 97, 111, 49, 0, 9, 3, 231, 137, 186, 120, 105, 49, 0, 10, 3, 232, 138, 130, 106, 105, 101, 50, 0, 10, 3, 230, 154, 130, 122, 97, 110, 52, 0, 0, 9, 3, 232, 128, 179, 101, 114, 51, 0, 10, 3, 230, 158, 163, 122, 97, 111, 51, 0, 11, 3, 229, 162, 131, 106, 105, 110, 103, 52, 0, 9, 3, 231, 146, 131, 108, 105, 50, 0, 0, 9, 3, 230, 145, 184, 109, 111, 49, 0, 9, 3, 229, 167, 168, 121, 105, 50, 0, 10, 3, 229, 153, 184, 100, 117, 110, 49, 0, 10, 3, 233, 130, 128, 121, 97, 111, 49, 0, 0, 9, 3, 231, 137, 185, 116, 101, 52, 0, 9, 3, 232, 143, 169, 112, 117, 50, 0, 10, 3, 233, 130, 129, 109, 97, 105, 52, 0, 10, 3, 231, 149, 153, 108, 105, 117, 50, 0, 10, 3, 229, 152, 177, 122, 104, 117, 51, 0, 11, 3, 230, 155, 137, 120, 105, 97, 111, 51, 0, 9, 3, 231, 136, 177, 97, 105, 52, 0, 0, 11, 3, 232, 140, 142, 106, 105, 110, 103, 49, 0, 12, 3, 229, 165, 150, 106, 105, 97, 110, 103, 51, 0, 0, 10, 3, 229, 165, 151, 116, 97, 111, 52, 0, 11, 3, 230, 146, 191, 106, 105, 97, 110, 51, 0, 12, 3, 232, 130, 191, 122, 104, 111, 110, 103, 51, 0, 10, 3, 232, 139, 135, 119, 101, 105, 51, 0, 11, 3, 229, 152, 175, 120, 105, 97, 111, 52, 0, 10, 3, 229, 164, 143, 120, 105, 97, 52, 0, 10, 3, 232, 129, 183, 122, 104, 105, 50, 0, 0, 9, 3, 232, 141, 148, 108, 105, 52, 0, 10, 3, 229, 154, 188, 106, 117, 101, 50, 0, 10, 3, 230, 144, 172, 98, 97, 110, 49, 0, 10, 3, 230, 146, 188, 104, 97, 110, 52, 0, 9, 3, 231, 136, 172, 112, 97, 50, 0, 10, 3, 230, 158, 156, 103, 117, 111, 51, 0, 10, 3, 229, 153, 180, 112, 101, 110, 49, 0, 10, 3, 229, 165, 148, 98, 101, 110, 49, 0, 10, 3, 231, 149, 148, 112, 97, 110, 52, 0, 0, 12, 3, 231, 136, 173, 122, 104, 101, 110, 103, 49, 0, 9, 3, 230, 156, 141, 102, 117, 50, 0, 11, 3, 231, 137, 181, 113, 105, 97, 110, 49, 0, 10, 3, 230, 159, 165, 99, 104, 97, 50, 0, 9, 3, 230, 144, 173, 100, 97, 49, 0, 10, 3, 230, 158, 157, 122, 104, 105, 49, 0, 9, 3, 229, 164, 141, 102, 117, 52, 0, 0, 12, 3, 232, 141, 146, 104, 117, 97, 110, 103, 49, 0, 12, 3, 231, 137, 178, 115, 104, 101, 110, 103, 49, 0, 11, 3, 230, 144, 170, 116, 97, 110, 103, 50, 0, 10, 3, 232, 130, 186, 102, 101, 105, 52, 0, 10, 3, 230, 158, 154, 109, 101, 105, 50, 0, 10, 3, 233, 133, 146, 106, 105, 117, 51, 0, 12, 3, 232, 129, 178, 115, 104, 101, 110, 103, 49, 0, 11, 3, 231, 136, 170, 122, 104, 97, 111, 51, 0, 0, 11, 3, 233, 135, 163, 100, 105, 97, 111, 52, 0, 11, 3, 230, 156, 139, 112, 101, 110, 103, 50, 0, 11, 3, 232, 129, 179, 115, 111, 110, 103, 51, 0, 0, 10, 3, 230, 156, 136, 121, 117, 101, 52, 0, 10, 3, 230, 157, 144, 99, 97, 105, 50, 0, 11, 3, 232, 141, 144, 106, 105, 97, 110, 52, 0, 11, 3, 232, 129, 176, 99, 111, 110, 103, 49, 0, 0, 12, 3, 233, 132, 137, 120, 105, 97, 110, 103, 49, 0, 10, 3, 229, 152, 169, 104, 117, 97, 49, 0, 9, 3, 231, 150, 153, 103, 101, 49, 0, 11, 3, 229, 166, 153, 109, 105, 97, 111, 52, 0, 9, 3, 233, 131, 129, 121, 117, 52, 0, 10, 3, 230, 156, 137, 121, 111, 117, 51, 0, 10, 3, 230, 157, 145, 99, 117, 110, 49, 0, 10, 3, 231, 138, 185, 121, 111, 117, 50, 0, 9, 3, 229, 163, 129, 98, 105, 52, 0, 0, 10, 3, 230, 152, 167, 109, 101, 105, 52, 0, 9, 3, 230, 155, 191, 116, 105, 52, 0, 11, 3, 229, 174, 151, 122, 111, 110, 103, 49, 0, 10, 3, 229, 175, 159, 99, 104, 97, 50, 0, 11, 3, 230, 153, 175, 106, 105, 110, 103, 51, 0, 11, 3, 233, 143, 159, 99, 104, 97, 110, 51, 0, 12, 3, 232, 137, 175, 108, 105, 97, 110, 103, 50, 0, 0, 9, 3, 229, 175, 158, 109, 111, 52, 0, 9, 3, 230, 153, 174, 112, 117, 51, 0, 10, 3, 233, 129, 174, 122, 104, 101, 49, 0, 10, 3, 233, 142, 150, 115, 117, 111, 51, 0, 11, 3, 230, 155, 190, 99, 101, 110, 103, 50, 0, 0, 9, 3, 232, 151, 157, 121, 105, 52, 0, 10, 3, 233, 129, 173, 122, 97, 111, 49, 0, 11, 3, 230, 166, 149, 114, 111, 110, 103, 50, 0, 9, 3, 230, 164, 133, 121, 105, 51, 0, 9, 3, 233, 141, 141, 100, 117, 52, 0, 11, 3, 230, 152, 165, 99, 104, 117, 110, 49, 0, 10, 3, 233, 131, 189, 100, 111, 117, 49, 0, 11, 3, 229, 163, 189, 115, 104, 111, 117, 52, 0, 0, 9, 3, 233, 140, 132, 108, 117, 52, 0, 9, 3, 229, 160, 164, 100, 105, 49, 0, 10, 3, 230, 154, 180, 98, 97, 111, 52, 0, 0, 10, 3, 233, 141, 139, 103, 117, 111, 49, 0, 11, 3, 229, 161, 171, 116, 105, 97, 110, 50, 0, 10, 3, 230, 167, 155, 107, 97, 110, 51, 0, 11, 3, 233, 128, 163, 108, 105, 97, 110, 50, 0, 10, 3, 231, 159, 155, 109, 97, 111, 50, 0, 10, 3, 229, 162, 179, 102, 101, 110, 50, 0, 0, 10, 3, 231, 158, 146, 109, 97, 110, 50, 0, 11, 3, 230, 165, 138, 121, 97, 110, 103, 50, 0, 9, 3, 229, 163, 186, 104, 117, 50, 0, 11, 3, 233, 128, 162, 102, 101, 110, 103, 50, 0, 10, 3, 231, 144, 162, 122, 117, 111, 50, 0, 0, 12, 3, 231, 156, 129, 115, 104, 101, 110, 103, 51, 0, 10, 3, 232, 138, 177, 104, 117, 97, 49, 0, 10, 3, 229, 160, 161, 98, 97, 111, 51, 0, 11, 3, 231, 145, 169, 121, 105, 110, 103, 50, 0, 11, 3, 232, 149, 137, 106, 105, 97, 111, 49, 0, 10, 3, 233, 129, 169, 115, 104, 105, 52, 0, 11, 3, 232, 139, 185, 112, 105, 110, 103, 50, 0, 0, 11, 3, 231, 146, 176, 104, 117, 97, 110, 50, 0, 11, 3, 230, 152, 160, 121, 105, 110, 103, 52, 0, 10, 3, 230, 155, 184, 115, 104, 117, 49, 0, 11, 3, 230, 153, 168, 99, 104, 101, 110, 53, 0, 10, 3, 233, 128, 160, 122, 97, 111, 52, 0, 0, 10, 3, 231, 159, 151, 99, 104, 117, 52, 0, 9, 3, 233, 128, 159, 115, 117, 52, 0, 9, 3, 231, 147, 183, 99, 105, 50, 0, 11, 3, 232, 136, 159, 122, 104, 111, 117, 49, 0, 11, 3, 229, 174, 143, 104, 111, 110, 103, 50, 0, 11, 3, 230, 152, 159, 120, 105, 110, 103, 49, 0, 10, 3, 232, 138, 175, 120, 105, 110, 49, 0, 0, 10, 3, 229, 164, 190, 106, 105, 97, 49, 0, 10, 3, 231, 158, 142, 120, 105, 97, 49, 0, 11, 3, 232, 137, 166, 106, 105, 97, 110, 52, 0, 9, 3, 232, 136, 158, 119, 117, 51, 0, 9, 3, 229, 163, 182, 104, 117, 50, 0, 10, 3, 233, 130, 174, 121, 111, 117, 50, 0, 11, 3, 231, 147, 182, 112, 105, 110, 103, 50, 0, 0, 10, 3, 233, 131, 181, 121, 111, 117, 50, 0, 10, 3, 230, 156, 189, 120, 105, 117, 51, 0, 10, 3, 233, 129, 165, 121, 97, 111, 50, 0, 10, 3, 233, 128, 157, 115, 104, 105, 52, 0, 0, 9, 3, 231, 158, 140, 107, 101, 49, 0, 10, 3, 229, 174, 140, 119, 97, 110, 50, 0, 11, 3, 230, 155, 180, 103, 101, 110, 103, 52, 0, 0, 10, 3, 231, 145, 163, 115, 117, 111, 51, 0, 11, 3, 233, 129, 163, 113, 105, 97, 110, 51, 0, 9, 3, 229, 175, 147, 121, 117, 52, 0, 9, 3, 229, 163, 179, 107, 101, 50, 0, 10, 3, 231, 148, 187, 104, 117, 97, 52, 0, 12, 3, 233, 128, 155, 103, 117, 97, 110, 103, 52, 0, 10, 3, 230, 154, 171, 122, 97, 110, 52, 0, 0, 11, 3, 233, 128, 154, 116, 111, 110, 103, 49, 0, 10, 3, 229, 175, 146, 104, 97, 110, 50, 0, 10, 3, 229, 164, 186, 100, 117, 111, 50, 0, 9, 3, 230, 155, 178, 113, 117, 49, 0, 9, 3, 230, 156, 186, 106, 105, 49, 0, 0, 10, 3, 229, 164, 185, 106, 105, 97, 49, 0, 10, 3, 229, 162, 169, 100, 117, 110, 49, 0, 9, 3, 229, 174, 137, 97, 110, 49, 0, 11, 3, 232, 139, 177, 121, 105, 110, 103, 49, 0, 10, 3, 233, 128, 153, 122, 104, 101, 52, 0, 12, 3, 231, 157, 129, 122, 104, 101, 110, 103, 49, 0, 0, 9, 3, 229, 162, 168, 109, 111, 52, 0, 11, 3, 232, 140, 184, 114, 111, 110, 103, 49, 0, 12, 3, 229, 163, 176, 115, 104, 101, 110, 103, 49, 0, 11, 3, 230, 167, 144, 104, 117, 97, 105, 50, 0, 11, 3, 231, 148, 184, 100, 105, 97, 110, 52, 0, 10, 3, 231, 157, 128, 122, 104, 101, 53, 0, 10, 3, 229, 164, 184, 107, 117, 97, 49, 0, 11, 3, 229, 174, 136, 115, 104, 111, 117, 51, 0, 10, 3, 230, 155, 176, 121, 117, 101, 49, 0, 11, 3, 233, 129, 160, 121, 117, 97, 110, 51, 0, 0, 10, 3, 231, 148, 183, 110, 97, 110, 50, 0, 12, 3, 233, 133, 191, 110, 105, 97, 110, 103, 52, 0, 9, 3, 229, 174, 135, 121, 117, 51, 0, 9, 3, 231, 158, 135, 109, 105, 49, 0, 11, 3, 232, 151, 143, 99, 97, 110, 103, 50, 0, 10, 3, 233, 128, 151, 100, 111, 117, 52, 0, 10, 3, 230, 157, 191, 98, 97, 110, 51, 0, 13, 3, 229, 163, 175, 122, 104, 117, 97, 110, 103, 52, 0, 0, 13, 3, 229, 163, 174, 122, 104, 117, 97, 110, 103, 52, 0, 11, 3, 233, 130, 166, 98, 97, 110, 103, 49, 0, 10, 3, 232, 140, 182, 99, 104, 97, 50, 0, 9, 3, 233, 129, 158, 100, 105, 52, 0, 11, 3, 230, 157, 190, 115, 111, 110, 103, 49, 0, 9, 3, 232, 138, 166, 108, 117, 50, 0, 10, 3, 229, 161, 158, 115, 97, 105, 49, 0, 0, 10, 3, 232, 151, 141, 108, 97, 110, 50, 0, 12, 3, 230, 167, 141, 113, 105, 97, 110, 103, 49, 0, 11, 3, 231, 148, 181, 100, 105, 97, 110, 52, 0, 11, 3, 229, 174, 133, 122, 104, 97, 105, 50, 0, 11, 3, 231, 158, 133, 99, 104, 111, 117, 51, 0, 10, 3, 229, 165, 189, 104, 97, 111, 51, 0, 11, 3, 230, 153, 157, 122, 104, 111, 117, 52, 0, 10, 3, 230, 156, 181, 100, 117, 111, 53, 0, 0, 11, 3, 231, 158, 132, 109, 105, 97, 111, 50, 0, 9, 3, 229, 175, 140, 102, 117, 52, 0, 9, 3, 230, 156, 180, 112, 117, 51, 0, 11, 3, 232, 136, 148, 116, 105, 97, 110, 51, 0, 10, 3, 233, 129, 156, 120, 117, 110, 52, 0, 10, 3, 232, 150, 132, 98, 97, 111, 50, 0, 10, 3, 229, 164, 180, 116, 111, 117, 50, 0, 9, 3, 233, 128, 148, 116, 117, 50, 0, 0, 10, 3, 229, 163, 171, 115, 104, 105, 52, 0, 10, 3, 230, 167, 139, 103, 111, 117, 52, 0, 11, 3, 231, 148, 179, 115, 104, 101, 110, 49, 0, 9, 3, 229, 174, 131, 116, 97, 49, 0, 9, 3, 233, 130, 163, 110, 97, 52, 0, 9, 3, 230, 152, 147, 121, 105, 52, 0, 0, 10, 3, 232, 136, 146, 115, 104, 117, 49, 0, 9, 3, 231, 145, 154, 104, 117, 50, 0, 10, 3, 233, 142, 130, 109, 101, 105, 51, 0, 10, 3, 230, 166, 130, 103, 97, 105, 52, 0, 9, 3, 233, 128, 146, 100, 105, 52, 0, 10, 3, 230, 153, 154, 119, 97, 110, 51, 0, 10, 3, 231, 148, 178, 106, 105, 97, 51, 0, 12, 3, 230, 154, 162, 99, 104, 97, 110, 103, 52, 0, 0, 11, 3, 232, 137, 153, 99, 97, 110, 103, 49, 0, 9, 3, 229, 163, 169, 98, 97, 52, 0, 10, 3, 229, 164, 177, 115, 104, 105, 49, 0, 10, 3, 231, 148, 177, 121, 111, 117, 50, 0, 11, 3, 229, 174, 129, 110, 105, 110, 103, 50, 0, 10, 3, 233, 129, 153, 121, 97, 111, 50, 0, 9, 3, 229, 165, 185, 116, 97, 49, 0, 0, 11, 3, 229, 161, 152, 116, 97, 110, 103, 50, 0, 11, 3, 231, 148, 176, 116, 105, 97, 110, 50, 0, 11, 3, 233, 133, 184, 115, 117, 97, 110, 49, 0, 11, 3, 229, 165, 184, 106, 105, 97, 110, 49, 0, 10, 3, 233, 132, 176, 108, 105, 110, 50, 0, 9, 3, 233, 131, 168, 98, 117, 52, 0, 10, 3, 233, 128, 144, 122, 104, 117, 50, 0, 10, 3, 231, 144, 144, 115, 117, 111, 51, 0, 11, 3, 233, 143, 136, 108, 105, 97, 110, 52, 0, 10, 3, 232, 137, 152, 115, 111, 117, 49, 0, 0, 10, 3, 229, 175, 135, 107, 111, 117, 52, 0, 10, 3, 230, 156, 175, 115, 104, 117, 52, 0, 9, 3, 232, 141, 183, 104, 101, 50, 0, 10, 3, 230, 152, 143, 104, 117, 110, 49, 0, 9, 3, 233, 129, 151, 121, 105, 50, 0, 9, 3, 233, 133, 183, 107, 117, 52, 0, 10, 3, 233, 128, 143, 116, 111, 117, 52, 0, 0, 11, 3, 229, 164, 174, 121, 97, 110, 103, 49, 0, 9, 3, 232, 139, 166, 107, 117, 51, 0, 11, 3, 229, 162, 158, 122, 101, 110, 103, 49, 0, 10, 3, 230, 156, 174, 115, 104, 117, 52, 0, 11, 3, 230, 152, 142, 109, 105, 110, 103, 50, 0, 10, 3, 229, 165, 182, 110, 97, 105, 51, 0, 11, 3, 231, 149, 182, 100, 97, 110, 103, 49, 0, 9, 3, 231, 147, 166, 119, 97, 51, 0, 10, 3, 233, 133, 182, 109, 101, 105, 50, 0, 9, 3, 229, 175, 134, 109, 105, 52, 0, 9, 3, 231, 150, 190, 106, 105, 50, 0, 0, 10, 3, 230, 153, 149, 121, 117, 110, 49, 0, 10, 3, 232, 139, 165, 114, 117, 111, 52, 0, 11, 3, 233, 133, 181, 106, 105, 97, 111, 52, 0, 10, 3, 232, 136, 141, 115, 104, 101, 51, 0, 12, 3, 233, 132, 173, 122, 104, 101, 110, 103, 52, 0, 10, 3, 233, 129, 149, 119, 101, 105, 50, 0, 11, 3, 231, 148, 173, 98, 101, 110, 103, 50, 0, 10, 3, 232, 138, 157, 122, 104, 105, 49, 0, 0, 11, 3, 229, 163, 164, 114, 97, 110, 103, 51, 0, 9, 3, 229, 165, 180, 110, 117, 50, 0, 9, 3, 229, 161, 148, 116, 97, 51, 0, 9, 3, 229, 175, 132, 106, 105, 52, 0, 11, 3, 231, 150, 188, 116, 101, 110, 103, 50, 0, 9, 3, 233, 129, 148, 100, 97, 50, 0, 11, 3, 229, 162, 156, 122, 104, 117, 105, 52, 0, 10, 3, 230, 156, 172, 98, 101, 110, 51, 0, 10, 3, 232, 136, 140, 115, 104, 101, 50, 0, 0, 10, 3, 232, 136, 139, 120, 105, 110, 52, 0, 9, 3, 229, 165, 179, 110, 118, 51, 0, 11, 3, 232, 140, 171, 109, 97, 110, 103, 50, 0, 10, 3, 233, 129, 147, 100, 97, 111, 52, 0, 9, 3, 230, 156, 171, 109, 111, 52, 0, 10, 3, 231, 147, 163, 98, 97, 110, 52, 0, 11, 3, 230, 153, 147, 120, 105, 97, 111, 51, 0, 9, 3, 229, 166, 187, 113, 105, 49, 0, 9, 3, 229, 164, 171, 102, 117, 53, 0, 9, 3, 231, 148, 171, 102, 117, 53, 0, 0, 11, 3, 231, 147, 162, 112, 105, 97, 111, 50, 0, 10, 3, 233, 128, 138, 120, 117, 110, 52, 0, 11, 3, 230, 153, 146, 115, 104, 97, 105, 52, 0, 9, 3, 229, 175, 130, 106, 105, 52, 0, 10, 3, 230, 156, 170, 119, 101, 105, 52, 0, 10, 3, 232, 136, 138, 106, 105, 117, 52, 0, 10, 3, 229, 164, 170, 116, 97, 105, 52, 0, 0, 12, 3, 233, 133, 177, 106, 105, 97, 110, 103, 52, 0, 9, 3, 229, 161, 145, 115, 117, 52, 0, 9, 3, 232, 136, 137, 106, 117, 51, 0, 12, 3, 231, 148, 169, 115, 104, 117, 97, 105, 51, 0, 11, 3, 229, 164, 169, 116, 105, 97, 110, 49, 0, 12, 3, 229, 162, 153, 113, 105, 97, 110, 103, 50, 0, 11, 3, 232, 142, 185, 121, 105, 110, 103, 50, 0, 10, 3, 229, 166, 185, 109, 101, 105, 52, 0, 11, 3, 233, 128, 137, 120, 117, 97, 110, 51, 0, 11, 3, 230, 157, 177, 100, 111, 110, 103, 49, 0, 0, 9, 3, 230, 156, 168, 109, 117, 52, 0, 10, 3, 230, 157, 176, 106, 105, 101, 50, 0, 11, 3, 231, 148, 168, 121, 111, 110, 103, 52, 0, 11, 3, 232, 136, 136, 120, 105, 110, 103, 52, 0, 9, 3, 231, 149, 176, 121, 105, 52, 0, 12, 3, 230, 155, 160, 107, 117, 97, 110, 103, 52, 0, 0, 11, 3, 230, 160, 135, 98, 105, 97, 111, 49, 0, 11, 3, 231, 155, 159, 109, 101, 110, 103, 50, 0, 11, 3, 229, 168, 135, 106, 105, 97, 111, 49, 0, 11, 3, 230, 162, 151, 103, 101, 110, 103, 51, 0, 12, 3, 231, 159, 191, 107, 117, 97, 110, 103, 52, 0, 11, 3, 229, 175, 191, 115, 104, 111, 117, 52, 0, 0, 10, 3, 233, 140, 166, 106, 105, 110, 51, 0, 11, 3, 231, 155, 158, 122, 104, 97, 110, 51, 0, 10, 3, 229, 174, 182, 106, 105, 97, 49, 0, 0, 10, 3, 230, 167, 189, 99, 97, 111, 50, 0, 11, 3, 232, 148, 165, 99, 111, 110, 103, 49, 0, 11, 3, 229, 174, 181, 120, 105, 97, 111, 49, 0, 10, 3, 232, 147, 157, 108, 97, 110, 50, 0, 9, 3, 230, 165, 173, 121, 101, 52, 0, 10, 3, 233, 143, 189, 120, 105, 117, 52, 0, 0, 10, 3, 231, 155, 156, 100, 97, 111, 52, 0, 11, 3, 230, 161, 140, 122, 104, 117, 111, 49, 0, 10, 3, 230, 166, 180, 108, 105, 117, 50, 0, 10, 3, 229, 175, 188, 100, 97, 111, 51, 0, 9, 3, 231, 153, 140, 97, 105, 50, 0, 10, 3, 229, 174, 180, 121, 97, 110, 52, 0, 11, 3, 233, 141, 172, 113, 105, 97, 111, 49, 0, 10, 3, 232, 144, 132, 116, 97, 111, 50, 0, 0, 10, 3, 231, 157, 171, 106, 105, 101, 50, 0, 10, 3, 229, 173, 171, 115, 117, 110, 49, 0, 12, 3, 231, 155, 155, 115, 104, 101, 110, 103, 52, 0, 10, 3, 229, 174, 179, 104, 97, 105, 52, 0, 9, 3, 229, 168, 131, 119, 97, 50, 0, 10, 3, 229, 175, 187, 120, 117, 110, 50, 0, 0, 11, 3, 230, 163, 154, 112, 101, 110, 103, 50, 0, 11, 3, 233, 140, 162, 113, 105, 97, 110, 50, 0, 0, 9, 3, 232, 151, 185, 97, 105, 51, 0, 10, 3, 229, 173, 169, 104, 97, 105, 50, 0, 11, 3, 232, 149, 169, 100, 97, 110, 103, 52, 0, 10, 3, 229, 168, 129, 119, 101, 105, 49, 0, 10, 3, 229, 175, 185, 100, 117, 105, 52, 0, 9, 3, 232, 145, 137, 121, 101, 52, 0, 0, 10, 3, 229, 174, 176, 122, 97, 105, 51, 0, 10, 3, 231, 155, 152, 112, 97, 110, 50, 0, 9, 3, 230, 161, 136, 97, 110, 52, 0, 11, 3, 231, 156, 160, 109, 105, 97, 110, 50, 0, 10, 3, 229, 175, 184, 99, 117, 110, 52, 0, 11, 3, 233, 140, 160, 100, 105, 110, 103, 52, 0, 10, 2, 95, 51, 89, 35, 50, 117, 0, 29, 0, 11, 3, 231, 156, 159, 122, 104, 101, 110, 49, 0, 10, 3, 232, 150, 175, 115, 104, 117, 51, 0, 10, 3, 230, 163, 151, 122, 97, 111, 51, 0, 10, 3, 231, 155, 151, 100, 97, 111, 52, 0, 8, 2, 95, 50, 129, 115, 0, 29, 0, 11, 3, 233, 142, 174, 122, 104, 101, 110, 52, 0, 10, 3, 229, 173, 166, 120, 117, 101, 50, 0, 11, 3, 230, 152, 190, 120, 105, 97, 110, 51, 0, 10, 3, 231, 155, 150, 103, 97, 105, 52, 0, 12, 3, 230, 161, 134, 107, 117, 97, 110, 103, 49, 0, 11, 3, 229, 174, 174, 103, 111, 110, 103, 49, 0, 10, 3, 229, 175, 182, 98, 97, 111, 51, 0, 9, 3, 229, 169, 134, 112, 111, 50, 0, 11, 3, 230, 166, 174, 114, 111, 110, 103, 50, 0, 9, 2, 95, 49, 57, 37, 117, 0, 29, 0, 10, 3, 230, 161, 133, 119, 101, 105, 50, 0, 11, 3, 231, 158, 173, 108, 105, 97, 111, 51, 0, 10, 2, 95, 48, 55, 37, 68, 113, 0, 29, 0, 9, 3, 229, 173, 164, 103, 117, 49, 0, 9, 3, 233, 128, 188, 98, 105, 49, 0, 10, 3, 231, 155, 148, 107, 117, 105, 49, 0, 11, 3, 230, 152, 188, 122, 104, 111, 117, 52, 0, 9, 2, 95, 55, 121, 37, 117, 0, 29, 0, 11, 3, 229, 174, 171, 103, 111, 110, 103, 49, 0, 10, 3, 230, 161, 131, 116, 97, 111, 50, 0, 10, 3, 231, 159, 179, 115, 104, 105, 50, 0, 9, 3, 229, 173, 163, 106, 105, 52, 0, 10, 3, 233, 128, 187, 108, 117, 111, 50, 0, 12, 3, 230, 167, 179, 106, 105, 97, 110, 103, 51, 0, 9, 3, 231, 157, 163, 100, 117, 49, 0, 9, 2, 95, 54, 55, 138, 115, 0, 29, 0, 11, 3, 231, 153, 130, 108, 105, 97, 111, 50, 0, 10, 3, 232, 150, 170, 120, 105, 110, 49, 0, 11, 3, 230, 163, 146, 98, 97, 110, 103, 52, 0, 11, 3, 233, 139, 146, 102, 101, 110, 103, 49, 0, 11, 3, 229, 174, 170, 120, 105, 97, 110, 52, 0, 11, 3, 231, 158, 170, 100, 101, 110, 103, 52, 0, 9, 3, 231, 155, 146, 104, 101, 50, 0, 9, 2, 95, 53, 58, 40, 110, 0, 29, 0, 12, 3, 232, 136, 185, 99, 104, 117, 97, 110, 50, 0, 11, 3, 231, 155, 145, 106, 105, 97, 110, 49, 0, 11, 3, 231, 157, 161, 115, 104, 117, 105, 52, 0, 9, 3, 232, 150, 169, 115, 97, 52, 0, 9, 2, 95, 52, 89, 132, 115, 0, 29, 0, 11, 3, 233, 140, 152, 99, 104, 117, 105, 50, 0, 10, 3, 231, 155, 144, 121, 97, 110, 50, 0, 0, 12, 3, 231, 154, 135, 104, 117, 97, 110, 103, 50, 0, 11, 3, 231, 155, 143, 122, 104, 97, 110, 51, 0, 11, 3, 231, 158, 167, 113, 105, 97, 111, 50, 0, 9, 3, 233, 129, 191, 98, 105, 52, 0, 10, 3, 232, 148, 151, 122, 104, 101, 53, 0, 0, 11, 3, 230, 162, 134, 98, 97, 110, 103, 49, 0, 9, 3, 231, 159, 174, 97, 105, 51, 0, 12, 3, 230, 153, 190, 108, 105, 97, 110, 103, 52, 0, 10, 3, 231, 154, 134, 106, 105, 101, 49, 0, 9, 3, 232, 136, 182, 98, 111, 50, 0, 9, 2, 95, 57, 97, 138, 110, 0, 29, 0, 11, 3, 233, 138, 133, 116, 111, 110, 103, 50, 0, 10, 3, 230, 163, 141, 103, 117, 110, 52, 0, 9, 3, 229, 160, 181, 100, 117, 51, 0, 10, 3, 231, 158, 165, 112, 105, 101, 49, 0, 11, 3, 231, 159, 173, 100, 117, 97, 110, 51, 0, 10, 3, 230, 162, 133, 109, 101, 105, 50, 0, 9, 2, 95, 56, 48, 126, 117, 0, 29, 0, 11, 3, 229, 171, 140, 120, 105, 97, 110, 50, 0, 10, 3, 229, 174, 164, 115, 104, 105, 52, 0, 11, 3, 229, 175, 172, 107, 117, 97, 110, 49, 0, 12, 3, 231, 157, 156, 122, 104, 101, 110, 103, 49, 0, 10, 3, 231, 144, 180, 113, 105, 110, 50, 0, 11, 3, 233, 129, 188, 108, 105, 97, 111, 50, 0, 12, 3, 229, 160, 180, 99, 104, 97, 110, 103, 51, 0, 9, 3, 231, 154, 132, 100, 101, 53, 0, 0, 11, 3, 233, 141, 155, 100, 117, 97, 110, 52, 0, 9, 3, 230, 163, 139, 113, 105, 50, 0, 11, 3, 231, 157, 155, 106, 105, 110, 103, 53, 0, 10, 3, 232, 147, 139, 103, 97, 105, 52, 0, 11, 3, 229, 174, 163, 120, 117, 97, 110, 49, 0, 10, 3, 229, 175, 171, 120, 105, 101, 51, 0, 0, 9, 3, 229, 174, 162, 107, 101, 52, 0, 11, 3, 230, 164, 146, 106, 105, 97, 111, 49, 0, 9, 3, 233, 129, 186, 121, 105, 50, 0, 10, 3, 230, 165, 154, 99, 104, 117, 53, 0, 9, 3, 231, 155, 138, 121, 105, 52, 0, 10, 3, 230, 153, 186, 122, 104, 105, 52, 0, 10, 3, 231, 154, 130, 122, 97, 111, 52, 0, 9, 3, 232, 137, 186, 121, 105, 52, 0, 10, 3, 233, 128, 178, 106, 105, 110, 52, 0, 0, 11, 3, 229, 175, 169, 115, 104, 101, 110, 51, 0, 9, 3, 231, 159, 169, 106, 117, 53, 0, 12, 3, 230, 162, 129, 108, 105, 97, 110, 103, 50, 0, 10, 3, 229, 173, 153, 115, 117, 110, 49, 0, 10, 3, 229, 160, 177, 98, 97, 111, 52, 0, 11, 3, 230, 163, 137, 109, 105, 97, 110, 50, 0, 11, 3, 232, 136, 177, 99, 97, 110, 103, 49, 0, 11, 3, 229, 174, 161, 115, 104, 101, 110, 51, 0, 10, 3, 232, 148, 145, 109, 105, 101, 52, 0, 0, 11, 3, 232, 136, 176, 106, 105, 97, 110, 52, 0, 10, 3, 233, 138, 128, 121, 105, 110, 50, 0, 11, 3, 233, 129, 184, 120, 117, 97, 110, 51, 0, 10, 3, 229, 173, 152, 99, 117, 110, 50, 0, 10, 3, 229, 160, 176, 121, 97, 110, 52, 0, 0, 11, 3, 229, 175, 167, 110, 105, 110, 103, 50, 0, 10, 3, 232, 137, 183, 121, 97, 110, 52, 0, 9, 3, 229, 173, 151, 122, 105, 52, 0, 10, 3, 230, 152, 175, 115, 104, 105, 52, 0, 11, 3, 233, 129, 183, 113, 105, 97, 110, 49, 0, 0, 10, 3, 229, 174, 158, 115, 104, 105, 50, 0, 10, 3, 231, 158, 158, 109, 97, 110, 50, 0, 10, 3, 229, 175, 166, 115, 104, 105, 50, 0, 10, 3, 231, 155, 134, 112, 101, 110, 50, 0, 10, 3, 233, 128, 174, 100, 97, 105, 51, 0, 10, 3, 229, 162, 190, 107, 101, 110, 51, 0, 11, 3, 230, 153, 182, 106, 105, 110, 103, 49, 0, 0, 10, 3, 233, 139, 133, 120, 105, 110, 49, 0, 10, 3, 231, 159, 165, 122, 104, 105, 49, 0, 10, 3, 232, 151, 165, 121, 97, 111, 52, 0, 10, 3, 233, 129, 181, 122, 117, 110, 49, 0, 10, 3, 230, 164, 141, 122, 104, 105, 50, 0, 10, 3, 229, 174, 157, 98, 97, 111, 51, 0, 9, 3, 232, 138, 189, 121, 97, 50, 0, 11, 3, 229, 161, 181, 99, 104, 101, 110, 50, 0, 0, 11, 3, 232, 151, 164, 116, 101, 110, 103, 50, 0, 9, 3, 230, 163, 132, 113, 105, 52, 0, 11, 3, 230, 166, 156, 98, 97, 110, 103, 51, 0, 11, 3, 229, 173, 148, 107, 111, 110, 103, 51, 0, 9, 3, 232, 147, 132, 120, 117, 52, 0, 9, 3, 229, 174, 156, 121, 105, 53, 0, 11, 3, 229, 172, 140, 106, 105, 97, 111, 49, 0, 11, 3, 230, 153, 180, 113, 105, 110, 103, 50, 0, 10, 3, 232, 136, 172, 98, 97, 110, 49, 0, 0, 10, 3, 233, 130, 187, 108, 105, 110, 50, 0, 10, 3, 232, 137, 179, 121, 97, 110, 52, 0, 10, 3, 231, 156, 139, 107, 97, 110, 52, 0, 0, 9, 3, 232, 137, 178, 115, 101, 52, 0, 10, 3, 229, 160, 170, 107, 97, 110, 49, 0, 11, 3, 232, 136, 170, 104, 97, 110, 103, 50, 0, 11, 3, 229, 174, 154, 100, 105, 110, 103, 52, 0, 10, 3, 233, 129, 178, 99, 104, 105, 50, 0, 10, 3, 229, 171, 130, 115, 97, 111, 51, 0, 0, 11, 3, 229, 174, 153, 122, 104, 111, 117, 52, 0, 9, 3, 233, 139, 129, 108, 118, 51, 0, 10, 3, 229, 171, 129, 106, 105, 97, 52, 0, 10, 3, 231, 156, 137, 109, 101, 105, 50, 0, 10, 3, 229, 175, 161, 103, 117, 97, 51, 0, 11, 3, 233, 143, 161, 106, 105, 110, 103, 52, 0, 11, 3, 232, 137, 177, 106, 105, 97, 110, 49, 0, 0, 9, 3, 230, 153, 176, 120, 105, 49, 0, 11, 3, 230, 163, 128, 106, 105, 97, 110, 51, 0, 11, 3, 232, 137, 176, 106, 105, 97, 110, 49, 0, 9, 3, 229, 173, 144, 122, 105, 53, 0, 10, 3, 230, 152, 168, 122, 117, 111, 50, 0, 11, 3, 229, 174, 152, 103, 117, 97, 110, 49, 0, 0, 9, 3, 231, 167, 159, 122, 117, 49, 0, 10, 3, 228, 189, 143, 122, 104, 117, 52, 0, 11, 3, 233, 138, 183, 120, 105, 97, 111, 49, 0, 12, 3, 229, 180, 135, 99, 104, 111, 110, 103, 50, 0, 0, 11, 3, 231, 152, 166, 115, 104, 111, 117, 52, 0, 9, 3, 228, 189, 142, 100, 105, 49, 0, 11, 3, 229, 183, 158, 122, 104, 111, 117, 49, 0, 10, 3, 231, 155, 190, 100, 117, 110, 52, 0, 10, 3, 230, 174, 150, 122, 104, 105, 50, 0, 0, 10, 3, 228, 189, 141, 119, 101, 105, 52, 0, 10, 3, 233, 148, 133, 103, 117, 111, 49, 0, 11, 3, 232, 144, 165, 121, 105, 110, 103, 50, 0, 10, 3, 228, 191, 157, 98, 97, 111, 51, 0, 0, 10, 3, 231, 155, 188, 112, 97, 110, 52, 0, 10, 3, 230, 172, 132, 108, 97, 110, 50, 0, 11, 3, 233, 139, 188, 103, 97, 110, 103, 49, 0, 11, 3, 229, 181, 140, 113, 105, 97, 110, 52, 0, 9, 3, 232, 157, 140, 107, 101, 49, 0, 11, 3, 233, 151, 156, 103, 117, 97, 110, 49, 0, 11, 3, 232, 145, 172, 122, 97, 110, 103, 52, 0, 10, 3, 233, 148, 132, 99, 104, 117, 50, 0, 11, 3, 232, 144, 164, 121, 105, 110, 103, 50, 0, 9, 3, 230, 173, 140, 103, 101, 49, 0, 0, 10, 3, 233, 138, 179, 114, 117, 105, 52, 0, 9, 3, 232, 145, 171, 104, 117, 50, 0, 9, 3, 229, 170, 179, 120, 105, 50, 0, 11, 3, 233, 150, 147, 106, 105, 97, 110, 49, 0, 10, 3, 230, 175, 155, 109, 97, 111, 50, 0, 10, 3, 233, 136, 163, 103, 97, 105, 52, 0, 10, 3, 230, 162, 179, 115, 104, 117, 49, 0, 0, 11, 3, 230, 163, 186, 103, 117, 97, 110, 49, 0, 11, 3, 232, 156, 130, 102, 101, 110, 103, 49, 0, 0, 9, 3, 228, 188, 129, 113, 105, 51, 0, 11, 3, 233, 150, 145, 120, 105, 97, 110, 50, 0, 9, 3, 230, 175, 153, 98, 105, 52, 0, 11, 3, 232, 157, 137, 99, 104, 97, 110, 50, 0, 11, 3, 230, 173, 137, 113, 105, 97, 110, 52, 0, 11, 3, 231, 154, 177, 122, 104, 111, 117, 52, 0, 11, 3, 230, 160, 161, 120, 105, 97, 111, 52, 0, 13, 3, 230, 161, 169, 122, 104, 117, 97, 110, 103, 49, 0, 10, 3, 233, 148, 129, 115, 117, 111, 51, 0, 0, 12, 3, 230, 161, 168, 106, 105, 97, 110, 103, 51, 0, 9, 3, 233, 139, 184, 106, 117, 52, 0, 9, 3, 231, 167, 152, 109, 105, 52, 0, 10, 3, 230, 162, 176, 120, 105, 101, 52, 0, 11, 3, 233, 148, 128, 120, 105, 97, 111, 49, 0, 12, 3, 231, 155, 184, 120, 105, 97, 110, 103, 49, 0, 9, 3, 228, 191, 152, 102, 117, 50, 0, 0, 9, 3, 228, 191, 151, 115, 117, 50, 0, 9, 3, 230, 162, 175, 116, 105, 49, 0, 11, 3, 233, 149, 135, 122, 104, 101, 110, 52, 0, 9, 3, 231, 166, 143, 102, 117, 50, 0, 10, 3, 230, 173, 135, 120, 105, 101, 49, 0, 11, 3, 232, 157, 135, 121, 105, 110, 103, 53, 0, 0, 10, 3, 228, 189, 134, 100, 97, 110, 52, 0, 10, 3, 232, 145, 166, 119, 101, 105, 51, 0, 9, 3, 231, 154, 174, 112, 105, 50, 0, 10, 3, 230, 161, 166, 104, 117, 97, 52, 0, 13, 3, 233, 151, 150, 99, 104, 117, 97, 110, 103, 51, 0, 12, 3, 231, 156, 190, 122, 104, 111, 110, 103, 52, 0, 9, 3, 229, 169, 166, 102, 117, 52, 0, 0, 10, 3, 228, 190, 141, 115, 104, 105, 52, 0, 11, 3, 232, 158, 141, 114, 111, 110, 103, 50, 0, 9, 3, 230, 163, 181, 107, 101, 49, 0, 9, 3, 230, 175, 149, 98, 105, 52, 0, 9, 3, 232, 148, 189, 98, 105, 52, 0, 10, 3, 231, 166, 141, 104, 117, 111, 52, 0, 11, 3, 230, 161, 165, 113, 105, 97, 111, 50, 0, 10, 3, 232, 144, 157, 108, 117, 111, 50, 0, 0, 9, 3, 232, 148, 188, 97, 105, 51, 0, 10, 3, 231, 155, 180, 122, 104, 105, 50, 0, 10, 3, 233, 137, 164, 103, 111, 117, 49, 0, 9, 3, 230, 175, 148, 98, 105, 51, 0, 10, 3, 231, 156, 188, 121, 97, 110, 51, 0, 0, 9, 3, 228, 190, 139, 108, 105, 52, 0, 10, 3, 230, 174, 139, 99, 97, 110, 50, 0, 9, 3, 229, 168, 155, 121, 117, 50, 0, 11, 3, 230, 161, 163, 100, 97, 110, 103, 52, 0, 10, 3, 233, 150, 139, 107, 97, 105, 49, 0, 11, 3, 228, 189, 131, 100, 105, 97, 110, 52, 0, 0, 9, 3, 230, 175, 146, 100, 117, 50, 0, 10, 3, 230, 174, 138, 115, 104, 117, 49, 0, 11, 3, 231, 155, 178, 109, 97, 110, 103, 50, 0, 11, 3, 229, 183, 146, 108, 117, 97, 110, 50, 0, 11, 3, 231, 167, 146, 109, 105, 97, 111, 51, 0, 11, 3, 231, 156, 186, 116, 105, 97, 111, 52, 0, 0, 9, 3, 231, 167, 145, 107, 101, 49, 0, 10, 3, 233, 149, 129, 109, 101, 105, 51, 0, 9, 3, 232, 145, 161, 112, 117, 50, 0, 9, 3, 233, 150, 137, 98, 105, 52, 0, 0, 9, 3, 230, 162, 168, 108, 105, 50, 0, 11, 3, 229, 172, 184, 115, 104, 101, 110, 51, 0, 9, 3, 233, 149, 128, 100, 117, 52, 0, 12, 3, 229, 168, 152, 110, 105, 97, 110, 103, 53, 0, 0, 11, 3, 231, 155, 175, 100, 105, 110, 103, 49, 0, 10, 3, 230, 175, 143, 109, 101, 105, 51, 0, 9, 3, 229, 182, 135, 113, 117, 49, 0, 10, 3, 231, 153, 159, 98, 105, 101, 51, 0, 0, 12, 3, 231, 156, 182, 107, 117, 97, 110, 103, 52, 0, 11, 3, 230, 162, 166, 109, 101, 110, 103, 52, 0, 10, 3, 230, 163, 174, 115, 101, 110, 49, 0, 9, 3, 231, 155, 174, 109, 117, 52, 0, 10, 3, 228, 190, 134, 108, 97, 105, 50, 0, 0, 12, 3, 231, 167, 141, 122, 104, 111, 110, 103, 51, 0, 10, 3, 229, 183, 141, 119, 101, 105, 49, 0, 9, 3, 230, 175, 141, 109, 117, 51, 0, 0, 10, 3, 230, 165, 188, 108, 111, 117, 50, 0, 11, 3, 233, 136, 148, 99, 104, 97, 111, 49, 0, 11, 3, 229, 182, 132, 122, 104, 97, 110, 51, 0, 11, 3, 232, 147, 172, 112, 101, 110, 103, 50, 0, 0, 11, 3, 233, 137, 155, 113, 105, 97, 110, 49, 0, 10, 3, 231, 167, 139, 113, 105, 117, 49, 0, 11, 3, 233, 150, 131, 115, 104, 97, 110, 51, 0, 9, 3, 232, 159, 139, 120, 105, 49, 0, 0, 10, 3, 233, 151, 138, 107, 117, 111, 52, 0, 11, 3, 230, 162, 162, 115, 104, 97, 111, 49, 0, 9, 3, 233, 139, 170, 112, 117, 52, 0, 10, 3, 229, 169, 154, 104, 117, 110, 49, 0, 0, 10, 3, 230, 160, 145, 115, 104, 117, 52, 0, 10, 3, 231, 166, 129, 106, 105, 110, 52, 0, 10, 3, 229, 171, 169, 110, 101, 110, 52, 0, 0, 10, 3, 233, 150, 128, 109, 101, 110, 50, 0, 11, 3, 229, 172, 176, 121, 105, 110, 103, 49, 0, 10, 3, 229, 173, 184, 120, 117, 101, 50, 0, 0, 11, 3, 233, 137, 151, 113, 105, 97, 110, 50, 0, 9, 3, 231, 156, 175, 109, 105, 49, 0, 10, 3, 233, 140, 175, 99, 117, 111, 52, 0, 10, 3, 232, 145, 151, 122, 104, 101, 53, 0, 10, 3, 230, 160, 143, 108, 97, 110, 50, 0, 9, 3, 229, 174, 191, 115, 117, 52, 0, 0, 10, 3, 231, 167, 134, 103, 97, 110, 51, 0, 10, 3, 229, 174, 190, 98, 105, 110, 49, 0, 9, 3, 232, 159, 134, 109, 97, 53, 0, 0, 11, 3, 230, 162, 157, 116, 105, 97, 111, 50, 0, 9, 3, 230, 165, 181, 106, 105, 50, 0, 9, 3, 230, 175, 133, 121, 105, 52, 0, 9, 3, 229, 173, 181, 102, 117, 49, 0, 11, 3, 229, 174, 189, 107, 117, 97, 110, 49, 0, 11, 3, 233, 141, 181, 106, 105, 97, 110, 52, 0, 10, 3, 230, 164, 173, 116, 117, 111, 51, 0, 0, 11, 3, 233, 138, 156, 120, 105, 97, 110, 50, 0, 10, 3, 232, 148, 172, 115, 104, 117, 49, 0, 11, 3, 232, 146, 156, 115, 117, 97, 110, 52, 0, 10, 3, 231, 155, 164, 112, 97, 110, 50, 0, 9, 3, 230, 161, 148, 106, 117, 50, 0, 8, 3, 228, 191, 132, 101, 50, 0, 10, 3, 233, 139, 164, 99, 104, 117, 50, 0, 10, 3, 232, 149, 180, 121, 117, 110, 52, 0, 0, 11, 3, 231, 155, 163, 106, 105, 97, 110, 49, 0, 9, 3, 233, 140, 171, 120, 105, 49, 0, 11, 3, 231, 158, 187, 122, 104, 97, 110, 49, 0, 9, 3, 228, 191, 131, 99, 117, 52, 0, 11, 3, 231, 152, 139, 102, 101, 110, 103, 49, 0, 9, 3, 231, 167, 131, 116, 117, 49, 0, 0, 0, 11, 3, 230, 161, 145, 115, 97, 110, 103, 49, 0, 11, 3, 229, 174, 185, 114, 111, 110, 103, 50, 0, 9, 3, 231, 167, 129, 115, 105, 49, 0, 11, 3, 232, 146, 153, 109, 101, 110, 103, 50, 0, 10, 3, 231, 155, 161, 106, 105, 110, 51, 0, 10, 3, 230, 175, 129, 104, 117, 105, 51, 0, 0, 10, 3, 230, 175, 128, 104, 117, 105, 51, 0, 10, 3, 231, 156, 168, 122, 104, 97, 51, 0, 12, 3, 232, 159, 128, 115, 104, 117, 97, 105, 52, 0, 10, 3, 231, 167, 128, 120, 105, 117, 52, 0, 0, 12, 3, 229, 176, 135, 106, 105, 97, 110, 103, 49, 0, 11, 3, 229, 177, 143, 112, 105, 110, 103, 50, 0, 9, 3, 230, 172, 167, 111, 117, 49, 0, 9, 3, 232, 153, 143, 108, 117, 51, 0, 10, 3, 231, 162, 151, 119, 97, 110, 51, 0, 10, 3, 228, 184, 135, 119, 97, 110, 52, 0, 11, 3, 229, 178, 151, 103, 97, 110, 103, 51, 0, 9, 3, 232, 152, 135, 115, 117, 49, 0, 9, 3, 228, 185, 143, 102, 97, 50, 0, 0, 9, 3, 229, 178, 150, 113, 117, 49, 0, 9, 3, 232, 153, 142, 104, 117, 51, 0, 9, 3, 228, 185, 142, 104, 117, 53, 0, 9, 3, 232, 152, 134, 108, 117, 50, 0, 10, 3, 233, 148, 166, 106, 105, 110, 51, 0, 10, 3, 229, 183, 190, 106, 105, 110, 49, 0, 12, 3, 229, 176, 134, 106, 105, 97, 110, 103, 49, 0, 10, 3, 229, 177, 142, 115, 104, 105, 51, 0, 12, 3, 231, 164, 166, 107, 117, 97, 110, 103, 52, 0, 0, 10, 3, 232, 154, 149, 99, 97, 110, 50, 0, 9, 3, 233, 147, 157, 108, 118, 51, 0, 10, 3, 228, 190, 181, 113, 105, 110, 49, 0, 11, 3, 230, 174, 181, 100, 117, 97, 110, 52, 0, 11, 3, 228, 186, 149, 106, 105, 110, 103, 51, 0, 0, 12, 3, 228, 188, 164, 115, 104, 97, 110, 103, 49, 0, 10, 3, 229, 176, 132, 115, 104, 101, 52, 0, 9, 3, 228, 185, 140, 119, 117, 49, 0, 11, 3, 233, 148, 164, 99, 104, 117, 105, 50, 0, 11, 3, 233, 147, 156, 116, 111, 110, 103, 50, 0, 11, 3, 230, 170, 148, 100, 97, 110, 103, 52, 0, 9, 3, 228, 186, 148, 119, 117, 51, 0, 0, 10, 3, 233, 151, 187, 119, 101, 110, 50, 0, 11, 3, 230, 169, 139, 113, 105, 97, 111, 50, 0, 10, 3, 232, 154, 147, 121, 105, 110, 51, 0, 10, 3, 228, 185, 139, 122, 104, 105, 49, 0, 10, 3, 233, 148, 163, 108, 117, 111, 50, 0, 11, 3, 233, 147, 155, 100, 97, 110, 103, 53, 0, 9, 3, 231, 167, 187, 121, 105, 50, 0, 9, 3, 232, 159, 187, 121, 105, 51, 0, 11, 3, 233, 146, 147, 100, 105, 97, 111, 52, 0, 9, 3, 229, 177, 139, 119, 117, 49, 0, 10, 3, 230, 172, 163, 120, 105, 110, 49, 0, 10, 3, 232, 155, 155, 122, 104, 117, 49, 0, 9, 3, 228, 184, 131, 113, 105, 49, 0, 0, 10, 3, 229, 177, 138, 106, 105, 101, 52, 0, 11, 3, 230, 174, 178, 106, 105, 97, 110, 49, 0, 9, 3, 228, 191, 186, 97, 110, 51, 0, 9, 3, 230, 168, 130, 108, 101, 52, 0, 12, 3, 231, 163, 154, 122, 104, 117, 97, 110, 49, 0, 10, 3, 233, 151, 186, 103, 117, 105, 49, 0, 11, 3, 230, 172, 162, 104, 117, 97, 110, 53, 0, 9, 3, 228, 186, 146, 104, 117, 52, 0, 10, 3, 231, 160, 130, 115, 104, 97, 49, 0, 10, 3, 230, 173, 170, 119, 97, 105, 49, 0, 0, 9, 3, 228, 185, 137, 121, 105, 52, 0, 9, 3, 230, 172, 161, 99, 105, 52, 0, 10, 3, 231, 162, 145, 98, 101, 105, 49, 0, 10, 3, 233, 151, 185, 110, 97, 111, 52, 0, 11, 3, 229, 176, 129, 102, 101, 110, 103, 49, 0, 10, 3, 228, 189, 169, 112, 101, 105, 52, 0, 9, 3, 231, 160, 129, 109, 97, 51, 0, 9, 3, 232, 156, 161, 108, 97, 52, 0, 10, 3, 233, 150, 177, 121, 117, 101, 52, 0, 9, 3, 232, 155, 153, 119, 97, 49, 0, 9, 3, 229, 177, 137, 116, 105, 53, 0, 10, 3, 228, 186, 145, 121, 117, 110, 50, 0, 11, 3, 228, 184, 129, 100, 105, 110, 103, 49, 0, 13, 3, 230, 168, 129, 122, 104, 117, 97, 110, 103, 49, 0, 9, 3, 233, 148, 161, 120, 105, 49, 0, 11, 3, 228, 187, 153, 120, 105, 97, 110, 53, 0, 0, 10, 3, 230, 170, 144, 121, 97, 110, 50, 0, 11, 3, 231, 165, 168, 112, 105, 97, 111, 52, 0, 10, 3, 233, 151, 184, 122, 104, 97, 50, 0, 9, 3, 228, 184, 128, 121, 105, 49, 0, 9, 3, 229, 177, 136, 113, 117, 49, 0, 9, 3, 228, 187, 152, 102, 117, 52, 0, 12, 3, 228, 188, 160, 99, 104, 117, 97, 110, 50, 0, 11, 3, 230, 172, 160, 113, 105, 97, 110, 52, 0, 9, 3, 228, 185, 136, 109, 101, 53, 0, 0, 10, 3, 228, 188, 159, 119, 101, 105, 51, 0, 10, 3, 228, 186, 143, 107, 117, 105, 49, 0, 12, 3, 229, 183, 183, 120, 105, 97, 110, 103, 52, 0, 12, 3, 228, 187, 151, 122, 104, 97, 110, 103, 52, 0, 10, 3, 233, 151, 183, 109, 101, 110, 52, 0, 0, 9, 3, 228, 186, 142, 121, 117, 50, 0, 9, 3, 230, 173, 166, 119, 117, 51, 0, 10, 3, 233, 136, 190, 121, 111, 117, 50, 0, 10, 3, 229, 177, 134, 106, 105, 101, 52, 0, 10, 3, 232, 157, 166, 120, 105, 97, 49, 0, 9, 3, 228, 187, 150, 116, 97, 49, 0, 9, 3, 228, 190, 174, 119, 117, 51, 0, 10, 3, 231, 162, 142, 115, 117, 105, 52, 0, 9, 3, 231, 166, 174, 108, 105, 51, 0, 10, 3, 228, 188, 158, 115, 97, 110, 51, 0, 0, 12, 3, 231, 165, 165, 120, 105, 97, 110, 103, 50, 0, 10, 3, 228, 185, 133, 106, 105, 117, 51, 0, 9, 3, 231, 162, 141, 97, 105, 52, 0, 9, 3, 230, 173, 165, 98, 117, 52, 0, 9, 3, 231, 163, 149, 107, 101, 49, 0, 10, 3, 230, 160, 189, 122, 97, 105, 49, 0, 10, 3, 231, 161, 133, 103, 117, 105, 49, 0, 10, 3, 232, 144, 189, 108, 117, 111, 52, 0, 9, 3, 229, 177, 133, 106, 117, 49, 0, 0, 9, 3, 230, 173, 164, 99, 105, 51, 0, 11, 3, 233, 151, 180, 106, 105, 97, 110, 49, 0, 9, 3, 230, 160, 188, 103, 101, 50, 0, 9, 3, 229, 183, 180, 98, 97, 53, 0, 9, 3, 228, 186, 140, 101, 114, 52, 0, 9, 3, 228, 187, 148, 122, 105, 51, 0, 9, 3, 232, 156, 156, 109, 105, 52, 0, 10, 3, 233, 145, 132, 122, 104, 117, 52, 0, 9, 3, 231, 162, 140, 108, 117, 52, 0, 0, 11, 3, 228, 187, 147, 99, 97, 110, 103, 49, 0, 10, 3, 228, 185, 131, 110, 97, 105, 51, 0, 10, 3, 228, 186, 139, 115, 104, 105, 52, 0, 12, 3, 230, 173, 163, 122, 104, 101, 110, 103, 52, 0, 0, 11, 3, 233, 151, 178, 120, 105, 97, 110, 50, 0, 10, 3, 228, 188, 154, 104, 117, 105, 52, 0, 10, 3, 232, 154, 138, 119, 101, 110, 50, 0, 9, 3, 229, 183, 178, 121, 105, 51, 0, 10, 3, 230, 173, 162, 122, 104, 105, 51, 0, 11, 3, 229, 177, 130, 99, 101, 110, 103, 50, 0, 0, 9, 3, 229, 177, 129, 112, 105, 52, 0, 9, 3, 231, 164, 153, 97, 105, 52, 0, 12, 3, 228, 186, 137, 122, 104, 101, 110, 103, 49, 0, 10, 3, 233, 148, 153, 99, 117, 111, 52, 0, 9, 3, 228, 191, 177, 106, 117, 52, 0, 10, 3, 228, 188, 153, 104, 117, 111, 51, 0, 11, 3, 233, 146, 137, 100, 105, 110, 103, 49, 0, 11, 3, 230, 173, 161, 104, 117, 97, 110, 53, 0, 9, 3, 229, 183, 177, 106, 105, 51, 0, 10, 3, 230, 160, 185, 103, 101, 110, 49, 0, 0, 10, 3, 228, 188, 152, 121, 111, 117, 49, 0, 10, 3, 233, 150, 168, 103, 117, 105, 49, 0, 9, 3, 232, 157, 160, 102, 117, 50, 0, 9, 3, 228, 189, 160, 110, 105, 51, 0, 11, 3, 233, 146, 136, 122, 104, 101, 110, 49, 0, 9, 3, 230, 160, 184, 104, 101, 50, 0, 10, 3, 232, 156, 152, 122, 104, 105, 49, 0, 12, 3, 231, 167, 176, 99, 104, 101, 110, 103, 49, 0, 9, 3, 228, 186, 136, 121, 117, 51, 0, 9, 3, 229, 177, 128, 106, 117, 50, 0, 10, 3, 231, 161, 128, 99, 104, 117, 51, 0, 0, 11, 3, 229, 180, 151, 103, 97, 110, 103, 51, 0, 9, 3, 231, 167, 175, 106, 105, 49, 0, 9, 3, 233, 136, 183, 103, 117, 51, 0, 10, 3, 232, 157, 159, 119, 101, 105, 53, 0, 13, 3, 233, 151, 175, 99, 104, 117, 97, 110, 103, 51, 0, 9, 3, 228, 190, 167, 99, 101, 52, 0, 12, 3, 228, 188, 151, 122, 104, 111, 110, 103, 52, 0, 10, 3, 230, 175, 175, 116, 97, 110, 51, 0, 9, 3, 228, 191, 175, 102, 117, 51, 0, 11, 3, 230, 160, 183, 121, 97, 110, 103, 52, 0, 9, 3, 232, 156, 151, 119, 111, 49, 0, 0, 10, 3, 228, 191, 174, 120, 105, 117, 49, 0, 11, 3, 228, 187, 142, 99, 111, 110, 103, 50, 0, 11, 3, 231, 165, 158, 115, 104, 101, 110, 50, 0, 10, 3, 231, 153, 190, 98, 97, 105, 51, 0, 10, 3, 229, 183, 174, 99, 104, 97, 52, 0, 9, 3, 228, 186, 134, 108, 101, 53, 0, 11, 3, 228, 190, 166, 122, 104, 101, 110, 49, 0, 9, 3, 229, 168, 182, 113, 117, 51, 0, 9, 3, 229, 180, 150, 121, 97, 50, 0, 10, 3, 233, 151, 174, 119, 101, 110, 52, 0, 0, 9, 3, 233, 151, 173, 98, 105, 52, 0, 10, 3, 231, 165, 157, 122, 104, 117, 52, 0, 11, 3, 228, 191, 173, 106, 105, 97, 110, 51, 0, 11, 3, 228, 187, 141, 114, 101, 110, 103, 50, 0, 9, 3, 233, 150, 165, 102, 97, 50, 0, 10, 3, 231, 153, 189, 98, 97, 105, 50, 0, 0, 11, 3, 232, 159, 172, 99, 104, 97, 110, 50, 0, 11, 3, 233, 136, 180, 108, 105, 110, 103, 50, 0, 9, 3, 231, 153, 188, 102, 97, 49, 0, 11, 3, 233, 149, 156, 106, 105, 110, 103, 52, 0, 10, 3, 228, 189, 156, 122, 117, 111, 52, 0, 0, 11, 3, 232, 156, 147, 116, 105, 110, 103, 50, 0, 9, 3, 228, 189, 155, 102, 117, 50, 0, 10, 3, 228, 187, 139, 106, 105, 101, 52, 0, 11, 3, 231, 153, 187, 100, 101, 110, 103, 49, 0, 10, 3, 230, 175, 171, 104, 97, 111, 50, 0, 10, 3, 232, 155, 139, 100, 97, 110, 52, 0, 0, 9, 3, 229, 178, 130, 113, 105, 51, 0, 11, 3, 232, 158, 162, 121, 105, 110, 103, 50, 0, 10, 3, 228, 187, 138, 106, 105, 110, 49, 0, 11, 3, 233, 151, 170, 115, 104, 97, 110, 51, 0, 9, 3, 232, 154, 130, 109, 97, 51, 0, 11, 3, 228, 186, 130, 108, 117, 97, 110, 52, 0, 10, 3, 231, 163, 138, 108, 101, 105, 51, 0, 0, 10, 3, 228, 188, 145, 120, 105, 117, 49, 0, 10, 3, 229, 178, 129, 115, 117, 105, 52, 0, 10, 3, 228, 191, 169, 108, 105, 97, 51, 0, 11, 3, 232, 157, 153, 98, 105, 97, 110, 49, 0, 9, 3, 228, 189, 153, 121, 117, 50, 0, 11, 3, 229, 183, 169, 103, 111, 110, 103, 51, 0, 10, 3, 231, 167, 169, 122, 104, 105, 52, 0, 9, 3, 232, 154, 129, 121, 105, 51, 0, 9, 3, 229, 168, 177, 121, 117, 50, 0, 0, 9, 3, 229, 183, 168, 106, 117, 52, 0, 10, 3, 233, 151, 168, 109, 101, 110, 50, 0, 10, 3, 232, 154, 128, 115, 104, 105, 50, 0, 10, 3, 233, 148, 144, 114, 117, 105, 52, 0, 9, 3, 228, 188, 144, 102, 97, 50, 0, 0, 9, 3, 228, 188, 143, 102, 117, 50, 0, 11, 3, 229, 183, 167, 113, 105, 97, 111, 51, 0, 11, 3, 231, 167, 167, 121, 97, 110, 103, 49, 0, 10, 3, 232, 155, 135, 115, 104, 101, 50, 0, 12, 3, 232, 157, 151, 104, 117, 97, 110, 103, 50, 0, 11, 3, 228, 187, 135, 99, 104, 111, 117, 50, 0, 0, 10, 3, 229, 183, 166, 122, 117, 111, 51, 0, 9, 3, 232, 158, 158, 109, 97, 51, 0, 10, 3, 231, 164, 142, 99, 104, 117, 51, 0, 11, 3, 230, 161, 182, 116, 111, 110, 103, 51, 0, 9, 3, 229, 180, 142, 113, 105, 50, 0, 9, 3, 231, 165, 150, 122, 117, 51, 0, 9, 3, 232, 155, 134, 113, 117, 49, 0, 11, 3, 229, 169, 182, 115, 104, 101, 110, 51, 0, 0, 10, 3, 228, 187, 133, 106, 105, 110, 51, 0, 9, 3, 228, 188, 141, 119, 117, 53, 0, 9, 3, 229, 170, 189, 109, 97, 49, 0, 9, 3, 228, 189, 149, 104, 101, 50, 0, 10, 3, 232, 145, 181, 107, 117, 105, 50, 0, 11, 3, 231, 163, 133, 98, 97, 110, 103, 52, 0, 11, 3, 233, 147, 133, 113, 105, 97, 110, 49, 0, 9, 3, 228, 190, 157, 121, 105, 49, 0, 11, 3, 229, 183, 165, 103, 111, 110, 103, 49, 0, 10, 3, 232, 157, 149, 115, 104, 105, 50, 0, 0, 10, 3, 233, 148, 140, 120, 105, 110, 49, 0, 10, 3, 232, 144, 172, 119, 97, 110, 52, 0, 12, 3, 231, 167, 164, 99, 104, 101, 110, 103, 52, 0, 11, 3, 233, 137, 180, 106, 105, 97, 110, 52, 0, 11, 3, 229, 169, 180, 121, 105, 110, 103, 49, 0, 11, 3, 232, 146, 188, 99, 97, 110, 103, 49, 0, 0, 11, 3, 228, 190, 155, 103, 111, 110, 103, 49, 0, 11, 3, 233, 148, 139, 102, 101, 110, 103, 49, 0, 9, 3, 228, 189, 147, 116, 105, 51, 0, 11, 3, 233, 147, 131, 108, 105, 110, 103, 50, 0, 0, 11, 3, 230, 172, 138, 113, 117, 97, 110, 50, 0, 9, 3, 228, 188, 138, 121, 105, 49, 0, 11, 3, 229, 183, 162, 99, 104, 97, 111, 50, 0, 11, 3, 231, 154, 186, 122, 104, 111, 117, 52, 0, 10, 3, 230, 160, 170, 122, 104, 117, 49, 0, 10, 3, 231, 152, 170, 98, 105, 101, 51, 0, 0, 10, 3, 229, 183, 161, 120, 117, 110, 50, 0, 11, 3, 233, 151, 161, 99, 104, 97, 110, 51, 0, 11, 3, 232, 145, 177, 99, 111, 110, 103, 49, 0, 9, 3, 231, 152, 169, 100, 97, 53, 0, 10, 3, 233, 147, 129, 116, 105, 101, 51, 0, 10, 3, 228, 191, 161, 120, 105, 110, 52, 0, 11, 3, 230, 175, 161, 122, 104, 97, 110, 49, 0, 10, 3, 228, 189, 145, 121, 111, 117, 52, 0, 9, 3, 231, 163, 129, 99, 105, 50, 0, 0, 10, 3, 233, 150, 152, 122, 104, 97, 50, 0, 9, 3, 232, 144, 168, 115, 97, 52, 0, 10, 3, 233, 147, 128, 121, 111, 117, 50, 0, 9, 3, 232, 156, 136, 119, 117, 50, 0, 10, 3, 232, 155, 128, 122, 104, 117, 52, 0, 9, 3, 230, 173, 144, 111, 117, 49, 0, 12, 3, 232, 146, 184, 122, 104, 101, 110, 103, 49, 0, 11, 3, 228, 187, 128, 115, 104, 101, 110, 50, 0, 10, 3, 233, 148, 136, 120, 105, 117, 52, 0, 10, 3, 230, 174, 152, 99, 97, 110, 50, 0, 0, 9, 3, 232, 164, 135, 102, 117, 52, 0, 11, 3, 228, 184, 167, 115, 97, 110, 103, 52, 0, 11, 3, 231, 174, 151, 115, 117, 97, 110, 52, 0, 9, 3, 229, 190, 151, 100, 101, 53, 0, 11, 3, 228, 187, 191, 102, 97, 110, 103, 51, 0, 11, 3, 233, 156, 135, 122, 104, 101, 110, 52, 0, 0, 9, 3, 230, 181, 142, 106, 105, 52, 0, 11, 3, 233, 147, 190, 108, 105, 97, 110, 52, 0, 10, 3, 232, 166, 150, 115, 104, 105, 52, 0, 9, 3, 231, 172, 134, 98, 97, 53, 0, 10, 3, 229, 189, 142, 119, 97, 110, 49, 0, 8, 3, 232, 155, 190, 101, 50, 0, 10, 3, 231, 161, 174, 113, 117, 101, 52, 0, 0, 9, 3, 230, 182, 149, 116, 105, 52, 0, 10, 3, 228, 187, 189, 102, 101, 110, 52, 0, 10, 3, 228, 184, 165, 121, 97, 110, 50, 0, 10, 3, 229, 179, 189, 120, 105, 97, 50, 0, 0, 12, 3, 228, 184, 164, 108, 105, 97, 110, 103, 51, 0, 11, 3, 229, 188, 132, 110, 111, 110, 103, 52, 0, 9, 3, 233, 146, 180, 103, 117, 51, 0, 10, 3, 229, 176, 164, 121, 111, 117, 50, 0, 10, 3, 229, 177, 172, 115, 104, 117, 51, 0, 11, 3, 231, 161, 172, 121, 105, 110, 103, 52, 0, 9, 3, 229, 189, 140, 109, 105, 50, 0, 0, 9, 3, 229, 188, 131, 113, 105, 52, 0, 10, 3, 229, 179, 187, 106, 117, 110, 52, 0, 10, 3, 231, 161, 171, 108, 105, 117, 50, 0, 10, 3, 231, 173, 139, 106, 105, 110, 49, 0, 11, 3, 230, 168, 163, 121, 97, 110, 103, 52, 0, 11, 3, 233, 146, 179, 113, 105, 97, 110, 50, 0, 10, 3, 228, 187, 187, 114, 101, 110, 52, 0, 12, 3, 232, 153, 171, 99, 104, 111, 110, 103, 50, 0, 11, 3, 230, 169, 171, 104, 101, 110, 103, 50, 0, 9, 3, 230, 181, 139, 99, 101, 52, 0, 10, 3, 231, 162, 179, 116, 97, 110, 52, 0, 0, 9, 3, 229, 190, 146, 116, 117, 50, 0, 10, 3, 232, 164, 130, 103, 117, 97, 52, 0, 11, 3, 230, 181, 138, 122, 104, 117, 111, 50, 0, 10, 3, 228, 184, 162, 100, 105, 117, 49, 0, 12, 3, 231, 163, 186, 104, 117, 97, 110, 103, 50, 0, 9, 3, 229, 188, 130, 121, 105, 52, 0, 10, 3, 230, 183, 154, 108, 101, 105, 52, 0, 9, 3, 233, 147, 186, 112, 117, 52, 0, 10, 3, 228, 186, 178, 113, 105, 110, 49, 0, 0, 11, 3, 229, 191, 153, 109, 97, 110, 103, 50, 0, 11, 3, 231, 173, 137, 100, 101, 110, 103, 51, 0, 10, 3, 230, 180, 129, 106, 105, 101, 50, 0, 11, 3, 233, 146, 177, 113, 105, 97, 110, 50, 0, 11, 3, 231, 162, 177, 106, 105, 97, 110, 51, 0, 9, 3, 230, 168, 161, 109, 111, 50, 0, 11, 3, 229, 190, 145, 106, 105, 110, 103, 52, 0, 0, 10, 3, 229, 189, 136, 100, 97, 110, 52, 0, 10, 3, 230, 183, 152, 116, 97, 111, 50, 0, 11, 3, 233, 157, 136, 108, 105, 110, 103, 50, 0, 11, 3, 231, 162, 176, 112, 101, 110, 103, 52, 0, 9, 3, 229, 190, 144, 120, 117, 50, 0, 10, 3, 233, 147, 184, 122, 104, 117, 52, 0, 10, 3, 229, 188, 128, 107, 97, 105, 49, 0, 11, 3, 229, 191, 152, 119, 97, 110, 103, 52, 0, 9, 3, 233, 156, 128, 120, 117, 49, 0, 0, 10, 3, 229, 191, 151, 122, 104, 105, 52, 0, 10, 3, 232, 153, 167, 107, 117, 105, 49, 0, 10, 3, 232, 166, 143, 103, 117, 105, 49, 0, 11, 3, 230, 181, 135, 106, 105, 97, 111, 49, 0, 10, 3, 231, 163, 183, 108, 105, 110, 50, 0, 11, 3, 233, 158, 143, 103, 111, 110, 103, 51, 0, 12, 3, 230, 168, 159, 122, 104, 97, 110, 103, 49, 0, 10, 3, 232, 154, 175, 113, 105, 117, 49, 0, 10, 3, 228, 184, 159, 100, 105, 117, 49, 0, 10, 3, 228, 187, 183, 106, 105, 97, 52, 0, 0, 10, 3, 231, 164, 190, 115, 104, 101, 52, 0, 9, 3, 231, 173, 134, 98, 105, 51, 0, 12, 3, 228, 186, 174, 108, 105, 97, 110, 103, 52, 0, 11, 3, 228, 187, 182, 106, 105, 97, 110, 52, 0, 11, 3, 230, 172, 190, 107, 117, 97, 110, 51, 0, 12, 3, 230, 181, 134, 106, 105, 97, 110, 103, 49, 0, 10, 3, 233, 147, 182, 121, 105, 110, 50, 0, 10, 3, 230, 168, 158, 115, 104, 117, 49, 0, 10, 3, 229, 179, 182, 100, 97, 111, 51, 0, 10, 3, 228, 185, 166, 115, 104, 117, 49, 0, 0, 11, 3, 229, 178, 173, 108, 105, 110, 103, 51, 0, 11, 3, 230, 181, 133, 113, 105, 97, 110, 51, 0, 9, 3, 228, 184, 157, 115, 105, 49, 0, 10, 3, 230, 172, 189, 113, 105, 110, 49, 0, 11, 3, 228, 186, 173, 116, 105, 110, 103, 50, 0, 12, 3, 229, 176, 157, 99, 104, 97, 110, 103, 50, 0, 10, 3, 229, 180, 189, 122, 97, 105, 51, 0, 0, 11, 3, 230, 182, 140, 121, 111, 110, 103, 51, 0, 11, 3, 229, 177, 164, 99, 101, 110, 103, 50, 0, 9, 3, 231, 164, 188, 108, 105, 51, 0, 11, 3, 228, 184, 156, 100, 111, 110, 103, 49, 0, 9, 3, 228, 188, 188, 115, 105, 52, 0, 0, 9, 3, 229, 190, 139, 108, 118, 52, 0, 11, 3, 228, 184, 155, 99, 111, 110, 103, 50, 0, 11, 3, 232, 156, 187, 113, 105, 110, 103, 49, 0, 10, 3, 233, 158, 139, 120, 105, 101, 50, 0, 11, 3, 233, 148, 187, 100, 117, 97, 110, 52, 0, 11, 3, 232, 166, 139, 106, 105, 97, 110, 52, 0, 12, 3, 228, 186, 171, 120, 105, 97, 110, 103, 51, 0, 0, 10, 3, 232, 154, 170, 100, 111, 117, 51, 0, 10, 3, 230, 169, 162, 116, 117, 111, 51, 0, 10, 3, 231, 164, 186, 115, 104, 105, 52, 0, 11, 3, 233, 147, 178, 99, 104, 97, 110, 51, 0, 12, 3, 229, 176, 154, 115, 104, 97, 110, 103, 52, 0, 11, 3, 229, 190, 138, 104, 117, 97, 105, 50, 0, 9, 3, 230, 183, 146, 113, 105, 49, 0, 9, 3, 230, 172, 186, 113, 105, 49, 0, 11, 3, 232, 167, 146, 106, 105, 97, 111, 51, 0, 9, 3, 228, 188, 186, 99, 105, 52, 0, 9, 3, 228, 184, 154, 121, 101, 52, 0, 0, 10, 3, 233, 146, 169, 103, 111, 117, 49, 0, 10, 3, 230, 181, 129, 108, 105, 117, 50, 0, 11, 3, 233, 148, 185, 113, 105, 97, 111, 49, 0, 10, 3, 229, 178, 169, 121, 97, 110, 50, 0, 11, 3, 230, 168, 153, 98, 105, 97, 111, 49, 0, 11, 3, 228, 184, 153, 98, 105, 110, 103, 51, 0, 12, 3, 228, 185, 161, 120, 105, 97, 110, 103, 49, 0, 12, 3, 230, 169, 161, 120, 105, 97, 110, 103, 52, 0, 10, 3, 232, 154, 169, 99, 104, 105, 49, 0, 9, 3, 228, 186, 169, 109, 117, 51, 0, 10, 3, 230, 182, 137, 115, 104, 101, 52, 0, 0, 9, 3, 228, 185, 160, 120, 105, 50, 0, 12, 3, 233, 144, 152, 122, 104, 111, 110, 103, 49, 0, 11, 3, 228, 188, 184, 115, 104, 101, 110, 49, 0, 11, 3, 229, 176, 152, 99, 104, 101, 110, 50, 0, 11, 3, 229, 179, 176, 102, 101, 110, 103, 49, 0, 11, 3, 230, 182, 136, 120, 105, 97, 111, 49, 0, 9, 3, 229, 177, 160, 116, 117, 50, 0, 10, 3, 228, 184, 152, 113, 105, 117, 49, 0, 11, 3, 228, 187, 176, 121, 97, 110, 103, 51, 0, 10, 3, 229, 190, 136, 104, 101, 110, 51, 0, 0, 11, 3, 228, 186, 167, 99, 104, 97, 110, 51, 0, 12, 3, 233, 149, 191, 99, 104, 97, 110, 103, 50, 0, 10, 3, 232, 153, 159, 104, 97, 111, 52, 0, 9, 3, 231, 162, 167, 98, 105, 52, 0, 10, 3, 228, 189, 191, 115, 104, 105, 51, 0, 9, 3, 228, 185, 159, 121, 101, 51, 0, 9, 3, 230, 169, 159, 106, 105, 49, 0, 0, 11, 3, 228, 188, 182, 108, 105, 110, 103, 53, 0, 10, 3, 228, 184, 150, 115, 104, 105, 52, 0, 9, 3, 232, 166, 134, 102, 117, 52, 0, 10, 3, 233, 146, 166, 113, 105, 110, 49, 0, 9, 3, 228, 186, 166, 121, 105, 52, 0, 11, 3, 229, 176, 150, 106, 105, 97, 110, 49, 0, 12, 3, 231, 160, 150, 122, 104, 117, 97, 110, 49, 0, 10, 3, 229, 177, 158, 115, 104, 117, 51, 0, 0, 11, 3, 231, 161, 157, 120, 105, 97, 111, 49, 0, 10, 3, 229, 190, 133, 100, 97, 105, 52, 0, 10, 3, 228, 185, 157, 106, 105, 117, 51, 0, 11, 3, 229, 179, 173, 113, 105, 97, 111, 52, 0, 10, 3, 229, 191, 141, 114, 101, 110, 51, 0, 10, 3, 233, 146, 165, 121, 97, 111, 52, 0, 0, 10, 3, 228, 184, 148, 113, 105, 101, 51, 0, 10, 3, 228, 187, 172, 109, 101, 110, 53, 0, 10, 3, 233, 159, 140, 114, 101, 110, 52, 0, 11, 3, 229, 190, 132, 106, 105, 110, 103, 52, 0, 9, 3, 232, 153, 156, 108, 117, 51, 0, 10, 3, 228, 188, 180, 98, 97, 110, 52, 0, 10, 3, 231, 160, 148, 121, 97, 110, 50, 0, 11, 3, 230, 173, 188, 106, 105, 97, 110, 49, 0, 9, 3, 229, 176, 148, 101, 114, 51, 0, 11, 3, 230, 183, 140, 116, 97, 110, 103, 51, 0, 9, 3, 229, 177, 156, 116, 105, 53, 0, 11, 3, 228, 186, 164, 106, 105, 97, 111, 49, 0, 0, 9, 3, 230, 173, 187, 115, 105, 51, 0, 11, 3, 232, 154, 163, 103, 111, 110, 103, 53, 0, 10, 3, 230, 183, 139, 108, 105, 110, 50, 0, 9, 3, 232, 153, 155, 120, 117, 49, 0, 12, 3, 228, 184, 147, 122, 104, 117, 97, 110, 49, 0, 10, 3, 230, 168, 147, 108, 111, 117, 50, 0, 0, 9, 3, 228, 187, 170, 121, 105, 50, 0, 11, 3, 233, 146, 162, 103, 97, 110, 103, 49, 0, 9, 3, 230, 172, 178, 121, 117, 52, 0, 9, 3, 230, 182, 130, 116, 117, 53, 0, 11, 3, 230, 170, 162, 106, 105, 97, 110, 51, 0, 9, 3, 232, 153, 154, 120, 117, 49, 0, 0, 9, 3, 228, 185, 153, 121, 105, 51, 0, 10, 3, 232, 166, 129, 121, 97, 111, 52, 0, 11, 3, 229, 176, 145, 115, 104, 97, 111, 51, 0, 11, 3, 228, 186, 161, 119, 97, 110, 103, 50, 0, 9, 3, 232, 152, 145, 109, 111, 50, 0, 11, 3, 228, 184, 145, 99, 104, 111, 117, 51, 0, 11, 3, 229, 178, 161, 103, 97, 110, 103, 49, 0, 10, 3, 232, 167, 137, 106, 117, 101, 50, 0, 12, 3, 229, 190, 129, 122, 104, 101, 110, 103, 49, 0, 0, 10, 3, 231, 165, 184, 104, 117, 111, 52, 0, 11, 3, 231, 174, 128, 106, 105, 97, 110, 51, 0, 10, 3, 232, 167, 136, 108, 97, 110, 51, 0, 11, 3, 229, 190, 128, 119, 97, 110, 103, 51, 0, 9, 3, 230, 169, 152, 106, 117, 50, 0, 12, 3, 228, 185, 152, 99, 104, 101, 110, 103, 50, 0, 9, 3, 232, 157, 184, 119, 111, 49, 0, 9, 3, 228, 188, 176, 103, 117, 49, 0, 10, 3, 230, 173, 184, 103, 117, 105, 49, 0, 9, 3, 231, 163, 168, 109, 111, 50, 0, 8, 3, 229, 179, 168, 101, 50, 0, 0, 11, 3, 231, 175, 135, 112, 105, 97, 110, 49, 0, 9, 3, 228, 188, 175, 98, 111, 50, 0, 10, 3, 231, 162, 159, 100, 105, 101, 50, 0, 9, 3, 230, 173, 183, 108, 105, 52, 0, 12, 3, 233, 146, 159, 122, 104, 111, 110, 103, 49, 0, 9, 3, 231, 166, 191, 116, 117, 49, 0, 11, 3, 229, 176, 143, 120, 105, 97, 111, 51, 0, 12, 3, 233, 149, 183, 99, 104, 97, 110, 103, 50, 0, 9, 3, 233, 148, 175, 106, 117, 52, 0, 11, 3, 228, 190, 191, 98, 105, 97, 110, 52, 0, 11, 3, 230, 174, 191, 100, 105, 97, 110, 52, 0, 0, 9, 3, 228, 186, 158, 121, 97, 52, 0, 10, 3, 232, 167, 134, 115, 104, 105, 52, 0, 10, 3, 229, 176, 142, 100, 97, 111, 51, 0, 10, 3, 232, 157, 182, 100, 105, 101, 50, 0, 11, 3, 233, 148, 174, 106, 105, 97, 110, 52, 0, 9, 3, 228, 184, 142, 121, 117, 51, 0, 12, 3, 233, 149, 182, 120, 105, 97, 110, 103, 49, 0, 11, 3, 229, 179, 166, 108, 117, 97, 110, 50, 0, 11, 3, 233, 146, 158, 99, 104, 97, 111, 49, 0, 9, 3, 229, 191, 134, 121, 105, 52, 0, 11, 3, 228, 185, 150, 103, 117, 97, 105, 49, 0, 0, 9, 3, 228, 184, 141, 98, 117, 52, 0, 9, 3, 228, 187, 165, 121, 105, 51, 0, 10, 3, 232, 153, 149, 99, 104, 117, 52, 0, 9, 3, 229, 191, 133, 98, 105, 52, 0, 11, 3, 233, 148, 173, 100, 105, 110, 103, 52, 0, 10, 3, 229, 176, 141, 100, 117, 105, 52, 0, 10, 3, 231, 160, 141, 107, 97, 110, 51, 0, 11, 3, 229, 177, 149, 122, 104, 97, 110, 51, 0, 11, 3, 229, 180, 173, 122, 104, 97, 110, 51, 0, 0, 9, 3, 232, 154, 156, 121, 97, 50, 0, 9, 3, 231, 160, 140, 113, 105, 52, 0, 10, 3, 232, 167, 132, 103, 117, 105, 49, 0, 9, 3, 230, 174, 188, 107, 101, 50, 0, 9, 3, 232, 157, 180, 104, 117, 50, 0, 11, 3, 228, 187, 164, 108, 105, 110, 103, 52, 0, 9, 3, 232, 155, 164, 104, 97, 50, 0, 9, 3, 229, 182, 188, 121, 117, 51, 0, 0, 10, 3, 228, 187, 163, 100, 97, 105, 52, 0, 11, 3, 232, 152, 139, 112, 105, 110, 103, 50, 0, 10, 3, 229, 191, 131, 120, 105, 110, 49, 0, 10, 3, 228, 184, 139, 120, 105, 97, 52, 0, 10, 3, 229, 178, 155, 100, 97, 111, 51, 0, 10, 3, 228, 189, 179, 106, 105, 97, 49, 0, 11, 3, 228, 185, 147, 112, 97, 110, 103, 49, 0, 9, 3, 231, 166, 187, 108, 105, 50, 0, 9, 3, 231, 164, 171, 108, 105, 52, 0, 10, 3, 229, 176, 139, 120, 117, 110, 50, 0, 10, 3, 228, 186, 155, 120, 105, 101, 49, 0, 0, 11, 3, 228, 185, 146, 112, 105, 110, 103, 49, 0, 10, 3, 228, 188, 170, 119, 101, 105, 51, 0, 11, 3, 229, 182, 186, 108, 105, 110, 103, 51, 0, 9, 3, 228, 186, 154, 121, 97, 52, 0, 10, 3, 229, 176, 138, 122, 117, 110, 49, 0, 10, 3, 230, 173, 178, 115, 117, 105, 52, 0, 10, 3, 232, 152, 138, 121, 117, 110, 52, 0, 10, 3, 230, 174, 186, 115, 104, 97, 49, 0, 11, 3, 232, 167, 130, 103, 117, 97, 110, 49, 0, 11, 3, 233, 145, 146, 106, 105, 97, 110, 52, 0, 12, 3, 228, 184, 138, 115, 104, 97, 110, 103, 52, 0, 0, 10, 3, 229, 177, 145, 120, 105, 101, 52, 0, 10, 3, 233, 146, 153, 103, 97, 105, 52, 0, 11, 3, 229, 180, 169, 98, 101, 110, 103, 49, 0, 10, 3, 228, 184, 137, 115, 97, 110, 49, 0, 11, 3, 232, 167, 129, 106, 105, 97, 110, 52, 0, 12, 3, 233, 159, 129, 106, 105, 97, 110, 103, 49, 0, 10, 3, 229, 179, 161, 120, 105, 97, 50, 0, 9, 3, 232, 153, 145, 108, 118, 52, 0, 0, 10, 3, 231, 175, 128, 106, 105, 101, 50, 0, 12, 3, 229, 176, 136, 122, 104, 117, 97, 110, 49, 0, 9, 3, 228, 185, 144, 108, 101, 52, 0, 11, 3, 230, 183, 128, 100, 105, 97, 110, 52, 0, 11, 3, 233, 149, 176, 108, 105, 97, 110, 50, 0, 12, 3, 228, 184, 136, 122, 104, 97, 110, 103, 52, 0, 11, 3, 232, 167, 128, 103, 117, 97, 110, 49, 0, 0, 13, 3, 231, 170, 151, 99, 104, 117, 97, 110, 103, 49, 0, 11, 3, 229, 186, 151, 100, 105, 97, 110, 52, 0, 11, 3, 232, 165, 175, 99, 104, 101, 110, 52, 0, 11, 3, 229, 187, 159, 109, 105, 97, 111, 52, 0, 11, 3, 231, 171, 159, 106, 105, 110, 103, 52, 0, 9, 3, 229, 190, 183, 100, 101, 50, 0, 10, 3, 229, 191, 191, 102, 101, 110, 52, 0, 12, 3, 233, 159, 191, 120, 105, 97, 110, 103, 51, 0, 9, 3, 233, 156, 167, 119, 117, 52, 0, 0, 12, 3, 230, 178, 150, 99, 104, 111, 110, 103, 49, 0, 10, 3, 229, 184, 134, 102, 97, 110, 49, 0, 9, 3, 230, 181, 174, 102, 117, 50, 0, 11, 3, 231, 169, 142, 121, 105, 110, 103, 51, 0, 10, 3, 232, 162, 150, 120, 105, 117, 52, 0, 11, 3, 229, 188, 166, 120, 105, 97, 110, 50, 0, 9, 3, 231, 172, 166, 102, 117, 50, 0, 11, 3, 231, 170, 150, 106, 105, 97, 111, 52, 0, 9, 3, 233, 155, 158, 106, 105, 49, 0, 11, 3, 231, 171, 158, 106, 105, 110, 103, 52, 0, 0, 10, 3, 232, 161, 141, 121, 97, 110, 51, 0, 13, 3, 232, 163, 157, 122, 104, 117, 97, 110, 103, 49, 0, 10, 3, 230, 180, 165, 106, 105, 110, 49, 0, 11, 3, 232, 160, 133, 121, 105, 110, 103, 53, 0, 9, 3, 229, 186, 149, 100, 105, 51, 0, 12, 3, 229, 184, 133, 115, 104, 117, 97, 105, 52, 0, 11, 3, 231, 168, 133, 115, 104, 117, 105, 52, 0, 9, 3, 229, 191, 189, 104, 117, 49, 0, 12, 3, 233, 153, 141, 106, 105, 97, 110, 103, 52, 0, 9, 3, 231, 169, 141, 106, 105, 49, 0, 10, 3, 233, 152, 133, 121, 117, 101, 52, 0, 9, 3, 229, 188, 165, 109, 105, 50, 0, 0, 11, 3, 232, 161, 140, 120, 105, 110, 103, 50, 0, 9, 3, 233, 155, 156, 122, 97, 50, 0, 9, 3, 233, 154, 148, 103, 101, 50, 0, 9, 3, 233, 153, 140, 109, 111, 52, 0, 9, 3, 232, 163, 156, 98, 117, 51, 0, 11, 3, 229, 186, 148, 121, 105, 110, 103, 49, 0, 0, 10, 3, 230, 179, 155, 102, 97, 110, 52, 0, 9, 3, 229, 186, 147, 107, 117, 52, 0, 10, 3, 233, 153, 139, 108, 111, 117, 52, 0, 11, 3, 230, 183, 187, 116, 105, 97, 110, 49, 0, 9, 3, 229, 184, 131, 98, 117, 52, 0, 0, 10, 3, 229, 187, 154, 99, 104, 117, 50, 0, 9, 3, 232, 165, 170, 119, 97, 52, 0, 10, 3, 230, 178, 146, 109, 101, 105, 50, 0, 11, 3, 230, 181, 170, 108, 97, 110, 103, 52, 0, 10, 3, 229, 184, 130, 115, 104, 105, 52, 0, 9, 3, 230, 182, 178, 121, 101, 52, 0, 11, 3, 230, 183, 186, 113, 105, 97, 110, 51, 0, 0, 10, 3, 232, 163, 153, 113, 117, 110, 50, 0, 9, 3, 233, 157, 169, 103, 101, 50, 0, 10, 3, 230, 183, 185, 121, 97, 110, 49, 0, 10, 3, 229, 189, 169, 99, 97, 105, 51, 0, 13, 3, 233, 155, 153, 115, 104, 117, 97, 110, 103, 49, 0, 10, 3, 230, 177, 137, 104, 97, 110, 52, 0, 12, 3, 231, 174, 177, 120, 105, 97, 110, 103, 49, 0, 10, 3, 231, 170, 145, 121, 97, 111, 50, 0, 9, 3, 229, 184, 129, 98, 105, 52, 0, 10, 3, 230, 181, 169, 104, 97, 111, 52, 0, 11, 3, 231, 171, 153, 122, 104, 97, 110, 52, 0, 0, 9, 3, 233, 152, 128, 102, 97, 50, 0, 10, 3, 232, 167, 184, 99, 104, 117, 52, 0, 9, 3, 231, 168, 128, 120, 105, 49, 0, 10, 3, 233, 154, 144, 121, 105, 110, 51, 0, 11, 3, 233, 153, 136, 99, 104, 101, 110, 50, 0, 12, 3, 229, 188, 160, 122, 104, 97, 110, 103, 49, 0, 0, 9, 3, 230, 178, 143, 113, 105, 49, 0, 9, 3, 229, 188, 159, 100, 105, 52, 0, 11, 3, 231, 175, 183, 112, 101, 110, 103, 53, 0, 11, 3, 229, 176, 191, 110, 105, 97, 111, 52, 0, 9, 3, 229, 186, 143, 120, 117, 52, 0, 10, 3, 230, 183, 183, 104, 117, 110, 52, 0, 10, 3, 232, 152, 191, 108, 117, 111, 50, 0, 10, 3, 230, 177, 135, 104, 117, 105, 52, 0, 10, 3, 233, 154, 143, 115, 117, 105, 50, 0, 0, 10, 3, 233, 155, 150, 115, 117, 105, 49, 0, 10, 3, 231, 171, 150, 115, 104, 117, 52, 0, 9, 3, 228, 184, 190, 106, 117, 51, 0, 10, 3, 229, 190, 174, 119, 101, 105, 49, 0, 10, 3, 233, 154, 142, 106, 105, 101, 49, 0, 11, 3, 230, 180, 158, 100, 111, 110, 103, 52, 0, 10, 3, 233, 156, 158, 120, 105, 97, 50, 0, 9, 3, 233, 153, 134, 108, 117, 52, 0, 9, 3, 231, 160, 190, 108, 105, 52, 0, 9, 3, 231, 169, 134, 109, 117, 52, 0, 10, 3, 229, 176, 190, 119, 101, 105, 51, 0, 0, 10, 3, 232, 162, 141, 112, 97, 111, 50, 0, 11, 3, 229, 191, 181, 110, 105, 97, 110, 52, 0, 9, 3, 228, 184, 189, 108, 105, 52, 0, 9, 3, 233, 153, 133, 106, 105, 52, 0, 9, 3, 229, 185, 133, 102, 117, 50, 0, 11, 3, 233, 155, 149, 100, 105, 97, 111, 49, 0, 11, 3, 233, 158, 173, 98, 105, 97, 110, 49, 0, 9, 3, 230, 179, 149, 102, 97, 51, 0, 10, 3, 229, 176, 189, 106, 105, 110, 52, 0, 10, 3, 232, 161, 133, 120, 105, 110, 52, 0, 11, 3, 231, 174, 173, 106, 105, 97, 110, 52, 0, 9, 3, 232, 163, 149, 121, 117, 52, 0, 0, 9, 3, 233, 153, 132, 102, 117, 52, 0, 13, 3, 233, 156, 156, 115, 104, 117, 97, 110, 103, 49, 0, 0, 10, 3, 228, 184, 187, 122, 104, 117, 51, 0, 10, 3, 233, 159, 179, 121, 105, 110, 49, 0, 10, 3, 229, 187, 147, 107, 117, 111, 52, 0, 10, 3, 232, 162, 139, 100, 97, 105, 52, 0, 11, 3, 231, 174, 171, 120, 105, 97, 111, 49, 0, 9, 3, 231, 172, 155, 100, 105, 50, 0, 11, 3, 230, 183, 179, 99, 104, 117, 110, 50, 0, 0, 10, 3, 229, 176, 186, 99, 104, 105, 51, 0, 11, 3, 233, 157, 162, 109, 105, 97, 110, 52, 0, 10, 3, 233, 154, 138, 100, 117, 105, 52, 0, 13, 3, 229, 186, 138, 99, 104, 117, 97, 110, 103, 50, 0, 10, 3, 232, 166, 170, 113, 105, 110, 49, 0, 11, 3, 229, 189, 162, 120, 105, 110, 103, 50, 0, 11, 3, 233, 144, 186, 100, 97, 110, 103, 53, 0, 10, 3, 230, 168, 186, 104, 117, 97, 52, 0, 10, 3, 229, 190, 170, 120, 117, 110, 50, 0, 10, 3, 228, 184, 186, 119, 101, 105, 52, 0, 10, 3, 230, 177, 130, 113, 105, 117, 50, 0, 0, 10, 3, 230, 177, 129, 122, 104, 105, 49, 0, 10, 3, 231, 174, 169, 108, 117, 111, 50, 0, 9, 3, 231, 175, 177, 108, 105, 50, 0, 11, 3, 229, 191, 177, 99, 104, 101, 110, 50, 0, 10, 3, 228, 184, 185, 100, 97, 110, 49, 0, 10, 3, 230, 168, 185, 115, 104, 117, 52, 0, 11, 3, 230, 178, 137, 99, 104, 101, 110, 50, 0, 11, 3, 230, 183, 177, 115, 104, 101, 110, 49, 0, 0, 10, 3, 233, 157, 160, 107, 97, 111, 52, 0, 9, 3, 231, 160, 184, 122, 97, 50, 0, 12, 3, 230, 182, 168, 122, 104, 97, 110, 103, 51, 0, 10, 3, 229, 176, 184, 115, 104, 105, 49, 0, 10, 3, 232, 161, 128, 120, 117, 101, 52, 0, 11, 3, 232, 152, 184, 122, 104, 97, 110, 52, 0, 10, 3, 228, 184, 184, 119, 97, 110, 50, 0, 0, 9, 3, 230, 180, 151, 120, 105, 51, 0, 9, 3, 229, 177, 191, 121, 117, 51, 0, 10, 3, 233, 145, 191, 122, 97, 111, 50, 0, 10, 3, 232, 165, 159, 106, 105, 110, 49, 0, 0, 10, 3, 232, 153, 190, 120, 105, 97, 49, 0, 10, 3, 231, 175, 174, 108, 97, 110, 50, 0, 10, 3, 230, 182, 166, 114, 117, 110, 52, 0, 11, 3, 229, 186, 134, 113, 105, 110, 103, 52, 0, 10, 3, 233, 157, 158, 102, 101, 105, 49, 0, 11, 3, 233, 154, 134, 108, 111, 110, 103, 50, 0, 0, 11, 3, 233, 145, 189, 122, 117, 97, 110, 49, 0, 10, 3, 233, 144, 181, 116, 105, 101, 51, 0, 10, 3, 232, 153, 189, 115, 117, 105, 49, 0, 10, 3, 229, 188, 149, 121, 105, 110, 51, 0, 0, 9, 3, 232, 162, 132, 97, 111, 51, 0, 10, 3, 228, 184, 180, 108, 105, 110, 50, 0, 9, 3, 231, 172, 148, 98, 105, 51, 0, 9, 3, 233, 155, 140, 99, 105, 50, 0, 9, 3, 230, 179, 140, 109, 105, 52, 0, 9, 3, 231, 160, 180, 112, 111, 52, 0, 10, 3, 233, 145, 188, 108, 117, 111, 50, 0, 9, 3, 230, 182, 164, 100, 105, 50, 0, 11, 3, 231, 170, 132, 122, 104, 97, 105, 51, 0, 11, 3, 233, 157, 156, 106, 105, 110, 103, 52, 0, 13, 3, 229, 186, 132, 122, 104, 117, 97, 110, 103, 49, 0, 0, 11, 3, 229, 188, 147, 103, 111, 110, 103, 49, 0, 10, 3, 231, 170, 131, 113, 105, 101, 52, 0, 11, 3, 231, 173, 155, 115, 104, 97, 105, 49, 0, 9, 3, 231, 171, 139, 108, 105, 52, 0, 9, 3, 230, 178, 131, 119, 111, 52, 0, 11, 3, 229, 191, 171, 107, 117, 97, 105, 52, 0, 0, 12, 3, 228, 184, 178, 99, 104, 117, 97, 110, 52, 0, 9, 3, 230, 180, 146, 115, 97, 51, 0, 10, 3, 231, 171, 138, 113, 105, 101, 52, 0, 9, 3, 230, 179, 138, 112, 111, 49, 0, 0, 9, 3, 230, 182, 161, 119, 111, 49, 0, 11, 3, 231, 172, 145, 120, 105, 97, 111, 52, 0, 11, 3, 233, 157, 153, 106, 105, 110, 103, 52, 0, 11, 3, 231, 175, 169, 115, 104, 97, 105, 49, 0, 10, 3, 229, 176, 177, 106, 105, 117, 52, 0, 11, 3, 230, 179, 137, 113, 117, 97, 110, 50, 0, 11, 3, 231, 174, 161, 103, 117, 97, 110, 51, 0, 9, 3, 229, 190, 161, 121, 117, 52, 0, 9, 3, 231, 170, 129, 116, 117, 49, 0, 9, 3, 229, 177, 185, 121, 105, 52, 0, 11, 3, 229, 187, 137, 108, 105, 97, 110, 50, 0, 0, 9, 3, 233, 158, 160, 106, 117, 49, 0, 11, 3, 230, 183, 168, 106, 105, 110, 103, 52, 0, 10, 3, 229, 187, 136, 115, 104, 97, 52, 0, 9, 3, 232, 164, 144, 104, 101, 52, 0, 11, 3, 228, 184, 176, 102, 101, 110, 103, 49, 0, 11, 3, 231, 160, 176, 112, 101, 110, 103, 49, 0, 0, 10, 3, 229, 191, 167, 121, 111, 117, 49, 0, 10, 3, 233, 159, 167, 114, 101, 110, 52, 0, 10, 3, 229, 188, 143, 115, 104, 105, 52, 0, 9, 3, 228, 186, 191, 121, 105, 52, 0, 9, 3, 233, 155, 135, 103, 117, 52, 0, 0, 9, 3, 231, 173, 150, 99, 101, 52, 0, 11, 3, 229, 190, 158, 99, 111, 110, 103, 50, 0, 10, 3, 232, 167, 166, 99, 104, 117, 52, 0, 10, 3, 233, 156, 142, 115, 104, 97, 52, 0, 11, 3, 231, 162, 190, 110, 105, 97, 110, 51, 0, 11, 3, 233, 144, 174, 108, 105, 97, 110, 50, 0, 9, 3, 233, 155, 134, 106, 105, 50, 0, 9, 3, 232, 165, 150, 97, 111, 51, 0, 0, 12, 3, 228, 184, 173, 122, 104, 111, 110, 103, 49, 0, 9, 3, 229, 189, 149, 108, 117, 52, 0, 13, 3, 232, 163, 133, 122, 104, 117, 97, 110, 103, 49, 0, 0, 10, 3, 230, 179, 132, 120, 105, 101, 52, 0, 9, 3, 231, 173, 148, 100, 97, 50, 0, 9, 3, 231, 162, 188, 109, 97, 51, 0, 11, 3, 231, 171, 132, 99, 117, 97, 110, 52, 0, 12, 3, 233, 155, 132, 120, 105, 111, 110, 103, 50, 0, 0, 9, 3, 228, 184, 171, 121, 97, 49, 0, 11, 3, 233, 146, 187, 122, 117, 97, 110, 49, 0, 11, 3, 230, 180, 139, 121, 97, 110, 103, 50, 0, 9, 3, 228, 185, 179, 114, 117, 51, 0, 11, 3, 230, 181, 147, 110, 111, 110, 103, 50, 0, 10, 3, 232, 167, 163, 106, 105, 101, 51, 0, 10, 3, 230, 182, 155, 116, 97, 111, 49, 0, 10, 3, 230, 170, 187, 107, 97, 110, 51, 0, 11, 3, 229, 189, 147, 100, 97, 110, 103, 49, 0, 0, 10, 3, 232, 163, 130, 108, 105, 101, 52, 0, 11, 3, 233, 157, 146, 113, 105, 110, 103, 49, 0, 10, 3, 229, 189, 146, 103, 117, 105, 49, 0, 11, 3, 231, 173, 146, 116, 111, 110, 103, 51, 0, 10, 3, 228, 186, 186, 114, 101, 110, 50, 0, 12, 3, 233, 145, 178, 120, 105, 97, 110, 103, 49, 0, 12, 3, 229, 187, 130, 120, 105, 97, 110, 103, 49, 0, 9, 3, 228, 184, 170, 103, 101, 53, 0, 10, 3, 231, 162, 186, 113, 117, 101, 52, 0, 11, 3, 230, 168, 170, 104, 101, 110, 103, 50, 0, 0, 10, 3, 230, 183, 161, 100, 97, 110, 52, 0, 11, 3, 229, 177, 177, 115, 104, 97, 110, 49, 0, 10, 3, 230, 181, 145, 104, 117, 110, 50, 0, 9, 3, 229, 187, 129, 99, 101, 52, 0, 10, 3, 232, 163, 129, 99, 97, 105, 50, 0, 11, 3, 228, 185, 177, 108, 117, 97, 110, 52, 0, 10, 3, 231, 173, 145, 122, 104, 117, 52, 0, 10, 3, 233, 156, 137, 109, 101, 105, 50, 0, 12, 3, 230, 179, 129, 107, 117, 97, 110, 103, 52, 0, 0, 10, 3, 228, 185, 176, 109, 97, 105, 51, 0, 12, 3, 229, 191, 160, 122, 104, 111, 110, 103, 49, 0, 10, 3, 233, 155, 128, 113, 117, 101, 52, 0, 12, 3, 231, 173, 144, 107, 117, 97, 110, 103, 49, 0, 9, 3, 229, 178, 184, 97, 110, 52, 0, 10, 3, 233, 145, 176, 121, 97, 111, 52, 0, 10, 3, 229, 190, 152, 112, 97, 105, 50, 0, 0, 11, 3, 229, 186, 183, 107, 97, 110, 103, 49, 0, 9, 3, 232, 173, 143, 106, 105, 49, 0, 10, 3, 231, 171, 191, 103, 97, 110, 49, 0, 11, 3, 229, 187, 191, 110, 105, 97, 110, 52, 0, 9, 3, 230, 191, 159, 106, 105, 52, 0, 11, 3, 230, 176, 167, 121, 97, 110, 103, 51, 0, 0, 11, 3, 233, 166, 150, 115, 104, 111, 117, 51, 0, 10, 3, 229, 184, 166, 100, 97, 105, 52, 0, 9, 3, 230, 188, 134, 113, 105, 49, 0, 10, 3, 232, 175, 158, 100, 97, 110, 52, 0, 11, 3, 231, 183, 158, 100, 117, 97, 110, 52, 0, 9, 3, 233, 155, 190, 119, 117, 52, 0, 9, 3, 233, 154, 182, 108, 105, 52, 0, 0, 10, 3, 233, 167, 157, 116, 117, 111, 53, 0, 11, 3, 233, 164, 133, 98, 105, 110, 103, 51, 0, 9, 3, 231, 171, 189, 121, 117, 50, 0, 11, 3, 231, 180, 133, 104, 111, 110, 103, 50, 0, 10, 3, 232, 175, 157, 104, 117, 97, 52, 0, 12, 3, 229, 184, 165, 115, 104, 117, 97, 105, 52, 0, 0, 11, 3, 232, 161, 172, 99, 104, 101, 110, 52, 0, 9, 3, 230, 179, 188, 112, 111, 53, 0, 10, 3, 231, 180, 132, 121, 117, 101, 49, 0, 0, 9, 3, 230, 176, 163, 113, 105, 52, 0, 11, 3, 231, 182, 147, 106, 105, 110, 103, 49, 0, 10, 3, 233, 167, 155, 115, 104, 105, 51, 0, 11, 3, 232, 161, 171, 115, 104, 97, 110, 49, 0, 11, 3, 233, 164, 131, 106, 105, 97, 111, 51, 0, 11, 3, 229, 185, 171, 98, 97, 110, 103, 49, 0, 11, 3, 233, 155, 187, 100, 105, 97, 110, 52, 0, 11, 3, 232, 174, 147, 114, 97, 110, 103, 52, 0, 9, 3, 230, 178, 179, 104, 101, 50, 0, 0, 11, 3, 229, 187, 186, 106, 105, 97, 110, 52, 0, 11, 3, 230, 177, 170, 119, 97, 110, 103, 49, 0, 12, 3, 232, 175, 154, 99, 104, 101, 110, 103, 50, 0, 11, 3, 230, 188, 130, 112, 105, 97, 111, 52, 0, 11, 3, 231, 183, 154, 120, 105, 97, 110, 52, 0, 10, 3, 233, 153, 170, 112, 101, 105, 50, 0, 10, 3, 232, 172, 130, 119, 101, 105, 52, 0, 11, 3, 230, 176, 162, 113, 105, 110, 103, 49, 0, 10, 3, 233, 166, 146, 109, 97, 110, 50, 0, 0, 9, 3, 230, 188, 129, 121, 117, 50, 0, 10, 3, 231, 169, 169, 119, 101, 110, 51, 0, 10, 3, 233, 154, 177, 121, 105, 110, 51, 0, 11, 3, 233, 153, 169, 120, 105, 97, 110, 51, 0, 10, 3, 232, 163, 185, 103, 117, 111, 51, 0, 10, 3, 231, 171, 185, 122, 104, 117, 50, 0, 9, 3, 232, 162, 177, 102, 117, 53, 0, 10, 3, 233, 155, 185, 98, 97, 111, 50, 0, 0, 9, 3, 231, 180, 128, 106, 105, 52, 0, 11, 3, 231, 168, 160, 99, 104, 111, 117, 50, 0, 11, 3, 232, 161, 168, 98, 105, 97, 111, 51, 0, 10, 3, 232, 172, 128, 109, 111, 117, 50, 0, 0, 9, 3, 232, 160, 159, 108, 97, 52, 0, 10, 3, 232, 175, 151, 115, 104, 105, 49, 0, 10, 3, 233, 155, 183, 108, 101, 105, 50, 0, 10, 3, 231, 170, 175, 121, 97, 111, 50, 0, 10, 3, 233, 152, 159, 100, 117, 105, 52, 0, 0, 10, 3, 230, 180, 190, 112, 97, 105, 52, 0, 12, 3, 231, 170, 174, 113, 105, 111, 110, 103, 50, 0, 11, 3, 233, 155, 182, 108, 105, 110, 103, 50, 0, 11, 3, 230, 190, 142, 112, 101, 110, 103, 49, 0, 10, 3, 229, 187, 182, 121, 97, 110, 50, 0, 11, 3, 231, 171, 182, 106, 105, 110, 103, 52, 0, 0, 10, 3, 232, 175, 149, 115, 104, 105, 52, 0, 9, 3, 229, 184, 157, 100, 105, 52, 0, 11, 3, 230, 179, 181, 98, 101, 110, 103, 52, 0, 10, 3, 230, 191, 149, 115, 104, 105, 49, 0, 9, 3, 232, 162, 173, 120, 105, 50, 0, 10, 3, 233, 165, 133, 109, 97, 110, 50, 0, 11, 3, 229, 186, 173, 116, 105, 110, 103, 50, 0, 10, 3, 233, 167, 149, 106, 105, 97, 52, 0, 9, 3, 232, 161, 165, 98, 117, 51, 0, 0, 11, 3, 230, 177, 164, 116, 97, 110, 103, 49, 0, 10, 3, 229, 184, 156, 122, 104, 105, 52, 0, 10, 3, 233, 153, 164, 99, 104, 117, 50, 0, 11, 3, 231, 172, 188, 108, 111, 110, 103, 50, 0, 9, 3, 231, 181, 132, 122, 117, 51, 0, 0, 10, 3, 232, 162, 171, 98, 101, 105, 52, 0, 11, 3, 229, 187, 179, 116, 105, 110, 103, 49, 0, 9, 3, 232, 161, 163, 121, 105, 49, 0, 9, 3, 230, 178, 171, 109, 111, 52, 0, 10, 3, 230, 176, 155, 102, 101, 110, 49, 0, 9, 3, 229, 185, 163, 98, 105, 52, 0, 11, 3, 230, 179, 179, 121, 111, 110, 103, 51, 0, 11, 3, 233, 153, 163, 122, 104, 101, 110, 52, 0, 10, 3, 230, 180, 187, 104, 117, 111, 50, 0, 12, 3, 232, 163, 179, 115, 104, 97, 110, 103, 53, 0, 9, 3, 229, 186, 171, 107, 117, 52, 0, 11, 3, 233, 166, 139, 99, 104, 97, 110, 50, 0, 0, 11, 3, 233, 154, 170, 120, 105, 97, 110, 51, 0, 11, 3, 233, 153, 162, 121, 117, 97, 110, 52, 0, 9, 3, 231, 183, 146, 120, 117, 52, 0, 9, 3, 233, 167, 146, 106, 117, 49, 0, 12, 3, 231, 181, 130, 122, 104, 111, 110, 103, 49, 0, 12, 3, 229, 188, 186, 113, 105, 97, 110, 103, 50, 0, 11, 3, 229, 184, 154, 122, 104, 111, 117, 53, 0, 10, 3, 231, 168, 154, 122, 104, 105, 52, 0, 11, 3, 232, 174, 138, 98, 105, 97, 110, 52, 0, 0, 9, 3, 230, 177, 161, 119, 117, 49, 0, 11, 3, 232, 161, 161, 104, 101, 110, 103, 50, 0, 10, 3, 229, 188, 185, 100, 97, 110, 52, 0, 9, 3, 231, 170, 169, 119, 111, 49, 0, 9, 3, 232, 175, 145, 121, 105, 52, 0, 10, 3, 233, 153, 161, 100, 111, 117, 51, 0, 0, 9, 3, 233, 156, 184, 98, 97, 52, 0, 10, 3, 230, 177, 160, 99, 104, 105, 50, 0, 11, 3, 229, 184, 152, 108, 105, 97, 110, 50, 0, 10, 3, 233, 154, 168, 115, 117, 105, 50, 0, 10, 3, 233, 167, 144, 122, 104, 117, 52, 0, 0, 9, 3, 232, 165, 191, 120, 105, 53, 0, 10, 3, 229, 186, 167, 122, 117, 111, 52, 0, 10, 3, 233, 154, 167, 115, 117, 105, 52, 0, 11, 3, 231, 171, 175, 100, 117, 97, 110, 49, 0, 12, 3, 230, 177, 159, 106, 105, 97, 110, 103, 49, 0, 12, 3, 229, 188, 183, 113, 105, 97, 110, 103, 50, 0, 10, 3, 229, 185, 159, 122, 104, 105, 52, 0, 0, 11, 3, 233, 166, 134, 103, 117, 97, 110, 51, 0, 12, 3, 230, 180, 182, 120, 105, 111, 110, 103, 49, 0, 9, 3, 229, 186, 166, 100, 117, 52, 0, 11, 3, 231, 173, 190, 113, 105, 97, 110, 49, 0, 11, 3, 230, 190, 134, 106, 105, 97, 111, 49, 0, 11, 3, 230, 177, 158, 103, 111, 110, 103, 51, 0, 0, 11, 3, 233, 166, 133, 120, 105, 97, 110, 52, 0, 10, 3, 231, 171, 173, 106, 105, 101, 50, 0, 9, 3, 232, 160, 149, 114, 117, 50, 0, 9, 3, 230, 178, 165, 108, 105, 52, 0, 9, 3, 229, 184, 149, 112, 97, 52, 0, 9, 3, 232, 175, 141, 99, 105, 50, 0, 12, 3, 229, 188, 181, 122, 104, 97, 110, 103, 49, 0, 0, 10, 3, 233, 152, 148, 107, 117, 111, 52, 0, 9, 3, 230, 176, 148, 113, 105, 52, 0, 9, 3, 229, 189, 188, 98, 105, 51, 0, 0, 10, 3, 229, 189, 187, 99, 104, 101, 52, 0, 11, 3, 230, 176, 147, 109, 97, 110, 103, 50, 0, 10, 3, 230, 177, 155, 120, 117, 110, 52, 0, 10, 3, 232, 161, 155, 119, 101, 105, 52, 0, 0, 9, 3, 233, 156, 178, 108, 117, 52, 0, 10, 3, 231, 183, 138, 106, 105, 110, 51, 0, 10, 3, 233, 155, 170, 120, 117, 101, 51, 0, 10, 3, 230, 179, 170, 108, 101, 105, 52, 0, 9, 3, 232, 164, 178, 107, 117, 52, 0, 11, 3, 230, 180, 178, 122, 104, 111, 117, 49, 0, 11, 3, 232, 175, 138, 122, 104, 101, 110, 51, 0, 0, 10, 3, 229, 188, 177, 114, 117, 111, 52, 0, 10, 3, 230, 176, 145, 109, 105, 110, 50, 0, 9, 3, 232, 175, 137, 115, 117, 53, 0, 11, 3, 231, 182, 129, 98, 97, 110, 103, 51, 0, 9, 3, 229, 189, 185, 121, 105, 52, 0, 10, 3, 230, 178, 161, 109, 101, 105, 50, 0, 9, 3, 232, 161, 153, 121, 97, 50, 0, 0, 9, 3, 232, 174, 128, 100, 117, 50, 0, 9, 3, 233, 155, 168, 121, 117, 51, 0, 11, 3, 233, 152, 144, 99, 104, 97, 110, 51, 0, 10, 3, 230, 181, 184, 106, 105, 110, 52, 0, 12, 3, 229, 184, 144, 122, 104, 97, 110, 103, 52, 0, 10, 3, 230, 179, 168, 122, 104, 117, 52, 0, 0, 10, 3, 229, 188, 175, 119, 97, 110, 49, 0, 10, 3, 230, 178, 159, 103, 111, 117, 49, 0, 11, 3, 231, 173, 183, 107, 117, 97, 105, 52, 0, 10, 3, 231, 169, 151, 115, 117, 105, 52, 0, 10, 3, 232, 161, 151, 106, 105, 101, 49, 0, 9, 3, 231, 170, 159, 107, 117, 49, 0, 10, 3, 230, 176, 143, 115, 104, 105, 52, 0, 10, 3, 229, 186, 159, 102, 101, 105, 52, 0, 10, 3, 230, 181, 183, 104, 97, 105, 51, 0, 10, 3, 230, 177, 151, 104, 97, 110, 52, 0, 0, 11, 3, 229, 186, 158, 112, 97, 110, 103, 50, 0, 10, 3, 232, 175, 134, 115, 104, 105, 53, 0, 11, 3, 231, 168, 142, 115, 104, 117, 105, 52, 0, 0, 11, 3, 231, 168, 141, 115, 104, 97, 111, 49, 0, 10, 3, 232, 166, 189, 108, 97, 110, 51, 0, 11, 3, 231, 171, 165, 116, 111, 110, 103, 50, 0, 9, 3, 229, 185, 149, 109, 117, 52, 0, 9, 3, 231, 170, 157, 119, 111, 49, 0, 9, 3, 230, 179, 165, 110, 105, 50, 0, 0, 12, 3, 233, 154, 156, 122, 104, 97, 110, 103, 52, 0, 9, 3, 232, 163, 164, 107, 117, 52, 0, 10, 3, 233, 157, 180, 120, 117, 101, 49, 0, 9, 3, 229, 186, 156, 102, 117, 51, 0, 11, 3, 231, 170, 156, 99, 117, 97, 110, 52, 0, 9, 3, 232, 162, 156, 119, 97, 52, 0, 9, 3, 229, 184, 140, 120, 105, 49, 0, 11, 3, 232, 175, 132, 112, 105, 110, 103, 50, 0, 12, 3, 230, 182, 188, 108, 105, 97, 110, 103, 50, 0, 11, 3, 232, 161, 148, 120, 105, 97, 110, 50, 0, 9, 3, 231, 172, 172, 100, 105, 52, 0, 0, 12, 3, 229, 187, 163, 103, 117, 97, 110, 103, 51, 0, 11, 3, 230, 191, 131, 110, 111, 110, 103, 50, 0, 10, 3, 230, 178, 155, 112, 101, 105, 52, 0, 10, 3, 233, 155, 163, 110, 97, 110, 50, 0, 12, 3, 231, 168, 139, 99, 104, 101, 110, 103, 50, 0, 9, 3, 233, 154, 155, 106, 105, 52, 0, 9, 3, 230, 179, 163, 113, 105, 52, 0, 0, 9, 3, 230, 179, 162, 98, 111, 49, 0, 10, 3, 232, 166, 186, 106, 117, 101, 50, 0, 9, 3, 232, 165, 178, 120, 105, 50, 0, 10, 3, 229, 187, 162, 102, 101, 105, 52, 0, 11, 3, 230, 180, 170, 104, 111, 110, 103, 50, 0, 9, 3, 233, 155, 162, 108, 105, 50, 0, 0, 10, 3, 229, 190, 185, 99, 104, 101, 52, 0, 10, 3, 230, 178, 153, 115, 104, 97, 49, 0, 9, 3, 233, 167, 129, 98, 111, 50, 0, 9, 3, 232, 163, 161, 108, 105, 53, 0, 11, 3, 230, 191, 129, 122, 104, 117, 111, 50, 0, 9, 3, 233, 154, 153, 120, 105, 52, 0, 11, 3, 229, 186, 153, 109, 105, 97, 111, 52, 0, 12, 3, 232, 175, 129, 122, 104, 101, 110, 103, 52, 0, 10, 3, 230, 179, 161, 112, 97, 111, 52, 0, 11, 3, 229, 189, 177, 121, 105, 110, 103, 51, 0, 0, 11, 3, 233, 153, 144, 120, 105, 97, 110, 52, 0, 9, 3, 230, 191, 128, 106, 105, 49, 0, 10, 3, 231, 172, 168, 98, 101, 110, 52, 0, 11, 3, 230, 176, 136, 122, 104, 97, 110, 49, 0, 10, 3, 231, 168, 136, 103, 97, 110, 51, 0, 9, 3, 233, 154, 152, 97, 105, 52, 0, 10, 3, 229, 184, 136, 115, 104, 105, 49, 0, 12, 3, 231, 171, 160, 122, 104, 97, 110, 103, 49, 0, 12, 3, 229, 187, 160, 99, 104, 97, 110, 103, 51, 0, 0, 10, 3, 231, 180, 167, 106, 105, 110, 51, 0, 10, 3, 233, 161, 143, 121, 97, 110, 50, 0, 9, 3, 231, 176, 135, 99, 117, 52, 0, 9, 3, 231, 178, 151, 99, 117, 49, 0, 10, 3, 233, 163, 159, 115, 104, 105, 50, 0, 9, 3, 232, 173, 175, 121, 105, 52, 0, 9, 3, 233, 162, 151, 107, 101, 49, 0, 10, 3, 231, 179, 159, 122, 97, 111, 49, 0, 0, 10, 3, 233, 163, 158, 102, 101, 105, 49, 0, 10, 3, 233, 165, 174, 121, 105, 110, 51, 0, 10, 3, 231, 179, 158, 102, 101, 110, 52, 0, 11, 3, 233, 162, 150, 121, 105, 110, 103, 51, 0, 9, 3, 232, 175, 190, 107, 101, 52, 0, 9, 3, 232, 174, 182, 121, 97, 52, 0, 11, 3, 230, 189, 174, 99, 104, 97, 111, 50, 0, 11, 3, 233, 160, 134, 115, 104, 117, 110, 52, 0, 0, 10, 3, 232, 170, 149, 100, 97, 110, 52, 0, 10, 3, 230, 189, 173, 116, 97, 110, 50, 0, 8, 3, 233, 161, 141, 101, 50, 0, 9, 3, 231, 177, 141, 106, 105, 50, 0, 12, 3, 233, 160, 133, 120, 105, 97, 110, 103, 52, 0, 11, 3, 230, 184, 133, 113, 105, 110, 103, 49, 0, 10, 3, 233, 165, 173, 102, 97, 110, 52, 0, 0, 11, 3, 231, 182, 180, 122, 104, 117, 105, 53, 0, 9, 3, 233, 161, 140, 116, 105, 50, 0, 9, 3, 232, 173, 172, 112, 105, 52, 0, 0, 11, 3, 233, 160, 131, 113, 105, 110, 103, 51, 0, 10, 3, 232, 170, 147, 115, 104, 105, 52, 0, 10, 3, 233, 166, 179, 99, 104, 105, 50, 0, 10, 3, 233, 163, 155, 102, 101, 105, 49, 0, 9, 3, 232, 175, 187, 100, 117, 50, 0, 0, 10, 3, 230, 187, 154, 103, 117, 110, 51, 0, 11, 3, 232, 168, 130, 100, 105, 110, 103, 52, 0, 10, 3, 231, 180, 162, 115, 117, 111, 51, 0, 9, 3, 231, 178, 146, 108, 105, 52, 0, 11, 3, 230, 191, 186, 106, 105, 97, 110, 52, 0, 12, 3, 232, 174, 178, 106, 105, 97, 110, 103, 51, 0, 11, 3, 233, 160, 130, 100, 105, 110, 103, 51, 0, 10, 3, 230, 185, 138, 99, 111, 117, 52, 0, 11, 3, 231, 182, 178, 119, 97, 110, 103, 51, 0, 10, 3, 230, 188, 162, 104, 97, 110, 52, 0, 9, 3, 232, 170, 146, 101, 105, 50, 0, 0, 11, 3, 231, 182, 177, 103, 97, 110, 103, 49, 0, 9, 3, 233, 160, 129, 121, 101, 52, 0, 10, 3, 233, 162, 145, 112, 105, 110, 50, 0, 10, 3, 233, 166, 177, 116, 117, 111, 50, 0, 10, 3, 231, 179, 153, 99, 97, 111, 49, 0, 11, 3, 230, 190, 177, 100, 105, 97, 110, 52, 0, 11, 3, 231, 180, 161, 102, 97, 110, 103, 51, 0, 11, 3, 233, 164, 161, 120, 105, 97, 110, 52, 0, 0, 9, 3, 231, 180, 160, 115, 117, 52, 0, 11, 3, 230, 186, 144, 121, 117, 97, 110, 50, 0, 10, 3, 232, 168, 128, 121, 97, 110, 50, 0, 11, 3, 231, 181, 168, 114, 111, 110, 103, 50, 0, 9, 3, 232, 174, 176, 106, 105, 52, 0, 9, 3, 230, 188, 160, 109, 111, 52, 0, 11, 3, 233, 163, 152, 112, 105, 97, 111, 49, 0, 10, 3, 232, 175, 184, 122, 104, 117, 49, 0, 10, 3, 232, 172, 160, 121, 97, 111, 50, 0, 0, 11, 3, 232, 175, 183, 113, 105, 110, 103, 51, 0, 10, 3, 232, 174, 175, 120, 117, 110, 52, 0, 8, 3, 233, 152, 191, 97, 49, 0, 10, 3, 231, 168, 191, 103, 97, 111, 51, 0, 0, 9, 3, 232, 174, 174, 121, 105, 52, 0, 9, 3, 233, 161, 134, 107, 101, 49, 0, 10, 3, 232, 171, 150, 108, 117, 110, 52, 0, 11, 3, 232, 173, 166, 106, 105, 110, 103, 51, 0, 10, 3, 231, 181, 166, 103, 101, 105, 51, 0, 11, 3, 231, 179, 150, 116, 97, 110, 103, 50, 0, 9, 3, 232, 175, 182, 101, 105, 50, 0, 0, 10, 3, 232, 172, 157, 120, 105, 101, 52, 0, 10, 3, 229, 184, 189, 109, 97, 111, 52, 0, 10, 3, 231, 182, 173, 119, 101, 105, 50, 0, 9, 3, 233, 165, 165, 106, 105, 49, 0, 11, 3, 232, 175, 181, 115, 111, 110, 103, 52, 0, 10, 3, 232, 170, 141, 114, 101, 110, 52, 0, 10, 3, 232, 174, 173, 120, 117, 110, 52, 0, 10, 3, 231, 179, 149, 103, 97, 111, 49, 0, 0, 10, 3, 230, 189, 164, 114, 117, 110, 52, 0, 11, 3, 231, 183, 180, 108, 105, 97, 110, 52, 0, 11, 3, 232, 175, 180, 115, 104, 117, 111, 49, 0, 10, 3, 230, 187, 148, 116, 97, 111, 49, 0, 10, 3, 231, 168, 188, 106, 105, 97, 53, 0, 9, 3, 233, 166, 172, 109, 97, 51, 0, 0, 10, 3, 231, 168, 187, 100, 97, 111, 52, 0, 10, 3, 231, 177, 131, 108, 97, 110, 50, 0, 12, 3, 232, 172, 155, 106, 105, 97, 110, 103, 51, 0, 9, 3, 233, 152, 187, 122, 117, 51, 0, 10, 3, 230, 185, 131, 112, 97, 105, 52, 0, 10, 3, 231, 180, 155, 102, 101, 110, 49, 0, 0, 12, 3, 232, 171, 146, 108, 105, 97, 110, 103, 52, 0, 9, 3, 231, 180, 154, 106, 105, 50, 0, 10, 3, 233, 162, 138, 106, 105, 97, 50, 0, 11, 3, 231, 181, 162, 120, 117, 97, 110, 52, 0, 0, 10, 3, 231, 180, 153, 122, 104, 105, 51, 0, 10, 3, 230, 186, 137, 103, 97, 105, 52, 0, 10, 3, 232, 175, 177, 121, 111, 117, 52, 0, 9, 3, 232, 170, 137, 121, 117, 52, 0, 10, 3, 230, 191, 177, 98, 105, 110, 49, 0, 10, 3, 231, 181, 161, 108, 117, 111, 52, 0, 10, 3, 230, 187, 145, 104, 117, 97, 50, 0, 11, 3, 232, 174, 169, 114, 97, 110, 103, 52, 0, 10, 3, 231, 178, 137, 102, 101, 110, 51, 0, 10, 3, 233, 167, 177, 108, 117, 111, 52, 0, 11, 3, 232, 172, 153, 113, 105, 97, 110, 49, 0, 0, 11, 3, 233, 162, 136, 106, 105, 110, 103, 51, 0, 11, 3, 230, 176, 184, 121, 111, 110, 103, 51, 0, 10, 3, 232, 174, 168, 116, 97, 111, 51, 0, 12, 3, 229, 184, 184, 99, 104, 97, 110, 103, 50, 0, 0, 10, 3, 231, 180, 151, 115, 104, 97, 49, 0, 10, 3, 231, 183, 175, 119, 101, 105, 51, 0, 12, 3, 231, 169, 191, 99, 104, 117, 97, 110, 49, 0, 12, 3, 229, 185, 191, 103, 117, 97, 110, 103, 51, 0, 9, 3, 232, 175, 175, 119, 117, 52, 0, 9, 3, 233, 162, 135, 112, 111, 49, 0, 0, 10, 3, 232, 160, 182, 99, 97, 110, 50, 0, 11, 3, 233, 165, 158, 99, 104, 97, 110, 50, 0, 9, 3, 229, 185, 190, 106, 105, 51, 0, 11, 3, 233, 162, 134, 108, 105, 110, 103, 51, 0, 10, 3, 233, 152, 182, 106, 105, 101, 49, 0, 11, 3, 233, 163, 142, 102, 101, 110, 103, 49, 0, 10, 3, 229, 184, 182, 100, 97, 105, 52, 0, 0, 9, 3, 232, 174, 165, 106, 105, 49, 0, 9, 3, 230, 177, 189, 113, 105, 52, 0, 11, 3, 230, 186, 133, 106, 105, 97, 110, 52, 0, 11, 3, 233, 153, 189, 121, 97, 110, 103, 50, 0, 11, 3, 233, 152, 181, 122, 104, 101, 110, 52, 0, 9, 3, 232, 175, 173, 121, 117, 51, 0, 0, 9, 3, 232, 175, 172, 119, 117, 49, 0, 9, 3, 233, 162, 132, 121, 117, 52, 0, 9, 3, 230, 187, 140, 100, 105, 50, 0, 10, 3, 232, 174, 164, 114, 101, 110, 52, 0, 10, 3, 230, 188, 148, 121, 97, 110, 51, 0, 10, 3, 229, 185, 188, 121, 111, 117, 52, 0, 10, 3, 233, 152, 180, 121, 105, 110, 49, 0, 11, 3, 230, 189, 156, 113, 105, 97, 110, 50, 0, 11, 3, 230, 176, 180, 115, 104, 117, 105, 51, 0, 11, 3, 231, 180, 148, 99, 104, 117, 110, 50, 0, 0, 10, 3, 230, 186, 131, 107, 117, 105, 52, 0, 11, 3, 230, 189, 155, 113, 105, 97, 110, 50, 0, 9, 3, 230, 187, 139, 122, 105, 49, 0, 12, 3, 229, 184, 179, 122, 104, 97, 110, 103, 52, 0, 10, 3, 231, 168, 179, 119, 101, 110, 51, 0, 10, 3, 232, 175, 171, 106, 105, 101, 52, 0, 8, 3, 233, 164, 147, 101, 52, 0, 11, 3, 229, 185, 187, 104, 117, 97, 110, 52, 0, 11, 3, 233, 152, 179, 121, 97, 110, 103, 50, 0, 10, 3, 230, 191, 171, 108, 97, 110, 52, 0, 11, 3, 232, 171, 139, 113, 105, 110, 103, 51, 0, 0, 11, 3, 233, 162, 130, 115, 111, 110, 103, 52, 0, 10, 3, 230, 177, 186, 106, 117, 101, 50, 0, 11, 3, 232, 174, 162, 100, 105, 110, 103, 52, 0, 11, 3, 233, 152, 178, 102, 97, 110, 103, 50, 0, 11, 3, 231, 182, 162, 99, 104, 111, 117, 50, 0, 11, 3, 231, 169, 186, 107, 111, 110, 103, 49, 0, 9, 3, 231, 179, 138, 104, 117, 53, 0, 0, 10, 3, 233, 162, 129, 98, 97, 110, 49, 0, 10, 3, 230, 190, 161, 122, 97, 111, 51, 0, 12, 3, 230, 177, 185, 120, 105, 111, 110, 103, 49, 0, 11, 3, 231, 183, 169, 104, 117, 97, 110, 51, 0, 9, 3, 232, 174, 161, 106, 105, 52, 0, 12, 3, 231, 168, 177, 99, 104, 101, 110, 103, 49, 0, 0, 10, 3, 231, 180, 144, 110, 105, 117, 51, 0, 11, 3, 231, 183, 168, 98, 105, 97, 110, 49, 0, 10, 3, 233, 164, 144, 99, 97, 110, 49, 0, 11, 3, 229, 185, 184, 120, 105, 110, 103, 52, 0, 10, 3, 232, 173, 152, 115, 104, 105, 53, 0, 9, 3, 233, 153, 184, 108, 117, 52, 0, 9, 3, 231, 182, 160, 108, 118, 52, 0, 0, 12, 3, 231, 169, 183, 113, 105, 111, 110, 103, 50, 0, 10, 3, 230, 178, 191, 121, 97, 110, 50, 0, 10, 3, 232, 175, 167, 99, 104, 97, 52, 0, 10, 3, 230, 188, 143, 108, 111, 117, 52, 0, 11, 3, 233, 153, 183, 120, 105, 97, 110, 52, 0, 11, 3, 231, 170, 191, 108, 111, 110, 103, 53, 0, 10, 3, 232, 171, 135, 116, 97, 110, 50, 0, 0, 12, 3, 231, 168, 174, 122, 104, 111, 110, 103, 51, 0, 11, 3, 229, 184, 174, 98, 97, 110, 103, 49, 0, 10, 3, 233, 154, 190, 110, 97, 110, 50, 0, 10, 3, 233, 153, 182, 116, 97, 111, 50, 0, 11, 3, 230, 178, 190, 122, 104, 97, 110, 49, 0, 10, 3, 230, 176, 174, 100, 97, 110, 52, 0, 11, 3, 229, 185, 182, 98, 105, 110, 103, 52, 0, 12, 3, 232, 175, 166, 120, 105, 97, 110, 103, 50, 0, 10, 3, 231, 169, 182, 106, 105, 117, 49, 0, 0, 10, 3, 232, 175, 165, 103, 97, 105, 49, 0, 10, 3, 231, 181, 149, 106, 117, 101, 50, 0, 11, 3, 233, 153, 181, 108, 105, 110, 103, 50, 0, 9, 3, 229, 184, 173, 120, 105, 50, 0, 10, 3, 230, 187, 133, 109, 105, 101, 52, 0, 9, 3, 231, 180, 141, 110, 97, 52, 0, 0, 11, 3, 231, 182, 156, 122, 111, 110, 103, 49, 0, 11, 3, 233, 163, 132, 112, 105, 97, 111, 49, 0, 10, 3, 230, 189, 148, 106, 105, 101, 50, 0, 11, 3, 229, 185, 180, 110, 105, 97, 110, 50, 0, 10, 3, 230, 191, 164, 116, 97, 111, 49, 0, 0, 10, 3, 229, 184, 171, 115, 104, 105, 49, 0, 11, 3, 233, 153, 179, 99, 104, 101, 110, 50, 0, 10, 3, 231, 180, 139, 119, 101, 110, 50, 0, 11, 3, 229, 185, 179, 112, 105, 110, 103, 50, 0, 10, 3, 230, 178, 187, 122, 104, 105, 52, 0, 11, 3, 230, 176, 171, 113, 105, 110, 103, 49, 0, 11, 3, 231, 183, 163, 121, 117, 97, 110, 50, 0, 0, 6, 20, 201, 2, 0, 0, 49, 0, 0, 0, 202, 2, 0, 0, 50, 0, 0, 0, 199, 2, 0, 0, 51, 0, 0, 0, 203, 2, 0, 0, 52, 0, 0, 0, 1, 1, 0, 0, 97, 0, 49, 0, 225, 0, 0, 0, 97, 0, 50, 0, 3, 1, 0, 0, 97, 0, 51, 0, 206, 1, 0, 0, 97, 0, 51, 0, 224, 0, 0, 0, 97, 0, 52, 0, 77, 1, 0, 0, 111, 0, 49, 0, 243, 0, 0, 0, 111, 0, 50, 0, 79, 1, 0, 0, 111, 0, 51, 0, 210, 1, 0, 0, 111, 0, 51, 0, 242, 0, 0, 0, 111, 0, 52, 0, 234, 0, 0, 0, 101, 0, 97, 0, 19, 1, 0, 0, 101, 0, 49, 0, 233, 0, 0, 0, 101, 0, 50, 0, 21, 1, 0, 0, 101, 0, 51, 0, 27, 1, 0, 0, 101, 0, 51, 0, 232, 0, 0, 0, 101, 0, 52, 0, 43, 1, 0, 0, 105, 0, 49, 0, 237, 0, 0, 0, 105, 0, 50, 0, 45, 1, 0, 0, 105, 0, 51, 0, 208, 1, 0, 0, 105, 0, 51, 0, 236, 0, 0, 0, 105, 0, 52, 0, 107, 1, 0, 0, 117, 0, 49, 0, 250, 0, 0, 0, 117, 0, 50, 0, 212, 1, 0, 0, 117, 0, 51, 0, 249, 0, 0, 0, 117, 0, 52, 0, 214, 1, 0, 0, 252, 0, 49, 0, 216, 1, 0, 0, 252, 0, 50, 0, 109, 1, 0, 0, 117, 0, 51, 0, 218, 1, 0, 0, 252, 0, 51, 0, 220, 1, 0, 0, 252, 0, 52, 0, 75, 1, 0, 0, 110, 0, 103, 0, 81, 2, 0, 0, 97, 0, 0, 0, 97, 2, 0, 0, 103, 0, 0, 0, 145, 30, 0, 0, 122, 0, 104, 0, 9, 1, 0, 0, 99, 0, 104, 0, 93, 1, 0, 0, 115, 0, 104, 0, 0, 0, 0, 0, 6, 18, 66, 106, 0, 113, 0, 120, 0, 121, 0, 7, 6, 195, 188, 0, 3, 148, 0, 101, 3, 151, 0, 7, 6, 97, 0, 4, 1, 104, 99, 2, 52, 110, 103, 25, 3, 35, 0, 1, 104, 99, 2, 110, 103, 52, 25, 0, 2, 15, 110, 25, 0, 4, 3, 126, 0, 1, 104, 99, 2, 15, 110, 103, 25, 0, 1, 107, 2, 15, 110, 103, 25, 0, 8, 2, 15, 110, 103, 25, 0, 105, 3, 127, 0, 51, 105, 3, 127, 110, 0, 50, 105, 3, 127, 113, 0, 52, 105, 3, 127, 115, 0, 49, 105, 3, 127, 117, 0, 4, 111, 3, 128, 0, 111, 1, 121, 0, 4, 51, 111, 3, 128, 110, 0, 51, 111, 1, 121, 0, 4, 50, 111, 3, 128, 113, 0, 50, 111, 1, 121, 0, 4, 52, 111, 3, 128, 115, 0, 52, 111, 1, 121, 0, 4, 49, 111, 3, 128, 117, 0, 49, 111, 1, 121, 0, 4, 1, 121, 3, 134, 0, 1, 121, 2, 15, 110, 103, 25, 0, 1, 121, 2, 15, 110, 25, 3, 136, 0, 7, 6, 98, 0, 1, 21, 2, 25, 3, 21, 0, 3, 48, 0, 7, 6, 99, 0, 1, 21, 2, 25, 3, 21, 0, 3, 123, 0, 104, 2, 12, 3, 125, 0, 7, 6, 100, 0, 1, 21, 2, 25, 3, 21, 0, 3, 47, 0, 7, 6, 101, 0, 4, 1, 100, 3, 13, 0, 1, 108, 0, 1, 110, 0, 1, 116, 0, 2, 15, 110, 0, 114, 2, 25, 3, 129, 0, 51, 114, 2, 25, 3, 129, 110, 0, 50, 114, 2, 25, 3, 129, 113, 0, 52, 114, 2, 25, 3, 129, 115, 0, 49, 114, 2, 25, 3, 129, 117, 0, 97, 3, 130, 0, 105, 3, 131, 0, 51, 105, 3, 131, 110, 0, 50, 105, 3, 131, 113, 0, 52, 105, 3, 131, 115, 0, 49, 105, 3, 131, 117, 0, 1, 121, 3, 136, 0, 3, 139, 0, 7, 6, 102, 0, 1, 21, 2, 25, 3, 21, 0, 3, 83, 0, 7, 6, 103, 0, 1, 21, 2, 25, 3, 21, 0, 3, 49, 0, 7, 6, 104, 0, 1, 21, 2, 25, 3, 21, 0, 3, 101, 0, 7, 6, 105, 0, 3, 37, 0, 111, 1, 113, 2, 15, 110, 103, 25, 3, 40, 0, 97, 111, 3, 57, 128, 0, 97, 51, 111, 3, 57, 128, 110, 0, 97, 50, 111, 3, 57, 128, 113, 0, 97, 52, 111, 3, 57, 128, 115, 0, 97, 49, 111, 3, 57, 128, 117, 0, 4, 1, 99, 3, 132, 0, 1, 115, 0, 1, 122, 0, 4, 1, 104, 3, 133, 0, 1, 114, 0, 4, 97, 3, 134, 0, 97, 2, 15, 110, 103, 25, 0, 4, 97, 2, 15, 110, 25, 3, 136, 0, 101, 0, 117, 3, 138, 0, 111, 2, 15, 110, 103, 25, 3, 148, 0, 7, 6, 106, 0, 1, 21, 2, 25, 3, 21, 0, 3, 78, 0, 7, 6, 107, 0, 1, 21, 2, 25, 3, 21, 0, 3, 120, 0, 7, 6, 108, 0, 1, 21, 2, 25, 3, 21, 0, 4, 3, 55, 0, 1, 21, 2, 118, 0, 7, 6, 109, 0, 1, 21, 2, 25, 3, 21, 0, 3, 65, 0, 7, 6, 110, 0, 103, 8, 2, 25, 3, 43, 0, 3, 50, 0, 103, 2, 25, 3, 68, 0, 7, 6, 111, 0, 3, 39, 0, 1, 121, 3, 137, 0, 117, 1, 121, 3, 138, 0, 51, 117, 1, 121, 3, 138, 110, 0, 50, 117, 1, 121, 3, 138, 113, 0, 52, 117, 1, 121, 3, 138, 115, 0, 49, 117, 1, 121, 3, 138, 117, 0, 117, 3, 140, 0, 51, 117, 3, 140, 110, 0, 50, 117, 3, 140, 113, 0, 52, 117, 3, 140, 115, 0, 49, 117, 3, 140, 117, 0, 110, 103, 2, 25, 3, 141, 0, 51, 110, 103, 2, 25, 3, 141, 110, 0, 50, 110, 103, 2, 25, 3, 141, 113, 0, 52, 110, 103, 2, 25, 3, 141, 115, 0, 49, 110, 103, 2, 25, 3, 141, 117, 0, 7, 6, 112, 0, 1, 21, 2, 25, 3, 21, 0, 3, 118, 0, 7, 6, 113, 0, 1, 21, 2, 25, 3, 21, 0, 3, 121, 0, 7, 6, 114, 0, 3, 92, 0, 2, 25, 3, 129, 108, 0, 7, 6, 115, 0, 1, 21, 2, 25, 3, 21, 0, 3, 89, 0, 104, 2, 12, 3, 93, 0, 7, 6, 116, 0, 1, 21, 2, 25, 3, 21, 0, 3, 119, 0, 7, 6, 117, 0, 105, 1, 104, 115, 3, 34, 131, 0, 3, 40, 0, 4, 97, 1, 103, 2, 15, 110, 25, 3, 58, 35, 0, 97, 1, 107, 2, 15, 110, 25, 0, 111, 1, 104, 115, 3, 58, 39, 0, 4, 97, 3, 58, 126, 0, 97, 2, 15, 110, 103, 25, 0, 105, 1, 104, 115, 3, 58, 131, 0, 1, 104, 115, 2, 15, 110, 25, 3, 58, 139, 0, 4, 1, 107, 2, 15, 110, 25, 3, 58, 145, 0, 1, 116, 2, 15, 110, 25, 0, 8, 104, 2, 15, 110, 25, 0, 97, 2, 15, 110, 25, 3, 143, 0, 97, 105, 3, 144, 0, 97, 51, 105, 3, 144, 110, 0, 97, 50, 105, 3, 144, 113, 0, 97, 52, 105, 3, 144, 115, 0, 97, 49, 105, 3, 144, 117, 0, 2, 15, 110, 25, 3, 145, 0, 105, 3, 146, 0, 111, 3, 147, 0, 1, 18, 66, 3, 148, 0, 97, 1, 18, 66, 2, 15, 110, 25, 3, 150, 0, 4, 101, 3, 151, 0, 101, 1, 18, 66, 0, 1, 18, 66, 2, 15, 110, 25, 3, 152, 0, 1, 113, 2, 15, 110, 25, 12, 3, 153, 0, 7, 6, 118, 0, 3, 84, 0, 4, 1, 108, 3, 148, 0, 1, 110, 0, 4, 101, 1, 108, 3, 151, 0, 101, 1, 110, 0, 7, 6, 119, 0, 1, 21, 2, 25, 3, 21, 0, 111, 3, 58, 39, 0, 117, 3, 58, 40, 0, 97, 3, 58, 126, 0, 97, 105, 3, 58, 127, 0, 97, 51, 105, 3, 58, 127, 110, 0, 97, 50, 105, 3, 58, 127, 113, 0, 97, 52, 105, 3, 58, 127, 115, 0, 97, 49, 105, 3, 58, 127, 117, 0, 101, 105, 3, 58, 131, 0, 101, 51, 105, 3, 58, 131, 110, 0, 101, 50, 105, 3, 58, 131, 113, 0, 101, 52, 105, 3, 58, 131, 115, 0, 101, 49, 105, 3, 58, 131, 117, 0, 101, 3, 58, 145, 0, 7, 6, 120, 0, 1, 21, 2, 25, 3, 21, 0, 3, 97, 0, 7, 6, 121, 0, 2, 117, 3, 0, 1, 21, 2, 25, 3, 21, 0, 2, 25, 3, 37, 0, 4, 2, 117, 15, 110, 3, 38, 0, 2, 117, 25, 0, 3, 57, 0, 111, 2, 15, 110, 103, 25, 3, 149, 0, 7, 6, 122, 0, 1, 21, 2, 25, 3, 21, 0, 3, 122, 0, 104, 2, 12, 3, 124, 0, 7, 6, 0, 124, 3, 23, 0, 53, 3, 108, 0, 51, 3, 110, 0, 50, 3, 113, 0, 52, 3, 115, 0, 49, 3, 117, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts70 = FileInMemory_createWithData (41827, reinterpret_cast (&espeakdata_dicts70_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/zh_dict", U"zh"); Collection_addItem (me.peek(), espeakdata_dicts70.transfer()); static unsigned char espeakdata_dicts71_data[1557] = { 0, 4, 0, 0, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 97, 0, 5, 1, 3, 21, 0, 5, 2, 3, 35, 0, 97, 5, 2, 3, 114, 0, 97, 105, 5, 2, 3, 115, 0, 97, 117, 5, 2, 3, 116, 0, 97, 110, 103, 5, 2, 3, 118, 0, 105, 5, 2, 3, 119, 0, 117, 5, 2, 3, 120, 0, 7, 6, 98, 0, 5, 1, 3, 21, 0, 5, 2, 3, 71, 0, 7, 6, 99, 0, 5, 1, 3, 21, 0, 104, 5, 2, 3, 76, 0, 5, 2, 3, 80, 0, 7, 6, 100, 0, 5, 1, 3, 21, 0, 5, 2, 3, 72, 0, 7, 6, 101, 0, 5, 1, 3, 21, 0, 5, 2, 3, 36, 0, 105, 5, 2, 3, 121, 0, 117, 5, 2, 3, 123, 0, 111, 5, 2, 3, 134, 0, 111, 105, 5, 2, 3, 135, 0, 7, 6, 102, 0, 5, 1, 3, 21, 0, 5, 2, 3, 83, 0, 7, 6, 103, 0, 5, 1, 3, 21, 0, 5, 2, 3, 81, 0, 7, 6, 104, 0, 5, 1, 3, 21, 0, 5, 2, 3, 107, 0, 7, 6, 105, 0, 5, 1, 3, 21, 0, 5, 2, 3, 37, 0, 117, 5, 2, 3, 125, 0, 7, 6, 106, 0, 5, 1, 3, 21, 0, 5, 2, 3, 57, 0, 7, 6, 107, 0, 5, 1, 3, 21, 0, 5, 2, 3, 49, 0, 7, 6, 108, 0, 5, 1, 3, 21, 0, 5, 2, 3, 55, 0, 7, 6, 109, 0, 5, 1, 3, 21, 0, 5, 2, 3, 65, 0, 7, 6, 110, 0, 5, 1, 3, 21, 0, 5, 2, 3, 50, 0, 103, 5, 2, 3, 68, 0, 7, 6, 111, 0, 5, 1, 3, 21, 0, 5, 2, 3, 39, 0, 105, 5, 2, 3, 128, 0, 117, 5, 2, 3, 129, 0, 110, 103, 5, 2, 3, 130, 0, 101, 5, 2, 3, 133, 0, 7, 6, 112, 0, 5, 1, 3, 21, 0, 5, 2, 3, 48, 0, 7, 6, 113, 0, 5, 1, 3, 21, 0, 5, 2, 3, 49, 0, 117, 5, 2, 3, 49, 58, 0, 7, 6, 114, 0, 5, 1, 3, 21, 0, 5, 2, 3, 34, 0, 7, 6, 115, 0, 5, 1, 3, 21, 0, 5, 2, 3, 89, 0, 7, 6, 116, 0, 5, 1, 3, 21, 0, 5, 2, 3, 47, 0, 7, 6, 117, 0, 5, 1, 3, 21, 0, 5, 2, 3, 40, 0, 105, 5, 2, 3, 132, 0, 7, 6, 118, 0, 5, 1, 3, 21, 0, 5, 2, 3, 84, 0, 7, 6, 119, 0, 5, 1, 3, 21, 0, 5, 2, 3, 58, 0, 7, 6, 120, 0, 5, 1, 3, 21, 0, 5, 2, 3, 49, 89, 0, 7, 6, 121, 0, 5, 1, 3, 21, 0, 5, 2, 3, 57, 0, 117, 5, 2, 3, 136, 0, 7, 6, 122, 0, 5, 1, 3, 21, 0, 5, 2, 3, 88, 0, 7, 6, 0, 49, 3, 17, 0, 50, 3, 108, 0, 51, 3, 109, 0, 52, 3, 110, 0, 53, 3, 111, 0, 54, 3, 112, 0, 55, 3, 113, 0, 7, 0, 0}; autoFileInMemory espeakdata_dicts71 = FileInMemory_createWithData (1556, reinterpret_cast (&espeakdata_dicts71_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/zhy_dict", U"zhy"); Collection_addItem (me.peek(), espeakdata_dicts71.transfer()); return me.transfer(); } catch (MelderError) { Melder_throw (U"FilesInMemory not created."); } } praat-6.0.04/external/espeak/espeakdata_phons.cpp000066400000000000000000067741371261542461700220600ustar00rootroot00000000000000/* File espeakdata_phons.cpp was generated on Sun Nov 4 17:43:38 2012 from the following files in espeak-data/: * phondata, phonindex, phontab, intonations */ #include "espeakdata_FileInMemory.h" #include "Collection.h" #include "FileInMemory.h" #include "melder.h" FilesInMemory create_espeakdata_phons () { try { autoFilesInMemory me = FilesInMemory_create (); static unsigned char espeakdata_phons1_data[817] = { 115, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 24, 8, 0, 0, 0, 0, 46, 57, 0, 16, 0, 0, 255, 80, 50, 255, 4, 5, 248, 248, 248, 251, 251, 251, 0, 64, 8, 0, 70, 18, 24, 12, 0, 70, 18, 24, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 24, 8, 0, 0, 0, 0, 46, 57, 0, 16, 0, 0, 255, 80, 46, 255, 4, 5, 248, 248, 248, 251, 251, 251, 4, 80, 18, 6, 78, 22, 34, 52, 6, 78, 22, 34, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 40, 24, 8, 0, 0, 0, 0, 46, 57, 0, 16, 0, 0, 255, 75, 43, 255, 4, 5, 249, 249, 249, 0, 0, 0, 4, 88, 22, 6, 82, 22, 34, 66, 6, 82, 22, 34, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 52, 32, 20, 10, 0, 0, 0, 46, 57, 0, 16, 0, 0, 255, 90, 50, 255, 3, 5, 247, 247, 247, 0, 0, 0, 0, 92, 8, 0, 92, 80, 76, 8, 0, 92, 80, 76, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 24, 8, 0, 0, 0, 0, 46, 57, 0, 16, 0, 0, 75, 65, 60, 255, 4, 5, 251, 248, 248, 251, 251, 251, 0, 44, 28, 0, 50, 42, 34, 28, 0, 50, 42, 34, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 24, 8, 0, 0, 0, 0, 46, 57, 0, 16, 0, 0, 255, 65, 50, 255, 4, 5, 249, 248, 248, 249, 251, 251, 2, 60, 42, 2, 55, 42, 34, 52, 2, 55, 42, 34, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 40, 24, 8, 0, 0, 0, 0, 40, 75, 0, 16, 0, 0, 255, 75, 43, 255, 4, 5, 249, 249, 249, 249, 0, 0, 2, 70, 50, 2, 35, 45, 60, 70, 2, 35, 45, 60, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 52, 32, 20, 10, 0, 0, 0, 46, 57, 0, 16, 0, 0, 255, 90, 50, 255, 3, 5, 249, 247, 247, 249, 0, 0, 0, 92, 8, 0, 92, 80, 76, 8, 0, 92, 80, 76, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 24, 8, 0, 0, 0, 0, 46, 57, 0, 16, 0, 0, 255, 80, 50, 255, 4, 5, 249, 248, 248, 249, 251, 251, 0, 64, 8, 0, 70, 18, 24, 12, 0, 70, 18, 24, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 24, 8, 0, 0, 0, 0, 46, 57, 0, 16, 0, 0, 255, 70, 30, 255, 4, 5, 249, 248, 248, 249, 251, 251, 4, 75, 50, 0, 70, 18, 24, 12, 0, 70, 18, 24, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 40, 24, 8, 0, 0, 0, 0, 46, 57, 0, 16, 0, 0, 255, 75, 43, 255, 4, 5, 249, 249, 249, 249, 0, 0, 4, 88, 22, 6, 82, 22, 34, 66, 6, 82, 22, 34, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 52, 32, 20, 10, 0, 0, 0, 46, 57, 0, 16, 0, 0, 255, 90, 50, 255, 3, 5, 249, 247, 247, 249, 0, 0, 0, 92, 8, 0, 92, 80, 76, 8, 0, 92, 80, 76, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; autoFileInMemory espeakdata_phons1 = FileInMemory_createWithData (816, reinterpret_cast (&espeakdata_phons1_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/intonations", U"intonations"); Collection_addItem (me.peek(), espeakdata_phons1.transfer()); static unsigned char espeakdata_phons2_data[385581] = { 36, 70, 1, 0, 74, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, 3, 0, 1, 0, 112, 0, 13, 2, 161, 5, 36, 9, 188, 12, 116, 14, 96, 27, 50, 60, 34, 66, 80, 45, 47, 36, 18, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 3, 0, 116, 0, 13, 2, 161, 5, 36, 9, 188, 12, 116, 14, 96, 27, 90, 86, 41, 79, 96, 54, 56, 43, 23, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 13, 2, 161, 5, 36, 9, 188, 12, 116, 14, 96, 27, 0, 46, 30, 58, 70, 39, 41, 32, 16, 9, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 140, 0, 3, 0, 1, 0, 116, 0, 13, 2, 161, 5, 36, 9, 188, 12, 116, 14, 96, 27, 50, 20, 19, 38, 46, 26, 27, 20, 10, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 3, 0, 116, 0, 13, 2, 161, 5, 36, 9, 188, 12, 116, 14, 96, 27, 90, 29, 23, 45, 55, 31, 32, 24, 13, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 13, 2, 161, 5, 36, 9, 188, 12, 116, 14, 96, 27, 0, 15, 16, 33, 40, 22, 23, 18, 9, 5, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 50, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 151, 0, 4, 0, 1, 0, 16, 1, 136, 3, 40, 5, 140, 10, 112, 13, 35, 15, 32, 28, 46, 50, 33, 65, 59, 37, 25, 22, 8, 7, 217, 150, 105, 120, 120, 120, 255, 180, 150, 44, 65, 70, 130, 53, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 3, 0, 32, 1, 136, 3, 40, 5, 140, 10, 112, 13, 191, 14, 32, 28, 40, 96, 43, 94, 78, 57, 42, 26, 13, 6, 217, 155, 105, 120, 120, 120, 247, 170, 165, 44, 65, 75, 130, 54, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 32, 1, 136, 3, 40, 5, 140, 10, 112, 13, 191, 14, 32, 28, 65, 81, 39, 86, 71, 52, 38, 24, 11, 5, 217, 155, 105, 120, 120, 120, 247, 170, 165, 44, 65, 75, 130, 53, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 16, 1, 128, 3, 60, 5, 100, 10, 112, 13, 191, 14, 160, 28, 0, 51, 35, 68, 61, 35, 32, 24, 7, 8, 217, 135, 105, 120, 120, 120, 255, 165, 165, 44, 65, 70, 130, 53, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 200, 0, 4, 0, 1, 0, 200, 0, 200, 1, 188, 7, 236, 9, 32, 13, 136, 14, 128, 28, 50, 41, 26, 55, 55, 55, 47, 35, 11, 5, 185, 107, 127, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 3, 0, 200, 0, 200, 1, 188, 7, 236, 9, 32, 13, 136, 14, 128, 28, 80, 78, 36, 76, 76, 76, 65, 49, 15, 7, 185, 107, 127, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 200, 0, 192, 1, 188, 7, 236, 9, 32, 13, 136, 14, 128, 28, 70, 67, 33, 69, 69, 69, 59, 45, 13, 6, 185, 107, 127, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 200, 0, 184, 1, 188, 7, 236, 9, 32, 13, 136, 14, 128, 28, 0, 30, 22, 47, 47, 47, 40, 30, 9, 4, 185, 107, 127, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 4, 0, 33, 0, 152, 0, 32, 1, 224, 8, 24, 11, 72, 13, 0, 15, 160, 26, 52, 44, 9, 65, 57, 58, 53, 28, 13, 6, 175, 105, 120, 120, 120, 120, 175, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 3, 0, 152, 0, 24, 1, 232, 8, 24, 11, 72, 13, 0, 15, 160, 26, 75, 67, 11, 81, 66, 66, 66, 35, 17, 8, 167, 105, 120, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 152, 0, 24, 1, 232, 8, 24, 11, 72, 13, 0, 15, 160, 26, 69, 54, 10, 73, 59, 59, 59, 31, 15, 7, 167, 105, 120, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 118, 0, 240, 0, 35, 9, 24, 11, 72, 13, 30, 15, 112, 26, 0, 27, 7, 48, 43, 42, 42, 23, 10, 6, 171, 105, 112, 120, 120, 120, 175, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 160, 0, 4, 0, 1, 0, 192, 0, 40, 2, 92, 3, 100, 10, 164, 11, 96, 14, 159, 27, 50, 57, 23, 57, 62, 34, 32, 19, 12, 4, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 3, 0, 192, 0, 40, 2, 92, 3, 100, 10, 164, 11, 96, 14, 159, 27, 60, 121, 34, 82, 90, 49, 47, 27, 18, 7, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 192, 0, 40, 2, 112, 3, 100, 10, 164, 11, 96, 14, 159, 27, 50, 73, 29, 70, 64, 42, 40, 23, 15, 6, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 192, 0, 40, 2, 112, 3, 100, 10, 164, 11, 96, 14, 159, 27, 0, 41, 22, 52, 48, 32, 30, 17, 11, 4, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 120, 0, 4, 0, 1, 0, 176, 0, 64, 1, 92, 3, 56, 9, 12, 13, 60, 15, 144, 26, 50, 39, 6, 64, 43, 21, 21, 30, 12, 7, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 3, 0, 176, 0, 64, 1, 92, 3, 56, 9, 12, 13, 60, 15, 144, 26, 70, 55, 7, 77, 51, 25, 25, 36, 14, 9, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 176, 0, 64, 1, 92, 3, 156, 9, 12, 13, 60, 15, 144, 26, 50, 40, 6, 65, 43, 21, 21, 31, 12, 7, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 176, 0, 64, 1, 92, 3, 156, 9, 12, 13, 60, 15, 144, 26, 0, 26, 5, 52, 35, 17, 17, 25, 10, 6, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 120, 0, 6, 0, 1, 0, 116, 0, 0, 2, 20, 5, 36, 9, 188, 12, 116, 14, 96, 27, 20, 22, 20, 39, 48, 27, 28, 21, 10, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 3, 0, 116, 0, 0, 2, 20, 5, 36, 9, 188, 12, 116, 14, 96, 27, 0, 22, 20, 39, 48, 27, 28, 21, 10, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 0, 2, 20, 5, 36, 9, 188, 12, 116, 14, 96, 27, 0, 18, 18, 35, 44, 24, 25, 19, 9, 5, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 50, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 236, 0, 216, 1, 76, 4, 82, 8, 172, 13, 160, 15, 0, 27, 60, 18, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 100, 100, 53, 225, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 236, 0, 216, 1, 76, 4, 82, 8, 172, 13, 160, 15, 0, 27, 40, 17, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 100, 100, 53, 225, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 236, 0, 216, 1, 76, 4, 82, 8, 172, 13, 160, 15, 0, 27, 0, 17, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 100, 100, 53, 225, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 120, 0, 6, 0, 1, 0, 116, 0, 0, 2, 20, 5, 36, 9, 188, 12, 116, 14, 96, 27, 20, 22, 20, 39, 48, 27, 28, 21, 10, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 3, 0, 116, 0, 0, 2, 20, 5, 36, 9, 188, 12, 116, 14, 96, 27, 0, 22, 20, 39, 48, 27, 28, 21, 10, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 0, 2, 20, 5, 36, 9, 188, 12, 116, 14, 96, 27, 0, 18, 18, 35, 44, 24, 25, 19, 9, 5, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 50, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 196, 0, 114, 1, 96, 4, 16, 9, 88, 12, 91, 14, 32, 27, 60, 17, 38, 33, 28, 24, 33, 28, 7, 0, 120, 60, 135, 120, 120, 120, 75, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 196, 0, 114, 1, 96, 4, 16, 9, 88, 12, 91, 14, 32, 27, 40, 17, 38, 33, 28, 24, 33, 28, 7, 0, 120, 60, 135, 120, 120, 120, 75, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 196, 0, 114, 1, 16, 4, 252, 8, 200, 10, 91, 14, 32, 27, 0, 14, 40, 28, 20, 12, 8, 8, 6, 0, 120, 60, 135, 120, 120, 120, 75, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 160, 0, 5, 0, 1, 0, 140, 0, 240, 1, 232, 5, 76, 9, 236, 12, 176, 14, 77, 27, 20, 18, 22, 36, 40, 24, 24, 18, 9, 3, 160, 132, 126, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 3, 0, 140, 0, 240, 1, 232, 5, 76, 9, 236, 12, 176, 14, 77, 27, 40, 18, 22, 36, 40, 24, 24, 18, 9, 3, 160, 132, 126, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 236, 0, 224, 1, 220, 5, 236, 9, 172, 13, 160, 15, 0, 27, 60, 17, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 150, 150, 53, 225, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 236, 0, 224, 1, 220, 5, 236, 9, 172, 13, 160, 15, 0, 27, 40, 17, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 150, 150, 53, 225, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 236, 0, 224, 1, 220, 5, 236, 9, 172, 13, 160, 15, 0, 27, 0, 14, 48, 34, 20, 12, 10, 12, 7, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 150, 150, 53, 225, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 160, 0, 5, 0, 1, 0, 140, 0, 240, 1, 232, 5, 76, 9, 236, 12, 176, 14, 77, 27, 20, 18, 22, 36, 40, 24, 24, 18, 9, 3, 160, 132, 126, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 3, 0, 140, 0, 240, 1, 232, 5, 76, 9, 236, 12, 176, 14, 77, 27, 40, 18, 22, 36, 40, 24, 24, 18, 9, 3, 160, 132, 126, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 236, 0, 124, 1, 8, 7, 236, 9, 172, 13, 160, 15, 0, 27, 60, 23, 53, 41, 24, 20, 16, 13, 8, 0, 132, 60, 90, 120, 120, 120, 42, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 236, 0, 124, 1, 8, 7, 236, 9, 172, 13, 160, 15, 0, 27, 40, 23, 53, 41, 24, 20, 16, 13, 8, 0, 132, 60, 90, 120, 120, 120, 42, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 236, 0, 124, 1, 244, 6, 236, 9, 172, 13, 160, 15, 0, 27, 0, 14, 42, 32, 20, 16, 12, 9, 6, 0, 132, 60, 90, 120, 120, 120, 42, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 120, 0, 5, 0, 1, 0, 184, 0, 248, 1, 32, 7, 244, 9, 85, 13, 104, 15, 70, 26, 20, 17, 26, 32, 37, 22, 22, 17, 8, 2, 148, 119, 137, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 3, 0, 184, 0, 248, 1, 32, 7, 244, 9, 85, 13, 104, 15, 70, 26, 0, 17, 26, 32, 37, 22, 22, 17, 8, 2, 148, 119, 137, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 236, 0, 234, 1, 52, 8, 236, 9, 172, 13, 160, 15, 0, 27, 60, 25, 57, 49, 29, 20, 20, 18, 10, 0, 120, 60, 90, 120, 120, 120, 50, 135, 105, 44, 20, 200, 200, 55, 230, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 236, 0, 234, 1, 52, 8, 236, 9, 172, 13, 160, 15, 0, 27, 40, 25, 57, 49, 29, 20, 20, 18, 10, 0, 120, 60, 90, 120, 120, 120, 50, 135, 105, 44, 20, 200, 200, 55, 230, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 236, 0, 234, 1, 52, 8, 236, 9, 172, 13, 160, 15, 0, 27, 0, 15, 44, 38, 23, 16, 16, 14, 8, 0, 120, 60, 90, 120, 120, 120, 50, 135, 105, 44, 20, 200, 200, 55, 230, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 8, 2, 70, 0, 0, 0, 0, 0, 0, 0, 4, 14, 28, 40, 46, 48, 46, 38, 23, 252, 211, 174, 161, 177, 209, 238, 0, 14, 26, 30, 17, 237, 190, 160, 167, 201, 232, 251, 15, 51, 91, 109, 92, 52, 11, 239, 216, 190, 166, 161, 190, 247, 51, 89, 101, 103, 104, 93, 52, 246, 185, 151, 149, 164, 184, 210, 252, 50, 101, 126, 115, 78, 34, 251, 212, 169, 136, 134, 171, 231, 31, 70, 95, 111, 115, 96, 50, 245, 190, 158, 151, 161, 180, 212, 2, 57, 102, 118, 104, 73, 37, 254, 209, 164, 137, 141, 175, 223, 12, 49, 76, 94, 96, 75, 32, 238, 196, 173, 166, 169, 182, 212, 0, 48, 80, 89, 78, 57, 27, 247, 205, 168, 149, 157, 188, 229, 14, 49, 78, 98, 100, 80, 40, 254, 219, 197, 185, 183, 195, 222, 3, 39, 62, 69, 63, 47, 25, 253, 220, 192, 179, 185, 205, 231, 0, 25, 47, 61, 59, 41, 14, 244, 222, 208, 200, 202, 213, 235, 4, 28, 42, 46, 42, 32, 17, 253, 230, 213, 208, 214, 228, 245, 6, 24, 39, 45, 41, 26, 6, 244, 229, 220, 216, 219, 230, 248, 12, 29, 37, 39, 35, 26, 12, 251, 235, 224, 221, 227, 238, 252, 10, 25, 36, 40, 35, 22, 6, 248, 235, 227, 223, 227, 237, 252, 10, 22, 29, 31, 27, 19, 7, 249, 236, 229, 227, 232, 241, 253, 9, 20, 28, 31, 26, 17, 5, 250, 240, 233, 231, 234, 242, 253, 7, 16, 22, 23, 21, 14, 5, 252, 243, 238, 237, 239, 245, 252, 4, 13, 18, 20, 17, 12, 5, 254, 248, 243, 241, 243, 248, 255, 5, 10, 14, 15, 13, 9, 3, 254, 249, 246, 245, 247, 251, 0, 3, 7, 10, 11, 9, 6, 2, 255, 251, 249, 249, 250, 252, 0, 2, 5, 7, 7, 6, 4, 1, 255, 253, 252, 252, 253, 254, 0, 1, 3, 3, 3, 3, 1, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 0, 5, 0, 1, 0, 204, 0, 128, 2, 176, 4, 252, 8, 240, 10, 52, 18, 0, 28, 45, 42, 34, 58, 42, 39, 34, 8, 14, 5, 170, 165, 137, 120, 120, 120, 170, 180, 137, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 3, 0, 216, 0, 136, 2, 176, 4, 252, 8, 227, 12, 20, 15, 214, 27, 55, 56, 32, 63, 62, 39, 39, 30, 15, 6, 189, 159, 136, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 65, 0, 216, 0, 136, 2, 176, 4, 252, 8, 227, 12, 20, 15, 214, 27, 80, 42, 28, 55, 54, 34, 34, 26, 13, 5, 189, 159, 136, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 204, 0, 128, 2, 176, 4, 212, 8, 44, 11, 20, 15, 0, 28, 35, 26, 26, 47, 33, 27, 29, 9, 11, 4, 170, 165, 137, 120, 120, 120, 170, 180, 137, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 204, 0, 128, 2, 176, 4, 212, 8, 44, 11, 20, 15, 0, 28, 0, 26, 26, 47, 33, 27, 29, 9, 11, 4, 170, 165, 137, 120, 120, 120, 170, 180, 137, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 165, 0, 4, 0, 1, 0, 104, 0, 96, 1, 0, 5, 204, 11, 192, 13, 180, 15, 32, 29, 45, 37, 18, 64, 39, 21, 43, 25, 8, 0, 155, 120, 97, 120, 120, 120, 95, 120, 97, 44, 45, 70, 130, 59, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 3, 0, 104, 0, 96, 1, 216, 4, 204, 11, 192, 13, 180, 15, 32, 29, 60, 45, 20, 72, 44, 24, 48, 28, 9, 0, 155, 120, 97, 120, 120, 120, 95, 120, 97, 44, 45, 70, 130, 59, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 104, 0, 96, 1, 176, 4, 204, 11, 192, 13, 180, 15, 32, 29, 60, 45, 20, 72, 44, 24, 48, 28, 9, 0, 155, 120, 97, 120, 120, 120, 95, 120, 97, 44, 45, 70, 130, 58, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 104, 0, 96, 1, 176, 4, 204, 11, 192, 13, 180, 15, 32, 29, 0, 37, 18, 64, 39, 21, 43, 25, 8, 0, 155, 120, 97, 120, 120, 120, 95, 120, 97, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 75, 0, 3, 0, 1, 0, 244, 0, 129, 1, 96, 4, 24, 6, 88, 12, 41, 14, 192, 27, 40, 40, 48, 51, 44, 16, 0, 0, 10, 0, 147, 80, 120, 120, 120, 120, 87, 95, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 228, 0, 149, 1, 98, 4, 224, 6, 88, 12, 41, 14, 192, 28, 35, 65, 39, 84, 62, 33, 22, 17, 16, 0, 150, 90, 120, 120, 120, 120, 90, 90, 120, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 228, 0, 13, 2, 172, 5, 208, 7, 88, 12, 41, 14, 192, 28, 0, 85, 40, 77, 109, 49, 46, 29, 16, 0, 120, 165, 120, 120, 120, 120, 60, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 75, 0, 3, 0, 21, 0, 0, 1, 184, 1, 176, 4, 64, 6, 124, 11, 96, 14, 224, 27, 40, 26, 45, 40, 47, 25, 0, 16, 5, 0, 150, 60, 120, 120, 120, 120, 105, 90, 75, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 184, 0, 164, 1, 96, 4, 168, 7, 28, 12, 66, 14, 96, 27, 35, 61, 40, 80, 60, 33, 19, 14, 13, 0, 157, 105, 120, 120, 120, 120, 112, 90, 60, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 184, 0, 128, 2, 65, 4, 232, 8, 28, 12, 166, 14, 96, 27, 0, 99, 45, 78, 119, 51, 50, 35, 17, 0, 120, 105, 120, 120, 120, 120, 75, 90, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 75, 0, 3, 0, 5, 0, 216, 0, 64, 1, 236, 4, 24, 6, 184, 11, 166, 14, 224, 26, 40, 42, 43, 56, 31, 15, 0, 0, 15, 0, 147, 60, 150, 120, 120, 120, 87, 90, 90, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 196, 0, 160, 1, 236, 4, 144, 6, 184, 11, 236, 14, 64, 27, 35, 59, 36, 76, 64, 33, 32, 13, 15, 0, 150, 120, 105, 120, 120, 120, 105, 90, 78, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 228, 0, 178, 2, 249, 5, 232, 8, 188, 12, 91, 14, 0, 28, 0, 82, 40, 57, 115, 64, 66, 42, 14, 0, 120, 165, 120, 120, 120, 120, 120, 165, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 80, 0, 3, 0, 37, 0, 216, 0, 64, 1, 236, 4, 24, 6, 184, 11, 166, 14, 224, 26, 40, 46, 46, 59, 33, 16, 0, 0, 10, 0, 147, 60, 150, 120, 120, 120, 87, 90, 90, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 37, 0, 120, 0, 124, 1, 117, 5, 52, 8, 224, 11, 166, 14, 224, 26, 40, 49, 19, 73, 56, 36, 39, 19, 12, 0, 150, 165, 150, 120, 120, 120, 90, 90, 90, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 120, 0, 84, 1, 97, 8, 116, 9, 12, 13, 110, 15, 96, 27, 0, 79, 16, 75, 80, 86, 84, 54, 17, 0, 120, 135, 150, 120, 120, 120, 60, 120, 75, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 75, 0, 3, 0, 1, 0, 0, 1, 184, 1, 176, 4, 64, 6, 124, 11, 96, 14, 224, 27, 40, 26, 45, 40, 47, 25, 0, 16, 5, 0, 150, 60, 120, 120, 120, 120, 105, 90, 75, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 136, 0, 49, 1, 21, 4, 88, 7, 48, 12, 41, 14, 32, 26, 35, 47, 35, 76, 55, 29, 14, 14, 22, 0, 150, 75, 105, 120, 120, 120, 60, 105, 120, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 168, 0, 189, 1, 123, 3, 132, 8, 48, 12, 41, 14, 64, 27, 0, 119, 49, 103, 110, 61, 48, 33, 18, 0, 120, 150, 105, 120, 120, 120, 30, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 75, 0, 3, 0, 1, 0, 0, 1, 184, 1, 176, 4, 64, 6, 124, 11, 96, 14, 224, 27, 40, 26, 45, 40, 47, 25, 0, 16, 5, 0, 150, 60, 120, 120, 120, 120, 105, 90, 75, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 40, 0, 54, 1, 109, 4, 104, 6, 128, 12, 247, 13, 192, 28, 35, 35, 16, 59, 46, 31, 31, 18, 13, 0, 150, 120, 120, 120, 120, 120, 150, 120, 120, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 40, 0, 134, 1, 205, 5, 72, 8, 128, 12, 247, 13, 192, 28, 0, 74, 16, 95, 70, 33, 36, 18, 13, 0, 120, 120, 120, 120, 120, 120, 120, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 50, 0, 2, 0, 5, 0, 244, 0, 174, 1, 136, 4, 4, 6, 124, 11, 79, 16, 64, 27, 50, 21, 51, 34, 39, 16, 18, 7, 7, 0, 120, 45, 135, 120, 120, 120, 60, 90, 93, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 244, 0, 174, 1, 136, 4, 4, 6, 124, 11, 79, 16, 64, 27, 0, 21, 51, 34, 39, 16, 18, 7, 7, 0, 120, 45, 135, 120, 120, 120, 60, 90, 93, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 65, 0, 3, 0, 1, 0, 8, 1, 184, 1, 232, 3, 160, 5, 108, 12, 210, 15, 224, 27, 40, 16, 34, 40, 26, 12, 0, 4, 3, 0, 120, 60, 120, 120, 120, 120, 75, 90, 75, 44, 35, 50, 60, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 8, 1, 184, 1, 232, 3, 200, 5, 48, 12, 140, 15, 224, 27, 25, 24, 42, 44, 45, 20, 8, 16, 7, 0, 120, 60, 120, 120, 120, 120, 75, 90, 75, 44, 35, 50, 60, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 8, 1, 184, 1, 32, 3, 200, 5, 48, 12, 140, 15, 224, 27, 0, 26, 42, 44, 45, 20, 8, 16, 7, 0, 120, 60, 120, 120, 120, 120, 75, 90, 75, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 20, 0, 2, 0, 1, 0, 24, 1, 184, 1, 233, 3, 200, 5, 108, 12, 210, 15, 224, 27, 20, 10, 34, 21, 26, 13, 5, 5, 3, 0, 120, 60, 120, 120, 120, 120, 75, 90, 75, 44, 35, 50, 60, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 24, 1, 184, 1, 233, 3, 200, 5, 108, 12, 210, 15, 224, 27, 0, 34, 61, 39, 47, 24, 12, 11, 7, 0, 120, 60, 120, 120, 120, 120, 75, 90, 75, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 12, 0, 3, 0, 1, 0, 0, 1, 184, 1, 176, 4, 64, 6, 124, 11, 96, 14, 224, 27, 12, 27, 45, 44, 40, 20, 12, 16, 5, 0, 150, 60, 120, 120, 120, 120, 105, 90, 75, 44, 35, 50, 60, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 0, 1, 184, 1, 176, 4, 64, 6, 124, 11, 96, 14, 224, 27, 0, 26, 45, 40, 47, 25, 12, 16, 5, 0, 150, 60, 120, 120, 120, 120, 105, 90, 75, 44, 35, 50, 60, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 0, 1, 184, 1, 176, 4, 64, 6, 124, 11, 96, 14, 224, 27, 0, 26, 45, 40, 47, 25, 20, 11, 5, 0, 150, 60, 120, 120, 120, 120, 105, 90, 75, 44, 35, 50, 60, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 40, 0, 2, 0, 37, 0, 184, 0, 24, 2, 112, 5, 72, 8, 0, 10, 188, 12, 136, 19, 40, 17, 43, 9, 14, 19, 28, 9, 9, 9, 157, 125, 137, 137, 150, 175, 157, 125, 137, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 184, 0, 24, 2, 112, 5, 248, 7, 236, 9, 188, 12, 131, 24, 0, 17, 42, 14, 14, 32, 23, 9, 4, 4, 157, 125, 137, 137, 150, 175, 157, 125, 137, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 81, 19, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 3, 6, 9, 10, 9, 4, 7, 1, 249, 249, 241, 233, 233, 234, 251, 8, 3, 8, 14, 34, 32, 37, 29, 26, 28, 27, 13, 12, 8, 253, 3, 20, 27, 20, 10, 22, 17, 16, 9, 3, 249, 244, 234, 237, 244, 242, 242, 249, 4, 25, 30, 28, 27, 25, 38, 32, 15, 6, 3, 0, 246, 247, 246, 255, 249, 5, 23, 31, 14, 7, 14, 9, 2, 1, 247, 241, 238, 227, 239, 248, 244, 246, 254, 8, 26, 28, 21, 19, 22, 25, 26, 5, 3, 14, 11, 7, 7, 10, 24, 23, 20, 31, 33, 23, 20, 19, 9, 3, 244, 247, 237, 235, 235, 237, 237, 237, 236, 246, 246, 242, 245, 247, 247, 243, 248, 248, 231, 236, 241, 244, 241, 243, 5, 23, 26, 28, 37, 41, 35, 29, 25, 23, 21, 12, 5, 10, 12, 16, 24, 21, 24, 29, 38, 32, 15, 6, 3, 1, 252, 246, 246, 248, 250, 2, 253, 8, 12, 7, 14, 18, 7, 3, 247, 247, 0, 0, 250, 247, 1, 3, 254, 5, 15, 19, 22, 16, 22, 27, 21, 19, 16, 18, 29, 28, 16, 21, 34, 39, 38, 31, 32, 37, 36, 23, 22, 17, 10, 251, 250, 11, 9, 3, 9, 10, 12, 7, 0, 5, 14, 5, 249, 241, 245, 248, 253, 253, 252, 7, 251, 254, 5, 9, 10, 8, 250, 9, 6, 8, 17, 26, 41, 43, 35, 33, 51, 54, 44, 34, 34, 31, 25, 21, 24, 42, 34, 15, 22, 29, 34, 31, 12, 1, 255, 227, 218, 220, 223, 227, 222, 223, 249, 12, 11, 15, 30, 36, 22, 0, 251, 11, 249, 232, 247, 245, 0, 12, 16, 49, 78, 78, 83, 91, 82, 70, 45, 30, 23, 244, 229, 243, 247, 245, 253, 255, 22, 28, 13, 18, 22, 254, 247, 228, 220, 229, 219, 209, 227, 247, 253, 10, 16, 24, 19, 18, 255, 241, 236, 240, 236, 236, 4, 31, 30, 45, 78, 76, 86, 85, 75, 72, 57, 16, 0, 239, 242, 247, 250, 2, 13, 18, 33, 42, 33, 32, 14, 1, 250, 230, 209, 202, 201, 204, 222, 237, 254, 0, 15, 36, 34, 36, 16, 245, 253, 250, 240, 242, 249, 7, 34, 37, 58, 89, 82, 68, 82, 68, 47, 40, 19, 3, 251, 247, 250, 254, 246, 254, 14, 27, 28, 15, 12, 13, 253, 226, 219, 223, 211, 198, 204, 222, 230, 232, 234, 253, 0, 243, 244, 253, 251, 238, 241, 4, 14, 13, 20, 36, 52, 51, 43, 33, 30, 34, 25, 20, 21, 21, 22, 21, 36, 60, 59, 45, 31, 20, 9, 254, 237, 239, 228, 205, 201, 211, 226, 226, 221, 246, 4, 248, 252, 243, 253, 238, 228, 214, 216, 235, 235, 241, 250, 14, 25, 35, 47, 63, 60, 47, 39, 42, 50, 34, 14, 4, 2, 248, 250, 2, 21, 32, 18, 10, 29, 29, 15, 3, 0, 255, 241, 227, 211, 226, 240, 232, 221, 229, 249, 8, 18, 18, 26, 23, 15, 16, 25, 17, 7, 255, 7, 2, 255, 9, 20, 7, 13, 20, 34, 39, 38, 24, 28, 37, 20, 8, 12, 11, 17, 17, 2, 4, 8, 17, 27, 20, 26, 29, 14, 7, 14, 12, 243, 240, 247, 255, 9, 12, 18, 32, 31, 22, 38, 26, 13, 255, 242, 248, 252, 231, 240, 252, 8, 18, 17, 21, 41, 45, 38, 42, 30, 23, 28, 9, 251, 17, 22, 1, 5, 26, 29, 26, 32, 34, 45, 15, 253, 17, 11, 251, 242, 237, 253, 236, 215, 6, 17, 25, 56, 57, 32, 53, 42, 14, 44, 54, 15, 14, 10, 8, 1, 243, 15, 33, 30, 17, 16, 14, 2, 240, 234, 242, 225, 195, 192, 206, 225, 2, 244, 239, 253, 239, 246, 247, 244, 2, 1, 250, 255, 26, 37, 37, 28, 49, 52, 24, 21, 16, 10, 252, 237, 250, 3, 3, 14, 10, 6, 20, 252, 236, 238, 222, 202, 182, 168, 168, 183, 186, 189, 213, 253, 8, 41, 43, 51, 75, 51, 45, 54, 23, 16, 15, 229, 240, 14, 5, 18, 46, 51, 65, 76, 61, 61, 49, 34, 27, 247, 227, 233, 215, 223, 238, 236, 2, 22, 21, 60, 63, 23, 20, 15, 237, 236, 237, 203, 207, 215, 229, 0, 6, 17, 51, 61, 55, 52, 35, 24, 11, 253, 4, 253, 234, 242, 0, 1, 24, 48, 66, 96, 101, 104, 94, 78, 68, 55, 41, 27, 9, 236, 235, 244, 253, 1, 253, 253, 10, 19, 23, 5, 1, 6, 249, 223, 215, 228, 223, 220, 240, 244, 244, 255, 0, 20, 50, 38, 44, 51, 37, 44, 56, 44, 49, 51, 38, 57, 57, 61, 87, 76, 83, 82, 59, 48, 30, 3, 4, 247, 231, 225, 214, 227, 236, 226, 245, 250, 243, 243, 247, 243, 253, 247, 251, 255, 250, 239, 249, 13, 25, 29, 19, 30, 40, 33, 46, 63, 53, 38, 45, 48, 34, 23, 34, 43, 39, 45, 25, 13, 26, 4, 250, 249, 0, 5, 227, 231, 245, 242, 233, 226, 219, 250, 16, 251, 252, 21, 14, 8, 0, 1, 10, 246, 242, 11, 255, 233, 245, 236, 242, 2, 18, 35, 45, 41, 29, 37, 48, 46, 33, 12, 19, 21, 252, 236, 244, 10, 15, 22, 18, 43, 62, 23, 18, 36, 10, 232, 242, 217, 224, 232, 211, 250, 23, 254, 8, 23, 37, 41, 254, 253, 7, 236, 213, 213, 223, 244, 235, 237, 7, 26, 20, 25, 43, 45, 33, 16, 6, 1, 236, 224, 238, 4, 13, 21, 17, 56, 70, 37, 59, 60, 29, 36, 0, 213, 217, 199, 176, 205, 225, 237, 14, 21, 28, 43, 40, 14, 4, 8, 0, 228, 209, 221, 227, 220, 220, 248, 20, 49, 66, 53, 68, 66, 29, 8, 8, 235, 215, 224, 239, 249, 253, 31, 71, 51, 51, 77, 61, 24, 16, 238, 206, 181, 166, 173, 170, 177, 245, 24, 26, 55, 81, 93, 88, 51, 36, 34, 251, 200, 196, 211, 199, 212, 5, 20, 34, 58, 60, 64, 85, 67, 51, 14, 241, 246, 195, 198, 251, 220, 240, 0, 254, 48, 31, 250, 66, 80, 27, 16, 17, 10, 237, 201, 235, 13, 2, 221, 227, 42, 54, 35, 56, 68, 86, 36, 253, 34, 34, 247, 234, 244, 249, 250, 235, 2, 51, 50, 58, 63, 52, 49, 45, 35, 39, 250, 210, 228, 243, 247, 251, 243, 239, 246, 250, 250, 0, 255, 254, 233, 192, 190, 206, 198, 189, 197, 219, 249, 4, 240, 0, 4, 250, 1, 253, 250, 14, 32, 51, 52, 27, 27, 54, 71, 56, 43, 48, 50, 50, 1, 247, 25, 12, 243, 238, 236, 234, 249, 225, 231, 248, 220, 227, 238, 215, 213, 227, 228, 249, 253, 228, 0, 241, 206, 224, 253, 18, 48, 41, 56, 84, 68, 71, 89, 89, 95, 98, 82, 89, 59, 21, 33, 18, 240, 251, 238, 244, 25, 255, 246, 9, 253, 254, 248, 233, 255, 234, 201, 216, 237, 229, 237, 246, 11, 36, 49, 62, 73, 63, 53, 73, 63, 36, 27, 15, 24, 9, 16, 52, 56, 33, 26, 22, 19, 0, 226, 235, 240, 225, 219, 224, 250, 13, 12, 31, 82, 59, 36, 44, 50, 41, 8, 225, 236, 239, 220, 255, 18, 27, 49, 42, 57, 91, 74, 40, 42, 29, 5, 254, 238, 240, 246, 227, 245, 13, 30, 31, 39, 47, 67, 33, 9, 12, 3, 4, 5, 244, 10, 18, 255, 29, 49, 32, 28, 10, 9, 254, 233, 236, 3, 246, 236, 243, 252, 2, 15, 25, 41, 64, 48, 19, 9, 7, 1, 249, 253, 10, 9, 251, 245, 21, 29, 20, 24, 28, 25, 21, 250, 246, 13, 29, 24, 28, 36, 32, 47, 12, 6, 47, 41, 8, 15, 12, 15, 23, 248, 7, 45, 6, 239, 27, 24, 3, 28, 21, 38, 43, 255, 16, 45, 1, 3, 44, 25, 18, 22, 238, 16, 23, 236, 241, 222, 186, 213, 187, 172, 227, 233, 236, 248, 2, 49, 44, 9, 47, 42, 0, 10, 233, 223, 240, 216, 233, 7, 248, 242, 18, 25, 37, 32, 29, 67, 66, 31, 15, 18, 24, 12, 240, 229, 247, 234, 215, 208, 220, 228, 208, 188, 234, 238, 201, 219, 235, 238, 246, 217, 242, 25, 244, 212, 229, 252, 14, 246, 250, 62, 34, 239, 255, 32, 51, 36, 255, 29, 51, 250, 239, 13, 18, 254, 255, 9, 28, 21, 237, 251, 20, 3, 235, 243, 251, 251, 233, 236, 21, 6, 249, 6, 20, 25, 4, 254, 9, 7, 252, 239, 251, 4, 243, 251, 23, 25, 17, 1, 21, 33, 36, 17, 240, 0, 11, 229, 253, 38, 24, 38, 16, 2, 53, 53, 42, 59, 23, 4, 12, 252, 6, 9, 235, 0, 3, 223, 234, 6, 20, 17, 243, 245, 13, 12, 21, 35, 13, 34, 23, 240, 14, 19, 2, 0, 251, 237, 237, 222, 238, 21, 8, 16, 29, 1, 25, 17, 228, 23, 47, 10, 22, 7, 16, 33, 253, 8, 75, 59, 33, 47, 28, 27, 25, 12, 33, 21, 245, 236, 244, 2, 252, 239, 0, 5, 229, 225, 14, 26, 15, 6, 3, 22, 29, 242, 252, 17, 227, 229, 243, 240, 0, 1, 17, 65, 79, 53, 80, 79, 81, 76, 64, 53, 28, 242, 249, 246, 253, 3, 26, 88, 97, 79, 94, 73, 41, 44, 42, 45, 35, 242, 233, 228, 218, 243, 0, 31, 49, 9, 51, 97, 40, 10, 0, 241, 12, 219, 199, 224, 239, 255, 252, 37, 68, 59, 63, 89, 99, 95, 50, 2, 12, 11, 254, 227, 229, 214, 185, 221, 0, 21, 30, 7, 238, 6, 28, 9, 244, 231, 236, 232, 209, 219, 249, 224, 193, 240, 5, 250, 229, 227, 16, 35, 242, 214, 5, 254, 212, 231, 15, 23, 13, 0, 7, 52, 50, 18, 18, 8, 235, 235, 0, 241, 211, 224, 9, 36, 32, 23, 50, 45, 26, 22, 26, 21, 241, 209, 214, 238, 240, 254, 0, 5, 30, 21, 31, 36, 251, 249, 234, 229, 229, 189, 183, 248, 5, 11, 59, 60, 68, 94, 95, 83, 96, 69, 36, 50, 28, 246, 244, 0, 255, 0, 19, 32, 39, 21, 11, 30, 22, 248, 249, 237, 231, 243, 216, 216, 247, 251, 9, 47, 33, 46, 74, 62, 72, 53, 254, 3, 19, 253, 243, 237, 238, 8, 10, 22, 60, 62, 42, 41, 71, 86, 67, 37, 21, 33, 17, 14, 15, 12, 3, 242, 36, 66, 43, 14, 29, 28, 31, 3, 224, 232, 245, 238, 251, 245, 9, 20, 15, 30, 70, 53, 29, 12, 0, 246, 228, 212, 220, 237, 1, 37, 53, 58, 57, 58, 67, 56, 14, 4, 4, 241, 245, 238, 215, 213, 215, 246, 21, 19, 252, 6, 10, 250, 3, 251, 242, 246, 235, 246, 255, 242, 243, 233, 0, 24, 6, 255, 12, 16, 13, 17, 10, 249, 242, 249, 239, 240, 242, 233, 235, 8, 29, 255, 240, 9, 7, 10, 21, 254, 239, 224, 193, 210, 245, 243, 240, 230, 247, 19, 11, 252, 25, 31, 33, 15, 239, 230, 250, 8, 0, 6, 252, 236, 0, 17, 14, 10, 9, 7, 237, 227, 5, 22, 1, 249, 235, 246, 11, 5, 235, 6, 8, 254, 3, 231, 239, 35, 11, 238, 3, 7, 253, 5, 4, 7, 20, 244, 7, 55, 38, 38, 44, 34, 42, 20, 244, 20, 44, 246, 228, 245, 252, 254, 254, 7, 37, 21, 4, 18, 13, 252, 8, 21, 250, 213, 212, 250, 15, 234, 226, 31, 57, 45, 35, 56, 83, 70, 25, 48, 56, 14, 2, 248, 236, 220, 215, 255, 24, 8, 38, 74, 58, 44, 48, 41, 41, 36, 10, 225, 225, 247, 241, 232, 253, 15, 20, 17, 26, 46, 30, 11, 0, 242, 246, 238, 228, 228, 239, 218, 242, 31, 48, 23, 11, 36, 38, 15, 249, 252, 0, 0, 237, 254, 11, 5, 3, 21, 69, 95, 55, 45, 85, 70, 13, 8, 11, 247, 229, 210, 7, 49, 237, 225, 15, 32, 32, 19, 10, 20, 254, 222, 249, 249, 224, 216, 222, 11, 18, 5, 43, 75, 62, 55, 47, 43, 40, 0, 252, 52, 30, 233, 2, 21, 37, 77, 73, 74, 92, 66, 50, 77, 50, 2, 249, 224, 223, 210, 196, 228, 243, 221, 242, 10, 12, 12, 255, 3, 27, 8, 231, 221, 222, 225, 219, 209, 226, 228, 205, 248, 29, 33, 70, 67, 57, 86, 84, 93, 100, 82, 72, 43, 7, 16, 31, 13, 15, 29, 19, 20, 26, 19, 55, 30, 247, 5, 251, 193, 171, 180, 233, 240, 226, 14, 28, 17, 30, 67, 92, 55, 247, 242, 240, 243, 234, 204, 234, 9, 14, 65, 104, 98, 84, 75, 106, 112, 53, 32, 29, 226, 206, 238, 0, 11, 230, 219, 35, 59, 0, 246, 227, 254, 0, 191, 187, 203, 159, 168, 231, 255, 235, 231, 213, 18, 33, 254, 247, 239, 243, 13, 6, 26, 62, 30, 9, 73, 99, 109, 50, 5, 40, 27, 2, 0, 0, 9, 9, 4, 23, 36, 15, 255, 11, 46, 6, 192, 209, 229, 228, 206, 178, 224, 5, 248, 12, 57, 37, 29, 239, 237, 56, 40, 231, 237, 241, 229, 229, 225, 26, 19, 242, 18, 62, 44, 239, 230, 31, 34, 211, 199, 248, 233, 227, 217, 245, 245, 210, 214, 242, 24, 28, 235, 246, 8, 253, 9, 17, 9, 5, 223, 0, 50, 6, 206, 236, 240, 233, 250, 225, 16, 18, 220, 0, 67, 45, 24, 11, 33, 47, 247, 224, 14, 236, 201, 224, 227, 229, 228, 206, 36, 79, 37, 53, 54, 42, 81, 47, 45, 43, 227, 221, 25, 14, 20, 247, 215, 24, 46, 38, 68, 67, 36, 14, 235, 238, 247, 198, 173, 199, 241, 10, 5, 15, 34, 31, 43, 71, 55, 31, 246, 245, 245, 211, 190, 217, 249, 9, 36, 36, 59, 79, 73, 98, 103, 89, 60, 31, 14, 249, 240, 247, 8, 249, 254, 28, 54, 58, 52, 34, 51, 38, 250, 3, 9, 246, 237, 236, 230, 226, 223, 1, 22, 245, 247, 12, 6, 31, 47, 56, 52, 42, 45, 48, 47, 66, 79, 41, 29, 53, 64, 54, 68, 57, 51, 49, 20, 7, 23, 40, 26, 4, 9, 247, 254, 47, 47, 7, 2, 9, 239, 207, 212, 229, 237, 219, 241, 3, 242, 15, 41, 25, 63, 87, 55, 54, 63, 59, 59, 25, 253, 11, 9, 45, 63, 34, 55, 57, 11, 80, 58, 249, 220, 191, 230, 253, 199, 230, 244, 188, 181, 211, 9, 249, 203, 223, 254, 252, 187, 165, 228, 0, 7, 23, 38, 26, 4, 245, 6, 28, 6, 216, 235, 13, 10, 6, 22, 44, 59, 47, 46, 79, 69, 11, 251, 14, 247, 195, 155, 163, 192, 189, 194, 234, 244, 252, 1, 5, 31, 12, 233, 233, 255, 8, 233, 246, 17, 16, 255, 16, 24, 57, 36, 0, 7, 8, 223, 212, 219, 252, 253, 232, 255, 36, 37, 26, 45, 60, 44, 38, 46, 58, 32, 239, 245, 27, 46, 47, 68, 80, 52, 32, 38, 26, 13, 245, 229, 243, 234, 228, 247, 4, 23, 41, 41, 51, 63, 33, 15, 14, 8, 255, 219, 217, 10, 25, 8, 254, 5, 21, 27, 35, 71, 56, 11, 255, 10, 38, 29, 248, 0, 25, 238, 240, 21, 29, 25, 255, 244, 50, 63, 16, 22, 59, 69, 45, 10, 58, 61, 8, 22, 38, 9, 235, 206, 242, 38, 18, 250, 11, 247, 250, 9, 0, 27, 3, 206, 233, 248, 228, 237, 250, 241, 29, 34, 53, 50, 43, 68, 70, 43, 46, 47, 13, 9, 23, 14, 19, 251, 255, 39, 58, 68, 45, 21, 23, 27, 21, 24, 24, 235, 212, 197, 189, 206, 209, 191, 209, 216, 244, 1, 249, 9, 27, 13, 19, 30, 24, 8, 242, 243, 248, 235, 232, 15, 54, 88, 88, 98, 117, 122, 112, 107, 87, 50, 7, 218, 240, 217, 174, 192, 207, 193, 239, 255, 235, 246, 242, 233, 240, 206, 178, 188, 191, 230, 244, 225, 18, 22, 15, 72, 70, 46, 56, 17, 0, 20, 252, 237, 224, 202, 1, 33, 15, 28, 26, 10, 39, 40, 7, 17, 241, 228, 25, 247, 229, 34, 6, 247, 27, 9, 24, 19, 229, 16, 30, 217, 203, 216, 168, 172, 184, 185, 190, 160, 163, 229, 235, 220, 255, 238, 0, 23, 237, 34, 59, 8, 255, 3, 246, 255, 243, 14, 56, 36, 21, 61, 72, 77, 77, 61, 46, 35, 8, 248, 1, 251, 206, 188, 201, 228, 249, 4, 7, 28, 13, 224, 218, 229, 199, 212, 232, 208, 208, 212, 220, 4, 35, 29, 50, 58, 58, 58, 41, 50, 48, 11, 16, 17, 31, 75, 53, 40, 50, 76, 87, 95, 82, 85, 65, 31, 18, 11, 35, 37, 8, 0, 15, 12, 1, 19, 23, 249, 227, 221, 208, 194, 189, 209, 227, 227, 245, 254, 20, 39, 41, 38, 63, 75, 45, 28, 42, 44, 31, 6, 14, 44, 37, 39, 68, 87, 83, 58, 47, 60, 63, 36, 252, 0, 250, 212, 196, 231, 235, 236, 9, 30, 31, 48, 24, 31, 41, 248, 219, 206, 182, 182, 159, 179, 1, 236, 237, 70, 40, 55, 113, 62, 60, 68, 16, 36, 32, 234, 32, 61, 31, 65, 69, 87, 112, 76, 52, 79, 48, 32, 26, 252, 21, 47, 242, 239, 246, 220, 218, 208, 201, 254, 237, 229, 246, 242, 245, 230, 245, 27, 224, 199, 7, 247, 207, 224, 235, 37, 26, 248, 38, 54, 24, 19, 2, 16, 4, 203, 224, 38, 12, 246, 18, 34, 32, 24, 22, 50, 29, 252, 1, 253, 215, 193, 186, 212, 233, 229, 238, 242, 1, 22, 18, 11, 21, 242, 226, 228, 215, 235, 241, 235, 6, 41, 43, 54, 44, 51, 74, 48, 43, 42, 242, 232, 240, 231, 255, 244, 237, 12, 4, 253, 15, 23, 34, 48, 13, 10, 239, 177, 208, 249, 228, 225, 223, 213, 237, 2, 3, 44, 54, 34, 33, 46, 56, 43, 11, 14, 41, 35, 33, 49, 39, 50, 65, 39, 53, 36, 249, 16, 24, 20, 2, 231, 238, 14, 13, 13, 24, 11, 20, 33, 21, 12, 252, 230, 224, 249, 6, 7, 13, 16, 12, 32, 68, 75, 52, 62, 39, 41, 55, 38, 19, 13, 17, 11, 12, 19, 3, 12, 245, 11, 251, 240, 253, 245, 246, 3, 246, 239, 255, 7, 17, 28, 246, 12, 252, 249, 15, 12, 22, 17, 241, 13, 44, 23, 52, 67, 44, 61, 64, 45, 54, 10, 243, 254, 243, 228, 238, 237, 242, 8, 254, 253, 13, 24, 32, 20, 6, 2, 249, 3, 5, 241, 238, 245, 243, 7, 23, 29, 30, 0, 232, 235, 227, 229, 6, 2, 5, 32, 20, 38, 61, 40, 56, 55, 28, 33, 12, 238, 219, 214, 225, 210, 219, 25, 54, 43, 12, 15, 29, 11, 252, 12, 18, 245, 233, 246, 9, 8, 17, 48, 80, 68, 48, 68, 68, 43, 44, 28, 29, 18, 248, 231, 249, 4, 3, 241, 250, 14, 8, 3, 4, 242, 242, 226, 216, 209, 216, 206, 218, 203, 222, 251, 233, 2, 36, 18, 40, 52, 39, 43, 27, 7, 27, 3, 3, 8, 236, 237, 253, 2, 12, 18, 24, 24, 21, 37, 55, 28, 1, 244, 239, 233, 212, 202, 204, 197, 187, 209, 227, 222, 236, 12, 255, 25, 18, 244, 229, 229, 239, 249, 233, 236, 7, 25, 35, 46, 43, 63, 45, 20, 45, 36, 14, 6, 250, 7, 16, 14, 5, 13, 35, 47, 54, 55, 43, 26, 15, 5, 8, 247, 218, 225, 241, 234, 232, 236, 247, 252, 5, 254, 19, 6, 249, 237, 254, 252, 237, 238, 252, 24, 37, 46, 64, 53, 58, 65, 63, 80, 45, 0, 255, 255, 240, 237, 0, 24, 30, 26, 51, 61, 40, 51, 75, 60, 40, 39, 22, 254, 237, 232, 252, 16, 14, 22, 46, 51, 29, 17, 6, 10, 5, 231, 222, 223, 222, 225, 233, 236, 239, 3, 254, 10, 33, 36, 33, 34, 19, 17, 11, 10, 26, 28, 27, 37, 31, 20, 41, 51, 33, 38, 36, 21, 13, 25, 23, 25, 15, 1, 16, 29, 8, 2, 21, 28, 12, 1, 2, 255, 248, 221, 200, 204, 225, 216, 211, 229, 1, 10, 5, 29, 44, 45, 30, 18, 28, 28, 9, 251, 250, 243, 223, 244, 26, 57, 52, 53, 72, 71, 52, 41, 49, 57, 40, 23, 18, 16, 11, 0, 3, 15, 19, 24, 34, 33, 17, 2, 253, 9, 6, 245, 7, 37, 39, 31, 14, 26, 59, 36, 22, 37, 30, 23, 15, 23, 37, 26, 249, 240, 244, 250, 243, 227, 229, 239, 232, 242, 18, 30, 248, 209, 244, 11, 255, 241, 242, 1, 10, 0, 7, 36, 52, 29, 42, 69, 48, 8, 253, 244, 242, 230, 225, 215, 203, 204, 226, 8, 18, 241, 230, 253, 5, 235, 250, 250, 238, 236, 216, 208, 244, 230, 232, 15, 34, 33, 21, 7, 15, 18, 4, 12, 9, 12, 20, 12, 7, 34, 8, 1, 12, 31, 30, 10, 249, 250, 243, 227, 228, 234, 251, 2, 234, 234, 252, 244, 249, 252, 252, 252, 221, 216, 254, 251, 236, 243, 241, 1, 20, 27, 38, 37, 31, 32, 22, 6, 14, 28, 5, 251, 11, 17, 13, 16, 17, 48, 55, 32, 30, 15, 237, 229, 227, 230, 222, 186, 198, 254, 247, 238, 23, 31, 37, 48, 28, 40, 42, 5, 7, 255, 248, 26, 12, 249, 27, 34, 22, 38, 26, 19, 27, 3, 0, 5, 236, 236, 243, 242, 3, 240, 231, 13, 27, 20, 24, 32, 39, 28, 251, 241, 15, 255, 238, 255, 2, 3, 252, 244, 253, 24, 19, 13, 38, 41, 24, 30, 34, 30, 14, 7, 15, 26, 6, 14, 12, 11, 18, 0, 250, 252, 8, 251, 245, 232, 227, 239, 219, 219, 2, 21, 5, 0, 27, 35, 40, 35, 30, 35, 24, 9, 0, 252, 248, 248, 2, 25, 28, 10, 48, 66, 54, 52, 51, 52, 54, 44, 21, 19, 20, 7, 250, 251, 11, 35, 32, 7, 5, 6, 12, 23, 250, 243, 252, 245, 232, 235, 239, 253, 0, 255, 4, 19, 27, 22, 16, 12, 5, 246, 2, 15, 248, 7, 12, 17, 28, 31, 34, 61, 49, 30, 37, 28, 16, 25, 15, 12, 9, 6, 10, 34, 35, 33, 37, 28, 20, 8, 233, 245, 254, 244, 226, 211, 226, 241, 242, 253, 12, 24, 33, 35, 39, 55, 32, 249, 231, 241, 250, 237, 249, 18, 32, 27, 46, 58, 53, 46, 46, 48, 52, 34, 10, 7, 0, 13, 17, 14, 32, 17, 5, 31, 23, 18, 16, 241, 240, 244, 220, 203, 211, 210, 216, 230, 240, 7, 9, 5, 35, 36, 8, 13, 7, 6, 16, 14, 9, 16, 255, 10, 30, 28, 43, 46, 17, 26, 23, 249, 3, 14, 1, 6, 16, 14, 21, 15, 17, 26, 21, 17, 27, 17, 8, 21, 9, 244, 251, 246, 4, 25, 22, 29, 45, 37, 30, 24, 18, 31, 33, 15, 7, 1, 243, 247, 247, 244, 16, 17, 9, 30, 26, 10, 16, 2, 247, 250, 242, 248, 251, 242, 251, 12, 12, 29, 45, 43, 40, 32, 12, 1, 239, 235, 235, 243, 243, 253, 15, 33, 35, 38, 43, 45, 39, 31, 22, 5, 247, 241, 234, 222, 228, 236, 3, 19, 12, 14, 34, 24, 23, 30, 32, 45, 20, 238, 238, 246, 247, 252, 248, 0, 8, 23, 21, 22, 18, 17, 23, 27, 16, 20, 11, 17, 4, 9, 31, 35, 27, 32, 25, 17, 26, 14, 7, 3, 0, 6, 14, 246, 240, 240, 240, 247, 254, 247, 252, 1, 249, 0, 0, 242, 242, 1, 254, 255, 8, 250, 244, 243, 243, 3, 24, 20, 14, 10, 10, 22, 26, 10, 22, 25, 24, 30, 25, 29, 34, 25, 13, 17, 8, 6, 254, 252, 7, 255, 243, 254, 253, 254, 9, 8, 12, 21, 7, 5, 12, 11, 249, 236, 240, 253, 0, 252, 0, 10, 5, 10, 10, 7, 252, 3, 7, 5, 7, 10, 0, 6, 4, 4, 23, 25, 13, 14, 14, 254, 1, 3, 8, 21, 17, 21, 31, 12, 8, 5, 1, 255, 238, 228, 238, 226, 228, 230, 241, 247, 244, 252, 24, 33, 22, 16, 15, 12, 13, 4, 252, 15, 14, 254, 1, 7, 8, 7, 13, 21, 38, 23, 19, 31, 25, 9, 2, 7, 9, 8, 251, 5, 25, 12, 251, 7, 17, 25, 19, 12, 14, 16, 9, 8, 9, 5, 1, 251, 3, 2, 8, 4, 4, 7, 17, 17, 18, 22, 27, 23, 7, 5, 5, 253, 244, 253, 11, 12, 5, 4, 12, 27, 37, 28, 29, 35, 34, 18, 12, 17, 19, 16, 12, 15, 24, 23, 24, 18, 25, 22, 9, 255, 10, 6, 11, 1, 6, 14, 0, 7, 31, 31, 39, 20, 13, 18, 11, 249, 250, 1, 9, 13, 13, 13, 19, 20, 15, 27, 30, 17, 4, 3, 6, 8, 255, 253, 8, 19, 20, 30, 52, 52, 20, 13, 17, 20, 3, 235, 239, 250, 253, 251, 248, 3, 15, 18, 11, 21, 13, 3, 252, 255, 253, 246, 234, 243, 251, 253, 11, 26, 38, 39, 29, 27, 37, 30, 8, 1, 13, 24, 10, 253, 0, 9, 4, 9, 30, 32, 20, 17, 22, 22, 6, 254, 12, 13, 0, 250, 1, 8, 11, 0, 2, 10, 8, 247, 251, 254, 7, 12, 255, 2, 12, 9, 12, 11, 2, 8, 2, 245, 2, 254, 250, 0, 3, 17, 16, 18, 25, 39, 36, 37, 31, 14, 13, 6, 251, 6, 11, 0, 5, 3, 0, 20, 22, 11, 14, 17, 13, 15, 1, 253, 0, 2, 0, 5, 10, 12, 16, 15, 17, 22, 20, 16, 8, 11, 12, 11, 1, 251, 253, 9, 13, 14, 26, 21, 15, 25, 38, 28, 24, 17, 11, 12, 5, 246, 5, 5, 254, 3, 4, 1, 2, 0, 0, 3, 250, 251, 7, 3, 1, 7, 254, 245, 249, 254, 7, 3, 7, 19, 17, 10, 20, 24, 24, 22, 26, 30, 33, 21, 21, 16, 4, 12, 15, 2, 4, 252, 1, 0, 0, 247, 252, 14, 17, 17, 18, 20, 12, 11, 4, 5, 0, 249, 244, 246, 252, 253, 253, 242, 238, 254, 2, 5, 12, 6, 0, 5, 4, 0, 4, 4, 5, 8, 13, 15, 12, 18, 19, 28, 19, 9, 14, 9, 5, 5, 10, 9, 8, 11, 16, 24, 30, 30, 19, 26, 26, 16, 16, 250, 235, 241, 242, 240, 249, 243, 245, 250, 0, 11, 23, 20, 17, 23, 13, 11, 17, 6, 255, 4, 12, 7, 14, 14, 18, 25, 25, 17, 12, 7, 5, 254, 6, 6, 0, 252, 253, 11, 11, 18, 17, 23, 23, 19, 11, 1, 246, 243, 239, 244, 245, 246, 252, 254, 2, 11, 8, 7, 6, 6, 10, 9, 1, 248, 245, 254, 10, 15, 10, 15, 20, 14, 15, 9, 3, 3, 255, 255, 1, 1, 0, 2, 10, 13, 21, 9, 3, 13, 6, 1, 6, 253, 255, 250, 254, 9, 24, 19, 15, 12, 10, 14, 14, 10, 8, 4, 2, 9, 6, 6, 8, 14, 23, 24, 20, 24, 25, 21, 23, 13, 10, 12, 7, 7, 3, 251, 251, 255, 2, 7, 12, 17, 11, 18, 15, 23, 28, 23, 16, 15, 17, 19, 19, 16, 18, 19, 19, 16, 20, 17, 15, 18, 18, 16, 10, 8, 10, 16, 29, 19, 18, 23, 14, 21, 16, 18, 11, 6, 2, 4, 8, 2, 1, 3, 4, 9, 17, 21, 27, 23, 17, 18, 15, 13, 15, 14, 13, 11, 9, 2, 4, 8, 14, 22, 21, 20, 22, 23, 27, 27, 24, 18, 23, 19, 24, 29, 20, 22, 23, 21, 27, 28, 21, 23, 17, 11, 6, 0, 0, 5, 3, 7, 15, 12, 12, 14, 18, 24, 25, 18, 13, 7, 12, 10, 4, 0, 0, 255, 8, 15, 14, 19, 17, 15, 14, 15, 14, 14, 3, 6, 4, 3, 3, 255, 253, 7, 19, 25, 27, 33, 36, 35, 35, 28, 21, 16, 13, 11, 9, 10, 11, 12, 17, 17, 19, 17, 19, 19, 16, 15, 13, 8, 8, 4, 2, 8, 12, 17, 12, 10, 10, 20, 20, 17, 12, 7, 14, 13, 7, 6, 8, 8, 11, 9, 15, 21, 20, 23, 25, 22, 25, 18, 19, 25, 23, 10, 9, 11, 9, 8, 8, 14, 13, 5, 2, 0, 5, 1, 250, 254, 0, 0, 0, 76, 0, 3, 0, 5, 0, 8, 1, 144, 1, 233, 3, 184, 6, 108, 12, 210, 15, 224, 27, 38, 29, 45, 46, 47, 25, 13, 11, 7, 0, 120, 60, 120, 120, 120, 120, 75, 90, 75, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 8, 1, 144, 1, 233, 3, 184, 6, 108, 12, 210, 15, 224, 27, 38, 29, 45, 46, 47, 25, 13, 11, 7, 0, 120, 60, 120, 120, 120, 120, 75, 90, 75, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 8, 1, 144, 1, 233, 3, 184, 6, 108, 12, 210, 15, 224, 27, 0, 29, 45, 46, 47, 25, 13, 11, 7, 0, 120, 60, 120, 120, 120, 120, 75, 90, 75, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 60, 0, 3, 0, 5, 0, 8, 1, 144, 1, 233, 3, 184, 6, 108, 12, 210, 15, 224, 27, 30, 29, 45, 46, 47, 25, 13, 11, 7, 0, 120, 60, 120, 120, 120, 120, 75, 90, 75, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 8, 1, 144, 1, 233, 3, 184, 6, 108, 12, 210, 15, 224, 27, 30, 29, 45, 46, 47, 25, 13, 11, 7, 0, 120, 60, 120, 120, 120, 120, 75, 90, 75, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 8, 1, 144, 1, 233, 3, 184, 6, 108, 12, 210, 15, 224, 27, 0, 30, 45, 46, 47, 25, 13, 11, 7, 0, 120, 60, 120, 120, 120, 120, 75, 90, 75, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 60, 0, 2, 0, 37, 0, 184, 0, 24, 2, 112, 5, 72, 8, 0, 10, 188, 12, 136, 19, 60, 17, 24, 40, 12, 16, 20, 8, 8, 8, 157, 125, 137, 137, 150, 175, 157, 125, 137, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 184, 0, 24, 2, 112, 5, 248, 7, 236, 9, 188, 12, 131, 24, 0, 4, 18, 6, 9, 21, 15, 6, 3, 3, 157, 125, 137, 137, 150, 175, 157, 125, 137, 44, 45, 70, 130, 50, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 90, 0, 3, 0, 5, 0, 4, 0, 16, 1, 220, 5, 156, 9, 58, 14, 216, 19, 224, 21, 40, 5, 8, 23, 10, 6, 6, 6, 4, 4, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 4, 0, 16, 1, 220, 5, 156, 9, 58, 14, 216, 19, 224, 21, 50, 6, 9, 26, 12, 7, 7, 7, 5, 4, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 9, 0, 4, 0, 16, 1, 220, 5, 156, 9, 58, 14, 216, 19, 224, 21, 0, 6, 9, 25, 11, 6, 6, 6, 5, 4, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 8, 7, 36, 0, 248, 248, 251, 0, 6, 7, 6, 3, 0, 252, 246, 241, 237, 237, 237, 239, 252, 2, 9, 19, 29, 34, 34, 31, 22, 15, 7, 4, 9, 17, 19, 24, 30, 36, 43, 61, 69, 68, 66, 52, 37, 33, 25, 13, 4, 249, 232, 236, 250, 1, 15, 18, 3, 250, 242, 230, 223, 217, 202, 187, 185, 185, 193, 210, 218, 220, 224, 232, 239, 250, 3, 0, 249, 242, 236, 233, 237, 244, 250, 3, 9, 15, 25, 27, 27, 26, 21, 16, 10, 3, 254, 246, 242, 240, 241, 242, 243, 243, 245, 249, 255, 0, 1, 255, 250, 243, 238, 236, 235, 237, 239, 238, 241, 246, 252, 1, 3, 1, 254, 251, 249, 249, 247, 244, 240, 235, 232, 232, 232, 232, 235, 255, 25, 54, 78, 82, 78, 74, 67, 56, 44, 27, 15, 11, 16, 31, 40, 50, 52, 49, 44, 34, 27, 18, 2, 237, 218, 203, 202, 209, 218, 223, 227, 226, 225, 218, 216, 218, 218, 219, 220, 218, 215, 210, 209, 214, 222, 239, 0, 19, 30, 34, 30, 26, 17, 11, 10, 10, 10, 11, 12, 18, 18, 24, 27, 26, 23, 19, 10, 3, 250, 242, 239, 236, 234, 237, 237, 236, 238, 243, 246, 247, 249, 248, 246, 244, 239, 237, 238, 243, 254, 12, 21, 28, 29, 25, 18, 13, 9, 5, 3, 3, 6, 9, 14, 18, 17, 21, 18, 10, 5, 0, 251, 249, 248, 248, 250, 251, 252, 253, 255, 6, 9, 8, 4, 7, 19, 24, 23, 21, 8, 253, 246, 244, 252, 255, 10, 21, 22, 22, 11, 5, 5, 254, 247, 245, 239, 235, 232, 230, 235, 223, 232, 248, 0, 5, 13, 23, 44, 39, 32, 31, 14, 255, 1, 14, 31, 46, 51, 68, 76, 94, 114, 112, 107, 91, 63, 48, 42, 34, 23, 10, 248, 231, 244, 3, 16, 33, 21, 252, 234, 215, 201, 194, 186, 163, 149, 147, 150, 167, 185, 196, 200, 207, 218, 229, 249, 4, 0, 252, 242, 229, 229, 232, 237, 245, 4, 17, 34, 48, 52, 52, 47, 37, 26, 17, 6, 253, 246, 245, 245, 246, 247, 246, 245, 246, 250, 255, 1, 0, 249, 237, 231, 226, 228, 230, 233, 233, 236, 240, 248, 0, 4, 4, 2, 0, 254, 253, 255, 254, 253, 252, 251, 250, 251, 252, 254, 255, 254, 255, 254, 254, 254, 253, 252, 252, 252, 255, 0, 0, 1, 2, 3, 1, 1, 1, 1, 2, 3, 4, 5, 5, 5, 4, 4, 3, 1, 1, 255, 254, 252, 252, 251, 251, 250, 249, 250, 250, 249, 249, 249, 251, 249, 252, 252, 251, 250, 253, 255, 0, 2, 4, 6, 6, 6, 5, 4, 4, 2, 0, 0, 0, 1, 2, 4, 4, 3, 1, 0, 255, 253, 252, 251, 251, 252, 252, 253, 255, 0, 2, 3, 5, 5, 7, 7, 8, 8, 8, 9, 10, 10, 10, 10, 10, 9, 8, 7, 8, 10, 9, 9, 6, 8, 9, 10, 10, 8, 5, 4, 3, 3, 5, 2, 255, 251, 251, 0, 8, 17, 23, 24, 25, 28, 31, 32, 29, 18, 9, 1, 255, 2, 9, 14, 15, 13, 11, 12, 14, 14, 11, 4, 250, 238, 227, 217, 207, 199, 199, 202, 214, 232, 244, 2, 14, 23, 27, 30, 20, 7, 2, 253, 3, 26, 38, 50, 60, 64, 74, 92, 117, 124, 121, 109, 82, 65, 60, 50, 32, 13, 244, 220, 234, 254, 11, 34, 25, 252, 235, 215, 200, 194, 184, 158, 139, 134, 135, 154, 178, 191, 196, 202, 215, 227, 247, 6, 1, 253, 242, 228, 227, 232, 238, 249, 8, 21, 37, 52, 58, 58, 55, 45, 33, 22, 10, 255, 247, 244, 244, 245, 246, 246, 244, 243, 247, 254, 2, 0, 249, 238, 229, 226, 225, 230, 230, 233, 234, 239, 248, 0, 6, 7, 6, 2, 0, 254, 255, 0, 255, 251, 249, 248, 250, 251, 250, 249, 249, 252, 252, 253, 253, 252, 251, 251, 251, 251, 250, 251, 251, 251, 254, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 5, 3, 1, 0, 254, 250, 248, 249, 255, 27, 48, 36, 32, 9, 248, 246, 226, 196, 203, 231, 5, 26, 28, 18, 4, 252, 241, 226, 218, 217, 238, 6, 20, 25, 22, 17, 13, 2, 241, 229, 223, 228, 242, 0, 8, 16, 26, 25, 22, 7, 242, 234, 241, 252, 2, 10, 14, 22, 24, 16, 251, 242, 249, 253, 2, 3, 8, 9, 253, 232, 0, 26, 23, 21, 3, 1, 7, 3, 1, 20, 22, 21, 10, 4, 249, 241, 252, 0, 254, 3, 251, 242, 244, 247, 246, 232, 233, 252, 8, 4, 0, 255, 2, 6, 10, 5, 7, 12, 15, 10, 5, 0, 248, 245, 253, 0, 8, 19, 33, 31, 24, 11, 249, 240, 234, 243, 249, 249, 252, 253, 253, 246, 243, 244, 250, 255, 3, 13, 22, 23, 7, 247, 233, 233, 236, 0, 22, 39, 50, 52, 43, 25, 9, 12, 15, 22, 29, 30, 23, 18, 7, 253, 250, 248, 248, 3, 7, 4, 5, 2, 254, 246, 237, 226, 218, 217, 220, 228, 235, 238, 239, 240, 243, 246, 252, 1, 0, 0, 254, 252, 252, 255, 0, 0, 3, 7, 9, 14, 16, 19, 20, 19, 17, 12, 7, 3, 253, 249, 249, 250, 253, 255, 253, 0, 0, 0, 1, 0, 254, 253, 252, 250, 250, 251, 249, 247, 244, 246, 252, 0, 3, 4, 3, 1, 255, 253, 251, 254, 0, 254, 253, 253, 248, 248, 249, 251, 255, 3, 8, 8, 2, 251, 244, 240, 241, 247, 253, 5, 13, 16, 14, 6, 0, 247, 241, 241, 249, 2, 11, 10, 10, 9, 9, 4, 255, 250, 246, 247, 250, 252, 0, 6, 8, 3, 252, 246, 245, 248, 251, 0, 10, 12, 8, 0, 247, 246, 248, 250, 254, 2, 7, 8, 7, 5, 8, 13, 10, 7, 0, 251, 249, 249, 252, 0, 5, 9, 8, 7, 3, 2, 1, 252, 254, 255, 254, 251, 249, 245, 247, 250, 254, 0, 3, 1, 0, 253, 250, 247, 254, 3, 7, 12, 15, 13, 10, 7, 4, 6, 7, 8, 11, 16, 18, 16, 14, 12, 12, 12, 13, 16, 16, 15, 12, 9, 8, 6, 4, 0, 247, 240, 237, 242, 0, 14, 30, 38, 42, 48, 52, 56, 55, 43, 32, 21, 15, 18, 22, 25, 26, 24, 21, 22, 26, 27, 23, 12, 254, 238, 223, 208, 195, 187, 185, 189, 200, 215, 229, 242, 253, 2, 6, 5, 0, 241, 234, 231, 236, 4, 26, 42, 51, 55, 63, 77, 96, 105, 103, 95, 72, 55, 53, 48, 34, 22, 1, 233, 239, 255, 8, 24, 18, 247, 229, 212, 203, 200, 197, 177, 157, 149, 148, 161, 184, 199, 204, 210, 219, 230, 246, 2, 254, 251, 247, 242, 242, 246, 250, 253, 5, 12, 24, 41, 51, 57, 58, 49, 37, 24, 11, 0, 249, 246, 243, 247, 246, 244, 244, 244, 250, 0, 3, 252, 242, 229, 219, 215, 219, 221, 230, 240, 243, 248, 253, 251, 248, 242, 241, 250, 11, 24, 24, 14, 255, 242, 233, 231, 236, 252, 10, 12, 10, 7, 0, 250, 246, 242, 242, 244, 246, 247, 246, 243, 240, 236, 232, 230, 233, 247, 18, 47, 74, 80, 81, 78, 75, 63, 40, 14, 4, 5, 21, 38, 53, 55, 51, 48, 38, 31, 20, 10, 4, 0, 247, 237, 225, 222, 223, 226, 230, 233, 239, 239, 232, 227, 225, 223, 225, 229, 231, 228, 220, 216, 216, 223, 236, 249, 7, 14, 16, 9, 0, 246, 240, 238, 239, 245, 254, 3, 10, 15, 16, 12, 3, 252, 249, 249, 253, 255, 1, 2, 2, 1, 0, 255, 253, 251, 252, 1, 6, 10, 12, 14, 10, 3, 249, 244, 244, 239, 243, 252, 9, 20, 28, 26, 17, 1, 251, 246, 254, 2, 5, 11, 5, 8, 3, 11, 15, 15, 15, 11, 13, 20, 26, 33, 27, 18, 11, 1, 0, 250, 0, 4, 3, 2, 6, 18, 28, 23, 12, 254, 246, 237, 226, 216, 214, 217, 223, 234, 247, 3, 10, 15, 17, 15, 13, 10, 2, 0, 0, 7, 22, 33, 38, 41, 40, 44, 55, 71, 79, 79, 72, 56, 44, 40, 35, 25, 14, 0, 240, 244, 255, 7, 19, 15, 255, 242, 231, 221, 216, 210, 193, 180, 177, 179, 191, 206, 215, 219, 223, 230, 237, 248, 1, 254, 249, 244, 237, 238, 243, 249, 255, 7, 16, 23, 33, 36, 36, 33, 27, 20, 14, 8, 2, 254, 251, 251, 252, 252, 251, 248, 249, 250, 254, 0, 0, 252, 245, 239, 237, 237, 240, 242, 243, 245, 249, 254, 0, 4, 4, 1, 255, 254, 0, 0, 1, 0, 0, 255, 254, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 254, 0, 1, 1, 2, 0, 2, 3, 1, 2, 3, 3, 3, 2, 2, 4, 4, 5, 5, 5, 3, 3, 0, 0, 255, 255, 252, 254, 252, 252, 253, 253, 254, 253, 252, 252, 251, 250, 248, 249, 249, 250, 250, 250, 251, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 4, 0, 5, 0, 116, 0, 13, 2, 161, 5, 152, 8, 128, 12, 212, 13, 96, 27, 30, 8, 14, 26, 25, 12, 12, 12, 7, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 116, 0, 13, 2, 161, 5, 152, 8, 128, 12, 212, 13, 96, 27, 35, 15, 19, 35, 33, 16, 16, 16, 9, 5, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 116, 0, 13, 2, 161, 5, 152, 8, 128, 12, 212, 13, 96, 27, 30, 15, 19, 35, 33, 16, 16, 16, 9, 5, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 13, 2, 161, 5, 152, 8, 128, 12, 212, 13, 96, 27, 0, 10, 15, 29, 26, 13, 13, 13, 8, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 101, 10, 56, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 3, 2, 1, 255, 253, 250, 247, 246, 246, 247, 248, 250, 251, 252, 252, 252, 253, 253, 253, 253, 252, 250, 249, 250, 251, 253, 0, 5, 12, 19, 22, 20, 15, 9, 4, 255, 250, 250, 247, 245, 245, 248, 251, 0, 254, 253, 252, 249, 244, 240, 236, 234, 231, 233, 238, 245, 253, 0, 4, 7, 13, 16, 16, 17, 20, 21, 21, 18, 22, 21, 19, 20, 27, 31, 27, 25, 25, 21, 13, 10, 1, 252, 246, 244, 245, 247, 245, 249, 250, 251, 251, 251, 250, 249, 246, 245, 246, 246, 245, 247, 250, 252, 255, 1, 4, 6, 9, 8, 6, 4, 3, 3, 5, 5, 5, 7, 4, 3, 3, 3, 3, 3, 0, 252, 247, 244, 247, 247, 248, 252, 255, 255, 250, 246, 244, 240, 239, 242, 242, 245, 247, 247, 249, 247, 246, 244, 245, 245, 247, 249, 252, 255, 1, 0, 2, 3, 5, 5, 3, 0, 252, 254, 254, 251, 250, 250, 250, 253, 254, 253, 251, 249, 248, 246, 243, 239, 234, 229, 227, 226, 224, 223, 227, 0, 41, 84, 119, 125, 120, 115, 104, 88, 70, 45, 26, 20, 26, 46, 59, 73, 76, 71, 64, 49, 37, 23, 255, 222, 195, 174, 173, 184, 199, 207, 214, 214, 214, 206, 203, 206, 206, 206, 207, 205, 201, 194, 193, 200, 210, 235, 4, 33, 48, 52, 44, 35, 21, 11, 9, 9, 9, 10, 11, 19, 20, 29, 33, 32, 27, 20, 8, 254, 241, 231, 228, 224, 223, 228, 229, 228, 232, 240, 245, 245, 247, 245, 240, 237, 230, 227, 228, 234, 249, 13, 26, 35, 36, 30, 20, 13, 7, 2, 255, 0, 4, 9, 17, 21, 19, 22, 18, 8, 3, 253, 245, 241, 238, 240, 248, 253, 0, 253, 247, 248, 244, 239, 231, 234, 248, 253, 255, 5, 254, 248, 242, 236, 240, 238, 253, 14, 18, 18, 1, 247, 250, 247, 250, 5, 9, 16, 24, 30, 38, 18, 16, 19, 15, 5, 2, 9, 32, 21, 23, 37, 20, 5, 0, 247, 0, 6, 1, 21, 21, 22, 23, 13, 8, 254, 247, 244, 244, 248, 253, 0, 3, 5, 6, 6, 6, 5, 4, 1, 254, 250, 247, 245, 247, 248, 250, 251, 252, 252, 249, 250, 250, 251, 252, 252, 253, 254, 254, 255, 255, 252, 252, 249, 249, 246, 250, 251, 0, 0, 0, 0, 0, 254, 251, 253, 251, 251, 252, 255, 0, 0, 0, 0, 1, 1, 1, 1, 255, 255, 255, 252, 255, 253, 0, 0, 1, 255, 0, 254, 254, 254, 254, 254, 255, 2, 2, 0, 1, 255, 255, 1, 1, 1, 1, 0, 1, 3, 1, 3, 3, 3, 3, 3, 2, 2, 2, 6, 6, 6, 6, 6, 5, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 255, 255, 255, 1, 0, 1, 255, 254, 254, 254, 254, 253, 253, 0, 253, 0, 0, 255, 252, 255, 255, 254, 254, 255, 1, 1, 1, 254, 253, 252, 249, 248, 248, 248, 249, 250, 252, 253, 253, 252, 252, 251, 250, 250, 250, 251, 253, 255, 0, 2, 4, 5, 6, 8, 8, 10, 9, 9, 8, 7, 7, 6, 6, 5, 5, 5, 5, 4, 4, 5, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 1, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 255, 255, 255, 255, 255, 255, 252, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 0, 254, 254, 254, 1, 2, 2, 2, 1, 255, 255, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 254, 254, 254, 254, 255, 255, 1, 0, 2, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 2, 2, 0, 255, 254, 254, 255, 1, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 3, 1, 3, 0, 3, 0, 0, 0, 0, 0, 0, 4, 4, 4, 1, 1, 1, 1, 254, 254, 254, 255, 254, 251, 250, 251, 255, 0, 2, 2, 2, 2, 2, 2, 1, 254, 254, 253, 253, 255, 0, 2, 3, 4, 4, 3, 2, 1, 1, 0, 0, 254, 252, 252, 250, 247, 247, 251, 5, 49, 81, 63, 56, 19, 247, 243, 214, 173, 187, 230, 19, 49, 50, 36, 15, 1, 238, 212, 197, 195, 225, 6, 27, 34, 29, 21, 15, 0, 231, 215, 206, 212, 232, 253, 8, 20, 35, 34, 30, 9, 234, 224, 235, 251, 5, 17, 23, 34, 37, 24, 248, 234, 244, 250, 2, 3, 11, 11, 248, 218, 252, 35, 31, 28, 2, 255, 8, 3, 255, 27, 30, 29, 13, 4, 241, 229, 245, 254, 251, 4, 247, 232, 235, 241, 242, 223, 224, 249, 9, 254, 245, 241, 247, 251, 0, 248, 253, 9, 18, 15, 8, 253, 239, 232, 244, 250, 6, 22, 41, 39, 30, 14, 247, 240, 236, 254, 11, 15, 20, 19, 13, 252, 241, 236, 239, 243, 247, 5, 24, 31, 10, 244, 220, 209, 208, 232, 5, 28, 40, 34, 10, 236, 215, 224, 241, 2, 15, 21, 20, 20, 16, 10, 0, 244, 237, 244, 0, 9, 18, 22, 21, 13, 4, 255, 252, 253, 1, 4, 4, 2, 1, 0, 255, 254, 253, 254, 255, 0, 2, 5, 7, 8, 8, 4, 0, 0, 253, 252, 253, 1, 5, 9, 10, 7, 6, 5, 255, 251, 251, 252, 0, 3, 1, 5, 5, 1, 1, 255, 255, 2, 6, 5, 5, 5, 1, 254, 247, 248, 252, 0, 1, 2, 2, 2, 255, 252, 249, 252, 0, 254, 254, 253, 246, 245, 245, 249, 255, 6, 14, 14, 6, 250, 240, 235, 236, 244, 253, 9, 21, 25, 21, 9, 255, 242, 234, 234, 244, 3, 15, 13, 13, 12, 11, 4, 252, 244, 239, 242, 247, 252, 4, 12, 15, 7, 251, 242, 240, 243, 248, 1, 16, 19, 14, 2, 246, 244, 246, 248, 253, 4, 11, 10, 6, 0, 1, 5, 2, 255, 246, 241, 240, 241, 246, 254, 5, 9, 5, 0, 249, 247, 246, 240, 246, 250, 251, 250, 248, 244, 247, 251, 1, 5, 8, 3, 254, 248, 243, 239, 249, 3, 9, 16, 19, 14, 9, 3, 253, 255, 1, 3, 10, 18, 22, 19, 17, 15, 15, 14, 13, 14, 14, 14, 13, 11, 9, 5, 0, 250, 243, 239, 237, 240, 250, 3, 15, 22, 26, 33, 34, 37, 37, 30, 29, 27, 25, 26, 24, 20, 18, 17, 16, 17, 21, 21, 17, 9, 1, 249, 241, 233, 228, 228, 228, 231, 234, 234, 236, 237, 235, 233, 233, 226, 225, 222, 221, 224, 229, 237, 248, 0, 2, 2, 4, 3, 255, 254, 253, 253, 252, 253, 0, 4, 5, 9, 9, 6, 6, 3, 0, 252, 249, 245, 245, 242, 246, 250, 255, 255, 254, 249, 247, 244, 247, 253, 253, 255, 255, 0, 255, 252, 247, 250, 0, 10, 13, 12, 10, 3, 254, 248, 247, 253, 4, 12, 19, 17, 12, 6, 1, 253, 255, 255, 252, 0, 253, 252, 255, 255, 2, 5, 3, 248, 242, 236, 234, 233, 239, 239, 249, 6, 9, 9, 5, 248, 235, 225, 228, 246, 20, 40, 37, 22, 0, 240, 229, 226, 232, 254, 17, 20, 18, 13, 4, 251, 245, 241, 242, 245, 248, 249, 246, 241, 235, 228, 221, 218, 222, 244, 28, 71, 109, 116, 116, 110, 105, 87, 53, 16, 1, 4, 29, 56, 80, 86, 83, 79, 65, 53, 35, 18, 8, 0, 243, 229, 212, 209, 212, 219, 226, 232, 239, 236, 224, 214, 210, 205, 207, 209, 209, 204, 192, 187, 189, 201, 221, 242, 8, 19, 21, 10, 249, 233, 222, 220, 221, 232, 247, 3, 15, 24, 27, 22, 9, 254, 248, 249, 253, 255, 2, 2, 2, 0, 253, 252, 248, 245, 245, 253, 4, 9, 11, 13, 8, 255, 240, 233, 233, 227, 233, 246, 11, 25, 36, 31, 18, 254, 246, 239, 251, 0, 5, 17, 12, 19, 11, 16, 12, 3, 254, 246, 246, 254, 5, 16, 14, 10, 11, 2, 253, 240, 242, 247, 246, 247, 253, 14, 28, 22, 12, 0, 0, 254, 248, 244, 249, 0, 7, 13, 17, 22, 19, 14, 9, 0, 249, 251, 252, 0, 5, 12, 13, 13, 9, 5, 0, 254, 254, 254, 255, 1, 2, 2, 2, 2, 2, 2, 3, 6, 4, 3, 0, 0, 0, 1, 2, 2, 2, 0, 255, 254, 252, 251, 251, 252, 253, 254, 255, 255, 0, 0, 255, 253, 251, 249, 248, 248, 249, 251, 252, 255, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 1, 2, 2, 2, 2, 2, 2, 2, 0, 2, 0, 0, 0, 0, 1, 0, 254, 254, 254, 1, 2, 3, 3, 3, 3, 0, 0, 0, 253, 253, 254, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 5, 5, 2, 5, 6, 6, 6, 3, 6, 6, 3, 3, 4, 4, 4, 1, 1, 2, 2, 3, 4, 4, 1, 1, 255, 255, 255, 0, 253, 0, 254, 254, 255, 255, 255, 252, 252, 253, 253, 253, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 252, 249, 249, 252, 252, 251, 251, 254, 254, 0, 0, 0, 255, 255, 1, 1, 0, 0, 255, 255, 2, 5, 5, 4, 4, 3, 2, 2, 2, 2, 5, 5, 5, 4, 4, 3, 3, 2, 2, 2, 5, 5, 6, 9, 9, 9, 9, 5, 1, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 255, 255, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 1, 255, 255, 1, 255, 1, 2, 5, 2, 1, 1, 1, 255, 1, 1, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 253, 253, 253, 253, 254, 0, 1, 1, 1, 1, 0, 254, 254, 0, 1, 1, 255, 0, 0, 254, 254, 0, 0, 255, 0, 0, 0, 254, 0, 0, 0, 0, 3, 0, 3, 0, 254, 252, 249, 253, 0, 255, 1, 7, 27, 58, 60, 55, 18, 245, 221, 212, 188, 188, 210, 251, 40, 62, 54, 29, 5, 243, 222, 205, 201, 222, 1, 27, 44, 43, 31, 17, 0, 236, 219, 210, 218, 236, 0, 16, 19, 24, 16, 2, 240, 230, 221, 246, 16, 20, 36, 22, 15, 251, 237, 243, 237, 0, 4, 8, 9, 57, 46, 9, 220, 224, 247, 241, 246, 254, 54, 31, 11, 245, 226, 245, 242, 246, 254, 249, 252, 4, 10, 17, 36, 255, 225, 222, 243, 245, 249, 27, 21, 23, 13, 244, 238, 232, 236, 3, 12, 3, 19, 11, 9, 2, 239, 242, 243, 254, 5, 3, 15, 22, 16, 10, 3, 5, 11, 17, 22, 25, 25, 13, 255, 240, 236, 238, 254, 5, 12, 12, 33, 29, 71, 24, 253, 231, 240, 227, 212, 220, 244, 22, 24, 0, 223, 234, 232, 0, 240, 232, 234, 237, 219, 222, 239, 250, 20, 15, 5, 252, 0, 240, 245, 255, 0, 11, 20, 17, 9, 10, 9, 6, 6, 8, 0, 12, 14, 13, 16, 11, 1, 250, 250, 251, 253, 0, 252, 2, 3, 249, 244, 240, 241, 246, 250, 253, 246, 248, 248, 252, 255, 254, 252, 248, 246, 246, 251, 251, 255, 9, 17, 21, 19, 11, 5, 0, 253, 252, 248, 252, 4, 16, 22, 22, 20, 9, 4, 0, 250, 249, 250, 5, 11, 13, 16, 11, 0, 248, 248, 254, 253, 4, 13, 21, 21, 13, 8, 4, 0, 253, 0, 255, 9, 19, 25, 29, 19, 13, 2, 252, 252, 254, 0, 5, 11, 13, 10, 3, 253, 250, 247, 245, 243, 247, 249, 254, 252, 253, 252, 247, 246, 246, 243, 244, 248, 249, 249, 248, 245, 244, 244, 247, 251, 253, 3, 3, 4, 250, 242, 244, 250, 244, 247, 254, 9, 15, 19, 17, 8, 255, 243, 238, 237, 240, 246, 2, 17, 25, 18, 8, 252, 245, 239, 233, 240, 252, 6, 14, 11, 9, 7, 255, 245, 236, 236, 250, 3, 12, 19, 18, 10, 3, 243, 227, 224, 228, 237, 254, 10, 20, 18, 4, 241, 230, 226, 229, 235, 241, 247, 250, 252, 251, 248, 245, 244, 246, 254, 9, 19, 19, 16, 9, 0, 250, 248, 251, 6, 18, 29, 32, 24, 18, 11, 6, 3, 6, 11, 22, 23, 21, 24, 20, 16, 9, 8, 8, 9, 12, 8, 0, 250, 245, 248, 2, 16, 39, 54, 65, 66, 62, 51, 35, 19, 4, 255, 0, 10, 22, 28, 28, 27, 20, 15, 4, 253, 249, 242, 234, 230, 222, 217, 213, 212, 215, 218, 220, 226, 228, 233, 233, 230, 225, 220, 215, 214, 214, 220, 227, 238, 249, 0, 7, 12, 7, 1, 252, 250, 249, 249, 255, 2, 8, 8, 8, 7, 10, 10, 14, 18, 22, 23, 23, 18, 11, 6, 0, 0, 254, 1, 3, 12, 17, 19, 19, 8, 2, 248, 240, 236, 240, 244, 249, 253, 0, 3, 2, 1, 253, 252, 251, 253, 252, 255, 1, 4, 7, 5, 1, 0, 2, 6, 7, 14, 13, 9, 0, 248, 243, 239, 235, 237, 241, 247, 1, 9, 8, 0, 246, 238, 229, 227, 231, 241, 252, 2, 6, 7, 6, 3, 254, 248, 242, 244, 247, 253, 0, 3, 8, 3, 251, 245, 243, 249, 255, 7, 17, 16, 7, 251, 246, 252, 253, 1, 3, 6, 6, 5, 2, 255, 250, 246, 242, 239, 238, 238, 239, 237, 234, 229, 217, 205, 205, 241, 32, 85, 113, 111, 109, 102, 98, 82, 46, 23, 18, 25, 46, 64, 73, 80, 73, 65, 54, 41, 39, 34, 26, 16, 253, 234, 217, 208, 210, 210, 214, 226, 225, 225, 221, 216, 211, 207, 198, 195, 194, 186, 185, 187, 195, 213, 233, 249, 5, 7, 3, 249, 245, 243, 245, 251, 255, 5, 11, 7, 5, 4, 8, 13, 22, 27, 28, 25, 21, 10, 0, 248, 246, 247, 250, 255, 253, 254, 255, 0, 254, 255, 255, 251, 247, 243, 238, 237, 237, 244, 248, 251, 254, 253, 255, 1, 4, 6, 8, 7, 5, 4, 5, 1, 4, 4, 9, 10, 9, 10, 15, 9, 7, 2, 0, 2, 6, 7, 7, 3, 255, 253, 247, 251, 2, 6, 2, 250, 244, 240, 247, 251, 255, 1, 0, 0, 254, 0, 252, 255, 1, 6, 3, 2, 8, 7, 8, 1, 1, 7, 14, 11, 11, 10, 9, 4, 254, 250, 0, 4, 9, 7, 8, 3, 254, 253, 0, 253, 255, 252, 254, 9, 9, 12, 13, 11, 4, 0, 249, 248, 248, 246, 253, 1, 6, 10, 6, 7, 3, 251, 243, 243, 244, 253, 1, 1, 1, 254, 2, 255, 251, 251, 0, 0, 0, 253, 254, 254, 253, 252, 252, 251, 251, 252, 254, 255, 0, 0, 253, 249, 245, 244, 244, 247, 0, 10, 22, 34, 41, 37, 32, 19, 10, 6, 7, 12, 17, 23, 24, 21, 19, 16, 14, 16, 15, 17, 20, 14, 8, 2, 249, 243, 241, 244, 246, 249, 251, 253, 255, 252, 250, 251, 249, 246, 243, 239, 232, 228, 233, 238, 243, 248, 248, 248, 248, 243, 239, 238, 242, 242, 250, 249, 248, 248, 247, 246, 245, 248, 252, 2, 2, 9, 4, 3, 3, 2, 2, 2, 1, 254, 0, 0, 4, 4, 9, 8, 4, 4, 4, 0, 0, 0, 0, 64, 4, 31, 0, 0, 2, 7, 12, 13, 8, 3, 255, 251, 245, 242, 243, 251, 3, 7, 5, 255, 249, 248, 253, 1, 6, 8, 5, 0, 249, 246, 252, 5, 13, 12, 4, 252, 248, 249, 251, 255, 4, 8, 8, 2, 252, 251, 0, 6, 7, 4, 255, 252, 252, 252, 252, 253, 253, 254, 255, 2, 9, 15, 16, 11, 3, 251, 244, 240, 240, 248, 3, 13, 15, 9, 0, 248, 243, 242, 246, 0, 8, 15, 15, 9, 0, 248, 245, 248, 254, 1, 5, 8, 8, 4, 253, 246, 246, 251, 2, 9, 14, 14, 8, 253, 239, 232, 236, 248, 4, 15, 22, 20, 9, 247, 230, 226, 238, 3, 27, 40, 39, 26, 8, 247, 234, 232, 245, 9, 31, 51, 65, 66, 45, 4, 216, 186, 181, 201, 235, 10, 30, 28, 7, 234, 210, 202, 214, 236, 2, 19, 27, 24, 12, 253, 237, 226, 222, 227, 243, 8, 30, 38, 29, 8, 245, 234, 237, 250, 11, 26, 32, 26, 11, 253, 242, 242, 249, 2, 10, 15, 15, 11, 5, 0, 253, 250, 249, 251, 0, 8, 14, 16, 9, 255, 244, 241, 245, 251, 0, 5, 7, 6, 2, 255, 252, 250, 250, 252, 0, 6, 9, 7, 2, 255, 254, 254, 0, 0, 1, 2, 3, 4, 4, 3, 1, 0, 0, 1, 2, 3, 5, 5, 3, 0, 254, 253, 254, 255, 0, 1, 0, 253, 250, 251, 254, 0, 0, 0, 1, 1, 0, 253, 251, 252, 254, 255, 255, 254, 255, 0, 255, 255, 255, 255, 254, 254, 0, 0, 1, 0, 0, 0, 2, 2, 1, 0, 255, 0, 0, 1, 3, 4, 3, 2, 1, 0, 0, 0, 2, 4, 6, 6, 5, 3, 3, 4, 3, 0, 254, 253, 254, 0, 2, 2, 0, 0, 1, 2, 1, 0, 255, 255, 0, 1, 2, 0, 0, 255, 0, 255, 252, 251, 251, 254, 0, 1, 1, 0, 0, 254, 252, 252, 254, 0, 1, 3, 2, 0, 254, 253, 254, 255, 0, 1, 2, 1, 0, 0, 0, 2, 3, 3, 3, 2, 2, 1, 1, 1, 2, 2, 3, 2, 0, 255, 255, 1, 4, 4, 2, 0, 0, 0, 0, 3, 15, 29, 28, 0, 214, 196, 219, 4, 32, 32, 16, 0, 249, 241, 233, 234, 252, 19, 32, 23, 1, 240, 233, 238, 247, 0, 9, 15, 16, 6, 246, 235, 238, 253, 13, 23, 18, 4, 250, 254, 18, 45, 54, 24, 223, 180, 186, 233, 29, 56, 55, 43, 30, 14, 252, 241, 244, 244, 216, 165, 130, 153, 228, 51, 87, 80, 59, 43, 20, 234, 188, 173, 199, 242, 14, 23, 26, 34, 39, 31, 16, 9, 14, 22, 19, 4, 239, 223, 223, 238, 254, 2, 251, 240, 239, 250, 7, 14, 14, 11, 4, 247, 229, 219, 226, 244, 3, 12, 19, 29, 40, 45, 44, 39, 29, 11, 246, 226, 217, 220, 229, 236, 241, 247, 255, 2, 3, 2, 5, 14, 25, 28, 23, 15, 10, 10, 8, 0, 244, 238, 240, 247, 253, 2, 10, 18, 23, 27, 28, 24, 11, 248, 230, 221, 224, 233, 243, 251, 0, 3, 0, 252, 248, 247, 245, 244, 246, 253, 12, 31, 44, 41, 26, 7, 250, 244, 242, 244, 251, 4, 9, 4, 249, 238, 234, 236, 241, 247, 3, 18, 29, 27, 14, 1, 254, 255, 252, 243, 235, 234, 242, 253, 4, 10, 14, 15, 10, 0, 243, 234, 235, 244, 0, 9, 14, 13, 10, 5, 255, 250, 248, 249, 250, 248, 246, 247, 251, 2, 10, 16, 17, 11, 0, 246, 240, 242, 251, 4, 11, 10, 4, 253, 248, 251, 2, 9, 13, 12, 8, 3, 254, 250, 247, 248, 251, 254, 1, 6, 11, 16, 16, 10, 1, 248, 243, 244, 248, 253, 1, 4, 6, 6, 4, 1, 255, 255, 0, 3, 2, 0, 253, 253, 255, 4, 8, 9, 5, 255, 247, 243, 244, 248, 254, 1, 6, 12, 16, 14, 7, 0, 253, 250, 248, 249, 253, 2, 6, 5, 1, 255, 0, 2, 2, 0, 254, 253, 255, 0, 0, 0, 0, 0, 254, 253, 253, 1, 6, 11, 11, 7, 0, 245, 238, 239, 247, 0, 6, 9, 9, 9, 8, 5, 2, 0, 251, 247, 248, 253, 3, 10, 14, 11, 3, 252, 246, 244, 246, 251, 0, 6, 9, 9, 7, 2, 253, 248, 246, 247, 251, 0, 6, 11, 11, 5, 255, 250, 248, 248, 252, 1, 7, 10, 8, 2, 254, 249, 247, 247, 250, 255, 2, 5, 6, 4, 0, 249, 240, 235, 236, 245, 5, 26, 43, 48, 39, 18, 248, 227, 221, 233, 4, 38, 66, 75, 60, 26, 244, 212, 196, 199, 218, 248, 16, 27, 19, 0, 232, 216, 210, 214, 229, 252, 17, 32, 32, 19, 254, 231, 216, 215, 228, 252, 19, 32, 30, 16, 254, 238, 234, 241, 0, 16, 29, 30, 21, 8, 254, 248, 247, 249, 254, 5, 14, 19, 16, 9, 0, 250, 246, 246, 253, 5, 11, 11, 7, 1, 252, 247, 244, 246, 252, 4, 9, 8, 3, 254, 251, 250, 253, 0, 1, 3, 4, 4, 3, 3, 1, 0, 254, 254, 0, 4, 5, 5, 3, 2, 1, 0, 0, 0, 3, 5, 6, 5, 2, 0, 252, 251, 252, 255, 1, 3, 3, 2, 0, 254, 253, 254, 255, 255, 255, 255, 0, 0, 255, 253, 251, 250, 252, 255, 0, 1, 0, 255, 253, 253, 252, 252, 253, 0, 1, 1, 0, 0, 1, 2, 2, 2, 2, 1, 0, 0, 1, 3, 5, 5, 4, 3, 3, 3, 3, 1, 0, 0, 1, 2, 3, 3, 2, 2, 1, 0, 0, 0, 1, 3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 253, 253, 254, 255, 0, 1, 2, 0, 253, 249, 247, 249, 253, 0, 4, 4, 4, 4, 4, 3, 1, 254, 251, 249, 250, 254, 1, 3, 3, 3, 2, 0, 0, 0, 0, 2, 3, 2, 0, 0, 1, 3, 3, 1, 0, 1, 2, 3, 4, 3, 1, 0, 255, 252, 252, 253, 0, 2, 4, 3, 1, 0, 0, 1, 2, 1, 0, 0, 0, 254, 253, 255, 1, 2, 0, 251, 250, 255, 3, 4, 0, 254, 255, 1, 2, 0, 254, 252, 252, 253, 253, 252, 255, 7, 15, 18, 19, 25, 21, 0, 232, 235, 6, 26, 5, 216, 200, 241, 41, 58, 27, 252, 5, 44, 55, 13, 207, 179, 145, 0, 4, 0, 69, 0, 208, 0, 128, 2, 160, 5, 56, 9, 128, 12, 148, 17, 244, 26, 60, 5, 21, 12, 9, 15, 6, 6, 0, 0, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 44, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 69, 0, 208, 0, 128, 2, 160, 5, 56, 9, 128, 12, 148, 17, 244, 26, 45, 5, 22, 12, 9, 16, 6, 6, 0, 0, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 43, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 69, 0, 192, 0, 24, 2, 80, 5, 136, 9, 128, 12, 148, 17, 244, 26, 40, 9, 19, 25, 25, 19, 6, 6, 0, 0, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 45, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 192, 0, 24, 2, 80, 5, 136, 9, 128, 12, 148, 17, 244, 26, 0, 9, 19, 25, 25, 19, 6, 6, 0, 0, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 45, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 3, 15, 38, 0, 253, 255, 1, 1, 0, 253, 252, 253, 253, 255, 252, 253, 0, 0, 1, 254, 252, 253, 2, 10, 19, 28, 37, 42, 43, 32, 0, 224, 200, 200, 223, 243, 253, 252, 247, 246, 242, 244, 1, 17, 31, 30, 13, 0, 245, 241, 248, 255, 6, 9, 9, 12, 13, 15, 16, 11, 6, 0, 251, 248, 245, 245, 244, 242, 242, 242, 247, 255, 7, 14, 14, 8, 255, 248, 246, 248, 254, 1, 2, 3, 4, 5, 8, 12, 17, 19, 19, 16, 12, 6, 253, 242, 235, 234, 236, 240, 243, 247, 251, 253, 253, 0, 4, 10, 13, 14, 12, 5, 0, 255, 255, 2, 7, 10, 12, 10, 4, 0, 254, 253, 254, 254, 252, 249, 245, 242, 242, 245, 250, 255, 4, 9, 10, 9, 8, 6, 5, 5, 4, 3, 2, 0, 253, 252, 252, 251, 253, 255, 1, 5, 7, 8, 5, 1, 251, 247, 248, 251, 1, 3, 1, 0, 255, 0, 2, 6, 11, 15, 14, 9, 255, 244, 237, 238, 244, 249, 253, 255, 0, 1, 254, 253, 255, 3, 6, 4, 5, 9, 9, 4, 2, 6, 21, 33, 33, 23, 2, 237, 224, 221, 232, 246, 0, 3, 252, 241, 236, 240, 252, 7, 15, 18, 14, 4, 252, 248, 252, 1, 5, 6, 8, 10, 12, 12, 12, 9, 5, 255, 250, 249, 251, 252, 253, 250, 247, 245, 247, 253, 4, 8, 8, 4, 254, 249, 247, 250, 255, 1, 3, 3, 1, 1, 0, 3, 6, 9, 10, 10, 8, 4, 2, 0, 0, 0, 0, 255, 252, 251, 250, 252, 254, 253, 254, 254, 0, 255, 253, 252, 252, 254, 255, 0, 4, 10, 12, 12, 9, 5, 3, 1, 1, 1, 1, 0, 253, 249, 247, 249, 251, 0, 3, 4, 0, 253, 251, 252, 255, 1, 2, 4, 6, 4, 4, 3, 3, 4, 2, 0, 255, 0, 2, 0, 254, 250, 247, 247, 250, 0, 7, 9, 7, 5, 2, 0, 0, 0, 3, 6, 4, 0, 254, 252, 252, 252, 254, 1, 6, 9, 6, 3, 2, 254, 247, 246, 248, 252, 254, 252, 249, 250, 252, 254, 0, 6, 11, 9, 5, 2, 0, 6, 10, 17, 29, 33, 22, 5, 240, 231, 231, 236, 246, 252, 253, 253, 244, 241, 244, 250, 4, 11, 10, 8, 0, 253, 252, 251, 0, 4, 7, 11, 11, 12, 14, 11, 9, 5, 0, 255, 251, 250, 251, 250, 250, 250, 250, 253, 0, 3, 6, 5, 2, 254, 247, 245, 246, 250, 255, 1, 3, 4, 5, 6, 7, 9, 11, 9, 6, 2, 0, 253, 255, 3, 3, 2, 3, 255, 246, 246, 249, 254, 2, 255, 253, 253, 255, 252, 249, 0, 5, 7, 6, 4, 6, 8, 6, 4, 3, 2, 2, 2, 1, 0, 0, 254, 250, 247, 246, 249, 254, 2, 2, 0, 0, 255, 254, 0, 3, 7, 9, 9, 5, 2, 0, 0, 0, 0, 0, 0, 255, 254, 253, 252, 252, 253, 255, 1, 4, 5, 4, 5, 3, 1, 1, 255, 254, 255, 253, 254, 0, 2, 5, 7, 4, 1, 1, 1, 1, 0, 255, 253, 253, 253, 251, 251, 255, 4, 6, 7, 2, 255, 250, 246, 245, 247, 253, 0, 0, 0, 1, 2, 6, 9, 14, 21, 26, 28, 22, 8, 250, 237, 231, 232, 238, 248, 0, 1, 0, 253, 252, 254, 0, 2, 3, 1, 254, 249, 246, 248, 251, 0, 7, 13, 18, 20, 19, 15, 9, 2, 253, 247, 244, 245, 247, 251, 254, 0, 0, 0, 1, 4, 6, 7, 6, 1, 251, 245, 242, 242, 247, 254, 4, 10, 13, 13, 9, 6, 3, 2, 2, 1, 1, 0, 254, 254, 255, 0, 3, 1, 253, 250, 252, 255, 0, 0, 1, 0, 253, 247, 246, 253, 3, 8, 11, 13, 11, 6, 1, 254, 255, 0, 0, 0, 0, 255, 253, 252, 253, 254, 0, 0, 1, 0, 1, 0, 253, 250, 250, 254, 1, 6, 8, 8, 7, 5, 0, 255, 0, 1, 2, 2, 2, 0, 254, 250, 250, 252, 0, 2, 1, 0, 0, 0, 0, 0, 2, 5, 5, 1, 255, 254, 253, 254, 0, 1, 3, 3, 3, 3, 4, 5, 3, 3, 0, 252, 250, 252, 255, 1, 2, 0, 254, 253, 253, 251, 255, 2, 4, 5, 0, 250, 249, 251, 254, 0, 4, 6, 6, 6, 7, 10, 16, 21, 18, 9, 0, 244, 237, 236, 238, 246, 255, 1, 4, 5, 4, 3, 0, 0, 254, 252, 252, 250, 250, 253, 252, 254, 3, 7, 13, 16, 14, 12, 7, 2, 253, 248, 247, 249, 251, 253, 255, 0, 3, 4, 5, 6, 5, 3, 255, 251, 248, 248, 249, 251, 253, 0, 1, 3, 6, 8, 8, 8, 7, 5, 1, 255, 254, 253, 253, 254, 255, 1, 4, 4, 2, 254, 252, 252, 251, 248, 248, 254, 2, 3, 2, 2, 4, 6, 7, 7, 9, 7, 0, 250, 247, 251, 0, 2, 2, 1, 0, 254, 0, 2, 4, 3, 0, 248, 245, 247, 252, 0, 4, 6, 6, 5, 5, 6, 11, 13, 6, 251, 242, 245, 254, 1, 3, 0, 0, 253, 246, 253, 0, 5, 8, 4, 254, 251, 253, 252, 6, 11, 12, 11, 255, 246, 251, 255, 255, 255, 0, 3, 1, 254, 3, 5, 4, 5, 2, 0, 3, 252, 245, 247, 250, 251, 5, 10, 7, 7, 6, 2, 0, 254, 253, 251, 248, 244, 243, 249, 0, 1, 8, 15, 12, 11, 12, 11, 13, 14, 5, 252, 247, 240, 240, 246, 251, 2, 8, 8, 4, 0, 0, 0, 253, 252, 248, 245, 247, 247, 251, 2, 7, 7, 11, 9, 10, 11, 9, 5, 1, 254, 250, 249, 249, 251, 255, 2, 4, 6, 6, 5, 1, 254, 250, 248, 251, 253, 253, 0, 0, 0, 3, 2, 1, 5, 6, 4, 4, 3, 2, 2, 1, 0, 255, 254, 255, 1, 4, 5, 4, 1, 251, 245, 242, 243, 251, 3, 6, 8, 5, 254, 251, 255, 4, 8, 10, 8, 2, 0, 254, 250, 1, 4, 1, 254, 254, 1, 4, 4, 0, 255, 249, 240, 243, 251, 5, 16, 14, 9, 4, 1, 252, 244, 251, 5, 9, 14, 7, 0, 254, 241, 236, 255, 3, 3, 10, 3, 252, 1, 2, 249, 245, 252, 16, 23, 13, 253, 244, 233, 240, 1, 3, 17, 28, 0, 254, 12, 4, 254, 3, 250, 244, 3, 251, 233, 239, 5, 9, 3, 16, 22, 7, 6, 241, 228, 255, 16, 5, 254, 253, 244, 248, 248, 6, 20, 11, 3, 244, 232, 251, 5, 10, 13, 6, 246, 245, 0, 15, 30, 38, 30, 4, 239, 230, 224, 228, 249, 6, 8, 10, 5, 252, 255, 2, 1, 254, 251, 246, 249, 251, 254, 6, 5, 2, 5, 3, 4, 12, 15, 10, 6, 1, 246, 239, 243, 250, 251, 255, 2, 2, 7, 9, 7, 9, 4, 255, 252, 249, 250, 0, 1, 253, 1, 2, 254, 0, 10, 13, 11, 13, 6, 251, 242, 251, 254, 248, 0, 6, 252, 246, 254, 254, 254, 10, 9, 252, 250, 253, 242, 239, 0, 17, 10, 6, 27, 23, 0, 3, 7, 251, 238, 243, 250, 247, 10, 8, 245, 247, 4, 0, 251, 20, 32, 10, 252, 248, 236, 236, 238, 233, 243, 32, 15, 2, 29, 3, 248, 5, 15, 0, 1, 27, 242, 239, 213, 196, 253, 20, 37, 79, 92, 5, 232, 236, 200, 180, 193, 4, 26, 12, 21, 25, 12, 19, 28, 235, 255, 36, 3, 237, 236, 235, 227, 223, 228, 248, 28, 64, 58, 39, 28, 255, 221, 205, 201, 210, 246, 255, 254, 18, 32, 23, 12, 21, 30, 30, 13, 249, 245, 246, 240, 223, 236, 255, 2, 14, 21, 21, 20, 22, 255, 235, 232, 231, 230, 239, 248, 3, 8, 7, 6, 8, 10, 9, 6, 2, 3, 0, 248, 242, 244, 251, 0, 7, 14, 19, 20, 14, 6, 250, 245, 241, 240, 240, 247, 3, 9, 9, 10, 8, 8, 6, 3, 2, 1, 251, 249, 249, 248, 248, 250, 1, 10, 17, 23, 16, 9, 4, 247, 235, 230, 232, 238, 251, 2, 7, 8, 9, 5, 6, 3, 3, 5, 6, 7, 2, 254, 251, 1, 253, 252, 7, 19, 11, 5, 0, 251, 254, 239, 232, 242, 4, 1, 253, 10, 16, 13, 253, 251, 9, 6, 1, 0, 254, 254, 242, 241, 18, 27, 249, 243, 12, 7, 251, 255, 255, 4, 255, 232, 231, 255, 14, 23, 15, 3, 11, 18, 246, 232, 247, 251, 0, 0, 0, 12, 17, 1, 243, 248, 2, 0, 2, 4, 4, 255, 247, 240, 250, 8, 16, 16, 8, 3, 255, 249, 245, 247, 247, 247, 245, 252, 5, 12, 11, 13, 19, 16, 8, 0, 253, 0, 2, 254, 248, 248, 247, 247, 248, 0, 10, 16, 15, 9, 1, 249, 244, 237, 239, 250, 0, 4, 7, 4, 5, 6, 2, 2, 0, 2, 1, 0, 0, 255, 0, 1, 255, 0, 2, 2, 2, 5, 5, 1, 255, 253, 253, 251, 253, 1, 1, 1, 2, 1, 4, 2, 254, 253, 0, 1, 3, 2, 1, 2, 3, 3, 0, 1, 5, 6, 3, 254, 248, 244, 242, 243, 248, 253, 4, 10, 13, 10, 5, 6, 2, 0, 7, 4, 0, 0, 248, 243, 248, 0, 8, 12, 9, 2, 2, 254, 250, 255, 0, 254, 250, 246, 246, 255, 3, 2, 12, 12, 5, 1, 0, 252, 3, 9, 3, 1, 0, 252, 247, 251, 4, 7, 15, 10, 255, 255, 250, 241, 241, 247, 248, 255, 3, 254, 0, 9, 14, 13, 12, 11, 7, 3, 252, 245, 251, 0, 253, 254, 253, 251, 252, 254, 255, 2, 6, 7, 7, 3, 253, 247, 250, 254, 5, 10, 13, 7, 1, 249, 251, 253, 254, 2, 3, 0, 252, 251, 251, 0, 2, 4, 3, 3, 0, 254, 255, 253, 1, 0, 0, 4, 2, 2, 4, 3, 2, 11, 13, 5, 255, 248, 247, 248, 248, 250, 255, 3, 5, 6, 4, 3, 3, 254, 249, 249, 251, 0, 2, 1, 0, 2, 255, 255, 3, 5, 4, 10, 9, 2, 254, 251, 245, 250, 255, 4, 4, 4, 5, 0, 252, 255, 4, 3, 255, 0, 252, 255, 1, 1, 3, 4, 8, 5, 254, 254, 0, 254, 253, 4, 2, 0, 0, 246, 247, 0, 5, 4, 9, 3, 3, 249, 240, 244, 0, 0, 8, 21, 11, 1, 255, 253, 251, 3, 9, 9, 255, 249, 238, 233, 237, 251, 2, 17, 24, 24, 7, 254, 254, 3, 11, 15, 6, 252, 2, 23, 46, 235, 133, 179, 224, 23, 75, 51, 25, 25, 234, 202, 2, 36, 20, 15, 251, 219, 230, 243, 237, 2, 33, 20, 6, 5, 2, 2, 14, 0, 242, 243, 238, 231, 249, 11, 31, 41, 32, 1, 244, 237, 237, 240, 248, 252, 251, 250, 250, 3, 18, 29, 26, 13, 246, 241, 246, 247, 244, 252, 0, 253, 0, 255, 5, 13, 6, 1, 7, 2, 0, 245, 246, 255, 3, 255, 247, 250, 4, 15, 20, 29, 31, 12, 246, 230, 226, 232, 243, 3, 14, 17, 13, 7, 0, 1, 2, 250, 244, 238, 237, 245, 1, 8, 14, 18, 7, 253, 251, 0, 6, 9, 8, 0, 246, 240, 242, 246, 3, 12, 13, 13, 10, 4, 4, 4, 0, 252, 246, 242, 245, 252, 3, 10, 12, 7, 3, 2, 4, 7, 9, 5, 255, 252, 253, 255, 253, 252, 248, 248, 250, 249, 255, 254, 255, 254, 255, 0, 1, 5, 5, 7, 8, 3, 1, 253, 251, 254, 13, 15, 10, 10, 255, 244, 247, 253, 2, 4, 4, 249, 244, 247, 250, 255, 9, 8, 0, 0, 4, 0, 0, 1, 254, 2, 7, 3, 0, 6, 7, 252, 251, 249, 253, 251, 3, 4, 10, 10, 246, 232, 248, 9, 11, 14, 27, 14, 246, 227, 222, 249, 12, 11, 18, 22, 6, 247, 244, 254, 1, 251, 240, 233, 246, 254, 254, 2, 0, 7, 3, 0, 2, 20, 33, 38, 32, 21, 4, 240, 226, 222, 237, 2, 6, 8, 10, 7, 6, 6, 1, 255, 247, 236, 222, 223, 239, 252, 8, 20, 20, 12, 3, 255, 0, 7, 11, 4, 249, 243, 242, 243, 252, 10, 20, 21, 12, 4, 5, 6, 4, 0, 250, 249, 250, 252, 0, 4, 8, 9, 2, 0, 0, 1, 255, 253, 249, 246, 248, 248, 252, 1, 8, 15, 15, 12, 6, 255, 249, 241, 240, 242, 242, 252, 0, 3, 13, 11, 10, 4, 254, 0, 2, 5, 6, 2, 253, 244, 244, 0, 5, 10, 17, 13, 7, 9, 254, 243, 240, 242, 242, 245, 2, 17, 24, 11, 250, 231, 240, 10, 7, 4, 3, 2, 9, 16, 15, 20, 28, 246, 208, 197, 230, 6, 16, 28, 31, 9, 254, 244, 226, 244, 17, 19, 6, 11, 7, 246, 232, 228, 245, 10, 27, 20, 12, 13, 5, 254, 254, 249, 250, 249, 241, 237, 248, 0, 5, 14, 16, 18, 12, 254, 244, 246, 246, 242, 242, 245, 254, 8, 15, 14, 14, 14, 4, 253, 252, 6, 14, 16, 11, 0, 247, 237, 231, 239, 255, 11, 19, 21, 16, 11, 1, 247, 236, 232, 232, 233, 241, 0, 12, 22, 24, 18, 7, 251, 244, 247, 252, 5, 12, 11, 253, 245, 247, 249, 2, 10, 16, 13, 4, 253, 251, 1, 0, 255, 255, 249, 244, 248, 0, 4, 19, 14, 255, 253, 253, 245, 251, 1, 4, 10, 7, 0, 253, 3, 0, 9, 6, 255, 252, 244, 238, 244, 250, 5, 3, 254, 0, 0, 4, 24, 23, 23, 13, 255, 246, 244, 242, 246, 236, 239, 0, 5, 245, 4, 14, 17, 20, 6, 249, 0, 12, 253, 247, 255, 251, 253, 248, 0, 4, 12, 13, 4, 1, 4, 249, 250, 243, 249, 2, 253, 251, 252, 9, 15, 18, 9, 7, 2, 247, 240, 237, 243, 254, 2, 9, 12, 13, 9, 8, 9, 9, 0, 243, 233, 237, 245, 255, 7, 10, 1, 4, 10, 10, 12, 14, 3, 241, 239, 240, 249, 8, 16, 8, 251, 248, 245, 253, 17, 25, 12, 1, 239, 226, 225, 245, 4, 14, 18, 16, 6, 255, 255, 253, 255, 6, 6, 1, 1, 10, 14, 15, 10, 0, 249, 244, 241, 245, 0, 9, 8, 5, 1, 255, 251, 250, 248, 246, 248, 248, 249, 0, 8, 13, 11, 7, 0, 250, 247, 253, 3, 7, 10, 4, 252, 253, 0, 0, 4, 8, 4, 1, 0, 254, 2, 4, 255, 249, 245, 248, 253, 8, 19, 25, 19, 4, 245, 238, 238, 247, 5, 12, 13, 6, 253, 251, 253, 255, 255, 254, 0, 252, 245, 246, 250, 0, 0, 3, 6, 6, 7, 4, 2, 1, 1, 254, 249, 249, 247, 250, 0, 4, 8, 16, 15, 17, 21, 33, 35, 23, 255, 228, 203, 181, 175, 214, 16, 67, 82, 56, 8, 227, 212, 208, 241, 31, 60, 45, 12, 236, 207, 213, 226, 235, 11, 43, 39, 34, 34, 23, 250, 225, 212, 205, 225, 249, 5, 24, 36, 36, 20, 7, 249, 236, 241, 239, 248, 5, 12, 6, 253, 245, 241, 233, 239, 244, 2, 21, 28, 26, 14, 253, 248, 253, 10, 22, 39, 40, 26, 2, 239, 231, 234, 244, 249, 249, 254, 254, 255, 0, 0, 254, 246, 239, 233, 238, 249, 3, 11, 11, 7, 254, 245, 245, 254, 10, 21, 20, 10, 255, 248, 246, 250, 1, 8, 15, 15, 8, 3, 1, 6, 8, 11, 6, 0, 251, 246, 248, 250, 253, 254, 0, 0, 2, 5, 11, 10, 9, 2, 248, 237, 230, 232, 237, 247, 253, 1, 4, 8, 13, 14, 13, 16, 10, 2, 248, 246, 249, 255, 1, 8, 11, 9, 6, 2, 255, 0, 5, 5, 1, 252, 242, 244, 245, 244, 255, 8, 13, 13, 9, 7, 3, 253, 250, 249, 242, 246, 253, 5, 4, 10, 8, 0, 253, 8, 10, 0, 2, 249, 237, 240, 252, 9, 5, 0, 8, 12, 9, 21, 38, 19, 250, 226, 203, 211, 231, 250, 24, 34, 27, 7, 245, 231, 237, 255, 250, 255, 11, 10, 7, 8, 18, 37, 45, 30, 7, 252, 234, 222, 230, 245, 11, 15, 4, 247, 242, 251, 0, 3, 8, 1, 249, 235, 224, 233, 244, 250, 0, 3, 9, 11, 14, 18, 20, 18, 11, 251, 240, 236, 242, 0, 10, 17, 21, 17, 12, 7, 6, 6, 2, 0, 252, 247, 248, 245, 241, 244, 252, 0, 6, 9, 10, 10, 8, 255, 251, 247, 245, 245, 247, 251, 5, 10, 6, 5, 254, 251, 253, 1, 2, 3, 1, 255, 252, 252, 254, 4, 7, 2, 253, 255, 7, 17, 19, 12, 12, 6, 243, 222, 231, 246, 0, 11, 18, 19, 10, 249, 234, 237, 1, 19, 18, 4, 242, 233, 237, 248, 13, 23, 24, 18, 5, 250, 247, 246, 250, 3, 254, 247, 255, 0, 255, 3, 1, 255, 6, 6, 11, 20, 10, 255, 247, 239, 242, 0, 252, 252, 6, 10, 0, 3, 0, 1, 11, 7, 251, 247, 252, 244, 250, 1, 10, 10, 0, 247, 244, 253, 4, 1, 255, 1, 2, 0, 0, 255, 6, 16, 13, 15, 18, 23, 13, 254, 245, 239, 241, 245, 245, 254, 6, 5, 2, 2, 0, 0, 253, 245, 241, 243, 246, 247, 253, 1, 8, 7, 5, 5, 4, 7, 7, 11, 7, 4, 254, 247, 247, 252, 3, 11, 11, 3, 1, 0, 0, 3, 7, 6, 0, 253, 251, 0, 0, 251, 249, 255, 253, 1, 13, 13, 12, 8, 248, 240, 241, 238, 242, 252, 255, 2, 5, 0, 255, 10, 15, 7, 6, 10, 2, 251, 251, 0, 5, 249, 252, 248, 253, 0, 33, 20, 8, 3, 240, 235, 244, 253, 2, 7, 249, 8, 19, 2, 1, 252, 240, 237, 232, 254, 24, 34, 26, 11, 248, 238, 245, 240, 11, 23, 21, 7, 1, 245, 225, 213, 239, 15, 22, 26, 16, 249, 250, 241, 243, 255, 5, 13, 7, 16, 5, 246, 235, 253, 255, 9, 26, 19, 16, 2, 240, 230, 237, 253, 253, 237, 226, 0, 11, 24, 24, 21, 1, 251, 249, 241, 252, 12, 4, 4, 9, 6, 8, 29, 31, 13, 250, 235, 231, 240, 6, 10, 4, 3, 252, 234, 232, 251, 2, 7, 8, 7, 250, 248, 243, 239, 248, 0, 0, 2, 11, 11, 11, 13, 6, 2, 253, 249, 247, 250, 3, 6, 9, 6, 8, 3, 3, 5, 9, 11, 6, 0, 248, 245, 243, 247, 3, 10, 10, 8, 10, 6, 1, 1, 0, 1, 251, 244, 231, 226, 230, 239, 250, 3, 13, 20, 20, 10, 8, 6, 6, 2, 254, 250, 252, 255, 1, 11, 16, 15, 11, 2, 1, 1, 0, 247, 240, 236, 235, 240, 247, 1, 13, 17, 17, 10, 5, 6, 6, 3, 6, 4, 255, 245, 241, 247, 252, 5, 7, 6, 1, 253, 252, 245, 240, 253, 11, 12, 12, 6, 2, 1, 0, 5, 7, 10, 2, 247, 243, 237, 235, 248, 252, 254, 0, 255, 250, 249, 250, 255, 248, 252, 0, 10, 17, 24, 32, 45, 55, 58, 47, 17, 236, 205, 203, 226, 2, 18, 14, 248, 222, 213, 218, 238, 0, 13, 11, 0, 247, 238, 234, 236, 241, 247, 251, 4, 17, 34, 45, 42, 20, 253, 236, 234, 237, 253, 10, 16, 15, 11, 7, 11, 21, 27, 26, 14, 3, 249, 238, 233, 231, 231, 239, 245, 0, 10, 20, 26, 18, 3, 233, 212, 211, 218, 231, 247, 9, 24, 26, 27, 24, 24, 22, 21, 16, 3, 248, 239, 235, 236, 238, 249, 4, 11, 18, 18, 16, 12, 7, 252, 238, 232, 225, 228, 241, 4, 24, 36, 34, 22, 12, 255, 245, 246, 245, 245, 244, 242, 245, 249, 0, 10, 11, 7, 2, 2, 13, 11, 0, 246, 244, 240, 243, 8, 26, 24, 20, 9, 2, 5, 250, 234, 227, 226, 218, 224, 236, 237, 11, 27, 26, 18, 14, 13, 14, 18, 33, 49, 60, 44, 8, 232, 202, 198, 216, 248, 23, 43, 38, 14, 247, 234, 231, 231, 225, 220, 223, 227, 237, 250, 4, 16, 17, 11, 3, 0, 8, 17, 24, 22, 10, 0, 237, 230, 232, 247, 13, 29, 38, 37, 33, 22, 6, 253, 243, 238, 237, 238, 246, 6, 17, 14, 10, 3, 254, 253, 250, 251, 255, 253, 246, 228, 220, 219, 225, 238, 255, 15, 27, 36, 37, 25, 13, 5, 0, 251, 249, 0, 2, 2, 5, 4, 3, 0, 250, 248, 250, 255, 250, 247, 3, 248, 237, 251, 3, 14, 33, 34, 19, 7, 1, 255, 247, 252, 255, 240, 235, 250, 244, 246, 3, 250, 244, 12, 21, 15, 4, 253, 3, 6, 242, 233, 254, 19, 30, 17, 3, 4, 9, 249, 234, 236, 246, 0, 0, 255, 0, 5, 6, 2, 4, 9, 1, 251, 248, 241, 235, 240, 239, 251, 11, 9, 4, 13, 21, 21, 26, 29, 27, 22, 10, 247, 230, 230, 238, 241, 252, 7, 12, 12, 11, 7, 3, 255, 244, 232, 226, 226, 231, 240, 250, 2, 8, 10, 11, 12, 13, 15, 16, 13, 8, 1, 252, 249, 247, 247, 250, 253, 0, 10, 19, 25, 21, 14, 3, 249, 239, 240, 244, 248, 255, 6, 10, 13, 16, 13, 7, 0, 248, 247, 240, 238, 240, 241, 241, 245, 248, 252, 2, 9, 15, 19, 13, 6, 1, 253, 248, 249, 0, 6, 3, 9, 14, 10, 14, 18, 1, 252, 252, 244, 243, 251, 239, 250, 5, 0, 4, 25, 7, 6, 255, 228, 245, 5, 13, 4, 247, 246, 2, 251, 17, 18, 5, 8, 253, 229, 233, 5, 9, 8, 6, 234, 235, 0, 8, 27, 37, 19, 8, 255, 242, 236, 0, 254, 247, 250, 250, 247, 6, 0, 2, 16, 7, 245, 7, 250, 241, 2, 0, 247, 1, 0, 254, 4, 7, 253, 255, 7, 15, 15, 21, 25, 17, 6, 248, 235, 237, 244, 247, 2, 8, 8, 6, 4, 2, 254, 247, 240, 234, 235, 243, 253, 4, 4, 7, 8, 3, 3, 6, 6, 6, 6, 4, 2, 255, 250, 247, 249, 250, 255, 7, 11, 13, 16, 15, 8, 1, 251, 250, 250, 250, 247, 248, 250, 0, 8, 13, 13, 12, 5, 255, 253, 0, 2, 4, 6, 5, 253, 240, 234, 236, 239, 240, 245, 255, 7, 11, 13, 16, 11, 5, 0, 251, 251, 1, 5, 6, 12, 16, 11, 0, 249, 243, 249, 2, 9, 7, 6, 3, 244, 240, 246, 248, 1, 16, 3, 0, 9, 6, 245, 253, 254, 246, 251, 11, 17, 16, 12, 4, 246, 245, 255, 252, 238, 0, 12, 0, 5, 6, 253, 3, 13, 245, 243, 7, 8, 249, 1, 254, 0, 49, 0, 3, 0, 5, 0, 76, 0, 44, 1, 20, 5, 84, 11, 112, 13, 135, 15, 160, 28, 10, 33, 11, 58, 50, 34, 55, 26, 13, 0, 150, 120, 120, 120, 120, 120, 90, 120, 75, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 124, 0, 184, 1, 20, 5, 84, 11, 52, 13, 110, 15, 160, 28, 39, 44, 29, 70, 56, 46, 61, 29, 14, 0, 120, 120, 120, 120, 120, 120, 60, 60, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 208, 0, 13, 2, 106, 5, 84, 11, 168, 12, 141, 14, 160, 28, 0, 90, 41, 72, 106, 78, 67, 41, 24, 0, 120, 135, 150, 120, 120, 120, 120, 165, 90, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 45, 0, 2, 0, 5, 0, 148, 0, 120, 1, 100, 5, 84, 11, 32, 13, 135, 15, 224, 28, 45, 35, 32, 58, 36, 40, 51, 27, 10, 0, 102, 105, 127, 120, 120, 120, 102, 90, 127, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 84, 1, 7, 3, 153, 4, 84, 11, 208, 12, 241, 14, 224, 28, 0, 101, 47, 95, 101, 61, 67, 43, 20, 0, 195, 135, 120, 120, 120, 120, 120, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 45, 0, 2, 0, 5, 0, 208, 0, 249, 1, 160, 5, 84, 11, 52, 13, 135, 15, 192, 28, 45, 35, 33, 58, 48, 44, 49, 28, 11, 0, 150, 120, 120, 120, 120, 120, 90, 120, 120, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 208, 0, 53, 2, 172, 5, 84, 11, 12, 13, 35, 15, 192, 28, 0, 98, 43, 86, 110, 84, 80, 43, 13, 0, 120, 120, 120, 120, 120, 120, 90, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 65, 0, 3, 0, 1, 0, 104, 0, 44, 1, 200, 5, 84, 11, 12, 13, 135, 15, 32, 28, 0, 31, 17, 53, 34, 32, 55, 26, 8, 0, 150, 120, 150, 120, 120, 120, 120, 105, 150, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 136, 0, 184, 1, 84, 6, 84, 11, 92, 13, 210, 15, 32, 28, 65, 34, 21, 63, 48, 43, 41, 21, 7, 0, 150, 105, 150, 120, 120, 120, 120, 45, 150, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 136, 0, 104, 1, 152, 8, 84, 11, 32, 13, 210, 15, 32, 28, 0, 76, 20, 78, 80, 78, 76, 34, 10, 0, 150, 150, 120, 120, 120, 120, 120, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 65, 0, 4, 0, 5, 0, 92, 0, 69, 1, 76, 4, 84, 11, 72, 13, 241, 14, 160, 28, 20, 32, 20, 64, 39, 19, 26, 31, 13, 0, 150, 105, 105, 120, 120, 120, 90, 90, 75, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 92, 0, 69, 1, 232, 3, 84, 11, 168, 12, 141, 14, 32, 27, 9, 40, 22, 69, 49, 42, 33, 29, 14, 0, 150, 105, 105, 120, 120, 120, 90, 90, 75, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 156, 0, 189, 1, 200, 3, 84, 11, 148, 12, 191, 14, 32, 27, 36, 51, 31, 74, 65, 42, 39, 24, 19, 0, 150, 120, 105, 120, 120, 120, 90, 90, 75, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 124, 0, 209, 1, 112, 3, 84, 11, 68, 12, 191, 14, 160, 26, 0, 145, 39, 116, 103, 71, 71, 45, 26, 0, 120, 120, 120, 120, 120, 120, 75, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 51, 0, 3, 0, 5, 0, 92, 0, 19, 1, 120, 5, 84, 11, 52, 13, 216, 14, 128, 27, 12, 33, 10, 60, 36, 40, 59, 33, 11, 0, 150, 105, 135, 120, 120, 120, 75, 75, 105, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 172, 0, 144, 1, 80, 5, 84, 11, 32, 13, 191, 14, 224, 26, 39, 45, 35, 70, 52, 50, 58, 33, 15, 0, 150, 105, 150, 120, 120, 120, 75, 60, 105, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 172, 0, 144, 1, 70, 6, 84, 11, 228, 12, 141, 14, 224, 26, 0, 116, 48, 135, 71, 71, 67, 43, 17, 0, 120, 90, 150, 120, 120, 120, 45, 60, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 4, 0, 1, 0, 188, 0, 8, 2, 40, 5, 140, 10, 128, 12, 91, 14, 0, 27, 34, 69, 36, 83, 77, 49, 57, 38, 23, 0, 150, 120, 120, 120, 120, 120, 135, 90, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 204, 0, 8, 2, 176, 4, 84, 11, 208, 12, 191, 14, 0, 27, 44, 52, 38, 68, 65, 49, 50, 31, 23, 0, 150, 120, 120, 120, 120, 120, 135, 90, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 140, 0, 244, 1, 176, 4, 84, 11, 152, 13, 104, 16, 128, 27, 42, 23, 21, 57, 27, 25, 19, 16, 11, 0, 150, 120, 120, 120, 120, 120, 135, 60, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 140, 0, 224, 1, 20, 5, 84, 11, 152, 13, 104, 16, 0, 27, 0, 20, 19, 49, 26, 17, 13, 15, 8, 0, 150, 150, 120, 120, 120, 120, 135, 60, 120, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 25, 0, 4, 0, 1, 0, 184, 0, 93, 2, 200, 3, 40, 10, 68, 12, 141, 14, 160, 28, 30, 70, 39, 71, 86, 54, 58, 35, 17, 0, 150, 105, 120, 120, 120, 120, 150, 90, 135, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 168, 0, 249, 1, 176, 4, 84, 11, 168, 12, 85, 15, 64, 29, 25, 37, 27, 62, 51, 35, 37, 27, 13, 0, 150, 105, 120, 120, 120, 120, 150, 120, 135, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 168, 0, 189, 1, 176, 4, 84, 11, 228, 12, 60, 15, 64, 29, 60, 32, 27, 57, 34, 25, 30, 20, 10, 0, 150, 105, 120, 120, 120, 120, 150, 120, 135, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 72, 0, 149, 1, 20, 5, 84, 11, 52, 13, 235, 15, 64, 29, 0, 18, 24, 48, 20, 10, 10, 13, 9, 0, 150, 105, 120, 120, 120, 120, 105, 120, 135, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 3, 0, 1, 0, 216, 0, 68, 2, 186, 4, 100, 10, 32, 13, 191, 14, 64, 29, 33, 39, 26, 55, 68, 37, 42, 32, 19, 0, 150, 144, 120, 120, 120, 120, 150, 93, 105, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 192, 0, 249, 1, 176, 4, 84, 11, 228, 12, 91, 14, 128, 28, 75, 26, 27, 44, 44, 33, 26, 19, 7, 0, 150, 150, 120, 120, 120, 120, 150, 90, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 64, 0, 189, 1, 20, 5, 84, 11, 52, 13, 235, 15, 128, 27, 0, 19, 16, 48, 32, 17, 11, 10, 7, 0, 150, 135, 120, 120, 120, 120, 120, 60, 120, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 4, 0, 1, 0, 192, 0, 239, 1, 70, 6, 196, 9, 12, 13, 241, 14, 224, 27, 40, 66, 32, 77, 77, 68, 57, 41, 20, 0, 150, 120, 120, 120, 120, 120, 120, 120, 150, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 33, 0, 192, 0, 239, 1, 20, 5, 84, 11, 92, 13, 241, 14, 224, 27, 45, 29, 24, 58, 37, 35, 28, 22, 8, 0, 150, 120, 120, 120, 120, 120, 120, 90, 150, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 176, 0, 219, 1, 216, 4, 104, 11, 92, 13, 85, 15, 224, 27, 45, 25, 27, 53, 28, 16, 19, 10, 5, 0, 150, 120, 120, 120, 120, 120, 120, 90, 150, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 128, 0, 219, 1, 40, 5, 104, 11, 72, 13, 85, 15, 224, 27, 0, 20, 22, 49, 36, 11, 14, 13, 7, 0, 150, 120, 120, 120, 120, 120, 120, 90, 105, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 16, 0, 5, 0, 1, 0, 228, 0, 38, 2, 134, 3, 140, 10, 88, 12, 166, 14, 128, 28, 33, 52, 32, 61, 59, 47, 39, 22, 17, 0, 150, 120, 120, 120, 120, 120, 150, 120, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 228, 0, 239, 1, 116, 4, 84, 11, 168, 12, 10, 15, 96, 28, 16, 59, 36, 73, 48, 43, 42, 25, 16, 0, 150, 120, 120, 120, 120, 120, 150, 120, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 180, 0, 239, 1, 176, 4, 84, 11, 208, 12, 166, 14, 96, 28, 28, 32, 27, 61, 38, 29, 27, 20, 11, 0, 150, 120, 120, 120, 120, 120, 105, 120, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 180, 0, 239, 1, 176, 4, 84, 11, 208, 12, 166, 14, 96, 28, 45, 21, 17, 59, 33, 24, 22, 13, 6, 0, 150, 120, 75, 120, 120, 120, 105, 30, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 180, 0, 179, 1, 20, 5, 84, 11, 32, 13, 166, 14, 96, 28, 0, 19, 23, 46, 28, 23, 16, 13, 8, 0, 120, 150, 105, 120, 120, 120, 75, 60, 120, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 35, 0, 4, 0, 1, 0, 200, 0, 159, 1, 68, 3, 160, 10, 28, 12, 141, 14, 32, 26, 44, 53, 36, 69, 41, 26, 30, 24, 11, 0, 150, 120, 120, 120, 120, 120, 105, 120, 105, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 200, 0, 99, 1, 176, 4, 84, 11, 108, 12, 60, 15, 32, 26, 55, 49, 32, 69, 34, 31, 35, 24, 11, 0, 150, 105, 120, 120, 120, 120, 75, 120, 105, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 172, 0, 139, 1, 176, 4, 84, 11, 112, 13, 60, 15, 32, 26, 35, 28, 34, 51, 41, 20, 24, 22, 7, 0, 150, 105, 120, 120, 120, 120, 75, 120, 105, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 172, 0, 139, 1, 20, 5, 84, 11, 112, 13, 60, 15, 32, 26, 0, 23, 31, 47, 38, 19, 22, 20, 7, 0, 150, 105, 120, 120, 120, 120, 75, 120, 105, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 50, 0, 2, 0, 5, 0, 76, 0, 104, 1, 84, 6, 84, 11, 132, 13, 135, 15, 32, 29, 50, 17, 9, 45, 22, 18, 33, 19, 8, 0, 155, 135, 97, 120, 120, 120, 95, 105, 97, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 76, 0, 104, 1, 84, 6, 84, 11, 132, 13, 135, 15, 32, 29, 0, 12, 7, 38, 23, 15, 28, 16, 7, 0, 150, 135, 97, 120, 120, 120, 90, 105, 97, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 50, 0, 2, 0, 5, 0, 108, 0, 124, 1, 230, 4, 120, 10, 132, 13, 135, 15, 32, 29, 50, 25, 12, 55, 30, 20, 36, 21, 9, 0, 150, 135, 120, 120, 120, 120, 90, 105, 75, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 172, 0, 94, 1, 175, 4, 180, 10, 212, 13, 185, 15, 160, 28, 0, 18, 27, 41, 23, 19, 23, 19, 12, 0, 165, 105, 135, 120, 120, 120, 60, 120, 105, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 70, 0, 3, 0, 5, 0, 204, 0, 94, 1, 120, 5, 84, 11, 212, 13, 185, 15, 160, 28, 30, 13, 22, 33, 18, 15, 18, 15, 10, 0, 165, 105, 135, 120, 120, 120, 60, 120, 105, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 76, 0, 104, 1, 120, 5, 84, 11, 132, 13, 135, 15, 32, 29, 40, 20, 10, 49, 28, 20, 36, 21, 9, 0, 155, 135, 120, 120, 120, 120, 95, 105, 75, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 76, 0, 104, 1, 120, 5, 84, 11, 132, 13, 135, 15, 32, 29, 0, 20, 10, 49, 30, 20, 36, 21, 9, 0, 150, 135, 120, 120, 120, 120, 90, 105, 75, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 40, 0, 2, 0, 5, 0, 76, 0, 104, 1, 230, 4, 120, 10, 132, 13, 135, 15, 32, 29, 40, 8, 6, 32, 19, 13, 23, 14, 5, 0, 150, 135, 120, 120, 120, 120, 90, 105, 75, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 76, 0, 104, 1, 230, 4, 120, 10, 132, 13, 135, 15, 32, 29, 0, 21, 10, 49, 30, 20, 36, 21, 9, 0, 150, 135, 120, 120, 120, 120, 90, 105, 75, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 85, 0, 2, 0, 5, 0, 76, 0, 104, 1, 156, 4, 120, 10, 132, 13, 135, 15, 32, 29, 85, 14, 9, 40, 27, 13, 20, 10, 8, 0, 150, 135, 120, 120, 120, 120, 90, 105, 75, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 76, 0, 104, 1, 196, 4, 120, 10, 132, 13, 135, 15, 32, 29, 0, 23, 10, 51, 32, 21, 38, 23, 10, 0, 150, 135, 120, 120, 120, 120, 90, 105, 75, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 48, 0, 2, 0, 5, 0, 76, 0, 104, 1, 100, 5, 120, 10, 132, 13, 135, 15, 32, 29, 48, 13, 8, 40, 25, 13, 20, 10, 8, 0, 150, 135, 97, 120, 120, 120, 90, 105, 97, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 76, 0, 104, 1, 100, 5, 120, 10, 132, 13, 135, 15, 32, 29, 0, 22, 10, 51, 30, 21, 38, 23, 10, 0, 150, 135, 97, 120, 120, 120, 90, 105, 97, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 3, 0, 1, 0, 216, 0, 68, 2, 186, 4, 100, 10, 32, 13, 191, 14, 64, 29, 33, 39, 26, 55, 68, 37, 42, 32, 19, 0, 150, 144, 120, 120, 120, 120, 150, 93, 105, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 192, 0, 249, 1, 189, 3, 120, 10, 228, 12, 91, 14, 128, 28, 100, 27, 27, 44, 44, 33, 26, 19, 7, 0, 150, 150, 120, 120, 120, 120, 150, 90, 120, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 64, 0, 189, 1, 112, 3, 200, 10, 52, 13, 235, 15, 128, 27, 0, 19, 16, 48, 32, 17, 11, 10, 7, 0, 150, 135, 120, 120, 120, 120, 120, 60, 120, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 35, 0, 4, 0, 1, 0, 200, 0, 159, 1, 68, 3, 160, 10, 28, 12, 141, 14, 32, 26, 44, 43, 32, 62, 36, 23, 27, 21, 9, 0, 150, 120, 120, 120, 120, 120, 105, 120, 105, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 200, 0, 88, 1, 188, 2, 64, 11, 108, 12, 60, 15, 32, 26, 60, 39, 27, 58, 27, 26, 29, 20, 9, 0, 150, 105, 120, 120, 120, 120, 75, 120, 105, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 172, 0, 139, 1, 200, 3, 64, 11, 112, 13, 60, 15, 32, 26, 35, 28, 34, 51, 41, 20, 24, 22, 7, 0, 150, 105, 120, 120, 120, 120, 75, 120, 105, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 172, 0, 139, 1, 200, 3, 64, 11, 112, 13, 60, 15, 32, 26, 0, 23, 31, 47, 38, 19, 22, 20, 7, 0, 150, 105, 120, 120, 120, 120, 75, 120, 105, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 4, 0, 1, 0, 188, 0, 8, 2, 40, 5, 140, 10, 128, 12, 91, 14, 0, 27, 34, 69, 36, 83, 77, 49, 57, 38, 23, 0, 150, 120, 120, 120, 120, 120, 135, 90, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 204, 0, 8, 2, 164, 4, 140, 10, 208, 12, 191, 14, 0, 27, 49, 52, 38, 68, 65, 49, 50, 31, 23, 0, 150, 120, 120, 120, 120, 120, 135, 90, 120, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 140, 0, 244, 1, 90, 3, 84, 11, 152, 13, 104, 16, 128, 27, 50, 25, 21, 57, 27, 25, 19, 16, 11, 0, 150, 120, 120, 120, 120, 120, 135, 60, 120, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 140, 0, 224, 1, 46, 3, 84, 11, 152, 13, 104, 16, 0, 27, 0, 22, 19, 49, 26, 17, 13, 15, 8, 0, 150, 150, 120, 120, 120, 120, 135, 60, 120, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 25, 0, 4, 0, 1, 0, 184, 0, 93, 2, 200, 3, 40, 10, 68, 12, 141, 14, 160, 28, 40, 70, 39, 71, 86, 54, 58, 35, 17, 0, 150, 105, 120, 120, 120, 120, 150, 90, 135, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 168, 0, 249, 1, 156, 3, 160, 10, 168, 12, 85, 15, 64, 29, 25, 40, 27, 62, 51, 35, 37, 27, 13, 0, 150, 105, 120, 120, 120, 120, 150, 120, 135, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 168, 0, 189, 1, 24, 3, 160, 10, 228, 12, 60, 15, 64, 29, 75, 36, 27, 57, 34, 25, 30, 20, 10, 0, 150, 105, 120, 120, 120, 120, 150, 120, 135, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 72, 0, 149, 1, 68, 3, 160, 10, 52, 13, 235, 15, 64, 29, 0, 19, 24, 48, 20, 10, 10, 13, 9, 0, 150, 105, 120, 120, 120, 120, 105, 120, 135, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 4, 0, 1, 0, 192, 0, 239, 1, 70, 6, 196, 9, 12, 13, 241, 14, 224, 27, 40, 66, 32, 77, 77, 68, 57, 41, 20, 0, 150, 120, 120, 120, 120, 120, 120, 120, 150, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 37, 0, 192, 0, 239, 1, 21, 4, 4, 11, 92, 13, 241, 14, 224, 27, 50, 29, 24, 58, 37, 35, 28, 22, 8, 0, 150, 120, 120, 120, 120, 120, 120, 90, 150, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 176, 0, 219, 1, 101, 3, 4, 11, 92, 13, 85, 15, 224, 27, 50, 26, 27, 53, 27, 16, 19, 10, 5, 0, 150, 120, 120, 120, 120, 120, 120, 90, 150, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 128, 0, 219, 1, 57, 3, 24, 11, 72, 13, 85, 15, 224, 27, 0, 22, 22, 49, 32, 11, 14, 13, 7, 0, 150, 120, 120, 120, 120, 120, 120, 90, 105, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 20, 0, 5, 0, 1, 0, 228, 0, 38, 2, 134, 3, 140, 10, 88, 12, 166, 14, 128, 28, 33, 56, 36, 60, 66, 44, 44, 25, 19, 0, 150, 120, 120, 120, 120, 120, 150, 120, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 228, 0, 239, 1, 145, 3, 220, 10, 168, 12, 10, 15, 96, 28, 20, 51, 36, 64, 48, 43, 42, 25, 16, 0, 150, 120, 120, 120, 120, 120, 150, 120, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 180, 0, 239, 1, 35, 3, 44, 11, 208, 12, 166, 14, 96, 28, 28, 39, 27, 61, 38, 29, 27, 20, 11, 0, 150, 120, 120, 120, 120, 120, 105, 120, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 180, 0, 239, 1, 115, 2, 44, 11, 208, 12, 166, 14, 96, 28, 51, 25, 17, 59, 33, 24, 22, 13, 6, 0, 150, 120, 75, 120, 120, 120, 105, 30, 120, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 72, 0, 149, 1, 68, 3, 160, 10, 52, 13, 235, 15, 64, 29, 0, 19, 24, 48, 20, 10, 10, 13, 9, 0, 150, 105, 120, 120, 120, 120, 105, 120, 135, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 2, 0, 5, 0, 85, 0, 221, 1, 77, 5, 116, 10, 4, 13, 85, 15, 115, 27, 75, 28, 21, 51, 46, 25, 22, 17, 9, 3, 157, 141, 126, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 64, 0, 189, 1, 20, 5, 84, 11, 52, 13, 235, 15, 128, 27, 0, 18, 16, 48, 32, 17, 11, 10, 7, 0, 150, 135, 120, 120, 120, 120, 120, 60, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 2, 0, 5, 0, 168, 0, 139, 2, 30, 5, 240, 10, 82, 13, 135, 15, 208, 27, 75, 24, 21, 49, 38, 22, 14, 13, 6, 4, 168, 130, 128, 120, 120, 120, 217, 150, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 64, 0, 189, 1, 20, 5, 84, 11, 52, 13, 235, 15, 128, 27, 0, 18, 16, 48, 32, 17, 11, 10, 7, 0, 150, 135, 120, 120, 120, 120, 120, 60, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 2, 0, 5, 0, 192, 0, 249, 1, 176, 4, 84, 11, 228, 12, 91, 14, 128, 28, 75, 26, 27, 44, 44, 33, 26, 20, 7, 0, 150, 150, 120, 120, 120, 120, 150, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 64, 0, 189, 1, 20, 5, 84, 11, 52, 13, 235, 15, 128, 27, 0, 19, 16, 48, 32, 17, 11, 10, 7, 0, 150, 135, 120, 120, 120, 120, 120, 60, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 3, 0, 37, 0, 149, 0, 24, 1, 207, 8, 214, 11, 112, 13, 134, 16, 42, 27, 45, 43, 8, 62, 52, 48, 52, 24, 16, 8, 182, 120, 133, 133, 142, 161, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 204, 0, 94, 1, 120, 5, 84, 11, 212, 13, 185, 15, 160, 28, 45, 23, 30, 44, 24, 21, 24, 20, 14, 0, 165, 105, 135, 120, 120, 120, 60, 120, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 204, 0, 94, 1, 120, 5, 84, 11, 212, 13, 185, 15, 160, 28, 0, 23, 30, 44, 24, 21, 24, 20, 14, 0, 165, 105, 135, 120, 120, 120, 60, 120, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 3, 0, 37, 0, 168, 0, 32, 2, 132, 3, 216, 9, 164, 11, 141, 14, 32, 27, 90, 54, 32, 56, 64, 39, 36, 18, 14, 6, 187, 125, 137, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 76, 0, 104, 1, 100, 5, 120, 10, 132, 13, 135, 15, 32, 29, 45, 19, 10, 48, 30, 16, 24, 12, 10, 0, 150, 135, 97, 120, 120, 120, 90, 105, 97, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 76, 0, 104, 1, 100, 5, 120, 10, 132, 13, 135, 15, 32, 29, 0, 19, 10, 48, 30, 16, 24, 12, 10, 0, 150, 135, 97, 120, 120, 120, 90, 105, 97, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 2, 0, 5, 0, 120, 0, 118, 1, 6, 4, 70, 10, 32, 13, 147, 15, 8, 27, 75, 25, 11, 50, 35, 19, 16, 21, 9, 5, 168, 130, 128, 120, 120, 120, 177, 125, 102, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 64, 0, 189, 1, 20, 5, 84, 11, 52, 13, 235, 15, 128, 27, 0, 18, 16, 48, 32, 17, 11, 10, 7, 0, 150, 135, 120, 120, 120, 120, 120, 60, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 3, 0, 5, 0, 148, 0, 24, 1, 209, 8, 68, 12, 112, 13, 140, 15, 112, 23, 20, 21, 12, 40, 14, 12, 16, 9, 3, 6, 110, 180, 177, 225, 247, 175, 110, 180, 177, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 232, 0, 128, 1, 132, 8, 240, 10, 112, 13, 80, 15, 137, 23, 40, 63, 15, 78, 24, 18, 27, 12, 6, 6, 110, 155, 177, 225, 247, 175, 110, 155, 177, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 208, 0, 8, 2, 228, 7, 60, 10, 72, 13, 40, 15, 137, 23, 0, 88, 21, 93, 36, 45, 48, 24, 6, 6, 110, 180, 202, 225, 252, 175, 110, 180, 202, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 3, 0, 5, 0, 192, 0, 160, 1, 48, 7, 40, 10, 32, 13, 20, 15, 137, 23, 25, 12, 8, 30, 19, 20, 22, 17, 2, 2, 150, 185, 192, 222, 242, 195, 150, 185, 192, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 240, 0, 40, 2, 44, 6, 236, 9, 188, 12, 156, 14, 137, 23, 42, 36, 39, 48, 30, 33, 29, 21, 6, 6, 150, 155, 192, 247, 242, 195, 150, 155, 192, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 212, 0, 168, 2, 216, 4, 236, 9, 48, 12, 116, 14, 143, 22, 0, 65, 48, 66, 54, 33, 36, 24, 6, 3, 202, 155, 192, 180, 242, 225, 202, 155, 192, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 3, 0, 5, 0, 176, 0, 80, 1, 56, 9, 84, 11, 112, 13, 100, 15, 88, 27, 20, 19, 15, 32, 12, 20, 18, 11, 2, 5, 177, 192, 197, 235, 220, 175, 177, 192, 197, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 237, 0, 219, 1, 0, 8, 136, 10, 108, 13, 54, 15, 47, 28, 40, 35, 24, 47, 36, 36, 28, 19, 7, 6, 214, 159, 176, 171, 165, 144, 177, 192, 197, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 31, 1, 77, 2, 255, 6, 225, 9, 104, 13, 15, 15, 224, 28, 0, 44, 31, 56, 60, 55, 42, 31, 10, 6, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 3, 0, 5, 0, 116, 0, 0, 1, 16, 9, 144, 11, 212, 13, 180, 15, 243, 22, 25, 10, 3, 30, 27, 15, 15, 9, 0, 3, 150, 142, 140, 165, 210, 175, 150, 142, 140, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 125, 0, 25, 1, 152, 8, 44, 11, 16, 14, 160, 15, 243, 22, 40, 20, 4, 46, 28, 20, 23, 12, 0, 4, 150, 142, 138, 143, 162, 175, 150, 142, 140, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 128, 0, 40, 1, 132, 8, 124, 11, 32, 13, 40, 15, 44, 26, 0, 152, 12, 116, 28, 44, 69, 28, 12, 8, 150, 190, 200, 235, 185, 157, 150, 190, 200, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 4, 0, 37, 0, 0, 1, 112, 1, 153, 8, 154, 11, 228, 12, 216, 14, 88, 27, 20, 25, 9, 45, 14, 12, 16, 12, 2, 4, 120, 187, 137, 187, 150, 237, 120, 187, 137, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 37, 0, 232, 0, 248, 1, 240, 5, 176, 9, 128, 12, 216, 14, 88, 27, 20, 35, 31, 55, 26, 16, 16, 12, 2, 4, 127, 140, 182, 187, 222, 237, 127, 140, 182, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 37, 0, 216, 0, 8, 2, 136, 4, 176, 9, 8, 12, 216, 14, 88, 27, 35, 54, 30, 69, 39, 21, 21, 15, 3, 6, 182, 140, 182, 187, 222, 237, 182, 140, 182, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 232, 0, 64, 2, 252, 3, 120, 10, 68, 12, 216, 14, 88, 27, 0, 88, 27, 87, 55, 27, 33, 21, 6, 6, 182, 155, 145, 187, 222, 237, 182, 155, 145, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 15, 0, 4, 0, 5, 0, 140, 0, 0, 1, 96, 9, 64, 11, 208, 12, 100, 15, 88, 27, 20, 30, 10, 54, 25, 10, 18, 7, 3, 7, 77, 147, 150, 150, 150, 150, 77, 147, 150, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 140, 0, 248, 0, 96, 9, 64, 11, 208, 12, 100, 15, 88, 27, 15, 19, 8, 42, 11, 11, 14, 5, 2, 5, 77, 147, 150, 150, 150, 150, 77, 147, 150, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 140, 0, 0, 1, 96, 9, 64, 11, 208, 12, 100, 15, 88, 27, 30, 26, 10, 50, 25, 14, 18, 7, 3, 7, 77, 147, 150, 150, 150, 150, 77, 147, 150, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 164, 0, 32, 1, 52, 8, 236, 9, 168, 12, 172, 14, 175, 25, 0, 117, 0, 112, 24, 24, 44, 36, 8, 12, 150, 180, 137, 137, 150, 175, 150, 180, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 110, 0, 4, 0, 5, 0, 132, 0, 232, 0, 232, 8, 220, 10, 192, 13, 180, 15, 200, 25, 35, 6, 6, 24, 6, 21, 24, 6, 6, 0, 120, 105, 120, 120, 120, 120, 45, 135, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 132, 0, 240, 0, 185, 8, 224, 11, 72, 13, 80, 15, 150, 25, 50, 17, 3, 45, 7, 26, 30, 3, 7, 0, 120, 105, 150, 120, 120, 120, 45, 135, 90, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 132, 0, 232, 0, 185, 8, 224, 11, 72, 13, 80, 15, 150, 25, 25, 23, 3, 53, 3, 26, 30, 3, 0, 0, 120, 105, 150, 120, 120, 120, 45, 135, 90, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 132, 0, 232, 0, 185, 8, 224, 11, 72, 13, 80, 15, 0, 29, 0, 15, 3, 43, 3, 18, 24, 3, 0, 0, 120, 105, 150, 120, 120, 120, 45, 135, 90, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 145, 0, 4, 0, 37, 0, 132, 0, 240, 0, 76, 9, 28, 12, 212, 13, 140, 15, 225, 25, 60, 20, 8, 48, 17, 30, 17, 17, 8, 0, 120, 105, 120, 120, 120, 120, 45, 135, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 132, 0, 240, 0, 76, 9, 28, 12, 212, 13, 140, 15, 225, 25, 60, 20, 8, 48, 17, 30, 17, 17, 8, 0, 120, 105, 120, 120, 120, 120, 45, 135, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 132, 0, 240, 0, 76, 9, 28, 12, 212, 13, 140, 15, 225, 25, 25, 9, 6, 33, 12, 21, 12, 12, 6, 0, 120, 105, 120, 120, 120, 120, 45, 135, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 132, 0, 240, 0, 76, 9, 28, 12, 212, 13, 140, 15, 225, 25, 0, 10, 6, 35, 12, 22, 12, 12, 6, 0, 120, 105, 120, 120, 120, 120, 45, 135, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 95, 0, 3, 0, 5, 0, 104, 0, 64, 1, 64, 6, 108, 7, 192, 13, 180, 15, 32, 29, 55, 17, 6, 44, 34, 13, 17, 13, 8, 0, 150, 135, 97, 120, 120, 120, 90, 105, 97, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 9, 0, 104, 0, 64, 1, 64, 6, 108, 7, 192, 13, 180, 15, 32, 29, 40, 23, 8, 52, 40, 16, 20, 16, 10, 0, 150, 135, 97, 120, 120, 120, 90, 105, 97, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 104, 0, 64, 1, 64, 6, 108, 7, 192, 13, 180, 15, 32, 29, 0, 23, 8, 52, 40, 16, 20, 16, 10, 0, 150, 135, 97, 120, 120, 120, 90, 105, 97, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 100, 0, 3, 0, 5, 0, 176, 0, 184, 1, 32, 3, 64, 11, 32, 13, 120, 15, 144, 26, 50, 38, 18, 54, 39, 30, 27, 24, 12, 7, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 176, 0, 184, 1, 32, 3, 64, 11, 32, 13, 120, 15, 144, 26, 50, 38, 18, 54, 39, 30, 27, 24, 12, 7, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 176, 0, 184, 1, 32, 3, 64, 11, 32, 13, 120, 15, 144, 26, 0, 33, 16, 50, 36, 28, 25, 22, 11, 7, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 90, 0, 4, 0, 5, 0, 176, 0, 184, 1, 32, 3, 64, 11, 32, 13, 120, 15, 144, 26, 30, 24, 14, 43, 31, 24, 21, 19, 9, 6, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 176, 0, 184, 1, 32, 3, 64, 11, 32, 13, 120, 15, 144, 26, 40, 33, 16, 50, 36, 28, 25, 22, 11, 7, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 21, 0, 176, 0, 184, 1, 32, 3, 64, 11, 32, 13, 120, 15, 144, 26, 20, 30, 16, 50, 28, 28, 25, 22, 11, 7, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 176, 0, 184, 1, 32, 3, 64, 11, 32, 13, 120, 15, 144, 26, 0, 33, 16, 50, 36, 28, 25, 22, 11, 7, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 50, 0, 3, 0, 5, 0, 176, 0, 184, 1, 32, 3, 64, 11, 32, 13, 120, 15, 144, 26, 30, 33, 16, 50, 36, 28, 25, 22, 11, 7, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 21, 0, 176, 0, 184, 1, 32, 3, 64, 11, 32, 13, 120, 15, 144, 26, 20, 30, 16, 50, 28, 28, 25, 22, 11, 7, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 176, 0, 184, 1, 32, 3, 64, 11, 32, 13, 120, 15, 144, 26, 0, 29, 15, 46, 33, 26, 23, 20, 10, 6, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 77, 0, 3, 0, 5, 0, 96, 0, 99, 1, 214, 2, 156, 9, 8, 12, 135, 15, 192, 27, 30, 25, 8, 57, 20, 14, 14, 10, 8, 0, 120, 135, 90, 120, 120, 120, 60, 105, 180, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 192, 0, 179, 1, 134, 3, 212, 8, 204, 11, 166, 14, 192, 27, 47, 45, 18, 78, 33, 14, 16, 10, 4, 0, 120, 111, 150, 120, 120, 120, 60, 81, 123, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 208, 0, 43, 2, 18, 5, 132, 8, 28, 12, 166, 14, 192, 27, 0, 76, 39, 84, 98, 46, 59, 40, 11, 0, 120, 150, 120, 120, 120, 120, 60, 120, 75, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 71, 0, 3, 0, 5, 0, 192, 0, 179, 1, 92, 3, 252, 8, 184, 11, 60, 15, 32, 28, 26, 43, 19, 81, 28, 14, 11, 8, 7, 0, 120, 82, 90, 120, 120, 120, 75, 82, 90, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 208, 0, 199, 1, 132, 3, 16, 9, 184, 11, 60, 15, 32, 28, 45, 62, 31, 81, 61, 30, 24, 15, 8, 0, 120, 120, 150, 120, 120, 120, 75, 90, 105, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 16, 1, 223, 2, 255, 3, 20, 10, 184, 11, 35, 15, 224, 27, 0, 122, 45, 69, 106, 78, 82, 48, 10, 0, 120, 195, 120, 120, 120, 120, 195, 120, 120, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 70, 0, 3, 0, 5, 0, 100, 0, 154, 1, 12, 3, 96, 9, 224, 11, 166, 14, 128, 27, 35, 41, 8, 77, 28, 15, 16, 12, 7, 0, 120, 120, 105, 120, 120, 120, 120, 75, 105, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 228, 0, 38, 2, 20, 5, 192, 8, 48, 12, 166, 14, 128, 27, 35, 65, 35, 77, 80, 45, 38, 29, 8, 0, 120, 120, 180, 120, 120, 120, 120, 120, 105, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 228, 0, 78, 2, 249, 5, 252, 8, 128, 12, 66, 14, 128, 27, 0, 91, 44, 83, 109, 55, 49, 34, 10, 0, 120, 120, 180, 120, 120, 120, 120, 120, 90, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 76, 0, 3, 0, 37, 0, 40, 0, 112, 1, 68, 3, 36, 9, 28, 12, 216, 14, 32, 28, 40, 45, 19, 77, 28, 16, 16, 12, 8, 0, 120, 105, 120, 120, 120, 120, 120, 105, 120, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 37, 0, 120, 0, 112, 1, 153, 4, 76, 9, 148, 12, 166, 14, 192, 27, 36, 43, 20, 76, 24, 24, 26, 17, 13, 0, 120, 90, 120, 120, 120, 120, 120, 90, 105, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 40, 0, 79, 1, 221, 7, 96, 9, 208, 12, 116, 14, 192, 27, 0, 89, 9, 86, 74, 89, 97, 58, 13, 0, 120, 120, 120, 120, 120, 120, 120, 120, 120, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 73, 0, 3, 0, 5, 0, 112, 0, 84, 1, 49, 2, 236, 9, 64, 11, 91, 14, 160, 27, 33, 29, 13, 60, 24, 12, 12, 6, 5, 0, 120, 135, 60, 120, 120, 120, 75, 90, 90, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 136, 0, 136, 1, 180, 2, 0, 10, 64, 11, 91, 14, 160, 27, 40, 35, 24, 64, 44, 25, 23, 8, 11, 0, 120, 105, 75, 120, 120, 120, 75, 105, 105, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 144, 0, 184, 1, 181, 2, 20, 10, 64, 11, 91, 14, 32, 28, 0, 93, 35, 114, 65, 46, 46, 17, 21, 0, 120, 75, 60, 120, 120, 120, 75, 90, 90, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 70, 0, 3, 0, 5, 0, 128, 0, 84, 1, 108, 2, 66, 9, 164, 11, 116, 14, 144, 27, 33, 39, 19, 69, 26, 12, 12, 9, 4, 0, 120, 120, 90, 120, 120, 120, 75, 90, 90, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 144, 0, 120, 1, 192, 3, 252, 8, 28, 12, 141, 14, 128, 27, 37, 43, 20, 77, 42, 21, 23, 17, 10, 0, 120, 96, 129, 120, 120, 120, 75, 84, 126, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 144, 0, 164, 1, 128, 5, 152, 8, 88, 12, 141, 14, 128, 27, 0, 119, 37, 140, 62, 45, 54, 39, 20, 0, 120, 90, 120, 120, 120, 120, 75, 60, 165, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 30, 0, 2, 0, 1, 0, 84, 0, 34, 1, 217, 1, 0, 10, 224, 11, 10, 15, 128, 27, 30, 20, 4, 50, 40, 10, 9, 8, 6, 0, 120, 120, 60, 120, 120, 120, 120, 45, 75, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 84, 0, 34, 1, 217, 1, 0, 10, 224, 11, 10, 15, 128, 27, 0, 20, 4, 50, 40, 10, 9, 8, 6, 0, 120, 120, 60, 120, 120, 120, 120, 45, 75, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 55, 0, 3, 0, 5, 0, 64, 0, 19, 1, 204, 1, 56, 9, 28, 12, 220, 15, 192, 27, 25, 10, 2, 33, 19, 11, 7, 3, 2, 0, 120, 135, 90, 120, 120, 120, 60, 60, 120, 44, 45, 70, 130, 50, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 64, 0, 19, 1, 204, 1, 56, 9, 28, 12, 220, 15, 192, 27, 30, 17, 2, 45, 22, 15, 9, 4, 3, 0, 120, 135, 90, 120, 120, 120, 60, 60, 120, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 64, 0, 19, 1, 224, 1, 56, 9, 28, 12, 220, 15, 192, 27, 0, 20, 3, 48, 28, 16, 10, 5, 4, 0, 120, 135, 90, 120, 120, 120, 60, 60, 120, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 125, 0, 4, 0, 37, 0, 214, 0, 176, 1, 161, 3, 232, 8, 88, 12, 178, 14, 96, 27, 45, 21, 22, 44, 26, 13, 19, 12, 9, 5, 202, 90, 150, 120, 120, 120, 145, 120, 135, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 172, 0, 112, 1, 132, 3, 192, 8, 168, 12, 60, 15, 96, 27, 40, 18, 17, 37, 28, 11, 8, 8, 7, 5, 200, 90, 120, 120, 120, 120, 200, 120, 135, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 172, 0, 112, 1, 132, 3, 192, 8, 168, 12, 60, 15, 96, 27, 40, 18, 17, 37, 28, 11, 8, 8, 7, 5, 200, 90, 120, 120, 120, 120, 200, 120, 135, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 172, 0, 96, 1, 92, 3, 192, 8, 168, 12, 60, 15, 96, 27, 0, 13, 15, 30, 23, 10, 7, 7, 6, 5, 200, 90, 120, 120, 120, 120, 200, 120, 135, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 90, 0, 3, 0, 37, 0, 214, 0, 176, 1, 161, 3, 232, 8, 88, 12, 178, 14, 96, 27, 40, 33, 26, 52, 43, 15, 22, 14, 11, 7, 202, 90, 150, 120, 120, 120, 145, 120, 135, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 21, 0, 172, 0, 112, 1, 132, 3, 192, 8, 168, 12, 60, 15, 96, 27, 50, 25, 17, 45, 35, 14, 10, 10, 8, 7, 200, 90, 120, 120, 120, 120, 200, 120, 135, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 172, 0, 96, 1, 92, 3, 192, 8, 168, 12, 60, 15, 96, 27, 0, 17, 15, 36, 27, 12, 9, 9, 7, 6, 200, 90, 120, 120, 120, 120, 200, 120, 135, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 121, 0, 4, 0, 5, 0, 76, 0, 255, 0, 141, 8, 180, 10, 32, 13, 85, 15, 160, 28, 21, 21, 10, 48, 36, 37, 48, 23, 13, 0, 120, 90, 105, 120, 120, 120, 60, 105, 120, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 76, 0, 255, 0, 141, 8, 140, 10, 248, 12, 185, 15, 160, 28, 40, 25, 13, 52, 38, 42, 54, 31, 11, 0, 120, 90, 105, 120, 120, 120, 60, 75, 120, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 220, 0, 144, 1, 89, 7, 76, 9, 188, 12, 141, 14, 160, 28, 60, 50, 36, 78, 45, 57, 48, 32, 8, 0, 120, 75, 120, 120, 120, 120, 60, 120, 135, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 220, 0, 8, 2, 249, 5, 172, 8, 48, 12, 41, 14, 160, 28, 0, 76, 43, 73, 97, 69, 65, 41, 13, 0, 120, 120, 120, 120, 120, 120, 75, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 103, 0, 4, 0, 5, 0, 180, 0, 29, 1, 185, 8, 200, 10, 32, 13, 116, 14, 0, 29, 31, 20, 3, 46, 21, 33, 43, 24, 6, 0, 120, 105, 150, 120, 120, 120, 45, 135, 90, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 180, 0, 149, 1, 177, 7, 216, 9, 128, 12, 116, 14, 0, 28, 31, 28, 26, 55, 37, 47, 46, 28, 6, 0, 120, 120, 120, 120, 120, 120, 45, 105, 120, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 196, 0, 229, 1, 136, 6, 36, 9, 28, 12, 116, 14, 0, 28, 41, 40, 33, 55, 70, 54, 51, 31, 7, 0, 120, 120, 150, 120, 120, 120, 75, 105, 120, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 228, 0, 37, 3, 252, 4, 232, 8, 184, 11, 16, 14, 224, 27, 0, 82, 42, 73, 109, 66, 59, 44, 10, 0, 120, 150, 120, 120, 120, 120, 120, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 135, 0, 4, 0, 5, 0, 116, 0, 225, 0, 229, 8, 64, 11, 32, 13, 160, 15, 192, 28, 45, 20, 3, 43, 33, 38, 46, 30, 7, 0, 120, 105, 135, 120, 120, 120, 45, 150, 105, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 132, 0, 9, 1, 207, 8, 160, 10, 208, 12, 4, 16, 192, 28, 40, 24, 5, 45, 42, 48, 51, 23, 5, 0, 120, 105, 135, 120, 120, 120, 45, 150, 120, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 164, 0, 179, 1, 166, 7, 176, 9, 248, 12, 160, 15, 192, 28, 50, 49, 33, 77, 47, 57, 47, 23, 4, 0, 120, 117, 159, 120, 120, 120, 63, 90, 120, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 212, 0, 53, 2, 224, 6, 96, 9, 168, 12, 66, 14, 192, 28, 0, 84, 46, 69, 100, 83, 74, 46, 8, 0, 120, 135, 195, 120, 120, 120, 90, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 95, 0, 3, 0, 5, 0, 84, 0, 255, 0, 39, 9, 164, 11, 92, 13, 135, 15, 224, 28, 30, 18, 6, 43, 28, 36, 41, 26, 9, 0, 120, 90, 120, 120, 120, 120, 75, 120, 120, 44, 45, 70, 130, 51, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 84, 0, 250, 0, 39, 9, 164, 11, 92, 13, 135, 15, 64, 28, 65, 20, 5, 44, 34, 41, 46, 23, 9, 0, 120, 90, 120, 120, 120, 120, 75, 105, 120, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 84, 0, 59, 1, 174, 8, 160, 10, 208, 12, 235, 15, 64, 28, 0, 65, 15, 83, 68, 74, 78, 41, 12, 0, 120, 90, 120, 120, 120, 120, 75, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 125, 0, 5, 0, 5, 0, 136, 0, 240, 0, 172, 8, 224, 11, 52, 13, 191, 14, 32, 28, 30, 22, 9, 46, 23, 27, 40, 28, 13, 0, 120, 120, 135, 120, 120, 120, 60, 90, 90, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 136, 0, 4, 1, 112, 8, 80, 10, 52, 13, 166, 14, 32, 28, 25, 31, 9, 57, 31, 27, 42, 39, 12, 0, 120, 120, 135, 120, 120, 120, 60, 90, 90, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 136, 0, 44, 1, 133, 7, 96, 9, 148, 12, 41, 14, 32, 28, 30, 45, 16, 72, 57, 48, 37, 29, 15, 0, 120, 120, 105, 120, 120, 120, 60, 90, 90, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 136, 0, 164, 1, 150, 5, 96, 9, 48, 12, 41, 14, 32, 28, 40, 49, 26, 80, 58, 44, 38, 28, 18, 0, 120, 120, 90, 120, 120, 120, 60, 75, 135, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 152, 0, 184, 1, 178, 3, 116, 9, 184, 11, 41, 14, 96, 27, 0, 127, 48, 110, 106, 80, 62, 41, 26, 0, 120, 120, 120, 120, 120, 120, 75, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 60, 0, 3, 0, 5, 0, 88, 0, 24, 1, 6, 9, 140, 10, 32, 13, 191, 14, 224, 28, 30, 18, 9, 41, 37, 34, 45, 21, 6, 0, 135, 120, 135, 120, 120, 120, 30, 105, 75, 44, 45, 70, 130, 51, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 88, 0, 84, 1, 188, 7, 36, 9, 168, 12, 191, 14, 224, 28, 60, 20, 5, 45, 20, 48, 40, 25, 5, 0, 135, 135, 135, 120, 120, 120, 30, 90, 75, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 168, 0, 144, 1, 56, 7, 212, 8, 168, 12, 191, 14, 224, 28, 0, 85, 34, 108, 57, 76, 60, 37, 9, 0, 120, 105, 120, 120, 120, 120, 30, 75, 120, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 30, 0, 2, 0, 1, 0, 180, 0, 29, 1, 185, 8, 200, 10, 32, 13, 116, 14, 0, 29, 30, 19, 3, 45, 21, 33, 42, 24, 6, 0, 120, 105, 150, 120, 120, 120, 45, 135, 90, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 180, 0, 29, 1, 185, 8, 200, 10, 32, 13, 116, 14, 0, 29, 0, 19, 3, 45, 21, 33, 42, 24, 6, 0, 120, 105, 150, 120, 120, 120, 45, 135, 90, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 25, 0, 2, 0, 5, 0, 180, 0, 29, 1, 185, 8, 200, 10, 32, 13, 116, 14, 0, 29, 25, 14, 3, 39, 18, 28, 36, 20, 6, 0, 120, 105, 150, 120, 120, 120, 45, 135, 90, 44, 45, 70, 130, 51, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 180, 0, 29, 1, 185, 8, 200, 10, 32, 13, 116, 14, 0, 29, 0, 25, 4, 52, 24, 38, 48, 27, 8, 0, 120, 105, 150, 120, 120, 120, 45, 135, 90, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 70, 0, 3, 0, 5, 0, 156, 0, 99, 1, 174, 8, 160, 10, 92, 13, 10, 15, 32, 28, 35, 21, 25, 39, 40, 37, 30, 20, 7, 6, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 156, 0, 72, 1, 174, 8, 160, 10, 92, 13, 10, 15, 32, 28, 35, 17, 22, 34, 35, 32, 26, 17, 6, 5, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 156, 0, 72, 1, 192, 8, 160, 10, 92, 13, 10, 15, 32, 28, 0, 17, 21, 37, 23, 20, 20, 14, 6, 5, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 3, 0, 5, 0, 148, 0, 24, 1, 209, 8, 184, 11, 112, 13, 140, 15, 112, 23, 20, 21, 12, 40, 14, 12, 16, 9, 3, 6, 110, 180, 177, 225, 247, 175, 110, 180, 177, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 232, 0, 128, 1, 132, 8, 240, 10, 112, 13, 80, 15, 137, 23, 40, 63, 15, 78, 24, 18, 27, 12, 6, 6, 110, 155, 177, 225, 247, 175, 110, 155, 177, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 208, 0, 8, 2, 228, 7, 60, 10, 72, 13, 40, 15, 137, 23, 0, 88, 21, 93, 36, 45, 48, 24, 6, 6, 110, 180, 202, 225, 252, 175, 110, 180, 202, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 3, 0, 5, 0, 192, 0, 160, 1, 48, 7, 40, 10, 32, 13, 20, 15, 137, 23, 25, 12, 8, 30, 19, 20, 22, 17, 2, 2, 150, 185, 192, 222, 242, 195, 150, 185, 192, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 240, 0, 40, 2, 44, 6, 236, 9, 188, 12, 156, 14, 137, 23, 42, 36, 39, 48, 30, 33, 29, 21, 6, 6, 150, 155, 192, 247, 242, 195, 150, 155, 192, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 212, 0, 168, 2, 216, 4, 236, 9, 48, 12, 116, 14, 143, 22, 0, 65, 48, 66, 54, 33, 36, 24, 6, 3, 202, 155, 192, 180, 242, 225, 202, 155, 192, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 3, 0, 5, 0, 176, 0, 80, 1, 212, 8, 84, 11, 112, 13, 100, 15, 88, 27, 20, 19, 15, 32, 12, 20, 18, 11, 2, 5, 177, 192, 197, 235, 220, 175, 177, 192, 197, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 237, 0, 219, 1, 0, 8, 136, 10, 108, 13, 54, 15, 47, 28, 40, 35, 24, 47, 36, 36, 28, 19, 7, 6, 214, 159, 176, 171, 165, 144, 177, 192, 197, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 31, 1, 77, 2, 255, 6, 225, 9, 104, 13, 15, 15, 224, 28, 0, 44, 31, 56, 60, 55, 42, 31, 10, 6, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 3, 0, 5, 0, 116, 0, 24, 1, 152, 8, 44, 11, 112, 13, 120, 15, 243, 22, 20, 8, 3, 30, 15, 15, 15, 9, 0, 3, 150, 142, 140, 165, 210, 175, 150, 142, 140, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 128, 0, 32, 1, 52, 8, 4, 11, 28, 14, 160, 15, 243, 22, 40, 21, 4, 48, 16, 20, 24, 12, 0, 4, 150, 142, 137, 137, 150, 175, 150, 142, 137, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 128, 0, 40, 1, 132, 8, 124, 11, 32, 13, 40, 15, 44, 26, 0, 152, 12, 116, 28, 44, 69, 28, 12, 8, 150, 190, 200, 235, 185, 157, 150, 190, 200, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 4, 0, 37, 0, 0, 1, 112, 1, 153, 8, 154, 11, 228, 12, 216, 14, 88, 27, 20, 25, 9, 45, 14, 12, 16, 12, 2, 4, 120, 187, 137, 187, 150, 237, 120, 187, 137, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 37, 0, 232, 0, 248, 1, 240, 5, 176, 9, 128, 12, 216, 14, 88, 27, 20, 35, 31, 55, 26, 16, 16, 12, 2, 4, 127, 140, 182, 187, 222, 237, 127, 140, 182, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 37, 0, 216, 0, 8, 2, 136, 4, 176, 9, 8, 12, 216, 14, 88, 27, 35, 54, 30, 69, 39, 21, 21, 15, 3, 6, 182, 140, 182, 187, 222, 237, 182, 140, 182, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 232, 0, 64, 2, 252, 3, 120, 10, 68, 12, 216, 14, 88, 27, 0, 88, 27, 87, 55, 27, 33, 21, 6, 6, 182, 155, 145, 187, 222, 237, 182, 155, 145, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 3, 0, 5, 0, 156, 0, 8, 1, 132, 8, 120, 10, 12, 13, 100, 15, 62, 23, 20, 30, 3, 54, 17, 17, 25, 9, 3, 6, 150, 180, 195, 170, 237, 175, 150, 180, 195, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 184, 0, 104, 1, 156, 9, 64, 11, 208, 12, 100, 15, 62, 23, 40, 61, 52, 56, 24, 20, 28, 16, 4, 12, 77, 180, 195, 170, 237, 175, 77, 180, 195, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 164, 0, 32, 1, 52, 8, 236, 9, 168, 12, 172, 14, 175, 25, 0, 117, 0, 112, 24, 24, 44, 36, 8, 12, 150, 180, 137, 137, 150, 175, 150, 180, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 20, 0, 2, 0, 1, 0, 184, 0, 104, 1, 243, 7, 80, 10, 32, 13, 216, 14, 32, 27, 20, 26, 17, 56, 27, 36, 40, 23, 8, 0, 120, 105, 135, 120, 120, 120, 66, 96, 105, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 184, 0, 104, 1, 243, 7, 80, 10, 32, 13, 216, 14, 32, 27, 0, 26, 17, 56, 27, 36, 40, 23, 8, 0, 120, 105, 135, 120, 120, 120, 66, 96, 105, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 2, 0, 5, 0, 148, 0, 8, 1, 232, 8, 68, 12, 112, 13, 140, 15, 186, 19, 15, 18, 12, 36, 14, 12, 16, 9, 3, 3, 110, 180, 177, 225, 247, 175, 110, 180, 177, 44, 45, 70, 130, 50, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 148, 0, 24, 1, 209, 8, 68, 12, 112, 13, 140, 15, 186, 19, 0, 21, 12, 40, 14, 12, 16, 9, 3, 3, 110, 180, 177, 225, 247, 175, 110, 180, 177, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 95, 0, 4, 0, 5, 0, 236, 0, 216, 1, 76, 4, 82, 8, 172, 13, 160, 15, 0, 27, 45, 17, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 100, 100, 52, 225, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 236, 0, 216, 1, 76, 4, 82, 8, 172, 13, 160, 15, 0, 27, 50, 17, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 100, 100, 52, 225, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 236, 0, 216, 1, 76, 4, 82, 8, 172, 13, 160, 15, 0, 27, 0, 17, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 100, 100, 47, 225, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 236, 0, 216, 1, 76, 4, 82, 8, 172, 13, 160, 15, 0, 27, 0, 17, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 100, 100, 48, 225, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 80, 0, 4, 0, 5, 0, 236, 0, 216, 1, 76, 4, 82, 8, 172, 13, 160, 15, 0, 27, 45, 17, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 100, 100, 53, 225, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 236, 0, 216, 1, 76, 4, 82, 8, 172, 13, 160, 15, 0, 27, 35, 17, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 100, 100, 53, 225, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 236, 0, 216, 1, 76, 4, 82, 8, 172, 13, 160, 15, 0, 27, 0, 17, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 100, 100, 53, 225, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 236, 0, 216, 1, 76, 4, 82, 8, 172, 13, 160, 15, 0, 27, 0, 17, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 100, 100, 53, 225, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 110, 0, 4, 0, 5, 0, 196, 0, 114, 1, 84, 4, 252, 8, 88, 12, 91, 14, 32, 27, 70, 18, 46, 20, 38, 12, 16, 16, 6, 0, 125, 60, 135, 120, 120, 120, 80, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 196, 0, 114, 1, 84, 4, 252, 8, 88, 12, 91, 14, 32, 27, 0, 18, 46, 20, 38, 12, 16, 16, 6, 0, 125, 60, 135, 120, 120, 120, 80, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 244, 0, 18, 2, 208, 4, 76, 9, 168, 12, 91, 14, 32, 27, 40, 50, 46, 58, 81, 45, 46, 28, 8, 0, 120, 75, 135, 120, 120, 120, 90, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 244, 0, 98, 2, 172, 5, 116, 9, 188, 12, 141, 14, 32, 27, 0, 82, 48, 65, 110, 71, 69, 39, 13, 0, 120, 135, 135, 120, 120, 120, 120, 75, 90, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 110, 0, 4, 0, 5, 0, 196, 0, 114, 1, 84, 4, 252, 8, 88, 12, 91, 14, 32, 27, 70, 18, 46, 20, 38, 12, 16, 16, 6, 0, 125, 60, 135, 120, 120, 120, 80, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 196, 0, 114, 1, 84, 4, 252, 8, 88, 12, 91, 14, 32, 27, 0, 19, 47, 20, 38, 12, 16, 16, 6, 0, 125, 60, 135, 120, 120, 120, 80, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 252, 0, 27, 3, 21, 4, 120, 10, 68, 12, 116, 14, 192, 28, 40, 56, 51, 56, 84, 43, 41, 23, 13, 0, 120, 120, 105, 120, 120, 120, 165, 60, 90, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 12, 1, 27, 3, 21, 4, 24, 11, 148, 12, 216, 14, 64, 29, 0, 96, 55, 76, 108, 65, 68, 37, 17, 0, 120, 120, 105, 120, 120, 120, 150, 60, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 110, 0, 4, 0, 5, 0, 196, 0, 114, 1, 84, 4, 252, 8, 88, 12, 91, 14, 32, 27, 70, 18, 46, 20, 38, 12, 16, 16, 6, 0, 125, 60, 135, 120, 120, 120, 80, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 196, 0, 114, 1, 84, 4, 252, 8, 88, 12, 91, 14, 32, 27, 0, 19, 47, 20, 38, 12, 16, 16, 6, 0, 125, 60, 135, 120, 120, 120, 80, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 20, 1, 18, 2, 205, 5, 136, 9, 248, 12, 191, 14, 0, 28, 40, 51, 49, 64, 81, 61, 52, 35, 12, 0, 135, 60, 120, 120, 120, 120, 75, 90, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 4, 1, 98, 2, 180, 6, 236, 9, 72, 13, 85, 15, 128, 27, 0, 86, 50, 69, 101, 95, 76, 39, 20, 0, 120, 120, 150, 120, 120, 120, 120, 120, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 108, 0, 5, 0, 5, 0, 196, 0, 114, 1, 84, 4, 252, 8, 88, 12, 91, 14, 32, 27, 70, 18, 46, 20, 38, 12, 16, 16, 6, 0, 125, 60, 135, 120, 120, 120, 80, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 196, 0, 114, 1, 84, 4, 252, 8, 88, 12, 91, 14, 32, 27, 0, 19, 47, 20, 38, 12, 16, 16, 6, 0, 125, 60, 135, 120, 120, 120, 80, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 216, 0, 184, 1, 169, 6, 96, 9, 128, 12, 66, 14, 192, 27, 9, 30, 38, 54, 49, 44, 42, 26, 10, 0, 120, 105, 120, 120, 120, 120, 30, 105, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 212, 0, 179, 1, 155, 7, 96, 9, 228, 12, 216, 14, 160, 27, 29, 42, 42, 61, 58, 67, 51, 31, 11, 0, 120, 105, 180, 120, 120, 120, 24, 96, 99, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 200, 0, 164, 1, 141, 8, 0, 10, 32, 13, 110, 15, 64, 27, 0, 95, 63, 93, 97, 97, 76, 45, 16, 0, 120, 105, 120, 120, 120, 120, 15, 75, 75, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 105, 0, 4, 0, 5, 0, 196, 0, 114, 1, 84, 4, 252, 8, 88, 12, 91, 14, 32, 27, 70, 18, 46, 20, 39, 12, 16, 16, 6, 0, 125, 60, 135, 120, 120, 120, 80, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 196, 0, 114, 1, 84, 4, 252, 8, 88, 12, 91, 14, 32, 27, 0, 19, 47, 20, 38, 12, 16, 16, 6, 0, 125, 60, 135, 120, 120, 120, 80, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 105, 0, 205, 0, 208, 2, 252, 8, 88, 12, 76, 14, 32, 27, 35, 34, 36, 32, 40, 20, 20, 16, 9, 0, 117, 117, 153, 135, 135, 120, 117, 117, 153, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 168, 0, 209, 1, 68, 3, 100, 10, 104, 11, 141, 14, 32, 27, 0, 160, 47, 105, 110, 63, 58, 28, 23, 0, 120, 120, 135, 120, 120, 120, 120, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 105, 0, 4, 0, 5, 0, 196, 0, 114, 1, 84, 4, 252, 8, 88, 12, 91, 14, 32, 27, 70, 18, 46, 20, 38, 12, 16, 16, 6, 0, 125, 60, 135, 120, 120, 120, 80, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 196, 0, 114, 1, 84, 4, 252, 8, 88, 12, 91, 14, 32, 27, 0, 19, 47, 20, 38, 12, 16, 16, 6, 0, 125, 60, 135, 120, 120, 120, 80, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 252, 0, 164, 1, 95, 5, 252, 8, 168, 12, 141, 14, 96, 27, 35, 55, 57, 70, 73, 45, 48, 30, 15, 0, 135, 75, 120, 120, 120, 120, 45, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 188, 0, 184, 1, 205, 5, 16, 9, 148, 12, 41, 14, 96, 27, 0, 150, 82, 110, 123, 99, 82, 58, 20, 0, 120, 90, 120, 120, 120, 120, 90, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 70, 0, 3, 0, 5, 0, 196, 0, 114, 1, 84, 4, 252, 8, 88, 12, 91, 14, 32, 27, 70, 22, 51, 28, 30, 12, 16, 16, 6, 0, 125, 60, 135, 120, 120, 120, 80, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 196, 0, 114, 1, 84, 4, 252, 8, 88, 12, 91, 14, 32, 27, 0, 22, 51, 28, 30, 12, 16, 16, 6, 0, 125, 60, 135, 120, 120, 120, 80, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 184, 0, 164, 1, 153, 4, 132, 8, 128, 12, 254, 16, 64, 27, 0, 6, 28, 12, 16, 8, 6, 4, 3, 0, 120, 105, 120, 120, 120, 120, 75, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 20, 0, 2, 0, 5, 0, 196, 0, 114, 1, 84, 4, 252, 8, 88, 12, 91, 14, 32, 27, 20, 12, 38, 22, 25, 9, 12, 12, 5, 0, 120, 60, 135, 120, 120, 120, 75, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 196, 0, 114, 1, 84, 4, 252, 8, 88, 12, 91, 14, 32, 27, 0, 19, 48, 28, 32, 12, 16, 16, 6, 0, 120, 60, 135, 120, 120, 120, 75, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 115, 0, 3, 0, 5, 0, 196, 0, 114, 1, 56, 4, 252, 8, 88, 12, 91, 14, 32, 27, 65, 18, 46, 20, 36, 12, 16, 16, 6, 0, 125, 60, 135, 120, 120, 120, 80, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 196, 0, 114, 1, 56, 4, 252, 8, 88, 12, 91, 14, 32, 27, 50, 18, 48, 20, 28, 12, 16, 16, 6, 0, 125, 60, 135, 120, 120, 120, 80, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 196, 0, 114, 1, 36, 4, 252, 8, 88, 12, 91, 14, 32, 27, 0, 12, 40, 17, 17, 6, 13, 13, 5, 0, 125, 60, 135, 120, 120, 120, 80, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 80, 0, 4, 0, 5, 0, 236, 0, 224, 1, 220, 5, 236, 9, 172, 13, 160, 15, 0, 27, 45, 17, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 150, 150, 53, 225, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 236, 0, 224, 1, 220, 5, 236, 9, 172, 13, 160, 15, 0, 27, 35, 17, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 150, 150, 53, 225, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 236, 0, 224, 1, 220, 5, 236, 9, 172, 13, 160, 15, 0, 27, 0, 17, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 150, 150, 53, 225, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 236, 0, 224, 1, 220, 5, 236, 9, 172, 13, 160, 15, 0, 27, 0, 17, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 150, 150, 53, 225, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 94, 0, 4, 0, 5, 0, 236, 0, 124, 1, 12, 7, 236, 9, 172, 13, 160, 15, 0, 27, 50, 16, 48, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 236, 0, 144, 1, 12, 7, 236, 9, 172, 13, 160, 15, 0, 27, 0, 17, 52, 36, 25, 18, 16, 18, 11, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 32, 1, 18, 2, 4, 6, 196, 9, 92, 13, 135, 15, 160, 27, 45, 25, 37, 46, 47, 47, 48, 28, 7, 0, 120, 75, 135, 120, 120, 120, 60, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 240, 0, 73, 2, 15, 6, 176, 9, 208, 12, 16, 14, 160, 27, 0, 99, 58, 71, 121, 73, 58, 41, 11, 0, 120, 120, 150, 120, 120, 120, 120, 90, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 115, 0, 4, 0, 5, 0, 236, 0, 124, 1, 12, 7, 236, 9, 172, 13, 160, 15, 0, 27, 45, 19, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 236, 0, 124, 1, 224, 6, 236, 9, 172, 13, 160, 15, 0, 27, 20, 18, 52, 38, 23, 18, 16, 18, 10, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 4, 1, 57, 3, 216, 5, 20, 10, 172, 13, 241, 14, 64, 25, 50, 26, 33, 43, 58, 43, 44, 27, 5, 0, 120, 90, 135, 120, 120, 120, 75, 90, 90, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 228, 0, 137, 3, 252, 4, 236, 9, 188, 12, 41, 14, 64, 27, 0, 92, 46, 74, 100, 77, 70, 57, 12, 0, 120, 165, 135, 120, 120, 120, 120, 90, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 115, 0, 4, 0, 5, 0, 236, 0, 124, 1, 12, 7, 236, 9, 172, 13, 160, 15, 0, 27, 50, 16, 48, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 176, 0, 154, 1, 78, 7, 20, 10, 192, 13, 185, 15, 224, 27, 20, 18, 48, 35, 19, 17, 13, 13, 7, 0, 120, 30, 120, 120, 120, 120, 60, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 32, 1, 78, 2, 169, 6, 20, 10, 192, 13, 185, 15, 224, 27, 45, 26, 43, 42, 55, 45, 42, 29, 5, 0, 120, 75, 120, 120, 120, 120, 90, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 240, 0, 58, 2, 125, 6, 20, 10, 92, 13, 48, 17, 224, 27, 0, 73, 48, 61, 95, 89, 78, 33, 7, 0, 120, 120, 120, 120, 120, 120, 90, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 108, 0, 4, 0, 5, 0, 236, 0, 124, 1, 12, 7, 236, 9, 172, 13, 160, 15, 0, 27, 45, 17, 53, 33, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 236, 0, 144, 1, 12, 7, 236, 9, 172, 13, 160, 15, 0, 27, 15, 15, 52, 31, 25, 18, 16, 18, 11, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 236, 0, 164, 1, 122, 7, 80, 10, 172, 13, 235, 15, 128, 27, 49, 23, 43, 38, 48, 50, 43, 29, 9, 0, 120, 75, 90, 120, 120, 120, 30, 105, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 204, 0, 144, 1, 97, 8, 20, 10, 92, 13, 135, 15, 128, 27, 0, 81, 57, 73, 72, 90, 90, 58, 13, 0, 120, 105, 150, 120, 120, 120, 45, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 107, 0, 4, 0, 5, 0, 220, 0, 164, 1, 133, 7, 20, 10, 52, 13, 29, 16, 0, 25, 45, 19, 54, 26, 9, 10, 9, 7, 8, 0, 120, 45, 120, 120, 120, 120, 75, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 220, 0, 164, 1, 249, 5, 196, 9, 108, 12, 141, 14, 128, 24, 20, 18, 52, 28, 18, 19, 10, 10, 8, 0, 120, 45, 120, 120, 120, 120, 75, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 252, 0, 224, 1, 18, 5, 196, 9, 228, 12, 41, 14, 128, 25, 43, 39, 54, 58, 54, 38, 37, 25, 12, 0, 120, 60, 120, 120, 120, 120, 90, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 12, 1, 224, 1, 178, 3, 236, 9, 8, 12, 222, 13, 128, 25, 0, 117, 65, 90, 99, 67, 78, 52, 17, 0, 120, 75, 150, 120, 120, 120, 90, 120, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 106, 0, 4, 0, 5, 0, 236, 0, 124, 1, 12, 7, 236, 9, 172, 13, 160, 15, 0, 27, 45, 18, 53, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 236, 0, 164, 1, 12, 7, 236, 9, 172, 13, 160, 15, 0, 27, 21, 17, 52, 39, 23, 16, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 150, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 8, 1, 224, 1, 169, 6, 156, 9, 152, 13, 166, 14, 32, 27, 41, 27, 39, 45, 42, 41, 51, 30, 8, 0, 120, 75, 120, 120, 120, 120, 60, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 228, 0, 224, 1, 125, 6, 76, 9, 148, 12, 66, 14, 32, 27, 0, 102, 68, 83, 83, 94, 100, 68, 14, 0, 120, 90, 120, 120, 120, 120, 90, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 60, 0, 3, 0, 5, 0, 236, 0, 124, 1, 12, 7, 236, 9, 172, 13, 160, 15, 0, 27, 60, 16, 49, 35, 21, 13, 11, 13, 7, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 236, 0, 124, 1, 12, 7, 236, 9, 172, 13, 160, 15, 0, 27, 0, 22, 58, 41, 25, 16, 13, 16, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 236, 0, 124, 1, 12, 7, 236, 9, 172, 13, 160, 15, 0, 27, 0, 22, 58, 41, 25, 16, 13, 16, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 20, 0, 2, 0, 5, 0, 236, 0, 124, 1, 12, 7, 236, 9, 172, 13, 160, 15, 0, 27, 20, 19, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 236, 0, 124, 1, 12, 7, 236, 9, 172, 13, 160, 15, 0, 27, 0, 19, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 100, 0, 3, 0, 5, 0, 236, 0, 124, 1, 8, 7, 236, 9, 172, 13, 160, 15, 0, 27, 60, 23, 53, 41, 24, 20, 16, 13, 8, 0, 132, 60, 90, 120, 120, 120, 42, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 236, 0, 124, 1, 8, 7, 236, 9, 172, 13, 160, 15, 0, 27, 40, 23, 53, 41, 24, 20, 16, 13, 8, 0, 132, 60, 90, 120, 120, 120, 42, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 236, 0, 124, 1, 244, 6, 236, 9, 172, 13, 160, 15, 0, 27, 0, 14, 42, 32, 20, 16, 12, 9, 6, 0, 132, 60, 90, 120, 120, 120, 42, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 75, 0, 4, 0, 5, 0, 236, 0, 224, 1, 44, 6, 252, 8, 144, 11, 180, 15, 0, 27, 45, 17, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 150, 150, 55, 225, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 236, 0, 224, 1, 44, 6, 252, 8, 144, 11, 180, 15, 0, 27, 30, 17, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 150, 150, 55, 225, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 236, 0, 224, 1, 44, 6, 252, 8, 144, 11, 180, 15, 0, 27, 0, 17, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 150, 150, 55, 225, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 236, 0, 224, 1, 44, 6, 252, 8, 144, 11, 180, 15, 0, 27, 0, 17, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 150, 150, 55, 225, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 20, 0, 2, 0, 5, 0, 236, 0, 224, 1, 120, 5, 252, 8, 28, 12, 172, 13, 0, 27, 20, 18, 59, 30, 17, 8, 8, 4, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 236, 0, 224, 1, 120, 5, 252, 8, 28, 12, 172, 13, 0, 27, 0, 18, 59, 30, 17, 8, 8, 4, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 95, 0, 3, 0, 5, 0, 236, 0, 152, 1, 120, 5, 252, 8, 28, 12, 172, 13, 0, 27, 55, 19, 59, 30, 17, 8, 8, 4, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 236, 0, 152, 1, 120, 5, 252, 8, 28, 12, 172, 13, 0, 27, 40, 19, 59, 30, 17, 8, 8, 4, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 236, 0, 152, 1, 120, 5, 252, 8, 28, 12, 172, 13, 0, 27, 0, 12, 48, 24, 14, 7, 7, 3, 7, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 50, 0, 2, 0, 5, 0, 204, 0, 214, 1, 252, 8, 184, 11, 16, 14, 160, 15, 0, 27, 50, 29, 60, 48, 20, 24, 16, 16, 10, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 20, 150, 150, 51, 220, 10, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 204, 0, 214, 1, 252, 8, 184, 11, 16, 14, 160, 15, 0, 27, 0, 29, 60, 48, 20, 24, 16, 16, 10, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 20, 150, 150, 51, 220, 10, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 95, 0, 4, 0, 5, 0, 204, 0, 214, 1, 92, 8, 24, 11, 172, 13, 160, 15, 0, 27, 45, 29, 60, 48, 20, 24, 16, 16, 10, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 20, 150, 150, 51, 220, 14, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 204, 0, 214, 1, 92, 8, 24, 11, 172, 13, 160, 15, 0, 27, 50, 29, 60, 48, 20, 24, 16, 16, 10, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 20, 150, 150, 50, 220, 14, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 204, 0, 214, 1, 252, 8, 184, 11, 16, 14, 4, 16, 0, 27, 0, 29, 60, 48, 20, 24, 16, 16, 10, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 20, 150, 150, 50, 220, 14, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 204, 0, 214, 1, 252, 8, 184, 11, 16, 14, 4, 16, 0, 27, 0, 29, 60, 48, 20, 24, 16, 16, 10, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 20, 150, 150, 50, 220, 14, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 145, 0, 6, 0, 5, 0, 204, 0, 120, 1, 92, 8, 124, 11, 172, 13, 160, 15, 0, 27, 35, 22, 44, 48, 20, 20, 16, 16, 10, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 204, 0, 120, 1, 192, 8, 28, 12, 172, 13, 160, 15, 0, 27, 50, 22, 46, 46, 21, 21, 16, 16, 10, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 204, 0, 120, 1, 252, 8, 104, 11, 172, 13, 160, 15, 0, 27, 0, 21, 46, 46, 25, 21, 16, 16, 10, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 37, 0, 200, 0, 112, 1, 252, 8, 104, 11, 172, 13, 160, 15, 112, 23, 20, 28, 36, 32, 24, 24, 16, 16, 4, 8, 110, 180, 160, 200, 200, 175, 110, 180, 160, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 37, 0, 204, 0, 120, 1, 92, 8, 124, 11, 172, 13, 160, 15, 0, 27, 60, 30, 60, 48, 20, 24, 16, 16, 10, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 13, 2, 161, 5, 36, 9, 188, 12, 116, 14, 96, 27, 0, 87, 41, 79, 96, 54, 56, 43, 23, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 100, 0, 5, 0, 5, 0, 204, 0, 120, 1, 92, 8, 124, 11, 172, 13, 160, 15, 0, 27, 50, 22, 44, 48, 20, 20, 16, 16, 10, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 204, 0, 120, 1, 192, 8, 28, 12, 172, 13, 160, 15, 0, 27, 50, 22, 46, 46, 21, 21, 16, 16, 10, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 204, 0, 120, 1, 252, 8, 104, 11, 172, 13, 160, 15, 0, 27, 0, 21, 46, 46, 25, 21, 16, 16, 10, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 180, 0, 29, 1, 192, 8, 104, 11, 172, 13, 160, 15, 0, 29, 80, 16, 6, 42, 19, 30, 34, 22, 6, 0, 120, 105, 120, 120, 120, 120, 45, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 72, 1, 157, 3, 40, 5, 140, 10, 112, 13, 191, 14, 32, 28, 0, 111, 52, 100, 84, 56, 48, 28, 12, 8, 207, 150, 105, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 100, 0, 6, 0, 5, 0, 204, 0, 120, 1, 92, 8, 124, 11, 172, 13, 160, 15, 0, 27, 50, 22, 44, 48, 20, 20, 16, 16, 10, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 204, 0, 120, 1, 192, 8, 28, 12, 172, 13, 160, 15, 0, 27, 50, 22, 46, 46, 21, 21, 16, 16, 10, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 204, 0, 120, 1, 252, 8, 104, 11, 172, 13, 160, 15, 0, 27, 0, 21, 46, 46, 25, 21, 17, 16, 10, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 37, 0, 184, 0, 88, 1, 56, 9, 112, 11, 132, 13, 80, 15, 162, 23, 25, 31, 20, 40, 20, 28, 24, 18, 4, 8, 177, 192, 197, 235, 220, 175, 177, 192, 197, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 176, 0, 0, 2, 36, 8, 88, 10, 112, 13, 160, 15, 162, 23, 35, 47, 30, 60, 33, 40, 39, 18, 6, 6, 177, 162, 152, 235, 235, 207, 177, 162, 152, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 204, 0, 88, 2, 128, 7, 20, 10, 72, 13, 100, 15, 162, 23, 0, 113, 44, 103, 54, 60, 68, 28, 8, 8, 120, 162, 235, 235, 235, 255, 120, 162, 235, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 100, 0, 6, 0, 5, 0, 204, 0, 120, 1, 92, 8, 124, 11, 172, 13, 160, 15, 0, 27, 50, 22, 44, 48, 20, 20, 16, 16, 10, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 204, 0, 120, 1, 192, 8, 28, 12, 172, 13, 160, 15, 0, 27, 50, 22, 46, 46, 21, 21, 16, 16, 10, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 204, 0, 120, 1, 252, 8, 104, 11, 172, 13, 160, 15, 0, 27, 0, 21, 46, 46, 25, 21, 17, 16, 10, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 204, 0, 120, 1, 36, 9, 204, 11, 172, 13, 160, 15, 0, 27, 20, 26, 49, 45, 22, 19, 19, 15, 9, 0, 128, 60, 90, 120, 120, 120, 67, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 184, 0, 83, 1, 232, 8, 139, 11, 126, 13, 98, 15, 219, 26, 25, 30, 33, 58, 34, 39, 39, 22, 12, 3, 138, 77, 101, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 152, 0, 24, 1, 232, 8, 4, 11, 52, 13, 0, 15, 160, 26, 0, 72, 10, 83, 73, 74, 75, 36, 17, 8, 167, 105, 120, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 100, 0, 7, 0, 5, 0, 204, 0, 120, 1, 92, 8, 124, 11, 172, 13, 160, 15, 0, 27, 50, 22, 44, 48, 20, 20, 16, 16, 10, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 204, 0, 120, 1, 192, 8, 28, 12, 172, 13, 160, 15, 0, 27, 50, 22, 46, 46, 21, 21, 16, 16, 10, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 204, 0, 120, 1, 252, 8, 104, 11, 172, 13, 160, 15, 0, 27, 0, 21, 46, 46, 25, 21, 17, 16, 10, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 37, 0, 160, 0, 184, 1, 212, 8, 104, 11, 172, 13, 160, 15, 37, 23, 25, 29, 40, 32, 32, 20, 16, 16, 4, 8, 150, 187, 137, 187, 150, 237, 150, 187, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 37, 0, 216, 0, 248, 1, 64, 6, 176, 9, 68, 12, 176, 14, 37, 23, 25, 35, 39, 48, 30, 24, 21, 15, 3, 6, 150, 140, 182, 187, 222, 237, 150, 140, 182, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 216, 0, 60, 2, 136, 4, 176, 9, 8, 12, 216, 14, 218, 22, 30, 70, 52, 68, 52, 28, 28, 20, 4, 8, 182, 140, 182, 187, 222, 237, 182, 140, 182, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 232, 0, 64, 2, 252, 3, 120, 10, 68, 12, 216, 14, 193, 22, 0, 121, 36, 100, 64, 36, 44, 28, 8, 8, 182, 155, 145, 187, 222, 237, 182, 155, 145, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 100, 0, 6, 0, 5, 0, 204, 0, 120, 1, 92, 8, 124, 11, 172, 13, 160, 15, 0, 27, 50, 22, 44, 48, 20, 20, 16, 16, 10, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 204, 0, 120, 1, 192, 8, 28, 12, 172, 13, 160, 15, 0, 27, 50, 22, 46, 46, 21, 21, 16, 16, 10, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 204, 0, 120, 1, 252, 8, 104, 11, 172, 13, 160, 15, 0, 27, 0, 23, 48, 48, 26, 22, 18, 17, 11, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 37, 0, 176, 0, 120, 1, 152, 8, 104, 11, 172, 13, 160, 15, 62, 23, 25, 28, 40, 28, 23, 24, 16, 16, 4, 8, 150, 150, 170, 170, 237, 175, 150, 150, 170, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 37, 0, 167, 0, 116, 1, 48, 7, 186, 10, 34, 13, 76, 15, 61, 24, 35, 40, 44, 36, 28, 30, 23, 19, 8, 8, 153, 164, 164, 155, 202, 158, 150, 180, 170, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 184, 0, 144, 1, 172, 3, 36, 9, 224, 11, 136, 14, 144, 26, 0, 94, 36, 84, 72, 44, 40, 28, 20, 10, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 15, 0, 2, 0, 5, 0, 204, 0, 120, 1, 92, 8, 124, 11, 172, 13, 160, 15, 0, 27, 15, 17, 45, 36, 15, 18, 12, 12, 7, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 204, 0, 120, 1, 92, 8, 124, 11, 172, 13, 160, 15, 0, 27, 0, 30, 60, 48, 20, 24, 16, 16, 10, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 150, 0, 5, 0, 5, 0, 204, 0, 112, 1, 92, 8, 184, 11, 172, 13, 160, 15, 0, 27, 30, 22, 44, 48, 24, 8, 8, 8, 10, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 204, 0, 112, 1, 172, 8, 184, 11, 172, 13, 160, 15, 0, 27, 60, 24, 48, 48, 26, 8, 8, 8, 13, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 204, 0, 112, 1, 172, 8, 184, 11, 172, 13, 160, 15, 0, 27, 30, 24, 48, 48, 26, 8, 8, 8, 13, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 204, 0, 120, 1, 172, 8, 184, 11, 172, 13, 160, 15, 0, 27, 30, 19, 38, 45, 38, 30, 15, 15, 9, 0, 120, 60, 95, 120, 120, 120, 30, 135, 110, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 37, 0, 200, 0, 144, 1, 172, 8, 184, 11, 172, 13, 160, 15, 112, 23, 0, 10, 20, 20, 28, 18, 10, 10, 2, 5, 110, 180, 160, 200, 200, 175, 110, 180, 160, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 90, 0, 4, 0, 5, 0, 236, 0, 234, 1, 52, 8, 236, 9, 172, 13, 160, 15, 0, 27, 45, 17, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 200, 200, 55, 230, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 236, 0, 234, 1, 52, 8, 236, 9, 172, 13, 160, 15, 0, 27, 45, 17, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 200, 200, 55, 230, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 236, 0, 234, 1, 52, 8, 236, 9, 172, 13, 160, 15, 0, 27, 0, 17, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 200, 200, 55, 230, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 236, 0, 234, 1, 52, 8, 236, 9, 172, 13, 160, 15, 0, 27, 0, 17, 54, 38, 23, 14, 12, 14, 8, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 20, 200, 200, 55, 230, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 129, 0, 3, 0, 5, 0, 240, 0, 13, 2, 248, 9, 124, 11, 76, 14, 23, 17, 224, 23, 50, 13, 43, 11, 11, 5, 7, 10, 3, 0, 120, 90, 165, 120, 120, 120, 90, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 240, 0, 13, 2, 248, 9, 124, 11, 76, 14, 23, 17, 224, 23, 80, 13, 43, 11, 11, 5, 7, 10, 3, 0, 120, 90, 165, 120, 120, 120, 90, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 240, 0, 73, 2, 15, 6, 176, 9, 208, 12, 16, 14, 160, 27, 0, 99, 58, 71, 121, 73, 58, 41, 11, 0, 120, 120, 150, 120, 120, 120, 120, 90, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 129, 0, 3, 0, 5, 0, 240, 0, 13, 2, 248, 9, 124, 11, 76, 14, 23, 17, 224, 23, 50, 13, 43, 11, 11, 5, 7, 10, 3, 0, 120, 90, 165, 120, 120, 120, 90, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 240, 0, 13, 2, 248, 9, 124, 11, 76, 14, 23, 17, 224, 23, 80, 13, 43, 11, 11, 5, 7, 10, 3, 0, 120, 90, 165, 120, 120, 120, 90, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 228, 0, 137, 3, 252, 4, 236, 9, 188, 12, 41, 14, 64, 27, 0, 92, 46, 74, 100, 77, 70, 57, 12, 0, 120, 165, 135, 120, 120, 120, 120, 90, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 129, 0, 3, 0, 5, 0, 240, 0, 13, 2, 248, 9, 124, 11, 76, 14, 23, 17, 224, 23, 50, 13, 43, 11, 11, 5, 7, 10, 3, 0, 120, 90, 165, 120, 120, 120, 90, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 240, 0, 13, 2, 248, 9, 124, 11, 76, 14, 23, 17, 224, 23, 80, 13, 43, 11, 11, 5, 7, 10, 3, 0, 120, 90, 165, 120, 120, 120, 90, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 240, 0, 58, 2, 125, 6, 20, 10, 92, 13, 48, 17, 224, 27, 0, 73, 48, 61, 95, 89, 78, 33, 7, 0, 120, 120, 120, 120, 120, 120, 90, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 129, 0, 3, 0, 5, 0, 240, 0, 13, 2, 248, 9, 124, 11, 76, 14, 23, 17, 224, 23, 50, 13, 43, 11, 11, 5, 7, 10, 3, 0, 120, 90, 165, 120, 120, 120, 90, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 240, 0, 13, 2, 248, 9, 124, 11, 76, 14, 23, 17, 224, 23, 80, 13, 43, 11, 11, 10, 7, 10, 3, 0, 120, 90, 165, 120, 120, 120, 90, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 204, 0, 144, 1, 97, 8, 20, 10, 92, 13, 135, 15, 128, 27, 0, 81, 57, 73, 72, 90, 90, 58, 13, 0, 120, 105, 150, 120, 120, 120, 45, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 129, 0, 3, 0, 5, 0, 240, 0, 13, 2, 248, 9, 124, 11, 76, 14, 23, 17, 224, 23, 50, 13, 43, 11, 11, 5, 7, 10, 3, 0, 120, 90, 165, 120, 120, 120, 90, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 240, 0, 13, 2, 248, 9, 124, 11, 76, 14, 23, 17, 224, 23, 80, 13, 43, 11, 11, 5, 7, 10, 3, 0, 120, 90, 165, 120, 120, 120, 90, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 12, 1, 224, 1, 178, 3, 236, 9, 8, 12, 222, 13, 128, 25, 0, 117, 65, 90, 99, 67, 78, 52, 17, 0, 120, 75, 150, 120, 120, 120, 90, 120, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 129, 0, 3, 0, 5, 0, 240, 0, 13, 2, 248, 9, 124, 11, 76, 14, 23, 17, 224, 23, 50, 13, 43, 11, 11, 5, 7, 10, 3, 0, 120, 90, 165, 120, 120, 120, 90, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 240, 0, 13, 2, 248, 9, 124, 11, 76, 14, 23, 17, 224, 23, 80, 13, 43, 11, 11, 5, 7, 10, 3, 0, 120, 90, 165, 120, 120, 120, 90, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 228, 0, 224, 1, 125, 6, 76, 9, 148, 12, 66, 14, 32, 27, 0, 102, 68, 83, 83, 94, 100, 68, 14, 0, 120, 90, 120, 120, 120, 120, 90, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 49, 0, 3, 0, 1, 0, 12, 1, 249, 1, 61, 9, 96, 9, 152, 13, 29, 16, 64, 27, 50, 39, 52, 19, 25, 54, 27, 19, 8, 0, 150, 120, 120, 120, 120, 120, 135, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 12, 1, 249, 1, 61, 9, 96, 9, 152, 13, 29, 16, 64, 27, 0, 39, 52, 19, 25, 54, 27, 19, 8, 0, 150, 120, 120, 120, 120, 120, 135, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 12, 1, 249, 1, 61, 9, 96, 9, 152, 13, 29, 16, 64, 27, 0, 39, 52, 19, 25, 54, 27, 19, 8, 0, 150, 120, 120, 120, 120, 120, 135, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 70, 0, 2, 0, 5, 0, 240, 0, 13, 2, 248, 9, 124, 11, 76, 14, 23, 17, 224, 23, 70, 16, 48, 16, 16, 8, 8, 12, 3, 0, 120, 90, 165, 120, 120, 120, 90, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 240, 0, 13, 2, 248, 9, 124, 11, 76, 14, 23, 17, 224, 23, 0, 16, 48, 16, 16, 8, 8, 12, 3, 0, 120, 90, 165, 120, 120, 120, 90, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 30, 0, 2, 0, 5, 0, 240, 0, 13, 2, 248, 9, 124, 11, 76, 14, 23, 17, 224, 23, 30, 13, 43, 11, 11, 5, 7, 10, 3, 0, 120, 90, 165, 120, 120, 120, 90, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 240, 0, 13, 2, 248, 9, 124, 11, 76, 14, 23, 17, 224, 23, 0, 13, 43, 11, 11, 5, 7, 10, 3, 0, 120, 90, 165, 120, 120, 120, 90, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 109, 0, 3, 0, 5, 0, 240, 0, 13, 2, 248, 9, 124, 11, 212, 13, 200, 15, 224, 23, 60, 24, 52, 20, 19, 10, 12, 8, 4, 0, 162, 90, 165, 120, 120, 120, 132, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 240, 0, 13, 2, 248, 9, 124, 11, 212, 13, 200, 15, 224, 23, 50, 24, 52, 20, 19, 10, 12, 8, 4, 0, 162, 90, 165, 120, 120, 120, 132, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 240, 0, 13, 2, 248, 9, 124, 11, 212, 13, 160, 15, 224, 23, 0, 14, 40, 14, 10, 5, 7, 9, 3, 0, 162, 90, 165, 120, 120, 120, 132, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 41, 0, 5, 0, 1, 0, 116, 0, 13, 2, 64, 6, 196, 9, 84, 11, 72, 13, 96, 27, 16, 16, 18, 36, 37, 24, 19, 17, 9, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 51, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 116, 0, 13, 2, 64, 6, 196, 9, 84, 11, 72, 13, 96, 27, 0, 22, 22, 43, 39, 24, 22, 19, 12, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 52, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 136, 0, 216, 1, 64, 6, 196, 9, 228, 12, 60, 15, 124, 21, 25, 20, 12, 40, 24, 8, 0, 0, 0, 0, 200, 212, 187, 187, 205, 175, 200, 212, 187, 44, 45, 70, 130, 52, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 136, 0, 216, 1, 64, 6, 196, 9, 228, 12, 60, 15, 124, 21, 0, 17, 12, 36, 24, 8, 0, 0, 0, 0, 200, 212, 187, 187, 205, 175, 200, 212, 187, 44, 45, 70, 130, 51, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 136, 0, 216, 1, 64, 6, 196, 9, 228, 12, 60, 15, 124, 21, 0, 17, 12, 36, 24, 8, 4, 8, 0, 0, 200, 212, 187, 187, 205, 175, 200, 212, 187, 44, 45, 70, 130, 51, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 53, 0, 5, 0, 1, 0, 116, 0, 13, 2, 176, 4, 196, 9, 84, 11, 72, 13, 96, 27, 18, 16, 18, 36, 37, 24, 19, 17, 9, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 51, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 116, 0, 13, 2, 20, 5, 196, 9, 84, 11, 72, 13, 96, 27, 0, 22, 22, 43, 39, 24, 22, 19, 12, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 52, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 136, 0, 224, 1, 24, 6, 196, 9, 228, 12, 60, 15, 124, 21, 35, 20, 12, 40, 24, 8, 0, 0, 0, 0, 200, 212, 187, 187, 205, 175, 200, 212, 187, 44, 45, 70, 130, 52, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 136, 0, 224, 1, 24, 6, 196, 9, 228, 12, 60, 15, 124, 21, 0, 16, 12, 36, 24, 8, 0, 0, 0, 0, 200, 212, 187, 187, 205, 175, 200, 212, 187, 44, 45, 70, 130, 51, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 136, 0, 224, 1, 24, 6, 196, 9, 228, 12, 60, 15, 124, 21, 0, 16, 12, 36, 24, 8, 4, 8, 0, 0, 200, 212, 187, 187, 205, 175, 200, 212, 187, 44, 45, 70, 130, 51, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 27, 0, 3, 0, 5, 0, 136, 0, 8, 2, 64, 6, 252, 8, 184, 11, 100, 15, 124, 21, 28, 14, 7, 36, 21, 14, 14, 14, 0, 0, 200, 212, 187, 187, 205, 175, 200, 212, 187, 44, 45, 70, 130, 50, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 136, 0, 216, 1, 64, 6, 32, 8, 184, 11, 100, 15, 124, 21, 0, 11, 3, 32, 21, 7, 3, 7, 0, 0, 200, 212, 187, 187, 205, 175, 200, 212, 187, 44, 45, 70, 130, 47, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 136, 0, 216, 1, 64, 6, 32, 8, 184, 11, 100, 15, 124, 21, 0, 11, 3, 32, 21, 7, 3, 7, 0, 0, 200, 212, 187, 187, 205, 175, 200, 212, 187, 44, 45, 70, 130, 47, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 34, 0, 4, 0, 5, 0, 136, 0, 8, 2, 64, 6, 252, 8, 184, 11, 100, 15, 124, 21, 12, 19, 8, 40, 32, 16, 16, 16, 0, 0, 200, 212, 187, 187, 205, 175, 200, 212, 187, 44, 45, 70, 130, 51, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 136, 0, 8, 2, 64, 6, 252, 8, 184, 11, 100, 15, 124, 21, 22, 4, 4, 20, 16, 8, 4, 8, 0, 0, 200, 212, 187, 187, 205, 175, 200, 212, 187, 44, 45, 70, 130, 45, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 136, 0, 8, 2, 64, 6, 252, 8, 184, 11, 100, 15, 124, 21, 0, 4, 4, 20, 16, 8, 4, 8, 0, 0, 200, 212, 187, 187, 205, 175, 200, 212, 187, 44, 45, 70, 130, 45, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 136, 0, 8, 2, 64, 6, 252, 8, 184, 11, 100, 15, 124, 21, 0, 4, 4, 20, 16, 8, 4, 8, 0, 0, 200, 212, 187, 187, 205, 175, 200, 212, 187, 44, 45, 70, 130, 45, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 35, 0, 2, 0, 5, 0, 136, 0, 216, 0, 220, 5, 46, 9, 228, 12, 24, 16, 124, 21, 35, 9, 16, 16, 9, 6, 3, 3, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 50, 85, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 136, 0, 216, 0, 220, 5, 46, 9, 228, 12, 24, 16, 124, 21, 0, 9, 16, 16, 9, 6, 3, 3, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 50, 85, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 64, 0, 5, 0, 1, 0, 116, 0, 13, 2, 60, 5, 208, 7, 84, 11, 16, 14, 96, 27, 30, 13, 18, 33, 30, 22, 19, 17, 9, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 116, 0, 13, 2, 60, 5, 128, 7, 40, 10, 60, 15, 96, 27, 0, 19, 22, 39, 33, 26, 24, 8, 12, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 136, 0, 72, 2, 100, 5, 108, 7, 40, 10, 244, 11, 124, 21, 35, 14, 16, 32, 20, 20, 8, 8, 0, 0, 200, 212, 187, 187, 205, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 136, 0, 72, 2, 100, 5, 108, 7, 40, 10, 244, 11, 124, 21, 0, 14, 16, 32, 20, 20, 8, 8, 0, 0, 200, 212, 187, 187, 205, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 136, 0, 224, 1, 24, 6, 252, 8, 28, 12, 116, 14, 124, 21, 0, 13, 12, 32, 20, 16, 4, 8, 0, 0, 200, 212, 187, 187, 205, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 58, 0, 3, 0, 5, 0, 116, 0, 200, 0, 26, 4, 102, 8, 232, 13, 24, 16, 124, 21, 58, 10, 21, 12, 8, 4, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 55, 65, 50, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 200, 0, 26, 4, 102, 8, 232, 13, 24, 16, 124, 21, 0, 10, 21, 12, 8, 4, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 55, 65, 50, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 200, 0, 26, 4, 102, 8, 232, 13, 24, 16, 124, 21, 0, 10, 21, 12, 8, 4, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 55, 65, 50, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 24, 0, 3, 0, 5, 0, 136, 0, 200, 0, 76, 4, 102, 8, 232, 13, 24, 16, 124, 21, 25, 18, 16, 28, 12, 8, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 55, 65, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 136, 0, 200, 0, 76, 4, 102, 8, 232, 13, 24, 16, 124, 21, 0, 18, 16, 28, 12, 8, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 55, 65, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 136, 0, 200, 0, 76, 4, 102, 8, 232, 13, 24, 16, 124, 21, 0, 18, 16, 28, 12, 8, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 55, 65, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 20, 4, 6, 0, 246, 249, 251, 253, 4, 0, 1, 6, 6, 5, 3, 6, 255, 2, 4, 3, 1, 4, 8, 7, 10, 21, 15, 15, 19, 23, 20, 21, 12, 10, 4, 247, 235, 227, 227, 216, 215, 217, 220, 221, 228, 237, 242, 243, 248, 5, 17, 22, 32, 35, 30, 36, 36, 40, 42, 41, 39, 20, 28, 26, 14, 6, 217, 231, 225, 244, 244, 244, 232, 233, 221, 216, 190, 151, 193, 5, 37, 28, 23, 21, 18, 20, 36, 44, 39, 24, 5, 2, 4, 249, 247, 235, 242, 250, 2, 4, 0, 255, 7, 6, 22, 226, 244, 13, 238, 238, 232, 2, 173, 187, 55, 56, 26, 32, 47, 45, 49, 48, 53, 13, 243, 223, 220, 238, 24, 24, 19, 245, 213, 220, 236, 212, 238, 10, 14, 226, 9, 8, 8, 248, 234, 250, 250, 235, 255, 34, 0, 239, 220, 192, 202, 179, 190, 213, 235, 2, 33, 28, 47, 87, 108, 117, 88, 66, 78, 53, 15, 9, 29, 22, 249, 243, 233, 238, 247, 235, 236, 241, 230, 218, 220, 206, 196, 218, 229, 232, 224, 228, 241, 241, 239, 248, 254, 255, 8, 5, 1, 254, 243, 5, 11, 249, 249, 7, 23, 21, 20, 17, 29, 28, 29, 37, 35, 33, 35, 42, 29, 21, 22, 27, 14, 2, 254, 4, 244, 248, 212, 208, 211, 215, 216, 203, 201, 215, 220, 219, 231, 250, 19, 20, 26, 30, 49, 56, 45, 38, 28, 45, 42, 0, 215, 230, 239, 1, 253, 250, 252, 249, 237, 3, 4, 8, 229, 185, 201, 210, 223, 233, 227, 235, 6, 33, 35, 22, 21, 23, 25, 30, 46, 39, 23, 25, 31, 37, 30, 26, 27, 31, 25, 32, 21, 2, 232, 223, 222, 219, 216, 223, 217, 210, 209, 224, 247, 238, 234, 245, 255, 236, 239, 250, 250, 231, 242, 0, 18, 17, 9, 12, 10, 8, 10, 3, 255, 3, 10, 23, 25, 31, 39, 32, 23, 29, 37, 45, 33, 17, 10, 13, 6, 252, 246, 238, 249, 246, 5, 254, 229, 222, 223, 214, 212, 216, 213, 215, 217, 228, 240, 1, 255, 5, 5, 14, 30, 32, 7, 243, 250, 255, 23, 24, 22, 11, 17, 26, 23, 42, 42, 29, 12, 252, 249, 249, 247, 248, 239, 249, 7, 14, 7, 0, 245, 241, 250, 248, 237, 238, 235, 230, 232, 235, 240, 0, 11, 17, 26, 14, 3, 2, 0, 2, 10, 12, 14, 3, 247, 244, 2, 15, 23, 9, 0, 1, 244, 253, 249, 245, 248, 248, 248, 248, 234, 239, 241, 244, 255, 0, 13, 12, 3, 7, 19, 25, 38, 32, 21, 28, 21, 11, 10, 5, 3, 6, 7, 12, 2, 0, 239, 229, 225, 224, 216, 211, 206, 207, 213, 236, 0, 0, 7, 8, 16, 25, 21, 23, 27, 16, 9, 9, 17, 25, 23, 25, 20, 18, 11, 8, 253, 248, 252, 251, 244, 243, 245, 237, 246, 247, 244, 254, 11, 3, 250, 249, 253, 244, 246, 7, 11, 13, 11, 13, 25, 25, 15, 19, 13, 255, 254, 254, 239, 225, 214, 213, 217, 234, 252, 0, 0, 249, 2, 3, 13, 14, 8, 5, 4, 255, 255, 251, 244, 252, 12, 25, 21, 24, 12, 19, 15, 8, 14, 11, 13, 7, 8, 11, 16, 11, 1, 255, 0, 6, 13, 8, 248, 243, 242, 234, 225, 226, 233, 231, 214, 221, 224, 230, 230, 233, 248, 254, 12, 12, 8, 3, 7, 20, 25, 22, 15, 16, 18, 24, 24, 27, 33, 27, 25, 16, 12, 6, 2, 2, 253, 254, 248, 242, 240, 248, 6, 1, 247, 228, 233, 253, 3, 2, 244, 248, 242, 247, 249, 241, 240, 238, 246, 251, 11, 12, 11, 247, 244, 249, 5, 9, 2, 246, 248, 250, 255, 0, 13, 12, 25, 29, 31, 46, 37, 6, 250, 253, 0, 6, 1, 10, 4, 253, 250, 252, 246, 236, 238, 244, 245, 241, 242, 240, 238, 233, 2, 14, 11, 4, 255, 0, 6, 5, 11, 12, 14, 16, 11, 255, 2, 2, 10, 0, 0, 251, 241, 239, 237, 232, 232, 231, 252, 16, 20, 19, 16, 23, 18, 18, 16, 16, 7, 254, 242, 240, 241, 237, 250, 0, 0, 16, 17, 10, 253, 247, 0, 254, 251, 248, 243, 247, 243, 239, 248, 2, 1, 11, 21, 35, 39, 32, 18, 3, 247, 233, 235, 246, 253, 246, 242, 245, 3, 252, 251, 6, 15, 0, 249, 254, 254, 245, 247, 250, 9, 13, 19, 21, 21, 4, 252, 5, 250, 237, 236, 242, 241, 235, 223, 235, 250, 253, 8, 20, 17, 19, 30, 27, 33, 38, 30, 29, 24, 17, 20, 31, 14, 251, 245, 233, 214, 208, 198, 191, 196, 213, 231, 249, 243, 241, 249, 5, 9, 20, 39, 36, 27, 13, 12, 23, 23, 29, 23, 24, 24, 9, 255, 236, 221, 231, 255, 9, 1, 6, 8, 7, 1, 255, 253, 12, 9, 7, 252, 246, 236, 232, 238, 244, 1, 0, 254, 234, 237, 243, 238, 242, 248, 247, 254, 2, 4, 2, 8, 14, 27, 44, 45, 38, 28, 16, 9, 7, 11, 4, 248, 244, 244, 236, 230, 240, 237, 244, 246, 248, 249, 249, 245, 255, 0, 6, 5, 18, 23, 24, 9, 11, 14, 9, 255, 246, 249, 241, 240, 230, 224, 237, 249, 0, 5, 0, 255, 0, 248, 2, 13, 14, 18, 5, 254, 8, 17, 22, 17, 18, 25, 37, 23, 8, 2, 241, 238, 236, 238, 235, 240, 239, 240, 221, 232, 235, 250, 15, 14, 10, 12, 4, 254, 9, 23, 33, 38, 26, 255, 0, 2, 6, 253, 244, 238, 241, 247, 238, 226, 225, 233, 245, 237, 244, 241, 246, 248, 254, 19, 45, 43, 28, 22, 26, 30, 39, 33, 21, 1, 252, 3, 0, 243, 245, 243, 250, 238, 241, 249, 237, 228, 221, 233, 234, 236, 243, 3, 1, 14, 17, 20, 17, 21, 31, 32, 18, 0, 3, 252, 239, 219, 227, 241, 248, 248, 7, 17, 10, 7, 7, 3, 11, 11, 13, 255, 235, 246, 14, 25, 23, 13, 255, 241, 238, 248, 255, 255, 246, 246, 253, 244, 248, 252, 13, 9, 10, 6, 0, 249, 244, 95, 1, 17, 0, 9, 7, 6, 6, 2, 0, 255, 254, 254, 252, 250, 252, 253, 254, 255, 0, 0, 3, 4, 6, 7, 13, 15, 19, 17, 22, 236, 133, 180, 12, 41, 52, 55, 56, 39, 238, 156, 177, 251, 32, 42, 33, 7, 241, 230, 252, 17, 10, 17, 15, 247, 236, 240, 245, 248, 251, 0, 7, 16, 12, 9, 2, 0, 4, 3, 0, 249, 247, 11, 8, 250, 0, 253, 250, 250, 253, 252, 250, 1, 4, 1, 254, 255, 7, 13, 14, 14, 24, 29, 37, 252, 193, 183, 173, 222, 24, 44, 55, 53, 28, 4, 248, 249, 251, 254, 254, 236, 232, 240, 250, 255, 8, 17, 15, 18, 11, 251, 252, 253, 1, 254, 247, 247, 250, 254, 3, 3, 5, 11, 12, 6, 255, 253, 0, 254, 246, 253, 250, 253, 249, 1, 6, 10, 28, 19, 3, 245, 203, 219, 20, 20, 1, 241, 3, 22, 30, 32, 36, 253, 225, 225, 222, 230, 238, 248, 4, 11, 22, 28, 29, 20, 7, 243, 236, 4, 4, 5, 252, 224, 225, 255, 10, 11, 8, 17, 18, 14, 8, 2, 219, 204, 227, 254, 16, 39, 57, 31, 5, 244, 247, 255, 248, 233, 226, 227, 242, 253, 0, 7, 16, 27, 36, 33, 26, 22, 248, 211, 211, 216, 236, 1, 9, 9, 17, 20, 27, 18, 3, 248, 248, 252, 252, 247, 242, 244, 238, 247, 4, 19, 29, 31, 20, 3, 248, 247, 244, 242, 235, 237, 251, 7, 15, 12, 8, 2, 5, 4, 0, 0, 255, 253, 248, 248, 250, 3, 7, 12, 8, 11, 7, 4, 252, 246, 238, 242, 241, 244, 0, 251, 9, 21, 17, 26, 27, 15, 11, 250, 231, 239, 232, 229, 238, 249, 3, 13, 16, 11, 13, 18, 18, 17, 253, 241, 245, 238, 245, 246, 244, 2, 12, 14, 17, 14, 4, 0, 250, 241, 249, 0, 252, 0, 245, 248, 0, 8, 14, 13, 8, 12, 14, 4, 0, 255, 243, 241, 239, 239, 252, 5, 4, 2, 7, 3, 7, 5, 0, 1, 5, 12, 20, 24, 0, 70, 0, 3, 0, 1, 0, 116, 0, 232, 0, 232, 3, 60, 10, 232, 13, 24, 16, 124, 21, 70, 3, 12, 7, 4, 2, 2, 2, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 232, 0, 232, 3, 60, 10, 232, 13, 24, 16, 124, 21, 0, 3, 12, 7, 4, 2, 2, 2, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 232, 0, 232, 3, 60, 10, 232, 13, 24, 16, 124, 21, 0, 3, 12, 7, 4, 2, 2, 2, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 41, 0, 4, 0, 1, 0, 216, 0, 235, 0, 197, 4, 124, 11, 84, 16, 160, 15, 124, 21, 12, 20, 30, 21, 7, 10, 7, 0, 0, 0, 177, 108, 147, 135, 135, 0, 177, 108, 147, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 216, 0, 235, 0, 197, 4, 124, 11, 84, 16, 160, 15, 124, 21, 0, 20, 30, 21, 7, 10, 7, 0, 0, 0, 177, 108, 147, 135, 135, 0, 177, 108, 147, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 172, 0, 4, 1, 200, 3, 52, 8, 248, 12, 41, 14, 32, 27, 30, 30, 31, 33, 30, 34, 24, 24, 9, 0, 120, 135, 180, 120, 120, 120, 120, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 140, 0, 244, 1, 172, 5, 36, 9, 248, 12, 41, 14, 32, 27, 0, 28, 24, 50, 44, 44, 31, 31, 12, 0, 120, 135, 180, 120, 120, 120, 120, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 41, 0, 4, 0, 1, 0, 216, 0, 235, 0, 197, 4, 124, 11, 84, 16, 160, 15, 124, 21, 12, 20, 30, 21, 7, 10, 7, 0, 0, 0, 177, 108, 147, 135, 135, 0, 177, 108, 147, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 216, 0, 235, 0, 197, 4, 124, 11, 84, 16, 160, 15, 124, 21, 0, 20, 30, 21, 7, 10, 7, 0, 0, 0, 177, 108, 147, 135, 135, 0, 177, 108, 147, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 172, 0, 4, 1, 200, 3, 52, 8, 248, 12, 41, 14, 32, 27, 30, 57, 43, 45, 42, 46, 33, 33, 13, 0, 120, 135, 180, 120, 120, 120, 120, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 140, 0, 244, 1, 172, 5, 36, 9, 248, 12, 41, 14, 32, 27, 0, 58, 34, 72, 63, 63, 45, 45, 18, 0, 120, 135, 180, 120, 120, 120, 120, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 41, 0, 4, 0, 1, 0, 135, 0, 235, 0, 212, 3, 124, 11, 84, 16, 184, 16, 124, 21, 12, 19, 30, 21, 7, 10, 7, 0, 0, 0, 177, 108, 147, 135, 135, 0, 177, 108, 147, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 135, 0, 235, 0, 212, 3, 124, 11, 84, 16, 160, 15, 124, 21, 0, 19, 30, 21, 7, 10, 7, 0, 0, 0, 177, 108, 147, 135, 135, 0, 177, 108, 147, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 36, 1, 68, 2, 178, 3, 196, 9, 152, 13, 35, 15, 64, 27, 30, 37, 36, 38, 45, 34, 35, 16, 3, 0, 165, 165, 150, 120, 120, 120, 165, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 248, 0, 137, 3, 62, 5, 140, 10, 112, 13, 35, 15, 32, 28, 0, 82, 32, 89, 86, 48, 32, 28, 12, 0, 150, 135, 105, 120, 120, 120, 210, 165, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 36, 0, 4, 0, 1, 0, 135, 0, 235, 0, 212, 3, 124, 11, 84, 16, 160, 15, 124, 21, 12, 19, 30, 21, 7, 10, 7, 0, 0, 0, 177, 108, 147, 135, 135, 0, 177, 108, 147, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 135, 0, 235, 0, 212, 3, 124, 11, 84, 16, 184, 16, 124, 21, 0, 19, 30, 21, 7, 10, 7, 0, 0, 0, 177, 108, 147, 135, 135, 0, 177, 108, 147, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 240, 0, 184, 1, 164, 4, 192, 8, 112, 13, 10, 15, 96, 27, 25, 47, 45, 38, 50, 55, 38, 22, 6, 0, 120, 165, 180, 120, 120, 120, 150, 150, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 240, 0, 203, 2, 224, 6, 176, 9, 112, 13, 10, 15, 96, 27, 0, 60, 40, 75, 69, 67, 45, 27, 8, 0, 120, 135, 240, 120, 120, 120, 150, 105, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 46, 0, 4, 0, 1, 0, 135, 0, 235, 0, 252, 3, 124, 11, 84, 16, 184, 16, 124, 21, 12, 19, 30, 21, 7, 10, 7, 0, 0, 0, 177, 108, 147, 135, 135, 0, 177, 108, 147, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 135, 0, 235, 0, 252, 3, 124, 11, 84, 16, 184, 16, 124, 21, 0, 19, 30, 21, 7, 10, 7, 0, 0, 0, 177, 108, 147, 135, 135, 0, 177, 108, 147, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 60, 0, 170, 0, 106, 5, 112, 8, 92, 13, 135, 15, 160, 26, 35, 33, 14, 51, 44, 37, 30, 21, 6, 0, 120, 120, 120, 120, 120, 120, 120, 105, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 60, 0, 59, 1, 174, 8, 160, 10, 92, 13, 135, 15, 160, 26, 0, 62, 15, 79, 70, 68, 55, 32, 15, 0, 120, 120, 120, 120, 120, 120, 120, 105, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 41, 0, 4, 0, 1, 0, 135, 0, 235, 0, 212, 3, 124, 11, 84, 16, 184, 16, 124, 21, 12, 15, 26, 18, 6, 8, 6, 0, 0, 0, 177, 108, 147, 135, 135, 0, 177, 108, 147, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 135, 0, 235, 0, 212, 3, 124, 11, 84, 16, 184, 16, 124, 21, 0, 17, 30, 18, 8, 8, 8, 0, 0, 0, 177, 108, 147, 135, 135, 0, 177, 108, 147, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 200, 0, 205, 0, 247, 2, 212, 8, 224, 11, 41, 14, 160, 26, 30, 54, 32, 51, 37, 20, 17, 12, 7, 0, 117, 117, 153, 135, 135, 120, 117, 117, 153, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 232, 0, 218, 2, 222, 3, 60, 10, 224, 11, 222, 13, 160, 28, 0, 54, 31, 55, 68, 32, 33, 22, 8, 7, 230, 150, 120, 120, 120, 120, 185, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 41, 0, 4, 0, 1, 0, 135, 0, 235, 0, 212, 3, 124, 11, 84, 16, 160, 15, 124, 21, 12, 19, 30, 21, 7, 10, 7, 0, 0, 0, 177, 108, 147, 135, 135, 0, 177, 108, 147, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 135, 0, 235, 0, 212, 3, 124, 11, 84, 16, 184, 16, 124, 21, 0, 19, 30, 21, 7, 10, 7, 0, 0, 0, 177, 108, 147, 135, 135, 0, 177, 108, 147, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 105, 0, 205, 0, 92, 3, 228, 7, 208, 12, 41, 14, 96, 26, 30, 43, 37, 39, 37, 27, 21, 15, 5, 0, 117, 132, 153, 135, 135, 120, 117, 117, 153, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 84, 0, 104, 1, 232, 3, 212, 8, 148, 12, 41, 14, 64, 26, 0, 57, 19, 78, 58, 43, 44, 40, 13, 0, 120, 150, 135, 120, 120, 120, 60, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 25, 0, 4, 0, 5, 0, 116, 0, 232, 0, 252, 3, 60, 10, 232, 13, 24, 16, 124, 21, 15, 9, 17, 15, 4, 2, 2, 2, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 232, 0, 252, 3, 60, 10, 232, 13, 24, 16, 124, 21, 0, 9, 17, 15, 4, 2, 2, 2, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 160, 0, 4, 1, 200, 3, 108, 7, 248, 12, 41, 14, 32, 27, 10, 13, 18, 25, 18, 11, 14, 14, 5, 0, 120, 135, 180, 120, 120, 120, 120, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 160, 0, 4, 1, 200, 3, 108, 7, 248, 12, 41, 14, 32, 27, 0, 24, 25, 34, 24, 15, 19, 19, 7, 0, 120, 135, 180, 120, 120, 120, 120, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 58, 0, 3, 0, 5, 0, 116, 0, 208, 0, 104, 6, 40, 10, 232, 13, 24, 16, 124, 21, 58, 7, 12, 16, 8, 4, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 50, 85, 50, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 208, 0, 104, 6, 40, 10, 232, 13, 24, 16, 124, 21, 0, 7, 12, 16, 8, 4, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 50, 85, 50, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 208, 0, 104, 6, 40, 10, 232, 13, 24, 16, 124, 21, 0, 7, 12, 16, 8, 4, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 50, 85, 50, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 70, 0, 3, 0, 1, 0, 116, 0, 200, 0, 64, 6, 40, 10, 232, 13, 24, 16, 124, 21, 70, 3, 9, 9, 4, 2, 2, 2, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 50, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 200, 0, 64, 6, 40, 10, 232, 13, 24, 16, 124, 21, 0, 3, 9, 9, 4, 2, 2, 2, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 49, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 200, 0, 64, 6, 40, 10, 232, 13, 24, 16, 124, 21, 0, 3, 9, 9, 4, 2, 2, 2, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 48, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 34, 4, 15, 0, 254, 255, 255, 0, 2, 2, 0, 0, 1, 4, 3, 6, 5, 8, 4, 4, 5, 2, 1, 251, 255, 251, 250, 249, 249, 246, 247, 248, 252, 0, 1, 3, 8, 9, 12, 14, 16, 14, 18, 16, 16, 15, 239, 131, 222, 37, 254, 20, 239, 9, 11, 8, 8, 12, 0, 252, 1, 3, 2, 250, 5, 255, 6, 253, 254, 5, 253, 6, 3, 10, 253, 0, 253, 254, 4, 244, 243, 249, 255, 249, 250, 2, 248, 1, 8, 13, 8, 18, 16, 12, 22, 5, 6, 12, 3, 3, 233, 149, 189, 10, 14, 23, 254, 18, 33, 41, 2, 5, 2, 249, 7, 253, 255, 255, 254, 255, 241, 246, 245, 249, 0, 9, 15, 32, 32, 22, 177, 166, 39, 11, 35, 1, 0, 24, 10, 247, 240, 1, 231, 24, 251, 2, 9, 2, 21, 241, 247, 255, 12, 250, 232, 9, 8, 244, 22, 249, 252, 37, 242, 235, 229, 36, 248, 201, 64, 231, 246, 30, 0, 48, 0, 239, 20, 0, 242, 242, 247, 7, 215, 251, 34, 4, 217, 254, 31, 252, 14, 8, 224, 255, 24, 1, 3, 21, 10, 19, 2, 19, 35, 225, 139, 245, 38, 243, 249, 234, 10, 47, 227, 248, 27, 243, 21, 38, 46, 250, 224, 24, 255, 221, 4, 21, 219, 231, 241, 3, 25, 238, 242, 0, 3, 14, 8, 3, 1, 33, 10, 1, 18, 245, 240, 27, 230, 252, 15, 236, 245, 1, 7, 245, 0, 4, 229, 248, 3, 5, 23, 229, 4, 34, 13, 6, 38, 11, 230, 247, 0, 8, 252, 227, 205, 41, 38, 202, 245, 26, 236, 12, 247, 247, 15, 24, 251, 228, 36, 73, 217, 224, 32, 1, 234, 11, 251, 0, 226, 241, 254, 24, 7, 202, 29, 31, 254, 10, 11, 210, 253, 55, 232, 8, 23, 238, 249, 246, 29, 2, 228, 242, 255, 30, 233, 247, 35, 255, 28, 241, 242, 248, 249, 2, 254, 250, 20, 37, 230, 242, 245, 6, 27, 239, 9, 2, 18, 240, 238, 247, 16, 29, 240, 249, 9, 241, 250, 11, 12, 232, 21, 31, 224, 251, 14, 20, 232, 234, 8, 18, 13, 228, 246, 248, 30, 249, 3, 16, 37, 252, 215, 233, 244, 31, 18, 218, 34, 24, 228, 4, 251, 15, 7, 223, 2, 11, 237, 21, 0, 231, 3, 11, 24, 231, 226, 62, 20, 202, 17, 10, 252, 245, 1, 26, 0, 239, 0, 28, 232, 251, 0, 245, 0, 235, 214, 31, 16, 17, 36, 254, 2, 11, 220, 249, 1, 31, 15, 217, 2, 252, 13, 25, 243, 244, 22, 225, 238, 224, 7, 33, 247, 4, 19, 254, 17, 14, 239, 244, 1, 35, 239, 237, 29, 0, 0, 5, 241, 242, 11, 0, 7, 229, 6, 255, 215, 26, 17, 217, 25, 51, 248, 11, 240, 253, 10, 15, 17, 232, 222, 7, 7, 253, 8, 251, 241, 8, 10, 240, 33, 12, 204, 8, 9, 13, 239, 211, 27, 33, 254, 18, 6, 246, 238, 245, 29, 15, 244, 231, 253, 39, 30, 241, 245, 0, 212, 238, 22, 1, 241, 221, 1, 49, 38, 250, 246, 10, 20, 12, 0, 237, 1, 5, 230, 232, 18, 55, 221, 199, 27, 48, 253, 230, 206, 2, 31, 0, 5, 251, 13, 31, 2, 21, 3, 227, 19, 224, 245, 3, 5, 36, 222, 214, 60, 20, 210, 12, 242, 226, 18, 22, 242, 222, 38, 42, 0, 17, 14, 238, 239, 237, 7, 21, 217, 224, 33, 241, 247, 39, 250, 245, 10, 26, 7, 229, 14, 14, 215, 12, 33, 242, 243, 241, 0, 45, 12, 212, 237, 8, 250, 244, 5, 13, 8, 0, 28, 22, 252, 253, 239, 241, 14, 19, 253, 221, 233, 20, 21, 9, 10, 247, 222, 246, 11, 6, 255, 238, 248, 36, 23, 248, 12, 18, 10, 2, 249, 5, 235, 228, 247, 248, 5, 1, 255, 6, 253, 2, 251, 10, 2, 251, 8, 250, 11, 21, 1, 4, 13, 4, 253, 244, 250, 246, 238, 246, 245, 253, 14, 11, 9, 9, 8, 12, 250, 244, 3, 255, 249, 250, 241, 16, 27, 240, 1, 17, 15, 255, 224, 250, 1, 0, 3, 245, 254, 24, 26, 7, 245, 251, 3, 227, 233, 1, 11, 8, 250, 246, 3, 23, 27, 0, 255, 20, 253, 232, 252, 252, 251, 7, 7, 249, 253, 20, 254, 236, 10, 254, 243, 250, 244, 4, 17, 11, 8, 19, 21, 249, 239, 255, 254, 246, 248, 243, 2, 11, 2, 4, 0, 7, 16, 5, 252, 244, 242, 244, 248, 2, 24, 15, 252, 247, 5, 13, 2, 248, 251, 253, 248, 247, 6, 15, 11, 3, 254, 255, 12, 247, 230, 250, 9, 15, 7, 254, 249, 0, 14, 13, 254, 252, 248, 239, 244, 253, 5, 2, 3, 15, 16, 0, 0, 2, 252, 3, 11, 0, 243, 254, 255, 246, 1, 15, 4, 245, 248, 0, 255, 253, 249, 247, 11, 14, 6, 6, 0, 6, 10, 5, 1, 0, 243, 239, 245, 0, 15, 14, 255, 254, 3, 2, 250, 250, 254, 247, 247, 0, 255, 7, 13, 4, 4, 15, 6, 253, 254, 255, 255, 251, 252, 8, 255, 253, 7, 3, 2, 2, 248, 251, 252, 246, 244, 249, 9, 18, 7, 3, 3, 10, 11, 254, 246, 253, 3, 1, 0, 4, 5, 246, 254, 12, 7, 249, 241, 239, 245, 252, 8, 8, 4, 7, 13, 9, 6, 4, 251, 242, 254, 9, 2, 1, 253, 253, 4, 10, 3, 249, 251, 0, 247, 249, 251, 252, 4, 2, 11, 13, 5, 2, 252, 250, 0, 1, 0, 0, 1, 1, 8, 4, 0, 3, 253, 255, 254, 250, 253, 243, 245, 2, 1, 6, 11, 9, 4, 3, 3, 255, 0, 0, 0, 255, 254, 0, 5, 3, 254, 253, 255, 255, 249, 248, 252, 5, 6, 1, 0, 1, 8, 11, 3, 255, 254, 254, 0, 0, 251, 1, 3, 4, 0, 252, 1, 2, 0, 0, 250, 0, 0, 249, 252, 5, 8, 5, 3, 3, 7, 5, 0, 0, 252, 252, 255, 252, 251, 1, 9, 3, 0, 1, 2, 251, 249, 254, 255, 255, 3, 2, 253, 3, 10, 6, 3, 0, 255, 255, 0, 2, 255, 1, 0, 252, 0, 0, 2, 2, 0, 0, 24, 0, 3, 0, 5, 0, 136, 0, 200, 0, 64, 6, 40, 10, 232, 13, 24, 16, 124, 21, 25, 18, 15, 28, 12, 8, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 50, 85, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 136, 0, 200, 0, 64, 6, 40, 10, 232, 13, 24, 16, 124, 21, 0, 18, 15, 28, 16, 12, 8, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 50, 85, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 136, 0, 200, 0, 64, 6, 40, 10, 232, 13, 24, 16, 124, 21, 0, 18, 15, 28, 16, 12, 8, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 50, 85, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 21, 2, 14, 0, 0, 2, 6, 7, 11, 10, 10, 10, 7, 244, 199, 214, 83, 238, 9, 4, 240, 254, 255, 1, 3, 18, 253, 10, 1, 13, 20, 15, 252, 172, 182, 7, 30, 69, 32, 10, 239, 247, 243, 5, 15, 242, 4, 240, 250, 247, 3, 17, 4, 251, 248, 254, 11, 249, 10, 2, 12, 2, 0, 10, 250, 8, 235, 252, 252, 244, 2, 1, 246, 246, 6, 13, 21, 30, 24, 29, 30, 176, 194, 200, 246, 49, 27, 30, 28, 14, 236, 182, 29, 22, 228, 34, 239, 21, 35, 236, 10, 35, 230, 170, 190, 233, 43, 34, 48, 41, 253, 86, 225, 13, 233, 192, 214, 236, 236, 228, 39, 255, 33, 65, 21, 249, 14, 20, 32, 235, 150, 155, 7, 0, 119, 78, 204, 33, 219, 213, 249, 240, 225, 60, 47, 4, 244, 99, 232, 169, 227, 232, 246, 13, 244, 20, 38, 213, 41, 63, 10, 61, 190, 174, 28, 187, 29, 233, 31, 6, 12, 255, 18, 19, 33, 230, 184, 74, 211, 249, 48, 15, 206, 212, 82, 7, 222, 9, 213, 250, 247, 15, 76, 253, 18, 9, 168, 77, 222, 206, 54, 198, 23, 242, 2, 35, 248, 1, 13, 47, 220, 30, 241, 177, 103, 197, 202, 36, 252, 232, 73, 249, 23, 26, 183, 235, 70, 24, 165, 11, 234, 109, 169, 237, 62, 27, 184, 72, 235, 241, 223, 224, 49, 52, 237, 176, 115, 244, 18, 188, 243, 246, 35, 215, 20, 70, 229, 255, 177, 48, 22, 37, 22, 181, 227, 68, 244, 185, 63, 191, 53, 35, 4, 233, 202, 37, 28, 235, 33, 13, 230, 219, 243, 255, 17, 28, 58, 184, 233, 247, 37, 29, 2, 229, 236, 25, 38, 226, 248, 238, 202, 90, 244, 41, 197, 242, 226, 104, 250, 206, 37, 199, 55, 17, 181, 31, 42, 201, 15, 247, 21, 8, 218, 44, 247, 214, 11, 21, 53, 203, 26, 6, 197, 20, 247, 18, 55, 225, 168, 110, 198, 232, 45, 236, 20, 21, 236, 57, 237, 172, 91, 189, 3, 41, 190, 15, 52, 235, 6, 6, 253, 0, 221, 70, 14, 173, 24, 34, 204, 45, 203, 60, 250, 199, 12, 246, 101, 183, 239, 16, 46, 15, 12, 190, 33, 206, 220, 31, 42, 38, 180, 242, 38, 33, 233, 0, 244, 53, 0, 240, 7, 198, 250, 223, 17, 95, 252, 207, 255, 27, 13, 238, 0, 9, 236, 239, 255, 27, 1, 245, 8, 14, 41, 222, 212, 242, 61, 218, 223, 70, 249, 3, 11, 12, 245, 223, 241, 8, 38, 14, 198, 230, 67, 8, 238, 6, 15, 1, 225, 245, 1, 9, 254, 9, 12, 25, 249, 238, 228, 45, 251, 211, 4, 19, 249, 226, 40, 63, 229, 215, 54, 3, 200, 241, 1, 248, 15, 48, 197, 35, 35, 2, 236, 255, 27, 162, 228, 67, 246, 250, 39, 46, 32, 241, 213, 193, 254, 242, 25, 242, 249, 69, 10, 244, 47, 27, 196, 224, 12, 237, 188, 28, 54, 231, 17, 58, 10, 234, 237, 212, 24, 248, 248, 14, 249, 43, 1, 227, 7, 32, 248, 222, 16, 230, 197, 229, 50, 0, 0, 0, 221, 2, 23, 0, 255, 2, 250, 255, 251, 0, 253, 255, 253, 252, 1, 2, 2, 1, 253, 8, 5, 6, 7, 14, 13, 12, 17, 13, 16, 5, 164, 135, 240, 0, 35, 45, 3, 43, 36, 3, 19, 0, 247, 11, 247, 252, 12, 228, 242, 255, 240, 250, 251, 3, 3, 244, 8, 13, 1, 248, 3, 3, 2, 25, 11, 0, 16, 22, 6, 22, 212, 179, 243, 250, 37, 8, 255, 19, 4, 12, 254, 239, 7, 240, 219, 252, 239, 251, 42, 29, 42, 28, 15, 28, 249, 214, 226, 225, 240, 240, 240, 15, 9, 245, 23, 14, 4, 246, 238, 11, 21, 16, 5, 249, 251, 23, 6, 9, 5, 248, 241, 251, 246, 255, 227, 234, 255, 5, 20, 13, 0, 253, 252, 247, 42, 12, 247, 248, 6, 30, 30, 0, 3, 18, 191, 220, 208, 229, 20, 255, 12, 19, 5, 53, 25, 245, 19, 215, 7, 47, 251, 12, 213, 238, 248, 247, 4, 229, 37, 250, 228, 246, 12, 20, 37, 3, 230, 33, 231, 223, 243, 40, 76, 233, 219, 36, 242, 246, 242, 41, 16, 230, 220, 215, 0, 21, 251, 224, 251, 54, 217, 217, 22, 40, 26, 42, 59, 27, 220, 15, 72, 244, 207, 167, 168, 209, 3, 239, 12, 33, 63, 6, 218, 45, 55, 222, 243, 44, 11, 241, 23, 29, 247, 250, 16, 193, 238, 25, 218, 204, 251, 37, 16, 218, 24, 18, 213, 50, 43, 230, 3, 22, 230, 243, 4, 43, 25, 243, 18, 232, 222, 32, 6, 226, 228, 242, 229, 212, 57, 35, 249, 10, 37, 251, 244, 1, 18, 39, 232, 230, 218, 219, 34, 255, 23, 32, 43, 8, 228, 237, 15, 228, 235, 41, 192, 231, 251, 253, 36, 14, 27, 46, 229, 249, 239, 6, 47, 216, 246, 25, 244, 3, 4, 12, 11, 231, 242, 236, 229, 0, 250, 2, 45, 32, 3, 237, 242, 33, 30, 21, 241, 172, 232, 26, 15, 18, 0, 216, 3, 31, 10, 10, 10, 244, 249, 245, 5, 11, 247, 232, 9, 7, 4, 22, 5, 229, 241, 4, 11, 246, 17, 254, 222, 15, 54, 10, 1, 241, 210, 37, 26, 210, 249, 235, 249, 1, 40, 31, 219, 239, 11, 3, 41, 11, 254, 247, 205, 233, 54, 249, 4, 18, 201, 33, 16, 3, 6, 211, 20, 13, 220, 43, 19, 204, 7, 13, 5, 38, 199, 5, 6, 226, 23, 9, 16, 1, 245, 247, 246, 28, 25, 206, 2, 52, 238, 246, 248, 252, 22, 252, 236, 3, 5, 3, 0, 229, 19, 28, 244, 239, 236, 31, 7, 226, 17, 46, 245, 242, 0, 13, 25, 225, 243, 249, 7, 6, 223, 241, 4, 10, 12, 33, 10, 252, 210, 0, 56, 17, 1, 254, 245, 205, 241, 30, 32, 230, 246, 255, 245, 24, 251, 238, 4, 39, 37, 252, 224, 0, 236, 247, 10, 25, 14, 245, 228, 250, 7, 19, 238, 220, 29, 17, 10, 6, 237, 18, 6, 241, 17, 7, 243, 236, 236, 20, 23, 4, 249, 245, 28, 247, 216, 0, 0, 242, 23, 8, 15, 13, 243, 0, 7, 16, 4, 254, 6, 241, 237, 248, 254, 253, 13, 6, 3, 248, 4, 8, 238, 255, 7, 13, 2, 236, 253, 3, 2, 30, 7, 251, 9, 246, 6, 9, 229, 255, 241, 253, 26, 247, 239, 9, 6, 16, 248, 2, 24, 235, 236, 251, 251, 8, 9, 10, 40, 245, 246, 247, 239, 4, 12, 16, 239, 1, 27, 255, 253, 26, 231, 237, 241, 243, 245, 250, 245, 15, 0, 12, 21, 14, 44, 19, 250, 24, 221, 206, 4, 224, 0, 36, 18, 12, 240, 245, 25, 237, 236, 223, 253, 11, 0, 250, 1, 44, 54, 18, 248, 245, 237, 242, 241, 253, 7, 246, 254, 0, 10, 23, 7, 247, 15, 2, 237, 237, 238, 231, 245, 3, 21, 37, 15, 7, 13, 18, 4, 247, 234, 242, 253, 245, 250, 12, 9, 3, 254, 22, 13, 245, 229, 233, 250, 3, 251, 1, 6, 4, 19, 22, 14, 15, 16, 243, 236, 253, 3, 247, 236, 238, 251, 11, 19, 6, 247, 247, 249, 5, 16, 5, 2, 242, 251, 21, 4, 10, 19, 4, 239, 249, 4, 0, 248, 245, 240, 234, 6, 11, 5, 14, 12, 0, 1, 3, 9, 5, 3, 245, 248, 6, 2, 0, 0, 0, 58, 0, 3, 0, 5, 0, 116, 0, 240, 0, 8, 7, 4, 11, 224, 11, 210, 15, 96, 27, 58, 11, 22, 13, 9, 4, 4, 4, 0, 0, 200, 212, 150, 250, 250, 250, 200, 212, 150, 44, 30, 40, 135, 50, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 240, 0, 8, 7, 4, 11, 224, 11, 210, 15, 96, 27, 0, 11, 22, 13, 9, 4, 4, 4, 0, 0, 200, 212, 150, 250, 250, 250, 200, 212, 150, 44, 30, 40, 135, 50, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 240, 0, 8, 7, 4, 11, 224, 11, 210, 15, 96, 27, 0, 11, 22, 13, 9, 4, 4, 4, 0, 0, 200, 212, 150, 250, 250, 250, 200, 212, 150, 44, 30, 40, 135, 50, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 125, 0, 3, 0, 5, 0, 116, 0, 4, 1, 8, 7, 4, 11, 224, 11, 210, 15, 96, 27, 125, 3, 12, 7, 4, 2, 2, 2, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 40, 135, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 4, 1, 8, 7, 4, 11, 224, 11, 210, 15, 96, 27, 0, 3, 12, 7, 4, 2, 2, 2, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 40, 135, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 4, 1, 8, 7, 4, 11, 224, 11, 210, 15, 96, 27, 0, 3, 12, 7, 4, 2, 2, 2, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 40, 135, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 52, 10, 25, 0, 0, 251, 249, 253, 3, 7, 7, 4, 255, 1, 6, 9, 9, 12, 246, 222, 236, 253, 8, 13, 3, 250, 246, 255, 11, 19, 16, 5, 249, 242, 250, 5, 6, 12, 1, 240, 240, 254, 5, 14, 7, 253, 250, 254, 249, 7, 15, 253, 252, 253, 253, 8, 9, 0, 253, 252, 247, 9, 8, 4, 6, 249, 246, 255, 0, 1, 2, 4, 2, 0, 1, 253, 253, 252, 0, 10, 5, 2, 4, 253, 244, 2, 3, 3, 11, 252, 250, 253, 252, 3, 3, 10, 3, 251, 252, 253, 253, 11, 13, 251, 248, 254, 249, 3, 16, 2, 251, 255, 249, 246, 11, 18, 6, 2, 238, 250, 1, 1, 18, 13, 236, 233, 0, 10, 14, 15, 254, 240, 245, 0, 16, 0, 7, 4, 248, 247, 4, 11, 6, 244, 244, 4, 4, 18, 251, 250, 4, 245, 4, 8, 5, 12, 236, 245, 9, 11, 9, 247, 250, 233, 255, 24, 11, 6, 237, 243, 254, 18, 27, 9, 243, 238, 251, 242, 16, 30, 1, 255, 207, 230, 46, 244, 12, 30, 235, 239, 9, 9, 1, 7, 255, 235, 10, 5, 16, 21, 242, 6, 232, 227, 21, 29, 233, 210, 13, 16, 10, 31, 241, 244, 4, 232, 16, 51, 21, 247, 226, 232, 243, 6, 12, 16, 250, 215, 253, 5, 26, 15, 14, 1, 235, 4, 12, 21, 255, 242, 244, 222, 240, 35, 34, 242, 248, 248, 237, 255, 29, 40, 249, 240, 246, 239, 11, 22, 17, 8, 243, 214, 226, 10, 27, 21, 13, 251, 239, 242, 3, 11, 9, 255, 0, 5, 3, 245, 255, 6, 249, 2, 5, 2, 11, 239, 244, 8, 5, 1, 4, 255, 8, 2, 237, 7, 6, 245, 1, 10, 6, 250, 3, 1, 238, 251, 4, 9, 17, 20, 0, 234, 239, 249, 1, 16, 14, 6, 254, 237, 250, 252, 13, 22, 255, 243, 247, 252, 6, 9, 253, 0, 252, 252, 20, 18, 253, 248, 243, 244, 251, 8, 20, 11, 249, 244, 246, 242, 15, 24, 4, 253, 239, 246, 8, 12, 4, 0, 2, 0, 253, 251, 0, 6, 1, 245, 254, 15, 1, 254, 0, 7, 0, 237, 4, 14, 254, 253, 0, 1, 5, 254, 251, 11, 1, 255, 254, 5, 7, 248, 254, 3, 247, 253, 18, 5, 1, 3, 239, 227, 6, 38, 0, 0, 0, 238, 254, 7, 22, 2, 1, 238, 246, 1, 5, 7, 14, 8, 242, 250, 243, 8, 1, 255, 10, 2, 0, 251, 249, 253, 7, 15, 8, 242, 254, 8, 254, 247, 3, 10, 7, 240, 244, 5, 9, 11, 8, 1, 220, 253, 12, 15, 14, 234, 16, 0, 222, 15, 27, 238, 247, 10, 22, 245, 234, 21, 14, 232, 2, 10, 254, 253, 1, 254, 246, 2, 9, 250, 19, 12, 231, 0, 255, 247, 24, 254, 252, 21, 243, 238, 8, 14, 239, 2, 1, 8, 21, 227, 7, 20, 218, 250, 38, 232, 255, 45, 255, 218, 241, 23, 247, 34, 48, 191, 209, 14, 39, 3, 8, 7, 245, 1, 233, 236, 247, 49, 35, 242, 18, 211, 192, 29, 45, 18, 246, 255, 247, 0, 250, 240, 19, 18, 249, 8, 252, 221, 43, 14, 237, 231, 228, 51, 32, 222, 7, 1, 230, 251, 244, 29, 51, 240, 0, 220, 216, 36, 19, 10, 20, 222, 247, 11, 249, 5, 19, 238, 2, 8, 233, 12, 14, 4, 1, 252, 235, 239, 28, 12, 246, 19, 241, 230, 15, 29, 9, 0, 240, 227, 248, 4, 12, 40, 30, 236, 199, 234, 16, 19, 39, 1, 243, 240, 252, 3, 246, 27, 4, 223, 245, 21, 34, 0, 234, 237, 248, 14, 16, 24, 252, 248, 6, 233, 244, 253, 10, 35, 0, 239, 244, 0, 254, 241, 12, 34, 252, 238, 15, 255, 248, 1, 0, 7, 254, 2, 6, 4, 249, 240, 246, 10, 10, 5, 15, 246, 238, 6, 0, 1, 4, 4, 9, 12, 232, 238, 10, 17, 17, 249, 243, 0, 241, 252, 21, 5, 18, 251, 241, 255, 245, 6, 20, 231, 8, 47, 252, 206, 248, 24, 242, 8, 38, 243, 244, 11, 239, 236, 254, 13, 36, 4, 254, 18, 238, 191, 240, 64, 47, 233, 238, 252, 2, 244, 5, 0, 252, 14, 13, 254, 3, 249, 237, 11, 19, 255, 233, 13, 16, 4, 248, 221, 242, 46, 17, 218, 30, 28, 223, 236, 253, 241, 40, 19, 240, 12, 15, 209, 202, 34, 39, 47, 250, 188, 17, 7, 208, 34, 51, 241, 239, 16, 217, 3, 41, 232, 228, 2, 28, 31, 16, 223, 229, 13, 204, 221, 124, 71, 215, 204, 226, 221, 4, 51, 34, 4, 6, 0, 175, 251, 50, 4, 24, 231, 232, 23, 244, 234, 48, 20, 222, 252, 9, 251, 25, 1, 218, 248, 25, 227, 0, 77, 47, 193, 184, 252, 7, 7, 54, 59, 218, 195, 235, 12, 27, 25, 20, 232, 246, 242, 233, 27, 49, 245, 230, 226, 14, 29, 18, 252, 247, 231, 209, 15, 39, 17, 56, 243, 173, 245, 1, 28, 50, 20, 243, 221, 210, 238, 38, 38, 37, 240, 195, 0, 25, 249, 252, 54, 14, 158, 248, 47, 21, 25, 247, 207, 216, 48, 47, 0, 14, 234, 192, 214, 47, 78, 25, 253, 214, 176, 234, 65, 53, 37, 246, 212, 182, 237, 50, 50, 13, 0, 244, 232, 238, 7, 20, 21, 12, 214, 227, 44, 39, 230, 226, 250, 1, 247, 24, 63, 243, 200, 223, 15, 37, 20, 246, 235, 3, 22, 0, 223, 10, 29, 254, 247, 237, 5, 9, 2, 8, 2, 235, 250, 9, 11, 0, 254, 13, 254, 230, 2, 19, 2, 246, 2, 27, 6, 233, 240, 249, 6, 30, 255, 239, 21, 246, 233, 248, 32, 34, 231, 234, 251, 0, 10, 17, 3, 244, 254, 2, 250, 15, 17, 224, 231, 17, 31, 249, 247, 23, 239, 245, 0, 16, 33, 248, 227, 216, 0, 13, 42, 50, 245, 205, 208, 2, 40, 30, 252, 248, 253, 3, 238, 0, 22, 37, 249, 220, 222, 2, 30, 255, 24, 222, 239, 39, 2, 44, 25, 185, 197, 3, 253, 27, 56, 72, 254, 188, 200, 223, 16, 42, 19, 245, 248, 30, 52, 243, 192, 200, 219, 70, 81, 17, 249, 239, 182, 217, 21, 73, 29, 255, 10, 196, 225, 3, 29, 8, 229, 48, 17, 208, 43, 35, 175, 222, 0, 246, 69, 75, 7, 186, 209, 10, 3, 240, 40, 254, 245, 57, 226, 201, 42, 0, 225, 39, 32, 202, 18, 42, 225, 206, 246, 54, 0, 32, 20, 239, 195, 191, 35, 48, 20, 36, 250, 244, 11, 231, 194, 203, 51, 103, 36, 235, 235, 233, 183, 247, 36, 14, 37, 35, 217, 5, 0, 173, 26, 47, 250, 45, 0, 225, 15, 235, 207, 236, 9, 58, 72, 12, 236, 184, 199, 239, 56, 54, 40, 222, 204, 43, 222, 251, 61, 216, 204, 34, 50, 13, 232, 14, 228, 202, 255, 53, 38, 14, 235, 241, 249, 212, 10, 17, 33, 3, 236, 9, 29, 242, 188, 238, 31, 26, 39, 33, 217, 253, 25, 187, 223, 36, 10, 233, 49, 57, 254, 213, 198, 248, 253, 16, 60, 49, 223, 185, 250, 43, 250, 250, 21, 254, 253, 232, 26, 29, 233, 225, 7, 7, 1, 27, 4, 249, 241, 237, 13, 229, 228, 68, 25, 230, 23, 34, 251, 213, 221, 231, 235, 23, 73, 44, 232, 9, 243, 195, 190, 18, 78, 38, 5, 243, 253, 185, 3, 16, 237, 50, 26, 4, 29, 235, 209, 212, 225, 22, 67, 28, 254, 32, 247, 192, 207, 252, 11, 57, 76, 235, 187, 232, 9, 17, 4, 16, 26, 232, 244, 21, 0, 223, 219, 21, 34, 30, 36, 241, 216, 232, 215, 7, 68, 8, 253, 253, 222, 237, 30, 45, 237, 225, 30, 255, 230, 255, 12, 4, 22, 243, 234, 24, 6, 2, 2, 229, 243, 43, 239, 251, 39, 242, 209, 32, 248, 222, 52, 6, 239, 14, 11, 221, 238, 39, 30, 215, 14, 75, 164, 198, 47, 2, 27, 40, 255, 233, 230, 224, 229, 43, 48, 245, 30, 10, 221, 219, 214, 49, 24, 250, 58, 2, 183, 12, 16, 209, 36, 255, 211, 44, 34, 251, 252, 216, 1, 28, 2, 14, 244, 226, 254, 255, 253, 24, 45, 25, 239, 222, 196, 6, 51, 14, 215, 15, 33, 191, 242, 76, 35, 237, 228, 243, 247, 233, 10, 51, 251, 215, 230, 38, 83, 2, 237, 232, 152, 224, 81, 34, 18, 32, 240, 218, 241, 15, 16, 18, 238, 238, 212, 247, 71, 34, 246, 244, 12, 215, 215, 0, 58, 255, 241, 10, 7, 24, 11, 251, 252, 219, 197, 22, 46, 36, 12, 210, 245, 38, 231, 208, 24, 60, 4, 203, 216, 6, 47, 27, 5, 31, 213, 192, 37, 29, 2, 13, 244, 190, 249, 36, 50, 20, 223, 226, 3, 5, 232, 10, 45, 227, 248, 14, 28, 24, 249, 182, 199, 36, 70, 29, 36, 247, 152, 190, 34, 83, 32, 239, 0, 255, 198, 210, 57, 24, 241, 23, 17, 0, 7, 18, 182, 190, 15, 35, 85, 42, 234, 233, 221, 172, 7, 53, 27, 11, 37, 18, 193, 204, 18, 3, 226, 52, 35, 238, 17, 20, 208, 218, 247, 14, 62, 24, 253, 238, 220, 238, 220, 27, 65, 6, 255, 5, 237, 217, 236, 17, 25, 4, 9, 31, 11, 222, 201, 239, 28, 14, 34, 55, 241, 190, 247, 0, 213, 27, 69, 250, 252, 11, 244, 241, 255, 222, 217, 33, 55, 34, 16, 222, 225, 224, 245, 30, 38, 5, 0, 11, 236, 221, 251, 12, 253, 7, 31, 250, 1, 9, 246, 252, 239, 225, 10, 57, 6, 242, 4, 226, 239, 29, 6, 34, 26, 209, 226, 219, 22, 37, 2, 20, 9, 234, 232, 235, 32, 9, 218, 8, 34, 16, 6, 246, 229, 255, 254, 5, 3, 12, 37, 233, 197, 1, 44, 1, 248, 16, 252, 234, 6, 37, 234, 233, 16, 0, 249, 8, 8, 250, 8, 1, 243, 15, 7, 1, 9, 225, 255, 3, 222, 255, 46, 16, 0, 26, 247, 213, 231, 16, 27, 2, 231, 250, 13, 17, 1, 13, 245, 4, 0, 207, 5, 43, 250, 4, 28, 235, 214, 254, 31, 8, 241, 250, 31, 7, 224, 16, 22, 223, 218, 40, 25, 229, 20, 17, 233, 253, 247, 232, 18, 29, 253, 250, 248, 255, 24, 11, 5, 221, 200, 1, 57, 24, 20, 14, 227, 225, 225, 8, 14, 248, 11, 15, 40, 4, 242, 252, 241, 208, 217, 14, 107, 55, 174, 1, 20, 200, 212, 40, 34, 254, 32, 25, 214, 215, 25, 0, 231, 25, 11, 251, 16, 14, 244, 228, 243, 246, 14, 34, 4, 254, 239, 249, 14, 4, 31, 0, 211, 2, 14, 1, 255, 222, 253, 43, 13, 251, 231, 249, 21, 8, 252, 4, 1, 1, 236, 242, 28, 238, 250, 29, 17, 0, 6, 17, 239, 191, 242, 14, 21, 44, 252, 238, 1, 243, 7, 6, 247, 255, 10, 2, 13, 18, 235, 227, 15, 9, 0, 4, 13, 237, 227, 23, 6, 229, 3, 23, 14, 26, 8, 227, 227, 236, 13, 25, 10, 9, 17, 224, 215, 255, 13, 31, 253, 8, 34, 240, 236, 242, 241, 6, 14, 2, 21, 20, 244, 222, 224, 12, 24, 2, 24, 35, 209, 227, 3, 3, 13, 8, 30, 14, 241, 224, 252, 3, 246, 0, 0, 2, 24, 7, 250, 5, 6, 243, 245, 254, 4, 1, 4, 250, 1, 3, 9, 32, 11, 226, 217, 3, 19, 250, 254, 4, 26, 9, 217, 0, 26, 1, 241, 250, 248, 253, 20, 13, 12, 3, 246, 230, 4, 32, 7, 239, 236, 244, 250, 15, 20, 11, 11, 253, 229, 243, 2, 5, 252, 16, 13, 251, 247, 251, 22, 39, 237, 208, 234, 246, 50, 36, 3, 240, 251, 230, 247, 18, 6, 10, 250, 220, 247, 18, 38, 19, 243, 251, 247, 224, 249, 38, 8, 254, 15, 0, 245, 12, 10, 233, 228, 225, 234, 56, 78, 7, 247, 198, 192, 9, 56, 21, 5, 40, 237, 176, 240, 49, 42, 232, 231, 31, 33, 248, 241, 248, 201, 218, 29, 31, 61, 43, 245, 214, 210, 207, 235, 43, 65, 12, 15, 19, 237, 217, 239, 252, 242, 23, 34, 3, 239, 247, 255, 11, 6, 221, 245, 40, 26, 250, 23, 230, 198, 249, 34, 24, 17, 11, 230, 229, 0, 16, 16, 23, 239, 208, 253, 20, 24, 16, 17, 248, 206, 241, 3, 15, 43, 4, 245, 223, 6, 37, 232, 235, 248, 4, 7, 34, 23, 9, 227, 225, 240, 250, 13, 32, 27, 7, 225, 222, 255, 18, 20, 13, 244, 245, 244, 253, 9, 15, 253, 249, 251, 6, 26, 24, 224, 209, 5, 10, 21, 32, 21, 3, 208, 211, 17, 15, 240, 1, 33, 4, 231, 5, 22, 250, 236, 8, 11, 254, 39, 243, 220, 238, 252, 20, 3, 40, 22, 219, 237, 245, 229, 10, 48, 13, 0, 34, 231, 191, 235, 20, 5, 20, 50, 17, 231, 235, 252, 227, 6, 24, 235, 2, 27, 7, 241, 247, 21, 4, 227, 249, 38, 20, 227, 223, 251, 10, 24, 13, 243, 3, 9, 243, 253, 16, 9, 252, 240, 242, 251, 255, 11, 29, 21, 249, 234, 244, 251, 0, 6, 8, 6, 0, 0, 8, 2, 249, 253, 234, 218, 17, 49, 33, 17, 238, 222, 233, 252, 14, 8, 7, 1, 238, 246, 23, 14, 12, 7, 224, 232, 15, 25, 8, 244, 240, 247, 252, 21, 38, 16, 231, 225, 251, 254, 249, 11, 15, 14, 3, 233, 4, 24, 255, 243, 0, 246, 238, 253, 20, 37, 248, 235, 12, 18, 242, 249, 1, 238, 247, 254, 14, 33, 28, 236, 230, 0, 251, 245, 251, 27, 22, 236, 240, 15, 12, 249, 3, 3, 246, 3, 3, 1, 255, 248, 245, 255, 17, 8, 6, 11, 250, 239, 249, 238, 242, 28, 28, 5, 12, 15, 247, 231, 221, 250, 20, 0, 9, 16, 15, 255, 231, 243, 28, 6, 226, 0, 0, 0, 25, 6, 241, 12, 3, 249, 4, 0, 252, 4, 254, 231, 243, 18, 35, 2, 254, 251, 238, 254, 9, 248, 252, 12, 2, 1, 13, 13, 6, 249, 216, 250, 19, 1, 1, 0, 5, 0, 245, 18, 35, 249, 220, 224, 255, 27, 16, 249, 254, 22, 9, 248, 233, 6, 21, 248, 232, 253, 16, 16, 5, 243, 238, 4, 21, 251, 234, 23, 17, 230, 253, 22, 251, 250, 4, 2, 9, 242, 233, 3, 24, 15, 6, 243, 249, 17, 3, 239, 238, 243, 253, 6, 21, 30, 18, 253, 242, 233, 244, 255, 247, 5, 27, 0, 0, 9, 0, 248, 245, 1, 5, 0, 2, 5, 4, 5, 253, 240, 252, 10, 10, 0, 0, 0, 255, 243, 241, 3, 16, 17, 20, 9, 241, 237, 239, 232, 1, 23, 14, 21, 22, 9, 229, 219, 235, 249, 12, 23, 25, 20, 1, 248, 231, 227, 0, 21, 3, 250, 10, 27, 254, 238, 254, 253, 247, 5, 21, 14, 245, 227, 245, 9, 12, 9, 9, 5, 0, 251, 254, 251, 235, 242, 13, 18, 22, 18, 1, 234, 237, 252, 248, 0, 7, 8, 14, 7, 255, 0, 2, 243, 244, 254, 4, 7, 3, 2, 4, 7, 2, 0, 251, 245, 254, 0, 253, 1, 9, 12, 3, 254, 254, 252, 249, 1, 9, 255, 246, 251, 8, 13, 40, 0, 3, 0, 5, 0, 120, 0, 8, 1, 8, 7, 4, 11, 224, 11, 210, 15, 96, 27, 40, 12, 20, 17, 8, 4, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 40, 135, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 120, 0, 8, 1, 8, 7, 4, 11, 224, 11, 210, 15, 96, 27, 0, 10, 19, 16, 7, 3, 3, 3, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 40, 135, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 120, 0, 8, 1, 8, 7, 4, 11, 224, 11, 210, 15, 96, 27, 0, 10, 19, 16, 7, 3, 3, 3, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 40, 135, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 6, 4, 35, 0, 3, 255, 254, 0, 251, 245, 255, 15, 20, 0, 235, 247, 0, 6, 7, 6, 251, 243, 21, 6, 240, 255, 2, 4, 0, 9, 251, 244, 4, 255, 0, 1, 15, 7, 245, 245, 254, 9, 2, 3, 1, 243, 10, 10, 253, 254, 0, 248, 244, 8, 19, 6, 250, 243, 0, 8, 2, 5, 254, 2, 2, 249, 251, 4, 6, 251, 254, 4, 10, 6, 230, 247, 19, 1, 3, 14, 9, 240, 239, 0, 10, 13, 1, 248, 249, 253, 6, 254, 6, 3, 243, 9, 12, 5, 247, 251, 2, 2, 251, 1, 10, 5, 248, 250, 0, 251, 14, 5, 9, 255, 239, 243, 6, 25, 245, 245, 13, 6, 246, 252, 25, 13, 226, 216, 35, 50, 231, 204, 23, 40, 240, 223, 7, 38, 7, 230, 231, 14, 13, 244, 23, 13, 239, 245, 253, 3, 8, 3, 5, 1, 236, 251, 8, 6, 10, 2, 250, 248, 252, 255, 25, 10, 247, 230, 241, 36, 38, 234, 206, 12, 28, 243, 253, 15, 253, 23, 3, 211, 249, 19, 9, 0, 0, 12, 239, 245, 26, 23, 234, 219, 254, 30, 22, 14, 240, 226, 252, 0, 0, 30, 20, 249, 233, 232, 251, 29, 25, 0, 249, 236, 254, 26, 11, 215, 234, 32, 19, 252, 10, 0, 236, 242, 1, 14, 7, 3, 10, 249, 241, 251, 18, 27, 238, 216, 254, 29, 34, 12, 207, 232, 22, 248, 15, 44, 244, 201, 255, 41, 248, 7, 15, 232, 238, 13, 47, 3, 197, 212, 13, 52, 36, 246, 219, 1, 43, 241, 198, 248, 45, 49, 244, 219, 245, 17, 27, 230, 200, 6, 100, 29, 185, 224, 19, 0, 219, 39, 59, 217, 207, 46, 37, 193, 232, 54, 3, 230, 15, 16, 253, 7, 231, 222, 253, 42, 44, 5, 239, 216, 208, 17, 60, 11, 5, 0, 232, 218, 244, 40, 30, 4, 6, 214, 232, 14, 13, 14, 253, 8, 11, 233, 251, 11, 253, 250, 251, 19, 0, 227, 36, 50, 183, 202, 50, 34, 21, 243, 245, 228, 251, 2, 21, 7, 1, 248, 7, 6, 236, 246, 28, 30, 220, 232, 15, 19, 3, 232, 252, 13, 44, 255, 213, 233, 2, 7, 19, 26, 23, 1, 196, 173, 46, 95, 22, 248, 204, 174, 23, 89, 20, 212, 238, 246, 17, 243, 11, 55, 249, 201, 211, 14, 48, 75, 6, 176, 192, 11, 45, 4, 44, 26, 200, 230, 250, 224, 19, 68, 26, 225, 246, 223, 224, 17, 45, 55, 241, 164, 11, 80, 9, 208, 226, 234, 26, 42, 3, 1, 231, 13, 5, 193, 224, 110, 87, 184, 207, 226, 231, 68, 68, 245, 178, 231, 21, 9, 16, 43, 2, 196, 243, 34, 10, 240, 22, 19, 192, 217, 48, 107, 226, 173, 31, 252, 223, 30, 10, 12, 22, 245, 202, 231, 55, 83, 249, 151, 199, 59, 79, 4, 201, 8, 44, 227, 189, 20, 22, 27, 69, 193, 170, 42, 58, 198, 252, 116, 248, 131, 233, 89, 34, 177, 239, 100, 42, 169, 174, 24, 67, 28, 5, 202, 237, 17, 15, 44, 222, 228, 29, 237, 250, 6, 7, 30, 4, 210, 245, 26, 20, 252, 251, 2, 237, 21, 255, 239, 24, 6, 221, 238, 3, 15, 47, 44, 228, 177, 235, 41, 35, 234, 239, 51, 25, 211, 218, 240, 2, 32, 80, 7, 188, 205, 219, 62, 62, 0, 246, 233, 255, 228, 217, 34, 108, 250, 165, 12, 34, 214, 220, 27, 52, 15, 232, 243, 0, 17, 4, 208, 208, 53, 82, 236, 248, 28, 214, 173, 244, 46, 109, 12, 179, 250, 245, 217, 20, 48, 3, 14, 252, 248, 251, 217, 230, 29, 49, 8, 244, 55, 227, 174, 225, 8, 51, 53, 28, 249, 205, 216, 246, 9, 25, 40, 11, 233, 15, 223, 233, 20, 1, 239, 37, 4, 251, 46, 204, 182, 28, 54, 0, 253, 14, 23, 253, 190, 210, 70, 32, 229, 37, 232, 194, 49, 31, 234, 5, 245, 228, 6, 30, 33, 231, 225, 24, 3, 249, 240, 20, 49, 198, 213, 50, 28, 242, 2, 233, 253, 1, 9, 35, 228, 246, 6, 245, 10, 67, 232, 183, 31, 11, 222, 0, 32, 26, 3, 232, 236, 30, 251, 237, 17, 227, 235, 39, 78, 253, 199, 188, 7, 43, 20, 6, 2, 27, 234, 192, 19, 13, 247, 24, 47, 18, 195, 190, 46, 38, 212, 0, 67, 230, 230, 8, 255, 28, 2, 207, 206, 45, 87, 24, 201, 195, 26, 247, 233, 45, 37, 16, 236, 179, 241, 52, 33, 26, 250, 183, 230, 45, 41, 23, 239, 206, 235, 45, 0, 252, 22, 3, 227, 0, 8, 236, 0, 34, 41, 255, 214, 196, 243, 49, 55, 5, 253, 247, 219, 224, 4, 30, 19, 253, 46, 248, 206, 5, 231, 236, 45, 33, 11, 249, 241, 3, 3, 189, 215, 64, 64, 36, 238, 233, 239, 178, 215, 123, 79, 198, 239, 9, 225, 208, 250, 49, 70, 4, 223, 250, 217, 228, 35, 12, 24, 13, 247, 252, 253, 0, 226, 226, 20, 27, 253, 28, 42, 16, 190, 157, 239, 42, 91, 38, 252, 15, 204, 181, 212, 41, 84, 12, 204, 19, 41, 0, 221, 205, 236, 21, 31, 23, 45, 31, 206, 192, 222, 253, 22, 66, 37, 234, 13, 209, 220, 9, 2, 24, 0, 7, 36, 12, 236, 215, 217, 231, 35, 73, 27, 214, 0, 14, 227, 242, 238, 31, 3, 251, 45, 6, 197, 239, 40, 250, 220, 17, 46, 30, 231, 207, 9, 3, 224, 28, 43, 27, 0, 191, 218, 237, 10, 92, 50, 187, 237, 51, 215, 187, 254, 68, 64, 3, 220, 232, 237, 209, 21, 23, 55, 50, 209, 229, 19, 203, 187, 32, 101, 37, 237, 226, 239, 213, 230, 49, 16, 43, 42, 203, 214, 242, 223, 38, 54, 25, 237, 212, 255, 3, 252, 254, 40, 35, 233, 190, 234, 65, 25, 238, 251, 1, 251, 16, 15, 210, 206, 28, 45, 45, 32, 212, 175, 213, 54, 63, 235, 248, 33, 18, 233, 208, 0, 16, 224, 16, 52, 0, 252, 0, 0, 91, 4, 39, 0, 249, 19, 23, 0, 1, 249, 239, 2, 9, 4, 7, 250, 255, 2, 245, 252, 14, 6, 8, 0, 240, 244, 5, 5, 5, 6, 8, 248, 247, 2, 11, 241, 250, 18, 7, 6, 249, 239, 249, 23, 12, 242, 1, 254, 249, 4, 23, 248, 221, 28, 21, 240, 250, 2, 254, 245, 10, 12, 3, 5, 254, 228, 249, 32, 3, 251, 254, 244, 13, 13, 234, 5, 12, 248, 246, 0, 18, 18, 243, 229, 244, 35, 27, 231, 232, 3, 20, 10, 237, 3, 14, 242, 244, 7, 24, 1, 248, 247, 240, 18, 8, 248, 11, 8, 246, 240, 8, 247, 8, 28, 247, 246, 1, 251, 251, 5, 15, 254, 251, 0, 0, 2, 242, 10, 30, 232, 232, 17, 20, 3, 234, 246, 15, 8, 1, 248, 251, 15, 5, 236, 2, 17, 254, 229, 13, 24, 252, 254, 246, 250, 255, 15, 8, 245, 255, 5, 5, 245, 0, 11, 255, 249, 5, 10, 244, 243, 17, 17, 248, 245, 13, 253, 234, 3, 24, 11, 250, 242, 249, 12, 9, 238, 254, 16, 18, 246, 232, 6, 14, 243, 11, 14, 251, 242, 252, 0, 2, 30, 254, 235, 242, 4, 19, 3, 9, 246, 244, 4, 255, 5, 3, 7, 248, 3, 6, 240, 248, 18, 19, 247, 231, 0, 17, 13, 255, 240, 1, 3, 252, 248, 38, 247, 215, 13, 36, 9, 225, 237, 8, 12, 12, 9, 250, 239, 248, 12, 8, 252, 255, 6, 12, 0, 233, 240, 22, 20, 254, 245, 241, 27, 8, 232, 246, 16, 3, 245, 11, 15, 254, 243, 1, 250, 2, 0, 12, 253, 248, 7, 21, 254, 228, 247, 6, 13, 16, 255, 8, 228, 224, 40, 28, 236, 246, 0, 242, 28, 29, 203, 226, 53, 43, 231, 213, 3, 5, 14, 29, 254, 209, 252, 55, 237, 236, 32, 243, 246, 19, 226, 251, 61, 0, 193, 254, 65, 248, 215, 0, 18, 253, 14, 30, 203, 230, 60, 13, 203, 9, 24, 242, 13, 7, 218, 2, 47, 0, 229, 240, 249, 28, 43, 235, 200, 17, 37, 241, 252, 18, 251, 236, 255, 9, 8, 9, 254, 247, 248, 8, 14, 247, 248, 2, 18, 249, 232, 13, 47, 248, 201, 245, 32, 29, 254, 238, 244, 15, 25, 219, 233, 51, 14, 219, 250, 16, 14, 249, 243, 3, 253, 11, 12, 241, 4, 1, 243, 1, 17, 1, 254, 2, 250, 241, 2, 23, 16, 241, 225, 0, 35, 24, 232, 230, 249, 7, 24, 24, 247, 229, 2, 255, 241, 24, 16, 238, 255, 27, 245, 244, 2, 237, 252, 29, 21, 250, 0, 239, 224, 19, 31, 3, 242, 237, 1, 21, 12, 248, 245, 0, 0, 246, 3, 19, 11, 243, 249, 0, 244, 25, 22, 232, 216, 12, 58, 7, 206, 234, 36, 12, 245, 2, 4, 245, 250, 0, 6, 28, 0, 216, 252, 47, 240, 241, 249, 0, 36, 12, 232, 252, 242, 247, 8, 27, 21, 243, 253, 215, 253, 46, 16, 230, 229, 29, 1, 237, 23, 26, 241, 222, 234, 18, 27, 4, 17, 24, 198, 203, 50, 21, 243, 25, 244, 232, 34, 1, 219, 248, 40, 0, 249, 3, 236, 12, 17, 230, 14, 4, 254, 17, 226, 251, 6, 3, 21, 252, 253, 15, 10, 203, 221, 54, 39, 244, 232, 8, 21, 245, 216, 251, 64, 248, 214, 17, 38, 2, 219, 226, 15, 43, 239, 244, 32, 244, 237, 9, 248, 8, 16, 3, 245, 216, 29, 50, 228, 235, 0, 253, 14, 33, 222, 220, 26, 47, 6, 218, 232, 219, 52, 83, 206, 193, 33, 44, 214, 223, 31, 33, 0, 236, 243, 254, 24, 10, 221, 245, 48, 7, 236, 246, 247, 2, 14, 25, 249, 218, 246, 34, 20, 247, 3, 239, 224, 8, 36, 19, 239, 242, 11, 245, 248, 13, 4, 254, 250, 8, 11, 7, 249, 227, 254, 26, 7, 251, 4, 251, 235, 15, 22, 253, 254, 243, 237, 3, 26, 23, 254, 242, 236, 233, 23, 51, 250, 216, 245, 4, 17, 14, 5, 252, 233, 2, 26, 243, 206, 6, 52, 50, 15, 184, 192, 233, 56, 102, 253, 206, 196, 7, 62, 223, 218, 83, 52, 204, 155, 232, 84, 63, 249, 238, 236, 237, 3, 239, 248, 36, 27, 2, 12, 17, 203, 150, 2, 124, 79, 232, 189, 205, 239, 19, 74, 47, 195, 223, 12, 233, 9, 52, 0, 227, 246, 9, 23, 12, 234, 180, 0, 89, 69, 6, 149, 184, 20, 52, 64, 0, 233, 224, 240, 3, 17, 7, 253, 15, 4, 245, 5, 238, 227, 12, 51, 5, 236, 15, 253, 190, 246, 44, 69, 20, 172, 216, 29, 57, 0, 202, 239, 33, 40, 240, 228, 15, 19, 217, 254, 22, 13, 3, 243, 225, 255, 70, 17, 181, 218, 68, 42, 214, 219, 249, 32, 57, 237, 216, 9, 6, 220, 11, 39, 9, 243, 231, 244, 17, 49, 31, 185, 177, 36, 64, 248, 3, 44, 242, 192, 238, 18, 0, 23, 47, 241, 231, 241, 239, 20, 26, 6, 248, 251, 232, 237, 26, 28, 12, 3, 245, 228, 231, 18, 21, 0, 14, 251, 247, 11, 255, 249, 248, 2, 4, 4, 2, 251, 4, 0, 7, 9, 250, 253, 247, 235, 249, 27, 42, 2, 229, 244, 6, 0, 226, 254, 51, 17, 221, 247, 6, 6, 14, 252, 228, 7, 14, 251, 0, 250, 0, 28, 23, 233, 220, 252, 12, 7, 254, 18, 16, 253, 234, 249, 7, 0, 1, 253, 0, 245, 8, 41, 16, 219, 215, 7, 18, 5, 6, 236, 4, 50, 15, 212, 216, 242, 42, 254, 12, 27, 17, 226, 186, 23, 35, 22, 239, 243, 3, 12, 5, 219, 11, 9, 21, 5, 244, 240, 247, 246, 11, 61, 235, 220, 56, 222, 170, 47, 75, 7, 242, 209, 199, 25, 108, 29, 189, 170, 227, 92, 64, 225, 1, 240, 210, 11, 255, 35, 23, 220, 249, 243, 49, 53, 205, 180, 226, 39, 85, 39, 224, 202, 232, 250, 17, 57, 16, 234, 179, 0, 48, 41, 10, 221, 248, 236, 248, 29, 254, 4, 248, 1, 19, 29, 10, 211, 217, 234, 13, 56, 32, 247, 225, 248, 50, 9, 204, 184, 235, 64, 83, 67, 233, 155, 188, 255, 56, 85, 20, 195, 183, 222, 58, 104, 43, 196, 172, 218, 0, 53, 50, 5, 248, 244, 254, 0, 240, 246, 246, 13, 21, 10, 6, 240, 249, 8, 16, 9, 231, 232, 241, 10, 34, 24, 13, 244, 230, 245, 2, 2, 249, 252, 13, 16, 12, 3, 250, 253, 249, 235, 253, 9, 251, 0, 65, 0, 3, 0, 37, 0, 116, 0, 240, 0, 140, 10, 128, 12, 116, 14, 104, 16, 96, 27, 65, 9, 20, 12, 16, 8, 4, 4, 0, 0, 200, 212, 187, 250, 250, 175, 200, 212, 187, 44, 30, 40, 135, 49, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 33, 0, 116, 0, 240, 0, 140, 10, 128, 12, 116, 14, 104, 16, 96, 27, 0, 9, 20, 12, 16, 8, 4, 4, 0, 0, 200, 212, 187, 250, 250, 175, 200, 212, 187, 44, 30, 40, 135, 49, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 240, 0, 140, 10, 128, 12, 116, 14, 104, 16, 96, 27, 0, 9, 20, 12, 16, 8, 4, 4, 0, 0, 200, 212, 187, 250, 250, 175, 200, 212, 187, 44, 30, 40, 135, 49, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 70, 0, 3, 0, 5, 0, 196, 0, 240, 0, 208, 7, 184, 11, 172, 13, 210, 15, 96, 27, 70, 27, 45, 20, 4, 4, 3, 3, 0, 0, 210, 60, 120, 120, 120, 120, 105, 90, 120, 44, 30, 40, 135, 54, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 196, 0, 240, 0, 208, 7, 184, 11, 172, 13, 210, 15, 96, 27, 0, 22, 41, 19, 4, 4, 3, 3, 0, 0, 210, 60, 120, 120, 120, 120, 105, 90, 120, 44, 30, 40, 135, 54, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 196, 0, 240, 0, 208, 7, 184, 11, 172, 13, 210, 15, 96, 27, 0, 18, 36, 17, 3, 3, 2, 2, 0, 0, 210, 60, 120, 120, 120, 120, 105, 90, 120, 44, 30, 40, 135, 50, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 40, 0, 3, 0, 5, 0, 196, 0, 240, 0, 208, 7, 184, 11, 172, 13, 210, 15, 96, 27, 40, 16, 34, 16, 3, 3, 2, 2, 0, 0, 210, 60, 120, 120, 120, 120, 105, 90, 120, 44, 30, 40, 135, 51, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 196, 0, 240, 0, 208, 7, 184, 11, 172, 13, 210, 15, 96, 27, 0, 22, 41, 19, 4, 4, 3, 3, 0, 0, 210, 60, 120, 120, 120, 120, 105, 90, 120, 44, 30, 40, 135, 52, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 196, 0, 240, 0, 208, 7, 184, 11, 172, 13, 210, 15, 96, 27, 0, 22, 41, 19, 4, 4, 3, 3, 0, 0, 210, 60, 120, 120, 120, 120, 105, 90, 120, 44, 30, 40, 135, 52, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 70, 0, 3, 0, 5, 0, 116, 0, 232, 0, 140, 10, 128, 12, 116, 14, 124, 16, 124, 21, 70, 11, 22, 13, 17, 8, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 232, 0, 140, 10, 128, 12, 116, 14, 124, 16, 124, 21, 0, 9, 20, 12, 16, 8, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 232, 0, 140, 10, 128, 12, 116, 14, 124, 16, 124, 21, 0, 7, 18, 10, 14, 7, 3, 3, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 40, 0, 3, 0, 5, 0, 196, 0, 204, 1, 140, 10, 184, 11, 228, 12, 210, 15, 96, 27, 40, 8, 30, 13, 13, 3, 2, 2, 0, 0, 210, 60, 120, 120, 120, 120, 105, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 132, 0, 244, 1, 140, 10, 184, 11, 228, 12, 210, 15, 96, 27, 0, 7, 28, 12, 16, 8, 1, 1, 1, 0, 210, 75, 120, 120, 120, 120, 120, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 132, 0, 244, 1, 140, 10, 184, 11, 228, 12, 210, 15, 96, 27, 0, 8, 32, 12, 12, 3, 1, 1, 1, 0, 210, 75, 120, 120, 120, 120, 120, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 58, 0, 3, 0, 5, 0, 100, 0, 200, 0, 188, 2, 208, 7, 72, 13, 60, 15, 124, 21, 58, 11, 21, 12, 6, 8, 4, 4, 0, 0, 200, 212, 187, 200, 255, 175, 200, 212, 187, 44, 30, 75, 140, 48, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 100, 0, 200, 0, 188, 2, 208, 7, 72, 13, 60, 15, 124, 21, 0, 11, 21, 12, 6, 8, 4, 4, 0, 0, 200, 212, 187, 200, 255, 175, 200, 212, 187, 44, 30, 75, 140, 48, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 100, 0, 200, 0, 188, 2, 208, 7, 72, 13, 60, 15, 124, 21, 0, 11, 21, 12, 6, 8, 4, 4, 0, 0, 200, 212, 187, 200, 255, 175, 200, 212, 187, 44, 30, 75, 140, 48, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 65, 0, 3, 0, 5, 0, 116, 0, 200, 0, 198, 7, 34, 11, 232, 13, 24, 16, 124, 21, 65, 6, 15, 15, 6, 3, 3, 3, 0, 0, 100, 150, 150, 150, 150, 150, 100, 150, 150, 44, 30, 75, 140, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 200, 0, 198, 7, 34, 11, 232, 13, 24, 16, 124, 21, 0, 2, 10, 10, 4, 2, 2, 2, 0, 0, 100, 150, 150, 150, 150, 150, 100, 150, 150, 44, 30, 75, 140, 50, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 200, 0, 198, 7, 34, 11, 232, 13, 24, 16, 124, 21, 0, 2, 10, 10, 4, 2, 2, 2, 0, 0, 100, 150, 150, 150, 150, 150, 100, 150, 150, 44, 30, 75, 140, 50, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 185, 3, 25, 0, 255, 254, 255, 0, 0, 2, 3, 4, 4, 4, 3, 3, 3, 1, 2, 1, 1, 0, 0, 255, 253, 251, 252, 253, 254, 253, 254, 255, 0, 1, 4, 4, 6, 4, 5, 3, 3, 5, 4, 2, 0, 1, 0, 255, 255, 253, 252, 250, 251, 249, 251, 252, 255, 0, 2, 3, 5, 3, 5, 8, 12, 13, 13, 15, 16, 15, 17, 232, 132, 160, 0, 57, 76, 58, 15, 3, 245, 227, 210, 210, 248, 31, 57, 52, 23, 255, 233, 217, 213, 237, 5, 23, 26, 26, 19, 1, 240, 221, 225, 240, 2, 18, 31, 27, 12, 250, 250, 245, 243, 248, 254, 4, 10, 8, 14, 8, 0, 239, 241, 250, 0, 2, 8, 10, 5, 3, 0, 254, 251, 247, 247, 0, 6, 10, 11, 5, 1, 254, 247, 255, 1, 0, 2, 0, 0, 4, 0, 254, 248, 250, 253, 254, 7, 13, 9, 6, 1, 251, 249, 248, 249, 253, 3, 9, 14, 11, 4, 251, 247, 248, 245, 250, 1, 7, 10, 13, 5, 1, 249, 244, 249, 253, 0, 9, 14, 14, 6, 0, 238, 246, 248, 246, 250, 4, 16, 16, 7, 7, 4, 252, 249, 243, 242, 250, 1, 8, 12, 8, 4, 0, 246, 0, 254, 4, 16, 20, 3, 222, 7, 7, 253, 0, 234, 233, 1, 2, 18, 13, 1, 0, 254, 253, 0, 6, 20, 22, 11, 5, 0, 243, 226, 224, 232, 253, 14, 20, 20, 13, 2, 246, 249, 252, 0, 8, 7, 15, 13, 254, 254, 244, 236, 245, 251, 9, 15, 10, 14, 2, 245, 250, 246, 250, 2, 3, 6, 5, 0, 254, 250, 252, 254, 4, 16, 15, 8, 252, 254, 251, 248, 251, 252, 2, 5, 0, 2, 249, 253, 0, 255, 0, 1, 9, 19, 8, 3, 245, 243, 247, 251, 5, 6, 15, 9, 250, 253, 3, 241, 244, 249, 11, 1, 251, 25, 8, 239, 4, 4, 4, 14, 251, 1, 19, 237, 0, 0, 244, 247, 251, 251, 8, 6, 238, 250, 1, 8, 17, 8, 253, 2, 22, 12, 16, 0, 250, 12, 26, 12, 183, 156, 200, 26, 51, 34, 30, 6, 12, 2, 0, 252, 243, 255, 14, 30, 20, 251, 218, 219, 246, 251, 16, 21, 20, 253, 0, 4, 242, 223, 232, 7, 26, 28, 5, 8, 7, 248, 236, 243, 14, 21, 13, 6, 248, 247, 236, 246, 0, 15, 11, 11, 10, 255, 232, 192, 224, 12, 33, 32, 32, 28, 7, 8, 255, 2, 221, 206, 253, 22, 30, 2, 0, 244, 234, 243, 0, 10, 251, 253, 9, 33, 23, 252, 243, 246, 0, 2, 5, 12, 5, 246, 242, 252, 254, 0, 1, 0, 254, 255, 2, 4, 7, 253, 249, 2, 9, 10, 4, 255, 255, 251, 254, 3, 7, 2, 250, 250, 2, 2, 247, 251, 3, 3, 1, 4, 2, 4, 0, 0, 3, 2, 0, 0, 1, 0, 250, 254, 0, 7, 2, 252, 1, 3, 1, 252, 252, 0, 1, 5, 7, 8, 1, 254, 248, 251, 255, 1, 4, 3, 2, 3, 2, 0, 252, 252, 252, 1, 3, 4, 0, 4, 0, 2, 252, 254, 0, 2, 1, 0, 2, 0, 2, 253, 250, 7, 2, 254, 3, 253, 251, 2, 4, 0, 13, 2, 253, 251, 247, 255, 8, 1, 251, 0, 4, 4, 7, 254, 0, 0, 254, 249, 254, 0, 3, 14, 9, 252, 253, 253, 246, 251, 252, 255, 11, 16, 8, 0, 244, 252, 0, 3, 4, 4, 4, 255, 251, 252, 1, 0, 0, 252, 254, 3, 5, 6, 4, 255, 248, 248, 7, 2, 255, 255, 12, 11, 4, 254, 245, 248, 252, 0, 0, 7, 4, 0, 0, 253, 2, 0, 253, 255, 0, 3, 2, 2, 6, 7, 254, 253, 255, 248, 250, 7, 9, 2, 1, 0, 4, 5, 252, 244, 246, 255, 1, 9, 13, 0, 255, 255, 0, 254, 250, 0, 7, 6, 2, 0, 1, 1, 254, 246, 245, 2, 15, 11, 255, 249, 249, 5, 3, 255, 254, 253, 0, 8, 2, 5, 1, 251, 255, 0, 1, 5, 1, 252, 252, 0, 3, 0, 2, 8, 0, 253, 0, 255, 2, 253, 255, 0, 0, 0, 1, 2, 10, 0, 251, 255, 4, 7, 3, 248, 246, 250, 2, 11, 9, 253, 245, 255, 8, 6, 1, 253, 253, 3, 254, 2, 0, 254, 252, 2, 7, 8, 2, 249, 253, 0, 0, 0, 3, 6, 0, 254, 255, 1, 1, 0, 254, 250, 254, 5, 10, 9, 0, 246, 252, 2, 5, 5, 254, 255, 0, 251, 255, 4, 255, 0, 3, 2, 4, 254, 252, 0, 0, 0, 3, 2, 5, 0, 251, 0, 253, 0, 0, 0, 3, 3, 6, 4, 0, 253, 252, 250, 0, 7, 3, 1, 0, 254, 0, 255, 253, 253, 255, 3, 3, 5, 5, 0, 254, 253, 251, 3, 9, 7, 0, 253, 252, 251, 251, 253, 254, 2, 8, 9, 4, 2, 254, 252, 254, 255, 2, 5, 5, 0, 255, 250, 253, 2, 2, 1, 1, 0, 3, 1, 0, 253, 251, 254, 1, 5, 5, 0, 249, 254, 3, 5, 4, 3, 1, 254, 254, 255, 0, 0, 0, 0, 6, 2, 254, 253, 254, 253, 0, 2, 5, 7, 0, 255, 254, 253, 0, 0, 3, 7, 4, 251, 249, 254, 3, 6, 3, 2, 0, 254, 0, 255, 252, 252, 255, 1, 5, 8, 6, 2, 0, 253, 251, 253, 254, 3, 6, 5, 4, 0, 251, 253, 255, 252, 0, 1, 2, 5, 2, 1, 0, 254, 1, 0, 2, 0, 254, 0, 0, 0, 255, 5, 5, 2, 0, 253, 0, 0, 254, 254, 0, 0, 0, 30, 0, 3, 0, 5, 0, 116, 0, 200, 0, 198, 7, 34, 11, 232, 13, 24, 16, 124, 21, 30, 11, 20, 20, 8, 4, 4, 4, 0, 0, 100, 150, 150, 150, 150, 150, 100, 150, 150, 44, 30, 75, 140, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 200, 0, 198, 7, 34, 11, 232, 13, 24, 16, 124, 21, 0, 8, 17, 17, 6, 3, 3, 3, 0, 0, 100, 150, 150, 150, 150, 150, 100, 150, 150, 44, 30, 75, 140, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 200, 0, 198, 7, 34, 11, 232, 13, 24, 16, 124, 21, 0, 8, 17, 17, 6, 3, 3, 3, 0, 0, 100, 150, 150, 150, 150, 150, 100, 150, 150, 44, 30, 75, 140, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 129, 2, 18, 0, 1, 251, 255, 247, 254, 1, 6, 2, 3, 251, 1, 251, 4, 242, 105, 120, 72, 1, 211, 222, 253, 2, 233, 242, 251, 41, 24, 5, 226, 212, 207, 247, 251, 2, 11, 17, 6, 240, 230, 221, 237, 247, 241, 0, 0, 2, 0, 253, 236, 226, 232, 233, 238, 248, 248, 245, 235, 224, 232, 224, 246, 235, 41, 56, 112, 108, 63, 37, 185, 240, 255, 45, 33, 53, 62, 52, 38, 242, 215, 213, 227, 228, 31, 41, 40, 24, 0, 228, 211, 207, 233, 248, 244, 9, 245, 6, 222, 237, 235, 235, 231, 223, 254, 15, 20, 5, 243, 215, 254, 249, 241, 242, 6, 30, 7, 35, 14, 27, 250, 23, 243, 0, 252, 20, 23, 29, 21, 8, 245, 250, 248, 10, 11, 4, 5, 5, 249, 11, 10, 242, 239, 239, 240, 253, 15, 253, 253, 9, 250, 0, 250, 253, 235, 238, 0, 255, 10, 13, 1, 240, 239, 243, 252, 3, 10, 255, 11, 14, 4, 237, 231, 245, 3, 21, 9, 254, 246, 6, 12, 253, 240, 254, 14, 15, 3, 10, 17, 255, 255, 248, 242, 20, 41, 21, 253, 251, 243, 35, 45, 13, 248, 245, 249, 248, 9, 19, 17, 13, 248, 228, 209, 227, 245, 4, 234, 221, 0, 10, 37, 27, 251, 222, 228, 224, 5, 22, 25, 35, 10, 251, 244, 255, 252, 3, 248, 13, 22, 21, 16, 0, 242, 234, 240, 0, 2, 14, 11, 249, 255, 251, 249, 252, 249, 255, 233, 240, 249, 240, 4, 14, 5, 0, 249, 225, 236, 253, 10, 8, 246, 255, 5, 5, 230, 234, 252, 18, 24, 23, 35, 35, 31, 6, 5, 21, 13, 9, 3, 12, 14, 13, 2, 233, 221, 247, 255, 247, 242, 226, 7, 53, 44, 33, 246, 233, 1, 10, 21, 241, 243, 25, 29, 22, 29, 244, 208, 221, 216, 245, 251, 19, 243, 231, 2, 3, 0, 254, 225, 227, 6, 26, 233, 204, 213, 255, 243, 219, 253, 236, 235, 198, 247, 240, 65, 59, 40, 5, 223, 18, 18, 41, 30, 32, 42, 52, 55, 39, 1, 245, 255, 254, 30, 42, 36, 37, 251, 237, 232, 252, 0, 1, 241, 231, 224, 235, 229, 217, 250, 224, 203, 214, 189, 223, 233, 253, 50, 31, 28, 226, 5, 10, 14, 2, 255, 245, 37, 66, 43, 33, 2, 254, 3, 11, 5, 1, 19, 11, 5, 5, 234, 4, 252, 3, 242, 253, 247, 224, 246, 249, 237, 223, 231, 240, 0, 253, 248, 254, 239, 1, 253, 15, 12, 1, 10, 14, 28, 5, 0, 11, 9, 13, 21, 11, 13, 20, 11, 16, 29, 11, 0, 242, 249, 9, 246, 253, 244, 252, 254, 252, 2, 238, 249, 248, 255, 254, 247, 248, 226, 242, 235, 237, 250, 254, 240, 238, 244, 251, 0, 5, 4, 249, 252, 6, 255, 6, 6, 11, 15, 25, 8, 8, 30, 22, 33, 17, 19, 12, 25, 35, 24, 9, 13, 251, 248, 4, 253, 3, 13, 0, 239, 241, 251, 252, 245, 221, 223, 232, 247, 4, 239, 240, 241, 246, 5, 13, 249, 246, 237, 239, 233, 1, 255, 235, 250, 4, 0, 0, 0, 252, 3, 16, 20, 15, 9, 19, 8, 252, 4, 17, 18, 1, 248, 7, 11, 14, 6, 0, 245, 233, 253, 16, 12, 253, 236, 237, 3, 12, 246, 241, 0, 4, 247, 2, 8, 18, 13, 2, 2, 7, 28, 30, 24, 8, 250, 4, 2, 10, 3, 25, 20, 2, 7, 8, 250, 0, 254, 0, 0, 9, 250, 4, 248, 236, 237, 0, 243, 226, 220, 246, 246, 254, 244, 244, 248, 235, 234, 240, 248, 247, 234, 231, 246, 253, 0, 249, 250, 0, 10, 251, 253, 253, 11, 13, 19, 16, 4, 5, 9, 8, 15, 25, 18, 0, 0, 0, 75, 0, 3, 0, 21, 0, 168, 0, 220, 0, 36, 4, 32, 8, 72, 13, 168, 17, 106, 24, 40, 10, 25, 14, 2, 2, 5, 2, 8, 5, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 30, 45, 60, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 168, 0, 220, 0, 36, 4, 32, 8, 72, 13, 168, 17, 106, 24, 35, 10, 25, 14, 2, 2, 5, 2, 8, 5, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 30, 45, 60, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 168, 0, 220, 0, 36, 4, 32, 8, 72, 13, 168, 17, 106, 24, 0, 2, 12, 7, 1, 1, 2, 1, 4, 2, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 30, 45, 60, 51, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 252, 8, 6, 0, 250, 250, 254, 7, 12, 10, 10, 6, 3, 0, 255, 245, 254, 4, 0, 254, 255, 255, 0, 0, 241, 253, 7, 4, 4, 18, 2, 0, 0, 246, 0, 12, 15, 15, 251, 231, 228, 233, 248, 7, 16, 10, 4, 17, 20, 26, 17, 251, 243, 232, 235, 248, 252, 243, 245, 237, 250, 27, 27, 38, 37, 21, 250, 241, 237, 234, 235, 242, 236, 246, 5, 14, 25, 21, 0, 5, 7, 10, 12, 5, 242, 233, 243, 243, 246, 250, 255, 14, 13, 18, 24, 8, 0, 245, 241, 240, 2, 251, 5, 10, 251, 254, 1, 2, 5, 255, 4, 5, 0, 15, 251, 240, 246, 255, 5, 5, 250, 10, 8, 252, 251, 248, 13, 3, 9, 1, 254, 253, 245, 0, 7, 251, 248, 6, 3, 9, 254, 250, 5, 250, 0, 7, 11, 5, 1, 252, 248, 247, 252, 252, 254, 12, 7, 5, 10, 247, 10, 0, 246, 0, 254, 249, 249, 2, 1, 4, 4, 10, 4, 1, 3, 6, 255, 249, 250, 248, 0, 2, 0, 251, 9, 1, 5, 1, 251, 0, 2, 5, 4, 255, 9, 251, 0, 4, 250, 255, 253, 253, 252, 8, 5, 2, 253, 248, 248, 8, 10, 6, 3, 255, 3, 7, 9, 248, 247, 250, 245, 254, 4, 2, 11, 2, 255, 0, 0, 255, 4, 0, 246, 255, 6, 9, 252, 4, 253, 5, 14, 14, 1, 246, 246, 242, 245, 0, 252, 251, 253, 253, 251, 1, 10, 21, 29, 42, 45, 37, 27, 215, 152, 140, 139, 204, 41, 92, 107, 103, 78, 38, 11, 223, 187, 179, 172, 191, 226, 2, 42, 55, 54, 40, 29, 14, 19, 12, 237, 218, 212, 210, 224, 253, 10, 19, 27, 22, 22, 19, 6, 255, 244, 234, 244, 8, 9, 8, 248, 240, 239, 241, 6, 21, 15, 8, 0, 8, 253, 7, 3, 244, 244, 247, 248, 12, 17, 4, 252, 248, 243, 4, 15, 12, 1, 248, 249, 3, 4, 255, 253, 251, 255, 7, 2, 0, 10, 255, 230, 7, 13, 1, 16, 0, 250, 244, 248, 11, 10, 242, 242, 11, 250, 18, 17, 242, 8, 253, 5, 255, 1, 253, 243, 241, 253, 8, 4, 18, 10, 255, 0, 7, 4, 246, 0, 243, 243, 251, 14, 1, 255, 11, 3, 0, 253, 7, 17, 7, 247, 0, 237, 251, 247, 3, 7, 4, 250, 2, 13, 7, 0, 0, 247, 2, 5, 6, 3, 240, 238, 3, 16, 3, 5, 252, 245, 13, 9, 246, 2, 250, 252, 254, 253, 7, 6, 9, 7, 253, 255, 19, 3, 244, 237, 243, 2, 3, 243, 7, 4, 254, 30, 10, 3, 2, 1, 249, 248, 247, 7, 0, 239, 249, 244, 7, 10, 4, 13, 250, 13, 16, 253, 253, 2, 249, 4, 248, 250, 2, 0, 251, 254, 251, 1, 6, 0, 5, 254, 2, 10, 252, 0, 12, 7, 1, 1, 4, 249, 3, 2, 244, 244, 242, 254, 0, 244, 252, 8, 15, 22, 9, 9, 19, 13, 1, 0, 0, 244, 228, 227, 230, 225, 8, 20, 20, 24, 19, 11, 9, 9, 1, 2, 0, 246, 254, 246, 238, 235, 240, 237, 0, 5, 24, 38, 31, 25, 11, 246, 235, 237, 235, 238, 248, 249, 0, 3, 10, 12, 21, 14, 13, 8, 4, 254, 246, 240, 239, 239, 242, 255, 3, 1, 19, 7, 9, 7, 3, 16, 11, 3, 252, 246, 245, 244, 242, 237, 15, 0, 239, 20, 24, 0, 14, 247, 0, 8, 252, 254, 17, 241, 247, 14, 247, 254, 252, 255, 3, 253, 7, 0, 3, 6, 251, 0, 0, 7, 4, 5, 230, 255, 15, 248, 17, 253, 249, 1, 251, 10, 8, 1, 242, 4, 254, 6, 5, 252, 246, 7, 255, 243, 14, 0, 254, 11, 255, 2, 17, 0, 251, 6, 245, 234, 251, 14, 253, 250, 13, 4, 250, 7, 251, 12, 19, 242, 241, 10, 0, 254, 1, 247, 0, 250, 252, 13, 34, 0, 241, 243, 235, 33, 238, 239, 28, 252, 243, 41, 12, 229, 4, 252, 0, 244, 2, 9, 241, 14, 4, 253, 12, 3, 245, 243, 254, 11, 0, 243, 1, 14, 2, 0, 9, 13, 253, 238, 0, 5, 15, 11, 228, 232, 11, 248, 254, 0, 15, 10, 243, 0, 20, 21, 20, 254, 239, 241, 233, 249, 2, 255, 2, 4, 249, 20, 9, 255, 14, 241, 247, 12, 255, 252, 15, 3, 249, 5, 14, 3, 246, 240, 248, 252, 250, 249, 247, 255, 0, 1, 19, 21, 19, 24, 22, 33, 21, 245, 210, 184, 183, 200, 248, 30, 40, 44, 42, 35, 29, 31, 11, 249, 229, 221, 234, 235, 234, 230, 227, 239, 10, 27, 41, 48, 37, 7, 6, 250, 243, 234, 240, 238, 240, 0, 0, 254, 3, 255, 10, 7, 6, 9, 15, 253, 245, 0, 250, 6, 7, 7, 5, 253, 247, 236, 237, 5, 7, 12, 5, 9, 251, 8, 16, 252, 249, 237, 254, 7, 4, 252, 13, 255, 248, 253, 253, 23, 7, 241, 255, 250, 13, 0, 234, 16, 0, 5, 0, 244, 250, 6, 23, 0, 0, 0, 254, 14, 235, 235, 245, 9, 21, 2, 3, 1, 245, 8, 251, 34, 241, 251, 4, 239, 2, 0, 3, 10, 254, 243, 252, 23, 6, 241, 247, 18, 4, 251, 1, 2, 17, 224, 239, 9, 11, 16, 0, 249, 8, 13, 3, 231, 251, 255, 252, 6, 7, 254, 6, 19, 241, 0, 242, 248, 34, 17, 245, 239, 1, 245, 6, 0, 0, 254, 11, 235, 247, 20, 19, 15, 243, 249, 0, 250, 7, 2, 8, 6, 251, 235, 255, 248, 254, 26, 253, 249, 15, 247, 8, 21, 224, 0, 11, 253, 34, 8, 229, 246, 239, 246, 8, 3, 23, 0, 252, 28, 229, 251, 18, 237, 3, 25, 246, 251, 251, 5, 0, 242, 5, 9, 12, 5, 0, 3, 244, 234, 6, 7, 255, 0, 240, 253, 30, 255, 0, 10, 8, 3, 251, 246, 1, 4, 251, 0, 254, 250, 255, 12, 246, 253, 4, 253, 6, 246, 255, 7, 11, 18, 6, 7, 17, 252, 249, 13, 242, 207, 209, 222, 236, 48, 74, 47, 12, 246, 229, 246, 23, 13, 246, 239, 221, 242, 5, 14, 14, 250, 235, 249, 14, 37, 39, 8, 233, 232, 232, 233, 16, 25, 249, 245, 13, 7, 10, 24, 4, 235, 245, 246, 236, 7, 14, 3, 249, 240, 5, 17, 4, 9, 13, 245, 250, 23, 249, 238, 39, 244, 224, 7, 248, 252, 246, 255, 252, 6, 15, 23, 10, 32, 254, 220, 240, 5, 239, 18, 7, 228, 15, 249, 6, 27, 246, 239, 11, 4, 21, 249, 245, 0, 243, 249, 2, 10, 7, 239, 27, 250, 254, 20, 245, 16, 248, 248, 22, 248, 223, 246, 6, 251, 249, 11, 25, 7, 14, 11, 241, 2, 12, 233, 255, 3, 251, 245, 244, 17, 0, 252, 6, 0, 9, 12, 251, 250, 5, 13, 232, 5, 15, 233, 22, 6, 219, 12, 33, 241, 255, 242, 243, 18, 251, 2, 20, 249, 9, 244, 242, 34, 3, 247, 1, 250, 240, 6, 4, 248, 254, 254, 24, 6, 254, 4, 241, 23, 251, 233, 243, 0, 17, 251, 1, 25, 8, 246, 1, 8, 231, 0, 15, 223, 10, 15, 16, 1, 228, 6, 247, 7, 34, 246, 244, 12, 250, 251, 0, 14, 10, 243, 247, 10, 245, 9, 255, 239, 3, 250, 11, 28, 251, 3, 6, 235, 0, 4, 254, 4, 250, 13, 10, 254, 244, 238, 5, 14, 252, 3, 15, 236, 243, 251, 8, 23, 31, 248, 243, 5, 250, 241, 21, 248, 237, 5, 248, 255, 12, 6, 252, 254, 0, 7, 2, 1, 7, 255, 251, 8, 17, 13, 5, 234, 252, 247, 229, 251, 252, 237, 252, 25, 21, 33, 29, 7, 235, 251, 247, 8, 7, 239, 235, 237, 251, 1, 4, 252, 10, 12, 3, 23, 34, 245, 245, 237, 254, 254, 243, 16, 10, 238, 248, 243, 26, 16, 245, 6, 254, 251, 2, 18, 251, 238, 1, 251, 2, 253, 18, 2, 1, 254, 0, 252, 12, 23, 232, 246, 255, 4, 5, 229, 246, 5, 9, 12, 12, 14, 2, 0, 5, 250, 238, 9, 0, 248, 2, 222, 14, 25, 238, 15, 255, 250, 18, 251, 248, 34, 251, 227, 21, 235, 232, 42, 253, 232, 35, 254, 226, 23, 0, 253, 14, 244, 237, 9, 10, 251, 25, 251, 235, 9, 242, 16, 34, 231, 231, 17, 17, 243, 245, 10, 241, 251, 22, 241, 30, 7, 235, 0, 30, 248, 222, 41, 237, 207, 57, 248, 213, 65, 235, 241, 40, 15, 223, 251, 247, 1, 23, 233, 245, 6, 12, 8, 255, 8, 19, 231, 13, 8, 204, 16, 29, 233, 7, 10, 232, 6, 33, 253, 223, 1, 18, 15, 249, 252, 248, 10, 9, 249, 228, 26, 243, 16, 20, 244, 246, 226, 29, 8, 229, 14, 12, 252, 255, 2, 7, 255, 255, 12, 231, 11, 17, 0, 247, 0, 234, 17, 253, 242, 30, 245, 253, 2, 248, 249, 16, 13, 1, 7, 251, 2, 12, 245, 254, 244, 240, 0, 11, 11, 248, 7, 251, 255, 6, 246, 8, 14, 244, 15, 24, 241, 246, 0, 252, 9, 247, 255, 11, 233, 244, 23, 253, 252, 3, 246, 10, 14, 249, 0, 253, 5, 25, 30, 26, 9, 236, 196, 200, 203, 246, 40, 60, 26, 250, 2, 1, 26, 33, 7, 234, 225, 233, 239, 16, 32, 244, 226, 219, 240, 25, 40, 46, 17, 234, 255, 255, 248, 2, 1, 233, 230, 3, 20, 18, 17, 248, 232, 239, 2, 21, 18, 1, 238, 8, 254, 251, 13, 14, 232, 0, 11, 232, 18, 253, 254, 14, 236, 0, 9, 22, 230, 9, 29, 246, 250, 6, 245, 247, 8, 241, 238, 23, 18, 242, 254, 20, 11, 242, 7, 5, 12, 232, 238, 8, 8, 4, 12, 236, 213, 32, 5, 15, 35, 218, 6, 46, 229, 224, 11, 230, 30, 231, 21, 233, 246, 56, 9, 224, 20, 241, 9, 36, 226, 211, 30, 244, 8, 253, 225, 30, 24, 248, 22, 244, 1, 0, 8, 246, 232, 9, 4, 245, 24, 242, 229, 44, 3, 253, 245, 252, 34, 231, 240, 26, 220, 14, 73, 193, 223, 64, 249, 249, 255, 233, 1, 5, 11, 14, 238, 253, 16, 233, 7, 24, 6, 0, 242, 236, 20, 2, 251, 17, 236, 231, 18, 44, 231, 245, 19, 238, 241, 34, 243, 2, 18, 239, 2, 236, 18, 10, 240, 15, 16, 230, 0, 29, 243, 236, 246, 16, 5, 245, 238, 18, 48, 230, 249, 0, 4, 20, 24, 210, 239, 29, 211, 16, 5, 255, 20, 250, 239, 40, 231, 21, 23, 222, 2, 1, 253, 4, 6, 227, 244, 30, 3, 15, 240, 242, 6, 12, 247, 20, 249, 236, 251, 25, 252, 19, 19, 220, 11, 252, 242, 22, 9, 227, 255, 15, 237, 249, 14, 5, 238, 12, 36, 240, 5, 44, 253, 241, 249, 216, 239, 0, 8, 6, 10, 3, 248, 8, 1, 9, 25, 7, 240, 239, 8, 1, 253, 16, 253, 230, 252, 244, 0, 13, 11, 20, 241, 7, 25, 241, 3, 4, 241, 234, 7, 4, 243, 20, 11, 228, 6, 32, 239, 253, 19, 0, 241, 255, 3, 10, 230, 5, 19, 229, 15, 29, 225, 230, 40, 21, 227, 247, 43, 235, 224, 41, 16, 226, 14, 239, 250, 2, 253, 254, 16, 254, 9, 246, 253, 25, 245, 13, 249, 3, 245, 238, 37, 244, 238, 12, 3, 227, 25, 9, 244, 17, 239, 13, 253, 0, 9, 254, 241, 26, 240, 230, 5, 39, 253, 249, 245, 17, 0, 239, 253, 7, 7, 18, 212, 15, 21, 229, 22, 10, 236, 1, 2, 252, 18, 232, 30, 15, 209, 9, 36, 225, 241, 10, 9, 254, 253, 21, 0, 238, 17, 0, 244, 229, 10, 43, 248, 241, 24, 236, 249, 5, 237, 30, 10, 0, 247, 237, 242, 28, 4, 243, 6, 24, 0, 240, 249, 246, 1, 25, 252, 246, 40, 233, 230, 46, 224, 242, 35, 240, 204, 63, 23, 199, 11, 40, 227, 7, 23, 223, 249, 51, 236, 225, 26, 252, 1, 221, 29, 34, 211, 17, 6, 225, 34, 235, 15, 43, 210, 251, 37, 200, 5, 16, 243, 24, 255, 241, 20, 17, 235, 6, 20, 254, 225, 7, 230, 4, 25, 236, 18, 244, 248, 28, 0, 17, 3, 236, 254, 0, 29, 8, 209, 0, 6, 224, 33, 10, 242, 15, 245, 238, 25, 1, 249, 10, 1, 15, 19, 6, 250, 235, 247, 254, 240, 253, 232, 6, 26, 248, 9, 26, 0, 247, 3, 3, 27, 7, 246, 241, 239, 1, 249, 9, 240, 241, 248, 252, 16, 37, 7, 23, 251, 242, 8, 248, 255, 10, 223, 253, 242, 6, 23, 5, 243, 17, 11, 217, 8, 44, 227, 243, 22, 243, 14, 15, 219, 14, 255, 241, 2, 25, 253, 9, 225, 252, 20, 15, 248, 247, 40, 232, 227, 35, 248, 232, 20, 244, 242, 13, 22, 3, 230, 10, 24, 0, 12, 7, 237, 223, 255, 17, 16, 230, 249, 10, 238, 18, 8, 4, 23, 23, 220, 249, 25, 245, 229, 13, 6, 239, 14, 22, 237, 4, 253, 246, 255, 4, 5, 3, 16, 248, 242, 23, 249, 238, 32, 236, 16, 18, 228, 10, 254, 251, 224, 252, 46, 28, 182, 1, 45, 242, 2, 16, 17, 248, 228, 11, 9, 226, 20, 0, 4, 2, 251, 3, 253, 9, 4, 231, 245, 20, 249, 240, 29, 250, 1, 32, 246, 246, 8, 255, 11, 250, 250, 3, 213, 34, 239, 236, 50, 0, 3, 0, 5, 0, 168, 0, 220, 0, 232, 3, 32, 8, 72, 13, 160, 15, 106, 24, 30, 10, 25, 14, 2, 2, 5, 2, 8, 5, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 45, 45, 60, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 168, 0, 220, 0, 76, 4, 32, 8, 72, 13, 160, 15, 106, 24, 20, 10, 25, 14, 2, 2, 5, 2, 8, 5, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 45, 45, 60, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 9, 0, 168, 0, 220, 0, 76, 4, 32, 8, 72, 13, 160, 15, 106, 24, 0, 2, 12, 7, 1, 1, 2, 1, 4, 2, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 45, 45, 60, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 75, 0, 3, 0, 5, 0, 168, 0, 160, 1, 232, 3, 216, 9, 72, 13, 168, 17, 81, 24, 40, 6, 25, 14, 2, 2, 5, 2, 8, 5, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 168, 0, 160, 1, 232, 3, 216, 9, 72, 13, 168, 17, 106, 24, 35, 6, 25, 14, 2, 2, 5, 2, 8, 5, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 168, 0, 160, 1, 232, 3, 216, 9, 72, 13, 168, 17, 56, 24, 0, 1, 12, 7, 1, 1, 2, 1, 4, 2, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 55, 0, 3, 0, 5, 0, 216, 0, 168, 1, 192, 3, 209, 9, 56, 14, 210, 16, 244, 26, 30, 20, 29, 29, 22, 7, 4, 2, 2, 0, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 216, 0, 168, 1, 16, 4, 209, 9, 56, 14, 210, 16, 244, 26, 25, 16, 26, 26, 19, 6, 4, 2, 2, 0, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 9, 0, 216, 0, 168, 1, 16, 4, 209, 9, 56, 14, 210, 16, 244, 26, 0, 16, 26, 26, 19, 6, 4, 2, 2, 0, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 80, 0, 3, 0, 5, 0, 168, 0, 220, 0, 76, 4, 32, 8, 72, 13, 160, 15, 106, 24, 40, 10, 25, 14, 2, 2, 5, 2, 8, 5, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 45, 45, 60, 51, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 168, 0, 220, 0, 76, 4, 32, 8, 72, 13, 160, 15, 106, 24, 40, 10, 25, 14, 2, 2, 5, 2, 8, 5, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 45, 45, 60, 52, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 168, 0, 220, 0, 76, 4, 32, 8, 72, 13, 160, 15, 106, 24, 0, 2, 12, 7, 1, 1, 2, 1, 4, 2, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 45, 45, 60, 52, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 98, 0, 4, 0, 5, 0, 168, 0, 160, 1, 232, 3, 216, 9, 72, 13, 168, 17, 81, 24, 35, 6, 25, 16, 3, 3, 6, 3, 6, 6, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 168, 0, 160, 1, 232, 3, 216, 9, 72, 13, 168, 17, 106, 24, 40, 10, 31, 19, 3, 3, 7, 3, 7, 11, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 9, 0, 168, 0, 160, 1, 232, 3, 216, 9, 72, 13, 168, 17, 106, 24, 23, 10, 31, 19, 3, 3, 7, 3, 7, 7, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 168, 0, 160, 1, 232, 3, 216, 9, 72, 13, 168, 17, 106, 24, 0, 10, 31, 19, 3, 3, 7, 3, 7, 7, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 75, 0, 3, 0, 5, 0, 168, 0, 72, 1, 232, 3, 96, 9, 72, 13, 168, 17, 106, 24, 40, 7, 22, 16, 11, 8, 8, 2, 5, 5, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 168, 0, 72, 1, 232, 3, 96, 9, 72, 13, 168, 17, 106, 24, 35, 7, 22, 16, 11, 8, 8, 2, 5, 5, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 168, 0, 72, 1, 232, 3, 96, 9, 72, 13, 168, 17, 106, 24, 0, 1, 11, 8, 5, 4, 4, 1, 2, 2, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 98, 0, 4, 0, 5, 0, 168, 0, 72, 1, 232, 3, 96, 9, 72, 13, 168, 17, 106, 24, 35, 8, 22, 19, 12, 9, 9, 3, 6, 6, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 168, 0, 72, 1, 232, 3, 96, 9, 72, 13, 168, 17, 106, 24, 40, 12, 27, 23, 15, 11, 11, 3, 7, 7, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 9, 0, 168, 0, 72, 1, 232, 3, 96, 9, 72, 13, 168, 17, 106, 24, 23, 12, 27, 23, 15, 11, 11, 3, 7, 7, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 168, 0, 72, 1, 232, 3, 96, 9, 72, 13, 168, 17, 106, 24, 0, 12, 27, 23, 15, 11, 11, 3, 7, 7, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 75, 0, 3, 0, 5, 0, 120, 0, 14, 1, 20, 5, 236, 9, 58, 14, 136, 19, 224, 21, 45, 10, 13, 26, 2, 2, 5, 5, 5, 5, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 30, 40, 85, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 120, 0, 14, 1, 20, 5, 236, 9, 58, 14, 136, 19, 224, 21, 30, 10, 13, 26, 2, 2, 5, 5, 5, 5, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 30, 40, 85, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 120, 0, 14, 1, 20, 5, 236, 9, 58, 14, 136, 19, 224, 21, 0, 3, 7, 15, 1, 1, 3, 3, 3, 3, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 30, 40, 85, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 3, 9, 11, 0, 232, 231, 247, 240, 226, 237, 245, 245, 248, 248, 253, 0, 7, 2, 12, 20, 17, 5, 255, 29, 22, 0, 1, 3, 13, 6, 7, 7, 9, 2, 251, 247, 244, 11, 5, 240, 244, 242, 0, 3, 245, 249, 3, 3, 240, 247, 19, 15, 239, 240, 7, 15, 15, 5, 234, 233, 5, 19, 5, 254, 0, 253, 250, 0, 21, 14, 8, 1, 253, 0, 4, 11, 8, 252, 251, 9, 14, 6, 248, 235, 253, 22, 19, 245, 229, 236, 235, 249, 26, 22, 212, 200, 240, 14, 18, 14, 1, 253, 0, 7, 32, 42, 2, 233, 1, 2, 18, 22, 14, 0, 1, 10, 17, 7, 252, 1, 252, 253, 251, 249, 239, 234, 225, 238, 244, 0, 240, 235, 247, 234, 234, 5, 9, 0, 16, 17, 24, 24, 41, 25, 34, 24, 5, 12, 27, 17, 16, 13, 255, 224, 226, 238, 229, 248, 254, 226, 211, 220, 218, 230, 252, 251, 242, 6, 18, 9, 14, 21, 18, 26, 41, 38, 33, 31, 8, 255, 5, 9, 2, 1, 251, 238, 241, 243, 234, 243, 245, 230, 241, 0, 253, 237, 242, 252, 247, 4, 7, 8, 16, 2, 246, 9, 28, 13, 0, 11, 10, 13, 20, 3, 252, 14, 250, 243, 27, 9, 236, 252, 0, 245, 235, 1, 0, 245, 229, 234, 252, 0, 254, 1, 21, 15, 248, 255, 0, 7, 8, 0, 10, 10, 6, 250, 1, 16, 21, 17, 17, 0, 242, 240, 255, 252, 236, 247, 252, 243, 254, 252, 247, 244, 7, 11, 3, 2, 6, 247, 236, 7, 13, 18, 15, 0, 3, 6, 8, 7, 21, 24, 250, 235, 240, 4, 5, 250, 239, 239, 5, 14, 15, 19, 2, 244, 255, 249, 204, 153, 199, 249, 38, 51, 13, 240, 31, 57, 27, 60, 78, 16, 233, 15, 13, 238, 219, 211, 219, 22, 36, 2, 244, 234, 209, 202, 248, 249, 247, 225, 212, 225, 10, 10, 249, 29, 83, 74, 50, 72, 60, 17, 223, 193, 208, 0, 0, 242, 2, 252, 233, 246, 24, 39, 42, 10, 226, 224, 235, 200, 178, 206, 238, 254, 21, 39, 30, 21, 11, 7, 40, 66, 35, 237, 230, 246, 255, 245, 1, 22, 33, 13, 8, 17, 14, 225, 208, 235, 2, 247, 237, 219, 228, 239, 243, 13, 40, 25, 251, 228, 1, 12, 10, 241, 253, 21, 33, 18, 20, 22, 1, 253, 13, 18, 7, 247, 235, 225, 247, 9, 231, 231, 250, 13, 0, 233, 10, 11, 17, 252, 10, 32, 2, 215, 209, 0, 13, 5, 18, 9, 5, 3, 11, 23, 5, 5, 247, 244, 12, 0, 0, 246, 0, 5, 254, 255, 255, 246, 248, 10, 0, 232, 246, 244, 11, 22, 255, 1, 5, 21, 13, 242, 236, 9, 18, 250, 8, 0, 246, 253, 249, 6, 252, 250, 13, 8, 254, 3, 4, 250, 241, 6, 12, 0, 250, 252, 13, 4, 254, 0, 5, 9, 252, 244, 247, 2, 0, 1, 244, 238, 1, 15, 253, 250, 9, 30, 20, 252, 12, 13, 237, 226, 250, 19, 7, 246, 249, 19, 19, 0, 244, 2, 17, 251, 234, 251, 249, 239, 227, 235, 4, 25, 4, 254, 18, 29, 4, 247, 13, 19, 5, 18, 9, 0, 251, 238, 238, 3, 20, 5, 234, 232, 246, 4, 251, 241, 250, 3, 254, 255, 22, 24, 244, 232, 4, 24, 18, 6, 254, 0, 4, 4, 6, 13, 6, 249, 248, 8, 8, 248, 236, 230, 243, 5, 254, 254, 7, 250, 234, 255, 24, 18, 3, 4, 0, 252, 14, 25, 252, 3, 10, 244, 245, 20, 13, 231, 237, 0, 0, 7, 253, 237, 253, 254, 255, 17, 18, 24, 0, 3, 237, 201, 225, 31, 41, 232, 236, 34, 39, 240, 219, 29, 53, 9, 223, 248, 249, 248, 28, 255, 248, 13, 8, 238, 233, 6, 243, 237, 1, 246, 1, 8, 2, 13, 17, 250, 0, 6, 10, 253, 249, 1, 13, 6, 251, 8, 22, 7, 233, 247, 0, 12, 253, 217, 254, 28, 5, 253, 0, 1, 234, 247, 11, 8, 6, 2, 255, 244, 4, 15, 4, 252, 245, 255, 4, 244, 7, 2, 255, 9, 14, 1, 1, 2, 240, 9, 11, 244, 245, 7, 28, 246, 246, 17, 11, 4, 7, 17, 254, 231, 239, 228, 240, 255, 255, 241, 254, 254, 248, 1, 17, 22, 23, 29, 12, 244, 250, 253, 243, 251, 11, 20, 4, 7, 7, 247, 251, 17, 20, 15, 16, 11, 231, 197, 211, 226, 227, 252, 12, 1, 250, 10, 246, 238, 36, 52, 16, 16, 42, 27, 242, 225, 243, 8, 20, 253, 252, 9, 9, 243, 219, 244, 20, 27, 250, 237, 253, 10, 225, 190, 238, 68, 48, 229, 231, 28, 16, 199, 211, 45, 72, 253, 218, 251, 20, 1, 233, 249, 48, 61, 246, 211, 32, 62, 237, 207, 9, 34, 4, 227, 212, 248, 10, 212, 204, 23, 50, 5, 228, 227, 0, 33, 12, 232, 5, 51, 242, 222, 16, 41, 14, 243, 255, 48, 43, 236, 237, 30, 253, 211, 214, 6, 9, 254, 241, 2, 248, 229, 15, 10, 233, 255, 1, 6, 235, 9, 15, 16, 6, 13, 19, 3, 14, 2, 5, 7, 254, 244, 246, 32, 20, 212, 236, 0, 246, 229, 2, 12, 243, 254, 248, 231, 11, 32, 24, 249, 5, 9, 10, 10, 250, 250, 247, 239, 18, 39, 9, 241, 239, 19, 25, 248, 252, 253, 235, 232, 10, 252, 231, 1, 8, 230, 226, 24, 254, 228, 24, 18, 19, 1, 17, 22, 249, 31, 25, 8, 9, 245, 243, 241, 12, 249, 241, 244, 8, 3, 237, 1, 254, 223, 217, 29, 38, 236, 0, 2, 241, 241, 15, 16, 249, 18, 253, 1, 21, 20, 227, 202, 6, 23, 23, 9, 14, 22, 23, 10, 6, 43, 27, 229, 229, 251, 255, 232, 221, 216, 222, 247, 248, 249, 241, 236, 222, 240, 17, 20, 8, 25, 33, 59, 71, 39, 30, 37, 254, 235, 1, 229, 199, 233, 255, 3, 5, 248, 208, 213, 7, 39, 38, 8, 220, 194, 221, 248, 2, 28, 34, 0, 251, 21, 33, 31, 18, 255, 1, 17, 13, 251, 239, 240, 233, 244, 255, 17, 16, 253, 237, 227, 246, 8, 4, 254, 7, 11, 252, 7, 26, 18, 16, 254, 242, 6, 1, 242, 237, 217, 231, 6, 22, 2, 4, 0, 214, 241, 32, 34, 15, 0, 243, 10, 23, 0, 2, 14, 24, 12, 255, 17, 16, 240, 207, 4, 6, 222, 4, 255, 213, 206, 9, 39, 247, 240, 19, 4, 241, 4, 34, 5, 237, 253, 35, 25, 238, 9, 46, 2, 254, 1, 253, 6, 8, 219, 250, 23, 251, 225, 246, 7, 251, 235, 6, 255, 228, 242, 17, 8, 241, 11, 21, 26, 230, 228, 50, 38, 232, 0, 32, 35, 238, 242, 251, 255, 252, 251, 246, 244, 24, 0, 233, 247, 10, 12, 247, 238, 230, 229, 16, 252, 19, 40, 7, 16, 14, 241, 236, 3, 5, 11, 0, 238, 24, 249, 241, 19, 27, 26, 255, 246, 245, 232, 221, 239, 2, 254, 24, 33, 244, 223, 243, 15, 11, 0, 242, 246, 16, 228, 224, 29, 37, 7, 246, 12, 47, 29, 3, 9, 30, 14, 247, 9, 31, 249, 205, 226, 228, 220, 221, 234, 235, 222, 233, 242, 246, 12, 17, 15, 38, 61, 31, 17, 44, 46, 44, 50, 9, 209, 209, 2, 0, 245, 240, 194, 168, 220, 36, 47, 19, 236, 203, 234, 31, 35, 10, 241, 231, 227, 11, 46, 39, 11, 249, 250, 19, 59, 49, 247, 217, 237, 2, 4, 253, 245, 244, 239, 240, 254, 7, 255, 241, 236, 0, 3, 249, 248, 235, 0, 30, 24, 12, 18, 26, 28, 34, 19, 241, 245, 249, 214, 206, 246, 1, 239, 250, 1, 247, 254, 22, 30, 35, 20, 4, 241, 216, 244, 11, 22, 16, 4, 10, 252, 246, 0, 255, 6, 13, 244, 224, 4, 7, 208, 228, 48, 12, 13, 12, 251, 5, 254, 251, 2, 255, 244, 237, 26, 12, 235, 13, 6, 18, 246, 19, 13, 245, 2, 232, 2, 249, 34, 250, 232, 13, 239, 248, 220, 23, 15, 245, 5, 18, 21, 214, 7, 24, 240, 241, 24, 24, 236, 251, 20, 3, 10, 0, 239, 242, 22, 236, 236, 46, 19, 231, 233, 9, 242, 210, 18, 29, 10, 2, 9, 241, 22, 10, 242, 253, 1, 4, 222, 239, 33, 24, 251, 12, 41, 233, 222, 15, 17, 243, 236, 10, 7, 19, 6, 216, 0, 37, 0, 215, 245, 253, 224, 238, 249, 16, 32, 14, 3, 245, 12, 0, 253, 26, 14, 255, 20, 24, 4, 253, 14, 13, 17, 15, 0, 245, 228, 227, 229, 242, 229, 218, 214, 222, 232, 250, 8, 246, 2, 29, 39, 53, 44, 27, 63, 75, 51, 46, 12, 217, 205, 220, 202, 206, 235, 205, 182, 5, 45, 5, 8, 18, 236, 0, 44, 16, 230, 226, 229, 240, 11, 22, 17, 27, 36, 13, 33, 55, 23, 237, 230, 248, 13, 0, 227, 216, 231, 249, 0, 252, 6, 16, 251, 230, 251, 250, 245, 238, 235, 254, 24, 26, 4, 5, 22, 21, 52, 48, 27, 5, 253, 251, 221, 214, 225, 230, 207, 223, 24, 34, 4, 248, 4, 17, 16, 17, 253, 249, 252, 254, 239, 239, 3, 8, 26, 22, 3, 31, 48, 237, 232, 19, 3, 208, 222, 6, 237, 6, 252, 246, 19, 247, 15, 5, 251, 252, 237, 25, 0, 222, 20, 11, 12, 17, 36, 244, 239, 225, 8, 40, 24, 8, 237, 235, 215, 16, 7, 224, 18, 26, 253, 6, 0, 0, 249, 239, 219, 30, 47, 248, 202, 9, 10, 227, 5, 43, 36, 13, 228, 16, 10, 209, 224, 53, 48, 222, 232, 27, 227, 192, 244, 50, 51, 7, 231, 254, 222, 220, 25, 47, 39, 233, 223, 26, 10, 254, 3, 227, 245, 46, 18, 251, 13, 228, 232, 252, 16, 39, 251, 220, 246, 11, 2, 222, 248, 254, 8, 244, 19, 22, 245, 218, 231, 35, 36, 23, 2, 1, 249, 4, 8, 14, 20, 4, 13, 25, 17, 12, 2, 253, 221, 221, 253, 244, 196, 189, 223, 244, 227, 232, 1, 5, 8, 17, 52, 74, 48, 17, 51, 74, 83, 48, 254, 222, 208, 204, 184, 227, 243, 198, 199, 4, 7, 253, 32, 7, 209, 6, 62, 21, 229, 220, 227, 232, 30, 25, 9, 43, 51, 248, 1, 80, 43, 228, 222, 9, 10, 7, 230, 217, 240, 9, 241, 242, 23, 21, 235, 206, 244, 255, 234, 215, 243, 5, 4, 1, 5, 17, 8, 6, 48, 56, 23, 37, 20, 17, 16, 13, 7, 9, 245, 176, 186, 223, 240, 234, 252, 15, 241, 248, 19, 4, 242, 15, 11, 3, 18, 254, 255, 252, 252, 9, 31, 72, 22, 0, 16, 254, 215, 219, 33, 39, 10, 178, 199, 244, 249, 12, 0, 16, 27, 30, 209, 180, 2, 70, 216, 229, 19, 67, 23, 245, 30, 5, 255, 21, 0, 242, 235, 235, 240, 42, 46, 185, 218, 33, 21, 5, 12, 15, 223, 211, 228, 17, 45, 24, 244, 239, 242, 247, 6, 5, 251, 20, 31, 1, 9, 0, 234, 242, 7, 22, 22, 235, 193, 216, 52, 22, 251, 255, 14, 7, 19, 245, 10, 2, 247, 225, 6, 30, 255, 232, 254, 15, 17, 13, 4, 13, 222, 222, 16, 255, 242, 9, 2, 254, 12, 6, 255, 244, 247, 238, 8, 9, 227, 255, 246, 241, 15, 26, 32, 250, 34, 43, 14, 253, 22, 7, 224, 3, 16, 13, 244, 216, 7, 253, 226, 244, 5, 213, 196, 215, 238, 250, 234, 254, 255, 8, 35, 50, 59, 69, 29, 10, 70, 77, 64, 8, 197, 201, 226, 201, 204, 223, 208, 201, 228, 6, 37, 52, 12, 207, 241, 57, 44, 230, 228, 219, 215, 6, 20, 23, 53, 42, 244, 6, 69, 52, 241, 231, 255, 253, 244, 252, 248, 239, 246, 0, 243, 253, 31, 6, 219, 235, 9, 247, 214, 222, 255, 249, 236, 0, 15, 11, 9, 25, 52, 29, 252, 9, 26, 3, 8, 29, 30, 30, 9, 10, 250, 239, 193, 183, 231, 249, 0, 233, 220, 205, 236, 61, 6, 255, 56, 44, 247, 218, 30, 254, 253, 0, 10, 63, 59, 13, 234, 10, 8, 225, 3, 255, 220, 223, 219, 0, 5, 239, 3, 9, 48, 42, 228, 232, 235, 197, 234, 11, 243, 41, 17, 217, 233, 57, 103, 4, 23, 39, 17, 229, 215, 12, 239, 5, 230, 237, 5, 234, 231, 0, 0, 220, 30, 26, 255, 1, 243, 249, 13, 36, 245, 244, 17, 21, 243, 15, 4, 228, 232, 0, 244, 18, 24, 230, 245, 7, 2, 34, 23, 24, 19, 223, 232, 249, 18, 12, 226, 252, 25, 7, 229, 240, 26, 32, 245, 239, 237, 238, 244, 247, 247, 7, 255, 253, 0, 8, 9, 0, 28, 18, 239, 252, 8, 40, 252, 207, 252, 37, 1, 8, 27, 12, 15, 28, 14, 247, 3, 5, 232, 232, 6, 249, 216, 214, 226, 208, 209, 253, 240, 207, 230, 12, 23, 30, 57, 55, 75, 72, 55, 65, 91, 73, 253, 184, 225, 203, 137, 172, 222, 212, 222, 0, 241, 0, 72, 50, 229, 4, 68, 0, 199, 212, 225, 255, 246, 233, 2, 75, 76, 0, 23, 82, 32, 243, 237, 0, 10, 241, 214, 220, 253, 8, 0, 246, 23, 31, 239, 228, 0, 0, 223, 215, 229, 246, 10, 241, 0, 29, 244, 254, 35, 33, 238, 253, 54, 14, 221, 244, 40, 19, 2, 14, 15, 33, 30, 1, 33, 31, 248, 218, 176, 170, 202, 252, 0, 80, 0, 3, 0, 5, 0, 120, 0, 14, 1, 20, 5, 236, 9, 58, 14, 136, 19, 224, 21, 45, 10, 9, 30, 3, 3, 6, 6, 6, 6, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 30, 40, 85, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 120, 0, 14, 1, 20, 5, 236, 9, 58, 14, 136, 19, 224, 21, 35, 11, 9, 31, 3, 3, 6, 6, 7, 6, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 30, 40, 85, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 120, 0, 14, 1, 20, 5, 236, 9, 58, 14, 136, 19, 224, 21, 0, 11, 9, 31, 3, 3, 6, 6, 7, 6, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 30, 40, 85, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 95, 0, 3, 0, 5, 0, 160, 0, 240, 0, 160, 5, 40, 10, 199, 14, 36, 19, 0, 25, 50, 11, 14, 23, 12, 9, 7, 3, 7, 7, 135, 142, 160, 160, 150, 175, 135, 142, 160, 44, 35, 30, 90, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 160, 0, 240, 0, 160, 5, 40, 10, 199, 14, 36, 19, 0, 25, 45, 11, 14, 23, 12, 9, 7, 3, 7, 7, 135, 142, 160, 160, 150, 175, 135, 142, 160, 44, 35, 30, 90, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 160, 0, 240, 0, 160, 5, 40, 10, 199, 14, 36, 19, 0, 25, 0, 0, 2, 3, 2, 1, 1, 0, 1, 1, 135, 142, 160, 160, 150, 175, 135, 142, 160, 44, 35, 30, 90, 45, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 173, 10, 22, 0, 20, 8, 0, 249, 234, 255, 245, 10, 13, 6, 240, 248, 2, 11, 20, 245, 254, 7, 6, 20, 243, 251, 35, 28, 247, 241, 228, 15, 7, 200, 227, 32, 17, 245, 205, 246, 49, 49, 2, 209, 19, 39, 9, 227, 2, 30, 6, 230, 246, 8, 8, 243, 221, 2, 32, 25, 237, 220, 251, 21, 224, 11, 22, 3, 4, 223, 0, 28, 12, 30, 249, 234, 18, 0, 22, 246, 215, 19, 42, 253, 225, 228, 251, 8, 215, 239, 24, 27, 21, 247, 232, 65, 23, 216, 252, 253, 41, 244, 225, 9, 244, 252, 249, 254, 21, 19, 253, 251, 245, 239, 14, 246, 11, 7, 220, 8, 63, 5, 221, 2, 9, 8, 223, 221, 16, 43, 247, 208, 34, 70, 249, 204, 241, 30, 17, 242, 245, 254, 4, 9, 218, 240, 68, 245, 232, 9, 235, 15, 12, 241, 8, 16, 22, 235, 211, 41, 47, 224, 228, 24, 240, 251, 33, 213, 231, 38, 23, 254, 216, 13, 60, 252, 215, 4, 249, 245, 51, 223, 184, 38, 36, 21, 248, 214, 27, 7, 236, 18, 33, 242, 230, 22, 23, 9, 17, 203, 229, 13, 234, 6, 232, 11, 27, 245, 236, 16, 34, 241, 16, 251, 2, 57, 9, 201, 233, 18, 61, 255, 168, 26, 20, 179, 0, 23, 236, 17, 10, 252, 40, 17, 242, 252, 235, 45, 27, 202, 235, 18, 20, 26, 233, 223, 33, 0, 0, 254, 223, 255, 243, 231, 5, 31, 38, 247, 210, 21, 63, 18, 252, 211, 254, 18, 246, 245, 7, 9, 203, 7, 26, 1, 6, 243, 206, 255, 57, 53, 225, 232, 41, 236, 214, 45, 65, 216, 217, 1, 250, 255, 19, 234, 246, 250, 29, 23, 237, 219, 2, 33, 18, 10, 13, 218, 236, 57, 43, 208, 211, 25, 0, 4, 249, 227, 1, 35, 219, 242, 18, 2, 14, 235, 36, 46, 254, 249, 234, 0, 2, 244, 252, 238, 9, 20, 246, 0, 12, 16, 228, 196, 22, 63, 249, 220, 241, 36, 37, 244, 221, 18, 35, 232, 0, 28, 237, 239, 239, 234, 11, 46, 20, 199, 237, 51, 21, 225, 250, 13, 251, 16, 245, 220, 11, 67, 238, 181, 63, 26, 222, 228, 5, 36, 15, 231, 235, 57, 249, 251, 224, 230, 34, 7, 22, 230, 221, 27, 28, 239, 245, 252, 0, 58, 254, 188, 245, 47, 34, 245, 243, 3, 37, 213, 240, 253, 226, 59, 10, 205, 4, 33, 233, 253, 35, 9, 221, 209, 73, 69, 195, 198, 29, 36, 18, 216, 203, 31, 27, 249, 210, 44, 66, 207, 205, 16, 32, 45, 211, 190, 48, 56, 221, 201, 249, 84, 8, 198, 236, 38, 37, 255, 211, 247, 51, 30, 215, 225, 10, 5, 26, 255, 221, 232, 7, 11, 46, 230, 230, 11, 22, 15, 255, 246, 246, 10, 27, 245, 238, 16, 234, 251, 18, 246, 25, 228, 226, 21, 14, 47, 219, 204, 44, 10, 249, 20, 216, 2, 36, 255, 43, 201, 238, 36, 243, 5, 31, 222, 227, 27, 237, 226, 40, 51, 239, 202, 15, 19, 226, 28, 44, 223, 233, 255, 39, 16, 203, 252, 38, 232, 24, 12, 202, 23, 30, 224, 253, 14, 18, 253, 201, 8, 53, 230, 236, 24, 2, 18, 19, 214, 209, 41, 31, 243, 252, 17, 43, 225, 193, 47, 30, 227, 227, 232, 56, 16, 228, 237, 217, 27, 81, 220, 207, 50, 32, 243, 205, 0, 43, 38, 207, 229, 47, 1, 234, 9, 232, 7, 25, 245, 240, 206, 19, 54, 3, 235, 225, 42, 54, 225, 247, 217, 7, 46, 235, 232, 23, 12, 22, 219, 221, 87, 8, 207, 194, 12, 27, 244, 8, 12, 17, 248, 15, 249, 4, 34, 217, 205, 10, 82, 17, 166, 219, 51, 63, 7, 208, 208, 58, 22, 241, 219, 209, 70, 6, 215, 26, 3, 24, 1, 209, 1, 54, 234, 215, 37, 1, 248, 13, 6, 14, 8, 199, 6, 55, 245, 232, 210, 18, 22, 242, 1, 24, 2, 248, 18, 248, 243, 4, 31, 242, 226, 12, 12, 236, 0, 32, 231, 14, 48, 236, 251, 226, 214, 32, 37, 231, 235, 3, 16, 31, 249, 8, 9, 235, 4, 1, 237, 251, 17, 244, 236, 25, 7, 237, 37, 30, 214, 241, 0, 38, 241, 209, 46, 24, 248, 198, 9, 78, 238, 208, 253, 7, 49, 255, 147, 240, 102, 20, 248, 236, 249, 74, 235, 205, 36, 252, 234, 32, 213, 251, 21, 234, 24, 245, 248, 9, 28, 37, 181, 246, 27, 0, 27, 248, 239, 19, 26, 224, 253, 34, 236, 231, 253, 9, 20, 243, 235, 26, 246, 252, 29, 241, 30, 7, 179, 242, 76, 14, 253, 234, 230, 30, 16, 210, 253, 47, 19, 218, 227, 10, 42, 253, 194, 53, 39, 199, 8, 39, 252, 229, 204, 40, 39, 187, 14, 32, 1, 245, 255, 6, 52, 4, 187, 254, 2, 32, 11, 223, 253, 16, 3, 25, 233, 212, 34, 26, 227, 235, 2, 18, 251, 240, 31, 40, 235, 253, 9, 24, 250, 204, 36, 14, 193, 250, 18, 248, 2, 1, 2, 18, 37, 3, 231, 246, 5, 235, 11, 28, 235, 3, 13, 3, 4, 251, 207, 23, 30, 250, 251, 238, 12, 246, 33, 11, 210, 26, 2, 200, 14, 29, 7, 253, 235, 32, 11, 1, 26, 212, 245, 34, 15, 249, 235, 236, 21, 247, 191, 255, 68, 70, 221, 133, 54, 96, 227, 226, 245, 251, 45, 15, 226, 233, 253, 60, 254, 245, 18, 220, 219, 20, 6, 236, 29, 254, 217, 11, 38, 234, 241, 50, 39, 208, 243, 13, 248, 5, 1, 1, 29, 251, 219, 238, 20, 32, 253, 214, 16, 30, 227, 252, 0, 242, 23, 7, 235, 21, 15, 238, 249, 14, 15, 243, 8, 18, 241, 1, 19, 229, 223, 29, 37, 220, 213, 12, 8, 21, 15, 214, 238, 61, 43, 203, 242, 42, 16, 227, 238, 6, 8, 18, 223, 202, 49, 65, 185, 225, 53, 11, 3, 225, 11, 27, 245, 0, 207, 33, 82, 205, 184, 23, 61, 248, 221, 252, 253, 30, 246, 215, 33, 55, 248, 186, 248, 50, 38, 233, 218, 28, 19, 226, 246, 14, 21, 240, 221, 37, 11, 226, 8, 238, 39, 30, 204, 251, 26, 21, 10, 213, 227, 44, 36, 219, 191, 24, 75, 0, 221, 215, 9, 55, 21, 209, 233, 29, 21, 11, 211, 221, 42, 29, 244, 234, 244, 25, 35, 229, 232, 5, 11, 43, 226, 223, 44, 243, 231, 28, 3, 0, 245, 255, 248, 249, 12, 45, 251, 184, 20, 40, 246, 245, 254, 0, 9, 0, 239, 22, 32, 251, 216, 249, 22, 11, 0, 223, 14, 21, 232, 237, 16, 33, 12, 237, 223, 26, 20, 234, 229, 29, 252, 240, 48, 4, 234, 242, 9, 9, 12, 249, 225, 242, 40, 13, 230, 251, 8, 7, 25, 232, 220, 18, 39, 239, 237, 12, 11, 246, 14, 24, 211, 32, 28, 177, 243, 71, 239, 245, 253, 240, 25, 1, 254, 18, 0, 255, 254, 231, 2, 43, 252, 206, 224, 51, 54, 218, 221, 18, 53, 3, 213, 237, 33, 5, 213, 24, 29, 208, 242, 42, 10, 13, 230, 242, 16, 241, 14, 11, 241, 18, 40, 204, 217, 38, 26, 237, 225, 24, 17, 212, 9, 28, 19, 12, 209, 250, 33, 6, 245, 232, 12, 34, 218, 243, 18, 22, 5, 213, 9, 44, 250, 222, 6, 239, 28, 43, 189, 239, 57, 37, 228, 179, 34, 72, 227, 237, 231, 25, 16, 207, 247, 27, 12, 16, 9, 249, 12, 254, 238, 9, 240, 235, 32, 13, 222, 242, 4, 52, 246, 222, 24, 13, 30, 202, 237, 13, 22, 26, 237, 205, 13, 55, 5, 217, 202, 82, 58, 151, 236, 54, 12, 252, 233, 236, 42, 26, 230, 246, 243, 22, 12, 229, 7, 1, 0, 250, 9, 0, 246, 9, 18, 254, 10, 251, 209, 6, 30, 28, 230, 212, 56, 22, 215, 0, 5, 243, 5, 19, 252, 230, 5, 28, 11, 226, 240, 29, 31, 239, 250, 217, 6, 83, 220, 202, 20, 8, 37, 10, 187, 252, 27, 1, 32, 235, 209, 17, 54, 240, 210, 16, 57, 33, 186, 213, 58, 33, 5, 206, 214, 60, 9, 204, 238, 5, 49, 5, 211, 11, 39, 5, 235, 231, 34, 30, 195, 249, 71, 241, 248, 39, 223, 226, 22, 2, 240, 232, 24, 1, 197, 17, 56, 248, 235, 2, 28, 52, 242, 213, 245, 13, 29, 231, 7, 24, 218, 0, 26, 255, 233, 17, 242, 221, 6, 33, 247, 234, 25, 1, 0, 4, 21, 33, 204, 17, 22, 224, 39, 251, 174, 2, 87, 15, 185, 216, 26, 50, 249, 238, 239, 20, 17, 209, 4, 49, 14, 232, 245, 25, 16, 217, 27, 7, 184, 38, 42, 205, 253, 58, 228, 203, 8, 34, 34, 245, 235, 242, 3, 36, 8, 204, 246, 55, 244, 231, 0, 246, 41, 28, 223, 228, 23, 25, 2, 231, 238, 20, 39, 228, 196, 45, 21, 208, 4, 30, 241, 8, 253, 248, 22, 11, 15, 4, 207, 17, 47, 214, 245, 255, 0, 41, 1, 217, 249, 246, 234, 68, 8, 199, 24, 28, 246, 229, 20, 26, 222, 14, 38, 213, 242, 53, 0, 181, 24, 29, 248, 15, 204, 31, 10, 200, 48, 27, 219, 18, 255, 237, 14, 19, 247, 10, 2, 244, 13, 249, 247, 255, 234, 23, 21, 232, 252, 8, 14, 249, 234, 23, 18, 253, 236, 233, 31, 17, 241, 13, 239, 236, 33, 0, 254, 1, 0, 251, 7, 255, 244, 0, 255, 41, 221, 194, 34, 60, 27, 212, 183, 46, 104, 214, 172, 249, 76, 28, 145, 3, 89, 248, 235, 227, 248, 71, 33, 205, 213, 6, 24, 252, 253, 23, 252, 249, 13, 243, 10, 0, 214, 254, 33, 6, 0, 244, 241, 25, 19, 5, 10, 0, 235, 220, 38, 9, 220, 6, 252, 246, 26, 253, 10, 28, 228, 244, 0, 9, 32, 231, 209, 25, 0, 15, 35, 235, 246, 7, 8, 240, 0, 23, 215, 2, 79, 215, 200, 50, 250, 239, 16, 246, 27, 4, 202, 18, 6, 231, 56, 248, 222, 30, 7, 9, 2, 253, 250, 238, 0, 21, 19, 204, 251, 37, 240, 218, 23, 47, 240, 196, 21, 85, 244, 170, 21, 55, 246, 235, 245, 23, 15, 4, 248, 234, 236, 49, 241, 189, 45, 23, 233, 0, 1, 9, 19, 5, 25, 237, 207, 18, 1, 7, 30, 224, 211, 31, 61, 243, 211, 5, 37, 18, 221, 220, 55, 250, 180, 22, 51, 30, 214, 223, 21, 28, 14, 251, 217, 248, 57, 5, 204, 215, 52, 49, 239, 221, 239, 58, 29, 192, 220, 31, 23, 243, 12, 253, 238, 240, 44, 10, 222, 21, 3, 1, 4, 30, 208, 210, 58, 8, 222, 10, 29, 235, 241, 18, 10, 0, 246, 254, 1, 10, 239, 6, 23, 3, 246, 4, 6, 237, 25, 17, 215, 209, 39, 18, 242, 6, 223, 249, 63, 19, 228, 230, 24, 44, 233, 192, 13, 30, 13, 237, 230, 54, 31, 200, 0, 9, 232, 42, 254, 196, 23, 1, 246, 36, 231, 241, 47, 5, 242, 26, 253, 229, 255, 12, 255, 237, 7, 57, 218, 175, 42, 61, 4, 233, 222, 246, 9, 14, 13, 224, 11, 41, 255, 227, 14, 29, 239, 242, 241, 19, 18, 250, 248, 223, 18, 23, 2, 252, 241, 13, 239, 232, 7, 17, 16, 245, 246, 17, 11, 20, 252, 235, 12, 15, 228, 233, 44, 2, 228, 228, 248, 63, 32, 206, 216, 26, 17, 19, 252, 219, 14, 10, 242, 9, 20, 241, 13, 18, 220, 250, 22, 5, 251, 250, 2, 251, 243, 252, 16, 11, 255, 4, 2, 11, 254, 245, 248, 238, 30, 10, 204, 25, 33, 230, 3, 243, 0, 43, 248, 220, 39, 9, 239, 254, 213, 39, 30, 204, 24, 4, 241, 12, 239, 16, 21, 223, 241, 14, 38, 253, 207, 21, 39, 246, 229, 253, 27, 252, 245, 9, 246, 17, 15, 233, 241, 10, 254, 16, 0, 226, 29, 6, 225, 14, 2, 252, 242, 8, 25, 248, 13, 24, 223, 228, 54, 251, 245, 31, 178, 239, 83, 230, 239, 14, 250, 8, 246, 11, 35, 219, 250, 38, 218, 246, 30, 10, 240, 247, 17, 0, 254, 25, 240, 233, 20, 247, 1, 252, 217, 43, 21, 250, 5, 223, 5, 39, 242, 227, 22, 12, 238, 242, 244, 24, 30, 245, 1, 5, 255, 7, 222, 233, 51, 10, 221, 231, 2, 51, 53, 209, 175, 35, 68, 15, 203, 225, 15, 251, 36, 5, 205, 255, 83, 231, 201, 42, 251, 14, 25, 206, 223, 42, 38, 255, 217, 224, 34, 18, 246, 255, 251, 251, 9, 12, 230, 7, 6, 8, 24, 220, 8, 32, 236, 241, 2, 13, 25, 220, 243, 35, 245, 230, 255, 24, 30, 237, 218, 10, 35, 11, 231, 247, 1, 4, 47, 240, 189, 18, 58, 24, 219, 231, 17, 8, 237, 5, 1, 230, 1, 9, 13, 12, 229, 16, 4, 248, 16, 251, 3, 24, 4, 209, 236, 51, 43, 233, 217, 0, 254, 15, 253, 4, 0, 221, 255, 25, 22, 5, 240, 238, 246, 34, 15, 232, 9, 42, 253, 218, 220, 36, 75, 245, 173, 237, 49, 249, 2, 4, 204, 10, 33, 3, 255, 252, 252, 22, 8, 238, 4, 8, 21, 253, 223, 9, 23, 253, 4, 239, 241, 15, 240, 240, 254, 24, 22, 233, 237, 34, 7, 248, 250, 4, 254, 28, 19, 218, 5, 248, 250, 24, 251, 240, 241, 21, 25, 237, 227, 16, 253, 248, 37, 10, 234, 220, 13, 41, 17, 237, 224, 255, 20, 29, 228, 232, 9, 18, 25, 242, 233, 1, 27, 248, 223, 22, 26, 233, 247, 31, 220, 235, 65, 249, 227, 37, 242, 202, 43, 22, 234, 232, 4, 65, 253, 195, 11, 19, 8, 14, 225, 248, 51, 239, 213, 4, 254, 28, 4, 232, 7, 16, 12, 247, 242, 3, 13, 11, 245, 229, 255, 7, 2, 21, 29, 247, 221, 17, 43, 218, 202, 25, 21, 240, 251, 17, 247, 247, 3, 13, 0, 42, 251, 220, 43, 15, 205, 226, 23, 19, 18, 235, 203, 29, 48, 249, 217, 238, 65, 6, 198, 16, 12, 1, 0, 214, 18, 45, 17, 240, 222, 20, 44, 231, 208, 1, 35, 27, 211, 220, 26, 38, 6, 209, 3, 8, 23, 16, 229, 13, 243, 249, 21, 251, 235, 21, 34, 237, 224, 252, 33, 26, 236, 228, 249, 10, 246, 20, 4, 1, 10, 222, 241, 41, 24, 235, 252, 228, 23, 55, 235, 198, 247, 45, 40, 243, 191, 22, 56, 233, 221, 236, 18, 33, 15, 224, 235, 15, 10, 16, 243, 1, 10, 250, 7, 240, 239, 32, 17, 237, 249, 5, 5, 18, 233, 233, 27, 13, 234, 228, 1, 41, 0, 235, 15, 241, 13, 37, 248, 229, 2, 1, 4, 10, 29, 226, 189, 27, 43, 236, 250, 24, 12, 254, 226, 16, 7, 236, 18, 245, 238, 16, 15, 237, 24, 14, 225, 249, 19, 20, 250, 226, 0, 18, 15, 1, 216, 9, 31, 229, 250, 25, 6, 250, 4, 233, 255, 21, 249, 246, 246, 8, 50, 247, 221, 8, 12, 11, 247, 3, 0, 215, 4, 55, 12, 189, 233, 49, 37, 243, 197, 5, 54, 9, 233, 223, 24, 37, 239, 231, 253, 27, 2, 223, 11, 20, 0, 247, 243, 12, 8, 7, 242, 17, 2, 228, 8, 23, 241, 223, 27, 35, 244, 229, 234, 7, 43, 13, 226, 238, 0, 69, 16, 162, 233, 78, 17, 203, 247, 40, 252, 217, 14, 15, 255, 32, 255, 209, 251, 24, 15, 4, 222, 4, 38, 244, 251, 241, 228, 45, 23, 224, 252, 9, 12, 3, 221, 4, 37, 5, 236, 251, 255, 16, 246, 226, 19, 19, 248, 250, 248, 11, 24, 238, 219, 37, 38, 227, 238, 4, 12, 4, 250, 247, 2, 21, 11, 242, 230, 249, 20, 14, 236, 247, 27, 255, 228, 1, 24, 2, 4, 0, 245, 11, 12, 241, 1, 15, 239, 5, 9, 222, 7, 12, 236, 27, 255, 234, 14, 4, 13, 5, 245, 2, 0, 0, 0, 90, 0, 3, 0, 5, 0, 160, 0, 240, 0, 160, 5, 40, 10, 199, 14, 36, 19, 0, 25, 55, 13, 16, 26, 14, 10, 8, 4, 8, 8, 135, 142, 160, 160, 150, 175, 135, 142, 160, 44, 35, 30, 90, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 160, 0, 240, 0, 160, 5, 40, 10, 199, 14, 36, 19, 0, 25, 35, 17, 18, 29, 15, 11, 9, 4, 9, 9, 135, 142, 160, 160, 150, 175, 135, 142, 160, 44, 35, 30, 90, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 9, 0, 160, 0, 240, 0, 160, 5, 40, 10, 199, 14, 36, 19, 0, 25, 0, 17, 18, 29, 15, 11, 9, 4, 9, 9, 135, 142, 160, 160, 150, 175, 135, 142, 160, 44, 35, 30, 90, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 86, 0, 3, 0, 5, 0, 160, 0, 220, 0, 48, 7, 190, 10, 199, 14, 148, 18, 0, 25, 46, 25, 31, 25, 6, 2, 2, 2, 9, 9, 135, 142, 160, 160, 150, 175, 135, 142, 160, 44, 35, 30, 90, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 160, 0, 220, 0, 48, 7, 190, 10, 199, 14, 148, 18, 0, 25, 40, 25, 31, 25, 6, 2, 2, 2, 9, 9, 135, 142, 160, 160, 150, 175, 135, 142, 160, 44, 35, 30, 90, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 160, 0, 220, 0, 48, 7, 190, 10, 199, 14, 148, 18, 0, 25, 0, 10, 20, 15, 4, 1, 1, 1, 5, 5, 135, 142, 160, 160, 150, 175, 135, 142, 160, 44, 35, 30, 90, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 99, 9, 39, 0, 250, 249, 253, 4, 6, 5, 4, 0, 253, 0, 255, 254, 254, 0, 0, 4, 5, 3, 1, 254, 252, 254, 0, 1, 3, 3, 0, 0, 1, 0, 254, 0, 0, 0, 0, 0, 3, 5, 2, 253, 250, 248, 253, 10, 11, 7, 3, 245, 242, 0, 9, 9, 3, 248, 252, 0, 0, 10, 12, 250, 239, 13, 15, 239, 236, 0, 19, 16, 252, 0, 11, 4, 235, 223, 3, 23, 10, 13, 17, 243, 235, 244, 251, 20, 21, 5, 236, 236, 7, 7, 15, 21, 249, 222, 239, 17, 26, 4, 253, 244, 243, 5, 10, 2, 12, 5, 253, 239, 231, 13, 22, 2, 2, 252, 0, 3, 0, 249, 248, 245, 3, 23, 20, 0, 243, 249, 242, 244, 8, 26, 24, 250, 235, 239, 254, 10, 9, 2, 9, 2, 251, 247, 250, 3, 7, 3, 250, 253, 12, 1, 253, 2, 2, 254, 254, 254, 0, 0, 253, 5, 8, 253, 0, 7, 15, 9, 237, 216, 222, 3, 53, 71, 40, 223, 176, 190, 244, 46, 67, 35, 254, 233, 234, 246, 250, 243, 243, 10, 38, 40, 10, 229, 211, 228, 1, 25, 31, 18, 0, 242, 238, 242, 251, 4, 18, 22, 8, 246, 239, 242, 255, 10, 11, 5, 3, 2, 0, 254, 242, 240, 253, 13, 24, 22, 5, 237, 228, 238, 255, 15, 19, 14, 6, 254, 247, 242, 245, 254, 7, 12, 10, 4, 255, 252, 252, 251, 255, 0, 1, 5, 7, 2, 252, 251, 251, 2, 10, 9, 254, 246, 249, 1, 2, 6, 6, 0, 2, 251, 249, 7, 3, 243, 249, 9, 14, 8, 0, 249, 255, 250, 251, 0, 251, 15, 27, 252, 232, 254, 14, 0, 236, 255, 15, 2, 8, 4, 5, 247, 240, 253, 254, 19, 4, 4, 13, 243, 236, 2, 250, 6, 19, 254, 13, 11, 229, 225, 253, 12, 27, 26, 0, 239, 236, 244, 254, 19, 19, 248, 250, 255, 4, 12, 0, 247, 251, 246, 255, 11, 14, 22, 241, 227, 0, 16, 2, 253, 5, 14, 254, 233, 245, 14, 15, 4, 1, 251, 252, 0, 0, 0, 250, 252, 5, 17, 10, 0, 0, 240, 238, 248, 9, 26, 22, 3, 241, 233, 245, 5, 6, 10, 16, 8, 248, 240, 240, 2, 11, 8, 12, 5, 244, 248, 248, 2, 13, 3, 251, 254, 8, 6, 252, 244, 250, 5, 7, 11, 9, 254, 246, 243, 250, 2, 3, 9, 13, 12, 11, 2, 230, 219, 220, 4, 48, 64, 43, 233, 190, 201, 239, 33, 49, 25, 250, 241, 238, 4, 16, 2, 243, 237, 251, 11, 19, 18, 0, 241, 243, 250, 7, 21, 5, 249, 239, 239, 0, 15, 25, 22, 253, 236, 234, 244, 2, 13, 12, 6, 0, 1, 6, 1, 246, 239, 242, 4, 20, 20, 13, 247, 234, 245, 255, 11, 11, 2, 254, 252, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 253, 0, 6, 0, 0, 3, 0, 252, 250, 0, 4, 1, 8, 12, 2, 241, 239, 2, 7, 6, 0, 255, 8, 8, 5, 0, 244, 235, 253, 11, 3, 12, 30, 252, 222, 247, 12, 11, 248, 244, 13, 26, 0, 219, 242, 28, 15, 255, 15, 254, 242, 221, 231, 52, 32, 248, 246, 250, 17, 1, 226, 234, 16, 33, 0, 239, 255, 15, 21, 239, 224, 0, 30, 15, 236, 236, 5, 25, 250, 7, 18, 225, 239, 20, 9, 255, 0, 250, 249, 248, 18, 27, 0, 244, 9, 233, 203, 24, 41, 249, 14, 30, 250, 208, 234, 9, 10, 15, 12, 3, 244, 7, 16, 238, 219, 0, 36, 11, 2, 6, 239, 226, 4, 16, 16, 22, 0, 235, 220, 232, 25, 41, 31, 3, 226, 222, 237, 22, 28, 252, 254, 0, 253, 5, 13, 10, 252, 224, 225, 14, 41, 22, 0, 241, 240, 241, 0, 15, 10, 4, 255, 253, 253, 0, 7, 2, 242, 245, 0, 21, 31, 4, 236, 235, 232, 0, 30, 24, 253, 246, 250, 255, 10, 10, 4, 248, 221, 221, 3, 51, 72, 29, 213, 186, 209, 0, 42, 50, 18, 240, 233, 245, 7, 13, 2, 245, 240, 251, 14, 23, 12, 250, 241, 243, 254, 11, 16, 7, 247, 238, 244, 2, 15, 22, 14, 254, 236, 232, 244, 9, 22, 12, 3, 250, 250, 2, 5, 255, 243, 245, 2, 14, 19, 12, 254, 242, 239, 245, 2, 12, 13, 13, 1, 247, 245, 247, 0, 10, 8, 255, 253, 6, 252, 251, 7, 254, 250, 15, 17, 249, 232, 241, 1, 7, 19, 33, 6, 222, 232, 5, 253, 247, 17, 36, 11, 241, 240, 231, 248, 12, 39, 9, 231, 250, 1, 249, 1, 8, 9, 3, 1, 252, 237, 246, 24, 15, 249, 249, 250, 22, 18, 217, 228, 29, 8, 253, 34, 5, 229, 222, 237, 34, 36, 1, 244, 255, 241, 243, 255, 28, 30, 240, 216, 12, 24, 253, 238, 233, 27, 33, 252, 247, 249, 237, 248, 33, 8, 208, 7, 49, 8, 245, 250, 232, 246, 24, 248, 7, 8, 249, 10, 1, 247, 1, 7, 1, 8, 227, 215, 26, 53, 25, 234, 214, 255, 21, 2, 253, 6, 243, 231, 23, 30, 2, 248, 235, 4, 7, 247, 255, 7, 248, 9, 9, 253, 9, 9, 242, 231, 244, 13, 27, 15, 10, 238, 214, 8, 24, 2, 3, 8, 247, 235, 4, 23, 254, 243, 12, 10, 239, 246, 9, 12, 0, 241, 249, 10, 23, 5, 246, 248, 244, 242, 3, 19, 21, 13, 249, 237, 234, 249, 18, 18, 5, 0, 253, 241, 242, 7, 18, 6, 255, 7, 10, 247, 229, 225, 253, 35, 41, 31, 0, 216, 209, 235, 13, 32, 26, 7, 253, 253, 249, 247, 249, 249, 1, 9, 17, 13, 251, 243, 243, 247, 7, 22, 13, 251, 242, 248, 250, 255, 7, 13, 14, 6, 247, 243, 241, 249, 9, 16, 13, 5, 249, 250, 0, 253, 246, 249, 6, 20, 17, 0, 245, 244, 241, 254, 16, 15, 244, 2, 29, 6, 216, 228, 23, 33, 250, 233, 7, 32, 249, 235, 1, 5, 241, 254, 17, 14, 12, 255, 224, 237, 9, 23, 14, 253, 12, 231, 212, 12, 58, 16, 230, 235, 9, 4, 227, 255, 60, 254, 192, 25, 56, 5, 215, 209, 247, 38, 19, 4, 20, 9, 243, 192, 1, 55, 239, 3, 28, 224, 249, 5, 252, 42, 27, 214, 206, 12, 16, 4, 37, 243, 233, 3, 254, 19, 19, 233, 234, 7, 0, 242, 2, 38, 44, 230, 210, 253, 0, 22, 250, 242, 12, 8, 29, 0, 233, 245, 245, 239, 13, 25, 26, 12, 211, 254, 19, 230, 243, 10, 26, 18, 244, 0, 21, 233, 214, 11, 1, 0, 28, 51, 4, 198, 248, 4, 224, 243, 48, 43, 252, 235, 13, 250, 205, 2, 20, 17, 6, 250, 23, 16, 225, 204, 251, 42, 33, 0, 252, 19, 238, 195, 242, 42, 28, 18, 13, 238, 231, 242, 235, 13, 50, 6, 232, 251, 255, 6, 5, 7, 244, 228, 6, 27, 32, 243, 201, 5, 55, 0, 216, 1, 27, 243, 242, 255, 8, 30, 20, 240, 223, 246, 255, 3, 21, 17, 7, 244, 244, 0, 7, 251, 248, 5, 253, 2, 6, 5, 8, 9, 248, 240, 1, 0, 244, 254, 15, 15, 15, 7, 242, 230, 242, 0, 15, 19, 9, 253, 245, 251, 7, 8, 249, 242, 1, 14, 4, 3, 1, 245, 253, 0, 1, 8, 5, 254, 0, 255, 244, 251, 3, 17, 21, 254, 231, 238, 15, 10, 254, 4, 0, 0, 4, 0, 0, 250, 247, 253, 10, 16, 7, 250, 252, 245, 241, 9, 25, 8, 248, 245, 245, 2, 2, 6, 25, 5, 248, 230, 215, 21, 50, 4, 255, 8, 218, 243, 1, 0, 29, 0, 3, 20, 2, 242, 233, 222, 240, 34, 64, 21, 226, 246, 9, 212, 207, 3, 61, 57, 20, 224, 186, 252, 28, 10, 1, 9, 245, 245, 23, 16, 248, 230, 249, 18, 6, 235, 7, 31, 5, 251, 220, 238, 28, 23, 248, 254, 13, 236, 245, 38, 12, 216, 237, 18, 2, 15, 24, 246, 237, 1, 254, 247, 2, 29, 250, 231, 16, 40, 234, 206, 9, 21, 36, 248, 224, 22, 249, 220, 12, 45, 4, 227, 235, 254, 58, 17, 189, 253, 36, 231, 235, 28, 45, 254, 207, 225, 39, 53, 236, 230, 223, 249, 45, 18, 253, 5, 237, 249, 10, 5, 239, 242, 18, 37, 242, 222, 29, 5, 225, 4, 34, 0, 232, 14, 12, 224, 226, 252, 48, 79, 248, 177, 235, 7, 5, 15, 13, 23, 236, 215, 29, 50, 241, 213, 239, 23, 14, 237, 16, 38, 244, 219, 245, 5, 21, 21, 3, 244, 235, 243, 12, 255, 0, 36, 3, 246, 252, 253, 248, 238, 243, 13, 34, 16, 2, 249, 241, 232, 252, 12, 9, 12, 3, 4, 242, 239, 13, 23, 9, 237, 232, 247, 15, 25, 10, 248, 250, 2, 0, 238, 239, 9, 38, 23, 244, 238, 243, 240, 0, 17, 21, 10, 247, 249, 1, 249, 255, 1, 250, 0, 16, 11, 7, 1, 234, 231, 0, 27, 25, 255, 243, 246, 251, 249, 2, 21, 24, 0, 237, 238, 248, 9, 11, 0, 5, 11, 252, 246, 12, 3, 239, 236, 3, 22, 21, 248, 244, 10, 5, 231, 239, 21, 25, 252, 249, 6, 249, 228, 0, 41, 17, 238, 238, 7, 13, 236, 246, 5, 13, 33, 254, 231, 222, 255, 41, 33, 251, 226, 231, 3, 8, 19, 18, 236, 250, 29, 245, 239, 11, 1, 240, 243, 3, 13, 46, 23, 223, 234, 233, 239, 0, 31, 43, 0, 215, 9, 32, 239, 231, 219, 244, 47, 88, 7, 179, 207, 250, 44, 32, 251, 6, 13, 227, 196, 4, 62, 50, 233, 193, 255, 40, 1, 242, 9, 242, 255, 8, 25, 18, 220, 218, 21, 41, 220, 255, 38, 249, 13, 223, 212, 38, 26, 255, 3, 252, 246, 0, 9, 242, 232, 3, 32, 39, 14, 252, 204, 166, 245, 125, 18, 231, 42, 7, 201, 209, 251, 0, 8, 42, 75, 252, 192, 228, 235, 249, 39, 47, 1, 240, 253, 243, 205, 244, 62, 54, 246, 237, 252, 241, 218, 248, 43, 8, 2, 6, 12, 2, 244, 250, 241, 246, 250, 9, 8, 28, 17, 241, 0, 254, 239, 235, 244, 21, 27, 0, 2, 15, 255, 218, 224, 36, 43, 0, 240, 226, 245, 0, 12, 30, 16, 10, 249, 235, 223, 233, 8, 38, 50, 253, 215, 243, 21, 248, 236, 11, 32, 10, 246, 231, 228, 6, 26, 22, 20, 1, 236, 242, 233, 225, 3, 38, 52, 26, 235, 223, 227, 234, 12, 27, 13, 2, 5, 3, 253, 248, 254, 253, 241, 247, 15, 29, 15, 252, 243, 238, 239, 3, 20, 14, 9, 255, 245, 246, 1, 5, 245, 251, 13, 19, 10, 243, 249, 9, 242, 226, 2, 34, 32, 0, 235, 230, 249, 31, 3, 245, 14, 237, 242, 28, 16, 245, 238, 250, 30, 5, 244, 255, 248, 247, 0, 7, 18, 10, 3, 9, 231, 223, 1, 34, 4, 227, 12, 34, 248, 250, 12, 240, 238, 238, 7, 31, 9, 10, 249, 230, 250, 19, 9, 18, 251, 203, 3, 33, 241, 240, 48, 45, 209, 233, 3, 19, 245, 202, 251, 59, 30, 12, 26, 227, 188, 237, 11, 24, 43, 242, 251, 21, 240, 235, 250, 18, 15, 254, 255, 238, 227, 27, 35, 0, 227, 253, 34, 253, 247, 3, 248, 223, 228, 38, 35, 31, 17, 229, 201, 0, 16, 231, 252, 21, 33, 27, 0, 248, 227, 219, 0, 3, 7, 25, 62, 252, 194, 15, 217, 194, 67, 80, 15, 247, 222, 187, 214, 8, 87, 67, 8, 234, 199, 218, 252, 250, 7, 36, 61, 42, 223, 195, 201, 242, 17, 47, 59, 27, 216, 213, 244, 247, 11, 249, 8, 52, 41, 218, 187, 255, 30, 243, 2, 36, 33, 238, 208, 252, 20, 3, 237, 1, 32, 18, 0, 235, 233, 251, 10, 243, 9, 40, 8, 255, 235, 227, 244, 9, 25, 20, 251, 249, 2, 250, 252, 252, 243, 15, 21, 10, 3, 247, 237, 229, 246, 17, 34, 38, 15, 236, 222, 222, 228, 251, 27, 62, 52, 5, 227, 203, 200, 239, 36, 55, 24, 253, 246, 2, 247, 240, 245, 249, 252, 5, 35, 29, 0, 235, 232, 241, 250, 14, 30, 20, 244, 231, 247, 1, 7, 17, 15, 250, 237, 3, 9, 247, 237, 0, 19, 21, 9, 254, 254, 235, 224, 253, 31, 25, 253, 2, 10, 246, 233, 246, 21, 11, 238, 245, 11, 29, 4, 251, 244, 237, 253, 22, 255, 238, 10, 27, 253, 245, 253, 0, 252, 0, 15, 5, 234, 2, 18, 244, 251, 12, 9, 5, 253, 248, 240, 252, 13, 1, 253, 6, 27, 41, 206, 177, 26, 54, 239, 235, 56, 16, 215, 232, 6, 11, 11, 251, 224, 27, 37, 7, 193, 255, 59, 240, 201, 22, 13, 243, 64, 254, 211, 247, 20, 253, 231, 2, 22, 254, 7, 32, 9, 247, 188, 205, 79, 62, 195, 0, 59, 222, 203, 37, 30, 230, 218, 45, 48, 214, 215, 7, 15, 1, 33, 234, 253, 69, 242, 146, 214, 42, 103, 34, 220, 229, 17, 216, 181, 13, 109, 38, 203, 232, 39, 253, 197, 1, 247, 250, 74, 64, 224, 198, 247, 3, 228, 197, 91, 124, 195, 194, 8, 248, 237, 1, 12, 36, 29, 229, 224, 7, 8, 241, 4, 9, 15, 30, 246, 211, 239, 14, 9, 13, 16, 14, 246, 239, 247, 253, 6, 245, 255, 34, 14, 231, 242, 11, 32, 253, 213, 228, 11, 37, 34, 253, 230, 238, 249, 19, 0, 13, 14, 224, 251, 11, 248, 1, 13, 14, 19, 2, 233, 223, 227, 4, 36, 37, 25, 2, 235, 214, 230, 11, 20, 2, 0, 11, 17, 6, 2, 0, 232, 212, 240, 20, 43, 38, 7, 241, 232, 230, 240, 3, 17, 22, 15, 0, 254, 246, 242, 250, 2, 5, 7, 19, 2, 236, 250, 8, 251, 249, 8, 22, 10, 236, 237, 254, 6, 14, 21, 0, 232, 245, 10, 0, 254, 12, 8, 252, 253, 1, 0, 3, 254, 238, 248, 18, 22, 0, 86, 0, 3, 0, 5, 0, 160, 0, 220, 0, 48, 7, 190, 10, 199, 14, 148, 18, 0, 25, 46, 21, 29, 23, 6, 2, 2, 2, 8, 8, 135, 142, 160, 160, 150, 175, 135, 142, 160, 44, 35, 30, 90, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 160, 0, 220, 0, 48, 7, 190, 10, 199, 14, 148, 18, 0, 25, 40, 24, 31, 24, 6, 2, 2, 2, 8, 8, 135, 142, 160, 160, 150, 175, 135, 142, 160, 44, 35, 30, 90, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 160, 0, 220, 0, 48, 7, 190, 10, 199, 14, 148, 18, 0, 25, 0, 24, 31, 24, 6, 2, 2, 2, 8, 8, 135, 142, 160, 160, 150, 175, 135, 142, 160, 44, 35, 30, 90, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 86, 0, 3, 0, 5, 0, 112, 0, 112, 1, 248, 8, 233, 10, 169, 13, 14, 18, 174, 21, 46, 7, 13, 26, 4, 4, 5, 4, 6, 6, 92, 165, 137, 137, 150, 175, 92, 165, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 112, 0, 112, 1, 248, 8, 233, 10, 169, 13, 14, 18, 174, 21, 40, 7, 13, 26, 4, 4, 4, 4, 6, 6, 92, 165, 137, 137, 150, 175, 92, 165, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 112, 0, 112, 1, 248, 8, 233, 10, 169, 13, 14, 18, 174, 21, 0, 3, 8, 16, 2, 2, 2, 2, 4, 4, 92, 165, 137, 137, 150, 175, 92, 165, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 86, 0, 3, 0, 5, 0, 112, 0, 112, 1, 248, 8, 233, 10, 169, 13, 14, 18, 174, 21, 46, 6, 12, 24, 5, 5, 5, 4, 6, 6, 92, 165, 137, 137, 150, 175, 92, 165, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 112, 0, 112, 1, 248, 8, 233, 10, 169, 13, 14, 18, 174, 21, 40, 7, 13, 25, 5, 5, 5, 4, 6, 6, 92, 165, 137, 137, 150, 175, 92, 165, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 9, 0, 112, 0, 112, 1, 248, 8, 233, 10, 169, 13, 14, 18, 174, 21, 0, 7, 13, 25, 5, 5, 5, 4, 6, 6, 92, 165, 137, 137, 150, 175, 92, 165, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 139, 8, 23, 0, 246, 250, 253, 247, 254, 0, 13, 9, 16, 0, 13, 6, 244, 3, 251, 250, 246, 246, 243, 250, 1, 0, 20, 24, 26, 12, 1, 245, 243, 243, 241, 241, 251, 247, 4, 5, 12, 17, 14, 13, 10, 1, 2, 250, 253, 245, 229, 231, 248, 251, 14, 18, 8, 13, 22, 12, 19, 15, 248, 228, 233, 246, 237, 227, 0, 0, 243, 19, 47, 54, 27, 249, 240, 246, 16, 235, 212, 208, 237, 16, 7, 250, 10, 53, 52, 30, 252, 250, 244, 255, 213, 203, 226, 253, 0, 30, 41, 18, 2, 6, 34, 17, 230, 240, 239, 246, 0, 240, 240, 253, 8, 7, 4, 12, 30, 31, 15, 251, 229, 230, 232, 245, 1, 13, 0, 2, 15, 6, 7, 250, 6, 17, 0, 2, 247, 237, 252, 247, 250, 253, 3, 14, 12, 16, 10, 17, 1, 233, 239, 240, 243, 243, 5, 13, 19, 16, 15, 4, 254, 6, 243, 242, 246, 238, 0, 5, 16, 14, 252, 254, 254, 255, 8, 5, 14, 8, 251, 254, 247, 238, 248, 243, 252, 6, 7, 20, 27, 15, 1, 2, 232, 254, 248, 240, 253, 252, 0, 3, 10, 13, 6, 5, 2, 0, 1, 0, 3, 245, 250, 0, 248, 252, 0, 252, 12, 5, 255, 16, 5, 8, 0, 0, 0, 246, 244, 249, 246, 250, 255, 4, 23, 14, 12, 9, 9, 4, 241, 239, 233, 245, 243, 253, 10, 18, 12, 14, 18, 10, 2, 247, 0, 0, 236, 236, 243, 237, 242, 4, 24, 21, 31, 31, 22, 16, 1, 242, 216, 200, 199, 220, 246, 31, 50, 53, 69, 51, 26, 230, 198, 209, 224, 238, 218, 232, 255, 14, 21, 25, 62, 60, 49, 54, 252, 215, 154, 167, 189, 193, 224, 36, 96, 91, 84, 87, 83, 246, 170, 166, 170, 170, 138, 232, 53, 96, 98, 72, 72, 50, 4, 224, 195, 182, 192, 180, 198, 247, 31, 102, 103, 52, 18, 0, 240, 244, 215, 196, 217, 250, 13, 7, 251, 5, 23, 32, 34, 247, 253, 10, 255, 4, 246, 230, 238, 252, 244, 4, 0, 234, 9, 39, 35, 18, 251, 245, 7, 253, 243, 228, 252, 0, 254, 251, 247, 254, 2, 18, 31, 20, 20, 1, 254, 244, 238, 216, 243, 5, 246, 239, 255, 27, 40, 36, 20, 6, 249, 250, 232, 215, 220, 248, 251, 5, 34, 24, 31, 22, 6, 250, 242, 241, 249, 246, 229, 236, 255, 10, 28, 14, 13, 5, 12, 7, 5, 243, 240, 239, 241, 249, 254, 251, 11, 16, 17, 16, 15, 0, 253, 252, 245, 239, 240, 253, 0, 253, 9, 7, 14, 12, 13, 3, 251, 0, 240, 241, 3, 252, 6, 250, 252, 0, 13, 0, 4, 13, 11, 1, 6, 248, 247, 242, 250, 254, 245, 3, 0, 18, 1, 11, 15, 6, 11, 247, 242, 252, 241, 252, 238, 255, 1, 7, 18, 22, 9, 1, 0, 6, 0, 248, 237, 241, 248, 0, 254, 13, 7, 254, 15, 13, 13, 250, 244, 251, 247, 4, 16, 18, 0, 236, 235, 238, 249, 241, 246, 20, 55, 73, 66, 228, 171, 190, 226, 232, 13, 53, 40, 16, 6, 4, 3, 234, 215, 208, 12, 28, 31, 37, 26, 249, 250, 10, 224, 205, 214, 232, 6, 44, 32, 24, 23, 29, 12, 250, 0, 223, 227, 246, 230, 233, 248, 15, 23, 9, 11, 21, 10, 12, 17, 32, 255, 1, 250, 220, 206, 199, 224, 236, 246, 16, 76, 112, 54, 31, 24, 27, 235, 139, 131, 158, 218, 251, 40, 74, 85, 89, 84, 59, 5, 190, 179, 172, 165, 179, 237, 36, 73, 89, 67, 50, 21, 232, 221, 202, 198, 236, 251, 17, 20, 21, 5, 14, 14, 4, 248, 239, 255, 3, 2, 248, 247, 243, 7, 19, 0, 18, 7, 15, 5, 246, 223, 229, 221, 248, 16, 33, 40, 34, 19, 7, 236, 220, 233, 239, 228, 251, 7, 26, 24, 35, 6, 249, 237, 251, 4, 1, 0, 0, 239, 244, 6, 255, 12, 2, 6, 5, 0, 10, 3, 240, 238, 6, 9, 0, 4, 255, 251, 12, 255, 3, 252, 248, 248, 1, 9, 3, 4, 14, 4, 250, 250, 251, 0, 244, 0, 255, 17, 4, 251, 9, 0, 254, 254, 8, 248, 1, 252, 0, 0, 3, 254, 1, 8, 10, 255, 0, 2, 243, 243, 244, 6, 10, 7, 7, 16, 9, 7, 254, 251, 239, 232, 240, 241, 2, 16, 45, 25, 21, 252, 0, 251, 217, 220, 233, 254, 4, 19, 19, 31, 40, 13, 23, 223, 210, 214, 243, 240, 228, 30, 57, 51, 13, 234, 1, 16, 237, 235, 232, 240, 12, 245, 226, 251, 41, 48, 24, 3, 9, 2, 0, 240, 207, 214, 238, 230, 226, 75, 76, 45, 40, 25, 15, 188, 143, 168, 215, 12, 59, 94, 90, 55, 6, 224, 185, 189, 216, 222, 246, 12, 46, 82, 52, 24, 242, 229, 217, 231, 245, 239, 212, 12, 40, 22, 11, 253, 8, 43, 0, 246, 255, 243, 232, 235, 233, 246, 5, 3, 19, 33, 28, 20, 3, 2, 243, 250, 245, 197, 209, 7, 24, 23, 27, 17, 27, 1, 4, 5, 242, 235, 238, 228, 235, 242, 3, 36, 51, 25, 20, 251, 250, 233, 231, 239, 237, 238, 2, 19, 25, 15, 23, 13, 12, 5, 242, 224, 227, 240, 239, 242, 23, 42, 42, 0, 254, 4, 246, 1, 241, 228, 242, 248, 11, 18, 23, 9, 248, 244, 251, 3, 13, 4, 255, 0, 250, 3, 254, 254, 242, 247, 5, 6, 8, 15, 255, 1, 5, 7, 1, 249, 233, 236, 10, 21, 8, 0, 251, 253, 250, 3, 3, 6, 3, 5, 4, 10, 251, 248, 247, 251, 250, 3, 0, 247, 8, 21, 5, 2, 6, 248, 255, 7, 251, 252, 254, 246, 248, 243, 254, 20, 23, 6, 10, 10, 0, 245, 246, 235, 250, 251, 252, 9, 3, 11, 17, 13, 6, 5, 246, 239, 243, 249, 2, 2, 7, 15, 21, 227, 205, 249, 47, 44, 13, 16, 23, 252, 198, 176, 239, 21, 249, 2, 22, 59, 49, 22, 10, 255, 234, 202, 182, 211, 245, 35, 47, 29, 13, 20, 46, 22, 242, 215, 225, 241, 249, 240, 218, 255, 29, 43, 30, 5, 238, 6, 23, 18, 6, 242, 203, 204, 253, 27, 10, 227, 0, 47, 63, 46, 6, 219, 192, 211, 240, 249, 25, 45, 36, 11, 253, 226, 248, 251, 239, 242, 7, 18, 29, 22, 253, 246, 255, 214, 244, 19, 23, 17, 242, 233, 239, 0, 14, 26, 3, 1, 22, 12, 243, 220, 248, 11, 254, 244, 242, 1, 3, 19, 12, 2, 14, 22, 7, 243, 239, 6, 250, 248, 210, 214, 251, 21, 57, 49, 19, 12, 7, 249, 246, 226, 218, 231, 230, 0, 8, 10, 25, 36, 34, 30, 24, 0, 235, 213, 196, 195, 253, 20, 23, 30, 25, 31, 39, 15, 2, 228, 206, 225, 233, 243, 5, 15, 23, 25, 25, 17, 8, 244, 242, 242, 238, 240, 253, 254, 9, 3, 8, 17, 15, 19, 1, 243, 250, 249, 241, 249, 246, 250, 2, 0, 19, 19, 17, 14, 10, 4, 247, 230, 224, 236, 247, 7, 16, 18, 12, 11, 12, 13, 246, 247, 2, 250, 245, 250, 244, 1, 0, 4, 7, 252, 7, 7, 10, 9, 6, 5, 1, 251, 247, 252, 243, 231, 247, 0, 9, 22, 14, 19, 9, 245, 255, 12, 9, 237, 234, 250, 2, 4, 254, 247, 238, 253, 12, 25, 0, 254, 35, 45, 31, 224, 228, 238, 214, 190, 209, 4, 59, 39, 58, 51, 43, 7, 237, 212, 200, 212, 227, 245, 230, 10, 39, 60, 80, 50, 6, 199, 184, 180, 246, 21, 30, 52, 56, 252, 196, 243, 246, 253, 208, 250, 79, 39, 254, 238, 6, 11, 4, 230, 234, 230, 246, 43, 22, 9, 233, 210, 235, 19, 20, 56, 40, 16, 248, 228, 232, 231, 231, 242, 242, 241, 4, 21, 29, 33, 36, 43, 0, 243, 239, 251, 220, 192, 219, 0, 255, 6, 26, 42, 44, 57, 25, 0, 250, 230, 208, 205, 203, 224, 3, 15, 25, 39, 52, 32, 33, 23, 4, 236, 206, 205, 216, 221, 220, 24, 24, 34, 52, 48, 42, 16, 254, 231, 210, 179, 214, 250, 248, 20, 36, 27, 55, 42, 23, 0, 221, 191, 218, 231, 252, 8, 21, 33, 8, 22, 23, 17, 255, 231, 227, 229, 250, 0, 1, 248, 18, 16, 21, 21, 6, 253, 248, 239, 247, 248, 240, 240, 252, 12, 29, 25, 16, 4, 0, 239, 239, 237, 248, 254, 4, 9, 21, 15, 6, 251, 241, 246, 248, 0, 2, 1, 7, 15, 4, 5, 255, 252, 240, 247, 8, 8, 0, 242, 254, 0, 1, 18, 17, 15, 13, 247, 241, 245, 243, 226, 233, 4, 14, 35, 33, 35, 18, 232, 234, 229, 230, 223, 251, 2, 19, 21, 65, 75, 233, 214, 220, 186, 204, 7, 54, 28, 31, 39, 44, 18, 214, 206, 203, 215, 185, 29, 81, 80, 55, 23, 232, 168, 183, 0, 42, 42, 20, 7, 254, 220, 204, 223, 23, 31, 37, 42, 42, 15, 201, 221, 220, 229, 217, 243, 58, 79, 51, 251, 0, 247, 200, 192, 213, 253, 25, 57, 66, 44, 30, 26, 2, 173, 139, 139, 201, 31, 85, 98, 113, 98, 65, 206, 136, 169, 188, 203, 195, 245, 61, 100, 88, 50, 30, 254, 222, 211, 220, 242, 222, 221, 255, 17, 12, 0, 12, 49, 37, 13, 8, 0, 233, 225, 222, 235, 250, 4, 17, 21, 15, 251, 238, 251, 20, 26, 16, 14, 4, 247, 222, 226, 232, 245, 252, 3, 16, 45, 53, 15, 250, 245, 223, 235, 229, 236, 249, 21, 26, 34, 20, 1, 238, 237, 239, 247, 4, 15, 11, 4, 11, 4, 245, 240, 236, 244, 4, 30, 30, 5, 250, 251, 251, 247, 251, 242, 250, 255, 12, 23, 16, 5, 248, 243, 254, 255, 0, 0, 254, 1, 252, 246, 7, 12, 7, 0, 5, 5, 0, 0, 2, 251, 238, 244, 0, 251, 9, 13, 13, 17, 10, 0, 252, 247, 236, 248, 254, 242, 255, 18, 13, 7, 15, 7, 6, 243, 235, 254, 1, 1, 255, 242, 4, 23, 12, 6, 233, 227, 13, 23, 27, 0, 223, 238, 17, 8, 248, 16, 17, 248, 224, 216, 251, 39, 53, 29, 1, 220, 227, 237, 8, 41, 0, 238, 251, 242, 218, 252, 33, 45, 48, 251, 240, 254, 248, 229, 234, 253, 240, 254, 4, 12, 15, 21, 22, 26, 5, 250, 242, 0, 238, 229, 218, 238, 8, 244, 254, 41, 63, 62, 32, 254, 246, 223, 196, 170, 199, 221, 7, 58, 113, 86, 39, 2, 1, 223, 181, 180, 208, 221, 1, 33, 64, 58, 46, 36, 38, 229, 171, 206, 214, 233, 255, 28, 30, 34, 40, 42, 28, 223, 207, 217, 215, 212, 242, 46, 54, 68, 55, 18, 225, 206, 205, 213, 219, 225, 21, 53, 54, 68, 43, 17, 219, 202, 195, 209, 239, 11, 16, 28, 30, 27, 42, 9, 239, 233, 233, 241, 0, 248, 234, 249, 250, 24, 25, 25, 24, 27, 253, 252, 227, 218, 228, 236, 240, 0, 34, 41, 46, 43, 11, 236, 234, 213, 206, 233, 244, 10, 24, 33, 36, 28, 10, 0, 247, 228, 236, 230, 241, 11, 9, 11, 2, 3, 7, 9, 6, 13, 0, 249, 1, 248, 241, 247, 250, 252, 7, 6, 12, 10, 17, 1, 239, 247, 254, 4, 255, 253, 247, 9, 23, 9, 3, 250, 235, 237, 248, 247, 248, 12, 26, 46, 26, 251, 237, 240, 248, 236, 218, 249, 21, 25, 28, 2, 240, 230, 5, 15, 30, 2, 2, 24, 251, 217, 213, 252, 5, 9, 4, 22, 17, 220, 242, 15, 33, 27, 49, 43, 204, 174, 202, 248, 29, 236, 244, 12, 32, 39, 44, 26, 24, 10, 232, 210, 201, 223, 217, 231, 6, 6, 48, 90, 77, 49, 254, 208, 171, 181, 204, 1, 17, 32, 57, 51, 18, 245, 1, 240, 221, 225, 241, 243, 241, 54, 66, 28, 251, 255, 218, 217, 227, 233, 248, 25, 24, 26, 43, 39, 21, 245, 207, 211, 203, 227, 246, 31, 72, 42, 27, 253, 239, 231, 239, 245, 242, 251, 230, 8, 42, 40, 26, 248, 222, 235, 250, 251, 15, 2, 1, 253, 253, 0, 13, 7, 248, 253, 7, 11, 18, 13, 239, 222, 217, 245, 7, 25, 16, 19, 9, 16, 29, 252, 227, 235, 224, 239, 247, 10, 12, 25, 27, 13, 254, 0, 252, 248, 249, 237, 242, 11, 9, 17, 3, 252, 254, 0, 0, 0, 242, 255, 8, 9, 7, 7, 251, 4, 6, 255, 250, 247, 244, 248, 0, 245, 13, 9, 14, 19, 14, 0, 0, 253, 243, 236, 8, 5, 0, 255, 254, 6, 253, 2, 3, 252, 251, 10, 7, 250, 251, 0, 8, 252, 253, 252, 5, 0, 10, 8, 252, 249, 0, 95, 0, 3, 0, 5, 0, 112, 0, 14, 1, 96, 9, 24, 11, 116, 14, 132, 18, 174, 21, 50, 6, 16, 16, 7, 7, 7, 5, 8, 8, 92, 165, 137, 137, 150, 175, 92, 165, 137, 44, 40, 35, 90, 45, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 112, 0, 14, 1, 156, 9, 64, 11, 116, 14, 132, 18, 174, 21, 45, 6, 16, 16, 7, 7, 7, 5, 8, 8, 92, 165, 137, 137, 150, 175, 92, 165, 137, 44, 40, 35, 90, 45, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 9, 0, 112, 0, 14, 1, 156, 9, 64, 11, 116, 14, 132, 18, 174, 21, 0, 2, 10, 10, 4, 4, 4, 3, 5, 5, 92, 165, 137, 137, 150, 175, 92, 165, 137, 44, 45, 70, 130, 41, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 255, 10, 12, 0, 26, 20, 0, 44, 51, 8, 205, 214, 4, 227, 231, 197, 61, 250, 248, 60, 17, 8, 205, 177, 211, 6, 198, 41, 41, 248, 35, 44, 252, 19, 250, 141, 190, 234, 239, 22, 8, 36, 50, 8, 4, 223, 209, 231, 202, 153, 24, 15, 39, 81, 25, 176, 31, 31, 159, 202, 200, 19, 193, 33, 94, 217, 12, 59, 205, 231, 13, 208, 210, 203, 59, 83, 222, 75, 17, 220, 82, 226, 220, 30, 252, 236, 22, 29, 71, 35, 20, 69, 232, 253, 32, 2, 227, 237, 10, 20, 17, 71, 18, 233, 21, 25, 192, 234, 251, 229, 222, 23, 39, 35, 233, 225, 245, 15, 179, 225, 0, 215, 216, 30, 4, 15, 205, 242, 246, 244, 0, 218, 18, 4, 228, 215, 255, 22, 45, 248, 23, 51, 10, 220, 205, 6, 33, 222, 50, 223, 240, 75, 6, 253, 55, 8, 243, 208, 48, 231, 10, 41, 58, 12, 248, 8, 208, 4, 241, 38, 207, 234, 15, 233, 26, 32, 44, 9, 186, 18, 36, 175, 9, 23, 223, 240, 43, 230, 14, 24, 229, 254, 221, 251, 187, 212, 34, 18, 19, 255, 242, 62, 21, 221, 217, 205, 225, 38, 193, 235, 97, 212, 192, 16, 238, 222, 237, 208, 246, 17, 186, 17, 10, 236, 8, 232, 246, 234, 215, 223, 220, 241, 10, 247, 243, 11, 12, 250, 215, 201, 239, 227, 238, 253, 236, 188, 42, 242, 213, 20, 7, 24, 204, 25, 6, 163, 183, 79, 32, 9, 9, 3, 20, 228, 223, 196, 35, 21, 203, 245, 50, 68, 237, 167, 249, 38, 254, 189, 219, 56, 245, 187, 247, 25, 0, 252, 17, 25, 182, 222, 218, 215, 45, 225, 176, 31, 10, 231, 182, 246, 246, 250, 172, 252, 43, 206, 198, 28, 32, 219, 239, 173, 208, 236, 212, 210, 230, 18, 241, 214, 57, 14, 187, 179, 231, 62, 221, 175, 39, 24, 237, 199, 213, 31, 16, 220, 237, 0, 237, 8, 2, 29, 247, 241, 59, 185, 4, 40, 253, 242, 22, 30, 210, 24, 22, 6, 255, 13, 24, 241, 228, 16, 33, 164, 23, 63, 190, 239, 240, 239, 1, 16, 31, 240, 212, 39, 203, 234, 71, 200, 9, 221, 230, 12, 204, 4, 5, 243, 19, 217, 217, 20, 221, 220, 10, 14, 233, 223, 12, 19, 0, 26, 38, 248, 213, 232, 250, 51, 222, 10, 51, 247, 22, 252, 10, 5, 236, 233, 247, 49, 26, 212, 232, 255, 253, 33, 214, 240, 42, 0, 227, 224, 44, 1, 227, 28, 29, 238, 56, 23, 228, 232, 54, 221, 236, 51, 14, 17, 245, 56, 20, 237, 18, 68, 252, 0, 62, 0, 42, 12, 4, 230, 35, 67, 47, 34, 20, 19, 219, 34, 254, 230, 22, 69, 25, 5, 229, 29, 6, 253, 205, 41, 235, 34, 85, 184, 216, 17, 24, 240, 87, 0, 233, 182, 4, 28, 253, 14, 254, 6, 4, 247, 210, 14, 244, 3, 216, 255, 58, 239, 233, 244, 36, 62, 225, 203, 15, 16, 218, 227, 25, 20, 11, 7, 246, 40, 237, 201, 30, 76, 217, 14, 4, 213, 68, 45, 247, 1, 37, 11, 0, 242, 29, 10, 14, 255, 252, 59, 37, 1, 19, 16, 206, 33, 3, 250, 36, 211, 80, 33, 24, 29, 33, 220, 210, 34, 53, 225, 232, 13, 12, 22, 7, 38, 0, 226, 17, 18, 215, 16, 252, 247, 250, 245, 9, 24, 235, 220, 17, 238, 211, 218, 215, 210, 38, 1, 7, 24, 30, 248, 200, 225, 211, 11, 5, 13, 4, 28, 240, 40, 243, 1, 21, 236, 204, 34, 3, 239, 0, 70, 2, 209, 30, 227, 206, 226, 224, 15, 255, 240, 229, 20, 219, 245, 3, 241, 226, 23, 246, 217, 40, 248, 0, 238, 13, 253, 8, 246, 237, 229, 23, 252, 0, 55, 231, 230, 49, 9, 239, 1, 234, 1, 248, 0, 28, 233, 17, 218, 209, 43, 204, 249, 31, 236, 0, 228, 238, 4, 220, 240, 53, 221, 211, 223, 255, 250, 234, 16, 218, 9, 228, 15, 225, 205, 56, 2, 180, 20, 16, 170, 197, 251, 24, 252, 235, 231, 232, 223, 252, 217, 3, 41, 203, 230, 3, 14, 4, 178, 242, 48, 0, 250, 34, 243, 0, 242, 223, 249, 66, 42, 177, 5, 100, 233, 205, 238, 6, 251, 240, 5, 247, 255, 20, 255, 236, 12, 9, 228, 211, 238, 34, 6, 218, 2, 15, 29, 7, 13, 224, 227, 16, 234, 13, 7, 237, 14, 9, 217, 22, 7, 223, 219, 8, 247, 180, 5, 30, 31, 244, 23, 247, 205, 208, 19, 238, 205, 16, 0, 239, 20, 25, 214, 20, 3, 222, 230, 7, 238, 238, 15, 13, 68, 0, 20, 218, 9, 239, 13, 12, 242, 1, 222, 16, 1, 55, 239, 251, 10, 1, 250, 233, 243, 3, 236, 12, 61, 246, 240, 243, 17, 6, 250, 209, 239, 27, 14, 247, 0, 69, 230, 229, 9, 12, 231, 20, 205, 249, 54, 200, 7, 1, 8, 238, 225, 23, 243, 242, 48, 249, 163, 48, 241, 5, 248, 18, 239, 30, 214, 1, 27, 226, 1, 16, 215, 27, 27, 217, 251, 244, 29, 248, 241, 232, 30, 214, 220, 248, 25, 32, 216, 245, 5, 251, 227, 212, 3, 36, 211, 206, 22, 249, 19, 229, 213, 32, 229, 236, 214, 42, 13, 243, 6, 221, 218, 41, 51, 198, 24, 240, 248, 28, 8, 213, 9, 1, 246, 250, 250, 0, 11, 247, 195, 38, 18, 213, 212, 13, 0, 225, 5, 49, 211, 1, 232, 207, 84, 216, 204, 245, 28, 212, 1, 18, 245, 237, 230, 247, 220, 57, 224, 195, 237, 29, 245, 184, 30, 29, 222, 231, 222, 37, 2, 180, 3, 241, 254, 2, 209, 5, 212, 245, 224, 6, 250, 13, 218, 30, 9, 209, 10, 254, 24, 231, 1, 27, 225, 238, 36, 185, 78, 24, 217, 251, 9, 3, 10, 202, 244, 47, 212, 251, 241, 14, 240, 252, 2, 243, 236, 205, 2, 234, 242, 15, 8, 194, 225, 16, 28, 247, 249, 228, 222, 13, 7, 32, 233, 241, 10, 225, 0, 74, 240, 221, 224, 251, 51, 203, 12, 249, 2, 254, 10, 233, 28, 215, 3, 245, 245, 5, 224, 246, 252, 20, 202, 222, 244, 249, 215, 251, 251, 15, 237, 195, 13, 1, 252, 230, 239, 38, 212, 186, 239, 40, 19, 233, 214, 3, 236, 219, 250, 239, 14, 15, 208, 235, 247, 58, 215, 243, 255, 26, 242, 199, 14, 1, 242, 2, 0, 218, 237, 30, 188, 27, 15, 224, 226, 19, 27, 243, 233, 18, 224, 8, 9, 198, 255, 25, 248, 234, 20, 243, 222, 1, 38, 249, 237, 3, 242, 239, 203, 41, 2, 193, 12, 217, 215, 250, 2, 199, 3, 34, 212, 228, 9, 22, 193, 184, 53, 8, 214, 33, 208, 222, 12, 19, 213, 11, 31, 221, 252, 0, 221, 212, 252, 246, 22, 224, 22, 31, 222, 212, 45, 10, 243, 229, 221, 8, 34, 218, 223, 23, 43, 214, 239, 16, 242, 244, 253, 232, 217, 46, 250, 224, 19, 53, 244, 222, 255, 33, 202, 7, 225, 243, 234, 14, 254, 227, 9, 47, 218, 237, 10, 209, 4, 15, 12, 208, 234, 35, 244, 246, 236, 55, 211, 205, 223, 240, 4, 247, 251, 35, 17, 198, 4, 4, 51, 214, 226, 222, 254, 224, 253, 246, 0, 25, 231, 12, 252, 224, 214, 22, 185, 38, 231, 234, 22, 251, 224, 253, 38, 247, 220, 253, 20, 197, 225, 0, 24, 254, 229, 37, 4, 203, 245, 2, 6, 242, 9, 12, 189, 13, 22, 27, 23, 243, 11, 28, 224, 192, 235, 12, 19, 208, 34, 236, 9, 29, 239, 0, 33, 191, 43, 244, 0, 8, 228, 24, 10, 3, 241, 15, 247, 0, 222, 228, 239, 242, 19, 247, 243, 0, 15, 203, 250, 69, 247, 186, 15, 211, 247, 249, 29, 7, 22, 232, 249, 4, 17, 3, 255, 201, 1, 20, 222, 247, 9, 15, 246, 217, 239, 41, 244, 196, 4, 235, 24, 14, 219, 0, 8, 245, 242, 22, 251, 11, 243, 244, 211, 0, 14, 203, 216, 18, 5, 233, 251, 36, 224, 247, 240, 251, 7, 207, 19, 11, 253, 255, 237, 22, 16, 240, 253, 0, 248, 3, 223, 225, 40, 29, 244, 243, 5, 15, 250, 240, 238, 23, 248, 244, 17, 231, 245, 19, 0, 248, 243, 225, 232, 253, 234, 226, 246, 17, 16, 243, 238, 242, 224, 45, 224, 215, 251, 242, 253, 248, 245, 247, 7, 220, 2, 243, 227, 47, 199, 230, 19, 232, 16, 12, 210, 29, 231, 239, 254, 233, 15, 18, 241, 193, 255, 14, 240, 4, 19, 234, 235, 14, 253, 238, 13, 236, 11, 19, 210, 13, 11, 221, 27, 0, 227, 248, 4, 10, 230, 14, 7, 226, 11, 7, 215, 49, 10, 224, 2, 208, 21, 25, 202, 247, 6, 250, 229, 248, 0, 253, 224, 234, 248, 5, 224, 237, 237, 240, 236, 243, 211, 8, 242, 219, 34, 22, 207, 234, 224, 3, 231, 245, 23, 224, 228, 30, 1, 216, 253, 241, 253, 0, 255, 219, 197, 254, 52, 220, 219, 19, 243, 249, 232, 245, 255, 211, 13, 234, 236, 6, 14, 233, 213, 40, 2, 201, 249, 21, 218, 230, 28, 5, 206, 254, 16, 21, 240, 229, 11, 181, 227, 52, 226, 250, 29, 7, 219, 196, 50, 20, 201, 13, 3, 207, 24, 187, 32, 26, 207, 21, 2, 240, 21, 214, 32, 233, 211, 33, 25, 232, 251, 34, 240, 239, 242, 25, 33, 249, 207, 243, 13, 46, 221, 230, 65, 8, 219, 233, 3, 23, 240, 241, 22, 223, 13, 4, 202, 4, 29, 233, 219, 15, 28, 224, 11, 237, 213, 7, 243, 6, 242, 9, 247, 222, 5, 20, 31, 204, 217, 242, 14, 247, 220, 6, 7, 246, 240, 226, 10, 0, 243, 3, 246, 213, 40, 6, 224, 10, 8, 0, 231, 254, 242, 31, 242, 242, 242, 47, 240, 206, 29, 26, 23, 207, 6, 35, 234, 241, 238, 243, 28, 233, 225, 239, 18, 2, 255, 11, 11, 247, 235, 214, 23, 39, 218, 23, 232, 250, 0, 234, 7, 13, 242, 4, 22, 247, 254, 250, 2, 1, 206, 13, 3, 21, 223, 16, 255, 27, 247, 234, 8, 230, 0, 5, 254, 247, 8, 217, 0, 16, 38, 223, 231, 7, 7, 223, 247, 252, 2, 17, 252, 229, 225, 5, 33, 233, 235, 255, 245, 235, 0, 241, 7, 252, 237, 29, 239, 213, 38, 222, 242, 48, 226, 239, 15, 235, 38, 1, 220, 20, 10, 235, 249, 234, 31, 2, 230, 24, 251, 240, 249, 230, 2, 242, 15, 250, 253, 0, 223, 3, 251, 240, 22, 247, 252, 6, 237, 248, 255, 21, 222, 13, 247, 236, 0, 249, 10, 10, 205, 18, 13, 251, 2, 7, 253, 177, 2, 2, 214, 30, 227, 231, 24, 209, 3, 3, 240, 245, 223, 6, 29, 219, 245, 3, 250, 23, 252, 230, 242, 225, 36, 223, 239, 8, 246, 1, 249, 231, 11, 242, 232, 32, 226, 2, 26, 242, 7, 244, 5, 248, 14, 3, 249, 4, 241, 251, 8, 250, 238, 23, 213, 19, 9, 249, 234, 241, 23, 0, 230, 227, 29, 2, 218, 222, 28, 244, 11, 6, 239, 22, 248, 244, 4, 0, 5, 253, 252, 9, 226, 245, 0, 234, 31, 247, 234, 17, 250, 8, 222, 12, 255, 248, 220, 28, 6, 224, 254, 20, 221, 235, 52, 236, 230, 233, 248, 2, 250, 7, 246, 233, 21, 8, 225, 226, 6, 240, 236, 23, 250, 254, 242, 244, 6, 252, 10, 0, 200, 12, 21, 220, 220, 29, 15, 197, 252, 41, 249, 238, 249, 237, 3, 2, 2, 255, 231, 28, 247, 224, 247, 8, 227, 9, 13, 251, 251, 222, 4, 18, 214, 7, 24, 240, 211, 29, 32, 249, 227, 249, 15, 2, 222, 223, 49, 243, 242, 252, 228, 13, 14, 218, 253, 254, 237, 233, 235, 0, 254, 234, 243, 4, 243, 15, 222, 207, 36, 249, 199, 29, 0, 234, 1, 228, 250, 30, 229, 249, 220, 253, 5, 217, 11, 252, 254, 3, 228, 224, 9, 255, 245, 2, 202, 244, 255, 249, 227, 2, 244, 0, 0, 245, 240, 248, 247, 242, 6, 254, 232, 236, 7, 249, 28, 252, 214, 13, 11, 209, 248, 21, 245, 225, 26, 248, 251, 229, 245, 2, 23, 234, 238, 0, 0, 11, 222, 252, 48, 242, 211, 239, 11, 247, 234, 4, 3, 12, 241, 221, 18, 14, 7, 217, 225, 252, 34, 229, 242, 35, 235, 254, 251, 29, 220, 12, 250, 237, 0, 9, 234, 247, 247, 237, 26, 23, 231, 244, 0, 249, 10, 221, 22, 3, 237, 14, 9, 244, 11, 1, 233, 6, 248, 18, 245, 21, 234, 4, 3, 0, 31, 243, 226, 8, 246, 243, 18, 224, 16, 19, 243, 16, 246, 251, 30, 20, 23, 227, 238, 12, 2, 21, 12, 235, 32, 1, 250, 5, 0, 58, 225, 228, 5, 254, 34, 5, 229, 36, 12, 7, 250, 1, 16, 4, 249, 7, 254, 251, 27, 15, 230, 236, 42, 23, 234, 0, 19, 255, 10, 1, 252, 7, 250, 21, 3, 232, 20, 252, 1, 14, 250, 254, 252, 248, 251, 255, 12, 9, 242, 252, 4, 17, 11, 231, 230, 252, 33, 232, 246, 46, 226, 224, 0, 9, 26, 229, 28, 16, 232, 6, 30, 239, 245, 11, 10, 18, 250, 5, 1, 250, 251, 17, 6, 207, 254, 0, 4, 241, 252, 3, 34, 235, 237, 9, 37, 234, 245, 22, 222, 2, 22, 11, 234, 26, 19, 243, 248, 253, 250, 243, 236, 12, 9, 3, 1, 236, 243, 25, 243, 253, 236, 251, 31, 220, 244, 25, 250, 252, 247, 244, 15, 253, 249, 237, 9, 254, 212, 245, 16, 249, 230, 237, 4, 10, 237, 253, 250, 8, 0, 229, 230, 0, 12, 224, 2, 7, 232, 0, 248, 232, 5, 4, 240, 9, 240, 244, 248, 231, 4, 7, 229, 251, 10, 214, 251, 5, 230, 250, 242, 230, 239, 11, 26, 219, 226, 6, 1, 239, 236, 250, 253, 255, 246, 231, 4, 9, 246, 251, 242, 3, 249, 209, 23, 0, 220, 246, 246, 0, 33, 212, 242, 236, 246, 10, 226, 246, 251, 241, 12, 242, 1, 220, 231, 254, 1, 238, 0, 246, 214, 245, 244, 241, 247, 244, 0, 0, 239, 11, 238, 228, 9, 242, 0, 242, 223, 22, 225, 253, 17, 241, 255, 255, 226, 247, 255, 9, 244, 220, 25, 21, 244, 247, 218, 238, 27, 253, 233, 234, 244, 10, 229, 235, 8, 9, 228, 250, 246, 4, 19, 240, 228, 252, 9, 2, 253, 221, 5, 12, 245, 252, 249, 1, 240, 14, 249, 247, 0, 247, 237, 233, 1, 5, 242, 3, 227, 243, 10, 237, 246, 227, 1, 0, 253, 230, 235, 7, 248, 217, 8, 12, 236, 244, 238, 249, 250, 242, 234, 7, 1, 7, 231, 239, 245, 16, 235, 244, 11, 255, 231, 242, 18, 239, 245, 4, 255, 0, 254, 222, 233, 246, 239, 234, 9, 2, 237, 232, 253, 1, 255, 245, 245, 254, 249, 251, 222, 230, 0, 32, 236, 240, 35, 242, 237, 250, 252, 26, 0, 241, 14, 240, 251, 26, 231, 240, 16, 246, 249, 232, 14, 7, 232, 13, 255, 0, 4, 255, 239, 222, 245, 23, 240, 232, 23, 31, 239, 238, 243, 0, 12, 244, 14, 7, 0, 0, 230, 238, 23, 247, 254, 252, 0, 2, 232, 10, 243, 14, 15, 219, 253, 27, 228, 249, 242, 23, 1, 234, 8, 255, 11, 250, 229, 4, 5, 244, 9, 249, 4, 1, 1, 254, 248, 0, 1, 10, 252, 247, 242, 253, 253, 19, 0, 253, 2, 249, 242, 236, 39, 250, 235, 255, 18, 10, 253, 247, 245, 13, 2, 238, 245, 23, 252, 207, 3, 28, 245, 240, 3, 12, 254, 226, 2, 15, 230, 242, 3, 254, 14, 248, 236, 252, 28, 237, 240, 5, 255, 248, 239, 0, 14, 252, 248, 244, 251, 20, 231, 250, 8, 1, 244, 240, 0, 0, 250, 240, 244, 15, 1, 217, 232, 12, 0, 229, 246, 12, 241, 4, 246, 229, 23, 0, 235, 239, 4, 9, 233, 223, 36, 233, 233, 18, 249, 242, 0, 2, 4, 13, 5, 231, 239, 2, 6, 239, 9, 10, 245, 233, 6, 14, 232, 254, 251, 249, 235, 249, 1, 1, 238, 248, 7, 237, 250, 6, 0, 235, 250, 254, 222, 243, 14, 241, 232, 9, 242, 244, 246, 242, 245, 6, 7, 233, 248, 0, 3, 250, 240, 253, 8, 248, 245, 7, 235, 0, 250, 238, 12, 12, 252, 247, 0, 95, 0, 3, 0, 5, 0, 112, 0, 14, 1, 156, 9, 64, 11, 116, 14, 132, 18, 174, 21, 50, 5, 14, 16, 6, 6, 6, 4, 7, 7, 92, 165, 137, 137, 150, 175, 92, 165, 137, 44, 40, 35, 90, 44, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 112, 0, 14, 1, 156, 9, 64, 11, 116, 14, 132, 18, 174, 21, 45, 8, 17, 20, 7, 7, 7, 5, 8, 8, 92, 165, 137, 137, 150, 175, 92, 165, 137, 44, 40, 35, 90, 46, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 9, 0, 112, 0, 14, 1, 56, 9, 24, 11, 116, 14, 132, 18, 174, 21, 0, 8, 17, 20, 7, 7, 7, 5, 8, 8, 92, 165, 137, 137, 150, 175, 92, 165, 137, 44, 40, 35, 90, 46, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 52, 9, 14, 0, 253, 13, 2, 250, 242, 3, 5, 3, 233, 238, 32, 249, 238, 9, 17, 247, 8, 9, 232, 33, 236, 249, 8, 245, 5, 24, 4, 253, 7, 241, 30, 2, 243, 8, 17, 237, 255, 1, 0, 12, 241, 6, 18, 248, 2, 249, 4, 20, 238, 254, 12, 3, 17, 5, 4, 255, 252, 32, 245, 3, 9, 250, 25, 6, 233, 10, 41, 227, 234, 29, 0, 228, 8, 246, 0, 6, 228, 1, 9, 14, 255, 232, 6, 250, 240, 14, 255, 13, 237, 11, 30, 7, 249, 14, 244, 254, 248, 7, 2, 240, 32, 12, 222, 22, 16, 246, 14, 19, 242, 7, 252, 246, 9, 249, 241, 10, 241, 251, 243, 252, 1, 253, 237, 244, 244, 53, 227, 230, 2, 1, 14, 246, 8, 253, 17, 15, 221, 27, 7, 240, 216, 8, 28, 226, 221, 18, 253, 17, 225, 224, 21, 249, 237, 201, 50, 18, 197, 13, 12, 246, 0, 226, 244, 231, 238, 20, 224, 14, 233, 220, 7, 33, 204, 224, 25, 5, 208, 240, 255, 227, 16, 250, 237, 246, 24, 233, 206, 1, 10, 207, 237, 21, 227, 0, 253, 217, 223, 12, 251, 222, 218, 35, 254, 183, 30, 253, 242, 243, 233, 6, 244, 221, 243, 218, 26, 231, 169, 51, 255, 215, 242, 14, 8, 193, 225, 15, 14, 202, 241, 241, 7, 231, 219, 213, 245, 246, 210, 242, 4, 253, 203, 216, 253, 247, 235, 193, 15, 4, 243, 219, 254, 221, 221, 1, 237, 252, 246, 241, 246, 5, 203, 237, 2, 248, 239, 218, 246, 0, 22, 227, 238, 7, 202, 242, 17, 170, 245, 5, 201, 236, 17, 187, 252, 238, 6, 237, 206, 241, 207, 251, 2, 215, 8, 225, 210, 238, 2, 228, 235, 224, 227, 23, 228, 203, 252, 24, 225, 229, 221, 247, 248, 253, 211, 237, 0, 247, 210, 228, 36, 228, 208, 244, 33, 211, 210, 11, 212, 231, 11, 0, 212, 11, 223, 0, 224, 224, 19, 225, 239, 222, 232, 252, 17, 221, 218, 40, 229, 241, 4, 234, 229, 0, 255, 231, 255, 0, 235, 210, 36, 1, 220, 13, 223, 233, 30, 8, 247, 250, 4, 7, 235, 250, 18, 16, 234, 211, 1, 13, 33, 229, 220, 55, 8, 236, 247, 5, 243, 229, 11, 20, 255, 2, 237, 5, 4, 247, 7, 253, 219, 25, 0, 18, 30, 246, 234, 15, 8, 13, 239, 253, 7, 240, 246, 30, 219, 249, 28, 215, 234, 49, 226, 254, 240, 12, 242, 211, 12, 74, 186, 38, 13, 206, 15, 18, 239, 11, 244, 16, 16, 220, 18, 42, 9, 227, 8, 246, 2, 30, 238, 237, 46, 237, 243, 27, 15, 247, 235, 252, 229, 12, 255, 233, 11, 3, 240, 24, 243, 19, 2, 239, 16, 19, 231, 253, 53, 251, 242, 53, 4, 229, 34, 1, 13, 17, 249, 0, 254, 11, 9, 9, 19, 236, 31, 4, 4, 244, 4, 19, 237, 2, 237, 2, 50, 249, 229, 245, 16, 0, 236, 6, 40, 226, 252, 23, 1, 244, 24, 43, 245, 214, 59, 2, 226, 65, 223, 219, 254, 34, 8, 238, 7, 247, 208, 53, 48, 229, 192, 32, 18, 251, 18, 238, 2, 255, 23, 7, 219, 254, 22, 249, 244, 245, 218, 29, 18, 232, 12, 8, 0, 0, 246, 6, 255, 252, 211, 239, 47, 3, 233, 253, 8, 16, 254, 248, 232, 9, 5, 248, 253, 255, 15, 17, 219, 23, 27, 0, 249, 234, 231, 44, 252, 215, 228, 16, 12, 236, 16, 214, 1, 7, 194, 8, 245, 235, 232, 227, 40, 237, 4, 241, 243, 6, 1, 248, 240, 2, 31, 228, 227, 40, 239, 241, 4, 242, 238, 41, 235, 198, 57, 230, 252, 232, 236, 29, 4, 242, 3, 217, 9, 23, 233, 4, 229, 0, 239, 246, 25, 226, 223, 38, 0, 202, 1, 17, 241, 231, 247, 24, 249, 226, 4, 229, 225, 13, 3, 0, 255, 35, 219, 216, 58, 10, 185, 29, 255, 238, 16, 251, 254, 237, 30, 247, 236, 252, 248, 27, 254, 232, 51, 0, 11, 5, 238, 7, 248, 237, 241, 9, 66, 201, 251, 45, 207, 246, 244, 241, 235, 251, 3, 235, 14, 29, 245, 231, 252, 1, 10, 226, 30, 238, 235, 232, 0, 22, 221, 215, 15, 7, 249, 233, 16, 0, 214, 7, 36, 15, 224, 232, 40, 1, 251, 35, 225, 8, 249, 233, 233, 3, 24, 235, 5, 33, 252, 226, 11, 226, 67, 184, 230, 5, 11, 1, 8, 221, 1, 26, 213, 246, 21, 222, 210, 14, 2, 251, 236, 24, 227, 0, 26, 231, 26, 242, 230, 0, 8, 49, 233, 194, 75, 30, 229, 21, 236, 248, 248, 249, 238, 18, 26, 223, 7, 23, 245, 214, 19, 254, 237, 213, 36, 236, 227, 41, 237, 250, 236, 6, 17, 241, 199, 28, 241, 213, 53, 212, 14, 48, 216, 3, 29, 203, 3, 27, 253, 218, 2, 2, 244, 26, 239, 247, 253, 18, 34, 218, 6, 38, 222, 228, 45, 14, 229, 56, 202, 16, 30, 238, 253, 225, 6, 24, 232, 22, 9, 203, 30, 225, 9, 241, 233, 5, 252, 14, 241, 235, 11, 11, 4, 210, 7, 6, 251, 226, 17, 254, 44, 225, 245, 15, 238, 9, 249, 21, 252, 21, 253, 172, 20, 57, 197, 0, 21, 17, 15, 217, 2, 36, 23, 227, 41, 252, 241, 30, 30, 213, 39, 242, 0, 19, 254, 1, 245, 27, 224, 29, 246, 230, 27, 9, 213, 14, 9, 20, 14, 253, 250, 29, 14, 193, 37, 18, 223, 16, 17, 20, 31, 229, 226, 66, 10, 236, 19, 21, 0, 34, 21, 231, 31, 15, 207, 26, 246, 3, 251, 249, 5, 16, 10, 188, 44, 245, 242, 214, 14, 255, 21, 247, 21, 210, 27, 54, 191, 46, 241, 238, 8, 27, 231, 42, 15, 244, 20, 249, 39, 40, 0, 207, 11, 35, 228, 7, 6, 31, 247, 21, 234, 6, 237, 0, 0, 230, 7, 29, 202, 59, 3, 224, 48, 242, 187, 41, 216, 38, 225, 226, 64, 208, 239, 19, 246, 20, 242, 242, 247, 6, 15, 247, 224, 42, 237, 247, 32, 220, 48, 220, 210, 34, 2, 232, 12, 216, 12, 255, 219, 5, 252, 38, 40, 186, 1, 32, 210, 223, 13, 29, 240, 213, 39, 232, 31, 190, 234, 253, 15, 245, 209, 19, 227, 234, 21, 16, 245, 226, 9, 247, 228, 252, 236, 226, 251, 15, 227, 13, 255, 0, 230, 7, 9, 213, 218, 253, 8, 223, 19, 250, 0, 229, 14, 237, 252, 228, 218, 252, 24, 232, 195, 51, 0, 223, 252, 53, 223, 236, 248, 10, 227, 203, 19, 255, 228, 9, 237, 230, 13, 239, 240, 225, 202, 27, 224, 238, 251, 248, 247, 247, 252, 233, 238, 10, 226, 236, 18, 231, 226, 21, 12, 232, 217, 3, 23, 213, 208, 0, 15, 240, 185, 26, 10, 227, 244, 250, 1, 251, 249, 219, 240, 253, 246, 213, 226, 29, 232, 207, 1, 225, 217, 247, 242, 222, 215, 251, 48, 216, 237, 247, 240, 241, 247, 241, 222, 252, 237, 249, 239, 252, 223, 238, 44, 220, 235, 10, 227, 219, 254, 248, 18, 224, 248, 250, 14, 30, 213, 245, 21, 235, 236, 234, 26, 245, 195, 12, 4, 193, 26, 5, 213, 246, 21, 241, 221, 246, 243, 254, 242, 252, 241, 236, 7, 36, 172, 2, 36, 226, 206, 17, 15, 222, 226, 8, 239, 255, 218, 30, 227, 236, 2, 2, 214, 225, 8, 7, 224, 248, 29, 209, 238, 21, 224, 243, 243, 0, 255, 7, 21, 243, 238, 241, 15, 222, 229, 243, 22, 222, 222, 4, 27, 244, 223, 9, 253, 251, 250, 233, 22, 2, 225, 239, 17, 232, 233, 252, 236, 22, 1, 222, 20, 255, 245, 219, 9, 7, 12, 218, 0, 18, 240, 36, 237, 248, 0, 11, 246, 7, 220, 13, 238, 23, 244, 11, 44, 199, 50, 249, 235, 225, 252, 14, 246, 247, 41, 1, 255, 9, 247, 25, 228, 241, 39, 207, 29, 27, 240, 219, 41, 28, 240, 163, 43, 14, 203, 17, 7, 221, 40, 3, 232, 42, 225, 253, 233, 7, 53, 226, 235, 24, 13, 0, 246, 18, 28, 12, 8, 209, 29, 21, 237, 1, 252, 24, 255, 10, 11, 13, 246, 18, 218, 253, 10, 236, 18, 252, 16, 2, 248, 235, 21, 247, 5, 241, 244, 15, 9, 246, 241, 242, 58, 1, 230, 6, 235, 24, 32, 224, 250, 3, 15, 27, 223, 248, 39, 234, 208, 35, 0, 244, 236, 32, 1, 253, 238, 3, 32, 251, 244, 12, 252, 6, 234, 237, 31, 15, 0, 248, 38, 237, 251, 15, 223, 14, 2, 20, 243, 224, 38, 248, 243, 13, 219, 6, 8, 238, 251, 250, 6, 243, 1, 11, 2, 232, 0, 0, 32, 6, 229, 28, 233, 231, 254, 230, 17, 40, 15, 249, 236, 253, 0, 23, 29, 206, 0, 15, 252, 3, 231, 244, 16, 218, 247, 39, 228, 237, 25, 249, 28, 3, 239, 235, 249, 27, 227, 9, 35, 237, 232, 55, 231, 239, 1, 245, 232, 38, 221, 253, 14, 247, 47, 215, 245, 4, 238, 217, 253, 4, 238, 214, 48, 12, 240, 255, 253, 235, 252, 7, 227, 4, 2, 242, 11, 252, 15, 244, 251, 1, 253, 12, 214, 237, 252, 6, 5, 231, 20, 249, 26, 233, 229, 9, 9, 240, 213, 10, 255, 213, 247, 49, 220, 238, 22, 218, 249, 13, 210, 249, 249, 17, 6, 249, 20, 227, 14, 234, 23, 237, 188, 55, 236, 236, 9, 1, 249, 0, 254, 251, 238, 24, 244, 223, 242, 34, 251, 223, 42, 219, 40, 39, 183, 51, 22, 206, 243, 247, 25, 246, 244, 10, 245, 247, 23, 235, 0, 252, 8, 194, 207, 77, 202, 245, 33, 6, 7, 245, 249, 249, 11, 206, 9, 32, 227, 243, 34, 27, 243, 253, 236, 33, 238, 214, 252, 49, 216, 245, 246, 55, 7, 203, 246, 47, 253, 197, 216, 14, 1, 191, 31, 18, 237, 8, 251, 0, 0, 219, 33, 231, 210, 49, 32, 228, 21, 241, 4, 0, 225, 252, 2, 203, 53, 5, 183, 70, 51, 202, 8, 244, 27, 232, 221, 19, 204, 4, 11, 231, 219, 14, 4, 252, 9, 2, 237, 239, 220, 41, 231, 248, 12, 233, 31, 223, 13, 45, 194, 246, 36, 225, 0, 13, 239, 227, 20, 22, 14, 216, 30, 234, 243, 15, 251, 209, 4, 48, 229, 211, 71, 8, 228, 33, 10, 200, 15, 20, 219, 241, 16, 13, 235, 216, 48, 242, 215, 21, 251, 220, 40, 13, 195, 47, 253, 235, 7, 27, 235, 252, 7, 248, 228, 39, 222, 246, 22, 230, 1, 243, 15, 243, 225, 25, 11, 230, 0, 38, 224, 244, 40, 32, 204, 23, 234, 29, 237, 36, 222, 18, 17, 229, 45, 15, 240, 4, 255, 243, 15, 227, 0, 11, 16, 0, 215, 24, 16, 226, 229, 45, 245, 241, 14, 246, 17, 31, 218, 29, 253, 255, 216, 37, 26, 199, 230, 29, 3, 250, 37, 233, 226, 48, 24, 195, 11, 19, 18, 247, 244, 236, 24, 241, 6, 247, 25, 229, 185, 30, 34, 247, 242, 17, 5, 205, 15, 21, 239, 4, 5, 244, 236, 1, 5, 212, 11, 58, 199, 21, 16, 243, 29, 218, 198, 70, 240, 228, 63, 246, 246, 216, 28, 18, 224, 29, 243, 238, 0, 203, 34, 38, 235, 246, 25, 248, 7, 37, 203, 245, 56, 230, 194, 1, 38, 11, 220, 7, 26, 2, 214, 32, 218, 240, 5, 235, 254, 23, 251, 4, 4, 12, 247, 250, 244, 246, 2, 215, 14, 5, 245, 19, 246, 26, 237, 216, 54, 7, 194, 51, 11, 241, 250, 7, 9, 238, 30, 15, 237, 5, 0, 17, 195, 37, 40, 200, 27, 33, 240, 43, 229, 253, 6, 17, 230, 223, 65, 232, 205, 60, 5, 240, 37, 255, 32, 22, 222, 5, 0, 8, 242, 3, 23, 24, 11, 236, 35, 7, 254, 234, 236, 50, 241, 220, 74, 255, 238, 0, 17, 47, 191, 229, 55, 219, 249, 18, 0, 26, 9, 16, 53, 191, 233, 2, 28, 9, 0, 239, 5, 10, 223, 227, 27, 58, 228, 187, 69, 14, 192, 4, 245, 222, 17, 4, 23, 36, 219, 221, 12, 247, 246, 1, 241, 233, 0, 253, 254, 223, 248, 6, 204, 250, 24, 241, 16, 0, 242, 24, 233, 242, 24, 174, 52, 4, 200, 253, 13, 69, 177, 174, 74, 186, 244, 248, 251, 217, 25, 6, 215, 241, 19, 178, 2, 19, 203, 245, 28, 206, 244, 17, 234, 10, 239, 236, 218, 7, 243, 211, 21, 237, 225, 243, 231, 35, 173, 205, 29, 208, 206, 23, 249, 245, 213, 242, 12, 213, 245, 230, 28, 232, 200, 15, 7, 243, 210, 185, 30, 232, 199, 45, 231, 244, 24, 200, 186, 44, 240, 195, 49, 176, 223, 63, 222, 201, 194, 30, 23, 134, 208, 124, 151, 239, 47, 178, 241, 255, 245, 224, 255, 48, 197, 249, 234, 254, 11, 230, 232, 75, 149, 11, 48, 201, 244, 14, 33, 215, 164, 12, 241, 178, 57, 252, 192, 253, 1, 252, 3, 194, 244, 12, 243, 210, 224, 249, 22, 233, 10, 5, 183, 21, 12, 245, 212, 231, 31, 56, 152, 70, 47, 153, 54, 24, 212, 221, 15, 39, 198, 11, 68, 238, 189, 113, 197, 189, 53, 250, 245, 208, 31, 223, 234, 34, 210, 174, 42, 25, 206, 10, 194, 224, 37, 253, 213, 0, 56, 240, 6, 240, 199, 61, 253, 186, 33, 19, 3, 20, 18, 7, 31, 242, 252, 247, 250, 38, 249, 227, 14, 56, 212, 242, 233, 216, 232, 30, 221, 212, 242, 21, 252, 220, 248, 218, 9, 5, 245, 227, 253, 15, 248, 1, 10, 13, 223, 224, 19, 225, 0, 26, 235, 242, 69, 224, 228, 16, 245, 11, 212, 241, 32, 252, 212, 23, 239, 0, 17, 250, 5, 245, 195, 10, 23, 0, 250, 205, 14, 39, 25, 29, 16, 220, 196, 26, 41, 236, 25, 17, 255, 230, 195, 55, 45, 221, 204, 215, 10, 32, 31, 0, 0, 183, 241, 46, 239, 33, 41, 237, 232, 234, 248, 17, 73, 0, 219, 8, 251, 230, 246, 16, 60, 26, 222, 250, 3, 205, 1, 253, 62, 46, 197, 226, 51, 47, 188, 175, 251, 106, 38, 204, 203, 245, 81, 15, 200, 5, 37, 242, 246, 227, 203, 10, 31, 7, 29, 9, 20, 227, 210, 42, 0, 230, 46, 10, 250, 245, 241, 235, 30, 241, 4, 73, 248, 250, 241, 182, 217, 23, 45, 21, 19, 2, 208, 207, 7, 50, 24, 21, 25, 252, 249, 239, 1, 4, 13, 42, 244, 202, 254, 32, 39, 0, 249, 46, 193, 221, 6, 225, 48, 4, 184, 219, 45, 6, 219, 250, 240, 255, 237, 28, 242, 6, 18, 3, 7, 238, 16, 44, 26, 250, 248, 16, 9, 5, 19, 49, 32, 241, 255, 205, 250, 35, 27, 6, 243, 24, 4, 197, 181, 229, 33, 40, 250, 225, 244, 238, 237, 230, 252, 4, 7, 251, 238, 28, 19, 240, 19, 32, 247, 27, 243, 238, 26, 47, 45, 235, 202, 215, 230, 46, 76, 31, 238, 23, 212, 211, 1, 21, 37, 33, 250, 10, 208, 188, 225, 32, 11, 66, 29, 178, 168, 211, 31, 77, 39, 6, 207, 207, 18, 21, 245, 8, 54, 37, 191, 235, 44, 43, 254, 236, 14, 37, 205, 198, 55, 7, 250, 43, 36, 202, 132, 20, 88, 44, 205, 219, 38, 11, 205, 219, 67, 44, 1, 176, 184, 77, 68, 238, 210, 36, 11, 190, 239, 33, 41, 250, 11, 34, 224, 236, 251, 31, 34, 240, 200, 227, 26, 19, 7, 12, 30, 16, 211, 223, 29, 19, 248, 26, 248, 254, 29, 232, 188, 227, 62, 22, 235, 5, 9, 24, 253, 206, 206, 38, 79, 56, 219, 185, 2, 251, 220, 36, 40, 37, 201, 189, 36, 29, 239, 240, 50, 19, 203, 226, 20, 46, 224, 248, 3, 6, 58, 0, 209, 255, 248, 251, 24, 249, 209, 2, 90, 25, 233, 28, 242, 192, 3, 49, 21, 12, 230, 212, 0, 6, 0, 254, 11, 38, 231, 187, 235, 62, 45, 228, 23, 27, 195, 214, 31, 27, 9, 253, 206, 239, 32, 35, 32, 247, 199, 250, 1, 8, 34, 219, 240, 254, 222, 64, 22, 222, 220, 23, 39, 20, 255, 205, 3, 24, 1, 234, 19, 55, 27, 2, 235, 44, 227, 202, 7, 48, 30, 15, 234, 222, 252, 218, 19, 31, 255, 238, 212, 248, 25, 243, 198, 244, 22, 9, 22, 232, 231, 232, 5, 47, 49, 0, 213, 193, 248, 68, 53, 11, 247, 255, 239, 243, 34, 11, 17, 81, 213, 187, 58, 16, 237, 12, 15, 248, 227, 244, 17, 41, 7, 210, 175, 239, 44, 29, 17, 216, 219, 229, 246, 17, 31, 40, 231, 215, 7, 8, 18, 14, 42, 50, 181, 201, 3, 255, 30, 39, 7, 211, 243, 3, 23, 28, 28, 191, 251, 48, 244, 5, 241, 4, 27, 253, 241, 40, 31, 195, 210, 13, 38, 28, 238, 207, 231, 56, 33, 5, 209, 207, 40, 37, 231, 250, 0, 228, 241, 15, 9, 0, 17, 253, 16, 19, 238, 212, 6, 55, 16, 239, 7, 232, 235, 61, 21, 243, 237, 223, 228, 16, 46, 238, 27, 9, 192, 12, 247, 14, 37, 5, 3, 218, 203, 22, 38, 247, 255, 239, 252, 240, 4, 18, 5, 8, 37, 9, 213, 251, 6, 15, 39, 246, 237, 20, 251, 232, 4, 11, 36, 241, 203, 236, 29, 49, 254, 227, 242, 23, 14, 4, 244, 251, 18, 251, 238, 232, 10, 36, 236, 226, 244, 243, 27, 53, 247, 234, 210, 245, 10, 26, 14, 5, 9, 242, 188, 253, 85, 59, 1, 222, 224, 246, 5, 42, 30, 49, 227, 183, 7, 6, 225, 42, 33, 1, 251, 208, 206, 4, 21, 3, 24, 250, 236, 237, 246, 18, 22, 1, 251, 240, 12, 49, 30, 242, 230, 216, 23, 53, 211, 234, 48, 6, 208, 234, 3, 40, 11, 213, 44, 42, 212, 217, 254, 29, 16, 29, 9, 221, 221, 251, 11, 0, 25, 23, 221, 237, 22, 255, 224, 5, 31, 220, 233, 15, 15, 11, 24, 0, 245, 18, 2, 234, 254, 29, 41, 237, 247, 0, 250, 1, 39, 255, 197, 242, 40, 53, 248, 223, 239, 19, 233, 209, 18, 32, 1, 255, 197, 0, 51, 247, 4, 254, 1, 0, 234, 237, 0, 14, 10, 4, 228, 2, 30, 25, 242, 0, 26, 236, 219, 14, 83, 24, 225, 210, 248, 37, 48, 250, 205, 15, 19, 243, 255, 249, 16, 5, 221, 218, 35, 242, 8, 44, 241, 249, 243, 186, 253, 61, 53, 3, 217, 222, 202, 239, 49, 34, 27, 247, 255, 15, 207, 234, 66, 35, 244, 255, 212, 213, 7, 71, 74, 236, 208, 230, 0, 5, 51, 28, 244, 238, 208, 0, 22, 2, 240, 8, 252, 19, 12, 232, 229, 231, 254, 26, 26, 1, 231, 4, 13, 0, 1, 250, 237, 17, 38, 6, 227, 7, 249, 246, 14, 20, 247, 226, 248, 57, 16, 214, 21, 16, 254, 253, 245, 0, 7, 238, 248, 26, 234, 253, 33, 203, 224, 20, 19, 58, 5, 185, 255, 59, 9, 217, 247, 249, 3, 13, 9, 233, 246, 37, 1, 232, 12, 7, 2, 11, 250, 14, 248, 254, 3, 7, 249, 240, 46, 4, 238, 14, 242, 252, 223, 6, 16, 248, 13, 248, 222, 12, 35, 7, 246, 236, 235, 233, 13, 29, 253, 248, 21, 1, 249, 6, 27, 32, 225, 232, 249, 9, 251, 4, 30, 44, 233, 220, 19, 251, 4, 243, 247, 29, 4, 212, 245, 36, 9, 0, 247, 207, 221, 1, 60, 67, 254, 180, 231, 11, 44, 11, 248, 249, 241, 23, 248, 208, 39, 63, 254, 232, 233, 16, 12, 233, 30, 16, 3, 248, 240, 251, 10, 9, 246, 1, 22, 240, 224, 253, 235, 245, 20, 27, 248, 249, 24, 225, 235, 20, 6, 4, 237, 227, 25, 65, 1, 229, 8, 229, 226, 10, 32, 31, 255, 217, 14, 28, 245, 18, 252, 3, 12, 246, 255, 13, 17, 12, 236, 199, 0, 51, 9, 5, 241, 220, 246, 236, 250, 45, 24, 229, 240, 219, 16, 32, 238, 12, 246, 240, 14, 3, 1, 19, 16, 9, 241, 209, 5, 20, 249, 33, 26, 239, 8, 239, 218, 9, 16, 11, 45, 7, 247, 205, 4, 50, 236, 254, 26, 8, 250, 222, 199, 11, 49, 7, 1, 253, 226, 224, 25, 32, 240, 232, 24, 22, 225, 242, 28, 24, 247, 226, 255, 50, 254, 201, 252, 26, 43, 25, 221, 226, 3, 251, 229, 37, 21, 237, 232, 251, 44, 240, 241, 12, 2, 233, 247, 53, 33, 238, 235, 8, 19, 3, 222, 250, 65, 17, 188, 196, 14, 71, 43, 247, 225, 227, 246, 252, 26, 13, 247, 2, 252, 240, 26, 252, 238, 226, 0, 51, 3, 239, 240, 254, 25, 9, 243, 26, 2, 209, 0, 242, 10, 62, 247, 217, 255, 6, 3, 2, 0, 27, 6, 237, 232, 3, 35, 19, 14, 236, 210, 3, 15, 247, 13, 19, 3, 229, 1, 2, 9, 250, 233, 33, 1, 4, 7, 209, 12, 33, 3, 236, 3, 6, 217, 244, 31, 26, 34, 242, 207, 245, 4, 41, 4, 229, 0, 0, 248, 255, 40, 0, 255, 243, 229, 255, 7, 27, 16, 0, 242, 235, 246, 8, 25, 10, 245, 240, 6, 245, 249, 255, 7, 22, 40, 18, 202, 210, 50, 20, 253, 255, 235, 9, 31, 232, 6, 10, 252, 3, 235, 18, 11, 220, 236, 242, 27, 32, 247, 220, 14, 50, 237, 209, 20, 24, 239, 1, 26, 223, 253, 21, 236, 244, 34, 2, 247, 22, 1, 236, 246, 25, 6, 247, 8, 227, 0, 9, 9, 4, 250, 242, 239, 26, 15, 254, 6, 242, 6, 28, 4, 0, 10, 228, 239, 13, 25, 3, 7, 243, 232, 22, 20, 232, 235, 239, 240, 5, 254, 4, 11, 20, 16, 255, 186, 240, 67, 31, 252, 244, 0, 240, 241, 248, 7, 47, 28, 204, 218, 40, 18, 250, 252, 3, 1, 21, 6, 7, 31, 239, 226, 247, 0, 250, 0, 17, 5, 241, 219, 15, 28, 253, 235, 12, 5, 234, 253, 246, 24, 33, 246, 233, 249, 16, 244, 7, 16, 248, 3, 12, 232, 239, 20, 23, 23, 3, 215, 217, 28, 48, 3, 255, 249, 230, 252, 248, 253, 23, 14, 27, 253, 211, 240, 7, 20, 41, 240, 228, 240, 12, 3, 255, 0, 10, 8, 229, 244, 17, 8, 40, 8, 197, 220, 38, 39, 16, 233, 208, 13, 18, 241, 14, 11, 238, 13, 239, 188, 9, 74, 70, 236, 196, 244, 9, 20, 28, 4, 252, 253, 228, 233, 17, 1, 29, 0, 254, 252, 254, 6, 242, 33, 22, 227, 231, 3, 253, 244, 25, 6, 248, 209, 0, 14, 248, 38, 5, 221, 246, 18, 230, 32, 49, 234, 254, 242, 225, 5, 9, 36, 36, 230, 221, 2, 238, 0, 58, 53, 2, 215, 207, 5, 32, 37, 13, 227, 235, 251, 228, 28, 25, 230, 246, 246, 248, 9, 244, 227, 22, 31, 251, 231, 234, 28, 27, 12, 8, 228, 235, 253, 9, 34, 24, 7, 229, 236, 250, 255, 57, 31, 209, 227, 253, 240, 16, 39, 27, 246, 245, 244, 224, 245, 21, 38, 6, 234, 220, 245, 20, 26, 27, 255, 202, 249, 24, 10, 4, 6, 0, 244, 235, 252, 13, 30, 253, 245, 12, 8, 244, 234, 12, 16, 8, 7, 211, 227, 35, 36, 227, 220, 34, 22, 1, 255, 218, 242, 30, 39, 240, 242, 1, 254, 2, 250, 15, 6, 26, 7, 246, 224, 228, 28, 11, 16, 255, 222, 244, 247, 18, 0, 9, 252, 255, 12, 245, 1, 247, 14, 12, 7, 253, 227, 246, 24, 44, 245, 249, 11, 227, 4, 34, 7, 245, 12, 253, 215, 4, 248, 5, 33, 232, 246, 34, 237, 202, 9, 36, 15, 227, 228, 33, 24, 25, 4, 227, 238, 253, 245, 13, 19, 252, 7, 15, 226, 224, 8, 41, 56, 235, 214, 246, 5, 11, 15, 5, 234, 6, 253, 237, 11, 26, 1, 5, 254, 253, 223, 250, 36, 38, 5, 214, 222, 7, 14, 18, 7, 243, 242, 232, 14, 16, 1, 1, 251, 1, 0, 249, 253, 26, 7, 223, 235, 29, 28, 2, 232, 0, 1, 253, 255, 19, 4, 255, 248, 15, 1, 250, 8, 251, 9, 3, 242, 21, 2, 250, 240, 243, 17, 10, 248, 15, 244, 229, 8, 15, 251, 1, 254, 1, 8, 255, 252, 251, 251, 6, 250, 6, 5, 255, 229, 234, 35, 28, 243, 254, 4, 3, 255, 1, 21, 234, 239, 38, 24, 240, 10, 251, 219, 12, 26, 255, 232, 246, 31, 18, 220, 241, 12, 33, 5, 246, 241, 223, 255, 10, 2, 22, 0, 216, 9, 22, 253, 243, 255, 1, 3, 9, 4, 0, 250, 1, 26, 255, 255, 3, 15, 2, 8, 242, 252, 24, 239, 222, 18, 39, 215, 233, 17, 239, 12, 7, 254, 1, 3, 235, 4, 29, 252, 245, 250, 16, 9, 241, 255, 3, 9, 236, 17, 29, 237, 226, 26, 40, 245, 240, 239, 233, 35, 25, 252, 233, 232, 231, 10, 18, 6, 12, 10, 5, 229, 207, 6, 37, 36, 8, 251, 253, 244, 241, 8, 39, 34, 254, 215, 211, 2, 3, 21, 26, 7, 228, 234, 8, 6, 249, 253, 22, 5, 4, 251, 253, 243, 3, 16, 246, 255, 6, 240, 6, 12, 251, 250, 3, 0, 242, 239, 21, 52, 245, 241, 22, 9, 240, 236, 7, 249, 15, 17, 0, 253, 246, 229, 240, 43, 255, 223, 28, 251, 0, 15, 241, 235, 245, 3, 20, 21, 253, 243, 243, 1, 15, 255, 253, 7, 13, 15, 5, 254, 248, 240, 9, 21, 11, 2, 253, 248, 247, 252, 249, 242, 15, 10, 255, 8, 253, 202, 240, 24, 29, 27, 250, 232, 246, 250, 10, 22, 8, 249, 243, 244, 242, 17, 12, 20, 11, 240, 243, 232, 252, 21, 14, 13, 27, 244, 215, 247, 8, 34, 8, 230, 0, 245, 16, 20, 254, 239, 17, 244, 224, 16, 22, 20, 0, 241, 250, 238, 241, 28, 38, 251, 244, 237, 252, 21, 241, 239, 242, 22, 32, 240, 240, 249, 4, 3, 245, 5, 0, 0, 14, 13, 241, 252, 11, 247, 13, 12, 254, 253, 247, 238, 11, 42, 8, 3, 243, 242, 231, 4, 28, 248, 0, 25, 2, 232, 242, 3, 20, 13, 237, 247, 255, 243, 0, 30, 7, 245, 254, 251, 240, 7, 8, 25, 19, 209, 227, 34, 16, 251, 248, 0, 5, 0, 1, 14, 2, 227, 241, 23, 16, 234, 249, 23, 243, 252, 6, 18, 24, 5, 242, 232, 9, 4, 4, 13, 0, 3, 229, 237, 4, 30, 18, 231, 246, 3, 3, 244, 15, 18, 231, 239, 0, 19, 0, 246, 2, 24, 247, 253, 10, 2, 3, 9, 249, 229, 7, 5, 7, 16, 1, 252, 252, 0, 3, 3, 250, 1, 4, 246, 247, 251, 30, 9, 241, 0, 239, 254, 28, 246, 237, 12, 19, 248, 227, 255, 26, 11, 5, 248, 228, 3, 18, 251, 4, 11, 245, 246, 231, 252, 34, 12, 0, 251, 251, 9, 0, 253, 12, 13, 252, 4, 1, 254, 254, 4, 19, 239, 1, 20, 231, 250, 25, 5, 246, 242, 241, 5, 8, 6, 5, 228, 220, 2, 15, 11, 17, 0, 247, 243, 12, 15, 247, 244, 0, 15, 12, 7, 2, 238, 242, 251, 27, 27, 249, 230, 7, 6, 247, 6, 249, 13, 33, 253, 249, 236, 255, 23, 1, 20, 19, 236, 215, 238, 13, 23, 22, 0, 229, 238, 6, 240, 12, 22, 249, 2, 247, 240, 229, 246, 24, 28, 16, 252, 203, 247, 29, 250, 20, 24, 248, 234, 240, 12, 14, 0, 15, 23, 247, 255, 0, 8, 13, 2, 12, 10, 255, 240, 253, 253, 253, 9, 8, 254, 227, 243, 11, 5, 238, 13, 250, 216, 8, 25, 0, 254, 250, 0, 1, 245, 9, 1, 250, 18, 8, 6, 8, 232, 11, 49, 245, 235, 246, 3, 7, 7, 10, 246, 8, 253, 2, 17, 250, 246, 11, 0, 0, 2, 236, 250, 246, 249, 23, 253, 242, 255, 247, 7, 8, 229, 245, 25, 13, 254, 247, 255, 10, 22, 6, 244, 7, 255, 255, 2, 24, 9, 243, 247, 252, 9, 15, 0, 244, 4, 19, 249, 253, 0, 238, 243, 1, 5, 10, 0, 242, 252, 251, 244, 5, 6, 251, 251, 8, 1, 0, 12, 17, 15, 246, 239, 251, 254, 253, 25, 4, 251, 248, 246, 0, 5, 6, 253, 23, 23, 242, 239, 239, 20, 12, 4, 0, 248, 254, 12, 3, 253, 12, 234, 239, 23, 23, 1, 235, 242, 5, 9, 242, 248, 252, 252, 4, 5, 3, 8, 230, 236, 13, 9, 15, 2, 236, 0, 11, 19, 3, 243, 0, 11, 6, 11, 246, 244, 2, 1, 28, 12, 229, 243, 4, 6, 13, 4, 255, 7, 237, 3, 18, 243, 252, 9, 0, 255, 19, 9, 229, 236, 255, 12, 14, 245, 240, 243, 3, 13, 247, 248, 17, 253, 227, 11, 21, 242, 253, 253, 6, 12, 0, 243, 14, 30, 254, 0, 3, 3, 14, 253, 245, 1, 12, 1, 241, 4, 10, 252, 12, 14, 250, 236, 242, 6, 13, 6, 251, 240, 235, 1, 19, 18, 7, 232, 238, 0, 245, 0, 27, 2, 241, 5, 0, 240, 1, 5, 10, 7, 249, 248, 8, 6, 6, 7, 1, 0, 254, 247, 7, 30, 8, 244, 252, 4, 5, 5, 253, 254, 253, 3, 5, 5, 249, 225, 234, 7, 23, 24, 4, 231, 243, 0, 241, 248, 27, 24, 244, 2, 12, 250, 240, 242, 8, 18, 18, 2, 244, 242, 245, 2, 16, 17, 247, 255, 5, 255, 0, 237, 5, 21, 6, 251, 238, 240, 3, 26, 12, 1, 252, 230, 0, 20, 9, 254, 4, 0, 244, 255, 7, 5, 10, 5, 255, 244, 255, 2, 10, 6, 253, 253, 254, 0, 252, 255, 245, 255, 4, 249, 218, 249, 36, 17, 2, 244, 242, 252, 0, 10, 33, 19, 220, 230, 11, 42, 24, 253, 2, 2, 0, 46, 9, 29, 0, 245, 5, 245, 248, 27, 12, 3, 237, 249, 10, 249, 0, 42, 31, 0, 236, 243, 19, 20, 13, 255, 249, 34, 33, 254, 209, 229, 4, 22, 34, 11, 232, 253, 20, 249, 230, 21, 50, 249, 249, 10, 252, 10, 12, 252, 8, 13, 9, 26, 21, 233, 242, 26, 20, 243, 231, 16, 25, 251, 3, 5, 242, 4, 3, 12, 3, 250, 20, 13, 247, 221, 2, 21, 8, 5, 252, 45, 36, 204, 221, 7, 24, 43, 33, 6, 246, 241, 5, 10, 10, 24, 5, 250, 31, 3, 239, 4, 241, 15, 30, 239, 7, 4, 251, 25, 253, 240, 21, 18, 246, 244, 243, 26, 38, 0, 250, 240, 14, 19, 238, 232, 19, 56, 1, 221, 240, 246, 32, 51, 10, 245, 230, 239, 35, 21, 14, 7, 0, 19, 232, 234, 8, 250, 11, 26, 13, 254, 230, 236, 255, 0, 32, 29, 5, 25, 222, 215, 10, 28, 14, 1, 48, 8, 228, 6, 13, 215, 0, 42, 14, 19, 8, 241, 240, 6, 14, 23, 25, 249, 248, 6, 0, 252, 255, 255, 17, 31, 3, 248, 221, 1, 11, 253, 35, 5, 197, 249, 38, 249, 8, 2, 236, 32, 11, 243, 233, 244, 12, 11, 1, 51, 26, 226, 11, 254, 229, 4, 36, 23, 3, 22, 5, 225, 237, 252, 231, 58, 68, 232, 210, 1, 14, 24, 31, 231, 227, 238, 46, 43, 223, 251, 15, 15, 5, 251, 11, 3, 8, 1, 253, 17, 2, 251, 245, 3, 243, 253, 37, 15, 237, 255, 14, 227, 231, 12, 10, 5, 5, 2, 255, 250, 253, 255, 20, 30, 27, 246, 0, 24, 6, 247, 255, 238, 11, 50, 11, 252, 243, 15, 15, 246, 4, 10, 17, 13, 20, 255, 230, 237, 247, 30, 35, 30, 255, 211, 198, 245, 0, 27, 67, 252, 6, 0, 206, 226, 29, 6, 17, 50, 11, 239, 215, 244, 34, 25, 28, 40, 238, 213, 9, 242, 241, 64, 0, 3, 56, 230, 212, 229, 36, 39, 15, 9, 227, 42, 23, 227, 225, 13, 38, 31, 9, 241, 7, 219, 30, 12, 195, 25, 44, 237, 242, 6, 217, 12, 51, 238, 236, 255, 42, 243, 227, 254, 247, 61, 40, 22, 235, 239, 9, 194, 14, 95, 51, 7, 254, 197, 247, 42, 218, 4, 59, 66, 0, 217, 229, 204, 25, 63, 20, 250, 221, 2, 17, 244, 236, 253, 38, 49, 253, 234, 23, 222, 227, 42, 6, 246, 36, 20, 219, 11, 14, 254, 34, 236, 215, 6, 31, 50, 20, 240, 236, 231, 15, 42, 251, 4, 35, 5, 247, 236, 2, 13, 250, 46, 30, 216, 2, 7, 243, 11, 2, 252, 15, 1, 19, 253, 215, 23, 36, 245, 10, 20, 0, 6, 251, 250, 29, 35, 14, 251, 242, 229, 6, 57, 14, 10, 11, 255, 252, 239, 24, 11, 246, 24, 4, 227, 17, 3, 2, 46, 244, 223, 35, 16, 226, 253, 254, 0, 45, 229, 21, 37, 220, 250, 8, 6, 30, 248, 243, 50, 7, 222, 28, 17, 1, 23, 5, 11, 17, 239, 236, 20, 34, 32, 243, 226, 238, 21, 8, 236, 12, 21, 2, 252, 7, 253, 242, 229, 40, 37, 246, 24, 246, 251, 16, 0, 242, 239, 19, 29, 20, 10, 12, 18, 227, 241, 13, 2, 35, 60, 253, 209, 254, 40, 19, 234, 14, 2, 214, 32, 24, 223, 5, 30, 10, 234, 255, 11, 251, 234, 21, 0, 17, 6, 201, 17, 56, 19, 238, 0, 24, 232, 246, 11, 35, 13, 225, 243, 29, 236, 229, 18, 6, 33, 44, 224, 245, 230, 8, 65, 0, 248, 5, 248, 229, 18, 250, 15, 72, 10, 206, 227, 15, 3, 8, 19, 244, 14, 8, 20, 2, 215, 11, 12, 245, 6, 23, 14, 242, 3, 24, 238, 221, 62, 94, 222, 215, 235, 236, 16, 31, 37, 35, 240, 222, 9, 21, 240, 246, 8, 10, 17, 16, 247, 1, 240, 200, 36, 72, 23, 230, 242, 2, 230, 225, 17, 40, 236, 21, 19, 223, 248, 212, 239, 62, 3, 229, 16, 255, 245, 14, 39, 27, 228, 227, 26, 21, 241, 29, 45, 245, 229, 20, 23, 241, 14, 0, 7, 28, 39, 232, 215, 54, 9, 220, 29, 58, 253, 227, 11, 237, 248, 30, 239, 248, 53, 17, 203, 226, 23, 30, 6, 10, 3, 232, 7, 3, 228, 232, 40, 53, 211, 233, 36, 231, 241, 4, 247, 64, 28, 221, 246, 7, 15, 4, 8, 252, 21, 46, 21, 249, 227, 6, 23, 33, 28, 252, 5, 253, 2, 232, 251, 14, 14, 44, 227, 224, 238, 228, 26, 242, 22, 10, 6, 6, 231, 222, 10, 36, 3, 29, 251, 226, 10, 232, 221, 25, 69, 44, 13, 223, 200, 248, 35, 50, 36, 5, 24, 18, 217, 219, 250, 43, 58, 15, 32, 5, 228, 210, 251, 48, 25, 35, 29, 254, 212, 228, 248, 12, 22, 13, 20, 15, 231, 236, 242, 17, 12, 251, 24, 7, 15, 234, 245, 254, 11, 255, 5, 32, 254, 13, 240, 6, 45, 244, 240, 242, 249, 55, 28, 11, 228, 218, 20, 50, 247, 225, 31, 20, 228, 25, 39, 248, 248, 249, 250, 25, 40, 251, 237, 23, 25, 17, 207, 237, 59, 6, 232, 15, 40, 241, 240, 21, 244, 239, 245, 8, 28, 30, 6, 210, 233, 31, 7, 204, 240, 35, 72, 41, 198, 245, 6, 246, 19, 22, 29, 1, 7, 11, 0, 8, 222, 13, 48, 20, 254, 230, 29, 6, 252, 25, 244, 3, 9, 229, 8, 52, 243, 246, 27, 225, 211, 6, 63, 41, 241, 234, 10, 215, 16, 5, 216, 42, 50, 249, 249, 244, 234, 247, 20, 33, 16, 10, 9, 3, 202, 243, 62, 31, 231, 40, 23, 237, 239, 200, 11, 65, 70, 18, 244, 240, 5, 238, 220, 47, 43, 16, 13, 247, 202, 216, 28, 34, 22, 27, 9, 245, 215, 232, 250, 64, 72, 228, 11, 12, 224, 249, 12, 9, 246, 32, 31, 20, 10, 240, 227, 238, 34, 239, 236, 58, 93, 18, 130, 185, 36, 252, 29, 51, 0, 26, 240, 211, 251, 241, 11, 52, 0, 29, 16, 213, 204, 10, 28, 254, 45, 34, 16, 12, 211, 215, 244, 25, 68, 71, 4, 232, 251, 187, 204, 54, 96, 24, 215, 228, 2, 220, 204, 39, 54, 0, 48, 12, 167, 208, 255, 15, 93, 72, 224, 201, 214, 226, 45, 59, 9, 19, 10, 9, 221, 218, 22, 239, 8, 58, 49, 0, 229, 219, 18, 20, 238, 33, 245, 14, 30, 253, 225, 236, 51, 11, 238, 13, 34, 233, 220, 51, 5, 223, 246, 18, 50, 0, 246, 23, 229, 213, 25, 22, 252, 29, 35, 221, 219, 231, 245, 250, 10, 73, 61, 234, 227, 224, 235, 18, 40, 49, 26, 248, 220, 217, 255, 24, 32, 55, 10, 4, 195, 242, 77, 239, 241, 40, 31, 7, 32, 234, 230, 253, 216, 10, 72, 7, 211, 255, 5, 222, 237, 29, 29, 243, 251, 9, 197, 241, 64, 4, 248, 44, 240, 198, 0, 37, 15, 27, 31, 221, 250, 12, 229, 38, 26, 250, 39, 27, 253, 3, 230, 245, 65, 254, 7, 14, 207, 36, 13, 206, 39, 23, 237, 19, 199, 8, 75, 202, 239, 44, 250, 3, 10, 232, 245, 3, 15, 44, 6, 249, 216, 230, 58, 18, 197, 9, 65, 8, 0, 242, 12, 248, 246, 52, 34, 41, 5, 201, 240, 22, 21, 64, 10, 165, 0, 23, 3, 11, 249, 244, 178, 22, 73, 226, 227, 0, 4, 254, 251, 31, 11, 225, 10, 5, 232, 17, 60, 28, 244, 19, 245, 11, 245, 236, 60, 55, 19, 234, 240, 251, 7, 23, 255, 35, 34, 0, 0, 247, 232, 222, 20, 47, 81, 251, 206, 14, 244, 229, 235, 3, 67, 40, 196, 221, 44, 251, 230, 23, 41, 21, 236, 235, 21, 43, 6, 16, 22, 20, 242, 247, 30, 26, 4, 230, 29, 33, 205, 13, 22, 0, 25, 255, 241, 12, 9, 26, 7, 200, 252, 9, 247, 26, 20, 4, 18, 244, 228, 32, 14, 239, 41, 22, 11, 2, 254, 229, 247, 26, 13, 17, 229, 243, 21, 18, 49, 3, 175, 231, 58, 32, 245, 251, 252, 250, 25, 15, 14, 11, 224, 216, 17, 66, 25, 237, 26, 15, 198, 247, 56, 2, 246, 50, 249, 207, 31, 253, 4, 47, 4, 236, 5, 32, 22, 231, 206, 4, 31, 4, 42, 22, 203, 245, 249, 44, 251, 213, 16, 0, 39, 249, 0, 32, 255, 221, 220, 48, 94, 9, 184, 6, 18, 216, 14, 27, 245, 255, 39, 45, 246, 197, 221, 222, 40, 76, 251, 32, 240, 185, 7, 19, 21, 31, 4, 10, 30, 251, 245, 30, 5, 21, 248, 196, 62, 61, 224, 228, 249, 248, 22, 28, 212, 234, 228, 6, 47, 7, 243, 225, 215, 254, 41, 241, 6, 36, 213, 27, 76, 241, 210, 7, 2, 22, 55, 242, 245, 0, 14, 43, 240, 10, 46, 239, 246, 24, 248, 223, 21, 33, 2, 74, 251, 142, 217, 65, 83, 35, 232, 201, 223, 233, 41, 60, 251, 40, 18, 208, 216, 211, 246, 48, 51, 35, 18, 231, 0, 240, 211, 36, 36, 6, 24, 236, 239, 13, 0, 198, 251, 88, 46, 12, 224, 213, 246, 250, 47, 91, 242, 217, 24, 208, 206, 22, 42, 87, 16, 223, 254, 251, 244, 1, 250, 26, 55, 235, 226, 16, 21, 4, 0, 14, 5, 249, 252, 26, 228, 226, 50, 15, 14, 19, 211, 219, 247, 241, 4, 26, 242, 21, 8, 230, 249, 254, 249, 242, 7, 255, 43, 245, 253, 33, 226, 23, 252, 25, 22, 0, 254, 210, 21, 40, 35, 27, 253, 223, 5, 251, 241, 8, 17, 98, 28, 195, 240, 253, 213, 245, 72, 42, 27, 244, 201, 230, 4, 47, 28, 238, 242, 229, 0, 29, 252, 207, 228, 48, 58, 247, 249, 37, 219, 224, 17, 249, 17, 27, 233, 244, 38, 15, 245, 21, 241, 223, 239, 61, 50, 211, 239, 19, 11, 252, 30, 229, 213, 51, 248, 237, 56, 255, 207, 250, 1, 19, 33, 27, 38, 188, 212, 88, 249, 235, 56, 30, 231, 238, 249, 24, 28, 234, 8, 28, 17, 19, 246, 223, 9, 18, 237, 37, 30, 7, 241, 229, 10, 252, 53, 46, 223, 223, 235, 0, 255, 15, 31, 45, 15, 218, 4, 224, 236, 40, 70, 45, 14, 244, 198, 233, 20, 21, 6, 48, 25, 218, 220, 14, 35, 24, 71, 17, 207, 201, 2, 25, 1, 22, 250, 29, 58, 215, 212, 0, 221, 1, 32, 8, 48, 244, 213, 4, 23, 19, 245, 237, 34, 41, 13, 21, 254, 213, 26, 40, 224, 8, 74, 55, 241, 230, 238, 243, 30, 43, 5, 247, 15, 55, 235, 202, 3, 232, 1, 117, 63, 173, 208, 25, 16, 243, 249, 49, 42, 243, 8, 237, 234, 18, 0, 228, 39, 72, 247, 227, 214, 219, 40, 54, 10, 31, 50, 248, 212, 207, 11, 31, 45, 42, 5, 251, 241, 217, 234, 48, 52, 37, 253, 217, 247, 255, 7, 6, 30, 0, 12, 52, 213, 201, 43, 251, 239, 60, 254, 236, 252, 250, 6, 4, 15, 30, 230, 232, 25, 254, 234, 39, 19, 193, 0, 7, 13, 35, 45, 10, 174, 212, 40, 56, 21, 20, 0, 201, 250, 40, 19, 40, 31, 186, 224, 29, 6, 7, 6, 26, 16, 241, 6, 8, 208, 221, 15, 42, 39, 0, 194, 238, 18, 233, 221, 19, 52, 47, 254, 205, 223, 247, 2, 15, 26, 237, 249, 23, 246, 19, 7, 29, 3, 219, 45, 13, 251, 21, 42, 29, 11, 6, 210, 242, 71, 65, 249, 14, 46, 245, 224, 247, 35, 10, 0, 4, 9, 235, 234, 247, 233, 9, 239, 226, 8, 0, 255, 238, 240, 214, 18, 28, 194, 227, 23, 31, 251, 236, 20, 237, 184, 29, 86, 22, 15, 227, 205, 34, 72, 21, 8, 20, 23, 13, 242, 0, 31, 29, 24, 252, 251, 242, 254, 9, 34, 40, 240, 212, 27, 15, 215, 14, 56, 227, 211, 48, 0, 212, 4, 5, 16, 25, 12, 237, 203, 253, 28, 0, 252, 32, 15, 236, 251, 201, 233, 38, 22, 39, 11, 239, 245, 251, 235, 1, 24, 28, 34, 240, 223, 9, 13, 29, 50, 28, 26, 247, 219, 248, 244, 42, 63, 32, 28, 234, 209, 231, 218, 3, 92, 75, 1, 206, 188, 239, 250, 29, 66, 19, 240, 222, 210, 249, 22, 248, 32, 40, 246, 235, 249, 16, 214, 227, 25, 38, 25, 236, 246, 0, 23, 15, 13, 243, 243, 16, 12, 5, 25, 0, 3, 26, 240, 255, 42, 15, 251, 7, 25, 6, 22, 0, 235, 5, 245, 16, 36, 255, 249, 0, 8, 25, 5, 233, 246, 238, 254, 35, 17, 8, 248, 236, 0, 0, 20, 0, 0, 22, 30, 255, 9, 12, 233, 18, 24, 28, 237, 196, 248, 13, 15, 25, 24, 22, 16, 239, 230, 1, 13, 30, 17, 253, 251, 4, 16, 0, 230, 15, 29, 242, 19, 34, 235, 244, 2, 8, 10, 4, 246, 234, 18, 13, 4, 10, 15, 33, 17, 251, 235, 231, 2, 28, 24, 38, 13, 227, 224, 0, 11, 7, 24, 28, 27, 0, 221, 210, 240, 32, 56, 33, 253, 226, 252, 8, 11, 10, 234, 24, 61, 15, 224, 249, 2, 253, 25, 26, 19, 247, 242, 242, 236, 5, 30, 32, 14, 1, 219, 235, 5, 244, 252, 21, 44, 3, 250, 19, 248, 241, 6, 7, 26, 22, 253, 12, 244, 225, 18, 40, 27, 15, 253, 7, 0, 239, 254, 20, 15, 8, 9, 2, 38, 21, 204, 223, 6, 8, 12, 36, 21, 9, 241, 240, 245, 213, 18, 71, 19, 236, 250, 10, 244, 251, 5, 14, 32, 18, 10, 232, 228, 27, 29, 25, 48, 1, 220, 239, 243, 236, 19, 34, 7, 3, 0, 252, 0, 0, 105, 0, 4, 0, 5, 0, 146, 0, 39, 1, 52, 8, 84, 11, 196, 14, 124, 16, 87, 25, 40, 11, 7, 32, 14, 18, 14, 14, 5, 3, 106, 132, 143, 128, 135, 147, 92, 162, 137, 44, 35, 35, 90, 45, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 146, 0, 39, 1, 52, 8, 84, 11, 196, 14, 124, 16, 87, 25, 30, 15, 8, 39, 16, 22, 16, 16, 7, 4, 106, 132, 143, 128, 135, 147, 92, 162, 137, 44, 35, 35, 90, 45, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 146, 0, 39, 1, 52, 8, 84, 11, 196, 14, 124, 16, 87, 25, 35, 15, 8, 39, 16, 22, 16, 16, 7, 4, 106, 132, 143, 128, 135, 147, 92, 162, 137, 44, 35, 35, 90, 43, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 146, 0, 39, 1, 52, 8, 84, 11, 196, 14, 124, 16, 87, 25, 0, 15, 8, 39, 16, 22, 16, 16, 7, 4, 106, 132, 143, 128, 135, 147, 92, 162, 137, 44, 35, 35, 90, 43, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 20, 7, 27, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 4, 3, 1, 254, 253, 1, 5, 0, 246, 243, 249, 1, 9, 3, 245, 235, 246, 0, 0, 7, 255, 238, 246, 0, 8, 7, 240, 223, 246, 9, 18, 17, 255, 241, 246, 4, 4, 253, 252, 1, 254, 7, 22, 27, 4, 243, 240, 243, 8, 32, 31, 30, 19, 251, 237, 248, 16, 16, 8, 11, 253, 244, 1, 6, 255, 8, 253, 231, 222, 240, 5, 21, 25, 19, 238, 217, 214, 227, 0, 25, 33, 9, 223, 215, 243, 16, 35, 36, 4, 233, 234, 252, 10, 21, 27, 25, 16, 4, 241, 243, 22, 32, 7, 245, 0, 3, 254, 248, 0, 7, 254, 239, 236, 249, 248, 0, 11, 9, 1, 218, 217, 241, 7, 25, 30, 8, 240, 227, 245, 6, 25, 25, 2, 232, 245, 19, 23, 12, 255, 2, 252, 16, 10, 254, 7, 33, 24, 247, 247, 254, 248, 242, 6, 13, 13, 6, 219, 205, 236, 7, 0, 241, 249, 245, 241, 237, 245, 252, 7, 7, 8, 13, 1, 245, 8, 21, 9, 254, 255, 252, 16, 39, 46, 31, 7, 253, 248, 238, 246, 0, 21, 40, 22, 243, 229, 243, 6, 4, 255, 253, 250, 240, 233, 246, 0, 0, 240, 238, 245, 253, 250, 0, 255, 238, 243, 254, 1, 21, 24, 2, 241, 244, 7, 18, 22, 240, 232, 17, 27, 5, 249, 12, 14, 5, 255, 235, 243, 15, 8, 1, 254, 3, 11, 249, 11, 27, 249, 223, 222, 255, 45, 36, 4, 245, 240, 0, 4, 12, 28, 13, 23, 9, 247, 249, 253, 28, 54, 13, 253, 243, 242, 10, 15, 0, 253, 250, 253, 246, 226, 224, 237, 238, 240, 242, 236, 252, 6, 231, 202, 211, 251, 20, 0, 251, 245, 241, 0, 242, 227, 3, 22, 9, 1, 6, 5, 8, 26, 18, 250, 3, 254, 38, 70, 32, 5, 11, 0, 6, 21, 18, 8, 18, 28, 33, 7, 236, 237, 5, 12, 254, 241, 13, 240, 220, 245, 23, 29, 247, 229, 217, 205, 254, 24, 22, 254, 224, 217, 233, 9, 26, 244, 216, 225, 1, 30, 43, 17, 242, 236, 224, 235, 13, 23, 5, 245, 0, 6, 243, 4, 34, 5, 0, 250, 239, 14, 63, 38, 12, 234, 225, 14, 17, 25, 15, 255, 16, 8, 2, 254, 22, 16, 244, 225, 247, 4, 19, 8, 228, 240, 5, 254, 220, 222, 251, 15, 10, 11, 240, 231, 247, 252, 0, 8, 254, 2, 254, 251, 248, 249, 6, 26, 43, 7, 247, 5, 1, 228, 233, 8, 22, 30, 9, 215, 236, 22, 5, 1, 11, 243, 231, 241, 15, 32, 20, 11, 229, 200, 226, 13, 41, 45, 5, 219, 226, 253, 45, 23, 230, 0, 250, 5, 21, 3, 13, 255, 215, 242, 24, 31, 29, 3, 253, 243, 227, 247, 0, 8, 13, 253, 239, 246, 242, 225, 236, 11, 40, 17, 243, 235, 2, 14, 255, 252, 16, 21, 15, 0, 248, 4, 30, 36, 9, 253, 255, 243, 247, 13, 21, 42, 27, 232, 201, 222, 14, 36, 1, 235, 237, 237, 241, 236, 3, 246, 8, 13, 223, 237, 251, 10, 57, 30, 192, 186, 246, 39, 67, 38, 23, 250, 218, 236, 251, 35, 74, 52, 2, 184, 220, 34, 21, 28, 31, 246, 229, 224, 217, 2, 36, 26, 240, 222, 202, 192, 5, 39, 243, 228, 247, 2, 231, 206, 241, 242, 242, 38, 31, 234, 220, 219, 252, 13, 17, 230, 187, 225, 3, 21, 37, 7, 235, 220, 253, 21, 253, 21, 27, 11, 37, 34, 2, 3, 246, 9, 69, 30, 3, 15, 10, 24, 4, 214, 249, 42, 5, 250, 19, 19, 2, 248, 218, 249, 14, 252, 253, 236, 241, 12, 248, 233, 226, 200, 250, 40, 29, 233, 223, 226, 215, 248, 0, 249, 251, 12, 252, 244, 0, 250, 10, 7, 250, 7, 33, 30, 255, 239, 251, 13, 27, 9, 250, 23, 53, 41, 30, 11, 200, 211, 7, 12, 72, 59, 243, 248, 214, 229, 19, 2, 244, 251, 17, 10, 245, 230, 248, 253, 243, 0, 234, 242, 3, 249, 30, 39, 242, 207, 209, 249, 46, 43, 0, 240, 243, 254, 0, 7, 233, 237, 42, 18, 243, 244, 238, 0, 2, 238, 0, 27, 44, 36, 225, 201, 4, 10, 13, 27, 255, 236, 5, 255, 3, 0, 254, 23, 229, 208, 242, 19, 51, 36, 244, 174, 190, 28, 61, 51, 33, 244, 210, 234, 229, 235, 40, 72, 32, 226, 193, 228, 22, 36, 8, 21, 38, 251, 247, 21, 7, 0, 9, 250, 249, 13, 29, 29, 27, 28, 227, 179, 238, 5, 255, 30, 30, 236, 217, 201, 192, 225, 60, 61, 250, 203, 206, 241, 236, 240, 4, 2, 21, 7, 214, 245, 37, 57, 11, 187, 198, 16, 67, 65, 18, 231, 235, 9, 34, 16, 231, 4, 42, 54, 26, 226, 230, 5, 17, 22, 232, 229, 42, 57, 11, 249, 227, 219, 247, 249, 215, 238, 38, 20, 238, 223, 244, 10, 252, 241, 0, 244, 14, 36, 34, 16, 208, 194, 0, 36, 38, 34, 5, 223, 222, 229, 248, 18, 39, 26, 240, 240, 212, 210, 249, 12, 49, 62, 22, 245, 220, 251, 247, 254, 33, 39, 9, 237, 235, 223, 18, 29, 17, 255, 217, 212, 12, 50, 20, 22, 243, 210, 218, 225, 44, 73, 41, 233, 191, 226, 8, 21, 40, 25, 254, 0, 243, 231, 1, 249, 25, 36, 238, 207, 199, 235, 36, 17, 13, 245, 237, 241, 234, 238, 22, 38, 17, 0, 224, 238, 10, 26, 29, 1, 241, 249, 255, 255, 20, 37, 248, 205, 248, 37, 68, 47, 10, 235, 202, 229, 6, 19, 38, 19, 228, 212, 234, 248, 13, 27, 4, 0, 249, 240, 231, 233, 14, 37, 33, 213, 183, 238, 30, 35, 15, 30, 253, 252, 216, 228, 52, 96, 80, 1, 185, 200, 11, 56, 39, 14, 2, 220, 214, 248, 11, 31, 43, 252, 193, 210, 233, 1, 10, 9, 245, 221, 244, 240, 226, 223, 253, 57, 63, 239, 187, 190, 20, 54, 24, 248, 239, 10, 7, 240, 252, 33, 44, 10, 251, 246, 14, 52, 5, 175, 206, 37, 56, 25, 249, 240, 11, 21, 201, 185, 30, 56, 29, 251, 216, 240, 34, 25, 255, 223, 234, 11, 28, 244, 215, 3, 23, 20, 23, 232, 194, 245, 51, 37, 252, 250, 255, 7, 16, 251, 1, 19, 36, 11, 0, 9, 39, 48, 11, 233, 221, 24, 49, 244, 239, 244, 16, 28, 218, 172, 215, 251, 226, 8, 2, 236, 5, 224, 168, 175, 223, 45, 51, 2, 5, 243, 237, 252, 244, 3, 41, 40, 48, 20, 224, 212, 254, 47, 67, 28, 235, 233, 12, 29, 38, 15, 250, 242, 10, 40, 234, 234, 247, 28, 62, 1, 190, 222, 0, 23, 22, 29, 14, 247, 225, 201, 230, 253, 41, 21, 253, 204, 207, 12, 34, 27, 6, 241, 251, 250, 12, 52, 40, 2, 219, 220, 2, 0, 24, 71, 250, 215, 237, 221, 217, 249, 22, 10, 245, 230, 246, 245, 255, 225, 185, 237, 52, 41, 223, 254, 17, 240, 243, 255, 1, 23, 50, 53, 239, 215, 250, 36, 51, 3, 232, 11, 46, 53, 14, 217, 243, 22, 34, 59, 31, 5, 219, 222, 20, 23, 17, 251, 229, 238, 2, 250, 252, 253, 226, 247, 13, 239, 184, 224, 15, 29, 23, 229, 202, 228, 221, 206, 10, 61, 34, 227, 222, 215, 243, 29, 31, 24, 17, 47, 25, 211, 214, 19, 48, 48, 26, 238, 235, 229, 224, 14, 31, 246, 231, 7, 42, 28, 255, 225, 195, 239, 32, 29, 253, 12, 45, 46, 244, 187, 224, 28, 82, 38, 251, 29, 17, 226, 219, 237, 18, 29, 44, 23, 244, 236, 3, 32, 11, 249, 209, 196, 4, 45, 27, 245, 234, 230, 211, 211, 215, 239, 12, 25, 238, 185, 195, 240, 30, 246, 219, 3, 30, 15, 228, 250, 21, 4, 4, 5, 23, 65, 49, 242, 231, 2, 39, 63, 44, 2, 242, 14, 49, 41, 247, 10, 12, 12, 253, 4, 12, 13, 253, 221, 246, 239, 13, 15, 219, 233, 238, 225, 248, 5, 3, 245, 226, 201, 235, 0, 45, 32, 249, 244, 221, 208, 243, 1, 44, 76, 255, 185, 209, 251, 2, 30, 26, 10, 17, 0, 230, 237, 0, 2, 8, 25, 23, 243, 241, 9, 252, 23, 34, 5, 220, 232, 39, 70, 47, 5, 211, 213, 3, 50, 67, 36, 249, 238, 238, 251, 0, 249, 250, 7, 13, 237, 231, 6, 15, 248, 221, 242, 11, 11, 11, 248, 229, 227, 238, 4, 26, 13, 231, 205, 217, 1, 253, 15, 20, 247, 245, 243, 236, 252, 247, 2, 20, 21, 0, 245, 232, 251, 0, 10, 16, 2, 228, 16, 35, 24, 16, 235, 249, 31, 16, 9, 21, 11, 12, 45, 71, 48, 228, 171, 194, 57, 123, 31, 209, 200, 219, 236, 0, 35, 36, 2, 208, 191, 221, 13, 39, 251, 0, 2, 240, 220, 223, 244, 48, 73, 6, 203, 209, 248, 10, 13, 28, 13, 11, 21, 247, 231, 245, 249, 251, 8, 17, 11, 250, 255, 244, 217, 234, 255, 13, 27, 22, 254, 10, 34, 5, 226, 221, 1, 52, 73, 44, 240, 213, 216, 0, 31, 56, 23, 229, 247, 245, 234, 244, 238, 252, 26, 1, 221, 229, 223, 226, 252, 7, 253, 227, 240, 248, 234, 238, 247, 13, 251, 232, 242, 22, 16, 1, 248, 14, 24, 1, 241, 247, 34, 74, 71, 5, 208, 185, 229, 69, 116, 79, 241, 213, 216, 217, 11, 62, 65, 13, 214, 230, 14, 18, 15, 242, 217, 245, 29, 51, 32, 247, 209, 211, 251, 23, 255, 233, 243, 254, 11, 8, 233, 205, 218, 248, 8, 12, 0, 255, 15, 254, 243, 0, 12, 0, 6, 56, 50, 11, 11, 1, 14, 244, 234, 7, 41, 47, 18, 0, 244, 218, 209, 222, 11, 55, 28, 235, 200, 201, 244, 252, 253, 2, 255, 245, 247, 225, 201, 221, 3, 0, 236, 0, 16, 5, 230, 221, 241, 3, 8, 0, 4, 8, 13, 28, 28, 0, 245, 3, 35, 46, 35, 28, 9, 5, 9, 5, 0, 7, 33, 41, 24, 2, 253, 252, 1, 6, 14, 23, 5, 254, 248, 248, 0, 248, 241, 236, 235, 0, 7, 18, 251, 208, 218, 235, 240, 16, 35, 17, 243, 239, 240, 245, 10, 16, 24, 35, 28, 18, 229, 227, 3, 18, 14, 0, 0, 5, 14, 23, 247, 216, 227, 241, 22, 37, 14, 247, 218, 222, 250, 243, 225, 220, 0, 26, 12, 240, 211, 206, 0, 32, 14, 231, 222, 227, 251, 3, 6, 4, 2, 224, 226, 75, 0, 3, 0, 5, 0, 4, 0, 14, 1, 108, 7, 240, 10, 58, 14, 136, 19, 224, 21, 45, 10, 0, 36, 3, 3, 6, 6, 6, 6, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 30, 40, 85, 51, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 4, 0, 14, 1, 108, 7, 240, 10, 58, 14, 136, 19, 224, 21, 30, 11, 0, 38, 3, 3, 6, 6, 7, 6, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 30, 40, 85, 51, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 4, 0, 14, 1, 108, 7, 240, 10, 58, 14, 136, 19, 224, 21, 0, 11, 0, 38, 3, 3, 6, 6, 7, 6, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 30, 40, 85, 49, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 8, 7, 0, 4, 8, 20, 20, 18, 5, 21, 44, 14, 3, 34, 13, 8, 17, 25, 21, 0, 245, 239, 246, 230, 239, 227, 197, 186, 207, 230, 252, 199, 167, 241, 0, 246, 7, 0, 242, 23, 35, 23, 255, 9, 34, 33, 10, 9, 0, 237, 20, 29, 228, 4, 0, 239, 27, 1, 10, 243, 41, 60, 23, 43, 27, 60, 30, 5, 0, 4, 29, 24, 5, 196, 224, 7, 199, 247, 35, 221, 209, 245, 8, 238, 207, 223, 0, 20, 223, 17, 21, 215, 213, 197, 241, 30, 224, 179, 24, 16, 204, 6, 2, 209, 11, 37, 3, 19, 30, 242, 247, 45, 69, 36, 30, 94, 91, 34, 29, 38, 34, 6, 251, 31, 29, 219, 214, 42, 14, 225, 241, 244, 11, 2, 209, 220, 15, 199, 156, 201, 230, 207, 201, 210, 227, 233, 213, 229, 19, 252, 218, 2, 25, 11, 252, 11, 40, 31, 11, 45, 57, 53, 52, 42, 63, 77, 29, 11, 45, 29, 241, 7, 30, 247, 232, 254, 254, 247, 240, 241, 248, 235, 224, 234, 229, 211, 215, 186, 181, 214, 206, 187, 214, 222, 205, 239, 21, 19, 24, 39, 53, 65, 87, 96, 94, 68, 62, 71, 78, 48, 33, 17, 3, 8, 250, 251, 231, 224, 211, 204, 206, 183, 183, 187, 185, 170, 172, 183, 178, 179, 214, 226, 233, 7, 27, 30, 37, 49, 68, 85, 87, 84, 72, 78, 69, 66, 67, 48, 32, 37, 42, 24, 11, 4, 247, 229, 249, 239, 217, 197, 199, 217, 224, 220, 217, 226, 219, 216, 236, 236, 222, 220, 223, 246, 236, 222, 230, 230, 236, 4, 6, 236, 251, 17, 18, 14, 14, 2, 30, 35, 25, 47, 37, 20, 55, 56, 53, 56, 33, 44, 59, 27, 255, 8, 40, 28, 241, 255, 7, 213, 222, 6, 10, 234, 194, 192, 244, 253, 184, 198, 234, 201, 176, 216, 27, 236, 164, 249, 7, 238, 9, 253, 253, 250, 227, 27, 60, 235, 237, 25, 34, 53, 46, 68, 97, 41, 40, 107, 64, 239, 239, 12, 24, 225, 211, 1, 210, 184, 6, 26, 0, 49, 242, 249, 71, 26, 12, 243, 213, 218, 236, 195, 216, 229, 172, 165, 202, 212, 255, 220, 214, 46, 37, 230, 24, 48, 11, 6, 246, 90, 106, 248, 31, 62, 254, 18, 47, 24, 42, 5, 20, 84, 28, 199, 213, 252, 0, 9, 248, 227, 245, 210, 224, 210, 197, 198, 226, 236, 227, 226, 219, 221, 213, 244, 7, 11, 20, 51, 60, 12, 17, 35, 48, 48, 47, 50, 35, 25, 38, 41, 249, 255, 43, 36, 8, 32, 24, 2, 4, 244, 13, 218, 166, 196, 198, 182, 172, 167, 161, 174, 164, 197, 238, 211, 213, 0, 30, 26, 33, 72, 86, 73, 64, 94, 88, 79, 94, 70, 51, 36, 18, 49, 49, 254, 245, 1, 254, 253, 248, 240, 227, 206, 224, 246, 205, 199, 207, 205, 207, 220, 202, 204, 206, 210, 239, 240, 228, 235, 244, 2, 15, 0, 254, 15, 1, 19, 37, 21, 15, 22, 19, 20, 35, 34, 47, 47, 39, 60, 64, 45, 47, 46, 38, 36, 21, 16, 15, 249, 229, 222, 218, 209, 202, 219, 225, 214, 211, 205, 208, 229, 235, 250, 10, 250, 234, 1, 2, 4, 253, 239, 234, 2, 2, 245, 250, 255, 212, 206, 19, 33, 249, 246, 2, 251, 7, 18, 28, 25, 28, 33, 34, 51, 50, 55, 48, 52, 34, 4, 33, 72, 10, 248, 14, 0, 3, 7, 15, 13, 232, 215, 248, 8, 233, 184, 179, 214, 196, 190, 212, 188, 133, 181, 250, 228, 218, 235, 229, 0, 58, 32, 34, 20, 0, 50, 94, 24, 232, 19, 16, 36, 15, 22, 27, 68, 83, 55, 80, 78, 46, 58, 66, 19, 27, 255, 178, 210, 227, 162, 178, 203, 179, 196, 212, 210, 248, 249, 210, 232, 26, 240, 216, 0, 16, 2, 234, 229, 14, 4, 237, 9, 21, 43, 46, 19, 3, 58, 26, 23, 84, 50, 2, 38, 56, 33, 10, 223, 246, 250, 187, 199, 249, 236, 164, 211, 226, 238, 20, 255, 4, 15, 24, 0, 244, 1, 251, 226, 251, 27, 7, 253, 27, 22, 18, 22, 25, 27, 35, 253, 4, 20, 236, 231, 239, 234, 247, 17, 13, 1, 7, 253, 253, 13, 8, 245, 3, 252, 6, 2, 231, 247, 0, 228, 242, 13, 252, 247, 246, 238, 242, 252, 236, 213, 242, 249, 255, 17, 13, 247, 250, 22, 31, 16, 13, 31, 14, 32, 31, 3, 7, 11, 4, 6, 12, 3, 251, 253, 23, 251, 214, 249, 5, 10, 21, 15, 253, 11, 32, 30, 22, 17, 245, 234, 253, 2, 227, 204, 200, 203, 201, 233, 232, 207, 213, 249, 246, 1, 16, 244, 234, 4, 18, 255, 13, 12, 4, 26, 31, 46, 38, 41, 51, 50, 46, 44, 34, 28, 33, 27, 8, 4, 253, 248, 0, 6, 249, 241, 228, 235, 235, 228, 228, 206, 199, 208, 206, 197, 211, 221, 205, 210, 249, 249, 251, 16, 10, 17, 43, 59, 56, 60, 38, 31, 34, 27, 33, 25, 9, 1, 252, 19, 26, 2, 1, 32, 255, 6, 6, 234, 236, 247, 239, 232, 204, 208, 246, 236, 232, 233, 236, 0, 8, 0, 252, 232, 234, 8, 17, 238, 220, 246, 8, 43, 41, 33, 42, 41, 53, 58, 53, 32, 16, 244, 244, 33, 249, 194, 197, 227, 241, 226, 222, 220, 214, 235, 12, 222, 239, 227, 228, 1, 17, 240, 224, 245, 51, 54, 4, 38, 60, 58, 57, 85, 56, 4, 4, 37, 24, 248, 209, 230, 247, 246, 218, 222, 247, 255, 0, 250, 230, 226, 230, 241, 231, 165, 196, 245, 183, 202, 234, 246, 0, 2, 44, 63, 48, 8, 63, 79, 27, 246, 20, 53, 60, 38, 25, 56, 39, 24, 44, 46, 12, 247, 23, 41, 218, 184, 221, 1, 236, 220, 203, 193, 188, 187, 188, 199, 215, 199, 202, 218, 2, 248, 210, 243, 245, 246, 254, 251, 17, 42, 47, 54, 91, 77, 96, 104, 93, 98, 63, 34, 47, 65, 5, 229, 214, 214, 210, 238, 0, 208, 211, 232, 4, 9, 0, 250, 218, 225, 245, 225, 185, 172, 185, 186, 197, 190, 212, 230, 14, 24, 14, 42, 47, 43, 53, 64, 42, 254, 5, 28, 20, 239, 253, 15, 19, 33, 52, 50, 42, 46, 51, 39, 28, 11, 0, 244, 250, 213, 208, 233, 231, 209, 219, 3, 246, 225, 10, 4, 250, 254, 246, 233, 244, 213, 194, 204, 204, 209, 213, 232, 253, 0, 10, 43, 58, 41, 48, 54, 41, 38, 30, 13, 11, 247, 237, 1, 14, 9, 15, 38, 48, 34, 19, 34, 34, 16, 8, 6, 241, 232, 230, 223, 211, 205, 220, 242, 232, 229, 239, 247, 247, 229, 238, 244, 227, 226, 223, 230, 227, 224, 248, 29, 20, 7, 34, 50, 49, 51, 44, 56, 41, 24, 14, 24, 17, 1, 240, 249, 240, 231, 254, 28, 22, 245, 246, 2, 13, 15, 3, 4, 248, 211, 233, 242, 232, 249, 245, 247, 246, 234, 242, 16, 16, 237, 208, 227, 254, 6, 0, 232, 230, 228, 246, 7, 30, 13, 247, 23, 48, 47, 13, 3, 12, 29, 26, 16, 47, 32, 5, 10, 32, 28, 1, 7, 3, 239, 238, 246, 235, 189, 187, 206, 224, 235, 237, 242, 2, 30, 26, 0, 24, 32, 17, 25, 17, 233, 225, 202, 253, 22, 231, 9, 15, 19, 27, 25, 36, 19, 251, 250, 1, 0, 225, 196, 201, 213, 228, 29, 9, 247, 19, 38, 41, 18, 15, 20, 20, 2, 4, 2, 253, 253, 236, 10, 40, 7, 0, 19, 24, 8, 7, 3, 1, 253, 236, 1, 242, 215, 207, 238, 243, 250, 222, 230, 14, 0, 228, 252, 18, 247, 227, 245, 36, 245, 219, 26, 41, 37, 2, 4, 56, 42, 9, 20, 36, 0, 251, 242, 1, 235, 205, 217, 25, 16, 228, 236, 24, 40, 254, 15, 35, 6, 249, 5, 19, 9, 220, 203, 242, 6, 217, 222, 3, 8, 248, 17, 36, 21, 246, 232, 5, 10, 250, 236, 228, 13, 254, 231, 10, 37, 12, 252, 29, 47, 13, 252, 14, 13, 230, 216, 213, 251, 9, 222, 226, 5, 25, 10, 8, 31, 33, 9, 24, 48, 5, 241, 239, 4, 234, 220, 215, 247, 7, 0, 254, 20, 20, 1, 11, 20, 11, 250, 239, 1, 7, 231, 223, 233, 230, 255, 14, 23, 23, 28, 19, 29, 39, 254, 240, 248, 245, 220, 208, 210, 221, 219, 227, 249, 4, 8, 33, 46, 57, 55, 26, 25, 36, 29, 254, 247, 250, 243, 245, 0, 253, 241, 253, 21, 20, 12, 1, 250, 241, 247, 236, 215, 212, 207, 208, 224, 232, 247, 255, 2, 24, 32, 32, 32, 26, 28, 28, 18, 5, 1, 247, 0, 244, 0, 24, 12, 8, 34, 29, 10, 9, 255, 252, 9, 252, 231, 217, 223, 233, 221, 232, 241, 236, 245, 25, 42, 22, 10, 22, 14, 243, 252, 237, 238, 240, 220, 215, 230, 250, 247, 19, 42, 33, 49, 44, 49, 37, 6, 223, 250, 253, 228, 251, 245, 243, 243, 6, 24, 21, 14, 18, 17, 254, 9, 14, 243, 221, 245, 252, 238, 251, 12, 248, 247, 244, 245, 248, 242, 235, 217, 230, 238, 247, 3, 14, 243, 222, 5, 40, 33, 22, 20, 22, 22, 37, 39, 21, 0, 17, 22, 27, 29, 3, 248, 253, 235, 214, 240, 9, 3, 252, 232, 240, 252, 222, 236, 12, 241, 231, 251, 11, 7, 244, 238, 245, 239, 250, 6, 254, 252, 240, 242, 13, 20, 2, 10, 32, 42, 24, 15, 17, 22, 244, 243, 7, 7, 248, 239, 10, 21, 15, 6, 0, 26, 20, 20, 21, 15, 253, 224, 223, 249, 239, 207, 219, 232, 240, 232, 233, 245, 249, 253, 0, 0, 12, 1, 0, 19, 16, 245, 240, 255, 19, 9, 11, 19, 16, 17, 23, 29, 32, 36, 26, 16, 21, 6, 6, 255, 238, 239, 237, 230, 237, 240, 229, 241, 251, 0, 252, 246, 238, 245, 249, 240, 238, 236, 227, 240, 252, 2, 9, 14, 12, 33, 39, 26, 25, 27, 23, 25, 15, 4, 252, 243, 255, 3, 252, 254, 254, 252, 3, 4, 0, 251, 244, 248, 244, 240, 237, 236, 239, 249, 252, 254, 8, 9, 7, 11, 5, 2, 3, 1, 2, 255, 251, 0, 3, 2, 7, 4, 13, 16, 17, 12, 10, 9, 3, 0, 255, 254, 253, 240, 238, 240, 247, 251, 253, 250, 251, 249, 248, 5, 11, 0, 246, 252, 254, 251, 253, 3, 5, 255, 7, 16, 18, 14, 8, 9, 6, 7, 5, 0, 1, 2, 1, 254, 4, 250, 248, 3, 4, 6, 3, 0, 253, 0, 251, 255, 0, 251, 249, 251, 249, 241, 245, 247, 242, 245, 248, 254, 8, 9, 1, 2, 9, 6, 7, 4, 1, 3, 2, 0, 4, 6, 5, 5, 12, 15, 16, 17, 12, 7, 11, 2, 2, 2, 252, 248, 249, 248, 248, 245, 239, 245, 251, 252, 248, 251, 252, 252, 247, 245, 255, 254, 252, 251, 248, 1, 3, 2, 6, 12, 7, 3, 8, 16, 14, 8, 8, 12, 12, 12, 4, 6, 10, 2, 0, 1, 254, 250, 247, 249, 254, 251, 247, 248, 254, 252, 248, 248, 254, 249, 246, 250, 1, 255, 252, 252, 3, 9, 6, 4, 5, 7, 10, 6, 4, 3, 3, 0, 1, 2, 1, 0, 3, 3, 0, 0, 6, 8, 6, 5, 1, 255, 252, 249, 253, 255, 253, 250, 250, 251, 252, 252, 0, 255, 0, 0, 0, 2, 3, 2, 0, 0, 254, 0, 1, 1, 3, 3, 2, 3, 6, 5, 7, 5, 2, 0, 0, 255, 0, 0, 252, 252, 253, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 255, 255, 255, 0, 0, 255, 0, 255, 0, 1, 2, 2, 1, 3, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, 3, 0, 5, 0, 4, 0, 14, 1, 108, 7, 240, 10, 58, 14, 136, 19, 224, 21, 45, 10, 0, 36, 3, 3, 6, 6, 6, 6, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 30, 40, 85, 53, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 4, 0, 14, 1, 108, 7, 240, 10, 58, 14, 136, 19, 224, 21, 35, 11, 0, 38, 3, 3, 6, 6, 7, 6, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 30, 40, 85, 53, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 17, 0, 4, 0, 14, 1, 108, 7, 240, 10, 58, 14, 136, 19, 224, 21, 0, 11, 0, 38, 3, 3, 6, 6, 7, 6, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 30, 40, 85, 53, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 8, 7, 0, 4, 8, 20, 20, 18, 5, 21, 44, 14, 3, 34, 13, 8, 17, 25, 21, 0, 245, 239, 247, 230, 239, 227, 197, 186, 207, 230, 252, 199, 167, 240, 0, 246, 7, 0, 242, 23, 35, 23, 255, 9, 34, 33, 10, 10, 0, 237, 20, 29, 228, 4, 0, 239, 27, 1, 11, 243, 41, 60, 23, 43, 28, 60, 30, 5, 0, 4, 29, 25, 5, 196, 224, 7, 199, 247, 35, 221, 209, 245, 7, 238, 207, 223, 0, 20, 222, 17, 21, 215, 213, 197, 241, 30, 224, 179, 24, 16, 204, 6, 1, 209, 11, 37, 4, 19, 30, 242, 247, 45, 69, 37, 30, 94, 91, 34, 29, 37, 34, 6, 251, 31, 29, 219, 214, 42, 14, 225, 241, 244, 11, 2, 209, 219, 16, 199, 156, 202, 230, 207, 201, 210, 227, 233, 213, 229, 19, 251, 218, 2, 25, 11, 252, 11, 40, 31, 11, 45, 57, 54, 51, 43, 63, 77, 29, 11, 45, 29, 241, 7, 29, 248, 232, 254, 254, 247, 240, 241, 248, 235, 223, 234, 229, 211, 215, 186, 181, 215, 206, 187, 214, 222, 205, 239, 21, 19, 24, 39, 53, 65, 87, 97, 93, 69, 62, 71, 79, 48, 33, 17, 3, 8, 250, 251, 230, 224, 211, 204, 206, 183, 183, 187, 185, 170, 172, 183, 178, 179, 214, 226, 233, 7, 27, 30, 37, 49, 68, 85, 87, 84, 72, 78, 69, 66, 67, 48, 32, 37, 42, 24, 11, 5, 247, 229, 249, 239, 217, 198, 199, 218, 224, 220, 217, 227, 219, 216, 236, 236, 222, 220, 223, 246, 236, 222, 230, 230, 236, 4, 6, 236, 251, 17, 17, 14, 14, 2, 30, 35, 25, 47, 37, 19, 55, 56, 52, 56, 33, 45, 58, 27, 255, 8, 41, 27, 241, 255, 8, 213, 222, 6, 10, 234, 194, 192, 244, 253, 185, 198, 234, 201, 176, 216, 27, 236, 164, 249, 7, 238, 8, 253, 253, 250, 227, 27, 60, 235, 238, 25, 34, 53, 46, 67, 97, 41, 40, 106, 64, 239, 239, 12, 23, 225, 210, 1, 210, 184, 6, 26, 0, 50, 242, 249, 71, 26, 12, 243, 213, 218, 236, 195, 216, 229, 172, 165, 202, 212, 255, 220, 214, 46, 37, 229, 24, 48, 11, 6, 246, 90, 106, 248, 31, 62, 254, 18, 47, 24, 42, 5, 20, 84, 28, 199, 213, 252, 0, 9, 248, 227, 245, 210, 224, 210, 197, 198, 226, 236, 227, 226, 218, 221, 213, 244, 7, 11, 20, 51, 60, 12, 16, 36, 48, 48, 47, 50, 35, 25, 38, 41, 249, 255, 43, 36, 8, 32, 24, 2, 4, 243, 13, 218, 166, 197, 198, 182, 172, 167, 161, 174, 164, 197, 237, 211, 213, 0, 30, 26, 33, 72, 86, 73, 64, 94, 88, 79, 94, 70, 51, 36, 18, 49, 49, 254, 245, 1, 254, 253, 248, 241, 227, 207, 224, 246, 205, 199, 206, 205, 207, 220, 203, 204, 206, 210, 239, 239, 228, 235, 244, 3, 15, 0, 254, 15, 1, 19, 37, 21, 14, 22, 19, 20, 35, 34, 47, 47, 39, 60, 64, 45, 47, 46, 38, 36, 21, 16, 15, 249, 229, 222, 218, 209, 202, 219, 226, 214, 211, 205, 208, 229, 235, 250, 10, 250, 234, 1, 2, 4, 253, 239, 234, 2, 2, 245, 251, 255, 212, 206, 20, 33, 248, 246, 2, 251, 7, 18, 28, 25, 28, 33, 34, 51, 50, 55, 48, 52, 34, 4, 33, 72, 10, 248, 14, 0, 3, 7, 15, 13, 232, 215, 248, 8, 233, 184, 179, 214, 196, 190, 212, 189, 133, 181, 249, 228, 218, 235, 229, 255, 58, 33, 34, 20, 0, 50, 94, 24, 232, 19, 15, 36, 15, 22, 26, 68, 83, 56, 80, 78, 46, 58, 66, 20, 27, 255, 178, 210, 227, 162, 178, 203, 179, 196, 212, 210, 248, 249, 210, 232, 26, 239, 217, 0, 16, 1, 234, 229, 14, 4, 236, 9, 21, 43, 46, 19, 3, 58, 26, 23, 84, 50, 2, 38, 56, 33, 10, 224, 246, 250, 187, 200, 249, 236, 164, 211, 227, 238, 20, 255, 4, 15, 24, 0, 244, 1, 251, 226, 251, 27, 7, 253, 27, 21, 18, 22, 25, 28, 35, 253, 4, 20, 236, 232, 239, 234, 247, 17, 13, 1, 7, 253, 253, 13, 8, 245, 3, 252, 6, 2, 230, 247, 0, 228, 241, 13, 252, 247, 247, 238, 242, 251, 236, 213, 243, 249, 254, 17, 13, 247, 250, 23, 31, 15, 13, 32, 14, 32, 31, 3, 7, 11, 4, 6, 12, 3, 251, 253, 23, 251, 214, 249, 5, 10, 21, 14, 253, 12, 32, 30, 22, 17, 245, 235, 253, 2, 227, 204, 200, 203, 201, 233, 232, 207, 213, 249, 246, 1, 16, 244, 234, 4, 18, 255, 13, 12, 4, 25, 32, 46, 38, 41, 51, 50, 47, 43, 34, 28, 33, 27, 8, 5, 253, 248, 0, 6, 249, 241, 228, 235, 235, 228, 228, 205, 199, 208, 207, 197, 211, 221, 205, 210, 249, 249, 251, 16, 10, 16, 43, 59, 56, 59, 38, 31, 34, 26, 33, 25, 10, 1, 251, 19, 26, 2, 1, 32, 255, 6, 6, 233, 237, 247, 238, 231, 204, 208, 246, 236, 232, 233, 237, 0, 8, 0, 252, 232, 234, 8, 17, 238, 220, 246, 8, 43, 41, 34, 42, 42, 53, 57, 54, 32, 17, 244, 244, 34, 249, 194, 197, 227, 241, 227, 222, 220, 214, 235, 12, 222, 239, 227, 228, 1, 17, 240, 225, 245, 51, 54, 4, 38, 60, 58, 56, 85, 56, 4, 4, 37, 24, 247, 209, 230, 247, 246, 219, 222, 247, 255, 0, 249, 231, 226, 230, 241, 231, 165, 196, 245, 183, 202, 234, 246, 0, 2, 44, 63, 48, 8, 63, 79, 27, 247, 20, 52, 61, 38, 25, 57, 39, 24, 44, 46, 12, 247, 23, 41, 218, 184, 221, 1, 236, 219, 203, 193, 188, 187, 188, 199, 215, 199, 202, 218, 2, 248, 210, 243, 245, 246, 254, 251, 17, 42, 47, 54, 91, 77, 95, 104, 93, 99, 63, 34, 46, 65, 6, 228, 215, 214, 210, 238, 0, 208, 211, 232, 4, 10, 255, 250, 218, 225, 245, 224, 184, 172, 185, 185, 197, 190, 212, 230, 14, 24, 14, 42, 47, 43, 53, 64, 41, 254, 6, 28, 20, 239, 253, 15, 19, 33, 52, 50, 41, 46, 51, 40, 27, 11, 0, 244, 250, 213, 208, 233, 231, 209, 219, 3, 246, 225, 10, 4, 250, 254, 246, 233, 244, 213, 194, 205, 204, 209, 213, 232, 253, 0, 10, 43, 58, 41, 48, 54, 41, 37, 30, 12, 11, 247, 237, 1, 14, 9, 15, 38, 48, 34, 19, 34, 34, 16, 8, 6, 241, 232, 230, 223, 211, 205, 219, 242, 232, 229, 239, 247, 247, 229, 238, 243, 227, 226, 223, 230, 227, 224, 248, 29, 20, 7, 34, 51, 49, 51, 45, 56, 41, 24, 14, 24, 17, 1, 240, 249, 240, 231, 254, 28, 22, 245, 246, 2, 13, 15, 3, 4, 248, 211, 233, 242, 232, 249, 245, 247, 246, 234, 242, 16, 16, 237, 208, 227, 253, 6, 0, 232, 230, 228, 246, 7, 30, 13, 247, 23, 48, 47, 13, 3, 12, 29, 26, 16, 47, 32, 5, 10, 32, 29, 1, 7, 4, 239, 238, 246, 235, 189, 187, 206, 224, 235, 237, 242, 2, 31, 26, 0, 24, 32, 17, 25, 17, 233, 225, 202, 253, 22, 231, 9, 16, 19, 27, 25, 36, 19, 251, 250, 1, 0, 225, 196, 201, 213, 228, 29, 9, 247, 19, 38, 41, 18, 15, 20, 20, 2, 4, 3, 253, 253, 236, 10, 40, 7, 0, 18, 24, 8, 7, 3, 1, 253, 236, 1, 243, 214, 207, 238, 244, 250, 222, 230, 14, 0, 229, 252, 18, 247, 227, 245, 36, 245, 219, 26, 41, 37, 2, 4, 56, 42, 10, 20, 36, 0, 251, 242, 1, 235, 205, 217, 25, 17, 228, 236, 24, 40, 254, 15, 35, 6, 249, 5, 19, 9, 220, 203, 242, 6, 217, 222, 3, 8, 248, 17, 36, 21, 246, 232, 5, 11, 250, 235, 228, 13, 254, 231, 10, 37, 12, 252, 29, 47, 12, 252, 14, 14, 230, 216, 213, 250, 9, 222, 226, 5, 25, 10, 9, 31, 33, 9, 24, 48, 5, 242, 239, 4, 234, 220, 215, 247, 6, 0, 254, 20, 20, 1, 12, 19, 12, 250, 239, 1, 7, 231, 223, 233, 230, 255, 14, 24, 23, 28, 19, 29, 39, 254, 239, 248, 245, 221, 208, 210, 221, 219, 227, 249, 4, 8, 32, 46, 57, 55, 26, 25, 36, 28, 254, 247, 250, 243, 245, 0, 253, 241, 254, 21, 20, 12, 1, 249, 241, 247, 236, 215, 212, 207, 208, 224, 232, 247, 255, 2, 24, 32, 33, 32, 26, 28, 28, 18, 4, 1, 247, 0, 244, 0, 24, 12, 8, 34, 28, 11, 9, 255, 252, 9, 251, 231, 216, 222, 232, 221, 232, 240, 235, 245, 26, 43, 23, 11, 23, 14, 242, 252, 237, 237, 240, 218, 213, 228, 250, 247, 20, 45, 35, 53, 46, 53, 40, 7, 221, 249, 253, 225, 250, 244, 241, 242, 7, 27, 23, 15, 20, 19, 253, 10, 16, 241, 217, 244, 251, 235, 250, 14, 247, 246, 242, 244, 246, 239, 231, 212, 226, 235, 246, 3, 17, 241, 216, 6, 47, 39, 26, 24, 26, 26, 44, 46, 24, 0, 21, 27, 32, 34, 3, 247, 252, 230, 204, 237, 10, 4, 251, 226, 236, 251, 213, 231, 15, 237, 224, 249, 14, 9, 241, 234, 242, 235, 248, 8, 253, 251, 235, 238, 17, 26, 2, 13, 41, 55, 31, 19, 22, 29, 240, 238, 9, 10, 245, 233, 14, 28, 20, 8, 1, 35, 27, 27, 28, 21, 252, 211, 211, 246, 233, 187, 205, 222, 233, 222, 224, 240, 245, 251, 0, 0, 17, 0, 1, 27, 23, 240, 233, 255, 27, 14, 17, 28, 24, 26, 34, 44, 48, 53, 39, 24, 31, 9, 10, 253, 228, 230, 227, 216, 227, 230, 213, 232, 247, 0, 249, 240, 228, 238, 244, 229, 227, 223, 208, 230, 249, 3, 13, 22, 19, 54, 64, 43, 41, 44, 38, 41, 25, 8, 249, 233, 253, 6, 249, 252, 252, 248, 4, 6, 0, 247, 235, 242, 234, 226, 221, 219, 226, 243, 249, 252, 15, 17, 12, 20, 10, 5, 6, 2, 4, 253, 247, 255, 6, 4, 13, 7, 24, 31, 33, 23, 19, 17, 5, 1, 254, 251, 248, 223, 219, 223, 238, 245, 248, 242, 245, 240, 238, 10, 23, 0, 234, 247, 252, 245, 249, 5, 10, 252, 15, 33, 39, 30, 18, 21, 13, 15, 12, 254, 2, 4, 2, 251, 9, 241, 235, 6, 10, 14, 5, 255, 247, 254, 244, 253, 0, 243, 238, 242, 238, 219, 227, 233, 221, 227, 233, 250, 21, 23, 3, 5, 23, 14, 18, 9, 2, 7, 5, 254, 11, 17, 14, 14, 33, 41, 43, 45, 34, 20, 30, 6, 4, 5, 244, 231, 235, 230, 231, 223, 205, 221, 238, 243, 229, 240, 240, 241, 226, 220, 250, 247, 240, 239, 231, 3, 9, 6, 20, 37, 23, 10, 25, 51, 48, 28, 28, 41, 41, 41, 14, 19, 34, 8, 254, 5, 248, 230, 220, 227, 246, 234, 221, 224, 244, 236, 224, 221, 246, 225, 212, 227, 3, 249, 238, 234, 11, 38, 27, 17, 23, 30, 45, 24, 17, 11, 15, 0, 2, 11, 4, 252, 14, 12, 254, 0, 30, 37, 30, 24, 7, 247, 233, 217, 233, 246, 234, 221, 220, 225, 226, 231, 250, 246, 254, 249, 0, 12, 15, 14, 0, 246, 236, 251, 3, 9, 23, 22, 16, 24, 40, 37, 50, 39, 18, 3, 253, 245, 245, 255, 217, 221, 223, 250, 252, 3, 4, 0, 1, 4, 8, 6, 6, 254, 238, 237, 238, 241, 242, 234, 241, 239, 241, 10, 28, 26, 21, 31, 19, 3, 0, 245, 254, 252, 244, 0, 22, 16, 10, 3, 19, 18, 252, 0, 12, 2, 241, 0, 249, 241, 246, 242, 252, 3, 252, 246, 248, 246, 251, 249, 255, 2, 253, 253, 6, 8, 11, 3, 9, 6, 0, 0, 0, 90, 0, 3, 0, 5, 0, 4, 0, 192, 0, 52, 8, 128, 12, 58, 14, 136, 19, 224, 21, 50, 9, 0, 33, 2, 2, 4, 3, 3, 2, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 4, 0, 192, 0, 52, 8, 128, 12, 58, 14, 136, 19, 224, 21, 40, 5, 0, 26, 1, 1, 3, 2, 2, 1, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 4, 0, 184, 0, 52, 8, 128, 12, 58, 14, 136, 19, 224, 21, 0, 1, 0, 14, 1, 1, 2, 2, 2, 2, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 80, 0, 3, 0, 5, 0, 4, 0, 176, 0, 208, 7, 184, 11, 58, 14, 136, 19, 224, 21, 31, 8, 0, 33, 3, 3, 6, 6, 6, 6, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 5, 0, 4, 0, 176, 0, 208, 7, 184, 11, 58, 14, 136, 19, 224, 21, 50, 9, 0, 34, 3, 3, 6, 6, 7, 6, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 9, 0, 4, 0, 176, 0, 108, 7, 184, 11, 58, 14, 136, 19, 224, 21, 0, 9, 0, 34, 3, 3, 6, 6, 7, 6, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 105, 0, 4, 0, 69, 0, 120, 0, 0, 1, 176, 4, 192, 8, 4, 16, 172, 18, 244, 26, 30, 7, 14, 17, 5, 17, 5, 5, 0, 0, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 69, 0, 120, 0, 0, 1, 176, 4, 192, 8, 4, 16, 172, 18, 244, 26, 50, 8, 16, 19, 6, 19, 6, 6, 0, 0, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 69, 0, 120, 0, 0, 1, 176, 4, 192, 8, 4, 16, 172, 18, 244, 26, 25, 7, 14, 17, 5, 17, 5, 5, 0, 0, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 120, 0, 0, 1, 40, 5, 152, 8, 104, 16, 172, 18, 244, 26, 0, 3, 5, 17, 8, 8, 2, 2, 0, 0, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 246, 10, 18, 0, 246, 249, 251, 254, 1, 4, 3, 255, 252, 253, 250, 246, 249, 252, 251, 248, 250, 254, 254, 255, 2, 10, 18, 19, 14, 8, 2, 255, 252, 246, 245, 252, 6, 12, 7, 2, 255, 246, 245, 248, 248, 245, 252, 9, 5, 245, 238, 245, 251, 250, 250, 5, 17, 18, 10, 0, 251, 250, 253, 255, 255, 0, 7, 10, 6, 1, 2, 7, 10, 10, 10, 13, 13, 4, 249, 241, 243, 251, 252, 252, 8, 27, 32, 21, 9, 6, 9, 0, 242, 237, 241, 246, 250, 0, 6, 9, 15, 22, 20, 5, 247, 243, 249, 248, 235, 236, 255, 15, 14, 5, 9, 14, 12, 7, 255, 248, 244, 240, 239, 241, 242, 247, 2, 16, 22, 16, 10, 4, 246, 229, 219, 223, 236, 247, 0, 10, 21, 21, 12, 9, 8, 2, 0, 2, 5, 1, 248, 240, 241, 255, 14, 22, 28, 31, 28, 21, 11, 249, 229, 230, 246, 253, 255, 14, 33, 31, 11, 7, 17, 6, 234, 226, 243, 1, 0, 245, 245, 0, 7, 7, 4, 0, 0, 7, 12, 3, 245, 239, 247, 252, 249, 247, 250, 0, 11, 20, 7, 239, 234, 243, 247, 242, 247, 255, 255, 254, 7, 5, 241, 226, 236, 3, 8, 251, 251, 14, 24, 7, 241, 232, 243, 254, 0, 0, 1, 12, 25, 24, 254, 234, 249, 6, 0, 247, 247, 2, 11, 4, 0, 2, 0, 2, 13, 16, 9, 5, 5, 5, 1, 253, 2, 10, 9, 14, 23, 23, 16, 9, 3, 5, 4, 254, 250, 252, 6, 17, 10, 253, 251, 2, 6, 255, 243, 246, 7, 12, 1, 247, 248, 254, 1, 250, 241, 241, 250, 2, 5, 255, 252, 255, 0, 1, 252, 244, 248, 5, 10, 3, 0, 3, 9, 8, 254, 255, 14, 13, 252, 239, 242, 251, 0, 249, 239, 249, 14, 21, 12, 5, 0, 246, 241, 242, 244, 232, 221, 243, 18, 17, 247, 242, 9, 20, 0, 239, 247, 0, 242, 236, 253, 0, 252, 5, 35, 48, 32, 16, 20, 27, 16, 0, 252, 253, 2, 12, 11, 3, 5, 7, 0, 247, 247, 243, 239, 241, 234, 223, 229, 249, 253, 248, 0, 18, 24, 12, 3, 250, 241, 246, 9, 17, 19, 29, 35, 20, 7, 0, 243, 232, 242, 0, 4, 3, 7, 11, 6, 0, 5, 10, 5, 0, 5, 9, 0, 241, 232, 246, 10, 9, 253, 252, 0, 250, 232, 218, 210, 207, 217, 238, 248, 241, 250, 14, 20, 6, 0, 11, 15, 6, 0, 0, 6, 11, 15, 17, 16, 20, 27, 23, 7, 255, 10, 16, 3, 249, 2, 9, 1, 0, 6, 7, 5, 12, 18, 2, 242, 242, 247, 246, 241, 239, 249, 4, 15, 13, 252, 249, 6, 8, 252, 248, 0, 6, 8, 14, 17, 9, 9, 17, 25, 20, 3, 254, 4, 0, 246, 233, 228, 242, 251, 249, 249, 0, 7, 4, 1, 0, 251, 248, 250, 247, 244, 247, 251, 255, 0, 0, 2, 4, 5, 3, 253, 245, 244, 246, 242, 240, 251, 3, 4, 5, 5, 2, 0, 0, 3, 5, 0, 254, 4, 5, 254, 250, 1, 11, 20, 22, 17, 11, 2, 248, 242, 239, 238, 242, 0, 10, 15, 15, 3, 252, 1, 4, 0, 254, 5, 16, 17, 2, 243, 239, 244, 254, 10, 14, 8, 12, 19, 2, 238, 229, 232, 247, 4, 7, 12, 18, 15, 5, 255, 254, 0, 2, 5, 13, 15, 3, 250, 250, 245, 242, 249, 253, 0, 8, 12, 9, 0, 250, 254, 252, 249, 0, 9, 14, 18, 21, 16, 8, 9, 6, 250, 242, 252, 9, 0, 247, 251, 253, 1, 0, 239, 224, 237, 2, 3, 248, 244, 0, 11, 7, 248, 235, 240, 4, 16, 2, 242, 250, 16, 17, 245, 225, 242, 17, 21, 0, 247, 254, 7, 4, 240, 228, 236, 255, 12, 12, 254, 253, 12, 18, 252, 222, 222, 253, 18, 2, 235, 244, 18, 19, 249, 239, 253, 14, 22, 27, 23, 3, 0, 12, 13, 3, 250, 3, 34, 47, 27, 13, 15, 10, 250, 234, 233, 243, 249, 249, 3, 13, 4, 253, 253, 250, 250, 246, 246, 255, 2, 252, 253, 0, 249, 248, 0, 6, 11, 15, 17, 14, 6, 0, 253, 250, 1, 13, 21, 25, 29, 29, 15, 248, 244, 253, 245, 233, 240, 0, 1, 248, 248, 0, 0, 252, 0, 4, 254, 250, 3, 0, 234, 233, 253, 7, 2, 252, 11, 25, 13, 254, 248, 248, 248, 250, 250, 238, 235, 255, 10, 0, 244, 249, 8, 15, 1, 237, 233, 246, 0, 245, 227, 237, 16, 31, 6, 241, 255, 25, 30, 5, 241, 1, 26, 23, 1, 243, 240, 247, 2, 1, 255, 7, 20, 22, 3, 240, 244, 0, 252, 248, 6, 24, 34, 28, 2, 233, 240, 10, 13, 250, 254, 29, 38, 3, 233, 236, 242, 245, 1, 23, 20, 7, 18, 18, 237, 206, 224, 5, 7, 255, 15, 36, 21, 238, 221, 226, 227, 228, 243, 4, 19, 24, 11, 248, 232, 217, 228, 248, 6, 27, 40, 32, 15, 8, 3, 243, 238, 254, 12, 14, 13, 14, 2, 240, 240, 250, 237, 222, 236, 254, 244, 221, 223, 240, 241, 235, 244, 1, 12, 20, 25, 23, 17, 19, 22, 9, 0, 1, 4, 10, 17, 16, 13, 22, 34, 21, 243, 231, 245, 250, 240, 235, 248, 17, 27, 16, 4, 7, 20, 18, 255, 247, 4, 14, 1, 246, 253, 5, 14, 19, 14, 18, 27, 22, 13, 5, 253, 247, 246, 246, 248, 250, 253, 254, 1, 6, 5, 0, 247, 241, 242, 242, 245, 253, 0, 2, 10, 16, 10, 253, 248, 254, 0, 253, 247, 249, 3, 3, 247, 241, 252, 3, 2, 255, 4, 13, 8, 252, 246, 240, 234, 235, 244, 243, 241, 3, 22, 18, 7, 1, 3, 0, 248, 248, 249, 251, 7, 20, 16, 4, 5, 14, 9, 252, 244, 248, 2, 1, 247, 247, 254, 2, 2, 249, 251, 10, 16, 3, 253, 252, 254, 0, 253, 243, 248, 12, 25, 19, 7, 255, 0, 7, 252, 235, 242, 3, 9, 5, 5, 18, 17, 0, 255, 8, 0, 245, 253, 14, 10, 255, 0, 4, 8, 4, 246, 235, 232, 234, 227, 227, 232, 230, 240, 251, 251, 243, 235, 229, 230, 235, 230, 234, 247, 252, 2, 7, 5, 6, 7, 6, 8, 7, 1, 7, 25, 20, 2, 6, 26, 35, 27, 18, 26, 36, 30, 10, 2, 3, 5, 1, 0, 2, 4, 14, 19, 8, 250, 246, 254, 0, 254, 0, 14, 22, 19, 23, 19, 5, 254, 6, 16, 9, 9, 22, 39, 35, 13, 9, 15, 9, 250, 237, 235, 242, 254, 253, 240, 238, 254, 15, 7, 243, 244, 2, 1, 244, 238, 243, 248, 254, 245, 236, 246, 253, 247, 245, 249, 244, 233, 235, 234, 229, 232, 241, 246, 242, 243, 7, 17, 0, 243, 1, 16, 10, 3, 7, 11, 15, 21, 16, 248, 239, 3, 12, 0, 253, 6, 16, 15, 9, 6, 255, 249, 1, 14, 6, 252, 4, 14, 6, 252, 247, 250, 254, 250, 252, 0, 6, 9, 0, 237, 254, 36, 26, 252, 0, 22, 25, 250, 218, 218, 243, 13, 20, 6, 252, 14, 34, 4, 211, 202, 241, 11, 241, 194, 193, 230, 251, 236, 208, 208, 255, 45, 49, 24, 1, 9, 34, 31, 243, 205, 237, 49, 73, 38, 17, 47, 66, 38, 241, 211, 227, 243, 244, 234, 230, 237, 249, 255, 247, 251, 18, 39, 47, 42, 32, 18, 252, 216, 193, 201, 221, 241, 3, 29, 58, 61, 40, 15, 0, 246, 236, 233, 232, 239, 4, 10, 250, 240, 252, 10, 19, 27, 34, 35, 34, 22, 253, 214, 191, 199, 220, 224, 230, 8, 48, 54, 34, 15, 3, 249, 236, 228, 233, 245, 12, 27, 20, 9, 14, 22, 12, 1, 10, 23, 26, 18, 8, 251, 238, 234, 230, 223, 229, 253, 19, 18, 11, 20, 26, 6, 237, 235, 245, 239, 227, 234, 0, 9, 7, 6, 10, 9, 1, 254, 248, 235, 237, 253, 4, 251, 253, 13, 17, 3, 252, 0, 3, 252, 251, 250, 240, 234, 244, 253, 248, 247, 6, 27, 35, 23, 9, 2, 254, 242, 231, 233, 243, 9, 35, 48, 44, 33, 30, 26, 0, 232, 236, 0, 4, 248, 255, 15, 17, 7, 255, 2, 14, 14, 6, 1, 255, 250, 254, 255, 244, 235, 244, 5, 6, 242, 235, 255, 11, 251, 240, 248, 0, 248, 239, 234, 233, 237, 245, 248, 242, 238, 4, 20, 7, 246, 253, 22, 25, 2, 232, 222, 230, 235, 228, 226, 242, 7, 27, 30, 10, 1, 2, 248, 228, 227, 231, 214, 208, 239, 11, 12, 4, 37, 64, 34, 249, 239, 246, 238, 230, 240, 2, 18, 17, 21, 43, 48, 27, 17, 54, 72, 36, 255, 247, 252, 241, 237, 255, 11, 27, 52, 70, 50, 5, 244, 245, 245, 226, 201, 215, 247, 2, 240, 233, 252, 5, 5, 9, 15, 6, 248, 2, 12, 253, 235, 252, 29, 38, 25, 15, 23, 35, 19, 247, 238, 251, 1, 247, 240, 249, 6, 9, 8, 14, 16, 6, 253, 246, 236, 219, 209, 208, 214, 223, 231, 238, 251, 12, 20, 6, 0, 3, 5, 255, 238, 230, 238, 4, 0, 228, 237, 13, 32, 18, 253, 1, 18, 16, 250, 229, 231, 244, 254, 1, 0, 10, 18, 30, 40, 31, 14, 20, 36, 22, 251, 245, 0, 6, 3, 12, 32, 39, 36, 27, 22, 10, 250, 240, 238, 244, 251, 245, 240, 249, 249, 238, 255, 15, 0, 252, 23, 39, 5, 220, 218, 253, 21, 251, 227, 4, 53, 52, 248, 201, 207, 241, 5, 251, 236, 239, 8, 31, 4, 205, 173, 211, 26, 35, 250, 246, 24, 26, 232, 175, 167, 215, 3, 253, 244, 8, 32, 17, 214, 160, 156, 200, 249, 11, 15, 24, 52, 59, 11, 211, 202, 9, 60, 47, 31, 53, 78, 57, 7, 248, 16, 51, 62, 57, 50, 36, 15, 232, 197, 186, 190, 226, 16, 33, 33, 45, 62, 36, 239, 209, 218, 237, 226, 209, 224, 1, 20, 11, 6, 22, 53, 60, 37, 20, 23, 32, 13, 231, 222, 243, 255, 242, 241, 6, 28, 36, 35, 30, 21, 8, 246, 225, 211, 201, 207, 226, 244, 0, 13, 21, 13, 2, 248, 234, 237, 246, 242, 232, 237, 252, 255, 243, 234, 250, 21, 30, 21, 20, 30, 29, 7, 241, 236, 247, 3, 14, 14, 13, 22, 17, 255, 235, 229, 236, 248, 5, 10, 8, 7, 11, 8, 237, 216, 231, 251, 252, 246, 1, 12, 0, 241, 243, 249, 244, 246, 13, 24, 6, 246, 254, 2, 241, 230, 249, 18, 31, 31, 31, 31, 19, 254, 246, 245, 245, 4, 25, 28, 22, 30, 30, 16, 3, 0, 255, 6, 19, 16, 255, 252, 3, 0, 239, 234, 255, 19, 17, 10, 13, 16, 4, 245, 235, 231, 236, 248, 7, 14, 0, 241, 251, 251, 217, 190, 214, 253, 4, 244, 248, 7, 2, 228, 201, 194, 216, 247, 2, 251, 0, 21, 23, 253, 229, 234, 248, 4, 17, 10, 247, 255, 22, 11, 213, 191, 235, 11, 246, 228, 0, 20, 2, 249, 244, 229, 218, 243, 27, 28, 10, 22, 53, 60, 27, 249, 252, 40, 64, 28, 8, 43, 73, 32, 225, 231, 13, 8, 246, 16, 55, 50, 38, 41, 24, 248, 227, 230, 240, 246, 246, 252, 17, 35, 31, 9, 8, 17, 3, 242, 252, 5, 251, 247, 17, 29, 2, 240, 1, 10, 250, 235, 245, 4, 14, 7, 246, 237, 242, 245, 239, 241, 247, 244, 236, 238, 236, 212, 194, 211, 233, 241, 252, 14, 22, 17, 10, 2, 246, 240, 251, 1, 253, 251, 6, 11, 1, 246, 245, 249, 253, 1, 10, 18, 10, 253, 5, 12, 255, 235, 238, 12, 28, 7, 254, 17, 33, 26, 4, 0, 10, 14, 9, 0, 253, 248, 248, 0, 2, 7, 15, 29, 38, 21, 3, 6, 5, 240, 238, 10, 20, 15, 26, 36, 19, 253, 11, 19, 248, 237, 4, 25, 12, 242, 242, 251, 240, 229, 239, 247, 249, 12, 25, 10, 250, 246, 250, 243, 226, 225, 247, 8, 254, 239, 0, 27, 18, 252, 1, 17, 0, 232, 222, 223, 228, 229, 224, 212, 209, 240, 248, 200, 181, 230, 7, 239, 207, 193, 192, 197, 202, 228, 2, 11, 60, 127, 111, 34, 249, 0, 255, 232, 216, 248, 57, 86, 72, 48, 38, 34, 12, 246, 243, 252, 1, 1, 250, 230, 219, 225, 236, 254, 15, 42, 72, 67, 42, 20, 253, 234, 231, 238, 247, 11, 39, 59, 54, 32, 28, 33, 8, 246, 251, 3, 6, 8, 7, 11, 19, 17, 7, 5, 4, 7, 8, 1, 252, 250, 244, 233, 215, 200, 203, 215, 215, 218, 242, 14, 24, 15, 5, 2, 251, 240, 233, 231, 237, 0, 19, 15, 4, 10, 20, 16, 3, 9, 29, 28, 8, 2, 7, 253, 242, 247, 251, 253, 3, 19, 32, 23, 252, 243, 252, 245, 217, 215, 247, 10, 0, 251, 2, 6, 251, 237, 232, 235, 247, 4, 10, 11, 8, 4, 2, 2, 6, 6, 2, 5, 24, 38, 30, 15, 9, 14, 9, 254, 252, 3, 4, 2, 12, 17, 2, 251, 0, 253, 242, 241, 242, 236, 227, 228, 236, 245, 247, 255, 13, 26, 16, 247, 243, 252, 234, 207, 212, 243, 2, 250, 247, 8, 19, 10, 1, 254, 250, 252, 0, 0, 247, 250, 3, 10, 8, 4, 12, 25, 30, 21, 250, 231, 238, 243, 226, 214, 237, 15, 24, 5, 248, 0, 9, 0, 232, 212, 226, 1, 5, 242, 233, 237, 237, 244, 252, 240, 233, 10, 55, 45, 1, 7, 34, 17, 246, 1, 32, 48, 52, 60, 53, 31, 15, 12, 1, 239, 229, 242, 253, 253, 240, 228, 243, 2, 254, 254, 12, 13, 254, 245, 240, 237, 239, 244, 1, 22, 45, 52, 38, 33, 43, 40, 10, 249, 12, 16, 246, 233, 248, 5, 6, 14, 27, 31, 37, 38, 19, 245, 222, 216, 223, 232, 227, 230, 249, 4, 253, 233, 232, 235, 230, 240, 0, 255, 246, 253, 7, 240, 214, 224, 248, 0, 253, 6, 25, 26, 12, 254, 250, 249, 246, 248, 2, 19, 25, 10, 1, 7, 5, 247, 244, 4, 10, 4, 11, 30, 25, 254, 249, 7, 5, 250, 248, 4, 10, 7, 4, 8, 3, 247, 246, 0, 252, 255, 17, 25, 14, 5, 7, 5, 244, 239, 251, 255, 253, 9, 17, 3, 8, 28, 11, 233, 235, 6, 6, 235, 232, 254, 5, 254, 255, 254, 250, 251, 7, 4, 233, 214, 238, 3, 241, 217, 227, 246, 248, 251, 253, 248, 0, 28, 38, 0, 209, 217, 243, 225, 190, 204, 246, 6, 5, 16, 15, 246, 245, 17, 21, 249, 0, 42, 51, 8, 237, 252, 10, 254, 242, 1, 24, 36, 39, 34, 18, 2, 4, 11, 254, 230, 218, 233, 249, 241, 237, 250, 13, 29, 41, 39, 24, 10, 4, 244, 226, 228, 248, 1, 5, 26, 51, 52, 42, 38, 37, 30, 20, 2, 241, 236, 238, 238, 233, 237, 4, 29, 37, 29, 26, 24, 7, 244, 229, 223, 222, 228, 238, 242, 247, 1, 16, 18, 7, 7, 16, 16, 10, 3, 0, 3, 6, 0, 250, 252, 0, 0, 0, 0, 1, 12, 11, 1, 255, 1, 254, 244, 240, 246, 248, 247, 250, 0, 2, 250, 241, 244, 252, 248, 239, 243, 0, 7, 2, 250, 252, 0, 247, 234, 234, 246, 251, 249, 0, 10, 9, 255, 250, 247, 243, 245, 253, 5, 10, 7, 2, 250, 240, 235, 234, 241, 4, 32, 45, 38, 24, 15, 1, 233, 214, 225, 253, 12, 18, 27, 40, 45, 31, 5, 251, 5, 15, 5, 249, 0, 6, 248, 235, 242, 254, 4, 17, 29, 24, 14, 16, 13, 242, 213, 212, 226, 232, 232, 238, 250, 6, 17, 11, 244, 227, 231, 241, 241, 232, 231, 244, 7, 8, 243, 229, 239, 4, 15, 7, 4, 25, 51, 41, 0, 234, 242, 251, 248, 245, 5, 26, 34, 35, 26, 8, 0, 7, 21, 14, 2, 2, 16, 15, 245, 221, 234, 6, 15, 19, 34, 45, 36, 20, 10, 251, 219, 210, 242, 16, 4, 2, 38, 59, 28, 252, 1, 16, 2, 245, 7, 25, 16, 3, 6, 9, 253, 244, 254, 13, 17, 12, 5, 3, 249, 233, 222, 226, 236, 234, 222, 225, 237, 239, 223, 210, 220, 231, 235, 239, 241, 238, 239, 241, 236, 224, 215, 217, 225, 231, 230, 234, 0, 0, 12, 8, 12, 0, 14, 17, 18, 23, 26, 28, 26, 33, 33, 28, 29, 28, 29, 28, 26, 25, 24, 26, 25, 23, 13, 15, 12, 9, 9, 6, 9, 12, 12, 13, 15, 14, 14, 16, 20, 25, 27, 27, 28, 28, 33, 37, 40, 37, 42, 40, 38, 36, 41, 41, 38, 38, 39, 41, 40, 42, 44, 40, 37, 39, 40, 36, 37, 34, 32, 31, 33, 31, 30, 28, 27, 22, 19, 17, 14, 15, 12, 12, 15, 15, 17, 18, 19, 14, 12, 14, 18, 21, 23, 24, 25, 27, 26, 27, 26, 28, 23, 18, 18, 15, 14, 8, 3, 4, 5, 1, 8, 248, 0, 178, 140, 255, 16, 1, 251, 245, 245, 245, 239, 226, 221, 249, 31, 37, 28, 33, 28, 31, 38, 43, 44, 49, 55, 52, 43, 43, 39, 41, 30, 29, 23, 25, 23, 21, 10, 6, 10, 3, 3, 0, 2, 3, 11, 11, 7, 240, 202, 209, 221, 230, 252, 13, 19, 14, 250, 9, 219, 164, 223, 255, 242, 234, 247, 246, 247, 250, 247, 255, 214, 197, 207, 206, 226, 238, 6, 14, 25, 40, 51, 58, 37, 11, 3, 7, 8, 2, 224, 231, 31, 56, 68, 76, 86, 82, 81, 65, 53, 57, 65, 34, 19, 51, 54, 62, 60, 41, 36, 22, 12, 248, 239, 235, 250, 250, 254, 11, 15, 28, 41, 48, 45, 37, 39, 24, 12, 253, 0, 29, 44, 54, 62, 65, 67, 59, 50, 40, 41, 41, 30, 35, 46, 55, 69, 78, 73, 68, 65, 56, 46, 42, 30, 22, 18, 18, 27, 254, 233, 4, 26, 27, 7, 0, 240, 233, 223, 213, 217, 235, 249, 0, 13, 19, 25, 33, 25, 30, 32, 32, 39, 33, 41, 51, 58, 66, 67, 74, 78, 76, 72, 59, 50, 38, 35, 36, 38, 36, 33, 41, 39, 34, 29, 10, 253, 239, 226, 217, 215, 228, 233, 238, 239, 246, 251, 243, 248, 245, 250, 253, 4, 12, 19, 32, 44, 51, 58, 62, 66, 70, 68, 60, 44, 28, 19, 19, 22, 22, 21, 24, 31, 18, 15, 15, 9, 10, 4, 5, 6, 9, 19, 17, 18, 24, 25, 17, 8, 8, 10, 9, 5, 253, 255, 253, 7, 17, 18, 15, 14, 14, 4, 4, 12, 19, 30, 22, 17, 24, 26, 22, 20, 21, 23, 20, 17, 14, 6, 4, 6, 15, 14, 24, 27, 21, 19, 17, 21, 18, 22, 20, 20, 31, 26, 24, 30, 36, 28, 27, 31, 28, 20, 15, 11, 11, 3, 254, 6, 8, 19, 21, 20, 24, 23, 16, 12, 15, 19, 29, 35, 34, 31, 34, 37, 35, 30, 22, 21, 17, 19, 10, 0, 252, 247, 247, 247, 243, 236, 232, 232, 231, 234, 239, 246, 241, 240, 243, 252, 9, 14, 9, 2, 1, 255, 248, 246, 244, 248, 0, 4, 2, 1, 2, 0, 6, 6, 6, 9, 10, 9, 11, 15, 23, 33, 29, 18, 21, 20, 17, 19, 13, 7, 8, 3, 3, 7, 11, 16, 15, 22, 17, 19, 19, 26, 32, 32, 30, 38, 39, 39, 45, 50, 44, 41, 39, 21, 24, 30, 31, 30, 25, 24, 28, 27, 22, 18, 20, 23, 23, 20, 25, 33, 39, 45, 44, 41, 36, 37, 35, 30, 28, 14, 7, 4, 0, 1, 254, 0, 5, 2, 5, 2, 6, 8, 10, 19, 25, 33, 30, 31, 37, 40, 49, 49, 53, 49, 46, 45, 40, 37, 31, 27, 26, 22, 26, 26, 22, 11, 1, 0, 7, 10, 10, 7, 7, 10, 10, 3, 7, 12, 13, 13, 22, 26, 27, 26, 29, 31, 33, 41, 43, 44, 38, 36, 36, 30, 31, 30, 21, 28, 35, 29, 28, 32, 29, 21, 11, 11, 16, 14, 15, 15, 17, 16, 18, 22, 25, 32, 31, 26, 27, 29, 26, 30, 31, 27, 23, 22, 22, 21, 21, 14, 15, 19, 18, 11, 8, 13, 20, 24, 28, 37, 41, 45, 38, 32, 23, 29, 35, 39, 44, 44, 42, 31, 28, 34, 39, 40, 39, 31, 27, 26, 28, 29, 25, 27, 21, 23, 17, 18, 14, 21, 22, 12, 15, 26, 36, 39, 34, 34, 42, 45, 50, 49, 46, 51, 58, 53, 46, 43, 45, 47, 39, 40, 42, 35, 29, 20, 17, 14, 12, 10, 12, 17, 20, 32, 41, 44, 40, 35, 30, 24, 21, 15, 17, 20, 24, 20, 21, 24, 20, 20, 20, 18, 20, 18, 16, 11, 20, 27, 37, 37, 39, 43, 47, 40, 30, 23, 20, 21, 15, 14, 6, 5, 6, 14, 15, 14, 12, 14, 16, 21, 23, 21, 22, 25, 32, 30, 30, 24, 18, 11, 10, 3, 2, 0, 3, 0, 253, 4, 10, 13, 14, 13, 10, 9, 7, 3, 4, 15, 27, 31, 30, 25, 27, 29, 33, 30, 23, 19, 17, 14, 8, 8, 9, 18, 22, 20, 25, 26, 20, 11, 4, 8, 8, 4, 255, 251, 0, 0, 1, 2, 254, 250, 251, 1, 5, 7, 7, 9, 18, 25, 26, 33, 38, 38, 43, 47, 47, 41, 46, 47, 43, 45, 40, 34, 28, 22, 22, 16, 17, 15, 11, 9, 9, 10, 8, 11, 15, 19, 20, 22, 16, 6, 12, 19, 18, 20, 21, 22, 27, 28, 34, 34, 31, 21, 14, 9, 8, 5, 0, 1, 4, 10, 11, 14, 15, 8, 4, 4, 3, 5, 2, 0, 10, 6, 12, 18, 19, 11, 6, 11, 10, 6, 7, 8, 7, 16, 18, 21, 22, 26, 29, 24, 16, 19, 21, 15, 10, 11, 20, 22, 18, 10, 11, 18, 21, 19, 6, 2, 6, 12, 8, 13, 21, 28, 31, 31, 25, 30, 30, 34, 35, 34, 33, 33, 36, 37, 39, 42, 43, 43, 36, 27, 23, 20, 17, 13, 11, 10, 15, 11, 9, 13, 17, 21, 22, 21, 20, 23, 28, 24, 27, 31, 37, 47, 50, 47, 40, 34, 31, 21, 18, 13, 12, 10, 9, 5, 7, 7, 8, 9, 15, 13, 8, 3, 10, 22, 21, 18, 20, 27, 34, 34, 35, 36, 39, 42, 42, 31, 32, 32, 38, 36, 37, 37, 36, 32, 22, 20, 17, 14, 19, 20, 20, 19, 19, 15, 16, 15, 17, 24, 28, 30, 29, 26, 25, 30, 32, 38, 43, 47, 48, 48, 41, 43, 44, 43, 42, 39, 36, 39, 32, 34, 30, 27, 30, 29, 19, 13, 8, 5, 2, 5, 4, 0, 5, 4, 0, 251, 255, 0, 5, 8, 8, 12, 13, 12, 14, 11, 8, 12, 14, 12, 10, 7, 11, 9, 4, 4, 12, 16, 16, 12, 5, 5, 8, 8, 10, 8, 6, 10, 15, 18, 16, 19, 19, 15, 16, 16, 13, 9, 9, 7, 10, 13, 14, 15, 18, 26, 25, 26, 29, 28, 28, 33, 26, 24, 22, 29, 32, 27, 25, 25, 27, 29, 31, 30, 26, 27, 22, 19, 20, 22, 23, 23, 23, 26, 27, 25, 22, 20, 17, 19, 17, 20, 20, 17, 19, 17, 15, 11, 13, 12, 11, 9, 4, 4, 6, 9, 9, 13, 19, 22, 21, 15, 11, 14, 26, 31, 36, 30, 28, 30, 32, 29, 23, 18, 13, 11, 6, 1, 254, 252, 252, 255, 255, 3, 2, 2, 3, 7, 10, 9, 11, 18, 25, 28, 36, 35, 32, 34, 38, 38, 39, 33, 29, 31, 29, 23, 17, 14, 11, 10, 13, 9, 3, 1, 4, 6, 8, 11, 10, 9, 7, 8, 7, 16, 16, 13, 13, 10, 12, 16, 16, 12, 9, 13, 10, 10, 8, 13, 10, 10, 12, 12, 17, 17, 19, 19, 20, 25, 22, 25, 25, 28, 26, 21, 15, 8, 3, 4, 6, 8, 4, 253, 252, 0, 0, 255, 253, 253, 0, 5, 10, 9, 6, 6, 6, 14, 14, 13, 9, 6, 12, 12, 15, 14, 11, 9, 10, 14, 15, 17, 20, 23, 26, 31, 37, 37, 37, 34, 38, 40, 40, 35, 32, 29, 25, 26, 20, 18, 15, 10, 15, 15, 15, 13, 11, 20, 16, 14, 11, 15, 20, 25, 24, 25, 26, 28, 30, 29, 34, 31, 27, 26, 25, 26, 25, 21, 14, 13, 10, 12, 11, 8, 7, 3, 1, 4, 8, 8, 8, 7, 4, 6, 6, 10, 12, 21, 22, 21, 23, 17, 17, 21, 24, 25, 26, 24, 20, 21, 23, 26, 26, 23, 17, 18, 13, 16, 21, 20, 16, 15, 15, 16, 12, 14, 10, 14, 15, 14, 11, 9, 7, 8, 7, 13, 11, 8, 8, 9, 11, 14, 13, 17, 17, 22, 22, 22, 22, 20, 11, 11, 10, 11, 18, 11, 6, 7, 6, 6, 9, 7, 8, 5, 4, 9, 15, 15, 18, 17, 20, 21, 26, 29, 26, 24, 25, 28, 25, 24, 23, 22, 19, 17, 16, 16, 13, 9, 8, 8, 9, 14, 18, 21, 23, 23, 22, 25, 31, 34, 33, 35, 39, 40, 39, 37, 37, 38, 40, 36, 33, 30, 26, 25, 20, 17, 12, 13, 16, 20, 14, 11, 13, 9, 16, 13, 11, 13, 13, 16, 18, 20, 19, 22, 25, 21, 23, 23, 19, 17, 15, 20, 22, 25, 26, 26, 26, 27, 26, 26, 26, 25, 16, 15, 16, 17, 20, 17, 15, 13, 10, 8, 7, 6, 2, 5, 5, 2, 5, 7, 12, 15, 13, 14, 17, 19, 20, 19, 23, 20, 20, 21, 23, 25, 28, 25, 25, 18, 20, 17, 16, 10, 12, 11, 8, 10, 10, 7, 8, 13, 13, 13, 15, 16, 21, 15, 16, 19, 26, 25, 28, 31, 29, 32, 33, 32, 28, 26, 20, 16, 19, 16, 14, 8, 13, 11, 6, 4, 6, 9, 9, 9, 7, 10, 9, 7, 15, 13, 19, 24, 25, 25, 28, 25, 24, 24, 28, 29, 27, 24, 24, 22, 22, 22, 15, 19, 16, 18, 14, 15, 17, 17, 18, 17, 17, 17, 19, 19, 21, 20, 27, 26, 25, 23, 24, 23, 27, 27, 35, 32, 34, 34, 32, 34, 32, 32, 33, 32, 32, 29, 31, 29, 29, 28, 26, 24, 23, 21, 19, 18, 18, 22, 23, 21, 21, 20, 22, 20, 25, 29, 27, 24, 26, 25, 24, 25, 26, 26, 27, 27, 28, 23, 21, 18, 14, 18, 16, 19, 18, 19, 18, 20, 17, 17, 17, 16, 20, 18, 16, 16, 17, 15, 17, 15, 12, 13, 11, 15, 19, 43, 39, 17, 19, 17, 22, 25, 22, 28, 44, 36, 26, 21, 25, 17, 20, 15, 14, 9, 4, 6, 6, 1, 3, 10, 9, 10, 8, 9, 12, 14, 11, 13, 13, 10, 11, 14, 15, 15, 18, 22, 25, 24, 26, 33, 33, 37, 42, 46, 48, 48, 48, 43, 48, 46, 38, 40, 40, 42, 43, 41, 38, 35, 32, 25, 25, 22, 20, 18, 20, 19, 20, 19, 19, 25, 20, 22, 20, 19, 16, 19, 17, 19, 20, 21, 18, 17, 19, 20, 21, 20, 21, 19, 19, 21, 15, 19, 20, 20, 21, 23, 21, 22, 17, 16, 15, 19, 13, 11, 12, 14, 15, 16, 15, 17, 20, 19, 19, 17, 15, 20, 20, 20, 22, 26, 32, 34, 32, 29, 30, 25, 26, 28, 27, 27, 27, 27, 25, 23, 22, 21, 24, 20, 19, 14, 14, 13, 13, 12, 11, 13, 12, 12, 12, 10, 6, 5, 8, 7, 6, 4, 9, 10, 13, 15, 13, 12, 10, 12, 15, 14, 17, 16, 14, 18, 21, 20, 24, 25, 25, 25, 28, 32, 30, 27, 26, 26, 26, 27, 25, 26, 26, 28, 26, 22, 21, 20, 16, 15, 18, 13, 14, 15, 19, 22, 21, 22, 22, 25, 26, 27, 28, 28, 23, 28, 31, 32, 32, 34, 32, 32, 33, 35, 31, 29, 27, 27, 26, 28, 29, 25, 25, 26, 24, 25, 25, 22, 23, 25, 25, 26, 24, 23, 27, 29, 26, 26, 25, 22, 22, 26, 25, 27, 27, 29, 28, 30, 31, 29, 28, 29, 30, 30, 31, 30, 29, 25, 29, 29, 30, 29, 27, 27, 24, 23, 23, 22, 20, 16, 17, 18, 17, 16, 17, 16, 12, 14, 15, 15, 13, 12, 13, 14, 19, 20, 22, 18, 15, 19, 20, 20, 23, 25, 21, 26, 22, 25, 27, 26, 23, 25, 21, 23, 20, 20, 19, 16, 18, 16, 14, 19, 14, 12, 14, 12, 11, 8, 8, 11, 13, 13, 11, 66, 4, 32, 0, 3, 4, 3, 4, 3, 3, 3, 4, 3, 2, 3, 3, 1, 2, 1, 2, 1, 2, 0, 1, 0, 2, 1, 2, 0, 2, 0, 3, 254, 3, 198, 132, 211, 3, 9, 250, 251, 8, 20, 21, 7, 0, 6, 4, 2, 6, 19, 13, 2, 251, 253, 6, 13, 12, 14, 14, 9, 245, 190, 196, 229, 245, 251, 251, 1, 235, 150, 135, 155, 167, 164, 155, 173, 213, 244, 247, 249, 248, 239, 238, 255, 33, 62, 60, 36, 18, 8, 30, 64, 70, 58, 50, 41, 29, 50, 80, 86, 68, 45, 34, 43, 60, 63, 47, 22, 253, 244, 240, 246, 243, 227, 208, 201, 210, 227, 240, 240, 231, 225, 225, 231, 236, 242, 239, 233, 230, 235, 245, 2, 12, 17, 21, 30, 51, 75, 80, 78, 78, 77, 76, 70, 64, 49, 34, 26, 23, 28, 32, 28, 24, 23, 25, 24, 23, 24, 28, 32, 31, 33, 30, 24, 17, 9, 10, 13, 4, 254, 251, 250, 5, 13, 21, 26, 23, 21, 23, 32, 35, 30, 27, 34, 45, 50, 38, 33, 34, 32, 31, 31, 36, 39, 37, 33, 33, 30, 26, 19, 17, 21, 17, 1, 250, 250, 0, 5, 0, 253, 5, 13, 14, 12, 18, 34, 26, 13, 7, 3, 2, 7, 255, 245, 244, 249, 4, 19, 26, 15, 7, 27, 51, 53, 45, 30, 23, 13, 0, 244, 240, 249, 4, 10, 15, 28, 32, 24, 10, 12, 27, 33, 30, 24, 22, 17, 4, 3, 19, 27, 14, 4, 6, 12, 17, 24, 22, 21, 27, 30, 22, 15, 14, 7, 8, 9, 252, 0, 7, 8, 0, 243, 243, 247, 250, 0, 4, 12, 21, 11, 6, 13, 12, 2, 244, 241, 254, 12, 9, 243, 240, 0, 3, 0, 252, 0, 5, 18, 29, 33, 36, 32, 33, 25, 18, 14, 9, 8, 250, 240, 251, 16, 14, 4, 14, 21, 26, 28, 8, 252, 249, 243, 232, 216, 215, 231, 237, 240, 251, 252, 248, 10, 23, 25, 21, 0, 236, 227, 248, 5, 4, 9, 21, 18, 12, 16, 16, 2, 11, 37, 32, 14, 5, 253, 249, 0, 10, 8, 11, 37, 38, 27, 31, 27, 13, 0, 3, 9, 9, 255, 220, 210, 226, 248, 253, 249, 231, 227, 245, 8, 21, 5, 246, 0, 9, 36, 59, 39, 21, 17, 24, 33, 27, 0, 249, 1, 1, 1, 0, 253, 5, 18, 10, 13, 16, 10, 5, 255, 3, 12, 17, 25, 18, 14, 20, 18, 9, 251, 233, 219, 228, 251, 251, 237, 230, 233, 245, 252, 245, 229, 222, 228, 246, 15, 49, 43, 23, 32, 47, 54, 40, 20, 16, 18, 24, 8, 237, 254, 18, 21, 40, 57, 63, 52, 33, 23, 10, 21, 14, 245, 245, 9, 3, 244, 6, 35, 43, 25, 12, 5, 12, 16, 5, 252, 242, 230, 218, 219, 243, 247, 237, 253, 13, 16, 14, 19, 16, 17, 30, 37, 31, 28, 32, 46, 65, 62, 39, 19, 25, 38, 20, 247, 247, 1, 253, 236, 219, 236, 255, 253, 3, 1, 14, 28, 5, 249, 255, 247, 247, 252, 4, 19, 20, 255, 248, 243, 1, 8, 255, 4, 15, 21, 28, 40, 47, 35, 13, 246, 239, 254, 12, 255, 250, 14, 42, 56, 57, 44, 39, 43, 37, 30, 19, 6, 248, 235, 232, 209, 171, 194, 208, 234, 247, 6, 12, 14, 36, 46, 37, 33, 37, 43, 35, 32, 18, 6, 29, 49, 27, 254, 244, 254, 14, 17, 27, 37, 35, 16, 10, 18, 14, 0, 246, 255, 9, 19, 21, 251, 243, 255, 24, 37, 30, 24, 16, 13, 3, 255, 250, 242, 234, 227, 225, 208, 206, 226, 241, 252, 3, 13, 24, 15, 10, 17, 32, 43, 42, 31, 39, 43, 27, 11, 10, 17, 10, 6, 9, 8, 11, 15, 7, 0, 1, 254, 255, 7, 3, 255, 1, 1, 3, 6, 7, 247, 242, 252, 0, 0, 251, 255, 5, 2, 254, 245, 227, 224, 246, 5, 14, 10, 0, 7, 6, 6, 12, 21, 29, 19, 2, 5, 17, 27, 20, 7, 1, 7, 15, 15, 9, 4, 3, 3, 251, 0, 249, 241, 233, 226, 226, 234, 238, 234, 222, 234, 245, 245, 243, 247, 255, 255, 253, 1, 1, 3, 248, 247, 1, 2, 7, 1, 0, 0, 255, 2, 12, 18, 21, 27, 19, 5, 8, 6, 253, 255, 4, 8, 7, 3, 1, 2, 3, 3, 7, 9, 10, 7, 252, 255, 0, 251, 247, 240, 237, 247, 254, 251, 252, 5, 11, 7, 255, 250, 247, 247, 252, 6, 4, 248, 247, 2, 11, 13, 3, 4, 16, 15, 10, 2, 252, 2, 8, 7, 5, 251, 245, 0, 14, 19, 14, 6, 10, 13, 14, 3, 250, 250, 2, 12, 13, 19, 16, 2, 0, 14, 17, 13, 3, 249, 251, 12, 13, 9, 8, 6, 10, 17, 24, 17, 251, 237, 248, 4, 251, 245, 241, 241, 247, 245, 248, 1, 3, 0, 1, 12, 14, 8, 254, 3, 11, 0, 244, 239, 242, 251, 253, 253, 253, 247, 244, 254, 4, 11, 5, 2, 4, 9, 9, 9, 12, 14, 13, 3, 4, 12, 12, 4, 250, 254, 255, 0, 6, 3, 1, 253, 244, 249, 5, 1, 255, 0, 11, 25, 31, 20, 6, 2, 4, 6, 7, 9, 0, 253, 5, 26, 30, 22, 20, 16, 15, 17, 20, 19, 22, 20, 7, 9, 22, 15, 252, 243, 253, 17, 20, 8, 1, 2, 8, 6, 10, 12, 7, 1, 0, 2, 9, 9, 7, 9, 20, 28, 29, 24, 16, 15, 21, 24, 25, 13, 252, 252, 4, 6, 0, 241, 244, 1, 4, 2, 254, 255, 6, 12, 10, 13, 15, 12, 7, 1, 5, 7, 255, 246, 249, 2, 1, 250, 250, 5, 22, 17, 8, 7, 15, 21, 18, 25, 28, 34, 34, 27, 23, 22, 21, 13, 4, 1, 5, 254, 244, 250, 5, 12, 10, 8, 20, 29, 23, 15, 12, 17, 21, 15, 6, 4, 7, 5, 252, 251, 254, 255, 1, 3, 255, 250, 243, 237, 244, 252, 1, 3, 4, 10, 16, 22, 32, 34, 23, 15, 17, 20, 15, 4, 253, 253, 1, 1, 1, 6, 13, 21, 17, 17, 22, 17, 12, 15, 16, 12, 11, 8, 3, 255, 0, 2, 6, 9, 13, 14, 12, 14, 13, 9, 1, 249, 247, 250, 245, 245, 246, 254, 6, 9, 8, 14, 17, 13, 12, 5, 7, 15, 11, 9, 9, 0, 0, 40, 3, 18, 0, 12, 12, 4, 5, 19, 13, 14, 10, 10, 6, 248, 247, 255, 253, 11, 6, 6, 4, 3, 208, 162, 133, 132, 159, 181, 210, 239, 19, 21, 3, 250, 11, 17, 15, 15, 23, 30, 31, 31, 27, 13, 4, 248, 245, 6, 27, 50, 59, 62, 60, 57, 58, 59, 66, 66, 61, 59, 53, 31, 17, 6, 252, 8, 11, 15, 5, 218, 214, 202, 179, 177, 193, 224, 232, 227, 247, 248, 231, 231, 238, 244, 255, 0, 5, 11, 12, 15, 16, 16, 18, 14, 13, 14, 14, 21, 23, 22, 26, 31, 34, 33, 38, 43, 44, 47, 41, 39, 39, 37, 42, 30, 33, 32, 29, 29, 22, 14, 9, 250, 245, 0, 1, 0, 12, 19, 29, 21, 21, 27, 22, 12, 14, 242, 254, 22, 18, 5, 255, 9, 20, 14, 5, 12, 21, 24, 21, 15, 25, 36, 32, 37, 42, 49, 50, 47, 41, 45, 47, 41, 34, 31, 31, 36, 29, 27, 26, 28, 32, 28, 25, 24, 21, 22, 21, 15, 10, 11, 16, 11, 10, 10, 254, 250, 254, 3, 2, 2, 4, 8, 12, 16, 20, 19, 22, 32, 37, 42, 41, 37, 40, 42, 45, 44, 38, 33, 34, 35, 34, 37, 35, 34, 32, 27, 19, 22, 18, 16, 14, 254, 252, 0, 249, 4, 23, 23, 18, 11, 9, 8, 4, 6, 11, 20, 28, 32, 34, 41, 44, 41, 36, 32, 32, 27, 22, 21, 25, 30, 38, 40, 36, 41, 32, 19, 9, 8, 8, 8, 11, 11, 12, 13, 5, 9, 12, 8, 6, 253, 248, 248, 249, 252, 5, 15, 20, 22, 23, 28, 23, 15, 17, 22, 30, 28, 27, 30, 38, 46, 50, 45, 42, 37, 34, 24, 22, 23, 18, 14, 14, 13, 6, 3, 250, 243, 244, 248, 251, 247, 248, 248, 250, 255, 11, 25, 24, 19, 16, 9, 0, 6, 31, 38, 32, 31, 34, 29, 32, 38, 41, 32, 21, 12, 12, 3, 0, 253, 0, 3, 11, 11, 4, 1, 10, 13, 19, 22, 20, 23, 23, 27, 27, 25, 21, 12, 11, 20, 35, 51, 52, 31, 9, 253, 247, 246, 254, 6, 5, 254, 247, 249, 253, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, 3, 26, 0, 9, 9, 9, 9, 10, 9, 10, 8, 9, 8, 10, 8, 7, 9, 8, 7, 7, 7, 9, 7, 6, 8, 7, 6, 8, 7, 7, 7, 6, 3, 5, 2, 8, 2, 4, 206, 151, 181, 217, 246, 5, 0, 244, 159, 133, 202, 252, 16, 14, 16, 12, 15, 15, 12, 23, 27, 27, 27, 28, 30, 31, 22, 21, 24, 16, 17, 19, 20, 233, 187, 188, 195, 200, 216, 246, 6, 8, 14, 18, 24, 19, 7, 254, 248, 203, 165, 164, 177, 198, 214, 228, 2, 27, 46, 50, 52, 57, 49, 46, 49, 51, 43, 37, 42, 50, 58, 64, 66, 62, 49, 37, 28, 24, 18, 5, 247, 241, 238, 239, 243, 248, 251, 252, 253, 2, 7, 11, 14, 13, 15, 10, 8, 9, 7, 5, 252, 246, 248, 253, 6, 12, 22, 31, 41, 45, 53, 64, 66, 61, 55, 45, 41, 38, 36, 33, 33, 33, 32, 35, 41, 44, 44, 38, 31, 29, 26, 18, 10, 9, 8, 0, 0, 4, 9, 11, 15, 15, 18, 15, 17, 15, 7, 2, 255, 254, 0, 0, 3, 1, 7, 13, 13, 21, 22, 19, 13, 16, 18, 17, 22, 18, 19, 14, 7, 1, 9, 241, 195, 217, 243, 253, 11, 12, 5, 4, 253, 238, 245, 254, 255, 9, 33, 37, 35, 39, 33, 28, 34, 44, 46, 52, 44, 31, 23, 21, 6, 255, 0, 255, 2, 20, 32, 33, 36, 32, 22, 14, 11, 0, 251, 250, 254, 250, 0, 251, 242, 239, 224, 224, 235, 0, 29, 42, 31, 15, 254, 229, 222, 239, 8, 22, 37, 36, 29, 39, 42, 22, 11, 19, 22, 27, 32, 26, 4, 243, 250, 9, 29, 41, 33, 18, 17, 9, 252, 237, 248, 3, 6, 0, 251, 255, 13, 27, 16, 11, 6, 251, 247, 0, 17, 18, 9, 13, 29, 39, 35, 9, 254, 244, 243, 252, 3, 19, 9, 253, 6, 18, 29, 36, 26, 21, 24, 22, 15, 20, 19, 9, 1, 13, 37, 35, 36, 11, 5, 25, 5, 251, 254, 0, 252, 248, 250, 242, 246, 4, 15, 31, 31, 16, 6, 246, 7, 18, 21, 30, 23, 34, 33, 28, 23, 16, 15, 22, 30, 43, 23, 253, 249, 249, 249, 254, 26, 41, 57, 29, 251, 3, 15, 12, 0, 10, 8, 9, 11, 254, 0, 7, 0, 249, 255, 252, 248, 239, 236, 238, 246, 4, 251, 1, 11, 9, 242, 238, 9, 34, 35, 1, 0, 29, 8, 6, 8, 255, 3, 26, 35, 25, 44, 19, 196, 185, 231, 223, 229, 15, 20, 249, 247, 10, 2, 1, 33, 39, 6, 4, 33, 22, 4, 15, 16, 9, 18, 32, 40, 40, 37, 19, 12, 16, 6, 249, 252, 26, 30, 8, 255, 2, 7, 20, 37, 40, 26, 5, 255, 253, 8, 16, 12, 0, 0, 6, 3, 3, 3, 6, 255, 255, 3, 1, 255, 6, 7, 8, 14, 14, 12, 18, 21, 9, 1, 5, 11, 10, 7, 12, 22, 23, 20, 18, 11, 7, 9, 10, 20, 11, 0, 0, 10, 18, 19, 9, 4, 11, 19, 21, 20, 11, 5, 248, 244, 249, 10, 26, 21, 17, 10, 3, 7, 14, 3, 252, 1, 4, 253, 253, 7, 10, 18, 24, 30, 30, 10, 251, 251, 3, 13, 6, 0, 0, 255, 5, 21, 39, 43, 17, 249, 253, 11, 8, 255, 252, 3, 23, 30, 22, 7, 247, 238, 244, 11, 31, 36, 8, 233, 232, 248, 5, 14, 20, 21, 19, 23, 16, 7, 254, 248, 253, 8, 26, 18, 243, 245, 252, 1, 20, 31, 42, 41, 19, 255, 236, 245, 0, 253, 1, 13, 16, 246, 226, 251, 21, 33, 23, 17, 18, 8, 249, 243, 4, 15, 27, 32, 25, 11, 6, 251, 234, 252, 24, 22, 21, 26, 8, 231, 235, 0, 12, 18, 26, 18, 251, 245, 247, 255, 253, 11, 24, 5, 243, 249, 0, 255, 253, 2, 10, 2, 8, 253, 239, 251, 10, 6, 2, 7, 8, 8, 17, 26, 10, 250, 4, 7, 12, 7, 252, 250, 11, 28, 29, 10, 231, 218, 3, 43, 40, 0, 231, 237, 246, 245, 253, 255, 255, 9, 13, 0, 252, 250, 235, 248, 13, 13, 246, 235, 253, 4, 10, 9, 10, 253, 234, 253, 14, 8, 252, 238, 236, 255, 28, 30, 11, 1, 9, 16, 10, 252, 253, 13, 22, 24, 14, 246, 235, 249, 2, 0, 3, 11, 14, 7, 0, 245, 244, 252, 0, 15, 29, 23, 0, 244, 250, 2, 25, 40, 25, 4, 255, 249, 0, 7, 20, 9, 253, 9, 15, 7, 11, 3, 251, 11, 33, 31, 10, 3, 5, 2, 0, 10, 7, 1, 6, 4, 0, 10, 3, 249, 246, 2, 10, 253, 0, 4, 5, 253, 251, 2, 14, 8, 10, 17, 13, 8, 9, 11, 9, 6, 21, 17, 253, 248, 15, 28, 18, 6, 2, 6, 10, 8, 12, 23, 17, 6, 6, 8, 4, 254, 3, 23, 21, 250, 253, 16, 8, 10, 11, 17, 30, 17, 9, 9, 11, 20, 25, 6, 9, 2, 0, 23, 32, 23, 4, 4, 2, 15, 30, 22, 17, 8, 1, 10, 11, 0, 254, 17, 39, 13, 230, 240, 16, 19, 0, 12, 20, 10, 5, 248, 1, 37, 50, 19, 254, 3, 247, 2, 29, 33, 21, 12, 10, 0, 8, 28, 36, 34, 18, 252, 240, 7, 8, 0, 12, 14, 18, 5, 233, 230, 254, 7, 4, 13, 6, 240, 235, 240, 246, 253, 8, 3, 240, 241, 0, 255, 247, 2, 8, 8, 12, 2, 240, 253, 24, 26, 17, 10, 255, 3, 8, 2, 3, 18, 30, 23, 9, 9, 23, 18, 9, 23, 31, 36, 16, 250, 0, 26, 38, 34, 15, 8, 4, 5, 13, 20, 31, 10, 10, 20, 254, 255, 15, 15, 29, 34, 18, 3, 8, 10, 3, 21, 31, 19, 7, 252, 4, 18, 16, 4, 249, 1, 1, 253, 7, 8, 255, 241, 252, 4, 249, 242, 246, 5, 15, 255, 106, 3, 24, 0, 9, 9, 3, 4, 14, 10, 10, 8, 7, 4, 250, 250, 0, 254, 8, 5, 4, 3, 2, 220, 185, 164, 163, 184, 200, 222, 244, 14, 16, 2, 252, 8, 13, 11, 12, 17, 22, 23, 23, 21, 9, 3, 251, 248, 4, 20, 38, 44, 47, 45, 43, 43, 44, 50, 49, 46, 44, 40, 23, 13, 4, 254, 6, 8, 11, 4, 228, 225, 216, 199, 197, 209, 232, 239, 234, 250, 250, 238, 237, 243, 247, 0, 0, 4, 9, 9, 11, 12, 12, 13, 10, 9, 10, 11, 16, 18, 16, 20, 23, 25, 25, 29, 33, 33, 35, 31, 29, 29, 28, 31, 23, 25, 24, 22, 21, 17, 11, 7, 252, 248, 0, 0, 0, 9, 14, 21, 15, 16, 20, 17, 9, 10, 246, 255, 17, 13, 4, 255, 7, 15, 10, 3, 9, 16, 18, 16, 11, 19, 27, 24, 27, 32, 36, 37, 36, 31, 34, 35, 30, 25, 23, 23, 27, 22, 20, 20, 21, 24, 21, 19, 18, 16, 17, 16, 11, 8, 8, 12, 8, 7, 8, 255, 251, 255, 2, 2, 2, 3, 6, 9, 12, 15, 14, 16, 24, 28, 31, 31, 28, 30, 32, 34, 33, 29, 25, 26, 27, 25, 28, 26, 26, 24, 20, 15, 17, 13, 12, 10, 255, 253, 0, 251, 3, 17, 17, 14, 8, 7, 6, 3, 4, 8, 15, 21, 24, 26, 31, 33, 30, 27, 24, 24, 20, 17, 16, 19, 23, 29, 30, 27, 31, 24, 14, 7, 6, 6, 6, 8, 8, 9, 10, 4, 7, 9, 6, 4, 254, 250, 250, 251, 253, 4, 11, 15, 16, 17, 21, 17, 11, 13, 17, 23, 21, 20, 22, 28, 34, 38, 34, 31, 28, 25, 18, 17, 17, 14, 10, 11, 10, 5, 2, 252, 246, 248, 250, 253, 250, 250, 250, 252, 0, 8, 19, 18, 15, 12, 7, 0, 4, 23, 28, 24, 24, 25, 22, 24, 29, 31, 24, 15, 9, 9, 3, 0, 254, 0, 2, 8, 8, 3, 1, 8, 10, 14, 16, 15, 17, 17, 20, 20, 19, 16, 9, 8, 15, 26, 38, 39, 23, 7, 254, 249, 249, 255, 4, 4, 255, 250, 251, 254, 1, 2, 2, 0, 8, 22, 26, 10, 10, 30, 34, 16, 16, 19, 15, 2, 251, 8, 17, 5, 242, 227, 225, 239, 239, 236, 229, 227, 239, 254, 251, 255, 1, 13, 20, 24, 43, 39, 28, 29, 31, 18, 8, 20, 21, 2, 10, 29, 23, 19, 9, 255, 243, 244, 19, 16, 234, 249, 10, 4, 6, 13, 34, 25, 14, 26, 26, 15, 29, 17, 251, 244, 15, 32, 2, 242, 4, 10, 3, 18, 29, 16, 251, 10, 17, 254, 8, 24, 26, 15, 30, 68, 60, 42, 47, 41, 18, 246, 252, 15, 17, 20, 21, 10, 7, 20, 0, 236, 233, 7, 27, 8, 251, 253, 4, 26, 33, 18, 4, 254, 255, 1, 20, 39, 60, 64, 41, 15, 10, 20, 12, 241, 239, 27, 39, 26, 26, 27, 21, 21, 19, 13, 9, 25, 39, 29, 12, 3, 248, 9, 52, 67, 53, 17, 236, 223, 228, 3, 10, 234, 231, 249, 250, 233, 228, 239, 233, 237, 255, 20, 36, 9, 228, 206, 229, 6, 32, 16, 252, 232, 236, 253, 0, 244, 254, 0, 248, 220, 210, 229, 231, 226, 240, 1, 6, 254, 2, 0, 242, 1, 13, 10, 24, 51, 64, 52, 47, 43, 30, 26, 39, 21, 246, 248, 1, 1, 241, 245, 12, 24, 18, 8, 3, 26, 24, 25, 32, 60, 99, 100, 93, 72, 47, 33, 36, 34, 40, 47, 71, 68, 35, 255, 254, 2, 18, 44, 35, 18, 14, 27, 17, 39, 69, 42, 253, 10, 50, 67, 29, 0, 248, 8, 16, 6, 241, 214, 251, 31, 2, 233, 249, 231, 201, 209, 228, 244, 250, 0, 243, 219, 240, 239, 220, 203, 220, 237, 212, 196, 207, 252, 6, 237, 191, 173, 183, 191, 225, 238, 218, 227, 242, 243, 220, 212, 201, 213, 229, 243, 0, 225, 224, 232, 254, 6, 1, 245, 231, 240, 4, 4, 253, 4, 10, 248, 251, 28, 45, 24, 7, 21, 20, 10, 11, 23, 23, 23, 33, 40, 20, 0, 14, 25, 13, 7, 23, 30, 20, 46, 83, 80, 40, 25, 37, 37, 40, 48, 48, 47, 72, 73, 45, 16, 11, 19, 21, 33, 51, 71, 85, 84, 60, 33, 19, 22, 33, 45, 55, 48, 28, 29, 39, 36, 23, 14, 11, 16, 37, 46, 37, 14, 9, 11, 28, 40, 21, 250, 242, 8, 45, 43, 3, 217, 236, 25, 64, 58, 27, 12, 243, 236, 212, 218, 250, 27, 40, 14, 240, 228, 232, 213, 185, 203, 235, 249, 243, 14, 32, 249, 235, 222, 225, 235, 18, 12, 236, 251, 39, 57, 18, 26, 41, 255, 219, 231, 248, 244, 254, 27, 29, 7, 4, 237, 188, 198, 216, 214, 206, 224, 246, 222, 222, 244, 250, 234, 239, 243, 233, 231, 229, 236, 233, 247, 4, 1, 253, 229, 205, 173, 173, 195, 182, 196, 217, 252, 247, 217, 173, 134, 156, 198, 213, 203, 205, 214, 213, 229, 249, 13, 254, 232, 252, 8, 12, 0, 0, 0, 188, 4, 15, 0, 32, 20, 44, 55, 14, 36, 37, 12, 13, 23, 241, 240, 13, 253, 5, 17, 226, 0, 245, 12, 228, 250, 230, 250, 237, 251, 22, 3, 53, 11, 2, 39, 1, 20, 40, 35, 9, 221, 25, 18, 17, 227, 252, 27, 247, 0, 51, 28, 29, 37, 34, 30, 48, 18, 30, 63, 55, 54, 252, 61, 66, 33, 52, 35, 69, 52, 75, 53, 31, 54, 72, 31, 27, 58, 12, 41, 44, 43, 245, 26, 23, 5, 237, 4, 247, 244, 21, 3, 241, 21, 3, 6, 5, 31, 7, 25, 43, 11, 36, 64, 37, 82, 41, 21, 47, 36, 40, 21, 51, 64, 13, 18, 59, 22, 49, 255, 17, 45, 30, 21, 23, 18, 15, 32, 25, 22, 226, 19, 26, 247, 32, 248, 5, 17, 41, 6, 24, 12, 234, 27, 23, 59, 249, 1, 14, 32, 43, 250, 246, 252, 42, 35, 251, 8, 45, 245, 6, 3, 5, 7, 40, 226, 18, 30, 0, 243, 22, 251, 3, 57, 50, 230, 235, 89, 9, 234, 62, 14, 240, 82, 68, 216, 7, 20, 16, 10, 247, 21, 236, 223, 59, 40, 166, 4, 245, 223, 22, 252, 17, 15, 27, 249, 32, 22, 245, 3, 46, 49, 228, 59, 41, 249, 44, 29, 25, 9, 246, 69, 241, 36, 25, 7, 0, 18, 47, 217, 248, 0, 241, 32, 46, 251, 238, 24, 67, 28, 230, 35, 31, 47, 13, 41, 85, 0, 14, 72, 239, 57, 70, 245, 16, 31, 22, 24, 32, 30, 36, 39, 75, 7, 217, 13, 61, 15, 253, 57, 66, 223, 38, 77, 36, 235, 242, 66, 60, 237, 2, 52, 8, 48, 25, 208, 61, 45, 234, 227, 12, 68, 202, 242, 97, 227, 252, 94, 216, 240, 50, 255, 4, 252, 41, 235, 18, 81, 235, 17, 251, 64, 214, 213, 80, 239, 210, 80, 33, 185, 39, 226, 37, 239, 224, 47, 255, 36, 38, 14, 62, 254, 12, 42, 23, 239, 48, 4, 16, 239, 5, 60, 245, 68, 221, 240, 54, 234, 212, 22, 22, 16, 253, 95, 49, 146, 20, 89, 202, 10, 102, 228, 243, 84, 26, 248, 22, 78, 235, 224, 38, 37, 196, 28, 75, 209, 16, 62, 234, 247, 13, 244, 56, 11, 237, 35, 58, 233, 251, 67, 36, 214, 53, 61, 0, 77, 236, 5, 58, 47, 10, 251, 11, 42, 0, 224, 14, 10, 21, 241, 20, 50, 28, 203, 238, 72, 60, 12, 250, 18, 53, 1, 14, 30, 238, 41, 60, 255, 253, 41, 29, 236, 202, 59, 73, 203, 2, 255, 187, 77, 30, 153, 253, 96, 2, 144, 24, 109, 205, 195, 66, 55, 9, 236, 192, 41, 44, 7, 203, 41, 97, 239, 215, 252, 69, 53, 244, 226, 85, 95, 183, 208, 72, 64, 242, 231, 245, 32, 51, 235, 10, 252, 49, 11, 161, 64, 78, 240, 248, 16, 72, 52, 234, 45, 31, 226, 4, 238, 3, 40, 17, 244, 254, 248, 242, 250, 239, 13, 13, 221, 9, 215, 2, 80, 10, 248, 40, 14, 38, 34, 210, 245, 34, 253, 7, 7, 70, 13, 215, 13, 34, 47, 230, 218, 68, 51, 8, 36, 236, 10, 50, 183, 6, 0, 187, 20, 28, 215, 234, 6, 245, 53, 239, 198, 36, 7, 237, 36, 34, 16, 14, 215, 4, 55, 245, 14, 91, 59, 6, 2, 19, 44, 40, 237, 72, 120, 64, 6, 39, 66, 47, 16, 14, 71, 57, 19, 252, 23, 13, 9, 70, 25, 200, 11, 18, 233, 230, 36, 51, 29, 65, 45, 18, 249, 8, 7, 237, 41, 26, 250, 72, 87, 203, 240, 85, 2, 144, 217, 11, 13, 37, 4, 41, 120, 30, 195, 248, 67, 11, 184, 215, 60, 43, 214, 27, 120, 49, 209, 223, 20, 40, 194, 173, 246, 53, 20, 253, 23, 249, 1, 249, 213, 233, 221, 199, 213, 28, 67, 28, 248, 1, 36, 254, 222, 58, 53, 248, 10, 58, 79, 41, 20, 53, 59, 251, 227, 231, 253, 255, 235, 13, 41, 34, 228, 212, 32, 81, 18, 158, 232, 69, 13, 220, 3, 96, 63, 31, 35, 43, 45, 231, 234, 59, 77, 27, 14, 31, 69, 27, 235, 26, 231, 0, 56, 63, 21, 216, 4, 46, 36, 11, 246, 250, 243, 238, 248, 31, 16, 233, 6, 11, 15, 7, 10, 5, 41, 72, 241, 233, 248, 254, 2, 6, 30, 20, 254, 10, 246, 4, 28, 225, 253, 61, 59, 42, 0, 248, 51, 52, 41, 13, 4, 7, 2, 25, 49, 26, 27, 42, 3, 31, 65, 4, 225, 29, 41, 13, 29, 255, 5, 16, 25, 46, 29, 8, 27, 6, 251, 24, 239, 227, 34, 31, 254, 17, 36, 255, 5, 16, 21, 29, 38, 14, 1, 30, 66, 34, 1, 16, 47, 14, 253, 22, 26, 20, 22, 14, 25, 42, 237, 237, 21, 3, 249, 243, 248, 0, 221, 210, 247, 9, 15, 7, 250, 247, 35, 23, 4, 2, 235, 7, 40, 10, 0, 28, 46, 38, 242, 254, 54, 45, 5, 242, 3, 28, 53, 25, 13, 44, 35, 15, 22, 23, 34, 17, 6, 17, 25, 19, 8, 0, 62, 88, 15, 242, 0, 18, 49, 241, 237, 34, 8, 18, 23, 15, 6, 245, 237, 12, 28, 17, 28, 35, 56, 39, 33, 43, 42, 9, 1, 50, 34, 25, 2, 9, 22, 35, 28, 247, 244, 19, 25, 8, 4, 24, 16, 244, 246, 20, 251, 224, 255, 12, 16, 18, 246, 225, 246, 34, 54, 24, 245, 9, 7, 43, 53, 33, 35, 16, 34, 43, 41, 18, 9, 21, 35, 31, 18, 0, 240, 254, 11, 40, 34, 233, 244, 29, 41, 20, 11, 34, 16, 3, 31, 35, 0, 239, 17, 41, 29, 30, 3, 0, 28, 40, 13, 18, 6, 249, 37, 18, 8, 29, 5, 6, 26, 28, 33, 6, 249, 29, 24, 3, 19, 3, 7, 68, 54, 17, 9, 23, 49, 27, 3, 31, 27, 16, 23, 0, 18, 26, 254, 239, 246, 10, 9, 228, 255, 41, 28, 17, 7, 17, 29, 13, 11, 35, 32, 12, 36, 33, 7, 11, 33, 46, 18, 9, 18, 248, 7, 46, 38, 36, 53, 49, 22, 28, 47, 28, 20, 11, 31, 39, 1, 236, 250, 245, 4, 13, 14, 8, 244, 13, 41, 27, 18, 12, 12, 27, 18, 13, 9, 27, 38, 24, 12, 15, 41, 37, 21, 33, 60, 38, 13, 30, 46, 46, 36, 24, 41, 43, 16, 22, 25, 17, 14, 252, 7, 17, 7, 7, 7, 15, 26, 16, 247, 9, 30, 18, 27, 26, 35, 54, 18, 18, 54, 29, 249, 0, 2, 32, 11, 240, 251, 19, 31, 14, 2, 14, 253, 248, 3, 9, 21, 21, 20, 43, 50, 32, 35, 21, 16, 27, 23, 16, 19, 34, 42, 34, 16, 20, 26, 22, 253, 247, 3, 11, 255, 250, 21, 21, 253, 247, 253, 251, 242, 251, 12, 3, 10, 27, 23, 15, 33, 48, 36, 13, 21, 32, 24, 19, 31, 25, 6, 29, 41, 21, 3, 12, 23, 14, 6, 16, 28, 27, 31, 29, 22, 21, 33, 19, 19, 31, 33, 33, 25, 27, 31, 41, 43, 23, 18, 29, 22, 28, 23, 91, 7, 30, 0, 12, 14, 11, 4, 6, 8, 11, 12, 10, 7, 6, 6, 10, 8, 7, 5, 2, 241, 225, 0, 36, 52, 38, 252, 226, 244, 23, 43, 32, 3, 246, 251, 8, 26, 22, 10, 0, 252, 8, 16, 19, 18, 10, 1, 1, 8, 13, 16, 11, 3, 1, 7, 13, 10, 6, 4, 4, 6, 6, 6, 4, 2, 255, 246, 243, 0, 8, 22, 20, 3, 255, 254, 4, 17, 16, 10, 1, 3, 9, 11, 230, 193, 233, 15, 43, 39, 4, 242, 251, 18, 36, 37, 24, 8, 6, 11, 25, 24, 18, 8, 253, 14, 21, 16, 20, 0, 243, 32, 42, 4, 255, 218, 186, 240, 41, 51, 38, 248, 230, 0, 25, 39, 34, 4, 246, 247, 243, 240, 211, 202, 240, 22, 37, 34, 13, 239, 0, 40, 47, 48, 12, 238, 252, 2, 10, 20, 2, 223, 210, 220, 252, 35, 30, 26, 6, 251, 31, 49, 37, 24, 18, 10, 27, 51, 3, 1, 50, 25, 12, 16, 13, 18, 37, 54, 11, 254, 2, 3, 28, 22, 32, 18, 254, 5, 239, 7, 26, 4, 7, 0, 245, 2, 28, 12, 238, 238, 0, 5, 7, 17, 250, 255, 14, 247, 8, 9, 9, 239, 255, 254, 16, 31, 10, 254, 253, 14, 17, 20, 19, 10, 15, 252, 4, 23, 254, 249, 17, 23, 28, 26, 234, 2, 16, 22, 50, 15, 229, 248, 14, 19, 33, 21, 248, 242, 25, 252, 3, 30, 10, 4, 233, 246, 22, 0, 21, 251, 0, 30, 252, 240, 4, 17, 13, 36, 1, 254, 4, 241, 23, 18, 249, 255, 10, 15, 26, 0, 217, 8, 29, 7, 59, 247, 218, 8, 9, 33, 32, 26, 7, 201, 220, 33, 14, 49, 41, 219, 226, 25, 223, 32, 60, 230, 9, 13, 228, 35, 35, 0, 254, 14, 242, 237, 20, 233, 14, 73, 251, 224, 247, 29, 39, 47, 246, 207, 0, 52, 31, 38, 64, 190, 224, 35, 20, 31, 7, 35, 230, 197, 71, 24, 238, 44, 234, 39, 25, 225, 252, 17, 36, 3, 26, 214, 234, 53, 240, 45, 233, 216, 21, 19, 46, 221, 213, 23, 39, 8, 17, 24, 239, 244, 46, 4, 6, 17, 214, 253, 62, 30, 228, 232, 25, 28, 20, 9, 41, 208, 210, 67, 14, 39, 5, 201, 230, 92, 54, 251, 243, 198, 202, 36, 95, 28, 232, 16, 244, 206, 14, 10, 18, 87, 30, 184, 201, 0, 46, 49, 38, 231, 217, 216, 61, 32, 237, 32, 6, 200, 1, 14, 12, 28, 48, 7, 212, 231, 0, 72, 255, 219, 11, 249, 30, 67, 225, 227, 28, 213, 42, 38, 241, 23, 14, 30, 204, 224, 0, 19, 124, 250, 170, 13, 2, 252, 36, 44, 33, 18, 212, 174, 242, 67, 56, 251, 230, 245, 45, 42, 205, 231, 42, 11, 0, 28, 216, 250, 66, 12, 254, 231, 238, 224, 44, 101, 0, 181, 216, 227, 247, 81, 29, 243, 246, 201, 190, 33, 37, 77, 54, 193, 234, 41, 255, 66, 29, 0, 243, 252, 92, 230, 14, 103, 233, 202, 18, 68, 12, 11, 21, 224, 27, 243, 14, 35, 9, 0, 241, 61, 194, 30, 19, 174, 61, 54, 218, 237, 0, 21, 248, 2, 18, 28, 240, 239, 21, 20, 20, 232, 39, 12, 242, 64, 248, 53, 45, 181, 252, 18, 71, 5, 208, 56, 245, 248, 54, 244, 240, 12, 43, 237, 225, 82, 254, 240, 12, 212, 9, 29, 33, 49, 3, 233, 255, 234, 219, 68, 106, 225, 205, 39, 226, 48, 53, 249, 252, 234, 34, 61, 247, 246, 26, 36, 23, 22, 231, 234, 14, 216, 90, 6, 233, 22, 245, 3, 8, 207, 0, 37, 24, 26, 176, 184, 53, 52, 224, 18, 19, 238, 5, 216, 244, 106, 9, 229, 40, 15, 14, 0, 245, 46, 2, 4, 53, 232, 229, 45, 45, 17, 11, 0, 217, 237, 61, 27, 183, 28, 11, 254, 39, 217, 4, 40, 3, 27, 232, 231, 13, 27, 18, 250, 253, 19, 37, 233, 6, 6, 19, 26, 233, 19, 25, 235, 64, 39, 240, 37, 29, 236, 8, 11, 6, 58, 38, 254, 33, 215, 23, 38, 231, 28, 25, 254, 10, 252, 3, 240, 13, 43, 15, 234, 3, 5, 16, 13, 233, 248, 225, 22, 34, 215, 45, 25, 222, 214, 14, 27, 250, 0, 18, 25, 240, 254, 49, 26, 205, 39, 47, 211, 20, 70, 224, 34, 22, 220, 33, 253, 236, 53, 51, 5, 239, 250, 74, 35, 236, 29, 16, 214, 44, 6, 225, 55, 27, 211, 250, 25, 215, 250, 46, 238, 246, 21, 6, 240, 5, 254, 235, 252, 246, 250, 48, 42, 229, 237, 4, 232, 245, 59, 41, 12, 33, 245, 8, 6, 16, 33, 3, 241, 39, 62, 254, 34, 0, 31, 17, 228, 0, 29, 23, 28, 45, 249, 244, 26, 254, 236, 26, 252, 226, 15, 22, 35, 5, 244, 13, 15, 212, 0, 23, 224, 32, 59, 17, 253, 225, 223, 8, 17, 9, 10, 47, 20, 243, 29, 6, 249, 13, 49, 5, 253, 72, 22, 245, 254, 9, 248, 25, 16, 21, 24, 255, 19, 0, 216, 39, 8, 201, 24, 54, 20, 11, 4, 247, 17, 10, 13, 47, 236, 253, 28, 0, 251, 17, 34, 9, 22, 22, 236, 5, 241, 13, 33, 203, 255, 77, 14, 231, 31, 0, 215, 11, 12, 222, 13, 35, 9, 4, 11, 235, 247, 34, 14, 46, 30, 227, 23, 27, 247, 229, 255, 34, 27, 235, 5, 46, 251, 243, 253, 249, 29, 11, 231, 5, 45, 43, 255, 215, 10, 20, 243, 29, 1, 19, 18, 215, 5, 23, 231, 17, 21, 250, 9, 16, 4, 247, 17, 249, 251, 42, 15, 26, 25, 221, 251, 23, 33, 42, 16, 6, 10, 6, 25, 10, 16, 27, 253, 231, 23, 12, 10, 22, 0, 0, 27, 11, 243, 21, 245, 248, 32, 3, 233, 251, 20, 35, 254, 26, 11, 211, 231, 17, 7, 2, 251, 13, 41, 255, 240, 1, 252, 44, 58, 240, 247, 35, 20, 240, 5, 17, 26, 49, 14, 2, 7, 255, 15, 18, 253, 255, 22, 45, 8, 246, 12, 12, 235, 251, 9, 241, 5, 17, 254, 226, 240, 14, 0, 14, 4, 245, 3, 26, 1, 226, 6, 13, 5, 32, 35, 29, 10, 21, 17, 24, 3, 253, 8, 28, 43, 4, 1, 39, 36, 5, 243, 3, 1, 12, 40, 0, 238, 31, 2, 248, 19, 6, 15, 28, 11, 241, 236, 1, 242, 240, 6, 35, 23, 247, 249, 238, 6, 14, 0, 255, 3, 250, 245, 36, 50, 34, 23, 8, 240, 15, 11, 8, 41, 6, 223, 6, 24, 247, 255, 12, 14, 252, 6, 35, 255, 255, 36, 19, 212, 18, 54, 249, 253, 27, 13, 254, 6, 249, 243, 6, 27, 253, 10, 37, 19, 253, 11, 31, 15, 236, 13, 33, 27, 19, 26, 22, 6, 5, 9, 18, 29, 247, 228, 3, 18, 7, 25, 21, 5, 2, 2, 6, 253, 255, 23, 249, 245, 18, 14, 247, 5, 2, 238, 242, 13, 3, 11, 255, 0, 13, 255, 16, 9, 237, 1, 10, 252, 24, 15, 10, 40, 1, 241, 20, 11, 248, 15, 35, 30, 21, 28, 12, 246, 249, 5, 7, 250, 12, 18, 0, 13, 36, 19, 17, 250, 245, 7, 9, 253, 9, 12, 6, 18, 20, 245, 239, 13, 8, 231, 252, 26, 6, 2, 254, 0, 247, 251, 16, 17, 17, 35, 25, 5, 250, 251, 246, 0, 12, 15, 14, 29, 36, 21, 0, 4, 0, 243, 248, 2, 250, 247, 10, 241, 249, 0, 251, 19, 31, 4, 234, 254, 9, 14, 7, 14, 25, 4, 1, 25, 0, 14, 29, 4, 3, 20, 11, 250, 255, 10, 5, 2, 21, 39, 30, 19, 28, 26, 14, 19, 13, 9, 8, 34, 21, 5, 32, 10, 247, 0, 254, 245, 247, 247, 238, 236, 240, 4, 7, 1, 252, 252, 16, 15, 9, 8, 1, 254, 249, 4, 14, 21, 18, 12, 10, 21, 13, 7, 13, 19, 9, 15, 253, 241, 8, 19, 19, 13, 22, 40, 21, 255, 13, 14, 250, 254, 253, 0, 13, 11, 16, 3, 253, 3, 10, 5, 252, 7, 250, 224, 250, 15, 3, 254, 16, 6, 255, 9, 18, 14, 2, 10, 18, 3, 0, 11, 9, 1, 26, 31, 2, 34, 57, 20, 1, 21, 11, 227, 246, 28, 15, 14, 24, 24, 12, 13, 12, 254, 0, 0, 228, 235, 4, 10, 1, 250, 255, 253, 241, 248, 255, 254, 0, 13, 10, 6, 18, 10, 250, 254, 0, 7, 25, 23, 31, 37, 14, 2, 0, 1, 248, 8, 24, 33, 36, 12, 12, 21, 19, 10, 0, 16, 42, 16, 2, 16, 8, 252, 8, 10, 254, 7, 12, 3, 2, 2, 7, 254, 251, 251, 247, 2, 5, 255, 10, 26, 20, 14, 27, 15, 16, 26, 33, 20, 8, 12, 5, 8, 13, 8, 16, 29, 17, 1, 13, 17, 8, 4, 5, 253, 0, 1, 250, 253, 2, 5, 13, 21, 12, 12, 8, 249, 235, 229, 241, 252, 8, 24, 27, 15, 5, 7, 7, 14, 20, 24, 6, 250, 5, 7, 11, 23, 25, 25, 23, 13, 10, 21, 21, 12, 11, 8, 8, 6, 9, 9, 8, 8, 255, 3, 14, 17, 12, 6, 0, 249, 251, 251, 0, 4, 5, 4, 7, 18, 13, 7, 6, 6, 252, 6, 21, 18, 14, 13, 4, 7, 7, 2, 10, 12, 12, 19, 15, 15, 20, 23, 17, 5, 1, 11, 13, 4, 11, 21, 18, 12, 12, 11, 8, 2, 255, 249, 0, 0, 1, 9, 8, 4, 3, 2, 2, 8, 13, 9, 255, 2, 20, 19, 10, 7, 252, 4, 11, 8, 10, 22, 15, 12, 21, 13, 6, 5, 18, 18, 2, 6, 11, 14, 19, 15, 15, 5, 0, 9, 8, 13, 17, 5, 8, 4, 253, 255, 254, 4, 4, 2, 7, 6, 10, 18, 15, 0, 253, 0, 253, 248, 250, 2, 255, 247, 1, 8, 4, 1, 251, 0, 5, 11, 19, 9, 5, 0, 255, 2, 1, 8, 20, 26, 21, 20, 18, 12, 14, 15, 10, 6, 13, 9, 7, 15, 20, 18, 30, 31, 20, 12, 13, 9, 6, 10, 6, 254, 255, 1, 253, 2, 4, 0, 6, 4, 0, 0, 1, 254, 247, 252, 250, 250, 9, 11, 13, 22, 15, 15, 21, 15, 3, 9, 7, 6, 13, 14, 11, 11, 13, 11, 11, 8, 11, 13, 10, 11, 11, 15, 19, 7, 1, 2, 253, 250, 254, 9, 7, 8, 12, 9, 6, 2, 0, 253, 1, 7, 2, 6, 7, 4, 1, 7, 10, 5, 11, 13, 8, 4, 6, 11, 10, 11, 21, 21, 11, 15, 21, 14, 14, 18, 11, 12, 16, 13, 12, 18, 22, 21, 19, 14, 10, 3, 9, 11, 9, 10, 10, 9, 8, 12, 18, 14, 16, 22, 18, 11, 7, 4, 2, 1, 254, 0, 3, 9, 13, 12, 14, 11, 8, 8, 8, 5, 0, 254, 253, 254, 255, 0, 6, 11, 10, 8, 8, 8, 4, 1, 1, 251, 249, 247, 244, 252, 0, 254, 0, 254, 249, 0, 11, 4, 35, 0, 4, 1, 255, 7, 0, 255, 251, 254, 27, 255, 232, 16, 244, 241, 20, 242, 250, 25, 4, 8, 248, 250, 28, 0, 246, 0, 238, 248, 23, 242, 1, 17, 2, 3, 245, 237, 34, 250, 240, 244, 6, 10, 251, 1, 232, 16, 251, 17, 9, 5, 10, 10, 6, 232, 1, 249, 20, 0, 5, 10, 245, 9, 5, 23, 254, 15, 246, 0, 7, 251, 254, 252, 30, 251, 239, 29, 244, 1, 16, 5, 250, 2, 232, 6, 9, 220, 41, 252, 0, 13, 217, 242, 224, 228, 237, 209, 198, 246, 213, 243, 236, 0, 8, 252, 10, 253, 33, 0, 23, 16, 14, 48, 27, 255, 39, 38, 25, 8, 5, 14, 11, 34, 1, 19, 1, 25, 2, 9, 4, 17, 252, 255, 2, 247, 253, 229, 241, 223, 14, 0, 194, 243, 249, 215, 238, 11, 212, 237, 0, 10, 2, 244, 2, 20, 33, 235, 36, 245, 6, 251, 3, 15, 3, 7, 32, 215, 240, 66, 230, 14, 24, 208, 40, 27, 246, 235, 234, 15, 13, 219, 8, 230, 234, 40, 217, 7, 206, 19, 6, 235, 250, 0, 206, 12, 14, 233, 29, 35, 20, 229, 53, 27, 16, 65, 28, 54, 30, 52, 42, 26, 82, 55, 222, 28, 50, 1, 11, 236, 190, 177, 41, 64, 245, 208, 166, 203, 167, 151, 171, 169, 6, 181, 132, 246, 205, 188, 243, 225, 250, 246, 204, 27, 251, 22, 56, 36, 72, 52, 219, 64, 98, 42, 31, 72, 6, 56, 81, 40, 24, 46, 90, 6, 43, 10, 241, 14, 64, 241, 0, 0, 1, 187, 249, 29, 212, 219, 194, 2, 214, 209, 227, 229, 252, 223, 183, 234, 255, 204, 227, 0, 247, 250, 237, 16, 246, 33, 29, 9, 6, 5, 23, 17, 23, 255, 5, 33, 36, 0, 240, 23, 69, 219, 242, 49, 233, 45, 195, 9, 76, 189, 238, 19, 219, 18, 228, 227, 54, 214, 29, 235, 7, 17, 222, 23, 7, 246, 247, 11, 87, 214, 250, 19, 247, 74, 231, 6, 19, 231, 255, 242, 237, 44, 198, 33, 205, 219, 29, 11, 247, 217, 0, 18, 237, 9, 57, 198, 77, 243, 214, 33, 242, 6, 8, 13, 54, 221, 232, 14, 223, 214, 234, 21, 236, 36, 23, 175, 36, 42, 238, 249, 21, 247, 243, 250, 255, 211, 14, 87, 224, 218, 37, 0, 236, 6, 253, 0, 18, 4, 229, 248, 15, 243, 240, 30, 11, 238, 9, 248, 235, 12, 24, 250, 4, 30, 17, 222, 33, 25, 220, 32, 41, 248, 239, 28, 241, 5, 33, 16, 241, 12, 38, 242, 221, 238, 30, 234, 2, 238, 224, 17, 40, 204, 238, 6, 224, 246, 240, 35, 232, 244, 254, 224, 19, 30, 239, 4, 26, 15, 240, 219, 0, 252, 14, 19, 32, 242, 25, 246, 215, 36, 59, 248, 5, 33, 203, 8, 27, 2, 231, 15, 24, 16, 225, 233, 230, 233, 42, 20, 233, 222, 17, 245, 231, 36, 32, 202, 243, 9, 11, 230, 247, 32, 229, 15, 22, 230, 250, 20, 253, 238, 24, 31, 235, 0, 49, 248, 0, 16, 235, 20, 19, 52, 250, 210, 16, 15, 199, 1, 12, 244, 240, 7, 231, 218, 60, 248, 223, 21, 5, 237, 234, 253, 6, 248, 18, 24, 252, 234, 13, 27, 232, 21, 9, 221, 13, 16, 233, 0, 44, 248, 248, 6, 43, 231, 218, 61, 26, 171, 237, 16, 254, 43, 0, 226, 245, 70, 223, 225, 37, 25, 233, 249, 23, 209, 244, 46, 14, 219, 0, 2, 251, 243, 29, 248, 235, 31, 251, 238, 4, 31, 223, 7, 28, 244, 227, 14, 10, 13, 10, 241, 255, 31, 29, 233, 238, 2, 18, 5, 17, 234, 8, 21, 241, 244, 234, 32, 249, 212, 13, 245, 247, 41, 220, 232, 255, 32, 5, 226, 8, 239, 0, 14, 7, 20, 253, 14, 246, 246, 36, 244, 229, 41, 247, 4, 10, 248, 230, 14, 17, 5, 216, 8, 38, 234, 249, 243, 241, 3, 23, 251, 253, 20, 246, 220, 19, 15, 21, 241, 242, 245, 210, 248, 24, 28, 34, 237, 255, 243, 14, 8, 23, 41, 3, 244, 238, 4, 29, 250, 18, 38, 14, 255, 224, 233, 5, 8, 252, 0, 243, 230, 235, 237, 251, 10, 250, 251, 3, 9, 0, 249, 248, 242, 21, 21, 17, 246, 222, 10, 248, 1, 28, 16, 11, 223, 236, 9, 238, 0, 10, 43, 48, 16, 222, 235, 11, 4, 0, 12, 255, 216, 223, 251, 17, 35, 23, 223, 230, 4, 28, 245, 8, 3, 233, 7, 0, 244, 248, 13, 43, 8, 241, 245, 216, 14, 41, 245, 252, 16, 0, 238, 11, 10, 38, 22, 20, 0, 253, 237, 226, 1, 12, 14, 0, 245, 250, 243, 240, 246, 254, 245, 233, 252, 249, 221, 252, 4, 18, 19, 13, 244, 15, 250, 221, 0, 25, 25, 3, 8, 1, 15, 7, 8, 6, 8, 13, 7, 2, 231, 232, 18, 19, 255, 17, 26, 19, 235, 245, 0, 9, 243, 242, 16, 240, 249, 254, 232, 9, 27, 234, 12, 253, 238, 212, 223, 6, 2, 251, 14, 3, 240, 236, 244, 21, 31, 20, 5, 255, 14, 16, 253, 240, 9, 19, 15, 4, 252, 240, 11, 9, 253, 11, 255, 234, 236, 239, 8, 14, 246, 253, 241, 255, 25, 2, 246, 15, 9, 0, 255, 17, 0, 234, 19, 25, 5, 254, 244, 252, 5, 11, 243, 250, 13, 2, 7, 25, 21, 255, 236, 23, 1, 231, 9, 4, 242, 245, 1, 1, 8, 248, 229, 243, 32, 252, 204, 253, 3, 242, 0, 5, 19, 4, 241, 248, 249, 255, 6, 249, 0, 3, 3, 7, 21, 11, 246, 31, 22, 1, 0, 236, 235, 5, 248, 4, 13, 6, 243, 237, 10, 8, 251, 10, 17, 0, 250, 252, 249, 2, 4, 1, 1, 13, 10, 227, 222, 253, 1, 19, 246, 248, 3, 9, 5, 255, 15, 11, 254, 4, 21, 26, 252, 244, 12, 16, 26, 12, 249, 238, 238, 251, 254, 2, 7, 238, 227, 253, 0, 249, 232, 240, 9, 5, 245, 237, 234, 245, 0, 47, 4, 33, 0, 5, 4, 4, 5, 3, 3, 0, 253, 226, 205, 14, 38, 39, 6, 234, 3, 13, 23, 5, 0, 9, 12, 14, 1, 4, 6, 9, 8, 6, 7, 5, 9, 12, 11, 7, 8, 5, 6, 5, 6, 9, 6, 7, 4, 5, 5, 6, 5, 2, 5, 2, 5, 3, 2, 0, 2, 9, 236, 222, 5, 30, 35, 245, 224, 3, 42, 51, 19, 225, 200, 15, 33, 11, 4, 18, 36, 34, 5, 233, 13, 23, 35, 25, 0, 14, 9, 14, 231, 216, 228, 246, 13, 6, 1, 7, 20, 11, 8, 21, 250, 247, 4, 253, 13, 7, 254, 12, 5, 251, 255, 14, 24, 26, 5, 237, 16, 3, 10, 4, 249, 236, 8, 23, 245, 23, 246, 247, 17, 19, 28, 1, 247, 2, 24, 25, 1, 255, 247, 252, 255, 17, 242, 13, 0, 15, 7, 0, 0, 0, 40, 8, 23, 5, 246, 37, 0, 31, 9, 14, 21, 11, 15, 0, 15, 246, 211, 250, 22, 24, 6, 11, 4, 12, 0, 0, 15, 22, 247, 19, 5, 247, 24, 255, 3, 6, 240, 7, 7, 250, 8, 4, 11, 11, 247, 5, 1, 17, 5, 255, 253, 252, 14, 9, 0, 4, 3, 12, 3, 241, 28, 0, 248, 13, 245, 16, 255, 4, 11, 5, 16, 236, 22, 28, 238, 18, 235, 24, 40, 194, 49, 5, 251, 53, 236, 8, 3, 2, 23, 241, 252, 24, 245, 33, 6, 236, 37, 233, 14, 6, 238, 10, 24, 244, 240, 13, 15, 247, 3, 45, 209, 0, 31, 11, 238, 239, 45, 254, 0, 239, 7, 23, 241, 6, 4, 21, 250, 7, 234, 253, 45, 248, 238, 21, 1, 13, 13, 243, 248, 7, 14, 0, 16, 254, 17, 255, 240, 20, 8, 1, 255, 20, 240, 22, 39, 196, 42, 1, 236, 56, 237, 245, 1, 218, 66, 220, 253, 23, 225, 26, 230, 19, 235, 15, 10, 227, 25, 5, 8, 33, 10, 249, 253, 34, 1, 12, 26, 25, 249, 19, 227, 50, 1, 15, 20, 220, 39, 19, 6, 29, 222, 239, 54, 7, 246, 11, 254, 6, 13, 25, 228, 24, 26, 196, 52, 34, 189, 6, 30, 32, 4, 245, 235, 59, 242, 11, 15, 224, 56, 2, 210, 60, 226, 248, 51, 217, 56, 1, 170, 101, 231, 14, 19, 237, 47, 5, 237, 15, 11, 17, 2, 209, 45, 10, 2, 3, 242, 38, 1, 242, 17, 7, 2, 238, 16, 34, 2, 9, 16, 203, 87, 209, 14, 44, 185, 48, 58, 176, 29, 42, 186, 96, 197, 48, 11, 194, 91, 208, 24, 71, 174, 222, 127, 225, 253, 0, 235, 28, 35, 3, 228, 0, 230, 16, 13, 17, 30, 201, 247, 69, 249, 246, 8, 216, 33, 44, 228, 43, 234, 241, 38, 250, 43, 0, 234, 10, 23, 14, 28, 190, 5, 57, 235, 250, 205, 243, 68, 17, 193, 15, 63, 50, 182, 225, 109, 56, 226, 202, 55, 34, 231, 250, 13, 247, 249, 255, 11, 44, 2, 221, 42, 49, 238, 233, 16, 17, 3, 44, 232, 43, 236, 188, 61, 19, 0, 205, 24, 40, 252, 231, 21, 21, 237, 11, 22, 0, 16, 237, 222, 25, 11, 19, 255, 47, 13, 229, 4, 35, 244, 247, 27, 240, 247, 123, 220, 143, 111, 240, 43, 51, 144, 34, 27, 231, 33, 211, 8, 49, 201, 239, 28, 0, 222, 52, 239, 8, 0, 1, 69, 208, 45, 252, 189, 11, 5, 239, 81, 206, 227, 37, 252, 19, 207, 17, 90, 239, 245, 244, 254, 60, 220, 1, 49, 14, 24, 229, 254, 23, 57, 201, 8, 40, 217, 30, 242, 197, 20, 31, 240, 10, 9, 237, 31, 20, 230, 8, 38, 224, 8, 44, 249, 236, 23, 243, 255, 22, 253, 12, 223, 34, 8, 243, 14, 40, 227, 2, 240, 15, 56, 223, 253, 236, 39, 47, 12, 201, 66, 1, 4, 11, 13, 248, 1, 20, 8, 35, 21, 234, 246, 74, 1, 202, 10, 27, 6, 15, 16, 14, 18, 241, 47, 15, 244, 250, 4, 244, 254, 248, 19, 30, 210, 224, 24, 20, 204, 224, 34, 40, 1, 1, 13, 20, 11, 220, 241, 32, 12, 230, 15, 28, 26, 255, 213, 30, 55, 248, 241, 36, 16, 9, 14, 37, 252, 9, 29, 250, 242, 17, 11, 236, 45, 42, 254, 22, 253, 244, 239, 28, 53, 191, 230, 52, 249, 255, 8, 224, 21, 13, 23, 247, 216, 16, 2, 18, 10, 241, 29, 5, 223, 34, 31, 35, 232, 228, 21, 31, 25, 236, 255, 25, 12, 243, 27, 16, 14, 9, 216, 35, 9, 213, 18, 234, 12, 61, 232, 0, 216, 210, 23, 240, 245, 3, 223, 20, 35, 8, 4, 227, 5, 14, 9, 38, 14, 225, 66, 30, 12, 19, 249, 12, 4, 4, 17, 18, 33, 0, 18, 75, 6, 239, 244, 1, 0, 0, 32, 9, 4, 239, 250, 0, 5, 248, 242, 7, 1, 0, 16, 246, 226, 12, 22, 0, 246, 21, 15, 251, 26, 26, 253, 253, 245, 0, 23, 4, 244, 249, 53, 15, 246, 13, 251, 244, 14, 12, 241, 249, 0, 21, 42, 26, 226, 4, 17, 8, 250, 0, 10, 4, 14, 0, 5, 0, 0, 16, 7, 16, 253, 215, 21, 12, 244, 7, 17, 24, 27, 243, 253, 38, 244, 223, 12, 1, 255, 18, 27, 8, 0, 10, 3, 0, 9, 2, 241, 1, 16, 6, 3, 7, 252, 3, 21, 248, 236, 241, 254, 245, 246, 9, 30, 22, 1, 21, 14, 254, 6, 8, 252, 12, 13, 5, 5, 13, 14, 19, 255, 9, 240, 237, 248, 253, 13, 22, 11, 34, 13, 7, 7, 2, 8, 246, 17, 25, 0, 23, 14, 240, 39, 11, 241, 22, 10, 236, 248, 8, 20, 5, 0, 12, 247, 11, 4, 0, 11, 21, 253, 254, 4, 13, 15, 5, 7, 13, 17, 5, 2, 8, 13, 3, 27, 255, 249, 20, 22, 11, 17, 13, 0, 240, 244, 14, 252, 245, 249, 1, 4, 3, 251, 254, 240, 246, 2, 5, 253, 248, 2, 7, 22, 16, 9, 3, 0, 250, 3, 10, 3, 1, 0, 247, 6, 12, 254, 252, 1, 2, 4, 0, 253, 9, 11, 13, 10, 6, 5, 255, 249, 242, 247, 251, 244, 0, 4, 2, 255, 0, 4, 250, 253, 7, 20, 19, 15, 7, 0, 149, 3, 54, 0, 2, 2, 2, 1, 1, 0, 1, 0, 5, 4, 0, 254, 252, 255, 0, 3, 4, 2, 255, 255, 0, 1, 2, 2, 2, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 255, 255, 0, 0, 0, 255, 255, 255, 0, 255, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 254, 254, 254, 253, 254, 252, 253, 254, 253, 253, 253, 255, 255, 254, 254, 253, 253, 254, 255, 255, 253, 255, 255, 254, 255, 255, 254, 255, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 1, 2, 2, 2, 1, 3, 2, 2, 1, 3, 255, 0, 3, 5, 5, 3, 1, 0, 255, 0, 2, 3, 2, 0, 255, 254, 254, 0, 0, 0, 0, 0, 1, 0, 1, 0, 255, 255, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 255, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 254, 254, 253, 254, 253, 253, 254, 253, 253, 253, 254, 254, 254, 255, 254, 255, 255, 254, 254, 254, 254, 254, 254, 253, 253, 253, 253, 253, 254, 254, 253, 254, 254, 254, 253, 253, 255, 254, 254, 255, 0, 0, 253, 254, 254, 255, 255, 255, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 2, 0, 2, 1, 0, 1, 1, 1, 2, 3, 2, 2, 2, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 2, 2, 1, 1, 1, 1, 2, 1, 2, 1, 2, 2, 2, 2, 2, 3, 4, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 4, 3, 4, 4, 3, 4, 4, 5, 4, 4, 4, 4, 4, 8, 9, 3, 2, 0, 1, 4, 6, 8, 6, 2, 2, 1, 4, 5, 6, 5, 6, 4, 5, 5, 5, 4, 5, 4, 5, 5, 6, 4, 6, 7, 6, 9, 11, 13, 16, 18, 19, 16, 11, 7, 4, 4, 16, 13, 5, 4, 6, 9, 8, 5, 9, 6, 4, 6, 3, 2, 4, 1, 3, 1, 0, 3, 4, 0, 7, 4, 6, 5, 6, 7, 5, 7, 10, 9, 10, 13, 15, 18, 21, 25, 37, 44, 54, 62, 97, 127, 100, 111, 114, 59, 79, 86, 68, 72, 61, 54, 67, 54, 33, 50, 33, 25, 1, 244, 237, 220, 227, 242, 231, 235, 231, 227, 247, 234, 235, 236, 238, 246, 230, 239, 253, 249, 9, 18, 23, 23, 23, 18, 21, 43, 32, 27, 35, 19, 18, 21, 7, 5, 20, 7, 7, 5, 245, 251, 249, 249, 250, 247, 234, 229, 228, 219, 228, 229, 223, 235, 237, 233, 233, 238, 237, 249, 246, 242, 247, 235, 237, 246, 252, 253, 0, 6, 6, 12, 12, 8, 20, 21, 19, 23, 19, 6, 16, 14, 13, 18, 12, 9, 14, 12, 7, 14, 11, 11, 16, 12, 8, 12, 8, 12, 19, 15, 16, 18, 17, 18, 26, 25, 28, 31, 30, 30, 31, 25, 26, 27, 25, 25, 22, 11, 13, 18, 19, 16, 15, 7, 4, 253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 9, 28, 0, 246, 0, 11, 13, 16, 12, 252, 240, 252, 15, 15, 16, 10, 244, 239, 3, 22, 20, 15, 12, 3, 249, 3, 27, 35, 29, 13, 0, 3, 22, 23, 31, 32, 8, 9, 5, 3, 14, 23, 19, 16, 0, 247, 6, 27, 17, 250, 248, 253, 0, 15, 22, 255, 250, 0, 249, 7, 8, 7, 14, 7, 255, 253, 12, 12, 254, 16, 28, 8, 3, 8, 14, 13, 16, 8, 6, 13, 12, 9, 8, 12, 1, 242, 1, 25, 28, 15, 239, 230, 237, 14, 31, 22, 11, 234, 215, 245, 22, 37, 25, 13, 242, 218, 234, 15, 31, 31, 28, 11, 243, 237, 248, 17, 38, 26, 246, 233, 18, 40, 25, 3, 240, 241, 7, 31, 33, 28, 14, 249, 245, 0, 14, 27, 27, 12, 21, 10, 247, 251, 19, 25, 20, 19, 17, 2, 255, 20, 23, 1, 4, 10, 17, 11, 0, 8, 18, 255, 6, 250, 4, 30, 11, 1, 254, 8, 11, 251, 251, 22, 29, 15, 6, 243, 1, 34, 31, 9, 0, 6, 21, 7, 21, 23, 19, 25, 15, 247, 44, 47, 242, 235, 19, 32, 22, 29, 16, 246, 252, 4, 9, 25, 25, 11, 234, 232, 0, 20, 31, 15, 253, 230, 226, 246, 29, 27, 242, 246, 252, 1, 254, 246, 255, 2, 5, 3, 251, 248, 11, 0, 250, 20, 5, 244, 242, 14, 14, 12, 23, 247, 221, 255, 23, 23, 34, 16, 208, 211, 24, 52, 18, 232, 240, 13, 2, 0, 13, 16, 2, 232, 239, 9, 18, 39, 23, 229, 216, 245, 30, 43, 34, 16, 244, 234, 248, 26, 43, 34, 22, 6, 3, 5, 13, 27, 21, 31, 25, 15, 9, 10, 17, 14, 8, 30, 30, 14, 251, 236, 18, 48, 34, 246, 232, 3, 13, 17, 16, 11, 5, 242, 247, 249, 6, 21, 20, 20, 245, 219, 242, 18, 22, 20, 17, 254, 237, 243, 20, 38, 20, 8, 4, 240, 249, 27, 37, 28, 7, 254, 238, 247, 25, 45, 34, 1, 243, 244, 2, 32, 42, 17, 243, 245, 12, 20, 22, 23, 254, 254, 14, 18, 18, 23, 26, 20, 250, 248, 16, 27, 29, 24, 18, 3, 244, 1, 36, 35, 7, 254, 7, 14, 14, 13, 17, 250, 245, 10, 15, 18, 16, 240, 233, 11, 17, 4, 253, 11, 20, 251, 238, 251, 8, 12, 9, 240, 246, 14, 19, 5, 244, 252, 253, 247, 251, 9, 15, 5, 249, 243, 252, 8, 11, 251, 252, 248, 240, 1, 14, 25, 13, 221, 213, 9, 45, 25, 251, 250, 7, 251, 255, 6, 254, 13, 33, 20, 241, 248, 7, 32, 28, 248, 251, 18, 7, 17, 41, 21, 219, 238, 16, 34, 42, 20, 254, 3, 0, 244, 26, 50, 27, 245, 252, 16, 9, 5, 28, 44, 40, 255, 232, 255, 43, 55, 23, 254, 11, 30, 17, 22, 27, 13, 252, 0, 53, 52, 14, 0, 233, 4, 25, 15, 15, 29, 13, 247, 2, 246, 227, 11, 41, 14, 252, 252, 248, 241, 226, 252, 42, 11, 242, 241, 245, 11, 5, 233, 231, 13, 43, 27, 236, 227, 251, 3, 13, 23, 9, 14, 26, 2, 234, 2, 29, 10, 14, 2, 252, 2, 31, 25, 235, 214, 252, 20, 49, 24, 227, 241, 4, 253, 242, 15, 42, 5, 243, 255, 239, 239, 3, 31, 58, 15, 248, 249, 252, 26, 60, 244, 230, 49, 25, 252, 32, 59, 33, 252, 249, 235, 250, 52, 54, 22, 17, 251, 216, 242, 36, 35, 218, 225, 61, 27, 215, 2, 20, 195, 215, 49, 34, 1, 13, 254, 5, 10, 242, 228, 235, 53, 89, 1, 239, 28, 7, 241, 42, 63, 240, 249, 32, 9, 12, 18, 41, 34, 249, 0, 17, 244, 3, 40, 24, 241, 3, 28, 219, 232, 33, 19, 242, 253, 21, 8, 12, 1, 239, 248, 9, 8, 17, 35, 3, 11, 40, 0, 255, 41, 26, 250, 36, 27, 7, 26, 59, 7, 206, 20, 52, 252, 10, 38, 252, 245, 238, 7, 35, 33, 12, 244, 202, 219, 33, 35, 221, 226, 39, 26, 239, 232, 0, 9, 29, 26, 223, 228, 18, 47, 16, 3, 35, 253, 0, 35, 35, 6, 237, 28, 38, 3, 15, 34, 8, 12, 42, 8, 167, 235, 92, 89, 245, 191, 238, 0, 6, 37, 37, 227, 239, 7, 250, 249, 25, 28, 251, 224, 7, 19, 252, 21, 33, 2, 249, 19, 10, 16, 28, 11, 251, 245, 20, 32, 18, 38, 5, 221, 238, 69, 47, 232, 246, 1, 243, 13, 37, 26, 3, 255, 220, 249, 39, 251, 244, 23, 15, 21, 14, 250, 246, 12, 49, 252, 232, 22, 32, 16, 28, 10, 218, 11, 32, 20, 36, 20, 8, 240, 232, 14, 48, 39, 0, 2, 49, 34, 253, 247, 10, 26, 40, 38, 254, 251, 14, 32, 52, 9, 201, 249, 75, 29, 4, 33, 0, 218, 6, 5, 0, 17, 41, 20, 235, 248, 38, 8, 195, 217, 15, 56, 28, 12, 247, 238, 237, 240, 19, 21, 18, 24, 19, 6, 248, 203, 235, 55, 51, 14, 17, 25, 8, 5, 216, 224, 55, 83, 14, 227, 10, 59, 28, 209, 208, 13, 43, 22, 10, 254, 4, 13, 235, 202, 252, 24, 8, 38, 11, 232, 230, 9, 254, 224, 235, 54, 44, 254, 248, 246, 255, 251, 214, 245, 67, 69, 15, 238, 231, 241, 4, 18, 46, 52, 22, 3, 7, 17, 240, 239, 250, 30, 75, 46, 254, 3, 15, 246, 213, 245, 72, 68, 4, 0, 253, 249, 4, 244, 5, 67, 75, 21, 211, 229, 10, 241, 252, 63, 80, 51, 5, 197, 199, 1, 26, 240, 30, 63, 16, 246, 227, 0, 250, 222, 223, 252, 69, 85, 3, 208, 250, 7, 0, 55, 27, 235, 17, 14, 254, 0, 56, 64, 247, 248, 35, 22, 5, 5, 8, 45, 34, 248, 12, 35, 35, 1, 253, 230, 245, 38, 55, 43, 236, 201, 255, 9, 252, 37, 39, 232, 221, 12, 4, 224, 3, 49, 26, 243, 255, 5, 229, 254, 29, 26, 12, 248, 0, 12, 12, 58, 59, 245, 205, 225, 14, 46, 18, 0, 25, 34, 254, 230, 236, 3, 15, 234, 220, 43, 76, 16, 221, 227, 250, 227, 210, 10, 62, 30, 236, 226, 241, 11, 0, 241, 3, 240, 7, 28, 32, 2, 247, 247, 246, 251, 42, 96, 34, 250, 245, 239, 225, 241, 60, 123, 59, 237, 230, 252, 240, 12, 32, 32, 33, 10, 1, 12, 10, 245, 243, 14, 25, 9, 248, 13, 29, 13, 237, 228, 22, 51, 40, 14, 248, 0, 236, 252, 26, 37, 40, 11, 2, 8, 5, 248, 212, 1, 66, 25, 243, 27, 31, 246, 215, 234, 13, 21, 42, 42, 255, 220, 229, 21, 44, 251, 251, 16, 17, 16, 0, 229, 242, 20, 48, 23, 6, 249, 243, 16, 2, 231, 17, 53, 28, 11, 20, 15, 20, 249, 228, 254, 25, 39, 37, 2, 8, 14, 1, 230, 230, 11, 46, 37, 19, 248, 228, 248, 16, 15, 14, 14, 18, 20, 225, 233, 23, 253, 246, 31, 26, 14, 251, 253, 20, 37, 7, 212, 216, 42, 53, 16, 28, 9, 228, 243, 35, 62, 13, 211, 234, 1, 32, 46, 12, 248, 21, 30, 243, 208, 245, 36, 29, 4, 0, 252, 250, 255, 8, 18, 16, 240, 10, 31, 246, 244, 13, 28, 8, 10, 22, 18, 5, 241, 13, 16, 5, 36, 65, 27, 229, 234, 20, 4, 6, 36, 50, 42, 242, 218, 1, 20, 0, 2, 237, 14, 49, 25, 0, 0, 227, 192, 238, 63, 54, 26, 26, 254, 218, 240, 0, 245, 40, 52, 24, 29, 31, 250, 223, 230, 34, 54, 2, 12, 46, 14, 230, 4, 42, 34, 0, 255, 239, 245, 25, 32, 21, 244, 237, 11, 2, 242, 12, 33, 2, 242, 248, 1, 29, 55, 46, 227, 210, 2, 20, 252, 10, 39, 45, 255, 218, 0, 27, 2, 2, 25, 0, 250, 8, 24, 39, 29, 251, 252, 4, 4, 11, 5, 250, 252, 26, 29, 1, 242, 0, 44, 15, 218, 238, 4, 0, 55, 51, 228, 233, 23, 26, 1, 11, 31, 12, 13, 9, 236, 240, 27, 64, 40, 241, 239, 24, 0, 236, 249, 33, 50, 6, 225, 2, 6, 2, 5, 245, 253, 25, 33, 249, 234, 10, 6, 234, 246, 45, 61, 22, 245, 228, 222, 250, 22, 53, 38, 6, 5, 17, 15, 11, 253, 239, 254, 41, 31, 13, 26, 30, 22, 250, 254, 7, 251, 4, 28, 39, 30, 16, 5, 245, 253, 6, 247, 237, 33, 69, 7, 2, 16, 255, 236, 237, 245, 22, 71, 64, 0, 245, 242, 231, 252, 17, 36, 19, 33, 35, 0, 224, 249, 34, 3, 225, 4, 43, 41, 28, 12, 211, 205, 22, 39, 6, 15, 22, 246, 251, 17, 11, 253, 251, 2, 11, 248, 251, 48, 67, 1, 207, 232, 5, 37, 37, 250, 240, 22, 51, 0, 223, 13, 39, 9, 239, 10, 42, 6, 232, 11, 27, 233, 249, 40, 19, 17, 13, 217, 209, 16, 44, 19, 5, 32, 17, 214, 241, 38, 13, 248, 36, 58, 6, 219, 244, 31, 28, 18, 7, 0, 23, 29, 4, 238, 240, 254, 29, 39, 254, 230, 22, 51, 3, 210, 240, 25, 30, 8, 246, 0, 4, 0, 12, 27, 19, 241, 235, 8, 27, 27, 14, 11, 11, 6, 250, 6, 25, 33, 31, 25, 253, 226, 245, 25, 34, 17, 22, 27, 43, 29, 205, 203, 19, 53, 28, 7, 22, 36, 28, 0, 225, 227, 4, 44, 58, 55, 22, 231, 219, 230, 25, 48, 16, 24, 48, 0, 209, 238, 1, 22, 43, 12, 3, 20, 15, 253, 240, 234, 6, 34, 31, 27, 11, 248, 247, 6, 12, 253, 0, 26, 32, 16, 0, 248, 5, 30, 17, 254, 20, 26, 252, 4, 20, 22, 16, 1, 243, 253, 18, 5, 6, 29, 23, 248, 237, 5, 245, 234, 20, 40, 4, 236, 2, 17, 6, 12, 247, 222, 2, 22, 23, 36, 37, 13, 230, 238, 238, 241, 14, 46, 58, 27, 254, 253, 17, 13, 229, 223, 24, 68, 56, 5, 254, 15, 19, 7, 223, 240, 50, 61, 16, 245, 252, 12, 253, 248, 4, 16, 10, 15, 254, 248, 18, 6, 250, 243, 8, 29, 13, 254, 6, 11, 251, 3, 18, 32, 12, 241, 7, 30, 25, 15, 10, 7, 2, 11, 15, 16, 18, 14, 17, 9, 3, 252, 6, 31, 12, 249, 7, 18, 7, 10, 5, 247, 250, 18, 24, 5, 0, 15, 3, 245, 253, 16, 34, 30, 8, 234, 231, 10, 32, 18, 23, 35, 13, 241, 254, 16, 19, 19, 13, 16, 34, 30, 18, 2, 0, 3, 0, 12, 24, 23, 16, 11, 7, 251, 5, 25, 8, 252, 10, 36, 25, 240, 242, 6, 6, 7, 14, 22, 42, 24, 239, 231, 244, 255, 9, 9, 28, 53, 30, 240, 227, 249, 7, 5, 0, 12, 32, 32, 255, 250, 6, 254, 252, 14, 21, 16, 11, 13, 8, 248, 250, 9, 18, 26, 24, 1, 243, 2, 16, 10, 241, 252, 27, 29, 12, 16, 0, 247, 0, 0, 7, 22, 20, 7, 18, 9, 254, 14, 26, 15, 253, 249, 4, 28, 25, 2, 233, 0, 47, 37, 2, 1, 248, 233, 8, 30, 18, 11, 22, 12, 254, 4, 24, 26, 4, 254, 12, 12, 251, 12, 27, 23, 20, 11, 255, 254, 13, 13, 248, 254, 3, 6, 11, 20, 19, 1, 0, 252, 251, 7, 6, 250, 18, 20, 0, 19, 30, 10, 245, 240, 244, 0, 29, 53, 37, 3, 249, 241, 238, 8, 33, 33, 17, 12, 7, 246, 0, 21, 6, 250, 8, 32, 34, 0, 241, 0, 8, 1, 252, 1, 16, 23, 8, 248, 249, 4, 10, 253, 0, 14, 9, 2, 20, 29, 15, 1, 250, 252, 9, 33, 35, 21, 21, 16, 250, 251, 5, 11, 14, 11, 9, 7, 14, 24, 0, 239, 248, 254, 2, 15, 18, 8, 12, 13, 248, 233, 236, 5, 25, 14, 12, 18, 2, 249, 251, 3, 9, 17, 16, 22, 29, 10, 0, 6, 6, 10, 6, 6, 22, 27, 23, 22, 8, 250, 251, 9, 4, 1, 20, 29, 23, 15, 9, 8, 7, 7, 255, 252, 5, 15, 30, 35, 22, 253, 241, 254, 251, 248, 19, 28, 15, 3, 6, 10, 2, 0, 4, 10, 13, 19, 17, 254, 0, 21, 21, 0, 0, 24, 30, 14, 12, 9, 246, 251, 16, 12, 7, 22, 29, 8, 248, 8, 21, 9, 10, 10, 0, 0, 16, 24, 19, 6, 3, 1, 5, 15, 23, 10, 249, 245, 5, 15, 18, 15, 13, 5, 250, 234, 253, 26, 36, 31, 255, 237, 6, 23, 4, 8, 21, 18, 10, 9, 13, 16, 13, 6, 10, 13, 18, 18, 16, 8, 2, 250, 246, 8, 33, 28, 14, 15, 12, 254, 249, 2, 14, 5, 0, 3, 15, 30, 6, 246, 11, 6, 234, 240, 8, 26, 22, 2, 240, 247, 8, 15, 12, 0, 0, 0, 0, 21, 41, 20, 236, 243, 22, 23, 10, 10, 18, 15, 0, 252, 1, 6, 14, 23, 24, 17, 3, 0, 2, 250, 246, 2, 26, 38, 34, 6, 240, 244, 252, 7, 13, 2, 19, 37, 12, 247, 250, 4, 5, 5, 15, 15, 11, 16, 12, 255, 3, 9, 3, 11, 29, 30, 15, 5, 15, 10, 250, 252, 4, 18, 24, 21, 10, 15, 18, 2, 247, 248, 253, 10, 20, 23, 15, 5, 5, 0, 245, 0, 9, 8, 14, 17, 15, 9, 5, 252, 246, 0, 13, 18, 13, 12, 12, 3, 253, 255, 6, 6, 6, 9, 1, 3, 15, 12, 4, 2, 254, 0, 11, 16, 0, 249, 7, 14, 6, 1, 253, 254, 7, 20, 8, 255, 9, 11, 255, 2, 18, 12, 3, 8, 17, 12, 4, 15, 19, 8, 3, 8, 17, 21, 16, 14, 4, 2, 12, 11, 1, 8, 18, 20, 14, 4, 253, 249, 0, 0, 0, 58, 6, 43, 0, 255, 15, 12, 13, 10, 254, 255, 18, 15, 8, 0, 0, 6, 19, 19, 0, 4, 10, 0, 22, 11, 0, 2, 10, 17, 9, 15, 251, 249, 21, 15, 16, 17, 253, 235, 14, 31, 13, 14, 250, 254, 6, 13, 20, 26, 249, 241, 2, 35, 47, 254, 213, 0, 34, 21, 2, 13, 7, 251, 252, 10, 13, 9, 11, 13, 13, 248, 228, 254, 35, 40, 250, 249, 0, 238, 17, 30, 27, 6, 254, 1, 3, 14, 0, 10, 29, 18, 3, 3, 254, 243, 6, 46, 32, 246, 237, 17, 21, 253, 18, 2, 250, 12, 26, 9, 254, 2, 3, 10, 10, 7, 9, 0, 249, 236, 23, 34, 255, 0, 246, 12, 22, 220, 1, 31, 12, 245, 247, 8, 10, 3, 247, 245, 40, 24, 214, 242, 29, 5, 0, 23, 246, 0, 10, 246, 21, 21, 227, 239, 41, 36, 239, 229, 253, 24, 33, 253, 242, 3, 2, 9, 14, 253, 253, 17, 21, 235, 240, 40, 23, 230, 10, 18, 3, 246, 1, 23, 9, 252, 17, 13, 236, 13, 29, 221, 250, 64, 246, 236, 22, 251, 8, 5, 254, 20, 15, 14, 243, 237, 7, 17, 12, 27, 44, 213, 196, 12, 46, 31, 11, 228, 209, 255, 42, 24, 232, 243, 8, 0, 3, 1, 253, 3, 4, 12, 6, 252, 219, 250, 49, 22, 246, 8, 7, 254, 235, 48, 71, 222, 197, 16, 58, 12, 233, 26, 86, 244, 132, 36, 89, 6, 250, 13, 21, 238, 225, 19, 27, 43, 20, 236, 216, 244, 39, 33, 234, 249, 236, 234, 255, 48, 41, 171, 171, 46, 60, 244, 0, 22, 240, 209, 7, 47, 24, 5, 249, 9, 247, 10, 23, 254, 29, 22, 12, 31, 15, 22, 250, 12, 55, 2, 0, 40, 3, 8, 28, 247, 23, 44, 17, 245, 215, 7, 54, 19, 237, 7, 254, 3, 16, 247, 225, 249, 74, 46, 193, 178, 17, 90, 4, 206, 5, 19, 36, 247, 207, 246, 53, 15, 251, 28, 0, 225, 10, 55, 16, 216, 6, 60, 3, 1, 26, 9, 9, 25, 17, 227, 12, 19, 251, 36, 17, 244, 244, 31, 34, 228, 239, 4, 49, 12, 245, 38, 6, 212, 214, 22, 47, 33, 4, 226, 249, 12, 249, 248, 39, 251, 217, 0, 54, 17, 236, 252, 255, 253, 240, 10, 45, 10, 19, 2, 199, 251, 33, 48, 3, 232, 26, 2, 240, 41, 7, 210, 11, 42, 25, 5, 209, 214, 56, 52, 254, 0, 231, 248, 39, 7, 230, 19, 29, 245, 246, 10, 44, 239, 197, 20, 52, 18, 228, 229, 27, 6, 247, 2, 18, 10, 35, 20, 225, 219, 13, 56, 38, 219, 252, 249, 240, 40, 35, 40, 227, 223, 11, 3, 43, 7, 226, 25, 32, 252, 235, 18, 14, 7, 40, 6, 202, 239, 45, 36, 9, 19, 224, 192, 23, 118, 5, 165, 233, 34, 66, 18, 251, 238, 245, 21, 10, 233, 32, 48, 3, 215, 247, 56, 11, 230, 24, 35, 213, 227, 51, 30, 214, 2, 47, 0, 242, 25, 3, 220, 232, 39, 25, 8, 45, 227, 185, 36, 69, 251, 208, 61, 64, 154, 2, 83, 248, 21, 8, 251, 0, 232, 0, 46, 38, 42, 1, 187, 254, 33, 237, 36, 50, 0, 225, 251, 36, 216, 247, 55, 44, 196, 240, 72, 199, 7, 32, 222, 30, 42, 225, 249, 55, 250, 213, 14, 27, 46, 252, 239, 46, 251, 196, 3, 47, 48, 249, 180, 36, 67, 215, 8, 52, 232, 234, 21, 246, 34, 46, 0, 226, 235, 27, 65, 252, 210, 230, 25, 81, 240, 214, 39, 37, 244, 1, 202, 242, 70, 15, 247, 250, 238, 72, 27, 156, 0, 71, 255, 250, 21, 250, 251, 42, 0, 229, 21, 24, 15, 233, 243, 51, 222, 254, 102, 239, 189, 1, 30, 26, 1, 10, 249, 232, 45, 10, 254, 44, 14, 174, 226, 78, 43, 0, 216, 245, 57, 6, 227, 221, 254, 73, 30, 11, 205, 193, 19, 39, 24, 30, 252, 9, 26, 214, 206, 253, 60, 54, 30, 244, 176, 195, 48, 94, 247, 211, 33, 36, 249, 213, 2, 30, 232, 42, 47, 204, 43, 64, 158, 227, 94, 250, 196, 79, 87, 167, 177, 16, 41, 23, 32, 36, 220, 237, 240, 10, 40, 235, 8, 22, 29, 15, 212, 230, 244, 50, 35, 246, 28, 229, 248, 15, 9, 216, 255, 36, 72, 53, 205, 233, 229, 229, 48, 2, 26, 38, 12, 23, 240, 186, 12, 45, 222, 23, 22, 241, 70, 3, 189, 236, 52, 34, 226, 252, 82, 7, 211, 241, 10, 251, 20, 63, 241, 4, 255, 235, 69, 234, 255, 16, 234, 36, 24, 190, 255, 63, 52, 37, 217, 153, 26, 54, 17, 43, 28, 232, 240, 250, 11, 239, 6, 16, 54, 41, 203, 245, 14, 222, 14, 30, 18, 15, 238, 4, 20, 25, 51, 196, 149, 68, 73, 28, 13, 24, 19, 208, 205, 247, 11, 14, 79, 20, 234, 23, 219, 211, 237, 32, 57, 26, 237, 20, 12, 186, 247, 41, 52, 20, 12, 29, 0, 161, 193, 97, 100, 22, 205, 249, 13, 12, 12, 224, 7, 29, 222, 6, 81, 37, 226, 201, 233, 33, 25, 21, 10, 27, 21, 215, 206, 250, 41, 38, 248, 10, 248, 253, 26, 5, 190, 230, 99, 80, 238, 189, 215, 11, 47, 30, 47, 53, 189, 226, 0, 209, 30, 59, 16, 17, 30, 250, 194, 239, 20, 24, 13, 13, 9, 17, 240, 253, 20, 0, 235, 229, 255, 56, 51, 228, 224, 23, 253, 10, 248, 235, 21, 35, 31, 250, 18, 254, 215, 17, 36, 41, 235, 228, 8, 238, 21, 33, 27, 14, 239, 232, 222, 23, 27, 247, 9, 61, 18, 193, 217, 32, 51, 228, 253, 44, 46, 253, 188, 209, 33, 80, 5, 241, 239, 3, 2, 1, 3, 240, 16, 22, 245, 244, 15, 25, 234, 3, 41, 218, 214, 20, 36, 31, 1, 239, 4, 33, 249, 210, 13, 32, 20, 254, 0, 26, 0, 35, 44, 236, 214, 6, 27, 31, 15, 242, 15, 13, 45, 14, 191, 225, 69, 30, 35, 24, 178, 223, 31, 28, 253, 240, 41, 50, 238, 238, 217, 228, 250, 37, 50, 29, 247, 245, 25, 245, 236, 253, 41, 58, 241, 249, 21, 26, 252, 205, 2, 18, 54, 29, 2, 0, 255, 244, 0, 40, 251, 219, 24, 30, 35, 25, 233, 5, 14, 244, 246, 250, 29, 8, 234, 28, 16, 241, 243, 250, 14, 220, 232, 53, 45, 15, 246, 247, 236, 229, 4, 40, 73, 40, 237, 201, 10, 0, 245, 45, 5, 23, 40, 12, 228, 225, 253, 20, 23, 38, 24, 227, 10, 42, 251, 217, 248, 12, 36, 37, 0, 12, 233, 234, 28, 9, 224, 4, 3, 22, 10, 6, 247, 8, 242, 235, 18, 32, 26, 236, 211, 24, 74, 10, 224, 248, 39, 7, 236, 6, 36, 38, 28, 245, 224, 2, 252, 243, 6, 57, 70, 13, 198, 201, 240, 9, 42, 54, 14, 245, 15, 245, 239, 8, 249, 6, 51, 34, 13, 0, 232, 247, 237, 27, 45, 12, 232, 13, 46, 32, 2, 242, 245, 255, 11, 248, 246, 18, 55, 41, 254, 224, 243, 237, 243, 255, 254, 0, 57, 68, 248, 212, 225, 233, 21, 21, 5, 26, 16, 237, 234, 3, 30, 255, 242, 14, 4, 18, 32, 21, 254, 247, 242, 244, 1, 75, 50, 3, 16, 231, 214, 247, 40, 35, 12, 8, 33, 0, 204, 252, 12, 1, 23, 58, 8, 228, 0, 9, 232, 4, 35, 2, 14, 27, 234, 227, 250, 28, 38, 2, 2, 245, 227, 243, 18, 27, 10, 254, 6, 20, 5, 248, 218, 15, 44, 14, 8, 18, 27, 253, 228, 249, 253, 32, 54, 15, 247, 255, 241, 223, 11, 62, 39, 249, 251, 29, 254, 216, 254, 17, 47, 49, 17, 243, 241, 6, 245, 244, 28, 42, 19, 11, 246, 239, 246, 10, 27, 7, 249, 13, 11, 255, 19, 255, 243, 8, 0, 1, 13, 16, 12, 253, 15, 4, 233, 252, 25, 7, 255, 21, 22, 0, 253, 12, 252, 247, 252, 10, 25, 38, 14, 242, 255, 10, 5, 9, 16, 15, 244, 249, 23, 25, 1, 3, 7, 250, 1, 2, 14, 23, 15, 240, 245, 15, 12, 0, 6, 17, 10, 1, 243, 249, 13, 23, 0, 8, 16, 1, 7, 6, 1, 1, 10, 6, 12, 9, 7, 11, 5, 0, 3, 4, 8, 18, 2, 251, 10, 29, 25, 246, 237, 244, 16, 31, 23, 8, 0, 252, 251, 5, 7, 12, 18, 9, 4, 250, 251, 10, 5, 1, 9, 17, 255, 254, 11, 10, 7, 0, 2, 8, 2, 12, 14, 1, 8, 3, 243, 6, 20, 8, 250, 0, 16, 11, 2, 7, 4, 249, 4, 12, 10, 8, 4, 13, 14, 1, 0, 1, 6, 8, 5, 0, 2, 10, 7, 6, 250, 247, 4, 8, 12, 15, 4, 248, 244, 1, 10, 5, 2, 6, 13, 8, 251, 251, 12, 8, 246, 250, 4, 12, 12, 11, 9, 1, 250, 248, 4, 4, 5, 19, 19, 7, 255, 255, 6, 17, 11, 1, 10, 24, 7, 2, 10, 10, 254, 2, 22, 13, 254, 0, 9, 14, 7, 3, 2, 4, 8, 12, 11, 11, 10, 10, 13, 17, 2, 2, 14, 20, 11, 8, 27, 13, 254, 14, 13, 7, 8, 10, 13, 14, 13, 6, 6, 3, 3, 4, 0, 0, 254, 6, 29, 0, 249, 255, 10, 5, 11, 0, 255, 254, 2, 4, 4, 9, 252, 250, 6, 2, 10, 255, 239, 0, 12, 11, 0, 249, 246, 4, 12, 253, 253, 254, 18, 254, 236, 235, 13, 24, 254, 244, 246, 0, 5, 7, 3, 248, 0, 1, 241, 250, 12, 11, 3, 4, 2, 0, 247, 251, 2, 5, 14, 3, 254, 2, 234, 8, 31, 5, 238, 248, 252, 255, 20, 4, 243, 9, 5, 253, 246, 0, 253, 13, 2, 8, 242, 233, 18, 30, 5, 237, 235, 253, 11, 10, 10, 253, 235, 6, 9, 5, 255, 245, 254, 7, 5, 2, 244, 239, 255, 21, 16, 242, 0, 20, 239, 237, 18, 2, 251, 4, 254, 6, 247, 3, 31, 3, 0, 255, 226, 243, 29, 21, 244, 242, 9, 22, 255, 231, 243, 19, 12, 241, 248, 18, 4, 225, 254, 23, 6, 246, 240, 13, 6, 249, 18, 255, 243, 251, 11, 5, 248, 2, 246, 2, 15, 19, 7, 230, 233, 16, 12, 13, 5, 226, 232, 18, 41, 13, 232, 229, 6, 12, 10, 0, 237, 252, 7, 11, 10, 247, 244, 254, 0, 9, 0, 238, 10, 30, 4, 240, 241, 243, 17, 8, 2, 1, 245, 4, 12, 255, 255, 0, 6, 12, 251, 247, 8, 242, 238, 4, 24, 25, 253, 232, 227, 255, 42, 255, 247, 249, 252, 13, 10, 8, 255, 228, 245, 17, 10, 11, 236, 226, 21, 42, 252, 248, 228, 229, 16, 39, 14, 238, 3, 249, 240, 22, 254, 11, 236, 228, 26, 48, 3, 201, 0, 5, 40, 13, 211, 230, 14, 23, 253, 11, 247, 247, 248, 246, 29, 25, 247, 224, 224, 253, 41, 48, 228, 236, 247, 239, 51, 32, 208, 228, 17, 38, 14, 1, 250, 239, 230, 1, 38, 19, 230, 237, 28, 22, 243, 235, 5, 2, 244, 250, 8, 7, 0, 239, 238, 34, 9, 218, 3, 34, 233, 213, 22, 42, 23, 222, 219, 246, 47, 19, 226, 249, 1, 19, 18, 244, 255, 248, 233, 247, 20, 38, 253, 235, 44, 17, 195, 251, 49, 252, 231, 239, 0, 30, 20, 247, 247, 6, 242, 2, 4, 254, 248, 1, 39, 2, 214, 236, 26, 27, 250, 236, 237, 11, 22, 249, 0, 252, 249, 254, 249, 9, 0, 248, 17, 27, 235, 225, 252, 37, 40, 240, 194, 0, 31, 3, 240, 251, 28, 18, 14, 234, 226, 2, 23, 4, 2, 10, 1, 12, 236, 232, 3, 18, 247, 19, 25, 233, 225, 16, 13, 239, 245, 13, 254, 237, 43, 63, 225, 153, 231, 53, 35, 7, 2, 243, 211, 255, 33, 15, 224, 214, 36, 62, 9, 9, 249, 183, 240, 40, 33, 29, 233, 252, 239, 243, 55, 4, 198, 220, 33, 74, 29, 211, 211, 241, 8, 36, 16, 0, 227, 211, 22, 245, 9, 16, 20, 10, 214, 231, 5, 30, 230, 242, 38, 28, 25, 228, 220, 248, 249, 35, 47, 2, 215, 227, 21, 4, 255, 19, 6, 242, 209, 19, 54, 2, 233, 240, 0, 255, 28, 248, 228, 17, 12, 7, 8, 0, 249, 227, 24, 18, 4, 242, 232, 16, 8, 10, 240, 4, 15, 224, 223, 246, 36, 21, 48, 10, 195, 212, 253, 44, 22, 2, 249, 233, 6, 235, 2, 13, 38, 13, 194, 235, 0, 14, 247, 6, 77, 8, 171, 234, 49, 223, 9, 61, 249, 35, 11, 183, 241, 27, 24, 29, 253, 181, 215, 72, 81, 240, 222, 18, 11, 233, 211, 223, 81, 32, 184, 215, 65, 36, 215, 203, 247, 88, 18, 171, 223, 45, 29, 248, 229, 2, 31, 240, 190, 255, 66, 39, 4, 216, 255, 253, 236, 7, 27, 19, 233, 246, 42, 6, 230, 2, 22, 0, 249, 239, 8, 31, 246, 244, 235, 11, 18, 239, 237, 7, 25, 12, 254, 245, 243, 253, 37, 8, 221, 242, 43, 19, 196, 204, 33, 63, 7, 242, 191, 221, 45, 79, 26, 210, 185, 4, 55, 1, 223, 7, 35, 228, 217, 1, 78, 51, 177, 165, 41, 81, 4, 244, 223, 223, 83, 37, 213, 253, 17, 234, 235, 5, 32, 16, 236, 199, 229, 22, 86, 37, 174, 179, 20, 52, 29, 250, 222, 207, 10, 85, 36, 222, 182, 196, 48, 69, 20, 240, 235, 23, 7, 228, 251, 220, 246, 87, 66, 198, 140, 43, 80, 14, 4, 16, 203, 157, 7, 60, 59, 20, 225, 223, 26, 24, 235, 216, 175, 7, 46, 31, 20, 73, 23, 131, 204, 73, 27, 204, 249, 25, 10, 14, 36, 21, 204, 213, 11, 57, 18, 197, 198, 251, 68, 58, 235, 14, 235, 157, 215, 27, 125, 87, 175, 148, 13, 44, 26, 36, 228, 196, 8, 13, 39, 52, 234, 148, 252, 96, 60, 18, 170, 155, 64, 84, 234, 187, 225, 8, 19, 240, 9, 17, 14, 247, 192, 42, 73, 250, 236, 224, 238, 76, 33, 176, 218, 49, 47, 252, 223, 252, 248, 244, 63, 32, 164, 21, 52, 195, 211, 23, 44, 9, 225, 248, 57, 210, 246, 102, 208, 191, 37, 2, 227, 29, 53, 220, 242, 15, 15, 205, 238, 40, 27, 30, 216, 218, 12, 21, 220, 202, 23, 105, 37, 140, 208, 60, 7, 219, 35, 42, 232, 244, 255, 47, 46, 189, 167, 246, 55, 90, 12, 207, 162, 222, 64, 81, 47, 236, 173, 222, 81, 42, 243, 182, 203, 46, 46, 30, 202, 207, 24, 63, 20, 36, 23, 164, 163, 255, 77, 100, 250, 187, 223, 0, 245, 35, 71, 220, 196, 232, 18, 31, 21, 251, 239, 71, 224, 160, 15, 4, 10, 93, 12, 190, 241, 234, 187, 48, 59, 24, 21, 193, 215, 5, 25, 2, 232, 254, 12, 33, 248, 0, 240, 1, 41, 18, 5, 252, 232, 247, 42, 31, 201, 12, 74, 223, 229, 16, 20, 12, 242, 226, 235, 1, 14, 44, 0, 179, 245, 19, 187, 8, 107, 253, 186, 234, 44, 3, 216, 3, 24, 224, 3, 34, 1, 232, 7, 238, 201, 48, 67, 242, 2, 252, 10, 33, 225, 224, 8, 1, 14, 84, 243, 166, 34, 67, 222, 188, 51, 114, 230, 187, 180, 6, 114, 37, 200, 190, 254, 10, 20, 28, 21, 38, 187, 198, 9, 60, 3, 166, 245, 106, 43, 156, 233, 0, 33, 43, 177, 220, 32, 22, 0, 252, 226, 10, 77, 235, 165, 244, 62, 6, 247, 29, 251, 47, 252, 176, 221, 110, 44, 229, 12, 236, 222, 61, 26, 209, 237, 29, 36, 17, 211, 211, 8, 56, 11, 211, 6, 233, 217, 7, 61, 3, 221, 226, 251, 33, 246, 223, 42, 242, 214, 21, 50, 243, 240, 253, 226, 19, 47, 56, 220, 192, 245, 29, 33, 19, 220, 230, 44, 38, 238, 5, 221, 174, 98, 43, 206, 245, 250, 57, 250, 214, 27, 254, 197, 23, 55, 254, 172, 1, 72, 14, 201, 233, 54, 15, 203, 0, 69, 232, 240, 227, 223, 47, 77, 0, 182, 238, 51, 50, 243, 166, 19, 39, 234, 254, 47, 4, 215, 11, 10, 223, 253, 40, 55, 210, 235, 10, 7, 16, 176, 223, 96, 77, 210, 164, 212, 16, 90, 54, 162, 218, 10, 13, 65, 13, 185, 210, 36, 41, 37, 17, 214, 245, 238, 0, 54, 35, 217, 223, 20, 16, 227, 212, 60, 33, 221, 230, 12, 16, 22, 242, 229, 43, 240, 194, 14, 15, 223, 39, 70, 244, 186, 236, 46, 53, 233, 174, 9, 64, 12, 251, 220, 4, 31, 3, 218, 244, 30, 240, 14, 30, 18, 238, 40, 243, 163, 224, 74, 45, 198, 249, 255, 33, 3, 227, 10, 253, 254, 250, 31, 44, 254, 10, 215, 205, 29, 26, 212, 234, 23, 5, 10, 18, 241, 230, 45, 1, 218, 4, 37, 31, 192, 220, 50, 56, 234, 248, 14, 216, 11, 240, 11, 67, 210, 233, 21, 248, 214, 0, 39, 35, 0, 215, 35, 10, 210, 255, 16, 228, 210, 92, 61, 222, 189, 247, 21, 247, 10, 9, 24, 224, 220, 27, 68, 6, 193, 233, 48, 28, 204, 250, 49, 29, 221, 211, 23, 7, 248, 6, 10, 21, 255, 251, 214, 221, 29, 23, 0, 237, 8, 252, 241, 23, 23, 246, 216, 0, 22, 246, 29, 32, 230, 197, 26, 63, 6, 224, 247, 37, 43, 0, 210, 254, 236, 228, 77, 21, 174, 206, 15, 49, 14, 234, 227, 252, 251, 0, 9, 19, 5, 246, 1, 4, 17, 239, 208, 252, 30, 66, 46, 3, 199, 192, 6, 67, 66, 246, 199, 215, 66, 72, 220, 202, 255, 14, 27, 253, 216, 235, 242, 0, 57, 42, 191, 155, 229, 72, 49, 222, 0, 253, 188, 233, 21, 27, 16, 31, 9, 193, 213, 78, 55, 0, 237, 227, 36, 54, 22, 212, 221, 12, 74, 68, 206, 186, 27, 74, 27, 195, 216, 12, 0, 252, 5, 23, 1, 212, 208, 234, 50, 53, 240, 225, 199, 232, 15, 18, 10, 202, 207, 4, 19, 43, 23, 247, 4, 254, 238, 253, 22, 32, 238, 232, 66, 75, 222, 207, 225, 10, 61, 55, 242, 200, 239, 32, 14, 0, 240, 255, 21, 6, 239, 34, 20, 204, 246, 9, 235, 234, 255, 9, 0, 29, 0, 208, 220, 0, 58, 54, 217, 180, 253, 19, 37, 64, 251, 194, 219, 254, 28, 254, 253, 254, 29, 50, 0, 173, 212, 57, 74, 16, 223, 245, 2, 242, 8, 42, 0, 243, 4, 253, 9, 27, 241, 217, 1, 34, 36, 1, 223, 217, 250, 28, 30, 236, 224, 239, 242, 14, 20, 253, 232, 212, 232, 78, 65, 192, 166, 235, 42, 66, 14, 225, 228, 230, 12, 67, 48, 221, 208, 249, 29, 42, 44, 10, 201, 208, 52, 69, 230, 218, 24, 30, 20, 239, 208, 235, 23, 40, 29, 10, 249, 227, 205, 219, 4, 39, 27, 232, 224, 254, 28, 35, 231, 193, 228, 37, 9, 244, 255, 7, 33, 246, 225, 234, 246, 250, 16, 48, 37, 243, 204, 242, 35, 64, 19, 210, 219, 231, 243, 14, 43, 51, 32, 237, 206, 2, 19, 3, 2, 236, 252, 29, 9, 234, 8, 46, 9, 223, 234, 12, 24, 252, 229, 247, 249, 9, 16, 1, 233, 6, 14, 245, 250, 255, 251, 242, 252, 5, 6, 10, 233, 223, 5, 22, 12, 249, 4, 247, 240, 245, 27, 29, 231, 235, 26, 34, 15, 248, 223, 247, 14, 3, 0, 3, 22, 13, 230, 239, 43, 54, 236, 219, 233, 253, 19, 18, 9, 0, 5, 7, 0, 240, 236, 1, 18, 251, 16, 12, 239, 234, 5, 11, 242, 247, 12, 33, 250, 241, 0, 234, 240, 0, 10, 235, 219, 248, 0, 0, 72, 4, 48, 0, 20, 243, 243, 32, 248, 1, 249, 9, 17, 225, 246, 27, 7, 231, 12, 8, 254, 5, 245, 255, 15, 0, 210, 26, 28, 197, 8, 36, 238, 7, 245, 247, 30, 237, 0, 26, 235, 38, 16, 183, 40, 43, 183, 12, 55, 228, 255, 252, 3, 23, 227, 10, 24, 231, 32, 245, 220, 36, 4, 231, 28, 21, 247, 248, 8, 10, 208, 244, 18, 3, 226, 205, 40, 40, 222, 255, 22, 236, 18, 0, 0, 24, 243, 19, 14, 230, 2, 246, 237, 4, 242, 4, 37, 244, 5, 20, 2, 235, 220, 29, 82, 188, 216, 75, 243, 253, 253, 249, 27, 238, 242, 8, 1, 245, 16, 236, 228, 42, 48, 202, 236, 53, 231, 231, 36, 0, 249, 21, 204, 52, 228, 214, 65, 198, 214, 110, 251, 205, 32, 48, 10, 222, 0, 19, 228, 251, 10, 201, 8, 74, 235, 229, 251, 251, 253, 31, 233, 206, 66, 30, 205, 3, 6, 23, 248, 211, 15, 23, 249, 237, 6, 10, 33, 240, 201, 49, 22, 215, 247, 24, 24, 9, 240, 6, 47, 249, 228, 42, 5, 211, 1, 12, 37, 16, 216, 2, 29, 218, 208, 17, 249, 33, 1, 200, 46, 7, 228, 239, 255, 17, 232, 235, 35, 27, 222, 232, 17, 7, 240, 237, 17, 23, 216, 234, 44, 21, 240, 7, 44, 1, 224, 248, 48, 13, 217, 5, 20, 26, 0, 3, 17, 1, 214, 243, 42, 246, 232, 32, 31, 235, 243, 6, 243, 240, 7, 15, 4, 8, 244, 241, 254, 8, 4, 3, 0, 236, 237, 243, 23, 227, 0, 51, 196, 200, 76, 45, 201, 231, 15, 27, 249, 253, 9, 249, 37, 18, 194, 16, 69, 213, 211, 9, 19, 26, 244, 8, 23, 20, 238, 210, 9, 59, 221, 205, 82, 52, 181, 231, 26, 7, 230, 238, 37, 17, 4, 226, 239, 40, 32, 234, 203, 5, 38, 235, 228, 40, 220, 0, 65, 208, 210, 41, 26, 213, 238, 35, 43, 213, 228, 63, 217, 234, 22, 255, 8, 253, 233, 0, 47, 244, 5, 12, 2, 10, 240, 42, 240, 230, 46, 237, 234, 28, 24, 250, 3, 254, 237, 253, 10, 26, 213, 246, 87, 224, 155, 58, 64, 172, 167, 58, 52, 206, 0, 26, 252, 239, 238, 239, 233, 37, 16, 236, 245, 27, 20, 237, 30, 14, 225, 2, 17, 2, 254, 30, 10, 241, 18, 32, 10, 241, 251, 255, 13, 254, 234, 39, 4, 245, 17, 220, 0, 37, 243, 193, 36, 47, 195, 193, 76, 60, 177, 244, 40, 245, 210, 236, 255, 2, 252, 26, 3, 254, 45, 201, 196, 60, 238, 231, 53, 18, 244, 24, 245, 222, 20, 14, 2, 15, 242, 249, 246, 38, 28, 219, 235, 48, 49, 201, 228, 44, 16, 218, 17, 0, 10, 26, 1, 233, 226, 35, 19, 223, 208, 40, 25, 217, 1, 217, 24, 34, 242, 229, 238, 55, 48, 159, 183, 75, 51, 251, 229, 244, 41, 253, 179, 249, 66, 42, 229, 212, 47, 29, 212, 0, 25, 3, 2, 30, 19, 234, 0, 221, 20, 39, 235, 249, 5, 11, 5, 192, 232, 67, 0, 223, 20, 234, 12, 30, 212, 234, 4, 12, 7, 217, 15, 46, 217, 244, 6, 240, 23, 39, 236, 226, 30, 17, 242, 248, 1, 18, 251, 255, 255, 0, 11, 11, 0, 251, 16, 23, 241, 0, 11, 16, 248, 239, 245, 16, 12, 216, 0, 3, 10, 43, 246, 227, 13, 254, 205, 1, 47, 31, 234, 194, 35, 66, 234, 210, 228, 6, 62, 226, 202, 43, 19, 193, 227, 54, 33, 17, 228, 240, 254, 14, 14, 186, 30, 126, 219, 166, 31, 42, 248, 214, 231, 52, 2, 1, 39, 191, 228, 68, 227, 212, 63, 37, 3, 227, 215, 35, 31, 226, 0, 8, 250, 17, 240, 219, 18, 23, 253, 214, 0, 51, 0, 209, 21, 51, 242, 202, 252, 43, 8, 250, 16, 7, 18, 242, 218, 36, 13, 194, 246, 35, 12, 255, 219, 251, 71, 10, 189, 233, 15, 13, 0, 227, 41, 64, 236, 191, 212, 17, 36, 1, 215, 52, 43, 216, 186, 4, 65, 11, 236, 3, 16, 245, 253, 24, 5, 222, 15, 19, 2, 21, 243, 227, 32, 11, 200, 5, 58, 22, 220, 225, 21, 10, 14, 224, 185, 57, 66, 197, 248, 25, 230, 254, 249, 242, 26, 24, 238, 240, 253, 33, 14, 244, 26, 240, 206, 244, 8, 22, 20, 4, 4, 7, 16, 221, 225, 18, 33, 231, 235, 35, 24, 22, 238, 240, 253, 4, 8, 234, 236, 2, 21, 6, 30, 250, 221, 18, 6, 233, 244, 17, 22, 254, 244, 4, 21, 17, 241, 213, 16, 23, 223, 253, 18, 255, 5, 3, 225, 24, 4, 245, 239, 217, 27, 44, 247, 2, 7, 6, 0, 210, 244, 50, 9, 247, 9, 0, 20, 216, 232, 53, 11, 230, 2, 248, 8, 30, 250, 237, 241, 35, 50, 252, 210, 225, 6, 11, 8, 7, 22, 254, 231, 253, 255, 3, 15, 252, 241, 14, 11, 236, 230, 227, 250, 22, 22, 2, 7, 21, 0, 230, 253, 31, 9, 235, 245, 16, 13, 229, 239, 2, 5, 20, 250, 234, 27, 29, 225, 213, 4, 39, 48, 5, 231, 0, 3, 0, 14, 229, 227, 13, 17, 24, 15, 231, 229, 3, 246, 22, 6, 255, 17, 244, 239, 20, 3, 247, 16, 247, 234, 245, 21, 1, 217, 246, 43, 35, 2, 231, 241, 13, 247, 248, 20, 13, 18, 4, 229, 242, 7, 9, 250, 249, 17, 255, 245, 19, 0, 0, 19, 255, 6, 242, 237, 254, 254, 247, 10, 10, 247, 2, 251, 239, 242, 6, 36, 13, 242, 232, 13, 24, 255, 236, 246, 5, 9, 16, 29, 7, 219, 250, 18, 252, 247, 2, 25, 0, 222, 249, 25, 30, 0, 237, 216, 2, 31, 254, 244, 251, 1, 0, 252, 255, 24, 247, 224, 254, 18, 30, 8, 253, 251, 3, 0, 13, 251, 235, 16, 22, 5, 246, 246, 9, 16, 242, 253, 11, 9, 250, 208, 237, 22, 18, 255, 253, 6, 8, 237, 227, 249, 254, 250, 7, 10, 20, 12, 250, 248, 249, 0, 0, 0, 9, 19, 12, 17, 12, 253, 235, 242, 7, 19, 10, 244, 253, 9, 9, 8, 2, 255, 2, 244, 243, 254, 248, 246, 1, 22, 4, 0, 244, 251, 253, 243, 255, 17, 20, 244, 237, 253, 2, 7, 6, 250, 247, 249, 250, 4, 0, 1, 0, 6, 9, 169, 2, 15, 0, 248, 210, 174, 42, 30, 188, 13, 55, 245, 4, 253, 171, 232, 59, 16, 228, 244, 243, 221, 35, 28, 227, 237, 8, 48, 27, 3, 252, 218, 9, 14, 243, 249, 250, 4, 20, 3, 244, 243, 7, 37, 11, 227, 247, 251, 31, 58, 231, 237, 2, 5, 254, 227, 253, 15, 243, 248, 244, 19, 4, 249, 30, 11, 5, 27, 35, 35, 187, 131, 49, 46, 252, 236, 220, 241, 36, 60, 208, 211, 62, 254, 255, 25, 227, 2, 30, 27, 240, 198, 244, 37, 241, 213, 19, 241, 1, 34, 241, 17, 5, 230, 9, 12, 4, 254, 14, 5, 12, 244, 238, 23, 6, 21, 27, 231, 255, 16, 245, 232, 250, 4, 15, 7, 238, 225, 7, 255, 23, 15, 5, 229, 239, 26, 249, 234, 27, 254, 185, 229, 31, 239, 221, 18, 215, 172, 221, 43, 6, 238, 251, 234, 11, 34, 254, 254, 5, 11, 50, 34, 225, 243, 53, 49, 8, 233, 250, 41, 42, 42, 240, 252, 53, 31, 244, 246, 20, 25, 18, 235, 249, 42, 1, 238, 15, 1, 2, 29, 0, 2, 40, 254, 18, 11, 226, 15, 44, 231, 168, 243, 37, 48, 238, 190, 244, 17, 47, 245, 224, 4, 246, 23, 29, 247, 230, 244, 42, 37, 225, 204, 234, 37, 67, 210, 168, 236, 55, 67, 221, 192, 9, 67, 253, 218, 227, 3, 52, 22, 227, 203, 235, 86, 48, 210, 176, 21, 69, 30, 253, 230, 29, 38, 245, 248, 49, 28, 254, 26, 8, 237, 33, 57, 22, 245, 242, 32, 57, 0, 226, 15, 42, 20, 0, 233, 183, 238, 55, 45, 213, 172, 203, 29, 71, 254, 185, 170, 235, 49, 25, 190, 195, 21, 42, 250, 195, 230, 13, 27, 19, 239, 244, 226, 245, 0, 249, 4, 224, 204, 231, 50, 50, 208, 187, 204, 189, 231, 52, 18, 205, 191, 239, 26, 250, 241, 220, 228, 18, 23, 226, 210, 25, 71, 30, 195, 191, 9, 79, 62, 250, 2, 250, 3, 43, 44, 4, 250, 26, 10, 254, 30, 36, 5, 245, 17, 33, 10, 245, 4, 55, 3, 6, 50, 4, 254, 17, 249, 28, 26, 245, 0, 6, 240, 237, 16, 253, 204, 215, 248, 232, 30, 23, 190, 208, 26, 32, 225, 208, 243, 22, 3, 215, 241, 13, 46, 38, 253, 224, 229, 28, 37, 17, 5, 3, 244, 244, 0, 0, 225, 254, 17, 215, 198, 237, 35, 26, 233, 219, 213, 232, 30, 8, 244, 6, 242, 8, 36, 14, 196, 230, 50, 48, 249, 212, 245, 21, 27, 235, 236, 246, 2, 38, 2, 197, 209, 29, 28, 0, 9, 242, 248, 31, 32, 228, 226, 41, 68, 29, 221, 244, 45, 88, 62, 248, 238, 250, 49, 42, 50, 10, 195, 206, 76, 84, 197, 204, 29, 17, 183, 19, 59, 244, 201, 234, 252, 238, 29, 231, 221, 11, 16, 209, 245, 22, 236, 228, 13, 11, 225, 196, 229, 41, 32, 224, 232, 248, 255, 246, 226, 22, 28, 216, 174, 33, 78, 24, 216, 235, 32, 36, 11, 252, 250, 247, 31, 79, 26, 212, 247, 78, 69, 28, 236, 244, 65, 75, 30, 238, 24, 29, 248, 27, 78, 37, 255, 215, 230, 69, 64, 10, 12, 4, 0, 253, 24, 43, 16, 206, 235, 18, 42, 37, 2, 174, 176, 254, 43, 2, 221, 200, 219, 254, 241, 237, 229, 210, 237, 252, 221, 217, 242, 237, 215, 244, 17, 220, 172, 202, 26, 22, 242, 222, 250, 238, 216, 228, 233, 241, 244, 229, 220, 247, 233, 219, 215, 239, 251, 239, 216, 208, 226, 18, 44, 27, 0, 254, 242, 7, 29, 33, 20, 9, 15, 61, 59, 8, 224, 226, 29, 92, 85, 11, 211, 206, 250, 21, 235, 206, 240, 252, 204, 174, 217, 251, 237, 187, 186, 202, 216, 207, 173, 159, 178, 233, 241, 198, 169, 166, 181, 214, 9, 4, 209, 179, 193, 239, 8, 6, 249, 239, 235, 246, 7, 14, 0, 252, 12, 18, 21, 245, 228, 8, 31, 0, 0, 0, 183, 4, 23, 0, 11, 14, 14, 14, 12, 9, 7, 8, 15, 14, 14, 15, 11, 4, 2, 254, 251, 247, 248, 249, 254, 4, 8, 7, 6, 10, 9, 7, 11, 9, 3, 1, 7, 9, 6, 14, 13, 14, 10, 12, 12, 12, 15, 16, 14, 18, 14, 10, 11, 11, 9, 10, 12, 12, 18, 16, 6, 3, 0, 0, 0, 255, 0, 1, 9, 8, 14, 23, 21, 17, 22, 2, 250, 1, 255, 199, 133, 166, 246, 26, 34, 27, 1, 8, 21, 3, 233, 240, 3, 32, 53, 54, 43, 44, 39, 16, 1, 5, 22, 29, 30, 30, 34, 35, 30, 32, 18, 7, 8, 20, 33, 48, 45, 42, 32, 19, 10, 9, 9, 9, 4, 8, 14, 24, 16, 6, 1, 0, 246, 246, 6, 15, 14, 9, 7, 4, 10, 14, 244, 186, 206, 248, 29, 13, 18, 4, 7, 26, 4, 237, 224, 0, 25, 38, 33, 18, 23, 26, 17, 254, 4, 9, 18, 27, 31, 27, 24, 22, 11, 6, 253, 0, 6, 22, 20, 9, 5, 12, 14, 8, 1, 250, 248, 1, 3, 2, 255, 0, 4, 7, 255, 251, 255, 10, 17, 11, 9, 10, 12, 11, 8, 14, 17, 21, 28, 23, 25, 19, 17, 25, 26, 14, 9, 15, 29, 29, 17, 19, 17, 13, 16, 15, 15, 20, 17, 10, 254, 254, 0, 8, 8, 7, 9, 8, 4, 3, 0, 0, 255, 252, 255, 2, 15, 7, 11, 13, 15, 15, 13, 8, 16, 25, 17, 24, 28, 23, 23, 20, 28, 36, 33, 22, 15, 16, 26, 24, 14, 11, 12, 9, 15, 24, 15, 8, 7, 0, 251, 254, 0, 5, 10, 11, 16, 3, 5, 2, 0, 248, 246, 1, 9, 16, 7, 3, 4, 5, 8, 5, 0, 247, 4, 19, 10, 0, 254, 9, 14, 12, 1, 253, 14, 17, 14, 1, 1, 18, 19, 25, 17, 3, 9, 22, 19, 9, 2, 255, 0, 9, 8, 4, 10, 15, 13, 255, 248, 252, 6, 14, 13, 7, 6, 13, 8, 254, 254, 11, 13, 15, 11, 5, 12, 19, 16, 11, 3, 252, 7, 18, 20, 14, 11, 13, 18, 10, 12, 10, 4, 17, 13, 6, 1, 7, 12, 17, 9, 254, 0, 6, 13, 11, 10, 7, 10, 11, 7, 15, 9, 12, 18, 16, 19, 14, 9, 8, 17, 18, 21, 20, 17, 19, 18, 11, 0, 5, 16, 26, 17, 1, 5, 19, 24, 3, 249, 1, 7, 19, 10, 3, 10, 15, 13, 8, 0, 0, 14, 22, 7, 4, 22, 28, 22, 14, 4, 15, 23, 16, 16, 24, 34, 33, 19, 4, 0, 7, 21, 33, 27, 21, 14, 4, 0, 0, 6, 6, 11, 14, 11, 15, 10, 9, 3, 255, 6, 11, 22, 27, 21, 4, 9, 23, 20, 6, 8, 12, 18, 22, 12, 8, 14, 14, 10, 2, 0, 255, 6, 17, 18, 8, 5, 4, 252, 3, 0, 0, 6, 9, 10, 8, 4, 3, 13, 11, 3, 1, 0, 11, 23, 23, 16, 17, 14, 11, 13, 17, 12, 10, 8, 3, 6, 11, 15, 16, 11, 4, 11, 7, 248, 246, 5, 7, 3, 9, 12, 12, 11, 0, 252, 16, 22, 13, 13, 19, 32, 35, 26, 17, 15, 30, 34, 21, 4, 15, 34, 37, 23, 15, 18, 27, 37, 19, 7, 14, 23, 22, 17, 4, 0, 22, 24, 16, 7, 9, 19, 19, 14, 5, 6, 12, 12, 4, 5, 21, 19, 13, 8, 255, 250, 255, 10, 15, 9, 8, 14, 11, 3, 254, 1, 14, 18, 23, 24, 20, 24, 14, 4, 3, 8, 15, 28, 34, 20, 16, 12, 3, 2, 4, 1, 4, 11, 13, 16, 11, 0, 248, 255, 5, 3, 9, 4, 0, 7, 14, 1, 248, 0, 6, 13, 9, 0, 4, 15, 9, 10, 11, 9, 18, 23, 25, 15, 11, 14, 19, 23, 16, 13, 21, 27, 21, 8, 6, 12, 16, 7, 7, 8, 9, 14, 14, 4, 249, 0, 1, 0, 0, 254, 1, 1, 250, 242, 245, 0, 10, 2, 252, 248, 248, 252, 2, 0, 0, 7, 10, 18, 24, 17, 5, 5, 7, 4, 3, 7, 20, 22, 21, 20, 14, 5, 255, 7, 17, 14, 10, 11, 17, 15, 2, 0, 4, 4, 12, 17, 12, 10, 4, 0, 9, 14, 7, 4, 3, 6, 8, 10, 16, 17, 11, 11, 14, 14, 8, 9, 12, 13, 14, 7, 5, 16, 21, 18, 17, 14, 12, 17, 17, 15, 3, 255, 10, 29, 30, 21, 12, 1, 2, 0, 254, 5, 17, 18, 13, 3, 0, 7, 9, 2, 253, 249, 0, 6, 9, 1, 1, 8, 8, 2, 5, 7, 0, 254, 255, 1, 13, 20, 19, 17, 16, 15, 6, 5, 15, 16, 15, 18, 17, 17, 18, 14, 4, 253, 252, 255, 5, 13, 10, 1, 4, 7, 4, 253, 249, 253, 255, 0, 3, 10, 12, 11, 10, 6, 15, 20, 17, 15, 19, 23, 21, 20, 23, 16, 12, 24, 29, 22, 15, 9, 14, 16, 1, 246, 255, 11, 15, 17, 7, 255, 253, 251, 254, 255, 3, 5, 14, 20, 14, 8, 12, 18, 9, 5, 6, 13, 21, 21, 17, 17, 20, 23, 15, 9, 11, 17, 14, 15, 12, 11, 15, 21, 21, 13, 5, 8, 5, 8, 5, 2, 4, 11, 5, 7, 10, 4, 5, 10, 12, 9, 12, 10, 10, 12, 13, 10, 10, 15, 11, 14, 16, 16, 13, 9, 2, 6, 19, 18, 13, 11, 15, 15, 12, 5, 8, 14, 17, 20, 21, 18, 9, 7, 16, 14, 7, 11, 19, 18, 19, 17, 18, 14, 11, 7, 4, 6, 12, 14, 13, 7, 9, 15, 14, 3, 254, 0, 4, 6, 6, 6, 10, 13, 9, 255, 0, 10, 13, 9, 8, 3, 4, 14, 14, 8, 7, 9, 7, 5, 3, 6, 2, 5, 8, 8, 3, 4, 6, 4, 7, 6, 4, 3, 7, 6, 0, 3, 12, 20, 18, 8, 6, 12, 16, 12, 7, 6, 8, 13, 11, 12, 14, 19, 20, 15, 9, 7, 8, 5, 9, 7, 0, 2, 9, 8, 5, 8, 6, 5, 8, 6, 2, 7, 17, 18, 17, 15, 11, 13, 12, 10, 9, 11, 20, 26, 23, 17, 12, 13, 17, 14, 8, 9, 13, 17, 15, 13, 8, 12, 17, 15, 13, 9, 5, 7, 12, 12, 13, 14, 13, 7, 2, 7, 13, 17, 17, 11, 9, 9, 11, 10, 8, 7, 4, 5, 7, 16, 18, 11, 9, 11, 17, 19, 12, 5, 7, 11, 16, 17, 12, 13, 18, 17, 13, 5, 5, 12, 16, 14, 10, 9, 11, 12, 8, 4, 4, 11, 13, 9, 3, 5, 8, 3, 1, 3, 5, 8, 9, 7, 6, 5, 6, 11, 11, 6, 7, 11, 13, 15, 13, 10, 10, 10, 10, 8, 10, 13, 17, 18, 17, 15, 13, 11, 12, 8, 4, 8, 11, 9, 8, 9, 12, 10, 4, 6, 6, 7, 10, 12, 12, 10, 11, 9, 12, 11, 11, 8, 7, 13, 16, 15, 9, 10, 16, 14, 10, 7, 5, 7, 13, 9, 6, 8, 7, 8, 12, 12, 10, 3, 4, 4, 4, 5, 0, 58, 6, 27, 0, 8, 9, 9, 8, 10, 8, 9, 8, 10, 8, 8, 4, 5, 1, 250, 159, 133, 206, 248, 27, 55, 18, 7, 42, 51, 45, 26, 231, 224, 252, 15, 41, 48, 32, 37, 54, 57, 46, 31, 251, 246, 2, 9, 22, 19, 12, 24, 40, 44, 43, 28, 0, 251, 251, 253, 253, 246, 246, 3, 15, 28, 25, 13, 255, 246, 247, 250, 247, 242, 247, 255, 15, 25, 28, 22, 15, 3, 5, 0, 0, 255, 2, 4, 11, 23, 25, 25, 21, 18, 13, 7, 5, 1, 0, 2, 11, 14, 22, 23, 19, 17, 17, 13, 7, 3, 0, 255, 1, 3, 7, 12, 15, 15, 18, 11, 7, 6, 2, 4, 4, 1, 4, 6, 9, 15, 18, 10, 10, 8, 4, 11, 12, 9, 5, 9, 11, 22, 25, 19, 15, 10, 13, 15, 13, 5, 3, 6, 9, 14, 13, 14, 11, 9, 12, 19, 14, 6, 5, 7, 8, 15, 19, 12, 12, 14, 13, 15, 20, 253, 212, 0, 29, 31, 49, 43, 5, 5, 21, 15, 11, 1, 241, 251, 0, 24, 45, 39, 15, 16, 12, 17, 24, 21, 254, 0, 14, 31, 32, 27, 12, 12, 16, 21, 16, 16, 3, 27, 17, 29, 40, 22, 7, 14, 6, 253, 9, 254, 243, 244, 255, 4, 9, 12, 254, 247, 3, 2, 1, 1, 255, 246, 254, 254, 18, 17, 23, 15, 14, 8, 9, 1, 248, 248, 246, 240, 236, 191, 157, 211, 17, 55, 60, 62, 13, 37, 48, 58, 36, 24, 17, 13, 228, 21, 21, 236, 248, 18, 243, 14, 25, 7, 10, 250, 190, 211, 9, 37, 43, 43, 246, 192, 213, 229, 243, 231, 210, 185, 225, 0, 16, 26, 12, 2, 14, 37, 15, 7, 244, 242, 21, 35, 39, 38, 44, 48, 70, 72, 46, 23, 19, 19, 31, 39, 29, 13, 30, 46, 49, 54, 35, 13, 13, 10, 14, 4, 253, 241, 4, 22, 28, 23, 13, 3, 255, 13, 7, 243, 240, 238, 253, 7, 14, 1, 21, 12, 30, 34, 33, 20, 22, 22, 12, 29, 17, 12, 25, 29, 32, 34, 9, 20, 51, 46, 38, 44, 18, 3, 30, 32, 14, 12, 5, 254, 19, 21, 13, 8, 252, 236, 252, 2, 255, 3, 251, 252, 8, 5, 249, 243, 243, 253, 19, 6, 249, 252, 250, 251, 6, 4, 246, 249, 0, 10, 26, 21, 5, 5, 14, 10, 6, 21, 3, 4, 41, 35, 23, 32, 15, 5, 20, 32, 4, 2, 252, 236, 254, 8, 11, 241, 248, 247, 252, 10, 255, 240, 240, 2, 3, 2, 0, 241, 245, 5, 10, 14, 10, 252, 2, 6, 5, 8, 1, 237, 250, 10, 10, 13, 19, 13, 24, 36, 19, 3, 255, 0, 23, 38, 33, 11, 8, 16, 25, 24, 5, 239, 245, 247, 3, 10, 8, 8, 21, 36, 28, 12, 249, 242, 0, 21, 14, 252, 254, 247, 10, 37, 30, 2, 2, 27, 19, 12, 254, 233, 228, 244, 3, 8, 17, 11, 16, 35, 43, 44, 31, 17, 252, 243, 240, 246, 241, 1, 36, 38, 29, 29, 17, 5, 9, 9, 250, 239, 0, 13, 31, 33, 6, 251, 7, 18, 12, 23, 0, 244, 10, 5, 249, 246, 235, 233, 252, 9, 8, 0, 252, 3, 255, 248, 2, 8, 6, 8, 19, 26, 28, 28, 34, 26, 16, 12, 253, 253, 255, 242, 11, 42, 29, 28, 52, 22, 22, 52, 26, 245, 254, 233, 209, 248, 0, 234, 255, 8, 250, 19, 23, 253, 251, 1, 252, 5, 8, 237, 239, 249, 236, 244, 24, 247, 222, 255, 32, 48, 43, 40, 5, 253, 25, 14, 244, 237, 1, 30, 26, 28, 20, 254, 9, 15, 15, 12, 0, 5, 24, 12, 5, 4, 10, 4, 18, 25, 12, 25, 37, 15, 4, 10, 255, 236, 244, 253, 11, 20, 22, 18, 5, 10, 22, 16, 0, 229, 244, 12, 7, 4, 9, 249, 2, 26, 25, 11, 254, 254, 3, 5, 255, 241, 254, 2, 2, 29, 34, 24, 61, 55, 19, 10, 30, 33, 33, 37, 14, 4, 253, 6, 11, 2, 7, 250, 7, 3, 1, 20, 18, 15, 3, 7, 6, 9, 1, 250, 8, 245, 239, 202, 204, 235, 0, 8, 21, 254, 231, 7, 5, 252, 247, 244, 245, 5, 32, 36, 18, 4, 244, 18, 36, 26, 31, 53, 33, 37, 55, 24, 247, 5, 0, 247, 13, 0, 244, 9, 18, 22, 12, 252, 2, 11, 8, 244, 246, 240, 224, 242, 243, 234, 240, 253, 0, 248, 237, 248, 4, 11, 25, 35, 34, 24, 7, 12, 25, 5, 11, 11, 12, 48, 42, 41, 48, 45, 25, 24, 28, 12, 11, 22, 33, 11, 255, 242, 245, 2, 9, 16, 23, 24, 16, 8, 1, 244, 226, 211, 220, 229, 233, 235, 241, 0, 11, 34, 34, 27, 19, 25, 25, 10, 3, 248, 0, 12, 12, 8, 30, 41, 54, 53, 47, 47, 38, 27, 16, 5, 0, 0, 252, 9, 17, 10, 24, 35, 31, 47, 21, 245, 239, 241, 225, 213, 220, 223, 231, 253, 10, 10, 21, 4, 245, 5, 13, 246, 239, 233, 241, 15, 27, 28, 18, 22, 43, 36, 23, 16, 11, 5, 17, 34, 23, 13, 31, 24, 12, 15, 9, 26, 30, 19, 14, 2, 248, 246, 241, 234, 235, 232, 233, 226, 235, 13, 14, 3, 246, 250, 249, 241, 237, 234, 241, 0, 242, 253, 22, 24, 33, 44, 47, 37, 12, 4, 7, 7, 255, 5, 5, 241, 2, 26, 38, 26, 37, 56, 51, 31, 1, 230, 215, 220, 235, 241, 252, 10, 26, 29, 23, 22, 11, 5, 0, 250, 237, 228, 220, 236, 254, 6, 20, 21, 35, 35, 46, 34, 17, 20, 4, 255, 19, 10, 0, 10, 34, 45, 26, 33, 31, 26, 35, 27, 5, 0, 14, 15, 17, 20, 25, 22, 15, 18, 3, 250, 6, 19, 4, 247, 242, 0, 16, 12, 12, 11, 5, 6, 7, 244, 234, 253, 248, 2, 19, 15, 10, 19, 31, 17, 9, 23, 31, 21, 15, 2, 6, 255, 0, 17, 16, 15, 10, 17, 22, 31, 30, 17, 0, 241, 254, 5, 226, 220, 252, 20, 14, 25, 34, 37, 42, 28, 4, 255, 238, 231, 232, 226, 242, 5, 20, 38, 46, 33, 19, 20, 16, 253, 2, 19, 9, 1, 0, 4, 6, 11, 20, 23, 12, 0, 3, 1, 244, 235, 1, 6, 4, 1, 1, 10, 10, 2, 7, 11, 250, 0, 6, 255, 9, 9, 22, 22, 7, 13, 9, 5, 8, 16, 13, 0, 255, 9, 16, 8, 7, 30, 33, 12, 11, 17, 17, 27, 19, 4, 2, 0, 248, 0, 23, 18, 11, 12, 7, 10, 17, 24, 21, 0, 254, 8, 4, 254, 2, 1, 3, 21, 29, 26, 9, 14, 27, 20, 11, 4, 252, 244, 246, 250, 249, 245, 11, 34, 38, 32, 29, 38, 33, 13, 254, 254, 241, 246, 4, 7, 5, 20, 20, 21, 41, 41, 20, 27, 25, 250, 4, 5, 247, 249, 255, 253, 11, 22, 30, 37, 24, 6, 14, 10, 6, 4, 252, 253, 3, 247, 241, 251, 243, 235, 245, 250, 8, 23, 34, 44, 41, 37, 34, 11, 4, 13, 3, 9, 21, 21, 33, 38, 43, 46, 40, 45, 43, 30, 21, 25, 27, 30, 25, 13, 15, 0, 232, 240, 249, 241, 250, 10, 9, 252, 2, 0, 0, 2, 6, 247, 235, 234, 221, 223, 226, 239, 249, 243, 248, 5, 21, 30, 30, 34, 27, 5, 0, 4, 4, 3, 13, 25, 41, 48, 45, 53, 52, 49, 45, 37, 30, 24, 17, 11, 11, 8, 254, 247, 253, 3, 10, 255, 6, 21, 16, 8, 11, 3, 243, 246, 246, 235, 232, 241, 245, 8, 23, 24, 19, 15, 17, 18, 14, 13, 10, 5, 5, 3, 6, 15, 14, 20, 33, 37, 47, 50, 39, 27, 26, 22, 16, 6, 10, 9, 0, 9, 14, 4, 1, 2, 246, 249, 241, 229, 243, 3, 253, 252, 250, 239, 247, 255, 251, 248, 252, 1, 1, 8, 12, 8, 7, 18, 19, 15, 22, 22, 26, 31, 32, 32, 22, 14, 6, 3, 6, 3, 8, 15, 22, 30, 26, 19, 10, 6, 5, 253, 0, 0, 253, 253, 255, 254, 253, 2, 255, 0, 1, 2, 0, 254, 255, 251, 245, 243, 253, 4, 4, 9, 18, 19, 23, 24, 17, 4, 246, 250, 0, 1, 255, 3, 12, 12, 20, 26, 15, 11, 18, 18, 7, 253, 255, 2, 3, 7, 9, 2, 4, 10, 12, 14, 14, 12, 15, 16, 15, 18, 21, 20, 22, 23, 18, 17, 18, 21, 28, 34, 33, 35, 39, 35, 24, 25, 24, 6, 5, 255, 243, 237, 244, 249, 252, 255, 1, 9, 9, 8, 9, 2, 0, 249, 246, 252, 1, 4, 0, 255, 248, 250, 6, 5, 6, 7, 4, 6, 7, 2, 255, 251, 244, 249, 254, 255, 0, 4, 9, 9, 11, 9, 6, 7, 8, 5, 2, 0, 247, 234, 233, 226, 222, 226, 235, 241, 252, 2, 9, 14, 12, 11, 7, 10, 8, 7, 11, 14, 22, 25, 29, 26, 33, 44, 43, 48, 47, 48, 43, 37, 32, 24, 22, 23, 27, 23, 21, 24, 29, 38, 44, 47, 43, 39, 36, 31, 28, 24, 16, 12, 9, 9, 7, 10, 13, 20, 20, 12, 7, 8, 11, 15, 19, 16, 15, 13, 16, 17, 10, 9, 8, 12, 8, 11, 8, 0, 0, 195, 5, 51, 0, 0, 1, 1, 1, 1, 1, 1, 2, 1, 1, 0, 0, 255, 0, 4, 5, 4, 2, 0, 0, 1, 2, 2, 3, 2, 3, 1, 248, 197, 214, 0, 44, 49, 16, 239, 219, 243, 0, 17, 24, 22, 18, 0, 247, 239, 0, 13, 24, 19, 12, 2, 0, 254, 2, 12, 13, 18, 11, 1, 1, 2, 8, 9, 8, 6, 5, 1, 2, 0, 0, 3, 6, 5, 3, 0, 0, 2, 1, 6, 2, 3, 0, 1, 3, 2, 3, 3, 3, 3, 3, 1, 5, 6, 3, 6, 4, 5, 2, 4, 3, 6, 4, 6, 4, 3, 2, 5, 6, 6, 4, 1, 3, 5, 6, 7, 4, 2, 3, 3, 4, 2, 2, 4, 5, 4, 3, 3, 1, 1, 2, 3, 5, 3, 1, 2, 2, 4, 6, 1, 254, 3, 0, 4, 5, 1, 1, 1, 255, 1, 2, 0, 0, 0, 5, 3, 3, 255, 253, 255, 4, 4, 1, 5, 0, 2, 2, 1, 0, 1, 2, 1, 7, 0, 0, 253, 253, 3, 9, 1, 255, 252, 251, 3, 6, 4, 2, 0, 251, 255, 4, 5, 5, 4, 1, 252, 254, 3, 4, 5, 3, 254, 0, 4, 254, 3, 3, 2, 4, 3, 0, 255, 2, 232, 237, 10, 18, 24, 11, 247, 239, 243, 254, 9, 17, 17, 5, 247, 247, 248, 255, 5, 6, 8, 4, 0, 251, 247, 1, 2, 6, 7, 1, 252, 1, 0, 0, 3, 4, 5, 4, 0, 251, 254, 7, 4, 13, 6, 254, 251, 1, 236, 255, 22, 18, 13, 1, 246, 249, 0, 2, 10, 9, 3, 1, 249, 255, 5, 11, 2, 0, 0, 255, 7, 254, 3, 0, 3, 5, 2, 9, 7, 9, 7, 6, 2, 3, 6, 3, 6, 0, 255, 1, 9, 3, 4, 4, 0, 5, 7, 2, 6, 3, 253, 3, 2, 9, 13, 4, 3, 2, 239, 195, 232, 27, 54, 38, 252, 217, 222, 251, 1, 9, 10, 14, 5, 243, 237, 242, 8, 27, 25, 12, 0, 250, 3, 6, 7, 15, 13, 12, 3, 0, 8, 17, 26, 26, 21, 20, 20, 17, 15, 14, 11, 43, 51, 24, 3, 219, 217, 237, 247, 255, 233, 182, 196, 224, 251, 26, 250, 222, 223, 221, 238, 255, 250, 254, 2, 245, 248, 244, 254, 18, 25, 24, 29, 24, 24, 35, 57, 62, 90, 38, 159, 185, 224, 57, 126, 67, 0, 201, 181, 221, 252, 13, 52, 50, 12, 220, 194, 209, 237, 19, 37, 31, 250, 220, 211, 222, 1, 20, 27, 11, 238, 226, 247, 12, 17, 18, 9, 16, 7, 252, 4, 9, 7, 24, 28, 18, 7, 244, 5, 17, 14, 22, 22, 10, 255, 3, 11, 22, 11, 6, 4, 3, 6, 15, 12, 0, 248, 250, 14, 6, 0, 255, 252, 7, 4, 1, 252, 246, 254, 4, 4, 1, 254, 1, 0, 4, 11, 10, 255, 255, 1, 5, 0, 254, 255, 4, 8, 9, 2, 1, 248, 247, 12, 12, 7, 254, 251, 6, 1, 254, 3, 0, 3, 6, 254, 250, 6, 255, 251, 249, 247, 255, 12, 10, 247, 243, 248, 0, 255, 254, 1, 247, 249, 253, 0, 8, 9, 252, 247, 5, 2, 252, 255, 1, 6, 0, 253, 252, 1, 14, 5, 248, 248, 0, 11, 10, 1, 5, 9, 253, 242, 248, 2, 16, 20, 5, 246, 243, 252, 0, 14, 11, 13, 17, 2, 240, 241, 5, 21, 27, 8, 248, 243, 251, 12, 5, 1, 2, 13, 3, 239, 243, 0, 9, 12, 15, 12, 250, 247, 4, 16, 15, 10, 2, 10, 17, 2, 252, 247, 12, 30, 18, 254, 249, 0, 5, 17, 16, 4, 0, 7, 7, 4, 3, 1, 253, 254, 7, 7, 250, 255, 248, 247, 12, 11, 3, 253, 242, 1, 12, 16, 9, 2, 246, 245, 0, 0, 5, 13, 2, 0, 254, 251, 3, 16, 2, 253, 13, 6, 0, 0, 255, 13, 11, 242, 244, 2, 19, 20, 7, 248, 248, 0, 9, 9, 4, 252, 250, 255, 1, 4, 0, 255, 4, 253, 252, 0, 253, 4, 13, 4, 2, 250, 249, 4, 0, 1, 12, 6, 3, 250, 249, 252, 11, 14, 2, 2, 2, 0, 253, 255, 255, 19, 22, 249, 243, 0, 0, 17, 20, 255, 241, 246, 8, 13, 250, 0, 7, 0, 251, 250, 254, 4, 6, 9, 0, 249, 238, 251, 14, 20, 11, 0, 245, 245, 1, 16, 8, 9, 9, 255, 247, 4, 10, 10, 20, 6, 250, 3, 4, 13, 18, 7, 252, 248, 13, 22, 12, 254, 250, 250, 0, 12, 15, 11, 2, 254, 0, 5, 9, 6, 1, 4, 254, 255, 251, 247, 5, 15, 11, 10, 1, 245, 255, 14, 14, 4, 12, 18, 254, 254, 7, 9, 17, 10, 252, 240, 0, 17, 13, 2, 243, 246, 21, 21, 1, 0, 250, 255, 7, 9, 4, 6, 7, 255, 254, 253, 9, 8, 252, 255, 4, 14, 11, 252, 244, 0, 15, 13, 5, 3, 247, 245, 255, 21, 13, 254, 251, 245, 255, 0, 249, 254, 12, 7, 248, 255, 251, 0, 15, 22, 5, 235, 247, 6, 14, 22, 7, 0, 251, 249, 5, 8, 2, 4, 4, 8, 4, 247, 255, 5, 4, 7, 8, 3, 0, 247, 238, 1, 19, 14, 3, 251, 253, 251, 249, 2, 16, 26, 10, 251, 242, 247, 15, 20, 11, 0, 2, 1, 245, 0, 6, 20, 14, 249, 236, 243, 5, 24, 25, 4, 249, 244, 254, 0, 0, 10, 16, 5, 2, 0, 254, 4, 13, 253, 3, 10, 5, 5, 12, 7, 3, 3, 0, 2, 252, 2, 15, 8, 253, 5, 0, 0, 3, 255, 9, 11, 252, 0, 4, 8, 6, 253, 248, 246, 2, 11, 6, 253, 241, 228, 226, 2, 22, 34, 25, 239, 204, 220, 7, 15, 251, 232, 239, 248, 4, 249, 232, 238, 15, 24, 9, 10, 249, 242, 4, 7, 16, 18, 18, 255, 237, 4, 25, 13, 11, 5, 251, 5, 2, 1, 11, 11, 8, 9, 4, 0, 247, 249, 9, 12, 5, 0, 1, 0, 245, 252, 14, 12, 253, 252, 248, 253, 6, 0, 249, 250, 255, 6, 13, 0, 255, 1, 255, 3, 6, 11, 8, 2, 8, 3, 8, 7, 252, 255, 5, 12, 16, 14, 2, 255, 253, 4, 0, 1, 8, 3, 10, 10, 2, 250, 246, 0, 9, 12, 10, 1, 253, 16, 7, 245, 251, 7, 19, 15, 2, 254, 2, 5, 8, 0, 0, 10, 12, 254, 249, 6, 18, 15, 7, 252, 246, 1, 9, 6, 12, 5, 249, 1, 6, 253, 5, 14, 7, 248, 242, 0, 15, 17, 6, 245, 246, 0, 2, 6, 4, 254, 253, 1, 5, 252, 241, 251, 12, 7, 3, 0, 242, 0, 0, 246, 255, 8, 9, 0, 244, 244, 2, 6, 14, 9, 252, 249, 4, 7, 5, 0, 255, 4, 6, 10, 4, 254, 0, 0, 5, 3, 0, 254, 253, 8, 13, 8, 253, 243, 246, 6, 8, 255, 0, 4, 3, 250, 246, 251, 6, 14, 1, 250, 252, 251, 0, 0, 251, 255, 9, 7, 2, 245, 241, 0, 11, 13, 10, 0, 251, 249, 247, 11, 20, 7, 252, 2, 9, 1, 5, 255, 1, 19, 13, 255, 255, 253, 3, 18, 4, 252, 4, 7, 12, 6, 5, 7, 9, 12, 3, 253, 0, 3, 4, 15, 15, 7, 248, 244, 0, 15, 20, 14, 4, 1, 0, 5, 3, 3, 17, 18, 6, 0, 2, 6, 16, 8, 1, 1, 4, 7, 3, 1, 7, 14, 8, 251, 244, 249, 4, 13, 6, 1, 2, 253, 248, 2, 12, 8, 2, 252, 0, 252, 252, 5, 10, 2, 0, 254, 253, 253, 3, 13, 9, 4, 254, 2, 7, 3, 255, 252, 1, 15, 17, 6, 252, 243, 253, 9, 9, 8, 1, 253, 252, 3, 3, 255, 254, 249, 254, 254, 252, 254, 0, 247, 252, 0, 253, 253, 250, 246, 248, 1, 6, 6, 253, 242, 240, 252, 6, 4, 1, 252, 252, 254, 250, 250, 0, 1, 255, 0, 2, 0, 247, 251, 5, 1, 255, 2, 4, 0, 252, 255, 4, 7, 14, 7, 254, 2, 9, 10, 9, 3, 3, 13, 16, 10, 5, 5, 7, 11, 14, 11, 10, 14, 13, 8, 3, 7, 17, 26, 20, 12, 10, 13, 14, 16, 18, 22, 28, 27, 19, 16, 8, 7, 20, 32, 33, 29, 26, 12, 2, 8, 21, 29, 32, 26, 20, 13, 9, 13, 13, 20, 31, 24, 15, 11, 10, 21, 19, 14, 12, 14, 16, 12, 3, 8, 16, 17, 15, 14, 2, 7, 8, 0, 10, 14, 20, 16, 6, 3, 5, 7, 10, 14, 14, 11, 13, 5, 0, 252, 253, 7, 7, 249, 230, 237, 0, 43, 6, 37, 0, 6, 8, 5, 6, 3, 1, 5, 8, 10, 13, 15, 19, 11, 6, 4, 1, 0, 5, 2, 6, 11, 13, 9, 8, 9, 9, 8, 7, 8, 12, 6, 4, 5, 3, 6, 12, 11, 11, 7, 0, 255, 2, 5, 5, 4, 11, 10, 11, 10, 5, 6, 0, 253, 254, 0, 251, 240, 0, 8, 15, 19, 24, 34, 54, 47, 60, 40, 205, 217, 208, 178, 228, 243, 228, 1, 11, 17, 23, 23, 15, 22, 10, 254, 235, 229, 232, 245, 255, 9, 16, 32, 37, 34, 24, 14, 254, 244, 241, 249, 248, 1, 10, 19, 29, 35, 28, 27, 17, 9, 2, 254, 247, 248, 252, 247, 255, 13, 16, 23, 20, 11, 1, 243, 239, 236, 238, 249, 244, 254, 250, 251, 0, 5, 9, 15, 15, 9, 254, 248, 248, 243, 2, 21, 13, 22, 33, 21, 23, 26, 1, 11, 25, 29, 37, 15, 12, 11, 24, 19, 19, 12, 3, 13, 19, 19, 12, 8, 241, 224, 12, 33, 1, 5, 244, 245, 32, 12, 253, 253, 250, 0, 17, 16, 252, 255, 4, 20, 22, 18, 22, 27, 28, 24, 16, 0, 4, 21, 17, 10, 8, 9, 252, 1, 16, 10, 9, 6, 12, 6, 254, 1, 22, 9, 6, 0, 250, 4, 3, 240, 233, 238, 252, 17, 250, 253, 16, 38, 23, 18, 7, 6, 248, 234, 224, 214, 231, 222, 241, 240, 219, 239, 243, 15, 28, 6, 3, 0, 5, 12, 7, 10, 23, 25, 32, 28, 25, 21, 30, 23, 21, 23, 8, 12, 23, 24, 23, 22, 22, 16, 16, 16, 7, 4, 4, 253, 255, 0, 254, 249, 251, 248, 0, 1, 3, 245, 244, 247, 0, 5, 8, 9, 8, 12, 7, 2, 10, 17, 16, 12, 12, 17, 22, 24, 19, 22, 26, 14, 12, 13, 12, 7, 6, 8, 11, 11, 16, 15, 20, 24, 5, 5, 0, 4, 7, 5, 9, 7, 6, 8, 9, 253, 255, 0, 0, 246, 251, 249, 3, 11, 18, 13, 11, 10, 0, 252, 5, 252, 244, 247, 0, 11, 14, 17, 27, 29, 29, 22, 9, 8, 6, 11, 254, 3, 252, 4, 23, 14, 8, 9, 5, 0, 253, 249, 241, 248, 5, 4, 9, 9, 15, 19, 20, 12, 3, 251, 250, 250, 253, 246, 247, 0, 6, 7, 14, 19, 15, 14, 9, 0, 7, 19, 4, 251, 2, 8, 10, 8, 13, 11, 4, 18, 19, 9, 12, 14, 4, 8, 14, 5, 2, 12, 14, 9, 12, 4, 4, 0, 4, 0, 251, 5, 254, 251, 1, 2, 5, 3, 4, 18, 19, 9, 6, 9, 0, 0, 0, 252, 246, 4, 11, 1, 6, 22, 16, 17, 10, 254, 1, 8, 7, 254, 1, 29, 19, 10, 11, 18, 11, 2, 250, 232, 245, 11, 0, 241, 247, 15, 18, 18, 22, 12, 16, 25, 16, 247, 4, 9, 248, 245, 254, 12, 18, 13, 255, 4, 13, 28, 8, 251, 0, 6, 2, 0, 5, 14, 18, 13, 251, 255, 4, 251, 244, 234, 245, 10, 7, 6, 7, 10, 28, 26, 9, 253, 0, 11, 12, 254, 240, 3, 15, 14, 26, 18, 13, 20, 13, 255, 6, 17, 1, 242, 247, 0, 13, 14, 15, 3, 8, 25, 7, 4, 6, 0, 255, 1, 8, 10, 14, 9, 9, 15, 8, 8, 0, 250, 0, 3, 250, 5, 17, 19, 19, 16, 17, 15, 21, 15, 7, 7, 9, 12, 0, 254, 0, 4, 11, 7, 0, 253, 0, 7, 6, 11, 10, 16, 13, 7, 11, 6, 6, 3, 1, 3, 9, 5, 2, 14, 15, 0, 1, 17, 28, 25, 11, 253, 3, 11, 7, 254, 251, 247, 8, 15, 6, 10, 28, 29, 25, 21, 10, 254, 0, 1, 246, 238, 255, 13, 15, 22, 27, 27, 28, 24, 10, 7, 6, 253, 251, 251, 244, 250, 6, 15, 13, 18, 23, 18, 11, 253, 252, 254, 251, 4, 18, 13, 14, 26, 24, 22, 19, 10, 7, 2, 6, 4, 238, 241, 12, 21, 7, 9, 17, 25, 25, 25, 14, 255, 17, 18, 6, 9, 1, 248, 252, 11, 2, 12, 11, 249, 11, 37, 30, 14, 5, 7, 3, 253, 22, 11, 9, 21, 2, 3, 25, 27, 7, 2, 11, 13, 18, 252, 0, 3, 5, 14, 235, 225, 242, 248, 255, 237, 236, 16, 31, 29, 7, 13, 10, 245, 234, 252, 245, 234, 228, 231, 249, 11, 4, 250, 1, 8, 253, 232, 240, 248, 235, 232, 249, 254, 245, 238, 235, 246, 249, 250, 252, 250, 255, 6, 252, 245, 244, 235, 235, 232, 238, 245, 235, 241, 0, 2, 253, 249, 0, 6, 252, 254, 0, 0, 253, 7, 14, 18, 24, 28, 25, 20, 11, 20, 33, 36, 44, 44, 49, 54, 38, 39, 38, 15, 9, 253, 228, 228, 198, 147, 154, 225, 50, 68, 40, 8, 10, 1, 220, 187, 212, 9, 38, 42, 10, 245, 8, 0, 189, 159, 210, 14, 49, 54, 55, 66, 49, 7, 243, 249, 25, 53, 66, 54, 40, 43, 30, 8, 255, 11, 31, 35, 44, 40, 24, 23, 16, 255, 255, 2, 255, 2, 15, 21, 30, 39, 19, 249, 244, 253, 21, 37, 42, 42, 20, 13, 14, 19, 30, 29, 21, 253, 192, 133, 158, 218, 19, 51, 72, 59, 20, 254, 227, 218, 236, 252, 19, 29, 15, 249, 233, 235, 249, 254, 15, 33, 27, 13, 243, 251, 4, 255, 250, 247, 255, 11, 2, 251, 3, 15, 22, 15, 11, 13, 12, 11, 14, 12, 8, 250, 1, 14, 9, 251, 242, 242, 246, 2, 255, 1, 10, 10, 4, 248, 251, 3, 255, 242, 246, 252, 243, 239, 243, 9, 6, 243, 224, 222, 0, 27, 37, 48, 58, 49, 32, 16, 16, 36, 59, 88, 92, 255, 196, 227, 248, 247, 5, 45, 64, 43, 255, 226, 226, 243, 230, 238, 6, 33, 32, 12, 0, 231, 237, 253, 1, 19, 31, 30, 25, 12, 6, 8, 245, 240, 25, 54, 55, 36, 32, 32, 21, 13, 28, 47, 34, 19, 29, 31, 23, 25, 23, 251, 236, 9, 43, 12, 233, 254, 25, 9, 237, 236, 0, 14, 0, 251, 255, 246, 243, 0, 242, 250, 13, 17, 6, 233, 241, 28, 15, 240, 242, 9, 30, 18, 255, 12, 33, 16, 243, 242, 7, 40, 40, 253, 240, 19, 27, 237, 227, 23, 48, 25, 251, 246, 0, 0, 0, 12, 12, 6, 248, 245, 243, 237, 8, 31, 15, 244, 246, 12, 12, 242, 0, 31, 2, 0, 4, 245, 254, 5, 13, 9, 4, 7, 13, 2, 251, 3, 20, 21, 5, 245, 0, 17, 15, 10, 0, 253, 254, 6, 10, 246, 245, 23, 21, 253, 247, 18, 23, 250, 249, 7, 6, 11, 12, 5, 4, 14, 21, 9, 246, 0, 31, 20, 255, 0, 13, 13, 7, 9, 13, 17, 22, 4, 244, 2, 14, 18, 6, 252, 21, 24, 0, 248, 247, 17, 33, 14, 4, 12, 3, 253, 252, 14, 30, 13, 252, 11, 15, 247, 5, 23, 17, 9, 4, 245, 239, 246, 10, 19, 0, 251, 15, 4, 237, 2, 22, 236, 217, 253, 12, 5, 5, 22, 23, 253, 239, 247, 250, 253, 11, 34, 32, 0, 250, 7, 7, 7, 11, 28, 30, 3, 243, 249, 16, 19, 16, 11, 6, 4, 2, 251, 255, 16, 10, 250, 252, 7, 6, 255, 2, 9, 2, 245, 243, 11, 16, 255, 250, 17, 13, 254, 1, 1, 255, 10, 12, 7, 6, 15, 11, 252, 249, 14, 19, 10, 9, 7, 7, 8, 0, 5, 16, 15, 4, 3, 13, 13, 254, 250, 14, 13, 11, 24, 8, 0, 12, 16, 15, 6, 0, 11, 20, 9, 13, 13, 3, 12, 17, 7, 14, 26, 13, 248, 248, 12, 21, 11, 0, 2, 18, 21, 16, 17, 16, 11, 7, 17, 27, 11, 0, 6, 12, 21, 24, 14, 11, 12, 10, 13, 17, 13, 14, 0, 246, 5, 15, 16, 2, 249, 13, 23, 9, 255, 10, 16, 8, 4, 7, 5, 251, 0, 11, 8, 1, 2, 255, 0, 9, 9, 1, 254, 5, 11, 8, 4, 8, 16, 15, 17, 9, 2, 9, 15, 12, 8, 12, 12, 3, 0, 12, 18, 10, 1, 10, 9, 0, 250, 251, 9, 20, 7, 0, 251, 255, 8, 13, 12, 254, 245, 251, 4, 4, 3, 5, 1, 251, 252, 0, 255, 4, 12, 13, 12, 2, 254, 11, 17, 9, 13, 10, 0, 1, 0, 7, 12, 6, 11, 24, 11, 255, 0, 12, 7, 253, 252, 7, 14, 7, 254, 254, 4, 13, 10, 7, 17, 17, 8, 8, 10, 16, 17, 8, 11, 11, 6, 13, 8, 9, 22, 24, 15, 6, 1, 8, 9, 4, 12, 14, 9, 6, 4, 8, 12, 14, 9, 1, 1, 9, 10, 3, 0, 10, 13, 10, 3, 251, 247, 3, 14, 10, 251, 246, 1, 12, 8, 2, 254, 244, 244, 3, 12, 7, 253, 248, 255, 6, 6, 7, 8, 4, 4, 15, 13, 2, 246, 251, 15, 24, 7, 243, 246, 2, 11, 7, 0, 2, 0, 251, 244, 247, 255, 5, 255, 246, 246, 255, 253, 245, 251, 0, 252, 240, 238, 252, 7, 0, 242, 240, 245, 249, 251, 247, 251, 255, 248, 250, 5, 1, 248, 249, 255, 2, 253, 241, 239, 254, 13, 8, 249, 244, 251, 6, 6, 0, 208, 4, 44, 0, 3, 1, 2, 1, 2, 1, 3, 2, 4, 236, 191, 217, 11, 26, 24, 27, 26, 24, 11, 246, 236, 247, 6, 12, 15, 16, 19, 15, 5, 252, 250, 252, 5, 17, 24, 23, 17, 16, 16, 1, 249, 251, 12, 14, 15, 0, 202, 203, 239, 22, 13, 13, 15, 21, 16, 248, 226, 229, 3, 15, 11, 9, 15, 11, 2, 254, 249, 249, 253, 15, 16, 26, 20, 15, 2, 254, 2, 4, 5, 10, 34, 36, 37, 14, 8, 211, 132, 222, 36, 36, 38, 37, 30, 19, 239, 208, 198, 241, 19, 26, 39, 40, 26, 254, 243, 230, 226, 242, 8, 39, 45, 33, 16, 6, 214, 182, 225, 0, 12, 27, 28, 33, 25, 1, 230, 220, 239, 3, 13, 25, 31, 29, 11, 254, 242, 234, 236, 248, 18, 33, 25, 21, 2, 247, 249, 242, 246, 6, 22, 32, 27, 10, 251, 241, 241, 244, 248, 17, 23, 24, 24, 9, 245, 241, 247, 244, 6, 12, 17, 24, 12, 6, 251, 242, 245, 248, 5, 16, 17, 16, 12, 2, 251, 252, 2, 1, 6, 2, 15, 19, 4, 252, 254, 245, 5, 15, 19, 15, 9, 8, 7, 254, 252, 9, 7, 16, 10, 6, 10, 15, 10, 0, 7, 217, 176, 205, 199, 227, 27, 48, 38, 36, 244, 223, 206, 214, 234, 9, 39, 54, 49, 12, 0, 244, 245, 0, 18, 31, 35, 56, 54, 29, 248, 2, 21, 248, 235, 11, 249, 217, 8, 32, 4, 232, 232, 242, 243, 10, 16, 16, 21, 46, 246, 180, 209, 244, 2, 11, 24, 5, 253, 232, 240, 251, 10, 33, 34, 28, 8, 247, 230, 231, 230, 233, 252, 7, 30, 18, 7, 241, 238, 250, 251, 254, 15, 32, 33, 17, 6, 7, 251, 0, 16, 12, 241, 242, 251, 10, 17, 20, 23, 13, 3, 12, 9, 243, 255, 19, 22, 18, 15, 255, 2, 10, 2, 16, 15, 15, 17, 19, 11, 11, 20, 15, 8, 17, 24, 12, 0, 4, 248, 254, 252, 251, 0, 0, 2, 1, 253, 4, 254, 245, 253, 14, 12, 6, 10, 6, 3, 0, 251, 253, 2, 21, 30, 9, 8, 0, 0, 2, 9, 4, 0, 8, 7, 19, 11, 8, 10, 10, 6, 251, 6, 20, 21, 18, 19, 3, 3, 255, 245, 248, 1, 7, 6, 0, 5, 12, 3, 8, 8, 246, 248, 14, 21, 16, 5, 4, 3, 0, 255, 1, 0, 12, 18, 8, 254, 250, 237, 245, 15, 13, 254, 246, 254, 15, 1, 230, 229, 246, 6, 0, 246, 250, 253, 238, 225, 234, 10, 11, 8, 15, 17, 12, 0, 231, 237, 10, 32, 45, 25, 242, 235, 11, 32, 28, 4, 7, 19, 29, 25, 255, 237, 9, 22, 6, 250, 6, 21, 3, 241, 245, 2, 252, 244, 247, 243, 0, 5, 1, 2, 254, 243, 248, 254, 254, 16, 11, 2, 8, 14, 10, 250, 229, 255, 20, 12, 7, 9, 21, 18, 249, 250, 10, 13, 14, 6, 255, 4, 15, 3, 243, 251, 4, 0, 252, 225, 226, 244, 4, 17, 11, 6, 9, 4, 243, 217, 229, 8, 28, 32, 26, 15, 1, 248, 239, 246, 255, 8, 19, 19, 14, 254, 250, 247, 253, 21, 38, 29, 254, 254, 249, 234, 236, 255, 12, 14, 6, 250, 246, 242, 236, 248, 14, 15, 2, 7, 249, 235, 243, 8, 5, 4, 2, 254, 7, 28, 14, 5, 26, 33, 18, 251, 246, 240, 249, 11, 24, 21, 14, 8, 249, 235, 242, 248, 1, 8, 4, 16, 17, 255, 239, 221, 240, 1, 1, 8, 24, 18, 255, 234, 228, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 208, 4, 44, 0, 3, 1, 2, 1, 2, 1, 3, 2, 4, 236, 191, 217, 11, 26, 24, 27, 26, 24, 11, 246, 236, 247, 6, 12, 15, 16, 19, 15, 5, 252, 250, 252, 5, 17, 24, 23, 17, 16, 16, 1, 249, 251, 12, 14, 15, 0, 202, 203, 239, 22, 13, 13, 15, 21, 16, 248, 226, 229, 3, 15, 11, 9, 15, 11, 2, 254, 249, 249, 253, 15, 16, 26, 20, 15, 2, 254, 2, 4, 5, 10, 34, 36, 37, 14, 8, 211, 132, 222, 36, 36, 38, 37, 30, 19, 239, 208, 198, 241, 19, 26, 39, 40, 26, 254, 243, 230, 226, 242, 8, 39, 45, 33, 16, 6, 214, 182, 225, 0, 12, 27, 28, 33, 25, 1, 230, 220, 239, 3, 13, 25, 31, 29, 11, 254, 242, 234, 236, 248, 18, 33, 25, 21, 2, 247, 249, 242, 246, 6, 22, 32, 27, 10, 251, 241, 241, 244, 248, 17, 23, 24, 24, 9, 245, 241, 247, 244, 6, 12, 17, 24, 12, 6, 251, 242, 245, 248, 5, 16, 17, 16, 12, 2, 251, 252, 2, 1, 6, 2, 15, 19, 4, 252, 254, 245, 5, 15, 19, 15, 9, 8, 7, 254, 252, 9, 7, 16, 10, 6, 10, 15, 10, 0, 7, 217, 176, 205, 199, 227, 27, 48, 38, 36, 244, 223, 206, 214, 234, 9, 39, 54, 49, 12, 0, 244, 245, 0, 18, 31, 35, 56, 54, 29, 248, 2, 21, 248, 235, 11, 249, 217, 8, 32, 4, 232, 232, 242, 243, 10, 16, 16, 21, 46, 246, 180, 209, 244, 2, 11, 24, 5, 253, 232, 240, 251, 10, 33, 34, 28, 8, 247, 230, 231, 230, 233, 252, 7, 30, 18, 7, 241, 238, 250, 251, 254, 15, 32, 33, 17, 6, 7, 251, 0, 16, 12, 241, 242, 251, 10, 17, 20, 23, 13, 3, 12, 9, 243, 255, 19, 22, 18, 15, 255, 2, 10, 2, 16, 15, 15, 17, 19, 11, 11, 20, 15, 8, 17, 24, 12, 0, 4, 248, 254, 252, 251, 0, 0, 2, 1, 253, 4, 254, 245, 253, 14, 12, 6, 10, 6, 3, 0, 251, 253, 2, 21, 30, 9, 8, 0, 0, 2, 9, 4, 0, 8, 7, 19, 11, 8, 10, 10, 6, 251, 6, 20, 21, 18, 19, 3, 3, 255, 245, 248, 1, 7, 6, 0, 5, 12, 3, 8, 8, 246, 248, 14, 21, 16, 5, 4, 3, 0, 255, 1, 0, 12, 18, 8, 254, 250, 237, 245, 15, 13, 254, 246, 254, 15, 1, 230, 229, 246, 6, 0, 246, 250, 253, 238, 225, 234, 10, 11, 8, 15, 17, 12, 0, 231, 237, 10, 32, 45, 25, 242, 235, 11, 32, 28, 4, 7, 19, 29, 25, 255, 237, 9, 22, 6, 250, 6, 21, 3, 241, 245, 2, 252, 244, 247, 243, 0, 5, 1, 2, 254, 243, 248, 254, 254, 16, 11, 2, 8, 14, 10, 250, 229, 255, 20, 12, 7, 9, 21, 18, 249, 250, 10, 13, 14, 6, 255, 4, 15, 3, 243, 251, 4, 0, 252, 225, 226, 244, 4, 17, 11, 6, 9, 4, 243, 217, 229, 8, 28, 32, 26, 15, 1, 248, 239, 246, 255, 8, 19, 19, 14, 254, 250, 247, 253, 21, 38, 29, 254, 254, 249, 234, 236, 255, 12, 14, 6, 250, 246, 242, 236, 248, 14, 15, 2, 7, 249, 235, 243, 8, 5, 4, 2, 254, 7, 28, 14, 5, 26, 33, 18, 251, 246, 240, 249, 11, 24, 21, 14, 8, 249, 235, 242, 248, 1, 8, 4, 16, 17, 255, 239, 221, 240, 1, 1, 8, 24, 18, 255, 234, 228, 241, 7, 30, 33, 18, 1, 239, 240, 4, 30, 18, 244, 245, 4, 4, 15, 11, 252, 15, 34, 20, 244, 253, 12, 27, 32, 27, 245, 246, 19, 20, 8, 247, 239, 238, 1, 20, 21, 10, 251, 251, 255, 3, 0, 249, 254, 254, 7, 9, 18, 4, 251, 247, 245, 4, 19, 5, 239, 2, 31, 39, 14, 240, 238, 254, 250, 0, 31, 34, 25, 7, 255, 254, 238, 237, 252, 31, 54, 42, 26, 247, 251, 246, 239, 245, 32, 60, 51, 12, 241, 232, 233, 239, 244, 23, 32, 19, 3, 246, 238, 229, 233, 245, 2, 16, 13, 245, 244, 7, 0, 239, 244, 254, 13, 13, 253, 0, 18, 13, 1, 249, 6, 28, 6, 0, 18, 31, 19, 7, 9, 7, 243, 244, 11, 32, 53, 24, 0, 3, 4, 244, 243, 9, 22, 2, 246, 10, 4, 243, 246, 245, 234, 238, 238, 255, 255, 2, 255, 9, 12, 6, 241, 235, 255, 27, 34, 21, 9, 23, 38, 13, 1, 6, 9, 14, 19, 22, 6, 255, 10, 7, 3, 3, 1, 2, 250, 1, 17, 9, 254, 248, 250, 251, 248, 252, 2, 1, 240, 244, 242, 255, 1, 6, 4, 254, 255, 244, 239, 239, 0, 26, 27, 252, 255, 23, 25, 8, 0, 1, 11, 27, 31, 21, 2, 7, 21, 1, 2, 6, 252, 7, 19, 7, 240, 243, 0, 250, 240, 243, 0, 1, 242, 234, 249, 5, 255, 247, 254, 254, 7, 15, 250, 221, 237, 13, 18, 1, 253, 4, 10, 15, 15, 17, 11, 9, 249, 1, 16, 34, 32, 26, 12, 250, 244, 1, 8, 17, 14, 0, 253, 2, 252, 246, 255, 1, 246, 241, 237, 232, 247, 7, 14, 4, 245, 241, 243, 243, 244, 251, 2, 10, 5, 251, 242, 252, 14, 7, 4, 0, 10, 25, 5, 251, 4, 12, 27, 24, 3, 255, 0, 248, 252, 7, 14, 253, 250, 255, 249, 251, 254, 249, 253, 255, 242, 250, 8, 16, 2, 238, 243, 0, 14, 19, 3, 251, 5, 15, 10, 253, 252, 6, 16, 27, 23, 3, 252, 15, 27, 6, 249, 5, 24, 24, 24, 19, 11, 7, 10, 10, 4, 4, 5, 4, 7, 12, 15, 13, 0, 0, 9, 12, 8, 4, 253, 250, 12, 11, 4, 2, 252, 4, 15, 16, 0, 245, 0, 5, 2, 255, 11, 10, 2, 13, 4, 244, 1, 17, 23, 15, 17, 12, 239, 240, 14, 25, 16, 15, 6, 245, 241, 4, 14, 254, 3, 26, 19, 2, 247, 247, 0, 247, 250, 6, 8, 249, 235, 253, 7, 1, 0, 248, 240, 248, 8, 14, 5, 3, 7, 2, 247, 249, 0, 10, 19, 19, 24, 18, 254, 245, 248, 255, 17, 30, 23, 10, 13, 7, 245, 254, 8, 3, 0, 14, 22, 15, 9, 255, 248, 255, 7, 0, 248, 253, 252, 7, 13, 254, 241, 245, 249, 248, 241, 12, 28, 15, 253, 0, 253, 238, 241, 1, 14, 6, 5, 14, 17, 10, 3, 0, 0, 246, 250, 250, 249, 10, 33, 38, 16, 246, 228, 228, 235, 255, 11, 26, 35, 252, 210, 233, 9, 5, 4, 6, 250, 232, 249, 11, 19, 20, 14, 249, 240, 237, 248, 254, 1, 13, 28, 50, 51, 18, 233, 229, 252, 11, 21, 36, 45, 33, 23, 30, 21, 3, 255, 8, 15, 38, 40, 22, 8, 10, 10, 2, 248, 0, 23, 50, 43, 6, 245, 0, 11, 6, 11, 36, 41, 21, 22, 9, 240, 0, 13, 17, 35, 44, 27, 245, 227, 248, 5, 19, 40, 32, 8, 252, 241, 229, 230, 249, 19, 23, 9, 251, 239, 240, 234, 234, 241, 232, 233, 102, 1, 41, 0, 0, 2, 5, 5, 3, 1, 6, 6, 3, 1, 6, 10, 4, 246, 229, 206, 184, 183, 209, 247, 22, 31, 26, 21, 37, 59, 61, 48, 21, 248, 216, 176, 160, 168, 181, 192, 222, 6, 44, 63, 76, 80, 81, 84, 79, 65, 40, 250, 140, 132, 192, 248, 218, 166, 183, 1, 35, 21, 53, 61, 25, 2, 11, 7, 210, 168, 169, 202, 210, 208, 208, 206, 244, 22, 54, 62, 50, 37, 38, 47, 33, 4, 241, 227, 226, 234, 233, 232, 229, 233, 253, 14, 25, 19, 19, 23, 13, 0, 3, 236, 237, 230, 239, 239, 238, 233, 242, 14, 16, 28, 24, 31, 34, 36, 27, 16, 2, 252, 247, 248, 254, 254, 1, 13, 23, 28, 30, 34, 27, 33, 35, 29, 9, 250, 249, 253, 248, 238, 235, 249, 8, 9, 21, 11, 255, 254, 8, 17, 8, 6, 5, 1, 249, 241, 236, 241, 248, 1, 5, 8, 253, 252, 0, 10, 12, 14, 8, 2, 0, 250, 0, 4, 251, 233, 244, 255, 9, 7, 255, 248, 247, 250, 255, 1, 251, 241, 246, 254, 1, 251, 243, 246, 254, 7, 13, 10, 0, 251, 251, 0, 255, 246, 234, 236, 243, 246, 248, 247, 1, 0, 8, 21, 24, 253, 250, 0, 10, 252, 245, 245, 244, 238, 237, 0, 253, 252, 244, 248, 245, 0, 4, 8, 251, 4, 12, 11, 7, 17, 31, 29, 23, 12, 17, 18, 15, 9, 10, 254, 1, 5, 12, 17, 27, 21, 17, 31, 48, 48, 33, 29, 27, 31, 20, 19, 17, 17, 11, 14, 17, 15, 14, 7, 255, 246, 250, 243, 240, 233, 232, 232, 231, 232, 229, 231, 233, 227, 233, 240, 249, 249, 248, 246, 251, 251, 251, 252, 1, 0, 253, 254, 254, 253, 251, 255, 250, 246, 243, 245, 248, 244, 235, 229, 224, 223, 221, 225, 227, 228, 235, 244, 251, 250, 248, 248, 251, 252, 255, 249, 245, 238, 236, 238, 230, 223, 222, 224, 233, 247, 244, 245, 251, 2, 1, 245, 246, 248, 252, 255, 13, 26, 19, 5, 243, 245, 2, 11, 11, 10, 0, 0, 27, 1, 19, 0, 4, 4, 5, 5, 6, 7, 8, 10, 13, 17, 23, 53, 94, 45, 40, 70, 104, 120, 65, 36, 65, 76, 65, 27, 255, 253, 7, 233, 207, 216, 190, 192, 190, 173, 190, 190, 185, 189, 197, 220, 240, 219, 219, 7, 13, 14, 7, 7, 36, 44, 15, 7, 35, 21, 13, 247, 0, 11, 242, 217, 236, 233, 219, 215, 212, 222, 229, 198, 216, 240, 228, 234, 233, 226, 0, 16, 248, 245, 0, 24, 24, 244, 9, 21, 0, 250, 10, 250, 251, 247, 227, 241, 238, 244, 225, 200, 249, 20, 226, 195, 246, 14, 253, 240, 246, 11, 33, 59, 23, 6, 48, 69, 60, 17, 45, 86, 46, 12, 47, 103, 79, 49, 8, 70, 100, 68, 22, 11, 42, 49, 3, 237, 1, 254, 206, 219, 227, 228, 206, 185, 205, 213, 227, 216, 218, 188, 255, 3, 237, 225, 12, 33, 0, 241, 23, 60, 14, 231, 16, 41, 28, 247, 244, 244, 20, 248, 225, 229, 245, 243, 214, 220, 252, 3, 205, 209, 7, 28, 14, 250, 247, 33, 45, 37, 5, 9, 28, 38, 17, 35, 38, 0, 0, 34, 47, 1, 239, 239, 12, 0, 238, 219, 224, 238, 230, 217, 221, 239, 235, 216, 228, 253, 253, 229, 238, 252, 255, 245, 246, 255, 253, 247, 238, 255, 6, 4, 241, 245, 10, 20, 14, 3, 7, 18, 25, 29, 22, 20, 21, 21, 24, 30, 23, 13, 5, 14, 29, 24, 0, 5, 14, 21, 13, 12, 3, 12, 9, 13, 7, 7, 6, 3, 4, 7, 11, 1, 3, 254, 13, 15, 9, 0, 12, 14, 17, 6, 10, 11, 17, 10, 1, 7, 12, 0, 202, 10, 6, 0, 5, 13, 51, 44, 21, 20, 8, 251, 242, 255, 3, 249, 230, 210, 223, 245, 245, 11, 19, 17, 49, 48, 16, 11, 7, 248, 236, 206, 183, 229, 246, 7, 22, 23, 33, 37, 41, 22, 250, 244, 254, 233, 214, 213, 250, 5, 21, 22, 11, 15, 255, 0, 255, 251, 6, 19, 12, 231, 229, 245, 239, 246, 0, 33, 9, 12, 14, 248, 0, 12, 2, 11, 27, 6, 243, 231, 226, 249, 199, 245, 20, 48, 54, 4, 235, 252, 254, 233, 236, 15, 6, 1, 0, 11, 18, 10, 10, 255, 240, 246, 7, 6, 243, 247, 238, 220, 13, 25, 19, 13, 23, 35, 250, 197, 226, 249, 10, 22, 0, 0, 255, 14, 21, 13, 237, 238, 216, 244, 16, 21, 52, 24, 4, 229, 242, 244, 2, 252, 250, 249, 6, 248, 242, 240, 6, 245, 8, 18, 13, 54, 0, 27, 29, 231, 192, 199, 21, 21, 9, 7, 16, 244, 235, 2, 30, 0, 250, 5, 253, 244, 234, 250, 238, 248, 13, 15, 24, 4, 25, 40, 3, 2, 251, 229, 217, 230, 7, 7, 23, 247, 249, 243, 30, 36, 9, 26, 229, 198, 217, 220, 250, 13, 29, 24, 32, 13, 7, 40, 36, 255, 15, 1, 219, 222, 219, 207, 221, 251, 37, 26, 14, 4, 27, 219, 230, 19, 10, 36, 5, 26, 9, 229, 234, 14, 14, 6, 8, 0, 10, 239, 204, 239, 227, 237, 29, 22, 13, 29, 41, 22, 228, 236, 244, 0, 244, 255, 240, 246, 254, 11, 240, 19, 43, 28, 20, 235, 14, 246, 252, 227, 220, 11, 252, 232, 15, 10, 23, 19, 243, 235, 0, 242, 8, 0, 250, 33, 248, 15, 15, 255, 226, 7, 15, 2, 11, 44, 32, 11, 222, 198, 229, 229, 193, 225, 25, 33, 35, 13, 30, 27, 234, 3, 30, 24, 14, 238, 218, 236, 12, 246, 11, 22, 15, 3, 251, 235, 255, 226, 214, 227, 11, 255, 6, 0, 18, 59, 49, 252, 233, 0, 31, 27, 247, 239, 234, 239, 219, 246, 15, 18, 254, 233, 250, 39, 28, 240, 235, 222, 4, 252, 12, 1, 7, 43, 250, 15, 6, 1, 11, 231, 0, 246, 247, 13, 16, 38, 251, 244, 214, 211, 228, 198, 34, 39, 27, 16, 5, 226, 31, 59, 28, 43, 22, 251, 192, 215, 211, 191, 230, 3, 8, 7, 59, 25, 52, 27, 240, 4, 236, 14, 0, 240, 235, 237, 234, 226, 188, 4, 82, 55, 26, 24, 12, 236, 241, 14, 2, 250, 208, 209, 235, 13, 38, 44, 7, 249, 247, 221, 225, 241, 72, 44, 17, 13, 238, 197, 213, 250, 26, 32, 5, 19, 228, 12, 46, 231, 241, 244, 16, 255, 235, 240, 251, 239, 221, 17, 42, 33, 45, 26, 15, 210, 230, 5, 244, 194, 11, 11, 22, 2, 254, 246, 3, 6, 9, 33, 24, 3, 237, 212, 236, 254, 18, 222, 25, 60, 1, 212, 224, 253, 2, 58, 14, 42, 254, 218, 6, 250, 32, 231, 190, 230, 3, 248, 6, 16, 242, 23, 42, 5, 35, 39, 3, 3, 235, 230, 203, 231, 220, 11, 54, 43, 241, 241, 2, 221, 239, 10, 18, 2, 22, 7, 251, 24, 27, 11, 240, 0, 31, 28, 16, 166, 168, 201, 242, 231, 250, 90, 73, 2, 9, 29, 15, 250, 249, 9, 52, 35, 251, 218, 174, 186, 19, 35, 0, 232, 220, 223, 197, 10, 44, 80, 39, 29, 50, 254, 8, 54, 253, 204, 241, 239, 201, 249, 220, 0, 240, 19, 29, 252, 254, 248, 12, 253, 219, 242, 34, 19, 18, 9, 6, 61, 63, 3, 222, 223, 249, 252, 231, 232, 4, 252, 205, 249, 255, 253, 45, 14, 207, 214, 15, 14, 20, 29, 28, 80, 37, 253, 243, 220, 3, 3, 220, 4, 217, 9, 248, 193, 242, 30, 44, 20, 207, 173, 9, 87, 249, 254, 45, 9, 4, 29, 39, 14, 36, 228, 175, 234, 232, 241, 230, 203, 31, 90, 56, 249, 213, 11, 13, 7, 238, 7, 10, 186, 174, 235, 37, 9, 28, 38, 54, 30, 26, 29, 2, 250, 252, 240, 216, 0, 240, 226, 164, 210, 240, 68, 41, 23, 68, 3, 214, 238, 22, 26, 246, 2, 232, 14, 223, 14, 32, 8, 18, 228, 24, 250, 37, 20, 242, 232, 222, 204, 225, 246, 219, 15, 29, 5, 11, 21, 22, 33, 29, 252, 14, 1, 31, 14, 232, 195, 14, 233, 20, 220, 214, 47, 24, 239, 241, 17, 243, 16, 238, 230, 7, 36, 232, 201, 251, 34, 68, 45, 33, 233, 2, 55, 247, 235, 195, 198, 211, 46, 42, 232, 24, 237, 241, 243, 13, 26, 32, 235, 211, 237, 1, 5, 248, 45, 5, 41, 16, 20, 18, 229, 29, 40, 235, 216, 227, 214, 214, 9, 15, 2, 241, 199, 19, 35, 11, 248, 1, 22, 238, 32, 32, 0, 26, 18, 34, 245, 23, 34, 235, 182, 205, 8, 235, 242, 242, 210, 222, 21, 8, 252, 22, 38, 60, 20, 254, 23, 33, 5, 219, 9, 15, 62, 241, 181, 245, 230, 228, 0, 214, 218, 16, 237, 255, 50, 67, 7, 249, 254, 7, 6, 242, 48, 31, 228, 225, 48, 223, 230, 10, 16, 19, 253, 230, 207, 235, 39, 36, 225, 218, 246, 254, 254, 226, 248, 63, 33, 33, 61, 35, 0, 28, 224, 192, 227, 4, 41, 230, 221, 212, 235, 226, 250, 247, 250, 59, 19, 13, 4, 16, 80, 70, 10, 17, 27, 209, 151, 148, 195, 1, 51, 21, 15, 24, 66, 10, 229, 236, 23, 31, 189, 219, 224, 11, 28, 8, 50, 35, 22, 1, 12, 15, 228, 249, 233, 189, 248, 249, 227, 220, 16, 42, 0, 243, 31, 79, 15, 24, 242, 14, 33, 251, 203, 242, 222, 246, 25, 208, 2, 225, 242, 7, 236, 45, 47, 236, 24, 60, 3, 2, 4, 230, 12, 246, 178, 6, 36, 2, 206, 231, 77, 19, 250, 10, 7, 254, 214, 233, 0, 5, 8, 15, 223, 245, 12, 65, 249, 234, 26, 53, 16, 226, 6, 228, 223, 9, 25, 207, 237, 227, 245, 14, 251, 25, 12, 29, 14, 238, 209, 40, 87, 5, 24, 254, 7, 220, 216, 177, 230, 26, 35, 26, 192, 249, 47, 11, 226, 12, 41, 0, 42, 242, 246, 255, 10, 11, 230, 222, 204, 246, 28, 12, 3, 53, 62, 7, 242, 240, 1, 238, 233, 211, 213, 13, 247, 4, 13, 23, 68, 16, 217, 252, 7, 245, 2, 236, 253, 42, 15, 47, 14, 26, 249, 204, 192, 193, 220, 230, 2, 22, 255, 28, 65, 60, 29, 254, 27, 25, 0, 218, 237, 199, 136, 228, 33, 69, 58, 60, 54, 224, 224, 229, 250, 233, 185, 220, 248, 47, 249, 49, 35, 30, 6, 19, 17, 225, 209, 240, 0, 4, 1, 250, 12, 31, 84, 4, 231, 223, 242, 195, 186, 250, 50, 22, 231, 0, 20, 8, 229, 2, 29, 51, 53, 250, 7, 1, 41, 3, 224, 241, 205, 193, 38, 232, 234, 18, 219, 189, 4, 57, 32, 73, 40, 26, 237, 228, 192, 252, 254, 2, 32, 28, 49, 35, 236, 251, 234, 207, 0, 255, 252, 220, 11, 222, 201, 250, 243, 236, 55, 70, 57, 13, 26, 4, 213, 72, 49, 14, 23, 173, 169, 212, 237, 240, 172, 253, 55, 74, 54, 60, 219, 179, 177, 220, 41, 123, 76, 250, 243, 30, 234, 0, 0, 3, 202, 218, 0, 8, 242, 219, 232, 246, 52, 26, 11, 16, 252, 230, 16, 6, 6, 18, 242, 1, 29, 65, 30, 210, 209, 214, 13, 207, 201, 27, 7, 255, 51, 33, 252, 244, 25, 20, 239, 249, 220, 193, 56, 65, 238, 242, 2, 4, 2, 44, 5, 245, 224, 219, 248, 29, 5, 184, 241, 72, 57, 238, 233, 230, 219, 28, 25, 255, 13, 7, 20, 4, 18, 3, 247, 20, 230, 21, 43, 209, 205, 238, 206, 177, 233, 82, 9, 53, 47, 8, 16, 5, 9, 234, 20, 37, 11, 228, 242, 229, 229, 224, 214, 17, 14, 10, 35, 21, 237, 253, 233, 8, 253, 28, 21, 204, 231, 31, 46, 56, 240, 3, 246, 233, 248, 230, 4, 251, 249, 14, 6, 3, 216, 23, 10, 216, 22, 246, 206, 66, 2, 216, 79, 76, 241, 226, 53, 6, 160, 175, 253, 20, 49, 10, 226, 253, 30, 247, 12, 240, 253, 1, 5, 245, 216, 2, 83, 34, 29, 27, 238, 216, 185, 237, 8, 54, 16, 203, 177, 14, 27, 13, 45, 246, 241, 13, 22, 6, 42, 14, 216, 249, 18, 35, 222, 1, 226, 4, 197, 231, 14, 240, 20, 240, 222, 95, 73, 230, 226, 1, 3, 15, 20, 253, 221, 69, 47, 238, 188, 239, 216, 201, 247, 243, 45, 17, 28, 31, 14, 242, 13, 223, 41, 31, 225, 255, 226, 211, 215, 47, 50, 26, 50, 255, 232, 246, 27, 166, 227, 14, 251, 245, 249, 10, 37, 21, 248, 2, 20, 21, 38, 191, 191, 29, 57, 214, 255, 16, 8, 18, 5, 0, 242, 1, 249, 243, 255, 247, 20, 253, 221, 219, 44, 11, 213, 244, 3, 50, 85, 23, 218, 221, 255, 27, 19, 27, 221, 221, 18, 230, 252, 249, 10, 250, 205, 7, 227, 239, 19, 58, 22, 18, 33, 247, 199, 248, 46, 65, 28, 8, 224, 236, 230, 187, 250, 237, 19, 29, 226, 220, 5, 25, 241, 13, 13, 38, 42, 31, 240, 248, 30, 5, 223, 12, 247, 162, 237, 24, 30, 39, 240, 7, 0, 203, 225, 246, 8, 28, 50, 38, 236, 254, 28, 247, 247, 250, 9, 11, 250, 204, 218, 62, 232, 238, 32, 6, 25, 235, 225, 37, 40, 49, 160, 194, 12, 40, 14, 11, 245, 6, 240, 237, 35, 241, 39, 9, 230, 15, 41, 247, 223, 223, 208, 11, 43, 6, 21, 236, 0, 8, 1, 255, 242, 6, 25, 6, 216, 241, 237, 252, 39, 7, 33, 0, 28, 39, 16, 231, 205, 235, 176, 218, 24, 47, 39, 222, 5, 20, 21, 47, 232, 189, 14, 28, 7, 34, 25, 225, 13, 228, 232, 16, 7, 214, 249, 43, 240, 206, 240, 0, 246, 10, 26, 47, 34, 55, 15, 249, 3, 245, 244, 208, 214, 237, 15, 2, 210, 202, 6, 35, 80, 68, 3, 252, 202, 19, 19, 193, 28, 36, 234, 235, 228, 244, 6, 242, 18, 67, 39, 246, 222, 5, 229, 9, 253, 231, 249, 225, 244, 2, 43, 6, 22, 28, 244, 48, 249, 223, 0, 239, 12, 233, 253, 23, 13, 248, 191, 239, 68, 19, 28, 219, 205, 2, 33, 35, 8, 251, 3, 242, 239, 244, 23, 245, 222, 217, 19, 16, 10, 51, 49, 32, 7, 225, 182, 209, 58, 21, 240, 210, 9, 19, 217, 2, 253, 4, 20, 58, 211, 253, 33, 28, 2, 182, 33, 80, 236, 236, 185, 236, 254, 6, 10, 73, 40, 248, 194, 251, 1, 26, 20, 193, 220, 202, 10, 66, 253, 30, 70, 6, 240, 228, 239, 26, 53, 205, 3, 22, 222, 228, 242, 247, 22, 237, 10, 234, 236, 3, 21, 41, 40, 249, 12, 235, 233, 20, 22, 29, 243, 224, 233, 16, 212, 228, 49, 234, 56, 11, 6, 230, 221, 4, 251, 199, 57, 45, 228, 58, 18, 234, 230, 239, 14, 5, 237, 38, 24, 237, 225, 243, 198, 29, 35, 30, 244, 225, 249, 237, 66, 218, 23, 14, 237, 247, 19, 62, 33, 244, 207, 0, 228, 234, 2, 234, 236, 22, 2, 242, 3, 236, 25, 38, 53, 43, 247, 210, 255, 23, 206, 226, 8, 27, 35, 236, 7, 16, 213, 240, 253, 194, 31, 20, 0, 240, 227, 37, 9, 29, 53, 76, 4, 204, 22, 228, 187, 14, 226, 0, 247, 247, 8, 242, 233, 251, 0, 238, 48, 50, 46, 45, 13, 221, 202, 236, 2, 21, 61, 10, 224, 233, 150, 205, 25, 1, 12, 45, 82, 9, 8, 252, 239, 255, 253, 5, 190, 254, 252, 18, 39, 0, 27, 4, 204, 1, 16, 8, 26, 237, 210, 236, 23, 9, 21, 225, 236, 243, 255, 70, 32, 0, 247, 29, 24, 210, 248, 44, 213, 232, 213, 181, 33, 48, 11, 15, 19, 14, 251, 5, 5, 224, 19, 3, 221, 9, 59, 240, 254, 11, 209, 5, 1, 239, 244, 22, 13, 247, 27, 255, 0, 24, 229, 42, 236, 215, 213, 18, 13, 240, 7, 6, 48, 231, 36, 45, 19, 208, 223, 241, 212, 4, 4, 35, 31, 29, 2, 249, 247, 225, 251, 240, 213, 248, 7, 4, 246, 50, 65, 252, 243, 19, 8, 18, 12, 215, 239, 241, 34, 247, 214, 228, 238, 2, 40, 20, 228, 0, 247, 31, 7, 226, 2, 4, 35, 51, 35, 0, 8, 208, 191, 9, 16, 17, 248, 233, 249, 237, 230, 229, 243, 46, 50, 25, 244, 253, 24, 235, 49, 9, 255, 232, 30, 243, 201, 5, 243, 14, 211, 250, 41, 242, 29, 236, 6, 240, 23, 255, 225, 19, 33, 24, 29, 12, 5, 215, 199, 223, 20, 11, 12, 0, 238, 5, 25, 31, 245, 255, 16, 6, 236, 248, 195, 226, 247, 254, 76, 53, 249, 10, 16, 43, 252, 248, 240, 153, 197, 19, 235, 40, 80, 42, 16, 224, 236, 198, 3, 249, 232, 42, 1, 30, 245, 1, 25, 253, 29, 41, 244, 214, 10, 226, 219, 3, 199, 235, 32, 45, 52, 34, 248, 240, 207, 242, 56, 24, 238, 247, 236, 3, 3, 193, 2, 8, 15, 38, 50, 15, 226, 229, 3, 32, 22, 249, 212, 225, 231, 254, 26, 252, 251, 254, 21, 4, 22, 241, 254, 0, 248, 39, 28, 14, 247, 249, 3, 235, 7, 244, 224, 20, 247, 227, 242, 241, 29, 247, 249, 36, 38, 23, 207, 233, 14, 255, 68, 69, 218, 238, 238, 226, 4, 246, 18, 249, 216, 209, 198, 0, 99, 39, 23, 53, 239, 13, 243, 186, 251, 20, 248, 239, 240, 241, 29, 28, 45, 21, 252, 226, 209, 252, 8, 22, 6, 11, 237, 245, 3, 201, 253, 254, 251, 55, 32, 10, 60, 2, 243, 250, 227, 17, 223, 211, 246, 210, 249, 56, 4, 4, 33, 37, 20, 245, 5, 246, 218, 204, 14, 17, 10, 28, 4, 0, 0, 250, 253, 239, 233, 28, 7, 0, 254, 247, 2, 0, 253, 19, 43, 243, 235, 1, 254, 225, 246, 232, 15, 59, 0, 1, 15, 246, 21, 212, 238, 253, 2, 9, 7, 18, 22, 13, 230, 25, 245, 225, 223, 241, 248, 247, 52, 11, 31, 7, 234, 240, 19, 28, 3, 18, 253, 228, 236, 223, 253, 2, 233, 3, 21, 32, 255, 11, 35, 247, 1, 249, 237, 221, 243, 2, 11, 249, 1, 35, 20, 8, 1, 13, 39, 242, 246, 254, 187, 233, 0, 251, 19, 247, 0, 19, 239, 239, 32, 12, 28, 41, 6, 21, 210, 255, 224, 208, 39, 25, 24, 9, 209, 218, 250, 233, 15, 32, 30, 15, 2, 254, 226, 233, 239, 250, 46, 32, 1, 22, 225, 248, 24, 3, 252, 248, 5, 22, 215, 220, 254, 236, 13, 13, 10, 21, 11, 3, 17, 249, 251, 9, 240, 230, 16, 10, 35, 214, 245, 255, 225, 4, 16, 49, 6, 6, 244, 37, 22, 203, 221, 247, 6, 247, 1, 235, 16, 36, 0, 0, 239, 233, 234, 27, 12, 44, 37, 5, 251, 217, 233, 14, 42, 232, 239, 8, 249, 226, 228, 9, 6, 25, 254, 24, 248, 234, 227, 252, 24, 8, 31, 16, 42, 11, 239, 240, 0, 251, 245, 242, 8, 252, 240, 231, 238, 3, 14, 10, 250, 7, 11, 7, 246, 11, 2, 7, 0, 24, 39, 254, 2, 250, 244, 235, 246, 241, 220, 13, 20, 10, 243, 232, 248, 8, 7, 0, 250, 34, 25, 0, 4, 251, 28, 253, 10, 1, 2, 251, 221, 228, 218, 2, 38, 6, 255, 16, 3, 244, 248, 234, 34, 18, 1, 2, 0, 247, 7, 251, 255, 17, 245, 248, 244, 5, 17, 0, 244, 6, 2, 243, 0, 242, 27, 20, 4, 255, 5, 5, 255, 224, 219, 241, 1, 16, 12, 7, 28, 251, 15, 39, 7, 230, 243, 0, 8, 253, 244, 0, 230, 239, 252, 236, 23, 47, 12, 246, 238, 249, 12, 231, 21, 38, 10, 12, 10, 233, 216, 233, 4, 6, 13, 7, 0, 1, 254, 0, 0, 233, 7, 15, 0, 2, 5, 24, 14, 23, 15, 18, 18, 22, 19, 26, 21, 27, 28, 17, 24, 30, 26, 17, 23, 26, 30, 31, 17, 28, 21, 16, 12, 29, 40, 4, 36, 18, 26, 31, 11, 21, 16, 29, 4, 19, 16, 20, 24, 7, 26, 14, 27, 8, 9, 11, 17, 23, 254, 22, 16, 24, 16, 18, 12, 253, 30, 1, 21, 18, 17, 28, 21, 14, 27, 23, 23, 14, 35, 33, 31, 27, 27, 25, 23, 13, 16, 33, 27, 3, 20, 12, 9, 36, 34, 20, 28, 13, 18, 12, 252, 20, 17, 8, 4, 13, 9, 2, 53, 18, 11, 14, 0, 0, 251, 20, 21, 16, 7, 0, 11, 22, 17, 27, 18, 14, 6, 8, 24, 23, 4, 32, 17, 26, 16, 24, 16, 28, 34, 15, 21, 33, 33, 26, 28, 3, 26, 21, 7, 34, 50, 18, 25, 4, 19, 37, 20, 19, 4, 20, 29, 9, 25, 21, 35, 23, 22, 9, 4, 23, 248, 30, 21, 18, 9, 8, 3, 29, 20, 10, 14, 13, 4, 9, 12, 27, 22, 0, 8, 10, 4, 4, 12, 20, 18, 20, 1, 20, 22, 12, 30, 9, 20, 27, 0, 11, 16, 34, 23, 37, 1, 33, 19, 11, 22, 11, 33, 14, 10, 25, 20, 21, 24, 1, 8, 29, 11, 14, 26, 19, 5, 13, 15, 17, 4, 14, 5, 4, 10, 11, 17, 4, 11, 17, 245, 11, 25, 8, 15, 3, 8, 10, 0, 18, 11, 14, 28, 31, 21, 7, 30, 11, 18, 34, 17, 42, 7, 9, 5, 9, 19, 11, 37, 13, 26, 31, 7, 20, 4, 30, 19, 28, 8, 16, 11, 30, 20, 5, 19, 17, 17, 5, 0, 2, 20, 10, 11, 25, 7, 26, 7, 10, 6, 15, 25, 7, 6, 7, 253, 21, 9, 16, 22, 27, 2, 18, 28, 5, 15, 12, 2, 23, 14, 37, 15, 10, 26, 14, 8, 21, 28, 12, 26, 9, 37, 21, 10, 30, 20, 13, 28, 30, 6, 17, 8, 4, 21, 6, 26, 27, 10, 23, 14, 14, 23, 11, 0, 12, 7, 10, 19, 14, 248, 18, 10, 1, 1, 2, 28, 14, 254, 4, 12, 9, 7, 17, 16, 27, 15, 3, 10, 31, 0, 11, 35, 11, 4, 19, 38, 23, 8, 13, 31, 18, 24, 18, 26, 32, 12, 26, 14, 24, 29, 11, 29, 13, 8, 21, 9, 4, 13, 19, 20, 8, 17, 17, 0, 10, 11, 11, 5, 1, 9, 0, 255, 10, 8, 8, 22, 4, 8, 20, 6, 252, 14, 25, 8, 24, 11, 19, 39, 30, 11, 34, 13, 11, 25, 3, 23, 38, 28, 40, 12, 27, 36, 11, 13, 24, 33, 20, 12, 26, 251, 35, 250, 8, 20, 18, 9, 0, 20, 4, 15, 13, 5, 250, 21, 0, 7, 2, 3, 9, 5, 0, 9, 20, 29, 0, 248, 15, 253, 10, 28, 33, 15, 14, 6, 13, 25, 29, 18, 3, 32, 44, 19, 22, 38, 5, 15, 24, 35, 7, 22, 24, 25, 26, 13, 8, 19, 31, 251, 10, 7, 237, 11, 247, 28, 1, 0, 13, 3, 2, 26, 2, 252, 13, 2, 17, 13, 5, 244, 1, 1, 9, 18, 15, 9, 12, 0, 41, 26, 22, 17, 0, 251, 13, 37, 22, 9, 1, 14, 58, 3, 20, 21, 13, 29, 16, 2, 41, 31, 0, 29, 18, 16, 18, 2, 24, 15, 10, 31, 253, 0, 27, 4, 37, 9, 1, 20, 3, 12, 9, 0, 11, 28, 251, 253, 14, 20, 28, 34, 249, 7, 12, 19, 16, 3, 2, 31, 7, 4, 6, 7, 32, 27, 0, 12, 7, 20, 14, 1, 253, 1, 35, 16, 249, 5, 24, 16, 15, 33, 252, 13, 7, 13, 23, 251, 43, 47, 252, 33, 38, 13, 33, 34, 248, 24, 32, 13, 37, 32, 22, 31, 16, 6, 16, 24, 34, 12, 0, 25, 26, 22, 25, 13, 24, 24, 240, 14, 27, 244, 15, 25, 239, 254, 8, 235, 37, 15, 6, 13, 254, 2, 12, 33, 250, 9, 236, 243, 9, 233, 26, 22, 20, 6, 24, 252, 24, 23, 15, 39, 8, 14, 30, 251, 34, 39, 0, 17, 43, 29, 26, 45, 23, 254, 43, 9, 45, 37, 14, 24, 34, 251, 51, 38, 11, 21, 16, 14, 28, 41, 15, 21, 250, 31, 4, 14, 24, 0, 5, 17, 27, 27, 15, 7, 0, 28, 26, 13, 15, 7, 17, 4, 246, 34, 23, 10, 18, 14, 7, 1, 14, 7, 20, 3, 13, 252, 240, 16, 23, 0, 21, 6, 3, 250, 255, 27, 15, 249, 5, 14, 4, 252, 29, 254, 247, 44, 20, 1, 30, 29, 243, 57, 27, 20, 28, 250, 36, 18, 11, 54, 35, 34, 36, 26, 43, 61, 22, 44, 20, 13, 34, 46, 44, 27, 41, 39, 6, 27, 0, 55, 32, 22, 9, 8, 16, 240, 25, 255, 15, 18, 6, 250, 247, 29, 10, 238, 18, 8, 230, 235, 250, 246, 11, 14, 236, 23, 250, 5, 6, 21, 250, 22, 42, 252, 11, 31, 31, 21, 23, 253, 22, 3, 30, 3, 32, 32, 249, 28, 14, 8, 24, 24, 254, 247, 2, 242, 244, 10, 15, 37, 254, 9, 11, 255, 17, 6, 38, 30, 23, 21, 15, 15, 20, 53, 18, 45, 22, 248, 24, 21, 28, 11, 72, 39, 31, 42, 4, 49, 19, 37, 27, 25, 32, 8, 21, 20, 40, 41, 4, 25, 6, 253, 23, 10, 11, 246, 5, 4, 253, 37, 15, 232, 0, 17, 254, 240, 28, 32, 7, 25, 233, 228, 11, 252, 0, 33, 28, 248, 12, 0, 15, 20, 19, 19, 48, 6, 12, 9, 2, 32, 11, 27, 33, 47, 19, 250, 41, 25, 23, 42, 36, 15, 35, 35, 254, 11, 6, 18, 65, 16, 255, 11, 22, 50, 255, 220, 0, 37, 232, 0, 3, 225, 22, 236, 185, 58, 82, 55, 30, 245, 245, 31, 17, 36, 238, 6, 55, 16, 19, 16, 47, 54, 45, 29, 31, 18, 65, 14, 29, 23, 55, 66, 19, 28, 39, 16, 27, 19, 227, 21, 27, 10, 19, 1, 235, 57, 20, 231, 3, 242, 9, 20, 251, 4, 229, 255, 28, 14, 248, 2, 15, 0, 3, 242, 8, 14, 17, 17, 234, 249, 47, 55, 13, 249, 58, 30, 31, 48, 1, 253, 26, 31, 24, 17, 245, 251, 33, 253, 241, 17, 83, 28, 4, 50, 29, 34, 42, 8, 222, 33, 60, 6, 15, 255, 249, 25, 72, 250, 235, 35, 37, 29, 224, 241, 252, 0, 242, 4, 32, 38, 13, 240, 221, 227, 16, 32, 229, 19, 14, 242, 21, 252, 9, 17, 12, 57, 72, 0, 0, 37, 250, 32, 21, 11, 60, 49, 1, 26, 255, 25, 68, 27, 250, 53, 30, 17, 24, 13, 29, 46, 6, 11, 27, 225, 251, 30, 17, 0, 4, 26, 24, 251, 239, 30, 21, 238, 10, 246, 236, 45, 47, 25, 6, 5, 18, 59, 252, 245, 39, 31, 26, 0, 249, 25, 40, 39, 19, 236, 232, 54, 5, 236, 14, 22, 48, 5, 250, 16, 230, 10, 46, 11, 242, 5, 0, 19, 250, 210, 23, 39, 246, 248, 254, 255, 8, 20, 241, 12, 31, 6, 41, 214, 238, 19, 36, 18, 40, 47, 54, 17, 43, 26, 238, 32, 25, 23, 32, 21, 15, 51, 11, 33, 57, 40, 47, 28, 8, 10, 23, 51, 40, 6, 9, 25, 12, 25, 25, 251, 22, 33, 1, 254, 252, 237, 11, 254, 22, 3, 14, 35, 245, 241, 2, 28, 22, 5, 10, 253, 254, 6, 23, 15, 9, 24, 36, 14, 255, 236, 6, 24, 30, 12, 34, 25, 14, 10, 23, 8, 13, 13, 22, 22, 6, 55, 44, 245, 251, 17, 5, 25, 34, 33, 22, 36, 50, 18, 17, 15, 30, 71, 71, 28, 29, 28, 20, 13, 244, 31, 29, 31, 46, 3, 11, 45, 248, 22, 33, 246, 27, 14, 229, 225, 232, 250, 220, 242, 234, 159, 137, 200, 232, 245, 239, 240, 24, 15, 5, 47, 34, 18, 33, 62, 0, 13, 51, 53, 30, 32, 121, 76, 19, 50, 47, 49, 85, 253, 17, 91, 53, 71, 85, 68, 42, 50, 21, 25, 47, 39, 14, 239, 16, 37, 246, 249, 251, 31, 31, 0, 14, 35, 236, 249, 254, 20, 23, 17, 22, 5, 245, 253, 37, 15, 9, 17, 10, 23, 255, 232, 9, 6, 10, 26, 16, 20, 16, 24, 9, 10, 8, 36, 23, 254, 233, 45, 30, 249, 6, 253, 9, 35, 18, 255, 7, 37, 34, 14, 12, 14, 31, 254, 252, 18, 7, 26, 30, 15, 27, 42, 21, 25, 22, 0, 8, 21, 23, 2, 250, 246, 36, 239, 8, 61, 245, 4, 13, 246, 16, 34, 247, 251, 6, 250, 250, 2, 21, 21, 16, 251, 253, 13, 250, 5, 254, 14, 26, 7, 3, 242, 233, 244, 13, 46, 28, 12, 16, 16, 4, 21, 45, 44, 27, 7, 6, 7, 15, 28, 40, 10, 22, 63, 42, 19, 15, 252, 28, 33, 17, 21, 18, 26, 19, 10, 8, 23, 18, 14, 1, 251, 35, 12, 25, 7, 255, 37, 10, 20, 9, 20, 25, 0, 242, 0, 36, 21, 16, 7, 251, 254, 13, 29, 243, 0, 2, 4, 14, 19, 1, 232, 11, 15, 42, 29, 11, 18, 8, 11, 9, 255, 253, 28, 11, 23, 20, 14, 19, 21, 14, 4, 15, 54, 23, 16, 17, 13, 14, 42, 9, 14, 50, 24, 14, 30, 10, 23, 250, 21, 22, 249, 70, 0, 0, 36, 245, 42, 41, 17, 38, 33, 254, 7, 21, 11, 42, 4, 21, 21, 4, 41, 36, 7, 28, 23, 40, 55, 47, 23, 17, 19, 22, 32, 4, 25, 57, 43, 42, 9, 253, 16, 17, 7, 24, 19, 20, 8, 242, 10, 27, 24, 19, 19, 43, 34, 10, 9, 3, 3, 22, 31, 21, 17, 10, 17, 37, 17, 26, 42, 28, 32, 26, 15, 33, 24, 5, 15, 7, 17, 38, 16, 13, 3, 14, 27, 24, 3, 254, 252, 5, 18, 16, 250, 255, 9, 252, 246, 4, 25, 7, 14, 7, 5, 5, 10, 254, 238, 4, 1, 5, 0, 255, 27, 45, 32, 29, 20, 12, 24, 42, 12, 46, 16, 40, 52, 14, 5, 6, 57, 26, 32, 60, 9, 20, 54, 3, 15, 33, 24, 20, 0, 2, 37, 27, 0, 1, 2, 32, 57, 18, 5, 24, 255, 253, 4, 7, 24, 47, 32, 15, 14, 12, 25, 23, 20, 24, 36, 47, 36, 21, 0, 9, 27, 18, 20, 12, 12, 11, 6, 254, 0, 16, 16, 16, 1, 10, 25, 15, 252, 239, 251, 25, 21, 18, 24, 28, 14, 3, 251, 247, 15, 32, 27, 15, 14, 19, 21, 16, 26, 44, 46, 32, 27, 252, 247, 255, 251, 20, 47, 44, 43, 38, 19, 25, 30, 3, 12, 11, 1, 21, 17, 10, 17, 17, 24, 41, 33, 27, 31, 22, 11, 4, 4, 8, 21, 22, 10, 15, 14, 1, 7, 253, 250, 24, 20, 1, 11, 1, 245, 4, 6, 9, 19, 15, 12, 3, 3, 11, 15, 5, 5, 13, 13, 17, 23, 9, 11, 25, 21, 14, 21, 26, 26, 19, 11, 11, 21, 18, 8, 11, 23, 12, 9, 28, 16, 16, 34, 49, 34, 14, 16, 35, 70, 19, 7, 36, 67, 21, 12, 35, 43, 52, 24, 11, 33, 44, 31, 20, 245, 30, 28, 7, 5, 0, 13, 36, 24, 3, 1, 18, 14, 252, 2, 12, 6, 18, 19, 0, 5, 21, 20, 15, 7, 6, 32, 31, 20, 24, 19, 22, 29, 34, 25, 24, 34, 35, 16, 13, 21, 25, 29, 21, 25, 17, 30, 18, 4, 23, 1, 15, 28, 6, 2, 0, 8, 253, 248, 241, 251, 10, 7, 4, 249, 8, 255, 1, 12, 6, 10, 18, 8, 0, 4, 7, 10, 23, 12, 13, 39, 38, 8, 15, 10, 6, 25, 31, 21, 10, 7, 9, 10, 13, 10, 22, 25, 25, 18, 255, 0, 255, 254, 2, 0, 0, 0, 122, 8, 8, 0, 10, 213, 185, 201, 218, 246, 30, 33, 19, 56, 71, 24, 0, 214, 189, 183, 232, 14, 26, 28, 12, 15, 57, 29, 252, 4, 244, 232, 213, 223, 2, 10, 16, 13, 5, 238, 255, 243, 245, 26, 10, 218, 238, 31, 37, 0, 0, 0, 1, 21, 21, 237, 233, 8, 244, 252, 45, 28, 219, 215, 249, 4, 251, 2, 229, 242, 250, 255, 14, 37, 36, 26, 0, 12, 6, 215, 225, 255, 12, 16, 2, 11, 17, 4, 248, 236, 0, 228, 217, 228, 3, 33, 7, 27, 18, 251, 28, 246, 235, 22, 246, 250, 248, 1, 59, 5, 229, 252, 251, 20, 2, 226, 11, 12, 229, 227, 253, 6, 247, 237, 253, 3, 20, 21, 251, 4, 21, 40, 20, 7, 238, 4, 35, 6, 224, 208, 223, 231, 252, 13, 2, 5, 4, 17, 13, 227, 252, 13, 250, 48, 14, 234, 220, 243, 18, 67, 52, 14, 253, 215, 213, 209, 236, 253, 247, 21, 31, 42, 5, 209, 241, 246, 38, 243, 215, 14, 41, 22, 35, 21, 210, 0, 245, 199, 13, 21, 10, 15, 252, 20, 22, 233, 233, 0, 12, 9, 205, 209, 244, 2, 9, 28, 42, 18, 23, 26, 20, 245, 229, 226, 13, 7, 230, 230, 242, 18, 33, 20, 253, 227, 214, 237, 1, 13, 2, 17, 37, 18, 25, 22, 209, 223, 29, 4, 27, 2, 210, 216, 249, 57, 255, 227, 0, 232, 4, 66, 0, 204, 0, 12, 253, 41, 46, 231, 231, 236, 247, 2, 246, 253, 3, 57, 68, 224, 211, 220, 218, 21, 9, 21, 2, 234, 11, 238, 12, 15, 16, 39, 213, 240, 32, 3, 251, 1, 4, 18, 7, 222, 230, 2, 239, 248, 244, 9, 33, 28, 252, 1, 241, 1, 246, 237, 16, 30, 28, 5, 0, 13, 16, 210, 197, 254, 20, 250, 12, 23, 225, 229, 254, 8, 39, 16, 222, 248, 20, 29, 15, 255, 42, 0, 203, 243, 1, 248, 240, 9, 6, 254, 0, 250, 244, 252, 23, 49, 237, 223, 238, 222, 252, 54, 42, 252, 23, 43, 0, 220, 239, 207, 11, 30, 216, 220, 40, 20, 241, 254, 40, 8, 216, 248, 27, 9, 234, 24, 217, 234, 20, 231, 0, 55, 31, 245, 34, 10, 214, 235, 24, 38, 25, 207, 174, 232, 9, 249, 23, 20, 27, 7, 255, 238, 238, 22, 231, 232, 61, 58, 235, 250, 19, 6, 10, 230, 217, 238, 32, 254, 212, 24, 6, 219, 13, 13, 249, 252, 248, 0, 254, 57, 32, 234, 249, 55, 240, 221, 1, 42, 244, 217, 212, 239, 32, 11, 6, 245, 36, 16, 183, 250, 14, 39, 44, 226, 223, 37, 1, 210, 23, 39, 255, 206, 225, 26, 43, 231, 238, 12, 44, 14, 216, 251, 41, 254, 210, 225, 38, 20, 235, 218, 33, 43, 13, 217, 172, 4, 66, 9, 16, 34, 5, 226, 228, 239, 49, 255, 237, 5, 252, 255, 231, 11, 28, 34, 18, 246, 216, 8, 233, 183, 216, 45, 34, 12, 20, 245, 17, 63, 28, 215, 254, 34, 211, 205, 236, 244, 44, 10, 28, 28, 237, 252, 241, 237, 233, 214, 226, 41, 63, 232, 0, 55, 24, 233, 240, 19, 234, 11, 19, 250, 12, 1, 213, 233, 80, 20, 157, 200, 25, 223, 5, 60, 7, 237, 44, 57, 2, 211, 20, 208, 3, 91, 231, 161, 12, 33, 0, 14, 44, 236, 177, 244, 21, 246, 8, 8, 237, 32, 3, 8, 27, 31, 212, 233, 62, 44, 212, 181, 4, 62, 217, 176, 8, 48, 22, 246, 4, 44, 15, 214, 250, 21, 212, 1, 55, 23, 3, 216, 211, 29, 29, 210, 242, 23, 4, 236, 231, 33, 34, 20, 234, 247, 19, 0, 228, 246, 28, 49, 42, 204, 172, 21, 91, 219, 190, 227, 14, 25, 25, 239, 252, 19, 237, 21, 11, 14, 18, 222, 26, 17, 0, 216, 243, 4, 9, 248, 232, 44, 10, 0, 248, 201, 21, 25, 214, 255, 14, 229, 246, 55, 46, 18, 235, 0, 18, 255, 244, 220, 247, 22, 243, 23, 236, 246, 33, 213, 250, 17, 213, 241, 48, 44, 234, 223, 61, 14, 224, 18, 7, 226, 230, 46, 55, 230, 224, 2, 250, 226, 8, 21, 237, 0, 247, 255, 240, 7, 251, 218, 60, 82, 226, 219, 78, 34, 191, 226, 7, 246, 8, 3, 222, 233, 31, 15, 233, 4, 41, 5, 207, 8, 18, 196, 11, 72, 245, 254, 31, 237, 229, 6, 233, 246, 56, 37, 222, 198, 38, 55, 187, 245, 55, 10, 199, 235, 232, 14, 33, 22, 4, 237, 53, 13, 231, 199, 33, 35, 172, 248, 51, 242, 7, 33, 15, 23, 220, 254, 251, 4, 217, 226, 48, 60, 212, 173, 6, 85, 33, 199, 227, 13, 48, 6, 242, 237, 21, 26, 22, 193, 184, 44, 60, 13, 40, 206, 168, 247, 39, 11, 20, 251, 12, 24, 1, 233, 203, 9, 58, 26, 252, 220, 223, 14, 244, 2, 50, 11, 227, 237, 244, 6, 31, 236, 252, 6, 36, 29, 0, 193, 36, 246, 215, 13, 3, 27, 248, 240, 193, 6, 68, 61, 246, 216, 10, 221, 245, 243, 250, 43, 13, 40, 231, 246, 17, 37, 238, 243, 199, 253, 20, 39, 3, 217, 0, 250, 16, 190, 202, 33, 58, 52, 9, 6, 248, 25, 30, 240, 243, 3, 223, 209, 13, 33, 217, 234, 38, 9, 236, 6, 246, 248, 254, 32, 9, 186, 61, 41, 240, 241, 8, 33, 230, 24, 31, 198, 20, 30, 174, 242, 19, 234, 53, 218, 215, 9, 18, 57, 11, 187, 4, 86, 18, 203, 209, 47, 53, 255, 230, 211, 245, 42, 12, 214, 240, 240, 8, 16, 229, 17, 71, 7, 196, 250, 23, 69, 253, 214, 253, 9, 246, 176, 243, 72, 15, 244, 32, 203, 190, 86, 59, 230, 234, 9, 19, 25, 234, 179, 229, 122, 81, 139, 229, 244, 253, 225, 246, 63, 47, 40, 214, 210, 7, 39, 177, 2, 98, 230, 242, 220, 39, 31, 15, 239, 224, 0, 5, 198, 3, 19, 17, 45, 206, 9, 73, 230, 193, 236, 70, 235, 224, 35, 59, 9, 165, 237, 10, 42, 16, 211, 239, 99, 249, 144, 63, 65, 242, 209, 251, 6, 226, 3, 5, 244, 19, 21, 208, 18, 66, 12, 247, 242, 39, 236, 195, 206, 2, 71, 27, 192, 12, 43, 13, 234, 218, 9, 50, 244, 210, 12, 47, 10, 207, 0, 4, 15, 189, 33, 56, 229, 230, 253, 34, 19, 252, 247, 2, 17, 6, 201, 235, 48, 13, 35, 221, 221, 221, 247, 26, 45, 1, 240, 22, 220, 28, 36, 215, 248, 81, 249, 212, 6, 243, 4, 222, 33, 195, 205, 120, 247, 188, 27, 39, 45, 17, 181, 236, 36, 26, 206, 21, 62, 22, 188, 253, 240, 28, 250, 172, 14, 80, 248, 206, 14, 3, 10, 215, 73, 36, 241, 7, 214, 186, 69, 36, 196, 13, 70, 19, 185, 223, 21, 33, 195, 248, 243, 248, 96, 0, 21, 17, 0, 175, 203, 78, 51, 180, 206, 34, 47, 245, 22, 12, 30, 224, 232, 4, 203, 7, 61, 248, 2, 247, 205, 34, 64, 31, 225, 215, 241, 224, 13, 1, 230, 5, 96, 220, 250, 16, 244, 11, 0, 5, 12, 246, 205, 31, 3, 13, 255, 245, 253, 0, 253, 27, 237, 207, 43, 14, 251, 18, 233, 9, 41, 238, 228, 241, 0, 250, 227, 69, 66, 162, 29, 70, 202, 157, 62, 51, 209, 9, 10, 10, 244, 18, 225, 20, 5, 254, 221, 216, 80, 195, 231, 59, 38, 247, 3, 244, 4, 37, 24, 229, 174, 29, 37, 237, 241, 6, 17, 9, 244, 227, 250, 4, 9, 251, 8, 4, 243, 245, 74, 7, 240, 51, 204, 208, 5, 209, 70, 43, 244, 23, 173, 250, 100, 174, 234, 35, 233, 39, 227, 246, 40, 13, 44, 241, 191, 226, 29, 5, 16, 246, 23, 246, 243, 14, 243, 32, 9, 245, 249, 73, 2, 150, 229, 28, 252, 231, 23, 30, 255, 252, 30, 235, 227, 72, 231, 222, 32, 20, 241, 235, 42, 249, 221, 2, 255, 235, 47, 254, 200, 28, 49, 191, 215, 104, 84, 194, 174, 22, 11, 202, 229, 54, 28, 28, 255, 216, 13, 56, 255, 189, 2, 52, 217, 233, 35, 241, 210, 42, 31, 246, 12, 7, 226, 249, 31, 214, 193, 6, 78, 40, 202, 30, 45, 241, 8, 233, 180, 7, 65, 243, 219, 64, 23, 183, 235, 71, 24, 210, 231, 194, 42, 79, 210, 203, 31, 52, 25, 221, 233, 43, 232, 251, 54, 16, 209, 242, 255, 254, 16, 230, 205, 21, 67, 250, 214, 254, 45, 2, 191, 52, 237, 7, 33, 247, 3, 10, 54, 193, 207, 60, 249, 189, 37, 34, 246, 1, 30, 221, 217, 29, 220, 219, 77, 27, 220, 1, 28, 21, 10, 254, 241, 246, 205, 247, 46, 244, 30, 55, 195, 206, 49, 8, 191, 25, 25, 240, 240, 18, 12, 232, 28, 5, 24, 14, 2, 232, 189, 253, 62, 10, 5, 15, 242, 237, 225, 255, 28, 245, 2, 7, 229, 17, 2, 214, 24, 76, 6, 0, 238, 239, 250, 222, 46, 251, 210, 44, 254, 232, 39, 235, 244, 14, 10, 18, 215, 211, 7, 32, 36, 10, 242, 23, 245, 222, 35, 0, 253, 0, 236, 255, 29, 247, 228, 249, 254, 37, 222, 20, 22, 252, 229, 27, 246, 246, 34, 3, 0, 4, 232, 229, 15, 14, 0, 2, 243, 8, 22, 8, 194, 23, 47, 229, 205, 15, 35, 251, 21, 237, 225, 20, 39, 209, 8, 75, 249, 174, 243, 15, 30, 30, 231, 248, 4, 7, 252, 225, 15, 39, 228, 2, 11, 233, 218, 23, 42, 14, 248, 5, 8, 221, 245, 9, 244, 19, 3, 245, 13, 13, 237, 29, 251, 1, 229, 227, 36, 249, 13, 14, 240, 236, 4, 16, 44, 244, 207, 251, 8, 0, 1, 0, 40, 24, 219, 237, 31, 235, 0, 22, 246, 17, 241, 236, 21, 0, 232, 255, 242, 1, 34, 225, 10, 35, 249, 253, 254, 28, 24, 248, 233, 251, 248, 3, 236, 253, 5, 11, 5, 247, 235, 24, 251, 245, 18, 12, 16, 244, 247, 12, 3, 254, 16, 238, 246, 252, 253, 21, 249, 12, 4, 252, 245, 239, 246, 1, 9, 23, 10, 247, 253, 9, 15, 246, 250, 1, 254, 5, 242, 247, 252, 13, 7, 251, 17, 21, 248, 238, 1, 4, 1, 235, 1, 242, 12, 32, 238, 235, 20, 12, 252, 5, 249, 26, 249, 246, 253, 247, 16, 253, 243, 2, 11, 246, 246, 19, 252, 11, 0, 244, 4, 3, 242, 248, 16, 11, 12, 0, 8, 246, 4, 238, 239, 16, 21, 255, 213, 22, 6, 243, 254, 26, 0, 244, 3, 242, 15, 15, 8, 233, 250, 31, 245, 244, 249, 5, 247, 11, 2, 242, 10, 26, 250, 227, 14, 12, 244, 231, 15, 27, 27, 254, 198, 248, 35, 7, 250, 245, 247, 253, 15, 0, 18, 6, 243, 245, 31, 6, 243, 248, 245, 14, 254, 242, 253, 12, 250, 17, 254, 232, 36, 246, 237, 0, 27, 0, 1, 253, 24, 255, 243, 11, 227, 241, 6, 25, 244, 242, 18, 11, 239, 13, 11, 251, 6, 242, 250, 5, 0, 22, 248, 250, 1, 3, 251, 0, 3, 253, 6, 242, 254, 25, 11, 231, 248, 24, 3, 255, 239, 8, 10, 232, 7, 12, 249, 242, 1, 19, 6, 11, 11, 242, 241, 1, 0, 241, 5, 9, 246, 3, 12, 5, 245, 18, 255, 240, 19, 7, 241, 239, 21, 4, 228, 3, 20, 252, 3, 11, 234, 243, 21, 13, 247, 236, 33, 255, 236, 23, 253, 251, 4, 5, 249, 239, 4, 20, 249, 16, 248, 225, 31, 254, 247, 2, 0, 12, 248, 239, 5, 3, 14, 13, 245, 1, 16, 237, 243, 14, 11, 8, 225, 253, 27, 241, 3, 11, 249, 16, 249, 232, 247, 23, 12, 221, 0, 33, 3, 253, 6, 247, 253, 0, 15, 1, 249, 7, 232, 10, 25, 3, 231, 237, 15, 255, 247, 5, 1, 235, 17, 24, 250, 10, 254, 13, 255, 248, 13, 246, 0, 0, 244, 2, 248, 239, 9, 14, 255, 251, 0, 9, 3, 238, 14, 5, 7, 4, 252, 10, 21, 1, 215, 249, 23, 249, 236, 9, 253, 240, 18, 14, 251, 7, 3, 238, 2, 18, 10, 234, 253, 17, 6, 246, 1, 3, 3, 9, 236, 251, 9, 2, 244, 244, 10, 9, 0, 241, 17, 12, 8, 0, 252, 243, 255, 0, 6, 254, 249, 9, 249, 3, 26, 16, 225, 1, 24, 238, 250, 236, 4, 10, 253, 7, 247, 252, 6, 6, 10, 1, 253, 10, 12, 227, 8, 18, 249, 246, 251, 255, 22, 253, 237, 1, 3, 1, 242, 2, 17, 250, 4, 7, 13, 5, 241, 0, 0, 147, 8, 9, 0, 250, 5, 240, 232, 11, 255, 245, 7, 234, 218, 30, 27, 215, 3, 33, 0, 232, 17, 7, 255, 23, 45, 13, 253, 246, 25, 33, 255, 227, 27, 13, 238, 4, 0, 241, 10, 245, 4, 29, 219, 235, 253, 240, 13, 234, 244, 1, 244, 0, 251, 5, 237, 34, 23, 226, 228, 38, 12, 204, 2, 42, 10, 239, 44, 14, 238, 15, 9, 27, 15, 5, 217, 244, 46, 254, 203, 18, 49, 248, 230, 247, 227, 239, 255, 9, 18, 242, 252, 231, 253, 238, 254, 251, 249, 3, 20, 246, 209, 25, 44, 3, 4, 25, 240, 248, 19, 12, 25, 241, 7, 31, 241, 9, 24, 244, 248, 26, 244, 236, 11, 7, 42, 240, 190, 28, 19, 252, 233, 254, 21, 228, 241, 227, 19, 10, 18, 235, 203, 40, 6, 167, 3, 63, 244, 228, 21, 2, 28, 240, 13, 6, 4, 58, 211, 253, 55, 254, 219, 37, 52, 215, 228, 21, 61, 243, 188, 248, 14, 35, 222, 219, 33, 5, 214, 17, 31, 229, 246, 30, 255, 211, 20, 12, 227, 16, 26, 248, 227, 14, 15, 219, 30, 26, 221, 0, 19, 233, 229, 69, 253, 206, 251, 29, 29, 238, 255, 17, 25, 235, 254, 24, 249, 242, 246, 0, 226, 247, 38, 0, 13, 0, 242, 243, 28, 42, 240, 205, 0, 15, 219, 21, 20, 228, 244, 41, 3, 235, 31, 249, 226, 21, 24, 235, 255, 11, 2, 5, 0, 59, 248, 210, 27, 32, 239, 252, 18, 230, 250, 18, 239, 242, 235, 24, 247, 6, 0, 233, 14, 226, 228, 251, 25, 244, 240, 5, 231, 18, 31, 243, 242, 24, 12, 5, 213, 33, 28, 215, 17, 4, 29, 55, 228, 239, 20, 2, 246, 243, 23, 26, 216, 238, 29, 255, 247, 249, 27, 4, 219, 248, 0, 30, 12, 215, 20, 41, 6, 193, 252, 60, 0, 185, 2, 29, 253, 0, 243, 9, 23, 0, 225, 240, 31, 35, 234, 223, 61, 2, 221, 20, 246, 10, 251, 243, 24, 7, 223, 231, 242, 2, 15, 248, 23, 249, 245, 254, 233, 25, 17, 1, 245, 31, 243, 238, 18, 247, 11, 252, 245, 253, 3, 243, 39, 238, 250, 60, 254, 252, 245, 8, 24, 253, 0, 9, 40, 252, 6, 2, 232, 244, 230, 4, 6, 230, 14, 0, 1, 241, 230, 0, 21, 250, 8, 250, 218, 28, 37, 231, 247, 5, 229, 9, 5, 252, 9, 239, 226, 18, 8, 232, 10, 3, 244, 29, 31, 8, 246, 250, 52, 10, 6, 8, 237, 18, 250, 209, 254, 38, 5, 238, 0, 34, 0, 202, 11, 49, 5, 212, 249, 38, 210, 232, 252, 41, 38, 224, 222, 6, 247, 7, 5, 204, 38, 32, 216, 1, 30, 12, 226, 244, 60, 4, 206, 7, 26, 234, 7, 19, 234, 33, 14, 234, 237, 22, 1, 235, 243, 0, 51, 234, 218, 34, 238, 9, 254, 233, 251, 25, 5, 254, 9, 244, 17, 4, 11, 250, 233, 18, 241, 22, 252, 246, 28, 241, 223, 251, 75, 244, 209, 20, 41, 2, 231, 21, 1, 24, 224, 217, 20, 38, 246, 198, 46, 26, 206, 243, 26, 20, 227, 255, 243, 220, 0, 252, 8, 3, 1, 44, 226, 229, 8, 19, 255, 33, 10, 233, 0, 243, 10, 28, 30, 24, 242, 16, 242, 9, 1, 226, 241, 26, 1, 199, 247, 37, 0, 213, 24, 35, 243, 243, 237, 1, 44, 250, 208, 240, 65, 248, 198, 13, 71, 246, 190, 6, 17, 237, 20, 9, 213, 16, 51, 214, 251, 38, 45, 254, 191, 67, 251, 255, 7, 225, 19, 53, 254, 183, 23, 45, 244, 215, 239, 41, 246, 238, 33, 226, 251, 254, 253, 244, 32, 237, 241, 41, 238, 249, 232, 240, 47, 232, 221, 247, 18, 20, 236, 17, 30, 31, 216, 7, 254, 242, 34, 252, 243, 14, 3, 247, 9, 28, 243, 234, 23, 37, 12, 207, 0, 0, 241, 30, 20, 201, 11, 38, 255, 239, 229, 34, 41, 224, 223, 240, 2, 38, 226, 9, 15, 14, 221, 226, 6, 28, 253, 227, 30, 2, 200, 4, 49, 241, 242, 21, 12, 23, 253, 213, 53, 37, 3, 213, 232, 60, 248, 214, 250, 52, 254, 255, 251, 244, 17, 7, 246, 6, 245, 246, 0, 240, 249, 229, 247, 23, 1, 217, 8, 11, 19, 30, 214, 238, 66, 33, 147, 222, 70, 252, 242, 250, 53, 246, 250, 53, 17, 241, 243, 22, 253, 37, 249, 227, 18, 250, 5, 253, 232, 27, 241, 225, 21, 50, 193, 3, 28, 19, 235, 219, 13, 28, 230, 240, 31, 10, 220, 232, 0, 37, 7, 191, 244, 16, 10, 250, 224, 52, 1, 214, 8, 47, 223, 249, 43, 237, 251, 22, 228, 1, 83, 212, 196, 20, 70, 21, 192, 254, 75, 243, 193, 38, 29, 253, 243, 251, 41, 238, 244, 13, 27, 247, 3, 252, 238, 18, 236, 228, 25, 27, 232, 210, 248, 38, 204, 221, 67, 22, 232, 236, 248, 35, 254, 212, 13, 36, 237, 233, 2, 20, 13, 20, 230, 3, 29, 246, 228, 245, 38, 23, 222, 11, 20, 20, 221, 247, 12, 27, 232, 253, 13, 247, 16, 243, 248, 29, 18, 234, 9, 243, 10, 245, 253, 255, 32, 231, 252, 0, 10, 8, 250, 255, 2, 234, 4, 40, 224, 207, 30, 58, 189, 220, 38, 50, 213, 248, 16, 21, 21, 228, 240, 16, 7, 253, 246, 14, 0, 224, 248, 13, 29, 234, 218, 24, 30, 214, 236, 34, 30, 233, 236, 61, 14, 206, 17, 53, 234, 241, 26, 45, 233, 197, 32, 0, 6, 248, 211, 26, 31, 204, 242, 58, 33, 222, 216, 20, 48, 230, 207, 17, 61, 186, 195, 67, 33, 173, 237, 23, 34, 44, 227, 239, 0, 45, 8, 203, 15, 40, 234, 234, 32, 12, 239, 255, 41, 5, 191, 34, 3, 206, 52, 43, 221, 229, 7, 13, 9, 227, 4, 0, 27, 20, 194, 220, 89, 27, 183, 242, 27, 24, 225, 246, 41, 250, 218, 2, 22, 3, 19, 222, 242, 17, 11, 2, 218, 25, 32, 239, 197, 26, 70, 246, 233, 17, 23, 244, 221, 22, 32, 251, 213, 2, 45, 5, 211, 227, 250, 45, 3, 210, 26, 33, 214, 248, 41, 15, 210, 243, 44, 234, 0, 23, 241, 253, 255, 17, 236, 254, 44, 250, 210, 42, 37, 223, 217, 252, 32, 253, 5, 248, 234, 22, 31, 254, 238, 21, 4, 240, 0, 12, 4, 209, 14, 22, 16, 249, 216, 251, 2, 29, 236, 7, 21, 230, 24, 9, 254, 219, 7, 4, 6, 23, 211, 1, 30, 255, 243, 244, 25, 3, 210, 20, 49, 7, 190, 252, 76, 248, 200, 21, 73, 204, 235, 240, 6, 78, 242, 232, 254, 37, 202, 229, 55, 37, 214, 242, 25, 6, 223, 216, 49, 44, 235, 193, 24, 21, 3, 203, 255, 46, 246, 239, 2, 0, 36, 221, 0, 10, 248, 243, 5, 241, 19, 19, 200, 16, 33, 21, 30, 242, 1, 15, 6, 234, 244, 9, 11, 14, 231, 245, 14, 19, 236, 240, 37, 1, 247, 213, 0, 14, 246, 9, 36, 19, 208, 6, 1, 17, 25, 227, 236, 41, 12, 213, 230, 20, 29, 237, 255, 4, 15, 229, 249, 28, 227, 6, 238, 49, 0, 219, 255, 11, 251, 225, 10, 251, 45, 14, 219, 246, 33, 13, 213, 46, 44, 181, 225, 55, 37, 239, 213, 16, 54, 9, 212, 227, 19, 34, 25, 188, 233, 86, 249, 185, 36, 54, 224, 242, 24, 238, 254, 234, 254, 251, 11, 3, 216, 61, 239, 221, 6, 255, 39, 243, 15, 11, 211, 251, 33, 13, 5, 0, 244, 10, 24, 242, 238, 17, 238, 250, 8, 10, 21, 212, 0, 8, 22, 251, 252, 247, 29, 243, 216, 33, 246, 230, 25, 243, 33, 12, 226, 0, 19, 235, 11, 254, 244, 28, 238, 4, 21, 213, 12, 25, 14, 239, 8, 7, 233, 4, 242, 13, 5, 2, 240, 4, 22, 243, 241, 46, 0, 224, 3, 49, 1, 236, 227, 242, 37, 245, 253, 19, 233, 15, 250, 249, 255, 0, 12, 1, 247, 239, 235, 255, 45, 13, 228, 253, 26, 0, 207, 253, 57, 25, 203, 247, 63, 218, 251, 10, 250, 41, 245, 198, 53, 24, 245, 204, 15, 83, 231, 198, 28, 28, 223, 229, 20, 233, 17, 255, 225, 35, 6, 236, 240, 48, 18, 207, 248, 63, 246, 167, 48, 26, 247, 28, 217, 58, 241, 214, 48, 14, 210, 222, 57, 32, 211, 246, 1, 19, 243, 4, 197, 23, 72, 215, 221, 48, 31, 2, 240, 241, 227, 22, 240, 21, 254, 231, 32, 229, 228, 12, 16, 8, 241, 14, 7, 6, 7, 1, 22, 5, 4, 218, 8, 18, 234, 246, 245, 49, 31, 204, 0, 39, 248, 230, 36, 13, 217, 0, 238, 16, 21, 235, 230, 24, 25, 214, 232, 25, 15, 227, 241, 22, 24, 245, 248, 38, 10, 234, 16, 222, 19, 249, 229, 24, 237, 11, 230, 1, 39, 3, 224, 253, 56, 226, 240, 6, 12, 20, 231, 0, 11, 250, 15, 247, 241, 40, 237, 230, 19, 252, 16, 17, 1, 0, 8, 253, 239, 7, 43, 0, 243, 250, 18, 4, 199, 46, 5, 248, 213, 246, 12, 247, 249, 235, 31, 14, 241, 254, 28, 15, 232, 217, 40, 49, 204, 221, 43, 27, 241, 226, 222, 30, 27, 234, 219, 30, 0, 246, 46, 255, 13, 7, 7, 237, 0, 0, 238, 6, 12, 255, 233, 32, 5, 211, 254, 16, 251, 249, 21, 10, 240, 234, 14, 84, 250, 205, 11, 28, 0, 218, 217, 39, 20, 251, 225, 240, 45, 23, 227, 226, 62, 237, 236, 254, 6, 10, 231, 0, 10, 240, 6, 33, 250, 221, 7, 9, 14, 230, 243, 30, 20, 249, 251, 0, 10, 255, 2, 34, 251, 236, 255, 9, 9, 255, 229, 31, 24, 196, 245, 236, 58, 253, 224, 6, 30, 8, 221, 217, 65, 9, 179, 229, 39, 2, 0, 243, 24, 70, 7, 209, 10, 29, 3, 209, 237, 67, 250, 196, 11, 74, 253, 6, 202, 17, 69, 194, 214, 52, 51, 233, 196, 245, 54, 10, 220, 34, 207, 248, 243, 233, 50, 28, 233, 203, 251, 40, 36, 239, 246, 32, 244, 200, 15, 216, 0, 59, 245, 228, 251, 1, 14, 24, 0, 8, 248, 244, 35, 240, 33, 10, 232, 20, 25, 1, 252, 33, 7, 12, 206, 227, 77, 246, 209, 6, 18, 25, 11, 235, 223, 23, 218, 236, 5, 11, 216, 231, 0, 48, 237, 249, 252, 17, 37, 226, 181, 23, 68, 219, 10, 16, 241, 6, 1, 17, 19, 248, 249, 247, 1, 19, 232, 205, 39, 48, 235, 247, 255, 253, 22, 220, 236, 44, 38, 249, 236, 236, 19, 2, 243, 0, 19, 255, 29, 254, 248, 17, 45, 239, 247, 60, 21, 216, 231, 60, 12, 222, 40, 37, 215, 236, 237, 9, 34, 245, 220, 4, 205, 227, 0, 226, 209, 184, 204, 193, 137, 190, 251, 22, 29, 18, 28, 36, 86, 82, 53, 51, 56, 60, 18, 38, 16, 0, 86, 69, 246, 207, 20, 57, 233, 202, 1, 36, 253, 208, 196, 245, 12, 232, 193, 0, 28, 214, 187, 0, 252, 196, 211, 249, 252, 243, 240, 230, 43, 77, 2, 213, 244, 68, 8, 227, 243, 6, 48, 233, 211, 253, 65, 27, 212, 249, 58, 32, 224, 236, 41, 47, 29, 10, 253, 16, 20, 238, 248, 0, 19, 5, 239, 6, 243, 242, 20, 221, 232, 14, 28, 12, 206, 247, 252, 210, 247, 241, 0, 26, 252, 233, 24, 9, 14, 15, 8, 7, 4, 41, 7, 193, 12, 77, 30, 21, 228, 241, 13, 237, 217, 254, 5, 227, 224, 210, 9, 20, 226, 214, 224, 30, 11, 227, 234, 6, 18, 255, 8, 15, 21, 243, 19, 43, 23, 26, 240, 46, 27, 0, 30, 0, 7, 14, 253, 234, 5, 27, 242, 242, 6, 8, 246, 228, 252, 2, 15, 1, 245, 239, 13, 254, 240, 252, 0, 2, 236, 235, 249, 243, 0, 231, 227, 14, 25, 230, 238, 11, 244, 253, 15, 19, 16, 18, 5, 8, 240, 249, 14, 225, 7, 41, 250, 231, 9, 25, 7, 7, 12, 6, 20, 0, 232, 0, 3, 255, 3, 19, 21, 0, 244, 255, 27, 238, 231, 8, 0, 250, 248, 240, 4, 18, 3, 5, 14, 24, 248, 247, 7, 238, 234, 10, 8, 1, 12, 243, 247, 247, 233, 8, 8, 1, 255, 249, 248, 241, 252, 16, 245, 245, 7, 20, 240, 245, 18, 10, 254, 7, 6, 0, 0, 249, 236, 13, 21, 239, 248, 9, 15, 6, 0, 10, 4, 10, 12, 0, 246, 13, 248, 239, 253, 4, 2, 246, 16, 253, 238, 2, 11, 252, 251, 17, 16, 253, 11, 7, 245, 0, 2, 6, 254, 251, 236, 0, 6, 239, 249, 0, 249, 1, 8, 242, 246, 7, 254, 1, 7, 252, 8, 13, 252, 1, 7, 21, 0, 171, 8, 22, 0, 3, 245, 0, 3, 242, 235, 252, 14, 28, 16, 241, 248, 2, 4, 237, 225, 245, 4, 0, 242, 9, 34, 7, 247, 5, 28, 5, 2, 239, 24, 30, 4, 241, 238, 7, 241, 230, 247, 242, 223, 12, 10, 2, 14, 249, 252, 36, 35, 244, 241, 18, 16, 8, 230, 248, 17, 22, 2, 221, 238, 10, 240, 218, 234, 36, 56, 244, 217, 249, 33, 28, 232, 253, 35, 29, 3, 240, 223, 254, 8, 9, 253, 229, 251, 6, 9, 5, 4, 9, 5, 18, 242, 223, 2, 230, 241, 14, 10, 34, 35, 245, 0, 9, 14, 0, 224, 229, 6, 4, 6, 248, 243, 14, 15, 245, 204, 23, 38, 4, 255, 3, 18, 24, 235, 255, 14, 239, 3, 208, 210, 4, 37, 31, 10, 241, 8, 12, 11, 18, 244, 253, 240, 254, 251, 237, 9, 30, 11, 228, 245, 9, 16, 230, 225, 244, 5, 12, 32, 51, 0, 227, 15, 30, 4, 247, 247, 242, 230, 249, 19, 3, 248, 252, 220, 222, 54, 8, 218, 248, 28, 45, 31, 244, 247, 37, 220, 2, 15, 244, 244, 17, 13, 243, 232, 8, 39, 177, 206, 76, 250, 211, 249, 16, 39, 18, 251, 0, 0, 42, 34, 220, 244, 6, 232, 238, 1, 23, 54, 237, 190, 13, 20, 226, 242, 2, 13, 227, 246, 42, 16, 9, 0, 253, 23, 24, 232, 249, 246, 235, 14, 20, 247, 239, 47, 2, 218, 251, 17, 13, 244, 233, 229, 6, 34, 250, 236, 255, 18, 245, 7, 6, 0, 10, 32, 5, 237, 6, 1, 5, 18, 16, 246, 221, 239, 4, 244, 241, 249, 13, 235, 218, 18, 33, 3, 42, 20, 11, 13, 232, 239, 5, 30, 255, 229, 1, 25, 21, 200, 237, 25, 225, 208, 245, 7, 9, 40, 23, 3, 27, 44, 231, 236, 25, 245, 231, 236, 246, 244, 35, 16, 217, 13, 18, 255, 6, 25, 200, 237, 44, 21, 220, 250, 37, 234, 16, 23, 231, 229, 238, 6, 233, 44, 32, 244, 254, 247, 40, 38, 244, 209, 247, 3, 243, 226, 254, 41, 26, 222, 254, 21, 34, 0, 185, 232, 32, 40, 12, 206, 215, 72, 33, 222, 6, 19, 239, 254, 1, 242, 1, 5, 29, 14, 220, 248, 35, 233, 252, 210, 239, 21, 234, 28, 37, 230, 34, 23, 242, 38, 0, 5, 248, 194, 234, 24, 48, 253, 192, 1, 25, 255, 240, 227, 13, 60, 244, 198, 38, 47, 38, 241, 202, 19, 44, 227, 207, 232, 42, 15, 207, 2, 20, 17, 252, 247, 242, 21, 47, 7, 247, 241, 232, 12, 64, 238, 156, 8, 35, 206, 53, 14, 167, 61, 65, 188, 240, 38, 67, 233, 208, 28, 2, 19, 13, 207, 1, 253, 208, 12, 243, 220, 81, 37, 227, 10, 232, 17, 25, 12, 2, 175, 19, 66, 200, 207, 74, 23, 222, 27, 210, 226, 40, 226, 243, 87, 26, 203, 243, 21, 41, 10, 202, 244, 0, 3, 236, 247, 251, 253, 34, 16, 254, 7, 8, 229, 236, 30, 74, 7, 177, 231, 49, 233, 224, 36, 255, 228, 22, 251, 6, 54, 178, 16, 45, 213, 6, 38, 212, 230, 71, 26, 3, 215, 232, 11, 209, 219, 86, 50, 193, 219, 65, 77, 218, 168, 10, 44, 15, 235, 0, 239, 232, 68, 242, 197, 35, 30, 189, 4, 49, 34, 214, 205, 33, 71, 10, 181, 223, 47, 28, 249, 23, 10, 180, 2, 28, 235, 44, 11, 223, 222, 250, 32, 20, 212, 213, 47, 59, 254, 248, 249, 15, 221, 6, 46, 244, 236, 34, 236, 215, 36, 239, 215, 20, 57, 211, 231, 43, 226, 17, 55, 3, 213, 254, 20, 203, 32, 38, 182, 216, 103, 54, 197, 18, 18, 201, 243, 60, 208, 240, 1, 206, 27, 61, 47, 224, 196, 229, 40, 81, 242, 190, 238, 15, 51, 25, 229, 248, 216, 40, 56, 175, 240, 0, 4, 250, 231, 81, 60, 166, 182, 75, 68, 248, 176, 4, 52, 237, 251, 245, 34, 29, 206, 220, 4, 77, 205, 220, 1, 58, 23, 200, 238, 56, 70, 198, 208, 48, 35, 187, 197, 47, 50, 225, 183, 43, 92, 223, 232, 17, 24, 232, 220, 235, 24, 40, 226, 5, 255, 49, 241, 210, 24, 21, 237, 1, 251, 215, 46, 32, 217, 244, 25, 18, 236, 20, 221, 231, 17, 38, 0, 203, 29, 29, 250, 229, 18, 26, 254, 33, 203, 249, 12, 254, 238, 251, 39, 243, 232, 246, 19, 7, 255, 28, 214, 62, 27, 169, 2, 19, 24, 37, 193, 224, 87, 246, 247, 204, 210, 94, 254, 200, 246, 17, 58, 248, 239, 8, 27, 23, 178, 254, 71, 255, 207, 220, 36, 58, 239, 146, 252, 123, 3, 192, 252, 252, 53, 8, 196, 38, 27, 240, 16, 231, 213, 72, 34, 195, 234, 236, 11, 43, 224, 1, 10, 228, 50, 20, 174, 251, 63, 255, 253, 1, 51, 1, 229, 209, 251, 55, 15, 195, 228, 45, 37, 224, 176, 27, 78, 224, 232, 11, 37, 12, 1, 225, 237, 255, 46, 35, 216, 246, 24, 1, 211, 249, 241, 20, 46, 233, 238, 19, 26, 245, 227, 248, 8, 24, 227, 5, 55, 202, 15, 17, 219, 23, 20, 12, 211, 222, 38, 70, 11, 207, 205, 41, 40, 219, 238, 232, 255, 31, 244, 196, 46, 93, 220, 205, 236, 75, 56, 173, 217, 56, 48, 236, 189, 244, 60, 18, 249, 0, 209, 1, 40, 229, 240, 14, 234, 233, 33, 14, 1, 2, 16, 255, 1, 31, 245, 7, 228, 245, 41, 24, 242, 224, 233, 228, 16, 41, 247, 181, 21, 26, 10, 7, 230, 72, 41, 204, 237, 50, 248, 249, 176, 189, 117, 70, 167, 180, 59, 110, 240, 200, 235, 19, 28, 233, 207, 247, 70, 40, 195, 197, 76, 79, 188, 203, 250, 46, 9, 194, 4, 37, 64, 249, 211, 34, 0, 245, 251, 212, 18, 15, 213, 13, 9, 228, 17, 75, 246, 186, 21, 66, 238, 216, 203, 30, 94, 220, 210, 33, 6, 14, 18, 173, 27, 65, 141, 249, 74, 13, 22, 219, 240, 28, 1, 21, 244, 195, 29, 7, 211, 38, 255, 240, 62, 240, 243, 79, 232, 205, 251, 247, 23, 241, 31, 15, 205, 245, 255, 34, 5, 209, 254, 12, 14, 11, 236, 19, 20, 9, 20, 231, 7, 55, 216, 215, 3, 34, 232, 195, 28, 246, 250, 54, 226, 249, 52, 226, 255, 255, 236, 30, 2, 41, 40, 172, 27, 63, 214, 161, 14, 99, 234, 203, 187, 48, 91, 206, 176, 27, 89, 23, 211, 209, 28, 25, 215, 232, 67, 59, 250, 170, 8, 94, 216, 172, 239, 47, 50, 239, 230, 227, 14, 37, 194, 1, 61, 42, 238, 188, 10, 36, 249, 3, 225, 45, 53, 202, 196, 18, 101, 247, 156, 231, 46, 50, 232, 204, 15, 27, 42, 232, 176, 32, 70, 240, 193, 5, 50, 70, 236, 184, 240, 27, 23, 2, 225, 7, 15, 13, 28, 226, 216, 0, 35, 227, 245, 5, 20, 233, 236, 32, 9, 18, 32, 229, 250, 81, 247, 162, 2, 58, 254, 210, 230, 22, 255, 244, 249, 243, 49, 27, 204, 3, 59, 22, 193, 211, 67, 254, 17, 1, 202, 16, 61, 215, 227, 51, 0, 223, 203, 40, 52, 169, 49, 29, 192, 55, 16, 198, 252, 53, 30, 207, 196, 34, 26, 28, 19, 211, 6, 43, 226, 220, 251, 24, 2, 238, 247, 22, 249, 7, 25, 209, 46, 20, 196, 27, 26, 185, 8, 30, 235, 3, 42, 25, 217, 2, 4, 5, 3, 252, 226, 5, 55, 222, 193, 50, 41, 4, 211, 208, 24, 74, 247, 135, 16, 112, 255, 175, 9, 75, 43, 192, 198, 101, 31, 158, 227, 39, 43, 225, 237, 249, 26, 37, 225, 166, 23, 66, 216, 220, 30, 32, 0, 2, 48, 248, 13, 40, 199, 202, 71, 246, 198, 24, 19, 235, 227, 10, 34, 25, 219, 210, 208, 63, 35, 228, 21, 245, 16, 48, 26, 207, 7, 34, 212, 0, 20, 236, 2, 10, 218, 233, 27, 3, 223, 242, 34, 19, 14, 240, 230, 20, 24, 4, 4, 14, 245, 250, 15, 2, 233, 2, 25, 208, 253, 62, 224, 232, 11, 221, 35, 51, 197, 234, 51, 214, 0, 245, 43, 65, 154, 21, 68, 221, 23, 251, 237, 26, 237, 240, 39, 209, 221, 13, 242, 67, 29, 201, 225, 30, 37, 233, 223, 250, 79, 242, 192, 33, 8, 24, 7, 215, 255, 57, 242, 213, 20, 241, 25, 247, 219, 42, 0, 254, 233, 214, 30, 43, 248, 218, 42, 19, 218, 249, 33, 22, 0, 210, 27, 16, 213, 30, 5, 208, 11, 250, 14, 67, 223, 194, 42, 255, 220, 29, 226, 1, 76, 255, 178, 32, 74, 245, 207, 219, 17, 83, 238, 176, 246, 47, 42, 230, 194, 5, 58, 29, 213, 190, 39, 107, 231, 131, 39, 113, 240, 141, 2, 84, 15, 223, 193, 32, 59, 245, 218, 250, 41, 33, 232, 181, 48, 24, 217, 228, 237, 74, 48, 174, 245, 52, 0, 247, 233, 249, 73, 246, 203, 38, 7, 249, 21, 249, 211, 1, 44, 230, 227, 10, 254, 4, 254, 26, 245, 228, 9, 43, 4, 217, 3, 64, 251, 234, 22, 254, 4, 236, 237, 20, 249, 212, 19, 0, 226, 55, 236, 196, 53, 44, 209, 248, 29, 9, 24, 252, 9, 19, 0, 236, 231, 244, 33, 1, 221, 25, 240, 233, 17, 246, 236, 3, 25, 15, 4, 237, 2, 38, 254, 249, 12, 255, 6, 231, 250, 37, 242, 253, 12, 209, 237, 42, 49, 204, 224, 30, 3, 246, 255, 30, 233, 239, 17, 17, 17, 0, 245, 9, 12, 3, 230, 2, 251, 3, 8, 221, 4, 55, 202, 0, 23, 230, 59, 201, 206, 97, 33, 198, 227, 18, 45, 1, 213, 17, 38, 228, 202, 21, 42, 232, 241, 8, 5, 28, 20, 213, 229, 40, 17, 228, 251, 12, 231, 19, 11, 236, 6, 35, 10, 198, 251, 47, 247, 232, 23, 4, 238, 27, 2, 225, 10, 20, 223, 250, 60, 239, 209, 12, 3, 230, 61, 30, 157, 18, 58, 251, 244, 218, 32, 28, 211, 16, 31, 235, 20, 6, 209, 7, 239, 0, 34, 221, 238, 51, 4, 225, 23, 7, 248, 7, 3, 244, 15, 13, 248, 12, 0, 22, 238, 215, 231, 21, 14, 232, 227, 33, 53, 197, 248, 59, 241, 241, 40, 10, 247, 0, 26, 13, 186, 13, 30, 189, 21, 9, 197, 55, 31, 237, 237, 225, 49, 16, 213, 31, 18, 240, 19, 236, 253, 59, 252, 181, 243, 71, 14, 187, 237, 40, 28, 248, 236, 2, 6, 248, 12, 6, 230, 16, 10, 228, 4, 18, 251, 7, 32, 248, 202, 21, 41, 1, 234, 244, 22, 235, 249, 21, 246, 10, 3, 239, 239, 23, 32, 193, 212, 70, 42, 222, 253, 17, 23, 237, 225, 18, 24, 24, 204, 227, 62, 20, 197, 234, 25, 24, 12, 224, 250, 18, 249, 8, 231, 255, 52, 240, 225, 9, 21, 24, 235, 220, 31, 44, 212, 227, 37, 24, 243, 0, 2, 226, 245, 4, 238, 25, 38, 233, 227, 17, 254, 16, 13, 226, 12, 29, 243, 221, 36, 47, 208, 233, 17, 18, 0, 234, 250, 1, 18, 3, 221, 0, 25, 2, 230, 252, 19, 24, 10, 234, 2, 46, 236, 218, 9, 232, 54, 23, 179, 4, 48, 245, 253, 232, 0, 44, 245, 224, 7, 253, 15, 5, 207, 28, 73, 226, 239, 245, 6, 55, 224, 205, 33, 9, 10, 226, 232, 36, 234, 20, 32, 221, 245, 22, 236, 250, 41, 248, 230, 32, 20, 227, 231, 16, 46, 238, 215, 21, 10, 10, 0, 228, 230, 50, 10, 218, 5, 0, 254, 11, 0, 242, 21, 26, 215, 222, 84, 47, 185, 232, 28, 15, 246, 243, 252, 217, 14, 25, 244, 236, 29, 39, 192, 8, 59, 247, 243, 246, 20, 6, 228, 250, 39, 227, 250, 26, 246, 21, 226, 224, 22, 24, 3, 226, 231, 50, 21, 217, 252, 32, 16, 243, 228, 23, 56, 201, 201, 36, 14, 23, 248, 213, 31, 14, 243, 3, 218, 12, 41, 238, 224, 22, 12, 10, 243, 233, 36, 13, 244, 252, 237, 26, 27, 219, 240, 25, 9, 248, 235, 247, 17, 12, 238, 246, 27, 10, 242, 246, 6, 22, 239, 6, 28, 236, 234, 1, 36, 11, 219, 248, 26, 245, 2, 4, 225, 19, 6, 252, 243, 0, 9, 33, 233, 217, 76, 11, 201, 255, 39, 240, 245, 245, 22, 10, 228, 16, 251, 253, 27, 231, 219, 54, 0, 229, 7, 18, 11, 233, 249, 14, 20, 247, 230, 18, 6, 10, 245, 220, 43, 0, 229, 5, 16, 18, 244, 240, 240, 21, 27, 222, 254, 14, 244, 10, 17, 242, 253, 17, 3, 0, 239, 1, 9, 246, 236, 16, 15, 253, 0, 233, 30, 19, 235, 246, 248, 28, 3, 220, 7, 6, 26, 0, 211, 21, 32, 249, 236, 247, 22, 14, 241, 244, 251, 22, 250, 244, 14, 252, 247, 5, 1, 14, 1, 238, 24, 4, 236, 5, 10, 243, 0, 153, 7, 51, 0, 12, 9, 4, 3, 255, 18, 20, 238, 7, 32, 4, 241, 4, 14, 2, 0, 26, 2, 233, 1, 17, 25, 12, 237, 252, 34, 14, 245, 252, 5, 24, 12, 3, 237, 251, 36, 2, 233, 0, 24, 13, 237, 246, 21, 9, 7, 3, 249, 17, 13, 251, 9, 9, 10, 11, 241, 12, 33, 235, 234, 33, 26, 234, 253, 23, 6, 254, 2, 11, 6, 6, 16, 13, 249, 12, 22, 0, 8, 9, 249, 1, 11, 4, 255, 12, 11, 2, 255, 5, 32, 11, 244, 16, 29, 4, 244, 11, 23, 244, 0, 36, 3, 247, 1, 251, 3, 40, 16, 228, 0, 28, 16, 251, 251, 13, 22, 9, 0, 238, 5, 35, 2, 253, 4, 2, 11, 8, 236, 245, 23, 27, 251, 246, 254, 10, 13, 7, 234, 10, 55, 243, 220, 4, 13, 21, 20, 232, 233, 24, 22, 252, 242, 12, 24, 250, 245, 255, 8, 12, 8, 248, 6, 25, 13, 233, 251, 35, 27, 239, 245, 15, 26, 0, 247, 13, 12, 3, 3, 250, 253, 7, 15, 3, 254, 13, 250, 235, 14, 14, 0, 25, 230, 252, 45, 243, 0, 29, 3, 0, 255, 12, 5, 252, 251, 28, 22, 235, 4, 21, 250, 10, 6, 253, 20, 19, 254, 253, 24, 22, 251, 0, 11, 7, 1, 0, 6, 250, 0, 33, 3, 236, 253, 16, 16, 252, 249, 3, 7, 21, 8, 242, 14, 25, 239, 14, 13, 232, 5, 17, 20, 8, 241, 245, 28, 8, 246, 17, 5, 3, 5, 246, 252, 14, 20, 10, 221, 16, 57, 238, 239, 3, 12, 26, 240, 253, 1, 248, 31, 4, 229, 25, 17, 249, 252, 21, 22, 241, 253, 18, 3, 255, 0, 251, 27, 6, 217, 19, 7, 244, 22, 245, 247, 12, 8, 254, 19, 6, 246, 10, 11, 8, 0, 234, 4, 27, 2, 254, 244, 13, 48, 1, 233, 3, 25, 5, 249, 1, 35, 6, 1, 7, 237, 24, 39, 249, 231, 22, 27, 242, 247, 17, 7, 11, 31, 234, 251, 22, 9, 20, 244, 250, 32, 247, 5, 21, 0, 21, 247, 246, 25, 5, 2, 25, 11, 243, 20, 13, 246, 23, 253, 6, 29, 253, 4, 17, 1, 10, 253, 250, 19, 5, 255, 0, 250, 21, 35, 233, 243, 32, 37, 254, 235, 13, 19, 0, 0, 255, 19, 255, 247, 22, 4, 250, 13, 249, 245, 31, 2, 250, 2, 254, 0, 38, 29, 231, 248, 32, 13, 241, 6, 6, 238, 20, 229, 227, 58, 16, 212, 253, 27, 12, 230, 253, 34, 20, 1, 240, 246, 7, 26, 9, 244, 252, 253, 249, 6, 4, 10, 0, 13, 15, 5, 254, 248, 30, 48, 225, 220, 42, 13, 252, 237, 215, 31, 68, 245, 218, 13, 55, 23, 197, 244, 52, 41, 253, 232, 2, 28, 17, 242, 0, 17, 255, 0, 245, 10, 43, 245, 220, 21, 59, 237, 223, 31, 38, 4, 244, 232, 19, 33, 2, 248, 243, 28, 20, 253, 252, 242, 37, 19, 214, 13, 24, 0, 12, 7, 239, 14, 27, 229, 250, 24, 7, 1, 241, 255, 33, 5, 233, 247, 40, 36, 245, 236, 2, 36, 17, 240, 251, 251, 14, 30, 240, 228, 21, 15, 8, 8, 228, 5, 43, 248, 253, 22, 19, 249, 238, 7, 28, 18, 222, 252, 21, 15, 4, 241, 238, 22, 19, 244, 248, 11, 3, 238, 43, 29, 236, 0, 17, 43, 7, 227, 18, 16, 6, 21, 227, 231, 31, 25, 244, 245, 244, 24, 21, 235, 0, 29, 2, 3, 18, 236, 252, 40, 0, 241, 9, 255, 31, 11, 214, 6, 27, 4, 248, 243, 246, 39, 9, 229, 8, 21, 9, 14, 244, 232, 30, 32, 248, 239, 3, 13, 239, 11, 16, 233, 11, 35, 250, 244, 24, 18, 235, 8, 30, 10, 241, 250, 32, 1, 255, 20, 244, 249, 28, 19, 247, 0, 10, 3, 18, 22, 218, 7, 42, 249, 5, 13, 244, 0, 247, 5, 31, 255, 251, 3, 5, 4, 10, 0, 3, 31, 242, 241, 13, 28, 6, 236, 21, 45, 250, 235, 12, 21, 15, 246, 6, 24, 251, 244, 254, 23, 13, 226, 254, 41, 239, 0, 26, 235, 7, 29, 255, 233, 229, 49, 22, 218, 10, 10, 2, 25, 254, 228, 14, 25, 243, 250, 6, 1, 9, 251, 250, 32, 255, 247, 31, 245, 242, 20, 10, 246, 30, 27, 222, 236, 46, 24, 209, 4, 30, 249, 0, 15, 236, 244, 36, 29, 240, 254, 35, 3, 241, 10, 9, 0, 222, 8, 41, 251, 211, 7, 43, 249, 252, 240, 245, 46, 6, 247, 5, 250, 43, 250, 213, 41, 28, 233, 6, 12, 38, 4, 211, 22, 51, 245, 233, 248, 29, 41, 249, 228, 0, 59, 36, 217, 239, 31, 20, 27, 222, 215, 62, 2, 211, 250, 37, 21, 243, 238, 2, 26, 5, 3, 0, 254, 3, 255, 5, 251, 15, 243, 254, 34, 13, 246, 255, 19, 24, 249, 230, 3, 35, 14, 244, 254, 8, 34, 13, 9, 251, 218, 18, 64, 222, 195, 14, 26, 24, 232, 235, 14, 11, 8, 236, 234, 56, 20, 204, 21, 36, 249, 8, 249, 249, 25, 237, 255, 18, 240, 14, 12, 230, 31, 41, 252, 227, 13, 29, 250, 229, 12, 37, 1, 235, 18, 245, 235, 67, 9, 227, 5, 11, 243, 9, 15, 246, 9, 21, 10, 248, 252, 251, 41, 37, 241, 248, 254, 11, 37, 18, 239, 5, 15, 20, 10, 250, 10, 6, 250, 27, 2, 237, 22, 0, 0, 26, 243, 1, 33, 231, 9, 46, 235, 245, 9, 30, 30, 186, 244, 60, 27, 7, 219, 251, 54, 24, 255, 232, 20, 58, 246, 195, 11, 40, 18, 2, 200, 0, 60, 42, 225, 219, 32, 32, 4, 232, 254, 5, 13, 37, 225, 247, 42, 255, 227, 19, 10, 230, 5, 26, 236, 255, 19, 8, 10, 21, 242, 238, 36, 3, 9, 1, 243, 53, 29, 200, 245, 43, 246, 25, 1, 188, 17, 48, 233, 0, 7, 240, 28, 12, 233, 10, 17, 0, 250, 17, 31, 237, 219, 30, 38, 12, 249, 237, 0, 38, 249, 9, 12, 224, 60, 17, 164, 60, 69, 186, 246, 2, 12, 106, 244, 132, 46, 76, 41, 222, 179, 29, 40, 30, 238, 186, 37, 78, 238, 227, 0, 40, 33, 7, 250, 249, 21, 27, 237, 8, 47, 202, 26, 57, 239, 25, 236, 237, 60, 21, 231, 223, 21, 81, 219, 184, 42, 30, 0, 25, 255, 224, 15, 38, 250, 232, 250, 0, 32, 7, 228, 22, 9, 244, 2, 23, 255, 230, 20, 17, 255, 249, 243, 37, 42, 244, 226, 0, 25, 5, 245, 12, 12, 242, 15, 41, 228, 203, 64, 67, 199, 241, 34, 10, 22, 238, 231, 33, 13, 250, 243, 235, 40, 21, 193, 10, 46, 244, 242, 253, 24, 40, 251, 232, 244, 35, 50, 223, 212, 37, 47, 229, 232, 14, 252, 39, 22, 231, 0, 48, 2, 226, 27, 35, 233, 2, 24, 12, 1, 209, 37, 53, 221, 246, 27, 10, 27, 253, 252, 15, 250, 2, 6, 5, 50, 247, 212, 26, 37, 1, 239, 244, 44, 30, 236, 7, 247, 30, 34, 228, 242, 4, 45, 0, 197, 22, 59, 255, 233, 254, 1, 23, 24, 240, 237, 47, 20, 242, 236, 32, 21, 237, 35, 4, 209, 13, 62, 3, 229, 15, 253, 10, 20, 235, 2, 39, 224, 255, 38, 243, 8, 244, 227, 73, 17, 203, 11, 38, 243, 6, 2, 255, 35, 246, 10, 246, 242, 61, 235, 206, 61, 254, 232, 39, 248, 246, 42, 13, 226, 253, 37, 13, 5, 9, 237, 24, 47, 227, 237, 51, 19, 232, 18, 7, 238, 27, 17, 235, 8, 14, 228, 21, 11, 236, 37, 2, 243, 12, 9, 8, 27, 0, 231, 3, 22, 253, 229, 38, 1, 221, 31, 13, 251, 8, 248, 17, 255, 250, 32, 5, 14, 30, 232, 246, 50, 0, 241, 23, 230, 28, 24, 208, 32, 55, 217, 214, 74, 45, 182, 1, 59, 19, 246, 233, 25, 4, 6, 7, 214, 40, 29, 241, 252, 0, 16, 21, 16, 218, 14, 61, 242, 245, 7, 0, 43, 12, 235, 10, 3, 6, 30, 240, 245, 49, 243, 219, 16, 66, 11, 175, 2, 101, 238, 236, 10, 212, 50, 100, 166, 173, 111, 43, 204, 232, 10, 50, 1, 225, 11, 20, 4, 254, 243, 8, 35, 235, 220, 17, 22, 241, 242, 34, 6, 243, 6, 248, 243, 44, 0, 230, 6, 15, 238, 0, 9, 0, 35, 235, 234, 51, 249, 218, 23, 11, 7, 250, 223, 24, 33, 7, 228, 230, 58, 27, 201, 15, 25, 248, 31, 27, 218, 212, 78, 56, 189, 200, 68, 66, 221, 212, 253, 34, 62, 218, 221, 32, 13, 6, 7, 7, 8, 14, 251, 6, 23, 30, 210, 250, 62, 19, 230, 227, 29, 29, 252, 245, 60, 246, 173, 65, 92, 206, 232, 54, 17, 230, 36, 27, 194, 14, 52, 208, 250, 50, 244, 197, 38, 59, 212, 253, 12, 7, 5, 249, 239, 28, 10, 0, 227, 0, 70, 241, 226, 27, 21, 12, 225, 241, 27, 18, 3, 226, 7, 33, 223, 1, 34, 11, 7, 224, 14, 56, 248, 220, 33, 10, 247, 247, 247, 42, 228, 208, 44, 51, 239, 237, 245, 22, 56, 202, 245, 54, 241, 1, 2, 245, 43, 251, 220, 18, 29, 246, 232, 33, 31, 236, 233, 6, 57, 5, 221, 250, 0, 32, 22, 200, 35, 54, 217, 10, 2, 233, 60, 35, 211, 0, 27, 26, 253, 228, 0, 35, 36, 254, 208, 4, 81, 223, 228, 58, 252, 236, 29, 231, 16, 50, 212, 245, 17, 33, 30, 191, 245, 72, 20, 237, 240, 243, 43, 27, 252, 3, 252, 249, 18, 48, 250, 247, 32, 252, 232, 42, 11, 210, 39, 53, 250, 196, 8, 57, 250, 243, 34, 242, 254, 45, 230, 242, 3, 30, 28, 239, 232, 248, 41, 15, 235, 31, 233, 233, 48, 3, 234, 2, 13, 20, 14, 254, 10, 235, 247, 40, 246, 28, 241, 224, 41, 18, 254, 224, 6, 39, 17, 244, 222, 0, 47, 12, 223, 11, 33, 246, 255, 0, 243, 30, 32, 235, 219, 35, 12, 241, 38, 253, 224, 30, 34, 237, 223, 25, 30, 252, 2, 247, 27, 252, 240, 45, 247, 237, 7, 17, 16, 250, 222, 17, 69, 230, 224, 37, 7, 53, 247, 198, 56, 34, 215, 25, 10, 238, 42, 11, 238, 22, 239, 31, 29, 223, 12, 1, 17, 6, 240, 39, 225, 238, 76, 244, 216, 6, 33, 32, 239, 241, 46, 227, 20, 52, 174, 4, 61, 246, 12, 249, 1, 56, 233, 234, 38, 239, 12, 56, 221, 215, 33, 17, 252, 7, 2, 9, 6, 233, 251, 44, 21, 222, 219, 35, 42, 215, 255, 7, 6, 40, 0, 188, 15, 76, 245, 193, 29, 25, 23, 8, 182, 44, 68, 240, 236, 240, 53, 10, 225, 18, 13, 11, 247, 16, 19, 2, 239, 204, 71, 69, 188, 229, 30, 35, 0, 2, 14, 236, 15, 32, 228, 249, 49, 3, 218, 5, 31, 2, 0, 11, 23, 237, 4, 46, 204, 233, 66, 250, 217, 22, 41, 2, 225, 27, 47, 234, 252, 10, 16, 32, 207, 1, 42, 242, 20, 254, 219, 33, 33, 214, 18, 53, 242, 10, 6, 234, 30, 19, 235, 9, 42, 242, 224, 32, 0, 243, 16, 251, 11, 23, 244, 253, 40, 252, 250, 35, 247, 246, 16, 251, 23, 249, 239, 13, 0, 0, 0, 172, 10, 36, 0, 2, 26, 14, 253, 249, 242, 249, 12, 10, 245, 245, 5, 17, 11, 247, 248, 3, 4, 242, 243, 251, 13, 38, 2, 239, 229, 238, 18, 32, 29, 251, 215, 251, 10, 254, 22, 5, 236, 0, 253, 249, 4, 245, 17, 37, 235, 225, 25, 14, 241, 235, 238, 21, 50, 5, 223, 245, 255, 4, 21, 251, 250, 15, 8, 224, 230, 4, 10, 6, 25, 39, 242, 232, 242, 238, 21, 16, 0, 249, 237, 8, 23, 246, 248, 2, 6, 15, 248, 241, 248, 246, 251, 24, 41, 19, 244, 218, 239, 0, 2, 23, 20, 229, 0, 16, 249, 252, 251, 243, 248, 2, 1, 17, 32, 19, 246, 233, 244, 16, 231, 228, 23, 35, 20, 0, 20, 236, 198, 228, 14, 29, 248, 3, 25, 26, 11, 227, 236, 252, 246, 5, 19, 20, 252, 238, 24, 15, 247, 249, 243, 236, 249, 14, 252, 0, 23, 15, 248, 228, 10, 11, 242, 244, 9, 42, 21, 247, 244, 220, 240, 21, 0, 254, 15, 14, 15, 234, 224, 255, 249, 249, 16, 32, 43, 13, 223, 209, 247, 27, 0, 248, 17, 23, 230, 215, 19, 42, 7, 253, 240, 228, 6, 255, 239, 29, 31, 27, 36, 223, 163, 202, 26, 61, 27, 12, 10, 4, 252, 222, 193, 239, 45, 44, 31, 40, 247, 167, 198, 37, 52, 11, 217, 226, 43, 54, 247, 244, 233, 231, 235, 228, 25, 94, 53, 235, 211, 190, 221, 25, 43, 37, 12, 245, 18, 16, 205, 169, 212, 34, 75, 50, 27, 0, 213, 227, 2, 255, 248, 0, 5, 6, 11, 48, 25, 221, 218, 225, 242, 7, 8, 9, 36, 25, 249, 230, 224, 4, 5, 4, 8, 42, 9, 216, 243, 25, 29, 239, 241, 17, 237, 208, 240, 19, 48, 30, 242, 252, 7, 251, 245, 217, 201, 23, 75, 51, 20, 238, 222, 229, 249, 240, 242, 24, 28, 3, 2, 250, 251, 16, 248, 236, 237, 1, 46, 22, 246, 205, 235, 25, 24, 30, 254, 16, 14, 209, 230, 12, 235, 226, 28, 40, 7, 0, 19, 4, 225, 223, 5, 16, 251, 10, 9, 4, 4, 252, 18, 252, 235, 226, 238, 14, 53, 51, 249, 205, 211, 250, 13, 5, 15, 42, 31, 245, 215, 219, 239, 14, 42, 9, 253, 23, 17, 224, 212, 246, 3, 244, 20, 46, 4, 227, 22, 41, 230, 216, 253, 241, 255, 35, 11, 1, 248, 241, 9, 244, 248, 58, 15, 206, 221, 11, 58, 253, 218, 0, 0, 238, 250, 69, 21, 189, 239, 53, 31, 242, 242, 236, 199, 219, 40, 71, 35, 20, 8, 189, 203, 19, 255, 243, 1, 21, 51, 43, 30, 180, 141, 25, 52, 245, 4, 33, 29, 0, 233, 234, 239, 238, 36, 57, 222, 223, 44, 14, 218, 222, 252, 5, 30, 34, 14, 10, 240, 224, 222, 229, 12, 36, 20, 11, 16, 247, 222, 252, 26, 6, 216, 214, 49, 76, 18, 228, 183, 215, 33, 38, 237, 29, 77, 232, 131, 206, 37, 69, 55, 38, 242, 198, 227, 251, 28, 15, 217, 222, 26, 27, 12, 47, 253, 196, 240, 29, 254, 224, 1, 37, 1, 245, 55, 7, 193, 204, 250, 40, 76, 26, 179, 232, 32, 240, 244, 36, 37, 239, 225, 242, 7, 39, 252, 200, 221, 37, 51, 7, 247, 253, 7, 16, 1, 230, 214, 234, 254, 56, 71, 17, 223, 200, 215, 246, 54, 47, 232, 218, 27, 39, 244, 197, 231, 43, 49, 0, 232, 2, 1, 243, 251, 17, 29, 2, 219, 208, 1, 55, 38, 223, 170, 254, 106, 48, 226, 246, 252, 213, 218, 6, 43, 49, 0, 198, 246, 25, 8, 10, 252, 234, 249, 24, 33, 11, 192, 196, 54, 52, 10, 241, 196, 237, 9, 26, 55, 14, 2, 10, 212, 209, 24, 18, 238, 247, 0, 29, 16, 241, 255, 0, 239, 241, 251, 0, 248, 40, 71, 4, 241, 8, 214, 166, 242, 68, 43, 255, 242, 0, 8, 249, 230, 231, 3, 41, 66, 10, 218, 210, 230, 244, 253, 60, 68, 237, 208, 249, 2, 243, 251, 255, 28, 37, 254, 226, 5, 17, 220, 218, 14, 29, 13, 15, 12, 241, 246, 12, 243, 227, 6, 14, 248, 36, 15, 217, 248, 250, 254, 34, 39, 245, 223, 224, 216, 8, 87, 68, 234, 233, 227, 222, 227, 244, 239, 9, 94, 46, 27, 18, 171, 146, 239, 30, 26, 60, 80, 5, 182, 198, 244, 42, 24, 219, 249, 45, 42, 224, 218, 18, 253, 227, 251, 17, 21, 244, 238, 36, 25, 241, 10, 28, 237, 211, 206, 237, 61, 79, 255, 230, 20, 235, 201, 232, 25, 49, 253, 222, 17, 0, 218, 20, 39, 12, 251, 227, 18, 23, 216, 219, 12, 11, 67, 18, 211, 4, 234, 234, 11, 9, 248, 241, 0, 19, 15, 0, 10, 8, 243, 240, 249, 29, 5, 242, 8, 252, 240, 23, 7, 219, 254, 34, 254, 242, 31, 14, 221, 233, 230, 235, 25, 61, 37, 250, 12, 245, 196, 221, 0, 35, 38, 3, 243, 220, 254, 56, 30, 217, 225, 2, 5, 230, 238, 66, 41, 220, 7, 236, 202, 28, 43, 239, 16, 23, 224, 227, 38, 26, 202, 217, 22, 34, 23, 254, 250, 255, 229, 241, 31, 20, 250, 12, 251, 228, 241, 235, 16, 52, 252, 254, 2, 8, 11, 218, 199, 25, 79, 0, 192, 251, 34, 13, 0, 3, 13, 241, 221, 215, 12, 39, 31, 63, 246, 171, 222, 31, 21, 19, 236, 241, 33, 0, 217, 37, 5, 209, 247, 18, 75, 29, 200, 189, 18, 23, 204, 8, 76, 54, 227, 203, 14, 7, 189, 244, 58, 0, 3, 67, 32, 196, 190, 202, 223, 37, 114, 93, 19, 173, 159, 193, 3, 78, 75, 10, 223, 254, 237, 231, 237, 6, 35, 251, 2, 43, 251, 214, 234, 20, 27, 11, 252, 221, 246, 252, 250, 42, 64, 0, 205, 239, 248, 237, 33, 27, 216, 235, 18, 10, 0, 32, 10, 228, 7, 16, 250, 226, 244, 8, 236, 0, 44, 13, 1, 54, 21, 170, 178, 226, 19, 73, 73, 28, 211, 209, 253, 11, 227, 189, 25, 95, 39, 248, 245, 218, 223, 244, 252, 10, 42, 38, 14, 246, 190, 215, 6, 12, 53, 73, 8, 207, 212, 229, 223, 230, 63, 89, 22, 231, 229, 211, 197, 254, 42, 63, 34, 8, 0, 223, 212, 228, 245, 21, 49, 51, 240, 196, 239, 15, 20, 247, 2, 7, 245, 240, 18, 32, 0, 245, 5, 5, 224, 237, 26, 7, 245, 16, 25, 0, 222, 233, 13, 33, 244, 244, 1, 6, 248, 239, 23, 24, 239, 14, 24, 227, 225, 10, 250, 251, 32, 50, 244, 217, 247, 239, 238, 2, 43, 50, 20, 227, 207, 193, 252, 26, 36, 37, 38, 24, 243, 197, 208, 246, 232, 21, 94, 64, 211, 187, 0, 20, 245, 209, 24, 69, 248, 238, 242, 238, 10, 241, 255, 37, 55, 251, 181, 244, 11, 32, 39, 243, 226, 233, 20, 9, 223, 254, 29, 5, 253, 12, 20, 11, 223, 197, 244, 22, 64, 66, 210, 187, 1, 27, 21, 0, 254, 252, 248, 248, 19, 250, 185, 5, 106, 55, 207, 205, 237, 229, 2, 32, 9, 5, 35, 32, 232, 218, 23, 230, 182, 0, 67, 73, 19, 233, 212, 202, 20, 27, 225, 249, 38, 24, 232, 252, 54, 23, 216, 208, 234, 255, 10, 38, 6, 239, 38, 21, 222, 223, 2, 6, 244, 16, 61, 3, 198, 242, 23, 255, 221, 4, 52, 10, 218, 218, 31, 60, 255, 231, 226, 235, 16, 255, 237, 38, 65, 0, 204, 233, 255, 6, 19, 19, 253, 252, 9, 211, 211, 1, 27, 54, 50, 1, 199, 215, 14, 13, 252, 7, 24, 27, 229, 214, 27, 21, 232, 239, 13, 11, 245, 250, 14, 23, 5, 5, 249, 220, 224, 255, 42, 44, 0, 242, 245, 232, 251, 25, 23, 243, 209, 237, 31, 59, 42, 254, 222, 205, 219, 254, 25, 44, 10, 230, 13, 30, 214, 214, 26, 35, 15, 241, 236, 250, 25, 13, 224, 249, 31, 13, 6, 225, 223, 27, 31, 225, 249, 42, 234, 255, 1, 233, 0, 20, 23, 11, 248, 227, 236, 4, 26, 23, 240, 253, 20, 251, 248, 234, 236, 41, 60, 242, 220, 232, 235, 249, 31, 30, 247, 252, 20, 235, 211, 17, 48, 8, 231, 31, 16, 225, 238, 250, 3, 229, 12, 75, 6, 199, 227, 7, 11, 25, 17, 231, 212, 247, 70, 22, 226, 18, 6, 201, 228, 42, 55, 243, 210, 10, 41, 242, 235, 16, 0, 220, 215, 16, 69, 24, 251, 246, 235, 220, 252, 27, 15, 243, 2, 29, 25, 254, 219, 221, 247, 11, 6, 5, 53, 45, 229, 180, 232, 56, 10, 218, 1, 30, 8, 242, 248, 35, 12, 204, 203, 15, 61, 52, 4, 216, 240, 12, 246, 201, 3, 62, 5, 232, 18, 38, 241, 187, 228, 21, 21, 46, 33, 217, 227, 38, 2, 215, 255, 11, 236, 0, 45, 44, 240, 226, 234, 241, 243, 253, 56, 27, 223, 4, 255, 249, 3, 255, 255, 2, 235, 9, 48, 245, 222, 235, 247, 41, 57, 17, 228, 198, 231, 255, 245, 10, 46, 62, 1, 242, 238, 211, 224, 0, 16, 24, 21, 39, 31, 218, 187, 223, 26, 50, 255, 239, 5, 248, 249, 23, 17, 245, 246, 31, 10, 213, 234, 23, 4, 229, 255, 43, 36, 228, 211, 15, 33, 228, 226, 30, 25, 243, 11, 0, 236, 14, 7, 240, 241, 2, 16, 249, 9, 35, 9, 214, 227, 10, 18, 253, 232, 12, 56, 34, 228, 202, 241, 250, 249, 30, 22, 25, 11, 205, 233, 36, 3, 228, 32, 35, 230, 210, 252, 28, 30, 5, 207, 236, 46, 31, 236, 221, 24, 29, 220, 231, 40, 15, 212, 4, 37, 3, 228, 0, 0, 241, 8, 31, 0, 237, 8, 16, 248, 248, 8, 2, 245, 208, 0, 70, 13, 234, 7, 7, 219, 223, 11, 20, 10, 19, 5, 5, 18, 5, 207, 218, 14, 1, 5, 21, 37, 34, 223, 209, 237, 233, 11, 28, 23, 34, 26, 223, 218, 241, 239, 3, 32, 37, 16, 241, 235, 246, 232, 243, 5, 22, 32, 23, 254, 228, 228, 234, 21, 29, 22, 254, 236, 242, 7, 7, 0, 251, 253, 236, 243, 39, 48, 248, 222, 252, 4, 247, 245, 254, 8, 23, 20, 5, 229, 242, 23, 20, 231, 204, 222, 44, 87, 26, 217, 210, 250, 12, 249, 253, 17, 23, 249, 236, 2, 16, 11, 239, 221, 3, 35, 24, 16, 219, 207, 19, 32, 23, 245, 206, 20, 47, 194, 209, 52, 71, 21, 212, 235, 5, 241, 231, 3, 2, 7, 42, 32, 13, 244, 182, 197, 255, 42, 70, 54, 253, 210, 212, 219, 0, 24, 29, 43, 0, 250, 7, 199, 217, 19, 14, 13, 30, 44, 5, 200, 198, 229, 15, 60, 71, 23, 206, 194, 223, 247, 31, 54, 26, 238, 244, 11, 3, 202, 235, 41, 26, 255, 23, 0, 206, 216, 255, 37, 33, 12, 0, 252, 255, 231, 224, 10, 40, 27, 5, 231, 232, 254, 243, 248, 1, 26, 46, 16, 236, 223, 200, 7, 66, 14, 228, 234, 2, 34, 17, 239, 244, 248, 0, 1, 246, 15, 30, 3, 232, 3, 0, 241, 250, 255, 12, 255, 253, 7, 250, 11, 43, 2, 224, 245, 236, 244, 21, 12, 255, 10, 10, 2, 1, 243, 236, 230, 0, 43, 44, 2, 214, 231, 11, 28, 254, 235, 5, 3, 252, 3, 7, 0, 4, 6, 233, 245, 29, 14, 233, 239, 7, 26, 31, 0, 235, 238, 235, 238, 232, 15, 99, 59, 218, 209, 236, 244, 231, 208, 20, 95, 80, 226, 174, 233, 18, 15, 3, 249, 9, 37, 2, 234, 226, 230, 7, 38, 46, 254, 200, 224, 36, 24, 207, 4, 62, 20, 233, 197, 243, 57, 31, 224, 217, 6, 42, 13, 202, 244, 70, 22, 206, 233, 11, 251, 6, 38, 13, 216, 235, 12, 14, 252, 233, 6, 38, 17, 228, 240, 10, 8, 5, 238, 252, 11, 251, 8, 25, 247, 224, 3, 17, 10, 251, 235, 255, 39, 5, 212, 0, 30, 5, 231, 232, 18, 43, 254, 231, 243, 1, 38, 14, 237, 226, 246, 14, 10, 3, 8, 7, 248, 252, 253, 250, 251, 15, 11, 243, 7, 13, 247, 1, 240, 239, 31, 29, 243, 238, 250, 244, 4, 12, 13, 13, 1, 247, 253, 248, 254, 242, 229, 30, 60, 15, 230, 231, 246, 245, 251, 5, 16, 253, 246, 16, 25, 3, 5, 240, 225, 252, 19, 8, 251, 6, 17, 246, 229, 21, 28, 237, 224, 3, 24, 249, 226, 14, 33, 6, 254, 30, 245, 206, 242, 17, 4, 245, 6, 27, 11, 246, 10, 251, 238, 254, 5, 252, 2, 16, 0, 251, 248, 6, 4, 244, 9, 8, 240, 252, 12, 12, 255, 251, 5, 4, 1, 241, 234, 255, 15, 29, 12, 249, 1, 248, 236, 249, 245, 16, 29, 12, 3, 249, 224, 219, 7, 51, 33, 240, 241, 255, 228, 254, 33, 0, 248, 13, 13, 0, 238, 244, 242, 241, 12, 37, 29, 253, 248, 243, 224, 244, 5, 9, 33, 25, 252, 245, 239, 228, 255, 13, 1, 21, 21, 247, 3, 11, 225, 227, 2, 22, 26, 253, 240, 9, 23, 242, 218, 244, 22, 33, 15, 246, 232, 235, 252, 30, 25, 0, 1, 3, 249, 241, 221, 234, 24, 42, 26, 252, 230, 247, 14, 247, 226, 3, 36, 15, 243, 250, 8, 253, 241, 0, 5, 20, 7, 238, 249, 250, 249, 9, 25, 10, 244, 4, 7, 238, 234, 6, 6, 248, 10, 10, 4, 30, 1, 225, 249, 3, 246, 252, 0, 4, 25, 9, 241, 14, 11, 235, 233, 244, 0, 15, 24, 16, 0, 251, 248, 242, 250, 253, 9, 255, 251, 31, 28, 238, 232, 18, 254, 211, 218, 34, 58, 8, 1, 5, 248, 232, 225, 238, 6, 32, 32, 37, 8, 215, 222, 249, 239, 254, 34, 31, 16, 2, 242, 215, 231, 14, 17, 10, 26, 14, 227, 235, 1, 2, 252, 14, 10, 249, 16, 21, 241, 216, 252, 4, 1, 25, 37, 9, 220, 223, 244, 6, 24, 25, 6, 217, 226, 29, 42, 7, 235, 231, 247, 20, 27, 6, 241, 221, 240, 17, 36, 39, 5, 208, 211, 15, 12, 255, 22, 22, 0, 230, 242, 8, 3, 255, 255, 11, 7, 254, 0, 3, 6, 247, 227, 6, 42, 0, 236, 246, 2, 3, 5, 12, 4, 250, 240, 250, 247, 0, 23, 16, 254, 4, 10, 237, 246, 8, 251, 252, 3, 7, 9, 11, 5, 236, 226, 1, 22, 9, 8, 3, 239, 251, 14, 249, 247, 13, 250, 247, 25, 8, 242, 11, 13, 245, 240, 2, 236, 255, 29, 20, 237, 228, 19, 26, 0, 245, 231, 240, 24, 25, 3, 7, 240, 226, 249, 4, 24, 44, 11, 227, 218, 234, 16, 9, 6, 21, 1, 248, 6, 5, 255, 234, 228, 253, 30, 38, 9, 247, 238, 244, 246, 252, 16, 24, 250, 234, 0, 3, 252, 21, 19, 1, 243, 229, 249, 21, 19, 244, 236, 5, 16, 4, 0, 13, 6, 235, 229, 251, 17, 27, 4, 237, 242, 11, 24, 14, 249, 219, 216, 5, 59, 40, 242, 222, 240, 255, 10, 16, 12, 0, 235, 231, 249, 21, 34, 9, 247, 236, 255, 16, 9, 252, 231, 237, 251, 25, 35, 16, 239, 224, 2, 2, 239, 11, 30, 6, 242, 255, 13, 6, 227, 230, 16, 20, 20, 5, 232, 1, 4, 233, 248, 13, 13, 24, 12, 234, 241, 6, 242, 226, 22, 48, 11, 242, 254, 248, 238, 236, 0, 22, 39, 10, 231, 235, 0, 249, 245, 13, 24, 19, 246, 253, 253, 243, 252, 244, 241, 21, 55, 19, 229, 225, 232, 255, 12, 18, 13, 8, 5, 243, 232, 1, 17, 3, 239, 0, 18, 7, 250, 255, 6, 245, 240, 3, 33, 25, 239, 222, 242, 9, 18, 10, 5, 4, 245, 235, 249, 9, 19, 11, 255, 252, 247, 2, 7, 243, 228, 0, 39, 29, 250, 242, 0, 247, 236, 254, 23, 169, 9, 63, 0, 14, 9, 244, 250, 10, 1, 244, 254, 255, 8, 16, 250, 252, 7, 7, 255, 245, 249, 252, 1, 5, 17, 18, 248, 234, 253, 2, 255, 8, 14, 0, 247, 0, 5, 10, 252, 239, 252, 11, 17, 255, 240, 246, 8, 15, 250, 3, 6, 252, 241, 251, 11, 9, 12, 10, 249, 243, 251, 255, 255, 254, 12, 16, 249, 241, 242, 5, 16, 4, 255, 2, 1, 246, 252, 1, 249, 0, 9, 10, 4, 251, 253, 247, 243, 9, 17, 1, 255, 6, 4, 247, 255, 3, 255, 16, 5, 0, 255, 240, 6, 12, 248, 241, 4, 21, 8, 255, 245, 243, 254, 1, 1, 253, 3, 13, 6, 252, 247, 233, 7, 8, 246, 1, 13, 9, 2, 255, 234, 243, 15, 21, 9, 3, 4, 239, 231, 254, 24, 17, 4, 254, 9, 2, 233, 244, 5, 12, 3, 9, 11, 251, 244, 250, 249, 4, 10, 254, 252, 8, 11, 246, 241, 247, 7, 20, 8, 249, 238, 244, 18, 31, 250, 232, 254, 12, 5, 253, 249, 0, 8, 1, 4, 1, 241, 250, 13, 0, 245, 7, 26, 5, 241, 245, 242, 249, 12, 26, 15, 253, 251, 3, 248, 230, 251, 18, 17, 6, 1, 254, 244, 254, 250, 234, 16, 35, 255, 241, 250, 18, 4, 231, 252, 27, 12, 251, 1, 2, 243, 243, 7, 10, 7, 7, 247, 227, 247, 15, 20, 15, 240, 228, 251, 15, 12, 13, 243, 243, 12, 245, 241, 6, 12, 9, 0, 10, 1, 234, 251, 14, 2, 1, 24, 14, 251, 231, 237, 16, 25, 10, 255, 250, 245, 254, 1, 255, 4, 12, 7, 243, 244, 255, 4, 254, 247, 0, 16, 4, 234, 226, 8, 35, 18, 244, 231, 249, 7, 243, 251, 34, 41, 248, 212, 245, 16, 14, 250, 3, 31, 16, 222, 227, 12, 39, 17, 241, 247, 0, 250, 255, 7, 12, 5, 0, 245, 244, 249, 0, 249, 3, 36, 18, 228, 231, 248, 246, 10, 19, 0, 8, 254, 230, 250, 5, 12, 14, 254, 0, 255, 0, 3, 250, 0, 254, 0, 5, 7, 10, 10, 246, 247, 1, 9, 9, 246, 244, 1, 14, 19, 14, 233, 236, 8, 4, 254, 252, 252, 12, 19, 4, 251, 248, 245, 253, 249, 234, 4, 34, 27, 5, 222, 237, 251, 240, 17, 21, 9, 253, 233, 238, 4, 22, 8, 0, 0, 14, 3, 226, 238, 25, 27, 5, 8, 14, 246, 216, 247, 28, 22, 250, 0, 3, 245, 244, 239, 2, 21, 9, 253, 5, 249, 239, 248, 254, 13, 6, 3, 250, 2, 17, 7, 241, 238, 0, 0, 23, 17, 245, 233, 11, 39, 247, 216, 242, 12, 23, 251, 252, 11, 28, 13, 230, 219, 229, 16, 42, 18, 5, 248, 243, 244, 248, 242, 245, 30, 36, 6, 238, 227, 241, 12, 19, 249, 253, 22, 15, 248, 247, 239, 246, 15, 19, 2, 254, 13, 1, 232, 238, 7, 15, 13, 8, 4, 254, 234, 233, 0, 14, 22, 8, 235, 247, 5, 5, 8, 248, 246, 8, 12, 255, 249, 253, 240, 2, 24, 12, 3, 8, 5, 227, 220, 0, 25, 25, 250, 7, 22, 245, 245, 240, 228, 6, 16, 9, 34, 18, 233, 242, 239, 242, 16, 24, 247, 255, 8, 1, 247, 238, 255, 254, 6, 27, 4, 247, 239, 3, 11, 247, 3, 8, 3, 0, 247, 247, 9, 22, 251, 248, 1, 2, 8, 249, 226, 7, 41, 255, 2, 18, 249, 236, 230, 250, 15, 16, 7, 11, 5, 244, 243, 239, 233, 6, 49, 15, 234, 252, 4, 237, 230, 9, 32, 25, 8, 239, 242, 241, 243, 0, 21, 23, 18, 0, 240, 245, 4, 242, 241, 16, 23, 14, 255, 10, 240, 221, 3, 24, 19, 253, 233, 252, 18, 7, 247, 237, 13, 20, 242, 231, 1, 12, 253, 13, 17, 255, 239, 0, 18, 246, 225, 3, 24, 7, 12, 10, 228, 236, 250, 24, 22, 242, 251, 254, 246, 25, 12, 232, 8, 10, 251, 250, 251, 8, 13, 240, 252, 17, 249, 0, 27, 16, 230, 201, 250, 44, 22, 228, 0, 38, 4, 222, 240, 14, 9, 255, 255, 34, 12, 209, 215, 30, 35, 237, 3, 27, 7, 248, 241, 229, 244, 17, 19, 1, 252, 11, 1, 221, 241, 24, 21, 247, 246, 15, 253, 232, 7, 31, 243, 220, 9, 57, 32, 226, 204, 254, 15, 241, 31, 40, 245, 241, 248, 5, 11, 233, 228, 27, 52, 254, 229, 2, 14, 233, 225, 251, 29, 47, 254, 223, 240, 250, 250, 249, 14, 16, 1, 0, 248, 249, 13, 247, 249, 243, 245, 28, 64, 6, 193, 252, 36, 246, 232, 5, 25, 5, 254, 11, 14, 245, 241, 239, 254, 19, 7, 18, 1, 224, 7, 7, 249, 255, 248, 0, 16, 7, 247, 250, 246, 242, 6, 17, 15, 255, 233, 232, 24, 32, 242, 3, 8, 246, 248, 7, 4, 252, 15, 0, 232, 252, 10, 2, 244, 24, 52, 0, 217, 231, 3, 7, 240, 254, 18, 35, 9, 246, 233, 223, 0, 2, 5, 25, 16, 20, 249, 211, 230, 13, 15, 11, 12, 13, 254, 243, 245, 234, 5, 29, 3, 243, 12, 34, 240, 196, 216, 15, 67, 51, 8, 226, 236, 247, 221, 236, 24, 47, 37, 251, 235, 238, 2, 246, 217, 248, 41, 43, 2, 250, 23, 250, 203, 208, 255, 50, 47, 20, 2, 225, 226, 225, 249, 25, 18, 15, 15, 2, 235, 233, 12, 21, 1, 237, 9, 14, 3, 241, 233, 252, 236, 27, 95, 248, 183, 241, 10, 238, 241, 35, 36, 2, 249, 245, 225, 255, 28, 255, 240, 7, 33, 0, 226, 241, 19, 17, 8, 248, 254, 247, 242, 20, 11, 245, 249, 11, 33, 248, 219, 228, 7, 39, 23, 245, 2, 19, 255, 224, 207, 8, 42, 24, 255, 17, 20, 213, 192, 221, 10, 47, 61, 49, 1, 211, 184, 217, 12, 35, 30, 27, 30, 253, 203, 198, 251, 42, 30, 4, 254, 251, 250, 238, 244, 11, 21, 24, 13, 237, 241, 254, 4, 5, 252, 21, 11, 0, 252, 241, 9, 5, 243, 5, 20, 228, 235, 31, 21, 236, 3, 13, 211, 225, 9, 36, 35, 9, 243, 207, 223, 14, 29, 11, 3, 9, 243, 247, 244, 246, 16, 5, 2, 13, 254, 9, 11, 235, 236, 25, 23, 255, 242, 253, 25, 20, 231, 244, 26, 252, 239, 254, 24, 48, 247, 197, 223, 27, 17, 253, 9, 248, 243, 28, 13, 222, 213, 249, 22, 18, 24, 4, 229, 209, 0, 48, 249, 226, 9, 39, 17, 248, 249, 246, 3, 11, 252, 234, 11, 36, 5, 242, 229, 14, 13, 13, 6, 245, 247, 8, 4, 5, 8, 251, 0, 246, 245, 12, 9, 0, 10, 251, 240, 2, 0, 224, 221, 21, 42, 21, 12, 242, 191, 221, 21, 26, 16, 3, 29, 10, 223, 234, 1, 14, 12, 5, 20, 0, 230, 5, 5, 243, 6, 32, 7, 240, 249, 244, 253, 21, 31, 4, 230, 249, 6, 226, 0, 18, 16, 247, 224, 1, 14, 241, 239, 5, 28, 21, 1, 240, 222, 251, 39, 26, 243, 226, 1, 9, 21, 241, 238, 17, 16, 13, 8, 6, 236, 213, 17, 39, 255, 253, 7, 3, 0, 238, 232, 246, 20, 40, 18, 2, 227, 198, 241, 26, 10, 13, 13, 6, 252, 253, 243, 247, 244, 14, 15, 247, 21, 36, 219, 204, 1, 41, 38, 231, 252, 41, 246, 179, 215, 46, 71, 24, 1, 230, 232, 249, 242, 246, 19, 40, 23, 244, 234, 253, 251, 230, 233, 15, 53, 31, 238, 233, 222, 236, 14, 33, 33, 0, 228, 228, 2, 14, 22, 0, 238, 3, 21, 12, 228, 235, 3, 0, 3, 33, 36, 227, 210, 244, 5, 16, 40, 21, 235, 246, 3, 239, 233, 255, 14, 0, 14, 26, 18, 239, 236, 240, 235, 2, 37, 12, 249, 250, 25, 253, 211, 239, 12, 55, 51, 249, 202, 175, 5, 70, 26, 239, 17, 33, 223, 190, 248, 46, 31, 244, 246, 245, 247, 19, 4, 0, 0, 241, 4, 4, 253, 10, 248, 221, 15, 53, 12, 239, 238, 227, 244, 252, 18, 32, 28, 14, 237, 205, 225, 21, 37, 5, 245, 33, 16, 205, 230, 24, 25, 16, 252, 4, 21, 238, 194, 18, 77, 20, 238, 222, 212, 215, 239, 26, 74, 58, 9, 238, 175, 172, 232, 49, 91, 42, 222, 214, 3, 10, 212, 195, 33, 125, 42, 184, 213, 255, 248, 19, 4, 254, 22, 47, 38, 190, 183, 34, 35, 236, 242, 46, 36, 241, 227, 237, 3, 6, 10, 4, 250, 5, 10, 242, 238, 255, 8, 3, 246, 244, 1, 255, 12, 39, 252, 201, 243, 21, 22, 7, 241, 244, 0, 19, 9, 234, 237, 27, 38, 6, 221, 222, 13, 7, 22, 14, 235, 16, 46, 12, 228, 209, 237, 4, 20, 50, 246, 234, 28, 0, 198, 225, 33, 47, 12, 238, 248, 252, 242, 241, 242, 253, 44, 21, 245, 7, 245, 224, 203, 0, 71, 52, 3, 237, 228, 3, 3, 245, 239, 20, 35, 3, 3, 219, 215, 38, 48, 255, 0, 248, 229, 234, 249, 4, 46, 48, 2, 215, 211, 221, 246, 30, 37, 32, 20, 253, 206, 208, 3, 28, 10, 249, 15, 38, 234, 236, 0, 245, 254, 249, 13, 22, 32, 25, 224, 214, 8, 13, 237, 250, 25, 32, 5, 236, 237, 247, 15, 9, 14, 0, 221, 251, 16, 1, 0, 10, 11, 248, 238, 240, 22, 5, 234, 251, 14, 41, 0, 217, 6, 8, 244, 233, 7, 20, 13, 7, 231, 0, 26, 9, 239, 254, 8, 252, 249, 248, 6, 25, 36, 253, 215, 228, 0, 16, 3, 25, 7, 9, 5, 223, 232, 247, 2, 13, 28, 11, 237, 246, 22, 0, 210, 225, 20, 51, 36, 0, 231, 253, 248, 216, 222, 16, 46, 51, 23, 241, 224, 241, 240, 234, 5, 26, 40, 10, 252, 244, 233, 240, 233, 246, 26, 61, 50, 237, 190, 208, 2, 27, 28, 39, 3, 230, 255, 242, 252, 40, 24, 223, 191, 3, 50, 27, 222, 248, 47, 15, 227, 211, 236, 255, 0, 38, 45, 9, 2, 209, 192, 250, 30, 34, 43, 50, 234, 184, 192, 253, 56, 22, 16, 42, 27, 233, 182, 208, 20, 28, 9, 15, 59, 12, 203, 194, 226, 4, 49, 61, 7, 234, 242, 245, 220, 231, 15, 25, 66, 28, 214, 242, 254, 211, 225, 49, 55, 27, 250, 243, 225, 191, 0, 42, 15, 57, 46, 207, 182, 230, 250, 14, 47, 42, 4, 229, 228, 229, 230, 10, 26, 27, 15, 255, 249, 241, 211, 238, 46, 50, 4, 7, 4, 220, 220, 3, 46, 18, 255, 26, 244, 195, 3, 31, 10, 36, 16, 197, 193, 20, 58, 28, 233, 240, 248, 11, 251, 191, 7, 77, 31, 206, 235, 13, 0, 243, 240, 21, 31, 3, 241, 250, 227, 237, 28, 36, 20, 238, 216, 240, 36, 11, 255, 37, 249, 221, 218, 2, 40, 39, 16, 248, 223, 234, 11, 19, 255, 3, 251, 246, 12, 1, 226, 25, 21, 220, 12, 26, 1, 244, 244, 250, 11, 14, 0, 250, 249, 1, 13, 227, 242, 17, 8, 5, 243, 0, 11, 255, 0, 2, 228, 255, 49, 4, 224, 255, 254, 0, 14, 7, 18, 0, 239, 238, 253, 3, 19, 19, 16, 13, 235, 215, 244, 28, 16, 242, 13, 29, 255, 213, 227, 0, 27, 24, 17, 3, 249, 236, 242, 13, 235, 253, 50, 12, 206, 243, 2, 5, 36, 37, 0, 225, 215, 0, 8, 242, 15, 34, 29, 247, 230, 0, 240, 231, 3, 6, 17, 45, 250, 222, 230, 7, 33, 254, 238, 3, 10, 9, 225, 241, 33, 29, 251, 219, 223, 34, 56, 242, 229, 12, 7, 252, 248, 255, 18, 22, 255, 248, 228, 245, 23, 23, 13, 0, 232, 235, 3, 13, 255, 254, 9, 248, 248, 232, 254, 28, 255, 252, 241, 254, 16, 250, 245, 247, 21, 17, 253, 9, 242, 234, 255, 14, 13, 25, 31, 239, 226, 246, 4, 5, 7, 29, 16, 253, 0, 235, 227, 251, 31, 15, 0, 7, 5, 239, 231, 229, 2, 29, 20, 253, 225, 248, 23, 239, 239, 11, 18, 18, 245, 226, 2, 3, 16, 20, 3, 249, 250, 239, 249, 13, 30, 17, 245, 252, 0, 250, 7, 2, 244, 250, 11, 10, 17, 14, 0, 240, 228, 248, 251, 4, 32, 28, 236, 219, 12, 21, 232, 233, 4, 25, 25, 253, 232, 244, 251, 255, 7, 6, 0, 9, 11, 247, 235, 8, 29, 11, 255, 251, 241, 252, 243, 6, 25, 6, 252, 0, 12, 254, 231, 250, 250, 5, 29, 24, 249, 235, 245, 227, 254, 36, 24, 4, 253, 2, 241, 221, 233, 24, 41, 2, 253, 17, 254, 232, 242, 254, 6, 11, 10, 5, 251, 6, 10, 239, 229, 248, 23, 19, 250, 240, 3, 14, 251, 3, 249, 240, 8, 11, 7, 9, 1, 228, 247, 9, 5, 10, 15, 15, 0, 240, 225, 251, 5, 13, 29, 31, 18, 235, 202, 228, 4, 21, 30, 24, 17, 243, 225, 239, 242, 236, 5, 31, 16, 24, 1, 222, 229, 241, 7, 36, 25, 238, 233, 2, 11, 0, 249, 249, 11, 14, 0, 253, 4, 5, 252, 246, 252, 16, 19, 1, 249, 241, 4, 1, 250, 12, 0, 255, 11, 11, 248, 241, 251, 250, 8, 21, 0, 249, 3, 254, 237, 243, 15, 13, 0, 249, 251, 10, 0, 250, 4, 250, 0, 14, 4, 247, 253, 2, 255, 6, 21, 2, 236, 254, 11, 255, 238, 244, 2, 11, 12, 19, 23, 241, 215, 224, 6, 36, 22, 0, 254, 8, 7, 248, 232, 247, 10, 13, 10, 8, 17, 9, 228, 226, 253, 8, 18, 14, 249, 243, 11, 2, 237, 0, 5, 250, 0, 3, 255, 255, 3, 251, 243, 255, 5, 4, 7, 6, 248, 254, 9, 245, 247, 18, 15, 2, 0, 249, 4, 10, 254, 6, 14, 250, 247, 5, 12, 0, 0, 3, 252, 0, 249, 239, 255, 7, 6, 7, 8, 250, 239, 241, 249, 6, 11, 3, 8, 1, 237, 249, 1, 9, 6, 0, 1, 6, 0, 249, 249, 1, 19, 18, 255, 248, 251, 246, 0, 14, 15, 3, 5, 5, 246, 239, 248, 2, 7, 5, 10, 15, 253, 241, 247, 247, 253, 3, 4, 10, 13, 251, 238, 245, 251, 5, 12, 254, 4, 12, 253, 250, 255, 254, 253, 0, 7, 7, 4, 254, 250, 1, 10, 3, 252, 0, 9, 3, 252, 252, 255, 5, 2, 4, 13, 5, 247, 241, 244, 0, 11, 12, 0, 0, 0, 152, 9, 27, 0, 229, 254, 18, 15, 23, 19, 255, 251, 251, 2, 4, 248, 244, 7, 12, 0, 11, 18, 11, 247, 229, 228, 236, 245, 5, 20, 17, 12, 8, 243, 231, 231, 219, 223, 230, 239, 2, 20, 24, 16, 12, 8, 245, 211, 201, 215, 222, 241, 2, 11, 27, 44, 35, 11, 239, 211, 203, 213, 234, 12, 51, 49, 28, 22, 15, 240, 234, 244, 242, 234, 232, 251, 17, 26, 8, 13, 14, 234, 233, 237, 229, 252, 5, 7, 11, 254, 0, 250, 235, 248, 1, 232, 216, 249, 21, 21, 6, 248, 253, 0, 10, 14, 3, 244, 240, 249, 242, 255, 7, 14, 7, 7, 16, 17, 9, 224, 211, 244, 13, 4, 18, 57, 20, 253, 0, 248, 219, 235, 255, 0, 7, 14, 9, 255, 248, 11, 28, 17, 16, 15, 241, 221, 213, 225, 254, 8, 16, 19, 27, 19, 254, 241, 232, 240, 248, 245, 21, 31, 10, 2, 0, 255, 236, 219, 233, 10, 36, 7, 254, 3, 16, 18, 250, 223, 234, 14, 19, 249, 242, 3, 20, 7, 233, 218, 231, 237, 253, 20, 17, 22, 29, 239, 215, 229, 236, 249, 253, 1, 250, 14, 38, 10, 253, 7, 6, 248, 227, 224, 237, 252, 16, 33, 16, 8, 30, 23, 5, 246, 232, 242, 245, 238, 236, 9, 34, 29, 0, 243, 246, 6, 255, 236, 238, 2, 4, 252, 250, 10, 22, 8, 7, 13, 249, 241, 1, 247, 245, 1, 252, 15, 28, 19, 24, 34, 16, 226, 218, 239, 236, 243, 24, 41, 18, 13, 18, 240, 211, 0, 21, 234, 240, 29, 19, 252, 12, 8, 242, 227, 240, 16, 23, 16, 10, 248, 244, 242, 224, 235, 10, 21, 7, 22, 55, 42, 241, 220, 223, 212, 225, 236, 249, 46, 61, 32, 6, 0, 216, 205, 229, 23, 56, 32, 253, 4, 237, 220, 243, 240, 234, 7, 35, 39, 12, 255, 248, 243, 252, 243, 236, 246, 4, 253, 246, 0, 248, 250, 255, 1, 16, 27, 248, 211, 223, 254, 13, 13, 18, 14, 6, 251, 248, 252, 7, 245, 231, 246, 16, 11, 251, 2, 22, 24, 11, 246, 224, 241, 0, 253, 254, 1, 252, 244, 6, 254, 233, 252, 1, 231, 248, 249, 13, 45, 38, 13, 5, 233, 198, 218, 235, 239, 21, 67, 39, 14, 24, 19, 241, 211, 206, 226, 246, 15, 36, 48, 31, 21, 255, 241, 243, 248, 227, 230, 2, 6, 251, 14, 27, 7, 225, 219, 226, 221, 238, 31, 33, 17, 15, 16, 1, 212, 203, 215, 206, 233, 28, 47, 49, 46, 35, 244, 228, 228, 225, 221, 213, 244, 18, 30, 41, 19, 8, 255, 254, 245, 244, 250, 242, 224, 241, 2, 16, 31, 44, 17, 238, 226, 223, 249, 17, 252, 235, 0, 5, 16, 35, 15, 7, 225, 222, 248, 0, 243, 229, 3, 23, 32, 33, 9, 226, 218, 239, 247, 243, 12, 9, 12, 30, 36, 28, 245, 226, 242, 231, 227, 246, 0, 11, 34, 27, 15, 8, 9, 237, 201, 200, 249, 5, 5, 33, 2, 8, 61, 15, 219, 217, 252, 248, 228, 217, 237, 15, 249, 5, 34, 29, 44, 20, 243, 243, 179, 133, 207, 22, 38, 70, 100, 72, 16, 251, 197, 172, 210, 225, 236, 37, 90, 41, 252, 254, 238, 234, 222, 241, 5, 3, 9, 9, 18, 24, 235, 172, 196, 238, 29, 72, 49, 0, 214, 206, 233, 234, 218, 250, 32, 64, 11, 238, 13, 7, 217, 203, 219, 234, 6, 28, 61, 56, 19, 12, 245, 195, 183, 209, 243, 16, 34, 40, 25, 10, 0, 238, 218, 1, 9, 229, 240, 37, 34, 27, 0, 0, 0, 242, 227, 229, 246, 1, 29, 33, 24, 247, 219, 231, 254, 250, 0, 2, 254, 13, 19, 235, 236, 0, 0, 231, 236, 34, 23, 23, 40, 6, 237, 239, 239, 222, 225, 26, 60, 11, 246, 251, 249, 250, 249, 251, 23, 34, 22, 6, 9, 242, 200, 200, 226, 0, 17, 14, 45, 61, 75, 19, 189, 182, 194, 202, 231, 26, 26, 60, 77, 8, 239, 241, 222, 204, 212, 2, 53, 37, 6, 5, 1, 242, 240, 246, 224, 240, 22, 39, 27, 0, 35, 23, 247, 60, 18, 198, 215, 238, 237, 255, 49, 57, 10, 1, 5, 239, 219, 216, 208, 19, 93, 53, 30, 14, 226, 162, 155, 209, 0, 24, 77, 79, 44, 22, 255, 217, 170, 173, 228, 29, 63, 60, 68, 67, 25, 222, 190, 191, 197, 229, 21, 54, 40, 26, 58, 43, 229, 199, 248, 13, 206, 219, 9, 41, 82, 59, 20, 14, 13, 249, 188, 203, 251, 245, 246, 23, 30, 241, 0, 19, 16, 13, 6, 0, 228, 203, 220, 250, 2, 26, 19, 16, 17, 1, 239, 232, 240, 199, 198, 34, 83, 51, 31, 11, 200, 215, 4, 225, 206, 231, 4, 30, 39, 57, 55, 248, 241, 13, 236, 207, 211, 229, 5, 35, 64, 61, 50, 26, 219, 180, 190, 248, 253, 232, 29, 37, 12, 2, 249, 182, 197, 242, 241, 26, 58, 54, 30, 242, 207, 199, 204, 225, 18, 33, 31, 46, 38, 21, 241, 189, 170, 190, 213, 13, 66, 59, 25, 241, 220, 223, 214, 206, 215, 248, 6, 18, 4, 255, 10, 238, 232, 7, 236, 194, 225, 13, 21, 41, 22, 250, 216, 220, 247, 217, 192, 19, 88, 241, 251, 24, 233, 214, 232, 246, 229, 238, 48, 64, 253, 42, 57, 238, 194, 221, 215, 220, 220, 240, 68, 54, 1, 244, 208, 230, 245, 211, 233, 16, 7, 236, 233, 4, 14, 1, 230, 205, 212, 30, 47, 220, 215, 38, 11, 218, 216, 254, 20, 238, 3, 38, 48, 81, 53, 231, 171, 178, 250, 23, 35, 69, 50, 254, 243, 5, 214, 206, 253, 30, 36, 33, 12, 227, 228, 230, 232, 212, 204, 248, 247, 12, 16, 16, 26, 29, 220, 192, 3, 255, 242, 6, 2, 213, 242, 45, 32, 255, 253, 0, 2, 251, 249, 17, 33, 36, 17, 7, 252, 6, 73, 57, 22, 233, 225, 227, 231, 251, 235, 230, 1, 37, 64, 55, 250, 173, 177, 193, 237, 9, 56, 45, 247, 249, 13, 217, 206, 233, 225, 237, 42, 79, 50, 27, 226, 197, 240, 4, 23, 14, 244, 20, 33, 246, 231, 223, 204, 1, 105, 100, 38, 246, 220, 227, 211, 212, 225, 243, 43, 71, 65, 80, 42, 221, 190, 222, 217, 196, 223, 48, 80, 54, 45, 23, 15, 217, 147, 153, 253, 92, 81, 254, 16, 57, 5, 203, 183, 202, 225, 227, 7, 10, 49, 118, 75, 236, 220, 229, 220, 220, 224, 7, 90, 79, 26, 35, 247, 193, 199, 221, 11, 32, 61, 56, 6, 250, 243, 245, 234, 213, 216, 230, 25, 52, 66, 61, 10, 227, 192, 185, 194, 225, 241, 240, 57, 96, 54, 26, 254, 219, 182, 199, 222, 253, 16, 255, 2, 37, 32, 253, 249, 249, 221, 226, 253, 14, 29, 50, 48, 12, 194, 205, 27, 23, 238, 0, 38, 231, 199, 30, 5, 223, 16, 49, 60, 37, 224, 190, 208, 206, 227, 249, 5, 57, 57, 16, 0, 227, 223, 234, 216, 241, 16, 27, 31, 52, 17, 223, 236, 240, 201, 248, 29, 247, 27, 79, 11, 241, 16, 25, 9, 25, 16, 183, 196, 9, 47, 25, 252, 5, 29, 13, 247, 243, 243, 219, 207, 221, 9, 38, 46, 18, 248, 0, 253, 249, 220, 241, 29, 15, 17, 9, 22, 27, 12, 11, 233, 239, 19, 20, 254, 240, 9, 49, 16, 22, 26, 247, 232, 2, 254, 216, 16, 28, 239, 249, 18, 23, 231, 197, 230, 233, 1, 34, 10, 12, 25, 7, 242, 212, 221, 251, 20, 32, 32, 0, 31, 11, 247, 237, 225, 251, 33, 15, 240, 252, 22, 33, 22, 239, 255, 22, 34, 243, 18, 24, 237, 18, 219, 231, 6, 224, 3, 16, 24, 26, 246, 242, 207, 210, 0, 56, 55, 241, 228, 217, 209, 245, 235, 240, 250, 33, 21, 23, 57, 24, 227, 187, 200, 24, 37, 3, 21, 16, 254, 30, 15, 216, 211, 217, 218, 252, 50, 103, 34, 189, 225, 246, 235, 20, 8, 214, 222, 17, 51, 18, 5, 230, 188, 205, 27, 68, 26, 224, 230, 3, 24, 31, 13, 243, 224, 211, 226, 3, 42, 70, 55, 242, 190, 185, 226, 229, 225, 35, 55, 43, 16, 233, 15, 24, 231, 156, 200, 8, 245, 0, 19, 23, 13, 10, 253, 11, 4, 219, 233, 238, 220, 228, 8, 55, 45, 41, 50, 22, 246, 193, 162, 194, 250, 0, 7, 44, 76, 34, 238, 40, 39, 222, 175, 160, 227, 0, 11, 50, 58, 35, 9, 231, 191, 188, 209, 234, 14, 35, 58, 48, 43, 2, 211, 191, 198, 206, 12, 25, 27, 25, 240, 244, 0, 249, 253, 250, 245, 37, 34, 5, 252, 251, 245, 236, 225, 240, 17, 57, 66, 251, 235, 14, 233, 193, 221, 38, 51, 36, 33, 56, 44, 223, 185, 181, 188, 211, 235, 23, 44, 87, 94, 8, 217, 6, 238, 183, 214, 3, 10, 12, 44, 36, 16, 15, 253, 189, 192, 9, 252, 225, 248, 48, 52, 239, 252, 7, 5, 28, 30, 213, 208, 7, 220, 206, 0, 52, 42, 14, 249, 194, 219, 29, 68, 24, 241, 247, 237, 0, 7, 4, 195, 212, 3, 5, 59, 89, 26, 229, 217, 214, 212, 237, 28, 89, 50, 255, 245, 215, 212, 233, 234, 251, 6, 13, 15, 239, 204, 190, 216, 253, 26, 57, 75, 47, 214, 212, 227, 217, 245, 10, 43, 18, 240, 252, 8, 29, 26, 25, 247, 253, 11, 204, 190, 5, 14, 46, 59, 77, 72, 251, 164, 165, 178, 220, 24, 19, 23, 97, 90, 25, 245, 206, 160, 156, 189, 227, 41, 69, 92, 114, 28, 191, 133, 163, 211, 6, 33, 29, 59, 49, 15, 1, 242, 187, 201, 242, 253, 11, 31, 38, 248, 20, 46, 255, 233, 217, 220, 231, 8, 9, 242, 249, 28, 54, 251, 217, 253, 3, 0, 13, 239, 255, 38, 15, 3, 248, 0, 27, 24, 0, 4, 11, 234, 212, 226, 237, 10, 43, 22, 1, 254, 16, 6, 213, 181, 200, 208, 3, 72, 107, 54, 248, 194, 188, 203, 218, 235, 3, 51, 79, 55, 37, 240, 237, 203, 175, 233, 26, 51, 49, 5, 234, 235, 238, 226, 6, 13, 213, 242, 38, 17, 9, 0, 242, 30, 75, 21, 218, 197, 196, 235, 243, 44, 90, 39, 50, 32, 250, 5, 246, 189, 187, 240, 234, 231, 37, 70, 56, 234, 201, 219, 226, 11, 40, 24, 254, 251, 221, 216, 245, 13, 20, 18, 25, 234, 228, 18, 248, 253, 12, 21, 17, 2, 246, 214, 223, 37, 32, 255, 18, 35, 2, 220, 0, 9, 229, 32, 28, 237, 225, 236, 250, 11, 16, 241, 235, 7, 3, 251, 247, 6, 237, 196, 215, 250, 7, 4, 248, 52, 90, 13, 187, 221, 45, 246, 194, 228, 19, 30, 32, 48, 17, 21, 12, 218, 224, 6, 5, 234, 242, 248, 14, 43, 34, 17, 246, 194, 236, 248, 251, 7, 51, 14, 214, 20, 31, 249, 235, 212, 223, 253, 21, 46, 19, 227, 226, 248, 15, 39, 21, 1, 5, 227, 218, 255, 245, 7, 10, 16, 1, 2, 19, 250, 242, 233, 3, 255, 248, 18, 252, 225, 227, 0, 10, 20, 45, 255, 224, 243, 248, 241, 224, 253, 42, 27, 17, 28, 24, 227, 203, 223, 0, 254, 9, 16, 30, 45, 8, 16, 0, 212, 228, 254, 14, 16, 28, 9, 252, 227, 224, 231, 249, 25, 55, 18, 241, 227, 226, 252, 249, 249, 0, 4, 28, 27, 255, 253, 4, 249, 184, 168, 238, 37, 39, 50, 75, 33, 204, 197, 180, 202, 0, 247, 249, 56, 78, 25, 233, 215, 200, 187, 236, 5, 247, 28, 96, 107, 29, 234, 216, 150, 131, 193, 21, 57, 71, 70, 41, 8, 225, 186, 176, 239, 34, 45, 26, 10, 14, 243, 246, 213, 192, 21, 97, 87, 34, 250, 204, 204, 207, 224, 6, 26, 21, 30, 41, 6, 220, 208, 222, 242, 225, 2, 59, 41, 21, 5, 204, 196, 198, 212, 246, 5, 14, 20, 15, 41, 25, 243, 209, 204, 236, 227, 6, 72, 75, 60, 254, 200, 231, 18, 251, 207, 252, 55, 48, 7, 225, 1, 28, 236, 227, 12, 44, 38, 254, 239, 12, 11, 238, 215, 237, 12, 33, 0, 250, 21, 7, 13, 247, 199, 208, 228, 0, 26, 12, 39, 53, 9, 226, 221, 232, 245, 242, 243, 28, 42, 29, 22, 236, 224, 6, 1, 222, 227, 6, 10, 250, 248, 3, 17, 5, 234, 234, 249, 247, 237, 252, 6, 254, 248, 225, 5, 47, 25, 6, 254, 221, 226, 19, 9, 238, 255, 32, 33, 37, 30, 238, 236, 0, 228, 220, 18, 5, 246, 14, 40, 22, 244, 239, 239, 221, 213, 218, 225, 6, 45, 8, 1, 46, 30, 220, 200, 225, 241, 252, 252, 6, 28, 24, 17, 7, 9, 12, 252, 222, 230, 18, 1, 249, 26, 0, 14, 32, 26, 33, 12, 229, 216, 210, 228, 34, 36, 31, 37, 6, 244, 253, 241, 240, 236, 229, 8, 29, 35, 39, 19, 226, 233, 17, 13, 252, 241, 247, 253, 250, 8, 15, 2, 245, 2, 9, 244, 228, 234, 247, 4, 10, 25, 45, 22, 4, 250, 227, 201, 197, 234, 0, 13, 50, 41, 12, 0, 231, 207, 238, 252, 249, 4, 32, 45, 23, 19, 44, 1, 220, 251, 6, 4, 16, 8, 7, 35, 39, 25, 11, 255, 234, 237, 5, 8, 0, 242, 224, 245, 11, 18, 22, 254, 232, 227, 222, 229, 255, 0, 1, 254, 236, 5, 44, 32, 249, 219, 217, 237, 247, 254, 11, 25, 37, 34, 0, 231, 252, 12, 234, 221, 1, 26, 47, 29, 253, 251, 250, 254, 244, 252, 15, 28, 9, 8, 3, 240, 246, 251, 246, 248, 255, 0, 255, 251, 246, 243, 240, 236, 241, 244, 1, 13, 6, 248, 239, 225, 224, 243, 250, 244, 1, 14, 34, 41, 17, 248, 247, 3, 0, 242, 246, 7, 19, 19, 10, 9, 21, 25, 9, 251, 254, 5, 0, 3, 9, 251, 242, 254, 255, 1, 248, 242, 9, 15, 0, 250, 242, 227, 219, 237, 252, 7, 0, 20, 29, 248, 215, 226, 235, 238, 246, 3, 18, 14, 4, 248, 248, 250, 246, 248, 248, 0, 19, 18, 2, 0, 12, 11, 253, 236, 250, 17, 9, 251, 244, 5, 20, 20, 5, 5, 7, 1, 251, 248, 63, 10, 39, 0, 13, 248, 245, 253, 241, 11, 3, 240, 16, 34, 30, 0, 248, 250, 240, 9, 254, 13, 21, 14, 253, 236, 234, 1, 24, 0, 229, 248, 4, 9, 250, 0, 255, 246, 251, 231, 247, 0, 3, 243, 245, 244, 248, 2, 248, 244, 3, 12, 240, 4, 0, 244, 4, 34, 255, 235, 252, 12, 1, 9, 11, 29, 26, 228, 229, 241, 254, 17, 23, 0, 250, 3, 249, 217, 237, 3, 15, 10, 0, 255, 10, 225, 210, 25, 39, 6, 2, 255, 250, 8, 4, 2, 7, 39, 44, 3, 223, 214, 2, 48, 25, 223, 234, 14, 19, 246, 206, 228, 45, 36, 16, 245, 236, 229, 228, 248, 43, 57, 13, 239, 243, 243, 245, 7, 29, 29, 24, 245, 228, 238, 247, 14, 49, 43, 227, 216, 0, 34, 0, 237, 12, 51, 24, 212, 212, 14, 10, 226, 252, 28, 253, 235, 235, 245, 254, 250, 228, 0, 19, 241, 232, 254, 1, 231, 240, 249, 5, 21, 18, 253, 252, 236, 237, 6, 23, 17, 24, 3, 236, 7, 9, 2, 17, 14, 254, 248, 2, 6, 15, 7, 249, 9, 26, 251, 234, 10, 41, 16, 230, 227, 12, 31, 252, 247, 30, 48, 6, 219, 241, 6, 251, 1, 15, 20, 11, 230, 223, 252, 10, 0, 241, 249, 255, 243, 236, 246, 7, 1, 16, 11, 241, 222, 238, 14, 22, 11, 5, 9, 13, 2, 241, 222, 6, 41, 26, 249, 253, 9, 247, 230, 245, 12, 28, 254, 238, 248, 0, 227, 246, 15, 8, 249, 222, 226, 244, 28, 16, 254, 6, 0, 250, 233, 2, 8, 251, 0, 17, 4, 226, 230, 7, 15, 0, 229, 254, 45, 15, 233, 1, 42, 21, 233, 247, 30, 48, 19, 233, 220, 24, 54, 19, 6, 250, 223, 226, 251, 7, 30, 22, 16, 251, 227, 203, 236, 20, 27, 14, 244, 242, 239, 250, 12, 12, 0, 4, 2, 255, 16, 12, 247, 243, 255, 13, 24, 242, 220, 5, 28, 248, 210, 242, 24, 14, 8, 244, 242, 17, 7, 231, 244, 16, 27, 22, 9, 238, 6, 249, 226, 254, 43, 30, 242, 219, 233, 1, 6, 7, 4, 5, 245, 245, 254, 13, 249, 248, 35, 247, 240, 248, 0, 11, 25, 36, 3, 5, 6, 213, 237, 33, 26, 2, 241, 242, 224, 246, 4, 35, 4, 241, 28, 246, 206, 241, 20, 31, 18, 17, 244, 218, 217, 248, 57, 42, 226, 217, 2, 19, 230, 229, 24, 60, 15, 225, 222, 252, 245, 231, 18, 42, 18, 253, 3, 250, 229, 236, 10, 27, 11, 243, 248, 1, 239, 223, 7, 37, 10, 228, 235, 12, 3, 237, 0, 27, 24, 239, 243, 249, 251, 5, 9, 48, 50, 245, 220, 0, 47, 25, 12, 22, 26, 12, 237, 231, 249, 28, 1, 244, 253, 11, 247, 234, 243, 246, 12, 25, 3, 242, 233, 2, 16, 22, 254, 231, 12, 27, 0, 253, 30, 15, 243, 237, 235, 21, 44, 226, 196, 241, 252, 230, 239, 239, 247, 7, 243, 246, 8, 2, 243, 243, 254, 22, 10, 240, 246, 27, 0, 236, 7, 23, 11, 7, 235, 229, 34, 53, 239, 209, 255, 33, 29, 8, 226, 250, 36, 16, 205, 216, 1, 21, 2, 2, 18, 13, 242, 219, 227, 14, 25, 10, 251, 254, 14, 250, 253, 255, 15, 30, 248, 237, 6, 5, 233, 210, 0, 59, 33, 234, 245, 3, 5, 2, 15, 41, 54, 254, 222, 227, 236, 40, 57, 26, 250, 245, 249, 251, 16, 17, 254, 238, 247, 10, 16, 246, 241, 36, 16, 180, 189, 31, 27, 2, 13, 245, 198, 196, 15, 50, 43, 248, 222, 250, 239, 231, 8, 45, 32, 9, 4, 221, 206, 221, 8, 48, 30, 0, 234, 249, 225, 230, 27, 67, 32, 233, 232, 239, 242, 17, 6, 3, 37, 18, 233, 204, 235, 21, 6, 248, 2, 30, 15, 216, 205, 254, 42, 25, 255, 236, 246, 253, 250, 252, 26, 13, 7, 18, 16, 253, 227, 235, 25, 25, 243, 229, 31, 52, 252, 229, 250, 246, 243, 28, 50, 254, 224, 238, 25, 38, 254, 236, 255, 26, 20, 216, 218, 24, 38, 249, 252, 248, 226, 245, 242, 18, 58, 36, 239, 233, 241, 235, 249, 252, 6, 22, 35, 254, 217, 197, 12, 57, 55, 24, 238, 235, 231, 9, 25, 11, 244, 214, 251, 18, 236, 178, 226, 20, 255, 237, 0, 8, 243, 211, 219, 14, 54, 43, 1, 7, 246, 227, 233, 34, 87, 62, 242, 204, 225, 14, 27, 18, 39, 45, 20, 210, 195, 215, 9, 53, 22, 248, 18, 14, 206, 189, 0, 52, 56, 11, 233, 244, 246, 229, 231, 238, 28, 8, 204, 10, 54, 248, 230, 240, 231, 8, 30, 17, 237, 210, 247, 60, 70, 0, 212, 21, 38, 242, 226, 26, 70, 35, 244, 231, 234, 251, 5, 27, 34, 26, 0, 222, 225, 226, 5, 76, 59, 217, 168, 233, 23, 1, 248, 29, 53, 11, 240, 213, 231, 11, 21, 6, 5, 4, 240, 231, 224, 228, 5, 2, 238, 232, 229, 244, 247, 241, 242, 3, 13, 9, 238, 224, 255, 3, 8, 24, 250, 247, 20, 20, 247, 244, 255, 29, 7, 214, 247, 52, 32, 218, 246, 15, 0, 245, 246, 11, 14, 0, 252, 18, 241, 215, 17, 58, 35, 0, 6, 7, 245, 228, 222, 6, 65, 60, 231, 200, 235, 25, 252, 242, 18, 31, 6, 250, 0, 9, 5, 216, 1, 62, 22, 1, 250, 9, 27, 28, 33, 32, 0, 229, 243, 248, 16, 14, 15, 6, 7, 249, 219, 227, 249, 11, 20, 4, 229, 241, 7, 0, 242, 254, 225, 185, 253, 58, 16, 216, 223, 232, 244, 246, 235, 13, 40, 8, 220, 201, 211, 8, 55, 18, 239, 241, 250, 254, 2, 18, 30, 22, 44, 22, 217, 193, 7, 70, 52, 28, 248, 218, 234, 238, 19, 37, 13, 254, 16, 1, 215, 222, 14, 28, 28, 14, 248, 240, 11, 0, 250, 18, 18, 255, 222, 241, 20, 29, 252, 233, 254, 7, 235, 231, 21, 38, 238, 226, 238, 236, 3, 25, 23, 11, 231, 234, 2, 1, 26, 43, 22, 223, 220, 241, 238, 254, 19, 33, 1, 234, 186, 207, 34, 47, 16, 245, 3, 10, 232, 204, 245, 60, 48, 235, 248, 16, 2, 0, 16, 11, 25, 37, 12, 254, 250, 251, 48, 53, 251, 236, 9, 25, 14, 247, 2, 250, 223, 172, 236, 25, 38, 47, 0, 174, 182, 237, 5, 5, 26, 47, 0, 204, 190, 199, 254, 72, 54, 251, 221, 236, 252, 18, 12, 12, 25, 23, 8, 234, 231, 19, 19, 239, 233, 25, 30, 0, 0, 21, 9, 241, 212, 222, 22, 45, 22, 217, 228, 18, 13, 237, 220, 233, 18, 33, 246, 201, 221, 1, 14, 2, 8, 11, 228, 228, 8, 20, 14, 18, 24, 252, 15, 21, 21, 29, 15, 0, 48, 74, 247, 223, 35, 57, 6, 18, 45, 27, 241, 237, 216, 247, 7, 249, 239, 252, 4, 5, 241, 245, 233, 226, 249, 255, 252, 227, 248, 25, 0, 186, 237, 43, 241, 226, 13, 31, 238, 178, 185, 17, 51, 3, 254, 25, 0, 205, 212, 255, 22, 39, 25, 254, 244, 246, 226, 254, 48, 40, 19, 235, 202, 225, 19, 19, 23, 46, 32, 236, 169, 168, 234, 51, 74, 66, 25, 212, 146, 199, 26, 83, 74, 35, 241, 196, 176, 224, 32, 92, 79, 12, 242, 207, 205, 0, 66, 111, 79, 242, 192, 199, 4, 63, 82, 48, 242, 227, 195, 210, 12, 71, 49, 251, 221, 185, 208, 242, 3, 34, 48, 6, 205, 202, 235, 15, 38, 22, 4, 228, 236, 250, 226, 229, 19, 34, 1, 251, 15, 11, 250, 212, 211, 10, 48, 26, 253, 0, 245, 235, 1, 11, 25, 11, 13, 20, 249, 216, 221, 13, 58, 30, 239, 201, 230, 244, 0, 0, 6, 251, 13, 11, 228, 225, 243, 29, 47, 13, 252, 251, 228, 223, 24, 57, 15, 0, 0, 2, 247, 236, 6, 22, 7, 0, 251, 243, 236, 238, 250, 9, 37, 35, 234, 207, 248, 17, 5, 255, 11, 1, 223, 205, 235, 48, 38, 8, 238, 221, 236, 5, 49, 45, 1, 233, 253, 8, 4, 17, 41, 35, 8, 246, 240, 5, 35, 33, 4, 23, 10, 232, 230, 243, 11, 28, 36, 4, 250, 247, 199, 220, 4, 28, 45, 15, 187, 187, 11, 17, 226, 240, 20, 11, 235, 202, 219, 238, 249, 241, 41, 54, 219, 207, 235, 248, 15, 18, 5, 34, 35, 247, 206, 247, 48, 54, 4, 219, 250, 18, 1, 1, 12, 253, 255, 18, 228, 226, 39, 31, 222, 244, 238, 236, 5, 9, 21, 42, 6, 206, 208, 234, 8, 73, 103, 1, 185, 201, 217, 2, 51, 64, 78, 42, 192, 152, 226, 31, 47, 65, 78, 42, 179, 132, 228, 36, 40, 60, 44, 22, 249, 218, 185, 236, 44, 32, 39, 53, 16, 218, 183, 226, 29, 48, 38, 235, 230, 10, 0, 226, 247, 27, 25, 253, 217, 239, 3, 250, 234, 239, 20, 233, 226, 2, 24, 38, 6, 192, 236, 31, 236, 230, 9, 26, 50, 10, 193, 186, 238, 26, 29, 19, 21, 1, 226, 205, 223, 250, 38, 45, 27, 251, 214, 190, 235, 33, 50, 37, 253, 216, 212, 238, 5, 23, 8, 21, 18, 242, 217, 207, 7, 39, 38, 6, 227, 246, 33, 37, 252, 9, 35, 1, 211, 243, 23, 42, 20, 246, 8, 19, 222, 199, 10, 70, 34, 230, 205, 224, 25, 14, 226, 12, 51, 245, 198, 1, 37, 254, 233, 254, 19, 43, 10, 208, 218, 9, 31, 40, 8, 223, 233, 8, 240, 226, 2, 57, 34, 241, 3, 255, 244, 9, 38, 42, 18, 251, 0, 255, 235, 8, 30, 4, 6, 16, 254, 240, 249, 11, 41, 247, 227, 252, 2, 2, 5, 254, 14, 26, 10, 228, 227, 243, 11, 19, 253, 243, 0, 4, 238, 240, 3, 18, 255, 229, 246, 246, 14, 245, 214, 240, 12, 8, 246, 246, 253, 8, 253, 250, 253, 9, 28, 0, 248, 255, 254, 248, 16, 10, 228, 247, 255, 248, 5, 255, 248, 0, 249, 247, 241, 238, 239, 242, 2, 28, 24, 7, 237, 211, 226, 19, 36, 33, 29, 4, 251, 221, 221, 17, 42, 30, 0, 252, 239, 220, 5, 17, 20, 13, 13, 241, 226, 241, 0, 7, 21, 32, 35, 16, 253, 254, 23, 2, 253, 29, 39, 16, 242, 242, 24, 14, 0, 12, 19, 0, 221, 225, 10, 35, 15, 249, 8, 7, 221, 222, 3, 17, 26, 8, 242, 255, 251, 237, 219, 1, 35, 40, 243, 189, 202, 235, 12, 16, 25, 33, 255, 195, 183, 222, 252, 51, 38, 5, 0, 233, 180, 184, 11, 90, 100, 41, 219, 208, 1, 239, 230, 34, 68, 46, 255, 227, 201, 220, 5, 19, 47, 38, 251, 201, 181, 243, 23, 25, 21, 21, 6, 235, 202, 196, 10, 58, 33, 253, 240, 236, 246, 18, 2, 244, 9, 36, 16, 238, 243, 4, 14, 24, 1, 223, 4, 43, 255, 221, 9, 31, 4, 233, 253, 33, 17, 7, 52, 50, 2, 230, 231, 248, 1, 3, 52, 62, 14, 219, 197, 250, 47, 14, 234, 16, 38, 245, 197, 205, 240, 17, 47, 44, 12, 194, 183, 241, 25, 44, 15, 254, 255, 227, 199, 229, 23, 40, 46, 6, 207, 186, 213, 249, 16, 41, 42, 43, 235, 160, 194, 27, 89, 51, 243, 238, 237, 213, 213, 14, 72, 62, 11, 240, 225, 221, 3, 46, 44, 28, 0, 228, 189, 213, 20, 26, 32, 31, 1, 229, 199, 215, 11, 36, 9, 248, 10, 2, 238, 0, 14, 20, 6, 12, 8, 244, 242, 9, 32, 2, 235, 2, 12, 1, 254, 12, 18, 0, 240, 252, 241, 243, 39, 33, 239, 213, 246, 14, 0, 247, 252, 38, 22, 199, 190, 241, 31, 28, 244, 237, 2, 246, 214, 254, 55, 27, 239, 239, 13, 14, 248, 8, 0, 0, 11, 243, 242, 245, 5, 33, 249, 225, 250, 20, 248, 222, 22, 56, 6, 201, 218, 14, 30, 7, 251, 23, 34, 246, 204, 233, 24, 54, 34, 6, 2, 246, 234, 228, 245, 39, 38, 6, 242, 233, 240, 3, 15, 23, 31, 9, 233, 243, 254, 0, 2, 23, 40, 26, 252, 232, 244, 245, 0, 37, 28, 250, 236, 223, 227, 251, 5, 21, 49, 26, 235, 202, 215, 11, 39, 19, 253, 235, 249, 249, 224, 227, 16, 43, 14, 245, 232, 239, 255, 254, 11, 19, 6, 238, 241, 5, 12, 0, 242, 245, 251, 2, 15, 252, 235, 254, 14, 253, 244, 27, 27, 237, 235, 1, 28, 12, 243, 249, 6, 5, 0, 0, 6, 1, 11, 1, 244, 1, 248, 238, 2, 21, 14, 5, 0, 0, 11, 252, 216, 220, 26, 61, 16, 244, 0, 4, 232, 225, 245, 32, 63, 29, 240, 228, 214, 228, 18, 38, 32, 5, 224, 223, 242, 252, 247, 28, 56, 11, 219, 206, 213, 251, 24, 36, 36, 32, 1, 219, 214, 232, 10, 51, 50, 21, 229, 212, 239, 250, 5, 38, 52, 25, 232, 194, 223, 7, 20, 28, 39, 18, 237, 214, 236, 249, 0, 30, 35, 14, 230, 219, 241, 251, 255, 12, 21, 243, 215, 234, 0, 7, 254, 1, 254, 248, 248, 252, 255, 251, 245, 235, 255, 46, 53, 3, 233, 243, 249, 241, 240, 0, 40, 65, 29, 214, 220, 255, 1, 255, 39, 52, 10, 231, 212, 230, 15, 43, 28, 252, 245, 243, 250, 8, 251, 0, 26, 37, 10, 233, 219, 236, 14, 39, 36, 5, 235, 243, 252, 239, 0, 34, 20, 247, 240, 8, 14, 237, 241, 13, 19, 1, 254, 5, 253, 237, 233, 0, 23, 18, 252, 237, 245, 4, 8, 250, 255, 6, 1, 232, 222, 3, 40, 39, 0, 229, 242, 247, 237, 248, 15, 32, 24, 235, 221, 238, 254, 2, 244, 0, 30, 14, 232, 217, 232, 0, 11, 18, 8, 9, 1, 222, 235, 11, 7, 16, 23, 249, 242, 250, 246, 8, 40, 9, 224, 245, 19, 22, 5, 0, 1, 255, 253, 0, 14, 12, 254, 254, 17, 12, 229, 232, 0, 11, 10, 7, 251, 242, 246, 231, 230, 8, 26, 23, 5, 226, 222, 252, 23, 23, 7, 254, 250, 4, 21, 21, 23, 31, 26, 0, 239, 249, 13, 20, 16, 18, 30, 17, 250, 0, 17, 11, 247, 245, 236, 0, 25, 13, 235, 237, 253, 249, 245, 240, 238, 246, 247, 250, 253, 0, 0, 244, 244, 239, 242, 5, 13, 254, 240, 236, 253, 5, 252, 251, 9, 6, 235, 217, 241, 11, 12, 10, 15, 18, 254, 234, 247, 20, 10, 245, 2, 22, 17, 250, 242, 4, 1, 245, 231, 249, 26, 26, 4, 6, 9, 243, 228, 245, 16, 33, 19, 240, 235, 4, 18, 247, 235, 8, 33, 11, 242, 237, 251, 12, 11, 8, 15, 10, 1, 254, 253, 245, 255, 20, 31, 18, 252, 244, 253, 7, 23, 29, 23, 0, 239, 235, 247, 17, 26, 17, 3, 249, 242, 229, 235, 0, 17, 13, 255, 245, 246, 245, 239, 242, 11, 27, 12, 245, 231, 241, 246, 248, 10, 34, 26, 246, 233, 241, 254, 255, 247, 22, 50, 21, 234, 231, 4, 17, 12, 7, 0, 248, 246, 254, 10, 0, 237, 252, 17, 9, 247, 225, 237, 13, 11, 0, 1, 247, 227, 222, 235, 4, 25, 15, 0, 238, 222, 215, 234, 3, 26, 22, 0, 35, 9, 17, 0, 236, 5, 4, 238, 4, 25, 5, 241, 231, 8, 35, 1, 223, 21, 16, 5, 243, 242, 12, 32, 16, 240, 211, 207, 18, 20, 252, 2, 247, 8, 0, 17, 23, 40, 29, 243, 207, 190, 244, 45, 62, 5, 244, 212, 237, 251, 232, 235, 35, 66, 40, 247, 203, 203, 3, 55, 45, 26, 229, 225, 254, 240, 212, 243, 45, 54, 35, 235, 168, 203, 40, 70, 46, 233, 199, 3, 20, 6, 0, 13, 7, 16, 214, 200, 8, 46, 51, 12, 187, 184, 21, 72, 22, 235, 231, 17, 47, 16, 226, 200, 1, 46, 5, 214, 221, 16, 43, 10, 230, 249, 27, 3, 225, 5, 35, 16, 8, 209, 200, 9, 5, 64, 80, 217, 195, 243, 254, 53, 18, 218, 226, 5, 255, 252, 240, 243, 38, 54, 240, 226, 28, 3, 246, 7, 9, 6, 242, 194, 236, 39, 51, 22, 226, 238, 9, 15, 234, 245, 24, 29, 2, 218, 194, 245, 36, 49, 24, 241, 225, 8, 31, 10, 6, 244, 233, 234, 247, 245, 25, 35, 16, 255, 234, 213, 10, 17, 0, 255, 12, 7, 3, 250, 0, 254, 12, 22, 235, 229, 222, 251, 47, 56, 5, 247, 204, 226, 1, 5, 20, 17, 52, 47, 208, 169, 228, 13, 37, 33, 43, 246, 206, 208, 255, 46, 13, 2, 13, 5, 2, 233, 230, 5, 37, 20, 243, 219, 219, 8, 45, 17, 8, 254, 236, 215, 245, 29, 56, 42, 242, 215, 211, 243, 252, 29, 61, 48, 224, 161, 201, 11, 59, 58, 32, 232, 221, 220, 244, 19, 46, 12, 0, 241, 223, 13, 36, 253, 240, 13, 245, 241, 248, 242, 249, 23, 1, 8, 20, 1, 255, 255, 0, 250, 254, 253, 28, 11, 244, 249, 227, 230, 35, 34, 1, 230, 216, 1, 49, 32, 241, 219, 213, 10, 58, 28, 9, 255, 230, 244, 2, 237, 251, 18, 0, 14, 16, 250, 237, 225, 230, 16, 32, 7, 3, 12, 2, 241, 231, 23, 57, 12, 230, 236, 247, 249, 4, 239, 229, 14, 8, 0, 9, 3, 21, 15, 222, 243, 25, 19, 17, 248, 250, 255, 224, 232, 22, 37, 10, 245, 240, 230, 4, 20, 231, 239, 40, 41, 252, 231, 254, 13, 4, 243, 254, 26, 2, 235, 217, 235, 5, 18, 26, 9, 2, 15, 15, 238, 235, 8, 33, 254, 237, 250, 12, 255, 217, 232, 14, 12, 10, 253, 252, 15, 24, 252, 238, 246, 9, 9, 14, 44, 11, 223, 202, 229, 15, 35, 39, 245, 236, 231, 234, 254, 43, 52, 1, 175, 170, 20, 70, 63, 13, 201, 11, 35, 248, 242, 14, 5, 35, 8, 187, 181, 240, 24, 40, 18, 229, 23, 18, 238, 242, 42, 48, 31, 232, 132, 203, 68, 61, 5, 236, 230, 14, 31, 242, 5, 12, 6, 210, 206, 13, 70, 39, 254, 241, 235, 249, 241, 232, 245, 23, 51, 19, 199, 200, 239, 46, 34, 20, 26, 20, 246, 226, 241, 0, 240, 20, 45, 248, 230, 241, 237, 16, 24, 230, 222, 2, 250, 17, 26, 8, 8, 252, 199, 231, 41, 64, 60, 5, 234, 249, 9, 218, 239, 28, 246, 202, 206, 228, 20, 33, 3, 10, 32, 7, 242, 4, 242, 39, 74, 16, 6, 220, 191, 227, 16, 39, 31, 235, 179, 189, 244, 15, 64, 101, 32, 195, 180, 210, 26, 78, 51, 41, 253, 196, 212, 228, 0, 53, 41, 251, 232, 218, 217, 254, 23, 9, 26, 29, 246, 226, 248, 17, 15, 2, 245, 2, 19, 241, 238, 13, 9, 25, 252, 241, 249, 251, 12, 252, 1, 251, 232, 248, 9, 253, 11, 8, 4, 6, 240, 5, 22, 21, 8, 3, 244, 252, 253, 248, 248, 213, 228, 17, 39, 18, 25, 0, 242, 241, 224, 235, 29, 28, 30, 6, 239, 3, 220, 222, 9, 37, 62, 26, 215, 211, 247, 17, 13, 227, 246, 0, 252, 251, 245, 2, 54, 67, 242, 197, 233, 17, 10, 43, 1, 199, 233, 26, 19, 0, 241, 7, 23, 2, 234, 225, 0, 0, 251, 255, 18, 43, 1, 219, 238, 28, 51, 34, 221, 210, 238, 248, 5, 19, 6, 254, 1, 254, 242, 9, 7, 6, 241, 238, 252, 251, 11, 33, 51, 22, 255, 225, 201, 229, 13, 27, 24, 8, 238, 236, 243, 240, 253, 0, 18, 20, 255, 1, 19, 35, 13, 230, 233, 249, 255, 27, 9, 251, 248, 238, 220, 220, 13, 63, 45, 250, 230, 187, 217, 45, 54, 39, 254, 231, 247, 17, 6, 7, 34, 45, 247, 185, 174, 211, 252, 21, 40, 50, 24, 236, 217, 227, 18, 52, 57, 26, 237, 221, 233, 248, 9, 235, 252, 28, 4, 248, 221, 236, 1, 11, 21, 18, 9, 1, 247, 11, 34, 241, 217, 235, 26, 41, 3, 236, 5, 4, 248, 212, 194, 13, 90, 59, 10, 202, 206, 1, 249, 0, 18, 37, 28, 249, 210, 212, 5, 33, 24, 37, 26, 227, 220, 233, 243, 14, 26, 14, 251, 254, 240, 214, 239, 30, 41, 41, 253, 222, 221, 227, 15, 56, 49, 10, 245, 222, 241, 245, 6, 255, 218, 243, 26, 19, 0, 247, 238, 32, 34, 243, 234, 236, 22, 39, 25, 4, 238, 230, 243, 232, 242, 9, 9, 34, 3, 236, 238, 255, 254, 20, 14, 10, 14, 16, 6, 204, 221, 11, 24, 31, 255, 241, 249, 248, 255, 246, 0, 24, 24, 3, 228, 236, 0, 250, 4, 15, 14, 16, 247, 232, 250, 28, 21, 247, 239, 2, 15, 8, 236, 215, 13, 31, 254, 221, 240, 40, 42, 244, 216, 255, 40, 16, 233, 222, 10, 55, 34, 220, 209, 232, 253, 247, 251, 53, 45, 1, 229, 219, 246, 32, 37, 243, 240, 3, 19, 255, 225, 219, 13, 22, 14, 5, 254, 3, 10, 238, 210, 243, 30, 40, 27, 16, 242, 246, 227, 229, 8, 18, 21, 14, 237, 238, 255, 241, 0, 253, 9, 36, 24, 230, 224, 0, 31, 35, 3, 238, 249, 3, 232, 222, 239, 11, 34, 15, 5, 249, 21, 10, 241, 239, 4, 30, 9, 225, 232, 13, 12, 246, 215, 242, 28, 29, 34, 15, 255, 246, 240, 230, 235, 30, 35, 254, 233, 235, 250, 8, 7, 249, 33, 39, 0, 228, 231, 240, 0, 245, 7, 22, 23, 15, 248, 218, 238, 12, 42, 28, 243, 239, 231, 221, 13, 32, 12, 0, 8, 249, 240, 231, 1, 37, 23, 14, 255, 224, 234, 237, 0, 24, 35, 251, 227, 251, 17, 2, 250, 253, 14, 27, 253, 226, 239, 13, 9, 255, 254, 24, 25, 242, 230, 231, 238, 10, 15, 22, 254, 253, 242, 10, 21, 237, 0, 19, 10, 11, 5, 227, 227, 13, 27, 255, 228, 245, 13, 18, 13, 234, 230, 13, 22, 254, 241, 4, 28, 20, 251, 235, 241, 5, 2, 248, 252, 252, 19, 12, 252, 251, 19, 3, 236, 5, 1, 252, 254, 243, 242, 13, 13, 249, 249, 2, 17, 28, 7, 246, 253, 249, 235, 6, 254, 5, 6, 254, 252, 6, 17, 242, 248, 244, 254, 39, 30, 224, 215, 255, 24, 27, 3, 228, 255, 18, 253, 229, 241, 17, 14, 31, 248, 234, 254, 15, 252, 11, 4, 0, 10, 9, 235, 213, 248, 34, 31, 242, 235, 242, 23, 7, 238, 252, 17, 3, 255, 2, 14, 37, 245, 220, 229, 9, 34, 15, 248, 244, 241, 238, 9, 36, 22, 241, 228, 230, 230, 18, 33, 23, 3, 234, 234, 22, 15, 237, 250, 16, 39, 21, 250, 226, 229, 251, 1, 15, 7, 6, 0, 238, 249, 254, 227, 241, 9, 33, 54, 30, 216, 198, 232, 11, 58, 59, 26, 255, 207, 199, 235, 0, 26, 44, 14, 234, 221, 242, 247, 245, 5, 26, 40, 9, 235, 224, 1, 23, 19, 5, 1, 0, 1, 252, 251, 255, 5, 25, 255, 217, 224, 249, 23, 16, 2, 241, 233, 255, 25, 10, 9, 11, 243, 3, 27, 14, 254, 252, 7, 225, 204, 8, 46, 20, 248, 214, 234, 15, 3, 253, 20, 21, 11, 246, 227, 0, 25, 28, 11, 227, 206, 247, 37, 42, 4, 247, 20, 240, 196, 207, 24, 51, 42, 8, 225, 239, 244, 250, 10, 24, 27, 7, 229, 209, 235, 15, 56, 40, 8, 229, 226, 232, 244, 6, 36, 12, 242, 227, 242, 11, 44, 29, 1, 0, 237, 230, 242, 6, 10, 28, 10, 207, 218, 11, 21, 31, 28, 235, 243, 254, 251, 251, 6, 32, 12, 252, 226, 0, 35, 249, 223, 230, 253, 29, 25, 243, 219, 2, 22, 7, 10, 245, 14, 27, 246, 235, 1, 0, 9, 12, 242, 239, 5, 4, 254, 247, 0, 10, 4, 250, 250, 30, 5, 220, 241, 9, 26, 26, 248, 242, 16, 20, 231, 212, 243, 15, 56, 18, 232, 247, 250, 238, 250, 246, 30, 32, 255, 239, 232, 232, 16, 26, 11, 26, 11, 254, 236, 226, 241, 5, 1, 250, 22, 18, 244, 225, 0, 24, 23, 19, 247, 242, 4, 0, 244, 253, 2, 22, 254, 223, 236, 14, 14, 250, 0, 24, 27, 250, 214, 222, 34, 58, 26, 221, 203, 253, 25, 19, 0, 240, 0, 11, 223, 243, 249, 11, 34, 252, 248, 14, 4, 25, 5, 223, 3, 14, 20, 0, 207, 227, 9, 21, 28, 9, 240, 243, 250, 0, 248, 2, 33, 22, 231, 210, 242, 37, 40, 15, 0, 238, 242, 6, 1, 228, 251, 19, 25, 255, 244, 242, 245, 239, 254, 15, 13, 18, 6, 253, 16, 7, 251, 251, 246, 254, 1, 3, 251, 231, 241, 1, 11, 36, 31, 243, 230, 13, 245, 247, 10, 254, 5, 26, 247, 215, 242, 11, 31, 28, 0, 246, 0, 239, 234, 242, 7, 16, 25, 0, 241, 253, 12, 0, 255, 250, 8, 29, 253, 221, 239, 16, 29, 15, 228, 216, 253, 25, 28, 255, 247, 255, 0, 22, 249, 237, 253, 8, 254, 252, 14, 19, 250, 251, 241, 252, 0, 13, 21, 5, 245, 233, 5, 9, 13, 12, 239, 214, 233, 18, 33, 29, 246, 232, 255, 31, 2, 255, 3, 250, 0, 252, 249, 8, 11, 240, 247, 0, 247, 7, 4, 246, 9, 28, 18, 246, 218, 238, 25, 29, 6, 249, 244, 238, 246, 255, 10, 38, 24, 241, 234, 240, 249, 16, 11, 20, 0, 240, 223, 232, 254, 33, 38, 14, 248, 220, 242, 12, 16, 17, 255, 243, 253, 0, 15, 12, 247, 1, 236, 218, 255, 25, 33, 27, 250, 234, 239, 0, 4, 242, 254, 39, 44, 0, 219, 206, 246, 20, 7, 243, 250, 30, 35, 237, 224, 255, 22, 30, 8, 5, 254, 5, 247, 229, 215, 252, 20, 28, 0, 234, 250, 3, 245, 245, 13, 28, 52, 18, 225, 224, 3, 23, 1, 254, 13, 2, 229, 206, 231, 13, 39, 19, 10, 0, 231, 236, 3, 17, 31, 28, 9, 247, 225, 217, 237, 5, 36, 37, 16, 237, 222, 227, 3, 15, 31, 10, 243, 246, 236, 18, 31, 247, 237, 6, 23, 2, 237, 240, 239, 5, 26, 2, 255, 2, 1, 13, 242, 242, 253, 0, 28, 29, 249, 226, 243, 2, 9, 255, 11, 18, 8, 242, 226, 232, 11, 22, 20, 13, 253, 244, 233, 228, 248, 15, 47, 42, 243, 228, 244, 252, 20, 21, 0, 10, 231, 207, 254, 26, 14, 254, 244, 248, 24, 13, 245, 224, 252, 29, 24, 0, 235, 2, 19, 26, 249, 231, 247, 17, 255, 236, 253, 7, 0, 248, 0, 2, 251, 0, 255, 14, 29, 12, 239, 238, 253, 8, 27, 9, 245, 237, 240, 1, 8, 3, 13, 5, 243, 236, 1, 2, 252, 4, 25, 6, 4, 255, 249, 255, 239, 10, 27, 254, 244, 246, 241, 0, 19, 4, 3, 9, 247, 1, 16, 240, 244, 248, 250, 6, 4, 13, 13, 249, 239, 255, 14, 23, 9, 251, 237, 246, 2, 28, 11, 245, 222, 243, 6, 18, 4, 1, 237, 1, 11, 7, 251, 246, 8, 29, 8, 2, 253, 236, 229, 5, 25, 13, 16, 245, 225, 232, 1, 15, 20, 7, 246, 4, 245, 0, 13, 1, 249, 8, 14, 18, 246, 211, 246, 25, 31, 0, 253, 249, 231, 0, 2, 7, 31, 16, 249, 228, 211, 241, 31, 35, 16, 2, 241, 241, 237, 255, 27, 21, 6, 243, 242, 252, 3, 14, 8, 1, 2, 248, 234, 2, 3, 13, 7, 230, 227, 14, 11, 13, 19, 2, 254, 2, 236, 244, 21, 19, 0, 255, 0, 250, 241, 233, 252, 18, 19, 19, 7, 241, 245, 239, 233, 9, 29, 28, 8, 253, 241, 238, 231, 242, 11, 43, 27, 5, 237, 223, 243, 15, 14, 11, 16, 0, 241, 247, 0, 245, 245, 245, 20, 38, 16, 243, 226, 236, 10, 21, 1, 247, 255, 0, 22, 3, 237, 0, 0, 10, 15, 1, 5, 248, 240, 1, 4, 249, 248, 255, 255, 2, 3, 2, 17, 8, 251, 235, 253, 24, 25, 7, 236, 239, 5, 254, 248, 6, 0, 8, 0, 246, 250, 4, 9, 17, 11, 245, 244, 246, 247, 14, 11, 242, 238, 6, 29, 30, 4, 232, 245, 253, 248, 0, 251, 0, 24, 23, 243, 220, 235, 7, 37, 32, 254, 238, 242, 255, 1, 7, 6, 8, 253, 235, 238, 7, 6, 7, 12, 2, 13, 248, 223, 11, 40, 14, 243, 240, 229, 228, 5, 23, 40, 44, 246, 206, 221, 240, 12, 28, 15, 8, 3, 0, 238, 230, 0, 37, 30, 251, 239, 254, 2, 246, 243, 246, 6, 22, 12, 1, 253, 246, 240, 251, 7, 15, 10, 4, 9, 248, 246, 242, 249, 255, 6, 15, 13, 7, 247, 244, 253, 0, 2, 16, 23, 251, 231, 244, 6, 9, 13, 252, 239, 251, 252, 252, 10, 13, 8, 254, 252, 243, 5, 13, 9, 2, 3, 247, 245, 6, 9, 0, 0, 95, 9, 10, 0, 223, 218, 13, 232, 202, 44, 18, 246, 1, 244, 0, 22, 52, 32, 248, 255, 36, 26, 5, 21, 28, 252, 15, 227, 225, 204, 189, 5, 237, 242, 244, 207, 2, 240, 254, 62, 56, 11, 255, 52, 34, 28, 42, 53, 11, 173, 209, 255, 13, 243, 224, 183, 191, 210, 26, 43, 246, 24, 39, 22, 254, 249, 20, 84, 64, 3, 236, 201, 192, 225, 0, 12, 29, 26, 238, 204, 243, 250, 246, 62, 46, 45, 246, 226, 187, 209, 13, 63, 75, 9, 216, 233, 204, 203, 8, 41, 40, 7, 17, 217, 206, 25, 50, 43, 55, 40, 1, 207, 187, 212, 21, 10, 6, 226, 188, 207, 239, 0, 10, 60, 74, 57, 5, 229, 9, 65, 53, 46, 238, 206, 218, 245, 203, 148, 179, 4, 40, 1, 2, 212, 223, 56, 105, 101, 51, 2, 46, 16, 20, 23, 201, 177, 209, 225, 228, 207, 161, 205, 11, 240, 26, 59, 72, 73, 51, 47, 32, 17, 9, 49, 251, 229, 204, 201, 207, 167, 188, 16, 244, 248, 27, 252, 241, 20, 64, 91, 52, 23, 28, 6, 224, 239, 250, 242, 231, 238, 216, 183, 243, 45, 46, 239, 11, 0, 5, 11, 7, 29, 225, 248, 38, 0, 198, 220, 23, 25, 7, 23, 17, 225, 0, 44, 32, 8, 6, 21, 238, 204, 226, 223, 242, 236, 6, 247, 204, 211, 38, 96, 39, 249, 10, 20, 51, 50, 12, 0, 234, 227, 0, 251, 202, 184, 223, 5, 247, 218, 251, 15, 7, 60, 34, 10, 47, 30, 7, 243, 13, 42, 242, 241, 233, 209, 200, 240, 27, 8, 229, 253, 19, 217, 253, 58, 245, 235, 47, 49, 25, 229, 253, 14, 19, 10, 1, 230, 215, 231, 10, 238, 204, 249, 12, 254, 14, 52, 16, 230, 33, 45, 236, 29, 33, 31, 223, 164, 239, 30, 234, 218, 253, 242, 238, 239, 22, 19, 40, 18, 46, 46, 16, 248, 244, 250, 234, 247, 11, 239, 206, 177, 227, 32, 38, 11, 240, 14, 33, 37, 0, 240, 250, 35, 74, 30, 214, 169, 215, 39, 24, 23, 210, 196, 0, 236, 4, 33, 2, 35, 48, 28, 251, 184, 226, 59, 41, 243, 253, 223, 231, 239, 232, 250, 4, 76, 79, 2, 218, 204, 231, 17, 46, 32, 237, 230, 236, 250, 224, 214, 2, 19, 49, 34, 251, 182, 220, 49, 65, 53, 18, 13, 242, 229, 19, 2, 216, 221, 255, 26, 253, 207, 159, 202, 10, 60, 52, 19, 12, 22, 47, 24, 235, 3, 55, 65, 54, 188, 160, 178, 211, 250, 40, 19, 221, 231, 211, 205, 32, 70, 61, 50, 34, 16, 247, 240, 253, 31, 33, 4, 0, 171, 200, 235, 251, 219, 209, 60, 14, 233, 242, 17, 38, 45, 59, 63, 250, 207, 21, 28, 196, 225, 22, 7, 178, 186, 59, 238, 199, 244, 24, 37, 17, 26, 58, 250, 7, 66, 21, 242, 5, 19, 240, 199, 178, 235, 38, 35, 201, 141, 166, 40, 104, 47, 234, 5, 74, 53, 22, 1, 5, 64, 70, 3, 185, 146, 191, 0, 4, 192, 211, 223, 19, 6, 228, 2, 33, 66, 84, 84, 36, 229, 0, 21, 42, 19, 220, 244, 180, 179, 238, 227, 211, 158, 226, 61, 32, 31, 25, 18, 47, 72, 85, 27, 21, 18, 0, 210, 187, 230, 218, 189, 231, 232, 2, 238, 218, 6, 48, 65, 27, 19, 39, 37, 251, 12, 59, 26, 231, 199, 218, 214, 175, 220, 50, 12, 224, 211, 254, 14, 28, 62, 81, 45, 19, 21, 1, 201, 215, 54, 16, 241, 202, 154, 168, 3, 22, 7, 253, 15, 28, 21, 32, 37, 51, 26, 57, 36, 0, 234, 225, 218, 177, 220, 5, 250, 237, 188, 191, 253, 36, 48, 57, 39, 11, 23, 29, 20, 19, 37, 36, 0, 213, 245, 225, 244, 201, 195, 230, 237, 12, 9, 232, 187, 19, 45, 64, 66, 22, 19, 11, 32, 49, 27, 1, 224, 217, 211, 210, 221, 212, 218, 248, 31, 222, 255, 34, 26, 21, 32, 59, 17, 10, 45, 5, 246, 227, 231, 13, 237, 200, 213, 240, 210, 241, 47, 34, 25, 251, 1, 38, 26, 14, 20, 45, 6, 216, 231, 246, 220, 203, 254, 33, 244, 238, 252, 0, 229, 2, 60, 27, 38, 9, 5, 252, 255, 2, 27, 237, 220, 16, 44, 202, 178, 244, 254, 28, 33, 244, 177, 35, 47, 6, 255, 247, 55, 39, 251, 227, 253, 25, 22, 243, 233, 223, 20, 246, 219, 229, 3, 35, 254, 17, 217, 0, 5, 30, 64, 245, 194, 255, 38, 24, 241, 3, 10, 236, 224, 33, 17, 231, 213, 9, 52, 255, 0, 5, 211, 230, 35, 61, 21, 174, 231, 17, 254, 0, 24, 12, 228, 27, 2, 236, 229, 9, 61, 35, 12, 241, 207, 250, 253, 47, 22, 202, 226, 226, 4, 251, 251, 5, 18, 16, 11, 23, 0, 229, 236, 40, 60, 17, 216, 229, 224, 13, 31, 7, 229, 226, 254, 31, 4, 218, 234, 22, 46, 21, 17, 217, 207, 8, 38, 20, 234, 238, 19, 2, 232, 5, 19, 12, 249, 3, 9, 21, 234, 235, 18, 4, 10, 13, 245, 212, 227, 28, 11, 237, 0, 1, 252, 235, 22, 17, 15, 22, 19, 27, 250, 5, 1, 223, 242, 10, 20, 221, 219, 230, 225, 17, 24, 10, 231, 24, 64, 16, 242, 224, 16, 47, 36, 1, 224, 209, 247, 4, 251, 234, 243, 251, 253, 15, 6, 254, 236, 7, 55, 44, 254, 201, 246, 53, 20, 251, 231, 236, 23, 19, 5, 180, 217, 23, 22, 247, 237, 240, 22, 17, 9, 2, 248, 20, 30, 62, 14, 238, 2, 245, 245, 222, 240, 254, 223, 0, 233, 202, 12, 12, 29, 251, 34, 54, 250, 1, 10, 28, 7, 19, 27, 237, 208, 233, 8, 246, 232, 2, 245, 224, 9, 5, 243, 210, 33, 55, 249, 229, 254, 68, 4, 251, 35, 32, 27, 6, 10, 227, 164, 5, 59, 232, 168, 248, 247, 223, 247, 13, 10, 228, 50, 53, 16, 11, 18, 66, 0, 6, 23, 0, 252, 222, 236, 218, 188, 235, 243, 7, 227, 229, 18, 11, 19, 32, 50, 39, 17, 41, 14, 225, 242, 25, 28, 191, 214, 7, 249, 206, 229, 255, 4, 238, 59, 7, 209, 35, 57, 11, 211, 34, 54, 20, 224, 224, 242, 0, 0, 32, 210, 213, 10, 31, 9, 211, 4, 254, 43, 37, 235, 230, 251, 7, 46, 1, 220, 228, 48, 47, 213, 233, 233, 10, 48, 6, 232, 206, 249, 36, 13, 5, 235, 5, 13, 2, 2, 210, 0, 56, 51, 231, 208, 32, 5, 241, 247, 5, 233, 255, 34, 241, 205, 241, 32, 44, 41, 234, 200, 11, 29, 20, 18, 217, 237, 19, 7, 252, 236, 250, 3, 16, 32, 236, 223, 254, 255, 42, 12, 215, 237, 29, 38, 250, 244, 244, 246, 31, 17, 221, 234, 33, 28, 224, 210, 2, 32, 51, 2, 215, 228, 5, 40, 8, 232, 227, 13, 48, 254, 239, 230, 225, 58, 45, 1, 183, 220, 23, 42, 34, 170, 226, 70, 56, 237, 203, 255, 33, 50, 19, 221, 216, 230, 20, 14, 228, 3, 0, 255, 233, 245, 9, 5, 35, 254, 13, 5, 35, 18, 2, 237, 254, 15, 17, 232, 195, 235, 15, 253, 232, 237, 229, 28, 43, 25, 225, 235, 38, 50, 42, 232, 0, 4, 28, 13, 238, 208, 242, 10, 13, 214, 213, 238, 22, 246, 215, 255, 15, 52, 37, 246, 38, 32, 46, 3, 212, 6, 6, 30, 232, 196, 215, 241, 5, 196, 236, 35, 19, 34, 245, 246, 39, 30, 14, 7, 45, 34, 249, 228, 179, 216, 20, 48, 247, 203, 208, 249, 12, 7, 22, 35, 34, 26, 13, 14, 244, 249, 12, 0, 3, 242, 201, 208, 214, 237, 9, 48, 30, 10, 227, 231, 27, 59, 67, 36, 27, 247, 222, 233, 237, 234, 245, 237, 223, 252, 227, 214, 4, 220, 251, 55, 81, 57, 3, 239, 244, 33, 54, 36, 22, 3, 241, 199, 188, 195, 228, 8, 2, 240, 0, 222, 246, 235, 27, 80, 36, 32, 60, 36, 237, 206, 247, 48, 39, 11, 230, 173, 172, 246, 22, 250, 244, 243, 3, 255, 3, 239, 24, 45, 48, 24, 21, 12, 241, 252, 4, 253, 3, 247, 5, 227, 190, 227, 230, 38, 46, 238, 250, 15, 8, 21, 228, 249, 71, 8, 246, 247, 245, 226, 235, 35, 39, 211, 5, 21, 22, 239, 215, 24, 34, 17, 12, 217, 211, 0, 6, 231, 217, 255, 17, 29, 255, 255, 250, 40, 45, 20, 33, 22, 3, 4, 218, 235, 221, 236, 2, 225, 225, 216, 233, 2, 7, 23, 26, 48, 21, 13, 28, 14, 35, 34, 30, 4, 202, 236, 211, 224, 251, 215, 225, 224, 233, 1, 253, 15, 16, 36, 56, 53, 52, 16, 15, 3, 0, 1, 245, 238, 216, 223, 220, 225, 219, 224, 252, 5, 24, 11, 5, 22, 47, 40, 4, 24, 32, 51, 11, 230, 246, 248, 220, 219, 225, 222, 217, 254, 242, 209, 252, 30, 75, 32, 11, 2, 25, 63, 27, 253, 246, 251, 4, 249, 238, 213, 219, 230, 222, 0, 240, 229, 18, 16, 13, 0, 35, 45, 32, 14, 23, 33, 12, 233, 244, 10, 236, 212, 247, 211, 189, 235, 22, 252, 249, 10, 13, 32, 29, 14, 23, 27, 57, 51, 254, 210, 213, 5, 247, 239, 235, 229, 213, 251, 3, 200, 234, 37, 48, 52, 11, 252, 2, 8, 36, 35, 15, 248, 247, 20, 235, 212, 236, 243, 1, 1, 232, 237, 236, 239, 0, 17, 12, 252, 21, 51, 12, 1, 21, 19, 12, 23, 30, 7, 210, 228, 234, 230, 220, 226, 2, 0, 221, 238, 1, 2, 28, 40, 41, 38, 23, 8, 254, 11, 31, 22, 239, 235, 228, 232, 237, 214, 223, 238, 252, 9, 1, 241, 0, 17, 31, 34, 35, 23, 7, 35, 25, 254, 224, 253, 241, 249, 251, 236, 221, 226, 246, 247, 246, 247, 12, 22, 24, 21, 255, 255, 18, 34, 41, 9, 241, 230, 11, 20, 214, 212, 10, 6, 235, 236, 236, 0, 5, 15, 9, 241, 4, 48, 48, 247, 215, 11, 23, 20, 13, 249, 232, 226, 7, 250, 244, 233, 236, 11, 11, 245, 252, 11, 24, 5, 18, 32, 4, 254, 25, 6, 242, 229, 236, 248, 240, 243, 6, 249, 226, 250, 13, 20, 17, 20, 31, 8, 255, 32, 253, 217, 7, 15, 249, 252, 247, 227, 208, 235, 20, 13, 255, 242, 17, 37, 20, 13, 5, 246, 19, 39, 18, 219, 216, 249, 245, 255, 236, 230, 0, 28, 12, 213, 253, 38, 31, 36, 227, 241, 21, 40, 31, 233, 204, 231, 33, 38, 228, 201, 231, 18, 22, 252, 234, 229, 21, 37, 36, 5, 236, 7, 32, 1, 241, 4, 3, 253, 10, 17, 215, 225, 7, 248, 237, 246, 3, 243, 0, 23, 11, 250, 11, 36, 22, 9, 13, 15, 255, 247, 253, 246, 225, 2, 11, 218, 215, 245, 0, 15, 7, 8, 255, 5, 32, 2, 0, 15, 37, 37, 249, 223, 227, 15, 25, 243, 214, 243, 13, 235, 225, 250, 15, 22, 8, 6, 0, 246, 18, 41, 0, 0, 7, 3, 245, 245, 246, 253, 5, 236, 231, 5, 11, 21, 0, 255, 4, 252, 16, 1, 7, 3, 252, 8, 231, 243, 250, 16, 2, 246, 9, 250, 241, 1, 8, 242, 1, 36, 18, 2, 255, 0, 6, 15, 31, 12, 246, 223, 235, 240, 207, 230, 1, 11, 255, 238, 231, 254, 33, 62, 34, 28, 42, 27, 23, 16, 226, 221, 253, 0, 233, 206, 195, 198, 223, 250, 3, 13, 17, 22, 42, 40, 37, 41, 37, 34, 26, 10, 0, 236, 216, 204, 214, 223, 216, 221, 248, 5, 241, 249, 3, 23, 60, 55, 33, 21, 7, 23, 25, 254, 238, 235, 245, 236, 234, 222, 216, 249, 9, 252, 0, 19, 48, 13, 233, 254, 18, 42, 7, 239, 239, 228, 248, 0, 254, 250, 0, 17, 11, 0, 10, 31, 20, 2, 253, 11, 250, 239, 230, 211, 234, 6, 249, 239, 236, 0, 20, 11, 19, 27, 40, 39, 16, 16, 28, 248, 243, 250, 237, 229, 211, 228, 232, 221, 236, 241, 253, 252, 45, 66, 9, 13, 47, 38, 36, 5, 0, 246, 239, 15, 240, 196, 173, 206, 16, 12, 241, 239, 247, 19, 32, 29, 32, 31, 54, 46, 16, 242, 235, 243, 243, 235, 216, 205, 231, 246, 246, 240, 253, 16, 46, 39, 17, 20, 11, 14, 16, 9, 3, 255, 0, 254, 229, 200, 218, 255, 5, 17, 234, 239, 1, 11, 20, 11, 15, 37, 36, 19, 255, 233, 4, 10, 7, 0, 221, 226, 236, 228, 231, 240, 13, 6, 2, 16, 14, 17, 26, 19, 21, 29, 19, 2, 248, 225, 237, 254, 0, 241, 214, 238, 247, 251, 4, 1, 250, 23, 30, 10, 8, 12, 6, 8, 15, 7, 245, 253, 22, 252, 231, 229, 247, 11, 8, 247, 235, 250, 255, 247, 243, 19, 5, 7, 33, 16, 245, 238, 24, 34, 250, 254, 14, 255, 236, 249, 8, 226, 232, 12, 20, 248, 232, 245, 249, 0, 11, 17, 3, 251, 36, 26, 239, 245, 22, 21, 248, 254, 13, 242, 225, 247, 245, 232, 13, 22, 249, 245, 7, 3, 243, 20, 33, 251, 253, 7, 255, 244, 251, 248, 252, 24, 19, 248, 239, 245, 12, 255, 242, 13, 30, 6, 245, 233, 240, 0, 27, 14, 245, 245, 244, 1, 21, 239, 228, 5, 36, 28, 245, 233, 245, 21, 29, 14, 245, 252, 7, 7, 253, 229, 228, 253, 20, 253, 229, 232, 254, 12, 14, 11, 5, 7, 31, 41, 2, 247, 0, 26, 2, 235, 244, 229, 248, 236, 209, 237, 1, 0, 6, 19, 21, 21, 13, 15, 27, 18, 25, 18, 245, 221, 246, 20, 232, 195, 229, 7, 17, 244, 229, 239, 9, 39, 38, 7, 238, 23, 58, 22, 218, 240, 21, 23, 240, 221, 233, 235, 247, 254, 8, 246, 241, 29, 11, 238, 1, 18, 28, 22, 255, 1, 253, 4, 11, 242, 229, 254, 15, 249, 233, 0, 15, 9, 76, 0, 239, 0, 5, 252, 8, 8, 8, 14, 14, 250, 7, 251, 253, 8, 245, 249, 0, 6, 18, 26, 22, 21, 15, 12, 0, 245, 240, 240, 247, 5, 17, 20, 27, 18, 18, 5, 248, 255, 248, 237, 246, 0, 1, 17, 25, 16, 4, 6, 2, 5, 5, 5, 245, 0, 9, 2, 255, 4, 248, 254, 14, 12, 14, 8, 0, 2, 5, 4, 253, 233, 249, 4, 11, 13, 8, 11, 17, 17, 252, 238, 233, 248, 247, 0, 2, 3, 22, 41, 18, 253, 253, 230, 236, 238, 228, 236, 14, 27, 32, 26, 9, 11, 6, 247, 233, 221, 226, 246, 255, 5, 17, 34, 28, 21, 5, 227, 226, 239, 245, 236, 238, 246, 7, 27, 26, 10, 7, 12, 12, 5, 254, 236, 239, 242, 244, 6, 7, 7, 16, 29, 19, 7, 10, 247, 235, 237, 232, 235, 245, 1, 6, 255, 15, 7, 15, 10, 253, 249, 248, 235, 238, 238, 237, 251, 255, 253, 12, 21, 13, 17, 251, 242, 243, 248, 248, 245, 247, 1, 6, 3, 11, 2, 3, 251, 249, 253, 243, 3, 11, 240, 244, 11, 251, 10, 22, 10, 18, 16, 10, 1, 238, 239, 241, 240, 251, 3, 8, 9, 1, 2, 8, 10, 0, 249, 241, 242, 251, 239, 236, 251, 9, 9, 20, 11, 15, 18, 1, 238, 224, 225, 241, 246, 250, 6, 24, 30, 35, 17, 10, 255, 254, 246, 238, 248, 254, 14, 14, 15, 8, 18, 11, 19, 2, 254, 3, 0, 0, 0, 251, 14, 15, 255, 9, 247, 4, 5, 247, 244, 241, 254, 25, 23, 16, 255, 255, 20, 12, 12, 252, 236, 0, 30, 9, 0, 255, 2, 15, 34, 16, 255, 255, 18, 28, 13, 251, 245, 14, 17, 18, 20, 0, 0, 18, 5, 254, 250, 250, 245, 252, 3, 242, 0, 13, 254, 10, 8, 252, 18, 30, 7, 0, 8, 10, 1, 8, 246, 224, 3, 29, 19, 20, 20, 2, 4, 252, 230, 227, 250, 4, 11, 10, 8, 11, 15, 10, 5, 245, 234, 9, 11, 3, 12, 26, 13, 25, 11, 255, 9, 14, 255, 243, 255, 12, 11, 29, 26, 29, 29, 5, 0, 249, 252, 239, 238, 242, 14, 32, 38, 28, 31, 18, 9, 237, 227, 225, 245, 252, 7, 29, 3, 32, 31, 8, 16, 247, 246, 5, 250, 253, 20, 17, 20, 19, 254, 22, 26, 18, 0, 251, 246, 247, 11, 5, 250, 5, 11, 5, 31, 13, 13, 15, 8, 1, 250, 0, 5, 14, 14, 24, 0, 13, 27, 8, 0, 250, 248, 3, 6, 3, 19, 8, 11, 21, 0, 245, 237, 233, 225, 236, 4, 10, 28, 36, 42, 41, 35, 8, 239, 220, 229, 222, 218, 241, 247, 27, 52, 35, 25, 27, 249, 246, 231, 211, 217, 247, 253, 15, 14, 4, 9, 21, 16, 5, 240, 222, 238, 242, 251, 239, 242, 9, 14, 19, 9, 243, 247, 0, 2, 243, 226, 234, 7, 12, 7, 246, 0, 9, 20, 16, 250, 237, 253, 7, 238, 0, 248, 2, 26, 18, 254, 11, 25, 13, 6, 3, 0, 10, 26, 0, 243, 2, 15, 12, 254, 239, 250, 8, 5, 231, 231, 236, 13, 26, 17, 10, 6, 6, 253, 223, 212, 219, 223, 249, 23, 30, 35, 34, 26, 251, 229, 219, 206, 225, 253, 2, 0, 22, 28, 35, 24, 31, 11, 243, 11, 249, 243, 240, 249, 251, 22, 21, 9, 28, 19, 0, 3, 245, 225, 0, 251, 253, 13, 7, 9, 27, 11, 1, 245, 240, 11, 250, 5, 253, 240, 6, 20, 9, 19, 11, 12, 5, 255, 6, 250, 245, 235, 250, 17, 41, 35, 40, 9, 254, 253, 246, 227, 231, 244, 245, 30, 27, 12, 26, 29, 249, 244, 233, 219, 251, 4, 232, 253, 20, 15, 45, 20, 243, 0, 8, 0, 253, 229, 247, 19, 3, 35, 27, 12, 17, 254, 241, 234, 229, 226, 241, 243, 20, 22, 17, 22, 9, 250, 251, 239, 238, 235, 233, 224, 252, 21, 6, 21, 14, 255, 16, 20, 234, 247, 244, 0, 10, 21, 26, 23, 40, 37, 2, 236, 221, 213, 236, 11, 0, 8, 22, 67, 56, 31, 5, 237, 246, 247, 214, 212, 250, 5, 22, 22, 22, 12, 34, 34, 0, 239, 249, 226, 246, 255, 232, 245, 1, 24, 37, 37, 31, 14, 8, 0, 241, 222, 214, 219, 234, 234, 12, 37, 44, 58, 41, 12, 254, 246, 243, 208, 201, 224, 3, 40, 54, 35, 20, 32, 43, 12, 233, 228, 228, 220, 240, 236, 235, 25, 51, 49, 32, 13, 0, 2, 247, 217, 191, 220, 232, 6, 41, 252, 7, 45, 12, 253, 238, 200, 253, 10, 252, 248, 232, 249, 26, 7, 18, 250, 6, 29, 0, 15, 5, 249, 244, 236, 235, 10, 20, 11, 247, 238, 4, 24, 15, 11, 0, 239, 233, 239, 228, 219, 230, 7, 0, 21, 21, 16, 24, 9, 221, 215, 217, 219, 5, 252, 16, 13, 19, 34, 40, 27, 252, 234, 237, 224, 224, 242, 223, 3, 30, 19, 34, 35, 18, 3, 220, 211, 191, 185, 221, 225, 252, 36, 50, 65, 54, 32, 4, 224, 211, 208, 192, 205, 239, 2, 6, 44, 55, 28, 40, 10, 240, 218, 216, 206, 206, 233, 249, 13, 35, 41, 45, 28, 14, 9, 241, 216, 204, 214, 240, 249, 9, 5, 3, 33, 18, 245, 228, 213, 239, 252, 254, 13, 21, 9, 31, 0, 228, 225, 230, 242, 9, 8, 0, 10, 12, 30, 13, 4, 238, 223, 243, 11, 236, 215, 205, 223, 4, 31, 23, 253, 9, 10, 0, 239, 209, 198, 233, 241, 246, 15, 0, 8, 30, 25, 35, 14, 234, 231, 220, 219, 220, 225, 244, 27, 42, 18, 36, 28, 255, 226, 212, 214, 242, 244, 0, 255, 4, 35, 40, 18, 246, 236, 241, 250, 236, 226, 216, 240, 4, 34, 20, 6, 7, 0, 5, 3, 251, 229, 3, 4, 13, 3, 11, 23, 22, 255, 5, 251, 1, 30, 15, 255, 230, 2, 6, 18, 5, 4, 9, 19, 23, 0, 239, 225, 234, 236, 21, 14, 12, 12, 15, 254, 250, 231, 206, 226, 231, 251, 19, 35, 9, 3, 4, 16, 2, 249, 252, 236, 230, 247, 233, 240, 1, 253, 17, 31, 43, 39, 13, 0, 247, 242, 255, 225, 232, 15, 28, 50, 34, 21, 36, 5, 238, 231, 203, 216, 227, 219, 245, 6, 20, 14, 30, 39, 248, 228, 234, 201, 204, 210, 198, 240, 12, 44, 58, 36, 37, 45, 19, 5, 246, 216, 212, 234, 250, 10, 47, 55, 59, 53, 10, 14, 26, 250, 220, 216, 228, 7, 32, 8, 0, 7, 242, 248, 240, 206, 219, 214, 209, 234, 250, 6, 15, 240, 254, 245, 236, 246, 245, 240, 11, 250, 2, 12, 252, 16, 13, 245, 248, 254, 14, 23, 14, 8, 255, 3, 29, 33, 252, 20, 11, 248, 252, 243, 236, 12, 6, 4, 1, 254, 237, 231, 23, 25, 30, 16, 22, 253, 254, 203, 189, 218, 211, 255, 15, 14, 53, 69, 27, 0, 223, 221, 229, 223, 229, 14, 27, 39, 69, 53, 23, 250, 222, 223, 240, 218, 220, 255, 27, 75, 73, 30, 27, 17, 242, 230, 223, 202, 223, 253, 248, 14, 47, 30, 8, 7, 11, 251, 238, 225, 211, 225, 11, 16, 16, 19, 254, 25, 29, 0, 240, 222, 245, 30, 28, 25, 15, 20, 29, 20, 7, 0, 249, 244, 15, 250, 251, 4, 0, 254, 21, 18, 3, 5, 253, 2, 0, 19, 11, 242, 20, 21, 4, 22, 238, 222, 239, 240, 1, 11, 34, 36, 27, 13, 36, 247, 230, 212, 186, 233, 3, 253, 17, 25, 20, 71, 48, 15, 244, 205, 200, 221, 222, 250, 38, 37, 57, 51, 36, 19, 252, 217, 197, 188, 229, 6, 250, 5, 11, 26, 39, 31, 3, 0, 248, 255, 249, 246, 1, 2, 32, 12, 9, 25, 58, 40, 29, 25, 2, 255, 233, 238, 217, 228, 239, 245, 17, 15, 238, 10, 3, 234, 249, 226, 203, 227, 18, 26, 252, 7, 6, 21, 33, 0, 236, 249, 235, 249, 249, 8, 37, 40, 47, 27, 17, 255, 5, 10, 13, 238, 254, 31, 5, 22, 35, 255, 31, 25, 225, 237, 234, 249, 255, 249, 227, 0, 9, 3, 244, 223, 245, 228, 244, 32, 20, 241, 224, 243, 4, 254, 11, 11, 238, 19, 34, 252, 3, 255, 227, 11, 7, 14, 18, 252, 2, 243, 250, 241, 238, 0, 12, 253, 3, 0, 7, 7, 14, 248, 237, 247, 231, 252, 7, 245, 244, 6, 247, 6, 20, 252, 254, 16, 250, 230, 236, 221, 215, 233, 4, 11, 19, 49, 57, 27, 252, 224, 218, 233, 240, 254, 252, 17, 50, 46, 48, 5, 237, 254, 240, 243, 26, 241, 216, 248, 232, 9, 23, 243, 254, 22, 243, 5, 242, 234, 246, 230, 241, 239, 1, 251, 20, 15, 19, 21, 31, 5, 0, 0, 247, 230, 255, 14, 6, 8, 245, 253, 231, 227, 212, 222, 248, 0, 237, 233, 220, 237, 250, 218, 245, 250, 5, 41, 41, 235, 4, 10, 255, 0, 0, 252, 238, 244, 12, 23, 50, 45, 17, 25, 35, 21, 240, 222, 219, 251, 254, 251, 229, 241, 14, 31, 47, 247, 248, 6, 252, 253, 231, 211, 218, 252, 6, 5, 34, 38, 20, 45, 23, 243, 230, 220, 183, 207, 233, 227, 26, 36, 67, 74, 67, 253, 252, 241, 210, 194, 199, 200, 236, 52, 15, 32, 42, 56, 59, 35, 220, 179, 213, 185, 195, 218, 236, 44, 114, 107, 84, 73, 10, 224, 170, 149, 151, 207, 250, 39, 89, 82, 98, 76, 42, 244, 202, 200, 150, 152, 202, 229, 244, 60, 79, 98, 97, 68, 3, 202, 179, 139, 132, 190, 252, 50, 92, 73, 89, 50, 255, 233, 187, 163, 200, 211, 213, 17, 14, 22, 64, 27, 19, 39, 0, 236, 2, 234, 236, 17, 10, 238, 15, 42, 27, 17, 7, 254, 23, 2, 252, 224, 227, 237, 227, 5, 16, 252, 28, 24, 246, 236, 200, 237, 249, 240, 237, 241, 239, 8, 7, 235, 0, 8, 30, 46, 36, 7, 9, 24, 27, 255, 253, 11, 253, 23, 253, 242, 248, 246, 249, 241, 241, 250, 5, 17, 8, 10, 8, 2, 10, 248, 244, 253, 249, 6, 255, 5, 1, 223, 231, 11, 255, 12, 16, 228, 228, 238, 209, 174, 200, 233, 20, 44, 46, 20, 7, 0, 0, 252, 225, 241, 14, 21, 11, 250, 18, 27, 246, 230, 212, 217, 217, 196, 227, 238, 238, 24, 30, 19, 0, 231, 221, 217, 207, 198, 192, 214, 253, 21, 34, 26, 36, 8, 229, 4, 234, 188, 213, 195, 191, 240, 29, 13, 68, 58, 49, 63, 11, 255, 247, 203, 219, 225, 232, 13, 18, 28, 61, 41, 28, 13, 207, 177, 192, 194, 215, 210, 234, 4, 37, 38, 29, 1, 24, 15, 3, 248, 217, 251, 21, 7, 246, 31, 44, 65, 62, 32, 247, 0, 255, 199, 202, 222, 255, 8, 27, 1, 240, 0, 12, 252, 230, 215, 243, 10, 4, 7, 239, 246, 252, 239, 5, 29, 6, 9, 22, 12, 23, 245, 245, 0, 21, 15, 14, 35, 29, 20, 23, 248, 231, 241, 254, 244, 247, 248, 5, 247, 228, 5, 8, 5, 9, 241, 200, 226, 238, 219, 235, 252, 24, 42, 58, 7, 247, 240, 234, 217, 236, 253, 37, 37, 254, 26, 246, 249, 0, 225, 230, 250, 20, 236, 244, 254, 248, 4, 246, 4, 31, 37, 36, 22, 12, 12, 23, 230, 176, 209, 242, 2, 43, 54, 89, 95, 81, 34, 221, 225, 217, 168, 178, 225, 14, 82, 100, 70, 38, 43, 34, 238, 209, 217, 201, 209, 246, 9, 9, 54, 62, 14, 17, 9, 250, 0, 236, 219, 237, 254, 31, 12, 14, 30, 24, 253, 254, 248, 238, 228, 244, 253, 7, 41, 15, 26, 7, 0, 1, 1, 235, 5, 8, 8, 34, 37, 19, 19, 24, 10, 25, 9, 14, 38, 18, 19, 15, 38, 23, 6, 238, 237, 246, 246, 15, 254, 28, 46, 34, 3, 223, 224, 255, 213, 222, 229, 232, 35, 34, 43, 33, 29, 254, 250, 237, 225, 231, 17, 39, 27, 60, 43, 30, 34, 23, 14, 238, 246, 251, 255, 14, 25, 45, 31, 18, 43, 28, 244, 230, 191, 168, 211, 215, 244, 26, 39, 48, 60, 37, 245, 242, 196, 189, 220, 216, 239, 18, 39, 60, 74, 48, 24, 230, 214, 228, 217, 234, 231, 238, 15, 53, 49, 56, 23, 1, 5, 230, 229, 207, 205, 223, 204, 218, 25, 42, 49, 23, 239, 241, 240, 240, 229, 200, 213, 248, 15, 29, 24, 32, 24, 14, 31, 31, 11, 8, 11, 15, 250, 253, 17, 253, 252, 249, 229, 245, 15, 250, 236, 232, 227, 230, 227, 226, 209, 224, 251, 246, 230, 242, 15, 21, 19, 244, 242, 3, 1, 206, 182, 186, 243, 37, 30, 6, 0, 56, 62, 16, 238, 216, 216, 215, 199, 222, 220, 7, 39, 32, 46, 38, 11, 242, 214, 188, 176, 182, 201, 230, 247, 16, 37, 27, 5, 253, 238, 225, 233, 219, 217, 237, 234, 242, 220, 246, 19, 26, 34, 41, 28, 23, 9, 231, 199, 199, 212, 226, 225, 234, 28, 35, 52, 38, 26, 2, 247, 237, 220, 209, 194, 214, 238, 6, 21, 22, 46, 64, 43, 17, 227, 215, 221, 215, 230, 234, 247, 26, 41, 48, 41, 255, 11, 16, 248, 236, 212, 209, 234, 239, 245, 18, 28, 51, 40, 1, 245, 235, 243, 244, 230, 242, 12, 26, 37, 0, 254, 252, 1, 10, 20, 9, 243, 255, 243, 228, 212, 209, 237, 0, 250, 11, 1, 243, 0, 79, 5, 27, 0, 0, 1, 0, 1, 4, 3, 253, 248, 251, 8, 10, 0, 2, 10, 10, 8, 5, 2, 0, 0, 2, 255, 248, 254, 5, 5, 251, 242, 247, 255, 254, 2, 7, 1, 248, 246, 242, 244, 245, 249, 4, 9, 6, 1, 254, 6, 10, 9, 11, 10, 9, 11, 5, 1, 0, 247, 247, 249, 248, 254, 2, 7, 11, 8, 2, 0, 254, 1, 5, 5, 2, 5, 2, 252, 251, 255, 0, 2, 4, 3, 1, 247, 240, 251, 249, 243, 246, 249, 254, 0, 3, 10, 9, 2, 5, 7, 255, 253, 3, 14, 22, 13, 2, 252, 255, 252, 251, 255, 2, 5, 3, 246, 241, 249, 255, 1, 0, 251, 254, 0, 250, 251, 0, 2, 5, 3, 252, 0, 7, 13, 11, 0, 247, 252, 253, 249, 2, 12, 14, 8, 255, 2, 3, 0, 254, 252, 0, 9, 10, 2, 1, 2, 2, 4, 2, 0, 1, 254, 251, 252, 249, 249, 249, 246, 239, 244, 1, 14, 16, 4, 253, 248, 245, 252, 0, 0, 0, 248, 244, 254, 4, 3, 3, 6, 12, 11, 2, 1, 6, 16, 18, 7, 9, 15, 13, 10, 12, 0, 254, 2, 247, 239, 236, 240, 0, 2, 248, 245, 247, 251, 0, 246, 245, 3, 2, 1, 253, 243, 3, 15, 15, 12, 5, 252, 2, 8, 0, 245, 245, 3, 3, 254, 0, 6, 8, 11, 7, 7, 6, 251, 254, 4, 0, 248, 253, 4, 1, 254, 1, 4, 8, 254, 244, 249, 253, 248, 248, 245, 254, 2, 4, 8, 0, 255, 10, 17, 9, 4, 7, 6, 0, 241, 234, 244, 1, 12, 14, 4, 6, 12, 12, 5, 250, 249, 2, 7, 5, 255, 251, 252, 1, 251, 246, 3, 1, 8, 14, 246, 240, 237, 235, 240, 241, 246, 4, 14, 15, 18, 16, 6, 0, 247, 250, 16, 10, 250, 255, 251, 251, 5, 8, 5, 251, 251, 8, 10, 5, 0, 254, 2, 255, 252, 2, 8, 8, 10, 6, 253, 251, 5, 13, 6, 253, 251, 250, 0, 4, 247, 239, 254, 249, 229, 235, 253, 6, 9, 3, 254, 4, 12, 5, 249, 250, 5, 14, 12, 0, 238, 249, 16, 17, 0, 247, 2, 18, 8, 252, 242, 245, 6, 10, 248, 250, 12, 18, 23, 17, 0, 1, 0, 251, 14, 8, 255, 1, 241, 230, 228, 221, 235, 252, 246, 249, 1, 0, 0, 254, 251, 254, 1, 19, 29, 14, 8, 16, 16, 18, 10, 2, 22, 25, 2, 246, 244, 250, 255, 250, 239, 231, 238, 5, 19, 255, 248, 8, 1, 2, 5, 250, 254, 0, 244, 235, 242, 244, 252, 10, 252, 247, 9, 5, 255, 1, 253, 5, 7, 15, 23, 7, 4, 15, 15, 9, 15, 26, 21, 5, 251, 255, 0, 239, 224, 239, 251, 5, 6, 248, 241, 232, 233, 248, 2, 244, 241, 251, 252, 6, 9, 5, 22, 15, 255, 2, 253, 8, 15, 3, 9, 1, 255, 3, 3, 12, 8, 12, 15, 0, 241, 242, 251, 8, 3, 255, 4, 3, 252, 252, 1, 5, 4, 245, 247, 1, 239, 237, 247, 249, 10, 19, 8, 6, 2, 11, 14, 246, 236, 231, 239, 249, 250, 10, 16, 2, 252, 249, 250, 254, 9, 23, 14, 17, 27, 23, 13, 249, 249, 3, 253, 4, 9, 0, 250, 229, 232, 0, 2, 254, 11, 14, 6, 0, 248, 249, 255, 252, 244, 233, 232, 3, 2, 253, 10, 252, 245, 12, 10, 11, 31, 9, 252, 7, 247, 252, 10, 4, 8, 6, 8, 13, 240, 219, 229, 240, 252, 14, 4, 247, 9, 13, 9, 16, 1, 4, 16, 254, 2, 253, 255, 19, 4, 2, 4, 242, 6, 18, 10, 1, 242, 234, 229, 229, 242, 253, 1, 255, 0, 5, 7, 5, 4, 7, 18, 21, 17, 12, 253, 1, 4, 255, 254, 243, 254, 15, 249, 249, 0, 240, 245, 244, 232, 255, 1, 5, 25, 253, 235, 246, 245, 1, 6, 252, 12, 14, 18, 36, 24, 251, 236, 248, 6, 19, 11, 251, 254, 0, 250, 255, 11, 0, 236, 241, 1, 248, 243, 4, 0, 242, 250, 13, 26, 20, 12, 18, 21, 8, 248, 234, 232, 241, 250, 5, 9, 244, 248, 20, 28, 20, 1, 248, 1, 255, 246, 225, 241, 1, 249, 250, 236, 231, 11, 27, 14, 14, 14, 17, 17, 242, 230, 252, 9, 6, 250, 232, 250, 14, 7, 13, 5, 242, 232, 230, 237, 7, 21, 17, 4, 236, 234, 255, 255, 11, 44, 28, 5, 19, 18, 14, 14, 21, 27, 15, 253, 255, 250, 240, 247, 228, 226, 2, 231, 213, 0, 15, 9, 248, 236, 253, 234, 228, 20, 41, 28, 21, 3, 7, 22, 2, 8, 22, 2, 251, 229, 207, 227, 248, 252, 23, 17, 249, 8, 9, 11, 253, 231, 247, 237, 228, 6, 2, 1, 22, 15, 8, 250, 239, 251, 6, 1, 4, 3, 253, 247, 247, 245, 10, 14, 13, 42, 27, 254, 5, 236, 245, 30, 18, 9, 240, 236, 18, 13, 4, 13, 255, 253, 9, 3, 251, 251, 253, 10, 22, 3, 224, 244, 251, 241, 245, 234, 235, 0, 244, 5, 12, 5, 35, 18, 242, 255, 248, 251, 253, 222, 221, 227, 244, 20, 18, 6, 22, 36, 29, 12, 6, 19, 0, 239, 212, 225, 14, 18, 11, 4, 243, 226, 249, 22, 238, 201, 238, 8, 23, 249, 226, 12, 24, 58, 71, 11, 6, 27, 14, 8, 243, 235, 19, 28, 242, 213, 230, 244, 254, 242, 226, 239, 250, 1, 7, 249, 4, 62, 65, 25, 249, 255, 39, 56, 13, 225, 225, 220, 247, 10, 235, 241, 2, 14, 24, 239, 215, 232, 234, 243, 1, 247, 244, 253, 3, 1, 240, 1, 15, 17, 252, 243, 3, 245, 222, 238, 236, 214, 238, 246, 248, 25, 33, 27, 27, 0, 233, 26, 44, 22, 249, 222, 254, 22, 252, 2, 9, 5, 10, 37, 45, 20, 5, 13, 17, 15, 0, 18, 30, 237, 242, 32, 44, 45, 18, 244, 41, 52, 28, 37, 251, 223, 224, 203, 229, 224, 195, 251, 16, 242, 228, 208, 186, 166, 144, 159, 190, 211, 193, 185, 190, 200, 230, 249, 16, 19, 3, 49, 107, 108, 124, 122, 106, 99, 81, 73, 67, 64, 55, 29, 12, 230, 218, 239, 231, 240, 240, 237, 14, 4, 231, 246, 233, 233, 254, 245, 239, 235, 227, 235, 233, 237, 4, 243, 237, 221, 190, 219, 242, 240, 235, 252, 23, 20, 251, 3, 27, 21, 7, 255, 222, 224, 250, 2, 2, 247, 250, 6, 25, 35, 29, 36, 7, 235, 228, 246, 6, 8, 13, 13, 24, 27, 48, 34, 254, 10, 22, 34, 41, 19, 10, 21, 8, 249, 248, 252, 248, 251, 249, 250, 9, 255, 224, 223, 227, 238, 14, 18, 241, 229, 235, 244, 238, 213, 231, 255, 245, 237, 241, 237, 232, 241, 234, 220, 231, 254, 21, 12, 249, 1, 13, 22, 12, 5, 22, 26, 21, 12, 6, 24, 20, 0, 4, 10, 29, 54, 34, 12, 14, 17, 21, 20, 242, 248, 2, 23, 28, 250, 235, 252, 23, 25, 3, 252, 14, 9, 234, 229, 242, 234, 217, 210, 221, 232, 253, 19, 25, 32, 4, 236, 0, 245, 220, 233, 25, 47, 13, 216, 234, 250, 227, 224, 221, 241, 230, 216, 252, 0, 236, 229, 239, 6, 0, 12, 27, 24, 11, 248, 253, 19, 19, 6, 16, 35, 48, 50, 42, 31, 8, 222, 235, 22, 26, 6, 15, 22, 15, 25, 61, 74, 51, 33, 37, 33, 30, 7, 220, 207, 214, 214, 206, 198, 213, 213, 214, 243, 237, 205, 193, 205, 233, 0, 253, 249, 236, 252, 23, 15, 17, 26, 10, 5, 9, 0, 235, 224, 255, 12, 243, 254, 26, 21, 11, 7, 24, 34, 18, 255, 245, 242, 8, 34, 33, 22, 2, 253, 13, 18, 0, 251, 251, 238, 227, 237, 250, 246, 229, 239, 252, 9, 13, 244, 242, 15, 18, 14, 15, 17, 36, 35, 31, 49, 38, 18, 25, 35, 5, 0, 120, 6, 13, 0, 0, 11, 15, 13, 14, 10, 20, 33, 25, 12, 252, 242, 235, 230, 232, 224, 228, 237, 248, 2, 246, 242, 0, 19, 30, 23, 18, 21, 13, 8, 1, 7, 8, 2, 3, 246, 235, 229, 230, 252, 0, 241, 251, 0, 254, 252, 7, 10, 11, 19, 20, 14, 5, 246, 3, 16, 8, 255, 240, 253, 6, 243, 230, 224, 246, 8, 19, 16, 246, 250, 20, 40, 33, 1, 3, 18, 8, 2, 239, 241, 255, 255, 250, 232, 228, 242, 253, 6, 0, 4, 9, 247, 248, 252, 8, 15, 1, 252, 243, 254, 7, 254, 253, 253, 4, 22, 14, 251, 248, 3, 12, 1, 1, 1, 255, 250, 240, 246, 1, 1, 254, 252, 7, 12, 13, 12, 9, 14, 14, 10, 4, 244, 254, 6, 245, 234, 220, 232, 0, 17, 10, 248, 250, 8, 22, 20, 11, 26, 39, 19, 251, 223, 229, 254, 10, 4, 225, 220, 226, 232, 239, 246, 246, 6, 17, 13, 10, 22, 34, 25, 16, 2, 19, 28, 13, 248, 234, 231, 245, 8, 254, 204, 193, 245, 39, 36, 2, 0, 10, 6, 7, 15, 14, 5, 252, 252, 239, 229, 241, 9, 4, 242, 247, 0, 9, 2, 7, 14, 14, 15, 15, 12, 20, 19, 21, 26, 8, 235, 230, 244, 239, 245, 247, 229, 222, 222, 247, 4, 255, 253, 1, 13, 6, 243, 1, 29, 40, 26, 4, 10, 22, 2, 251, 0, 7, 0, 248, 228, 221, 238, 255, 12, 19, 0, 0, 8, 8, 11, 5, 11, 0, 242, 255, 251, 245, 243, 254, 253, 236, 241, 6, 10, 6, 255, 0, 14, 19, 11, 1, 14, 13, 4, 253, 254, 250, 246, 1, 255, 230, 230, 249, 252, 250, 255, 3, 9, 5, 20, 20, 246, 245, 5, 19, 37, 33, 9, 0, 254, 240, 225, 245, 20, 20, 1, 246, 239, 228, 237, 11, 21, 10, 1, 240, 233, 244, 17, 25, 13, 16, 22, 8, 247, 249, 11, 1, 255, 241, 214, 211, 224, 255, 11, 15, 7, 247, 255, 3, 0, 22, 28, 24, 26, 15, 8, 245, 228, 249, 6, 249, 224, 228, 231, 238, 252, 2, 6, 16, 5, 10, 23, 33, 45, 31, 8, 6, 13, 9, 248, 235, 225, 238, 6, 252, 227, 210, 208, 245, 20, 36, 42, 31, 30, 27, 28, 25, 28, 34, 7, 235, 207, 199, 230, 230, 220, 217, 210, 206, 212, 246, 17, 45, 43, 19, 21, 16, 17, 47, 57, 50, 30, 5, 239, 232, 233, 223, 241, 247, 233, 222, 222, 225, 236, 254, 10, 17, 19, 31, 29, 30, 27, 30, 39, 29, 13, 0, 253, 239, 218, 211, 224, 226, 223, 233, 241, 236, 254, 15, 36, 58, 29, 2, 13, 21, 20, 20, 254, 247, 249, 230, 234, 245, 241, 255, 254, 228, 249, 16, 9, 0, 255, 3, 7, 253, 8, 16, 253, 0, 10, 9, 19, 12, 233, 230, 10, 39, 22, 231, 209, 217, 235, 10, 29, 12, 0, 0, 3, 18, 19, 19, 18, 0, 255, 247, 248, 7, 252, 230, 227, 240, 255, 4, 8, 6, 251, 12, 24, 2, 239, 253, 15, 11, 249, 242, 248, 253, 13, 14, 227, 204, 249, 16, 4, 6, 10, 16, 7, 16, 40, 41, 25, 16, 14, 0, 254, 10, 0, 233, 240, 229, 225, 236, 238, 254, 252, 237, 233, 238, 249, 16, 24, 245, 244, 4, 6, 18, 17, 14, 33, 44, 27, 254, 239, 245, 2, 242, 232, 249, 240, 220, 230, 248, 16, 30, 14, 239, 232, 8, 32, 8, 13, 47, 40, 7, 242, 230, 220, 237, 8, 12, 240, 218, 242, 255, 0, 29, 45, 42, 51, 53, 27, 237, 211, 226, 6, 7, 228, 208, 204, 221, 229, 235, 7, 27, 18, 255, 241, 244, 247, 252, 18, 23, 7, 4, 9, 5, 247, 28, 60, 31, 13, 20, 16, 255, 224, 226, 250, 10, 14, 242, 211, 214, 240, 0, 250, 247, 2, 29, 49, 30, 5, 0, 21, 29, 7, 249, 239, 225, 215, 211, 223, 0, 11, 5, 253, 0, 29, 47, 32, 21, 22, 13, 0, 254, 9, 13, 3, 237, 210, 222, 252, 240, 224, 218, 218, 226, 218, 216, 244, 0, 21, 57, 63, 66, 65, 48, 52, 69, 45, 29, 22, 239, 202, 204, 207, 205, 192, 201, 227, 222, 217, 238, 248, 24, 33, 0, 245, 22, 83, 79, 32, 247, 242, 17, 50, 47, 30, 232, 200, 225, 247, 252, 239, 214, 229, 244, 244, 245, 248, 244, 242, 4, 24, 30, 8, 0, 25, 26, 23, 40, 40, 11, 4, 5, 249, 238, 245, 3, 254, 215, 222, 236, 212, 188, 215, 244, 12, 13, 5, 251, 244, 12, 41, 49, 61, 53, 40, 17, 250, 20, 48, 26, 26, 0, 202, 199, 199, 194, 226, 248, 239, 234, 220, 197, 228, 21, 50, 66, 58, 39, 44, 42, 20, 7, 17, 14, 245, 215, 210, 250, 247, 218, 230, 238, 227, 241, 252, 17, 39, 25, 11, 0, 248, 11, 16, 237, 238, 8, 247, 243, 3, 244, 5, 18, 243, 11, 44, 3, 241, 250, 4, 54, 59, 3, 211, 212, 3, 60, 63, 2, 202, 191, 226, 20, 22, 1, 228, 207, 213, 234, 3, 2, 253, 0, 251, 246, 9, 16, 33, 38, 16, 44, 71, 23, 7, 30, 36, 57, 18, 194, 176, 175, 202, 250, 208, 165, 221, 2, 32, 40, 7, 240, 234, 20, 66, 51, 17, 2, 0, 9, 22, 39, 55, 45, 7, 240, 230, 234, 0, 245, 175, 185, 7, 248, 215, 227, 247, 10, 35, 42, 38, 251, 226, 32, 30, 246, 5, 32, 255, 228, 253, 27, 24, 21, 30, 11, 238, 237, 242, 231, 229, 5, 18, 239, 235, 233, 221, 228, 9, 48, 51, 15, 250, 2, 251, 251, 24, 252, 219, 230, 252, 246, 0, 246, 241, 20, 44, 38, 38, 34, 23, 26, 0, 245, 7, 203, 170, 218, 220, 195, 214, 240, 28, 14, 226, 15, 69, 63, 78, 84, 37, 255, 12, 36, 22, 240, 208, 242, 236, 198, 211, 0, 241, 218, 228, 214, 215, 7, 54, 61, 27, 0, 15, 26, 254, 9, 54, 46, 7, 246, 202, 163, 191, 249, 17, 242, 187, 219, 8, 3, 0, 16, 9, 22, 68, 75, 34, 23, 59, 76, 46, 0, 251, 15, 240, 208, 215, 206, 216, 198, 187, 221, 233, 245, 27, 15, 249, 24, 19, 31, 33, 12, 41, 50, 11, 251, 244, 252, 247, 198, 206, 218, 206, 241, 254, 225, 234, 4, 77, 97, 29, 24, 59, 49, 48, 51, 3, 224, 215, 216, 193, 156, 208, 27, 5, 226, 244, 248, 227, 243, 32, 39, 7, 25, 44, 249, 200, 15, 91, 61, 9, 2, 3, 255, 0, 23, 27, 239, 224, 225, 195, 210, 10, 20, 239, 196, 218, 17, 18, 25, 59, 38, 250, 255, 21, 18, 5, 1, 11, 236, 195, 212, 242, 209, 195, 5, 44, 10, 8, 12, 5, 22, 37, 55, 44, 249, 8, 77, 56, 5, 251, 249, 0, 248, 217, 211, 195, 195, 230, 214, 157, 186, 253, 15, 3, 250, 26, 77, 72, 57, 61, 42, 32, 42, 22, 249, 255, 249, 230, 213, 208, 226, 5, 6, 236, 244, 1, 6, 16, 12, 249, 6, 22, 10, 2, 14, 3, 236, 206, 226, 36, 32, 250, 0, 231, 193, 229, 43, 57, 9, 218, 209, 215, 217, 10, 45, 3, 254, 51, 34, 238, 237, 17, 38, 26, 32, 40, 12, 235, 8, 29, 15, 9, 25, 254, 199, 184, 237, 0, 239, 17, 1, 192, 183, 235, 42, 58, 15, 13, 6, 226, 240, 18, 8, 4, 22, 36, 32, 3, 239, 247, 0, 16, 37, 7, 220, 199, 197, 217, 242, 249, 0, 10, 233, 186, 222, 23, 43, 55, 35, 251, 4, 6, 35, 86, 73, 51, 56, 23, 3, 32, 15, 237, 226, 232, 250, 232, 196, 175, 156, 183, 250, 14, 254, 227, 197, 223, 3, 15, 68, 76, 35, 39, 42, 42, 50, 41, 45, 66, 26, 231, 230, 222, 205, 209, 218, 224, 217, 213, 211, 197, 188, 252, 60, 53, 253, 235, 253, 254, 13, 27, 14, 2, 4, 18, 248, 189, 222, 56, 60, 28, 14, 243, 243, 245, 2, 39, 39, 15, 25, 29, 229, 226, 18, 57, 67, 59, 45, 39, 15, 233, 226, 238, 200, 208, 229, 169, 137, 170, 186, 213, 5, 21, 57, 72, 39, 60, 82, 59, 62, 62, 0, 226, 239, 232, 221, 207, 209, 212, 208, 214, 238, 244, 224, 226, 0, 18, 20, 19, 16, 252, 14, 66, 91, 61, 15, 19, 32, 22, 8, 2, 231, 215, 210, 214, 213, 195, 190, 219, 238, 229, 246, 18, 27, 42, 64, 80, 78, 65, 44, 47, 54, 16, 242, 221, 182, 177, 202, 214, 212, 212, 215, 4, 29, 12, 22, 39, 35, 13, 237, 234, 244, 249, 246, 231, 215, 230, 21, 52, 39, 0, 23, 77, 70, 37, 33, 28, 15, 254, 230, 229, 225, 228, 255, 4, 247, 0, 11, 20, 18, 12, 23, 12, 222, 197, 202, 209, 206, 207, 202, 200, 201, 208, 234, 252, 2, 20, 47, 41, 18, 255, 250, 1, 30, 32, 17, 253, 229, 230, 253, 24, 39, 28, 17, 4, 14, 33, 47, 54, 48, 33, 19, 29, 22, 38, 39, 29, 23, 16, 8, 253, 246, 247, 2, 253, 14, 19, 8, 248, 215, 224, 3, 2, 244, 238, 194, 156, 170, 175, 210, 218, 190, 198, 209, 191, 208, 239, 250, 10, 28, 29, 18, 5, 15, 37, 50, 42, 35, 31, 2, 238, 231, 245, 252, 2, 2, 252, 233, 243, 24, 57, 73, 69, 67, 58, 41, 42, 43, 45, 22, 5, 6, 253, 236, 237, 253, 4, 16, 27, 25, 26, 21, 21, 38, 28, 8, 9, 253, 229, 224, 215, 214, 216, 215, 221, 225, 239, 142, 6, 24, 0, 1, 1, 3, 3, 253, 252, 0, 3, 8, 255, 231, 232, 255, 7, 15, 16, 9, 7, 0, 243, 249, 3, 9, 8, 0, 1, 6, 4, 7, 6, 253, 240, 244, 250, 0, 11, 8, 4, 11, 9, 4, 254, 244, 241, 253, 3, 6, 9, 1, 253, 254, 249, 248, 251, 249, 251, 2, 1, 0, 1, 0, 7, 12, 2, 251, 249, 249, 255, 7, 0, 245, 252, 0, 5, 11, 0, 248, 253, 255, 3, 4, 255, 0, 8, 11, 13, 16, 10, 5, 3, 253, 254, 2, 255, 0, 3, 251, 249, 252, 245, 249, 4, 1, 249, 251, 247, 0, 14, 8, 2, 5, 1, 0, 2, 250, 251, 2, 5, 10, 13, 7, 254, 254, 255, 243, 241, 247, 6, 20, 8, 253, 255, 250, 251, 252, 248, 253, 5, 7, 5, 0, 251, 249, 252, 2, 252, 251, 254, 251, 248, 251, 6, 18, 17, 5, 0, 253, 0, 9, 11, 4, 255, 252, 5, 13, 5, 248, 251, 1, 3, 3, 251, 247, 4, 9, 2, 0, 1, 3, 2, 251, 255, 16, 4, 249, 1, 6, 0, 247, 243, 250, 2, 6, 0, 240, 242, 246, 255, 4, 2, 3, 2, 255, 3, 252, 250, 5, 9, 13, 16, 7, 4, 6, 10, 7, 247, 237, 244, 255, 0, 0, 0, 6, 2, 254, 253, 1, 8, 2, 241, 240, 0, 2, 253, 251, 0, 18, 21, 9, 2, 250, 253, 2, 253, 0, 6, 5, 3, 255, 0, 252, 237, 239, 253, 1, 6, 2, 5, 6, 3, 8, 247, 236, 254, 19, 28, 25, 14, 12, 16, 11, 7, 254, 240, 240, 249, 0, 248, 236, 242, 253, 243, 237, 247, 0, 5, 16, 11, 253, 248, 246, 243, 3, 22, 11, 8, 20, 6, 245, 236, 242, 11, 13, 247, 244, 252, 253, 8, 4, 251, 2, 248, 241, 7, 27, 24, 21, 21, 1, 244, 253, 1, 4, 6, 246, 246, 5, 2, 250, 244, 243, 3, 9, 255, 250, 2, 9, 8, 1, 252, 248, 7, 22, 14, 7, 15, 11, 1, 250, 246, 254, 247, 231, 236, 245, 235, 238, 254, 7, 10, 254, 239, 246, 253, 2, 16, 12, 3, 6, 25, 19, 3, 5, 0, 248, 248, 230, 228, 5, 21, 25, 16, 247, 246, 0, 247, 249, 7, 15, 19, 13, 0, 253, 24, 36, 7, 246, 245, 238, 252, 15, 7, 254, 248, 241, 244, 245, 241, 250, 3, 5, 2, 255, 247, 242, 5, 21, 16, 2, 0, 6, 10, 1, 245, 243, 248, 253, 5, 2, 244, 245, 5, 12, 0, 229, 221, 248, 9, 9, 7, 253, 245, 11, 23, 13, 2, 252, 19, 37, 22, 8, 6, 4, 3, 3, 2, 242, 231, 243, 252, 6, 17, 1, 240, 237, 228, 244, 14, 15, 5, 254, 251, 3, 14, 22, 19, 3, 239, 236, 245, 254, 4, 10, 250, 239, 245, 251, 3, 17, 21, 0, 236, 235, 0, 32, 34, 11, 8, 6, 235, 226, 234, 246, 11, 17, 6, 242, 239, 250, 237, 237, 10, 11, 14, 10, 253, 9, 24, 25, 22, 253, 231, 4, 52, 65, 19, 222, 221, 220, 221, 250, 249, 249, 15, 28, 25, 231, 192, 218, 253, 26, 27, 255, 2, 10, 4, 34, 16, 235, 250, 254, 244, 4, 19, 16, 4, 3, 16, 253, 221, 220, 238, 13, 24, 12, 9, 0, 247, 7, 0, 236, 249, 254, 7, 30, 27, 3, 228, 204, 209, 1, 32, 14, 24, 44, 15, 251, 13, 244, 228, 6, 12, 7, 17, 249, 224, 237, 253, 11, 16, 4, 248, 248, 4, 252, 5, 29, 3, 221, 213, 223, 7, 61, 68, 32, 239, 209, 243, 17, 21, 20, 241, 212, 232, 7, 2, 237, 240, 0, 1, 13, 19, 1, 255, 255, 5, 19, 10, 0, 251, 238, 244, 0, 247, 242, 4, 25, 25, 10, 0, 251, 241, 243, 240, 242, 19, 27, 11, 19, 5, 252, 15, 16, 6, 2, 249, 0, 4, 248, 1, 2, 238, 240, 248, 241, 231, 249, 22, 5, 255, 20, 5, 245, 0, 252, 0, 251, 241, 4, 15, 23, 38, 18, 231, 225, 242, 248, 248, 238, 236, 6, 23, 18, 5, 255, 250, 242, 228, 241, 31, 59, 36, 254, 231, 241, 3, 9, 16, 18, 248, 235, 239, 244, 8, 31, 16, 248, 247, 2, 232, 212, 243, 20, 47, 49, 7, 234, 230, 246, 6, 5, 12, 27, 35, 17, 228, 199, 227, 5, 22, 25, 1, 221, 217, 241, 16, 48, 31, 221, 196, 211, 236, 19, 40, 36, 38, 48, 34, 18, 247, 224, 240, 244, 245, 239, 232, 3, 22, 8, 239, 227, 245, 2, 247, 235, 252, 16, 20, 21, 33, 21, 248, 1, 253, 226, 239, 252, 5, 45, 53, 28, 12, 2, 251, 250, 236, 234, 0, 15, 246, 232, 227, 205, 211, 0, 21, 13, 0, 239, 231, 1, 25, 28, 20, 14, 26, 43, 27, 5, 252, 236, 11, 46, 22, 226, 199, 195, 226, 20, 24, 4, 8, 0, 255, 23, 33, 8, 234, 240, 2, 2, 7, 13, 237, 237, 26, 252, 191, 195, 227, 254, 22, 21, 250, 236, 3, 53, 92, 61, 240, 200, 223, 28, 63, 44, 253, 239, 251, 4, 238, 211, 207, 207, 242, 12, 249, 237, 249, 7, 31, 51, 30, 236, 228, 0, 41, 68, 46, 0, 253, 25, 33, 3, 219, 190, 201, 251, 26, 19, 235, 180, 175, 217, 1, 46, 75, 47, 21, 0, 216, 228, 15, 44, 58, 30, 251, 252, 250, 246, 228, 219, 231, 246, 16, 31, 7, 245, 4, 11, 242, 232, 248, 251, 250, 254, 24, 32, 24, 5, 246, 248, 255, 251, 251, 244, 236, 254, 8, 0, 10, 27, 24, 10, 248, 222, 225, 3, 28, 31, 19, 6, 2, 0, 248, 228, 215, 241, 6, 249, 247, 16, 16, 237, 227, 3, 35, 21, 0, 3, 4, 23, 51, 27, 251, 238, 1, 16, 19, 245, 195, 202, 0, 18, 255, 243, 0, 251, 229, 230, 232, 231, 21, 60, 36, 21, 32, 28, 11, 5, 245, 232, 238, 251, 31, 49, 12, 229, 227, 220, 221, 240, 244, 255, 15, 0, 241, 233, 229, 239, 7, 28, 16, 14, 38, 37, 20, 1, 248, 3, 20, 23, 14, 253, 250, 240, 219, 254, 7, 232, 6, 49, 9, 235, 243, 235, 248, 14, 0, 240, 239, 234, 241, 28, 61, 26, 240, 204, 184, 222, 25, 60, 61, 22, 243, 233, 251, 1, 240, 228, 249, 7, 27, 49, 18, 211, 203, 250, 29, 35, 20, 7, 0, 250, 248, 248, 240, 5, 19, 11, 9, 19, 1, 251, 16, 12, 243, 244, 233, 225, 5, 45, 24, 237, 222, 228, 237, 18, 21, 228, 221, 36, 52, 4, 231, 214, 196, 243, 45, 64, 75, 47, 218, 175, 210, 248, 254, 4, 38, 33, 0, 6, 7, 209, 204, 245, 235, 234, 26, 45, 39, 19, 1, 11, 20, 24, 6, 229, 223, 28, 57, 40, 36, 20, 222, 218, 252, 246, 214, 215, 217, 219, 14, 35, 237, 242, 35, 26, 252, 233, 215, 213, 8, 76, 90, 35, 250, 0, 17, 29, 11, 214, 190, 214, 239, 3, 29, 12, 202, 192, 2, 8, 207, 232, 25, 33, 61, 87, 31, 216, 213, 252, 251, 236, 246, 237, 234, 255, 7, 26, 58, 36, 1, 255, 9, 23, 9, 1, 32, 32, 21, 74, 37, 190, 166, 210, 217, 215, 230, 242, 8, 49, 45, 239, 198, 203, 227, 245, 38, 68, 48, 21, 11, 10, 33, 33, 2, 233, 220, 207, 204, 250, 15, 5, 33, 61, 7, 199, 189, 206, 218, 5, 32, 16, 3, 16, 19, 14, 5, 12, 249, 243, 10, 14, 8, 42, 39, 29, 41, 18, 218, 194, 209, 238, 243, 238, 245, 248, 7, 16, 12, 233, 222, 247, 26, 45, 57, 27, 222, 198, 236, 45, 95, 72, 17, 215, 205, 228, 254, 15, 13, 11, 2, 230, 230, 244, 250, 246, 231, 227, 243, 242, 240, 16, 20, 3, 251, 11, 18, 22, 36, 37, 11, 244, 241, 4, 254, 3, 253, 251, 254, 241, 220, 207, 214, 248, 6, 21, 19, 251, 247, 3, 31, 62, 67, 33, 247, 219, 235, 247, 2, 18, 17, 1, 255, 222, 217, 253, 0, 222, 249, 21, 25, 24, 37, 15, 9, 28, 14, 226, 222, 254, 0, 249, 9, 14, 240, 233, 238, 216, 219, 253, 245, 243, 13, 30, 13, 8, 27, 14, 10, 25, 10, 246, 12, 33, 17, 7, 25, 4, 236, 242, 229, 195, 217, 9, 20, 18, 25, 247, 214, 235, 3, 237, 228, 250, 9, 8, 23, 32, 44, 49, 36, 255, 213, 219, 255, 253, 246, 12, 14, 242, 245, 8, 0, 248, 242, 230, 224, 240, 2, 18, 13, 254, 12, 30, 27, 21, 9, 252, 0, 254, 251, 7, 16, 18, 23, 38, 7, 219, 203, 199, 230, 22, 29, 26, 41, 33, 13, 1, 247, 220, 204, 225, 5, 17, 20, 17, 254, 240, 253, 26, 4, 222, 212, 213, 223, 255, 13, 9, 15, 23, 6, 249, 26, 36, 2, 223, 225, 236, 253, 17, 20, 254, 254, 30, 46, 253, 231, 251, 255, 254, 0, 252, 232, 231, 14, 47, 41, 21, 17, 247, 212, 252, 57, 53, 35, 29, 238, 198, 218, 31, 76, 51, 229, 154, 134, 202, 24, 70, 42, 10, 220, 184, 195, 235, 221, 219, 11, 68, 47, 23, 27, 18, 16, 22, 30, 25, 27, 9, 244, 241, 12, 21, 255, 213, 210, 213, 230, 2, 22, 13, 0, 247, 244, 249, 9, 1, 250, 3, 1, 245, 9, 25, 19, 5, 1, 5, 254, 251, 251, 235, 238, 1, 6, 253, 248, 5, 8, 253, 245, 251, 254, 11, 18, 12, 0, 251, 254, 244, 235, 252, 4, 254, 4, 16, 3, 235, 231, 254, 25, 40, 44, 27, 22, 28, 20, 14, 24, 33, 27, 3, 11, 25, 14, 6, 13, 10, 234, 219, 238, 246, 235, 243, 232, 209, 221, 11, 30, 0, 0, 147, 5, 17, 0, 252, 244, 246, 1, 12, 13, 9, 4, 253, 5, 9, 6, 251, 245, 249, 251, 10, 13, 16, 6, 239, 231, 245, 254, 7, 9, 8, 248, 231, 233, 243, 1, 4, 254, 246, 242, 0, 8, 6, 0, 247, 239, 244, 10, 28, 37, 26, 7, 249, 252, 0, 0, 5, 16, 25, 25, 15, 255, 240, 227, 229, 247, 12, 23, 16, 0, 243, 246, 247, 240, 241, 255, 11, 10, 0, 251, 253, 254, 250, 250, 240, 245, 2, 11, 12, 6, 5, 0, 0, 253, 250, 247, 0, 14, 20, 19, 18, 5, 240, 244, 0, 11, 20, 19, 10, 255, 247, 247, 253, 249, 248, 3, 5, 8, 1, 238, 229, 246, 5, 254, 251, 255, 6, 17, 12, 252, 242, 247, 255, 0, 13, 16, 11, 0, 244, 244, 248, 242, 245, 2, 8, 3, 7, 255, 240, 241, 253, 10, 14, 6, 253, 3, 18, 30, 33, 20, 9, 254, 249, 8, 10, 8, 3, 5, 5, 253, 249, 240, 235, 244, 4, 6, 253, 242, 237, 239, 248, 251, 0, 255, 248, 249, 243, 240, 242, 253, 12, 16, 5, 249, 239, 241, 1, 9, 15, 28, 25, 10, 252, 236, 244, 13, 24, 23, 23, 18, 10, 13, 8, 9, 8, 2, 254, 254, 3, 8, 14, 9, 252, 231, 223, 233, 241, 3, 12, 4, 239, 227, 232, 250, 0, 248, 255, 2, 248, 248, 250, 252, 4, 0, 0, 0, 251, 254, 20, 20, 1, 254, 0, 7, 14, 15, 15, 14, 14, 15, 14, 13, 14, 18, 14, 10, 2, 239, 225, 231, 255, 12, 13, 5, 245, 225, 221, 237, 2, 5, 0, 253, 250, 238, 228, 236, 4, 14, 8, 4, 1, 243, 234, 248, 16, 33, 35, 9, 240, 249, 5, 4, 0, 17, 38, 36, 22, 251, 242, 0, 20, 20, 249, 247, 2, 7, 2, 250, 234, 238, 247, 242, 239, 0, 12, 7, 247, 229, 225, 253, 11, 17, 15, 7, 247, 220, 233, 247, 253, 21, 41, 12, 236, 233, 241, 4, 22, 27, 15, 248, 250, 1, 0, 18, 15, 8, 7, 2, 8, 12, 5, 255, 3, 8, 6, 4, 247, 247, 254, 4, 0, 254, 244, 245, 252, 251, 246, 241, 244, 251, 9, 6, 254, 241, 239, 248, 4, 8, 2, 8, 13, 4, 246, 244, 6, 16, 22, 13, 254, 247, 236, 252, 24, 27, 4, 243, 247, 255, 9, 16, 18, 11, 10, 253, 254, 0, 253, 240, 246, 7, 22, 11, 252, 237, 225, 229, 235, 247, 254, 253, 6, 6, 255, 245, 244, 251, 255, 2, 13, 22, 14, 11, 14, 1, 244, 251, 12, 33, 40, 21, 244, 234, 250, 15, 22, 5, 233, 232, 7, 15, 248, 237, 0, 16, 14, 0, 232, 214, 222, 252, 20, 34, 25, 242, 237, 243, 250, 2, 2, 8, 240, 222, 229, 5, 28, 43, 18, 225, 228, 240, 254, 25, 57, 48, 4, 244, 241, 0, 16, 7, 3, 0, 6, 254, 14, 31, 25, 2, 232, 219, 213, 234, 15, 33, 25, 1, 249, 245, 241, 216, 196, 225, 24, 55, 19, 233, 228, 232, 244, 9, 10, 4, 25, 27, 15, 19, 250, 219, 233, 8, 19, 41, 50, 23, 247, 233, 226, 239, 16, 38, 20, 255, 242, 253, 252, 235, 244, 15, 34, 27, 242, 217, 233, 10, 14, 245, 214, 204, 231, 8, 29, 21, 255, 237, 226, 239, 15, 22, 6, 253, 20, 36, 37, 252, 214, 226, 20, 63, 65, 34, 1, 218, 221, 234, 251, 6, 252, 4, 16, 21, 17, 253, 234, 230, 243, 226, 242, 27, 64, 67, 17, 214, 174, 178, 244, 44, 48, 24, 0, 234, 217, 207, 207, 0, 33, 14, 3, 4, 4, 251, 230, 229, 1, 21, 12, 30, 53, 66, 42, 244, 212, 210, 245, 23, 52, 65, 48, 1, 231, 218, 215, 238, 16, 15, 16, 2, 242, 230, 210, 221, 246, 29, 37, 12, 231, 224, 6, 16, 253, 234, 224, 238, 19, 34, 6, 222, 214, 221, 243, 15, 24, 31, 37, 28, 0, 219, 210, 244, 45, 57, 52, 19, 246, 254, 20, 17, 252, 229, 234, 16, 47, 53, 28, 221, 192, 213, 240, 13, 38, 28, 11, 245, 230, 235, 227, 224, 228, 237, 8, 32, 31, 0, 249, 2, 255, 243, 210, 219, 10, 35, 53, 21, 238, 236, 255, 1, 242, 243, 6, 22, 22, 9, 1, 226, 3, 1, 248, 33, 23, 255, 243, 14, 19, 24, 42, 16, 238, 197, 217, 2, 23, 55, 38, 0, 224, 223, 235, 240, 15, 29, 13, 236, 227, 213, 218, 31, 32, 9, 244, 200, 203, 15, 49, 46, 29, 242, 219, 210, 232, 12, 25, 34, 34, 4, 243, 2, 0, 1, 3, 242, 1, 13, 27, 41, 33, 14, 246, 230, 232, 252, 239, 16, 46, 30, 5, 223, 233, 237, 247, 1, 232, 215, 255, 36, 6, 242, 245, 227, 233, 224, 243, 8, 17, 63, 44, 0, 219, 223, 231, 0, 53, 20, 36, 55, 25, 227, 181, 191, 236, 52, 81, 65, 8, 217, 221, 200, 203, 25, 69, 67, 33, 222, 208, 237, 17, 47, 10, 201, 205, 1, 33, 51, 250, 219, 242, 234, 234, 234, 209, 8, 67, 73, 36, 231, 180, 190, 231, 253, 48, 71, 67, 39, 204, 180, 206, 0, 38, 63, 19, 229, 212, 242, 61, 66, 12, 210, 177, 224, 37, 48, 43, 16, 0, 4, 245, 242, 216, 210, 16, 43, 20, 21, 9, 225, 217, 241, 255, 251, 247, 26, 61, 27, 231, 211, 213, 11, 50, 44, 245, 225, 215, 9, 51, 57, 11, 180, 162, 244, 41, 28, 11, 230, 205, 243, 12, 11, 239, 233, 239, 245, 40, 78, 29, 240, 220, 231, 244, 9, 39, 43, 36, 33, 20, 218, 219, 0, 248, 35, 55, 29, 236, 222, 6, 10, 14, 10, 15, 3, 230, 232, 238, 9, 44, 11, 229, 187, 179, 210, 249, 45, 2, 212, 211, 25, 35, 240, 239, 231, 0, 32, 27, 22, 6, 251, 11, 28, 38, 23, 0, 224, 222, 45, 47, 46, 10, 218, 238, 22, 18, 241, 4, 0, 8, 19, 252, 13, 0, 222, 242, 239, 235, 234, 20, 24, 235, 211, 204, 233, 231, 31, 46, 246, 230, 220, 210, 233, 26, 45, 29, 243, 236, 31, 41, 28, 32, 216, 254, 62, 41, 19, 29, 44, 1, 10, 225, 210, 216, 251, 87, 79, 2, 221, 174, 131, 223, 49, 37, 26, 15, 229, 216, 213, 230, 220, 214, 41, 56, 27, 231, 205, 217, 248, 64, 70, 250, 172, 227, 35, 41, 45, 23, 239, 248, 15, 31, 6, 7, 17, 39, 29, 233, 253, 13, 10, 23, 240, 234, 8, 15, 28, 38, 14, 201, 184, 184, 253, 94, 95, 3, 164, 131, 186, 20, 73, 41, 234, 195, 191, 11, 9, 239, 242, 244, 20, 40, 43, 239, 196, 228, 35, 94, 50, 236, 213, 200, 235, 32, 58, 49, 19, 226, 242, 15, 218, 227, 52, 74, 74, 15, 214, 0, 227, 250, 41, 38, 246, 8, 23, 231, 245, 237, 241, 230, 247, 32, 41, 5, 201, 210, 187, 216, 38, 50, 252, 237, 229, 232, 250, 0, 255, 237, 4, 10, 2, 240, 12, 12, 12, 9, 1, 5, 228, 12, 38, 15, 232, 247, 254, 241, 33, 47, 13, 210, 229, 20, 48, 18, 221, 237, 251, 26, 62, 8, 216, 246, 3, 2, 8, 30, 22, 18, 254, 249, 248, 241, 19, 23, 244, 253, 7, 248, 237, 6, 26, 3, 239, 242, 5, 7, 8, 12, 215, 217, 243, 255, 249, 251, 6, 236, 227, 245, 253, 253, 225, 231, 250, 234, 28, 25, 244, 210, 241, 6, 4, 28, 30, 47, 255, 227, 7, 247, 6, 50, 52, 11, 246, 9, 38, 0, 230, 252, 31, 20, 54, 61, 10, 216, 189, 233, 12, 39, 74, 30, 200, 147, 214, 50, 41, 16, 4, 243, 245, 204, 223, 218, 242, 242, 32, 53, 13, 6, 209, 196, 230, 28, 80, 61, 241, 186, 214, 26, 42, 65, 22, 234, 234, 238, 6, 17, 5, 245, 41, 42, 247, 237, 194, 208, 2, 19, 252, 18, 242, 238, 246, 224, 223, 216, 226, 13, 31, 30, 2, 228, 207, 218, 248, 14, 15, 255, 19, 18, 2, 14, 236, 241, 239, 7, 40, 44, 34, 9, 12, 251, 252, 22, 30, 38, 39, 31, 3, 20, 26, 9, 2, 8, 19, 38, 26, 28, 33, 13, 248, 1, 247, 239, 21, 56, 43, 12, 242, 239, 0, 183, 6, 8, 0, 1, 12, 253, 238, 243, 1, 5, 0, 5, 252, 253, 17, 26, 8, 255, 19, 43, 35, 14, 7, 17, 21, 19, 15, 8, 12, 12, 11, 252, 236, 255, 15, 10, 251, 235, 243, 238, 224, 225, 219, 217, 229, 228, 214, 198, 198, 224, 4, 245, 235, 14, 29, 26, 0, 3, 31, 47, 54, 54, 39, 16, 29, 56, 52, 33, 11, 18, 41, 23, 250, 246, 2, 1, 0, 253, 221, 220, 244, 237, 223, 209, 221, 249, 235, 204, 215, 245, 0, 245, 235, 247, 6, 17, 8, 245, 243, 0, 24, 16, 242, 243, 17, 30, 23, 0, 250, 16, 38, 29, 10, 9, 5, 21, 25, 4, 250, 21, 29, 16, 242, 240, 10, 18, 4, 245, 244, 244, 246, 241, 238, 230, 233, 237, 240, 229, 220, 243, 250, 251, 248, 4, 12, 21, 23, 14, 19, 29, 36, 40, 19, 9, 15, 16, 4, 3, 2, 251, 244, 237, 254, 0, 240, 244, 246, 233, 235, 249, 250, 236, 235, 246, 253, 243, 240, 2, 1, 247, 4, 9, 5, 8, 16, 24, 24, 2, 254, 13, 5, 252, 246, 254, 249, 0, 0, 254, 249, 248, 10, 13, 2, 15, 30, 32, 18, 5, 20, 20, 12, 0, 4, 3, 245, 253, 255, 249, 228, 236, 251, 251, 247, 249, 249, 0, 7, 10, 253, 240, 239, 255, 255, 229, 228, 254, 6, 247, 228, 238, 253, 0, 32, 48, 31, 7, 254, 255, 10, 2, 5, 30, 23, 248, 235, 253, 7, 248, 253, 31, 19, 240, 240, 253, 254, 255, 10, 18, 251, 227, 231, 253, 234, 237, 4, 6, 7, 245, 241, 248, 243, 253, 25, 17, 235, 250, 13, 254, 236, 252, 25, 34, 28, 11, 13, 20, 30, 46, 50, 32, 17, 30, 29, 252, 226, 247, 4, 242, 230, 233, 224, 189, 216, 2, 234, 208, 218, 249, 254, 217, 217, 242, 4, 2, 255, 8, 252, 245, 17, 38, 27, 3, 33, 64, 31, 12, 22, 26, 47, 40, 13, 14, 246, 6, 37, 3, 220, 219, 242, 252, 211, 173, 217, 246, 237, 229, 225, 220, 230, 3, 11, 244, 245, 13, 44, 25, 242, 247, 29, 47, 31, 24, 29, 43, 55, 43, 16, 7, 16, 47, 32, 243, 223, 0, 10, 249, 223, 213, 231, 249, 248, 235, 224, 211, 232, 1, 255, 230, 221, 244, 240, 238, 251, 1, 4, 1, 9, 10, 245, 250, 12, 35, 35, 10, 12, 2, 249, 1, 17, 38, 29, 13, 14, 4, 222, 245, 35, 35, 4, 241, 5, 15, 238, 224, 245, 5, 248, 252, 237, 218, 205, 225, 12, 6, 240, 252, 18, 4, 246, 254, 22, 38, 29, 30, 26, 4, 247, 19, 23, 4, 13, 21, 31, 13, 243, 251, 10, 14, 245, 246, 242, 248, 237, 209, 223, 233, 219, 223, 229, 226, 212, 228, 242, 0, 7, 13, 28, 14, 20, 49, 72, 60, 34, 42, 49, 38, 19, 4, 244, 254, 253, 244, 220, 205, 216, 247, 246, 209, 213, 243, 252, 0, 235, 236, 253, 254, 243, 13, 11, 249, 7, 23, 25, 248, 236, 27, 68, 30, 254, 20, 32, 10, 10, 2, 250, 235, 7, 36, 248, 202, 226, 10, 25, 248, 236, 6, 22, 26, 7, 247, 0, 31, 29, 2, 229, 224, 253, 8, 229, 203, 211, 240, 1, 239, 210, 223, 254, 3, 253, 239, 254, 12, 24, 2, 249, 0, 43, 58, 47, 16, 254, 33, 56, 50, 26, 18, 20, 16, 6, 255, 245, 244, 243, 6, 7, 225, 198, 222, 0, 249, 228, 242, 244, 234, 232, 248, 247, 226, 234, 9, 252, 230, 232, 0, 2, 251, 251, 5, 4, 251, 13, 21, 12, 9, 30, 32, 22, 10, 20, 49, 54, 37, 29, 27, 24, 45, 37, 246, 232, 245, 0, 238, 224, 219, 207, 194, 225, 226, 211, 199, 231, 2, 227, 206, 232, 12, 16, 14, 36, 34, 24, 19, 44, 46, 10, 20, 53, 62, 19, 240, 1, 22, 2, 6, 5, 252, 247, 223, 220, 234, 227, 248, 5, 241, 217, 218, 238, 230, 234, 6, 27, 22, 239, 240, 252, 2, 21, 30, 25, 11, 249, 253, 8, 10, 255, 19, 33, 5, 252, 243, 8, 27, 23, 13, 13, 16, 251, 248, 248, 250, 241, 0, 6, 254, 217, 222, 250, 241, 243, 8, 20, 6, 249, 247, 254, 6, 4, 18, 14, 227, 230, 12, 25, 248, 237, 244, 35, 4, 219, 6, 33, 19, 15, 24, 10, 250, 0, 33, 11, 209, 228, 255, 0, 229, 219, 237, 243, 228, 248, 26, 22, 14, 32, 41, 18, 254, 10, 46, 45, 27, 255, 241, 228, 251, 1, 240, 220, 224, 21, 10, 222, 243, 1, 12, 5, 241, 7, 13, 241, 231, 236, 241, 223, 252, 5, 240, 224, 220, 16, 14, 241, 255, 34, 20, 21, 43, 27, 36, 25, 35, 57, 23, 248, 3, 24, 4, 253, 246, 245, 0, 246, 250, 2, 242, 222, 4, 4, 226, 217, 228, 228, 205, 209, 244, 5, 225, 220, 254, 10, 255, 7, 55, 54, 41, 42, 40, 51, 43, 15, 10, 27, 19, 3, 233, 218, 224, 236, 236, 250, 239, 225, 0, 12, 242, 245, 2, 0, 6, 26, 4, 254, 4, 240, 242, 253, 245, 0, 7, 245, 0, 254, 250, 7, 248, 247, 13, 11, 243, 224, 240, 12, 1, 243, 246, 244, 249, 21, 10, 15, 13, 13, 33, 60, 44, 11, 11, 21, 37, 56, 11, 233, 247, 239, 0, 240, 207, 221, 243, 224, 223, 206, 187, 235, 7, 251, 246, 254, 13, 32, 20, 229, 0, 35, 46, 70, 33, 5, 29, 45, 27, 7, 253, 42, 69, 16, 216, 207, 221, 231, 231, 211, 190, 189, 200, 214, 223, 186, 196, 6, 41, 25, 239, 224, 6, 41, 38, 32, 26, 35, 63, 45, 35, 24, 16, 77, 112, 73, 10, 8, 28, 13, 244, 232, 240, 227, 186, 184, 170, 149, 158, 206, 219, 217, 238, 247, 3, 9, 7, 64, 100, 59, 39, 45, 49, 31, 22, 14, 31, 36, 0, 9, 247, 212, 3, 41, 34, 235, 202, 242, 246, 203, 177, 200, 221, 211, 204, 192, 207, 218, 11, 34, 13, 30, 44, 83, 69, 35, 44, 72, 92, 71, 11, 251, 228, 228, 0, 247, 200, 188, 216, 217, 194, 195, 240, 10, 251, 10, 26, 13, 8, 26, 59, 61, 42, 29, 5, 3, 4, 252, 0, 252, 1, 255, 233, 218, 219, 246, 255, 6, 250, 228, 244, 247, 244, 239, 245, 0, 19, 13, 237, 233, 230, 254, 34, 14, 24, 13, 21, 27, 8, 44, 45, 45, 58, 34, 1, 253, 4, 2, 254, 232, 207, 222, 207, 185, 195, 219, 241, 234, 235, 225, 229, 238, 240, 21, 33, 25, 47, 45, 33, 21, 19, 54, 65, 35, 18, 17, 254, 239, 241, 234, 226, 231, 5, 255, 229, 217, 205, 226, 0, 10, 14, 239, 241, 1, 5, 4, 9, 26, 25, 20, 38, 4, 238, 5, 35, 37, 16, 11, 2, 248, 245, 1, 252, 239, 239, 0, 245, 208, 209, 234, 227, 231, 9, 6, 8, 249, 251, 20, 28, 38, 58, 52, 19, 20, 26, 254, 245, 245, 1, 12, 232, 230, 232, 223, 231, 250, 15, 240, 236, 14, 249, 244, 241, 254, 2, 5, 27, 7, 234, 232, 17, 32, 0, 21, 26, 17, 249, 239, 253, 233, 3, 15, 254, 230, 207, 236, 237, 222, 243, 1, 15, 2, 4, 246, 7, 53, 53, 53, 53, 62, 52, 18, 27, 33, 41, 20, 253, 1, 212, 209, 227, 234, 218, 222, 229, 227, 227, 224, 236, 246, 237, 0, 246, 215, 220, 223, 235, 233, 0, 12, 0, 248, 247, 15, 30, 44, 73, 72, 44, 40, 35, 36, 36, 23, 20, 25, 248, 227, 227, 204, 211, 229, 245, 241, 223, 222, 238, 246, 254, 20, 38, 15, 10, 26, 2, 0, 14, 0, 249, 248, 251, 0, 228, 211, 242, 1, 15, 14, 11, 0, 251, 14, 6, 8, 24, 19, 17, 254, 233, 248, 248, 243, 19, 18, 234, 11, 11, 252, 254, 9, 44, 33, 254, 2, 6, 254, 231, 252, 12, 236, 229, 237, 224, 206, 220, 244, 255, 236, 228, 12, 7, 255, 16, 36, 41, 37, 38, 39, 15, 2, 11, 35, 23, 243, 18, 1, 229, 247, 237, 239, 2, 240, 246, 243, 229, 230, 255, 0, 244, 2, 249, 7, 6, 229, 240, 25, 43, 12, 255, 1, 247, 13, 14, 6, 11, 6, 3, 16, 235, 198, 0, 21, 7, 2, 220, 239, 18, 246, 248, 255, 9, 25, 33, 0, 244, 247, 6, 26, 25, 0, 248, 8, 1, 239, 238, 254, 7, 23, 5, 246, 248, 225, 239, 25, 4, 247, 3, 3, 9, 250, 244, 21, 36, 22, 11, 15, 10, 3, 23, 12, 1, 253, 2, 6, 244, 222, 218, 245, 250, 225, 226, 237, 238, 245, 244, 240, 237, 10, 10, 9, 249, 240, 31, 35, 18, 25, 251, 247, 21, 15, 244, 236, 247, 3, 14, 249, 238, 254, 252, 10, 24, 254, 252, 29, 24, 6, 12, 12, 30, 38, 21, 13, 11, 255, 9, 17, 8, 240, 242, 245, 224, 215, 223, 240, 242, 250, 233, 237, 238, 250, 15, 255, 247, 3, 19, 11, 1, 5, 0, 249, 19, 12, 9, 250, 2, 8, 7, 241, 26, 33, 253, 8, 247, 249, 252, 244, 6, 0, 220, 228, 241, 234, 235, 244, 244, 4, 253, 255, 8, 254, 9, 21, 29, 20, 16, 21, 29, 26, 7, 19, 26, 19, 23, 14, 12, 21, 253, 13, 4, 12, 2, 2, 250, 248, 247, 238, 237, 220, 230, 225, 222, 227, 211, 225, 229, 225, 245, 239, 241, 253, 3, 11, 8, 14, 17, 20, 17, 12, 12, 3, 6, 18, 5, 246, 246, 9, 14, 249, 247, 236, 245, 10, 10, 17, 0, 253, 19, 24, 16, 7, 37, 42, 28, 32, 14, 30, 16, 11, 29, 5, 251, 250, 8, 0, 229, 242, 234, 243, 244, 244, 249, 231, 239, 245, 5, 0, 237, 0, 250, 241, 252, 243, 10, 17, 254, 2, 2, 2, 2, 4, 2, 250, 244, 236, 249, 237, 219, 225, 239, 233, 214, 206, 222, 221, 225, 225, 227, 241, 227, 248, 0, 0, 30, 7, 15, 0, 0, 248, 249, 252, 250, 251, 254, 255, 255, 0, 249, 243, 242, 249, 1, 3, 0, 2, 3, 1, 253, 251, 247, 248, 252, 252, 255, 250, 253, 253, 255, 254, 0, 8, 16, 18, 18, 16, 12, 8, 6, 5, 7, 12, 17, 24, 24, 24, 21, 19, 20, 16, 13, 13, 7, 9, 8, 6, 7, 12, 14, 20, 21, 21, 19, 15, 7, 0, 249, 239, 242, 245, 243, 245, 247, 248, 251, 249, 251, 250, 243, 241, 237, 240, 241, 242, 244, 247, 248, 248, 249, 243, 241, 245, 247, 249, 248, 250, 0, 255, 254, 251, 251, 246, 239, 247, 241, 233, 230, 231, 236, 240, 245, 253, 0, 1, 3, 2, 0, 255, 0, 6, 8, 11, 16, 25, 27, 30, 36, 36, 26, 17, 5, 255, 253, 254, 0, 3, 9, 15, 19, 21, 21, 18, 12, 5, 5, 6, 5, 2, 2, 0, 253, 0, 12, 16, 12, 2, 246, 237, 235, 232, 227, 224, 226, 232, 238, 243, 247, 252, 255, 1, 3, 0, 251, 244, 242, 247, 251, 0, 4, 6, 1, 251, 248, 243, 247, 248, 249, 254, 4, 255, 255, 255, 253, 255, 4, 5, 5, 4, 0, 3, 2, 0, 254, 255, 3, 6, 12, 14, 10, 4, 0, 1, 3, 12, 20, 22, 26, 22, 20, 18, 15, 9, 4, 1, 0, 13, 15, 12, 11, 5, 254, 249, 241, 242, 238, 238, 243, 249, 247, 250, 253, 254, 255, 0, 1, 3, 6, 3, 0, 254, 254, 5, 7, 1, 0, 250, 248, 247, 240, 241, 241, 244, 248, 249, 250, 1, 4, 254, 0, 253, 253, 0, 0, 4, 10, 17, 21, 15, 4, 250, 242, 236, 230, 229, 234, 236, 239, 243, 0, 10, 19, 24, 22, 17, 18, 15, 17, 14, 11, 17, 31, 39, 44, 42, 34, 34, 30, 24, 14, 7, 255, 254, 0, 0, 1, 4, 11, 10, 7, 2, 2, 4, 1, 255, 250, 0, 5, 8, 8, 9, 6, 2, 1, 252, 243, 239, 237, 232, 230, 222, 221, 222, 229, 235, 235, 241, 240, 236, 237, 237, 242, 244, 244, 246, 245, 241, 245, 237, 231, 235, 235, 244, 248, 243, 240, 236, 234, 238, 236, 243, 252, 251, 254, 0, 252, 0, 0, 5, 9, 13, 18, 22, 21, 18, 22, 26, 36, 41, 38, 43, 40, 34, 26, 17, 11, 14, 8, 8, 8, 9, 18, 26, 24, 12, 254, 254, 254, 251, 254, 252, 253, 252, 253, 255, 1, 5, 6, 3, 254, 250, 250, 248, 241, 242, 245, 248, 254, 0, 3, 11, 11, 14, 9, 250, 236, 236, 235, 242, 246, 250, 251, 251, 0, 0, 252, 242, 234, 234, 230, 234, 238, 243, 246, 242, 250, 10, 16, 18, 15, 10, 3, 1, 254, 255, 251, 6, 20, 20, 25, 28, 20, 11, 1, 250, 250, 251, 252, 247, 246, 244, 254, 7, 0, 252, 255, 0, 3, 0, 1, 2, 12, 15, 22, 25, 21, 20, 11, 7, 10, 7, 8, 6, 2, 3, 9, 5, 255, 252, 239, 228, 230, 231, 233, 237, 237, 242, 248, 253, 8, 19, 16, 14, 9, 253, 253, 250, 244, 244, 243, 246, 253, 254, 252, 249, 238, 234, 237, 239, 243, 243, 252, 1, 0, 0, 11, 11, 12, 19, 23, 22, 20, 15, 16, 13, 9, 12, 20, 23, 28, 30, 26, 20, 12, 6, 6, 8, 10, 9, 7, 6, 9, 15, 24, 30, 29, 25, 12, 1, 250, 248, 245, 243, 237, 230, 224, 236, 244, 248, 242, 238, 241, 242, 249, 253, 246, 237, 233, 236, 248, 253, 3, 5, 5, 254, 252, 243, 242, 242, 241, 237, 231, 231, 232, 234, 244, 247, 255, 3, 0, 255, 255, 254, 2, 4, 254, 0, 3, 5, 7, 2, 2, 9, 14, 17, 14, 3, 254, 249, 244, 250, 246, 246, 252, 251, 0, 3, 8, 22, 29, 28, 33, 28, 25, 16, 6, 9, 5, 10, 18, 18, 17, 21, 23, 26, 15, 4, 3, 0, 253, 254, 249, 248, 246, 252, 2, 0, 255, 253, 254, 243, 239, 234, 224, 232, 242, 247, 3, 2, 2, 1, 243, 232, 239, 245, 253, 254, 255, 3, 10, 13, 12, 6, 255, 4, 7, 1, 250, 241, 240, 244, 246, 243, 247, 251, 2, 5, 0, 249, 233, 228, 229, 234, 250, 255, 253, 6, 27, 29, 28, 27, 21, 5, 255, 254, 255, 0, 253, 7, 11, 9, 17, 28, 29, 18, 3, 4, 4, 254, 251, 255, 1, 11, 16, 23, 29, 30, 31, 31, 23, 8, 250, 239, 238, 237, 244, 249, 251, 4, 5, 1, 2, 251, 242, 243, 241, 241, 233, 233, 245, 0, 14, 20, 16, 9, 0, 243, 239, 241, 235, 226, 224, 236, 249, 0, 4, 0, 251, 247, 240, 235, 236, 233, 237, 247, 1, 15, 27, 34, 35, 29, 21, 9, 3, 2, 253, 3, 8, 19, 25, 30, 26, 20, 15, 17, 14, 6, 248, 236, 245, 251, 252, 5, 9, 11, 16, 9, 4, 0, 244, 250, 254, 253, 5, 0, 0, 5, 252, 252, 0, 246, 247, 252, 243, 244, 241, 241, 250, 251, 251, 2, 10, 6, 3, 2, 250, 244, 235, 226, 232, 234, 234, 240, 239, 232, 227, 232, 240, 244, 246, 243, 241, 243, 244, 10, 24, 26, 29, 26, 20, 18, 21, 19, 14, 1, 3, 20, 16, 16, 23, 14, 6, 5, 5, 0, 253, 252, 253, 251, 253, 11, 22, 15, 17, 24, 29, 36, 40, 30, 17, 12, 255, 250, 242, 231, 234, 239, 229, 243, 253, 245, 253, 251, 248, 246, 230, 229, 242, 250, 6, 15, 21, 30, 23, 21, 17, 254, 254, 0, 255, 3, 255, 247, 248, 244, 254, 3, 251, 243, 231, 210, 215, 227, 230, 239, 250, 252, 0, 3, 10, 25, 36, 12, 253, 2, 241, 250, 3, 239, 242, 249, 3, 30, 40, 29, 15, 248, 229, 229, 243, 0, 4, 246, 243, 254, 11, 29, 34, 23, 20, 30, 33, 21, 8, 243, 233, 250, 15, 39, 52, 31, 18, 4, 236, 239, 236, 237, 244, 228, 228, 240, 255, 12, 20, 14, 255, 0, 13, 6, 17, 11, 229, 224, 237, 247, 14, 16, 10, 12, 254, 245, 236, 226, 220, 210, 216, 231, 233, 245, 247, 236, 246, 241, 247, 11, 15, 7, 255, 2, 0, 253, 12, 21, 29, 34, 17, 18, 25, 20, 23, 19, 24, 29, 32, 37, 33, 18, 10, 5, 0, 13, 10, 0, 251, 248, 246, 240, 243, 5, 25, 22, 23, 23, 20, 16, 252, 243, 245, 239, 248, 253, 248, 251, 245, 245, 253, 243, 235, 242, 235, 223, 216, 204, 190, 193, 205, 225, 249, 10, 8, 8, 250, 249, 4, 7, 13, 10, 2, 0, 252, 253, 245, 242, 246, 237, 243, 248, 237, 243, 237, 228, 251, 2, 19, 39, 22, 25, 24, 34, 51, 44, 41, 49, 48, 62, 56, 45, 38, 21, 23, 18, 254, 253, 230, 226, 241, 238, 255, 0, 252, 3, 243, 225, 241, 230, 244, 8, 254, 10, 9, 4, 21, 5, 10, 20, 255, 1, 242, 216, 229, 223, 209, 224, 217, 204, 226, 230, 223, 239, 246, 251, 18, 31, 39, 55, 52, 33, 16, 247, 243, 7, 4, 1, 1, 2, 12, 13, 255, 239, 216, 204, 212, 236, 246, 1, 8, 0, 255, 0, 8, 22, 18, 30, 42, 28, 21, 18, 6, 249, 230, 226, 239, 242, 241, 255, 1, 7, 23, 26, 31, 28, 23, 30, 31, 28, 24, 45, 57, 68, 70, 43, 30, 33, 39, 27, 5, 254, 232, 213, 207, 186, 189, 190, 183, 195, 213, 218, 224, 233, 219, 220, 224, 236, 243, 228, 235, 0, 5, 3, 14, 14, 249, 254, 1, 245, 241, 246, 253, 2, 3, 5, 8, 6, 251, 1, 1, 242, 245, 238, 236, 250, 3, 29, 48, 45, 43, 38, 23, 33, 29, 22, 19, 6, 1, 9, 6, 13, 18, 4, 4, 253, 2, 26, 29, 31, 19, 9, 8, 11, 18, 19, 26, 13, 9, 25, 12, 12, 2, 225, 227, 226, 214, 228, 229, 225, 239, 220, 191, 204, 208, 218, 237, 235, 244, 9, 22, 9, 235, 223, 226, 228, 253, 14, 4, 15, 13, 242, 246, 240, 245, 4, 0, 1, 10, 18, 17, 13, 25, 17, 9, 18, 26, 27, 28, 23, 23, 38, 43, 30, 35, 46, 24, 21, 15, 248, 253, 246, 216, 215, 214, 229, 0, 5, 9, 255, 236, 243, 234, 235, 231, 211, 224, 246, 240, 8, 10, 12, 30, 9, 255, 254, 0, 9, 6, 8, 2, 4, 19, 5, 14, 27, 17, 38, 44, 24, 19, 19, 4, 246, 238, 250, 2, 19, 24, 1, 1, 253, 246, 249, 239, 224, 219, 213, 213, 228, 252, 0, 252, 240, 242, 246, 255, 18, 29, 19, 17, 25, 22, 18, 18, 9, 12, 32, 26, 12, 9, 238, 227, 244, 229, 225, 3, 15, 21, 31, 29, 10, 10, 13, 249, 243, 236, 214, 211, 212, 209, 232, 251, 242, 231, 232, 225, 220, 227, 222, 214, 216, 231, 242, 249, 247, 254, 7, 14, 30, 41, 44, 34, 7, 1, 253, 244, 0, 0, 244, 5, 23, 30, 40, 14, 247, 249, 252, 255, 11, 24, 12, 0, 2, 2, 7, 27, 24, 14, 254, 245, 0, 241, 238, 244, 221, 234, 252, 250, 26, 36, 8, 15, 7, 249, 29, 48, 51, 73, 77, 79, 90, 81, 59, 47, 34, 28, 41, 36, 24, 30, 19, 6, 20, 18, 20, 34, 22, 4, 245, 229, 232, 222, 207, 212, 214, 237, 1, 255, 8, 0, 242, 240, 226, 217, 220, 215, 199, 193, 199, 222, 228, 245, 242, 211, 210, 207, 192, 197, 195, 183, 201, 215, 216, 231, 238, 221, 225, 242, 236, 240, 238, 215, 213, 221, 205, 212, 228, 220, 232, 254, 254, 8, 7, 251, 238, 234, 237, 242, 250, 0, 0, 5, 21, 39, 49, 77, 77, 62, 73, 65, 40, 26, 3, 3, 8, 21, 34, 43, 54, 40, 40, 36, 35, 43, 31, 36, 34, 26, 50, 53, 39, 47, 45, 45, 31, 34, 16, 243, 249, 227, 200, 220, 230, 232, 13, 15, 5, 31, 29, 33, 24, 7, 10, 11, 28, 30, 10, 36, 32, 39, 47, 22, 26, 32, 28, 19, 7, 4, 0, 9, 13, 4, 32, 52, 44, 54, 43, 7, 255, 235, 213, 210, 198, 192, 199, 191, 184, 171, 189, 198, 179, 186, 173, 157, 145, 133, 140, 143, 166, 200, 216, 227, 251, 233, 224, 219, 193, 197, 220, 224, 235, 255, 251, 251, 18, 30, 24, 36, 49, 50, 59, 50, 34, 31, 21, 15, 25, 39, 71, 65, 61, 53, 36, 32, 33, 20, 9, 5, 8, 21, 30, 22, 4, 13, 21, 23, 28, 24, 18, 14, 5, 253, 253, 254, 0, 3, 3, 4, 6, 7, 9, 6, 4, 3, 1, 0, 0, 168, 6, 10, 0, 0, 255, 0, 1, 254, 252, 1, 6, 8, 8, 10, 10, 9, 11, 11, 3, 250, 250, 253, 249, 246, 247, 248, 253, 0, 0, 4, 5, 253, 247, 245, 245, 242, 239, 244, 253, 3, 2, 3, 8, 5, 1, 0, 255, 3, 3, 0, 3, 7, 12, 13, 22, 27, 19, 10, 5, 9, 10, 7, 9, 9, 255, 247, 2, 9, 249, 237, 243, 250, 247, 244, 247, 239, 223, 235, 249, 251, 248, 239, 0, 14, 4, 253, 5, 9, 0, 1, 3, 6, 0, 254, 19, 17, 10, 17, 29, 31, 18, 13, 17, 21, 252, 238, 227, 204, 214, 246, 2, 4, 10, 21, 38, 37, 8, 227, 217, 225, 212, 196, 201, 217, 235, 19, 58, 48, 25, 30, 24, 253, 234, 231, 217, 226, 2, 0, 11, 38, 47, 61, 68, 48, 253, 233, 250, 242, 6, 14, 244, 249, 29, 69, 64, 50, 22, 0, 246, 232, 222, 185, 188, 230, 235, 242, 4, 6, 4, 14, 11, 217, 194, 213, 218, 218, 219, 235, 253, 17, 20, 0, 252, 6, 15, 23, 15, 251, 246, 0, 6, 249, 243, 24, 54, 49, 41, 44, 38, 6, 14, 26, 241, 191, 239, 38, 35, 28, 8, 17, 0, 234, 225, 220, 221, 199, 209, 241, 249, 0, 23, 13, 241, 236, 244, 6, 14, 12, 252, 236, 246, 250, 10, 31, 33, 29, 34, 76, 66, 3, 249, 13, 16, 5, 255, 216, 240, 43, 50, 38, 9, 2, 3, 238, 239, 233, 207, 236, 231, 216, 247, 225, 194, 217, 230, 196, 183, 227, 255, 244, 251, 31, 22, 3, 43, 44, 16, 9, 30, 28, 229, 231, 228, 230, 24, 55, 55, 51, 53, 35, 13, 240, 250, 254, 224, 237, 255, 243, 236, 250, 15, 37, 13, 229, 212, 214, 215, 212, 233, 248, 9, 16, 5, 30, 39, 38, 20, 238, 238, 237, 240, 244, 243, 13, 48, 79, 92, 62, 19, 2, 8, 252, 227, 232, 217, 231, 25, 46, 53, 35, 4, 1, 19, 253, 223, 215, 223, 244, 249, 5, 254, 7, 10, 5, 22, 248, 238, 226, 227, 239, 221, 220, 222, 0, 15, 30, 44, 20, 246, 201, 201, 241, 243, 251, 8, 14, 34, 35, 41, 31, 234, 168, 156, 183, 207, 245, 244, 242, 253, 255, 38, 78, 68, 28, 4, 232, 189, 169, 177, 207, 230, 9, 26, 23, 41, 79, 66, 52, 49, 234, 191, 225, 15, 42, 60, 52, 74, 101, 83, 92, 69, 32, 8, 235, 254, 253, 13, 36, 26, 34, 36, 12, 3, 11, 3, 226, 201, 188, 156, 171, 204, 222, 224, 2, 40, 21, 17, 10, 230, 199, 163, 143, 185, 247, 233, 219, 21, 38, 39, 39, 14, 250, 230, 203, 199, 230, 248, 241, 23, 88, 78, 61, 44, 252, 204, 199, 211, 190, 184, 210, 2, 23, 17, 46, 82, 112, 106, 46, 15, 235, 173, 150, 184, 239, 4, 43, 83, 99, 99, 52, 25, 35, 4, 237, 211, 198, 237, 237, 3, 40, 46, 43, 34, 36, 3, 224, 206, 203, 217, 234, 255, 244, 247, 21, 43, 36, 9, 242, 218, 215, 200, 218, 4, 250, 244, 32, 41, 21, 24, 14, 0, 228, 213, 227, 213, 219, 230, 203, 235, 37, 38, 50, 84, 63, 255, 215, 217, 202, 193, 218, 233, 243, 40, 86, 75, 68, 46, 2, 255, 14, 250, 197, 181, 222, 225, 0, 37, 12, 42, 69, 60, 32, 240, 226, 223, 217, 214, 222, 252, 13, 52, 79, 44, 46, 51, 24, 230, 220, 247, 230, 219, 207, 224, 1, 245, 228, 252, 40, 19, 220, 220, 214, 176, 188, 213, 229, 252, 255, 249, 249, 33, 25, 3, 26, 13, 250, 241, 38, 76, 61, 73, 62, 35, 31, 43, 46, 14, 235, 242, 35, 73, 59, 2, 228, 252, 247, 246, 14, 5, 224, 185, 208, 220, 187, 196, 206, 228, 249, 247, 11, 13, 236, 204, 218, 235, 235, 246, 253, 25, 39, 5, 251, 5, 27, 17, 0, 6, 14, 29, 37, 39, 30, 3, 242, 251, 250, 1, 12, 15, 0, 240, 29, 28, 8, 25, 4, 2, 247, 223, 239, 241, 251, 254, 229, 229, 0, 14, 12, 23, 13, 235, 241, 15, 243, 181, 225, 30, 31, 30, 245, 242, 0, 12, 27, 248, 236, 233, 253, 31, 40, 24, 250, 248, 16, 4, 227, 227, 231, 227, 249, 27, 48, 47, 41, 35, 29, 1, 229, 226, 225, 229, 225, 237, 17, 23, 249, 11, 44, 34, 19, 32, 23, 231, 222, 242, 244, 249, 12, 253, 249, 9, 22, 32, 27, 15, 242, 247, 14, 242, 195, 192, 212, 233, 243, 245, 245, 253, 20, 27, 12, 247, 255, 3, 228, 220, 215, 246, 16, 21, 49, 30, 20, 10, 245, 222, 216, 239, 242, 255, 0, 5, 37, 44, 34, 24, 23, 15, 241, 229, 246, 245, 229, 240, 0, 14, 35, 42, 39, 37, 29, 14, 241, 206, 204, 227, 216, 235, 7, 11, 45, 80, 83, 43, 21, 0, 226, 224, 206, 190, 202, 244, 40, 69, 69, 35, 15, 17, 234, 219, 217, 202, 221, 223, 228, 254, 17, 37, 61, 51, 27, 3, 196, 191, 232, 212, 190, 223, 12, 32, 26, 22, 12, 254, 230, 234, 232, 195, 198, 243, 12, 244, 252, 33, 73, 77, 43, 26, 8, 243, 221, 247, 18, 14, 14, 35, 93, 69, 23, 42, 39, 0, 236, 246, 252, 245, 245, 248, 245, 3, 16, 23, 33, 16, 230, 209, 198, 194, 194, 176, 185, 211, 199, 206, 228, 0, 2, 252, 43, 46, 4, 5, 10, 0, 246, 247, 26, 36, 30, 46, 58, 63, 93, 90, 54, 27, 13, 252, 234, 255, 2, 5, 0, 38, 43, 6, 17, 255, 217, 174, 149, 151, 159, 163, 175, 222, 15, 36, 12, 242, 0, 3, 225, 197, 205, 237, 237, 234, 24, 42, 46, 72, 57, 58, 47, 249, 0, 17, 16, 24, 27, 35, 24, 5, 24, 62, 50, 28, 22, 27, 21, 249, 221, 198, 211, 227, 249, 3, 11, 5, 232, 215, 212, 208, 186, 223, 7, 0, 239, 231, 255, 19, 38, 48, 58, 48, 32, 10, 231, 247, 242, 240, 12, 22, 18, 18, 65, 75, 45, 34, 16, 239, 207, 205, 201, 215, 224, 209, 234, 0, 245, 253, 16, 10, 248, 211, 208, 221, 217, 216, 219, 4, 44, 53, 38, 41, 28, 0, 1, 25, 26, 253, 253, 9, 31, 13, 251, 8, 23, 20, 0, 1, 248, 244, 241, 247, 9, 242, 225, 219, 233, 255, 233, 237, 239, 222, 205, 222, 235, 228, 5, 24, 31, 39, 39, 37, 43, 27, 236, 228, 5, 3, 240, 0, 35, 43, 32, 38, 26, 12, 20, 33, 46, 28, 249, 255, 39, 38, 12, 249, 254, 18, 8, 240, 205, 194, 219, 238, 244, 234, 234, 7, 20, 3, 234, 209, 194, 209, 238, 209, 209, 246, 0, 24, 24, 21, 19, 21, 18, 12, 12, 0, 247, 233, 7, 40, 17, 253, 254, 4, 26, 41, 19, 9, 37, 35, 23, 24, 16, 8, 243, 249, 243, 203, 207, 210, 201, 203, 230, 19, 29, 23, 9, 5, 5, 3, 253, 233, 231, 239, 254, 255, 250, 1, 12, 49, 73, 46, 16, 250, 251, 252, 245, 235, 208, 234, 9, 45, 82, 68, 49, 35, 33, 13, 236, 231, 217, 194, 201, 226, 243, 236, 236, 12, 25, 17, 10, 0, 12, 254, 220, 198, 187, 200, 223, 244, 250, 10, 10, 244, 8, 25, 15, 245, 225, 226, 233, 251, 4, 22, 27, 38, 66, 39, 29, 19, 6, 0, 241, 248, 249, 22, 33, 26, 31, 37, 45, 32, 11, 6, 253, 232, 236, 235, 232, 238, 242, 5, 23, 19, 2, 5, 253, 251, 231, 219, 238, 231, 234, 6, 19, 16, 23, 5, 4, 11, 5, 246, 241, 254, 237, 237, 251, 23, 43, 36, 30, 7, 246, 239, 239, 233, 227, 233, 245, 12, 14, 27, 39, 27, 33, 29, 248, 207, 200, 191, 176, 202, 232, 236, 246, 15, 23, 24, 3, 231, 238, 243, 238, 209, 225, 246, 243, 15, 36, 63, 72, 58, 35, 17, 4, 230, 218, 226, 249, 19, 31, 60, 65, 48, 64, 67, 35, 17, 239, 218, 218, 185, 177, 238, 50, 36, 30, 27, 9, 9, 10, 2, 219, 195, 192, 203, 222, 228, 252, 14, 34, 43, 33, 35, 21, 243, 209, 213, 235, 225, 227, 25, 63, 67, 68, 35, 239, 250, 233, 213, 248, 229, 210, 249, 21, 17, 24, 24, 26, 13, 227, 218, 215, 179, 156, 186, 241, 8, 255, 22, 65, 67, 48, 13, 247, 0, 233, 216, 238, 242, 244, 22, 77, 101, 71, 32, 22, 19, 254, 248, 0, 249, 232, 4, 46, 46, 37, 18, 246, 249, 252, 216, 181, 160, 160, 203, 11, 41, 25, 33, 58, 47, 20, 245, 200, 179, 205, 228, 233, 254, 21, 30, 37, 70, 67, 11, 7, 250, 207, 195, 213, 223, 235, 8, 18, 45, 66, 47, 19, 8, 4, 218, 200, 235, 2, 249, 242, 21, 36, 45, 29, 251, 234, 225, 207, 206, 252, 24, 26, 0, 19, 42, 16, 3, 0, 238, 206, 185, 202, 236, 0, 251, 31, 67, 40, 36, 44, 63, 25, 221, 218, 234, 249, 252, 3, 33, 52, 34, 31, 34, 9, 231, 195, 204, 230, 217, 221, 18, 43, 19, 17, 41, 17, 247, 240, 228, 235, 201, 175, 200, 247, 4, 248, 4, 15, 27, 24, 24, 25, 254, 236, 254, 33, 34, 10, 20, 43, 27, 4, 255, 16, 252, 235, 248, 250, 18, 15, 10, 8, 16, 6, 239, 247, 251, 243, 212, 204, 216, 231, 0, 254, 246, 252, 0, 1, 0, 245, 231, 229, 228, 252, 254, 2, 56, 54, 42, 35, 21, 21, 5, 254, 242, 253, 0, 243, 237, 248, 10, 13, 9, 10, 12, 15, 26, 12, 251, 240, 239, 251, 8, 16, 9, 0, 244, 249, 0, 4, 15, 5, 10, 12, 249, 236, 229, 0, 19, 20, 9, 2, 255, 244, 241, 252, 10, 255, 235, 241, 249, 234, 220, 226, 247, 6, 15, 12, 5, 13, 11, 1, 1, 0, 1, 89, 9, 40, 0, 2, 0, 0, 4, 1, 0, 2, 255, 254, 255, 250, 2, 254, 246, 254, 2, 255, 251, 251, 0, 253, 252, 253, 1, 0, 0, 2, 2, 1, 3, 4, 6, 2, 6, 7, 6, 4, 4, 6, 3, 3, 5, 5, 3, 255, 3, 1, 253, 2, 0, 252, 251, 255, 253, 250, 253, 0, 255, 251, 251, 253, 253, 0, 255, 250, 252, 1, 2, 255, 1, 0, 1, 2, 1, 1, 3, 2, 1, 1, 3, 8, 3, 3, 2, 6, 7, 6, 10, 254, 1, 11, 254, 255, 6, 0, 0, 0, 0, 6, 0, 251, 4, 0, 0, 2, 255, 0, 255, 1, 3, 248, 1, 3, 255, 3, 0, 2, 253, 251, 5, 0, 252, 255, 2, 1, 252, 249, 255, 240, 208, 216, 240, 247, 241, 244, 0, 255, 254, 254, 255, 15, 14, 5, 4, 7, 9, 14, 9, 14, 15, 10, 11, 1, 8, 19, 10, 11, 13, 9, 13, 8, 13, 5, 254, 253, 253, 0, 0, 247, 255, 251, 248, 0, 6, 247, 248, 5, 252, 250, 5, 4, 246, 4, 8, 3, 253, 5, 0, 8, 9, 254, 1, 2, 6, 5, 1, 2, 9, 4, 252, 227, 226, 225, 239, 242, 237, 246, 248, 249, 243, 246, 250, 0, 9, 5, 5, 5, 12, 22, 27, 24, 240, 8, 30, 235, 253, 23, 253, 246, 1, 15, 2, 251, 9, 6, 0, 6, 10, 6, 5, 21, 0, 243, 9, 15, 0, 234, 252, 3, 240, 235, 0, 254, 234, 244, 2, 2, 14, 15, 16, 2, 8, 11, 239, 3, 249, 247, 249, 1, 3, 240, 235, 2, 10, 240, 239, 251, 254, 249, 252, 12, 23, 6, 13, 12, 7, 10, 0, 0, 250, 4, 11, 0, 15, 5, 0, 31, 34, 0, 0, 11, 8, 8, 252, 8, 18, 252, 248, 241, 241, 249, 237, 239, 243, 241, 245, 2, 255, 252, 255, 0, 8, 13, 244, 206, 218, 240, 254, 0, 15, 252, 247, 10, 13, 1, 253, 10, 252, 11, 31, 4, 245, 14, 29, 10, 0, 9, 0, 4, 5, 254, 252, 255, 15, 5, 229, 16, 23, 230, 252, 19, 245, 243, 5, 251, 232, 10, 6, 241, 13, 10, 245, 240, 2, 21, 240, 230, 21, 13, 248, 242, 247, 25, 3, 252, 5, 239, 9, 25, 244, 246, 252, 16, 27, 245, 252, 21, 5, 251, 8, 12, 4, 250, 9, 19, 6, 237, 246, 26, 31, 225, 232, 40, 248, 250, 246, 239, 14, 1, 248, 4, 227, 9, 13, 211, 11, 27, 243, 230, 0, 9, 250, 249, 12, 13, 234, 235, 22, 11, 246, 245, 0, 1, 3, 11, 0, 2, 10, 254, 254, 0, 7, 5, 248, 254, 12, 13, 252, 237, 253, 13, 16, 250, 246, 28, 244, 224, 21, 32, 7, 197, 242, 62, 5, 227, 251, 17, 7, 238, 244, 19, 12, 241, 249, 0, 17, 18, 237, 7, 6, 250, 18, 246, 232, 17, 17, 238, 244, 247, 24, 7, 227, 0, 0, 9, 255, 242, 15, 1, 7, 253, 249, 16, 10, 6, 223, 16, 42, 241, 209, 17, 64, 237, 208, 4, 32, 15, 218, 249, 20, 253, 11, 245, 239, 27, 24, 222, 232, 30, 20, 239, 236, 17, 6, 231, 244, 17, 30, 222, 233, 20, 30, 249, 239, 246, 4, 28, 228, 228, 39, 7, 234, 5, 16, 17, 253, 216, 10, 23, 5, 239, 246, 46, 0, 232, 0, 251, 12, 8, 248, 238, 13, 20, 243, 238, 23, 2, 227, 12, 21, 244, 242, 22, 13, 249, 242, 254, 18, 9, 226, 248, 18, 27, 252, 198, 250, 57, 253, 215, 254, 40, 18, 203, 4, 46, 2, 1, 5, 240, 246, 58, 14, 208, 218, 42, 48, 208, 210, 49, 38, 214, 228, 0, 17, 15, 246, 234, 233, 43, 10, 196, 8, 34, 212, 0, 50, 235, 229, 12, 24, 6, 220, 240, 36, 20, 237, 233, 3, 56, 23, 199, 238, 53, 25, 214, 225, 42, 25, 228, 240, 24, 10, 18, 241, 206, 12, 52, 253, 193, 232, 55, 56, 223, 192, 23, 84, 215, 217, 48, 250, 234, 5, 49, 246, 204, 34, 42, 241, 217, 243, 57, 0, 210, 6, 243, 2, 12, 244, 7, 9, 2, 12, 249, 242, 240, 22, 35, 202, 0, 38, 248, 2, 244, 20, 3, 231, 10, 16, 4, 224, 1, 43, 235, 238, 44, 248, 241, 251, 254, 19, 248, 198, 40, 62, 196, 224, 62, 242, 232, 8, 4, 3, 246, 0, 27, 248, 204, 9, 51, 246, 234, 245, 15, 30, 220, 237, 26, 18, 253, 231, 15, 18, 0, 9, 245, 241, 30, 12, 19, 217, 236, 29, 20, 244, 249, 6, 241, 2, 10, 0, 237, 7, 249, 247, 18, 8, 243, 3, 21, 206, 5, 25, 13, 225, 219, 50, 247, 229, 4, 247, 7, 29, 241, 221, 47, 36, 211, 241, 34, 22, 240, 253, 21, 253, 0, 18, 245, 9, 8, 227, 23, 12, 229, 244, 11, 36, 236, 211, 30, 44, 252, 227, 250, 7, 249, 245, 21, 0, 235, 39, 221, 227, 55, 8, 254, 252, 218, 252, 39, 242, 217, 25, 29, 5, 202, 29, 73, 213, 197, 29, 30, 225, 12, 7, 253, 6, 220, 16, 21, 234, 248, 247, 17, 27, 249, 229, 255, 19, 37, 235, 236, 38, 231, 37, 247, 218, 52, 17, 217, 238, 251, 73, 13, 145, 31, 56, 223, 237, 0, 26, 0, 243, 1, 248, 3, 12, 252, 238, 12, 24, 238, 235, 22, 6, 220, 12, 16, 248, 3, 251, 2, 2, 24, 222, 247, 56, 238, 218, 13, 9, 252, 237, 255, 39, 236, 251, 26, 245, 246, 245, 2, 9, 8, 19, 208, 7, 74, 178, 238, 54, 243, 11, 230, 248, 27, 249, 12, 0, 235, 28, 56, 245, 191, 247, 104, 252, 180, 13, 36, 9, 232, 181, 56, 61, 207, 202, 252, 51, 17, 205, 237, 60, 225, 230, 64, 247, 249, 245, 222, 20, 55, 235, 233, 14, 1, 24, 249, 1, 27, 228, 251, 32, 213, 4, 98, 183, 173, 62, 61, 250, 178, 250, 68, 8, 209, 237, 24, 253, 249, 33, 206, 8, 30, 0, 235, 232, 64, 7, 215, 247, 15, 10, 254, 1, 0, 246, 226, 45, 30, 222, 230, 247, 17, 54, 14, 195, 20, 247, 19, 27, 215, 231, 48, 28, 199, 231, 43, 9, 236, 245, 225, 25, 74, 223, 187, 27, 34, 254, 248, 3, 248, 238, 57, 28, 161, 6, 101, 219, 245, 226, 23, 77, 166, 5, 16, 238, 37, 230, 222, 14, 4, 47, 220, 198, 57, 5, 214, 28, 228, 254, 55, 234, 227, 25, 252, 14, 250, 244, 47, 244, 0, 2, 225, 19, 25, 14, 194, 3, 53, 227, 247, 36, 241, 209, 17, 77, 224, 210, 51, 251, 0, 32, 12, 209, 237, 33, 8, 247, 251, 240, 28, 2, 229, 247, 34, 16, 240, 196, 16, 67, 235, 199, 255, 39, 6, 38, 199, 223, 126, 232, 183, 41, 246, 23, 210, 216, 79, 2, 182, 34, 60, 200, 228, 66, 251, 213, 18, 248, 9, 34, 228, 221, 255, 58, 47, 164, 244, 46, 237, 26, 244, 255, 20, 238, 219, 38, 34, 208, 9, 6, 6, 18, 202, 45, 18, 204, 13, 39, 243, 224, 32, 235, 226, 28, 44, 243, 200, 37, 33, 217, 244, 35, 249, 206, 7, 56, 26, 202, 228, 36, 1, 6, 221, 239, 64, 253, 200, 27, 58, 240, 221, 2, 14, 10, 254, 237, 244, 31, 21, 248, 249, 249, 22, 0, 224, 2, 36, 249, 206, 28, 18, 232, 241, 4, 32, 32, 209, 237, 47, 20, 240, 235, 7, 34, 249, 239, 235, 19, 24, 246, 187, 30, 62, 208, 16, 254, 236, 18, 212, 23, 66, 198, 231, 24, 253, 249, 18, 236, 0, 48, 220, 237, 27, 2, 20, 232, 240, 50, 18, 234, 235, 246, 66, 12, 159, 2, 68, 250, 220, 19, 249, 233, 40, 26, 184, 44, 26, 194, 255, 29, 252, 16, 255, 213, 31, 252, 245, 16, 1, 246, 13, 5, 233, 48, 220, 245, 34, 228, 52, 254, 203, 33, 16, 220, 253, 15, 249, 15, 231, 255, 51, 231, 250, 15, 250, 254, 30, 33, 205, 227, 39, 18, 255, 224, 247, 250, 233, 43, 255, 205, 248, 15, 18, 252, 214, 2, 64, 245, 191, 58, 52, 204, 22, 253, 240, 46, 254, 186, 39, 37, 236, 200, 17, 80, 232, 212, 250, 56, 3, 231, 243, 0, 44, 239, 210, 18, 30, 255, 230, 237, 5, 44, 233, 227, 31, 30, 254, 200, 12, 75, 233, 199, 3, 31, 22, 242, 0, 238, 7, 42, 224, 179, 86, 60, 174, 200, 64, 63, 206, 212, 30, 41, 13, 216, 243, 13, 12, 246, 14, 251, 208, 22, 29, 245, 244, 6, 10, 229, 254, 38, 204, 252, 58, 244, 193, 15, 61, 20, 207, 241, 29, 7, 1, 249, 8, 10, 253, 10, 247, 247, 21, 12, 216, 8, 11, 8, 6, 185, 1, 106, 207, 177, 42, 46, 11, 199, 208, 71, 11, 212, 229, 10, 26, 250, 234, 235, 37, 54, 249, 228, 0, 21, 40, 223, 205, 61, 47, 212, 220, 70, 46, 187, 225, 38, 51, 213, 222, 0, 22, 30, 218, 254, 17, 4, 251, 247, 253, 233, 248, 14, 4, 230, 234, 70, 18, 189, 16, 21, 5, 5, 242, 3, 3, 251, 18, 7, 237, 211, 64, 58, 166, 214, 65, 51, 194, 210, 56, 47, 231, 203, 232, 92, 55, 142, 230, 75, 34, 210, 200, 39, 255, 29, 19, 203, 252, 50, 253, 237, 5, 246, 37, 5, 215, 10, 1, 34, 251, 211, 34, 11, 218, 18, 24, 212, 25, 6, 210, 14, 23, 216, 243, 34, 27, 242, 214, 11, 23, 15, 244, 209, 255, 67, 243, 215, 12, 22, 36, 190, 250, 76, 244, 209, 5, 14, 39, 247, 211, 7, 30, 17, 252, 222, 0, 66, 240, 221, 254, 30, 17, 236, 226, 11, 22, 15, 241, 214, 10, 43, 246, 226, 247, 37, 20, 208, 248, 60, 242, 213, 3, 28, 22, 230, 254, 13, 250, 14, 32, 18, 200, 229, 61, 240, 249, 6, 222, 20, 21, 236, 240, 242, 24, 8, 235, 236, 13, 38, 234, 212, 4, 32, 35, 226, 228, 32, 253, 237, 252, 32, 243, 246, 24, 2, 246, 248, 254, 7, 16, 233, 254, 6, 253, 8, 244, 248, 18, 18, 0, 254, 243, 254, 3, 249, 4, 239, 18, 28, 219, 239, 28, 255, 250, 16, 249, 12, 6, 244, 17, 212, 30, 62, 193, 225, 73, 27, 188, 236, 67, 21, 214, 218, 34, 25, 242, 247, 240, 255, 38, 16, 227, 232, 252, 32, 34, 222, 233, 26, 31, 230, 227, 53, 27, 219, 218, 254, 18, 7, 8, 6, 6, 228, 4, 34, 223, 5, 29, 253, 241, 242, 9, 6, 252, 231, 8, 17, 0, 3, 214, 251, 31, 254, 10, 248, 253, 18, 245, 248, 249, 32, 39, 224, 244, 9, 4, 3, 249, 254, 8, 24, 220, 6, 26, 250, 228, 245, 35, 12, 252, 225, 0, 19, 13, 251, 230, 41, 240, 228, 23, 255, 241, 247, 5, 247, 235, 30, 15, 191, 17, 61, 228, 216, 28, 51, 226, 238, 27, 255, 21, 11, 220, 3, 45, 249, 242, 241, 231, 52, 250, 237, 8, 214, 37, 61, 192, 220, 38, 35, 23, 191, 240, 57, 245, 249, 3, 229, 17, 37, 227, 237, 12, 238, 12, 239, 231, 31, 21, 238, 239, 5, 36, 239, 217, 59, 17, 226, 254, 228, 16, 39, 1, 237, 253, 30, 7, 215, 239, 39, 14, 231, 236, 47, 236, 210, 56, 249, 235, 13, 0, 19, 255, 210, 30, 33, 202, 246, 41, 14, 240, 245, 0, 249, 248, 10, 15, 12, 227, 236, 23, 33, 251, 246, 14, 248, 9, 18, 249, 240, 228, 14, 51, 4, 195, 251, 70, 227, 242, 15, 2, 2, 232, 33, 8, 212, 26, 13, 217, 30, 10, 252, 13, 255, 249, 215, 35, 54, 212, 216, 19, 22, 248, 250, 214, 0, 77, 244, 191, 235, 77, 2, 202, 240, 37, 63, 221, 200, 14, 58, 13, 217, 249, 17, 9, 0, 244, 242, 11, 24, 240, 217, 41, 24, 197, 250, 18, 8, 243, 237, 23, 249, 10, 18, 232, 231, 45, 16, 216, 246, 6, 50, 218, 203, 56, 47, 226, 228, 6, 31, 15, 210, 248, 49, 17, 226, 223, 20, 55, 243, 214, 12, 36, 14, 240, 238, 19, 235, 255, 43, 247, 213, 5, 40, 250, 204, 0, 38, 4, 241, 250, 227, 26, 16, 232, 2, 0, 33, 231, 229, 34, 255, 244, 8, 255, 254, 15, 13, 231, 17, 23, 231, 5, 30, 246, 240, 251, 10, 37, 206, 230, 79, 232, 210, 17, 0, 12, 248, 242, 17, 226, 33, 28, 212, 252, 14, 3, 247, 9, 2, 228, 9, 9, 15, 251, 244, 12, 17, 0, 228, 4, 24, 251, 15, 17, 230, 247, 8, 34, 9, 215, 18, 25, 223, 14, 13, 234, 17, 3, 215, 15, 27, 217, 234, 16, 42, 215, 227, 34, 8, 3, 252, 225, 253, 49, 16, 233, 245, 23, 12, 235, 7, 8, 236, 35, 8, 204, 7, 44, 9, 218, 245, 50, 247, 195, 28, 35, 211, 0, 1, 17, 1, 248, 13, 235, 243, 7, 20, 252, 232, 0, 3, 255, 9, 241, 0, 7, 250, 6, 8, 241, 6, 5, 228, 31, 20, 247, 240, 252, 10, 253, 11, 16, 0, 2, 13, 252, 229, 21, 18, 253, 249, 209, 52, 55, 194, 224, 25, 26, 12, 216, 243, 35, 6, 221, 235, 33, 11, 243, 237, 245, 42, 8, 225, 255, 250, 1, 42, 250, 193, 24, 50, 240, 244, 242, 36, 34, 203, 239, 48, 6, 224, 251, 8, 251, 19, 7, 221, 247, 47, 6, 228, 242, 26, 0, 242, 38, 215, 239, 47, 12, 237, 235, 15, 16, 249, 225, 13, 18, 242, 253, 235, 9, 48, 224, 213, 34, 18, 234, 248, 18, 254, 231, 4, 36, 0, 237, 4, 10, 17, 3, 238, 13, 8, 253, 16, 242, 249, 33, 0, 228, 248, 41, 9, 216, 249, 18, 8, 247, 2, 17, 238, 237, 29, 19, 226, 244, 252, 19, 4, 252, 250, 5, 19, 244, 245, 1, 0, 0, 0, 86, 10, 51, 0, 1, 2, 2, 1, 1, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 251, 236, 235, 251, 4, 3, 254, 252, 2, 6, 3, 254, 253, 255, 4, 3, 1, 1, 1, 5, 249, 231, 249, 9, 11, 6, 0, 4, 11, 15, 1, 254, 255, 2, 7, 3, 2, 0, 5, 4, 2, 1, 2, 4, 1, 1, 0, 0, 1, 0, 254, 0, 0, 0, 0, 255, 0, 0, 254, 255, 253, 0, 255, 253, 0, 254, 0, 255, 0, 0, 0, 0, 0, 2, 0, 1, 0, 250, 245, 244, 249, 248, 251, 249, 249, 1, 0, 3, 4, 2, 6, 1, 3, 3, 0, 3, 6, 5, 5, 7, 8, 9, 8, 6, 3, 6, 9, 255, 6, 1, 3, 0, 5, 0, 255, 255, 0, 2, 248, 0, 252, 255, 0, 249, 253, 254, 255, 255, 254, 250, 254, 2, 1, 250, 253, 255, 255, 5, 252, 253, 3, 249, 1, 9, 252, 253, 6, 255, 4, 3, 253, 7, 251, 3, 8, 251, 1, 255, 7, 251, 250, 10, 252, 255, 3, 0, 2, 1, 2, 0, 0, 3, 254, 1, 3, 248, 7, 3, 5, 9, 8, 9, 1, 255, 252, 254, 0, 5, 253, 252, 254, 254, 1, 254, 249, 253, 254, 252, 253, 249, 253, 253, 255, 3, 251, 5, 8, 4, 5, 0, 249, 0, 0, 0, 3, 7, 18, 16, 11, 13, 10, 252, 1, 255, 249, 2, 247, 0, 0, 250, 2, 244, 253, 250, 242, 254, 249, 244, 252, 249, 251, 4, 8, 15, 3, 255, 245, 242, 5, 5, 0, 255, 6, 16, 23, 25, 21, 13, 11, 246, 225, 232, 0, 4, 255, 0, 255, 12, 13, 252, 250, 0, 251, 250, 1, 248, 252, 5, 0, 1, 0, 0, 11, 0, 254, 254, 7, 10, 255, 255, 6, 2, 5, 11, 244, 250, 240, 243, 0, 0, 2, 255, 254, 247, 4, 5, 254, 248, 251, 0, 0, 7, 255, 2, 0, 14, 10, 255, 1, 2, 12, 9, 0, 4, 254, 1, 7, 251, 5, 7, 0, 2, 253, 2, 2, 243, 0, 6, 243, 245, 9, 0, 251, 249, 255, 16, 240, 0, 10, 245, 12, 254, 245, 6, 4, 250, 2, 2, 246, 8, 1, 251, 10, 250, 2, 12, 247, 252, 3, 12, 253, 0, 251, 11, 10, 238, 9, 1, 0, 21, 238, 254, 15, 251, 3, 8, 245, 1, 8, 248, 3, 4, 242, 2, 0, 248, 0, 253, 12, 247, 250, 10, 245, 9, 4, 241, 255, 17, 3, 245, 0, 4, 15, 250, 1, 9, 253, 6, 1, 0, 6, 247, 3, 7, 253, 0, 253, 10, 244, 5, 255, 243, 3, 252, 0, 254, 4, 1, 243, 4, 254, 12, 253, 245, 10, 5, 5, 3, 252, 7, 3, 2, 4, 0, 0, 4, 8, 251, 4, 2, 0, 249, 0, 8, 245, 0, 249, 254, 11, 241, 0, 251, 248, 16, 3, 244, 3, 1, 10, 1, 240, 14, 5, 1, 12, 240, 254, 13, 253, 1, 21, 241, 246, 15, 3, 1, 252, 249, 8, 3, 245, 254, 252, 252, 7, 250, 251, 253, 250, 0, 9, 7, 0, 3, 24, 250, 10, 13, 240, 27, 8, 240, 1, 6, 1, 7, 249, 242, 5, 254, 12, 247, 236, 7, 247, 255, 8, 231, 2, 252, 246, 2, 240, 12, 12, 234, 3, 9, 2, 11, 241, 0, 23, 6, 3, 12, 6, 248, 16, 14, 246, 4, 12, 254, 0, 0, 1, 9, 244, 247, 1, 2, 251, 251, 255, 2, 255, 237, 10, 14, 236, 18, 9, 233, 16, 4, 229, 1, 247, 255, 14, 224, 10, 11, 241, 13, 251, 3, 15, 6, 9, 3, 11, 24, 252, 251, 2, 254, 14, 6, 245, 253, 22, 238, 232, 34, 233, 255, 14, 223, 8, 5, 242, 245, 255, 10, 251, 249, 20, 19, 0, 14, 6, 14, 17, 243, 1, 3, 234, 6, 248, 247, 29, 255, 234, 246, 236, 10, 0, 248, 225, 252, 0, 11, 253, 235, 1, 1, 250, 8, 12, 247, 8, 4, 18, 10, 252, 21, 2, 17, 4, 10, 25, 244, 25, 4, 246, 17, 247, 11, 17, 13, 248, 253, 13, 254, 11, 234, 228, 253, 209, 231, 15, 236, 244, 1, 230, 18, 253, 253, 0, 248, 252, 245, 14, 13, 249, 8, 5, 253, 44, 251, 9, 19, 234, 24, 18, 246, 0, 0, 17, 5, 0, 1, 0, 17, 251, 239, 255, 12, 250, 249, 243, 10, 9, 229, 5, 0, 240, 4, 1, 249, 251, 2, 10, 251, 255, 0, 248, 14, 3, 243, 251, 12, 4, 235, 22, 9, 251, 0, 4, 12, 252, 242, 15, 1, 253, 19, 232, 4, 15, 2, 251, 245, 10, 11, 246, 249, 7, 1, 4, 1, 253, 2, 245, 12, 1, 252, 249, 247, 14, 8, 246, 1, 1, 11, 243, 252, 20, 240, 7, 7, 248, 2, 249, 19, 14, 226, 250, 20, 11, 248, 245, 0, 0, 11, 254, 244, 8, 249, 240, 17, 11, 239, 249, 0, 29, 236, 4, 5, 255, 20, 233, 1, 12, 3, 1, 252, 16, 254, 246, 17, 1, 11, 248, 254, 21, 238, 246, 15, 0, 2, 237, 250, 8, 0, 250, 255, 4, 235, 20, 2, 240, 5, 246, 7, 19, 246, 231, 25, 14, 254, 234, 249, 27, 4, 0, 18, 228, 249, 35, 2, 237, 8, 3, 247, 14, 9, 253, 228, 13, 16, 246, 5, 241, 3, 11, 235, 19, 0, 234, 29, 242, 1, 8, 245, 24, 244, 239, 25, 255, 255, 254, 251, 9, 250, 250, 12, 19, 218, 13, 9, 237, 33, 247, 226, 25, 248, 4, 4, 244, 11, 240, 19, 15, 230, 7, 0, 7, 253, 250, 3, 254, 23, 249, 222, 39, 9, 231, 30, 243, 252, 29, 222, 252, 14, 254, 9, 239, 2, 16, 244, 252, 15, 233, 247, 39, 241, 240, 19, 240, 12, 252, 2, 15, 237, 249, 0, 26, 255, 250, 255, 243, 28, 13, 244, 249, 239, 20, 24, 243, 238, 255, 1, 14, 30, 230, 246, 13, 0, 19, 238, 249, 12, 250, 248, 12, 251, 248, 20, 19, 254, 253, 24, 22, 251, 0, 11, 7, 1, 0, 6, 250, 0, 33, 3, 236, 253, 16, 16, 252, 249, 3, 7, 21, 8, 242, 14, 25, 239, 14, 13, 232, 5, 17, 20, 8, 241, 245, 28, 8, 246, 17, 5, 3, 5, 246, 252, 14, 20, 10, 221, 16, 57, 238, 239, 3, 12, 26, 240, 253, 1, 248, 31, 4, 229, 25, 17, 249, 252, 21, 22, 241, 253, 18, 3, 255, 0, 251, 27, 6, 217, 19, 7, 244, 22, 245, 247, 12, 8, 254, 19, 6, 246, 10, 11, 8, 0, 234, 4, 27, 2, 254, 244, 13, 48, 1, 233, 3, 25, 5, 249, 1, 35, 6, 1, 7, 237, 24, 39, 249, 231, 22, 27, 242, 247, 17, 7, 11, 31, 234, 251, 22, 9, 20, 244, 250, 32, 247, 5, 21, 0, 21, 247, 246, 25, 5, 2, 25, 11, 243, 20, 13, 246, 23, 253, 6, 29, 253, 4, 17, 1, 10, 253, 250, 19, 5, 255, 0, 250, 21, 35, 233, 243, 32, 37, 254, 235, 13, 19, 0, 0, 255, 19, 255, 247, 22, 4, 250, 13, 249, 245, 31, 2, 250, 2, 254, 0, 38, 29, 231, 248, 32, 13, 241, 6, 6, 238, 20, 229, 227, 58, 16, 212, 253, 27, 12, 230, 253, 34, 20, 1, 240, 246, 7, 26, 9, 244, 252, 253, 249, 6, 4, 10, 0, 13, 15, 5, 254, 248, 30, 48, 225, 220, 42, 13, 252, 237, 215, 31, 68, 245, 218, 13, 55, 23, 197, 244, 52, 41, 253, 232, 2, 28, 17, 242, 0, 17, 255, 0, 245, 10, 43, 245, 220, 21, 59, 237, 223, 31, 38, 4, 244, 232, 19, 33, 2, 248, 243, 28, 20, 253, 252, 242, 37, 19, 214, 13, 24, 0, 12, 7, 239, 14, 27, 229, 250, 24, 7, 1, 241, 255, 33, 5, 233, 247, 40, 36, 245, 236, 2, 36, 17, 240, 251, 251, 14, 30, 240, 228, 21, 15, 8, 8, 228, 5, 43, 248, 253, 22, 19, 249, 238, 7, 28, 18, 222, 252, 21, 15, 4, 241, 238, 22, 19, 244, 248, 11, 3, 238, 43, 29, 236, 0, 17, 43, 7, 227, 18, 16, 6, 21, 227, 231, 31, 25, 244, 245, 244, 24, 21, 235, 0, 29, 2, 3, 18, 236, 252, 40, 0, 241, 9, 255, 31, 11, 214, 6, 27, 4, 248, 243, 246, 39, 9, 229, 8, 21, 9, 14, 244, 232, 30, 32, 248, 239, 3, 13, 239, 11, 16, 233, 11, 35, 250, 244, 24, 18, 235, 8, 30, 10, 241, 250, 32, 1, 255, 20, 244, 249, 28, 19, 247, 0, 10, 3, 18, 22, 218, 7, 42, 249, 5, 13, 244, 0, 247, 5, 31, 255, 251, 3, 5, 4, 10, 0, 3, 31, 242, 241, 13, 28, 6, 236, 21, 45, 250, 235, 12, 21, 15, 246, 6, 24, 251, 244, 254, 23, 13, 226, 254, 41, 239, 0, 26, 235, 7, 29, 255, 233, 229, 49, 22, 218, 10, 10, 2, 25, 254, 228, 14, 25, 243, 250, 6, 1, 9, 251, 250, 32, 255, 247, 31, 245, 242, 20, 10, 246, 30, 27, 222, 236, 46, 24, 209, 4, 30, 249, 0, 15, 236, 244, 36, 29, 240, 254, 35, 3, 241, 10, 9, 0, 222, 8, 41, 251, 211, 7, 43, 249, 252, 240, 245, 46, 6, 247, 5, 250, 43, 250, 213, 41, 28, 233, 6, 12, 38, 4, 211, 22, 51, 245, 233, 248, 29, 41, 249, 228, 0, 59, 36, 217, 239, 31, 20, 27, 222, 215, 62, 2, 211, 250, 37, 21, 243, 238, 2, 26, 5, 3, 0, 254, 3, 255, 5, 251, 15, 243, 254, 34, 13, 246, 255, 19, 24, 249, 230, 3, 35, 14, 244, 254, 8, 34, 13, 9, 251, 218, 18, 64, 222, 195, 14, 26, 24, 232, 235, 14, 11, 8, 236, 234, 56, 20, 204, 21, 36, 249, 8, 249, 249, 25, 237, 255, 18, 240, 14, 12, 230, 31, 41, 252, 227, 13, 29, 250, 229, 12, 37, 1, 235, 18, 245, 235, 67, 9, 227, 5, 11, 243, 9, 15, 246, 9, 21, 10, 248, 252, 251, 41, 37, 241, 248, 254, 11, 37, 18, 239, 5, 15, 20, 10, 250, 10, 6, 250, 27, 2, 237, 22, 0, 0, 26, 243, 1, 33, 231, 9, 46, 235, 245, 9, 30, 30, 186, 244, 60, 27, 7, 219, 251, 54, 24, 255, 232, 20, 58, 246, 195, 11, 40, 18, 2, 200, 0, 60, 42, 225, 219, 32, 32, 4, 232, 254, 5, 13, 37, 225, 247, 42, 255, 227, 19, 10, 230, 5, 26, 236, 255, 19, 8, 10, 21, 242, 238, 36, 3, 9, 1, 243, 53, 29, 200, 245, 43, 246, 25, 1, 188, 17, 48, 233, 0, 7, 240, 28, 12, 233, 10, 17, 0, 250, 17, 31, 237, 219, 30, 38, 12, 249, 237, 0, 38, 249, 9, 12, 224, 60, 17, 164, 60, 69, 186, 246, 2, 12, 106, 244, 132, 46, 76, 41, 222, 179, 29, 40, 30, 238, 186, 37, 78, 238, 227, 0, 40, 33, 7, 250, 249, 21, 27, 237, 8, 47, 202, 26, 57, 239, 25, 236, 237, 60, 21, 231, 223, 21, 81, 219, 184, 42, 30, 0, 25, 255, 224, 15, 38, 250, 232, 250, 0, 32, 7, 228, 22, 9, 244, 2, 23, 255, 230, 20, 17, 255, 249, 243, 37, 42, 244, 226, 0, 25, 5, 245, 12, 12, 242, 15, 41, 228, 203, 64, 67, 199, 241, 34, 10, 22, 238, 231, 33, 13, 250, 243, 235, 40, 21, 193, 10, 46, 244, 242, 253, 24, 40, 251, 232, 244, 35, 50, 223, 212, 37, 47, 229, 232, 14, 252, 39, 22, 231, 0, 48, 2, 226, 27, 35, 233, 2, 24, 12, 1, 209, 37, 53, 221, 246, 27, 10, 27, 253, 252, 15, 250, 2, 6, 5, 50, 247, 212, 26, 37, 1, 239, 244, 44, 30, 236, 7, 247, 30, 34, 228, 242, 4, 45, 0, 197, 22, 59, 255, 233, 254, 1, 23, 24, 240, 237, 47, 20, 242, 236, 32, 21, 237, 35, 4, 209, 13, 62, 3, 229, 15, 253, 10, 20, 235, 2, 39, 224, 255, 38, 243, 8, 244, 227, 73, 17, 203, 11, 38, 243, 6, 2, 255, 35, 246, 10, 246, 242, 61, 235, 206, 61, 254, 232, 39, 248, 246, 42, 13, 226, 253, 37, 13, 5, 9, 237, 24, 47, 227, 237, 51, 19, 232, 18, 7, 238, 27, 17, 235, 8, 14, 228, 21, 11, 236, 37, 2, 243, 12, 9, 8, 27, 0, 231, 3, 22, 253, 229, 38, 1, 221, 31, 13, 251, 8, 248, 17, 255, 250, 32, 5, 14, 30, 232, 246, 50, 0, 241, 23, 230, 28, 24, 208, 32, 55, 217, 214, 74, 45, 182, 1, 59, 19, 246, 233, 25, 4, 6, 7, 214, 40, 29, 241, 252, 0, 16, 21, 16, 218, 14, 61, 242, 245, 7, 0, 43, 12, 235, 10, 3, 6, 30, 240, 245, 49, 243, 219, 16, 66, 11, 175, 2, 101, 238, 236, 10, 212, 50, 100, 166, 173, 111, 43, 204, 232, 10, 50, 1, 225, 11, 20, 4, 254, 243, 8, 35, 235, 220, 17, 22, 241, 242, 34, 6, 243, 6, 248, 243, 44, 0, 230, 6, 15, 238, 0, 9, 0, 35, 235, 234, 51, 249, 218, 23, 11, 7, 250, 223, 24, 33, 7, 228, 230, 58, 27, 201, 15, 25, 248, 31, 27, 218, 212, 78, 56, 189, 200, 68, 66, 221, 212, 253, 34, 62, 218, 221, 32, 13, 6, 7, 7, 8, 14, 251, 6, 23, 30, 210, 250, 62, 19, 230, 227, 29, 29, 252, 245, 60, 246, 173, 65, 92, 206, 232, 54, 17, 230, 36, 27, 194, 14, 52, 208, 250, 50, 244, 197, 38, 59, 212, 253, 12, 7, 5, 249, 239, 28, 10, 0, 227, 0, 70, 241, 226, 27, 21, 12, 225, 241, 27, 18, 3, 226, 7, 33, 223, 1, 34, 11, 7, 224, 14, 56, 248, 220, 33, 10, 247, 247, 247, 42, 228, 208, 44, 51, 239, 237, 245, 22, 56, 202, 245, 54, 241, 1, 2, 245, 43, 251, 220, 18, 29, 246, 232, 33, 31, 236, 233, 6, 57, 5, 221, 250, 0, 32, 22, 200, 35, 54, 217, 10, 2, 233, 60, 35, 211, 0, 27, 26, 253, 228, 0, 35, 36, 254, 208, 4, 81, 223, 228, 58, 252, 236, 29, 231, 16, 50, 212, 245, 17, 33, 30, 191, 245, 72, 20, 237, 240, 243, 43, 27, 252, 3, 252, 249, 18, 48, 250, 247, 32, 252, 232, 42, 11, 210, 39, 53, 250, 196, 8, 57, 250, 243, 34, 242, 254, 45, 230, 242, 3, 30, 28, 239, 232, 248, 41, 15, 235, 31, 233, 233, 48, 3, 234, 2, 13, 20, 14, 254, 10, 235, 247, 40, 246, 28, 241, 224, 41, 18, 254, 224, 6, 39, 17, 244, 222, 0, 47, 12, 223, 11, 33, 246, 255, 0, 243, 30, 32, 235, 219, 35, 12, 241, 38, 253, 224, 30, 34, 237, 223, 25, 30, 252, 2, 247, 27, 252, 240, 45, 247, 237, 7, 17, 16, 250, 222, 17, 69, 230, 224, 37, 7, 53, 247, 198, 56, 34, 215, 25, 10, 238, 42, 11, 238, 22, 239, 31, 29, 223, 12, 1, 17, 6, 240, 39, 225, 238, 76, 244, 216, 6, 33, 32, 239, 241, 46, 227, 20, 52, 174, 4, 61, 246, 12, 249, 1, 56, 233, 234, 38, 239, 12, 56, 221, 215, 33, 17, 252, 7, 2, 9, 0, 0, 90, 0, 3, 0, 5, 0, 136, 0, 200, 0, 64, 6, 40, 10, 232, 13, 24, 16, 124, 21, 55, 14, 13, 25, 10, 7, 3, 3, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 50, 85, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 160, 0, 240, 0, 160, 5, 40, 10, 199, 14, 36, 19, 0, 25, 35, 13, 15, 25, 13, 9, 7, 3, 7, 7, 135, 142, 160, 160, 150, 175, 135, 142, 160, 44, 35, 30, 90, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 9, 0, 160, 0, 240, 0, 160, 5, 40, 10, 199, 14, 36, 19, 0, 25, 0, 13, 15, 25, 13, 9, 7, 3, 7, 7, 135, 142, 160, 160, 150, 175, 135, 142, 160, 44, 35, 30, 90, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 55, 1, 12, 0, 3, 4, 5, 1, 8, 248, 0, 178, 140, 255, 16, 1, 251, 245, 245, 245, 239, 226, 221, 249, 31, 37, 28, 33, 28, 31, 38, 43, 44, 49, 55, 52, 43, 43, 39, 41, 30, 29, 23, 25, 23, 21, 10, 6, 10, 3, 3, 0, 2, 3, 11, 11, 7, 240, 202, 209, 221, 230, 252, 13, 19, 14, 250, 9, 219, 164, 223, 255, 242, 234, 247, 246, 247, 250, 247, 255, 214, 197, 207, 206, 226, 238, 6, 14, 25, 40, 51, 58, 37, 11, 3, 7, 8, 2, 224, 231, 31, 56, 68, 76, 86, 82, 81, 65, 53, 57, 65, 34, 19, 51, 54, 62, 60, 41, 36, 22, 12, 248, 239, 235, 250, 250, 254, 11, 15, 28, 41, 48, 45, 37, 39, 24, 12, 253, 0, 29, 44, 54, 62, 65, 67, 59, 50, 40, 41, 41, 30, 35, 46, 55, 69, 78, 73, 68, 65, 56, 46, 42, 30, 22, 18, 18, 27, 254, 233, 4, 26, 27, 7, 0, 240, 233, 223, 213, 217, 235, 249, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 253, 4, 19, 0, 13, 13, 5, 6, 19, 14, 14, 11, 10, 6, 249, 248, 0, 254, 11, 6, 6, 4, 3, 211, 167, 140, 139, 164, 184, 212, 239, 17, 19, 2, 249, 9, 15, 12, 13, 20, 26, 27, 27, 23, 9, 1, 246, 243, 2, 22, 44, 52, 55, 53, 50, 50, 51, 58, 57, 53, 50, 45, 24, 10, 0, 246, 1, 4, 7, 255, 213, 209, 197, 175, 173, 188, 217, 225, 220, 239, 239, 223, 222, 229, 234, 245, 247, 251, 0, 0, 3, 3, 4, 5, 1, 0, 0, 1, 7, 9, 7, 11, 16, 18, 17, 22, 26, 26, 29, 24, 21, 21, 20, 23, 12, 15, 14, 11, 10, 4, 253, 248, 232, 227, 239, 239, 239, 249, 0, 8, 1, 1, 6, 2, 249, 251, 223, 235, 1, 254, 241, 235, 245, 255, 249, 241, 247, 0, 2, 0, 250, 3, 13, 9, 13, 19, 24, 25, 23, 17, 21, 22, 16, 10, 7, 7, 12, 5, 3, 2, 4, 8, 4, 1, 0, 255, 255, 254, 248, 244, 245, 250, 245, 244, 244, 232, 227, 232, 237, 236, 237, 238, 242, 246, 250, 253, 253, 0, 9, 13, 17, 17, 13, 16, 18, 21, 20, 14, 9, 11, 12, 10, 13, 12, 11, 9, 4, 254, 0, 253, 252, 249, 233, 231, 235, 229, 240, 2, 2, 254, 247, 245, 244, 241, 242, 247, 0, 7, 11, 13, 19, 22, 19, 14, 11, 11, 7, 2, 1, 5, 10, 18, 19, 16, 20, 12, 0, 247, 246, 247, 247, 249, 249, 251, 251, 244, 248, 250, 247, 245, 236, 231, 232, 232, 235, 245, 254, 2, 4, 5, 9, 5, 254, 0, 4, 12, 10, 9, 12, 19, 27, 32, 27, 24, 19, 16, 7, 5, 6, 2, 254, 255, 254, 248, 245, 235, 228, 230, 234, 237, 233, 234, 233, 236, 241, 252, 9, 9, 4, 0, 251, 242, 249, 15, 22, 17, 16, 18, 14, 17, 23, 26, 17, 6, 255, 255, 247, 244, 241, 244, 247, 255, 255, 249, 246, 255, 1, 6, 9, 7, 10, 10, 14, 14, 12, 9, 0, 0, 8, 22, 37, 39, 19, 255, 242, 237, 236, 245, 252, 252, 244, 238, 240, 244, 248, 250, 250, 246, 1, 18, 24, 4, 3, 29, 33, 11, 11, 15, 10, 251, 241, 1, 12, 255, 230, 210, 207, 225, 225, 221, 213, 210, 225, 243, 240, 245, 249, 7, 15, 20, 44, 38, 25, 26, 28, 12, 0, 14, 15, 248, 0, 24, 17, 12, 0, 242, 227, 227, 11, 7, 214, 233, 255, 248, 251, 2, 27, 16, 2, 17, 17, 3, 21, 5, 233, 223, 2, 24, 242, 220, 244, 252, 243, 4, 18, 1, 231, 250, 2, 234, 248, 11, 13, 0, 18, 66, 55, 33, 40, 31, 2, 224, 231, 0, 2, 6, 7, 250, 247, 6, 238, 211, 208, 247, 15, 249, 231, 234, 245, 15, 25, 6, 245, 237, 239, 243, 9, 34, 61, 66, 37, 5, 0, 12, 2, 224, 222, 22, 38, 22, 22, 23, 16, 16, 13, 7, 2, 22, 41, 28, 7, 253, 238, 4, 58, 77, 60, 15, 224, 207, 213, 254, 6, 222, 218, 240, 241, 220, 214, 228, 220, 225, 248, 18, 39, 5, 214, 185, 214, 0, 32, 12, 243, 216, 221, 242, 246, 231, 243, 247, 235, 199, 185, 210, 211, 205, 222, 245, 251, 239, 245, 240, 223, 242, 0, 253, 13, 47, 63, 47, 40, 36, 19, 14, 30, 7, 223, 225, 238, 238, 216, 221, 251, 10, 2, 246, 239, 12, 9, 11, 19, 55, 105, 106, 97, 71, 39, 22, 26, 25, 33, 41, 73, 69, 27, 238, 239, 244, 9, 42, 31, 11, 6, 23, 11, 39, 79, 44, 244, 6, 57, 80, 32, 253, 242, 8, 18, 6, 237, 203, 251, 41, 6, 230, 251, 229, 191, 202, 228, 248, 0, 7, 248, 219, 245, 245, 221, 200, 222, 243, 212, 191, 206, 5, 20, 244, 186, 163, 176, 186, 229, 244, 219, 230, 249, 251, 221, 211, 195, 210, 230, 248, 6, 224, 221, 231, 1, 12, 5, 244, 226, 237, 6, 4, 250, 2, 9, 241, 244, 29, 50, 23, 0, 16, 14, 1, 1, 16, 14, 13, 25, 32, 6, 236, 254, 10, 251, 242, 5, 13, 0, 31, 77, 72, 22, 2, 16, 16, 19, 29, 28, 26, 57, 59, 22, 242, 236, 245, 248, 5, 28, 53, 72, 70, 40, 5, 245, 248, 5, 21, 34, 25, 0, 2, 15, 11, 253, 242, 238, 245, 15, 28, 16, 244, 239, 243, 8, 24, 1, 223, 214, 243, 34, 33, 240, 187, 212, 14, 64, 57, 19, 0, 226, 218, 189, 198, 239, 26, 44, 12, 231, 216, 223, 200, 166, 189, 231, 249, 243, 22, 46, 254, 236, 221, 226, 240, 34, 27, 244, 6, 64, 87, 39, 49, 70, 16, 229, 244, 9, 5, 18, 56, 59, 33, 29, 0, 195, 209, 231, 230, 220, 243, 14, 242, 241, 13, 20, 0, 6, 12, 0, 255, 252, 17, 3, 21, 5, 233, 223, 2, 24, 242, 220, 244, 252, 243, 4, 18, 1, 231, 250, 2, 234, 248, 11, 13, 0, 18, 66, 55, 33, 40, 31, 2, 224, 231, 0, 2, 6, 7, 250, 247, 6, 238, 211, 208, 247, 15, 249, 231, 234, 245, 15, 25, 6, 245, 237, 239, 243, 9, 34, 61, 66, 37, 5, 0, 12, 2, 224, 222, 22, 38, 22, 22, 23, 16, 16, 13, 7, 2, 22, 41, 28, 7, 253, 238, 4, 58, 77, 60, 15, 224, 207, 213, 254, 6, 222, 218, 240, 241, 220, 214, 228, 220, 225, 248, 18, 39, 5, 214, 185, 214, 0, 32, 12, 243, 216, 221, 242, 246, 231, 243, 247, 235, 199, 185, 210, 211, 205, 222, 245, 251, 239, 245, 240, 223, 242, 0, 253, 13, 47, 63, 47, 40, 36, 19, 14, 30, 7, 223, 225, 238, 238, 216, 221, 251, 10, 2, 246, 239, 12, 9, 11, 19, 55, 105, 106, 97, 71, 39, 22, 26, 25, 33, 41, 73, 69, 27, 238, 239, 244, 9, 42, 31, 11, 6, 23, 11, 39, 79, 44, 244, 6, 57, 80, 32, 253, 242, 8, 18, 6, 237, 203, 251, 41, 6, 230, 251, 229, 191, 202, 228, 248, 0, 7, 248, 219, 245, 245, 221, 200, 222, 243, 212, 191, 206, 5, 20, 244, 186, 163, 176, 186, 229, 244, 219, 230, 249, 251, 221, 211, 195, 210, 230, 248, 6, 224, 221, 231, 1, 12, 5, 244, 226, 237, 6, 4, 250, 2, 9, 241, 244, 29, 50, 23, 0, 16, 14, 1, 1, 16, 14, 13, 25, 32, 6, 236, 254, 10, 251, 242, 5, 13, 0, 31, 77, 72, 22, 2, 16, 16, 19, 29, 28, 26, 57, 59, 22, 242, 236, 245, 248, 5, 28, 53, 72, 70, 40, 5, 245, 248, 5, 21, 34, 25, 0, 2, 15, 11, 253, 242, 238, 245, 15, 28, 16, 244, 239, 243, 8, 24, 1, 223, 214, 243, 34, 33, 240, 187, 212, 14, 64, 57, 19, 0, 226, 218, 189, 198, 239, 26, 44, 12, 231, 216, 223, 200, 166, 189, 231, 249, 243, 22, 46, 254, 236, 221, 226, 240, 34, 27, 244, 6, 64, 87, 39, 49, 70, 16, 229, 244, 9, 5, 18, 56, 59, 33, 29, 0, 195, 209, 231, 230, 220, 243, 14, 242, 241, 13, 20, 0, 6, 12, 0, 255, 252, 4, 0, 18, 36, 31, 26, 252, 221, 182, 181, 209, 192, 210, 237, 23, 17, 235, 180, 131, 157, 210, 229, 216, 219, 230, 227, 248, 16, 41, 20, 250, 17, 33, 38, 22, 0, 0, 0, 63, 2, 30, 0, 3, 7, 4, 5, 7, 0, 3, 254, 217, 209, 5, 49, 40, 4, 238, 252, 21, 22, 6, 0, 8, 16, 13, 3, 2, 8, 10, 8, 7, 6, 6, 9, 13, 12, 9, 7, 8, 6, 5, 8, 8, 8, 7, 4, 5, 6, 6, 6, 3, 3, 6, 3, 4, 4, 253, 5, 8, 233, 222, 2, 38, 35, 246, 219, 4, 48, 53, 25, 216, 200, 12, 40, 10, 5, 20, 38, 40, 1, 237, 8, 31, 36, 26, 6, 7, 19, 8, 232, 212, 223, 249, 11, 10, 0, 9, 23, 10, 12, 19, 252, 246, 2, 0, 9, 10, 253, 10, 11, 246, 1, 16, 24, 33, 1, 240, 12, 10, 3, 13, 242, 235, 14, 13, 2, 11, 254, 244, 13, 29, 23, 6, 245, 0, 30, 25, 2, 253, 248, 246, 6, 8, 252, 2, 10, 9, 12, 1, 249, 13, 28, 23, 17, 3, 1, 20, 23, 16, 19, 15, 16, 22, 8, 3, 16, 243, 209, 245, 29, 21, 12, 8, 6, 13, 0, 253, 23, 15, 0, 15, 5, 253, 15, 8, 0, 4, 247, 0, 12, 252, 1, 14, 7, 9, 0, 249, 13, 13, 4, 3, 246, 255, 16, 7, 4, 2, 2, 17, 254, 247, 22, 6, 245, 9, 0, 0, 15, 253, 8, 24, 250, 254, 21, 15, 10, 246, 249, 35, 11, 233, 15, 22, 4, 26, 13, 242, 5, 19, 3, 253, 0, 4, 14, 19, 5, 255, 8, 3, 0, 7, 247, 0, 31, 248, 227, 24, 15, 236, 22, 27, 225, 243, 40, 14, 227, 252, 32, 14, 242, 244, 9, 17, 252, 249, 18, 11, 1, 2, 233, 0, 44, 254, 232, 21, 9, 4, 23, 240, 241, 20, 3, 9, 15, 253, 18, 2, 232, 25, 16, 240, 22, 2, 243, 41, 9, 229, 18, 7, 252, 30, 7, 235, 240, 0, 23, 0, 236, 13, 0, 240, 12, 251, 243, 22, 255, 238, 16, 12, 7, 35, 16, 240, 6, 27, 8, 10, 31, 23, 5, 253, 1, 21, 24, 13, 3, 248, 14, 35, 14, 9, 241, 229, 48, 33, 220, 19, 12, 231, 48, 10, 220, 51, 0, 208, 58, 22, 200, 255, 31, 39, 11, 221, 13, 29, 1, 20, 245, 253, 47, 246, 241, 27, 243, 1, 19, 0, 37, 247, 209, 44, 32, 239, 18, 7, 15, 30, 234, 255, 36, 7, 249, 236, 9, 44, 249, 244, 18, 7, 19, 249, 246, 42, 239, 230, 46, 6, 14, 35, 216, 11, 39, 226, 31, 14, 205, 53, 35, 205, 15, 21, 248, 16, 10, 19, 252, 243, 36, 248, 13, 66, 183, 216, 118, 4, 212, 27, 228, 16, 64, 235, 242, 248, 228, 20, 11, 23, 30, 195, 249, 72, 250, 248, 0, 221, 33, 39, 247, 20, 252, 236, 26, 20, 21, 13, 232, 3, 28, 26, 8, 208, 248, 58, 0, 220, 222, 237, 65, 33, 183, 4, 96, 26, 192, 224, 99, 91, 197, 210, 61, 30, 234, 250, 7, 254, 244, 252, 20, 41, 5, 222, 36, 65, 228, 231, 25, 3, 25, 24, 252, 32, 238, 192, 42, 54, 222, 225, 14, 43, 3, 219, 27, 26, 228, 19, 21, 254, 22, 231, 220, 26, 18, 8, 19, 28, 31, 224, 248, 59, 227, 243, 53, 202, 21, 126, 193, 181, 65, 22, 40, 30, 177, 253, 47, 240, 5, 240, 247, 51, 216, 210, 53, 241, 227, 47, 255, 243, 0, 191, 4, 21, 0, 219, 229, 3, 19, 255, 1, 253, 238, 240, 255, 11, 255, 208, 218, 22, 67, 15, 200, 201, 255, 40, 29, 223, 234, 62, 56, 20, 217, 220, 255, 20, 18, 38, 11, 209, 222, 6, 56, 28, 232, 29, 32, 24, 239, 191, 255, 32, 13, 241, 204, 241, 19, 237, 210, 230, 232, 233, 49, 50, 234, 189, 201, 35, 55, 228, 191, 206, 254, 35, 236, 225, 8, 23, 0, 211, 236, 24, 61, 33, 232, 235, 17, 63, 26, 247, 2, 245, 32, 17, 49, 10, 236, 30, 48, 36, 1, 243, 5, 19, 25, 244, 241, 10, 34, 16, 2, 246, 239, 28, 26, 0, 253, 1, 242, 239, 246, 3, 10, 0, 242, 215, 0, 30, 10, 5, 249, 239, 227, 237, 239, 6, 238, 15, 47, 10, 247, 232, 7, 4, 239, 251, 24, 8, 251, 218, 206, 17, 11, 210, 214, 255, 21, 19, 27, 8, 254, 251, 17, 246, 253, 13, 10, 0, 8, 248, 248, 0, 244, 244, 0, 40, 27, 249, 235, 1, 23, 239, 222, 242, 12, 37, 255, 216, 237, 25, 28, 0, 254, 5, 254, 244, 236, 2, 37, 11, 233, 0, 0, 253, 6, 244, 255, 28, 24, 218, 233, 238, 234, 0, 3, 1, 14, 13, 5, 248, 7, 244, 237, 2, 35, 11, 239, 242, 18, 25, 4, 249, 251, 23, 27, 236, 236, 4, 5, 2, 246, 235, 253, 243, 240, 249, 254, 2, 18, 47, 14, 246, 252, 14, 29, 6, 222, 239, 15, 32, 30, 10, 226, 237, 3, 26, 31, 232, 247, 2, 231, 12, 19, 10, 0, 220, 241, 31, 7, 18, 1, 243, 243, 10, 30, 2, 228, 221, 255, 4, 252, 233, 4, 16, 242, 15, 249, 5, 17, 1, 25, 33, 243, 230, 226, 0, 26, 7, 212, 241, 247, 243, 33, 25, 2, 0, 14, 26, 244, 227, 247, 5, 228, 228, 3, 30, 23, 17, 208, 180, 236, 38, 32, 240, 230, 254, 11, 5, 254, 237, 225, 8, 35, 60, 229, 212, 21, 28, 35, 17, 248, 212, 208, 0, 39, 29, 227, 204, 215, 3, 45, 35, 4, 6, 7, 14, 1, 4, 253, 251, 17, 42, 46, 236, 247, 0, 2, 14, 14, 6, 0, 245, 208, 249, 14, 17, 14, 233, 239, 20, 250, 245, 4, 9, 28, 233, 5, 62, 23, 233, 199, 247, 48, 24, 239, 207, 13, 27, 245, 237, 239, 237, 247, 20, 20, 241, 242, 14, 8, 251, 214, 203, 5, 77, 5, 229, 233, 239, 36, 58, 10, 7, 12, 237, 244, 16, 25, 2, 251, 1, 24, 3, 224, 252, 27, 21, 250, 228, 242, 44, 57, 30, 226, 170, 8, 58, 28, 209, 249, 7, 4, 21, 241, 202, 0, 7, 251, 207, 252, 1, 233, 7, 5, 17, 36, 253, 232, 219, 3, 55, 65, 224, 209, 243, 0, 251, 2, 25, 15, 11, 218, 217, 17, 15, 13, 9, 0, 229, 228, 7, 6, 254, 241, 6, 42, 246, 187, 213, 245, 36, 27, 3, 233, 213, 245, 11, 19, 254, 0, 12, 244, 243, 17, 21, 252, 246, 19, 18, 26, 254, 229, 235, 35, 68, 21, 230, 216, 252, 33, 32, 18, 242, 247, 13, 21, 8, 250, 8, 20, 247, 247, 18, 21, 230, 238, 42, 16, 7, 249, 0, 9, 0, 9, 24, 23, 234, 10, 40, 15, 0, 233, 0, 25, 0, 228, 7, 13, 253, 24, 24, 221, 199, 244, 20, 228, 205, 1, 48, 26, 208, 219, 7, 13, 237, 255, 27, 27, 223, 185, 197, 27, 0, 229, 230, 216, 240, 37, 42, 247, 225, 200, 36, 70, 23, 248, 1, 42, 229, 204, 3, 18, 29, 11, 226, 246, 17, 15, 12, 20, 22, 21, 0, 205, 224, 253, 43, 63, 32, 209, 201, 235, 0, 38, 13, 255, 189, 221, 25, 20, 255, 238, 235, 255, 27, 20, 238, 234, 6, 248, 12, 19, 239, 242, 33, 30, 15, 230, 246, 15, 22, 26, 16, 12, 0, 252, 11, 31, 20, 244, 247, 40, 45, 6, 221, 225, 40, 29, 240, 190, 194, 18, 54, 254, 210, 219, 249, 27, 13, 230, 225, 220, 254, 61, 43, 223, 197, 202, 0, 79, 48, 243, 203, 205, 40, 96, 43, 230, 192, 246, 47, 40, 2, 235, 205, 6, 66, 9, 209, 203, 230, 45, 44, 255, 241, 211, 221, 22, 63, 54, 1, 205, 207, 35, 67, 36, 21, 252, 233, 19, 34, 46, 255, 199, 1, 88, 67, 215, 135, 235, 72, 62, 252, 176, 231, 1, 12, 0, 233, 222, 239, 27, 249, 219, 228, 255, 8, 231, 206, 224, 14, 26, 24, 10, 253, 217, 203, 205, 39, 83, 42, 237, 162, 237, 50, 11, 2, 242, 39, 240, 237, 245, 254, 8, 254, 11, 235, 201, 246, 17, 241, 27, 33, 21, 25, 236, 228, 12, 49, 64, 34, 0, 207, 18, 56, 16, 231, 243, 16, 9, 255, 235, 20, 53, 27, 226, 200, 180, 3, 68, 22, 5, 215, 249, 17, 255, 7, 250, 13, 8, 4, 41, 33, 232, 224, 6, 15, 255, 234, 220, 252, 40, 35, 254, 187, 199, 232, 34, 51, 248, 233, 220, 232, 55, 0, 216, 1, 27, 27, 251, 220, 213, 250, 47, 50, 8, 201, 195, 11, 25, 11, 3, 11, 29, 14, 230, 2, 45, 47, 24, 19, 247, 215, 216, 25, 47, 7, 219, 227, 7, 32, 30, 15, 23, 255, 226, 208, 233, 23, 2, 243, 250, 2, 2, 211, 198, 234, 2, 50, 27, 206, 196, 232, 9, 13, 13, 250, 244, 231, 244, 241, 5, 16, 1, 242, 10, 4, 239, 240, 21, 41, 23, 219, 227, 50, 37, 15, 251, 2, 22, 5, 3, 184, 227, 91, 45, 20, 245, 234, 235, 241, 15, 22, 251, 253, 245, 32, 18, 233, 215, 246, 34, 51, 29, 13, 237, 19, 58, 19, 241, 3, 18, 250, 11, 32, 37, 8, 247, 2, 11, 235, 211, 216, 17, 99, 20, 224, 200, 217, 252, 231, 252, 19, 3, 244, 246, 17, 34, 8, 219, 240, 3, 234, 248, 254, 3, 7, 23, 25, 243, 226, 251, 21, 47, 15, 242, 246, 26, 35, 14, 204, 178, 242, 29, 10, 19, 25, 12, 233, 240, 238, 242, 249, 14, 240, 215, 248, 4, 15, 21, 247, 247, 8, 5, 250, 254, 2, 254, 253, 2, 237, 233, 19, 36, 16, 249, 251, 34, 28, 245, 237, 244, 16, 39, 10, 251, 244, 244, 13, 12, 225, 212, 224, 29, 9, 239, 244, 0, 1, 11, 12, 7, 252, 248, 7, 0, 249, 224, 217, 239, 14, 24, 6, 225, 175, 190, 0, 26, 11, 3, 243, 253, 249, 11, 31, 27, 243, 228, 29, 32, 5, 0, 243, 252, 10, 52, 37, 239, 195, 251, 74, 46, 4, 211, 167, 32, 119, 72, 12, 212, 210, 2, 19, 12, 33, 53, 19, 11, 3, 223, 239, 9, 18, 31, 8, 223, 207, 246, 13, 17, 16, 244, 230, 230, 30, 46, 15, 249, 224, 250, 20, 6, 238, 239, 18, 24, 20, 1, 221, 196, 241, 25, 39, 38, 4, 230, 225, 34, 29, 237, 204, 236, 16, 50, 47, 240, 177, 207, 14, 26, 22, 229, 196, 247, 1, 251, 0, 229, 243, 12, 10, 0, 46, 3, 31, 0, 14, 38, 18, 32, 39, 17, 243, 10, 31, 23, 4, 9, 21, 31, 17, 8, 19, 34, 19, 38, 9, 255, 18, 33, 29, 22, 31, 239, 6, 20, 17, 41, 17, 5, 6, 16, 45, 17, 5, 36, 34, 7, 5, 37, 42, 25, 1, 14, 15, 21, 252, 6, 22, 31, 35, 0, 3, 250, 45, 32, 24, 24, 245, 16, 27, 23, 48, 38, 15, 249, 250, 25, 9, 250, 24, 16, 39, 16, 24, 27, 39, 31, 232, 29, 33, 30, 24, 14, 9, 26, 0, 0, 21, 38, 26, 23, 23, 4, 1, 36, 8, 16, 25, 250, 6, 13, 57, 7, 240, 10, 35, 28, 27, 30, 21, 28, 16, 42, 23, 3, 19, 13, 37, 18, 19, 37, 63, 9, 0, 42, 55, 53, 231, 15, 63, 55, 15, 1, 24, 253, 40, 32, 40, 6, 31, 27, 250, 10, 25, 34, 13, 9, 31, 19, 15, 20, 30, 10, 15, 3, 60, 43, 224, 0, 45, 53, 18, 5, 40, 19, 252, 27, 10, 12, 49, 22, 242, 252, 44, 18, 45, 14, 2, 233, 37, 36, 242, 7, 37, 19, 3, 24, 30, 1, 5, 58, 3, 252, 8, 29, 40, 15, 11, 14, 3, 255, 0, 37, 36, 11, 245, 17, 55, 249, 255, 25, 48, 21, 252, 18, 48, 23, 237, 235, 34, 38, 235, 240, 39, 36, 16, 23, 21, 1, 15, 20, 26, 44, 1, 19, 23, 10, 46, 33, 221, 229, 36, 32, 241, 254, 1, 12, 39, 56, 60, 251, 8, 19, 248, 34, 26, 21, 16, 19, 17, 14, 20, 249, 28, 18, 21, 29, 242, 239, 35, 47, 53, 25, 234, 34, 47, 255, 15, 45, 32, 15, 27, 3, 249, 12, 46, 36, 22, 41, 47, 222, 238, 62, 42, 11, 228, 11, 55, 29, 221, 5, 73, 31, 13, 20, 248, 252, 5, 42, 59, 15, 27, 14, 31, 10, 244, 48, 51, 33, 245, 11, 31, 253, 252, 9, 48, 18, 217, 242, 21, 53, 84, 25, 218, 33, 34, 39, 26, 21, 28, 1, 29, 4, 238, 12, 249, 32, 50, 0, 230, 36, 35, 10, 245, 225, 2, 75, 65, 2, 0, 246, 48, 45, 241, 235, 14, 34, 51, 45, 4, 224, 6, 15, 90, 23, 190, 33, 93, 28, 61, 28, 241, 183, 15, 47, 30, 12, 243, 240, 2, 89, 65, 216, 221, 22, 58, 65, 8, 234, 6, 30, 10, 21, 68, 242, 202, 60, 42, 3, 245, 176, 6, 45, 64, 25, 229, 222, 32, 47, 16, 238, 223, 65, 50, 241, 236, 27, 81, 252, 57, 64, 7, 235, 253, 22, 46, 23, 252, 0, 55, 61, 8, 255, 215, 255, 49, 85, 23, 206, 253, 10, 237, 71, 230, 201, 41, 49, 47, 25, 225, 208, 65, 66, 251, 246, 6, 69, 41, 20, 21, 245, 242, 27, 49, 4, 38, 52, 1, 220, 2, 48, 221, 248, 6, 11, 46, 55, 199, 208, 34, 16, 45, 29, 177, 41, 84, 33, 254, 8, 216, 55, 66, 22, 248, 208, 4, 63, 33, 21, 4, 253, 251, 28, 11, 37, 84, 42, 21, 239, 188, 44, 51, 31, 29, 41, 9, 219, 1, 243, 38, 108, 191, 254, 62, 242, 239, 60, 12, 13, 71, 11, 215, 32, 74, 1, 238, 55, 53, 248, 225, 227, 88, 112, 0, 57, 11, 217, 36, 4, 25, 55, 38, 44, 9, 3, 57, 81, 18, 247, 233, 63, 8, 9, 43, 52, 12, 21, 32, 22, 48, 44, 253, 9, 60, 56, 50, 30, 2, 211, 26, 78, 75, 43, 3, 13, 46, 255, 250, 57, 228, 211, 52, 82, 255, 233, 50, 200, 232, 66, 107, 252, 12, 10, 50, 22, 242, 23, 12, 14, 18, 47, 25, 2, 3, 32, 53, 39, 15, 228, 47, 9, 13, 17, 46, 241, 234, 59, 16, 233, 20, 20, 50, 250, 92, 17, 218, 253, 248, 243, 58, 7, 201, 20, 232, 221, 9, 87, 96, 3, 225, 242, 250, 14, 13, 0, 20, 64, 9, 13, 231, 238, 63, 49, 36, 253, 209, 207, 254, 70, 40, 30, 252, 131, 206, 66, 21, 51, 26, 241, 28, 17, 242, 255, 248, 61, 42, 233, 20, 77, 46, 222, 188, 25, 98, 85, 55, 243, 8, 16, 249, 7, 60, 43, 48, 55, 8, 185, 223, 76, 249, 14, 23, 11, 253, 66, 39, 255, 235, 7, 37, 5, 41, 18, 42, 232, 251, 38, 92, 50, 192, 2, 1, 245, 5, 53, 87, 9, 250, 236, 245, 22, 36, 213, 236, 62, 109, 71, 243, 224, 253, 80, 101, 248, 232, 57, 71, 38, 255, 254, 34, 48, 232, 240, 91, 78, 171, 193, 43, 91, 49, 246, 221, 250, 235, 61, 84, 227, 223, 4, 14, 27, 29, 198, 238, 31, 8, 82, 2, 184, 50, 42, 251, 254, 30, 33, 63, 39, 234, 234, 0, 0, 254, 6, 35, 0, 0, 0, 1, 2, 1, 0, 0, 1, 1, 0, 0, 0, 253, 251, 250, 247, 243, 240, 239, 242, 249, 2, 5, 11, 15, 18, 17, 20, 19, 14, 11, 1, 235, 224, 232, 234, 223, 235, 0, 253, 250, 14, 25, 21, 24, 26, 22, 20, 11, 254, 253, 249, 235, 232, 240, 241, 240, 249, 255, 7, 12, 19, 21, 26, 21, 14, 15, 6, 0, 248, 250, 241, 241, 245, 244, 246, 255, 6, 8, 14, 20, 15, 13, 16, 11, 5, 2, 239, 210, 214, 230, 219, 220, 244, 246, 245, 12, 25, 26, 37, 33, 22, 26, 15, 254, 250, 250, 236, 236, 243, 241, 245, 249, 4, 17, 26, 23, 25, 39, 27, 12, 16, 9, 242, 214, 192, 208, 228, 222, 206, 235, 251, 237, 5, 34, 46, 41, 40, 38, 36, 28, 1, 255, 4, 242, 227, 240, 252, 241, 241, 7, 19, 17, 24, 28, 32, 23, 18, 10, 9, 253, 234, 243, 242, 235, 243, 27, 52, 245, 4, 31, 44, 247, 28, 43, 245, 246, 241, 235, 219, 210, 203, 210, 238, 241, 7, 38, 22, 48, 61, 51, 24, 252, 228, 200, 200, 173, 166, 202, 221, 210, 248, 27, 49, 35, 67, 63, 40, 14, 245, 232, 189, 174, 162, 179, 174, 189, 226, 8, 30, 55, 92, 86, 75, 72, 54, 22, 0, 253, 224, 204, 207, 193, 211, 227, 17, 26, 56, 76, 84, 83, 72, 63, 44, 11, 248, 248, 224, 212, 215, 229, 221, 241, 6, 4, 23, 27, 32, 39, 13, 254, 2, 248, 212, 199, 208, 165, 183, 203, 200, 221, 25, 61, 46, 65, 85, 60, 33, 44, 0, 185, 182, 194, 158, 159, 224, 222, 0, 46, 64, 73, 111, 120, 86, 86, 67, 17, 248, 226, 206, 181, 183, 198, 217, 242, 2, 29, 46, 48, 45, 45, 24, 243, 205, 180, 153, 131, 148, 158, 168, 192, 231, 15, 49, 86, 95, 104, 105, 94, 69, 48, 23, 255, 234, 215, 211, 207, 210, 221, 242, 8, 31, 66, 70, 79, 88, 68, 48, 25, 5, 239, 220, 197, 201, 203, 205, 221, 254, 1, 14, 36, 42, 34, 31, 27, 1, 241, 244, 219, 199, 208, 213, 203, 220, 1, 0, 3, 38, 39, 28, 27, 36, 13, 0, 241, 229, 222, 224, 236, 238, 242, 247, 3, 1, 0, 4, 249, 235, 238, 239, 233, 241, 248, 0, 2, 22, 45, 53, 48, 42, 33, 24, 35, 2, 249, 254, 243, 211, 237, 247, 224, 250, 10, 10, 253, 14, 6, 14, 14, 9, 0, 1, 248, 238, 248, 251, 244, 231, 232, 234, 2, 0, 249, 4, 11, 7, 8, 21, 19, 13, 18, 11, 242, 238, 246, 252, 245, 239, 241, 0, 2, 2, 0, 3, 12, 5, 7, 2, 6, 2, 13, 6, 238, 242, 4, 13, 0, 247, 7, 16, 20, 12, 11, 12, 28, 38, 23, 13, 12, 6, 247, 244, 225, 219, 217, 230, 223, 233, 0, 5, 8, 20, 17, 15, 19, 23, 1, 12, 32, 33, 19, 18, 13, 238, 252, 253, 239, 235, 252, 225, 205, 237, 229, 216, 253, 250, 235, 231, 249, 227, 234, 253, 248, 238, 246, 253, 0, 6, 27, 33, 51, 52, 40, 33, 56, 47, 42, 32, 27, 3, 6, 19, 248, 235, 230, 221, 216, 226, 231, 216, 228, 240, 222, 234, 254, 250, 232, 234, 233, 221, 221, 232, 230, 236, 247, 7, 2, 248, 2, 13, 23, 30, 33, 26, 28, 39, 46, 52, 51, 46, 44, 34, 22, 27, 26, 2, 10, 3, 241, 233, 252, 253, 245, 4, 15, 0, 5, 10, 9, 235, 238, 234, 215, 212, 219, 203, 200, 223, 239, 238, 14, 29, 1, 10, 20, 17, 5, 252, 252, 236, 238, 231, 255, 234, 233, 241, 244, 247, 9, 22, 25, 22, 31, 24, 29, 20, 17, 8, 4, 255, 254, 22, 15, 247, 240, 239, 0, 2, 17, 28, 32, 28, 14, 10, 5, 11, 253, 251, 1, 0, 9, 29, 23, 3, 5, 1, 250, 246, 252, 234, 238, 2, 243, 240, 247, 0, 253, 2, 245, 237, 243, 0, 5, 13, 14, 30, 42, 16, 5, 5, 12, 246, 255, 234, 208, 212, 232, 241, 1, 2, 251, 237, 232, 212, 221, 198, 176, 178, 186, 199, 229, 248, 0, 23, 44, 65, 72, 78, 67, 47, 22, 7, 1, 253, 253, 4, 30, 22, 28, 59, 70, 48, 56, 64, 19, 3, 236, 180, 155, 162, 154, 138, 159, 183, 203, 242, 22, 57, 66, 64, 67, 55, 42, 28, 35, 0, 232, 245, 0, 235, 9, 39, 29, 37, 79, 81, 56, 65, 35, 231, 212, 213, 200, 181, 192, 181, 184, 208, 239, 4, 34, 56, 55, 56, 63, 38, 22, 14, 239, 221, 219, 246, 248, 17, 20, 30, 29, 22, 25, 20, 10, 5, 5, 252, 252, 255, 238, 235, 250, 243, 1, 246, 222, 234, 253, 247, 238, 241, 246, 239, 254, 241, 241, 15, 29, 25, 4, 24, 6, 255, 245, 222, 213, 242, 15, 4, 1, 26, 38, 45, 34, 16, 5, 3, 12, 242, 221, 224, 218, 203, 206, 202, 215, 247, 5, 6, 253, 27, 28, 44, 26, 6, 10, 1, 232, 212, 214, 220, 238, 17, 23, 30, 67, 42, 19, 7, 247, 206, 211, 227, 181, 181, 214, 202, 209, 241, 10, 3, 36, 61, 42, 47, 50, 13, 250, 243, 226, 220, 225, 217, 214, 5, 34, 41, 72, 84, 81, 65, 58, 43, 19, 21, 247, 226, 231, 235, 236, 242, 11, 11, 22, 43, 31, 20, 18, 15, 234, 207, 212, 190, 198, 222, 208, 208, 241, 9, 243, 24, 45, 50, 65, 76, 58, 40, 39, 28, 255, 249, 249, 238, 232, 235, 245, 5, 20, 30, 27, 21, 33, 32, 21, 247, 226, 204, 194, 184, 181, 175, 177, 197, 222, 222, 234, 12, 30, 37, 48, 58, 43, 48, 41, 10, 233, 233, 220, 206, 233, 240, 237, 252, 30, 27, 66, 80, 71, 53, 61, 19, 245, 246, 231, 198, 215, 206, 176, 200, 249, 240, 252, 34, 30, 29, 37, 33, 29, 29, 15, 241, 227, 210, 212, 214, 232, 248, 2, 21, 35, 50, 53, 69, 48, 49, 22, 5, 0, 251, 221, 226, 224, 232, 232, 3, 241, 254, 36, 18, 21, 23, 16, 236, 245, 238, 207, 222, 237, 198, 223, 253, 4, 4, 13, 17, 254, 15, 3, 246, 251, 250, 235, 212, 223, 243, 247, 5, 0, 5, 19, 33, 54, 43, 44, 26, 12, 240, 227, 221, 237, 238, 230, 215, 252, 14, 14, 7, 5, 10, 4, 5, 237, 232, 0, 15, 15, 248, 242, 254, 4, 245, 249, 0, 7, 14, 18, 250, 0, 23, 19, 6, 12, 19, 24, 21, 15, 2, 250, 251, 248, 244, 242, 244, 0, 246, 237, 221, 250, 242, 236, 240, 238, 227, 239, 7, 2, 10, 39, 43, 30, 39, 44, 20, 22, 17, 16, 6, 35, 23, 3, 253, 14, 9, 7, 14, 13, 3, 9, 24, 251, 227, 249, 252, 210, 217, 244, 226, 227, 245, 232, 226, 11, 6, 244, 251, 17, 9, 17, 11, 9, 255, 1, 248, 249, 249, 14, 19, 4, 0, 14, 13, 14, 30, 19, 255, 255, 247, 237, 238, 238, 243, 249, 250, 5, 7, 27, 23, 16, 17, 30, 6, 7, 4, 236, 233, 248, 226, 199, 231, 251, 247, 12, 29, 255, 254, 26, 10, 243, 254, 250, 210, 219, 224, 223, 231, 250, 244, 246, 6, 9, 250, 254, 4, 11, 9, 0, 255, 246, 249, 10, 12, 0, 26, 40, 19, 4, 27, 11, 0, 4, 237, 217, 244, 16, 253, 244, 3, 1, 250, 1, 2, 250, 9, 20, 2, 225, 235, 14, 10, 251, 9, 251, 254, 20, 23, 3, 18, 35, 29, 20, 15, 19, 20, 21, 19, 248, 232, 8, 254, 247, 247, 242, 237, 253, 10, 240, 245, 236, 235, 248, 236, 239, 239, 221, 240, 244, 242, 242, 8, 3, 3, 11, 22, 26, 30, 23, 28, 0, 17, 24, 246, 251, 1, 1, 240, 5, 239, 236, 24, 36, 27, 253, 24, 16, 249, 253, 243, 217, 244, 3, 212, 185, 220, 239, 238, 238, 249, 241, 253, 32, 31, 6, 21, 40, 19, 23, 33, 26, 13, 20, 14, 23, 35, 41, 22, 5, 22, 18, 27, 12, 250, 251, 254, 243, 224, 229, 226, 248, 244, 236, 239, 255, 8, 28, 15, 2, 18, 24, 16, 27, 15, 236, 254, 255, 249, 0, 254, 3, 4, 33, 22, 42, 31, 29, 23, 18, 4, 246, 237, 208, 234, 229, 226, 216, 242, 251, 253, 249, 15, 4, 16, 13, 254, 248, 1, 26, 235, 230, 248, 251, 231, 248, 254, 11, 18, 28, 232, 248, 20, 6, 243, 229, 246, 241, 244, 238, 228, 228, 1, 4, 235, 225, 246, 248, 235, 245, 9, 235, 231, 0, 1, 245, 17, 8, 247, 11, 36, 22, 249, 7, 19, 1, 248, 19, 241, 242, 2, 251, 216, 244, 8, 5, 255, 4, 11, 249, 8, 20, 13, 255, 7, 240, 238, 246, 252, 245, 229, 240, 252, 243, 1, 24, 12, 253, 37, 29, 1, 1, 18, 250, 250, 8, 249, 244, 7, 10, 255, 15, 44, 35, 21, 33, 37, 15, 8, 0, 234, 244, 253, 234, 209, 222, 222, 252, 249, 255, 253, 10, 252, 9, 2, 4, 253, 1, 250, 238, 251, 229, 3, 254, 20, 0, 11, 3, 24, 33, 21, 7, 11, 20, 23, 22, 0, 6, 253, 249, 238, 235, 247, 241, 232, 221, 243, 247, 240, 234, 242, 254, 2, 226, 232, 0, 15, 23, 250, 244, 255, 22, 20, 0, 9, 27, 38, 3, 2, 255, 15, 20, 11, 233, 228, 237, 251, 231, 218, 228, 248, 0, 8, 250, 251, 28, 30, 21, 15, 0, 18, 28, 2, 251, 232, 229, 248, 13, 240, 229, 234, 246, 17, 17, 250, 241, 17, 37, 27, 245, 232, 244, 17, 14, 240, 226, 245, 19, 37, 16, 244, 10, 28, 35, 30, 14, 14, 20, 24, 6, 10, 0, 5, 9, 9, 11, 4, 0, 23, 8, 9, 19, 4, 4, 27, 12, 242, 0, 0, 231, 255, 234, 253, 238, 245, 241, 246, 9, 5, 254, 1, 9, 251, 6, 0, 2, 0, 2, 228, 249, 234, 238, 0, 2, 0, 19, 39, 27, 27, 36, 51, 32, 22, 12, 253, 5, 252, 221, 234, 248, 249, 3, 4, 252, 39, 34, 9, 22, 44, 33, 30, 255, 226, 14, 12, 245, 225, 235, 253, 0, 2, 4, 11, 0, 17, 18, 253, 248, 241, 223, 247, 235, 224, 224, 230, 211, 239, 253, 241, 0, 10, 245, 241, 0, 249, 244, 250, 0, 0, 170, 7, 51, 0, 21, 242, 238, 36, 3, 9, 1, 243, 53, 29, 200, 245, 43, 246, 25, 1, 188, 17, 48, 233, 0, 7, 240, 28, 12, 233, 10, 17, 0, 250, 17, 31, 237, 219, 30, 38, 12, 249, 237, 0, 38, 249, 9, 12, 224, 60, 17, 164, 60, 69, 186, 246, 2, 12, 106, 244, 132, 46, 76, 41, 222, 179, 29, 40, 30, 238, 186, 37, 78, 238, 227, 0, 40, 33, 7, 250, 249, 21, 27, 237, 8, 47, 202, 26, 57, 239, 25, 236, 237, 60, 21, 231, 223, 21, 81, 219, 184, 42, 30, 0, 25, 255, 224, 15, 38, 250, 232, 250, 0, 32, 7, 228, 22, 9, 244, 2, 23, 255, 230, 20, 17, 255, 249, 243, 37, 42, 244, 226, 0, 25, 5, 245, 12, 12, 242, 15, 41, 228, 203, 64, 67, 199, 241, 34, 10, 22, 238, 231, 33, 13, 250, 243, 235, 40, 21, 193, 10, 46, 244, 242, 253, 24, 40, 251, 232, 244, 35, 50, 223, 212, 37, 47, 229, 232, 14, 252, 39, 22, 231, 0, 48, 2, 226, 27, 35, 233, 2, 24, 12, 1, 209, 37, 53, 221, 246, 27, 10, 27, 253, 252, 15, 250, 2, 6, 5, 50, 247, 212, 26, 37, 1, 239, 244, 44, 30, 236, 7, 247, 30, 34, 228, 242, 4, 45, 0, 197, 22, 59, 255, 233, 254, 1, 23, 24, 240, 237, 47, 20, 242, 236, 32, 21, 237, 35, 4, 209, 13, 62, 3, 229, 15, 253, 10, 20, 235, 2, 39, 224, 255, 38, 243, 8, 244, 227, 73, 17, 203, 11, 38, 243, 6, 2, 255, 35, 246, 10, 246, 242, 61, 235, 206, 61, 254, 232, 39, 248, 246, 42, 13, 226, 253, 37, 13, 5, 9, 237, 24, 47, 227, 237, 51, 19, 232, 18, 7, 238, 27, 17, 235, 8, 14, 228, 21, 11, 236, 37, 2, 243, 12, 9, 8, 27, 0, 231, 3, 22, 253, 229, 38, 1, 221, 31, 13, 251, 8, 248, 17, 255, 250, 32, 5, 14, 30, 232, 246, 50, 0, 241, 23, 230, 28, 24, 208, 32, 55, 217, 214, 74, 45, 182, 1, 59, 19, 246, 233, 25, 4, 6, 7, 214, 40, 29, 241, 252, 0, 16, 21, 16, 218, 14, 61, 242, 245, 7, 0, 43, 12, 235, 10, 3, 6, 30, 240, 245, 49, 243, 219, 16, 66, 11, 175, 2, 101, 238, 236, 10, 212, 50, 100, 166, 173, 111, 43, 204, 232, 10, 50, 1, 225, 11, 20, 4, 254, 243, 8, 35, 235, 220, 17, 22, 241, 242, 34, 6, 243, 6, 248, 243, 44, 0, 230, 6, 15, 238, 0, 9, 0, 35, 235, 234, 51, 249, 218, 23, 11, 7, 250, 223, 24, 33, 7, 228, 230, 58, 27, 201, 15, 25, 248, 31, 27, 218, 212, 78, 56, 189, 200, 68, 66, 221, 212, 253, 34, 62, 218, 221, 32, 13, 6, 7, 7, 8, 14, 251, 6, 23, 30, 210, 250, 62, 19, 230, 227, 29, 29, 252, 245, 60, 246, 173, 65, 92, 206, 232, 54, 17, 230, 36, 27, 194, 14, 52, 208, 250, 50, 244, 197, 38, 59, 212, 253, 12, 7, 5, 249, 239, 28, 10, 0, 227, 0, 70, 241, 226, 27, 21, 12, 225, 241, 27, 18, 3, 226, 7, 33, 223, 1, 34, 11, 7, 224, 14, 56, 248, 220, 33, 10, 247, 247, 247, 42, 228, 208, 44, 51, 239, 237, 245, 22, 56, 202, 245, 54, 241, 1, 2, 245, 43, 251, 220, 18, 29, 246, 232, 33, 31, 236, 233, 6, 57, 5, 221, 250, 0, 32, 22, 200, 35, 54, 217, 10, 2, 233, 60, 35, 211, 0, 27, 26, 253, 228, 0, 35, 36, 254, 208, 4, 81, 223, 228, 58, 252, 236, 29, 231, 16, 50, 212, 245, 17, 33, 30, 191, 245, 72, 20, 237, 240, 243, 43, 27, 252, 3, 252, 249, 18, 48, 250, 247, 32, 252, 232, 42, 11, 210, 39, 53, 250, 196, 8, 57, 250, 243, 34, 242, 254, 45, 230, 242, 3, 30, 28, 239, 232, 248, 41, 15, 235, 31, 233, 233, 48, 3, 234, 2, 13, 20, 14, 254, 10, 235, 247, 40, 246, 28, 241, 224, 41, 18, 254, 224, 6, 39, 17, 244, 222, 0, 47, 12, 223, 11, 33, 246, 255, 0, 243, 30, 32, 235, 219, 35, 12, 241, 38, 253, 224, 30, 34, 237, 223, 25, 30, 252, 2, 247, 27, 252, 240, 45, 247, 237, 7, 17, 16, 250, 222, 17, 69, 230, 224, 37, 7, 53, 247, 198, 56, 34, 215, 25, 10, 238, 42, 11, 238, 22, 239, 31, 29, 223, 12, 1, 17, 6, 240, 39, 225, 238, 76, 244, 216, 6, 33, 32, 239, 241, 46, 227, 20, 52, 174, 4, 61, 246, 12, 249, 1, 56, 233, 234, 38, 239, 12, 56, 221, 215, 33, 17, 252, 7, 2, 9, 6, 233, 251, 44, 21, 222, 219, 35, 42, 215, 255, 7, 6, 40, 0, 188, 15, 76, 245, 193, 29, 25, 23, 8, 182, 44, 68, 240, 236, 240, 53, 10, 225, 18, 13, 11, 247, 16, 19, 2, 239, 204, 71, 69, 188, 229, 30, 35, 0, 2, 14, 236, 15, 32, 228, 249, 49, 3, 218, 5, 31, 2, 0, 11, 23, 237, 4, 46, 204, 233, 66, 250, 217, 22, 41, 2, 225, 27, 47, 234, 252, 10, 16, 32, 207, 1, 42, 242, 20, 254, 219, 33, 33, 214, 18, 53, 242, 10, 6, 234, 30, 19, 235, 9, 42, 242, 224, 32, 0, 243, 16, 251, 11, 23, 244, 253, 40, 252, 250, 35, 247, 246, 16, 251, 23, 249, 239, 13, 237, 22, 0, 0, 26, 243, 1, 33, 231, 9, 46, 235, 245, 9, 30, 30, 186, 244, 60, 27, 7, 219, 251, 54, 24, 255, 232, 20, 58, 246, 195, 11, 40, 18, 2, 200, 0, 60, 42, 225, 219, 32, 32, 4, 232, 254, 5, 13, 37, 225, 247, 42, 255, 227, 19, 10, 230, 5, 26, 236, 255, 19, 8, 10, 21, 242, 238, 36, 3, 9, 1, 243, 53, 29, 200, 245, 43, 246, 25, 1, 188, 17, 48, 233, 0, 7, 240, 28, 12, 233, 10, 17, 0, 250, 17, 31, 237, 219, 30, 38, 12, 249, 237, 0, 38, 249, 9, 12, 224, 60, 17, 164, 60, 69, 186, 246, 2, 12, 106, 244, 132, 46, 76, 41, 222, 179, 29, 40, 30, 238, 186, 37, 78, 238, 227, 0, 40, 33, 7, 250, 249, 21, 27, 237, 8, 47, 202, 26, 57, 239, 25, 236, 237, 60, 21, 231, 223, 21, 81, 219, 184, 42, 30, 0, 25, 255, 224, 15, 38, 250, 232, 250, 0, 32, 7, 228, 22, 9, 244, 2, 23, 255, 230, 20, 17, 255, 249, 243, 37, 42, 244, 226, 0, 25, 5, 245, 12, 12, 242, 15, 41, 228, 203, 64, 67, 199, 241, 34, 10, 22, 238, 231, 33, 13, 250, 243, 235, 40, 21, 193, 10, 46, 244, 242, 253, 24, 40, 251, 232, 244, 35, 50, 223, 212, 37, 47, 229, 232, 14, 252, 39, 22, 231, 0, 48, 2, 226, 27, 35, 233, 2, 24, 12, 1, 209, 37, 53, 221, 246, 27, 10, 27, 253, 252, 15, 250, 2, 6, 5, 50, 247, 212, 26, 37, 1, 239, 244, 44, 30, 236, 7, 247, 30, 34, 228, 242, 4, 45, 0, 197, 22, 59, 255, 233, 254, 1, 23, 24, 240, 237, 47, 20, 242, 236, 32, 21, 237, 35, 4, 209, 13, 62, 3, 229, 15, 253, 10, 20, 235, 2, 39, 224, 255, 38, 243, 8, 244, 227, 73, 17, 203, 11, 38, 243, 6, 2, 255, 35, 246, 10, 246, 242, 61, 235, 206, 61, 254, 232, 39, 248, 246, 42, 13, 226, 253, 37, 13, 5, 9, 237, 24, 47, 227, 237, 51, 19, 232, 18, 7, 238, 27, 17, 235, 8, 14, 228, 21, 11, 236, 37, 2, 243, 12, 9, 8, 27, 0, 231, 3, 22, 253, 229, 38, 1, 221, 31, 13, 251, 8, 248, 17, 255, 250, 32, 5, 14, 30, 232, 246, 50, 0, 241, 23, 230, 28, 24, 208, 32, 55, 217, 214, 74, 45, 182, 1, 59, 19, 246, 233, 25, 4, 6, 7, 214, 40, 29, 241, 252, 0, 16, 21, 16, 218, 14, 61, 242, 245, 7, 0, 43, 12, 235, 10, 3, 6, 30, 240, 245, 49, 243, 219, 16, 66, 11, 175, 2, 101, 238, 236, 10, 212, 50, 100, 166, 173, 111, 43, 204, 232, 10, 50, 1, 225, 11, 20, 4, 254, 243, 8, 35, 235, 220, 17, 22, 241, 242, 34, 6, 243, 6, 248, 243, 44, 0, 230, 6, 15, 238, 0, 9, 0, 35, 235, 234, 51, 249, 218, 23, 11, 7, 250, 223, 24, 33, 7, 228, 230, 58, 27, 201, 15, 25, 248, 31, 27, 218, 212, 78, 56, 189, 200, 68, 66, 221, 212, 253, 34, 62, 218, 221, 32, 13, 6, 7, 7, 8, 14, 251, 6, 23, 30, 210, 250, 62, 19, 230, 227, 29, 29, 252, 245, 60, 246, 173, 65, 92, 206, 232, 54, 17, 230, 36, 27, 194, 14, 52, 208, 250, 50, 244, 197, 38, 59, 212, 253, 12, 7, 5, 249, 239, 28, 10, 0, 227, 0, 70, 241, 226, 27, 21, 12, 225, 241, 27, 18, 3, 226, 7, 33, 223, 1, 34, 11, 7, 224, 14, 56, 248, 220, 33, 10, 247, 247, 247, 42, 228, 208, 44, 51, 239, 237, 245, 22, 56, 202, 245, 54, 241, 1, 2, 245, 43, 251, 220, 18, 29, 246, 232, 33, 31, 236, 233, 6, 57, 5, 221, 250, 0, 32, 22, 200, 35, 54, 217, 10, 2, 233, 60, 35, 211, 0, 27, 26, 253, 228, 0, 35, 36, 254, 208, 4, 81, 223, 228, 58, 252, 236, 29, 231, 16, 50, 212, 245, 17, 33, 30, 191, 245, 72, 20, 237, 240, 243, 43, 27, 252, 3, 252, 249, 18, 48, 250, 247, 32, 252, 232, 42, 11, 210, 39, 53, 250, 196, 8, 57, 250, 243, 34, 242, 254, 45, 230, 242, 3, 30, 28, 239, 232, 248, 41, 15, 235, 31, 233, 233, 48, 3, 234, 2, 13, 20, 14, 254, 10, 235, 247, 40, 246, 28, 241, 224, 41, 18, 254, 224, 6, 39, 17, 244, 222, 0, 47, 12, 223, 11, 33, 246, 255, 0, 243, 30, 32, 235, 219, 35, 12, 241, 38, 253, 224, 30, 34, 237, 223, 25, 30, 252, 2, 247, 27, 252, 240, 45, 247, 237, 7, 17, 16, 250, 222, 17, 69, 230, 224, 37, 7, 53, 247, 198, 56, 34, 215, 25, 10, 238, 42, 11, 238, 22, 239, 31, 29, 223, 12, 1, 17, 6, 240, 39, 225, 238, 76, 244, 216, 6, 33, 32, 239, 241, 46, 227, 20, 52, 174, 4, 61, 246, 12, 249, 1, 56, 233, 234, 38, 239, 12, 56, 221, 215, 33, 17, 252, 7, 2, 9, 6, 233, 251, 44, 21, 222, 219, 35, 42, 215, 255, 7, 6, 40, 0, 188, 15, 76, 245, 193, 29, 25, 23, 8, 182, 44, 68, 240, 236, 240, 53, 10, 225, 18, 13, 11, 247, 16, 19, 2, 239, 204, 71, 69, 188, 229, 30, 35, 0, 2, 14, 236, 15, 32, 228, 249, 49, 3, 218, 5, 31, 2, 0, 11, 23, 237, 4, 46, 204, 233, 66, 250, 217, 22, 41, 2, 225, 27, 47, 234, 252, 10, 16, 32, 207, 1, 42, 242, 20, 254, 219, 33, 33, 214, 18, 53, 242, 10, 6, 234, 30, 19, 235, 9, 42, 242, 224, 32, 0, 243, 16, 251, 11, 23, 244, 253, 40, 252, 250, 35, 247, 246, 16, 251, 23, 249, 239, 13, 0, 0, 150, 0, 4, 0, 1, 0, 224, 0, 248, 2, 140, 5, 60, 10, 20, 13, 175, 14, 117, 27, 50, 43, 29, 57, 48, 41, 35, 29, 12, 3, 196, 162, 200, 120, 120, 120, 249, 174, 255, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 224, 0, 248, 2, 140, 5, 40, 10, 20, 13, 175, 14, 117, 27, 60, 67, 36, 71, 61, 52, 44, 37, 15, 4, 196, 162, 200, 120, 120, 120, 249, 174, 255, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 224, 0, 248, 2, 120, 5, 40, 10, 20, 13, 175, 14, 117, 27, 40, 55, 33, 64, 55, 40, 36, 33, 14, 4, 196, 162, 200, 120, 120, 120, 249, 174, 255, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 208, 0, 224, 2, 100, 5, 236, 9, 1, 13, 155, 14, 105, 27, 0, 33, 26, 52, 37, 27, 24, 24, 11, 3, 192, 158, 201, 120, 120, 120, 249, 174, 255, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 175, 0, 4, 0, 1, 0, 240, 0, 128, 3, 160, 5, 150, 10, 164, 13, 45, 15, 195, 27, 45, 45, 31, 64, 57, 40, 30, 20, 9, 4, 235, 162, 134, 132, 120, 120, 247, 170, 165, 44, 65, 70, 130, 55, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 240, 0, 128, 3, 160, 5, 150, 10, 164, 13, 45, 15, 195, 27, 50, 82, 42, 87, 77, 54, 41, 27, 12, 5, 235, 162, 134, 132, 120, 120, 247, 170, 165, 44, 65, 70, 130, 55, 0, 0, 0, 0, 45, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 240, 0, 128, 3, 160, 5, 150, 10, 164, 13, 45, 15, 195, 27, 80, 67, 37, 78, 69, 48, 37, 24, 11, 5, 235, 162, 134, 132, 120, 120, 247, 170, 165, 44, 65, 70, 130, 55, 0, 0, 0, 0, 45, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 240, 0, 128, 3, 160, 5, 150, 10, 164, 13, 45, 15, 195, 27, 0, 37, 28, 58, 52, 36, 27, 18, 8, 3, 235, 162, 134, 132, 120, 120, 247, 170, 165, 44, 65, 70, 130, 55, 0, 0, 0, 0, 45, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 0, 0, 5, 0, 1, 0, 240, 0, 200, 2, 224, 6, 176, 9, 112, 13, 10, 15, 96, 27, 44, 46, 34, 65, 59, 56, 38, 23, 6, 8, 165, 135, 240, 120, 120, 120, 195, 105, 165, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 240, 0, 208, 2, 224, 6, 116, 9, 112, 13, 60, 15, 96, 27, 77, 68, 36, 76, 79, 74, 40, 24, 8, 6, 170, 120, 180, 120, 120, 120, 200, 120, 165, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 240, 0, 192, 2, 202, 6, 116, 9, 72, 13, 60, 15, 96, 27, 77, 53, 29, 62, 71, 62, 56, 25, 13, 6, 167, 120, 180, 120, 120, 120, 242, 150, 150, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 240, 0, 160, 2, 114, 6, 196, 9, 172, 13, 60, 15, 96, 28, 35, 38, 27, 56, 50, 49, 42, 26, 10, 7, 167, 120, 180, 120, 120, 120, 242, 150, 150, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 240, 0, 160, 2, 26, 6, 216, 9, 172, 13, 60, 15, 96, 28, 0, 33, 26, 55, 45, 42, 36, 22, 7, 9, 167, 105, 180, 120, 120, 120, 242, 135, 150, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 215, 0, 5, 0, 1, 0, 153, 0, 198, 1, 44, 3, 255, 9, 194, 11, 151, 14, 244, 26, 50, 54, 22, 57, 64, 38, 35, 20, 14, 6, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 153, 0, 198, 1, 44, 3, 255, 9, 194, 11, 151, 14, 244, 26, 90, 82, 28, 70, 78, 46, 43, 24, 17, 7, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 153, 0, 198, 1, 44, 3, 255, 9, 194, 11, 151, 14, 244, 26, 45, 74, 26, 66, 74, 44, 41, 23, 16, 7, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 153, 0, 176, 1, 56, 3, 216, 9, 194, 11, 151, 14, 244, 26, 30, 45, 20, 54, 57, 34, 31, 18, 13, 5, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 153, 0, 176, 1, 56, 3, 216, 9, 194, 11, 151, 14, 244, 26, 0, 36, 18, 49, 52, 31, 28, 16, 11, 5, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 185, 0, 4, 0, 1, 0, 184, 0, 72, 2, 172, 3, 20, 10, 164, 11, 53, 14, 160, 27, 45, 56, 25, 59, 71, 35, 34, 19, 12, 5, 173, 142, 135, 120, 120, 120, 182, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 184, 0, 72, 2, 172, 3, 20, 10, 164, 11, 53, 14, 160, 27, 80, 106, 34, 81, 98, 48, 46, 27, 17, 7, 173, 142, 135, 120, 120, 120, 182, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 184, 0, 72, 2, 172, 3, 20, 10, 164, 11, 53, 14, 160, 27, 60, 95, 33, 77, 93, 46, 44, 25, 16, 7, 173, 142, 135, 120, 120, 120, 182, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 184, 0, 72, 2, 172, 3, 20, 10, 164, 11, 53, 14, 160, 27, 0, 51, 24, 56, 68, 33, 32, 18, 12, 5, 173, 142, 135, 120, 120, 120, 182, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 175, 0, 4, 0, 1, 0, 172, 0, 64, 1, 228, 2, 96, 9, 12, 13, 60, 15, 144, 26, 45, 39, 2, 67, 43, 20, 20, 26, 8, 7, 177, 117, 100, 120, 120, 120, 177, 117, 115, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 172, 0, 64, 1, 228, 2, 96, 9, 12, 13, 60, 15, 144, 26, 70, 66, 3, 87, 57, 26, 26, 34, 11, 9, 177, 117, 100, 120, 120, 120, 177, 117, 115, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 172, 0, 64, 1, 228, 2, 96, 9, 12, 13, 60, 15, 144, 26, 60, 59, 3, 83, 54, 25, 25, 32, 10, 9, 177, 117, 100, 120, 120, 120, 177, 117, 115, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 172, 0, 64, 1, 228, 2, 96, 9, 12, 13, 60, 15, 144, 26, 0, 37, 2, 65, 42, 19, 19, 25, 8, 7, 177, 117, 100, 120, 120, 120, 177, 117, 115, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 110, 0, 4, 0, 1, 0, 184, 0, 132, 1, 172, 3, 116, 9, 224, 11, 136, 14, 144, 26, 50, 51, 26, 61, 52, 32, 29, 20, 14, 7, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 184, 0, 132, 1, 172, 3, 116, 9, 224, 11, 136, 14, 144, 26, 60, 78, 32, 75, 64, 39, 36, 25, 18, 9, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 184, 0, 132, 1, 172, 3, 116, 9, 224, 11, 136, 14, 144, 26, 60, 67, 30, 71, 57, 37, 33, 23, 16, 8, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 184, 0, 138, 1, 212, 3, 56, 9, 224, 11, 136, 14, 144, 26, 0, 31, 21, 46, 40, 33, 29, 18, 13, 5, 162, 133, 155, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 50, 0, 5, 0, 1, 0, 132, 0, 24, 1, 184, 6, 36, 9, 228, 12, 96, 14, 100, 25, 45, 34, 17, 54, 37, 31, 34, 31, 8, 11, 160, 90, 135, 120, 120, 120, 160, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 132, 0, 24, 1, 184, 6, 36, 9, 228, 12, 96, 14, 100, 25, 50, 59, 22, 71, 47, 41, 45, 41, 11, 15, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 132, 0, 24, 1, 184, 6, 36, 9, 228, 12, 96, 14, 100, 25, 85, 54, 21, 68, 46, 39, 43, 39, 10, 14, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 132, 0, 24, 1, 184, 6, 36, 9, 228, 12, 96, 14, 100, 25, 40, 42, 19, 60, 41, 35, 38, 35, 9, 12, 165, 90, 135, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 132, 0, 24, 1, 184, 6, 36, 9, 228, 12, 96, 14, 100, 25, 0, 29, 15, 50, 34, 29, 31, 29, 7, 10, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 200, 0, 4, 0, 1, 0, 122, 0, 192, 1, 240, 5, 116, 9, 228, 12, 246, 14, 95, 27, 50, 49, 28, 59, 69, 41, 43, 30, 17, 6, 170, 133, 135, 122, 124, 128, 197, 131, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 122, 0, 192, 1, 240, 5, 116, 9, 228, 12, 246, 14, 95, 27, 70, 71, 34, 71, 83, 49, 52, 37, 20, 8, 170, 133, 135, 122, 124, 128, 197, 131, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 122, 0, 192, 1, 240, 5, 116, 9, 228, 12, 246, 14, 95, 27, 80, 64, 32, 68, 79, 47, 49, 35, 19, 7, 170, 133, 135, 122, 124, 128, 197, 131, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 121, 0, 207, 1, 240, 5, 96, 9, 220, 12, 220, 14, 95, 27, 0, 39, 26, 53, 62, 37, 39, 27, 15, 5, 170, 136, 135, 122, 123, 126, 197, 131, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 0, 0, 6, 0, 1, 0, 235, 0, 79, 3, 103, 5, 206, 9, 184, 12, 181, 14, 193, 27, 45, 62, 28, 63, 72, 40, 41, 26, 9, 5, 233, 132, 198, 126, 120, 120, 255, 174, 173, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 235, 0, 79, 3, 103, 5, 206, 9, 184, 12, 181, 14, 193, 27, 60, 108, 37, 83, 94, 54, 54, 35, 13, 6, 233, 132, 198, 126, 120, 120, 255, 174, 173, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 220, 0, 42, 3, 252, 4, 36, 9, 128, 12, 41, 14, 224, 27, 41, 66, 32, 59, 75, 41, 52, 32, 12, 7, 167, 120, 210, 120, 120, 120, 255, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 211, 0, 97, 2, 24, 4, 39, 9, 164, 12, 137, 14, 93, 27, 40, 64, 23, 64, 64, 33, 41, 32, 13, 7, 181, 134, 172, 120, 120, 120, 255, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 201, 0, 152, 1, 52, 3, 43, 9, 201, 12, 233, 14, 217, 26, 60, 51, 15, 65, 51, 24, 29, 31, 12, 7, 195, 149, 134, 120, 120, 120, 141, 120, 147, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 176, 0, 104, 1, 32, 3, 56, 9, 12, 13, 60, 15, 144, 26, 0, 31, 8, 55, 37, 20, 20, 26, 11, 7, 177, 125, 110, 120, 120, 120, 177, 125, 125, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 240, 0, 5, 0, 1, 0, 200, 0, 204, 1, 137, 7, 208, 9, 208, 12, 69, 14, 104, 28, 45, 29, 21, 46, 46, 49, 37, 28, 9, 6, 184, 108, 128, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 200, 0, 204, 1, 137, 7, 208, 9, 208, 12, 69, 14, 104, 28, 50, 84, 36, 79, 78, 83, 63, 48, 15, 11, 184, 108, 128, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 198, 0, 192, 1, 44, 7, 195, 9, 213, 12, 91, 14, 62, 28, 75, 71, 31, 76, 61, 74, 57, 44, 14, 10, 183, 109, 149, 120, 120, 120, 185, 107, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 178, 0, 71, 1, 179, 3, 63, 9, 9, 13, 48, 15, 166, 26, 70, 42, 4, 71, 37, 23, 22, 30, 12, 7, 178, 124, 103, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 178, 0, 71, 1, 179, 3, 63, 9, 9, 13, 48, 15, 166, 26, 0, 30, 3, 60, 31, 19, 18, 25, 10, 6, 178, 124, 103, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 255, 0, 6, 0, 33, 0, 152, 0, 32, 1, 224, 8, 4, 11, 52, 13, 0, 15, 160, 26, 45, 45, 6, 66, 59, 59, 60, 29, 14, 6, 175, 105, 120, 120, 120, 120, 175, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 152, 0, 24, 1, 232, 8, 4, 11, 52, 13, 0, 15, 160, 26, 40, 65, 9, 78, 70, 70, 71, 34, 16, 8, 167, 105, 120, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 152, 0, 24, 1, 172, 8, 240, 10, 32, 13, 0, 15, 160, 26, 50, 64, 9, 78, 64, 70, 71, 34, 16, 8, 167, 105, 130, 120, 120, 120, 167, 90, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 158, 0, 48, 1, 168, 7, 140, 10, 240, 12, 232, 14, 194, 26, 80, 50, 12, 70, 44, 58, 57, 29, 15, 7, 166, 109, 158, 120, 120, 120, 167, 90, 158, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 184, 0, 72, 1, 16, 4, 36, 9, 224, 11, 136, 14, 244, 26, 40, 29, 19, 45, 31, 26, 24, 16, 12, 6, 162, 127, 175, 120, 120, 120, 162, 127, 190, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 176, 0, 72, 1, 189, 3, 92, 8, 204, 11, 141, 14, 88, 27, 0, 30, 21, 52, 36, 20, 14, 11, 8, 7, 155, 105, 97, 120, 120, 120, 110, 105, 97, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 215, 0, 5, 0, 1, 0, 232, 0, 144, 3, 40, 5, 180, 10, 212, 13, 100, 15, 102, 27, 45, 57, 32, 62, 59, 39, 37, 22, 9, 3, 255, 170, 163, 145, 120, 120, 255, 174, 173, 44, 60, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 232, 0, 144, 3, 40, 5, 180, 10, 212, 13, 100, 15, 102, 27, 50, 99, 42, 82, 78, 52, 49, 29, 13, 4, 255, 170, 163, 145, 120, 120, 255, 174, 173, 44, 60, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 225, 0, 72, 3, 138, 5, 220, 10, 212, 13, 80, 15, 120, 27, 60, 66, 39, 73, 57, 49, 46, 28, 12, 5, 247, 162, 178, 142, 120, 120, 255, 174, 190, 44, 55, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 156, 0, 104, 1, 152, 8, 4, 11, 172, 13, 60, 15, 32, 28, 60, 30, 30, 47, 48, 44, 40, 32, 9, 8, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 156, 0, 104, 1, 152, 8, 4, 11, 112, 13, 20, 15, 32, 28, 0, 26, 27, 43, 44, 40, 37, 29, 8, 7, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 245, 0, 5, 0, 1, 0, 200, 0, 208, 1, 188, 7, 216, 9, 248, 12, 66, 14, 128, 28, 45, 29, 21, 47, 46, 50, 38, 29, 8, 6, 185, 107, 127, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 200, 0, 208, 1, 188, 7, 216, 9, 248, 12, 66, 14, 128, 28, 70, 85, 36, 79, 79, 85, 65, 49, 15, 11, 185, 107, 127, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 196, 0, 200, 1, 210, 7, 234, 9, 8, 13, 76, 14, 119, 28, 60, 72, 33, 73, 72, 78, 59, 45, 13, 10, 183, 105, 134, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 156, 0, 88, 1, 172, 8, 140, 10, 152, 13, 166, 14, 32, 28, 70, 45, 33, 56, 50, 60, 46, 33, 10, 8, 167, 90, 195, 120, 120, 120, 122, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 144, 0, 72, 1, 232, 8, 160, 10, 92, 13, 10, 15, 32, 28, 0, 24, 18, 44, 44, 40, 37, 29, 8, 7, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 20, 0, 6, 0, 1, 0, 56, 1, 168, 2, 8, 7, 136, 9, 32, 13, 141, 14, 32, 29, 34, 43, 31, 54, 66, 53, 40, 30, 10, 6, 255, 172, 180, 120, 120, 120, 105, 172, 150, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 56, 1, 168, 2, 8, 7, 136, 9, 32, 13, 141, 14, 32, 29, 20, 75, 42, 72, 88, 70, 53, 40, 14, 8, 255, 172, 180, 120, 120, 120, 105, 172, 150, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 56, 1, 168, 2, 8, 7, 136, 9, 32, 13, 141, 14, 32, 29, 46, 45, 32, 56, 68, 54, 41, 31, 10, 6, 255, 172, 180, 120, 120, 120, 105, 172, 150, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 240, 0, 78, 2, 67, 7, 176, 9, 32, 13, 116, 14, 32, 28, 94, 49, 29, 58, 68, 60, 49, 40, 12, 6, 184, 135, 168, 120, 120, 120, 169, 138, 150, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 5, 0, 156, 0, 99, 1, 141, 8, 140, 10, 112, 13, 0, 15, 32, 28, 40, 34, 29, 50, 45, 54, 41, 29, 9, 7, 167, 90, 195, 120, 120, 120, 122, 120, 135, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 156, 0, 99, 1, 174, 8, 160, 10, 112, 13, 10, 15, 32, 28, 0, 30, 30, 47, 45, 43, 40, 31, 9, 8, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 0, 0, 7, 0, 1, 0, 144, 0, 213, 1, 96, 3, 136, 9, 254, 11, 157, 14, 216, 26, 24, 59, 25, 66, 64, 38, 35, 20, 15, 7, 163, 120, 143, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 144, 0, 213, 1, 96, 3, 136, 9, 254, 11, 157, 14, 216, 26, 55, 83, 30, 79, 76, 45, 41, 24, 17, 8, 163, 120, 143, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 216, 0, 224, 1, 72, 3, 96, 9, 244, 11, 35, 15, 224, 27, 65, 84, 34, 78, 94, 48, 55, 28, 16, 7, 170, 120, 90, 120, 120, 120, 170, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 5, 0, 184, 0, 209, 1, 106, 5, 132, 8, 48, 12, 191, 14, 64, 27, 25, 50, 37, 69, 40, 60, 39, 22, 15, 7, 167, 100, 152, 120, 120, 120, 137, 115, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 208, 0, 149, 1, 246, 6, 152, 8, 128, 12, 191, 14, 64, 27, 48, 46, 32, 58, 36, 60, 35, 23, 14, 7, 155, 105, 150, 120, 120, 120, 125, 150, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 160, 0, 54, 1, 199, 7, 136, 9, 228, 12, 191, 14, 64, 27, 30, 33, 24, 51, 34, 29, 39, 25, 16, 7, 155, 105, 135, 120, 120, 120, 125, 105, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 1, 0, 160, 0, 54, 1, 248, 7, 136, 9, 72, 13, 191, 14, 64, 27, 0, 30, 22, 48, 32, 28, 37, 24, 15, 7, 155, 105, 135, 120, 120, 120, 125, 105, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 232, 65, 0, 191, 129, 244, 194, 182, 76, 250, 23, 8, 250, 0, 5, 0, 1, 0, 175, 0, 65, 1, 197, 3, 73, 9, 19, 13, 53, 15, 164, 26, 45, 37, 3, 65, 33, 20, 20, 27, 11, 6, 177, 123, 107, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 175, 0, 65, 1, 197, 3, 73, 9, 19, 13, 53, 15, 164, 26, 80, 75, 5, 94, 48, 29, 28, 39, 15, 9, 177, 123, 107, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 173, 0, 70, 1, 126, 4, 196, 9, 38, 13, 32, 15, 221, 26, 80, 56, 8, 79, 36, 30, 28, 34, 13, 8, 175, 118, 150, 120, 120, 120, 177, 125, 147, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 158, 0, 80, 1, 12, 8, 130, 10, 86, 13, 13, 15, 255, 27, 45, 31, 15, 53, 30, 37, 37, 31, 9, 8, 168, 109, 155, 120, 120, 120, 177, 109, 152, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 156, 0, 72, 1, 112, 8, 160, 10, 92, 13, 10, 15, 32, 28, 0, 31, 18, 55, 33, 36, 37, 29, 8, 7, 167, 105, 155, 120, 120, 120, 122, 105, 140, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 70, 0, 3, 0, 5, 0, 124, 0, 72, 1, 170, 2, 20, 10, 8, 12, 10, 15, 32, 27, 40, 22, 14, 46, 42, 20, 18, 13, 9, 3, 141, 97, 120, 120, 120, 120, 60, 97, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 124, 0, 72, 1, 170, 2, 20, 10, 8, 12, 10, 15, 32, 27, 30, 35, 18, 58, 52, 26, 23, 16, 12, 4, 141, 97, 120, 120, 120, 120, 60, 97, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 184, 0, 189, 1, 134, 3, 60, 10, 88, 12, 141, 14, 128, 26, 0, 72, 32, 68, 70, 45, 36, 28, 20, 8, 162, 135, 150, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 81, 2, 31, 0, 5, 251, 3, 14, 16, 10, 2, 0, 251, 4, 5, 238, 6, 31, 245, 248, 21, 249, 255, 20, 1, 2, 248, 237, 9, 252, 240, 21, 12, 254, 3, 231, 222, 231, 223, 229, 207, 194, 231, 228, 219, 250, 253, 2, 10, 249, 12, 24, 6, 23, 19, 16, 54, 30, 0, 41, 49, 22, 14, 5, 11, 23, 22, 18, 7, 12, 22, 7, 4, 13, 9, 4, 251, 255, 0, 238, 239, 229, 222, 17, 255, 189, 238, 253, 202, 244, 3, 212, 230, 1, 8, 7, 238, 1, 35, 14, 5, 12, 6, 0, 246, 9, 18, 249, 26, 22, 209, 0, 46, 252, 6, 15, 229, 15, 49, 245, 217, 248, 12, 2, 241, 240, 238, 244, 10, 1, 223, 229, 9, 7, 236, 250, 248, 214, 0, 24, 232, 18, 64, 252, 249, 46, 31, 29, 53, 54, 44, 42, 58, 43, 34, 91, 58, 225, 23, 62, 1, 6, 247, 164, 185, 34, 74, 0, 178, 181, 177, 157, 154, 132, 186, 250, 166, 136, 222, 211, 184, 224, 239, 243, 232, 224, 2, 12, 22, 52, 54, 76, 50, 233, 52, 125, 41, 37, 77, 19, 46, 107, 41, 15, 77, 72, 32, 34, 16, 238, 21, 60, 2, 234, 22, 240, 188, 246, 25, 224, 189, 214, 236, 220, 203, 214, 237, 246, 215, 182, 223, 254, 206, 210, 8, 250, 232, 1, 253, 0, 35, 30, 13, 7, 4, 23, 29, 12, 9, 3, 28, 55, 248, 228, 53, 44, 235, 247, 18, 30, 0, 213, 19, 51, 219, 216, 12, 248, 240, 242, 238, 16, 11, 238, 3, 10, 252, 249, 0, 21, 250, 223, 45, 63, 238, 237, 12, 20, 41, 11, 243, 17, 253, 226, 251, 255, 255, 0, 238, 226, 220, 3, 45, 230, 204, 23, 0, 234, 40, 12, 248, 44, 1, 218, 11, 11, 247, 8, 31, 38, 238, 215, 15, 232, 185, 0, 4, 241, 49, 5, 190, 20, 57, 236, 241, 28, 249, 228, 8, 245, 204, 29, 81, 233, 208, 36, 11, 225, 7, 3, 246, 26, 5, 220, 253, 15, 236, 245, 28, 11, 242, 1, 253, 232, 9, 32, 248, 255, 47, 5, 227, 34, 25, 223, 27, 56, 239, 245, 24, 246, 0, 41, 15, 240, 14, 41, 246, 204, 252, 17, 244, 252, 238, 219, 24, 33, 214, 223, 9, 232, 220, 11, 15, 240, 244, 242, 232, 15, 31, 245, 252, 35, 18, 232, 223, 247, 4, 6, 33, 24, 251, 20, 250, 208, 40, 69, 243, 12, 26, 211, 249, 46, 249, 233, 14, 30, 12, 230, 222, 229, 235, 34, 39, 216, 225, 20, 238, 232, 41, 27, 210, 223, 25, 6, 223, 2, 19, 242, 7, 27, 233, 239, 31, 250, 230, 36, 28, 231, 8, 40, 4, 253, 10, 252, 0, 41, 50, 246, 212, 12, 15, 204, 240, 32, 231, 238, 18, 211, 230, 54, 0, 216, 21, 12, 227, 237, 251, 2, 0, 9, 35, 251, 224, 27, 18, 237, 22, 7, 221, 12, 18, 229, 3, 40, 5, 231, 18, 44, 225, 218, 67, 25, 169, 224, 23, 0, 37, 19, 201, 6, 63, 231, 213, 46, 30, 223, 1, 15, 212, 238, 53, 16, 216, 250, 13, 238, 252, 26, 247, 237, 26, 4, 224, 16, 24, 228, 1, 36, 239, 226, 12, 16, 11, 13, 241, 249, 42, 27, 232, 236, 4, 14, 18, 3, 246, 2, 18, 255, 222, 248, 29, 244, 219, 0, 250, 251, 29, 240, 206, 13, 34, 252, 241, 246, 250, 252, 8, 0, 0, 0, 45, 0, 3, 0, 5, 0, 136, 0, 200, 0, 64, 6, 40, 10, 232, 13, 24, 16, 124, 21, 45, 5, 8, 15, 6, 4, 2, 2, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 50, 85, 48, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 136, 0, 200, 0, 64, 6, 40, 10, 232, 13, 24, 16, 124, 21, 0, 14, 14, 24, 10, 7, 3, 3, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 50, 85, 48, 0, 0, 0, 0, 60, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 136, 0, 200, 0, 64, 6, 40, 10, 232, 13, 24, 16, 124, 21, 0, 14, 14, 24, 10, 7, 3, 3, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 50, 85, 48, 0, 0, 0, 0, 60, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 24, 0, 3, 0, 5, 0, 136, 0, 200, 0, 64, 6, 40, 10, 232, 13, 24, 16, 124, 21, 25, 15, 14, 25, 10, 7, 3, 3, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 50, 85, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 136, 0, 200, 0, 64, 6, 40, 10, 232, 13, 24, 16, 124, 21, 0, 15, 14, 25, 10, 7, 3, 3, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 50, 85, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 136, 0, 200, 0, 64, 6, 40, 10, 232, 13, 24, 16, 124, 21, 0, 15, 14, 25, 10, 7, 3, 3, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 50, 85, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 45, 0, 3, 0, 5, 0, 116, 0, 232, 0, 164, 6, 176, 9, 152, 13, 60, 15, 124, 21, 45, 2, 11, 6, 4, 2, 2, 2, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 116, 0, 232, 0, 164, 6, 216, 9, 192, 13, 80, 15, 124, 21, 0, 7, 17, 10, 7, 14, 3, 3, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 116, 0, 232, 0, 164, 6, 216, 9, 192, 13, 80, 15, 124, 21, 0, 7, 17, 10, 7, 3, 3, 3, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 24, 0, 3, 0, 5, 0, 136, 0, 216, 1, 64, 6, 196, 9, 128, 12, 100, 15, 124, 21, 25, 14, 3, 36, 21, 7, 3, 7, 0, 0, 200, 212, 187, 187, 205, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 136, 0, 216, 1, 64, 6, 196, 9, 128, 12, 100, 15, 124, 21, 0, 11, 3, 32, 21, 7, 3, 7, 0, 0, 200, 212, 187, 187, 205, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 136, 0, 216, 1, 64, 6, 196, 9, 128, 12, 100, 15, 124, 21, 0, 11, 3, 32, 21, 7, 3, 7, 0, 0, 200, 212, 187, 187, 205, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 185, 3, 16, 0, 255, 254, 255, 0, 0, 2, 3, 4, 4, 4, 3, 3, 3, 1, 1, 1, 1, 0, 0, 255, 253, 251, 252, 253, 254, 253, 254, 255, 255, 1, 4, 4, 6, 4, 5, 3, 3, 5, 4, 2, 0, 1, 0, 255, 255, 253, 252, 250, 251, 249, 251, 252, 255, 0, 2, 3, 5, 3, 5, 8, 12, 12, 13, 15, 16, 14, 17, 233, 133, 161, 0, 56, 75, 57, 15, 3, 245, 228, 211, 211, 248, 30, 57, 51, 22, 255, 233, 218, 213, 237, 5, 23, 25, 25, 18, 1, 240, 222, 226, 240, 2, 18, 31, 27, 12, 250, 250, 245, 243, 248, 254, 4, 9, 8, 14, 8, 255, 240, 241, 250, 0, 2, 8, 10, 5, 3, 0, 254, 251, 247, 247, 0, 6, 10, 11, 5, 1, 254, 247, 255, 1, 0, 2, 0, 1, 4, 0, 254, 248, 250, 253, 254, 7, 13, 9, 6, 1, 251, 249, 248, 250, 253, 3, 8, 14, 11, 4, 251, 247, 248, 245, 250, 1, 7, 10, 13, 5, 1, 250, 244, 249, 253, 0, 9, 14, 14, 5, 0, 238, 246, 249, 246, 250, 4, 16, 16, 7, 7, 4, 252, 249, 243, 242, 250, 1, 8, 12, 8, 4, 0, 246, 0, 254, 4, 16, 20, 3, 223, 7, 7, 253, 0, 235, 234, 1, 2, 17, 13, 1, 0, 254, 253, 0, 6, 20, 21, 11, 5, 0, 243, 226, 224, 233, 253, 13, 20, 20, 13, 2, 246, 249, 252, 0, 8, 7, 15, 13, 254, 254, 244, 237, 245, 251, 9, 15, 10, 14, 2, 245, 250, 246, 250, 2, 3, 6, 5, 0, 254, 251, 252, 254, 4, 15, 14, 8, 252, 254, 251, 248, 251, 252, 2, 5, 0, 2, 249, 253, 0, 255, 0, 1, 9, 19, 8, 3, 245, 243, 247, 251, 5, 6, 15, 9, 250, 253, 3, 241, 244, 249, 11, 1, 251, 24, 8, 240, 4, 4, 5, 14, 251, 1, 18, 237, 0, 0, 244, 247, 251, 251, 8, 6, 238, 250, 1, 8, 16, 8, 253, 2, 22, 12, 15, 0, 250, 12, 26, 12, 184, 158, 200, 25, 50, 34, 29, 6, 12, 2, 0, 252, 243, 255, 14, 30, 20, 251, 218, 219, 246, 251, 16, 21, 20, 253, 0, 4, 242, 223, 232, 7, 26, 27, 5, 8, 7, 248, 237, 243, 14, 21, 13, 6, 248, 247, 236, 246, 255, 15, 11, 11, 10, 255, 233, 193, 224, 12, 33, 31, 31, 28, 7, 8, 255, 2, 222, 207, 253, 22, 29, 2, 255, 245, 234, 243, 0, 10, 251, 253, 9, 33, 23, 252, 244, 246, 0, 2, 5, 12, 5, 246, 243, 252, 254, 0, 1, 0, 254, 255, 2, 4, 7, 253, 249, 2, 9, 9, 4, 255, 255, 251, 254, 3, 7, 2, 250, 250, 2, 2, 247, 251, 3, 3, 1, 4, 2, 4, 0, 0, 3, 2, 0, 0, 1, 0, 250, 254, 0, 7, 2, 252, 1, 3, 1, 252, 252, 0, 1, 5, 7, 8, 1, 254, 248, 251, 255, 1, 4, 3, 2, 3, 2, 0, 252, 251, 252, 1, 3, 4, 0, 4, 0, 2, 252, 254, 0, 2, 1, 0, 2, 0, 1, 253, 250, 7, 2, 254, 3, 253, 251, 2, 4, 0, 13, 2, 253, 251, 247, 255, 8, 1, 251, 0, 4, 4, 7, 254, 0, 0, 254, 249, 254, 0, 3, 14, 8, 252, 253, 253, 246, 251, 252, 255, 11, 16, 8, 0, 244, 252, 0, 3, 4, 4, 4, 255, 251, 252, 1, 0, 0, 252, 254, 3, 5, 6, 4, 255, 248, 248, 7, 2, 255, 255, 12, 10, 4, 254, 245, 248, 252, 0, 0, 7, 4, 0, 0, 253, 2, 0, 253, 255, 0, 3, 2, 2, 6, 7, 254, 253, 255, 248, 250, 7, 9, 2, 1, 0, 4, 5, 253, 244, 246, 255, 1, 9, 13, 0, 255, 255, 0, 254, 250, 0, 7, 6, 2, 0, 1, 1, 254, 246, 245, 2, 15, 11, 255, 249, 249, 5, 3, 255, 254, 253, 0, 8, 2, 5, 1, 251, 255, 0, 1, 5, 1, 252, 252, 0, 3, 0, 2, 8, 0, 253, 0, 255, 2, 253, 255, 0, 0, 0, 1, 2, 10, 0, 251, 255, 4, 7, 3, 249, 246, 250, 2, 11, 9, 253, 246, 255, 8, 6, 1, 253, 253, 3, 254, 2, 0, 254, 252, 2, 7, 8, 1, 249, 253, 0, 0, 0, 3, 6, 0, 254, 255, 1, 1, 0, 254, 250, 254, 5, 10, 9, 0, 246, 252, 2, 5, 5, 255, 255, 0, 251, 255, 5, 255, 0, 3, 2, 4, 254, 252, 0, 0, 0, 3, 2, 5, 0, 251, 0, 253, 0, 0, 0, 3, 3, 5, 4, 0, 253, 252, 250, 0, 7, 3, 2, 0, 254, 0, 255, 253, 253, 255, 3, 3, 5, 5, 0, 254, 253, 251, 3, 9, 7, 0, 253, 252, 251, 251, 253, 254, 2, 8, 9, 4, 2, 254, 252, 254, 255, 2, 5, 5, 0, 255, 250, 253, 2, 2, 1, 1, 0, 3, 1, 0, 253, 251, 254, 1, 5, 5, 0, 249, 254, 3, 5, 4, 3, 1, 254, 254, 255, 0, 0, 0, 0, 6, 2, 254, 253, 254, 253, 0, 2, 5, 7, 0, 255, 254, 253, 0, 0, 3, 7, 4, 251, 249, 254, 3, 6, 3, 2, 0, 254, 0, 254, 252, 252, 255, 1, 5, 8, 6, 2, 0, 253, 251, 253, 254, 3, 6, 5, 4, 0, 251, 253, 255, 252, 0, 1, 2, 5, 2, 1, 0, 254, 0, 0, 2, 0, 254, 0, 0, 0, 255, 5, 5, 2, 0, 253, 0, 0, 254, 254, 0, 0, 0, 0, 0, 3, 0, 5, 0, 128, 0, 64, 1, 196, 4, 244, 6, 148, 12, 20, 15, 225, 25, 20, 24, 6, 51, 24, 18, 0, 9, 3, 6, 105, 155, 167, 142, 180, 175, 105, 155, 167, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 136, 0, 208, 1, 80, 5, 228, 7, 108, 12, 216, 14, 225, 25, 30, 67, 30, 90, 45, 30, 21, 15, 3, 9, 105, 125, 167, 142, 150, 175, 105, 125, 167, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 136, 0, 240, 1, 80, 5, 12, 8, 108, 12, 56, 14, 225, 25, 0, 70, 30, 84, 51, 33, 18, 18, 3, 9, 105, 170, 167, 157, 150, 175, 105, 170, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 0, 0, 3, 0, 5, 0, 228, 0, 80, 1, 136, 4, 164, 6, 168, 12, 236, 14, 200, 25, 20, 31, 18, 39, 27, 15, 0, 6, 6, 6, 150, 252, 157, 160, 150, 175, 150, 252, 157, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 224, 0, 32, 2, 0, 5, 68, 7, 128, 12, 76, 14, 200, 25, 30, 77, 15, 87, 66, 36, 15, 18, 6, 6, 150, 167, 157, 160, 150, 175, 150, 167, 157, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 232, 0, 168, 2, 0, 5, 252, 8, 128, 12, 36, 14, 200, 25, 0, 56, 45, 60, 60, 27, 27, 21, 3, 6, 150, 167, 207, 255, 182, 175, 150, 167, 207, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 0, 0, 4, 0, 5, 0, 232, 0, 136, 1, 196, 4, 164, 6, 184, 12, 220, 15, 124, 21, 20, 31, 30, 36, 24, 15, 0, 3, 0, 0, 180, 152, 180, 150, 250, 175, 180, 152, 180, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 0, 1, 248, 1, 160, 5, 52, 8, 184, 12, 200, 15, 124, 21, 20, 61, 27, 69, 36, 24, 9, 12, 3, 3, 197, 152, 217, 210, 250, 175, 197, 152, 217, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 5, 0, 0, 1, 72, 2, 4, 6, 132, 8, 184, 12, 90, 14, 124, 21, 24, 80, 30, 84, 54, 39, 24, 15, 3, 3, 197, 152, 217, 210, 250, 175, 197, 152, 217, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 176, 0, 120, 2, 121, 6, 64, 9, 184, 12, 90, 14, 124, 21, 0, 61, 30, 69, 66, 45, 42, 27, 3, 3, 252, 152, 157, 210, 250, 175, 252, 152, 157, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 0, 0, 3, 0, 5, 0, 208, 0, 136, 1, 176, 4, 164, 6, 80, 12, 185, 15, 169, 26, 20, 30, 27, 42, 21, 12, 0, 3, 0, 6, 150, 147, 172, 160, 150, 175, 150, 147, 172, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 208, 0, 192, 1, 180, 5, 52, 8, 80, 12, 185, 15, 169, 26, 30, 39, 27, 51, 30, 21, 15, 12, 0, 6, 150, 185, 152, 160, 150, 175, 150, 185, 152, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 208, 0, 240, 1, 224, 6, 16, 9, 148, 12, 76, 14, 88, 27, 0, 58, 27, 75, 33, 33, 30, 24, 6, 6, 150, 142, 170, 160, 150, 175, 150, 142, 170, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 0, 0, 3, 0, 5, 0, 200, 0, 136, 1, 76, 4, 164, 6, 212, 12, 14, 15, 150, 25, 19, 27, 39, 27, 18, 12, 0, 3, 6, 3, 150, 155, 195, 137, 255, 252, 150, 155, 195, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 200, 0, 204, 1, 176, 4, 168, 7, 212, 12, 14, 15, 150, 25, 30, 71, 39, 72, 51, 21, 15, 12, 6, 6, 150, 155, 195, 137, 255, 252, 150, 155, 195, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 200, 0, 80, 2, 252, 3, 76, 9, 88, 12, 196, 14, 150, 25, 0, 78, 40, 78, 52, 23, 20, 20, 5, 5, 150, 155, 162, 185, 217, 210, 150, 155, 162, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 0, 0, 3, 0, 5, 0, 128, 0, 64, 1, 196, 4, 164, 6, 148, 12, 20, 15, 225, 25, 20, 24, 6, 51, 24, 18, 0, 9, 3, 6, 105, 155, 167, 142, 180, 175, 105, 155, 167, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 136, 0, 208, 1, 80, 5, 228, 7, 108, 12, 216, 14, 225, 25, 30, 67, 30, 90, 45, 30, 21, 15, 3, 9, 105, 125, 167, 142, 150, 175, 105, 125, 167, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 136, 0, 240, 1, 80, 5, 12, 8, 108, 12, 56, 14, 225, 25, 0, 70, 30, 84, 51, 33, 18, 18, 3, 9, 105, 170, 167, 157, 150, 175, 105, 170, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 139, 0, 4, 0, 1, 0, 128, 0, 40, 2, 161, 5, 96, 9, 188, 12, 116, 14, 96, 27, 50, 59, 34, 66, 80, 45, 47, 36, 16, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 128, 0, 40, 2, 161, 5, 96, 9, 188, 12, 116, 14, 96, 27, 50, 81, 40, 76, 93, 52, 55, 42, 15, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 128, 0, 40, 2, 161, 5, 96, 9, 188, 12, 116, 14, 96, 27, 40, 69, 37, 71, 86, 48, 51, 39, 14, 7, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 128, 0, 40, 2, 161, 5, 96, 9, 188, 12, 116, 14, 96, 27, 0, 46, 31, 58, 70, 39, 35, 32, 16, 9, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 0, 0, 3, 0, 1, 0, 196, 0, 229, 1, 255, 3, 0, 10, 28, 12, 116, 14, 160, 26, 53, 62, 35, 71, 73, 28, 34, 20, 9, 8, 162, 120, 132, 120, 120, 120, 162, 90, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 7, 0, 208, 0, 229, 1, 123, 3, 220, 10, 204, 11, 141, 14, 0, 26, 75, 64, 38, 81, 60, 33, 35, 16, 11, 8, 162, 105, 87, 120, 120, 120, 162, 75, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 136, 0, 194, 1, 24, 3, 164, 11, 68, 12, 241, 14, 0, 26, 0, 27, 28, 46, 28, 31, 28, 16, 11, 8, 162, 135, 87, 120, 120, 120, 162, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 151, 0, 4, 0, 1, 0, 32, 1, 88, 3, 40, 5, 140, 10, 112, 13, 191, 14, 32, 28, 46, 50, 30, 67, 55, 40, 30, 19, 9, 4, 217, 155, 105, 120, 120, 120, 247, 170, 165, 44, 65, 75, 130, 54, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 32, 1, 88, 3, 40, 5, 140, 10, 112, 13, 191, 14, 32, 28, 40, 84, 40, 87, 72, 52, 39, 24, 12, 6, 217, 155, 105, 120, 120, 120, 247, 170, 165, 44, 65, 75, 130, 54, 0, 0, 0, 0, 50, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 32, 1, 88, 3, 40, 5, 140, 10, 112, 13, 191, 14, 32, 28, 65, 82, 39, 86, 71, 52, 38, 24, 11, 5, 217, 155, 105, 120, 120, 120, 247, 170, 165, 44, 65, 75, 130, 53, 0, 0, 0, 0, 50, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 32, 1, 88, 3, 40, 5, 140, 10, 112, 13, 191, 14, 32, 28, 0, 50, 30, 67, 55, 40, 30, 19, 9, 4, 217, 155, 105, 120, 120, 120, 247, 170, 165, 44, 65, 75, 130, 53, 0, 0, 0, 0, 50, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 150, 0, 4, 0, 1, 0, 186, 0, 146, 2, 128, 5, 156, 9, 248, 12, 141, 14, 160, 27, 50, 40, 30, 58, 58, 36, 29, 23, 13, 0, 180, 150, 172, 120, 120, 120, 200, 120, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 186, 0, 146, 2, 128, 5, 156, 9, 248, 12, 141, 14, 160, 27, 60, 78, 42, 80, 80, 51, 40, 33, 18, 0, 180, 150, 172, 120, 120, 120, 200, 120, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 186, 0, 146, 2, 128, 5, 156, 9, 248, 12, 141, 14, 160, 27, 40, 55, 35, 67, 67, 43, 33, 27, 15, 0, 180, 150, 172, 120, 120, 120, 200, 120, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 186, 0, 146, 2, 128, 5, 156, 9, 248, 12, 141, 14, 160, 27, 0, 33, 30, 51, 51, 33, 28, 23, 12, 0, 180, 150, 177, 120, 120, 120, 200, 120, 172, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 200, 0, 4, 0, 1, 0, 248, 0, 134, 2, 244, 6, 196, 9, 52, 13, 196, 14, 64, 28, 45, 39, 28, 52, 57, 51, 36, 22, 7, 5, 193, 135, 180, 120, 120, 120, 217, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 248, 0, 134, 2, 244, 6, 196, 9, 52, 13, 196, 14, 64, 28, 85, 83, 41, 76, 83, 75, 53, 33, 11, 7, 193, 135, 180, 120, 120, 120, 217, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 248, 0, 134, 2, 244, 6, 196, 9, 52, 13, 196, 14, 64, 28, 70, 67, 37, 68, 75, 67, 47, 29, 10, 6, 193, 135, 180, 120, 120, 120, 217, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 248, 0, 134, 2, 244, 6, 196, 9, 52, 13, 196, 14, 64, 28, 0, 31, 25, 46, 50, 45, 32, 20, 6, 4, 193, 135, 180, 120, 120, 120, 217, 180, 150, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 100, 0, 4, 0, 1, 0, 192, 0, 144, 1, 168, 7, 40, 10, 92, 13, 120, 15, 96, 25, 50, 51, 30, 72, 58, 50, 42, 30, 12, 5, 160, 90, 120, 120, 120, 120, 130, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 192, 0, 152, 1, 148, 7, 40, 10, 92, 13, 120, 15, 96, 25, 60, 92, 41, 98, 79, 68, 57, 41, 17, 7, 160, 90, 120, 120, 120, 120, 130, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 192, 0, 152, 1, 148, 7, 40, 10, 92, 13, 120, 15, 96, 25, 40, 74, 37, 88, 71, 61, 51, 37, 15, 6, 160, 90, 120, 120, 120, 120, 130, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 192, 0, 152, 1, 148, 7, 40, 10, 92, 13, 120, 15, 96, 25, 0, 43, 28, 67, 54, 46, 39, 28, 11, 5, 160, 90, 120, 120, 120, 120, 130, 90, 120, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 149, 0, 4, 0, 1, 0, 176, 0, 152, 1, 128, 7, 0, 10, 92, 13, 20, 15, 96, 25, 50, 53, 26, 83, 45, 45, 42, 25, 14, 7, 150, 105, 120, 120, 120, 120, 120, 60, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 192, 0, 152, 1, 128, 7, 20, 10, 92, 13, 120, 15, 96, 25, 60, 98, 38, 106, 57, 67, 67, 39, 16, 7, 160, 90, 120, 120, 120, 120, 130, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 192, 0, 160, 1, 108, 7, 20, 10, 92, 13, 120, 15, 96, 25, 40, 73, 35, 90, 49, 57, 57, 33, 13, 7, 160, 97, 120, 120, 120, 120, 130, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 192, 0, 160, 1, 108, 7, 20, 10, 92, 13, 120, 15, 96, 25, 0, 50, 31, 75, 42, 47, 47, 27, 10, 8, 160, 105, 120, 120, 120, 120, 130, 60, 120, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 175, 0, 4, 0, 1, 0, 170, 0, 120, 1, 178, 7, 25, 10, 37, 13, 55, 15, 96, 25, 45, 44, 25, 67, 44, 47, 45, 28, 11, 5, 160, 91, 120, 131, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 170, 0, 120, 1, 178, 7, 25, 10, 37, 13, 55, 15, 96, 25, 70, 88, 36, 95, 63, 66, 64, 39, 16, 7, 160, 91, 120, 131, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 170, 0, 120, 1, 178, 7, 25, 10, 37, 13, 55, 15, 96, 25, 60, 70, 32, 85, 56, 59, 58, 35, 14, 6, 160, 91, 120, 131, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 170, 0, 120, 1, 178, 7, 25, 10, 37, 13, 55, 15, 96, 25, 0, 35, 22, 60, 39, 42, 41, 25, 10, 4, 160, 91, 120, 131, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 150, 0, 4, 0, 1, 0, 232, 0, 218, 2, 222, 3, 60, 10, 224, 11, 222, 13, 160, 28, 50, 64, 34, 59, 74, 34, 35, 24, 9, 7, 230, 150, 120, 120, 120, 120, 185, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 232, 0, 158, 2, 178, 3, 60, 10, 224, 11, 222, 13, 32, 28, 60, 103, 27, 76, 97, 40, 40, 26, 14, 6, 182, 150, 120, 120, 120, 120, 182, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 232, 0, 158, 2, 178, 3, 60, 10, 224, 11, 222, 13, 32, 28, 40, 102, 27, 76, 97, 39, 40, 26, 14, 6, 182, 150, 120, 120, 120, 120, 182, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 228, 0, 118, 2, 134, 3, 140, 10, 224, 11, 66, 14, 32, 28, 0, 56, 31, 52, 75, 41, 39, 25, 13, 9, 177, 150, 120, 120, 120, 120, 177, 75, 120, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 185, 0, 4, 0, 1, 0, 216, 0, 142, 2, 250, 4, 26, 10, 32, 13, 20, 15, 210, 27, 45, 45, 30, 55, 66, 39, 38, 24, 13, 5, 185, 160, 141, 120, 120, 120, 235, 150, 118, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 216, 0, 142, 2, 250, 4, 26, 10, 12, 13, 20, 15, 210, 27, 80, 86, 39, 78, 90, 51, 50, 31, 18, 7, 185, 160, 141, 120, 120, 120, 235, 150, 118, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 216, 0, 142, 2, 250, 4, 26, 10, 32, 13, 20, 15, 210, 27, 60, 75, 37, 73, 84, 47, 47, 29, 16, 6, 185, 160, 141, 120, 120, 120, 235, 150, 118, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 216, 0, 142, 2, 250, 4, 26, 10, 32, 13, 20, 15, 210, 27, 0, 39, 28, 51, 61, 36, 36, 22, 12, 5, 185, 160, 141, 120, 120, 120, 235, 150, 118, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 140, 0, 4, 0, 1, 0, 184, 0, 189, 1, 134, 3, 60, 10, 88, 12, 141, 14, 128, 26, 50, 57, 28, 61, 63, 40, 32, 25, 18, 7, 162, 135, 150, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 184, 0, 189, 1, 134, 3, 60, 10, 88, 12, 141, 14, 128, 26, 50, 83, 38, 71, 75, 52, 42, 33, 24, 6, 162, 135, 150, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 184, 0, 189, 1, 134, 3, 60, 10, 88, 12, 141, 14, 128, 26, 40, 69, 35, 65, 68, 47, 39, 30, 22, 6, 162, 135, 150, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 184, 0, 189, 1, 134, 3, 60, 10, 88, 12, 141, 14, 128, 26, 0, 47, 26, 56, 57, 37, 29, 23, 16, 7, 162, 135, 150, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 0, 0, 6, 0, 1, 0, 244, 0, 77, 3, 87, 4, 160, 10, 148, 12, 41, 14, 96, 27, 50, 59, 26, 60, 76, 28, 19, 17, 5, 7, 225, 195, 120, 120, 120, 120, 165, 105, 120, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 244, 0, 7, 3, 43, 4, 240, 10, 148, 12, 41, 14, 96, 27, 45, 107, 29, 67, 105, 48, 41, 41, 13, 6, 200, 165, 135, 120, 120, 120, 200, 120, 135, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 0, 1, 27, 3, 255, 3, 64, 11, 228, 12, 41, 14, 224, 27, 59, 101, 33, 69, 92, 41, 45, 45, 11, 6, 200, 135, 150, 120, 120, 120, 200, 75, 210, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 228, 0, 7, 3, 10, 4, 240, 10, 52, 13, 41, 14, 224, 27, 58, 94, 32, 72, 86, 48, 50, 47, 11, 6, 200, 135, 150, 120, 120, 120, 200, 90, 135, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 228, 0, 243, 2, 255, 3, 160, 10, 148, 12, 41, 14, 224, 27, 38, 63, 32, 63, 82, 35, 38, 36, 13, 7, 167, 135, 120, 120, 120, 120, 167, 75, 135, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 164, 0, 27, 3, 98, 4, 20, 10, 148, 12, 41, 14, 224, 27, 0, 39, 23, 59, 58, 28, 24, 24, 7, 7, 167, 120, 120, 120, 120, 120, 227, 105, 105, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 0, 0, 5, 0, 1, 0, 140, 0, 244, 1, 172, 5, 36, 9, 248, 12, 41, 14, 32, 27, 45, 48, 30, 63, 56, 56, 40, 40, 15, 8, 167, 135, 180, 120, 120, 120, 167, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 140, 0, 224, 1, 128, 5, 16, 9, 148, 12, 41, 14, 32, 27, 48, 69, 26, 68, 82, 75, 61, 50, 25, 8, 170, 135, 165, 120, 120, 120, 140, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 172, 0, 224, 1, 128, 5, 16, 9, 168, 12, 41, 14, 160, 27, 41, 75, 33, 70, 90, 74, 60, 53, 17, 8, 170, 120, 150, 120, 120, 120, 170, 120, 90, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 204, 0, 249, 1, 139, 5, 16, 9, 168, 12, 41, 14, 160, 27, 78, 53, 34, 68, 67, 54, 45, 35, 15, 8, 170, 120, 150, 120, 120, 120, 140, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 204, 0, 33, 2, 139, 5, 16, 9, 168, 12, 141, 14, 160, 27, 0, 35, 31, 52, 54, 52, 38, 30, 11, 8, 170, 135, 150, 120, 120, 120, 140, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 76, 0, 4, 0, 45, 0, 40, 0, 112, 1, 68, 3, 36, 9, 28, 12, 216, 14, 32, 28, 0, 45, 19, 77, 28, 16, 16, 12, 8, 0, 120, 105, 120, 120, 120, 120, 120, 105, 120, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 37, 0, 40, 0, 112, 1, 68, 3, 36, 9, 28, 12, 216, 14, 32, 28, 40, 45, 19, 77, 28, 16, 16, 12, 8, 0, 120, 105, 120, 120, 120, 120, 120, 105, 120, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 37, 0, 72, 0, 104, 1, 153, 4, 36, 9, 148, 12, 166, 14, 192, 27, 36, 46, 16, 80, 33, 22, 26, 17, 13, 0, 120, 90, 120, 120, 120, 120, 120, 90, 105, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 40, 0, 79, 1, 221, 7, 96, 9, 208, 12, 116, 14, 192, 27, 0, 90, 9, 86, 74, 89, 97, 58, 13, 0, 120, 120, 120, 120, 120, 120, 120, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 0, 0, 5, 0, 33, 0, 152, 0, 48, 1, 174, 8, 200, 10, 92, 13, 135, 15, 160, 26, 52, 58, 8, 76, 67, 65, 53, 30, 14, 8, 180, 120, 120, 120, 120, 120, 180, 105, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 152, 0, 40, 1, 172, 8, 4, 11, 92, 13, 135, 15, 160, 26, 75, 69, 8, 83, 73, 74, 75, 36, 17, 8, 167, 105, 120, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 152, 0, 39, 1, 229, 8, 4, 11, 12, 13, 216, 14, 64, 26, 40, 43, 8, 60, 60, 63, 63, 34, 11, 8, 167, 105, 120, 120, 120, 120, 167, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 125, 0, 0, 1, 56, 9, 4, 11, 20, 13, 0, 15, 64, 26, 40, 33, 8, 52, 52, 53, 54, 29, 11, 8, 167, 99, 114, 120, 120, 120, 167, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 84, 0, 216, 0, 96, 9, 4, 11, 32, 13, 60, 15, 64, 26, 0, 20, 8, 40, 41, 39, 40, 23, 10, 8, 167, 90, 105, 120, 120, 120, 167, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 5, 0, 1, 0, 152, 0, 209, 1, 112, 3, 80, 10, 104, 11, 141, 14, 192, 27, 43, 48, 27, 57, 61, 29, 29, 16, 12, 6, 162, 135, 165, 120, 120, 120, 117, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 168, 0, 209, 1, 68, 3, 80, 10, 104, 11, 141, 14, 32, 27, 93, 92, 29, 72, 80, 48, 44, 26, 16, 6, 165, 135, 150, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 168, 0, 209, 1, 13, 3, 120, 10, 104, 11, 141, 14, 160, 27, 42, 77, 32, 74, 65, 49, 43, 25, 18, 7, 167, 135, 120, 120, 120, 120, 122, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 200, 0, 13, 2, 57, 3, 120, 10, 104, 11, 141, 14, 160, 27, 77, 39, 27, 46, 51, 38, 36, 14, 10, 7, 167, 135, 135, 120, 120, 120, 137, 105, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 232, 0, 18, 2, 233, 3, 60, 10, 8, 12, 141, 14, 160, 27, 0, 26, 30, 41, 48, 23, 20, 17, 8, 7, 167, 120, 135, 120, 120, 120, 137, 105, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 5, 0, 1, 0, 84, 0, 104, 1, 70, 6, 212, 8, 148, 12, 41, 14, 64, 26, 42, 48, 17, 72, 53, 40, 40, 37, 11, 0, 120, 150, 135, 120, 120, 120, 60, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 84, 0, 128, 1, 0, 5, 232, 8, 48, 12, 136, 14, 192, 25, 40, 67, 19, 79, 82, 64, 53, 45, 18, 8, 167, 135, 135, 120, 120, 120, 107, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 184, 0, 152, 1, 232, 3, 96, 9, 28, 12, 236, 14, 128, 26, 50, 62, 26, 66, 68, 45, 37, 28, 21, 6, 162, 135, 150, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 84, 0, 88, 1, 212, 3, 196, 9, 148, 12, 196, 14, 192, 25, 67, 56, 16, 83, 38, 36, 30, 29, 13, 0, 120, 145, 135, 120, 120, 120, 60, 100, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 84, 0, 34, 1, 255, 3, 172, 8, 28, 12, 116, 14, 192, 25, 0, 27, 16, 57, 35, 17, 20, 20, 10, 0, 120, 135, 135, 120, 120, 120, 60, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 5, 0, 1, 0, 84, 0, 104, 1, 70, 6, 212, 8, 148, 12, 41, 14, 64, 26, 42, 43, 17, 65, 54, 40, 34, 31, 11, 7, 162, 150, 135, 120, 120, 120, 102, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 84, 0, 104, 1, 26, 6, 212, 8, 148, 12, 116, 14, 192, 25, 40, 71, 19, 81, 83, 74, 54, 46, 18, 7, 167, 135, 135, 120, 120, 120, 107, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 88, 0, 104, 1, 48, 6, 172, 8, 148, 12, 116, 14, 192, 25, 50, 73, 19, 91, 65, 65, 53, 46, 20, 7, 167, 120, 135, 120, 120, 120, 107, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 84, 0, 64, 1, 106, 5, 192, 8, 68, 12, 116, 14, 192, 25, 67, 30, 11, 58, 41, 36, 31, 23, 13, 7, 165, 135, 135, 120, 120, 120, 105, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 84, 0, 34, 1, 255, 3, 172, 8, 28, 12, 116, 14, 192, 25, 0, 28, 16, 54, 35, 17, 20, 20, 9, 7, 165, 135, 135, 120, 120, 120, 105, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 6, 0, 1, 0, 236, 0, 82, 3, 84, 5, 116, 9, 88, 12, 116, 14, 224, 27, 50, 57, 28, 58, 75, 41, 43, 27, 10, 8, 250, 120, 210, 120, 120, 120, 255, 120, 165, 44, 45, 70, 130, 56, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 236, 0, 62, 3, 84, 5, 136, 9, 88, 12, 116, 14, 224, 27, 66, 104, 30, 81, 98, 53, 57, 36, 12, 6, 225, 120, 210, 120, 120, 120, 255, 120, 165, 44, 45, 70, 130, 56, 0, 0, 0, 0, 45, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 220, 0, 42, 3, 252, 4, 36, 9, 128, 12, 41, 14, 224, 27, 41, 69, 27, 59, 81, 41, 52, 32, 12, 7, 167, 120, 210, 120, 120, 120, 255, 120, 165, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 0, 1, 173, 2, 87, 4, 16, 9, 48, 12, 41, 14, 128, 27, 40, 60, 28, 49, 77, 34, 51, 36, 15, 6, 237, 207, 192, 120, 120, 120, 141, 120, 147, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 0, 1, 234, 1, 189, 3, 16, 9, 8, 12, 41, 14, 96, 27, 40, 62, 36, 68, 59, 21, 35, 23, 15, 8, 205, 90, 180, 120, 120, 120, 145, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 172, 0, 232, 1, 132, 3, 192, 8, 168, 12, 60, 15, 96, 27, 0, 29, 25, 50, 42, 16, 18, 13, 11, 9, 200, 90, 120, 120, 120, 120, 200, 120, 135, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 0, 0, 6, 0, 1, 0, 232, 0, 38, 2, 117, 5, 116, 9, 108, 12, 10, 15, 96, 28, 46, 56, 40, 60, 61, 44, 32, 36, 20, 8, 167, 120, 165, 120, 120, 120, 227, 150, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 248, 0, 118, 2, 73, 5, 36, 9, 28, 12, 166, 14, 96, 28, 25, 107, 47, 85, 109, 75, 55, 45, 19, 8, 167, 120, 165, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 240, 0, 118, 2, 73, 5, 212, 8, 28, 12, 141, 14, 96, 28, 43, 79, 36, 73, 95, 72, 54, 42, 18, 7, 170, 120, 165, 120, 120, 120, 200, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 8, 1, 18, 2, 117, 5, 132, 8, 204, 11, 166, 14, 96, 28, 48, 53, 24, 70, 70, 36, 32, 26, 15, 8, 165, 120, 135, 120, 120, 120, 150, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 5, 0, 192, 0, 174, 1, 197, 4, 172, 8, 204, 11, 141, 14, 224, 28, 46, 40, 28, 64, 39, 27, 18, 16, 8, 8, 162, 120, 135, 120, 120, 120, 117, 90, 180, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 176, 0, 134, 1, 189, 3, 92, 8, 204, 11, 141, 14, 224, 28, 0, 33, 24, 58, 38, 22, 15, 12, 9, 8, 152, 120, 75, 120, 120, 120, 107, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 226, 0, 7, 0, 5, 0, 44, 1, 92, 3, 216, 4, 4, 11, 72, 13, 191, 14, 64, 27, 51, 47, 28, 58, 63, 37, 40, 27, 4, 4, 167, 165, 165, 120, 120, 120, 167, 105, 165, 44, 60, 70, 130, 55, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 44, 1, 92, 3, 216, 4, 4, 11, 72, 13, 191, 14, 64, 27, 70, 100, 41, 85, 92, 54, 58, 39, 9, 7, 167, 165, 165, 120, 120, 120, 167, 105, 165, 44, 60, 70, 130, 55, 0, 0, 0, 0, 45, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 44, 1, 120, 3, 216, 4, 200, 10, 72, 13, 191, 14, 64, 27, 15, 92, 39, 80, 87, 51, 55, 37, 8, 6, 167, 165, 165, 120, 120, 120, 167, 105, 165, 44, 60, 70, 130, 55, 0, 0, 0, 0, 45, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 33, 0, 20, 1, 80, 3, 29, 5, 216, 9, 72, 13, 136, 14, 64, 27, 23, 59, 29, 68, 71, 53, 51, 35, 8, 6, 167, 172, 120, 120, 120, 120, 167, 172, 165, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 216, 0, 16, 3, 4, 6, 196, 9, 52, 13, 176, 14, 64, 27, 33, 43, 32, 66, 56, 47, 43, 39, 8, 7, 167, 150, 180, 120, 120, 120, 167, 120, 135, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 212, 0, 232, 1, 188, 7, 40, 10, 92, 13, 120, 15, 64, 27, 34, 35, 37, 54, 51, 51, 39, 38, 13, 9, 167, 90, 180, 120, 120, 120, 137, 75, 150, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 1, 0, 196, 0, 159, 1, 252, 7, 40, 10, 112, 13, 120, 15, 220, 27, 0, 37, 39, 55, 48, 48, 39, 32, 11, 10, 167, 90, 114, 120, 120, 120, 122, 75, 90, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 232, 65, 0, 191, 129, 244, 194, 182, 76, 250, 23, 8, 0, 0, 7, 0, 1, 0, 16, 1, 53, 2, 12, 3, 160, 10, 244, 11, 35, 15, 96, 28, 24, 63, 33, 62, 70, 43, 37, 17, 11, 7, 167, 120, 90, 120, 120, 120, 167, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 0, 1, 33, 2, 12, 3, 160, 10, 244, 11, 35, 15, 224, 27, 49, 112, 43, 87, 92, 61, 53, 26, 15, 6, 165, 120, 90, 120, 120, 120, 165, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 216, 0, 33, 2, 72, 3, 40, 10, 244, 11, 35, 15, 224, 27, 65, 92, 39, 81, 98, 49, 57, 29, 17, 7, 170, 120, 90, 120, 120, 120, 170, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 37, 0, 184, 0, 209, 1, 106, 5, 172, 8, 108, 12, 216, 14, 64, 27, 22, 48, 36, 68, 39, 59, 38, 22, 15, 7, 167, 100, 152, 120, 120, 120, 137, 115, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 208, 0, 149, 1, 246, 6, 172, 8, 188, 12, 236, 14, 64, 27, 48, 43, 32, 56, 36, 59, 35, 22, 13, 7, 155, 105, 150, 120, 120, 120, 125, 150, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 160, 0, 54, 1, 199, 7, 136, 9, 112, 13, 60, 15, 64, 27, 26, 35, 25, 53, 36, 30, 41, 27, 16, 7, 155, 105, 135, 120, 120, 120, 125, 105, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 1, 0, 160, 0, 54, 1, 210, 7, 196, 9, 92, 13, 60, 15, 64, 28, 0, 24, 27, 45, 27, 20, 32, 21, 12, 7, 157, 105, 135, 120, 120, 120, 82, 105, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 232, 65, 0, 191, 129, 244, 194, 182, 76, 250, 23, 8, 0, 0, 6, 0, 1, 0, 96, 0, 104, 1, 92, 8, 80, 10, 232, 13, 60, 15, 160, 27, 42, 48, 10, 66, 51, 58, 42, 33, 10, 8, 155, 165, 150, 120, 120, 120, 155, 105, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 104, 0, 112, 1, 108, 8, 160, 10, 72, 13, 60, 15, 32, 27, 70, 59, 19, 64, 74, 76, 66, 36, 14, 8, 150, 120, 150, 120, 120, 120, 150, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 104, 0, 119, 1, 52, 8, 160, 10, 72, 13, 60, 15, 32, 27, 40, 52, 18, 61, 70, 72, 63, 34, 14, 7, 150, 120, 150, 120, 120, 120, 150, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 184, 0, 239, 1, 111, 7, 196, 9, 112, 13, 60, 15, 64, 27, 44, 52, 30, 75, 59, 58, 44, 30, 14, 8, 167, 90, 150, 120, 120, 120, 167, 90, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 5, 0, 152, 0, 16, 2, 124, 6, 156, 9, 32, 13, 85, 15, 64, 28, 35, 27, 23, 45, 46, 48, 38, 21, 7, 8, 167, 150, 120, 120, 120, 120, 167, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 200, 0, 16, 2, 59, 6, 156, 9, 112, 13, 29, 16, 192, 28, 0, 25, 26, 43, 39, 39, 31, 17, 5, 9, 167, 150, 120, 120, 120, 120, 167, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 190, 0, 5, 0, 1, 0, 132, 0, 8, 2, 136, 4, 136, 9, 128, 12, 156, 14, 84, 27, 50, 40, 30, 52, 60, 40, 33, 28, 16, 6, 167, 148, 143, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 132, 0, 8, 2, 136, 4, 136, 9, 128, 12, 156, 14, 84, 27, 50, 71, 40, 70, 80, 54, 44, 38, 22, 8, 167, 148, 143, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 128, 0, 16, 2, 220, 4, 106, 9, 146, 12, 144, 14, 87, 27, 40, 57, 35, 64, 74, 48, 41, 35, 19, 8, 167, 148, 140, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 123, 0, 16, 2, 48, 5, 56, 9, 128, 12, 132, 14, 91, 27, 50, 42, 29, 55, 65, 39, 37, 30, 16, 7, 167, 149, 138, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 119, 0, 12, 2, 121, 5, 252, 8, 108, 12, 122, 14, 94, 27, 0, 35, 25, 50, 61, 38, 35, 27, 14, 7, 167, 149, 136, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 6, 0, 1, 0, 140, 0, 174, 1, 152, 3, 36, 9, 164, 11, 16, 14, 96, 25, 48, 61, 31, 70, 69, 41, 27, 15, 12, 7, 167, 120, 120, 120, 120, 120, 167, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 140, 0, 174, 1, 192, 3, 36, 9, 164, 11, 16, 14, 96, 25, 36, 75, 35, 82, 66, 44, 35, 22, 16, 6, 165, 120, 120, 120, 120, 120, 165, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 140, 0, 154, 1, 156, 3, 36, 9, 164, 11, 16, 14, 96, 25, 49, 76, 34, 76, 81, 39, 33, 21, 20, 6, 167, 120, 120, 120, 120, 120, 167, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 228, 0, 239, 1, 255, 3, 252, 8, 184, 11, 16, 14, 192, 25, 49, 60, 31, 62, 76, 40, 30, 20, 18, 7, 167, 111, 135, 120, 120, 120, 191, 129, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 186, 0, 14, 2, 137, 4, 252, 8, 8, 12, 41, 14, 112, 26, 47, 35, 26, 49, 62, 35, 28, 19, 13, 6, 167, 115, 131, 120, 120, 120, 191, 129, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 144, 0, 46, 2, 20, 5, 252, 8, 88, 12, 66, 14, 32, 27, 0, 29, 25, 45, 57, 36, 31, 23, 11, 7, 167, 120, 127, 120, 120, 120, 255, 105, 90, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 0, 0, 7, 0, 5, 0, 44, 1, 92, 3, 216, 4, 4, 11, 72, 13, 191, 14, 64, 27, 45, 47, 28, 58, 63, 37, 40, 27, 6, 4, 167, 165, 165, 120, 120, 120, 167, 105, 165, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 44, 1, 92, 3, 216, 4, 4, 11, 72, 13, 191, 14, 64, 27, 40, 107, 42, 88, 95, 55, 60, 40, 9, 7, 167, 165, 165, 120, 120, 120, 167, 105, 165, 44, 45, 70, 130, 57, 0, 0, 0, 0, 45, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 80, 1, 132, 3, 161, 5, 36, 9, 112, 13, 241, 14, 64, 27, 31, 71, 36, 76, 95, 55, 45, 28, 10, 7, 240, 165, 120, 120, 120, 120, 195, 120, 120, 44, 45, 70, 130, 57, 0, 0, 0, 0, 45, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 32, 1, 248, 2, 191, 6, 36, 9, 192, 13, 241, 14, 64, 27, 25, 41, 32, 47, 53, 53, 50, 47, 11, 7, 255, 180, 180, 120, 120, 120, 200, 195, 180, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 224, 0, 224, 1, 45, 7, 136, 9, 112, 13, 241, 14, 64, 27, 27, 42, 34, 43, 61, 61, 51, 50, 12, 8, 255, 105, 180, 120, 120, 120, 165, 120, 135, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 224, 0, 8, 2, 23, 7, 176, 9, 112, 13, 241, 14, 64, 27, 52, 37, 28, 51, 56, 56, 49, 43, 8, 8, 255, 90, 180, 120, 120, 120, 187, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 1, 0, 208, 0, 128, 2, 238, 5, 96, 9, 52, 13, 216, 14, 64, 27, 0, 21, 20, 40, 48, 36, 32, 28, 7, 8, 252, 90, 165, 120, 120, 120, 252, 105, 120, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 232, 65, 0, 191, 129, 244, 194, 182, 76, 250, 23, 8, 0, 0, 6, 0, 1, 0, 0, 1, 136, 3, 200, 5, 110, 10, 154, 13, 40, 15, 67, 27, 45, 46, 28, 60, 58, 41, 34, 27, 9, 4, 228, 152, 186, 132, 120, 120, 255, 174, 173, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 0, 1, 136, 3, 200, 5, 110, 10, 154, 13, 40, 15, 67, 27, 29, 90, 39, 85, 81, 57, 48, 38, 12, 5, 228, 152, 186, 132, 120, 120, 255, 174, 173, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 5, 0, 8, 1, 136, 3, 62, 5, 20, 10, 188, 12, 166, 14, 32, 27, 39, 88, 33, 76, 89, 68, 56, 46, 13, 6, 185, 180, 165, 120, 120, 120, 245, 135, 120, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 5, 0, 8, 1, 178, 2, 32, 4, 116, 9, 8, 12, 166, 14, 64, 27, 42, 90, 37, 64, 99, 52, 43, 35, 14, 7, 185, 135, 150, 120, 120, 120, 194, 105, 111, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 200, 0, 33, 2, 178, 3, 36, 9, 8, 12, 216, 14, 160, 27, 84, 49, 27, 58, 75, 37, 32, 23, 12, 8, 177, 120, 120, 120, 120, 120, 147, 105, 105, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 200, 0, 193, 2, 64, 5, 16, 9, 128, 12, 241, 14, 32, 28, 0, 28, 28, 44, 60, 36, 32, 26, 8, 8, 185, 150, 120, 120, 120, 120, 155, 150, 105, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 140, 0, 5, 0, 1, 0, 192, 0, 32, 2, 60, 5, 156, 9, 92, 13, 52, 18, 0, 28, 45, 54, 25, 63, 72, 40, 34, 17, 14, 6, 170, 165, 135, 120, 120, 120, 170, 180, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 192, 0, 32, 2, 60, 5, 156, 9, 92, 13, 52, 18, 0, 28, 50, 96, 34, 84, 96, 53, 45, 22, 19, 8, 170, 165, 135, 120, 120, 120, 170, 180, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 192, 0, 32, 2, 60, 5, 156, 9, 92, 13, 52, 18, 0, 28, 60, 87, 32, 80, 91, 50, 43, 21, 18, 7, 170, 165, 135, 120, 120, 120, 170, 180, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 201, 0, 104, 2, 166, 4, 146, 9, 240, 10, 127, 18, 0, 28, 35, 29, 25, 49, 38, 30, 24, 8, 11, 4, 170, 165, 136, 120, 120, 120, 170, 180, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 201, 0, 104, 2, 166, 4, 146, 9, 240, 10, 127, 18, 0, 28, 0, 28, 24, 48, 38, 30, 23, 8, 10, 4, 170, 165, 136, 120, 120, 120, 170, 180, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 135, 0, 5, 0, 1, 0, 216, 0, 136, 2, 156, 4, 35, 10, 227, 12, 20, 15, 214, 27, 45, 70, 34, 68, 76, 43, 39, 30, 15, 6, 189, 159, 136, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 216, 0, 136, 2, 156, 4, 35, 10, 227, 12, 20, 15, 214, 27, 50, 124, 45, 90, 101, 57, 52, 40, 20, 8, 189, 159, 136, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 216, 0, 136, 2, 176, 4, 35, 10, 227, 12, 20, 15, 214, 27, 55, 111, 43, 86, 96, 54, 49, 38, 19, 8, 189, 159, 136, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 204, 0, 128, 2, 116, 4, 156, 9, 240, 10, 152, 18, 0, 28, 35, 33, 30, 51, 34, 32, 27, 6, 11, 4, 170, 165, 137, 120, 120, 120, 170, 180, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 204, 0, 128, 2, 116, 4, 156, 9, 240, 10, 152, 18, 0, 28, 0, 28, 25, 48, 32, 30, 25, 6, 10, 4, 170, 165, 137, 120, 120, 120, 170, 180, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 190, 0, 5, 0, 1, 0, 0, 1, 80, 2, 232, 3, 80, 10, 28, 12, 36, 14, 15, 28, 50, 42, 31, 49, 62, 20, 36, 20, 6, 5, 186, 151, 122, 120, 120, 120, 105, 164, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 0, 1, 80, 2, 232, 3, 80, 10, 28, 12, 36, 14, 15, 28, 50, 82, 43, 68, 86, 28, 50, 28, 8, 7, 186, 151, 122, 120, 120, 120, 105, 164, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 0, 1, 80, 2, 232, 3, 80, 10, 28, 12, 36, 14, 15, 28, 50, 82, 43, 68, 86, 28, 50, 28, 8, 7, 186, 151, 122, 120, 120, 120, 105, 164, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 0, 1, 80, 2, 232, 3, 80, 10, 28, 12, 36, 14, 15, 28, 40, 59, 36, 58, 73, 24, 42, 24, 7, 6, 186, 151, 122, 120, 120, 120, 105, 164, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 0, 1, 80, 2, 232, 3, 80, 10, 28, 12, 36, 14, 15, 28, 0, 25, 24, 38, 48, 16, 28, 16, 4, 4, 186, 151, 122, 120, 120, 120, 105, 164, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 190, 0, 5, 0, 1, 0, 228, 0, 28, 2, 128, 3, 72, 10, 190, 11, 15, 14, 216, 27, 50, 57, 28, 61, 69, 28, 35, 19, 9, 5, 180, 112, 128, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 228, 0, 28, 2, 128, 3, 72, 10, 190, 11, 15, 14, 216, 27, 50, 90, 35, 76, 87, 35, 44, 24, 11, 6, 180, 112, 128, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 0, 1, 0, 2, 132, 3, 64, 10, 216, 11, 234, 13, 15, 28, 50, 74, 39, 57, 91, 24, 46, 25, 8, 7, 186, 83, 122, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 0, 1, 0, 2, 132, 3, 64, 10, 216, 11, 234, 13, 15, 28, 40, 59, 35, 51, 81, 22, 42, 22, 7, 6, 186, 83, 122, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 8, 1, 0, 2, 132, 3, 60, 10, 224, 11, 222, 13, 32, 28, 0, 20, 27, 31, 51, 12, 23, 14, 4, 4, 180, 75, 120, 120, 120, 120, 85, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 140, 0, 3, 0, 1, 0, 112, 0, 16, 2, 220, 5, 76, 9, 188, 12, 116, 14, 96, 27, 50, 48, 30, 59, 72, 40, 42, 32, 16, 7, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 116, 0, 16, 2, 220, 5, 76, 9, 188, 12, 116, 14, 96, 27, 90, 78, 39, 75, 91, 51, 54, 41, 21, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 116, 0, 16, 2, 220, 5, 76, 9, 188, 12, 116, 14, 96, 27, 0, 46, 30, 58, 70, 39, 41, 32, 16, 9, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 139, 0, 3, 0, 1, 0, 112, 0, 244, 1, 132, 5, 36, 9, 188, 12, 116, 14, 96, 27, 50, 56, 31, 63, 76, 38, 46, 34, 18, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 116, 0, 244, 1, 132, 5, 16, 9, 188, 12, 116, 14, 96, 27, 90, 80, 37, 72, 96, 48, 60, 43, 23, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 116, 0, 244, 1, 132, 5, 36, 9, 188, 12, 116, 14, 96, 27, 0, 48, 30, 58, 70, 31, 44, 32, 16, 9, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 190, 0, 4, 0, 1, 0, 52, 1, 135, 2, 242, 6, 226, 9, 172, 13, 154, 15, 176, 28, 50, 45, 30, 56, 65, 54, 35, 25, 8, 5, 255, 142, 180, 120, 120, 120, 150, 180, 150, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 52, 1, 135, 2, 242, 6, 226, 9, 172, 13, 154, 15, 176, 28, 90, 86, 41, 77, 90, 75, 49, 35, 12, 7, 255, 142, 180, 120, 120, 120, 150, 180, 150, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 52, 1, 135, 2, 242, 6, 226, 9, 172, 13, 154, 15, 176, 28, 50, 78, 39, 73, 85, 71, 46, 33, 11, 7, 255, 142, 180, 120, 120, 120, 150, 180, 150, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 52, 1, 135, 2, 242, 6, 226, 9, 172, 13, 154, 15, 176, 28, 0, 35, 26, 50, 57, 48, 31, 22, 7, 4, 255, 142, 180, 120, 120, 120, 150, 180, 150, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 175, 0, 4, 0, 1, 0, 148, 0, 128, 1, 238, 7, 50, 10, 42, 13, 50, 15, 96, 25, 45, 48, 27, 72, 52, 48, 45, 29, 11, 5, 160, 92, 120, 143, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 148, 0, 128, 1, 238, 7, 50, 10, 42, 13, 50, 15, 96, 25, 70, 97, 39, 102, 74, 68, 64, 41, 16, 8, 160, 92, 120, 143, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 148, 0, 128, 1, 238, 7, 50, 10, 42, 13, 50, 15, 96, 25, 60, 87, 37, 97, 70, 64, 61, 39, 15, 7, 160, 92, 120, 143, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 148, 0, 128, 1, 238, 7, 50, 10, 42, 13, 50, 15, 96, 25, 0, 38, 24, 64, 47, 43, 40, 26, 10, 5, 160, 92, 120, 143, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 200, 0, 4, 0, 1, 0, 158, 0, 118, 1, 192, 8, 44, 11, 132, 13, 0, 15, 8, 28, 50, 40, 18, 55, 57, 49, 46, 30, 11, 8, 180, 111, 153, 120, 120, 120, 185, 112, 155, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 158, 0, 118, 1, 192, 8, 44, 11, 132, 13, 0, 15, 8, 28, 80, 75, 26, 76, 78, 68, 63, 42, 16, 11, 180, 111, 153, 120, 120, 120, 185, 112, 155, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 158, 0, 118, 1, 192, 8, 44, 11, 132, 13, 0, 15, 8, 28, 70, 63, 23, 69, 72, 62, 58, 38, 15, 10, 180, 111, 153, 120, 120, 120, 185, 112, 155, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 158, 0, 118, 1, 192, 8, 44, 11, 132, 13, 0, 15, 8, 28, 0, 29, 16, 47, 48, 42, 39, 26, 10, 6, 180, 111, 153, 120, 120, 120, 185, 112, 155, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 195, 0, 4, 0, 1, 0, 216, 0, 118, 2, 152, 3, 67, 10, 194, 11, 10, 14, 224, 27, 45, 50, 21, 50, 63, 30, 30, 18, 11, 4, 178, 146, 127, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 216, 0, 118, 2, 152, 3, 67, 10, 194, 11, 10, 14, 224, 27, 80, 131, 34, 80, 103, 49, 49, 30, 18, 7, 178, 146, 127, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 216, 0, 104, 2, 172, 3, 67, 10, 194, 11, 10, 14, 224, 27, 70, 105, 32, 74, 95, 46, 45, 28, 16, 7, 178, 146, 127, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 216, 0, 104, 2, 172, 3, 67, 10, 194, 11, 10, 14, 224, 27, 0, 44, 20, 47, 62, 29, 28, 17, 10, 4, 178, 146, 127, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 175, 0, 4, 0, 1, 0, 188, 0, 221, 1, 200, 3, 60, 10, 104, 12, 166, 14, 204, 26, 45, 42, 27, 51, 58, 37, 33, 23, 16, 5, 164, 141, 150, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 188, 0, 221, 1, 200, 3, 60, 10, 104, 12, 166, 14, 204, 26, 70, 87, 39, 74, 84, 53, 47, 33, 24, 7, 164, 141, 150, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 188, 0, 221, 1, 200, 3, 60, 10, 104, 12, 166, 14, 204, 26, 60, 70, 35, 66, 75, 48, 42, 30, 21, 6, 164, 141, 150, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 188, 0, 221, 1, 200, 3, 60, 10, 104, 12, 166, 14, 204, 26, 0, 37, 25, 48, 54, 34, 31, 22, 15, 4, 164, 141, 150, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 0, 0, 5, 0, 1, 0, 248, 1, 97, 3, 7, 5, 60, 10, 72, 13, 141, 14, 88, 27, 65, 48, 25, 51, 60, 25, 22, 20, 6, 6, 255, 162, 210, 120, 120, 120, 120, 162, 120, 44, 60, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 104, 1, 136, 3, 219, 4, 60, 10, 72, 13, 141, 14, 88, 27, 75, 111, 36, 82, 86, 52, 35, 33, 13, 7, 210, 175, 150, 120, 120, 120, 210, 175, 120, 44, 60, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 104, 1, 128, 3, 219, 4, 196, 9, 32, 13, 116, 14, 88, 27, 63, 110, 36, 82, 86, 52, 35, 33, 13, 7, 210, 175, 150, 120, 120, 120, 210, 175, 120, 44, 55, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 104, 1, 134, 3, 219, 4, 184, 9, 20, 13, 116, 14, 33, 27, 71, 104, 35, 79, 85, 50, 35, 33, 13, 8, 214, 172, 150, 120, 120, 120, 210, 175, 120, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 104, 1, 127, 3, 220, 4, 156, 9, 248, 12, 116, 14, 160, 26, 0, 41, 24, 51, 61, 32, 26, 22, 8, 8, 225, 165, 150, 120, 120, 120, 225, 120, 120, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 211, 0, 5, 0, 1, 0, 140, 0, 224, 1, 100, 5, 252, 8, 28, 12, 192, 13, 32, 27, 45, 40, 22, 52, 62, 57, 47, 38, 19, 6, 170, 135, 165, 120, 120, 120, 140, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 140, 0, 224, 1, 100, 5, 252, 8, 28, 12, 192, 13, 32, 27, 48, 63, 28, 65, 78, 71, 58, 48, 23, 8, 170, 135, 165, 120, 120, 120, 140, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 140, 0, 224, 1, 100, 5, 252, 8, 28, 12, 192, 13, 32, 27, 40, 63, 28, 65, 78, 71, 58, 48, 23, 8, 170, 135, 165, 120, 120, 120, 140, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 140, 0, 248, 1, 100, 5, 252, 8, 28, 12, 192, 13, 32, 27, 78, 45, 25, 55, 66, 61, 49, 40, 20, 6, 170, 135, 165, 120, 120, 120, 140, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 140, 0, 8, 2, 100, 5, 252, 8, 28, 12, 192, 13, 32, 27, 0, 31, 21, 46, 55, 51, 41, 34, 16, 5, 170, 135, 165, 120, 120, 120, 140, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 220, 0, 5, 0, 1, 0, 168, 0, 0, 2, 92, 3, 88, 10, 104, 11, 141, 14, 32, 27, 45, 55, 21, 52, 64, 39, 36, 18, 13, 5, 167, 135, 150, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 168, 0, 0, 2, 92, 3, 88, 10, 104, 11, 141, 14, 32, 27, 40, 107, 29, 73, 89, 54, 50, 25, 18, 7, 167, 135, 150, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 168, 0, 0, 2, 92, 3, 88, 10, 104, 11, 141, 14, 32, 27, 90, 103, 34, 73, 85, 51, 41, 24, 18, 7, 167, 135, 150, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 168, 0, 0, 2, 92, 3, 88, 10, 104, 11, 141, 14, 32, 27, 45, 59, 26, 58, 60, 39, 31, 18, 13, 5, 167, 135, 150, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 168, 0, 0, 2, 92, 3, 88, 10, 104, 11, 141, 14, 32, 27, 0, 27, 18, 40, 40, 23, 20, 12, 9, 3, 167, 135, 150, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 4, 0, 1, 0, 236, 0, 28, 2, 167, 3, 0, 10, 128, 12, 10, 15, 96, 28, 50, 64, 34, 58, 76, 48, 26, 21, 16, 7, 120, 135, 135, 120, 120, 120, 135, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 236, 0, 63, 2, 123, 3, 80, 10, 48, 12, 66, 14, 224, 27, 106, 123, 47, 82, 94, 55, 34, 21, 16, 7, 120, 135, 135, 120, 120, 120, 135, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 236, 0, 23, 2, 123, 3, 0, 10, 48, 12, 191, 14, 224, 27, 79, 96, 32, 67, 102, 58, 35, 28, 18, 7, 120, 135, 105, 120, 120, 120, 135, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 216, 0, 68, 2, 255, 3, 176, 9, 128, 12, 191, 14, 224, 27, 0, 49, 27, 52, 77, 41, 28, 24, 9, 7, 120, 135, 135, 120, 120, 120, 135, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 0, 0, 5, 0, 1, 0, 84, 0, 76, 1, 247, 5, 208, 8, 132, 12, 116, 14, 192, 25, 42, 48, 16, 69, 62, 55, 44, 40, 14, 6, 167, 135, 135, 120, 120, 120, 107, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 84, 0, 76, 1, 247, 5, 208, 8, 132, 12, 116, 14, 192, 25, 40, 76, 20, 87, 78, 69, 55, 50, 18, 8, 167, 135, 135, 120, 120, 120, 107, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 84, 0, 64, 1, 106, 5, 192, 8, 68, 12, 116, 14, 192, 25, 50, 75, 16, 93, 59, 53, 45, 43, 19, 11, 165, 135, 135, 120, 120, 120, 105, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 84, 0, 64, 1, 106, 5, 192, 8, 68, 12, 116, 14, 192, 25, 67, 39, 12, 67, 43, 38, 32, 31, 14, 8, 165, 135, 135, 120, 120, 120, 105, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 84, 0, 34, 1, 255, 3, 172, 8, 28, 12, 116, 14, 192, 25, 0, 34, 17, 60, 37, 18, 21, 21, 10, 8, 165, 135, 135, 120, 120, 120, 105, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 5, 0, 1, 0, 220, 0, 148, 2, 4, 6, 56, 9, 84, 11, 16, 14, 192, 28, 34, 47, 34, 53, 70, 53, 36, 48, 13, 8, 120, 165, 150, 120, 120, 120, 165, 210, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 220, 0, 148, 2, 26, 6, 56, 9, 124, 11, 116, 14, 192, 28, 60, 82, 42, 76, 91, 74, 45, 57, 24, 8, 120, 165, 150, 120, 120, 120, 165, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 220, 0, 224, 1, 4, 6, 232, 8, 68, 12, 191, 14, 192, 28, 54, 54, 36, 55, 79, 57, 35, 30, 16, 7, 120, 120, 120, 120, 120, 120, 165, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 220, 0, 164, 1, 120, 4, 152, 8, 88, 12, 141, 14, 64, 28, 45, 56, 44, 77, 54, 30, 24, 26, 15, 9, 120, 120, 120, 120, 120, 120, 60, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 140, 0, 84, 1, 222, 3, 56, 9, 188, 12, 141, 14, 192, 27, 0, 21, 28, 46, 37, 15, 7, 9, 9, 8, 120, 105, 90, 120, 120, 120, 60, 120, 75, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 6, 0, 1, 0, 44, 1, 120, 3, 80, 5, 60, 10, 112, 13, 191, 14, 64, 27, 41, 30, 24, 49, 53, 37, 31, 23, 3, 4, 167, 165, 165, 120, 120, 120, 167, 105, 165, 44, 45, 70, 130, 56, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 44, 1, 92, 3, 80, 5, 100, 10, 112, 13, 191, 14, 64, 27, 77, 90, 41, 86, 93, 58, 59, 40, 5, 7, 167, 165, 165, 120, 120, 120, 167, 105, 165, 44, 45, 70, 130, 56, 0, 0, 0, 0, 45, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 44, 1, 136, 3, 140, 5, 20, 10, 152, 13, 191, 14, 64, 27, 33, 80, 40, 82, 89, 55, 56, 38, 5, 6, 167, 165, 165, 120, 120, 120, 167, 105, 165, 44, 45, 70, 130, 56, 0, 0, 0, 0, 45, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 216, 0, 92, 3, 59, 6, 252, 8, 192, 13, 241, 14, 160, 28, 31, 63, 32, 65, 87, 53, 49, 32, 7, 7, 120, 75, 195, 120, 120, 120, 255, 180, 135, 44, 45, 70, 130, 56, 0, 0, 0, 0, 43, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 240, 0, 203, 2, 224, 6, 176, 9, 112, 13, 10, 15, 96, 27, 53, 48, 32, 63, 65, 62, 36, 22, 5, 7, 165, 135, 240, 120, 120, 120, 195, 105, 165, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 212, 0, 232, 1, 48, 7, 136, 9, 172, 13, 80, 15, 64, 27, 0, 26, 32, 46, 44, 44, 33, 32, 13, 7, 167, 90, 180, 120, 120, 120, 137, 75, 150, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 0, 0, 5, 0, 1, 0, 52, 1, 135, 2, 242, 6, 226, 9, 172, 13, 154, 15, 176, 28, 44, 45, 28, 57, 65, 54, 36, 26, 9, 5, 255, 142, 180, 120, 120, 120, 150, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 52, 1, 135, 2, 242, 6, 226, 9, 172, 13, 154, 15, 176, 28, 77, 83, 39, 77, 88, 73, 49, 35, 12, 7, 255, 142, 180, 120, 120, 120, 150, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 240, 0, 136, 2, 224, 6, 116, 9, 72, 13, 60, 15, 96, 27, 77, 56, 30, 63, 71, 62, 57, 25, 13, 7, 167, 120, 180, 120, 120, 120, 242, 150, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 178, 0, 103, 2, 84, 6, 76, 9, 2, 13, 216, 14, 96, 27, 35, 38, 25, 52, 61, 45, 43, 24, 12, 7, 167, 135, 157, 120, 120, 120, 242, 150, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 163, 0, 81, 2, 17, 6, 66, 9, 241, 12, 191, 14, 96, 27, 0, 34, 26, 48, 55, 38, 38, 25, 13, 7, 167, 138, 152, 120, 120, 120, 242, 150, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 40, 0, 7, 0, 1, 0, 136, 0, 64, 1, 172, 8, 240, 10, 152, 13, 120, 15, 236, 26, 42, 44, 7, 65, 55, 56, 44, 27, 11, 7, 172, 133, 129, 120, 120, 120, 180, 105, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 128, 0, 64, 1, 172, 8, 240, 10, 112, 13, 100, 15, 224, 26, 40, 64, 10, 75, 75, 77, 72, 37, 16, 8, 158, 112, 135, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 128, 0, 64, 1, 172, 8, 240, 10, 112, 13, 100, 15, 224, 26, 28, 60, 10, 73, 73, 74, 70, 36, 16, 8, 158, 112, 135, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 104, 0, 136, 1, 52, 8, 80, 10, 52, 13, 60, 15, 64, 27, 31, 59, 17, 81, 60, 61, 57, 31, 12, 8, 160, 90, 150, 120, 120, 120, 160, 105, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 184, 0, 248, 1, 111, 7, 96, 9, 72, 13, 20, 15, 64, 27, 34, 53, 30, 75, 59, 58, 44, 30, 14, 8, 167, 90, 150, 120, 120, 120, 167, 90, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 176, 0, 16, 2, 64, 6, 36, 9, 238, 12, 90, 15, 128, 28, 45, 26, 24, 44, 48, 48, 31, 19, 6, 8, 167, 150, 120, 120, 120, 120, 167, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 1, 0, 200, 0, 16, 2, 240, 5, 56, 9, 248, 12, 160, 15, 192, 28, 0, 22, 25, 41, 37, 37, 24, 16, 5, 8, 167, 150, 120, 120, 120, 120, 167, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 232, 65, 0, 191, 129, 244, 194, 182, 76, 250, 23, 8, 155, 0, 4, 0, 1, 0, 142, 0, 224, 1, 180, 5, 110, 8, 88, 12, 110, 14, 38, 27, 45, 41, 25, 56, 62, 50, 43, 35, 16, 6, 170, 135, 161, 120, 120, 120, 140, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 142, 0, 224, 1, 180, 5, 110, 8, 88, 12, 110, 14, 38, 27, 60, 51, 28, 62, 69, 56, 48, 40, 18, 6, 170, 135, 161, 120, 120, 120, 140, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 142, 0, 212, 1, 164, 5, 240, 7, 72, 12, 146, 14, 38, 27, 50, 46, 28, 59, 66, 50, 40, 33, 13, 6, 170, 135, 161, 120, 120, 120, 140, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 142, 0, 208, 1, 160, 5, 208, 7, 68, 12, 156, 14, 38, 27, 0, 36, 25, 52, 58, 41, 35, 29, 10, 5, 170, 135, 161, 120, 120, 120, 140, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 140, 0, 3, 0, 1, 0, 112, 0, 240, 1, 220, 5, 116, 9, 228, 12, 156, 14, 96, 27, 50, 47, 25, 59, 72, 40, 42, 32, 16, 7, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 116, 0, 240, 1, 220, 5, 116, 9, 228, 12, 156, 14, 96, 27, 90, 77, 34, 75, 91, 51, 54, 41, 21, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 116, 0, 240, 1, 220, 5, 116, 9, 228, 12, 116, 14, 96, 27, 0, 47, 30, 58, 70, 39, 41, 32, 16, 9, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 135, 0, 3, 0, 1, 0, 152, 0, 72, 2, 120, 5, 134, 9, 195, 12, 165, 14, 141, 27, 45, 49, 32, 59, 72, 43, 45, 30, 16, 6, 174, 154, 137, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 152, 0, 72, 2, 120, 5, 134, 9, 195, 12, 165, 14, 141, 27, 90, 77, 40, 74, 91, 53, 56, 38, 21, 8, 174, 154, 137, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 152, 0, 80, 2, 120, 5, 134, 9, 195, 12, 165, 14, 141, 27, 0, 38, 28, 52, 64, 37, 39, 27, 14, 5, 174, 154, 137, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 180, 0, 5, 0, 1, 0, 55, 1, 158, 2, 183, 6, 252, 9, 163, 13, 121, 15, 154, 28, 50, 41, 34, 52, 64, 49, 35, 24, 9, 5, 255, 140, 173, 120, 120, 120, 150, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 55, 1, 158, 2, 183, 6, 252, 9, 163, 13, 121, 15, 154, 28, 40, 76, 46, 70, 86, 66, 47, 33, 12, 7, 255, 140, 173, 120, 120, 120, 150, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 61, 1, 178, 2, 159, 6, 56, 10, 143, 13, 44, 15, 103, 28, 50, 57, 48, 54, 80, 51, 42, 28, 12, 6, 226, 136, 157, 120, 120, 120, 150, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 61, 1, 178, 2, 159, 6, 56, 10, 143, 13, 44, 15, 103, 28, 40, 51, 45, 51, 76, 48, 40, 27, 11, 6, 226, 136, 157, 120, 120, 120, 150, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 68, 1, 198, 2, 136, 6, 111, 10, 123, 13, 229, 14, 57, 28, 0, 21, 34, 28, 51, 26, 26, 17, 7, 4, 195, 132, 142, 120, 120, 120, 150, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 185, 0, 4, 0, 1, 0, 78, 1, 188, 2, 144, 6, 202, 9, 184, 13, 183, 15, 10, 29, 45, 40, 38, 49, 58, 48, 37, 28, 10, 6, 255, 151, 208, 120, 120, 120, 135, 180, 182, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 78, 1, 188, 2, 144, 6, 202, 9, 184, 13, 183, 15, 10, 29, 80, 60, 47, 60, 71, 58, 45, 34, 12, 8, 255, 151, 208, 120, 120, 120, 135, 180, 182, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 34, 1, 166, 2, 48, 6, 186, 9, 152, 13, 191, 15, 176, 28, 60, 49, 39, 56, 67, 51, 41, 31, 12, 8, 255, 157, 191, 120, 120, 120, 135, 180, 182, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 236, 0, 140, 2, 208, 5, 166, 9, 112, 13, 200, 15, 64, 28, 0, 42, 33, 53, 64, 43, 38, 29, 12, 9, 233, 165, 170, 120, 120, 120, 135, 165, 175, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 170, 0, 4, 0, 1, 0, 64, 1, 72, 2, 28, 7, 0, 10, 104, 13, 15, 15, 224, 28, 50, 47, 31, 57, 61, 56, 43, 31, 10, 6, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 64, 1, 72, 2, 28, 7, 0, 10, 104, 13, 15, 15, 224, 28, 80, 80, 40, 74, 79, 72, 56, 41, 13, 8, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 211, 0, 64, 2, 144, 6, 20, 10, 117, 13, 160, 15, 149, 28, 40, 57, 36, 62, 68, 56, 46, 34, 12, 7, 208, 142, 158, 120, 120, 120, 189, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 215, 0, 96, 2, 64, 6, 20, 10, 123, 13, 160, 15, 73, 28, 0, 40, 32, 56, 58, 44, 39, 29, 11, 6, 228, 153, 158, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 190, 0, 4, 0, 1, 0, 168, 0, 160, 1, 8, 7, 0, 10, 72, 13, 200, 15, 163, 25, 50, 41, 32, 62, 49, 47, 44, 32, 14, 6, 161, 98, 126, 120, 120, 120, 130, 107, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 168, 0, 160, 1, 8, 7, 0, 10, 72, 13, 200, 15, 163, 25, 80, 65, 40, 78, 61, 59, 55, 40, 17, 8, 161, 98, 126, 120, 120, 120, 130, 107, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 168, 0, 160, 1, 8, 7, 0, 10, 72, 13, 200, 15, 163, 25, 60, 55, 37, 71, 56, 54, 51, 37, 16, 7, 161, 98, 126, 120, 120, 120, 130, 107, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 168, 0, 160, 1, 8, 7, 0, 10, 72, 13, 200, 15, 163, 25, 0, 31, 28, 54, 42, 41, 38, 28, 12, 5, 161, 98, 126, 120, 120, 120, 130, 107, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 190, 0, 4, 0, 1, 0, 168, 0, 192, 1, 124, 6, 224, 9, 12, 13, 60, 15, 230, 25, 50, 42, 29, 59, 53, 50, 47, 34, 15, 6, 163, 119, 133, 120, 120, 120, 130, 119, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 168, 0, 192, 1, 124, 6, 224, 9, 12, 13, 60, 15, 230, 25, 80, 69, 38, 76, 69, 65, 61, 44, 19, 8, 163, 119, 133, 120, 120, 120, 130, 119, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 168, 0, 192, 1, 124, 6, 224, 9, 12, 13, 60, 15, 230, 25, 60, 56, 34, 69, 62, 58, 55, 39, 17, 7, 163, 119, 133, 120, 120, 120, 130, 119, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 168, 0, 192, 1, 124, 6, 224, 9, 12, 13, 60, 15, 230, 25, 0, 32, 26, 52, 47, 44, 41, 30, 13, 5, 163, 119, 133, 120, 120, 120, 130, 119, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 175, 0, 4, 0, 1, 0, 126, 0, 112, 1, 52, 8, 100, 10, 47, 13, 60, 15, 96, 25, 45, 40, 25, 65, 47, 43, 43, 26, 10, 4, 160, 93, 120, 155, 120, 120, 130, 95, 120, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 126, 0, 112, 1, 52, 8, 100, 10, 47, 13, 60, 15, 96, 25, 70, 66, 31, 84, 60, 56, 56, 34, 14, 6, 160, 93, 120, 155, 120, 120, 130, 95, 120, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 126, 0, 88, 1, 98, 8, 140, 10, 41, 13, 45, 15, 152, 25, 60, 39, 22, 64, 44, 41, 41, 24, 11, 5, 161, 95, 118, 147, 120, 120, 130, 95, 120, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 126, 0, 88, 1, 98, 8, 140, 10, 41, 13, 45, 15, 152, 25, 0, 20, 16, 47, 32, 30, 30, 18, 8, 4, 161, 95, 118, 147, 120, 120, 130, 95, 120, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 185, 0, 4, 0, 1, 0, 0, 1, 216, 2, 176, 4, 100, 10, 188, 12, 176, 14, 87, 27, 45, 43, 29, 54, 65, 39, 35, 32, 10, 5, 175, 147, 147, 120, 120, 120, 175, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 0, 1, 216, 2, 176, 4, 100, 10, 188, 12, 176, 14, 87, 27, 80, 84, 41, 76, 90, 54, 48, 44, 14, 7, 175, 147, 147, 120, 120, 120, 175, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 0, 1, 208, 2, 176, 4, 100, 10, 188, 12, 176, 14, 87, 27, 60, 66, 36, 67, 80, 48, 43, 39, 12, 6, 175, 147, 147, 120, 120, 120, 175, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 0, 1, 200, 2, 176, 4, 100, 10, 188, 12, 176, 14, 87, 27, 0, 44, 29, 54, 67, 38, 34, 31, 10, 5, 175, 147, 147, 120, 120, 120, 175, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 184, 0, 4, 0, 1, 0, 208, 0, 120, 2, 20, 5, 40, 10, 228, 12, 0, 15, 210, 27, 45, 46, 30, 53, 70, 42, 39, 25, 14, 5, 185, 160, 141, 120, 120, 120, 235, 150, 118, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 208, 0, 120, 2, 20, 5, 40, 10, 228, 12, 0, 15, 210, 27, 80, 85, 41, 72, 95, 57, 53, 34, 19, 7, 185, 160, 141, 120, 120, 120, 235, 150, 118, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 208, 0, 114, 2, 36, 5, 40, 10, 228, 12, 0, 15, 210, 27, 60, 68, 35, 64, 85, 51, 47, 30, 17, 6, 185, 160, 141, 120, 120, 120, 235, 150, 118, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 208, 0, 104, 2, 60, 5, 40, 10, 228, 12, 0, 15, 210, 27, 0, 39, 26, 49, 65, 39, 36, 23, 13, 5, 185, 160, 141, 120, 120, 120, 235, 150, 118, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 175, 0, 4, 0, 1, 0, 116, 0, 240, 1, 16, 4, 0, 10, 168, 12, 96, 14, 96, 27, 45, 53, 30, 64, 67, 35, 37, 31, 16, 6, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 116, 0, 240, 1, 16, 4, 0, 10, 168, 12, 96, 14, 96, 27, 70, 101, 41, 88, 92, 48, 52, 43, 23, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 116, 0, 240, 1, 16, 4, 0, 10, 168, 12, 96, 14, 96, 27, 60, 82, 37, 79, 82, 43, 46, 39, 20, 7, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 116, 0, 240, 1, 16, 4, 0, 10, 168, 12, 96, 14, 96, 27, 0, 46, 28, 59, 62, 32, 35, 29, 15, 5, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 240, 0, 6, 0, 1, 0, 250, 0, 216, 2, 176, 4, 40, 10, 188, 12, 92, 14, 87, 27, 45, 47, 29, 54, 70, 40, 36, 33, 9, 5, 167, 147, 147, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 250, 0, 216, 2, 176, 4, 40, 10, 188, 12, 92, 14, 87, 27, 85, 95, 41, 77, 100, 57, 51, 47, 13, 8, 167, 147, 147, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 250, 0, 200, 2, 176, 4, 196, 9, 128, 12, 92, 14, 87, 27, 50, 66, 35, 65, 84, 48, 43, 39, 11, 6, 167, 147, 147, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 116, 0, 80, 2, 236, 4, 128, 7, 164, 11, 232, 13, 96, 27, 35, 40, 26, 60, 58, 35, 36, 28, 14, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 116, 0, 8, 2, 236, 4, 108, 7, 164, 11, 232, 13, 96, 27, 25, 34, 23, 54, 52, 31, 32, 25, 12, 7, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 8, 2, 236, 4, 108, 7, 164, 11, 232, 13, 96, 27, 0, 27, 20, 48, 46, 28, 28, 22, 11, 6, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 185, 0, 5, 0, 1, 0, 140, 0, 224, 1, 128, 5, 16, 9, 148, 12, 41, 14, 32, 27, 45, 44, 22, 54, 66, 60, 49, 40, 20, 6, 170, 135, 165, 120, 120, 120, 140, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 140, 0, 224, 1, 128, 5, 16, 9, 148, 12, 41, 14, 32, 27, 40, 61, 24, 64, 77, 71, 57, 47, 23, 7, 170, 135, 165, 120, 120, 120, 140, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 141, 0, 218, 1, 146, 5, 128, 8, 118, 12, 78, 14, 35, 27, 50, 48, 24, 59, 69, 58, 47, 38, 17, 6, 170, 135, 163, 120, 120, 120, 140, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 142, 0, 212, 1, 164, 5, 240, 7, 88, 12, 116, 14, 38, 27, 50, 43, 25, 58, 64, 49, 39, 33, 12, 6, 170, 135, 161, 120, 120, 120, 140, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 142, 0, 208, 1, 160, 5, 208, 7, 88, 12, 136, 14, 38, 27, 0, 38, 24, 54, 60, 42, 36, 30, 10, 6, 170, 135, 161, 120, 120, 120, 140, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 210, 0, 5, 0, 1, 0, 232, 0, 100, 2, 232, 3, 40, 10, 224, 11, 222, 13, 32, 28, 40, 51, 23, 55, 71, 34, 35, 23, 12, 5, 182, 127, 125, 120, 120, 120, 182, 127, 125, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 232, 0, 100, 2, 232, 3, 40, 10, 224, 11, 222, 13, 32, 28, 50, 93, 31, 75, 97, 47, 47, 31, 17, 7, 182, 127, 125, 120, 120, 120, 182, 127, 125, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 232, 0, 96, 2, 232, 3, 20, 10, 224, 11, 222, 13, 32, 28, 80, 72, 29, 68, 84, 42, 43, 28, 15, 6, 182, 127, 125, 120, 120, 120, 182, 127, 125, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 116, 0, 0, 2, 176, 4, 8, 7, 144, 11, 172, 13, 96, 27, 40, 42, 26, 59, 59, 35, 36, 28, 14, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 116, 0, 0, 2, 176, 4, 8, 7, 144, 11, 172, 13, 96, 27, 0, 35, 24, 54, 54, 32, 33, 25, 12, 7, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 165, 0, 4, 0, 1, 0, 232, 0, 200, 2, 232, 3, 60, 10, 224, 11, 222, 13, 160, 28, 45, 58, 33, 56, 73, 34, 35, 23, 9, 8, 230, 150, 120, 120, 120, 120, 185, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 232, 0, 144, 2, 232, 3, 60, 10, 224, 11, 222, 13, 32, 28, 80, 94, 29, 78, 98, 44, 45, 29, 16, 7, 182, 150, 120, 120, 120, 120, 182, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 232, 0, 144, 2, 232, 3, 60, 10, 224, 11, 222, 13, 32, 28, 40, 75, 28, 73, 83, 42, 42, 28, 15, 6, 182, 150, 120, 120, 120, 120, 182, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 228, 0, 118, 2, 192, 3, 140, 10, 224, 11, 66, 14, 32, 28, 0, 45, 29, 49, 70, 38, 37, 23, 12, 9, 177, 150, 120, 120, 120, 120, 177, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 220, 0, 5, 0, 1, 0, 168, 0, 212, 1, 72, 3, 100, 10, 124, 11, 196, 14, 32, 27, 45, 50, 23, 51, 59, 38, 35, 17, 13, 5, 165, 135, 150, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 168, 0, 212, 1, 72, 3, 100, 10, 124, 11, 196, 14, 32, 27, 55, 96, 32, 72, 82, 53, 48, 24, 18, 7, 165, 135, 150, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 168, 0, 212, 1, 72, 3, 100, 10, 124, 11, 196, 14, 32, 27, 75, 78, 29, 64, 74, 48, 44, 22, 16, 6, 165, 135, 150, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 116, 0, 8, 2, 136, 4, 108, 7, 144, 11, 116, 14, 96, 27, 45, 35, 24, 54, 54, 32, 33, 25, 12, 7, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 116, 0, 8, 2, 136, 4, 108, 7, 124, 11, 212, 13, 96, 27, 0, 31, 22, 50, 50, 30, 31, 24, 12, 7, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 185, 0, 4, 0, 1, 0, 228, 0, 145, 2, 76, 4, 143, 10, 188, 12, 99, 14, 87, 27, 45, 46, 26, 53, 66, 37, 34, 31, 11, 5, 167, 143, 143, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 228, 0, 145, 2, 76, 4, 143, 10, 188, 12, 99, 14, 87, 27, 60, 89, 36, 74, 92, 52, 48, 43, 15, 7, 167, 143, 143, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 228, 0, 145, 2, 96, 4, 143, 10, 188, 12, 99, 14, 87, 27, 80, 77, 34, 70, 87, 49, 45, 40, 14, 7, 167, 143, 143, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 228, 0, 145, 2, 96, 4, 143, 10, 188, 12, 99, 14, 87, 27, 0, 44, 25, 53, 65, 37, 34, 30, 10, 5, 167, 143, 143, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 0, 0, 5, 0, 1, 0, 84, 0, 96, 1, 180, 5, 212, 8, 148, 12, 41, 14, 64, 26, 42, 46, 16, 68, 54, 38, 38, 35, 11, 7, 162, 150, 135, 120, 120, 120, 102, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 84, 0, 96, 1, 140, 5, 212, 8, 148, 12, 116, 14, 192, 25, 40, 71, 20, 82, 78, 69, 54, 50, 17, 7, 167, 135, 135, 120, 120, 120, 107, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 88, 0, 96, 1, 120, 5, 172, 8, 148, 12, 116, 14, 192, 25, 50, 67, 21, 84, 64, 66, 50, 47, 19, 7, 167, 120, 135, 120, 120, 120, 107, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 98, 0, 80, 1, 236, 4, 179, 8, 86, 12, 118, 14, 218, 25, 67, 47, 15, 71, 56, 50, 40, 37, 15, 7, 166, 127, 128, 120, 120, 120, 107, 90, 128, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 109, 0, 64, 1, 96, 4, 187, 8, 23, 12, 121, 14, 244, 25, 0, 28, 8, 51, 43, 31, 28, 25, 11, 6, 165, 135, 138, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 210, 0, 5, 0, 1, 0, 229, 0, 16, 3, 40, 5, 60, 10, 52, 13, 160, 15, 238, 27, 45, 46, 31, 58, 62, 38, 39, 24, 12, 5, 186, 155, 145, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 229, 0, 16, 3, 40, 5, 60, 10, 52, 13, 160, 15, 238, 27, 80, 88, 43, 81, 86, 54, 54, 34, 18, 7, 186, 155, 145, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 224, 0, 234, 2, 20, 5, 80, 10, 248, 12, 140, 15, 220, 27, 45, 70, 38, 71, 76, 47, 47, 29, 16, 6, 184, 154, 145, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 185, 0, 64, 2, 16, 4, 68, 10, 8, 12, 20, 15, 89, 27, 40, 35, 22, 45, 48, 29, 25, 16, 10, 4, 172, 140, 148, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 168, 0, 240, 1, 132, 3, 60, 10, 144, 11, 176, 14, 32, 27, 0, 33, 21, 45, 47, 28, 23, 14, 10, 4, 167, 135, 150, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 45, 0, 5, 0, 1, 0, 169, 0, 37, 2, 92, 4, 76, 9, 72, 13, 64, 16, 98, 27, 45, 34, 28, 49, 54, 38, 33, 24, 14, 5, 167, 141, 152, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 169, 0, 37, 2, 92, 4, 76, 9, 72, 13, 64, 16, 98, 27, 80, 60, 37, 64, 72, 50, 44, 32, 19, 7, 167, 141, 152, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 160, 0, 8, 2, 212, 3, 36, 9, 32, 13, 64, 16, 71, 27, 50, 60, 30, 61, 71, 48, 45, 25, 17, 6, 167, 144, 151, 120, 120, 120, 197, 120, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 178, 0, 162, 1, 77, 3, 116, 9, 7, 13, 160, 15, 178, 26, 40, 36, 21, 45, 48, 32, 27, 19, 13, 6, 163, 137, 150, 120, 120, 120, 197, 120, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 184, 0, 128, 1, 32, 3, 156, 9, 12, 13, 160, 15, 128, 26, 0, 29, 19, 41, 41, 27, 22, 17, 12, 5, 162, 135, 150, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 205, 0, 6, 0, 5, 0, 28, 1, 28, 3, 236, 4, 50, 10, 112, 13, 254, 14, 176, 27, 45, 51, 30, 69, 65, 42, 35, 25, 7, 5, 192, 145, 135, 120, 120, 120, 167, 135, 165, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 28, 1, 28, 3, 236, 4, 50, 10, 112, 13, 254, 14, 176, 27, 80, 96, 41, 94, 89, 58, 48, 34, 9, 7, 192, 145, 135, 120, 120, 120, 167, 135, 165, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 11, 1, 15, 3, 36, 5, 28, 10, 104, 13, 254, 14, 154, 27, 40, 71, 37, 82, 76, 51, 44, 33, 8, 6, 187, 148, 144, 120, 120, 120, 167, 135, 165, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 196, 0, 216, 2, 4, 6, 196, 9, 72, 13, 0, 15, 64, 27, 40, 47, 35, 66, 56, 47, 47, 43, 8, 7, 167, 162, 180, 120, 120, 120, 167, 132, 135, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 205, 0, 48, 2, 28, 7, 196, 9, 72, 13, 0, 15, 63, 27, 40, 38, 32, 56, 51, 47, 43, 41, 12, 8, 167, 120, 157, 120, 120, 120, 167, 120, 157, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 205, 0, 48, 2, 28, 7, 196, 9, 72, 13, 0, 15, 63, 27, 0, 35, 30, 53, 48, 45, 41, 39, 11, 7, 167, 120, 157, 120, 120, 120, 167, 120, 157, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 230, 0, 5, 0, 1, 0, 0, 1, 24, 2, 8, 7, 236, 9, 104, 13, 15, 15, 224, 28, 45, 30, 25, 47, 53, 44, 37, 27, 9, 6, 216, 138, 159, 120, 120, 120, 107, 138, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 0, 1, 24, 2, 8, 7, 236, 9, 104, 13, 15, 15, 224, 28, 90, 67, 38, 70, 80, 66, 56, 41, 13, 9, 216, 138, 159, 120, 120, 120, 107, 138, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 216, 0, 232, 1, 108, 7, 40, 10, 163, 13, 57, 15, 148, 28, 55, 56, 37, 67, 69, 62, 51, 39, 12, 9, 197, 114, 149, 120, 120, 120, 107, 131, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 144, 0, 125, 1, 52, 8, 148, 10, 188, 13, 76, 15, 32, 28, 40, 30, 27, 50, 48, 46, 40, 32, 9, 8, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 144, 0, 125, 1, 52, 8, 148, 10, 188, 13, 76, 15, 32, 28, 0, 27, 26, 47, 45, 44, 38, 30, 8, 8, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 165, 0, 5, 0, 1, 0, 179, 0, 40, 2, 172, 3, 96, 10, 15, 12, 141, 14, 32, 27, 45, 47, 26, 53, 60, 38, 37, 17, 13, 5, 166, 135, 150, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 179, 0, 40, 2, 172, 3, 96, 10, 15, 12, 141, 14, 32, 27, 75, 97, 37, 76, 86, 54, 53, 25, 18, 7, 166, 135, 150, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 179, 0, 27, 2, 0, 4, 91, 10, 35, 12, 144, 14, 18, 27, 50, 68, 33, 68, 75, 49, 48, 24, 16, 7, 165, 134, 149, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 180, 0, 158, 1, 244, 6, 38, 10, 218, 12, 175, 14, 141, 26, 45, 32, 22, 50, 42, 40, 36, 27, 10, 5, 161, 128, 142, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 181, 0, 144, 1, 13, 7, 32, 10, 239, 12, 179, 14, 126, 26, 0, 24, 20, 46, 38, 37, 34, 26, 9, 4, 160, 127, 142, 120, 120, 120, 130, 87, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 230, 0, 6, 0, 1, 0, 14, 1, 24, 2, 240, 6, 236, 9, 112, 13, 80, 15, 186, 28, 50, 42, 28, 57, 61, 55, 44, 32, 10, 7, 211, 132, 156, 120, 120, 120, 107, 131, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 14, 1, 24, 2, 240, 6, 236, 9, 112, 13, 80, 15, 186, 28, 75, 67, 35, 72, 77, 70, 55, 40, 13, 8, 211, 132, 156, 120, 120, 120, 107, 131, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 14, 1, 24, 2, 240, 6, 196, 9, 112, 13, 80, 15, 186, 28, 45, 53, 31, 64, 69, 61, 48, 35, 11, 7, 211, 132, 156, 120, 120, 120, 107, 131, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 116, 0, 8, 2, 120, 5, 8, 7, 144, 11, 56, 14, 96, 27, 35, 31, 26, 49, 49, 29, 29, 23, 11, 6, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 116, 0, 8, 2, 120, 5, 8, 7, 144, 11, 252, 13, 96, 27, 25, 28, 25, 47, 47, 27, 28, 21, 10, 6, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 8, 2, 120, 5, 8, 7, 144, 11, 252, 13, 96, 27, 0, 24, 23, 44, 44, 25, 26, 20, 10, 5, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 250, 0, 6, 0, 1, 0, 187, 0, 149, 1, 140, 7, 245, 9, 50, 13, 120, 15, 96, 25, 45, 42, 25, 69, 36, 43, 43, 26, 10, 4, 160, 90, 120, 122, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 187, 0, 149, 1, 140, 7, 245, 9, 50, 13, 120, 15, 96, 25, 65, 78, 34, 94, 50, 59, 59, 35, 14, 6, 160, 90, 120, 122, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 187, 0, 149, 1, 140, 7, 196, 9, 50, 13, 120, 15, 96, 25, 45, 58, 30, 82, 43, 44, 47, 30, 12, 5, 160, 90, 120, 145, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 120, 0, 250, 1, 144, 6, 188, 7, 164, 11, 16, 14, 13, 27, 50, 27, 25, 49, 47, 29, 30, 22, 10, 6, 166, 144, 133, 123, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 120, 0, 250, 1, 180, 5, 28, 7, 144, 11, 252, 13, 44, 27, 45, 27, 27, 49, 47, 29, 30, 22, 10, 6, 166, 144, 133, 123, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 120, 0, 250, 1, 180, 5, 28, 7, 144, 11, 252, 13, 44, 27, 0, 24, 25, 46, 44, 28, 28, 21, 10, 5, 166, 144, 133, 123, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 220, 0, 5, 0, 1, 0, 116, 0, 200, 1, 56, 4, 96, 9, 168, 12, 96, 14, 96, 27, 45, 43, 28, 58, 58, 33, 36, 30, 16, 5, 167, 140, 135, 120, 120, 120, 197, 110, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 116, 0, 200, 1, 56, 4, 96, 9, 168, 12, 96, 14, 96, 27, 80, 66, 35, 71, 71, 41, 44, 37, 19, 7, 167, 140, 135, 120, 120, 120, 197, 110, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 116, 0, 208, 1, 56, 4, 46, 9, 140, 12, 98, 14, 96, 27, 55, 59, 33, 68, 68, 39, 42, 35, 18, 7, 167, 141, 135, 120, 120, 120, 197, 110, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 116, 0, 8, 2, 156, 4, 188, 7, 104, 11, 212, 13, 96, 27, 40, 39, 25, 57, 57, 33, 35, 27, 13, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 116, 0, 8, 2, 156, 4, 188, 7, 104, 11, 212, 13, 96, 27, 0, 32, 23, 51, 51, 30, 31, 24, 12, 7, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 70, 0, 6, 0, 1, 0, 240, 0, 224, 2, 196, 4, 140, 10, 232, 13, 160, 15, 64, 27, 45, 54, 29, 64, 70, 37, 40, 32, 5, 6, 167, 135, 165, 120, 120, 120, 167, 135, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 240, 0, 224, 2, 196, 4, 140, 10, 232, 13, 160, 15, 64, 27, 50, 83, 36, 79, 86, 46, 50, 39, 6, 7, 167, 135, 165, 120, 120, 120, 167, 135, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 224, 0, 208, 2, 136, 5, 176, 9, 36, 14, 180, 15, 117, 27, 68, 67, 36, 71, 61, 44, 40, 37, 15, 4, 196, 162, 200, 120, 120, 120, 249, 174, 255, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 195, 0, 112, 2, 238, 5, 126, 9, 76, 14, 240, 15, 35, 27, 40, 57, 34, 66, 59, 45, 41, 34, 14, 5, 181, 137, 168, 120, 120, 120, 249, 174, 255, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 160, 0, 72, 2, 220, 5, 96, 9, 16, 14, 44, 16, 199, 27, 25, 38, 30, 53, 56, 42, 36, 23, 14, 5, 171, 161, 165, 121, 122, 125, 171, 137, 172, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 160, 0, 72, 2, 220, 5, 96, 9, 16, 14, 44, 16, 199, 27, 0, 32, 28, 49, 52, 39, 33, 22, 13, 5, 171, 161, 165, 121, 122, 125, 171, 137, 172, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 70, 0, 6, 0, 1, 0, 240, 0, 224, 2, 196, 4, 140, 10, 232, 13, 160, 15, 64, 27, 45, 54, 29, 64, 70, 37, 40, 32, 5, 6, 167, 135, 165, 120, 120, 120, 167, 135, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 240, 0, 224, 2, 196, 4, 140, 10, 232, 13, 160, 15, 64, 27, 50, 83, 36, 79, 86, 46, 50, 39, 6, 7, 167, 135, 165, 120, 120, 120, 167, 135, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 224, 0, 208, 2, 136, 5, 176, 9, 36, 14, 180, 15, 117, 27, 68, 66, 36, 71, 61, 44, 40, 36, 15, 4, 196, 162, 200, 120, 120, 120, 249, 174, 255, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 165, 0, 16, 2, 84, 6, 76, 9, 116, 14, 44, 16, 208, 26, 40, 39, 31, 61, 57, 48, 42, 34, 14, 6, 165, 113, 136, 120, 120, 120, 130, 113, 136, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 160, 0, 16, 2, 220, 5, 232, 8, 232, 13, 44, 16, 199, 27, 25, 39, 28, 53, 56, 42, 36, 23, 14, 5, 171, 161, 165, 121, 122, 125, 171, 137, 172, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 151, 0, 12, 2, 190, 5, 142, 8, 42, 13, 100, 15, 119, 27, 0, 30, 24, 46, 52, 37, 32, 24, 11, 5, 170, 148, 163, 120, 121, 122, 171, 137, 172, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 19, 1, 7, 0, 1, 0, 229, 0, 16, 3, 40, 5, 60, 10, 52, 13, 160, 15, 238, 27, 45, 46, 31, 58, 62, 38, 39, 24, 12, 5, 186, 155, 145, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 229, 0, 16, 3, 40, 5, 60, 10, 52, 13, 160, 15, 238, 27, 75, 88, 43, 81, 86, 54, 54, 34, 18, 7, 186, 155, 145, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 224, 0, 234, 2, 20, 5, 40, 10, 248, 12, 140, 15, 220, 27, 45, 70, 38, 71, 76, 47, 47, 29, 16, 6, 184, 154, 145, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 185, 0, 64, 2, 76, 4, 236, 9, 28, 12, 20, 15, 89, 27, 40, 32, 23, 45, 48, 29, 25, 16, 10, 4, 172, 140, 148, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 164, 0, 8, 2, 0, 5, 10, 9, 38, 12, 216, 14, 64, 27, 40, 25, 19, 41, 45, 29, 25, 18, 9, 4, 171, 137, 155, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 153, 0, 236, 1, 50, 5, 109, 8, 53, 12, 186, 14, 51, 27, 30, 23, 17, 39, 44, 29, 25, 19, 8, 4, 170, 136, 158, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 1, 0, 142, 0, 208, 1, 100, 5, 208, 7, 68, 12, 156, 14, 38, 27, 0, 15, 14, 34, 39, 27, 23, 19, 6, 3, 170, 135, 161, 120, 120, 120, 140, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 232, 65, 0, 191, 129, 244, 194, 182, 76, 250, 23, 8, 165, 0, 4, 0, 1, 0, 204, 0, 100, 2, 208, 4, 60, 10, 168, 12, 10, 15, 0, 28, 45, 66, 33, 67, 77, 42, 51, 25, 15, 6, 170, 165, 150, 120, 120, 120, 170, 180, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 204, 0, 100, 2, 208, 4, 60, 10, 168, 12, 10, 15, 0, 28, 80, 101, 41, 84, 95, 52, 63, 31, 18, 8, 170, 165, 150, 120, 120, 120, 170, 180, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 204, 0, 100, 2, 208, 4, 60, 10, 168, 12, 10, 15, 0, 28, 40, 83, 37, 76, 87, 48, 57, 28, 17, 7, 170, 165, 150, 120, 120, 120, 170, 180, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 204, 0, 100, 2, 216, 4, 60, 10, 168, 12, 10, 15, 0, 28, 0, 51, 31, 59, 68, 37, 45, 22, 13, 9, 167, 165, 150, 120, 120, 120, 167, 180, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 195, 0, 4, 0, 1, 0, 24, 1, 16, 3, 156, 4, 120, 10, 152, 13, 60, 15, 32, 28, 45, 52, 29, 59, 64, 45, 35, 22, 10, 5, 186, 152, 135, 120, 120, 120, 192, 155, 150, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 24, 1, 16, 3, 156, 4, 120, 10, 152, 13, 60, 15, 32, 28, 80, 99, 40, 81, 89, 62, 48, 31, 14, 7, 186, 152, 135, 120, 120, 120, 192, 155, 150, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 24, 1, 16, 3, 156, 4, 120, 10, 152, 13, 60, 15, 32, 28, 70, 89, 38, 77, 84, 59, 45, 29, 14, 7, 186, 152, 135, 120, 120, 120, 192, 155, 150, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 24, 1, 8, 3, 176, 4, 120, 10, 152, 13, 60, 15, 32, 28, 0, 47, 28, 58, 61, 42, 33, 22, 10, 5, 186, 152, 135, 120, 120, 120, 192, 155, 150, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 160, 0, 4, 0, 1, 0, 215, 0, 6, 2, 128, 7, 236, 9, 251, 12, 61, 14, 144, 28, 50, 45, 31, 61, 55, 60, 46, 36, 11, 8, 175, 109, 133, 120, 120, 120, 160, 105, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 215, 0, 6, 2, 128, 7, 236, 9, 251, 12, 61, 14, 144, 28, 70, 80, 42, 81, 74, 80, 61, 48, 15, 11, 175, 109, 133, 120, 120, 120, 160, 105, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 202, 0, 62, 2, 30, 7, 236, 9, 82, 13, 228, 14, 207, 28, 40, 62, 39, 70, 73, 69, 53, 39, 13, 8, 195, 127, 153, 120, 120, 120, 160, 105, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 200, 0, 69, 2, 18, 7, 236, 9, 92, 13, 247, 14, 215, 28, 0, 35, 29, 51, 54, 50, 39, 28, 9, 6, 198, 129, 156, 120, 120, 120, 198, 105, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 170, 0, 4, 0, 1, 0, 154, 0, 248, 1, 164, 6, 176, 9, 238, 12, 216, 14, 96, 26, 50, 39, 29, 58, 54, 47, 42, 30, 14, 6, 163, 133, 150, 120, 120, 120, 130, 128, 142, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 154, 0, 248, 1, 164, 6, 176, 9, 238, 12, 216, 14, 96, 26, 60, 76, 41, 81, 76, 65, 58, 42, 20, 8, 163, 133, 150, 120, 120, 120, 130, 128, 142, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 154, 0, 248, 1, 164, 6, 176, 9, 238, 12, 216, 14, 96, 26, 60, 68, 39, 77, 72, 62, 55, 40, 18, 7, 163, 133, 150, 120, 120, 120, 130, 128, 142, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 154, 0, 248, 1, 164, 6, 176, 9, 238, 12, 216, 14, 96, 26, 0, 34, 27, 54, 50, 44, 39, 28, 13, 5, 163, 133, 150, 120, 120, 120, 130, 128, 142, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 200, 0, 4, 0, 1, 0, 184, 0, 8, 2, 208, 7, 236, 9, 248, 12, 66, 14, 128, 28, 50, 40, 27, 55, 61, 58, 43, 32, 11, 8, 185, 117, 127, 120, 120, 120, 185, 117, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 184, 0, 8, 2, 208, 7, 236, 9, 248, 12, 66, 14, 128, 28, 70, 76, 38, 76, 83, 80, 60, 44, 16, 12, 185, 117, 127, 120, 120, 120, 185, 117, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 184, 0, 8, 2, 208, 7, 236, 9, 248, 12, 66, 14, 128, 28, 80, 43, 28, 57, 62, 60, 45, 33, 12, 9, 185, 117, 127, 120, 120, 120, 185, 117, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 184, 0, 8, 2, 208, 7, 236, 9, 248, 12, 66, 14, 128, 28, 0, 27, 22, 45, 50, 48, 36, 26, 9, 7, 185, 117, 127, 120, 120, 120, 185, 117, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 150, 0, 4, 0, 1, 0, 199, 0, 54, 2, 122, 3, 81, 10, 163, 11, 54, 14, 159, 27, 50, 61, 22, 57, 69, 34, 33, 19, 12, 5, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 199, 0, 54, 2, 122, 3, 81, 10, 163, 11, 54, 14, 159, 27, 60, 115, 30, 78, 96, 47, 45, 26, 17, 7, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 199, 0, 54, 2, 122, 3, 81, 10, 163, 11, 54, 14, 159, 27, 40, 104, 29, 74, 91, 45, 43, 25, 16, 6, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 199, 0, 54, 2, 122, 3, 81, 10, 163, 11, 54, 14, 159, 27, 0, 52, 20, 52, 64, 32, 30, 17, 11, 4, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 175, 0, 4, 0, 1, 0, 216, 0, 160, 2, 156, 4, 35, 10, 227, 12, 20, 15, 214, 27, 45, 44, 27, 54, 58, 34, 31, 24, 12, 4, 189, 159, 136, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 216, 0, 160, 2, 156, 4, 35, 10, 227, 12, 20, 15, 214, 27, 80, 96, 40, 81, 86, 51, 46, 36, 18, 7, 189, 159, 136, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 216, 0, 160, 2, 156, 4, 35, 10, 227, 12, 20, 15, 214, 27, 50, 85, 38, 76, 81, 48, 44, 34, 17, 6, 189, 159, 136, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 216, 0, 160, 2, 156, 4, 35, 10, 227, 12, 20, 15, 214, 27, 0, 42, 27, 54, 57, 34, 31, 24, 12, 4, 189, 159, 136, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 195, 0, 4, 0, 1, 0, 135, 0, 151, 1, 220, 5, 112, 8, 188, 12, 136, 14, 153, 24, 45, 43, 21, 58, 55, 49, 40, 32, 10, 11, 178, 126, 132, 123, 123, 141, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 135, 0, 151, 1, 220, 5, 112, 8, 188, 12, 136, 14, 153, 24, 80, 65, 26, 72, 68, 61, 49, 39, 12, 13, 178, 126, 132, 123, 123, 141, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 135, 0, 151, 1, 220, 5, 112, 8, 188, 12, 136, 14, 153, 24, 70, 56, 24, 67, 63, 56, 45, 36, 12, 12, 178, 126, 132, 123, 123, 141, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 135, 0, 136, 1, 220, 5, 112, 8, 188, 12, 136, 14, 153, 24, 0, 38, 20, 55, 52, 46, 37, 30, 9, 10, 178, 126, 132, 123, 123, 141, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 240, 0, 7, 0, 1, 0, 24, 1, 240, 2, 166, 4, 80, 10, 192, 13, 150, 15, 32, 28, 45, 57, 30, 66, 66, 46, 36, 23, 11, 5, 186, 152, 135, 120, 120, 120, 192, 155, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 24, 1, 240, 2, 166, 4, 80, 10, 192, 13, 150, 15, 32, 28, 70, 109, 41, 91, 91, 63, 49, 32, 15, 8, 186, 152, 135, 120, 120, 120, 192, 155, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 24, 1, 228, 2, 175, 4, 58, 10, 204, 13, 162, 15, 32, 28, 50, 94, 40, 84, 85, 57, 48, 31, 14, 7, 186, 152, 135, 120, 120, 120, 192, 155, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 5, 0, 24, 1, 199, 2, 196, 4, 4, 10, 232, 13, 192, 15, 32, 28, 30, 77, 38, 76, 78, 46, 47, 29, 13, 7, 186, 152, 135, 120, 120, 120, 192, 155, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 5, 0, 24, 1, 184, 2, 20, 5, 176, 9, 244, 11, 120, 15, 32, 28, 25, 31, 28, 51, 40, 30, 33, 20, 9, 5, 186, 152, 135, 120, 120, 120, 192, 155, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 24, 1, 176, 2, 40, 5, 176, 9, 204, 11, 236, 14, 32, 28, 20, 30, 28, 52, 24, 7, 14, 14, 9, 5, 186, 152, 135, 120, 120, 120, 192, 155, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 1, 0, 24, 1, 176, 2, 40, 5, 176, 9, 204, 11, 236, 14, 32, 28, 0, 33, 28, 52, 40, 31, 33, 14, 9, 5, 186, 152, 135, 120, 120, 120, 192, 155, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 232, 65, 0, 191, 129, 244, 194, 182, 76, 250, 23, 8, 240, 0, 5, 0, 1, 0, 200, 0, 208, 1, 188, 7, 216, 9, 248, 12, 66, 14, 128, 28, 45, 44, 25, 57, 57, 61, 46, 35, 10, 8, 185, 107, 127, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 200, 0, 208, 1, 188, 7, 216, 9, 248, 12, 66, 14, 128, 28, 70, 77, 34, 75, 75, 81, 61, 46, 14, 10, 185, 107, 127, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 199, 0, 227, 1, 131, 7, 210, 9, 248, 12, 73, 14, 106, 28, 75, 67, 33, 72, 72, 74, 57, 43, 14, 9, 184, 111, 127, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 186, 0, 146, 2, 128, 5, 156, 9, 248, 12, 141, 14, 160, 27, 50, 62, 37, 71, 79, 48, 44, 32, 16, 0, 180, 150, 125, 120, 120, 120, 200, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 186, 0, 146, 2, 128, 5, 156, 9, 248, 12, 141, 14, 160, 27, 0, 38, 29, 56, 62, 38, 35, 25, 13, 0, 180, 150, 125, 120, 120, 120, 200, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 45, 0, 4, 0, 1, 0, 152, 0, 72, 1, 76, 9, 124, 11, 172, 13, 120, 15, 160, 26, 45, 41, 17, 60, 53, 49, 49, 26, 12, 6, 167, 105, 120, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 152, 0, 72, 1, 76, 9, 124, 11, 172, 13, 120, 15, 160, 26, 100, 69, 22, 78, 70, 64, 64, 34, 16, 8, 167, 105, 120, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 152, 0, 24, 1, 136, 9, 164, 11, 16, 14, 120, 15, 160, 26, 40, 67, 21, 74, 66, 57, 61, 32, 15, 7, 167, 97, 120, 120, 120, 120, 167, 97, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 152, 0, 24, 1, 136, 9, 164, 11, 16, 14, 120, 15, 160, 26, 0, 38, 16, 56, 50, 43, 46, 24, 11, 5, 167, 97, 120, 120, 120, 120, 167, 97, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 150, 0, 4, 0, 1, 0, 192, 0, 40, 2, 112, 3, 100, 10, 164, 11, 96, 14, 159, 27, 50, 59, 24, 59, 64, 35, 34, 20, 12, 5, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 192, 0, 40, 2, 112, 3, 100, 10, 164, 11, 96, 14, 159, 27, 60, 124, 36, 85, 93, 52, 50, 29, 18, 7, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 192, 0, 40, 2, 132, 3, 100, 10, 164, 11, 96, 14, 159, 27, 40, 97, 32, 77, 83, 46, 45, 26, 16, 7, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 192, 0, 40, 2, 56, 4, 0, 10, 104, 11, 36, 14, 159, 27, 0, 34, 21, 51, 55, 31, 30, 17, 11, 4, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 185, 0, 6, 0, 1, 0, 153, 0, 168, 1, 12, 3, 120, 10, 168, 12, 196, 14, 244, 26, 45, 64, 21, 71, 54, 37, 41, 30, 17, 7, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 153, 0, 168, 1, 12, 3, 120, 10, 168, 12, 196, 14, 244, 26, 60, 89, 25, 84, 64, 44, 49, 36, 20, 9, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 153, 0, 192, 1, 32, 3, 120, 10, 168, 12, 176, 14, 244, 26, 50, 79, 23, 79, 60, 41, 41, 38, 19, 8, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 153, 0, 224, 1, 112, 3, 196, 9, 168, 12, 156, 14, 244, 26, 45, 68, 32, 75, 57, 21, 39, 36, 18, 8, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 153, 0, 248, 1, 172, 3, 252, 8, 128, 12, 116, 14, 244, 26, 30, 33, 28, 54, 31, 23, 28, 25, 11, 6, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 153, 0, 248, 1, 172, 3, 28, 7, 84, 11, 72, 13, 244, 26, 0, 31, 27, 51, 38, 16, 27, 24, 10, 6, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 195, 0, 4, 0, 1, 0, 135, 0, 136, 1, 164, 6, 192, 8, 188, 12, 128, 14, 153, 24, 45, 42, 22, 57, 51, 48, 39, 31, 10, 11, 178, 126, 132, 123, 123, 141, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 135, 0, 136, 1, 164, 6, 192, 8, 188, 12, 128, 14, 153, 24, 80, 73, 30, 76, 68, 64, 52, 41, 13, 14, 178, 126, 132, 123, 123, 141, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 135, 0, 136, 1, 164, 6, 192, 8, 188, 12, 128, 14, 153, 24, 70, 59, 27, 68, 61, 57, 46, 37, 12, 13, 178, 126, 132, 123, 123, 141, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 135, 0, 136, 1, 164, 6, 192, 8, 188, 12, 128, 14, 153, 24, 0, 37, 21, 53, 48, 45, 36, 29, 9, 10, 178, 126, 132, 123, 123, 141, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 235, 0, 5, 0, 1, 0, 24, 1, 186, 2, 40, 5, 180, 9, 98, 13, 20, 15, 71, 28, 45, 42, 28, 56, 57, 42, 34, 27, 9, 6, 210, 133, 142, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 24, 1, 186, 2, 40, 5, 180, 9, 98, 13, 20, 15, 71, 28, 60, 81, 39, 79, 80, 58, 48, 37, 13, 8, 210, 133, 142, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 10, 1, 145, 2, 70, 5, 166, 9, 86, 13, 2, 15, 254, 27, 80, 64, 33, 70, 69, 51, 43, 34, 11, 8, 205, 129, 141, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 132, 0, 24, 1, 84, 6, 36, 9, 228, 12, 96, 14, 100, 25, 50, 43, 19, 61, 41, 35, 38, 35, 9, 12, 165, 90, 135, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 132, 0, 24, 1, 64, 6, 36, 9, 228, 12, 96, 14, 100, 25, 0, 27, 15, 48, 33, 28, 30, 28, 7, 10, 165, 90, 135, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 220, 0, 5, 0, 1, 0, 153, 0, 156, 1, 248, 2, 120, 10, 148, 12, 176, 14, 244, 26, 50, 45, 14, 61, 43, 32, 35, 26, 14, 6, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 153, 0, 156, 1, 248, 2, 120, 10, 148, 12, 176, 14, 244, 26, 90, 77, 19, 79, 57, 41, 46, 34, 19, 8, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 153, 0, 156, 1, 248, 2, 120, 10, 148, 12, 176, 14, 244, 26, 50, 62, 17, 71, 51, 37, 41, 30, 17, 7, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 153, 0, 156, 1, 248, 2, 120, 10, 148, 12, 176, 14, 244, 26, 30, 51, 15, 65, 46, 34, 38, 28, 15, 7, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 153, 0, 156, 1, 248, 2, 120, 10, 148, 12, 176, 14, 244, 26, 0, 30, 11, 50, 35, 26, 29, 21, 11, 5, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 6, 0, 1, 0, 51, 1, 124, 3, 60, 5, 124, 10, 93, 13, 187, 14, 253, 27, 45, 59, 32, 70, 62, 38, 33, 22, 10, 5, 205, 152, 124, 120, 120, 120, 249, 174, 255, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 51, 1, 124, 3, 60, 5, 124, 10, 93, 13, 187, 14, 253, 27, 50, 117, 45, 99, 87, 54, 47, 31, 15, 7, 205, 152, 124, 120, 120, 120, 249, 174, 255, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 9, 1, 254, 2, 28, 6, 68, 10, 45, 13, 119, 14, 49, 28, 50, 93, 43, 90, 79, 62, 51, 33, 14, 8, 187, 133, 125, 120, 120, 120, 249, 174, 255, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 200, 0, 64, 2, 108, 7, 240, 9, 228, 12, 16, 14, 128, 28, 50, 57, 37, 72, 64, 71, 54, 34, 13, 10, 160, 105, 127, 120, 120, 120, 160, 105, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 224, 0, 40, 2, 8, 7, 176, 9, 112, 13, 241, 14, 64, 27, 40, 42, 28, 60, 56, 56, 49, 43, 8, 8, 255, 90, 180, 120, 120, 120, 187, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 224, 0, 40, 2, 8, 7, 176, 9, 112, 13, 241, 14, 64, 27, 0, 34, 25, 54, 50, 50, 44, 39, 7, 7, 255, 90, 180, 120, 120, 120, 187, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 245, 0, 6, 0, 1, 0, 24, 1, 248, 2, 176, 4, 120, 10, 152, 13, 60, 15, 32, 28, 45, 60, 34, 66, 63, 43, 37, 24, 11, 6, 186, 152, 152, 120, 120, 120, 192, 155, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 24, 1, 248, 2, 176, 4, 120, 10, 152, 13, 60, 15, 32, 28, 60, 116, 48, 92, 88, 60, 52, 34, 16, 8, 186, 152, 152, 120, 120, 120, 192, 155, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 12, 1, 224, 2, 100, 5, 134, 10, 158, 13, 64, 15, 41, 28, 40, 94, 45, 93, 72, 60, 49, 33, 15, 8, 186, 148, 160, 120, 120, 120, 192, 155, 172, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 214, 0, 28, 2, 28, 7, 177, 10, 185, 13, 82, 15, 84, 28, 40, 65, 36, 72, 61, 57, 48, 35, 14, 9, 185, 127, 169, 120, 120, 120, 192, 155, 172, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 160, 0, 88, 1, 212, 8, 220, 10, 212, 13, 100, 15, 128, 28, 60, 41, 16, 61, 42, 44, 39, 30, 11, 8, 185, 107, 177, 120, 120, 120, 185, 107, 177, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 204, 0, 96, 1, 232, 8, 220, 10, 16, 14, 196, 19, 88, 27, 0, 33, 20, 48, 32, 36, 32, 12, 11, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 175, 0, 4, 0, 1, 0, 184, 0, 160, 1, 92, 8, 100, 10, 212, 13, 60, 15, 128, 28, 45, 39, 25, 53, 56, 47, 39, 34, 11, 8, 185, 107, 143, 120, 120, 120, 185, 107, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 184, 0, 160, 1, 92, 8, 100, 10, 212, 13, 60, 15, 128, 28, 70, 81, 37, 76, 80, 68, 56, 48, 16, 12, 185, 107, 143, 120, 120, 120, 185, 107, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 184, 0, 160, 1, 92, 8, 100, 10, 212, 13, 60, 15, 128, 28, 60, 66, 33, 68, 72, 61, 50, 43, 14, 10, 185, 107, 143, 120, 120, 120, 185, 107, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 184, 0, 160, 1, 92, 8, 100, 10, 212, 13, 60, 15, 128, 28, 0, 29, 22, 45, 48, 40, 33, 29, 9, 7, 185, 107, 143, 120, 120, 120, 185, 107, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 45, 0, 6, 0, 1, 0, 208, 0, 112, 2, 212, 3, 60, 10, 188, 12, 92, 14, 87, 27, 45, 57, 26, 56, 67, 40, 36, 33, 9, 5, 167, 147, 147, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 208, 0, 112, 2, 212, 3, 60, 10, 188, 12, 92, 14, 87, 27, 75, 104, 36, 76, 90, 54, 48, 44, 12, 7, 167, 147, 147, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 152, 0, 16, 2, 180, 5, 192, 8, 32, 13, 199, 14, 92, 26, 69, 77, 41, 83, 68, 57, 53, 42, 15, 8, 163, 119, 156, 137, 120, 120, 167, 142, 157, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 152, 0, 88, 1, 238, 7, 100, 10, 132, 13, 50, 15, 96, 25, 30, 59, 27, 78, 48, 48, 52, 30, 13, 6, 160, 92, 147, 155, 120, 120, 130, 95, 147, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 152, 0, 80, 1, 30, 8, 240, 10, 229, 13, 181, 15, 20, 26, 30, 78, 34, 87, 56, 53, 54, 37, 16, 8, 162, 95, 159, 149, 120, 120, 130, 95, 147, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 152, 0, 72, 1, 79, 8, 124, 11, 71, 14, 56, 16, 200, 26, 0, 38, 27, 58, 40, 35, 32, 27, 12, 7, 165, 99, 171, 142, 120, 120, 130, 99, 147, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 210, 0, 5, 0, 1, 0, 148, 0, 128, 1, 238, 7, 60, 10, 42, 13, 50, 15, 96, 25, 45, 39, 23, 65, 47, 43, 41, 26, 10, 5, 160, 92, 120, 143, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 148, 0, 128, 1, 238, 7, 60, 10, 42, 13, 50, 15, 96, 25, 60, 71, 32, 88, 64, 58, 55, 35, 14, 6, 160, 92, 120, 143, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 148, 0, 128, 1, 228, 7, 216, 9, 248, 12, 0, 15, 96, 25, 60, 62, 27, 83, 60, 55, 52, 33, 13, 6, 160, 92, 120, 155, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 120, 0, 250, 1, 144, 6, 188, 7, 164, 11, 16, 14, 13, 27, 45, 27, 24, 49, 46, 29, 30, 22, 11, 6, 166, 144, 133, 123, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 120, 0, 250, 1, 180, 5, 28, 7, 144, 11, 252, 13, 44, 27, 0, 26, 24, 49, 46, 29, 30, 22, 11, 6, 166, 144, 133, 123, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 75, 0, 5, 0, 1, 0, 135, 0, 88, 1, 224, 6, 192, 8, 188, 12, 128, 14, 153, 24, 45, 51, 22, 63, 57, 50, 41, 32, 10, 11, 178, 126, 132, 123, 123, 141, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 135, 0, 88, 1, 204, 6, 192, 8, 188, 12, 128, 14, 153, 24, 70, 74, 26, 76, 68, 61, 49, 39, 12, 13, 178, 126, 132, 123, 123, 141, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 150, 0, 162, 1, 48, 6, 246, 8, 164, 12, 131, 14, 85, 25, 70, 70, 30, 74, 72, 56, 45, 37, 13, 9, 178, 128, 130, 122, 122, 134, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 186, 0, 80, 2, 196, 4, 116, 9, 108, 12, 141, 14, 13, 27, 30, 64, 37, 70, 79, 47, 38, 32, 16, 0, 180, 135, 125, 120, 120, 120, 200, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 186, 0, 80, 2, 196, 4, 96, 9, 108, 12, 141, 14, 13, 27, 0, 49, 32, 61, 69, 41, 33, 28, 14, 0, 180, 135, 125, 120, 120, 120, 200, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 4, 0, 1, 0, 196, 0, 104, 2, 252, 3, 0, 10, 28, 12, 116, 14, 119, 26, 53, 61, 35, 71, 73, 28, 34, 20, 9, 8, 162, 105, 132, 120, 120, 120, 162, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 7, 0, 208, 0, 48, 2, 132, 3, 220, 10, 204, 11, 141, 14, 0, 26, 24, 60, 38, 81, 60, 33, 35, 16, 11, 8, 162, 105, 87, 120, 120, 120, 162, 75, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 208, 0, 229, 1, 123, 3, 220, 10, 204, 11, 141, 14, 0, 26, 51, 41, 30, 65, 48, 27, 28, 13, 9, 6, 162, 105, 87, 120, 120, 120, 162, 75, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 136, 0, 194, 1, 24, 3, 164, 11, 68, 12, 241, 14, 0, 26, 0, 25, 28, 46, 28, 24, 20, 16, 11, 8, 162, 135, 87, 120, 120, 120, 162, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 135, 0, 3, 0, 1, 0, 176, 0, 72, 2, 160, 5, 156, 9, 188, 12, 116, 14, 88, 27, 45, 50, 33, 60, 73, 41, 39, 33, 17, 6, 167, 135, 135, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 176, 0, 72, 2, 160, 5, 156, 9, 188, 12, 116, 14, 88, 27, 90, 78, 41, 75, 91, 51, 49, 41, 21, 8, 167, 135, 135, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 176, 0, 88, 2, 160, 5, 156, 9, 188, 12, 116, 14, 88, 27, 0, 33, 27, 50, 60, 34, 32, 27, 14, 5, 167, 135, 135, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 185, 0, 4, 0, 1, 0, 240, 0, 224, 2, 4, 6, 196, 9, 92, 13, 80, 15, 153, 28, 45, 37, 29, 51, 56, 41, 29, 26, 9, 5, 197, 176, 161, 135, 120, 120, 220, 176, 161, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 240, 0, 224, 2, 4, 6, 196, 9, 92, 13, 80, 15, 153, 28, 80, 59, 37, 64, 71, 53, 37, 33, 11, 6, 197, 176, 161, 135, 120, 120, 220, 176, 161, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 240, 0, 232, 2, 4, 6, 196, 9, 92, 13, 80, 15, 153, 28, 60, 55, 35, 64, 64, 50, 35, 31, 11, 6, 197, 179, 161, 135, 120, 120, 220, 179, 161, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 240, 0, 240, 2, 4, 6, 196, 9, 92, 13, 80, 15, 153, 28, 0, 33, 27, 50, 50, 39, 27, 24, 8, 5, 197, 179, 161, 135, 120, 120, 220, 179, 161, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 170, 0, 4, 0, 1, 0, 64, 1, 72, 2, 28, 7, 0, 10, 104, 13, 15, 15, 224, 28, 50, 34, 26, 48, 51, 47, 36, 27, 9, 5, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 64, 1, 72, 2, 28, 7, 0, 10, 104, 13, 15, 15, 224, 28, 60, 68, 37, 68, 73, 67, 51, 38, 12, 7, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 64, 1, 72, 2, 28, 7, 0, 10, 104, 13, 15, 15, 224, 28, 60, 68, 37, 68, 73, 67, 51, 38, 12, 7, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 64, 1, 72, 2, 28, 7, 0, 10, 104, 13, 15, 15, 224, 28, 0, 34, 26, 48, 51, 47, 36, 27, 9, 5, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 160, 0, 4, 0, 1, 0, 229, 0, 183, 2, 36, 5, 196, 9, 228, 12, 216, 14, 197, 27, 50, 43, 28, 56, 58, 35, 35, 23, 12, 5, 190, 159, 148, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 229, 0, 183, 2, 36, 5, 196, 9, 228, 12, 216, 14, 197, 27, 60, 86, 40, 80, 82, 50, 50, 32, 17, 7, 190, 159, 148, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 229, 0, 183, 2, 36, 5, 196, 9, 228, 12, 216, 14, 197, 27, 50, 76, 38, 75, 78, 47, 47, 30, 16, 6, 190, 159, 148, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 229, 0, 183, 2, 36, 5, 196, 9, 228, 12, 216, 14, 197, 27, 0, 38, 27, 53, 55, 33, 33, 21, 11, 4, 190, 159, 148, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 175, 0, 4, 0, 1, 0, 184, 0, 192, 1, 232, 3, 216, 9, 88, 12, 141, 14, 128, 26, 45, 40, 24, 52, 57, 37, 31, 24, 17, 4, 162, 127, 157, 120, 120, 120, 162, 127, 157, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 184, 0, 192, 1, 232, 3, 216, 9, 88, 12, 141, 14, 128, 26, 70, 95, 38, 79, 88, 57, 47, 37, 27, 7, 162, 127, 157, 120, 120, 120, 162, 127, 157, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 184, 0, 192, 1, 232, 3, 216, 9, 88, 12, 141, 14, 128, 26, 60, 76, 34, 71, 79, 51, 42, 33, 24, 6, 162, 127, 157, 120, 120, 120, 162, 127, 157, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 184, 0, 192, 1, 232, 3, 216, 9, 88, 12, 141, 14, 128, 26, 0, 36, 23, 49, 54, 35, 29, 23, 17, 4, 162, 127, 157, 120, 120, 120, 162, 127, 157, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 225, 0, 5, 0, 1, 0, 224, 0, 136, 2, 84, 4, 24, 11, 228, 12, 136, 14, 96, 27, 45, 34, 20, 41, 60, 29, 29, 29, 9, 4, 167, 167, 135, 120, 120, 120, 167, 167, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 224, 0, 136, 2, 84, 4, 24, 11, 228, 12, 136, 14, 96, 27, 60, 114, 38, 76, 110, 53, 53, 53, 16, 8, 167, 167, 135, 120, 120, 120, 167, 167, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 224, 0, 136, 2, 84, 4, 24, 11, 228, 12, 136, 14, 96, 27, 60, 102, 36, 72, 104, 50, 50, 50, 15, 7, 167, 167, 135, 120, 120, 120, 167, 167, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 224, 0, 128, 2, 84, 4, 24, 11, 228, 12, 136, 14, 96, 27, 60, 61, 28, 56, 81, 39, 39, 39, 12, 6, 167, 167, 135, 120, 120, 120, 167, 167, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 224, 0, 120, 2, 116, 4, 24, 11, 228, 12, 136, 14, 96, 27, 0, 26, 18, 37, 54, 26, 26, 26, 8, 4, 167, 167, 135, 120, 120, 120, 167, 167, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 5, 0, 1, 0, 140, 0, 32, 2, 160, 5, 36, 9, 248, 12, 41, 14, 32, 27, 45, 47, 30, 64, 56, 56, 40, 40, 15, 8, 167, 135, 180, 120, 120, 120, 167, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 168, 0, 32, 2, 160, 5, 16, 9, 148, 12, 41, 14, 32, 27, 48, 82, 37, 79, 86, 79, 64, 53, 26, 9, 170, 135, 157, 120, 120, 120, 140, 120, 157, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 172, 0, 32, 2, 160, 5, 16, 9, 168, 12, 41, 14, 160, 27, 50, 67, 34, 67, 86, 71, 57, 51, 16, 8, 170, 120, 120, 120, 120, 120, 170, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 204, 0, 32, 2, 148, 5, 16, 9, 168, 12, 41, 14, 160, 27, 60, 52, 34, 68, 67, 54, 45, 35, 15, 8, 170, 120, 135, 120, 120, 120, 140, 90, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 204, 0, 33, 2, 140, 5, 16, 9, 168, 12, 141, 14, 160, 27, 0, 39, 31, 52, 64, 56, 38, 30, 11, 8, 170, 135, 150, 120, 120, 120, 140, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 4, 0, 1, 0, 180, 0, 64, 1, 76, 4, 212, 8, 28, 12, 226, 14, 144, 26, 50, 40, 13, 59, 45, 30, 33, 29, 14, 7, 170, 130, 126, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 180, 0, 64, 1, 76, 4, 212, 8, 28, 12, 226, 14, 144, 26, 85, 59, 16, 72, 55, 37, 41, 36, 18, 9, 170, 130, 126, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 180, 0, 64, 1, 76, 4, 212, 8, 28, 12, 226, 14, 144, 26, 56, 43, 13, 61, 47, 32, 35, 30, 15, 7, 170, 130, 126, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 180, 0, 64, 1, 252, 3, 152, 8, 28, 12, 226, 14, 144, 26, 0, 36, 12, 57, 37, 23, 25, 23, 11, 7, 170, 130, 148, 120, 120, 120, 162, 120, 148, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 0, 0, 6, 0, 1, 0, 236, 0, 136, 3, 140, 5, 116, 9, 88, 12, 116, 14, 224, 27, 50, 55, 32, 56, 75, 41, 43, 27, 10, 8, 250, 120, 210, 120, 120, 120, 255, 120, 165, 44, 45, 70, 130, 57, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 236, 0, 136, 3, 140, 5, 136, 9, 88, 12, 116, 14, 224, 27, 75, 103, 34, 81, 98, 53, 57, 36, 12, 6, 225, 120, 210, 120, 120, 120, 255, 120, 165, 44, 60, 70, 130, 57, 0, 0, 0, 0, 45, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 220, 0, 80, 3, 80, 5, 36, 9, 128, 12, 41, 14, 224, 27, 40, 64, 28, 59, 81, 41, 52, 32, 12, 7, 167, 120, 210, 120, 120, 120, 255, 120, 165, 44, 60, 70, 130, 57, 0, 0, 0, 0, 43, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 0, 1, 173, 2, 87, 4, 16, 9, 48, 12, 41, 14, 128, 27, 35, 60, 28, 49, 77, 34, 51, 36, 15, 6, 237, 207, 192, 120, 120, 120, 141, 120, 147, 44, 55, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 0, 1, 76, 2, 10, 4, 16, 9, 28, 12, 41, 14, 112, 27, 35, 70, 35, 63, 75, 31, 48, 33, 17, 8, 221, 148, 186, 120, 120, 120, 141, 120, 147, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 0, 1, 24, 2, 172, 3, 252, 8, 28, 12, 41, 14, 112, 27, 0, 23, 20, 36, 37, 17, 25, 19, 9, 4, 221, 148, 186, 120, 120, 120, 141, 120, 147, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 0, 0, 5, 0, 1, 0, 248, 0, 56, 2, 84, 6, 36, 9, 28, 12, 166, 14, 96, 28, 49, 28, 22, 43, 55, 38, 28, 23, 9, 4, 167, 120, 165, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 248, 0, 56, 2, 84, 6, 36, 9, 28, 12, 166, 14, 96, 28, 41, 87, 39, 77, 98, 67, 50, 41, 17, 7, 167, 120, 165, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 248, 0, 8, 2, 84, 6, 212, 8, 28, 12, 166, 14, 96, 28, 31, 82, 37, 72, 92, 63, 47, 38, 16, 7, 167, 120, 165, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 8, 1, 232, 1, 44, 6, 152, 8, 204, 11, 166, 14, 96, 28, 90, 50, 23, 66, 66, 38, 30, 25, 14, 8, 165, 120, 135, 120, 120, 120, 150, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 190, 0, 120, 1, 231, 4, 195, 8, 205, 12, 116, 14, 160, 28, 0, 33, 30, 54, 32, 25, 21, 18, 7, 7, 120, 103, 105, 120, 120, 120, 120, 100, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 196, 0, 7, 0, 5, 0, 72, 1, 136, 3, 62, 5, 140, 10, 112, 13, 191, 14, 32, 28, 51, 43, 28, 63, 56, 33, 28, 18, 8, 4, 207, 150, 105, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 56, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 72, 1, 136, 3, 62, 5, 140, 10, 112, 13, 191, 14, 32, 28, 45, 104, 44, 98, 87, 51, 44, 28, 13, 6, 207, 150, 105, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 56, 0, 0, 0, 0, 45, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 72, 1, 136, 3, 62, 5, 140, 10, 112, 13, 191, 14, 32, 28, 14, 92, 41, 92, 82, 48, 41, 26, 12, 6, 207, 150, 105, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 56, 0, 0, 0, 0, 45, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 33, 0, 6, 1, 95, 3, 155, 5, 186, 9, 22, 13, 91, 14, 176, 27, 23, 65, 36, 77, 72, 48, 45, 36, 10, 7, 187, 142, 142, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 56, 0, 0, 0, 0, 45, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 33, 0, 196, 0, 32, 3, 249, 5, 232, 8, 188, 12, 247, 13, 64, 27, 33, 41, 29, 58, 60, 50, 50, 50, 9, 8, 167, 135, 180, 120, 120, 120, 167, 105, 135, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 212, 0, 244, 1, 133, 7, 136, 9, 228, 12, 91, 14, 64, 27, 30, 38, 38, 56, 53, 53, 40, 39, 16, 9, 167, 90, 180, 120, 120, 120, 137, 75, 150, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 1, 0, 212, 0, 184, 1, 177, 7, 196, 9, 52, 13, 91, 14, 192, 27, 0, 34, 40, 51, 44, 44, 32, 28, 11, 10, 167, 90, 105, 120, 120, 120, 122, 75, 90, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 232, 65, 0, 191, 129, 244, 194, 182, 76, 250, 23, 8, 230, 0, 5, 0, 1, 0, 0, 1, 24, 2, 108, 7, 236, 9, 104, 13, 15, 15, 224, 28, 45, 29, 25, 47, 53, 44, 37, 27, 9, 6, 216, 138, 159, 120, 120, 120, 107, 138, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 0, 1, 24, 2, 108, 7, 236, 9, 104, 13, 15, 15, 224, 28, 90, 67, 38, 70, 80, 66, 56, 41, 13, 9, 216, 138, 159, 120, 120, 120, 107, 138, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 216, 0, 232, 1, 188, 7, 40, 10, 163, 13, 57, 15, 148, 28, 55, 55, 37, 67, 69, 62, 51, 39, 12, 9, 197, 114, 149, 120, 120, 120, 107, 131, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 144, 0, 125, 1, 52, 8, 148, 10, 188, 13, 76, 15, 32, 28, 40, 30, 27, 50, 48, 46, 40, 32, 9, 8, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 144, 0, 125, 1, 52, 8, 148, 10, 188, 13, 76, 15, 32, 28, 0, 27, 26, 47, 45, 44, 38, 30, 8, 8, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 6, 0, 1, 0, 179, 0, 50, 2, 175, 3, 96, 10, 15, 12, 141, 14, 32, 27, 45, 36, 22, 46, 52, 33, 32, 15, 11, 4, 166, 135, 150, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 179, 0, 50, 2, 175, 3, 96, 10, 15, 12, 141, 14, 32, 27, 40, 116, 40, 82, 93, 59, 58, 27, 20, 8, 166, 135, 150, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 179, 0, 50, 2, 175, 3, 96, 10, 15, 12, 141, 14, 32, 27, 70, 94, 36, 74, 84, 53, 52, 24, 18, 7, 166, 135, 150, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 196, 0, 24, 2, 164, 6, 116, 9, 228, 12, 36, 14, 64, 27, 30, 49, 30, 57, 68, 57, 53, 46, 8, 8, 167, 135, 180, 120, 120, 120, 167, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 199, 0, 101, 1, 123, 7, 201, 10, 228, 12, 107, 14, 64, 27, 35, 38, 24, 47, 48, 45, 44, 36, 11, 6, 156, 128, 153, 120, 120, 120, 167, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 199, 0, 101, 1, 123, 7, 201, 10, 228, 12, 107, 14, 64, 27, 0, 29, 21, 41, 42, 39, 39, 31, 9, 5, 156, 128, 153, 120, 120, 120, 167, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 0, 0, 5, 0, 1, 0, 240, 0, 168, 2, 28, 7, 176, 9, 112, 13, 10, 15, 96, 27, 44, 48, 34, 65, 59, 56, 38, 23, 6, 8, 165, 135, 240, 120, 120, 120, 195, 105, 165, 44, 45, 70, 130, 57, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 240, 0, 176, 2, 28, 7, 136, 9, 112, 13, 60, 15, 96, 27, 77, 68, 36, 76, 79, 74, 40, 24, 8, 6, 170, 120, 180, 120, 120, 120, 200, 120, 165, 44, 45, 70, 130, 57, 0, 0, 0, 0, 43, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 240, 0, 163, 2, 244, 6, 116, 9, 72, 13, 60, 15, 96, 27, 77, 54, 29, 62, 71, 62, 56, 25, 13, 6, 167, 120, 180, 120, 120, 120, 242, 150, 150, 44, 45, 70, 130, 57, 0, 0, 0, 0, 43, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 240, 0, 223, 2, 114, 6, 216, 9, 172, 13, 60, 15, 96, 28, 35, 36, 27, 56, 50, 49, 42, 26, 10, 7, 167, 120, 180, 120, 120, 120, 242, 150, 150, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 240, 0, 223, 2, 26, 6, 236, 9, 172, 13, 60, 15, 96, 28, 0, 28, 25, 53, 43, 40, 35, 21, 7, 8, 167, 105, 180, 120, 120, 120, 242, 135, 150, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 193, 0, 6, 0, 1, 0, 104, 0, 160, 1, 9, 8, 80, 10, 72, 13, 60, 15, 160, 27, 42, 46, 10, 66, 56, 58, 42, 33, 10, 8, 150, 165, 150, 120, 120, 120, 150, 105, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 104, 0, 160, 1, 20, 8, 160, 10, 72, 13, 60, 15, 32, 27, 40, 63, 20, 72, 72, 77, 67, 37, 15, 8, 167, 120, 150, 120, 120, 120, 167, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 128, 0, 179, 1, 232, 7, 80, 10, 52, 13, 60, 15, 64, 27, 51, 45, 20, 70, 53, 50, 46, 25, 9, 8, 180, 90, 150, 120, 120, 120, 180, 105, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 198, 0, 48, 2, 8, 7, 136, 9, 46, 13, 249, 14, 212, 25, 30, 40, 24, 62, 57, 51, 41, 26, 11, 8, 157, 117, 150, 120, 120, 120, 167, 90, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 201, 0, 94, 2, 44, 6, 72, 9, 183, 12, 226, 14, 170, 25, 30, 17, 18, 36, 40, 36, 29, 17, 5, 6, 148, 154, 138, 120, 120, 120, 167, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 210, 0, 141, 2, 150, 5, 24, 9, 128, 12, 15, 15, 77, 25, 0, 19, 23, 36, 44, 37, 29, 17, 3, 8, 139, 168, 138, 120, 120, 120, 167, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 180, 0, 4, 0, 1, 0, 168, 0, 232, 1, 132, 3, 216, 9, 164, 11, 141, 14, 32, 27, 45, 56, 28, 58, 64, 39, 36, 18, 13, 5, 165, 135, 150, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 168, 0, 232, 1, 132, 3, 216, 9, 164, 11, 141, 14, 32, 27, 70, 115, 40, 83, 92, 56, 51, 26, 19, 8, 165, 135, 150, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 168, 0, 232, 1, 132, 3, 216, 9, 164, 11, 141, 14, 32, 27, 65, 93, 36, 74, 83, 50, 46, 23, 17, 7, 165, 135, 150, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 168, 0, 232, 1, 152, 3, 216, 9, 164, 11, 141, 14, 32, 27, 0, 35, 25, 45, 52, 29, 27, 15, 11, 4, 165, 135, 150, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 0, 0, 6, 0, 1, 0, 24, 1, 168, 3, 205, 5, 60, 10, 92, 13, 216, 14, 32, 27, 36, 52, 28, 64, 61, 46, 40, 35, 8, 4, 200, 135, 210, 120, 120, 120, 255, 150, 135, 44, 60, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 24, 1, 168, 3, 205, 5, 60, 10, 92, 13, 216, 14, 32, 27, 29, 112, 41, 94, 90, 67, 58, 52, 12, 6, 200, 135, 210, 120, 120, 120, 255, 150, 135, 44, 60, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 5, 0, 8, 1, 168, 3, 62, 5, 216, 9, 188, 12, 166, 14, 32, 27, 39, 128, 38, 94, 103, 79, 65, 53, 16, 8, 185, 180, 165, 120, 120, 120, 245, 135, 120, 44, 60, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 5, 0, 2, 1, 128, 3, 34, 5, 184, 9, 164, 12, 173, 14, 60, 27, 42, 108, 37, 86, 98, 72, 60, 48, 15, 8, 185, 175, 159, 120, 120, 120, 245, 135, 120, 44, 50, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 232, 0, 185, 2, 116, 4, 56, 9, 68, 12, 203, 14, 176, 27, 84, 52, 33, 55, 80, 46, 39, 31, 11, 8, 185, 157, 135, 120, 120, 120, 194, 105, 111, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 200, 0, 193, 2, 196, 4, 252, 8, 128, 12, 241, 14, 32, 28, 0, 26, 28, 42, 56, 36, 32, 26, 8, 8, 185, 180, 120, 120, 120, 120, 155, 120, 105, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 139, 0, 3, 0, 1, 0, 158, 0, 56, 1, 165, 8, 215, 10, 49, 13, 9, 15, 112, 26, 50, 32, 10, 59, 42, 49, 50, 25, 11, 5, 166, 105, 120, 120, 120, 120, 130, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 158, 0, 56, 1, 165, 8, 215, 10, 49, 13, 9, 15, 112, 26, 90, 73, 15, 88, 64, 74, 75, 37, 17, 8, 166, 105, 120, 120, 120, 120, 130, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 158, 0, 56, 1, 165, 8, 215, 10, 49, 13, 9, 15, 112, 26, 0, 33, 10, 60, 43, 50, 51, 25, 11, 5, 166, 105, 120, 120, 120, 120, 130, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 235, 0, 5, 0, 1, 0, 192, 0, 176, 1, 188, 7, 60, 10, 102, 13, 191, 14, 128, 28, 45, 27, 21, 44, 45, 44, 34, 28, 8, 6, 185, 107, 135, 120, 120, 120, 185, 107, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 192, 0, 176, 1, 188, 7, 60, 10, 102, 13, 191, 14, 128, 28, 70, 80, 35, 76, 77, 75, 59, 47, 15, 11, 185, 107, 135, 120, 120, 120, 185, 107, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 188, 0, 164, 1, 212, 7, 72, 10, 99, 13, 196, 14, 96, 28, 70, 69, 32, 71, 72, 69, 55, 44, 14, 10, 184, 107, 134, 120, 120, 120, 185, 107, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 136, 0, 17, 1, 207, 8, 213, 10, 57, 13, 7, 15, 236, 26, 50, 38, 13, 54, 50, 49, 46, 28, 11, 7, 174, 105, 118, 120, 120, 120, 185, 107, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 118, 0, 224, 0, 35, 9, 4, 11, 42, 13, 30, 15, 112, 26, 0, 23, 7, 45, 40, 39, 39, 21, 10, 6, 171, 105, 112, 120, 120, 120, 175, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 5, 0, 1, 0, 116, 0, 13, 2, 161, 5, 36, 9, 188, 12, 116, 14, 96, 27, 34, 35, 26, 50, 60, 34, 36, 27, 14, 5, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 116, 0, 13, 2, 161, 5, 36, 9, 188, 12, 116, 14, 96, 27, 60, 80, 39, 76, 92, 52, 54, 42, 22, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 220, 0, 224, 1, 120, 5, 232, 8, 68, 12, 191, 14, 192, 28, 54, 54, 36, 55, 79, 57, 35, 30, 16, 7, 120, 120, 120, 120, 120, 120, 165, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 220, 0, 164, 1, 120, 4, 152, 8, 88, 12, 141, 14, 64, 28, 45, 56, 44, 77, 54, 30, 24, 26, 15, 9, 120, 120, 120, 120, 120, 120, 60, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 140, 0, 84, 1, 222, 3, 56, 9, 188, 12, 141, 14, 192, 27, 0, 21, 28, 46, 37, 15, 7, 9, 9, 8, 120, 105, 90, 120, 120, 120, 60, 120, 75, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 6, 0, 1, 0, 248, 0, 104, 2, 196, 4, 76, 9, 28, 12, 166, 14, 96, 28, 46, 45, 26, 58, 66, 49, 36, 30, 12, 5, 167, 120, 165, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 248, 0, 104, 2, 196, 4, 76, 9, 28, 12, 166, 14, 96, 28, 25, 103, 40, 88, 100, 75, 55, 45, 19, 8, 167, 120, 165, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 248, 0, 104, 2, 176, 4, 76, 9, 28, 12, 166, 14, 96, 28, 43, 73, 33, 73, 84, 63, 46, 38, 16, 7, 167, 120, 165, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 198, 0, 248, 1, 176, 4, 76, 9, 58, 12, 204, 14, 112, 28, 48, 72, 28, 76, 72, 41, 43, 25, 14, 8, 166, 142, 142, 120, 120, 120, 170, 180, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 5, 0, 192, 0, 174, 1, 196, 4, 172, 8, 204, 11, 141, 14, 224, 28, 46, 40, 28, 64, 39, 27, 18, 16, 8, 8, 162, 120, 135, 120, 120, 120, 117, 90, 180, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 176, 0, 134, 1, 189, 3, 92, 8, 204, 11, 141, 14, 224, 28, 0, 33, 24, 58, 38, 22, 15, 12, 9, 8, 152, 120, 75, 120, 120, 120, 107, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 0, 0, 5, 0, 1, 0, 180, 0, 137, 2, 205, 5, 126, 9, 233, 12, 116, 14, 176, 27, 40, 46, 32, 60, 68, 44, 39, 31, 13, 3, 174, 157, 145, 120, 120, 120, 200, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 180, 0, 137, 2, 205, 5, 126, 9, 233, 12, 116, 14, 176, 27, 66, 104, 48, 89, 101, 65, 58, 47, 20, 4, 174, 157, 145, 120, 120, 120, 200, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 216, 0, 102, 2, 173, 6, 120, 9, 242, 12, 86, 14, 243, 27, 94, 61, 33, 67, 76, 59, 50, 41, 14, 6, 180, 144, 158, 120, 120, 120, 200, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 156, 0, 99, 1, 152, 8, 140, 10, 152, 13, 166, 14, 32, 28, 40, 44, 33, 56, 50, 60, 46, 33, 10, 8, 167, 90, 195, 120, 120, 120, 122, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 156, 0, 99, 1, 174, 8, 160, 10, 92, 13, 10, 15, 32, 28, 0, 31, 30, 47, 48, 44, 40, 32, 9, 8, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 95, 0, 6, 0, 1, 0, 136, 0, 72, 1, 138, 8, 200, 10, 134, 13, 113, 15, 236, 26, 45, 44, 7, 65, 55, 56, 44, 27, 11, 7, 172, 133, 129, 120, 120, 120, 180, 105, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 128, 0, 72, 1, 142, 8, 210, 10, 82, 13, 98, 15, 224, 26, 50, 64, 10, 75, 75, 77, 72, 37, 16, 8, 158, 112, 135, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 128, 0, 72, 1, 142, 8, 210, 10, 82, 13, 98, 15, 224, 26, 40, 64, 10, 75, 75, 77, 72, 37, 16, 8, 158, 112, 135, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 169, 0, 216, 1, 108, 7, 60, 10, 92, 13, 20, 15, 32, 27, 35, 66, 33, 76, 73, 60, 56, 36, 18, 4, 173, 127, 122, 120, 120, 120, 167, 97, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 116, 0, 13, 2, 161, 5, 36, 9, 188, 12, 116, 14, 96, 27, 50, 37, 26, 51, 63, 35, 36, 28, 14, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 13, 2, 161, 5, 36, 9, 188, 12, 116, 14, 96, 27, 0, 21, 20, 38, 47, 26, 27, 21, 10, 6, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 0, 0, 7, 0, 1, 0, 179, 0, 50, 2, 175, 3, 96, 10, 15, 12, 141, 14, 32, 27, 45, 36, 22, 46, 52, 33, 32, 15, 11, 4, 166, 135, 150, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 179, 0, 50, 2, 175, 3, 96, 10, 15, 12, 141, 14, 32, 27, 40, 116, 40, 82, 93, 59, 58, 27, 20, 8, 166, 135, 150, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 179, 0, 50, 2, 175, 3, 96, 10, 15, 12, 141, 14, 32, 27, 70, 94, 36, 74, 84, 53, 52, 24, 18, 7, 166, 135, 150, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 196, 0, 24, 2, 164, 6, 116, 9, 228, 12, 36, 14, 64, 27, 30, 49, 30, 57, 68, 57, 53, 46, 8, 8, 167, 135, 180, 120, 120, 120, 167, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 199, 0, 112, 1, 123, 7, 201, 10, 228, 12, 107, 14, 64, 27, 35, 37, 24, 47, 48, 45, 44, 36, 11, 6, 156, 128, 153, 120, 120, 120, 167, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 199, 0, 112, 1, 123, 7, 201, 10, 228, 12, 107, 14, 64, 27, 55, 37, 24, 47, 48, 45, 44, 36, 11, 6, 156, 128, 153, 120, 120, 120, 167, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 1, 0, 208, 0, 128, 2, 238, 5, 96, 9, 52, 13, 216, 14, 64, 27, 0, 21, 20, 40, 48, 36, 32, 28, 7, 8, 252, 90, 165, 120, 120, 120, 252, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 232, 65, 0, 191, 129, 244, 194, 182, 76, 250, 23, 8, 170, 0, 4, 0, 1, 0, 188, 0, 0, 2, 84, 6, 0, 10, 132, 13, 170, 15, 32, 27, 50, 33, 26, 55, 43, 41, 38, 26, 9, 5, 152, 126, 147, 120, 120, 120, 144, 148, 174, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 188, 0, 0, 2, 84, 6, 0, 10, 132, 13, 170, 15, 32, 27, 60, 84, 41, 87, 68, 66, 60, 42, 15, 8, 152, 126, 147, 120, 120, 120, 144, 148, 174, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 188, 0, 0, 2, 84, 6, 0, 10, 132, 13, 170, 15, 32, 27, 60, 75, 39, 82, 64, 62, 57, 40, 14, 8, 152, 126, 147, 120, 120, 120, 144, 148, 174, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 188, 0, 0, 2, 84, 6, 0, 10, 132, 13, 170, 15, 32, 27, 0, 33, 26, 55, 43, 41, 38, 26, 9, 5, 152, 126, 147, 120, 120, 120, 144, 148, 174, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 100, 0, 4, 0, 1, 0, 176, 0, 112, 1, 112, 3, 136, 9, 184, 11, 60, 15, 144, 26, 50, 50, 12, 64, 58, 30, 27, 18, 15, 7, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 176, 0, 112, 1, 112, 3, 136, 9, 184, 11, 60, 15, 144, 26, 50, 84, 16, 84, 76, 40, 36, 24, 20, 10, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 176, 0, 112, 1, 112, 3, 136, 9, 184, 11, 60, 15, 144, 26, 70, 67, 14, 74, 67, 35, 32, 21, 17, 8, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 176, 0, 112, 1, 132, 3, 136, 9, 184, 11, 60, 15, 144, 26, 0, 34, 12, 52, 47, 25, 22, 15, 12, 6, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 0, 0, 4, 0, 33, 0, 152, 0, 48, 1, 136, 9, 204, 11, 232, 13, 220, 15, 160, 26, 52, 45, 18, 59, 59, 53, 47, 28, 13, 6, 167, 110, 120, 120, 120, 120, 167, 110, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 152, 0, 48, 1, 136, 9, 204, 11, 232, 13, 220, 15, 160, 26, 75, 71, 23, 74, 74, 66, 58, 35, 17, 8, 167, 110, 120, 120, 120, 120, 167, 110, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 152, 0, 48, 1, 136, 9, 204, 11, 232, 13, 220, 15, 160, 26, 78, 52, 20, 64, 64, 57, 50, 30, 14, 7, 167, 110, 120, 120, 120, 120, 167, 110, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 84, 0, 48, 1, 136, 9, 204, 11, 232, 13, 220, 15, 64, 26, 0, 20, 11, 40, 41, 38, 39, 22, 9, 8, 175, 105, 105, 120, 120, 120, 175, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 210, 0, 5, 0, 1, 0, 153, 0, 198, 1, 44, 3, 255, 9, 194, 11, 151, 14, 244, 26, 50, 57, 24, 58, 65, 39, 36, 20, 14, 6, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 153, 0, 198, 1, 44, 3, 255, 9, 194, 11, 151, 14, 244, 26, 40, 96, 31, 76, 85, 51, 46, 26, 19, 8, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 153, 0, 198, 1, 44, 3, 255, 9, 194, 11, 151, 14, 244, 26, 70, 96, 31, 76, 85, 51, 46, 26, 19, 8, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 184, 0, 14, 2, 162, 3, 255, 9, 218, 11, 171, 14, 124, 27, 50, 69, 33, 65, 78, 42, 41, 26, 17, 7, 170, 136, 137, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 192, 0, 32, 2, 192, 3, 0, 10, 224, 11, 176, 14, 159, 27, 0, 40, 25, 49, 59, 31, 31, 20, 12, 5, 172, 138, 135, 120, 120, 120, 167, 138, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 45, 0, 5, 0, 1, 0, 14, 1, 212, 2, 106, 4, 200, 10, 2, 13, 238, 14, 192, 27, 45, 50, 25, 57, 68, 37, 31, 26, 10, 5, 165, 148, 135, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 14, 1, 212, 2, 106, 4, 200, 10, 2, 13, 238, 14, 192, 27, 50, 107, 37, 84, 100, 54, 45, 38, 14, 7, 165, 148, 135, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 218, 0, 120, 2, 169, 3, 161, 10, 109, 12, 71, 14, 60, 27, 60, 103, 28, 69, 91, 51, 41, 36, 16, 8, 166, 145, 137, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 144, 0, 216, 1, 12, 3, 196, 9, 254, 11, 157, 14, 216, 26, 50, 65, 24, 63, 63, 44, 40, 23, 17, 8, 163, 120, 143, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 144, 0, 216, 1, 12, 3, 196, 9, 254, 11, 157, 14, 216, 26, 0, 42, 20, 51, 51, 35, 32, 19, 14, 6, 163, 120, 143, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 250, 0, 5, 0, 33, 0, 152, 0, 32, 1, 224, 8, 4, 11, 52, 13, 0, 15, 160, 26, 45, 44, 6, 66, 58, 59, 60, 28, 13, 6, 175, 105, 120, 120, 120, 120, 175, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 152, 0, 24, 1, 232, 8, 4, 11, 52, 13, 0, 15, 160, 26, 70, 72, 10, 83, 73, 74, 75, 36, 17, 8, 167, 105, 120, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 152, 0, 24, 1, 172, 8, 4, 11, 12, 13, 216, 14, 64, 26, 70, 45, 10, 60, 60, 63, 63, 34, 11, 8, 167, 105, 120, 120, 120, 120, 167, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 5, 0, 240, 0, 168, 2, 164, 6, 136, 9, 72, 13, 60, 15, 96, 27, 65, 36, 27, 54, 45, 54, 45, 22, 12, 6, 167, 135, 180, 120, 120, 120, 242, 135, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 240, 0, 216, 2, 26, 6, 216, 9, 172, 13, 60, 15, 96, 28, 0, 32, 28, 56, 44, 44, 36, 21, 7, 8, 167, 120, 180, 120, 120, 120, 242, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 165, 0, 3, 0, 1, 0, 116, 0, 24, 2, 140, 5, 116, 9, 188, 12, 116, 14, 88, 27, 110, 86, 41, 79, 96, 54, 56, 43, 23, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 7, 0, 116, 0, 24, 2, 136, 5, 16, 9, 88, 12, 16, 14, 88, 27, 55, 24, 22, 43, 46, 30, 28, 21, 11, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 116, 0, 72, 2, 120, 5, 208, 7, 224, 11, 152, 13, 88, 27, 0, 21, 22, 43, 37, 30, 13, 11, 6, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 0, 0, 3, 0, 1, 0, 116, 0, 24, 2, 140, 5, 116, 9, 188, 12, 116, 14, 88, 27, 50, 50, 31, 60, 73, 41, 43, 33, 17, 6, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 116, 0, 24, 2, 140, 5, 116, 9, 188, 12, 116, 14, 88, 27, 90, 86, 41, 79, 96, 54, 56, 43, 23, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 116, 0, 24, 2, 140, 5, 116, 9, 188, 12, 116, 14, 88, 27, 0, 42, 28, 55, 67, 38, 39, 30, 16, 6, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 160, 0, 4, 0, 1, 0, 200, 0, 248, 1, 108, 7, 236, 9, 228, 12, 16, 14, 128, 28, 50, 45, 27, 61, 54, 66, 52, 36, 11, 8, 160, 105, 127, 120, 120, 120, 160, 105, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 200, 0, 248, 1, 108, 7, 240, 9, 228, 12, 16, 14, 128, 28, 50, 80, 36, 81, 72, 88, 70, 48, 15, 11, 160, 105, 127, 120, 120, 120, 160, 105, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 200, 0, 248, 1, 108, 7, 240, 9, 228, 12, 16, 14, 128, 28, 60, 65, 32, 73, 64, 79, 63, 44, 13, 10, 160, 105, 127, 120, 120, 120, 160, 105, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 200, 0, 240, 1, 128, 7, 248, 9, 228, 12, 16, 14, 128, 28, 0, 35, 24, 53, 47, 58, 46, 32, 10, 7, 160, 105, 127, 120, 120, 120, 160, 105, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 0, 0, 3, 0, 1, 0, 123, 0, 15, 2, 181, 5, 176, 9, 198, 12, 136, 14, 38, 27, 50, 49, 30, 62, 69, 42, 44, 32, 16, 6, 166, 145, 133, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 123, 0, 15, 2, 181, 5, 176, 9, 198, 12, 136, 14, 38, 27, 90, 88, 40, 83, 92, 56, 58, 43, 22, 8, 166, 145, 133, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 123, 0, 15, 2, 181, 5, 176, 9, 198, 12, 136, 14, 38, 27, 0, 42, 27, 57, 63, 38, 40, 30, 15, 5, 166, 145, 133, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 0, 0, 3, 0, 1, 0, 200, 0, 40, 2, 12, 3, 200, 10, 188, 12, 36, 14, 32, 28, 50, 64, 25, 60, 60, 38, 38, 22, 15, 6, 182, 150, 120, 120, 120, 120, 182, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 200, 0, 40, 2, 12, 3, 200, 10, 188, 12, 36, 14, 32, 28, 90, 100, 32, 76, 76, 48, 48, 28, 19, 8, 182, 150, 120, 120, 120, 120, 182, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 200, 0, 40, 2, 12, 3, 200, 10, 188, 12, 36, 14, 32, 28, 0, 54, 26, 55, 55, 35, 35, 20, 14, 6, 182, 150, 120, 120, 120, 120, 182, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 140, 0, 3, 0, 1, 0, 116, 0, 13, 2, 40, 5, 152, 8, 228, 12, 136, 14, 96, 27, 50, 49, 30, 59, 72, 40, 42, 32, 17, 6, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 116, 0, 13, 2, 40, 5, 152, 8, 228, 12, 136, 14, 96, 27, 90, 88, 41, 79, 96, 54, 56, 43, 23, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 116, 0, 13, 2, 40, 5, 152, 8, 228, 12, 136, 14, 96, 27, 0, 40, 28, 53, 65, 36, 38, 29, 15, 5, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 50, 0, 3, 0, 1, 0, 184, 0, 96, 1, 232, 3, 192, 8, 144, 11, 136, 14, 144, 26, 50, 42, 23, 49, 55, 43, 40, 29, 17, 7, 162, 135, 150, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 184, 0, 96, 1, 232, 3, 192, 8, 144, 11, 136, 14, 144, 26, 100, 58, 27, 58, 64, 51, 47, 34, 20, 8, 162, 135, 150, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 184, 0, 96, 1, 232, 3, 152, 8, 104, 11, 136, 14, 144, 26, 0, 34, 22, 44, 49, 38, 33, 22, 16, 6, 162, 135, 150, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 100, 0, 3, 0, 1, 0, 216, 0, 68, 2, 0, 5, 160, 10, 248, 12, 191, 14, 64, 29, 45, 40, 26, 55, 68, 37, 42, 32, 19, 0, 150, 144, 120, 120, 120, 120, 150, 93, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 192, 0, 224, 1, 16, 4, 180, 10, 12, 13, 140, 15, 128, 28, 100, 28, 27, 45, 50, 33, 27, 20, 7, 0, 150, 120, 120, 120, 120, 120, 150, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 17, 0, 192, 0, 224, 1, 16, 4, 180, 10, 12, 13, 140, 15, 128, 28, 0, 23, 26, 42, 42, 32, 25, 19, 7, 0, 150, 120, 120, 120, 120, 120, 150, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 140, 0, 3, 0, 1, 0, 8, 1, 223, 2, 224, 6, 116, 9, 112, 13, 60, 15, 96, 27, 50, 31, 25, 51, 52, 46, 27, 15, 5, 4, 225, 120, 180, 120, 120, 120, 255, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 8, 1, 223, 2, 224, 6, 116, 9, 112, 13, 60, 15, 96, 27, 90, 83, 41, 83, 85, 75, 44, 25, 9, 7, 225, 120, 180, 120, 120, 120, 255, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 240, 0, 163, 2, 202, 6, 116, 9, 72, 13, 60, 15, 96, 27, 0, 32, 23, 48, 54, 44, 39, 19, 10, 5, 192, 120, 180, 120, 120, 120, 255, 150, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 0, 0, 4, 0, 1, 0, 244, 0, 152, 2, 16, 4, 240, 10, 148, 12, 41, 14, 96, 27, 45, 49, 21, 52, 68, 32, 27, 27, 11, 5, 167, 142, 135, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 244, 0, 152, 2, 16, 4, 240, 10, 148, 12, 41, 14, 96, 27, 80, 109, 30, 74, 104, 50, 46, 46, 15, 7, 167, 142, 135, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 244, 0, 136, 2, 36, 4, 240, 10, 148, 12, 41, 14, 96, 27, 90, 85, 29, 71, 92, 47, 44, 44, 14, 7, 167, 142, 135, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 244, 0, 136, 2, 36, 4, 24, 11, 168, 12, 76, 14, 96, 27, 0, 63, 26, 63, 76, 42, 39, 39, 13, 6, 167, 142, 135, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 0, 0, 6, 0, 1, 0, 104, 0, 8, 1, 72, 8, 64, 11, 228, 12, 88, 17, 160, 27, 45, 42, 11, 57, 39, 57, 61, 22, 13, 9, 150, 135, 157, 120, 120, 120, 150, 135, 157, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 104, 0, 8, 1, 132, 8, 224, 11, 32, 13, 48, 17, 32, 27, 50, 52, 17, 61, 44, 57, 61, 22, 16, 9, 167, 120, 150, 120, 120, 120, 167, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 104, 0, 24, 1, 112, 8, 224, 11, 32, 13, 68, 17, 32, 27, 50, 36, 15, 51, 35, 47, 51, 19, 14, 8, 167, 120, 150, 120, 120, 120, 167, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 128, 0, 128, 1, 168, 7, 220, 10, 72, 13, 164, 16, 64, 27, 40, 52, 22, 66, 30, 57, 51, 28, 13, 9, 180, 137, 200, 140, 120, 120, 180, 152, 215, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 168, 0, 3, 2, 28, 7, 80, 10, 32, 13, 120, 15, 64, 28, 33, 50, 27, 68, 55, 42, 51, 21, 6, 9, 167, 150, 120, 120, 120, 120, 167, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 168, 0, 232, 1, 164, 6, 40, 10, 52, 13, 140, 15, 64, 28, 0, 44, 30, 61, 48, 50, 48, 22, 6, 9, 167, 127, 120, 120, 120, 120, 167, 127, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 60, 0, 4, 0, 1, 0, 160, 0, 16, 1, 199, 8, 28, 12, 132, 13, 8, 17, 88, 27, 50, 37, 15, 50, 35, 39, 46, 15, 15, 7, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 148, 0, 16, 1, 199, 8, 28, 12, 132, 13, 8, 17, 88, 27, 60, 47, 17, 57, 39, 44, 52, 17, 17, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 160, 0, 32, 1, 199, 8, 28, 12, 132, 13, 8, 17, 88, 27, 50, 46, 17, 57, 39, 44, 52, 17, 17, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 160, 0, 32, 1, 199, 8, 28, 12, 132, 13, 8, 17, 88, 27, 0, 33, 14, 48, 33, 37, 44, 14, 14, 7, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 0, 0, 6, 0, 1, 0, 152, 0, 72, 1, 172, 3, 76, 9, 48, 12, 92, 13, 128, 26, 45, 42, 26, 52, 43, 32, 29, 28, 17, 6, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 152, 0, 80, 1, 36, 4, 56, 9, 168, 12, 232, 13, 128, 26, 50, 61, 32, 64, 54, 39, 36, 35, 21, 7, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 168, 0, 136, 1, 76, 4, 36, 9, 148, 12, 36, 14, 128, 26, 33, 61, 32, 68, 54, 43, 39, 32, 21, 7, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 140, 0, 200, 1, 236, 4, 252, 8, 128, 12, 212, 13, 32, 27, 26, 60, 24, 64, 74, 68, 55, 45, 22, 7, 170, 135, 165, 120, 120, 120, 140, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 140, 0, 224, 1, 80, 5, 232, 8, 188, 12, 56, 14, 32, 27, 40, 58, 24, 64, 74, 68, 55, 45, 22, 7, 170, 135, 165, 120, 120, 120, 140, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 116, 0, 224, 1, 200, 5, 196, 9, 228, 12, 116, 14, 88, 27, 0, 51, 32, 62, 68, 42, 44, 25, 18, 6, 167, 135, 135, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 60, 0, 4, 0, 1, 0, 153, 0, 52, 1, 16, 8, 20, 10, 132, 13, 80, 15, 88, 27, 50, 39, 28, 44, 44, 42, 48, 12, 15, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 153, 0, 72, 1, 52, 8, 20, 10, 132, 13, 80, 15, 88, 27, 60, 55, 33, 52, 52, 50, 57, 14, 18, 9, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 153, 0, 72, 1, 52, 8, 20, 10, 132, 13, 80, 15, 88, 27, 50, 38, 28, 44, 44, 42, 48, 12, 15, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 153, 0, 48, 1, 112, 8, 80, 10, 212, 13, 80, 15, 88, 27, 0, 29, 28, 36, 24, 28, 32, 12, 15, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 0, 0, 7, 0, 1, 0, 195, 0, 39, 1, 167, 8, 244, 11, 212, 13, 56, 19, 88, 27, 40, 45, 15, 60, 30, 35, 45, 15, 20, 10, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 180, 0, 24, 1, 132, 8, 224, 11, 132, 13, 152, 18, 88, 27, 20, 57, 15, 68, 36, 42, 52, 21, 15, 10, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 195, 0, 39, 1, 167, 8, 211, 11, 115, 13, 36, 19, 88, 27, 55, 40, 15, 55, 30, 35, 40, 15, 15, 10, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 195, 0, 39, 1, 92, 8, 176, 9, 52, 13, 12, 18, 88, 27, 80, 48, 14, 62, 48, 33, 43, 14, 14, 9, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 195, 0, 39, 1, 156, 4, 252, 8, 168, 12, 60, 15, 88, 27, 60, 58, 14, 72, 48, 28, 33, 9, 9, 9, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 195, 0, 39, 1, 172, 3, 252, 8, 168, 12, 60, 15, 88, 27, 45, 35, 14, 52, 33, 24, 24, 14, 9, 9, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 1, 0, 172, 0, 16, 1, 132, 3, 252, 8, 168, 12, 60, 15, 88, 27, 0, 30, 14, 48, 33, 24, 24, 14, 9, 9, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 232, 65, 0, 191, 129, 244, 194, 182, 76, 250, 23, 8, 0, 0, 6, 0, 1, 0, 186, 0, 108, 2, 221, 4, 250, 8, 154, 12, 103, 14, 96, 28, 40, 47, 30, 59, 70, 52, 38, 31, 13, 6, 167, 120, 149, 120, 120, 120, 197, 120, 142, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 186, 0, 108, 2, 221, 4, 250, 8, 154, 12, 103, 14, 96, 28, 47, 97, 43, 85, 100, 75, 55, 45, 19, 8, 167, 120, 149, 120, 120, 120, 197, 120, 142, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 104, 0, 208, 1, 136, 4, 152, 8, 188, 12, 76, 14, 96, 28, 28, 76, 32, 85, 68, 52, 52, 32, 19, 8, 167, 120, 142, 120, 120, 120, 197, 120, 142, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 137, 0, 160, 1, 16, 4, 185, 8, 163, 12, 101, 14, 151, 27, 39, 69, 32, 76, 62, 36, 36, 24, 19, 8, 165, 123, 145, 120, 120, 120, 197, 120, 142, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 184, 0, 120, 1, 212, 3, 232, 8, 128, 12, 136, 14, 128, 26, 60, 42, 35, 46, 43, 31, 31, 18, 15, 6, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 184, 0, 120, 1, 112, 3, 232, 8, 128, 12, 136, 14, 128, 26, 0, 38, 32, 43, 40, 26, 29, 17, 14, 6, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 0, 0, 6, 0, 1, 0, 24, 1, 0, 3, 176, 4, 4, 11, 172, 13, 200, 15, 64, 27, 45, 56, 30, 58, 72, 40, 34, 24, 4, 5, 187, 135, 165, 120, 120, 120, 187, 135, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 24, 1, 0, 3, 176, 4, 4, 11, 172, 13, 200, 15, 64, 27, 56, 114, 43, 83, 102, 57, 49, 34, 6, 8, 187, 135, 165, 120, 120, 120, 187, 135, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 246, 0, 208, 2, 140, 5, 20, 10, 252, 13, 64, 16, 88, 27, 50, 85, 38, 84, 92, 52, 44, 24, 18, 10, 226, 150, 128, 120, 120, 120, 235, 150, 128, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 227, 0, 80, 2, 8, 7, 20, 10, 252, 13, 108, 17, 88, 27, 44, 48, 28, 60, 64, 44, 36, 20, 15, 9, 208, 138, 160, 128, 134, 145, 235, 150, 156, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 204, 0, 112, 1, 52, 8, 160, 10, 16, 14, 36, 19, 88, 27, 75, 40, 22, 52, 44, 39, 39, 15, 13, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 204, 0, 56, 1, 192, 8, 124, 11, 16, 14, 196, 19, 88, 27, 0, 35, 20, 48, 32, 36, 32, 12, 11, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 0, 0, 7, 0, 1, 0, 244, 0, 152, 2, 16, 4, 240, 10, 148, 12, 41, 14, 96, 27, 50, 55, 23, 57, 69, 41, 35, 35, 12, 5, 167, 142, 135, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 244, 0, 152, 2, 16, 4, 240, 10, 148, 12, 41, 14, 96, 27, 80, 105, 30, 74, 100, 54, 46, 46, 15, 7, 167, 142, 135, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 244, 0, 136, 2, 36, 4, 240, 10, 148, 12, 41, 14, 96, 27, 34, 86, 29, 71, 92, 51, 44, 44, 15, 7, 167, 142, 135, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 244, 0, 216, 2, 116, 4, 160, 10, 148, 12, 41, 14, 96, 27, 60, 78, 30, 65, 94, 47, 40, 40, 15, 7, 167, 142, 135, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 246, 0, 200, 2, 120, 5, 216, 9, 132, 13, 224, 16, 88, 27, 50, 64, 34, 76, 64, 48, 44, 20, 12, 10, 226, 150, 136, 120, 120, 120, 235, 150, 136, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 204, 0, 128, 1, 52, 8, 44, 11, 248, 12, 164, 16, 88, 27, 68, 32, 20, 48, 36, 36, 36, 16, 12, 8, 187, 125, 145, 137, 150, 175, 187, 125, 145, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 1, 0, 204, 0, 56, 1, 192, 8, 124, 11, 16, 14, 172, 18, 88, 27, 0, 36, 21, 48, 32, 36, 36, 16, 8, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 232, 65, 0, 191, 129, 244, 194, 182, 76, 250, 23, 8, 0, 0, 5, 0, 1, 0, 174, 0, 128, 2, 26, 6, 96, 9, 218, 12, 91, 14, 192, 27, 40, 49, 33, 60, 68, 48, 40, 37, 13, 7, 168, 165, 165, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 174, 0, 128, 2, 26, 6, 96, 9, 218, 12, 91, 14, 192, 27, 66, 93, 46, 82, 94, 66, 55, 51, 18, 10, 168, 165, 165, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 240, 0, 78, 2, 67, 7, 116, 9, 248, 12, 66, 14, 32, 28, 94, 53, 28, 61, 69, 60, 49, 41, 13, 6, 184, 135, 168, 120, 120, 120, 169, 138, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 156, 0, 99, 1, 152, 8, 140, 10, 152, 13, 166, 14, 32, 28, 40, 40, 31, 54, 47, 57, 44, 32, 10, 8, 167, 90, 195, 120, 120, 120, 122, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 156, 0, 99, 1, 174, 8, 160, 10, 92, 13, 10, 15, 32, 28, 0, 34, 31, 49, 49, 45, 42, 33, 9, 8, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 7, 0, 1, 0, 0, 1, 8, 2, 12, 3, 100, 10, 108, 12, 60, 15, 224, 27, 41, 82, 39, 72, 72, 48, 42, 23, 13, 6, 165, 97, 107, 120, 120, 120, 165, 97, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 0, 1, 8, 2, 12, 3, 100, 10, 108, 12, 60, 15, 224, 27, 30, 131, 49, 91, 91, 60, 53, 29, 17, 7, 165, 97, 107, 120, 120, 120, 165, 97, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 0, 1, 8, 2, 12, 3, 100, 10, 108, 12, 60, 15, 224, 27, 35, 131, 49, 91, 91, 60, 53, 29, 17, 7, 165, 97, 107, 120, 120, 120, 165, 97, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 144, 0, 24, 2, 100, 5, 252, 8, 188, 12, 156, 14, 32, 27, 60, 58, 28, 76, 56, 60, 56, 40, 20, 8, 170, 135, 200, 120, 120, 120, 140, 120, 185, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 160, 0, 144, 1, 208, 7, 120, 10, 172, 13, 224, 16, 88, 27, 48, 43, 20, 60, 52, 40, 48, 16, 16, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 160, 0, 72, 1, 52, 8, 4, 11, 192, 13, 224, 16, 88, 27, 45, 36, 16, 52, 48, 40, 48, 16, 16, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 1, 0, 160, 0, 72, 1, 92, 8, 220, 10, 36, 14, 224, 16, 88, 27, 0, 29, 16, 46, 42, 37, 33, 16, 16, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 232, 65, 0, 191, 129, 244, 194, 182, 76, 250, 23, 8, 0, 0, 7, 0, 1, 0, 152, 0, 80, 1, 132, 3, 232, 8, 168, 12, 232, 13, 128, 26, 40, 51, 25, 61, 51, 30, 23, 23, 17, 7, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 152, 0, 80, 1, 16, 4, 56, 9, 168, 12, 232, 13, 128, 26, 82, 70, 30, 72, 60, 44, 40, 39, 24, 8, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 176, 0, 240, 1, 180, 5, 172, 8, 221, 12, 78, 14, 88, 27, 49, 48, 28, 60, 52, 64, 42, 39, 17, 8, 166, 137, 154, 150, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 169, 0, 125, 1, 88, 7, 36, 9, 254, 12, 140, 14, 218, 27, 39, 45, 24, 48, 60, 64, 44, 39, 13, 8, 168, 144, 156, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 165, 0, 64, 1, 52, 8, 216, 9, 28, 13, 180, 14, 240, 27, 44, 44, 16, 60, 60, 51, 43, 37, 12, 8, 83, 127, 134, 120, 120, 120, 112, 120, 134, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 140, 0, 24, 1, 172, 8, 80, 10, 92, 13, 231, 14, 12, 28, 41, 40, 20, 48, 56, 52, 41, 34, 10, 8, 168, 105, 130, 120, 120, 120, 197, 120, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 1, 0, 156, 0, 48, 1, 56, 9, 120, 10, 92, 13, 10, 15, 32, 28, 0, 34, 20, 52, 48, 44, 40, 32, 9, 8, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 232, 65, 0, 191, 129, 244, 194, 182, 76, 250, 23, 8, 0, 0, 6, 0, 1, 0, 184, 0, 96, 1, 112, 3, 192, 8, 144, 11, 136, 14, 144, 26, 55, 29, 19, 40, 45, 31, 28, 21, 14, 6, 162, 135, 150, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 184, 0, 96, 1, 192, 3, 192, 8, 144, 11, 136, 14, 144, 26, 20, 59, 27, 58, 65, 51, 48, 34, 20, 8, 162, 135, 150, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 33, 0, 179, 0, 80, 1, 232, 3, 96, 9, 48, 12, 6, 15, 177, 26, 60, 66, 29, 65, 56, 52, 54, 36, 22, 9, 166, 133, 148, 122, 124, 129, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 33, 0, 164, 0, 56, 1, 148, 7, 36, 9, 148, 12, 57, 16, 2, 27, 79, 49, 22, 58, 32, 48, 52, 26, 19, 8, 176, 129, 143, 129, 137, 151, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 148, 0, 16, 1, 152, 8, 200, 10, 188, 12, 128, 17, 88, 27, 84, 37, 16, 52, 36, 40, 48, 16, 16, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 160, 0, 40, 1, 199, 8, 28, 12, 132, 13, 8, 17, 88, 27, 0, 36, 16, 52, 36, 36, 40, 16, 12, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 40, 0, 6, 0, 1, 0, 140, 0, 232, 1, 196, 4, 36, 9, 128, 12, 41, 14, 32, 27, 40, 51, 30, 65, 61, 55, 44, 43, 21, 7, 170, 135, 165, 120, 120, 120, 140, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 140, 0, 240, 1, 196, 4, 36, 9, 128, 12, 41, 14, 32, 27, 45, 65, 34, 73, 69, 62, 50, 49, 24, 8, 170, 135, 165, 120, 120, 120, 140, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 158, 0, 8, 2, 80, 5, 16, 9, 188, 12, 148, 14, 0, 28, 50, 59, 34, 72, 64, 59, 53, 42, 18, 9, 172, 128, 153, 127, 132, 143, 140, 120, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 184, 0, 192, 1, 84, 6, 56, 9, 208, 12, 40, 15, 51, 29, 45, 55, 27, 68, 51, 51, 51, 30, 10, 10, 175, 120, 137, 137, 150, 175, 175, 120, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 153, 0, 96, 1, 148, 7, 196, 9, 92, 13, 80, 15, 88, 27, 15, 31, 28, 40, 40, 36, 44, 12, 9, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 153, 0, 40, 1, 228, 7, 96, 9, 112, 13, 80, 15, 88, 27, 0, 26, 28, 32, 28, 28, 24, 8, 9, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 0, 0, 5, 0, 1, 0, 188, 0, 40, 1, 228, 7, 136, 9, 52, 13, 8, 17, 88, 27, 40, 36, 9, 54, 51, 42, 39, 12, 12, 7, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 188, 0, 40, 1, 188, 7, 176, 9, 12, 13, 188, 17, 88, 27, 65, 55, 11, 68, 64, 53, 49, 15, 15, 9, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 154, 0, 96, 1, 244, 6, 156, 9, 208, 12, 244, 16, 88, 27, 50, 52, 15, 66, 57, 49, 49, 22, 17, 8, 178, 137, 161, 129, 135, 148, 187, 125, 162, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 116, 0, 160, 1, 84, 6, 96, 9, 188, 12, 164, 16, 88, 27, 40, 33, 23, 48, 51, 34, 37, 25, 15, 6, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 116, 0, 224, 1, 44, 6, 116, 9, 12, 13, 224, 16, 88, 27, 0, 30, 24, 48, 50, 34, 34, 21, 13, 5, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 190, 0, 5, 0, 1, 0, 0, 1, 88, 2, 36, 4, 80, 10, 28, 12, 36, 14, 15, 28, 50, 34, 28, 41, 62, 28, 36, 23, 6, 5, 186, 151, 122, 120, 120, 120, 105, 164, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 0, 1, 88, 2, 36, 4, 80, 10, 28, 12, 36, 14, 15, 28, 50, 69, 39, 64, 82, 39, 50, 32, 8, 7, 186, 151, 122, 120, 120, 120, 105, 164, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 0, 1, 88, 2, 36, 4, 80, 10, 28, 12, 36, 14, 15, 28, 50, 69, 39, 64, 82, 39, 50, 32, 8, 7, 186, 151, 122, 120, 120, 120, 105, 164, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 0, 1, 88, 2, 36, 4, 80, 10, 28, 12, 36, 14, 15, 28, 40, 50, 33, 55, 70, 33, 42, 27, 7, 6, 186, 151, 122, 120, 120, 120, 105, 164, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 0, 1, 88, 2, 36, 4, 80, 10, 28, 12, 36, 14, 15, 28, 0, 24, 23, 38, 49, 23, 30, 19, 5, 4, 186, 151, 122, 120, 120, 120, 105, 164, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 200, 0, 4, 0, 1, 0, 184, 0, 200, 1, 168, 7, 216, 9, 248, 12, 66, 14, 128, 28, 50, 36, 26, 44, 49, 52, 44, 30, 11, 8, 185, 153, 127, 120, 120, 120, 185, 200, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 184, 0, 200, 1, 168, 7, 216, 9, 248, 12, 66, 14, 128, 28, 80, 68, 36, 60, 68, 72, 60, 41, 15, 11, 185, 153, 127, 120, 120, 120, 185, 200, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 184, 0, 200, 1, 168, 7, 216, 9, 248, 12, 66, 14, 128, 28, 70, 56, 34, 52, 62, 66, 55, 38, 13, 10, 185, 153, 127, 120, 120, 120, 185, 200, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 184, 0, 200, 1, 168, 7, 216, 9, 248, 12, 66, 14, 128, 28, 0, 23, 25, 32, 37, 37, 32, 25, 9, 7, 185, 153, 127, 120, 120, 120, 185, 200, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 200, 0, 5, 0, 1, 0, 184, 0, 136, 1, 188, 2, 160, 10, 88, 12, 176, 14, 159, 27, 50, 37, 28, 41, 51, 23, 33, 18, 9, 5, 177, 100, 131, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 184, 0, 136, 1, 188, 2, 160, 10, 88, 12, 176, 14, 159, 27, 50, 72, 39, 57, 72, 32, 45, 25, 13, 7, 177, 100, 131, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 184, 0, 136, 1, 188, 2, 160, 10, 88, 12, 176, 14, 159, 27, 50, 72, 39, 57, 72, 32, 45, 25, 13, 7, 177, 100, 131, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 184, 0, 136, 1, 188, 2, 160, 10, 88, 12, 176, 14, 159, 27, 50, 52, 33, 48, 61, 27, 39, 21, 11, 6, 177, 100, 131, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 176, 0, 136, 1, 188, 2, 160, 10, 88, 12, 176, 14, 159, 27, 0, 34, 31, 45, 41, 20, 33, 18, 9, 5, 177, 100, 131, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 83, 9, 26, 0, 255, 7, 255, 250, 3, 1, 3, 248, 252, 4, 19, 15, 0, 254, 1, 6, 0, 251, 254, 255, 255, 4, 242, 243, 0, 1, 7, 10, 3, 1, 9, 6, 248, 255, 23, 0, 235, 0, 253, 229, 4, 22, 255, 0, 21, 16, 0, 0, 255, 245, 4, 6, 255, 233, 237, 5, 248, 246, 17, 29, 10, 247, 6, 11, 4, 241, 255, 251, 243, 13, 245, 223, 0, 34, 8, 13, 7, 246, 255, 242, 17, 12, 243, 7, 254, 230, 254, 24, 4, 244, 250, 243, 233, 254, 27, 7, 230, 254, 26, 22, 233, 0, 24, 0, 243, 250, 253, 243, 248, 232, 243, 4, 34, 53, 237, 242, 14, 255, 7, 252, 6, 243, 233, 1, 15, 229, 2, 51, 249, 250, 248, 21, 33, 246, 243, 232, 2, 16, 255, 243, 15, 29, 252, 250, 238, 27, 27, 13, 2, 239, 12, 15, 249, 253, 7, 1, 14, 255, 243, 2, 248, 255, 14, 0, 7, 255, 246, 245, 251, 6, 11, 252, 238, 243, 233, 252, 26, 255, 249, 0, 4, 8, 250, 255, 254, 252, 246, 251, 244, 244, 1, 0, 244, 6, 12, 8, 8, 249, 4, 253, 252, 2, 242, 244, 1, 4, 255, 0, 2, 4, 7, 7, 13, 2, 252, 251, 2, 255, 249, 0, 6, 2, 246, 7, 8, 8, 16, 252, 252, 1, 4, 3, 243, 252, 1, 0, 7, 10, 253, 5, 9, 6, 6, 3, 250, 0, 6, 4, 249, 255, 9, 244, 4, 4, 1, 4, 8, 8, 250, 252, 8, 5, 14, 246, 250, 4, 253, 1, 248, 254, 241, 0, 254, 0, 252, 244, 13, 0, 250, 15, 20, 255, 2, 18, 247, 232, 249, 9, 2, 248, 242, 237, 0, 1, 7, 19, 18, 10, 4, 254, 238, 18, 20, 237, 245, 245, 242, 242, 249, 250, 250, 19, 9, 249, 6, 13, 17, 3, 14, 24, 5, 7, 243, 245, 2, 0, 7, 238, 236, 243, 244, 252, 8, 4, 246, 12, 16, 18, 254, 11, 8, 6, 1, 241, 248, 247, 2, 247, 247, 231, 4, 11, 9, 5, 251, 14, 254, 255, 6, 248, 6, 16, 4, 245, 241, 11, 19, 11, 2, 239, 249, 6, 2, 245, 250, 253, 234, 7, 13, 20, 4, 13, 18, 3, 11, 250, 249, 246, 239, 240, 239, 250, 243, 249, 6, 5, 24, 20, 25, 253, 1, 254, 251, 2, 250, 242, 236, 250, 254, 18, 13, 2, 0, 11, 31, 0, 255, 8, 247, 249, 252, 249, 252, 0, 246, 253, 3, 9, 5, 11, 10, 245, 4, 11, 3, 1, 7, 249, 253, 242, 253, 254, 245, 6, 250, 251, 6, 9, 6, 9, 10, 8, 4, 254, 241, 247, 255, 251, 242, 245, 249, 248, 24, 6, 6, 14, 8, 12, 247, 237, 239, 11, 250, 239, 250, 251, 11, 20, 18, 5, 24, 19, 253, 249, 237, 241, 248, 248, 236, 237, 254, 6, 21, 23, 15, 18, 18, 3, 248, 1, 246, 247, 252, 232, 243, 1, 11, 2, 0, 252, 6, 10, 0, 2, 10, 1, 250, 249, 245, 5, 12, 20, 255, 0, 247, 247, 5, 10, 16, 247, 250, 12, 249, 6, 20, 6, 14, 241, 6, 1, 250, 0, 237, 250, 4, 253, 0, 15, 12, 21, 11, 4, 247, 248, 1, 242, 234, 231, 1, 244, 238, 7, 255, 20, 24, 8, 8, 252, 11, 241, 2, 249, 245, 253, 248, 255, 0, 23, 251, 6, 20, 253, 7, 247, 250, 255, 2, 9, 247, 239, 254, 249, 0, 247, 0, 1, 246, 3, 0, 0, 11, 11, 3, 254, 0, 245, 255, 6, 249, 238, 1, 1, 249, 19, 25, 10, 18, 7, 245, 1, 9, 4, 238, 251, 1, 238, 7, 0, 9, 2, 9, 33, 14, 236, 6, 8, 241, 244, 234, 241, 237, 6, 253, 238, 12, 52, 10, 3, 15, 1, 4, 239, 228, 230, 224, 13, 228, 230, 9, 34, 44, 28, 28, 25, 29, 10, 253, 247, 245, 242, 226, 241, 238, 244, 36, 0, 252, 22, 3, 35, 15, 2, 0, 3, 9, 246, 231, 241, 10, 246, 250, 13, 240, 246, 253, 14, 22, 19, 39, 11, 235, 1, 253, 230, 243, 236, 228, 219, 239, 6, 240, 0, 14, 20, 245, 5, 38, 11, 228, 2, 24, 243, 243, 250, 196, 243, 18, 250, 6, 243, 46, 4, 44, 250, 4, 27, 3, 13, 203, 252, 245, 247, 238, 232, 29, 255, 27, 9, 32, 16, 228, 33, 245, 241, 253, 255, 244, 250, 19, 241, 255, 4, 7, 22, 24, 12, 206, 234, 33, 230, 246, 250, 10, 21, 6, 27, 14, 20, 15, 239, 15, 233, 242, 7, 238, 254, 249, 3, 9, 21, 6, 11, 252, 6, 12, 243, 6, 221, 236, 9, 2, 0, 249, 245, 255, 25, 19, 255, 250, 20, 246, 251, 253, 233, 8, 2, 9, 248, 251, 30, 22, 16, 3, 254, 9, 255, 240, 235, 242, 230, 247, 17, 251, 250, 5, 3, 253, 8, 20, 3, 0, 6, 238, 236, 253, 2, 5, 249, 239, 254, 18, 0, 240, 241, 15, 18, 250, 1, 9, 12, 6, 246, 0, 248, 1, 4, 244, 236, 251, 253, 7, 0, 253, 0, 5, 30, 13, 232, 250, 18, 0, 2, 9, 249, 243, 11, 5, 252, 11, 13, 255, 0, 249, 227, 254, 19, 2, 241, 1, 24, 27, 35, 0, 249, 11, 4, 0, 240, 249, 247, 249, 0, 246, 5, 18, 22, 14, 5, 4, 0, 12, 2, 246, 0, 253, 251, 254, 250, 246, 249, 3, 1, 250, 252, 252, 7, 5, 254, 235, 240, 254, 251, 230, 241, 239, 246, 237, 246, 255, 10, 7, 255, 254, 251, 9, 0, 17, 6, 5, 13, 252, 3, 17, 13, 24, 13, 21, 14, 11, 12, 6, 7, 7, 3, 252, 248, 236, 247, 0, 252, 253, 252, 4, 1, 254, 255, 2, 252, 248, 241, 245, 251, 251, 7, 0, 0, 14, 5, 12, 15, 16, 9, 18, 8, 244, 8, 7, 254, 4, 5, 1, 0, 0, 10, 8, 251, 251, 5, 250, 243, 0, 9, 245, 245, 247, 235, 241, 8, 253, 242, 12, 3, 244, 246, 0, 250, 14, 7, 253, 248, 248, 243, 244, 237, 240, 247, 254, 5, 8, 253, 8, 24, 21, 252, 0, 1, 236, 241, 242, 241, 1, 8, 248, 12, 23, 8, 35, 15, 0, 9, 14, 250, 244, 10, 230, 218, 250, 10, 249, 3, 17, 247, 43, 13, 243, 29, 8, 2, 216, 0, 251, 246, 18, 250, 26, 1, 44, 29, 34, 13, 239, 252, 235, 19, 239, 15, 19, 9, 25, 4, 38, 230, 245, 36, 234, 214, 209, 223, 2, 255, 252, 23, 35, 9, 240, 251, 3, 0, 9, 194, 229, 226, 213, 22, 244, 0, 6, 46, 11, 15, 55, 8, 18, 252, 245, 219, 244, 251, 201, 250, 247, 244, 32, 26, 11, 2, 37, 6, 249, 1, 210, 233, 234, 221, 1, 8, 249, 249, 36, 253, 31, 13, 247, 26, 237, 235, 253, 3, 252, 240, 247, 32, 16, 24, 11, 1, 14, 9, 245, 1, 236, 223, 4, 246, 0, 14, 45, 22, 33, 27, 233, 18, 12, 219, 234, 223, 231, 13, 17, 223, 11, 46, 25, 2, 34, 41, 163, 34, 242, 189, 0, 253, 250, 210, 255, 48, 10, 15, 64, 250, 220, 58, 229, 229, 19, 240, 247, 1, 219, 220, 24, 46, 240, 2, 23, 26, 3, 238, 11, 244, 33, 14, 240, 249, 226, 217, 8, 2, 3, 23, 247, 33, 233, 250, 50, 9, 1, 3, 249, 226, 236, 7, 230, 235, 14, 41, 250, 7, 39, 223, 254, 27, 21, 251, 22, 211, 250, 233, 233, 18, 227, 0, 16, 254, 0, 31, 20, 250, 10, 34, 233, 227, 243, 5, 219, 22, 12, 202, 17, 38, 247, 13, 29, 231, 255, 19, 227, 200, 249, 55, 243, 1, 12, 7, 8, 17, 251, 208, 255, 29, 244, 251, 251, 2, 249, 3, 33, 240, 4, 18, 235, 219, 7, 247, 244, 41, 19, 0, 255, 34, 251, 18, 27, 245, 244, 14, 218, 244, 249, 6, 233, 21, 10, 238, 17, 17, 3, 243, 30, 11, 1, 246, 245, 234, 255, 246, 231, 6, 6, 253, 245, 27, 18, 9, 44, 13, 249, 36, 19, 228, 11, 249, 223, 245, 14, 5, 14, 11, 252, 237, 9, 14, 253, 13, 253, 244, 249, 246, 228, 250, 7, 3, 251, 236, 236, 242, 242, 255, 5, 246, 1, 11, 5, 0, 10, 18, 15, 253, 231, 238, 248, 11, 19, 0, 1, 12, 21, 19, 14, 20, 3, 3, 1, 235, 231, 243, 242, 238, 248, 239, 248, 15, 19, 2, 9, 9, 253, 254, 248, 246, 247, 3, 0, 252, 5, 7, 4, 13, 10, 13, 8, 0, 251, 248, 0, 254, 255, 255, 3, 18, 16, 0, 0, 11, 9, 254, 239, 246, 253, 255, 254, 247, 0, 9, 14, 6, 0, 5, 19, 25, 6, 249, 251, 250, 250, 255, 255, 255, 3, 253, 255, 254, 246, 249, 255, 12, 0, 251, 2, 1, 3, 7, 4, 0, 0, 12, 2, 246, 239, 246, 7, 0, 0, 11, 3, 246, 246, 253, 9, 11, 252, 249, 255, 248, 242, 238, 247, 240, 245, 4, 249, 242, 253, 3, 12, 23, 25, 10, 17, 24, 0, 246, 255, 1, 254, 254, 246, 236, 0, 9, 9, 15, 11, 6, 17, 25, 7, 245, 248, 255, 3, 243, 241, 238, 238, 1, 248, 236, 245, 6, 32, 34, 253, 252, 2, 14, 20, 0, 6, 0, 248, 241, 226, 223, 252, 41, 39, 251, 252, 3, 10, 8, 23, 26, 6, 0, 232, 215, 9, 26, 11, 229, 214, 4, 233, 241, 10, 253, 18, 26, 241, 2, 17, 2, 20, 0, 250, 217, 233, 26, 221, 213, 5, 5, 42, 8, 238, 35, 13, 21, 28, 249, 252, 29, 10, 242, 233, 32, 3, 237, 6, 254, 0, 232, 249, 220, 4, 38, 13, 6, 250, 27, 10, 218, 51, 52, 219, 254, 227, 133, 235, 27, 239, 244, 15, 232, 7, 57, 31, 1, 49, 52, 213, 229, 205, 227, 30, 239, 229, 233, 14, 23, 247, 4, 28, 36, 5, 2, 226, 209, 0, 251, 16, 33, 6, 8, 12, 59, 11, 22, 3, 212, 221, 240, 217, 199, 14, 238, 231, 41, 4, 34, 80, 53, 13, 35, 233, 232, 254, 223, 218, 250, 217, 248, 32, 226, 17, 22, 46, 34, 26, 25, 237, 240, 1, 232, 222, 21, 219, 223, 28, 4, 11, 245, 8, 46, 243, 7, 246, 1, 255, 228, 243, 243, 0, 17, 17, 7, 26, 248, 0, 20, 14, 245, 221, 16, 1, 219, 0, 12, 242, 252, 49, 32, 235, 232, 10, 210, 2, 226, 208, 0, 9, 5, 214, 31, 42, 13, 51, 22, 0, 12, 246, 226, 244, 0, 241, 253, 243, 4, 0, 32, 28, 19, 32, 26, 249, 236, 229, 2, 252, 248, 240, 230, 249, 242, 5, 246, 2, 5, 248, 1, 238, 236, 245, 246, 6, 19, 19, 5, 7, 17, 0, 1, 24, 14, 7, 3, 10, 232, 253, 12, 11, 251, 248, 9, 253, 12, 12, 0, 245, 248, 15, 8, 10, 1, 0, 0, 240, 242, 239, 248, 13, 10, 224, 228, 4, 29, 17, 4, 248, 9, 24, 15, 250, 242, 1, 16, 4, 235, 238, 6, 1, 252, 250, 3, 14, 17, 252, 252, 7, 5, 247, 252, 10, 246, 251, 246, 250, 8, 239, 248, 252, 5, 6, 27, 19, 251, 240, 0, 11, 15, 9, 237, 251, 252, 242, 250, 252, 2, 10, 10, 0, 252, 238, 3, 23, 1, 0, 255, 255, 0, 11, 255, 238, 1, 4, 243, 252, 3, 245, 239, 12, 12, 7, 3, 6, 21, 17, 1, 252, 249, 4, 0, 247, 236, 243, 245, 249, 1, 9, 13, 16, 13, 13, 14, 0, 243, 251, 253, 246, 247, 238, 243, 0, 10, 21, 21, 19, 21, 9, 0, 243, 242, 247, 229, 244, 0, 245, 254, 0, 12, 28, 21, 8, 6, 0, 250, 247, 242, 244, 0, 251, 246, 2, 4, 5, 17, 21, 10, 9, 2, 248, 247, 250, 251, 247, 252, 254, 251, 10, 7, 0, 6, 8, 7, 254, 249, 251, 252, 245, 254, 4, 251, 1, 2, 250, 4, 13, 2, 252, 254, 2, 9, 3, 253, 0, 7, 9, 0, 255, 250, 249, 248, 246, 253, 5, 2, 14, 17, 7, 5, 7, 8, 7, 0, 243, 240, 238, 238, 254, 0, 0, 7, 24, 22, 9, 253, 248, 254, 254, 248, 249, 249, 248, 247, 0, 4, 7, 18, 10, 0, 14, 3, 243, 235, 237, 249, 254, 5, 8, 2, 12, 14, 11, 16, 13, 0, 3, 253, 246, 239, 245, 10, 3, 1, 9, 6, 248, 255, 14, 0, 253, 255, 249, 238, 244, 241, 243, 3, 6, 8, 7, 6, 10, 9, 0, 3, 10, 254, 253, 254, 248, 251, 255, 255, 3, 11, 5, 249, 18, 24, 9, 1, 0, 3, 0, 254, 248, 241, 240, 237, 248, 249, 238, 249, 6, 12, 10, 9, 6, 13, 11, 1, 251, 253, 253, 237, 238, 245, 245, 247, 255, 13, 19, 8, 13, 23, 19, 15, 12, 254, 250, 250, 247, 243, 247, 251, 0, 0, 8, 11, 246, 246, 15, 19, 244, 252, 15, 248, 242, 250, 4, 249, 3, 3, 241, 0, 0, 252, 250, 253, 7, 5, 6, 4, 15, 15, 5, 0, 2, 14, 17, 3, 252, 254, 3, 5, 9, 10, 0, 3, 249, 247, 0, 246, 249, 251, 235, 253, 9, 3, 7, 11, 8, 8, 1, 249, 0, 12, 250, 231, 242, 6, 4, 240, 242, 18, 34, 23, 14, 10, 7, 3, 1, 1, 243, 252, 249, 242, 245, 235, 245, 9, 4, 247, 253, 253, 2, 3, 250, 248, 245, 248, 254, 249, 251, 4, 8, 2, 254, 5, 13, 12, 12, 6, 252, 0, 4, 251, 241, 238, 249, 254, 245, 235, 249, 1, 252, 253, 1, 8, 15, 17, 1, 250, 1, 5, 8, 248, 232, 0, 15, 253, 245, 252, 13, 26, 13, 15, 17, 8, 15, 2, 249, 246, 8, 21, 13, 22, 10, 255, 255, 9, 6, 9, 18, 2, 244, 241, 0, 6, 255, 17, 26, 14, 7, 0, 140, 0, 4, 0, 1, 0, 0, 1, 133, 2, 169, 6, 216, 9, 192, 13, 185, 15, 32, 29, 50, 47, 31, 55, 66, 49, 36, 28, 9, 7, 217, 150, 180, 120, 120, 120, 217, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 0, 1, 133, 2, 169, 6, 216, 9, 192, 13, 185, 15, 32, 29, 50, 90, 43, 76, 91, 68, 51, 39, 13, 7, 217, 150, 180, 120, 120, 120, 217, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 0, 1, 133, 2, 169, 6, 216, 9, 192, 13, 185, 15, 32, 29, 40, 68, 37, 66, 79, 59, 45, 34, 11, 6, 217, 150, 180, 120, 120, 120, 217, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 0, 1, 133, 2, 169, 6, 216, 9, 192, 13, 185, 15, 32, 29, 0, 49, 31, 56, 68, 51, 38, 28, 9, 9, 217, 150, 180, 120, 120, 120, 217, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 175, 0, 4, 0, 1, 0, 104, 0, 104, 1, 72, 8, 120, 10, 52, 13, 40, 15, 96, 25, 45, 49, 25, 74, 48, 46, 48, 28, 11, 5, 160, 95, 120, 167, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 104, 0, 104, 1, 72, 8, 120, 10, 52, 13, 40, 15, 96, 25, 70, 100, 36, 105, 69, 65, 68, 40, 16, 7, 160, 95, 120, 167, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 104, 0, 104, 1, 72, 8, 120, 10, 52, 13, 40, 15, 96, 25, 60, 80, 32, 94, 62, 58, 61, 35, 14, 6, 160, 95, 120, 167, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 104, 0, 104, 1, 72, 8, 100, 10, 72, 13, 40, 15, 96, 25, 0, 40, 23, 66, 43, 41, 43, 25, 10, 4, 160, 95, 120, 167, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 185, 0, 4, 0, 1, 0, 148, 0, 48, 1, 238, 7, 60, 10, 42, 13, 50, 15, 96, 25, 45, 37, 15, 54, 57, 51, 48, 33, 13, 6, 160, 111, 120, 143, 120, 120, 130, 111, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 148, 0, 48, 1, 238, 7, 60, 10, 42, 13, 50, 15, 96, 25, 75, 65, 20, 72, 76, 68, 64, 44, 18, 8, 160, 111, 120, 143, 120, 120, 130, 111, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 148, 0, 40, 1, 12, 8, 92, 10, 42, 13, 50, 15, 96, 25, 65, 48, 17, 61, 64, 57, 54, 37, 15, 7, 160, 111, 120, 143, 120, 120, 130, 111, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 148, 0, 40, 1, 32, 8, 140, 10, 42, 13, 50, 15, 96, 25, 0, 24, 12, 43, 46, 41, 39, 27, 11, 5, 160, 111, 120, 143, 120, 120, 130, 111, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 105, 0, 5, 0, 1, 0, 144, 0, 176, 1, 32, 3, 20, 10, 148, 12, 120, 15, 88, 27, 45, 42, 22, 48, 58, 37, 34, 19, 13, 6, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 144, 0, 168, 1, 32, 3, 20, 10, 148, 12, 120, 15, 88, 27, 60, 80, 28, 70, 77, 46, 43, 24, 17, 7, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 144, 0, 168, 1, 32, 3, 20, 10, 148, 12, 120, 15, 88, 27, 40, 71, 26, 66, 72, 43, 40, 23, 16, 7, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 136, 0, 160, 1, 22, 3, 30, 10, 148, 12, 120, 15, 88, 27, 40, 49, 22, 55, 60, 36, 33, 19, 13, 6, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 128, 0, 152, 1, 12, 3, 40, 10, 148, 12, 120, 15, 88, 27, 0, 43, 20, 51, 56, 34, 31, 18, 12, 5, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 40, 0, 5, 0, 1, 0, 176, 0, 168, 1, 88, 7, 216, 9, 32, 13, 60, 15, 96, 25, 45, 103, 44, 108, 68, 68, 75, 44, 18, 8, 160, 90, 120, 120, 120, 120, 130, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 177, 0, 149, 1, 254, 6, 138, 9, 240, 12, 24, 15, 141, 25, 44, 91, 42, 98, 65, 63, 69, 40, 18, 8, 160, 93, 125, 120, 120, 120, 130, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 180, 0, 104, 1, 44, 6, 212, 8, 128, 12, 196, 14, 248, 25, 71, 72, 40, 76, 60, 52, 55, 32, 19, 8, 161, 101, 138, 120, 120, 120, 130, 101, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 184, 0, 88, 1, 56, 4, 152, 8, 104, 11, 136, 14, 144, 26, 40, 45, 36, 44, 52, 36, 36, 20, 20, 8, 162, 135, 157, 120, 120, 120, 162, 120, 157, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 184, 0, 88, 1, 56, 4, 152, 8, 104, 11, 136, 14, 144, 26, 0, 35, 31, 38, 45, 31, 31, 17, 17, 7, 162, 135, 157, 120, 120, 120, 162, 120, 157, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 75, 0, 6, 0, 1, 0, 184, 0, 96, 1, 192, 3, 36, 9, 224, 11, 136, 14, 144, 26, 50, 46, 20, 55, 58, 40, 35, 26, 14, 7, 162, 127, 157, 120, 120, 120, 162, 127, 157, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 184, 0, 96, 1, 192, 3, 36, 9, 224, 11, 136, 14, 144, 26, 50, 63, 23, 64, 68, 47, 40, 30, 17, 8, 162, 127, 157, 120, 120, 120, 162, 127, 157, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 183, 0, 96, 1, 11, 4, 46, 9, 241, 11, 137, 14, 166, 26, 50, 53, 23, 59, 61, 45, 39, 29, 16, 8, 162, 126, 164, 120, 120, 120, 162, 127, 157, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 174, 0, 97, 1, 182, 5, 108, 9, 83, 12, 147, 14, 38, 27, 50, 36, 24, 48, 39, 45, 40, 28, 14, 7, 164, 118, 201, 120, 120, 120, 162, 120, 200, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 168, 0, 91, 1, 240, 6, 229, 9, 206, 12, 153, 14, 143, 27, 25, 26, 22, 42, 33, 36, 33, 22, 10, 6, 165, 106, 186, 120, 120, 120, 162, 120, 172, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 164, 0, 87, 1, 119, 7, 26, 10, 3, 13, 157, 14, 189, 27, 0, 23, 21, 40, 33, 32, 27, 20, 6, 6, 166, 101, 183, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 100, 0, 5, 0, 1, 0, 32, 1, 32, 3, 236, 4, 160, 10, 172, 13, 180, 15, 32, 28, 50, 46, 32, 56, 66, 39, 32, 22, 9, 4, 162, 155, 135, 120, 120, 120, 192, 155, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 32, 1, 32, 3, 216, 4, 160, 10, 172, 13, 180, 15, 32, 28, 50, 91, 44, 82, 88, 54, 44, 30, 13, 6, 162, 155, 135, 120, 120, 120, 192, 155, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 32, 1, 32, 3, 0, 5, 160, 10, 172, 13, 180, 15, 32, 28, 50, 87, 44, 82, 88, 54, 44, 30, 13, 6, 162, 155, 135, 120, 120, 120, 192, 155, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 32, 1, 13, 3, 0, 5, 120, 10, 52, 13, 120, 15, 32, 28, 50, 68, 39, 69, 82, 48, 39, 27, 12, 6, 162, 155, 135, 120, 120, 120, 192, 155, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 32, 1, 13, 3, 0, 5, 120, 10, 52, 13, 120, 15, 32, 28, 0, 35, 28, 50, 59, 35, 28, 19, 8, 4, 162, 155, 135, 120, 120, 120, 192, 155, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 160, 0, 4, 0, 1, 0, 149, 0, 24, 1, 207, 8, 214, 11, 112, 13, 134, 16, 42, 27, 50, 44, 7, 62, 51, 47, 51, 23, 16, 8, 182, 120, 133, 133, 142, 161, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 149, 0, 24, 1, 207, 8, 214, 11, 112, 13, 134, 16, 42, 27, 60, 56, 8, 70, 58, 53, 58, 26, 18, 9, 182, 120, 133, 133, 142, 161, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 149, 0, 8, 1, 207, 8, 214, 11, 112, 13, 134, 16, 42, 27, 50, 49, 14, 62, 47, 46, 49, 21, 16, 8, 182, 120, 133, 133, 142, 161, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 149, 0, 8, 1, 207, 8, 214, 11, 112, 13, 134, 16, 42, 27, 0, 45, 14, 59, 45, 44, 47, 20, 15, 7, 182, 120, 133, 133, 142, 161, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 125, 0, 6, 0, 1, 0, 14, 1, 8, 3, 176, 4, 200, 10, 2, 13, 238, 14, 192, 27, 45, 42, 24, 56, 63, 36, 30, 25, 9, 4, 165, 148, 135, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 14, 1, 8, 3, 176, 4, 200, 10, 2, 13, 238, 14, 192, 27, 40, 92, 36, 82, 93, 53, 44, 37, 13, 6, 165, 148, 135, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 14, 1, 8, 3, 176, 4, 200, 10, 2, 13, 238, 14, 192, 27, 35, 75, 32, 74, 84, 48, 39, 33, 12, 6, 165, 148, 135, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 245, 0, 150, 2, 86, 4, 144, 10, 229, 12, 209, 14, 107, 27, 80, 62, 28, 69, 70, 43, 36, 31, 13, 6, 164, 144, 140, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 186, 0, 137, 1, 132, 3, 13, 10, 159, 12, 139, 14, 164, 26, 40, 48, 21, 61, 38, 31, 28, 28, 17, 7, 163, 134, 154, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 184, 0, 112, 1, 132, 3, 236, 9, 148, 12, 136, 14, 144, 26, 0, 32, 18, 50, 30, 25, 23, 23, 14, 6, 162, 133, 155, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 230, 0, 5, 0, 1, 0, 72, 1, 136, 3, 40, 5, 180, 10, 112, 13, 191, 14, 32, 28, 45, 45, 30, 64, 55, 34, 30, 19, 9, 4, 207, 150, 105, 120, 120, 120, 237, 165, 165, 44, 65, 70, 130, 54, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 72, 1, 136, 3, 40, 5, 180, 10, 112, 13, 191, 14, 32, 28, 70, 103, 45, 97, 83, 52, 45, 28, 13, 6, 207, 150, 105, 120, 120, 120, 237, 165, 165, 44, 65, 70, 130, 54, 0, 0, 0, 0, 50, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 55, 1, 100, 3, 140, 5, 160, 10, 116, 13, 189, 14, 32, 28, 70, 80, 40, 88, 78, 48, 40, 26, 12, 6, 203, 144, 114, 120, 120, 120, 237, 165, 165, 44, 60, 70, 130, 54, 0, 0, 0, 0, 50, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 156, 0, 88, 1, 152, 8, 140, 10, 152, 13, 166, 14, 32, 28, 45, 40, 27, 54, 49, 58, 45, 32, 9, 7, 167, 90, 195, 120, 120, 120, 122, 120, 135, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 156, 0, 88, 1, 174, 8, 160, 10, 92, 13, 10, 15, 32, 28, 0, 25, 22, 44, 45, 41, 37, 30, 8, 7, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 200, 0, 4, 0, 1, 0, 160, 0, 232, 1, 198, 7, 236, 9, 12, 13, 101, 14, 128, 28, 50, 37, 26, 54, 56, 55, 44, 32, 11, 6, 185, 112, 127, 120, 120, 120, 185, 117, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 160, 0, 232, 1, 198, 7, 236, 9, 12, 13, 101, 14, 128, 28, 80, 57, 32, 66, 69, 68, 54, 40, 13, 8, 185, 112, 127, 120, 120, 120, 185, 117, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 160, 0, 232, 1, 198, 7, 236, 9, 12, 13, 101, 14, 128, 28, 70, 59, 33, 68, 70, 69, 55, 41, 13, 8, 185, 112, 127, 120, 120, 120, 185, 117, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 160, 0, 232, 1, 198, 7, 236, 9, 12, 13, 101, 14, 128, 28, 0, 27, 22, 45, 47, 47, 37, 27, 9, 5, 185, 112, 127, 120, 120, 120, 185, 117, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 60, 0, 4, 0, 1, 0, 130, 0, 49, 1, 164, 6, 36, 9, 228, 12, 99, 14, 151, 25, 45, 35, 18, 54, 40, 32, 35, 31, 9, 10, 167, 96, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 130, 0, 49, 1, 164, 6, 36, 9, 228, 12, 99, 14, 151, 25, 60, 68, 25, 76, 56, 45, 48, 43, 13, 15, 167, 96, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 130, 0, 49, 1, 164, 6, 36, 9, 228, 12, 99, 14, 151, 25, 60, 55, 23, 68, 50, 40, 44, 39, 11, 13, 167, 96, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 130, 0, 49, 1, 164, 6, 36, 9, 228, 12, 99, 14, 151, 25, 0, 44, 20, 61, 45, 36, 39, 35, 10, 12, 167, 96, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 55, 0, 2, 0, 5, 0, 76, 0, 104, 1, 8, 7, 124, 11, 172, 13, 160, 15, 32, 29, 55, 17, 9, 45, 22, 18, 34, 20, 8, 0, 155, 135, 97, 120, 120, 120, 95, 105, 97, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 76, 0, 104, 1, 8, 7, 124, 11, 172, 13, 160, 15, 32, 29, 0, 12, 7, 38, 23, 15, 28, 16, 7, 0, 150, 135, 97, 120, 120, 120, 90, 105, 97, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 18, 0, 2, 0, 5, 0, 180, 0, 29, 1, 185, 8, 200, 10, 32, 13, 116, 14, 0, 29, 18, 14, 3, 39, 18, 28, 36, 20, 6, 0, 120, 105, 150, 120, 120, 120, 45, 135, 90, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 180, 0, 29, 1, 185, 8, 200, 10, 32, 13, 116, 14, 0, 29, 0, 26, 4, 52, 24, 38, 48, 27, 8, 0, 120, 105, 150, 120, 120, 120, 45, 135, 90, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 35, 0, 3, 0, 5, 0, 224, 0, 224, 2, 40, 5, 76, 9, 208, 12, 136, 14, 117, 27, 35, 30, 23, 47, 39, 34, 28, 23, 9, 2, 196, 162, 195, 120, 120, 120, 249, 174, 250, 44, 35, 70, 130, 50, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 224, 0, 224, 2, 40, 5, 76, 9, 208, 12, 136, 14, 117, 27, 40, 30, 23, 47, 39, 34, 28, 23, 9, 2, 196, 162, 195, 120, 120, 120, 249, 174, 250, 44, 35, 70, 130, 50, 0, 0, 0, 0, 45, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 208, 0, 208, 2, 60, 5, 76, 9, 208, 12, 136, 14, 105, 27, 0, 24, 22, 44, 31, 23, 21, 21, 10, 2, 192, 158, 201, 120, 120, 120, 249, 174, 255, 44, 35, 70, 130, 52, 0, 0, 0, 0, 45, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 35, 0, 3, 0, 5, 0, 116, 0, 32, 2, 100, 5, 252, 8, 168, 12, 116, 14, 96, 27, 35, 28, 23, 45, 56, 31, 32, 24, 12, 7, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 116, 0, 32, 2, 100, 5, 252, 8, 168, 12, 116, 14, 96, 27, 40, 28, 23, 45, 56, 31, 32, 24, 12, 7, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 116, 0, 32, 2, 100, 5, 252, 8, 168, 12, 116, 14, 96, 27, 0, 22, 20, 40, 50, 28, 28, 22, 11, 6, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 35, 0, 3, 0, 5, 0, 208, 0, 120, 2, 20, 5, 252, 8, 88, 12, 196, 14, 210, 27, 35, 34, 27, 45, 60, 36, 33, 21, 12, 4, 185, 160, 141, 120, 120, 120, 235, 150, 118, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 208, 0, 120, 2, 20, 5, 252, 8, 88, 12, 196, 14, 210, 27, 40, 34, 27, 45, 60, 36, 33, 21, 12, 4, 185, 160, 141, 120, 120, 120, 235, 150, 118, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 208, 0, 120, 2, 20, 5, 252, 8, 88, 12, 156, 14, 210, 27, 0, 27, 25, 41, 52, 30, 28, 19, 11, 4, 185, 160, 141, 120, 120, 120, 235, 150, 118, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 150, 0, 5, 0, 1, 0, 184, 0, 132, 1, 172, 3, 116, 9, 224, 11, 136, 14, 144, 26, 50, 51, 26, 61, 52, 32, 29, 20, 14, 7, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 184, 0, 132, 1, 172, 3, 116, 9, 224, 11, 136, 14, 144, 26, 60, 78, 32, 75, 64, 39, 36, 25, 18, 9, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 184, 0, 132, 1, 172, 3, 116, 9, 224, 11, 136, 14, 144, 26, 40, 67, 30, 71, 57, 37, 33, 23, 16, 8, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 128, 0, 32, 2, 156, 4, 252, 8, 68, 12, 136, 14, 96, 27, 40, 34, 29, 53, 50, 34, 31, 29, 15, 5, 167, 135, 135, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 128, 0, 32, 2, 156, 4, 252, 8, 68, 12, 136, 14, 96, 27, 0, 34, 29, 53, 50, 34, 31, 29, 15, 5, 167, 135, 135, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 190, 0, 5, 0, 1, 0, 0, 1, 112, 2, 192, 3, 64, 11, 48, 12, 36, 14, 15, 28, 50, 34, 23, 44, 44, 18, 36, 20, 5, 5, 186, 175, 135, 120, 120, 120, 105, 185, 148, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 0, 1, 112, 2, 192, 3, 64, 11, 48, 12, 36, 14, 15, 28, 50, 66, 32, 61, 61, 25, 50, 28, 8, 7, 186, 175, 135, 120, 120, 120, 105, 185, 148, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 0, 1, 112, 2, 192, 3, 64, 11, 48, 12, 36, 14, 15, 28, 50, 66, 32, 61, 61, 25, 50, 28, 8, 7, 186, 175, 135, 120, 120, 120, 105, 185, 148, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 0, 1, 112, 2, 192, 3, 64, 11, 48, 12, 36, 14, 15, 28, 40, 47, 27, 52, 52, 21, 42, 24, 6, 6, 186, 175, 135, 120, 120, 120, 105, 185, 148, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 0, 1, 112, 2, 192, 3, 64, 11, 48, 12, 36, 14, 15, 28, 0, 20, 18, 34, 34, 14, 28, 16, 4, 4, 186, 175, 135, 120, 120, 120, 105, 185, 148, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 255, 0, 0, 3, 0, 0, 0, 0, 0, 127, 0, 114, 0, 0, 0, 0, 245, 0, 5, 0, 1, 0, 244, 0, 35, 2, 63, 7, 232, 9, 38, 13, 144, 14, 176, 28, 45, 32, 26, 49, 47, 49, 41, 30, 9, 6, 202, 118, 143, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 244, 0, 35, 2, 63, 7, 232, 9, 38, 13, 144, 14, 176, 28, 80, 71, 38, 72, 72, 76, 63, 46, 14, 10, 202, 118, 143, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 244, 0, 35, 2, 63, 7, 232, 9, 38, 13, 144, 14, 176, 28, 60, 50, 32, 60, 60, 64, 53, 38, 12, 8, 202, 118, 143, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 144, 0, 64, 1, 252, 8, 180, 10, 152, 13, 10, 15, 32, 28, 60, 25, 18, 46, 43, 39, 36, 28, 8, 7, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 144, 0, 64, 1, 252, 8, 180, 10, 152, 13, 10, 15, 32, 28, 0, 23, 17, 45, 41, 38, 35, 27, 8, 7, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 175, 0, 4, 0, 1, 0, 156, 0, 56, 1, 252, 8, 4, 11, 212, 13, 120, 15, 144, 27, 45, 40, 11, 59, 53, 52, 45, 28, 11, 7, 176, 106, 143, 120, 120, 120, 185, 107, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 156, 0, 56, 1, 252, 8, 4, 11, 212, 13, 120, 15, 144, 27, 70, 83, 17, 85, 76, 75, 65, 40, 16, 10, 176, 106, 143, 120, 120, 120, 185, 107, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 156, 0, 56, 1, 252, 8, 4, 11, 212, 13, 120, 15, 144, 27, 60, 67, 15, 76, 69, 67, 58, 36, 15, 9, 176, 106, 143, 120, 120, 120, 185, 107, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 156, 0, 48, 1, 252, 8, 4, 11, 212, 13, 120, 15, 144, 27, 0, 30, 10, 51, 46, 45, 39, 24, 10, 6, 176, 106, 143, 120, 120, 120, 185, 107, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 185, 0, 4, 0, 1, 0, 248, 0, 200, 2, 136, 4, 220, 10, 52, 13, 68, 15, 176, 27, 45, 50, 30, 61, 64, 39, 36, 25, 7, 5, 165, 130, 155, 120, 120, 120, 167, 130, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 248, 0, 200, 2, 136, 4, 220, 10, 52, 13, 68, 15, 176, 27, 60, 96, 42, 85, 89, 55, 49, 35, 10, 7, 165, 130, 155, 120, 120, 120, 167, 130, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 248, 0, 192, 2, 136, 4, 220, 10, 52, 13, 68, 15, 176, 27, 80, 85, 40, 80, 84, 52, 47, 33, 9, 7, 165, 130, 155, 120, 120, 120, 167, 130, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 248, 0, 184, 2, 136, 4, 220, 10, 52, 13, 68, 15, 176, 27, 0, 48, 30, 60, 63, 39, 35, 25, 7, 5, 165, 130, 155, 120, 120, 120, 167, 130, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 100, 0, 4, 0, 1, 0, 176, 0, 88, 1, 32, 3, 56, 9, 12, 13, 60, 15, 144, 26, 50, 47, 3, 73, 43, 21, 21, 30, 12, 7, 177, 125, 110, 120, 120, 120, 177, 125, 125, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 176, 0, 88, 1, 32, 3, 56, 9, 12, 13, 60, 15, 144, 26, 50, 79, 4, 96, 56, 28, 28, 40, 16, 10, 177, 125, 110, 120, 120, 120, 177, 125, 125, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 176, 0, 88, 1, 32, 3, 56, 9, 12, 13, 60, 15, 144, 26, 70, 63, 3, 85, 49, 24, 24, 35, 14, 8, 177, 125, 110, 120, 120, 120, 177, 125, 125, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 176, 0, 88, 1, 32, 3, 56, 9, 12, 13, 60, 15, 144, 26, 0, 31, 2, 60, 35, 17, 17, 25, 10, 6, 177, 125, 110, 120, 120, 120, 177, 125, 125, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 175, 0, 4, 0, 1, 0, 176, 0, 112, 1, 32, 3, 100, 10, 48, 12, 60, 15, 144, 26, 45, 55, 12, 64, 58, 30, 27, 24, 15, 7, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 176, 0, 112, 1, 32, 3, 100, 10, 48, 12, 60, 15, 144, 26, 70, 92, 16, 84, 76, 40, 36, 32, 20, 10, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 176, 0, 112, 1, 32, 3, 100, 10, 48, 12, 60, 15, 144, 26, 60, 75, 14, 75, 68, 36, 32, 28, 18, 9, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 176, 0, 112, 1, 32, 3, 100, 10, 48, 12, 60, 15, 144, 26, 0, 49, 11, 61, 55, 29, 26, 23, 14, 7, 162, 127, 150, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 0, 0, 6, 0, 1, 0, 250, 0, 176, 2, 40, 4, 246, 10, 188, 12, 92, 14, 87, 27, 45, 60, 24, 58, 73, 41, 37, 34, 9, 5, 167, 147, 147, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 250, 0, 176, 2, 40, 4, 246, 10, 188, 12, 92, 14, 87, 27, 30, 103, 32, 76, 95, 54, 48, 44, 12, 7, 167, 147, 147, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 244, 0, 216, 2, 116, 4, 160, 10, 148, 12, 41, 14, 96, 27, 35, 85, 32, 68, 98, 49, 41, 41, 16, 8, 167, 142, 135, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 246, 0, 200, 2, 120, 5, 216, 9, 132, 13, 224, 16, 88, 27, 50, 64, 34, 76, 64, 48, 44, 20, 12, 10, 226, 150, 136, 120, 120, 120, 235, 150, 136, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 5, 0, 166, 0, 80, 1, 192, 8, 229, 10, 132, 13, 94, 15, 138, 27, 70, 50, 16, 60, 60, 57, 50, 30, 13, 8, 181, 110, 142, 120, 120, 120, 235, 150, 136, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 156, 0, 56, 1, 252, 8, 4, 11, 132, 13, 50, 15, 144, 27, 0, 40, 11, 59, 53, 52, 45, 28, 11, 7, 176, 106, 143, 120, 120, 120, 185, 107, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 255, 0, 5, 0, 1, 0, 24, 1, 232, 2, 4, 6, 196, 9, 112, 13, 40, 15, 153, 28, 45, 45, 31, 60, 60, 46, 36, 28, 10, 6, 215, 138, 143, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 24, 1, 232, 2, 4, 6, 196, 9, 112, 13, 40, 15, 153, 28, 75, 88, 44, 84, 84, 64, 51, 39, 14, 8, 215, 138, 143, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 24, 1, 232, 2, 4, 6, 196, 9, 112, 13, 40, 15, 153, 28, 65, 79, 41, 79, 79, 60, 48, 37, 13, 8, 215, 138, 143, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 156, 0, 80, 1, 192, 8, 140, 10, 152, 13, 166, 14, 32, 28, 70, 43, 32, 55, 49, 58, 45, 33, 10, 8, 167, 90, 195, 120, 120, 120, 122, 90, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 156, 0, 72, 1, 232, 8, 160, 10, 92, 13, 10, 15, 32, 28, 0, 30, 28, 45, 45, 41, 38, 30, 8, 8, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 250, 0, 5, 0, 1, 0, 122, 0, 192, 1, 240, 5, 116, 9, 228, 12, 246, 14, 95, 27, 45, 49, 28, 59, 69, 41, 43, 30, 17, 6, 170, 133, 135, 122, 124, 128, 197, 131, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 122, 0, 192, 1, 240, 5, 116, 9, 228, 12, 246, 14, 95, 27, 80, 79, 36, 75, 88, 52, 55, 38, 21, 8, 170, 133, 135, 122, 124, 128, 197, 131, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 122, 0, 192, 1, 240, 5, 116, 9, 228, 12, 246, 14, 95, 27, 80, 64, 32, 68, 79, 47, 49, 35, 19, 7, 170, 133, 135, 122, 124, 128, 197, 131, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 156, 0, 99, 1, 152, 8, 140, 10, 152, 13, 166, 14, 32, 28, 45, 43, 32, 56, 49, 59, 46, 33, 10, 8, 167, 90, 195, 120, 120, 120, 122, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 156, 0, 99, 1, 174, 8, 160, 10, 92, 13, 10, 15, 32, 28, 0, 27, 28, 44, 44, 40, 37, 29, 8, 7, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 210, 0, 5, 0, 1, 0, 172, 0, 64, 1, 228, 2, 96, 9, 12, 13, 60, 15, 144, 26, 45, 35, 2, 64, 42, 19, 19, 25, 8, 7, 177, 117, 100, 120, 120, 120, 177, 117, 115, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 172, 0, 64, 1, 228, 2, 96, 9, 12, 13, 60, 15, 144, 26, 75, 74, 4, 92, 64, 28, 28, 36, 12, 10, 177, 117, 100, 120, 120, 120, 177, 117, 115, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 170, 0, 60, 1, 122, 3, 166, 9, 24, 13, 106, 15, 164, 26, 30, 52, 4, 79, 39, 26, 27, 30, 11, 8, 178, 118, 103, 121, 123, 125, 177, 117, 115, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 9, 0, 148, 0, 16, 1, 199, 8, 28, 12, 132, 13, 8, 17, 88, 27, 60, 35, 15, 49, 34, 38, 45, 15, 15, 7, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 148, 0, 16, 1, 199, 8, 28, 12, 132, 13, 8, 17, 88, 27, 0, 33, 14, 47, 33, 36, 44, 14, 14, 7, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 75, 0, 5, 0, 1, 0, 132, 0, 24, 1, 184, 6, 16, 9, 228, 12, 96, 14, 100, 25, 45, 42, 18, 60, 40, 35, 37, 34, 9, 12, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 132, 0, 24, 1, 184, 6, 16, 9, 228, 12, 96, 14, 100, 25, 75, 78, 25, 82, 56, 47, 51, 47, 12, 17, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 133, 0, 27, 1, 40, 7, 96, 9, 253, 12, 122, 14, 196, 25, 75, 61, 23, 71, 51, 46, 48, 41, 11, 14, 167, 91, 138, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 136, 0, 38, 1, 187, 8, 180, 10, 86, 13, 215, 14, 33, 27, 45, 49, 21, 60, 52, 55, 50, 32, 12, 9, 169, 96, 152, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 137, 0, 40, 1, 232, 8, 220, 10, 97, 13, 226, 14, 72, 27, 0, 38, 20, 55, 49, 53, 47, 29, 11, 8, 169, 97, 153, 120, 120, 120, 122, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 125, 0, 6, 0, 1, 0, 240, 0, 176, 2, 36, 4, 20, 10, 188, 12, 92, 14, 87, 27, 45, 44, 21, 50, 62, 33, 33, 29, 8, 5, 167, 147, 147, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 240, 0, 176, 2, 36, 4, 20, 10, 188, 12, 92, 14, 87, 27, 40, 96, 30, 73, 92, 48, 48, 43, 12, 7, 167, 147, 147, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 232, 0, 148, 2, 12, 4, 76, 10, 200, 12, 104, 14, 87, 27, 35, 78, 27, 66, 81, 43, 43, 38, 11, 6, 167, 147, 147, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 200, 0, 32, 2, 172, 3, 220, 10, 248, 12, 156, 14, 87, 27, 80, 74, 27, 66, 75, 43, 43, 38, 11, 6, 167, 147, 147, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 186, 0, 137, 1, 132, 3, 13, 10, 159, 12, 139, 14, 164, 26, 40, 49, 22, 61, 38, 31, 28, 28, 17, 7, 163, 134, 154, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 184, 0, 112, 1, 132, 3, 236, 9, 148, 12, 136, 14, 144, 26, 0, 32, 18, 50, 30, 25, 23, 23, 14, 6, 162, 133, 155, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 255, 0, 5, 0, 1, 0, 168, 0, 4, 2, 92, 3, 88, 10, 104, 11, 141, 14, 32, 27, 45, 56, 21, 52, 64, 39, 36, 18, 13, 5, 167, 135, 150, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 168, 0, 4, 2, 92, 3, 88, 10, 104, 11, 141, 14, 32, 27, 70, 108, 29, 73, 89, 54, 50, 25, 18, 7, 167, 135, 150, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 168, 0, 240, 1, 92, 3, 60, 10, 146, 11, 158, 14, 18, 27, 80, 90, 25, 71, 81, 49, 45, 25, 17, 7, 168, 134, 145, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 176, 0, 56, 1, 92, 3, 56, 9, 12, 13, 60, 15, 144, 26, 60, 53, 3, 79, 43, 23, 23, 33, 13, 8, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 176, 0, 56, 1, 92, 3, 56, 9, 12, 13, 60, 15, 144, 26, 0, 33, 2, 62, 35, 19, 19, 27, 10, 6, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 250, 0, 5, 0, 1, 0, 200, 0, 204, 1, 137, 7, 208, 9, 208, 12, 69, 14, 104, 28, 45, 29, 21, 46, 46, 49, 37, 28, 9, 6, 184, 108, 128, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 200, 0, 204, 1, 137, 7, 208, 9, 208, 12, 69, 14, 104, 28, 60, 84, 36, 79, 78, 83, 63, 48, 15, 11, 184, 108, 128, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 198, 0, 192, 1, 44, 7, 195, 9, 213, 12, 91, 14, 62, 28, 80, 71, 31, 76, 61, 74, 57, 44, 14, 10, 183, 109, 149, 120, 120, 120, 185, 107, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 178, 0, 71, 1, 179, 3, 63, 9, 9, 13, 48, 15, 166, 26, 65, 42, 4, 71, 37, 23, 22, 30, 12, 7, 178, 124, 103, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 178, 0, 71, 1, 179, 3, 63, 9, 9, 13, 48, 15, 166, 26, 0, 30, 3, 60, 31, 19, 18, 25, 10, 6, 178, 124, 103, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 4, 1, 6, 0, 1, 0, 152, 0, 40, 1, 152, 8, 4, 11, 92, 13, 135, 15, 160, 26, 45, 21, 4, 46, 41, 41, 42, 20, 9, 4, 167, 105, 120, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 152, 0, 40, 1, 132, 8, 4, 11, 92, 13, 135, 15, 160, 26, 60, 62, 7, 78, 70, 70, 71, 34, 16, 8, 167, 105, 120, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 155, 0, 43, 1, 188, 7, 195, 10, 81, 13, 125, 15, 158, 26, 80, 53, 6, 76, 54, 61, 61, 33, 15, 7, 168, 107, 150, 120, 120, 120, 167, 90, 152, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 174, 0, 62, 1, 199, 3, 80, 9, 17, 13, 64, 15, 145, 26, 35, 39, 3, 71, 36, 22, 22, 29, 12, 7, 176, 123, 103, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 176, 0, 64, 1, 152, 3, 56, 9, 12, 13, 60, 15, 144, 26, 40, 37, 2, 67, 33, 19, 19, 28, 11, 7, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 176, 0, 64, 1, 152, 3, 56, 9, 12, 13, 60, 15, 144, 26, 0, 30, 2, 60, 30, 17, 17, 25, 10, 6, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 250, 0, 5, 0, 1, 0, 40, 1, 232, 2, 240, 5, 196, 9, 112, 13, 40, 15, 153, 28, 45, 42, 29, 57, 60, 43, 35, 26, 9, 5, 215, 138, 143, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 40, 1, 232, 2, 240, 5, 196, 9, 112, 13, 40, 15, 153, 28, 80, 81, 41, 79, 83, 60, 48, 37, 13, 8, 215, 138, 143, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 24, 1, 186, 2, 4, 6, 180, 9, 98, 13, 20, 15, 71, 28, 80, 64, 35, 71, 72, 53, 43, 34, 12, 7, 210, 133, 142, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 132, 0, 40, 1, 184, 6, 36, 9, 228, 12, 96, 14, 100, 25, 45, 42, 19, 61, 41, 35, 38, 35, 9, 12, 165, 90, 135, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 132, 0, 40, 1, 184, 6, 36, 9, 228, 12, 96, 14, 100, 25, 0, 26, 15, 48, 33, 28, 30, 28, 7, 10, 165, 90, 135, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 250, 0, 5, 0, 1, 0, 244, 0, 35, 2, 63, 7, 232, 9, 38, 13, 144, 14, 176, 28, 45, 28, 23, 46, 45, 48, 37, 27, 8, 6, 202, 118, 143, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 244, 0, 35, 2, 63, 7, 232, 9, 38, 13, 144, 14, 176, 28, 80, 82, 40, 79, 77, 81, 63, 46, 14, 10, 202, 118, 143, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 244, 0, 35, 2, 63, 7, 232, 9, 38, 13, 144, 14, 176, 28, 80, 73, 38, 75, 72, 77, 60, 43, 13, 9, 202, 118, 143, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 132, 0, 24, 1, 184, 6, 36, 9, 228, 12, 96, 14, 100, 25, 45, 47, 20, 63, 43, 37, 40, 36, 10, 13, 165, 90, 135, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 132, 0, 24, 1, 184, 6, 36, 9, 228, 12, 96, 14, 100, 25, 0, 30, 16, 50, 34, 29, 32, 29, 8, 10, 165, 90, 135, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 250, 0, 5, 0, 1, 0, 122, 0, 192, 1, 240, 5, 116, 9, 228, 12, 246, 14, 95, 27, 45, 49, 28, 59, 69, 41, 43, 30, 17, 6, 170, 133, 135, 122, 124, 128, 197, 131, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 122, 0, 192, 1, 240, 5, 116, 9, 228, 12, 246, 14, 95, 27, 80, 79, 36, 75, 88, 52, 55, 38, 21, 8, 170, 133, 135, 122, 124, 128, 197, 131, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 122, 0, 192, 1, 240, 5, 116, 9, 228, 12, 246, 14, 95, 27, 80, 64, 32, 68, 79, 47, 49, 35, 19, 7, 170, 133, 135, 122, 124, 128, 197, 131, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 132, 0, 24, 1, 184, 6, 36, 9, 228, 12, 96, 14, 100, 25, 45, 47, 20, 63, 43, 37, 40, 36, 10, 13, 165, 90, 135, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 132, 0, 24, 1, 184, 6, 36, 9, 228, 12, 96, 14, 100, 25, 0, 30, 16, 50, 34, 29, 32, 29, 8, 10, 165, 90, 135, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 250, 0, 5, 0, 33, 0, 152, 0, 32, 1, 224, 8, 4, 11, 52, 13, 0, 15, 160, 26, 45, 45, 6, 66, 59, 59, 60, 29, 14, 6, 175, 105, 120, 120, 120, 120, 175, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 152, 0, 24, 1, 232, 8, 4, 11, 52, 13, 0, 15, 160, 26, 80, 72, 10, 83, 73, 74, 75, 36, 17, 8, 167, 105, 120, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 152, 0, 24, 1, 232, 8, 4, 11, 12, 13, 216, 14, 64, 26, 80, 45, 10, 60, 60, 63, 63, 34, 11, 8, 167, 105, 120, 120, 120, 120, 167, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 132, 0, 24, 1, 184, 6, 36, 9, 228, 12, 96, 14, 100, 25, 45, 47, 20, 63, 43, 37, 40, 36, 10, 13, 165, 90, 135, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 132, 0, 24, 1, 184, 6, 36, 9, 228, 12, 96, 14, 100, 25, 0, 30, 16, 50, 34, 29, 32, 29, 8, 10, 165, 90, 135, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 185, 0, 5, 0, 1, 0, 176, 0, 88, 1, 128, 3, 71, 9, 213, 12, 38, 15, 162, 26, 45, 47, 6, 73, 41, 23, 23, 29, 12, 7, 176, 126, 108, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 176, 0, 88, 1, 128, 3, 71, 9, 213, 12, 38, 15, 162, 26, 80, 80, 8, 94, 53, 31, 30, 38, 16, 9, 176, 126, 108, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 176, 0, 103, 1, 125, 3, 80, 9, 181, 12, 25, 15, 173, 26, 65, 60, 9, 80, 48, 28, 26, 31, 13, 7, 175, 126, 112, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 5, 0, 170, 0, 224, 1, 99, 3, 155, 9, 98, 12, 223, 14, 7, 27, 60, 47, 22, 59, 51, 32, 27, 19, 12, 5, 169, 133, 142, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 169, 0, 238, 1, 96, 3, 164, 9, 88, 12, 216, 14, 18, 27, 0, 33, 19, 48, 44, 26, 23, 15, 11, 4, 168, 134, 145, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 80, 0, 5, 0, 1, 0, 132, 0, 24, 1, 184, 6, 36, 9, 228, 12, 96, 14, 100, 25, 45, 35, 17, 55, 37, 32, 35, 32, 8, 11, 160, 90, 135, 120, 120, 120, 160, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 132, 0, 24, 1, 184, 6, 36, 9, 228, 12, 96, 14, 100, 25, 80, 67, 24, 76, 51, 44, 48, 44, 12, 16, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 132, 0, 24, 1, 184, 6, 36, 9, 228, 12, 96, 14, 100, 25, 80, 54, 21, 68, 46, 39, 43, 39, 10, 14, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 122, 0, 192, 1, 240, 5, 116, 9, 228, 12, 246, 14, 95, 27, 45, 38, 25, 52, 61, 36, 38, 27, 15, 5, 170, 133, 135, 122, 124, 128, 197, 131, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 122, 0, 192, 1, 240, 5, 116, 9, 228, 12, 246, 14, 95, 27, 0, 27, 21, 44, 52, 30, 32, 23, 12, 5, 170, 133, 135, 122, 124, 128, 197, 131, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 65, 0, 4, 0, 5, 0, 116, 0, 13, 2, 161, 5, 152, 8, 128, 12, 212, 13, 96, 27, 20, 8, 14, 26, 25, 12, 12, 12, 7, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 116, 0, 13, 2, 161, 5, 152, 8, 128, 12, 212, 13, 96, 27, 25, 15, 19, 35, 33, 16, 16, 16, 9, 5, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 5, 0, 116, 0, 13, 2, 161, 5, 152, 8, 128, 12, 212, 13, 96, 27, 20, 15, 19, 35, 33, 16, 16, 16, 9, 5, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 116, 0, 13, 2, 161, 5, 152, 8, 128, 12, 212, 13, 96, 27, 0, 9, 15, 28, 26, 13, 13, 13, 7, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 234, 8, 18, 0, 253, 253, 0, 0, 249, 246, 252, 252, 244, 236, 237, 245, 247, 248, 252, 254, 2, 10, 16, 10, 13, 22, 7, 13, 34, 24, 31, 29, 14, 29, 17, 7, 25, 0, 230, 246, 252, 249, 247, 228, 229, 242, 246, 232, 229, 240, 238, 245, 1, 252, 215, 217, 5, 13, 18, 35, 17, 20, 45, 18, 244, 251, 254, 0, 17, 252, 225, 245, 2, 29, 10, 214, 234, 22, 55, 56, 13, 2, 28, 34, 40, 24, 228, 233, 251, 253, 37, 250, 182, 232, 30, 33, 245, 208, 223, 245, 231, 217, 220, 197, 216, 8, 234, 158, 176, 233, 228, 240, 246, 252, 40, 51, 23, 37, 82, 62, 43, 73, 90, 92, 101, 75, 32, 44, 50, 20, 12, 5, 239, 216, 208, 226, 230, 167, 151, 213, 223, 225, 233, 220, 234, 10, 42, 34, 4, 37, 71, 36, 31, 49, 246, 226, 15, 248, 229, 238, 211, 238, 5, 225, 250, 249, 204, 238, 22, 12, 10, 20, 34, 43, 33, 45, 64, 46, 36, 60, 60, 32, 245, 230, 16, 29, 228, 223, 218, 162, 218, 0, 199, 217, 235, 226, 39, 30, 244, 34, 5, 242, 30, 25, 17, 12, 7, 20, 44, 22, 240, 243, 231, 210, 1, 19, 208, 221, 252, 238, 238, 204, 185, 246, 246, 221, 32, 35, 237, 3, 41, 40, 25, 10, 22, 70, 103, 70, 50, 74, 68, 49, 38, 12, 251, 22, 14, 238, 7, 220, 153, 181, 212, 215, 209, 171, 165, 225, 239, 204, 206, 224, 204, 248, 19, 241, 3, 255, 2, 49, 58, 12, 237, 19, 48, 25, 18, 19, 6, 15, 35, 37, 18, 220, 224, 42, 25, 238, 231, 243, 17, 12, 10, 44, 22, 18, 88, 50, 245, 18, 241, 197, 3, 22, 240, 243, 201, 184, 244, 238, 212, 227, 237, 14, 55, 32, 222, 248, 95, 72, 228, 196, 223, 255, 10, 6, 231, 253, 40, 4, 18, 47, 220, 226, 65, 61, 34, 33, 13, 18, 41, 23, 253, 242, 248, 5, 8, 251, 215, 197, 206, 196, 168, 164, 201, 206, 222, 26, 245, 186, 227, 4, 53, 90, 6, 219, 39, 43, 0, 10, 236, 205, 244, 7, 255, 3, 233, 217, 15, 36, 250, 234, 0, 0, 254, 24, 3, 236, 29, 71, 55, 37, 43, 0, 232, 9, 5, 243, 239, 236, 230, 243, 242, 232, 245, 247, 215, 190, 215, 222, 221, 253, 255, 240, 5, 23, 29, 61, 48, 3, 29, 31, 4, 28, 14, 8, 13, 241, 15, 33, 1, 246, 255, 7, 231, 214, 14, 22, 251, 251, 228, 251, 254, 215, 246, 21, 241, 233, 0, 254, 46, 59, 0, 7, 58, 49, 7, 246, 241, 8, 38, 241, 175, 184, 205, 232, 252, 193, 156, 206, 253, 5, 239, 207, 229, 12, 46, 70, 27, 20, 69, 76, 69, 60, 34, 65, 55, 255, 21, 0, 182, 205, 252, 254, 238, 207, 186, 212, 7, 238, 214, 221, 204, 244, 46, 40, 6, 243, 253, 39, 33, 242, 229, 232, 1, 0, 224, 2, 253, 217, 253, 13, 245, 254, 252, 251, 56, 28, 232, 3, 241, 245, 16, 17, 12, 252, 15, 31, 23, 26, 6, 238, 2, 15, 11, 48, 64, 39, 2, 46, 101, 19, 219, 14, 41, 7, 234, 200, 219, 244, 206, 222, 13, 4, 230, 234, 243, 3, 34, 30, 27, 35, 31, 59, 80, 56, 49, 51, 26, 9, 3, 7, 242, 196, 216, 1, 210, 193, 193, 161, 224, 5, 177, 158, 221, 243, 1, 246, 215, 9, 46, 16, 33, 51, 35, 55, 36, 255, 22, 20, 216, 182, 213, 220, 208, 214, 214, 202, 218, 252, 1, 253, 254, 252, 21, 38, 254, 15, 66, 43, 62, 105, 73, 65, 77, 58, 49, 40, 241, 232, 34, 239, 180, 237, 234, 189, 234, 254, 226, 242, 254, 5, 53, 61, 3, 3, 62, 61, 37, 11, 249, 0, 10, 240, 197, 221, 243, 204, 224, 30, 226, 211, 35, 251, 234, 10, 242, 37, 49, 204, 13, 85, 4, 7, 45, 250, 238, 9, 244, 247, 9, 6, 32, 42, 1, 238, 252, 252, 248, 25, 5, 182, 212, 49, 41, 239, 235, 239, 4, 29, 225, 199, 227, 189, 208, 7, 219, 214, 11, 241, 217, 3, 49, 38, 16, 21, 55, 97, 48, 2, 43, 26, 198, 221, 4, 198, 203, 235, 195, 231, 237, 180, 238, 34, 5, 10, 21, 53, 108, 80, 46, 52, 46, 46, 35, 17, 13, 242, 230, 251, 206, 155, 190, 214, 187, 208, 217, 195, 11, 17, 231, 33, 40, 5, 26, 21, 24, 43, 238, 229, 22, 14, 238, 200, 239, 34, 34, 34, 251, 205, 234, 56, 35, 231, 19, 53, 37, 33, 251, 244, 51, 26, 230, 3, 233, 209, 1, 247, 231, 0, 216, 167, 218, 228, 191, 221, 231, 219, 14, 5, 219, 26, 29, 250, 44, 61, 19, 252, 8, 33, 62, 46, 0, 246, 9, 22, 5, 242, 236, 231, 228, 243, 227, 219, 6, 11, 30, 62, 17, 40, 106, 70, 93, 104, 14, 17, 55, 30, 242, 196, 183, 221, 233, 176, 136, 156, 192, 179, 183, 184, 158, 189, 227, 245, 244, 251, 22, 56, 66, 39, 2, 6, 28, 248, 237, 255, 248, 231, 209, 220, 222, 236, 15, 7, 8, 16, 6, 33, 47, 34, 53, 59, 40, 42, 42, 47, 39, 0, 7, 2, 220, 207, 178, 154, 195, 216, 179, 178, 193, 215, 26, 10, 235, 58, 67, 16, 71, 93, 29, 9, 24, 48, 54, 11, 245, 23, 33, 1, 216, 223, 25, 37, 66, 67, 248, 226, 13, 28, 16, 9, 225, 227, 7, 225, 229, 3, 220, 229, 0, 251, 37, 14, 225, 19, 21, 230, 226, 242, 7, 16, 254, 5, 14, 242, 244, 19, 26, 13, 252, 10, 14, 6, 25, 6, 232, 255, 18, 244, 233, 17, 31, 6, 255, 22, 27, 241, 203, 229, 8, 251, 226, 238, 6, 241, 239, 9, 228, 249, 61, 9, 226, 33, 30, 1, 42, 6, 242, 44, 15, 251, 34, 255, 250, 27, 245, 227, 9, 33, 17, 28, 9, 199, 215, 15, 243, 205, 208, 190, 211, 8, 248, 207, 240, 252, 226, 7, 8, 237, 50, 74, 47, 87, 54, 10, 65, 46, 253, 239, 243, 0, 250, 0, 230, 225, 238, 220, 254, 22, 200, 204, 22, 243, 1, 34, 232, 231, 40, 38, 251, 17, 8, 2, 79, 45, 224, 28, 56, 17, 32, 245, 187, 244, 42, 0, 219, 239, 242, 233, 242, 220, 205, 244, 236, 215, 255, 0, 237, 12, 37, 46, 55, 53, 58, 55, 27, 21, 30, 30, 36, 19, 248, 249, 235, 231, 253, 207, 161, 208, 242, 221, 210, 236, 12, 9, 227, 216, 7, 6, 243, 249, 251, 6, 18, 47, 46, 17, 30, 21, 6, 71, 96, 46, 50, 35, 1, 16, 231, 200, 239, 252, 252, 3, 225, 184, 180, 190, 211, 232, 225, 221, 1, 22, 29, 22, 255, 28, 46, 33, 59, 48, 19, 36, 17, 244, 254, 237, 236, 248, 240, 247, 228, 212, 189, 164, 178, 222, 6, 0, 254, 19, 46, 67, 55, 4, 251, 38, 46, 44, 58, 40, 19, 12, 2, 10, 14, 234, 214, 243, 228, 180, 173, 186, 210, 243, 221, 192, 232, 248, 246, 13, 0, 225, 9, 59, 45, 35, 29, 18, 24, 32, 26, 30, 54, 42, 2, 11, 23, 4, 1, 10, 246, 218, 249, 240, 198, 217, 235, 244, 250, 234, 231, 3, 20, 10, 24, 35, 7, 0, 24, 245, 215, 228, 228, 223, 209, 219, 220, 206, 211, 225, 215, 192, 215, 245, 248, 9, 27, 17, 30, 64, 53, 52, 74, 80, 94, 86, 51, 41, 27, 241, 221, 245, 233, 221, 10, 2, 225, 244, 234, 216, 1, 254, 211, 10, 62, 12, 237, 253, 254, 12, 44, 15, 249, 27, 9, 241, 247, 213, 193, 230, 242, 214, 216, 2, 31, 22, 7, 237, 242, 37, 51, 29, 27, 27, 9, 32, 18, 205, 215, 254, 253, 3, 247, 238, 1, 8, 1, 242, 215, 227, 16, 15, 3, 251, 250, 15, 246, 245, 18, 3, 12, 35, 241, 208, 254, 249, 223, 227, 214, 223, 252, 4, 6, 10, 251, 247, 25, 28, 253, 10, 35, 21, 22, 40, 8, 247, 16, 19, 4, 5, 237, 218, 7, 6, 208, 215, 230, 231, 1, 248, 228, 253, 254, 231, 0, 11, 244, 3, 40, 25, 7, 21, 4, 0, 23, 1, 0, 16, 7, 25, 13, 241, 253, 245, 217, 220, 232, 253, 12, 252, 237, 19, 52, 19, 18, 41, 18, 37, 64, 22, 4, 1, 243, 3, 23, 17, 3, 6, 15, 0, 9, 13, 223, 252, 31, 5, 17, 26, 245, 248, 16, 7, 20, 40, 3, 237, 31, 25, 232, 223, 199, 210, 243, 210, 204, 238, 229, 232, 245, 246, 244, 251, 19, 42, 69, 72, 16, 243, 24, 45, 15, 237, 228, 233, 246, 240, 214, 227, 254, 247, 244, 235, 224, 250, 18, 13, 254, 233, 243, 2, 16, 44, 19, 11, 44, 53, 37, 15, 17, 22, 19, 34, 27, 249, 251, 16, 24, 255, 231, 249, 253, 3, 255, 223, 245, 14, 249, 214, 222, 247, 248, 2, 251, 236, 233, 227, 238, 17, 18, 238, 248, 4, 11, 36, 15, 234, 16, 56, 40, 45, 28, 1, 33, 18, 227, 233, 244, 242, 4, 8, 251, 254, 250, 248, 7, 11, 10, 14, 5, 5, 22, 26, 5, 255, 249, 229, 231, 255, 243, 212, 234, 243, 198, 216, 1, 243, 236, 247, 247, 250, 238, 238, 25, 33, 23, 28, 47, 52, 47, 72, 45, 249, 247, 6, 14, 14, 8, 241, 237, 247, 251, 243, 221, 210, 226, 14, 12, 232, 239, 4, 12, 8, 244, 225, 246, 6, 246, 242, 242, 240, 246, 243, 213, 224, 16, 255, 248, 6, 247, 8, 31, 10, 16, 38, 29, 42, 50, 39, 37, 23, 9, 249, 1, 28, 2, 243, 237, 208, 223, 241, 228, 230, 228, 217, 235, 236, 218, 239, 254, 223, 229, 12, 9, 13, 29, 27, 40, 40, 44, 48, 13, 239, 245, 18, 27, 253, 222, 226, 242, 231, 221, 211, 200, 228, 237, 211, 205, 213, 241, 22, 35, 36, 34, 46, 61, 57, 52, 35, 30, 48, 39, 25, 19, 239, 222, 238, 235, 203, 189, 192, 187, 204, 228, 210, 205, 234, 0, 27, 25, 5, 24, 34, 25, 32, 27, 17, 32, 50, 35, 9, 14, 13, 249, 245, 244, 248, 8, 245, 227, 246, 239, 229, 252, 238, 206, 229, 248, 244, 9, 12, 255, 15, 24, 14, 22, 29, 5, 12, 35, 12, 9, 10, 236, 234, 250, 225, 201, 213, 204, 186, 203, 220, 220, 240, 242, 238, 252, 4, 18, 26, 18, 17, 52, 63, 37, 38, 67, 58, 23, 30, 15, 239, 252, 255, 237, 224, 204, 215, 241, 213, 199, 221, 222, 223, 254, 8, 248, 22, 52, 49, 61, 56, 49, 73, 76, 60, 77, 52, 15, 34, 29, 15, 13, 232, 209, 229, 219, 184, 189, 219, 208, 192, 223, 243, 243, 5, 11, 5, 22, 27, 34, 71, 63, 33, 60, 63, 20, 18, 23, 255, 0, 8, 244, 245, 5, 237, 215, 222, 208, 213, 220, 177, 174, 219, 222, 218, 235, 219, 239, 38, 47, 45, 50, 23, 17, 61, 46, 3, 6, 245, 244, 8, 224, 186, 203, 206, 208, 219, 188, 188, 241, 9, 15, 15, 7, 7, 40, 73, 66, 67, 70, 53, 77, 90, 38, 19, 28, 253, 0, 19, 230, 207, 237, 241, 231, 221, 191, 207, 1, 1, 245, 255, 250, 7, 41, 35, 35, 36, 27, 57, 80, 51, 20, 19, 26, 33, 8, 219, 229, 7, 253, 236, 216, 194, 213, 231, 215, 218, 239, 234, 247, 6, 248, 252, 8, 7, 26, 44, 30, 26, 33, 36, 47, 57, 21, 240, 246, 247, 247, 249, 229, 208, 225, 237, 221, 220, 225, 230, 246, 11, 17, 20, 40, 35, 49, 80, 51, 34, 56, 40, 14, 28, 1, 215, 231, 230, 217, 211, 193, 201, 218, 203, 195, 220, 233, 232, 250, 3, 0, 7, 17, 17, 14, 10, 26, 49, 45, 34, 37, 41, 27, 9, 8, 16, 15, 2, 242, 233, 241, 244, 234, 230, 245, 251, 255, 21, 17, 0, 23, 45, 25, 7, 10, 21, 24, 23, 19, 4, 253, 0, 249, 227, 218, 225, 234, 225, 219, 218, 194, 201, 224, 223, 230, 233, 222, 242, 12, 251, 245, 10, 8, 16, 31, 8, 5, 45, 34, 252, 13, 10, 240, 247, 251, 244, 244, 247, 245, 0, 1, 240, 5, 27, 8, 16, 38, 20, 20, 22, 248, 252, 19, 9, 5, 6, 231, 221, 236, 226, 214, 221, 221, 223, 242, 241, 231, 243, 245, 242, 7, 19, 1, 0, 8, 252, 15, 34, 7, 15, 30, 14, 28, 35, 3, 7, 23, 1, 8, 28, 2, 251, 8, 242, 248, 15, 239, 229, 255, 239, 238, 11, 1, 253, 13, 8, 6, 6, 234, 223, 251, 253, 236, 250, 0, 249, 254, 248, 241, 249, 242, 247, 12, 0, 250, 14, 14, 8, 10, 17, 28, 39, 22, 0, 14, 21, 1, 3, 11, 251, 255, 5, 249, 1, 5, 238, 241, 1, 237, 228, 238, 244, 7, 254, 229, 243, 5, 5, 249, 254, 14, 23, 28, 21, 8, 252, 251, 4, 2, 247, 244, 248, 250, 251, 242, 238, 250, 3, 2, 253, 252, 248, 255, 24, 13, 247, 254, 7, 13, 6, 246, 248, 255, 255, 247, 238, 245, 249, 253, 0, 249, 254, 6, 2, 3, 5, 1, 4, 0, 0, 185, 0, 4, 0, 1, 0, 250, 0, 176, 2, 40, 4, 246, 10, 188, 12, 92, 14, 87, 27, 45, 46, 22, 50, 61, 38, 34, 31, 9, 5, 167, 157, 147, 120, 120, 120, 167, 152, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 250, 0, 176, 2, 40, 4, 246, 10, 188, 12, 92, 14, 87, 27, 60, 88, 31, 70, 84, 52, 47, 43, 12, 7, 167, 157, 147, 120, 120, 120, 167, 152, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 250, 0, 176, 2, 40, 4, 246, 10, 188, 12, 92, 14, 87, 27, 80, 79, 29, 66, 79, 49, 45, 41, 11, 7, 167, 157, 147, 120, 120, 120, 167, 152, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 250, 0, 160, 2, 76, 4, 246, 10, 188, 12, 92, 14, 87, 27, 0, 42, 22, 50, 60, 37, 34, 31, 8, 5, 167, 159, 147, 120, 120, 120, 167, 155, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 200, 0, 4, 0, 1, 0, 191, 0, 196, 1, 88, 7, 216, 9, 248, 12, 123, 14, 185, 27, 50, 42, 27, 55, 55, 57, 48, 34, 11, 7, 178, 107, 129, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 191, 0, 196, 1, 88, 7, 216, 9, 248, 12, 123, 14, 185, 27, 80, 80, 37, 76, 76, 79, 65, 47, 16, 10, 178, 107, 129, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 191, 0, 196, 1, 88, 7, 216, 9, 248, 12, 123, 14, 185, 27, 70, 67, 34, 69, 70, 73, 60, 43, 15, 9, 178, 107, 129, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 191, 0, 196, 1, 88, 7, 216, 9, 248, 12, 123, 14, 185, 27, 0, 30, 23, 47, 47, 49, 40, 29, 10, 6, 178, 107, 129, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 170, 0, 4, 0, 1, 0, 200, 0, 80, 2, 44, 6, 176, 9, 52, 13, 7, 15, 8, 28, 50, 48, 31, 58, 68, 47, 38, 28, 12, 5, 221, 163, 157, 120, 120, 120, 150, 163, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 200, 0, 80, 2, 44, 6, 176, 9, 52, 13, 7, 15, 8, 28, 80, 83, 41, 76, 90, 62, 51, 38, 17, 7, 221, 163, 157, 120, 120, 120, 150, 163, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 200, 0, 80, 2, 44, 6, 156, 9, 52, 13, 7, 15, 8, 28, 40, 63, 36, 66, 78, 54, 44, 33, 14, 6, 221, 163, 157, 120, 120, 120, 150, 163, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 200, 0, 80, 2, 44, 6, 156, 9, 52, 13, 7, 15, 8, 28, 0, 33, 27, 50, 54, 40, 33, 24, 11, 4, 221, 163, 157, 120, 120, 120, 150, 163, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 160, 0, 4, 0, 1, 0, 172, 0, 64, 1, 207, 8, 214, 11, 112, 13, 134, 16, 42, 27, 50, 42, 7, 61, 51, 47, 51, 23, 15, 7, 182, 120, 133, 133, 142, 161, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 172, 0, 64, 1, 207, 8, 214, 11, 112, 13, 134, 16, 42, 27, 60, 54, 8, 69, 58, 53, 58, 26, 17, 8, 182, 120, 133, 133, 142, 161, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 172, 0, 64, 1, 207, 8, 214, 11, 112, 13, 134, 16, 42, 27, 50, 47, 14, 61, 47, 46, 49, 20, 15, 7, 182, 120, 133, 133, 142, 161, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 172, 0, 64, 1, 207, 8, 214, 11, 112, 13, 134, 16, 42, 27, 0, 34, 12, 53, 41, 40, 42, 17, 13, 6, 182, 120, 133, 133, 142, 161, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 195, 0, 4, 0, 33, 0, 152, 0, 8, 1, 36, 9, 64, 11, 132, 13, 100, 15, 160, 26, 50, 43, 8, 65, 53, 53, 53, 28, 13, 6, 167, 105, 120, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 152, 0, 8, 1, 36, 9, 64, 11, 132, 13, 100, 15, 160, 26, 75, 66, 10, 80, 65, 65, 65, 35, 16, 8, 167, 105, 120, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 152, 0, 8, 1, 36, 9, 84, 11, 132, 13, 100, 15, 160, 26, 70, 54, 9, 73, 59, 59, 59, 31, 15, 7, 167, 105, 120, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 118, 0, 240, 0, 35, 9, 44, 11, 72, 13, 60, 15, 112, 26, 0, 26, 7, 48, 42, 41, 42, 23, 10, 6, 171, 105, 112, 120, 120, 120, 175, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 195, 0, 4, 0, 1, 0, 120, 0, 80, 1, 160, 5, 156, 9, 228, 12, 100, 15, 90, 26, 45, 32, 25, 51, 51, 44, 38, 32, 17, 6, 168, 112, 148, 120, 120, 120, 107, 112, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 120, 0, 80, 1, 160, 5, 156, 9, 228, 12, 100, 15, 90, 26, 75, 46, 30, 60, 60, 53, 45, 38, 20, 8, 168, 112, 148, 120, 120, 120, 107, 112, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 120, 0, 80, 1, 160, 5, 156, 9, 228, 12, 100, 15, 90, 26, 75, 41, 28, 57, 57, 50, 43, 36, 19, 7, 168, 112, 148, 120, 120, 120, 107, 112, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 120, 0, 80, 1, 160, 5, 156, 9, 228, 12, 100, 15, 90, 26, 0, 32, 25, 51, 51, 44, 38, 32, 17, 6, 168, 112, 148, 120, 120, 120, 107, 112, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 120, 0, 4, 0, 1, 0, 176, 0, 64, 1, 52, 3, 56, 9, 12, 13, 60, 15, 144, 26, 50, 35, 6, 61, 36, 21, 21, 30, 12, 7, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 176, 0, 64, 1, 52, 3, 56, 9, 12, 13, 60, 15, 144, 26, 70, 59, 8, 80, 48, 28, 28, 40, 16, 10, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 176, 0, 64, 1, 52, 3, 56, 9, 12, 13, 60, 15, 144, 26, 50, 36, 6, 62, 37, 21, 21, 31, 12, 7, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 176, 0, 64, 1, 52, 3, 56, 9, 12, 13, 60, 15, 144, 26, 0, 23, 5, 50, 30, 17, 17, 25, 10, 6, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 175, 0, 4, 0, 1, 0, 172, 0, 40, 1, 228, 2, 96, 9, 12, 13, 60, 15, 144, 26, 45, 40, 3, 67, 48, 19, 25, 28, 9, 8, 177, 117, 100, 120, 120, 120, 177, 117, 115, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 172, 0, 40, 1, 228, 2, 96, 9, 12, 13, 60, 15, 144, 26, 70, 63, 4, 84, 60, 24, 32, 36, 12, 10, 177, 117, 100, 120, 120, 120, 177, 117, 115, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 172, 0, 40, 1, 228, 2, 96, 9, 12, 13, 60, 15, 144, 26, 60, 56, 3, 79, 57, 22, 30, 34, 11, 9, 177, 117, 100, 120, 120, 120, 177, 117, 115, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 172, 0, 40, 1, 228, 2, 96, 9, 12, 13, 60, 15, 144, 26, 0, 38, 3, 65, 46, 18, 24, 28, 9, 7, 177, 117, 100, 120, 120, 120, 177, 117, 115, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 125, 0, 4, 0, 1, 0, 176, 0, 104, 1, 92, 3, 56, 9, 108, 12, 60, 15, 144, 26, 45, 43, 6, 69, 44, 22, 25, 25, 12, 7, 177, 125, 110, 120, 120, 120, 177, 125, 125, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 176, 0, 104, 1, 92, 3, 56, 9, 108, 12, 60, 15, 144, 26, 80, 70, 8, 88, 56, 28, 32, 32, 16, 10, 177, 125, 110, 120, 120, 120, 177, 125, 125, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 176, 0, 104, 1, 92, 3, 56, 9, 108, 12, 60, 15, 144, 26, 70, 57, 7, 79, 50, 25, 28, 28, 14, 9, 177, 125, 110, 120, 120, 120, 177, 125, 125, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 176, 0, 104, 1, 92, 3, 56, 9, 108, 12, 60, 15, 144, 26, 0, 38, 5, 65, 41, 20, 23, 23, 11, 7, 177, 125, 110, 120, 120, 120, 177, 125, 125, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 165, 0, 4, 0, 1, 0, 180, 0, 192, 1, 196, 4, 212, 8, 148, 12, 226, 14, 144, 26, 45, 34, 24, 51, 51, 36, 36, 30, 15, 7, 170, 125, 145, 120, 120, 120, 162, 125, 145, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 180, 0, 192, 1, 196, 4, 212, 8, 148, 12, 226, 14, 144, 26, 70, 60, 32, 68, 68, 48, 48, 40, 20, 10, 170, 125, 145, 120, 120, 120, 162, 125, 145, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 180, 0, 192, 1, 196, 4, 212, 8, 148, 12, 226, 14, 144, 26, 50, 54, 30, 64, 64, 45, 45, 38, 19, 9, 170, 125, 145, 120, 120, 120, 162, 125, 145, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 180, 0, 192, 1, 196, 4, 212, 8, 148, 12, 226, 14, 144, 26, 0, 29, 22, 47, 47, 33, 33, 28, 14, 7, 170, 125, 145, 120, 120, 120, 162, 125, 145, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 175, 0, 4, 0, 1, 0, 116, 0, 208, 1, 116, 4, 80, 10, 48, 12, 196, 14, 96, 27, 45, 40, 23, 57, 57, 37, 34, 31, 16, 6, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 116, 0, 208, 1, 116, 4, 80, 10, 48, 12, 196, 14, 96, 27, 70, 79, 32, 80, 80, 52, 48, 44, 23, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 116, 0, 208, 1, 116, 4, 80, 10, 48, 12, 196, 14, 96, 27, 60, 64, 28, 72, 72, 46, 43, 39, 20, 7, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 116, 0, 208, 1, 116, 4, 80, 10, 48, 12, 196, 14, 96, 27, 0, 35, 21, 53, 53, 34, 32, 29, 15, 5, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 0, 0, 5, 0, 1, 0, 116, 0, 24, 2, 140, 5, 116, 9, 188, 12, 116, 14, 88, 27, 40, 44, 29, 57, 69, 39, 40, 31, 16, 6, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 116, 0, 24, 2, 140, 5, 116, 9, 188, 12, 116, 14, 88, 27, 66, 97, 43, 84, 102, 57, 60, 46, 24, 9, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 124, 0, 244, 1, 40, 6, 172, 9, 232, 12, 126, 14, 128, 27, 94, 50, 32, 60, 70, 44, 44, 33, 16, 6, 167, 138, 147, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 156, 0, 99, 1, 152, 8, 140, 10, 152, 13, 166, 14, 32, 28, 40, 40, 31, 54, 47, 57, 44, 32, 10, 8, 167, 90, 195, 120, 120, 120, 122, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 156, 0, 99, 1, 174, 8, 160, 10, 92, 13, 10, 15, 32, 28, 0, 34, 31, 49, 49, 45, 42, 33, 9, 8, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 175, 8, 35, 0, 10, 234, 191, 13, 42, 250, 10, 243, 236, 16, 5, 2, 0, 226, 210, 25, 80, 2, 180, 13, 43, 252, 13, 226, 242, 255, 251, 50, 248, 205, 34, 7, 237, 34, 235, 12, 251, 235, 63, 0, 246, 239, 1, 49, 228, 236, 20, 211, 14, 67, 204, 220, 28, 253, 0, 12, 231, 222, 16, 35, 16, 227, 216, 47, 50, 231, 255, 236, 0, 24, 232, 29, 26, 225, 208, 57, 84, 205, 220, 5, 40, 27, 220, 19, 14, 228, 26, 30, 250, 255, 4, 230, 244, 60, 7, 184, 230, 76, 37, 188, 252, 20, 235, 3, 42, 7, 221, 0, 3, 19, 45, 234, 227, 8, 26, 52, 220, 232, 34, 216, 6, 42, 7, 216, 192, 39, 57, 236, 222, 8, 10, 249, 20, 241, 0, 5, 230, 62, 23, 235, 213, 249, 95, 226, 213, 34, 6, 227, 223, 49, 34, 195, 248, 59, 236, 236, 38, 17, 231, 253, 23, 13, 246, 226, 28, 212, 4, 66, 199, 10, 250, 241, 56, 231, 224, 35, 251, 228, 20, 12, 6, 247, 236, 21, 32, 244, 228, 0, 11, 8, 0, 12, 18, 8, 233, 251, 29, 244, 242, 25, 1, 11, 6, 219, 58, 11, 193, 255, 38, 27, 178, 22, 25, 194, 42, 18, 221, 230, 9, 10, 244, 243, 2, 11, 254, 0, 229, 250, 255, 9, 28, 226, 226, 48, 40, 209, 12, 3, 249, 57, 193, 33, 63, 167, 62, 22, 229, 65, 179, 0, 103, 215, 191, 51, 39, 177, 3, 47, 245, 250, 220, 7, 44, 219, 233, 11, 206, 25, 8, 162, 49, 33, 179, 22, 33, 214, 242, 11, 245, 252, 32, 32, 212, 27, 80, 181, 225, 71, 249, 232, 70, 10, 204, 50, 239, 238, 42, 205, 227, 230, 23, 65, 165, 245, 78, 170, 245, 45, 176, 35, 35, 184, 81, 24, 182, 42, 242, 242, 39, 230, 231, 11, 12, 241, 5, 28, 251, 222, 20, 32, 212, 250, 35, 1, 231, 29, 32, 174, 253, 60, 222, 244, 14, 244, 0, 254, 8, 19, 245, 241, 242, 16, 18, 211, 1, 23, 252, 26, 244, 221, 14, 22, 225, 224, 17, 9, 242, 7, 21, 242, 250, 25, 252, 231, 30, 252, 213, 66, 20, 227, 254, 249, 40, 7, 207, 217, 55, 32, 209, 227, 249, 66, 210, 193, 91, 214, 188, 37, 8, 22, 240, 233, 17, 243, 21, 0, 231, 245, 12, 54, 228, 241, 27, 204, 246, 60, 233, 222, 3, 1, 41, 232, 238, 42, 249, 226, 11, 25, 221, 26, 14, 217, 48, 23, 206, 225, 54, 248, 185, 48, 28, 216, 251, 244, 12, 24, 230, 2, 10, 20, 251, 238, 26, 238, 34, 228, 186, 105, 1, 145, 33, 71, 221, 195, 32, 24, 191, 20, 31, 197, 10, 33, 7, 229, 16, 42, 179, 30, 95, 213, 240, 11, 29, 15, 204, 56, 251, 165, 80, 43, 199, 248, 12, 247, 29, 31, 178, 240, 36, 245, 25, 225, 248, 59, 225, 207, 3, 46, 214, 198, 65, 17, 245, 242, 6, 255, 249, 49, 196, 254, 67, 220, 5, 14, 243, 55, 247, 177, 64, 10, 184, 47, 0, 221, 53, 250, 216, 18, 245, 255, 243, 232, 41, 22, 225, 250, 38, 251, 241, 217, 38, 89, 154, 236, 108, 244, 195, 249, 47, 22, 229, 218, 19, 49, 191, 216, 81, 247, 231, 21, 220, 0, 46, 10, 236, 6, 242, 229, 30, 228, 230, 59, 233, 231, 31, 241, 10, 212, 246, 99, 224, 225, 37, 238, 24, 28, 226, 33, 21, 202, 6, 51, 3, 206, 17, 52, 224, 233, 245, 19, 12, 160, 46, 104, 168, 230, 252, 2, 53, 189, 11, 23, 218, 41, 249, 4, 14, 201, 13, 60, 21, 217, 226, 56, 11, 10, 42, 225, 209, 11, 69, 220, 201, 58, 19, 231, 241, 40, 20, 163, 230, 123, 17, 163, 16, 40, 237, 240, 27, 4, 208, 29, 28, 207, 19, 27, 199, 242, 84, 9, 163, 25, 25, 225, 43, 250, 11, 3, 194, 68, 52, 192, 11, 24, 246, 7, 224, 14, 17, 197, 35, 54, 213, 4, 13, 215, 253, 33, 31, 251, 226, 243, 75, 15, 142, 24, 38, 236, 255, 249, 69, 218, 187, 111, 26, 166, 243, 10, 251, 14, 12, 214, 9, 93, 204, 176, 66, 21, 191, 25, 68, 210, 218, 52, 12, 224, 28, 10, 237, 22, 252, 8, 250, 5, 36, 232, 247, 255, 21, 251, 201, 48, 31, 201, 234, 21, 32, 241, 212, 247, 48, 28, 200, 239, 20, 22, 18, 193, 2, 81, 200, 209, 120, 3, 144, 69, 52, 179, 12, 12, 254, 13, 199, 49, 56, 163, 255, 76, 243, 211, 247, 66, 38, 170, 242, 68, 43, 204, 184, 72, 32, 230, 224, 46, 86, 146, 218, 126, 12, 165, 0, 53, 223, 5, 42, 220, 230, 31, 254, 230, 19, 1, 230, 19, 5, 254, 0, 243, 15, 231, 21, 33, 207, 0, 251, 237, 29, 228, 234, 23, 226, 27, 32, 231, 1, 255, 42, 252, 203, 34, 48, 255, 252, 1, 26, 10, 214, 22, 17, 230, 221, 3, 65, 235, 214, 11, 15, 252, 246, 12, 248, 247, 17, 255, 253, 253, 255, 12, 220, 23, 15, 214, 26, 252, 24, 2, 226, 34, 223, 254, 39, 216, 248, 7, 8, 20, 231, 248, 8, 25, 246, 255, 42, 221, 247, 255, 21, 35, 201, 4, 17, 239, 24, 250, 20, 3, 217, 69, 243, 222, 28, 228, 48, 246, 220, 26, 239, 226, 228, 36, 27, 204, 228, 25, 14, 252, 0, 255, 7, 1, 255, 45, 232, 191, 66, 14, 202, 21, 29, 223, 240, 74, 252, 196, 24, 18, 229, 17, 26, 250, 251, 243, 44, 17, 197, 18, 55, 214, 237, 35, 249, 6, 246, 14, 253, 213, 62, 6, 172, 40, 65, 194, 232, 44, 1, 196, 234, 61, 233, 238, 43, 233, 248, 13, 0, 2, 247, 22, 250, 240, 45, 236, 231, 28, 5, 253, 240, 244, 15, 50, 249, 213, 74, 16, 197, 26, 1, 10, 233, 232, 75, 221, 7, 18, 204, 70, 227, 233, 64, 226, 238, 1, 7, 13, 245, 240, 7, 16, 209, 212, 23, 251, 251, 18, 222, 18, 19, 220, 10, 4, 18, 248, 253, 40, 238, 246, 33, 37, 239, 251, 23, 237, 14, 9, 233, 19, 44, 217, 6, 41, 189, 1, 4, 33, 255, 146, 74, 37, 174, 1, 16, 1, 246, 1, 19, 237, 233, 39, 253, 226, 32, 20, 225, 222, 82, 8, 145, 56, 61, 231, 236, 243, 56, 232, 229, 28, 246, 66, 236, 200, 49, 252, 246, 253, 236, 13, 33, 201, 189, 103, 8, 140, 31, 48, 234, 243, 10, 32, 9, 226, 22, 60, 210, 214, 47, 23, 237, 241, 47, 12, 216, 24, 35, 236, 232, 49, 10, 192, 20, 42, 226, 236, 41, 16, 192, 230, 46, 18, 208, 217, 53, 22, 185, 3, 61, 241, 238, 7, 9, 5, 223, 0, 245, 36, 54, 175, 11, 40, 232, 6, 241, 37, 249, 216, 80, 254, 197, 36, 16, 15, 247, 228, 9, 1, 25, 216, 235, 81, 233, 208, 52, 21, 224, 255, 47, 6, 214, 23, 14, 221, 244, 23, 21, 245, 250, 237, 245, 16, 12, 229, 235, 44, 243, 229, 58, 214, 192, 88, 238, 187, 34, 34, 0, 208, 69, 27, 181, 43, 238, 231, 30, 238, 18, 245, 1, 41, 217, 16, 254, 201, 74, 0, 191, 41, 12, 250, 2, 250, 33, 11, 242, 223, 18, 45, 210, 241, 31, 26, 209, 204, 41, 233, 241, 26, 219, 14, 40, 205, 240, 45, 12, 224, 237, 54, 9, 210, 223, 48, 47, 170, 253, 56, 255, 5, 223, 248, 54, 6, 214, 4, 31, 0, 224, 245, 44, 241, 231, 37, 0, 1, 247, 240, 23, 5, 237, 3, 19, 215, 4, 6, 217, 42, 253, 219, 8, 39, 249, 198, 48, 41, 204, 18, 48, 211, 249, 22, 4, 245, 229, 78, 0, 176, 31, 53, 9, 200, 241, 64, 238, 210, 60, 26, 210, 21, 32, 241, 245, 19, 235, 241, 62, 209, 189, 50, 252, 231, 244, 246, 29, 245, 252, 16, 2, 2, 254, 10, 249, 30, 252, 214, 43, 0, 2, 18, 229, 1, 23, 26, 7, 230, 8, 60, 179, 231, 92, 189, 244, 7, 235, 61, 232, 215, 42, 19, 205, 4, 49, 221, 224, 59, 10, 217, 9, 243, 7, 3, 233, 3, 12, 9, 234, 8, 0, 12, 22, 190, 29, 37, 189, 31, 10, 233, 60, 237, 227, 24, 232, 23, 3, 223, 32, 252, 28, 7, 221, 61, 9, 241, 244, 37, 43, 159, 9, 73, 236, 205, 254, 50, 220, 220, 37, 249, 217, 11, 41, 238, 220, 41, 254, 253, 25, 212, 35, 246, 219, 57, 245, 238, 254, 0, 3, 25, 251, 203, 48, 15, 211, 19, 45, 255, 217, 21, 32, 246, 17, 10, 230, 40, 12, 218, 20, 0, 49, 6, 216, 36, 191, 0, 40, 182, 7, 7, 255, 18, 229, 6, 9, 230, 243, 58, 4, 146, 38, 73, 196, 244, 23, 242, 224, 28, 21, 213, 11, 13, 3, 10, 246, 16, 10, 247, 6, 37, 29, 233, 2, 28, 237, 0, 29, 1, 206, 8, 62, 211, 246, 18, 204, 249, 19, 12, 0, 220, 0, 24, 246, 9, 246, 226, 248, 23, 24, 220, 11, 7, 248, 33, 227, 235, 244, 223, 33, 42, 236, 197, 4, 78, 6, 230, 248, 247, 22, 39, 254, 217, 28, 33, 248, 0, 8, 6, 225, 244, 77, 40, 147, 12, 57, 205, 41, 3, 248, 228, 215, 78, 253, 211, 236, 0, 38, 219, 5, 36, 164, 240, 83, 228, 187, 236, 44, 30, 205, 43, 37, 182, 36, 46, 227, 255, 25, 250, 218, 66, 29, 173, 250, 73, 11, 213, 246, 23, 43, 196, 5, 63, 186, 7, 250, 247, 40, 213, 255, 6, 232, 53, 2, 174, 16, 35, 229, 218, 15, 15, 202, 32, 30, 240, 6, 247, 17, 249, 18, 14, 205, 23, 21, 253, 15, 252, 24, 4, 229, 245, 28, 6, 200, 23, 21, 249, 16, 219, 14, 43, 230, 239, 5, 234, 12, 33, 249, 234, 249, 51, 224, 203, 56, 231, 231, 46, 235, 211, 30, 21, 212, 10, 22, 0, 246, 216, 39, 17, 206, 53, 13, 214, 61, 246, 217, 21, 247, 9, 253, 4, 26, 242, 218, 41, 61, 167, 248, 68, 190, 222, 43, 243, 206, 34, 51, 220, 222, 24, 30, 239, 223, 39, 9, 217, 44, 0, 240, 32, 15, 240, 217, 47, 246, 199, 33, 253, 16, 12, 244, 26, 235, 9, 11, 212, 7, 235, 0, 50, 1, 231, 3, 66, 212, 191, 29, 253, 11, 252, 8, 20, 248, 35, 5, 203, 6, 36, 211, 251, 59, 248, 243, 34, 1, 13, 12, 212, 54, 5, 190, 69, 248, 229, 53, 218, 3, 33, 200, 0, 15, 203, 1, 31, 220, 245, 70, 230, 193, 72, 8, 233, 23, 206, 6, 45, 210, 219, 63, 44, 226, 246, 0, 48, 16, 203, 39, 6, 235, 47, 221, 254, 59, 203, 0, 53, 222, 255, 4, 244, 44, 2, 225, 19, 1, 249, 23, 219, 222, 27, 242, 245, 2, 8, 28, 237, 235, 247, 23, 248, 167, 52, 74, 177, 252, 65, 244, 248, 0, 1, 29, 234, 241, 27, 16, 28, 247, 245, 59, 243, 227, 29, 214, 13, 36, 223, 24, 0, 227, 14, 255, 252, 255, 242, 254, 1, 8, 16, 232, 12, 40, 223, 5, 10, 230, 14, 229, 10, 43, 222, 243, 254, 3, 2, 243, 7, 242, 27, 248, 217, 46, 7, 23, 11, 213, 28, 33, 237, 237, 38, 14, 242, 24, 246, 232, 21, 242, 226, 51, 1, 198, 248, 41, 1, 206, 14, 28, 249, 207, 240, 57, 242, 204, 55, 31, 201, 24, 248, 245, 45, 233, 225, 21, 28, 215, 0, 21, 243, 9, 228, 13, 38, 240, 3, 8, 13, 34, 246, 9, 22, 225, 11, 43, 208, 222, 70, 255, 201, 0, 43, 226, 209, 53, 228, 226, 34, 250, 239, 241, 14, 9, 239, 237, 253, 36, 2, 242, 24, 253, 31, 14, 248, 18, 244, 29, 234, 239, 32, 15, 0, 200, 10, 47, 215, 205, 51, 251, 204, 27, 1, 254, 18, 21, 235, 8, 29, 212, 252, 16, 2, 18, 239, 250, 41, 227, 238, 43, 241, 241, 31, 247, 212, 48, 11, 173, 25, 61, 213, 209, 5, 31, 15, 214, 13, 40, 242, 249, 10, 14, 237, 252, 20, 4, 255, 236, 32, 10, 208, 51, 14, 219, 28, 223, 231, 64, 250, 209, 49, 5, 234, 26, 247, 2, 4, 248, 19, 19, 216, 247, 19, 219, 0, 18, 2, 238, 0, 8, 243, 18, 6, 229, 242, 24, 245, 223, 9, 19, 8, 243, 8, 30, 237, 228, 36, 17, 230, 9, 17, 250, 255, 242, 5, 11, 219, 23, 21, 202, 255, 46, 10, 231, 242, 46, 248, 163, 62, 48, 167, 245, 52, 32, 201, 237, 61, 232, 223, 31, 246, 254, 244, 216, 57, 0, 236, 28, 211, 2, 34, 226, 241, 12, 10, 12, 249, 10, 10, 227, 11, 25, 7, 7, 218, 18, 60, 200, 252, 59, 214, 1, 47, 229, 237, 4, 0, 58, 0, 3, 0, 5, 0, 116, 0, 232, 0, 52, 8, 140, 10, 16, 14, 104, 16, 124, 21, 58, 14, 25, 15, 10, 10, 10, 10, 5, 5, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 116, 0, 232, 0, 52, 8, 140, 10, 16, 14, 104, 16, 124, 21, 0, 14, 25, 15, 10, 10, 10, 10, 5, 5, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 116, 0, 232, 0, 52, 8, 140, 10, 16, 14, 104, 16, 124, 21, 0, 14, 25, 15, 10, 5, 5, 5, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 14, 4, 30, 0, 1, 1, 1, 248, 1, 254, 243, 4, 9, 5, 0, 4, 5, 15, 15, 16, 12, 15, 146, 182, 22, 55, 66, 236, 245, 250, 3, 18, 227, 255, 36, 231, 7, 17, 254, 15, 253, 241, 243, 232, 4, 21, 231, 9, 10, 252, 15, 8, 14, 0, 247, 7, 242, 253, 24, 226, 220, 17, 39, 31, 248, 243, 232, 226, 250, 21, 15, 13, 249, 7, 13, 6, 23, 216, 228, 252, 24, 10, 5, 33, 223, 222, 250, 32, 253, 10, 17, 211, 15, 252, 2, 252, 20, 3, 20, 19, 28, 181, 196, 10, 7, 68, 6, 9, 233, 236, 231, 40, 253, 237, 14, 231, 50, 247, 17, 234, 225, 38, 20, 2, 254, 255, 222, 192, 243, 67, 47, 34, 247, 192, 0, 43, 230, 239, 16, 228, 27, 254, 23, 18, 218, 27, 3, 210, 242, 36, 253, 9, 214, 15, 54, 14, 3, 222, 246, 242, 248, 230, 61, 42, 154, 13, 31, 70, 2, 162, 18, 32, 216, 232, 49, 34, 205, 236, 87, 1, 223, 225, 225, 60, 14, 181, 215, 96, 71, 194, 225, 15, 97, 161, 199, 65, 4, 0, 216, 11, 84, 182, 14, 0, 220, 44, 248, 2, 245, 204, 48, 78, 208, 253, 22, 224, 14, 12, 241, 229, 210, 34, 16, 40, 17, 243, 241, 217, 15, 5, 24, 252, 215, 33, 40, 237, 216, 31, 29, 222, 193, 47, 39, 227, 238, 242, 61, 43, 163, 236, 41, 71, 238, 208, 225, 255, 36, 5, 226, 37, 41, 245, 219, 250, 9, 227, 237, 44, 66, 230, 166, 247, 60, 39, 49, 178, 175, 58, 50, 17, 242, 178, 221, 96, 49, 2, 232, 206, 219, 3, 238, 22, 54, 53, 18, 173, 250, 25, 252, 249, 208, 246, 80, 13, 242, 5, 238, 219, 36, 226, 255, 37, 254, 36, 198, 2, 48, 11, 228, 193, 252, 53, 35, 12, 222, 205, 44, 49, 224, 210, 42, 253, 225, 18, 235, 17, 69, 239, 211, 9, 0, 15, 180, 237, 114, 26, 219, 255, 0, 8, 239, 211, 235, 62, 5, 14, 225, 238, 9, 20, 44, 11, 217, 218, 242, 18, 49, 5, 245, 203, 229, 53, 23, 249, 50, 221, 215, 224, 249, 60, 37, 231, 50, 7, 149, 236, 55, 45, 218, 235, 245, 255, 44, 37, 252, 202, 34, 232, 233, 23, 41, 252, 191, 225, 36, 79, 3, 243, 231, 240, 23, 210, 184, 54, 82, 14, 18, 244, 244, 214, 234, 31, 215, 246, 24, 18, 45, 7, 237, 242, 235, 249, 33, 53, 23, 164, 133, 22, 96, 96, 9, 166, 0, 39, 1, 214, 184, 253, 73, 18, 0, 33, 21, 249, 182, 218, 33, 43, 12, 217, 234, 14, 23, 69, 236, 178, 250, 51, 237, 232, 30, 229, 11, 50, 13, 237, 253, 245, 179, 1, 9, 51, 73, 15, 209, 246, 248, 243, 206, 0, 255, 16, 38, 28, 249, 240, 29, 15, 246, 204, 228, 243, 36, 75, 232, 209, 243, 24, 38, 243, 3, 255, 204, 241, 57, 55, 222, 195, 13, 38, 1, 13, 26, 208, 214, 237, 251, 55, 25, 24, 8, 237, 6, 214, 190, 50, 3, 21, 30, 223, 17, 29, 252, 223, 221, 244, 19, 9, 3, 11, 10, 63, 240, 223, 255, 242, 238, 204, 240, 50, 68, 56, 1, 165, 230, 20, 19, 11, 209, 1, 40, 198, 17, 57, 25, 37, 251, 158, 201, 76, 27, 203, 213, 0, 66, 28, 23, 2, 0, 247, 217, 250, 229, 9, 31, 217, 19, 64, 246, 242, 235, 250, 20, 214, 255, 40, 237, 3, 249, 6, 87, 0, 196, 247, 244, 237, 241, 252, 56, 37, 224, 250, 245, 3, 15, 4, 15, 214, 2, 19, 247, 250, 54, 236, 192, 3, 29, 68, 233, 227, 37, 197, 238, 5, 238, 39, 74, 25, 217, 222, 232, 208, 234, 67, 77, 249, 209, 22, 41, 218, 206, 222, 244, 17, 92, 50, 201, 231, 14, 229, 214, 28, 47, 35, 0, 185, 210, 30, 52, 229, 244, 41, 55, 10, 164, 232, 4, 198, 240, 78, 104, 52, 235, 165, 170, 1, 43, 26, 13, 20, 3, 252, 209, 228, 12, 26, 24, 25, 238, 225, 14, 5, 238, 11, 12, 253, 7, 9, 245, 241, 252, 233, 2, 38, 0, 14, 4, 24, 227, 210, 250, 9, 20, 17, 29, 20, 235, 233, 201, 230, 32, 44, 0, 26, 54, 230, 164, 209, 36, 42, 25, 239, 20, 29, 250, 236, 202, 236, 12, 39, 16, 15, 244, 19, 222, 197, 43, 239, 46, 43, 253, 236, 222, 212, 7, 35, 251, 39, 4, 20, 224, 224, 241, 250, 14, 5, 37, 61, 242, 196, 17, 202, 238, 13, 15, 50, 38, 252, 218, 225, 234, 8, 254, 50, 35, 227, 250, 226, 6, 252, 15, 22, 237, 234, 37, 251, 236, 249, 20, 18, 240, 22, 246, 248, 0, 0, 239, 243, 17, 13, 25, 253, 253, 236, 241, 45, 244, 222, 248, 15, 22, 25, 255, 241, 249, 237, 252, 23, 21, 238, 242, 2, 6, 240, 7, 23, 25, 34, 233, 223, 194, 201, 45, 76, 40, 252, 250, 234, 245, 250, 236, 225, 40, 35, 253, 16, 9, 233, 238, 207, 235, 42, 37, 59, 15, 239, 240, 178, 191, 9, 61, 81, 46, 213, 222, 233, 240, 1, 238, 10, 16, 27, 44, 10, 215, 212, 240, 33, 7, 6, 2, 27, 253, 214, 217, 229, 55, 63, 29, 14, 231, 204, 201, 240, 17, 41, 26, 27, 34, 237, 182, 211, 23, 53, 21, 13, 0, 221, 230, 244, 255, 2, 27, 17, 14, 21, 246, 249, 227, 218, 5, 20, 30, 36, 3, 229, 218, 224, 0, 24, 32, 50, 243, 214, 1, 250, 240, 254, 7, 27, 42, 14, 228, 206, 238, 0, 1, 21, 38, 8, 242, 227, 253, 20, 0, 6, 12, 241, 244, 23, 2, 243, 14, 245, 242, 243, 9, 22, 6, 6, 230, 233, 33, 11, 244, 24, 20, 234, 230, 241, 22, 5, 239, 9, 6, 37, 11, 212, 223, 251, 10, 245, 11, 63, 43, 223, 214, 240, 3, 39, 248, 231, 241, 1, 0, 1, 32, 29, 10, 232, 220, 252, 0, 0, 125, 0, 2, 0, 17, 0, 158, 0, 220, 1, 180, 5, 166, 9, 103, 12, 96, 14, 162, 26, 125, 21, 25, 43, 26, 25, 25, 22, 6, 6, 153, 115, 128, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 17, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 60, 0, 2, 0, 1, 0, 252, 0, 90, 2, 230, 5, 20, 10, 169, 12, 184, 14, 96, 28, 60, 13, 27, 28, 29, 28, 20, 22, 8, 3, 193, 136, 140, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 17, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 65, 0, 2, 0, 17, 0, 220, 0, 110, 2, 56, 4, 180, 10, 13, 12, 66, 14, 248, 27, 65, 11, 23, 26, 26, 16, 20, 16, 5, 3, 164, 157, 128, 120, 120, 120, 105, 185, 148, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 17, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 95, 0, 3, 0, 5, 0, 63, 1, 182, 2, 80, 5, 64, 10, 139, 13, 33, 15, 96, 28, 80, 45, 45, 48, 68, 35, 38, 25, 11, 5, 221, 135, 155, 120, 120, 120, 150, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 37, 0, 205, 0, 164, 2, 200, 4, 44, 10, 41, 12, 125, 14, 244, 27, 15, 17, 37, 31, 23, 20, 18, 13, 4, 0, 154, 139, 127, 120, 120, 120, 150, 180, 150, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 37, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 95, 0, 3, 0, 5, 0, 184, 0, 136, 1, 188, 2, 160, 10, 88, 12, 176, 14, 159, 27, 80, 46, 31, 46, 57, 25, 36, 20, 10, 5, 177, 100, 131, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 37, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 15, 11, 34, 27, 13, 17, 13, 10, 3, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 37, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 18, 40, 32, 16, 20, 16, 12, 4, 0, 142, 140, 122, 120, 120, 120, 172, 110, 152, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 90, 0, 2, 0, 17, 0, 150, 0, 60, 2, 41, 5, 166, 9, 83, 12, 106, 14, 160, 27, 90, 13, 28, 26, 29, 22, 17, 19, 9, 4, 155, 145, 128, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 17, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 65, 0, 2, 0, 17, 0, 236, 0, 226, 2, 236, 4, 90, 10, 173, 12, 144, 14, 0, 28, 65, 16, 26, 32, 28, 23, 16, 16, 7, 3, 180, 147, 113, 120, 120, 120, 247, 170, 165, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 17, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 70, 0, 2, 0, 1, 0, 172, 0, 68, 2, 59, 6, 10, 10, 123, 12, 99, 14, 48, 28, 70, 32, 35, 50, 44, 46, 36, 26, 9, 4, 163, 126, 125, 120, 120, 120, 185, 117, 127, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 17, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 50, 0, 2, 0, 17, 0, 178, 0, 214, 1, 192, 6, 255, 10, 173, 12, 115, 15, 133, 27, 50, 21, 18, 40, 33, 35, 33, 17, 10, 4, 162, 130, 127, 126, 131, 140, 187, 125, 137, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 17, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 40, 0, 2, 0, 17, 0, 172, 0, 70, 2, 26, 4, 0, 10, 199, 11, 119, 14, 128, 27, 40, 25, 29, 40, 46, 33, 28, 15, 10, 3, 153, 137, 136, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 17, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 50, 0, 2, 0, 17, 0, 180, 0, 214, 1, 242, 3, 176, 9, 123, 12, 206, 14, 56, 27, 50, 14, 14, 37, 23, 18, 15, 19, 7, 3, 160, 132, 112, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 17, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 74, 0, 2, 0, 37, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 75, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 64, 1, 72, 2, 28, 7, 0, 10, 104, 13, 15, 15, 224, 28, 0, 34, 26, 48, 51, 47, 36, 27, 9, 5, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 74, 0, 2, 0, 37, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 75, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 128, 0, 40, 2, 161, 5, 96, 9, 188, 12, 116, 14, 96, 27, 0, 36, 28, 51, 63, 35, 32, 28, 14, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 75, 0, 2, 0, 37, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 75, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 0, 1, 112, 2, 192, 3, 64, 11, 48, 12, 36, 14, 15, 28, 0, 42, 25, 48, 48, 20, 40, 23, 6, 5, 186, 175, 135, 120, 120, 120, 105, 185, 148, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 75, 0, 2, 0, 37, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 75, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 63, 1, 182, 2, 80, 5, 64, 10, 139, 13, 33, 15, 96, 28, 0, 45, 45, 48, 68, 35, 38, 25, 11, 5, 221, 135, 155, 120, 120, 120, 150, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 74, 0, 2, 0, 37, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 75, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 132, 0, 24, 1, 184, 6, 36, 9, 228, 12, 96, 14, 100, 25, 0, 67, 24, 76, 51, 44, 48, 44, 12, 16, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 74, 0, 2, 0, 37, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 75, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 192, 0, 179, 1, 92, 3, 252, 8, 184, 11, 60, 15, 32, 28, 0, 43, 19, 81, 28, 14, 11, 8, 7, 0, 120, 82, 90, 120, 120, 120, 75, 82, 90, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 75, 0, 2, 0, 37, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 75, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 184, 0, 136, 1, 188, 2, 160, 10, 88, 12, 176, 14, 159, 27, 0, 46, 31, 46, 57, 25, 36, 20, 10, 5, 177, 100, 131, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 100, 0, 2, 0, 37, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 100, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 150, 150, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 156, 0, 99, 1, 174, 8, 160, 10, 92, 13, 10, 15, 32, 28, 0, 21, 25, 39, 40, 37, 30, 20, 7, 6, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 74, 0, 2, 0, 37, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 75, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 112, 0, 13, 2, 161, 5, 36, 9, 188, 12, 116, 14, 96, 27, 0, 60, 34, 66, 80, 45, 47, 36, 18, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 75, 0, 2, 0, 37, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 75, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 32, 1, 88, 3, 40, 5, 140, 10, 112, 13, 191, 14, 32, 28, 0, 53, 31, 69, 57, 42, 31, 19, 9, 4, 217, 155, 105, 120, 120, 120, 247, 170, 165, 44, 65, 75, 130, 54, 0, 0, 0, 0, 50, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 74, 0, 2, 0, 37, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 75, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 160, 0, 232, 1, 198, 7, 236, 9, 12, 13, 101, 14, 128, 28, 0, 41, 27, 56, 59, 58, 46, 34, 11, 7, 185, 112, 127, 120, 120, 120, 185, 117, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 100, 0, 2, 0, 37, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 100, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 172, 0, 64, 1, 207, 8, 214, 11, 112, 13, 134, 16, 42, 27, 0, 27, 6, 49, 41, 38, 41, 19, 12, 6, 182, 120, 133, 133, 142, 161, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 74, 0, 2, 0, 37, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 75, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 153, 0, 156, 1, 248, 2, 120, 10, 148, 12, 176, 14, 244, 26, 0, 35, 17, 52, 37, 27, 30, 22, 12, 5, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 74, 0, 2, 0, 37, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 75, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 176, 0, 64, 1, 52, 3, 56, 9, 12, 13, 60, 15, 144, 26, 0, 35, 6, 61, 36, 21, 21, 30, 12, 7, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 12, 0, 2, 0, 1, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 12, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 60, 0, 3, 0, 5, 0, 200, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 30, 4, 20, 15, 12, 15, 12, 16, 5, 0, 150, 175, 175, 120, 120, 120, 100, 125, 125, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 200, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 30, 4, 17, 18, 11, 14, 11, 15, 4, 0, 150, 175, 175, 120, 120, 120, 100, 125, 125, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 200, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 4, 14, 20, 10, 13, 10, 14, 4, 0, 150, 175, 175, 120, 120, 120, 100, 125, 125, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 55, 0, 2, 0, 5, 0, 200, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 55, 5, 16, 23, 12, 15, 12, 16, 5, 0, 150, 175, 175, 120, 120, 120, 100, 125, 125, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 200, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 5, 16, 23, 12, 15, 12, 16, 5, 0, 150, 175, 175, 120, 120, 120, 100, 125, 125, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 90, 0, 2, 0, 17, 0, 116, 0, 13, 2, 161, 5, 36, 9, 188, 12, 116, 14, 96, 27, 90, 21, 28, 36, 46, 24, 22, 28, 14, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 17, 0, 184, 0, 108, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 10, 35, 20, 15, 25, 15, 12, 5, 0, 70, 175, 150, 150, 150, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 65, 0, 2, 0, 17, 0, 32, 1, 88, 3, 40, 5, 140, 10, 112, 13, 191, 14, 32, 28, 65, 35, 32, 53, 48, 31, 24, 25, 12, 6, 217, 155, 105, 120, 120, 120, 247, 170, 165, 44, 65, 75, 130, 53, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 17, 0, 184, 0, 108, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 10, 35, 20, 15, 25, 15, 12, 5, 0, 70, 175, 150, 150, 150, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 60, 0, 2, 0, 1, 0, 64, 1, 72, 2, 28, 7, 0, 10, 104, 13, 15, 15, 224, 28, 60, 31, 31, 43, 49, 39, 30, 38, 12, 7, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 17, 0, 184, 0, 108, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 10, 35, 20, 15, 25, 15, 12, 5, 0, 70, 175, 150, 150, 150, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 50, 0, 2, 0, 17, 0, 172, 0, 64, 1, 207, 8, 214, 11, 112, 13, 134, 16, 42, 27, 50, 47, 8, 65, 54, 50, 54, 25, 16, 8, 182, 120, 133, 133, 142, 161, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 17, 0, 184, 0, 108, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 10, 35, 20, 15, 25, 15, 12, 5, 0, 70, 175, 150, 150, 150, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 40, 0, 2, 0, 17, 0, 160, 0, 32, 2, 132, 3, 216, 9, 164, 11, 141, 14, 32, 27, 40, 87, 34, 66, 84, 51, 46, 23, 17, 6, 165, 135, 150, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 17, 0, 184, 0, 108, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 10, 35, 20, 15, 25, 15, 12, 5, 0, 70, 175, 150, 150, 150, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 50, 0, 2, 0, 17, 0, 176, 0, 64, 1, 52, 3, 56, 9, 12, 13, 60, 15, 144, 26, 50, 36, 6, 62, 37, 21, 21, 31, 12, 7, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 17, 0, 184, 0, 108, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 10, 35, 20, 15, 25, 15, 12, 5, 0, 70, 175, 150, 150, 150, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 40, 0, 2, 0, 17, 0, 132, 0, 24, 1, 184, 6, 36, 9, 228, 12, 96, 14, 100, 25, 40, 43, 19, 60, 40, 35, 38, 35, 9, 12, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 17, 0, 184, 0, 108, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 10, 35, 20, 15, 25, 15, 12, 5, 0, 70, 175, 150, 150, 150, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 47, 0, 3, 0, 37, 0, 184, 0, 108, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 27, 6, 28, 16, 12, 20, 12, 10, 5, 0, 70, 175, 150, 150, 150, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 37, 0, 172, 0, 134, 2, 176, 4, 80, 10, 234, 11, 96, 14, 224, 27, 20, 9, 34, 12, 12, 23, 10, 9, 6, 0, 106, 157, 136, 135, 135, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 160, 0, 160, 2, 176, 4, 120, 10, 234, 11, 96, 14, 224, 27, 0, 6, 27, 6, 9, 18, 6, 6, 6, 0, 142, 140, 122, 120, 120, 120, 172, 110, 152, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 45, 0, 2, 0, 37, 0, 184, 0, 108, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 45, 10, 35, 20, 15, 25, 15, 12, 5, 0, 70, 175, 150, 150, 150, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 184, 0, 108, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 4, 22, 13, 9, 16, 9, 7, 3, 0, 70, 175, 150, 150, 150, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 47, 0, 4, 0, 1, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 7, 5, 27, 12, 20, 10, 4, 4, 2, 0, 70, 175, 150, 150, 150, 120, 85, 130, 137, 44, 35, 50, 60, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 20, 9, 32, 21, 21, 13, 6, 5, 2, 0, 70, 175, 150, 150, 150, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 20, 11, 35, 26, 18, 16, 10, 8, 2, 0, 70, 175, 150, 150, 150, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 12, 37, 27, 19, 17, 11, 9, 3, 0, 70, 175, 150, 150, 150, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 45, 0, 4, 0, 1, 0, 160, 0, 160, 2, 76, 4, 40, 10, 234, 11, 96, 14, 224, 27, 5, 21, 47, 38, 19, 24, 15, 11, 4, 0, 70, 175, 150, 150, 150, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 172, 0, 160, 2, 126, 4, 40, 10, 234, 11, 96, 14, 224, 27, 35, 20, 42, 34, 17, 21, 15, 11, 3, 0, 142, 140, 122, 120, 120, 120, 172, 110, 152, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 5, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 45, 0, 2, 0, 5, 0, 148, 0, 120, 1, 100, 5, 84, 11, 32, 13, 135, 15, 224, 28, 45, 35, 32, 58, 36, 40, 51, 27, 10, 0, 102, 105, 127, 120, 120, 120, 102, 90, 127, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 124, 0, 209, 1, 112, 3, 84, 11, 68, 12, 191, 14, 160, 26, 0, 66, 26, 78, 70, 48, 48, 30, 17, 0, 120, 120, 120, 120, 120, 120, 75, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 0, 0, 2, 0, 5, 0, 98, 0, 106, 1, 230, 5, 60, 10, 12, 13, 37, 15, 114, 26, 75, 20, 14, 45, 29, 19, 17, 16, 9, 8, 155, 112, 127, 120, 120, 120, 160, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 17, 0, 64, 0, 189, 1, 20, 5, 84, 11, 52, 13, 235, 15, 128, 27, 0, 18, 16, 48, 32, 17, 11, 10, 7, 0, 150, 135, 120, 120, 120, 120, 120, 60, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 140, 0, 3, 0, 1, 0, 115, 0, 200, 1, 180, 5, 122, 9, 200, 12, 179, 14, 96, 27, 50, 42, 26, 54, 67, 41, 43, 34, 16, 6, 167, 134, 130, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 115, 0, 200, 1, 180, 5, 122, 9, 200, 12, 179, 14, 96, 27, 90, 74, 35, 72, 89, 54, 57, 44, 22, 8, 167, 134, 130, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 115, 0, 200, 1, 180, 5, 122, 9, 200, 12, 179, 14, 96, 27, 0, 38, 25, 51, 64, 39, 41, 32, 16, 6, 167, 134, 130, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 175, 0, 4, 0, 1, 0, 32, 1, 88, 3, 40, 5, 140, 10, 112, 13, 191, 14, 32, 28, 45, 53, 31, 69, 57, 41, 31, 19, 9, 4, 217, 155, 105, 120, 120, 120, 247, 170, 165, 44, 65, 75, 130, 54, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 32, 1, 88, 3, 40, 5, 140, 10, 112, 13, 191, 14, 32, 28, 50, 96, 42, 93, 77, 56, 42, 26, 12, 6, 217, 155, 105, 120, 120, 120, 247, 170, 165, 44, 65, 75, 130, 54, 0, 0, 0, 0, 50, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 32, 1, 88, 3, 40, 5, 140, 10, 112, 13, 191, 14, 32, 28, 80, 78, 38, 84, 69, 51, 37, 24, 11, 5, 217, 155, 105, 120, 120, 120, 247, 170, 165, 44, 65, 75, 130, 54, 0, 0, 0, 0, 50, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 32, 1, 88, 3, 40, 5, 140, 10, 112, 13, 191, 14, 32, 28, 0, 43, 28, 62, 52, 37, 28, 17, 8, 4, 217, 155, 105, 120, 120, 120, 247, 170, 165, 44, 65, 75, 130, 54, 0, 0, 0, 0, 50, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 0, 0, 4, 0, 33, 0, 156, 0, 99, 1, 174, 8, 160, 10, 92, 13, 10, 15, 32, 28, 52, 21, 24, 39, 39, 36, 29, 19, 7, 6, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 156, 0, 99, 1, 174, 8, 160, 10, 92, 13, 10, 15, 32, 28, 75, 29, 29, 46, 47, 43, 35, 23, 8, 7, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 156, 0, 99, 1, 174, 8, 160, 10, 92, 13, 10, 15, 32, 28, 70, 23, 26, 41, 42, 38, 31, 21, 7, 7, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 156, 0, 99, 1, 174, 8, 160, 10, 92, 13, 10, 15, 32, 28, 0, 25, 27, 43, 44, 40, 33, 22, 8, 7, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 220, 0, 5, 0, 1, 0, 153, 0, 156, 1, 248, 2, 120, 10, 148, 12, 176, 14, 244, 26, 50, 44, 11, 61, 43, 32, 35, 26, 14, 6, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 153, 0, 156, 1, 248, 2, 120, 10, 148, 12, 176, 14, 244, 26, 90, 75, 15, 79, 57, 41, 46, 34, 19, 8, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 153, 0, 156, 1, 248, 2, 120, 10, 148, 12, 176, 14, 244, 26, 50, 60, 13, 71, 51, 37, 41, 30, 17, 7, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 153, 0, 156, 1, 248, 2, 120, 10, 148, 12, 176, 14, 244, 26, 30, 50, 12, 65, 46, 34, 38, 28, 15, 7, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 153, 0, 156, 1, 248, 2, 120, 10, 148, 12, 176, 14, 244, 26, 0, 29, 9, 50, 35, 26, 29, 21, 11, 5, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 175, 0, 4, 0, 1, 0, 160, 0, 32, 2, 132, 3, 216, 9, 164, 11, 141, 14, 32, 27, 45, 41, 23, 45, 58, 35, 32, 16, 11, 4, 165, 135, 150, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 160, 0, 32, 2, 132, 3, 216, 9, 164, 11, 141, 14, 32, 27, 50, 75, 32, 61, 78, 47, 43, 21, 16, 6, 165, 135, 150, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 160, 0, 32, 2, 132, 3, 216, 9, 164, 11, 141, 14, 32, 27, 80, 61, 29, 55, 70, 43, 39, 19, 14, 5, 165, 135, 150, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 160, 0, 32, 2, 132, 3, 216, 9, 164, 11, 141, 14, 32, 27, 0, 34, 21, 41, 52, 32, 29, 14, 10, 4, 165, 135, 150, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 71, 0, 3, 0, 5, 0, 192, 0, 179, 1, 92, 3, 252, 8, 184, 11, 60, 15, 32, 28, 26, 43, 19, 81, 28, 14, 11, 8, 7, 0, 120, 82, 90, 120, 120, 120, 75, 82, 90, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 208, 0, 199, 1, 132, 3, 16, 9, 184, 11, 60, 15, 32, 28, 45, 62, 31, 81, 61, 30, 24, 15, 8, 0, 120, 120, 150, 120, 120, 120, 75, 90, 105, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 32, 1, 88, 3, 40, 5, 140, 10, 112, 13, 191, 14, 32, 28, 0, 53, 31, 69, 57, 42, 31, 19, 9, 4, 217, 155, 105, 120, 120, 120, 247, 170, 165, 44, 65, 75, 130, 54, 0, 0, 0, 0, 50, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 180, 0, 5, 0, 1, 0, 63, 1, 182, 2, 80, 5, 64, 10, 139, 13, 33, 15, 96, 28, 50, 37, 40, 43, 61, 31, 35, 23, 10, 5, 221, 135, 155, 120, 120, 120, 150, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 63, 1, 182, 2, 80, 5, 64, 10, 139, 13, 33, 15, 96, 28, 40, 67, 55, 59, 82, 43, 47, 31, 13, 7, 221, 135, 155, 120, 120, 120, 150, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 63, 1, 182, 2, 80, 5, 64, 10, 139, 13, 33, 15, 96, 28, 50, 54, 49, 53, 74, 38, 42, 28, 12, 6, 221, 135, 155, 120, 120, 120, 150, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 63, 1, 182, 2, 80, 5, 64, 10, 139, 13, 33, 15, 96, 28, 40, 48, 46, 50, 70, 36, 40, 26, 11, 6, 221, 135, 155, 120, 120, 120, 150, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 63, 1, 182, 2, 80, 5, 64, 10, 139, 13, 33, 15, 96, 28, 0, 21, 30, 33, 46, 24, 26, 17, 7, 4, 221, 135, 155, 120, 120, 120, 150, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 200, 0, 5, 0, 1, 0, 184, 0, 88, 1, 188, 2, 60, 10, 88, 12, 176, 14, 159, 27, 50, 37, 28, 41, 51, 15, 25, 18, 9, 5, 177, 100, 131, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 184, 0, 88, 1, 188, 2, 60, 10, 88, 12, 176, 14, 159, 27, 50, 58, 35, 51, 64, 19, 32, 22, 12, 6, 177, 100, 131, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 184, 0, 88, 1, 188, 2, 60, 10, 88, 12, 176, 14, 159, 27, 50, 58, 35, 51, 64, 19, 32, 22, 12, 6, 177, 100, 131, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 184, 0, 88, 1, 188, 2, 60, 10, 88, 12, 176, 14, 159, 27, 50, 51, 33, 48, 61, 18, 30, 21, 11, 6, 177, 100, 131, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 184, 0, 88, 1, 188, 2, 60, 10, 88, 12, 176, 14, 159, 27, 0, 37, 28, 41, 51, 15, 25, 18, 9, 5, 177, 100, 131, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 58, 0, 3, 0, 5, 0, 116, 0, 200, 0, 26, 4, 102, 8, 232, 13, 24, 16, 124, 21, 48, 10, 21, 12, 8, 4, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 55, 65, 50, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 116, 0, 216, 0, 251, 4, 202, 8, 102, 13, 24, 16, 124, 21, 10, 12, 20, 16, 10, 6, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 55, 65, 50, 0, 0, 0, 0, 60, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 35, 0, 2, 0, 5, 0, 116, 0, 232, 0, 252, 3, 60, 10, 232, 13, 24, 16, 124, 21, 35, 8, 16, 14, 4, 2, 2, 2, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 4, 22, 17, 8, 11, 8, 6, 2, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 58, 0, 3, 0, 5, 0, 116, 0, 208, 0, 104, 6, 40, 10, 232, 13, 24, 16, 124, 21, 48, 7, 12, 16, 8, 4, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 50, 85, 50, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 126, 0, 212, 0, 34, 6, 171, 9, 102, 13, 24, 16, 124, 21, 10, 10, 16, 18, 10, 6, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 50, 85, 50, 0, 0, 0, 0, 60, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 136, 0, 216, 0, 220, 5, 46, 9, 228, 12, 24, 16, 124, 21, 0, 15, 20, 20, 12, 8, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 50, 85, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 58, 0, 3, 0, 5, 0, 116, 0, 200, 0, 208, 7, 34, 11, 232, 13, 24, 16, 124, 21, 48, 11, 22, 13, 9, 4, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 75, 140, 48, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 116, 0, 200, 0, 214, 6, 40, 10, 102, 13, 24, 16, 124, 21, 10, 12, 20, 16, 10, 6, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 75, 140, 48, 0, 0, 0, 0, 60, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 116, 0, 200, 0, 220, 5, 46, 9, 228, 12, 24, 16, 124, 21, 0, 12, 18, 18, 10, 7, 3, 3, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 30, 50, 85, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 35, 0, 3, 0, 5, 0, 116, 0, 200, 0, 198, 7, 34, 11, 232, 13, 24, 16, 124, 21, 20, 10, 19, 19, 7, 3, 3, 3, 0, 0, 100, 150, 150, 150, 150, 150, 100, 150, 150, 44, 30, 75, 140, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 150, 0, 180, 1, 59, 6, 165, 10, 233, 12, 60, 15, 174, 24, 15, 11, 28, 24, 11, 11, 9, 7, 1, 0, 85, 162, 150, 135, 135, 135, 100, 150, 150, 44, 30, 50, 85, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 184, 0, 160, 2, 176, 4, 40, 10, 234, 11, 96, 14, 224, 27, 0, 15, 40, 32, 16, 20, 16, 12, 4, 0, 70, 175, 150, 120, 120, 120, 85, 130, 187, 44, 45, 70, 130, 53, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 188, 2, 51, 0, 255, 0, 0, 1, 0, 2, 2, 5, 3, 6, 5, 8, 5, 8, 2, 0, 197, 190, 230, 30, 57, 50, 29, 11, 254, 227, 221, 233, 4, 27, 27, 14, 254, 235, 231, 234, 243, 254, 14, 25, 22, 11, 3, 250, 246, 245, 249, 2, 8, 11, 10, 5, 0, 247, 251, 248, 250, 1, 1, 2, 3, 255, 7, 251, 250, 249, 246, 6, 9, 17, 21, 18, 14, 14, 14, 16, 217, 147, 162, 234, 65, 82, 67, 26, 6, 228, 208, 211, 245, 23, 42, 52, 46, 4, 203, 170, 192, 245, 35, 57, 45, 26, 9, 236, 231, 212, 239, 3, 20, 34, 34, 12, 244, 221, 213, 247, 5, 23, 34, 25, 13, 9, 245, 243, 196, 218, 233, 25, 56, 34, 23, 246, 229, 224, 245, 2, 20, 23, 29, 16, 251, 231, 236, 228, 244, 3, 16, 26, 12, 252, 0, 239, 253, 239, 10, 15, 16, 4, 4, 253, 245, 250, 247, 6, 9, 255, 18, 0, 246, 250, 236, 11, 14, 12, 240, 242, 250, 249, 16, 16, 2, 250, 0, 1, 13, 14, 11, 23, 252, 235, 212, 208, 241, 14, 34, 37, 31, 16, 254, 229, 215, 230, 244, 249, 34, 47, 61, 25, 234, 208, 221, 238, 2, 225, 248, 49, 55, 24, 235, 198, 230, 251, 8, 27, 20, 20, 18, 3, 238, 243, 242, 255, 1, 252, 13, 13, 0, 235, 243, 3, 254, 253, 254, 13, 15, 12, 0, 249, 3, 3, 254, 18, 15, 8, 254, 208, 217, 227, 254, 40, 27, 23, 15, 0, 251, 240, 242, 4, 6, 14, 16, 1, 250, 230, 228, 240, 0, 15, 26, 21, 8, 250, 254, 255, 252, 252, 3, 4, 17, 15, 253, 246, 219, 232, 1, 12, 12, 10, 255, 255, 253, 249, 255, 2, 13, 22, 0, 59, 23, 15, 0, 202, 131, 161, 242, 60, 99, 41, 39, 0, 245, 220, 219, 248, 17, 65, 81, 15, 197, 157, 184, 227, 24, 67, 64, 44, 233, 204, 227, 244, 241, 31, 44, 46, 20, 253, 233, 202, 206, 235, 26, 66, 33, 13, 239, 212, 218, 234, 28, 26, 24, 21, 4, 253, 236, 219, 246, 0, 6, 35, 34, 25, 240, 234, 230, 235, 239, 242, 13, 39, 46, 30, 0, 225, 190, 215, 12, 36, 38, 23, 253, 241, 248, 3, 0, 247, 233, 236, 14, 34, 32, 6, 247, 228, 235, 0, 8, 10, 0, 246, 0, 19, 16, 4, 250, 239, 237, 249, 14, 13, 9, 6, 252, 6, 3, 251, 236, 242, 244, 1, 27, 27, 17, 7, 243, 238, 239, 239, 252, 1, 22, 21, 16, 12, 233, 236, 246, 247, 5, 8, 3, 16, 18, 14, 4, 235, 227, 227, 253, 21, 26, 23, 7, 247, 240, 245, 236, 0, 6, 0, 32, 8, 16, 0, 237, 247, 232, 3, 11, 23, 6, 230, 250, 253, 9, 16, 3, 0, 241, 1, 253, 13, 252, 244, 23, 15, 2, 248, 230, 240, 2, 6, 20, 24, 4, 1, 244, 226, 254, 236, 8, 27, 4, 15, 9, 250, 240, 238, 247, 28, 30, 20, 245, 216, 223, 242, 12, 27, 31, 14, 252, 247, 239, 242, 252, 0, 32, 19, 5, 253, 232, 220, 242, 16, 30, 35, 8, 249, 229, 226, 250, 18, 39, 21, 235, 226, 223, 234, 26, 52, 50, 13, 223, 202, 216, 252, 37, 35, 13, 247, 238, 11, 20, 2, 236, 218, 229, 8, 42, 51, 24, 238, 214, 223, 250, 14, 21, 11, 255, 250, 3, 12, 6, 249, 242, 242, 255, 10, 9, 10, 3, 250, 254, 254, 0, 1, 0, 1, 255, 252, 1, 7, 8, 7, 254, 246, 245, 248, 3, 12, 10, 0, 255, 250, 0, 11, 2, 253, 244, 245, 2, 15, 16, 12, 245, 240, 242, 251, 15, 11, 7, 252, 0, 5, 6, 254, 246, 242, 253, 12, 12, 6, 249, 247, 251, 4, 7, 8, 0, 250, 254, 5, 0, 5, 3, 247, 7, 253, 255, 0, 242, 252, 0, 14, 16, 0, 249, 0, 253, 6, 10, 252, 251, 253, 255, 6, 7, 249, 249, 252, 1, 7, 9, 6, 244, 247, 249, 3, 13, 6, 125, 0, 3, 0, 5, 0, 236, 0, 124, 1, 12, 7, 236, 9, 172, 13, 160, 15, 0, 27, 65, 23, 53, 41, 25, 16, 13, 16, 8, 0, 132, 60, 90, 120, 120, 120, 42, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 236, 0, 124, 1, 12, 7, 236, 9, 172, 13, 160, 15, 0, 27, 60, 23, 53, 41, 25, 16, 13, 16, 8, 0, 132, 60, 90, 120, 120, 120, 42, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 236, 0, 124, 1, 12, 7, 236, 9, 172, 13, 160, 15, 0, 27, 0, 13, 42, 29, 18, 11, 9, 11, 6, 0, 132, 60, 90, 120, 120, 120, 42, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 136, 2, 15, 0, 32, 20, 44, 55, 14, 36, 37, 12, 13, 23, 241, 240, 13, 253, 5, 17, 226, 0, 245, 12, 228, 250, 230, 250, 237, 251, 22, 3, 53, 11, 2, 39, 1, 20, 40, 35, 9, 221, 25, 18, 17, 227, 252, 27, 247, 0, 51, 28, 29, 37, 34, 30, 48, 18, 30, 63, 55, 54, 252, 61, 66, 33, 52, 35, 69, 52, 75, 53, 31, 54, 72, 31, 27, 58, 12, 41, 44, 43, 245, 26, 23, 5, 237, 4, 247, 244, 21, 3, 241, 21, 3, 6, 5, 31, 7, 25, 43, 11, 36, 64, 37, 82, 41, 21, 47, 36, 40, 21, 51, 64, 13, 18, 59, 22, 49, 255, 17, 45, 30, 21, 23, 18, 15, 32, 25, 22, 226, 19, 26, 247, 32, 248, 5, 17, 41, 6, 24, 12, 234, 27, 23, 59, 249, 1, 14, 32, 43, 250, 246, 252, 42, 35, 251, 8, 45, 245, 6, 3, 5, 7, 40, 226, 18, 30, 0, 243, 22, 251, 3, 57, 50, 230, 235, 89, 9, 234, 62, 14, 240, 82, 68, 216, 7, 20, 16, 10, 247, 21, 236, 223, 59, 40, 166, 4, 245, 223, 22, 252, 17, 15, 27, 249, 32, 22, 245, 3, 46, 49, 228, 59, 41, 249, 44, 29, 25, 9, 246, 69, 241, 36, 25, 7, 0, 18, 47, 217, 248, 0, 241, 32, 46, 251, 238, 24, 67, 28, 230, 35, 31, 47, 13, 41, 85, 0, 14, 72, 239, 57, 70, 245, 16, 31, 22, 24, 32, 30, 36, 39, 75, 7, 217, 13, 61, 15, 253, 57, 66, 223, 38, 77, 36, 235, 242, 66, 60, 237, 2, 52, 8, 48, 25, 208, 61, 45, 234, 227, 12, 68, 202, 242, 97, 227, 252, 94, 216, 240, 50, 255, 4, 252, 41, 235, 18, 81, 235, 17, 251, 64, 214, 213, 80, 239, 210, 80, 33, 185, 39, 226, 37, 239, 224, 47, 255, 36, 38, 14, 62, 254, 12, 42, 23, 239, 48, 4, 16, 239, 5, 60, 245, 68, 221, 240, 54, 234, 212, 22, 22, 16, 253, 95, 49, 146, 20, 89, 202, 10, 102, 228, 243, 84, 26, 248, 22, 78, 235, 224, 38, 37, 196, 28, 75, 209, 16, 62, 234, 247, 13, 244, 56, 11, 237, 35, 58, 233, 251, 67, 36, 214, 53, 61, 0, 77, 236, 5, 58, 47, 10, 251, 11, 42, 0, 224, 14, 10, 21, 241, 20, 50, 28, 203, 238, 72, 60, 12, 250, 18, 53, 1, 14, 30, 238, 41, 60, 255, 253, 41, 29, 236, 202, 59, 73, 203, 2, 255, 187, 77, 30, 153, 253, 96, 2, 144, 24, 109, 205, 195, 66, 55, 9, 236, 192, 41, 44, 7, 203, 41, 97, 239, 215, 252, 69, 53, 244, 226, 85, 95, 183, 208, 72, 64, 242, 231, 245, 32, 51, 235, 10, 252, 49, 11, 161, 64, 78, 240, 248, 16, 72, 52, 234, 45, 31, 226, 4, 238, 3, 40, 17, 244, 254, 248, 242, 250, 239, 13, 13, 221, 9, 215, 2, 80, 10, 248, 40, 14, 38, 34, 210, 245, 34, 253, 7, 7, 70, 13, 215, 13, 34, 47, 230, 218, 68, 51, 8, 36, 236, 10, 50, 183, 6, 0, 187, 20, 28, 215, 234, 6, 245, 53, 239, 198, 36, 7, 237, 36, 34, 16, 14, 215, 4, 55, 245, 14, 91, 59, 6, 2, 19, 44, 40, 237, 72, 120, 64, 6, 39, 66, 47, 16, 14, 71, 57, 19, 252, 23, 13, 9, 70, 25, 200, 11, 18, 233, 230, 36, 51, 29, 65, 45, 18, 249, 8, 7, 237, 41, 26, 250, 72, 87, 203, 240, 85, 2, 144, 217, 11, 13, 37, 4, 41, 120, 30, 195, 248, 67, 11, 184, 215, 60, 43, 214, 27, 120, 49, 209, 223, 20, 40, 194, 173, 246, 53, 20, 253, 23, 249, 1, 249, 213, 3, 0, 0, 44, 0, 0, 0, 0, 124, 127, 0, 114, 117, 34, 0, 128, 117, 12, 34, 0, 13, 117, 0, 14, 117, 0, 115, 117, 0, 116, 117, 0, 118, 117, 55, 0, 119, 122, 0, 126, 35, 12, 0, 127, 35, 34, 0, 120, 35, 12, 0, 137, 35, 57, 0, 145, 35, 57, 131, 34, 0, 144, 35, 57, 131, 34, 0, 135, 35, 58, 0, 146, 35, 58, 13, 0, 150, 113, 0, 121, 112, 0, 152, 36, 0, 140, 112, 12, 34, 0, 138, 112, 12, 118, 0, 122, 125, 0, 113, 126, 0, 129, 37, 12, 0, 141, 37, 34, 0, 142, 37, 12, 34, 0, 131, 127, 0, 130, 127, 12, 0, 149, 39, 0, 132, 127, 34, 0, 133, 127, 34, 0, 139, 127, 57, 0, 136, 128, 0, 151, 116, 0, 117, 40, 0, 134, 129, 0, 143, 40, 34, 0, 125, 142, 0, 147, 37, 34, 0, 148, 117, 34, 0, 44, 34, 0, 108, 47, 0, 58, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 5, 0, 1, 0, 63, 1, 160, 2, 124, 6, 64, 10, 139, 13, 33, 15, 96, 28, 50, 38, 37, 37, 66, 41, 35, 23, 10, 5, 221, 200, 155, 120, 120, 120, 150, 245, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 63, 1, 160, 2, 124, 6, 64, 10, 139, 13, 33, 15, 96, 28, 40, 71, 50, 50, 89, 55, 47, 31, 13, 7, 221, 200, 155, 120, 120, 120, 150, 245, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 63, 1, 160, 2, 124, 6, 64, 10, 139, 13, 33, 15, 96, 28, 50, 57, 45, 45, 80, 49, 42, 28, 12, 6, 221, 200, 155, 120, 120, 120, 150, 245, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 63, 1, 160, 2, 124, 6, 64, 10, 139, 13, 33, 15, 96, 28, 40, 45, 40, 40, 71, 44, 37, 25, 10, 6, 221, 200, 155, 120, 120, 120, 150, 245, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 63, 1, 160, 2, 124, 6, 64, 10, 139, 13, 33, 15, 96, 28, 0, 22, 28, 28, 50, 31, 26, 17, 7, 4, 221, 200, 155, 120, 120, 120, 150, 245, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 175, 0, 4, 0, 1, 0, 141, 0, 97, 1, 68, 7, 134, 9, 242, 12, 208, 14, 66, 26, 45, 39, 21, 58, 49, 47, 48, 27, 11, 7, 167, 100, 124, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 141, 0, 97, 1, 68, 7, 134, 9, 242, 12, 208, 14, 66, 26, 70, 75, 29, 81, 68, 66, 66, 38, 15, 10, 167, 100, 124, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 141, 0, 97, 1, 68, 7, 134, 9, 242, 12, 208, 14, 66, 26, 60, 61, 26, 73, 61, 59, 60, 34, 14, 9, 167, 100, 124, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 141, 0, 97, 1, 68, 7, 134, 9, 242, 12, 208, 14, 66, 26, 0, 34, 20, 55, 46, 45, 45, 26, 10, 7, 167, 100, 124, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 215, 0, 5, 0, 1, 0, 32, 1, 92, 3, 192, 5, 102, 10, 158, 13, 27, 15, 118, 27, 45, 35, 30, 56, 58, 37, 34, 23, 6, 4, 209, 165, 164, 130, 120, 120, 167, 105, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 32, 1, 92, 3, 192, 5, 102, 10, 158, 13, 27, 15, 118, 27, 60, 74, 44, 82, 84, 54, 49, 34, 9, 6, 209, 165, 164, 130, 120, 120, 167, 105, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 56, 1, 207, 2, 86, 6, 216, 9, 152, 13, 112, 15, 220, 28, 70, 68, 39, 69, 75, 57, 44, 34, 12, 7, 255, 144, 161, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 6, 1, 50, 2, 45, 7, 223, 9, 77, 13, 225, 14, 189, 28, 40, 48, 32, 52, 60, 51, 42, 35, 11, 7, 228, 126, 148, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 0, 1, 32, 2, 70, 7, 225, 9, 68, 13, 208, 14, 185, 28, 0, 31, 25, 41, 48, 41, 34, 29, 9, 6, 224, 124, 146, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 105, 0, 4, 0, 1, 0, 116, 0, 13, 2, 161, 5, 232, 8, 188, 12, 116, 14, 96, 27, 30, 16, 19, 37, 29, 17, 15, 15, 5, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 116, 0, 13, 2, 161, 5, 232, 8, 188, 12, 116, 14, 96, 27, 45, 19, 22, 41, 33, 19, 17, 17, 6, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 116, 0, 13, 2, 161, 5, 232, 8, 188, 12, 116, 14, 96, 27, 30, 19, 22, 41, 33, 19, 17, 17, 6, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 116, 0, 13, 2, 161, 5, 232, 8, 188, 12, 116, 14, 96, 27, 0, 13, 16, 31, 34, 21, 22, 17, 8, 5, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 175, 0, 4, 0, 1, 0, 128, 0, 32, 2, 196, 4, 216, 9, 188, 12, 20, 15, 96, 27, 45, 45, 33, 61, 58, 39, 36, 33, 17, 6, 167, 135, 135, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 128, 0, 32, 2, 196, 4, 216, 9, 188, 12, 20, 15, 96, 27, 60, 71, 42, 76, 72, 49, 46, 42, 22, 7, 167, 135, 135, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 128, 0, 32, 2, 196, 4, 216, 9, 188, 12, 20, 15, 96, 27, 70, 57, 38, 69, 65, 44, 41, 38, 19, 6, 167, 135, 135, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 128, 0, 32, 2, 236, 4, 216, 9, 188, 12, 20, 15, 96, 27, 0, 41, 32, 58, 55, 37, 35, 32, 16, 5, 167, 135, 135, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 175, 0, 4, 0, 1, 0, 156, 0, 40, 1, 172, 8, 64, 11, 192, 13, 120, 15, 144, 27, 45, 40, 11, 59, 53, 50, 42, 28, 11, 7, 176, 106, 155, 120, 120, 120, 185, 107, 155, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 156, 0, 40, 1, 172, 8, 64, 11, 192, 13, 120, 15, 144, 27, 80, 74, 16, 81, 73, 68, 57, 38, 15, 9, 176, 106, 155, 120, 120, 120, 185, 107, 155, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 156, 0, 36, 1, 196, 8, 76, 11, 216, 13, 144, 15, 144, 27, 50, 63, 14, 75, 67, 63, 52, 35, 14, 9, 176, 106, 155, 120, 120, 120, 185, 107, 155, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 156, 0, 32, 1, 212, 8, 84, 11, 232, 13, 160, 15, 144, 27, 0, 33, 10, 53, 48, 45, 37, 25, 10, 6, 176, 106, 155, 120, 120, 120, 185, 107, 155, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 250, 0, 5, 0, 1, 0, 248, 0, 144, 2, 204, 6, 196, 9, 242, 13, 183, 15, 64, 28, 45, 28, 24, 44, 49, 44, 29, 19, 7, 4, 193, 135, 180, 120, 120, 120, 217, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 248, 0, 144, 2, 204, 6, 196, 9, 242, 13, 183, 15, 64, 28, 80, 82, 41, 76, 83, 75, 49, 33, 12, 8, 193, 135, 180, 120, 120, 120, 217, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 244, 0, 128, 2, 204, 6, 208, 9, 225, 13, 155, 15, 70, 28, 80, 74, 39, 72, 78, 72, 48, 33, 11, 8, 193, 132, 174, 120, 120, 120, 217, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 214, 0, 33, 2, 59, 7, 27, 10, 118, 13, 233, 14, 110, 28, 45, 48, 28, 58, 59, 61, 44, 33, 10, 7, 187, 115, 141, 120, 120, 120, 217, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 200, 0, 248, 1, 108, 7, 60, 10, 72, 13, 156, 14, 128, 28, 0, 30, 23, 48, 48, 52, 39, 30, 9, 6, 185, 107, 127, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 4, 0, 33, 0, 169, 0, 56, 1, 192, 8, 28, 11, 84, 13, 40, 15, 20, 26, 52, 28, 19, 35, 41, 45, 45, 29, 11, 5, 166, 170, 129, 120, 120, 120, 167, 190, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 169, 0, 56, 1, 192, 8, 28, 11, 84, 13, 40, 15, 20, 26, 75, 44, 24, 44, 52, 56, 56, 36, 14, 6, 166, 170, 129, 120, 120, 120, 167, 190, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 169, 0, 56, 1, 192, 8, 28, 11, 84, 13, 40, 15, 20, 26, 79, 35, 21, 39, 46, 50, 51, 33, 13, 6, 166, 170, 129, 120, 120, 120, 167, 190, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 169, 0, 56, 1, 192, 8, 28, 11, 84, 13, 40, 15, 20, 26, 0, 33, 25, 36, 43, 46, 46, 33, 13, 6, 166, 170, 129, 120, 120, 120, 167, 190, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 150, 0, 4, 0, 1, 0, 184, 0, 152, 1, 128, 7, 236, 9, 52, 13, 80, 15, 96, 25, 50, 41, 35, 59, 42, 57, 53, 28, 12, 5, 160, 90, 120, 120, 120, 120, 130, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 184, 0, 152, 1, 128, 7, 236, 9, 52, 13, 80, 15, 96, 25, 60, 74, 47, 79, 57, 76, 71, 38, 17, 7, 160, 90, 120, 120, 120, 120, 130, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 184, 0, 152, 1, 128, 7, 236, 9, 52, 13, 80, 15, 96, 25, 40, 60, 42, 71, 51, 68, 64, 34, 15, 6, 160, 90, 120, 120, 120, 120, 130, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 184, 0, 160, 1, 108, 7, 20, 10, 92, 13, 120, 15, 96, 25, 0, 44, 34, 68, 38, 51, 47, 27, 10, 8, 160, 105, 120, 120, 120, 120, 130, 60, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 190, 0, 5, 0, 1, 0, 251, 0, 136, 2, 96, 4, 92, 10, 60, 12, 48, 14, 235, 27, 50, 39, 30, 52, 63, 24, 35, 22, 7, 5, 182, 149, 126, 120, 120, 120, 105, 164, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 251, 0, 136, 2, 96, 4, 92, 10, 60, 12, 48, 14, 235, 27, 50, 77, 41, 72, 87, 33, 49, 31, 9, 7, 182, 149, 126, 120, 120, 120, 105, 164, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 251, 0, 136, 2, 96, 4, 92, 10, 60, 12, 48, 14, 235, 27, 50, 77, 41, 72, 87, 33, 49, 31, 9, 7, 182, 149, 126, 120, 120, 120, 105, 164, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 251, 0, 136, 2, 96, 4, 92, 10, 60, 12, 48, 14, 235, 27, 40, 55, 35, 61, 74, 28, 42, 26, 8, 6, 182, 149, 126, 120, 120, 120, 105, 164, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 0, 1, 80, 2, 232, 3, 80, 10, 28, 12, 36, 14, 15, 28, 0, 25, 24, 38, 48, 16, 28, 16, 4, 4, 186, 151, 122, 120, 120, 120, 105, 164, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 165, 0, 4, 0, 1, 0, 204, 0, 100, 2, 208, 4, 60, 10, 168, 12, 10, 15, 0, 28, 45, 48, 34, 51, 73, 40, 48, 24, 14, 6, 170, 150, 150, 120, 120, 120, 170, 165, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 204, 0, 100, 2, 208, 4, 60, 10, 168, 12, 10, 15, 0, 28, 80, 68, 41, 61, 87, 48, 57, 28, 17, 7, 170, 150, 150, 120, 120, 120, 170, 165, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 204, 0, 100, 2, 208, 4, 60, 10, 168, 12, 10, 15, 0, 28, 40, 59, 38, 55, 82, 45, 54, 27, 16, 6, 170, 150, 150, 120, 120, 120, 170, 165, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 204, 0, 100, 2, 216, 4, 60, 10, 168, 12, 10, 15, 0, 28, 0, 40, 37, 46, 64, 35, 42, 21, 12, 9, 167, 150, 150, 120, 120, 120, 167, 165, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 190, 0, 5, 0, 1, 0, 192, 0, 192, 1, 72, 3, 38, 10, 208, 11, 47, 14, 159, 27, 50, 40, 25, 45, 62, 20, 33, 18, 9, 5, 177, 100, 131, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 192, 0, 192, 1, 72, 3, 38, 10, 208, 11, 47, 14, 159, 27, 50, 77, 35, 63, 87, 28, 45, 25, 13, 7, 177, 100, 131, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 192, 0, 192, 1, 72, 3, 38, 10, 208, 11, 47, 14, 159, 27, 50, 77, 35, 63, 87, 28, 45, 25, 13, 7, 177, 100, 131, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 192, 0, 192, 1, 72, 3, 38, 10, 208, 11, 47, 14, 159, 27, 40, 49, 31, 53, 66, 24, 39, 21, 11, 6, 177, 100, 131, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 192, 0, 192, 1, 72, 3, 38, 10, 208, 11, 47, 14, 159, 27, 0, 28, 28, 45, 41, 20, 33, 18, 9, 5, 177, 100, 131, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 100, 0, 4, 0, 1, 0, 176, 0, 72, 1, 132, 3, 56, 9, 12, 13, 60, 15, 144, 26, 50, 36, 3, 58, 43, 21, 21, 30, 15, 7, 177, 175, 102, 120, 120, 120, 177, 175, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 176, 0, 72, 1, 132, 3, 56, 9, 12, 13, 60, 15, 144, 26, 50, 61, 4, 76, 56, 28, 28, 40, 20, 10, 177, 175, 102, 120, 120, 120, 177, 175, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 176, 0, 72, 1, 132, 3, 56, 9, 12, 13, 60, 15, 144, 26, 70, 45, 3, 64, 49, 24, 24, 35, 17, 8, 177, 180, 102, 120, 120, 120, 177, 180, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 176, 0, 72, 1, 132, 3, 56, 9, 12, 13, 60, 15, 144, 26, 0, 24, 2, 45, 35, 17, 17, 25, 12, 6, 177, 200, 102, 120, 120, 120, 177, 200, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 110, 0, 6, 0, 1, 0, 14, 1, 212, 2, 106, 4, 200, 10, 2, 13, 238, 14, 192, 27, 45, 58, 27, 62, 74, 40, 33, 28, 10, 5, 165, 148, 135, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 14, 1, 212, 2, 106, 4, 200, 10, 2, 13, 238, 14, 192, 27, 65, 137, 42, 95, 114, 62, 51, 43, 16, 8, 165, 148, 135, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 14, 1, 212, 2, 106, 4, 200, 10, 2, 13, 238, 14, 192, 27, 40, 111, 38, 86, 102, 55, 46, 39, 15, 7, 165, 148, 135, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 218, 0, 120, 2, 232, 3, 161, 10, 109, 12, 71, 14, 60, 27, 50, 94, 29, 71, 93, 53, 42, 37, 17, 8, 166, 145, 137, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 144, 0, 216, 1, 12, 3, 196, 9, 254, 11, 157, 14, 216, 26, 40, 75, 26, 68, 68, 47, 43, 25, 18, 8, 163, 120, 143, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 144, 0, 216, 1, 12, 3, 196, 9, 254, 11, 157, 14, 216, 26, 0, 53, 22, 57, 57, 40, 36, 21, 15, 7, 163, 120, 143, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 45, 0, 3, 0, 5, 0, 116, 0, 232, 0, 164, 6, 176, 9, 152, 13, 60, 15, 124, 21, 45, 9, 20, 12, 8, 4, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 116, 0, 232, 0, 164, 6, 216, 9, 192, 13, 80, 15, 124, 21, 0, 9, 20, 12, 8, 4, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 116, 0, 232, 0, 164, 6, 216, 9, 192, 13, 80, 15, 124, 21, 0, 9, 20, 12, 8, 4, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 58, 0, 3, 0, 5, 0, 116, 0, 232, 0, 252, 8, 240, 10, 232, 13, 24, 16, 124, 21, 58, 11, 22, 13, 9, 4, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 116, 0, 232, 0, 252, 8, 240, 10, 232, 13, 24, 16, 124, 21, 0, 11, 22, 13, 9, 4, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 116, 0, 232, 0, 252, 8, 240, 10, 232, 13, 24, 16, 124, 21, 0, 11, 22, 13, 9, 4, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 42, 3, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 14, 26, 36, 42, 44, 45, 42, 34, 23, 3, 230, 196, 171, 166, 179, 204, 230, 249, 5, 15, 25, 30, 24, 0, 222, 185, 164, 168, 195, 224, 243, 0, 17, 47, 80, 102, 102, 79, 44, 11, 244, 226, 206, 185, 168, 166, 187, 230, 25, 68, 91, 97, 98, 100, 96, 75, 34, 239, 189, 158, 150, 159, 174, 191, 213, 245, 32, 78, 113, 125, 112, 81, 44, 9, 234, 200, 165, 137, 131, 153, 198, 251, 39, 70, 91, 106, 114, 110, 87, 46, 252, 202, 168, 153, 153, 163, 180, 204, 239, 26, 71, 104, 116, 106, 82, 53, 22, 245, 208, 171, 144, 137, 154, 187, 228, 9, 40, 64, 82, 92, 91, 73, 40, 255, 216, 188, 174, 170, 172, 180, 198, 229, 10, 48, 75, 85, 80, 66, 46, 22, 250, 216, 184, 161, 154, 166, 192, 225, 1, 31, 57, 77, 91, 94, 82, 55, 20, 244, 219, 203, 193, 189, 193, 206, 229, 1, 30, 51, 61, 62, 55, 42, 25, 4, 237, 213, 195, 187, 192, 206, 225, 245, 7, 25, 41, 52, 54, 45, 29, 8, 245, 229, 217, 210, 207, 210, 220, 235, 255, 17, 32, 40, 41, 38, 31, 21, 7, 248, 231, 219, 214, 217, 226, 238, 251, 7, 20, 31, 39, 40, 33, 21, 7, 250, 238, 229, 224, 223, 225, 233, 244, 2, 16, 27, 32, 33, 31, 26, 18, 7, 252, 240, 232, 228, 230, 235, 243, 253, 6, 17, 26, 31, 32, 28, 20, 9, 255, 246, 238, 233, 231, 232, 238, 246, 0, 10, 17, 22, 24, 23, 20, 13, 5, 253, 245, 238, 235, 235, 239, 245, 252, 2, 10, 17, 21, 22, 20, 15, 8, 1, 251, 246, 242, 240, 240, 243, 249, 255, 4, 9, 13, 15, 15, 13, 10, 5, 0, 251, 248, 245, 245, 246, 249, 252, 0, 3, 7, 10, 11, 10, 8, 5, 2, 0, 253, 251, 250, 250, 251, 253, 255, 1, 3, 5, 5, 6, 5, 4, 2, 0, 0, 255, 254, 254, 254, 255, 0, 0, 1, 1, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 175, 0, 4, 0, 1, 0, 32, 1, 66, 3, 196, 4, 130, 10, 112, 13, 48, 15, 32, 28, 45, 49, 30, 65, 58, 38, 30, 19, 9, 4, 186, 152, 120, 120, 120, 120, 192, 155, 135, 44, 45, 70, 130, 58, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 32, 1, 66, 3, 196, 4, 130, 10, 112, 13, 48, 15, 32, 28, 70, 100, 43, 92, 83, 55, 43, 28, 13, 6, 186, 152, 120, 120, 120, 120, 192, 155, 135, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 32, 1, 66, 3, 196, 4, 130, 10, 112, 13, 48, 15, 32, 28, 60, 82, 38, 83, 75, 50, 38, 25, 11, 5, 186, 152, 120, 120, 120, 120, 192, 155, 135, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 32, 1, 66, 3, 196, 4, 130, 10, 112, 13, 48, 15, 32, 28, 0, 43, 28, 61, 55, 36, 28, 18, 8, 4, 186, 152, 120, 120, 120, 120, 192, 155, 135, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 175, 0, 4, 0, 1, 0, 130, 0, 80, 1, 162, 8, 240, 10, 112, 13, 100, 15, 120, 26, 45, 48, 19, 68, 52, 50, 43, 30, 11, 6, 168, 95, 132, 143, 120, 120, 185, 102, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 130, 0, 80, 1, 162, 8, 240, 10, 112, 13, 100, 15, 120, 26, 70, 89, 26, 93, 71, 68, 59, 40, 16, 8, 168, 95, 132, 143, 120, 120, 185, 102, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 130, 0, 80, 1, 162, 8, 200, 10, 112, 13, 100, 15, 120, 26, 60, 81, 24, 88, 67, 64, 56, 38, 15, 8, 168, 95, 132, 143, 120, 120, 185, 102, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 130, 0, 80, 1, 162, 8, 200, 10, 112, 13, 100, 15, 120, 26, 0, 36, 16, 58, 44, 43, 37, 25, 10, 5, 168, 95, 132, 143, 120, 120, 185, 102, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 175, 0, 4, 0, 1, 0, 176, 0, 64, 1, 172, 3, 56, 9, 228, 12, 60, 15, 144, 26, 45, 39, 5, 66, 34, 17, 26, 29, 11, 7, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 176, 0, 64, 1, 172, 3, 56, 9, 228, 12, 60, 15, 144, 26, 80, 65, 7, 85, 44, 22, 33, 37, 14, 9, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 176, 0, 64, 1, 152, 3, 56, 9, 228, 12, 60, 15, 144, 26, 50, 48, 6, 73, 38, 19, 28, 31, 12, 7, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 176, 0, 64, 1, 132, 3, 56, 9, 228, 12, 60, 15, 144, 26, 0, 35, 5, 62, 32, 16, 24, 27, 10, 6, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 195, 0, 4, 0, 1, 0, 133, 0, 93, 1, 164, 6, 242, 8, 208, 12, 114, 14, 24, 25, 45, 41, 21, 57, 47, 41, 38, 32, 10, 11, 173, 111, 133, 121, 121, 130, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 133, 0, 93, 1, 164, 6, 242, 8, 208, 12, 114, 14, 24, 25, 80, 71, 27, 76, 62, 54, 50, 42, 13, 14, 173, 111, 133, 121, 121, 130, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 133, 0, 93, 1, 164, 6, 242, 8, 208, 12, 114, 14, 24, 25, 70, 57, 25, 68, 55, 49, 45, 38, 12, 13, 173, 111, 133, 121, 121, 130, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 133, 0, 93, 1, 164, 6, 242, 8, 208, 12, 114, 14, 24, 25, 0, 35, 19, 54, 44, 38, 35, 30, 9, 10, 173, 111, 133, 121, 121, 130, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 245, 0, 6, 0, 1, 0, 72, 1, 136, 3, 40, 5, 140, 10, 112, 13, 191, 14, 32, 28, 45, 50, 32, 67, 59, 34, 30, 19, 9, 4, 207, 150, 105, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 56, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 72, 1, 136, 3, 40, 5, 140, 10, 112, 13, 191, 14, 32, 28, 40, 101, 43, 96, 85, 49, 43, 27, 13, 6, 207, 150, 105, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 57, 0, 0, 0, 0, 45, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 55, 1, 100, 3, 128, 5, 140, 10, 116, 13, 189, 14, 32, 28, 75, 82, 41, 88, 78, 48, 40, 26, 12, 6, 203, 144, 114, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 56, 0, 0, 0, 0, 45, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 152, 0, 48, 1, 56, 9, 164, 11, 232, 13, 220, 15, 160, 26, 40, 59, 21, 68, 68, 61, 54, 32, 15, 7, 167, 110, 120, 120, 120, 120, 167, 110, 120, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 105, 0, 48, 1, 56, 9, 164, 11, 232, 13, 220, 15, 93, 26, 45, 31, 15, 51, 51, 47, 46, 26, 12, 8, 172, 106, 109, 120, 120, 120, 167, 110, 120, 44, 45, 70, 130, 55, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 105, 0, 48, 1, 56, 9, 164, 11, 232, 13, 220, 15, 93, 26, 0, 31, 15, 51, 51, 47, 46, 26, 12, 8, 172, 106, 109, 120, 120, 120, 167, 110, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 170, 0, 4, 0, 1, 0, 229, 0, 216, 2, 20, 5, 35, 10, 227, 12, 233, 14, 214, 27, 50, 53, 31, 61, 69, 39, 42, 24, 13, 6, 189, 159, 136, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 229, 0, 216, 2, 20, 5, 35, 10, 227, 12, 233, 14, 214, 27, 70, 82, 38, 77, 86, 48, 53, 29, 17, 6, 189, 159, 136, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 229, 0, 216, 2, 20, 5, 35, 10, 227, 12, 233, 14, 214, 27, 50, 68, 35, 70, 78, 44, 48, 27, 15, 6, 189, 159, 136, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 229, 0, 224, 2, 20, 5, 35, 10, 227, 12, 233, 14, 214, 27, 0, 38, 27, 54, 55, 34, 37, 21, 12, 5, 189, 159, 136, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 115, 0, 4, 0, 1, 0, 136, 0, 224, 1, 24, 6, 116, 9, 248, 12, 240, 15, 95, 27, 45, 44, 27, 57, 66, 39, 41, 24, 16, 6, 170, 137, 135, 122, 124, 128, 197, 137, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 136, 0, 224, 1, 24, 6, 116, 9, 248, 12, 220, 15, 95, 27, 70, 71, 34, 72, 83, 49, 52, 30, 20, 8, 170, 137, 135, 122, 124, 128, 197, 137, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 136, 0, 234, 1, 4, 6, 92, 9, 227, 12, 157, 15, 95, 27, 70, 64, 33, 69, 79, 47, 50, 30, 19, 7, 170, 137, 135, 122, 124, 128, 197, 137, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 136, 0, 4, 2, 240, 5, 36, 9, 178, 12, 10, 15, 95, 27, 0, 36, 24, 52, 59, 35, 38, 25, 14, 5, 170, 137, 135, 122, 124, 128, 197, 137, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 45, 0, 5, 0, 1, 0, 144, 0, 120, 1, 188, 7, 120, 10, 132, 13, 160, 15, 128, 28, 45, 45, 22, 58, 58, 58, 47, 44, 11, 8, 185, 107, 127, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 144, 0, 120, 1, 188, 7, 120, 10, 132, 13, 160, 15, 128, 28, 41, 91, 32, 84, 84, 84, 68, 64, 16, 12, 185, 107, 127, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 200, 0, 208, 1, 188, 7, 80, 10, 132, 13, 216, 14, 128, 28, 74, 93, 38, 84, 88, 84, 68, 51, 16, 12, 185, 107, 127, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 200, 0, 208, 1, 148, 7, 60, 10, 92, 13, 196, 14, 128, 28, 40, 93, 38, 84, 88, 84, 68, 51, 16, 12, 185, 107, 127, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 200, 0, 32, 2, 8, 7, 136, 9, 228, 12, 76, 14, 128, 28, 0, 44, 30, 58, 61, 58, 47, 36, 11, 8, 185, 107, 127, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 255, 0, 5, 0, 1, 0, 31, 1, 64, 2, 255, 6, 225, 9, 104, 13, 15, 15, 224, 28, 45, 37, 28, 51, 55, 50, 39, 28, 9, 6, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 22, 1, 160, 2, 204, 6, 255, 9, 124, 13, 33, 15, 156, 28, 70, 58, 37, 68, 71, 61, 48, 35, 12, 7, 245, 138, 159, 124, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 242, 0, 97, 3, 196, 5, 122, 10, 204, 13, 109, 15, 140, 27, 80, 78, 43, 84, 81, 56, 44, 31, 14, 6, 250, 166, 163, 142, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 236, 0, 128, 3, 160, 5, 140, 10, 216, 13, 120, 15, 102, 27, 60, 83, 41, 81, 77, 51, 41, 29, 13, 5, 251, 170, 163, 145, 120, 120, 255, 174, 173, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 236, 0, 128, 3, 160, 5, 140, 10, 216, 13, 120, 15, 102, 27, 0, 50, 32, 63, 60, 40, 32, 22, 10, 4, 251, 170, 163, 145, 120, 120, 255, 174, 173, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 199, 0, 6, 0, 5, 0, 24, 1, 240, 2, 116, 4, 4, 11, 152, 13, 35, 15, 64, 27, 51, 53, 27, 57, 72, 38, 39, 19, 3, 8, 225, 165, 135, 120, 120, 120, 225, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 24, 1, 240, 2, 116, 4, 4, 11, 72, 13, 191, 14, 64, 27, 75, 95, 34, 81, 88, 51, 55, 37, 5, 7, 167, 165, 165, 120, 120, 120, 167, 105, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 24, 1, 240, 2, 196, 4, 200, 10, 72, 13, 191, 14, 64, 27, 30, 77, 32, 77, 83, 48, 52, 35, 5, 6, 167, 165, 165, 120, 120, 120, 167, 105, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 33, 0, 196, 0, 224, 2, 249, 5, 232, 8, 188, 12, 247, 13, 64, 27, 33, 39, 29, 59, 54, 45, 44, 45, 8, 8, 167, 150, 180, 120, 120, 120, 167, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 193, 0, 208, 1, 160, 7, 173, 9, 21, 13, 229, 14, 64, 27, 40, 41, 30, 57, 50, 49, 43, 40, 14, 9, 167, 105, 180, 120, 120, 120, 167, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 192, 0, 168, 1, 208, 7, 196, 9, 32, 13, 0, 15, 64, 27, 0, 30, 27, 50, 44, 44, 38, 34, 13, 8, 167, 100, 180, 120, 120, 120, 137, 85, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 225, 0, 6, 0, 1, 0, 177, 0, 117, 1, 37, 3, 102, 10, 50, 12, 55, 15, 148, 26, 45, 38, 11, 53, 49, 26, 23, 20, 12, 6, 162, 127, 149, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 177, 0, 117, 1, 37, 3, 102, 10, 50, 12, 55, 15, 148, 26, 50, 60, 13, 66, 61, 32, 29, 26, 16, 8, 162, 127, 149, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 189, 0, 168, 1, 84, 3, 128, 10, 68, 12, 5, 15, 185, 26, 50, 64, 24, 59, 72, 37, 34, 31, 17, 8, 163, 130, 147, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 244, 0, 128, 2, 36, 4, 240, 10, 148, 12, 41, 14, 96, 27, 40, 94, 30, 75, 97, 50, 46, 46, 15, 7, 167, 142, 135, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 244, 0, 128, 2, 36, 4, 240, 10, 148, 12, 41, 14, 96, 27, 40, 84, 29, 71, 92, 47, 44, 44, 14, 7, 167, 142, 135, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 244, 0, 128, 2, 36, 4, 240, 10, 148, 12, 41, 14, 96, 27, 0, 45, 23, 53, 64, 36, 33, 33, 11, 5, 167, 142, 135, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 250, 0, 5, 0, 1, 0, 152, 0, 24, 1, 232, 8, 4, 11, 52, 13, 0, 15, 160, 26, 45, 27, 6, 51, 45, 46, 46, 22, 10, 5, 167, 105, 120, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 152, 0, 24, 1, 232, 8, 4, 11, 52, 13, 0, 15, 160, 26, 80, 65, 9, 78, 70, 70, 71, 34, 16, 8, 167, 105, 120, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 161, 0, 67, 1, 160, 8, 207, 10, 36, 13, 208, 14, 0, 27, 65, 48, 12, 66, 59, 62, 59, 31, 13, 7, 166, 105, 121, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 31, 1, 72, 2, 244, 6, 0, 10, 104, 13, 15, 15, 224, 28, 60, 38, 30, 52, 55, 49, 38, 27, 10, 6, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 31, 1, 72, 2, 244, 6, 0, 10, 104, 13, 15, 15, 224, 28, 0, 33, 28, 48, 51, 46, 35, 25, 9, 6, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 240, 0, 5, 0, 1, 0, 168, 0, 240, 1, 132, 3, 216, 9, 164, 11, 141, 14, 32, 27, 45, 54, 23, 57, 64, 39, 35, 17, 13, 5, 165, 135, 150, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 168, 0, 240, 1, 132, 3, 216, 9, 164, 11, 141, 14, 32, 27, 80, 105, 33, 80, 89, 54, 49, 24, 18, 7, 165, 135, 150, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 170, 0, 224, 1, 138, 3, 186, 9, 168, 11, 141, 14, 76, 27, 55, 83, 27, 74, 79, 48, 43, 22, 16, 6, 164, 133, 148, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 192, 0, 120, 1, 32, 3, 172, 8, 204, 11, 141, 14, 224, 28, 60, 44, 23, 63, 38, 26, 17, 15, 7, 7, 162, 120, 135, 120, 120, 120, 117, 90, 180, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 176, 0, 104, 1, 32, 3, 92, 8, 204, 11, 141, 14, 224, 28, 0, 33, 19, 57, 37, 21, 14, 11, 8, 7, 152, 120, 97, 120, 120, 120, 107, 90, 97, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 5, 0, 1, 0, 16, 1, 96, 2, 8, 7, 225, 9, 104, 13, 15, 15, 224, 28, 40, 29, 23, 47, 51, 46, 36, 26, 8, 5, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 16, 1, 96, 2, 8, 7, 225, 9, 104, 13, 15, 15, 224, 28, 66, 69, 36, 73, 77, 71, 55, 40, 13, 8, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 6, 1, 64, 2, 20, 7, 226, 9, 99, 13, 18, 15, 157, 28, 94, 58, 30, 66, 70, 65, 50, 37, 12, 8, 237, 130, 156, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 168, 0, 112, 1, 128, 7, 40, 10, 50, 13, 48, 15, 64, 26, 40, 37, 19, 53, 51, 51, 47, 29, 11, 8, 181, 111, 129, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 152, 0, 152, 1, 168, 7, 40, 10, 52, 13, 60, 15, 96, 25, 0, 30, 24, 56, 44, 48, 45, 26, 10, 8, 160, 105, 120, 120, 120, 120, 130, 60, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 201, 4, 37, 0, 1, 5, 238, 14, 15, 233, 0, 15, 12, 244, 232, 21, 11, 0, 252, 238, 27, 254, 250, 251, 0, 30, 251, 232, 4, 19, 244, 249, 15, 238, 27, 244, 247, 11, 249, 2, 8, 250, 2, 7, 249, 8, 243, 14, 242, 2, 29, 243, 242, 0, 20, 248, 3, 5, 245, 7, 2, 12, 248, 239, 10, 18, 3, 229, 11, 9, 248, 28, 222, 16, 19, 252, 19, 249, 5, 237, 227, 235, 239, 35, 16, 242, 248, 244, 11, 239, 33, 20, 213, 26, 249, 5, 21, 227, 0, 35, 39, 240, 220, 12, 29, 29, 243, 242, 16, 29, 2, 229, 13, 0, 19, 8, 250, 245, 19, 4, 247, 220, 239, 234, 211, 242, 20, 8, 0, 6, 12, 238, 224, 14, 41, 195, 231, 247, 188, 236, 15, 234, 1, 25, 3, 231, 252, 28, 27, 35, 252, 236, 23, 58, 255, 232, 34, 41, 255, 8, 19, 252, 252, 29, 46, 235, 238, 74, 8, 189, 13, 27, 235, 233, 31, 14, 236, 228, 253, 23, 237, 239, 16, 234, 231, 29, 241, 242, 4, 16, 236, 239, 38, 228, 234, 68, 238, 216, 40, 240, 255, 24, 247, 11, 239, 255, 3, 21, 18, 227, 243, 44, 224, 253, 15, 5, 10, 216, 247, 51, 8, 200, 4, 36, 250, 2, 218, 249, 45, 2, 213, 11, 13, 177, 229, 20, 1, 232, 30, 21, 208, 26, 55, 18, 194, 20, 42, 7, 14, 218, 8, 59, 243, 251, 29, 252, 2, 247, 1, 15, 18, 243, 253, 10, 4, 255, 11, 252, 232, 248, 23, 250, 242, 243, 21, 246, 222, 33, 252, 244, 13, 253, 221, 255, 38, 250, 201, 55, 247, 214, 13, 0, 250, 2, 217, 218, 251, 51, 210, 204, 33, 55, 237, 217, 34, 13, 11, 232, 0, 80, 228, 255, 8, 19, 58, 210, 25, 40, 226, 51, 246, 237, 37, 12, 255, 234, 27, 26, 203, 36, 19, 221, 3, 1, 0, 237, 250, 28, 221, 237, 35, 240, 240, 1, 229, 253, 0, 7, 9, 244, 245, 233, 46, 251, 210, 26, 14, 248, 238, 33, 13, 203, 28, 26, 224, 5, 5, 252, 25, 245, 15, 1, 250, 29, 236, 237, 54, 221, 206, 247, 8, 247, 187, 21, 51, 222, 25, 35, 233, 12, 25, 219, 254, 45, 3, 245, 21, 26, 5, 253, 0, 5, 237, 35, 236, 226, 22, 43, 206, 238, 52, 19, 226, 236, 21, 1, 249, 244, 244, 4, 54, 223, 204, 22, 5, 0, 11, 197, 240, 53, 218, 232, 53, 210, 10, 21, 251, 244, 0, 2, 11, 8, 255, 249, 241, 38, 249, 217, 26, 27, 5, 11, 251, 218, 55, 26, 199, 5, 30, 10, 12, 198, 38, 7, 221, 38, 255, 227, 13, 6, 43, 224, 215, 62, 0, 235, 42, 212, 243, 43, 253, 253, 224, 16, 28, 244, 12, 4, 223, 251, 51, 226, 239, 19, 225, 30, 32, 213, 238, 6, 32, 231, 232, 27, 240, 238, 13, 11, 233, 247, 27, 237, 3, 250, 2, 22, 216, 19, 25, 222, 36, 10, 211, 254, 37, 46, 215, 220, 50, 230, 240, 30, 250, 246, 232, 31, 5, 232, 32, 243, 42, 239, 253, 31, 233, 14, 220, 48, 31, 210, 15, 245, 11, 15, 2, 237, 24, 251, 8, 217, 47, 33, 207, 7, 31, 17, 190, 11, 20, 242, 218, 34, 10, 179, 23, 52, 222, 236, 14, 25, 16, 246, 243, 10, 239, 183, 244, 12, 195, 241, 62, 188, 9, 23, 249, 246, 232, 88, 27, 171, 23, 49, 21, 34, 27, 225, 11, 7, 71, 197, 217, 93, 254, 213, 27, 22, 240, 25, 16, 224, 23, 23, 223, 36, 243, 220, 57, 242, 219, 218, 38, 13, 172, 28, 18, 226, 179, 57, 41, 164, 244, 66, 208, 251, 248, 234, 23, 34, 29, 195, 45, 248, 250, 12, 0, 20, 234, 33, 47, 208, 3, 63, 207, 34, 18, 185, 0, 31, 252, 216, 254, 19, 36, 10, 217, 220, 22, 34, 251, 217, 245, 70, 2, 181, 18, 35, 220, 96, 161, 18, 92, 165, 252, 42, 254, 10, 1, 228, 32, 0, 246, 2, 4, 30, 18, 240, 235, 26, 235, 225, 246, 35, 31, 184, 224, 65, 251, 241, 246, 13, 28, 232, 234, 48, 191, 233, 90, 231, 226, 43, 8, 191, 24, 62, 206, 221, 38, 25, 189, 252, 72, 218, 222, 69, 5, 208, 46, 245, 209, 21, 53, 250, 180, 54, 0, 198, 76, 7, 194, 26, 41, 235, 1, 240, 31, 240, 237, 51, 199, 237, 112, 217, 177, 52, 24, 222, 6, 238, 241, 55, 217, 183, 59, 58, 208, 241, 17, 35, 214, 0, 25, 255, 31, 219, 233, 54, 0, 247, 1, 228, 30, 215, 20, 53, 200, 20, 249, 238, 83, 254, 142, 16, 125, 236, 153, 40, 54, 253, 18, 206, 254, 49, 36, 205, 182, 51, 75, 223, 172, 9, 247, 48, 245, 240, 251, 8, 20, 226, 1, 24, 232, 3, 29, 15, 4, 252, 252, 12, 0, 16, 242, 66, 239, 184, 4, 38, 15, 225, 245, 21, 1, 241, 3, 219, 11, 227, 250, 38, 248, 188, 216, 77, 64, 187, 240, 5, 69, 230, 203, 57, 39, 243, 5, 240, 39, 19, 208, 248, 28, 2, 234, 248, 6, 248, 14, 11, 250, 24, 30, 221, 218, 44, 9, 250, 203, 242, 17, 19, 254, 202, 217, 49, 241, 241, 0, 238, 14, 32, 0, 230, 253, 44, 0, 223, 86, 233, 246, 39, 1, 246, 6, 4, 12, 234, 3, 38, 237, 16, 223, 223, 50, 23, 229, 211, 250, 27, 254, 246, 233, 219, 46, 250, 188, 40, 20, 239, 244, 42, 19, 233, 48, 18, 202, 9, 11, 229, 16, 22, 218, 245, 35, 32, 238, 223, 58, 7, 0, 11, 205, 221, 74, 25, 186, 10, 34, 244, 222, 250, 53, 16, 200, 20, 37, 254, 252, 227, 13, 18, 14, 252, 252, 31, 216, 204, 28, 50, 6, 234, 225, 35, 1, 230, 251, 22, 11, 2, 237, 0, 42, 241, 212, 38, 32, 227, 13, 9, 209, 10, 27, 238, 210, 248, 20, 231, 249, 13, 33, 0, 236, 34, 21, 9, 11, 227, 12, 29, 249, 226, 245, 14, 224, 196, 1, 3, 196, 242, 12, 37, 234, 243, 40, 16, 250, 21, 3, 252, 18, 11, 209, 241, 70, 18, 248, 3, 1, 249, 229, 16, 29, 236, 64, 29, 214, 13, 18, 4, 253, 240, 15, 4, 15, 239, 216, 10, 32, 246, 4, 239, 232, 222, 241, 4, 10, 1, 242, 238, 255, 12, 227, 242, 16, 248, 244, 10, 248, 244, 7, 0, 28, 35, 12, 237, 5, 32, 20, 17, 226, 0, 26, 4, 231, 15, 26, 224, 239, 31, 22, 244, 233, 246, 0, 0, 18, 246, 244, 24, 11, 253, 3, 242, 241, 0, 14, 18, 254, 247, 249, 1, 0, 243, 4, 13, 2, 243, 0, 6, 1, 29, 219, 236, 44, 3, 248, 243, 6, 48, 241, 242, 31, 4, 12, 252, 250, 22, 13, 240, 247, 1, 253, 237, 231, 246, 6, 1, 241, 252, 1, 6, 252, 247, 16, 11, 0, 17, 7, 7, 253, 0, 10, 232, 254, 20, 3, 250, 237, 245, 0, 0, 14, 254, 247, 252, 243, 0, 252, 248, 6, 7, 252, 0, 0, 0, 165, 0, 4, 0, 1, 0, 144, 0, 224, 1, 32, 3, 140, 10, 228, 12, 120, 15, 88, 27, 45, 51, 23, 55, 59, 35, 32, 18, 13, 5, 165, 131, 145, 120, 120, 120, 165, 110, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 144, 0, 224, 1, 32, 3, 140, 10, 228, 12, 120, 15, 88, 27, 60, 94, 32, 75, 80, 47, 44, 25, 18, 8, 165, 131, 145, 120, 120, 120, 165, 110, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 144, 0, 224, 1, 32, 3, 140, 10, 228, 12, 120, 15, 88, 27, 60, 75, 29, 67, 71, 42, 39, 22, 16, 7, 165, 131, 145, 120, 120, 120, 165, 110, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 144, 0, 224, 1, 32, 3, 140, 10, 228, 12, 120, 15, 88, 27, 0, 44, 22, 51, 54, 32, 30, 17, 12, 5, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 156, 0, 4, 0, 1, 0, 253, 0, 32, 3, 40, 5, 77, 10, 28, 13, 216, 14, 244, 27, 46, 49, 30, 64, 61, 39, 37, 21, 11, 5, 200, 157, 123, 120, 120, 120, 247, 170, 165, 44, 65, 75, 130, 53, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 253, 0, 32, 3, 40, 5, 77, 10, 28, 13, 216, 14, 244, 27, 50, 85, 40, 84, 80, 52, 48, 28, 15, 6, 200, 157, 123, 120, 120, 120, 247, 170, 165, 44, 65, 75, 130, 53, 0, 0, 0, 0, 50, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 253, 0, 32, 3, 40, 5, 77, 10, 28, 13, 216, 14, 244, 27, 60, 79, 38, 81, 77, 50, 46, 27, 14, 6, 200, 157, 123, 120, 120, 120, 247, 170, 165, 44, 65, 75, 130, 53, 0, 0, 0, 0, 50, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 253, 0, 32, 3, 40, 5, 77, 10, 28, 13, 216, 14, 244, 27, 0, 52, 31, 66, 63, 40, 38, 22, 11, 5, 200, 157, 123, 120, 120, 120, 247, 170, 165, 44, 65, 75, 130, 53, 0, 0, 0, 0, 50, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 0, 0, 4, 0, 1, 0, 136, 0, 224, 1, 4, 6, 36, 9, 248, 12, 220, 15, 95, 27, 45, 47, 29, 60, 60, 42, 44, 25, 17, 6, 170, 137, 153, 122, 124, 128, 197, 137, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 136, 0, 224, 1, 4, 6, 36, 9, 248, 12, 220, 15, 95, 27, 50, 74, 36, 76, 76, 52, 55, 32, 21, 8, 170, 137, 153, 122, 124, 128, 197, 137, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 136, 0, 168, 1, 180, 5, 72, 8, 248, 12, 220, 15, 95, 27, 70, 79, 36, 76, 68, 52, 55, 32, 21, 8, 170, 137, 165, 122, 124, 128, 197, 137, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 136, 0, 144, 1, 84, 6, 72, 8, 248, 12, 220, 15, 95, 27, 0, 38, 24, 51, 54, 35, 29, 21, 14, 5, 170, 137, 135, 122, 124, 128, 197, 137, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 240, 0, 5, 0, 1, 0, 168, 0, 240, 1, 132, 3, 216, 9, 224, 11, 141, 14, 32, 27, 45, 56, 27, 57, 64, 39, 35, 21, 13, 5, 165, 135, 150, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 168, 0, 240, 1, 132, 3, 216, 9, 224, 11, 141, 14, 32, 27, 80, 108, 38, 80, 89, 54, 49, 29, 18, 7, 165, 135, 150, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 170, 0, 224, 1, 138, 3, 186, 9, 224, 11, 141, 14, 76, 27, 55, 85, 31, 74, 79, 48, 43, 27, 16, 6, 164, 133, 148, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 181, 0, 172, 1, 115, 3, 51, 9, 224, 11, 141, 14, 22, 28, 60, 73, 31, 73, 64, 40, 33, 21, 12, 7, 163, 126, 141, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 192, 0, 120, 1, 92, 3, 172, 8, 224, 11, 141, 14, 224, 28, 0, 39, 25, 58, 35, 24, 16, 14, 7, 7, 162, 120, 135, 120, 120, 120, 117, 90, 180, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 215, 0, 6, 0, 1, 0, 132, 0, 16, 1, 184, 6, 36, 9, 228, 12, 96, 14, 100, 25, 45, 37, 18, 57, 36, 30, 30, 30, 9, 12, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 132, 0, 16, 1, 184, 6, 36, 9, 228, 12, 96, 14, 100, 25, 20, 68, 24, 76, 51, 44, 48, 44, 12, 16, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 132, 0, 24, 1, 184, 6, 36, 9, 228, 12, 96, 14, 100, 25, 70, 54, 21, 68, 46, 39, 43, 39, 10, 14, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 178, 0, 126, 1, 31, 4, 53, 9, 251, 11, 131, 14, 113, 26, 40, 37, 22, 51, 47, 36, 32, 21, 14, 7, 163, 128, 153, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 184, 0, 138, 1, 212, 3, 56, 9, 224, 11, 136, 14, 144, 26, 40, 41, 24, 53, 51, 38, 33, 21, 15, 6, 162, 133, 155, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 184, 0, 138, 1, 212, 3, 56, 9, 224, 11, 136, 14, 144, 26, 0, 29, 20, 44, 42, 31, 27, 17, 13, 5, 162, 133, 155, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 100, 0, 3, 0, 5, 0, 4, 0, 176, 0, 208, 7, 184, 11, 58, 14, 136, 19, 224, 21, 40, 4, 0, 24, 2, 2, 4, 4, 4, 4, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 4, 0, 176, 0, 208, 7, 184, 11, 58, 14, 136, 19, 224, 21, 60, 5, 0, 25, 2, 2, 4, 4, 5, 4, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 9, 0, 4, 0, 176, 0, 108, 7, 184, 11, 58, 14, 136, 19, 224, 21, 0, 5, 0, 25, 2, 2, 4, 4, 5, 4, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 198, 8, 12, 0, 0, 255, 254, 252, 251, 251, 253, 0, 1, 1, 2, 2, 2, 0, 253, 251, 248, 245, 241, 237, 235, 236, 236, 237, 237, 237, 240, 243, 246, 245, 241, 238, 236, 235, 236, 237, 239, 244, 250, 253, 254, 0, 5, 10, 10, 4, 254, 250, 247, 240, 232, 227, 227, 228, 227, 230, 235, 240, 244, 245, 241, 240, 247, 0, 6, 6, 255, 247, 241, 231, 223, 230, 239, 242, 243, 247, 255, 8, 11, 6, 5, 6, 10, 22, 38, 49, 60, 70, 70, 66, 65, 65, 65, 64, 59, 49, 38, 23, 4, 244, 232, 218, 206, 202, 199, 196, 196, 197, 196, 199, 203, 207, 213, 221, 228, 233, 237, 239, 238, 238, 242, 247, 0, 14, 26, 30, 33, 37, 37, 39, 42, 41, 43, 47, 47, 46, 47, 43, 36, 31, 29, 27, 30, 39, 48, 56, 60, 58, 56, 61, 71, 81, 93, 105, 114, 120, 125, 123, 116, 113, 113, 109, 103, 104, 105, 102, 97, 90, 81, 78, 75, 60, 44, 38, 32, 25, 19, 6, 246, 235, 227, 225, 235, 249, 0, 0, 253, 249, 250, 254, 3, 11, 16, 16, 6, 252, 249, 254, 2, 2, 255, 251, 249, 242, 230, 214, 201, 197, 200, 200, 200, 207, 215, 224, 231, 231, 234, 246, 255, 252, 246, 241, 235, 227, 217, 211, 220, 242, 2, 8, 11, 14, 12, 1, 243, 227, 216, 210, 199, 182, 171, 172, 178, 183, 185, 188, 195, 208, 219, 222, 218, 214, 212, 210, 209, 213, 218, 225, 237, 249, 254, 0, 4, 14, 22, 20, 11, 3, 1, 250, 235, 222, 219, 222, 225, 228, 234, 241, 247, 255, 1, 3, 13, 27, 35, 34, 26, 17, 13, 4, 249, 246, 249, 249, 248, 249, 254, 4, 9, 7, 6, 9, 12, 19, 27, 29, 28, 28, 27, 22, 18, 18, 17, 13, 8, 3, 0, 250, 241, 234, 234, 237, 236, 235, 237, 238, 235, 227, 219, 220, 232, 249, 4, 14, 22, 30, 37, 37, 31, 25, 22, 16, 11, 11, 11, 13, 19, 24, 33, 39, 35, 27, 25, 18, 5, 254, 254, 0, 0, 251, 245, 241, 235, 229, 231, 236, 239, 239, 239, 239, 236, 232, 234, 242, 251, 0, 2, 7, 7, 255, 248, 247, 242, 227, 204, 190, 198, 217, 232, 247, 1, 2, 253, 244, 242, 9, 40, 37, 9, 246, 235, 223, 216, 220, 232, 244, 241, 223, 223, 251, 14, 7, 0, 253, 235, 216, 218, 236, 250, 249, 246, 254, 10, 19, 25, 36, 59, 70, 51, 31, 32, 31, 17, 3, 3, 22, 44, 48, 38, 29, 31, 30, 16, 254, 244, 244, 239, 226, 218, 230, 251, 8, 14, 20, 28, 29, 18, 2, 245, 235, 235, 244, 251, 3, 20, 35, 33, 21, 23, 44, 51, 21, 245, 245, 246, 234, 239, 1, 14, 17, 8, 252, 7, 32, 42, 35, 23, 12, 5, 255, 245, 242, 244, 240, 236, 241, 246, 247, 255, 9, 16, 20, 15, 12, 22, 24, 8, 1, 6, 8, 11, 9, 253, 251, 6, 11, 14, 15, 13, 24, 38, 30, 18, 21, 21, 8, 250, 244, 252, 5, 9, 20, 30, 19, 6, 13, 26, 29, 19, 6, 7, 16, 21, 33, 51, 56, 43, 23, 10, 11, 20, 31, 29, 11, 251, 244, 249, 9, 11, 251, 251, 10, 8, 250, 251, 13, 28, 22, 11, 15, 24, 15, 0, 255, 3, 4, 10, 18, 15, 8, 2, 3, 12, 13, 15, 35, 32, 249, 235, 1, 6, 251, 0, 13, 6, 251, 252, 11, 31, 32, 15, 15, 24, 18, 6, 255, 253, 2, 1, 251, 3, 19, 21, 12, 1, 3, 19, 27, 15, 254, 237, 221, 218, 234, 245, 241, 248, 2, 248, 236, 4, 45, 58, 42, 32, 40, 43, 36, 35, 41, 29, 252, 226, 228, 237, 245, 12, 34, 29, 11, 249, 236, 241, 252, 249, 241, 234, 228, 235, 246, 0, 28, 54, 45, 19, 6, 10, 24, 22, 251, 231, 237, 252, 11, 23, 27, 21, 5, 249, 1, 15, 21, 24, 14, 248, 241, 251, 8, 23, 26, 14, 10, 7, 249, 249, 17, 26, 0, 232, 238, 2, 0, 244, 251, 13, 16, 0, 247, 8, 29, 21, 0, 1, 11, 2, 231, 209, 223, 4, 18, 3, 0, 20, 29, 9, 5, 46, 62, 13, 235, 254, 17, 11, 254, 251, 12, 18, 252, 241, 4, 18, 5, 242, 245, 15, 27, 13, 4, 7, 6, 7, 18, 25, 12, 251, 253, 15, 17, 6, 13, 27, 12, 240, 244, 24, 38, 10, 235, 233, 252, 10, 2, 252, 5, 6, 0, 10, 17, 16, 24, 21, 0, 252, 4, 11, 19, 12, 255, 18, 46, 40, 33, 40, 33, 23, 27, 13, 243, 233, 237, 241, 247, 242, 241, 9, 36, 33, 3, 235, 226, 212, 195, 205, 229, 243, 254, 3, 255, 6, 38, 71, 76, 43, 13, 25, 47, 39, 13, 9, 37, 43, 255, 221, 243, 27, 38, 255, 204, 211, 249, 244, 226, 246, 20, 24, 15, 11, 25, 42, 35, 1, 234, 246, 0, 245, 249, 8, 245, 221, 248, 34, 38, 3, 231, 252, 35, 8, 203, 221, 34, 22, 199, 199, 33, 76, 21, 241, 29, 75, 58, 15, 254, 2, 252, 219, 202, 241, 25, 13, 246, 9, 44, 48, 33, 27, 24, 6, 238, 229, 246, 7, 234, 190, 204, 242, 243, 232, 249, 8, 3, 4, 24, 34, 26, 11, 250, 237, 235, 246, 17, 31, 9, 248, 250, 3, 30, 45, 29, 26, 25, 0, 240, 242, 239, 245, 252, 242, 236, 247, 6, 22, 30, 19, 252, 243, 252, 246, 227, 222, 224, 221, 221, 231, 252, 21, 21, 255, 246, 5, 24, 26, 252, 222, 232, 248, 237, 235, 0, 9, 255, 246, 3, 42, 69, 45, 6, 249, 250, 255, 254, 244, 246, 246, 215, 206, 255, 43, 33, 251, 236, 251, 0, 237, 234, 253, 249, 212, 182, 206, 254, 253, 224, 236, 15, 24, 13, 0, 0, 20, 16, 238, 239, 26, 31, 246, 226, 252, 37, 47, 3, 236, 15, 24, 238, 221, 244, 0, 234, 199, 209, 253, 0, 239, 246, 9, 32, 31, 253, 244, 254, 234, 215, 217, 234, 9, 16, 6, 31, 49, 33, 28, 18, 246, 231, 224, 223, 240, 232, 202, 195, 208, 229, 6, 28, 30, 25, 15, 0, 251, 5, 10, 241, 203, 201, 244, 31, 31, 12, 15, 17, 1, 249, 253, 239, 201, 186, 226, 7, 7, 10, 8, 249, 244, 235, 228, 250, 246, 211, 207, 218, 232, 6, 10, 252, 0, 248, 237, 0, 3, 248, 250, 238, 229, 250, 12, 14, 13, 14, 16, 7, 1, 3, 242, 231, 249, 254, 239, 231, 224, 230, 248, 253, 3, 14, 0, 227, 216, 231, 248, 254, 253, 241, 228, 228, 230, 239, 6, 15, 247, 219, 232, 10, 9, 243, 252, 17, 22, 2, 225, 236, 15, 252, 233, 13, 31, 11, 250, 247, 21, 48, 22, 238, 221, 228, 238, 228, 234, 13, 3, 218, 226, 5, 32, 36, 250, 215, 232, 231, 212, 233, 251, 226, 207, 235, 35, 55, 13, 236, 254, 20, 15, 252, 239, 240, 243, 247, 13, 34, 13, 238, 242, 6, 20, 23, 255, 219, 218, 239, 246, 243, 246, 247, 237, 230, 240, 0, 9, 8, 248, 237, 3, 7, 215, 189, 217, 233, 233, 247, 247, 231, 240, 255, 2, 21, 25, 12, 21, 25, 253, 234, 234, 245, 7, 11, 18, 27, 249, 222, 7, 47, 54, 31, 224, 196, 230, 234, 224, 240, 219, 189, 200, 223, 4, 34, 5, 234, 249, 0, 0, 8, 255, 234, 223, 222, 230, 233, 238, 0, 14, 15, 20, 35, 50, 45, 22, 11, 8, 247, 231, 238, 243, 227, 209, 210, 229, 5, 26, 14, 251, 244, 240, 234, 228, 221, 219, 216, 218, 236, 249, 250, 3, 17, 25, 31, 14, 238, 229, 232, 224, 225, 242, 2, 16, 14, 17, 48, 57, 21, 4, 8, 249, 227, 215, 217, 243, 7, 1, 255, 1, 247, 234, 240, 5, 19, 2, 219, 203, 235, 11, 253, 227, 239, 12, 22, 5, 243, 2, 14, 230, 199, 219, 229, 215, 217, 234, 14, 53, 38, 252, 248, 19, 33, 18, 243, 222, 219, 213, 203, 223, 255, 243, 211, 224, 16, 52, 50, 14, 249, 6, 21, 11, 241, 221, 216, 195, 177, 210, 250, 240, 215, 222, 15, 57, 48, 29, 15, 241, 231, 241, 237, 233, 214, 192, 227, 18, 35, 65, 71, 36, 29, 30, 8, 246, 205, 162, 174, 195, 204, 223, 235, 2, 31, 29, 38, 52, 17, 239, 239, 254, 4, 214, 156, 187, 252, 12, 23, 45, 48, 20, 240, 245, 37, 53, 5, 207, 197, 214, 214, 214, 233, 248, 250, 243, 246, 30, 62, 38, 0, 228, 216, 244, 15, 10, 254, 232, 218, 239, 251, 249, 13, 8, 228, 230, 13, 46, 43, 255, 222, 237, 5, 7, 232, 199, 214, 237, 227, 239, 24, 34, 6, 229, 243, 41, 37, 222, 188, 226, 8, 4, 239, 237, 252, 10, 15, 12, 33, 50, 8, 222, 229, 245, 254, 237, 196, 205, 237, 229, 240, 254, 220, 228, 24, 48, 68, 56, 250, 235, 4, 8, 15, 255, 204, 197, 207, 203, 239, 21, 2, 234, 243, 21, 58, 42, 246, 227, 236, 243, 243, 229, 224, 241, 243, 234, 247, 4, 8, 14, 13, 3, 2, 0, 247, 0, 9, 253, 251, 0, 235, 227, 1, 5, 236, 228, 230, 241, 5, 3, 251, 253, 240, 234, 253, 254, 248, 254, 245, 239, 1, 17, 26, 28, 15, 0, 248, 243, 247, 251, 249, 245, 226, 222, 0, 18, 3, 248, 245, 251, 0, 242, 237, 248, 240, 227, 229, 234, 249, 253, 234, 242, 12, 14, 8, 3, 0, 17, 17, 250, 254, 7, 255, 0, 248, 233, 251, 0, 244, 0, 6, 253, 0, 240, 229, 13, 31, 5, 254, 255, 248, 245, 228, 237, 20, 4, 220, 240, 24, 36, 11, 213, 214, 12, 255, 210, 230, 255, 250, 244, 242, 23, 65, 21, 222, 249, 25, 7, 227, 209, 228, 239, 217, 227, 7, 16, 12, 2, 2, 42, 57, 18, 254, 250, 230, 216, 206, 218, 1, 3, 238, 8, 49, 45, 12, 240, 236, 240, 237, 232, 225, 218, 214, 209, 240, 47, 63, 22, 240, 234, 253, 254, 222, 213, 237, 242, 230, 236, 12, 45, 38, 6, 253, 14, 20, 248, 212, 211, 227, 231, 236, 255, 19, 24, 8, 4, 30, 51, 37, 6, 237, 228, 222, 211, 216, 232, 235, 229, 231, 255, 30, 27, 253, 250, 22, 34, 255, 208, 207, 231, 229, 227, 242, 4, 20, 11, 251, 31, 65, 29, 254, 11, 22, 17, 241, 204, 223, 246, 226, 224, 251, 2, 2, 0, 250, 6, 17, 1, 239, 237, 240, 231, 213, 223, 254, 9, 1, 246, 239, 5, 29, 16, 5, 7, 240, 224, 238, 252, 10, 14, 244, 236, 7, 27, 39, 37, 4, 243, 247, 245, 248, 248, 227, 218, 221, 226, 248, 16, 21, 12, 4, 18, 42, 34, 9, 250, 233, 224, 225, 218, 218, 234, 243, 245, 251, 4, 27, 41, 20, 253, 1, 5, 244, 222, 223, 252, 9, 242, 232, 5, 22, 9, 253, 253, 10, 10, 232, 213, 245, 4, 237, 226, 240, 252, 6, 8, 255, 0, 0, 247, 251, 1, 0, 253, 230, 222, 16, 51, 29, 14, 11, 255, 0, 0, 241, 230, 214, 202, 220, 246, 250, 248, 3, 18, 24, 28, 23, 254, 230, 225, 226, 235, 255, 17, 12, 249, 2, 29, 26, 10, 6, 254, 248, 235, 223, 253, 18, 236, 219, 249, 12, 35, 49, 21, 255, 1, 3, 12, 13, 238, 205, 194, 202, 231, 2, 3, 255, 8, 28, 41, 41, 31, 10, 238, 214, 205, 216, 230, 238, 244, 244, 247, 11, 29, 26, 12, 253, 252, 5, 250, 232, 236, 237, 225, 223, 241, 23, 46, 28, 9, 7, 5, 0, 242, 229, 235, 238, 232, 235, 244, 4, 19, 10, 4, 14, 8, 251, 236, 227, 242, 0, 253, 0, 7, 15, 23, 5, 247, 252, 236, 224, 245, 249, 241, 250, 250, 253, 18, 27, 34, 46, 36, 4, 235, 221, 211, 212, 232, 253, 0, 251, 253, 19, 49, 53, 30, 8, 249, 232, 215, 204, 211, 228, 229, 222, 244, 35, 63, 48, 17, 1, 1, 254, 237, 221, 219, 224, 233, 244, 255, 14, 24, 11, 253, 2, 14, 17, 9, 245, 229, 235, 249, 1, 0, 242, 230, 244, 18, 28, 17, 12, 4, 253, 8, 0, 224, 213, 205, 200, 238, 15, 12, 16, 19, 11, 28, 46, 30, 255, 231, 234, 253, 247, 232, 237, 242, 253, 19, 20, 14, 14, 3, 4, 20, 3, 242, 252, 248, 255, 26, 12, 245, 0, 4, 5, 24, 16, 253, 244, 233, 249, 19, 5, 243, 235, 228, 254, 12, 244, 240, 247, 240, 5, 20, 5, 13, 7, 239, 12, 37, 16, 10, 0, 238, 0, 253, 227, 249, 9, 250, 251, 245, 240, 11, 9, 236, 248, 4, 240, 231, 246, 4, 0, 233, 227, 246, 254, 253, 5, 11, 2, 246, 245, 0, 254, 244, 241, 243, 247, 249, 0, 20, 30, 13, 1, 13, 24, 22, 9, 252, 254, 1, 244, 233, 239, 242, 240, 241, 240, 242, 253, 253, 247, 254, 1, 254, 254, 250, 250, 0, 0, 175, 0, 4, 0, 1, 0, 208, 0, 144, 2, 24, 6, 136, 9, 22, 13, 216, 14, 92, 27, 45, 38, 30, 55, 57, 46, 32, 23, 10, 5, 168, 135, 157, 120, 120, 120, 200, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 208, 0, 144, 2, 24, 6, 136, 9, 22, 13, 216, 14, 92, 27, 70, 61, 38, 70, 73, 58, 41, 29, 13, 6, 168, 135, 157, 120, 120, 120, 200, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 202, 0, 136, 2, 0, 6, 140, 9, 4, 13, 196, 14, 92, 27, 60, 50, 35, 63, 67, 51, 37, 27, 13, 6, 168, 136, 153, 120, 120, 120, 200, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 202, 0, 136, 2, 0, 6, 140, 9, 4, 13, 196, 14, 92, 27, 0, 27, 27, 46, 49, 37, 23, 17, 9, 4, 168, 136, 153, 120, 120, 120, 200, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 195, 0, 4, 0, 1, 0, 192, 0, 24, 2, 152, 3, 40, 10, 244, 11, 196, 14, 159, 27, 45, 56, 28, 56, 68, 34, 34, 22, 14, 6, 172, 138, 135, 120, 120, 120, 167, 138, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 192, 0, 24, 2, 152, 3, 40, 10, 244, 11, 196, 14, 159, 27, 80, 111, 40, 80, 96, 48, 48, 31, 20, 8, 172, 138, 135, 120, 120, 120, 167, 138, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 192, 0, 24, 2, 152, 3, 40, 10, 244, 11, 196, 14, 159, 27, 70, 96, 38, 72, 91, 45, 45, 29, 19, 8, 172, 138, 135, 120, 120, 120, 167, 138, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 192, 0, 24, 2, 152, 3, 40, 10, 244, 11, 196, 14, 159, 27, 0, 47, 26, 50, 64, 32, 32, 20, 13, 5, 172, 138, 135, 120, 120, 120, 167, 138, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 190, 0, 4, 0, 1, 0, 168, 0, 152, 1, 224, 6, 236, 9, 72, 13, 180, 15, 163, 25, 50, 42, 32, 62, 49, 52, 44, 32, 14, 6, 161, 98, 126, 120, 120, 120, 130, 107, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 168, 0, 152, 1, 224, 6, 236, 9, 72, 13, 180, 15, 163, 25, 80, 67, 40, 78, 61, 66, 55, 40, 17, 8, 161, 98, 126, 120, 120, 120, 130, 107, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 168, 0, 152, 1, 224, 6, 236, 9, 72, 13, 180, 15, 163, 25, 60, 56, 37, 71, 56, 61, 51, 37, 16, 7, 161, 98, 126, 120, 120, 120, 130, 107, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 168, 0, 152, 1, 224, 6, 236, 9, 72, 13, 180, 15, 163, 25, 0, 32, 28, 54, 42, 46, 38, 28, 12, 5, 161, 98, 126, 120, 120, 120, 130, 107, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 185, 0, 6, 0, 1, 0, 186, 0, 176, 2, 84, 6, 80, 10, 192, 13, 100, 15, 160, 27, 50, 41, 39, 54, 66, 42, 33, 27, 15, 0, 180, 150, 125, 120, 120, 120, 200, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 186, 0, 176, 2, 84, 6, 80, 10, 192, 13, 100, 15, 160, 27, 50, 63, 48, 66, 81, 52, 40, 33, 18, 0, 180, 150, 125, 120, 120, 120, 200, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 186, 0, 160, 2, 84, 6, 80, 10, 192, 13, 100, 15, 160, 27, 45, 47, 42, 52, 75, 45, 36, 29, 16, 0, 180, 150, 125, 120, 120, 120, 200, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 188, 0, 34, 2, 57, 5, 54, 10, 250, 12, 206, 14, 197, 27, 45, 26, 37, 37, 42, 31, 26, 21, 10, 2, 180, 119, 122, 120, 120, 120, 200, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 192, 0, 135, 1, 222, 3, 20, 10, 6, 12, 21, 14, 244, 27, 40, 20, 40, 29, 26, 17, 22, 16, 6, 5, 180, 81, 119, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 192, 0, 135, 1, 222, 3, 20, 10, 6, 12, 21, 14, 244, 27, 0, 14, 34, 24, 14, 14, 18, 14, 5, 4, 180, 81, 119, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 244, 0, 6, 0, 1, 0, 228, 0, 40, 2, 128, 3, 120, 10, 8, 12, 15, 14, 216, 27, 50, 61, 29, 60, 73, 30, 34, 21, 10, 6, 180, 112, 128, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 228, 0, 40, 2, 128, 3, 120, 10, 8, 12, 15, 14, 216, 27, 40, 85, 35, 71, 86, 35, 40, 25, 12, 7, 180, 112, 128, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 228, 0, 40, 2, 128, 3, 120, 10, 8, 12, 15, 14, 216, 27, 45, 75, 33, 67, 81, 33, 38, 23, 11, 6, 180, 112, 128, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 215, 0, 229, 1, 83, 3, 127, 10, 228, 12, 60, 15, 176, 27, 50, 47, 41, 51, 63, 25, 25, 19, 11, 5, 164, 96, 118, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 205, 0, 184, 1, 52, 3, 132, 10, 248, 12, 4, 16, 148, 27, 60, 21, 43, 30, 30, 20, 13, 13, 9, 4, 153, 85, 112, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 205, 0, 184, 1, 52, 3, 132, 10, 248, 12, 4, 16, 148, 27, 0, 16, 37, 26, 26, 17, 11, 11, 8, 3, 153, 85, 112, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 139, 0, 3, 0, 1, 0, 80, 1, 168, 2, 124, 6, 216, 9, 192, 13, 185, 15, 32, 29, 50, 49, 35, 57, 69, 51, 38, 29, 10, 8, 255, 150, 180, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 88, 1, 168, 2, 124, 6, 216, 9, 192, 13, 185, 15, 32, 29, 90, 82, 45, 74, 89, 66, 50, 38, 13, 8, 255, 150, 180, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 88, 1, 168, 2, 124, 6, 216, 9, 192, 13, 185, 15, 32, 29, 0, 47, 34, 56, 67, 50, 38, 28, 9, 9, 255, 150, 180, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 167, 10, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 255, 253, 255, 0, 1, 1, 0, 255, 253, 255, 1, 0, 254, 0, 7, 6, 254, 2, 3, 1, 0, 0, 0, 253, 253, 244, 245, 8, 21, 10, 251, 249, 4, 0, 0, 4, 4, 246, 237, 246, 10, 15, 27, 27, 225, 225, 2, 34, 31, 7, 252, 226, 4, 33, 247, 210, 242, 25, 37, 13, 247, 241, 243, 25, 28, 247, 237, 254, 65, 35, 236, 218, 188, 249, 59, 78, 31, 199, 236, 10, 229, 22, 50, 36, 238, 191, 14, 47, 241, 234, 236, 224, 68, 38, 10, 241, 213, 43, 0, 6, 33, 244, 26, 235, 221, 6, 233, 38, 252, 235, 235, 5, 57, 253, 254, 18, 15, 5, 221, 203, 212, 219, 255, 22, 52, 57, 23, 218, 184, 213, 244, 18, 31, 40, 10, 225, 228, 236, 242, 245, 17, 29, 243, 221, 245, 24, 23, 17, 251, 237, 225, 237, 0, 250, 243, 0, 20, 17, 21, 246, 216, 245, 30, 55, 242, 209, 2, 7, 27, 23, 248, 236, 219, 6, 19, 254, 47, 23, 250, 227, 207, 5, 12, 23, 13, 7, 0, 251, 249, 249, 250, 254, 0, 255, 251, 248, 248, 254, 5, 8, 12, 12, 255, 254, 13, 0, 243, 245, 247, 0, 0, 10, 14, 2, 250, 247, 251, 4, 1, 253, 243, 250, 4, 4, 255, 1, 2, 2, 1, 4, 0, 1, 255, 0, 3, 5, 7, 4, 5, 9, 5, 1, 0, 3, 4, 11, 8, 5, 0, 2, 3, 6, 4, 255, 255, 0, 1, 1, 1, 2, 8, 9, 6, 3, 252, 250, 248, 252, 5, 8, 5, 4, 0, 255, 252, 253, 251, 1, 7, 4, 0, 252, 254, 253, 1, 3, 2, 254, 0, 255, 252, 252, 255, 254, 1, 3, 253, 253, 0, 3, 255, 253, 2, 4, 4, 6, 2, 255, 249, 252, 4, 4, 8, 8, 3, 1, 255, 3, 254, 250, 0, 4, 6, 0, 252, 1, 255, 1, 1, 255, 248, 253, 2, 5, 9, 255, 247, 251, 251, 0, 10, 2, 251, 236, 250, 2, 7, 6, 0, 1, 11, 7, 5, 4, 3, 3, 245, 253, 6, 253, 0, 0, 254, 243, 244, 1, 5, 4, 251, 248, 247, 236, 249, 5, 6, 250, 252, 6, 12, 254, 248, 242, 245, 21, 37, 248, 234, 3, 248, 247, 20, 30, 246, 224, 0, 34, 13, 14, 239, 248, 10, 0, 16, 0, 3, 9, 253, 3, 3, 247, 244, 238, 23, 49, 1, 247, 225, 0, 29, 245, 1, 3, 253, 236, 249, 11, 14, 14, 13, 10, 10, 11, 10, 6, 254, 244, 240, 254, 13, 5, 254, 254, 18, 0, 4, 206, 237, 18, 253, 25, 241, 250, 1, 243, 32, 206, 6, 52, 241, 211, 219, 46, 28, 221, 18, 238, 221, 47, 39, 8, 197, 0, 239, 208, 39, 69, 254, 208, 241, 15, 5, 245, 0, 238, 41, 15, 190, 47, 15, 242, 226, 247, 28, 10, 22, 2, 230, 214, 17, 16, 46, 16, 161, 31, 46, 223, 245, 241, 64, 206, 19, 20, 216, 36, 208, 34, 18, 211, 27, 207, 62, 231, 221, 100, 183, 255, 41, 235, 242, 245, 100, 239, 150, 0, 52, 13, 16, 253, 8, 23, 0, 248, 15, 24, 206, 211, 226, 64, 40, 42, 23, 151, 194, 28, 50, 19, 214, 3, 19, 224, 241, 244, 45, 255, 230, 255, 24, 24, 245, 246, 213, 241, 46, 1, 232, 236, 30, 30, 5, 77, 20, 2, 57, 17, 35, 9, 250, 10, 221, 25, 21, 255, 15, 213, 226, 5, 241, 238, 208, 211, 12, 234, 0, 244, 188, 253, 26, 246, 211, 240, 21, 3, 6, 236, 225, 231, 233, 46, 49, 13, 243, 2, 34, 12, 243, 3, 0, 19, 54, 56, 13, 14, 10, 36, 8, 232, 1, 0, 252, 2, 4, 255, 228, 250, 246, 250, 244, 226, 235, 242, 236, 237, 213, 231, 10, 23, 242, 225, 242, 26, 5, 251, 250, 9, 8, 13, 8, 0, 1, 11, 18, 16, 9, 7, 12, 17, 14, 1, 245, 243, 22, 49, 38, 246, 247, 247, 7, 8, 253, 221, 229, 21, 10, 247, 240, 237, 9, 15, 232, 229, 252, 33, 22, 237, 1, 249, 228, 0, 14, 37, 4, 226, 21, 0, 214, 14, 41, 39, 4, 217, 243, 17, 22, 6, 243, 12, 15, 2, 18, 4, 219, 242, 254, 17, 31, 248, 246, 248, 252, 241, 253, 19, 2, 15, 252, 240, 253, 252, 247, 244, 5, 23, 12, 21, 217, 210, 0, 5, 39, 7, 239, 249, 248, 25, 0, 251, 240, 221, 36, 49, 14, 244, 224, 0, 10, 226, 247, 24, 9, 18, 10, 5, 250, 235, 5, 243, 1, 18, 250, 245, 250, 14, 15, 243, 244, 10, 12, 246, 229, 241, 23, 34, 253, 219, 213, 4, 52, 34, 27, 224, 233, 16, 247, 252, 21, 248, 233, 7, 3, 3, 237, 225, 12, 23, 26, 17, 251, 4, 243, 224, 235, 240, 22, 23, 29, 11, 212, 215, 28, 18, 12, 0, 248, 8, 237, 247, 250, 222, 23, 23, 23, 32, 229, 228, 248, 254, 28, 12, 253, 251, 227, 234, 38, 31, 9, 2, 230, 251, 0, 246, 26, 26, 10, 255, 234, 29, 39, 207, 213, 230, 7, 66, 19, 238, 242, 223, 247, 13, 25, 38, 6, 230, 233, 0, 0, 255, 239, 250, 0, 24, 36, 9, 239, 236, 255, 11, 12, 5, 2, 3, 5, 5, 5, 3, 4, 5, 2, 255, 248, 240, 242, 250, 5, 252, 39, 5, 213, 9, 20, 254, 237, 230, 50, 60, 240, 249, 3, 212, 244, 22, 2, 21, 239, 17, 27, 220, 228, 35, 6, 221, 239, 11, 52, 14, 210, 8, 25, 4, 229, 200, 38, 22, 236, 33, 5, 215, 207, 253, 52, 11, 254, 16, 227, 217, 5, 44, 244, 171, 225, 40, 27, 32, 35, 223, 212, 243, 28, 21, 223, 237, 5, 231, 235, 57, 72, 238, 166, 222, 248, 23, 45, 52, 14, 170, 252, 54, 249, 220, 198, 30, 43, 215, 18, 38, 19, 241, 245, 10, 211, 195, 55, 73, 250, 226, 0, 37, 226, 199, 47, 63, 212, 13, 46, 3, 32, 187, 236, 102, 1, 235, 10, 221, 66, 15, 169, 50, 213, 249, 117, 242, 244, 237, 221, 36, 9, 241, 19, 219, 246, 65, 218, 215, 27, 33, 13, 209, 13, 250, 225, 243, 75, 45, 191, 223, 223, 19, 33, 5, 66, 208, 188, 29, 11, 39, 246, 221, 38, 228, 2, 35, 229, 21, 243, 212, 79, 252, 229, 17, 240, 24, 201, 220, 82, 27, 215, 231, 7, 21, 243, 239, 18, 246, 235, 4, 251, 24, 243, 5, 6, 221, 5, 16, 23, 230, 247, 23, 251, 224, 228, 35, 41, 1, 237, 205, 20, 68, 243, 219, 235, 16, 31, 240, 243, 218, 225, 255, 11, 8, 1, 2, 7, 9, 7, 2, 253, 1, 14, 13, 2, 252, 7, 19, 239, 11, 11, 1, 251, 229, 18, 11, 1, 235, 22, 7, 230, 244, 28, 252, 24, 243, 252, 241, 12, 7, 34, 230, 239, 22, 239, 34, 249, 239, 246, 244, 29, 16, 252, 4, 0, 201, 16, 37, 247, 244, 6, 19, 251, 210, 247, 86, 250, 197, 239, 23, 42, 0, 221, 31, 246, 197, 22, 50, 14, 6, 207, 15, 7, 211, 47, 22, 245, 254, 216, 5, 4, 24, 48, 245, 175, 199, 75, 66, 45, 209, 179, 241, 241, 71, 92, 223, 203, 205, 16, 23, 255, 24, 23, 244, 242, 239, 242, 11, 2, 45, 254, 229, 205, 235, 84, 45, 222, 203, 220, 66, 2, 22, 25, 212, 243, 240, 11, 28, 236, 12, 36, 252, 231, 236, 228, 47, 31, 232, 232, 239, 8, 25, 10, 17, 200, 238, 35, 34, 35, 238, 224, 229, 222, 249, 57, 66, 23, 185, 189, 244, 58, 55, 226, 253, 5, 244, 8, 232, 0, 11, 21, 19, 203, 212, 50, 0, 36, 42, 231, 206, 207, 48, 45, 252, 236, 220, 42, 15, 3, 2, 201, 232, 73, 45, 247, 212, 239, 1, 1, 41, 2, 227, 234, 10, 30, 14, 241, 252, 17, 0, 236, 25, 236, 247, 29, 12, 250, 250, 233, 21, 5, 252, 251, 21, 17, 32, 210, 237, 229, 243, 13, 0, 252, 244, 241, 253, 5, 6, 5, 7, 11, 13, 6, 232, 205, 232, 45, 97, 10, 211, 208, 238, 35, 10, 11, 2, 231, 3, 38, 6, 246, 228, 220, 49, 29, 234, 224, 220, 12, 45, 49, 250, 185, 227, 22, 52, 49, 242, 178, 237, 22, 44, 11, 209, 247, 6, 227, 34, 25, 18, 243, 22, 67, 7, 202, 13, 60, 255, 229, 188, 253, 72, 10, 236, 231, 183, 255, 78, 30, 244, 193, 251, 14, 46, 49, 227, 207, 198, 34, 62, 5, 232, 245, 13, 236, 228, 0, 15, 237, 214, 233, 1, 3, 28, 249, 1, 253, 18, 17, 0, 6, 6, 241, 16, 0, 0, 4, 238, 255, 22, 31, 254, 202, 2, 26, 243, 13, 25, 20, 0, 193, 255, 20, 242, 27, 17, 246, 216, 224, 29, 50, 0, 240, 234, 228, 219, 40, 95, 19, 173, 225, 63, 42, 7, 0, 0, 241, 251, 19, 28, 240, 223, 238, 46, 39, 219, 201, 245, 13, 31, 11, 219, 195, 255, 51, 28, 214, 198, 7, 41, 37, 20, 254, 198, 208, 215, 52, 74, 36, 251, 191, 206, 20, 45, 54, 233, 241, 4, 19, 25, 17, 241, 235, 232, 1, 38, 36, 9, 253, 233, 211, 255, 49, 11, 222, 20, 56, 247, 208, 181, 243, 55, 21, 14, 23, 240, 212, 253, 24, 29, 33, 201, 225, 14, 39, 68, 254, 193, 212, 252, 20, 2, 252, 249, 248, 254, 1, 0, 255, 3, 10, 15, 12, 255, 243, 255, 11, 13, 242, 237, 202, 20, 88, 19, 223, 203, 213, 23, 26, 15, 41, 247, 204, 250, 243, 47, 44, 215, 205, 17, 11, 40, 4, 232, 253, 8, 235, 1, 14, 14, 7, 241, 11, 24, 2, 240, 241, 234, 218, 10, 87, 37, 227, 178, 202, 24, 65, 27, 253, 221, 204, 239, 40, 49, 21, 216, 202, 247, 11, 48, 44, 251, 203, 215, 7, 85, 29, 210, 171, 246, 63, 84, 225, 184, 250, 34, 254, 245, 248, 45, 19, 223, 227, 227, 50, 74, 13, 251, 185, 194, 38, 248, 15, 59, 253, 234, 196, 231, 127, 5, 228, 216, 209, 76, 19, 200, 255, 4, 8, 58, 210, 219, 11, 245, 92, 29, 225, 4, 195, 234, 69, 3, 225, 242, 15, 50, 231, 214, 10, 247, 219, 59, 59, 227, 199, 188, 53, 85, 245, 237, 218, 214, 44, 50, 237, 214, 13, 46, 14, 233, 251, 251, 242, 251, 37, 19, 216, 211, 22, 59, 26, 217, 229, 18, 22, 15, 252, 252, 243, 222, 243, 29, 41, 235, 214, 32, 32, 42, 226, 200, 8, 236, 39, 39, 239, 0, 8, 223, 237, 21, 43, 31, 236, 200, 19, 51, 22, 235, 217, 0, 6, 230, 31, 48, 24, 251, 201, 214, 27, 39, 17, 236, 207, 251, 48, 10, 248, 235, 2, 14, 247, 254, 0, 253, 253, 251, 249, 250, 252, 0, 9, 17, 21, 12, 250, 237, 233, 238, 250, 38, 249, 216, 245, 30, 43, 28, 189, 208, 21, 25, 37, 8, 213, 200, 220, 39, 66, 252, 242, 219, 248, 21, 13, 9, 12, 226, 193, 254, 61, 37, 230, 199, 234, 17, 50, 6, 254, 249, 221, 11, 36, 248, 245, 15, 11, 225, 225, 28, 59, 21, 232, 241, 228, 20, 28, 23, 4, 207, 218, 4, 37, 57, 240, 213, 0, 255, 16, 16, 0, 233, 245, 17, 15, 22, 252, 231, 15, 252, 228, 253, 10, 52, 41, 231, 244, 236, 211, 5, 29, 53, 24, 222, 207, 224, 30, 75, 14, 224, 220, 253, 48, 18, 202, 222, 46, 63, 0, 198, 209, 25, 47, 11, 227, 233, 6, 39, 16, 234, 246, 251, 240, 2, 252, 11, 46, 242, 211, 251, 37, 33, 243, 218, 251, 29, 0, 252, 251, 3, 248, 242, 21, 15, 6, 251, 239, 252, 252, 1, 5, 23, 8, 222, 232, 27, 30, 247, 228, 252, 13, 6, 19, 13, 244, 218, 229, 16, 36, 15, 1, 240, 1, 16, 11, 255, 255, 229, 250, 22, 0, 241, 23, 27, 13, 233, 217, 8, 25, 21, 14, 221, 246, 14, 19, 255, 245, 229, 240, 22, 37, 25, 242, 209, 244, 3, 17, 26, 240, 220, 234, 2, 48, 24, 235, 218, 224, 16, 39, 247, 246, 2, 17, 1, 244, 238, 241, 253, 7, 8, 1, 254, 4, 14, 16, 2, 241, 232, 253, 18, 32, 255, 210, 227, 10, 50, 2, 218, 240, 244, 36, 43, 242, 226, 222, 255, 35, 47, 253, 213, 216, 245, 33, 39, 16, 247, 238, 253, 10, 5, 15, 255, 231, 247, 6, 7, 5, 27, 3, 237, 7, 0, 0, 7, 12, 2, 237, 242, 11, 17, 24, 252, 217, 253, 19, 28, 6, 232, 239, 254, 247, 5, 18, 19, 3, 230, 6, 24, 233, 247, 28, 4, 241, 243, 11, 13, 4, 244, 249, 0, 252, 25, 25, 255, 231, 220, 16, 37, 250, 232, 238, 36, 33, 250, 1, 253, 226, 248, 6, 36, 5, 219, 234, 245, 10, 38, 16, 238, 211, 255, 32, 24, 252, 239, 232, 236, 0, 29, 11, 252, 242, 254, 24, 15, 248, 240, 243, 253, 1, 20, 7, 236, 240, 7, 15, 12, 6, 247, 4, 251, 255, 16, 254, 250, 255, 254, 0, 252, 16, 37, 13, 231, 236, 2, 21, 23, 6, 241, 245, 255, 18, 12, 246, 244, 10, 24, 10, 238, 242, 8, 18, 20, 13, 239, 240, 4, 13, 4, 250, 254, 16, 20, 0, 235, 246, 14, 27, 1, 248, 235, 241, 16, 17, 254, 243, 234, 238, 6, 27, 1, 245, 253, 7, 232, 233, 5, 254, 253, 12, 0, 248, 244, 6, 246, 220, 2, 9, 9, 18, 245, 242, 248, 249, 2, 3, 252, 247, 255, 8, 12, 10, 6, 2, 1, 6, 9, 6, 2, 247, 237, 230, 16, 251, 228, 31, 16, 245, 244, 235, 254, 252, 21, 62, 252, 208, 219, 221, 30, 71, 253, 213, 251, 18, 8, 238, 36, 36, 231, 212, 248, 232, 42, 78, 14, 181, 209, 40, 31, 234, 30, 59, 241, 182, 5, 28, 6, 235, 20, 38, 213, 202, 27, 53, 15, 10, 11, 225, 180, 21, 79, 30, 226, 207, 180, 234, 66, 83, 21, 196, 218, 241, 0, 32, 10, 1, 235, 187, 2, 67, 39, 231, 189, 235, 40, 51, 22, 205, 209, 13, 31, 10, 244, 220, 242, 32, 45, 18, 232, 218, 247, 21, 31, 23, 228, 210, 5, 54, 45, 246, 201, 235, 16, 40, 26, 248, 232, 245, 4, 18, 6, 247, 251, 14, 17, 15, 0, 250, 3, 15, 19, 10, 3, 11, 17, 19, 25, 15, 9, 19, 25, 18, 7, 17, 28, 23, 12, 9, 6, 5, 12, 20, 14, 255, 250, 0, 10, 10, 254, 242, 241, 247, 249, 249, 244, 244, 244, 247, 246, 233, 228, 242, 245, 237, 234, 227, 227, 241, 245, 236, 226, 240, 2, 255, 242, 233, 223, 230, 243, 254, 255, 250, 245, 231, 239, 23, 28, 245, 218, 235, 0, 8, 9, 14, 247, 236, 229, 252, 23, 28, 13, 246, 240, 0, 251, 4, 8, 1, 0, 254, 4, 0, 15, 17, 3, 253, 253, 250, 248, 249, 251, 252, 252, 2, 11, 19, 16, 6, 6, 15, 25, 3, 244, 18, 7, 0, 26, 44, 7, 222, 255, 32, 7, 25, 32, 230, 218, 20, 51, 16, 231, 222, 253, 55, 21, 219, 253, 32, 3, 239, 2, 242, 231, 12, 14, 8, 18, 247, 212, 246, 43, 12, 223, 251, 36, 2, 221, 240, 10, 19, 9, 240, 230, 252, 29, 29, 0, 231, 214, 242, 29, 31, 251, 230, 250, 4, 6, 21, 15, 1, 252, 251, 252, 252, 11, 12, 253, 252, 253, 249, 251, 10, 10, 7, 10, 18, 35, 55, 52, 27, 252, 0, 24, 28, 32, 32, 18, 9, 21, 36, 34, 25, 18, 9, 6, 10, 8, 244, 235, 0, 85, 0, 3, 0, 5, 0, 112, 0, 144, 1, 8, 7, 152, 8, 216, 14, 14, 18, 174, 21, 55, 2, 12, 14, 4, 4, 4, 3, 5, 5, 92, 165, 137, 137, 150, 175, 92, 165, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 112, 0, 144, 1, 8, 7, 152, 8, 216, 14, 14, 18, 174, 21, 30, 3, 14, 16, 5, 5, 5, 4, 6, 6, 92, 165, 137, 137, 150, 175, 92, 165, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 9, 0, 112, 0, 144, 1, 8, 7, 152, 8, 216, 14, 14, 18, 174, 21, 0, 3, 13, 15, 4, 4, 4, 3, 5, 5, 92, 165, 137, 137, 150, 175, 92, 165, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 240, 0, 5, 0, 1, 0, 184, 0, 72, 2, 172, 3, 20, 10, 164, 11, 53, 14, 160, 27, 45, 61, 26, 62, 74, 37, 35, 20, 13, 5, 173, 142, 135, 120, 120, 120, 182, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 184, 0, 72, 2, 172, 3, 20, 10, 164, 11, 53, 14, 160, 27, 75, 118, 36, 86, 103, 51, 49, 28, 18, 7, 173, 142, 135, 120, 120, 120, 182, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 184, 0, 52, 2, 158, 3, 240, 9, 168, 11, 61, 14, 192, 27, 60, 96, 33, 79, 91, 46, 43, 26, 16, 7, 172, 140, 135, 120, 120, 120, 182, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 192, 0, 120, 1, 32, 3, 172, 8, 204, 11, 141, 14, 224, 28, 60, 47, 27, 63, 39, 27, 18, 16, 8, 8, 162, 120, 135, 120, 120, 120, 117, 90, 180, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 176, 0, 104, 1, 32, 3, 92, 8, 204, 11, 141, 14, 224, 28, 0, 36, 23, 58, 38, 22, 15, 12, 9, 8, 152, 120, 97, 120, 120, 120, 107, 90, 97, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 144, 9, 55, 0, 0, 1, 1, 1, 1, 1, 2, 3, 3, 3, 1, 0, 2, 4, 3, 1, 1, 0, 0, 0, 1, 0, 255, 254, 255, 0, 1, 1, 0, 255, 254, 255, 255, 254, 254, 253, 251, 252, 253, 254, 0, 1, 1, 1, 2, 2, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 2, 3, 3, 3, 2, 3, 3, 3, 1, 0, 0, 255, 255, 0, 1, 0, 0, 255, 255, 255, 254, 253, 254, 0, 2, 3, 4, 4, 2, 0, 254, 253, 253, 253, 252, 251, 252, 255, 0, 0, 0, 1, 2, 2, 1, 0, 255, 254, 253, 252, 253, 255, 0, 1, 2, 3, 3, 2, 3, 3, 0, 255, 0, 0, 253, 251, 252, 254, 0, 3, 5, 4, 3, 3, 1, 0, 0, 1, 0, 253, 253, 255, 0, 0, 255, 254, 255, 0, 0, 0, 254, 254, 255, 255, 0, 0, 255, 0, 1, 1, 1, 4, 6, 1, 253, 254, 2, 8, 8, 5, 0, 255, 254, 254, 0, 2, 0, 255, 255, 1, 4, 6, 6, 4, 3, 2, 1, 0, 255, 254, 250, 246, 243, 245, 249, 0, 6, 11, 11, 6, 255, 250, 248, 249, 251, 251, 250, 249, 251, 2, 7, 6, 4, 5, 8, 11, 12, 8, 5, 2, 253, 245, 245, 249, 250, 251, 1, 10, 15, 17, 15, 5, 252, 251, 248, 241, 243, 251, 252, 251, 0, 2, 0, 253, 253, 252, 255, 4, 5, 0, 1, 4, 1, 250, 245, 245, 248, 1, 11, 15, 13, 8, 4, 0, 250, 249, 0, 4, 6, 11, 17, 16, 9, 1, 249, 243, 246, 253, 252, 250, 254, 4, 12, 14, 8, 0, 254, 0, 254, 248, 246, 246, 239, 238, 254, 14, 14, 1, 248, 247, 1, 14, 15, 4, 254, 252, 250, 252, 253, 248, 245, 0, 11, 11, 8, 11, 9, 3, 4, 9, 5, 250, 241, 241, 251, 10, 19, 10, 254, 253, 2, 7, 13, 11, 249, 232, 239, 0, 8, 10, 10, 5, 0, 252, 250, 250, 250, 246, 244, 0, 16, 18, 6, 255, 2, 8, 10, 4, 250, 244, 248, 251, 249, 252, 1, 0, 253, 2, 10, 12, 12, 13, 8, 255, 248, 246, 243, 241, 246, 252, 0, 8, 16, 16, 12, 10, 6, 254, 249, 253, 252, 244, 243, 249, 253, 255, 6, 13, 12, 10, 7, 4, 5, 7, 3, 246, 236, 245, 2, 6, 8, 8, 2, 255, 254, 253, 251, 253, 0, 253, 251, 255, 4, 8, 10, 4, 251, 253, 6, 6, 254, 250, 252, 0, 2, 0, 248, 252, 7, 5, 255, 7, 16, 0, 238, 243, 0, 8, 12, 6, 250, 252, 11, 14, 5, 1, 1, 252, 247, 249, 250, 249, 252, 254, 252, 0, 15, 20, 9, 251, 245, 248, 255, 1, 253, 248, 1, 10, 5, 254, 254, 0, 254, 254, 2, 11, 15, 5, 247, 242, 248, 0, 2, 1, 0, 3, 4, 4, 6, 2, 245, 242, 0, 10, 1, 253, 0, 252, 246, 0, 14, 11, 255, 247, 244, 244, 254, 3, 253, 248, 252, 255, 2, 12, 13, 0, 247, 249, 253, 1, 10, 12, 254, 237, 238, 250, 254, 1, 11, 14, 8, 10, 17, 12, 254, 246, 244, 243, 249, 3, 7, 5, 2, 255, 254, 5, 7, 6, 12, 18, 4, 241, 245, 6, 1, 239, 242, 9, 18, 4, 247, 245, 251, 2, 4, 3, 8, 6, 246, 239, 0, 16, 8, 251, 247, 247, 255, 19, 33, 16, 243, 235, 246, 0, 5, 3, 253, 251, 1, 4, 2, 8, 13, 1, 244, 252, 10, 6, 253, 2, 11, 5, 251, 253, 8, 13, 6, 254, 248, 243, 237, 236, 251, 14, 19, 16, 13, 9, 0, 247, 245, 251, 0, 0, 253, 254, 6, 12, 11, 1, 244, 239, 250, 7, 12, 7, 4, 2, 255, 247, 245, 0, 6, 251, 242, 255, 16, 19, 6, 245, 235, 240, 1, 20, 26, 14, 242, 225, 235, 249, 1, 17, 31, 15, 240, 236, 0, 11, 3, 249, 248, 2, 15, 17, 6, 251, 243, 234, 236, 4, 32, 29, 5, 255, 3, 254, 247, 0, 9, 2, 252, 1, 0, 233, 219, 236, 8, 28, 32, 16, 248, 245, 5, 2, 241, 240, 250, 250, 1, 23, 22, 246, 226, 236, 251, 6, 20, 17, 247, 240, 14, 31, 10, 242, 238, 240, 238, 249, 16, 23, 6, 250, 3, 23, 32, 17, 246, 233, 240, 244, 242, 246, 0, 9, 15, 19, 19, 4, 244, 244, 250, 243, 234, 248, 20, 22, 1, 254, 2, 249, 237, 243, 255, 254, 251, 2, 10, 7, 5, 4, 253, 247, 251, 251, 244, 252, 6, 254, 246, 11, 31, 17, 248, 239, 247, 8, 26, 15, 241, 238, 1, 254, 235, 255, 29, 5, 213, 219, 12, 42, 38, 17, 245, 231, 243, 255, 1, 4, 251, 224, 226, 10, 34, 17, 13, 30, 13, 236, 243, 11, 8, 238, 218, 225, 255, 24, 20, 2, 0, 10, 16, 27, 28, 255, 219, 221, 255, 20, 6, 234, 225, 248, 22, 28, 7, 248, 254, 4, 251, 243, 6, 30, 19, 240, 227, 248, 6, 1, 247, 243, 251, 13, 32, 33, 8, 238, 237, 253, 249, 232, 251, 26, 16, 247, 0, 17, 4, 242, 249, 1, 255, 1, 8, 9, 17, 16, 247, 234, 255, 250, 215, 231, 36, 45, 253, 240, 11, 4, 222, 219, 250, 9, 11, 21, 14, 252, 251, 251, 234, 227, 248, 17, 23, 20, 13, 250, 237, 250, 12, 252, 226, 243, 16, 12, 3, 21, 21, 248, 240, 254, 248, 237, 0, 19, 6, 252, 8, 8, 250, 255, 2, 238, 230, 251, 10, 5, 7, 25, 30, 14, 246, 228, 225, 238, 5, 19, 10, 246, 233, 242, 14, 41, 35, 251, 211, 215, 11, 51, 29, 239, 227, 239, 235, 229, 249, 23, 37, 14, 244, 4, 37, 18, 229, 231, 253, 232, 209, 245, 35, 26, 247, 243, 17, 42, 29, 5, 6, 9, 236, 211, 235, 7, 252, 248, 33, 58, 29, 248, 244, 10, 15, 234, 204, 237, 22, 2, 226, 246, 33, 46, 26, 251, 231, 241, 6, 3, 244, 252, 2, 242, 237, 252, 0, 255, 15, 26, 12, 3, 3, 246, 237, 255, 12, 254, 249, 13, 11, 236, 236, 14, 24, 3, 2, 27, 31, 252, 212, 216, 253, 8, 246, 251, 35, 62, 43, 7, 233, 218, 235, 253, 230, 214, 255, 44, 32, 5, 11, 23, 15, 0, 230, 196, 220, 24, 26, 236, 234, 14, 12, 247, 2, 20, 17, 28, 28, 232, 192, 232, 24, 5, 225, 235, 3, 5, 14, 37, 35, 6, 242, 242, 242, 241, 0, 32, 40, 3, 229, 245, 5, 240, 226, 0, 30, 22, 3, 3, 14, 13, 247, 214, 211, 3, 50, 30, 247, 11, 42, 0, 198, 213, 3, 13, 254, 248, 0, 20, 48, 39, 251, 236, 254, 237, 204, 225, 17, 27, 4, 248, 241, 250, 33, 64, 36, 239, 221, 239, 4, 9, 252, 242, 242, 247, 248, 246, 4, 31, 35, 12, 0, 7, 10, 254, 236, 229, 242, 254, 252, 2, 20, 15, 249, 252, 14, 4, 240, 254, 20, 254, 222, 240, 24, 19, 236, 223, 0, 28, 17, 255, 13, 37, 15, 215, 195, 231, 18, 25, 12, 5, 6, 8, 8, 6, 255, 246, 247, 0, 254, 238, 239, 14, 31, 6, 245, 5, 11, 252, 0, 14, 254, 233, 249, 11, 0, 240, 250, 9, 12, 4, 253, 3, 19, 11, 245, 244, 251, 240, 237, 6, 20, 3, 243, 237, 243, 14, 34, 23, 5, 1, 247, 238, 1, 20, 254, 226, 244, 14, 0, 237, 1, 29, 22, 1, 0, 7, 5, 250, 243, 240, 241, 0, 13, 8, 245, 228, 239, 30, 63, 18, 210, 224, 27, 41, 2, 230, 240, 3, 252, 227, 237, 16, 25, 9, 255, 254, 252, 2, 17, 2, 216, 213, 12, 54, 39, 2, 237, 239, 6, 21, 250, 221, 250, 24, 3, 253, 23, 11, 211, 199, 255, 44, 45, 24, 248, 216, 225, 9, 22, 0, 253, 20, 5, 207, 216, 54, 74, 208, 156, 32, 126, 27, 176, 223, 44, 32, 230, 203, 234, 31, 37, 250, 239, 18, 27, 3, 255, 244, 211, 233, 32, 18, 229, 250, 36, 17, 245, 6, 23, 248, 212, 224, 7, 23, 7, 251, 1, 5, 0, 11, 30, 5, 225, 247, 33, 7, 211, 231, 34, 25, 209, 198, 36, 79, 248, 193, 8, 62, 254, 189, 224, 25, 15, 230, 231, 21, 53, 30, 242, 238, 8, 2, 235, 253, 20, 0, 240, 3, 252, 206, 218, 41, 68, 15, 250, 20, 14, 233, 217, 217, 213, 239, 38, 51, 3, 228, 249, 17, 15, 9, 6, 254, 249, 248, 233, 221, 244, 23, 21, 255, 4, 26, 28, 12, 251, 236, 227, 232, 253, 9, 2, 249, 246, 2, 30, 37, 12, 251, 4, 4, 233, 207, 212, 252, 35, 30, 0, 3, 38, 27, 238, 235, 13, 9, 225, 219, 3, 29, 17, 253, 237, 222, 234, 23, 66, 66, 27, 231, 201, 216, 241, 231, 219, 2, 72, 95, 45, 236, 205, 218, 231, 223, 240, 23, 37, 24, 4, 241, 228, 240, 11, 17, 4, 6, 13, 8, 0, 243, 224, 221, 238, 255, 3, 20, 56, 56, 9, 232, 221, 200, 188, 233, 40, 52, 31, 16, 255, 228, 212, 224, 9, 59, 62, 251, 195, 224, 22, 14, 228, 234, 15, 19, 0, 254, 16, 35, 25, 239, 208, 229, 16, 23, 253, 246, 8, 8, 250, 253, 0, 1, 30, 49, 0, 183, 182, 252, 42, 14, 230, 247, 35, 44, 9, 228, 213, 223, 1, 33, 30, 255, 225, 222, 247, 18, 27, 21, 25, 37, 24, 233, 190, 198, 242, 20, 34, 32, 12, 241, 236, 2, 17, 13, 17, 32, 12, 201, 170, 229, 48, 53, 1, 235, 11, 39, 12, 223, 225, 12, 23, 241, 219, 246, 11, 255, 242, 4, 32, 34, 14, 8, 16, 247, 198, 201, 8, 46, 6, 229, 22, 67, 10, 184, 204, 36, 71, 35, 247, 226, 214, 202, 217, 14, 75, 87, 42, 250, 219, 201, 204, 247, 45, 38, 238, 217, 239, 242, 233, 17, 74, 60, 254, 216, 227, 248, 244, 230, 239, 10, 14, 1, 11, 24, 9, 250, 24, 67, 33, 190, 141, 193, 18, 57, 57, 29, 253, 247, 247, 238, 242, 11, 37, 26, 241, 216, 240, 5, 223, 186, 245, 93, 106, 9, 204, 243, 26, 8, 234, 220, 218, 238, 21, 39, 18, 7, 27, 24, 243, 222, 240, 16, 22, 248, 218, 233, 18, 26, 253, 247, 23, 29, 242, 228, 26, 65, 4, 170, 171, 0, 65, 54, 10, 236, 228, 234, 252, 41, 79, 44, 215, 160, 181, 247, 48, 60, 30, 7, 9, 18, 1, 217, 197, 231, 35, 62, 36, 246, 216, 219, 233, 236, 3, 42, 48, 19, 252, 0, 11, 248, 205, 193, 238, 38, 57, 35, 250, 217, 221, 4, 39, 30, 251, 245, 14, 12, 230, 223, 253, 251, 215, 231, 56, 102, 45, 216, 200, 238, 2, 5, 12, 6, 243, 232, 240, 1, 24, 28, 12, 12, 13, 247, 229, 236, 237, 229, 250, 25, 22, 254, 246, 252, 0, 7, 29, 33, 253, 205, 190, 226, 31, 58, 25, 240, 244, 11, 20, 24, 18, 236, 201, 219, 253, 12, 21, 22, 0, 240, 251, 6, 13, 32, 39, 7, 222, 221, 245, 252, 247, 250, 3, 18, 31, 26, 254, 221, 213, 243, 28, 39, 10, 231, 214, 228, 3, 28, 23, 6, 11, 15, 0, 253, 7, 238, 198, 225, 45, 66, 19, 240, 229, 220, 229, 5, 28, 29, 28, 22, 1, 230, 209, 218, 9, 49, 35, 245, 228, 242, 249, 3, 30, 34, 6, 244, 251, 0, 245, 227, 223, 251, 13, 1, 1, 21, 16, 245, 242, 9, 17, 9, 12, 6, 235, 222, 238, 237, 224, 11, 74, 49, 226, 214, 21, 55, 16, 216, 216, 5, 11, 221, 205, 4, 56, 34, 251, 11, 33, 254, 208, 225, 14, 23, 254, 222, 210, 240, 35, 49, 20, 6, 10, 248, 221, 240, 24, 21, 234, 209, 228, 10, 26, 7, 5, 51, 71, 11, 194, 179, 219, 14, 44, 45, 22, 247, 214, 191, 228, 62, 106, 55, 238, 217, 211, 198, 216, 8, 43, 45, 32, 13, 242, 230, 236, 233, 235, 20, 68, 52, 241, 200, 203, 222, 253, 30, 48, 52, 42, 251, 176, 164, 238, 49, 51, 27, 19, 8, 251, 243, 224, 217, 6, 61, 39, 221, 214, 18, 30, 255, 252, 10, 251, 222, 239, 47, 80, 30, 204, 168, 190, 226, 9, 74, 112, 58, 213, 169, 207, 242, 239, 255, 46, 71, 28, 221, 195, 213, 12, 59, 47, 2, 239, 251, 250, 227, 228, 3, 30, 27, 7, 253, 1, 4, 254, 250, 255, 252, 243, 250, 8, 6, 253, 250, 248, 253, 19, 35, 12, 230, 222, 245, 0, 246, 249, 4, 8, 12, 24, 27, 10, 237, 215, 223, 4, 32, 10, 223, 229, 16, 26, 255, 2, 32, 20, 231, 215, 247, 21, 16, 243, 228, 245, 15, 19, 0, 246, 10, 30, 24, 11, 249, 207, 168, 192, 17, 80, 78, 22, 225, 216, 233, 0, 27, 48, 33, 239, 201, 210, 240, 255, 251, 7, 38, 58, 41, 254, 226, 240, 1, 248, 235, 243, 251, 249, 6, 22, 8, 251, 19, 42, 21, 246, 238, 237, 231, 240, 8, 15, 5, 255, 246, 248, 21, 46, 29, 249, 239, 249, 250, 237, 223, 226, 253, 34, 53, 38, 2, 234, 234, 249, 9, 18, 3, 229, 219, 248, 16, 18, 17, 17, 254, 231, 247, 25, 23, 239, 211, 222, 248, 7, 15, 22, 23, 9, 238, 229, 5, 39, 25, 239, 227, 244, 250, 241, 249, 20, 34, 20, 251, 242, 1, 15, 4, 245, 244, 255, 6, 0, 239, 231, 1, 38, 44, 21, 249, 236, 241, 243, 236, 245, 20, 31, 253, 222, 238, 16, 25, 17, 16, 8, 247, 243, 247, 245, 245, 253, 2, 8, 21, 24, 5, 247, 250, 250, 236, 239, 10, 25, 8, 240, 231, 238, 253, 8, 9, 6, 9, 12, 0, 231, 227, 252, 13, 9, 8, 9, 0, 245, 247, 252, 254, 2, 9, 2, 249, 255, 16, 23, 17, 4, 241, 223, 230, 7, 28, 15, 252, 247, 255, 6, 7, 11, 15, 5, 239, 229, 244, 3, 3, 0, 6, 7, 249, 240, 250, 10, 20, 18, 0, 231, 220, 236, 11, 28, 16, 1, 0, 4, 247, 226, 234, 15, 44, 32, 0, 238, 238, 8, 7, 88, 0, 0, 0, 0, 0, 0, 0, 255, 0, 2, 2, 0, 255, 254, 253, 254, 0, 4, 8, 8, 5, 1, 0, 254, 254, 0, 1, 2, 1, 255, 254, 254, 0, 1, 2, 2, 1, 0, 0, 0, 255, 0, 0, 2, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 1, 3, 5, 9, 18, 26, 21, 254, 230, 223, 231, 248, 4, 10, 14, 12, 1, 251, 251, 0, 0, 255, 255, 0, 255, 252, 252, 4, 13, 14, 8, 0, 245, 231, 224, 234, 1, 23, 26, 17, 7, 3, 3, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 255, 255, 0, 0, 0, 1, 2, 2, 1, 255, 254, 254, 0, 2, 3, 1, 255, 254, 254, 0, 2, 6, 8, 7, 3, 0, 253, 253, 254, 255, 0, 3, 3, 0, 255, 0, 0, 0, 0, 1, 1, 0, 255, 0, 1, 0, 255, 0, 2, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 7, 13, 15, 6, 247, 235, 236, 246, 1, 9, 14, 13, 7, 254, 250, 251, 253, 255, 0, 2, 4, 3, 1, 0, 0, 255, 252, 252, 254, 0, 0, 255, 255, 0, 1, 3, 5, 6, 6, 3, 0, 253, 253, 254, 255, 255, 0, 0, 0, 1, 5, 9, 6, 255, 251, 252, 0, 2, 1, 0, 0, 4, 7, 4, 252, 246, 248, 255, 5, 9, 6, 255, 249, 250, 1, 15, 35, 51, 47, 20, 246, 225, 214, 219, 241, 13, 27, 16, 255, 247, 252, 0, 253, 252, 255, 245, 229, 247, 23, 13, 233, 234, 11, 17, 244, 228, 243, 0, 249, 228, 223, 251, 22, 24, 23, 23, 1, 232, 240, 11, 13, 253, 251, 0, 1, 6, 17, 18, 4, 251, 7, 15, 252, 242, 7, 22, 7, 244, 249, 7, 11, 6, 3, 2, 4, 255, 238, 227, 248, 21, 16, 241, 239, 20, 35, 251, 215, 240, 22, 18, 242, 233, 252, 249, 228, 246, 32, 23, 238, 242, 16, 17, 253, 240, 245, 4, 6, 243, 246, 24, 29, 250, 231, 252, 24, 10, 229, 237, 21, 15, 233, 236, 16, 28, 11, 244, 245, 7, 3, 240, 251, 27, 27, 243, 225, 253, 19, 7, 0, 19, 22, 238, 203, 235, 40, 41, 241, 220, 246, 13, 22, 5, 233, 239, 13, 18, 249, 236, 255, 16, 10, 249, 241, 246, 246, 244, 10, 40, 23, 229, 222, 5, 18, 0, 247, 0, 14, 4, 232, 239, 25, 31, 251, 238, 0, 13, 10, 244, 242, 25, 43, 254, 207, 226, 20, 37, 13, 250, 3, 27, 16, 220, 207, 255, 25, 15, 14, 23, 6, 233, 220, 236, 27, 44, 250, 206, 230, 18, 29, 22, 0, 224, 220, 247, 26, 35, 10, 241, 224, 219, 244, 36, 46, 12, 250, 246, 234, 238, 255, 253, 248, 25, 53, 1, 179, 199, 42, 68, 254, 220, 1, 20, 248, 231, 253, 14, 3, 1, 20, 19, 246, 221, 241, 37, 35, 221, 192, 251, 49, 35, 0, 242, 242, 242, 239, 249, 15, 30, 28, 8, 220, 195, 1, 69, 16, 190, 221, 65, 80, 243, 190, 242, 30, 255, 221, 9, 75, 46, 209, 183, 241, 18, 250, 243, 25, 45, 254, 192, 232, 64, 53, 234, 205, 241, 30, 20, 231, 232, 25, 40, 238, 188, 232, 53, 58, 7, 227, 211, 212, 4, 61, 44, 247, 237, 242, 223, 240, 39, 47, 253, 214, 225, 3, 28, 23, 6, 0, 242, 230, 255, 34, 27, 0, 245, 226, 203, 240, 65, 86, 6, 174, 182, 23, 78, 10, 190, 212, 20, 39, 23, 7, 243, 227, 246, 22, 17, 247, 252, 37, 31, 193, 177, 54, 117, 7, 203, 30, 47, 191, 164, 39, 126, 29, 169, 209, 38, 15, 223, 29, 106, 46, 184, 176, 5, 29, 232, 235, 55, 67, 228, 176, 0, 67, 10, 203, 245, 33, 249, 222, 10, 22, 231, 229, 27, 34, 236, 208, 239, 16, 8, 237, 235, 1, 16, 10, 255, 250, 5, 29, 28, 245, 215, 237, 23, 26, 0, 7, 37, 21, 221, 213, 15, 54, 23, 234, 241, 24, 24, 238, 214, 242, 28, 36, 11, 248, 241, 232, 226, 244, 14, 23, 14, 247, 228, 245, 12, 248, 213, 247, 66, 45, 184, 148, 8, 106, 41, 190, 222, 68, 44, 191, 198, 56, 86, 250, 194, 242, 32, 8, 229, 0, 50, 47, 242, 197, 236, 49, 45, 246, 231, 0, 6, 1, 5, 6, 9, 11, 239, 205, 244, 59, 31, 197, 213, 54, 54, 227, 224, 25, 15, 226, 242, 18, 13, 6, 4, 230, 220, 19, 41, 245, 241, 36, 14, 219, 249, 38, 3, 219, 2, 39, 255, 229, 20, 46, 248, 205, 249, 50, 27, 217, 218, 29, 42, 220, 183, 11, 73, 10, 207, 246, 46, 10, 176, 206, 71, 74, 237, 237, 46, 7, 175, 220, 81, 74, 220, 197, 12, 29, 244, 246, 22, 22, 247, 225, 241, 18, 35, 20, 234, 215, 245, 21, 25, 18, 4, 234, 245, 26, 4, 226, 9, 48, 247, 196, 253, 52, 25, 249, 251, 237, 232, 7, 32, 25, 238, 192, 211, 35, 79, 35, 220, 180, 208, 32, 73, 32, 236, 224, 225, 240, 12, 22, 27, 28, 252, 218, 235, 15, 11, 243, 249, 18, 24, 9, 248, 236, 240, 9, 24, 6, 238, 245, 19, 23, 240, 220, 3, 35, 18, 241, 227, 247, 21, 25, 2, 244, 222, 197, 248, 83, 78, 238, 184, 221, 8, 11, 10, 34, 40, 236, 190, 241, 45, 19, 240, 23, 48, 228, 177, 255, 70, 23, 205, 206, 9, 37, 11, 255, 11, 249, 214, 243, 48, 35, 230, 230, 6, 250, 239, 14, 38, 27, 255, 246, 6, 0, 228, 233, 21, 28, 243, 244, 40, 35, 229, 208, 244, 30, 40, 3, 214, 219, 15, 35, 251, 229, 12, 42, 13, 215, 209, 19, 39, 224, 205, 18, 46, 0, 227, 255, 20, 5, 252, 253, 245, 241, 248, 11, 36, 29, 244, 218, 239, 19, 24, 6, 254, 244, 232, 244, 12, 17, 5, 0, 250, 242, 6, 31, 4, 212, 224, 15, 12, 240, 4, 28, 253, 225, 252, 26, 0, 214, 232, 25, 25, 244, 241, 18, 25, 248, 225, 246, 28, 32, 244, 218, 3, 34, 242, 202, 1, 57, 19, 230, 241, 249, 238, 7, 28, 2, 245, 1, 247, 229, 0, 37, 21, 242, 238, 241, 242, 9, 28, 14, 243, 215, 220, 14, 59, 48, 250, 197, 189, 245, 53, 48, 2, 237, 233, 228, 246, 22, 33, 27, 1, 227, 229, 1, 14, 1, 250, 3, 12, 10, 4, 250, 241, 252, 16, 14, 246, 235, 2, 27, 8, 222, 231, 23, 35, 4, 233, 237, 6, 21, 10, 253, 245, 218, 217, 35, 90, 32, 198, 193, 246, 13, 3, 15, 38, 7, 203, 206, 18, 37, 247, 252, 47, 16, 185, 206, 54, 65, 240, 197, 240, 36, 27, 255, 6, 11, 233, 222, 19, 51, 3, 221, 250, 4, 238, 252, 30, 35, 9, 243, 253, 7, 239, 218, 252, 35, 8, 231, 10, 49, 9, 212, 223, 14, 45, 25, 227, 203, 243, 32, 12, 224, 244, 38, 35, 244, 211, 249, 49, 8, 201, 243, 56, 33, 228, 233, 18, 17, 251, 251, 253, 241, 236, 253, 30, 42, 6, 222, 224, 4, 27, 20, 9, 249, 223, 226, 12, 30, 6, 249, 4, 2, 244, 8, 28, 241, 204, 242, 28, 19, 2, 9, 6, 236, 232, 8, 33, 5, 216, 221, 14, 29, 253, 246, 23, 20, 222, 198, 0, 68, 47, 214, 206, 30, 32, 210, 232, 81, 74, 228, 202, 243, 249, 248, 24, 39, 17, 238, 207, 222, 27, 62, 28, 233, 219, 227, 239, 19, 47, 16, 227, 215, 239, 20, 41, 29, 0, 227, 215, 232, 13, 33, 17, 1, 6, 244, 220, 253, 50, 38, 232, 208, 240, 8, 5, 12, 29, 15, 237, 226, 255, 23, 17, 0, 250, 252, 254, 247, 246, 18, 49, 20, 211, 211, 22, 42, 251, 236, 2, 250, 230, 252, 34, 34, 0, 231, 235, 251, 3, 14, 25, 5, 219, 230, 31, 37, 243, 228, 15, 37, 254, 219, 248, 33, 14, 228, 241, 23, 7, 227, 246, 27, 5, 227, 255, 36, 0, 212, 254, 52, 25, 228, 217, 239, 6, 15, 17, 23, 17, 237, 216, 4, 48, 8, 211, 242, 27, 249, 213, 1, 40, 1, 230, 10, 28, 240, 218, 252, 4, 234, 245, 18, 10, 1, 17, 6, 217, 220, 28, 48, 249, 211, 224, 0, 25, 26, 5, 1, 21, 13, 229, 229, 30, 50, 245, 196, 226, 16, 23, 22, 34, 25, 245, 217, 221, 248, 26, 45, 18, 225, 212, 248, 20, 17, 18, 23, 1, 224, 218, 246, 16, 20, 9, 252, 243, 247, 5, 9, 1, 7, 16, 255, 220, 216, 5, 48, 37, 247, 222, 236, 9, 23, 11, 247, 242, 0, 10, 0, 244, 252, 7, 8, 0, 248, 252, 3, 5, 255, 250, 2, 9, 246, 231, 249, 16, 9, 250, 0, 12, 5, 243, 237, 251, 13, 10, 246, 246, 11, 9, 237, 240, 22, 42, 23, 249, 228, 225, 248, 25, 31, 8, 251, 252, 250, 254, 16, 28, 10, 238, 231, 247, 5, 14, 10, 254, 249, 253, 248, 246, 6, 20, 1, 235, 243, 3, 253, 237, 244, 13, 27, 11, 244, 232, 229, 246, 20, 33, 16, 248, 242, 247, 243, 239, 255, 26, 32, 12, 245, 231, 241, 11, 22, 11, 0, 250, 237, 242, 13, 24, 8, 255, 7, 4, 245, 247, 9, 14, 3, 251, 246, 240, 246, 12, 25, 18, 2, 249, 244, 247, 255, 3, 6, 12, 12, 254, 236, 242, 4, 11, 9, 12, 8, 249, 236, 240, 0, 15, 16, 6, 2, 4, 255, 242, 243, 6, 18, 12, 2, 254, 252, 251, 255, 2, 2, 0, 0, 2, 4, 0, 253, 1, 8, 1, 246, 248, 5, 9, 0, 248, 248, 249, 246, 250, 6, 10, 253, 238, 240, 251, 1, 4, 3, 255, 252, 252, 253, 0, 2, 0, 253, 254, 2, 8, 12, 5, 249, 248, 3, 11, 11, 13, 13, 252, 235, 244, 9, 18, 13, 7, 3, 254, 248, 246, 252, 3, 6, 3, 255, 254, 253, 252, 253, 2, 6, 2, 250, 244, 242, 244, 251, 0, 253, 248, 254, 5, 3, 255, 0, 0, 249, 243, 245, 253, 6, 10, 6, 0, 254, 254, 3, 12, 11, 1, 248, 244, 247, 3, 15, 16, 11, 8, 8, 7, 5, 6, 4, 251, 244, 249, 1, 5, 6, 11, 13, 6, 0, 0, 254, 250, 249, 248, 249, 251, 0, 4, 7, 10, 10, 122, 6, 55, 0, 253, 254, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 254, 255, 0, 2, 1, 0, 254, 253, 0, 6, 7, 5, 2, 255, 250, 255, 9, 11, 2, 253, 0, 3, 2, 255, 0, 4, 3, 3, 1, 255, 0, 4, 1, 254, 3, 7, 0, 248, 248, 254, 4, 9, 5, 253, 248, 250, 255, 8, 9, 250, 243, 253, 4, 2, 255, 254, 255, 253, 252, 255, 5, 8, 5, 0, 251, 248, 253, 10, 15, 6, 247, 237, 248, 5, 6, 4, 3, 252, 245, 249, 0, 5, 12, 11, 254, 248, 0, 6, 1, 251, 250, 255, 9, 14, 252, 236, 251, 9, 13, 12, 248, 235, 1, 25, 11, 251, 253, 251, 250, 5, 10, 6, 8, 255, 231, 233, 7, 28, 26, 2, 234, 243, 23, 37, 20, 4, 246, 233, 240, 0, 11, 17, 9, 235, 228, 247, 252, 8, 25, 12, 244, 238, 244, 249, 13, 30, 10, 236, 230, 238, 248, 11, 21, 5, 245, 245, 249, 250, 254, 7, 24, 27, 251, 221, 238, 15, 18, 11, 13, 0, 239, 247, 7, 8, 7, 2, 250, 4, 10, 246, 240, 9, 28, 16, 250, 236, 235, 252, 20, 26, 4, 239, 241, 254, 4, 10, 12, 253, 232, 241, 13, 17, 0, 252, 245, 238, 13, 31, 0, 236, 238, 245, 4, 20, 10, 7, 20, 253, 222, 242, 16, 15, 8, 6, 248, 244, 255, 254, 253, 3, 8, 14, 14, 249, 230, 245, 2, 254, 5, 23, 23, 3, 232, 219, 241, 21, 34, 24, 1, 223, 212, 253, 41, 38, 11, 242, 220, 230, 16, 37, 15, 245, 227, 228, 8, 42, 30, 252, 226, 218, 249, 40, 30, 252, 4, 3, 222, 230, 27, 28, 253, 1, 1, 223, 224, 14, 34, 23, 7, 239, 219, 228, 3, 39, 47, 252, 192, 213, 19, 48, 42, 3, 195, 202, 45, 73, 252, 213, 244, 6, 253, 251, 13, 29, 13, 230, 225, 2, 29, 26, 249, 211, 232, 44, 58, 250, 199, 205, 1, 61, 50, 237, 209, 243, 2, 255, 28, 53, 0, 201, 223, 1, 23, 39, 25, 3, 12, 19, 253, 0, 43, 59, 26, 235, 219, 245, 2, 239, 227, 246, 251, 247, 9, 7, 229, 220, 247, 10, 21, 21, 246, 239, 24, 8, 184, 204, 51, 53, 249, 218, 188, 194, 27, 90, 29, 214, 235, 16, 5, 0, 12, 7, 27, 50, 3, 195, 222, 33, 46, 32, 6, 221, 205, 244, 68, 82, 250, 192, 220, 3, 31, 48, 11, 211, 227, 1, 240, 245, 25, 12, 235, 246, 250, 232, 252, 13, 253, 24, 60, 215, 132, 252, 115, 83, 234, 156, 175, 8, 67, 41, 247, 245, 11, 1, 255, 4, 235, 234, 20, 48, 40, 5, 222, 216, 245, 12, 41, 73, 27, 214, 209, 212, 236, 60, 99, 28, 197, 184, 226, 40, 62, 0, 223, 248, 254, 234, 242, 16, 7, 235, 255, 12, 239, 250, 16, 244, 231, 1, 252, 245, 43, 55, 249, 219, 217, 230, 28, 76, 36, 212, 203, 251, 21, 2, 242, 17, 40, 8, 219, 208, 240, 29, 55, 39, 241, 200, 218, 10, 49, 57, 0, 189, 205, 13, 59, 49, 234, 173, 228, 62, 51, 10, 5, 233, 203, 234, 21, 29, 39, 25, 220, 199, 252, 27, 6, 255, 250, 242, 10, 16, 237, 244, 45, 43, 251, 235, 224, 230, 18, 41, 23, 250, 228, 229, 11, 42, 27, 2, 222, 191, 223, 31, 54, 34, 1, 215, 221, 23, 29, 0, 11, 15, 232, 207, 231, 11, 45, 50, 1, 210, 225, 18, 27, 250, 233, 251, 9, 0, 235, 248, 52, 50, 224, 198, 247, 31, 34, 255, 209, 217, 20, 44, 33, 26, 248, 204, 226, 30, 40, 1, 218, 209, 8, 66, 30, 224, 237, 17, 2, 237, 243, 8, 26, 252, 209, 232, 35, 57, 24, 238, 215, 220, 252, 23, 12, 5, 25, 0, 209, 229, 34, 51, 33, 255, 199, 196, 252, 27, 33, 25, 247, 218, 239, 19, 32, 27, 251, 217, 227, 255, 22, 42, 26, 234, 240, 26, 3, 232, 0, 11, 11, 8, 229, 199, 249, 53, 38, 11, 253, 219, 208, 251, 26, 29, 49, 22, 192, 184, 26, 76, 26, 226, 194, 220, 40, 67, 22, 228, 208, 221, 17, 61, 41, 252, 217, 210, 246, 33, 33, 0, 243, 9, 13, 223, 202, 0, 67, 61, 247, 205, 221, 244, 24, 56, 23, 233, 244, 4, 235, 248, 20, 245, 239, 11, 255, 239, 11, 11, 228, 237, 4, 240, 238, 29, 54, 2, 190, 193, 2, 69, 84, 11, 199, 212, 230, 251, 48, 64, 17, 241, 237, 220, 240, 40, 47, 22, 248, 224, 244, 15, 11, 0, 255, 246, 5, 55, 42, 217, 170, 199, 25, 86, 52, 217, 188, 0, 40, 0, 245, 18, 255, 240, 0, 234, 225, 7, 30, 20, 5, 235, 203, 228, 37, 48, 2, 229, 223, 241, 35, 53, 21, 250, 233, 229, 255, 32, 32, 5, 231, 218, 1, 39, 24, 22, 24, 237, 208, 241, 19, 13, 16, 13, 242, 243, 17, 2, 226, 253, 21, 242, 214, 235, 1, 14, 33, 28, 249, 227, 232, 254, 23, 19, 241, 226, 239, 245, 7, 36, 32, 252, 213, 203, 6, 87, 43, 199, 216, 12, 16, 28, 47, 25, 1, 247, 201, 197, 12, 54, 50, 17, 208, 192, 27, 76, 255, 220, 252, 239, 239, 47, 35, 198, 212, 25, 34, 34, 14, 202, 186, 5, 32, 248, 242, 3, 20, 38, 19, 224, 227, 21, 28, 1, 222, 206, 5, 57, 20, 240, 3, 255, 227, 3, 36, 33, 30, 233, 165, 208, 70, 121, 70, 235, 153, 163, 254, 58, 69, 40, 220, 161, 217, 49, 43, 14, 33, 4, 170, 175, 24, 65, 18, 236, 213, 225, 45, 57, 214, 188, 26, 57, 236, 204, 232, 0, 40, 80, 39, 221, 212, 239, 2, 26, 34, 2, 231, 238, 242, 252, 27, 51, 48, 3, 201, 198, 251, 35, 36, 12, 227, 221, 16, 35, 6, 3, 6, 225, 210, 3, 31, 21, 5, 233, 222, 255, 45, 64, 26, 204, 155, 196, 21, 56, 50, 24, 220, 179, 234, 69, 87, 22, 194, 161, 222, 61, 78, 15, 234, 242, 240, 236, 6, 32, 24, 253, 219, 203, 245, 60, 81, 42, 8, 242, 207, 212, 4, 23, 25, 25, 237, 191, 237, 60, 45, 234, 216, 248, 13, 253, 230, 237, 13, 31, 16, 251, 249, 5, 7, 241, 216, 232, 13, 12, 5, 20, 7, 240, 5, 28, 253, 230, 245, 243, 245, 9, 30, 41, 12, 228, 225, 248, 30, 57, 14, 191, 191, 14, 56, 47, 33, 0, 217, 230, 32, 57, 29, 252, 237, 240, 5, 31, 36, 33, 18, 232, 196, 216, 5, 14, 248, 229, 233, 247, 242, 232, 234, 241, 254, 0, 234, 217, 224, 232, 247, 32, 45, 3, 229, 226, 243, 22, 44, 24, 245, 227, 233, 21, 70, 55, 0, 228, 238, 14, 48, 42, 0, 231, 245, 9, 18, 22, 15, 0, 250, 252, 241, 228, 249, 23, 23, 2, 234, 222, 239, 11, 22, 3, 238, 238, 251, 254, 245, 246, 3, 10, 0, 246, 2, 23, 13, 239, 235, 3, 18, 11, 2, 4, 2, 249, 247, 10, 28, 17, 250, 235, 241, 4, 15, 8, 255, 253, 0, 7, 7, 248, 243, 4, 14, 9, 6, 4, 251, 249, 3, 13, 14, 8, 252, 240, 242, 3, 14, 5, 253, 1, 5, 6, 12, 7, 239, 228, 245, 6, 9, 3, 248, 239, 250, 7, 0, 245, 251, 0, 250, 247, 248, 247, 253, 11, 19, 5, 235, 231, 0, 22, 20, 5, 241, 230, 255, 28, 24, 10, 1, 253, 255, 252, 249, 0, 10, 16, 16, 7, 251, 255, 8, 5, 0, 1, 255, 254, 3, 6, 253, 242, 242, 253, 10, 19, 8, 239, 223, 230, 247, 6, 23, 22, 4, 249, 241, 240, 0, 22, 20, 252, 235, 241, 3, 21, 24, 11, 247, 231, 235, 11, 35, 20, 250, 237, 240, 2, 21, 27, 21, 13, 255, 231, 222, 246, 25, 34, 11, 236, 222, 236, 11, 33, 19, 239, 217, 232, 13, 36, 20, 240, 224, 243, 17, 27, 15, 3, 249, 243, 251, 2, 0, 1, 9, 14, 10, 253, 238, 239, 4, 25, 24, 7, 251, 252, 252, 249, 251, 8, 24, 24, 2, 229, 221, 242, 14, 26, 9, 241, 237, 252, 7, 8, 255, 248, 254, 5, 9, 12, 6, 246, 228, 230, 3, 31, 26, 255, 231, 227, 244, 10, 21, 15, 3, 249, 242, 243, 251, 6, 12, 1, 241, 242, 253, 0, 255, 249, 244, 253, 5, 6, 0, 247, 246, 255, 1, 252, 254, 7, 9, 3, 253, 249, 250, 0, 6, 6, 3, 2, 1, 255, 2, 11, 15, 11, 9, 6, 0, 0, 5, 8, 10, 7, 0, 254, 0, 4, 7, 5, 0, 252, 251, 255, 3, 2, 0, 255, 0, 255, 254, 253, 253, 254, 255, 0, 0, 0, 0, 3, 1, 252, 250, 255, 4, 7, 6, 1, 254, 255, 4, 10, 10, 6, 1, 0, 3, 8, 12, 12, 12, 6, 255, 0, 3, 3, 4, 6, 3, 253, 248, 252, 2, 7, 8, 2, 251, 253, 0, 251, 244, 251, 6, 6, 0, 248, 246, 252, 1, 254, 246, 242, 248, 8, 13, 254, 244, 243, 246, 0, 12, 19, 15, 253, 231, 227, 246, 17, 32, 17, 240, 223, 238, 3, 12, 11, 6, 0, 251, 251, 3, 10, 0, 241, 239, 255, 21, 23, 252, 226, 224, 247, 20, 29, 14, 254, 247, 250, 254, 253, 2, 18, 27, 14, 246, 234, 247, 7, 15, 11, 4, 0, 0, 255, 247, 245, 0, 14, 22, 21, 0, 229, 231, 8, 34, 25, 246, 218, 229, 7, 32, 22, 246, 223, 230, 2, 29, 31, 3, 227, 223, 0, 0, 60, 0, 3, 0, 5, 0, 176, 0, 248, 1, 176, 4, 192, 8, 48, 12, 210, 15, 96, 27, 60, 2, 16, 5, 3, 1, 0, 0, 0, 0, 210, 75, 120, 120, 120, 120, 120, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 176, 0, 248, 1, 176, 4, 192, 8, 48, 12, 210, 15, 96, 27, 0, 11, 35, 12, 8, 3, 1, 1, 1, 0, 210, 75, 120, 120, 120, 120, 120, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 176, 0, 248, 1, 176, 4, 192, 8, 48, 12, 210, 15, 96, 27, 0, 11, 35, 12, 8, 3, 1, 1, 1, 0, 210, 75, 120, 120, 120, 120, 120, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 52, 3, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 4, 7, 13, 21, 16, 235, 225, 4, 24, 254, 238, 0, 14, 0, 243, 2, 13, 254, 247, 11, 17, 255, 251, 7, 9, 5, 2, 4, 0, 251, 0, 5, 1, 253, 254, 0, 0, 249, 254, 3, 1, 255, 253, 253, 252, 247, 242, 7, 16, 255, 2, 26, 30, 218, 217, 27, 25, 228, 218, 26, 92, 34, 201, 216, 21, 41, 254, 232, 31, 59, 222, 164, 0, 79, 91, 225, 131, 243, 104, 75, 234, 182, 9, 69, 38, 233, 212, 247, 18, 20, 249, 218, 254, 25, 9, 234, 237, 3, 13, 4, 239, 249, 9, 12, 243, 3, 11, 10, 17, 13, 15, 254, 234, 229, 249, 25, 19, 230, 226, 16, 13, 245, 249, 17, 2, 4, 252, 248, 255, 21, 33, 226, 222, 19, 30, 22, 26, 252, 241, 247, 35, 24, 221, 241, 21, 17, 7, 0, 27, 32, 51, 47, 19, 239, 18, 28, 6, 225, 254, 5, 244, 230, 9, 7, 7, 2, 5, 6, 12, 246, 245, 12, 10, 235, 214, 14, 21, 252, 7, 24, 254, 15, 45, 16, 208, 227, 7, 0, 219, 217, 22, 51, 4, 248, 30, 14, 2, 19, 15, 242, 219, 249, 33, 238, 230, 16, 17, 245, 245, 34, 24, 224, 240, 51, 27, 223, 237, 17, 15, 251, 8, 33, 24, 4, 25, 19, 253, 4, 9, 254, 251, 245, 12, 0, 237, 2, 21, 255, 8, 31, 250, 248, 16, 6, 245, 248, 248, 12, 15, 249, 250, 9, 5, 3, 2, 4, 255, 252, 251, 252, 1, 251, 245, 1, 20, 0, 251, 10, 7, 246, 12, 18, 245, 245, 9, 0, 245, 255, 253, 238, 240, 5, 7, 251, 239, 0, 255, 254, 248, 252, 9, 245, 238, 14, 6, 240, 0, 16, 9, 1, 5, 14, 1, 252, 20, 12, 240, 5, 26, 2, 247, 13, 19, 251, 0, 20, 255, 0, 15, 255, 252, 3, 3, 7, 252, 248, 252, 8, 254, 6, 4, 253, 9, 11, 250, 241, 0, 6, 250, 2, 2, 248, 6, 13, 252, 242, 6, 5, 254, 251, 248, 14, 13, 241, 253, 6, 251, 241, 250, 0, 248, 242, 3, 254, 242, 0, 251, 244, 237, 240, 249, 254, 240, 237, 242, 237, 239, 245, 238, 236, 1, 224, 244, 230, 234, 242, 241, 238, 240, 249, 227, 252, 4, 211, 17, 252, 240, 0, 8, 250, 249, 5, 3, 250, 4, 9, 4, 8, 23, 11, 11, 14, 18, 14, 255, 19, 17, 6, 10, 25, 17, 10, 21, 12, 1, 14, 14, 1, 13, 17, 4, 5, 13, 10, 241, 19, 0, 245, 16, 0, 0, 1, 255, 8, 247, 6, 5, 7, 239, 16, 251, 244, 255, 0, 254, 247, 0, 5, 249, 2, 4, 246, 2, 5, 1, 252, 1, 253, 9, 1, 3, 253, 16, 4, 14, 9, 2, 11, 14, 4, 5, 18, 14, 6, 20, 16, 3, 19, 24, 8, 11, 20, 14, 10, 10, 15, 10, 5, 18, 18, 254, 17, 27, 0, 13, 22, 1, 9, 20, 9, 3, 11, 27, 6, 7, 30, 255, 7, 20, 247, 0, 5, 6, 7, 12, 246, 9, 244, 245, 8, 232, 246, 251, 247, 226, 250, 235, 236, 250, 245, 236, 237, 6, 234, 231, 250, 235, 243, 5, 250, 229, 14, 234, 237, 3, 217, 237, 12, 221, 252, 25, 233, 244, 29, 184, 13, 1, 201, 33, 226, 0, 14, 235, 253, 245, 246, 255, 254, 238, 237, 0, 238, 239, 247, 255, 241, 20, 18, 244, 21, 25, 242, 20, 7, 12, 23, 28, 7, 8, 31, 22, 11, 24, 5, 18, 15, 22, 2, 245, 10, 4, 239, 14, 253, 236, 20, 0, 249, 254, 19, 243, 4, 8, 233, 5, 0, 236, 6, 227, 4, 4, 243, 244, 0, 233, 248, 253, 228, 232, 236, 250, 230, 237, 252, 235, 238, 254, 237, 227, 0, 244, 228, 5, 234, 237, 247, 246, 230, 249, 238, 250, 254, 234, 0, 255, 248, 8, 0, 239, 14, 17, 255, 22, 9, 9, 32, 18, 14, 28, 28, 16, 33, 18, 7, 23, 29, 14, 12, 24, 19, 21, 24, 10, 14, 16, 24, 14, 7, 21, 21, 14, 18, 17, 9, 18, 18, 17, 3, 15, 11, 0, 8, 0, 0, 7, 1, 0, 254, 251, 6, 0, 246, 8, 247, 254, 5, 247, 2, 247, 2, 2, 250, 4, 1, 240, 244, 253, 254, 240, 10, 250, 235, 249, 239, 244, 220, 252, 227, 233, 244, 246, 221, 228, 2, 216, 222, 248, 225, 210, 11, 241, 213, 4, 244, 193, 218, 234, 177, 215, 248, 193, 205, 225, 226, 214, 206, 1, 205, 211, 31, 224, 211, 32, 13, 232, 49, 47, 14, 52, 83, 38, 38, 78, 66, 32, 60, 52, 11, 40, 46, 10, 14, 29, 21, 19, 14, 24, 0, 3, 0, 5, 0, 116, 0, 232, 0, 240, 5, 176, 9, 152, 13, 60, 15, 124, 21, 25, 3, 12, 8, 4, 4, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 116, 0, 232, 0, 240, 5, 176, 9, 152, 13, 60, 15, 124, 21, 0, 3, 12, 8, 4, 4, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 116, 0, 232, 0, 240, 5, 176, 9, 152, 13, 60, 15, 124, 21, 0, 3, 12, 8, 4, 4, 4, 4, 0, 0, 200, 212, 187, 255, 255, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 219, 11, 36, 0, 7, 17, 19, 225, 216, 254, 31, 13, 216, 207, 17, 33, 10, 243, 229, 3, 15, 238, 228, 235, 33, 49, 231, 196, 4, 51, 235, 175, 11, 48, 5, 236, 241, 241, 15, 13, 230, 226, 14, 25, 243, 241, 6, 250, 8, 247, 239, 250, 26, 19, 216, 234, 44, 11, 226, 0, 19, 245, 247, 1, 255, 14, 11, 239, 1, 4, 231, 0, 33, 21, 242, 237, 5, 229, 244, 45, 15, 223, 0, 13, 226, 250, 35, 5, 2, 10, 211, 255, 49, 252, 251, 6, 28, 30, 252, 213, 220, 8, 20, 14, 11, 254, 0, 5, 2, 251, 242, 248, 37, 12, 245, 8, 0, 229, 252, 1, 234, 10, 16, 10, 13, 228, 222, 22, 38, 252, 210, 243, 36, 252, 227, 22, 38, 233, 246, 2, 237, 8, 31, 244, 238, 17, 8, 229, 213, 8, 67, 9, 187, 227, 35, 34, 215, 224, 42, 44, 247, 206, 227, 24, 54, 229, 215, 14, 31, 11, 243, 222, 0, 45, 9, 221, 236, 8, 25, 24, 241, 226, 10, 31, 229, 230, 18, 28, 11, 241, 213, 242, 39, 5, 239, 10, 251, 236, 7, 22, 255, 0, 4, 251, 0, 9, 251, 253, 238, 226, 19, 42, 14, 238, 0, 238, 231, 245, 23, 50, 11, 233, 252, 12, 230, 234, 29, 49, 3, 209, 226, 26, 48, 249, 228, 34, 37, 211, 200, 18, 53, 34, 240, 229, 0, 37, 254, 206, 250, 78, 44, 196, 221, 36, 22, 243, 230, 252, 32, 32, 244, 239, 249, 14, 252, 234, 13, 39, 238, 231, 6, 250, 253, 252, 232, 11, 51, 0, 202, 219, 35, 30, 210, 230, 42, 9, 238, 251, 255, 22, 10, 214, 224, 17, 32, 15, 235, 252, 24, 251, 213, 28, 33, 238, 13, 13, 238, 1, 20, 246, 249, 2, 14, 19, 254, 233, 248, 28, 9, 5, 0, 230, 230, 6, 21, 19, 27, 242, 229, 245, 2, 250, 39, 36, 228, 222, 25, 1, 218, 15, 37, 235, 17, 20, 215, 238, 15, 253, 253, 14, 37, 5, 220, 220, 21, 21, 1, 234, 253, 37, 3, 191, 10, 57, 240, 236, 21, 230, 244, 33, 235, 228, 18, 24, 250, 242, 223, 3, 44, 5, 238, 246, 4, 13, 231, 237, 44, 65, 223, 196, 6, 51, 19, 220, 227, 52, 39, 237, 204, 255, 33, 247, 223, 14, 22, 251, 241, 238, 238, 13, 30, 0, 240, 255, 6, 247, 243, 12, 1, 7, 25, 246, 250, 15, 251, 230, 255, 30, 25, 237, 225, 11, 19, 240, 254, 17, 21, 1, 215, 219, 71, 59, 224, 212, 6, 19, 8, 244, 7, 25, 2, 227, 251, 254, 8, 31, 14, 182, 241, 44, 12, 1, 252, 240, 1, 18, 248, 216, 5, 41, 239, 243, 37, 234, 209, 16, 53, 218, 230, 52, 8, 193, 247, 50, 26, 238, 239, 0, 28, 38, 219, 185, 31, 81, 249, 201, 19, 40, 230, 204, 251, 52, 54, 1, 201, 208, 27, 37, 241, 251, 35, 5, 227, 218, 235, 62, 45, 214, 214, 25, 28, 220, 212, 46, 61, 220, 206, 13, 27, 12, 237, 0, 15, 27, 253, 231, 15, 17, 250, 233, 3, 2, 16, 15, 0, 234, 7, 11, 235, 7, 14, 248, 236, 254, 30, 22, 235, 236, 251, 13, 13, 247, 230, 8, 12, 1, 14, 10, 6, 245, 223, 26, 51, 223, 229, 36, 249, 239, 26, 25, 248, 0, 242, 238, 9, 35, 0, 235, 26, 7, 223, 253, 33, 251, 240, 4, 2, 29, 28, 227, 228, 13, 252, 242, 255, 32, 51, 235, 200, 254, 26, 244, 255, 22, 8, 251, 237, 5, 18, 253, 244, 21, 13, 4, 249, 240, 0, 7, 19, 9, 234, 247, 8, 244, 223, 19, 55, 24, 203, 212, 17, 12, 244, 22, 24, 0, 254, 231, 233, 14, 36, 6, 231, 252, 29, 252, 233, 0, 235, 0, 44, 234, 230, 35, 8, 212, 233, 21, 24, 246, 210, 10, 45, 3, 230, 216, 26, 40, 235, 235, 32, 26, 242, 233, 253, 15, 27, 5, 3, 228, 245, 20, 254, 240, 22, 11, 7, 30, 242, 208, 11, 18, 239, 18, 49, 2, 209, 240, 254, 8, 15, 28, 5, 248, 231, 235, 6, 25, 6, 245, 237, 230, 18, 18, 228, 2, 25, 244, 221, 1, 22, 28, 252, 218, 252, 5, 252, 23, 232, 224, 51, 24, 224, 7, 8, 231, 10, 17, 10, 31, 251, 192, 230, 48, 26, 236, 1, 22, 244, 226, 247, 246, 39, 53, 215, 197, 31, 41, 245, 234, 245, 27, 34, 251, 219, 249, 31, 243, 228, 38, 46, 227, 231, 242, 241, 31, 57, 250, 196, 245, 20, 26, 0, 1, 15, 244, 228, 220, 13, 25, 15, 9, 238, 243, 6, 246, 234, 10, 15, 5, 249, 250, 253, 0, 5, 243, 236, 14, 48, 240, 222, 5, 4, 16, 12, 238, 0, 30, 239, 228, 15, 20, 13, 8, 231, 218, 27, 56, 252, 217, 238, 16, 36, 247, 220, 18, 35, 237, 210, 235, 48, 55, 251, 210, 249, 4, 229, 228, 45, 57, 7, 245, 223, 226, 229, 247, 27, 67, 10, 225, 1, 222, 235, 27, 29, 4, 255, 247, 238, 237, 16, 43, 0, 251, 250, 255, 234, 251, 15, 35, 18, 245, 231, 248, 15, 255, 248, 242, 35, 29, 252, 215, 234, 12, 19, 250, 220, 5, 20, 244, 244, 17, 19, 20, 192, 207, 51, 21, 223, 9, 23, 246, 250, 234, 232, 13, 29, 21, 239, 227, 13, 18, 228, 252, 33, 3, 250, 230, 226, 16, 39, 1, 248, 250, 4, 0, 232, 255, 47, 232, 213, 40, 52, 221, 206, 13, 30, 6, 231, 238, 23, 35, 251, 206, 9, 29, 244, 236, 11, 33, 17, 221, 175, 3, 80, 11, 227, 11, 0, 223, 252, 2, 252, 28, 34, 247, 203, 232, 42, 52, 232, 210, 38, 56, 227, 209, 29, 37, 211, 247, 72, 11, 205, 241, 2, 1, 26, 38, 13, 248, 204, 229, 54, 36, 218, 10, 57, 204, 194, 15, 35, 7, 24, 242, 214, 9, 0, 232, 14, 25, 17, 16, 232, 194, 245, 22, 17, 4, 11, 7, 224, 254, 249, 235, 21, 31, 233, 245, 25, 233, 238, 40, 2, 229, 12, 42, 226, 212, 19, 46, 243, 3, 22, 208, 246, 53, 246, 228, 22, 35, 244, 208, 23, 41, 239, 228, 0, 15, 0, 14, 255, 229, 8, 12, 249, 232, 11, 41, 234, 187, 14, 69, 240, 225, 10, 3, 221, 243, 33, 24, 250, 2, 250, 223, 9, 27, 12, 28, 237, 201, 254, 40, 3, 11, 253, 218, 16, 21, 240, 5, 244, 247, 8, 246, 10, 42, 9, 212, 220, 24, 33, 9, 225, 6, 14, 252, 245, 247, 22, 30, 239, 234, 18, 243, 2, 36, 216, 249, 70, 241, 206, 37, 252, 237, 56, 2, 207, 16, 21, 249, 0, 233, 15, 13, 208, 2, 77, 14, 210, 228, 253, 4, 1, 23, 20, 5, 219, 205, 2, 43, 24, 255, 217, 252, 15, 4, 11, 247, 227, 0, 253, 255, 10, 12, 253, 0, 32, 250, 222, 240, 1, 21, 21, 241, 255, 36, 254, 194, 238, 29, 26, 10, 19, 15, 233, 209, 4, 28, 15, 11, 251, 247, 252, 250, 8, 23, 0, 4, 240, 222, 16, 24, 9, 26, 2, 222, 234, 9, 22, 5, 248, 32, 21, 224, 241, 1, 14, 9, 249, 251, 24, 12, 222, 250, 16, 29, 15, 207, 239, 69, 8, 199, 7, 254, 247, 42, 243, 181, 40, 84, 209, 178, 18, 68, 16, 223, 223, 35, 42, 227, 200, 18, 81, 241, 210, 42, 27, 210, 235, 247, 19, 53, 6, 188, 238, 66, 23, 192, 216, 28, 65, 234, 229, 33, 26, 240, 247, 245, 242, 32, 43, 237, 237, 23, 15, 253, 17, 0, 223, 0, 34, 16, 21, 25, 247, 216, 221, 11, 61, 30, 242, 233, 238, 6, 8, 20, 22, 255, 221, 227, 16, 26, 11, 16, 244, 216, 245, 3, 3, 34, 38, 240, 191, 247, 21, 254, 21, 48, 227, 170, 0, 71, 246, 228, 14, 238, 219, 21, 20, 253, 33, 251, 205, 1, 19, 12, 7, 252, 2, 234, 225, 14, 21, 13, 26, 223, 213, 19, 3, 13, 53, 234, 207, 14, 254, 243, 41, 20, 222, 35, 2, 196, 232, 58, 67, 239, 213, 34, 34, 191, 215, 45, 33, 23, 36, 223, 199, 36, 13, 212, 4, 59, 14, 196, 231, 12, 207, 9, 85, 241, 187, 0, 247, 2, 45, 242, 226, 43, 0, 189, 251, 22, 5, 13, 0, 250, 15, 237, 214, 7, 14, 31, 19, 195, 225, 63, 13, 191, 255, 18, 11, 252, 209, 5, 63, 242, 190, 49, 27, 231, 238, 208, 10, 75, 0, 205, 9, 29, 32, 219, 174, 48, 81, 238, 203, 29, 42, 249, 209, 225, 13, 31, 10, 11, 17, 5, 217, 209, 6, 29, 31, 0, 242, 10, 253, 234, 243, 23, 44, 245, 220, 14, 9, 239, 34, 27, 229, 238, 4, 17, 11, 253, 3, 250, 219, 252, 55, 32, 211, 242, 59, 13, 201, 224, 46, 44, 222, 242, 34, 28, 213, 223, 54, 255, 195, 19, 63, 0, 224, 0, 20, 244, 18, 8, 239, 6, 3, 231, 12, 41, 16, 212, 254, 44, 239, 241, 250, 233, 38, 51, 224, 209, 25, 45, 233, 214, 234, 19, 49, 236, 215, 37, 16, 219, 225, 2, 48, 43, 252, 221, 217, 0, 17, 250, 250, 43, 26, 205, 195, 26, 46, 245, 229, 73, 66, 159, 165, 68, 48, 233, 251, 231, 36, 77, 191, 151, 53, 92, 238, 221, 32, 60, 252, 203, 218, 6, 76, 94, 3, 186, 9, 27, 228, 240, 52, 62, 20, 181, 215, 72, 25, 240, 13, 21, 12, 229, 203, 13, 90, 33, 229, 210, 246, 19, 246, 232, 38, 81, 5, 205, 196, 242, 35, 2, 6, 33, 248, 212, 216, 245, 48, 69, 6, 194, 220, 33, 34, 26, 254, 239, 6, 43, 241, 192, 37, 72, 237, 225, 41, 12, 226, 244, 236, 3, 34, 1, 222, 15, 62, 229, 166, 5, 86, 250, 177, 18, 52, 234, 225, 245, 13, 30, 227, 234, 40, 11, 192, 231, 18, 33, 251, 225, 44, 31, 175, 205, 28, 232, 0, 92, 17, 190, 207, 25, 6, 225, 9, 29, 249, 231, 215, 252, 54, 0, 196, 236, 12, 245, 244, 24, 18, 233, 205, 237, 43, 26, 229, 211, 240, 31, 3, 252, 5, 239, 249, 240, 208, 54, 61, 196, 226, 36, 245, 204, 14, 5, 0, 14, 233, 252, 8, 251, 249, 252, 216, 19, 51, 14, 229, 197, 234, 56, 42, 250, 251, 5, 216, 236, 28, 255, 255, 42, 27, 200, 195, 49, 61, 211, 220, 35, 13, 231, 249, 50, 35, 204, 217, 29, 28, 248, 234, 13, 28, 251, 213, 9, 68, 236, 208, 13, 9, 10, 22, 250, 226, 236, 58, 23, 211, 250, 34, 195, 213, 86, 52, 219, 205, 0, 24, 26, 248, 233, 249, 8, 22, 237, 6, 37, 250, 231, 223, 2, 77, 30, 181, 210, 43, 19, 254, 253, 6, 27, 246, 167, 2, 95, 12, 177, 5, 50, 0, 225, 208, 238, 35, 45, 9, 208, 220, 47, 251, 178, 12, 69, 23, 240, 196, 251, 78, 254, 163, 249, 73, 11, 202, 228, 38, 38, 233, 241, 4, 11, 8, 242, 220, 19, 46, 250, 238, 250, 9, 250, 222, 240, 50, 61, 242, 199, 253, 33, 243, 233, 13, 60, 15, 217, 211, 25, 72, 7, 189, 3, 63, 251, 210, 17, 29, 241, 253, 36, 249, 234, 21, 248, 202, 35, 114, 34, 177, 208, 6, 15, 25, 41, 18, 251, 5, 221, 211, 31, 21, 231, 32, 42, 214, 212, 3, 22, 61, 238, 205, 47, 16, 157, 234, 89, 47, 243, 246, 240, 241, 3, 246, 235, 49, 58, 230, 184, 251, 13, 238, 26, 16, 192, 5, 75, 251, 165, 3, 61, 20, 234, 2, 13, 3, 230, 3, 40, 5, 221, 24, 24, 191, 245, 61, 30, 246, 207, 2, 12, 10, 13, 4, 243, 254, 239, 219, 43, 21, 238, 38, 248, 183, 29, 56, 204, 14, 37, 215, 242, 40, 234, 215, 47, 35, 218, 224, 1, 251, 253, 31, 15, 237, 28, 2, 178, 36, 60, 201, 252, 59, 244, 11, 16, 220, 18, 47, 236, 6, 6, 247, 44, 15, 161, 228, 106, 40, 183, 219, 53, 63, 187, 199, 64, 47, 238, 233, 204, 43, 117, 226, 164, 27, 75, 234, 197, 222, 48, 72, 233, 223, 22, 252, 194, 214, 50, 75, 215, 173, 49, 71, 198, 192, 18, 60, 246, 203, 236, 38, 50, 16, 225, 186, 3, 97, 1, 150, 228, 84, 57, 192, 191, 30, 35, 186, 217, 57, 37, 230, 240, 208, 212, 22, 20, 255, 23, 8, 245, 191, 179, 33, 84, 250, 242, 254, 207, 224, 229, 248, 77, 52, 193, 203, 23, 3, 0, 235, 251, 71, 242, 160, 11, 44, 253, 230, 221, 78, 69, 147, 150, 97, 91, 202, 195, 234, 1, 20, 20, 36, 28, 244, 199, 204, 0, 54, 24, 31, 52, 229, 169, 251, 27, 23, 54, 39, 195, 218, 46, 7, 249, 51, 17, 222, 8, 61, 235, 227, 49, 10, 5, 65, 255, 180, 30, 83, 221, 226, 97, 31, 172, 0, 32, 32, 46, 234, 225, 20, 22, 245, 237, 31, 40, 229, 199, 39, 50, 218, 243, 50, 2, 198, 252, 38, 36, 227, 206, 29, 99, 8, 175, 1, 71, 244, 203, 62, 47, 218, 233, 1, 233, 10, 69, 5, 209, 209, 11, 23, 6, 222, 13, 72, 211, 136, 32, 115, 202, 161, 79, 87, 207, 157, 14, 77, 7, 211, 249, 4, 30, 249, 179, 251, 76, 249, 190, 24, 16, 252, 27, 244, 229, 29, 23, 238, 255, 38, 18, 206, 213, 66, 95, 236, 164, 253, 82, 0, 137, 9, 119, 5, 173, 255, 16, 5, 17, 200, 201, 124, 106, 142, 160, 70, 25, 206, 253, 51, 56, 247, 169, 210, 47, 53, 240, 228, 6, 15, 215, 221, 4, 24, 39, 243, 190, 10, 66, 247, 223, 228, 22, 52, 242, 194, 5, 69, 9, 220, 210, 254, 57, 27, 210, 221, 33, 19, 219, 221, 60, 41, 225, 7, 56, 248, 236, 209, 234, 70, 64, 234, 13, 22, 231, 230, 11, 5, 40, 40, 217, 223, 0, 236, 15, 54, 254, 225, 251, 11, 208, 212, 72, 65, 211, 213, 43, 234, 211, 24, 24, 0, 33, 251, 189, 245, 23, 18, 19, 223, 206, 44, 60, 206, 181, 23, 88, 230, 156, 47, 71, 193, 200, 20, 29, 22, 234, 245, 10, 245, 244, 30, 226, 233, 48, 13, 224, 219, 254, 35, 4, 251, 32, 37, 203, 186, 255, 29, 21, 16, 36, 4, 209, 179, 30, 95, 6, 216, 11, 17, 218, 219, 21, 45, 253, 6, 37, 235, 188, 0, 36, 251, 238, 25, 7, 224, 251, 20, 214, 213, 58, 43, 208, 211, 6, 5, 250, 246, 12, 22, 0, 210, 217, 27, 34, 249, 9, 27, 233, 248, 250, 224, 6, 79, 17, 228, 9, 235, 215, 25, 42, 249, 252, 31, 234, 153, 243, 105, 42, 229, 5, 237, 232, 253, 249, 27, 79, 6, 183, 243, 63, 7, 239, 251, 16, 237, 236, 30, 1, 198, 10, 34, 213, 250, 44, 223, 230, 18, 229, 255, 42, 230, 242, 33, 4, 206, 245, 56, 65, 243, 178, 216, 44, 61, 255, 185, 29, 76, 186, 137, 44, 90, 0, 192, 245, 17, 244, 253, 33, 248, 231, 39, 10, 195, 248, 61, 35, 244, 218, 1, 254, 223, 231, 61, 72, 226, 157, 228, 68, 52, 199, 216, 62, 62, 233, 209, 246, 34, 250, 249, 39, 17, 190, 232, 11, 22, 29, 23, 5, 226, 0, 23, 254, 244, 54, 50, 249, 222, 241, 14, 16, 244, 248, 27, 29, 244, 244, 31, 10, 211, 228, 44, 34, 212, 240, 25, 7, 2, 255, 250, 14, 8, 228, 226, 9, 33, 30, 0, 191, 220, 25, 18, 241, 248, 44, 12, 201, 199, 28, 36, 7, 251, 219, 220, 22, 252, 216, 39, 67, 235, 217, 252, 11, 6, 15, 234, 239, 59, 42, 178, 210, 68, 24, 200, 6, 56, 18, 247, 223, 196, 40, 97, 250, 213, 25, 29, 213, 218, 32, 70, 21, 210, 220, 3, 1, 250, 243, 26, 52, 228, 212, 32, 43, 223, 235, 41, 21, 254, 249, 232, 232, 36, 34, 220, 239, 26, 7, 218, 236, 33, 29, 232, 229, 253, 13, 14, 239, 235, 27, 41, 250, 199, 243, 44, 19, 214, 233, 54, 253, 203, 240, 20, 11, 250, 230, 10, 44, 230, 209, 13, 35, 249, 230, 249, 16, 9, 245, 251, 11, 17, 7, 211, 225, 31, 29, 7, 253, 230, 233, 15, 16, 1, 8, 241, 238, 8, 250, 251, 32, 19, 226, 226, 254, 19, 35, 0, 232, 232, 248, 22, 254, 237, 4, 14, 253, 244, 248, 10, 22, 238, 235, 22, 36, 0, 253, 243, 242, 27, 32, 3, 8, 7, 250, 239, 13, 42, 2, 215, 245, 11, 26, 28, 251, 226, 12, 25, 233, 255, 42, 0, 223, 246, 5, 9, 11, 230, 236, 10, 4, 252, 249, 251, 7, 248, 227, 249, 44, 41, 220, 211, 9, 25, 254, 7, 13, 248, 255, 0, 235, 10, 23, 235, 232, 20, 25, 254, 235, 241, 4, 8, 252, 3, 27, 3, 237, 251, 16, 11, 7, 15, 0, 239, 249, 2, 254, 15, 32, 1, 223, 242, 14, 11, 254, 240, 247, 22, 4, 208, 0, 49, 250, 234, 34, 16, 227, 252, 12, 4, 16, 12, 9, 6, 241, 244, 251, 1, 23, 30, 253, 236, 245, 0, 6, 0, 11, 44, 10, 210, 234, 24, 28, 5, 238, 0, 24, 244, 218, 4, 32, 12, 246, 244, 254, 8, 253, 237, 251, 27, 12, 241, 235, 254, 252, 253, 243, 250, 13, 4, 230, 221, 254, 16, 3, 246, 251, 251, 239, 236, 255, 16, 13, 234, 211, 254, 27, 246, 230, 247, 2, 246, 240, 246, 2, 244, 0, 121, 8, 30, 0, 248, 12, 23, 0, 234, 214, 221, 242, 8, 252, 4, 28, 34, 36, 47, 28, 249, 224, 232, 242, 227, 215, 244, 15, 6, 13, 43, 54, 41, 33, 40, 28, 245, 226, 226, 222, 197, 220, 255, 254, 29, 57, 36, 31, 48, 58, 3, 235, 23, 251, 212, 0, 30, 244, 252, 34, 38, 42, 42, 13, 8, 14, 247, 233, 230, 219, 200, 242, 23, 18, 10, 48, 61, 46, 39, 236, 225, 252, 225, 204, 217, 233, 237, 27, 53, 33, 48, 44, 255, 20, 5, 220, 223, 230, 200, 214, 24, 1, 245, 53, 49, 15, 38, 19, 223, 224, 249, 219, 203, 254, 14, 11, 29, 32, 29, 27, 34, 29, 254, 6, 2, 212, 209, 230, 218, 201, 217, 19, 24, 12, 37, 49, 27, 18, 31, 244, 212, 235, 244, 224, 223, 254, 11, 9, 26, 30, 29, 39, 28, 15, 1, 225, 219, 244, 227, 234, 9, 243, 231, 17, 28, 245, 253, 30, 255, 236, 16, 23, 247, 254, 3, 0, 240, 243, 248, 0, 2, 242, 12, 19, 253, 253, 24, 32, 2, 4, 255, 237, 241, 236, 212, 241, 19, 11, 17, 56, 50, 16, 37, 17, 184, 192, 223, 179, 180, 2, 27, 33, 73, 93, 66, 41, 41, 13, 224, 217, 214, 187, 189, 211, 243, 14, 36, 60, 87, 53, 33, 51, 6, 219, 227, 199, 167, 195, 220, 211, 240, 17, 33, 63, 89, 45, 25, 43, 244, 180, 222, 206, 188, 240, 242, 242, 34, 46, 22, 34, 24, 250, 247, 241, 211, 211, 228, 234, 249, 13, 32, 18, 37, 62, 32, 23, 34, 6, 227, 242, 223, 206, 235, 226, 225, 3, 13, 1, 25, 44, 26, 8, 10, 254, 224, 209, 207, 201, 201, 214, 244, 38, 51, 27, 54, 71, 23, 3, 15, 219, 192, 223, 215, 220, 238, 235, 11, 46, 32, 38, 41, 6, 0, 245, 221, 208, 219, 232, 228, 246, 8, 16, 28, 46, 43, 32, 4, 223, 218, 236, 205, 205, 234, 249, 35, 29, 40, 85, 58, 7, 6, 3, 207, 181, 205, 206, 202, 6, 17, 32, 76, 82, 30, 29, 54, 238, 188, 226, 208, 179, 220, 233, 246, 12, 31, 39, 67, 69, 42, 59, 26, 210, 177, 182, 194, 184, 223, 9, 16, 52, 92, 78, 63, 43, 0, 217, 213, 213, 188, 203, 215, 247, 16, 29, 47, 56, 37, 39, 24, 5, 6, 240, 221, 208, 238, 240, 226, 243, 28, 48, 34, 24, 43, 26, 16, 0, 223, 200, 210, 224, 225, 247, 244, 240, 34, 39, 8, 42, 59, 6, 243, 6, 247, 211, 217, 203, 215, 1, 6, 21, 51, 54, 37, 20, 21, 30, 0, 223, 229, 207, 199, 228, 238, 243, 39, 47, 44, 63, 58, 33, 17, 248, 221, 209, 201, 215, 214, 194, 239, 23, 18, 33, 61, 48, 30, 10, 0, 2, 234, 225, 230, 239, 0, 14, 37, 32, 36, 46, 59, 31, 247, 234, 236, 203, 213, 236, 206, 214, 3, 19, 11, 47, 64, 19, 31, 50, 255, 231, 250, 224, 182, 194, 219, 218, 243, 49, 35, 33, 86, 64, 26, 51, 14, 193, 226, 233, 177, 196, 250, 251, 237, 33, 54, 27, 27, 46, 9, 239, 2, 252, 219, 219, 206, 212, 4, 16, 16, 29, 48, 64, 19, 10, 27, 224, 202, 230, 219, 224, 1, 22, 37, 37, 22, 17, 46, 27, 210, 191, 228, 202, 168, 237, 251, 248, 42, 47, 32, 49, 53, 254, 244, 3, 233, 209, 208, 218, 222, 240, 0, 2, 16, 54, 29, 24, 38, 12, 240, 252, 4, 220, 198, 220, 244, 252, 21, 29, 25, 31, 62, 49, 251, 13, 14, 217, 219, 220, 217, 232, 243, 19, 49, 67, 45, 32, 44, 15, 239, 215, 207, 208, 221, 231, 233, 244, 249, 6, 26, 40, 62, 54, 15, 16, 4, 220, 205, 209, 211, 229, 217, 236, 17, 41, 59, 62, 41, 43, 54, 17, 232, 233, 216, 178, 178, 216, 232, 245, 27, 41, 36, 63, 68, 40, 1, 232, 241, 200, 159, 182, 226, 231, 247, 44, 63, 64, 70, 67, 4, 3, 254, 176, 166, 235, 224, 180, 1, 26, 28, 58, 65, 38, 45, 41, 248, 218, 224, 222, 192, 218, 233, 223, 253, 61, 39, 25, 54, 67, 43, 0, 212, 213, 213, 197, 210, 249, 248, 2, 56, 51, 34, 41, 27, 7, 22, 250, 209, 185, 203, 246, 210, 213, 42, 46, 11, 78, 74, 35, 59, 28, 231, 240, 217, 161, 170, 204, 232, 242, 42, 45, 25, 62, 69, 24, 8, 10, 239, 223, 227, 171, 197, 247, 217, 245, 27, 26, 48, 57, 28, 4, 252, 243, 233, 228, 227, 8, 31, 41, 24, 29, 37, 17, 240, 230, 239, 226, 228, 249, 3, 6, 7, 23, 15, 5, 42, 28, 222, 248, 5, 235, 239, 223, 216, 41, 20, 217, 22, 58, 3, 5, 28, 10, 231, 218, 235, 233, 225, 252, 230, 243, 55, 16, 24, 76, 39, 0, 20, 12, 217, 224, 237, 225, 192, 231, 18, 252, 248, 39, 32, 19, 48, 19, 235, 247, 243, 238, 221, 197, 221, 251, 237, 217, 26, 63, 30, 5, 42, 49, 253, 244, 3, 237, 224, 251, 225, 211, 240, 3, 251, 22, 9, 239, 23, 63, 47, 7, 40, 23, 194, 225, 30, 195, 158, 7, 12, 243, 42, 66, 32, 8, 20, 19, 243, 226, 2, 8, 254, 12, 244, 238, 14, 13, 235, 252, 242, 237, 8, 254, 5, 11, 15, 4, 5, 0, 252, 241, 247, 4, 8, 243, 0, 16, 253, 2, 24, 250, 243, 22, 17, 223, 225, 13, 237, 205, 253, 40, 3, 3, 61, 39, 27, 53, 248, 196, 227, 205, 175, 204, 230, 216, 20, 52, 33, 52, 65, 32, 243, 6, 25, 217, 215, 11, 243, 216, 234, 9, 32, 25, 22, 41, 43, 20, 26, 16, 239, 225, 228, 229, 236, 229, 229, 240, 21, 28, 22, 39, 45, 24, 41, 32, 237, 241, 236, 207, 215, 232, 229, 234, 10, 45, 43, 45, 58, 21, 19, 31, 229, 200, 223, 226, 204, 220, 248, 255, 249, 20, 47, 26, 0, 17, 42, 21, 248, 246, 12, 0, 219, 229, 228, 216, 225, 13, 25, 6, 24, 31, 10, 0, 10, 0, 207, 218, 20, 240, 220, 26, 255, 0, 50, 8, 230, 20, 8, 252, 1, 245, 18, 25, 11, 13, 9, 236, 218, 237, 249, 207, 231, 32, 41, 0, 21, 54, 41, 23, 14, 8, 250, 227, 226, 206, 216, 245, 244, 20, 49, 60, 63, 61, 29, 1, 13, 211, 149, 215, 209, 148, 216, 51, 6, 2, 67, 44, 23, 55, 10, 201, 6, 247, 183, 223, 22, 227, 247, 58, 18, 45, 71, 13, 252, 18, 2, 239, 244, 227, 188, 220, 0, 221, 212, 35, 30, 254, 44, 60, 248, 229, 12, 231, 200, 226, 251, 196, 195, 10, 29, 11, 23, 43, 31, 13, 14, 8, 241, 244, 238, 238, 9, 34, 27, 19, 6, 19, 248, 234, 10, 1, 221, 230, 13, 237, 241, 255, 22, 6, 0, 22, 12, 29, 0, 234, 24, 9, 198, 215, 6, 249, 230, 22, 39, 0, 37, 62, 211, 180, 247, 210, 228, 52, 253, 228, 74, 52, 2, 74, 34, 212, 26, 31, 214, 225, 8, 231, 211, 9, 233, 211, 65, 37, 218, 30, 53, 232, 242, 30, 205, 180, 252, 240, 227, 6, 1, 252, 41, 51, 6, 238, 5, 11, 238, 249, 0, 239, 255, 36, 28, 8, 52, 40, 234, 235, 239, 208, 212, 244, 206, 223, 46, 22, 245, 48, 70, 238, 241, 20, 227, 190, 252, 248, 218, 253, 23, 22, 29, 11, 6, 35, 241, 208, 49, 51, 197, 242, 45, 0, 248, 17, 250, 245, 20, 249, 225, 17, 28, 211, 221, 32, 248, 233, 54, 45, 39, 38, 9, 3, 10, 230, 196, 199, 193, 203, 224, 17, 24, 15, 77, 78, 22, 45, 66, 233, 214, 17, 219, 154, 201, 255, 235, 9, 9, 251, 36, 73, 8, 0, 17, 214, 201, 215, 209, 215, 15, 63, 5, 18, 90, 31, 204, 9, 12, 210, 3, 20, 203, 243, 41, 249, 15, 67, 255, 248, 67, 40, 0, 24, 236, 203, 204, 221, 202, 226, 0, 13, 53, 55, 31, 35, 73, 3, 195, 247, 232, 166, 212, 1, 229, 232, 24, 0, 243, 71, 50, 5, 37, 14, 218, 255, 12, 202, 220, 243, 212, 221, 20, 21, 14, 26, 56, 54, 24, 22, 20, 246, 248, 232, 203, 231, 2, 235, 226, 252, 10, 32, 47, 3, 19, 69, 28, 218, 253, 19, 205, 185, 20, 21, 210, 26, 70, 3, 15, 61, 254, 252, 19, 206, 205, 234, 215, 211, 242, 230, 246, 35, 39, 21, 28, 39, 54, 23, 228, 234, 241, 235, 214, 246, 24, 16, 0, 9, 14, 245, 231, 232, 255, 6, 240, 241, 12, 8, 3, 38, 42, 248, 237, 12, 2, 244, 239, 223, 222, 5, 11, 6, 50, 54, 26, 38, 48, 248, 229, 244, 227, 192, 214, 241, 1, 33, 56, 68, 52, 36, 4, 1, 27, 227, 183, 187, 194, 208, 230, 35, 59, 68, 70, 47, 36, 22, 231, 179, 196, 213, 178, 214, 12, 0, 20, 63, 55, 42, 44, 26, 243, 200, 187, 182, 201, 215, 234, 0, 48, 51, 30, 56, 65, 26, 11, 247, 206, 207, 197, 201, 216, 237, 245, 244, 14, 79, 98, 79, 76, 50, 247, 219, 199, 152, 159, 180, 200, 219, 8, 76, 94, 103, 89, 64, 55, 10, 226, 212, 206, 186, 140, 172, 234, 13, 6, 46, 101, 78, 93, 94, 3, 204, 172, 156, 156, 188, 196, 192, 31, 57, 30, 84, 94, 29, 25, 63, 248, 155, 199, 203, 149, 192, 0, 239, 29, 125, 94, 52, 89, 46, 205, 225, 199, 141, 175, 203, 220, 1, 43, 49, 67, 56, 10, 34, 39, 214, 205, 253, 233, 219, 0, 20, 5, 44, 67, 20, 24, 18, 236, 237, 219, 198, 254, 14, 227, 26, 72, 16, 4, 55, 38, 246, 240, 241, 215, 219, 252, 248, 253, 15, 2, 255, 19, 248, 230, 17, 241, 193, 24, 84, 244, 225, 43, 25, 219, 230, 248, 236, 237, 253, 253, 255, 19, 11, 3, 30, 34, 8, 229, 230, 240, 229, 222, 220, 243, 23, 24, 28, 26, 19, 39, 40, 244, 204, 233, 241, 195, 209, 241, 8, 5, 13, 81, 87, 17, 12, 39, 249, 202, 241, 220, 188, 235, 253, 227, 255, 47, 26, 20, 35, 253, 251, 30, 17, 251, 222, 225, 0, 252, 250, 6, 244, 247, 5, 1, 14, 17, 253, 29, 80, 7, 230, 12, 3, 210, 196, 230, 246, 232, 252, 47, 43, 35, 19, 8, 23, 11, 232, 225, 221, 200, 203, 238, 242, 250, 80, 102, 43, 43, 80, 35, 211, 211, 230, 192, 152, 185, 241, 251, 14, 89, 78, 42, 94, 91, 1, 228, 248, 179, 149, 183, 174, 177, 228, 251, 53, 104, 62, 77, 111, 39, 232, 230, 198, 154, 162, 215, 231, 227, 44, 103, 67, 70, 101, 49, 12, 243, 215, 194, 164, 161, 207, 226, 238, 47, 52, 33, 79, 69, 6, 21, 18, 225, 162, 175, 206, 177, 216, 18, 15, 37, 97, 84, 33, 23, 36, 232, 180, 168, 177, 197, 186, 226, 45, 91, 70, 68, 102, 87, 35, 254, 231, 204, 184, 173, 193, 221, 250, 21, 59, 57, 62, 112, 98, 33, 237, 221, 195, 143, 164, 206, 200, 228, 241, 23, 49, 65, 57, 41, 47, 9, 6, 251, 206, 209, 227, 220, 214, 221, 253, 29, 22, 24, 59, 64, 27, 22, 32, 9, 253, 236, 228, 237, 224, 239, 248, 223, 255, 30, 7, 20, 52, 37, 41, 29, 7, 251, 225, 223, 227, 210, 219, 232, 232, 244, 21, 15, 27, 47, 41, 41, 12, 21, 18, 222, 232, 228, 229, 245, 234, 244, 18, 5, 12, 29, 13, 16, 24, 1, 27, 17, 241, 254, 243, 222, 230, 236, 229, 210, 248, 17, 18, 244, 12, 49, 11, 21, 38, 6, 235, 251, 236, 205, 237, 247, 251, 12, 19, 40, 35, 25, 15, 13, 255, 241, 252, 249, 221, 206, 247, 245, 216, 246, 33, 32, 35, 27, 39, 62, 12, 0, 234, 209, 214, 187, 183, 248, 231, 248, 41, 33, 43, 67, 42, 30, 24, 243, 216, 216, 190, 193, 214, 219, 229, 19, 26, 36, 43, 54, 54, 23, 10, 0, 232, 201, 215, 218, 178, 231, 38, 5, 34, 99, 52, 32, 72, 22, 247, 5, 199, 203, 236, 204, 240, 10, 2, 22, 33, 47, 31, 255, 10, 6, 233, 225, 229, 230, 221, 249, 0, 0, 34, 34, 15, 40, 10, 252, 0, 231, 205, 228, 253, 235, 230, 21, 20, 24, 28, 31, 41, 8, 13, 5, 244, 5, 231, 222, 253, 1, 233, 12, 16, 3, 41, 27, 16, 6, 250, 255, 240, 217, 234, 249, 242, 246, 0, 0, 0, 76, 11, 178, 0, 10, 246, 247, 248, 0, 19, 0, 242, 9, 16, 0, 239, 239, 3, 14, 11, 4, 253, 1, 252, 245, 250, 2, 10, 19, 12, 242, 231, 246, 9, 15, 8, 3, 2, 249, 240, 254, 9, 255, 1, 9, 11, 15, 245, 216, 244, 30, 29, 4, 238, 244, 11, 253, 232, 5, 27, 16, 5, 242, 231, 0, 17, 0, 236, 253, 31, 27, 244, 233, 253, 1, 247, 5, 27, 8, 235, 242, 3, 1, 250, 6, 37, 21, 221, 219, 0, 20, 16, 248, 248, 30, 22, 215, 204, 16, 49, 11, 239, 0, 21, 244, 213, 251, 25, 8, 12, 19, 248, 236, 245, 1, 15, 2, 245, 14, 13, 241, 246, 254, 255, 19, 20, 253, 248, 247, 246, 250, 249, 7, 23, 18, 250, 236, 248, 2, 3, 255, 253, 13, 27, 248, 216, 241, 27, 30, 254, 249, 12, 251, 221, 245, 32, 25, 242, 242, 14, 13, 240, 235, 5, 13, 5, 11, 3, 240, 241, 253, 13, 11, 241, 253, 45, 18, 194, 206, 35, 53, 248, 226, 7, 26, 250, 230, 254, 19, 10, 2, 3, 250, 242, 0, 13, 246, 232, 16, 42, 11, 230, 230, 0, 254, 254, 27, 19, 250, 250, 251, 244, 244, 3, 29, 13, 251, 3, 247, 222, 237, 16, 32, 20, 253, 253, 247, 225, 253, 34, 8, 238, 3, 30, 21, 216, 185, 1, 70, 37, 1, 246, 233, 243, 245, 250, 15, 32, 20, 231, 225, 12, 13, 232, 244, 41, 46, 240, 202, 240, 24, 8, 238, 0, 40, 28, 229, 217, 251, 22, 7, 250, 5, 29, 9, 212, 221, 24, 31, 0, 254, 13, 0, 233, 235, 250, 8, 24, 35, 11, 231, 225, 241, 4, 24, 27, 10, 238, 232, 247, 4, 255, 3, 28, 25, 245, 230, 240, 6, 9, 252, 6, 22, 253, 227, 246, 5, 9, 21, 4, 241, 0, 10, 244, 230, 8, 45, 14, 219, 235, 32, 20, 227, 224, 11, 39, 8, 235, 8, 11, 234, 239, 8, 26, 19, 238, 235, 3, 254, 244, 0, 21, 34, 4, 232, 243, 249, 254, 10, 11, 255, 2, 7, 244, 232, 254, 24, 20, 3, 254, 247, 242, 247, 4, 12, 0, 2, 36, 8, 204, 222, 24, 42, 13, 238, 238, 3, 4, 240, 240, 14, 40, 23, 231, 217, 254, 20, 7, 252, 254, 4, 10, 253, 242, 0, 7, 254, 11, 26, 255, 225, 231, 4, 21, 11, 8, 3, 238, 235, 4, 13, 0, 0, 9, 15, 9, 241, 232, 244, 252, 11, 28, 21, 245, 229, 250, 20, 12, 254, 253, 3, 249, 234, 251, 17, 22, 9, 234, 236, 23, 25, 245, 230, 247, 21, 17, 254, 253, 247, 240, 255, 17, 26, 16, 246, 230, 246, 11, 242, 223, 20, 63, 13, 206, 219, 40, 43, 218, 207, 29, 57, 3, 213, 223, 28, 35, 237, 237, 26, 12, 232, 231, 12, 42, 4, 221, 1, 22, 236, 217, 13, 54, 26, 226, 215, 248, 21, 37, 2, 215, 241, 25, 23, 6, 236, 232, 12, 20, 254, 0, 245, 254, 28, 7, 232, 242, 0, 6, 255, 3, 28, 3, 237, 254, 4, 0, 7, 0, 233, 244, 20, 19, 251, 247, 18, 20, 239, 215, 246, 21, 13, 6, 26, 8, 219, 215, 7, 44, 25, 233, 242, 36, 6, 188, 219, 49, 64, 1, 204, 236, 26, 7, 246, 10, 18, 13, 253, 214, 225, 33, 36, 249, 243, 19, 7, 217, 229, 23, 28, 20, 13, 240, 225, 231, 9, 23, 255, 11, 34, 247, 207, 232, 13, 22, 18, 22, 2, 225, 236, 11, 9, 252, 0, 29, 17, 217, 222, 21, 20, 249, 2, 11, 0, 0, 5, 245, 229, 251, 39, 33, 233, 229, 10, 10, 238, 247, 10, 17, 17, 3, 237, 238, 254, 8, 3, 254, 22, 30, 230, 197, 245, 43, 40, 253, 248, 8, 237, 219, 5, 29, 15, 11, 255, 236, 240, 249, 10, 9, 10, 23, 254, 223, 247, 25, 6, 232, 1, 26, 9, 245, 225, 232, 24, 49, 6, 217, 253, 41, 251, 214, 247, 23, 13, 253, 0, 14, 254, 226, 251, 39, 13, 233, 245, 255, 4, 14, 253, 234, 253, 24, 30, 247, 222, 254, 27, 3, 230, 252, 15, 3, 255, 11, 9, 240, 237, 11, 25, 4, 235, 243, 19, 7, 238, 2, 29, 6, 227, 232, 13, 25, 247, 241, 21, 12, 224, 237, 28, 29, 238, 228, 25, 43, 240, 200, 242, 48, 27, 229, 0, 27, 244, 224, 4, 25, 12, 251, 249, 2, 248, 238, 7, 15, 2, 10, 2, 240, 237, 237, 16, 53, 6, 224, 238, 12, 34, 3, 204, 225, 33, 47, 6, 229, 237, 13, 15, 247, 239, 253, 10, 17, 9, 246, 244, 6, 1, 234, 4, 44, 8, 210, 228, 32, 46, 246, 216, 255, 23, 1, 247, 249, 6, 24, 8, 227, 233, 18, 18, 248, 249, 10, 13, 3, 0, 251, 238, 249, 14, 12, 255, 242, 4, 21, 244, 229, 249, 17, 29, 6, 244, 255, 3, 250, 6, 2, 238, 1, 23, 253, 235, 245, 22, 44, 250, 197, 238, 46, 36, 234, 201, 0, 62, 20, 220, 225, 10, 40, 5, 222, 251, 21, 13, 236, 215, 15, 55, 4, 215, 235, 15, 27, 2, 251, 23, 0, 206, 239, 27, 17, 2, 14, 15, 245, 214, 251, 29, 13, 5, 246, 232, 255, 3, 1, 19, 13, 245, 251, 8, 6, 251, 236, 247, 27, 18, 245, 245, 8, 7, 238, 232, 19, 34, 15, 0, 250, 241, 217, 224, 30, 65, 7, 214, 234, 21, 28, 247, 228, 1, 25, 12, 238, 227, 0, 15, 9, 16, 14, 232, 226, 6, 27, 22, 245, 223, 7, 30, 242, 218, 4, 52, 30, 223, 227, 9, 0, 250, 18, 19, 244, 239, 2, 249, 247, 25, 43, 246, 202, 238, 39, 32, 235, 223, 4, 32, 9, 220, 238, 47, 39, 213, 199, 43, 76, 223, 168, 250, 75, 34, 215, 235, 31, 12, 230, 246, 18, 16, 0, 228, 231, 22, 31, 249, 245, 0, 0, 9, 11, 242, 252, 13, 246, 251, 11, 0, 0, 0, 248, 14, 23, 239, 238, 0, 3, 14, 0, 236, 1, 0, 0, 20, 17, 235, 221, 23, 46, 243, 213, 16, 55, 247, 182, 242, 73, 40, 218, 216, 18, 31, 241, 226, 2, 19, 10, 247, 255, 22, 6, 220, 230, 27, 22, 236, 4, 32, 11, 233, 224, 0, 24, 254, 247, 15, 14, 248, 241, 252, 4, 4, 3, 2, 0, 8, 2, 247, 248, 0, 16, 12, 240, 240, 9, 23, 10, 230, 231, 22, 23, 244, 238, 0, 17, 11, 232, 254, 23, 0, 1, 254, 212, 252, 53, 26, 254, 235, 208, 254, 46, 23, 248, 234, 238, 15, 12, 243, 4, 252, 240, 33, 34, 234, 227, 0, 12, 247, 249, 19, 16, 244, 245, 8, 3, 251, 7, 0, 246, 15, 8, 229, 243, 8, 26, 34, 0, 212, 224, 27, 40, 248, 218, 251, 36, 15, 228, 235, 23, 11, 233, 1, 31, 9, 245, 225, 229, 23, 42, 13, 240, 232, 253, 21, 252, 216, 3, 61, 33, 216, 190, 246, 50, 41, 1, 232, 237, 17, 27, 240, 203, 244, 63, 49, 232, 207, 254, 28, 10, 249, 237, 235, 21, 34, 247, 217, 0, 35, 14, 237, 231, 4, 19, 0, 0, 17, 248, 224, 254, 50, 18, 200, 218, 34, 44, 0, 238, 249, 9, 7, 255, 245, 0, 10, 250, 245, 27, 30, 221, 199, 14, 61, 24, 227, 227, 17, 3, 210, 255, 44, 18, 236, 233, 31, 47, 207, 161, 11, 104, 43, 230, 223, 226, 244, 4, 20, 25, 20, 2, 244, 236, 244, 244, 0, 16, 26, 21, 248, 217, 224, 11, 55, 25, 220, 221, 13, 22, 239, 229, 12, 45, 11, 223, 247, 17, 0, 252, 244, 254, 21, 14, 248, 225, 243, 33, 15, 234, 255, 31, 17, 223, 223, 11, 15, 255, 9, 7, 8, 2, 236, 224, 3, 47, 25, 246, 228, 253, 30, 236, 191, 12, 66, 26, 255, 217, 222, 36, 23, 216, 245, 26, 28, 13, 209, 201, 35, 61, 251, 225, 17, 39, 222, 184, 3, 81, 17, 173, 237, 94, 37, 205, 217, 3, 32, 19, 235, 241, 9, 241, 240, 30, 16, 250, 20, 4, 218, 240, 31, 11, 218, 225, 27, 54, 11, 216, 234, 22, 12, 252, 9, 7, 240, 241, 9, 2, 244, 17, 17, 246, 241, 255, 14, 5, 242, 5, 10, 244, 255, 21, 244, 220, 0, 43, 40, 229, 206, 3, 38, 9, 240, 240, 12, 7, 241, 11, 9, 239, 0, 20, 5, 249, 238, 10, 24, 245, 239, 16, 14, 245, 232, 239, 30, 43, 252, 231, 244, 245, 12, 17, 1, 255, 242, 247, 0, 1, 34, 23, 200, 223, 53, 34, 218, 205, 21, 84, 7, 169, 218, 57, 62, 221, 177, 26, 98, 251, 173, 233, 60, 62, 209, 181, 49, 67, 212, 201, 10, 52, 26, 216, 225, 41, 12, 212, 3, 45, 0, 228, 230, 252, 23, 11, 11, 20, 218, 209, 26, 42, 0, 241, 234, 4, 39, 2, 218, 245, 31, 26, 240, 219, 246, 36, 36, 246, 219, 246, 26, 24, 254, 216, 226, 38, 71, 250, 191, 237, 46, 22, 212, 233, 40, 17, 239, 1, 5, 234, 230, 14, 50, 252, 212, 11, 25, 236, 239, 18, 37, 8, 223, 215, 17, 38, 0, 0, 15, 228, 219, 11, 32, 20, 9, 245, 229, 1, 12, 252, 248, 0, 18, 14, 232, 224, 13, 37, 15, 248, 229, 243, 15, 15, 247, 231, 6, 54, 250, 182, 246, 77, 32, 210, 224, 39, 14, 197, 251, 74, 20, 212, 215, 252, 46, 20, 242, 11, 11, 234, 237, 252, 255, 30, 27, 227, 225, 29, 6, 227, 3, 21, 3, 251, 244, 5, 8, 254, 9, 16, 241, 206, 255, 62, 20, 227, 238, 10, 8, 240, 238, 38, 37, 213, 212, 25, 42, 20, 242, 202, 238, 46, 32, 233, 226, 4, 46, 38, 205, 187, 26, 68, 13, 221, 219, 15, 35, 252, 223, 230, 9, 43, 16, 244, 0, 249, 212, 246, 27, 22, 24, 16, 222, 220, 3, 32, 38, 246, 206, 255, 27, 239, 0, 35, 15, 254, 225, 215, 12, 39, 12, 1, 255, 239, 254, 13, 245, 243, 13, 20, 248, 221, 8, 55, 11, 197, 227, 32, 32, 4, 238, 235, 5, 29, 11, 231, 240, 13, 7, 244, 245, 9, 27, 8, 233, 233, 16, 6, 229, 16, 64, 1, 197, 228, 27, 16, 237, 6, 27, 0, 245, 4, 10, 1, 226, 233, 36, 38, 3, 233, 211, 251, 57, 19, 211, 235, 30, 14, 234, 10, 15, 233, 243, 28, 11, 237, 229, 248, 24, 21, 3, 12, 2, 232, 221, 255, 45, 12, 242, 14, 11, 219, 218, 21, 37, 250, 11, 37, 216, 181, 22, 95, 18, 185, 207, 37, 47, 242, 223, 9, 22, 0, 253, 253, 229, 242, 37, 40, 242, 222, 249, 26, 2, 210, 248, 69, 21, 216, 245, 9, 253, 244, 251, 31, 27, 234, 226, 6, 32, 252, 217, 240, 35, 31, 246, 236, 22, 24, 239, 231, 238, 249, 47, 30, 212, 225, 25, 33, 2, 212, 219, 65, 81, 231, 158, 238, 69, 31, 205, 239, 28, 12, 238, 240, 26, 27, 219, 248, 56, 239, 158, 239, 101, 75, 197, 176, 43, 83, 223, 180, 8, 79, 7, 189, 233, 39, 29, 227, 217, 42, 48, 204, 236, 74, 32, 185, 188, 25, 64, 243, 231, 27, 12, 223, 242, 20, 24, 3, 243, 6, 10, 212, 203, 30, 77, 22, 203, 211, 30, 55, 244, 203, 251, 61, 28, 204, 207, 17, 46, 5, 238, 2, 1, 240, 0, 23, 13, 252, 239, 234, 0, 26, 2, 241, 12, 16, 241, 230, 6, 69, 25, 176, 195, 49, 68, 246, 201, 2, 61, 1, 185, 219, 28, 50, 37, 248, 216, 227, 20, 11, 228, 255, 70, 26, 192, 204, 38, 46, 224, 227, 53, 37, 202, 200, 31, 67, 6, 185, 224, 65, 58, 206, 189, 27, 46, 245, 240, 19, 18, 241, 220, 249, 22, 28, 24, 239, 226, 0, 17, 250, 229, 3, 36, 24, 237, 226, 238, 9, 32, 20, 233, 239, 24, 6, 226, 254, 23, 24, 242, 207, 4, 89, 12, 166, 200, 30, 64, 30, 213, 225, 39, 17, 220, 239, 33, 37, 248, 203, 237, 53, 21, 214, 252, 32, 16, 236, 212, 245, 58, 45, 224, 212, 12, 33, 226, 194, 18, 91, 21, 184, 230, 54, 7, 202, 248, 51, 44, 246, 174, 219, 79, 53, 208, 224, 24, 33, 4, 216, 235, 46, 33, 233, 232, 233, 250, 32, 43, 6, 192, 206, 56, 55, 212, 225, 33, 30, 246, 216, 251, 35, 19, 234, 198, 248, 105, 50, 156, 177, 81, 103, 213, 130, 5, 114, 12, 179, 241, 59, 32, 216, 200, 26, 69, 242, 198, 14, 46, 244, 209, 253, 59, 27, 201, 215, 23, 33, 25, 242, 210, 2, 35, 249, 233, 17, 37, 2, 222, 209, 2, 54, 28, 221, 202, 12, 70, 14, 199, 248, 60, 253, 174, 253, 83, 32, 207, 234, 22, 250, 236, 22, 30, 237, 213, 15, 72, 4, 182, 238, 48, 10, 215, 233, 24, 56, 13, 216, 239, 251, 236, 252, 29, 46, 0, 204, 247, 37, 12, 244, 238, 238, 248, 20, 67, 36, 192, 171, 6, 84, 35, 187, 222, 85, 46, 175, 186, 52, 92, 255, 170, 218, 53, 32, 233, 237, 25, 25, 230, 216, 2, 35, 36, 229, 202, 16, 51, 250, 208, 244, 40, 58, 2, 228, 0, 238, 192, 243, 56, 49, 249, 217, 4, 46, 245, 214, 5, 43, 16, 216, 220, 28, 27, 250, 246, 1, 4, 235, 239, 60, 52, 197, 189, 25, 46, 252, 231, 20, 51, 230, 155, 243, 96, 48, 196, 207, 33, 70, 0, 180, 224, 52, 31, 248, 14, 246, 212, 10, 38, 2, 223, 216, 43, 76, 230, 201, 8, 38, 3, 204, 199, 45, 75, 11, 229, 228, 5, 6, 218, 255, 62, 31, 219, 191, 240, 63, 42, 224, 214, 0, 37, 8, 236, 33, 38, 202, 217, 40, 14, 211, 0, 76, 34, 176, 194, 53, 52, 227, 215, 28, 55, 242, 192, 237, 35, 42, 253, 222, 1, 36, 20, 232, 215, 18, 29, 198, 209, 53, 87, 13, 171, 178, 35, 92, 16, 207, 222, 27, 28, 222, 245, 58, 18, 202, 218, 30, 46, 8, 246, 251, 246, 230, 237, 8, 25, 22, 3, 242, 248, 0, 244, 252, 255, 21, 25, 242, 229, 40, 16, 173, 225, 87, 61, 217, 186, 242, 27, 10, 23, 34, 242, 204, 1, 67, 14, 165, 220, 89, 40, 206, 220, 25, 56, 253, 195, 251, 37, 254, 225, 254, 26, 11, 250, 224, 0, 49, 11, 208, 246, 39, 32, 245, 204, 228, 58, 42, 205, 214, 34, 56, 11, 214, 228, 34, 17, 221, 239, 36, 8, 207, 229, 47, 35, 241, 236, 246, 13, 19, 250, 0, 15, 245, 217, 234, 24, 44, 17, 224, 251, 51, 8, 200, 217, 28, 53, 6, 220, 248, 12, 250, 248, 6, 19, 0, 247, 6, 1, 238, 255, 35, 19, 221, 222, 16, 15, 249, 17, 24, 242, 204, 243, 45, 39, 249, 218, 244, 43, 253, 211, 0, 30, 6, 247, 246, 30, 25, 218, 211, 20, 58, 8, 209, 242, 15, 10, 12, 247, 0, 30, 0, 242, 254, 242, 244, 14, 17, 254, 223, 244, 48, 23, 224, 239, 19, 31, 240, 206, 6, 41, 4, 231, 233, 12, 30, 0, 224, 249, 32, 33, 0, 220, 225, 18, 38, 255, 224, 244, 32, 21, 226, 234, 33, 38, 246, 218, 243, 36, 13, 222, 231, 11, 40, 14, 219, 236, 38, 29, 232, 233, 16, 14, 231, 233, 32, 33, 223, 213, 26, 57, 0, 218, 242, 6, 0, 254, 253, 8, 11, 0, 247, 252, 11, 5, 2, 7, 250, 240, 245, 16, 30, 2, 234, 244, 245, 9, 33, 11, 242, 246, 3, 6, 249, 243, 15, 14, 227, 239, 25, 21, 252, 242, 0, 13, 253, 239, 0, 21, 7, 239, 245, 2, 9, 13, 247, 252, 252, 251, 20, 14, 244, 239, 250, 12, 25, 0, 211, 252, 54, 11, 228, 251, 11, 0, 238, 236, 31, 41, 232, 233, 12, 0, 244, 250, 11, 39, 6, 233, 253, 251, 227, 241, 27, 44, 13, 240, 233, 224, 248, 35, 33, 10, 239, 219, 243, 20, 17, 15, 13, 245, 228, 227, 6, 44, 27, 243, 230, 237, 252, 13, 14, 2, 6, 6, 252, 5, 4, 249, 251, 249, 252, 14, 0, 243, 3, 15, 5, 253, 249, 255, 5, 14, 5, 239, 234, 252, 19, 16, 255, 236, 239, 11, 30, 18, 254, 238, 251, 0, 246, 0, 6, 11, 14, 248, 242, 255, 1, 16, 8, 249, 8, 0, 233, 241, 9, 12, 6, 1, 254, 253, 252, 254, 14, 10, 249, 7, 11, 222, 222, 22, 34, 6, 247, 248, 5, 1, 243, 7, 13, 0, 3, 252, 244, 0, 9, 2, 5, 5, 244, 243, 4, 5, 3, 6, 253, 253, 5, 0, 254, 1, 3, 9, 9, 248, 245, 0, 255, 1, 2, 182, 7, 69, 0, 0, 7, 18, 244, 226, 0, 8, 237, 247, 12, 250, 247, 255, 237, 242, 6, 18, 0, 235, 225, 244, 23, 11, 246, 247, 242, 237, 247, 14, 21, 244, 222, 239, 10, 8, 246, 255, 251, 239, 1, 3, 244, 248, 0, 251, 253, 251, 237, 8, 22, 229, 226, 11, 9, 253, 240, 247, 10, 251, 236, 255, 15, 241, 224, 16, 24, 229, 225, 17, 10, 227, 2, 12, 240, 240, 255, 6, 2, 244, 246, 249, 248, 11, 0, 235, 245, 3, 1, 248, 3, 253, 241, 2, 250, 238, 0, 8, 4, 247, 238, 243, 7, 14, 242, 248, 6, 243, 232, 8, 20, 254, 234, 250, 0, 233, 251, 35, 7, 202, 238, 28, 5, 239, 0, 0, 230, 242, 27, 2, 234, 4, 253, 215, 3, 53, 246, 208, 252, 10, 243, 255, 19, 5, 244, 228, 233, 4, 22, 13, 243, 228, 239, 9, 20, 245, 232, 0, 2, 242, 0, 21, 235, 220, 22, 22, 225, 240, 18, 253, 232, 5, 15, 238, 235, 15, 6, 235, 239, 13, 12, 240, 231, 255, 19, 2, 230, 251, 255, 241, 10, 3, 252, 8, 245, 215, 255, 40, 5, 223, 237, 7, 3, 254, 15, 253, 217, 237, 11, 22, 12, 235, 242, 4, 233, 229, 27, 32, 245, 233, 242, 242, 250, 30, 20, 228, 229, 4, 1, 244, 6, 14, 246, 228, 255, 13, 0, 249, 252, 248, 230, 249, 42, 12, 213, 234, 15, 4, 250, 253, 8, 255, 224, 241, 24, 21, 234, 227, 13, 16, 229, 245, 21, 253, 237, 240, 248, 12, 25, 1, 225, 229, 0, 14, 9, 9, 234, 241, 2, 248, 12, 21, 238, 211, 252, 34, 19, 226, 247, 17, 242, 226, 18, 38, 239, 227, 253, 4, 5, 9, 255, 240, 247, 246, 250, 22, 15, 243, 237, 244, 0, 7, 2, 254, 249, 255, 249, 245, 9, 8, 252, 233, 244, 8, 9, 1, 252, 251, 247, 244, 3, 17, 253, 233, 248, 6, 2, 5, 245, 238, 14, 14, 230, 242, 17, 250, 238, 14, 18, 253, 229, 233, 4, 24, 7, 227, 0, 19, 241, 231, 18, 17, 240, 237, 8, 10, 252, 249, 246, 250, 7, 9, 237, 251, 26, 246, 225, 253, 4, 252, 251, 0, 29, 16, 212, 230, 36, 24, 212, 231, 38, 15, 224, 241, 10, 252, 8, 23, 247, 227, 222, 0, 53, 31, 219, 215, 253, 13, 252, 251, 19, 10, 235, 226, 249, 16, 9, 0, 243, 249, 10, 251, 235, 5, 21, 245, 230, 247, 15, 26, 253, 213, 235, 23, 20, 235, 235, 22, 2, 224, 9, 21, 232, 238, 22, 10, 235, 239, 19, 19, 236, 228, 7, 5, 242, 14, 34, 246, 208, 2, 25, 246, 248, 6, 253, 249, 0, 11, 247, 236, 3, 3, 249, 0, 3, 249, 235, 255, 38, 16, 217, 219, 17, 19, 237, 4, 27, 244, 224, 0, 11, 249, 4, 18, 246, 222, 252, 16, 13, 242, 229, 16, 28, 229, 219, 17, 23, 241, 240, 7, 11, 246, 249, 11, 255, 229, 252, 18, 10, 239, 227, 6, 30, 3, 228, 235, 11, 17, 0, 243, 248, 8, 255, 240, 249, 26, 13, 217, 234, 10, 12, 8, 12, 3, 225, 234, 14, 2, 252, 23, 6, 224, 229, 5, 28, 3, 227, 248, 21, 3, 241, 245, 9, 244, 242, 27, 18, 231, 243, 4, 240, 250, 37, 7, 226, 240, 254, 15, 0, 233, 10, 30, 255, 234, 252, 7, 250, 241, 13, 21, 240, 235, 6, 6, 240, 0, 13, 4, 242, 239, 5, 0, 240, 6, 12, 4, 237, 212, 27, 50, 228, 205, 20, 48, 225, 196, 26, 55, 237, 211, 0, 14, 247, 246, 14, 15, 246, 244, 236, 230, 5, 42, 17, 237, 226, 242, 16, 16, 1, 8, 243, 201, 239, 43, 62, 251, 201, 233, 0, 245, 253, 49, 41, 244, 176, 191, 42, 44, 1, 240, 238, 240, 234, 16, 64, 3, 212, 11, 4, 227, 7, 23, 17, 246, 223, 238, 11, 25, 251, 229, 255, 18, 0, 250, 245, 241, 7, 1, 248, 4, 243, 1, 24, 236, 218, 251, 30, 24, 229, 246, 27, 215, 211, 54, 51, 245, 233, 251, 255, 240, 15, 29, 0, 228, 228, 0, 13, 248, 5, 31, 243, 196, 242, 47, 18, 241, 24, 250, 191, 245, 58, 21, 217, 248, 21, 240, 245, 1, 9, 1, 233, 245, 22, 24, 240, 216, 246, 20, 8, 230, 0, 46, 35, 196, 169, 1, 54, 45, 21, 233, 202, 220, 9, 44, 21, 214, 240, 34, 245, 196, 23, 80, 0, 151, 233, 88, 22, 219, 245, 9, 253, 249, 2, 21, 10, 232, 243, 20, 245, 224, 14, 50, 12, 204, 229, 31, 18, 245, 14, 247, 215, 238, 50, 48, 249, 194, 217, 0, 27, 36, 5, 221, 235, 4, 5, 244, 254, 32, 26, 221, 187, 254, 55, 67, 235, 155, 240, 48, 10, 241, 21, 37, 214, 176, 9, 94, 11, 193, 220, 19, 35, 26, 223, 212, 13, 25, 14, 230, 220, 14, 32, 245, 243, 252, 11, 0, 216, 5, 46, 16, 221, 212, 25, 47, 218, 199, 11, 20, 36, 43, 234, 181, 195, 8, 86, 46, 242, 236, 248, 233, 190, 252, 100, 49, 206, 181, 237, 35, 32, 239, 250, 25, 251, 216, 253, 43, 13, 227, 209, 252, 45, 32, 240, 225, 226, 242, 12, 39, 45, 231, 215, 235, 220, 252, 78, 48, 219, 236, 246, 245, 18, 14, 16, 1, 228, 253, 25, 10, 231, 219, 13, 51, 254, 233, 242, 236, 250, 50, 48, 222, 197, 217, 247, 25, 57, 49, 233, 190, 233, 6, 246, 8, 24, 36, 5, 224, 0, 11, 208, 183, 22, 90, 34, 234, 0, 238, 176, 183, 38, 113, 95, 243, 130, 194, 11, 5, 38, 68, 30, 207, 200, 246, 245, 234, 24, 32, 35, 44, 230, 179, 199, 228, 21, 89, 86, 255, 143, 199, 9, 4, 11, 61, 253, 208, 252, 39, 19, 168, 173, 60, 120, 29, 173, 175, 235, 16, 73, 66, 219, 177, 233, 12, 36, 5, 230, 8, 13, 242, 252, 243, 248, 14, 2, 254, 4, 253, 244, 225, 32, 68, 226, 181, 236, 26, 44, 54, 238, 167, 200, 84, 91, 213, 157, 236, 57, 12, 243, 41, 42, 213, 163, 206, 53, 69, 26, 2, 234, 179, 206, 33, 78, 29, 194, 228, 31, 243, 210, 50, 46, 233, 185, 251, 94, 26, 177, 207, 32, 34, 2, 12, 11, 245, 203, 210, 0, 48, 105, 30, 134, 139, 19, 68, 46, 11, 6, 224, 216, 232, 26, 39, 228, 7, 36, 15, 227, 182, 217, 51, 45, 31, 9, 198, 214, 5, 6, 15, 15, 254, 30, 28, 194, 168, 31, 76, 33, 203, 226, 41, 4, 238, 248, 250, 239, 18, 20, 253, 9, 22, 231, 187, 240, 59, 66, 246, 188, 217, 6, 35, 24, 7, 0, 232, 217, 240, 22, 54, 3, 231, 3, 0, 236, 224, 250, 62, 8, 213, 25, 24, 230, 218, 252, 2, 232, 11, 87, 46, 179, 151, 253, 65, 16, 234, 54, 65, 200, 136, 216, 60, 80, 19, 252, 206, 181, 255, 93, 69, 184, 189, 33, 29, 187, 220, 100, 52, 183, 199, 27, 10, 226, 9, 56, 15, 196, 216, 18, 25, 3, 255, 0, 30, 13, 192, 221, 34, 36, 238, 246, 45, 8, 167, 226, 70, 26, 189, 217, 98, 77, 177, 134, 4, 72, 13, 244, 26, 29, 210, 171, 249, 70, 38, 15, 0, 222, 208, 235, 7, 8, 34, 36, 10, 244, 209, 207, 7, 31, 14, 253, 254, 1, 27, 5, 194, 223, 28, 48, 18, 10, 246, 174, 174, 38, 112, 60, 231, 161, 206, 251, 241, 23, 77, 50, 229, 208, 188, 236, 37, 24, 252, 22, 31, 245, 210, 212, 1, 15, 237, 4, 68, 50, 188, 153, 224, 41, 63, 43, 22, 245, 179, 178, 237, 52, 82, 24, 236, 228, 216, 234, 238, 33, 97, 10, 172, 199, 24, 39, 3, 246, 244, 247, 246, 240, 255, 20, 7, 232, 233, 253, 28, 4, 246, 4, 242, 232, 235, 22, 46, 13, 214, 184, 241, 36, 31, 4, 7, 224, 190, 239, 53, 46, 8, 223, 213, 243, 10, 26, 9, 231, 240, 246, 243, 25, 50, 3, 213, 186, 223, 34, 61, 17, 241, 215, 233, 4, 248, 5, 19, 5, 232, 231, 10, 6, 253, 255, 250, 237, 240, 7, 33, 13, 236, 195, 223, 42, 18, 238, 8, 11, 221, 195, 246, 59, 28, 246, 240, 0, 238, 195, 0, 59, 7, 238, 4, 0, 227, 203, 16, 57, 4, 210, 240, 10, 243, 245, 2, 0, 255, 13, 20, 238, 207, 241, 20, 1, 10, 38, 24, 223, 189, 229, 19, 28, 34, 31, 222, 197, 248, 42, 15, 229, 14, 20, 240, 226, 237, 5, 20, 10, 0, 0, 236, 240, 0, 232, 247, 41, 39, 243, 208, 226, 25, 15, 238, 4, 4, 3, 244, 242, 14, 19, 2, 226, 3, 29, 233, 219, 251, 36, 15, 236, 4, 26, 234, 213, 245, 11, 15, 1, 13, 12, 242, 221, 233, 35, 39, 236, 221, 0, 23, 255, 219, 248, 37, 28, 240, 229, 236, 12, 28, 254, 243, 19, 14, 235, 239, 1, 20, 2, 240, 14, 14, 250, 250, 255, 0, 17, 10, 233, 242, 8, 16, 236, 251, 46, 27, 245, 204, 229, 1, 33, 49, 10, 236, 225, 248, 4, 13, 247, 250, 26, 21, 230, 234, 15, 24, 237, 226, 0, 37, 31, 249, 229, 244, 255, 2, 14, 43, 21, 230, 226, 254, 15, 0, 252, 20, 18, 253, 240, 239, 1, 20, 9, 230, 248, 46, 22, 241, 226, 244, 11, 254, 6, 19, 11, 247, 236, 7, 32, 245, 230, 19, 40, 3, 214, 255, 33, 250, 227, 3, 39, 13, 233, 251, 10, 9, 231, 237, 38, 38, 247, 232, 0, 12, 238, 3, 26, 22, 5, 228, 241, 14, 254, 243, 5, 42, 24, 233, 246, 253, 250, 253, 3, 26, 10, 247, 250, 4, 6, 0, 235, 0, 43, 13, 243, 243, 251, 5, 4, 3, 28, 8, 247, 236, 249, 13, 16, 2, 2, 11, 11, 238, 248, 4, 13, 11, 245, 3, 2, 5, 1, 251, 252, 13, 8, 251, 4, 23, 245, 224, 6, 27, 14, 245, 0, 27, 248, 234, 2, 18, 7, 1, 17, 11, 229, 252, 12, 16, 14, 234, 248, 6, 245, 7, 2, 16, 11, 237, 7, 12, 1, 251, 245, 17, 32, 250, 0, 15, 1, 233, 232, 27, 41, 242, 243, 36, 19, 209, 216, 28, 33, 4, 7, 8, 5, 239, 227, 13, 34, 14, 244, 252, 19, 247, 234, 18, 24, 255, 252, 14, 10, 245, 249, 7, 2, 2, 0, 24, 20, 238, 226, 239, 36, 25, 245, 245, 10, 18, 1, 227, 248, 22, 11, 246, 1, 12, 7, 5, 0, 244, 252, 250, 0, 15, 23, 253, 236, 2, 5, 251, 20, 9, 0, 242, 253, 18, 250, 0, 1, 248, 18, 13, 243, 251, 3, 10, 255, 239, 17, 38, 16, 241, 231, 250, 18, 0, 237, 7, 36, 8, 244, 239, 0, 19, 243, 242, 24, 19, 250, 249, 8, 31, 244, 219, 14, 32, 244, 227, 6, 23, 1, 246, 252, 1, 1, 2, 253, 239, 233, 250, 21, 15, 248, 249, 0, 248, 246, 244, 19, 11, 246, 248, 9, 16, 242, 246, 13, 12, 234, 230, 11, 38, 0, 238, 254, 5, 5, 251, 3, 11, 249, 244, 255, 18, 10, 8, 0, 252, 245, 254, 9, 247, 249, 9, 11, 12, 243, 242, 8, 6, 2, 248, 241, 14, 26, 251, 235, 251, 13, 2, 248, 22, 21, 233, 216, 253, 27, 7, 251, 13, 12, 239, 228, 252, 22, 5, 236, 0, 0, 18, 9, 134, 0, 0, 0, 0, 1, 4, 8, 6, 252, 244, 248, 0, 2, 2, 4, 4, 255, 251, 250, 254, 1, 3, 4, 3, 1, 255, 253, 253, 255, 2, 3, 2, 0, 255, 253, 253, 255, 1, 2, 1, 0, 254, 254, 254, 255, 0, 0, 0, 0, 255, 254, 254, 255, 0, 0, 0, 0, 255, 254, 254, 255, 255, 255, 0, 0, 0, 254, 254, 255, 255, 0, 0, 254, 254, 0, 255, 253, 254, 0, 1, 1, 0, 253, 254, 0, 0, 255, 255, 0, 1, 0, 254, 253, 0, 4, 4, 4, 0, 247, 245, 0, 5, 2, 0, 3, 2, 250, 246, 254, 5, 4, 2, 1, 0, 254, 0, 0, 253, 255, 5, 5, 0, 254, 0, 0, 255, 255, 0, 2, 2, 0, 0, 254, 253, 0, 3, 1, 255, 0, 0, 253, 255, 0, 0, 0, 1, 253, 253, 2, 255, 252, 3, 5, 253, 253, 255, 255, 2, 3, 0, 1, 0, 250, 253, 3, 3, 0, 252, 249, 0, 6, 1, 252, 253, 255, 0, 0, 253, 254, 2, 0, 252, 251, 254, 1, 0, 252, 254, 5, 1, 249, 250, 1, 5, 0, 254, 255, 251, 252, 4, 3, 254, 254, 0, 0, 2, 1, 249, 244, 4, 18, 2, 242, 250, 3, 255, 255, 8, 6, 252, 246, 249, 1, 7, 5, 1, 252, 244, 251, 9, 2, 249, 1, 8, 0, 245, 250, 5, 1, 253, 3, 3, 0, 253, 250, 254, 5, 0, 255, 1, 253, 252, 7, 8, 249, 242, 252, 12, 14, 248, 235, 6, 16, 246, 243, 12, 8, 248, 253, 254, 1, 6, 252, 242, 1, 5, 253, 0, 1, 252, 3, 4, 253, 1, 5, 255, 1, 4, 254, 255, 8, 3, 246, 245, 6, 15, 252, 242, 4, 9, 3, 2, 255, 248, 253, 12, 11, 244, 245, 11, 250, 234, 13, 31, 253, 229, 241, 0, 6, 4, 3, 8, 251, 234, 248, 12, 1, 252, 8, 3, 249, 252, 253, 251, 0, 9, 2, 252, 252, 254, 253, 253, 4, 5, 251, 253, 7, 253, 235, 254, 22, 8, 246, 250, 1, 253, 251, 2, 12, 8, 248, 238, 253, 16, 4, 245, 255, 3, 253, 0, 4, 254, 0, 1, 249, 248, 9, 8, 243, 254, 11, 247, 244, 9, 8, 254, 244, 253, 14, 1, 238, 253, 11, 0, 252, 1, 3, 252, 247, 1, 8, 254, 250, 0, 0, 254, 8, 0, 236, 253, 23, 1, 242, 1, 5, 254, 253, 254, 2, 8, 253, 252, 4, 0, 248, 7, 6, 244, 255, 22, 255, 232, 0, 18, 5, 251, 246, 248, 14, 17, 245, 240, 4, 11, 1, 248, 0, 12, 7, 243, 242, 12, 16, 249, 240, 253, 10, 11, 245, 239, 15, 22, 240, 239, 11, 10, 253, 252, 253, 255, 8, 1, 248, 255, 5, 4, 9, 1, 247, 1, 6, 254, 250, 0, 2, 4, 2, 255, 249, 252, 0, 2, 7, 8, 249, 247, 4, 2, 253, 12, 5, 230, 241, 20, 17, 241, 241, 3, 0, 248, 0, 5, 0, 248, 253, 6, 249, 239, 5, 15, 1, 7, 5, 237, 1, 40, 31, 1, 247, 254, 7, 247, 227, 249, 17, 8, 241, 242, 25, 17, 203, 226, 58, 33, 214, 238, 37, 13, 229, 4, 34, 0, 239, 248, 244, 11, 24, 244, 235, 252, 254, 16, 8, 249, 253, 251, 0, 255, 242, 9, 36, 248, 207, 247, 28, 13, 3, 249, 244, 8, 9, 246, 253, 14, 255, 244, 252, 255, 4, 14, 253, 242, 1, 255, 237, 9, 35, 243, 223, 10, 19, 248, 255, 17, 0, 237, 241, 7, 33, 1, 215, 247, 20, 253, 247, 9, 0, 245, 2, 3, 242, 250, 15, 7, 243, 245, 2, 9, 245, 244, 27, 9, 221, 237, 20, 19, 237, 238, 31, 11, 216, 229, 19, 32, 252, 234, 4, 4, 250, 248, 250, 22, 21, 242, 230, 253, 20, 0, 236, 6, 25, 1, 240, 243, 2, 11, 255, 253, 5, 12, 242, 223, 13, 37, 254, 240, 245, 249, 12, 13, 243, 254, 12, 247, 236, 16, 19, 246, 251, 0, 241, 1, 10, 255, 6, 254, 244, 4, 13, 253, 237, 13, 21, 232, 240, 17, 6, 252, 2, 248, 250, 12, 2, 238, 237, 12, 30, 253, 228, 3, 18, 242, 232, 23, 33, 245, 220, 240, 27, 23, 239, 239, 15, 21, 252, 228, 246, 37, 8, 220, 0, 16, 253, 0, 249, 244, 29, 22, 216, 217, 33, 55, 251, 207, 239, 33, 12, 240, 252, 9, 0, 245, 249, 4, 9, 3, 1, 245, 241, 9, 22, 245, 249, 4, 1, 251, 254, 253, 11, 15, 238, 224, 28, 47, 211, 212, 46, 36, 215, 233, 42, 41, 224, 179, 254, 75, 22, 207, 230, 17, 8, 251, 17, 8, 225, 247, 21, 254, 245, 22, 17, 239, 243, 16, 4, 12, 18, 243, 226, 254, 240, 241, 14, 32, 34, 248, 198, 251, 67, 28, 221, 232, 21, 24, 242, 227, 25, 48, 227, 191, 7, 41, 254, 223, 255, 36, 251, 220, 5, 18, 14, 11, 242, 231, 11, 29, 0, 219, 250, 42, 9, 215, 253, 30, 248, 232, 8, 15, 11, 1, 213, 247, 54, 25, 231, 235, 9, 30, 3, 208, 245, 33, 13, 1, 5, 255, 2, 1, 226, 230, 18, 29, 242, 226, 15, 30, 234, 233, 16, 254, 247, 11, 10, 243, 243, 11, 29, 252, 226, 255, 15, 249, 248, 12, 7, 239, 254, 24, 247, 226, 17, 26, 237, 252, 19, 249, 233, 1, 28, 18, 232, 222, 17, 33, 232, 242, 47, 9, 202, 239, 50, 18, 209, 235, 29, 4, 237, 9, 19, 247, 223, 250, 36, 34, 238, 221, 251, 9, 14, 24, 0, 213, 239, 33, 22, 250, 244, 233, 251, 27, 5, 243, 252, 255, 250, 241, 8, 36, 4, 225, 244, 2, 10, 12, 254, 254, 2, 241, 236, 22, 35, 243, 215, 4, 22, 3, 240, 244, 17, 0, 213, 251, 68, 22, 184, 221, 45, 24, 249, 243, 0, 254, 244, 246, 20, 21, 233, 238, 19, 4, 235, 9, 32, 239, 200, 0, 54, 12, 213, 0, 33, 245, 210, 9, 60, 12, 208, 208, 34, 50, 217, 219, 36, 35, 232, 215, 12, 35, 254, 241, 3, 241, 249, 24, 0, 251, 32, 11, 207, 220, 35, 43, 253, 229, 236, 253, 11, 8, 15, 1, 240, 244, 8, 16, 2, 240, 252, 16, 3, 252, 253, 253, 2, 254, 0, 19, 7, 247, 245, 255, 9, 0, 243, 4, 18, 253, 235, 15, 26, 246, 232, 251, 40, 28, 212, 211, 29, 29, 9, 20, 231, 184, 5, 78, 10, 213, 238, 7, 255, 253, 17, 23, 242, 227, 2, 15, 20, 12, 230, 237, 27, 254, 239, 27, 5, 213, 7, 38, 243, 237, 10, 3, 4, 253, 239, 20, 36, 233, 224, 16, 12, 253, 25, 15, 228, 226, 18, 31, 6, 248, 240, 8, 17, 239, 253, 31, 248, 231, 19, 9, 224, 9, 53, 243, 207, 255, 34, 18, 252, 226, 230, 32, 21, 237, 4, 11, 245, 10, 0, 218, 13, 70, 246, 193, 254, 38, 13, 247, 7, 33, 11, 222, 228, 21, 49, 246, 194, 26, 58, 213, 215, 36, 40, 2, 210, 223, 58, 48, 205, 227, 46, 7, 227, 12, 254, 240, 24, 17, 223, 237, 12, 20, 10, 245, 254, 20, 250, 227, 7, 41, 11, 219, 238, 24, 15, 254, 255, 1, 16, 18, 225, 207, 43, 72, 232, 178, 252, 69, 36, 205, 211, 45, 34, 214, 226, 46, 27, 217, 232, 38, 39, 236, 234, 254, 255, 19, 22, 233, 246, 29, 242, 213, 22, 53, 253, 224, 230, 12, 46, 247, 204, 28, 45, 234, 226, 3, 18, 21, 239, 215, 27, 45, 244, 222, 8, 33, 15, 226, 219, 26, 40, 250, 255, 255, 234, 244, 26, 40, 12, 220, 221, 26, 40, 225, 207, 47, 54, 219, 189, 18, 74, 2, 194, 0, 59, 5, 215, 246, 37, 29, 11, 0, 211, 231, 48, 39, 220, 221, 16, 25, 5, 243, 250, 28, 2, 230, 6, 21, 8, 8, 8, 10, 23, 11, 237, 237, 13, 35, 244, 205, 8, 43, 10, 228, 209, 9, 55, 8, 204, 218, 22, 60, 25, 210, 226, 34, 19, 211, 226, 55, 40, 199, 215, 37, 41, 5, 206, 222, 50, 38, 231, 225, 6, 32, 255, 217, 228, 40, 59, 215, 157, 39, 111, 221, 131, 7, 98, 17, 181, 214, 64, 37, 197, 221, 31, 19, 252, 229, 244, 39, 0, 189, 4, 79, 246, 184, 2, 43, 243, 228, 29, 5, 215, 1, 42, 233, 232, 27, 14, 231, 231, 11, 21, 246, 243, 255, 240, 244, 18, 11, 241, 252, 1, 226, 2, 53, 244, 197, 14, 16, 235, 34, 21, 181, 220, 50, 38, 225, 219, 30, 3, 194, 7, 70, 251, 167, 234, 85, 24, 155, 234, 89, 245, 187, 7, 43, 22, 218, 206, 35, 53, 216, 222, 28, 255, 249, 0, 240, 251, 26, 243, 229, 29, 36, 205, 202, 44, 49, 228, 226, 18, 4, 250, 10, 247, 239, 20, 255, 231, 12, 19, 253, 237, 241, 8, 21, 1, 244, 245, 249, 3, 0, 13, 2, 244, 8, 20, 219, 223, 31, 31, 233, 223, 15, 25, 217, 211, 37, 45, 4, 221, 223, 17, 41, 240, 249, 4, 233, 11, 9, 224, 8, 58, 229, 177, 13, 74, 7, 205, 238, 14, 9, 249, 235, 6, 33, 255, 220, 229, 13, 29, 12, 250, 245, 248, 245, 19, 23, 231, 232, 12, 9, 248, 0, 7, 2, 0, 2, 246, 2, 8, 255, 248, 250, 254, 17, 12, 255, 251, 240, 9, 29, 242, 221, 32, 27, 211, 246, 53, 255, 199, 2, 50, 17, 216, 226, 30, 30, 232, 239, 24, 249, 231, 11, 19, 253, 253, 1, 243, 236, 43, 47, 198, 194, 38, 35, 233, 232, 12, 12, 232, 233, 33, 30, 230, 241, 18, 254, 247, 32, 1, 206, 250, 42, 4, 239, 251, 234, 9, 58, 229, 199, 47, 24, 196, 11, 42, 249, 251, 239, 236, 24, 22, 245, 249, 6, 5, 244, 241, 5, 27, 15, 235, 233, 2, 16, 22, 1, 213, 235, 32, 22, 224, 245, 31, 253, 226, 254, 20, 22, 5, 212, 243, 24, 245, 240, 30, 5, 225, 238, 7, 19, 245, 0, 18, 235, 224, 21, 20, 237, 10, 31, 239, 226, 4, 11, 9, 11, 241, 213, 251, 37, 23, 248, 217, 231, 32, 44, 221, 196, 28, 64, 230, 184, 22, 56, 244, 210, 252, 29, 10, 236, 6, 12, 215, 250, 59, 13, 200, 240, 35, 11, 237, 242, 240, 12, 42, 236, 214, 21, 35, 232, 245, 37, 10, 210, 247, 40, 251, 230, 25, 20, 215, 1, 38, 246, 222, 12, 29, 8, 232, 232, 16, 15, 243, 253, 12, 249, 250, 16, 10, 237, 0, 31, 244, 227, 37, 30, 207, 223, 46, 45, 239, 200, 1, 62, 10, 202, 236, 48, 26, 218, 248, 55, 251, 202, 25, 52, 234, 233, 14, 23, 0, 236, 253, 18, 12, 249, 255, 241, 3, 36, 20, 221, 245, 18, 3, 0, 12, 3, 0, 246, 253, 14, 13, 254, 241, 253, 26, 20, 213, 241, 56, 24, 216, 223, 37, 43, 220, 217, 51, 24, 203, 245, 35, 21, 241, 228, 22, 33, 240, 240, 18, 253, 253, 23, 8, 238, 14, 31, 244, 223, 251, 23, 24, 248, 232, 254, 21, 6, 231, 18, 46, 237, 197, 11, 41, 15, 239, 226, 12, 30, 253, 239, 19, 12, 232, 239, 22, 26, 250, 236, 254, 6, 16, 7, 239, 2, 24, 249, 236, 17, 8, 253, 0, 5, 13, 21, 241, 223, 21, 41, 239, 210, 14, 45, 2, 224, 0, 18, 5, 0, 250, 0, 12, 255, 245, 5, 3, 0, 22, 5, 235, 255, 25, 2, 245, 15, 10, 237, 251, 25, 9, 245, 10, 11, 237, 254, 22, 247, 245, 31, 20, 217, 213, 47, 69, 215, 180, 34, 69, 240, 196, 14, 65, 252, 211, 247, 25, 19, 239, 235, 29, 16, 213, 243, 45, 23, 226, 225, 13, 36, 247, 229, 9, 8, 241, 10, 15, 240, 238, 18, 22, 226, 242, 42, 7, 219, 6, 23, 6, 5, 255, 250, 249, 0, 14, 13, 4, 3, 232, 236, 28, 34, 243, 237, 8, 245, 233, 20, 38, 247, 209, 254, 40, 1, 238, 29, 33, 224, 195, 14, 77, 17, 195, 235, 32, 246, 230, 32, 34, 242, 223, 249, 19, 20, 13, 255, 231, 248, 43, 11, 213, 255, 46, 0, 225, 1, 32, 19, 237, 222, 10, 47, 1, 211, 250, 51, 21, 209, 235, 50, 28, 224, 239, 46, 26, 200, 211, 50, 51, 233, 216, 7, 41, 0, 209, 1, 43, 255, 218, 8, 40, 243, 207, 8, 54, 1, 208, 247, 40, 4, 217, 245, 30, 7, 228, 251, 32, 12, 237, 245, 2, 14, 8, 4, 5, 243, 242, 16, 17, 7, 251, 225, 13, 39, 235, 223, 27, 12, 225, 4, 37, 4, 226, 230, 12, 46, 13, 221, 242, 23, 248, 239, 29, 22, 232, 239, 14, 11, 3, 2, 4, 254, 243, 11, 35, 3, 206, 247, 54, 7, 205, 7, 51, 241, 208, 26, 49, 231, 209, 11, 41, 3, 219, 250, 36, 8, 230, 243, 28, 28, 241, 229, 9, 21, 252, 242, 13, 19, 240, 236, 21, 9, 225, 254, 47, 3, 208, 252, 49, 12, 221, 249, 30, 10, 232, 245, 16, 15, 251, 247, 0, 2, 0, 6, 3, 0, 2, 244, 246, 10, 16, 3, 255, 252, 253, 1, 0, 10, 15, 248, 235, 5, 25, 2, 233, 248, 18, 8, 245, 249, 7, 9, 246, 241, 17, 17, 239, 250, 28, 6, 226, 252, 31, 13, 225, 239, 25, 17, 232, 242, 27, 11, 232, 2, 25, 2, 250, 3, 255, 247, 4, 0, 0, 225, 1, 33, 0, 8, 4, 7, 7, 20, 44, 10, 4, 9, 250, 252, 247, 237, 225, 218, 237, 231, 235, 246, 241, 0, 9, 13, 10, 0, 14, 14, 2, 3, 246, 240, 239, 232, 230, 219, 224, 229, 226, 235, 237, 236, 246, 248, 247, 245, 244, 247, 241, 236, 233, 223, 217, 220, 218, 209, 207, 210, 214, 222, 230, 235, 237, 243, 251, 0, 255, 255, 252, 252, 253, 253, 250, 250, 0, 6, 10, 14, 19, 24, 34, 38, 41, 43, 50, 56, 54, 55, 57, 61, 79, 76, 73, 75, 67, 65, 59, 47, 32, 16, 15, 11, 6, 5, 4, 11, 21, 28, 36, 30, 33, 35, 25, 21, 12, 253, 245, 233, 220, 213, 200, 197, 192, 192, 198, 192, 197, 212, 215, 223, 231, 236, 239, 236, 241, 236, 222, 224, 218, 215, 212, 206, 205, 204, 208, 221, 219, 227, 231, 242, 253, 0, 2, 0, 0, 4, 0, 0, 0, 1, 0, 2, 8, 6, 13, 16, 20, 24, 27, 27, 25, 27, 24, 8, 4, 254, 231, 221, 178, 176, 59, 41, 45, 88, 81, 98, 114, 125, 80, 4, 22, 232, 215, 213, 158, 170, 198, 247, 18, 0, 44, 85, 91, 125, 107, 85, 60, 43, 37, 241, 222, 212, 196, 224, 225, 222, 239, 3, 18, 3, 5, 16, 19, 26, 29, 16, 254, 255, 14, 6, 2, 245, 226, 242, 245, 252, 247, 228, 235, 246, 246, 250, 237, 231, 228, 228, 235, 217, 218, 213, 205, 221, 216, 222, 235, 234, 242, 235, 236, 235, 226, 231, 213, 204, 208, 206, 205, 203, 205, 209, 217, 235, 245, 249, 0, 10, 12, 22, 28, 24, 14, 17, 15, 14, 20, 27, 37, 41, 49, 60, 59, 65, 63, 62, 66, 63, 68, 66, 63, 63, 58, 59, 59, 61, 56, 42, 42, 45, 40, 47, 37, 30, 20, 8, 6, 1, 250, 243, 237, 243, 244, 243, 244, 231, 230, 236, 224, 230, 219, 211, 211, 212, 214, 211, 205, 209, 197, 202, 191, 187, 194, 195, 203, 202, 206, 217, 217, 229, 236, 219, 218, 203, 207, 209, 209, 218, 221, 233, 248, 0, 14, 11, 20, 28, 27, 35, 16, 1, 0, 252, 1, 254, 249, 0, 9, 36, 50, 71, 96, 98, 110, 120, 114, 104, 103, 84, 64, 43, 27, 13, 249, 234, 219, 215, 226, 228, 238, 248, 254, 16, 27, 36, 42, 34, 23, 15, 254, 239, 221, 194, 182, 179, 181, 197, 214, 236, 1, 17, 49, 59, 66, 64, 45, 35, 14, 1, 246, 222, 223, 224, 232, 3, 15, 29, 43, 53, 67, 60, 49, 37, 14, 253, 234, 217, 201, 191, 190, 191, 193, 204, 214, 223, 235, 242, 241, 240, 233, 225, 213, 204, 187, 179, 171, 164, 160, 160, 178, 210, 226, 244, 4, 0, 247, 239, 240, 224, 217, 225, 217, 230, 246, 0, 0, 0, 0, 108, 0, 5, 0, 5, 0, 196, 0, 114, 1, 84, 4, 252, 8, 88, 12, 91, 14, 32, 27, 70, 18, 46, 20, 38, 12, 16, 16, 6, 0, 125, 60, 135, 120, 120, 120, 80, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 7, 0, 196, 0, 114, 1, 84, 4, 252, 8, 88, 12, 91, 14, 32, 27, 0, 19, 47, 20, 38, 12, 16, 16, 6, 0, 125, 60, 135, 120, 120, 120, 80, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 216, 0, 184, 1, 169, 6, 96, 9, 128, 12, 66, 14, 192, 27, 9, 17, 28, 40, 36, 33, 32, 19, 7, 0, 120, 105, 120, 120, 120, 120, 30, 105, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 212, 0, 179, 1, 155, 7, 96, 9, 228, 12, 216, 14, 160, 27, 29, 15, 25, 37, 34, 40, 30, 18, 6, 0, 120, 105, 180, 120, 120, 120, 24, 96, 99, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 200, 0, 164, 1, 141, 8, 0, 10, 32, 13, 110, 15, 64, 27, 0, 95, 63, 93, 97, 97, 76, 45, 16, 0, 120, 105, 120, 120, 120, 120, 15, 75, 75, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 140, 0, 3, 0, 1, 0, 148, 0, 128, 1, 168, 7, 196, 9, 228, 12, 50, 15, 96, 25, 50, 6, 8, 22, 28, 22, 24, 15, 6, 3, 160, 92, 120, 143, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 148, 0, 128, 1, 168, 7, 196, 9, 228, 12, 50, 15, 96, 25, 90, 6, 8, 22, 28, 22, 24, 15, 6, 3, 160, 92, 120, 143, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 148, 0, 80, 1, 32, 8, 60, 10, 42, 13, 50, 15, 96, 25, 0, 1, 4, 11, 14, 12, 12, 7, 3, 1, 160, 92, 120, 143, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 175, 0, 4, 0, 1, 0, 104, 0, 104, 1, 72, 8, 120, 10, 52, 13, 40, 15, 96, 25, 45, 54, 26, 77, 50, 48, 50, 29, 12, 5, 160, 95, 120, 167, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 104, 0, 104, 1, 72, 8, 120, 10, 52, 13, 40, 15, 96, 25, 70, 120, 40, 116, 76, 72, 75, 44, 18, 8, 160, 95, 120, 167, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 104, 0, 104, 1, 72, 8, 120, 10, 52, 13, 40, 15, 96, 25, 60, 97, 36, 104, 68, 64, 67, 39, 16, 7, 160, 95, 120, 167, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 104, 0, 104, 1, 72, 8, 100, 10, 72, 13, 40, 15, 96, 25, 0, 43, 24, 69, 45, 43, 45, 26, 10, 5, 160, 95, 120, 167, 120, 120, 130, 95, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 90, 0, 3, 0, 1, 0, 192, 0, 144, 1, 168, 7, 236, 9, 32, 13, 60, 15, 96, 25, 50, 38, 29, 64, 37, 26, 24, 8, 5, 5, 160, 90, 120, 120, 120, 120, 130, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 192, 0, 152, 1, 148, 7, 236, 9, 32, 13, 60, 15, 96, 25, 90, 84, 44, 96, 64, 44, 40, 20, 8, 8, 160, 90, 120, 120, 120, 120, 130, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 192, 0, 152, 1, 168, 7, 236, 9, 32, 13, 60, 15, 96, 25, 0, 31, 26, 58, 41, 29, 21, 14, 4, 5, 160, 90, 120, 120, 120, 120, 130, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 195, 0, 4, 0, 1, 0, 141, 0, 84, 1, 144, 6, 16, 9, 172, 13, 160, 15, 104, 25, 45, 64, 13, 76, 60, 68, 68, 40, 15, 12, 174, 115, 127, 122, 122, 132, 187, 130, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 141, 0, 84, 1, 144, 6, 16, 9, 172, 13, 160, 15, 104, 25, 80, 64, 13, 76, 60, 68, 68, 40, 15, 12, 174, 115, 127, 122, 122, 132, 187, 130, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 141, 0, 84, 1, 144, 6, 16, 9, 172, 13, 160, 15, 104, 25, 70, 53, 11, 69, 54, 62, 61, 36, 13, 11, 174, 115, 127, 122, 122, 132, 187, 130, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 141, 0, 84, 1, 144, 6, 16, 9, 172, 13, 160, 15, 104, 25, 0, 34, 9, 55, 43, 49, 49, 29, 11, 8, 174, 115, 127, 122, 122, 132, 187, 130, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 170, 0, 4, 0, 1, 0, 31, 1, 77, 2, 255, 6, 225, 9, 104, 13, 15, 15, 224, 28, 50, 32, 26, 48, 51, 47, 36, 27, 9, 5, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 31, 1, 77, 2, 255, 6, 225, 9, 104, 13, 15, 15, 224, 28, 60, 81, 42, 77, 82, 75, 58, 42, 14, 9, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 31, 1, 77, 2, 255, 6, 225, 9, 104, 13, 15, 15, 224, 28, 60, 73, 40, 73, 77, 71, 55, 40, 13, 8, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 31, 1, 77, 2, 255, 6, 225, 9, 104, 13, 15, 15, 224, 28, 0, 32, 26, 48, 51, 47, 36, 27, 9, 5, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 170, 0, 4, 0, 1, 0, 31, 1, 176, 1, 255, 6, 225, 9, 104, 13, 15, 15, 224, 28, 50, 34, 26, 40, 51, 47, 36, 27, 9, 5, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 31, 1, 184, 1, 255, 6, 225, 9, 104, 13, 15, 15, 224, 28, 60, 71, 42, 49, 82, 75, 58, 42, 14, 9, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 31, 1, 160, 1, 255, 6, 225, 9, 104, 13, 15, 15, 224, 28, 60, 60, 40, 39, 77, 71, 55, 40, 13, 8, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 31, 1, 168, 1, 255, 6, 225, 9, 104, 13, 15, 15, 224, 28, 0, 26, 26, 26, 51, 47, 36, 27, 9, 5, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 170, 0, 4, 0, 1, 0, 31, 1, 77, 2, 255, 6, 225, 9, 104, 13, 15, 15, 224, 28, 50, 24, 26, 40, 43, 38, 31, 21, 9, 5, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 31, 1, 77, 2, 255, 6, 225, 9, 104, 13, 15, 15, 224, 28, 60, 55, 42, 60, 64, 57, 49, 34, 14, 9, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 31, 1, 77, 2, 255, 6, 225, 9, 104, 13, 15, 15, 224, 28, 60, 54, 40, 61, 64, 54, 50, 32, 13, 8, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 31, 1, 77, 2, 255, 6, 225, 9, 104, 13, 15, 15, 224, 28, 0, 23, 26, 40, 40, 38, 31, 21, 9, 5, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 220, 0, 4, 0, 1, 0, 153, 0, 198, 1, 44, 3, 255, 9, 194, 11, 151, 14, 244, 26, 50, 41, 24, 49, 52, 39, 36, 20, 14, 6, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 153, 0, 198, 1, 44, 3, 255, 9, 194, 11, 151, 14, 244, 26, 90, 63, 31, 60, 64, 51, 46, 26, 19, 8, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 153, 0, 192, 1, 44, 3, 255, 9, 194, 11, 151, 14, 244, 26, 80, 53, 28, 54, 61, 45, 42, 23, 17, 7, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 153, 0, 176, 1, 56, 3, 216, 9, 194, 11, 151, 14, 244, 26, 0, 31, 21, 43, 46, 34, 31, 18, 12, 5, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 140, 0, 3, 0, 1, 0, 204, 0, 158, 2, 252, 4, 60, 10, 168, 12, 10, 15, 0, 28, 50, 54, 35, 56, 76, 42, 50, 25, 14, 8, 170, 165, 150, 120, 120, 120, 170, 180, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 204, 0, 93, 2, 208, 4, 60, 10, 168, 12, 10, 15, 0, 28, 90, 108, 43, 86, 98, 54, 65, 32, 19, 8, 170, 165, 150, 120, 120, 120, 170, 180, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 204, 0, 93, 2, 252, 4, 60, 10, 168, 12, 10, 15, 0, 28, 0, 52, 31, 61, 69, 38, 46, 22, 13, 9, 167, 165, 150, 120, 120, 120, 167, 180, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 100, 0, 4, 0, 1, 0, 176, 0, 64, 1, 132, 3, 56, 9, 12, 13, 60, 15, 144, 26, 50, 45, 3, 73, 36, 21, 21, 30, 12, 7, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 176, 0, 64, 1, 132, 3, 56, 9, 12, 13, 60, 15, 144, 26, 50, 77, 4, 96, 48, 28, 28, 40, 16, 10, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 176, 0, 64, 1, 132, 3, 56, 9, 12, 13, 60, 15, 144, 26, 70, 61, 3, 85, 42, 24, 24, 35, 14, 8, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 176, 0, 64, 1, 132, 3, 56, 9, 12, 13, 60, 15, 144, 26, 0, 30, 2, 60, 30, 17, 17, 25, 10, 6, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 50, 0, 5, 0, 1, 0, 135, 0, 96, 1, 138, 6, 68, 9, 128, 12, 128, 14, 153, 24, 50, 48, 12, 67, 56, 50, 45, 32, 10, 11, 178, 122, 132, 123, 123, 141, 187, 130, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 135, 0, 96, 1, 138, 6, 68, 9, 128, 12, 128, 14, 153, 24, 115, 80, 16, 86, 72, 64, 58, 41, 13, 14, 178, 122, 132, 123, 123, 141, 187, 130, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 135, 0, 96, 1, 138, 6, 68, 9, 128, 12, 128, 14, 153, 24, 55, 51, 12, 69, 58, 51, 47, 33, 10, 11, 178, 122, 132, 123, 123, 141, 187, 130, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 135, 0, 88, 1, 138, 6, 68, 9, 128, 12, 128, 14, 153, 24, 40, 43, 10, 64, 51, 48, 44, 31, 10, 10, 178, 122, 132, 123, 123, 141, 187, 130, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 135, 0, 80, 1, 138, 6, 68, 9, 128, 12, 128, 14, 153, 24, 0, 40, 9, 63, 46, 40, 35, 30, 8, 8, 181, 122, 132, 123, 123, 141, 190, 130, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 5, 0, 1, 0, 84, 0, 104, 1, 70, 6, 212, 8, 148, 12, 41, 14, 64, 26, 42, 56, 18, 76, 56, 42, 42, 39, 12, 8, 162, 150, 135, 120, 120, 120, 102, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 84, 0, 104, 1, 26, 6, 212, 8, 148, 12, 116, 14, 192, 25, 40, 87, 23, 91, 86, 77, 60, 55, 19, 8, 167, 135, 135, 120, 120, 120, 107, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 88, 0, 104, 1, 48, 6, 172, 8, 148, 12, 116, 14, 192, 25, 50, 80, 24, 94, 68, 74, 55, 53, 21, 8, 167, 120, 135, 120, 120, 120, 107, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 84, 0, 64, 1, 106, 5, 192, 8, 68, 12, 116, 14, 192, 25, 67, 39, 12, 67, 43, 38, 32, 31, 14, 8, 165, 135, 135, 120, 120, 120, 105, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 84, 0, 34, 1, 255, 3, 172, 8, 28, 12, 116, 14, 192, 25, 0, 34, 17, 60, 37, 18, 21, 21, 10, 8, 165, 135, 135, 120, 120, 120, 105, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 139, 0, 3, 0, 1, 0, 112, 0, 13, 2, 161, 5, 36, 9, 188, 12, 116, 14, 96, 27, 50, 60, 34, 66, 80, 45, 47, 36, 18, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 116, 0, 13, 2, 161, 5, 36, 9, 188, 12, 116, 14, 96, 27, 90, 87, 41, 79, 96, 54, 56, 43, 23, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 116, 0, 13, 2, 161, 5, 36, 9, 188, 12, 116, 14, 96, 27, 0, 46, 30, 58, 70, 39, 41, 32, 16, 9, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 105, 0, 4, 0, 5, 0, 88, 0, 24, 1, 6, 9, 140, 10, 32, 13, 191, 14, 224, 28, 30, 19, 10, 42, 37, 34, 45, 22, 7, 0, 135, 120, 135, 120, 120, 120, 30, 105, 75, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 7, 0, 88, 0, 24, 1, 174, 8, 196, 9, 32, 13, 91, 14, 224, 28, 17, 24, 7, 55, 33, 35, 37, 24, 7, 0, 135, 90, 135, 120, 120, 120, 30, 105, 75, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 5, 0, 88, 0, 84, 1, 188, 7, 36, 9, 168, 12, 191, 14, 224, 28, 58, 20, 5, 45, 20, 48, 40, 26, 5, 0, 135, 135, 135, 120, 120, 120, 30, 90, 75, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 168, 0, 144, 1, 56, 7, 212, 8, 168, 12, 191, 14, 224, 28, 0, 86, 34, 108, 58, 77, 61, 37, 10, 0, 120, 105, 120, 120, 120, 120, 30, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 0, 0, 6, 0, 5, 0, 180, 0, 248, 2, 185, 8, 200, 10, 32, 13, 116, 14, 0, 29, 45, 13, 4, 8, 23, 36, 46, 26, 7, 0, 120, 62, 150, 120, 120, 120, 45, 92, 90, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 196, 0, 229, 1, 136, 6, 36, 9, 28, 12, 116, 14, 0, 28, 50, 37, 32, 53, 66, 51, 49, 29, 6, 0, 120, 120, 150, 120, 120, 120, 75, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 244, 0, 7, 3, 43, 4, 240, 10, 148, 12, 41, 14, 96, 27, 59, 126, 29, 73, 116, 52, 45, 45, 15, 7, 167, 165, 135, 120, 120, 120, 167, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 228, 0, 7, 3, 10, 4, 240, 10, 52, 13, 41, 14, 224, 27, 58, 116, 30, 82, 97, 55, 57, 54, 13, 8, 167, 135, 150, 120, 120, 120, 167, 90, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 228, 0, 243, 2, 255, 3, 160, 10, 148, 12, 41, 14, 224, 27, 38, 71, 34, 67, 87, 37, 41, 38, 14, 8, 167, 135, 120, 120, 120, 120, 167, 75, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 164, 0, 27, 3, 98, 4, 20, 10, 148, 12, 41, 14, 224, 27, 0, 40, 24, 60, 59, 29, 25, 25, 8, 8, 167, 120, 120, 120, 120, 120, 227, 105, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 154, 0, 4, 0, 1, 0, 248, 0, 137, 3, 40, 5, 140, 10, 112, 13, 35, 15, 32, 28, 50, 60, 34, 70, 69, 40, 27, 24, 9, 8, 210, 150, 105, 120, 120, 120, 255, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 72, 1, 157, 3, 40, 5, 140, 10, 112, 13, 191, 14, 32, 28, 40, 66, 42, 75, 65, 49, 43, 27, 13, 7, 207, 150, 105, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 72, 1, 157, 3, 40, 5, 140, 10, 112, 13, 191, 14, 32, 28, 65, 72, 41, 80, 67, 56, 42, 26, 13, 6, 210, 150, 105, 120, 120, 120, 240, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 16, 1, 128, 3, 60, 5, 100, 10, 112, 13, 191, 14, 160, 28, 0, 54, 35, 70, 63, 37, 33, 26, 8, 9, 210, 135, 105, 120, 120, 120, 255, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 154, 0, 4, 0, 1, 0, 248, 0, 137, 3, 40, 5, 140, 10, 112, 13, 35, 15, 32, 28, 50, 60, 34, 70, 69, 40, 27, 24, 9, 8, 210, 150, 105, 120, 120, 120, 255, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 72, 1, 157, 3, 40, 5, 140, 10, 112, 13, 191, 14, 32, 28, 40, 102, 42, 95, 85, 49, 43, 27, 13, 7, 207, 150, 105, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 72, 1, 157, 3, 40, 5, 140, 10, 112, 13, 191, 14, 32, 28, 65, 97, 41, 93, 83, 56, 42, 26, 13, 6, 210, 150, 105, 120, 120, 120, 240, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 16, 1, 128, 3, 60, 5, 100, 10, 112, 13, 191, 14, 160, 28, 0, 54, 35, 70, 63, 37, 33, 26, 8, 9, 210, 135, 105, 120, 120, 120, 255, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 50, 0, 4, 0, 5, 0, 4, 0, 16, 1, 220, 5, 136, 9, 58, 14, 216, 19, 224, 21, 40, 5, 8, 23, 10, 6, 6, 6, 4, 4, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 4, 0, 16, 1, 220, 5, 136, 9, 58, 14, 216, 19, 224, 21, 10, 6, 9, 25, 11, 6, 6, 6, 5, 4, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 5, 0, 4, 0, 16, 1, 220, 5, 144, 9, 58, 14, 216, 19, 224, 21, 0, 6, 9, 26, 12, 7, 7, 7, 5, 4, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 17, 0, 4, 0, 16, 1, 220, 5, 160, 9, 58, 14, 216, 19, 224, 21, 0, 6, 9, 25, 11, 6, 6, 6, 5, 4, 150, 125, 137, 137, 150, 175, 150, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 253, 2, 193, 0, 1, 254, 252, 255, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 2, 4, 6, 8, 9, 11, 10, 9, 8, 6, 5, 5, 6, 7, 8, 10, 11, 12, 13, 13, 12, 11, 10, 10, 9, 8, 8, 8, 8, 9, 9, 8, 7, 5, 3, 3, 4, 4, 1, 254, 251, 251, 251, 252, 252, 251, 252, 252, 252, 252, 252, 252, 252, 252, 252, 253, 251, 245, 236, 226, 218, 215, 216, 221, 227, 234, 238, 240, 239, 237, 234, 231, 229, 228, 230, 234, 238, 242, 246, 252, 0, 6, 10, 15, 17, 18, 16, 13, 9, 6, 5, 7, 11, 17, 22, 26, 28, 28, 27, 23, 19, 15, 10, 7, 4, 1, 0, 255, 255, 254, 254, 254, 254, 253, 252, 250, 247, 243, 240, 237, 235, 234, 235, 237, 239, 242, 244, 246, 248, 249, 250, 251, 252, 253, 254, 254, 255, 0, 0, 1, 3, 4, 5, 6, 6, 5, 4, 2, 0, 253, 252, 251, 252, 254, 0, 3, 5, 5, 5, 3, 1, 0, 254, 253, 251, 250, 250, 251, 253, 0, 1, 3, 3, 3, 3, 2, 1, 0, 0, 0, 1, 2, 3, 4, 4, 4, 4, 3, 3, 3, 4, 4, 4, 4, 3, 2, 1, 0, 0, 255, 255, 255, 255, 0, 0, 1, 2, 3, 2, 0, 255, 253, 252, 253, 254, 0, 0, 2, 3, 4, 4, 3, 2, 2, 2, 3, 3, 2, 0, 0, 0, 2, 4, 5, 6, 6, 4, 2, 0, 254, 253, 252, 251, 250, 250, 252, 255, 0, 0, 0, 255, 255, 0, 0, 255, 253, 252, 252, 253, 253, 253, 252, 252, 253, 252, 251, 250, 252, 253, 252, 250, 251, 0, 8, 14, 16, 14, 13, 13, 13, 11, 8, 6, 6, 7, 9, 15, 23, 32, 39, 40, 27, 253, 209, 166, 138, 130, 142, 167, 197, 229, 255, 12, 11, 0, 241, 231, 228, 231, 236, 242, 248, 253, 0, 3, 9, 20, 36, 53, 67, 73, 68, 54, 34, 13, 253, 242, 239, 244, 255, 12, 23, 27, 23, 14, 3, 249, 240, 234, 230, 229, 227, 224, 219, 215, 212, 214, 220, 230, 240, 249, 254, 255, 250, 243, 235, 229, 228, 232, 241, 252, 6, 15, 21, 24, 25, 24, 22, 22, 21, 20, 17, 14, 10, 5, 2, 0, 0, 3, 7, 11, 13, 12, 7, 0, 248, 240, 234, 229, 228, 229, 232, 236, 240, 242, 244, 245, 246, 247, 248, 250, 253, 255, 0, 0, 0, 0, 2, 5, 10, 15, 20, 25, 26, 26, 23, 19, 15, 11, 8, 7, 6, 5, 4, 4, 3, 3, 3, 3, 3, 2, 0, 254, 250, 245, 241, 237, 237, 238, 242, 246, 252, 1, 7, 11, 12, 12, 11, 10, 8, 6, 6, 6, 8, 10, 12, 15, 17, 20, 22, 24, 24, 21, 15, 9, 3, 0, 252, 249, 249, 251, 255, 2, 3, 2, 0, 255, 252, 250, 247, 245, 246, 249, 252, 254, 254, 252, 252, 252, 255, 3, 8, 11, 12, 9, 6, 3, 2, 1, 2, 3, 4, 6, 7, 8, 9, 9, 8, 6, 4, 3, 3, 4, 7, 9, 9, 8, 5, 2, 1, 3, 7, 12, 14, 12, 4, 249, 234, 221, 213, 214, 223, 237, 254, 13, 23, 24, 17, 6, 252, 243, 237, 238, 244, 254, 4, 5, 0, 252, 252, 252, 247, 237, 226, 218, 215, 216, 221, 227, 234, 239, 240, 239, 238, 235, 232, 230, 229, 231, 234, 239, 243, 247, 252, 1, 6, 11, 15, 17, 18, 17, 14, 10, 7, 6, 8, 12, 17, 23, 27, 29, 29, 27, 24, 19, 15, 11, 7, 4, 1, 0, 0, 255, 254, 254, 254, 254, 254, 253, 250, 247, 244, 241, 238, 235, 234, 235, 237, 240, 242, 244, 246, 248, 250, 251, 252, 252, 253, 254, 255, 0, 0, 1, 3, 4, 5, 6, 7, 7, 6, 5, 2, 0, 254, 252, 251, 252, 255, 1, 3, 5, 6, 5, 4, 2, 0, 255, 253, 251, 250, 251, 252, 254, 0, 2, 3, 3, 3, 3, 3, 2, 0, 0, 0, 1, 2, 3, 4, 5, 5, 4, 4, 4, 4, 4, 5, 5, 4, 4, 3, 2, 0, 0, 0, 255, 255, 0, 0, 0, 1, 3, 3, 3, 1, 0, 254, 253, 253, 255, 0, 1, 3, 4, 4, 5, 4, 3, 2, 2, 3, 3, 3, 1, 1, 1, 3, 5, 6, 7, 6, 5, 2, 0, 255, 253, 252, 251, 250, 251, 253, 255, 1, 1, 0, 255, 0, 0, 0, 0, 254, 252, 0, 0, 0, 50, 0, 5, 0, 1, 0, 132, 0, 16, 1, 28, 7, 232, 8, 228, 12, 96, 14, 100, 25, 45, 35, 17, 54, 37, 34, 34, 31, 8, 11, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 132, 0, 16, 1, 28, 7, 232, 8, 228, 12, 96, 14, 100, 25, 50, 68, 24, 76, 52, 48, 48, 44, 12, 16, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 132, 0, 16, 1, 28, 7, 232, 8, 228, 12, 96, 14, 100, 25, 85, 55, 21, 68, 46, 43, 43, 39, 10, 14, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 132, 0, 16, 1, 28, 7, 232, 8, 228, 12, 96, 14, 100, 25, 40, 43, 19, 60, 41, 38, 38, 35, 9, 12, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 132, 0, 16, 1, 8, 7, 212, 8, 228, 12, 96, 14, 100, 25, 0, 29, 15, 50, 34, 29, 31, 29, 7, 10, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 235, 0, 5, 0, 1, 0, 244, 0, 35, 2, 48, 7, 232, 9, 38, 13, 144, 14, 176, 28, 45, 28, 23, 46, 45, 48, 37, 27, 8, 6, 202, 118, 143, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 244, 0, 35, 2, 48, 7, 232, 9, 38, 13, 144, 14, 176, 28, 80, 82, 40, 79, 77, 81, 63, 46, 14, 10, 202, 118, 143, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 238, 0, 18, 2, 230, 6, 214, 9, 6, 13, 144, 14, 122, 28, 80, 72, 37, 74, 71, 73, 58, 41, 14, 9, 198, 118, 144, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 184, 0, 120, 1, 192, 3, 46, 9, 224, 11, 136, 14, 144, 26, 30, 48, 26, 59, 47, 37, 32, 21, 15, 7, 162, 122, 155, 120, 120, 120, 162, 120, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 184, 0, 120, 1, 212, 3, 56, 9, 224, 11, 136, 14, 144, 26, 0, 29, 20, 45, 39, 32, 28, 17, 13, 5, 162, 125, 155, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 140, 0, 4, 0, 1, 0, 56, 1, 73, 3, 129, 5, 246, 9, 86, 13, 211, 14, 92, 28, 50, 26, 22, 47, 48, 30, 24, 17, 7, 3, 211, 144, 124, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 56, 1, 73, 3, 129, 5, 246, 9, 86, 13, 211, 14, 92, 28, 25, 91, 41, 88, 89, 56, 45, 32, 13, 7, 211, 144, 124, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 56, 1, 73, 3, 129, 5, 246, 9, 86, 13, 211, 14, 92, 28, 65, 87, 40, 86, 87, 54, 44, 31, 13, 6, 211, 144, 124, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 57, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 56, 1, 73, 3, 129, 5, 246, 9, 86, 13, 211, 14, 92, 28, 0, 27, 23, 48, 49, 30, 24, 17, 7, 3, 211, 144, 124, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 56, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 48, 0, 3, 0, 5, 0, 168, 0, 160, 1, 232, 3, 216, 9, 72, 13, 168, 17, 106, 24, 25, 10, 31, 19, 3, 3, 7, 3, 7, 11, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 9, 0, 168, 0, 160, 1, 232, 3, 216, 9, 72, 13, 168, 17, 106, 24, 23, 10, 31, 19, 3, 3, 7, 3, 7, 7, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 168, 0, 160, 1, 232, 3, 216, 9, 72, 13, 168, 17, 106, 24, 0, 10, 31, 19, 3, 3, 7, 3, 7, 7, 97, 125, 137, 137, 150, 175, 97, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 175, 0, 4, 0, 1, 0, 24, 1, 96, 3, 0, 5, 140, 10, 132, 13, 140, 15, 32, 28, 45, 44, 27, 62, 53, 40, 30, 19, 9, 4, 217, 155, 105, 120, 120, 120, 247, 170, 165, 44, 65, 75, 130, 54, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 24, 1, 96, 3, 0, 5, 140, 10, 132, 13, 140, 15, 32, 28, 70, 93, 40, 90, 76, 58, 43, 27, 13, 6, 217, 155, 105, 120, 120, 120, 247, 170, 165, 44, 65, 75, 130, 54, 0, 0, 0, 0, 50, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 24, 1, 96, 3, 0, 5, 140, 10, 132, 13, 140, 15, 32, 28, 60, 83, 38, 85, 72, 55, 41, 26, 12, 6, 217, 155, 105, 120, 120, 120, 247, 170, 165, 44, 65, 75, 130, 54, 0, 0, 0, 0, 50, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 24, 1, 96, 3, 0, 5, 140, 10, 132, 13, 140, 15, 32, 28, 0, 39, 26, 58, 50, 38, 28, 18, 8, 4, 217, 155, 105, 120, 120, 120, 247, 170, 165, 44, 65, 75, 130, 54, 0, 0, 0, 0, 50, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 0, 0, 4, 0, 33, 0, 152, 0, 40, 1, 232, 8, 4, 11, 52, 13, 0, 15, 160, 26, 52, 30, 12, 39, 42, 51, 51, 33, 13, 6, 167, 190, 120, 120, 120, 120, 167, 190, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 152, 0, 40, 1, 232, 8, 4, 11, 52, 13, 0, 15, 160, 26, 75, 47, 15, 49, 53, 64, 64, 41, 16, 8, 167, 190, 120, 120, 120, 120, 167, 190, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 152, 0, 40, 1, 232, 8, 4, 11, 52, 13, 0, 15, 160, 26, 79, 38, 13, 44, 47, 58, 58, 37, 14, 7, 167, 190, 120, 120, 120, 120, 167, 190, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 84, 0, 240, 0, 94, 9, 4, 11, 32, 13, 60, 15, 64, 26, 0, 22, 11, 34, 39, 37, 38, 21, 9, 8, 175, 200, 105, 120, 120, 120, 175, 200, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 150, 0, 4, 0, 1, 0, 186, 0, 152, 2, 128, 5, 156, 9, 248, 12, 141, 14, 160, 27, 50, 37, 31, 52, 63, 36, 29, 23, 13, 0, 180, 145, 125, 120, 120, 120, 200, 127, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 186, 0, 152, 2, 128, 5, 156, 9, 248, 12, 141, 14, 160, 27, 60, 68, 43, 72, 86, 50, 39, 32, 18, 0, 180, 145, 125, 120, 120, 120, 200, 127, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 186, 0, 152, 2, 128, 5, 156, 9, 248, 12, 141, 14, 160, 27, 40, 61, 40, 68, 81, 47, 37, 30, 17, 0, 180, 145, 125, 120, 120, 120, 200, 127, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 186, 0, 152, 2, 128, 5, 156, 9, 248, 12, 141, 14, 160, 27, 0, 32, 29, 49, 59, 34, 27, 22, 12, 0, 180, 145, 125, 120, 120, 120, 200, 127, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 247, 0, 5, 0, 1, 0, 186, 0, 146, 2, 128, 5, 156, 9, 248, 12, 141, 14, 160, 27, 45, 41, 33, 55, 66, 38, 30, 24, 13, 0, 180, 150, 125, 120, 120, 120, 200, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 186, 0, 146, 2, 128, 5, 156, 9, 248, 12, 141, 14, 160, 27, 60, 62, 41, 68, 82, 47, 37, 30, 17, 0, 180, 150, 125, 120, 120, 120, 200, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 186, 0, 146, 2, 128, 5, 156, 9, 248, 12, 141, 14, 160, 27, 80, 49, 36, 60, 72, 42, 33, 27, 15, 0, 180, 150, 125, 120, 120, 120, 200, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 208, 0, 136, 1, 8, 2, 20, 10, 216, 11, 234, 13, 15, 28, 62, 27, 39, 30, 16, 28, 28, 19, 6, 6, 186, 83, 122, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 208, 0, 136, 1, 8, 2, 20, 10, 216, 11, 234, 13, 15, 28, 0, 16, 32, 22, 14, 24, 24, 17, 5, 5, 186, 83, 122, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 7, 0, 1, 0, 206, 0, 200, 1, 72, 3, 38, 10, 208, 11, 47, 14, 159, 27, 24, 50, 28, 50, 69, 23, 36, 20, 10, 6, 177, 100, 131, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 206, 0, 200, 1, 72, 3, 38, 10, 208, 11, 47, 14, 159, 27, 55, 78, 35, 63, 87, 28, 45, 25, 13, 7, 177, 100, 131, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 206, 0, 200, 1, 72, 3, 38, 10, 208, 11, 47, 14, 159, 27, 65, 70, 33, 60, 82, 27, 43, 24, 12, 7, 177, 100, 131, 120, 120, 120, 105, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 5, 0, 201, 0, 184, 1, 80, 5, 16, 9, 243, 11, 67, 14, 134, 27, 25, 40, 26, 56, 46, 36, 43, 24, 12, 7, 176, 151, 153, 120, 120, 120, 105, 177, 157, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 152, 0, 120, 1, 244, 6, 172, 8, 168, 12, 0, 15, 160, 26, 48, 30, 14, 43, 43, 39, 46, 32, 15, 7, 167, 197, 120, 120, 120, 120, 167, 197, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 152, 0, 56, 1, 248, 7, 220, 10, 12, 13, 0, 15, 160, 26, 30, 27, 12, 42, 35, 29, 35, 29, 14, 6, 167, 200, 120, 120, 120, 120, 167, 200, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 1, 0, 152, 0, 56, 1, 248, 7, 220, 10, 52, 13, 0, 15, 160, 26, 0, 21, 11, 37, 28, 28, 28, 23, 12, 6, 167, 200, 120, 120, 120, 120, 167, 200, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 232, 65, 0, 191, 129, 244, 194, 182, 76, 250, 23, 8, 0, 0, 7, 0, 1, 0, 232, 0, 218, 2, 222, 3, 60, 10, 224, 11, 222, 13, 160, 28, 40, 57, 32, 56, 70, 33, 33, 22, 9, 7, 230, 150, 120, 120, 120, 120, 185, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 232, 0, 158, 2, 178, 3, 60, 10, 224, 11, 222, 13, 32, 28, 49, 114, 28, 81, 103, 42, 43, 28, 15, 6, 182, 150, 120, 120, 120, 120, 182, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 228, 0, 138, 2, 222, 3, 14, 10, 232, 11, 244, 13, 10, 28, 65, 105, 30, 83, 101, 46, 44, 29, 16, 7, 181, 145, 123, 120, 120, 120, 182, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 37, 0, 184, 0, 209, 1, 106, 5, 112, 8, 48, 12, 191, 14, 64, 27, 22, 49, 37, 68, 39, 59, 39, 22, 15, 7, 167, 100, 152, 120, 120, 120, 137, 115, 167, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 208, 0, 149, 1, 246, 6, 112, 8, 128, 12, 191, 14, 64, 27, 48, 45, 32, 57, 36, 60, 35, 23, 14, 7, 155, 105, 150, 120, 120, 120, 125, 150, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 160, 0, 54, 1, 199, 7, 136, 9, 228, 12, 191, 14, 64, 27, 26, 36, 25, 53, 36, 30, 41, 27, 16, 7, 155, 105, 135, 120, 120, 120, 125, 105, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 1, 0, 160, 0, 54, 1, 210, 7, 252, 8, 92, 13, 35, 15, 64, 28, 0, 25, 27, 45, 27, 21, 33, 22, 13, 8, 157, 105, 135, 120, 120, 120, 82, 105, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 232, 65, 0, 191, 129, 244, 194, 182, 76, 250, 23, 8, 0, 0, 5, 0, 1, 0, 88, 1, 128, 2, 169, 6, 216, 9, 192, 13, 185, 15, 32, 29, 46, 46, 33, 54, 65, 48, 36, 27, 9, 8, 255, 150, 180, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 88, 1, 133, 2, 169, 6, 216, 9, 192, 13, 185, 15, 32, 29, 61, 85, 45, 74, 89, 66, 50, 38, 13, 8, 255, 150, 180, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 36, 1, 64, 2, 241, 5, 12, 9, 148, 12, 20, 15, 173, 28, 48, 56, 30, 66, 71, 45, 36, 29, 13, 7, 222, 132, 153, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 192, 0, 174, 1, 156, 4, 172, 8, 204, 11, 141, 14, 224, 28, 46, 36, 26, 61, 37, 26, 17, 15, 8, 8, 162, 120, 135, 120, 120, 120, 117, 90, 180, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 176, 0, 134, 1, 189, 3, 92, 8, 204, 11, 141, 14, 224, 28, 0, 29, 25, 53, 35, 20, 14, 11, 8, 7, 155, 120, 75, 120, 120, 120, 110, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 195, 0, 4, 0, 1, 0, 112, 0, 120, 1, 235, 5, 156, 9, 208, 12, 60, 15, 90, 26, 45, 28, 23, 48, 46, 43, 40, 28, 15, 6, 168, 135, 148, 120, 120, 120, 107, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 112, 0, 120, 1, 235, 5, 156, 9, 208, 12, 60, 15, 90, 26, 75, 39, 27, 58, 54, 51, 47, 34, 18, 7, 168, 135, 148, 120, 120, 120, 107, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 112, 0, 120, 1, 235, 5, 156, 9, 208, 12, 60, 15, 90, 26, 75, 35, 25, 55, 51, 48, 45, 32, 17, 6, 168, 135, 148, 120, 120, 120, 107, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 112, 0, 120, 1, 235, 5, 156, 9, 208, 12, 60, 15, 90, 26, 0, 28, 23, 48, 46, 43, 40, 28, 15, 6, 168, 135, 148, 120, 120, 120, 107, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 105, 0, 4, 0, 1, 0, 116, 0, 13, 2, 161, 5, 232, 8, 188, 12, 116, 14, 96, 27, 30, 13, 18, 34, 28, 16, 14, 14, 5, 3, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 116, 0, 13, 2, 161, 5, 232, 8, 188, 12, 116, 14, 96, 27, 45, 16, 20, 38, 32, 18, 16, 16, 6, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 116, 0, 13, 2, 161, 5, 232, 8, 188, 12, 116, 14, 96, 27, 30, 16, 20, 38, 32, 18, 16, 16, 6, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 116, 0, 13, 2, 161, 5, 232, 8, 188, 12, 116, 14, 96, 27, 0, 11, 15, 29, 35, 19, 20, 16, 8, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 80, 0, 4, 0, 1, 0, 104, 0, 44, 1, 172, 5, 84, 11, 12, 13, 135, 15, 32, 28, 0, 32, 17, 53, 34, 32, 55, 26, 8, 0, 150, 120, 150, 120, 120, 120, 120, 105, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 11, 0, 104, 0, 44, 1, 172, 5, 84, 11, 12, 13, 135, 15, 32, 28, 40, 23, 14, 45, 29, 27, 47, 22, 7, 0, 150, 120, 150, 120, 120, 120, 120, 105, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 9, 0, 136, 0, 184, 1, 48, 6, 84, 11, 92, 13, 210, 15, 32, 28, 40, 14, 13, 41, 31, 28, 27, 13, 5, 0, 150, 105, 150, 120, 120, 120, 120, 45, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 136, 0, 104, 1, 152, 8, 84, 11, 32, 13, 210, 15, 32, 28, 0, 76, 20, 78, 80, 78, 76, 34, 10, 0, 150, 150, 120, 120, 120, 120, 120, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 103, 0, 4, 0, 5, 0, 236, 0, 124, 1, 12, 7, 236, 9, 172, 13, 160, 15, 0, 27, 40, 14, 48, 29, 21, 13, 11, 13, 7, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 7, 0, 236, 0, 144, 1, 12, 7, 236, 9, 172, 13, 160, 15, 0, 27, 15, 12, 46, 28, 22, 16, 14, 16, 10, 0, 120, 60, 90, 120, 120, 120, 30, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 236, 0, 164, 1, 122, 7, 80, 10, 172, 13, 235, 15, 128, 27, 49, 9, 28, 24, 31, 32, 28, 18, 6, 0, 120, 75, 90, 120, 120, 120, 30, 105, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 204, 0, 144, 1, 97, 8, 20, 10, 92, 13, 135, 15, 128, 27, 0, 66, 51, 66, 65, 81, 81, 52, 12, 0, 120, 105, 150, 120, 120, 120, 45, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 140, 0, 3, 0, 1, 0, 148, 0, 128, 1, 32, 8, 60, 10, 42, 13, 50, 15, 96, 25, 50, 6, 8, 21, 26, 24, 23, 14, 6, 2, 160, 92, 120, 143, 120, 120, 130, 95, 120, 44, 45, 70, 130, 52, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 148, 0, 128, 1, 32, 8, 60, 10, 42, 13, 50, 15, 96, 25, 90, 7, 8, 22, 28, 25, 24, 15, 6, 2, 160, 92, 120, 143, 120, 120, 130, 95, 120, 44, 45, 70, 130, 54, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 148, 0, 128, 1, 32, 8, 60, 10, 42, 13, 50, 15, 96, 25, 0, 1, 4, 11, 14, 12, 12, 7, 3, 1, 160, 92, 120, 143, 120, 120, 130, 95, 120, 44, 45, 70, 130, 46, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 175, 0, 4, 0, 1, 0, 176, 0, 240, 1, 204, 3, 196, 9, 104, 12, 166, 14, 204, 26, 45, 50, 29, 56, 64, 39, 34, 24, 17, 5, 164, 141, 150, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 176, 0, 240, 1, 204, 3, 196, 9, 104, 12, 166, 14, 204, 26, 70, 109, 43, 83, 95, 57, 51, 36, 26, 8, 164, 141, 150, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 176, 0, 240, 1, 204, 3, 196, 9, 104, 12, 166, 14, 204, 26, 60, 88, 39, 75, 85, 51, 46, 32, 23, 7, 164, 141, 150, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 176, 0, 240, 1, 204, 3, 196, 9, 104, 12, 166, 14, 204, 26, 0, 44, 27, 53, 60, 36, 32, 23, 16, 5, 164, 141, 150, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 235, 0, 6, 0, 1, 0, 176, 0, 72, 2, 120, 5, 156, 9, 188, 12, 116, 14, 88, 27, 45, 49, 33, 60, 69, 41, 39, 33, 17, 6, 167, 135, 135, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 176, 0, 72, 2, 120, 5, 156, 9, 188, 12, 116, 14, 88, 27, 60, 76, 41, 75, 87, 51, 49, 41, 21, 8, 167, 135, 135, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 176, 0, 72, 2, 100, 5, 156, 9, 188, 12, 116, 14, 88, 27, 40, 61, 37, 67, 78, 46, 44, 37, 19, 7, 167, 135, 135, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 176, 0, 184, 1, 66, 4, 106, 9, 228, 12, 216, 14, 244, 26, 40, 53, 20, 68, 59, 32, 32, 33, 15, 7, 172, 130, 122, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 176, 0, 92, 1, 32, 3, 246, 8, 172, 12, 8, 15, 65, 27, 50, 47, 10, 68, 42, 22, 20, 26, 11, 8, 170, 123, 106, 120, 120, 120, 177, 125, 125, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 176, 0, 92, 1, 32, 3, 246, 8, 172, 12, 8, 15, 65, 27, 0, 32, 8, 57, 35, 18, 17, 22, 9, 6, 170, 123, 106, 120, 120, 120, 177, 125, 125, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 120, 0, 7, 0, 33, 0, 152, 0, 32, 1, 224, 8, 4, 11, 52, 13, 0, 15, 160, 26, 52, 43, 6, 65, 57, 58, 58, 28, 13, 6, 175, 105, 120, 120, 120, 120, 175, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 152, 0, 24, 1, 232, 8, 4, 11, 52, 13, 0, 15, 160, 26, 50, 69, 9, 81, 72, 72, 73, 35, 17, 8, 167, 105, 120, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 152, 0, 24, 1, 232, 8, 4, 11, 52, 13, 0, 15, 160, 26, 40, 50, 8, 69, 61, 61, 62, 30, 14, 7, 167, 105, 120, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 152, 0, 24, 1, 232, 8, 4, 11, 52, 13, 0, 15, 160, 26, 30, 44, 7, 65, 57, 58, 58, 28, 13, 6, 167, 105, 120, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 152, 0, 24, 1, 252, 8, 4, 11, 52, 13, 0, 15, 160, 26, 48, 62, 9, 77, 68, 69, 69, 33, 16, 8, 167, 105, 120, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 152, 0, 24, 1, 252, 8, 4, 11, 12, 13, 216, 14, 64, 26, 60, 44, 9, 58, 58, 61, 62, 33, 11, 8, 167, 105, 120, 120, 120, 120, 167, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 1, 0, 84, 0, 200, 0, 94, 9, 4, 11, 32, 13, 60, 15, 64, 26, 0, 21, 7, 40, 41, 38, 39, 22, 9, 8, 175, 105, 105, 120, 120, 120, 175, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 232, 65, 0, 191, 129, 244, 194, 182, 76, 250, 23, 8, 250, 0, 5, 0, 1, 0, 141, 0, 80, 1, 244, 6, 236, 9, 32, 13, 160, 15, 104, 25, 45, 40, 9, 60, 53, 53, 51, 31, 11, 9, 174, 115, 127, 122, 122, 132, 187, 130, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 141, 0, 80, 1, 244, 6, 236, 9, 32, 13, 160, 15, 104, 25, 80, 64, 12, 76, 68, 68, 65, 39, 15, 12, 174, 115, 127, 122, 122, 132, 187, 130, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 143, 0, 66, 1, 116, 7, 51, 10, 27, 13, 109, 15, 159, 25, 80, 48, 10, 64, 59, 60, 58, 34, 12, 10, 172, 113, 125, 121, 121, 129, 187, 130, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 152, 0, 24, 1, 232, 8, 4, 11, 12, 13, 216, 14, 64, 26, 45, 39, 9, 55, 55, 58, 59, 31, 11, 7, 167, 105, 120, 120, 120, 120, 167, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 84, 0, 200, 0, 94, 9, 4, 11, 32, 13, 60, 15, 64, 26, 0, 22, 8, 41, 41, 39, 40, 23, 10, 8, 175, 105, 105, 120, 120, 120, 175, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 5, 0, 1, 0, 84, 0, 104, 1, 180, 5, 212, 8, 148, 12, 41, 14, 64, 26, 42, 51, 17, 72, 57, 40, 40, 37, 11, 8, 162, 150, 135, 120, 120, 120, 102, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 84, 0, 104, 1, 140, 5, 212, 8, 148, 12, 116, 14, 192, 25, 40, 79, 21, 87, 82, 73, 57, 52, 18, 8, 167, 135, 135, 120, 120, 120, 107, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 88, 0, 96, 1, 120, 5, 172, 8, 148, 12, 116, 14, 192, 25, 50, 74, 22, 89, 68, 70, 52, 50, 20, 8, 167, 120, 135, 120, 120, 120, 107, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 109, 0, 64, 1, 113, 4, 187, 8, 23, 12, 121, 14, 244, 25, 67, 49, 11, 68, 57, 41, 37, 33, 15, 8, 165, 135, 138, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 84, 0, 34, 1, 255, 3, 172, 8, 28, 12, 116, 14, 192, 25, 0, 30, 16, 57, 35, 17, 20, 20, 10, 8, 165, 135, 135, 120, 120, 120, 105, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 235, 0, 6, 0, 1, 0, 0, 1, 43, 2, 64, 6, 243, 9, 229, 12, 226, 14, 112, 28, 45, 37, 27, 53, 51, 46, 38, 25, 10, 5, 222, 133, 154, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 19, 0, 0, 1, 43, 2, 241, 5, 243, 9, 229, 12, 226, 14, 112, 28, 40, 46, 31, 59, 57, 52, 42, 28, 11, 6, 222, 133, 154, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 162, 0, 16, 2, 16, 4, 216, 9, 58, 12, 176, 14, 121, 27, 40, 48, 30, 55, 67, 39, 35, 26, 16, 6, 169, 143, 139, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 162, 0, 16, 2, 16, 4, 216, 9, 58, 12, 176, 14, 121, 27, 70, 54, 32, 58, 71, 41, 37, 27, 16, 6, 169, 143, 139, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 162, 0, 16, 2, 16, 4, 216, 9, 58, 12, 176, 14, 121, 27, 40, 60, 34, 62, 74, 43, 39, 28, 17, 6, 169, 143, 139, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 162, 0, 16, 2, 16, 4, 216, 9, 58, 12, 176, 14, 121, 27, 0, 38, 27, 49, 59, 34, 31, 23, 14, 5, 169, 143, 139, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 255, 0, 5, 0, 1, 0, 243, 0, 200, 1, 8, 7, 216, 9, 28, 13, 170, 14, 164, 28, 45, 36, 23, 48, 54, 53, 41, 30, 9, 6, 214, 120, 143, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 237, 0, 196, 1, 174, 6, 202, 9, 27, 13, 183, 14, 116, 28, 70, 57, 27, 62, 67, 63, 49, 38, 12, 8, 210, 120, 140, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 183, 0, 160, 1, 123, 3, 71, 9, 14, 13, 46, 15, 193, 26, 80, 82, 23, 87, 71, 32, 30, 40, 15, 9, 181, 124, 113, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 176, 0, 88, 1, 32, 3, 56, 9, 12, 13, 60, 15, 144, 26, 60, 64, 3, 86, 50, 25, 25, 36, 14, 9, 177, 125, 110, 120, 120, 120, 177, 125, 125, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 176, 0, 88, 1, 32, 3, 56, 9, 12, 13, 60, 15, 144, 26, 0, 31, 2, 60, 35, 17, 17, 25, 10, 6, 177, 125, 110, 120, 120, 120, 177, 125, 125, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 255, 0, 5, 0, 1, 0, 168, 0, 16, 2, 112, 3, 88, 10, 104, 11, 141, 14, 32, 27, 45, 52, 20, 51, 63, 38, 35, 17, 13, 5, 167, 135, 150, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 195, 0, 156, 2, 68, 4, 108, 10, 97, 12, 235, 14, 60, 27, 70, 83, 34, 75, 82, 52, 45, 26, 16, 6, 201, 149, 155, 130, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 231, 0, 105, 3, 125, 5, 136, 10, 178, 13, 105, 15, 97, 27, 80, 78, 43, 85, 82, 54, 44, 30, 14, 5, 246, 167, 162, 143, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 236, 0, 128, 3, 160, 5, 140, 10, 216, 13, 120, 15, 102, 27, 60, 83, 41, 81, 77, 51, 41, 29, 13, 5, 251, 170, 163, 145, 120, 120, 255, 174, 173, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 236, 0, 128, 3, 160, 5, 140, 10, 216, 13, 120, 15, 102, 27, 0, 56, 34, 67, 63, 42, 34, 23, 11, 4, 251, 170, 163, 145, 120, 120, 255, 174, 173, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 20, 0, 3, 0, 5, 0, 136, 0, 216, 1, 64, 6, 32, 8, 128, 12, 100, 15, 124, 21, 20, 14, 3, 36, 21, 7, 3, 7, 0, 0, 200, 212, 187, 187, 205, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 136, 0, 216, 1, 64, 6, 32, 8, 128, 12, 100, 15, 124, 21, 0, 11, 3, 32, 21, 7, 3, 7, 0, 0, 200, 212, 187, 187, 205, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 136, 0, 216, 1, 64, 6, 32, 8, 128, 12, 100, 15, 124, 21, 0, 11, 3, 32, 21, 7, 3, 7, 0, 0, 200, 212, 187, 187, 205, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 20, 0, 3, 0, 5, 0, 136, 0, 8, 2, 120, 5, 148, 7, 128, 12, 100, 15, 124, 21, 20, 4, 4, 20, 16, 8, 4, 8, 0, 0, 200, 212, 187, 187, 205, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 136, 0, 8, 2, 120, 5, 148, 7, 128, 12, 100, 15, 124, 21, 0, 4, 4, 20, 16, 8, 4, 8, 0, 0, 200, 212, 187, 187, 205, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 136, 0, 8, 2, 120, 5, 148, 7, 128, 12, 100, 15, 124, 21, 0, 4, 4, 20, 16, 8, 4, 8, 0, 0, 200, 212, 187, 187, 205, 175, 200, 212, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 8, 1, 23, 0, 255, 2, 250, 255, 251, 0, 253, 255, 253, 252, 1, 2, 2, 1, 253, 8, 5, 6, 7, 14, 13, 12, 17, 13, 16, 5, 164, 135, 240, 0, 35, 45, 3, 43, 36, 3, 19, 0, 247, 11, 247, 252, 12, 228, 242, 255, 240, 250, 251, 3, 3, 244, 8, 13, 1, 248, 3, 3, 2, 25, 11, 0, 16, 22, 6, 22, 212, 179, 243, 250, 37, 8, 255, 19, 4, 12, 254, 239, 7, 240, 219, 252, 239, 251, 42, 29, 42, 28, 15, 28, 249, 214, 226, 225, 240, 240, 240, 15, 9, 245, 23, 14, 4, 246, 238, 11, 21, 16, 5, 249, 251, 23, 6, 9, 5, 248, 241, 251, 246, 255, 227, 234, 255, 5, 20, 13, 0, 253, 252, 247, 42, 12, 247, 248, 6, 30, 30, 0, 3, 18, 191, 220, 208, 229, 20, 255, 12, 19, 5, 53, 25, 245, 19, 215, 7, 47, 251, 12, 213, 238, 248, 247, 4, 229, 37, 250, 228, 246, 12, 20, 37, 3, 230, 33, 231, 223, 243, 40, 76, 233, 219, 36, 242, 246, 242, 41, 16, 230, 220, 215, 0, 21, 251, 224, 251, 54, 217, 217, 22, 40, 26, 42, 59, 27, 220, 15, 72, 244, 207, 167, 168, 209, 3, 239, 12, 33, 63, 6, 218, 45, 55, 222, 243, 44, 11, 241, 23, 29, 247, 250, 16, 193, 238, 25, 218, 204, 251, 37, 16, 218, 24, 18, 213, 50, 43, 230, 3, 22, 230, 243, 4, 43, 25, 243, 18, 232, 222, 32, 6, 226, 228, 242, 229, 212, 50, 0, 5, 0, 1, 0, 132, 0, 24, 1, 12, 8, 36, 9, 228, 12, 96, 14, 100, 25, 45, 35, 17, 54, 37, 31, 34, 31, 8, 11, 160, 90, 135, 120, 120, 120, 160, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 132, 0, 24, 1, 188, 7, 36, 9, 228, 12, 96, 14, 100, 25, 50, 68, 24, 76, 51, 44, 48, 44, 12, 16, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 132, 0, 24, 1, 168, 7, 36, 9, 228, 12, 96, 14, 100, 25, 85, 55, 21, 68, 46, 39, 43, 39, 10, 14, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 132, 0, 24, 1, 188, 7, 36, 9, 228, 12, 96, 14, 100, 25, 40, 43, 19, 60, 41, 35, 38, 35, 9, 12, 165, 90, 135, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 132, 0, 24, 1, 188, 7, 36, 9, 228, 12, 96, 14, 100, 25, 0, 29, 15, 50, 34, 29, 31, 29, 7, 10, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 175, 0, 4, 0, 1, 0, 144, 0, 128, 1, 128, 7, 176, 9, 248, 12, 0, 15, 160, 26, 45, 42, 23, 60, 54, 54, 54, 26, 12, 6, 167, 105, 120, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 144, 0, 128, 1, 128, 7, 176, 9, 248, 12, 0, 15, 160, 26, 70, 81, 32, 84, 76, 76, 75, 36, 17, 8, 167, 105, 120, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 144, 0, 128, 1, 128, 7, 176, 9, 248, 12, 0, 15, 160, 26, 60, 65, 28, 75, 68, 68, 67, 32, 15, 7, 167, 105, 120, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 152, 0, 128, 1, 128, 7, 136, 9, 32, 13, 0, 15, 160, 26, 0, 35, 19, 56, 50, 50, 51, 24, 11, 5, 167, 105, 120, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 175, 0, 4, 0, 1, 0, 135, 0, 120, 1, 4, 6, 212, 8, 72, 13, 0, 15, 50, 25, 45, 40, 14, 59, 47, 56, 44, 26, 10, 5, 178, 122, 132, 123, 123, 141, 187, 130, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 135, 0, 104, 1, 4, 6, 172, 8, 72, 13, 0, 15, 50, 25, 70, 73, 20, 80, 64, 68, 60, 36, 13, 8, 178, 122, 132, 123, 123, 141, 187, 130, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 135, 0, 104, 1, 4, 6, 192, 8, 72, 13, 0, 15, 50, 25, 60, 59, 18, 72, 57, 61, 54, 32, 12, 7, 178, 122, 132, 123, 123, 141, 187, 130, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 135, 0, 104, 1, 24, 6, 232, 8, 72, 13, 0, 15, 50, 25, 0, 30, 12, 51, 40, 43, 38, 23, 8, 5, 178, 122, 132, 123, 123, 141, 187, 130, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 115, 0, 3, 0, 1, 0, 160, 0, 75, 2, 220, 5, 252, 8, 148, 12, 165, 15, 199, 27, 45, 53, 37, 66, 63, 47, 41, 27, 15, 6, 171, 143, 165, 121, 122, 125, 171, 120, 172, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 160, 0, 75, 2, 220, 5, 252, 8, 148, 12, 165, 15, 199, 27, 70, 85, 48, 84, 80, 60, 52, 34, 20, 8, 171, 143, 165, 121, 122, 125, 171, 120, 172, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 160, 0, 75, 2, 220, 5, 252, 8, 148, 12, 165, 15, 199, 27, 0, 68, 43, 75, 72, 54, 46, 31, 18, 7, 171, 143, 165, 121, 122, 125, 171, 120, 172, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 205, 0, 4, 0, 1, 0, 248, 0, 152, 2, 232, 3, 160, 10, 216, 12, 109, 14, 87, 27, 45, 50, 25, 54, 60, 33, 35, 31, 9, 5, 167, 148, 135, 120, 120, 120, 167, 145, 131, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 248, 0, 152, 2, 232, 3, 160, 10, 216, 12, 109, 14, 87, 27, 90, 91, 34, 73, 81, 45, 47, 42, 12, 7, 167, 148, 135, 120, 120, 120, 167, 145, 131, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 248, 0, 144, 2, 252, 3, 140, 10, 216, 12, 109, 14, 87, 27, 70, 73, 31, 67, 74, 41, 43, 38, 11, 6, 167, 148, 135, 120, 120, 120, 167, 145, 131, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 248, 0, 144, 2, 16, 4, 80, 10, 168, 12, 109, 14, 87, 27, 0, 46, 25, 54, 60, 33, 35, 31, 9, 5, 167, 148, 135, 120, 120, 120, 167, 145, 131, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 67, 8, 23, 0, 1, 5, 2, 0, 254, 252, 253, 251, 251, 248, 247, 250, 1, 12, 15, 13, 5, 0, 248, 241, 243, 249, 255, 0, 8, 22, 34, 38, 35, 30, 23, 10, 1, 251, 238, 223, 220, 231, 239, 243, 247, 253, 251, 246, 252, 0, 249, 238, 235, 237, 242, 254, 4, 0, 243, 239, 245, 249, 253, 1, 10, 18, 21, 22, 24, 34, 43, 47, 42, 36, 32, 30, 25, 13, 2, 254, 254, 0, 11, 28, 37, 34, 33, 32, 24, 15, 9, 5, 249, 242, 245, 242, 219, 197, 197, 210, 219, 221, 226, 244, 17, 48, 58, 44, 25, 20, 20, 7, 242, 225, 224, 238, 2, 14, 12, 20, 40, 58, 48, 27, 18, 23, 21, 0, 231, 213, 204, 203, 210, 214, 212, 213, 234, 1, 6, 252, 251, 1, 250, 231, 217, 220, 230, 244, 254, 0, 253, 4, 22, 30, 21, 10, 6, 10, 13, 11, 1, 249, 255, 8, 9, 252, 244, 251, 13, 29, 33, 32, 31, 38, 44, 39, 24, 14, 11, 4, 249, 236, 231, 236, 244, 253, 0, 249, 242, 249, 6, 5, 246, 230, 230, 241, 248, 248, 248, 247, 248, 251, 251, 241, 230, 227, 231, 237, 235, 234, 234, 239, 245, 250, 246, 235, 234, 243, 246, 237, 232, 239, 249, 0, 253, 248, 242, 242, 249, 251, 243, 232, 238, 250, 5, 8, 8, 13, 25, 34, 31, 20, 10, 14, 26, 31, 20, 14, 22, 30, 28, 19, 20, 21, 11, 3, 12, 26, 25, 14, 9, 12, 18, 13, 5, 254, 249, 243, 238, 238, 239, 244, 241, 238, 243, 2, 10, 12, 15, 19, 15, 3, 250, 248, 248, 239, 230, 223, 227, 241, 2, 12, 24, 45, 60, 61, 52, 36, 21, 13, 13, 10, 2, 0, 5, 20, 30, 37, 29, 14, 2, 254, 251, 246, 248, 242, 228, 217, 210, 203, 198, 211, 234, 250, 0, 1, 11, 14, 11, 5, 253, 243, 238, 248, 1, 11, 18, 23, 20, 11, 6, 11, 14, 2, 245, 246, 2, 11, 12, 5, 8, 19, 31, 33, 22, 2, 247, 251, 249, 229, 213, 214, 228, 237, 239, 240, 243, 255, 12, 23, 9, 240, 223, 222, 230, 236, 237, 233, 242, 2, 16, 21, 24, 31, 45, 54, 46, 25, 10, 5, 0, 237, 208, 195, 202, 221, 234, 243, 251, 8, 18, 21, 20, 15, 0, 251, 253, 237, 205, 193, 212, 228, 236, 247, 16, 42, 54, 56, 44, 24, 8, 255, 243, 223, 219, 231, 246, 6, 19, 35, 38, 39, 42, 43, 25, 251, 238, 238, 236, 231, 234, 242, 246, 254, 16, 34, 43, 36, 29, 17, 4, 0, 2, 2, 252, 254, 0, 6, 8, 13, 13, 3, 242, 230, 231, 238, 244, 240, 223, 213, 226, 243, 243, 226, 222, 234, 252, 8, 16, 18, 14, 15, 17, 11, 252, 244, 249, 253, 251, 253, 5, 22, 31, 40, 41, 31, 19, 24, 42, 37, 18, 14, 30, 31, 9, 253, 5, 11, 4, 250, 245, 241, 241, 248, 246, 240, 236, 238, 237, 233, 231, 221, 208, 213, 231, 236, 211, 206, 234, 9, 26, 32, 36, 25, 30, 52, 62, 39, 6, 254, 254, 254, 0, 5, 9, 11, 26, 35, 34, 33, 35, 32, 12, 246, 222, 209, 201, 199, 198, 195, 201, 225, 5, 20, 10, 6, 25, 32, 2, 230, 227, 225, 211, 207, 221, 230, 237, 11, 43, 44, 28, 35, 57, 55, 23, 247, 236, 247, 254, 246, 229, 239, 14, 40, 46, 40, 41, 36, 31, 13, 243, 221, 219, 230, 232, 228, 231, 247, 7, 13, 2, 247, 253, 8, 254, 231, 229, 249, 253, 250, 255, 8, 13, 29, 54, 54, 29, 8, 9, 254, 230, 210, 212, 222, 231, 251, 13, 29, 33, 44, 55, 51, 29, 7, 249, 229, 216, 226, 234, 221, 209, 229, 249, 246, 253, 17, 21, 251, 246, 2, 3, 243, 251, 9, 254, 237, 244, 10, 12, 5, 4, 4, 2, 12, 28, 32, 26, 32, 40, 28, 5, 0, 7, 244, 210, 198, 211, 220, 224, 241, 6, 17, 28, 41, 46, 30, 14, 0, 235, 223, 227, 239, 235, 234, 253, 24, 39, 41, 37, 28, 20, 21, 18, 0, 236, 234, 243, 245, 248, 6, 14, 13, 26, 47, 46, 16, 253, 0, 0, 235, 210, 201, 199, 211, 228, 243, 249, 0, 13, 20, 13, 5, 249, 231, 216, 218, 229, 234, 235, 251, 19, 32, 33, 30, 28, 23, 31, 36, 22, 251, 243, 253, 238, 214, 221, 1, 21, 24, 25, 38, 40, 37, 16, 244, 219, 211, 213, 217, 234, 248, 253, 5, 30, 40, 7, 227, 233, 4, 253, 220, 210, 234, 253, 3, 11, 25, 16, 11, 18, 26, 5, 248, 6, 19, 4, 238, 242, 251, 252, 0, 12, 21, 26, 42, 56, 38, 10, 2, 9, 1, 234, 226, 218, 213, 214, 234, 240, 226, 224, 4, 35, 44, 55, 82, 77, 26, 233, 218, 207, 181, 171, 185, 194, 188, 216, 21, 62, 53, 40, 65, 86, 80, 50, 26, 255, 228, 217, 214, 202, 196, 224, 13, 38, 43, 50, 68, 80, 62, 25, 249, 230, 219, 197, 176, 172, 188, 212, 248, 27, 47, 43, 49, 67, 68, 24, 233, 223, 237, 233, 211, 199, 209, 231, 5, 34, 42, 31, 36, 63, 75, 43, 246, 224, 227, 227, 209, 205, 215, 231, 250, 9, 27, 30, 39, 44, 36, 12, 255, 253, 251, 236, 220, 203, 192, 191, 213, 240, 252, 254, 8, 36, 58, 63, 55, 45, 40, 33, 10, 223, 195, 211, 243, 245, 212, 211, 252, 35, 37, 25, 27, 27, 29, 31, 34, 13, 236, 230, 237, 222, 194, 197, 228, 243, 253, 23, 48, 43, 40, 56, 45, 3, 238, 254, 251, 220, 205, 214, 214, 211, 236, 2, 2, 0, 21, 42, 34, 19, 16, 14, 247, 229, 231, 249, 249, 236, 235, 251, 8, 9, 15, 28, 32, 33, 39, 50, 36, 3, 232, 223, 232, 233, 224, 213, 232, 3, 20, 28, 49, 63, 46, 15, 2, 243, 211, 199, 208, 205, 180, 194, 245, 33, 29, 27, 35, 41, 35, 27, 15, 242, 218, 224, 244, 237, 209, 218, 6, 31, 18, 13, 44, 56, 41, 41, 54, 32, 244, 234, 246, 231, 199, 192, 211, 227, 252, 34, 48, 38, 42, 75, 80, 37, 240, 233, 239, 224, 188, 182, 204, 225, 244, 11, 27, 24, 32, 56, 56, 16, 238, 237, 240, 228, 220, 230, 226, 226, 248, 24, 25, 8, 16, 34, 23, 255, 253, 8, 1, 248, 1, 10, 12, 13, 26, 22, 2, 245, 245, 246, 243, 239, 228, 228, 242, 6, 9, 16, 27, 42, 34, 29, 28, 23, 244, 202, 173, 168, 174, 190, 219, 235, 250, 21, 85, 125, 114, 68, 41, 30, 5, 218, 189, 180, 168, 172, 207, 10, 34, 36, 52, 96, 110, 84, 39, 4, 226, 204, 194, 179, 162, 168, 215, 5, 29, 38, 47, 60, 59, 49, 23, 245, 213, 191, 190, 197, 205, 209, 221, 255, 42, 80, 84, 67, 48, 35, 20, 254, 228, 205, 188, 194, 223, 244, 244, 0, 30, 51, 52, 51, 56, 48, 31, 14, 250, 217, 192, 201, 211, 218, 216, 229, 255, 27, 43, 44, 39, 45, 56, 50, 13, 235, 227, 231, 220, 196, 191, 196, 198, 219, 20, 62, 50, 36, 70, 105, 74, 19, 3, 1, 217, 179, 186, 210, 203, 211, 245, 18, 9, 13, 42, 67, 57, 43, 31, 8, 243, 239, 238, 215, 192, 194, 224, 244, 251, 0, 13, 24, 25, 23, 16, 11, 3, 2, 2, 251, 245, 252, 3, 5, 3, 10, 12, 6, 251, 245, 247, 253, 2, 0, 2, 22, 46, 43, 16, 5, 14, 21, 14, 252, 238, 217, 210, 219, 233, 229, 217, 228, 9, 47, 46, 25, 15, 18, 14, 251, 229, 212, 202, 211, 243, 9, 0, 253, 28, 53, 42, 14, 16, 26, 15, 255, 247, 239, 219, 216, 239, 1, 0, 246, 3, 31, 55, 50, 24, 6, 11, 24, 6, 225, 205, 218, 240, 246, 247, 249, 255, 7, 24, 36, 20, 245, 246, 0, 249, 216, 214, 245, 3, 244, 240, 0, 6, 6, 15, 27, 21, 7, 19, 37, 19, 233, 214, 224, 232, 221, 218, 235, 6, 20, 43, 60, 56, 34, 27, 36, 36, 9, 239, 224, 220, 213, 212, 210, 224, 4, 42, 52, 34, 40, 56, 58, 22, 241, 219, 206, 196, 205, 217, 215, 212, 233, 11, 19, 9, 11, 37, 42, 28, 16, 10, 255, 240, 244, 243, 230, 216, 239, 6, 5, 251, 2, 22, 37, 35, 28, 5, 250, 4, 20, 10, 249, 0, 15, 13, 255, 252, 248, 232, 228, 246, 1, 243, 239, 16, 45, 38, 13, 0, 253, 241, 236, 232, 224, 213, 233, 0, 4, 5, 28, 46, 40, 29, 23, 18, 253, 235, 221, 201, 196, 224, 254, 14, 26, 41, 49, 40, 33, 18, 251, 224, 222, 229, 229, 230, 243, 0, 0, 250, 1, 17, 21, 10, 10, 20, 25, 18, 7, 249, 235, 237, 0, 1, 234, 221, 247, 17, 12, 254, 1, 6, 12, 16, 25, 10, 245, 244, 9, 5, 235, 218, 223, 240, 255, 8, 8, 9, 19, 35, 31, 12, 0, 253, 241, 233, 231, 235, 247, 7, 23, 16, 255, 251, 8, 21, 24, 16, 255, 246, 255, 13, 7, 243, 228, 227, 236, 246, 250, 249, 246, 0, 7, 11, 14, 24, 26, 28, 33, 32, 10, 243, 236, 239, 225, 205, 212, 240, 4, 7, 16, 35, 51, 46, 35, 27, 6, 238, 228, 233, 230, 220, 226, 248, 8, 15, 24, 27, 22, 14, 7, 248, 234, 233, 232, 220, 214, 223, 237, 247, 5, 18, 16, 11, 27, 44, 40, 23, 17, 15, 11, 3, 251, 238, 227, 227, 231, 226, 227, 250, 23, 41, 47, 52, 58, 54, 36, 13, 241, 210, 199, 208, 214, 207, 214, 253, 36, 49, 46, 46, 36, 21, 13, 0, 223, 195, 202, 219, 210, 196, 213, 244, 2, 8, 16, 24, 29, 42, 45, 25, 0, 252, 255, 246, 228, 223, 237, 0, 22, 31, 26, 21, 31, 43, 38, 12, 243, 233, 238, 247, 251, 237, 221, 230, 4, 20, 14, 6, 14, 21, 19, 13, 4, 247, 240, 240, 236, 227, 230, 245, 1, 4, 4, 1, 5, 15, 25, 18, 1, 248, 252, 252, 243, 228, 219, 224, 238, 253, 5, 17, 33, 50, 52, 37, 15, 0, 246, 234, 221, 207, 200, 210, 238, 7, 15, 20, 34, 48, 55, 54, 44, 23, 4, 254, 245, 227, 215, 225, 236, 243, 252, 14, 24, 29, 37, 41, 24, 0, 249, 250, 237, 215, 201, 195, 200, 217, 240, 245, 241, 249, 16, 33, 31, 22, 15, 9, 7, 13, 10, 250, 238, 248, 9, 7, 254, 0, 9, 14, 26, 39, 39, 31, 38, 49, 38, 16, 10, 7, 246, 228, 226, 223, 217, 227, 249, 254, 242, 242, 1, 5, 253, 244, 240, 236, 238, 249, 1, 253, 248, 0, 8, 3, 248, 249, 3, 7, 6, 6, 8, 13, 29, 38, 23, 0, 252, 6, 6, 251, 239, 236, 241, 3, 20, 20, 11, 16, 31, 34, 12, 244, 234, 233, 228, 219, 212, 213, 226, 246, 3, 0, 251, 255, 4, 0, 243, 230, 224, 228, 244, 255, 1, 6, 23, 42, 45, 36, 26, 21, 18, 12, 4, 254, 253, 3, 11, 13, 9, 10, 18, 22, 17, 11, 8, 5, 0, 251, 247, 244, 247, 252, 255, 0, 5, 10, 13, 12, 3, 245, 231, 226, 223, 217, 215, 217, 220, 223, 230, 236, 242, 251, 4, 8, 4, 0, 0, 4, 5, 1, 251, 246, 244, 251, 8, 16, 12, 9, 14, 21, 23, 24, 25, 20, 12, 9, 10, 6, 1, 2, 7, 10, 15, 25, 35, 34, 26, 19, 12, 0, 243, 233, 222, 214, 217, 235, 0, 11, 18, 23, 29, 34, 29, 10, 244, 225, 210, 199, 197, 204, 217, 230, 244, 3, 22, 40, 49, 50, 44, 36, 26, 17, 8, 249, 234, 228, 235, 245, 0, 6, 16, 33, 57, 65, 50, 32, 26, 21, 1, 236, 227, 232, 242, 250, 0, 8, 20, 31, 35, 27, 11, 252, 245, 237, 222, 203, 193, 191, 197, 206, 215, 219, 232, 254, 16, 19, 15, 14, 15, 11, 253, 233, 218, 219, 229, 240, 250, 3, 16, 35, 55, 62, 54, 43, 38, 32, 21, 7, 254, 250, 255, 6, 8, 6, 14, 30, 41, 36, 24, 13, 6, 254, 236, 214, 199, 197, 204, 211, 211, 211, 217, 228, 232, 223, 215, 0, 185, 0, 4, 0, 1, 0, 147, 0, 22, 1, 238, 7, 186, 9, 17, 13, 141, 14, 81, 26, 45, 41, 10, 62, 52, 48, 52, 29, 12, 8, 167, 101, 123, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 147, 0, 22, 1, 238, 7, 186, 9, 17, 13, 141, 14, 81, 26, 70, 75, 14, 84, 71, 65, 70, 39, 16, 10, 167, 101, 123, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 147, 0, 22, 1, 238, 7, 186, 9, 17, 13, 141, 14, 81, 26, 70, 61, 12, 76, 63, 58, 63, 35, 15, 9, 167, 101, 123, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 147, 0, 22, 1, 238, 7, 186, 9, 17, 13, 141, 14, 81, 26, 0, 30, 8, 54, 45, 41, 45, 25, 10, 6, 167, 101, 123, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 165, 0, 4, 0, 1, 0, 160, 0, 248, 1, 60, 5, 172, 8, 228, 12, 246, 14, 95, 27, 45, 43, 27, 55, 64, 43, 40, 30, 16, 6, 170, 133, 127, 122, 124, 128, 197, 131, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 160, 0, 248, 1, 60, 5, 172, 8, 228, 12, 246, 14, 95, 27, 60, 72, 36, 72, 84, 56, 52, 38, 21, 8, 170, 133, 127, 122, 124, 128, 197, 131, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 160, 0, 248, 1, 60, 5, 172, 8, 228, 12, 246, 14, 95, 27, 60, 60, 32, 65, 76, 50, 47, 35, 19, 7, 170, 133, 127, 122, 124, 128, 197, 131, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 160, 0, 248, 1, 60, 5, 172, 8, 228, 12, 246, 14, 95, 27, 0, 36, 28, 50, 58, 39, 36, 27, 15, 5, 170, 133, 127, 122, 124, 128, 197, 131, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 45, 0, 4, 0, 1, 0, 122, 0, 136, 1, 180, 5, 132, 8, 228, 12, 246, 14, 95, 27, 45, 41, 18, 54, 67, 39, 42, 29, 16, 6, 170, 133, 127, 122, 124, 128, 197, 131, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 122, 0, 136, 1, 180, 5, 132, 8, 228, 12, 246, 14, 95, 27, 97, 72, 24, 72, 88, 52, 55, 38, 21, 8, 170, 133, 127, 122, 124, 128, 197, 131, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 122, 0, 136, 1, 120, 5, 112, 8, 228, 12, 246, 14, 95, 27, 73, 62, 21, 68, 79, 47, 43, 35, 19, 7, 170, 133, 127, 122, 124, 128, 197, 131, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 122, 0, 152, 1, 79, 5, 153, 8, 228, 12, 246, 14, 95, 27, 0, 39, 23, 54, 57, 37, 34, 23, 11, 6, 170, 133, 127, 122, 124, 128, 197, 131, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 165, 0, 4, 0, 1, 0, 24, 1, 248, 2, 236, 4, 196, 9, 112, 13, 40, 15, 153, 28, 45, 48, 28, 57, 63, 46, 37, 28, 10, 6, 215, 138, 143, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 24, 1, 248, 2, 236, 4, 196, 9, 112, 13, 40, 15, 153, 28, 60, 83, 38, 76, 83, 60, 48, 37, 13, 8, 215, 138, 143, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 24, 1, 248, 2, 20, 5, 196, 9, 112, 13, 40, 15, 153, 28, 60, 73, 36, 72, 79, 57, 46, 35, 13, 7, 215, 138, 143, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 24, 1, 248, 2, 40, 5, 196, 9, 112, 13, 40, 15, 153, 28, 0, 40, 26, 53, 59, 43, 34, 26, 9, 5, 215, 138, 143, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 175, 0, 4, 0, 1, 0, 132, 0, 67, 1, 240, 5, 92, 8, 228, 12, 96, 14, 100, 25, 45, 41, 18, 63, 40, 35, 37, 34, 9, 12, 167, 105, 135, 120, 120, 120, 167, 112, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 132, 0, 67, 1, 240, 5, 92, 8, 228, 12, 96, 14, 100, 25, 70, 66, 22, 80, 51, 44, 48, 44, 12, 16, 167, 105, 135, 120, 120, 120, 167, 112, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 132, 0, 67, 1, 240, 5, 112, 8, 228, 12, 96, 14, 100, 25, 60, 58, 21, 75, 48, 41, 45, 41, 11, 15, 167, 105, 135, 120, 120, 120, 167, 112, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 132, 0, 67, 1, 240, 5, 112, 8, 228, 12, 96, 14, 100, 25, 0, 41, 18, 63, 40, 35, 37, 34, 9, 12, 167, 105, 135, 120, 120, 120, 167, 112, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 210, 0, 5, 0, 1, 0, 132, 0, 16, 1, 240, 5, 52, 8, 228, 12, 96, 14, 100, 25, 45, 42, 15, 62, 40, 34, 37, 34, 9, 12, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 132, 0, 16, 1, 240, 5, 52, 8, 228, 12, 96, 14, 100, 25, 60, 69, 20, 80, 51, 44, 48, 44, 12, 16, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 132, 0, 16, 1, 240, 5, 52, 8, 228, 12, 96, 14, 100, 25, 70, 62, 19, 76, 49, 42, 45, 41, 11, 15, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 132, 0, 24, 1, 24, 6, 72, 8, 228, 12, 96, 14, 100, 25, 35, 41, 15, 62, 40, 34, 37, 34, 9, 12, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 132, 0, 24, 1, 24, 6, 72, 8, 228, 12, 96, 14, 100, 25, 0, 36, 14, 58, 37, 32, 35, 32, 8, 11, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 235, 0, 5, 0, 1, 0, 8, 1, 8, 3, 60, 5, 236, 9, 32, 13, 191, 14, 64, 27, 45, 53, 34, 66, 72, 43, 43, 31, 4, 6, 167, 135, 165, 120, 120, 120, 167, 135, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 8, 1, 8, 3, 60, 5, 236, 9, 32, 13, 191, 14, 64, 27, 80, 103, 48, 92, 100, 60, 60, 44, 6, 8, 167, 135, 165, 120, 120, 120, 167, 135, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 254, 0, 222, 2, 146, 5, 252, 9, 44, 13, 189, 14, 86, 27, 70, 92, 46, 88, 95, 60, 58, 43, 7, 8, 167, 130, 168, 120, 120, 120, 167, 135, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 156, 0, 99, 1, 152, 8, 140, 10, 152, 13, 166, 14, 32, 28, 40, 43, 32, 55, 49, 58, 45, 33, 10, 8, 167, 90, 195, 120, 120, 120, 122, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 156, 0, 99, 1, 174, 8, 160, 10, 92, 13, 10, 15, 32, 28, 0, 28, 28, 44, 45, 41, 38, 30, 8, 8, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 250, 0, 5, 0, 1, 0, 122, 0, 240, 1, 140, 5, 132, 8, 228, 12, 246, 14, 95, 27, 45, 38, 25, 54, 60, 37, 39, 28, 15, 6, 170, 133, 127, 122, 124, 128, 197, 131, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 122, 0, 240, 1, 140, 5, 132, 8, 228, 12, 246, 14, 95, 27, 75, 74, 36, 76, 84, 52, 55, 38, 21, 8, 170, 133, 127, 122, 124, 128, 197, 131, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 125, 0, 218, 1, 214, 5, 191, 8, 236, 12, 247, 14, 76, 27, 60, 72, 31, 76, 82, 53, 57, 38, 21, 8, 170, 129, 127, 122, 124, 127, 197, 131, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 152, 0, 11, 1, 112, 8, 212, 10, 52, 13, 0, 15, 160, 26, 70, 40, 4, 64, 57, 46, 58, 28, 13, 6, 167, 99, 120, 120, 120, 120, 167, 97, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 152, 0, 11, 1, 112, 8, 212, 10, 52, 13, 0, 15, 160, 26, 0, 34, 3, 59, 53, 43, 54, 26, 12, 6, 167, 99, 120, 120, 120, 120, 167, 97, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 40, 0, 7, 0, 1, 0, 24, 1, 232, 2, 140, 5, 196, 9, 112, 13, 40, 15, 153, 28, 40, 50, 33, 63, 63, 48, 38, 29, 10, 6, 215, 138, 143, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 24, 1, 232, 2, 140, 5, 196, 9, 112, 13, 40, 15, 153, 28, 35, 89, 44, 84, 84, 64, 51, 39, 14, 8, 215, 138, 143, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 245, 0, 176, 2, 104, 5, 160, 9, 112, 13, 40, 15, 153, 28, 40, 81, 41, 79, 79, 53, 49, 38, 13, 8, 215, 138, 143, 120, 120, 120, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 195, 0, 56, 2, 122, 5, 68, 9, 112, 13, 30, 15, 83, 27, 50, 73, 33, 76, 65, 46, 53, 38, 13, 7, 201, 130, 147, 121, 121, 127, 237, 165, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 144, 0, 173, 1, 140, 5, 232, 8, 55, 13, 20, 15, 13, 26, 60, 55, 21, 69, 49, 38, 39, 32, 12, 7, 188, 123, 151, 122, 122, 135, 237, 165, 151, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 147, 0, 64, 1, 20, 5, 34, 9, 40, 13, 15, 15, 105, 25, 35, 37, 10, 61, 46, 28, 25, 18, 12, 7, 181, 109, 137, 123, 123, 139, 187, 120, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 1, 0, 147, 0, 64, 1, 20, 5, 34, 9, 40, 13, 15, 15, 105, 25, 0, 29, 9, 54, 41, 25, 22, 16, 11, 6, 181, 109, 137, 123, 123, 139, 187, 120, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 232, 65, 0, 191, 129, 244, 194, 182, 76, 250, 23, 8, 155, 0, 4, 0, 1, 0, 133, 0, 144, 1, 64, 6, 116, 9, 196, 12, 151, 14, 39, 25, 50, 40, 23, 56, 50, 37, 41, 32, 12, 10, 177, 127, 132, 124, 123, 138, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 133, 0, 144, 1, 64, 6, 116, 9, 196, 12, 151, 14, 39, 25, 70, 52, 26, 64, 57, 43, 46, 37, 13, 11, 177, 127, 132, 124, 123, 138, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 133, 0, 144, 1, 64, 6, 116, 9, 196, 12, 151, 14, 39, 25, 35, 52, 26, 64, 57, 43, 46, 37, 13, 11, 177, 127, 132, 124, 123, 138, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 133, 0, 144, 1, 64, 6, 116, 9, 196, 12, 151, 14, 39, 25, 0, 31, 20, 50, 44, 33, 36, 28, 10, 9, 177, 127, 132, 124, 123, 138, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 95, 0, 4, 0, 1, 0, 135, 0, 151, 1, 220, 5, 96, 9, 188, 12, 136, 14, 153, 24, 45, 43, 21, 59, 56, 46, 37, 28, 10, 11, 178, 126, 132, 123, 123, 141, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 135, 0, 151, 1, 220, 5, 96, 9, 188, 12, 136, 14, 153, 24, 80, 71, 28, 76, 72, 60, 48, 36, 13, 14, 178, 126, 132, 123, 123, 141, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 135, 0, 202, 1, 233, 5, 179, 9, 188, 12, 136, 14, 153, 24, 50, 76, 33, 81, 72, 60, 48, 36, 13, 14, 178, 126, 132, 123, 123, 141, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 135, 0, 202, 1, 233, 5, 179, 9, 188, 12, 136, 14, 153, 24, 0, 76, 33, 81, 72, 60, 48, 36, 13, 14, 178, 126, 132, 123, 123, 141, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 0, 0, 4, 0, 1, 0, 168, 0, 232, 1, 152, 3, 136, 9, 244, 11, 141, 14, 32, 27, 45, 55, 28, 58, 65, 39, 32, 18, 13, 5, 165, 135, 150, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 168, 0, 232, 1, 152, 3, 136, 9, 244, 11, 141, 14, 32, 27, 90, 109, 42, 80, 92, 59, 48, 27, 20, 8, 165, 135, 150, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 171, 0, 160, 1, 211, 2, 101, 9, 239, 12, 42, 15, 89, 27, 60, 57, 28, 60, 52, 27, 22, 14, 11, 8, 196, 108, 123, 120, 120, 120, 165, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 172, 0, 160, 1, 188, 2, 96, 9, 12, 13, 60, 15, 96, 27, 0, 36, 24, 48, 40, 24, 20, 12, 10, 8, 200, 105, 120, 120, 120, 120, 200, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 155, 0, 5, 0, 1, 0, 136, 0, 232, 1, 64, 6, 140, 10, 232, 13, 64, 16, 95, 27, 45, 44, 24, 58, 58, 43, 33, 27, 16, 6, 170, 152, 153, 122, 124, 128, 197, 152, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 136, 0, 232, 1, 64, 6, 140, 10, 232, 13, 64, 16, 95, 27, 60, 67, 30, 72, 72, 53, 41, 34, 20, 8, 170, 152, 153, 122, 124, 128, 197, 152, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 136, 0, 232, 1, 64, 6, 140, 10, 232, 13, 64, 16, 95, 27, 40, 60, 28, 68, 68, 50, 39, 32, 19, 7, 170, 152, 153, 122, 124, 128, 197, 152, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 160, 0, 136, 1, 12, 8, 60, 10, 127, 13, 159, 14, 16, 28, 50, 46, 31, 55, 51, 54, 33, 36, 10, 7, 168, 109, 141, 120, 120, 120, 200, 109, 141, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 160, 0, 136, 1, 12, 8, 60, 10, 127, 13, 159, 14, 16, 28, 0, 32, 26, 46, 43, 45, 27, 30, 8, 6, 168, 109, 141, 120, 120, 120, 200, 109, 141, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 90, 0, 4, 0, 5, 0, 196, 0, 114, 1, 84, 4, 252, 8, 88, 12, 91, 14, 32, 27, 35, 13, 36, 20, 38, 12, 16, 16, 6, 0, 125, 60, 135, 120, 120, 120, 80, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 196, 0, 114, 1, 84, 4, 252, 8, 88, 12, 91, 14, 32, 27, 25, 13, 36, 20, 38, 12, 16, 16, 6, 0, 125, 60, 135, 120, 120, 120, 80, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 5, 0, 196, 0, 114, 1, 84, 4, 252, 8, 88, 12, 91, 14, 32, 27, 30, 5, 22, 11, 22, 8, 11, 11, 4, 0, 125, 60, 135, 120, 120, 120, 80, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 196, 0, 114, 1, 84, 4, 252, 8, 88, 12, 91, 14, 32, 27, 0, 3, 19, 9, 19, 7, 9, 9, 3, 0, 125, 60, 135, 120, 120, 120, 80, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 90, 0, 4, 0, 5, 0, 236, 0, 124, 1, 12, 7, 236, 9, 172, 13, 160, 15, 0, 27, 35, 17, 40, 41, 25, 16, 13, 16, 8, 0, 132, 60, 90, 120, 120, 120, 42, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 236, 0, 124, 1, 12, 7, 236, 9, 172, 13, 160, 15, 0, 27, 25, 14, 36, 37, 22, 14, 12, 14, 8, 0, 132, 60, 90, 120, 120, 120, 42, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 236, 0, 124, 1, 12, 7, 236, 9, 172, 13, 160, 15, 0, 27, 30, 5, 22, 22, 20, 12, 10, 12, 7, 0, 132, 60, 90, 120, 120, 120, 42, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 236, 0, 124, 1, 12, 7, 236, 9, 172, 13, 160, 15, 0, 27, 0, 3, 16, 16, 15, 9, 8, 9, 5, 0, 132, 60, 90, 120, 120, 120, 42, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 100, 0, 4, 0, 5, 0, 204, 0, 120, 1, 92, 8, 124, 11, 172, 13, 160, 15, 0, 27, 30, 19, 41, 45, 19, 19, 15, 15, 9, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 204, 0, 120, 1, 192, 8, 28, 12, 172, 13, 160, 15, 0, 27, 25, 16, 39, 39, 18, 18, 15, 14, 9, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 5, 0, 204, 0, 120, 1, 192, 8, 28, 12, 172, 13, 160, 15, 0, 27, 45, 4, 21, 21, 15, 15, 12, 12, 7, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 37, 0, 204, 0, 120, 1, 192, 8, 28, 12, 172, 13, 160, 15, 0, 27, 0, 4, 21, 21, 15, 15, 12, 12, 7, 0, 135, 60, 90, 120, 120, 120, 45, 135, 105, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 95, 0, 4, 0, 5, 0, 240, 0, 13, 2, 248, 9, 124, 11, 76, 14, 23, 17, 224, 23, 40, 17, 44, 14, 19, 10, 10, 13, 4, 0, 162, 90, 165, 120, 120, 120, 132, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 240, 0, 13, 2, 248, 9, 124, 11, 76, 14, 23, 17, 224, 23, 25, 17, 44, 14, 19, 10, 10, 13, 4, 0, 162, 90, 165, 120, 120, 120, 132, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 232, 0, 13, 2, 236, 9, 44, 11, 76, 14, 23, 17, 224, 23, 30, 5, 25, 6, 15, 8, 8, 10, 3, 0, 162, 90, 165, 120, 120, 120, 132, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 232, 0, 13, 2, 236, 9, 44, 11, 76, 14, 23, 17, 224, 23, 0, 4, 22, 5, 13, 7, 7, 9, 3, 0, 162, 90, 165, 120, 120, 120, 132, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 97, 9, 23, 0, 0, 255, 255, 254, 255, 255, 255, 255, 254, 254, 254, 254, 254, 254, 255, 255, 254, 254, 254, 255, 255, 254, 255, 255, 254, 255, 0, 255, 255, 254, 255, 0, 0, 255, 255, 255, 0, 255, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 254, 255, 0, 0, 0, 0, 0, 0, 0, 7, 40, 43, 3, 236, 248, 2, 254, 9, 28, 28, 15, 6, 0, 251, 1, 17, 25, 17, 16, 22, 13, 9, 24, 30, 25, 29, 91, 77, 249, 254, 0, 245, 246, 42, 53, 24, 241, 196, 216, 250, 239, 246, 4, 245, 195, 162, 180, 212, 233, 249, 235, 204, 175, 172, 165, 194, 235, 223, 215, 169, 135, 191, 226, 235, 0, 249, 242, 239, 213, 191, 2, 90, 36, 246, 254, 12, 72, 57, 93, 127, 43, 26, 20, 11, 36, 68, 78, 30, 14, 239, 229, 46, 32, 240, 14, 37, 231, 164, 187, 7, 26, 223, 167, 175, 221, 208, 181, 182, 227, 241, 173, 188, 230, 216, 197, 211, 247, 213, 230, 240, 192, 228, 1, 8, 26, 5, 224, 3, 32, 24, 15, 20, 16, 23, 0, 6, 20, 4, 32, 64, 49, 40, 78, 49, 13, 11, 29, 50, 28, 255, 241, 20, 36, 254, 207, 251, 69, 29, 220, 197, 244, 18, 234, 202, 238, 44, 6, 161, 164, 1, 39, 17, 202, 184, 9, 25, 210, 178, 243, 56, 29, 215, 166, 250, 83, 246, 197, 14, 80, 17, 190, 216, 15, 58, 55, 31, 6, 243, 241, 251, 33, 38, 249, 24, 40, 233, 183, 219, 29, 50, 31, 245, 252, 24, 11, 222, 198, 250, 61, 38, 251, 241, 5, 18, 254, 247, 62, 62, 44, 4, 207, 214, 245, 33, 62, 32, 250, 252, 226, 202, 207, 241, 26, 47, 29, 187, 175, 228, 242, 236, 243, 11, 11, 228, 208, 180, 194, 235, 46, 31, 222, 220, 242, 250, 202, 215, 2, 47, 23, 216, 229, 253, 236, 244, 247, 242, 26, 33, 229, 193, 246, 15, 3, 5, 5, 17, 253, 236, 220, 238, 36, 23, 251, 202, 209, 11, 23, 248, 242, 37, 8, 193, 208, 245, 10, 31, 2, 240, 1, 254, 228, 192, 221, 16, 38, 27, 244, 253, 244, 209, 223, 0, 40, 39, 241, 239, 2, 10, 243, 227, 12, 44, 40, 19, 237, 230, 243, 253, 8, 0, 49, 63, 19, 249, 208, 238, 22, 21, 4, 254, 35, 13, 246, 0, 248, 251, 0, 10, 23, 32, 29, 254, 252, 243, 240, 16, 32, 13, 19, 38, 11, 246, 0, 251, 251, 7, 29, 41, 34, 28, 232, 231, 10, 9, 254, 4, 47, 48, 12, 226, 245, 27, 2, 230, 232, 35, 44, 241, 227, 247, 14, 248, 205, 235, 23, 21, 3, 3, 252, 235, 199, 213, 3, 25, 16, 5, 253, 4, 10, 232, 217, 248, 39, 18, 226, 248, 32, 13, 222, 197, 251, 44, 248, 236, 45, 45, 0, 220, 216, 251, 3, 4, 7, 22, 33, 252, 216, 243, 255, 255, 255, 245, 4, 243, 245, 1, 4, 225, 212, 241, 241, 253, 3, 2, 229, 233, 254, 227, 234, 244, 238, 236, 6, 7, 251, 237, 242, 247, 234, 247, 14, 2, 0, 248, 241, 238, 235, 255, 8, 17, 255, 248, 14, 18, 240, 207, 7, 63, 27, 234, 242, 20, 11, 224, 217, 1, 53, 20, 236, 244, 12, 26, 240, 242, 254, 21, 4, 221, 239, 29, 14, 222, 209, 7, 18, 242, 229, 230, 242, 232, 226, 254, 19, 9, 240, 222, 243, 2, 19, 232, 219, 17, 25, 0, 238, 29, 24, 242, 237, 255, 7, 245, 254, 23, 19, 29, 2, 221, 235, 1, 15, 2, 7, 13, 16, 242, 221, 229, 245, 5, 3, 231, 248, 26, 8, 206, 210, 59, 23, 203, 217, 12, 16, 204, 226, 12, 14, 241, 247, 247, 251, 246, 203, 236, 10, 28, 3, 249, 10, 38, 14, 225, 250, 18, 5, 235, 11, 35, 24, 5, 8, 4, 246, 1, 237, 240, 245, 239, 0, 17, 4, 231, 11, 6, 211, 223, 252, 19, 249, 242, 247, 8, 0, 225, 237, 248, 254, 252, 10, 10, 2, 10, 237, 243, 22, 21, 2, 4, 1, 228, 7, 21, 246, 237, 25, 31, 246, 246, 252, 0, 247, 254, 4, 32, 32, 15, 18, 254, 255, 231, 240, 252, 27, 21, 247, 252, 250, 14, 2, 253, 3, 250, 238, 244, 3, 254, 0, 9, 31, 6, 233, 243, 238, 238, 222, 245, 24, 16, 3, 8, 17, 239, 217, 234, 234, 211, 221, 15, 48, 24, 254, 251, 251, 2, 9, 236, 242, 6, 3, 223, 242, 29, 8, 244, 229, 13, 251, 218, 219, 241, 0, 231, 0, 42, 57, 49, 28, 29, 14, 6, 3, 12, 21, 23, 19, 35, 38, 12, 22, 41, 18, 238, 233, 1, 237, 222, 246, 255, 5, 1, 249, 234, 250, 247, 219, 210, 234, 5, 0, 244, 243, 11, 23, 4, 253, 4, 0, 237, 242, 13, 34, 7, 0, 21, 21, 11, 2, 251, 246, 3, 11, 18, 15, 1, 2, 2, 5, 242, 232, 227, 240, 255, 249, 230, 222, 242, 251, 235, 228, 5, 13, 246, 224, 230, 243, 244, 235, 237, 243, 252, 6, 254, 4, 250, 239, 238, 218, 213, 242, 247, 234, 248, 3, 247, 221, 231, 240, 221, 202, 201, 206, 223, 234, 249, 251, 246, 225, 225, 228, 212, 215, 238, 0, 250, 238, 245, 12, 252, 226, 228, 242, 241, 226, 229, 252, 4, 1, 250, 0, 4, 10, 2, 252, 0, 0, 253, 231, 245, 21, 15, 246, 242, 0, 2, 241, 27, 52, 7, 235, 0, 16, 216, 212, 232, 221, 218, 242, 3, 2, 9, 4, 234, 232, 234, 240, 235, 228, 235, 228, 238, 0, 251, 4, 17, 17, 13, 244, 222, 226, 237, 246, 6, 29, 58, 54, 33, 11, 249, 0, 236, 224, 252, 18, 29, 24, 27, 45, 23, 237, 236, 237, 226, 211, 215, 229, 239, 248, 8, 28, 16, 10, 5, 252, 206, 179, 219, 229, 227, 18, 45, 36, 18, 25, 11, 236, 227, 223, 231, 9, 20, 7, 13, 49, 29, 246, 232, 225, 213, 224, 237, 229, 5, 28, 16, 253, 252, 19, 11, 252, 246, 219, 226, 0, 254, 250, 28, 57, 42, 10, 250, 248, 229, 238, 3, 10, 50, 49, 32, 14, 241, 229, 232, 221, 216, 229, 12, 21, 254, 4, 16, 16, 246, 219, 226, 241, 252, 242, 0, 23, 28, 0, 223, 242, 10, 7, 253, 254, 4, 246, 225, 242, 6, 17, 18, 19, 16, 1, 7, 10, 251, 0, 20, 30, 32, 35, 33, 1, 10, 23, 14, 26, 11, 243, 242, 239, 240, 239, 11, 18, 8, 19, 26, 19, 243, 231, 228, 204, 203, 195, 225, 24, 39, 35, 24, 28, 13, 228, 198, 197, 222, 243, 237, 244, 34, 76, 71, 38, 43, 42, 17, 237, 235, 6, 24, 6, 246, 23, 56, 42, 4, 4, 20, 246, 225, 225, 226, 0, 4, 247, 248, 248, 237, 219, 241, 248, 227, 211, 230, 251, 226, 245, 22, 31, 36, 19, 254, 1, 12, 238, 200, 233, 20, 15, 26, 49, 42, 27, 45, 7, 216, 235, 5, 243, 229, 32, 45, 10, 16, 25, 21, 6, 228, 221, 241, 220, 186, 212, 7, 2, 247, 13, 48, 27, 220, 191, 183, 191, 189, 193, 6, 68, 55, 10, 0, 2, 229, 194, 194, 223, 252, 13, 24, 45, 50, 41, 31, 27, 17, 248, 228, 229, 219, 222, 7, 28, 27, 26, 30, 26, 8, 231, 207, 198, 204, 220, 222, 0, 37, 41, 40, 40, 18, 238, 243, 244, 225, 221, 230, 247, 239, 236, 12, 35, 27, 10, 4, 250, 235, 239, 247, 242, 243, 14, 16, 6, 250, 235, 242, 249, 227, 202, 232, 3, 240, 240, 4, 16, 22, 251, 222, 231, 1, 10, 0, 1, 33, 48, 27, 253, 227, 237, 3, 240, 226, 7, 27, 15, 11, 25, 31, 15, 22, 252, 234, 245, 241, 247, 238, 218, 228, 4, 6, 222, 247, 11, 249, 232, 228, 0, 1, 227, 224, 249, 5, 6, 240, 222, 216, 224, 230, 225, 248, 23, 30, 43, 43, 16, 9, 7, 0, 230, 223, 249, 29, 33, 25, 30, 23, 23, 16, 242, 237, 9, 12, 243, 230, 244, 243, 238, 211, 205, 239, 7, 5, 244, 3, 9, 254, 226, 219, 241, 241, 235, 236, 250, 4, 9, 249, 222, 5, 33, 27, 10, 251, 3, 6, 255, 233, 223, 228, 220, 231, 12, 25, 22, 30, 41, 27, 252, 229, 234, 229, 220, 228, 241, 250, 246, 7, 29, 32, 12, 232, 224, 213, 212, 230, 229, 240, 239, 8, 21, 19, 28, 26, 13, 236, 218, 241, 250, 4, 12, 5, 29, 46, 25, 254, 235, 236, 244, 235, 228, 217, 233, 16, 21, 242, 243, 13, 22, 0, 254, 0, 249, 254, 247, 243, 252, 255, 7, 23, 46, 37, 13, 16, 247, 228, 222, 237, 10, 27, 23, 24, 45, 51, 26, 241, 236, 227, 211, 229, 0, 3, 3, 14, 19, 13, 21, 31, 0, 206, 202, 219, 242, 248, 220, 245, 39, 28, 3, 252, 253, 239, 210, 199, 215, 233, 26, 55, 48, 42, 38, 30, 9, 227, 212, 214, 221, 247, 8, 11, 28, 48, 45, 25, 253, 250, 245, 218, 197, 202, 236, 15, 15, 30, 33, 9, 7, 250, 217, 206, 214, 226, 255, 18, 22, 47, 74, 46, 8, 244, 236, 234, 232, 250, 9, 39, 90, 87, 52, 25, 12, 9, 231, 190, 199, 224, 244, 22, 30, 40, 45, 21, 239, 218, 199, 190, 226, 22, 44, 21, 47, 60, 19, 223, 204, 233, 235, 220, 220, 3, 42, 50, 30, 15, 3, 239, 232, 217, 214, 239, 14, 29, 32, 39, 42, 47, 25, 245, 226, 234, 241, 244, 7, 13, 14, 9, 21, 6, 234, 221, 213, 231, 245, 252, 251, 243, 10, 11, 251, 242, 253, 239, 211, 206, 230, 244, 241, 0, 16, 27, 29, 13, 235, 222, 208, 206, 244, 10, 4, 1, 29, 43, 24, 253, 238, 239, 235, 237, 235, 243, 13, 28, 21, 6, 15, 20, 6, 244, 225, 222, 245, 6, 2, 8, 25, 39, 33, 2, 227, 225, 246, 212, 186, 230, 21, 28, 22, 31, 33, 255, 229, 215, 199, 223, 251, 252, 18, 61, 59, 38, 17, 7, 250, 231, 222, 218, 232, 249, 10, 38, 57, 35, 5, 249, 239, 227, 213, 221, 5, 14, 3, 19, 36, 43, 36, 7, 235, 214, 218, 222, 211, 212, 253, 29, 25, 16, 1, 232, 212, 203, 213, 233, 250, 7, 29, 47, 18, 4, 3, 245, 224, 208, 241, 17, 23, 0, 248, 14, 27, 23, 242, 242, 255, 249, 250, 252, 253, 2, 7, 0, 247, 239, 223, 205, 231, 254, 245, 254, 250, 7, 249, 220, 237, 18, 254, 222, 232, 2, 16, 247, 230, 246, 9, 14, 249, 233, 246, 8, 15, 9, 253, 255, 18, 15, 252, 247, 0, 248, 233, 241, 240, 251, 27, 46, 43, 16, 249, 236, 221, 218, 220, 238, 8, 17, 21, 251, 238, 1, 252, 225, 207, 221, 252, 9, 9, 10, 18, 26, 7, 227, 221, 235, 233, 238, 11, 27, 40, 42, 30, 18, 241, 217, 218, 217, 230, 2, 10, 33, 56, 47, 255, 226, 213, 204, 210, 212, 231, 17, 38, 26, 7, 250, 0, 245, 210, 199, 216, 234, 253, 12, 22, 21, 7, 245, 231, 211, 218, 249, 7, 11, 24, 24, 17, 10, 240, 229, 226, 235, 4, 14, 34, 40, 23, 17, 1, 232, 228, 244, 252, 13, 31, 29, 28, 5, 247, 244, 211, 218, 250, 3, 2, 18, 12, 249, 242, 245, 242, 219, 226, 255, 14, 17, 14, 6, 2, 251, 244, 238, 236, 253, 8, 18, 37, 38, 13, 226, 231, 254, 249, 255, 19, 35, 37, 26, 9, 0, 236, 212, 226, 249, 251, 252, 31, 64, 40, 245, 240, 241, 214, 200, 227, 21, 40, 18, 22, 32, 5, 246, 238, 232, 242, 243, 252, 11, 16, 12, 12, 20, 3, 236, 240, 3, 16, 12, 15, 18, 11, 250, 247, 248, 238, 240, 250, 254, 11, 16, 33, 35, 9, 236, 225, 239, 10, 0, 233, 5, 27, 10, 245, 239, 254, 8, 3, 2, 14, 1, 8, 15, 231, 217, 240, 251, 11, 22, 2, 11, 22, 19, 250, 232, 1, 17, 0, 247, 249, 254, 1, 248, 232, 240, 7, 30, 21, 253, 251, 235, 226, 245, 253, 243, 253, 28, 36, 20, 5, 0, 7, 1, 234, 220, 228, 245, 7, 12, 4, 245, 247, 254, 243, 224, 230, 238, 246, 10, 7, 249, 237, 251, 10, 6, 250, 255, 17, 21, 4, 240, 250, 21, 16, 253, 241, 243, 11, 15, 255, 254, 0, 243, 231, 249, 13, 7, 4, 7, 1, 250, 230, 223, 251, 3, 254, 12, 34, 36, 15, 252, 243, 245, 239, 244, 255, 15, 20, 26, 31, 7, 243, 222, 220, 236, 243, 0, 21, 20, 8, 7, 1, 241, 225, 239, 4, 7, 250, 252, 19, 13, 248, 240, 240, 241, 247, 252, 252, 252, 11, 20, 8, 250, 254, 5, 2, 247, 240, 5, 35, 19, 0, 9, 17, 18, 12, 3, 0, 253, 239, 239, 3, 3, 243, 252, 16, 8, 237, 233, 237, 232, 229, 227, 239, 20, 20, 253, 248, 242, 228, 240, 249, 246, 4, 28, 33, 11, 250, 240, 230, 239, 244, 250, 17, 33, 25, 14, 2, 239, 230, 238, 245, 250, 10, 42, 51, 18, 244, 229, 238, 230, 216, 231, 6, 32, 28, 2, 235, 228, 218, 192, 183, 222, 15, 37, 26, 5, 244, 237, 226, 225, 248, 8, 21, 42, 56, 41, 10, 242, 230, 231, 242, 249, 17, 50, 52, 18, 248, 244, 233, 225, 228, 238, 6, 43, 45, 22, 6, 248, 231, 219, 213, 225, 0, 31, 39, 16, 245, 231, 217, 210, 225, 253, 25, 45, 31, 4, 236, 228, 239, 239, 240, 249, 19, 37, 22, 4, 245, 241, 249, 245, 243, 5, 21, 16, 2, 252, 250, 255, 0, 241, 227, 230, 251, 251, 251, 11, 9, 252, 231, 219, 228, 240, 252, 7, 8, 6, 8, 4, 253, 242, 234, 241, 15, 29, 22, 12, 7, 0, 255, 247, 234, 248, 12, 22, 14, 0, 0, 0, 90, 0, 2, 0, 37, 0, 184, 0, 24, 2, 112, 5, 72, 8, 0, 10, 188, 12, 136, 19, 90, 2, 9, 16, 4, 6, 8, 3, 3, 3, 157, 125, 137, 137, 150, 175, 157, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 184, 0, 24, 2, 112, 5, 248, 7, 236, 9, 188, 12, 131, 24, 0, 0, 7, 2, 3, 8, 6, 2, 1, 1, 157, 125, 137, 137, 150, 175, 157, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 127, 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 254, 254, 253, 252, 251, 250, 249, 247, 246, 245, 244, 243, 241, 240, 239, 237, 236, 234, 233, 231, 230, 228, 226, 225, 223, 221, 220, 218, 216, 214, 212, 210, 209, 207, 205, 203, 201, 199, 197, 195, 193, 191, 189, 186, 184, 182, 180, 178, 176, 174, 171, 169, 167, 165, 162, 160, 158, 156, 153, 151, 149, 147, 144, 142, 140, 137, 135, 133, 131, 128, 126, 124, 121, 119, 117, 114, 112, 110, 108, 105, 103, 101, 99, 96, 94, 92, 90, 88, 85, 83, 81, 79, 77, 75, 73, 70, 68, 66, 64, 62, 59, 57, 55, 53, 51, 49, 46, 44, 42, 40, 38, 35, 33, 31, 29, 27, 25, 23, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0, 2, 4, 6, 8, 10, 11, 13, 15, 16, 18, 19, 21, 22, 23, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 36, 37, 38, 39, 40, 40, 41, 42, 43, 43, 44, 45, 46, 47, 48, 48, 49, 50, 51, 52, 53, 54, 55, 56, 58, 59, 60, 62, 63, 64, 66, 68, 69, 71, 73, 75, 77, 79, 81, 83, 85, 88, 90, 93, 95, 98, 101, 104, 107, 110, 114, 117, 121, 124, 128, 132, 136, 140, 145, 149, 154, 159, 163, 166, 170, 174, 177, 181, 184, 188, 192, 195, 199, 202, 206, 209, 213, 216, 219, 223, 226, 229, 232, 235, 238, 241, 243, 245, 247, 249, 250, 252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 254, 251, 248, 245, 242, 238, 234, 230, 227, 222, 218, 214, 210, 205, 201, 196, 191, 187, 182, 177, 172, 167, 162, 157, 152, 147, 142, 137, 132, 127, 122, 117, 112, 107, 102, 97, 92, 87, 82, 78, 73, 69, 64, 60, 56, 51, 47, 43, 40, 36, 32, 29, 26, 23, 20, 17, 14, 12, 9, 7, 5, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 5, 7, 10, 12, 15, 19, 23, 27, 31, 36, 41, 46, 52, 58, 65, 72, 79, 86, 94, 103, 112, 117, 122, 127, 132, 137, 142, 147, 152, 157, 162, 167, 172, 177, 182, 187, 191, 196, 201, 205, 210, 214, 218, 222, 227, 230, 234, 238, 242, 245, 248, 251, 127, 123, 118, 114, 110, 105, 101, 97, 94, 90, 86, 82, 79, 75, 72, 68, 65, 62, 59, 56, 53, 50, 47, 44, 42, 39, 37, 34, 32, 30, 28, 26, 24, 22, 20, 19, 17, 16, 14, 13, 12, 11, 10, 9, 8, 7, 6, 6, 5, 5, 5, 4, 4, 4, 4, 5, 5, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 20, 21, 23, 25, 27, 30, 32, 34, 37, 40, 42, 45, 48, 51, 55, 58, 61, 65, 68, 72, 76, 80, 84, 88, 93, 97, 101, 105, 109, 113, 117, 122, 126, 130, 134, 139, 143, 148, 152, 157, 162, 166, 171, 176, 181, 186, 191, 196, 201, 206, 211, 217, 222, 227, 233, 238, 243, 249, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 151, 143, 136, 128, 121, 114, 108, 101, 95, 90, 85, 81, 77, 73, 70, 68, 66, 65, 65, 66, 67, 69, 72, 76, 81, 86, 93, 101, 109, 119, 130, 142, 152, 152, 152, 152, 151, 151, 151, 151, 150, 150, 150, 150, 149, 149, 149, 149, 148, 148, 148, 148, 147, 147, 147, 147, 146, 146, 146, 146, 145, 145, 145, 145, 144, 144, 144, 144, 143, 143, 143, 143, 142, 142, 142, 142, 141, 141, 141, 141, 140, 140, 140, 254, 251, 248, 244, 241, 237, 233, 229, 225, 221, 217, 213, 208, 204, 199, 195, 190, 185, 180, 176, 171, 166, 161, 156, 151, 146, 141, 136, 131, 126, 121, 117, 112, 107, 102, 97, 93, 88, 83, 79, 74, 70, 66, 61, 57, 53, 49, 45, 42, 38, 35, 31, 28, 25, 22, 19, 17, 14, 12, 10, 8, 6, 5, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 5, 7, 9, 12, 14, 17, 21, 24, 27, 29, 32, 34, 37, 39, 42, 45, 47, 49, 52, 54, 57, 59, 61, 63, 65, 67, 69, 71, 73, 74, 76, 77, 78, 80, 80, 81, 82, 82, 82, 83, 82, 82, 82, 81, 80, 79, 77, 76, 74, 71, 69, 66, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 124, 120, 116, 112, 108, 104, 101, 97, 94, 91, 88, 86, 84, 82, 80, 78, 77, 76, 75, 75, 75, 76, 76, 78, 79, 81, 84, 86, 90, 94, 98, 103, 108, 114, 120, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 175, 0, 4, 0, 1, 0, 153, 0, 128, 1, 224, 2, 200, 10, 148, 12, 176, 14, 244, 26, 45, 54, 16, 64, 49, 33, 40, 27, 15, 6, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 1, 250, 0, 0, 3, 0, 153, 0, 128, 1, 224, 2, 200, 10, 148, 12, 176, 14, 244, 26, 70, 91, 22, 84, 64, 44, 52, 36, 20, 9, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 153, 0, 128, 1, 224, 2, 200, 10, 148, 12, 176, 14, 244, 26, 60, 91, 22, 84, 64, 44, 52, 36, 20, 9, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 2, 0, 0, 0, 240, 250, 209, 182, 1, 0, 153, 0, 128, 1, 224, 2, 200, 10, 148, 12, 176, 14, 244, 26, 0, 91, 22, 84, 64, 44, 52, 36, 20, 9, 165, 126, 145, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 160, 0, 4, 0, 1, 0, 130, 0, 48, 1, 24, 6, 36, 9, 12, 13, 0, 15, 151, 25, 45, 40, 19, 58, 43, 34, 40, 30, 10, 11, 167, 96, 127, 120, 120, 120, 197, 120, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 1, 250, 0, 0, 3, 0, 130, 0, 48, 1, 24, 6, 36, 9, 12, 13, 0, 15, 151, 25, 70, 69, 25, 76, 56, 45, 52, 40, 13, 15, 167, 96, 127, 120, 120, 120, 197, 120, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 130, 0, 48, 1, 24, 6, 36, 9, 12, 13, 0, 15, 151, 25, 45, 56, 23, 68, 50, 40, 46, 36, 11, 13, 167, 96, 127, 120, 120, 120, 197, 120, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 2, 0, 0, 0, 240, 250, 209, 182, 1, 0, 130, 0, 48, 1, 24, 6, 36, 9, 12, 13, 0, 15, 151, 25, 0, 69, 25, 76, 56, 45, 52, 40, 13, 15, 167, 96, 127, 120, 120, 120, 197, 120, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 185, 0, 4, 0, 1, 0, 112, 0, 244, 1, 132, 5, 36, 9, 188, 12, 116, 14, 96, 27, 45, 41, 27, 54, 66, 33, 39, 30, 15, 7, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 1, 250, 0, 0, 3, 0, 116, 0, 244, 1, 132, 5, 16, 9, 188, 12, 116, 14, 96, 27, 80, 67, 34, 66, 88, 44, 55, 40, 21, 7, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 116, 0, 244, 1, 132, 5, 16, 9, 188, 12, 116, 14, 96, 27, 60, 54, 30, 59, 79, 39, 49, 36, 19, 7, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 2, 0, 0, 0, 240, 250, 209, 182, 1, 0, 116, 0, 244, 1, 132, 5, 36, 9, 188, 12, 116, 14, 96, 27, 0, 32, 24, 47, 58, 25, 36, 26, 13, 7, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 0, 0, 6, 0, 1, 0, 180, 0, 160, 2, 180, 5, 126, 9, 233, 12, 116, 14, 176, 27, 40, 41, 33, 52, 68, 44, 39, 31, 13, 3, 174, 157, 145, 120, 120, 120, 200, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 1, 250, 0, 0, 3, 0, 180, 0, 160, 2, 180, 5, 126, 9, 233, 12, 116, 14, 176, 27, 50, 92, 50, 78, 101, 65, 58, 47, 20, 4, 174, 157, 145, 120, 120, 120, 200, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 180, 0, 160, 2, 180, 5, 126, 9, 233, 12, 116, 14, 176, 27, 50, 69, 44, 68, 88, 57, 50, 41, 17, 4, 174, 157, 145, 120, 120, 120, 200, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 2, 0, 0, 0, 240, 250, 209, 182, 1, 0, 174, 0, 104, 2, 63, 6, 195, 9, 22, 13, 128, 14, 204, 27, 60, 47, 36, 57, 68, 50, 43, 34, 14, 4, 172, 140, 150, 120, 120, 120, 200, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 160, 0, 189, 1, 132, 7, 102, 10, 127, 13, 159, 14, 16, 28, 30, 49, 34, 59, 55, 59, 47, 34, 11, 7, 168, 99, 162, 120, 120, 120, 200, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 108, 65, 227, 191, 251, 250, 194, 182, 1, 0, 156, 0, 144, 1, 208, 7, 140, 10, 152, 13, 166, 14, 32, 28, 0, 33, 29, 51, 45, 54, 42, 30, 9, 7, 167, 90, 165, 120, 120, 120, 122, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 8, 87, 182, 53, 250, 0, 0, 250, 0, 5, 0, 1, 0, 135, 0, 88, 1, 220, 5, 132, 8, 128, 12, 128, 14, 153, 24, 45, 38, 11, 58, 50, 44, 41, 29, 9, 10, 178, 122, 132, 123, 123, 141, 187, 130, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 1, 250, 0, 0, 3, 0, 135, 0, 88, 1, 220, 5, 132, 8, 128, 12, 128, 14, 153, 24, 80, 77, 16, 84, 72, 64, 58, 41, 13, 14, 178, 122, 132, 123, 123, 141, 187, 130, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 141, 0, 86, 1, 132, 6, 29, 9, 192, 12, 170, 14, 158, 25, 80, 50, 14, 68, 54, 50, 47, 35, 11, 11, 175, 118, 139, 122, 122, 134, 187, 130, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 2, 0, 0, 0, 240, 250, 209, 182, 1, 0, 158, 0, 80, 1, 12, 8, 130, 10, 86, 13, 13, 15, 255, 27, 45, 31, 15, 53, 30, 37, 37, 31, 9, 8, 168, 109, 155, 120, 120, 120, 177, 109, 152, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 156, 0, 72, 1, 112, 8, 160, 10, 92, 13, 10, 15, 32, 28, 0, 31, 18, 55, 33, 36, 37, 29, 8, 7, 167, 105, 155, 120, 120, 120, 122, 105, 140, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 108, 65, 227, 191, 251, 250, 194, 182, 0, 0, 6, 0, 1, 0, 224, 0, 8, 3, 216, 4, 236, 9, 8, 12, 116, 14, 224, 27, 46, 69, 26, 64, 75, 42, 45, 28, 10, 5, 225, 120, 187, 120, 120, 120, 255, 120, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 1, 250, 0, 0, 3, 0, 224, 0, 8, 3, 216, 4, 236, 9, 8, 12, 116, 14, 224, 27, 60, 111, 34, 82, 95, 54, 57, 36, 13, 7, 225, 120, 187, 120, 120, 120, 255, 120, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 224, 0, 208, 2, 16, 4, 96, 9, 8, 12, 116, 14, 224, 27, 70, 100, 32, 77, 64, 51, 54, 34, 12, 6, 225, 120, 187, 120, 120, 120, 255, 120, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 2, 0, 0, 0, 240, 250, 209, 182, 1, 0, 240, 0, 24, 2, 92, 3, 56, 9, 48, 12, 79, 14, 160, 27, 70, 93, 38, 68, 40, 36, 48, 33, 15, 8, 215, 112, 172, 120, 120, 120, 255, 120, 187, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 0, 1, 200, 1, 52, 3, 16, 9, 8, 12, 41, 14, 96, 27, 30, 84, 36, 76, 59, 21, 35, 23, 15, 8, 205, 105, 157, 120, 120, 120, 145, 105, 157, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 108, 65, 227, 191, 251, 250, 194, 182, 1, 0, 172, 0, 152, 1, 188, 2, 192, 8, 88, 12, 60, 15, 96, 27, 0, 37, 24, 48, 40, 24, 20, 12, 10, 8, 200, 90, 120, 120, 120, 120, 200, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 8, 87, 182, 53, 250, 0, 0, 217, 0, 6, 0, 1, 0, 104, 0, 144, 1, 132, 8, 160, 10, 72, 13, 60, 15, 32, 27, 42, 45, 17, 61, 61, 61, 57, 31, 12, 7, 167, 120, 157, 120, 120, 120, 167, 120, 157, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 1, 250, 0, 0, 3, 0, 104, 0, 144, 1, 132, 8, 160, 10, 72, 13, 60, 15, 32, 27, 40, 63, 20, 72, 72, 72, 67, 37, 15, 8, 167, 120, 157, 120, 120, 120, 167, 120, 157, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 117, 0, 192, 1, 9, 8, 113, 10, 47, 13, 24, 15, 42, 27, 50, 64, 24, 74, 74, 68, 64, 38, 16, 8, 167, 122, 153, 120, 120, 120, 167, 120, 157, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 2, 0, 0, 0, 240, 250, 209, 182, 1, 0, 169, 0, 69, 2, 26, 6, 180, 9, 201, 12, 135, 14, 82, 27, 50, 64, 37, 74, 74, 50, 48, 38, 20, 7, 167, 133, 137, 120, 120, 120, 167, 120, 157, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 176, 0, 128, 2, 220, 5, 156, 9, 188, 12, 116, 14, 88, 27, 35, 58, 37, 71, 71, 46, 44, 37, 19, 7, 167, 135, 135, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 108, 65, 227, 191, 251, 250, 194, 182, 1, 0, 176, 0, 128, 2, 220, 5, 156, 9, 188, 12, 116, 14, 88, 27, 0, 39, 30, 58, 58, 38, 36, 30, 16, 6, 167, 135, 135, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 8, 87, 182, 53, 250, 0, 0, 110, 0, 4, 0, 5, 0, 76, 0, 80, 1, 200, 5, 40, 10, 152, 13, 160, 15, 32, 29, 40, 19, 11, 48, 18, 14, 36, 21, 9, 0, 150, 123, 97, 120, 120, 120, 90, 116, 97, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 1, 250, 0, 0, 1, 0, 76, 0, 80, 1, 200, 5, 40, 10, 152, 13, 160, 15, 32, 29, 35, 27, 13, 57, 22, 17, 42, 25, 11, 0, 150, 123, 97, 120, 120, 120, 90, 116, 97, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 17, 0, 76, 0, 80, 1, 200, 5, 40, 10, 152, 13, 160, 15, 32, 29, 35, 27, 13, 57, 22, 17, 42, 25, 11, 0, 150, 123, 97, 120, 120, 120, 90, 116, 97, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 2, 0, 0, 0, 240, 250, 209, 182, 1, 0, 76, 0, 80, 1, 200, 5, 40, 10, 152, 13, 160, 15, 32, 29, 0, 27, 13, 57, 22, 17, 42, 25, 11, 0, 150, 123, 97, 120, 120, 120, 90, 116, 97, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 46, 0, 8, 0, 1, 0, 200, 0, 127, 2, 126, 5, 127, 9, 197, 12, 114, 14, 244, 26, 12, 59, 40, 72, 72, 40, 28, 20, 16, 12, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 200, 0, 125, 2, 136, 5, 127, 9, 207, 12, 123, 14, 244, 26, 12, 66, 52, 72, 72, 44, 32, 28, 20, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 200, 0, 103, 2, 9, 6, 181, 9, 248, 12, 224, 14, 244, 26, 12, 53, 52, 60, 64, 36, 28, 28, 20, 16, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 200, 0, 65, 2, 159, 6, 235, 9, 253, 12, 61, 15, 244, 26, 12, 43, 52, 48, 52, 28, 28, 28, 8, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 152, 0, 200, 1, 12, 3, 144, 11, 16, 14, 180, 15, 159, 27, 48, 32, 36, 32, 44, 36, 32, 20, 16, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 152, 0, 72, 1, 208, 2, 144, 11, 16, 14, 200, 15, 159, 27, 24, 22, 36, 20, 20, 8, 4, 4, 8, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 1, 0, 152, 0, 72, 1, 208, 2, 144, 11, 16, 14, 200, 15, 159, 27, 24, 22, 36, 20, 20, 8, 4, 4, 8, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 232, 65, 0, 191, 129, 244, 194, 182, 76, 250, 23, 8, 1, 0, 152, 0, 72, 1, 208, 2, 144, 11, 16, 14, 200, 15, 159, 27, 0, 22, 36, 20, 20, 8, 4, 4, 8, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 188, 69, 0, 182, 129, 244, 194, 182, 2, 250, 0, 0, 0, 0, 9, 0, 1, 0, 250, 0, 176, 2, 40, 4, 246, 10, 188, 12, 92, 14, 87, 27, 28, 62, 24, 59, 74, 42, 38, 34, 10, 6, 167, 147, 147, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 250, 0, 176, 2, 40, 4, 246, 10, 188, 12, 92, 14, 87, 27, 35, 127, 35, 84, 105, 60, 54, 49, 14, 8, 167, 147, 147, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 250, 0, 176, 2, 40, 4, 246, 10, 188, 12, 92, 14, 87, 27, 29, 127, 35, 84, 105, 60, 54, 49, 14, 8, 167, 147, 147, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 250, 0, 160, 2, 76, 4, 246, 10, 188, 12, 92, 14, 87, 27, 43, 118, 35, 84, 105, 60, 54, 49, 14, 8, 167, 147, 147, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 204, 0, 93, 2, 252, 4, 60, 10, 168, 12, 10, 15, 0, 28, 50, 40, 28, 53, 61, 33, 40, 20, 11, 8, 167, 165, 150, 120, 120, 120, 167, 180, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 152, 0, 200, 1, 12, 3, 144, 11, 16, 14, 180, 15, 159, 27, 21, 32, 36, 32, 44, 36, 32, 20, 16, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 1, 0, 152, 0, 72, 1, 208, 2, 144, 11, 16, 14, 200, 15, 159, 27, 21, 22, 36, 20, 20, 8, 4, 4, 8, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 232, 65, 0, 191, 129, 244, 194, 182, 76, 250, 23, 8, 1, 0, 152, 0, 72, 1, 208, 2, 144, 11, 16, 14, 200, 15, 159, 27, 43, 22, 36, 20, 20, 8, 4, 4, 8, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 188, 69, 0, 182, 129, 244, 194, 182, 2, 250, 0, 0, 1, 0, 152, 0, 72, 1, 208, 2, 144, 11, 16, 14, 200, 15, 159, 27, 0, 22, 36, 20, 20, 8, 4, 4, 8, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 239, 208, 182, 96, 1, 0, 182, 29, 32, 0, 0, 152, 250, 227, 191, 0, 0, 6, 0, 1, 0, 228, 0, 224, 2, 180, 5, 196, 9, 68, 12, 216, 14, 80, 28, 45, 46, 25, 55, 66, 44, 36, 32, 12, 5, 172, 142, 180, 120, 120, 120, 255, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 228, 0, 224, 2, 180, 5, 196, 9, 68, 12, 216, 14, 80, 28, 66, 83, 34, 75, 90, 60, 49, 43, 17, 7, 172, 142, 180, 120, 120, 120, 255, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 222, 0, 224, 2, 40, 5, 96, 9, 98, 12, 76, 14, 247, 27, 41, 73, 29, 63, 84, 46, 52, 35, 14, 7, 168, 124, 204, 120, 120, 120, 255, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 0, 1, 96, 2, 87, 4, 16, 9, 48, 12, 41, 14, 128, 27, 40, 64, 28, 61, 77, 35, 52, 36, 15, 7, 237, 126, 192, 120, 120, 120, 141, 126, 147, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 0, 1, 208, 1, 189, 3, 16, 9, 8, 12, 41, 14, 96, 27, 40, 65, 36, 68, 59, 21, 35, 23, 15, 8, 205, 90, 180, 120, 120, 120, 145, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 172, 0, 200, 1, 152, 3, 192, 8, 168, 12, 60, 15, 96, 27, 0, 30, 25, 50, 42, 16, 18, 13, 11, 9, 200, 90, 120, 120, 120, 120, 200, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 34, 0, 8, 0, 1, 0, 200, 0, 196, 2, 190, 6, 114, 9, 178, 13, 224, 13, 244, 26, 12, 56, 40, 72, 68, 64, 20, 20, 20, 12, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 200, 0, 201, 2, 197, 6, 100, 9, 129, 13, 48, 14, 244, 26, 12, 66, 40, 80, 76, 64, 24, 24, 16, 16, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 200, 0, 200, 2, 192, 6, 98, 9, 90, 13, 131, 14, 244, 26, 12, 56, 40, 72, 72, 60, 40, 0, 16, 12, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 200, 0, 197, 2, 184, 6, 97, 9, 75, 13, 174, 14, 244, 26, 24, 51, 36, 68, 68, 56, 48, 12, 16, 16, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 200, 0, 182, 2, 153, 6, 108, 9, 67, 13, 220, 14, 244, 26, 36, 48, 36, 68, 60, 48, 44, 28, 16, 12, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 152, 0, 200, 1, 12, 3, 144, 11, 16, 14, 180, 15, 159, 27, 24, 32, 36, 32, 44, 36, 32, 20, 16, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 1, 0, 152, 0, 72, 1, 208, 2, 144, 11, 16, 14, 200, 15, 159, 27, 36, 22, 36, 20, 20, 8, 4, 4, 8, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 232, 65, 0, 191, 129, 244, 194, 182, 76, 250, 23, 8, 1, 0, 152, 0, 72, 1, 208, 2, 144, 11, 16, 14, 200, 15, 159, 27, 0, 22, 36, 20, 20, 8, 4, 4, 8, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 188, 69, 0, 182, 129, 244, 194, 182, 2, 250, 0, 0, 89, 0, 9, 0, 1, 0, 200, 0, 104, 1, 38, 8, 98, 10, 18, 13, 10, 15, 244, 26, 12, 55, 30, 57, 48, 42, 39, 24, 12, 9, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 200, 0, 136, 1, 230, 7, 48, 10, 17, 13, 30, 15, 244, 26, 12, 111, 36, 92, 64, 64, 56, 36, 20, 12, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 200, 0, 136, 1, 223, 7, 46, 10, 23, 13, 38, 15, 244, 26, 12, 110, 40, 88, 64, 64, 56, 40, 24, 16, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 200, 0, 136, 1, 224, 7, 48, 10, 26, 13, 40, 15, 244, 26, 12, 97, 36, 84, 60, 60, 56, 36, 24, 12, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 200, 0, 144, 1, 245, 7, 60, 10, 43, 13, 84, 15, 244, 26, 12, 68, 40, 60, 56, 56, 56, 40, 20, 12, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 152, 0, 200, 1, 152, 8, 140, 10, 16, 14, 180, 15, 159, 27, 24, 24, 36, 32, 36, 36, 32, 20, 16, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 1, 0, 168, 0, 96, 1, 204, 6, 196, 9, 176, 14, 48, 17, 244, 26, 42, 37, 44, 40, 8, 36, 24, 12, 0, 0, 125, 125, 137, 137, 150, 175, 125, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 232, 65, 0, 191, 129, 244, 194, 182, 76, 250, 23, 8, 1, 0, 168, 0, 96, 1, 204, 6, 196, 9, 176, 14, 68, 17, 244, 26, 30, 37, 44, 40, 8, 36, 24, 12, 0, 0, 125, 125, 137, 137, 150, 175, 125, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 188, 69, 0, 182, 129, 244, 194, 182, 2, 250, 0, 0, 1, 0, 168, 0, 96, 1, 204, 6, 196, 9, 176, 14, 68, 17, 244, 26, 0, 26, 40, 32, 8, 16, 8, 12, 0, 0, 125, 125, 137, 137, 150, 175, 125, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 239, 208, 182, 96, 1, 0, 182, 29, 32, 0, 0, 152, 250, 227, 191, 0, 0, 5, 0, 1, 0, 200, 0, 38, 1, 6, 5, 126, 10, 152, 11, 253, 14, 244, 26, 29, 91, 56, 52, 48, 44, 16, 28, 12, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 200, 0, 58, 1, 37, 5, 140, 10, 174, 16, 160, 15, 244, 26, 51, 74, 48, 52, 40, 36, 12, 16, 16, 12, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 200, 0, 42, 1, 244, 4, 57, 10, 85, 10, 215, 16, 244, 26, 98, 59, 48, 40, 32, 20, 8, 4, 4, 4, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 152, 0, 72, 1, 208, 2, 144, 11, 16, 14, 200, 15, 159, 27, 104, 52, 52, 36, 20, 8, 4, 4, 8, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 152, 0, 72, 1, 208, 2, 144, 11, 16, 14, 200, 15, 159, 27, 0, 22, 36, 20, 20, 8, 4, 4, 8, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 23, 0, 7, 0, 1, 0, 200, 0, 191, 1, 229, 5, 86, 9, 209, 12, 236, 14, 244, 26, 23, 73, 36, 72, 76, 40, 40, 28, 24, 12, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 200, 0, 193, 1, 232, 5, 89, 9, 218, 12, 246, 14, 244, 26, 24, 70, 32, 72, 76, 44, 44, 36, 28, 16, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 200, 0, 194, 1, 241, 5, 85, 9, 209, 12, 239, 14, 244, 26, 12, 55, 32, 64, 60, 36, 36, 28, 20, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 200, 0, 200, 1, 119, 6, 146, 9, 16, 13, 86, 15, 244, 26, 12, 38, 36, 48, 40, 32, 32, 24, 16, 12, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 152, 0, 200, 1, 12, 3, 144, 11, 16, 14, 180, 15, 159, 27, 36, 39, 44, 36, 44, 36, 32, 20, 16, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 152, 0, 72, 1, 208, 2, 144, 11, 16, 14, 200, 15, 159, 27, 48, 22, 36, 20, 20, 8, 4, 4, 8, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 1, 0, 152, 0, 72, 1, 208, 2, 144, 11, 16, 14, 200, 15, 159, 27, 0, 22, 36, 20, 20, 8, 4, 4, 8, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 232, 65, 0, 191, 129, 244, 194, 182, 76, 250, 23, 8, 0, 0, 6, 0, 1, 0, 152, 0, 56, 2, 132, 3, 44, 11, 192, 13, 120, 15, 159, 27, 45, 62, 29, 67, 58, 32, 29, 22, 14, 6, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 152, 0, 56, 2, 132, 3, 44, 11, 192, 13, 120, 15, 159, 27, 84, 116, 40, 92, 80, 44, 40, 31, 20, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 152, 0, 72, 2, 92, 3, 144, 11, 232, 13, 140, 15, 159, 27, 40, 112, 40, 80, 80, 44, 40, 31, 20, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 152, 0, 200, 1, 12, 3, 144, 11, 16, 14, 180, 15, 159, 27, 55, 32, 36, 32, 44, 36, 32, 20, 16, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 152, 0, 72, 1, 208, 2, 144, 11, 16, 14, 200, 15, 159, 27, 60, 22, 36, 20, 20, 8, 4, 4, 8, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 152, 0, 72, 1, 208, 2, 144, 11, 16, 14, 200, 15, 159, 27, 0, 22, 36, 20, 20, 8, 4, 4, 8, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 0, 0, 6, 0, 1, 0, 152, 0, 56, 2, 132, 3, 44, 11, 192, 13, 120, 15, 159, 27, 55, 116, 40, 92, 80, 44, 40, 31, 20, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 1, 0, 152, 0, 56, 2, 132, 3, 44, 11, 192, 13, 120, 15, 159, 27, 74, 116, 40, 92, 80, 44, 40, 31, 20, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 3, 0, 176, 0, 56, 1, 92, 3, 56, 9, 12, 13, 60, 15, 144, 26, 46, 78, 4, 96, 52, 28, 28, 40, 16, 10, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 152, 0, 200, 1, 12, 3, 144, 11, 16, 14, 180, 15, 159, 27, 17, 32, 36, 32, 44, 36, 32, 20, 16, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 152, 0, 72, 1, 208, 2, 144, 11, 16, 14, 200, 15, 159, 27, 16, 22, 36, 20, 20, 8, 4, 4, 8, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 152, 0, 72, 1, 208, 2, 144, 11, 16, 14, 200, 15, 159, 27, 0, 22, 36, 20, 20, 8, 4, 4, 8, 8, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 175, 0, 4, 0, 1, 0, 116, 0, 232, 1, 136, 4, 236, 9, 168, 12, 156, 14, 96, 27, 45, 48, 27, 63, 60, 34, 37, 31, 16, 6, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 116, 0, 232, 1, 136, 4, 236, 9, 168, 12, 156, 14, 96, 27, 70, 93, 38, 88, 84, 48, 52, 43, 23, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 116, 0, 232, 1, 136, 4, 236, 9, 168, 12, 156, 14, 96, 27, 60, 75, 34, 79, 75, 43, 46, 39, 20, 7, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 116, 0, 232, 1, 136, 4, 236, 9, 168, 12, 156, 14, 96, 27, 0, 41, 25, 58, 56, 32, 34, 29, 15, 5, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 152, 153, 153, 154, 156, 157, 159, 161, 164, 167, 169, 172, 176, 179, 182, 186, 190, 193, 197, 201, 205, 209, 212, 216, 220, 223, 227, 230, 234, 237, 240, 242, 245, 247, 249, 251, 252, 253, 254, 254, 255, 255, 255, 255, 255, 255, 254, 253, 251, 250, 248, 246, 243, 241, 238, 236, 233, 230, 228, 224, 221, 218, 215, 211, 208, 204, 200, 196, 192, 188, 184, 180, 176, 172, 167, 163, 159, 154, 150, 145, 141, 136, 132, 127, 123, 118, 114, 109, 105, 101, 96, 92, 88, 84, 80, 76, 72, 68, 64, 60, 57, 53, 50, 47, 43, 40, 38, 35, 32, 29, 26, 23, 21, 18, 15, 13, 10, 8, 7, 5, 3, 2, 1, 0, 0, 0, 0, 0, 110, 0, 3, 0, 5, 0, 240, 0, 13, 2, 108, 7, 128, 12, 156, 14, 23, 17, 224, 23, 60, 24, 54, 8, 8, 16, 6, 8, 4, 0, 162, 90, 165, 120, 120, 120, 132, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 250, 0, 0, 5, 0, 240, 0, 13, 2, 108, 7, 128, 12, 156, 14, 23, 17, 224, 23, 50, 24, 54, 8, 8, 16, 6, 8, 4, 0, 162, 90, 165, 120, 120, 120, 132, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 240, 0, 13, 2, 108, 7, 128, 12, 156, 14, 23, 17, 224, 23, 0, 15, 43, 6, 6, 13, 5, 6, 3, 0, 162, 90, 165, 120, 120, 120, 132, 165, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 3, 0, 0, 0, 240, 250, 209, 182, 181, 2, 30, 0, 23, 23, 23, 23, 23, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 22, 22, 23, 23, 24, 24, 23, 23, 24, 24, 24, 23, 23, 22, 22, 22, 21, 21, 22, 22, 22, 22, 22, 22, 21, 22, 22, 22, 22, 21, 21, 21, 22, 21, 21, 22, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20, 20, 20, 20, 20, 20, 20, 19, 19, 19, 20, 20, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 18, 18, 17, 18, 18, 18, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 16, 16, 15, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 16, 16, 16, 17, 17, 17, 16, 17, 17, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 18, 19, 18, 18, 18, 18, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 20, 20, 19, 19, 19, 19, 19, 19, 20, 20, 19, 19, 20, 20, 20, 20, 19, 19, 20, 20, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 20, 20, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 24, 23, 23, 23, 23, 23, 23, 23, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 23, 23, 23, 23, 23, 23, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 23, 22, 22, 22, 22, 22, 22, 21, 21, 21, 21, 21, 20, 21, 21, 20, 20, 20, 19, 19, 18, 18, 17, 14, 12, 7, 1, 222, 165, 138, 148, 195, 198, 198, 244, 25, 46, 55, 66, 97, 101, 57, 31, 23, 253, 219, 214, 234, 2, 15, 26, 54, 77, 73, 65, 79, 75, 55, 28, 2, 254, 245, 236, 249, 23, 34, 48, 51, 57, 73, 62, 47, 36, 29, 22, 3, 249, 248, 1, 11, 20, 50, 73, 76, 44, 6, 13, 30, 51, 1, 2, 2, 251, 226, 225, 253, 13, 8, 4, 31, 33, 20, 10, 32, 44, 25, 243, 222, 217, 210, 204, 204, 253, 34, 46, 54, 65, 72, 71, 46, 40, 52, 37, 7, 255, 7, 22, 2, 246, 23, 47, 56, 15, 36, 47, 51, 22, 16, 49, 55, 31, 255, 25, 43, 30, 1, 22, 43, 40, 6, 19, 42, 28, 242, 222, 9, 8, 241, 226, 12, 37, 31, 35, 46, 81, 83, 51, 45, 74, 60, 27, 17, 41, 65, 55, 29, 42, 42, 247, 179, 146, 149, 154, 146, 144, 229, 243, 17, 31, 88, 105, 125, 118, 68, 76, 252, 220, 204, 207, 195, 218, 252, 22, 59, 44, 8, 243, 191, 206, 217, 166, 153, 171, 211, 228, 251, 20, 87, 118, 103, 109, 84, 65, 31, 255, 232, 250, 252, 253, 9, 18, 43, 85, 96, 88, 59, 31, 48, 48, 245, 191, 205, 221, 31, 35, 18, 39, 43, 19, 237, 232, 244, 248, 215, 195, 212, 205, 218, 236, 20, 42, 32, 19, 12, 21, 246, 225, 229, 255, 2, 1, 27, 51, 57, 0, 0, 0, 75, 8, 18, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 39, 39, 39, 39, 39, 40, 39, 39, 39, 38, 39, 38, 38, 38, 38, 38, 38, 38, 37, 37, 36, 36, 36, 36, 36, 35, 35, 36, 35, 35, 34, 35, 34, 34, 33, 33, 33, 33, 33, 33, 33, 33, 33, 32, 32, 32, 32, 31, 31, 31, 31, 30, 30, 30, 30, 30, 30, 30, 29, 29, 29, 29, 29, 30, 29, 29, 29, 28, 29, 28, 28, 28, 28, 27, 27, 27, 28, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, 26, 26, 27, 27, 26, 26, 25, 25, 25, 26, 26, 26, 26, 26, 26, 25, 25, 26, 26, 26, 26, 25, 26, 26, 26, 26, 25, 24, 24, 25, 25, 25, 25, 26, 25, 26, 26, 26, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 24, 24, 24, 24, 25, 25, 26, 26, 25, 26, 26, 26, 26, 26, 26, 26, 26, 27, 26, 26, 26, 26, 26, 26, 27, 27, 27, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 28, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 29, 30, 30, 30, 31, 31, 31, 31, 30, 30, 30, 30, 30, 30, 30, 31, 31, 30, 31, 31, 31, 31, 31, 31, 32, 32, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 37, 37, 36, 36, 36, 37, 37, 37, 37, 37, 38, 37, 37, 37, 38, 38, 38, 38, 38, 38, 39, 39, 38, 39, 40, 40, 39, 39, 39, 40, 41, 41, 41, 41, 42, 42, 42, 42, 42, 42, 42, 42, 41, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 44, 43, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 44, 44, 45, 45, 45, 45, 45, 46, 45, 45, 45, 46, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 44, 44, 44, 45, 45, 45, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 41, 41, 41, 41, 41, 42, 42, 42, 41, 42, 42, 42, 42, 42, 42, 42, 41, 42, 41, 41, 41, 41, 41, 41, 41, 42, 42, 41, 41, 40, 40, 40, 40, 39, 39, 39, 39, 39, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 38, 38, 38, 38, 38, 38, 38, 37, 37, 38, 37, 36, 36, 36, 36, 36, 36, 36, 35, 35, 35, 35, 35, 35, 35, 35, 36, 35, 34, 32, 32, 33, 34, 34, 34, 33, 32, 31, 32, 33, 32, 32, 31, 31, 30, 30, 31, 31, 31, 31, 30, 30, 30, 31, 31, 31, 32, 31, 31, 30, 30, 30, 30, 30, 29, 29, 29, 28, 29, 31, 33, 31, 26, 25, 27, 30, 31, 31, 29, 27, 27, 28, 28, 29, 31, 31, 28, 26, 27, 26, 26, 18, 238, 195, 224, 70, 120, 72, 11, 245, 235, 247, 42, 84, 72, 32, 5, 251, 0, 31, 65, 61, 27, 7, 10, 20, 34, 48, 49, 33, 16, 12, 20, 33, 45, 48, 35, 16, 8, 19, 36, 44, 42, 32, 20, 14, 19, 33, 44, 43, 31, 18, 16, 23, 33, 38, 36, 28, 22, 21, 24, 28, 29, 30, 32, 33, 29, 23, 23, 29, 32, 31, 32, 32, 27, 22, 23, 28, 30, 32, 31, 22, 21, 28, 33, 31, 30, 30, 25, 21, 22, 31, 38, 33, 21, 20, 29, 32, 28, 29, 32, 26, 21, 29, 37, 33, 27, 28, 28, 27, 32, 37, 30, 23, 28, 35, 32, 28, 30, 36, 38, 32, 21, 25, 42, 41, 29, 29, 34, 29, 29, 39, 43, 34, 26, 26, 29, 33, 40, 42, 38, 31, 29, 31, 32, 33, 41, 47, 40, 27, 23, 28, 38, 47, 46, 31, 24, 38, 45, 32, 30, 45, 46, 34, 33, 39, 36, 35, 41, 42, 37, 34, 35, 34, 35, 43, 46, 37, 33, 40, 42, 34, 37, 46, 40, 32, 43, 48, 33, 29, 45, 52, 42, 33, 32, 38, 44, 44, 46, 49, 41, 28, 33, 52, 57, 40, 25, 36, 53, 52, 36, 32, 46, 54, 44, 37, 46, 45, 33, 42, 58, 52, 37, 36, 38, 38, 48, 58, 48, 32, 31, 42, 50, 51, 42, 34, 43, 54, 46, 36, 44, 45, 34, 42, 60, 51, 31, 43, 58, 37, 22, 47, 62, 47, 42, 45, 33, 32, 54, 59, 39, 31, 36, 45, 55, 46, 31, 31, 43, 53, 58, 51, 33, 22, 28, 44, 61, 59, 39, 30, 34, 34, 42, 54, 47, 33, 36, 44, 34, 32, 61, 70, 25, 0, 32, 61, 64, 66, 45, 254, 255, 58, 82, 50, 35, 40, 26, 21, 48, 60, 45, 46, 41, 13, 25, 74, 70, 25, 23, 42, 38, 36, 49, 52, 46, 45, 35, 21, 38, 63, 55, 37, 30, 28, 36, 47, 47, 50, 50, 33, 15, 30, 60, 58, 34, 34, 44, 29, 18, 48, 77, 55, 19, 17, 30, 29, 47, 73, 56, 21, 16, 28, 39, 48, 47, 35, 33, 42, 42, 30, 26, 33, 38, 37, 43, 52, 43, 21, 14, 34, 46, 37, 34, 44, 41, 23, 17, 24, 36, 52, 59, 39, 2, 254, 30, 46, 46, 62, 53, 3, 243, 29, 51, 30, 33, 58, 41, 7, 12, 33, 38, 42, 42, 19, 13, 44, 46, 9, 6, 45, 55, 26, 12, 31, 33, 9, 23, 63, 51, 255, 246, 30, 54, 41, 33, 35, 16, 255, 13, 37, 49, 52, 40, 8, 241, 8, 57, 70, 41, 11, 0, 255, 22, 66, 72, 29, 255, 3, 20, 35, 44, 41, 25, 15, 26, 34, 21, 19, 39, 51, 30, 0, 8, 44, 48, 20, 13, 29, 29, 25, 42, 48, 22, 4, 19, 35, 32, 36, 48, 39, 17, 5, 13, 32, 48, 48, 27, 16, 30, 32, 13, 12, 39, 54, 38, 22, 22, 21, 16, 28, 36, 31, 35, 46, 42, 13, 240, 2, 60, 89, 52, 253, 243, 4, 31, 71, 79, 22, 234, 9, 45, 33, 37, 63, 36, 243, 2, 54, 58, 29, 22, 22, 16, 35, 62, 42, 7, 6, 27, 48, 50, 33, 22, 26, 24, 20, 31, 53, 48, 18, 10, 32, 45, 40, 25, 17, 40, 57, 33, 8, 16, 41, 53, 32, 21, 45, 48, 17, 255, 22, 69, 78, 34, 254, 14, 49, 39, 14, 50, 73, 18, 245, 43, 83, 43, 253, 7, 50, 66, 52, 37, 21, 3, 17, 61, 75, 52, 26, 6, 4, 37, 71, 63, 35, 27, 21, 13, 40, 74, 58, 26, 20, 24, 44, 62, 47, 26, 27, 30, 43, 60, 59, 35, 2, 9, 48, 72, 69, 48, 23, 17, 24, 34, 59, 69, 33, 17, 60, 73, 14, 246, 43, 78, 66, 51, 30, 10, 23, 54, 64, 49, 38, 38, 32, 35, 52, 47, 30, 40, 59, 44, 21, 37, 54, 38, 36, 57, 44, 17, 44, 72, 37, 9, 42, 65, 45, 37, 44, 36, 29, 45, 55, 35, 25, 51, 61, 39, 27, 35, 40, 48, 60, 46, 19, 31, 57, 50, 38, 46, 46, 21, 21, 57, 72, 48, 26, 11, 17, 69, 88, 32, 252, 31, 60, 39, 34, 59, 56, 23, 15, 37, 42, 34, 55, 74, 42, 254, 9, 57, 67, 49, 36, 31, 28, 28, 43, 60, 56, 39, 23, 10, 25, 62, 74, 48, 22, 20, 27, 33, 48, 64, 58, 33, 14, 18, 40, 57, 57, 55, 34, 0, 9, 59, 74, 54, 37, 15, 254, 25, 74, 71, 26, 17, 49, 42, 4, 24, 73, 62, 23, 22, 34, 25, 26, 62, 69, 18, 0, 41, 57, 28, 23, 48, 43, 17, 28, 46, 33, 27, 36, 28, 29, 50, 45, 16, 15, 44, 53, 31, 20, 33, 38, 34, 40, 33, 11, 20, 49, 49, 29, 19, 26, 41, 42, 15, 0, 31, 58, 47, 31, 24, 10, 8, 36, 55, 41, 27, 21, 10, 9, 34, 57, 43, 18, 27, 36, 10, 2, 39, 51, 29, 28, 30, 10, 16, 46, 37, 5, 14, 43, 45, 26, 15, 23, 29, 25, 28, 38, 39, 27, 21, 24, 22, 15, 26, 46, 38, 15, 15, 28, 34, 29, 24, 21, 27, 36, 27, 16, 28, 40, 28, 11, 22, 48, 39, 5, 9, 40, 44, 30, 28, 27, 14, 12, 33, 54, 46, 21, 5, 8, 30, 50, 45, 27, 16, 18, 26, 37, 42, 31, 14, 18, 32, 24, 21, 48, 57, 27, 0, 4, 27, 50, 52, 26, 9, 23, 38, 27, 19, 30, 38, 35, 34, 28, 14, 13, 29, 45, 44, 31, 22, 20, 22, 26, 30, 35, 35, 25, 21, 30, 37, 33, 29, 27, 19, 23, 43, 46, 25, 15, 22, 24, 32, 48, 44, 18, 7, 25, 41, 33, 25, 34, 40, 26, 19, 31, 34, 26, 34, 41, 28, 18, 27, 36, 29, 29, 44, 42, 19, 14, 35, 43, 27, 23, 43, 45, 20, 16, 36, 45, 41, 42, 31, 15, 27, 49, 44, 27, 28, 37, 33, 34, 44, 37, 20, 26, 45, 47, 34, 31, 36, 37, 32, 33, 43, 46, 36, 31, 33, 32, 32, 42, 50, 43, 30, 27, 36, 46, 46, 37, 33, 32, 32, 43, 58, 53, 31, 22, 30, 41, 52, 56, 44, 31, 28, 30, 37, 53, 59, 42, 23, 27, 42, 51, 50, 42, 29, 26, 42, 58, 57, 42, 27, 24, 35, 50, 55, 47, 34, 32, 38, 41, 43, 47, 46, 37, 31, 36, 42, 43, 42, 47, 46, 33, 27, 41, 56, 49, 35, 34, 37, 38, 44, 51, 46, 37, 36, 37, 37, 40, 46, 46, 39, 30, 31, 41, 48, 45, 41, 38, 32, 31, 39, 46, 44, 41, 41, 38, 34, 35, 40, 43, 44, 44, 38, 31, 33, 41, 42, 40, 36, 39, 46, 42, 28, 31, 43, 42, 37, 42, 43, 36, 37, 41, 33, 29, 40, 44, 35, 34, 41, 39, 32, 31, 37, 42, 42, 36, 32, 33, 33, 34, 41, 45, 38, 30, 33, 37, 35, 34, 38, 40, 37, 33, 34, 38, 38, 37, 37, 36, 34, 34, 36, 36, 36, 35, 32, 30, 37, 47, 41, 26, 24, 33, 38, 41, 43, 36, 25, 27, 36, 40, 42, 39, 31, 25, 29, 35, 36, 38, 39, 33, 27, 31, 34, 33, 35, 36, 31, 28, 32, 34, 33, 36, 36, 30, 27, 33, 35, 32, 33, 32, 30, 29, 32, 34, 34, 34, 29, 23, 25, 32, 36, 34, 29, 27, 28, 27, 27, 31, 35, 31, 25, 22, 23, 26, 31, 33, 31, 29, 27, 22, 22, 29, 34, 33, 29, 25, 21, 25, 32, 34, 29, 27, 27, 26, 25, 25, 27, 29, 30, 28, 27, 26, 24, 23, 24, 28, 29, 27, 25, 24, 26, 28, 30, 29, 26, 25, 26, 29, 28, 24, 22, 27, 31, 30, 29, 29, 25, 22, 25, 29, 28, 29, 30, 27, 23, 24, 28, 29, 30, 30, 27, 23, 24, 27, 31, 33, 33, 27, 24, 26, 30, 31, 31, 32, 28, 24, 26, 31, 31, 30, 30, 28, 25, 27, 32, 31, 26, 26, 29, 29, 30, 32, 30, 27, 28, 30, 30, 29, 30, 32, 32, 29, 27, 28, 31, 34, 33, 28, 27, 28, 29, 29, 33, 34, 29, 27, 30, 31, 31, 32, 32, 29, 28, 30, 31, 32, 33, 31, 28, 28, 31, 32, 32, 32, 30, 27, 29, 33, 33, 32, 31, 31, 31, 32, 33, 32, 32, 35, 36, 33, 33, 34, 35, 33, 33, 35, 36, 34, 33, 33, 34, 34, 34, 34, 34, 33, 33, 33, 33, 34, 35, 35, 35, 34, 33, 33, 34, 35, 35, 35, 34, 35, 37, 37, 36, 35, 35, 36, 37, 39, 39, 38, 36, 36, 36, 38, 39, 37, 37, 38, 38, 37, 37, 38, 38, 38, 38, 38, 39, 38, 37, 38, 39, 38, 37, 38, 38, 37, 37, 38, 38, 38, 37, 37, 38, 39, 39, 38, 38, 39, 40, 39, 39, 39, 39, 39, 38, 39, 41, 41, 39, 37, 39, 40, 40, 40, 41, 40, 38, 39, 40, 40, 41, 42, 40, 38, 39, 39, 41, 41, 39, 38, 38, 40, 42, 40, 39, 39, 40, 40, 40, 0, 59, 11, 50, 0, 7, 251, 250, 9, 253, 8, 246, 253, 17, 225, 2, 33, 228, 2, 29, 239, 238, 19, 3, 255, 0, 249, 12, 254, 3, 7, 252, 250, 241, 17, 31, 231, 239, 24, 248, 234, 10, 12, 16, 253, 242, 4, 252, 6, 11, 238, 253, 254, 30, 19, 213, 253, 23, 235, 254, 20, 252, 17, 3, 232, 15, 245, 237, 33, 254, 225, 15, 25, 255, 246, 4, 252, 234, 13, 11, 235, 10, 27, 253, 242, 14, 243, 239, 14, 241, 22, 48, 245, 211, 236, 6, 8, 18, 11, 248, 234, 0, 18, 244, 251, 21, 245, 236, 5, 4, 24, 4, 229, 254, 17, 5, 244, 4, 19, 240, 246, 21, 10, 240, 2, 2, 229, 19, 14, 5, 7, 224, 244, 23, 9, 240, 252, 34, 253, 206, 8, 50, 235, 0, 25, 229, 4, 32, 237, 243, 12, 6, 16, 239, 236, 27, 254, 4, 254, 244, 28, 247, 253, 21, 244, 241, 9, 248, 13, 20, 236, 13, 10, 232, 244, 25, 4, 217, 12, 38, 254, 223, 224, 0, 43, 40, 243, 222, 238, 15, 27, 236, 239, 32, 20, 214, 225, 21, 29, 247, 241, 0, 11, 31, 248, 220, 7, 0, 21, 22, 217, 203, 39, 56, 222, 237, 20, 253, 4, 9, 238, 227, 9, 23, 11, 0, 242, 242, 242, 53, 4, 207, 45, 255, 228, 27, 255, 220, 12, 45, 250, 249, 244, 235, 8, 19, 8, 253, 18, 241, 212, 249, 40, 39, 244, 225, 248, 23, 12, 255, 8, 217, 0, 42, 251, 233, 22, 29, 215, 234, 19, 6, 253, 0, 19, 250, 238, 3, 3, 24, 35, 221, 209, 36, 21, 237, 10, 8, 250, 228, 6, 29, 10, 243, 227, 247, 0, 5, 29, 18, 216, 243, 46, 231, 252, 22, 244, 254, 249, 249, 255, 1, 250, 7, 14, 252, 29, 246, 189, 21, 33, 9, 13, 233, 246, 0, 243, 12, 30, 249, 221, 40, 20, 210, 252, 255, 1, 46, 25, 220, 237, 15, 13, 31, 233, 209, 30, 44, 219, 230, 29, 238, 253, 35, 255, 236, 251, 7, 253, 5, 254, 19, 48, 197, 189, 50, 11, 34, 29, 191, 4, 34, 236, 247, 242, 246, 35, 43, 231, 216, 7, 9, 37, 3, 190, 247, 64, 16, 216, 5, 243, 241, 59, 237, 197, 19, 56, 18, 207, 223, 253, 37, 45, 215, 206, 32, 51, 232, 224, 13, 26, 37, 229, 222, 251, 22, 43, 226, 219, 28, 251, 247, 13, 2, 0, 253, 3, 251, 240, 31, 25, 226, 232, 2, 25, 37, 254, 217, 234, 26, 21, 246, 232, 245, 18, 31, 247, 216, 15, 20, 231, 226, 16, 55, 250, 218, 12, 57, 216, 206, 81, 255, 199, 44, 51, 221, 198, 6, 248, 27, 58, 225, 215, 243, 27, 48, 239, 188, 47, 52, 186, 242, 45, 6, 0, 237, 203, 5, 85, 241, 190, 21, 15, 235, 49, 33, 167, 255, 98, 212, 241, 46, 194, 0, 48, 236, 9, 2, 222, 23, 35, 0, 232, 0, 25, 249, 9, 4, 227, 4, 37, 46, 240, 171, 233, 46, 11, 225, 19, 18, 228, 231, 248, 33, 28, 215, 241, 35, 241, 6, 69, 223, 151, 32, 72, 199, 19, 69, 188, 199, 35, 46, 243, 226, 34, 3, 200, 246, 46, 34, 255, 249, 231, 231, 41, 27, 211, 220, 24, 38, 24, 243, 0, 254, 205, 243, 56, 1, 254, 22, 226, 244, 12, 244, 247, 26, 54, 239, 222, 241, 3, 46, 28, 247, 204, 236, 32, 14, 245, 238, 30, 23, 252, 245, 210, 0, 34, 227, 244, 74, 7, 237, 4, 202, 243, 44, 36, 245, 249, 9, 241, 238, 232, 59, 55, 157, 197, 93, 60, 204, 250, 23, 177, 244, 82, 8, 1, 6, 199, 5, 35, 2, 6, 197, 234, 54, 9, 18, 6, 216, 229, 13, 25, 27, 255, 181, 252, 73, 253, 236, 236, 246, 51, 33, 234, 224, 10, 11, 248, 5, 0, 235, 24, 21, 234, 18, 0, 224, 31, 31, 199, 236, 46, 252, 234, 239, 5, 48, 246, 216, 24, 26, 226, 217, 249, 52, 52, 3, 241, 206, 207, 23, 39, 12, 255, 31, 247, 194, 22, 51, 0, 210, 201, 55, 90, 228, 187, 249, 14, 16, 22, 254, 246, 249, 226, 13, 31, 243, 253, 34, 0, 238, 7, 0, 241, 246, 238, 39, 56, 232, 210, 227, 253, 33, 28, 228, 214, 55, 56, 208, 213, 15, 252, 217, 222, 26, 103, 29, 197, 232, 251, 228, 0, 233, 29, 96, 245, 215, 0, 0, 245, 242, 34, 31, 24, 25, 202, 180, 254, 8, 35, 65, 216, 219, 48, 53, 252, 159, 205, 49, 81, 27, 209, 182, 224, 78, 31, 231, 4, 255, 30, 238, 200, 16, 2, 238, 10, 250, 30, 67, 220, 165, 4, 64, 38, 254, 214, 215, 33, 50, 254, 234, 204, 7, 61, 39, 242, 214, 16, 246, 218, 11, 20, 32, 30, 247, 179, 228, 97, 35, 196, 212, 16, 34, 3, 5, 5, 215, 225, 4, 16, 52, 27, 214, 245, 247, 239, 17, 24, 1, 239, 240, 34, 50, 233, 176, 239, 69, 48, 210, 203, 250, 54, 82, 209, 200, 41, 240, 243, 21, 242, 241, 24, 24, 2, 244, 4, 255, 238, 10, 7, 246, 23, 1, 250, 24, 237, 227, 19, 7, 9, 9, 233, 250, 0, 254, 23, 251, 4, 245, 208, 32, 60, 251, 198, 199, 40, 91, 11, 180, 213, 48, 22, 233, 240, 0, 249, 255, 36, 12, 243, 211, 226, 46, 48, 241, 243, 239, 207, 225, 38, 81, 23, 213, 239, 17, 39, 7, 220, 225, 249, 13, 0, 246, 33, 36, 248, 243, 0, 247, 248, 2, 20, 24, 4, 238, 229, 2, 240, 223, 28, 88, 27, 202, 211, 244, 6, 217, 13, 77, 223, 220, 43, 242, 231, 38, 1, 24, 29, 175, 213, 33, 2, 21, 28, 10, 241, 250, 4, 246, 236, 11, 31, 253, 25, 25, 207, 248, 14, 8, 32, 246, 202, 237, 8, 57, 34, 227, 199, 243, 12, 244, 42, 48, 242, 222, 221, 43, 34, 197, 200, 13, 72, 22, 244, 222, 189, 13, 34, 1, 37, 38, 194, 194, 47, 19, 250, 0, 179, 4, 125, 15, 171, 248, 3, 219, 50, 64, 199, 213, 77, 44, 244, 0, 168, 224, 91, 4, 222, 32, 40, 239, 248, 7, 249, 6, 10, 14, 16, 250, 5, 238, 224, 37, 25, 247, 246, 192, 230, 99, 69, 186, 201, 34, 13, 240, 242, 6, 20, 40, 8, 202, 253, 252, 223, 30, 28, 243, 254, 248, 4, 20, 230, 237, 249, 3, 36, 241, 193, 242, 36, 30, 1, 236, 244, 210, 226, 85, 78, 227, 203, 203, 250, 47, 5, 1, 51, 35, 246, 234, 194, 208, 30, 54, 42, 15, 211, 226, 21, 19, 246, 236, 6, 46, 18, 235, 206, 216, 27, 28, 43, 13, 195, 251, 12, 18, 23, 236, 5, 30, 230, 236, 18, 221, 231, 59, 50, 233, 200, 14, 62, 239, 220, 41, 240, 240, 39, 14, 222, 244, 48, 41, 244, 223, 242, 251, 216, 246, 62, 31, 224, 245, 25, 7, 220, 232, 4, 5, 19, 7, 231, 11, 10, 241, 1, 227, 237, 42, 44, 0, 230, 244, 239, 238, 30, 34, 19, 234, 196, 215, 23, 37, 14, 3, 214, 0, 36, 255, 192, 185, 50, 91, 43, 253, 218, 226, 244, 2, 250, 243, 41, 28, 243, 10, 9, 226, 245, 242, 246, 63, 33, 239, 21, 212, 202, 11, 37, 53, 32, 252, 229, 208, 243, 6, 252, 37, 59, 21, 233, 226, 211, 228, 33, 38, 247, 229, 7, 4, 243, 221, 224, 83, 74, 210, 198, 202, 5, 62, 27, 245, 232, 17, 3, 210, 25, 76, 241, 185, 29, 80, 236, 201, 228, 20, 78, 39, 240, 185, 200, 56, 76, 13, 237, 223, 200, 246, 48, 32, 251, 249, 13, 39, 14, 199, 171, 10, 79, 44, 241, 166, 181, 37, 66, 33, 242, 221, 233, 240, 252, 39, 20, 216, 2, 249, 2, 26, 194, 221, 52, 40, 18, 7, 243, 219, 227, 14, 26, 48, 21, 206, 241, 13, 217, 254, 43, 3, 0, 30, 241, 221, 5, 12, 20, 49, 28, 202, 178, 227, 13, 41, 51, 29, 0, 216, 208, 251, 34, 1, 237, 3, 2, 5, 4, 230, 240, 7, 42, 31, 246, 207, 213, 19, 6, 27, 82, 243, 194, 220, 10, 42, 32, 230, 208, 63, 60, 192, 239, 16, 251, 34, 47, 2, 229, 13, 4, 199, 3, 62, 47, 248, 190, 197, 253, 17, 37, 55, 231, 151, 37, 71, 194, 214, 42, 23, 0, 252, 252, 2, 10, 7, 9, 3, 242, 251, 241, 223, 248, 36, 61, 255, 187, 203, 246, 12, 22, 39, 0, 236, 253, 232, 11, 52, 8, 202, 199, 6, 68, 42, 241, 236, 5, 255, 0, 15, 249, 0, 243, 252, 60, 38, 215, 184, 231, 37, 66, 34, 229, 237, 17, 11, 244, 7, 16, 254, 253, 25, 0, 212, 251, 2, 222, 249, 30, 40, 1, 232, 240, 7, 1, 236, 242, 255, 5, 17, 4, 248, 0, 238, 250, 252, 244, 29, 24, 243, 212, 245, 22, 222, 6, 56, 245, 215, 3, 0, 1, 20, 240, 8, 14, 222, 42, 72, 223, 213, 234, 15, 33, 21, 11, 234, 12, 25, 247, 237, 6, 252, 5, 20, 237, 251, 18, 255, 17, 12, 4, 251, 214, 239, 21, 12, 41, 11, 180, 214, 52, 31, 238, 248, 2, 8, 29, 247, 216, 2, 40, 248, 240, 7, 243, 22, 18, 233, 246, 245, 238, 34, 52, 249, 252, 253, 221, 241, 1, 26, 35, 229, 218, 10, 41, 22, 235, 1, 14, 237, 233, 252, 252, 0, 18, 22, 24, 5, 246, 245, 245, 219, 254, 53, 14, 249, 11, 1, 225, 245, 255, 2, 20, 37, 255, 214, 224, 16, 22, 249, 234, 224, 253, 17, 250, 3, 249, 227, 233, 255, 54, 44, 225, 209, 209, 232, 60, 95, 239, 172, 222, 31, 27, 252, 12, 0, 252, 32, 37, 35, 224, 180, 246, 55, 47, 11, 231, 213, 2, 28, 3, 37, 23, 231, 192, 232, 41, 17, 242, 247, 253, 25, 39, 236, 212, 244, 18, 45, 244, 245, 1, 221, 8, 28, 252, 253, 13, 230, 216, 14, 23, 35, 33, 243, 5, 11, 245, 230, 241, 29, 24, 0, 12, 16, 0, 11, 8, 254, 2, 246, 234, 243, 250, 33, 44, 0, 217, 214, 238, 15, 50, 11, 215, 211, 6, 28, 254, 2, 234, 219, 23, 24, 37, 25, 218, 243, 255, 233, 246, 25, 13, 251, 28, 11, 14, 33, 223, 174, 0, 60, 0, 240, 248, 232, 254, 18, 21, 29, 26, 208, 187, 13, 11, 50, 48, 215, 223, 252, 251, 253, 41, 64, 26, 220, 200, 1, 238, 234, 30, 48, 59, 242, 206, 223, 189, 255, 83, 50, 249, 218, 197, 227, 29, 23, 0, 250, 236, 236, 9, 36, 231, 203, 21, 33, 251, 249, 219, 221, 243, 51, 33, 243, 240, 223, 21, 15, 0, 51, 252, 191, 17, 68, 32, 242, 238, 232, 225, 32, 62, 6, 206, 1, 29, 233, 221, 248, 20, 32, 57, 46, 227, 202, 215, 235, 25, 59, 47, 244, 203, 0, 33, 4, 4, 8, 235, 208, 231, 20, 36, 19, 253, 1, 241, 228, 0, 21, 12, 246, 248, 0, 47, 10, 214, 229, 215, 12, 55, 27, 243, 200, 236, 32, 52, 47, 5, 213, 212, 227, 252, 37, 69, 31, 246, 225, 231, 6, 32, 49, 205, 190, 21, 238, 210, 243, 5, 12, 27, 55, 253, 169, 195, 239, 19, 11, 45, 63, 219, 192, 4, 255, 246, 27, 11, 249, 38, 52, 38, 14, 237, 235, 234, 11, 64, 36, 8, 255, 237, 251, 13, 244, 229, 246, 31, 49, 35, 230, 178, 201, 240, 16, 34, 37, 246, 201, 233, 212, 212, 35, 60, 39, 252, 186, 178, 253, 41, 45, 67, 12, 228, 226, 195, 211, 52, 104, 46, 225, 238, 244, 248, 21, 237, 232, 59, 69, 15, 191, 169, 251, 50, 67, 33, 253, 232, 212, 236, 245, 254, 26, 14, 252, 242, 245, 221, 193, 246, 31, 60, 77, 16, 170, 160, 240, 57, 64, 19, 225, 220, 219, 7, 44, 238, 251, 53, 3, 226, 5, 244, 234, 11, 35, 38, 0, 251, 3, 251, 11, 17, 8, 251, 241, 240, 8, 20, 251, 0, 238, 248, 43, 0, 234, 4, 243, 251, 29, 250, 242, 52, 44, 229, 207, 250, 11, 7, 49, 30, 232, 8, 251, 215, 211, 228, 31, 46, 39, 253, 196, 185, 253, 51, 4, 253, 14, 240, 242, 3, 253, 236, 249, 16, 22, 22, 4, 254, 0, 252, 248, 238, 249, 243, 252, 27, 8, 222, 235, 22, 12, 242, 229, 232, 14, 44, 26, 246, 240, 254, 13, 7, 236, 249, 38, 20, 10, 33, 220, 198, 7, 24, 31, 10, 251, 2, 227, 236, 24, 44, 1, 215, 250, 5, 34, 28, 237, 1, 48, 44, 213, 167, 212, 2, 48, 70, 28, 219, 192, 214, 42, 68, 236, 236, 9, 252, 237, 242, 11, 29, 14, 234, 213, 219, 232, 20, 57, 32, 246, 194, 196, 239, 26, 53, 35, 28, 246, 228, 241, 3, 50, 33, 19, 34, 14, 234, 218, 245, 9, 26, 44, 16, 239, 240, 214, 228, 34, 41, 8, 244, 214, 222, 4, 255, 16, 36, 248, 211, 204, 249, 22, 19, 14, 237, 224, 235, 248, 233, 241, 41, 84, 35, 204, 213, 15, 2, 236, 5, 30, 37, 246, 193, 220, 23, 65, 66, 8, 223, 224, 210, 205, 23, 68, 43, 20, 235, 230, 240, 3, 18, 4, 21, 30, 254, 248, 10, 3, 253, 10, 23, 26, 245, 240, 4, 217, 207, 6, 28, 7, 253, 226, 197, 1, 41, 13, 248, 212, 224, 242, 247, 25, 45, 39, 226, 225, 18, 19, 25, 9, 220, 7, 67, 43, 243, 193, 197, 14, 94, 77, 8, 227, 216, 252, 14, 2, 8, 28, 5, 170, 178, 20, 57, 32, 204, 164, 218, 37, 60, 34, 230, 217, 1, 244, 240, 16, 16, 0, 237, 1, 35, 252, 232, 228, 227, 40, 50, 9, 221, 200, 7, 84, 73, 26, 244, 174, 182, 39, 81, 49, 17, 194, 183, 0, 28, 45, 27, 227, 230, 2, 12, 251, 244, 248, 218, 10, 25, 3, 22, 238, 233, 246, 233, 36, 60, 13, 247, 2, 12, 0, 21, 7, 224, 18, 58, 36, 243, 191, 207, 238, 18, 32, 28, 33, 3, 238, 251, 14, 251, 217, 239, 3, 3, 33, 6, 218, 227, 251, 36, 40, 245, 207, 194, 218, 25, 54, 10, 233, 3, 249, 231, 4, 35, 12, 240, 238, 4, 15, 244, 239, 16, 9, 18, 15, 224, 251, 18, 12, 247, 1, 17, 253, 254, 254, 7, 245, 4, 52, 7, 202, 226, 6, 14, 17, 22, 242, 214, 3, 33, 21, 19, 228, 199, 252, 38, 65, 44, 214, 187, 232, 11, 37, 61, 22, 197, 179, 227, 17, 34, 31, 12, 244, 1, 245, 222, 250, 252, 8, 28, 14, 248, 234, 235, 225, 252, 40, 43, 10, 227, 229, 1, 26, 41, 23, 233, 203, 222, 248, 47, 74, 16, 237, 216, 235, 29, 27, 251, 2, 250, 220, 236, 6, 0, 9, 49, 56, 15, 218, 197, 210, 249, 46, 46, 16, 251, 225, 225, 2, 13, 11, 32, 253, 211, 247, 12, 240, 251, 14, 243, 13, 49, 12, 218, 226, 243, 2, 30, 49, 22, 249, 232, 228, 1, 18, 5, 248, 255, 7, 12, 16, 16, 246, 230, 3, 23, 19, 0, 235, 233, 14, 49, 17, 254, 235, 205, 249, 12, 35, 16, 215, 218, 3, 30, 245, 218, 223, 222, 248, 31, 41, 17, 237, 227, 243, 248, 249, 7, 11, 16, 36, 9, 244, 8, 8, 247, 255, 39, 36, 240, 220, 245, 20, 41, 17, 243, 254, 13, 15, 13, 250, 230, 238, 252, 11, 15, 9, 1, 11, 22, 253, 223, 232, 8, 0, 255, 6, 248, 230, 236, 0, 1, 13, 19, 255, 242, 227, 230, 3, 18, 250, 241, 238, 241, 9, 21, 23, 16, 13, 250, 222, 231, 4, 31, 37, 21, 254, 244, 227, 230, 2, 22, 32, 23, 253, 228, 216, 248, 37, 56, 29, 251, 214, 209, 243, 13, 39, 42, 247, 236, 239, 240, 18, 246, 254, 31, 246, 235, 3, 245, 250, 10, 13, 22, 20, 11, 239, 228, 227, 4, 17, 6, 17, 16, 0, 236, 12, 33, 250, 254, 247, 241, 14, 249, 249, 12, 4, 2, 6, 243, 228, 254, 16, 10, 12, 14, 4, 246, 245, 252, 245, 6, 19, 3, 15, 5, 248, 250, 247, 2, 255, 0, 12, 1, 240, 228, 247, 20, 30, 4, 231, 235, 251, 253, 231, 240, 35, 34, 254, 254, 248, 226, 240, 248, 14, 31, 4, 245, 254, 251, 9, 17, 12, 22, 4, 227, 222, 5, 29, 16, 245, 239, 24, 8, 246, 14, 13, 244, 228, 238, 5, 29, 18, 5, 249, 229, 250, 3, 15, 15, 247, 241, 237, 248, 18, 2, 3, 10, 253, 7, 2, 232, 237, 0, 116, 8, 28, 0, 1, 1, 1, 0, 1, 3, 2, 255, 252, 252, 255, 3, 7, 8, 5, 0, 253, 253, 255, 0, 3, 3, 2, 0, 254, 1, 4, 4, 2, 0, 255, 0, 0, 0, 0, 0, 3, 5, 4, 0, 253, 249, 250, 253, 0, 0, 254, 253, 254, 1, 8, 10, 5, 255, 244, 238, 239, 246, 245, 231, 228, 234, 249, 20, 41, 42, 24, 1, 239, 232, 245, 9, 24, 27, 17, 1, 247, 247, 254, 5, 9, 8, 5, 2, 1, 1, 1, 3, 7, 8, 5, 0, 252, 250, 250, 253, 1, 6, 8, 6, 4, 0, 255, 255, 0, 0, 0, 254, 253, 254, 255, 0, 1, 4, 7, 6, 2, 255, 251, 249, 252, 2, 7, 7, 8, 9, 11, 14, 15, 5, 240, 223, 215, 197, 189, 207, 232, 6, 33, 41, 31, 15, 4, 253, 254, 4, 12, 21, 21, 15, 8, 254, 248, 249, 255, 2, 1, 0, 3, 3, 0, 254, 0, 3, 6, 9, 9, 6, 6, 7, 2, 0, 2, 255, 254, 255, 251, 253, 1, 2, 1, 0, 1, 1, 0, 0, 253, 252, 253, 0, 7, 2, 255, 0, 255, 255, 0, 0, 254, 249, 248, 247, 253, 4, 254, 0, 2, 245, 240, 250, 251, 246, 0, 6, 0, 4, 10, 3, 1, 6, 3, 4, 5, 7, 8, 12, 2, 252, 0, 2, 0, 9, 7, 255, 6, 12, 254, 254, 9, 251, 241, 6, 13, 247, 253, 8, 249, 254, 10, 2, 1, 1, 251, 252, 4, 251, 254, 12, 255, 238, 0, 3, 249, 0, 14, 8, 246, 0, 4, 246, 255, 1, 253, 5, 3, 252, 252, 255, 250, 1, 9, 0, 0, 6, 252, 249, 1, 4, 10, 2, 0, 5, 242, 253, 15, 255, 252, 9, 255, 244, 4, 11, 0, 4, 5, 251, 253, 250, 0, 9, 255, 253, 7, 255, 242, 254, 4, 248, 12, 17, 245, 253, 0, 246, 8, 9, 249, 6, 3, 244, 253, 4, 248, 4, 10, 253, 0, 7, 2, 4, 254, 0, 254, 252, 254, 251, 252, 9, 6, 13, 6, 247, 252, 5, 250, 6, 4, 251, 2, 2, 252, 5, 4, 0, 3, 252, 250, 255, 253, 4, 14, 0, 244, 2, 254, 253, 11, 3, 0, 6, 250, 240, 0, 5, 0, 9, 6, 252, 0, 248, 245, 6, 10, 6, 2, 252, 4, 250, 253, 5, 7, 6, 0, 255, 5, 252, 252, 0, 3, 2, 252, 255, 5, 248, 0, 5, 245, 251, 17, 6, 0, 9, 249, 248, 3, 2, 0, 6, 6, 248, 240, 0, 254, 248, 14, 12, 5, 9, 253, 1, 4, 242, 5, 11, 246, 6, 11, 250, 3, 1, 1, 255, 238, 2, 0, 237, 12, 14, 243, 7, 10, 249, 9, 12, 246, 3, 2, 242, 1, 12, 250, 254, 11, 2, 248, 0, 248, 244, 4, 246, 252, 16, 0, 10, 13, 231, 253, 10, 246, 4, 25, 1, 249, 3, 0, 244, 1, 12, 6, 4, 6, 0, 250, 248, 252, 255, 2, 1, 10, 0, 245, 254, 8, 1, 0, 11, 1, 241, 1, 0, 243, 15, 15, 240, 11, 11, 231, 1, 16, 250, 8, 11, 246, 250, 252, 250, 0, 6, 7, 2, 16, 0, 240, 4, 248, 234, 20, 6, 237, 13, 8, 235, 5, 12, 0, 2, 0, 252, 10, 252, 254, 0, 248, 255, 0, 255, 0, 248, 7, 10, 255, 11, 1, 245, 9, 5, 248, 3, 2, 248, 1, 9, 4, 7, 255, 1, 13, 249, 247, 9, 248, 245, 15, 8, 4, 14, 247, 246, 11, 246, 242, 19, 0, 245, 16, 251, 239, 16, 246, 233, 24, 6, 237, 17, 252, 235, 13, 0, 246, 26, 4, 249, 28, 254, 225, 4, 250, 239, 14, 254, 251, 15, 11, 0, 255, 249, 254, 255, 0, 253, 12, 17, 254, 249, 247, 249, 10, 10, 0, 4, 3, 252, 0, 250, 240, 9, 12, 248, 10, 12, 246, 2, 255, 246, 11, 2, 247, 18, 11, 241, 4, 2, 233, 10, 15, 243, 0, 2, 247, 3, 254, 254, 19, 8, 251, 0, 252, 240, 243, 4, 4, 9, 19, 0, 248, 10, 239, 239, 18, 252, 1, 22, 248, 247, 14, 251, 2, 9, 241, 253, 4, 243, 5, 13, 0, 5, 255, 253, 1, 254, 4, 244, 246, 27, 255, 252, 22, 250, 234, 6, 7, 251, 3, 15, 250, 248, 7, 240, 232, 19, 12, 253, 27, 6, 227, 6, 255, 234, 15, 16, 0, 13, 2, 246, 0, 7, 249, 241, 7, 7, 247, 18, 2, 245, 19, 255, 230, 10, 245, 249, 34, 7, 247, 28, 249, 223, 2, 2, 250, 13, 13, 249, 249, 245, 3, 13, 255, 251, 5, 241, 246, 19, 2, 251, 16, 249, 235, 12, 8, 250, 7, 254, 238, 0, 12, 3, 248, 11, 11, 251, 20, 0, 230, 22, 7, 249, 10, 239, 242, 21, 243, 250, 24, 252, 244, 11, 249, 250, 8, 9, 2, 247, 250, 0, 251, 12, 8, 253, 11, 6, 249, 254, 255, 0, 247, 252, 15, 0, 242, 10, 10, 254, 245, 250, 6, 253, 250, 21, 255, 241, 0, 1, 255, 247, 2, 27, 241, 247, 25, 255, 236, 3, 237, 244, 13, 10, 15, 19, 3, 11, 250, 233, 11, 15, 247, 8, 4, 239, 13, 0, 235, 10, 12, 241, 254, 3, 246, 24, 22, 243, 10, 244, 214, 6, 6, 254, 39, 12, 239, 4, 6, 241, 248, 16, 253, 251, 18, 241, 238, 31, 238, 217, 41, 8, 215, 35, 20, 216, 17, 18, 225, 9, 7, 236, 12, 7, 238, 4, 255, 255, 20, 241, 252, 31, 0, 243, 20, 8, 238, 6, 1, 6, 252, 234, 18, 18, 235, 14, 250, 242, 14, 252, 249, 26, 251, 233, 253, 13, 251, 232, 22, 33, 242, 250, 30, 239, 225, 16, 2, 217, 26, 31, 232, 251, 27, 248, 247, 6, 255, 4, 4, 243, 9, 8, 243, 3, 0, 9, 13, 226, 12, 5, 218, 40, 38, 230, 26, 242, 233, 13, 233, 248, 41, 236, 245, 31, 234, 245, 19, 233, 2, 17, 231, 4, 11, 230, 254, 13, 247, 16, 20, 7, 8, 246, 240, 0, 243, 8, 36, 2, 229, 22, 15, 229, 13, 6, 245, 4, 0, 243, 244, 9, 26, 232, 14, 45, 217, 245, 34, 212, 255, 51, 235, 235, 50, 245, 248, 36, 228, 220, 18, 238, 250, 27, 244, 238, 12, 245, 248, 14, 254, 254, 25, 6, 248, 7, 238, 254, 27, 2, 249, 6, 235, 9, 7, 11, 5, 248, 252, 253, 230, 249, 24, 3, 240, 42, 23, 233, 10, 254, 219, 3, 0, 233, 18, 18, 235, 3, 29, 0, 234, 247, 247, 252, 254, 11, 21, 0, 253, 253, 237, 11, 42, 237, 252, 29, 232, 225, 21, 254, 7, 8, 219, 249, 39, 231, 22, 47, 219, 6, 41, 225, 9, 11, 221, 3, 19, 250, 1, 9, 240, 252, 4, 255, 11, 239, 254, 23, 254, 237, 22, 253, 245, 19, 247, 237, 14, 245, 244, 21, 5, 244, 1, 1, 6, 251, 253, 37, 7, 230, 37, 17, 207, 6, 31, 229, 242, 28, 251, 234, 13, 244, 250, 24, 249, 3, 13, 214, 18, 47, 242, 12, 3, 245, 44, 7, 224, 43, 255, 223, 45, 245, 233, 22, 252, 255, 255, 203, 245, 221, 170, 235, 244, 185, 26, 35, 218, 12, 20, 237, 40, 35, 238, 43, 32, 236, 46, 20, 220, 62, 253, 205, 55, 6, 197, 57, 251, 209, 49, 23, 225, 43, 244, 227, 23, 20, 244, 0, 18, 12, 221, 245, 47, 234, 243, 48, 249, 193, 37, 13, 210, 11, 34, 254, 10, 244, 25, 4, 215, 13, 17, 201, 22, 7, 187, 38, 30, 204, 40, 12, 212, 9, 242, 230, 21, 220, 0, 45, 229, 236, 25, 249, 17, 23, 253, 10, 254, 24, 242, 239, 17, 240, 230, 41, 5, 216, 19, 29, 222, 11, 62, 219, 202, 48, 245, 216, 44, 21, 213, 21, 1, 229, 253, 11, 0, 8, 233, 19, 9, 252, 254, 252, 16, 40, 241, 251, 13, 230, 249, 17, 2, 0, 9, 19, 3, 238, 15, 241, 251, 24, 248, 4, 4, 231, 235, 245, 7, 37, 14, 253, 14, 3, 221, 0, 233, 245, 25, 4, 3, 67, 225, 220, 55, 231, 194, 74, 230, 203, 79, 237, 180, 76, 232, 231, 116, 223, 210, 46, 174, 240, 68, 180, 34, 50, 185, 40, 39, 162, 23, 38, 217, 29, 41, 200, 28, 28, 200, 11, 38, 194, 16, 45, 244, 4, 13, 231, 6, 7, 211, 35, 19, 217, 0, 14, 240, 15, 14, 12, 254, 250, 24, 245, 252, 32, 224, 0, 44, 204, 13, 21, 223, 37, 248, 194, 77, 6, 179, 56, 20, 171, 37, 22, 184, 47, 22, 226, 56, 231, 204, 78, 231, 199, 69, 235, 210, 63, 229, 228, 82, 221, 215, 85, 191, 216, 86, 229, 225, 90, 220, 209, 51, 246, 211, 59, 12, 222, 47, 249, 179, 63, 21, 160, 89, 23, 159, 66, 27, 130, 31, 55, 192, 12, 60, 209, 3, 56, 232, 247, 42, 243, 226, 33, 243, 198, 23, 9, 216, 36, 16, 201, 251, 25, 255, 245, 18, 22, 250, 8, 19, 210, 17, 9, 237, 50, 11, 201, 45, 8, 207, 36, 251, 239, 37, 238, 215, 49, 1, 222, 56, 26, 210, 251, 245, 236, 34, 19, 238, 1, 25, 205, 236, 50, 243, 216, 46, 14, 219, 12, 1, 220, 37, 31, 215, 23, 5, 224, 15, 17, 248, 24, 218, 236, 36, 210, 32, 44, 182, 24, 92, 168, 243, 73, 212, 241, 60, 226, 237, 43, 212, 250, 36, 252, 254, 29, 220, 18, 4, 218, 11, 17, 224, 68, 35, 166, 19, 7, 191, 49, 42, 220, 32, 246, 246, 16, 200, 21, 79, 208, 16, 59, 150, 233, 49, 212, 16, 52, 232, 253, 19, 210, 228, 0, 7, 10, 22, 23, 249, 214, 37, 251, 199, 20, 41, 224, 36, 27, 185, 2, 25, 208, 33, 52, 207, 15, 28, 218, 18, 17, 238, 48, 16, 200, 17, 253, 213, 41, 29, 223, 4, 0, 0, 29, 247, 230, 5, 242, 248, 31, 17, 235, 244, 239, 27, 11, 245, 27, 239, 226, 58, 9, 206, 19, 244, 239, 76, 253, 210, 20, 254, 254, 25, 237, 249, 41, 12, 228, 249, 253, 236, 2, 40, 18, 210, 247, 12, 243, 239, 232, 246, 13, 240, 37, 27, 213, 23, 41, 196, 247, 46, 233, 237, 25, 0, 242, 6, 238, 0, 31, 4, 249, 9, 254, 238, 248, 25, 26, 237, 244, 21, 238, 242, 32, 251, 225, 5, 255, 221, 14, 19, 244, 18, 7, 13, 22, 243, 253, 236, 246, 35, 15, 243, 25, 2, 243, 18, 15, 247, 22, 248, 237, 35, 0, 231, 8, 246, 245, 14, 246, 5, 3, 231, 16, 232, 228, 19, 253, 245, 34, 251, 250, 30, 240, 231, 33, 251, 240, 13, 228, 247, 33, 223, 3, 44, 248, 253, 10, 252, 7, 30, 33, 0, 3, 14, 7, 249, 246, 0, 247, 241, 23, 11, 253, 1, 229, 230, 16, 248, 234, 11, 222, 224, 38, 0, 217, 31, 0, 206, 47, 5, 206, 54, 20, 207, 32, 18, 204, 19, 67, 209, 237, 49, 209, 228, 60, 217, 229, 66, 241, 214, 50, 9, 224, 38, 3, 215, 31, 10, 231, 36, 5, 223, 14, 24, 220, 2, 39, 210, 215, 58, 239, 204, 51, 254, 201, 33, 0, 203, 30, 28, 222, 18, 38, 211, 236, 47, 220, 241, 40, 253, 237, 47, 43, 214, 6, 53, 240, 0, 47, 252, 0, 42, 20, 244, 9, 6, 244, 4, 19, 3, 252, 7, 4, 226, 245, 24, 244, 253, 37, 245, 225, 20, 242, 223, 11, 8, 241, 21, 21, 233, 0, 12, 221, 254, 13, 221, 0, 8, 211, 243, 249, 242, 251, 0, 228, 241, 250, 236, 11, 7, 243, 16, 1, 250, 7, 253, 247, 8, 1, 247, 20, 6, 218, 12, 27, 249, 11, 29, 249, 6, 7, 255, 16, 255, 6, 40, 6, 2, 30, 10, 249, 251, 6, 244, 239, 2, 2, 253, 10, 22, 253, 6, 25, 252, 247, 28, 1, 233, 2, 251, 227, 1, 15, 228, 244, 8, 234, 249, 22, 255, 252, 9, 3, 239, 0, 11, 5, 246, 0, 5, 253, 8, 3, 250, 242, 4, 5, 235, 243, 15, 245, 247, 8, 244, 246, 8, 4, 251, 13, 254, 255, 11, 12, 9, 14, 28, 12, 255, 13, 6, 250, 3, 11, 4, 10, 23, 0, 236, 1, 15, 251, 4, 11, 250, 255, 4, 247, 249, 8, 253, 253, 12, 255, 237, 251, 3, 246, 248, 245, 238, 250, 3, 254, 8, 5, 1, 252, 1, 253, 241, 7, 15, 237, 240, 0, 232, 248, 15, 248, 237, 242, 232, 247, 254, 242, 250, 250, 252, 1, 0, 251, 5, 251, 2, 11, 232, 11, 45, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 17, 17, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 17, 17, 17, 17, 18, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 16, 16, 16, 16, 16, 17, 17, 17, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 15, 15, 15, 15, 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 14, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 9, 9, 9, 10, 10, 10, 10, 9, 9, 9, 10, 10, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 15, 15, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 16, 16, 16, 16, 17, 17, 16, 16, 17, 17, 17, 17, 16, 16, 16, 16, 17, 17, 16, 17, 17, 17, 17, 17, 16, 17, 17, 17, 17, 17, 17, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 16, 15, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 11, 9, 3, 0, 0, 12, 42, 58, 34, 0, 250, 6, 11, 11, 14, 16, 14, 14, 19, 23, 24, 20, 14, 10, 10, 11, 13, 17, 22, 23, 20, 15, 13, 15, 17, 18, 18, 16, 13, 12, 14, 19, 22, 23, 21, 17, 14, 12, 13, 17, 20, 21, 21, 19, 17, 16, 16, 17, 17, 18, 19, 20, 19, 17, 17, 19, 19, 17, 17, 17, 17, 18, 19, 19, 19, 17, 16, 15, 16, 17, 19, 20, 20, 18, 17, 16, 17, 17, 17, 17, 18, 19, 18, 17, 16, 17, 17, 18, 18, 17, 16, 16, 17, 17, 17, 18, 18, 19, 19, 18, 17, 15, 17, 18, 16, 16, 19, 20, 17, 16, 18, 18, 17, 16, 17, 18, 18, 17, 17, 17, 18, 18, 17, 16, 17, 17, 17, 16, 17, 18, 17, 17, 18, 18, 18, 16, 16, 14, 8, 249, 229, 213, 226, 37, 119, 127, 62, 10, 0, 241, 208, 200, 228, 1, 13, 22, 44, 70, 85, 77, 49, 14, 239, 221, 226, 248, 11, 13, 5, 5, 20, 35, 46, 55, 61, 51, 13, 214, 182, 207, 7, 48, 60, 61, 55, 37, 12, 254, 0, 3, 0, 253, 3, 17, 30, 42, 46, 36, 16, 255, 243, 246, 10, 29, 26, 16, 15, 9, 247, 227, 214, 223, 9, 67, 95, 76, 37, 8, 0, 1, 0, 255, 249, 238, 245, 24, 54, 52, 41, 38, 18, 239, 227, 250, 22, 32, 33, 32, 23, 6, 0, 14, 26, 12, 250, 251, 5, 13, 24, 31, 28, 21, 17, 11, 1, 0, 0, 3, 15, 25, 17, 7, 13, 29, 34, 14, 243, 244, 14, 24, 6, 252, 5, 24, 34, 22, 10, 14, 15, 0, 253, 18, 22, 1, 253, 14, 20, 13, 10, 12, 21, 25, 11, 254, 6, 19, 16, 6, 6, 8, 10, 21, 29, 17, 254, 249, 6, 29, 36, 12, 251, 4, 13, 8, 16, 27, 19, 10, 7, 0, 7, 32, 30, 251, 240, 14, 36, 20, 11, 22, 15, 0, 2, 10, 20, 29, 10, 239, 3, 45, 35, 251, 2, 39, 29, 243, 233, 8, 47, 42, 5, 249, 10, 23, 19, 12, 6, 9, 17, 20, 13, 3, 9, 28, 33, 12, 240, 239, 11, 44, 48, 23, 0, 247, 247, 5, 31, 43, 28, 6, 0, 6, 6, 3, 13, 20, 15, 13, 20, 21, 11, 8, 22, 22, 250, 243, 14, 26, 17, 26, 42, 19, 237, 240, 30, 45, 2, 240, 19, 35, 10, 8, 30, 25, 7, 13, 19, 253, 237, 11, 57, 52, 2, 233, 4, 34, 23, 8, 18, 25, 8, 1, 20, 32, 21, 8, 8, 10, 9, 6, 16, 42, 48, 16, 241, 244, 18, 44, 39, 18, 4, 247, 244, 20, 63, 44, 248, 249, 28, 28, 8, 7, 15, 20, 27, 17, 3, 14, 31, 19, 250, 248, 9, 16, 252, 221, 216, 242, 20, 55, 92, 103, 60, 3, 241, 250, 244, 228, 252, 47, 54, 11, 8, 68, 92, 33, 216, 200, 251, 45, 30, 9, 55, 79, 9, 225, 18, 41, 10, 13, 39, 26, 247, 225, 251, 61, 76, 22, 4, 34, 31, 1, 246, 252, 12, 33, 47, 37, 0, 239, 26, 60, 20, 244, 24, 43, 0, 237, 21, 56, 33, 251, 241, 9, 58, 67, 13, 242, 13, 14, 246, 12, 38, 18, 8, 24, 28, 23, 17, 14, 26, 22, 246, 248, 27, 33, 25, 32, 11, 239, 8, 50, 35, 255, 249, 17, 40, 29, 2, 5, 34, 19, 234, 6, 69, 43, 241, 251, 21, 37, 51, 16, 207, 211, 32, 90, 74, 14, 230, 237, 17, 44, 41, 9, 236, 253, 35, 36, 19, 21, 13, 13, 50, 38, 212, 204, 50, 94, 18, 228, 5, 34, 32, 22, 2, 253, 19, 17, 249, 19, 64, 47, 1, 236, 239, 15, 44, 24, 253, 21, 40, 3, 239, 11, 41, 39, 31, 12, 229, 222, 3, 41, 46, 33, 12, 4, 26, 27, 242, 220, 8, 59, 41, 252, 252, 10, 4, 11, 41, 38, 252, 234, 14, 48, 20, 236, 235, 22, 60, 34, 228, 238, 55, 67, 4, 205, 208, 18, 85, 66, 253, 228, 240, 2, 39, 53, 20, 0, 253, 232, 245, 48, 50, 248, 235, 26, 64, 31, 209, 194, 39, 106, 18, 191, 238, 56, 47, 253, 243, 24, 32, 246, 249, 43, 33, 242, 252, 17, 0, 8, 41, 32, 254, 245, 0, 3, 12, 36, 47, 18, 232, 232, 24, 50, 7, 225, 248, 35, 45, 31, 0, 215, 239, 64, 80, 0, 210, 241, 20, 26, 28, 15, 250, 0, 32, 43, 13, 246, 244, 2, 17, 16, 10, 24, 27, 245, 251, 42, 33, 252, 254, 250, 246, 30, 47, 10, 2, 20, 5, 243, 10, 37, 28, 10, 252, 240, 254, 31, 54, 33, 240, 214, 254, 67, 70, 242, 200, 7, 46, 15, 19, 36, 253, 228, 15, 34, 11, 12, 19, 3, 13, 36, 7, 237, 14, 28, 254, 5, 37, 14, 249, 26, 37, 247, 232, 23, 47, 13, 243, 253, 12, 24, 52, 48, 253, 235, 5, 8, 245, 5, 41, 46, 16, 2, 21, 22, 241, 221, 20, 88, 59, 216, 193, 34, 98, 30, 225, 254, 10, 248, 32, 85, 37, 217, 230, 26, 30, 14, 28, 38, 24, 255, 240, 5, 40, 24, 242, 18, 75, 50, 242, 227, 242, 13, 56, 59, 11, 242, 253, 17, 40, 39, 11, 250, 253, 15, 50, 56, 3, 222, 0, 41, 26, 19, 41, 24, 233, 244, 47, 45, 0, 1, 37, 30, 3, 7, 23, 24, 9, 2, 9, 16, 34, 54, 38, 254, 237, 245, 0, 27, 61, 55, 9, 246, 10, 14, 2, 19, 44, 33, 252, 237, 16, 69, 54, 238, 225, 30, 58, 25, 252, 238, 244, 50, 97, 26, 201, 231, 37, 43, 48, 41, 241, 233, 35, 37, 254, 26, 59, 1, 207, 249, 44, 63, 68, 30, 222, 213, 1, 37, 53, 44, 1, 240, 27, 43, 0, 1, 45, 28, 236, 248, 26, 28, 24, 23, 16, 27, 35, 6, 243, 5, 21, 25, 29, 21, 9, 12, 13, 9, 26, 40, 17, 235, 235, 29, 78, 61, 254, 225, 240, 6, 38, 55, 24, 251, 6, 23, 21, 25, 24, 3, 253, 15, 24, 25, 23, 11, 11, 29, 27, 13, 9, 254, 255, 33, 54, 21, 245, 3, 31, 25, 0, 255, 27, 48, 20, 238, 244, 31, 52, 30, 246, 234, 13, 45, 33, 4, 1, 15, 26, 21, 0, 244, 7, 46, 47, 6, 239, 3, 24, 11, 8, 30, 26, 250, 251, 17, 31, 37, 9, 225, 250, 47, 36, 0, 1, 19, 17, 1, 3, 19, 18, 5, 19, 28, 253, 240, 10, 26, 21, 25, 19, 0, 250, 3, 18, 25, 24, 12, 255, 252, 16, 38, 7, 226, 10, 83, 51, 215, 199, 5, 56, 48, 7, 238, 2, 26, 13, 0, 24, 35, 4, 247, 12, 12, 254, 10, 21, 9, 2, 13, 29, 32, 12, 242, 254, 27, 18, 243, 239, 16, 54, 50, 10, 242, 253, 8, 3, 14, 38, 22, 242, 244, 12, 35, 47, 20, 230, 241, 30, 22, 4, 36, 41, 234, 214, 22, 58, 26, 254, 253, 13, 32, 30, 3, 247, 6, 16, 9, 18, 41, 27, 243, 242, 22, 44, 22, 3, 6, 253, 248, 29, 55, 14, 241, 12, 38, 18, 251, 8, 35, 23, 239, 231, 18, 60, 48, 12, 6, 250, 215, 246, 83, 94, 3, 210, 225, 243, 26, 85, 73, 250, 206, 238, 38, 64, 29, 226, 222, 32, 84, 34, 203, 218, 63, 74, 236, 209, 25, 66, 36, 4, 248, 237, 241, 15, 57, 61, 6, 222, 249, 47, 54, 5, 224, 247, 35, 40, 12, 5, 19, 5, 247, 27, 64, 25, 226, 238, 31, 42, 22, 4, 247, 252, 28, 49, 46, 28, 247, 221, 246, 33, 57, 53, 12, 229, 248, 42, 43, 0, 239, 13, 45, 47, 32, 0, 231, 253, 34, 31, 16, 25, 30, 8, 254, 28, 44, 10, 242, 6, 31, 30, 30, 33, 14, 248, 253, 17, 26, 33, 44, 30, 253, 248, 15, 24, 18, 15, 15, 23, 29, 18, 7, 12, 26, 37, 28, 247, 230, 19, 61, 38, 4, 8, 10, 2, 21, 46, 39, 12, 244, 235, 13, 58, 40, 0, 10, 38, 17, 242, 5, 47, 44, 1, 246, 17, 36, 27, 10, 12, 21, 8, 0, 24, 50, 39, 8, 250, 9, 28, 2, 242, 31, 67, 32, 0, 8, 13, 7, 7, 20, 34, 29, 14, 7, 2, 0, 27, 56, 35, 247, 240, 15, 36, 24, 9, 14, 24, 15, 3, 14, 32, 30, 17, 0, 239, 2, 54, 55, 4, 246, 21, 26, 254, 253, 25, 45, 27, 254, 255, 18, 21, 13, 21, 31, 14, 249, 253, 7, 21, 48, 50, 7, 233, 247, 20, 32, 22, 16, 18, 15, 9, 7, 8, 20, 34, 21, 253, 0, 25, 31, 6, 0, 26, 36, 5, 239, 9, 54, 46, 1, 245, 255, 0, 16, 44, 45, 11, 240, 0, 31, 29, 7, 0, 13, 33, 29, 0, 246, 8, 35, 35, 4, 253, 27, 28, 243, 247, 52, 59, 250, 217, 254, 31, 30, 28, 21, 4, 2, 12, 12, 17, 31, 18, 242, 241, 21, 38, 15, 9, 33, 27, 247, 243, 12, 19, 11, 20, 31, 13, 0, 8, 4, 252, 20, 38, 13, 247, 6, 20, 18, 34, 30, 240, 221, 5, 35, 26, 15, 13, 20, 21, 254, 241, 13, 36, 15, 247, 250, 7, 29, 45, 17, 239, 255, 19, 2, 1, 22, 18, 10, 13, 4, 7, 30, 20, 238, 242, 27, 32, 11, 15, 12, 247, 3, 32, 15, 252, 11, 16, 247, 249, 37, 53, 5, 219, 245, 34, 39, 8, 247, 3, 18, 11, 6, 26, 32, 0, 232, 248, 21, 29, 20, 15, 9, 5, 9, 8, 2, 3, 2, 4, 27, 35, 7, 254, 17, 9, 246, 10, 32, 13, 249, 3, 27, 30, 13, 0, 3, 11, 12, 6, 255, 253, 15, 46, 48, 11, 236, 240, 1, 16, 30, 32, 10, 240, 251, 35, 53, 27, 239, 222, 251, 38, 51, 27, 252, 241, 4, 33, 33, 12, 0, 253, 252, 12, 36, 34, 10, 255, 9, 17, 11, 13, 22, 9, 244, 4, 40, 44, 15, 241, 241, 21, 43, 20, 0, 3, 12, 17, 19, 17, 15, 6, 0, 18, 39, 17, 241, 251, 22, 20, 12, 28, 42, 19, 240, 235, 9, 38, 34, 13, 9, 19, 5, 249, 23, 49, 19, 240, 254, 31, 32, 7, 1, 13, 18, 21, 27, 21, 9, 8, 4, 2, 20, 37, 28, 15, 16, 15, 5, 253, 4, 25, 37, 33, 23, 12, 7, 5, 5, 14, 24, 18, 14, 28, 38, 25, 253, 241, 2, 29, 38, 30, 21, 16, 5, 254, 8, 24, 29, 32, 26, 8, 8, 19, 9, 254, 19, 42, 30, 8, 5, 13, 17, 15, 14, 11, 9, 17, 39, 46, 14, 234, 241, 18, 31, 22, 25, 34, 31, 13, 246, 242, 11, 35, 34, 29, 26, 9, 250, 255, 17, 30, 27, 8, 2, 27, 41, 19, 255, 2, 6, 4, 13, 32, 41, 27, 6, 4, 18, 16, 254, 252, 19, 40, 33, 11, 6, 12, 7, 8, 31, 41, 14, 242, 248, 20, 42, 35, 7, 248, 5, 25, 27, 21, 23, 22, 1, 242, 5, 35, 32, 13, 13, 24, 21, 8, 255, 4, 21, 27, 20, 13, 9, 11, 22, 23, 8, 5, 19, 21, 8, 2, 10, 25, 36, 27, 1, 248, 12, 30, 13, 252, 18, 40, 14, 248, 11, 30, 20, 11, 14, 8, 1, 9, 22, 22, 15, 11, 10, 10, 13, 15, 16, 17, 17, 10, 2, 6, 17, 19, 15, 16, 15, 10, 9, 13, 12, 10, 14, 15, 13, 11, 8, 7, 13, 17, 12, 11, 21, 18, 2, 255, 9, 13, 14, 19, 16, 9, 8, 9, 5, 6, 18, 24, 13, 255, 4, 20, 17, 3, 8, 19, 10, 253, 2, 20, 23, 11, 5, 13, 17, 7, 1, 6, 12, 15, 13, 8, 2, 6, 18, 24, 13, 0, 1, 12, 10, 2, 11, 20, 12, 2, 4, 10, 16, 15, 6, 3, 12, 14, 8, 10, 14, 9, 4, 7, 8, 7, 14, 23, 19, 5, 0, 8, 14, 12, 9, 7, 6, 12, 17, 10, 2, 9, 21, 22, 11, 0, 0, 12, 16, 10, 9, 12, 8, 7, 13, 12, 7, 11, 21, 21, 11, 4, 5, 10, 9, 3, 218, 12, 24, 0, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 21, 22, 22, 22, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 22, 23, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 23, 23, 24, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 23, 23, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 25, 26, 26, 26, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 29, 29, 28, 28, 28, 28, 29, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 29, 29, 29, 30, 29, 29, 29, 29, 29, 30, 30, 30, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 28, 28, 28, 28, 28, 29, 29, 29, 28, 28, 28, 28, 28, 27, 27, 27, 27, 27, 27, 28, 28, 28, 27, 28, 28, 28, 27, 27, 27, 27, 28, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 27, 27, 27, 27, 27, 27, 26, 26, 26, 26, 26, 26, 27, 26, 26, 26, 26, 26, 26, 26, 26, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 23, 23, 24, 23, 23, 23, 23, 23, 23, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 22, 23, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 21, 21, 22, 22, 23, 22, 22, 22, 23, 23, 23, 23, 22, 22, 22, 22, 22, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 22, 22, 22, 22, 23, 23, 23, 23, 22, 22, 23, 23, 23, 23, 23, 23, 23, 22, 22, 22, 22, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 28, 27, 28, 28, 28, 28, 28, 28, 28, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, 31, 30, 30, 30, 30, 30, 30, 29, 30, 30, 30, 31, 31, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 29, 30, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 28, 28, 29, 29, 29, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 27, 27, 27, 28, 28, 28, 28, 27, 27, 28, 28, 28, 28, 28, 28, 28, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, 26, 26, 27, 27, 26, 26, 26, 26, 26, 26, 26, 26, 26, 25, 25, 26, 26, 26, 25, 26, 26, 26, 25, 25, 25, 25, 24, 25, 25, 25, 25, 25, 24, 24, 24, 24, 23, 23, 23, 23, 23, 22, 23, 23, 23, 23, 23, 22, 23, 22, 22, 22, 22, 23, 23, 23, 22, 22, 22, 22, 22, 22, 22, 22, 21, 21, 21, 21, 21, 21, 21, 21, 20, 21, 21, 22, 22, 22, 21, 20, 19, 19, 19, 20, 20, 20, 21, 20, 20, 20, 21, 22, 21, 20, 20, 18, 1, 223, 195, 201, 247, 42, 74, 82, 63, 30, 3, 239, 210, 185, 197, 243, 24, 43, 60, 71, 65, 53, 43, 28, 6, 246, 241, 247, 6, 31, 56, 69, 66, 48, 24, 2, 250, 253, 5, 14, 23, 30, 34, 37, 38, 33, 25, 18, 11, 7, 3, 4, 12, 23, 33, 39, 39, 34, 24, 14, 7, 4, 5, 16, 34, 44, 35, 22, 16, 24, 25, 13, 9, 24, 35, 27, 11, 13, 31, 44, 39, 22, 12, 10, 13, 18, 26, 35, 39, 32, 17, 10, 15, 22, 30, 36, 34, 24, 14, 15, 26, 34, 30, 20, 22, 25, 24, 23, 26, 28, 26, 31, 38, 23, 4, 8, 37, 49, 32, 15, 16, 28, 32, 25, 22, 23, 19, 25, 32, 34, 27, 22, 19, 20, 30, 36, 33, 23, 18, 14, 21, 26, 32, 45, 43, 15, 242, 252, 15, 17, 6, 21, 48, 55, 54, 39, 12, 4, 29, 52, 25, 7, 27, 38, 17, 18, 53, 54, 23, 19, 42, 37, 3, 252, 33, 64, 47, 12, 14, 33, 42, 35, 31, 16, 13, 44, 47, 5, 4, 42, 51, 32, 29, 35, 8, 15, 39, 52, 39, 35, 41, 16, 254, 12, 66, 73, 32, 254, 252, 40, 71, 52, 15, 24, 50, 32, 3, 10, 44, 49, 33, 31, 31, 11, 234, 227, 236, 6, 39, 50, 44, 23, 28, 57, 60, 34, 34, 41, 26, 14, 18, 22, 38, 67, 70, 35, 1, 1, 27, 53, 49, 27, 20, 29, 27, 11, 9, 39, 66, 51, 41, 28, 249, 240, 27, 71, 48, 16, 32, 34, 8, 23, 61, 40, 9, 27, 37, 13, 1, 38, 56, 28, 35, 74, 29, 206, 243, 85, 88, 29, 37, 44, 253, 229, 28, 76, 58, 26, 24, 29, 16, 26, 31, 42, 39, 24, 15, 15, 48, 53, 23, 4, 31, 50, 35, 29, 32, 28, 23, 25, 14, 29, 51, 23, 3, 45, 75, 18, 231, 26, 88, 47, 244, 247, 31, 48, 44, 33, 22, 21, 30, 38, 21, 12, 15, 39, 68, 39, 249, 5, 39, 23, 1, 34, 83, 51, 235, 246, 51, 57, 18, 25, 24, 246, 248, 71, 98, 15, 231, 1, 28, 32, 46, 70, 19, 227, 4, 59, 49, 23, 4, 252, 27, 48, 24, 22, 78, 39, 214, 230, 56, 60, 252, 22, 68, 26, 212, 12, 82, 34, 236, 22, 74, 18, 232, 22, 59, 36, 247, 13, 55, 25, 1, 24, 53, 17, 237, 2, 36, 34, 33, 69, 27, 213, 246, 65, 42, 248, 4, 46, 52, 20, 18, 13, 245, 24, 66, 39, 237, 244, 35, 27, 34, 57, 36, 251, 245, 40, 25, 243, 15, 52, 64, 7, 211, 0, 87, 73, 244, 227, 29, 53, 247, 245, 66, 72, 0, 246, 28, 19, 250, 22, 72, 41, 235, 238, 22, 70, 59, 5, 0, 26, 19, 245, 7, 58, 67, 25, 19, 34, 248, 217, 14, 84, 79, 5, 243, 2, 9, 37, 57, 33, 253, 255, 27, 49, 43, 15, 6, 31, 63, 14, 201, 255, 89, 76, 245, 251, 57, 67, 7, 235, 19, 21, 0, 50, 86, 25, 226, 7, 45, 25, 4, 35, 57, 28, 39, 37, 239, 231, 44, 73, 9, 241, 43, 62, 3, 237, 67, 91, 253, 219, 11, 33, 33, 25, 45, 54, 15, 19, 29, 4, 249, 46, 78, 7, 229, 36, 79, 64, 23, 238, 248, 38, 51, 36, 21, 8, 20, 52, 28, 239, 19, 69, 58, 27, 21, 24, 247, 236, 47, 64, 25, 42, 80, 30, 241, 254, 23, 59, 59, 39, 0, 235, 39, 67, 41, 39, 46, 12, 237, 255, 47, 81, 69, 21, 1, 12, 26, 41, 34, 35, 59, 57, 254, 238, 68, 79, 10, 255, 35, 45, 2, 15, 71, 94, 40, 217, 246, 69, 58, 251, 14, 92, 59, 243, 20, 74, 8, 229, 75, 97, 6, 221, 25, 67, 51, 42, 55, 21, 240, 36, 52, 20, 34, 55, 22, 6, 42, 78, 31, 229, 252, 82, 122, 40, 207, 229, 59, 71, 32, 20, 33, 63, 34, 246, 2, 54, 89, 62, 17, 239, 242, 37, 57, 27, 24, 58, 65, 25, 11, 41, 40, 254, 255, 34, 46, 62, 62, 18, 243, 25, 88, 53, 0, 23, 28, 254, 252, 67, 93, 12, 241, 34, 55, 15, 255, 53, 59, 36, 23, 16, 11, 13, 51, 63, 20, 247, 36, 76, 45, 8, 1, 14, 37, 41, 45, 26, 0, 22, 59, 43, 25, 41, 31, 252, 3, 33, 70, 64, 24, 33, 9, 242, 18, 64, 51, 18, 16, 25, 16, 36, 73, 38, 235, 237, 39, 48, 22, 39, 37, 8, 23, 55, 17, 234, 10, 36, 38, 37, 32, 0, 251, 24, 39, 33, 35, 20, 0, 32, 44, 28, 21, 38, 20, 238, 29, 90, 56, 235, 254, 33, 25, 29, 69, 55, 246, 245, 31, 37, 6, 31, 65, 32, 234, 243, 59, 71, 5, 221, 1, 42, 44, 42, 14, 252, 23, 41, 21, 4, 13, 32, 27, 250, 9, 43, 44, 37, 22, 5, 5, 14, 14, 26, 38, 16, 0, 31, 48, 27, 255, 254, 251, 10, 64, 70, 12, 220, 243, 35, 22, 244, 25, 71, 45, 239, 241, 11, 254, 15, 65, 42, 235, 225, 8, 45, 56, 35, 251, 232, 4, 39, 27, 249, 8, 46, 26, 251, 17, 35, 18, 0, 10, 30, 17, 14, 20, 18, 6, 254, 9, 28, 28, 16, 39, 54, 4, 202, 226, 21, 57, 71, 46, 1, 227, 245, 24, 29, 22, 14, 22, 45, 20, 240, 10, 40, 30, 8, 250, 13, 48, 45, 15, 253, 254, 13, 18, 39, 41, 250, 231, 15, 67, 56, 21, 245, 247, 5, 249, 228, 230, 4, 10, 12, 18, 248, 233, 6, 43, 59, 32, 236, 247, 49, 73, 37, 9, 13, 29, 35, 23, 13, 8, 18, 36, 36, 16, 4, 27, 47, 15, 254, 30, 61, 39, 250, 246, 17, 22, 24, 36, 20, 0, 3, 18, 22, 28, 33, 16, 252, 3, 29, 39, 37, 34, 20, 13, 27, 34, 15, 13, 46, 63, 52, 14, 247, 8, 45, 66, 44, 7, 1, 19, 34, 35, 22, 30, 46, 47, 18, 252, 5, 12, 30, 57, 56, 28, 253, 3, 30, 26, 20, 33, 38, 33, 37, 34, 16, 14, 32, 50, 40, 5, 255, 29, 59, 61, 33, 19, 33, 38, 8, 248, 24, 61, 61, 28, 11, 28, 39, 34, 31, 41, 30, 10, 25, 56, 25, 254, 29, 42, 25, 32, 57, 42, 20, 20, 20, 16, 39, 60, 38, 2, 16, 71, 69, 20, 22, 41, 44, 35, 23, 37, 31, 22, 44, 66, 37, 1, 9, 36, 51, 25, 26, 58, 42, 3, 2, 35, 49, 34, 18, 10, 29, 56, 53, 19, 5, 15, 29, 41, 34, 36, 26, 18, 33, 60, 61, 42, 14, 251, 17, 56, 69, 34, 16, 26, 28, 33, 40, 42, 34, 28, 28, 23, 25, 43, 49, 22, 16, 42, 48, 26, 24, 44, 54, 35, 24, 26, 9, 17, 63, 71, 15, 248, 24, 76, 78, 17, 231, 1, 53, 57, 23, 18, 39, 25, 252, 28, 86, 54, 0, 2, 49, 55, 1, 10, 66, 77, 42, 10, 4, 25, 34, 28, 21, 39, 68, 48, 9, 8, 41, 47, 28, 29, 20, 16, 35, 66, 68, 12, 246, 32, 56, 46, 29, 24, 27, 22, 35, 62, 52, 10, 244, 21, 74, 75, 20, 13, 51, 38, 251, 0, 40, 48, 26, 30, 33, 25, 21, 38, 44, 19, 14, 21, 15, 5, 37, 70, 55, 15, 0, 3, 18, 45, 40, 24, 29, 41, 34, 17, 5, 19, 39, 45, 31, 25, 50, 65, 3, 221, 0, 58, 52, 1, 14, 52, 53, 22, 250, 0, 53, 72, 37, 251, 239, 23, 69, 56, 21, 19, 49, 45, 252, 247, 27, 57, 55, 52, 17, 247, 19, 25, 27, 56, 77, 38, 239, 250, 19, 43, 75, 75, 14, 223, 16, 87, 81, 22, 237, 244, 36, 68, 40, 255, 9, 69, 66, 29, 33, 22, 246, 16, 72, 70, 27, 22, 32, 14, 15, 22, 43, 48, 64, 76, 19, 247, 22, 22, 253, 30, 93, 71, 2, 12, 58, 50, 7, 2, 37, 48, 29, 31, 36, 22, 11, 20, 36, 30, 33, 43, 22, 7, 26, 50, 55, 50, 21, 3, 250, 22, 73, 66, 34, 18, 39, 35, 4, 0, 21, 44, 33, 26, 40, 39, 15, 3, 48, 75, 28, 238, 3, 31, 30, 49, 52, 25, 13, 36, 41, 15, 1, 13, 38, 56, 54, 21, 249, 32, 66, 32, 252, 25, 65, 31, 242, 249, 54, 80, 47, 17, 7, 11, 9, 21, 37, 50, 41, 27, 36, 20, 240, 2, 54, 68, 41, 26, 16, 18, 24, 30, 32, 31, 31, 32, 24, 254, 17, 47, 45, 22, 30, 37, 25, 17, 19, 13, 13, 54, 61, 30, 248, 3, 42, 62, 48, 13, 12, 37, 36, 21, 12, 42, 63, 47, 28, 16, 25, 19, 17, 32, 61, 58, 19, 17, 39, 39, 25, 36, 56, 30, 20, 38, 42, 28, 18, 21, 21, 54, 75, 37, 249, 244, 11, 31, 66, 72, 22, 248, 7, 38, 38, 41, 50, 35, 255, 5, 48, 54, 31, 23, 16, 20, 51, 64, 40, 3, 1, 46, 37, 1, 28, 67, 41, 0, 19, 51, 36, 17, 25, 37, 31, 44, 64, 35, 0, 18, 30, 24, 18, 34, 58, 49, 34, 17, 25, 13, 3, 28, 51, 49, 25, 30, 42, 37, 24, 28, 40, 6, 4, 41, 59, 55, 47, 40, 12, 6, 27, 24, 17, 51, 75, 42, 0, 12, 45, 34, 13, 19, 26, 28, 44, 66, 51, 16, 0, 6, 29, 60, 69, 46, 24, 21, 14, 13, 36, 57, 56, 37, 25, 13, 16, 42, 57, 43, 35, 30, 10, 19, 60, 66, 19, 16, 49, 42, 14, 11, 26, 42, 42, 23, 12, 20, 50, 55, 46, 47, 33, 250, 248, 51, 71, 29, 9, 41, 53, 37, 46, 56, 31, 255, 6, 33, 40, 43, 43, 28, 14, 26, 50, 41, 16, 39, 50, 19, 0, 6, 21, 44, 59, 35, 0, 255, 47, 91, 70, 20, 245, 254, 39, 44, 17, 12, 38, 63, 40, 8, 20, 41, 21, 1, 24, 37, 10, 242, 21, 54, 68, 54, 7, 248, 12, 30, 21, 17, 24, 38, 24, 11, 19, 17, 18, 38, 48, 38, 16, 0, 1, 1, 19, 45, 47, 34, 18, 16, 33, 27, 19, 27, 40, 37, 3, 248, 13, 21, 17, 30, 64, 80, 32, 240, 2, 24, 255, 240, 42, 71, 17, 248, 30, 48, 21, 20, 30, 7, 233, 1, 50, 46, 16, 10, 9, 0, 16, 42, 49, 35, 18, 9, 7, 23, 29, 8, 3, 20, 41, 51, 44, 36, 21, 4, 247, 6, 35, 31, 20, 17, 15, 20, 50, 56, 22, 255, 1, 12, 21, 35, 20, 243, 252, 35, 36, 24, 28, 25, 6, 3, 33, 43, 17, 5, 10, 16, 37, 52, 37, 26, 29, 35, 28, 12, 11, 27, 23, 5, 2, 16, 44, 54, 29, 5, 19, 19, 253, 7, 30, 14, 0, 26, 51, 30, 0, 4, 37, 46, 29, 19, 12, 12, 15, 14, 3, 2, 29, 48, 27, 6, 18, 43, 19, 237, 5, 52, 45, 14, 11, 19, 26, 52, 53, 10, 4, 37, 34, 3, 14, 40, 25, 255, 17, 43, 28, 5, 14, 36, 23, 11, 18, 28, 41, 41, 250, 212, 251, 68, 83, 46, 18, 4, 251, 13, 60, 64, 19, 254, 0, 22, 43, 37, 26, 41, 46, 23, 0, 1, 17, 23, 27, 33, 29, 14, 22, 49, 32, 245, 241, 22, 57, 61, 41, 8, 238, 247, 24, 41, 34, 29, 28, 17, 254, 2, 45, 65, 31, 0, 6, 10, 4, 17, 41, 51, 44, 21, 0, 9, 22, 28, 38, 33, 8, 5, 30, 29, 28, 35, 28, 3, 5, 46, 60, 28, 3, 5, 11, 28, 42, 56, 53, 21, 240, 2, 40, 46, 43, 37, 27, 17, 17, 14, 9, 19, 43, 41, 25, 26, 34, 28, 29, 35, 23, 9, 12, 32, 34, 31, 37, 35, 17, 17, 38, 42, 33, 28, 30, 22, 24, 37, 32, 14, 12, 30, 34, 32, 47, 50, 31, 17, 8, 1, 11, 29, 47, 56, 39, 22, 16, 26, 46, 50, 48, 28, 0, 4, 34, 46, 35, 19, 10, 17, 33, 38, 28, 18, 27, 32, 13, 3, 25, 51, 39, 14, 12, 27, 37, 35, 28, 25, 23, 29, 36, 22, 14, 16, 27, 41, 39, 34, 32, 31, 28, 24, 25, 34, 32, 12, 9, 29, 42, 32, 20, 24, 28, 26, 32, 30, 21, 10, 7, 18, 39, 46, 38, 30, 21, 21, 21, 26, 36, 36, 11, 6, 32, 38, 28, 34, 39, 29, 17, 17, 28, 37, 33, 17, 14, 22, 22, 18, 29, 40, 35, 23, 21, 34, 31, 10, 255, 6, 19, 26, 33, 31, 21, 19, 27, 33, 31, 27, 19, 6, 11, 30, 22, 5, 16, 33, 40, 39, 31, 23, 8, 5, 21, 31, 22, 11, 17, 30, 38, 32, 25, 26, 31, 28, 20, 18, 19, 20, 26, 41, 34, 3, 247, 17, 43, 39, 29, 31, 24, 10, 6, 5, 1, 9, 31, 39, 17, 0, 13, 36, 31, 14, 8, 10, 20, 29, 19, 6, 11, 25, 24, 21, 34, 39, 19, 4, 19, 32, 26, 23, 33, 19, 249, 0, 35, 43, 25, 21, 27, 19, 4, 15, 27, 20, 16, 19, 17, 9, 13, 28, 37, 31, 27, 30, 26, 17, 13, 17, 18, 19, 32, 42, 35, 23, 22, 26, 23, 18, 27, 34, 33, 30, 17, 8, 13, 31, 34, 30, 36, 34, 23, 18, 17, 16, 24, 32, 27, 13, 9, 21, 33, 32, 26, 27, 26, 17, 9, 13, 24, 31, 32, 31, 28, 19, 13, 20, 31, 31, 29, 32, 31, 20, 12, 13, 25, 32, 30, 24, 22, 28, 26, 17, 16, 22, 27, 31, 33, 26, 16, 20, 27, 30, 29, 30, 26, 17, 19, 25, 27, 25, 26, 31, 30, 21, 15, 18, 26, 34, 36, 28, 15, 10, 21, 29, 27, 28, 35, 33, 23, 20, 24, 26, 29, 35, 31, 21, 18, 22, 28, 30, 27, 27, 31, 33, 30, 22, 18, 23, 33, 35, 26, 19, 25, 32, 28, 26, 29, 30, 26, 26, 26, 19, 0, 0, 175, 0, 4, 0, 1, 0, 44, 1, 66, 3, 196, 4, 130, 10, 112, 13, 48, 15, 32, 28, 45, 50, 30, 64, 60, 39, 31, 20, 9, 5, 186, 152, 120, 120, 120, 120, 192, 155, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 250, 0, 0, 3, 0, 44, 1, 66, 3, 196, 4, 130, 10, 112, 13, 48, 15, 32, 28, 70, 104, 44, 92, 87, 57, 44, 29, 13, 7, 186, 152, 120, 120, 120, 120, 192, 155, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 44, 1, 66, 3, 216, 4, 240, 10, 112, 13, 48, 15, 32, 28, 60, 80, 45, 77, 82, 54, 42, 27, 13, 6, 186, 152, 120, 120, 120, 120, 192, 155, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 3, 0, 0, 0, 240, 250, 209, 182, 1, 0, 44, 1, 66, 3, 216, 4, 84, 11, 152, 13, 80, 15, 32, 28, 0, 30, 37, 35, 56, 37, 29, 19, 9, 4, 186, 152, 120, 120, 120, 120, 192, 155, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 45, 0, 5, 0, 1, 0, 240, 0, 212, 2, 106, 4, 200, 10, 2, 13, 238, 14, 192, 27, 45, 61, 34, 63, 75, 41, 34, 29, 11, 5, 165, 148, 135, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 250, 0, 0, 3, 0, 248, 0, 212, 2, 106, 4, 200, 10, 2, 13, 238, 14, 192, 27, 130, 112, 43, 86, 102, 55, 46, 39, 15, 7, 165, 148, 135, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 218, 0, 120, 2, 169, 3, 161, 10, 109, 12, 71, 14, 60, 27, 55, 109, 34, 71, 93, 53, 42, 37, 17, 8, 166, 145, 137, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 3, 0, 0, 0, 240, 250, 209, 182, 1, 0, 144, 0, 208, 1, 12, 3, 196, 9, 254, 11, 157, 14, 216, 26, 40, 67, 25, 64, 64, 45, 41, 24, 17, 8, 163, 120, 143, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 144, 0, 208, 1, 12, 3, 196, 9, 254, 11, 157, 14, 216, 26, 0, 42, 19, 51, 51, 35, 32, 19, 14, 6, 163, 120, 143, 120, 120, 120, 165, 115, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 108, 65, 227, 191, 251, 250, 194, 182, 195, 0, 4, 0, 1, 0, 141, 0, 80, 1, 204, 6, 0, 10, 208, 12, 40, 15, 104, 25, 45, 36, 12, 54, 51, 51, 49, 30, 11, 9, 174, 115, 127, 122, 122, 132, 187, 130, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 250, 0, 0, 3, 0, 141, 0, 80, 1, 204, 6, 0, 10, 208, 12, 40, 15, 104, 25, 75, 63, 16, 72, 68, 68, 65, 39, 15, 12, 174, 115, 127, 122, 122, 132, 187, 130, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 141, 0, 80, 1, 204, 6, 0, 10, 208, 12, 40, 15, 104, 25, 75, 46, 13, 61, 57, 57, 55, 33, 12, 10, 174, 115, 127, 122, 122, 132, 187, 130, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 3, 0, 0, 0, 240, 250, 209, 182, 1, 0, 141, 0, 80, 1, 204, 6, 0, 10, 208, 12, 40, 15, 104, 25, 0, 30, 11, 49, 46, 47, 45, 27, 10, 8, 174, 115, 127, 122, 122, 132, 187, 130, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 210, 0, 5, 0, 1, 0, 171, 0, 105, 1, 248, 7, 2, 11, 28, 13, 224, 14, 196, 26, 45, 29, 17, 48, 48, 38, 38, 24, 10, 5, 167, 113, 125, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 250, 0, 0, 3, 0, 214, 0, 18, 2, 160, 6, 203, 10, 77, 13, 4, 15, 79, 27, 60, 58, 30, 71, 73, 55, 50, 32, 14, 7, 175, 128, 129, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 24, 1, 16, 3, 156, 4, 120, 10, 152, 13, 60, 15, 32, 28, 60, 73, 36, 66, 79, 56, 43, 28, 13, 7, 186, 152, 135, 120, 120, 120, 192, 155, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 3, 0, 0, 0, 240, 250, 209, 182, 1, 0, 24, 1, 16, 3, 156, 4, 120, 10, 152, 13, 60, 15, 32, 28, 45, 65, 37, 62, 75, 52, 40, 27, 12, 6, 186, 152, 135, 120, 120, 120, 192, 155, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 24, 1, 16, 3, 156, 4, 120, 10, 152, 13, 60, 15, 32, 28, 0, 43, 30, 50, 61, 42, 33, 22, 10, 5, 186, 152, 135, 120, 120, 120, 192, 155, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 108, 65, 227, 191, 251, 250, 194, 182, 203, 0, 6, 0, 1, 0, 200, 0, 29, 1, 245, 8, 36, 11, 186, 12, 165, 15, 244, 26, 61, 64, 0, 88, 56, 44, 48, 36, 16, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 250, 0, 0, 3, 0, 200, 0, 34, 2, 165, 7, 70, 9, 110, 13, 79, 15, 244, 26, 70, 85, 40, 88, 68, 64, 40, 20, 16, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 200, 0, 9, 3, 208, 4, 241, 9, 60, 13, 194, 14, 244, 26, 72, 99, 52, 96, 92, 48, 44, 32, 16, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 3, 0, 0, 0, 240, 250, 209, 182, 1, 0, 14, 1, 212, 2, 106, 4, 200, 10, 2, 13, 238, 14, 192, 27, 61, 140, 52, 95, 114, 62, 51, 43, 16, 8, 165, 148, 135, 120, 120, 120, 167, 142, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 200, 0, 145, 2, 228, 3, 118, 10, 225, 12, 56, 15, 244, 26, 60, 127, 48, 108, 68, 40, 44, 28, 16, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 108, 65, 227, 191, 251, 250, 194, 182, 1, 0, 200, 0, 45, 2, 57, 3, 209, 10, 2, 13, 122, 15, 244, 26, 0, 106, 46, 86, 54, 36, 32, 18, 14, 7, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 48, 250, 48, 0, 215, 0, 5, 0, 33, 0, 173, 0, 64, 1, 156, 8, 220, 10, 66, 13, 19, 15, 228, 26, 45, 44, 12, 60, 60, 59, 56, 29, 13, 6, 182, 105, 128, 120, 120, 120, 167, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 250, 0, 0, 3, 0, 173, 0, 64, 1, 156, 8, 220, 10, 66, 13, 19, 15, 228, 26, 40, 56, 14, 68, 68, 66, 64, 32, 14, 7, 182, 105, 128, 120, 120, 120, 167, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 244, 0, 229, 1, 108, 7, 82, 10, 89, 13, 17, 15, 34, 28, 90, 58, 28, 67, 66, 65, 55, 35, 13, 8, 221, 122, 147, 120, 120, 120, 167, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 3, 0, 0, 0, 240, 250, 209, 182, 1, 0, 31, 1, 72, 2, 204, 6, 0, 10, 104, 13, 15, 15, 224, 28, 40, 43, 31, 56, 56, 55, 42, 31, 10, 6, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 31, 1, 72, 2, 204, 6, 0, 10, 104, 13, 15, 15, 224, 28, 0, 32, 26, 48, 48, 47, 36, 27, 9, 5, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 108, 65, 227, 191, 251, 250, 194, 182, 225, 0, 5, 0, 1, 0, 136, 0, 44, 1, 8, 7, 96, 9, 148, 12, 41, 14, 144, 26, 45, 27, 13, 56, 44, 37, 29, 23, 11, 0, 120, 120, 105, 120, 120, 120, 60, 90, 90, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 250, 0, 0, 3, 0, 136, 0, 164, 1, 120, 5, 196, 9, 48, 12, 41, 14, 144, 26, 40, 52, 27, 82, 60, 46, 40, 29, 19, 0, 120, 120, 112, 120, 120, 120, 60, 75, 112, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 192, 0, 40, 2, 132, 3, 20, 10, 204, 11, 96, 14, 88, 27, 80, 106, 35, 84, 81, 51, 49, 28, 18, 7, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 3, 0, 0, 0, 240, 250, 209, 182, 1, 0, 192, 0, 40, 2, 92, 3, 100, 10, 164, 11, 96, 14, 159, 27, 60, 105, 32, 76, 83, 46, 44, 26, 16, 7, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 192, 0, 40, 2, 92, 3, 100, 10, 164, 11, 96, 14, 159, 27, 0, 55, 23, 55, 60, 34, 32, 18, 12, 5, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 108, 65, 227, 191, 251, 250, 194, 182, 102, 0, 6, 0, 1, 0, 200, 0, 14, 1, 21, 9, 210, 11, 91, 12, 164, 15, 244, 26, 43, 65, 3, 83, 38, 41, 38, 38, 11, 7, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 250, 0, 0, 3, 0, 144, 0, 76, 1, 251, 8, 200, 10, 111, 12, 209, 14, 244, 26, 60, 104, 11, 102, 72, 64, 60, 49, 15, 9, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 104, 0, 154, 1, 228, 6, 50, 9, 139, 12, 250, 14, 244, 26, 107, 56, 33, 69, 42, 48, 42, 27, 12, 6, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 3, 0, 0, 0, 240, 250, 209, 182, 1, 0, 200, 0, 207, 1, 11, 4, 244, 9, 110, 12, 228, 14, 244, 26, 124, 75, 32, 80, 54, 35, 25, 16, 12, 6, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 104, 0, 168, 1, 29, 3, 47, 10, 55, 12, 77, 15, 244, 26, 35, 84, 41, 76, 64, 22, 15, 7, 15, 7, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 108, 65, 227, 191, 251, 250, 194, 182, 1, 0, 200, 0, 114, 1, 202, 2, 115, 10, 103, 12, 72, 15, 244, 26, 0, 64, 24, 63, 45, 21, 15, 9, 12, 6, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 48, 250, 48, 0, 160, 0, 4, 0, 1, 0, 132, 0, 8, 2, 136, 4, 136, 9, 128, 12, 156, 14, 84, 27, 50, 40, 30, 52, 60, 40, 33, 28, 16, 6, 167, 148, 143, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 250, 0, 0, 3, 0, 132, 0, 8, 2, 136, 4, 136, 9, 128, 12, 156, 14, 84, 27, 60, 71, 40, 70, 80, 54, 44, 38, 22, 8, 167, 148, 143, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 132, 0, 8, 2, 136, 4, 136, 9, 128, 12, 156, 14, 84, 27, 50, 53, 34, 60, 69, 46, 38, 33, 19, 7, 167, 148, 143, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 3, 0, 0, 0, 240, 250, 209, 182, 1, 0, 132, 0, 8, 2, 136, 4, 136, 9, 128, 12, 156, 14, 84, 27, 0, 33, 27, 48, 55, 37, 30, 26, 15, 5, 167, 148, 143, 120, 120, 120, 197, 135, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 239, 0, 5, 0, 1, 0, 80, 0, 96, 1, 52, 3, 193, 10, 228, 12, 114, 15, 244, 26, 87, 79, 30, 80, 61, 42, 30, 0, 15, 7, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 250, 0, 0, 3, 0, 80, 0, 191, 1, 17, 3, 196, 10, 108, 12, 119, 15, 244, 26, 50, 97, 53, 83, 53, 41, 38, 34, 15, 7, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 128, 0, 80, 2, 81, 3, 120, 10, 94, 12, 201, 14, 244, 26, 53, 122, 49, 83, 79, 38, 30, 19, 19, 7, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 3, 0, 0, 0, 240, 250, 209, 182, 1, 0, 200, 0, 57, 3, 115, 4, 10, 10, 41, 12, 214, 13, 244, 26, 49, 96, 50, 90, 75, 54, 28, 39, 14, 7, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 200, 0, 57, 3, 115, 4, 10, 10, 41, 12, 214, 13, 244, 26, 0, 97, 54, 90, 75, 54, 28, 39, 14, 7, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 108, 65, 227, 191, 251, 250, 194, 182, 14, 1, 6, 0, 1, 0, 200, 0, 68, 1, 46, 3, 69, 11, 54, 13, 160, 15, 244, 26, 48, 50, 11, 68, 41, 15, 11, 0, 15, 7, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 250, 0, 0, 3, 0, 200, 0, 124, 1, 239, 2, 107, 10, 86, 12, 52, 16, 244, 26, 45, 96, 30, 79, 57, 26, 22, 15, 15, 7, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 200, 0, 197, 2, 187, 3, 240, 9, 163, 12, 23, 15, 244, 26, 67, 134, 49, 91, 83, 49, 38, 30, 15, 7, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 3, 0, 0, 0, 240, 250, 209, 182, 1, 0, 224, 0, 30, 3, 60, 5, 1, 9, 112, 13, 119, 14, 244, 26, 70, 94, 49, 106, 68, 57, 38, 0, 15, 7, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 200, 0, 190, 1, 106, 8, 33, 10, 134, 12, 93, 14, 244, 26, 40, 58, 27, 69, 54, 46, 34, 31, 15, 7, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 108, 65, 227, 191, 251, 250, 194, 182, 1, 0, 200, 0, 190, 1, 106, 8, 33, 10, 134, 12, 93, 14, 244, 26, 0, 23, 17, 44, 34, 29, 22, 19, 7, 4, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 48, 250, 48, 0, 38, 1, 6, 0, 1, 0, 200, 0, 126, 1, 12, 3, 253, 9, 107, 12, 48, 14, 244, 26, 46, 107, 24, 88, 72, 40, 40, 40, 16, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 250, 0, 0, 3, 0, 168, 0, 215, 1, 238, 3, 112, 9, 161, 12, 217, 14, 244, 26, 50, 145, 48, 100, 100, 44, 40, 44, 16, 8, 187, 125, 175, 137, 150, 175, 187, 125, 175, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 200, 0, 203, 1, 170, 6, 140, 8, 3, 12, 148, 13, 244, 26, 62, 128, 45, 98, 60, 91, 68, 38, 15, 9, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 3, 0, 0, 0, 240, 250, 209, 182, 1, 0, 200, 0, 176, 1, 88, 8, 132, 9, 72, 12, 130, 14, 244, 26, 60, 81, 32, 75, 68, 57, 57, 32, 14, 7, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 176, 0, 88, 1, 180, 8, 228, 10, 161, 12, 16, 15, 244, 26, 76, 85, 12, 92, 64, 60, 56, 28, 16, 8, 187, 125, 137, 137, 150, 175, 187, 125, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 108, 65, 227, 191, 251, 250, 194, 182, 1, 0, 152, 0, 72, 1, 232, 8, 160, 10, 92, 13, 10, 15, 32, 28, 0, 46, 26, 66, 44, 44, 37, 29, 11, 7, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 48, 250, 48, 0, 240, 0, 6, 0, 1, 0, 142, 0, 62, 1, 138, 2, 166, 9, 38, 12, 203, 14, 24, 27, 40, 35, 7, 66, 37, 18, 19, 14, 8, 4, 148, 126, 80, 120, 120, 120, 75, 90, 90, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 250, 0, 0, 3, 0, 142, 0, 62, 1, 138, 2, 166, 9, 38, 12, 203, 14, 24, 27, 40, 39, 8, 69, 39, 18, 20, 15, 8, 4, 148, 126, 80, 120, 120, 120, 75, 90, 90, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 147, 0, 85, 1, 159, 2, 185, 9, 25, 12, 193, 14, 37, 27, 40, 38, 10, 68, 43, 21, 22, 20, 9, 4, 151, 127, 85, 120, 120, 120, 75, 90, 90, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 3, 0, 0, 0, 240, 250, 209, 182, 1, 0, 192, 0, 40, 2, 92, 3, 100, 10, 164, 11, 96, 14, 159, 27, 70, 99, 31, 74, 81, 45, 43, 25, 16, 6, 172, 142, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 184, 0, 72, 2, 172, 3, 20, 10, 164, 11, 53, 14, 160, 27, 50, 81, 30, 71, 86, 42, 41, 23, 15, 6, 173, 142, 135, 120, 120, 120, 182, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 108, 65, 227, 191, 251, 250, 194, 182, 1, 0, 184, 0, 72, 2, 172, 3, 20, 10, 164, 11, 53, 14, 160, 27, 0, 46, 23, 54, 64, 32, 30, 18, 11, 4, 173, 142, 135, 120, 120, 120, 182, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 48, 250, 48, 0, 205, 0, 5, 0, 1, 0, 132, 0, 24, 1, 184, 6, 36, 9, 228, 12, 96, 14, 100, 25, 45, 27, 15, 48, 33, 28, 30, 28, 7, 10, 160, 90, 135, 120, 120, 120, 160, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 250, 0, 0, 3, 0, 132, 0, 24, 1, 184, 6, 36, 9, 228, 12, 96, 14, 100, 25, 40, 38, 18, 58, 39, 33, 36, 33, 9, 12, 160, 90, 135, 120, 120, 120, 160, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 142, 0, 83, 1, 156, 6, 74, 9, 252, 12, 124, 14, 151, 25, 80, 53, 24, 69, 50, 41, 43, 38, 11, 13, 169, 98, 137, 122, 120, 120, 160, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 3, 0, 0, 0, 240, 250, 209, 182, 1, 0, 232, 0, 104, 3, 160, 5, 160, 10, 216, 13, 120, 15, 102, 27, 40, 84, 44, 78, 82, 54, 44, 30, 14, 5, 255, 170, 163, 145, 120, 120, 255, 174, 173, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 232, 0, 104, 3, 160, 5, 160, 10, 216, 13, 120, 15, 102, 27, 0, 45, 32, 57, 60, 40, 32, 22, 10, 4, 255, 170, 163, 145, 120, 120, 255, 174, 173, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 108, 65, 227, 191, 251, 250, 194, 182, 205, 0, 5, 0, 1, 0, 147, 0, 22, 1, 238, 7, 186, 9, 17, 13, 141, 14, 81, 26, 45, 38, 10, 60, 51, 47, 50, 28, 12, 7, 167, 101, 123, 120, 120, 120, 167, 90, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 250, 0, 0, 3, 0, 132, 0, 16, 1, 28, 7, 232, 8, 228, 12, 96, 14, 100, 25, 30, 40, 18, 58, 39, 36, 36, 33, 9, 12, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 147, 0, 54, 1, 186, 6, 58, 9, 241, 12, 113, 14, 189, 25, 80, 54, 23, 68, 49, 43, 44, 39, 11, 13, 168, 94, 137, 120, 120, 120, 160, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 3, 0, 0, 0, 240, 250, 209, 182, 1, 0, 3, 1, 17, 2, 200, 6, 216, 9, 80, 13, 239, 14, 63, 28, 50, 61, 34, 68, 64, 62, 50, 38, 12, 9, 228, 124, 154, 120, 120, 120, 160, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 31, 1, 72, 2, 204, 6, 0, 10, 104, 13, 15, 15, 224, 28, 0, 35, 28, 51, 50, 49, 38, 28, 9, 6, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 108, 65, 227, 191, 251, 250, 194, 182, 0, 0, 5, 0, 1, 0, 132, 0, 16, 1, 8, 7, 232, 8, 228, 12, 96, 14, 100, 25, 40, 39, 18, 57, 39, 36, 36, 33, 9, 12, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 250, 0, 0, 3, 0, 132, 0, 16, 1, 8, 7, 232, 8, 228, 12, 96, 14, 100, 25, 65, 61, 22, 72, 49, 45, 45, 41, 11, 15, 167, 90, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 128, 0, 52, 1, 219, 6, 6, 9, 218, 12, 241, 14, 225, 25, 50, 59, 24, 70, 54, 45, 46, 39, 13, 13, 167, 105, 135, 120, 120, 120, 167, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 3, 0, 0, 0, 240, 250, 209, 182, 1, 0, 116, 0, 160, 1, 84, 6, 96, 9, 188, 12, 164, 16, 88, 27, 40, 33, 23, 48, 51, 34, 37, 25, 15, 6, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 116, 0, 224, 1, 44, 6, 116, 9, 12, 13, 224, 16, 88, 27, 0, 30, 24, 48, 50, 34, 34, 21, 13, 5, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 108, 65, 227, 191, 251, 250, 194, 182, 174, 0, 4, 0, 1, 0, 136, 0, 200, 1, 216, 4, 96, 9, 100, 12, 156, 14, 12, 27, 44, 39, 25, 55, 58, 34, 33, 25, 14, 5, 165, 141, 141, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 136, 0, 200, 1, 216, 4, 96, 9, 100, 12, 156, 14, 12, 27, 80, 58, 31, 67, 71, 41, 40, 30, 17, 6, 165, 141, 141, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 136, 0, 200, 1, 216, 4, 96, 9, 100, 12, 156, 14, 12, 27, 50, 52, 29, 63, 67, 39, 38, 28, 16, 6, 165, 141, 141, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 136, 0, 200, 1, 216, 4, 96, 9, 100, 12, 156, 14, 12, 27, 0, 35, 24, 52, 55, 32, 31, 23, 13, 5, 165, 141, 141, 120, 120, 120, 162, 127, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 160, 0, 4, 0, 1, 0, 142, 0, 52, 2, 136, 4, 160, 10, 188, 12, 236, 14, 99, 27, 50, 42, 31, 57, 60, 33, 36, 28, 16, 6, 168, 147, 130, 120, 120, 120, 197, 135, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 142, 0, 52, 2, 136, 4, 160, 10, 188, 12, 236, 14, 99, 27, 60, 75, 42, 76, 80, 44, 49, 38, 22, 8, 168, 147, 130, 120, 120, 120, 197, 135, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 142, 0, 52, 2, 136, 4, 160, 10, 188, 12, 236, 14, 99, 27, 50, 57, 36, 66, 69, 38, 42, 33, 19, 7, 168, 147, 130, 120, 120, 120, 197, 135, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 142, 0, 52, 2, 136, 4, 160, 10, 188, 12, 236, 14, 99, 27, 0, 35, 28, 52, 55, 30, 33, 26, 15, 5, 168, 147, 130, 120, 120, 120, 197, 135, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 160, 0, 4, 0, 1, 0, 169, 0, 193, 1, 89, 3, 196, 9, 244, 11, 146, 14, 186, 26, 50, 43, 23, 52, 55, 34, 29, 20, 14, 4, 163, 130, 148, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 169, 0, 193, 1, 89, 3, 196, 9, 244, 11, 146, 14, 186, 26, 70, 85, 33, 72, 77, 48, 41, 28, 20, 6, 163, 130, 148, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 169, 0, 193, 1, 89, 3, 196, 9, 244, 11, 146, 14, 186, 26, 40, 71, 30, 66, 71, 44, 38, 25, 18, 6, 163, 130, 148, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 169, 0, 193, 1, 89, 3, 196, 9, 244, 11, 146, 14, 186, 26, 0, 43, 23, 52, 55, 34, 29, 20, 14, 4, 163, 130, 148, 120, 120, 120, 162, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 165, 0, 4, 0, 1, 0, 180, 0, 144, 1, 216, 4, 152, 8, 148, 12, 226, 14, 144, 26, 45, 36, 24, 51, 51, 36, 36, 30, 15, 7, 170, 125, 145, 120, 120, 120, 162, 125, 145, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 180, 0, 144, 1, 216, 4, 152, 8, 148, 12, 226, 14, 144, 26, 80, 65, 32, 68, 68, 48, 48, 40, 20, 10, 170, 125, 145, 120, 120, 120, 162, 125, 145, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 180, 0, 144, 1, 216, 4, 152, 8, 148, 12, 226, 14, 144, 26, 40, 58, 30, 64, 64, 45, 45, 38, 19, 9, 170, 125, 145, 120, 120, 120, 162, 125, 145, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 180, 0, 144, 1, 216, 4, 152, 8, 148, 12, 226, 14, 144, 26, 0, 31, 22, 47, 47, 33, 33, 28, 14, 7, 170, 125, 145, 120, 120, 120, 162, 125, 145, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 185, 0, 4, 0, 1, 0, 116, 0, 240, 1, 32, 5, 104, 9, 180, 12, 132, 14, 96, 27, 45, 59, 31, 64, 78, 41, 48, 37, 19, 7, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 116, 0, 240, 1, 32, 5, 104, 9, 180, 12, 132, 14, 96, 27, 80, 73, 35, 72, 86, 45, 53, 41, 21, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 116, 0, 240, 1, 32, 5, 104, 9, 180, 12, 132, 14, 96, 27, 60, 59, 31, 64, 78, 41, 48, 37, 19, 7, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 116, 0, 240, 1, 32, 5, 104, 9, 180, 12, 132, 14, 96, 27, 0, 73, 35, 72, 86, 45, 53, 41, 21, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 170, 0, 4, 0, 1, 0, 246, 0, 80, 2, 164, 6, 201, 9, 70, 13, 255, 14, 73, 28, 50, 33, 27, 49, 54, 44, 34, 25, 9, 5, 219, 138, 158, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 246, 0, 80, 2, 164, 6, 201, 9, 70, 13, 255, 14, 73, 28, 60, 83, 43, 78, 87, 70, 54, 39, 15, 8, 219, 138, 158, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 246, 0, 80, 2, 164, 6, 201, 9, 70, 13, 255, 14, 73, 28, 60, 74, 40, 74, 82, 67, 51, 37, 14, 8, 219, 138, 158, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 246, 0, 80, 2, 164, 6, 201, 9, 70, 13, 255, 14, 73, 28, 0, 33, 27, 49, 54, 44, 34, 25, 9, 5, 219, 138, 158, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 190, 0, 5, 0, 1, 0, 132, 0, 24, 1, 184, 6, 36, 9, 228, 12, 96, 14, 100, 25, 40, 23, 14, 45, 31, 26, 28, 26, 7, 9, 160, 90, 135, 120, 120, 120, 160, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 132, 0, 24, 1, 184, 6, 36, 9, 228, 12, 96, 14, 100, 25, 30, 48, 20, 64, 44, 37, 40, 37, 10, 13, 160, 90, 135, 120, 120, 120, 160, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 166, 0, 136, 1, 18, 7, 138, 9, 228, 12, 56, 14, 242, 26, 40, 68, 30, 76, 60, 65, 57, 45, 13, 13, 160, 97, 131, 120, 120, 120, 160, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 6, 1, 33, 2, 26, 7, 232, 9, 77, 13, 228, 14, 125, 28, 80, 71, 37, 72, 73, 69, 54, 41, 13, 9, 227, 125, 153, 120, 120, 120, 160, 135, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 31, 1, 72, 2, 28, 7, 0, 10, 104, 13, 15, 15, 224, 28, 0, 32, 26, 48, 51, 47, 36, 27, 9, 5, 244, 132, 159, 120, 120, 120, 135, 180, 150, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 125, 0, 5, 0, 13, 0, 76, 0, 224, 0, 8, 7, 4, 11, 156, 14, 220, 15, 32, 29, 0, 19, 7, 46, 7, 28, 21, 10, 7, 3, 150, 115, 97, 120, 120, 120, 90, 130, 97, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 13, 0, 76, 0, 224, 0, 8, 7, 4, 11, 156, 14, 220, 15, 32, 29, 50, 19, 7, 46, 7, 28, 21, 10, 7, 3, 150, 115, 97, 120, 120, 120, 90, 130, 97, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 76, 0, 224, 0, 8, 7, 4, 11, 156, 14, 220, 15, 32, 29, 45, 17, 6, 44, 10, 27, 20, 10, 6, 3, 150, 115, 97, 120, 120, 120, 90, 130, 97, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 76, 0, 224, 0, 8, 7, 4, 11, 156, 14, 220, 15, 32, 29, 30, 13, 6, 39, 9, 24, 18, 9, 6, 3, 150, 115, 97, 120, 120, 120, 90, 130, 97, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 76, 0, 224, 0, 136, 9, 4, 11, 156, 14, 220, 15, 32, 29, 0, 15, 6, 41, 9, 28, 22, 12, 6, 3, 150, 115, 97, 120, 120, 120, 90, 130, 97, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 105, 0, 4, 0, 1, 0, 76, 0, 224, 0, 156, 9, 4, 11, 156, 14, 220, 15, 32, 29, 35, 19, 7, 46, 10, 28, 18, 10, 5, 3, 150, 115, 97, 120, 120, 120, 90, 130, 97, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 13, 0, 76, 0, 224, 0, 156, 9, 4, 11, 156, 14, 220, 15, 32, 29, 40, 19, 7, 46, 10, 28, 18, 10, 5, 3, 150, 115, 97, 120, 120, 120, 90, 130, 97, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 76, 0, 224, 0, 156, 9, 4, 11, 156, 14, 220, 15, 32, 29, 30, 19, 7, 46, 10, 28, 18, 10, 5, 3, 150, 115, 97, 120, 120, 120, 90, 130, 97, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 76, 0, 224, 0, 156, 9, 4, 11, 156, 14, 220, 15, 32, 29, 0, 19, 7, 46, 10, 28, 18, 10, 5, 3, 150, 115, 97, 120, 120, 120, 90, 130, 97, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 65, 0, 3, 0, 5, 0, 140, 0, 224, 1, 178, 3, 84, 11, 152, 13, 104, 16, 0, 27, 35, 16, 16, 43, 23, 15, 10, 13, 7, 0, 160, 150, 120, 120, 120, 120, 145, 60, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 140, 0, 224, 1, 178, 3, 84, 11, 152, 13, 104, 16, 0, 27, 30, 20, 18, 48, 25, 17, 12, 14, 8, 0, 160, 150, 120, 120, 120, 120, 145, 60, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 140, 0, 224, 1, 178, 3, 84, 11, 152, 13, 104, 16, 0, 27, 0, 20, 18, 48, 25, 17, 12, 14, 8, 0, 160, 150, 120, 120, 120, 120, 145, 60, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 170, 0, 4, 0, 1, 0, 148, 0, 224, 1, 248, 2, 150, 10, 188, 12, 236, 14, 38, 27, 45, 52, 22, 54, 54, 36, 34, 22, 14, 6, 165, 131, 156, 120, 120, 120, 165, 110, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 148, 0, 224, 1, 248, 2, 150, 10, 188, 12, 236, 14, 38, 27, 70, 92, 30, 72, 72, 48, 46, 30, 19, 8, 165, 131, 156, 120, 120, 120, 165, 110, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 148, 0, 224, 1, 248, 2, 150, 10, 188, 12, 236, 14, 38, 27, 55, 83, 28, 68, 68, 45, 43, 28, 18, 8, 165, 131, 156, 120, 120, 120, 165, 110, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 148, 0, 224, 1, 248, 2, 150, 10, 188, 12, 236, 14, 38, 27, 0, 45, 21, 50, 50, 33, 32, 21, 13, 5, 165, 131, 156, 120, 120, 120, 165, 110, 130, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 35, 0, 3, 0, 5, 0, 224, 0, 248, 2, 140, 5, 60, 10, 20, 13, 175, 14, 117, 27, 35, 24, 21, 43, 36, 31, 26, 21, 9, 2, 196, 162, 200, 120, 120, 120, 249, 174, 255, 44, 35, 70, 130, 50, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 224, 0, 248, 2, 140, 5, 40, 10, 20, 13, 175, 14, 117, 27, 40, 22, 21, 41, 35, 30, 25, 21, 8, 2, 196, 162, 200, 120, 120, 120, 249, 174, 255, 44, 35, 70, 130, 50, 0, 0, 0, 0, 45, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 208, 0, 224, 2, 100, 5, 236, 9, 1, 13, 155, 14, 105, 27, 0, 22, 21, 42, 30, 22, 20, 20, 9, 2, 192, 158, 201, 120, 120, 120, 249, 174, 255, 44, 35, 70, 130, 52, 0, 0, 0, 0, 45, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 45, 0, 3, 0, 5, 0, 224, 0, 216, 2, 80, 5, 232, 8, 20, 13, 175, 14, 117, 27, 45, 15, 19, 32, 27, 23, 19, 16, 6, 1, 196, 162, 200, 120, 120, 120, 249, 174, 255, 44, 45, 70, 130, 46, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 5, 0, 224, 0, 216, 2, 80, 5, 232, 8, 20, 13, 175, 14, 117, 27, 35, 22, 20, 40, 34, 29, 24, 20, 8, 2, 196, 162, 200, 120, 120, 120, 249, 174, 255, 44, 45, 70, 130, 50, 0, 0, 0, 0, 45, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 224, 0, 216, 2, 80, 5, 232, 8, 20, 13, 175, 14, 117, 27, 0, 23, 21, 41, 34, 30, 25, 20, 8, 2, 196, 162, 200, 120, 120, 120, 249, 174, 255, 44, 45, 70, 130, 50, 0, 0, 0, 0, 45, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 199, 7, 49, 0, 6, 7, 6, 7, 6, 6, 3, 4, 1, 3, 232, 221, 255, 253, 1, 246, 234, 38, 20, 20, 249, 11, 15, 37, 242, 0, 223, 1, 242, 224, 248, 229, 2, 0, 244, 3, 39, 10, 27, 238, 36, 13, 2, 233, 224, 225, 240, 219, 218, 221, 237, 4, 13, 12, 25, 14, 37, 219, 243, 224, 244, 213, 217, 230, 34, 40, 20, 19, 19, 65, 20, 240, 235, 232, 251, 242, 239, 255, 19, 7, 5, 245, 254, 241, 220, 205, 220, 230, 240, 234, 228, 7, 25, 35, 19, 13, 30, 29, 24, 244, 3, 253, 247, 252, 227, 19, 2, 20, 253, 31, 12, 39, 7, 244, 247, 244, 245, 229, 202, 210, 242, 245, 238, 246, 249, 41, 32, 10, 31, 17, 28, 19, 243, 255, 2, 245, 253, 238, 0, 24, 11, 12, 24, 22, 25, 16, 243, 254, 252, 236, 232, 173, 27, 27, 7, 222, 38, 97, 105, 9, 251, 67, 56, 20, 196, 211, 0, 24, 230, 246, 1, 51, 59, 18, 10, 50, 36, 17, 222, 237, 13, 250, 216, 221, 253, 24, 17, 248, 12, 39, 30, 30, 243, 239, 192, 215, 187, 180, 173, 203, 244, 247, 25, 17, 56, 61, 58, 22, 0, 1, 225, 228, 193, 222, 230, 253, 0, 3, 20, 50, 18, 19, 10, 253, 246, 223, 203, 223, 219, 212, 238, 234, 20, 10, 20, 25, 24, 22, 8, 250, 229, 224, 228, 238, 210, 236, 233, 255, 10, 30, 19, 24, 37, 14, 6, 248, 213, 238, 211, 221, 222, 241, 0, 16, 8, 61, 48, 66, 34, 47, 21, 10, 253, 220, 221, 225, 217, 243, 2, 253, 33, 8, 44, 53, 14, 11, 254, 251, 239, 219, 214, 219, 235, 227, 244, 0, 17, 16, 24, 20, 39, 16, 1, 0, 246, 248, 253, 220, 243, 231, 10, 3, 18, 16, 54, 42, 42, 31, 17, 29, 17, 242, 252, 223, 4, 245, 1, 234, 57, 35, 22, 33, 16, 19, 6, 219, 202, 236, 193, 215, 200, 248, 22, 23, 16, 64, 52, 76, 45, 45, 67, 62, 30, 39, 19, 44, 36, 11, 25, 35, 40, 9, 226, 201, 234, 186, 152, 133, 162, 197, 193, 162, 194, 0, 7, 4, 2, 17, 39, 22, 240, 241, 245, 2, 247, 239, 16, 42, 59, 55, 57, 77, 97, 59, 41, 22, 28, 13, 239, 202, 212, 222, 210, 213, 219, 236, 247, 238, 233, 230, 208, 211, 194, 196, 186, 193, 200, 197, 205, 232, 254, 5, 9, 26, 26, 49, 21, 23, 29, 21, 39, 30, 5, 32, 33, 10, 14, 17, 15, 33, 4, 238, 7, 247, 236, 231, 225, 238, 0, 245, 223, 220, 226, 247, 242, 226, 4, 251, 19, 0, 249, 6, 19, 24, 38, 19, 49, 37, 28, 24, 11, 10, 18, 1, 15, 47, 39, 35, 28, 43, 24, 6, 251, 246, 2, 0, 223, 244, 250, 237, 240, 242, 246, 2, 249, 0, 3, 7, 7, 13, 255, 0, 0, 251, 219, 240, 245, 8, 0, 9, 36, 42, 40, 25, 14, 36, 33, 252, 5, 242, 1, 252, 250, 2, 24, 27, 47, 6, 19, 25, 254, 238, 230, 215, 222, 228, 235, 251, 17, 15, 3, 7, 5, 248, 232, 194, 200, 232, 187, 213, 196, 2, 7, 15, 1, 28, 10, 7, 241, 227, 230, 210, 214, 206, 238, 242, 233, 243, 13, 11, 27, 37, 19, 26, 7, 239, 196, 199, 180, 213, 190, 231, 253, 28, 44, 67, 54, 74, 39, 7, 2, 234, 211, 212, 212, 225, 233, 7, 10, 31, 47, 59, 48, 58, 9, 2, 243, 213, 220, 213, 201, 232, 244, 0, 2, 14, 32, 31, 35, 254, 250, 229, 208, 215, 189, 207, 223, 244, 20, 18, 44, 59, 37, 27, 40, 25, 29, 254, 242, 248, 248, 14, 8, 20, 45, 57, 74, 59, 71, 79, 72, 37, 21, 5, 242, 244, 248, 9, 10, 41, 43, 55, 54, 63, 48, 37, 30, 6, 252, 239, 206, 231, 227, 219, 252, 12, 10, 35, 30, 49, 40, 39, 35, 18, 25, 5, 1, 237, 230, 228, 218, 224, 225, 231, 251, 253, 224, 233, 224, 233, 207, 204, 192, 223, 200, 195, 201, 218, 217, 216, 233, 233, 237, 244, 236, 6, 6, 246, 8, 7, 13, 28, 13, 23, 31, 33, 43, 23, 28, 31, 38, 33, 7, 25, 247, 2, 247, 249, 231, 246, 244, 244, 237, 252, 4, 0, 248, 255, 10, 253, 243, 251, 234, 254, 237, 235, 226, 243, 224, 247, 239, 2, 1, 4, 12, 8, 8, 251, 247, 250, 245, 243, 236, 247, 0, 2, 247, 3, 245, 249, 243, 229, 236, 227, 237, 236, 253, 244, 3, 5, 7, 10, 14, 8, 254, 11, 8, 34, 18, 25, 16, 47, 28, 37, 18, 22, 28, 35, 30, 36, 41, 26, 34, 39, 25, 34, 24, 245, 0, 20, 228, 252, 220, 231, 252, 233, 214, 249, 232, 237, 243, 234, 250, 243, 206, 235, 221, 237, 243, 224, 238, 0, 0, 6, 246, 252, 12, 21, 25, 9, 17, 6, 5, 7, 241, 254, 238, 236, 242, 243, 5, 248, 253, 252, 0, 237, 251, 223, 250, 217, 237, 228, 226, 243, 239, 12, 2, 23, 9, 37, 37, 19, 25, 4, 19, 255, 0, 248, 249, 248, 3, 235, 246, 255, 249, 239, 249, 18, 17, 14, 8, 16, 10, 7, 248, 0, 255, 251, 254, 16, 4, 8, 22, 28, 33, 28, 26, 39, 30, 36, 38, 48, 43, 48, 72, 25, 48, 39, 49, 47, 33, 37, 40, 15, 17, 251, 255, 241, 218, 223, 213, 206, 221, 217, 226, 209, 238, 241, 0, 247, 253, 232, 241, 242, 244, 235, 240, 0, 12, 2, 36, 14, 13, 27, 8, 6, 1, 231, 232, 226, 223, 236, 204, 251, 215, 239, 252, 242, 251, 236, 238, 249, 209, 220, 202, 189, 203, 196, 193, 208, 210, 236, 228, 10, 255, 14, 12, 9, 8, 248, 6, 0, 254, 248, 8, 27, 31, 23, 48, 66, 64, 77, 44, 60, 31, 53, 4, 29, 11, 13, 26, 18, 18, 21, 26, 29, 20, 25, 24, 20, 7, 9, 18, 14, 237, 19, 253, 255, 247, 250, 252, 6, 0, 252, 8, 245, 17, 4, 14, 13, 30, 252, 25, 254, 6, 17, 229, 4, 243, 238, 250, 239, 250, 234, 248, 238, 249, 243, 243, 252, 244, 254, 244, 1, 249, 248, 230, 253, 239, 241, 244, 242, 251, 9, 244, 248, 5, 6, 254, 231, 223, 237, 211, 215, 209, 229, 241, 229, 232, 239, 227, 246, 221, 232, 231, 232, 232, 224, 238, 247, 253, 242, 0, 8, 9, 251, 254, 0, 11, 251, 248, 6, 5, 9, 1, 4, 10, 7, 16, 12, 9, 13, 23, 13, 19, 25, 18, 25, 25, 31, 33, 17, 13, 27, 5, 35, 8, 27, 26, 38, 22, 26, 8, 19, 1, 8, 252, 253, 4, 254, 253, 7, 11, 17, 4, 15, 35, 7, 16, 22, 17, 24, 15, 13, 31, 14, 28, 21, 16, 14, 4, 17, 0, 254, 5, 2, 11, 255, 9, 0, 246, 0, 0, 0, 243, 238, 251, 248, 234, 242, 255, 249, 246, 251, 2, 0, 247, 239, 5, 239, 229, 242, 227, 243, 217, 219, 228, 217, 226, 227, 224, 242, 227, 249, 250, 226, 255, 247, 243, 249, 238, 10, 238, 238, 242, 232, 252, 228, 229, 0, 242, 0, 254, 6, 20, 251, 22, 28, 18, 30, 24, 25, 21, 14, 26, 6, 22, 7, 19, 34, 22, 28, 22, 24, 23, 8, 16, 25, 12, 16, 15, 10, 12, 4, 7, 3, 12, 1, 9, 3, 247, 1, 251, 247, 254, 246, 248, 249, 229, 249, 231, 244, 239, 246, 253, 252, 0, 0, 0, 247, 251, 246, 248, 241, 236, 245, 225, 221, 244, 226, 238, 246, 241, 255, 6, 6, 22, 1, 18, 18, 11, 18, 3, 22, 10, 5, 22, 5, 251, 2, 231, 249, 248, 240, 0, 253, 8, 27, 15, 23, 30, 27, 29, 16, 11, 10, 253, 247, 237, 241, 235, 227, 231, 233, 234, 249, 253, 0, 9, 254, 6, 3, 255, 9, 250, 248, 246, 252, 243, 235, 239, 234, 2, 233, 238, 251, 253, 244, 250, 243, 5, 14, 249, 16, 9, 13, 9, 7, 20, 11, 16, 7, 9, 9, 0, 254, 243, 244, 4, 0, 251, 17, 16, 23, 26, 13, 35, 30, 16, 21, 19, 28, 25, 19, 32, 27, 33, 28, 28, 33, 25, 11, 11, 7, 5, 252, 245, 251, 0, 253, 253, 252, 254, 252, 249, 253, 244, 255, 246, 254, 244, 4, 251, 254, 237, 244, 254, 245, 253, 252, 5, 1, 2, 1, 12, 254, 236, 235, 229, 225, 223, 218, 233, 224, 239, 247, 253, 249, 253, 254, 252, 248, 3, 255, 248, 248, 251, 0, 252, 2, 253, 3, 251, 1, 254, 3, 255, 5, 248, 23, 6, 1, 251, 250, 249, 242, 238, 239, 248, 232, 240, 251, 255, 8, 3, 10, 5, 1, 2, 254, 253, 250, 4, 254, 0, 247, 255, 239, 255, 0, 22, 4, 17, 20, 20, 14, 17, 24, 23, 8, 5, 5, 254, 239, 231, 235, 239, 245, 248, 6, 9, 15, 4, 14, 1, 14, 0, 0, 0, 11, 7, 12, 0, 13, 10, 10, 6, 17, 12, 16, 2, 17, 14, 22, 10, 7, 13, 0, 254, 239, 254, 235, 243, 239, 255, 255, 1, 253, 10, 255, 15, 13, 25, 16, 21, 17, 11, 0, 0, 2, 244, 247, 0, 13, 252, 0, 6, 9, 3, 252, 15, 8, 253, 250, 254, 253, 235, 243, 238, 243, 230, 248, 244, 239, 241, 0, 0, 254, 6, 25, 12, 0, 9, 11, 7, 242, 2, 2, 1, 241, 255, 249, 246, 237, 244, 247, 248, 247, 252, 247, 247, 0, 248, 2, 252, 17, 0, 255, 255, 255, 254, 237, 2, 4, 0, 8, 3, 18, 254, 1, 246, 255, 248, 0, 254, 0, 3, 2, 3, 0, 9, 1, 3, 248, 3, 251, 246, 238, 244, 243, 239, 245, 250, 7, 2, 11, 11, 16, 21, 17, 22, 12, 20, 2, 3, 241, 242, 244, 239, 242, 240, 255, 246, 251, 243, 2, 255, 0, 246, 1, 4, 1, 254, 255, 5, 5, 4, 0, 14, 11, 14, 3, 9, 10, 252, 248, 248, 254, 242, 244, 252, 244, 252, 246, 3, 248, 0, 7, 9, 4, 10, 20, 8, 4, 0, 10, 251, 252, 253, 253, 252, 254, 252, 249, 253, 244, 255, 246, 254, 244, 4, 251, 254, 237, 244, 254, 245, 253, 252, 5, 1, 2, 1, 12, 254, 236, 235, 229, 225, 223, 218, 233, 224, 239, 247, 253, 249, 253, 254, 252, 248, 3, 255, 248, 248, 251, 0, 252, 2, 253, 3, 251, 1, 254, 3, 255, 5, 248, 23, 6, 1, 251, 250, 249, 242, 238, 239, 248, 232, 240, 251, 255, 8, 3, 10, 5, 1, 2, 254, 253, 250, 4, 254, 0, 247, 255, 239, 255, 0, 22, 4, 17, 20, 20, 14, 17, 24, 23, 8, 5, 5, 254, 239, 231, 235, 239, 245, 248, 6, 9, 15, 4, 14, 1, 14, 0, 0, 0, 11, 7, 12, 0, 13, 10, 10, 6, 17, 12, 16, 2, 17, 14, 22, 10, 7, 13, 0, 254, 239, 254, 235, 243, 239, 255, 255, 1, 253, 10, 255, 15, 13, 25, 16, 21, 17, 11, 0, 0, 2, 244, 247, 0, 13, 252, 0, 6, 9, 3, 252, 15, 8, 253, 250, 254, 253, 235, 243, 238, 243, 230, 248, 244, 239, 241, 0, 0, 254, 6, 25, 12, 0, 9, 11, 7, 242, 2, 2, 1, 241, 255, 249, 246, 237, 244, 247, 248, 247, 252, 247, 247, 0, 248, 2, 252, 17, 0, 255, 255, 255, 254, 237, 2, 4, 0, 8, 3, 18, 254, 1, 246, 255, 248, 0, 254, 0, 3, 2, 3, 0, 9, 1, 0, 0, 7, 15, 22, 29, 36, 43, 50, 57, 63, 70, 76, 83, 89, 95, 101, 107, 112, 118, 123, 129, 134, 139, 144, 149, 153, 158, 162, 167, 171, 175, 179, 183, 187, 190, 194, 197, 201, 204, 207, 210, 213, 215, 218, 220, 223, 225, 227, 229, 231, 232, 234, 236, 237, 238, 239, 240, 241, 242, 243, 243, 244, 244, 244, 244, 244, 244, 244, 243, 243, 242, 241, 240, 239, 238, 237, 236, 234, 232, 231, 229, 227, 225, 223, 220, 218, 215, 213, 210, 207, 204, 201, 197, 194, 190, 187, 183, 179, 175, 171, 167, 162, 158, 153, 149, 144, 139, 134, 129, 123, 118, 112, 107, 101, 95, 89, 83, 76, 70, 63, 57, 50, 43, 36, 29, 22, 15, 7, 0, 0, 6, 0, 1, 0, 204, 0, 158, 2, 252, 4, 60, 10, 168, 12, 10, 15, 0, 28, 40, 47, 32, 52, 71, 39, 47, 23, 13, 7, 170, 165, 150, 120, 120, 120, 170, 180, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 204, 0, 93, 2, 208, 4, 60, 10, 168, 12, 10, 15, 0, 28, 50, 115, 45, 89, 101, 56, 67, 33, 20, 8, 170, 165, 150, 120, 120, 120, 170, 180, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 204, 0, 93, 2, 208, 4, 60, 10, 168, 12, 10, 15, 0, 28, 30, 104, 42, 84, 96, 53, 64, 32, 19, 8, 170, 165, 150, 120, 120, 120, 170, 180, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 190, 0, 32, 2, 242, 5, 84, 10, 240, 12, 236, 14, 9, 28, 75, 69, 37, 71, 77, 51, 55, 30, 15, 7, 169, 142, 163, 120, 120, 120, 170, 180, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 156, 0, 144, 1, 152, 8, 140, 10, 152, 13, 166, 14, 32, 28, 30, 37, 31, 54, 47, 57, 44, 32, 10, 8, 167, 90, 195, 120, 120, 120, 122, 120, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 156, 0, 144, 1, 174, 8, 160, 10, 92, 13, 10, 15, 32, 28, 0, 31, 31, 49, 49, 45, 42, 33, 9, 8, 167, 90, 135, 120, 120, 120, 122, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 22, 21, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 254, 255, 255, 254, 253, 251, 249, 245, 238, 230, 224, 229, 251, 22, 38, 34, 17, 252, 234, 229, 235, 252, 10, 15, 20, 16, 5, 250, 236, 241, 247, 254, 12, 15, 16, 3, 244, 232, 235, 254, 11, 24, 26, 27, 17, 250, 243, 242, 251, 1, 247, 239, 244, 4, 7, 234, 201, 193, 236, 60, 94, 65, 11, 222, 209, 192, 184, 221, 27, 76, 64, 17, 235, 218, 205, 200, 222, 14, 62, 62, 32, 1, 238, 233, 228, 239, 6, 26, 16, 5, 8, 239, 1, 11, 1, 28, 250, 249, 2, 223, 246, 247, 254, 35, 17, 3, 250, 221, 235, 241, 232, 251, 0, 27, 40, 10, 5, 242, 218, 231, 248, 13, 30, 26, 11, 248, 237, 236, 240, 2, 19, 19, 8, 250, 244, 237, 233, 249, 7, 20, 29, 22, 0, 240, 238, 245, 247, 248, 5, 27, 37, 23, 253, 242, 239, 248, 1, 249, 233, 234, 40, 82, 39, 234, 205, 234, 253, 248, 3, 8, 31, 31, 245, 251, 252, 233, 249, 248, 12, 25, 5, 8, 249, 240, 253, 244, 7, 34, 18, 8, 249, 236, 243, 250, 18, 18, 1, 11, 4, 7, 27, 4, 233, 228, 234, 26, 48, 25, 14, 0, 3, 5, 234, 219, 246, 33, 49, 30, 253, 237, 232, 231, 239, 249, 36, 65, 16, 223, 219, 249, 26, 19, 246, 238, 5, 30, 25, 13, 4, 252, 1, 253, 230, 245, 20, 20, 4, 247, 9, 38, 41, 13, 224, 219, 229, 203, 203, 252, 43, 65, 46, 8, 245, 224, 199, 201, 231, 14, 36, 37, 23, 253, 241, 228, 220, 254, 15, 11, 18, 12, 9, 3, 241, 239, 251, 252, 240, 242, 3, 17, 10, 254, 252, 0, 7, 255, 242, 240, 242, 249, 11, 20, 0, 237, 237, 250, 6, 9, 1, 2, 7, 247, 234, 247, 9, 9, 1, 0, 2, 252, 236, 236, 252, 10, 11, 0, 0, 2, 254, 244, 232, 239, 252, 250, 255, 15, 9, 247, 242, 252, 5, 4, 250, 0, 14, 1, 243, 234, 242, 18, 22, 255, 244, 249, 14, 32, 4, 221, 226, 252, 13, 14, 10, 20, 24, 4, 242, 236, 244, 252, 1, 16, 21, 27, 14, 243, 248, 0, 243, 247, 13, 19, 14, 3, 250, 3, 18, 3, 247, 254, 0, 20, 20, 247, 249, 5, 5, 0, 252, 8, 18, 253, 249, 3, 3, 20, 17, 7, 16, 13, 247, 233, 240, 250, 26, 42, 3, 240, 245, 250, 12, 18, 10, 5, 253, 6, 6, 244, 241, 251, 16, 12, 253, 4, 8, 1, 239, 224, 5, 39, 18, 4, 0, 245, 255, 0, 246, 2, 24, 21, 18, 22, 15, 244, 208, 227, 19, 24, 11, 17, 2, 230, 0, 246, 217, 19, 28, 17, 21, 246, 245, 236, 239, 245, 1, 56, 61, 6, 240, 240, 212, 253, 22, 247, 24, 33, 34, 3, 214, 239, 218, 251, 58, 31, 39, 43, 220, 170, 1, 35, 5, 27, 0, 10, 32, 5, 7, 248, 228, 254, 29, 29, 23, 238, 227, 24, 7, 213, 207, 226, 17, 66, 61, 7, 229, 249, 12, 4, 2, 3, 6, 32, 19, 226, 220, 1, 8, 245, 24, 31, 9, 29, 255, 220, 237, 2, 249, 232, 24, 52, 7, 248, 5, 0, 4, 3, 220, 240, 45, 37, 0, 254, 5, 249, 241, 229, 217, 250, 10, 247, 247, 13, 15, 244, 244, 249, 214, 217, 9, 8, 243, 252, 246, 245, 3, 241, 220, 225, 2, 16, 255, 11, 255, 221, 240, 255, 9, 31, 4, 213, 220, 252, 1, 1, 5, 16, 36, 14, 213, 193, 232, 26, 33, 16, 6, 242, 240, 5, 250, 218, 223, 7, 35, 7, 242, 3, 3, 247, 228, 227, 1, 22, 15, 244, 237, 248, 252, 245, 255, 15, 1, 0, 246, 227, 249, 4, 2, 6, 13, 13, 3, 242, 228, 246, 248, 14, 43, 12, 4, 242, 219, 233, 248, 17, 17, 26, 25, 253, 246, 243, 8, 253, 229, 11, 16, 5, 32, 30, 246, 232, 227, 242, 22, 12, 35, 56, 1, 241, 1, 11, 250, 232, 250, 28, 50, 250, 228, 11, 22, 9, 219, 217, 29, 61, 2, 223, 255, 8, 5, 239, 212, 22, 87, 27, 218, 223, 0, 24, 4, 228, 253, 79, 89, 235, 169, 233, 48, 17, 205, 241, 76, 83, 23, 201, 183, 223, 19, 57, 16, 17, 49, 3, 237, 247, 244, 0, 0, 9, 53, 25, 226, 239, 13, 47, 56, 247, 213, 4, 6, 223, 218, 235, 51, 122, 57, 223, 233, 6, 251, 200, 181, 6, 81, 62, 0, 237, 10, 18, 250, 220, 232, 2, 11, 36, 16, 248, 22, 21, 248, 0, 10, 1, 252, 246, 241, 209, 207, 11, 66, 96, 37, 208, 225, 249, 234, 224, 220, 21, 84, 72, 58, 27, 220, 201, 209, 228, 22, 37, 8, 242, 8, 36, 245, 215, 229, 218, 248, 23, 19, 10, 248, 244, 248, 2, 241, 232, 15, 2, 232, 1, 25, 9, 237, 206, 212, 17, 33, 4, 246, 221, 194, 207, 255, 31, 37, 10, 249, 240, 204, 215, 237, 249, 22, 25, 45, 16, 215, 210, 209, 236, 8, 13, 21, 40, 12, 213, 202, 209, 12, 29, 8, 11, 249, 6, 232, 186, 234, 24, 38, 38, 255, 226, 238, 230, 238, 244, 0, 45, 23, 8, 4, 226, 243, 9, 255, 242, 14, 37, 7, 240, 220, 220, 23, 46, 0, 0, 11, 2, 227, 195, 248, 21, 33, 47, 13, 7, 221, 199, 243, 24, 62, 38, 8, 0, 239, 253, 250, 224, 236, 24, 66, 54, 241, 227, 2, 250, 249, 252, 250, 21, 32, 11, 246, 241, 246, 243, 242, 1, 55, 66, 245, 188, 193, 2, 56, 40, 15, 17, 28, 245, 199, 203, 234, 22, 49, 45, 31, 35, 23, 224, 183, 202, 0, 52, 80, 31, 230, 245, 0, 234, 228, 247, 8, 48, 60, 249, 222, 236, 255, 21, 0, 23, 55, 0, 223, 189, 188, 32, 89, 50, 224, 217, 20, 7, 220, 191, 251, 75, 40, 1, 249, 252, 252, 234, 252, 19, 30, 35, 250, 236, 8, 12, 25, 249, 215, 239, 7, 21, 255, 2, 47, 43, 242, 207, 243, 17, 0, 221, 226, 54, 104, 34, 185, 166, 0, 65, 12, 209, 250, 47, 30, 240, 229, 19, 23, 246, 231, 233, 31, 49, 245, 193, 212, 52, 89, 249, 185, 254, 44, 23, 3, 238, 237, 254, 12, 4, 243, 15, 15, 253, 253, 221, 246, 255, 229, 253, 14, 45, 23, 206, 159, 173, 251, 57, 101, 70, 239, 196, 209, 250, 4, 247, 241, 9, 5, 228, 212, 219, 25, 39, 245, 234, 22, 54, 0, 194, 204, 11, 46, 2, 216, 223, 251, 36, 32, 210, 189, 13, 50, 7, 210, 203, 13, 35, 254, 242, 245, 35, 50, 249, 221, 231, 12, 47, 1, 175, 177, 8, 95, 97, 11, 208, 206, 215, 233, 9, 49, 61, 54, 12, 223, 207, 198, 235, 44, 80, 44, 249, 8, 13, 226, 195, 221, 33, 77, 69, 12, 218, 222, 224, 226, 8, 38, 35, 24, 19, 17, 232, 186, 215, 1, 53, 76, 3, 217, 252, 19, 5, 215, 206, 54, 114, 28, 205, 195, 239, 28, 30, 25, 6, 230, 246, 10, 254, 18, 40, 18, 242, 200, 202, 244, 16, 56, 62, 25, 2, 212, 199, 9, 35, 23, 29, 29, 9, 231, 230, 253, 237, 0, 60, 55, 254, 237, 12, 252, 229, 248, 250, 6, 41, 40, 3, 236, 215, 246, 34, 234, 214, 21, 84, 72, 252, 195, 184, 7, 44, 250, 234, 9, 68, 34, 210, 213, 238, 20, 29, 238, 246, 31, 33, 254, 221, 237, 2, 12, 250, 245, 47, 66, 13, 229, 214, 191, 240, 64, 58, 34, 7, 1, 37, 252, 166, 174, 253, 65, 61, 26, 56, 29, 206, 188, 188, 231, 250, 9, 108, 112, 18, 211, 181, 213, 252, 0, 35, 76, 22, 227, 225, 201, 244, 47, 47, 26, 0, 0, 242, 238, 248, 239, 9, 27, 0, 245, 12, 34, 24, 229, 193, 221, 250, 17, 16, 247, 247, 255, 251, 226, 197, 213, 24, 56, 10, 247, 255, 237, 231, 223, 248, 47, 28, 4, 6, 2, 1, 237, 241, 11, 4, 236, 8, 47, 1, 217, 228, 253, 17, 7, 7, 16, 241, 219, 235, 234, 221, 248, 25, 27, 2, 230, 228, 245, 252, 254, 253, 249, 254, 253, 249, 246, 0, 18, 12, 254, 236, 240, 6, 4, 250, 246, 2, 19, 9, 246, 233, 236, 251, 7, 8, 249, 246, 245, 252, 0, 234, 245, 5, 0, 15, 11, 237, 233, 1, 28, 20, 251, 243, 230, 248, 39, 30, 235, 236, 23, 36, 241, 223, 11, 23, 18, 253, 252, 9, 251, 0, 243, 2, 16, 242, 12, 17, 247, 230, 230, 20, 45, 27, 231, 197, 240, 21, 12, 8, 9, 33, 42, 240, 210, 219, 14, 47, 14, 3, 248, 5, 38, 5, 194, 202, 39, 48, 236, 232, 8, 24, 255, 202, 229, 48, 60, 12, 208, 221, 6, 5, 18, 26, 20, 10, 221, 221, 9, 28, 20, 7, 18, 26, 13, 237, 227, 6, 32, 17, 0, 5, 6, 28, 23, 235, 227, 18, 48, 250, 229, 10, 47, 52, 243, 223, 3, 33, 40, 244, 219, 253, 18, 24, 1, 245, 35, 34, 231, 221, 5, 24, 227, 206, 249, 62, 112, 32, 195, 208, 14, 22, 239, 246, 13, 21, 25, 15, 250, 7, 18, 254, 237, 223, 13, 55, 8, 188, 192, 6, 33, 34, 10, 231, 250, 27, 0, 200, 219, 26, 49, 25, 2, 233, 219, 247, 17, 13, 4, 3, 240, 250, 15, 0, 242, 225, 231, 242, 241, 17, 43, 9, 216, 225, 8, 10, 219, 198, 224, 11, 50, 19, 244, 252, 240, 215, 199, 231, 28, 33, 0, 249, 255, 230, 231, 248, 242, 1, 4, 239, 247, 252, 251, 249, 225, 240, 254, 235, 244, 6, 23, 19, 255, 230, 201, 228, 17, 20, 249, 235, 2, 20, 9, 221, 210, 255, 21, 17, 4, 236, 234, 245, 230, 243, 6, 255, 4, 250, 234, 243, 245, 233, 237, 2, 8, 7, 238, 221, 251, 11, 246, 232, 253, 11, 23, 2, 213, 225, 247, 17, 21, 241, 0, 12, 250, 1, 245, 229, 224, 1, 52, 24, 1, 234, 231, 8, 241, 243, 250, 18, 48, 0, 252, 251, 236, 253, 243, 4, 19, 38, 54, 242, 206, 233, 0, 5, 2, 31, 23, 32, 44, 233, 210, 232, 13, 12, 254, 23, 14, 3, 244, 240, 17, 29, 25, 8, 233, 230, 239, 20, 70, 21, 239, 16, 6, 5, 24, 4, 2, 11, 1, 7, 25, 31, 17, 240, 210, 255, 53, 50, 31, 0, 0, 14, 13, 0, 237, 6, 41, 48, 27, 250, 235, 242, 16, 35, 24, 9, 17, 21, 248, 224, 207, 245, 80, 78, 33, 22, 251, 237, 214, 215, 26, 32, 27, 58, 49, 19, 218, 167, 180, 247, 66, 94, 50, 244, 254, 12, 227, 214, 253, 27, 10, 243, 3, 62, 88, 34, 209, 177, 236, 40, 35, 4, 240, 248, 8, 247, 234, 254, 249, 253, 11, 7, 15, 237, 195, 215, 7, 33, 20, 15, 2, 255, 1, 221, 207, 237, 4, 16, 13, 8, 17, 7, 226, 207, 223, 252, 254, 251, 19, 22, 16, 14, 230, 205, 217, 242, 3, 246, 6, 24, 4, 249, 229, 216, 214, 243, 26, 24, 1, 228, 233, 251, 242, 238, 244, 250, 250, 253, 12, 20, 241, 199, 202, 249, 39, 4, 218, 234, 253, 254, 213, 197, 229, 10, 25, 2, 248, 229, 210, 225, 0, 1, 232, 7, 23, 0, 7, 246, 215, 217, 255, 20, 249, 2, 1, 244, 23, 248, 226, 0, 248, 6, 5, 236, 243, 6, 18, 246, 219, 242, 3, 17, 19, 237, 245, 252, 230, 249, 245, 0, 31, 23, 5, 220, 211, 246, 0, 16, 24, 34, 16, 215, 212, 226, 19, 39, 255, 29, 25, 9, 254, 206, 231, 254, 28, 41, 4, 25, 13, 4, 254, 209, 215, 0, 60, 59, 14, 255, 15, 29, 221, 209, 18, 29, 12, 9, 17, 3, 243, 252, 251, 12, 35, 5, 254, 5, 237, 250, 250, 247, 36, 22, 244, 3, 21, 5, 241, 244, 0, 24, 20, 0, 254, 251, 39, 42, 244, 235, 246, 8, 13, 15, 10, 246, 1, 14, 15, 5, 248, 252, 32, 40, 217, 201, 15, 39, 18, 250, 5, 15, 238, 225, 250, 14, 16, 9, 3, 4, 255, 2, 10, 255, 250, 237, 242, 255, 6, 47, 50, 9, 228, 197, 217, 19, 45, 27, 252, 245, 252, 244, 243, 253, 244, 251, 30, 32, 236, 198, 226, 2, 13, 13, 0, 3, 24, 11, 223, 222, 0, 254, 248, 6, 5, 255, 253, 22, 35, 248, 238, 229, 201, 251, 17, 4, 10, 250, 9, 24, 238, 191, 204, 6, 44, 35, 246, 226, 241, 7, 251, 211, 224, 4, 22, 17, 0, 246, 228, 243, 4, 239, 239, 3, 14, 6, 245, 239, 224, 226, 0, 9, 10, 19, 6, 241, 231, 226, 234, 3, 13, 4, 254, 255, 252, 246, 241, 221, 230, 13, 13, 0, 0, 243, 247, 255, 239, 233, 241, 17, 31, 253, 236, 238, 0, 17, 2, 219, 223, 19, 22, 2, 0, 227, 221, 20, 18, 241, 247, 237, 1, 14, 238, 244, 13, 9, 231, 237, 7, 7, 15, 254, 243, 11, 21, 243, 222, 244, 8, 31, 32, 8, 247, 251, 255, 228, 237, 21, 27, 23, 0, 248, 13, 244, 220, 245, 10, 25, 32, 26, 3, 231, 226, 246, 25, 21, 237, 249, 32, 27, 7, 247, 249, 7, 235, 223, 10, 33, 30, 17, 239, 252, 45, 23, 234, 228, 253, 27, 31, 24, 11, 254, 244, 236, 9, 37, 17, 0, 255, 16, 32, 7, 245, 3, 30, 41, 12, 255, 12, 26, 15, 221, 236, 37, 24, 0, 6, 22, 39, 20, 235, 231, 15, 41, 20, 253, 13, 20, 5, 255, 244, 17, 32, 251, 236, 6, 33, 32, 16, 8, 9, 245, 235, 251, 3, 32, 32, 5, 5, 1, 250, 253, 243, 243, 25, 55, 41, 5, 245, 238, 215, 217, 10, 51, 43, 16, 5, 0, 236, 227, 238, 1, 14, 15, 23, 4, 241, 242, 247, 2, 13, 22, 8, 237, 229, 3, 28, 14, 255, 238, 249, 19, 22, 4, 233, 250, 17, 7, 245, 238, 3, 31, 24, 234, 226, 9, 36, 13, 218, 223, 23, 41, 253, 229, 243, 2, 20, 248, 228, 12, 11, 247, 248, 255, 1, 247, 254, 1, 14, 20, 247, 248, 18, 4, 230, 247, 247, 245, 39, 24, 243, 241, 248, 9, 254, 254, 1, 2, 13, 246, 232, 244, 249, 0, 17, 24, 5, 238, 240, 14, 2, 219, 233, 26, 52, 13, 236, 230, 245, 17, 249, 234, 250, 24, 50, 3, 230, 235, 241, 3, 7, 20, 24, 12, 250, 225, 241, 12, 12, 0, 238, 251, 17, 3, 251, 244, 2, 15, 250, 251, 3, 2, 2, 9, 6, 250, 247, 246, 2, 2, 4, 14, 253, 245, 252, 5, 248, 234, 246, 252, 24, 37, 8, 227, 225, 15, 8, 230, 247, 27, 40, 11, 238, 235, 2, 14, 240, 222, 3, 43, 19, 229, 240, 24, 23, 254, 246, 3, 11, 252, 241, 248, 8, 6, 4, 16, 6, 1, 5, 245, 244, 251, 255, 7, 6, 21, 24, 9, 248, 227, 254, 16, 245, 237, 6, 36, 30, 251, 230, 240, 252, 4, 6, 1, 12, 32, 22, 239, 224, 249, 22, 20, 244, 252, 31, 29, 13, 253, 241, 244, 3, 23, 13, 0, 3, 5, 22, 26, 255, 243, 255, 10, 14, 0, 250, 5, 13, 24, 25, 5, 255, 20, 23, 230, 200, 236, 39, 58, 20, 245, 9, 26, 0, 228, 216, 246, 31, 26, 1, 0, 23, 15, 246, 241, 250, 10, 18, 7, 3, 12, 6, 244, 237, 0, 25, 16, 1, 2, 1, 2, 3, 7, 5, 255, 253, 244, 3, 34, 25, 0, 238, 236, 10, 27, 2, 231, 255, 29, 20, 1, 237, 247, 21, 16, 254, 246, 246, 8, 19, 3, 250, 239, 242, 12, 18, 1, 248, 250, 10, 15, 0, 239, 244, 17, 11, 246, 249, 248, 3, 10, 252, 2, 12, 255, 251, 2, 251, 246, 252, 255, 5, 9, 6, 0, 252, 240, 234, 0, 30, 27, 248, 231, 240, 5, 13, 238, 228, 3, 20, 22, 7, 233, 233, 255, 255, 255, 255, 253, 12, 13, 2, 238, 227, 255, 1, 252, 8, 19, 24, 243, 225, 2, 0, 240, 242, 250, 13, 17, 7, 17, 6, 224, 232, 249, 241, 9, 18, 5, 10, 6, 4, 246, 240, 11, 3, 242, 251, 244, 17, 45, 255, 230, 247, 8, 12, 230, 218, 15, 56, 26, 227, 223, 0, 14, 2, 238, 236, 17, 39, 4, 244, 3, 0, 251, 240, 229, 252, 16, 24, 20, 243, 226, 245, 252, 2, 2, 240, 247, 21, 35, 16, 241, 237, 239, 233, 250, 16, 34, 33, 253, 240, 4, 4, 246, 243, 249, 3, 19, 20, 15, 1, 243, 0, 0, 238, 246, 17, 21, 1, 251, 248, 6, 10, 239, 242, 7, 14, 7, 250, 246, 254, 9, 0, 243, 246, 3, 18, 9, 250, 244, 247, 249, 252, 6, 8, 9, 7, 253, 251, 254, 255, 251, 247, 0, 11, 8, 1, 4, 0, 242, 241, 254, 18, 25, 11, 245, 243, 6, 9, 252, 237, 254, 29, 23, 250, 237, 255, 14, 2, 235, 240, 24, 41, 13, 239, 232, 246, 0, 6, 13, 19, 20, 14, 255, 240, 246, 249, 249, 2, 15, 33, 28, 4, 236, 233, 255, 5, 0, 0, 14, 26, 12, 5, 0, 239, 252, 9, 10, 17, 6, 0, 10, 3, 1, 1, 245, 245, 1, 14, 17, 13, 5, 253, 253, 254, 245, 243, 5, 24, 22, 8, 1, 249, 232, 223, 239, 17, 37, 25, 252, 235, 240, 255, 6, 248, 245, 12, 23, 13, 2, 247, 242, 238, 237, 1, 14, 9, 22, 23, 251, 234, 230, 237, 6, 21, 13, 0, 9, 16, 255, 244, 239, 241, 242, 6, 27, 18, 24, 7, 232, 231, 234, 255, 18, 17, 22, 11, 239, 231, 239, 252, 17, 23, 2, 0, 5, 250, 237, 229, 249, 21, 25, 7, 251, 10, 8, 251, 249, 228, 222, 4, 38, 29, 10, 250, 245, 251, 248, 0, 9, 12, 16, 4, 4, 7, 231, 216, 250, 23, 26, 21, 5, 238, 245, 253, 248, 250, 243, 1, 17, 20, 10, 232, 243, 249, 233, 14, 30, 12, 1, 249, 248, 0, 16, 2, 249, 6, 9, 5, 241, 247, 6, 246, 247, 255, 2, 10, 4, 255, 253, 3, 3, 246, 240, 249, 19, 26, 250, 240, 255, 1, 254, 250, 254, 3, 17, 8, 231, 245, 10, 4, 7, 6, 4, 9, 254, 235, 244, 16, 31, 8, 238, 250, 17, 16, 245, 234, 249, 0, 7, 12, 6, 0, 247, 244, 249, 1, 9, 3, 251, 2, 7, 254, 244, 248, 0, 1, 8, 6, 252, 245, 247, 0, 9, 9, 252, 235, 240, 9, 20, 3, 242, 253, 9, 252, 240, 249, 14, 17, 251, 240, 251, 9, 15, 255, 239, 252, 7, 249, 249, 1, 1, 8, 6, 247, 240, 254, 13, 9, 252, 243, 249, 0, 4, 10, 7, 2, 0, 253, 245, 241, 253, 5, 5, 2, 249, 2, 12, 0, 247, 243, 252, 11, 7, 247, 248, 5, 5, 0, 0, 0, 246, 246, 6, 21, 18, 254, 247, 246, 241, 249, 251, 0, 9, 19, 19, 0, 246, 244, 251, 249, 238, 248, 12, 30, 19, 242, 238, 252, 253, 250, 1, 8, 12, 12, 0, 248, 4, 0, 230, 233, 10, 24, 18, 255, 247, 0, 1, 243, 232, 255, 21, 19, 7, 249, 2, 9, 249, 232, 242, 12, 11, 244, 248, 18, 21, 1, 245, 243, 249, 253, 0, 0, 8, 13, 255, 251, 251, 249, 251, 254, 4, 4, 8, 2, 248, 255, 0, 0, 9, 3, 243, 245, 5, 14, 6, 248, 0, 5, 251, 249, 250, 1, 9, 7, 0, 246, 247, 1, 3, 7, 253, 250, 6, 248, 242, 0, 1, 18, 17, 247, 246, 4, 9, 250, 232, 239, 12, 33, 24, 6, 247, 245, 248, 246, 255, 7, 9, 16, 26, 22, 253, 224, 224, 245, 3, 21, 14, 5, 19, 5, 249, 240, 228, 244, 18, 27, 5, 2, 255, 248, 5, 4, 2, 1, 10, 21, 254, 234, 255, 18, 8, 6, 14, 4, 1, 1, 246, 247, 255, 0, 255, 13, 28, 10, 247, 235, 232, 246, 8, 34, 31, 0, 247, 242, 242, 252, 251, 1, 20, 18, 255, 240, 246, 255, 3, 5, 0, 252, 253, 5, 11, 255, 240, 251, 14, 7, 248, 0, 15, 4, 241, 239, 252, 15, 10, 247, 251, 254, 0, 11, 0, 239, 248, 255, 255, 1, 249, 250, 10, 14, 0, 238, 246, 0, 252, 251, 1, 8, 5, 254, 246, 249, 2, 255, 248, 249, 0, 10, 15, 251, 234, 252, 8, 254, 243, 245, 5, 18, 10, 248, 243, 0, 5, 245, 238, 254, 11, 17, 6, 249, 249, 253, 248, 239, 247, 8, 12, 5, 253, 0, 5, 250, 238, 242, 2, 14, 7, 0, 1, 0, 246, 238, 249, 7, 9, 7, 1, 1, 0, 240, 239, 252, 2, 12, 13, 9, 0, 246, 240, 244, 4, 5, 0, 4, 8, 13, 7, 242, 239, 0, 7, 252, 242, 0, 13, 10, 252, 245, 1, 7, 246, 240, 252, 8, 12, 1, 252, 0, 0, 254, 252, 254, 1, 3, 4, 1, 1, 0, 252, 253, 250, 250, 3, 8, 9, 2, 249, 246, 0, 11, 1, 252, 252, 254, 7, 6, 252, 254, 10, 9, 247, 240, 254, 14, 7, 252, 1, 5, 9, 0, 236, 244, 8, 11, 4, 250, 0, 15, 7, 245, 246, 3, 8, 3, 6, 253, 251, 8, 253, 249, 11, 9, 248, 247, 9, 9, 1, 6, 254, 253, 4, 251, 248, 2, 12, 7, 254, 6, 12, 252, 244, 251, 0, 11, 4, 247, 0, 11, 15, 3, 245, 246, 254, 13, 9, 246, 255, 9, 5, 4, 2, 251, 254, 8, 1, 247, 255, 11, 14, 7, 252, 254, 8, 4, 4, 252, 248, 20, 23, 5, 253, 248, 5, 10, 254, 244, 1, 28, 21, 3, 243, 237, 10, 15, 246, 253, 19, 21, 14, 255, 244, 0, 254, 245, 254, 14, 32, 24, 247, 230, 248, 14, 11, 250, 249, 6, 22, 25, 255, 237, 253, 9, 18, 10, 239, 243, 11, 18, 6, 255, 253, 6, 21, 3, 243, 245, 253, 15, 15, 0, 0, 8, 5, 249, 239, 246, 13, 20, 4, 0, 4, 251, 241, 252, 11, 12, 4, 251, 252, 1, 1, 3, 4, 1, 3, 2, 0, 2, 5, 1, 249, 246, 252, 6, 14, 7, 250, 248, 251, 255, 254, 254, 5, 12, 11, 255, 244, 240, 246, 4, 9, 4, 3, 6, 5, 1, 248, 241, 253, 9, 7, 3, 3, 1, 252, 248, 244, 250, 8, 13, 5, 250, 244, 248, 1, 4, 253, 251, 4, 7, 0, 251, 248, 248, 2, 7, 254, 249, 2, 8, 2, 250, 247, 0, 5, 254, 247, 251, 8, 13, 0, 242, 246, 0, 3, 0, 250, 250, 1, 7, 3, 248, 245, 253, 2, 5, 252, 246, 2, 8, 0, 249, 246, 251, 2, 6, 2, 252, 253, 250, 255, 4, 251, 247, 0, 4, 7, 7, 253, 248, 248, 250, 1, 3, 254, 253, 0, 5, 8, 253, 244, 248, 1, 1, 250, 0, 8, 11, 5, 250, 248, 250, 251, 253, 1, 9, 7, 0, 254, 254, 253, 251, 253, 3, 2, 255, 254, 2, 10, 253, 246, 0, 2, 6, 1, 254, 2, 2, 0, 253, 255, 4, 1, 255, 0, 2, 7, 4, 248, 245, 3, 13, 3, 251, 254, 7, 15, 2, 241, 238, 251, 12, 14, 11, 5, 255, 0, 247, 245, 252, 0, 12, 15, 9, 255, 247, 255, 0, 254, 3, 7, 1, 3, 6, 1, 254, 246, 247, 4, 10, 5, 0, 10, 7, 246, 246, 253, 10, 16, 7, 254, 248, 0, 1, 254, 3, 0, 254, 7, 13, 9, 251, 243, 255, 9, 3, 247, 246, 10, 20, 11, 251, 240, 255, 4, 252, 254, 0, 0, 4, 9, 11, 11, 0, 244, 249, 0, 6, 7, 2, 4, 6, 8, 3, 249, 247, 252, 3, 9, 9, 7, 0, 249, 253, 0, 255, 4, 2, 3, 10, 6, 4, 255, 248, 255, 1, 4, 13, 13, 254, 245, 249, 0, 4, 254, 250, 4, 20, 18, 254, 238, 242, 255, 2, 0, 4, 14, 16, 0, 249, 250, 250, 0, 0, 0, 11, 16, 10, 253, 245, 251, 0, 253, 252, 5, 9, 14, 10, 251, 251, 0, 248, 244, 1, 11, 14, 18, 6, 249, 245, 243, 250, 0, 2, 1, 10, 18, 5, 249, 248, 251, 252, 249, 252, 12, 21, 7, 252, 248, 252, 1, 249, 241, 254, 21, 26, 11, 250, 240, 246, 253, 249, 253, 10, 18, 16, 3, 250, 245, 239, 246, 3, 7, 9, 9, 4, 0, 252, 249, 252, 254, 0, 4, 5, 8, 9, 255, 242, 241, 253, 10, 6, 252, 253, 2, 9, 6, 246, 238, 250, 10, 8, 255, 0, 3, 0, 253, 250, 248, 1, 10, 2, 247, 248, 4, 5, 253, 254, 0, 5, 5, 253, 248, 252, 255, 255, 2, 5, 6, 1, 253, 253, 0, 255, 252, 0, 1, 2, 3, 255, 249, 250, 0, 3, 1, 253, 252, 0, 0, 249, 253, 4, 4, 0, 252, 251, 1, 4, 253, 249, 0, 3, 3, 255, 250, 254, 254, 253, 254, 0, 3, 1, 0, 253, 1, 6, 0, 249, 249, 255, 3, 2, 0, 255, 0, 254, 255, 0, 252, 255, 6, 3, 252, 250, 255, 255, 0, 1, 253, 2, 6, 0, 252, 249, 0, 4, 4, 0, 247, 252, 3, 3, 1, 251, 0, 6, 2, 254, 248, 246, 255, 2, 0, 3, 9, 9, 0, 245, 243, 250, 0, 4, 2, 4, 11, 7, 253, 244, 246, 255, 4, 4, 3, 5, 9, 2, 248, 249, 248, 252, 1, 3, 12, 14, 5, 250, 243, 246, 246, 252, 6, 12, 16, 9, 252, 244, 243, 241, 249, 10, 18, 18, 6, 253, 252, 243, 239, 252, 8, 18, 24, 10, 245, 237, 241, 251, 2, 9, 15, 12, 8, 2, 245, 241, 245, 254, 8, 14, 10, 4, 5, 3, 248, 238, 241, 0, 16, 20, 10, 1, 253, 249, 247, 248, 0, 10, 15, 10, 0, 253, 254, 252, 245, 252, 9, 11, 12, 9, 0, 248, 246, 251, 255, 2, 8, 9, 10, 7, 252, 244, 247, 253, 0, 6, 9, 8, 8, 3, 253, 249, 246, 248, 7, 16, 7, 0, 251, 255, 8, 2, 249, 248, 252, 3, 12, 8, 255, 253, 1, 0, 249, 251, 5, 16, 14, 2, 254, 251, 252, 254, 254, 3, 9, 10, 6, 253, 248, 250, 0, 3, 5, 8, 8, 0, 252, 252, 250, 253, 5, 7, 9, 10, 1, 251, 251, 254, 0, 0, 0, 5, 7, 6, 4, 2, 0, 251, 249, 253, 0, 4, 3, 6, 11, 2, 253, 253, 252, 254, 0, 1, 8, 12, 8, 3, 249, 243, 249, 1, 7, 7, 7, 8, 4, 253, 250, 250, 251, 3, 11, 9, 2, 254, 255, 0, 255, 255, 2, 6, 7, 1, 255, 254, 250, 251, 0, 4, 8, 6, 0, 255, 0, 254, 251, 255, 6, 8, 4, 254, 252, 0, 2, 0, 0, 0, 2, 3, 3, 1, 255, 254, 255, 0, 0, 2, 1, 4, 2, 251, 249, 254, 5, 9, 5, 0, 0, 3, 1, 251, 250, 1, 10, 7, 254, 253, 0, 1, 0, 251, 251, 4, 7, 3, 255, 0, 1, 255, 252, 252, 255, 4, 5, 0, 0, 4, 1, 251, 251, 255, 3, 2, 255, 0, 8, 9, 255, 250, 252, 253, 0, 3, 3, 2, 2, 2, 0, 251, 251, 255, 0, 2, 3, 3, 6, 4, 255, 248, 248, 254, 3, 7, 8, 3, 0, 254, 251, 253, 254, 255, 3, 9, 5, 0, 2, 0, 253, 250, 250, 1, 10, 10, 1, 254, 0, 0, 254, 251, 253, 0, 6, 8, 6, 1, 248, 245, 253, 3, 6, 7, 5, 2, 0, 251, 250, 253, 0, 2, 5, 9, 8, 255, 248, 249, 251, 2, 8, 7, 3, 0, 0, 255, 251, 250, 254, 8, 10, 0, 255, 0, 0, 253, 252, 1, 5, 8, 4, 252, 251, 254, 0, 0, 255, 3, 8, 4, 254, 254, 254, 255, 0, 1, 3, 3, 0, 253, 254, 3, 1, 254, 1, 6, 4, 0, 254, 254, 0, 1, 1, 0, 2, 2, 2, 255, 254, 0, 0, 1, 2, 1, 2, 0, 253, 254, 255, 2, 8, 4, 1, 1, 251, 251, 0, 6, 5, 2, 1, 1, 0, 254, 252, 255, 1, 3, 5, 3, 3, 3, 254, 250, 254, 2, 5, 5, 3, 0, 255, 0, 0, 0, 0, 3, 5, 3, 254, 251, 254, 4, 6, 2, 0, 0, 1, 1, 0, 255, 2, 7, 7, 3, 254, 251, 253, 3, 2, 253, 1, 8, 7, 3, 0, 253, 253, 255, 0, 1, 5, 6, 1, 253, 252, 253, 1, 1, 1, 4, 4, 5, 3, 253, 251, 252, 255, 1, 5, 6, 5, 1, 251, 251, 255, 0, 0, 1, 3, 2, 2, 1, 253, 253, 0, 0, 1, 3, 0, 254, 255, 2, 3, 255, 252, 254, 2, 2, 0, 255, 2, 5, 3, 254, 249, 254, 5, 3, 0, 0, 4, 2, 255, 253, 255, 0, 0, 0, 0, 0, 200, 0, 4, 0, 1, 0, 191, 0, 180, 1, 28, 8, 44, 10, 124, 13, 216, 14, 128, 28, 50, 41, 25, 54, 56, 53, 42, 34, 11, 8, 185, 107, 137, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 191, 0, 180, 1, 28, 8, 44, 10, 124, 13, 216, 14, 128, 28, 80, 77, 35, 75, 77, 73, 57, 47, 15, 11, 185, 107, 137, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 191, 0, 180, 1, 28, 8, 44, 10, 124, 13, 216, 14, 128, 28, 70, 65, 32, 69, 71, 67, 53, 43, 13, 10, 185, 107, 137, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 191, 0, 180, 1, 28, 8, 44, 10, 124, 13, 216, 14, 128, 28, 0, 29, 22, 46, 48, 45, 35, 29, 9, 7, 185, 107, 137, 120, 120, 120, 185, 107, 127, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 188, 4, 48, 0, 2, 252, 253, 253, 7, 7, 0, 0, 248, 251, 0, 6, 8, 0, 248, 248, 0, 7, 4, 2, 252, 247, 0, 255, 7, 6, 251, 243, 249, 3, 14, 16, 0, 247, 246, 252, 2, 8, 0, 0, 250, 253, 7, 4, 255, 252, 253, 251, 2, 2, 249, 252, 2, 16, 12, 246, 236, 252, 4, 18, 6, 248, 246, 241, 12, 7, 5, 253, 241, 248, 7, 7, 8, 254, 243, 245, 4, 10, 11, 8, 234, 234, 6, 19, 11, 7, 240, 240, 12, 18, 255, 237, 245, 252, 6, 1, 8, 21, 2, 236, 242, 250, 1, 32, 30, 243, 212, 234, 14, 23, 17, 250, 246, 4, 4, 239, 239, 13, 17, 2, 3, 254, 243, 14, 0, 253, 244, 6, 23, 232, 249, 35, 255, 212, 14, 47, 232, 213, 254, 39, 36, 238, 227, 16, 240, 229, 44, 63, 242, 202, 228, 9, 47, 36, 247, 209, 207, 28, 47, 4, 252, 238, 213, 235, 33, 56, 28, 213, 205, 235, 25, 44, 18, 238, 238, 240, 6, 12, 2, 26, 245, 238, 2, 1, 244, 10, 36, 19, 214, 227, 13, 35, 20, 240, 210, 6, 60, 14, 219, 217, 11, 49, 22, 231, 226, 244, 7, 35, 63, 221, 170, 3, 10, 73, 25, 195, 4, 27, 3, 198, 230, 69, 74, 213, 203, 7, 8, 230, 48, 252, 251, 26, 1, 200, 202, 109, 91, 206, 162, 3, 71, 4, 240, 222, 210, 56, 55, 3, 254, 221, 13, 227, 18, 46, 237, 251, 211, 9, 71, 18, 245, 24, 182, 184, 91, 85, 237, 202, 212, 38, 49, 201, 248, 16, 52, 29, 154, 218, 76, 55, 204, 10, 21, 229, 17, 231, 236, 29, 22, 253, 234, 74, 228, 157, 73, 77, 220, 178, 4, 39, 51, 28, 219, 218, 15, 11, 217, 30, 74, 254, 170, 221, 26, 23, 18, 2, 0, 48, 2, 177, 165, 75, 90, 37, 241, 147, 215, 70, 51, 6, 253, 201, 217, 85, 6, 226, 4, 250, 251, 3, 18, 23, 222, 218, 47, 34, 237, 14, 229, 228, 50, 248, 219, 252, 51, 252, 241, 3, 241, 39, 11, 255, 201, 177, 77, 89, 237, 196, 222, 253, 3, 60, 58, 208, 214, 206, 30, 1, 51, 75, 156, 162, 39, 105, 244, 184, 18, 29, 6, 204, 206, 26, 59, 63, 179, 212, 226, 54, 37, 196, 34, 6, 210, 231, 26, 239, 5, 30, 232, 21, 253, 181, 254, 54, 32, 235, 163, 18, 62, 53, 228, 153, 248, 46, 12, 253, 31, 11, 188, 2, 13, 220, 251, 46, 12, 195, 243, 16, 34, 29, 187, 193, 27, 71, 208, 250, 40, 241, 238, 221, 201, 82, 83, 185, 203, 1, 4, 24, 36, 161, 255, 108, 250, 179, 208, 51, 47, 3, 181, 224, 41, 22, 40, 52, 157, 151, 221, 89, 124, 22, 183, 192, 201, 217, 90, 125, 232, 186, 208, 186, 57, 83, 53, 238, 138, 230, 54, 23, 4, 24, 240, 199, 237, 2, 9, 77, 34, 209, 179, 182, 35, 113, 58, 199, 181, 218, 0, 12, 57, 87, 228, 153, 192, 40, 84, 33, 248, 158, 234, 31, 63, 12, 251, 228, 227, 244, 249, 24, 35, 71, 219, 149, 1, 34, 48, 55, 17, 184, 215, 9, 1, 85, 23, 194, 251, 227, 225, 60, 91, 217, 209, 202, 217, 109, 73, 206, 200, 16, 247, 246, 19, 26, 0, 15, 244, 189, 253, 94, 10, 196, 25, 12, 236, 255, 1, 238, 9, 26, 25, 239, 255, 5, 233, 38, 17, 189, 3, 51, 19, 4, 248, 237, 217, 8, 67, 45, 207, 221, 236, 10, 52, 36, 231, 225, 13, 252, 22, 18, 250, 220, 217, 17, 69, 44, 229, 220, 228, 236, 48, 51, 231, 0, 56, 233, 194, 220, 34, 92, 48, 191, 174, 1, 67, 50, 249, 230, 234, 231, 2, 65, 31, 237, 239, 247, 254, 17, 223, 4, 76, 1, 187, 227, 17, 89, 65, 215, 162, 196, 251, 46, 84, 56, 251, 213, 191, 221, 59, 46, 230, 246, 10, 5, 14, 5, 233, 255, 25, 254, 8, 16, 232, 244, 26, 250, 224, 10, 47, 16, 252, 14, 225, 230, 33, 20, 223, 234, 12, 28, 45, 35, 236, 202, 214, 253, 47, 62, 20, 226, 222, 244, 19, 30, 10, 248, 244, 224, 254, 54, 35, 243, 240, 251, 248, 0, 6, 255, 27, 42, 248, 213, 232, 17, 38, 30, 254, 227, 239, 1, 18, 32, 10, 234, 234, 231, 249, 41, 47, 19, 247, 232, 215, 233, 0, 43, 61, 21, 234, 217, 219, 248, 47, 33, 0, 248, 242, 254, 19, 35, 248, 209, 229, 13, 40, 31, 10, 251, 224, 219, 245, 13, 38, 32, 6, 241, 241, 229, 242, 0, 21, 41, 10, 247, 240, 246, 249, 2, 7, 249, 254, 9, 18, 12, 251, 248, 246, 249, 246, 4, 15, 12, 16, 3, 243, 247, 255, 248, 5, 25, 23, 250, 225, 227, 253, 26, 31, 11, 250, 0, 1, 254, 241, 242, 255, 1, 2, 3, 9, 2, 248, 254, 0, 248, 253, 3, 3, 2, 3, 243, 232, 0, 19, 22, 8, 247, 246, 247, 248, 3, 7, 3, 255, 2, 7, 2, 255, 246, 240, 255, 14, 14, 5, 0, 253, 243, 243, 8, 9, 4, 6, 2, 249, 246, 241, 248, 7, 11, 9, 1, 0, 248, 242, 253, 3, 250, 252, 4, 8, 4, 254, 246, 240, 253, 254, 255, 8, 9, 255, 249, 254, 253, 249, 248, 251, 8, 14, 5, 254, 240, 242, 253, 4, 9, 9, 5, 253, 249, 251, 250, 252, 5, 6, 4, 4, 255, 249, 247, 1, 9, 254, 252, 251, 249, 7, 8, 3, 247, 244, 251, 2, 10, 7, 0, 247, 245, 251, 254, 254, 8, 9, 253, 249, 248, 246, 2, 3, 0, 1, 0, 253, 252, 2, 2, 253, 251, 251, 2, 7, 4, 1, 0, 254, 251, 254, 1, 0, 254, 2, 3, 252, 254, 3, 0, 255, 0, 1, 2, 0, 0, 252, 251, 254, 255, 1, 9, 6, 254, 251, 252, 255, 2, 1, 252, 253, 1, 4, 3, 0, 255, 255, 0, 0, 253, 255, 3, 0, 255, 0, 0, 255, 0, 1, 1, 1, 0, 252, 254, 254, 0, 6, 1, 0, 0, 0, 0, 1, 2, 255, 252, 0, 2, 1, 2, 3, 255, 255, 0, 254, 3, 5, 252, 252, 3, 3, 0, 1, 1, 1, 0, 0, 1, 255, 254, 1, 1, 2, 1, 0, 2, 0, 0, 3, 0, 254, 0, 0, 2, 3, 3, 3, 255, 255, 2, 2, 0, 0, 0, 1, 1, 0, 255, 2, 0, 2, 3, 0, 0, 255, 0, 0, 2, 3, 3, 255, 255, 5, 2, 255, 3, 0, 253, 255, 2, 4, 5, 0, 253, 1, 3, 2, 2, 255, 254, 2, 0, 3, 4, 254, 252, 4, 6, 0, 255, 0, 1, 2, 2, 0, 254, 0, 3, 1, 5, 4, 254, 1, 0, 1, 1, 255, 0, 5, 4, 254, 0, 2, 1, 2, 1, 255, 0, 2, 2, 0, 1, 0, 0, 3, 1, 0, 0, 3, 0, 255, 4, 255, 254, 2, 0, 2, 3, 0, 254, 255, 2, 2, 0, 2, 0, 255, 1, 3, 2, 172, 7, 130, 0, 1, 1, 1, 1, 1, 1, 1, 2, 4, 12, 31, 46, 11, 197, 182, 214, 6, 55, 45, 33, 240, 222, 13, 255, 213, 207, 230, 4, 90, 100, 0, 167, 227, 243, 38, 96, 2, 131, 232, 24, 14, 75, 16, 202, 2, 34, 243, 255, 239, 214, 7, 41, 2, 11, 20, 17, 13, 235, 211, 226, 247, 19, 6, 19, 16, 35, 6, 1, 9, 216, 216, 255, 0, 52, 53, 255, 249, 242, 247, 255, 249, 232, 207, 233, 32, 41, 0, 21, 2, 234, 252, 251, 29, 57, 247, 206, 220, 232, 54, 39, 14, 222, 240, 239, 8, 49, 37, 3, 222, 223, 0, 37, 16, 240, 237, 249, 24, 10, 245, 212, 227, 7, 52, 32, 244, 226, 230, 4, 0, 0, 16, 41, 45, 23, 212, 217, 231, 17, 26, 4, 238, 218, 239, 254, 249, 255, 226, 247, 7, 1, 233, 217, 238, 19, 40, 64, 20, 3, 242, 231, 246, 3, 250, 0, 18, 18, 10, 14, 22, 9, 10, 251, 217, 235, 10, 10, 15, 12, 24, 32, 30, 230, 222, 231, 1, 9, 4, 251, 252, 20, 27, 15, 254, 231, 231, 241, 255, 7, 9, 5, 3, 246, 254, 12, 236, 238, 225, 7, 13, 8, 12, 246, 4, 10, 8, 249, 239, 1, 2, 231, 227, 10, 21, 81, 57, 250, 200, 214, 225, 6, 24, 1, 253, 9, 22, 12, 251, 230, 232, 250, 18, 12, 7, 247, 249, 246, 249, 253, 5, 4, 6, 255, 240, 235, 248, 23, 42, 9, 248, 229, 0, 6, 19, 0, 239, 247, 8, 20, 8, 255, 248, 5, 22, 32, 11, 244, 228, 238, 254, 12, 10, 0, 252, 3, 4, 0, 4, 0, 253, 249, 251, 3, 11, 5, 5, 248, 233, 247, 0, 10, 8, 250, 237, 247, 5, 3, 255, 2, 249, 249, 0, 3, 2, 0, 251, 250, 4, 3, 5, 12, 12, 2, 252, 252, 250, 8, 10, 5, 6, 13, 3, 3, 7, 251, 255, 253, 244, 250, 4, 0, 3, 4, 253, 243, 246, 250, 1, 1, 251, 245, 255, 3, 2, 2, 251, 244, 247, 251, 251, 8, 2, 248, 254, 5, 6, 2, 5, 255, 0, 253, 250, 7, 10, 7, 255, 0, 0, 5, 11, 10, 6, 1, 250, 0, 3, 2, 251, 253, 3, 9, 10, 2, 255, 253, 254, 6, 10, 8, 0, 252, 4, 10, 5, 253, 246, 252, 0, 7, 7, 1, 3, 252, 253, 0, 4, 1, 0, 255, 253, 253, 0, 255, 1, 0, 254, 253, 2, 2, 0, 2, 1, 255, 255, 255, 0, 4, 3, 0, 0, 0, 1, 1, 2, 2, 2, 3, 0, 2, 3, 1, 0, 0, 255, 0, 0, 2, 2, 3, 2, 1, 0, 254, 252, 0, 0, 0, 0, 255, 255, 0, 0, 255, 254, 253, 253, 254, 0, 0, 2, 255, 251, 251, 254, 0, 2, 0, 255, 255, 255, 1, 2, 0, 255, 255, 255, 0, 3, 2, 1, 255, 254, 254, 0, 2, 2, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 254, 0, 1, 1, 254, 254, 255, 255, 1, 1, 255, 254, 255, 255, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 255, 254, 254, 0, 1, 2, 2, 0, 255, 0, 1, 0, 1, 0, 254, 1, 2, 2, 1, 0, 255, 0, 0, 0, 1, 0, 0, 255, 0, 0, 2, 2, 2, 0, 255, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 255, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 2, 1, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 255, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 255, 0, 0, 1, 0, 0, 255, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 2, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 2, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 2, 0, 0, 0, 1, 1, 1, 2, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 2, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 1, 0, 1, 0, 0, 2, 0, 0, 0, 0, 2, 2, 0, 0, 0, 2, 1, 0, 0, 0, 1, 2, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 2, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 2, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 255, 0, 0, 1, 2, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 255, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 1, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 2, 3, 2, 255, 251, 247, 247, 251, 1, 8, 10, 7, 4, 1, 254, 252, 249, 250, 248, 255, 4, 9, 10, 4, 2, 0, 255, 254, 253, 255, 254, 1, 3, 3, 1, 255, 255, 254, 0, 0, 1, 3, 2, 1, 0, 254, 254, 252, 254, 254, 0, 2, 3, 4, 4, 2, 0, 254, 254, 254, 255, 0, 2, 3, 3, 2, 2, 0, 255, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 1, 1, 2, 1, 0, 254, 251, 252, 255, 1, 3, 3, 3, 2, 1, 0, 0, 253, 252, 253, 0, 4, 5, 5, 4, 2, 0, 0, 0, 254, 254, 0, 2, 3, 1, 1, 0, 0, 255, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 255, 0, 2, 4, 3, 2, 0, 0, 0, 0, 255, 0, 0, 2, 3, 3, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 254, 253, 255, 2, 5, 6, 3, 0, 254, 253, 255, 0, 0, 0, 2, 4, 5, 5, 2, 0, 254, 253, 255, 1, 2, 1, 0, 0, 0, 0, 1, 0, 255, 255, 0, 1, 2, 1, 0, 0, 255, 255, 0, 0, 0, 0, 2, 3, 2, 2, 0, 255, 0, 0, 1, 2, 1, 1, 1, 1, 1, 0, 0, 0, 2, 2, 1, 0, 255, 253, 251, 251, 253, 0, 2, 5, 7, 5, 1, 254, 253, 252, 252, 253, 255, 2, 5, 7, 7, 4, 0, 254, 254, 255, 0, 0, 0, 2, 2, 1, 1, 0, 255, 255, 255, 0, 1, 1, 1, 0, 255, 255, 255, 255, 255, 0, 0, 2, 4, 3, 2, 1, 0, 254, 255, 0, 0, 1, 2, 2, 2, 1, 0, 0, 0, 255, 0, 0, 1, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0, 0, 254, 253, 253, 253, 254, 1, 3, 6, 7, 3, 255, 251, 251, 253, 255, 255, 0, 2, 4, 5, 5, 1, 254, 252, 252, 0, 1, 2, 1, 1, 0, 1, 1, 0, 255, 254, 0, 2, 3, 2, 0, 0, 254, 255, 0, 0, 0, 0, 0, 2, 3, 2, 0, 255, 255, 255, 0, 0, 1, 1, 1, 2, 1, 0, 0, 255, 0, 0, 0, 1, 2, 1, 0, 255, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 255, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 2, 2, 1, 0, 254, 253, 252, 254, 1, 2, 3, 4, 3, 2, 255, 253, 254, 255, 0, 0, 3, 4, 2, 1, 0, 0, 255, 0, 1, 1, 2, 0, 0, 0, 0, 0, 255, 0, 0, 0, 2, 2, 3, 1, 0, 0, 255, 255, 255, 0, 1, 1, 2, 3, 2, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 2, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 254, 254, 0, 2, 4, 3, 2, 0, 0, 0, 1, 1, 0, 0, 0, 2, 3, 2, 0, 0, 255, 0, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 3, 0, 1, 0, 116, 0, 24, 2, 140, 5, 116, 9, 188, 12, 116, 14, 88, 27, 110, 86, 41, 79, 96, 54, 56, 43, 23, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 7, 0, 116, 0, 24, 2, 136, 5, 16, 9, 88, 12, 16, 14, 88, 27, 55, 24, 22, 43, 46, 30, 28, 21, 11, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 116, 0, 72, 2, 120, 5, 208, 7, 224, 11, 152, 13, 88, 27, 0, 21, 22, 43, 37, 30, 13, 11, 6, 4, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 0, 0, 3, 0, 1, 0, 116, 0, 24, 2, 140, 5, 116, 9, 188, 12, 116, 14, 88, 27, 50, 50, 31, 60, 73, 41, 43, 33, 17, 6, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 116, 0, 24, 2, 140, 5, 116, 9, 188, 12, 116, 14, 88, 27, 90, 86, 41, 79, 96, 54, 56, 43, 23, 8, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 116, 0, 24, 2, 140, 5, 116, 9, 188, 12, 116, 14, 88, 27, 0, 42, 28, 55, 67, 38, 39, 30, 16, 6, 167, 150, 135, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 0, 0, 3, 0, 1, 0, 123, 0, 15, 2, 181, 5, 176, 9, 198, 12, 136, 14, 38, 27, 50, 49, 30, 62, 69, 42, 44, 32, 16, 6, 166, 145, 133, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 123, 0, 15, 2, 181, 5, 176, 9, 198, 12, 136, 14, 38, 27, 90, 88, 40, 83, 92, 56, 58, 43, 22, 8, 166, 145, 133, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 123, 0, 15, 2, 181, 5, 176, 9, 198, 12, 136, 14, 38, 27, 0, 42, 27, 57, 63, 38, 40, 30, 15, 5, 166, 145, 133, 120, 120, 120, 197, 120, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 201, 0, 6, 0, 1, 0, 104, 0, 139, 1, 9, 8, 80, 10, 72, 13, 60, 15, 160, 27, 42, 46, 10, 66, 56, 58, 42, 33, 10, 8, 150, 165, 150, 120, 120, 120, 150, 105, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 104, 0, 139, 1, 20, 8, 160, 10, 72, 13, 60, 15, 32, 27, 50, 60, 16, 66, 78, 77, 67, 37, 15, 8, 167, 120, 150, 120, 120, 120, 167, 120, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 128, 0, 179, 1, 232, 7, 80, 10, 52, 13, 60, 15, 64, 27, 31, 45, 20, 70, 53, 50, 46, 25, 9, 8, 180, 90, 150, 120, 120, 120, 180, 105, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 168, 0, 3, 2, 67, 7, 196, 9, 112, 13, 60, 15, 64, 27, 44, 40, 25, 65, 56, 50, 38, 25, 12, 8, 167, 90, 150, 120, 120, 120, 167, 90, 165, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 168, 0, 3, 2, 103, 6, 156, 9, 32, 13, 85, 15, 64, 28, 34, 25, 21, 43, 43, 45, 36, 20, 6, 8, 167, 150, 120, 120, 120, 120, 167, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 184, 0, 3, 2, 59, 6, 156, 9, 112, 13, 29, 16, 192, 28, 0, 25, 26, 43, 39, 39, 31, 16, 4, 8, 167, 150, 120, 120, 120, 120, 167, 105, 135, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 180, 0, 4, 0, 1, 0, 158, 0, 56, 1, 165, 8, 215, 10, 49, 13, 9, 15, 112, 26, 50, 32, 10, 58, 42, 49, 50, 24, 11, 5, 166, 105, 120, 120, 120, 120, 130, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 158, 0, 56, 1, 165, 8, 215, 10, 49, 13, 9, 15, 112, 26, 70, 73, 15, 88, 64, 74, 75, 37, 17, 8, 166, 105, 120, 120, 120, 120, 130, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 158, 0, 56, 1, 165, 8, 215, 10, 49, 13, 9, 15, 112, 26, 60, 65, 14, 83, 60, 70, 71, 35, 16, 7, 166, 105, 120, 120, 120, 120, 130, 75, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 125, 0, 0, 1, 56, 9, 4, 11, 20, 13, 0, 15, 64, 26, 0, 33, 8, 52, 52, 53, 54, 29, 11, 8, 167, 99, 114, 120, 120, 120, 167, 105, 120, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 95, 0, 4, 0, 1, 0, 157, 0, 144, 1, 90, 5, 252, 8, 168, 12, 181, 14, 148, 25, 45, 41, 21, 56, 54, 42, 37, 29, 12, 9, 174, 125, 138, 121, 121, 130, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 157, 0, 144, 1, 90, 5, 252, 8, 168, 12, 181, 14, 148, 25, 90, 74, 29, 75, 73, 56, 50, 39, 16, 12, 174, 125, 138, 121, 121, 130, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 143, 0, 183, 1, 0, 5, 65, 9, 121, 12, 164, 14, 155, 26, 50, 60, 29, 67, 70, 44, 41, 32, 16, 7, 168, 136, 140, 120, 120, 123, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 143, 0, 183, 1, 0, 5, 65, 9, 121, 12, 164, 14, 155, 26, 0, 44, 25, 58, 60, 38, 36, 27, 14, 6, 168, 136, 140, 120, 120, 123, 187, 126, 137, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 215, 0, 6, 0, 1, 0, 176, 0, 64, 1, 92, 3, 56, 9, 12, 13, 60, 15, 144, 26, 45, 44, 6, 70, 36, 21, 21, 30, 12, 7, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 104, 64, 0, 191, 197, 190, 111, 182, 1, 250, 0, 0, 3, 0, 176, 0, 64, 1, 92, 3, 56, 9, 12, 13, 60, 15, 144, 26, 30, 68, 7, 87, 45, 26, 26, 38, 15, 9, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 242, 110, 182, 232, 64, 0, 191, 233, 59, 105, 182, 200, 250, 21, 8, 1, 0, 176, 0, 64, 1, 92, 3, 56, 9, 12, 13, 60, 15, 144, 26, 50, 61, 7, 83, 43, 25, 25, 36, 14, 9, 177, 125, 102, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 49, 165, 0, 182, 29, 32, 0, 0, 240, 250, 209, 182, 1, 0, 146, 0, 166, 1, 126, 4, 46, 9, 228, 12, 216, 14, 248, 26, 50, 47, 16, 68, 52, 30, 30, 32, 14, 8, 172, 137, 118, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 186, 209, 182, 72, 65, 0, 191, 145, 236, 45, 182, 1, 250, 0, 0, 1, 0, 125, 0, 240, 1, 78, 5, 39, 9, 200, 12, 145, 14, 66, 27, 40, 32, 21, 51, 55, 31, 32, 27, 13, 7, 169, 146, 130, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 36, 23, 8, 28, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 1, 0, 122, 0, 8, 2, 102, 5, 38, 9, 196, 12, 136, 14, 75, 27, 0, 31, 22, 50, 55, 31, 32, 26, 13, 7, 168, 147, 131, 120, 120, 120, 177, 125, 117, 44, 45, 70, 130, 59, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 191, 76, 8, 87, 182, 0, 250, 0, 0, 51, 1, 61, 0, 0, 0, 3, 3, 34, 126, 63, 228, 224, 253, 19, 246, 245, 31, 94, 39, 4, 4, 31, 47, 12, 255, 17, 4, 41, 10, 7, 12, 9, 8, 13, 12, 5, 243, 226, 244, 244, 251, 240, 226, 238, 62, 71, 228, 217, 12, 18, 14, 249, 10, 3, 233, 224, 4, 36, 44, 25, 254, 4, 35, 16, 240, 229, 2, 18, 12, 5, 11, 0, 245, 243, 249, 16, 11, 253, 241, 231, 251, 4, 238, 233, 250, 8, 11, 3, 252, 0, 250, 243, 254, 5, 37, 34, 8, 239, 251, 34, 27, 27, 11, 16, 40, 29, 12, 11, 7, 7, 239, 247, 6, 23, 9, 245, 233, 8, 7, 6, 247, 234, 6, 236, 209, 242, 5, 246, 224, 219, 0, 30, 9, 224, 212, 223, 249, 246, 235, 227, 234, 10, 15, 237, 7, 242, 22, 6, 217, 215, 0, 48, 10, 217, 227, 12, 32, 7, 235, 2, 9, 231, 226, 241, 248, 28, 221, 213, 247, 17, 5, 248, 246, 244, 214, 224, 245, 234, 241, 2, 19, 221, 246, 6, 247, 236, 228, 23, 0, 240, 234, 11, 5, 253, 1, 10, 3, 32, 19, 241, 254, 15, 249, 240, 14, 35, 8, 238, 20, 47, 17, 252, 246, 241, 0, 13, 33, 1, 9, 5, 9, 0, 6, 20, 0, 249, 244, 3, 250, 0, 39, 11, 220, 241, 39, 38, 14, 227, 236, 255, 255, 252, 250, 251, 4, 250, 246, 254, 254, 245, 231, 234, 248, 248, 243, 243, 244, 246, 245, 240, 236, 238, 239, 239, 240, 239, 242, 244, 238, 233, 239, 242, 243, 242, 235, 234, 238, 236, 240, 240, 246, 0, 5, 6, 9, 5, 241, 242, 245, 251, 10, 2, 19, 23, 19, 23, 15, 15, 2, 0, 253, 5, 13, 19, 19, 6, 8, 4, 247, 246, 0, 0}; autoFileInMemory espeakdata_phons2 = FileInMemory_createWithData (385580, reinterpret_cast (&espeakdata_phons2_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/phondata", U"phondata"); Collection_addItem (me.peek(), espeakdata_phons2.transfer()); static unsigned char espeakdata_phons3_data[20427] = { 36, 70, 1, 0, 0, 161, 213, 131, 0, 0, 0, 0, 0, 162, 18, 130, 0, 0, 0, 0, 0, 192, 1, 0, 0, 176, 85, 0, 2, 13, 153, 201, 16, 52, 34, 36, 3, 104, 1, 13, 0, 32, 25, 10, 0, 176, 134, 0, 0, 176, 183, 0, 0, 176, 248, 0, 38, 5, 0, 176, 57, 1, 0, 176, 122, 1, 0, 176, 187, 1, 3, 13, 204, 109, 0, 169, 134, 40, 95, 10, 2, 47, 0, 176, 252, 1, 0, 176, 93, 2, 3, 13, 204, 110, 0, 169, 134, 40, 95, 10, 2, 47, 0, 176, 190, 2, 0, 176, 15, 3, 4, 13, 139, 197, 169, 204, 0, 176, 96, 3, 192, 195, 177, 3, 3, 13, 204, 114, 0, 169, 0, 176, 52, 4, 3, 13, 204, 108, 0, 169, 0, 176, 133, 4, 2, 13, 185, 201, 138, 41, 46, 1, 6, 106, 16, 223, 198, 4, 16, 223, 247, 4, 16, 223, 40, 5, 16, 223, 89, 5, 16, 223, 138, 5, 16, 223, 187, 5, 2, 39, 224, 236, 236, 5, 0, 39, 0, 176, 13, 6, 47, 48, 48, 48, 49, 32, 0, 176, 62, 6, 0, 176, 95, 6, 50, 34, 5, 104, 0, 176, 144, 6, 0, 240, 177, 6, 47, 48, 48, 48, 49, 32, 0, 176, 135, 11, 138, 39, 0, 176, 184, 11, 0, 176, 233, 11, 0, 240, 177, 6, 1, 13, 0, 114, 52, 36, 3, 104, 1, 13, 0, 32, 0, 161, 25, 3, 75, 1, 96, 170, 0, 162, 18, 34, 75, 9, 96, 170, 0, 176, 10, 12, 16, 244, 59, 12, 1, 13, 0, 114, 0, 161, 25, 3, 73, 1, 98, 170, 0, 162, 18, 34, 73, 9, 98, 170, 0, 176, 254, 13, 32, 243, 63, 14, 1, 13, 0, 114, 0, 161, 25, 3, 64, 9, 118, 90, 0, 162, 18, 2, 64, 9, 98, 90, 6, 106, 16, 223, 198, 4, 16, 223, 247, 4, 16, 223, 40, 5, 16, 223, 89, 5, 16, 223, 138, 5, 16, 223, 187, 5, 2, 39, 224, 236, 236, 5, 0, 176, 254, 13, 0, 240, 218, 16, 2, 13, 128, 202, 138, 41, 5, 104, 0, 176, 235, 17, 32, 243, 44, 18, 0, 176, 235, 17, 176, 244, 44, 18, 6, 106, 0, 208, 238, 21, 0, 208, 31, 22, 0, 208, 64, 22, 96, 223, 97, 22, 0, 208, 146, 22, 0, 208, 211, 22, 1, 0, 138, 41, 56, 1, 138, 41, 17, 104, 6, 108, 64, 236, 4, 23, 128, 237, 69, 23, 32, 238, 134, 23, 32, 238, 183, 23, 128, 237, 248, 23, 128, 237, 73, 24, 0, 176, 138, 24, 1, 0, 0, 145, 194, 0, 28, 32, 224, 236, 171, 24, 4, 96, 2, 39, 128, 237, 171, 24, 0, 39, 0, 176, 204, 24, 47, 32, 0, 176, 253, 24, 56, 32, 0, 176, 30, 25, 0, 176, 63, 25, 2, 41, 55, 1, 6, 108, 64, 236, 4, 23, 128, 237, 69, 23, 32, 238, 134, 23, 32, 238, 183, 23, 128, 237, 248, 23, 128, 237, 73, 24, 57, 37, 0, 176, 134, 23, 58, 37, 0, 176, 134, 23, 0, 176, 138, 24, 2, 41, 55, 1, 0, 145, 194, 0, 57, 37, 0, 176, 96, 25, 58, 37, 0, 176, 145, 25, 6, 108, 64, 236, 210, 25, 224, 236, 19, 26, 128, 237, 96, 25, 32, 238, 84, 26, 224, 236, 149, 26, 128, 237, 145, 25, 1, 0, 2, 41, 55, 1, 6, 108, 0, 224, 230, 26, 0, 224, 7, 27, 0, 224, 40, 27, 0, 224, 73, 27, 0, 224, 122, 27, 192, 238, 171, 27, 0, 176, 138, 24, 2, 13, 142, 202, 1, 162, 30, 82, 0, 0, 0, 0, 6, 106, 0, 208, 204, 27, 0, 208, 253, 27, 0, 208, 46, 28, 0, 208, 95, 28, 0, 208, 144, 28, 0, 208, 209, 28, 0, 39, 0, 176, 18, 29, 0, 176, 83, 29, 2, 13, 173, 201, 0, 176, 148, 29, 138, 41, 63, 1, 128, 237, 197, 29, 0, 39, 0, 176, 246, 29, 0, 176, 55, 30, 2, 41, 23, 104, 6, 106, 0, 208, 104, 30, 0, 208, 153, 30, 0, 208, 202, 30, 0, 208, 251, 30, 0, 208, 44, 31, 0, 208, 93, 31, 32, 238, 142, 31, 0, 39, 3, 104, 0, 176, 175, 31, 0, 176, 175, 31, 11, 96, 0, 162, 25, 18, 0, 0, 0, 0, 31, 32, 3, 104, 0, 176, 224, 31, 0, 176, 33, 32, 1, 0, 2, 43, 21, 104, 6, 106, 0, 208, 82, 32, 0, 208, 147, 32, 0, 208, 212, 32, 0, 208, 21, 33, 0, 208, 70, 33, 0, 208, 151, 33, 32, 238, 200, 33, 0, 39, 3, 104, 0, 176, 233, 33, 7, 96, 0, 162, 35, 18, 0, 0, 0, 0, 0, 176, 10, 34, 1, 0, 31, 32, 3, 104, 1, 13, 0, 32, 138, 41, 1, 1, 6, 106, 0, 208, 59, 34, 0, 208, 108, 34, 0, 208, 157, 34, 0, 208, 206, 34, 0, 208, 255, 34, 0, 208, 64, 35, 31, 32, 128, 237, 113, 35, 0, 39, 0, 176, 146, 35, 1, 0, 0, 162, 18, 34, 75, 9, 84, 65, 2, 47, 11, 104, 0, 161, 25, 3, 75, 1, 212, 114, 133, 41, 3, 104, 0, 176, 179, 35, 0, 176, 244, 35, 6, 106, 0, 208, 53, 36, 0, 208, 118, 36, 0, 208, 183, 36, 0, 208, 248, 36, 0, 208, 73, 37, 0, 208, 138, 37, 138, 39, 3, 43, 0, 176, 203, 37, 0, 39, 0, 176, 252, 37, 138, 41, 0, 176, 29, 38, 1, 0, 0, 162, 146, 50, 77, 9, 98, 162, 2, 47, 7, 104, 0, 161, 25, 3, 79, 1, 222, 154, 0, 176, 78, 38, 6, 106, 0, 208, 143, 38, 0, 208, 208, 38, 0, 208, 17, 39, 0, 208, 82, 39, 0, 208, 147, 39, 0, 208, 212, 39, 138, 39, 3, 43, 0, 176, 21, 40, 0, 55, 50, 32, 0, 176, 70, 40, 138, 41, 0, 176, 103, 40, 1, 0, 2, 13, 179, 201, 0, 161, 153, 18, 69, 73, 88, 162, 0, 162, 146, 50, 69, 73, 88, 162, 2, 47, 0, 176, 152, 40, 6, 106, 0, 208, 143, 38, 0, 208, 208, 38, 0, 208, 17, 39, 0, 208, 82, 39, 0, 208, 147, 39, 0, 208, 212, 39, 138, 39, 3, 43, 0, 176, 21, 40, 0, 55, 66, 32, 0, 176, 217, 40, 138, 41, 0, 176, 250, 40, 1, 0, 2, 13, 178, 201, 0, 162, 23, 114, 81, 13, 114, 205, 2, 47, 5, 104, 0, 208, 43, 41, 0, 176, 76, 41, 6, 106, 0, 208, 141, 41, 0, 208, 238, 41, 0, 208, 63, 42, 0, 208, 160, 42, 0, 208, 1, 43, 0, 208, 114, 43, 0, 39, 0, 176, 211, 43, 138, 41, 10, 104, 67, 36, 3, 104, 37, 10, 4, 96, 67, 37, 2, 104, 50, 10, 0, 176, 244, 43, 1, 0, 0, 162, 148, 50, 75, 13, 110, 189, 2, 47, 7, 104, 0, 161, 25, 3, 79, 1, 42, 172, 0, 176, 69, 44, 6, 106, 0, 208, 134, 44, 0, 208, 183, 44, 0, 208, 232, 44, 0, 208, 25, 45, 0, 208, 74, 45, 0, 208, 123, 45, 31, 32, 128, 237, 172, 45, 138, 39, 3, 43, 0, 176, 221, 45, 0, 39, 0, 176, 254, 45, 138, 41, 0, 176, 31, 46, 1, 0, 2, 13, 190, 201, 0, 162, 136, 20, 73, 13, 96, 170, 0, 161, 10, 19, 77, 9, 96, 170, 31, 48, 30, 32, 0, 176, 80, 46, 0, 176, 161, 46, 2, 13, 190, 201, 14, 37, 3, 104, 1, 13, 0, 114, 30, 50, 31, 34, 13, 104, 0, 161, 25, 3, 75, 1, 94, 170, 0, 176, 242, 46, 96, 249, 177, 6, 0, 176, 242, 46, 96, 249, 177, 6, 0, 161, 25, 3, 75, 9, 94, 170, 29, 34, 5, 104, 0, 176, 35, 47, 128, 252, 177, 6, 34, 34, 0, 176, 100, 47, 0, 162, 153, 20, 75, 13, 222, 169, 0, 161, 25, 3, 75, 1, 94, 170, 0, 176, 35, 47, 128, 252, 177, 6, 0, 162, 136, 20, 71, 77, 220, 169, 0, 161, 10, 19, 71, 9, 220, 169, 0, 176, 133, 47, 0, 162, 18, 34, 73, 9, 84, 73, 1, 47, 0, 176, 214, 47, 2, 47, 15, 104, 0, 161, 213, 3, 73, 5, 84, 73, 133, 41, 5, 104, 0, 176, 7, 48, 0, 240, 56, 48, 0, 176, 7, 48, 0, 240, 62, 49, 133, 41, 5, 104, 0, 176, 151, 49, 0, 240, 56, 48, 14, 34, 5, 104, 0, 176, 200, 49, 0, 240, 62, 49, 28, 34, 5, 104, 0, 176, 9, 50, 0, 240, 62, 49, 29, 34, 5, 104, 0, 176, 74, 50, 0, 240, 62, 49, 30, 34, 5, 104, 0, 176, 139, 50, 0, 240, 62, 49, 31, 34, 5, 104, 0, 176, 204, 50, 0, 240, 62, 49, 32, 34, 5, 104, 0, 176, 13, 51, 0, 240, 62, 49, 33, 34, 5, 104, 0, 176, 78, 51, 0, 240, 62, 49, 0, 176, 143, 51, 0, 240, 62, 49, 0, 161, 213, 3, 77, 5, 98, 170, 0, 162, 18, 34, 77, 9, 98, 170, 1, 47, 0, 176, 208, 51, 133, 41, 5, 104, 0, 176, 1, 52, 0, 240, 50, 52, 0, 176, 60, 53, 0, 240, 109, 53, 0, 161, 213, 3, 76, 9, 94, 170, 0, 162, 18, 2, 76, 9, 94, 170, 1, 47, 0, 176, 208, 51, 133, 41, 5, 104, 0, 176, 1, 52, 0, 240, 50, 52, 34, 34, 5, 104, 0, 176, 100, 47, 64, 246, 244, 53, 0, 176, 60, 53, 64, 246, 244, 53, 0, 161, 213, 3, 81, 9, 238, 188, 0, 162, 18, 34, 81, 9, 46, 173, 1, 47, 0, 176, 173, 54, 133, 41, 5, 104, 0, 176, 222, 54, 0, 240, 15, 55, 0, 176, 157, 57, 0, 240, 206, 57, 3, 13, 202, 100, 0, 145, 0, 161, 227, 83, 85, 9, 246, 221, 0, 162, 18, 2, 85, 9, 246, 221, 1, 47, 0, 176, 173, 54, 2, 47, 11, 104, 133, 41, 5, 104, 0, 176, 222, 54, 0, 240, 15, 55, 0, 176, 157, 57, 0, 240, 209, 58, 133, 41, 5, 104, 0, 176, 222, 54, 0, 240, 15, 55, 0, 176, 157, 57, 0, 240, 209, 58, 0, 161, 227, 83, 85, 9, 246, 221, 0, 162, 18, 2, 85, 41, 246, 221, 1, 47, 0, 176, 233, 59, 2, 47, 11, 104, 133, 41, 5, 104, 0, 176, 26, 60, 48, 242, 206, 57, 0, 176, 75, 60, 208, 242, 206, 57, 133, 41, 5, 104, 0, 176, 124, 60, 48, 242, 206, 57, 0, 176, 173, 60, 208, 242, 206, 57, 0, 161, 213, 3, 73, 9, 238, 172, 0, 162, 18, 34, 73, 9, 46, 173, 1, 47, 0, 176, 222, 60, 133, 41, 5, 104, 0, 176, 15, 61, 0, 240, 64, 61, 0, 176, 48, 62, 96, 249, 97, 62, 0, 161, 25, 3, 173, 9, 84, 90, 0, 162, 25, 18, 13, 9, 84, 73, 2, 47, 11, 104, 133, 41, 5, 104, 0, 176, 3, 63, 0, 240, 52, 63, 0, 176, 116, 65, 0, 240, 52, 63, 133, 41, 5, 104, 0, 176, 165, 65, 0, 240, 52, 63, 0, 176, 214, 65, 0, 240, 52, 63, 0, 161, 25, 3, 169, 1, 84, 90, 0, 162, 25, 18, 9, 1, 84, 73, 2, 47, 15, 104, 0, 162, 25, 50, 9, 5, 84, 73, 133, 41, 5, 104, 0, 176, 3, 63, 0, 240, 52, 63, 0, 176, 7, 66, 96, 249, 52, 63, 133, 41, 5, 104, 0, 176, 165, 65, 0, 240, 52, 63, 134, 40, 3, 43, 35, 10, 0, 176, 56, 66, 0, 240, 52, 63, 2, 13, 139, 202, 0, 161, 25, 3, 169, 1, 84, 90, 0, 162, 25, 18, 9, 1, 84, 73, 133, 41, 0, 176, 121, 66, 0, 176, 170, 66, 0, 162, 25, 18, 13, 1, 98, 170, 2, 47, 0, 161, 25, 3, 15, 0, 90, 170, 133, 41, 5, 104, 0, 176, 235, 66, 0, 240, 28, 67, 0, 176, 94, 69, 0, 240, 28, 67, 0, 162, 25, 18, 13, 1, 98, 170, 2, 47, 9, 104, 0, 161, 25, 3, 15, 0, 92, 170, 0, 162, 25, 50, 13, 5, 92, 170, 133, 41, 5, 104, 0, 176, 143, 69, 96, 244, 192, 69, 0, 176, 109, 72, 80, 245, 192, 69, 0, 161, 25, 3, 75, 1, 232, 171, 0, 162, 18, 34, 75, 9, 232, 171, 2, 47, 11, 104, 133, 41, 5, 104, 0, 176, 158, 72, 0, 240, 207, 72, 0, 176, 41, 75, 32, 248, 207, 72, 133, 41, 5, 104, 0, 176, 90, 75, 0, 240, 207, 72, 0, 176, 139, 75, 32, 248, 207, 72, 2, 13, 144, 202, 0, 161, 25, 3, 73, 1, 100, 171, 0, 162, 18, 34, 73, 9, 100, 171, 2, 47, 11, 104, 133, 41, 5, 104, 0, 176, 158, 72, 0, 240, 188, 75, 0, 176, 41, 75, 0, 240, 188, 75, 133, 41, 5, 104, 0, 176, 90, 75, 0, 240, 188, 75, 0, 176, 139, 75, 0, 240, 188, 75, 2, 13, 145, 202, 0, 161, 35, 83, 85, 9, 246, 221, 0, 162, 18, 34, 73, 9, 46, 173, 133, 41, 5, 104, 0, 176, 224, 77, 0, 245, 17, 78, 0, 176, 210, 80, 0, 245, 3, 81, 2, 13, 145, 202, 0, 161, 35, 83, 85, 9, 246, 221, 0, 162, 18, 34, 73, 9, 46, 173, 133, 41, 5, 104, 0, 176, 224, 77, 0, 240, 81, 83, 0, 176, 210, 80, 0, 245, 3, 86, 2, 13, 157, 202, 0, 161, 25, 3, 51, 5, 246, 221, 0, 162, 50, 18, 51, 5, 246, 221, 0, 176, 80, 88, 144, 241, 145, 88, 0, 161, 25, 3, 77, 9, 238, 188, 0, 162, 18, 34, 73, 9, 46, 173, 2, 47, 11, 104, 133, 41, 5, 104, 0, 176, 87, 90, 0, 240, 136, 90, 0, 176, 139, 92, 0, 240, 188, 92, 133, 41, 5, 104, 0, 176, 191, 94, 0, 240, 136, 90, 0, 176, 240, 94, 0, 240, 188, 92, 0, 161, 25, 3, 83, 9, 246, 221, 0, 162, 18, 34, 83, 9, 54, 220, 133, 41, 5, 104, 0, 176, 191, 94, 0, 240, 136, 90, 0, 176, 240, 94, 0, 240, 188, 92, 2, 13, 129, 202, 133, 41, 5, 104, 0, 176, 33, 95, 192, 243, 98, 95, 0, 176, 33, 95, 0, 245, 98, 95, 0, 161, 213, 26, 75, 1, 84, 115, 0, 162, 210, 18, 73, 1, 84, 65, 133, 41, 0, 192, 33, 98, 34, 34, 96, 196, 37, 100, 51, 50, 52, 34, 0, 192, 37, 100, 14, 34, 0, 192, 55, 101, 55, 34, 0, 192, 2, 102, 0, 192, 0, 103, 0, 161, 213, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 133, 41, 0, 192, 220, 103, 34, 50, 51, 50, 52, 34, 0, 192, 12, 105, 14, 34, 32, 195, 228, 106, 160, 197, 232, 107, 0, 161, 21, 28, 77, 5, 158, 162, 0, 162, 146, 18, 77, 1, 94, 162, 133, 41, 48, 194, 228, 106, 96, 196, 245, 108, 0, 161, 213, 3, 77, 1, 238, 188, 133, 41, 0, 192, 220, 109, 0, 192, 44, 112, 3, 13, 201, 116, 0, 149, 0, 161, 227, 83, 85, 1, 246, 221, 133, 41, 0, 192, 188, 113, 0, 192, 188, 113, 0, 161, 227, 83, 85, 1, 246, 221, 0, 162, 25, 18, 51, 37, 246, 221, 133, 41, 224, 193, 125, 115, 96, 201, 144, 116, 0, 161, 213, 3, 75, 1, 238, 172, 0, 162, 146, 18, 75, 1, 110, 189, 2, 47, 0, 162, 146, 18, 75, 1, 238, 172, 133, 41, 0, 192, 60, 117, 34, 50, 51, 50, 52, 34, 0, 192, 107, 118, 31, 50, 38, 34, 0, 192, 251, 119, 55, 34, 0, 192, 109, 121, 14, 34, 96, 196, 249, 122, 0, 192, 46, 124, 6, 161, 213, 19, 73, 5, 226, 155, 2, 162, 146, 20, 73, 5, 98, 155, 133, 41, 128, 194, 99, 125, 33, 34, 0, 197, 190, 125, 0, 195, 99, 125, 0, 162, 18, 2, 75, 1, 84, 65, 0, 41, 0, 192, 6, 126, 0, 192, 186, 128, 0, 161, 25, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 0, 41, 0, 192, 182, 130, 0, 192, 214, 132, 0, 161, 25, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 0, 41, 0, 192, 192, 69, 48, 50, 47, 50, 49, 34, 0, 192, 252, 134, 0, 192, 40, 137, 0, 161, 25, 3, 77, 1, 106, 172, 0, 162, 18, 2, 77, 1, 106, 172, 0, 41, 0, 192, 16, 139, 0, 192, 188, 141, 2, 13, 130, 202, 0, 161, 25, 3, 73, 1, 100, 171, 0, 162, 18, 2, 73, 1, 100, 171, 0, 41, 192, 195, 40, 144, 160, 197, 40, 144, 2, 13, 130, 202, 0, 161, 35, 83, 51, 5, 246, 221, 0, 162, 35, 82, 51, 5, 246, 221, 0, 41, 0, 192, 17, 78, 0, 192, 3, 81, 2, 13, 149, 201, 0, 161, 35, 83, 51, 5, 246, 221, 0, 162, 18, 66, 51, 5, 246, 221, 0, 41, 0, 192, 81, 83, 0, 192, 3, 86, 2, 13, 172, 201, 6, 106, 0, 208, 238, 21, 0, 208, 31, 22, 0, 208, 64, 22, 96, 223, 97, 22, 0, 208, 146, 22, 0, 208, 211, 22, 2, 39, 128, 237, 171, 24, 192, 195, 143, 146, 0, 161, 25, 3, 51, 1, 246, 221, 0, 162, 146, 18, 51, 1, 246, 221, 0, 41, 0, 192, 32, 149, 0, 192, 145, 88, 0, 161, 25, 3, 77, 1, 238, 188, 0, 162, 146, 18, 77, 1, 110, 189, 0, 41, 128, 199, 106, 151, 144, 193, 195, 153, 0, 41, 96, 196, 98, 95, 0, 192, 98, 95, 1, 13, 0, 104, 28, 34, 0, 192, 8, 156, 29, 34, 0, 192, 93, 157, 30, 34, 0, 192, 252, 158, 31, 34, 0, 192, 161, 160, 32, 34, 0, 192, 7, 162, 33, 34, 0, 192, 182, 163, 96, 196, 127, 165, 0, 161, 213, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 133, 41, 0, 192, 42, 167, 0, 192, 130, 169, 0, 161, 217, 19, 77, 5, 98, 170, 0, 162, 18, 2, 77, 9, 98, 170, 1, 47, 0, 176, 208, 51, 133, 41, 5, 104, 0, 176, 143, 69, 192, 243, 42, 167, 0, 176, 25, 172, 192, 248, 130, 169, 0, 161, 213, 3, 75, 1, 84, 115, 0, 162, 210, 19, 73, 1, 84, 65, 55, 34, 0, 192, 2, 102, 87, 41, 0, 192, 37, 100, 133, 41, 0, 197, 74, 172, 0, 192, 55, 101, 0, 161, 213, 3, 75, 1, 84, 115, 0, 162, 210, 19, 73, 1, 84, 65, 133, 41, 0, 192, 33, 98, 55, 34, 0, 192, 2, 102, 0, 192, 153, 172, 0, 161, 213, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 133, 41, 0, 192, 220, 103, 0, 192, 218, 173, 0, 161, 227, 83, 85, 1, 246, 221, 0, 162, 18, 2, 85, 33, 246, 221, 133, 41, 0, 192, 107, 174, 160, 197, 156, 175, 0, 161, 213, 3, 76, 1, 238, 172, 0, 162, 146, 18, 76, 1, 110, 189, 133, 41, 32, 195, 249, 122, 192, 195, 249, 122, 0, 161, 213, 3, 76, 1, 238, 172, 0, 162, 146, 18, 76, 1, 110, 189, 133, 41, 32, 195, 105, 176, 55, 34, 0, 192, 109, 121, 160, 197, 105, 176, 0, 161, 25, 3, 77, 1, 98, 170, 133, 41, 0, 192, 192, 69, 0, 192, 42, 178, 128, 40, 4, 104, 108, 1, 0, 176, 22, 180, 0, 176, 87, 180, 0, 176, 22, 180, 0, 176, 248, 0, 0, 176, 152, 180, 38, 5, 0, 176, 57, 1, 0, 176, 233, 180, 0, 176, 58, 181, 0, 176, 123, 181, 0, 176, 188, 181, 0, 176, 253, 181, 0, 176, 78, 182, 0, 176, 143, 182, 0, 176, 240, 182, 0, 176, 65, 183, 0, 176, 162, 183, 0, 176, 243, 183, 0, 176, 68, 184, 0, 176, 165, 184, 0, 176, 22, 185, 0, 145, 93, 1, 2, 41, 0, 176, 103, 185, 1, 0, 0, 161, 213, 3, 75, 1, 84, 115, 0, 162, 210, 19, 73, 1, 84, 65, 133, 41, 0, 197, 74, 172, 87, 41, 0, 192, 37, 100, 55, 34, 0, 192, 2, 102, 0, 192, 55, 101, 0, 161, 213, 3, 77, 1, 96, 170, 0, 162, 146, 18, 77, 1, 96, 162, 133, 41, 224, 193, 228, 106, 192, 195, 152, 185, 0, 161, 213, 3, 76, 9, 94, 170, 0, 162, 18, 2, 76, 9, 94, 170, 1, 47, 0, 176, 208, 51, 133, 41, 5, 104, 0, 176, 1, 52, 0, 240, 50, 52, 87, 41, 5, 104, 0, 176, 100, 47, 224, 246, 244, 53, 0, 176, 60, 53, 224, 246, 244, 53, 0, 161, 213, 3, 77, 1, 238, 188, 0, 162, 146, 18, 77, 1, 110, 189, 133, 41, 0, 192, 60, 117, 87, 41, 0, 192, 107, 118, 31, 50, 38, 34, 0, 192, 251, 119, 55, 34, 0, 192, 109, 121, 96, 196, 249, 122, 47, 1, 1, 0, 2, 13, 190, 201, 0, 161, 213, 3, 77, 5, 98, 170, 0, 162, 18, 2, 77, 9, 98, 170, 2, 47, 9, 104, 1, 47, 3, 104, 0, 176, 46, 186, 0, 176, 95, 186, 96, 244, 109, 53, 1, 47, 0, 176, 144, 186, 0, 176, 193, 186, 96, 244, 109, 53, 140, 39, 72, 1, 2, 96, 47, 1, 1, 0, 140, 39, 88, 1, 2, 96, 89, 1, 1, 0, 2, 43, 3, 0, 8, 104, 2, 55, 57, 48, 58, 32, 3, 104, 59, 1, 2, 96, 56, 1, 0, 145, 208, 0, 1, 0, 0, 161, 213, 3, 73, 9, 238, 172, 0, 162, 18, 34, 73, 9, 46, 173, 1, 47, 0, 176, 222, 60, 133, 41, 5, 104, 0, 176, 15, 61, 0, 240, 242, 186, 0, 176, 48, 62, 0, 240, 242, 186, 2, 13, 185, 201, 6, 106, 0, 208, 226, 187, 0, 208, 19, 188, 0, 208, 68, 188, 0, 208, 133, 188, 0, 208, 182, 188, 0, 208, 231, 188, 2, 39, 64, 236, 236, 5, 0, 176, 95, 6, 69, 39, 113, 3, 140, 39, 3, 0, 89, 1, 88, 1, 1, 0, 44, 5, 136, 40, 0, 176, 24, 189, 0, 176, 85, 0, 0, 145, 127, 7, 2, 13, 153, 201, 1, 0, 2, 41, 113, 1, 0, 176, 85, 0, 2, 57, 0, 41, 117, 1, 0, 176, 85, 0, 3, 13, 153, 201, 0, 108, 0, 145, 194, 0, 0, 176, 89, 189, 119, 16, 129, 40, 0, 176, 138, 189, 0, 176, 183, 0, 2, 13, 144, 201, 0, 176, 203, 189, 1, 13, 0, 97, 44, 5, 0, 176, 183, 0, 113, 16, 0, 176, 12, 190, 38, 5, 0, 176, 77, 190, 38, 5, 0, 176, 142, 190, 38, 5, 113, 1, 1, 0, 2, 13, 170, 201, 38, 5, 0, 176, 207, 190, 13, 16, 0, 176, 16, 191, 13, 16, 0, 176, 81, 191, 0, 176, 146, 191, 44, 5, 0, 176, 211, 191, 4, 13, 145, 201, 144, 203, 44, 5, 0, 176, 211, 191, 44, 5, 13, 16, 0, 176, 52, 192, 38, 5, 58, 32, 0, 208, 133, 192, 0, 176, 198, 192, 13, 16, 0, 176, 23, 193, 13, 16, 0, 176, 23, 193, 4, 13, 148, 201, 144, 203, 44, 5, 0, 176, 23, 193, 4, 13, 148, 201, 144, 203, 44, 5, 0, 176, 23, 193, 59, 34, 0, 176, 104, 193, 57, 37, 90, 10, 0, 176, 185, 193, 0, 176, 10, 194, 4, 13, 153, 201, 138, 202, 0, 176, 107, 194, 29, 34, 38, 4, 0, 176, 204, 194, 0, 176, 68, 184, 0, 176, 61, 195, 44, 5, 0, 176, 152, 180, 44, 5, 0, 176, 174, 195, 44, 5, 0, 176, 174, 195, 44, 5, 129, 40, 0, 176, 15, 196, 0, 176, 96, 196, 44, 5, 0, 176, 193, 196, 144, 1, 1, 0, 44, 5, 0, 176, 50, 197, 4, 13, 153, 201, 185, 201, 44, 36, 3, 104, 2, 13, 153, 201, 44, 5, 0, 176, 147, 197, 4, 13, 140, 202, 185, 201, 44, 36, 3, 104, 2, 13, 140, 202, 44, 5, 0, 176, 228, 197, 0, 176, 233, 180, 0, 176, 53, 198, 0, 176, 134, 198, 0, 176, 248, 0, 0, 176, 215, 198, 111, 5, 0, 145, 82, 2, 1, 0, 2, 13, 153, 201, 44, 5, 0, 176, 8, 199, 119, 16, 0, 176, 183, 0, 113, 16, 0, 176, 57, 199, 38, 5, 0, 176, 122, 199, 38, 5, 0, 176, 122, 199, 38, 5, 0, 176, 187, 199, 13, 16, 0, 176, 252, 199, 2, 13, 138, 202, 13, 16, 0, 176, 61, 200, 0, 176, 146, 191, 2, 13, 144, 201, 44, 5, 0, 176, 203, 189, 44, 5, 0, 176, 126, 200, 4, 13, 145, 201, 144, 203, 44, 5, 0, 176, 126, 200, 1, 13, 0, 97, 0, 176, 183, 0, 44, 5, 13, 16, 0, 176, 207, 200, 38, 5, 58, 32, 0, 208, 133, 192, 0, 176, 57, 1, 44, 5, 13, 16, 0, 176, 32, 201, 4, 13, 148, 201, 144, 203, 44, 5, 0, 176, 113, 201, 4, 13, 148, 201, 144, 203, 44, 5, 0, 176, 113, 201, 13, 16, 0, 176, 23, 193, 0, 176, 178, 201, 4, 13, 166, 195, 138, 202, 0, 176, 3, 202, 3, 13, 203, 111, 0, 144, 0, 176, 233, 180, 0, 176, 84, 202, 3, 13, 203, 101, 0, 144, 0, 176, 248, 0, 0, 176, 61, 195, 44, 5, 0, 176, 181, 202, 44, 5, 0, 176, 6, 203, 44, 5, 0, 176, 96, 196, 44, 5, 0, 176, 193, 196, 144, 1, 1, 0, 44, 5, 0, 176, 50, 197, 2, 13, 154, 201, 44, 5, 0, 176, 119, 203, 87, 41, 114, 1, 0, 176, 184, 203, 0, 176, 233, 203, 2, 41, 113, 1, 0, 176, 233, 203, 3, 13, 153, 201, 0, 108, 0, 176, 89, 189, 2, 13, 166, 195, 119, 16, 8, 41, 0, 176, 26, 204, 0, 176, 107, 204, 2, 13, 144, 201, 0, 176, 203, 189, 113, 16, 0, 176, 172, 204, 38, 5, 113, 16, 0, 176, 142, 190, 38, 5, 0, 176, 237, 204, 0, 176, 46, 205, 38, 5, 0, 176, 111, 205, 4, 13, 145, 201, 144, 203, 13, 16, 34, 34, 130, 1, 0, 176, 176, 205, 13, 16, 0, 176, 241, 205, 0, 176, 50, 206, 34, 34, 0, 176, 115, 206, 0, 176, 176, 205, 6, 13, 145, 201, 144, 203, 185, 201, 44, 34, 4, 104, 4, 13, 145, 201, 144, 203, 130, 10, 44, 5, 0, 176, 115, 206, 44, 5, 0, 176, 212, 206, 38, 5, 0, 176, 198, 192, 13, 16, 34, 34, 0, 176, 37, 207, 0, 176, 118, 207, 6, 13, 148, 201, 144, 203, 185, 201, 34, 36, 4, 104, 4, 13, 148, 201, 144, 203, 34, 5, 0, 176, 37, 207, 5, 13, 203, 111, 201, 144, 0, 185, 34, 36, 4, 104, 3, 13, 203, 111, 0, 144, 34, 5, 0, 176, 183, 207, 13, 16, 0, 176, 8, 208, 0, 176, 73, 208, 0, 176, 154, 208, 0, 176, 235, 208, 29, 50, 32, 34, 38, 4, 0, 176, 60, 209, 0, 176, 157, 209, 0, 176, 238, 209, 4, 13, 155, 201, 185, 201, 34, 36, 3, 104, 2, 13, 155, 201, 34, 5, 0, 176, 63, 210, 0, 176, 174, 195, 4, 13, 170, 201, 185, 201, 34, 36, 3, 104, 2, 13, 170, 201, 34, 5, 0, 176, 160, 210, 4, 13, 138, 202, 185, 201, 44, 36, 3, 104, 2, 13, 138, 202, 44, 5, 0, 176, 1, 211, 5, 13, 201, 97, 201, 170, 0, 153, 44, 5, 0, 176, 82, 211, 5, 13, 201, 97, 201, 170, 0, 154, 44, 5, 0, 176, 179, 211, 7, 13, 201, 97, 202, 170, 201, 138, 0, 185, 34, 36, 5, 104, 5, 13, 201, 97, 202, 170, 0, 138, 34, 5, 0, 176, 20, 212, 2, 60, 50, 37, 9, 104, 2, 43, 129, 41, 6, 104, 50, 35, 135, 42, 2, 104, 2, 96, 25, 1, 0, 161, 213, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 133, 41, 0, 192, 220, 103, 34, 50, 51, 50, 52, 34, 0, 192, 12, 105, 14, 34, 32, 195, 228, 106, 160, 197, 232, 107, 44, 5, 0, 176, 215, 198, 2, 41, 13, 1, 44, 5, 0, 41, 0, 176, 228, 197, 0, 176, 133, 212, 2, 41, 113, 1, 0, 176, 215, 198, 2, 57, 0, 41, 117, 1, 0, 176, 215, 198, 119, 16, 154, 18, 0, 176, 198, 212, 119, 16, 0, 176, 198, 212, 2, 13, 144, 201, 44, 5, 0, 176, 22, 180, 2, 13, 58, 97, 44, 5, 0, 176, 198, 212, 113, 16, 0, 176, 7, 213, 59, 34, 5, 104, 32, 238, 210, 25, 0, 176, 215, 198, 0, 176, 72, 213, 0, 145, 177, 9, 1, 0, 1, 13, 0, 101, 38, 5, 0, 176, 137, 213, 13, 16, 0, 176, 202, 213, 13, 16, 0, 176, 11, 214, 2, 13, 137, 202, 0, 176, 76, 214, 2, 13, 58, 97, 44, 5, 34, 34, 4, 104, 125, 10, 0, 176, 141, 214, 0, 176, 198, 212, 3, 13, 203, 97, 0, 144, 34, 4, 0, 176, 141, 214, 148, 18, 1, 13, 0, 101, 34, 4, 0, 176, 254, 214, 38, 5, 58, 32, 0, 208, 133, 192, 7, 57, 0, 41, 90, 10, 0, 176, 79, 215, 13, 16, 34, 34, 0, 176, 183, 207, 0, 176, 122, 1, 2, 13, 148, 201, 34, 4, 0, 176, 144, 215, 1, 13, 0, 111, 34, 4, 0, 176, 209, 215, 13, 16, 0, 176, 118, 207, 4, 13, 137, 202, 144, 203, 7, 41, 100, 10, 0, 41, 4, 104, 100, 10, 0, 176, 76, 214, 0, 176, 50, 216, 4, 13, 140, 202, 137, 202, 0, 176, 115, 216, 3, 13, 203, 111, 0, 144, 0, 176, 196, 216, 2, 57, 7, 41, 155, 1, 59, 34, 0, 176, 21, 217, 0, 176, 118, 217, 0, 176, 118, 217, 3, 13, 203, 101, 0, 144, 0, 176, 215, 217, 0, 176, 24, 218, 1, 13, 0, 101, 34, 4, 0, 176, 254, 214, 2, 13, 170, 201, 34, 4, 0, 176, 121, 218, 4, 13, 137, 202, 185, 201, 44, 34, 3, 104, 2, 13, 137, 202, 120, 10, 44, 5, 0, 176, 202, 218, 44, 5, 0, 176, 50, 197, 44, 5, 0, 176, 21, 217, 144, 1, 1, 0, 3, 13, 153, 201, 0, 108, 0, 145, 194, 0, 0, 176, 27, 219, 0, 176, 0, 0, 138, 41, 46, 1, 0, 145, 72, 0, 1, 0, 44, 5, 136, 40, 0, 176, 92, 219, 0, 176, 85, 0, 0, 145, 79, 10, 2, 13, 153, 201, 1, 0, 2, 41, 113, 1, 0, 176, 92, 219, 2, 57, 0, 41, 117, 1, 0, 176, 92, 219, 2, 13, 166, 195, 119, 16, 0, 176, 141, 219, 113, 16, 0, 176, 206, 219, 38, 5, 0, 176, 122, 199, 38, 5, 0, 176, 122, 199, 38, 5, 0, 176, 111, 205, 13, 16, 0, 176, 118, 207, 13, 16, 0, 176, 15, 220, 0, 176, 80, 220, 2, 13, 144, 201, 44, 5, 0, 176, 92, 219, 44, 5, 0, 176, 145, 220, 4, 13, 145, 201, 144, 203, 44, 5, 0, 176, 145, 220, 4, 13, 145, 201, 144, 203, 0, 176, 145, 220, 13, 16, 44, 5, 0, 176, 226, 220, 38, 5, 58, 32, 0, 208, 133, 192, 0, 176, 57, 1, 13, 16, 44, 5, 0, 176, 32, 201, 4, 13, 148, 201, 144, 203, 44, 5, 0, 176, 32, 201, 13, 16, 0, 176, 23, 193, 0, 176, 51, 221, 0, 176, 116, 221, 4, 13, 153, 201, 138, 202, 0, 176, 213, 221, 29, 50, 32, 34, 38, 4, 0, 176, 38, 222, 0, 176, 151, 222, 0, 176, 232, 222, 44, 5, 0, 176, 73, 223, 44, 5, 0, 176, 154, 223, 4, 13, 148, 201, 144, 203, 44, 5, 0, 176, 251, 223, 44, 5, 0, 176, 193, 196, 144, 1, 1, 0, 44, 5, 0, 176, 60, 224, 111, 5, 0, 145, 82, 2, 1, 0, 119, 16, 0, 176, 183, 0, 113, 16, 0, 176, 248, 0, 38, 5, 55, 50, 59, 34, 0, 176, 122, 199, 0, 176, 157, 224, 38, 5, 0, 176, 57, 1, 13, 16, 0, 176, 58, 181, 2, 13, 138, 202, 13, 16, 0, 176, 61, 200, 23, 5, 0, 176, 146, 191, 2, 13, 144, 201, 0, 176, 203, 189, 44, 5, 0, 176, 126, 200, 4, 13, 145, 201, 144, 203, 44, 5, 0, 176, 126, 200, 1, 13, 0, 97, 0, 176, 183, 0, 13, 16, 44, 5, 0, 176, 78, 182, 2, 13, 105, 101, 38, 5, 0, 176, 206, 224, 13, 16, 44, 5, 0, 176, 32, 201, 4, 13, 148, 201, 144, 203, 44, 5, 0, 176, 32, 201, 13, 16, 0, 176, 32, 201, 3, 13, 153, 201, 0, 117, 0, 176, 31, 225, 4, 13, 166, 195, 138, 202, 0, 176, 3, 202, 4, 13, 140, 202, 138, 202, 0, 176, 112, 225, 4, 13, 148, 201, 170, 201, 0, 176, 232, 222, 3, 13, 203, 101, 0, 144, 0, 176, 209, 225, 3, 13, 201, 111, 0, 170, 0, 176, 165, 184, 4, 13, 156, 201, 144, 203, 44, 5, 0, 176, 52, 192, 44, 5, 0, 176, 34, 226, 44, 5, 0, 176, 96, 196, 44, 5, 0, 176, 131, 226, 144, 1, 1, 0, 44, 5, 0, 176, 50, 197, 44, 5, 0, 176, 244, 226, 2, 41, 113, 1, 0, 176, 244, 226, 0, 176, 87, 180, 113, 16, 0, 176, 248, 0, 38, 5, 0, 176, 157, 224, 38, 5, 0, 176, 157, 224, 38, 5, 0, 176, 57, 1, 0, 176, 8, 208, 0, 176, 58, 181, 0, 176, 53, 227, 0, 176, 22, 180, 0, 176, 87, 180, 44, 5, 0, 176, 87, 180, 0, 176, 87, 180, 44, 5, 0, 176, 58, 181, 38, 5, 0, 176, 118, 227, 0, 176, 122, 1, 44, 5, 0, 176, 122, 1, 44, 5, 0, 176, 183, 227, 0, 176, 122, 1, 0, 176, 187, 1, 0, 176, 8, 228, 0, 176, 233, 180, 0, 176, 162, 183, 0, 176, 248, 0, 0, 176, 24, 218, 44, 5, 0, 176, 254, 214, 44, 5, 0, 176, 89, 228, 46, 34, 4, 104, 95, 10, 0, 176, 170, 228, 0, 176, 219, 228, 2, 13, 144, 201, 0, 176, 81, 191, 0, 176, 12, 229, 2, 13, 153, 201, 46, 34, 4, 104, 95, 10, 0, 176, 170, 228, 0, 176, 77, 229, 0, 176, 126, 229, 0, 176, 175, 229, 0, 176, 224, 229, 59, 34, 32, 238, 17, 230, 0, 176, 66, 230, 59, 34, 32, 238, 17, 230, 0, 176, 66, 230, 3, 13, 153, 201, 0, 108, 0, 176, 89, 189, 0, 176, 115, 230, 3, 13, 201, 105, 0, 153, 0, 176, 180, 230, 38, 5, 0, 176, 21, 231, 4, 13, 138, 202, 153, 201, 0, 176, 86, 231, 0, 176, 183, 231, 0, 176, 248, 231, 0, 176, 105, 232, 38, 5, 0, 176, 202, 232, 38, 5, 0, 176, 43, 233, 4, 13, 155, 201, 170, 201, 38, 5, 0, 176, 156, 233, 38, 5, 0, 176, 237, 233, 4, 13, 138, 202, 170, 201, 38, 5, 0, 176, 94, 234, 38, 5, 0, 176, 207, 234, 38, 5, 0, 176, 48, 235, 0, 176, 145, 235, 0, 176, 10, 194, 0, 176, 248, 0, 0, 176, 32, 201, 0, 176, 52, 192, 0, 176, 226, 235, 0, 176, 51, 236, 0, 176, 116, 236, 0, 161, 25, 3, 173, 1, 238, 188, 0, 162, 146, 18, 173, 1, 110, 189, 192, 195, 197, 236, 0, 161, 25, 3, 64, 9, 118, 90, 0, 162, 18, 2, 64, 9, 98, 90, 6, 106, 16, 223, 198, 4, 16, 223, 247, 4, 16, 223, 40, 5, 16, 223, 89, 5, 16, 223, 138, 5, 16, 223, 187, 5, 2, 39, 224, 236, 236, 5, 0, 176, 254, 13, 64, 246, 218, 16, 13, 48, 109, 32, 2, 104, 5, 96, 0, 176, 233, 11, 0, 240, 177, 6, 1, 0, 0, 161, 213, 3, 83, 1, 246, 221, 0, 162, 146, 18, 83, 1, 246, 221, 0, 192, 251, 119, 0, 176, 183, 0, 0, 176, 27, 239, 2, 13, 168, 201, 0, 176, 92, 239, 0, 176, 46, 205, 0, 176, 202, 213, 0, 176, 123, 181, 0, 176, 85, 0, 109, 18, 0, 176, 57, 1, 4, 13, 168, 201, 144, 203, 110, 18, 0, 176, 157, 239, 112, 18, 0, 176, 187, 1, 108, 18, 0, 176, 248, 0, 111, 18, 0, 176, 222, 239, 35, 18, 0, 176, 211, 191, 4, 13, 145, 201, 168, 201, 0, 176, 43, 233, 0, 176, 204, 194, 3, 13, 201, 97, 0, 168, 0, 176, 204, 194, 0, 176, 143, 182, 0, 176, 156, 233, 4, 13, 153, 201, 168, 201, 0, 176, 156, 233, 0, 176, 240, 182, 0, 176, 47, 240, 3, 13, 168, 201, 0, 117, 0, 176, 47, 240, 0, 176, 61, 195, 4, 13, 148, 201, 168, 201, 0, 176, 61, 195, 0, 176, 128, 240, 3, 13, 201, 117, 0, 168, 0, 176, 128, 240, 0, 161, 25, 3, 75, 1, 96, 170, 0, 162, 18, 34, 75, 9, 96, 170, 0, 176, 10, 12, 16, 244, 59, 12, 0, 161, 213, 3, 73, 9, 238, 172, 0, 162, 18, 34, 73, 9, 46, 173, 1, 47, 0, 176, 222, 60, 133, 41, 5, 104, 0, 176, 15, 61, 192, 248, 64, 61, 0, 176, 48, 62, 96, 249, 97, 62, 34, 34, 5, 104, 2, 42, 2, 104, 2, 96, 108, 1, 0, 176, 184, 203, 139, 40, 105, 10, 0, 176, 203, 189, 87, 41, 62, 10, 0, 176, 183, 0, 16, 34, 67, 10, 0, 176, 12, 229, 13, 16, 16, 34, 67, 10, 0, 176, 12, 229, 16, 34, 67, 10, 38, 5, 0, 176, 122, 199, 0, 176, 122, 199, 16, 34, 67, 10, 0, 176, 122, 1, 16, 34, 67, 10, 34, 34, 5, 104, 2, 42, 2, 104, 2, 96, 115, 1, 0, 176, 188, 181, 0, 176, 225, 240, 35, 17, 0, 176, 225, 240, 58, 32, 0, 208, 133, 192, 0, 176, 50, 241, 111, 18, 58, 32, 0, 208, 133, 192, 0, 176, 50, 241, 0, 176, 187, 1, 0, 176, 115, 241, 0, 176, 212, 241, 0, 176, 68, 184, 0, 176, 165, 184, 0, 176, 37, 242, 0, 176, 215, 217, 0, 176, 233, 180, 0, 176, 253, 181, 2, 13, 143, 202, 16, 34, 57, 10, 0, 176, 102, 242, 0, 176, 78, 182, 16, 34, 80, 10, 0, 176, 175, 229, 2, 13, 102, 112, 0, 162, 18, 2, 75, 1, 84, 65, 0, 192, 186, 128, 140, 43, 81, 1, 2, 96, 99, 1, 1, 0, 2, 41, 55, 1, 6, 108, 64, 236, 4, 23, 128, 237, 69, 23, 32, 238, 134, 23, 32, 238, 183, 23, 128, 237, 248, 23, 128, 237, 73, 24, 0, 176, 167, 242, 2, 41, 21, 104, 6, 106, 0, 208, 82, 32, 0, 208, 147, 32, 0, 208, 212, 32, 0, 208, 21, 33, 0, 208, 70, 33, 0, 208, 151, 33, 32, 238, 200, 33, 0, 39, 3, 104, 0, 176, 200, 242, 7, 96, 0, 162, 35, 18, 0, 0, 0, 0, 0, 176, 10, 34, 1, 0, 14, 37, 2, 104, 11, 96, 2, 43, 9, 104, 2, 44, 3, 104, 51, 1, 5, 96, 47, 37, 2, 104, 2, 96, 14, 3, 92, 39, 1, 1, 0, 145, 137, 2, 1, 0, 2, 13, 128, 202, 2, 43, 5, 104, 0, 176, 235, 17, 32, 243, 44, 18, 92, 39, 3, 104, 1, 1, 2, 96, 136, 1, 1, 0, 2, 43, 34, 1, 2, 13, 144, 201, 29, 48, 109, 32, 0, 176, 233, 242, 33, 32, 0, 176, 26, 243, 0, 176, 75, 243, 4, 13, 138, 202, 144, 201, 0, 176, 124, 243, 0, 176, 205, 243, 55, 1, 1, 0, 139, 34, 48, 1, 0, 145, 193, 2, 1, 0, 139, 34, 47, 1, 0, 145, 12, 3, 1, 0, 139, 34, 49, 1, 0, 145, 150, 3, 1, 0, 0, 176, 87, 180, 0, 176, 12, 229, 38, 5, 0, 176, 57, 1, 136, 40, 0, 176, 233, 180, 0, 176, 32, 201, 0, 176, 187, 1, 0, 176, 143, 182, 0, 176, 240, 182, 0, 176, 162, 183, 0, 176, 34, 244, 0, 176, 237, 233, 0, 176, 22, 185, 0, 176, 12, 229, 0, 176, 12, 229, 38, 5, 108, 17, 0, 176, 115, 244, 38, 5, 0, 176, 92, 239, 0, 176, 12, 229, 0, 176, 141, 219, 0, 176, 180, 244, 0, 176, 8, 208, 0, 176, 32, 201, 0, 176, 78, 182, 0, 176, 123, 181, 0, 176, 245, 244, 0, 176, 54, 245, 0, 176, 253, 181, 0, 176, 119, 245, 0, 176, 216, 245, 0, 176, 61, 195, 0, 176, 34, 244, 0, 176, 41, 246, 0, 176, 122, 246, 0, 176, 203, 246, 0, 176, 28, 247, 0, 176, 125, 247, 0, 176, 206, 247, 0, 176, 31, 248, 0, 176, 128, 248, 0, 176, 209, 248, 0, 176, 34, 249, 0, 176, 115, 249, 0, 176, 196, 249, 0, 176, 89, 228, 0, 176, 21, 250, 1, 13, 0, 114, 0, 161, 25, 3, 73, 1, 98, 170, 0, 162, 18, 34, 73, 9, 98, 170, 0, 176, 102, 250, 32, 243, 63, 14, 0, 161, 25, 3, 169, 1, 84, 90, 0, 162, 25, 18, 9, 1, 84, 73, 133, 41, 0, 176, 165, 65, 0, 176, 56, 66, 0, 161, 213, 3, 79, 9, 98, 155, 0, 162, 146, 18, 79, 9, 98, 155, 1, 47, 0, 176, 208, 51, 133, 41, 5, 104, 0, 176, 1, 52, 0, 240, 50, 52, 34, 34, 5, 104, 0, 176, 100, 47, 192, 243, 244, 53, 0, 176, 60, 53, 192, 243, 244, 53, 28, 34, 0, 192, 8, 156, 29, 34, 0, 192, 93, 157, 30, 34, 0, 192, 252, 158, 31, 34, 0, 192, 161, 160, 32, 34, 96, 196, 167, 250, 33, 34, 0, 197, 167, 250, 96, 196, 127, 165, 0, 176, 180, 244, 0, 176, 227, 252, 0, 176, 176, 205, 0, 176, 72, 213, 0, 176, 36, 253, 0, 176, 101, 253, 0, 176, 166, 253, 0, 176, 231, 253, 0, 176, 92, 239, 0, 176, 40, 254, 0, 176, 251, 223, 0, 176, 233, 180, 0, 176, 58, 181, 0, 176, 105, 254, 0, 176, 170, 254, 0, 176, 235, 254, 0, 176, 44, 255, 0, 176, 109, 255, 0, 176, 141, 219, 0, 176, 141, 219, 0, 176, 78, 182, 0, 176, 78, 182, 0, 176, 253, 181, 0, 176, 253, 181, 0, 176, 216, 245, 0, 176, 174, 255, 0, 176, 203, 246, 0, 161, 25, 3, 169, 1, 84, 90, 0, 162, 25, 18, 9, 1, 84, 73, 133, 41, 0, 176, 165, 65, 0, 176, 56, 66, 0, 161, 21, 29, 77, 5, 158, 162, 0, 162, 146, 18, 77, 1, 94, 162, 133, 41, 192, 195, 228, 106, 0, 197, 245, 108, 0, 161, 213, 3, 79, 9, 98, 155, 0, 162, 146, 18, 79, 9, 98, 155, 1, 47, 0, 176, 208, 51, 133, 41, 5, 104, 0, 176, 1, 52, 0, 240, 50, 52, 34, 34, 5, 104, 0, 176, 100, 47, 192, 243, 244, 53, 0, 176, 60, 53, 192, 243, 244, 53, 50, 34, 5, 104, 0, 176, 144, 6, 0, 240, 177, 6, 0, 176, 233, 11, 0, 240, 177, 6, 0, 161, 213, 3, 77, 1, 238, 188, 0, 162, 146, 18, 77, 1, 110, 189, 0, 41, 0, 192, 249, 122, 31, 50, 61, 34, 128, 194, 251, 119, 55, 34, 128, 194, 109, 121, 34, 34, 128, 194, 107, 118, 49, 34, 160, 192, 249, 122, 64, 193, 249, 122, 28, 34, 0, 192, 8, 156, 29, 34, 0, 192, 93, 157, 30, 34, 0, 192, 252, 158, 31, 34, 0, 192, 161, 160, 32, 34, 0, 192, 7, 162, 33, 34, 0, 192, 182, 163, 96, 196, 127, 165, 0, 161, 25, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 0, 192, 255, 255, 0, 161, 227, 83, 85, 1, 246, 221, 0, 162, 25, 18, 51, 37, 246, 221, 133, 41, 192, 195, 125, 115, 0, 197, 245, 108, 0, 161, 232, 83, 83, 9, 246, 221, 0, 162, 50, 82, 83, 41, 246, 221, 1, 47, 1, 176, 44, 2, 133, 41, 5, 104, 0, 176, 1, 52, 129, 242, 93, 2, 87, 41, 5, 104, 0, 176, 100, 47, 1, 245, 93, 2, 0, 176, 60, 53, 1, 245, 93, 2, 111, 32, 1, 224, 98, 3, 33, 96, 112, 32, 1, 224, 131, 3, 29, 96, 113, 32, 1, 224, 164, 3, 25, 96, 114, 48, 115, 32, 1, 224, 197, 3, 20, 96, 116, 32, 1, 224, 246, 3, 16, 96, 2, 39, 14, 104, 6, 108, 1, 224, 39, 4, 1, 224, 72, 4, 1, 224, 105, 4, 1, 224, 138, 4, 1, 224, 171, 4, 1, 224, 204, 4, 1, 0, 112, 34, 1, 208, 237, 4, 46, 96, 117, 34, 1, 208, 14, 5, 42, 96, 113, 34, 1, 208, 47, 5, 38, 96, 114, 50, 115, 34, 1, 208, 80, 5, 33, 96, 111, 34, 1, 208, 113, 5, 29, 96, 58, 34, 1, 208, 146, 5, 25, 96, 116, 34, 1, 208, 179, 5, 21, 96, 57, 50, 118, 34, 1, 208, 212, 5, 16, 96, 2, 41, 14, 104, 6, 106, 1, 208, 245, 5, 1, 208, 22, 6, 1, 208, 55, 6, 1, 208, 88, 6, 1, 208, 121, 6, 1, 208, 154, 6, 1, 0, 0, 161, 25, 3, 71, 1, 222, 185, 2, 13, 129, 202, 138, 41, 46, 1, 4, 96, 138, 55, 0, 39, 119, 1, 0, 145, 248, 14, 0, 145, 29, 15, 1, 176, 187, 6, 2, 13, 129, 202, 138, 41, 1, 1, 2, 96, 34, 1, 1, 0, 2, 13, 129, 202, 47, 53, 48, 53, 49, 37, 5, 104, 1, 176, 220, 6, 240, 240, 177, 6, 138, 39, 5, 104, 1, 176, 13, 7, 240, 240, 177, 6, 6, 108, 1, 224, 46, 7, 1, 224, 79, 7, 1, 224, 112, 7, 1, 224, 145, 7, 1, 224, 178, 7, 1, 224, 211, 7, 111, 32, 1, 224, 244, 7, 8, 41, 5, 104, 1, 176, 21, 8, 64, 241, 177, 6, 109, 34, 15, 10, 1, 176, 70, 8, 64, 241, 177, 6, 0, 161, 25, 3, 71, 1, 222, 185, 2, 13, 129, 202, 0, 145, 29, 15, 83, 53, 49, 53, 48, 53, 89, 53, 47, 53, 91, 37, 1, 176, 103, 8, 110, 37, 1, 176, 168, 8, 40, 10, 1, 176, 187, 6, 1, 0, 138, 41, 56, 1, 3, 96, 110, 37, 59, 1, 6, 106, 0, 208, 238, 21, 96, 223, 31, 22, 16, 223, 64, 22, 16, 223, 97, 22, 97, 223, 233, 8, 192, 222, 211, 22, 28, 32, 224, 236, 171, 24, 4, 96, 2, 39, 128, 237, 171, 24, 0, 55, 134, 40, 0, 176, 204, 24, 87, 55, 8, 39, 0, 176, 204, 24, 47, 32, 0, 176, 253, 24, 56, 32, 0, 176, 30, 25, 0, 176, 63, 25, 2, 41, 55, 1, 111, 37, 1, 224, 10, 9, 16, 96, 2, 44, 14, 104, 6, 108, 0, 224, 230, 26, 0, 224, 7, 27, 0, 224, 40, 27, 0, 224, 73, 27, 0, 224, 122, 27, 0, 224, 171, 27, 109, 32, 0, 176, 204, 24, 0, 176, 138, 24, 138, 41, 56, 1, 6, 106, 0, 208, 238, 21, 96, 223, 31, 22, 16, 223, 64, 22, 16, 223, 97, 22, 96, 223, 146, 22, 192, 222, 211, 22, 47, 32, 0, 176, 253, 24, 0, 176, 63, 25, 1, 176, 43, 9, 1, 176, 43, 9, 2, 43, 110, 10, 2, 96, 85, 10, 1, 176, 92, 9, 81, 181, 92, 9, 56, 34, 192, 238, 171, 24, 5, 96, 2, 41, 100, 10, 2, 96, 85, 10, 0, 176, 37, 242, 0, 176, 37, 242, 57, 36, 95, 10, 2, 96, 85, 10, 0, 176, 206, 219, 0, 176, 206, 219, 119, 53, 59, 37, 5, 104, 2, 43, 2, 104, 120, 10, 16, 96, 109, 37, 2, 43, 8, 104, 31, 36, 4, 104, 110, 10, 38, 5, 2, 96, 118, 1, 6, 96, 2, 43, 57, 1, 3, 96, 75, 10, 38, 5, 0, 176, 166, 253, 6, 106, 0, 208, 82, 32, 0, 208, 147, 32, 0, 208, 212, 32, 0, 208, 21, 33, 0, 208, 70, 33, 0, 208, 151, 33, 1, 176, 157, 9, 2, 41, 110, 10, 2, 96, 85, 10, 139, 40, 1, 176, 222, 9, 0, 176, 233, 180, 1, 0, 139, 40, 1, 176, 47, 10, 108, 36, 138, 42, 1, 176, 47, 10, 109, 36, 138, 42, 1, 176, 47, 10, 0, 176, 251, 223, 2, 57, 57, 34, 110, 10, 2, 96, 90, 10, 0, 176, 105, 254, 0, 176, 105, 254, 114, 52, 31, 36, 4, 104, 55, 10, 0, 181, 253, 181, 90, 10, 0, 176, 253, 181, 0, 176, 253, 181, 0, 176, 24, 189, 0, 176, 24, 189, 0, 176, 78, 182, 109, 48, 108, 37, 15, 104, 6, 106, 0, 208, 104, 30, 1, 208, 112, 10, 0, 208, 202, 30, 0, 208, 251, 30, 0, 208, 44, 31, 0, 208, 93, 31, 2, 96, 133, 1, 1, 0, 2, 41, 23, 104, 6, 106, 0, 208, 104, 30, 1, 208, 112, 10, 0, 208, 202, 30, 0, 208, 251, 30, 0, 208, 44, 31, 0, 208, 93, 31, 32, 238, 142, 31, 0, 39, 3, 104, 0, 176, 175, 31, 0, 176, 175, 31, 11, 96, 0, 162, 25, 18, 0, 0, 0, 0, 31, 32, 3, 104, 0, 176, 224, 31, 0, 176, 33, 32, 1, 0, 0, 176, 205, 243, 134, 34, 0, 176, 206, 219, 1, 176, 161, 10, 1, 176, 242, 10, 1, 176, 161, 10, 0, 161, 213, 3, 173, 9, 84, 90, 0, 162, 18, 34, 73, 9, 84, 73, 2, 47, 15, 104, 0, 161, 213, 3, 73, 5, 84, 73, 133, 41, 5, 104, 0, 176, 7, 48, 0, 240, 56, 48, 0, 176, 7, 48, 0, 240, 62, 49, 1, 47, 7, 104, 109, 36, 3, 104, 1, 176, 67, 11, 0, 176, 214, 47, 133, 57, 55, 34, 5, 104, 0, 176, 151, 49, 0, 240, 56, 48, 56, 34, 0, 176, 143, 51, 109, 34, 5, 104, 1, 176, 116, 11, 32, 243, 62, 49, 0, 176, 143, 51, 96, 244, 62, 49, 0, 161, 21, 29, 77, 5, 98, 170, 0, 162, 18, 2, 77, 9, 98, 170, 1, 47, 7, 104, 109, 36, 3, 104, 1, 176, 149, 11, 0, 176, 208, 51, 133, 41, 5, 104, 0, 176, 1, 52, 32, 243, 50, 52, 109, 36, 5, 104, 0, 176, 100, 47, 32, 243, 50, 52, 0, 176, 60, 53, 128, 242, 109, 53, 0, 162, 18, 2, 171, 1, 84, 65, 0, 41, 0, 192, 6, 126, 0, 197, 186, 128, 0, 161, 213, 3, 73, 9, 238, 172, 0, 162, 18, 34, 73, 5, 46, 173, 1, 47, 7, 104, 109, 36, 3, 104, 1, 176, 198, 11, 0, 176, 222, 60, 133, 41, 5, 104, 0, 176, 15, 61, 0, 240, 64, 61, 109, 36, 5, 104, 1, 176, 247, 11, 65, 241, 40, 12, 0, 176, 48, 62, 65, 241, 40, 12, 0, 161, 213, 3, 77, 1, 238, 188, 0, 162, 146, 18, 77, 1, 110, 189, 133, 41, 0, 192, 60, 117, 31, 50, 38, 34, 208, 194, 251, 119, 108, 34, 128, 194, 109, 121, 109, 34, 4, 104, 22, 10, 32, 195, 46, 124, 128, 194, 46, 124, 0, 162, 146, 50, 77, 9, 98, 162, 2, 47, 7, 104, 0, 161, 25, 3, 79, 1, 222, 154, 0, 176, 78, 38, 6, 106, 0, 208, 143, 38, 0, 208, 208, 38, 0, 208, 17, 39, 0, 208, 82, 39, 0, 208, 147, 39, 0, 208, 212, 39, 138, 39, 3, 43, 0, 176, 21, 40, 0, 55, 50, 32, 0, 176, 70, 40, 138, 41, 4, 104, 60, 10, 1, 176, 216, 12, 1, 0, 58, 50, 2, 41, 50, 1, 2, 96, 1, 1, 1, 0, 0, 161, 213, 26, 75, 1, 84, 115, 0, 162, 210, 18, 73, 1, 84, 65, 133, 41, 0, 197, 33, 98, 14, 34, 96, 196, 55, 101, 108, 34, 32, 195, 2, 102, 109, 34, 4, 104, 20, 10, 0, 197, 33, 98, 160, 197, 74, 172, 0, 161, 213, 26, 75, 1, 84, 115, 0, 162, 210, 18, 73, 1, 84, 65, 138, 41, 1, 1, 208, 194, 0, 103, 0, 161, 25, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 0, 41, 208, 194, 192, 69, 48, 50, 47, 50, 49, 34, 208, 194, 252, 134, 208, 194, 40, 137, 0, 161, 25, 3, 77, 1, 102, 172, 0, 162, 18, 2, 77, 1, 102, 172, 47, 37, 30, 10, 0, 41, 208, 194, 16, 139, 208, 194, 188, 141, 0, 161, 213, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 133, 41, 128, 194, 220, 103, 109, 34, 4, 104, 20, 10, 33, 195, 9, 13, 128, 194, 218, 173, 0, 161, 213, 3, 77, 1, 96, 170, 0, 162, 146, 18, 77, 1, 96, 162, 2, 57, 58, 50, 57, 34, 224, 193, 218, 173, 1, 1, 1, 0, 0, 41, 47, 1, 5, 96, 138, 41, 1, 1, 2, 96, 140, 1, 1, 0, 0, 161, 25, 3, 169, 1, 84, 90, 0, 162, 18, 2, 169, 1, 84, 73, 2, 47, 4, 104, 0, 145, 201, 3, 1, 0, 133, 41, 5, 104, 0, 176, 165, 65, 0, 240, 52, 63, 134, 40, 3, 43, 35, 10, 4, 96, 133, 52, 109, 36, 30, 10, 0, 176, 56, 66, 192, 243, 52, 63, 13, 16, 0, 176, 81, 191, 0, 162, 25, 18, 13, 1, 98, 170, 88, 36, 0, 176, 208, 51, 133, 57, 0, 41, 5, 104, 0, 176, 143, 69, 208, 242, 192, 69, 47, 37, 30, 10, 0, 176, 109, 72, 208, 242, 192, 69, 2, 57, 133, 50, 57, 34, 6, 104, 35, 10, 0, 176, 109, 72, 128, 242, 40, 137, 1, 1, 1, 0, 0, 41, 89, 1, 6, 96, 2, 57, 133, 34, 88, 1, 2, 96, 1, 1, 1, 0, 0, 176, 206, 219, 0, 176, 123, 181, 1, 176, 217, 13, 38, 5, 0, 176, 122, 199, 0, 176, 53, 227, 1, 176, 42, 14, 1, 176, 107, 14, 0, 176, 227, 252, 0, 161, 25, 3, 71, 1, 222, 185, 138, 41, 46, 1, 1, 176, 188, 14, 128, 247, 177, 6, 14, 16, 108, 34, 0, 176, 92, 219, 1, 176, 253, 14, 130, 40, 19, 104, 108, 32, 2, 104, 13, 1, 136, 40, 2, 104, 1, 1, 92, 45, 7, 0, 2, 104, 9, 96, 143, 40, 3, 104, 1, 1, 5, 96, 141, 40, 2, 104, 2, 96, 1, 1, 73, 39, 110, 1, 11, 96, 34, 32, 111, 1, 8, 96, 130, 40, 2, 104, 13, 1, 108, 34, 3, 104, 0, 176, 92, 219, 0, 176, 15, 220, 0, 176, 92, 219, 14, 16, 0, 176, 215, 198, 38, 5, 0, 176, 118, 227, 38, 5, 1, 176, 62, 15, 38, 5, 0, 176, 92, 239, 0, 176, 215, 217, 0, 176, 215, 217, 1, 176, 127, 15, 0, 176, 206, 219, 0, 176, 141, 219, 0, 176, 180, 244, 0, 176, 203, 189, 0, 176, 222, 239, 0, 176, 233, 180, 0, 176, 58, 181, 0, 176, 16, 191, 0, 176, 53, 227, 0, 176, 123, 181, 1, 176, 208, 15, 1, 176, 17, 16, 0, 176, 51, 236, 0, 176, 26, 204, 1, 176, 82, 16, 1, 176, 163, 16, 0, 176, 134, 198, 1, 176, 228, 16, 1, 176, 53, 17, 1, 176, 53, 17, 0, 176, 216, 245, 1, 176, 118, 17, 0, 161, 213, 3, 75, 1, 84, 115, 0, 162, 210, 19, 73, 1, 84, 65, 1, 47, 0, 176, 214, 47, 0, 176, 200, 49, 96, 244, 153, 172, 0, 161, 21, 28, 77, 1, 94, 170, 0, 162, 146, 18, 77, 1, 94, 162, 133, 41, 48, 194, 228, 106, 32, 195, 228, 106, 0, 161, 213, 3, 77, 1, 94, 170, 0, 162, 146, 18, 77, 1, 94, 162, 1, 47, 0, 176, 208, 51, 1, 176, 215, 17, 128, 242, 228, 106, 2, 13, 136, 202, 0, 161, 213, 3, 71, 1, 100, 170, 0, 162, 146, 18, 71, 65, 100, 162, 0, 192, 218, 173, 3, 13, 136, 202, 0, 104, 0, 161, 213, 3, 71, 1, 100, 170, 0, 162, 146, 18, 71, 65, 100, 162, 0, 192, 232, 107, 2, 13, 150, 201, 0, 161, 213, 3, 71, 5, 100, 170, 0, 162, 18, 2, 71, 69, 100, 170, 1, 47, 1, 176, 149, 11, 133, 41, 5, 104, 0, 176, 1, 52, 0, 240, 50, 52, 0, 176, 100, 47, 0, 240, 109, 53, 3, 13, 150, 201, 0, 104, 0, 161, 213, 3, 71, 5, 100, 170, 0, 162, 18, 2, 71, 69, 100, 170, 1, 47, 1, 176, 149, 11, 0, 176, 100, 47, 0, 240, 232, 107, 0, 145, 29, 5, 2, 13, 104, 99, 1, 0, 0, 161, 227, 83, 85, 1, 246, 221, 0, 162, 18, 2, 85, 33, 246, 221, 1, 47, 0, 176, 233, 59, 0, 176, 233, 59, 0, 240, 188, 113, 0, 161, 149, 18, 76, 5, 238, 172, 0, 162, 146, 18, 76, 1, 110, 189, 1, 47, 1, 176, 8, 18, 133, 41, 5, 104, 1, 176, 8, 18, 48, 242, 105, 176, 1, 176, 8, 18, 32, 243, 105, 176, 193, 195, 57, 18, 0, 176, 81, 191, 109, 18, 0, 176, 183, 0, 2, 13, 140, 202, 136, 41, 65, 34, 13, 1, 0, 176, 15, 220, 2, 59, 150, 36, 1, 1, 109, 1, 1, 0, 1, 176, 5, 19, 0, 176, 248, 0, 0, 176, 248, 0, 136, 40, 130, 40, 1, 176, 70, 19, 1, 176, 62, 15, 0, 176, 57, 1, 0, 176, 233, 180, 0, 176, 233, 180, 122, 18, 1, 176, 135, 19, 1, 176, 135, 19, 2, 13, 137, 202, 1, 176, 200, 19, 40, 44, 2, 104, 2, 96, 152, 18, 1, 176, 135, 19, 2, 13, 137, 202, 1, 176, 200, 19, 1, 176, 9, 20, 0, 176, 10, 194, 1, 1, 1, 0, 0, 176, 85, 0, 2, 13, 144, 201, 1, 176, 106, 20, 0, 176, 198, 212, 0, 176, 248, 0, 0, 176, 248, 0, 1, 176, 62, 15, 0, 176, 57, 1, 0, 176, 233, 180, 0, 176, 233, 180, 0, 176, 53, 227, 0, 176, 53, 227, 0, 176, 162, 183, 1, 176, 118, 17, 0, 161, 213, 3, 76, 9, 94, 170, 0, 162, 18, 2, 76, 9, 94, 170, 1, 47, 0, 176, 208, 51, 133, 41, 5, 104, 0, 176, 1, 52, 0, 240, 50, 52, 34, 34, 5, 104, 0, 176, 100, 47, 64, 246, 244, 53, 32, 179, 60, 53, 192, 243, 152, 185, 0, 176, 92, 219, 2, 13, 168, 201, 0, 181, 76, 214, 2, 13, 144, 201, 131, 56, 141, 56, 136, 40, 1, 176, 106, 20, 13, 17, 65, 34, 136, 41, 2, 104, 13, 1, 0, 176, 203, 189, 1, 0, 35, 1, 1, 0, 1, 176, 5, 19, 0, 176, 248, 0, 0, 176, 248, 0, 1, 176, 62, 15, 0, 176, 122, 199, 0, 176, 57, 1, 0, 176, 233, 180, 0, 176, 233, 180, 0, 176, 187, 1, 0, 176, 187, 1, 0, 176, 162, 183, 1, 176, 118, 17, 0, 176, 118, 207, 0, 176, 206, 219, 38, 5, 0, 176, 115, 244, 0, 176, 251, 223, 0, 176, 53, 227, 1, 176, 171, 20, 0, 176, 102, 242, 0, 176, 57, 1, 0, 176, 187, 199, 0, 176, 183, 0, 0, 176, 222, 239, 0, 176, 123, 181, 0, 176, 253, 181, 0, 176, 78, 182, 0, 161, 213, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 0, 192, 130, 169, 0, 161, 213, 3, 77, 1, 96, 170, 0, 162, 146, 18, 77, 1, 96, 162, 133, 41, 208, 194, 228, 106, 32, 195, 228, 106, 47, 34, 0, 192, 1, 0, 47, 1, 1, 0, 0, 161, 213, 3, 76, 9, 94, 170, 0, 162, 18, 2, 76, 9, 94, 170, 1, 47, 0, 176, 208, 51, 133, 41, 5, 104, 0, 176, 1, 52, 0, 240, 244, 53, 34, 34, 5, 104, 0, 176, 100, 47, 224, 246, 244, 53, 0, 176, 60, 53, 224, 246, 244, 53, 138, 41, 56, 1, 0, 145, 194, 0, 28, 32, 224, 236, 171, 24, 4, 96, 2, 39, 128, 237, 171, 24, 0, 39, 0, 176, 204, 24, 47, 32, 0, 176, 253, 24, 0, 176, 63, 25, 0, 176, 44, 255, 0, 176, 198, 212, 0, 176, 198, 212, 0, 176, 198, 212, 0, 41, 0, 176, 152, 180, 0, 176, 206, 219, 0, 41, 0, 176, 152, 180, 0, 176, 206, 219, 0, 176, 206, 219, 1, 176, 236, 20, 1, 176, 61, 21, 114, 19, 0, 176, 21, 231, 0, 176, 21, 231, 1, 176, 62, 15, 0, 176, 32, 201, 0, 176, 32, 201, 0, 176, 32, 201, 0, 176, 187, 1, 0, 176, 187, 1, 0, 176, 123, 181, 0, 176, 187, 1, 0, 176, 187, 1, 1, 176, 142, 21, 0, 176, 34, 244, 0, 176, 28, 247, 1, 176, 239, 21, 0, 176, 61, 195, 0, 176, 22, 185, 1, 176, 80, 22, 0, 176, 143, 182, 0, 176, 240, 182, 1, 176, 161, 22, 0, 176, 162, 183, 1, 176, 242, 22, 2, 44, 2, 104, 2, 96, 14, 3, 0, 181, 254, 13, 32, 243, 63, 14, 0, 161, 227, 83, 85, 9, 246, 221, 1, 47, 0, 176, 173, 54, 133, 41, 5, 104, 0, 176, 222, 54, 0, 240, 15, 55, 1, 0, 0, 161, 227, 83, 85, 1, 246, 221, 0, 192, 188, 113, 0, 161, 213, 3, 77, 1, 96, 170, 0, 162, 146, 18, 77, 1, 96, 162, 133, 41, 48, 194, 228, 106, 192, 195, 228, 106, 0, 161, 227, 83, 85, 1, 246, 221, 0, 162, 25, 18, 51, 37, 246, 221, 133, 41, 224, 193, 125, 115, 192, 195, 125, 115, 0, 161, 213, 3, 76, 9, 94, 170, 0, 162, 18, 2, 76, 9, 94, 170, 1, 47, 0, 176, 208, 51, 133, 41, 5, 104, 0, 176, 1, 52, 0, 240, 50, 52, 87, 41, 5, 104, 0, 176, 100, 47, 224, 246, 244, 53, 0, 176, 60, 53, 224, 246, 244, 53, 0, 161, 232, 83, 83, 9, 246, 221, 0, 162, 50, 82, 83, 41, 246, 221, 1, 47, 1, 176, 44, 2, 133, 41, 5, 104, 0, 176, 1, 52, 129, 242, 93, 2, 87, 41, 5, 104, 0, 176, 100, 47, 1, 245, 93, 2, 0, 176, 60, 53, 1, 245, 93, 2, 6, 106, 0, 208, 141, 41, 0, 208, 238, 41, 0, 208, 63, 42, 0, 208, 160, 42, 0, 208, 1, 43, 0, 208, 114, 43, 0, 39, 0, 176, 211, 43, 138, 41, 10, 104, 67, 36, 3, 104, 37, 10, 4, 96, 67, 37, 2, 104, 50, 10, 0, 176, 244, 43, 1, 0, 2, 13, 173, 201, 0, 176, 148, 29, 3, 13, 204, 108, 0, 169, 0, 176, 133, 4, 0, 176, 44, 255, 38, 5, 1, 176, 62, 15, 38, 5, 1, 176, 62, 15, 0, 176, 206, 219, 0, 176, 206, 219, 0, 176, 141, 219, 0, 176, 141, 219, 112, 16, 0, 176, 198, 212, 0, 176, 198, 212, 2, 13, 144, 201, 0, 176, 241, 205, 0, 176, 32, 201, 0, 176, 32, 201, 0, 176, 187, 1, 0, 176, 187, 1, 1, 176, 142, 21, 0, 176, 34, 244, 0, 176, 28, 247, 1, 176, 239, 21, 0, 176, 61, 195, 0, 176, 22, 185, 1, 176, 80, 22, 0, 176, 31, 248, 0, 161, 25, 3, 73, 1, 98, 170, 0, 162, 18, 34, 73, 9, 98, 170, 0, 176, 254, 13, 32, 243, 63, 14, 0, 161, 213, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 133, 41, 0, 192, 42, 167, 161, 197, 67, 23, 0, 161, 213, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 133, 41, 0, 192, 220, 103, 48, 199, 218, 173, 0, 161, 213, 3, 75, 1, 84, 115, 0, 162, 210, 19, 73, 1, 84, 65, 133, 41, 0, 197, 74, 172, 55, 34, 0, 192, 2, 102, 128, 199, 55, 101, 0, 161, 213, 3, 77, 1, 238, 188, 0, 162, 146, 18, 77, 1, 110, 189, 133, 41, 0, 192, 60, 117, 31, 50, 61, 34, 0, 192, 251, 119, 55, 34, 0, 192, 109, 121, 192, 195, 249, 122, 0, 161, 25, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 0, 192, 42, 178, 0, 176, 184, 203, 0, 176, 50, 241, 0, 176, 122, 199, 0, 176, 253, 181, 0, 176, 78, 182, 0, 176, 123, 181, 0, 176, 12, 229, 13, 16, 0, 176, 27, 239, 1, 176, 119, 24, 1, 176, 119, 24, 129, 40, 7, 104, 136, 40, 3, 104, 1, 176, 106, 20, 1, 176, 184, 24, 0, 176, 183, 0, 0, 176, 87, 180, 129, 40, 1, 176, 106, 20, 0, 176, 176, 205, 0, 176, 134, 198, 0, 176, 243, 183, 13, 17, 119, 1, 1, 0, 1, 176, 249, 24, 1, 176, 58, 25, 0, 176, 68, 184, 0, 176, 128, 248, 0, 176, 8, 228, 0, 176, 240, 182, 1, 176, 139, 25, 0, 161, 25, 3, 73, 9, 238, 172, 0, 162, 18, 34, 73, 9, 46, 173, 101, 37, 1, 1, 140, 43, 2, 104, 2, 96, 101, 1, 133, 41, 5, 104, 0, 176, 191, 94, 0, 240, 136, 90, 1, 176, 236, 25, 193, 248, 29, 26, 1, 13, 0, 32, 1, 0, 136, 40, 5, 104, 47, 50, 72, 34, 2, 104, 128, 1, 0, 145, 87, 6, 1, 0, 136, 40, 5, 104, 47, 50, 72, 34, 2, 104, 128, 1, 128, 32, 47, 1, 0, 145, 12, 3, 1, 0, 136, 40, 5, 104, 48, 50, 71, 34, 2, 104, 128, 1, 0, 145, 52, 6, 1, 0, 136, 40, 5, 104, 48, 50, 71, 34, 2, 104, 128, 1, 128, 32, 48, 1, 0, 145, 193, 2, 1, 0, 136, 40, 5, 104, 89, 50, 88, 34, 2, 104, 128, 1, 0, 145, 125, 5, 1, 0, 136, 40, 5, 104, 89, 50, 88, 34, 2, 104, 128, 1, 128, 32, 89, 1, 0, 145, 16, 4, 1, 0, 108, 16, 0, 176, 183, 0, 2, 13, 144, 201, 1, 176, 106, 20, 0, 41, 0, 176, 152, 180, 0, 176, 206, 219, 1, 176, 80, 28, 38, 5, 0, 176, 231, 253, 1, 176, 145, 28, 0, 176, 123, 181, 2, 13, 168, 201, 1, 176, 210, 28, 1, 176, 19, 29, 1, 176, 116, 29, 1, 13, 0, 114, 0, 161, 25, 3, 73, 1, 98, 170, 0, 162, 18, 34, 73, 9, 98, 170, 0, 176, 254, 13, 32, 243, 63, 14, 0, 161, 213, 3, 77, 1, 96, 170, 0, 162, 146, 18, 77, 1, 96, 162, 133, 41, 48, 194, 228, 106, 192, 195, 228, 106, 0, 161, 227, 83, 85, 1, 246, 221, 0, 162, 25, 18, 51, 37, 246, 221, 133, 41, 224, 193, 125, 115, 192, 195, 125, 115, 0, 161, 213, 3, 76, 9, 94, 170, 0, 162, 18, 2, 76, 9, 94, 170, 1, 47, 0, 176, 208, 51, 133, 41, 5, 104, 0, 176, 1, 52, 0, 240, 50, 52, 87, 41, 5, 104, 0, 176, 100, 47, 224, 246, 244, 53, 0, 176, 60, 53, 224, 246, 244, 53, 0, 161, 232, 83, 83, 9, 246, 221, 0, 162, 50, 82, 83, 41, 246, 221, 1, 47, 1, 176, 44, 2, 133, 41, 5, 104, 0, 176, 1, 52, 129, 242, 93, 2, 87, 41, 5, 104, 0, 176, 100, 47, 1, 245, 93, 2, 0, 176, 60, 53, 1, 245, 93, 2, 0, 145, 31, 6, 3, 13, 202, 100, 0, 145, 1, 0, 0, 145, 29, 5, 3, 13, 201, 116, 0, 149, 1, 0, 0, 145, 93, 1, 2, 41, 0, 176, 103, 185, 1, 0, 0, 162, 18, 2, 75, 1, 84, 65, 133, 41, 0, 192, 6, 126, 89, 34, 0, 202, 186, 128, 192, 200, 186, 128, 38, 5, 0, 176, 92, 239, 38, 5, 0, 176, 21, 231, 1, 176, 213, 29, 0, 176, 12, 229, 0, 176, 206, 219, 136, 40, 129, 40, 0, 176, 138, 189, 0, 176, 183, 0, 0, 176, 183, 0, 0, 176, 32, 201, 0, 176, 32, 201, 0, 176, 245, 244, 0, 176, 123, 181, 0, 176, 143, 182, 0, 176, 240, 182, 1, 176, 161, 22, 0, 176, 162, 183, 1, 176, 242, 22, 3, 13, 204, 114, 0, 169, 0, 176, 52, 4, 5, 13, 204, 114, 203, 169, 0, 144, 0, 176, 52, 4, 3, 13, 204, 114, 0, 157, 0, 161, 25, 3, 73, 1, 98, 170, 0, 162, 18, 34, 73, 9, 98, 170, 0, 176, 139, 75, 33, 243, 6, 30, 5, 13, 204, 114, 204, 157, 0, 138, 0, 161, 25, 3, 73, 1, 98, 170, 0, 162, 18, 34, 73, 9, 98, 170, 1, 176, 177, 32, 145, 241, 6, 30, 3, 13, 204, 108, 0, 169, 0, 176, 133, 4, 5, 13, 204, 108, 203, 169, 0, 144, 0, 176, 133, 4, 0, 161, 213, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 133, 41, 0, 192, 220, 103, 0, 192, 218, 173, 0, 161, 213, 3, 75, 1, 84, 115, 0, 162, 210, 19, 73, 1, 84, 65, 133, 41, 0, 197, 55, 101, 55, 34, 0, 192, 2, 102, 128, 199, 55, 101, 0, 176, 206, 219, 0, 176, 198, 212, 0, 176, 202, 213, 0, 176, 187, 1, 1, 176, 226, 32, 3, 13, 204, 114, 0, 169, 0, 176, 52, 4, 0, 161, 25, 3, 77, 1, 106, 172, 0, 162, 18, 2, 77, 1, 106, 172, 133, 41, 161, 197, 51, 33, 225, 198, 51, 33, 0, 161, 213, 3, 77, 1, 102, 156, 133, 41, 129, 194, 152, 35, 33, 195, 152, 35, 3, 13, 201, 116, 0, 149, 0, 161, 227, 83, 85, 1, 114, 205, 133, 41, 33, 195, 91, 37, 33, 195, 91, 37, 0, 161, 25, 3, 75, 1, 232, 171, 0, 162, 18, 34, 75, 9, 232, 171, 133, 41, 5, 104, 0, 176, 90, 75, 1, 245, 51, 33, 0, 176, 139, 75, 97, 249, 51, 33, 0, 161, 213, 3, 81, 9, 102, 172, 0, 162, 18, 34, 81, 9, 102, 172, 1, 47, 0, 176, 173, 54, 133, 41, 5, 104, 0, 176, 222, 54, 33, 243, 152, 35, 1, 176, 251, 38, 1, 245, 152, 35, 3, 13, 202, 100, 0, 145, 0, 161, 227, 83, 85, 9, 114, 205, 1, 47, 0, 176, 173, 54, 133, 41, 5, 104, 0, 176, 222, 54, 33, 243, 91, 37, 1, 176, 251, 38, 1, 245, 91, 37, 1, 176, 43, 9, 0, 176, 244, 226, 122, 18, 0, 176, 183, 0, 0, 176, 183, 0, 1, 176, 106, 20, 0, 176, 206, 219, 0, 176, 248, 0, 138, 18, 38, 5, 1, 176, 62, 15, 38, 5, 0, 176, 92, 239, 0, 176, 32, 201, 139, 18, 0, 176, 123, 181, 0, 176, 245, 244, 0, 176, 162, 183, 0, 161, 213, 3, 77, 1, 96, 170, 0, 162, 146, 18, 77, 1, 96, 162, 133, 41, 48, 194, 228, 106, 32, 195, 228, 106, 0, 161, 21, 28, 77, 9, 98, 170, 0, 162, 18, 2, 77, 9, 98, 170, 1, 47, 0, 176, 208, 51, 133, 41, 5, 104, 0, 176, 1, 52, 0, 240, 50, 52, 34, 34, 5, 104, 0, 176, 100, 47, 0, 240, 109, 53, 0, 176, 60, 53, 32, 243, 109, 53, 0, 161, 25, 3, 77, 1, 238, 188, 0, 162, 146, 18, 77, 1, 110, 189, 208, 194, 195, 153, 1, 13, 0, 32, 16, 4, 0, 176, 134, 0, 0, 161, 213, 3, 87, 1, 246, 221, 0, 162, 146, 18, 87, 1, 246, 221, 0, 192, 251, 119, 3, 13, 202, 100, 0, 145, 0, 161, 227, 83, 85, 9, 246, 221, 1, 47, 0, 176, 173, 54, 133, 41, 5, 104, 0, 176, 222, 54, 0, 240, 15, 55, 0, 176, 157, 57, 0, 240, 209, 58, 38, 5, 0, 176, 157, 224, 2, 13, 144, 201, 0, 176, 22, 180, 1, 13, 0, 114, 0, 161, 25, 3, 73, 1, 98, 170, 0, 162, 18, 34, 73, 9, 98, 170, 0, 176, 254, 13, 32, 243, 63, 14, 0, 161, 213, 3, 77, 1, 96, 170, 0, 162, 146, 18, 77, 1, 96, 162, 133, 41, 49, 194, 44, 39, 33, 195, 44, 39, 0, 161, 21, 28, 77, 9, 98, 170, 0, 162, 18, 2, 77, 9, 98, 170, 1, 47, 0, 176, 208, 51, 133, 41, 5, 104, 1, 176, 250, 39, 1, 240, 44, 39, 1, 176, 250, 39, 33, 243, 44, 39, 31, 50, 30, 34, 1, 192, 43, 40, 2, 41, 1, 192, 35, 43, 97, 196, 35, 43, 28, 34, 0, 192, 8, 156, 31, 50, 30, 34, 1, 192, 43, 40, 2, 41, 1, 192, 35, 43, 97, 196, 35, 43, 0, 161, 213, 3, 81, 9, 238, 188, 0, 162, 18, 34, 81, 9, 46, 173, 1, 47, 0, 176, 173, 54, 0, 176, 157, 57, 1, 240, 67, 45, 3, 13, 202, 100, 0, 145, 0, 161, 227, 83, 85, 9, 246, 221, 1, 47, 0, 176, 173, 54, 0, 176, 157, 57, 1, 240, 23, 48, 0, 161, 213, 3, 77, 1, 238, 188, 33, 195, 6, 50, 3, 13, 201, 116, 0, 149, 0, 161, 227, 83, 85, 1, 246, 221, 1, 192, 23, 48, 0, 161, 25, 3, 75, 1, 232, 171, 0, 162, 18, 34, 75, 9, 232, 171, 133, 41, 5, 104, 0, 176, 139, 75, 33, 243, 67, 45, 0, 176, 139, 75, 193, 243, 67, 45, 0, 161, 25, 3, 77, 1, 106, 172, 0, 162, 18, 2, 77, 1, 106, 172, 133, 41, 193, 195, 67, 45, 97, 196, 67, 45, 0, 161, 213, 3, 73, 9, 238, 172, 0, 162, 18, 34, 73, 9, 46, 173, 1, 47, 0, 176, 222, 60, 133, 41, 5, 104, 0, 176, 15, 61, 0, 240, 64, 61, 0, 176, 48, 62, 161, 245, 76, 52, 0, 161, 25, 3, 77, 1, 238, 188, 0, 162, 146, 18, 77, 1, 110, 189, 224, 193, 195, 153, 2, 13, 173, 201, 0, 176, 148, 29, 2, 13, 173, 201, 0, 176, 148, 29, 0, 161, 25, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 0, 192, 40, 137, 2, 13, 178, 201, 0, 162, 23, 114, 81, 13, 114, 205, 2, 47, 5, 104, 0, 208, 43, 41, 0, 176, 76, 41, 6, 106, 0, 208, 141, 41, 0, 208, 238, 41, 0, 208, 63, 42, 0, 208, 160, 42, 0, 208, 1, 43, 0, 208, 114, 43, 0, 39, 0, 176, 211, 43, 138, 41, 10, 104, 67, 36, 3, 104, 37, 10, 4, 96, 67, 37, 2, 104, 50, 10, 0, 176, 244, 43, 1, 0, 2, 44, 2, 104, 2, 96, 14, 3, 0, 181, 254, 13, 32, 243, 63, 14, 0, 161, 227, 83, 85, 9, 246, 221, 1, 47, 0, 176, 173, 54, 133, 41, 5, 104, 0, 176, 222, 54, 0, 240, 15, 55, 1, 0, 0, 161, 227, 83, 85, 1, 246, 221, 0, 192, 188, 113, 0, 162, 18, 34, 75, 9, 84, 65, 2, 47, 11, 104, 0, 161, 25, 3, 75, 1, 212, 114, 133, 41, 3, 104, 0, 176, 179, 35, 0, 176, 244, 35, 0, 208, 248, 36, 0, 176, 203, 37, 2, 41, 38, 1, 113, 32, 1, 176, 198, 52, 1, 176, 23, 53, 90, 32, 115, 1, 25, 10, 1, 176, 72, 53, 132, 45, 7, 0, 117, 1, 132, 40, 37, 1, 1, 176, 137, 53, 1, 176, 186, 53, 132, 40, 6, 104, 57, 37, 3, 104, 35, 1, 2, 96, 37, 1, 1, 176, 72, 53, 132, 40, 36, 1, 73, 44, 117, 1, 1, 176, 72, 53, 132, 40, 6, 104, 57, 37, 3, 104, 36, 1, 2, 96, 120, 1, 73, 44, 117, 1, 1, 176, 72, 53, 1, 176, 251, 53, 132, 40, 6, 104, 57, 37, 3, 104, 36, 1, 2, 96, 121, 1, 1, 176, 60, 54, 132, 45, 7, 0, 6, 104, 57, 32, 3, 104, 119, 1, 2, 96, 122, 1, 132, 40, 6, 104, 57, 37, 3, 104, 36, 1, 2, 96, 121, 1, 1, 176, 125, 54, 132, 45, 7, 0, 117, 1, 132, 40, 36, 1, 73, 44, 123, 1, 1, 176, 125, 54, 122, 1, 1, 0, 126, 18, 1, 176, 190, 54, 73, 44, 128, 1, 132, 40, 39, 1, 1, 176, 255, 54, 1, 176, 48, 55, 1, 176, 113, 55, 1, 176, 194, 55, 126, 18, 1, 176, 19, 56, 90, 32, 3, 104, 115, 18, 121, 1, 91, 32, 3, 104, 115, 18, 121, 1, 110, 32, 3, 104, 115, 18, 121, 1, 37, 18, 1, 176, 236, 20, 1, 176, 68, 56, 132, 40, 4, 104, 100, 10, 1, 176, 133, 56, 0, 176, 174, 195, 1, 0, 132, 40, 0, 176, 141, 219, 73, 44, 2, 104, 117, 1, 1, 0, 132, 40, 6, 104, 57, 37, 3, 104, 134, 1, 2, 96, 120, 1, 73, 44, 126, 1, 0, 176, 81, 191, 0, 176, 46, 205, 1, 176, 230, 56, 57, 37, 2, 104, 12, 96, 132, 40, 7, 104, 73, 44, 3, 104, 120, 1, 2, 96, 134, 1, 4, 96, 73, 44, 2, 104, 117, 1, 136, 40, 0, 176, 203, 189, 1, 176, 39, 57, 132, 45, 7, 0, 35, 1, 132, 40, 6, 104, 57, 37, 3, 104, 35, 1, 2, 96, 134, 1, 0, 176, 81, 191, 0, 176, 203, 189, 0, 161, 153, 55, 75, 1, 94, 170, 0, 162, 18, 2, 75, 9, 94, 170, 1, 176, 104, 57, 33, 243, 169, 57, 38, 5, 130, 40, 1, 176, 70, 19, 1, 176, 62, 15, 130, 40, 0, 176, 12, 229, 0, 176, 206, 219, 130, 40, 0, 176, 133, 212, 1, 176, 253, 14, 130, 40, 10, 104, 131, 45, 7, 0, 3, 104, 1, 176, 184, 24, 2, 13, 144, 201, 0, 176, 15, 220, 0, 176, 183, 0, 130, 40, 0, 176, 251, 223, 0, 176, 122, 1, 130, 40, 0, 176, 245, 244, 0, 176, 123, 181, 0, 161, 213, 3, 85, 5, 110, 173, 0, 162, 18, 34, 85, 37, 110, 173, 1, 47, 0, 176, 222, 60, 133, 41, 5, 104, 0, 176, 15, 61, 0, 240, 64, 61, 0, 176, 48, 62, 96, 249, 97, 62, 108, 18, 0, 176, 183, 0, 136, 40, 1, 176, 184, 24, 1, 176, 5, 19, 124, 18, 0, 176, 215, 217, 8, 59, 3, 43, 0, 176, 12, 229, 0, 176, 248, 0, 1, 0, 124, 17, 0, 176, 206, 219, 38, 5, 0, 176, 57, 1, 1, 18, 37, 1, 1, 0, 38, 5, 0, 176, 115, 244, 127, 18, 0, 176, 233, 180, 8, 59, 3, 43, 0, 176, 32, 201, 0, 176, 233, 180, 1, 0, 127, 17, 0, 176, 58, 181, 111, 18, 0, 176, 123, 181, 0, 176, 123, 181, 0, 176, 154, 208, 0, 176, 162, 183, 0, 176, 165, 184, 1, 176, 5, 19, 0, 176, 152, 180, 38, 5, 1, 176, 70, 19, 0, 176, 233, 180, 0, 176, 187, 1, 0, 176, 198, 212, 0, 176, 248, 0, 0, 176, 50, 241, 0, 176, 222, 239, 0, 176, 105, 254, 0, 176, 253, 181, 1, 176, 106, 58, 0, 176, 8, 228, 1, 176, 107, 14, 0, 176, 243, 183, 1, 176, 187, 58, 0, 176, 165, 184, 2, 13, 176, 202, 28, 34, 0, 192, 8, 156, 29, 34, 0, 192, 93, 157, 30, 34, 0, 192, 252, 158, 31, 34, 0, 192, 161, 160, 32, 34, 0, 192, 7, 162, 33, 34, 0, 192, 182, 163, 96, 196, 127, 165, 1, 176, 12, 59, 0, 176, 12, 229, 0, 176, 12, 229, 38, 5, 0, 176, 57, 1, 0, 176, 122, 1, 0, 176, 122, 1, 0, 176, 105, 254, 0, 161, 213, 3, 73, 9, 238, 172, 0, 162, 18, 34, 73, 9, 46, 173, 2, 57, 87, 57, 3, 41, 6, 104, 0, 55, 8, 39, 2, 104, 2, 96, 100, 1, 1, 47, 0, 176, 222, 60, 133, 41, 5, 104, 0, 176, 15, 61, 0, 240, 64, 61, 0, 176, 48, 62, 0, 240, 97, 62, 2, 57, 87, 57, 57, 34, 7, 104, 0, 55, 8, 55, 55, 32, 2, 104, 2, 96, 86, 1, 0, 145, 233, 6, 1, 0, 2, 57, 87, 57, 3, 41, 6, 104, 0, 55, 8, 39, 2, 104, 2, 96, 82, 1, 0, 145, 193, 2, 1, 0, 0, 145, 253, 3, 133, 41, 5, 104, 0, 176, 235, 66, 128, 242, 28, 67, 1, 0, 0, 161, 25, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 0, 41, 192, 195, 192, 69, 48, 50, 47, 50, 49, 34, 0, 192, 252, 134, 0, 197, 40, 137, 2, 13, 139, 202, 0, 161, 25, 3, 169, 5, 84, 90, 0, 162, 5, 18, 9, 1, 84, 73, 133, 41, 5, 104, 0, 176, 165, 65, 0, 245, 52, 63, 1, 176, 77, 59, 0, 245, 52, 63, 2, 13, 190, 201, 2, 43, 69, 1, 0, 145, 137, 2, 1, 0, 124, 17, 1, 176, 126, 59, 2, 13, 144, 201, 0, 176, 203, 189, 13, 17, 0, 176, 248, 0, 13, 17, 0, 176, 206, 219, 0, 176, 206, 219, 111, 17, 0, 176, 122, 1, 111, 17, 0, 176, 233, 180, 0, 176, 188, 181, 111, 17, 0, 176, 123, 181, 0, 176, 157, 224, 0, 176, 51, 236, 38, 5, 1, 176, 191, 59, 1, 176, 228, 16, 1, 176, 53, 17, 4, 13, 144, 201, 131, 204, 1, 176, 0, 60, 8, 13, 144, 201, 131, 204, 138, 202, 131, 204, 1, 176, 65, 60, 7, 13, 204, 111, 201, 131, 204, 170, 0, 131, 1, 176, 146, 60, 0, 176, 203, 189, 2, 41, 1, 1, 0, 176, 203, 189, 0, 176, 87, 180, 0, 176, 66, 230, 0, 176, 248, 0, 38, 5, 0, 176, 157, 224, 2, 41, 57, 1, 38, 5, 0, 176, 157, 224, 0, 176, 16, 191, 0, 176, 123, 181, 136, 40, 2, 41, 58, 1, 0, 176, 53, 227, 38, 5, 0, 176, 162, 183, 38, 5, 0, 176, 243, 183, 38, 5, 1, 176, 3, 61, 0, 176, 240, 182, 1, 176, 116, 61, 2, 13, 129, 202, 134, 40, 107, 1, 0, 161, 25, 3, 73, 1, 98, 170, 0, 162, 18, 34, 73, 9, 98, 170, 0, 176, 254, 13, 32, 243, 63, 14, 0, 145, 125, 5, 1, 13, 0, 115, 1, 0, 2, 13, 190, 201, 0, 161, 213, 3, 79, 5, 98, 170, 0, 162, 18, 2, 79, 9, 98, 170, 1, 47, 0, 176, 144, 186, 0, 176, 193, 186, 128, 242, 109, 53, 2, 13, 144, 201, 0, 176, 203, 189, 2, 13, 144, 201, 2, 41, 1, 1, 0, 176, 203, 189, 132, 18, 0, 176, 87, 180, 4, 13, 144, 201, 131, 204, 0, 176, 26, 204, 8, 13, 144, 201, 131, 204, 138, 202, 131, 204, 1, 176, 65, 60, 112, 17, 0, 176, 206, 219, 112, 17, 0, 176, 248, 0, 2, 13, 168, 201, 1, 176, 197, 61, 38, 5, 0, 176, 57, 1, 2, 13, 168, 201, 2, 41, 1, 1, 38, 5, 1, 176, 197, 61, 0, 176, 252, 199, 40, 18, 0, 176, 233, 180, 1, 176, 135, 19, 2, 41, 58, 1, 1, 176, 135, 19, 1, 176, 187, 58, 2, 13, 129, 202, 0, 161, 25, 3, 71, 1, 222, 185, 138, 41, 46, 1, 1, 176, 6, 62, 128, 247, 177, 6, 0, 145, 143, 5, 2, 13, 131, 202, 1, 0, 2, 13, 178, 202, 2, 41, 38, 1, 125, 32, 4, 104, 30, 10, 1, 176, 71, 62, 126, 32, 1, 176, 198, 52, 127, 32, 1, 176, 136, 62, 1, 176, 201, 62, 124, 18, 38, 5, 0, 176, 57, 1, 0, 176, 12, 229, 2, 13, 168, 201, 1, 176, 197, 61, 0, 176, 87, 180, 0, 176, 92, 219, 1, 176, 250, 62, 0, 176, 245, 244, 0, 176, 78, 182, 0, 176, 209, 225, 1, 176, 59, 63, 1, 176, 161, 22, 1, 176, 156, 63, 1, 176, 13, 64, 1, 176, 94, 64, 1, 176, 61, 21, 1, 176, 175, 64, 1, 176, 16, 65, 1, 176, 97, 65, 138, 41, 46, 1, 6, 106, 16, 223, 198, 4, 16, 223, 247, 4, 16, 223, 40, 5, 16, 223, 89, 5, 16, 223, 138, 5, 16, 223, 187, 5, 2, 39, 224, 236, 236, 5, 47, 48, 48, 48, 49, 32, 0, 176, 135, 11, 0, 176, 184, 11, 0, 145, 208, 0, 0, 162, 18, 2, 0, 32, 0, 0, 1, 0, 0, 145, 183, 1, 0, 162, 18, 34, 83, 41, 84, 65, 1, 0, 0, 145, 223, 1, 0, 162, 146, 50, 83, 41, 98, 162, 1, 0, 0, 145, 201, 6, 0, 162, 210, 19, 73, 33, 84, 65, 1, 0, 0, 145, 220, 6, 0, 162, 146, 18, 79, 33, 98, 164, 1, 0, 0, 145, 18, 6, 0, 162, 146, 18, 77, 33, 98, 162, 1, 0, 0, 145, 103, 5, 0, 162, 18, 2, 75, 33, 84, 65, 1, 0, 0, 161, 25, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 33, 98, 162, 32, 195, 3, 81, 0, 161, 25, 3, 77, 1, 106, 172, 0, 162, 18, 2, 77, 33, 106, 172, 0, 192, 3, 86, 0, 162, 18, 34, 73, 41, 84, 73, 31, 34, 5, 104, 0, 176, 204, 50, 0, 240, 62, 49, 0, 176, 143, 51, 0, 240, 62, 49, 0, 145, 233, 6, 0, 161, 213, 3, 79, 9, 98, 172, 0, 162, 18, 2, 79, 41, 98, 172, 1, 0, 0, 162, 136, 20, 73, 45, 98, 170, 31, 34, 9, 104, 0, 161, 25, 3, 71, 1, 98, 170, 1, 176, 178, 65, 0, 240, 177, 6, 1, 176, 227, 65, 0, 240, 177, 6, 0, 161, 25, 3, 169, 1, 84, 90, 0, 162, 25, 18, 9, 33, 84, 73, 133, 41, 5, 104, 0, 176, 165, 65, 0, 240, 52, 63, 0, 176, 56, 66, 0, 240, 52, 63, 0, 162, 25, 18, 13, 33, 98, 170, 133, 41, 5, 104, 0, 176, 143, 69, 0, 240, 192, 69, 0, 176, 109, 72, 0, 240, 192, 69, 0, 161, 25, 3, 75, 33, 232, 171, 0, 162, 18, 34, 75, 9, 232, 171, 133, 41, 5, 104, 0, 176, 90, 75, 0, 240, 207, 72, 0, 176, 139, 75, 0, 240, 207, 72, 136, 40, 130, 40, 35, 34, 1, 1, 128, 40, 1, 176, 12, 59, 0, 176, 87, 180, 0, 176, 12, 229, 38, 5, 0, 176, 57, 1, 0, 176, 122, 1, 0, 176, 123, 181, 0, 161, 213, 26, 77, 5, 96, 170, 0, 162, 146, 18, 77, 1, 96, 162, 133, 41, 1, 192, 20, 66, 1, 192, 20, 66, 0, 161, 213, 3, 77, 1, 238, 188, 0, 162, 146, 18, 77, 1, 110, 189, 133, 41, 0, 192, 60, 117, 87, 41, 0, 192, 107, 118, 55, 34, 0, 192, 109, 121, 96, 196, 249, 122, 0, 176, 102, 242, 0, 176, 248, 0, 0, 176, 152, 180, 0, 176, 233, 180, 0, 176, 16, 191, 1, 176, 116, 61, 1, 176, 3, 61, 1, 176, 226, 32, 0, 176, 203, 246, 0, 162, 18, 2, 75, 1, 84, 65, 0, 192, 186, 128, 38, 5, 58, 32, 0, 208, 133, 192, 0, 176, 50, 241, 38, 5, 0, 176, 92, 239, 0, 176, 215, 217, 112, 17, 0, 176, 57, 199, 0, 176, 152, 180, 13, 16, 1, 176, 213, 29, 2, 13, 153, 201, 0, 176, 101, 253, 1, 176, 87, 66, 1, 176, 168, 66, 2, 13, 137, 202, 1, 176, 233, 66, 1, 176, 171, 20, 1, 176, 42, 67, 0, 176, 50, 206, 130, 40, 136, 40, 1, 176, 106, 20, 1, 176, 5, 19, 0, 176, 141, 219, 1, 176, 91, 67, 0, 176, 122, 1, 0, 176, 233, 180, 0, 176, 54, 245, 0, 176, 123, 181, 0, 161, 25, 3, 179, 1, 110, 189, 0, 162, 146, 18, 179, 1, 110, 189, 193, 195, 156, 67, 0, 176, 184, 203, 0, 176, 92, 219, 38, 5, 0, 176, 92, 239, 38, 5, 58, 32, 0, 208, 133, 192, 0, 176, 57, 1, 1, 176, 42, 14, 1, 176, 174, 69, 1, 176, 239, 69, 1, 176, 48, 70, 13, 16, 0, 176, 206, 219, 0, 176, 152, 180, 0, 176, 215, 217, 1, 176, 113, 70, 1, 176, 113, 70, 0, 176, 227, 252, 0, 176, 227, 252, 0, 176, 122, 1, 0, 176, 222, 239, 0, 176, 53, 227, 0, 176, 123, 181, 2, 13, 137, 202, 1, 176, 178, 70, 4, 13, 137, 202, 144, 203, 1, 176, 243, 70, 38, 5, 0, 176, 24, 218, 38, 5, 1, 176, 68, 71, 38, 5, 0, 176, 61, 195, 4, 13, 137, 202, 170, 201, 38, 5, 0, 176, 203, 246, 1, 176, 149, 71, 1, 176, 230, 71, 38, 5, 0, 176, 157, 224, 38, 5, 37, 18, 0, 176, 115, 244, 38, 5, 0, 176, 122, 199, 38, 5, 109, 18, 0, 176, 122, 199, 0, 176, 206, 219, 0, 176, 7, 213, 1, 176, 106, 20, 35, 18, 0, 176, 176, 205, 1, 176, 145, 28, 114, 18, 0, 176, 183, 227, 0, 176, 245, 244, 40, 18, 0, 176, 123, 181, 1, 176, 87, 72, 117, 18, 0, 176, 102, 242, 1, 176, 152, 72, 119, 18, 1, 176, 152, 72, 0, 176, 118, 217, 121, 18, 0, 176, 118, 217, 0, 176, 243, 183, 123, 18, 0, 176, 243, 183, 0, 176, 28, 247, 125, 18, 0, 176, 28, 247, 1, 176, 217, 72, 127, 18, 1, 176, 217, 72, 1, 176, 26, 73, 129, 18, 1, 176, 26, 73, 0, 176, 165, 184, 0, 176, 102, 242, 2, 13, 35, 109, 0, 162, 18, 34, 75, 9, 84, 65, 1, 176, 107, 73, 2, 13, 35, 110, 0, 162, 146, 50, 77, 9, 98, 162, 6, 106, 0, 208, 143, 38, 0, 208, 208, 38, 0, 208, 17, 39, 0, 208, 82, 39, 0, 208, 147, 39, 0, 208, 212, 39, 1, 176, 172, 73, 3, 13, 178, 201, 0, 35, 0, 162, 18, 98, 81, 13, 110, 189, 1, 176, 237, 73, 3, 13, 139, 197, 0, 35, 0, 162, 148, 50, 75, 13, 110, 189, 6, 106, 0, 208, 134, 44, 0, 208, 183, 44, 0, 208, 232, 44, 0, 208, 25, 45, 0, 208, 74, 45, 0, 208, 123, 45, 1, 176, 46, 74, 2, 13, 35, 108, 144, 193, 143, 146, 3, 13, 108, 116, 0, 35, 0, 161, 213, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 33, 195, 111, 74, 2, 13, 35, 114, 1, 176, 201, 76, 0, 240, 177, 6, 0, 161, 213, 26, 75, 5, 84, 90, 0, 162, 18, 34, 73, 9, 84, 74, 0, 192, 62, 49, 0, 161, 213, 3, 77, 9, 98, 170, 0, 162, 18, 2, 77, 9, 98, 170, 133, 41, 0, 192, 50, 52, 0, 197, 109, 53, 0, 161, 213, 3, 73, 9, 238, 172, 0, 162, 18, 34, 73, 9, 46, 173, 133, 41, 0, 192, 64, 61, 96, 201, 97, 62, 5, 146, 168, 51, 1, 0, 5, 146, 40, 52, 1, 0, 5, 146, 168, 52, 1, 0, 5, 146, 40, 53, 1, 0, 5, 146, 168, 53, 5, 147, 40, 54, 1, 0, 5, 146, 168, 54, 5, 147, 40, 55, 1, 0, 5, 146, 40, 52, 1, 0, 1, 176, 12, 59, 1, 176, 126, 59, 0, 176, 66, 230, 0, 176, 248, 0, 38, 5, 58, 37, 0, 208, 251, 30, 0, 176, 115, 244, 1, 176, 91, 67, 0, 176, 222, 239, 1, 176, 234, 77, 1, 176, 43, 78, 1, 176, 108, 78, 1, 176, 108, 78, 1, 176, 173, 78, 0, 176, 162, 183, 0, 176, 174, 255, 0, 176, 174, 255, 0, 176, 243, 183, 0, 176, 68, 184, 1, 176, 3, 61, 0, 176, 165, 184, 0, 176, 22, 185, 1, 176, 14, 79, 1, 176, 95, 79, 0, 176, 10, 194, 0, 176, 240, 182, 1, 176, 116, 61, 0, 176, 65, 183, 0, 176, 31, 225, 0, 176, 31, 225, 1, 176, 192, 79, 0, 176, 21, 250, 0, 176, 96, 196, 0, 161, 25, 3, 83, 1, 238, 188, 0, 162, 146, 18, 83, 1, 110, 189, 32, 195, 106, 151, 138, 41, 59, 1, 0, 145, 194, 0, 1, 176, 33, 80, 5, 146, 168, 51, 1, 0, 5, 146, 168, 52, 1, 0, 5, 146, 168, 51, 1, 0, 5, 146, 40, 52, 1, 0, 5, 146, 168, 52, 1, 0, 5, 146, 168, 51, 1, 0, 5, 146, 40, 52, 1, 0, 0, 161, 213, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 0, 192, 130, 169, 0, 161, 213, 3, 77, 1, 238, 188, 133, 41, 0, 192, 220, 109, 0, 192, 44, 112, 0, 161, 213, 3, 75, 1, 238, 172, 0, 162, 146, 18, 75, 5, 110, 189, 133, 41, 0, 192, 0, 0, 31, 34, 0, 192, 251, 119, 34, 50, 51, 34, 0, 192, 107, 118, 55, 34, 0, 192, 109, 121, 14, 34, 96, 196, 249, 122, 0, 192, 46, 124, 0, 161, 213, 19, 75, 1, 84, 115, 0, 162, 210, 18, 73, 5, 84, 65, 133, 41, 0, 192, 0, 0, 0, 192, 0, 103, 0, 161, 213, 3, 81, 1, 98, 170, 0, 162, 146, 18, 77, 5, 98, 162, 133, 41, 0, 192, 0, 0, 0, 192, 232, 107, 0, 176, 227, 252, 1, 176, 142, 21, 0, 176, 8, 228, 1, 176, 98, 80, 1, 176, 227, 80, 0, 176, 203, 189, 0, 176, 209, 225, 1, 176, 116, 81, 0, 176, 152, 180, 0, 176, 243, 183, 1, 176, 213, 81, 1, 176, 116, 61, 38, 5, 49, 52, 68, 36, 4, 104, 75, 10, 0, 176, 122, 199, 0, 176, 57, 1, 1, 176, 86, 82, 0, 176, 65, 183, 2, 41, 68, 1, 1, 176, 231, 82, 0, 176, 122, 1, 1, 176, 56, 83, 0, 176, 61, 195, 0, 176, 125, 247, 1, 176, 169, 83, 49, 52, 68, 36, 0, 176, 53, 227, 0, 176, 123, 181, 1, 176, 10, 84, 0, 176, 22, 185, 0, 176, 78, 182, 1, 176, 107, 84, 0, 176, 48, 235, 0, 176, 253, 181, 5, 146, 176, 82, 1, 0, 5, 146, 40, 52, 1, 0, 5, 146, 168, 53, 1, 0, 5, 146, 40, 52, 1, 0, 5, 146, 40, 52, 1, 0, 5, 146, 168, 52, 1, 0, 5, 146, 168, 52, 1, 0, 5, 146, 40, 52, 1, 0, 5, 146, 40, 52, 1, 0, 5, 146, 168, 51, 1, 0, 0, 162, 146, 50, 77, 9, 98, 162, 6, 106, 0, 208, 143, 38, 0, 208, 208, 38, 0, 208, 17, 39, 0, 208, 82, 39, 0, 208, 147, 39, 0, 208, 212, 39, 138, 41, 1, 176, 216, 12, 0, 176, 70, 40, 0, 162, 25, 50, 87, 9, 230, 171, 6, 106, 0, 208, 134, 44, 0, 208, 183, 44, 0, 208, 232, 44, 0, 208, 25, 45, 0, 208, 74, 45, 0, 208, 123, 45, 0, 39, 0, 176, 254, 45, 138, 41, 1, 176, 204, 84, 1, 0, 0, 145, 194, 0, 31, 36, 0, 208, 97, 22, 0, 176, 204, 24, 2, 41, 18, 104, 6, 106, 0, 208, 82, 32, 0, 208, 147, 32, 0, 208, 212, 32, 0, 208, 21, 33, 0, 208, 70, 33, 0, 208, 151, 33, 32, 238, 200, 33, 0, 176, 233, 33, 0, 162, 35, 18, 0, 0, 0, 0, 0, 176, 10, 34, 1, 0, 0, 161, 213, 26, 75, 1, 84, 115, 0, 162, 210, 18, 73, 1, 84, 65, 0, 192, 55, 101, 0, 161, 213, 26, 75, 1, 84, 115, 0, 162, 210, 18, 73, 1, 84, 65, 0, 192, 153, 172, 0, 162, 18, 2, 75, 1, 84, 65, 0, 192, 186, 128, 0, 161, 21, 21, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 129, 194, 20, 66, 0, 161, 213, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 0, 192, 220, 103, 2, 161, 213, 3, 73, 5, 226, 155, 2, 162, 210, 19, 73, 5, 226, 155, 177, 196, 253, 84, 2, 161, 213, 3, 73, 5, 226, 155, 2, 162, 210, 19, 73, 5, 226, 155, 0, 197, 105, 176, 3, 13, 201, 116, 0, 149, 0, 161, 213, 3, 85, 1, 246, 221, 1, 192, 172, 85, 4, 13, 201, 116, 104, 149, 0, 161, 213, 3, 85, 1, 246, 221, 1, 197, 192, 87, 2, 13, 149, 201, 0, 161, 25, 3, 85, 1, 246, 221, 65, 193, 67, 45, 0, 161, 25, 3, 73, 1, 100, 171, 0, 162, 18, 2, 73, 1, 100, 171, 133, 41, 32, 195, 40, 144, 32, 195, 40, 144, 0, 161, 213, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 97, 196, 144, 90, 0, 161, 213, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 192, 195, 130, 169, 0, 161, 25, 3, 73, 1, 100, 171, 0, 162, 18, 2, 73, 1, 100, 171, 1, 192, 174, 92, 0, 161, 25, 3, 73, 1, 100, 171, 0, 162, 18, 2, 73, 1, 100, 171, 1, 192, 169, 95, 1, 176, 204, 84, 68, 34, 1, 176, 225, 98, 0, 176, 183, 0, 68, 34, 0, 176, 211, 191, 0, 176, 198, 212, 0, 176, 38, 222, 1, 176, 34, 99, 68, 34, 1, 176, 253, 14, 0, 176, 207, 200, 0, 176, 228, 197, 0, 176, 27, 239, 0, 176, 157, 209, 68, 34, 0, 176, 77, 190, 50, 34, 1, 176, 70, 19, 0, 176, 57, 1, 0, 176, 40, 254, 1, 176, 115, 99, 1, 176, 180, 99, 1, 176, 5, 100, 1, 176, 102, 100, 1, 176, 183, 100, 1, 176, 8, 101, 68, 34, 0, 176, 134, 198, 0, 176, 183, 227, 1, 176, 105, 101, 0, 176, 235, 208, 1, 176, 169, 83, 68, 34, 1, 176, 53, 17, 0, 176, 123, 181, 1, 176, 170, 101, 1, 176, 97, 65, 1, 176, 251, 101, 0, 176, 86, 231, 1, 176, 92, 102, 1, 176, 189, 102, 68, 34, 0, 176, 224, 229, 1, 176, 106, 58, 1, 176, 139, 25, 1, 176, 30, 103, 1, 176, 111, 103, 1, 176, 192, 103, 0, 176, 203, 246, 0, 176, 57, 1, 0, 176, 12, 229, 1, 176, 106, 20, 108, 17, 1, 176, 5, 19, 0, 176, 252, 199, 0, 176, 235, 254, 144, 40, 2, 104, 8, 96, 139, 40, 2, 104, 124, 1, 138, 41, 138, 42, 2, 104, 124, 1, 1, 176, 62, 15, 1, 176, 70, 19, 144, 40, 2, 104, 8, 96, 139, 40, 2, 104, 113, 1, 138, 41, 138, 42, 2, 104, 113, 1, 1, 176, 87, 66, 0, 176, 50, 216, 144, 40, 2, 104, 8, 96, 139, 40, 2, 104, 109, 1, 138, 41, 138, 42, 2, 104, 109, 1, 0, 176, 12, 229, 0, 176, 206, 219, 0, 176, 78, 182, 1, 176, 184, 24, 144, 40, 2, 104, 8, 96, 139, 40, 2, 104, 111, 1, 138, 41, 138, 42, 2, 104, 111, 1, 0, 176, 245, 244, 0, 176, 188, 181, 2, 13, 175, 201, 1, 176, 17, 104, 144, 40, 2, 104, 8, 96, 139, 40, 2, 104, 110, 1, 138, 41, 138, 42, 2, 104, 110, 1, 0, 176, 251, 223, 0, 176, 122, 1, 0, 161, 222, 19, 87, 1, 246, 204, 0, 162, 18, 2, 85, 1, 118, 205, 133, 41, 0, 197, 251, 119, 0, 192, 251, 119, 1, 47, 0, 176, 233, 59, 0, 161, 213, 3, 85, 9, 246, 221, 0, 162, 18, 2, 85, 41, 246, 221, 2, 47, 5, 104, 0, 176, 75, 60, 192, 243, 251, 119, 0, 176, 173, 60, 192, 243, 251, 119, 1, 176, 62, 15, 57, 34, 0, 176, 122, 199, 0, 176, 46, 205, 0, 176, 187, 199, 1, 176, 213, 29, 0, 176, 27, 239, 0, 176, 8, 208, 1, 176, 82, 104, 1, 176, 147, 104, 1, 176, 212, 104, 1, 176, 135, 19, 1, 176, 87, 66, 1, 176, 242, 22, 0, 176, 3, 202, 0, 176, 81, 191, 0, 161, 25, 3, 173, 1, 238, 188, 0, 162, 146, 18, 173, 1, 110, 189, 192, 195, 197, 236, 0, 161, 222, 19, 87, 1, 246, 204, 0, 162, 18, 2, 85, 1, 118, 205, 133, 41, 0, 197, 251, 119, 0, 192, 251, 119, 0, 161, 213, 3, 85, 9, 246, 221, 0, 162, 18, 2, 85, 41, 246, 221, 1, 47, 0, 176, 233, 59, 0, 176, 173, 60, 192, 243, 251, 119, 0, 176, 92, 219, 108, 17, 0, 176, 183, 0, 13, 17, 0, 176, 206, 219, 0, 176, 206, 219, 0, 176, 248, 0, 38, 5, 1, 176, 62, 15, 0, 176, 122, 1, 0, 176, 233, 180, 0, 176, 187, 1, 0, 176, 162, 183, 0, 176, 34, 244, 0, 176, 143, 182, 0, 176, 107, 194, 1, 176, 108, 78, 1, 176, 108, 78, 13, 17, 107, 34, 1, 176, 21, 105, 1, 176, 108, 78, 13, 17, 0, 176, 122, 199, 128, 40, 0, 176, 203, 189, 0, 176, 198, 212, 0, 176, 203, 189, 128, 40, 0, 176, 203, 189, 0, 176, 115, 230, 1, 176, 86, 105, 0, 176, 101, 253, 130, 40, 0, 176, 12, 229, 0, 176, 248, 0, 59, 34, 5, 104, 224, 236, 84, 26, 0, 176, 46, 205, 60, 34, 5, 104, 32, 238, 73, 27, 0, 176, 207, 190, 0, 176, 231, 253, 0, 176, 157, 224, 0, 176, 253, 181, 130, 40, 0, 176, 32, 201, 1, 176, 145, 28, 0, 176, 123, 181, 1, 176, 142, 21, 0, 176, 157, 209, 0, 176, 238, 209, 1, 176, 151, 105, 2, 41, 55, 1, 1, 176, 232, 105, 138, 41, 122, 1, 6, 106, 0, 208, 204, 27, 0, 208, 253, 27, 0, 208, 46, 28, 0, 208, 95, 28, 0, 208, 144, 28, 0, 208, 209, 28, 0, 39, 0, 176, 18, 29, 1, 176, 57, 106, 138, 41, 59, 1, 0, 145, 194, 0, 28, 32, 224, 236, 171, 24, 4, 96, 2, 39, 128, 237, 171, 24, 1, 176, 122, 106, 0, 145, 93, 1, 0, 176, 103, 185, 0, 161, 213, 3, 75, 1, 84, 115, 0, 162, 210, 19, 73, 1, 84, 65, 133, 41, 0, 197, 74, 172, 55, 34, 0, 192, 2, 102, 128, 199, 55, 101, 0, 161, 21, 28, 75, 9, 98, 170, 0, 162, 18, 2, 77, 9, 98, 170, 1, 47, 0, 176, 208, 51, 133, 41, 5, 104, 0, 176, 1, 52, 0, 240, 50, 52, 34, 34, 5, 104, 0, 176, 100, 47, 32, 243, 109, 53, 0, 176, 60, 53, 32, 243, 109, 53, 0, 162, 25, 18, 13, 1, 98, 170, 133, 41, 5, 104, 0, 176, 143, 69, 0, 240, 192, 69, 0, 176, 109, 72, 0, 240, 40, 137, 3, 13, 202, 100, 0, 145, 0, 161, 227, 83, 85, 9, 246, 221, 1, 47, 0, 176, 173, 54, 133, 41, 5, 104, 0, 176, 222, 54, 0, 240, 188, 113, 0, 176, 157, 57, 96, 249, 188, 113, 0, 161, 213, 3, 77, 1, 238, 188, 0, 162, 146, 18, 77, 1, 110, 189, 133, 41, 0, 192, 60, 117, 0, 192, 249, 122, 0, 176, 85, 0, 0, 176, 57, 1, 0, 176, 102, 242, 0, 176, 206, 219, 0, 176, 227, 252, 0, 176, 233, 180, 0, 176, 123, 181, 0, 176, 175, 229, 0, 176, 162, 183, 0, 176, 68, 184, 0, 176, 6, 203, 0, 161, 213, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 1, 192, 67, 23, 0, 176, 215, 198, 0, 176, 203, 189, 38, 5, 0, 176, 115, 244, 0, 176, 248, 0, 0, 176, 12, 229, 0, 176, 27, 239, 0, 176, 141, 219, 0, 176, 87, 180, 0, 176, 198, 212, 0, 176, 123, 181, 0, 176, 222, 239, 1, 176, 171, 106, 0, 176, 11, 214, 0, 176, 202, 213, 0, 176, 253, 181, 1, 176, 42, 14, 0, 176, 175, 229, 0, 176, 133, 212, 0, 176, 162, 183, 60, 1, 0, 145, 208, 0, 1, 0, 2, 43, 51, 1, 1, 176, 236, 106, 2, 13, 129, 202, 1, 176, 29, 107, 0, 161, 25, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 48, 50, 47, 50, 49, 34, 0, 192, 252, 134, 0, 192, 40, 137, 0, 161, 213, 26, 75, 1, 84, 115, 0, 162, 210, 18, 73, 1, 84, 65, 133, 41, 0, 192, 55, 101, 34, 34, 96, 196, 37, 100, 51, 50, 52, 34, 0, 192, 37, 100, 14, 34, 0, 192, 55, 101, 55, 34, 0, 192, 2, 102, 0, 192, 0, 103, 0, 161, 213, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 34, 50, 51, 50, 52, 34, 0, 192, 12, 105, 160, 197, 232, 107, 0, 176, 85, 0, 0, 176, 57, 1, 136, 40, 0, 176, 206, 219, 0, 176, 57, 199, 1, 176, 106, 20, 0, 176, 32, 201, 0, 176, 123, 181, 0, 161, 213, 3, 76, 5, 92, 139, 0, 162, 146, 18, 76, 1, 110, 189, 133, 41, 129, 194, 78, 107, 55, 34, 0, 192, 109, 121, 193, 195, 78, 107, 0, 161, 213, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 1, 192, 67, 23, 2, 41, 1, 1, 0, 41, 124, 1, 108, 18, 0, 176, 87, 180, 2, 41, 1, 1, 0, 41, 124, 1, 0, 176, 22, 180, 2, 41, 1, 1, 0, 41, 125, 1, 0, 176, 248, 0, 2, 41, 1, 1, 0, 41, 126, 1, 0, 176, 57, 1, 2, 41, 1, 1, 0, 41, 127, 1, 0, 176, 233, 180, 2, 41, 1, 1, 0, 41, 128, 1, 0, 176, 123, 181, 2, 41, 1, 1, 0, 176, 22, 180, 2, 41, 1, 1, 0, 176, 248, 0, 2, 41, 1, 1, 0, 176, 57, 1, 2, 41, 1, 1, 0, 176, 233, 180, 2, 41, 1, 1, 0, 176, 123, 181, 5, 146, 40, 52, 1, 0, 5, 146, 4, 181, 1, 0, 13, 18, 108, 34, 0, 176, 92, 219, 1, 176, 253, 14, 0, 176, 215, 198, 108, 34, 0, 176, 92, 219, 1, 176, 253, 14, 38, 5, 0, 176, 57, 1, 0, 176, 248, 0, 0, 176, 180, 244, 0, 176, 251, 223, 0, 176, 123, 181, 1, 176, 142, 21, 1, 176, 118, 17, 0, 176, 68, 184, 0, 176, 240, 182, 1, 176, 97, 109, 0, 176, 105, 232, 0, 176, 165, 184, 0, 176, 125, 247, 0, 176, 22, 185, 5, 146, 168, 54, 1, 0, 108, 34, 0, 176, 92, 219, 1, 176, 253, 14, 13, 18, 108, 34, 0, 176, 92, 219, 0, 176, 15, 220, 38, 5, 0, 176, 118, 227, 38, 5, 0, 176, 92, 239, 0, 176, 215, 217, 0, 176, 27, 239, 0, 176, 180, 244, 0, 176, 58, 181, 0, 176, 233, 180, 0, 176, 53, 227, 0, 176, 123, 181, 38, 5, 0, 176, 57, 1, 0, 176, 206, 219, 0, 176, 115, 230, 0, 176, 122, 1, 0, 176, 187, 1, 0, 176, 68, 184, 0, 176, 10, 194, 0, 176, 85, 0, 38, 5, 0, 176, 92, 239, 0, 176, 245, 244, 0, 176, 183, 0, 0, 176, 248, 0, 0, 176, 152, 180, 0, 176, 233, 180, 1, 176, 145, 28, 0, 176, 57, 1, 0, 176, 12, 229, 1, 176, 106, 20, 0, 176, 252, 199, 0, 176, 235, 254, 6, 106, 0, 208, 238, 21, 0, 208, 31, 22, 0, 208, 64, 22, 96, 223, 97, 22, 0, 208, 146, 22, 0, 208, 211, 22, 2, 39, 128, 237, 171, 24, 1, 197, 194, 109, 81, 181, 92, 9, 1, 176, 9, 115, 0, 176, 206, 219, 38, 5, 0, 176, 166, 253, 1, 176, 222, 9, 1, 176, 47, 10, 0, 176, 105, 254, 0, 176, 205, 243, 1, 176, 161, 10, 1, 176, 228, 16, 1, 176, 70, 19, 0, 176, 12, 229, 0, 176, 141, 219, 0, 176, 253, 181, 1, 176, 171, 20, 0, 176, 235, 254, 0, 176, 251, 223, 0, 176, 227, 252, 2, 13, 175, 201, 1, 176, 17, 104, 0, 176, 57, 1, 1, 176, 9, 115, 0, 176, 12, 190, 0, 176, 180, 244, 0, 176, 202, 213, 0, 176, 233, 180, 0, 176, 187, 1, 38, 5, 1, 176, 70, 19, 0, 176, 12, 229, 2, 13, 168, 201, 1, 176, 210, 28, 73, 43, 0, 176, 212, 241, 1, 176, 126, 59, 73, 43, 0, 176, 156, 233, 0, 176, 215, 198, 1, 176, 250, 62, 0, 176, 245, 244, 4, 161, 213, 3, 75, 1, 84, 115, 0, 162, 210, 19, 73, 1, 84, 65, 0, 192, 55, 101, 2, 44, 2, 43, 82, 1, 0, 145, 193, 2, 1, 0, 4, 161, 213, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 133, 41, 0, 192, 220, 103, 96, 196, 245, 108, 4, 161, 213, 3, 77, 1, 228, 154, 133, 41, 1, 197, 74, 115, 1, 197, 74, 115, 6, 161, 213, 3, 75, 1, 162, 162, 0, 162, 146, 18, 75, 1, 110, 189, 193, 195, 122, 116, 31, 37, 99, 1, 3, 96, 0, 145, 234, 5, 1, 0, 0, 176, 85, 0, 0, 176, 85, 0, 38, 5, 0, 176, 157, 224, 38, 5, 0, 176, 57, 1, 0, 176, 248, 0, 0, 176, 248, 0, 0, 176, 12, 190, 0, 176, 12, 190, 0, 176, 22, 180, 1, 176, 126, 59, 0, 176, 122, 1, 0, 176, 122, 1, 0, 176, 233, 180, 0, 176, 233, 180, 0, 176, 245, 244, 0, 176, 187, 1, 109, 16, 0, 176, 22, 180, 0, 176, 22, 180, 0, 176, 248, 0, 0, 176, 248, 0, 1, 176, 62, 15, 0, 176, 57, 1, 0, 176, 251, 223, 0, 176, 251, 223, 1, 176, 135, 19, 1, 176, 135, 19, 1, 176, 9, 20, 0, 176, 85, 0, 1, 176, 106, 20, 1, 176, 5, 19, 0, 176, 12, 229, 0, 176, 248, 0, 1, 176, 62, 15, 0, 176, 57, 1, 0, 176, 233, 180, 0, 176, 233, 180, 1, 176, 135, 19, 1, 176, 135, 19, 0, 176, 162, 183, 1, 176, 118, 17, 0, 176, 92, 219, 2, 13, 144, 201, 13, 18, 1, 176, 106, 20, 0, 176, 198, 212, 1, 176, 213, 29, 1, 176, 213, 29, 0, 176, 206, 219, 0, 176, 12, 229, 1, 176, 62, 15, 0, 176, 57, 1, 0, 176, 32, 201, 0, 176, 32, 201, 1, 176, 135, 19, 1, 176, 135, 19, 1, 176, 9, 20, 0, 176, 10, 194, 2, 43, 2, 104, 6, 96, 138, 39, 3, 104, 56, 1, 2, 96, 59, 1, 0, 145, 208, 0, 1, 0, 2, 13, 185, 201, 6, 106, 0, 208, 226, 187, 0, 208, 19, 188, 0, 208, 68, 188, 0, 208, 133, 188, 0, 208, 182, 188, 0, 208, 231, 188, 2, 39, 64, 236, 236, 5, 0, 176, 95, 6, 46, 34, 4, 104, 95, 10, 1, 176, 102, 118, 1, 176, 151, 118, 0, 176, 122, 199, 38, 5, 1, 176, 200, 118, 38, 5, 0, 176, 142, 190, 55, 17, 0, 176, 101, 253, 3, 13, 201, 105, 0, 153, 44, 5, 0, 176, 180, 230, 109, 16, 0, 176, 12, 190, 1, 13, 0, 97, 1, 176, 5, 19, 4, 13, 145, 201, 144, 203, 44, 5, 0, 176, 211, 191, 0, 176, 32, 201, 114, 17, 0, 176, 252, 199, 0, 176, 235, 254, 0, 176, 146, 191, 0, 161, 213, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 133, 41, 0, 192, 42, 167, 0, 192, 130, 169, 0, 161, 213, 3, 76, 1, 238, 172, 0, 162, 146, 18, 76, 1, 110, 189, 133, 41, 32, 195, 105, 176, 55, 34, 0, 192, 109, 121, 160, 197, 105, 176, 0, 161, 213, 3, 76, 1, 238, 172, 0, 162, 146, 18, 76, 1, 110, 189, 133, 41, 32, 195, 249, 122, 192, 195, 249, 122, 6, 106, 0, 208, 238, 21, 0, 208, 31, 22, 0, 208, 64, 22, 96, 223, 97, 22, 0, 208, 146, 22, 0, 208, 211, 22, 2, 39, 128, 237, 171, 24, 1, 197, 194, 109, 0, 161, 213, 3, 75, 1, 84, 115, 0, 162, 210, 19, 73, 1, 84, 65, 133, 41, 0, 192, 33, 98, 34, 34, 0, 192, 37, 100, 55, 34, 0, 192, 2, 102, 0, 192, 153, 172, 0, 161, 25, 3, 64, 9, 118, 90, 0, 162, 18, 2, 64, 9, 98, 90, 6, 106, 16, 223, 198, 4, 16, 223, 247, 4, 16, 223, 40, 5, 16, 223, 89, 5, 16, 223, 138, 5, 16, 223, 187, 5, 2, 39, 224, 236, 236, 5, 0, 176, 254, 13, 64, 246, 218, 16, 13, 48, 108, 32, 2, 104, 5, 96, 0, 176, 233, 11, 0, 240, 177, 6, 1, 0, 0, 161, 213, 3, 77, 1, 238, 188, 133, 41, 0, 192, 220, 109, 0, 192, 44, 112, 3, 13, 201, 116, 0, 149, 0, 161, 227, 83, 85, 1, 246, 221, 133, 41, 0, 192, 188, 113, 0, 192, 188, 113, 38, 5, 108, 17, 0, 176, 115, 244, 38, 5, 0, 176, 77, 190, 0, 176, 12, 229, 0, 176, 180, 244, 0, 176, 32, 201, 0, 176, 78, 182, 0, 176, 123, 181, 0, 176, 54, 245, 0, 176, 253, 181, 0, 176, 119, 245, 0, 176, 216, 245, 0, 176, 61, 195, 0, 176, 34, 244, 0, 176, 41, 246, 0, 176, 122, 246, 0, 176, 203, 246, 0, 176, 28, 247, 0, 176, 125, 247, 0, 176, 206, 247, 0, 176, 31, 248, 0, 176, 209, 248, 0, 176, 34, 249, 0, 176, 115, 249, 0, 176, 196, 249, 0, 176, 89, 228, 0, 176, 21, 250, 0, 161, 25, 3, 169, 1, 84, 90, 0, 162, 25, 18, 9, 1, 84, 73, 133, 41, 0, 176, 165, 65, 0, 176, 56, 66, 0, 161, 213, 3, 79, 9, 98, 155, 0, 162, 146, 18, 79, 9, 98, 155, 1, 47, 0, 176, 208, 51, 133, 41, 5, 104, 0, 176, 1, 52, 0, 240, 50, 52, 34, 34, 5, 104, 0, 176, 100, 47, 192, 243, 244, 53, 0, 176, 60, 53, 192, 243, 244, 53, 28, 34, 0, 192, 8, 156, 29, 34, 0, 192, 93, 157, 30, 34, 0, 192, 252, 158, 31, 34, 0, 192, 161, 160, 32, 34, 96, 196, 167, 250, 33, 34, 0, 197, 167, 250, 96, 196, 127, 165, 0, 176, 183, 0, 0, 176, 12, 229, 0, 176, 57, 1, 0, 176, 233, 180, 0, 176, 187, 1, 0, 161, 213, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 133, 41, 1, 192, 67, 23, 1, 192, 67, 23, 0, 161, 217, 19, 77, 5, 98, 170, 0, 162, 18, 2, 77, 9, 98, 170, 1, 47, 0, 176, 208, 51, 133, 41, 5, 104, 0, 176, 143, 69, 193, 243, 67, 23, 0, 176, 25, 172, 193, 248, 67, 23, 0, 161, 213, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 133, 41, 0, 192, 42, 167, 0, 192, 130, 169, 0, 161, 217, 19, 77, 5, 98, 170, 0, 162, 18, 2, 77, 9, 98, 170, 1, 47, 0, 176, 208, 51, 133, 41, 5, 104, 0, 176, 143, 69, 192, 243, 42, 167, 0, 176, 25, 172, 192, 248, 130, 169, 136, 40, 70, 10, 0, 176, 46, 205, 136, 40, 70, 10, 1, 176, 105, 101, 136, 40, 70, 10, 0, 176, 73, 208, 136, 40, 70, 10, 0, 176, 188, 181, 0, 176, 180, 244, 1, 176, 5, 19, 0, 176, 27, 239, 1, 176, 249, 118, 0, 176, 244, 226, 1, 176, 90, 119, 0, 176, 196, 216, 1, 176, 155, 119, 0, 176, 170, 254, 0, 161, 25, 3, 173, 1, 238, 188, 0, 162, 146, 18, 173, 1, 110, 189, 192, 195, 197, 236, 92, 43, 2, 104, 2, 96, 64, 1, 0, 145, 208, 0, 1, 0, 0, 176, 118, 207, 0, 176, 57, 1, 0, 176, 105, 254, 0, 176, 141, 219, 0, 176, 12, 229, 0, 176, 251, 223, 0, 176, 34, 244, 1, 176, 161, 22, 0, 176, 85, 0, 1, 176, 12, 59, 35, 19, 0, 176, 203, 189, 0, 176, 206, 219, 109, 19, 0, 176, 85, 0, 38, 5, 0, 176, 77, 190, 111, 19, 38, 5, 0, 176, 85, 0, 0, 176, 58, 181, 113, 19, 0, 176, 85, 0, 0, 176, 146, 191, 115, 19, 0, 176, 85, 0, 0, 176, 211, 191, 0, 176, 248, 0, 0, 176, 57, 1, 0, 176, 233, 180, 0, 176, 123, 181, 0, 176, 174, 255, 1, 176, 59, 63, 0, 176, 6, 203, 1, 176, 220, 119, 0, 176, 57, 1, 0, 176, 253, 181, 0, 176, 187, 1, 0, 176, 46, 205, 0, 176, 175, 229, 0, 176, 251, 223, 2, 13, 175, 201, 1, 176, 108, 78, 0, 176, 57, 199, 58, 36, 3, 0, 144, 40, 3, 0, 9, 104, 141, 40, 2, 104, 113, 1, 113, 38, 8, 0, 142, 40, 2, 104, 113, 1, 0, 176, 176, 205, 0, 176, 118, 207, 1, 176, 9, 115, 0, 176, 122, 199, 92, 61, 8, 0, 92, 45, 7, 0, 111, 1, 112, 1, 1, 0, 92, 61, 8, 0, 92, 45, 7, 0, 108, 1, 2, 96, 40, 1, 1, 0, 93, 45, 7, 0, 110, 1, 2, 96, 36, 1, 1, 0, 93, 61, 8, 0, 93, 45, 7, 0, 104, 1, 0, 145, 54, 5, 1, 0, 93, 61, 8, 0, 93, 45, 7, 0, 118, 1, 2, 96, 100, 1, 1, 0, 93, 61, 8, 0, 93, 45, 7, 0, 64, 1, 0, 145, 208, 0, 1, 0, 2, 13, 144, 201, 0, 176, 176, 205, 2, 13, 155, 201, 0, 176, 12, 190, 2, 13, 140, 202, 0, 176, 202, 213, 1, 13, 0, 111, 1, 176, 222, 9, 1, 13, 0, 117, 0, 176, 123, 181, 2, 13, 175, 201, 0, 176, 40, 254, 2, 161, 213, 3, 73, 5, 226, 155, 2, 162, 210, 19, 73, 5, 226, 155, 177, 196, 253, 84, 0, 161, 21, 21, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 129, 194, 61, 120, 3, 13, 201, 116, 0, 149, 0, 161, 213, 3, 85, 1, 246, 221, 1, 192, 91, 37, 3, 13, 202, 100, 0, 145, 0, 161, 213, 3, 85, 1, 246, 221, 0, 176, 157, 57, 0, 240, 209, 58, 2, 13, 190, 201, 0, 162, 136, 20, 73, 13, 96, 170, 0, 161, 10, 19, 77, 9, 96, 170, 31, 48, 30, 32, 0, 176, 80, 46, 0, 176, 161, 46, 0, 176, 183, 0, 136, 40, 0, 176, 72, 213, 0, 176, 248, 0, 0, 176, 57, 1, 0, 176, 233, 180, 0, 176, 105, 254, 0, 176, 162, 183, 3, 13, 108, 116, 0, 35, 0, 161, 213, 3, 77, 1, 98, 170, 0, 162, 146, 18, 77, 1, 98, 162, 33, 195, 111, 74, 0}; autoFileInMemory espeakdata_phons3 = FileInMemory_createWithData (20426, reinterpret_cast (&espeakdata_phons3_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/phonindex", U"phonindex"); Collection_addItem (me.peek(), espeakdata_phons3.transfer()); static unsigned char espeakdata_phons4_data[36149] = { 84, 0, 0, 0, 109, 0, 0, 0, 0, 0, 0, 0, 98, 97, 115, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 1, 0, 37, 37, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0, 0, 2, 0, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 5, 1, 0, 0, 3, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 1, 0, 0, 4, 0, 39, 39, 0, 0, 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 5, 0, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 1, 0, 0, 2, 0, 95, 58, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 10, 0, 37, 1, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 10, 0, 12, 1, 95, 33, 0, 0, 64, 0, 0, 0, 0, 0, 11, 0, 10, 0, 17, 1, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 9, 0, 0, 35, 0, 64, 0, 0, 0, 2, 0, 0, 0, 12, 0, 13, 2, 28, 28, 70, 0, 64, 45, 0, 0, 2, 0, 16, 0, 14, 0, 14, 2, 28, 28, 90, 0, 124, 124, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 9, 42, 0, 0, 0, 16, 64, 132, 0, 137, 2, 16, 5, 0, 0, 0, 3, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 35, 88, 49, 0, 40, 0, 4, 0, 60, 0, 18, 6, 0, 0, 0, 3, 63, 0, 0, 0, 72, 0, 12, 0, 2, 0, 19, 4, 0, 0, 0, 2, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 9, 0, 0, 0, 0, 95, 94, 95, 0, 0, 0, 0, 0, 0, 0, 21, 0, 10, 0, 5, 1, 95, 88, 49, 0, 0, 0, 0, 0, 0, 0, 22, 0, 10, 0, 5, 1, 95, 124, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 10, 0, 0, 5, 95, 58, 58, 0, 0, 0, 0, 0, 0, 0, 24, 0, 10, 0, 75, 1, 116, 35, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 39, 33, 0, 0, 0, 0, 0, 0, 0, 0, 26, 1, 0, 0, 6, 0, 95, 59, 95, 0, 0, 0, 0, 0, 0, 0, 27, 0, 10, 0, 100, 1, 35, 64, 0, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 0, 0, 35, 97, 0, 0, 0, 0, 0, 0, 0, 0, 29, 9, 0, 0, 0, 0, 35, 101, 0, 0, 0, 0, 0, 0, 0, 0, 30, 9, 0, 0, 0, 0, 35, 105, 0, 0, 0, 0, 0, 0, 0, 0, 31, 9, 0, 0, 0, 0, 35, 111, 0, 0, 0, 0, 0, 0, 0, 0, 32, 9, 0, 0, 0, 0, 35, 117, 0, 0, 0, 0, 0, 0, 0, 0, 33, 9, 0, 0, 0, 0, 114, 0, 0, 0, 0, 0, 128, 0, 72, 0, 34, 3, 0, 0, 0, 7, 97, 0, 0, 0, 0, 0, 0, 0, 24, 0, 35, 2, 29, 29, 90, 0, 101, 0, 0, 0, 0, 0, 0, 0, 26, 0, 36, 2, 30, 30, 85, 0, 105, 0, 0, 0, 0, 0, 0, 0, 28, 0, 37, 2, 31, 31, 85, 0, 59, 0, 0, 0, 0, 2, 0, 0, 157, 1, 38, 3, 0, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 31, 0, 39, 2, 32, 32, 85, 0, 117, 0, 0, 0, 0, 0, 0, 0, 33, 0, 40, 2, 33, 33, 85, 0, 109, 45, 0, 0, 0, 0, 0, 0, 35, 0, 41, 2, 28, 28, 85, 0, 110, 45, 0, 0, 0, 0, 0, 0, 45, 0, 42, 2, 28, 28, 85, 0, 78, 45, 0, 0, 0, 0, 0, 0, 55, 0, 43, 2, 30, 30, 95, 0, 114, 45, 0, 0, 2, 0, 0, 0, 62, 0, 44, 2, 28, 28, 110, 0, 108, 45, 0, 0, 2, 0, 0, 0, 67, 0, 45, 2, 28, 28, 100, 0, 114, 47, 0, 0, 0, 0, 128, 0, 102, 0, 46, 3, 0, 0, 0, 2, 116, 0, 0, 0, 8, 0, 4, 0, 242, 4, 47, 4, 0, 72, 0, 2, 112, 0, 0, 0, 8, 0, 1, 0, 216, 4, 48, 4, 0, 71, 0, 2, 107, 0, 0, 0, 8, 0, 8, 0, 54, 5, 49, 4, 0, 81, 0, 2, 110, 0, 0, 0, 16, 0, 4, 0, 223, 1, 50, 8, 0, 0, 0, 4, 82, 0, 0, 0, 128, 0, 0, 0, 120, 0, 51, 3, 0, 0, 0, 6, 82, 50, 0, 0, 128, 0, 0, 0, 138, 0, 52, 3, 0, 0, 0, 6, 82, 51, 0, 0, 128, 0, 0, 0, 152, 0, 53, 3, 0, 0, 30, 6, 114, 34, 0, 0, 16, 0, 10, 0, 182, 0, 54, 7, 0, 0, 0, 6, 108, 0, 0, 0, 0, 0, 0, 0, 208, 0, 55, 3, 0, 0, 0, 7, 108, 47, 0, 0, 0, 0, 0, 0, 248, 0, 56, 3, 0, 0, 0, 7, 106, 0, 0, 0, 0, 2, 0, 0, 128, 1, 57, 3, 0, 0, 0, 7, 119, 0, 0, 0, 0, 0, 0, 0, 93, 1, 58, 3, 0, 0, 0, 7, 108, 47, 50, 0, 0, 0, 0, 0, 15, 1, 59, 3, 0, 0, 0, 7, 108, 47, 51, 0, 0, 0, 0, 0, 39, 1, 60, 3, 0, 0, 0, 7, 108, 94, 0, 0, 0, 0, 0, 0, 56, 1, 61, 3, 0, 0, 50, 7, 108, 46, 0, 0, 0, 0, 5, 0, 80, 1, 62, 3, 0, 0, 0, 7, 76, 47, 0, 0, 0, 0, 0, 0, 15, 1, 63, 3, 0, 0, 0, 7, 76, 0, 0, 0, 0, 0, 0, 0, 84, 1, 64, 3, 0, 0, 0, 7, 109, 0, 0, 0, 16, 0, 1, 0, 183, 1, 65, 8, 0, 0, 0, 4, 110, 46, 0, 0, 16, 0, 5, 0, 4, 2, 66, 8, 50, 0, 0, 4, 110, 94, 0, 0, 16, 2, 7, 0, 42, 2, 67, 8, 0, 0, 0, 4, 78, 0, 0, 0, 16, 0, 8, 0, 82, 2, 68, 8, 0, 0, 0, 8, 42, 42, 0, 0, 0, 0, 132, 0, 121, 2, 69, 3, 0, 0, 0, 3, 114, 46, 0, 0, 0, 0, 5, 0, 183, 2, 70, 3, 0, 0, 0, 3, 98, 0, 0, 0, 16, 0, 1, 0, 193, 2, 71, 5, 0, 48, 0, 5, 100, 0, 0, 0, 16, 0, 4, 0, 12, 3, 72, 5, 0, 47, 0, 5, 100, 91, 0, 0, 16, 0, 3, 0, 33, 3, 73, 5, 0, 74, 0, 5, 116, 91, 0, 0, 8, 0, 3, 0, 7, 5, 74, 4, 0, 73, 0, 2, 100, 90, 0, 0, 48, 0, 6, 0, 60, 3, 75, 5, 0, 76, 0, 5, 116, 83, 0, 0, 40, 0, 6, 0, 20, 5, 76, 4, 0, 75, 0, 2, 100, 90, 59, 0, 48, 2, 6, 0, 81, 3, 77, 5, 0, 78, 0, 5, 116, 83, 59, 0, 40, 2, 7, 0, 29, 5, 78, 4, 0, 77, 0, 2, 74, 0, 0, 0, 48, 2, 7, 0, 117, 3, 79, 5, 0, 80, 0, 5, 99, 0, 0, 0, 8, 2, 7, 0, 41, 5, 80, 4, 0, 79, 0, 2, 103, 0, 0, 0, 16, 0, 8, 0, 150, 3, 81, 5, 0, 49, 0, 5, 66, 0, 0, 0, 16, 0, 1, 0, 171, 3, 82, 7, 0, 83, 0, 6, 102, 0, 0, 0, 8, 0, 2, 0, 103, 5, 83, 6, 0, 84, 0, 3, 118, 0, 0, 0, 16, 0, 2, 0, 201, 3, 84, 7, 0, 83, 0, 6, 118, 35, 0, 0, 16, 0, 2, 0, 238, 3, 85, 7, 0, 83, 0, 6, 68, 0, 0, 0, 16, 0, 3, 0, 253, 3, 86, 7, 0, 87, 0, 6, 84, 0, 0, 0, 8, 0, 3, 0, 112, 5, 87, 6, 0, 86, 0, 3, 122, 0, 0, 0, 48, 0, 4, 0, 16, 4, 88, 7, 0, 89, 0, 6, 115, 0, 0, 0, 40, 0, 4, 0, 125, 5, 89, 6, 0, 88, 0, 3, 90, 0, 0, 0, 48, 0, 6, 0, 40, 4, 90, 7, 0, 91, 0, 6, 83, 0, 0, 0, 40, 0, 6, 0, 143, 5, 91, 6, 0, 90, 0, 3, 122, 46, 0, 0, 48, 0, 6, 0, 70, 4, 92, 7, 0, 93, 0, 6, 115, 46, 0, 0, 40, 0, 6, 0, 156, 5, 93, 6, 0, 92, 0, 3, 122, 59, 0, 0, 48, 2, 7, 0, 102, 4, 94, 7, 0, 95, 0, 6, 115, 59, 0, 0, 40, 2, 7, 0, 171, 5, 95, 6, 0, 94, 0, 3, 90, 59, 0, 0, 48, 2, 7, 0, 122, 4, 96, 7, 0, 97, 0, 6, 83, 59, 0, 0, 40, 2, 7, 0, 186, 5, 97, 6, 0, 96, 0, 3, 74, 94, 0, 0, 16, 2, 7, 0, 142, 4, 98, 7, 0, 99, 0, 6, 67, 0, 0, 0, 8, 2, 7, 0, 221, 5, 99, 6, 0, 0, 0, 3, 81, 0, 0, 0, 16, 0, 8, 0, 156, 4, 100, 7, 0, 101, 0, 6, 120, 0, 0, 0, 8, 0, 8, 0, 234, 5, 101, 6, 0, 100, 0, 3, 81, 94, 0, 0, 16, 0, 8, 0, 186, 4, 102, 7, 0, 0, 0, 6, 81, 34, 0, 0, 16, 0, 10, 0, 204, 4, 103, 7, 0, 0, 0, 6, 113, 0, 0, 0, 8, 0, 10, 0, 87, 5, 104, 4, 0, 0, 0, 2, 108, 35, 0, 0, 8, 0, 4, 0, 201, 5, 105, 6, 0, 0, 0, 3, 88, 0, 0, 0, 8, 0, 10, 0, 247, 5, 106, 6, 0, 103, 0, 3, 104, 0, 0, 0, 8, 0, 12, 0, 252, 5, 107, 6, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 1, 0, 0, 0, 0, 0, 0, 99, 111, 110, 115, 111, 110, 97, 110, 116, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 115, 0, 0, 40, 0, 4, 0, 18, 6, 108, 4, 0, 109, 0, 2, 100, 122, 0, 0, 48, 0, 4, 0, 31, 6, 109, 5, 0, 108, 0, 5, 112, 45, 0, 0, 8, 0, 1, 0, 52, 6, 110, 4, 0, 71, 0, 2, 112, 104, 0, 0, 8, 0, 1, 0, 71, 6, 111, 4, 0, 71, 0, 2, 116, 45, 0, 0, 8, 0, 4, 0, 87, 6, 112, 4, 0, 72, 0, 2, 99, 50, 0, 0, 40, 0, 7, 0, 100, 6, 113, 4, 0, 0, 0, 2, 107, 45, 0, 0, 8, 0, 8, 0, 113, 6, 114, 4, 0, 81, 0, 2, 107, 104, 0, 0, 8, 0, 8, 0, 126, 6, 115, 4, 0, 81, 0, 2, 115, 50, 0, 0, 40, 0, 4, 0, 142, 6, 116, 6, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 1, 0, 0, 0, 0, 0, 0, 98, 97, 115, 101, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 151, 6, 35, 2, 29, 29, 90, 0, 101, 0, 0, 0, 0, 0, 0, 0, 160, 6, 36, 2, 30, 30, 85, 0, 105, 0, 0, 0, 0, 0, 0, 0, 164, 6, 37, 2, 31, 31, 75, 0, 111, 0, 0, 0, 0, 0, 0, 0, 167, 6, 39, 2, 32, 32, 85, 0, 117, 0, 0, 0, 0, 0, 0, 0, 171, 6, 40, 2, 33, 33, 80, 0, 116, 0, 0, 0, 8, 0, 3, 0, 220, 6, 47, 4, 0, 72, 0, 2, 112, 0, 0, 0, 8, 0, 1, 0, 201, 6, 48, 4, 0, 71, 0, 2, 107, 0, 0, 0, 8, 0, 8, 0, 4, 7, 49, 4, 0, 81, 0, 2, 100, 0, 0, 0, 16, 0, 3, 0, 233, 6, 72, 5, 0, 47, 0, 5, 97, 47, 0, 0, 0, 0, 0, 0, 158, 6, 108, 2, 28, 28, 90, 0, 69, 0, 0, 0, 0, 0, 0, 0, 162, 6, 109, 2, 30, 30, 85, 0, 79, 0, 0, 0, 0, 0, 0, 0, 169, 6, 110, 2, 32, 32, 85, 0, 85, 0, 0, 0, 0, 0, 0, 0, 173, 6, 111, 2, 33, 33, 80, 0, 121, 0, 0, 0, 0, 0, 0, 0, 175, 6, 112, 2, 31, 31, 80, 0, 89, 0, 0, 0, 0, 0, 0, 0, 177, 6, 113, 2, 28, 28, 80, 0, 97, 85, 0, 0, 0, 0, 0, 0, 179, 6, 114, 2, 29, 33, 135, 0, 101, 85, 0, 0, 0, 0, 0, 0, 181, 6, 115, 2, 30, 33, 130, 0, 105, 85, 0, 0, 0, 0, 0, 0, 183, 6, 116, 2, 31, 33, 120, 0, 97, 73, 0, 0, 0, 0, 0, 0, 185, 6, 117, 2, 29, 31, 125, 0, 101, 73, 0, 0, 0, 0, 0, 0, 187, 6, 118, 2, 30, 31, 125, 0, 69, 73, 0, 0, 0, 0, 0, 0, 189, 6, 119, 2, 30, 31, 115, 0, 111, 73, 0, 0, 0, 0, 0, 0, 191, 6, 120, 2, 32, 31, 120, 0, 117, 73, 0, 0, 0, 0, 0, 0, 193, 6, 121, 2, 33, 31, 120, 0, 119, 50, 0, 0, 0, 0, 0, 0, 195, 6, 122, 3, 0, 0, 0, 7, 116, 115, 0, 0, 40, 0, 4, 0, 18, 6, 123, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 0, 0, 101, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 127, 7, 13, 2, 28, 28, 70, 0, 116, 35, 0, 0, 16, 0, 4, 0, 29, 7, 25, 5, 0, 0, 0, 5, 97, 0, 0, 0, 0, 0, 0, 0, 154, 7, 35, 2, 29, 29, 80, 0, 105, 0, 0, 0, 0, 0, 0, 0, 181, 7, 37, 2, 31, 31, 70, 0, 114, 45, 0, 0, 0, 0, 128, 0, 100, 7, 44, 3, 0, 0, 0, 0, 108, 0, 0, 0, 0, 0, 0, 0, 66, 7, 55, 3, 0, 0, 0, 7, 116, 50, 0, 0, 16, 0, 4, 0, 27, 7, 108, 5, 0, 0, 0, 0, 100, 35, 0, 0, 8, 0, 4, 0, 56, 7, 109, 4, 0, 0, 0, 0, 122, 35, 0, 0, 40, 0, 4, 0, 61, 7, 110, 6, 0, 0, 0, 0, 103, 45, 0, 0, 16, 0, 8, 0, 79, 7, 111, 5, 0, 0, 0, 5, 122, 47, 50, 0, 48, 0, 4, 0, 120, 7, 112, 7, 0, 0, 0, 6, 73, 50, 0, 0, 2, 0, 0, 0, 175, 7, 113, 2, 31, 31, 65, 0, 51, 0, 0, 0, 2, 0, 0, 0, 133, 7, 114, 2, 28, 28, 70, 0, 64, 50, 0, 0, 2, 0, 0, 0, 138, 7, 115, 2, 28, 28, 60, 0, 64, 53, 0, 0, 2, 0, 0, 0, 142, 7, 116, 2, 28, 28, 70, 0, 85, 0, 0, 0, 0, 0, 0, 0, 192, 7, 117, 2, 32, 32, 75, 0, 64, 76, 0, 0, 2, 0, 0, 0, 147, 7, 118, 2, 28, 55, 80, 0, 97, 35, 0, 0, 2, 0, 0, 0, 160, 7, 119, 2, 28, 28, 75, 0, 97, 97, 0, 0, 0, 0, 0, 0, 164, 7, 120, 2, 29, 29, 92, 0, 69, 0, 0, 0, 0, 0, 0, 0, 169, 7, 121, 2, 30, 30, 70, 0, 73, 0, 0, 0, 0, 0, 0, 0, 172, 7, 122, 2, 31, 31, 65, 0, 73, 35, 0, 0, 2, 0, 0, 0, 178, 7, 123, 2, 31, 31, 65, 0, 48, 0, 0, 0, 0, 0, 0, 0, 186, 7, 124, 2, 32, 32, 70, 0, 86, 0, 0, 0, 0, 0, 0, 0, 189, 7, 125, 2, 29, 28, 70, 0, 65, 58, 0, 0, 0, 0, 0, 0, 194, 7, 126, 2, 29, 29, 115, 0, 65, 64, 0, 0, 0, 0, 0, 0, 197, 7, 127, 2, 29, 29, 115, 0, 51, 58, 0, 0, 0, 0, 0, 0, 203, 7, 128, 2, 28, 28, 105, 0, 105, 58, 0, 0, 0, 0, 0, 0, 207, 7, 129, 2, 31, 31, 87, 0, 79, 58, 0, 0, 0, 0, 0, 0, 213, 7, 130, 2, 32, 32, 115, 0, 79, 0, 0, 0, 0, 0, 0, 0, 216, 7, 131, 2, 32, 32, 100, 0, 79, 64, 0, 0, 0, 0, 0, 0, 219, 7, 132, 2, 32, 32, 120, 0, 111, 64, 0, 0, 0, 0, 0, 0, 225, 7, 133, 2, 32, 32, 125, 0, 117, 58, 0, 0, 0, 0, 0, 0, 231, 7, 134, 2, 33, 33, 105, 0, 97, 85, 0, 0, 0, 0, 0, 0, 238, 7, 135, 2, 29, 33, 115, 0, 111, 85, 0, 0, 0, 0, 0, 0, 240, 7, 136, 2, 28, 33, 110, 0, 97, 73, 0, 0, 0, 0, 0, 0, 245, 7, 137, 2, 29, 31, 120, 0, 101, 73, 0, 0, 0, 0, 0, 0, 249, 7, 138, 2, 30, 31, 105, 0, 79, 73, 0, 0, 0, 0, 0, 0, 251, 7, 139, 2, 32, 31, 115, 0, 101, 64, 0, 0, 0, 0, 0, 0, 253, 7, 140, 2, 30, 28, 115, 0, 105, 64, 0, 0, 0, 0, 0, 0, 0, 8, 141, 2, 31, 28, 125, 0, 105, 64, 51, 0, 0, 0, 0, 0, 3, 8, 142, 2, 31, 28, 125, 0, 85, 64, 0, 0, 0, 0, 0, 0, 6, 8, 143, 2, 33, 28, 100, 0, 97, 73, 64, 0, 0, 0, 0, 0, 12, 8, 144, 2, 29, 28, 140, 0, 97, 73, 51, 0, 0, 0, 0, 0, 15, 8, 145, 2, 29, 28, 140, 0, 97, 85, 64, 0, 0, 0, 0, 0, 17, 8, 146, 2, 29, 28, 140, 0, 73, 82, 0, 0, 0, 0, 0, 0, 20, 8, 147, 2, 28, 28, 95, 0, 86, 82, 0, 0, 0, 0, 0, 0, 30, 8, 148, 2, 28, 28, 105, 0, 111, 58, 0, 0, 0, 0, 0, 0, 40, 8, 149, 2, 32, 32, 110, 0, 65, 126, 0, 0, 0, 0, 0, 0, 42, 8, 150, 2, 29, 29, 130, 0, 79, 126, 0, 0, 0, 0, 0, 0, 44, 8, 151, 2, 32, 32, 120, 0, 101, 58, 0, 0, 0, 0, 0, 0, 46, 8, 152, 2, 30, 30, 105, 0, 64, 35, 0, 0, 2, 0, 0, 0, 48, 8, 153, 2, 31, 31, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 4, 0, 0, 0, 0, 0, 0, 101, 110, 45, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 59, 8, 35, 2, 29, 29, 70, 0, 105, 0, 0, 0, 0, 0, 0, 0, 71, 8, 37, 2, 31, 31, 75, 0, 78, 0, 0, 0, 16, 0, 8, 0, 50, 8, 68, 8, 0, 0, 0, 8, 73, 50, 0, 0, 2, 0, 0, 0, 68, 8, 113, 2, 31, 31, 70, 0, 51, 0, 0, 0, 2, 0, 0, 0, 54, 8, 114, 2, 28, 28, 70, 0, 85, 0, 0, 0, 0, 0, 0, 0, 82, 8, 117, 2, 32, 32, 85, 0, 97, 35, 0, 0, 2, 0, 0, 0, 84, 8, 119, 2, 28, 28, 70, 0, 97, 97, 0, 0, 0, 0, 0, 0, 98, 8, 120, 2, 29, 29, 75, 0, 69, 0, 0, 0, 0, 0, 0, 0, 62, 8, 121, 2, 29, 29, 75, 0, 73, 0, 0, 0, 0, 0, 0, 0, 65, 8, 122, 2, 31, 31, 65, 0, 48, 0, 0, 0, 0, 0, 0, 0, 74, 8, 124, 2, 32, 32, 75, 0, 86, 0, 0, 0, 0, 0, 0, 0, 77, 8, 125, 2, 32, 32, 70, 0, 65, 58, 0, 0, 0, 0, 0, 0, 89, 8, 126, 2, 29, 28, 120, 0, 65, 64, 0, 0, 0, 0, 0, 0, 92, 8, 127, 2, 29, 28, 125, 0, 51, 58, 0, 0, 0, 0, 0, 0, 102, 8, 128, 2, 28, 28, 115, 0, 105, 58, 0, 0, 0, 0, 0, 0, 106, 8, 129, 2, 31, 31, 87, 0, 79, 58, 0, 0, 0, 0, 0, 0, 112, 8, 130, 2, 32, 32, 120, 0, 79, 0, 0, 0, 0, 0, 0, 0, 128, 8, 131, 2, 32, 32, 75, 0, 79, 64, 0, 0, 0, 0, 0, 0, 116, 8, 132, 2, 32, 28, 120, 0, 111, 64, 0, 0, 0, 0, 0, 0, 122, 8, 133, 2, 32, 28, 120, 0, 117, 58, 0, 0, 0, 0, 0, 0, 131, 8, 134, 2, 33, 33, 100, 0, 97, 85, 0, 0, 0, 0, 0, 0, 133, 8, 135, 2, 30, 33, 115, 0, 111, 85, 0, 0, 0, 0, 0, 0, 138, 8, 136, 2, 32, 32, 110, 0, 97, 73, 0, 0, 0, 0, 0, 0, 143, 8, 137, 2, 29, 31, 115, 0, 101, 73, 0, 0, 0, 0, 0, 0, 145, 8, 138, 2, 31, 31, 105, 0, 79, 73, 0, 0, 0, 0, 0, 0, 150, 8, 139, 2, 32, 31, 115, 0, 101, 64, 0, 0, 0, 0, 0, 0, 152, 8, 140, 2, 30, 28, 110, 0, 105, 64, 0, 0, 0, 0, 0, 0, 155, 8, 141, 2, 31, 28, 120, 0, 85, 64, 0, 0, 0, 0, 0, 0, 158, 8, 143, 2, 33, 28, 100, 0, 97, 73, 64, 0, 0, 0, 0, 0, 161, 8, 144, 2, 29, 28, 140, 0, 97, 73, 51, 0, 0, 0, 0, 0, 164, 8, 145, 2, 29, 28, 140, 0, 97, 85, 64, 0, 0, 0, 0, 0, 166, 8, 146, 2, 29, 28, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 4, 0, 0, 0, 0, 0, 0, 101, 110, 45, 117, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 174, 8, 13, 2, 28, 28, 65, 0, 97, 0, 0, 0, 0, 0, 0, 0, 189, 8, 35, 2, 30, 28, 105, 0, 105, 0, 0, 0, 2, 0, 0, 0, 213, 8, 37, 2, 31, 31, 85, 0, 114, 47, 0, 0, 0, 0, 0, 0, 0, 0, 46, 3, 0, 0, 0, 2, 116, 0, 0, 0, 8, 0, 4, 0, 105, 9, 47, 4, 0, 72, 0, 2, 116, 50, 0, 0, 8, 0, 4, 0, 242, 4, 108, 4, 0, 0, 0, 2, 73, 50, 0, 0, 2, 0, 0, 0, 208, 8, 113, 2, 31, 31, 80, 0, 51, 0, 0, 0, 2, 0, 0, 0, 169, 8, 114, 2, 28, 28, 105, 0, 64, 50, 0, 0, 2, 0, 0, 0, 180, 8, 115, 2, 28, 28, 60, 0, 85, 0, 0, 0, 0, 0, 0, 0, 227, 8, 117, 2, 32, 32, 72, 0, 64, 76, 0, 0, 2, 0, 0, 0, 184, 8, 118, 2, 28, 55, 80, 0, 97, 35, 0, 0, 2, 0, 0, 0, 197, 8, 119, 2, 28, 28, 75, 0, 97, 97, 0, 0, 0, 0, 0, 0, 189, 8, 120, 2, 30, 28, 105, 0, 69, 0, 0, 0, 0, 0, 0, 0, 201, 8, 121, 2, 30, 30, 97, 0, 73, 0, 0, 0, 0, 0, 0, 0, 204, 8, 122, 2, 31, 31, 80, 0, 73, 35, 0, 0, 2, 0, 0, 0, 211, 8, 123, 2, 31, 31, 80, 0, 48, 0, 0, 0, 0, 0, 0, 0, 216, 8, 124, 2, 29, 29, 100, 0, 86, 0, 0, 0, 0, 0, 0, 0, 224, 8, 125, 2, 29, 28, 85, 0, 65, 58, 0, 0, 0, 0, 0, 0, 229, 8, 126, 2, 29, 29, 100, 0, 65, 64, 0, 0, 0, 0, 0, 0, 234, 8, 127, 2, 29, 29, 90, 0, 51, 58, 0, 0, 0, 0, 0, 0, 247, 8, 128, 2, 28, 28, 120, 0, 105, 58, 0, 0, 0, 0, 0, 0, 250, 8, 129, 2, 31, 31, 85, 0, 79, 58, 0, 0, 0, 0, 0, 0, 253, 8, 130, 2, 32, 32, 105, 0, 79, 0, 0, 0, 0, 0, 0, 0, 27, 9, 131, 2, 32, 32, 100, 0, 79, 64, 0, 0, 0, 0, 0, 0, 3, 9, 132, 2, 32, 28, 125, 0, 111, 64, 0, 0, 0, 0, 0, 0, 15, 9, 133, 2, 32, 28, 125, 0, 117, 58, 0, 0, 0, 0, 0, 0, 30, 9, 134, 2, 33, 33, 95, 0, 97, 85, 0, 0, 0, 0, 0, 0, 32, 9, 135, 2, 29, 32, 117, 0, 111, 85, 0, 0, 0, 0, 0, 0, 34, 9, 136, 2, 28, 33, 115, 0, 97, 73, 0, 0, 0, 0, 0, 0, 36, 9, 137, 2, 29, 31, 125, 0, 101, 73, 0, 0, 0, 0, 0, 0, 41, 9, 138, 2, 30, 31, 115, 0, 79, 73, 0, 0, 0, 0, 0, 0, 43, 9, 139, 2, 32, 31, 142, 0, 101, 64, 0, 0, 0, 0, 0, 0, 45, 9, 140, 2, 30, 28, 140, 0, 105, 64, 0, 0, 0, 0, 0, 0, 55, 9, 141, 2, 31, 28, 125, 0, 105, 64, 51, 0, 0, 0, 0, 0, 57, 9, 142, 2, 31, 28, 140, 0, 85, 64, 0, 0, 0, 0, 0, 0, 67, 9, 143, 2, 28, 28, 125, 0, 97, 73, 64, 0, 0, 0, 0, 0, 77, 9, 144, 2, 29, 28, 150, 0, 97, 73, 51, 0, 0, 0, 0, 0, 84, 9, 145, 2, 29, 28, 150, 0, 97, 85, 64, 0, 0, 0, 0, 0, 91, 9, 146, 2, 29, 28, 150, 0, 64, 47, 0, 0, 2, 0, 0, 0, 178, 8, 154, 2, 28, 28, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 4, 0, 0, 0, 0, 0, 0, 101, 110, 45, 115, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 137, 9, 13, 2, 28, 28, 70, 0, 114, 0, 0, 0, 128, 0, 128, 0, 74, 10, 34, 3, 0, 0, 0, 7, 97, 0, 0, 0, 0, 0, 0, 0, 157, 9, 35, 2, 29, 29, 100, 0, 105, 0, 0, 0, 0, 0, 0, 0, 188, 9, 37, 2, 31, 30, 75, 0, 114, 47, 0, 0, 0, 0, 0, 0, 72, 10, 46, 3, 0, 0, 0, 2, 73, 50, 0, 0, 2, 0, 0, 0, 185, 9, 113, 2, 28, 28, 55, 0, 51, 0, 0, 0, 2, 0, 0, 0, 140, 9, 114, 2, 28, 28, 70, 0, 64, 50, 0, 0, 2, 0, 0, 0, 148, 9, 115, 2, 28, 28, 60, 0, 64, 53, 0, 0, 2, 0, 0, 0, 152, 9, 116, 2, 28, 28, 70, 0, 85, 0, 0, 0, 0, 0, 0, 0, 199, 9, 117, 2, 33, 33, 70, 0, 64, 76, 0, 0, 2, 0, 0, 0, 65, 10, 118, 2, 28, 55, 80, 0, 97, 35, 0, 0, 2, 0, 0, 0, 164, 9, 119, 2, 28, 28, 70, 0, 97, 97, 0, 0, 0, 0, 0, 0, 169, 9, 120, 2, 29, 29, 110, 0, 69, 0, 0, 0, 0, 0, 0, 0, 174, 9, 121, 2, 30, 30, 85, 0, 73, 0, 0, 0, 0, 0, 0, 0, 177, 9, 122, 2, 28, 28, 55, 0, 48, 0, 0, 0, 0, 0, 0, 0, 193, 9, 124, 2, 32, 32, 100, 0, 86, 0, 0, 0, 0, 0, 0, 0, 196, 9, 125, 2, 29, 28, 70, 0, 65, 58, 0, 0, 0, 0, 0, 0, 203, 9, 126, 2, 29, 29, 110, 0, 65, 64, 0, 0, 0, 0, 0, 0, 213, 9, 127, 2, 29, 28, 125, 0, 51, 58, 0, 0, 0, 0, 0, 0, 219, 9, 128, 2, 30, 28, 105, 0, 105, 58, 0, 0, 0, 0, 0, 0, 225, 9, 129, 2, 31, 31, 65, 0, 79, 58, 0, 0, 0, 0, 0, 0, 234, 9, 130, 2, 32, 32, 100, 0, 79, 0, 0, 0, 0, 0, 0, 0, 250, 9, 131, 2, 32, 32, 75, 0, 79, 64, 0, 0, 0, 0, 0, 0, 240, 9, 132, 2, 32, 28, 115, 0, 111, 64, 0, 0, 0, 0, 0, 0, 245, 9, 133, 2, 32, 28, 115, 0, 117, 58, 0, 0, 0, 0, 0, 0, 253, 9, 134, 2, 33, 33, 80, 0, 97, 85, 0, 0, 0, 0, 0, 0, 9, 10, 135, 2, 29, 33, 100, 0, 111, 85, 0, 0, 0, 0, 0, 0, 14, 10, 136, 2, 32, 33, 95, 0, 97, 73, 0, 0, 0, 0, 0, 0, 19, 10, 137, 2, 29, 31, 95, 0, 101, 73, 0, 0, 0, 0, 0, 0, 29, 10, 138, 2, 30, 31, 95, 0, 79, 73, 0, 0, 0, 0, 0, 0, 34, 10, 139, 2, 32, 31, 105, 0, 101, 64, 0, 0, 0, 0, 0, 0, 36, 10, 140, 2, 30, 28, 110, 0, 105, 64, 51, 0, 0, 0, 0, 0, 41, 10, 142, 2, 31, 28, 110, 0, 85, 64, 0, 0, 0, 0, 0, 0, 46, 10, 143, 2, 33, 28, 90, 0, 97, 73, 64, 0, 0, 0, 0, 0, 60, 10, 144, 2, 29, 28, 135, 0, 97, 73, 51, 0, 0, 0, 0, 0, 63, 10, 145, 2, 29, 28, 140, 0, 97, 85, 64, 0, 0, 0, 0, 0, 57, 10, 146, 2, 29, 28, 135, 0, 97, 47, 0, 0, 0, 0, 0, 0, 161, 9, 154, 2, 29, 29, 80, 0, 97, 73, 50, 0, 0, 0, 0, 0, 27, 10, 155, 2, 29, 31, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 4, 0, 0, 0, 0, 0, 0, 101, 110, 45, 114, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 79, 10, 13, 2, 28, 28, 70, 0, 97, 0, 0, 0, 0, 0, 0, 0, 99, 10, 35, 2, 29, 29, 87, 0, 105, 0, 0, 0, 0, 0, 0, 0, 113, 10, 37, 2, 31, 31, 70, 0, 73, 50, 0, 0, 2, 0, 0, 0, 110, 10, 113, 2, 31, 31, 65, 0, 51, 0, 0, 0, 2, 0, 0, 0, 85, 10, 114, 2, 28, 28, 70, 0, 64, 50, 0, 0, 2, 0, 0, 0, 90, 10, 115, 2, 28, 28, 60, 0, 64, 53, 0, 0, 2, 0, 0, 0, 94, 10, 116, 2, 28, 28, 70, 0, 85, 0, 0, 0, 0, 0, 0, 0, 122, 10, 117, 2, 32, 32, 75, 0, 97, 35, 0, 0, 2, 0, 0, 0, 124, 10, 119, 2, 28, 28, 75, 0, 97, 97, 0, 0, 0, 0, 0, 0, 138, 10, 120, 2, 29, 29, 100, 0, 69, 0, 0, 0, 0, 0, 0, 0, 104, 10, 121, 2, 30, 30, 70, 0, 73, 0, 0, 0, 0, 0, 0, 0, 107, 10, 122, 2, 31, 31, 65, 0, 48, 0, 0, 0, 0, 0, 0, 0, 116, 10, 124, 2, 32, 32, 70, 0, 86, 0, 0, 0, 0, 0, 0, 0, 119, 10, 125, 2, 29, 28, 70, 0, 65, 58, 0, 0, 0, 0, 0, 0, 129, 10, 126, 2, 29, 29, 120, 0, 65, 64, 0, 0, 0, 0, 0, 0, 132, 10, 127, 2, 29, 29, 120, 0, 51, 58, 0, 0, 0, 0, 0, 0, 143, 10, 128, 2, 28, 28, 105, 0, 105, 58, 0, 0, 0, 0, 32, 0, 147, 10, 129, 2, 31, 31, 87, 0, 79, 58, 0, 0, 0, 0, 0, 0, 153, 10, 130, 2, 32, 32, 115, 0, 79, 0, 0, 0, 0, 0, 0, 0, 163, 10, 131, 2, 32, 32, 75, 0, 79, 64, 0, 0, 0, 0, 0, 0, 157, 10, 132, 2, 32, 28, 115, 0, 117, 58, 0, 0, 0, 0, 0, 0, 166, 10, 134, 2, 33, 33, 95, 0, 97, 85, 0, 0, 0, 0, 0, 0, 168, 10, 135, 2, 29, 33, 115, 0, 111, 85, 0, 0, 0, 0, 0, 0, 170, 10, 136, 2, 28, 33, 110, 0, 97, 73, 0, 0, 0, 0, 0, 0, 175, 10, 137, 2, 29, 31, 115, 0, 101, 73, 0, 0, 0, 0, 0, 0, 180, 10, 138, 2, 31, 31, 110, 0, 79, 73, 0, 0, 0, 0, 0, 0, 182, 10, 139, 2, 32, 31, 115, 0, 101, 64, 0, 0, 0, 0, 0, 0, 184, 10, 140, 2, 30, 28, 110, 0, 105, 64, 0, 0, 0, 0, 0, 0, 187, 10, 141, 2, 31, 28, 120, 0, 85, 64, 0, 0, 0, 0, 0, 0, 190, 10, 143, 2, 33, 28, 115, 0, 97, 73, 64, 0, 0, 0, 0, 0, 196, 10, 144, 2, 29, 28, 135, 0, 97, 73, 51, 0, 0, 0, 0, 0, 199, 10, 145, 2, 29, 28, 140, 0, 97, 85, 64, 0, 0, 0, 0, 0, 201, 10, 146, 2, 29, 28, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 4, 0, 0, 0, 0, 0, 0, 101, 110, 45, 119, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 208, 10, 35, 2, 29, 29, 80, 0, 105, 0, 0, 0, 0, 0, 0, 0, 221, 10, 37, 2, 31, 31, 110, 0, 78, 0, 0, 0, 16, 0, 8, 0, 204, 10, 68, 8, 0, 0, 0, 8, 73, 50, 0, 0, 2, 0, 0, 0, 214, 10, 113, 2, 31, 31, 70, 0, 85, 0, 0, 0, 0, 0, 0, 0, 232, 10, 117, 2, 33, 33, 75, 0, 97, 35, 0, 0, 2, 0, 0, 0, 235, 10, 119, 2, 28, 28, 70, 0, 97, 97, 0, 0, 0, 0, 0, 0, 248, 10, 120, 2, 29, 29, 80, 0, 69, 0, 0, 0, 0, 0, 0, 0, 211, 10, 121, 2, 30, 30, 75, 0, 73, 0, 0, 0, 0, 0, 0, 0, 214, 10, 122, 2, 31, 31, 70, 0, 48, 0, 0, 0, 0, 0, 0, 0, 224, 10, 124, 2, 32, 32, 70, 0, 86, 0, 0, 0, 0, 0, 0, 0, 227, 10, 125, 2, 32, 32, 70, 0, 65, 58, 0, 0, 0, 0, 0, 0, 239, 10, 126, 2, 29, 29, 120, 0, 65, 64, 0, 0, 0, 0, 0, 0, 242, 10, 127, 2, 29, 29, 120, 0, 51, 58, 0, 0, 0, 0, 0, 0, 252, 10, 128, 2, 28, 28, 125, 0, 105, 58, 0, 0, 0, 0, 0, 0, 0, 11, 129, 2, 30, 31, 110, 0, 79, 58, 0, 0, 0, 0, 0, 0, 5, 11, 130, 2, 32, 32, 120, 0, 79, 0, 0, 0, 0, 0, 0, 0, 15, 11, 131, 2, 32, 32, 75, 0, 79, 64, 0, 0, 0, 0, 0, 0, 9, 11, 132, 2, 32, 28, 120, 0, 117, 58, 0, 0, 0, 0, 0, 0, 18, 11, 134, 2, 33, 33, 100, 0, 97, 85, 0, 0, 0, 0, 0, 0, 23, 11, 135, 2, 29, 33, 115, 0, 111, 85, 0, 0, 0, 0, 0, 0, 28, 11, 136, 2, 28, 33, 110, 0, 97, 73, 0, 0, 0, 0, 0, 0, 33, 11, 137, 2, 32, 31, 120, 0, 101, 73, 0, 0, 0, 0, 0, 0, 38, 11, 138, 2, 28, 31, 120, 0, 79, 73, 0, 0, 0, 0, 0, 0, 43, 11, 139, 2, 32, 31, 115, 0, 101, 64, 0, 0, 0, 0, 0, 0, 48, 11, 140, 2, 28, 28, 120, 0, 105, 64, 0, 0, 0, 0, 0, 0, 54, 11, 141, 2, 31, 28, 120, 0, 85, 64, 0, 0, 0, 0, 0, 0, 57, 11, 143, 2, 33, 28, 100, 0, 97, 73, 64, 0, 0, 0, 0, 0, 60, 11, 144, 2, 29, 28, 140, 0, 97, 73, 51, 0, 0, 0, 0, 0, 63, 11, 145, 2, 29, 28, 140, 0, 97, 85, 64, 0, 0, 0, 0, 0, 65, 11, 146, 2, 29, 28, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 4, 0, 0, 0, 0, 0, 0, 101, 110, 45, 119, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 68, 11, 13, 2, 28, 28, 70, 0, 97, 0, 0, 0, 0, 0, 0, 0, 75, 11, 35, 2, 29, 29, 80, 0, 105, 0, 0, 0, 0, 0, 0, 0, 86, 11, 37, 2, 31, 31, 75, 0, 108, 0, 0, 0, 0, 0, 0, 0, 208, 0, 55, 3, 0, 0, 0, 7, 73, 50, 0, 0, 2, 0, 0, 0, 83, 11, 113, 2, 31, 31, 70, 0, 64, 50, 0, 0, 2, 0, 0, 0, 71, 11, 115, 2, 28, 28, 60, 0, 85, 0, 0, 0, 0, 0, 0, 0, 93, 11, 117, 2, 32, 32, 75, 0, 97, 35, 0, 0, 2, 0, 0, 0, 95, 11, 119, 2, 28, 28, 70, 0, 97, 97, 0, 0, 0, 0, 0, 0, 102, 11, 120, 2, 29, 29, 105, 0, 69, 0, 0, 0, 0, 0, 0, 0, 77, 11, 121, 2, 30, 30, 85, 0, 73, 0, 0, 0, 0, 0, 0, 0, 80, 11, 122, 2, 31, 31, 70, 0, 48, 0, 0, 0, 0, 0, 0, 0, 89, 11, 124, 2, 29, 29, 70, 0, 86, 0, 0, 0, 0, 0, 0, 0, 91, 11, 125, 2, 32, 32, 70, 0, 65, 58, 0, 0, 0, 0, 0, 0, 97, 11, 126, 2, 29, 28, 120, 0, 65, 64, 0, 0, 0, 0, 0, 0, 99, 11, 127, 2, 29, 28, 130, 0, 51, 58, 0, 0, 0, 0, 0, 0, 104, 11, 128, 2, 32, 32, 120, 0, 105, 58, 0, 0, 0, 0, 0, 0, 107, 11, 129, 2, 31, 31, 95, 0, 79, 58, 0, 0, 0, 0, 0, 0, 110, 11, 130, 2, 32, 32, 120, 0, 79, 0, 0, 0, 0, 0, 0, 0, 118, 11, 131, 2, 32, 32, 75, 0, 79, 64, 0, 0, 0, 0, 0, 0, 112, 11, 132, 2, 32, 28, 120, 0, 111, 64, 0, 0, 0, 0, 0, 0, 115, 11, 133, 2, 32, 28, 120, 0, 117, 58, 0, 0, 0, 0, 0, 0, 120, 11, 134, 2, 33, 33, 95, 0, 97, 85, 0, 0, 0, 0, 0, 0, 122, 11, 135, 2, 29, 33, 115, 0, 111, 85, 0, 0, 0, 0, 0, 0, 124, 11, 136, 2, 32, 32, 115, 0, 97, 73, 0, 0, 0, 0, 0, 0, 126, 11, 137, 2, 29, 31, 115, 0, 101, 73, 0, 0, 0, 0, 0, 0, 128, 11, 138, 2, 31, 31, 105, 0, 79, 73, 0, 0, 0, 0, 0, 0, 130, 11, 139, 2, 32, 31, 115, 0, 101, 64, 0, 0, 0, 0, 0, 0, 132, 11, 140, 2, 30, 28, 110, 0, 105, 64, 0, 0, 0, 0, 0, 0, 135, 11, 141, 2, 31, 29, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 0, 0, 97, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 9, 0, 0, 70, 0, 64, 0, 0, 0, 2, 0, 0, 0, 138, 11, 13, 2, 28, 28, 70, 0, 114, 0, 0, 0, 128, 0, 128, 0, 255, 11, 34, 3, 0, 0, 0, 6, 97, 0, 0, 0, 0, 0, 0, 0, 145, 11, 35, 2, 29, 29, 70, 0, 105, 0, 0, 0, 0, 0, 0, 0, 188, 11, 37, 2, 31, 31, 50, 0, 117, 0, 0, 0, 0, 0, 0, 0, 164, 11, 40, 2, 33, 33, 55, 0, 114, 47, 0, 0, 0, 0, 0, 0, 27, 12, 46, 3, 0, 0, 0, 7, 108, 0, 0, 0, 0, 0, 0, 0, 66, 7, 55, 3, 0, 0, 0, 7, 99, 0, 0, 0, 8, 2, 7, 0, 36, 12, 80, 4, 0, 81, 0, 2, 69, 0, 0, 0, 0, 0, 0, 0, 149, 11, 108, 2, 30, 30, 70, 0, 73, 0, 0, 0, 0, 0, 0, 0, 151, 11, 109, 2, 28, 28, 70, 0, 79, 0, 0, 0, 0, 0, 0, 0, 160, 11, 110, 2, 32, 32, 70, 0, 87, 0, 0, 0, 0, 0, 0, 0, 162, 11, 111, 2, 28, 28, 70, 0, 38, 0, 0, 0, 0, 0, 0, 0, 166, 11, 112, 2, 30, 30, 75, 0, 38, 58, 0, 0, 0, 0, 0, 0, 171, 11, 113, 2, 30, 30, 140, 0, 64, 76, 0, 0, 2, 0, 0, 0, 176, 11, 114, 2, 28, 55, 80, 0, 65, 58, 0, 0, 0, 0, 0, 0, 181, 11, 115, 2, 29, 29, 140, 0, 101, 64, 0, 0, 0, 0, 0, 0, 183, 11, 116, 2, 31, 28, 115, 0, 111, 64, 0, 0, 0, 0, 0, 0, 191, 11, 117, 2, 33, 28, 125, 0, 121, 0, 0, 0, 0, 0, 0, 0, 196, 11, 118, 2, 31, 31, 90, 0, 105, 117, 0, 0, 0, 0, 0, 0, 198, 11, 119, 2, 31, 33, 110, 0, 64, 85, 0, 0, 0, 0, 0, 0, 200, 11, 120, 2, 28, 33, 85, 0, 97, 73, 0, 0, 0, 0, 0, 0, 202, 11, 121, 2, 29, 31, 110, 0, 65, 73, 0, 0, 0, 0, 0, 0, 205, 11, 122, 2, 29, 31, 155, 0, 101, 73, 0, 0, 0, 0, 0, 0, 208, 11, 123, 2, 30, 31, 85, 0, 79, 73, 0, 0, 0, 0, 0, 0, 214, 11, 124, 2, 32, 31, 115, 0, 111, 73, 0, 0, 0, 0, 0, 0, 217, 11, 125, 2, 32, 31, 145, 0, 117, 73, 0, 0, 0, 0, 0, 0, 223, 11, 126, 2, 33, 31, 120, 0, 89, 121, 0, 0, 0, 0, 0, 0, 226, 11, 127, 2, 28, 31, 110, 0, 89, 64, 0, 0, 0, 0, 0, 0, 229, 11, 128, 2, 31, 28, 105, 0, 97, 85, 0, 0, 0, 0, 0, 0, 231, 11, 129, 2, 29, 33, 115, 0, 101, 58, 0, 0, 0, 0, 0, 0, 233, 11, 130, 2, 30, 30, 105, 0, 79, 58, 0, 0, 0, 0, 0, 0, 235, 11, 131, 2, 32, 32, 140, 0, 51, 58, 0, 0, 0, 0, 0, 0, 237, 11, 132, 2, 28, 28, 115, 0, 65, 126, 0, 0, 0, 0, 0, 0, 239, 11, 133, 2, 29, 29, 120, 0, 101, 126, 0, 0, 0, 0, 0, 0, 241, 11, 134, 2, 30, 30, 120, 0, 111, 126, 0, 0, 0, 0, 0, 0, 243, 11, 135, 2, 32, 32, 120, 0, 120, 50, 0, 0, 8, 0, 8, 0, 245, 11, 136, 6, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 0, 0, 99, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114, 0, 0, 0, 128, 0, 0, 0, 127, 12, 34, 3, 0, 0, 0, 6, 97, 0, 0, 0, 0, 0, 0, 0, 46, 12, 35, 2, 29, 29, 75, 0, 103, 0, 0, 0, 16, 0, 8, 0, 139, 12, 81, 5, 0, 49, 0, 5, 69, 0, 0, 0, 0, 0, 0, 0, 48, 12, 108, 2, 30, 30, 75, 0, 73, 0, 0, 0, 0, 0, 0, 0, 50, 12, 109, 2, 31, 31, 75, 0, 89, 0, 0, 0, 0, 0, 0, 0, 54, 12, 110, 2, 31, 31, 75, 0, 79, 0, 0, 0, 0, 0, 0, 0, 56, 12, 111, 2, 32, 32, 75, 0, 85, 0, 0, 0, 0, 0, 0, 0, 58, 12, 112, 2, 33, 33, 75, 0, 86, 0, 0, 0, 0, 0, 0, 0, 60, 12, 113, 2, 28, 28, 75, 0, 105, 58, 0, 0, 0, 0, 0, 0, 62, 12, 114, 2, 31, 31, 90, 0, 121, 58, 0, 0, 0, 0, 0, 0, 65, 12, 115, 2, 31, 31, 90, 0, 117, 58, 0, 0, 0, 0, 0, 0, 71, 12, 116, 2, 33, 33, 95, 0, 101, 58, 0, 0, 0, 0, 0, 0, 74, 12, 117, 2, 30, 30, 105, 0, 111, 58, 0, 0, 0, 0, 0, 0, 77, 12, 118, 2, 32, 32, 105, 0, 65, 58, 0, 0, 0, 0, 0, 0, 80, 12, 119, 2, 29, 29, 115, 0, 65, 89, 0, 0, 0, 0, 0, 0, 83, 12, 120, 2, 29, 31, 125, 0, 97, 73, 0, 0, 0, 0, 0, 0, 88, 12, 121, 2, 29, 31, 105, 0, 97, 89, 0, 0, 0, 0, 0, 0, 90, 12, 122, 2, 29, 31, 105, 0, 97, 85, 0, 0, 0, 0, 0, 0, 95, 12, 123, 2, 29, 33, 105, 0, 64, 73, 0, 0, 0, 0, 0, 0, 97, 12, 124, 2, 28, 31, 105, 0, 64, 89, 0, 0, 0, 0, 0, 0, 99, 12, 125, 2, 28, 31, 105, 0, 101, 85, 0, 0, 0, 0, 0, 0, 104, 12, 126, 2, 30, 33, 105, 0, 73, 117, 0, 0, 0, 0, 0, 0, 106, 12, 127, 2, 31, 33, 105, 0, 89, 117, 0, 0, 0, 0, 0, 0, 108, 12, 128, 2, 31, 33, 105, 0, 79, 73, 0, 0, 0, 0, 0, 0, 113, 12, 129, 2, 32, 31, 105, 0, 79, 89, 0, 0, 0, 0, 0, 0, 115, 12, 130, 2, 32, 31, 105, 0, 117, 73, 0, 0, 0, 0, 0, 0, 120, 12, 131, 2, 33, 31, 105, 0, 117, 89, 0, 0, 0, 0, 0, 0, 122, 12, 132, 2, 33, 31, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 1, 0, 0, 120, 208, 3, 0, 100, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 160, 12, 13, 2, 28, 28, 60, 0, 114, 0, 0, 0, 16, 0, 132, 0, 55, 13, 34, 5, 0, 0, 0, 6, 97, 0, 0, 0, 0, 0, 0, 0, 172, 12, 35, 2, 29, 29, 55, 0, 108, 47, 0, 0, 0, 0, 0, 0, 9, 13, 56, 3, 0, 0, 0, 7, 106, 0, 0, 0, 0, 2, 0, 0, 26, 13, 57, 3, 0, 0, 0, 7, 98, 0, 0, 0, 48, 0, 4, 0, 109, 13, 71, 7, 0, 48, 0, 0, 100, 0, 0, 0, 16, 0, 4, 0, 114, 13, 72, 5, 0, 47, 0, 0, 103, 0, 0, 0, 16, 0, 8, 0, 119, 13, 81, 5, 0, 49, 0, 0, 51, 0, 0, 0, 2, 0, 0, 16, 168, 12, 108, 2, 28, 28, 80, 0, 69, 0, 0, 0, 0, 0, 0, 0, 176, 12, 109, 2, 30, 30, 60, 0, 69, 50, 0, 0, 0, 0, 0, 0, 180, 12, 110, 2, 30, 30, 60, 0, 73, 0, 0, 0, 0, 0, 0, 0, 185, 12, 111, 2, 31, 31, 60, 0, 73, 58, 0, 0, 0, 0, 0, 0, 190, 12, 112, 2, 31, 31, 95, 0, 79, 0, 0, 0, 0, 0, 0, 0, 192, 12, 113, 2, 32, 32, 60, 0, 85, 0, 0, 0, 0, 0, 0, 0, 196, 12, 114, 2, 33, 33, 60, 0, 85, 82, 0, 0, 0, 0, 0, 16, 100, 13, 115, 2, 33, 28, 90, 0, 65, 58, 0, 0, 0, 0, 0, 0, 206, 12, 116, 2, 29, 29, 125, 0, 65, 0, 0, 0, 0, 0, 0, 0, 208, 12, 117, 2, 29, 29, 125, 0, 105, 58, 0, 0, 0, 0, 0, 0, 211, 12, 118, 2, 31, 31, 90, 0, 105, 50, 0, 0, 0, 0, 0, 0, 216, 12, 119, 2, 31, 31, 90, 0, 117, 58, 0, 0, 0, 0, 0, 0, 222, 12, 120, 2, 33, 33, 95, 0, 97, 85, 0, 0, 0, 0, 0, 0, 224, 12, 121, 2, 29, 33, 110, 0, 97, 73, 0, 0, 0, 0, 0, 0, 226, 12, 122, 2, 29, 31, 105, 0, 69, 73, 0, 0, 0, 0, 0, 0, 228, 12, 123, 2, 30, 31, 105, 0, 79, 89, 0, 0, 0, 0, 0, 0, 230, 12, 124, 2, 32, 31, 110, 0, 69, 58, 0, 0, 0, 0, 0, 0, 232, 12, 125, 2, 30, 30, 100, 0, 101, 58, 0, 0, 0, 0, 0, 0, 234, 12, 126, 2, 30, 30, 100, 0, 111, 58, 0, 0, 0, 0, 0, 0, 236, 12, 127, 2, 32, 32, 105, 0, 121, 58, 0, 0, 0, 0, 0, 0, 238, 12, 128, 2, 33, 33, 100, 0, 121, 0, 0, 0, 0, 0, 0, 0, 240, 12, 129, 2, 33, 33, 55, 0, 89, 58, 0, 0, 0, 0, 0, 0, 246, 12, 130, 2, 28, 28, 90, 0, 87, 0, 0, 0, 0, 0, 0, 0, 248, 12, 131, 2, 28, 28, 75, 0, 116, 115, 0, 0, 40, 0, 4, 0, 18, 6, 132, 4, 0, 0, 0, 2, 112, 70, 0, 0, 8, 0, 1, 0, 252, 12, 133, 4, 0, 0, 0, 2, 103, 35, 0, 0, 8, 2, 7, 0, 4, 13, 134, 6, 0, 0, 0, 3, 114, 50, 0, 0, 16, 0, 10, 0, 73, 13, 135, 7, 0, 0, 55, 6, 86, 35, 0, 0, 0, 0, 0, 0, 87, 13, 136, 3, 0, 0, 0, 7, 111, 85, 0, 0, 0, 0, 0, 0, 34, 9, 137, 2, 28, 33, 115, 0, 65, 126, 0, 0, 0, 0, 0, 0, 105, 13, 138, 2, 29, 29, 130, 0, 108, 50, 0, 0, 0, 0, 0, 0, 107, 13, 139, 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 0, 0, 101, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 124, 13, 35, 2, 29, 29, 90, 0, 101, 0, 0, 0, 0, 0, 0, 0, 126, 13, 36, 2, 30, 30, 85, 0, 105, 0, 0, 0, 0, 0, 0, 0, 128, 13, 37, 2, 31, 31, 85, 0, 111, 0, 0, 0, 0, 0, 0, 0, 131, 13, 39, 2, 32, 32, 85, 0, 117, 0, 0, 0, 0, 0, 0, 0, 136, 13, 40, 2, 33, 33, 85, 0, 97, 85, 0, 0, 0, 0, 0, 0, 138, 13, 108, 2, 29, 33, 125, 0, 101, 85, 0, 0, 0, 0, 0, 0, 140, 13, 109, 2, 30, 33, 125, 0, 97, 73, 0, 0, 0, 0, 0, 0, 142, 13, 110, 2, 29, 31, 125, 0, 101, 73, 0, 0, 0, 0, 0, 0, 144, 13, 111, 2, 30, 31, 125, 0, 111, 73, 0, 0, 0, 0, 0, 0, 146, 13, 112, 2, 32, 31, 125, 0, 117, 73, 0, 0, 0, 0, 0, 0, 148, 13, 113, 2, 33, 31, 125, 0, 116, 115, 0, 0, 40, 0, 4, 0, 18, 6, 114, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 14, 0, 0, 0, 0, 0, 0, 106, 98, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, 150, 13, 36, 2, 30, 30, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 110, 99, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 9, 0, 0, 150, 0, 101, 0, 0, 0, 0, 0, 0, 0, 152, 13, 36, 2, 30, 30, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 0, 0, 102, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 9, 0, 0, 80, 0, 114, 0, 0, 0, 128, 0, 0, 0, 120, 0, 34, 3, 0, 0, 0, 6, 97, 0, 0, 0, 0, 0, 0, 0, 165, 13, 35, 2, 29, 29, 85, 0, 101, 0, 0, 0, 0, 0, 0, 0, 161, 13, 36, 2, 30, 30, 75, 0, 105, 0, 0, 0, 0, 0, 0, 0, 154, 13, 37, 2, 31, 31, 70, 0, 111, 0, 0, 0, 0, 0, 0, 0, 169, 13, 39, 2, 32, 32, 77, 0, 117, 0, 0, 0, 0, 0, 0, 0, 173, 13, 40, 2, 33, 33, 70, 0, 116, 0, 0, 0, 8, 0, 3, 0, 7, 5, 47, 4, 0, 72, 0, 2, 112, 0, 0, 0, 8, 0, 1, 0, 201, 6, 48, 4, 0, 71, 0, 2, 107, 0, 0, 0, 8, 0, 8, 0, 4, 7, 49, 4, 0, 81, 0, 2, 82, 50, 0, 0, 128, 0, 0, 0, 217, 13, 52, 3, 0, 0, 0, 6, 100, 0, 0, 0, 16, 0, 3, 0, 244, 13, 72, 5, 0, 47, 0, 5, 118, 0, 0, 0, 16, 0, 2, 0, 231, 13, 84, 7, 0, 83, 0, 6, 104, 0, 0, 0, 8, 0, 12, 0, 15, 14, 107, 6, 0, 0, 0, 3, 73, 0, 0, 0, 0, 0, 0, 0, 158, 13, 108, 2, 31, 31, 70, 0, 38, 0, 0, 0, 0, 0, 0, 0, 163, 13, 109, 2, 29, 29, 75, 0, 97, 50, 0, 0, 0, 0, 0, 0, 167, 13, 110, 2, 29, 29, 85, 0, 89, 0, 0, 0, 0, 0, 0, 0, 171, 13, 111, 2, 28, 28, 77, 0, 117, 49, 0, 0, 0, 0, 0, 0, 175, 13, 112, 2, 33, 33, 70, 0, 85, 0, 0, 0, 0, 0, 0, 0, 177, 13, 113, 2, 33, 33, 70, 0, 121, 0, 0, 0, 0, 0, 0, 0, 179, 13, 114, 2, 33, 33, 75, 0, 97, 105, 0, 0, 0, 0, 32, 0, 181, 13, 115, 2, 29, 31, 155, 0, 38, 105, 0, 0, 0, 0, 32, 0, 183, 13, 116, 2, 29, 31, 145, 0, 111, 105, 0, 0, 0, 0, 32, 0, 185, 13, 117, 2, 32, 31, 140, 0, 101, 105, 0, 0, 0, 0, 32, 0, 187, 13, 118, 2, 30, 31, 140, 0, 89, 105, 0, 0, 0, 0, 32, 0, 189, 13, 119, 2, 28, 31, 135, 0, 117, 105, 0, 0, 0, 0, 32, 0, 191, 13, 120, 2, 33, 31, 135, 0, 121, 105, 0, 0, 0, 0, 32, 0, 193, 13, 121, 2, 33, 31, 135, 0, 97, 117, 0, 0, 0, 0, 32, 0, 195, 13, 122, 2, 29, 33, 150, 0, 111, 117, 0, 0, 0, 0, 32, 0, 197, 13, 123, 2, 32, 33, 140, 0, 101, 117, 0, 0, 0, 0, 32, 0, 199, 13, 124, 2, 30, 33, 140, 0, 105, 117, 0, 0, 0, 0, 32, 0, 201, 13, 125, 2, 31, 33, 140, 0, 38, 121, 0, 0, 0, 0, 32, 0, 203, 13, 126, 2, 29, 33, 140, 0, 101, 121, 0, 0, 0, 0, 32, 0, 205, 13, 127, 2, 30, 33, 140, 0, 89, 121, 0, 0, 0, 0, 32, 0, 207, 13, 128, 2, 28, 33, 135, 0, 105, 121, 0, 0, 0, 0, 32, 0, 209, 13, 129, 2, 31, 33, 130, 0, 117, 111, 0, 0, 0, 0, 32, 0, 211, 13, 130, 2, 33, 32, 140, 0, 105, 101, 0, 0, 0, 0, 32, 0, 213, 13, 131, 2, 31, 30, 140, 0, 121, 89, 0, 0, 0, 0, 32, 0, 215, 13, 132, 2, 33, 28, 140, 0, 115, 50, 0, 0, 40, 0, 4, 0, 142, 6, 133, 6, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 1, 0, 0, 0, 0, 0, 0, 101, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 9, 0, 0, 80, 0, 114, 0, 0, 0, 0, 0, 0, 0, 142, 14, 34, 3, 0, 0, 0, 2, 97, 0, 0, 0, 0, 0, 0, 0, 35, 14, 35, 2, 29, 29, 85, 0, 101, 0, 0, 0, 0, 0, 0, 0, 41, 14, 36, 2, 30, 30, 80, 0, 105, 0, 0, 0, 0, 0, 0, 0, 47, 14, 37, 2, 31, 31, 70, 0, 111, 0, 0, 0, 0, 0, 0, 0, 55, 14, 39, 2, 32, 32, 80, 0, 117, 0, 0, 0, 0, 0, 0, 0, 61, 14, 40, 2, 33, 33, 72, 0, 116, 0, 0, 0, 8, 0, 67, 0, 102, 14, 47, 4, 0, 72, 0, 5, 112, 0, 0, 0, 8, 0, 1, 0, 201, 6, 48, 4, 0, 71, 0, 2, 107, 0, 0, 0, 8, 0, 8, 0, 152, 14, 49, 4, 0, 81, 0, 5, 100, 0, 0, 0, 16, 0, 3, 0, 115, 14, 72, 5, 0, 47, 0, 5, 118, 0, 0, 0, 16, 0, 2, 0, 89, 14, 84, 7, 0, 83, 0, 6, 104, 0, 0, 0, 8, 0, 12, 0, 178, 14, 107, 6, 0, 0, 0, 3, 97, 58, 0, 0, 0, 0, 0, 0, 37, 14, 108, 2, 29, 29, 170, 0, 65, 49, 0, 0, 0, 0, 0, 0, 39, 14, 109, 2, 29, 29, 127, 0, 101, 58, 0, 0, 0, 0, 0, 0, 43, 14, 110, 2, 30, 30, 160, 0, 69, 49, 0, 0, 0, 0, 0, 0, 45, 14, 111, 2, 30, 30, 120, 0, 105, 58, 0, 0, 0, 0, 0, 0, 49, 14, 112, 2, 31, 31, 140, 0, 73, 49, 0, 0, 0, 0, 0, 0, 51, 14, 113, 2, 31, 31, 105, 0, 105, 49, 0, 0, 0, 0, 0, 0, 53, 14, 114, 2, 31, 31, 15, 0, 111, 58, 0, 0, 0, 0, 0, 0, 57, 14, 115, 2, 32, 32, 160, 0, 79, 49, 0, 0, 0, 0, 0, 0, 59, 14, 116, 2, 32, 32, 112, 0, 117, 58, 0, 0, 0, 0, 0, 0, 63, 14, 117, 2, 33, 33, 145, 0, 85, 49, 0, 0, 0, 0, 0, 0, 65, 14, 118, 2, 33, 33, 109, 0, 56, 0, 0, 0, 0, 0, 0, 0, 67, 14, 119, 2, 28, 28, 82, 0, 56, 58, 0, 0, 0, 0, 0, 0, 69, 14, 120, 2, 28, 28, 165, 0, 38, 0, 0, 0, 0, 0, 0, 0, 71, 14, 121, 2, 29, 29, 87, 0, 38, 58, 0, 0, 0, 0, 0, 0, 73, 14, 122, 2, 29, 29, 175, 0, 89, 0, 0, 0, 0, 0, 0, 0, 75, 14, 123, 2, 28, 28, 82, 0, 89, 58, 0, 0, 0, 0, 0, 0, 77, 14, 124, 2, 28, 28, 165, 0, 121, 0, 0, 0, 0, 0, 0, 0, 79, 14, 125, 2, 33, 33, 72, 0, 121, 58, 0, 0, 0, 0, 0, 0, 81, 14, 126, 2, 33, 33, 145, 0, 38, 105, 0, 0, 0, 0, 32, 0, 83, 14, 127, 2, 29, 31, 157, 0, 89, 105, 0, 0, 0, 0, 32, 0, 85, 14, 128, 2, 28, 31, 152, 0, 121, 105, 0, 0, 0, 0, 32, 0, 87, 14, 129, 2, 33, 31, 142, 0, 115, 50, 0, 0, 40, 0, 4, 0, 142, 6, 130, 6, 0, 0, 0, 3, 115, 94, 0, 0, 40, 2, 4, 0, 198, 14, 131, 6, 0, 88, 0, 3, 116, 94, 0, 0, 8, 2, 7, 0, 208, 14, 132, 4, 0, 133, 0, 5, 100, 94, 0, 0, 16, 2, 4, 0, 221, 14, 133, 5, 0, 132, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 1, 0, 0, 176, 54, 4, 0, 102, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 9, 0, 0, 20, 0, 64, 0, 0, 0, 0, 0, 0, 0, 2, 16, 13, 2, 28, 28, 85, 0, 64, 45, 0, 0, 2, 0, 0, 0, 4, 16, 14, 2, 28, 28, 65, 0, 114, 0, 0, 0, 16, 0, 138, 1, 79, 15, 34, 7, 109, 0, 0, 7, 97, 0, 0, 0, 0, 0, 0, 0, 6, 16, 35, 2, 29, 29, 90, 0, 101, 0, 0, 0, 0, 0, 0, 0, 14, 16, 36, 2, 30, 30, 90, 0, 105, 0, 0, 0, 0, 2, 0, 0, 34, 16, 37, 2, 31, 31, 90, 0, 111, 0, 0, 0, 0, 0, 0, 0, 73, 16, 39, 2, 32, 32, 90, 0, 117, 0, 0, 0, 0, 0, 0, 0, 96, 16, 40, 2, 33, 33, 90, 0, 114, 47, 0, 0, 16, 0, 138, 0, 104, 15, 46, 7, 109, 0, 0, 7, 116, 0, 0, 0, 8, 0, 4, 0, 195, 17, 47, 4, 110, 72, 0, 2, 112, 0, 0, 0, 8, 0, 1, 0, 126, 17, 48, 4, 110, 71, 0, 2, 107, 0, 0, 0, 8, 0, 8, 0, 56, 17, 49, 4, 110, 81, 25, 2, 110, 0, 0, 0, 16, 0, 4, 0, 81, 17, 50, 8, 0, 0, 0, 4, 108, 0, 0, 0, 0, 0, 0, 0, 171, 15, 55, 3, 108, 0, 0, 7, 108, 47, 0, 0, 0, 0, 5, 0, 212, 15, 56, 3, 108, 0, 0, 7, 119, 0, 0, 0, 0, 0, 0, 0, 122, 16, 58, 2, 33, 33, 90, 0, 108, 47, 50, 0, 0, 0, 0, 0, 238, 15, 59, 3, 108, 0, 0, 0, 98, 0, 0, 0, 16, 0, 1, 0, 187, 16, 71, 5, 110, 48, 0, 6, 100, 0, 0, 0, 16, 0, 4, 0, 239, 16, 72, 5, 110, 47, 0, 5, 103, 0, 0, 0, 16, 0, 8, 0, 24, 17, 81, 5, 110, 49, 0, 5, 102, 0, 0, 0, 8, 0, 2, 0, 15, 17, 83, 6, 110, 84, 0, 3, 118, 0, 0, 0, 16, 0, 2, 0, 236, 17, 84, 7, 110, 83, 45, 6, 122, 0, 0, 0, 48, 0, 4, 0, 13, 18, 88, 7, 0, 89, 0, 6, 115, 0, 0, 0, 40, 0, 4, 0, 162, 17, 89, 6, 0, 88, 0, 3, 83, 0, 0, 0, 40, 0, 6, 0, 180, 17, 91, 6, 110, 90, 0, 3, 35, 108, 0, 0, 0, 0, 0, 0, 0, 0, 108, 9, 0, 0, 0, 0, 35, 114, 0, 0, 0, 0, 0, 0, 0, 0, 109, 9, 0, 0, 0, 0, 35, 99, 70, 82, 0, 0, 0, 0, 0, 0, 110, 9, 0, 0, 0, 0, 121, 0, 0, 0, 0, 0, 0, 0, 105, 16, 111, 2, 33, 33, 90, 0, 69, 0, 0, 0, 0, 0, 0, 0, 26, 16, 112, 2, 30, 30, 90, 0, 65, 126, 0, 0, 0, 0, 0, 0, 176, 16, 113, 2, 29, 29, 95, 0, 69, 126, 0, 0, 0, 0, 0, 0, 178, 16, 114, 2, 30, 30, 95, 0, 87, 126, 0, 0, 0, 0, 0, 0, 185, 16, 115, 2, 28, 28, 95, 0, 79, 126, 0, 0, 0, 0, 0, 0, 183, 16, 116, 2, 32, 32, 95, 0, 87, 0, 0, 0, 0, 0, 0, 0, 116, 16, 117, 2, 28, 28, 90, 0, 106, 47, 0, 0, 0, 0, 0, 0, 58, 16, 118, 2, 31, 31, 40, 0, 114, 47, 50, 0, 0, 0, 138, 1, 148, 15, 119, 3, 109, 0, 0, 0, 114, 50, 0, 0, 16, 0, 138, 0, 97, 15, 120, 7, 109, 0, 0, 0, 97, 45, 0, 0, 2, 0, 0, 0, 12, 16, 121, 2, 29, 29, 65, 0, 97, 35, 0, 0, 2, 0, 0, 0, 160, 7, 122, 2, 28, 28, 75, 0, 101, 45, 0, 0, 2, 0, 0, 0, 24, 16, 123, 2, 30, 30, 65, 0, 69, 45, 0, 0, 2, 0, 0, 0, 32, 16, 124, 2, 30, 30, 65, 0, 73, 0, 0, 0, 0, 0, 0, 0, 172, 7, 125, 2, 31, 31, 65, 0, 73, 50, 0, 0, 2, 0, 0, 0, 175, 7, 126, 2, 31, 31, 65, 0, 79, 0, 0, 0, 0, 0, 0, 0, 83, 16, 127, 2, 32, 32, 85, 0, 111, 85, 0, 0, 0, 0, 0, 0, 240, 7, 128, 2, 28, 33, 110, 0, 117, 58, 0, 0, 0, 0, 0, 0, 103, 16, 129, 2, 33, 33, 120, 0, 121, 45, 0, 0, 2, 0, 0, 0, 114, 16, 130, 2, 33, 33, 65, 0, 87, 50, 0, 0, 2, 0, 0, 0, 118, 16, 131, 2, 28, 28, 50, 0, 89, 0, 0, 0, 0, 0, 0, 0, 120, 16, 132, 2, 28, 28, 85, 0, 119, 47, 0, 0, 0, 0, 0, 0, 141, 16, 133, 3, 0, 0, 0, 7, 110, 50, 0, 0, 16, 0, 4, 0, 120, 17, 134, 8, 0, 0, 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, 96, 16, 135, 2, 33, 33, 90, 0, 121, 34, 0, 0, 0, 0, 0, 0, 105, 16, 136, 2, 33, 33, 90, 0, 69, 58, 0, 0, 0, 0, 0, 0, 26, 16, 137, 2, 30, 30, 90, 0, 65, 0, 0, 0, 0, 0, 0, 0, 6, 16, 138, 2, 29, 29, 90, 0, 112, 50, 0, 0, 8, 0, 1, 0, 150, 17, 139, 4, 0, 0, 0, 2, 116, 50, 0, 0, 8, 0, 4, 0, 213, 17, 140, 4, 0, 0, 0, 2, 116, 51, 0, 0, 8, 0, 4, 0, 228, 17, 141, 4, 0, 0, 0, 2, 86, 0, 0, 0, 0, 0, 0, 0, 10, 18, 142, 2, 29, 28, 70, 0, 122, 50, 0, 0, 48, 0, 4, 0, 33, 18, 143, 7, 0, 0, 0, 0, 122, 51, 0, 0, 48, 0, 4, 0, 44, 18, 144, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 19, 0, 0, 0, 0, 0, 0, 102, 114, 45, 99, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 9, 0, 0, 35, 0, 117, 0, 0, 0, 0, 0, 0, 0, 55, 18, 40, 2, 33, 33, 87, 0, 82, 0, 0, 0, 128, 0, 0, 0, 70, 18, 51, 3, 0, 0, 0, 7, 69, 0, 0, 0, 0, 0, 0, 0, 53, 18, 112, 2, 30, 30, 82, 0, 69, 126, 0, 0, 0, 0, 0, 0, 57, 18, 114, 2, 30, 30, 96, 0, 73, 0, 0, 0, 0, 0, 0, 0, 59, 18, 125, 2, 31, 31, 79, 0, 85, 0, 0, 0, 0, 0, 0, 0, 62, 18, 135, 2, 33, 33, 75, 0, 121, 34, 0, 0, 0, 0, 0, 0, 64, 18, 136, 2, 33, 33, 70, 0, 69, 58, 0, 0, 0, 0, 0, 0, 66, 18, 137, 2, 28, 30, 115, 0, 65, 0, 0, 0, 0, 0, 0, 0, 68, 18, 138, 2, 29, 29, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 0, 0, 104, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 9, 0, 0, 50, 0, 64, 0, 0, 0, 0, 0, 0, 16, 80, 18, 13, 2, 28, 28, 65, 0, 97, 0, 0, 0, 0, 0, 32, 0, 147, 18, 35, 2, 29, 29, 65, 0, 101, 0, 0, 0, 0, 0, 0, 0, 137, 18, 36, 2, 30, 30, 65, 0, 105, 0, 0, 0, 0, 0, 0, 0, 129, 18, 37, 2, 31, 31, 115, 0, 111, 0, 0, 0, 0, 0, 0, 0, 151, 18, 39, 2, 32, 32, 65, 0, 116, 0, 0, 0, 8, 0, 3, 0, 7, 5, 47, 4, 0, 72, 0, 2, 112, 0, 0, 0, 8, 0, 1, 0, 52, 6, 48, 4, 0, 0, 0, 2, 107, 0, 0, 0, 8, 0, 8, 0, 113, 6, 49, 4, 0, 81, 0, 2, 98, 0, 0, 0, 16, 0, 1, 0, 193, 2, 71, 5, 0, 0, 0, 5, 100, 0, 0, 0, 16, 0, 3, 0, 33, 3, 72, 5, 0, 47, 0, 5, 74, 0, 0, 0, 48, 2, 7, 0, 117, 3, 79, 5, 0, 0, 0, 5, 99, 0, 0, 0, 8, 2, 7, 0, 41, 5, 80, 4, 0, 0, 0, 2, 103, 0, 0, 0, 16, 0, 8, 0, 150, 3, 81, 5, 0, 49, 0, 5, 118, 0, 0, 0, 16, 0, 2, 0, 238, 3, 84, 7, 0, 83, 0, 6, 72, 0, 0, 0, 8, 0, 12, 0, 252, 5, 108, 6, 0, 0, 0, 3, 86, 0, 0, 0, 0, 0, 0, 16, 86, 18, 109, 2, 28, 28, 65, 0, 64, 51, 0, 0, 0, 0, 0, 16, 123, 18, 110, 2, 28, 28, 65, 0, 64, 50, 0, 0, 0, 0, 0, 16, 121, 18, 111, 2, 28, 28, 65, 0, 105, 58, 0, 0, 0, 0, 32, 0, 126, 18, 112, 2, 31, 31, 115, 0, 73, 0, 0, 0, 0, 0, 0, 0, 132, 18, 113, 2, 31, 31, 50, 0, 101, 58, 0, 0, 0, 0, 32, 0, 135, 18, 114, 2, 30, 30, 110, 0, 69, 58, 0, 0, 0, 0, 32, 0, 139, 18, 115, 2, 30, 30, 110, 0, 69, 0, 0, 0, 0, 0, 0, 0, 141, 18, 116, 2, 30, 30, 65, 0, 38, 58, 0, 0, 0, 0, 32, 0, 143, 18, 117, 2, 29, 29, 110, 0, 97, 58, 0, 0, 0, 0, 32, 0, 145, 18, 118, 2, 29, 29, 115, 0, 111, 58, 0, 0, 0, 0, 32, 0, 149, 18, 119, 2, 32, 32, 110, 0, 79, 58, 0, 0, 0, 0, 32, 0, 153, 18, 120, 2, 32, 32, 105, 0, 79, 0, 0, 0, 0, 0, 0, 0, 155, 18, 121, 2, 32, 32, 65, 0, 85, 0, 0, 0, 0, 0, 0, 0, 157, 18, 122, 2, 33, 33, 60, 0, 117, 58, 0, 0, 0, 0, 32, 0, 159, 18, 123, 2, 33, 33, 115, 0, 105, 126, 0, 0, 0, 0, 32, 0, 161, 18, 124, 2, 31, 31, 110, 0, 73, 126, 0, 0, 0, 0, 32, 0, 163, 18, 125, 2, 31, 31, 85, 0, 101, 126, 0, 0, 0, 0, 32, 0, 165, 18, 126, 2, 30, 30, 110, 0, 69, 126, 0, 0, 0, 0, 32, 0, 167, 18, 127, 2, 30, 30, 115, 0, 97, 126, 0, 0, 0, 0, 32, 0, 169, 18, 128, 2, 29, 29, 125, 0, 86, 126, 0, 0, 0, 0, 32, 0, 171, 18, 129, 2, 28, 28, 125, 0, 79, 126, 0, 0, 0, 0, 32, 0, 173, 18, 130, 2, 32, 32, 115, 0, 111, 126, 0, 0, 0, 0, 32, 0, 175, 18, 131, 2, 32, 32, 110, 0, 85, 126, 0, 0, 0, 0, 0, 0, 177, 18, 132, 2, 33, 33, 85, 0, 117, 126, 0, 0, 0, 0, 32, 0, 179, 18, 133, 2, 33, 33, 115, 0, 97, 73, 0, 0, 0, 0, 32, 0, 181, 18, 134, 2, 28, 31, 120, 0, 97, 85, 0, 0, 0, 0, 32, 0, 183, 18, 135, 2, 29, 33, 120, 0, 112, 104, 0, 0, 8, 0, 1, 0, 71, 6, 136, 4, 0, 0, 0, 2, 98, 104, 0, 0, 16, 0, 1, 0, 185, 18, 137, 5, 0, 136, 0, 5, 116, 104, 0, 0, 8, 0, 3, 0, 200, 18, 138, 4, 0, 72, 0, 2, 100, 104, 0, 0, 16, 0, 3, 0, 213, 18, 139, 5, 0, 138, 0, 5, 116, 46, 0, 0, 8, 0, 5, 0, 228, 18, 140, 4, 0, 141, 0, 2, 100, 46, 0, 0, 16, 0, 5, 0, 253, 18, 141, 5, 0, 140, 0, 5, 116, 104, 46, 0, 8, 0, 5, 0, 240, 18, 142, 4, 0, 143, 0, 2, 100, 104, 46, 0, 16, 0, 5, 0, 20, 19, 143, 5, 0, 142, 0, 5, 99, 104, 0, 0, 40, 2, 7, 0, 38, 19, 144, 4, 0, 77, 0, 2, 74, 104, 0, 0, 48, 0, 7, 0, 43, 19, 145, 5, 0, 144, 0, 5, 107, 104, 0, 0, 8, 0, 8, 0, 126, 6, 146, 4, 0, 147, 0, 2, 103, 104, 0, 0, 16, 0, 3, 0, 58, 19, 147, 5, 0, 146, 0, 5, 35, 88, 50, 0, 40, 0, 4, 0, 79, 19, 148, 6, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 21, 0, 0, 0, 0, 0, 0, 116, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 9, 0, 0, 25, 0, 64, 0, 0, 0, 0, 0, 0, 0, 81, 19, 13, 2, 28, 28, 65, 0, 97, 0, 0, 0, 0, 0, 0, 0, 83, 19, 35, 2, 29, 29, 65, 0, 101, 0, 0, 0, 0, 0, 0, 0, 100, 19, 36, 2, 30, 30, 65, 0, 105, 0, 0, 0, 0, 0, 0, 0, 104, 19, 37, 2, 31, 31, 65, 0, 111, 0, 0, 0, 0, 0, 0, 0, 112, 19, 39, 2, 32, 32, 65, 0, 117, 0, 0, 0, 0, 0, 0, 0, 116, 19, 40, 2, 33, 33, 55, 0, 116, 0, 0, 0, 8, 0, 3, 0, 220, 6, 47, 4, 0, 0, 0, 2, 118, 0, 0, 0, 16, 0, 2, 0, 201, 3, 84, 7, 0, 0, 0, 6, 86, 0, 0, 0, 0, 0, 0, 0, 86, 19, 109, 2, 28, 28, 65, 0, 105, 58, 0, 0, 0, 0, 0, 0, 110, 19, 112, 2, 31, 31, 135, 0, 101, 58, 0, 0, 0, 0, 0, 0, 102, 19, 114, 2, 30, 30, 125, 0, 97, 58, 0, 0, 0, 0, 0, 0, 98, 19, 118, 2, 29, 29, 150, 0, 111, 58, 0, 0, 0, 0, 0, 0, 114, 19, 119, 2, 32, 32, 150, 0, 85, 0, 0, 0, 0, 0, 0, 0, 121, 19, 122, 2, 33, 33, 55, 0, 117, 58, 0, 0, 0, 0, 0, 0, 125, 19, 123, 2, 33, 33, 140, 0, 97, 73, 0, 0, 0, 0, 0, 0, 135, 19, 134, 2, 29, 31, 140, 0, 97, 85, 0, 0, 0, 0, 0, 0, 137, 19, 135, 2, 29, 33, 135, 0, 86, 35, 0, 0, 0, 0, 0, 0, 93, 19, 149, 2, 28, 28, 65, 0, 35, 0, 0, 0, 0, 0, 0, 0, 139, 19, 150, 9, 0, 0, 0, 0, 117, 50, 0, 0, 0, 0, 0, 0, 119, 19, 151, 2, 33, 33, 55, 0, 85, 58, 0, 0, 0, 0, 0, 0, 131, 19, 152, 2, 33, 33, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 21, 0, 0, 0, 0, 0, 0, 107, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 141, 19, 13, 2, 29, 29, 65, 0, 114, 0, 0, 0, 0, 0, 128, 0, 72, 0, 34, 3, 0, 0, 0, 7, 97, 0, 0, 0, 0, 0, 32, 0, 143, 19, 35, 2, 28, 29, 65, 0, 101, 0, 0, 0, 0, 0, 0, 0, 149, 19, 36, 2, 30, 30, 65, 0, 105, 0, 0, 0, 0, 0, 0, 0, 153, 19, 37, 2, 31, 31, 65, 0, 111, 0, 0, 0, 0, 0, 0, 0, 157, 19, 39, 2, 32, 32, 65, 0, 117, 0, 0, 0, 0, 0, 0, 0, 161, 19, 40, 2, 33, 33, 55, 0, 100, 0, 0, 0, 16, 0, 3, 0, 169, 19, 72, 5, 0, 74, 0, 5, 118, 0, 0, 0, 16, 0, 2, 0, 201, 3, 84, 7, 0, 0, 0, 6, 105, 58, 0, 0, 0, 0, 0, 0, 155, 19, 112, 2, 31, 31, 135, 0, 101, 58, 0, 0, 0, 0, 0, 0, 151, 19, 114, 2, 30, 30, 135, 0, 97, 58, 0, 0, 0, 0, 0, 0, 147, 19, 118, 2, 29, 29, 150, 0, 111, 58, 0, 0, 0, 0, 0, 0, 159, 19, 119, 2, 32, 32, 150, 0, 117, 58, 0, 0, 0, 0, 0, 0, 163, 19, 123, 2, 33, 33, 140, 0, 97, 73, 0, 0, 0, 0, 32, 0, 165, 19, 134, 2, 29, 31, 140, 0, 97, 85, 0, 0, 0, 0, 32, 0, 167, 19, 135, 2, 29, 33, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 0, 0, 0, 0, 0, 0, 109, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 196, 19, 13, 2, 28, 28, 65, 0, 114, 0, 0, 0, 16, 64, 132, 0, 137, 2, 34, 5, 0, 0, 0, 3, 97, 0, 0, 0, 0, 0, 0, 0, 202, 19, 35, 2, 29, 29, 65, 0, 101, 0, 0, 0, 0, 0, 0, 0, 221, 19, 36, 2, 30, 30, 65, 0, 105, 0, 0, 0, 0, 0, 0, 0, 225, 19, 37, 2, 31, 31, 65, 0, 111, 0, 0, 0, 0, 0, 0, 0, 231, 19, 39, 2, 32, 32, 65, 0, 117, 0, 0, 0, 0, 0, 0, 0, 235, 19, 40, 2, 33, 33, 55, 0, 82, 0, 0, 0, 128, 0, 0, 0, 138, 0, 51, 3, 0, 0, 0, 6, 118, 0, 0, 0, 16, 0, 2, 0, 201, 3, 84, 7, 0, 0, 0, 6, 105, 58, 0, 0, 0, 0, 32, 0, 229, 19, 112, 2, 31, 31, 135, 0, 73, 0, 0, 0, 0, 0, 0, 0, 227, 19, 113, 2, 31, 31, 65, 0, 101, 58, 0, 0, 0, 0, 32, 0, 223, 19, 114, 2, 30, 30, 135, 0, 97, 58, 0, 0, 0, 0, 32, 0, 219, 19, 118, 2, 29, 29, 150, 0, 111, 58, 0, 0, 0, 0, 32, 0, 233, 19, 119, 2, 32, 32, 150, 0, 117, 58, 0, 0, 0, 0, 32, 0, 237, 19, 123, 2, 33, 33, 140, 0, 97, 73, 0, 0, 0, 0, 32, 0, 239, 19, 134, 2, 29, 31, 140, 0, 97, 85, 0, 0, 0, 0, 32, 0, 241, 19, 135, 2, 29, 33, 135, 0, 121, 0, 0, 0, 2, 0, 0, 0, 198, 19, 149, 2, 28, 28, 40, 0, 97, 35, 0, 0, 0, 0, 0, 0, 217, 19, 150, 2, 29, 29, 90, 0, 100, 35, 0, 0, 16, 0, 4, 0, 12, 3, 151, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 0, 0, 104, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105, 0, 0, 0, 0, 0, 0, 0, 247, 19, 37, 2, 31, 31, 70, 0, 111, 0, 0, 0, 0, 0, 0, 0, 250, 19, 39, 2, 32, 32, 65, 0, 117, 0, 0, 0, 0, 0, 0, 0, 252, 19, 40, 2, 33, 33, 65, 0, 116, 0, 0, 0, 8, 0, 3, 0, 26, 20, 47, 4, 0, 72, 0, 2, 112, 0, 0, 0, 8, 0, 1, 0, 52, 6, 48, 4, 0, 71, 0, 2, 107, 0, 0, 0, 8, 0, 8, 0, 113, 6, 49, 4, 0, 81, 0, 2, 108, 0, 0, 0, 0, 0, 0, 0, 71, 20, 55, 3, 0, 0, 0, 7, 100, 0, 0, 0, 16, 0, 3, 0, 44, 20, 72, 5, 0, 47, 0, 5, 99, 0, 0, 0, 40, 0, 7, 0, 100, 6, 80, 4, 0, 79, 0, 2, 65, 0, 0, 0, 0, 0, 0, 0, 243, 19, 108, 2, 32, 32, 70, 0, 69, 0, 0, 0, 0, 0, 0, 0, 245, 19, 109, 2, 30, 30, 70, 0, 89, 0, 0, 0, 0, 0, 0, 0, 254, 19, 110, 2, 28, 28, 65, 0, 121, 0, 0, 0, 0, 0, 0, 0, 0, 20, 111, 2, 33, 33, 65, 0, 105, 58, 0, 0, 0, 0, 0, 0, 2, 20, 112, 2, 31, 31, 110, 0, 101, 58, 0, 0, 0, 0, 0, 0, 4, 20, 113, 2, 30, 30, 120, 0, 97, 58, 0, 0, 0, 0, 0, 0, 6, 20, 114, 2, 29, 29, 135, 0, 111, 58, 0, 0, 0, 0, 0, 0, 8, 20, 115, 2, 32, 32, 130, 0, 117, 58, 0, 0, 0, 0, 0, 0, 10, 20, 116, 2, 33, 33, 120, 0, 121, 58, 0, 0, 0, 0, 0, 0, 12, 20, 117, 2, 33, 33, 120, 0, 89, 58, 0, 0, 0, 0, 0, 0, 14, 20, 118, 2, 28, 28, 130, 0, 116, 115, 0, 0, 40, 0, 4, 0, 16, 20, 119, 4, 0, 0, 0, 2, 100, 122, 0, 0, 48, 0, 4, 0, 31, 6, 120, 5, 0, 119, 0, 5, 116, 50, 0, 0, 8, 0, 3, 0, 39, 20, 121, 4, 0, 0, 0, 2, 115, 50, 0, 0, 40, 0, 4, 0, 142, 6, 122, 6, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 1, 0, 0, 0, 0, 0, 0, 108, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 90, 20, 13, 2, 28, 28, 60, 0, 114, 0, 0, 0, 192, 0, 132, 0, 161, 20, 34, 3, 0, 0, 40, 0, 97, 0, 0, 0, 0, 0, 0, 0, 92, 20, 35, 2, 29, 29, 60, 0, 101, 0, 0, 0, 0, 0, 0, 0, 98, 20, 36, 2, 30, 30, 90, 0, 105, 0, 0, 0, 0, 0, 0, 0, 114, 20, 37, 2, 31, 31, 50, 0, 111, 0, 0, 0, 0, 0, 0, 0, 121, 20, 39, 2, 32, 32, 60, 0, 117, 0, 0, 0, 0, 0, 0, 0, 129, 20, 40, 2, 33, 33, 55, 0, 116, 0, 0, 0, 8, 0, 3, 0, 189, 20, 47, 4, 0, 72, 0, 2, 108, 0, 0, 0, 2, 0, 0, 0, 45, 21, 55, 2, 28, 28, 150, 0, 119, 0, 0, 0, 0, 0, 0, 0, 133, 20, 58, 2, 33, 33, 90, 0, 100, 0, 0, 0, 16, 0, 3, 0, 215, 20, 72, 5, 0, 47, 0, 5, 100, 90, 59, 0, 48, 2, 7, 0, 169, 20, 77, 5, 0, 78, 0, 5, 116, 83, 59, 0, 40, 2, 7, 0, 183, 20, 78, 4, 0, 77, 0, 2, 65, 0, 0, 0, 0, 0, 0, 0, 94, 20, 108, 2, 29, 29, 40, 0, 97, 58, 0, 0, 0, 0, 32, 0, 96, 20, 109, 2, 29, 29, 175, 0, 69, 0, 0, 0, 0, 0, 0, 0, 103, 20, 110, 2, 30, 30, 40, 0, 101, 58, 0, 0, 0, 0, 0, 0, 108, 20, 111, 2, 30, 30, 150, 0, 101, 101, 0, 0, 0, 0, 32, 0, 110, 20, 112, 2, 30, 30, 130, 0, 101, 65, 0, 0, 0, 0, 32, 0, 112, 20, 113, 2, 30, 29, 145, 0, 73, 0, 0, 0, 0, 0, 0, 0, 117, 20, 114, 2, 31, 31, 35, 0, 105, 58, 0, 0, 0, 0, 0, 0, 119, 20, 115, 2, 31, 31, 150, 0, 79, 0, 0, 0, 0, 0, 0, 0, 123, 20, 116, 2, 32, 32, 35, 0, 111, 58, 0, 0, 0, 0, 0, 0, 125, 20, 117, 2, 32, 32, 150, 0, 85, 0, 0, 0, 0, 0, 0, 0, 127, 20, 118, 2, 33, 33, 35, 0, 117, 58, 0, 0, 0, 0, 0, 0, 131, 20, 119, 2, 33, 33, 165, 0, 87, 0, 0, 0, 0, 0, 0, 0, 135, 20, 120, 2, 33, 33, 50, 0, 97, 105, 0, 0, 0, 0, 32, 0, 137, 20, 121, 2, 29, 31, 155, 0, 101, 105, 0, 0, 0, 0, 32, 0, 139, 20, 122, 2, 30, 31, 150, 0, 97, 117, 0, 0, 0, 0, 32, 0, 141, 20, 123, 2, 29, 33, 150, 0, 117, 111, 0, 0, 0, 0, 32, 0, 143, 20, 124, 2, 33, 29, 150, 0, 111, 105, 0, 0, 0, 0, 32, 0, 145, 20, 125, 2, 32, 31, 145, 0, 117, 105, 0, 0, 0, 0, 32, 0, 147, 20, 126, 2, 33, 31, 145, 0, 105, 101, 0, 0, 0, 0, 32, 0, 149, 20, 127, 2, 31, 30, 145, 0, 97, 85, 0, 0, 0, 0, 0, 0, 151, 20, 128, 2, 29, 33, 135, 0, 101, 85, 0, 0, 0, 0, 0, 0, 153, 20, 129, 2, 30, 33, 130, 0, 111, 85, 0, 0, 0, 0, 0, 0, 155, 20, 130, 2, 32, 33, 130, 0, 97, 73, 0, 0, 0, 0, 0, 0, 157, 20, 131, 2, 29, 31, 135, 0, 101, 73, 0, 0, 0, 0, 0, 0, 159, 20, 132, 2, 30, 31, 130, 0, 116, 115, 0, 0, 40, 0, 4, 0, 18, 6, 133, 4, 0, 0, 0, 2, 116, 59, 0, 0, 8, 2, 7, 0, 202, 20, 134, 4, 0, 135, 0, 2, 100, 59, 0, 0, 16, 2, 4, 0, 242, 20, 135, 5, 0, 134, 0, 5, 110, 59, 0, 0, 0, 2, 0, 0, 13, 21, 136, 3, 0, 0, 0, 0, 108, 59, 0, 0, 0, 2, 5, 0, 41, 21, 137, 3, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 0, 0, 108, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 50, 21, 13, 2, 28, 28, 60, 0, 97, 0, 0, 0, 0, 0, 0, 0, 66, 21, 35, 2, 29, 29, 60, 0, 101, 0, 0, 0, 0, 0, 0, 0, 58, 21, 36, 2, 30, 30, 60, 0, 105, 0, 0, 0, 0, 0, 0, 0, 52, 21, 37, 2, 31, 31, 55, 0, 111, 0, 0, 0, 0, 0, 0, 0, 75, 21, 39, 2, 32, 32, 60, 0, 117, 0, 0, 0, 0, 0, 0, 0, 79, 21, 40, 2, 33, 33, 55, 0, 116, 0, 0, 0, 8, 0, 68, 0, 124, 21, 47, 4, 0, 72, 0, 2, 112, 0, 0, 0, 8, 0, 1, 0, 137, 21, 48, 4, 0, 71, 0, 2, 107, 0, 0, 0, 8, 0, 8, 0, 153, 21, 49, 4, 0, 81, 0, 2, 82, 50, 0, 0, 128, 0, 0, 0, 99, 21, 52, 3, 0, 0, 0, 6, 105, 58, 0, 0, 0, 0, 0, 0, 55, 21, 108, 2, 31, 31, 150, 0, 101, 58, 0, 0, 0, 0, 0, 0, 60, 21, 109, 2, 30, 30, 165, 0, 38, 0, 0, 0, 0, 0, 0, 0, 62, 21, 110, 2, 29, 29, 60, 0, 38, 58, 0, 0, 0, 0, 0, 0, 64, 21, 111, 2, 29, 29, 165, 0, 97, 35, 0, 0, 0, 0, 0, 0, 71, 21, 112, 2, 29, 29, 60, 0, 97, 58, 0, 0, 0, 0, 0, 0, 69, 21, 113, 2, 29, 29, 175, 0, 111, 58, 0, 0, 0, 0, 0, 0, 77, 21, 114, 2, 32, 32, 165, 0, 117, 58, 0, 0, 0, 0, 0, 0, 81, 21, 115, 2, 33, 33, 165, 0, 97, 105, 0, 0, 0, 0, 32, 0, 83, 21, 116, 2, 29, 31, 155, 0, 101, 105, 0, 0, 0, 0, 32, 0, 85, 21, 117, 2, 30, 31, 150, 0, 97, 117, 0, 0, 0, 0, 32, 0, 87, 21, 118, 2, 29, 33, 150, 0, 117, 111, 0, 0, 0, 0, 32, 0, 89, 21, 119, 2, 33, 29, 150, 0, 111, 105, 0, 0, 0, 0, 32, 0, 91, 21, 120, 2, 32, 31, 145, 0, 117, 105, 0, 0, 0, 0, 32, 0, 93, 21, 121, 2, 33, 31, 145, 0, 105, 101, 0, 0, 0, 0, 32, 0, 95, 21, 122, 2, 31, 30, 145, 0, 105, 117, 0, 0, 0, 0, 32, 0, 97, 21, 123, 2, 31, 33, 145, 0, 116, 115, 0, 0, 40, 0, 68, 0, 111, 21, 124, 4, 0, 0, 0, 2, 115, 50, 0, 0, 40, 0, 4, 0, 173, 21, 125, 6, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 0, 0, 110, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 183, 21, 13, 2, 28, 28, 62, 0, 114, 0, 0, 0, 128, 0, 0, 0, 138, 0, 34, 3, 0, 0, 0, 6, 97, 0, 0, 0, 0, 0, 0, 0, 214, 21, 35, 2, 29, 29, 75, 0, 105, 0, 0, 0, 0, 0, 0, 0, 185, 21, 37, 2, 31, 31, 65, 0, 117, 0, 0, 0, 0, 0, 0, 0, 193, 21, 40, 2, 33, 33, 75, 0, 116, 0, 0, 0, 8, 0, 4, 0, 13, 22, 47, 4, 0, 72, 0, 2, 112, 0, 0, 0, 8, 0, 1, 0, 33, 22, 48, 4, 0, 71, 0, 2, 107, 0, 0, 0, 8, 0, 8, 0, 113, 6, 49, 4, 0, 0, 0, 2, 98, 0, 0, 0, 16, 0, 1, 0, 42, 22, 71, 5, 0, 48, 0, 5, 100, 0, 0, 0, 16, 0, 4, 0, 22, 22, 72, 5, 0, 47, 0, 5, 122, 0, 0, 0, 48, 0, 4, 0, 62, 22, 88, 7, 0, 89, 0, 6, 115, 0, 0, 0, 40, 0, 4, 0, 53, 22, 89, 6, 0, 88, 0, 3, 81, 0, 0, 0, 16, 0, 8, 0, 242, 21, 100, 7, 0, 101, 0, 6, 73, 0, 0, 0, 0, 0, 0, 0, 187, 21, 108, 2, 31, 31, 65, 0, 121, 0, 0, 0, 0, 0, 0, 0, 189, 21, 109, 2, 33, 33, 90, 0, 56, 0, 0, 0, 0, 0, 0, 0, 191, 21, 110, 2, 33, 33, 70, 0, 69, 0, 0, 0, 0, 0, 0, 0, 195, 21, 111, 2, 30, 30, 70, 0, 69, 50, 0, 0, 0, 0, 0, 0, 197, 21, 112, 2, 30, 30, 70, 0, 79, 0, 0, 0, 0, 0, 0, 0, 200, 21, 113, 2, 32, 32, 70, 0, 79, 58, 0, 0, 0, 0, 0, 0, 202, 21, 114, 2, 32, 32, 105, 0, 97, 58, 0, 0, 0, 0, 0, 0, 204, 21, 115, 2, 29, 29, 105, 0, 65, 0, 0, 0, 0, 0, 0, 0, 216, 21, 116, 2, 29, 29, 75, 0, 65, 126, 0, 0, 0, 0, 0, 0, 176, 16, 117, 2, 29, 29, 95, 0, 79, 126, 0, 0, 0, 0, 0, 0, 221, 21, 118, 2, 32, 32, 95, 0, 101, 58, 0, 0, 0, 0, 0, 0, 223, 21, 119, 2, 30, 31, 95, 0, 101, 35, 0, 0, 0, 0, 0, 0, 225, 21, 120, 2, 30, 31, 95, 0, 89, 58, 0, 0, 0, 0, 0, 0, 228, 21, 121, 2, 28, 28, 110, 0, 111, 58, 0, 0, 0, 0, 0, 0, 230, 21, 122, 2, 32, 33, 75, 0, 69, 73, 0, 0, 0, 0, 0, 0, 232, 21, 123, 2, 29, 31, 105, 0, 87, 121, 0, 0, 0, 0, 0, 0, 234, 21, 124, 2, 28, 33, 110, 0, 86, 85, 0, 0, 0, 0, 0, 0, 236, 21, 125, 2, 29, 32, 110, 0, 101, 85, 0, 0, 0, 0, 0, 0, 238, 21, 126, 2, 30, 33, 110, 0, 121, 85, 0, 0, 0, 0, 0, 0, 240, 21, 127, 2, 33, 33, 110, 0, 33, 0, 0, 0, 0, 0, 0, 0, 10, 22, 128, 0, 10, 0, 12, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 0, 112, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 73, 22, 35, 2, 29, 29, 95, 0, 105, 0, 0, 0, 0, 0, 0, 0, 87, 22, 37, 2, 31, 31, 85, 0, 117, 0, 0, 0, 0, 0, 0, 0, 92, 22, 40, 2, 33, 33, 90, 0, 116, 0, 0, 0, 8, 0, 3, 0, 116, 22, 47, 4, 0, 72, 0, 2, 82, 0, 0, 0, 128, 0, 0, 0, 102, 22, 51, 3, 0, 0, 0, 6, 119, 0, 0, 0, 0, 0, 0, 0, 208, 22, 58, 3, 0, 0, 0, 7, 100, 0, 0, 0, 16, 0, 3, 0, 142, 22, 72, 5, 0, 47, 0, 5, 102, 0, 0, 0, 8, 0, 2, 0, 214, 22, 83, 6, 0, 84, 0, 3, 97, 35, 0, 0, 0, 0, 0, 0, 76, 22, 108, 2, 29, 29, 85, 0, 69, 0, 0, 0, 0, 0, 0, 0, 80, 22, 109, 2, 30, 30, 90, 0, 69, 35, 0, 0, 0, 0, 0, 0, 85, 22, 110, 2, 30, 30, 90, 0, 79, 0, 0, 0, 0, 0, 0, 0, 90, 22, 111, 2, 32, 32, 90, 0, 121, 0, 0, 0, 0, 0, 0, 0, 94, 22, 112, 2, 31, 31, 90, 0, 69, 126, 0, 0, 0, 0, 0, 0, 98, 22, 113, 2, 30, 33, 125, 0, 79, 126, 0, 0, 0, 0, 0, 0, 100, 22, 114, 2, 32, 32, 125, 0, 116, 59, 0, 0, 8, 2, 7, 0, 129, 22, 115, 4, 0, 116, 0, 2, 100, 59, 0, 0, 16, 2, 4, 0, 169, 22, 116, 5, 0, 115, 0, 5, 116, 115, 0, 0, 40, 0, 4, 0, 18, 6, 117, 4, 0, 118, 0, 2, 100, 122, 0, 0, 48, 0, 4, 0, 196, 22, 118, 5, 0, 117, 0, 5, 116, 115, 59, 0, 40, 2, 7, 0, 202, 22, 119, 4, 0, 120, 0, 2, 100, 122, 59, 0, 48, 2, 6, 0, 81, 3, 120, 5, 0, 119, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 29, 0, 0, 0, 0, 0, 0, 115, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 238, 22, 35, 2, 29, 29, 60, 0, 101, 0, 0, 0, 0, 0, 0, 0, 234, 22, 36, 2, 30, 30, 60, 0, 105, 0, 0, 0, 0, 0, 0, 0, 226, 22, 37, 2, 31, 31, 50, 0, 111, 0, 0, 0, 0, 0, 0, 0, 246, 22, 39, 2, 32, 32, 60, 0, 117, 0, 0, 0, 0, 0, 0, 0, 250, 22, 40, 2, 33, 33, 55, 0, 114, 45, 0, 0, 0, 0, 0, 0, 8, 23, 44, 2, 28, 28, 100, 0, 108, 45, 0, 0, 0, 0, 0, 0, 50, 23, 45, 2, 28, 28, 70, 0, 116, 0, 0, 0, 8, 0, 4, 0, 61, 23, 47, 4, 0, 72, 0, 2, 112, 0, 0, 0, 8, 0, 1, 0, 74, 23, 48, 4, 0, 71, 0, 2, 107, 0, 0, 0, 8, 0, 8, 0, 4, 7, 49, 4, 0, 0, 0, 2, 108, 0, 0, 0, 0, 0, 0, 0, 66, 7, 55, 3, 0, 0, 0, 7, 119, 0, 0, 0, 0, 0, 0, 0, 195, 6, 58, 3, 0, 0, 0, 7, 105, 58, 0, 0, 0, 0, 0, 0, 229, 22, 121, 2, 31, 31, 130, 0, 38, 0, 0, 0, 0, 0, 0, 0, 232, 22, 122, 2, 30, 30, 60, 0, 101, 58, 0, 0, 0, 0, 0, 0, 236, 22, 123, 2, 30, 30, 145, 0, 97, 58, 0, 0, 0, 0, 0, 0, 244, 22, 124, 2, 29, 29, 145, 0, 111, 58, 0, 0, 0, 0, 0, 0, 248, 22, 125, 2, 32, 32, 145, 0, 117, 58, 0, 0, 0, 0, 0, 0, 252, 22, 126, 2, 33, 33, 140, 0, 97, 85, 0, 0, 0, 0, 0, 0, 254, 22, 127, 2, 29, 33, 135, 0, 101, 85, 0, 0, 0, 0, 0, 0, 0, 23, 128, 2, 30, 33, 130, 0, 111, 85, 0, 0, 0, 0, 0, 0, 2, 23, 129, 2, 32, 33, 130, 0, 97, 73, 0, 0, 0, 0, 0, 0, 4, 23, 130, 2, 29, 31, 135, 0, 101, 73, 0, 0, 0, 0, 0, 0, 6, 23, 131, 2, 30, 31, 130, 0, 114, 58, 0, 0, 0, 0, 0, 0, 13, 23, 132, 2, 28, 28, 150, 0, 82, 94, 0, 0, 48, 0, 6, 0, 19, 23, 133, 7, 0, 0, 0, 6, 82, 94, 47, 0, 48, 0, 6, 0, 34, 23, 134, 7, 0, 0, 0, 6, 108, 58, 0, 0, 0, 0, 0, 0, 55, 23, 135, 2, 28, 28, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 30, 0, 0, 0, 0, 0, 0, 99, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, 90, 23, 36, 2, 30, 30, 60, 0, 111, 0, 0, 0, 0, 0, 0, 0, 94, 23, 39, 2, 32, 32, 60, 0, 114, 45, 0, 0, 0, 0, 0, 0, 100, 23, 44, 2, 28, 28, 60, 0, 97, 58, 0, 0, 0, 0, 0, 0, 92, 23, 124, 2, 29, 29, 145, 0, 117, 58, 0, 0, 0, 0, 0, 0, 96, 23, 126, 2, 33, 33, 140, 0, 111, 85, 0, 0, 0, 0, 0, 0, 98, 23, 129, 2, 32, 33, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 30, 0, 0, 0, 0, 0, 0, 104, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 198, 23, 13, 2, 28, 28, 70, 0, 97, 0, 0, 0, 0, 0, 0, 0, 202, 23, 35, 2, 29, 29, 80, 0, 101, 0, 0, 0, 0, 0, 0, 0, 211, 23, 36, 2, 30, 30, 70, 0, 105, 0, 0, 0, 0, 0, 0, 0, 213, 23, 37, 2, 31, 31, 60, 0, 111, 0, 0, 0, 0, 0, 0, 0, 220, 23, 39, 2, 32, 32, 70, 0, 117, 0, 0, 0, 0, 0, 0, 0, 222, 23, 40, 2, 33, 33, 70, 0, 116, 0, 0, 0, 8, 0, 3, 0, 229, 23, 47, 4, 0, 72, 0, 2, 82, 0, 0, 0, 128, 0, 0, 0, 120, 0, 51, 3, 0, 0, 0, 6, 100, 0, 0, 0, 16, 0, 4, 0, 242, 23, 72, 5, 0, 47, 0, 5, 100, 90, 0, 0, 48, 0, 6, 0, 157, 23, 75, 5, 0, 76, 0, 5, 116, 83, 0, 0, 40, 0, 6, 0, 118, 23, 76, 4, 0, 75, 0, 2, 100, 90, 59, 0, 48, 2, 6, 0, 178, 23, 77, 5, 0, 78, 0, 5, 116, 83, 59, 0, 40, 2, 7, 0, 127, 23, 78, 4, 0, 77, 0, 2, 90, 0, 0, 0, 48, 0, 6, 0, 139, 23, 90, 7, 0, 91, 0, 6, 83, 0, 0, 0, 40, 0, 6, 0, 105, 23, 91, 6, 0, 90, 0, 3, 120, 0, 0, 0, 8, 0, 8, 0, 13, 24, 101, 6, 0, 100, 0, 3, 69, 0, 0, 0, 0, 0, 0, 0, 209, 23, 109, 2, 30, 30, 70, 0, 38, 0, 0, 0, 0, 0, 0, 0, 207, 23, 122, 2, 29, 29, 70, 0, 97, 73, 0, 0, 0, 0, 0, 0, 227, 23, 130, 2, 29, 31, 125, 0, 64, 50, 0, 0, 0, 0, 0, 0, 200, 23, 136, 2, 28, 28, 70, 0, 65, 0, 0, 0, 0, 0, 0, 0, 205, 23, 137, 2, 29, 29, 80, 0, 73, 0, 0, 0, 0, 0, 0, 0, 217, 23, 138, 2, 31, 31, 60, 0, 85, 0, 0, 0, 0, 0, 0, 0, 225, 23, 139, 2, 33, 33, 70, 0, 114, 42, 0, 0, 2, 0, 16, 0, 23, 24, 140, 2, 28, 28, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 32, 0, 0, 0, 0, 0, 0, 109, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 90, 59, 0, 48, 2, 7, 0, 38, 24, 77, 5, 0, 78, 0, 5, 107, 94, 0, 0, 8, 0, 7, 0, 28, 24, 141, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 32, 0, 0, 0, 0, 0, 0, 115, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 8, 0, 3, 0, 79, 24, 47, 4, 0, 72, 0, 2, 100, 0, 0, 0, 16, 0, 4, 0, 92, 24, 72, 5, 0, 47, 0, 5, 100, 90, 0, 0, 48, 0, 6, 0, 134, 24, 75, 5, 0, 76, 0, 5, 116, 83, 0, 0, 40, 0, 6, 0, 163, 24, 76, 4, 0, 75, 0, 2, 100, 90, 59, 0, 48, 2, 6, 0, 149, 24, 77, 5, 0, 78, 0, 5, 116, 83, 59, 0, 40, 2, 7, 0, 169, 24, 78, 4, 0, 77, 0, 2, 90, 0, 0, 0, 48, 0, 6, 0, 178, 24, 90, 7, 0, 91, 0, 6, 83, 0, 0, 0, 40, 0, 6, 0, 196, 24, 91, 6, 0, 90, 0, 3, 38, 0, 0, 0, 0, 0, 0, 0, 61, 24, 122, 2, 29, 29, 70, 0, 73, 0, 0, 0, 0, 0, 0, 0, 58, 24, 138, 2, 31, 31, 60, 0, 114, 42, 0, 0, 128, 0, 0, 0, 65, 24, 140, 3, 0, 0, 0, 6, 120, 35, 0, 0, 8, 0, 8, 0, 113, 24, 141, 6, 0, 0, 0, 3, 104, 35, 0, 0, 8, 0, 8, 0, 122, 24, 142, 6, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 0, 0, 114, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114, 0, 0, 0, 192, 0, 132, 0, 42, 25, 34, 3, 0, 0, 40, 0, 97, 0, 0, 0, 0, 0, 0, 0, 241, 25, 35, 2, 29, 29, 50, 0, 101, 0, 0, 0, 0, 0, 0, 0, 194, 25, 36, 2, 30, 30, 50, 0, 105, 0, 0, 0, 0, 0, 0, 0, 97, 25, 37, 2, 31, 31, 90, 0, 111, 0, 0, 0, 0, 0, 0, 0, 176, 25, 39, 2, 32, 32, 50, 0, 117, 0, 0, 0, 0, 0, 0, 0, 185, 25, 40, 2, 33, 33, 40, 0, 116, 0, 0, 0, 8, 0, 3, 0, 116, 22, 47, 4, 0, 0, 0, 2, 112, 0, 0, 0, 8, 0, 1, 0, 52, 6, 48, 4, 0, 0, 0, 2, 107, 0, 0, 0, 8, 0, 8, 0, 113, 6, 49, 4, 0, 0, 0, 2, 108, 0, 0, 0, 0, 0, 5, 0, 240, 24, 55, 3, 0, 0, 20, 7, 108, 94, 0, 0, 0, 2, 5, 0, 244, 24, 61, 3, 0, 0, 40, 0, 100, 0, 0, 0, 16, 0, 3, 0, 142, 22, 72, 5, 0, 0, 0, 5, 100, 90, 59, 0, 48, 2, 7, 0, 50, 25, 77, 5, 0, 78, 0, 5, 116, 83, 59, 0, 40, 2, 7, 0, 64, 25, 78, 4, 0, 77, 0, 2, 103, 0, 0, 0, 16, 0, 8, 2, 209, 24, 81, 5, 0, 49, 0, 5, 115, 0, 0, 0, 40, 0, 4, 0, 248, 24, 89, 6, 0, 0, 0, 3, 115, 59, 0, 0, 40, 0, 4, 0, 125, 5, 95, 6, 0, 0, 0, 3, 120, 0, 0, 0, 8, 0, 8, 0, 230, 24, 101, 6, 0, 0, 0, 3, 110, 95, 0, 0, 16, 0, 4, 0, 223, 1, 108, 8, 0, 0, 0, 4, 110, 35, 0, 0, 16, 2, 7, 0, 2, 25, 109, 8, 0, 0, 0, 4, 116, 115, 0, 0, 40, 0, 4, 0, 18, 6, 110, 4, 0, 0, 0, 2, 116, 59, 0, 0, 8, 2, 7, 0, 129, 22, 111, 4, 0, 0, 0, 2, 100, 59, 0, 0, 16, 2, 4, 0, 169, 22, 112, 5, 0, 0, 0, 5, 109, 59, 0, 0, 16, 0, 1, 0, 70, 25, 113, 8, 0, 0, 0, 4, 73, 94, 0, 0, 2, 0, 16, 0, 90, 25, 114, 2, 31, 31, 35, 0, 121, 0, 0, 0, 0, 0, 0, 0, 109, 25, 115, 2, 31, 31, 50, 0, 73, 35, 0, 0, 0, 0, 0, 0, 102, 25, 116, 2, 31, 31, 40, 0, 73, 0, 0, 0, 0, 0, 0, 0, 111, 25, 117, 2, 31, 31, 40, 0, 73, 50, 0, 0, 0, 0, 0, 0, 120, 25, 118, 2, 31, 31, 40, 0, 73, 51, 0, 0, 0, 0, 0, 0, 126, 25, 119, 2, 31, 31, 40, 0, 106, 97, 0, 0, 0, 0, 0, 0, 211, 25, 120, 2, 31, 29, 90, 0, 69, 0, 0, 0, 0, 0, 0, 0, 137, 25, 121, 2, 30, 30, 50, 0, 69, 35, 0, 0, 0, 0, 0, 0, 139, 25, 122, 2, 30, 30, 50, 0, 69, 50, 0, 0, 0, 0, 0, 0, 148, 25, 123, 2, 30, 30, 40, 0, 69, 51, 0, 0, 0, 0, 0, 0, 165, 25, 124, 2, 30, 30, 40, 0, 69, 37, 0, 0, 0, 0, 0, 0, 174, 25, 125, 2, 0, 0, 90, 0, 86, 0, 0, 0, 2, 0, 0, 0, 4, 26, 126, 2, 29, 28, 40, 0, 79, 0, 0, 0, 0, 0, 0, 0, 179, 25, 127, 2, 32, 32, 40, 0, 56, 0, 0, 0, 0, 0, 0, 0, 191, 25, 128, 2, 32, 32, 50, 0, 117, 35, 0, 0, 0, 0, 0, 0, 187, 25, 129, 2, 33, 33, 40, 0, 117, 34, 0, 0, 0, 0, 0, 0, 189, 25, 130, 2, 33, 33, 75, 0, 106, 117, 0, 0, 0, 0, 0, 0, 209, 25, 131, 2, 33, 33, 95, 0, 106, 97, 35, 0, 0, 0, 0, 0, 219, 25, 132, 2, 31, 29, 90, 0, 86, 35, 0, 0, 2, 0, 0, 0, 226, 25, 133, 2, 29, 28, 40, 0, 65, 0, 0, 0, 0, 0, 0, 0, 239, 25, 134, 2, 29, 29, 50, 0, 89, 0, 0, 0, 2, 0, 0, 0, 237, 25, 135, 2, 33, 33, 70, 0, 97, 35, 0, 0, 0, 0, 0, 0, 16, 26, 136, 2, 29, 29, 50, 0, 82, 52, 0, 0, 0, 0, 0, 0, 18, 26, 137, 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 29, 0, 0, 0, 0, 0, 0, 98, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 41, 26, 13, 2, 28, 28, 70, 0, 114, 0, 0, 0, 128, 0, 0, 0, 138, 0, 34, 3, 0, 0, 0, 6, 97, 0, 0, 0, 0, 0, 0, 0, 46, 26, 35, 2, 29, 29, 75, 0, 101, 0, 0, 0, 0, 0, 0, 0, 36, 26, 36, 2, 30, 30, 70, 0, 105, 0, 0, 0, 0, 0, 0, 0, 30, 26, 37, 2, 31, 31, 65, 0, 111, 0, 0, 0, 0, 0, 0, 0, 59, 26, 39, 2, 32, 32, 70, 0, 117, 0, 0, 0, 0, 0, 0, 0, 64, 26, 40, 2, 33, 33, 70, 0, 108, 0, 0, 0, 0, 0, 0, 0, 66, 7, 55, 3, 0, 0, 0, 7, 76, 0, 0, 0, 0, 0, 0, 0, 84, 1, 64, 3, 0, 0, 0, 7, 120, 0, 0, 0, 8, 0, 8, 0, 234, 5, 101, 6, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 119, 14, 0, 0, 0, 0, 103, 35, 0, 0, 16, 0, 8, 2, 209, 24, 121, 5, 0, 0, 0, 5, 103, 59, 0, 0, 16, 2, 8, 0, 69, 26, 122, 5, 0, 49, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 3, 0, 0, 0, 0, 0, 0, 105, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 9, 0, 0, 25, 0, 97, 0, 0, 0, 0, 0, 0, 0, 90, 26, 35, 2, 29, 29, 90, 0, 101, 0, 0, 0, 0, 0, 0, 0, 98, 26, 36, 2, 30, 30, 85, 0, 105, 0, 0, 0, 0, 0, 0, 0, 111, 26, 37, 2, 31, 31, 70, 0, 111, 0, 0, 0, 0, 0, 0, 0, 120, 26, 39, 2, 32, 32, 85, 0, 117, 0, 0, 0, 0, 0, 0, 0, 133, 26, 40, 2, 33, 33, 80, 0, 108, 94, 0, 0, 0, 0, 0, 0, 56, 1, 61, 3, 0, 0, 70, 7, 97, 47, 0, 0, 0, 0, 0, 0, 93, 26, 108, 2, 28, 28, 90, 0, 69, 0, 0, 0, 0, 0, 0, 0, 108, 26, 109, 2, 30, 30, 85, 0, 79, 0, 0, 0, 0, 0, 0, 0, 130, 26, 110, 2, 32, 32, 85, 0, 85, 0, 0, 0, 0, 0, 0, 0, 136, 26, 111, 2, 33, 33, 80, 0, 97, 85, 0, 0, 0, 0, 0, 0, 138, 26, 114, 2, 29, 32, 135, 0, 97, 73, 0, 0, 0, 0, 0, 0, 140, 26, 117, 2, 29, 31, 125, 0, 111, 73, 0, 0, 0, 0, 0, 0, 142, 26, 120, 2, 32, 31, 115, 0, 101, 47, 0, 0, 0, 0, 0, 0, 101, 26, 124, 2, 30, 30, 85, 0, 105, 35, 0, 0, 0, 0, 0, 0, 114, 26, 125, 2, 31, 31, 70, 0, 73, 0, 0, 0, 0, 0, 0, 0, 117, 26, 126, 2, 31, 31, 75, 0, 111, 47, 0, 0, 0, 0, 0, 0, 123, 26, 127, 2, 32, 32, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 0, 0, 108, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 144, 26, 35, 2, 29, 29, 85, 0, 112, 0, 0, 0, 8, 0, 1, 0, 52, 6, 48, 4, 0, 71, 0, 2, 108, 0, 0, 0, 0, 0, 0, 0, 66, 7, 55, 3, 0, 0, 0, 7, 69, 0, 0, 0, 0, 0, 0, 0, 146, 26, 108, 2, 30, 30, 85, 0, 73, 0, 0, 0, 0, 0, 0, 0, 148, 26, 109, 2, 31, 31, 75, 0, 79, 0, 0, 0, 0, 0, 0, 0, 151, 26, 110, 2, 32, 32, 80, 0, 85, 0, 0, 0, 0, 0, 0, 0, 153, 26, 111, 2, 33, 33, 80, 0, 97, 58, 0, 0, 0, 0, 0, 0, 155, 26, 112, 2, 29, 29, 135, 0, 101, 58, 0, 0, 0, 0, 0, 0, 157, 26, 113, 2, 30, 30, 130, 0, 105, 58, 0, 0, 0, 0, 0, 0, 159, 26, 114, 2, 31, 31, 120, 0, 111, 58, 0, 0, 0, 0, 0, 0, 161, 26, 115, 2, 32, 32, 125, 0, 117, 58, 0, 0, 0, 0, 0, 0, 163, 26, 116, 2, 33, 33, 125, 0, 121, 0, 0, 0, 0, 0, 0, 0, 165, 26, 117, 2, 31, 31, 75, 0, 121, 58, 0, 0, 0, 0, 0, 0, 167, 26, 118, 2, 31, 31, 125, 0, 97, 85, 0, 0, 0, 0, 0, 0, 169, 26, 119, 2, 29, 33, 135, 0, 97, 73, 0, 0, 0, 0, 0, 0, 171, 26, 120, 2, 29, 31, 135, 0, 101, 73, 0, 0, 0, 0, 0, 0, 173, 26, 121, 2, 30, 31, 135, 0, 69, 85, 0, 0, 0, 0, 0, 0, 175, 26, 122, 2, 30, 33, 135, 0, 79, 73, 0, 0, 0, 0, 0, 0, 177, 26, 123, 2, 32, 31, 125, 0, 60, 104, 62, 0, 8, 0, 12, 0, 179, 26, 124, 6, 0, 0, 25, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 0, 0, 0, 0, 0, 0, 101, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114, 0, 0, 0, 16, 64, 132, 0, 62, 27, 34, 5, 0, 0, 0, 3, 97, 0, 0, 0, 0, 0, 0, 0, 201, 26, 35, 2, 29, 29, 90, 0, 101, 0, 0, 0, 0, 0, 0, 0, 203, 26, 36, 2, 30, 30, 95, 0, 105, 0, 0, 0, 0, 0, 0, 0, 207, 26, 37, 2, 31, 31, 85, 0, 111, 0, 0, 0, 0, 0, 0, 0, 210, 26, 39, 2, 32, 32, 95, 0, 117, 0, 0, 0, 0, 0, 0, 0, 214, 26, 40, 2, 33, 33, 90, 0, 98, 0, 0, 0, 16, 0, 1, 0, 3, 27, 71, 5, 0, 0, 0, 0, 100, 0, 0, 0, 16, 0, 3, 0, 246, 26, 72, 5, 0, 0, 0, 0, 103, 0, 0, 0, 16, 0, 8, 0, 216, 26, 81, 5, 0, 49, 0, 5, 118, 35, 0, 0, 16, 0, 2, 0, 42, 27, 85, 7, 0, 83, 0, 6, 68, 0, 0, 0, 16, 0, 3, 0, 15, 27, 86, 7, 0, 87, 0, 6, 115, 0, 0, 0, 40, 0, 4, 0, 24, 27, 89, 6, 0, 88, 0, 3, 69, 0, 0, 0, 0, 0, 0, 0, 205, 26, 109, 2, 30, 30, 95, 0, 79, 0, 0, 0, 0, 0, 0, 0, 212, 26, 110, 2, 32, 32, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 39, 0, 0, 0, 0, 0, 0, 101, 115, 45, 108, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 39, 0, 0, 0, 0, 0, 0, 99, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 69, 27, 35, 2, 29, 29, 90, 0, 101, 0, 0, 0, 0, 0, 0, 0, 76, 27, 36, 2, 30, 30, 85, 0, 111, 0, 0, 0, 0, 0, 0, 0, 87, 27, 39, 2, 32, 32, 85, 0, 117, 0, 0, 0, 0, 0, 0, 0, 92, 27, 40, 2, 33, 33, 80, 0, 108, 0, 0, 0, 0, 0, 0, 0, 66, 7, 55, 3, 0, 0, 0, 7, 69, 0, 0, 0, 0, 0, 0, 0, 79, 27, 109, 2, 30, 30, 90, 0, 79, 0, 0, 0, 0, 0, 0, 0, 84, 27, 110, 2, 32, 32, 85, 0, 85, 0, 0, 0, 2, 0, 0, 0, 90, 27, 111, 2, 33, 33, 80, 0, 97, 35, 0, 0, 2, 0, 0, 0, 72, 27, 124, 2, 28, 28, 85, 0, 69, 50, 0, 0, 0, 0, 0, 0, 82, 27, 125, 2, 30, 30, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 3, 0, 0, 0, 0, 0, 0, 112, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 16, 0, 4, 0, 188, 27, 16, 5, 0, 0, 0, 6, 101, 0, 0, 0, 0, 0, 0, 0, 135, 27, 36, 2, 30, 30, 80, 0, 117, 0, 0, 0, 0, 0, 0, 0, 147, 27, 40, 2, 33, 33, 80, 0, 114, 45, 0, 0, 0, 0, 128, 0, 100, 7, 44, 3, 0, 0, 0, 0, 108, 0, 0, 0, 0, 0, 0, 0, 66, 7, 55, 3, 0, 0, 0, 7, 120, 0, 0, 0, 128, 0, 0, 0, 167, 27, 101, 3, 0, 0, 0, 6, 69, 0, 0, 0, 0, 0, 0, 0, 133, 27, 109, 2, 30, 30, 85, 0, 79, 0, 0, 0, 0, 0, 0, 0, 145, 27, 110, 2, 32, 32, 85, 0, 85, 0, 0, 0, 0, 0, 0, 0, 149, 27, 111, 2, 33, 33, 70, 0, 121, 0, 0, 0, 0, 0, 0, 0, 137, 27, 112, 2, 31, 31, 55, 0, 101, 85, 0, 0, 0, 0, 0, 0, 163, 27, 115, 2, 30, 33, 115, 0, 97, 73, 0, 0, 0, 0, 0, 0, 154, 27, 117, 2, 29, 31, 115, 0, 101, 73, 0, 0, 0, 0, 0, 0, 157, 27, 118, 2, 30, 31, 105, 0, 73, 0, 0, 0, 2, 0, 0, 0, 95, 27, 124, 2, 31, 31, 45, 0, 101, 126, 0, 0, 0, 0, 0, 0, 97, 27, 125, 2, 30, 30, 120, 0, 105, 126, 0, 0, 0, 0, 0, 0, 99, 27, 126, 2, 31, 31, 120, 0, 111, 126, 0, 0, 0, 0, 0, 0, 102, 27, 127, 2, 32, 32, 120, 0, 117, 126, 0, 0, 0, 0, 0, 0, 104, 27, 128, 2, 33, 33, 90, 0, 38, 126, 0, 0, 0, 0, 0, 0, 106, 27, 129, 2, 28, 28, 90, 0, 38, 85, 126, 0, 0, 0, 0, 0, 111, 27, 130, 2, 28, 33, 120, 0, 111, 73, 126, 0, 0, 0, 0, 0, 118, 27, 131, 2, 32, 31, 130, 0, 38, 0, 0, 0, 0, 0, 0, 0, 125, 27, 132, 2, 28, 28, 90, 0, 38, 47, 0, 0, 0, 0, 0, 0, 127, 27, 133, 2, 28, 28, 90, 0, 65, 0, 0, 0, 0, 0, 0, 0, 131, 27, 134, 2, 29, 29, 100, 0, 105, 47, 0, 0, 0, 0, 0, 0, 140, 27, 135, 2, 31, 31, 75, 0, 79, 73, 0, 0, 0, 0, 0, 0, 160, 27, 136, 2, 32, 31, 115, 0, 69, 85, 0, 0, 0, 0, 0, 0, 165, 27, 137, 2, 30, 33, 115, 0, 115, 35, 0, 0, 40, 0, 4, 0, 183, 27, 138, 6, 0, 88, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 42, 0, 0, 0, 0, 0, 0, 112, 116, 45, 112, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 215, 27, 35, 2, 29, 29, 90, 0, 101, 0, 0, 0, 0, 0, 0, 0, 233, 27, 36, 2, 30, 30, 80, 0, 105, 0, 0, 0, 0, 0, 0, 0, 240, 27, 37, 2, 31, 31, 75, 0, 111, 0, 0, 0, 0, 0, 0, 0, 252, 27, 39, 2, 32, 32, 85, 0, 117, 0, 0, 0, 0, 0, 0, 0, 255, 27, 40, 2, 33, 33, 80, 0, 82, 0, 0, 0, 0, 0, 128, 0, 72, 0, 51, 3, 0, 0, 0, 7, 119, 0, 0, 0, 0, 0, 0, 0, 195, 6, 58, 3, 0, 0, 0, 7, 120, 0, 0, 0, 128, 0, 0, 0, 7, 28, 101, 3, 0, 0, 0, 7, 69, 0, 0, 0, 0, 0, 0, 0, 230, 27, 109, 2, 30, 30, 85, 0, 79, 0, 0, 0, 0, 0, 0, 0, 250, 27, 110, 2, 32, 32, 85, 0, 85, 0, 0, 0, 0, 0, 0, 0, 1, 28, 111, 2, 33, 33, 55, 0, 121, 0, 0, 0, 0, 0, 0, 0, 236, 27, 112, 2, 28, 28, 55, 0, 38, 126, 0, 0, 0, 0, 0, 0, 218, 27, 129, 2, 30, 28, 120, 0, 38, 85, 126, 0, 0, 0, 0, 0, 223, 27, 130, 2, 28, 33, 120, 0, 38, 0, 0, 0, 2, 0, 0, 0, 205, 27, 132, 2, 28, 28, 90, 0, 38, 47, 0, 0, 0, 0, 0, 0, 209, 27, 133, 2, 28, 28, 90, 0, 105, 47, 0, 0, 0, 0, 0, 0, 243, 27, 135, 2, 31, 31, 50, 0, 69, 85, 0, 0, 0, 0, 0, 0, 5, 28, 137, 2, 30, 33, 110, 0, 115, 35, 0, 0, 40, 0, 6, 0, 19, 28, 138, 6, 0, 90, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 3, 0, 0, 0, 0, 0, 0, 114, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 53, 28, 13, 2, 28, 28, 85, 0, 114, 0, 0, 0, 128, 0, 0, 0, 81, 28, 34, 3, 0, 0, 0, 7, 97, 0, 0, 0, 0, 0, 0, 0, 51, 28, 35, 2, 29, 29, 90, 0, 101, 0, 0, 0, 0, 0, 0, 0, 45, 28, 36, 2, 30, 30, 90, 0, 111, 0, 0, 0, 0, 0, 0, 0, 55, 28, 39, 2, 32, 32, 85, 0, 117, 0, 0, 0, 0, 0, 0, 0, 57, 28, 40, 2, 33, 33, 80, 0, 122, 59, 0, 0, 48, 0, 4, 0, 236, 28, 94, 7, 0, 95, 0, 6, 115, 59, 0, 0, 40, 0, 4, 0, 155, 28, 95, 6, 0, 94, 0, 3, 90, 59, 0, 0, 48, 0, 6, 0, 250, 28, 96, 7, 0, 97, 0, 6, 83, 59, 0, 0, 40, 0, 6, 0, 165, 28, 97, 6, 0, 96, 0, 3, 121, 0, 0, 0, 0, 0, 0, 0, 47, 28, 112, 2, 28, 28, 90, 0, 89, 0, 0, 0, 0, 0, 0, 0, 59, 28, 113, 2, 28, 28, 90, 0, 73, 94, 0, 0, 2, 0, 0, 0, 24, 28, 124, 2, 31, 31, 35, 0, 108, 59, 0, 0, 0, 0, 0, 0, 106, 28, 125, 3, 0, 0, 0, 7, 109, 59, 0, 0, 16, 0, 1, 0, 113, 28, 126, 8, 0, 0, 0, 4, 110, 59, 0, 0, 16, 0, 4, 0, 120, 28, 127, 8, 0, 0, 0, 4, 105, 47, 0, 0, 0, 0, 0, 0, 41, 28, 128, 2, 31, 31, 75, 0, 64, 73, 0, 0, 0, 0, 0, 0, 61, 28, 129, 2, 28, 31, 125, 0, 64, 85, 0, 0, 0, 0, 0, 0, 63, 28, 130, 2, 28, 33, 130, 0, 111, 85, 0, 0, 0, 0, 0, 0, 65, 28, 131, 2, 32, 33, 130, 0, 105, 73, 0, 0, 0, 0, 0, 0, 67, 28, 132, 2, 31, 31, 125, 0, 121, 73, 0, 0, 0, 0, 0, 0, 69, 28, 133, 2, 28, 31, 105, 0, 121, 85, 0, 0, 0, 0, 0, 0, 71, 28, 134, 2, 28, 33, 115, 0, 101, 97, 0, 0, 0, 0, 0, 0, 73, 28, 135, 2, 30, 29, 125, 0, 101, 111, 0, 0, 0, 0, 0, 0, 75, 28, 136, 2, 30, 32, 135, 0, 101, 91, 117, 0, 0, 0, 0, 0, 77, 28, 137, 2, 30, 33, 125, 0, 79, 97, 0, 0, 0, 0, 0, 0, 79, 28, 138, 2, 32, 29, 125, 0, 112, 59, 0, 0, 8, 0, 1, 0, 127, 28, 139, 4, 0, 71, 0, 2, 116, 59, 0, 0, 8, 0, 3, 0, 134, 28, 140, 4, 0, 72, 0, 2, 116, 115, 59, 0, 40, 0, 4, 0, 141, 28, 141, 4, 0, 0, 0, 2, 102, 59, 0, 0, 8, 0, 2, 0, 148, 28, 142, 6, 0, 84, 0, 3, 98, 59, 0, 0, 16, 0, 1, 0, 175, 28, 143, 5, 0, 139, 0, 5, 100, 59, 0, 0, 16, 0, 3, 0, 189, 28, 144, 5, 0, 140, 0, 5, 42, 59, 0, 0, 16, 0, 4, 0, 200, 28, 145, 5, 0, 0, 0, 2, 118, 59, 0, 0, 16, 0, 2, 0, 218, 28, 146, 7, 0, 142, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 0, 0, 0, 0, 0, 0, 101, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114, 0, 0, 0, 128, 0, 0, 0, 152, 0, 34, 3, 0, 0, 30, 6, 97, 0, 0, 0, 0, 0, 0, 0, 12, 29, 35, 2, 29, 29, 70, 0, 101, 0, 0, 0, 0, 0, 0, 0, 21, 29, 36, 2, 30, 30, 70, 0, 105, 0, 0, 0, 0, 0, 0, 0, 23, 29, 37, 2, 31, 31, 70, 0, 111, 0, 0, 0, 0, 0, 0, 0, 26, 29, 39, 2, 32, 32, 75, 0, 117, 0, 0, 0, 0, 0, 0, 0, 28, 29, 40, 2, 33, 33, 80, 0, 116, 0, 0, 0, 8, 0, 4, 0, 30, 29, 47, 4, 0, 72, 0, 2, 107, 0, 0, 0, 8, 0, 8, 0, 43, 29, 49, 4, 0, 81, 0, 2, 100, 0, 0, 0, 16, 0, 4, 0, 12, 3, 72, 5, 0, 47, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 0, 0, 0, 0, 0, 0, 103, 114, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 9, 0, 0, 50, 0, 101, 0, 0, 0, 0, 0, 0, 0, 64, 29, 36, 2, 30, 30, 70, 0, 111, 0, 0, 0, 0, 0, 0, 0, 68, 29, 39, 2, 32, 32, 70, 0, 102, 0, 0, 0, 8, 0, 1, 0, 80, 29, 83, 4, 0, 0, 0, 2, 69, 0, 0, 0, 0, 0, 0, 0, 66, 29, 109, 2, 30, 30, 75, 0, 79, 0, 0, 0, 0, 0, 0, 0, 70, 29, 110, 2, 32, 32, 75, 0, 121, 0, 0, 0, 0, 0, 0, 0, 62, 29, 112, 2, 31, 31, 80, 0, 69, 85, 0, 0, 0, 0, 0, 0, 72, 29, 124, 2, 30, 33, 115, 0, 79, 73, 0, 0, 0, 0, 0, 0, 74, 29, 125, 2, 32, 31, 115, 0, 79, 85, 0, 0, 0, 0, 0, 0, 76, 29, 126, 2, 32, 33, 115, 0, 121, 73, 0, 0, 0, 0, 0, 0, 78, 29, 127, 2, 31, 31, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 0, 115, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 123, 29, 35, 2, 29, 29, 70, 0, 105, 58, 0, 0, 0, 0, 0, 0, 86, 29, 108, 2, 31, 31, 90, 0, 73, 0, 0, 0, 0, 0, 0, 0, 92, 29, 109, 2, 31, 31, 65, 0, 101, 58, 0, 0, 0, 0, 0, 0, 95, 29, 110, 2, 30, 30, 105, 0, 69, 0, 0, 0, 0, 0, 0, 0, 97, 29, 111, 2, 30, 30, 70, 0, 69, 45, 0, 0, 2, 0, 0, 0, 105, 29, 112, 2, 28, 28, 70, 0, 69, 58, 0, 0, 0, 0, 0, 0, 100, 29, 113, 2, 30, 28, 110, 0, 69, 51, 0, 0, 0, 0, 0, 0, 102, 29, 114, 2, 30, 30, 70, 0, 121, 58, 0, 0, 0, 0, 0, 0, 109, 29, 115, 2, 33, 33, 110, 0, 121, 0, 0, 0, 0, 0, 0, 0, 111, 29, 116, 2, 33, 33, 70, 0, 117, 45, 0, 0, 0, 0, 0, 0, 113, 29, 117, 2, 33, 33, 100, 0, 89, 58, 0, 0, 0, 0, 0, 0, 117, 29, 118, 2, 28, 28, 110, 0, 87, 0, 0, 0, 0, 0, 0, 0, 119, 29, 119, 2, 28, 28, 70, 0, 56, 0, 0, 0, 0, 0, 0, 0, 121, 29, 120, 2, 33, 33, 70, 0, 38, 0, 0, 0, 0, 0, 0, 0, 129, 29, 121, 2, 29, 29, 70, 0, 65, 58, 0, 0, 0, 0, 0, 0, 131, 29, 122, 2, 29, 29, 125, 0, 79, 0, 0, 0, 0, 0, 0, 0, 133, 29, 123, 2, 32, 32, 70, 0, 111, 58, 0, 0, 0, 0, 0, 0, 135, 29, 124, 2, 32, 32, 105, 0, 85, 0, 0, 0, 0, 0, 0, 0, 137, 29, 125, 2, 33, 33, 70, 0, 117, 58, 0, 0, 0, 0, 0, 0, 139, 29, 126, 2, 33, 33, 105, 0, 115, 120, 0, 0, 8, 0, 8, 0, 141, 29, 127, 6, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 1, 0, 0, 0, 0, 0, 0, 110, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 151, 29, 13, 2, 28, 28, 60, 0, 97, 0, 0, 0, 0, 0, 0, 0, 179, 29, 35, 2, 29, 29, 60, 0, 97, 35, 0, 0, 2, 0, 0, 0, 153, 29, 108, 2, 28, 29, 60, 0, 73, 0, 0, 0, 0, 0, 0, 0, 155, 29, 109, 2, 31, 31, 50, 0, 105, 58, 0, 0, 0, 0, 0, 0, 158, 29, 110, 2, 31, 31, 115, 0, 121, 0, 0, 0, 0, 0, 0, 0, 164, 29, 111, 2, 33, 33, 60, 0, 121, 58, 0, 0, 0, 0, 0, 0, 166, 29, 112, 2, 33, 33, 130, 0, 87, 0, 0, 0, 0, 0, 0, 0, 168, 29, 113, 2, 28, 28, 60, 0, 89, 58, 0, 0, 0, 0, 0, 0, 170, 29, 114, 2, 28, 28, 130, 0, 69, 0, 0, 0, 0, 0, 0, 0, 172, 29, 115, 2, 30, 30, 60, 0, 69, 58, 0, 0, 0, 0, 0, 0, 175, 29, 116, 2, 30, 30, 135, 0, 101, 58, 0, 0, 0, 0, 0, 0, 177, 29, 117, 2, 30, 30, 125, 0, 97, 58, 0, 0, 0, 0, 0, 0, 181, 29, 118, 2, 29, 29, 135, 0, 65, 0, 0, 0, 0, 0, 0, 0, 183, 29, 119, 2, 29, 29, 65, 0, 65, 58, 0, 0, 0, 0, 0, 0, 185, 29, 120, 2, 29, 29, 140, 0, 79, 0, 0, 0, 0, 0, 0, 0, 187, 29, 121, 2, 32, 32, 60, 0, 111, 58, 0, 0, 0, 0, 0, 0, 189, 29, 122, 2, 32, 32, 135, 0, 85, 0, 0, 0, 0, 0, 0, 0, 191, 29, 123, 2, 33, 33, 60, 0, 117, 58, 0, 0, 0, 0, 0, 0, 193, 29, 124, 2, 33, 33, 120, 0, 117, 45, 0, 0, 0, 0, 0, 0, 195, 29, 125, 2, 33, 33, 60, 0, 117, 45, 58, 0, 0, 0, 0, 0, 199, 29, 126, 2, 33, 33, 130, 0, 65, 73, 0, 0, 0, 0, 0, 0, 204, 29, 127, 2, 29, 31, 135, 0, 97, 73, 0, 0, 0, 0, 0, 0, 207, 29, 128, 2, 29, 31, 135, 0, 79, 73, 0, 0, 0, 0, 0, 0, 210, 29, 129, 2, 32, 31, 135, 0, 117, 45, 73, 0, 0, 0, 0, 0, 213, 29, 130, 2, 33, 31, 135, 0, 89, 121, 0, 0, 0, 0, 0, 0, 219, 29, 131, 2, 28, 33, 135, 0, 97, 85, 0, 0, 0, 0, 0, 0, 221, 29, 132, 2, 29, 33, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 1, 0, 0, 0, 0, 0, 0, 105, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 9, 0, 0, 55, 0, 97, 0, 0, 0, 0, 0, 0, 0, 241, 29, 35, 2, 28, 28, 65, 0, 105, 0, 0, 0, 0, 0, 0, 0, 223, 29, 37, 2, 31, 31, 65, 0, 117, 0, 0, 0, 0, 0, 0, 0, 251, 29, 40, 2, 33, 33, 65, 0, 98, 0, 0, 0, 8, 0, 1, 0, 122, 30, 71, 4, 0, 0, 0, 5, 100, 0, 0, 0, 8, 0, 4, 0, 132, 30, 72, 4, 0, 0, 0, 5, 103, 0, 0, 0, 8, 0, 8, 0, 145, 30, 81, 4, 0, 0, 0, 5, 118, 0, 0, 0, 16, 0, 2, 0, 238, 3, 84, 7, 0, 83, 0, 6, 108, 35, 0, 0, 8, 0, 4, 0, 99, 30, 105, 6, 0, 0, 0, 3, 105, 58, 0, 0, 0, 0, 0, 0, 226, 29, 108, 2, 31, 31, 115, 0, 73, 0, 0, 0, 0, 0, 0, 0, 230, 29, 109, 2, 31, 31, 65, 0, 73, 58, 0, 0, 0, 0, 0, 0, 233, 29, 110, 2, 31, 31, 115, 0, 69, 0, 0, 0, 0, 0, 0, 0, 237, 29, 111, 2, 30, 30, 65, 0, 69, 58, 0, 0, 0, 0, 0, 0, 239, 29, 112, 2, 30, 30, 65, 0, 97, 58, 0, 0, 0, 0, 0, 0, 243, 29, 113, 2, 29, 29, 115, 0, 79, 0, 0, 0, 0, 0, 0, 0, 246, 29, 114, 2, 32, 32, 65, 0, 79, 58, 0, 0, 0, 0, 0, 0, 248, 29, 115, 2, 32, 32, 115, 0, 117, 58, 0, 0, 0, 0, 0, 0, 253, 29, 116, 2, 33, 33, 115, 0, 121, 0, 0, 0, 0, 0, 0, 0, 0, 30, 117, 2, 28, 28, 65, 0, 121, 58, 0, 0, 0, 0, 0, 0, 2, 30, 118, 2, 31, 31, 115, 0, 87, 0, 0, 0, 0, 0, 0, 0, 5, 30, 119, 2, 28, 28, 65, 0, 87, 58, 0, 0, 0, 0, 0, 0, 7, 30, 120, 2, 28, 28, 65, 0, 97, 73, 0, 0, 0, 0, 0, 0, 10, 30, 121, 2, 29, 31, 85, 0, 97, 73, 58, 0, 0, 0, 0, 0, 12, 30, 122, 2, 29, 31, 115, 0, 101, 73, 0, 0, 0, 0, 0, 0, 15, 30, 123, 2, 30, 31, 85, 0, 101, 73, 58, 0, 0, 0, 0, 0, 17, 30, 124, 2, 30, 31, 115, 0, 97, 85, 0, 0, 0, 0, 0, 0, 20, 30, 125, 2, 29, 33, 85, 0, 97, 85, 58, 0, 0, 0, 0, 0, 22, 30, 126, 2, 29, 33, 115, 0, 111, 85, 0, 0, 0, 0, 0, 0, 25, 30, 127, 2, 32, 33, 85, 0, 111, 85, 58, 0, 0, 0, 0, 0, 27, 30, 128, 2, 32, 33, 115, 0, 89, 121, 0, 0, 0, 0, 0, 0, 30, 30, 129, 2, 28, 31, 75, 0, 89, 121, 58, 0, 0, 0, 0, 0, 32, 30, 130, 2, 28, 31, 110, 0, 79, 73, 0, 0, 0, 0, 0, 0, 35, 30, 131, 2, 32, 31, 105, 0, 121, 73, 0, 0, 0, 0, 0, 0, 37, 30, 132, 2, 31, 31, 90, 0, 109, 35, 0, 0, 16, 0, 1, 0, 39, 30, 133, 8, 0, 0, 0, 6, 110, 35, 0, 0, 16, 0, 4, 0, 47, 30, 134, 8, 0, 0, 0, 6, 110, 94, 35, 0, 16, 2, 7, 0, 68, 30, 135, 8, 0, 0, 0, 6, 78, 35, 0, 0, 16, 0, 8, 0, 77, 30, 136, 8, 0, 0, 0, 6, 116, 108, 35, 0, 8, 0, 4, 0, 103, 30, 137, 4, 0, 0, 0, 2, 114, 35, 0, 0, 0, 0, 0, 0, 116, 30, 138, 3, 0, 0, 0, 2, 115, 50, 0, 0, 40, 0, 4, 0, 142, 6, 139, 6, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 0, 0, 118, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 205, 30, 13, 2, 28, 29, 65, 0, 49, 0, 0, 0, 0, 0, 0, 0, 158, 30, 17, 1, 28, 32, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 183, 30, 35, 2, 28, 28, 65, 0, 101, 0, 0, 0, 0, 0, 0, 0, 189, 30, 36, 2, 30, 30, 100, 0, 105, 0, 0, 0, 0, 0, 0, 0, 191, 30, 37, 2, 31, 31, 95, 0, 111, 0, 0, 0, 0, 0, 0, 0, 199, 30, 39, 2, 32, 32, 100, 0, 117, 0, 0, 0, 0, 0, 0, 0, 201, 30, 40, 2, 33, 33, 100, 0, 108, 0, 0, 0, 0, 0, 0, 0, 3, 31, 55, 3, 0, 0, 0, 7, 50, 0, 0, 0, 0, 0, 0, 0, 161, 30, 108, 1, 8, 20, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 164, 30, 109, 1, 25, 50, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 167, 30, 110, 1, 5, 30, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 170, 30, 111, 1, 28, 58, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 175, 30, 112, 1, 20, 40, 37, 0, 55, 0, 0, 0, 0, 0, 0, 0, 180, 30, 113, 1, 20, 40, 0, 0, 97, 58, 0, 0, 0, 0, 0, 0, 185, 30, 114, 2, 29, 29, 140, 0, 69, 0, 0, 0, 0, 0, 0, 0, 187, 30, 115, 2, 30, 30, 100, 0, 79, 0, 0, 0, 0, 0, 0, 0, 197, 30, 116, 2, 32, 32, 100, 0, 121, 0, 0, 0, 0, 0, 0, 0, 203, 30, 117, 2, 33, 33, 100, 0, 64, 58, 0, 0, 0, 0, 0, 0, 207, 30, 118, 2, 28, 28, 140, 0, 97, 73, 0, 0, 0, 0, 0, 0, 209, 30, 119, 2, 29, 31, 125, 0, 97, 58, 73, 0, 0, 0, 0, 0, 211, 30, 120, 2, 29, 31, 125, 0, 64, 73, 0, 0, 0, 0, 0, 0, 213, 30, 121, 2, 28, 31, 125, 0, 64, 58, 73, 0, 0, 0, 0, 0, 215, 30, 122, 2, 28, 31, 125, 0, 101, 73, 0, 0, 0, 0, 0, 0, 217, 30, 123, 2, 30, 31, 100, 0, 69, 73, 0, 0, 0, 0, 0, 0, 219, 30, 124, 2, 30, 31, 100, 0, 79, 73, 0, 0, 0, 0, 0, 0, 221, 30, 125, 2, 32, 31, 100, 0, 111, 73, 0, 0, 0, 0, 0, 0, 223, 30, 126, 2, 32, 31, 100, 0, 117, 73, 0, 0, 0, 0, 0, 0, 225, 30, 127, 2, 33, 31, 100, 0, 121, 73, 0, 0, 0, 0, 0, 0, 227, 30, 128, 2, 33, 31, 100, 0, 97, 85, 0, 0, 0, 0, 0, 0, 229, 30, 129, 2, 29, 33, 105, 0, 97, 58, 85, 0, 0, 0, 0, 0, 231, 30, 130, 2, 29, 33, 135, 0, 101, 85, 0, 0, 0, 0, 0, 0, 233, 30, 131, 2, 30, 33, 100, 0, 69, 85, 0, 0, 0, 0, 0, 0, 235, 30, 132, 2, 30, 33, 100, 0, 105, 85, 0, 0, 0, 0, 0, 0, 237, 30, 133, 2, 31, 33, 100, 0, 64, 85, 0, 0, 0, 0, 0, 0, 239, 30, 134, 2, 28, 33, 100, 0, 64, 58, 85, 0, 0, 0, 0, 0, 241, 30, 135, 2, 28, 33, 135, 0, 105, 64, 0, 0, 0, 0, 0, 0, 243, 30, 136, 2, 31, 28, 120, 0, 121, 64, 0, 0, 0, 0, 0, 0, 245, 30, 137, 2, 31, 28, 100, 0, 117, 64, 0, 0, 0, 0, 0, 0, 247, 30, 138, 2, 33, 28, 100, 0, 107, 104, 0, 0, 8, 0, 8, 0, 249, 30, 139, 6, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 0, 0, 122, 104, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 9, 31, 17, 1, 50, 50, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 111, 31, 35, 2, 28, 28, 75, 0, 101, 0, 0, 0, 0, 0, 0, 0, 117, 31, 36, 2, 30, 30, 110, 0, 105, 0, 0, 0, 0, 0, 0, 0, 125, 31, 37, 2, 31, 31, 95, 0, 111, 0, 0, 0, 0, 0, 0, 0, 142, 31, 39, 2, 32, 32, 85, 0, 117, 0, 0, 0, 0, 0, 0, 0, 152, 31, 40, 2, 33, 33, 85, 0, 116, 0, 0, 0, 8, 0, 4, 0, 88, 31, 47, 4, 0, 0, 0, 2, 112, 0, 0, 0, 8, 0, 1, 0, 75, 31, 48, 4, 0, 0, 0, 2, 107, 0, 0, 0, 8, 0, 8, 0, 49, 31, 49, 4, 0, 0, 0, 2, 99, 0, 0, 0, 40, 0, 6, 0, 40, 31, 80, 4, 0, 0, 0, 2, 122, 0, 0, 0, 40, 0, 4, 0, 30, 31, 88, 4, 0, 0, 0, 2, 50, 0, 0, 0, 0, 0, 0, 0, 12, 31, 108, 1, 30, 50, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 15, 31, 109, 1, 30, 30, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 18, 31, 110, 1, 10, 20, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 21, 31, 111, 1, 10, 30, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 24, 31, 112, 1, 20, 20, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 27, 31, 113, 1, 30, 50, 0, 0, 97, 97, 0, 0, 0, 0, 0, 0, 101, 31, 114, 2, 29, 29, 115, 0, 97, 97, 105, 0, 0, 0, 0, 0, 103, 31, 115, 2, 29, 31, 135, 0, 97, 97, 117, 0, 0, 0, 0, 0, 105, 31, 116, 2, 29, 33, 130, 0, 97, 110, 103, 0, 0, 0, 0, 0, 107, 31, 117, 2, 29, 29, 110, 0, 97, 97, 110, 103, 0, 0, 0, 0, 109, 31, 118, 2, 29, 29, 135, 0, 97, 105, 0, 0, 0, 0, 0, 0, 113, 31, 119, 2, 28, 31, 100, 0, 97, 117, 0, 0, 0, 0, 0, 0, 115, 31, 120, 2, 29, 33, 100, 0, 101, 105, 0, 0, 0, 0, 0, 0, 119, 31, 121, 2, 30, 31, 110, 0, 101, 110, 103, 0, 0, 0, 0, 0, 121, 31, 122, 2, 30, 30, 110, 0, 101, 117, 0, 0, 0, 0, 0, 0, 123, 31, 123, 2, 30, 33, 130, 0, 105, 110, 103, 0, 0, 0, 0, 0, 134, 31, 124, 2, 31, 31, 110, 0, 105, 117, 0, 0, 0, 0, 0, 0, 136, 31, 125, 2, 31, 33, 100, 0, 110, 103, 0, 0, 0, 0, 0, 0, 138, 31, 126, 2, 0, 0, 175, 0, 111, 101, 110, 103, 0, 0, 0, 0, 144, 31, 127, 2, 32, 30, 140, 0, 111, 105, 0, 0, 0, 0, 0, 0, 146, 31, 128, 2, 32, 31, 100, 0, 111, 117, 0, 0, 0, 0, 0, 0, 148, 31, 129, 2, 32, 33, 100, 0, 111, 110, 103, 0, 0, 0, 0, 0, 150, 31, 130, 2, 32, 32, 110, 0, 117, 110, 103, 0, 0, 0, 0, 0, 158, 31, 131, 2, 33, 33, 100, 0, 117, 105, 0, 0, 0, 0, 0, 0, 160, 31, 132, 2, 33, 31, 110, 0, 111, 101, 0, 0, 0, 0, 0, 0, 162, 31, 133, 2, 28, 28, 115, 0, 101, 111, 0, 0, 0, 0, 0, 0, 164, 31, 134, 2, 28, 28, 85, 0, 101, 111, 105, 0, 0, 0, 0, 0, 166, 31, 135, 2, 28, 31, 110, 0, 121, 117, 0, 0, 0, 0, 0, 0, 168, 31, 136, 2, 33, 33, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 1, 0, 0, 0, 0, 0, 0, 122, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 184, 32, 13, 2, 28, 28, 100, 0, 97, 0, 0, 0, 0, 0, 0, 0, 170, 32, 35, 2, 29, 29, 125, 0, 105, 0, 0, 0, 0, 0, 0, 0, 195, 32, 37, 2, 31, 31, 125, 0, 111, 0, 0, 0, 0, 0, 0, 0, 217, 32, 39, 2, 32, 32, 125, 0, 117, 0, 0, 0, 0, 0, 0, 0, 228, 32, 40, 2, 33, 33, 125, 0, 78, 45, 0, 0, 0, 0, 0, 0, 168, 32, 43, 2, 68, 68, 125, 0, 116, 0, 0, 0, 8, 0, 4, 0, 49, 32, 47, 4, 0, 0, 0, 2, 112, 0, 0, 0, 8, 0, 1, 0, 23, 32, 48, 4, 0, 0, 0, 2, 107, 0, 0, 0, 8, 0, 10, 0, 69, 32, 49, 4, 0, 0, 0, 2, 110, 0, 0, 0, 16, 0, 4, 0, 200, 31, 50, 8, 0, 0, 0, 2, 108, 0, 0, 0, 0, 0, 0, 0, 246, 31, 55, 3, 0, 0, 0, 2, 106, 0, 0, 0, 0, 2, 0, 0, 253, 31, 57, 3, 0, 0, 0, 1, 78, 0, 0, 0, 16, 0, 8, 0, 222, 31, 68, 8, 0, 0, 0, 7, 116, 83, 59, 0, 40, 2, 7, 0, 89, 32, 78, 4, 0, 0, 0, 2, 102, 0, 0, 0, 8, 0, 2, 0, 43, 32, 83, 6, 0, 0, 0, 2, 115, 46, 0, 0, 40, 0, 6, 0, 115, 32, 93, 6, 0, 0, 0, 3, 83, 59, 0, 0, 40, 0, 6, 0, 107, 32, 97, 6, 0, 0, 0, 2, 49, 49, 0, 0, 0, 0, 0, 0, 170, 31, 108, 1, 9, 12, 0, 0, 50, 49, 0, 0, 0, 0, 0, 0, 173, 31, 109, 1, 10, 20, 0, 0, 50, 49, 52, 0, 0, 0, 0, 0, 176, 31, 110, 1, 18, 42, 0, 0, 50, 50, 0, 0, 0, 0, 0, 0, 179, 31, 111, 1, 20, 22, 0, 0, 51, 51, 0, 0, 0, 0, 0, 0, 182, 31, 112, 1, 30, 32, 0, 0, 51, 53, 0, 0, 0, 0, 0, 0, 185, 31, 113, 1, 30, 50, 0, 0, 52, 52, 0, 0, 0, 0, 0, 0, 188, 31, 114, 1, 38, 41, 0, 0, 53, 49, 0, 0, 0, 0, 0, 0, 191, 31, 115, 1, 10, 50, 0, 0, 53, 51, 0, 0, 0, 0, 0, 0, 194, 31, 116, 1, 30, 50, 0, 0, 53, 53, 0, 0, 0, 0, 0, 0, 197, 31, 117, 1, 50, 55, 0, 0, 112, 104, 0, 0, 8, 0, 1, 0, 33, 32, 118, 4, 0, 0, 0, 2, 116, 104, 0, 0, 8, 0, 4, 0, 59, 32, 119, 4, 0, 0, 0, 2, 107, 104, 0, 0, 8, 0, 10, 0, 79, 32, 120, 4, 0, 0, 0, 2, 116, 83, 59, 104, 40, 2, 7, 0, 98, 32, 121, 4, 0, 0, 0, 2, 116, 115, 0, 0, 40, 0, 4, 0, 128, 32, 122, 4, 0, 0, 0, 2, 116, 115, 104, 0, 40, 0, 4, 0, 138, 32, 123, 4, 0, 0, 0, 2, 116, 115, 46, 0, 40, 0, 6, 0, 148, 32, 124, 6, 0, 0, 0, 3, 116, 115, 46, 104, 40, 0, 6, 0, 158, 32, 125, 6, 0, 0, 0, 3, 65, 0, 0, 0, 0, 0, 0, 0, 175, 32, 126, 2, 29, 29, 125, 0, 97, 105, 0, 0, 0, 0, 0, 0, 180, 32, 127, 2, 29, 31, 125, 0, 65, 117, 0, 0, 0, 0, 0, 0, 182, 32, 128, 2, 29, 33, 125, 0, 64, 114, 0, 0, 0, 0, 0, 0, 189, 32, 129, 2, 28, 28, 175, 0, 69, 0, 0, 0, 0, 0, 0, 0, 191, 32, 130, 2, 30, 30, 125, 0, 101, 105, 0, 0, 0, 0, 0, 0, 193, 32, 131, 2, 30, 31, 125, 0, 105, 91, 0, 0, 0, 0, 0, 0, 203, 32, 132, 2, 31, 31, 125, 0, 105, 46, 0, 0, 0, 0, 0, 0, 205, 32, 133, 2, 31, 31, 125, 0, 105, 65, 0, 0, 0, 0, 0, 0, 207, 32, 134, 2, 31, 29, 125, 0, 105, 65, 117, 0, 0, 0, 0, 0, 209, 32, 135, 2, 31, 33, 125, 0, 105, 69, 0, 0, 0, 0, 0, 0, 211, 32, 136, 2, 31, 30, 125, 0, 105, 111, 0, 0, 0, 0, 0, 0, 213, 32, 137, 2, 31, 32, 125, 0, 105, 111, 117, 0, 0, 0, 0, 0, 215, 32, 138, 2, 31, 33, 125, 0, 111, 45, 0, 0, 0, 0, 0, 0, 222, 32, 139, 2, 32, 32, 125, 0, 111, 117, 0, 0, 0, 0, 0, 0, 224, 32, 140, 2, 32, 33, 125, 0, 111, 110, 103, 0, 0, 0, 0, 0, 226, 32, 141, 2, 32, 32, 250, 0, 117, 65, 0, 0, 0, 0, 0, 0, 233, 32, 142, 2, 33, 29, 125, 0, 117, 97, 0, 0, 0, 0, 0, 0, 235, 32, 143, 2, 33, 29, 125, 0, 117, 97, 105, 0, 0, 0, 0, 0, 237, 32, 144, 2, 33, 31, 125, 0, 117, 64, 0, 0, 0, 0, 0, 0, 239, 32, 145, 2, 33, 28, 115, 0, 117, 101, 105, 0, 0, 0, 0, 0, 241, 32, 146, 2, 33, 31, 125, 0, 117, 111, 0, 0, 0, 0, 0, 0, 243, 32, 147, 2, 33, 32, 140, 0, 121, 0, 0, 0, 0, 0, 0, 0, 245, 32, 148, 2, 31, 33, 125, 0, 121, 117, 0, 0, 0, 0, 0, 0, 250, 32, 149, 2, 31, 33, 125, 0, 121, 38, 0, 0, 0, 0, 0, 0, 252, 32, 150, 2, 31, 30, 125, 0, 121, 69, 0, 0, 0, 0, 0, 0, 254, 32, 151, 2, 31, 30, 125, 0, 121, 64, 0, 0, 0, 0, 0, 0, 0, 33, 152, 2, 31, 28, 125, 0, 121, 105, 0, 0, 0, 0, 0, 0, 2, 33, 153, 2, 31, 31, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 0, 0, 115, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 10, 33, 35, 2, 29, 29, 90, 0, 101, 0, 0, 0, 0, 0, 0, 0, 6, 33, 36, 2, 30, 30, 90, 0, 105, 0, 0, 0, 0, 0, 0, 0, 4, 33, 37, 2, 31, 31, 82, 0, 111, 0, 0, 0, 0, 0, 0, 0, 13, 33, 39, 2, 32, 32, 90, 0, 117, 0, 0, 0, 0, 0, 0, 0, 15, 33, 40, 2, 33, 33, 85, 0, 116, 0, 0, 0, 8, 0, 3, 0, 220, 6, 47, 4, 0, 0, 0, 2, 100, 0, 0, 0, 16, 0, 3, 0, 233, 6, 72, 5, 0, 0, 0, 5, 97, 47, 0, 0, 0, 0, 0, 0, 8, 33, 108, 2, 28, 28, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 3, 0, 0, 0, 0, 0, 0, 116, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 9, 0, 0, 70, 0, 64, 0, 0, 0, 0, 0, 0, 0, 77, 33, 13, 2, 28, 28, 75, 0, 97, 0, 0, 0, 0, 0, 0, 0, 61, 33, 35, 2, 29, 29, 95, 0, 101, 0, 0, 0, 0, 0, 0, 0, 45, 33, 36, 2, 30, 30, 90, 0, 105, 0, 0, 0, 0, 0, 0, 0, 17, 33, 37, 2, 31, 31, 75, 0, 111, 0, 0, 0, 0, 0, 0, 0, 81, 33, 39, 2, 32, 32, 95, 0, 117, 0, 0, 0, 0, 0, 0, 0, 63, 33, 40, 2, 33, 33, 75, 0, 108, 0, 0, 0, 0, 0, 0, 0, 66, 7, 55, 3, 0, 0, 0, 7, 74, 0, 0, 0, 16, 0, 6, 0, 108, 33, 79, 5, 0, 0, 0, 5, 99, 0, 0, 0, 8, 0, 7, 0, 95, 33, 80, 4, 0, 0, 0, 2, 69, 0, 0, 0, 0, 0, 0, 0, 57, 33, 109, 2, 30, 30, 90, 0, 79, 0, 0, 0, 0, 0, 0, 0, 93, 33, 110, 2, 32, 32, 95, 0, 85, 0, 0, 0, 0, 0, 0, 0, 75, 33, 111, 2, 33, 33, 75, 0, 121, 0, 0, 0, 0, 0, 0, 0, 31, 33, 112, 2, 33, 33, 77, 0, 89, 0, 0, 0, 0, 0, 0, 0, 43, 33, 113, 2, 33, 33, 77, 0, 73, 0, 0, 0, 0, 0, 0, 0, 29, 33, 124, 2, 31, 31, 75, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 33, 125, 2, 28, 28, 90, 0, 71, 0, 0, 0, 0, 0, 128, 0, 102, 0, 126, 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 3, 0, 0, 0, 0, 0, 0, 107, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 142, 33, 35, 2, 29, 29, 105, 0, 101, 0, 0, 0, 0, 0, 0, 0, 136, 33, 36, 2, 30, 30, 110, 0, 105, 0, 0, 0, 0, 0, 0, 0, 129, 33, 37, 2, 31, 31, 95, 0, 111, 0, 0, 0, 0, 0, 0, 0, 146, 33, 39, 2, 32, 32, 110, 0, 117, 0, 0, 0, 0, 0, 0, 0, 150, 33, 40, 2, 33, 33, 100, 0, 74, 0, 0, 0, 16, 0, 6, 0, 183, 33, 79, 5, 0, 80, 0, 5, 99, 0, 0, 0, 8, 0, 7, 0, 170, 33, 80, 4, 0, 79, 0, 2, 120, 0, 0, 0, 8, 0, 8, 0, 160, 33, 101, 6, 0, 0, 0, 3, 69, 0, 0, 0, 0, 0, 0, 0, 138, 33, 109, 2, 29, 29, 75, 0, 85, 0, 0, 0, 0, 0, 0, 0, 148, 33, 111, 2, 33, 33, 65, 0, 121, 0, 0, 0, 0, 0, 0, 0, 152, 33, 112, 2, 33, 33, 80, 0, 101, 85, 0, 0, 0, 0, 0, 0, 156, 33, 115, 2, 30, 31, 140, 0, 101, 73, 0, 0, 0, 0, 0, 0, 154, 33, 118, 2, 30, 31, 140, 0, 73, 0, 0, 0, 0, 0, 0, 0, 131, 33, 124, 2, 28, 28, 55, 0, 69, 35, 0, 0, 0, 0, 0, 0, 140, 33, 125, 2, 30, 30, 70, 0, 56, 0, 0, 0, 0, 0, 0, 0, 144, 33, 126, 2, 28, 28, 80, 0, 86, 0, 0, 0, 0, 0, 0, 0, 158, 33, 127, 2, 28, 28, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 0, 0, 0, 0, 0, 0, 105, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 198, 33, 13, 2, 28, 28, 70, 0, 97, 0, 0, 0, 0, 0, 0, 0, 200, 33, 35, 2, 29, 29, 90, 0, 101, 0, 0, 0, 0, 0, 0, 0, 208, 33, 36, 2, 30, 30, 90, 0, 105, 0, 0, 0, 0, 0, 0, 0, 210, 33, 37, 2, 31, 31, 90, 0, 111, 0, 0, 0, 0, 0, 0, 0, 215, 33, 39, 2, 32, 32, 90, 0, 117, 0, 0, 0, 0, 0, 0, 0, 217, 33, 40, 2, 33, 33, 90, 0, 100, 0, 0, 0, 16, 0, 4, 0, 12, 3, 72, 5, 0, 47, 0, 5, 69, 0, 0, 0, 0, 0, 0, 0, 203, 33, 109, 2, 30, 30, 90, 0, 79, 0, 0, 0, 0, 0, 0, 0, 213, 33, 110, 2, 32, 32, 90, 0, 97, 85, 0, 0, 0, 0, 0, 0, 223, 33, 114, 2, 29, 33, 120, 0, 97, 73, 0, 0, 0, 0, 0, 0, 219, 33, 117, 2, 29, 31, 120, 0, 101, 73, 0, 0, 0, 0, 0, 0, 221, 33, 118, 2, 30, 31, 120, 0, 69, 50, 0, 0, 0, 0, 0, 0, 206, 33, 124, 2, 30, 30, 90, 0, 64, 85, 0, 0, 0, 0, 0, 0, 225, 33, 125, 2, 28, 33, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 0, 0, 115, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 227, 33, 13, 2, 28, 28, 75, 0, 97, 0, 0, 0, 0, 0, 0, 0, 240, 33, 35, 2, 29, 29, 85, 0, 101, 0, 0, 0, 0, 0, 0, 0, 0, 34, 36, 2, 30, 30, 85, 0, 105, 0, 0, 0, 0, 0, 0, 0, 5, 34, 37, 2, 31, 31, 70, 0, 117, 0, 0, 0, 0, 0, 0, 0, 28, 34, 40, 2, 33, 33, 80, 0, 116, 0, 0, 0, 8, 0, 3, 0, 7, 5, 47, 4, 0, 72, 0, 2, 112, 0, 0, 0, 8, 0, 1, 0, 79, 34, 48, 4, 0, 71, 0, 2, 107, 0, 0, 0, 8, 0, 8, 0, 156, 34, 49, 4, 0, 81, 0, 2, 119, 0, 0, 0, 0, 0, 0, 0, 75, 34, 58, 3, 0, 0, 0, 7, 76, 0, 0, 0, 0, 0, 0, 0, 42, 34, 64, 3, 0, 0, 0, 7, 100, 0, 0, 0, 16, 0, 4, 0, 95, 34, 72, 5, 0, 47, 0, 5, 100, 90, 59, 0, 48, 2, 6, 0, 136, 34, 77, 5, 0, 78, 0, 5, 99, 0, 0, 0, 40, 2, 7, 0, 29, 5, 80, 4, 0, 77, 0, 2, 122, 0, 0, 0, 48, 0, 4, 0, 122, 34, 88, 7, 0, 89, 0, 6, 64, 47, 0, 0, 0, 0, 0, 0, 229, 33, 108, 2, 28, 28, 50, 0, 86, 0, 0, 0, 0, 0, 0, 0, 231, 33, 109, 2, 28, 28, 85, 0, 73, 35, 0, 0, 0, 0, 0, 0, 237, 33, 110, 2, 28, 28, 85, 0, 97, 47, 0, 0, 0, 0, 0, 0, 245, 33, 111, 2, 29, 29, 85, 0, 65, 0, 0, 0, 0, 0, 0, 0, 247, 33, 112, 2, 29, 29, 85, 0, 69, 0, 0, 0, 0, 0, 0, 0, 252, 33, 113, 2, 30, 30, 85, 0, 69, 35, 0, 0, 0, 0, 0, 0, 254, 33, 114, 2, 28, 28, 85, 0, 73, 0, 0, 0, 0, 0, 0, 0, 19, 34, 115, 2, 31, 31, 70, 0, 121, 0, 0, 0, 0, 0, 0, 0, 21, 34, 116, 2, 33, 33, 80, 0, 79, 0, 0, 0, 0, 0, 0, 0, 23, 34, 117, 2, 32, 32, 85, 0, 97, 73, 0, 0, 0, 0, 0, 0, 30, 34, 118, 2, 29, 31, 110, 0, 101, 73, 0, 0, 0, 0, 0, 0, 32, 34, 119, 2, 30, 31, 110, 0, 79, 73, 0, 0, 0, 0, 0, 0, 34, 34, 120, 2, 32, 31, 110, 0, 121, 69, 0, 0, 0, 0, 0, 0, 36, 34, 121, 2, 33, 30, 120, 0, 108, 47, 52, 0, 0, 0, 0, 0, 38, 34, 122, 3, 0, 0, 0, 7, 108, 108, 0, 0, 0, 0, 0, 0, 62, 34, 123, 3, 0, 0, 0, 7, 116, 115, 0, 0, 40, 0, 4, 0, 18, 6, 124, 4, 0, 125, 0, 2, 100, 122, 0, 0, 48, 0, 4, 0, 31, 6, 125, 5, 0, 124, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 0, 0, 104, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 169, 34, 13, 2, 28, 28, 80, 0, 116, 35, 0, 0, 8, 0, 4, 0, 242, 4, 25, 4, 0, 0, 0, 2, 97, 0, 0, 0, 0, 0, 0, 0, 177, 34, 35, 2, 29, 29, 100, 0, 101, 0, 0, 0, 0, 0, 0, 0, 175, 34, 36, 2, 30, 30, 90, 0, 105, 0, 0, 0, 0, 0, 0, 0, 171, 34, 37, 2, 31, 31, 80, 0, 111, 0, 0, 0, 0, 0, 0, 0, 179, 34, 39, 2, 32, 32, 90, 0, 117, 0, 0, 0, 0, 0, 0, 0, 181, 34, 40, 2, 33, 33, 90, 0, 116, 0, 0, 0, 8, 0, 3, 0, 7, 5, 47, 4, 0, 0, 0, 2, 112, 0, 0, 0, 8, 0, 1, 0, 52, 6, 48, 4, 0, 0, 0, 2, 107, 0, 0, 0, 8, 0, 8, 0, 113, 6, 49, 4, 0, 0, 0, 2, 99, 0, 0, 0, 40, 0, 7, 0, 100, 6, 80, 4, 0, 0, 0, 2, 81, 0, 0, 0, 16, 0, 10, 0, 204, 4, 100, 7, 0, 0, 0, 6, 121, 0, 0, 0, 0, 0, 0, 0, 173, 34, 108, 2, 31, 31, 80, 0, 87, 0, 0, 0, 0, 0, 0, 0, 183, 34, 109, 2, 28, 28, 90, 0, 97, 73, 0, 0, 0, 0, 0, 0, 185, 34, 110, 2, 29, 31, 120, 0, 101, 73, 0, 0, 0, 0, 0, 0, 187, 34, 111, 2, 30, 31, 120, 0, 105, 64, 0, 0, 0, 0, 0, 0, 189, 34, 112, 2, 31, 28, 120, 0, 112, 35, 0, 0, 8, 0, 1, 0, 71, 6, 113, 4, 0, 0, 0, 2, 116, 115, 35, 0, 40, 0, 4, 0, 18, 6, 114, 4, 0, 0, 0, 2, 107, 35, 0, 0, 8, 0, 8, 0, 126, 6, 115, 4, 0, 0, 0, 2, 100, 122, 0, 0, 48, 0, 4, 0, 31, 6, 116, 5, 0, 117, 0, 5, 116, 115, 0, 0, 40, 0, 4, 0, 191, 34, 117, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 0, 0, 100, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 201, 34, 13, 2, 28, 28, 65, 0, 114, 0, 0, 0, 0, 0, 0, 0, 244, 34, 34, 3, 0, 0, 0, 7, 97, 0, 0, 0, 0, 0, 0, 0, 216, 34, 35, 2, 29, 29, 75, 0, 101, 0, 0, 0, 0, 0, 0, 0, 208, 34, 36, 2, 30, 30, 75, 0, 105, 0, 0, 0, 0, 0, 0, 0, 205, 34, 37, 2, 31, 31, 75, 0, 111, 0, 0, 0, 0, 0, 0, 0, 222, 34, 39, 2, 32, 32, 75, 0, 117, 0, 0, 0, 0, 0, 0, 0, 220, 34, 40, 2, 33, 33, 75, 0, 116, 0, 0, 0, 8, 0, 4, 0, 37, 35, 47, 4, 0, 72, 0, 2, 112, 0, 0, 0, 8, 0, 1, 0, 11, 35, 48, 4, 0, 71, 0, 2, 82, 0, 0, 0, 0, 0, 0, 0, 248, 34, 51, 3, 0, 0, 0, 7, 108, 0, 0, 0, 0, 0, 0, 0, 240, 34, 55, 3, 0, 0, 0, 7, 118, 0, 0, 0, 16, 0, 2, 0, 238, 3, 84, 7, 0, 83, 0, 6, 115, 0, 0, 0, 40, 0, 4, 0, 252, 34, 89, 6, 0, 88, 0, 3, 51, 0, 0, 0, 2, 0, 0, 0, 203, 34, 108, 2, 29, 29, 65, 0, 69, 0, 0, 0, 0, 0, 0, 0, 210, 34, 109, 2, 30, 30, 75, 0, 38, 0, 0, 0, 0, 0, 0, 0, 212, 34, 110, 2, 30, 30, 75, 0, 38, 35, 0, 0, 0, 0, 0, 0, 214, 34, 111, 2, 30, 30, 60, 0, 65, 0, 0, 0, 0, 0, 0, 0, 218, 34, 112, 2, 29, 29, 75, 0, 79, 0, 0, 0, 0, 0, 0, 0, 224, 34, 113, 2, 32, 32, 75, 0, 86, 0, 0, 0, 0, 0, 0, 0, 226, 34, 114, 2, 28, 28, 75, 0, 48, 0, 0, 0, 0, 0, 0, 0, 228, 34, 115, 2, 32, 32, 75, 0, 121, 0, 0, 0, 0, 0, 0, 0, 230, 34, 116, 2, 31, 31, 75, 0, 89, 0, 0, 0, 0, 0, 0, 0, 232, 34, 117, 2, 31, 31, 75, 0, 87, 0, 0, 0, 0, 0, 0, 0, 234, 34, 118, 2, 28, 28, 75, 0, 87, 35, 0, 0, 0, 0, 0, 0, 236, 34, 119, 2, 28, 28, 75, 0, 97, 73, 0, 0, 0, 0, 0, 0, 238, 34, 120, 2, 29, 31, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 0, 0, 107, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 52, 35, 13, 2, 28, 28, 60, 0, 116, 35, 0, 0, 8, 0, 4, 0, 242, 4, 25, 4, 0, 0, 0, 2, 114, 0, 0, 0, 128, 0, 0, 0, 120, 0, 34, 3, 0, 0, 0, 6, 97, 0, 0, 0, 0, 0, 0, 0, 61, 35, 35, 2, 29, 29, 90, 0, 101, 0, 0, 0, 0, 0, 0, 0, 56, 35, 36, 2, 30, 30, 90, 0, 105, 0, 0, 0, 0, 0, 0, 0, 54, 35, 37, 2, 31, 31, 80, 0, 111, 0, 0, 0, 0, 0, 0, 0, 63, 35, 39, 2, 32, 32, 90, 0, 117, 0, 0, 0, 0, 0, 0, 0, 65, 35, 40, 2, 33, 33, 90, 0, 116, 0, 0, 0, 8, 0, 4, 0, 87, 6, 47, 4, 0, 0, 0, 2, 112, 0, 0, 0, 8, 0, 1, 0, 52, 6, 48, 4, 0, 0, 0, 2, 107, 0, 0, 0, 8, 0, 8, 0, 113, 6, 49, 4, 0, 0, 0, 2, 99, 0, 0, 0, 40, 0, 7, 0, 100, 6, 80, 4, 0, 0, 0, 2, 81, 0, 0, 0, 16, 0, 10, 0, 204, 4, 100, 7, 0, 0, 0, 6, 112, 35, 0, 0, 8, 0, 1, 0, 71, 6, 108, 4, 0, 0, 0, 2, 116, 115, 35, 0, 40, 0, 4, 0, 18, 6, 109, 4, 0, 0, 0, 2, 107, 35, 0, 0, 8, 0, 8, 0, 67, 35, 110, 4, 0, 81, 0, 2, 100, 122, 0, 0, 48, 0, 4, 0, 31, 6, 111, 5, 0, 112, 0, 5, 116, 115, 0, 0, 40, 0, 4, 0, 83, 35, 112, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 3, 0, 0, 0, 0, 0, 0, 114, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 9, 0, 0, 60, 0, 97, 0, 0, 0, 0, 0, 0, 0, 93, 35, 35, 2, 29, 29, 90, 0, 101, 0, 0, 0, 0, 0, 0, 0, 106, 35, 36, 2, 30, 30, 85, 0, 105, 0, 0, 0, 0, 0, 0, 0, 112, 35, 37, 2, 31, 31, 75, 0, 111, 0, 0, 0, 0, 0, 0, 0, 118, 35, 39, 2, 32, 32, 85, 0, 117, 0, 0, 0, 0, 0, 0, 0, 124, 35, 40, 2, 33, 33, 80, 0, 97, 47, 0, 0, 0, 0, 0, 0, 100, 35, 108, 2, 28, 28, 90, 0, 97, 35, 0, 0, 0, 0, 0, 0, 130, 35, 124, 2, 28, 28, 50, 0, 101, 35, 0, 0, 0, 0, 0, 0, 134, 35, 125, 2, 30, 30, 50, 0, 105, 35, 0, 0, 0, 0, 0, 0, 138, 35, 126, 2, 31, 31, 50, 0, 111, 35, 0, 0, 0, 0, 0, 0, 142, 35, 127, 2, 32, 32, 50, 0, 117, 35, 0, 0, 0, 0, 0, 0, 146, 35, 128, 2, 33, 33, 50, 0, 43, 0, 0, 0, 0, 0, 0, 0, 150, 35, 129, 1, 0, 30, 0, 0, 43, 50, 0, 0, 0, 0, 0, 0, 153, 35, 130, 1, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 21, 0, 0, 0, 0, 0, 0, 110, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 32, 0, 174, 35, 35, 2, 29, 29, 115, 0, 101, 0, 0, 0, 0, 0, 0, 0, 172, 35, 36, 2, 30, 30, 90, 0, 105, 0, 0, 0, 0, 0, 0, 0, 169, 35, 37, 2, 31, 31, 80, 0, 111, 0, 0, 0, 0, 0, 0, 0, 176, 35, 39, 2, 32, 32, 90, 0, 117, 0, 0, 0, 0, 0, 0, 0, 178, 35, 40, 2, 33, 33, 80, 0, 86, 0, 0, 0, 0, 0, 0, 0, 156, 35, 109, 2, 28, 28, 80, 0, 64, 51, 0, 0, 0, 0, 0, 0, 162, 35, 110, 2, 28, 28, 70, 0, 97, 73, 0, 0, 0, 0, 32, 0, 180, 35, 134, 2, 29, 31, 120, 0, 97, 85, 0, 0, 0, 0, 32, 0, 182, 35, 135, 2, 29, 33, 120, 0, 64, 47, 0, 0, 0, 0, 0, 0, 164, 35, 149, 2, 28, 28, 65, 0, 101, 73, 0, 0, 0, 0, 32, 0, 184, 35, 150, 2, 30, 31, 120, 0, 101, 85, 0, 0, 0, 0, 32, 0, 186, 35, 151, 2, 30, 33, 120, 0, 86, 73, 0, 0, 0, 0, 32, 0, 188, 35, 152, 2, 28, 31, 120, 0, 86, 85, 0, 0, 0, 0, 32, 0, 190, 35, 153, 2, 28, 33, 120, 0, 111, 73, 0, 0, 0, 0, 32, 0, 192, 35, 154, 2, 32, 31, 120, 0, 111, 85, 0, 0, 0, 0, 32, 0, 194, 35, 155, 2, 32, 33, 120, 0, 117, 73, 0, 0, 0, 0, 32, 0, 196, 35, 156, 2, 33, 31, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 21, 0, 0, 0, 0, 0, 0, 112, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 201, 35, 13, 2, 28, 28, 65, 0, 97, 0, 0, 0, 0, 0, 32, 0, 222, 35, 35, 2, 29, 29, 110, 0, 101, 0, 0, 0, 0, 0, 32, 0, 218, 35, 36, 2, 30, 30, 110, 0, 105, 0, 0, 0, 0, 0, 32, 0, 212, 35, 37, 2, 31, 31, 110, 0, 117, 0, 0, 0, 0, 0, 32, 0, 230, 35, 40, 2, 33, 33, 110, 0, 118, 0, 0, 0, 16, 0, 2, 0, 201, 3, 84, 7, 0, 0, 0, 6, 86, 0, 0, 0, 0, 0, 0, 0, 206, 35, 109, 2, 28, 28, 65, 0, 73, 0, 0, 0, 0, 0, 0, 0, 215, 35, 113, 2, 31, 31, 75, 0, 69, 0, 0, 0, 0, 0, 32, 0, 220, 35, 116, 2, 30, 30, 100, 0, 111, 58, 0, 0, 0, 0, 32, 0, 226, 35, 119, 2, 32, 32, 110, 0, 79, 0, 0, 0, 0, 0, 32, 0, 224, 35, 121, 2, 32, 32, 100, 0, 85, 0, 0, 0, 0, 0, 0, 0, 228, 35, 122, 2, 33, 33, 75, 0, 43, 0, 0, 0, 0, 0, 0, 0, 198, 35, 149, 1, 5, 30, 0, 0, 101, 73, 0, 0, 0, 0, 0, 0, 249, 7, 150, 2, 30, 31, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 1, 0, 0, 0, 0, 0, 0, 112, 114, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105, 0, 0, 0, 0, 0, 0, 0, 232, 35, 37, 2, 31, 31, 85, 0, 111, 0, 0, 0, 0, 0, 0, 0, 239, 35, 39, 2, 32, 32, 85, 0, 117, 0, 0, 0, 0, 0, 0, 0, 241, 35, 40, 2, 33, 33, 85, 0, 69, 0, 0, 0, 0, 0, 0, 0, 235, 35, 108, 2, 30, 30, 85, 0, 65, 0, 0, 0, 0, 0, 0, 0, 237, 35, 109, 2, 29, 29, 90, 0, 101, 73, 0, 0, 0, 0, 0, 0, 243, 35, 110, 2, 30, 31, 105, 0, 97, 85, 0, 0, 0, 0, 0, 0, 245, 35, 111, 2, 29, 33, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 30, 0, 0, 0, 0, 0, 0, 115, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 247, 35, 13, 2, 28, 28, 70, 0, 97, 0, 0, 0, 0, 0, 0, 0, 254, 35, 35, 2, 29, 29, 85, 0, 101, 0, 0, 0, 0, 0, 0, 0, 0, 36, 36, 2, 30, 30, 80, 0, 105, 0, 0, 0, 0, 0, 0, 0, 249, 35, 37, 2, 31, 31, 70, 0, 111, 0, 0, 0, 0, 0, 0, 0, 4, 36, 39, 2, 32, 32, 80, 0, 117, 0, 0, 0, 0, 0, 0, 0, 252, 35, 40, 2, 33, 33, 70, 0, 118, 0, 0, 0, 16, 0, 2, 0, 238, 3, 84, 7, 0, 0, 0, 6, 69, 0, 0, 0, 0, 0, 0, 0, 2, 36, 109, 2, 30, 30, 80, 0, 79, 0, 0, 0, 0, 0, 0, 0, 6, 36, 111, 2, 32, 32, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 1, 0, 0, 0, 0, 0, 0, 103, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 8, 0, 3, 0, 200, 18, 47, 4, 0, 0, 0, 2, 107, 0, 0, 0, 8, 0, 8, 0, 54, 5, 49, 4, 0, 0, 0, 2, 98, 0, 0, 0, 8, 0, 1, 0, 122, 30, 71, 4, 0, 0, 0, 5, 100, 0, 0, 0, 8, 0, 3, 0, 7, 5, 72, 4, 0, 0, 0, 2, 103, 0, 0, 0, 8, 0, 8, 0, 113, 6, 81, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0, 110, 115, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 12, 36, 35, 2, 28, 28, 90, 0, 101, 0, 0, 0, 0, 0, 0, 0, 10, 36, 36, 2, 30, 30, 90, 0, 105, 0, 0, 0, 0, 0, 0, 0, 8, 36, 37, 2, 31, 31, 55, 0, 111, 0, 0, 0, 0, 0, 0, 0, 14, 36, 39, 2, 32, 32, 90, 0, 117, 0, 0, 0, 0, 0, 0, 0, 16, 36, 40, 2, 33, 33, 85, 0, 116, 0, 0, 0, 8, 0, 3, 0, 220, 6, 47, 4, 0, 0, 0, 2, 100, 0, 0, 0, 16, 0, 3, 0, 233, 6, 72, 5, 0, 0, 0, 5, 85, 0, 0, 0, 0, 0, 0, 0, 173, 6, 108, 2, 33, 33, 80, 0, 69, 0, 0, 0, 0, 0, 0, 0, 162, 6, 109, 2, 30, 30, 85, 0, 75, 0, 0, 0, 8, 0, 4, 0, 18, 36, 110, 6, 0, 0, 0, 3, 120, 50, 0, 0, 8, 0, 8, 0, 245, 11, 111, 6, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 19, 0, 0, 0, 0, 0, 0, 104, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 36, 36, 35, 2, 29, 29, 85, 0, 101, 0, 0, 0, 0, 0, 0, 0, 38, 36, 36, 2, 30, 30, 85, 0, 105, 0, 0, 0, 0, 0, 0, 0, 42, 36, 37, 2, 31, 31, 80, 0, 111, 0, 0, 0, 0, 0, 0, 0, 45, 36, 39, 2, 32, 32, 85, 0, 117, 0, 0, 0, 0, 0, 0, 0, 49, 36, 40, 2, 33, 33, 90, 0, 69, 0, 0, 0, 0, 0, 0, 0, 40, 36, 112, 2, 30, 30, 85, 0, 65, 126, 0, 0, 0, 0, 0, 0, 51, 36, 113, 2, 29, 29, 100, 0, 69, 126, 0, 0, 0, 0, 0, 0, 53, 36, 114, 2, 30, 30, 100, 0, 79, 126, 0, 0, 0, 0, 0, 0, 55, 36, 116, 2, 32, 32, 100, 0, 79, 0, 0, 0, 0, 0, 0, 0, 47, 36, 127, 2, 32, 32, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 54, 0, 0, 0, 0, 0, 0, 97, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 73, 36, 13, 2, 28, 28, 80, 0, 97, 0, 0, 0, 0, 0, 0, 0, 71, 36, 35, 2, 29, 29, 100, 0, 101, 0, 0, 0, 0, 0, 0, 0, 59, 36, 36, 2, 30, 30, 80, 0, 105, 0, 0, 0, 0, 0, 0, 0, 57, 36, 37, 2, 31, 31, 80, 0, 111, 0, 0, 0, 0, 0, 0, 0, 69, 36, 39, 2, 32, 32, 80, 0, 117, 0, 0, 0, 0, 0, 0, 0, 67, 36, 40, 2, 33, 33, 80, 0, 121, 0, 0, 0, 0, 0, 0, 0, 63, 36, 112, 2, 33, 33, 100, 0, 87, 0, 0, 0, 0, 0, 0, 0, 65, 36, 125, 2, 28, 28, 90, 0, 38, 0, 0, 0, 0, 0, 0, 0, 61, 36, 127, 2, 30, 30, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 1, 0, 0, 0, 0, 0, 0, 97, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 83, 36, 35, 2, 29, 29, 85, 0, 101, 0, 0, 0, 0, 0, 0, 0, 79, 36, 36, 2, 30, 30, 85, 0, 105, 0, 0, 0, 0, 0, 0, 0, 77, 36, 37, 2, 31, 31, 85, 0, 111, 0, 0, 0, 0, 0, 0, 0, 87, 36, 39, 2, 32, 32, 85, 0, 117, 0, 0, 0, 0, 0, 0, 0, 89, 36, 40, 2, 33, 33, 85, 0, 69, 0, 0, 0, 0, 0, 0, 0, 81, 36, 108, 2, 30, 30, 85, 0, 79, 0, 0, 0, 0, 0, 0, 0, 85, 36, 109, 2, 32, 32, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 0, 0, 97, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 105, 36, 13, 2, 28, 28, 110, 0, 114, 0, 0, 0, 128, 0, 0, 0, 138, 0, 34, 3, 0, 0, 0, 6, 97, 0, 0, 0, 0, 0, 0, 0, 100, 36, 35, 2, 29, 29, 110, 0, 101, 0, 0, 0, 0, 0, 0, 0, 94, 36, 36, 2, 30, 30, 110, 0, 105, 0, 0, 0, 0, 0, 0, 0, 91, 36, 37, 2, 31, 31, 100, 0, 111, 0, 0, 0, 0, 0, 0, 0, 110, 36, 39, 2, 32, 32, 110, 0, 117, 0, 0, 0, 0, 0, 0, 0, 112, 36, 40, 2, 33, 33, 110, 0, 98, 0, 0, 0, 16, 0, 1, 0, 124, 36, 71, 5, 0, 0, 0, 0, 120, 0, 0, 0, 8, 0, 8, 0, 162, 36, 101, 6, 0, 0, 0, 3, 121, 0, 0, 0, 0, 0, 0, 0, 96, 36, 108, 2, 28, 28, 90, 0, 112, 96, 0, 0, 8, 0, 1, 0, 114, 36, 109, 4, 0, 71, 0, 2, 116, 96, 0, 0, 8, 0, 4, 0, 130, 36, 110, 4, 0, 72, 0, 2, 116, 83, 96, 0, 40, 0, 6, 0, 143, 36, 111, 4, 0, 75, 0, 2, 107, 96, 0, 0, 8, 0, 8, 0, 152, 36, 112, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 1, 0, 0, 0, 0, 0, 0, 119, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 168, 36, 13, 2, 28, 28, 70, 0, 97, 0, 0, 0, 0, 0, 0, 0, 186, 36, 35, 2, 29, 29, 70, 0, 101, 0, 0, 0, 0, 0, 0, 0, 178, 36, 36, 2, 30, 30, 70, 0, 105, 0, 0, 0, 0, 0, 0, 0, 172, 36, 37, 2, 31, 31, 70, 0, 111, 0, 0, 0, 0, 0, 0, 0, 194, 36, 39, 2, 32, 32, 70, 0, 117, 0, 0, 0, 0, 0, 0, 0, 198, 36, 40, 2, 33, 33, 70, 0, 64, 58, 0, 0, 0, 0, 0, 0, 170, 36, 108, 2, 28, 28, 135, 0, 105, 58, 0, 0, 0, 0, 0, 0, 175, 36, 109, 2, 31, 31, 135, 0, 101, 58, 0, 0, 0, 0, 0, 0, 180, 36, 110, 2, 30, 30, 135, 0, 69, 0, 0, 0, 0, 0, 0, 0, 182, 36, 111, 2, 30, 30, 70, 0, 69, 58, 0, 0, 0, 0, 0, 0, 184, 36, 112, 2, 30, 30, 135, 0, 97, 58, 0, 0, 0, 0, 0, 0, 188, 36, 113, 2, 29, 29, 135, 0, 79, 0, 0, 0, 0, 0, 0, 0, 190, 36, 114, 2, 32, 32, 70, 0, 79, 58, 0, 0, 0, 0, 0, 0, 192, 36, 115, 2, 32, 32, 135, 0, 111, 58, 0, 0, 0, 0, 0, 0, 196, 36, 116, 2, 32, 32, 135, 0, 117, 58, 0, 0, 0, 0, 0, 0, 200, 36, 117, 2, 33, 33, 135, 0, 115, 50, 0, 0, 40, 0, 4, 0, 142, 6, 118, 6, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 21, 0, 0, 0, 0, 0, 0, 100, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 202, 36, 35, 2, 29, 29, 65, 0, 101, 0, 0, 0, 0, 0, 0, 0, 207, 36, 36, 2, 30, 30, 65, 0, 105, 0, 0, 0, 0, 0, 0, 0, 211, 36, 37, 2, 31, 31, 65, 0, 111, 0, 0, 0, 0, 0, 0, 0, 215, 36, 39, 2, 32, 32, 65, 0, 117, 0, 0, 0, 0, 0, 0, 0, 219, 36, 40, 2, 33, 33, 55, 0, 116, 0, 0, 0, 8, 0, 3, 0, 220, 6, 47, 4, 0, 0, 0, 2, 118, 0, 0, 0, 16, 0, 2, 0, 201, 3, 84, 7, 0, 0, 0, 6, 105, 58, 0, 0, 0, 0, 0, 0, 213, 36, 112, 2, 31, 31, 135, 0, 101, 58, 0, 0, 0, 0, 0, 0, 209, 36, 114, 2, 30, 30, 125, 0, 97, 58, 0, 0, 0, 0, 0, 0, 205, 36, 118, 2, 29, 29, 150, 0, 111, 58, 0, 0, 0, 0, 0, 0, 217, 36, 119, 2, 32, 32, 150, 0, 117, 58, 0, 0, 0, 0, 0, 0, 221, 36, 123, 2, 33, 33, 145, 0, 97, 73, 0, 0, 0, 0, 0, 0, 223, 36, 134, 2, 29, 31, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 21, 0, 0, 0, 0, 0, 0, 116, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 225, 36, 13, 2, 29, 29, 65, 0, 114, 0, 0, 0, 128, 0, 0, 0, 138, 0, 34, 3, 0, 0, 0, 6, 97, 0, 0, 0, 0, 0, 32, 0, 227, 36, 35, 2, 29, 29, 65, 0, 101, 0, 0, 0, 0, 0, 0, 0, 231, 36, 36, 2, 30, 30, 65, 0, 105, 0, 0, 0, 0, 0, 0, 0, 235, 36, 37, 2, 31, 31, 65, 0, 111, 0, 0, 0, 0, 0, 0, 0, 239, 36, 39, 2, 32, 32, 65, 0, 117, 0, 0, 0, 0, 0, 0, 0, 243, 36, 40, 2, 33, 33, 55, 0, 118, 0, 0, 0, 16, 0, 2, 0, 201, 3, 84, 7, 0, 0, 0, 6, 105, 58, 0, 0, 0, 0, 0, 0, 237, 36, 112, 2, 31, 31, 135, 0, 101, 58, 0, 0, 0, 0, 0, 0, 233, 36, 114, 2, 30, 30, 135, 0, 97, 58, 0, 0, 0, 0, 0, 0, 229, 36, 118, 2, 29, 29, 150, 0, 111, 58, 0, 0, 0, 0, 0, 0, 241, 36, 119, 2, 32, 32, 150, 0, 117, 58, 0, 0, 0, 0, 0, 0, 245, 36, 123, 2, 33, 33, 140, 0, 97, 73, 0, 0, 0, 0, 32, 0, 247, 36, 134, 2, 29, 31, 140, 0, 97, 85, 0, 0, 0, 0, 32, 0, 249, 36, 135, 2, 29, 33, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 21, 0, 0, 0, 0, 0, 0, 115, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 251, 36, 13, 2, 29, 29, 65, 0, 114, 0, 0, 0, 0, 0, 128, 0, 72, 0, 34, 3, 0, 0, 0, 7, 97, 0, 0, 0, 0, 0, 32, 0, 253, 36, 35, 2, 29, 29, 65, 0, 101, 0, 0, 0, 0, 0, 0, 0, 8, 37, 36, 2, 30, 30, 65, 0, 105, 0, 0, 0, 0, 0, 0, 0, 12, 37, 37, 2, 31, 31, 65, 0, 111, 0, 0, 0, 0, 0, 0, 0, 16, 37, 39, 2, 32, 32, 65, 0, 117, 0, 0, 0, 0, 0, 0, 0, 20, 37, 40, 2, 33, 33, 55, 0, 116, 0, 0, 0, 8, 0, 3, 0, 220, 6, 47, 4, 0, 0, 0, 2, 118, 0, 0, 0, 16, 0, 2, 0, 201, 3, 84, 7, 0, 0, 0, 6, 105, 58, 0, 0, 0, 0, 0, 0, 14, 37, 112, 2, 31, 31, 135, 0, 101, 58, 0, 0, 0, 0, 0, 0, 10, 37, 114, 2, 30, 30, 135, 0, 38, 58, 0, 0, 0, 0, 0, 0, 6, 37, 117, 2, 30, 30, 135, 0, 97, 58, 0, 0, 0, 0, 0, 0, 2, 37, 118, 2, 29, 29, 150, 0, 111, 58, 0, 0, 0, 0, 0, 0, 18, 37, 119, 2, 32, 32, 150, 0, 117, 58, 0, 0, 0, 0, 0, 0, 22, 37, 123, 2, 33, 33, 140, 0, 97, 73, 0, 0, 0, 0, 32, 0, 24, 37, 134, 2, 29, 31, 140, 0, 97, 85, 0, 0, 0, 0, 32, 0, 26, 37, 135, 2, 29, 33, 135, 0, 38, 0, 0, 0, 0, 0, 0, 0, 4, 37, 149, 2, 30, 30, 65, 0, 109, 35, 0, 0, 16, 0, 1, 0, 183, 1, 150, 8, 0, 0, 0, 4, 110, 35, 0, 0, 16, 0, 4, 0, 223, 1, 151, 8, 0, 0, 0, 4, 110, 46, 35, 0, 16, 0, 5, 0, 4, 2, 152, 8, 50, 0, 0, 4, 110, 94, 35, 0, 16, 2, 7, 0, 42, 2, 153, 8, 0, 0, 0, 4, 78, 35, 0, 0, 16, 0, 8, 0, 82, 2, 154, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 0, 0, 116, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 59, 37, 13, 2, 28, 28, 70, 0, 114, 0, 0, 0, 128, 0, 128, 0, 184, 37, 34, 3, 0, 0, 0, 6, 97, 0, 0, 0, 0, 0, 0, 0, 86, 37, 35, 2, 29, 29, 90, 0, 101, 0, 0, 0, 0, 0, 0, 0, 74, 37, 36, 2, 30, 30, 90, 0, 105, 0, 0, 0, 0, 0, 0, 0, 66, 37, 37, 2, 31, 31, 85, 0, 111, 0, 0, 0, 0, 0, 0, 0, 98, 37, 39, 2, 32, 32, 90, 0, 117, 0, 0, 0, 0, 0, 0, 0, 101, 37, 40, 2, 33, 33, 85, 0, 114, 45, 0, 0, 0, 0, 128, 0, 39, 37, 44, 3, 0, 0, 0, 0, 114, 47, 0, 0, 0, 0, 0, 0, 212, 37, 46, 3, 0, 0, 0, 7, 116, 0, 0, 0, 8, 0, 3, 0, 220, 6, 47, 4, 0, 0, 0, 2, 108, 0, 0, 0, 0, 0, 0, 0, 66, 7, 55, 3, 0, 0, 0, 7, 100, 0, 0, 0, 16, 0, 3, 0, 233, 6, 72, 5, 0, 0, 0, 5, 116, 83, 0, 0, 40, 0, 6, 0, 221, 37, 76, 4, 0, 75, 0, 2, 116, 83, 59, 0, 40, 2, 7, 0, 230, 37, 78, 4, 0, 77, 0, 2, 73, 0, 0, 0, 0, 0, 0, 0, 68, 37, 108, 2, 31, 31, 65, 0, 73, 50, 0, 0, 2, 0, 0, 0, 71, 37, 109, 2, 31, 31, 65, 0, 101, 64, 0, 0, 0, 0, 0, 0, 77, 37, 110, 2, 31, 28, 115, 0, 69, 0, 0, 0, 2, 0, 0, 0, 83, 37, 111, 2, 30, 30, 70, 0, 65, 64, 0, 0, 0, 0, 0, 0, 90, 37, 112, 2, 29, 29, 115, 0, 79, 0, 0, 0, 0, 0, 0, 0, 96, 37, 113, 2, 32, 32, 70, 0, 85, 0, 0, 0, 0, 0, 0, 0, 103, 37, 114, 2, 32, 32, 75, 0, 116, 115, 0, 0, 40, 0, 4, 0, 105, 37, 115, 4, 0, 0, 0, 2, 107, 104, 0, 0, 8, 0, 8, 0, 118, 37, 116, 4, 0, 81, 0, 2, 107, 45, 0, 0, 8, 0, 8, 0, 134, 37, 117, 4, 0, 81, 0, 2, 75, 0, 0, 0, 8, 0, 4, 0, 147, 37, 118, 6, 0, 0, 0, 3, 112, 104, 0, 0, 8, 0, 1, 0, 165, 37, 119, 4, 0, 71, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 1, 0, 0, 0, 0, 0, 0, 109, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 9, 0, 0, 80, 0, 97, 0, 0, 0, 0, 0, 0, 0, 251, 37, 35, 2, 29, 29, 85, 0, 101, 0, 0, 0, 0, 0, 0, 0, 249, 37, 36, 2, 30, 30, 75, 0, 105, 0, 0, 0, 0, 0, 32, 0, 9, 38, 37, 2, 29, 31, 145, 0, 111, 0, 0, 0, 0, 0, 0, 0, 253, 37, 39, 2, 32, 32, 77, 0, 117, 0, 0, 0, 0, 0, 0, 0, 1, 38, 40, 2, 33, 33, 70, 0, 112, 0, 0, 0, 8, 0, 1, 0, 201, 6, 48, 4, 0, 71, 0, 2, 107, 0, 0, 0, 8, 0, 8, 0, 4, 7, 49, 4, 0, 81, 0, 2, 100, 0, 0, 0, 16, 0, 3, 0, 54, 38, 72, 5, 0, 47, 0, 5, 118, 0, 0, 0, 16, 0, 2, 0, 41, 38, 84, 7, 0, 83, 0, 6, 104, 0, 0, 0, 8, 0, 12, 0, 81, 38, 107, 6, 0, 0, 0, 3, 73, 0, 0, 0, 0, 0, 0, 0, 246, 37, 108, 2, 31, 31, 65, 0, 89, 0, 0, 0, 0, 0, 0, 0, 255, 37, 109, 2, 28, 28, 77, 0, 85, 0, 0, 0, 0, 0, 0, 0, 3, 38, 110, 2, 33, 33, 70, 0, 121, 0, 0, 0, 0, 0, 0, 0, 5, 38, 111, 2, 33, 33, 75, 0, 97, 105, 0, 0, 0, 0, 32, 0, 7, 38, 112, 2, 29, 31, 155, 0, 111, 105, 0, 0, 0, 0, 32, 0, 11, 38, 113, 2, 32, 31, 140, 0, 101, 105, 0, 0, 0, 0, 32, 0, 13, 38, 114, 2, 30, 31, 140, 0, 89, 105, 0, 0, 0, 0, 32, 0, 15, 38, 115, 2, 28, 31, 135, 0, 117, 105, 0, 0, 0, 0, 32, 0, 17, 38, 116, 2, 33, 31, 135, 0, 121, 105, 0, 0, 0, 0, 32, 0, 19, 38, 117, 2, 33, 31, 135, 0, 97, 117, 0, 0, 0, 0, 32, 0, 21, 38, 118, 2, 29, 33, 150, 0, 111, 117, 0, 0, 0, 0, 32, 0, 23, 38, 119, 2, 32, 33, 140, 0, 101, 117, 0, 0, 0, 0, 32, 0, 25, 38, 120, 2, 30, 33, 140, 0, 105, 117, 0, 0, 0, 0, 32, 0, 27, 38, 121, 2, 31, 33, 140, 0, 101, 121, 0, 0, 0, 0, 32, 0, 29, 38, 122, 2, 30, 33, 140, 0, 89, 121, 0, 0, 0, 0, 32, 0, 31, 38, 123, 2, 28, 33, 135, 0, 105, 121, 0, 0, 0, 0, 32, 0, 33, 38, 124, 2, 31, 33, 130, 0, 117, 111, 0, 0, 0, 0, 32, 0, 35, 38, 125, 2, 33, 32, 140, 0, 105, 101, 0, 0, 0, 0, 32, 0, 37, 38, 126, 2, 31, 30, 140, 0, 121, 89, 0, 0, 0, 0, 32, 0, 39, 38, 127, 2, 33, 28, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 21, 0, 0, 0, 0, 0, 0, 98, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 101, 38, 35, 2, 29, 29, 90, 0, 101, 0, 0, 0, 0, 0, 0, 0, 103, 38, 36, 2, 30, 30, 90, 0, 105, 0, 0, 0, 0, 0, 0, 0, 105, 38, 37, 2, 31, 31, 90, 0, 111, 0, 0, 0, 0, 0, 0, 0, 107, 38, 39, 2, 32, 32, 90, 0, 117, 0, 0, 0, 0, 0, 0, 0, 109, 38, 40, 2, 33, 33, 90, 0, 116, 115, 0, 0, 40, 0, 4, 0, 111, 38, 149, 4, 0, 150, 0, 2, 100, 122, 0, 0, 48, 0, 4, 0, 124, 38, 150, 5, 0, 149, 0, 5, 116, 115, 104, 0, 40, 0, 4, 0, 145, 38, 151, 4, 0, 150, 0, 2, 100, 122, 104, 0, 48, 0, 4, 0, 158, 38, 152, 5, 0, 149, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 1, 0, 0, 0, 0, 0, 0, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114, 0, 0, 0, 128, 0, 0, 0, 138, 0, 34, 3, 0, 0, 0, 6, 97, 0, 0, 0, 0, 0, 0, 0, 197, 38, 35, 2, 29, 29, 100, 0, 101, 0, 0, 0, 0, 0, 0, 16, 201, 38, 36, 2, 30, 30, 100, 0, 105, 0, 0, 0, 0, 0, 0, 0, 205, 38, 37, 2, 31, 31, 90, 0, 111, 0, 0, 0, 0, 0, 0, 0, 207, 38, 39, 2, 32, 32, 100, 0, 117, 0, 0, 0, 0, 0, 0, 0, 211, 38, 40, 2, 33, 33, 100, 0, 116, 0, 0, 0, 8, 0, 3, 0, 220, 6, 47, 4, 0, 0, 0, 2, 108, 0, 0, 0, 0, 0, 0, 0, 223, 38, 55, 3, 0, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0, 62, 34, 64, 3, 0, 0, 0, 7, 88, 0, 0, 0, 8, 0, 10, 0, 213, 38, 106, 6, 0, 0, 0, 3, 73, 0, 0, 0, 0, 0, 0, 16, 179, 38, 108, 2, 28, 28, 50, 0, 56, 0, 0, 0, 0, 0, 0, 0, 183, 38, 109, 2, 28, 28, 50, 0, 117, 35, 0, 0, 0, 0, 0, 16, 187, 38, 110, 2, 13, 13, 50, 0, 85, 0, 0, 0, 0, 0, 0, 0, 191, 38, 111, 2, 33, 33, 50, 0, 65, 0, 0, 0, 0, 0, 0, 0, 195, 38, 112, 2, 29, 29, 100, 0, 38, 0, 0, 0, 0, 0, 0, 16, 199, 38, 113, 2, 29, 29, 100, 0, 69, 0, 0, 0, 0, 0, 0, 0, 203, 38, 114, 2, 13, 13, 100, 0, 89, 0, 0, 0, 0, 0, 0, 16, 209, 38, 115, 2, 28, 28, 100, 0, 71, 0, 0, 0, 16, 0, 10, 0, 182, 0, 116, 7, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 0, 0, 102, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 236, 38, 35, 2, 31, 31, 80, 0, 101, 0, 0, 0, 0, 0, 0, 0, 238, 38, 36, 2, 31, 31, 80, 0, 105, 0, 0, 0, 0, 0, 0, 0, 232, 38, 37, 2, 31, 31, 100, 0, 111, 0, 0, 0, 0, 0, 0, 0, 240, 38, 39, 2, 31, 31, 80, 0, 117, 0, 0, 0, 0, 0, 0, 0, 234, 38, 40, 2, 31, 31, 100, 0, 65, 0, 0, 0, 0, 0, 0, 0, 230, 38, 108, 2, 31, 31, 100, 0, 101, 73, 0, 0, 0, 0, 0, 0, 242, 38, 109, 2, 31, 31, 110, 0, 111, 85, 0, 0, 0, 0, 0, 0, 244, 38, 110, 2, 31, 31, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 0, 0, 103, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 246, 38, 13, 2, 28, 28, 60, 0, 97, 0, 0, 0, 0, 0, 0, 0, 248, 38, 35, 2, 29, 29, 100, 0, 97, 35, 0, 0, 0, 0, 0, 0, 250, 38, 108, 2, 28, 28, 60, 0, 69, 0, 0, 0, 0, 0, 0, 0, 253, 38, 109, 2, 30, 30, 70, 0, 69, 35, 0, 0, 0, 0, 0, 0, 255, 38, 110, 2, 28, 28, 60, 0, 73, 0, 0, 0, 0, 0, 0, 0, 2, 39, 111, 2, 31, 31, 60, 0, 73, 35, 0, 0, 0, 0, 0, 0, 5, 39, 112, 2, 28, 28, 60, 0, 79, 0, 0, 0, 0, 0, 0, 0, 9, 39, 113, 2, 32, 32, 70, 0, 79, 35, 0, 0, 0, 0, 0, 0, 11, 39, 114, 2, 28, 28, 60, 0, 85, 0, 0, 0, 0, 0, 0, 0, 14, 39, 115, 2, 33, 33, 70, 0, 85, 35, 0, 0, 0, 0, 0, 0, 16, 39, 116, 2, 28, 28, 60, 0, 65, 58, 0, 0, 0, 0, 0, 0, 19, 39, 117, 2, 29, 29, 100, 0, 101, 58, 0, 0, 0, 0, 0, 0, 21, 39, 118, 2, 30, 30, 105, 0, 105, 58, 0, 0, 0, 0, 0, 0, 23, 39, 119, 2, 31, 31, 105, 0, 111, 58, 0, 0, 0, 0, 0, 0, 25, 39, 120, 2, 32, 32, 95, 0, 117, 58, 0, 0, 0, 0, 0, 0, 27, 39, 121, 2, 33, 33, 105, 0, 64, 73, 0, 0, 0, 0, 0, 0, 29, 39, 122, 2, 28, 31, 120, 0, 64, 85, 0, 0, 0, 0, 0, 0, 31, 39, 123, 2, 28, 33, 120, 0, 105, 64, 0, 0, 0, 0, 0, 0, 33, 39, 124, 2, 31, 28, 120, 0, 117, 64, 0, 0, 0, 0, 0, 0, 35, 39, 125, 2, 33, 28, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 0, 0, 116, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114, 0, 0, 0, 128, 0, 0, 0, 138, 0, 34, 3, 0, 0, 0, 6, 97, 0, 0, 0, 0, 0, 0, 0, 76, 39, 35, 2, 29, 29, 90, 0, 101, 0, 0, 0, 0, 0, 0, 16, 43, 39, 36, 2, 28, 28, 55, 0, 105, 0, 0, 0, 0, 0, 0, 16, 37, 39, 37, 2, 31, 31, 90, 0, 111, 0, 0, 0, 0, 0, 0, 32, 47, 39, 39, 2, 32, 32, 55, 0, 117, 0, 0, 0, 0, 0, 0, 32, 41, 39, 40, 2, 33, 33, 90, 0, 116, 0, 0, 0, 8, 0, 3, 0, 220, 6, 47, 4, 0, 0, 0, 2, 107, 0, 0, 0, 8, 0, 8, 0, 97, 39, 49, 4, 0, 0, 0, 0, 108, 0, 0, 0, 0, 0, 0, 0, 113, 39, 55, 3, 0, 0, 0, 0, 100, 0, 0, 0, 16, 0, 3, 0, 33, 3, 72, 5, 0, 0, 0, 5, 103, 0, 0, 0, 16, 0, 8, 0, 105, 39, 81, 7, 0, 0, 0, 0, 121, 0, 0, 0, 0, 0, 0, 16, 39, 39, 108, 2, 33, 33, 90, 0, 87, 0, 0, 0, 0, 0, 0, 16, 45, 39, 109, 2, 28, 28, 55, 0, 86, 0, 0, 0, 0, 0, 0, 32, 49, 39, 110, 2, 28, 28, 55, 0, 38, 0, 0, 0, 0, 0, 0, 16, 53, 39, 111, 2, 30, 30, 90, 0, 65, 0, 0, 0, 0, 0, 0, 32, 55, 39, 112, 2, 29, 29, 90, 0, 48, 0, 0, 0, 0, 0, 0, 32, 70, 39, 113, 2, 32, 32, 90, 0, 101, 58, 0, 0, 0, 0, 0, 16, 72, 39, 114, 2, 30, 30, 120, 0, 73, 0, 0, 0, 0, 0, 0, 16, 74, 39, 115, 2, 31, 31, 55, 0, 117, 50, 0, 0, 0, 0, 0, 0, 83, 39, 116, 2, 33, 33, 90, 0, 101, 50, 0, 0, 0, 0, 0, 0, 91, 39, 117, 2, 28, 28, 50, 0, 71, 0, 0, 0, 16, 0, 10, 0, 204, 4, 118, 7, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 0, 0, 107, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 129, 39, 13, 2, 28, 28, 100, 0, 42, 0, 0, 0, 16, 0, 132, 0, 185, 39, 16, 5, 0, 0, 0, 3, 97, 0, 0, 0, 0, 0, 0, 0, 121, 39, 35, 2, 29, 29, 100, 0, 111, 0, 0, 0, 0, 0, 0, 0, 133, 39, 39, 2, 32, 32, 100, 0, 117, 0, 0, 0, 0, 0, 0, 0, 137, 39, 40, 2, 33, 33, 100, 0, 100, 90, 59, 0, 48, 2, 6, 0, 174, 39, 77, 5, 0, 0, 0, 2, 116, 83, 59, 0, 40, 2, 6, 0, 165, 39, 78, 4, 0, 0, 0, 2, 69, 0, 0, 0, 0, 0, 0, 0, 125, 39, 108, 2, 30, 30, 100, 0, 117, 45, 0, 0, 0, 0, 0, 0, 141, 39, 109, 2, 33, 33, 100, 0, 107, 45, 0, 0, 8, 0, 8, 0, 145, 39, 110, 4, 0, 0, 50, 3, 107, 104, 0, 0, 8, 0, 8, 0, 126, 6, 111, 4, 0, 0, 0, 2, 116, 45, 0, 0, 8, 0, 4, 0, 155, 39, 112, 4, 0, 0, 0, 3, 112, 45, 0, 0, 8, 0, 1, 0, 52, 6, 113, 4, 0, 0, 0, 2, 112, 104, 0, 0, 8, 0, 1, 0, 71, 6, 114, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 1, 0, 0, 0, 0, 0, 0, 107, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 9, 0, 0, 60, 0, 114, 0, 0, 0, 16, 0, 10, 0, 182, 0, 34, 7, 0, 0, 0, 6, 97, 0, 0, 0, 0, 0, 0, 0, 201, 39, 35, 2, 29, 29, 75, 0, 101, 0, 0, 0, 0, 0, 0, 0, 203, 39, 36, 2, 30, 30, 75, 0, 105, 0, 0, 0, 0, 0, 0, 0, 208, 39, 37, 2, 31, 31, 75, 0, 111, 0, 0, 0, 0, 0, 0, 0, 210, 39, 39, 2, 32, 32, 75, 0, 117, 0, 0, 0, 0, 0, 0, 0, 212, 39, 40, 2, 33, 33, 75, 0, 97, 73, 0, 0, 0, 0, 0, 0, 214, 39, 108, 2, 29, 31, 125, 0, 38, 0, 0, 0, 0, 0, 0, 0, 212, 34, 109, 2, 30, 30, 75, 0, 87, 0, 0, 0, 0, 0, 0, 0, 234, 34, 110, 2, 28, 28, 75, 0, 79, 0, 0, 0, 0, 0, 0, 0, 224, 34, 111, 2, 32, 32, 75, 0, 116, 108, 35, 0, 8, 0, 4, 0, 216, 39, 112, 4, 0, 0, 0, 2, 116, 115, 0, 0, 40, 0, 4, 0, 18, 6, 113, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; autoFileInMemory espeakdata_phons4 = FileInMemory_createWithData (36148, reinterpret_cast (&espeakdata_phons4_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/phontab", U"phontab"); Collection_addItem (me.peek(), espeakdata_phons4.transfer()); return me.transfer(); } catch (MelderError) { Melder_throw (U"FilesInMemory not created."); } } praat-6.0.04/external/espeak/espeakdata_variants.cpp000066400000000000000000000645571261542461700225500ustar00rootroot00000000000000/* File espeakdata_variants.cpp was generated automatically on Sun Nov 4 17:43:38 2012 from files in espeak-data/voices/!v */ #include "espeakdata_FileInMemory.h" #include "Collection.h" #include "FileInMemory.h" #include "melder.h" FilesInMemory create_espeakdata_variants () { try { autoFilesInMemory me = FilesInMemory_create (); static unsigned char espeakdata_variants1_data[94] = { 108, 97, 110, 103, 117, 97, 103, 101, 32, 118, 97, 114, 105, 97, 110, 116, 10, 110, 97, 109, 101, 32, 99, 114, 111, 97, 107, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 32, 55, 48, 10, 10, 112, 105, 116, 99, 104, 32, 56, 53, 32, 49, 49, 55, 10, 102, 108, 117, 116, 116, 101, 114, 32, 50, 48, 10, 10, 102, 111, 114, 109, 97, 110, 116, 32, 48, 32, 49, 48, 48, 32, 56, 48, 32, 49, 49, 48, 10, 10, 10, 10, 0}; autoFileInMemory espeakdata_variants1 = FileInMemory_createWithData (93, reinterpret_cast (&espeakdata_variants1_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/!v/croak", U"croak"); Collection_addItem (me.peek(), espeakdata_variants1.transfer()); static unsigned char espeakdata_variants2_data[325] = { 108, 97, 110, 103, 117, 97, 103, 101, 32, 118, 97, 114, 105, 97, 110, 116, 10, 110, 97, 109, 101, 32, 102, 101, 109, 97, 108, 101, 49, 10, 103, 101, 110, 100, 101, 114, 32, 102, 101, 109, 97, 108, 101, 32, 55, 48, 10, 10, 112, 105, 116, 99, 104, 32, 49, 52, 48, 32, 50, 48, 48, 10, 102, 108, 117, 116, 116, 101, 114, 32, 56, 10, 114, 111, 117, 103, 104, 110, 101, 115, 115, 32, 52, 10, 102, 111, 114, 109, 97, 110, 116, 32, 48, 32, 49, 49, 53, 32, 32, 56, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 49, 32, 49, 50, 48, 32, 32, 56, 48, 32, 49, 56, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 50, 32, 49, 48, 48, 32, 32, 55, 48, 32, 49, 53, 48, 32, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 51, 32, 49, 49, 53, 32, 32, 55, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 52, 32, 49, 49, 48, 32, 32, 56, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 53, 32, 49, 49, 48, 32, 32, 57, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 54, 32, 49, 48, 53, 32, 32, 56, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 55, 32, 49, 49, 48, 32, 32, 55, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 56, 32, 49, 49, 48, 32, 32, 55, 48, 32, 49, 53, 48, 10, 10, 115, 116, 114, 101, 115, 115, 65, 100, 100, 32, 45, 49, 48, 32, 45, 49, 48, 32, 45, 50, 48, 32, 45, 50, 48, 32, 48, 32, 48, 32, 52, 48, 32, 54, 48, 10, 0}; autoFileInMemory espeakdata_variants2 = FileInMemory_createWithData (324, reinterpret_cast (&espeakdata_variants2_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/!v/f1", U"f1"); Collection_addItem (me.peek(), espeakdata_variants2.transfer()); static unsigned char espeakdata_variants3_data[358] = { 108, 97, 110, 103, 117, 97, 103, 101, 32, 118, 97, 114, 105, 97, 110, 116, 10, 110, 97, 109, 101, 32, 102, 101, 109, 97, 108, 101, 50, 10, 103, 101, 110, 100, 101, 114, 32, 102, 101, 109, 97, 108, 101, 10, 10, 112, 105, 116, 99, 104, 32, 49, 52, 50, 32, 50, 50, 48, 10, 114, 111, 117, 103, 104, 110, 101, 115, 115, 32, 51, 10, 10, 102, 111, 114, 109, 97, 110, 116, 32, 48, 32, 49, 48, 53, 32, 32, 56, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 49, 32, 49, 49, 48, 32, 32, 56, 48, 32, 49, 54, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 50, 32, 49, 49, 48, 32, 32, 55, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 51, 32, 49, 49, 48, 32, 32, 55, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 52, 32, 49, 49, 53, 32, 32, 56, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 53, 32, 49, 49, 53, 32, 32, 56, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 54, 32, 49, 49, 48, 32, 32, 55, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 55, 32, 49, 49, 48, 32, 32, 55, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 56, 32, 49, 49, 48, 32, 32, 55, 48, 32, 49, 53, 48, 10, 10, 115, 116, 114, 101, 115, 115, 65, 100, 100, 32, 48, 32, 48, 32, 45, 49, 48, 32, 45, 49, 48, 32, 48, 32, 48, 32, 49, 48, 32, 52, 48, 10, 98, 114, 101, 97, 116, 104, 32, 48, 32, 50, 32, 51, 32, 51, 32, 51, 32, 51, 32, 51, 32, 50, 10, 101, 99, 104, 111, 32, 49, 52, 48, 32, 49, 48, 10, 99, 111, 110, 115, 111, 110, 97, 110, 116, 115, 32, 49, 50, 53, 32, 49, 50, 53, 10, 0}; autoFileInMemory espeakdata_variants3 = FileInMemory_createWithData (357, reinterpret_cast (&espeakdata_variants3_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/!v/f2", U"f2"); Collection_addItem (me.peek(), espeakdata_variants3.transfer()); static unsigned char espeakdata_variants4_data[376] = { 108, 97, 110, 103, 117, 97, 103, 101, 32, 118, 97, 114, 105, 97, 110, 116, 10, 110, 97, 109, 101, 32, 102, 101, 109, 97, 108, 101, 51, 10, 103, 101, 110, 100, 101, 114, 32, 102, 101, 109, 97, 108, 101, 10, 10, 112, 105, 116, 99, 104, 32, 49, 52, 48, 32, 50, 52, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 48, 32, 49, 48, 53, 32, 32, 56, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 49, 32, 49, 50, 48, 32, 32, 55, 53, 32, 49, 53, 48, 32, 45, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 50, 32, 49, 51, 53, 32, 32, 55, 48, 32, 49, 53, 48, 32, 45, 50, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 51, 32, 49, 50, 53, 32, 32, 56, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 52, 32, 49, 50, 53, 32, 32, 56, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 53, 32, 49, 50, 53, 32, 32, 56, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 54, 32, 49, 50, 48, 32, 32, 55, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 55, 32, 49, 49, 48, 32, 32, 55, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 56, 32, 49, 49, 48, 32, 32, 55, 48, 32, 49, 53, 48, 10, 10, 115, 116, 114, 101, 115, 115, 65, 109, 112, 32, 49, 56, 32, 49, 56, 32, 50, 48, 32, 50, 48, 32, 50, 48, 32, 50, 48, 32, 50, 48, 32, 50, 48, 10, 47, 47, 98, 114, 101, 97, 116, 104, 32, 48, 32, 50, 32, 52, 32, 52, 32, 52, 32, 52, 32, 52, 32, 52, 10, 98, 114, 101, 97, 116, 104, 32, 48, 32, 50, 32, 51, 32, 51, 32, 51, 32, 51, 32, 51, 32, 50, 10, 101, 99, 104, 111, 32, 49, 50, 48, 32, 49, 48, 10, 114, 111, 117, 103, 104, 110, 101, 115, 115, 32, 52, 10, 10, 10, 0}; autoFileInMemory espeakdata_variants4 = FileInMemory_createWithData (375, reinterpret_cast (&espeakdata_variants4_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/!v/f3", U"f3"); Collection_addItem (me.peek(), espeakdata_variants4.transfer()); static unsigned char espeakdata_variants5_data[351] = { 108, 97, 110, 103, 117, 97, 103, 101, 32, 118, 97, 114, 105, 97, 110, 116, 10, 110, 97, 109, 101, 32, 102, 101, 109, 97, 108, 101, 52, 10, 103, 101, 110, 100, 101, 114, 32, 102, 101, 109, 97, 108, 101, 10, 10, 101, 99, 104, 111, 32, 49, 51, 48, 32, 49, 53, 10, 112, 105, 116, 99, 104, 32, 49, 52, 50, 32, 50, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 48, 32, 49, 50, 48, 32, 32, 56, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 49, 32, 49, 49, 53, 32, 32, 56, 48, 32, 49, 54, 48, 32, 45, 50, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 50, 32, 49, 51, 48, 32, 32, 55, 53, 32, 49, 53, 48, 32, 45, 50, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 51, 32, 49, 50, 51, 32, 32, 55, 53, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 52, 32, 49, 50, 53, 32, 32, 56, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 53, 32, 49, 50, 53, 32, 32, 56, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 54, 32, 49, 49, 48, 32, 32, 56, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 55, 32, 49, 49, 48, 32, 32, 55, 53, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 56, 32, 49, 49, 48, 32, 32, 55, 53, 32, 49, 53, 48, 10, 10, 115, 116, 114, 101, 115, 115, 65, 100, 100, 32, 45, 50, 48, 32, 45, 50, 48, 32, 45, 50, 48, 32, 45, 50, 48, 32, 48, 32, 48, 32, 50, 48, 32, 49, 50, 48, 10, 115, 116, 114, 101, 115, 115, 65, 109, 112, 32, 49, 56, 32, 49, 54, 32, 50, 48, 32, 50, 48, 32, 50, 48, 32, 50, 48, 32, 50, 48, 32, 50, 48, 10, 0}; autoFileInMemory espeakdata_variants5 = FileInMemory_createWithData (350, reinterpret_cast (&espeakdata_variants5_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/!v/f4", U"f4"); Collection_addItem (me.peek(), espeakdata_variants5.transfer()); static unsigned char espeakdata_variants6_data[426] = { 108, 97, 110, 103, 117, 97, 103, 101, 32, 118, 97, 114, 105, 97, 110, 116, 32, 10, 110, 97, 109, 101, 32, 102, 101, 109, 97, 108, 101, 53, 10, 103, 101, 110, 100, 101, 114, 32, 102, 101, 109, 97, 108, 101, 32, 10, 10, 112, 105, 116, 99, 104, 32, 49, 54, 48, 32, 50, 50, 56, 10, 114, 111, 117, 103, 104, 110, 101, 115, 115, 32, 48, 10, 10, 102, 111, 114, 109, 97, 110, 116, 32, 48, 32, 49, 48, 53, 32, 32, 56, 48, 32, 49, 53, 48, 32, 10, 102, 111, 114, 109, 97, 110, 116, 32, 49, 32, 49, 49, 48, 32, 32, 56, 48, 32, 49, 54, 48, 32, 10, 102, 111, 114, 109, 97, 110, 116, 32, 50, 32, 49, 49, 48, 32, 32, 55, 48, 32, 49, 53, 48, 32, 10, 102, 111, 114, 109, 97, 110, 116, 32, 51, 32, 49, 49, 48, 32, 32, 55, 48, 32, 49, 53, 48, 32, 10, 102, 111, 114, 109, 97, 110, 116, 32, 52, 32, 49, 49, 53, 32, 32, 56, 48, 32, 50, 48, 48, 32, 10, 102, 111, 114, 109, 97, 110, 116, 32, 53, 32, 49, 49, 53, 32, 32, 56, 48, 32, 49, 48, 48, 32, 10, 102, 111, 114, 109, 97, 110, 116, 32, 54, 32, 49, 49, 48, 32, 32, 55, 48, 32, 49, 53, 48, 32, 10, 102, 111, 114, 109, 97, 110, 116, 32, 55, 32, 49, 49, 48, 32, 32, 55, 48, 32, 49, 48, 48, 32, 10, 102, 111, 114, 109, 97, 110, 116, 32, 56, 32, 49, 49, 48, 32, 32, 55, 48, 32, 49, 53, 48, 32, 10, 10, 115, 116, 114, 101, 115, 115, 65, 100, 100, 32, 48, 32, 48, 32, 45, 49, 48, 32, 45, 49, 48, 32, 48, 32, 48, 32, 49, 48, 32, 52, 48, 32, 10, 98, 114, 101, 97, 116, 104, 32, 48, 32, 52, 32, 32, 54, 32, 32, 32, 54, 32, 32, 32, 54, 32, 32, 32, 54, 32, 32, 48, 32, 49, 48, 32, 10, 101, 99, 104, 111, 32, 49, 52, 48, 32, 49, 48, 32, 10, 118, 111, 105, 99, 105, 110, 103, 32, 55, 53, 32, 10, 99, 111, 110, 115, 111, 110, 97, 110, 116, 115, 32, 49, 53, 48, 32, 49, 53, 48, 10, 98, 114, 101, 97, 116, 104, 119, 32, 49, 53, 48, 32, 49, 53, 48, 32, 50, 48, 48, 32, 50, 48, 48, 32, 52, 48, 48, 32, 52, 48, 48, 32, 10, 0}; autoFileInMemory espeakdata_variants6 = FileInMemory_createWithData (425, reinterpret_cast (&espeakdata_variants6_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/!v/f5", U"f5"); Collection_addItem (me.peek(), espeakdata_variants6.transfer()); static unsigned char espeakdata_variants7_data[39] = { 108, 97, 110, 103, 117, 97, 103, 101, 32, 118, 97, 114, 105, 97, 110, 116, 10, 110, 97, 109, 101, 32, 107, 108, 97, 116, 116, 10, 107, 108, 97, 116, 116, 32, 49, 10, 32, 10, 0}; autoFileInMemory espeakdata_variants7 = FileInMemory_createWithData (38, reinterpret_cast (&espeakdata_variants7_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/!v/klatt", U"klatt"); Collection_addItem (me.peek(), espeakdata_variants7.transfer()); static unsigned char espeakdata_variants8_data[39] = { 108, 97, 110, 103, 117, 97, 103, 101, 32, 118, 97, 114, 105, 97, 110, 116, 10, 110, 97, 109, 101, 32, 107, 108, 97, 116, 116, 50, 10, 107, 108, 97, 116, 116, 32, 50, 10, 10, 0}; autoFileInMemory espeakdata_variants8 = FileInMemory_createWithData (38, reinterpret_cast (&espeakdata_variants8_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/!v/klatt2", U"klatt2"); Collection_addItem (me.peek(), espeakdata_variants8.transfer()); static unsigned char espeakdata_variants9_data[40] = { 108, 97, 110, 103, 117, 97, 103, 101, 32, 118, 97, 114, 105, 97, 110, 116, 10, 110, 97, 109, 101, 32, 107, 108, 97, 116, 116, 51, 10, 107, 108, 97, 116, 116, 32, 51, 10, 32, 10, 0}; autoFileInMemory espeakdata_variants9 = FileInMemory_createWithData (39, reinterpret_cast (&espeakdata_variants9_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/!v/klatt3", U"klatt3"); Collection_addItem (me.peek(), espeakdata_variants9.transfer()); static unsigned char espeakdata_variants10_data[336] = { 108, 97, 110, 103, 117, 97, 103, 101, 32, 118, 97, 114, 105, 97, 110, 116, 10, 110, 97, 109, 101, 32, 109, 97, 108, 101, 49, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 32, 55, 48, 10, 10, 112, 105, 116, 99, 104, 32, 55, 53, 32, 49, 48, 57, 10, 102, 108, 117, 116, 116, 101, 114, 32, 53, 10, 114, 111, 117, 103, 104, 110, 101, 115, 115, 32, 52, 10, 99, 111, 110, 115, 111, 110, 97, 110, 116, 115, 32, 56, 48, 32, 49, 48, 48, 10, 10, 102, 111, 114, 109, 97, 110, 116, 32, 48, 32, 32, 57, 56, 32, 49, 48, 48, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 49, 32, 32, 57, 55, 32, 49, 48, 48, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 50, 32, 32, 57, 55, 32, 32, 57, 53, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 51, 32, 32, 57, 55, 32, 32, 57, 53, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 52, 32, 32, 57, 55, 32, 32, 56, 53, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 53, 32, 49, 48, 53, 32, 32, 56, 48, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 54, 32, 32, 57, 53, 32, 32, 56, 48, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 55, 32, 49, 48, 48, 32, 49, 48, 48, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 56, 32, 49, 48, 48, 32, 49, 48, 48, 32, 49, 48, 48, 10, 10, 47, 47, 115, 116, 114, 101, 115, 115, 65, 100, 100, 32, 45, 49, 48, 32, 45, 49, 48, 32, 45, 50, 48, 32, 45, 50, 48, 32, 48, 32, 48, 32, 52, 48, 32, 55, 48, 10, 0}; autoFileInMemory espeakdata_variants10 = FileInMemory_createWithData (335, reinterpret_cast (&espeakdata_variants10_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/!v/m1", U"m1"); Collection_addItem (me.peek(), espeakdata_variants10.transfer()); static unsigned char espeakdata_variants11_data[265] = { 108, 97, 110, 103, 117, 97, 103, 101, 32, 118, 97, 114, 105, 97, 110, 116, 10, 110, 97, 109, 101, 32, 109, 97, 108, 101, 50, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 112, 105, 116, 99, 104, 32, 56, 56, 32, 49, 49, 53, 10, 101, 99, 104, 111, 32, 49, 51, 48, 32, 49, 53, 10, 102, 111, 114, 109, 97, 110, 116, 32, 48, 32, 49, 48, 48, 32, 32, 56, 48, 32, 49, 50, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 49, 32, 32, 57, 48, 32, 32, 56, 53, 32, 49, 50, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 50, 32, 49, 49, 48, 32, 32, 56, 53, 32, 49, 50, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 51, 32, 49, 48, 53, 32, 32, 57, 48, 32, 49, 50, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 52, 32, 49, 48, 48, 32, 32, 57, 48, 32, 49, 50, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 53, 32, 49, 48, 48, 32, 32, 57, 48, 32, 49, 50, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 54, 32, 49, 48, 48, 32, 32, 57, 48, 32, 49, 50, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 55, 32, 49, 48, 48, 32, 32, 57, 48, 32, 49, 50, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 56, 32, 49, 48, 48, 32, 32, 57, 48, 32, 49, 50, 48, 10, 0}; autoFileInMemory espeakdata_variants11 = FileInMemory_createWithData (264, reinterpret_cast (&espeakdata_variants11_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/!v/m2", U"m2"); Collection_addItem (me.peek(), espeakdata_variants11.transfer()); static unsigned char espeakdata_variants12_data[286] = { 108, 97, 110, 103, 117, 97, 103, 101, 32, 118, 97, 114, 105, 97, 110, 116, 10, 110, 97, 109, 101, 32, 109, 97, 108, 101, 51, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 112, 105, 116, 99, 104, 32, 56, 48, 32, 49, 50, 50, 10, 102, 111, 114, 109, 97, 110, 116, 32, 48, 32, 49, 48, 48, 32, 49, 48, 48, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 49, 32, 32, 57, 54, 32, 32, 57, 55, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 50, 32, 32, 57, 54, 32, 32, 57, 55, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 51, 32, 32, 57, 54, 32, 49, 48, 51, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 52, 32, 32, 57, 53, 32, 49, 48, 51, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 53, 32, 32, 57, 53, 32, 49, 48, 51, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 54, 32, 49, 48, 48, 32, 49, 48, 48, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 55, 32, 49, 48, 48, 32, 49, 48, 48, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 56, 32, 49, 48, 48, 32, 49, 48, 48, 32, 49, 48, 48, 10, 10, 115, 116, 114, 101, 115, 115, 65, 100, 100, 32, 49, 48, 32, 49, 48, 32, 48, 32, 48, 32, 48, 32, 48, 32, 45, 51, 48, 32, 45, 51, 48, 10, 0}; autoFileInMemory espeakdata_variants12 = FileInMemory_createWithData (285, reinterpret_cast (&espeakdata_variants12_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/!v/m3", U"m3"); Collection_addItem (me.peek(), espeakdata_variants12.transfer()); static unsigned char espeakdata_variants13_data[291] = { 108, 97, 110, 103, 117, 97, 103, 101, 32, 118, 97, 114, 105, 97, 110, 116, 10, 110, 97, 109, 101, 32, 109, 97, 108, 101, 52, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 112, 105, 116, 99, 104, 32, 55, 48, 32, 49, 49, 48, 10, 10, 102, 111, 114, 109, 97, 110, 116, 32, 48, 32, 49, 48, 51, 32, 49, 48, 48, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 49, 32, 49, 48, 51, 32, 49, 48, 48, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 50, 32, 49, 48, 51, 32, 49, 48, 48, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 51, 32, 49, 48, 51, 32, 49, 48, 48, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 52, 32, 49, 48, 54, 32, 49, 48, 48, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 53, 32, 49, 48, 54, 32, 49, 48, 48, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 54, 32, 49, 48, 54, 32, 49, 48, 48, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 55, 32, 49, 48, 51, 32, 49, 48, 48, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 56, 32, 49, 48, 51, 32, 49, 48, 48, 32, 49, 48, 48, 10, 10, 115, 116, 114, 101, 115, 115, 65, 100, 100, 32, 45, 49, 48, 32, 45, 49, 48, 32, 45, 51, 48, 32, 45, 51, 48, 32, 48, 32, 48, 32, 54, 48, 32, 57, 48, 10, 0}; autoFileInMemory espeakdata_variants13 = FileInMemory_createWithData (290, reinterpret_cast (&espeakdata_variants13_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/!v/m4", U"m4"); Collection_addItem (me.peek(), espeakdata_variants13.transfer()); static unsigned char espeakdata_variants14_data[263] = { 108, 97, 110, 103, 117, 97, 103, 101, 32, 118, 97, 114, 105, 97, 110, 116, 10, 110, 97, 109, 101, 32, 109, 97, 108, 101, 53, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 102, 111, 114, 109, 97, 110, 116, 32, 48, 32, 49, 48, 48, 32, 32, 56, 53, 32, 49, 51, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 49, 32, 32, 57, 48, 32, 32, 56, 53, 32, 49, 51, 48, 32, 32, 52, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 50, 32, 32, 56, 48, 32, 32, 56, 53, 32, 49, 51, 48, 32, 32, 51, 49, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 51, 32, 49, 48, 53, 32, 32, 56, 53, 32, 49, 51, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 52, 32, 49, 48, 53, 32, 32, 56, 53, 32, 49, 51, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 53, 32, 49, 48, 53, 32, 32, 56, 53, 32, 49, 51, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 54, 32, 49, 48, 53, 32, 32, 56, 53, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 55, 32, 49, 48, 53, 32, 32, 56, 53, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 56, 32, 49, 48, 53, 32, 32, 56, 53, 32, 49, 53, 48, 10, 10, 105, 110, 116, 111, 110, 97, 116, 105, 111, 110, 32, 50, 10, 0}; autoFileInMemory espeakdata_variants14 = FileInMemory_createWithData (262, reinterpret_cast (&espeakdata_variants14_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/!v/m5", U"m5"); Collection_addItem (me.peek(), espeakdata_variants14.transfer()); static unsigned char espeakdata_variants15_data[189] = { 108, 97, 110, 103, 117, 97, 103, 101, 32, 118, 97, 114, 105, 97, 110, 116, 10, 110, 97, 109, 101, 32, 109, 97, 108, 101, 54, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 112, 105, 116, 99, 104, 32, 56, 50, 32, 49, 49, 55, 10, 10, 102, 111, 114, 109, 97, 110, 116, 32, 48, 32, 49, 48, 48, 32, 32, 57, 48, 32, 49, 50, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 49, 32, 49, 48, 48, 32, 32, 57, 48, 32, 49, 52, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 50, 32, 49, 48, 48, 32, 32, 55, 48, 32, 49, 52, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 51, 32, 49, 48, 48, 32, 32, 55, 53, 32, 49, 52, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 52, 32, 49, 48, 48, 32, 32, 56, 48, 32, 49, 52, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 53, 32, 49, 48, 48, 32, 32, 56, 48, 32, 49, 52, 48, 10, 10, 0}; autoFileInMemory espeakdata_variants15 = FileInMemory_createWithData (188, reinterpret_cast (&espeakdata_variants15_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/!v/m6", U"m6"); Collection_addItem (me.peek(), espeakdata_variants15.transfer()); static unsigned char espeakdata_variants16_data[255] = { 108, 97, 110, 103, 117, 97, 103, 101, 32, 118, 97, 114, 105, 97, 110, 116, 10, 110, 97, 109, 101, 32, 109, 97, 108, 101, 55, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 112, 105, 116, 99, 104, 32, 32, 55, 53, 32, 49, 50, 53, 10, 10, 102, 111, 114, 109, 97, 110, 116, 32, 48, 32, 49, 48, 48, 32, 49, 50, 53, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 49, 32, 49, 48, 48, 32, 57, 48, 32, 56, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 50, 32, 49, 48, 48, 32, 55, 48, 32, 57, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 51, 32, 49, 48, 48, 32, 54, 48, 32, 57, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 52, 32, 49, 48, 48, 32, 54, 48, 32, 57, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 53, 32, 32, 55, 53, 32, 53, 48, 32, 57, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 54, 32, 32, 57, 48, 32, 53, 48, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 55, 32, 49, 48, 48, 32, 53, 48, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 56, 32, 49, 48, 48, 32, 53, 48, 32, 49, 48, 48, 10, 118, 111, 105, 99, 105, 110, 103, 32, 49, 53, 53, 10, 10, 0}; autoFileInMemory espeakdata_variants16 = FileInMemory_createWithData (254, reinterpret_cast (&espeakdata_variants16_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/!v/m7", U"m7"); Collection_addItem (me.peek(), espeakdata_variants16.transfer()); static unsigned char espeakdata_variants17_data[187] = { 108, 97, 110, 103, 117, 97, 103, 101, 32, 118, 97, 114, 105, 97, 110, 116, 10, 110, 97, 109, 101, 32, 119, 104, 105, 115, 112, 101, 114, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 112, 105, 116, 99, 104, 32, 56, 50, 32, 49, 49, 55, 10, 102, 108, 117, 116, 116, 101, 114, 32, 50, 48, 10, 10, 102, 111, 114, 109, 97, 110, 116, 32, 48, 32, 49, 48, 48, 32, 32, 48, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 49, 32, 49, 48, 48, 32, 56, 48, 32, 49, 48, 48, 10, 10, 118, 111, 105, 99, 105, 110, 103, 32, 49, 55, 10, 98, 114, 101, 97, 116, 104, 32, 32, 32, 55, 53, 32, 32, 55, 53, 32, 32, 53, 48, 32, 32, 52, 48, 32, 32, 49, 53, 32, 32, 49, 48, 10, 98, 114, 101, 97, 116, 104, 119, 32, 49, 53, 48, 32, 49, 53, 48, 32, 50, 48, 48, 32, 50, 48, 48, 32, 52, 48, 48, 32, 52, 48, 48, 10, 0}; autoFileInMemory espeakdata_variants17 = FileInMemory_createWithData (186, reinterpret_cast (&espeakdata_variants17_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/!v/whisper", U"whisper"); Collection_addItem (me.peek(), espeakdata_variants17.transfer()); static unsigned char espeakdata_variants18_data[393] = { 108, 97, 110, 103, 117, 97, 103, 101, 32, 118, 97, 114, 105, 97, 110, 116, 10, 110, 97, 109, 101, 32, 102, 101, 109, 97, 108, 101, 95, 119, 104, 105, 115, 112, 101, 114, 10, 103, 101, 110, 100, 101, 114, 32, 102, 101, 109, 97, 108, 101, 10, 10, 112, 105, 116, 99, 104, 32, 49, 54, 48, 32, 50, 50, 48, 10, 114, 111, 117, 103, 104, 110, 101, 115, 115, 32, 51, 10, 10, 102, 111, 114, 109, 97, 110, 116, 32, 48, 32, 49, 48, 53, 32, 32, 32, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 49, 32, 49, 49, 48, 32, 32, 52, 48, 32, 49, 54, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 50, 32, 49, 49, 48, 32, 32, 55, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 51, 32, 49, 49, 48, 32, 32, 55, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 52, 32, 49, 49, 53, 32, 32, 56, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 53, 32, 49, 49, 53, 32, 32, 56, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 54, 32, 49, 49, 48, 32, 32, 55, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 55, 32, 49, 49, 48, 32, 32, 55, 48, 32, 49, 53, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 56, 32, 49, 49, 48, 32, 32, 55, 48, 32, 49, 53, 48, 10, 10, 115, 116, 114, 101, 115, 115, 65, 100, 100, 32, 48, 32, 48, 32, 45, 49, 48, 32, 45, 49, 48, 32, 48, 32, 48, 32, 49, 48, 32, 52, 48, 10, 10, 47, 47, 32, 119, 104, 105, 115, 112, 101, 114, 10, 118, 111, 105, 99, 105, 110, 103, 32, 50, 48, 10, 98, 114, 101, 97, 116, 104, 32, 55, 53, 32, 55, 53, 32, 53, 48, 32, 52, 48, 32, 49, 53, 32, 49, 48, 10, 98, 114, 101, 97, 116, 104, 119, 32, 49, 53, 48, 32, 49, 53, 48, 32, 50, 48, 48, 32, 50, 48, 48, 32, 52, 48, 48, 32, 52, 48, 48, 10, 32, 10, 0}; autoFileInMemory espeakdata_variants18 = FileInMemory_createWithData (392, reinterpret_cast (&espeakdata_variants18_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/!v/whisperf", U"whisperf"); Collection_addItem (me.peek(), espeakdata_variants18.transfer()); return me.transfer(); } catch (MelderError) { Melder_throw (U"FilesInMemory not created."); } } praat-6.0.04/external/espeak/espeakdata_voices.cpp000066400000000000000000002027771261542461700222070ustar00rootroot00000000000000/* File espeakdata_voices.cpp was generated automatically on Sun Nov 4 17:43:38 2012 from files in espeak-data/voices */ #include "espeakdata_FileInMemory.h" #include "Collection.h" #include "FileInMemory.h" #include "melder.h" FilesInMemory create_espeakdata_voices () { try { autoFilesInMemory me = FilesInMemory_create (); static unsigned char espeakdata_voices1_data[68] = { 110, 97, 109, 101, 32, 97, 102, 114, 105, 107, 97, 97, 110, 115, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 97, 102, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 114, 111, 117, 103, 104, 110, 101, 115, 115, 32, 48, 10, 112, 105, 116, 99, 104, 32, 54, 51, 32, 49, 50, 48, 10, 10, 10, 10, 0}; autoFileInMemory espeakdata_voices1 = FileInMemory_createWithData (67, reinterpret_cast (&espeakdata_voices1_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//af", U"af"); Collection_addItem (me.peek(), espeakdata_voices1.transfer()); static unsigned char espeakdata_voices2_data[116] = { 110, 97, 109, 101, 32, 98, 117, 108, 103, 97, 114, 105, 97, 110, 45, 116, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 98, 103, 10, 10, 115, 116, 114, 101, 115, 115, 65, 109, 112, 32, 49, 51, 32, 49, 50, 32, 49, 55, 32, 49, 55, 32, 50, 48, 32, 50, 50, 32, 50, 50, 32, 50, 49, 32, 10, 115, 116, 114, 101, 115, 115, 76, 101, 110, 103, 116, 104, 32, 49, 56, 48, 32, 49, 55, 48, 32, 32, 50, 48, 48, 32, 50, 48, 48, 32, 32, 50, 48, 48, 32, 50, 48, 48, 32, 32, 50, 49, 48, 32, 50, 50, 48, 0}; autoFileInMemory espeakdata_voices2 = FileInMemory_createWithData (115, reinterpret_cast (&espeakdata_voices2_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//bg", U"bg"); Collection_addItem (me.peek(), espeakdata_voices2.transfer()); static unsigned char espeakdata_voices3_data[258] = { 110, 97, 109, 101, 32, 98, 111, 115, 110, 105, 97, 110, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 98, 115, 10, 112, 104, 111, 110, 101, 109, 101, 115, 32, 104, 114, 10, 100, 105, 99, 116, 105, 111, 110, 97, 114, 121, 32, 104, 98, 115, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 112, 105, 116, 99, 104, 32, 56, 49, 32, 49, 50, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 48, 32, 49, 48, 48, 32, 49, 48, 48, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 49, 32, 32, 57, 55, 32, 32, 57, 55, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 50, 32, 32, 57, 55, 32, 32, 57, 55, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 51, 32, 32, 57, 55, 32, 49, 48, 50, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 52, 32, 32, 57, 55, 32, 49, 48, 50, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 53, 32, 32, 57, 55, 32, 49, 48, 50, 32, 49, 48, 48, 10, 10, 115, 116, 114, 101, 115, 115, 65, 100, 100, 32, 49, 48, 32, 49, 48, 32, 48, 32, 48, 32, 48, 32, 48, 32, 45, 51, 48, 32, 45, 51, 48, 10, 100, 105, 99, 116, 114, 117, 108, 101, 115, 32, 51, 32, 52, 10, 0}; autoFileInMemory espeakdata_voices3 = FileInMemory_createWithData (257, reinterpret_cast (&espeakdata_voices3_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//bs", U"bs"); Collection_addItem (me.peek(), espeakdata_voices3.transfer()); static unsigned char espeakdata_voices4_data[39] = { 110, 97, 109, 101, 32, 99, 97, 116, 97, 108, 97, 110, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 99, 97, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 0}; autoFileInMemory espeakdata_voices4 = FileInMemory_createWithData (38, reinterpret_cast (&espeakdata_voices4_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//ca", U"ca"); Collection_addItem (me.peek(), espeakdata_voices4.transfer()); static unsigned char espeakdata_voices5_data[37] = { 110, 97, 109, 101, 32, 99, 122, 101, 99, 104, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 99, 115, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 0}; autoFileInMemory espeakdata_voices5 = FileInMemory_createWithData (36, reinterpret_cast (&espeakdata_voices5_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//cs", U"cs"); Collection_addItem (me.peek(), espeakdata_voices5.transfer()); static unsigned char espeakdata_voices6_data[55] = { 108, 97, 110, 103, 117, 97, 103, 101, 32, 99, 121, 10, 110, 97, 109, 101, 32, 119, 101, 108, 115, 104, 45, 116, 101, 115, 116, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 105, 110, 116, 111, 110, 97, 116, 105, 111, 110, 32, 52, 10, 0}; autoFileInMemory espeakdata_voices6 = FileInMemory_createWithData (54, reinterpret_cast (&espeakdata_voices6_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//cy", U"cy"); Collection_addItem (me.peek(), espeakdata_voices6.transfer()); static unsigned char espeakdata_voices7_data[58] = { 110, 97, 109, 101, 32, 100, 97, 110, 105, 115, 104, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 100, 97, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 116, 117, 110, 101, 115, 32, 115, 50, 32, 99, 50, 32, 113, 50, 32, 101, 50, 10, 10, 10, 0}; autoFileInMemory espeakdata_voices7 = FileInMemory_createWithData (57, reinterpret_cast (&espeakdata_voices7_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//da", U"da"); Collection_addItem (me.peek(), espeakdata_voices7.transfer()); static unsigned char espeakdata_voices8_data[39] = { 110, 97, 109, 101, 32, 103, 101, 114, 109, 97, 110, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 100, 101, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 10, 0}; autoFileInMemory espeakdata_voices8 = FileInMemory_createWithData (38, reinterpret_cast (&espeakdata_voices8_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//de", U"de"); Collection_addItem (me.peek(), espeakdata_voices8.transfer()); static unsigned char espeakdata_voices9_data[39] = { 110, 97, 109, 101, 32, 100, 101, 102, 97, 117, 108, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 110, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 0}; autoFileInMemory espeakdata_voices9 = FileInMemory_createWithData (38, reinterpret_cast (&espeakdata_voices9_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//default", U"default"); Collection_addItem (me.peek(), espeakdata_voices9.transfer()); static unsigned char espeakdata_voices10_data[38] = { 110, 97, 109, 101, 32, 103, 114, 101, 101, 107, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 108, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 10, 0}; autoFileInMemory espeakdata_voices10 = FileInMemory_createWithData (37, reinterpret_cast (&espeakdata_voices10_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//el", U"el"); Collection_addItem (me.peek(), espeakdata_voices10.transfer()); static unsigned char espeakdata_voices11_data[40] = { 110, 97, 109, 101, 32, 101, 115, 112, 101, 114, 97, 110, 116, 111, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 111, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 0}; autoFileInMemory espeakdata_voices11 = FileInMemory_createWithData (39, reinterpret_cast (&espeakdata_voices11_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//eo", U"eo"); Collection_addItem (me.peek(), espeakdata_voices11.transfer()); static unsigned char espeakdata_voices12_data[67] = { 110, 97, 109, 101, 32, 115, 112, 97, 110, 105, 115, 104, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 115, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 100, 105, 99, 116, 114, 117, 108, 101, 115, 32, 49, 10, 47, 47, 105, 110, 116, 111, 110, 97, 116, 105, 111, 110, 32, 51, 10, 10, 0}; autoFileInMemory espeakdata_voices12 = FileInMemory_createWithData (66, reinterpret_cast (&espeakdata_voices12_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//es", U"es"); Collection_addItem (me.peek(), espeakdata_voices12.transfer()); static unsigned char espeakdata_voices13_data[188] = { 110, 97, 109, 101, 32, 115, 112, 97, 110, 105, 115, 104, 45, 108, 97, 116, 105, 110, 45, 97, 109, 101, 114, 105, 99, 97, 110, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 115, 45, 108, 97, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 115, 45, 109, 120, 32, 54, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 115, 32, 54, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 112, 104, 111, 110, 101, 109, 101, 115, 32, 101, 115, 45, 108, 97, 10, 100, 105, 99, 116, 114, 117, 108, 101, 115, 32, 50, 10, 105, 110, 116, 111, 110, 97, 116, 105, 111, 110, 32, 50, 10, 115, 116, 114, 101, 115, 115, 76, 101, 110, 103, 116, 104, 32, 49, 55, 48, 32, 50, 48, 48, 32, 32, 50, 51, 48, 32, 49, 56, 48, 32, 32, 48, 32, 48, 32, 32, 50, 53, 48, 32, 50, 56, 48, 10, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 48, 32, 84, 32, 115, 10, 0}; autoFileInMemory espeakdata_voices13 = FileInMemory_createWithData (187, reinterpret_cast (&espeakdata_voices13_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//es-la", U"es-la"); Collection_addItem (me.peek(), espeakdata_voices13.transfer()); static unsigned char espeakdata_voices14_data[28] = { 110, 97, 109, 101, 32, 101, 115, 116, 111, 110, 105, 97, 110, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 116, 10, 10, 0}; autoFileInMemory espeakdata_voices14 = FileInMemory_createWithData (27, reinterpret_cast (&espeakdata_voices14_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//et", U"et"); Collection_addItem (me.peek(), espeakdata_voices14.transfer()); static unsigned char espeakdata_voices15_data[39] = { 110, 97, 109, 101, 32, 102, 105, 110, 110, 105, 115, 104, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 102, 105, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 0}; autoFileInMemory espeakdata_voices15 = FileInMemory_createWithData (38, reinterpret_cast (&espeakdata_voices15_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//fi", U"fi"); Collection_addItem (me.peek(), espeakdata_voices15.transfer()); static unsigned char espeakdata_voices16_data[83] = { 110, 97, 109, 101, 32, 102, 114, 101, 110, 99, 104, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 102, 114, 45, 102, 114, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 102, 114, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 100, 105, 99, 116, 114, 117, 108, 101, 115, 32, 49, 10, 116, 117, 110, 101, 115, 32, 115, 51, 32, 99, 51, 32, 113, 51, 32, 101, 51, 10, 0}; autoFileInMemory espeakdata_voices16 = FileInMemory_createWithData (82, reinterpret_cast (&espeakdata_voices16_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//fr", U"fr"); Collection_addItem (me.peek(), espeakdata_voices16.transfer()); static unsigned char espeakdata_voices17_data[97] = { 110, 97, 109, 101, 32, 102, 114, 101, 110, 99, 104, 32, 40, 66, 101, 108, 103, 105, 117, 109, 41, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 102, 114, 45, 98, 101, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 102, 114, 32, 56, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 100, 105, 99, 116, 114, 117, 108, 101, 115, 32, 50, 10, 116, 117, 110, 101, 115, 32, 115, 51, 32, 99, 51, 32, 113, 51, 32, 101, 51, 10, 10, 10, 0}; autoFileInMemory espeakdata_voices17 = FileInMemory_createWithData (96, reinterpret_cast (&espeakdata_voices17_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//fr-be", U"fr-be"); Collection_addItem (me.peek(), espeakdata_voices17.transfer()); static unsigned char espeakdata_voices18_data[36] = { 110, 97, 109, 101, 32, 104, 105, 110, 100, 105, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 104, 105, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 0}; autoFileInMemory espeakdata_voices18 = FileInMemory_createWithData (35, reinterpret_cast (&espeakdata_voices18_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//hi", U"hi"); Collection_addItem (me.peek(), espeakdata_voices18.transfer()); static unsigned char espeakdata_voices19_data[291] = { 110, 97, 109, 101, 32, 99, 114, 111, 97, 116, 105, 97, 110, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 104, 114, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 104, 98, 115, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 100, 105, 99, 116, 105, 111, 110, 97, 114, 121, 32, 104, 98, 115, 10, 10, 47, 47, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 115, 32, 116, 111, 119, 97, 114, 100, 115, 32, 33, 118, 97, 114, 105, 97, 110, 116, 51, 10, 112, 105, 116, 99, 104, 32, 56, 49, 32, 49, 50, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 48, 32, 49, 48, 48, 32, 49, 48, 48, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 49, 32, 32, 57, 55, 32, 32, 57, 55, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 50, 32, 32, 57, 55, 32, 32, 57, 55, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 51, 32, 32, 57, 55, 32, 49, 48, 50, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 52, 32, 32, 57, 55, 32, 49, 48, 50, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 53, 32, 32, 57, 55, 32, 49, 48, 50, 32, 49, 48, 48, 10, 10, 115, 116, 114, 101, 115, 115, 65, 100, 100, 32, 49, 48, 32, 49, 48, 32, 48, 32, 48, 32, 48, 32, 48, 32, 45, 51, 48, 32, 45, 51, 48, 10, 100, 105, 99, 116, 114, 117, 108, 101, 115, 32, 49, 10, 0}; autoFileInMemory espeakdata_voices19 = FileInMemory_createWithData (290, reinterpret_cast (&espeakdata_voices19_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//hr", U"hr"); Collection_addItem (me.peek(), espeakdata_voices19.transfer()); static unsigned char espeakdata_voices20_data[74] = { 110, 97, 109, 101, 32, 104, 117, 110, 103, 97, 114, 105, 97, 110, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 104, 117, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 111, 112, 116, 105, 111, 110, 32, 98, 114, 97, 99, 107, 101, 116, 32, 48, 32, 48, 10, 112, 105, 116, 99, 104, 32, 56, 49, 32, 49, 49, 55, 10, 10, 10, 0}; autoFileInMemory espeakdata_voices20 = FileInMemory_createWithData (73, reinterpret_cast (&espeakdata_voices20_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//hu", U"hu"); Collection_addItem (me.peek(), espeakdata_voices20.transfer()); static unsigned char espeakdata_voices21_data[39] = { 110, 97, 109, 101, 32, 97, 114, 109, 101, 110, 105, 97, 110, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 104, 121, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 0}; autoFileInMemory espeakdata_voices21 = FileInMemory_createWithData (38, reinterpret_cast (&espeakdata_voices21_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//hy", U"hy"); Collection_addItem (me.peek(), espeakdata_voices21.transfer()); static unsigned char espeakdata_voices22_data[327] = { 110, 97, 109, 101, 32, 97, 114, 109, 101, 110, 105, 97, 110, 45, 119, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 104, 121, 45, 119, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 104, 121, 32, 32, 56, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 47, 47, 32, 99, 104, 97, 110, 103, 101, 32, 99, 111, 110, 115, 111, 110, 97, 110, 116, 115, 32, 102, 111, 114, 32, 87, 101, 115, 116, 32, 65, 114, 109, 101, 110, 105, 97, 110, 32, 112, 114, 111, 110, 117, 110, 99, 105, 97, 116, 105, 111, 110, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 48, 32, 98, 32, 32, 112, 35, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 48, 32, 100, 32, 32, 116, 35, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 48, 32, 100, 122, 32, 116, 115, 35, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 48, 32, 100, 90, 32, 116, 83, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 48, 32, 103, 32, 32, 107, 35, 10, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 48, 32, 112, 32, 32, 98, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 48, 32, 116, 32, 32, 100, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 48, 32, 116, 115, 32, 100, 122, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 48, 32, 99, 32, 32, 100, 90, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 48, 32, 107, 32, 32, 103, 10, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 48, 32, 42, 42, 32, 82, 32, 32, 47, 47, 32, 63, 63, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 48, 32, 114, 32, 32, 82, 10, 0}; autoFileInMemory espeakdata_voices22 = FileInMemory_createWithData (326, reinterpret_cast (&espeakdata_voices22_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//hy-west", U"hy-west"); Collection_addItem (me.peek(), espeakdata_voices22.transfer()); static unsigned char espeakdata_voices23_data[152] = { 110, 97, 109, 101, 32, 105, 110, 100, 111, 110, 101, 115, 105, 97, 110, 45, 116, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 105, 100, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 115, 116, 114, 101, 115, 115, 76, 101, 110, 103, 116, 104, 32, 49, 54, 48, 32, 50, 48, 48, 32, 32, 49, 56, 48, 32, 49, 56, 48, 32, 32, 48, 32, 48, 32, 32, 50, 50, 48, 32, 50, 52, 48, 10, 115, 116, 114, 101, 115, 115, 65, 109, 112, 32, 32, 32, 32, 49, 54, 32, 32, 49, 56, 32, 32, 32, 49, 56, 32, 32, 49, 56, 32, 32, 32, 48, 32, 48, 32, 32, 50, 50, 32, 32, 50, 49, 10, 10, 99, 111, 110, 115, 111, 110, 97, 110, 116, 115, 32, 56, 48, 32, 56, 48, 10, 0}; autoFileInMemory espeakdata_voices23 = FileInMemory_createWithData (151, reinterpret_cast (&espeakdata_voices23_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//id", U"id"); Collection_addItem (me.peek(), espeakdata_voices23.transfer()); static unsigned char espeakdata_voices24_data[46] = { 110, 97, 109, 101, 32, 105, 99, 101, 108, 97, 110, 100, 105, 99, 45, 116, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 105, 115, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 0}; autoFileInMemory espeakdata_voices24 = FileInMemory_createWithData (45, reinterpret_cast (&espeakdata_voices24_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//is", U"is"); Collection_addItem (me.peek(), espeakdata_voices24.transfer()); static unsigned char espeakdata_voices25_data[55] = { 110, 97, 109, 101, 32, 105, 116, 97, 108, 105, 97, 110, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 105, 116, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 51, 32, 105, 32, 73, 10, 10, 0}; autoFileInMemory espeakdata_voices25 = FileInMemory_createWithData (54, reinterpret_cast (&espeakdata_voices25_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//it", U"it"); Collection_addItem (me.peek(), espeakdata_voices25.transfer()); static unsigned char espeakdata_voices26_data[32] = { 110, 97, 109, 101, 32, 103, 101, 111, 114, 103, 105, 97, 110, 45, 116, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 107, 97, 10, 0}; autoFileInMemory espeakdata_voices26 = FileInMemory_createWithData (31, reinterpret_cast (&espeakdata_voices26_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//ka", U"ka"); Collection_addItem (me.peek(), espeakdata_voices26.transfer()); static unsigned char espeakdata_voices27_data[56] = { 110, 97, 109, 101, 32, 107, 97, 110, 110, 97, 100, 97, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 107, 110, 10, 10, 105, 110, 116, 111, 110, 97, 116, 105, 111, 110, 32, 50, 10, 47, 47, 99, 111, 110, 115, 111, 110, 97, 110, 116, 115, 32, 56, 48, 10, 0}; autoFileInMemory espeakdata_voices27 = FileInMemory_createWithData (55, reinterpret_cast (&espeakdata_voices27_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//kn", U"kn"); Collection_addItem (me.peek(), espeakdata_voices27.transfer()); static unsigned char espeakdata_voices28_data[53] = { 110, 97, 109, 101, 32, 107, 117, 114, 100, 105, 115, 104, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 107, 117, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 47, 47, 119, 111, 114, 100, 115, 32, 49, 32, 52, 56, 10, 10, 0}; autoFileInMemory espeakdata_voices28 = FileInMemory_createWithData (52, reinterpret_cast (&espeakdata_voices28_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//ku", U"ku"); Collection_addItem (me.peek(), espeakdata_voices28.transfer()); static unsigned char espeakdata_voices29_data[299] = { 110, 97, 109, 101, 32, 108, 97, 116, 105, 110, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 108, 97, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 115, 116, 114, 101, 115, 115, 114, 117, 108, 101, 32, 50, 32, 51, 51, 32, 48, 32, 50, 10, 47, 47, 32, 114, 117, 108, 101, 61, 112, 101, 110, 117, 108, 116, 105, 109, 97, 116, 101, 10, 47, 47, 32, 102, 108, 97, 103, 115, 61, 48, 49, 48, 48, 48, 48, 49, 32, 40, 110, 111, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 32, 115, 101, 99, 111, 110, 100, 97, 114, 121, 32, 115, 116, 114, 101, 115, 115, 32, 43, 32, 100, 111, 110, 39, 116, 32, 115, 116, 114, 101, 115, 32, 109, 111, 110, 111, 115, 121, 108, 108, 97, 98, 108, 101, 115, 41, 10, 47, 47, 32, 117, 110, 115, 116, 114, 101, 115, 115, 101, 100, 95, 119, 100, 49, 61, 48, 10, 47, 47, 32, 117, 110, 115, 116, 114, 101, 115, 115, 101, 100, 95, 119, 100, 50, 61, 50, 10, 10, 47, 47, 32, 115, 104, 111, 114, 116, 32, 103, 97, 112, 32, 98, 101, 116, 119, 101, 101, 110, 32, 119, 111, 114, 100, 115, 10, 119, 111, 114, 100, 115, 32, 50, 10, 10, 47, 47, 32, 78, 111, 116, 101, 58, 32, 84, 104, 101, 32, 76, 97, 116, 105, 110, 32, 118, 111, 105, 99, 101, 32, 110, 101, 101, 100, 115, 32, 108, 111, 110, 103, 32, 118, 111, 119, 101, 108, 115, 32, 116, 111, 32, 98, 101, 32, 109, 97, 114, 107, 101, 100, 32, 119, 105, 116, 104, 32, 109, 97, 99, 114, 111, 110, 115, 10, 0}; autoFileInMemory espeakdata_voices29 = FileInMemory_createWithData (298, reinterpret_cast (&espeakdata_voices29_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//la", U"la"); Collection_addItem (me.peek(), espeakdata_voices29.transfer()); static unsigned char espeakdata_voices30_data[58] = { 110, 97, 109, 101, 32, 108, 97, 116, 118, 105, 97, 110, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 108, 118, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 51, 32, 32, 111, 32, 32, 111, 58, 10, 10, 0}; autoFileInMemory espeakdata_voices30 = FileInMemory_createWithData (57, reinterpret_cast (&espeakdata_voices30_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//lv", U"lv"); Collection_addItem (me.peek(), espeakdata_voices30.transfer()); static unsigned char espeakdata_voices31_data[47] = { 110, 97, 109, 101, 32, 109, 97, 99, 101, 100, 111, 110, 105, 97, 110, 45, 116, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 109, 107, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 0}; autoFileInMemory espeakdata_voices31 = FileInMemory_createWithData (46, reinterpret_cast (&espeakdata_voices31_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//mk", U"mk"); Collection_addItem (me.peek(), espeakdata_voices31.transfer()); static unsigned char espeakdata_voices32_data[70] = { 110, 97, 109, 101, 32, 109, 97, 108, 97, 121, 97, 108, 97, 109, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 109, 108, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 105, 110, 116, 111, 110, 97, 116, 105, 111, 110, 32, 50, 10, 47, 47, 99, 111, 110, 115, 111, 110, 97, 110, 116, 115, 32, 56, 48, 10, 0}; autoFileInMemory espeakdata_voices32 = FileInMemory_createWithData (69, reinterpret_cast (&espeakdata_voices32_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//ml", U"ml"); Collection_addItem (me.peek(), espeakdata_voices32.transfer()); static unsigned char espeakdata_voices33_data[41] = { 108, 97, 110, 103, 117, 97, 103, 101, 32, 110, 108, 10, 110, 97, 109, 101, 32, 100, 117, 116, 99, 104, 45, 116, 101, 115, 116, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 0}; autoFileInMemory espeakdata_voices33 = FileInMemory_createWithData (40, reinterpret_cast (&espeakdata_voices33_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//nl", U"nl"); Collection_addItem (me.peek(), espeakdata_voices33.transfer()); static unsigned char espeakdata_voices34_data[66] = { 110, 97, 109, 101, 32, 110, 111, 114, 119, 101, 103, 105, 97, 110, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 110, 111, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 110, 98, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 105, 110, 116, 111, 110, 97, 116, 105, 111, 110, 32, 52, 10, 0}; autoFileInMemory espeakdata_voices34 = FileInMemory_createWithData (65, reinterpret_cast (&espeakdata_voices34_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//no", U"no"); Collection_addItem (me.peek(), espeakdata_voices34.transfer()); static unsigned char espeakdata_voices35_data[51] = { 110, 97, 109, 101, 32, 112, 111, 108, 105, 115, 104, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 112, 108, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 105, 110, 116, 111, 110, 97, 116, 105, 111, 110, 32, 50, 10, 0}; autoFileInMemory espeakdata_voices35 = FileInMemory_createWithData (50, reinterpret_cast (&espeakdata_voices35_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//pl", U"pl"); Collection_addItem (me.peek(), espeakdata_voices35.transfer()); static unsigned char espeakdata_voices36_data[66] = { 110, 97, 109, 101, 32, 98, 114, 97, 122, 105, 108, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 112, 116, 45, 98, 114, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 112, 116, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 100, 105, 99, 116, 114, 117, 108, 101, 115, 32, 50, 10, 10, 0}; autoFileInMemory espeakdata_voices36 = FileInMemory_createWithData (65, reinterpret_cast (&espeakdata_voices36_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//pt", U"pt"); Collection_addItem (me.peek(), espeakdata_voices36.transfer()); static unsigned char espeakdata_voices37_data[97] = { 110, 97, 109, 101, 32, 112, 111, 114, 116, 117, 103, 97, 108, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 112, 116, 45, 112, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 112, 116, 32, 54, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 112, 104, 111, 110, 101, 109, 101, 115, 32, 112, 116, 45, 112, 116, 10, 10, 100, 105, 99, 116, 114, 117, 108, 101, 115, 32, 49, 10, 105, 110, 116, 111, 110, 97, 116, 105, 111, 110, 32, 50, 10, 0}; autoFileInMemory espeakdata_voices37 = FileInMemory_createWithData (96, reinterpret_cast (&espeakdata_voices37_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//pt-pt", U"pt-pt"); Collection_addItem (me.peek(), espeakdata_voices37.transfer()); static unsigned char espeakdata_voices38_data[41] = { 110, 97, 109, 101, 32, 114, 111, 109, 97, 110, 105, 97, 110, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 114, 111, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 10, 0}; autoFileInMemory espeakdata_voices38 = FileInMemory_createWithData (40, reinterpret_cast (&espeakdata_voices38_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//ro", U"ro"); Collection_addItem (me.peek(), espeakdata_voices38.transfer()); static unsigned char espeakdata_voices39_data[61] = { 110, 97, 109, 101, 32, 114, 117, 115, 115, 105, 97, 110, 95, 116, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 114, 117, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 51, 32, 97, 32, 97, 35, 10, 10, 0}; autoFileInMemory espeakdata_voices39 = FileInMemory_createWithData (60, reinterpret_cast (&espeakdata_voices39_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//ru", U"ru"); Collection_addItem (me.peek(), espeakdata_voices39.transfer()); static unsigned char espeakdata_voices40_data[38] = { 110, 97, 109, 101, 32, 115, 108, 111, 118, 97, 107, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 115, 107, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 0}; autoFileInMemory espeakdata_voices40 = FileInMemory_createWithData (37, reinterpret_cast (&espeakdata_voices40_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//sk", U"sk"); Collection_addItem (me.peek(), espeakdata_voices40.transfer()); static unsigned char espeakdata_voices41_data[116] = { 110, 97, 109, 101, 32, 97, 108, 98, 97, 110, 105, 97, 110, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 115, 113, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 47, 47, 32, 97, 100, 100, 32, 116, 104, 105, 115, 32, 108, 105, 110, 101, 32, 116, 111, 32, 114, 101, 109, 111, 118, 101, 32, 39, 195, 171, 39, 32, 97, 116, 32, 116, 104, 101, 32, 101, 110, 100, 32, 111, 102, 32, 119, 111, 114, 100, 115, 10, 47, 47, 32, 114, 101, 112, 108, 97, 99, 101, 32, 48, 48, 32, 32, 64, 47, 32, 32, 78, 85, 76, 76, 10, 0}; autoFileInMemory espeakdata_voices41 = FileInMemory_createWithData (115, reinterpret_cast (&espeakdata_voices41_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//sq", U"sq"); Collection_addItem (me.peek(), espeakdata_voices41.transfer()); static unsigned char espeakdata_voices42_data[278] = { 110, 97, 109, 101, 32, 115, 101, 114, 98, 105, 97, 110, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 115, 114, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 100, 105, 99, 116, 105, 111, 110, 97, 114, 121, 32, 104, 98, 115, 10, 10, 47, 47, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 115, 32, 116, 111, 119, 97, 114, 100, 115, 32, 33, 118, 97, 114, 105, 97, 110, 116, 51, 32, 112, 105, 116, 99, 104, 32, 56, 48, 32, 49, 50, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 48, 32, 49, 48, 48, 32, 49, 48, 48, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 49, 32, 32, 57, 55, 32, 32, 57, 55, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 50, 32, 32, 57, 55, 32, 32, 57, 55, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 51, 32, 32, 57, 55, 32, 49, 48, 50, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 52, 32, 32, 57, 55, 32, 49, 48, 50, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 53, 32, 32, 57, 55, 32, 49, 48, 50, 32, 49, 48, 48, 10, 10, 115, 116, 114, 101, 115, 115, 65, 100, 100, 32, 49, 48, 32, 49, 48, 32, 48, 32, 48, 32, 48, 32, 48, 32, 45, 51, 48, 32, 45, 51, 48, 10, 100, 105, 99, 116, 114, 117, 108, 101, 115, 32, 50, 32, 52, 10, 0}; autoFileInMemory espeakdata_voices42 = FileInMemory_createWithData (277, reinterpret_cast (&espeakdata_voices42_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//sr", U"sr"); Collection_addItem (me.peek(), espeakdata_voices42.transfer()); static unsigned char espeakdata_voices43_data[39] = { 110, 97, 109, 101, 32, 115, 119, 101, 100, 105, 115, 104, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 115, 118, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 0}; autoFileInMemory espeakdata_voices43 = FileInMemory_createWithData (38, reinterpret_cast (&espeakdata_voices43_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//sv", U"sv"); Collection_addItem (me.peek(), espeakdata_voices43.transfer()); static unsigned char espeakdata_voices44_data[44] = { 110, 97, 109, 101, 32, 115, 119, 97, 104, 105, 108, 105, 45, 116, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 115, 119, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 0}; autoFileInMemory espeakdata_voices44 = FileInMemory_createWithData (43, reinterpret_cast (&espeakdata_voices44_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//sw", U"sw"); Collection_addItem (me.peek(), espeakdata_voices44.transfer()); static unsigned char espeakdata_voices45_data[64] = { 110, 97, 109, 101, 32, 116, 97, 109, 105, 108, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 116, 97, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 105, 110, 116, 111, 110, 97, 116, 105, 111, 110, 32, 50, 10, 99, 111, 110, 115, 111, 110, 97, 110, 116, 115, 32, 56, 48, 10, 0}; autoFileInMemory espeakdata_voices45 = FileInMemory_createWithData (63, reinterpret_cast (&espeakdata_voices45_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//ta", U"ta"); Collection_addItem (me.peek(), espeakdata_voices45.transfer()); static unsigned char espeakdata_voices46_data[39] = { 110, 97, 109, 101, 32, 116, 117, 114, 107, 105, 115, 104, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 116, 114, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 0}; autoFileInMemory espeakdata_voices46 = FileInMemory_createWithData (38, reinterpret_cast (&espeakdata_voices46_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//tr", U"tr"); Collection_addItem (me.peek(), espeakdata_voices46.transfer()); static unsigned char espeakdata_voices47_data[60] = { 110, 97, 109, 101, 32, 118, 105, 101, 116, 110, 97, 109, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 118, 105, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 119, 111, 114, 100, 115, 32, 49, 10, 112, 105, 116, 99, 104, 32, 56, 48, 32, 49, 49, 56, 10, 0}; autoFileInMemory espeakdata_voices47 = FileInMemory_createWithData (59, reinterpret_cast (&espeakdata_voices47_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//vi", U"vi"); Collection_addItem (me.peek(), espeakdata_voices47.transfer()); static unsigned char espeakdata_voices48_data[595] = { 110, 97, 109, 101, 32, 77, 97, 110, 100, 97, 114, 105, 110, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 122, 104, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 119, 111, 114, 100, 115, 32, 49, 10, 112, 105, 116, 99, 104, 32, 56, 48, 32, 49, 49, 56, 10, 10, 47, 47, 102, 111, 114, 32, 115, 111, 109, 101, 32, 100, 105, 97, 108, 101, 99, 116, 115, 10, 10, 47, 47, 91, 101, 110, 93, 58, 32, 114, 101, 112, 108, 97, 99, 101, 32, 110, 103, 32, 119, 105, 116, 104, 32, 110, 10, 47, 47, 91, 122, 104, 93, 58, 32, 239, 191, 189, 222, 186, 239, 191, 189, 239, 191, 189, 239, 191, 189, 239, 191, 189, 239, 191, 189, 239, 191, 189, 239, 191, 189, 110, 103, 239, 191, 189, 239, 191, 189, 239, 191, 189, 110, 10, 47, 47, 114, 101, 112, 108, 97, 99, 101, 32, 48, 32, 78, 32, 110, 10, 10, 47, 47, 91, 101, 110, 93, 58, 32, 114, 101, 112, 108, 97, 99, 101, 32, 114, 102, 120, 32, 99, 111, 110, 115, 111, 110, 97, 110, 116, 115, 10, 47, 47, 91, 122, 104, 93, 58, 32, 239, 191, 189, 222, 190, 239, 191, 189, 239, 191, 189, 239, 191, 189, 239, 191, 189, 239, 191, 189, 239, 191, 189, 239, 191, 189, 114, 239, 191, 189, 239, 191, 189, 239, 191, 189, 108, 239, 191, 189, 239, 191, 189, 122, 239, 191, 189, 239, 191, 189, 101, 114, 239, 191, 189, 239, 191, 189, 239, 191, 189, 101, 10, 47, 47, 114, 101, 112, 108, 97, 99, 101, 32, 48, 32, 116, 115, 46, 104, 32, 116, 115, 104, 10, 47, 47, 114, 101, 112, 108, 97, 99, 101, 32, 48, 32, 116, 115, 46, 32, 116, 115, 10, 47, 47, 114, 101, 112, 108, 97, 99, 101, 32, 48, 32, 115, 46, 32, 115, 10, 47, 47, 114, 101, 112, 108, 97, 99, 101, 32, 48, 32, 105, 46, 32, 105, 91, 10, 47, 47, 114, 101, 112, 108, 97, 99, 101, 32, 48, 32, 122, 46, 32, 108, 10, 47, 47, 114, 101, 112, 108, 97, 99, 101, 32, 48, 32, 122, 46, 32, 122, 10, 47, 47, 114, 101, 112, 108, 97, 99, 101, 32, 48, 32, 64, 114, 32, 64, 10, 10, 47, 47, 91, 101, 110, 93, 58, 32, 114, 101, 112, 108, 97, 99, 101, 32, 98, 101, 103, 105, 110, 110, 105, 110, 103, 32, 110, 32, 111, 114, 32, 108, 10, 47, 47, 91, 122, 104, 93, 58, 32, 239, 191, 189, 239, 191, 189, 239, 191, 189, 239, 191, 189, 110, 108, 239, 191, 189, 239, 191, 189, 110, 239, 191, 189, 239, 191, 189, 239, 191, 189, 108, 239, 191, 189, 239, 191, 189, 108, 239, 191, 189, 239, 191, 189, 239, 191, 189, 110, 10, 47, 47, 114, 101, 112, 108, 97, 99, 101, 32, 50, 32, 110, 32, 108, 10, 47, 47, 114, 101, 112, 108, 97, 99, 101, 32, 50, 32, 108, 32, 110, 10, 10, 47, 47, 91, 101, 110, 93, 58, 32, 114, 101, 112, 108, 97, 99, 101, 32, 98, 101, 103, 105, 110, 110, 105, 110, 103, 32, 119, 32, 119, 105, 116, 104, 32, 118, 10, 47, 47, 91, 122, 104, 93, 58, 32, 119, 239, 191, 189, 239, 191, 189, 239, 191, 189, 118, 10, 47, 47, 114, 101, 112, 108, 97, 99, 101, 32, 48, 32, 119, 32, 32, 118, 0}; autoFileInMemory espeakdata_voices48 = FileInMemory_createWithData (594, reinterpret_cast (&espeakdata_voices48_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//zh", U"zh"); Collection_addItem (me.peek(), espeakdata_voices48.transfer()); static unsigned char espeakdata_voices49_data[196] = { 110, 97, 109, 101, 32, 99, 97, 110, 116, 111, 110, 101, 115, 101, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 122, 104, 45, 121, 117, 101, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 121, 117, 101, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 122, 104, 121, 10, 10, 116, 114, 97, 110, 115, 108, 97, 116, 111, 114, 32, 122, 104, 121, 10, 112, 104, 111, 110, 101, 109, 101, 115, 32, 122, 104, 121, 10, 100, 105, 99, 116, 105, 111, 110, 97, 114, 121, 32, 122, 104, 121, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 47, 47, 32, 105, 110, 116, 101, 114, 112, 114, 101, 116, 32, 69, 110, 103, 108, 105, 115, 104, 32, 108, 101, 116, 116, 101, 114, 115, 32, 97, 115, 32, 49, 61, 69, 110, 103, 108, 105, 115, 104, 32, 119, 111, 114, 100, 115, 44, 32, 50, 61, 106, 121, 117, 116, 112, 105, 110, 103, 10, 100, 105, 99, 116, 114, 117, 108, 101, 115, 32, 49, 10, 10, 119, 111, 114, 100, 115, 32, 49, 10, 0}; autoFileInMemory espeakdata_voices49 = FileInMemory_createWithData (195, reinterpret_cast (&espeakdata_voices49_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices//zh-yue", U"zh-yue"); Collection_addItem (me.peek(), espeakdata_voices49.transfer()); static unsigned char espeakdata_voices50_data[143] = { 110, 97, 109, 101, 32, 101, 110, 103, 108, 105, 115, 104, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 110, 45, 117, 107, 32, 32, 50, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 110, 45, 103, 98, 32, 32, 50, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 110, 32, 50, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 51, 32, 73, 32, 105, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 51, 32, 73, 50, 32, 105, 10, 10, 47, 47, 112, 105, 116, 99, 104, 32, 56, 48, 32, 49, 49, 56, 10, 10, 116, 117, 110, 101, 115, 32, 115, 49, 32, 99, 49, 32, 113, 49, 32, 101, 49, 10, 0}; autoFileInMemory espeakdata_voices50 = FileInMemory_createWithData (142, reinterpret_cast (&espeakdata_voices50_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/en/en", U"en"); Collection_addItem (me.peek(), espeakdata_voices50.transfer()); static unsigned char espeakdata_voices51_data[217] = { 110, 97, 109, 101, 32, 108, 97, 110, 99, 97, 115, 104, 105, 114, 101, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 110, 45, 117, 107, 45, 110, 111, 114, 116, 104, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 110, 45, 117, 107, 32, 32, 51, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 110, 32, 53, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 112, 104, 111, 110, 101, 109, 101, 115, 32, 101, 110, 45, 110, 10, 10, 115, 116, 114, 101, 115, 115, 76, 101, 110, 103, 116, 104, 32, 49, 54, 48, 32, 49, 53, 48, 32, 32, 49, 56, 48, 32, 49, 56, 48, 32, 32, 50, 50, 48, 32, 50, 50, 48, 32, 32, 50, 57, 48, 32, 50, 57, 48, 10, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 48, 32, 105, 64, 51, 32, 105, 64, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 51, 32, 78, 32, 110, 10, 47, 47, 114, 101, 112, 108, 97, 99, 101, 32, 48, 51, 32, 73, 32, 32, 105, 10, 47, 47, 114, 101, 112, 108, 97, 99, 101, 32, 48, 51, 32, 73, 50, 32, 105, 10, 10, 0}; autoFileInMemory espeakdata_voices51 = FileInMemory_createWithData (216, reinterpret_cast (&espeakdata_voices51_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/en/en-n", U"en-n"); Collection_addItem (me.peek(), espeakdata_voices51.transfer()); static unsigned char espeakdata_voices52_data[195] = { 110, 97, 109, 101, 32, 101, 110, 103, 108, 105, 115, 104, 95, 114, 112, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 110, 45, 117, 107, 45, 114, 112, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 110, 45, 117, 107, 32, 32, 52, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 110, 32, 53, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 112, 104, 111, 110, 101, 109, 101, 115, 32, 101, 110, 45, 114, 112, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 48, 32, 32, 111, 64, 32, 32, 79, 64, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 48, 32, 105, 64, 51, 32, 105, 64, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 51, 32, 73, 32, 105, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 51, 32, 73, 50, 32, 105, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 51, 32, 64, 32, 97, 35, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 51, 32, 51, 32, 97, 35, 10, 0}; autoFileInMemory espeakdata_voices52 = FileInMemory_createWithData (194, reinterpret_cast (&espeakdata_voices52_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/en/en-rp", U"en-rp"); Collection_addItem (me.peek(), espeakdata_voices52.transfer()); static unsigned char espeakdata_voices53_data[247] = { 110, 97, 109, 101, 32, 101, 110, 45, 115, 99, 111, 116, 116, 105, 115, 104, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 110, 45, 115, 99, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 110, 32, 52, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 112, 104, 111, 110, 101, 109, 101, 115, 32, 101, 110, 45, 115, 99, 10, 100, 105, 99, 116, 114, 117, 108, 101, 115, 32, 53, 32, 54, 32, 55, 10, 115, 116, 114, 101, 115, 115, 76, 101, 110, 103, 116, 104, 32, 32, 49, 56, 48, 32, 49, 51, 48, 32, 50, 48, 48, 32, 50, 48, 48, 32, 48, 32, 48, 32, 50, 53, 48, 32, 50, 55, 48, 10, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 51, 32, 64, 32, 86, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 51, 32, 73, 32, 105, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 51, 32, 73, 50, 32, 105, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 49, 32, 97, 73, 32, 97, 73, 50, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 50, 32, 97, 32, 97, 47, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 50, 32, 117, 58, 32, 85, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 50, 32, 51, 58, 32, 86, 82, 10, 0}; autoFileInMemory espeakdata_voices53 = FileInMemory_createWithData (246, reinterpret_cast (&espeakdata_voices53_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/en/en-sc", U"en-sc"); Collection_addItem (me.peek(), espeakdata_voices53.transfer()); static unsigned char espeakdata_voices54_data[281] = { 47, 47, 32, 109, 111, 118, 105, 110, 103, 32, 116, 111, 119, 97, 114, 100, 115, 32, 85, 83, 32, 69, 110, 103, 108, 105, 115, 104, 10, 110, 97, 109, 101, 32, 101, 110, 103, 108, 105, 115, 104, 45, 117, 115, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 110, 45, 117, 115, 32, 50, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 110, 45, 114, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 110, 32, 51, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 112, 104, 111, 110, 101, 109, 101, 115, 32, 101, 110, 45, 117, 115, 10, 100, 105, 99, 116, 114, 117, 108, 101, 115, 32, 51, 32, 54, 10, 111, 112, 116, 105, 111, 110, 32, 114, 101, 100, 117, 99, 101, 95, 116, 32, 49, 10, 10, 115, 116, 114, 101, 115, 115, 76, 101, 110, 103, 116, 104, 32, 49, 52, 53, 32, 49, 50, 53, 32, 49, 57, 48, 32, 49, 55, 48, 32, 48, 32, 48, 32, 50, 54, 48, 32, 51, 48, 48, 10, 115, 116, 114, 101, 115, 115, 65, 109, 112, 32, 32, 49, 55, 32, 49, 54, 32, 32, 49, 57, 32, 49, 57, 32, 32, 49, 57, 32, 49, 57, 32, 32, 50, 49, 32, 49, 57, 10, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 51, 32, 73, 32, 32, 105, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 51, 32, 73, 50, 32, 105, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 51, 32, 64, 32, 32, 64, 47, 10, 0}; autoFileInMemory espeakdata_voices54 = FileInMemory_createWithData (280, reinterpret_cast (&espeakdata_voices54_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/en/en-us", U"en-us"); Collection_addItem (me.peek(), espeakdata_voices54.transfer()); static unsigned char espeakdata_voices55_data[317] = { 110, 97, 109, 101, 32, 101, 110, 45, 119, 101, 115, 116, 105, 110, 100, 105, 101, 115, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 110, 45, 119, 105, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 110, 45, 117, 107, 32, 32, 52, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 110, 32, 49, 48, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 112, 104, 111, 110, 101, 109, 101, 115, 32, 101, 110, 45, 119, 105, 10, 100, 105, 99, 116, 114, 117, 108, 101, 115, 32, 56, 10, 115, 116, 114, 101, 115, 115, 76, 101, 110, 103, 116, 104, 32, 49, 55, 53, 32, 49, 55, 53, 32, 32, 49, 55, 53, 32, 49, 55, 53, 32, 32, 50, 50, 48, 32, 50, 50, 48, 32, 32, 50, 53, 48, 32, 50, 57, 48, 10, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 48, 32, 68, 32, 100, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 48, 32, 84, 32, 116, 91, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 48, 32, 85, 64, 32, 111, 64, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 48, 32, 105, 64, 51, 32, 105, 64, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 51, 32, 64, 32, 97, 35, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 51, 32, 51, 32, 97, 35, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 51, 32, 78, 32, 110, 10, 10, 102, 111, 114, 109, 97, 110, 116, 32, 49, 32, 32, 57, 56, 32, 32, 49, 48, 48, 32, 49, 48, 48, 10, 102, 111, 114, 109, 97, 110, 116, 32, 50, 32, 32, 57, 56, 32, 32, 49, 48, 48, 32, 49, 48, 48, 10, 0}; autoFileInMemory espeakdata_voices55 = FileInMemory_createWithData (316, reinterpret_cast (&espeakdata_voices55_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/en/en-wi", U"en-wi"); Collection_addItem (me.peek(), espeakdata_voices55.transfer()); static unsigned char espeakdata_voices56_data[206] = { 110, 97, 109, 101, 32, 101, 110, 103, 108, 105, 115, 104, 95, 119, 109, 105, 100, 115, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 110, 45, 117, 107, 45, 119, 109, 105, 100, 115, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 110, 45, 117, 107, 32, 57, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 101, 110, 32, 57, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 112, 104, 111, 110, 101, 109, 101, 115, 32, 101, 110, 45, 119, 109, 10, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 48, 32, 104, 32, 78, 85, 76, 76, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 48, 32, 111, 64, 32, 79, 64, 10, 114, 101, 112, 108, 97, 99, 101, 32, 48, 48, 32, 105, 64, 51, 32, 105, 64, 10, 100, 105, 99, 116, 114, 117, 108, 101, 115, 32, 54, 10, 105, 110, 116, 111, 110, 97, 116, 105, 111, 110, 32, 52, 10, 115, 116, 114, 101, 115, 115, 65, 100, 100, 32, 48, 32, 48, 32, 48, 32, 48, 32, 48, 32, 48, 32, 48, 32, 50, 48, 10, 0}; autoFileInMemory espeakdata_voices56 = FileInMemory_createWithData (205, reinterpret_cast (&espeakdata_voices56_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/en/en-wm", U"en-wm"); Collection_addItem (me.peek(), espeakdata_voices56.transfer()); static unsigned char espeakdata_voices57_data[44] = { 110, 97, 109, 101, 32, 97, 107, 97, 110, 45, 116, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 97, 107, 10, 116, 114, 97, 110, 115, 108, 97, 116, 111, 114, 32, 115, 119, 10, 32, 10, 0}; autoFileInMemory espeakdata_voices57 = FileInMemory_createWithData (43, reinterpret_cast (&espeakdata_voices57_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/ak", U"ak"); Collection_addItem (me.peek(), espeakdata_voices57.transfer()); static unsigned char espeakdata_voices58_data[32] = { 110, 97, 109, 101, 32, 97, 109, 104, 97, 114, 105, 99, 45, 116, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 97, 109, 10, 10, 0}; autoFileInMemory espeakdata_voices58 = FileInMemory_createWithData (31, reinterpret_cast (&espeakdata_voices58_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/am", U"am"); Collection_addItem (me.peek(), espeakdata_voices58.transfer()); static unsigned char espeakdata_voices59_data[36] = { 110, 97, 109, 101, 32, 97, 122, 101, 114, 98, 97, 105, 106, 97, 110, 105, 45, 116, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 97, 122, 10, 10, 0}; autoFileInMemory espeakdata_voices59 = FileInMemory_createWithData (35, reinterpret_cast (&espeakdata_voices59_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/az", U"az"); Collection_addItem (me.peek(), espeakdata_voices59.transfer()); static unsigned char espeakdata_voices60_data[116] = { 110, 97, 109, 101, 32, 98, 117, 108, 103, 97, 114, 105, 97, 110, 45, 116, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 98, 103, 10, 10, 115, 116, 114, 101, 115, 115, 65, 109, 112, 32, 49, 51, 32, 49, 50, 32, 49, 55, 32, 49, 55, 32, 50, 48, 32, 50, 50, 32, 50, 50, 32, 50, 49, 32, 10, 115, 116, 114, 101, 115, 115, 76, 101, 110, 103, 116, 104, 32, 49, 56, 48, 32, 49, 55, 48, 32, 32, 50, 48, 48, 32, 50, 48, 48, 32, 32, 50, 48, 48, 32, 50, 48, 48, 32, 32, 50, 49, 48, 32, 50, 50, 48, 0}; autoFileInMemory espeakdata_voices60 = FileInMemory_createWithData (115, reinterpret_cast (&espeakdata_voices60_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/bg", U"bg"); Collection_addItem (me.peek(), espeakdata_voices60.transfer()); static unsigned char espeakdata_voices61_data[31] = { 110, 97, 109, 101, 32, 100, 105, 118, 101, 104, 105, 45, 116, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 100, 118, 10, 10, 0}; autoFileInMemory espeakdata_voices61 = FileInMemory_createWithData (30, reinterpret_cast (&espeakdata_voices61_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/dv", U"dv"); Collection_addItem (me.peek(), espeakdata_voices61.transfer()); static unsigned char espeakdata_voices62_data[43] = { 110, 97, 109, 101, 32, 105, 114, 105, 115, 104, 45, 116, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 103, 97, 10, 115, 116, 114, 101, 115, 115, 114, 117, 108, 101, 32, 48, 10, 10, 0}; autoFileInMemory espeakdata_voices62 = FileInMemory_createWithData (42, reinterpret_cast (&espeakdata_voices62_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/ga", U"ga"); Collection_addItem (me.peek(), espeakdata_voices62.transfer()); static unsigned char espeakdata_voices63_data[111] = { 110, 97, 109, 101, 32, 103, 114, 101, 101, 107, 45, 97, 110, 99, 105, 101, 110, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 103, 114, 99, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 115, 116, 114, 101, 115, 115, 76, 101, 110, 103, 116, 104, 32, 49, 55, 48, 32, 49, 55, 48, 32, 32, 49, 57, 48, 32, 49, 57, 48, 32, 32, 48, 32, 48, 32, 32, 50, 51, 48, 32, 50, 52, 48, 10, 100, 105, 99, 116, 114, 117, 108, 101, 115, 32, 49, 10, 119, 111, 114, 100, 115, 32, 51, 10, 10, 0}; autoFileInMemory espeakdata_voices63 = FileInMemory_createWithData (110, reinterpret_cast (&espeakdata_voices63_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/grc", U"grc"); Collection_addItem (me.peek(), espeakdata_voices63.transfer()); static unsigned char espeakdata_voices64_data[28] = { 110, 97, 109, 101, 32, 104, 97, 105, 116, 105, 97, 110, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 104, 116, 10, 32, 10, 0}; autoFileInMemory espeakdata_voices64 = FileInMemory_createWithData (27, reinterpret_cast (&espeakdata_voices64_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/ht", U"ht"); Collection_addItem (me.peek(), espeakdata_voices64.transfer()); static unsigned char espeakdata_voices65_data[70] = { 110, 97, 109, 101, 32, 108, 111, 106, 98, 97, 110, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 106, 98, 111, 10, 10, 115, 112, 101, 101, 100, 32, 56, 48, 32, 32, 32, 47, 47, 32, 115, 112, 101, 101, 100, 32, 97, 100, 106, 117, 115, 116, 109, 101, 110, 116, 44, 32, 112, 101, 114, 99, 101, 110, 116, 97, 103, 101, 10, 0}; autoFileInMemory espeakdata_voices65 = FileInMemory_createWithData (69, reinterpret_cast (&espeakdata_voices65_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/jbo", U"jbo"); Collection_addItem (me.peek(), espeakdata_voices65.transfer()); static unsigned char espeakdata_voices66_data[27] = { 110, 97, 109, 101, 32, 107, 97, 122, 97, 107, 104, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 107, 107, 10, 32, 10, 0}; autoFileInMemory espeakdata_voices66 = FileInMemory_createWithData (26, reinterpret_cast (&espeakdata_voices66_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/kk", U"kk"); Collection_addItem (me.peek(), espeakdata_voices66.transfer()); static unsigned char espeakdata_voices67_data[75] = { 110, 97, 109, 101, 32, 103, 114, 101, 101, 110, 108, 97, 110, 100, 105, 99, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 107, 108, 10, 10, 115, 116, 114, 101, 115, 115, 114, 117, 108, 101, 32, 50, 32, 32, 47, 47, 32, 112, 101, 110, 117, 108, 116, 105, 109, 97, 116, 101, 32, 40, 102, 111, 114, 32, 116, 101, 115, 116, 105, 110, 103, 41, 10, 10, 0}; autoFileInMemory espeakdata_voices67 = FileInMemory_createWithData (74, reinterpret_cast (&espeakdata_voices67_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/kl", U"kl"); Collection_addItem (me.peek(), espeakdata_voices67.transfer()); static unsigned char espeakdata_voices68_data[83] = { 110, 97, 109, 101, 32, 75, 111, 114, 101, 97, 110, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 107, 111, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 112, 105, 116, 99, 104, 32, 56, 48, 32, 49, 49, 56, 10, 105, 110, 116, 111, 110, 97, 116, 105, 111, 110, 32, 50, 10, 10, 116, 117, 110, 101, 115, 32, 113, 49, 32, 113, 49, 32, 113, 49, 32, 113, 49, 10, 10, 0}; autoFileInMemory espeakdata_voices68 = FileInMemory_createWithData (82, reinterpret_cast (&espeakdata_voices68_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/ko", U"ko"); Collection_addItem (me.peek(), espeakdata_voices68.transfer()); static unsigned char espeakdata_voices69_data[43] = { 10, 110, 97, 109, 101, 32, 108, 105, 116, 104, 117, 97, 110, 105, 97, 110, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 108, 116, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 0}; autoFileInMemory espeakdata_voices69 = FileInMemory_createWithData (42, reinterpret_cast (&espeakdata_voices69_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/lt", U"lt"); Collection_addItem (me.peek(), espeakdata_voices69.transfer()); static unsigned char espeakdata_voices70_data[33] = { 110, 97, 109, 101, 32, 109, 97, 108, 116, 101, 115, 101, 45, 116, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 109, 116, 10, 32, 10, 0}; autoFileInMemory espeakdata_voices70 = FileInMemory_createWithData (32, reinterpret_cast (&espeakdata_voices70_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/mt", U"mt"); Collection_addItem (me.peek(), espeakdata_voices70.transfer()); static unsigned char espeakdata_voices71_data[127] = { 110, 97, 109, 101, 32, 110, 97, 104, 117, 97, 116, 108, 32, 45, 32, 99, 108, 97, 115, 115, 105, 99, 97, 108, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 110, 99, 105, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 105, 110, 116, 111, 110, 97, 116, 105, 111, 110, 32, 51, 10, 115, 116, 114, 101, 115, 115, 114, 117, 108, 101, 32, 50, 10, 115, 116, 114, 101, 115, 115, 76, 101, 110, 103, 116, 104, 32, 32, 49, 57, 48, 32, 32, 49, 57, 48, 32, 32, 50, 48, 48, 32, 32, 50, 48, 48, 32, 32, 48, 32, 32, 48, 32, 32, 50, 50, 48, 32, 32, 50, 52, 48, 10, 0}; autoFileInMemory espeakdata_voices71 = FileInMemory_createWithData (126, reinterpret_cast (&espeakdata_voices71_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/nci", U"nci"); Collection_addItem (me.peek(), espeakdata_voices71.transfer()); static unsigned char espeakdata_voices72_data[55] = { 110, 97, 109, 101, 32, 110, 101, 112, 97, 108, 105, 45, 116, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 110, 101, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 10, 100, 105, 99, 116, 114, 117, 108, 101, 115, 32, 49, 10, 0}; autoFileInMemory espeakdata_voices72 = FileInMemory_createWithData (54, reinterpret_cast (&espeakdata_voices72_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/ne", U"ne"); Collection_addItem (me.peek(), espeakdata_voices72.transfer()); static unsigned char espeakdata_voices73_data[48] = { 110, 97, 109, 101, 32, 110, 111, 114, 116, 104, 101, 114, 110, 45, 115, 111, 116, 104, 111, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 110, 115, 111, 10, 116, 114, 97, 110, 115, 108, 97, 116, 111, 114, 32, 115, 119, 10, 0}; autoFileInMemory espeakdata_voices73 = FileInMemory_createWithData (47, reinterpret_cast (&espeakdata_voices73_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/nso", U"nso"); Collection_addItem (me.peek(), espeakdata_voices73.transfer()); static unsigned char espeakdata_voices74_data[31] = { 110, 97, 109, 101, 32, 112, 117, 110, 106, 97, 98, 105, 45, 116, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 112, 97, 10, 0}; autoFileInMemory espeakdata_voices74 = FileInMemory_createWithData (30, reinterpret_cast (&espeakdata_voices74_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/pa", U"pa"); Collection_addItem (me.peek(), espeakdata_voices74.transfer()); static unsigned char espeakdata_voices75_data[52] = { 110, 97, 109, 101, 32, 112, 97, 112, 105, 97, 109, 101, 110, 116, 111, 45, 116, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 112, 97, 112, 10, 10, 112, 104, 111, 110, 101, 109, 101, 115, 32, 98, 97, 115, 101, 50, 10, 10, 0}; autoFileInMemory espeakdata_voices75 = FileInMemory_createWithData (51, reinterpret_cast (&espeakdata_voices75_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/pap", U"pap"); Collection_addItem (me.peek(), espeakdata_voices75.transfer()); static unsigned char espeakdata_voices76_data[58] = { 110, 97, 109, 101, 32, 100, 97, 114, 105, 45, 116, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 112, 114, 115, 10, 10, 116, 114, 97, 110, 115, 108, 97, 116, 111, 114, 32, 102, 97, 10, 115, 116, 114, 101, 115, 115, 114, 117, 108, 101, 32, 49, 48, 10, 0}; autoFileInMemory espeakdata_voices76 = FileInMemory_createWithData (57, reinterpret_cast (&espeakdata_voices76_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/prs", U"prs"); Collection_addItem (me.peek(), espeakdata_voices76.transfer()); static unsigned char espeakdata_voices77_data[49] = { 110, 97, 109, 101, 32, 107, 105, 110, 121, 97, 114, 119, 97, 110, 100, 97, 45, 116, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 114, 119, 10, 103, 101, 110, 100, 101, 114, 32, 109, 97, 108, 101, 10, 32, 10, 0}; autoFileInMemory espeakdata_voices77 = FileInMemory_createWithData (48, reinterpret_cast (&espeakdata_voices77_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/rw", U"rw"); Collection_addItem (me.peek(), espeakdata_voices77.transfer()); static unsigned char espeakdata_voices78_data[40] = { 110, 97, 109, 101, 32, 115, 105, 110, 104, 97, 108, 97, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 115, 105, 10, 10, 105, 110, 116, 111, 110, 97, 116, 105, 111, 110, 32, 50, 10, 0}; autoFileInMemory espeakdata_voices78 = FileInMemory_createWithData (39, reinterpret_cast (&espeakdata_voices78_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/si", U"si"); Collection_addItem (me.peek(), espeakdata_voices78.transfer()); static unsigned char espeakdata_voices79_data[84] = { 110, 97, 109, 101, 32, 115, 108, 111, 118, 101, 110, 105, 97, 110, 45, 116, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 115, 108, 10, 32, 10, 115, 116, 114, 101, 115, 115, 76, 101, 110, 103, 116, 104, 32, 32, 32, 49, 54, 48, 32, 49, 53, 48, 32, 32, 50, 52, 48, 32, 50, 52, 48, 32, 32, 50, 52, 48, 32, 50, 52, 48, 32, 32, 51, 48, 48, 32, 51, 50, 48, 0}; autoFileInMemory espeakdata_voices79 = FileInMemory_createWithData (83, reinterpret_cast (&espeakdata_voices79_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/sl", U"sl"); Collection_addItem (me.peek(), espeakdata_voices79.transfer()); static unsigned char espeakdata_voices80_data[55] = { 110, 97, 109, 101, 32, 116, 101, 108, 117, 103, 117, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 116, 101, 10, 10, 105, 110, 116, 111, 110, 97, 116, 105, 111, 110, 32, 50, 10, 47, 47, 99, 111, 110, 115, 111, 110, 97, 110, 116, 115, 32, 56, 48, 10, 0}; autoFileInMemory espeakdata_voices80 = FileInMemory_createWithData (54, reinterpret_cast (&espeakdata_voices80_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/te", U"te"); Collection_addItem (me.peek(), espeakdata_voices80.transfer()); static unsigned char espeakdata_voices81_data[34] = { 110, 97, 109, 101, 32, 115, 101, 116, 115, 119, 97, 110, 97, 45, 116, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 116, 110, 10, 32, 10, 0}; autoFileInMemory espeakdata_voices81 = FileInMemory_createWithData (33, reinterpret_cast (&espeakdata_voices81_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/tn", U"tn"); Collection_addItem (me.peek(), espeakdata_voices81.transfer()); static unsigned char espeakdata_voices82_data[49] = { 110, 97, 109, 101, 32, 116, 97, 116, 97, 114, 45, 116, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 116, 116, 10, 10, 116, 117, 110, 101, 115, 32, 115, 51, 32, 99, 51, 32, 113, 51, 32, 101, 51, 10, 10, 0}; autoFileInMemory espeakdata_voices82 = FileInMemory_createWithData (48, reinterpret_cast (&espeakdata_voices82_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/tt", U"tt"); Collection_addItem (me.peek(), espeakdata_voices82.transfer()); static unsigned char espeakdata_voices83_data[55] = { 110, 97, 109, 101, 32, 117, 114, 100, 117, 45, 116, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 117, 114, 10, 10, 112, 104, 111, 110, 101, 109, 101, 115, 32, 104, 105, 10, 115, 116, 114, 101, 115, 115, 114, 117, 108, 101, 32, 54, 10, 10, 0}; autoFileInMemory espeakdata_voices83 = FileInMemory_createWithData (54, reinterpret_cast (&espeakdata_voices83_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/ur", U"ur"); Collection_addItem (me.peek(), espeakdata_voices83.transfer()); static unsigned char espeakdata_voices84_data[32] = { 110, 97, 109, 101, 32, 119, 111, 108, 111, 102, 45, 116, 101, 115, 116, 10, 108, 97, 110, 103, 117, 97, 103, 101, 32, 119, 111, 10, 10, 32, 10, 0}; autoFileInMemory espeakdata_voices84 = FileInMemory_createWithData (31, reinterpret_cast (&espeakdata_voices84_data), U"/home/david/praat/src/espeak-work/espeak-1.46.27/espeak-data/voices/test/wo", U"wo"); Collection_addItem (me.peek(), espeakdata_voices84.transfer()); return me.transfer(); } catch (MelderError) { Melder_throw (U"FilesInMemory not created."); } } praat-6.0.04/external/espeak/event.h000066400000000000000000000026521261542461700173110ustar00rootroot00000000000000#ifndef EVENT_H #define EVENT_H /* Manage events (sentence, word, mark, end,...), is responsible of calling the external callback as soon as the relevant audio sample is played. The audio stream is composed of samples from synthetised messages or audio icons. Each event is associated to a sample. Scenario: - event_declare is called for each expected event. - A timeout is started for the first pending event. - When the timeout happens, the synth_callback is called. Note: the timeout is checked against the real progress of the audio stream, which depends on pauses or underruns. If the real progress is lower than the expected one, a new timeout starts. */ #include "speak_lib.h" // Initialize the event component. // First function to be called. // the callback will be called when the event actually occurs. // The callback is detailled in speak_lib.h . void event_init(void); void event_set_callback(t_espeak_callback* cb); // Clear any pending event. // // Return: EE_OK: operation achieved // EE_INTERNAL_ERROR. espeak_ERROR event_clear_all (); // Declare a future event // // Return: EE_OK: operation achieved // EE_BUFFER_FULL: the event can not be buffered; // you may try after a while to call the function again. // EE_INTERNAL_ERROR. espeak_ERROR event_declare (espeak_EVENT* event); // Terminate the event component. // Last function to be called. void event_terminate(); #endif praat-6.0.04/external/espeak/fifo.h000066400000000000000000000035721261542461700171150ustar00rootroot00000000000000#ifndef FIFO_H #define FIFO_H // Helps to add espeak commands in a first-in first-out queue // and run them asynchronously. #include "espeak_command.h" #include "speak_lib.h" // Initialize the fifo component. // First function to be called. void fifo_init(); // Add an espeak command. // // Note: this function fails if too many commands are already buffered. // In such a case, the calling function could wait and then add again its command. // // Return: EE_OK: operation achieved // EE_BUFFER_FULL: the command can not be buffered; // you may try after a while to call the function again. // EE_INTERNAL_ERROR. espeak_ERROR fifo_add_command (t_espeak_command* c); // Add two espeak commands in a single transaction. // // Note: this function fails if too many commands are already buffered. // In such a case, the calling function could wait and then add again these commands. // // Return: EE_OK: operation achieved // EE_BUFFER_FULL: at least one command can not be buffered; // you may try after a while to call the function again. // EE_INTERNAL_ERROR. espeak_ERROR fifo_add_commands (t_espeak_command* c1, t_espeak_command* c2); // The current running command must be stopped and the awaiting commands are cleared. // Return: EE_OK: operation achieved // EE_INTERNAL_ERROR. espeak_ERROR fifo_stop (); // Is there a running command? // Returns 1 if yes; 0 otherwise. int fifo_is_busy (); // Terminate the fifo component. // Last function to be called. void fifo_terminate(); // Indicates if the running command is still enabled. // // Note: this function is mainly called by the SynthCallback (speak_lib.cpp) // It indicates if the actual wave sample can still be played. It is helpful for // stopping speech as soon as a cancel command is applied. // // Returns 1 if yes, or 0 otherwise. int fifo_is_command_enabled(); #endif praat-6.0.04/external/espeak/intonation.cpp000066400000000000000000001126631261542461700207110ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2005 to 2007 by Jonathan Duddington * * email: jonsd@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write see: * * . * ***************************************************************************/ #include "StdAfx.h" #include #include #include #include #include "speak_lib.h" #include "speech.h" #include "phoneme.h" #include "synthesize.h" #include "voice.h" #include "translate.h" /* Note this module is mostly old code that needs to be rewritten to provide a more flexible intonation system. */ // bits in SYLLABLE.flags #define SYL_RISE 1 #define SYL_EMPHASIS 2 #define SYL_END_CLAUSE 4 typedef struct { char stress; char env; char flags; //bit 0=pitch rising, bit1=emnphasized, bit2=end of clause char nextph_type; unsigned char pitch1; unsigned char pitch2; } SYLLABLE; static SYLLABLE *syllable_tab; static int tone_pitch_env; /* used to return pitch envelope */ /* Pitch data for tone types */ /*****************************/ #define PITCHfall 0 #define PITCHrise 2 #define PITCHfrise 4 // and 3 must be for the variant preceded by 'r' #define PITCHfrise2 6 // and 5 must be the 'r' variant #define PITCHrisefall 8 /* 0 fall */ unsigned char env_fall[128] = { 0xff, 0xfd, 0xfa, 0xf8, 0xf6, 0xf4, 0xf2, 0xf0, 0xee, 0xec, 0xea, 0xe8, 0xe6, 0xe4, 0xe2, 0xe0, 0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xd0, 0xce, 0xcc, 0xca, 0xc8, 0xc6, 0xc4, 0xc2, 0xc0, 0xbe, 0xbc, 0xba, 0xb8, 0xb6, 0xb4, 0xb2, 0xb0, 0xae, 0xac, 0xaa, 0xa8, 0xa6, 0xa4, 0xa2, 0xa0, 0x9e, 0x9c, 0x9a, 0x98, 0x96, 0x94, 0x92, 0x90, 0x8e, 0x8c, 0x8a, 0x88, 0x86, 0x84, 0x82, 0x80, 0x7e, 0x7c, 0x7a, 0x78, 0x76, 0x74, 0x72, 0x70, 0x6e, 0x6c, 0x6a, 0x68, 0x66, 0x64, 0x62, 0x60, 0x5e, 0x5c, 0x5a, 0x58, 0x56, 0x54, 0x52, 0x50, 0x4e, 0x4c, 0x4a, 0x48, 0x46, 0x44, 0x42, 0x40, 0x3e, 0x3c, 0x3a, 0x38, 0x36, 0x34, 0x32, 0x30, 0x2e, 0x2c, 0x2a, 0x28, 0x26, 0x24, 0x22, 0x20, 0x1e, 0x1c, 0x1a, 0x18, 0x16, 0x14, 0x12, 0x10, 0x0e, 0x0c, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x00 }; /* 1 rise */ unsigned char env_rise[128] = { 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e, 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfd, 0xff }; unsigned char env_frise[128] = { 0xff, 0xf4, 0xea, 0xe0, 0xd6, 0xcc, 0xc3, 0xba, 0xb1, 0xa8, 0x9f, 0x97, 0x8f, 0x87, 0x7f, 0x78, 0x71, 0x6a, 0x63, 0x5c, 0x56, 0x50, 0x4a, 0x44, 0x3f, 0x39, 0x34, 0x2f, 0x2b, 0x26, 0x22, 0x1e, 0x1a, 0x17, 0x13, 0x10, 0x0d, 0x0b, 0x08, 0x06, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x13, 0x15, 0x17, 0x1a, 0x1d, 0x1f, 0x22, 0x25, 0x28, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x39, 0x3b, 0x3d, 0x40, 0x42, 0x45, 0x47, 0x4a, 0x4c, 0x4f, 0x51, 0x54, 0x57, 0x5a, 0x5d, 0x5f, 0x62, 0x65, 0x68, 0x6b, 0x6e, 0x71, 0x74, 0x78, 0x7b, 0x7e, 0x81, 0x85, 0x88, 0x8b, 0x8f, 0x92, 0x96, 0x99, 0x9d, 0xa0, 0xa4, 0xa8, 0xac, 0xaf, 0xb3, 0xb7, 0xbb, 0xbf, 0xc3, 0xc7, 0xcb, 0xcf, 0xd3, 0xd7, 0xdb, 0xe0 }; static unsigned char env_r_frise[128] = { 0xcf, 0xcc, 0xc9, 0xc6, 0xc3, 0xc0, 0xbd, 0xb9, 0xb4, 0xb0, 0xab, 0xa7, 0xa2, 0x9c, 0x97, 0x92, 0x8c, 0x86, 0x81, 0x7b, 0x75, 0x6f, 0x69, 0x63, 0x5d, 0x57, 0x50, 0x4a, 0x44, 0x3e, 0x38, 0x33, 0x2d, 0x27, 0x22, 0x1c, 0x17, 0x12, 0x0d, 0x08, 0x04, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x08, 0x0a, 0x0c, 0x0d, 0x0f, 0x12, 0x14, 0x16, 0x19, 0x1b, 0x1e, 0x21, 0x24, 0x27, 0x2a, 0x2d, 0x30, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3f, 0x41, 0x43, 0x46, 0x48, 0x4b, 0x4d, 0x50, 0x52, 0x55, 0x58, 0x5a, 0x5d, 0x60, 0x63, 0x66, 0x69, 0x6c, 0x6f, 0x72, 0x75, 0x78, 0x7b, 0x7e, 0x81, 0x85, 0x88, 0x8b, 0x8f, 0x92, 0x96, 0x99, 0x9d, 0xa0, 0xa4, 0xa8, 0xac, 0xaf, 0xb3, 0xb7, 0xbb, 0xbf, 0xc3, 0xc7, 0xcb, 0xcf, 0xd3, 0xd7, 0xdb, 0xe0 }; static unsigned char env_frise2[128] = { 0xff, 0xf9, 0xf4, 0xee, 0xe9, 0xe4, 0xdf, 0xda, 0xd5, 0xd0, 0xcb, 0xc6, 0xc1, 0xbd, 0xb8, 0xb3, 0xaf, 0xaa, 0xa6, 0xa1, 0x9d, 0x99, 0x95, 0x90, 0x8c, 0x88, 0x84, 0x80, 0x7d, 0x79, 0x75, 0x71, 0x6e, 0x6a, 0x67, 0x63, 0x60, 0x5d, 0x59, 0x56, 0x53, 0x50, 0x4d, 0x4a, 0x47, 0x44, 0x41, 0x3e, 0x3c, 0x39, 0x37, 0x34, 0x32, 0x2f, 0x2d, 0x2b, 0x28, 0x26, 0x24, 0x22, 0x20, 0x1e, 0x1c, 0x1a, 0x19, 0x17, 0x15, 0x14, 0x12, 0x11, 0x0f, 0x0e, 0x0d, 0x0c, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x05, 0x04, 0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x04, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0e, 0x0f, 0x10, 0x12, 0x13, 0x15, 0x17, 0x18, 0x1a, 0x1c, 0x1e, 0x20 }; static unsigned char env_r_frise2[128] = { 0xd0, 0xce, 0xcd, 0xcc, 0xca, 0xc8, 0xc7, 0xc5, 0xc3, 0xc1, 0xc0, 0xbd, 0xbb, 0xb8, 0xb5, 0xb3, 0xb0, 0xad, 0xaa, 0xa7, 0xa3, 0xa0, 0x9d, 0x99, 0x96, 0x92, 0x8f, 0x8b, 0x87, 0x84, 0x80, 0x7c, 0x78, 0x74, 0x70, 0x6d, 0x69, 0x65, 0x61, 0x5d, 0x59, 0x55, 0x51, 0x4d, 0x4a, 0x46, 0x42, 0x3e, 0x3b, 0x37, 0x34, 0x31, 0x2f, 0x2d, 0x2a, 0x28, 0x26, 0x24, 0x22, 0x20, 0x1e, 0x1c, 0x1a, 0x19, 0x17, 0x15, 0x14, 0x12, 0x11, 0x0f, 0x0e, 0x0d, 0x0c, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x05, 0x04, 0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x04, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0e, 0x0f, 0x10, 0x12, 0x13, 0x15, 0x17, 0x18, 0x1a, 0x1c, 0x1e, 0x20 }; static unsigned char env_risefall[128] = { 0x98, 0x99, 0x99, 0x9a, 0x9c, 0x9d, 0x9f, 0xa1, 0xa4, 0xa7, 0xa9, 0xac, 0xb0, 0xb3, 0xb6, 0xba, 0xbe, 0xc1, 0xc5, 0xc9, 0xcd, 0xd1, 0xd4, 0xd8, 0xdc, 0xdf, 0xe3, 0xe6, 0xea, 0xed, 0xf0, 0xf2, 0xf5, 0xf7, 0xf9, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfd, 0xfb, 0xfa, 0xf8, 0xf6, 0xf3, 0xf1, 0xee, 0xec, 0xe9, 0xe6, 0xe4, 0xe0, 0xdd, 0xda, 0xd7, 0xd3, 0xd0, 0xcc, 0xc8, 0xc4, 0xc0, 0xbc, 0xb8, 0xb4, 0xb0, 0xac, 0xa7, 0xa3, 0x9f, 0x9a, 0x96, 0x91, 0x8d, 0x88, 0x84, 0x7f, 0x7b, 0x76, 0x72, 0x6d, 0x69, 0x65, 0x60, 0x5c, 0x58, 0x54, 0x50, 0x4c, 0x48, 0x44, 0x40, 0x3c, 0x39, 0x35, 0x32, 0x2f, 0x2b, 0x28, 0x26, 0x23, 0x20, 0x1d, 0x1a, 0x17, 0x15, 0x12, 0x0f, 0x0d, 0x0a, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }; static unsigned char env_rise2[128] = { 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x16, 0x17, 0x18, 0x19, 0x1b, 0x1c, 0x1d, 0x1f, 0x20, 0x22, 0x23, 0x25, 0x26, 0x28, 0x29, 0x2b, 0x2d, 0x2f, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x40, 0x42, 0x44, 0x47, 0x49, 0x4b, 0x4e, 0x50, 0x52, 0x55, 0x57, 0x5a, 0x5d, 0x5f, 0x62, 0x65, 0x67, 0x6a, 0x6d, 0x70, 0x73, 0x76, 0x79, 0x7c, 0x7f, 0x82, 0x86, 0x89, 0x8c, 0x90, 0x93, 0x96, 0x9a, 0x9d, 0xa0, 0xa3, 0xa6, 0xa9, 0xac, 0xaf, 0xb2, 0xb5, 0xb8, 0xbb, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd, 0xd0, 0xd3, 0xd6, 0xd9, 0xdc, 0xdf, 0xe2, 0xe4, 0xe7, 0xe9, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfb, 0xfd }; static unsigned char env_fall2[128] = { 0xfe, 0xfe, 0xfd, 0xfd, 0xfc, 0xfb, 0xfb, 0xfa, 0xfa, 0xf9, 0xf8, 0xf8, 0xf7, 0xf7, 0xf6, 0xf6, 0xf5, 0xf4, 0xf4, 0xf3, 0xf3, 0xf2, 0xf2, 0xf1, 0xf0, 0xf0, 0xef, 0xee, 0xee, 0xed, 0xec, 0xeb, 0xea, 0xea, 0xe9, 0xe8, 0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0, 0xde, 0xdd, 0xdc, 0xdb, 0xd9, 0xd8, 0xd6, 0xd5, 0xd3, 0xd2, 0xd0, 0xce, 0xcc, 0xcb, 0xc9, 0xc7, 0xc5, 0xc3, 0xc0, 0xbe, 0xbc, 0xb9, 0xb7, 0xb5, 0xb2, 0xaf, 0xad, 0xaa, 0xa7, 0xa4, 0xa1, 0x9e, 0x9a, 0x97, 0x94, 0x90, 0x8d, 0x89, 0x85, 0x81, 0x7d, 0x79, 0x75, 0x71, 0x6d, 0x68, 0x64, 0x61, 0x5e, 0x5b, 0x57, 0x54, 0x51, 0x4d, 0x4a, 0x46, 0x43, 0x40, 0x3c, 0x39, 0x35, 0x32, 0x2e, 0x2a, 0x27, 0x23, 0x1f, 0x1c, 0x18, 0x14, 0x11, 0x0d, 0x0b, 0x09, 0x07, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00 }; static unsigned char env_fallrise3[128] = { 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfd, 0xfc, 0xfa, 0xf8, 0xf6, 0xf4, 0xf1, 0xee, 0xeb, 0xe8, 0xe5, 0xe1, 0xde, 0xda, 0xd6, 0xd2, 0xcd, 0xc9, 0xc4, 0xbf, 0xba, 0xb6, 0xb0, 0xab, 0xa6, 0xa1, 0x9c, 0x96, 0x91, 0x8b, 0x86, 0x80, 0x7b, 0x75, 0x6f, 0x6a, 0x64, 0x5f, 0x59, 0x54, 0x4f, 0x49, 0x44, 0x3f, 0x3a, 0x35, 0x30, 0x2b, 0x26, 0x22, 0x1d, 0x19, 0x15, 0x11, 0x0d, 0x0a, 0x07, 0x04, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x04, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x10, 0x12, 0x15, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x29, 0x2d, 0x31, 0x35, 0x3a, 0x3e, 0x43, 0x48, 0x4c, 0x51, 0x57, 0x5b, 0x5e, 0x62, 0x65, 0x68, 0x6b, 0x6e, 0x71, 0x74, 0x76, 0x78, 0x7b, 0x7c, 0x7e, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x84, 0x83, 0x83, 0x82, 0x81 }; static unsigned char env_fallrise4[128] = { 0x72, 0x72, 0x71, 0x71, 0x70, 0x6f, 0x6d, 0x6c, 0x6a, 0x68, 0x66, 0x64, 0x61, 0x5f, 0x5c, 0x5a, 0x57, 0x54, 0x51, 0x4e, 0x4b, 0x48, 0x45, 0x42, 0x3f, 0x3b, 0x38, 0x35, 0x32, 0x2f, 0x2c, 0x29, 0x26, 0x23, 0x20, 0x1d, 0x1b, 0x18, 0x16, 0x14, 0x12, 0x10, 0x0e, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x07, 0x07, 0x08, 0x09, 0x0a, 0x0c, 0x0d, 0x0f, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1b, 0x1d, 0x20, 0x23, 0x26, 0x29, 0x2c, 0x2f, 0x33, 0x37, 0x3b, 0x3f, 0x43, 0x47, 0x4c, 0x51, 0x56, 0x5b, 0x60, 0x65, 0x6a, 0x6f, 0x74, 0x79, 0x7f, 0x84, 0x89, 0x8f, 0x95, 0x9b, 0xa1, 0xa7, 0xad, 0xb3, 0xba, 0xc0, 0xc7, 0xce, 0xd5, 0xdc, 0xe3, 0xea, 0xf1, 0xf5, 0xf7, 0xfa, 0xfc, 0xfd, 0xfe, 0xff, 0xff }; static unsigned char env_risefallrise[128] = { 0x7f, 0x7f, 0x7f, 0x80, 0x81, 0x83, 0x84, 0x87, 0x89, 0x8c, 0x8f, 0x92, 0x96, 0x99, 0x9d, 0xa1, 0xa5, 0xaa, 0xae, 0xb2, 0xb7, 0xbb, 0xc0, 0xc5, 0xc9, 0xcd, 0xd2, 0xd6, 0xda, 0xde, 0xe2, 0xe6, 0xea, 0xed, 0xf0, 0xf3, 0xf5, 0xf8, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xfd, 0xfc, 0xfb, 0xf9, 0xf7, 0xf4, 0xf0, 0xec, 0xe7, 0xe2, 0xdc, 0xd5, 0xce, 0xc6, 0xbd, 0xb4, 0xa9, 0x9e, 0x92, 0x88, 0x82, 0x7d, 0x77, 0x72, 0x6c, 0x66, 0x60, 0x5a, 0x54, 0x4e, 0x49, 0x42, 0x3c, 0x37, 0x32, 0x2d, 0x28, 0x24, 0x1f, 0x1b, 0x18, 0x14, 0x11, 0x0e, 0x0c, 0x09, 0x07, 0x06, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05, 0x06, 0x08, 0x0a, 0x0d, 0x10, 0x14, 0x18, 0x1d, 0x23, 0x29, 0x2f, 0x37, 0x3e, 0x47, 0x50, 0x5a, 0x64, 0x70, 0x7c, 0x83, 0x85, 0x88, 0x8a, 0x8c, 0x8e, 0x8f, 0x91, 0x92, 0x93, 0x93 }; unsigned char *envelope_data[N_ENVELOPE_DATA] = { env_fall, env_fall, env_rise, env_rise, env_frise, env_r_frise, env_frise2, env_r_frise2, env_risefall, env_risefall, env_fallrise3, env_fallrise3, env_fallrise4, env_fallrise4, env_fall2, env_fall2, env_rise2, env_rise2, env_risefallrise, env_risefallrise }; /* indexed by stress */ static int min_drop[] = {6,7,9,9,20,20,20,25}; // pitch change during the main part of the clause static int drops_0[8] = {9,9,16,16,16,23,55,32}; // overflow table values are 64ths of the body pitch range (between body_start and body_end) static signed char oflow[] = {0, 40, 24, 8, 0}; static signed char oflow_emf[] = {10, 52, 32, 20, 10}; static signed char oflow_less[] = {6, 38, 24, 14, 4}; #define N_TONE_HEAD_TABLE 13 #define N_TONE_NUCLEUS_TABLE 13 typedef struct { unsigned char pre_start; unsigned char pre_end; unsigned char body_start; unsigned char body_end; int *body_drops; unsigned char body_max_steps; char body_lower_u; unsigned char n_overflow; signed char *overflow; } TONE_HEAD; typedef struct { unsigned char pitch_env0; /* pitch envelope, tonic syllable at end */ unsigned char tonic_max0; unsigned char tonic_min0; unsigned char pitch_env1; /* followed by unstressed */ unsigned char tonic_max1; unsigned char tonic_min1; short *backwards; unsigned char tail_start; unsigned char tail_end; unsigned char flags; } TONE_NUCLEUS; #define T_EMPH 1 static TONE_HEAD tone_head_table[N_TONE_HEAD_TABLE] = { {46, 57, 78, 50, drops_0, 3, 7, 5, oflow}, // 0 statement {46, 57, 78, 46, drops_0, 3, 7, 5, oflow}, // 1 comma {46, 57, 78, 46, drops_0, 3, 7, 5, oflow}, // 2 question {46, 57, 90, 50, drops_0, 3, 9, 5, oflow_emf}, // 3 exclamation {46, 57, 78, 50, drops_0, 3, 7, 5, oflow}, // 4 statement, emphatic {46, 57, 74, 55, drops_0, 4, 7, 5, oflow_less}, // 5 statement, less intonation {46, 57, 74, 55, drops_0, 4, 7, 5, oflow_less}, // 6 comma, less intonation {46, 57, 74, 55, drops_0, 4, 7, 5, oflow_less}, // 7 comma, less intonation, less rise {46, 57, 78, 50, drops_0, 3, 7, 5, oflow}, // 8 pitch raises at end of sentence {46, 57, 78, 46, drops_0, 3, 7, 5, oflow}, // 9 comma {46, 57, 78, 50, drops_0, 3, 7, 5, oflow}, // 10 question {34, 41, 41, 32, drops_0, 3, 7, 5, oflow_less}, // 11 test {46, 57, 55, 50, drops_0, 3, 7, 5, oflow_less}, // 12 test }; static TONE_NUCLEUS tone_nucleus_table[N_TONE_NUCLEUS_TABLE] = { {PITCHfall, 64, 8, PITCHfall, 70,18, NULL, 24, 12, 0}, // 0 statement {PITCHfrise, 80,18, PITCHfrise2, 78,22, NULL, 34, 52, 0}, // 1 comma {PITCHfrise, 88,22, PITCHfrise2, 82,22, NULL, 34, 64, 0}, // 2 question {PITCHfall, 92, 8, PITCHfall, 92,80, NULL, 76, 8, T_EMPH}, // 3 exclamation {PITCHfall, 86, 4, PITCHfall, 94,66, NULL, 34, 10, 0}, // 4 statement, emphatic {PITCHfall, 62,10, PITCHfall, 62,20, NULL, 28, 16, 0}, // 5 statement, less intonation {PITCHfrise, 68,18, PITCHfrise2, 68,22, NULL, 30, 44, 0}, // 6 comma, less intonation {PITCHfrise2, 64,16, PITCHfall, 66,32, NULL, 32, 18, 0}, // 7 comma, less intonation, less rise {PITCHrise, 68,46, PITCHfall, 42,32, NULL, 46, 58, 0}, // 8 pitch raises at end of sentence {PITCHfrise, 78,24, PITCHfrise2, 72,22, NULL, 42, 52, 0}, // 9 comma {PITCHfrise, 88,34, PITCHfall, 64,32, NULL, 46, 82, 0}, // 10 question {PITCHfall, 56,12, PITCHfall, 56,20, NULL, 24, 12, 0}, // 11 test {PITCHfall, 70,18, PITCHfall, 70,24, NULL, 32, 20, 0}, // 12 test }; /* index by 0=. 1=, 2=?, 3=! 4=none, 5=emphasized */ unsigned char punctuation_to_tone[INTONATION_TYPES][PUNCT_INTONATIONS] = { {0,1,2,3,0,4}, {0,1,2,3,0,4}, {5,6,2,3,0,4}, {5,7,1,3,0,4}, {8,9,10,3,0,0}, {8,8,10,3,0,0}, {11,11,11,11,0,0}, // 6 test {12,12,12,12,0,0} }; int n_tunes = 0; TUNE *tunes = NULL; #define SECONDARY 3 #define PRIMARY 4 #define PRIMARY_STRESSED 6 #define PRIMARY_LAST 7 static int number_pre; static int number_body; static int number_tail; static int last_primary; static int tone_posn; static int tone_posn2; static int no_tonic; static void count_pitch_vowels(int start, int end, int clause_end) /****************************************************************/ { int ix; int stress; int max_stress = 0; int max_stress_posn = 0; // last syllable ot the highest stress int max_stress_posn2 = 0; // penuntimate syllable of the highest stress number_pre = -1; /* number of vowels before 1st primary stress */ number_body = 0; number_tail = 0; /* number between tonic syllable and next primary */ last_primary = -1; for(ix=start; ix= max_stress) { if(stress > max_stress) { max_stress_posn2 = ix; } else { max_stress_posn2 = max_stress_posn; } max_stress_posn = ix; max_stress = stress; } if(stress >= PRIMARY) { if(number_pre < 0) number_pre = ix - start; last_primary = ix; } } if(number_pre < 0) number_pre = end; number_tail = end - max_stress_posn - 1; tone_posn = max_stress_posn; tone_posn2 = max_stress_posn2; if(no_tonic) { tone_posn = tone_posn2 = end; // next position after the end of the truncated clause } else if(last_primary >= 0) { if(end == clause_end) { syllable_tab[last_primary].stress = PRIMARY_LAST; } } else { // no primary stress. Use the highest stress syllable_tab[tone_posn].stress = PRIMARY_LAST; } } /* end of count_pitch_vowels */ static int count_increments(int ix, int end_ix, int min_stress) /*************************************************************/ /* Count number of primary stresses up to tonic syllable or body_reset */ { int count = 0; int stress; while(ix < end_ix) { stress = syllable_tab[ix++].stress; if(stress >= PRIMARY_LAST) break; if(stress >= min_stress) count++; } return(count); } /* end of count_increments */ static void set_pitch(SYLLABLE *syl, int base, int drop) /******************************************************/ // Set the pitch of a vowel in syllable_tab { int pitch1, pitch2; int flags = 0; if(base < 0) base = 0; pitch2 = base; if(drop < 0) { flags = SYL_RISE; drop = -drop; } pitch1 = pitch2 + drop; if(pitch1 < 0) pitch1 = 0; if(pitch1 > 254) pitch1 = 254; if(pitch2 > 254) pitch2 = 254; syl->pitch1 = pitch1; syl->pitch2 = pitch2; syl->flags |= flags; } /* end of set_pitch */ static int CountUnstressed(int start, int end, int limit) {//====================================================== int ix; for(ix=start; ix <= end; ix++) { if(syllable_tab[ix].stress >= limit) break; } return(ix - start); } static int SetHeadIntonation(TUNE *tune, int syl_ix, int end_ix, int control) {//========================================================================== int stress; SYLLABLE *syl; int ix; int pitch=0; int increment=0; int n_steps=0; int stage; // onset, head, last int initial; int overflow_ix=0; int pitch_range; int pitch_range_abs; int *drops; int n_unstressed=0; int unstressed_ix=0; int unstressed_inc; int used_onset = 0; int head_final = end_ix; int secondary=2; // 2 pitch_range = (tune->head_end - tune->head_start) << 8; pitch_range_abs = abs(pitch_range); drops = drops_0; // this should be controled by tune->head_drops initial = 1; stage = 0; if(tune->onset == 255) stage = 1; // no onset specified if(tune->head_last != 255) { // find the last primary stress in the body for(ix = end_ix-1; ix >= syl_ix; ix--) { if(syllable_tab[ix].stress >= 4) { head_final = ix; break; } } } while(syl_ix < end_ix) { syl = &syllable_tab[syl_ix]; stress = syl->stress; if(initial || (stress >= 4)) { // a primary stress if((initial) || (stress == 5)) { initial = 0; overflow_ix = 0; if(tune->onset == 255) { n_steps = count_increments(syl_ix, head_final, 4); pitch = tune->head_start << 8; } else { // a pitch has been specified for the onset syllable, don't include it in the pitch incrementing n_steps = count_increments(syl_ix+1, head_final, 4); pitch = tune->onset << 8; used_onset = 1; } if(n_steps > tune->head_max_steps) n_steps = tune->head_max_steps; if(n_steps > 1) { increment = pitch_range / (n_steps -1); } else increment = 0; } else if(syl_ix == head_final) { // a pitch has been specified for the last primary stress before the nucleus pitch = tune->head_last << 8; stage = 2; } else { if(used_onset) { stage = 1; used_onset = 0; pitch = tune->head_start << 8; n_steps++; } else if(n_steps > 0) pitch += increment; else { pitch = (tune->head_end << 8) + (pitch_range_abs * tune->head_extend[overflow_ix++])/64; if(overflow_ix >= tune->n_head_extend) { overflow_ix = 0; } } } n_steps--; } if(stress >= PRIMARY) { n_unstressed = CountUnstressed(syl_ix+1, end_ix, secondary); unstressed_ix = 0; syl->stress = PRIMARY_STRESSED; syl->env = tune->stressed_env; set_pitch(syl,(pitch >> 8), tune->stressed_drop); } else if(stress >= secondary) { n_unstressed = CountUnstressed(syl_ix+1, end_ix, secondary); unstressed_ix = 0; set_pitch(syl,(pitch >> 8),drops[stress]); } else { if(n_unstressed > 1) unstressed_inc = (tune->unstr_end[stage] - tune->unstr_start[stage]) / (n_unstressed - 1); else unstressed_inc = 0; set_pitch(syl, (pitch >> 8) + tune->unstr_start[stage] + (unstressed_inc * unstressed_ix), drops[stress]); unstressed_ix++; } syl_ix++; } return(syl_ix); } // end of SetBodyIntonation static int calc_pitch_segment(int ix, int end_ix, TONE_HEAD *th, TONE_NUCLEUS *tn, int min_stress, int continuing) /**********************************************************************************************/ /* Calculate pitches until next RESET or tonic syllable, or end. Increment pitch if stress is >= min_stress. Used for tonic segment */ { int stress; int pitch=0; int increment=0; int n_primary=0; int n_steps=0; int initial; int overflow=0; int n_overflow; int pitch_range; int pitch_range_abs; int *drops; signed char *overflow_tab; SYLLABLE *syl; static signed char continue_tab[5] = {-26, 32, 20, 8, 0}; drops = th->body_drops; pitch_range = (th->body_end - th->body_start) << 8; pitch_range_abs = abs(pitch_range); if(continuing) { initial =0; overflow = 0; n_overflow = 5; overflow_tab = continue_tab; increment = pitch_range / (th->body_max_steps -1); } else { n_overflow = th->n_overflow; overflow_tab = th->overflow; initial = 1; } while(ix < end_ix) { syl = &syllable_tab[ix]; stress = syl->stress; // if(stress == PRIMARY_MARKED) // initial = 1; // reset the intonation pattern if(initial || (stress >= min_stress)) { // a primary stress if((initial) || (stress == 5)) { initial = 0; overflow = 0; n_steps = n_primary = count_increments(ix,end_ix,min_stress); if(n_steps > th->body_max_steps) n_steps = th->body_max_steps; if(n_steps > 1) { increment = pitch_range / (n_steps -1); } else increment = 0; pitch = th->body_start << 8; } else { if(n_steps > 0) pitch += increment; else { pitch = (th->body_end << 8) + (pitch_range_abs * overflow_tab[overflow++])/64; if(overflow >= n_overflow) { overflow = 0; overflow_tab = th->overflow; } } } n_steps--; n_primary--; if((tn->backwards) && (n_primary < 2)) { pitch = tn->backwards[n_primary] << 8; } } if(stress >= PRIMARY) { syl->stress = PRIMARY_STRESSED; set_pitch(syl,(pitch >> 8),drops[stress]); } else if(stress >= SECONDARY) { set_pitch(syl,(pitch >> 8),drops[stress]); } else { /* unstressed, drop pitch if preceded by PRIMARY */ if((syllable_tab[ix-1].stress & 0x3f) >= SECONDARY) set_pitch(syl,(pitch >> 8) - th->body_lower_u, drops[stress]); else set_pitch(syl,(pitch >> 8),drops[stress]); } ix++; } return(ix); } /* end of calc_pitch_segment */ static void SetPitchGradient(int start_ix, int end_ix, int start_pitch, int end_pitch) {//==================================================================================== // Set a linear pitch change over a number of syllables. // Used for pre-head, unstressed syllables in the body, and the tail int ix; int stress; int pitch; int increment; int n_increments; int drop; SYLLABLE *syl; increment = (end_pitch - start_pitch) << 8; n_increments = end_ix - start_ix; if(n_increments <= 0) return; if(n_increments > 1) { increment = increment / n_increments; } pitch = start_pitch << 8; for(ix=start_ix; ix < end_ix; ix++) { syl = &syllable_tab[ix]; stress = syl->stress; if(increment > 0) { set_pitch(syl,(pitch >> 8),-(increment >> 8)); pitch += increment; } else { drop = -(increment >> 8); if(drop < min_drop[stress]) drop = min_drop[stress]; pitch += increment; if(drop > 18) drop = 18; set_pitch(syl, (pitch >> 8), drop); } } } // end of SetPitchGradient static int calc_pitches2(int start, int end, int tune_number) //============================================================ // Calculate pitch values for the vowels in this tone group { int ix; TUNE *tune; int drop; tune = &tunes[tune_number]; ix = start; /* vowels before the first primary stress */ /******************************************/ SetPitchGradient(ix, ix+number_pre, tune->prehead_start, tune->prehead_end); ix += number_pre; /* body of tonic segment */ /*************************/ if(option_tone_flags & OPTION_EMPHASIZE_PENULTIMATE) { tone_posn = tone_posn2; // put tone on the penultimate stressed word } ix = SetHeadIntonation(tune, ix, tone_posn, 0); if(no_tonic) return(0); /* tonic syllable */ /******************/ // if(tn->flags & T_EMPH) // { // syllable_tab[ix].flags |= SYL_EMPHASIS; // } if(number_tail == 0) { tone_pitch_env = tune->nucleus0_env; drop = tune->nucleus0_max - tune->nucleus0_min; set_pitch(&syllable_tab[ix++],tune->nucleus0_min, drop); } else { tone_pitch_env = tune->nucleus1_env; drop = tune->nucleus1_max - tune->nucleus1_min; set_pitch(&syllable_tab[ix++],tune->nucleus1_min, drop); } syllable_tab[tone_posn].env = tone_pitch_env; if(syllable_tab[tone_posn].stress == PRIMARY) syllable_tab[tone_posn].stress = PRIMARY_STRESSED; /* tail, after the tonic syllable */ /**********************************/ SetPitchGradient(ix, end, tune->tail_start, tune->tail_end); return(tone_pitch_env); } /* end of calc_pitches2 */ static int calc_pitches(int control, int start, int end, int tune_number) //======================================================================== // Calculate pitch values for the vowels in this tone group { int ix; TONE_HEAD *th; TONE_NUCLEUS *tn; int drop; int continuing = 0; if(control == 0) { return(calc_pitches2(start, end, tune_number)); } if(start > 0) continuing = 1; th = &tone_head_table[tune_number]; tn = &tone_nucleus_table[tune_number]; ix = start; /* vowels before the first primary stress */ /******************************************/ SetPitchGradient(ix, ix+number_pre, th->pre_start, th->pre_end); ix += number_pre; /* body of tonic segment */ /*************************/ if(option_tone_flags & OPTION_EMPHASIZE_PENULTIMATE) { tone_posn = tone_posn2; // put tone on the penultimate stressed word } ix = calc_pitch_segment(ix,tone_posn, th, tn, PRIMARY, continuing); // ix = SetBodyIntonation(&tunes[0], ix, tone_posn, 0); if(no_tonic) return(0); /* tonic syllable */ /******************/ if(tn->flags & T_EMPH) { syllable_tab[ix].flags |= SYL_EMPHASIS; } if(number_tail == 0) { tone_pitch_env = tn->pitch_env0; drop = tn->tonic_max0 - tn->tonic_min0; set_pitch(&syllable_tab[ix++],tn->tonic_min0, drop); } else { tone_pitch_env = tn->pitch_env1; drop = tn->tonic_max1 - tn->tonic_min1; set_pitch(&syllable_tab[ix++],tn->tonic_min1, drop); } syllable_tab[tone_posn].env = tone_pitch_env; if(syllable_tab[tone_posn].stress == PRIMARY) syllable_tab[tone_posn].stress = PRIMARY_STRESSED; /* tail, after the tonic syllable */ /**********************************/ SetPitchGradient(ix, end, tn->tail_start, tn->tail_end); return(tone_pitch_env); } /* end of calc_pitches */ static void CalcPitches_Tone(Translator *tr, int clause_tone) {//========================================================== // clause_tone: 0=. 1=, 2=?, 3=! 4=none PHONEME_LIST *p; int ix; int count_stressed=0; int final_stressed=0; int tone_ph; int pause; int tone_promoted; PHONEME_TAB *tph; PHONEME_TAB *prev_tph; // forget across word boundary PHONEME_TAB *prevw_tph; // remember across word boundary // PHONEME_TAB *prev2_tph; // 2 tones previous PHONEME_LIST *prev_p; int pitch_adjust = 0; // pitch gradient through the clause - inital value int pitch_decrement = 0; // decrease by this for each stressed syllable int pitch_low = 0; // until it drops to this int pitch_high = 0; // then reset to this // count number of stressed syllables p = &phoneme_list[0]; for(ix=0; ixtype == phVOWEL) && (p->stresslevel >= 4)) { if(count_stressed == 0) final_stressed = ix; if(p->stresslevel >= 4) { final_stressed = ix; count_stressed++; } } } phoneme_list[final_stressed].stresslevel = 7; // language specific, changes to tones if(tr->translator_name == L('v','i')) { // LANG=vi p = &phoneme_list[final_stressed]; if(p->tone_ph == 0) p->tone_ph = PhonemeCode('7'); // change default tone (tone 1) to falling tone at end of clause } pause = 1; tone_promoted = 0; prev_p = p = &phoneme_list[0]; prev_tph = prevw_tph = phoneme_tab[phonPAUSE]; // perform tone sandhi for(ix=0; ixtype == phPAUSE) && (p->ph->std_length > 50)) { pause = 1; // there is a pause since the previous vowel prevw_tph = phoneme_tab[phonPAUSE]; // forget previous tone } if(p->newword) { prev_tph = phoneme_tab[phonPAUSE]; // forget across word boundaries } if(p->synthflags & SFLAG_SYLLABLE) { tone_ph = p->tone_ph; tph = phoneme_tab[tone_ph]; // Mandarin if(tr->translator_name == L('z','h')) { if(tone_ph == 0) { if(pause || tone_promoted) { tone_ph = PhonemeCode2('5','5'); // no previous vowel, use tone 1 tone_promoted = 1; } else { tone_ph = PhonemeCode2('1','1'); // default tone 5 } p->tone_ph = tone_ph; tph = phoneme_tab[tone_ph]; } else { tone_promoted = 0; } if(ix == final_stressed) { if((tph->mnemonic == 0x3535 ) || (tph->mnemonic == 0x3135)) { // change sentence final tone 1 or 4 to stress 6, not 7 phoneme_list[final_stressed].stresslevel = 6; } } if(prevw_tph->mnemonic == 0x343132) // [214] { if(tph->mnemonic == 0x343132) // [214] prev_p->tone_ph = PhonemeCode2('3','5'); else prev_p->tone_ph = PhonemeCode2('2','1'); } if((prev_tph->mnemonic == 0x3135) && (tph->mnemonic == 0x3135)) // [51] + [51] { prev_p->tone_ph = PhonemeCode2('5','3'); } if(tph->mnemonic == 0x3131) // [11] Tone 5 { // tone 5, change its level depending on the previous tone (across word boundaries) if(prevw_tph->mnemonic == 0x3535) p->tone_ph = PhonemeCode2('2','2'); if(prevw_tph->mnemonic == 0x3533) p->tone_ph = PhonemeCode2('3','3'); if(prevw_tph->mnemonic == 0x343132) p->tone_ph = PhonemeCode2('4','4'); // tone 5 is unstressed (shorter) p->stresslevel = 0; // diminished stress } } prev_p = p; // prev2_tph = prevw_tph; prevw_tph = prev_tph = tph; pause = 0; } } // convert tone numbers to pitch p = &phoneme_list[0]; for(ix=0; ixsynthflags & SFLAG_SYLLABLE) { tone_ph = p->tone_ph; if(p->stresslevel != 0) // TEST, consider all syllables as stressed { if(ix == final_stressed) { // the last stressed syllable pitch_adjust = pitch_low; } else { pitch_adjust -= pitch_decrement; if(pitch_adjust <= pitch_low) pitch_adjust = pitch_high; } } if(tone_ph ==0) { tone_ph = phonDEFAULTTONE; // no tone specified, use default tone 1 p->tone_ph = tone_ph; } p->pitch1 = pitch_adjust + phoneme_tab[tone_ph]->start_type; p->pitch2 = pitch_adjust + phoneme_tab[tone_ph]->end_type; } } } // end of Translator::CalcPitches_Tone void CalcPitches(Translator *tr, int clause_type) {//============================================== // clause_type: 0=. 1=, 2=?, 3=! 4=none PHONEME_LIST *p; SYLLABLE *syl; int ix; int x; int st_ix; int n_st; int option; int group_tone; int group_tone_emph; int group_tone_comma; int ph_start=0; int st_start; int st_clause_end; int count; int n_primary; int count_primary; PHONEME_TAB *ph; int ph_end=n_phoneme_list; SYLLABLE syllable_tab2[N_PHONEME_LIST]; syllable_tab = syllable_tab2; // don't use permanent storage. it's only needed during the call of CalcPitches() n_st = 0; n_primary = 0; for(ix=0; ix<(n_phoneme_list-1); ix++) { p = &phoneme_list[ix]; if(p->synthflags & SFLAG_SYLLABLE) { syllable_tab[n_st].flags = 0; syllable_tab[n_st].env = PITCHfall; syllable_tab[n_st].nextph_type = phoneme_list[ix+1].type; syllable_tab[n_st++].stress = p->stresslevel; if(p->stresslevel >= 4) n_primary++; } else if((p->ph->code == phonPAUSE_CLAUSE) && (n_st > 0)) { syllable_tab[n_st-1].flags |= SYL_END_CLAUSE; } } syllable_tab[n_st].stress = 0; // extra 0 entry at the end if(n_st == 0) return; // nothing to do if(tr->langopts.tone_language == 1) { CalcPitches_Tone(tr,clause_type); return; } option = tr->langopts.intonation_group; if(option >= INTONATION_TYPES) option = 1; if(option == 0) { group_tone = tr->langopts.tunes[clause_type]; group_tone_emph = tr->langopts.tunes[5]; group_tone_comma = tr->langopts.tunes[1]; } else { group_tone = tr->punct_to_tone[option][clause_type]; group_tone_emph = tr->punct_to_tone[option][5]; // emphatic form of statement group_tone_comma = tr->punct_to_tone[option][1]; // emphatic form of statement } if(clause_type == 4) no_tonic = 1; /* incomplete clause, used for abbreviations such as Mr. Dr. Mrs. */ else no_tonic = 0; st_start = 0; count_primary=0; for(st_ix=0; st_ixstress >= 4) count_primary++; if(syl->stress == 6) { // reduce the stress of the previous stressed syllable (review only the previous few syllables) for(ix=st_ix-1; ix>=st_start && ix>=(st_ix-3); ix--) { if(syllable_tab[ix].stress == 6) break; if(syllable_tab[ix].stress == 4) { syllable_tab[ix].stress = 3; break; } } // are the next primary syllables also emphasized ? for(ix=st_ix+1; ixstress = 5; break; } } } if(syl->stress == 6) { // an emphasized syllable, end the tone group after the next primary stress syllable_tab[st_ix].flags = SYL_EMPHASIS; count = 0; if((n_primary - count_primary) > 1) count =1; for(ix=st_ix+1; ix 4) break; if(syllable_tab[ix].stress == 4) { count++; if(count > 1) break; } } count_pitch_vowels(st_start, ix, n_st); if((ix < n_st) || (clause_type == 0)) calc_pitches(option, st_start, ix, group_tone_emph); // split into > 1 tone groups, use emphatic tone else calc_pitches(option, st_start, ix, group_tone); st_start = ix; } if((st_start < st_ix) && (syl->flags & SYL_END_CLAUSE)) { // end of clause after this syllable, indicated by a phonPAUSE_CLAUSE phoneme st_clause_end = st_ix+1; count_pitch_vowels(st_start, st_clause_end, st_clause_end); calc_pitches(option, st_start, st_clause_end, group_tone_comma); st_start = st_clause_end; } } if(st_start < st_ix) { count_pitch_vowels(st_start, st_ix, n_st); calc_pitches(option, st_start, st_ix, group_tone); } // unpack pitch data st_ix=0; for(ix=ph_start; ix < ph_end; ix++) { p = &phoneme_list[ix]; p->stresslevel = syllable_tab[st_ix].stress; if(p->synthflags & SFLAG_SYLLABLE) { syl = &syllable_tab[st_ix]; p->pitch1 = syl->pitch1; p->pitch2 = syl->pitch2; p->env = PITCHfall; if(syl->flags & SYL_RISE) { p->env = PITCHrise; } else if(p->stresslevel > 5) p->env = syl->env; if(p->pitch1 > p->pitch2) { // swap so that pitch2 is the higher x = p->pitch1; p->pitch1 = p->pitch2; p->pitch2 = x; } if(p->tone_ph) { ph = phoneme_tab[p->tone_ph]; x = (p->pitch1 + p->pitch2)/2; p->pitch2 = x + ph->end_type; p->pitch1 = x + ph->start_type; } if(syl->flags & SYL_EMPHASIS) { p->stresslevel |= 8; // emphasized } st_ix++; } } } // end of CalcPitches praat-6.0.04/external/espeak/klatt.cpp000066400000000000000000001033031261542461700176350ustar00rootroot00000000000000 /*************************************************************************** * Copyright (C) 2008 by Jonathan Duddington * * email: jonsd@users.sourceforge.net * * * * Based on a re-implementation by: * * (c) 1993,94 Jon Iles and Nick Ing-Simmons * * of the Klatt cascade-parallel formant synthesizer * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, see: * * . * ***************************************************************************/ // See URL: ftp://svr-ftp.eng.cam.ac.uk/pub/comp.speech/synthesis/klatt.3.04.tar.gz #include "StdAfx.h" #include #include #include #include #include "speak_lib.h" #include "speech.h" #include "klatt.h" #include "phoneme.h" #include "synthesize.h" #include "voice.h" #ifdef INCLUDE_KLATT // conditional compilation for the whole file extern unsigned char *out_ptr; // **JSD extern unsigned char *out_start; extern unsigned char *out_end; extern WGEN_DATA wdata; static int nsamples; static int sample_count; #ifdef _MSC_VER #define getrandom(min,max) ((rand()%(int)(((max)+1)-(min)))+(min)) #else #define getrandom(min,max) ((rand()%(long)(((max)+1)-(min)))+(min)) #endif /* function prototypes for functions private to this file */ static void flutter(klatt_frame_ptr); static double sampled_source (void); static double impulsive_source (void); static double natural_source (void); static void pitch_synch_par_reset (klatt_frame_ptr); static double gen_noise (double); static double DBtoLIN (long); static void frame_init (klatt_frame_ptr); static void setabc (long,long,resonator_ptr); static void setzeroabc (long,long,resonator_ptr); static klatt_frame_t kt_frame; static klatt_global_t kt_globals; /* function RESONATOR This is a generic resonator function. Internal memory for the resonator is stored in the globals structure. */ static double resonator(resonator_ptr r, double input) { double x; x = (double) ((double)r->a * (double)input + (double)r->b * (double)r->p1 + (double)r->c * (double)r->p2); r->p2 = (double)r->p1; r->p1 = (double)x; return (double)x; } static double resonator2(resonator_ptr r, double input) { double x; x = (double) ((double)r->a * (double)input + (double)r->b * (double)r->p1 + (double)r->c * (double)r->p2); r->p2 = (double)r->p1; r->p1 = (double)x; r->a += r->a_inc; r->b += r->b_inc; r->c += r->c_inc; return (double)x; } /* function ANTIRESONATOR This is a generic anti-resonator function. The code is the same as resonator except that a,b,c need to be set with setzeroabc() and we save inputs in p1/p2 rather than outputs. There is currently only one of these - "rnz" Output = (rnz.a * input) + (rnz.b * oldin1) + (rnz.c * oldin2) */ #ifdef deleted static double antiresonator(resonator_ptr r, double input) { register double x = (double)r->a * (double)input + (double)r->b * (double)r->p1 + (double)r->c * (double)r->p2; r->p2 = (double)r->p1; r->p1 = (double)input; return (double)x; } #endif static double antiresonator2(resonator_ptr r, double input) { register double x = (double)r->a * (double)input + (double)r->b * (double)r->p1 + (double)r->c * (double)r->p2; r->p2 = (double)r->p1; r->p1 = (double)input; r->a += r->a_inc; r->b += r->b_inc; r->c += r->c_inc; return (double)x; } /* function FLUTTER This function adds F0 flutter, as specified in: "Analysis, synthesis and perception of voice quality variations among female and male talkers" D.H. Klatt and L.C. Klatt JASA 87(2) February 1990. Flutter is added by applying a quasi-random element constructed from three slowly varying sine waves. */ static void flutter(klatt_frame_ptr frame) { static int time_count; double delta_f0; double fla,flb,flc,fld,fle; fla = (double) kt_globals.f0_flutter / 50; flb = (double) kt_globals.original_f0 / 100; // flc = sin(2*PI*12.7*time_count); // fld = sin(2*PI*7.1*time_count); // fle = sin(2*PI*4.7*time_count); flc = sin(PI*12.7*time_count); // because we are calling flutter() more frequently, every 2.9mS fld = sin(PI*7.1*time_count); fle = sin(PI*4.7*time_count); delta_f0 = fla * flb * (flc + fld + fle) * 10; frame->F0hz10 = frame->F0hz10 + (long) delta_f0; time_count++; } /* function SAMPLED_SOURCE Allows the use of a glottal excitation waveform sampled from a real voice. */ static double sampled_source() { int itemp; double ftemp; double result; double diff_value; int current_value; int next_value; double temp_diff; if(kt_globals.T0!=0) { ftemp = (double) kt_globals.nper; ftemp = ftemp / kt_globals.T0; ftemp = ftemp * kt_globals.num_samples; itemp = (int) ftemp; temp_diff = ftemp - (double) itemp; current_value = kt_globals.natural_samples[itemp]; next_value = kt_globals.natural_samples[itemp+1]; diff_value = (double) next_value - (double) current_value; diff_value = diff_value * temp_diff; result = kt_globals.natural_samples[itemp] + diff_value; result = result * kt_globals.sample_factor; } else { result = 0; } return(result); } /* function PARWAVE Converts synthesis parameters to a waveform. */ static int parwave(klatt_frame_ptr frame) { double temp; int value; double outbypas; double out; long n4; double frics; double glotout; double aspiration; double casc_next_in; double par_glotout; static double noise; static double voice; static double vlast; static double glotlast; static double sourc; int ix; flutter(frame); /* add f0 flutter */ #ifdef LOG_FRAMES if(option_log_frames) { FILE *f; f=fopen("log-klatt","a"); /* * ppgb: BUG; vervangen door fwrite (Melder_sprint... */ fprintf(f,"%4dhz %2dAV %4d %3d, %4d %3d, %4d %3d, %4d %3d, %4d, %3d, FNZ=%3d TLT=%2d\n",frame->F0hz10,frame->AVdb, frame->Fhz[1],frame->Bhz[1],frame->Fhz[2],frame->Bhz[2],frame->Fhz[3],frame->Bhz[3],frame->Fhz[4],frame->Bhz[4],frame->Fhz[5],frame->Bhz[5],frame->Fhz[0],frame->TLTdb); fclose(f); } #endif /* MAIN LOOP, for each output sample of current frame: */ for (kt_globals.ns=0; kt_globals.ns kt_globals.nmod) { noise *= (double) 0.5; } /* Compute frication noise */ frics = kt_globals.amp_frica * noise; /* Compute voicing waveform. Run glottal source simulation at 4 times normal sample rate to minimize quantization noise in period of female voice. */ for (n4=0; n4<4; n4++) { switch(kt_globals.glsource) { case IMPULSIVE: voice = impulsive_source(); break; case NATURAL: voice = natural_source(); break; case SAMPLED: voice = sampled_source(); break; } /* Reset period when counter 'nper' reaches T0 */ if (kt_globals.nper >= kt_globals.T0) { kt_globals.nper = 0; pitch_synch_par_reset(frame); } /* Low-pass filter voicing waveform before downsampling from 4*samrate to samrate samples/sec. Resonator f=.09*samrate, bw=.06*samrate */ voice = resonator(&(kt_globals.rsn[RLP]),voice); /* Increment counter that keeps track of 4*samrate samples per sec */ kt_globals.nper++; } /* Tilt spectrum of voicing source down by soft low-pass filtering, amount of tilt determined by TLTdb */ voice = (voice * kt_globals.onemd) + (vlast * kt_globals.decay); vlast = voice; /* Add breathiness during glottal open phase. Amount of breathiness determined by parameter Aturb Use nrand rather than noise because noise is low-passed. */ if (kt_globals.nper < kt_globals.nopen) { voice += kt_globals.amp_breth * kt_globals.nrand; } /* Set amplitude of voicing */ glotout = kt_globals.amp_voice * voice; par_glotout = kt_globals.par_amp_voice * voice; /* Compute aspiration amplitude and add to voicing source */ aspiration = kt_globals.amp_aspir * noise; glotout += aspiration; par_glotout += aspiration; /* Cascade vocal tract, excited by laryngeal sources. Nasal antiresonator, then formants FNP, F5, F4, F3, F2, F1 */ out=0; if(kt_globals.synthesis_model != ALL_PARALLEL) { casc_next_in = antiresonator2(&(kt_globals.rsn[Rnz]),glotout); casc_next_in = resonator(&(kt_globals.rsn[Rnpc]),casc_next_in); casc_next_in = resonator(&(kt_globals.rsn[R8c]),casc_next_in); casc_next_in = resonator(&(kt_globals.rsn[R7c]),casc_next_in); casc_next_in = resonator(&(kt_globals.rsn[R6c]),casc_next_in); casc_next_in = resonator2(&(kt_globals.rsn[R5c]),casc_next_in); casc_next_in = resonator2(&(kt_globals.rsn[R4c]),casc_next_in); casc_next_in = resonator2(&(kt_globals.rsn[R3c]),casc_next_in); casc_next_in = resonator2(&(kt_globals.rsn[R2c]),casc_next_in); out = resonator2(&(kt_globals.rsn[R1c]),casc_next_in); } /* Excite parallel F1 and FNP by voicing waveform */ sourc = par_glotout; /* Source is voicing plus aspiration */ /* Standard parallel vocal tract Formants F6,F5,F4,F3,F2, outputs added with alternating sign. Sound source for other parallel resonators is frication plus first difference of voicing waveform. */ out += resonator(&(kt_globals.rsn[R1p]),sourc); out += resonator(&(kt_globals.rsn[Rnpp]),sourc); sourc = frics + par_glotout - glotlast; glotlast = par_glotout; for(ix=R2p; ix<=R6p; ix++) { out = resonator(&(kt_globals.rsn[ix]),sourc) - out; } outbypas = kt_globals.amp_bypas * sourc; out = outbypas - out; #ifdef deleted // for testing if (kt_globals.outsl != 0) { switch(kt_globals.outsl) { case 1: out = voice; break; case 2: out = aspiration; break; case 3: out = frics; break; case 4: out = glotout; break; case 5: out = par_glotout; break; case 6: out = outbypas; break; case 7: out = sourc; break; } } #endif out = resonator(&(kt_globals.rsn[Rout]),out); temp = (int)(out * wdata.amplitude * kt_globals.amp_gain0) ; /* Convert back to integer */ // mix with a recorded WAV if required for this phoneme { int z2; signed char c; int sample; z2 = 0; if(wdata.mix_wavefile_ix < wdata.n_mix_wavefile) { if(wdata.mix_wave_scale == 0) { // a 16 bit sample c = wdata.mix_wavefile[wdata.mix_wavefile_ix+1]; sample = wdata.mix_wavefile[wdata.mix_wavefile_ix] + (c * 256); wdata.mix_wavefile_ix += 2; } else { // a 8 bit sample, scaled sample = (signed char)wdata.mix_wavefile[wdata.mix_wavefile_ix++] * wdata.mix_wave_scale; } z2 = sample * wdata.amplitude_v / 1024; z2 = (z2 * wdata.mix_wave_amp)/40; temp += z2; } } // if fadeout is set, fade to zero over 64 samples, to avoid clicks at end of synthesis if(kt_globals.fadeout > 0) { kt_globals.fadeout--; temp = (temp * kt_globals.fadeout) / 64; } value = (int)temp + ((echo_buf[echo_tail++]*echo_amp) >> 8); if(echo_tail >= N_ECHO_BUF) echo_tail=0; if (value < -32768) { value = -32768; } if (value > 32767) { value = 32767; } *out_ptr++ = value; *out_ptr++ = value >> 8; echo_buf[echo_head++] = value; if(echo_head >= N_ECHO_BUF) echo_head = 0; sample_count++; if(out_ptr >= out_end) { return(1); } } return(0); } // end of parwave void KlattReset(int control) { int r_ix; if(control == 2) { //Full reset kt_globals.FLPhz = (950 * kt_globals.samrate) / 10000; kt_globals.BLPhz = (630 * kt_globals.samrate) / 10000; kt_globals.minus_pi_t = -PI / kt_globals.samrate; kt_globals.two_pi_t = -2.0 * kt_globals.minus_pi_t; setabc(kt_globals.FLPhz,kt_globals.BLPhz,&(kt_globals.rsn[RLP])); } if(control > 0) { kt_globals.nper = 0; kt_globals.T0 = 0; kt_globals.nopen = 0; kt_globals.nmod = 0; for(r_ix=RGL; r_ix < N_RSN; r_ix++) { kt_globals.rsn[r_ix].p1 = 0; kt_globals.rsn[r_ix].p2 = 0; } } for(r_ix=0; r_ix <= R6p; r_ix++) { kt_globals.rsn[r_ix].p1 = 0; kt_globals.rsn[r_ix].p2 = 0; } } /* function FRAME_INIT Use parameters from the input frame to set up resonator coefficients. */ static void frame_init(klatt_frame_ptr frame) { double amp_par[7]; static double amp_par_factor[7] = {0.6, 0.4, 0.15, 0.06, 0.04, 0.022, 0.03}; long Gain0_tmp; int ix; kt_globals.original_f0 = frame->F0hz10 / 10; frame->AVdb_tmp = frame->AVdb - 7; if (frame->AVdb_tmp < 0) { frame->AVdb_tmp = 0; } kt_globals.amp_aspir = DBtoLIN(frame->ASP) * 0.05; kt_globals.amp_frica = DBtoLIN(frame->AF) * 0.25; kt_globals.par_amp_voice = DBtoLIN(frame->AVpdb); kt_globals.amp_bypas = DBtoLIN(frame->AB) * 0.05; for(ix=0; ix <= 6; ix++) { // parallel amplitudes F1 to F6, and parallel nasal pole amp_par[ix] = DBtoLIN(frame->Ap[ix]) * amp_par_factor[ix]; } Gain0_tmp = frame->Gain0 - 3; if (Gain0_tmp <= 0) { Gain0_tmp = 57; } kt_globals.amp_gain0 = DBtoLIN(Gain0_tmp) / kt_globals.scale_wav; /* Set coefficients of variable cascade resonators */ for(ix=1; ix<=9; ix++) { // formants 1 to 8, plus nasal pole setabc(frame->Fhz[ix],frame->Bhz[ix],&(kt_globals.rsn[ix])); if(ix <= 5) { setabc(frame->Fhz_next[ix],frame->Bhz_next[ix],&(kt_globals.rsn_next[ix])); kt_globals.rsn[ix].a_inc = (kt_globals.rsn_next[ix].a - kt_globals.rsn[ix].a) / 64.0; kt_globals.rsn[ix].b_inc = (kt_globals.rsn_next[ix].b - kt_globals.rsn[ix].b) / 64.0; kt_globals.rsn[ix].c_inc = (kt_globals.rsn_next[ix].c - kt_globals.rsn[ix].c) / 64.0; } } // nasal zero anti-resonator setzeroabc(frame->Fhz[F_NZ],frame->Bhz[F_NZ],&(kt_globals.rsn[Rnz])); setzeroabc(frame->Fhz_next[F_NZ],frame->Bhz_next[F_NZ],&(kt_globals.rsn_next[Rnz])); kt_globals.rsn[F_NZ].a_inc = (kt_globals.rsn_next[F_NZ].a - kt_globals.rsn[F_NZ].a) / 64.0; kt_globals.rsn[F_NZ].b_inc = (kt_globals.rsn_next[F_NZ].b - kt_globals.rsn[F_NZ].b) / 64.0; kt_globals.rsn[F_NZ].c_inc = (kt_globals.rsn_next[F_NZ].c - kt_globals.rsn[F_NZ].c) / 64.0; /* Set coefficients of parallel resonators, and amplitude of outputs */ for(ix=0; ix<=6; ix++) { setabc(frame->Fhz[ix],frame->Bphz[ix],&(kt_globals.rsn[Rparallel+ix])); kt_globals.rsn[Rparallel+ix].a *= amp_par[ix]; } /* output low-pass filter */ setabc((long)0.0,(long)(kt_globals.samrate/2),&(kt_globals.rsn[Rout])); } /* function IMPULSIVE_SOURCE Generate a low pass filtered train of impulses as an approximation of a natural excitation waveform. Low-pass filter the differentiated impulse with a critically-damped second-order filter, time constant proportional to Kopen. */ static double impulsive_source() { static double doublet[] = {0.0,13000000.0,-13000000.0}; static double vwave; if (kt_globals.nper < 3) { vwave = doublet[kt_globals.nper]; } else { vwave = 0.0; } return(resonator(&(kt_globals.rsn[RGL]),vwave)); } /* function NATURAL_SOURCE Vwave is the differentiated glottal flow waveform, there is a weak spectral zero around 800 Hz, magic constants a,b reset pitch synchronously. */ static double natural_source() { double lgtemp; static double vwave; if (kt_globals.nper < kt_globals.nopen) { kt_globals.pulse_shape_a -= kt_globals.pulse_shape_b; vwave += kt_globals.pulse_shape_a; lgtemp=vwave * 0.028; return(lgtemp); } else { vwave = 0.0; return(0.0); } } /* function PITCH_SYNC_PAR_RESET Reset selected parameters pitch-synchronously. Constant B0 controls shape of glottal pulse as a function of desired duration of open phase N0 (Note that N0 is specified in terms of 40,000 samples/sec of speech) Assume voicing waveform V(t) has form: k1 t**2 - k2 t**3 If the radiation characterivative, a temporal derivative is folded in, and we go from continuous time to discrete integers n: dV/dt = vwave[n] = sum over i=1,2,...,n of { a - (i * b) } = a n - b/2 n**2 where the constants a and b control the detailed shape and amplitude of the voicing waveform over the open potion of the voicing cycle "nopen". Let integral of dV/dt have no net dc flow --> a = (b * nopen) / 3 Let maximum of dUg(n)/dn be constant --> b = gain / (nopen * nopen) meaning as nopen gets bigger, V has bigger peak proportional to n Thus, to generate the table below for 40 <= nopen <= 263: B0[nopen - 40] = 1920000 / (nopen * nopen) */ static void pitch_synch_par_reset(klatt_frame_ptr frame) { long temp; double temp1; static long skew; static short B0[224] = { 1200,1142,1088,1038, 991, 948, 907, 869, 833, 799, 768, 738, 710, 683, 658, 634, 612, 590, 570, 551, 533, 515, 499, 483, 468, 454, 440, 427, 415, 403, 391, 380, 370, 360, 350, 341, 332, 323, 315, 307, 300, 292, 285, 278, 272, 265, 259, 253, 247, 242, 237, 231, 226, 221, 217, 212, 208, 204, 199, 195, 192, 188, 184, 180, 177, 174, 170, 167, 164, 161, 158, 155, 153, 150, 147, 145, 142, 140, 137, 135, 133, 131, 128, 126, 124, 122, 120, 119, 117, 115, 113,111, 110, 108, 106, 105, 103, 102, 100, 99, 97, 96, 95, 93, 92, 91, 90, 88, 87, 86, 85, 84, 83, 82, 80, 79, 78, 77, 76, 75, 75, 74, 73, 72, 71, 70, 69, 68, 68, 67, 66, 65, 64, 64, 63, 62, 61, 61, 60, 59, 59, 58, 57, 57, 56, 56, 55, 55, 54, 54, 53, 53, 52, 52, 51, 51, 50, 50, 49, 49, 48, 48, 47, 47, 46, 46, 45, 45, 44, 44, 43, 43, 42, 42, 41, 41, 41, 41, 40, 40, 39, 39, 38, 38, 38, 38, 37, 37, 36, 36, 36, 36, 35, 35, 35, 35, 34, 34,33, 33, 33, 33, 32, 32, 32, 32, 31, 31, 31, 31, 30, 30, 30, 30, 29, 29, 29, 29, 28, 28, 28, 28, 27, 27 }; if (frame->F0hz10 > 0) { /* T0 is 4* the number of samples in one pitch period */ kt_globals.T0 = (40 * kt_globals.samrate) / frame->F0hz10; kt_globals.amp_voice = DBtoLIN(frame->AVdb_tmp); /* Duration of period before amplitude modulation */ kt_globals.nmod = kt_globals.T0; if (frame->AVdb_tmp > 0) { kt_globals.nmod >>= 1; } /* Breathiness of voicing waveform */ kt_globals.amp_breth = DBtoLIN(frame->Aturb) * 0.1; /* Set open phase of glottal period where 40 <= open phase <= 263 */ kt_globals.nopen = 4 * frame->Kopen; if ((kt_globals.glsource == IMPULSIVE) && (kt_globals.nopen > 263)) { kt_globals.nopen = 263; } if (kt_globals.nopen >= (kt_globals.T0-1)) { // printf("Warning: glottal open period cannot exceed T0, truncated\n"); kt_globals.nopen = kt_globals.T0 - 2; } if (kt_globals.nopen < 40) { /* F0 max = 1000 Hz */ // printf("Warning: minimum glottal open period is 10 samples.\n"); // printf("truncated, nopen = %d\n",kt_globals.nopen); kt_globals.nopen = 40; } /* Reset a & b, which determine shape of "natural" glottal waveform */ kt_globals.pulse_shape_b = B0[kt_globals.nopen-40]; kt_globals.pulse_shape_a = (kt_globals.pulse_shape_b * kt_globals.nopen) * 0.333; /* Reset width of "impulsive" glottal pulse */ temp = kt_globals.samrate / kt_globals.nopen; setabc((long)0,temp,&(kt_globals.rsn[RGL])); /* Make gain at F1 about constant */ temp1 = kt_globals.nopen *.00833; kt_globals.rsn[RGL].a *= temp1 * temp1; /* Truncate skewness so as not to exceed duration of closed phase of glottal period. */ temp = kt_globals.T0 - kt_globals.nopen; if (frame->Kskew > temp) { // printf("Kskew duration=%d > glottal closed period=%d, truncate\n", frame->Kskew, kt_globals.T0 - kt_globals.nopen); frame->Kskew = temp; } if (skew >= 0) { skew = frame->Kskew; } else { skew = - frame->Kskew; } /* Add skewness to closed portion of voicing period */ kt_globals.T0 = kt_globals.T0 + skew; skew = - skew; } else { kt_globals.T0 = 4; /* Default for f0 undefined */ kt_globals.amp_voice = 0.0; kt_globals.nmod = kt_globals.T0; kt_globals.amp_breth = 0.0; kt_globals.pulse_shape_a = 0.0; kt_globals.pulse_shape_b = 0.0; } /* Reset these pars pitch synchronously or at update rate if f0=0 */ if ((kt_globals.T0 != 4) || (kt_globals.ns == 0)) { /* Set one-pole low-pass filter that tilts glottal source */ kt_globals.decay = (0.033 * frame->TLTdb); if (kt_globals.decay > 0.0) { kt_globals.onemd = 1.0 - kt_globals.decay; } else { kt_globals.onemd = 1.0; } } } /* function SETABC Convert formant freqencies and bandwidth into resonator difference equation constants. */ static void setabc(long int f, long int bw, resonator_ptr rp) { double r; double arg; /* Let r = exp(-pi bw t) */ arg = kt_globals.minus_pi_t * bw; r = exp(arg); /* Let c = -r**2 */ rp->c = -(r * r); /* Let b = r * 2*cos(2 pi f t) */ arg = kt_globals.two_pi_t * f; rp->b = r * cos(arg) * 2.0; /* Let a = 1.0 - b - c */ rp->a = 1.0 - rp->b - rp->c; } /* function SETZEROABC Convert formant freqencies and bandwidth into anti-resonator difference equation constants. */ static void setzeroabc(long int f, long int bw, resonator_ptr rp) { double r; double arg; f = -f; //NOTE, changes made 30.09.2011 for Reece Dunn // fix a sound spike when f=0 /* First compute ordinary resonator coefficients */ /* Let r = exp(-pi bw t) */ arg = kt_globals.minus_pi_t * bw; r = exp(arg); /* Let c = -r**2 */ rp->c = -(r * r); /* Let b = r * 2*cos(2 pi f t) */ arg = kt_globals.two_pi_t * f; rp->b = r * cos(arg) * 2.; /* Let a = 1.0 - b - c */ rp->a = 1.0 - rp->b - rp->c; /* Now convert to antiresonator coefficients (a'=1/a, b'=b/a, c'=c/a) */ /* If f == 0 then rp->a gets set to 0 which makes a'=1/a set a', b' and c' to * INF, causing an audible sound spike when triggered (e.g. apiration with the * nasal register set to f=0, bw=0). */ if (rp->a != 0) { /* Now convert to antiresonator coefficients (a'=1/a, b'=b/a, c'=c/a) */ rp->a = 1.0 / rp->a; rp->c *= -rp->a; rp->b *= -rp->a; } } /* function GEN_NOISE Random number generator (return a number between -8191 and +8191) Noise spectrum is tilted down by soft low-pass filter having a pole near the origin in the z-plane, i.e. output = input + (0.75 * lastoutput) */ static double gen_noise(double noise) { long temp; static double nlast; temp = (long) getrandom(-8191,8191); kt_globals.nrand = (long) temp; noise = kt_globals.nrand + (0.75 * nlast); nlast = noise; return(noise); } /* function DBTOLIN Convert from decibels to a linear scale factor Conversion table, db to linear, 87 dB --> 32767 86 dB --> 29491 (1 dB down = 0.5**1/6) ... 81 dB --> 16384 (6 dB down = 0.5) ... 0 dB --> 0 The just noticeable difference for a change in intensity of a vowel is approximately 1 dB. Thus all amplitudes are quantized to 1 dB steps. */ static double DBtoLIN(long dB) { static short amptable[88] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 13, 14, 16, 18, 20, 22, 25, 28, 32, 35, 40, 45, 51, 57, 64, 71, 80, 90, 101, 114, 128, 142, 159, 179, 202, 227, 256, 284, 318, 359, 405, 455, 512, 568, 638, 719, 881, 911, 1024, 1137, 1276, 1438, 1622, 1823, 2048, 2273, 2552, 2875, 3244, 3645, 4096, 4547, 5104, 5751, 6488, 7291, 8192, 9093, 10207, 11502, 12976, 14582, 16384, 18350, 20644, 23429, 26214, 29491, 32767 }; if ((dB < 0) || (dB > 87)) { return(0); } return((double)(amptable[dB]) * 0.001); } extern voice_t *wvoice; static klatt_peaks_t peaks[N_PEAKS]; static int end_wave; static int klattp[N_KLATTP]; static double klattp1[N_KLATTP]; static double klattp_inc[N_KLATTP]; static int scale_wav_tab[] = {45,38,45,45}; // scale output from different voicing sources int Wavegen_Klatt(int resume) {//========================== int pk; int x; int ix; int fade; if(resume==0) { sample_count = 0; } while(sample_count < nsamples) { kt_frame.F0hz10 = (wdata.pitch * 10) / 4096; // formants F6,F7,F8 are fixed values for cascade resonators, set in KlattInit() // but F6 is used for parallel resonator // F0 is used for the nasal zero for(ix=0; ix < 6; ix++) { kt_frame.Fhz[ix] = peaks[ix].freq; if(ix < 4) { kt_frame.Bhz[ix] = peaks[ix].bw; } } for(ix=1; ix < 7; ix++) { kt_frame.Ap[ix] = 0; } kt_frame.AVdb = klattp[KLATT_AV]; kt_frame.AVpdb = klattp[KLATT_AVp]; kt_frame.AF = klattp[KLATT_Fric]; kt_frame.AB = klattp[KLATT_FricBP]; kt_frame.ASP = klattp[KLATT_Aspr]; kt_frame.Aturb = klattp[KLATT_Turb]; kt_frame.Kskew = klattp[KLATT_Skew]; kt_frame.TLTdb = klattp[KLATT_Tilt]; kt_frame.Kopen = klattp[KLATT_Kopen]; // advance formants for(pk=0; pk>8) > 127) ix = 127; x = wdata.pitch_env[ix] * wdata.pitch_range; wdata.pitch = (x>>8) + wdata.pitch_base; kt_globals.nspfr = (nsamples - sample_count); if(kt_globals.nspfr > STEPSIZE) kt_globals.nspfr = STEPSIZE; frame_init(&kt_frame); /* get parameters for next frame of speech */ if(parwave(&kt_frame) == 1) { return(1); // output buffer is full } } if(end_wave > 0) { #ifdef deleted if(end_wave == 2) { fade = (kt_globals.T0 - kt_globals.nper)/4; // samples until end of current cycle if(fade < 64) fade = 64; } else #endif { fade = 64; // not followd by formant synthesis } // fade out to avoid a click kt_globals.fadeout = fade; end_wave = 0; sample_count -= fade; kt_globals.nspfr = fade; if(parwave(&kt_frame) == 1) { return(1); // output buffer is full } } return(0); } void SetSynth_Klatt(int length, int modn, frame_t *fr1, frame_t *fr2, voice_t *v, int control) {//=========================================================================================== int ix; DOUBLEX next; int qix; int cmd; frame_t *fr3; static frame_t prev_fr; if(wvoice != NULL) { if((wvoice->klattv[0] > 0) && (wvoice->klattv[0] <=3 )) { kt_globals.glsource = wvoice->klattv[0]; kt_globals.scale_wav = scale_wav_tab[kt_globals.glsource]; } kt_globals.f0_flutter = wvoice->flutter/32; } end_wave = 0; if(control & 2) { end_wave = 1; // fadeout at the end } if(control & 1) { end_wave = 1; for(qix=wcmdq_head+1;;qix++) { if(qix >= N_WCMDQ) qix = 0; if(qix == wcmdq_tail) break; cmd = wcmdq[qix][0]; if(cmd==WCMD_KLATT) { end_wave = 0; // next wave generation is from another spectrum fr3 = (frame_t *)wcmdq[qix][2]; for(ix=1; ix<6; ix++) { if(fr3->ffreq[ix] != fr2->ffreq[ix]) { // there is a discontinuity in formants end_wave = 2; break; } } break; } if((cmd==WCMD_WAVE) || (cmd==WCMD_PAUSE)) break; // next is not from spectrum, so continue until end of wave cycle } } #ifdef LOG_FRAMES if(option_log_frames) { FILE *f_log; f_log=fopen("log-espeakedit","a"); /* * ppgb: BUG; vervangen door fwrite (Melder_sprint... */ if(f_log != NULL) { fprintf(f_log,"K %3dmS %3d %3d %4d %4d %4d %4d (%2d) to %3d %3d %4d %4d %4d %4d (%2d)\n",length*1000/samplerate, fr1->klattp[KLATT_FNZ]*2,fr1->ffreq[1],fr1->ffreq[2],fr1->ffreq[3],fr1->ffreq[4],fr1->ffreq[5], fr1->klattp[KLATT_AV], fr2->klattp[KLATT_FNZ]*2,fr2->ffreq[1],fr2->ffreq[2],fr2->ffreq[3],fr1->ffreq[4],fr1->ffreq[5], fr2->klattp[KLATT_AV] ); fclose(f_log); } f_log=fopen("log-klatt","a"); /* * ppgb: BUG; vervangen door fwrite (Melder_sprint... */ if(f_log != NULL) { fprintf(f_log,"K %3dmS %3d %3d %4d %4d (%2d) to %3d %3d %4d %4d (%2d)\n",length*1000/samplerate, fr1->klattp[KLATT_FNZ]*2,fr1->ffreq[1],fr1->ffreq[2],fr1->ffreq[3], fr1->klattp[KLATT_AV], fr2->klattp[KLATT_FNZ]*2,fr2->ffreq[1],fr2->ffreq[2],fr2->ffreq[3], fr2->klattp[KLATT_AV] ); fclose(f_log); } } #endif if(control & 1) { for(ix=1; ix<6; ix++) { if(prev_fr.ffreq[ix] != fr1->ffreq[ix]) { // Discontinuity in formants. // end_wave was set in SetSynth_Klatt() to fade out the previous frame KlattReset(0); break; } } memcpy(&prev_fr,fr2,sizeof(prev_fr)); } for(ix=0; ix= 5) && ((fr1->frflags & FRFLAG_KLATT) == 0)) { klattp1[ix] = klattp[ix] = 0; klattp_inc[ix] = 0; } else { klattp1[ix] = klattp[ix] = fr1->klattp[ix]; klattp_inc[ix] = (double)((fr2->klattp[ix] - klattp[ix]) * STEPSIZE)/length; } // get klatt parameter adjustments for the voice // if((ix>0) && (ix < KLATT_AVp)) // klattp1[ix] = klattp[ix] = (klattp[ix] + wvoice->klattv[ix]); } nsamples = length; for(ix=1; ix < 6; ix++) { peaks[ix].freq1 = (fr1->ffreq[ix] * v->freq[ix] / 256.0) + v->freqadd[ix]; peaks[ix].freq = (int)peaks[ix].freq1; next = (fr2->ffreq[ix] * v->freq[ix] / 256.0) + v->freqadd[ix]; peaks[ix].freq_inc = ((next - peaks[ix].freq1) * STEPSIZE) / length; if(ix < 4) { // klatt bandwidth for f1, f2, f3 (others are fixed) peaks[ix].bw1 = fr1->bw[ix] * 2; peaks[ix].bw = (int)peaks[ix].bw1; next = fr2->bw[ix] * 2; peaks[ix].bw_inc = ((next - peaks[ix].bw1) * STEPSIZE) / length; } } // nasal zero frequency peaks[0].freq1 = fr1->klattp[KLATT_FNZ] * 2; if(peaks[0].freq1 == 0) peaks[0].freq1 = kt_frame.Fhz[F_NP]; // if no nasal zero, set it to same freq as nasal pole peaks[0].freq = (int)peaks[0].freq1; next = fr2->klattp[KLATT_FNZ] * 2; if(next == 0) next = kt_frame.Fhz[F_NP]; peaks[0].freq_inc = ((next - peaks[0].freq1) * STEPSIZE) / length; peaks[0].bw1 = 89; peaks[0].bw = 89; peaks[0].bw_inc = 0; if(fr1->frflags & FRFLAG_KLATT) { // the frame contains additional parameters for parallel resonators for(ix=1; ix < 7; ix++) { peaks[ix].bp1 = fr1->klatt_bp[ix] * 4; // parallel bandwidth peaks[ix].bp = (int)peaks[ix].bp1; next = fr2->klatt_bp[ix] * 2; peaks[ix].bp_inc = ((next - peaks[ix].bp1) * STEPSIZE) / length; peaks[ix].ap1 = fr1->klatt_ap[ix]; // parallal amplitude peaks[ix].ap = (int)peaks[ix].ap1; next = fr2->klatt_ap[ix] * 2; peaks[ix].ap_inc = ((next - peaks[ix].ap1) * STEPSIZE) / length; } } } // end of SetSynth_Klatt int Wavegen_Klatt2(int length, int modulation, int resume, frame_t *fr1, frame_t *fr2) {//=================================================================================== if(resume==0) SetSynth_Klatt(length, modulation, fr1, fr2, wvoice, 1); return(Wavegen_Klatt(resume)); } void KlattInit() { #define NUMBER_OF_SAMPLES 100 static short natural_samples[NUMBER_OF_SAMPLES]= { -310,-400,530,356,224,89,23,-10,-58,-16,461,599,536,701,770, 605,497,461,560,404,110,224,131,104,-97,155,278,-154,-1165, -598,737,125,-592,41,11,-247,-10,65,92,80,-304,71,167,-1,122, 233,161,-43,278,479,485,407,266,650,134,80,236,68,260,269,179, 53,140,275,293,296,104,257,152,311,182,263,245,125,314,140,44, 203,230,-235,-286,23,107,92,-91,38,464,443,176,98,-784,-2449, -1891,-1045,-1600,-1462,-1384,-1261,-949,-730 }; static short formant_hz[10] = {280,688,1064,2806,3260,3700,6500,7000,8000,280}; static short bandwidth[10] = {89,160,70,160,200,200,500,500,500,89}; static short parallel_amp[10] = { 0,59,59,59,59,59,59,0,0,0}; static short parallel_bw[10] = {59,59,89,149,200,200,500,0,0,0}; int ix; sample_count=0; kt_globals.synthesis_model = CASCADE_PARALLEL; kt_globals.samrate = 22050; kt_globals.glsource = IMPULSIVE; // IMPULSIVE, NATURAL, SAMPLED kt_globals.scale_wav = scale_wav_tab[kt_globals.glsource]; kt_globals.natural_samples = natural_samples; kt_globals.num_samples = NUMBER_OF_SAMPLES; kt_globals.sample_factor = 3.0; kt_globals.nspfr = (kt_globals.samrate * 10) / 1000; kt_globals.outsl = 0; kt_globals.f0_flutter = 20; KlattReset(2); // set default values for frame parameters for(ix=0; ix<=9; ix++) { kt_frame.Fhz[ix] = formant_hz[ix]; kt_frame.Bhz[ix] = bandwidth[ix]; kt_frame.Ap[ix] = parallel_amp[ix]; kt_frame.Bphz[ix] = parallel_bw[ix]; } kt_frame.Bhz_next[F_NZ] = bandwidth[F_NZ]; kt_frame.F0hz10 = 1000; kt_frame.AVdb = 59; // 59 kt_frame.ASP = 0; kt_frame.Kopen = 40; // 40 kt_frame.Aturb = 0; kt_frame.TLTdb = 0; kt_frame.AF =50; kt_frame.Kskew = 0; kt_frame.AB = 0; kt_frame.AVpdb = 0; kt_frame.Gain0 = 62; // 60 } // end of KlattInit #endif // INCLUDE_KLATT praat-6.0.04/external/espeak/klatt.h000066400000000000000000000113511261542461700173030ustar00rootroot00000000000000 #define CASCADE_PARALLEL 1 /* Type of synthesis model */ #define ALL_PARALLEL 2 #define IMPULSIVE 1 /* Type of voicing source */ #define NATURAL 2 #define SAMPLED 3 #define PI 3.1415927 /* typedef's that need to be exported */ typedef long flag; /* Resonator Structure */ typedef struct { double a; double b; double c; double p1; double p2; double a_inc; double b_inc; double c_inc; } resonator_t, *resonator_ptr; /* Structure for Klatt Globals */ typedef struct { flag synthesis_model; /* cascade-parallel or all-parallel */ flag outsl; /* Output waveform selector */ long samrate; /* Number of output samples per second */ long FLPhz ; /* Frequeny of glottal downsample low-pass filter */ long BLPhz ; /* Bandwidth of glottal downsample low-pass filter */ flag glsource; /* Type of glottal source */ int f0_flutter; /* Percentage of f0 flutter 0-100 */ long nspfr; /* number of samples per frame */ long nper; /* Counter for number of samples in a pitch period */ long ns; long T0; /* Fundamental period in output samples times 4 */ long nopen; /* Number of samples in open phase of period */ long nmod; /* Position in period to begin noise amp. modul */ long nrand; /* Varible used by random number generator */ double pulse_shape_a; /* Makes waveshape of glottal pulse when open */ double pulse_shape_b; /* Makes waveshape of glottal pulse when open */ double minus_pi_t; double two_pi_t; double onemd; double decay; double amp_bypas; /* AB converted to linear gain */ double amp_voice; /* AVdb converted to linear gain */ double par_amp_voice; /* AVpdb converted to linear gain */ double amp_aspir; /* AP converted to linear gain */ double amp_frica; /* AF converted to linear gain */ double amp_breth; /* ATURB converted to linear gain */ double amp_gain0; /* G0 converted to linear gain */ int num_samples; /* number of glottal samples */ double sample_factor; /* multiplication factor for glottal samples */ short *natural_samples; /* pointer to an array of glottal samples */ long original_f0; /* original value of f0 not modified by flutter */ int fadeout; // set to 64 to cause fadeout over 64 samples int scale_wav; // depends on the voicing source #define N_RSN 20 #define Rnz 0 // nasal zero, anti-resonator #define R1c 1 #define R2c 2 #define R3c 3 #define R4c 4 #define R5c 5 #define R6c 6 #define R7c 7 #define R8c 8 #define Rnpc 9 // nasal pole #define Rparallel 10 #define Rnpp 10 #define R1p 11 #define R2p 12 #define R3p 13 #define R4p 14 #define R5p 15 #define R6p 16 #define RGL 17 #define RLP 18 #define Rout 19 resonator_t rsn[N_RSN]; // internal storage for resonators resonator_t rsn_next[N_RSN]; } klatt_global_t, *klatt_global_ptr; /* Structure for Klatt Parameters */ #define F_NZ 0 // nasal zero formant #define F1 1 #define F2 2 #define F3 3 #define F4 4 #define F5 5 #define F6 6 #define F_NP 9 // nasal pole formant typedef struct { int F0hz10; /* Voicing fund freq in Hz */ int AVdb; /* Amp of voicing in dB, 0 to 70 */ int Fhz[10]; // formant Hz, F_NZ to F6 to F_NP int Bhz[10]; int Ap[10]; /* Amp of parallel formants in dB, 0 to 80 */ int Bphz[10]; /* Parallel formants bw in Hz, 40 to 1000 */ int ASP; /* Amp of aspiration in dB, 0 to 70 */ int Kopen; /* # of samples in open period, 10 to 65 */ int Aturb; /* Breathiness in voicing, 0 to 80 */ int TLTdb; /* Voicing spectral tilt in dB, 0 to 24 */ int AF; /* Amp of frication in dB, 0 to 80 */ int Kskew; /* Skewness of alternate periods, 0 to 40 in sample#/2 */ int AB; /* Amp of bypass fric. in dB, 0 to 80 */ int AVpdb; /* Amp of voicing, par in dB, 0 to 70 */ int Gain0; /* Overall gain, 60 dB is unity, 0 to 60 */ int AVdb_tmp; //copy of AVdb, which is changed within parwave() int Fhz_next[10]; // Fhz for the next chunk, so we can do interpolation of resonator (a,b,c) parameters int Bhz_next[10]; } klatt_frame_t, *klatt_frame_ptr; typedef struct { int freq; // Hz int bw; // klatt bandwidth int ap; // parallel amplitude int bp; // parallel bandwidth DOUBLEX freq1; // floating point versions of the above DOUBLEX bw1; DOUBLEX ap1; DOUBLEX bp1; DOUBLEX freq_inc; // increment by this every 64 samples DOUBLEX bw_inc; DOUBLEX ap_inc; DOUBLEX bp_inc; } klatt_peaks_t; praat-6.0.04/external/espeak/numbers.cpp000066400000000000000000001415041261542461700201760ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2005 to 2011 by Jonathan Duddington * * email: jonsd@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, see: * * . * ***************************************************************************/ #include "StdAfx.h" #include #include #include #include #include #include #include "speak_lib.h" #include "speech.h" #include "phoneme.h" #include "synthesize.h" #include "voice.h" #include "translate.h" #define M_NAME 0 #define M_SMALLCAP 1 #define M_TURNED 2 #define M_REVERSED 3 #define M_CURL 4 #define M_ACUTE 5 #define M_BREVE 6 #define M_CARON 7 #define M_CEDILLA 8 #define M_CIRCUMFLEX 9 #define M_DIAERESIS 10 #define M_DOUBLE_ACUTE 11 #define M_DOT_ABOVE 12 #define M_GRAVE 13 #define M_MACRON 14 #define M_OGONEK 15 #define M_RING 16 #define M_STROKE 17 #define M_TILDE 18 #define M_BAR 19 #define M_RETROFLEX 20 #define M_HOOK 21 #define M_MIDDLE_DOT M_DOT_ABOVE // duplicate of M_DOT_ABOVE #define M_IMPLOSIVE M_HOOK static int n_digit_lookup; static char *digit_lookup; static int speak_missing_thousands; static int number_control; typedef struct { const char *name; int flags; } ACCENTS; // these are tokens to look up in the *_list file. static ACCENTS accents_tab[] = { {"_lig", 1}, {"_smc", 1}, // smallcap {"_tur", 1}, // turned {"_rev", 1}, // reversed {"_crl", 0}, // curl {"_acu", 0}, // acute {"_brv", 0}, // breve {"_hac", 0}, // caron/hacek {"_ced", 0}, // cedilla {"_cir", 0}, // circumflex {"_dia", 0}, // diaeresis {"_ac2", 0}, // double acute {"_dot", 0}, // dot {"_grv", 0}, // grave {"_mcn", 0}, // macron {"_ogo", 0}, // ogonek {"_rng", 0}, // ring {"_stk", 0}, // stroke {"_tld", 0}, // tilde {"_bar", 0}, // bar {"_rfx", 0}, // retroflex {"_hok", 0}, // hook }; #define CAPITAL 0 #define LETTER(ch,mod1,mod2) (ch-59)+(mod1 << 6)+(mod2 << 11) #define LIGATURE(ch1,ch2,mod1) (ch1-59)+((ch2-59) << 6)+(mod1 << 12)+0x8000 #define L_ALPHA 60 // U+3B1 #define L_SCHWA 61 // U+259 #define L_OPEN_E 62 // U+25B #define L_GAMMA 63 // U+3B3 #define L_IOTA 64 // U+3B9 #define L_OE 65 // U+153 #define L_OMEGA 66 // U+3C9 #define L_PHI 67 // U+3C6 #define L_ESH 68 // U+283 #define L_UPSILON 69 // U+3C5 #define L_EZH 70 // U+292 #define L_GLOTTAL 71 // U+294 #define L_RTAP 72 // U+27E static const short non_ascii_tab[] = { 0, 0x3b1, 0x259, 0x25b, 0x3b3, 0x3b9, 0x153, 0x3c9, 0x3c6, 0x283, 0x3c5, 0x292, 0x294, 0x27e }; // characters U+00e0 to U+017f static const unsigned short letter_accents_0e0[] = { LETTER('a',M_GRAVE,0), // U+00e0 LETTER('a',M_ACUTE,0), LETTER('a',M_CIRCUMFLEX,0), LETTER('a',M_TILDE,0), LETTER('a',M_DIAERESIS,0), LETTER('a',M_RING,0), LIGATURE('a','e',0), LETTER('c',M_CEDILLA,0), LETTER('e',M_GRAVE,0), LETTER('e',M_ACUTE,0), LETTER('e',M_CIRCUMFLEX,0), LETTER('e',M_DIAERESIS,0), LETTER('i',M_GRAVE,0), LETTER('i',M_ACUTE,0), LETTER('i',M_CIRCUMFLEX,0), LETTER('i',M_DIAERESIS,0), LETTER('d',M_NAME,0), // eth // U+00f0 LETTER('n',M_TILDE,0), LETTER('o',M_GRAVE,0), LETTER('o',M_ACUTE,0), LETTER('o',M_CIRCUMFLEX,0), LETTER('o',M_TILDE,0), LETTER('o',M_DIAERESIS,0), 0, // division sign LETTER('o',M_STROKE,0), LETTER('u',M_GRAVE,0), LETTER('u',M_ACUTE,0), LETTER('u',M_CIRCUMFLEX,0), LETTER('u',M_DIAERESIS,0), LETTER('y',M_ACUTE,0), LETTER('t',M_NAME,0), // thorn LETTER('y',M_DIAERESIS,0), CAPITAL, // U+0100 LETTER('a',M_MACRON,0), CAPITAL, LETTER('a',M_BREVE,0), CAPITAL, LETTER('a',M_OGONEK,0), CAPITAL, LETTER('c',M_ACUTE,0), CAPITAL, LETTER('c',M_CIRCUMFLEX,0), CAPITAL, LETTER('c',M_DOT_ABOVE,0), CAPITAL, LETTER('c',M_CARON,0), CAPITAL, LETTER('d',M_CARON,0), CAPITAL, // U+0110 LETTER('d',M_STROKE,0), CAPITAL, LETTER('e',M_MACRON,0), CAPITAL, LETTER('e',M_BREVE,0), CAPITAL, LETTER('e',M_DOT_ABOVE,0), CAPITAL, LETTER('e',M_OGONEK,0), CAPITAL, LETTER('e',M_CARON,0), CAPITAL, LETTER('g',M_CIRCUMFLEX,0), CAPITAL, LETTER('g',M_BREVE,0), CAPITAL, // U+0120 LETTER('g',M_DOT_ABOVE,0), CAPITAL, LETTER('g',M_CEDILLA,0), CAPITAL, LETTER('h',M_CIRCUMFLEX,0), CAPITAL, LETTER('h',M_STROKE,0), CAPITAL, LETTER('i',M_TILDE,0), CAPITAL, LETTER('i',M_MACRON,0), CAPITAL, LETTER('i',M_BREVE,0), CAPITAL, LETTER('i',M_OGONEK,0), CAPITAL, // U+0130 LETTER('i',M_NAME,0), // dotless i CAPITAL, LIGATURE('i','j',0), CAPITAL, LETTER('j',M_CIRCUMFLEX,0), CAPITAL, LETTER('k',M_CEDILLA,0), LETTER('k',M_NAME,0), // kra CAPITAL, LETTER('l',M_ACUTE,0), CAPITAL, LETTER('l',M_CEDILLA,0), CAPITAL, LETTER('l',M_CARON,0), CAPITAL, LETTER('l',M_MIDDLE_DOT,0), // U+0140 CAPITAL, LETTER('l',M_STROKE,0), CAPITAL, LETTER('n',M_ACUTE,0), CAPITAL, LETTER('n',M_CEDILLA,0), CAPITAL, LETTER('n',M_CARON,0), LETTER('n',M_NAME,0), // apostrophe n CAPITAL, LETTER('n',M_NAME,0), // eng CAPITAL, LETTER('o',M_MACRON,0), CAPITAL, LETTER('o',M_BREVE,0), CAPITAL, // U+0150 LETTER('o',M_DOUBLE_ACUTE,0), CAPITAL, LIGATURE('o','e',0), CAPITAL, LETTER('r',M_ACUTE,0), CAPITAL, LETTER('r',M_CEDILLA,0), CAPITAL, LETTER('r',M_CARON,0), CAPITAL, LETTER('s',M_ACUTE,0), CAPITAL, LETTER('s',M_CIRCUMFLEX,0), CAPITAL, LETTER('s',M_CEDILLA,0), CAPITAL, // U+0160 LETTER('s',M_CARON,0), CAPITAL, LETTER('t',M_CEDILLA,0), CAPITAL, LETTER('t',M_CARON,0), CAPITAL, LETTER('t',M_STROKE,0), CAPITAL, LETTER('u',M_TILDE,0), CAPITAL, LETTER('u',M_MACRON,0), CAPITAL, LETTER('u',M_BREVE,0), CAPITAL, LETTER('u',M_RING,0), CAPITAL, // U+0170 LETTER('u',M_DOUBLE_ACUTE,0), CAPITAL, LETTER('u',M_OGONEK,0), CAPITAL, LETTER('w',M_CIRCUMFLEX,0), CAPITAL, LETTER('y',M_CIRCUMFLEX,0), CAPITAL, // Y-DIAERESIS CAPITAL, LETTER('z',M_ACUTE,0), CAPITAL, LETTER('z',M_DOT_ABOVE,0), CAPITAL, LETTER('z',M_CARON,0), LETTER('s',M_NAME,0), // long-s // U+17f }; // characters U+0250 to U+029F static const unsigned short letter_accents_250[] = { LETTER('a',M_TURNED,0), // U+250 LETTER(L_ALPHA,0,0), LETTER(L_ALPHA,M_TURNED,0), LETTER('b',M_IMPLOSIVE,0), 0, // open-o LETTER('c',M_CURL,0), LETTER('d',M_RETROFLEX,0), LETTER('d',M_IMPLOSIVE,0), LETTER('e',M_REVERSED,0), // U+258 0, // schwa LETTER(L_SCHWA,M_HOOK,0), 0, // open-e LETTER(L_OPEN_E,M_REVERSED,0), LETTER(L_OPEN_E,M_HOOK,M_REVERSED), 0,//LETTER(L_OPEN_E,M_CLOSED,M_REVERSED), LETTER('j',M_BAR,0), LETTER('g',M_IMPLOSIVE,0), // U+260 LETTER('g',0,0), LETTER('g',M_SMALLCAP,0), LETTER(L_GAMMA,0,0), 0, // ramshorn LETTER('h',M_TURNED,0), LETTER('h',M_HOOK,0), 0,//LETTER(L_HENG,M_HOOK,0), LETTER('i',M_BAR,0), // U+268 LETTER(L_IOTA,0,0), LETTER('i',M_SMALLCAP,0), LETTER('l',M_TILDE,0), LETTER('l',M_BAR,0), LETTER('l',M_RETROFLEX,0), LIGATURE('l','z',0), LETTER('m',M_TURNED,0), 0,//LETTER('m',M_TURNED,M_LEG), // U+270 LETTER('m',M_HOOK,0), 0,//LETTER('n',M_LEFTHOOK,0), LETTER('n',M_RETROFLEX,0), LETTER('n',M_SMALLCAP,0), LETTER('o',M_BAR,0), LIGATURE('o','e',M_SMALLCAP), 0,//LETTER(L_OMEGA,M_CLOSED,0), LETTER(L_PHI,0,0), // U+278 LETTER('r',M_TURNED,0), 0,//LETTER('r',M_TURNED,M_LEG), LETTER('r',M_RETROFLEX,M_TURNED), 0,//LETTER('r',M_LEG,0), LETTER('r',M_RETROFLEX,0), 0, // r-tap LETTER(L_RTAP,M_REVERSED,0), LETTER('r',M_SMALLCAP,0), // U+280 LETTER('r',M_TURNED,M_SMALLCAP), LETTER('s',M_RETROFLEX,0), 0, // esh 0,//LETTER('j',M_BAR,L_IMPLOSIVE), LETTER(L_ESH,M_REVERSED,0), LETTER(L_ESH,M_CURL,0), LETTER('t',M_TURNED,0), LETTER('t',M_RETROFLEX,0), // U+288 LETTER('u',M_BAR,0), LETTER(L_UPSILON,0,0), LETTER('v',M_HOOK,0), LETTER('v',M_TURNED,0), LETTER('w',M_TURNED,0), LETTER('y',M_TURNED,0), LETTER('y',M_SMALLCAP,0), LETTER('z',M_RETROFLEX,0), // U+290 LETTER('z',M_CURL,0), 0, // ezh LETTER(L_EZH,M_CURL,0), 0, // glottal stop LETTER(L_GLOTTAL,M_REVERSED,0), LETTER(L_GLOTTAL,M_TURNED,0), 0,//LETTER('c',M_LONG,0), 0, // bilabial click // U+298 LETTER('b',M_SMALLCAP,0), 0,//LETTER(L_OPEN_E,M_CLOSED,0), LETTER('g',M_IMPLOSIVE,M_SMALLCAP), LETTER('h',M_SMALLCAP,0), LETTER('j',M_CURL,0), LETTER('k',M_TURNED,0), LETTER('l',M_SMALLCAP,0), LETTER('q',M_HOOK,0), // U+2a0 LETTER(L_GLOTTAL,M_STROKE,0), LETTER(L_GLOTTAL,M_STROKE,M_REVERSED), LIGATURE('d','z',0), 0, // dezh LIGATURE('d','z',M_CURL), LIGATURE('t','s',0), 0, // tesh LIGATURE('t','s',M_CURL), }; static int LookupLetter2(Translator *tr, unsigned int letter, char *ph_buf) {//======================================================================== int len; char single_letter[10]; single_letter[0] = 0; single_letter[1] = '_'; len = utf8_out(letter, &single_letter[2]); single_letter[len+2] = ' '; single_letter[len+3] = 0; if(Lookup(tr, &single_letter[1], ph_buf) == 0) { single_letter[1] = ' '; if(Lookup(tr, &single_letter[2], ph_buf) == 0) { TranslateRules(tr, &single_letter[2], ph_buf, 20, NULL,0,NULL); } } return(ph_buf[0]); } void LookupAccentedLetter(Translator *tr, unsigned int letter, char *ph_buf) {//========================================================================= // lookup the character in the accents table int accent_data = 0; int accent1 = 0; int accent2 = 0; int basic_letter; int letter2=0; char ph_letter1[30]; char ph_letter2[30]; char ph_accent1[30]; char ph_accent2[30]; ph_accent2[0] = 0; if((letter >= 0xe0) && (letter < 0x17f)) { accent_data = letter_accents_0e0[letter - 0xe0]; } else if((letter >= 0x250) && (letter <= 0x2a8)) { accent_data = letter_accents_250[letter - 0x250]; } if(accent_data != 0) { basic_letter = (accent_data & 0x3f) + 59; if(basic_letter < 'a') basic_letter = non_ascii_tab[basic_letter-59]; if(accent_data & 0x8000) { letter2 = (accent_data >> 6) & 0x3f; letter2 += 59; accent2 = (accent_data >> 12) & 0x7; } else { accent1 = (accent_data >> 6) & 0x1f; accent2 = (accent_data >> 11) & 0xf; } if(Lookup(tr, accents_tab[accent1].name, ph_accent1) != 0) { if(LookupLetter2(tr, basic_letter, ph_letter1) != 0) { if(accent2 != 0) { if(Lookup(tr, accents_tab[accent2].name, ph_accent2) == 0) { // break; } if(accents_tab[accent2].flags & 1) { strcpy(ph_buf,ph_accent2); ph_buf += strlen(ph_buf); ph_accent2[0] = 0; } } if(letter2 != 0) { //ligature LookupLetter2(tr, letter2, ph_letter2); sprintf(ph_buf,"%s%c%s%c%s%s",ph_accent1, phonPAUSE_VSHORT, ph_letter1, phonSTRESS_P, ph_letter2, ph_accent2); } else { if(accent1 == 0) strcpy(ph_buf, ph_letter1); else if((tr->langopts.accents & 1) || (accents_tab[accent1].flags & 1)) sprintf(ph_buf,"%s%c%c%s", ph_accent1, phonPAUSE_VSHORT, phonSTRESS_P, ph_letter1); else sprintf(ph_buf,"%c%s%c%s%c", phonSTRESS_2, ph_letter1, phonPAUSE_VSHORT, ph_accent1, phonPAUSE_VSHORT); } } } } } // end of LookupAccentedLetter void LookupLetter(Translator *tr, unsigned int letter, int next_byte, char *ph_buf1, int control) {//============================================================================================== // control, bit 0: not the first letter of a word int len; static char single_letter[10] = {0,0}; unsigned int dict_flags[2]; char ph_buf3[40]; ph_buf1[0] = 0; len = utf8_out(letter,&single_letter[2]); single_letter[len+2] = ' '; if(next_byte == -1) { // speaking normal text, not individual characters if(Lookup(tr, &single_letter[2], ph_buf1) != 0) return; single_letter[1] = '_'; if(Lookup(tr, &single_letter[1], ph_buf3) != 0) return; // the character is specified as _* so ignore it when speaking normal text // check whether this character is specified for English if(tr->translator_name == L('e','n')) return; // we are already using English SetTranslator2("en"); if(Lookup(translator2, &single_letter[2], ph_buf3) != 0) { // yes, switch to English and re-translate the word sprintf(ph_buf1,"%c",phonSWITCH); } SelectPhonemeTable(voice->phoneme_tab_ix); // revert to original phoneme table return; } if((letter <= 32) || iswspace(letter)) { // lookup space as _&32 etc. sprintf(&single_letter[1],"_#%d ",letter); Lookup(tr, &single_letter[1], ph_buf1); return; } if(next_byte != ' ') next_byte = RULE_SPELLING; single_letter[3+len] = next_byte; // follow by space-space if the end of the word, or space-31 single_letter[1] = '_'; // if the $accent flag is set for this letter, use the accents table (below) dict_flags[1] = 0; if(Lookup(tr, &single_letter[1], ph_buf3) == 0) { single_letter[1] = ' '; if(Lookup(tr, &single_letter[2], ph_buf3) == 0) { TranslateRules(tr, &single_letter[2], ph_buf3, sizeof(ph_buf3), NULL,FLAG_NO_TRACE,NULL); } } if(ph_buf3[0] == 0) { LookupAccentedLetter(tr, letter, ph_buf3); } strcpy(ph_buf1, ph_buf3); if((ph_buf1[0] == 0) || (ph_buf1[0] == phonSWITCH)) { return; } dict_flags[0] = 0; dict_flags[1] = 0; SetWordStress(tr, ph_buf1, dict_flags, -1, control & 1); } // end of LookupLetter int TranslateLetter(Translator *tr, char *word, char *phonemes, int control) {//========================================================================= // get pronunciation for an isolated letter // return number of bytes used by the letter // control bit 0: a non-initial letter in a word // bit 1: say 'capital' int n_bytes; int letter; int len; int ix; int save_option_phonemes; char *p2; char *pbuf; char capital[20]; char ph_buf[80]; char ph_buf2[80]; char hexbuf[6]; ph_buf[0] = 0; capital[0] = 0; n_bytes = utf8_in(&letter,word); if((letter & 0xfff00) == 0x0e000) { letter &= 0xff; // uncode private usage area } if(control & 2) { // include CAPITAL information if(iswupper(letter)) { Lookup(tr, "_cap", capital); } } letter = towlower2(letter); LookupLetter(tr, letter, word[n_bytes], ph_buf, control & 1); if(ph_buf[0] == phonSWITCH) { strcpy(phonemes,ph_buf); return(0); } if((ph_buf[0] == 0) && (tr->translator_name != L('e','n'))) { // speak as English, check whether there is a translation for this character SetTranslator2("en"); save_option_phonemes = option_phonemes; option_phonemes = 0; LookupLetter(translator2, letter, word[n_bytes], ph_buf, control & 1); SelectPhonemeTable(voice->phoneme_tab_ix); // revert to original phoneme table option_phonemes = save_option_phonemes; if(ph_buf[0] != 0) { sprintf(phonemes,"%cen",phonSWITCH); return(0); } } if(ph_buf[0] == 0) { // character name not found if((letter >= 0x2800) && (letter <= 0x28ff)) { // braille dots symbol Lookup(tr, "_braille", ph_buf); if(ph_buf[0] == 0) { EncodePhonemes("br'e:l", ph_buf, NULL); } if(ph_buf[0] != 0) { pbuf = ph_buf + strlen(ph_buf); for(ix=0; ix<8; ix++) { if(letter & (1 << ix)) { *pbuf++ = phonPAUSE_VSHORT; LookupLetter(tr, '1'+ix, 0, pbuf, 1); pbuf += strlen(pbuf); } } } } if(ph_buf[0]== 0) { if(iswalpha(letter)) Lookup(tr, "_?A", ph_buf); if((ph_buf[0]==0) && !iswspace(letter)) Lookup(tr, "_??", ph_buf); if(ph_buf[0] != 0) { // speak the hexadecimal number of the character code sprintf(hexbuf,"%x",letter); pbuf = ph_buf; for(p2 = hexbuf; *p2 != 0; p2++) { pbuf += strlen(pbuf); *pbuf++ = phonPAUSE_VSHORT; LookupLetter(tr, *p2, 0, pbuf, 1); } } } } len = strlen(phonemes); if(tr->langopts.accents & 2) sprintf(ph_buf2,"%c%s%s",0xff,ph_buf,capital); else sprintf(ph_buf2,"%c%s%s",0xff,capital,ph_buf); // the 0xff marker will be removed or replaced in SetSpellingStress() if((len + strlen(ph_buf2)) < N_WORD_PHONEMES) { strcpy(&phonemes[len],ph_buf2); } return(n_bytes); } // end of TranslateLetter void SetSpellingStress(Translator *tr, char *phonemes, int control, int n_chars) {//============================================================================= // Individual letter names, reduce the stress of some. int ix; unsigned int c; int n_stress=0; int count; unsigned char buf[N_WORD_PHONEMES]; for(ix=0; (c = phonemes[ix]) != 0; ix++) { if(c == phonSTRESS_P) { n_stress++; } buf[ix] = c; } buf[ix] = 0; count = 0; for(ix=0; (c = buf[ix]) != 0; ix++) { if((c == phonSTRESS_P) && (n_chars > 1)) { count++; if(tr->langopts.spelling_stress == 1) { // stress on initial letter when spelling if(count > 1) c = phonSTRESS_3; } else { if(count != n_stress) { if(((count % 3) != 0) || (count == n_stress-1)) c = phonSTRESS_3; // reduce to secondary stress } } } else if(c == 0xff) { if((control < 2) || (ix==0)) continue; // don't insert pauses if(control == 4) c = phonPAUSE; // pause after each character if(((count % 3) == 0) || (control > 2)) c = phonPAUSE_NOLINK; // pause following a primary stress else c = phonPAUSE_VSHORT; // else // continue; // remove marker } *phonemes++ = c; } if(control >= 2) *phonemes++ = phonPAUSE_NOLINK; *phonemes = 0; } // end of SetSpellingStress // Numbers static char ph_ordinal2[12]; static int CheckDotOrdinal(Translator *tr, char *word, char *word_end, WORD_TAB *wtab, int roman) {//============================================================================================== int ordinal = 0; int c2; int nextflags; if((tr->langopts.numbers & NUM_ORDINAL_DOT) && ((word_end[0] == '.') || (wtab[0].flags & FLAG_HAS_DOT)) && !(wtab[1].flags & FLAG_NOSPACE)) { if(roman || !(wtab[1].flags & FLAG_FIRST_UPPER)) { if(word_end[0] == '.') utf8_in(&c2, &word_end[2]); else utf8_in(&c2, &word_end[0]); if((word_end[0] != 0) && (word_end[1] != 0) && ((c2 == 0) || (wtab[0].flags & FLAG_COMMA_AFTER) || IsAlpha(c2))) { // ordinal number is indicated by dot after the number // but not if the next word starts with an upper-case letter // (c2 == 0) is for cases such as, "2.," ordinal = 2; if(word_end[0] == '.') word_end[0] = ' '; if((roman==0) && (tr->translator_name == L('h','u'))) { // lang=hu don't treat dot as ordinal indicator if the next word is a month name ($alt). It may have a suffix. nextflags = 0; if(IsAlpha(c2)) { nextflags = TranslateWord(tr, &word_end[2], 0, NULL); } if((tr->prev_dict_flags & FLAG_ALT_TRANS) && ((c2 == 0) || (wtab[0].flags & FLAG_COMMA_AFTER) || iswdigit(c2))) ordinal = 0; // TEST 09.02.10 if(nextflags & FLAG_ALT_TRANS) ordinal = 0; if(nextflags & FLAG_ALT3_TRANS) { if(word[-2] == '-') ordinal = 0; // eg. december 2-5. között if(tr->prev_dict_flags & (FLAG_ALT_TRANS | FLAG_ALT3_TRANS)) ordinal = 0x22; } } } } } return(ordinal); } // end of CheckDotOrdinal static int hu_number_e(const char *word, int thousandplex, int value) {//================================================================== // lang-hu: variant form of numbers when followed by hyphen and a suffix starting with 'a' or 'e' (but not a, e, az, ez, azt, ezt, att. ett if((word[0] == 'a') || (word[0] == 'e')) { if((word[1] == ' ') || (word[1] == 'z') || ((word[1] == 't') && (word[2] == 't'))) return(0); if(((thousandplex==1) || ((value % 1000) == 0)) && (word[1] == 'l')) return(0); // 1000-el return(1); } return(0); } // end of hu_numnber_e int TranslateRoman(Translator *tr, char *word, char *ph_out, WORD_TAB *wtab) {//========================================================================= int c; char *p; const char *p2; int acc; int prev; int value; int subtract; int repeat = 0; int n_digits = 0; char *word_start; int num_control = 0; unsigned int flags[2]; char ph_roman[30]; char number_chars[N_WORD_BYTES]; static const char *roman_numbers = "ixcmvld"; static int roman_values[] = {1,10,100,1000,5,50,500}; acc = 0; prev = 0; subtract = 0x7fff; ph_out[0] = 0; flags[0] = 0; flags[1] = 0; if(((tr->langopts.numbers & NUM_ROMAN_CAPITALS) && !(wtab[0].flags & FLAG_ALL_UPPER)) || isdigit(word[-2])) return(0); // not '2xx' word_start = word; while((c = *word++) != ' ') { if((p2 = strchr(roman_numbers,c)) == NULL) return(0); value = roman_values[p2 - roman_numbers]; if(value == prev) { repeat++; if(repeat >= 3) return(0); } else repeat = 0; if((prev > 1) && (prev != 10) && (prev != 100)) { if(value >= prev) return(0); } if((prev != 0) && (prev < value)) { if(((acc % 10) != 0) || ((prev*10) < value)) return(0); subtract = prev; value -= subtract; } else if(value >= subtract) return(0); else acc += prev; prev = value; n_digits++; } if(isdigit(word[0])) return(0); // eg. 'xx2' acc += prev; if(acc < tr->langopts.min_roman) return(0); if(acc > tr->langopts.max_roman) return(0); Lookup(tr, "_roman",ph_roman); // precede by "roman" if _rom is defined in *_list p = &ph_out[0]; if((tr->langopts.numbers & NUM_ROMAN_AFTER) == 0) { strcpy(ph_out,ph_roman); p = &ph_out[strlen(ph_roman)]; } sprintf(number_chars," %d ",acc); if(word[0] == '.') { // dot has not been removed. This implies that there was no space after it return(0); } if(CheckDotOrdinal(tr, word_start, word, wtab, 1)) wtab[0].flags |= FLAG_ORDINAL; if(tr->langopts.numbers & NUM_ROMAN_ORDINAL) { if(tr->translator_name == L('h','u')) { if(!(wtab[0].flags & FLAG_ORDINAL)) { if((wtab[0].flags & FLAG_HYPHEN_AFTER) && hu_number_e(word, 0, acc)) { // should use the 'e' form of the number num_control |= 1; } else return(0); } } else { wtab[0].flags |= FLAG_ORDINAL; } } tr->prev_dict_flags = 0; TranslateNumber(tr, &number_chars[2], p, flags, wtab, num_control); if(tr->langopts.numbers & NUM_ROMAN_AFTER) strcat(ph_out,ph_roman); return(1); } // end of TranslateRoman static const char *M_Variant(int value) {//==================================== // returns M, or perhaps MA or MB for some cases int teens = 0; if(((value % 100) > 10) && ((value % 100) < 20)) teens = 1; switch((translator->langopts.numbers2 >> 6) & 0x7) { case 1: // lang=ru use singular for xx1 except for x11 if((teens == 0) && ((value % 10) == 1)) return("1M"); break; case 2: // lang=cs,sk if((value >= 2) && (value <= 4)) return("0MA"); break; case 3: // lang=pl if((teens == 0) && (((value % 10) >= 2) && ((value % 10) <= 4))) return("0MA"); break; case 4: // lang=lt if((teens == 1) || ((value % 10) == 0)) return("0MB"); if((value % 10) == 1) return("0MA"); break; case 5: // lang=bs,hr,sr if(teens == 0) { if((value % 10) == 1) return("1M"); if(((value % 10) >= 2) && ((value % 10) <= 4)) return("0MA"); } break; } return("0M"); } static int LookupThousands(Translator *tr, int value, int thousandplex, int thousands_exact, char *ph_out) {//======================================================================================================= // thousands_exact: bit 0 no hundreds,tens,or units, bit 1 ordinal numberr int found; int found_value=0; char string[12]; char ph_of[12]; char ph_thousands[40]; char ph_buf[40]; ph_of[0] = 0; // first look for a match with the exact value of thousands if(value > 0) { if(thousands_exact & 1) { if(thousands_exact & 2) { // ordinal number sprintf(string,"_%dM%do",value,thousandplex); found_value = Lookup(tr, string, ph_thousands); } if(!found_value & (number_control & 1)) { // look for the 'e' variant sprintf(string,"_%dM%de",value,thousandplex); found_value = Lookup(tr, string, ph_thousands); } if(!found_value) { // is there a different pronunciation if there are no hundreds,tens,or units ? (LANG=ta) sprintf(string,"_%dM%dx",value,thousandplex); found_value = Lookup(tr, string, ph_thousands); } } if(found_value == 0) { sprintf(string,"_%dM%d",value,thousandplex); found_value = Lookup(tr, string, ph_thousands); } } if(found_value == 0) { if((value % 100) >= 20) { Lookup(tr, "_0of", ph_of); } found = 0; if(thousands_exact & 1) { if(thousands_exact & 2) { // ordinal number sprintf(string,"_%s%do",M_Variant(value), thousandplex); found = Lookup(tr, string, ph_thousands); } if(!found && (number_control & 1)) { // look for the 'e' variant sprintf(string,"_%s%de",M_Variant(value), thousandplex); found = Lookup(tr, string, ph_thousands); } if(!found) { // is there a different pronunciation if there are no hundreds,tens,or units ? sprintf(string,"_%s%dx",M_Variant(value), thousandplex); found = Lookup(tr, string, ph_thousands); } } if(found == 0) { sprintf(string,"_%s%d",M_Variant(value), thousandplex); if(Lookup(tr, string, ph_thousands) == 0) { if(thousandplex > 3) { sprintf(string,"_0M%d", thousandplex-1); if(Lookup(tr, string, ph_buf) == 0) { // say "millions" if this name is not available and neither is the next lower Lookup(tr, "_0M2", ph_thousands); speak_missing_thousands = 3; } } if(ph_thousands[0] == 0) { // repeat "thousand" if higher order names are not available sprintf(string,"_%dM1",value); if((found_value = Lookup(tr, string, ph_thousands)) == 0) Lookup(tr, "_0M1", ph_thousands); speak_missing_thousands = 2; } } } } sprintf(ph_out,"%s%s",ph_of,ph_thousands); if((value == 1) && (thousandplex == 1) && (tr->langopts.numbers & NUM_OMIT_1_THOUSAND)) return(1); return(found_value); } // end f LookupThousands static int LookupNum2(Translator *tr, int value, const int control, char *ph_out) {//============================================================================= // Lookup a 2 digit number // control bit 0: ordinal number // control bit 1: final tens and units (not number of thousands) (use special form of '1', LANG=de "eins") // control bit 2: tens and units only, no higher digits // control bit 3: use feminine form of '2' (for thousands // control bit 4: speak zero tens // control bit 5: variant of ordinal number (lang=hu) int found; int ix; int units; int tens; int is_ordinal; int used_and=0; int found_ordinal = 0; int next_phtype; int ord_type = 'o'; char string[12]; // for looking up entries in *_list char ph_ordinal[20]; char ph_tens[50]; char ph_digits[50]; char ph_and[12]; units = value % 10; tens = value / 10; found = 0; ph_ordinal[0] = 0; ph_tens[0] = 0; ph_digits[0] = 0; ph_and[0] = 0; if(control & 0x20) { ord_type = 'q'; } is_ordinal = control & 1; if((control & 2) && (n_digit_lookup == 2)) { // pronunciation of the final 2 digits has already been found strcpy(ph_out, digit_lookup); } else { if(digit_lookup[0] == 0) { // is there a special pronunciation for this 2-digit number if(control & 8) { // is there a feminine form? sprintf(string,"_%df",value); found = Lookup(tr, string, ph_digits); } else if(is_ordinal) { strcpy(ph_ordinal, ph_ordinal2); if(control & 4) { sprintf(string,"_%d%cx",value,ord_type); // LANG=hu, special word for 1. 2. when there are no higher digits found = Lookup(tr, string, ph_digits); } if(found == 0) { sprintf(string,"_%d%c",value,ord_type); found = Lookup(tr, string, ph_digits); } found_ordinal = found; } if(found == 0) { if(control & 2) { // the final tens and units of a number if(number_control & 1) { // look for 'e' variant sprintf(string,"_%de",value); found = Lookup(tr, string, ph_digits); } } else { // followed by hundreds or thousands etc sprintf(string,"_%da",value); found = Lookup(tr, string, ph_digits); } if(!found) { if((is_ordinal) && (tr->langopts.numbers2 & NUM2_NO_TEEN_ORDINALS)) { // don't use numbers 10-99 to make ordinals, always use _1Xo etc (lang=pt) } else { sprintf(string,"_%d",value); found = Lookup(tr, string, ph_digits); } } } } // no, speak as tens+units if((control & 0x10) && (value < 10)) { // speak leading zero Lookup(tr, "_0", ph_tens); } else { if(found) { ph_tens[0] = 0; } else { if((is_ordinal) && ((units == 0) || (tr->langopts.numbers & NUM_SWAP_TENS) || (tr->langopts.numbers2 & NUM2_MULTIPLE_ORDINAL))) { sprintf(string,"_%dX%c", tens, ord_type); if(Lookup(tr, string, ph_tens) != 0) { found_ordinal = 1; if((units != 0) && (tr->langopts.numbers2 & NUM2_MULTIPLE_ORDINAL)) { // Use the ordinal form of tens as well as units. Add the ordinal ending strcat(ph_tens, ph_ordinal2); } } } if(found_ordinal == 0) { sprintf(string,"_%dX", tens); Lookup(tr, string, ph_tens); } if((ph_tens[0] == 0) && (tr->langopts.numbers & NUM_VIGESIMAL)) { // tens not found, (for example) 73 is 60+13 units = (value % 20); sprintf(string,"_%dX", tens & 0xfe); Lookup(tr, string, ph_tens); } ph_digits[0] = 0; if(units > 0) { found = 0; if((control & 2) && (digit_lookup[0] != 0)) { // we have an entry for this digit (possibly together with the next word) strcpy(ph_digits, digit_lookup); found_ordinal = 1; ph_ordinal[0] = 0; } else { if(control & 8) { // is there a variant form of this number? sprintf(string,"_%df",units); found = Lookup(tr, string, ph_digits); } if((is_ordinal) && ((tr->langopts.numbers & NUM_SWAP_TENS) == 0)) { // ordinal sprintf(string,"_%d%c",units,ord_type); if((found = Lookup(tr, string, ph_digits)) != 0) { found_ordinal = 1; } } if(found == 0) { if((number_control & 1) && (control & 2)) { // look for 'e' variant sprintf(string,"_%de",units); found = Lookup(tr, string, ph_digits); } else if(((control & 2) == 0) || ((tr->langopts.numbers & NUM_SWAP_TENS) != 0)) { // followed by hundreds or thousands (or tens) sprintf(string,"_%da",units); found = Lookup(tr, string, ph_digits); } } if(found == 0) { sprintf(string,"_%d",units); Lookup(tr, string, ph_digits); } } } } } if((is_ordinal) && (found_ordinal == 0) && (ph_ordinal[0] == 0)) { if((value >= 20) && (((value % 10) == 0) || (tr->langopts.numbers & NUM_SWAP_TENS))) Lookup(tr, "_ord20", ph_ordinal); if(ph_ordinal[0] == 0) Lookup(tr, "_ord", ph_ordinal); } if((tr->langopts.numbers & (NUM_SWAP_TENS | NUM_AND_UNITS)) && (ph_tens[0] != 0) && (ph_digits[0] != 0)) { Lookup(tr, "_0and", ph_and); if((is_ordinal) && (tr->langopts.numbers2 & NUM2_MULTIPLE_ORDINAL)) ph_and[0] = 0; if(tr->langopts.numbers & NUM_SWAP_TENS) sprintf(ph_out,"%s%s%s%s",ph_digits, ph_and, ph_tens, ph_ordinal); else sprintf(ph_out,"%s%s%s%s",ph_tens, ph_and, ph_digits, ph_ordinal); used_and = 1; } else { if(tr->langopts.numbers & NUM_SINGLE_VOWEL) { // remove vowel from the end of tens if units starts with a vowel (LANG=Italian) if(((ix = strlen(ph_tens)-1) >= 0) && (ph_digits[0] != 0)) { if((next_phtype = phoneme_tab[(unsigned int)(ph_digits[0])]->type) == phSTRESS) next_phtype = phoneme_tab[(unsigned int)(ph_digits[1])]->type; if((phoneme_tab[(unsigned int)(ph_tens[ix])]->type == phVOWEL) && (next_phtype == phVOWEL)) ph_tens[ix] = 0; } } sprintf(ph_out,"%s%s%s",ph_tens, ph_digits, ph_ordinal); } } if(tr->langopts.numbers & NUM_SINGLE_STRESS) { // only one primary stress found = 0; for(ix=strlen(ph_out)-1; ix>=0; ix--) { if(ph_out[ix] == phonSTRESS_P) { if(found) ph_out[ix] = phonSTRESS_3; else found = 1; } } } return(used_and); } // end of LookupNum2 static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null, int thousandplex, int control) {//============================================================================================================= // Translate a 3 digit number // control bit 0, previous thousands // bit 1, ordinal number // bit 5 variant form of ordinal number int found; int hundreds; int tensunits; int x; int ix; int exact; int ordinal; int tplex; int say_zero_hundred=0; char string[12]; // for looking up entries in **_list char buf1[100]; char buf2[100]; char ph_100[20]; char ph_10T[20]; char ph_digits[50]; char ph_thousands[50]; char ph_hundred_and[12]; char ph_thousand_and[12]; ordinal = control & 0x22; hundreds = value / 100; tensunits = value % 100; buf1[0] = 0; ph_thousands[0] = 0; ph_thousand_and[0] = 0; if((tr->langopts.numbers & NUM_ZERO_HUNDRED) && ((control & 1) || (hundreds >= 10))) { say_zero_hundred = 1; // lang=vi } if((hundreds > 0) || say_zero_hundred) { found = 0; if(ordinal && (tensunits == 0)) { // ordinal number, with no tens or units found = Lookup(tr, "_0Co", ph_100); } if(found == 0) { if(tensunits==0) { // special form for exact hundreds? found = Lookup(tr, "_0C0", ph_100); } if(!found) { Lookup(tr, "_0C", ph_100); } } if(((tr->langopts.numbers & NUM_1900) != 0) && (hundreds == 19)) { // speak numbers such as 1984 as years: nineteen-eighty-four // ph_100[0] = 0; // don't say "hundred", we also need to surpess "and" } else if(hundreds >= 10) { ph_digits[0] = 0; exact = 0; if ((value % 1000) == 0) exact = 1; tplex = thousandplex+1; if(tr->langopts.numbers2 & NUM2_MYRIADS) { tplex = 0; } if(LookupThousands(tr, hundreds / 10, tplex, exact | ordinal, ph_10T) == 0) { x = 0; if(tr->langopts.numbers2 & (1 << tplex)) x = 8; // use variant (feminine) for before thousands and millions LookupNum2(tr, hundreds/10, x, ph_digits); } if(tr->langopts.numbers2 & 0x200) sprintf(ph_thousands,"%s%s",ph_10T,ph_digits); // say "thousands" before its number, not after else sprintf(ph_thousands,"%s%s",ph_digits,ph_10T); hundreds %= 10; if((hundreds == 0) && (say_zero_hundred == 0)) ph_100[0] = 0; suppress_null = 1; } ph_digits[0] = 0; if((hundreds > 0) || say_zero_hundred) { if((tr->langopts.numbers & NUM_AND_HUNDRED) && ((control & 1) || (ph_thousands[0] != 0))) { Lookup(tr, "_0and", ph_thousand_and); } suppress_null = 1; found = 0; if((ordinal) && ((tensunits == 0) || (tr->langopts.numbers2 & NUM2_MULTIPLE_ORDINAL))) { // ordinal number sprintf(string, "_%dCo", hundreds); found = Lookup(tr, string, ph_digits); if((tr->langopts.numbers2 & NUM2_MULTIPLE_ORDINAL) && (tensunits > 0)) { // Use ordinal form of hundreds, as well as for tens and units // Add ordinal suffix to the hundreds strcat(ph_digits, ph_ordinal2); } } if((hundreds == 0) && say_zero_hundred) { Lookup(tr, "_0", ph_digits); } else { if((!found) && (tensunits == 0)) { // is there a special pronunciation for exactly n00 ? sprintf(string,"_%dC0",hundreds); found = Lookup(tr, string, ph_digits); } if(!found) { sprintf(string,"_%dC",hundreds); found = Lookup(tr, string, ph_digits); // is there a specific pronunciation for n-hundred ? } if(found) { ph_100[0] = 0; } else { if((hundreds > 1) || ((tr->langopts.numbers & NUM_OMIT_1_HUNDRED) == 0)) { LookupNum2(tr, hundreds, 0, ph_digits); } } } } sprintf(buf1,"%s%s%s%s",ph_thousands,ph_thousand_and,ph_digits,ph_100); } ph_hundred_and[0] = 0; if(tensunits > 0) { if((control & 2) && (tr->langopts.numbers2 & NUM2_MULTIPLE_ORDINAL)) { // Don't use "and" if we apply ordinal to both hundreds and units } else { if((value > 100) || ((control & 1) && (thousandplex==0))) { if((tr->langopts.numbers & NUM_HUNDRED_AND) || ((tr->langopts.numbers & NUM_HUNDRED_AND_DIGIT) && (tensunits < 10))) { Lookup(tr, "_0and", ph_hundred_and); } } if((tr->langopts.numbers & NUM_THOUSAND_AND) && (hundreds == 0) && ((control & 1) || (ph_thousands[0] != 0))) { Lookup(tr, "_0and", ph_hundred_and); } } } buf2[0] = 0; if((tensunits != 0) || (suppress_null == 0)) { x = 0; if(thousandplex==0) { x = 2; // allow "eins" for 1 rather than "ein" if(ordinal) x = 3; // ordinal number if((value < 100) && !(control & 1)) x |= 4; // tens and units only, no higher digits if(ordinal & 0x20) x |= 0x20; // variant form of ordinal number } else { if(tr->langopts.numbers2 & (1 << thousandplex)) x = 8; // use variant (feminine) for before thousands and millions } if(LookupNum2(tr, tensunits, x, buf2) != 0) { if(tr->langopts.numbers & NUM_SINGLE_AND) ph_hundred_and[0] = 0; // don't put 'and' after 'hundred' if there's 'and' between tens and units } } else { if(ph_ordinal2[0] != 0) { ix = strlen(buf1); if((ix > 0) && (buf1[ix-1] == phonPAUSE_SHORT)) buf1[ix-1] = 0; // remove pause before addding ordinal suffix strcpy(buf2, ph_ordinal2); } } sprintf(ph_out,"%s%s%s",buf1,ph_hundred_and,buf2); return(0); } // end of LookupNum3 bool CheckThousandsGroup(char *word, int group_len) {//================================================ // Is this a group of 3 digits which looks like a thousands group? int ix; if(isdigit(word[group_len]) || isdigit(-1)) return(false); for(ix=0; ix < group_len; ix++) { if(!isdigit(word[ix])) return(false); } return(true); } static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned int *flags, WORD_TAB *wtab, int control) {//===================================================================================================================== // Number translation with various options // the "word" may be up to 4 digits // "words" of 3 digits may be preceded by another number "word" for thousands or millions int n_digits; int value; int ix; int digix; unsigned char c; int suppress_null = 0; int decimal_point = 0; int thousandplex = 0; int thousands_exact = 1; int thousands_inc = 0; int prev_thousands = 0; int ordinal = 0; int dot_ordinal; int this_value; int decimal_count; int max_decimal_count; int decimal_mode; int suffix_ix; int skipwords = 0; int group_len; char *p; char string[32]; // for looking up entries in **_list char buf1[100]; char ph_append[50]; char ph_buf[200]; char ph_buf2[50]; char ph_zeros[50]; char suffix[30]; // string[] must be long enough for sizeof(suffix)+2 char buf_digit_lookup[50]; static const char str_pause[2] = {phonPAUSE_NOLINK,0}; *flags = 0; n_digit_lookup = 0; buf_digit_lookup[0] = 0; digit_lookup = buf_digit_lookup; number_control = control; for(ix=0; isdigit(word[ix]); ix++) ; n_digits = ix; value = this_value = atoi(word); group_len = 3; if(tr->langopts.numbers2 & NUM2_MYRIADS) group_len = 4; // is there a previous thousands part (as a previous "word") ? if((n_digits == group_len) && (word[-2] == tr->langopts.thousands_sep) && isdigit(word[-3])) { prev_thousands = 1; } else if((tr->langopts.thousands_sep == ' ') || (tr->langopts.numbers & NUM_ALLOW_SPACE)) { // thousands groups can be separated by spaces if((n_digits == 3) && !(wtab->flags & FLAG_MULTIPLE_SPACES) && isdigit(word[-2])) { prev_thousands = 1; } } if(prev_thousands == 0) { speak_missing_thousands = 0; } ph_ordinal2[0] = 0; ph_zeros[0] = 0; if(prev_thousands || (word[0] != '0')) { // don't check for ordinal if the number has a leading zero if((ordinal = CheckDotOrdinal(tr, word, &word[ix], wtab, 0)) != 0) dot_ordinal = 1; } if((word[ix] == '.') && !isdigit(word[ix+1]) && !isdigit(word[ix+2]) && !(wtab[1].flags & FLAG_NOSPACE)) { // remove dot unless followed by another number word[ix] = 0; } if((ordinal == 0) || (tr->translator_name == L('h','u'))) { // NOTE lang=hu, allow both dot and ordinal suffix, eg. "december 21.-én" // look for an ordinal number suffix after the number ix++; p = suffix; if(wtab[0].flags & FLAG_HYPHEN_AFTER) { *p++ = '-'; ix++; } while((word[ix] != 0) && (word[ix] != ' ') && (ix < (int)(sizeof(suffix)-1))) { *p++ = word[ix++]; } *p = 0; if(suffix[0] != 0) { if((tr->langopts.ordinal_indicator != NULL) && (strcmp(suffix, tr->langopts.ordinal_indicator) == 0)) { ordinal = 2; } else if(!isdigit(suffix[0])) // not _#9 (tab) { sprintf(string,"_#%s",suffix); if(Lookup(tr, string, ph_ordinal2)) { // this is an ordinal suffix ordinal = 2; flags[0] |= FLAG_SKIPWORDS; skipwords = 1; } } } } if(wtab[0].flags & FLAG_ORDINAL) ordinal = 2; ph_append[0] = 0; ph_buf2[0] = 0; if((word[0] == '0') && (prev_thousands == 0) && (word[1] != ' ') && (word[1] != tr->langopts.decimal_sep)) { if((n_digits == 2) && (word[3] == ':') && isdigit(word[5]) && isspace(word[7])) { // looks like a time 02:30, omit the leading zero } else { if(n_digits > 3) { flags[0] &= ~FLAG_SKIPWORDS; return(0); // long number string with leading zero, speak as individual digits } // speak leading zeros for(ix=0; (word[ix] == '0') && (ix < (n_digits-1)); ix++) { Lookup(tr, "_0", &ph_zeros[strlen(ph_zeros)]); } } } if((tr->langopts.numbers & NUM_ALLOW_SPACE) && (word[n_digits] == ' ')) thousands_inc = 1; else if(word[n_digits] == tr->langopts.thousands_sep) thousands_inc = 2; suffix_ix = n_digits+2; if(thousands_inc > 0) { // if the following "words" are three-digit groups, count them and add // a "thousand"/"million" suffix to this one digix = n_digits + thousands_inc; while(((wtab[thousandplex+1].flags & FLAG_MULTIPLE_SPACES) == 0) && CheckThousandsGroup(&word[digix], group_len)) { for(ix=0; ixlangopts.thousands_sep) || ((tr->langopts.numbers & NUM_ALLOW_SPACE) && (word[digix] == ' '))) { suffix_ix = digix+2; digix += thousands_inc; } else break; } } if((value == 0) && prev_thousands) { suppress_null = 1; } if(tr->translator_name == L('h','u')) { // variant form of numbers when followed by hyphen and a suffix starting with 'a' or 'e' (but not a, e, az, ez, azt, ezt if((wtab[thousandplex].flags & FLAG_HYPHEN_AFTER) && (thousands_exact==1) && hu_number_e(&word[suffix_ix], thousandplex, value)) { number_control |= 1; // use _1e variant of number } } if((word[n_digits] == tr->langopts.decimal_sep) && isdigit(word[n_digits+1])) { // this "word" ends with a decimal point Lookup(tr, "_dpt", ph_append); decimal_point = 1; } else if(suppress_null == 0) { if(thousands_inc > 0) { if(thousandplex > 0) // if((thousandplex > 0) && (value < 1000)) { if((suppress_null == 0) && (LookupThousands(tr,value,thousandplex, thousands_exact, ph_append))) { // found an exact match for N thousand value = 0; suppress_null = 1; } } } } else if(speak_missing_thousands == 1) { // speak this thousandplex if there was no word for the previous thousandplex sprintf(string,"_0M%d",thousandplex+1); if(Lookup(tr, string, buf1)==0) { sprintf(string,"_0M%d",thousandplex); Lookup(tr, string, ph_append); } } if((ph_append[0] == 0) && (word[n_digits] == '.') && (thousandplex == 0)) { Lookup(tr, "_.", ph_append); } if(thousandplex == 0) { char *p2; // look for combinations of the number with the next word p = word; while(isdigit(p[1])) p++; // just use the last digit if(isdigit(p[-1])) { p2 = p - 1; if(LookupDictList(tr, &p2, buf_digit_lookup, flags, FLAG_SUFX, wtab)) // lookup 2 digits { n_digit_lookup = 2; } } // if((buf_digit_lookup[0] == 0) && (*p != '0') && (dot_ordinal==0)) if((buf_digit_lookup[0] == 0) && (*p != '0')) { // not found, lookup only the last digit (?? but not if dot-ordinal has been found) if(LookupDictList(tr, &p, buf_digit_lookup, flags, FLAG_SUFX, wtab)) // don't match '0', or entries with $only { n_digit_lookup = 1; } } if((tr->langopts.numbers2 & NUM2_PERCENT_BEFORE) && (prev_thousands == 0)) { // LANG=si, say "percent" before the number p2 = word; while((*p2 != ' ') && (*p2 != 0)) { p2++; } if(p2[1] == '%') { Lookup(tr, "%", ph_out); ph_out += strlen(ph_out); p2[1] = ' '; } } } LookupNum3(tr, value, ph_buf, suppress_null, thousandplex, prev_thousands | ordinal); if((thousandplex > 0) && (tr->langopts.numbers2 & 0x200)) sprintf(ph_out,"%s%s%s%s",ph_zeros,ph_append,ph_buf2,ph_buf); // say "thousands" before its number else sprintf(ph_out,"%s%s%s%s",ph_zeros,ph_buf2,ph_buf,ph_append); while(decimal_point) { n_digits++; decimal_count = 0; while(isdigit(word[n_digits+decimal_count])) decimal_count++; // if(decimal_count > 1) { max_decimal_count = 2; switch(decimal_mode = (tr->langopts.numbers & 0xe000)) { case NUM_DFRACTION_4: max_decimal_count = 5; case NUM_DFRACTION_2: // French/Polish decimal fraction while(word[n_digits] == '0') { Lookup(tr, "_0", buf1); strcat(ph_out,buf1); decimal_count--; n_digits++; } if((decimal_count <= max_decimal_count) && isdigit(word[n_digits])) { LookupNum3(tr, atoi(&word[n_digits]), buf1, 0,0,0); strcat(ph_out,buf1); n_digits += decimal_count; } break; case NUM_DFRACTION_1: // italian, say "hundredths" if leading zero case NUM_DFRACTION_5: // hungarian, always say "tenths" etc. case NUM_DFRACTION_6: // kazakh, always say "tenths" etc, before the decimal fraction LookupNum3(tr, atoi(&word[n_digits]), ph_buf, 0,0,0); if((word[n_digits]=='0') || (decimal_mode != NUM_DFRACTION_1)) { // decimal part has leading zeros, so add a "hundredths" or "thousandths" suffix sprintf(string,"_0Z%d",decimal_count); if(Lookup(tr, string, buf1) == 0) break; // revert to speaking single digits if(decimal_mode == NUM_DFRACTION_6) strcat(ph_out, buf1); else strcat(ph_buf, buf1); } strcat(ph_out,ph_buf); n_digits += decimal_count; break; case NUM_DFRACTION_3: // Romanian decimal fractions if((decimal_count <= 4) && (word[n_digits] != '0')) { LookupNum3(tr, atoi(&word[n_digits]), buf1, 0,0,0); strcat(ph_out,buf1); n_digits += decimal_count; } break; } } while(isdigit(c = word[n_digits]) && (strlen(ph_out) < (N_WORD_PHONEMES - 10))) { // speak any remaining decimal fraction digits individually value = word[n_digits++] - '0'; LookupNum2(tr, value, 2, buf1); strcat(ph_out,buf1); } // something after the decimal part ? if(Lookup(tr, "_dpt2", buf1)) strcat(ph_out,buf1); if((c == tr->langopts.decimal_sep) && isdigit(word[n_digits+1])) { Lookup(tr, "_dpt", buf1); strcat(ph_out,buf1); } else { decimal_point = 0; } } if((ph_out[0] != 0) && (ph_out[0] != phonSWITCH)) { int next_char; char *p; p = &word[n_digits+1]; p += utf8_in(&next_char,p); if((tr->langopts.numbers & NUM_NOPAUSE) && (next_char == ' ')) utf8_in(&next_char,p); if(!iswalpha(next_char) && !((wtab[thousandplex].flags & FLAG_HYPHEN_AFTER) && (thousands_exact != 0))) strcat(ph_out,str_pause); // don't add pause for 100s, 6th, etc. } *flags |= FLAG_FOUND; speak_missing_thousands--; if(skipwords) dictionary_skipwords = skipwords; return(1); } // end of TranslateNumber_1 int TranslateNumber(Translator *tr, char *word1, char *ph_out, unsigned int *flags, WORD_TAB *wtab, int control) {//============================================================================================================= if((option_sayas == SAYAS_DIGITS1) || (wtab[0].flags & FLAG_INDIVIDUAL_DIGITS)) return(0); // speak digits individually if(tr->langopts.numbers != 0) { return(TranslateNumber_1(tr, word1, ph_out, flags, wtab, control)); } return(0); } // end of TranslateNumber praat-6.0.04/external/espeak/phoneme.h000066400000000000000000000142271261542461700176240ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2005 to 2010 by Jonathan Duddington * * email: jonsd@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, see: * * . * ***************************************************************************/ // phoneme types #define phPAUSE 0 #define phSTRESS 1 #define phVOWEL 2 #define phLIQUID 3 #define phSTOP 4 #define phVSTOP 5 #define phFRICATIVE 6 #define phVFRICATIVE 7 #define phNASAL 8 #define phVIRTUAL 9 #define phDELETED 14 #define phINVALID 15 // phoneme properties // bits 16-19 give place of articulation #define phARTICULATION 0xf0000 #define phWAVE 0x01 #define phUNSTRESSED 0x02 #define phFORTIS 0x08 #define phVOICED 0x10 #define phSIBILANT 0x20 #define phNOLINK 0x40 #define phTRILL 0x80 #define phVOWEL2 0x100 // liquid that is considered a vowel #define phPALATAL 0x200 #define phSINGLE_INSTN 0x1000 // this phoneme has a single instruction program, with an implicit Return #define phBRKAFTER 0x4000 // [*] add a post-pause #define phNONSYLLABIC 0x100000 // don't count this vowel as a syllable when finding the stress position #define phLONG 0x200000 #define phLENGTHENSTOP 0x400000 // make the pre-pause slightly longer #define phRHOTIC 0x800000 // bit 23 #define phNOPAUSE 0x1000000 #define phPREVOICE 0x2000000 // for voiced stops #define phFLAG1 0x10000000 #define phFLAG2 0x20000000 #define phFLAG3 0x40000000 #define phLOCAL 0x80000000 // used during compilation // fixed phoneme code numbers, these can be used from the program code #define phonCONTROL 1 #define phonSTRESS_U 2 #define phonSTRESS_D 3 #define phonSTRESS_2 4 #define phonSTRESS_3 5 #define phonSTRESS_P 6 #define phonSTRESS_P2 7 // priority stress within a word #define phonSTRESS_PREV 8 #define phonPAUSE 9 #define phonPAUSE_SHORT 10 #define phonPAUSE_NOLINK 11 #define phonLENGTHEN 12 #define phonSCHWA 13 #define phonSCHWA_SHORT 14 #define phonEND_WORD 15 #define phonDEFAULTTONE 17 #define phonCAPITAL 18 #define phonGLOTTALSTOP 19 #define phonSYLLABIC 20 #define phonSWITCH 21 #define phonX1 22 // a language specific action #define phonPAUSE_VSHORT 23 #define phonPAUSE_LONG 24 #define phonT_REDUCED 25 #define phonSTRESS_TONIC 26 #define phonPAUSE_CLAUSE 27 #define phonVOWELTYPES 28 // 28 to 33 extern const unsigned char pause_phonemes[8]; // 0, vshort, short, pause, long, glottalstop // place of articulation #define phPLACE 0xf0000 #define phPLACE_blb 0x10000 #define phPLACE_pla 0x60000 #define N_PHONEME_TABS 100 // number of phoneme tables #define N_PHONEME_TAB 256 // max phonemes in a phoneme table #define N_PHONEME_TAB_NAME 32 // must be multiple of 4 // main table of phonemes, index by phoneme number (1-254) typedef struct { unsigned int mnemonic; // Up to 4 characters. The first char is in the l.s.byte unsigned int phflags; // bits 16-19 place of articulation unsigned short program; // index into phondata file unsigned char code; // the phoneme number unsigned char type; // phVOWEL, phPAUSE, phSTOP etc unsigned char start_type; unsigned char end_type; unsigned char std_length; // for vowels, in mS/2; for phSTRESS phonemes, this is the stress/tone type unsigned char length_mod; // a length_mod group number, used to access length_mod_tab } PHONEME_TAB; // Several phoneme tables may be loaded into memory. phoneme_tab points to // one for the current voice extern int n_phoneme_tab; extern int current_phoneme_table; extern PHONEME_TAB *phoneme_tab[N_PHONEME_TAB]; extern unsigned char phoneme_tab_flags[N_PHONEME_TAB]; // bit 0: not inherited typedef struct { char name[N_PHONEME_TAB_NAME]; PHONEME_TAB *phoneme_tab_ptr; int n_phonemes; int includes; // also include the phonemes from this other phoneme table int equivalence_tables; // lists of equivalent phonemes to match other languages, byte index into phondata } PHONEME_TAB_LIST; // table of phonemes to be replaced with different phonemes, for the current voice #define N_REPLACE_PHONEMES 60 typedef struct { unsigned char old_ph; unsigned char new_ph; char type; // 0=always replace, 1=only at end of word } REPLACE_PHONEMES; extern int n_replace_phonemes; extern REPLACE_PHONEMES replace_phonemes[N_REPLACE_PHONEMES]; // Table of phoneme programs and lengths. Used by MakeVowelLists typedef struct { unsigned int addr; unsigned int length; } PHONEME_PROG_LOG; #define PH(c1,c2) (c2<<8)+c1 // combine two characters into an integer for phoneme name #define PH3(c1,c2,c3) (c3<<16)+(c2<<8)+c1 #define PhonemeCode2(c1,c2) PhonemeCode((c2<<8)+c1) int LookupPhonemeString(const char *string); int PhonemeCode(unsigned int mnem); const char *EncodePhonemes(const char *p, char *outptr, unsigned char *bad_phoneme); void DecodePhonemes(const char *inptr, char *outptr); extern const char *WordToString(unsigned int word); extern PHONEME_TAB_LIST phoneme_tab_list[N_PHONEME_TABS]; extern int phoneme_tab_number; praat-6.0.04/external/espeak/phonemelist.cpp000066400000000000000000000371341261542461700210550ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2005 to 2011 by Jonathan Duddington * * email: jonsd@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, see: * * . * ***************************************************************************/ #include "StdAfx.h" #include #include #include #include "speak_lib.h" #include "speech.h" #include "phoneme.h" #include "synthesize.h" #include "translate.h" const unsigned char pause_phonemes[8] = {0, phonPAUSE_VSHORT, phonPAUSE_SHORT, phonPAUSE, phonPAUSE_LONG, phonGLOTTALSTOP, phonPAUSE_LONG, phonPAUSE_LONG}; extern int n_ph_list2; extern PHONEME_LIST2 ph_list2[N_PHONEME_LIST]; // first stage of text->phonemes static int SubstitutePhonemes(Translator *tr, PHONEME_LIST *plist_out) {//=================================================================== // Copy the phonemes list and perform any substitutions that are required for the // current voice int ix; int k; int replace_flags; int n_plist_out = 0; int word_end; int switched_language = 0; PHONEME_LIST2 *plist2; PHONEME_TAB *next=NULL; for(ix=0; (ix < n_ph_list2) && (n_plist_out < N_PHONEME_LIST); ix++) { plist2 = &ph_list2[ix]; if(plist2->phcode == phonSWITCH) switched_language ^= 1; // don't do any substitution if the language has been temporarily changed if(switched_language == 0) { if(ix < (n_ph_list2 -1)) next = phoneme_tab[ph_list2[ix+1].phcode]; word_end = 0; if((plist2+1)->sourceix || ((next != 0) && (next->type == phPAUSE))) word_end = 1; // this phoneme is the end of a word // check whether a Voice has specified that we should replace this phoneme for(k=0; kphcode == replace_phonemes[k].old_ph) { replace_flags = replace_phonemes[k].type; if((replace_flags & 1) && (word_end == 0)) continue; // this replacement only occurs at the end of a word if((replace_flags & 2) && ((plist2->stresslevel & 0x7) > 3)) continue; // this replacement doesn't occur in stressed syllables // substitute the replacement phoneme plist2->phcode = replace_phonemes[k].new_ph; if((plist2->stresslevel > 1) && (phoneme_tab[plist2->phcode]->phflags & phUNSTRESSED)) plist2->stresslevel = 0; // the replacement must be unstressed break; } } if(plist2->phcode == 0) { continue; // phoneme has been replaced by NULL, so don't copy it } } // copy phoneme into the output list memcpy(&plist_out[n_plist_out],plist2,sizeof(PHONEME_LIST2)); plist_out[n_plist_out].ph = phoneme_tab[plist2->phcode]; plist_out[n_plist_out].type = plist_out[n_plist_out].ph->type; n_plist_out++; } return(n_plist_out); } // end of SubstitutePhonemes void MakePhonemeList(Translator *tr, int post_pause, int start_sentence) {//===================================================================== int ix=0; int j; int insert_ph = 0; PHONEME_LIST *phlist; PHONEME_TAB *ph; PHONEME_TAB *next, *next2; int unstress_count = 0; int word_stress = 0; int switched_language = 0; int max_stress; int voicing; int regression; int end_sourceix; int alternative; PHONEME_DATA phdata; int n_ph_list3; PHONEME_LIST *plist3; PHONEME_LIST *plist3_inserted = NULL; PHONEME_LIST ph_list3[N_PHONEME_LIST]; PHONEME_LIST2 *plist2; WORD_PH_DATA worddata; memset(&worddata, 0, sizeof(worddata)); plist2 = ph_list2; phlist = phoneme_list; end_sourceix = plist2[n_ph_list2-1].sourceix; // is the last word of the clause unstressed ? max_stress = 0; for(j = n_ph_list2-3; j>=0; j--) { // start with the last phoneme (before the terminating pauses) and move forwards if((plist2[j].stresslevel & 0x7f) > max_stress) max_stress = plist2[j].stresslevel & 0x7f; if(plist2[j].sourceix != 0) break; } if(max_stress < 4) { // the last word is unstressed, look for a previous word that can be stressed while(--j >= 0) { if(plist2[j].synthflags & SFLAG_PROMOTE_STRESS) // dictionary flags indicated that this stress can be promoted { plist2[j].stresslevel = 4; // promote to stressed break; } if(plist2[j].stresslevel >= 4) { // found a stressed syllable, so stop looking break; } } } if((regression = tr->langopts.param[LOPT_REGRESSIVE_VOICING]) != 0) { // set consonant clusters to all voiced or all unvoiced // Regressive int type; int stop_propagation = 0; voicing = 0; for(j=n_ph_list2-1; j>=0; j--) { ph = phoneme_tab[plist2[j].phcode]; if(ph == NULL) continue; if(ph->code == phonSWITCH) switched_language ^= 1; if(switched_language) continue; type = ph->type; if(regression & 0x2) { // [v] amd [v;] don't cause regression, or [R^] if(((ph->mnemonic & 0xff) == 'v') || ((ph->mnemonic & 0xff)== 'R')) { stop_propagation = 1; if(regression & 0x10) voicing = 0; } } if((type==phSTOP) || type==(phFRICATIVE)) { if((voicing==0) && (regression & 0xf)) { voicing = 1; } else if((voicing==2) && (ph->end_type != 0)) // use end_type field for voicing_switch for consonants { plist2[j].phcode = ph->end_type; // change to voiced equivalent } } else if((type==phVSTOP) || type==(phVFRICATIVE)) { if((voicing==0) && (regression & 0xf)) { voicing = 2; } else if((voicing==1) && (ph->end_type != 0)) { plist2[j].phcode = ph->end_type; // change to unvoiced equivalent } } else { if(regression & 0x8) { // LANG=Polish, propagate through liquids and nasals if((type == phPAUSE) || (type == phVOWEL)) voicing = 0; } else { voicing = 0; } } if(stop_propagation) { voicing = 0; stop_propagation = 0; } if(plist2[j].sourceix) { if(regression & 0x04) { // stop propagation at a word boundary voicing = 0; } if(regression & 0x100) { // devoice word-final consonants, unless propagating voiced if(voicing == 0) { voicing = 1; } } } } } n_ph_list3 = SubstitutePhonemes(tr,ph_list3) - 2; for(j=0; (j < n_ph_list3) && (ix < N_PHONEME_LIST-3);) { if(ph_list3[j].sourceix) { // start of a word int k; int nextw; word_stress = 0; // find the highest stress level in this word for(nextw=j; nextw < n_ph_list3;) { if(ph_list3[nextw].stresslevel > word_stress) word_stress = ph_list3[nextw].stresslevel; nextw++; if(ph_list3[nextw].sourceix) break; // start of the next word } for(k=j; kphcode]; // this phoneme, i.e. after the insert // re-use the previous entry for the inserted phoneme. // That's OK because we don't look backwards from plist3 *** but CountVowelPosiion() and isAfterStress does !!! j--; plist3 = plist3_inserted = &ph_list3[j]; if(j > 0) { memcpy(&plist3[-1], &plist3[0], sizeof(*plist3)); } memset(&plist3[0], 0, sizeof(*plist3)); plist3->phcode = insert_ph; ph = phoneme_tab[insert_ph]; plist3->ph = ph; insert_ph = 0; } else { // otherwise get the next phoneme from the list ph = phoneme_tab[plist3->phcode]; plist3[0].ph = ph; if(plist3->phcode == phonSWITCH) { // change phoneme table SelectPhonemeTable(plist3->tone_ph); switched_language ^= SFLAG_SWITCHED_LANG; } next = phoneme_tab[plist3[1].phcode]; // the phoneme after this one plist3[1].ph = next; } if(ph == NULL) continue; InterpretPhoneme(tr, 0x100, plist3, &phdata, &worddata); if((alternative = phdata.pd_param[pd_INSERTPHONEME]) > 0) { // PROBLEM: if we insert a phoneme before a vowel then we loose the stress. PHONEME_TAB *ph2; ph2 = ph; insert_ph = plist3->phcode; ph = phoneme_tab[alternative]; plist3->ph = ph; plist3->phcode = alternative; if(ph->type == phVOWEL) { plist3->synthflags |= SFLAG_SYLLABLE; if(ph2->type != phVOWEL) plist3->stresslevel = 0; // change from non-vowel to vowel, make sure it's unstressed } else plist3->synthflags &= ~SFLAG_SYLLABLE; // re-interpret the changed phoneme // But it doesn't obey a second ChangePhoneme() InterpretPhoneme(tr, 0x100, plist3, &phdata, &worddata); } if((alternative = phdata.pd_param[pd_CHANGEPHONEME]) > 0) { PHONEME_TAB *ph2; ph2 = ph; ph = phoneme_tab[alternative]; plist3->ph = ph; plist3->phcode = alternative; if(alternative == 1) continue; // NULL phoneme, discard if(ph->type == phVOWEL) { plist3->synthflags |= SFLAG_SYLLABLE; if(ph2->type != phVOWEL) plist3->stresslevel = 0; // change from non-vowel to vowel, make sure it's unstressed } else plist3->synthflags &= ~SFLAG_SYLLABLE; // re-interpret the changed phoneme // But it doesn't obey a second ChangePhoneme() InterpretPhoneme(tr, 0x100, plist3, &phdata, &worddata); } if(ph->type == phVOWEL) { PHONEME_LIST *p; // Check for consecutive unstressed syllables, even across word boundaries. // Do this after changing phonemes according to stress level. if(plist3->stresslevel <= 1) { // an unstressed vowel unstress_count++; if(tr->langopts.stress_flags & 0x08) { // change sequences of consecutive unstressed vowels in unstressed words to diminished stress (TEST) for(p=plist3+1; p->type != phPAUSE; p++) { if(p->type == phVOWEL) { if(p->stresslevel <= 1) { if(plist3->wordstress < 4) plist3->stresslevel = 0; if(p->wordstress < 4) p->stresslevel = 0; } break; } } } else { if((unstress_count > 1) && ((unstress_count & 1)==0)) { // in a sequence of unstressed syllables, reduce alternate syllables to 'diminished' // stress. But not for the last phoneme of a stressed word if((tr->langopts.stress_flags & 0x2) || ((word_stress > 3) && ((plist3+1)->sourceix!=0))) { // An unstressed final vowel of a stressed word unstress_count=1; // try again for next syllable } else { plist3->stresslevel = 0; // change stress to 'diminished' } } } } else { unstress_count = 0; } } if((plist3+1)->synthflags & SFLAG_LENGTHEN) { static char types_double[] = {phFRICATIVE,phVFRICATIVE,phNASAL,phLIQUID,0}; if(strchr(types_double,next->type)) { // lengthen this consonant by doubling it insert_ph = next->code; (plist3+1)->synthflags ^= SFLAG_LENGTHEN; } } if((plist3+1)->sourceix != 0) { int x; if(tr->langopts.vowel_pause && (ph->type != phPAUSE)) { if((ph->type != phVOWEL) && (tr->langopts.vowel_pause & 0x200)) { // add a pause after a word which ends in a consonant insert_ph = phonPAUSE_NOLINK; } if(next->type == phVOWEL) { if((x = tr->langopts.vowel_pause & 0x0c) != 0) { // break before a word which starts with a vowel if(x == 0xc) insert_ph = phonPAUSE_NOLINK; else insert_ph = phonPAUSE_VSHORT; } if((ph->type == phVOWEL) && ((x = tr->langopts.vowel_pause & 0x03) != 0)) { // adjacent vowels over a word boundary if(x == 2) insert_ph = phonPAUSE_SHORT; else insert_ph = phonPAUSE_VSHORT; } if(((plist3+1)->stresslevel >= 4) && (tr->langopts.vowel_pause & 0x100)) { // pause before a words which starts with a stressed vowel insert_ph = phonPAUSE_SHORT; } } } if(plist3 != plist3_inserted) { if((x = (tr->langopts.word_gap & 0x7)) != 0) { if((x > 1) || ((insert_ph != phonPAUSE_SHORT) && (insert_ph != phonPAUSE_NOLINK))) { // don't reduce the pause insert_ph = pause_phonemes[x]; } } if(option_wordgap > 0) { insert_ph = phonPAUSE_LONG; } } } next2 = phoneme_tab[plist3[2].phcode]; plist3[2].ph = next2; if((insert_ph == 0) && (phdata.pd_param[pd_APPENDPHONEME] != 0)) { insert_ph = phdata.pd_param[pd_APPENDPHONEME]; } if(ph->phflags & phVOICED) { // check that a voiced consonant is preceded or followed by a vowel or liquid // and if not, add a short schwa // not yet implemented } phlist[ix].ph = ph; phlist[ix].type = ph->type; phlist[ix].env = PITCHfall; // default, can be changed in the "intonation" module phlist[ix].synthflags = plist3->synthflags | switched_language; phlist[ix].stresslevel = plist3->stresslevel & 0xf; phlist[ix].wordstress = plist3->wordstress; phlist[ix].tone_ph = plist3->tone_ph; phlist[ix].sourceix = 0; phlist[ix].phcode = ph->code; if(plist3->sourceix != 0) { phlist[ix].sourceix = plist3->sourceix; phlist[ix].newword = 1; // this phoneme is the start of a word if(start_sentence) { phlist[ix].newword = 5; // start of sentence + start of word start_sentence = 0; } } else { phlist[ix].newword = 0; } // phlist[ix].length = ph->std_length; phlist[ix].length = phdata.pd_param[i_SET_LENGTH]*2; if((ph->code == phonPAUSE_LONG) && (option_wordgap > 0)) { phlist[ix].ph = phoneme_tab[phonPAUSE_SHORT]; phlist[ix].length = option_wordgap*14; // 10mS per unit at the default speed } if(ph->type==phVOWEL || ph->type==phLIQUID || ph->type==phNASAL || ph->type==phVSTOP || ph->type==phVFRICATIVE) { phlist[ix].length = 128; // length_mod phlist[ix].env = PITCHfall; } phlist[ix].prepause = 0; phlist[ix].amp = 20; // default, will be changed later phlist[ix].pitch1 = 255; phlist[ix].pitch2 = 255; ix++; } phlist[ix].newword = 2; // end of clause phlist[ix].phcode = phonPAUSE; phlist[ix].type = phPAUSE; // terminate with 2 Pause phonemes phlist[ix].length = post_pause; // length of the pause, depends on the punctuation phlist[ix].sourceix = end_sourceix; phlist[ix].synthflags = 0; phlist[ix++].ph = phoneme_tab[phonPAUSE]; phlist[ix].phcode = phonPAUSE; phlist[ix].type = phPAUSE; phlist[ix].length = 0; phlist[ix].sourceix=0; phlist[ix].synthflags = 0; phlist[ix++].ph = phoneme_tab[phonPAUSE_SHORT]; n_phoneme_list = ix; } // end of MakePhonemeList praat-6.0.04/external/espeak/readclause.cpp000066400000000000000000002011661261542461700206340ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2005 to 2011 by Jonathan Duddington * * email: jonsd@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write see: * * . * ***************************************************************************/ #include "StdAfx.h" #include #include #include #include #include #include #include #include "speak_lib.h" #include "speech.h" #include "phoneme.h" #include "synthesize.h" #include "voice.h" #include "translate.h" #ifdef PLATFORM_POSIX #include #endif #include #define N_XML_BUF 256 static const char *xmlbase = ""; // base URL from static int namedata_ix=0; static int n_namedata = 0; char *namedata = NULL; static FILE *f_input = NULL; static int ungot_char2 = 0; unsigned char *p_textinput; wchar_t *p_wchar_input; static int ungot_char; static const char *ungot_word = NULL; static int end_of_input; static int ignore_text=0; // set during ... to ignore text which has been replaced by an alias static int audio_text=0; // set during static int clear_skipping_text = 0; // next clause should clear the skipping_text flag int count_characters = 0; static int sayas_mode; static int sayas_start; static int ssml_ignore_l_angle = 0; // alter tone for announce punctuation or capitals //static const char *tone_punct_on = "\0016T"; // add reverberation, lower pitch //static const char *tone_punct_off = "\001T\001P"; // punctuations symbols that can end a clause static const unsigned short punct_chars[] = {',','.','?','!',':',';', 0x2013, // en-dash 0x2014, // em-dash 0x2026, // elipsis 0x037e, // Greek question mark (looks like semicolon) 0x0387, // Greek semicolon, ano teleia 0x0964, // Devanagari Danda (fullstop) 0x0589, // Armenian period 0x055d, // Armenian comma 0x055c, // Armenian exclamation 0x055e, // Armenian question 0x055b, // Armenian emphasis mark 0x0b1b, // Arabic ; 0x061f, // Arabic ? 0x0f0d, // Tibet Shad 0x0f0e, 0x1362, // Ethiopic period 0x1363, 0x1364, 0x1365, 0x1366, 0x1367, 0x1368, 0x10fb, // Georgian paragraph 0x3001, // ideograph comma 0x3002, // ideograph period 0xff01, // fullwidth exclamation 0xff0c, // fullwidth comma 0xff0e, // fullwidth period 0xff1a, // fullwidth colon 0xff1b, // fullwidth semicolon 0xff1f, // fullwidth question mark 0}; // indexed by (entry num. in punct_chars) + 1 // bits 0-7 pause x 10mS, bits 12-14 intonation type, bit 15 don't need following space or bracket static const unsigned int punct_attributes [] = { 0, CLAUSE_COMMA, CLAUSE_PERIOD, CLAUSE_QUESTION, CLAUSE_EXCLAMATION, CLAUSE_COLON, CLAUSE_SEMICOLON, CLAUSE_SEMICOLON, // en-dash CLAUSE_SEMICOLON, // em-dash CLAUSE_SEMICOLON | PUNCT_SAY_NAME | 0x8000, // elipsis CLAUSE_QUESTION, // Greek question mark CLAUSE_SEMICOLON, // Greek semicolon CLAUSE_PERIOD | 0x8000, // Devanagari Danda (fullstop) CLAUSE_PERIOD | 0x8000, // Armenian period CLAUSE_COMMA, // Armenian comma CLAUSE_EXCLAMATION | PUNCT_IN_WORD, // Armenian exclamation CLAUSE_QUESTION | PUNCT_IN_WORD, // Armenian question CLAUSE_PERIOD | PUNCT_IN_WORD, // Armenian emphasis mark CLAUSE_SEMICOLON, // Arabic ; CLAUSE_QUESTION, // Arabic question mark CLAUSE_PERIOD+0x8000, // Tibet period CLAUSE_PARAGRAPH, CLAUSE_PERIOD, // Ethiopic period CLAUSE_COMMA, // Ethiopic comma CLAUSE_SEMICOLON, // Ethiopic semicolon CLAUSE_COLON, // Ethiopic colon CLAUSE_COLON, // Ethiopic preface colon CLAUSE_QUESTION, // Ethiopic question mark CLAUSE_PARAGRAPH, // Ethiopic paragraph CLAUSE_PARAGRAPH, // Georgian paragraph CLAUSE_COMMA+0x8000, // ideograph comma CLAUSE_PERIOD+0x8000, // ideograph period CLAUSE_EXCLAMATION+0x8000, // fullwidth CLAUSE_COMMA+0x8000, CLAUSE_PERIOD+0x8000, CLAUSE_COLON+0x8000, CLAUSE_SEMICOLON+0x8000, CLAUSE_QUESTION+0x8000, CLAUSE_SEMICOLON, // spare 0 }; // stack for language and voice properties // frame 0 is for the defaults, before any ssml tags. typedef struct { int tag_type; int voice_variant_number; int voice_gender; int voice_age; char voice_name[40]; char language[20]; } SSML_STACK; #define N_SSML_STACK 20 static int n_ssml_stack; static SSML_STACK ssml_stack[N_SSML_STACK]; static espeak_VOICE base_voice; static char base_voice_variant_name[40] = {0}; static char current_voice_id[40] = {0}; #define N_PARAM_STACK 20 static int n_param_stack; PARAM_STACK param_stack[N_PARAM_STACK]; static int speech_parameters[N_SPEECH_PARAM]; // current values, from param_stack int saved_parameters[N_SPEECH_PARAM]; //Parameters saved on synthesis start const int param_defaults[N_SPEECH_PARAM] = { 0, // silence (internal use) 175, // rate wpm 100, // volume 50, // pitch 50, // range 0, // punctuation 0, // capital letters 0, // wordgap 0, // options 0, // intonation 0, 0, 0, // emphasis 0, // line length 0, // voice type }; #ifdef NEED_WCHAR_FUNCTIONS // additional Latin characters beyond the Latin1 character set #define MAX_WALPHA 0x233 // indexed by character - 0x100 // 0=not alphabetic, 0xff=lower case, 0xfe=special case // other=value to add to upper case to convert to lower case static unsigned char walpha_tab[MAX_WALPHA-0xff] = { 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 100 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 110 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 120 0xfe,0xff, 1,0xff, 1,0xff, 1,0xff,0xff, 1,0xff, 1,0xff, 1,0xff, 1, // 130 0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff,0xff, 1,0xff, 1,0xff, 1,0xff, // 140 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 150 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 160 1,0xff, 1,0xff, 1,0xff, 1,0xff,0xff, 1,0xff, 1,0xff, 1,0xff,0xff, // 170 0xff, 210, 1,0xff, 1,0xff, 206, 1,0xff, 205, 205, 1,0xff,0xff, 79, 202, // 180 203, 1,0xff, 205, 207,0xff, 211, 209, 1,0xff,0xff,0xff, 211, 213,0xff, 214, // 190 1,0xff, 1,0xff, 1,0xff, 218, 1,0xff, 218,0xff,0xff, 1,0xff, 218, 1, // 1a0 0xff, 217, 217, 1,0xff, 1,0xff, 219, 1,0xff,0xff,0xff, 1,0xff,0xff,0xff, // 1b0 0xff,0xff,0xff,0xff, 2, 1,0xff, 2, 1,0xff, 2, 1,0xff, 1,0xff, 1, // 1c0 0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff,0xff, 1,0xff, // 1d0 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 1e0 0xff, 2, 1,0xff, 1,0xff,0xff,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 1f0 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 200 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 210 0xff, 0, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 220 1,0xff, 1,0xff }; // 230 // use ctype.h functions for Latin1 (character < 0x100) int iswalpha(int c) { if(c < 0x100) return(isalpha(c)); if((c > 0x3040) && (c <= 0xa700)) return(1); // japanese, chinese characters if(c > MAX_WALPHA) return(0); return(walpha_tab[c-0x100]); } int iswdigit(int c) { if(c < 0x100) return(isdigit(c)); return(0); } int iswalnum(int c) { if(iswdigit(c)) return(1); return(iswalpha(c)); } int towlower(int c) { int x; if(c < 0x100) return(tolower(c)); if((c > MAX_WALPHA) || ((x = walpha_tab[c-0x100])==0xff)) return(c); // already lower case if(x == 0xfe) { // special cases if(c == 0x130) // uppercase i-dot return('i'); } return(c + x); // convert to lower case } int towupper(int c) { // check whether the previous character code is the upper-case equivalent of this character if(tolower(c-1) == c) return(c-1); // yes, use it return(c); // no } int iswupper(int c) { int x; if(c < 0x100) return(isupper(c)); if(((c > MAX_WALPHA) || (x = walpha_tab[c-0x100])==0) || (x == 0xff)) return(0); return(1); } int iswlower(int c) { if(c < 0x100) return(islower(c)); if((c > MAX_WALPHA) || (walpha_tab[c-0x100] != 0xff)) return(0); return(1); } int iswspace(int c) { if(c < 0x100) return(isspace(c)); return(0); } int iswpunct(int c) { if(c < 0x100) return(ispunct(c)); return(0); } const wchar_t *wcschr(const wchar_t *str, int c) { while(*str != 0) { if(*str == c) return(str); str++; } return(NULL); } #ifndef WINCE // wcslen() is provided by WINCE, but not the other wchar functions const int wcslen(const wchar_t *str) { int ix=0; while(*str != 0) { ix++; } return(ix); } #endif float wcstod(const wchar_t *str, wchar_t **tailptr) { int ix; char buf[80]; while(isspace(*str)) str++; for(ix=0; ix<80; ix++) { buf[ix] = str[ix]; if(isspace(buf[ix])) break; } *tailptr = (wchar_t *)&str[ix]; return(atof(buf)); } #endif int towlower2(unsigned int c) { // check for non-standard upper to lower case conversions if(c == 'I') { if(translator->translator_name == L('t','r')) { c = 0x131; // I -> ı } } #ifdef __WIN32__ if(c == 0x130) // uppercase i-dot return('i'); #endif return(towlower(c)); } static int IsRomanU(unsigned int c) {//================================ if((c=='I') || (c=='V') || (c=='X') || (c=='L')) return(1); return(0); } static void GetC_unget(int c) {//========================== // This is only called with UTF8 input, not wchar input if(f_input != NULL) ungetc(c,f_input); else { p_textinput--; *p_textinput = c; end_of_input = 0; } } int Eof(void) {//========== if(ungot_char != 0) return(0); if(f_input != 0) return(feof(f_input)); return(end_of_input); } static int GetC_get(void) {//====================== unsigned int c; unsigned int c2; if(f_input != NULL) { c = fgetc(f_input); if(feof(f_input)) c = ' '; if(option_multibyte == espeakCHARS_16BIT) { c2 = fgetc(f_input); if(feof(f_input)) c2 = 0; c = c + (c2 << 8); } return(c); } if(option_multibyte == espeakCHARS_WCHAR) { if(*p_wchar_input == 0) { end_of_input = 1; return(0); } if(!end_of_input) return(*p_wchar_input++); } else { if(*p_textinput == 0) { end_of_input = 1; return(0); } if(!end_of_input) { if(option_multibyte == espeakCHARS_16BIT) { c = p_textinput[0] + (p_textinput[1] << 8); p_textinput += 2; return(c); } return(*p_textinput++ & 0xff); } } return(0); } static int GetC(void) {//================== // Returns a unicode wide character // Performs UTF8 checking and conversion int c; int c1; int c2; int cbuf[4]; int ix; int n_bytes; static int ungot2 = 0; static const unsigned char mask[4] = {0xff,0x1f,0x0f,0x07}; if((c1 = ungot_char) != 0) { ungot_char = 0; return(c1); } if(ungot2 != 0) { c1 = ungot2; ungot2 = 0; } else { c1 = GetC_get(); } if((option_multibyte == espeakCHARS_WCHAR) || (option_multibyte == espeakCHARS_16BIT)) { count_characters++; return(c1); // wchar_t text } if((option_multibyte < 2) && (c1 & 0x80)) { // multi-byte utf8 encoding, convert to unicode n_bytes = 0; if(((c1 & 0xe0) == 0xc0) && ((c1 & 0x1e) != 0)) n_bytes = 1; else if((c1 & 0xf0) == 0xe0) n_bytes = 2; else if(((c1 & 0xf8) == 0xf0) && ((c1 & 0x0f) <= 4)) n_bytes = 3; if((ix = n_bytes) > 0) { c = c1 & mask[ix]; while(ix > 0) { if((c2 = cbuf[ix] = GetC_get()) == 0) { if(option_multibyte==espeakCHARS_AUTO) option_multibyte=espeakCHARS_8BIT; // change "auto" option to "no" GetC_unget(' '); break; } if((c2 & 0xc0) != 0x80) { // This is not UTF8. Change to 8-bit characterset. if((n_bytes == 2) && (ix == 1)) ungot2 = cbuf[2]; GetC_unget(c2); break; } c = (c << 6) + (c2 & 0x3f); ix--; } if(ix == 0) { count_characters++; return(c); } } // top-bit-set character is not utf8, drop through to 8bit charset case if((option_multibyte==espeakCHARS_AUTO) && !Eof()) option_multibyte=espeakCHARS_8BIT; // change "auto" option to "no" } // 8 bit character set, convert to unicode if count_characters++; if(c1 >= 0xa0) return(translator->charset_a0[c1-0xa0]); return(c1); } // end of GetC static void UngetC(int c) {//====================== ungot_char = c; } static const char *WordToString2(unsigned int word) {//================================================ // Convert a language mnemonic word into a string int ix; static char buf[5]; char *p; p = buf; for(ix=3; ix>=0; ix--) { if((*p = word >> (ix*8)) != 0) p++; } *p = 0; return(buf); } static const char *LookupSpecial(Translator *tr, const char *string, char* text_out) {//================================================================================= unsigned int flags[2]; char phonemes[55]; char phonemes2[55]; char *string1 = (char *)string; flags[0] = flags[1] = 0; if(LookupDictList(tr,&string1,phonemes,flags,0,NULL)) { SetWordStress(tr, phonemes, flags, -1, 0); DecodePhonemes(phonemes,phonemes2); sprintf(text_out,"[\002%s]]",phonemes2); return(text_out); } return(NULL); } static const char *LookupCharName(Translator *tr, int c, int only) {//=============================================================== // Find the phoneme string (in ascii) to speak the name of character c // Used for punctuation characters and symbols int ix; unsigned int flags[2]; char single_letter[24]; char phonemes[60]; char phonemes2[60]; const char *lang_name = NULL; char *string; static char buf[60]; buf[0] = 0; flags[0] = 0; flags[1] = 0; single_letter[0] = 0; single_letter[1] = '_'; ix = utf8_out(c,&single_letter[2]); single_letter[2+ix]=0; if(only) { string = &single_letter[2]; LookupDictList(tr, &string, phonemes, flags, 0, NULL); } else { string = &single_letter[1]; if(LookupDictList(tr, &string, phonemes, flags, 0, NULL) == 0) { // try _* then * string = &single_letter[2]; if(LookupDictList(tr, &string, phonemes, flags, 0, NULL) == 0) { // now try the rules single_letter[1] = ' '; TranslateRules(tr, &single_letter[2], phonemes, sizeof(phonemes), NULL,0,NULL); } } } if((only==0) && (phonemes[0] == 0) && (tr->translator_name != L('e','n'))) { // not found, try English SetTranslator2("en"); string = &single_letter[1]; single_letter[1] = '_'; if(LookupDictList(translator2, &string, phonemes, flags, 0, NULL) == 0) { string = &single_letter[2]; LookupDictList(translator2, &string, phonemes, flags, 0, NULL); } if(phonemes[0]) { lang_name = "en"; } else { SelectPhonemeTable(voice->phoneme_tab_ix); // revert to original phoneme table } } if(phonemes[0]) { if(lang_name) { SetWordStress(translator2, phonemes, flags, -1, 0); DecodePhonemes(phonemes,phonemes2); sprintf(buf,"[\002_^_%s %s _^_%s]]","en",phonemes2,WordToString2(tr->translator_name)); SelectPhonemeTable(voice->phoneme_tab_ix); // revert to original phoneme table } else { SetWordStress(tr, phonemes, flags, -1, 0); DecodePhonemes(phonemes,phonemes2); sprintf(buf,"[\002%s]] ",phonemes2); } } else if(only == 0) { strcpy(buf,"[\002(X1)(X1)(X1)]]"); } return(buf); } int Read4Bytes(FILE *f) {//==================== // Read 4 bytes (least significant first) into a word int ix; unsigned char c; int acc=0; for(ix=0; ix<4; ix++) { c = fgetc(f) & 0xff; acc += (c << (ix*8)); } return(acc); } static int LoadSoundFile(const char *fname, int index) {//=================================================== FILE *f; char *p; int *ip; int length; char fname_temp[100]; char fname2[sizeof(path_home)+13+40]; if(fname == NULL) { // filename is already in the table fname = soundicon_tab[index].filename; } if(fname==NULL) return(1); if(fname[0] != '/') { // a relative path, look in espeak-data/soundicons sprintf(fname2,"%s%csoundicons%c%s",path_home,PATHSEP,PATHSEP,fname); fname = fname2; } f = NULL; #ifdef PLATFORM_POSIX if((f = fopen(fname,"rb")) != NULL) { int ix; int fd_temp; const char *resample; int header[3]; char command[sizeof(fname2)+sizeof(fname2)+40]; fseek(f,20,SEEK_SET); for(ix=0; ix<3; ix++) header[ix] = Read4Bytes(f); // if the sound file is not mono, 16 bit signed, at the correct sample rate, then convert it if((header[0] != 0x10001) || (header[1] != samplerate) || (header[2] != samplerate*2)) { fclose(f); f = NULL; if(header[2] == samplerate) resample = ""; else resample = "polyphase"; strcpy(fname_temp,"/tmp/espeakXXXXXX"); if((fd_temp = mkstemp(fname_temp)) >= 0) { close(fd_temp); // sprintf(fname_temp,"%s.wav",tmpnam(NULL)); sprintf(command,"sox \"%s\" -r %d -w -s -c1 %s %s\n", fname, samplerate, fname_temp, resample); if(system(command) == 0) { fname = fname_temp; } } } } #endif if(f == NULL) { f = fopen(fname,"rb"); if(f == NULL) { // fprintf(stderr,"Can't read temp file: %s\n",fname); return(3); } } length = GetFileLength(fname); fseek(f,0,SEEK_SET); if((p = (char *)realloc(soundicon_tab[index].data, length)) == NULL) { fclose(f); return(4); } length = fread(p,1,length,f); fclose(f); remove(fname_temp); ip = (int *)(&p[40]); soundicon_tab[index].length = (*ip) / 2; // length in samples soundicon_tab[index].data = p; return(0); } // end of LoadSoundFile static int LookupSoundicon(int c) {//============================== // Find the sound icon number for a punctuation chatacter int ix; for(ix=N_SOUNDICON_SLOTS; ix= N_SOUNDICON_SLOTS) slot = 0; if(LoadSoundFile(fname, slot) != 0) return(-1); soundicon_tab[slot].filename = (char *)realloc(soundicon_tab[ix].filename, strlen(fname)+1); strcpy(soundicon_tab[slot].filename, fname); return(slot); } static int AnnouncePunctuation(Translator *tr, int c1, int *c2_ptr, char *output, int *bufix, int end_clause) {//========================================================================================================== // announce punctuation names // c1: the punctuation character // c2: the following character int punct_count; const char *punctname; int found = 0; int soundicon; int attributes; int short_pause; int c2; int len; int bufix1; char buf[200]; char buf2[80]; c2 = *c2_ptr; buf[0] = 0; if((soundicon = LookupSoundicon(c1)) >= 0) { // add an embedded command to play the soundicon sprintf(buf,"\001%dI ",soundicon); UngetC(c2); found = 1; } else if((punctname = LookupCharName(tr, c1, 0)) != NULL) { found = 1; if((*bufix==0) || (end_clause ==0) || (tr->langopts.param[LOPT_ANNOUNCE_PUNCT] & 2)) { punct_count=1; while((c2 == c1) && (c1 != '<')) // don't eat extra '<', it can miss XML tags { punct_count++; c2 = GetC(); } *c2_ptr = c2; if(end_clause) { UngetC(c2); } if(punct_count==1) { // sprintf(buf,"%s %s %s",tone_punct_on,punctname,tone_punct_off); sprintf(buf," %s",punctname); // we need the space before punctname, to ensure it doesn't merge with the previous word (eg. "2.-a") } else if(punct_count < 4) { buf[0] = 0; if(embedded_value[EMBED_S] < 300) sprintf(buf,"\001+10S"); // Speak punctuation name faster, unless we are already speaking fast. It would upset Sonic SpeedUp while(punct_count-- > 0) { sprintf(buf2," %s",punctname); strcat(buf, buf2); } if(embedded_value[EMBED_S] < 300) { sprintf(buf2," \001-10S"); strcat(buf, buf2); } } else { sprintf(buf," %s %d %s", punctname,punct_count,punctname); } } else { // end the clause now and pick up the punctuation next time UngetC(c2); if(option_ssml) { if((c1 == '<') || (c1 == '&')) ssml_ignore_l_angle = c1; // this was < which was converted to <, don't pick it up again as < } ungot_char2 = c1; buf[0] = ' '; buf[1] = 0; } } if(found == 0) return(-1); bufix1 = *bufix; len = strlen(buf); strcpy(&output[*bufix],buf); *bufix += len; if(end_clause==0) return(-1); if(c1 == '-') return(CLAUSE_NONE); // no pause attributes = punct_attributes[lookupwchar(punct_chars,c1)]; short_pause = CLAUSE_SHORTFALL; if((attributes & CLAUSE_BITS_INTONATION) == 0x1000) short_pause = CLAUSE_SHORTCOMMA; if((bufix1 > 0) && !(tr->langopts.param[LOPT_ANNOUNCE_PUNCT] & 2)) { if((attributes & ~0x8000) == CLAUSE_SEMICOLON) return(CLAUSE_SHORTFALL); return(short_pause); } if(attributes & CLAUSE_BIT_SENTENCE) return(attributes); return(short_pause); } // end of AnnouncePunctuation #define SSML_SPEAK 1 #define SSML_VOICE 2 #define SSML_PROSODY 3 #define SSML_SAYAS 4 #define SSML_MARK 5 #define SSML_SENTENCE 6 #define SSML_PARAGRAPH 7 #define SSML_PHONEME 8 #define SSML_SUB 9 #define SSML_STYLE 10 #define SSML_AUDIO 11 #define SSML_EMPHASIS 12 #define SSML_BREAK 13 #define SSML_IGNORE_TEXT 14 #define HTML_BREAK 15 #define HTML_NOSPACE 16 // don't insert a space for this element, so it doesn't break a word #define SSML_CLOSE 0x20 // for a closing tag, OR this with the tag type // these tags have no effect if they are self-closing, eg. static char ignore_if_self_closing[] = {0,1,1,1,1,0,0,0,0,1,1,0,1,0,1,0,0,0,0}; static MNEM_TAB ssmltags[] = { {"speak", SSML_SPEAK}, {"voice", SSML_VOICE}, {"prosody", SSML_PROSODY}, {"say-as", SSML_SAYAS}, {"mark", SSML_MARK}, {"s", SSML_SENTENCE}, {"p", SSML_PARAGRAPH}, {"phoneme", SSML_PHONEME}, {"sub", SSML_SUB}, {"tts:style", SSML_STYLE}, {"audio", SSML_AUDIO}, {"emphasis", SSML_EMPHASIS}, {"break", SSML_BREAK}, {"metadata", SSML_IGNORE_TEXT}, {"br", HTML_BREAK}, {"li", HTML_BREAK}, {"dd", HTML_BREAK}, {"img", HTML_BREAK}, {"td", HTML_BREAK}, {"h1", SSML_PARAGRAPH}, {"h2", SSML_PARAGRAPH}, {"h3", SSML_PARAGRAPH}, {"h4", SSML_PARAGRAPH}, {"hr", SSML_PARAGRAPH}, {"script", SSML_IGNORE_TEXT}, {"style", SSML_IGNORE_TEXT}, {"font", HTML_NOSPACE}, {"b", HTML_NOSPACE}, {"i", HTML_NOSPACE}, {"strong", HTML_NOSPACE}, {"em", HTML_NOSPACE}, {"code", HTML_NOSPACE}, {NULL,0}}; static const char *VoiceFromStack() {//================================ // Use the voice properties from the SSML stack to choose a voice, and switch // to that voice if it's not the current voice int ix; const char *p; SSML_STACK *sp; const char *v_id; int voice_name_specified; int voice_found; espeak_VOICE voice_select; static char voice_name[40]; char language[40]; char buf[80]; strcpy(voice_name,ssml_stack[0].voice_name); strcpy(language,ssml_stack[0].language); voice_select.age = ssml_stack[0].voice_age; voice_select.gender = ssml_stack[0].voice_gender; voice_select.variant = ssml_stack[0].voice_variant_number; voice_select.identifier = NULL; for(ix=0; ixvoice_name[0] != 0) && (SelectVoiceByName(NULL,sp->voice_name) != NULL)) { voice_name_specified = 1; strcpy(voice_name, sp->voice_name); language[0] = 0; voice_select.gender = 0; voice_select.age = 0; voice_select.variant = 0; } if(sp->language[0] != 0) { strcpy(language, sp->language); // is this language provided by the base voice? p = base_voice.languages; while(*p++ != 0) { if(strcmp(p, language) == 0) { // yes, change the language to the main language of the base voice strcpy(language, &base_voice.languages[1]); break; } p += (strlen(p) + 1); } if(voice_name_specified == 0) voice_name[0] = 0; // forget a previous voice name if a language is specified } if(sp->voice_gender != 0) { voice_select.gender = sp->voice_gender; } if(sp->voice_age != 0) voice_select.age = sp->voice_age; if(sp->voice_variant_number != 0) voice_select.variant = sp->voice_variant_number; } voice_select.name = voice_name; voice_select.languages = language; v_id = SelectVoice(&voice_select, &voice_found); if(v_id == NULL) return("default"); if((strchr(v_id, '+') == NULL) && ((voice_select.gender == 0) || (voice_select.gender == base_voice.gender)) && (base_voice_variant_name[0] != 0)) { // a voice variant has not been selected, use the original voice variant sprintf(buf, "%s+%s", v_id, base_voice_variant_name); strncpy0(voice_name, buf, sizeof(voice_name)); return(voice_name); } return(v_id); } // end of VoiceFromStack static void ProcessParamStack(char *outbuf, int &outix) {//==================================================== // Set the speech parameters from the parameter stack int param; int ix; int value; char buf[20]; int new_parameters[N_SPEECH_PARAM]; static char cmd_letter[N_SPEECH_PARAM] = {0, 'S','A','P','R', 0, 'C', 0, 0, 0, 0, 0, 'F'}; // embedded command letters for(param=0; param= 0) new_parameters[param] = param_stack[ix].parameter[param]; } } for(param=0; paramtype = tag_type; for(ix=0; ixparameter[ix] = -1; } return(sp); } // end of PushParamStack static void PopParamStack(int tag_type, char *outbuf, int &outix) {//============================================================== // unwind the stack up to and including the previous tag of this type int ix; int top = 0; if(tag_type >= SSML_CLOSE) tag_type -= SSML_CLOSE; for(ix=0; ix 0) { n_param_stack = top; } ProcessParamStack(outbuf, outix); } // end of PopParamStack static wchar_t *GetSsmlAttribute(wchar_t *pw, const char *name) {//============================================================ // Gets the value string for an attribute. // Returns NULL if the attribute is not present int ix; static wchar_t empty[1] = {0}; while(*pw != 0) { if(iswspace(pw[-1])) { ix = 0; while(*pw == name[ix]) { pw++; ix++; } if(name[ix]==0) { // found the attribute, now get the value while(iswspace(*pw)) pw++; if(*pw == '=') pw++; while(iswspace(*pw)) pw++; if((*pw == '"') || (*pw == '\'')) // allow single-quotes ? return(pw+1); else return(empty); } } pw++; } return(NULL); } // end of GetSsmlAttribute static int attrcmp(const wchar_t *string1, const char *string2) {//============================================================ int ix; if(string1 == NULL) return(1); for(ix=0; (string1[ix] == string2[ix]) && (string1[ix] != 0); ix++) { } if(((string1[ix]=='"') || (string1[ix]=='\'')) && (string2[ix]==0)) return(0); return(1); } static int attrlookup(const wchar_t *string1, const MNEM_TAB *mtab) {//================================================================ int ix; for(ix=0; mtab[ix].mnem != NULL; ix++) { if(attrcmp(string1,mtab[ix].mnem) == 0) return(mtab[ix].value); } return(mtab[ix].value); } static int attrnumber(const wchar_t *pw, int default_value, int type) {//================================================================== int value = 0; if((pw == NULL) || !isdigit(*pw)) return(default_value); while(isdigit(*pw)) { value = value*10 + *pw++ - '0'; } if((type==1) && (towlower(*pw)=='s')) { // time: seconds rather than ms value *= 1000; } return(value); } // end of attrnumber static int attrcopy_utf8(char *buf, const wchar_t *pw, int len) {//============================================================ // Convert attribute string into utf8, write to buf, and return its utf8 length unsigned int c; int ix = 0; int n; int prev_c = 0; if(pw != NULL) { while((ix < (len-4)) && ((c = *pw++) != 0)) { if((c=='"') && (prev_c != '\\')) break; // " indicates end of attribute, unless preceded by backstroke n = utf8_out(c,&buf[ix]); ix += n; prev_c = c; } } buf[ix] = 0; return(ix); } // end of attrcopy_utf8 static int attr_prosody_value(int param_type, const wchar_t *pw, int *value_out) {//============================================================================= int sign = 0; wchar_t *tail; double value; while(iswspace(*pw)) pw++; if(*pw == '+') { pw++; sign = 1; } if(*pw == '-') { pw++; sign = -1; } value = (double)wcstod(pw,&tail); if(tail == pw) { // failed to find a number, return 100% *value_out = 100; return(2); } if(*tail == '%') { if(sign != 0) value = 100 + (sign * value); *value_out = (int)value; return(2); // percentage } if((tail[0]=='s') && (tail[1]=='t')) { double x; // convert from semitones to a frequency percentage x = pow(double(2.0),double((value*sign)/12)) * 100; *value_out = (int)x; return(2); // percentage } if(param_type == espeakRATE) { if(sign == 0) *value_out = (int)(value * 100); else *value_out = 100 + (int)(sign * value * 100); return(2); // percentage } *value_out = (int)value; return(sign); // -1, 0, or 1 } // end of attr_prosody_value int AddNameData(const char *name, int wide) {//======================================== // Add the name to the namedata and return its position // (Used by the Windows SAPI wrapper) int ix; int len; void *vp; if(wide) { len = (wcslen((const wchar_t *)name)+1)*sizeof(wchar_t); n_namedata = (n_namedata + sizeof(wchar_t) - 1) % sizeof(wchar_t); // round to wchar_t boundary } else { len = strlen(name)+1; } if(namedata_ix+len >= n_namedata) { // allocate more space for marker names if((vp = realloc(namedata, namedata_ix+len + 1000)) == NULL) return(-1); // failed to allocate, original data is unchanged but ignore this new name // !!! Bug?? If the allocated data shifts position, then pointers given to user application will be invalid namedata = (char *)vp; n_namedata = namedata_ix+len + 1000; } memcpy(&namedata[ix = namedata_ix],name,len); namedata_ix += len; return(ix); } // end of AddNameData void SetVoiceStack(espeak_VOICE *v, const char *variant_name) {//========================================================== SSML_STACK *sp; sp = &ssml_stack[0]; if(v == NULL) { memset(sp,0,sizeof(ssml_stack[0])); return; } if(v->languages != NULL) strcpy(sp->language,v->languages); if(v->name != NULL) strncpy0(sp->voice_name, v->name, sizeof(sp->voice_name)); sp->voice_variant_number = v->variant; sp->voice_age = v->age; sp->voice_gender = v->gender; if(memcmp(variant_name, "!v", 2) == 0) variant_name += 3;// strip variant directory name, !v plus PATHSEP strncpy0(base_voice_variant_name, variant_name, sizeof(base_voice_variant_name)); memcpy(&base_voice, ¤t_voice_selected, sizeof(base_voice)); } static int GetVoiceAttributes(wchar_t *pw, int tag_type) {//===================================================== // Determines whether voice attribute are specified in this tag, and if so, whether this means // a voice change. // If it's a closing tag, delete the top frame of the stack and determine whether this implies // a voice change. // Returns CLAUSE_BIT_VOICE if there is a voice change wchar_t *lang; wchar_t *gender; wchar_t *name; wchar_t *age; wchar_t *variant; const char *new_voice_id; SSML_STACK *ssml_sp; static const MNEM_TAB mnem_gender[] = { {"male", 1}, {"female", 2}, {"neutral", 3}, {NULL, 0}}; if(tag_type & SSML_CLOSE) { // delete a stack frame if(n_ssml_stack > 1) { n_ssml_stack--; } } else { // add a stack frame if any voice details are specified lang = GetSsmlAttribute(pw,"xml:lang"); if(tag_type != SSML_VOICE) { // only expect an xml:lang attribute name = NULL; variant = NULL; age = NULL; gender = NULL; } else { name = GetSsmlAttribute(pw,"name"); variant = GetSsmlAttribute(pw,"variant"); age = GetSsmlAttribute(pw,"age"); gender = GetSsmlAttribute(pw,"gender"); } if((tag_type != SSML_VOICE) && (lang==NULL)) return(0); // or

without language spec, nothing to do ssml_sp = &ssml_stack[n_ssml_stack++]; attrcopy_utf8(ssml_sp->language,lang,sizeof(ssml_sp->language)); attrcopy_utf8(ssml_sp->voice_name,name,sizeof(ssml_sp->voice_name)); ssml_sp->voice_variant_number = attrnumber(variant,1,0)-1; ssml_sp->voice_age = attrnumber(age,0,0); ssml_sp->voice_gender = attrlookup(gender,mnem_gender); ssml_sp->tag_type = tag_type; } new_voice_id = VoiceFromStack(); if(strcmp(new_voice_id,current_voice_id) != 0) { // add an embedded command to change the voice strcpy(current_voice_id,new_voice_id); return(CLAUSE_BIT_VOICE); // change of voice } return(0); } // end of GetVoiceAttributes static void SetProsodyParameter(int param_type, wchar_t *attr1, PARAM_STACK *sp) {//============================================================================= int value; int sign; static const MNEM_TAB mnem_volume[] = { {"default",100}, {"silent",0}, {"x-soft",30}, {"soft",65}, {"medium",100}, {"loud",150}, {"x-loud",230}, {NULL, -1}}; static const MNEM_TAB mnem_rate[] = { {"default",100}, {"x-slow",60}, {"slow",80}, {"medium",100}, {"fast",125}, {"x-fast",160}, {NULL, -1}}; static const MNEM_TAB mnem_pitch[] = { {"default",100}, {"x-low",70}, {"low",85}, {"medium",100}, {"high",110}, {"x-high",120}, {NULL, -1}}; static const MNEM_TAB mnem_range[] = { {"default",100}, {"x-low",20}, {"low",50}, {"medium",100}, {"high",140}, {"x-high",180}, {NULL, -1}}; static const MNEM_TAB *mnem_tabs[5] = { NULL, mnem_rate, mnem_volume, mnem_pitch, mnem_range }; if((value = attrlookup(attr1,mnem_tabs[param_type])) >= 0) { // mnemonic specifies a value as a percentage of the base pitch/range/rate/volume sp->parameter[param_type] = (param_stack[0].parameter[param_type] * value)/100; } else { sign = attr_prosody_value(param_type,attr1,&value); if(sign == 0) sp->parameter[param_type] = value; // absolute value in Hz else if(sign == 2) { // change specified as percentage or in semitones sp->parameter[param_type] = (speech_parameters[param_type] * value)/100; } else { // change specified as plus or minus Hz sp->parameter[param_type] = speech_parameters[param_type] + (value*sign); } } } // end of SetProsodyParemeter static int ReplaceKeyName(char *outbuf, int index, int &outix) {//=========================================================== // Replace some key-names by single characters, so they can be pronounced in different languages static MNEM_TAB keynames[] = { {"space ",0xe020}, {"tab ", 0xe009}, {"underscore ", 0xe05f}, {"double-quote ", '"'}, {NULL, 0}}; int ix; int letter; char *p; p = &outbuf[index]; if((letter = LookupMnem(keynames, p)) != 0) { ix = utf8_out(letter, p); outix = index + ix; return(letter); } return(0); } static int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int &outix, int n_outbuf, int self_closing) {//================================================================================================== // xml_buf is the tag and attributes with a zero terminator in place of the original '>' // returns a clause terminator value. unsigned int ix; int index; int c; int tag_type; int value; int value2; int value3; int voice_change_flag; wchar_t *px; wchar_t *attr1; wchar_t *attr2; wchar_t *attr3; int terminator; char *uri; int param_type; char tag_name[40]; char buf[80]; PARAM_STACK *sp; SSML_STACK *ssml_sp; static const MNEM_TAB mnem_punct[] = { {"none", 1}, {"all", 2}, {"some", 3}, {NULL, -1}}; static const MNEM_TAB mnem_capitals[] = { {"no", 0}, {"spelling", 2}, {"icon", 1}, {"pitch", 20}, // this is the amount by which to raise the pitch {NULL, -1}}; static const MNEM_TAB mnem_interpret_as[] = { {"characters",SAYAS_CHARS}, {"tts:char",SAYAS_SINGLE_CHARS}, {"tts:key",SAYAS_KEY}, {"tts:digits",SAYAS_DIGITS}, {"telephone",SAYAS_DIGITS1}, {NULL, -1}}; static const MNEM_TAB mnem_sayas_format[] = { {"glyphs",1}, {NULL, -1}}; static const MNEM_TAB mnem_break[] = { {"none",0}, {"x-weak",1}, {"weak",2}, {"medium",3}, {"strong",4}, {"x-strong",5}, {NULL,-1}}; static const MNEM_TAB mnem_emphasis[] = { {"none",1}, {"reduced",2}, {"moderate",3}, {"strong",4}, {"x-strong",5}, {NULL,-1}}; static const char *prosody_attr[5] = { NULL, "rate", "volume", "pitch", "range" }; for(ix=0; ix<(sizeof(tag_name)-1); ix++) { if(((c = xml_buf[ix]) == 0) || iswspace(c)) break; tag_name[ix] = tolower((char)c); } tag_name[ix] = 0; px = &xml_buf[ix]; // the tag's attributes if(tag_name[0] == '/') { // closing tag if((tag_type = LookupMnem(ssmltags,&tag_name[1])) != HTML_NOSPACE) { outbuf[outix++] = ' '; } tag_type += SSML_CLOSE; } else { if((tag_type = LookupMnem(ssmltags,tag_name)) != HTML_NOSPACE) { // separate SSML tags from the previous word (but not HMTL tags such as which can occur inside a word) outbuf[outix++] = ' '; } if(self_closing && ignore_if_self_closing[tag_type]) return(0); } voice_change_flag = 0; terminator = CLAUSE_NONE; ssml_sp = &ssml_stack[n_ssml_stack-1]; switch(tag_type) { case SSML_STYLE: sp = PushParamStack(tag_type); attr1 = GetSsmlAttribute(px,"field"); attr2 = GetSsmlAttribute(px,"mode"); if(attrcmp(attr1,"punctuation")==0) { value = attrlookup(attr2,mnem_punct); sp->parameter[espeakPUNCTUATION] = value; } else if(attrcmp(attr1,"capital_letters")==0) { value = attrlookup(attr2,mnem_capitals); sp->parameter[espeakCAPITALS] = value; } ProcessParamStack(outbuf, outix); break; case SSML_PROSODY: sp = PushParamStack(tag_type); // look for attributes: rate, volume, pitch, range for(param_type=espeakRATE; param_type <= espeakRANGE; param_type++) { if((attr1 = GetSsmlAttribute(px,prosody_attr[param_type])) != NULL) { SetProsodyParameter(param_type, attr1, sp); } } ProcessParamStack(outbuf, outix); break; case SSML_EMPHASIS: sp = PushParamStack(tag_type); value = 3; // default is "moderate" if((attr1 = GetSsmlAttribute(px,"level")) != NULL) { value = attrlookup(attr1,mnem_emphasis); } if(translator->langopts.tone_language == 1) { static unsigned char emphasis_to_pitch_range[] = {50,50,40,70,90,100}; static unsigned char emphasis_to_volume[] = {100,100,70,110,135,150}; // tone language (eg.Chinese) do emphasis by increasing the pitch range. sp->parameter[espeakRANGE] = emphasis_to_pitch_range[value]; sp->parameter[espeakVOLUME] = emphasis_to_volume[value]; } else { static unsigned char emphasis_to_volume2[] = {100,100,75,100,120,150}; sp->parameter[espeakVOLUME] = emphasis_to_volume2[value]; sp->parameter[espeakEMPHASIS] = value; } ProcessParamStack(outbuf, outix); break; case SSML_STYLE + SSML_CLOSE: case SSML_PROSODY + SSML_CLOSE: case SSML_EMPHASIS + SSML_CLOSE: PopParamStack(tag_type, outbuf, outix); break; case SSML_SAYAS: attr1 = GetSsmlAttribute(px,"interpret-as"); attr2 = GetSsmlAttribute(px,"format"); attr3 = GetSsmlAttribute(px,"detail"); value = attrlookup(attr1,mnem_interpret_as); value2 = attrlookup(attr2,mnem_sayas_format); if(value2 == 1) value = SAYAS_GLYPHS; value3 = attrnumber(attr3,0,0); if(value == SAYAS_DIGITS) { if(value3 <= 1) value = SAYAS_DIGITS1; else value = SAYAS_DIGITS + value3; } sprintf(buf,"%c%dY",CTRL_EMBEDDED,value); strcpy(&outbuf[outix],buf); outix += strlen(buf); sayas_start = outix; sayas_mode = value; // punctuation doesn't end clause during SAY-AS break; case SSML_SAYAS + SSML_CLOSE: if(sayas_mode == SAYAS_KEY) { outbuf[outix] = 0; ReplaceKeyName(outbuf, sayas_start, outix); } outbuf[outix++] = CTRL_EMBEDDED; outbuf[outix++] = 'Y'; sayas_mode = 0; break; case SSML_SUB: if((attr1 = GetSsmlAttribute(px,"alias")) != NULL) { // use the alias rather than the text ignore_text = 1; outix += attrcopy_utf8(&outbuf[outix],attr1,n_outbuf-outix); } break; case SSML_IGNORE_TEXT: ignore_text = 1; break; case SSML_SUB + SSML_CLOSE: case SSML_IGNORE_TEXT + SSML_CLOSE: ignore_text = 0; break; case SSML_MARK: if((attr1 = GetSsmlAttribute(px,"name")) != NULL) { // add name to circular buffer of marker names attrcopy_utf8(buf,attr1,sizeof(buf)); if(strcmp(skip_marker,buf)==0) { // This is the marker we are waiting for before starting to speak clear_skipping_text = 1; skip_marker[0] = 0; return(CLAUSE_NONE); } if((index = AddNameData(buf,0)) >= 0) { sprintf(buf,"%c%dM",CTRL_EMBEDDED,index); strcpy(&outbuf[outix],buf); outix += strlen(buf); } } break; case SSML_AUDIO: sp = PushParamStack(tag_type); if((attr1 = GetSsmlAttribute(px,"src")) != NULL) { char fname[256]; attrcopy_utf8(buf,attr1,sizeof(buf)); if(uri_callback == NULL) { if((xmlbase != NULL) && (buf[0] != '/')) { sprintf(fname,"%s/%s",xmlbase,buf); index = LoadSoundFile2(fname); } else { index = LoadSoundFile2(buf); } if(index >= 0) { sprintf(buf,"%c%dI",CTRL_EMBEDDED,index); strcpy(&outbuf[outix],buf); outix += strlen(buf); sp->parameter[espeakSILENCE] = 1; } } else { if((index = AddNameData(buf,0)) >= 0) { uri = &namedata[index]; if(uri_callback(1,uri,xmlbase) == 0) { sprintf(buf,"%c%dU",CTRL_EMBEDDED,index); strcpy(&outbuf[outix],buf); outix += strlen(buf); sp->parameter[espeakSILENCE] = 1; } } } } ProcessParamStack(outbuf, outix); if(self_closing) PopParamStack(tag_type, outbuf, outix); else audio_text = 1; return(CLAUSE_NONE); case SSML_AUDIO + SSML_CLOSE: PopParamStack(tag_type, outbuf, outix); audio_text = 0; return(CLAUSE_NONE); case SSML_BREAK: value = 21; terminator = CLAUSE_NONE; if((attr1 = GetSsmlAttribute(px,"strength")) != NULL) { static int break_value[6] = {0,7,14,21,40,80}; // *10mS value = attrlookup(attr1,mnem_break); if(value < 3) { // adjust prepause on the following word sprintf(&outbuf[outix],"%c%dB",CTRL_EMBEDDED,value); outix += 3; terminator = 0; } value = break_value[value]; } if((attr2 = GetSsmlAttribute(px,"time")) != NULL) { value = (attrnumber(attr2,0,1) * 25) / speed.pause_factor; // compensate for speaking speed to keep constant pause length if(terminator == 0) terminator = CLAUSE_NONE; } if(terminator) { if(value > 0xfff) value = 0xfff; return(terminator + value); } break; case SSML_SPEAK: if((attr1 = GetSsmlAttribute(px,"xml:base")) != NULL) { attrcopy_utf8(buf,attr1,sizeof(buf)); if((index = AddNameData(buf,0)) >= 0) { xmlbase = &namedata[index]; } } if(GetVoiceAttributes(px, tag_type) == 0) return(0); // no voice change return(CLAUSE_VOICE); case SSML_VOICE: if(GetVoiceAttributes(px, tag_type) == 0) return(0); // no voice change return(CLAUSE_VOICE); case SSML_SPEAK + SSML_CLOSE: // unwind stack until the previous or tag while((n_ssml_stack > 1) && (ssml_stack[n_ssml_stack-1].tag_type != SSML_SPEAK)) { n_ssml_stack--; } return(CLAUSE_PERIOD + GetVoiceAttributes(px, tag_type)); case SSML_VOICE + SSML_CLOSE: // unwind stack until the previous or tag while((n_ssml_stack > 1) && (ssml_stack[n_ssml_stack-1].tag_type != SSML_VOICE)) { n_ssml_stack--; } terminator=0; // ?? Sentence intonation, but no pause ?? return(terminator + GetVoiceAttributes(px, tag_type)); case HTML_BREAK: case HTML_BREAK + SSML_CLOSE: return(CLAUSE_COLON); case SSML_SENTENCE: if(ssml_sp->tag_type == SSML_SENTENCE) { // new sentence implies end-of-sentence voice_change_flag = GetVoiceAttributes(px, SSML_SENTENCE+SSML_CLOSE); } voice_change_flag |= GetVoiceAttributes(px, tag_type); return(CLAUSE_PARAGRAPH + voice_change_flag); case SSML_PARAGRAPH: if(ssml_sp->tag_type == SSML_SENTENCE) { // new paragraph implies end-of-sentence or end-of-paragraph voice_change_flag = GetVoiceAttributes(px, SSML_SENTENCE+SSML_CLOSE); } if(ssml_sp->tag_type == SSML_PARAGRAPH) { // new paragraph implies end-of-sentence or end-of-paragraph voice_change_flag |= GetVoiceAttributes(px, SSML_PARAGRAPH+SSML_CLOSE); } voice_change_flag |= GetVoiceAttributes(px, tag_type); return(CLAUSE_PARAGRAPH + voice_change_flag); case SSML_SENTENCE + SSML_CLOSE: if(ssml_sp->tag_type == SSML_SENTENCE) { // end of a sentence which specified a language voice_change_flag = GetVoiceAttributes(px, tag_type); } return(CLAUSE_PERIOD + voice_change_flag); case SSML_PARAGRAPH + SSML_CLOSE: if((ssml_sp->tag_type == SSML_SENTENCE) || (ssml_sp->tag_type == SSML_PARAGRAPH)) { // End of a paragraph which specified a language. // (End-of-paragraph also implies end-of-sentence) return(GetVoiceAttributes(px, tag_type) + CLAUSE_PARAGRAPH); } return(CLAUSE_PARAGRAPH); } return(0); } // end of ProcessSsmlTag static void RemoveChar(char *p) {//======================= // Replace a UTF-8 character by spaces int c; memset(p, ' ', utf8_in(&c, p)); } // end of RemoveChar static MNEM_TAB xml_char_mnemonics[] = { {"gt",'>'}, {"lt", 0xe000 + '<'}, // private usage area, to avoid confusion with XML tag {"amp", '&'}, {"quot", '"'}, {"nbsp", ' '}, {"apos", '\''}, {NULL,-1}}; int ReadClause(Translator *tr, FILE *f_in, char *buf, short *charix, int *charix_top, int n_buf, int *tone_type, char *voice_change) {//================================================================================================================================= /* Find the end of the current clause. Write the clause into buf returns: clause type (bits 0-7: pause x10mS, bits 8-11 intonation type) Also checks for blank line (paragraph) as end-of-clause indicator. Does not end clause for: punctuation immediately followed by alphanumeric eg. 1.23 !Speak :path repeated punctuation, eg. ... !!! */ int c1=' '; // current character int c2; // next character int cprev=' '; // previous character int cprev2=' '; int c_next; int parag; int ix = 0; int j; int nl_count; int linelength = 0; int phoneme_mode = 0; int n_xml_buf; int terminator; int punct; int found; int any_alnum = 0; int self_closing; int punct_data = 0; int is_end_clause; int announced_punctuation = 0; int stressed_word = 0; int end_clause_after_tag = 0; int end_clause_index = 0; wchar_t xml_buf[N_XML_BUF+1]; #define N_XML_BUF2 20 char xml_buf2[N_XML_BUF2+2]; // for & and & sequences static char ungot_string[N_XML_BUF2+4]; static int ungot_string_ix = -1; if(clear_skipping_text) { skipping_text = 0; clear_skipping_text = 0; } tr->phonemes_repeat_count = 0; tr->clause_upper_count = 0; tr->clause_lower_count = 0; end_of_input = 0; *tone_type = 0; *voice_change = 0; f_input = f_in; // for GetC etc if(ungot_word != NULL) { strcpy(buf,ungot_word); ix += strlen(ungot_word); ungot_word = NULL; } if(ungot_char2 != 0) { c2 = ungot_char2; } else { c2 = GetC(); } while(!Eof() || (ungot_char != 0) || (ungot_char2 != 0) || (ungot_string_ix >= 0)) { if(!iswalnum(c1)) { if((end_character_position > 0) && (count_characters > end_character_position)) { end_of_input = 1; return(CLAUSE_EOF); } if((skip_characters > 0) && (count_characters > skip_characters)) { // reached the specified start position // don't break a word clear_skipping_text = 1; skip_characters = 0; UngetC(c2); return(CLAUSE_NONE); } } cprev2 = cprev; cprev = c1; c1 = c2; if(ungot_string_ix >= 0) { if(ungot_string[ungot_string_ix] == 0) ungot_string_ix = -1; } if((ungot_string_ix == 0) && (ungot_char2 == 0)) { c1 = ungot_string[ungot_string_ix++]; } if(ungot_string_ix >= 0) { c2 = ungot_string[ungot_string_ix++]; } else { c2 = GetC(); if(Eof()) { c2 = ' '; } } ungot_char2 = 0; if((option_ssml) && (phoneme_mode==0)) { if((ssml_ignore_l_angle != '&') && (c1 == '&') && ((c2=='#') || ((c2 >= 'a') && (c2 <= 'z')))) { n_xml_buf = 0; c1 = c2; while(!Eof() && (iswalnum(c1) || (c1=='#')) && (n_xml_buf < N_XML_BUF2)) { xml_buf2[n_xml_buf++] = c1; c1 = GetC(); } xml_buf2[n_xml_buf] = 0; c2 = GetC(); sprintf(ungot_string,"%s%c%c",&xml_buf2[0],c1,c2); if(c1 == ';') { if(xml_buf2[0] == '#') { // character code number if(xml_buf2[1] == 'x') found = sscanf(&xml_buf2[2],"%x",(unsigned int *)(&c1)); else found = sscanf(&xml_buf2[1],"%d",&c1); } else { if((found = LookupMnem(xml_char_mnemonics,xml_buf2)) != -1) { c1 = found; if(c2 == 0) c2 = ' '; } } } else { found = -1; } if(found <= 0) { ungot_string_ix = 0; c1 = '&'; c2 = ' '; } if((c1 <= 0x20) && ((sayas_mode == SAYAS_SINGLE_CHARS) || (sayas_mode == SAYAS_KEY))) { c1 += 0xe000; // move into unicode private usage area } } else if((c1 == '<') && (ssml_ignore_l_angle != '<')) { if(c2 == '!') { // a comment, ignore until closing '<' while(!Eof() && (c1 != '>')) { c1 = GetC(); } c2 = ' '; } else if((c2 == '/') || iswalpha(c2)) { // check for space in the output buffer for embedded commands produced by the SSML tag if(ix > (n_buf - 20)) { // Perhaps not enough room, end the clause before the SSML tag UngetC(c2); ungot_char2 = c1; buf[ix] = ' '; buf[ix+1] = 0; return(CLAUSE_NONE); } // SSML Tag n_xml_buf = 0; c1 = c2; while(!Eof() && (c1 != '>') && (n_xml_buf < N_XML_BUF)) { xml_buf[n_xml_buf++] = c1; c1 = GetC(); } xml_buf[n_xml_buf] = 0; c2 = ' '; self_closing = 0; if(xml_buf[n_xml_buf-1] == '/') { // a self-closing tag xml_buf[n_xml_buf-1] = ' '; self_closing = 1; } terminator = ProcessSsmlTag(xml_buf,buf,ix,n_buf,self_closing); if(terminator != 0) { if(end_clause_after_tag) ix = end_clause_index; buf[ix] = ' '; buf[ix++] = 0; if(terminator & CLAUSE_BIT_VOICE) { strcpy(voice_change, current_voice_id); } return(terminator); } c1 = ' '; c2 = GetC(); continue; } } } ssml_ignore_l_angle=0; if(ignore_text) continue; if((c2=='\n') && (option_linelength == -1)) { // single-line mode, return immediately on NL if((punct = lookupwchar(punct_chars,c1)) == 0) { charix[ix] = count_characters - clause_start_char; *charix_top = ix; ix += utf8_out(c1,&buf[ix]); terminator = CLAUSE_PERIOD; // line doesn't end in punctuation, assume period } else { terminator = punct_attributes[punct]; } buf[ix] = ' '; buf[ix+1] = 0; return(terminator); } if((c1 == CTRL_EMBEDDED) || (c1 == ctrl_embedded)) { // an embedded command. If it's a voice change, end the clause if(c2 == 'V') { buf[ix++] = 0; // end the clause at this point while(!iswspace(c1 = GetC()) && !Eof() && (ix < (n_buf-1))) buf[ix++] = c1; // add voice name to end of buffer, after the text buf[ix++] = 0; return(CLAUSE_VOICE); } else if(c2 == 'B') { // set the punctuation option from an embedded command // B0 B1 B strcpy(&buf[ix]," "); ix += 3; if((c2 = GetC()) == '0') option_punctuation = 0; else { option_punctuation = 1; option_punctlist[0] = 0; if(c2 != '1') { // a list of punctuation characters to be spoken, terminated by space j = 0; while(!iswspace(c2) && !Eof()) { option_punctlist[j++] = c2; c2 = GetC(); buf[ix++] = ' '; } option_punctlist[j] = 0; // terminate punctuation list option_punctuation = 2; } } c2 = GetC(); continue; } } linelength++; if(iswalnum(c1)) any_alnum = 1; else { if(stressed_word) { stressed_word = 0; c1 = CHAR_EMPHASIS; // indicate this word is stressed UngetC(c2); c2 = ' '; } if((j = lookupwchar2(tr->chars_ignore,c1)) != 0) { if(j == 1) { // ignore this character (eg. zero-width-non-joiner U+200C) continue; } c1 = j; // replace the character } if(c1 == 0xf0b) c1 = ' '; // Tibet inter-syllabic mark, ?? replace by space ?? if(iswspace(c1)) { char *p_word; if(tr->translator_name == 0x6a626f) { // language jbo : lojban // treat "i" or ".i" as end-of-sentence p_word = &buf[ix-1]; if(p_word[0] == 'i') { if(p_word[-1] == '.') p_word--; if(p_word[-1] == ' ') { ungot_word = "i "; UngetC(c2); p_word[0] = 0; return(CLAUSE_PERIOD); } } } } if(c1 == 0xd4d) { // Malayalam virama, check if next character is Zero-width-joiner if(c2 == 0x200d) { c1 = 0xd4e; // use this unofficial code for chillu-virama } } } if(iswupper(c1)) { tr->clause_upper_count++; if((option_capitals == 2) && (sayas_mode == 0) && !iswupper(cprev)) { char text_buf[40]; char text_buf2[30]; if(LookupSpecial(tr, "_cap", text_buf2) != NULL) { sprintf(text_buf,"%s",text_buf2); j = strlen(text_buf); if((ix + j) < n_buf) { strcpy(&buf[ix],text_buf); ix += j; } } } } else if(iswalpha(c1)) tr->clause_lower_count++; if(option_phoneme_input) { if(phoneme_mode > 0) phoneme_mode--; else if((c1 == '[') && (c2 == '[')) phoneme_mode = -1; // input is phoneme mnemonics, so don't look for punctuation else if((c1 == ']') && (c2 == ']')) phoneme_mode = 2; // set phoneme_mode to zero after the next two characters } if(c1 == '\n') { parag = 0; // count consecutive newlines, ignoring other spaces while(!Eof() && iswspace(c2)) { if(c2 == '\n') parag++; c2 = GetC(); } if(parag > 0) { // 2nd newline, assume paragraph UngetC(c2); if(end_clause_after_tag) { RemoveChar(&buf[end_clause_index]); // delete clause-end punctiation } buf[ix] = ' '; buf[ix+1] = 0; if(parag > 3) parag = 3; if(option_ssml) parag=1; return((CLAUSE_PARAGRAPH-30) + 30*parag); // several blank lines, longer pause } if(linelength <= option_linelength) { // treat lines shorter than a specified length as end-of-clause UngetC(c2); buf[ix] = ' '; buf[ix+1] = 0; return(CLAUSE_COLON); } linelength = 0; } announced_punctuation = 0; if((phoneme_mode==0) && (sayas_mode==0)) { is_end_clause = 0; if(end_clause_after_tag) { // Because of an xml tag, we are waiting for the // next non-blank character to decide whether to end the clause // i.e. is dot followed by an upper-case letter? if(!iswspace(c1)) { if(!IsAlpha(c1) || !iswlower(c1)) // if(iswdigit(c1) || (IsAlpha(c1) && !iswlower(c1))) { UngetC(c2); ungot_char2 = c1; buf[end_clause_index] = ' '; // delete the end-clause punctuation buf[end_clause_index+1] = 0; return(end_clause_after_tag); } end_clause_after_tag = 0; } } if((c1 == '.') && (c2 == '.')) { while((c_next = GetC()) == '.') { // 3 or more dots, replace by elipsis c1 = 0x2026; c2 = ' '; } if(c1 == 0x2026) c2 = c_next; else UngetC(c_next); } punct_data = 0; if((punct = lookupwchar(punct_chars,c1)) != 0) { punct_data = punct_attributes[punct]; if(punct_data & PUNCT_IN_WORD) { // Armenian punctuation inside a word stressed_word = 1; *tone_type = punct_data >> 12 & 0xf; // override the end-of-sentence type continue; } if((iswspace(c2) || (punct_data & 0x8000) || IsBracket(c2) || (c2=='?') || Eof() || (c2 == ctrl_embedded))) // don't check for '-' because it prevents recognizing ':-)' // if((iswspace(c2) || (punct_data & 0x8000) || IsBracket(c2) || (c2=='?') || (c2=='-') || Eof())) { // note: (c2='?') is for when a smart-quote has been replaced by '?' is_end_clause = 1; } } // don't announce punctuation for the alternative text inside inside if(c1 == 0xe000+'<') c1 = '<'; if(option_punctuation && iswpunct(c1) && (audio_text == 0)) { // option is set to explicitly speak punctuation characters // if a list of allowed punctuation has been set up, check whether the character is in it if((option_punctuation == 1) || (wcschr(option_punctlist,c1) != NULL)) { tr->phonemes_repeat_count = 0; if((terminator = AnnouncePunctuation(tr, c1, &c2, buf, &ix, is_end_clause)) >= 0) return(terminator); announced_punctuation = c1; } } if((punct_data & PUNCT_SAY_NAME) && (announced_punctuation == 0)) { // used for elipsis (and 3 dots) if a pronunciation for elipsis is given in *_list char *p2; p2 = &buf[ix]; sprintf(p2,"%s",LookupCharName(tr, c1, 1)); if(p2[0] != 0) { ix += strlen(p2); announced_punctuation = c1; punct_data = punct_data & ~CLAUSE_BITS_INTONATION; // change intonation type to 0 (full-stop) } } if(is_end_clause) { nl_count = 0; c_next = c2; if(iswspace(c_next)) { while(!Eof() && iswspace(c_next)) { if(c_next == '\n') nl_count++; c_next = GetC(); // skip past space(s) } } if((c1 == '.') && (nl_count < 2)) { punct_data |= CLAUSE_DOT; } if(nl_count==0) { if((c1 == ',') && (cprev == '.') && (tr->translator_name == L('h','u')) && iswdigit(cprev2) && (iswdigit(c_next) || (iswlower(c_next)))) { // lang=hu, fix for ordinal numbers, eg: "december 2., szerda", ignore ',' after ordinal number c1 = CHAR_COMMA_BREAK; is_end_clause = 0; } if(c1 == '.') { if((tr->langopts.numbers & NUM_ORDINAL_DOT) && (iswdigit(cprev) || (IsRomanU(cprev) && (IsRomanU(cprev2) || iswspace(cprev2))))) // lang=hu { // dot after a number indicates an ordinal number if(!iswdigit(cprev)) { is_end_clause = 0; // Roman number followed by dot } else { if (iswlower(c_next) || (c_next=='-')) // hyphen is needed for lang-hu (eg. 2.-kal) is_end_clause = 0; // only if followed by lower-case, (or if there is a XML tag) } } else if(c_next == '\'') { is_end_clause = 0; // eg. u.s.a.'s } if(iswlower(c_next)) { // next word has no capital letter, this dot is probably from an abbreviation // c1 = ' '; is_end_clause = 0; } if(any_alnum==0) { // no letters or digits yet, so probably not a sentence terminator // Here, dot is followed by space or bracket c1 = ' '; is_end_clause = 0; } } else { if(any_alnum==0) { // no letters or digits yet, so probably not a sentence terminator is_end_clause = 0; } } if(is_end_clause && (c1 == '.') && (c_next == '<') && option_ssml) { // wait until after the end of the xml tag, then look for upper-case letter is_end_clause = 0; end_clause_index = ix; end_clause_after_tag = punct_data; } } if(is_end_clause) { UngetC(c_next); buf[ix] = ' '; buf[ix+1] = 0; if(iswdigit(cprev) && !IsAlpha(c_next)) // ???? { punct_data &= ~CLAUSE_DOT; } if(nl_count > 1) { if((punct_data == CLAUSE_QUESTION) || (punct_data == CLAUSE_EXCLAMATION)) return(punct_data + 35); // with a longer pause return(CLAUSE_PARAGRAPH); } return(punct_data); // only recognise punctuation if followed by a blank or bracket/quote } else { if(!Eof()) { if(iswspace(c2)) UngetC(c_next); } } } } if(speech_parameters[espeakSILENCE]==1) continue; if(c1 == announced_punctuation) { // This character has already been announced, so delete it so that it isn't spoken a second time. // Unless it's a hyphen or apostrophe (which is used by TranslateClause() ) if(IsBracket(c1)) { c1 = 0xe000 + '('; // Unicode private useage area. So TranslateRules() knows the bracket name has been spoken } else if(c1 != '-') { c1 = ' '; } } j = ix+1; if(c1 == 0xe000 + '<') c1 = '<'; ix += utf8_out(c1,&buf[ix]); // buf[ix++] = c1; if(!iswspace(c1) && !IsBracket(c1)) { charix[ix] = count_characters - clause_start_char; while(j < ix) charix[j++] = -1; // subsequent bytes of a multibyte character } *charix_top = ix; if(((ix > (n_buf-75)) && !IsAlpha(c1) && !iswdigit(c1)) || (ix >= (n_buf-4))) { // clause too long, getting near end of buffer, so break here // try to break at a word boundary (unless we actually reach the end of buffer). // (n_buf-4) is to allow for 3 bytes of multibyte character plus terminator. buf[ix] = ' '; buf[ix+1] = 0; UngetC(c2); return(CLAUSE_NONE); } } if(stressed_word) { ix += utf8_out(CHAR_EMPHASIS, &buf[ix]); } if(end_clause_after_tag) { RemoveChar(&buf[end_clause_index]); // delete clause-end punctiation } buf[ix] = ' '; buf[ix+1] = 0; return(CLAUSE_EOF); // end of file } // end of ReadClause void InitNamedata(void) {//==================== namedata_ix = 0; if(namedata != NULL) { free(namedata); namedata = NULL; n_namedata = 0; } } void InitText2(void) {//================= int param; ungot_char = 0; ungot_char2 = 0; n_ssml_stack =1; n_param_stack = 1; ssml_stack[0].tag_type = 0; for(param=0; param. * ***************************************************************************/ #include "StdAfx.h" #include #include #include #include "speak_lib.h" #include "speech.h" #include "phoneme.h" #include "synthesize.h" #include "voice.h" #include "translate.h" extern int GetAmplitude(void); extern void DoSonicSpeed(int value); extern int saved_parameters[]; // convert from words-per-minute to internal speed factor // Use this to calibrate speed for wpm 80-350 static unsigned char speed_lookup[] = { 255, 255, 255, 255, 255, // 80 253, 249, 245, 242, 238, // 85 235, 232, 228, 225, 222, // 90 218, 216, 213, 210, 207, // 95 204, 201, 198, 196, 193, // 100 191, 188, 186, 183, 181, // 105 179, 176, 174, 172, 169, // 110 168, 165, 163, 161, 159, // 115 158, 155, 153, 152, 150, // 120 148, 146, 145, 143, 141, // 125 139, 137, 136, 135, 133, // 130 131, 130, 129, 127, 126, // 135 124, 123, 122, 120, 119, // 140 118, 117, 115, 114, 113, // 145 112, 111, 110, 109, 107, // 150 106, 105, 104, 103, 102, // 155 101, 100, 99, 98, 97, // 160 96, 95, 94, 93, 92, // 165 91, 90, 89, 89, 88, // 170 87, 86, 85, 84, 83, // 175 82, 82, 81, 80, 80, // 180 79, 78, 77, 76, 76, // 185 75, 75, 74, 73, 72, // 190 71, 71, 70, 69, 69, // 195 68, 67, 67, 66, 66, // 200 65, 64, 64, 63, 62, // 205 62, 61, 61, 60, 59, // 210 59, 58, 58, 57, 57, // 215 56, 56, 55, 54, 54, // 220 53, 53, 52, 52, 52, // 225 51, 50, 50, 49, 49, // 230 48, 48, 47, 47, 46, // 235 46, 46, 45, 45, 44, // 240 44, 44, 43, 43, 42, // 245 41, 40, 40, 40, 39, // 250 39, 39, 38, 38, 38, // 255 37, 37, 37, 36, 36, // 260 35, 35, 35, 35, 34, // 265 34, 34, 33, 33, 33, // 270 32, 32, 31, 31, 31, // 275 30, 30, 30, 29, 29, // 280 29, 29, 28, 28, 27, // 285 27, 27, 27, 26, 26, // 290 26, 26, 25, 25, 25, // 295 24, 24, 24, 24, 23, // 300 23, 23, 23, 22, 22, // 305 22, 21, 21, 21, 21, // 310 20, 20, 20, 20, 19, // 315 19, 19, 18, 18, 17, // 320 17, 17, 16, 16, 16, // 325 16, 16, 16, 15, 15, // 330 15, 15, 14, 14, 14, // 335 13, 13, 13, 12, 12, // 340 12, 12, 11, 11, 11, // 345 11, 10, 10, 10, 9, // 350 9, 9, 8, 8, 8, // 355 }; // speed_factor1 adjustments for speeds 350 to 374: pauses static unsigned char pause_factor_350[] = { 22,22,22,22,22,22,22,21,21,21, // 350 21,20,20,19,19,18,17,16,15,15, // 360 15,15,15,15,15}; // 370 // wav_factor adjustments for speeds 350 to 450 // Use this to calibrate speed for wpm 350-450 static unsigned char wav_factor_350[] = { 120, 121, 120, 119, 119, // 350 118, 118, 117, 116, 116, // 355 115, 114, 113, 112, 112, // 360 111, 111, 110, 109, 108, // 365 107, 106, 106, 104, 103, // 370 103, 102, 102, 102, 101, // 375 101, 99, 98, 98, 97, // 380 96, 96, 95, 94, 93, // 385 91, 90, 91, 90, 89, // 390 88, 86, 85, 86, 85, // 395 85, 84, 82, 81, 80, // 400 79, 77, 78, 78, 76, // 405 77, 75, 75, 74, 73, // 410 71, 72, 70, 69, 69, // 415 69, 67, 65, 64, 63, // 420 63, 63, 61, 61, 59, // 425 59, 59, 58, 56, 57, // 430 58, 56, 54, 53, 52, // 435 52, 53, 52, 52, 50, // 440 48, 47, 47, 45, 46, // 445 45}; // 450 static int speed1 = 130; static int speed2 = 121; static int speed3 = 118; //#define TEST_SPEED #ifdef INCLUDE_SONIC void SetSpeed(int control) {//======================= int x; int s1; int wpm; int wpm2; int wpm_value; double sonic; speed.loud_consonants = 0; speed.min_sample_len = 450; speed.lenmod_factor = 110; // controls the effect of FRFLAG_LEN_MOD reduce length change speed.lenmod2_factor = 100; speed.min_pause = 5; wpm = embedded_value[EMBED_S]; if(control == 2) wpm = embedded_value[EMBED_S2]; wpm_value = wpm; if(voice->speed_percent > 0) { wpm = (wpm * voice->speed_percent)/100; } if(control & 2) { DoSonicSpeed(1 * 1024); } if((wpm_value > 450) || ((wpm_value > speed.fast_settings[0]) && (wpm > 350))) { wpm2 = wpm; wpm = 175; // set special eSpeak speed parameters for Sonic use // The eSpeak output will be speeded up by at least x2 x = 73; if(control & 1) { speed1 = (x * voice->speedf1)/256; speed2 = (x * voice->speedf2)/256; speed3 = (x * voice->speedf3)/256; } if(control & 2) { sonic = ((double)wpm2)/wpm; DoSonicSpeed((int)(sonic * 1024)); speed.pause_factor = 85; speed.clause_pause_factor = 80; speed.min_pause = 22; speed.min_sample_len = 450*2; speed.wav_factor = 211; speed.lenmod_factor = 210; speed.lenmod2_factor = 170; } return; } #ifdef TEST_SPEED if(wpm > 1000) { // TESTING // test = wpm / 1000; wpm = wpm % 1000; } #endif if(wpm > 450) wpm = 450; if(wpm > 360) { speed.loud_consonants = (wpm - 360) / 8; } wpm2 = wpm; if(wpm > 359) wpm2 = 359; if(wpm < 80) wpm2 = 80; x = speed_lookup[wpm2-80]; if(wpm >= 380) x = 7; if(wpm >= 400) x = 6; if(control & 1) { // set speed factors for different syllable positions within a word // these are used in CalcLengths() speed1 = (x * voice->speedf1)/256; speed2 = (x * voice->speedf2)/256; speed3 = (x * voice->speedf3)/256; if(x <= 7) { speed1 = x; speed2 = speed3 = x - 1; } } if(control & 2) { // these are used in synthesis file if(wpm > 350) { speed.lenmod_factor = 85 - (wpm - 350) / 3; speed.lenmod2_factor = 60 - (wpm - 350) / 8; } else if(wpm > 250) { speed.lenmod_factor = 110 - (wpm - 250)/4; speed.lenmod2_factor = 110 - (wpm - 250)/2; } s1 = (x * voice->speedf1)/256; if(wpm >= 170) speed.wav_factor = 110 + (150*s1)/128; // reduced speed adjustment, used for playing recorded sounds else speed.wav_factor = 128 + (128*s1)/130; // = 215 at 170 wpm if(wpm >= 350) { speed.wav_factor = wav_factor_350[wpm-350]; } if(wpm >= 390) { speed.min_sample_len = 450 - (wpm - 400)/2; if(wpm > 440) speed.min_sample_len = 420 - (wpm - 440); } speed.pause_factor = (256 * s1)/115; // full speed adjustment, used for pause length speed.clause_pause_factor = 0; if(wpm > 430) { speed.pause_factor = 12; // speed.clause_pause_factor = 15; } else if(wpm > 400) { speed.pause_factor = 13; // speed.clause_pause_factor = 15; } else if(wpm > 374) { speed.pause_factor = 14; } else if(wpm > 350) { speed.pause_factor = pause_factor_350[wpm - 350]; } if(speed.clause_pause_factor == 0) { // restrict the reduction of pauses between clauses if((speed.clause_pause_factor = speed.pause_factor) < 16) speed.clause_pause_factor = 16; } } #ifdef TEST_SPEED //if(control==3) printf("%3d: speedf %d %d %d pause=%d %d wav=%d lenmod=%d %d\n",wpm,speed1,speed2,speed3, speed.pause_factor,speed.clause_pause_factor, speed.wav_factor,speed.lenmod_factor,speed.lenmod2_factor); #endif } // end of SetSpeed #else // not using sonic speed-up void SetSpeed(int control) {//======================= // This is the earlier version of SetSpeed() before sonic speed-up was added int x; int s1; int wpm; int wpm2; speed.loud_consonants = 0; speed.min_sample_len = 450; speed.lenmod_factor = 110; // controls the effect of FRFLAG_LEN_MOD reduce length change speed.lenmod2_factor = 100; wpm = embedded_value[EMBED_S]; if(control == 2) wpm = embedded_value[EMBED_S2]; #ifdef TEST_SPEED if(wpm > 1000) { // TESTING test = wpm / 1000; wpm = wpm % 1000; } #endif if(voice->speed_percent > 0) { wpm = (wpm * voice->speed_percent)/100; } if(wpm > 450) wpm = 450; if(wpm > 360) { speed.loud_consonants = (wpm - 360) / 8; } wpm2 = wpm; if(wpm > 359) wpm2 = 359; if(wpm < 80) wpm2 = 80; x = speed_lookup[wpm2-80]; if(wpm >= 380) x = 7; if(wpm >= 400) x = 6; if(control & 1) { // set speed factors for different syllable positions within a word // these are used in CalcLengths() speed1 = (x * voice->speedf1)/256; speed2 = (x * voice->speedf2)/256; speed3 = (x * voice->speedf3)/256; if(x <= 7) { speed1 = x; speed2 = speed3 = x - 1; } } if(control & 2) { // these are used in synthesis file if(wpm > 350) { speed.lenmod_factor = 85 - (wpm - 350) / 3; speed.lenmod2_factor = 60 - (wpm - 350) / 8; } else if(wpm > 250) { speed.lenmod_factor = 110 - (wpm - 250)/4; speed.lenmod2_factor = 110 - (wpm - 250)/2; } s1 = (x * voice->speedf1)/256; if(wpm >= 170) speed.wav_factor = 110 + (150*s1)/128; // reduced speed adjustment, used for playing recorded sounds else speed.wav_factor = 128 + (128*s1)/130; // = 215 at 170 wpm if(wpm >= 350) { speed.wav_factor = wav_factor_350[wpm-350]; } if(wpm >= 390) { speed.min_sample_len = 450 - (wpm - 400)/2; if(wpm > 440) speed.min_sample_len = 420 - (wpm - 440); } speed.pause_factor = (256 * s1)/115; // full speed adjustment, used for pause length speed.clause_pause_factor = 0; if(wpm > 430) { speed.pause_factor = 12; // speed.clause_pause_factor = 15; } else if(wpm > 400) { speed.pause_factor = 13; // speed.clause_pause_factor = 15; } else if(wpm > 374) { speed.pause_factor = 14; } else if(wpm > 350) { speed.pause_factor = pause_factor_350[wpm - 350]; } if(speed.clause_pause_factor == 0) { // restrict the reduction of pauses between clauses if((speed.clause_pause_factor = speed.pause_factor) < 16) speed.clause_pause_factor = 16; } } #ifdef TEST_SPEED //if(control==3) printf("%3d: speedf %d %d %d pause=%d %d wav=%d lenmod=%d %d\n",wpm,speed1,speed2,speed3, speed.pause_factor,speed.clause_pause_factor, speed.wav_factor,speed.lenmod_factor,speed.lenmod2_factor); #endif } // end of SetSpeed #endif // of INCLUDE_SONIC #ifdef deleted void SetAmplitude(int amp) {//======================= static unsigned char amplitude_factor[] = {0,5,6,7,9,11,14,17,21,26, 32, 38,44,50,56,63,70,77,84,91,100 }; if((amp >= 0) && (amp <= 20)) { option_amplitude = (amplitude_factor[amp] * 480)/256; } } #endif void SetParameter(int parameter, int value, int relative) {//====================================================== // parameter: reset-all, amp, pitch, speed, linelength, expression, capitals, number grouping // relative 0=absolute 1=relative int new_value = value; int default_value; if(relative) { if(parameter < 5) { default_value = param_defaults[parameter]; new_value = default_value + (default_value * value)/100; } } param_stack[0].parameter[parameter] = new_value; saved_parameters[parameter] = new_value; switch(parameter) { case espeakRATE: embedded_value[EMBED_S] = new_value; embedded_value[EMBED_S2] = new_value; SetSpeed(3); break; case espeakVOLUME: embedded_value[EMBED_A] = new_value; GetAmplitude(); break; case espeakPITCH: if(new_value > 99) new_value = 99; if(new_value < 0) new_value = 0; embedded_value[EMBED_P] = new_value; break; case espeakRANGE: if(new_value > 99) new_value = 99; embedded_value[EMBED_R] = new_value; break; case espeakLINELENGTH: option_linelength = new_value; break; case espeakWORDGAP: option_wordgap = new_value; break; case espeakINTONATION: if((new_value & 0xff) != 0) translator->langopts.intonation_group = new_value & 0xff; option_tone_flags = new_value; break; default: break; } } // end of SetParameter static void DoEmbedded2(int *embix) {//================================ // There were embedded commands in the text at this point unsigned int word; do { word = embedded_list[(*embix)++]; if((word & 0x1f) == EMBED_S) { // speed SetEmbedded(word & 0x7f, word >> 8); // adjusts embedded_value[EMBED_S] SetSpeed(1); } } while((word & 0x80) == 0); } void CalcLengths(Translator *tr) {//============================== int ix; int ix2; PHONEME_LIST *prev; PHONEME_LIST *next; PHONEME_LIST *next2; PHONEME_LIST *next3; PHONEME_LIST *p; PHONEME_LIST *p2; int stress; int type; static int more_syllables=0; int pre_sonorant=0; int pre_voiced=0; int last_pitch = 0; int pitch_start; int length_mod; int len; int env2; int end_of_clause; int embedded_ix = 0; int min_drop; int pitch1; int emphasized; int tone_mod; unsigned char *pitch_env=NULL; PHONEME_DATA phdata_tone; for(ix=1; ixstresslevel & 0x7; emphasized = p->stresslevel & 0x8; next = &phoneme_list[ix+1]; if(p->synthflags & SFLAG_EMBEDDED) { DoEmbedded2(&embedded_ix); } type = p->type; if(p->synthflags & SFLAG_SYLLABLE) type = phVOWEL; switch(type) { case phPAUSE: last_pitch = 0; break; case phSTOP: last_pitch = 0; if(prev->type == phFRICATIVE) p->prepause = 25; else if((more_syllables > 0) || (stress < 4)) p->prepause = 48; else p->prepause = 60; if(prev->type == phSTOP) p->prepause = 60; if((tr->langopts.word_gap & 0x10) && (p->newword)) p->prepause = 60; if(p->ph->phflags & phLENGTHENSTOP) p->prepause += 30; if(p->synthflags & SFLAG_LENGTHEN) p->prepause += tr->langopts.long_stop; break; case phVFRICATIVE: case phFRICATIVE: if(p->newword) { if((prev->type == phVOWEL) && (p->ph->phflags & phNOPAUSE)) { } else { p->prepause = 15; } } if(next->type==phPAUSE && prev->type==phNASAL && !(p->ph->phflags&phFORTIS)) p->prepause = 25; if(prev->ph->phflags & phBRKAFTER) p->prepause = 30; if((tr->langopts.word_gap & 0x10) && (p->newword)) p->prepause = 30; if((p->ph->phflags & phSIBILANT) && next->type==phSTOP && !next->newword) { if(prev->type == phVOWEL) p->length = 200; // ?? should do this if it's from a prefix else p->length = 150; } else p->length = 256; if(type == phVFRICATIVE) { if(next->type==phVOWEL) { pre_voiced = 1; } if((prev->type==phVOWEL) || (prev->type == phLIQUID)) { p->length = (255 + prev->length)/2; } } break; case phVSTOP: if(prev->type==phVFRICATIVE || prev->type==phFRICATIVE || (prev->ph->phflags & phSIBILANT) || (prev->type == phLIQUID)) p->prepause = 30; if(next->type==phVOWEL || next->type==phLIQUID) { if((next->type==phVOWEL) || !next->newword) pre_voiced = 1; p->prepause = 40; if((prev->type == phPAUSE) || (prev->type == phVOWEL)) // || (prev->ph->mnemonic == ('/'*256+'r'))) p->prepause = 0; else if(p->newword==0) { if(prev->type==phLIQUID) p->prepause = 20; if(prev->type==phNASAL) p->prepause = 12; if(prev->type==phSTOP && !(prev->ph->phflags & phFORTIS)) p->prepause = 0; } } if((tr->langopts.word_gap & 0x10) && (p->newword) && (p->prepause < 20)) p->prepause = 20; break; case phLIQUID: case phNASAL: p->amp = tr->stress_amps[0]; // unless changed later p->length = 256; // TEMPORARY min_drop = 0; if(p->newword) { if(prev->type==phLIQUID) p->prepause = 25; if(prev->type==phVOWEL) { if(!(p->ph->phflags & phNOPAUSE)) p->prepause = 12; } } if(next->type==phVOWEL) { pre_sonorant = 1; } else { p->pitch2 = last_pitch; if((prev->type==phVOWEL) || (prev->type == phLIQUID)) { p->length = prev->length; if(p->type == phLIQUID) { p->length = speed1; } if(next->type == phVSTOP) { p->length = (p->length * 160)/100; } if(next->type == phVFRICATIVE) { p->length = (p->length * 120)/100; } } else { for(ix2=ix; ix2pitch2 = phoneme_list[ix2].pitch2; break; } } } p->pitch1 = p->pitch2-16; if(p->pitch2 < 16) { p->pitch1 = 0; } p->env = PITCHfall; pre_voiced = 0; } break; case phVOWEL: min_drop = 0; next2 = &phoneme_list[ix+2]; next3 = &phoneme_list[ix+3]; if(stress > 7) stress = 7; if(stress <= 1) { stress = stress ^ 1; // swap diminished and unstressed (until we swap stress_amps,stress_lengths in tr_languages) } if(pre_sonorant) p->amp = tr->stress_amps[stress]-1; else p->amp = tr->stress_amps[stress]; if(emphasized) p->amp = 25; if(ix >= (n_phoneme_list-3)) { // last phoneme of a clause, limit its amplitude if(p->amp > tr->langopts.param[LOPT_MAXAMP_EOC]) p->amp = tr->langopts.param[LOPT_MAXAMP_EOC]; } // is the last syllable of a word ? more_syllables=0; end_of_clause = 0; for(p2 = p+1; p2->newword== 0; p2++) { if((p2->type == phVOWEL) && !(p2->ph->phflags & phNONSYLLABIC)) more_syllables++; if(p2->ph->code == phonPAUSE_CLAUSE) end_of_clause = 2; } if(p2->ph->code == phonPAUSE_CLAUSE) end_of_clause = 2; if((p2->newword & 2) && (more_syllables==0)) { end_of_clause = 2; } // calc length modifier if((next->ph->code == phonPAUSE_VSHORT) && (next2->type == phPAUSE)) { // if PAUSE_VSHORT is followed by a pause, then use that next = next2; next2 = next3; next3 = &phoneme_list[ix+4]; } if(more_syllables==0) { len = tr->langopts.length_mods0[next2->ph->length_mod *10+ next->ph->length_mod]; if((next->newword) && (tr->langopts.word_gap & 0x20)) { // consider as a pause + first phoneme of the next word length_mod = (len + tr->langopts.length_mods0[next->ph->length_mod *10+ 1])/2; } else length_mod = len; } else { length_mod = tr->langopts.length_mods[next2->ph->length_mod *10+ next->ph->length_mod]; if((next->type == phNASAL) && (next2->type == phSTOP || next2->type == phVSTOP) && (next3->ph->phflags & phFORTIS)) length_mod -= 15; } if(more_syllables==0) length_mod *= speed1; else if(more_syllables==1) length_mod *= speed2; else length_mod *= speed3; length_mod = length_mod / 128; if(length_mod < 8) length_mod = 8; // restrict how much lengths can be reduced if(stress >= 7) { // tonic syllable, include a constant component so it doesn't decrease directly with speed length_mod += tr->langopts.lengthen_tonic; if(emphasized) length_mod += (tr->langopts.lengthen_tonic/2); } else if(emphasized) { length_mod += tr->langopts.lengthen_tonic; } if((len = tr->stress_lengths[stress]) == 0) len = tr->stress_lengths[6]; length_mod = length_mod * len; if(p->tone_ph != 0) { if((tone_mod = phoneme_tab[p->tone_ph]->std_length) > 0) { // a tone phoneme specifies a percentage change to the length length_mod = (length_mod * tone_mod) / 100; } } if((end_of_clause == 2) && !(tr->langopts.stress_flags & S_NO_EOC_LENGTHEN)) { // this is the last syllable in the clause, lengthen it - more for short vowels len = (p->ph->std_length * 2); if(tr->langopts.stress_flags & 0x40000) len=200; // don't lengthen short vowels more than long vowels at end-of-clause length_mod = length_mod * (256 + (280 - len)/3)/256; } if(length_mod > tr->langopts.max_lengthmod*speed1) { //limit the vowel length adjustment for some languages length_mod = (tr->langopts.max_lengthmod*speed1); } length_mod = length_mod / 128; if(p->type != phVOWEL) { length_mod = 256; // syllabic consonant min_drop = 16; } p->length = length_mod; if(p->env >= (N_ENVELOPE_DATA-1)) { fprintf(stderr,"espeak: Bad intonation data\n"); p->env = 0; } // pre-vocalic part // set last-pitch env2 = p->env + 1; // version for use with preceding semi-vowel if(p->tone_ph != 0) { InterpretPhoneme2(p->tone_ph, &phdata_tone); pitch_env = GetEnvelope(phdata_tone.pitch_env); } else { pitch_env = envelope_data[env2]; } pitch_start = p->pitch1 + ((p->pitch2-p->pitch1)*pitch_env[0])/256; if(pre_sonorant || pre_voiced) { // set pitch for pre-vocalic part if(pitch_start == 255) last_pitch = pitch_start; // pitch is not set if(pitch_start - last_pitch > 16) last_pitch = pitch_start - 16; prev->pitch1 = last_pitch; prev->pitch2 = pitch_start; if(last_pitch < pitch_start) { prev->env = PITCHrise; p->env = env2; } else { prev->env = PITCHfall; } prev->length = length_mod; prev->amp = p->amp; if((prev->type != phLIQUID) && (prev->amp > 18)) prev->amp = 18; } // vowel & post-vocalic part next->synthflags &= ~SFLAG_SEQCONTINUE; if(next->type == phNASAL && next2->type != phVOWEL) next->synthflags |= SFLAG_SEQCONTINUE; if(next->type == phLIQUID) { next->synthflags |= SFLAG_SEQCONTINUE; if(next2->type == phVOWEL) { next->synthflags &= ~SFLAG_SEQCONTINUE; } if(next2->type != phVOWEL) { if(next->ph->mnemonic == ('/'*256+'r')) { next->synthflags &= ~SFLAG_SEQCONTINUE; // min_drop = 15; } } } if((min_drop > 0) && ((p->pitch2 - p->pitch1) < min_drop)) { pitch1 = p->pitch2 - min_drop; if(pitch1 < 0) pitch1 = 0; p->pitch1 = pitch1; } last_pitch = p->pitch1 + ((p->pitch2-p->pitch1)*envelope_data[p->env][127])/256; pre_sonorant = 0; pre_voiced = 0; break; } } } // end of CalcLengths praat-6.0.04/external/espeak/sintab.h000066400000000000000000000331641261542461700174520ustar00rootroot00000000000000short int sin_tab[2048] = { 0, -25, -50, -75, -100, -125, -150, -175, -201, -226, -251, -276, -301, -326, -351, -376, -401, -427, -452, -477, -502, -527, -552, -577, -602, -627, -652, -677, -702, -727, -752, -777, -802, -827, -852, -877, -902, -927, -952, -977, -1002, -1027, -1052, -1077, -1102, -1127, -1152, -1177, -1201, -1226, -1251, -1276, -1301, -1326, -1350, -1375, -1400, -1425, -1449, -1474, -1499, -1523, -1548, -1573, -1597, -1622, -1647, -1671, -1696, -1721, -1745, -1770, -1794, -1819, -1843, -1868, -1892, -1917, -1941, -1965, -1990, -2014, -2038, -2063, -2087, -2111, -2136, -2160, -2184, -2208, -2233, -2257, -2281, -2305, -2329, -2353, -2377, -2401, -2425, -2449, -2473, -2497, -2521, -2545, -2569, -2593, -2617, -2640, -2664, -2688, -2712, -2735, -2759, -2783, -2806, -2830, -2853, -2877, -2900, -2924, -2947, -2971, -2994, -3018, -3041, -3064, -3088, -3111, -3134, -3157, -3180, -3204, -3227, -3250, -3273, -3296, -3319, -3342, -3365, -3388, -3410, -3433, -3456, -3479, -3502, -3524, -3547, -3570, -3592, -3615, -3637, -3660, -3682, -3705, -3727, -3749, -3772, -3794, -3816, -3839, -3861, -3883, -3905, -3927, -3949, -3971, -3993, -4015, -4037, -4059, -4080, -4102, -4124, -4146, -4167, -4189, -4211, -4232, -4254, -4275, -4296, -4318, -4339, -4360, -4382, -4403, -4424, -4445, -4466, -4487, -4508, -4529, -4550, -4571, -4592, -4613, -4633, -4654, -4675, -4695, -4716, -4736, -4757, -4777, -4798, -4818, -4838, -4859, -4879, -4899, -4919, -4939, -4959, -4979, -4999, -5019, -5039, -5059, -5078, -5098, -5118, -5137, -5157, -5176, -5196, -5215, -5235, -5254, -5273, -5292, -5311, -5331, -5350, -5369, -5388, -5406, -5425, -5444, -5463, -5482, -5500, -5519, -5537, -5556, -5574, -5593, -5611, -5629, -5648, -5666, -5684, -5702, -5720, -5738, -5756, -5774, -5791, -5809, -5827, -5844, -5862, -5880, -5897, -5914, -5932, -5949, -5966, -5984, -6001, -6018, -6035, -6052, -6069, -6085, -6102, -6119, -6136, -6152, -6169, -6185, -6202, -6218, -6235, -6251, -6267, -6283, -6299, -6315, -6331, -6347, -6363, -6379, -6395, -6410, -6426, -6441, -6457, -6472, -6488, -6503, -6518, -6533, -6549, -6564, -6579, -6594, -6608, -6623, -6638, -6653, -6667, -6682, -6696, -6711, -6725, -6739, -6754, -6768, -6782, -6796, -6810, -6824, -6838, -6852, -6865, -6879, -6893, -6906, -6920, -6933, -6946, -6960, -6973, -6986, -6999, -7012, -7025, -7038, -7051, -7064, -7076, -7089, -7101, -7114, -7126, -7139, -7151, -7163, -7175, -7187, -7199, -7211, -7223, -7235, -7247, -7259, -7270, -7282, -7293, -7305, -7316, -7327, -7338, -7349, -7361, -7372, -7382, -7393, -7404, -7415, -7425, -7436, -7446, -7457, -7467, -7478, -7488, -7498, -7508, -7518, -7528, -7538, -7548, -7557, -7567, -7577, -7586, -7596, -7605, -7614, -7623, -7633, -7642, -7651, -7660, -7668, -7677, -7686, -7695, -7703, -7712, -7720, -7728, -7737, -7745, -7753, -7761, -7769, -7777, -7785, -7793, -7800, -7808, -7816, -7823, -7830, -7838, -7845, -7852, -7859, -7866, -7873, -7880, -7887, -7894, -7900, -7907, -7914, -7920, -7926, -7933, -7939, -7945, -7951, -7957, -7963, -7969, -7975, -7980, -7986, -7991, -7997, -8002, -8008, -8013, -8018, -8023, -8028, -8033, -8038, -8043, -8047, -8052, -8057, -8061, -8066, -8070, -8074, -8078, -8082, -8086, -8090, -8094, -8098, -8102, -8105, -8109, -8113, -8116, -8119, -8123, -8126, -8129, -8132, -8135, -8138, -8141, -8143, -8146, -8149, -8151, -8153, -8156, -8158, -8160, -8162, -8164, -8166, -8168, -8170, -8172, -8174, -8175, -8177, -8178, -8179, -8181, -8182, -8183, -8184, -8185, -8186, -8187, -8187, -8188, -8189, -8189, -8190, -8190, -8190, -8190, -8190, -8191, -8190, -8190, -8190, -8190, -8190, -8189, -8189, -8188, -8187, -8187, -8186, -8185, -8184, -8183, -8182, -8181, -8179, -8178, -8177, -8175, -8174, -8172, -8170, -8168, -8166, -8164, -8162, -8160, -8158, -8156, -8153, -8151, -8149, -8146, -8143, -8141, -8138, -8135, -8132, -8129, -8126, -8123, -8119, -8116, -8113, -8109, -8105, -8102, -8098, -8094, -8090, -8086, -8082, -8078, -8074, -8070, -8066, -8061, -8057, -8052, -8047, -8043, -8038, -8033, -8028, -8023, -8018, -8013, -8008, -8002, -7997, -7991, -7986, -7980, -7975, -7969, -7963, -7957, -7951, -7945, -7939, -7933, -7926, -7920, -7914, -7907, -7900, -7894, -7887, -7880, -7873, -7866, -7859, -7852, -7845, -7838, -7830, -7823, -7816, -7808, -7800, -7793, -7785, -7777, -7769, -7761, -7753, -7745, -7737, -7728, -7720, -7712, -7703, -7695, -7686, -7677, -7668, -7660, -7651, -7642, -7633, -7623, -7614, -7605, -7596, -7586, -7577, -7567, -7557, -7548, -7538, -7528, -7518, -7508, -7498, -7488, -7478, -7467, -7457, -7446, -7436, -7425, -7415, -7404, -7393, -7382, -7372, -7361, -7349, -7338, -7327, -7316, -7305, -7293, -7282, -7270, -7259, -7247, -7235, -7223, -7211, -7199, -7187, -7175, -7163, -7151, -7139, -7126, -7114, -7101, -7089, -7076, -7064, -7051, -7038, -7025, -7012, -6999, -6986, -6973, -6960, -6946, -6933, -6920, -6906, -6893, -6879, -6865, -6852, -6838, -6824, -6810, -6796, -6782, -6768, -6754, -6739, -6725, -6711, -6696, -6682, -6667, -6653, -6638, -6623, -6608, -6594, -6579, -6564, -6549, -6533, -6518, -6503, -6488, -6472, -6457, -6441, -6426, -6410, -6395, -6379, -6363, -6347, -6331, -6315, -6299, -6283, -6267, -6251, -6235, -6218, -6202, -6185, -6169, -6152, -6136, -6119, -6102, -6085, -6069, -6052, -6035, -6018, -6001, -5984, -5966, -5949, -5932, -5914, -5897, -5880, -5862, -5844, -5827, -5809, -5791, -5774, -5756, -5738, -5720, -5702, -5684, -5666, -5648, -5629, -5611, -5593, -5574, -5556, -5537, -5519, -5500, -5482, -5463, -5444, -5425, -5406, -5388, -5369, -5350, -5331, -5311, -5292, -5273, -5254, -5235, -5215, -5196, -5176, -5157, -5137, -5118, -5098, -5078, -5059, -5039, -5019, -4999, -4979, -4959, -4939, -4919, -4899, -4879, -4859, -4838, -4818, -4798, -4777, -4757, -4736, -4716, -4695, -4675, -4654, -4633, -4613, -4592, -4571, -4550, -4529, -4508, -4487, -4466, -4445, -4424, -4403, -4382, -4360, -4339, -4318, -4296, -4275, -4254, -4232, -4211, -4189, -4167, -4146, -4124, -4102, -4080, -4059, -4037, -4015, -3993, -3971, -3949, -3927, -3905, -3883, -3861, -3839, -3816, -3794, -3772, -3749, -3727, -3705, -3682, -3660, -3637, -3615, -3592, -3570, -3547, -3524, -3502, -3479, -3456, -3433, -3410, -3388, -3365, -3342, -3319, -3296, -3273, -3250, -3227, -3204, -3180, -3157, -3134, -3111, -3088, -3064, -3041, -3018, -2994, -2971, -2947, -2924, -2900, -2877, -2853, -2830, -2806, -2783, -2759, -2735, -2712, -2688, -2664, -2640, -2617, -2593, -2569, -2545, -2521, -2497, -2473, -2449, -2425, -2401, -2377, -2353, -2329, -2305, -2281, -2257, -2233, -2208, -2184, -2160, -2136, -2111, -2087, -2063, -2038, -2014, -1990, -1965, -1941, -1917, -1892, -1868, -1843, -1819, -1794, -1770, -1745, -1721, -1696, -1671, -1647, -1622, -1597, -1573, -1548, -1523, -1499, -1474, -1449, -1425, -1400, -1375, -1350, -1326, -1301, -1276, -1251, -1226, -1201, -1177, -1152, -1127, -1102, -1077, -1052, -1027, -1002, -977, -952, -927, -902, -877, -852, -827, -802, -777, -752, -727, -702, -677, -652, -627, -602, -577, -552, -527, -502, -477, -452, -427, -401, -376, -351, -326, -301, -276, -251, -226, -201, -175, -150, -125, -100, -75, -50, -25, 0, 25, 50, 75, 100, 125, 150, 175, 201, 226, 251, 276, 301, 326, 351, 376, 401, 427, 452, 477, 502, 527, 552, 577, 602, 627, 652, 677, 702, 727, 752, 777, 802, 827, 852, 877, 902, 927, 952, 977, 1002, 1027, 1052, 1077, 1102, 1127, 1152, 1177, 1201, 1226, 1251, 1276, 1301, 1326, 1350, 1375, 1400, 1425, 1449, 1474, 1499, 1523, 1548, 1573, 1597, 1622, 1647, 1671, 1696, 1721, 1745, 1770, 1794, 1819, 1843, 1868, 1892, 1917, 1941, 1965, 1990, 2014, 2038, 2063, 2087, 2111, 2136, 2160, 2184, 2208, 2233, 2257, 2281, 2305, 2329, 2353, 2377, 2401, 2425, 2449, 2473, 2497, 2521, 2545, 2569, 2593, 2617, 2640, 2664, 2688, 2712, 2735, 2759, 2783, 2806, 2830, 2853, 2877, 2900, 2924, 2947, 2971, 2994, 3018, 3041, 3064, 3088, 3111, 3134, 3157, 3180, 3204, 3227, 3250, 3273, 3296, 3319, 3342, 3365, 3388, 3410, 3433, 3456, 3479, 3502, 3524, 3547, 3570, 3592, 3615, 3637, 3660, 3682, 3705, 3727, 3749, 3772, 3794, 3816, 3839, 3861, 3883, 3905, 3927, 3949, 3971, 3993, 4015, 4037, 4059, 4080, 4102, 4124, 4146, 4167, 4189, 4211, 4232, 4254, 4275, 4296, 4318, 4339, 4360, 4382, 4403, 4424, 4445, 4466, 4487, 4508, 4529, 4550, 4571, 4592, 4613, 4633, 4654, 4675, 4695, 4716, 4736, 4757, 4777, 4798, 4818, 4838, 4859, 4879, 4899, 4919, 4939, 4959, 4979, 4999, 5019, 5039, 5059, 5078, 5098, 5118, 5137, 5157, 5176, 5196, 5215, 5235, 5254, 5273, 5292, 5311, 5331, 5350, 5369, 5388, 5406, 5425, 5444, 5463, 5482, 5500, 5519, 5537, 5556, 5574, 5593, 5611, 5629, 5648, 5666, 5684, 5702, 5720, 5738, 5756, 5774, 5791, 5809, 5827, 5844, 5862, 5880, 5897, 5914, 5932, 5949, 5966, 5984, 6001, 6018, 6035, 6052, 6069, 6085, 6102, 6119, 6136, 6152, 6169, 6185, 6202, 6218, 6235, 6251, 6267, 6283, 6299, 6315, 6331, 6347, 6363, 6379, 6395, 6410, 6426, 6441, 6457, 6472, 6488, 6503, 6518, 6533, 6549, 6564, 6579, 6594, 6608, 6623, 6638, 6653, 6667, 6682, 6696, 6711, 6725, 6739, 6754, 6768, 6782, 6796, 6810, 6824, 6838, 6852, 6865, 6879, 6893, 6906, 6920, 6933, 6946, 6960, 6973, 6986, 6999, 7012, 7025, 7038, 7051, 7064, 7076, 7089, 7101, 7114, 7126, 7139, 7151, 7163, 7175, 7187, 7199, 7211, 7223, 7235, 7247, 7259, 7270, 7282, 7293, 7305, 7316, 7327, 7338, 7349, 7361, 7372, 7382, 7393, 7404, 7415, 7425, 7436, 7446, 7457, 7467, 7478, 7488, 7498, 7508, 7518, 7528, 7538, 7548, 7557, 7567, 7577, 7586, 7596, 7605, 7614, 7623, 7633, 7642, 7651, 7660, 7668, 7677, 7686, 7695, 7703, 7712, 7720, 7728, 7737, 7745, 7753, 7761, 7769, 7777, 7785, 7793, 7800, 7808, 7816, 7823, 7830, 7838, 7845, 7852, 7859, 7866, 7873, 7880, 7887, 7894, 7900, 7907, 7914, 7920, 7926, 7933, 7939, 7945, 7951, 7957, 7963, 7969, 7975, 7980, 7986, 7991, 7997, 8002, 8008, 8013, 8018, 8023, 8028, 8033, 8038, 8043, 8047, 8052, 8057, 8061, 8066, 8070, 8074, 8078, 8082, 8086, 8090, 8094, 8098, 8102, 8105, 8109, 8113, 8116, 8119, 8123, 8126, 8129, 8132, 8135, 8138, 8141, 8143, 8146, 8149, 8151, 8153, 8156, 8158, 8160, 8162, 8164, 8166, 8168, 8170, 8172, 8174, 8175, 8177, 8178, 8179, 8181, 8182, 8183, 8184, 8185, 8186, 8187, 8187, 8188, 8189, 8189, 8190, 8190, 8190, 8190, 8190, 8191, 8190, 8190, 8190, 8190, 8190, 8189, 8189, 8188, 8187, 8187, 8186, 8185, 8184, 8183, 8182, 8181, 8179, 8178, 8177, 8175, 8174, 8172, 8170, 8168, 8166, 8164, 8162, 8160, 8158, 8156, 8153, 8151, 8149, 8146, 8143, 8141, 8138, 8135, 8132, 8129, 8126, 8123, 8119, 8116, 8113, 8109, 8105, 8102, 8098, 8094, 8090, 8086, 8082, 8078, 8074, 8070, 8066, 8061, 8057, 8052, 8047, 8043, 8038, 8033, 8028, 8023, 8018, 8013, 8008, 8002, 7997, 7991, 7986, 7980, 7975, 7969, 7963, 7957, 7951, 7945, 7939, 7933, 7926, 7920, 7914, 7907, 7900, 7894, 7887, 7880, 7873, 7866, 7859, 7852, 7845, 7838, 7830, 7823, 7816, 7808, 7800, 7793, 7785, 7777, 7769, 7761, 7753, 7745, 7737, 7728, 7720, 7712, 7703, 7695, 7686, 7677, 7668, 7660, 7651, 7642, 7633, 7623, 7614, 7605, 7596, 7586, 7577, 7567, 7557, 7548, 7538, 7528, 7518, 7508, 7498, 7488, 7478, 7467, 7457, 7446, 7436, 7425, 7415, 7404, 7393, 7382, 7372, 7361, 7349, 7338, 7327, 7316, 7305, 7293, 7282, 7270, 7259, 7247, 7235, 7223, 7211, 7199, 7187, 7175, 7163, 7151, 7139, 7126, 7114, 7101, 7089, 7076, 7064, 7051, 7038, 7025, 7012, 6999, 6986, 6973, 6960, 6946, 6933, 6920, 6906, 6893, 6879, 6865, 6852, 6838, 6824, 6810, 6796, 6782, 6768, 6754, 6739, 6725, 6711, 6696, 6682, 6667, 6653, 6638, 6623, 6608, 6594, 6579, 6564, 6549, 6533, 6518, 6503, 6488, 6472, 6457, 6441, 6426, 6410, 6395, 6379, 6363, 6347, 6331, 6315, 6299, 6283, 6267, 6251, 6235, 6218, 6202, 6185, 6169, 6152, 6136, 6119, 6102, 6085, 6069, 6052, 6035, 6018, 6001, 5984, 5966, 5949, 5932, 5914, 5897, 5880, 5862, 5844, 5827, 5809, 5791, 5774, 5756, 5738, 5720, 5702, 5684, 5666, 5648, 5629, 5611, 5593, 5574, 5556, 5537, 5519, 5500, 5482, 5463, 5444, 5425, 5406, 5388, 5369, 5350, 5331, 5311, 5292, 5273, 5254, 5235, 5215, 5196, 5176, 5157, 5137, 5118, 5098, 5078, 5059, 5039, 5019, 4999, 4979, 4959, 4939, 4919, 4899, 4879, 4859, 4838, 4818, 4798, 4777, 4757, 4736, 4716, 4695, 4675, 4654, 4633, 4613, 4592, 4571, 4550, 4529, 4508, 4487, 4466, 4445, 4424, 4403, 4382, 4360, 4339, 4318, 4296, 4275, 4254, 4232, 4211, 4189, 4167, 4146, 4124, 4102, 4080, 4059, 4037, 4015, 3993, 3971, 3949, 3927, 3905, 3883, 3861, 3839, 3816, 3794, 3772, 3749, 3727, 3705, 3682, 3660, 3637, 3615, 3592, 3570, 3547, 3524, 3502, 3479, 3456, 3433, 3410, 3388, 3365, 3342, 3319, 3296, 3273, 3250, 3227, 3204, 3180, 3157, 3134, 3111, 3088, 3064, 3041, 3018, 2994, 2971, 2947, 2924, 2900, 2877, 2853, 2830, 2806, 2783, 2759, 2735, 2712, 2688, 2664, 2640, 2617, 2593, 2569, 2545, 2521, 2497, 2473, 2449, 2425, 2401, 2377, 2353, 2329, 2305, 2281, 2257, 2233, 2208, 2184, 2160, 2136, 2111, 2087, 2063, 2038, 2014, 1990, 1965, 1941, 1917, 1892, 1868, 1843, 1819, 1794, 1770, 1745, 1721, 1696, 1671, 1647, 1622, 1597, 1573, 1548, 1523, 1499, 1474, 1449, 1425, 1400, 1375, 1350, 1326, 1301, 1276, 1251, 1226, 1201, 1177, 1152, 1127, 1102, 1077, 1052, 1027, 1002, 977, 952, 927, 902, 877, 852, 827, 802, 777, 752, 727, 702, 677, 652, 627, 602, 577, 552, 527, 502, 477, 452, 427, 401, 376, 351, 326, 301, 276, 251, 226, 201, 175, 150, 125, 100, 75, 50, 25, }; praat-6.0.04/external/espeak/sonic.cpp000066400000000000000000000655441261542461700176470ustar00rootroot00000000000000/* Sonic library Copyright 2010 Bill Cox This file is part of the Sonic Library. The Sonic Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include "StdAfx.h" #include #include #include #include #include "speech.h" #include "sonic.h" #ifdef INCLUDE_SONIC struct sonicStreamStruct { short *inputBuffer; short *outputBuffer; short *pitchBuffer; short *downSampleBuffer; float speed; float volume; float pitch; int numChannels; int inputBufferSize; int pitchBufferSize; int outputBufferSize; int numInputSamples; int numOutputSamples; int numPitchSamples; int minPeriod; int maxPeriod; int maxRequired; int remainingInputToCopy; int sampleRate; int prevPeriod; int prevMaxDiff; int prevMinDiff; }; /* Just used for debugging */ void sonicMSG(char *format, ...) { char buffer[4096]; va_list ap; FILE *file; va_start(ap, format); vsprintf((char *)buffer, (char *)format, ap); va_end(ap); file=fopen("/tmp/sonic.log", "a"); fprintf(file, "%s", buffer); fclose(file); } /* Scale the samples by the factor. */ static void scaleSamples( short *samples, int numSamples, float volume) { int fixedPointVolume = volume*4096.0f; int value; while(numSamples--) { value = (*samples*fixedPointVolume) >> 12; if(value > 32767) { value = 32767; } else if(value < -32767) { value = -32767; } *samples++ = value; } } /* Get the speed of the stream. */ float sonicGetSpeed( sonicStream stream) { return stream->speed; } /* Set the speed of the stream. */ void sonicSetSpeed( sonicStream stream, float speed) { stream->speed = speed; } /* Get the pitch of the stream. */ float sonicGetPitch( sonicStream stream) { return stream->pitch; } /* Set the pitch of the stream. */ void sonicSetPitch( sonicStream stream, float pitch) { stream->pitch = pitch; } /* Get the scaling factor of the stream. */ float sonicGetVolume( sonicStream stream) { return stream->volume; } /* Set the scaling factor of the stream. */ void sonicSetVolume( sonicStream stream, float volume) { stream->volume = volume; } /* Get the sample rate of the stream. */ int sonicGetSampleRate( sonicStream stream) { return stream->sampleRate; } /* Get the number of channels. */ int sonicGetNumChannels( sonicStream stream) { return stream->numChannels; } /* Destroy the sonic stream. */ void sonicDestroyStream( sonicStream stream) { if(stream->inputBuffer != NULL) { free(stream->inputBuffer); } if(stream->outputBuffer != NULL) { free(stream->outputBuffer); } if(stream->pitchBuffer != NULL) { free(stream->pitchBuffer); } if(stream->downSampleBuffer != NULL) { free(stream->downSampleBuffer); } free(stream); } /* Create a sonic stream. Return NULL only if we are out of memory and cannot allocate the stream. */ sonicStream sonicCreateStream( int sampleRate, int numChannels) { sonicStream stream = (sonicStream)calloc(1, sizeof(struct sonicStreamStruct)); int minPeriod = sampleRate/SONIC_MAX_PITCH; int maxPeriod = sampleRate/SONIC_MIN_PITCH; int maxRequired = 2*maxPeriod; if(stream == NULL) { return NULL; } stream->inputBufferSize = maxRequired; stream->inputBuffer = (short *)calloc(maxRequired, sizeof(short)*numChannels); if(stream->inputBuffer == NULL) { sonicDestroyStream(stream); return NULL; } stream->outputBufferSize = maxRequired; stream->outputBuffer = (short *)calloc(maxRequired, sizeof(short)*numChannels); if(stream->outputBuffer == NULL) { sonicDestroyStream(stream); return NULL; } stream->pitchBufferSize = maxRequired; stream->pitchBuffer = (short *)calloc(maxRequired, sizeof(short)*numChannels); if(stream->pitchBuffer == NULL) { sonicDestroyStream(stream); return NULL; } stream->downSampleBuffer = (short *)calloc(maxRequired, sizeof(short)); stream->speed = 1.0f; stream->pitch = 1.0f; stream->volume = 1.0f; stream->sampleRate = sampleRate; stream->numChannels = numChannels; stream->minPeriod = minPeriod; stream->maxPeriod = maxPeriod; stream->maxRequired = maxRequired; return stream; } /* Enlarge the output buffer if needed. */ static int enlargeOutputBufferIfNeeded( sonicStream stream, int numSamples) { if(stream->numOutputSamples + numSamples > stream->outputBufferSize) { stream->outputBufferSize += (stream->outputBufferSize >> 1) + numSamples; stream->outputBuffer = (short *)realloc(stream->outputBuffer, stream->outputBufferSize*sizeof(short)*stream->numChannels); if(stream->outputBuffer == NULL) { return 0; } } return 1; } /* Enlarge the input buffer if needed. */ static int enlargeInputBufferIfNeeded( sonicStream stream, int numSamples) { if(stream->numInputSamples + numSamples > stream->inputBufferSize) { stream->inputBufferSize += (stream->inputBufferSize >> 1) + numSamples; stream->inputBuffer = (short *)realloc(stream->inputBuffer, stream->inputBufferSize*sizeof(short)*stream->numChannels); if(stream->inputBuffer == NULL) { return 0; } } return 1; } /* Add the input samples to the input buffer. */ static int addFloatSamplesToInputBuffer( sonicStream stream, float *samples, int numSamples) { short *buffer; int count = numSamples*stream->numChannels; if(numSamples == 0) { return 1; } if(!enlargeInputBufferIfNeeded(stream, numSamples)) { return 0; } buffer = stream->inputBuffer + stream->numInputSamples*stream->numChannels; while(count--) { *buffer++ = (*samples++)*32767.0f; } stream->numInputSamples += numSamples; return 1; } /* Add the input samples to the input buffer. */ static int addShortSamplesToInputBuffer( sonicStream stream, short *samples, int numSamples) { if(numSamples == 0) { return 1; } if(!enlargeInputBufferIfNeeded(stream, numSamples)) { return 0; } memcpy(stream->inputBuffer + stream->numInputSamples*stream->numChannels, samples, numSamples*sizeof(short)*stream->numChannels); stream->numInputSamples += numSamples; return 1; } /* Add the input samples to the input buffer. */ static int addUnsignedCharSamplesToInputBuffer( sonicStream stream, unsigned char *samples, int numSamples) { short *buffer; int count = numSamples*stream->numChannels; if(numSamples == 0) { return 1; } if(!enlargeInputBufferIfNeeded(stream, numSamples)) { return 0; } buffer = stream->inputBuffer + stream->numInputSamples*stream->numChannels; while(count--) { *buffer++ = (*samples++ - 128) << 8; } stream->numInputSamples += numSamples; return 1; } /* Remove input samples that we have already processed. */ static void removeInputSamples( sonicStream stream, int position) { int remainingSamples = stream->numInputSamples - position; if(remainingSamples > 0) { memmove(stream->inputBuffer, stream->inputBuffer + position*stream->numChannels, remainingSamples*sizeof(short)*stream->numChannels); } stream->numInputSamples = remainingSamples; } /* Just copy from the array to the output buffer */ static int copyToOutput( sonicStream stream, short *samples, int numSamples) { if(!enlargeOutputBufferIfNeeded(stream, numSamples)) { return 0; } memcpy(stream->outputBuffer + stream->numOutputSamples*stream->numChannels, samples, numSamples*sizeof(short)*stream->numChannels); stream->numOutputSamples += numSamples; return numSamples; } /* Just copy from the input buffer to the output buffer. Return 0 if we fail to resize the output buffer. Otherwise, return numSamples */ static int copyInputToOutput( sonicStream stream, int position) { int numSamples = stream->remainingInputToCopy; if(numSamples > stream->maxRequired) { numSamples = stream->maxRequired; } if(!copyToOutput(stream, stream->inputBuffer + position*stream->numChannels, numSamples)) { return 0; } stream->remainingInputToCopy -= numSamples; return numSamples; } /* Read data out of the stream. Sometimes no data will be available, and zero is returned, which is not an error condition. */ int sonicReadFloatFromStream( sonicStream stream, float *samples, int maxSamples) { int numSamples = stream->numOutputSamples; int remainingSamples = 0; short *buffer; int count; if(numSamples == 0) { return 0; } if(numSamples > maxSamples) { remainingSamples = numSamples - maxSamples; numSamples = maxSamples; } buffer = stream->outputBuffer; count = numSamples*stream->numChannels; while(count--) { *samples++ = (*buffer++)/32767.0f; } if(remainingSamples > 0) { memmove(stream->outputBuffer, stream->outputBuffer + numSamples*stream->numChannels, remainingSamples*sizeof(short)*stream->numChannels); } stream->numOutputSamples = remainingSamples; return numSamples; } /* Read short data out of the stream. Sometimes no data will be available, and zero is returned, which is not an error condition. */ int sonicReadShortFromStream( sonicStream stream, short *samples, int maxSamples) { int numSamples = stream->numOutputSamples; int remainingSamples = 0; if(numSamples == 0) { return 0; } if(numSamples > maxSamples) { remainingSamples = numSamples - maxSamples; numSamples = maxSamples; } memcpy(samples, stream->outputBuffer, numSamples*sizeof(short)*stream->numChannels); if(remainingSamples > 0) { memmove(stream->outputBuffer, stream->outputBuffer + numSamples*stream->numChannels, remainingSamples*sizeof(short)*stream->numChannels); } stream->numOutputSamples = remainingSamples; return numSamples; } /* Read unsigned char data out of the stream. Sometimes no data will be available, and zero is returned, which is not an error condition. */ int sonicReadUnsignedCharFromStream( sonicStream stream, unsigned char *samples, int maxSamples) { int numSamples = stream->numOutputSamples; int remainingSamples = 0; short *buffer; int count; if(numSamples == 0) { return 0; } if(numSamples > maxSamples) { remainingSamples = numSamples - maxSamples; numSamples = maxSamples; } buffer = stream->outputBuffer; count = numSamples*stream->numChannels; while(count--) { *samples++ = (char)((*buffer++) >> 8) + 128; } if(remainingSamples > 0) { memmove(stream->outputBuffer, stream->outputBuffer + numSamples*stream->numChannels, remainingSamples*sizeof(short)*stream->numChannels); } stream->numOutputSamples = remainingSamples; return numSamples; } /* Force the sonic stream to generate output using whatever data it currently has. No extra delay will be added to the output, but flushing in the middle of words could introduce distortion. */ int sonicFlushStream( sonicStream stream) { int maxRequired = stream->maxRequired; int numSamples = stream->numInputSamples; int remainingSpace, numOutputSamples, expectedSamples; if(numSamples == 0) { return 1; } if(numSamples >= maxRequired && !sonicWriteShortToStream(stream, NULL, 0)) { return 0; } numSamples = stream->numInputSamples; /* Now numSamples < maxRequired */ if(numSamples == 0) { return 1; } remainingSpace = maxRequired - numSamples; memset(stream->inputBuffer + numSamples*stream->numChannels, 0, remainingSpace*sizeof(short)*stream->numChannels); stream->numInputSamples = maxRequired; numOutputSamples = stream->numOutputSamples; if(!sonicWriteShortToStream(stream, NULL, 0)) { return 0; } /* Throw away any extra samples we generated due to the silence we added */ expectedSamples = (int)(numSamples*stream->speed + 0.5); if(stream->numOutputSamples > numOutputSamples + expectedSamples) { stream->numOutputSamples = numOutputSamples + expectedSamples; } return 1; } /* Return the number of samples in the output buffer */ int sonicSamplesAvailable( sonicStream stream) { return stream->numOutputSamples; } /* If skip is greater than one, average skip samples togther and write them to the down-sample buffer. If numChannels is greater than one, mix the channels together as we down sample. */ static void downSampleInput( sonicStream stream, short *samples, int skip) { int numSamples = stream->maxRequired/skip; int samplesPerValue = stream->numChannels*skip; int i, j; int value; short *downSamples = stream->downSampleBuffer; for(i = 0; i < numSamples; i++) { value = 0; for(j = 0; j < samplesPerValue; j++) { value += *samples++; } value /= samplesPerValue; *downSamples++ = value; } } /* Find the best frequency match in the range, and given a sample skip multiple. For now, just find the pitch of the first channel. */ static int findPitchPeriodInRange( short *samples, int minPeriod, int maxPeriod, int *retMinDiff, int *retMaxDiff) { int period, bestPeriod = 0; short *s, *p, sVal, pVal; unsigned long diff, minDiff = 1, maxDiff = 0; int i; for(period = minPeriod; period <= maxPeriod; period++) { diff = 0; s = samples; p = samples + period; for(i = 0; i < period; i++) { sVal = *s++; pVal = *p++; diff += sVal >= pVal? (unsigned short)(sVal - pVal) : (unsigned short)(pVal - sVal); } /* Note that the highest number of samples we add into diff will be less than 256, since we skip samples. Thus, diff is a 24 bit number, and we can safely multiply by numSamples without overflow */ if(diff*bestPeriod < minDiff*period) { minDiff = diff; bestPeriod = period; } if(diff*bestPeriod > maxDiff*period) { maxDiff = diff; } } *retMinDiff = minDiff; *retMaxDiff = maxDiff; return bestPeriod; } /* At abrupt ends of voiced words, we can have pitch periods that are better aproximated by the previous pitch period estimate. Try to detect this case. */ static int prevPeriodBetter( sonicStream stream, int period, int minDiff, int maxDiff) { if(maxDiff*3/2 < stream->prevMaxDiff && (maxDiff*3.0f)*stream->prevMinDiff < (float)stream->prevMaxDiff*minDiff*2) { return 1; } return 0; } /* Find the pitch period. This is a critical step, and we may have to try multiple ways to get a good answer. This version uses AMDF. To improve speed, we down sample by an integer factor get in the 11KHz range, and then do it again with a narrower frequency range without down sampling */ static int findPitchPeriod( sonicStream stream, short *samples) { int minPeriod = stream->minPeriod; int maxPeriod = stream->maxPeriod; int sampleRate = stream->sampleRate; int minDiff, maxDiff, retPeriod; int skip = 1; int period; if(sampleRate > SONIC_AMDF_FREQ) { skip = sampleRate/SONIC_AMDF_FREQ; } if(stream->numChannels == 1 && skip == 1) { period = findPitchPeriodInRange(samples, minPeriod, maxPeriod, &minDiff, &maxDiff); } else { downSampleInput(stream, samples, skip); period = findPitchPeriodInRange(stream->downSampleBuffer, minPeriod/skip, maxPeriod/skip, &minDiff, &maxDiff); if(skip != 1) { period *= skip; minPeriod = period - (skip << 2); maxPeriod = period + (skip << 2); if(minPeriod < stream->minPeriod) { minPeriod = stream->minPeriod; } if(maxPeriod > stream->maxPeriod) { maxPeriod = stream->maxPeriod; } if(stream->numChannels == 1) { period = findPitchPeriodInRange(samples, minPeriod, maxPeriod, &minDiff, &maxDiff); } else { downSampleInput(stream, samples, 1); period = findPitchPeriodInRange(stream->downSampleBuffer, minPeriod, maxPeriod, &minDiff, &maxDiff); } } } if(prevPeriodBetter(stream, period, minDiff, maxDiff)) { retPeriod = stream->prevPeriod; } else { retPeriod = period; } stream->prevMinDiff = minDiff; stream->prevMaxDiff = maxDiff; stream->prevPeriod = period; return retPeriod; } /* Overlap two sound segments, ramp the volume of one down, while ramping the other one from zero up, and add them, storing the result at the output. */ static void overlapAdd( int numSamples, int numChannels, short *out, short *rampDown, short *rampUp) { short *o, *u, *d; int i, t; for(i = 0; i < numChannels; i++) { o = out + i; u = rampUp + i; d = rampDown + i; for(t = 0; t < numSamples; t++) { *o = (*d*(numSamples - t) + *u*t)/numSamples; o += numChannels; d += numChannels; u += numChannels; } } } /* Overlap two sound segments, ramp the volume of one down, while ramping the other one from zero up, and add them, storing the result at the output. */ static void overlapAddWithSeparation( int numSamples, int numChannels, int separation, short *out, short *rampDown, short *rampUp) { short *o, *u, *d; int i, t; for(i = 0; i < numChannels; i++) { o = out + i; u = rampUp + i; d = rampDown + i; for(t = 0; t < numSamples + separation; t++) { if(t < separation) { *o = *d*(numSamples - t)/numSamples; d += numChannels; } else if(t < numSamples) { *o = (*d*(numSamples - t) + *u*(t - separation))/numSamples; d += numChannels; u += numChannels; } else { *o = *u*(t - separation)/numSamples; u += numChannels; } o += numChannels; } } } /* Just move the new samples in the output buffer to the pitch bufer */ static int moveNewSamplesToPitchBuffer( sonicStream stream, int originalNumOutputSamples) { int numSamples = stream->numOutputSamples - originalNumOutputSamples; int numChannels = stream->numChannels; if(stream->numPitchSamples + numSamples > stream->pitchBufferSize) { stream->pitchBufferSize += (stream->pitchBufferSize >> 1) + numSamples; stream->pitchBuffer = (short *)realloc(stream->pitchBuffer, stream->pitchBufferSize*sizeof(short)*numChannels); if(stream->pitchBuffer == NULL) { return 0; } } memcpy(stream->pitchBuffer + stream->numPitchSamples*numChannels, stream->outputBuffer + originalNumOutputSamples*numChannels, numSamples*sizeof(short)*numChannels); stream->numOutputSamples = originalNumOutputSamples; stream->numPitchSamples += numSamples; return 1; } /* Remove processed samples from the pitch buffer. */ static void removePitchSamples( sonicStream stream, int numSamples) { int numChannels = stream->numChannels; short *source = stream->pitchBuffer + numSamples*numChannels; if(numSamples == 0) { return; } if(numSamples != stream->numPitchSamples) { memmove(stream->pitchBuffer, source, (stream->numPitchSamples - numSamples)*sizeof(short)*numChannels); } stream->numPitchSamples -= numSamples; } /* Change the pitch. The latency this introduces could be reduced by looking at past samples to determine pitch, rather than future. */ static int adjustPitch( sonicStream stream, int originalNumOutputSamples) { float pitch = stream->pitch; int numChannels = stream->numChannels; int period, newPeriod, separation; int position = 0; short *out, *rampDown, *rampUp; if(stream->numOutputSamples == originalNumOutputSamples) { return 1; } if(!moveNewSamplesToPitchBuffer(stream, originalNumOutputSamples)) { return 0; } while(stream->numPitchSamples - position >= stream->maxRequired) { period = findPitchPeriod(stream, stream->pitchBuffer + position*numChannels); newPeriod = period/pitch; if(!enlargeOutputBufferIfNeeded(stream, newPeriod)) { return 0; } out = stream->outputBuffer + stream->numOutputSamples*numChannels; if(pitch >= 1.0f) { rampDown = stream->pitchBuffer + position*numChannels; rampUp = stream->pitchBuffer + (position + period - newPeriod)*numChannels; overlapAdd(newPeriod, numChannels, out, rampDown, rampUp); } else { rampDown = stream->pitchBuffer + position*numChannels; rampUp = stream->pitchBuffer + position*numChannels; separation = newPeriod - period; overlapAddWithSeparation(period, numChannels, separation, out, rampDown, rampUp); } stream->numOutputSamples += newPeriod; position += period; } removePitchSamples(stream, position); return 1; } /* Skip over a pitch period, and copy period/speed samples to the output */ static int skipPitchPeriod( sonicStream stream, short *samples, float speed, int period) { long newSamples; int numChannels = stream->numChannels; if(speed >= 2.0f) { newSamples = period/(speed - 1.0f); } else if(speed > 1.0f) { newSamples = period; stream->remainingInputToCopy = period*(2.0f - speed)/(speed - 1.0f); } if(!enlargeOutputBufferIfNeeded(stream, newSamples)) { return 0; } overlapAdd(newSamples, numChannels, stream->outputBuffer + stream->numOutputSamples*numChannels, samples, samples + period*numChannels); stream->numOutputSamples += newSamples; return newSamples; } /* Insert a pitch period, and determine how much input to copy directly. */ static int insertPitchPeriod( sonicStream stream, short *samples, float speed, int period) { long newSamples; short *out; int numChannels = stream->numChannels; if(speed < 0.5f) { newSamples = period*speed/(1.0f - speed); } else { newSamples = period; stream->remainingInputToCopy = period*(2.0f*speed - 1.0f)/(1.0f - speed); } if(!enlargeOutputBufferIfNeeded(stream, period + newSamples)) { return 0; } out = stream->outputBuffer + stream->numOutputSamples*numChannels; memcpy(out, samples, period*sizeof(short)*numChannels); out = stream->outputBuffer + (stream->numOutputSamples + period)*numChannels; overlapAdd(newSamples, numChannels, out, samples + period*numChannels, samples); stream->numOutputSamples += period + newSamples; return newSamples; } /* Resample as many pitch periods as we have buffered on the input. Return 0 if we fail to resize an input or output buffer. Also scale the output by the volume. */ static int changeSpeed( sonicStream stream, float speed) { short *samples; int numSamples = stream->numInputSamples; int position = 0, period, newSamples; int maxRequired = stream->maxRequired; if(stream->numInputSamples < maxRequired) { return 1; } do { if(stream->remainingInputToCopy > 0) { newSamples = copyInputToOutput(stream, position); position += newSamples; } else { samples = stream->inputBuffer + position*stream->numChannels; period = findPitchPeriod(stream, samples); if(speed > 1.0) { newSamples = skipPitchPeriod(stream, samples, speed, period); position += period + newSamples; } else { newSamples = insertPitchPeriod(stream, samples, speed, period); position += newSamples; } } if(newSamples == 0) { return 0; /* Failed to resize output buffer */ } } while(position + maxRequired <= numSamples); removeInputSamples(stream, position); return 1; } /* Resample as many pitch periods as we have buffered on the input. Return 0 if we fail to resize an input or output buffer. Also scale the output by the volume. */ static int processStreamInput( sonicStream stream) { int originalNumOutputSamples = stream->numOutputSamples; float speed = stream->speed/stream->pitch; if(speed > 1.00001 || speed < 0.99999) { changeSpeed(stream, speed); } else { if(!copyToOutput(stream, stream->inputBuffer, stream->numInputSamples)) { return 0; } stream->numInputSamples = 0; } if(stream->pitch != 1.0f) { if(!adjustPitch(stream, originalNumOutputSamples)) { return 0; } } if(stream->volume != 1.0f) { /* Adjust output volume. */ scaleSamples(stream->outputBuffer + originalNumOutputSamples*stream->numChannels, (stream->numOutputSamples - originalNumOutputSamples)*stream->numChannels, stream->volume); } return 1; } /* Write floating point data to the input buffer and process it. */ int sonicWriteFloatToStream( sonicStream stream, float *samples, int numSamples) { if(!addFloatSamplesToInputBuffer(stream, samples, numSamples)) { return 0; } return processStreamInput(stream); } /* Simple wrapper around sonicWriteFloatToStream that does the short to float conversion for you. */ int sonicWriteShortToStream( sonicStream stream, short *samples, int numSamples) { if(!addShortSamplesToInputBuffer(stream, samples, numSamples)) { return 0; } return processStreamInput(stream); } /* Simple wrapper around sonicWriteFloatToStream that does the unsigned char to float conversion for you. */ int sonicWriteUnsignedCharToStream( sonicStream stream, unsigned char *samples, int numSamples) { if(!addUnsignedCharSamplesToInputBuffer(stream, samples, numSamples)) { return 0; } return processStreamInput(stream); } /* This is a non-stream oriented interface to just change the speed of a sound sample */ int sonicChangeFloatSpeed( float *samples, int numSamples, float speed, float pitch, float volume, int sampleRate, int numChannels) { sonicStream stream = sonicCreateStream(sampleRate, numChannels); sonicSetSpeed(stream, speed); sonicSetPitch(stream, pitch); sonicSetVolume(stream, volume); sonicWriteFloatToStream(stream, samples, numSamples); sonicFlushStream(stream); numSamples = sonicSamplesAvailable(stream); sonicReadFloatFromStream(stream, samples, numSamples); sonicDestroyStream(stream); return numSamples; } /* This is a non-stream oriented interface to just change the speed of a sound sample */ int sonicChangeShortSpeed( short *samples, int numSamples, float speed, float pitch, float volume, int sampleRate, int numChannels) { sonicStream stream = sonicCreateStream(sampleRate, numChannels); sonicSetSpeed(stream, speed); sonicSetPitch(stream, pitch); sonicSetVolume(stream, volume); sonicWriteShortToStream(stream, samples, numSamples); sonicFlushStream(stream); numSamples = sonicSamplesAvailable(stream); sonicReadShortFromStream(stream, samples, numSamples); sonicDestroyStream(stream); return numSamples; } #endif // INCLUDE_SONIC praat-6.0.04/external/espeak/sonic.h000066400000000000000000000152021261542461700172760ustar00rootroot00000000000000/* Sonic library Copyright 2010 Bill Cox This file is part of the Sonic Library. The Sonic Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ /* The Sonic Library implements Pitch Based Resampling, which is a new algorithm invented by Bill Cox for the specific purpose of speeding up speech by high factors at high quality. It generates smooth speech at speed up factors as high as 6X, possibly more. It is also capable of slowing down speech, and generates high quality results regardless of the speed up or slow down factor. For speeding up speech by 2X or more, the following equation is used: newSamples = period/(speed - 1.0) scale = 1.0/newSamples; where period is the current pitch period, determined using AMDF or any other pitch estimator, and speed is the speedup factor. If the current position in the input stream is pointed to by "samples", and the current output stream position is pointed to by "out", then newSamples number of samples can be generated with: out[t] = (samples[t]*(newSamples - t) + samples[t + period]*t)/newSamples; where t = 0 to newSamples - 1. For speed factors < 2X, an algorithm similar to PICOLA is used. The above algorithm is first used to double the speed of one pitch period. Then, enough input is directly copied from the input to the output to achieve the desired speed up facter, where 1.0 < speed < 2.0. The amount of data copied is derived: speed = (2*period + length)/(period + length) speed*length + speed*period = 2*period + length length(speed - 1) = 2*period - speed*period length = period*(2 - speed)/(speed - 1) For slowing down speech where 0.5 < speed < 1.0, a pitch period is inserted into the output twice, and length of input is copied from the input to the output until the output desired speed is reached. The length of data copied is: length = period*(speed - 0.5)/(1 - speed) For slow down factors between 0.5 and 0.5, no data is copied, and an algorithm similar to high speed factors is used. */ #ifdef __cplusplus extern "C" { #endif /* This specifies the range of voice pitches we try to match. Note that if we go lower than 65, we could overflow in findPitchInRange */ #define SONIC_MIN_PITCH 65 #define SONIC_MAX_PITCH 400 /* These are used to down-sample some inputs to improve speed */ #define SONIC_AMDF_FREQ 4000 struct sonicStreamStruct; typedef struct sonicStreamStruct *sonicStream; /* For all of the following functions, numChannels is multiplied by numSamples to determine the actual number of values read or returned. */ /* Create a sonic stream. Return NULL only if we are out of memory and cannot allocate the stream. Set numChannels to 1 for mono, and 2 for stereo. */ sonicStream sonicCreateStream(int sampleRate, int numChannels); /* Destroy the sonic stream. */ void sonicDestroyStream(sonicStream stream); /* Use this to write floating point data to be speed up or down into the stream. Values must be between -1 and 1. Return 0 if memory realloc failed, otherwise 1 */ int sonicWriteFloatToStream(sonicStream stream, float *samples, int numSamples); /* Use this to write 16-bit data to be speed up or down into the stream. Return 0 if memory realloc failed, otherwise 1 */ int sonicWriteShortToStream(sonicStream stream, short *samples, int numSamples); /* Use this to write 8-bit unsigned data to be speed up or down into the stream. Return 0 if memory realloc failed, otherwise 1 */ int sonicWriteUnsignedCharToStream(sonicStream stream, unsigned char *samples, int numSamples); /* Use this to read floating point data out of the stream. Sometimes no data will be available, and zero is returned, which is not an error condition. */ int sonicReadFloatFromStream(sonicStream stream, float *samples, int maxSamples); /* Use this to read 16-bit data out of the stream. Sometimes no data will be available, and zero is returned, which is not an error condition. */ int sonicReadShortFromStream(sonicStream stream, short *samples, int maxSamples); /* Use this to read 8-bit unsigned data out of the stream. Sometimes no data will be available, and zero is returned, which is not an error condition. */ int sonicReadUnsignedCharFromStream(sonicStream stream, unsigned char *samples, int maxSamples); /* Force the sonic stream to generate output using whatever data it currently has. No extra delay will be added to the output, but flushing in the middle of words could introduce distortion. */ int sonicFlushStream(sonicStream stream); /* Return the number of samples in the output buffer */ int sonicSamplesAvailable(sonicStream stream); /* Get the speed of the stream. */ float sonicGetSpeed(sonicStream stream); /* Set the speed of the stream. */ void sonicSetSpeed(sonicStream stream, float speed); /* Get the pitch of the stream. */ float sonicGetPitch(sonicStream stream); /* Set the pitch of the stream. */ void sonicSetPitch(sonicStream stream, float pitch); /* Get the scaling factor of the stream. */ float sonicGetVolume(sonicStream stream); /* Set the scaling factor of the stream. */ void sonicSetVolume(sonicStream stream, float volume); /* Get the sample rate of the stream. */ int sonicGetSampleRate(sonicStream stream); /* Get the number of channels. */ int sonicGetNumChannels(sonicStream stream); /* This is a non-stream oriented interface to just change the speed of a sound sample. It works in-place on the sample array, so there must be at least speed*numSamples available space in the array. Returns the new number of samples. */ int sonicChangeFloatSpeed(float *samples, int numSamples, float speed, float pitch, float volume, int sampleRate, int numChannels); /* This is a non-stream oriented interface to just change the speed of a sound sample. It works in-place on the sample array, so there must be at least speed*numSamples available space in the array. Returns the new number of samples. */ int sonicChangeShortSpeed(short *samples, int numSamples, float speed, float pitch, float volume, int sampleRate, int numChannels); #ifdef __cplusplus } #endif praat-6.0.04/external/espeak/speak_lib.cpp000066400000000000000000000755651261542461700204710ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2005 to 2011 by Jonathan Duddington * * email: jonsd@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write see: * * . * ***************************************************************************/ #include "StdAfx.h" #include "stdio.h" #include "ctype.h" #include "string.h" #include "stdlib.h" #include "wchar.h" #include "locale.h" #include #include #include "speech.h" #include #ifndef PLATFORM_WINDOWS #include #endif #include "speak_lib.h" #include "phoneme.h" #include "synthesize.h" #include "voice.h" #include "translate.h" #include "debug.h" #include "fifo.h" #include "event.h" #include "wave.h" unsigned char *outbuf=NULL; espeak_EVENT *event_list=NULL; int event_list_ix=0; int n_event_list; long count_samples; void* my_audio=NULL; static unsigned int my_unique_identifier=0; static void* my_user_data=NULL; static espeak_AUDIO_OUTPUT my_mode=AUDIO_OUTPUT_SYNCHRONOUS; static int synchronous_mode = 1; static int out_samplerate = 0; static int voice_samplerate = 22050; t_espeak_callback* synth_callback = NULL; int (* uri_callback)(int, const char *, const char *) = NULL; int (* phoneme_callback)(const char *) = NULL; char path_home[N_PATH_HOME]; // this is the espeak-data directory extern int saved_parameters[N_SPEECH_PARAM]; //Parameters saved on synthesis start void WVoiceChanged(voice_t *wvoice) {//================================= // Voice change in wavegen voice_samplerate = wvoice->samplerate; } #ifdef USE_ASYNC static int dispatch_audio(short* outbuf, int length, espeak_EVENT* event) {//====================================================================== ENTER("dispatch_audio"); int a_wave_can_be_played = fifo_is_command_enabled(); #ifdef DEBUG_ENABLED SHOW("*** dispatch_audio > uid=%d, [write=%p (%d bytes)], sample=%d, a_wave_can_be_played = %d\n", (event) ? event->unique_identifier : 0, wave_test_get_write_buffer(), 2*length, (event) ? event->sample : 0, a_wave_can_be_played); #endif switch(my_mode) { case AUDIO_OUTPUT_PLAYBACK: { int event_type=0; if(event) { event_type = event->type; } if(event_type == espeakEVENT_SAMPLERATE) { voice_samplerate = event->id.number; if(out_samplerate != voice_samplerate) { if(out_samplerate != 0) { // sound was previously open with a different sample rate wave_close(my_audio); // sleep(1); } out_samplerate = voice_samplerate; wave_init(voice_samplerate); wave_set_callback_is_output_enabled( fifo_is_command_enabled); my_audio = wave_open("alsa"); event_init(); } } if (outbuf && length && a_wave_can_be_played) { wave_write (my_audio, (char*)outbuf, 2*length); } while(a_wave_can_be_played) { // TBD: some event are filtered here but some insight might be given // TBD: in synthesise.cpp for avoiding to create WORDs with size=0. // TBD: For example sentence "or ALT)." returns three words // "or", "ALT" and "". // TBD: the last one has its size=0. if (event && (event->type == espeakEVENT_WORD) && (event->length==0)) { break; } espeak_ERROR a_error = event_declare(event); if (a_error != EE_BUFFER_FULL) { break; } SHOW_TIME("dispatch_audio > EE_BUFFER_FULL\n"); usleep(10000); a_wave_can_be_played = fifo_is_command_enabled(); } } break; case AUDIO_OUTPUT_RETRIEVAL: if (synth_callback) { synth_callback(outbuf, length, event); } break; case AUDIO_OUTPUT_SYNCHRONOUS: case AUDIO_OUTPUT_SYNCH_PLAYBACK: break; } if (!a_wave_can_be_played) { SHOW_TIME("dispatch_audio > synth must be stopped!\n"); } SHOW_TIME("LEAVE dispatch_audio\n"); return (a_wave_can_be_played==0); // 1 = stop synthesis } static int create_events(short* outbuf, int length, espeak_EVENT* event, uint32_t the_write_pos) {//===================================================================== int finished; int i=0; // The audio data are written to the output device. // The list of events in event_list (index: event_list_ix) is read: // Each event is declared to the "event" object which stores them internally. // The event object is responsible of calling the external callback // as soon as the relevant audio sample is played. do { // for each event espeak_EVENT* event; if (event_list_ix == 0) { event = NULL; } else { event = event_list + i; #ifdef DEBUG_ENABLED SHOW("Synthesize: event->sample(%d) + %d = %d\n", event->sample, the_write_pos, event->sample + the_write_pos); #endif event->sample += the_write_pos; } #ifdef DEBUG_ENABLED SHOW("*** Synthesize: i=%d (event_list_ix=%d), length=%d\n",i,event_list_ix,length); #endif finished = dispatch_audio((short *)outbuf, length, event); length = 0; // the wave data are played once. i++; } while((i < event_list_ix) && !finished); return finished; } int sync_espeak_terminated_msg( uint32_t unique_identifier, void* user_data) {//===================================================================== ENTER("sync_espeak_terminated_msg"); int finished=0; memset(event_list, 0, 2*sizeof(espeak_EVENT)); event_list[0].type = espeakEVENT_MSG_TERMINATED; event_list[0].unique_identifier = unique_identifier; event_list[0].user_data = user_data; event_list[1].type = espeakEVENT_LIST_TERMINATED; event_list[1].unique_identifier = unique_identifier; event_list[1].user_data = user_data; if (my_mode==AUDIO_OUTPUT_PLAYBACK) { while(1) { espeak_ERROR a_error = event_declare(event_list); if (a_error != EE_BUFFER_FULL) { break; } SHOW_TIME("sync_espeak_terminated_msg > EE_BUFFER_FULL\n"); usleep(10000); } } else { if (synth_callback) { finished=synth_callback(NULL,0,event_list); } } return finished; } #endif static void select_output(espeak_AUDIO_OUTPUT output_type) {//======================================================= my_mode = output_type; my_audio = NULL; synchronous_mode = 1; option_waveout = 1; // inhibit portaudio callback from wavegen.cpp out_samplerate = 0; switch(my_mode) { case AUDIO_OUTPUT_PLAYBACK: // wave_init() is now called just before the first wave_write() synchronous_mode = 0; break; case AUDIO_OUTPUT_RETRIEVAL: synchronous_mode = 0; break; case AUDIO_OUTPUT_SYNCHRONOUS: break; case AUDIO_OUTPUT_SYNCH_PLAYBACK: option_waveout = 0; WavegenInitSound(); break; } } // end of select_output int GetFileLength(const char *filename) {//==================================== struct stat statbuf; if(stat(filename,&statbuf) != 0) return(0); if((statbuf.st_mode & S_IFMT) == S_IFDIR) // if(S_ISDIR(statbuf.st_mode)) return(-2); // a directory return(statbuf.st_size); } // end of GetFileLength char *Alloc(int size) {//================== char *p; if((p = (char *)malloc(size)) == NULL) fprintf(stderr,"Can't allocate memory\n"); // I was told that size+1 fixes a crash on 64-bit systems return(p); } void Free(void *ptr) {//================= if(ptr != NULL) free(ptr); } #ifdef DATA_FROM_SOURCECODE_FILES static void init_path(const char *path) { (void) path; } #else static void init_path(const char *path) {//==================================== #ifdef PLATFORM_WINDOWS HKEY RegKey; unsigned long size; unsigned long var_type; char *env; unsigned char buf[sizeof(path_home)-13]; if(path != NULL) { sprintf(path_home,"%s/espeak-data",path); return; } if((env = getenv("ESPEAK_DATA_PATH")) != NULL) { sprintf(path_home,"%s/espeak-data",env); if(GetFileLength(path_home) == -2) return; // an espeak-data directory exists } buf[0] = 0; RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Speech\\Voices\\Tokens\\eSpeak", 0, KEY_READ, &RegKey); size = sizeof(buf); var_type = REG_SZ; RegQueryValueExA(RegKey, "path", 0, &var_type, buf, &size); sprintf(path_home,"%s\\espeak-data",buf); #else char *env; if(path != NULL) { snprintf(path_home,sizeof(path_home),"%s/espeak-data",path); return; } // check for environment variable if((env = getenv("ESPEAK_DATA_PATH")) != NULL) { snprintf(path_home,sizeof(path_home),"%s/espeak-data",env); if(GetFileLength(path_home) == -2) return; // an espeak-data directory exists } snprintf(path_home,sizeof(path_home),"%s/espeak-data",getenv("HOME")); if(access(path_home,R_OK) != 0) { strcpy(path_home,PATH_ESPEAK_DATA); } #endif } #endif static int initialise(int control) {//=============================== int param; int result; LoadConfig(); WavegenInit(22050,0); // 22050 if((result = LoadPhData()) != 1) { if(result == -1) { fprintf(stderr,"Failed to load espeak-data\n"); if((control & espeakINITIALIZE_DONT_EXIT) == 0) { exit(1); } } else fprintf(stderr,"Wrong version of espeak-data 0x%x (expects 0x%x) at %s\n",result,version_phdata,path_home); } memset(¤t_voice_selected,0,sizeof(current_voice_selected)); SetVoiceStack(NULL, ""); SynthesizeInit(); InitNamedata(); for(param=0; param uid=%d, flags=%d, >>>text=%s<<<\n", unique_identifier, flags, text); } #endif if((outbuf==NULL) || (event_list==NULL)) return(EE_INTERNAL_ERROR); // espeak_Initialize() has not been called option_multibyte = flags & 7; option_ssml = flags & espeakSSML; option_phoneme_input = flags & espeakPHONEMES; option_endpause = flags & espeakENDPAUSE; count_samples = 0; #ifdef USE_ASYNC if(my_mode == AUDIO_OUTPUT_PLAYBACK) { a_write_pos = wave_get_write_position(my_audio); } #endif if(translator == NULL) { SetVoiceByName("default"); } SpeakNextClause(NULL,text,0); if(my_mode == AUDIO_OUTPUT_SYNCH_PLAYBACK) { for(;;) { #ifdef PLATFORM_WINDOWS Sleep(300); // 0.3s #else #ifdef USE_NANOSLEEP struct timespec period; struct timespec remaining; period.tv_sec = 0; period.tv_nsec = 300000000; // 0.3 sec nanosleep(&period,&remaining); #else // sleep(1); #endif #endif if(SynthOnTimer() != 0) break; } return(EE_OK); } for(;;) { #ifdef DEBUG_ENABLED SHOW("Synthesize > %s\n","for (next)"); #endif out_ptr = outbuf; out_end = &outbuf[outbuf_size]; event_list_ix = 0; WavegenFill(0); length = (out_ptr - outbuf)/2; count_samples += length; event_list[event_list_ix].type = espeakEVENT_LIST_TERMINATED; // indicates end of event list event_list[event_list_ix].unique_identifier = my_unique_identifier; event_list[event_list_ix].user_data = my_user_data; count_buffers++; if (my_mode==AUDIO_OUTPUT_PLAYBACK) { #ifdef USE_ASYNC finished = create_events((short *)outbuf, length, event_list, a_write_pos); length = 0; // the wave data are played once. #endif } else { finished = synth_callback((short *)outbuf, length, event_list); } if(finished) { SpeakNextClause(NULL,0,2); // stop break; } if(Generate(phoneme_list,&n_phoneme_list,1)==0) { if(WcmdqUsed() == 0) { // don't process the next clause until the previous clause has finished generating speech. // This ensures that

::= * ::=
| * */ static void parse_integer(struct csa *csa) { int j, binary; /* parse the keyword 'general', 'integer', or 'binary' */ if (csa->token == T_GENERAL) binary = 0, scan_token(csa); else if (csa->token == T_INTEGER) binary = 0, scan_token(csa); else if (csa->token == T_BINARY) binary = 1, scan_token(csa); else xassert(csa != csa); /* parse list of variables (may be empty) */ while (csa->token == T_NAME) { /* find the corresponding column */ j = find_col(csa, csa->image); /* change kind of the variable */ glp_set_col_kind(csa->P, j, GLP_IV); /* set 0-1 bounds for the binary variable */ if (binary) { set_lower_bound(csa, j, 0.0); set_upper_bound(csa, j, 1.0); } scan_token(csa); } return; } int glp_read_lp(glp_prob *P, const glp_cpxcp *parm, const char *fname) { /* read problem data in CPLEX LP format */ glp_cpxcp _parm; struct csa _csa, *csa = &_csa; int ret; xprintf("Reading problem data from `%s'...\n", fname); if (parm == NULL) glp_init_cpxcp(&_parm), parm = &_parm; /* check control parameters */ check_parm("glp_read_lp", parm); /* initialize common storage area */ csa->P = P; csa->parm = parm; csa->fname = fname; csa->fp = NULL; if (setjmp(csa->jump)) { ret = 1; goto done; } csa->count = 0; csa->c = '\n'; csa->token = T_EOF; csa->image[0] = '\0'; csa->imlen = 0; csa->value = 0.0; csa->n_max = 100; csa->ind = xcalloc(1+csa->n_max, sizeof(int)); csa->val = xcalloc(1+csa->n_max, sizeof(double)); csa->flag = xcalloc(1+csa->n_max, sizeof(char)); memset(&csa->flag[1], 0, csa->n_max * sizeof(char)); csa->lb = xcalloc(1+csa->n_max, sizeof(double)); csa->ub = xcalloc(1+csa->n_max, sizeof(double)); /* erase problem object */ glp_erase_prob(P); glp_create_index(P); /* open input CPLEX LP file */ csa->fp = xfopen(fname, "r"); if (csa->fp == NULL) { xprintf("Unable to open `%s' - %s\n", fname, xerrmsg()); ret = 1; goto done; } /* scan very first token */ scan_token(csa); /* parse definition of the objective function */ if (!(csa->token == T_MINIMIZE || csa->token == T_MAXIMIZE)) error(csa, "`minimize' or `maximize' keyword missing\n"); parse_objective(csa); /* parse constraints section */ if (csa->token != T_SUBJECT_TO) error(csa, "constraints section missing\n"); parse_constraints(csa); /* parse optional bounds section */ if (csa->token == T_BOUNDS) parse_bounds(csa); /* parse optional general, integer, and binary sections */ while (csa->token == T_GENERAL || csa->token == T_INTEGER || csa->token == T_BINARY) parse_integer(csa); /* check for the keyword 'end' */ if (csa->token == T_END) scan_token(csa); else if (csa->token == T_EOF) warning(csa, "keyword `end' missing\n"); else error(csa, "symbol `%s' in wrong position\n", csa->image); /* nothing must follow the keyword 'end' (except comments) */ if (csa->token != T_EOF) error(csa, "extra symbol(s) detected beyond `end'\n"); /* set bounds of variables */ { int j, type; double lb, ub; for (j = 1; j <= P->n; j++) { lb = csa->lb[j]; ub = csa->ub[j]; if (lb == +DBL_MAX) lb = 0.0; /* default lb */ if (ub == -DBL_MAX) ub = +DBL_MAX; /* default ub */ if (lb == -DBL_MAX && ub == +DBL_MAX) type = GLP_FR; else if (ub == +DBL_MAX) type = GLP_LO; else if (lb == -DBL_MAX) type = GLP_UP; else if (lb != ub) type = GLP_DB; else type = GLP_FX; glp_set_col_bnds(csa->P, j, type, lb, ub); } } /* print some statistics */ xprintf("%d row%s, %d column%s, %d non-zero%s\n", P->m, P->m == 1 ? "" : "s", P->n, P->n == 1 ? "" : "s", P->nnz, P->nnz == 1 ? "" : "s"); if (glp_get_num_int(P) > 0) { int ni = glp_get_num_int(P); int nb = glp_get_num_bin(P); if (ni == 1) { if (nb == 0) xprintf("One variable is integer\n"); else xprintf("One variable is binary\n"); } else { xprintf("%d integer variables, ", ni); if (nb == 0) xprintf("none"); else if (nb == 1) xprintf("one"); else if (nb == ni) xprintf("all"); else xprintf("%d", nb); xprintf(" of which %s binary\n", nb == 1 ? "is" : "are"); } } xprintf("%d lines were read\n", csa->count); /* problem data has been successfully read */ glp_delete_index(P); glp_sort_matrix(P); ret = 0; done: if (csa->fp != NULL) xfclose(csa->fp); xfree(csa->ind); xfree(csa->val); xfree(csa->flag); xfree(csa->lb); xfree(csa->ub); if (ret != 0) glp_erase_prob(P); return ret; } /*********************************************************************** * NAME * * glp_write_lp - write problem data in CPLEX LP format * * SYNOPSIS * * int glp_write_lp(glp_prob *P, const glp_cpxcp *parm, const char * *fname); * * DESCRIPTION * * The routine glp_write_lp writes problem data in CPLEX LP format to * a text file. * * The parameter parm is a pointer to the structure glp_cpxcp, which * specifies control parameters used by the routine. If parm is NULL, * the routine uses default settings. * * The character string fname specifies a name of the text file to be * written. * * RETURNS * * If the operation was successful, the routine glp_write_lp returns * zero. Otherwise, it prints an error message and returns non-zero. */ #define csa csa1 struct csa { /* common storage area */ glp_prob *P; /* pointer to problem object */ const glp_cpxcp *parm; /* pointer to control parameters */ }; static int check_name(char *name) { /* check if specified name is valid for CPLEX LP format */ if (*name == '.') return 1; if (isdigit((unsigned char)*name)) return 1; for (; *name; name++) { if (!isalnum((unsigned char)*name) && strchr(CHAR_SET, (unsigned char)*name) == NULL) return 1; } return 0; /* name is ok */ } static void adjust_name(char *name) { /* attempt to adjust specified name to make it valid for CPLEX LP format */ for (; *name; name++) { if (*name == ' ') *name = '_'; else if (*name == '-') *name = '~'; else if (*name == '[') *name = '('; else if (*name == ']') *name = ')'; } return; } static char *row_name(struct csa *csa, int i, char rname[255+1]) { /* construct symbolic name of i-th row (constraint) */ const char *name; if (i == 0) name = glp_get_obj_name(csa->P); else name = glp_get_row_name(csa->P, i); if (name == NULL) goto fake; strcpy(rname, name); adjust_name(rname); if (check_name(rname)) goto fake; return rname; fake: if (i == 0) strcpy(rname, "obj"); else sprintf(rname, "r_%d", i); return rname; } static char *col_name(struct csa *csa, int j, char cname[255+1]) { /* construct symbolic name of j-th column (variable) */ const char *name; name = glp_get_col_name(csa->P, j); if (name == NULL) goto fake; strcpy(cname, name); adjust_name(cname); if (check_name(cname)) goto fake; return cname; fake: sprintf(cname, "x_%d", j); return cname; } int glp_write_lp(glp_prob *P, const glp_cpxcp *parm, const char *fname) { /* write problem data in CPLEX LP format */ glp_cpxcp _parm; struct csa _csa, *csa = &_csa; XFILE *fp; GLPROW *row; GLPCOL *col; GLPAIJ *aij; int i, j, len, flag, count, ret; char line[1000+1], term[500+1], name[255+1]; xprintf("Writing problem data to `%s'...\n", fname); if (parm == NULL) glp_init_cpxcp(&_parm), parm = &_parm; /* check control parameters */ check_parm("glp_write_lp", parm); /* initialize common storage area */ csa->P = P; csa->parm = parm; /* create output CPLEX LP file */ fp = xfopen(fname, "w"), count = 0; if (fp == NULL) { xprintf("Unable to create `%s' - %s\n", fname, xerrmsg()); ret = 1; goto done; } /* write problem name */ xfprintf(fp, "\\* Problem: %s *\\\n", P->name == NULL ? "Unknown" : P->name), count++; xfprintf(fp, "\n"), count++; /* the problem should contain at least one row and one column */ if (!(P->m > 0 && P->n > 0)) { xprintf("Warning: problem has no rows/columns\n"); xfprintf(fp, "\\* WARNING: PROBLEM HAS NO ROWS/COLUMNS *\\\n"), count++; xfprintf(fp, "\n"), count++; goto skip; } /* write the objective function definition */ if (P->dir == GLP_MIN) xfprintf(fp, "Minimize\n"), count++; else if (P->dir == GLP_MAX) xfprintf(fp, "Maximize\n"), count++; else xassert(P != P); row_name(csa, 0, name); sprintf(line, " %s:", name); len = 0; for (j = 1; j <= P->n; j++) { col = P->col[j]; if (col->coef != 0.0 || col->ptr == NULL) { len++; col_name(csa, j, name); if (col->coef == 0.0) sprintf(term, " + 0 %s", name); /* empty column */ else if (col->coef == +1.0) sprintf(term, " + %s", name); else if (col->coef == -1.0) sprintf(term, " - %s", name); else if (col->coef > 0.0) sprintf(term, " + %.*g %s", DBL_DIG, +col->coef, name); else sprintf(term, " - %.*g %s", DBL_DIG, -col->coef, name); if (strlen(line) + strlen(term) > 72) xfprintf(fp, "%s\n", line), line[0] = '\0', count++; strcat(line, term); } } if (len == 0) { /* empty objective */ sprintf(term, " 0 %s", col_name(csa, 1, name)); strcat(line, term); } xfprintf(fp, "%s\n", line), count++; if (P->c0 != 0.0) xfprintf(fp, "\\* constant term = %.*g *\\\n", DBL_DIG, P->c0), count++; xfprintf(fp, "\n"), count++; /* write the constraints section */ xfprintf(fp, "Subject To\n"), count++; for (i = 1; i <= P->m; i++) { row = P->row[i]; if (row->type == GLP_FR) continue; /* skip free row */ row_name(csa, i, name); sprintf(line, " %s:", name); /* linear form */ for (aij = row->ptr; aij != NULL; aij = aij->r_next) { col_name(csa, aij->col->j, name); if (aij->val == +1.0) sprintf(term, " + %s", name); else if (aij->val == -1.0) sprintf(term, " - %s", name); else if (aij->val > 0.0) sprintf(term, " + %.*g %s", DBL_DIG, +aij->val, name); else sprintf(term, " - %.*g %s", DBL_DIG, -aij->val, name); if (strlen(line) + strlen(term) > 72) xfprintf(fp, "%s\n", line), line[0] = '\0', count++; strcat(line, term); } if (row->type == GLP_DB) { /* double-bounded (ranged) constraint */ sprintf(term, " - ~r_%d", i); if (strlen(line) + strlen(term) > 72) xfprintf(fp, "%s\n", line), line[0] = '\0', count++; strcat(line, term); } else if (row->ptr == NULL) { /* empty constraint */ sprintf(term, " 0 %s", col_name(csa, 1, name)); strcat(line, term); } /* right hand-side */ if (row->type == GLP_LO) sprintf(term, " >= %.*g", DBL_DIG, row->lb); else if (row->type == GLP_UP) sprintf(term, " <= %.*g", DBL_DIG, row->ub); else if (row->type == GLP_DB || row->type == GLP_FX) sprintf(term, " = %.*g", DBL_DIG, row->lb); else xassert(row != row); if (strlen(line) + strlen(term) > 72) xfprintf(fp, "%s\n", line), line[0] = '\0', count++; strcat(line, term); xfprintf(fp, "%s\n", line), count++; } xfprintf(fp, "\n"), count++; /* write the bounds section */ flag = 0; for (i = 1; i <= P->m; i++) { row = P->row[i]; if (row->type != GLP_DB) continue; if (!flag) xfprintf(fp, "Bounds\n"), flag = 1, count++; xfprintf(fp, " 0 <= ~r_%d <= %.*g\n", i, DBL_DIG, row->ub - row->lb), count++; } for (j = 1; j <= P->n; j++) { col = P->col[j]; if (col->type == GLP_LO && col->lb == 0.0) continue; if (!flag) xfprintf(fp, "Bounds\n"), flag = 1, count++; col_name(csa, j, name); if (col->type == GLP_FR) xfprintf(fp, " %s free\n", name), count++; else if (col->type == GLP_LO) xfprintf(fp, " %s >= %.*g\n", name, DBL_DIG, col->lb), count++; else if (col->type == GLP_UP) xfprintf(fp, " -Inf <= %s <= %.*g\n", name, DBL_DIG, col->ub), count++; else if (col->type == GLP_DB) xfprintf(fp, " %.*g <= %s <= %.*g\n", DBL_DIG, col->lb, name, DBL_DIG, col->ub), count++; else if (col->type == GLP_FX) xfprintf(fp, " %s = %.*g\n", name, DBL_DIG, col->lb), count++; else xassert(col != col); } if (flag) xfprintf(fp, "\n"), count++; /* write the integer section */ flag = 0; for (j = 1; j <= P->n; j++) { col = P->col[j]; if (col->kind == GLP_CV) continue; xassert(col->kind == GLP_IV); if (!flag) xfprintf(fp, "Generals\n"), flag = 1, count++; xfprintf(fp, " %s\n", col_name(csa, j, name)), count++; } if (flag) xfprintf(fp, "\n"), count++; skip: /* write the end keyword */ xfprintf(fp, "End\n"), count++; xfflush(fp); if (xferror(fp)) { xprintf("Write error on `%s' - %s\n", fname, xerrmsg()); ret = 1; goto done; } /* problem data has been successfully written */ xprintf("%d lines were written\n", count); ret = 0; done: if (fp != NULL) xfclose(fp); return ret; } /* eof */ praat-6.0.04/external/glpk/glpdmp.c000066400000000000000000000171271261542461700171360ustar00rootroot00000000000000/* glpdmp.c (dynamic memory pool) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpdmp.h" #if 1 /* 29/VIII-2008 */ /* some processors need data to be properly aligned; the macro align_datasize enlarges the specified size of a data item to provide a proper alignment of immediately following data */ #define align_datasize(size) ((((size) + 7) / 8) * 8) /* 8 bytes is sufficient in both 32- and 64-bit environments */ #endif #ifdef GLP_DEBUG struct info { DMP *pool; int size; }; #endif /*********************************************************************** * NAME * * dmp_create_pool - create dynamic memory pool * * SYNOPSIS * * #include "glpdmp.h" * DMP *dmp_create_pool(void); * * DESCRIPTION * * The routine dmp_create_pool creates a dynamic memory pool. * * RETURNS * * The routine returns a pointer to the memory pool created. */ DMP *dmp_create_pool(void) { DMP *pool; int k; #ifdef GLP_DEBUG xprintf("dmp_create_pool: warning: debug mode enabled\n"); #endif pool = xmalloc(sizeof(DMP)); #if 0 pool->size = 0; #endif for (k = 0; k <= 31; k++) pool->avail[k] = NULL; pool->block = NULL; pool->used = DMP_BLK_SIZE; pool->count.lo = pool->count.hi = 0; return pool; } /*********************************************************************** * NAME * * dmp_get_atom - get free atom from dynamic memory pool * * SYNOPSIS * * #include "glpdmp.h" * void *dmp_get_atom(DMP *pool, int size); * * DESCRIPTION * * The routine dmp_get_atom obtains a free atom (memory block) from the * specified memory pool. * * The parameter size is the atom size, in bytes, 1 <= size <= 256. * * Note that the free atom contains arbitrary data, not binary zeros. * * RETURNS * * The routine returns a pointer to the free atom obtained. */ void *dmp_get_atom(DMP *pool, int size) { void *atom; int k; #ifdef GLP_DEBUG int orig_size = size; #endif if (!(1 <= size && size <= 256)) xerror("dmp_get_atom: size = %d; invalid atom size\n", size); #if 0 if (!(pool->size == 0 || pool->size == size)) xerror("dmp_get_atom: size = %d; wrong atom size\n", size); #endif /* adjust the size to provide the proper data alignment */ size = align_datasize(size); #ifdef GLP_DEBUG size += align_datasize(sizeof(struct info)); #endif /* adjust the size to make it multiple of 8 bytes, if needed */ size = ((size + 7) / 8) * 8; /* determine the corresponding list of free cells */ k = size / 8 - 1; xassert(0 <= k && k <= 31); /* obtain a free atom */ if (pool->avail[k] == NULL) { /* the list of free cells is empty */ if (pool->used + size > DMP_BLK_SIZE) { /* allocate a new memory block */ void *block = xmalloc(DMP_BLK_SIZE); *(void **)block = pool->block; pool->block = block; pool->used = align_datasize(sizeof(void *)); } /* place the atom in the current memory block */ atom = (char *)pool->block + pool->used; pool->used += size; } else { /* obtain the atom from the list of free cells */ atom = pool->avail[k]; pool->avail[k] = *(void **)atom; } memset(atom, '?', size); /* increase the number of atoms which are currently in use */ pool->count.lo++; if (pool->count.lo == 0) pool->count.hi++; #ifdef GLP_DEBUG ((struct info *)atom)->pool = pool; ((struct info *)atom)->size = orig_size; atom = (char *)atom + align_datasize(sizeof(struct info)); #endif return atom; } /*********************************************************************** * NAME * * dmp_free_atom - return atom to dynamic memory pool * * SYNOPSIS * * #include "glpdmp.h" * void dmp_free_atom(DMP *pool, void *atom, int size); * * DESCRIPTION * * The routine dmp_free_atom returns the specified atom (memory block) * to the specified memory pool, making it free. * * The parameter size is the atom size, in bytes, 1 <= size <= 256. * * Note that the atom can be returned only to the pool, from which it * was obtained, and its size must be exactly the same as on obtaining * it from the pool. */ void dmp_free_atom(DMP *pool, void *atom, int size) { int k; if (!(1 <= size && size <= 256)) xerror("dmp_free_atom: size = %d; invalid atom size\n", size); #if 0 if (!(pool->size == 0 || pool->size == size)) xerror("dmp_free_atom: size = %d; wrong atom size\n", size); #endif if (pool->count.lo == 0 && pool->count.hi == 0) xerror("dmp_free_atom: pool allocation error\n"); #ifdef GLP_DEBUG atom = (char *)atom - align_datasize(sizeof(struct info)); xassert(((struct info *)atom)->pool == pool); xassert(((struct info *)atom)->size == size); #endif /* adjust the size to provide the proper data alignment */ size = align_datasize(size); #ifdef GLP_DEBUG size += align_datasize(sizeof(struct info)); #endif /* adjust the size to make it multiple of 8 bytes, if needed */ size = ((size + 7) / 8) * 8; /* determine the corresponding list of free cells */ k = size / 8 - 1; xassert(0 <= k && k <= 31); /* return the atom to the list of free cells */ *(void **)atom = pool->avail[k]; pool->avail[k] = atom; /* decrease the number of atoms which are currently in use */ pool->count.lo--; if (pool->count.lo == 0xFFFFFFFF) pool->count.hi--; return; } /*********************************************************************** * NAME * * dmp_in_use - determine how many atoms are still in use * * SYNOPSIS * * #include "glpdmp.h" * glp_long dmp_in_use(DMP *pool); * * DESCRIPTION * * The routine dmp_in_use determines how many atoms allocated from the * specified memory pool with the routine dmp_get_atom are still in use, * i.e. not returned to the pool with the routine dmp_free_atom. * * RETURNS * * The routine returns the number of atoms which are still in use. */ glp_long dmp_in_use(DMP *pool) { return pool->count; } /*********************************************************************** * NAME * * dmp_delete_pool - delete dynamic memory pool * * SYNOPSIS * * #include "glpdmp.h" * void dmp_delete_pool(DMP *pool); * * DESCRIPTION * * The routine dmp_delete_pool deletes the specified dynamic memory * pool and frees all the memory allocated to this object. */ void dmp_delete_pool(DMP *pool) { while (pool->block != NULL) { void *block = pool->block; pool->block = *(void **)block; xfree(block); } xfree(pool); return; } /* eof */ praat-6.0.04/external/glpk/glpdmp.h000066400000000000000000000052261261542461700171400ustar00rootroot00000000000000/* glpdmp.h (dynamic memory pool) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPDMP_H #define GLPDMP_H #include "glpenv.h" typedef struct DMP DMP; #define DMP_BLK_SIZE 8000 /* size of memory blocks, in bytes, allocated for memory pools */ struct DMP { /* dynamic memory pool */ #if 0 int size; /* size of atoms, in bytes, 1 <= size <= 256; if size = 0, atoms may have different sizes */ #endif void *avail[32]; /* avail[k], 0 <= k <= 31, is a pointer to the first available (free) cell of (k+1)*8 bytes long; in the beginning of each free cell there is a pointer to another free cell of the same length */ void *block; /* pointer to the most recently allocated memory block; in the beginning of each allocated memory block there is a pointer to the previously allocated memory block */ int used; /* number of bytes used in the most recently allocated memory block */ glp_long count; /* number of atoms which are currently in use */ }; #define dmp_create_pool _glp_dmp_create_pool DMP *dmp_create_pool(void); /* create dynamic memory pool */ #define dmp_get_atom _glp_dmp_get_atom void *dmp_get_atom(DMP *pool, int size); /* get free atom from dynamic memory pool */ #define dmp_free_atom _glp_dmp_free_atom void dmp_free_atom(DMP *pool, void *atom, int size); /* return atom to dynamic memory pool */ #define dmp_in_use _glp_dmp_in_use glp_long dmp_in_use(DMP *pool); /* determine how many atoms are still in use */ #define dmp_delete_pool _glp_dmp_delete_pool void dmp_delete_pool(DMP *pool); /* delete dynamic memory pool */ #endif /* eof */ praat-6.0.04/external/glpk/glpdmx.c000066400000000000000000001430301261542461700171370ustar00rootroot00000000000000/* glpdmx.c (reading/writing data in DIMACS format) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #define _GLPSTD_STDIO #include "glpapi.h" struct csa { /* common storage area */ jmp_buf jump; /* label for go to in case of error */ const char *fname; /* name of input text file */ XFILE *fp; /* stream assigned to input text file */ int count; /* line count */ int c; /* current character */ char field[255+1]; /* data field */ int empty; /* warning 'empty line ignored' was printed */ int nonint; /* warning 'non-integer data detected' was printed */ }; static void error(struct csa *csa, const char *fmt, ...) { /* print error message and terminate processing */ va_list arg; xprintf("%s:%d: error: ", csa->fname, csa->count); va_start(arg, fmt); xvprintf(fmt, arg); va_end(arg); xprintf("\n"); longjmp(csa->jump, 1); /* no return */ } static void warning(struct csa *csa, const char *fmt, ...) { /* print warning message and continue processing */ va_list arg; xprintf("%s:%d: warning: ", csa->fname, csa->count); va_start(arg, fmt); xvprintf(fmt, arg); va_end(arg); xprintf("\n"); return; } static void read_char(struct csa *csa) { /* read character from input text file */ int c; if (csa->c == '\n') csa->count++; c = xfgetc(csa->fp); if (c < 0) { if (xferror(csa->fp)) error(csa, "read error - %s", xerrmsg()); else if (csa->c == '\n') error(csa, "unexpected end of file"); else { warning(csa, "missing final end of line"); c = '\n'; } } else if (c == '\n') ; else if (isspace(c)) c = ' '; else if (iscntrl(c)) error(csa, "invalid control character 0x%02X", c); csa->c = c; return; } static void read_designator(struct csa *csa) { /* read one-character line designator */ xassert(csa->c == '\n'); read_char(csa); for (;;) { /* skip preceding white-space characters */ while (csa->c == ' ') read_char(csa); if (csa->c == '\n') { /* ignore empty line */ if (!csa->empty) { warning(csa, "empty line ignored"); csa->empty = 1; } read_char(csa); } else if (csa->c == 'c') { /* skip comment line */ while (csa->c != '\n') read_char(csa); read_char(csa); } else { /* hmm... looks like a line designator */ csa->field[0] = (char)csa->c, csa->field[1] = '\0'; /* check that it is followed by a white-space character */ read_char(csa); if (!(csa->c == ' ' || csa->c == '\n')) error(csa, "line designator missing or invalid"); break; } } return; } static void read_field(struct csa *csa) { /* read data field */ int len = 0; /* skip preceding white-space characters */ while (csa->c == ' ') read_char(csa); /* scan data field */ if (csa->c == '\n') error(csa, "unexpected end of line"); while (!(csa->c == ' ' || csa->c == '\n')) { if (len == sizeof(csa->field)-1) error(csa, "data field `%.15s...' too long", csa->field); csa->field[len++] = (char)csa->c; read_char(csa); } csa->field[len] = '\0'; return; } static void end_of_line(struct csa *csa) { /* skip white-space characters until end of line */ while (csa->c == ' ') read_char(csa); if (csa->c != '\n') error(csa, "too many data fields specified"); return; } static void check_int(struct csa *csa, double num) { /* print a warning if non-integer data are detected */ if (!csa->nonint && num != floor(num)) { warning(csa, "non-integer data detected"); csa->nonint = 1; } return; } /*********************************************************************** * NAME * * glp_read_mincost - read min-cost flow problem data in DIMACS format * * SYNOPSIS * * int glp_read_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap, * int a_cost, const char *fname); * * DESCRIPTION * * The routine glp_read_mincost reads minimum cost flow problem data in * DIMACS format from a text file. * * RETURNS * * If the operation was successful, the routine returns zero. Otherwise * it prints an error message and returns non-zero. */ int glp_read_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap, int a_cost, const char *fname) { struct csa _csa, *csa = &_csa; glp_vertex *v; glp_arc *a; int i, j, k, nv, na, ret = 0; double rhs, low, cap, cost; char *flag = NULL; if (v_rhs >= 0 && v_rhs > G->v_size - (int)sizeof(double)) xerror("glp_read_mincost: v_rhs = %d; invalid offset\n", v_rhs); if (a_low >= 0 && a_low > G->a_size - (int)sizeof(double)) xerror("glp_read_mincost: a_low = %d; invalid offset\n", a_low); if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) xerror("glp_read_mincost: a_cap = %d; invalid offset\n", a_cap); if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) xerror("glp_read_mincost: a_cost = %d; invalid offset\n", a_cost); glp_erase_graph(G, G->v_size, G->a_size); if (setjmp(csa->jump)) { ret = 1; goto done; } csa->fname = fname; csa->fp = NULL; csa->count = 0; csa->c = '\n'; csa->field[0] = '\0'; csa->empty = csa->nonint = 0; xprintf("Reading min-cost flow problem data from `%s'...\n", fname); csa->fp = xfopen(fname, "r"); if (csa->fp == NULL) { xprintf("Unable to open `%s' - %s\n", fname, xerrmsg()); longjmp(csa->jump, 1); } /* read problem line */ read_designator(csa); if (strcmp(csa->field, "p") != 0) error(csa, "problem line missing or invalid"); read_field(csa); if (strcmp(csa->field, "min") != 0) error(csa, "wrong problem designator; `min' expected"); read_field(csa); if (!(str2int(csa->field, &nv) == 0 && nv >= 0)) error(csa, "number of nodes missing or invalid"); read_field(csa); if (!(str2int(csa->field, &na) == 0 && na >= 0)) error(csa, "number of arcs missing or invalid"); xprintf("Flow network has %d node%s and %d arc%s\n", nv, nv == 1 ? "" : "s", na, na == 1 ? "" : "s"); if (nv > 0) glp_add_vertices(G, nv); end_of_line(csa); /* read node descriptor lines */ flag = xcalloc(1+nv, sizeof(char)); memset(&flag[1], 0, nv * sizeof(char)); if (v_rhs >= 0) { rhs = 0.0; for (i = 1; i <= nv; i++) { v = G->v[i]; memcpy((char *)v->data + v_rhs, &rhs, sizeof(double)); } } for (;;) { read_designator(csa); if (strcmp(csa->field, "n") != 0) break; read_field(csa); if (str2int(csa->field, &i) != 0) error(csa, "node number missing or invalid"); if (!(1 <= i && i <= nv)) error(csa, "node number %d out of range", i); if (flag[i]) error(csa, "duplicate descriptor of node %d", i); read_field(csa); if (str2num(csa->field, &rhs) != 0) error(csa, "node supply/demand missing or invalid"); check_int(csa, rhs); if (v_rhs >= 0) { v = G->v[i]; memcpy((char *)v->data + v_rhs, &rhs, sizeof(double)); } flag[i] = 1; end_of_line(csa); } xfree(flag), flag = NULL; /* read arc descriptor lines */ for (k = 1; k <= na; k++) { if (k > 1) read_designator(csa); if (strcmp(csa->field, "a") != 0) error(csa, "wrong line designator; `a' expected"); read_field(csa); if (str2int(csa->field, &i) != 0) error(csa, "starting node number missing or invalid"); if (!(1 <= i && i <= nv)) error(csa, "starting node number %d out of range", i); read_field(csa); if (str2int(csa->field, &j) != 0) error(csa, "ending node number missing or invalid"); if (!(1 <= j && j <= nv)) error(csa, "ending node number %d out of range", j); read_field(csa); if (!(str2num(csa->field, &low) == 0 && low >= 0.0)) error(csa, "lower bound of arc flow missing or invalid"); check_int(csa, low); read_field(csa); if (!(str2num(csa->field, &cap) == 0 && cap >= low)) error(csa, "upper bound of arc flow missing or invalid"); check_int(csa, cap); read_field(csa); if (str2num(csa->field, &cost) != 0) error(csa, "per-unit cost of arc flow missing or invalid"); check_int(csa, cost); a = glp_add_arc(G, i, j); if (a_low >= 0) memcpy((char *)a->data + a_low, &low, sizeof(double)); if (a_cap >= 0) memcpy((char *)a->data + a_cap, &cap, sizeof(double)); if (a_cost >= 0) memcpy((char *)a->data + a_cost, &cost, sizeof(double)); end_of_line(csa); } xprintf("%d lines were read\n", csa->count); done: if (ret) glp_erase_graph(G, G->v_size, G->a_size); if (csa->fp != NULL) xfclose(csa->fp); if (flag != NULL) xfree(flag); return ret; } /*********************************************************************** * NAME * * glp_write_mincost - write min-cost flow problem data in DIMACS format * * SYNOPSIS * * int glp_write_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap, * int a_cost, const char *fname); * * DESCRIPTION * * The routine glp_write_mincost writes minimum cost flow problem data * in DIMACS format to a text file. * * RETURNS * * If the operation was successful, the routine returns zero. Otherwise * it prints an error message and returns non-zero. */ int glp_write_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap, int a_cost, const char *fname) { XFILE *fp; glp_vertex *v; glp_arc *a; int i, count = 0, ret; double rhs, low, cap, cost; if (v_rhs >= 0 && v_rhs > G->v_size - (int)sizeof(double)) xerror("glp_write_mincost: v_rhs = %d; invalid offset\n", v_rhs); if (a_low >= 0 && a_low > G->a_size - (int)sizeof(double)) xerror("glp_write_mincost: a_low = %d; invalid offset\n", a_low); if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) xerror("glp_write_mincost: a_cap = %d; invalid offset\n", a_cap); if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) xerror("glp_write_mincost: a_cost = %d; invalid offset\n", a_cost); xprintf("Writing min-cost flow problem data to `%s'...\n", fname); fp = xfopen(fname, "w"); if (fp == NULL) { xprintf("Unable to create `%s' - %s\n", fname, xerrmsg()); ret = 1; goto done; } xfprintf(fp, "c %s\n", G->name == NULL ? "unknown" : G->name), count++; xfprintf(fp, "p min %d %d\n", G->nv, G->na), count++; if (v_rhs >= 0) { for (i = 1; i <= G->nv; i++) { v = G->v[i]; memcpy(&rhs, (char *)v->data + v_rhs, sizeof(double)); if (rhs != 0.0) xfprintf(fp, "n %d %.*g\n", i, DBL_DIG, rhs), count++; } } for (i = 1; i <= G->nv; i++) { v = G->v[i]; for (a = v->out; a != NULL; a = a->t_next) { if (a_low >= 0) memcpy(&low, (char *)a->data + a_low, sizeof(double)); else low = 0.0; if (a_cap >= 0) memcpy(&cap, (char *)a->data + a_cap, sizeof(double)); else cap = 1.0; if (a_cost >= 0) memcpy(&cost, (char *)a->data + a_cost, sizeof(double)); else cost = 0.0; xfprintf(fp, "a %d %d %.*g %.*g %.*g\n", a->tail->i, a->head->i, DBL_DIG, low, DBL_DIG, cap, DBL_DIG, cost), count++; } } xfprintf(fp, "c eof\n"), count++; xfflush(fp); if (xferror(fp)) { xprintf("Write error on `%s' - %s\n", fname, xerrmsg()); ret = 1; goto done; } xprintf("%d lines were written\n", count); ret = 0; done: if (fp != NULL) xfclose(fp); return ret; } /*********************************************************************** * NAME * * glp_read_maxflow - read maximum flow problem data in DIMACS format * * SYNOPSIS * * int glp_read_maxflow(glp_graph *G, int *s, int *t, int a_cap, * const char *fname); * * DESCRIPTION * * The routine glp_read_maxflow reads maximum flow problem data in * DIMACS format from a text file. * * RETURNS * * If the operation was successful, the routine returns zero. Otherwise * it prints an error message and returns non-zero. */ int glp_read_maxflow(glp_graph *G, int *_s, int *_t, int a_cap, const char *fname) { struct csa _csa, *csa = &_csa; glp_arc *a; int i, j, k, s, t, nv, na, ret = 0; double cap; if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) xerror("glp_read_maxflow: a_cap = %d; invalid offset\n", a_cap); glp_erase_graph(G, G->v_size, G->a_size); if (setjmp(csa->jump)) { ret = 1; goto done; } csa->fname = fname; csa->fp = NULL; csa->count = 0; csa->c = '\n'; csa->field[0] = '\0'; csa->empty = csa->nonint = 0; xprintf("Reading maximum flow problem data from `%s'...\n", fname); csa->fp = xfopen(fname, "r"); if (csa->fp == NULL) { xprintf("Unable to open `%s' - %s\n", fname, xerrmsg()); longjmp(csa->jump, 1); } /* read problem line */ read_designator(csa); if (strcmp(csa->field, "p") != 0) error(csa, "problem line missing or invalid"); read_field(csa); if (strcmp(csa->field, "max") != 0) error(csa, "wrong problem designator; `max' expected"); read_field(csa); if (!(str2int(csa->field, &nv) == 0 && nv >= 2)) error(csa, "number of nodes missing or invalid"); read_field(csa); if (!(str2int(csa->field, &na) == 0 && na >= 0)) error(csa, "number of arcs missing or invalid"); xprintf("Flow network has %d node%s and %d arc%s\n", nv, nv == 1 ? "" : "s", na, na == 1 ? "" : "s"); if (nv > 0) glp_add_vertices(G, nv); end_of_line(csa); /* read node descriptor lines */ s = t = 0; for (;;) { read_designator(csa); if (strcmp(csa->field, "n") != 0) break; read_field(csa); if (str2int(csa->field, &i) != 0) error(csa, "node number missing or invalid"); if (!(1 <= i && i <= nv)) error(csa, "node number %d out of range", i); read_field(csa); if (strcmp(csa->field, "s") == 0) { if (s > 0) error(csa, "only one source node allowed"); s = i; } else if (strcmp(csa->field, "t") == 0) { if (t > 0) error(csa, "only one sink node allowed"); t = i; } else error(csa, "wrong node designator; `s' or `t' expected"); if (s > 0 && s == t) error(csa, "source and sink nodes must be distinct"); end_of_line(csa); } if (s == 0) error(csa, "source node descriptor missing\n"); if (t == 0) error(csa, "sink node descriptor missing\n"); if (_s != NULL) *_s = s; if (_t != NULL) *_t = t; /* read arc descriptor lines */ for (k = 1; k <= na; k++) { if (k > 1) read_designator(csa); if (strcmp(csa->field, "a") != 0) error(csa, "wrong line designator; `a' expected"); read_field(csa); if (str2int(csa->field, &i) != 0) error(csa, "starting node number missing or invalid"); if (!(1 <= i && i <= nv)) error(csa, "starting node number %d out of range", i); read_field(csa); if (str2int(csa->field, &j) != 0) error(csa, "ending node number missing or invalid"); if (!(1 <= j && j <= nv)) error(csa, "ending node number %d out of range", j); read_field(csa); if (!(str2num(csa->field, &cap) == 0 && cap >= 0.0)) error(csa, "arc capacity missing or invalid"); check_int(csa, cap); a = glp_add_arc(G, i, j); if (a_cap >= 0) memcpy((char *)a->data + a_cap, &cap, sizeof(double)); end_of_line(csa); } xprintf("%d lines were read\n", csa->count); done: if (ret) glp_erase_graph(G, G->v_size, G->a_size); if (csa->fp != NULL) xfclose(csa->fp); return ret; } /*********************************************************************** * NAME * * glp_write_maxflow - write maximum flow problem data in DIMACS format * * SYNOPSIS * * int glp_write_maxflow(glp_graph *G, int s, int t, int a_cap, * const char *fname); * * DESCRIPTION * * The routine glp_write_maxflow writes maximum flow problem data in * DIMACS format to a text file. * * RETURNS * * If the operation was successful, the routine returns zero. Otherwise * it prints an error message and returns non-zero. */ int glp_write_maxflow(glp_graph *G, int s, int t, int a_cap, const char *fname) { XFILE *fp; glp_vertex *v; glp_arc *a; int i, count = 0, ret; double cap; if (!(1 <= s && s <= G->nv)) xerror("glp_write_maxflow: s = %d; source node number out of r" "ange\n", s); if (!(1 <= t && t <= G->nv)) xerror("glp_write_maxflow: t = %d: sink node number out of ran" "ge\n", t); if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) xerror("glp_write_mincost: a_cap = %d; invalid offset\n", a_cap); xprintf("Writing maximum flow problem data to `%s'...\n", fname); fp = xfopen(fname, "w"); if (fp == NULL) { xprintf("Unable to create `%s' - %s\n", fname, xerrmsg()); ret = 1; goto done; } xfprintf(fp, "c %s\n", G->name == NULL ? "unknown" : G->name), count++; xfprintf(fp, "p max %d %d\n", G->nv, G->na), count++; xfprintf(fp, "n %d s\n", s), count++; xfprintf(fp, "n %d t\n", t), count++; for (i = 1; i <= G->nv; i++) { v = G->v[i]; for (a = v->out; a != NULL; a = a->t_next) { if (a_cap >= 0) memcpy(&cap, (char *)a->data + a_cap, sizeof(double)); else cap = 1.0; xfprintf(fp, "a %d %d %.*g\n", a->tail->i, a->head->i, DBL_DIG, cap), count++; } } xfprintf(fp, "c eof\n"), count++; xfflush(fp); if (xferror(fp)) { xprintf("Write error on `%s' - %s\n", fname, xerrmsg()); ret = 1; goto done; } xprintf("%d lines were written\n", count); ret = 0; done: if (fp != NULL) xfclose(fp); return ret; } /*********************************************************************** * NAME * * glp_read_asnprob - read assignment problem data in DIMACS format * * SYNOPSIS * * int glp_read_asnprob(glp_graph *G, int v_set, int a_cost, * const char *fname); * * DESCRIPTION * * The routine glp_read_asnprob reads assignment problem data in DIMACS * format from a text file. * * RETURNS * * If the operation was successful, the routine returns zero. Otherwise * it prints an error message and returns non-zero. */ int glp_read_asnprob(glp_graph *G, int v_set, int a_cost, const char *fname) { struct csa _csa, *csa = &_csa; glp_vertex *v; glp_arc *a; int nv, na, n1, i, j, k, ret = 0; double cost; char *flag = NULL; if (v_set >= 0 && v_set > G->v_size - (int)sizeof(int)) xerror("glp_read_asnprob: v_set = %d; invalid offset\n", v_set); if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) xerror("glp_read_asnprob: a_cost = %d; invalid offset\n", a_cost); glp_erase_graph(G, G->v_size, G->a_size); if (setjmp(csa->jump)) { ret = 1; goto done; } csa->fname = fname; csa->fp = NULL; csa->count = 0; csa->c = '\n'; csa->field[0] = '\0'; csa->empty = csa->nonint = 0; xprintf("Reading assignment problem data from `%s'...\n", fname); csa->fp = xfopen(fname, "r"); if (csa->fp == NULL) { xprintf("Unable to open `%s' - %s\n", fname, xerrmsg()); longjmp(csa->jump, 1); } /* read problem line */ read_designator(csa); if (strcmp(csa->field, "p") != 0) error(csa, "problem line missing or invalid"); read_field(csa); if (strcmp(csa->field, "asn") != 0) error(csa, "wrong problem designator; `asn' expected"); read_field(csa); if (!(str2int(csa->field, &nv) == 0 && nv >= 0)) error(csa, "number of nodes missing or invalid"); read_field(csa); if (!(str2int(csa->field, &na) == 0 && na >= 0)) error(csa, "number of arcs missing or invalid"); if (nv > 0) glp_add_vertices(G, nv); end_of_line(csa); /* read node descriptor lines */ flag = xcalloc(1+nv, sizeof(char)); memset(&flag[1], 0, nv * sizeof(char)); n1 = 0; for (;;) { read_designator(csa); if (strcmp(csa->field, "n") != 0) break; read_field(csa); if (str2int(csa->field, &i) != 0) error(csa, "node number missing or invalid"); if (!(1 <= i && i <= nv)) error(csa, "node number %d out of range", i); if (flag[i]) error(csa, "duplicate descriptor of node %d", i); flag[i] = 1, n1++; end_of_line(csa); } xprintf( "Assignment problem has %d + %d = %d node%s and %d arc%s\n", n1, nv - n1, nv, nv == 1 ? "" : "s", na, na == 1 ? "" : "s"); if (v_set >= 0) { for (i = 1; i <= nv; i++) { v = G->v[i]; k = (flag[i] ? 0 : 1); memcpy((char *)v->data + v_set, &k, sizeof(int)); } } /* read arc descriptor lines */ for (k = 1; k <= na; k++) { if (k > 1) read_designator(csa); if (strcmp(csa->field, "a") != 0) error(csa, "wrong line designator; `a' expected"); read_field(csa); if (str2int(csa->field, &i) != 0) error(csa, "starting node number missing or invalid"); if (!(1 <= i && i <= nv)) error(csa, "starting node number %d out of range", i); if (!flag[i]) error(csa, "node %d cannot be a starting node", i); read_field(csa); if (str2int(csa->field, &j) != 0) error(csa, "ending node number missing or invalid"); if (!(1 <= j && j <= nv)) error(csa, "ending node number %d out of range", j); if (flag[j]) error(csa, "node %d cannot be an ending node", j); read_field(csa); if (str2num(csa->field, &cost) != 0) error(csa, "arc cost missing or invalid"); check_int(csa, cost); a = glp_add_arc(G, i, j); if (a_cost >= 0) memcpy((char *)a->data + a_cost, &cost, sizeof(double)); end_of_line(csa); } xprintf("%d lines were read\n", csa->count); done: if (ret) glp_erase_graph(G, G->v_size, G->a_size); if (csa->fp != NULL) xfclose(csa->fp); if (flag != NULL) xfree(flag); return ret; } /*********************************************************************** * NAME * * glp_write_asnprob - write assignment problem data in DIMACS format * * SYNOPSIS * * int glp_write_asnprob(glp_graph *G, int v_set, int a_cost, * const char *fname); * * DESCRIPTION * * The routine glp_write_asnprob writes assignment problem data in * DIMACS format to a text file. * * RETURNS * * If the operation was successful, the routine returns zero. Otherwise * it prints an error message and returns non-zero. */ int glp_write_asnprob(glp_graph *G, int v_set, int a_cost, const char *fname) { XFILE *fp; glp_vertex *v; glp_arc *a; int i, k, count = 0, ret; double cost; if (v_set >= 0 && v_set > G->v_size - (int)sizeof(int)) xerror("glp_write_asnprob: v_set = %d; invalid offset\n", v_set); if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) xerror("glp_write_asnprob: a_cost = %d; invalid offset\n", a_cost); xprintf("Writing assignment problem data to `%s'...\n", fname); fp = xfopen(fname, "w"); if (fp == NULL) { xprintf("Unable to create `%s' - %s\n", fname, xerrmsg()); ret = 1; goto done; } xfprintf(fp, "c %s\n", G->name == NULL ? "unknown" : G->name), count++; xfprintf(fp, "p asn %d %d\n", G->nv, G->na), count++; for (i = 1; i <= G->nv; i++) { v = G->v[i]; if (v_set >= 0) memcpy(&k, (char *)v->data + v_set, sizeof(int)); else k = (v->out != NULL ? 0 : 1); if (k == 0) xfprintf(fp, "n %d\n", i), count++; } for (i = 1; i <= G->nv; i++) { v = G->v[i]; for (a = v->out; a != NULL; a = a->t_next) { if (a_cost >= 0) memcpy(&cost, (char *)a->data + a_cost, sizeof(double)); else cost = 1.0; xfprintf(fp, "a %d %d %.*g\n", a->tail->i, a->head->i, DBL_DIG, cost), count++; } } xfprintf(fp, "c eof\n"), count++; xfflush(fp); if (xferror(fp)) { xprintf("Write error on `%s' - %s\n", fname, xerrmsg()); ret = 1; goto done; } xprintf("%d lines were written\n", count); ret = 0; done: if (fp != NULL) xfclose(fp); return ret; } /*********************************************************************** * NAME * * glp_read_ccdata - read graph in DIMACS clique/coloring format * * SYNOPSIS * * int glp_read_ccdata(glp_graph *G, int v_wgt, const char *fname); * * DESCRIPTION * * The routine glp_read_ccdata reads an (undirected) graph in DIMACS * clique/coloring format from a text file. * * RETURNS * * If the operation was successful, the routine returns zero. Otherwise * it prints an error message and returns non-zero. */ int glp_read_ccdata(glp_graph *G, int v_wgt, const char *fname) { struct csa _csa, *csa = &_csa; glp_vertex *v; int i, j, k, nv, ne, ret = 0; double w; char *flag = NULL; if (v_wgt >= 0 && v_wgt > G->v_size - (int)sizeof(double)) xerror("glp_read_ccdata: v_wgt = %d; invalid offset\n", v_wgt); glp_erase_graph(G, G->v_size, G->a_size); if (setjmp(csa->jump)) { ret = 1; goto done; } csa->fname = fname; csa->fp = NULL; csa->count = 0; csa->c = '\n'; csa->field[0] = '\0'; csa->empty = csa->nonint = 0; xprintf("Reading graph from `%s'...\n", fname); csa->fp = xfopen(fname, "r"); if (csa->fp == NULL) { xprintf("Unable to open `%s' - %s\n", fname, xerrmsg()); longjmp(csa->jump, 1); } /* read problem line */ read_designator(csa); if (strcmp(csa->field, "p") != 0) error(csa, "problem line missing or invalid"); read_field(csa); if (strcmp(csa->field, "edge") != 0) error(csa, "wrong problem designator; `edge' expected"); read_field(csa); if (!(str2int(csa->field, &nv) == 0 && nv >= 0)) error(csa, "number of vertices missing or invalid"); read_field(csa); if (!(str2int(csa->field, &ne) == 0 && ne >= 0)) error(csa, "number of edges missing or invalid"); xprintf("Graph has %d vert%s and %d edge%s\n", nv, nv == 1 ? "ex" : "ices", ne, ne == 1 ? "" : "s"); if (nv > 0) glp_add_vertices(G, nv); end_of_line(csa); /* read node descriptor lines */ flag = xcalloc(1+nv, sizeof(char)); memset(&flag[1], 0, nv * sizeof(char)); if (v_wgt >= 0) { w = 1.0; for (i = 1; i <= nv; i++) { v = G->v[i]; memcpy((char *)v->data + v_wgt, &w, sizeof(double)); } } for (;;) { read_designator(csa); if (strcmp(csa->field, "n") != 0) break; read_field(csa); if (str2int(csa->field, &i) != 0) error(csa, "vertex number missing or invalid"); if (!(1 <= i && i <= nv)) error(csa, "vertex number %d out of range", i); if (flag[i]) error(csa, "duplicate descriptor of vertex %d", i); read_field(csa); if (str2num(csa->field, &w) != 0) error(csa, "vertex weight missing or invalid"); check_int(csa, w); if (v_wgt >= 0) { v = G->v[i]; memcpy((char *)v->data + v_wgt, &w, sizeof(double)); } flag[i] = 1; end_of_line(csa); } xfree(flag), flag = NULL; /* read edge descriptor lines */ for (k = 1; k <= ne; k++) { if (k > 1) read_designator(csa); if (strcmp(csa->field, "e") != 0) error(csa, "wrong line designator; `e' expected"); read_field(csa); if (str2int(csa->field, &i) != 0) error(csa, "first vertex number missing or invalid"); if (!(1 <= i && i <= nv)) error(csa, "first vertex number %d out of range", i); read_field(csa); if (str2int(csa->field, &j) != 0) error(csa, "second vertex number missing or invalid"); if (!(1 <= j && j <= nv)) error(csa, "second vertex number %d out of range", j); glp_add_arc(G, i, j); end_of_line(csa); } xprintf("%d lines were read\n", csa->count); done: if (ret) glp_erase_graph(G, G->v_size, G->a_size); if (csa->fp != NULL) xfclose(csa->fp); if (flag != NULL) xfree(flag); return ret; } /*********************************************************************** * NAME * * glp_write_ccdata - write graph in DIMACS clique/coloring format * * SYNOPSIS * * int glp_write_ccdata(glp_graph *G, int v_wgt, const char *fname); * * DESCRIPTION * * The routine glp_write_ccdata writes the specified graph in DIMACS * clique/coloring format to a text file. * * RETURNS * * If the operation was successful, the routine returns zero. Otherwise * it prints an error message and returns non-zero. */ int glp_write_ccdata(glp_graph *G, int v_wgt, const char *fname) { XFILE *fp; glp_vertex *v; glp_arc *e; int i, count = 0, ret; double w; if (v_wgt >= 0 && v_wgt > G->v_size - (int)sizeof(double)) xerror("glp_write_ccdata: v_wgt = %d; invalid offset\n", v_wgt); xprintf("Writing graph to `%s'\n", fname); fp = xfopen(fname, "w"); if (fp == NULL) { xprintf("Unable to create `%s' - %s\n", fname, xerrmsg()); ret = 1; goto done; } xfprintf(fp, "c %s\n", G->name == NULL ? "unknown" : G->name), count++; xfprintf(fp, "p edge %d %d\n", G->nv, G->na), count++; if (v_wgt >= 0) { for (i = 1; i <= G->nv; i++) { v = G->v[i]; memcpy(&w, (char *)v->data + v_wgt, sizeof(double)); if (w != 1.0) xfprintf(fp, "n %d %.*g\n", i, DBL_DIG, w), count++; } } for (i = 1; i <= G->nv; i++) { v = G->v[i]; for (e = v->out; e != NULL; e = e->t_next) xfprintf(fp, "e %d %d\n", e->tail->i, e->head->i), count++; } xfprintf(fp, "c eof\n"), count++; xfflush(fp); if (xferror(fp)) { xprintf("Write error on `%s' - %s\n", fname, xerrmsg()); ret = 1; goto done; } xprintf("%d lines were written\n", count); ret = 0; done: if (fp != NULL) xfclose(fp); return ret; } /*********************************************************************** * NAME * * glp_read_prob - read problem data in GLPK format * * SYNOPSIS * * int glp_read_prob(glp_prob *P, int flags, const char *fname); * * The routine glp_read_prob reads problem data in GLPK LP/MIP format * from a text file. * * RETURNS * * If the operation was successful, the routine returns zero. Otherwise * it prints an error message and returns non-zero. */ int glp_read_prob(glp_prob *P, int flags, const char *fname) { struct csa _csa, *csa = &_csa; int mip, m, n, nnz, ne, i, j, k, type, kind, ret, *ln = NULL, *ia = NULL, *ja = NULL; double lb, ub, temp, *ar = NULL; char *rf = NULL, *cf = NULL; if (P == NULL || P->magic != GLP_PROB_MAGIC) xerror("glp_read_prob: P = %p; invalid problem object\n", P); if (flags != 0) xerror("glp_read_prob: flags = %d; invalid parameter\n", flags); if (fname == NULL) xerror("glp_read_prob: fname = %d; invalid parameter\n", fname); glp_erase_prob(P); if (setjmp(csa->jump)) { ret = 1; goto done; } csa->fname = fname; csa->fp = NULL; csa->count = 0; csa->c = '\n'; csa->field[0] = '\0'; csa->empty = csa->nonint = 0; xprintf("Reading problem data from `%s'...\n", fname); csa->fp = xfopen(fname, "r"); if (csa->fp == NULL) { xprintf("Unable to open `%s' - %s\n", fname, xerrmsg()); longjmp(csa->jump, 1); } /* read problem line */ read_designator(csa); if (strcmp(csa->field, "p") != 0) error(csa, "problem line missing or invalid"); read_field(csa); if (strcmp(csa->field, "lp") == 0) mip = 0; else if (strcmp(csa->field, "mip") == 0) mip = 1; else error(csa, "wrong problem designator; `lp' or `mip' expected\n" ); read_field(csa); if (strcmp(csa->field, "min") == 0) glp_set_obj_dir(P, GLP_MIN); else if (strcmp(csa->field, "max") == 0) glp_set_obj_dir(P, GLP_MAX); else error(csa, "objective sense missing or invalid"); read_field(csa); if (!(str2int(csa->field, &m) == 0 && m >= 0)) error(csa, "number of rows missing or invalid"); read_field(csa); if (!(str2int(csa->field, &n) == 0 && n >= 0)) error(csa, "number of columns missing or invalid"); read_field(csa); if (!(str2int(csa->field, &nnz) == 0 && nnz >= 0)) error(csa, "number of constraint coefficients missing or inval" "id"); if (m > 0) { glp_add_rows(P, m); for (i = 1; i <= m; i++) glp_set_row_bnds(P, i, GLP_FX, 0.0, 0.0); } if (n > 0) { glp_add_cols(P, n); for (j = 1; j <= n; j++) { if (!mip) glp_set_col_bnds(P, j, GLP_LO, 0.0, 0.0); else glp_set_col_kind(P, j, GLP_BV); } } end_of_line(csa); /* allocate working arrays */ rf = xcalloc(1+m, sizeof(char)); memset(rf, 0, 1+m); cf = xcalloc(1+n, sizeof(char)); memset(cf, 0, 1+n); ln = xcalloc(1+nnz, sizeof(int)); ia = xcalloc(1+nnz, sizeof(int)); ja = xcalloc(1+nnz, sizeof(int)); ar = xcalloc(1+nnz, sizeof(double)); /* read descriptor lines */ ne = 0; for (;;) { read_designator(csa); if (strcmp(csa->field, "i") == 0) { /* row descriptor */ read_field(csa); if (str2int(csa->field, &i) != 0) error(csa, "row number missing or invalid"); if (!(1 <= i && i <= m)) error(csa, "row number out of range"); read_field(csa); if (strcmp(csa->field, "f") == 0) type = GLP_FR; else if (strcmp(csa->field, "l") == 0) type = GLP_LO; else if (strcmp(csa->field, "u") == 0) type = GLP_UP; else if (strcmp(csa->field, "d") == 0) type = GLP_DB; else if (strcmp(csa->field, "s") == 0) type = GLP_FX; else error(csa, "row type missing or invalid"); if (type == GLP_LO || type == GLP_DB || type == GLP_FX) { read_field(csa); if (str2num(csa->field, &lb) != 0) error(csa, "row lower bound/fixed value missing or in" "valid"); } else lb = 0.0; if (type == GLP_UP || type == GLP_DB) { read_field(csa); if (str2num(csa->field, &ub) != 0) error(csa, "row upper bound missing or invalid"); } else ub = 0.0; if (rf[i] & 0x01) error(csa, "duplicate row descriptor"); glp_set_row_bnds(P, i, type, lb, ub), rf[i] |= 0x01; } else if (strcmp(csa->field, "j") == 0) { /* column descriptor */ read_field(csa); if (str2int(csa->field, &j) != 0) error(csa, "column number missing or invalid"); if (!(1 <= j && j <= n)) error(csa, "column number out of range"); if (!mip) kind = GLP_CV; else { read_field(csa); if (strcmp(csa->field, "c") == 0) kind = GLP_CV; else if (strcmp(csa->field, "i") == 0) kind = GLP_IV; else if (strcmp(csa->field, "b") == 0) { kind = GLP_IV; type = GLP_DB, lb = 0.0, ub = 1.0; goto skip; } else error(csa, "column kind missing or invalid"); } read_field(csa); if (strcmp(csa->field, "f") == 0) type = GLP_FR; else if (strcmp(csa->field, "l") == 0) type = GLP_LO; else if (strcmp(csa->field, "u") == 0) type = GLP_UP; else if (strcmp(csa->field, "d") == 0) type = GLP_DB; else if (strcmp(csa->field, "s") == 0) type = GLP_FX; else error(csa, "column type missing or invalid"); if (type == GLP_LO || type == GLP_DB || type == GLP_FX) { read_field(csa); if (str2num(csa->field, &lb) != 0) error(csa, "column lower bound/fixed value missing or" " invalid"); } else lb = 0.0; if (type == GLP_UP || type == GLP_DB) { read_field(csa); if (str2num(csa->field, &ub) != 0) error(csa, "column upper bound missing or invalid"); } else ub = 0.0; skip: if (cf[j] & 0x01) error(csa, "duplicate column descriptor"); glp_set_col_kind(P, j, kind); glp_set_col_bnds(P, j, type, lb, ub), cf[j] |= 0x01; } else if (strcmp(csa->field, "a") == 0) { /* coefficient descriptor */ read_field(csa); if (str2int(csa->field, &i) != 0) error(csa, "row number missing or invalid"); if (!(0 <= i && i <= m)) error(csa, "row number out of range"); read_field(csa); if (str2int(csa->field, &j) != 0) error(csa, "column number missing or invalid"); if (!((i == 0 ? 0 : 1) <= j && j <= n)) error(csa, "column number out of range"); read_field(csa); if (i == 0) { if (str2num(csa->field, &temp) != 0) error(csa, "objective %s missing or invalid", j == 0 ? "constant term" : "coefficient"); if (cf[j] & 0x10) error(csa, "duplicate objective %s", j == 0 ? "constant term" : "coefficient"); glp_set_obj_coef(P, j, temp), cf[j] |= 0x10; } else { if (str2num(csa->field, &temp) != 0) error(csa, "constraint coefficient missing or invalid" ); if (ne == nnz) error(csa, "too many constraint coefficient descripto" "rs"); ln[++ne] = csa->count; ia[ne] = i, ja[ne] = j, ar[ne] = temp; } } else if (strcmp(csa->field, "n") == 0) { /* symbolic name descriptor */ read_field(csa); if (strcmp(csa->field, "p") == 0) { /* problem name */ read_field(csa); if (P->name != NULL) error(csa, "duplicate problem name"); glp_set_prob_name(P, csa->field); } else if (strcmp(csa->field, "z") == 0) { /* objective name */ read_field(csa); if (P->obj != NULL) error(csa, "duplicate objective name"); glp_set_obj_name(P, csa->field); } else if (strcmp(csa->field, "i") == 0) { /* row name */ read_field(csa); if (str2int(csa->field, &i) != 0) error(csa, "row number missing or invalid"); if (!(1 <= i && i <= m)) error(csa, "row number out of range"); read_field(csa); if (P->row[i]->name != NULL) error(csa, "duplicate row name"); glp_set_row_name(P, i, csa->field); } else if (strcmp(csa->field, "j") == 0) { /* column name */ read_field(csa); if (str2int(csa->field, &j) != 0) error(csa, "column number missing or invalid"); if (!(1 <= j && j <= n)) error(csa, "column number out of range"); read_field(csa); if (P->col[j]->name != NULL) error(csa, "duplicate column name"); glp_set_col_name(P, j, csa->field); } else error(csa, "object designator missing or invalid"); } else if (strcmp(csa->field, "e") == 0) break; else error(csa, "line designator missing or invalid"); end_of_line(csa); } if (ne < nnz) error(csa, "too few constraint coefficient descriptors"); xassert(ne == nnz); k = glp_check_dup(m, n, ne, ia, ja); xassert(0 <= k && k <= nnz); if (k > 0) { csa->count = ln[k]; error(csa, "duplicate constraint coefficient"); } glp_load_matrix(P, ne, ia, ja, ar); /* print some statistics */ if (P->name != NULL) xprintf("Problem: %s\n", P->name); if (P->obj != NULL) xprintf("Objective: %s\n", P->obj); xprintf("%d row%s, %d column%s, %d non-zero%s\n", m, m == 1 ? "" : "s", n, n == 1 ? "" : "s", nnz, nnz == 1 ? "" : "s"); if (glp_get_num_int(P) > 0) { int ni = glp_get_num_int(P); int nb = glp_get_num_bin(P); if (ni == 1) { if (nb == 0) xprintf("One variable is integer\n"); else xprintf("One variable is binary\n"); } else { xprintf("%d integer variables, ", ni); if (nb == 0) xprintf("none"); else if (nb == 1) xprintf("one"); else if (nb == ni) xprintf("all"); else xprintf("%d", nb); xprintf(" of which %s binary\n", nb == 1 ? "is" : "are"); } } xprintf("%d lines were read\n", csa->count); /* problem data has been successfully read */ glp_sort_matrix(P); ret = 0; done: if (csa->fp != NULL) xfclose(csa->fp); if (rf != NULL) xfree(rf); if (cf != NULL) xfree(cf); if (ln != NULL) xfree(ln); if (ia != NULL) xfree(ia); if (ja != NULL) xfree(ja); if (ar != NULL) xfree(ar); if (ret) glp_erase_prob(P); return ret; } /*********************************************************************** * NAME * * glp_write_prob - write problem data in GLPK format * * SYNOPSIS * * int glp_write_prob(glp_prob *P, int flags, const char *fname); * * The routine glp_write_prob writes problem data in GLPK LP/MIP format * to a text file. * * RETURNS * * If the operation was successful, the routine returns zero. Otherwise * it prints an error message and returns non-zero. */ int glp_write_prob(glp_prob *P, int flags, const char *fname) { XFILE *fp; GLPROW *row; GLPCOL *col; GLPAIJ *aij; int mip, i, j, count, ret; if (P == NULL || P->magic != GLP_PROB_MAGIC) xerror("glp_write_prob: P = %p; invalid problem object\n", P); if (flags != 0) xerror("glp_write_prob: flags = %d; invalid parameter\n", flags); if (fname == NULL) xerror("glp_write_prob: fname = %d; invalid parameter\n", fname); xprintf("Writing problem data to `%s'...\n", fname); fp = xfopen(fname, "w"), count = 0; if (fp == NULL) { xprintf("Unable to create `%s' - %s\n", fname, xerrmsg()); ret = 1; goto done; } /* write problem line */ mip = (glp_get_num_int(P) > 0); xfprintf(fp, "p %s %s %d %d %d\n", !mip ? "lp" : "mip", P->dir == GLP_MIN ? "min" : P->dir == GLP_MAX ? "max" : "???", P->m, P->n, P->nnz), count++; if (P->name != NULL) xfprintf(fp, "n p %s\n", P->name), count++; if (P->obj != NULL) xfprintf(fp, "n z %s\n", P->obj), count++; /* write row descriptors */ for (i = 1; i <= P->m; i++) { row = P->row[i]; if (row->type == GLP_FX && row->lb == 0.0) goto skip1; xfprintf(fp, "i %d ", i), count++; if (row->type == GLP_FR) xfprintf(fp, "f\n"); else if (row->type == GLP_LO) xfprintf(fp, "l %.*g\n", DBL_DIG, row->lb); else if (row->type == GLP_UP) xfprintf(fp, "u %.*g\n", DBL_DIG, row->ub); else if (row->type == GLP_DB) xfprintf(fp, "d %.*g %.*g\n", DBL_DIG, row->lb, DBL_DIG, row->ub); else if (row->type == GLP_FX) xfprintf(fp, "s %.*g\n", DBL_DIG, row->lb); else xassert(row != row); skip1: if (row->name != NULL) xfprintf(fp, "n i %d %s\n", i, row->name), count++; } /* write column descriptors */ for (j = 1; j <= P->n; j++) { col = P->col[j]; if (!mip && col->type == GLP_LO && col->lb == 0.0) goto skip2; if (mip && col->kind == GLP_IV && col->type == GLP_DB && col->lb == 0.0 && col->ub == 1.0) goto skip2; xfprintf(fp, "j %d ", j), count++; if (mip) { if (col->kind == GLP_CV) xfprintf(fp, "c "); else if (col->kind == GLP_IV) xfprintf(fp, "i "); else xassert(col != col); } if (col->type == GLP_FR) xfprintf(fp, "f\n"); else if (col->type == GLP_LO) xfprintf(fp, "l %.*g\n", DBL_DIG, col->lb); else if (col->type == GLP_UP) xfprintf(fp, "u %.*g\n", DBL_DIG, col->ub); else if (col->type == GLP_DB) xfprintf(fp, "d %.*g %.*g\n", DBL_DIG, col->lb, DBL_DIG, col->ub); else if (col->type == GLP_FX) xfprintf(fp, "s %.*g\n", DBL_DIG, col->lb); else xassert(col != col); skip2: if (col->name != NULL) xfprintf(fp, "n j %d %s\n", j, col->name), count++; } /* write objective coefficient descriptors */ if (P->c0 != 0.0) xfprintf(fp, "a 0 0 %.*g\n", DBL_DIG, P->c0), count++; for (j = 1; j <= P->n; j++) { col = P->col[j]; if (col->coef != 0.0) xfprintf(fp, "a 0 %d %.*g\n", j, DBL_DIG, col->coef), count++; } /* write constraint coefficient descriptors */ for (i = 1; i <= P->m; i++) { row = P->row[i]; for (aij = row->ptr; aij != NULL; aij = aij->r_next) xfprintf(fp, "a %d %d %.*g\n", i, aij->col->j, DBL_DIG, aij->val), count++; } /* write end line */ xfprintf(fp, "e o f\n"), count++; xfflush(fp); if (xferror(fp)) { xprintf("Write error on `%s' - %s\n", fname, xerrmsg()); ret = 1; goto done; } xprintf("%d lines were written\n", count); ret = 0; done: if (fp != NULL) xfclose(fp); return ret; } /* eof */ praat-6.0.04/external/glpk/glpenv.h000066400000000000000000000155101261542461700171450ustar00rootroot00000000000000/* glpenv.h (GLPK environment) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPENV_H #define GLPENV_H #include "glpstd.h" #include "glplib.h" typedef struct ENV ENV; typedef struct MEM MEM; typedef struct XFILE XFILE; #define ENV_MAGIC 0x454E5631 /* environment block magic value */ #define TERM_BUF_SIZE 4096 /* terminal output buffer size, in bytes */ #define IOERR_MSG_SIZE 1024 /* i/o error message buffer size, in bytes */ #define MEM_MAGIC 0x4D454D31 /* memory block descriptor magic value */ struct ENV { /* environment block */ int magic; /* magic value used for debugging */ char version[7+1]; /* version string returned by the routine glp_version */ /*--------------------------------------------------------------*/ /* terminal output */ char *term_buf; /* char term_buf[TERM_BUF_SIZE]; */ /* terminal output buffer */ int term_out; /* flag to enable/disable terminal output */ int (*term_hook)(void *info, const char *s); /* user-defined routine to intercept terminal output */ void *term_info; /* transit pointer (cookie) passed to the routine term_hook */ FILE *tee_file; /* output stream used to copy terminal output */ /*--------------------------------------------------------------*/ /* error handling */ const char *err_file; /* value of the __FILE__ macro passed to glp_error */ int err_line; /* value of the __LINE__ macro passed to glp_error */ void (*err_hook)(void *info); /* user-defined routine to intercept abnormal termination */ void *err_info; /* transit pointer (cookie) passed to the routine err_hook */ /*--------------------------------------------------------------*/ /* memory allocation */ glp_long mem_limit; /* maximal amount of memory (in bytes) available for dynamic allocation */ MEM *mem_ptr; /* pointer to the linked list of allocated memory blocks */ int mem_count; /* total number of currently allocated memory blocks */ int mem_cpeak; /* peak value of mem_count */ glp_long mem_total; /* total amount of currently allocated memory (in bytes; is the sum of the size field over all memory block descriptors) */ glp_long mem_tpeak; /* peak value of mem_total */ /*--------------------------------------------------------------*/ /* stream input/output */ XFILE *file_ptr; /* pointer to the linked list of active stream descriptors */ char *ioerr_msg; /* char ioerr_msg[IOERR_MSG_SIZE]; */ /* input/output error message buffer */ /*--------------------------------------------------------------*/ /* shared libraries support */ void *h_odbc; /* handle to ODBC shared library */ void *h_mysql; /* handle to MySQL shared library */ }; struct MEM { /* memory block descriptor */ int flag; /* descriptor flag */ int size; /* size of block (in bytes, including descriptor) */ MEM *prev; /* pointer to previous memory block descriptor */ MEM *next; /* pointer to next memory block descriptor */ }; struct XFILE { /* input/output stream descriptor */ int type; /* stream handle type: */ #define FH_FILE 0x11 /* FILE */ #define FH_ZLIB 0x22 /* gzFile */ void *fh; /* pointer to stream handle */ XFILE *prev; /* pointer to previous stream descriptor */ XFILE *next; /* pointer to next stream descriptor */ }; #define XEOF (-1) #define get_env_ptr _glp_get_env_ptr ENV *get_env_ptr(void); /* retrieve pointer to environment block */ #define tls_set_ptr _glp_tls_set_ptr void tls_set_ptr(void *ptr); /* store global pointer in TLS */ #define tls_get_ptr _glp_tls_get_ptr void *tls_get_ptr(void); /* retrieve global pointer from TLS */ #define xprintf glp_printf void glp_printf(const char *fmt, ...); /* write formatted output to the terminal */ #define xvprintf glp_vprintf void glp_vprintf(const char *fmt, va_list arg); /* write formatted output to the terminal */ #ifndef GLP_ERROR_DEFINED #define GLP_ERROR_DEFINED typedef void (*_glp_error)(const char *fmt, ...); #endif #define xerror glp_error_(__FILE__, __LINE__) _glp_error glp_error_(const char *file, int line); /* display error message and terminate execution */ #define xassert(expr) \ ((void)((expr) || (glp_assert_(#expr, __FILE__, __LINE__), 1))) void glp_assert_(const char *expr, const char *file, int line); /* check for logical condition */ #define xmalloc glp_malloc void *glp_malloc(int size); /* allocate memory block */ #define xcalloc glp_calloc void *glp_calloc(int n, int size); /* allocate memory block */ #define xfree glp_free void glp_free(void *ptr); /* free memory block */ #define xtime glp_time glp_long glp_time(void); /* determine current universal time */ #define xdifftime glp_difftime double glp_difftime(glp_long t1, glp_long t0); /* compute difference between two time values, in seconds */ #define lib_err_msg _glp_lib_err_msg void lib_err_msg(const char *msg); #define xerrmsg _glp_lib_xerrmsg const char *xerrmsg(void); #define xfopen _glp_lib_xfopen XFILE *xfopen(const char *fname, const char *mode); #define xferror _glp_lib_xferror int xferror(XFILE *file); #define xfeof _glp_lib_xfeof int xfeof(XFILE *file); #define xfgetc _glp_lib_xfgetc int xfgetc(XFILE *file); #define xfputc _glp_lib_xfputc int xfputc(int c, XFILE *file); #define xfflush _glp_lib_xfflush int xfflush(XFILE *fp); #define xfclose _glp_lib_xfclose int xfclose(XFILE *file); #define xfprintf _glp_lib_xfprintf int xfprintf(XFILE *file, const char *fmt, ...); #define xdlopen _glp_xdlopen void *xdlopen(const char *module); #define xdlsym _glp_xdlsym void *xdlsym(void *h, const char *symbol); #define xdlclose _glp_xdlclose void xdlclose(void *h); #endif /* eof */ praat-6.0.04/external/glpk/glpenv01.c000066400000000000000000000163721261542461700173100ustar00rootroot00000000000000/* glpenv01.c (environment initialization/termination) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpapi.h" /*********************************************************************** * NAME * * glp_init_env - initialize GLPK environment * * SYNOPSIS * * int glp_init_env(void); * * DESCRIPTION * * The routine glp_init_env initializes the GLPK environment. Normally * the application program does not need to call this routine, because * it is called automatically on the first call to any API routine. * * RETURNS * * The routine glp_init_env returns one of the following codes: * * 0 - initialization successful; * 1 - environment has been already initialized; * 2 - initialization failed (insufficient memory); * 3 - initialization failed (unsupported programming model). */ int glp_init_env(void) { ENV *env; int ok; /* check if the programming model is supported */ ok = (CHAR_BIT == 8 && sizeof(char) == 1 && sizeof(short) == 2 && sizeof(int) == 4 && (sizeof(void *) == 4 || sizeof(void *) == 8)); if (!ok) return 3; /* check if the environment is already initialized */ if (tls_get_ptr() != NULL) return 1; /* allocate and initialize the environment block */ env = malloc(sizeof(ENV)); if (env == NULL) return 2; env->magic = ENV_MAGIC; sprintf(env->version, "%d.%d", GLP_MAJOR_VERSION, GLP_MINOR_VERSION); env->term_buf = malloc(TERM_BUF_SIZE); if (env->term_buf == NULL) { free(env); return 2; } env->term_out = GLP_ON; env->term_hook = NULL; env->term_info = NULL; env->tee_file = NULL; env->err_file = ""; env->err_line = 0; env->err_hook = NULL; env->err_info = NULL; env->mem_limit.hi = 0x7FFFFFFF, env->mem_limit.lo = 0xFFFFFFFF; env->mem_ptr = NULL; env->mem_count = env->mem_cpeak = 0; env->mem_total = env->mem_tpeak = xlset(0); env->file_ptr = NULL; env->ioerr_msg = malloc(IOERR_MSG_SIZE); if (env->ioerr_msg == NULL) { free(env->term_buf); free(env); return 2; } strcpy(env->ioerr_msg, "No error"); env->h_odbc = env->h_mysql = NULL; /* save pointer to the environment block */ tls_set_ptr(env); /* initialization successful */ return 0; } /*********************************************************************** * NAME * * get_env_ptr - retrieve pointer to environment block * * SYNOPSIS * * #include "glpenv.h" * ENV *get_env_ptr(void); * * DESCRIPTION * * The routine get_env_ptr retrieves and returns a pointer to the GLPK * environment block. * * If the GLPK environment has not been initialized yet, the routine * performs initialization. If initialization fails, the routine prints * an error message to stderr and terminates the program. * * RETURNS * * The routine returns a pointer to the environment block. */ ENV *get_env_ptr(void) { ENV *env = tls_get_ptr(); /* check if the environment has been initialized */ if (env == NULL) { /* not initialized yet; perform initialization */ if (glp_init_env() != 0) { /* initialization failed; display an error message */ fprintf(stderr, "GLPK initialization failed\n"); fflush(stderr); /* and abnormally terminate the program */ abort(); } /* initialization successful; retrieve the pointer */ env = tls_get_ptr(); } /* check if the environment block is valid */ if (env->magic != ENV_MAGIC) { fprintf(stderr, "Invalid GLPK environment\n"); fflush(stderr); abort(); } return env; } /*********************************************************************** * NAME * * glp_version - determine library version * * SYNOPSIS * * const char *glp_version(void); * * RETURNS * * The routine glp_version returns a pointer to a null-terminated * character string, which specifies the version of the GLPK library in * the form "X.Y", where X is the major version number, and Y is the * minor version number, for example, "4.16". */ const char *glp_version(void) { ENV *env = get_env_ptr(); return env->version; } /*********************************************************************** * NAME * * glp_free_env - free GLPK environment * * SYNOPSIS * * int glp_free_env(void); * * DESCRIPTION * * The routine glp_free_env frees all resources used by GLPK routines * (memory blocks, etc.) which are currently still in use. * * Normally the application program does not need to call this routine, * because GLPK routines always free all unused resources. However, if * the application program even has deleted all problem objects, there * will be several memory blocks still allocated for the library needs. * For some reasons the application program may want GLPK to free this * memory, in which case it should call glp_free_env. * * Note that a call to glp_free_env invalidates all problem objects as * if no GLPK routine were called. * * RETURNS * * 0 - termination successful; * 1 - environment is inactive (was not initialized). */ int glp_free_env(void) { ENV *env = tls_get_ptr(); MEM *desc; /* check if the environment is active */ if (env == NULL) return 1; /* check if the environment block is valid */ if (env->magic != ENV_MAGIC) { fprintf(stderr, "Invalid GLPK environment\n"); fflush(stderr); abort(); } /* close handles to shared libraries */ if (env->h_odbc != NULL) xdlclose(env->h_odbc); if (env->h_mysql != NULL) xdlclose(env->h_mysql); /* close streams which are still open */ while (env->file_ptr != NULL) xfclose(env->file_ptr); /* free memory blocks which are still allocated */ while (env->mem_ptr != NULL) { desc = env->mem_ptr; env->mem_ptr = desc->next; free(desc); } /* invalidate the environment block */ env->magic = -1; /* free memory allocated to the environment block */ free(env->term_buf); free(env->ioerr_msg); free(env); /* reset a pointer to the environment block */ tls_set_ptr(NULL); /* termination successful */ return 0; } /* eof */ praat-6.0.04/external/glpk/glpenv02.c000066400000000000000000000041051261542461700173000ustar00rootroot00000000000000/* glpenv02.c (thread local storage) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpenv.h" static void *tls = NULL; /* in a re-entrant version of the package this variable must be placed in the Thread Local Storage (TLS) */ /*********************************************************************** * NAME * * tls_set_ptr - store global pointer in TLS * * SYNOPSIS * * #include "glpenv.h" * void tls_set_ptr(void *ptr); * * DESCRIPTION * * The routine tls_set_ptr stores a pointer specified by the parameter * ptr in the Thread Local Storage (TLS). */ void tls_set_ptr(void *ptr) { tls = ptr; return; } /*********************************************************************** * NAME * * tls_get_ptr - retrieve global pointer from TLS * * SYNOPSIS * * #include "glpenv.h" * void *tls_get_ptr(void); * * RETURNS * * The routine tls_get_ptr returns a pointer previously stored by the * routine tls_set_ptr. If the latter has not been called yet, NULL is * returned. */ void *tls_get_ptr(void) { void *ptr; ptr = tls; return ptr; } /* eof */ praat-6.0.04/external/glpk/glpenv03.c000066400000000000000000000147411261542461700173100ustar00rootroot00000000000000/* glpenv03.c (terminal output) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpapi.h" /*********************************************************************** * NAME * * glp_printf - write formatted output to terminal * * SYNOPSIS * * void glp_printf(const char *fmt, ...); * * DESCRIPTION * * The routine glp_printf uses the format control string fmt to format * its parameters and writes the formatted output to the terminal. */ void glp_printf(const char *fmt, ...) { va_list arg; va_start(arg, fmt); xvprintf(fmt, arg); va_end(arg); return; } /*********************************************************************** * NAME * * glp_vprintf - write formatted output to terminal * * SYNOPSIS * * void glp_vprintf(const char *fmt, va_list arg); * * DESCRIPTION * * The routine glp_vprintf uses the format control string fmt to format * its parameters specified by the list arg and writes the formatted * output to the terminal. */ void glp_vprintf(const char *fmt, va_list arg) { ENV *env = get_env_ptr(); /* if terminal output is disabled, do nothing */ if (!env->term_out) goto skip; /* format the output */ vsprintf(env->term_buf, fmt, arg); /* pass the output to the user-defined routine */ if (env->term_hook != NULL) { if (env->term_hook(env->term_info, env->term_buf) != 0) goto skip; } /* send the output to the terminal */ fputs(env->term_buf, stdout); fflush(stdout); /* copy the output to the text file */ if (env->tee_file != NULL) { fputs(env->term_buf, env->tee_file); fflush(env->tee_file); } skip: return; } /*********************************************************************** * NAME * * glp_term_out - enable/disable terminal output * * SYNOPSIS * * int glp_term_out(int flag); * * DESCRIPTION * * Depending on the parameter flag the routine glp_term_out enables or * disables terminal output performed by glpk routines: * * GLP_ON - enable terminal output; * GLP_OFF - disable terminal output. * * RETURNS * * The routine glp_term_out returns the previous value of the terminal * output flag. */ int glp_term_out(int flag) { ENV *env = get_env_ptr(); int old = env->term_out; if (!(flag == GLP_ON || flag == GLP_OFF)) xerror("glp_term_out: flag = %d; invalid value\n", flag); env->term_out = flag; return old; } /*********************************************************************** * NAME * * glp_term_hook - install hook to intercept terminal output * * SYNOPSIS * * void glp_term_hook(int (*func)(void *info, const char *s), * void *info); * * DESCRIPTION * * The routine glp_term_hook installs a user-defined hook routine to * intercept all terminal output performed by glpk routines. * * This feature can be used to redirect the terminal output to other * destination, for example to a file or a text window. * * The parameter func specifies the user-defined hook routine. It is * called from an internal printing routine, which passes to it two * parameters: info and s. The parameter info is a transit pointer, * specified in the corresponding call to the routine glp_term_hook; * it may be used to pass some information to the hook routine. The * parameter s is a pointer to the null terminated character string, * which is intended to be written to the terminal. If the hook routine * returns zero, the printing routine writes the string s to the * terminal in a usual way; otherwise, if the hook routine returns * non-zero, no terminal output is performed. * * To uninstall the hook routine the parameters func and info should be * specified as NULL. */ void glp_term_hook(int (*func)(void *info, const char *s), void *info) { ENV *env = get_env_ptr(); if (func == NULL) { env->term_hook = NULL; env->term_info = NULL; } else { env->term_hook = func; env->term_info = info; } return; } /*********************************************************************** * NAME * * glp_open_tee - start copying terminal output to text file * * SYNOPSIS * * int glp_open_tee(const char *fname); * * DESCRIPTION * * The routine glp_open_tee starts copying all the terminal output to * an output text file, whose name is specified by the character string * fname. * * RETURNS * * 0 - operation successful * 1 - copying terminal output is already active * 2 - unable to create output file */ int glp_open_tee(const char *fname) { ENV *env = get_env_ptr(); if (env->tee_file != NULL) { /* copying terminal output is already active */ return 1; } env->tee_file = fopen(fname, "w"); if (env->tee_file == NULL) { /* unable to create output file */ return 2; } return 0; } /*********************************************************************** * NAME * * glp_close_tee - stop copying terminal output to text file * * SYNOPSIS * * int glp_close_tee(void); * * DESCRIPTION * * The routine glp_close_tee stops copying the terminal output to the * output text file previously open by the routine glp_open_tee closing * that file. * * RETURNS * * 0 - operation successful * 1 - copying terminal output was not started */ int glp_close_tee(void) { ENV *env = get_env_ptr(); if (env->tee_file == NULL) { /* copying terminal output was not started */ return 1; } fclose(env->tee_file); env->tee_file = NULL; return 0; } /* eof */ praat-6.0.04/external/glpk/glpenv04.c000066400000000000000000000075101261542461700173050ustar00rootroot00000000000000/* glpenv04.c (error handling) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpapi.h" /*********************************************************************** * NAME * * glp_error - display error message and terminate execution * * SYNOPSIS * * void glp_error(const char *fmt, ...); * * DESCRIPTION * * The routine glp_error (implemented as a macro) formats its * parameters using the format control string fmt, writes the formatted * message to the terminal, and abnormally terminates the program. */ static void error(const char *fmt, ...) { ENV *env = get_env_ptr(); va_list arg; env->term_out = GLP_ON; va_start(arg, fmt); xvprintf(fmt, arg); va_end(arg); xprintf("Error detected in file %s at line %d\n", env->err_file, env->err_line); if (env->err_hook != NULL) env->err_hook(env->err_info); abort(); exit(EXIT_FAILURE); /* no return */ } _glp_error glp_error_(const char *file, int line) { ENV *env = get_env_ptr(); env->err_file = file; env->err_line = line; return error; } /*********************************************************************** * NAME * * glp_assert - check for logical condition * * SYNOPSIS * * #include "glplib.h" * void glp_assert(int expr); * * DESCRIPTION * * The routine glp_assert (implemented as a macro) checks for a logical * condition specified by the parameter expr. If the condition is false * (i.e. the value of expr is zero), the routine writes a message to * the terminal and abnormally terminates the program. */ void glp_assert_(const char *expr, const char *file, int line) { glp_error_(file, line)("Assertion failed: %s\n", expr); /* no return */ } /*********************************************************************** * NAME * * glp_error_hook - install hook to intercept abnormal termination * * SYNOPSIS * * void glp_error_hook(void (*func)(void *info), void *info); * * DESCRIPTION * * The routine glp_error_hook installs a user-defined hook routine to * intercept abnormal termination. * * The parameter func specifies the user-defined hook routine. It is * called from the routine glp_error before the latter calls the abort * function to abnormally terminate the application program because of * fatal error. The parameter info is a transit pointer, specified in * the corresponding call to the routine glp_error_hook; it may be used * to pass some information to the hook routine. * * To uninstall the hook routine the parameters func and info should be * specified as NULL. */ void glp_error_hook(void (*func)(void *info), void *info) { ENV *env = get_env_ptr(); if (func == NULL) { env->err_hook = NULL; env->err_info = NULL; } else { env->err_hook = func; env->err_info = info; } return; } /* eof */ praat-6.0.04/external/glpk/glpenv05.c000066400000000000000000000161301261542461700173040ustar00rootroot00000000000000/* glpenv05.c (memory allocation) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpapi.h" /* some processors need data to be properly aligned; the macro align_datasize enlarges the specified size of a data item to provide a proper alignment of immediately following data */ #define align_datasize(size) ((((size) + 15) / 16) * 16) /* 16 bytes is sufficient in both 32- and 64-bit environments (8 bytes is not sufficient in 64-bit environment due to jmp_buf) */ /*********************************************************************** * NAME * * glp_malloc - allocate memory block * * SYNOPSIS * * void *glp_malloc(int size); * * DESCRIPTION * * The routine glp_malloc allocates a memory block of size bytes long. * * Note that being allocated the memory block contains arbitrary data * (not binary zeros). * * RETURNS * * The routine glp_malloc returns a pointer to the allocated block. * To free this block the routine glp_free (not free!) must be used. */ void *glp_malloc(int size) { ENV *env = get_env_ptr(); MEM *desc; int size_of_desc = align_datasize(sizeof(MEM)); if (size < 1 || size > INT_MAX - size_of_desc) xerror("glp_malloc: size = %d; invalid parameter\n", size); size += size_of_desc; if (xlcmp(xlset(size), xlsub(env->mem_limit, env->mem_total)) > 0) xerror("glp_malloc: memory limit exceeded\n"); if (env->mem_count == INT_MAX) xerror("glp_malloc: too many memory blocks allocated\n"); desc = malloc(size); if (desc == NULL) xerror("glp_malloc: no memory available\n"); memset(desc, '?', size); desc->flag = MEM_MAGIC; desc->size = size; desc->prev = NULL; desc->next = env->mem_ptr; if (desc->next != NULL) desc->next->prev = desc; env->mem_ptr = desc; env->mem_count++; if (env->mem_cpeak < env->mem_count) env->mem_cpeak = env->mem_count; env->mem_total = xladd(env->mem_total, xlset(size)); if (xlcmp(env->mem_tpeak, env->mem_total) < 0) env->mem_tpeak = env->mem_total; return (void *)((char *)desc + size_of_desc); } /*********************************************************************** * NAME * * glp_calloc - allocate memory block * * SYNOPSIS * * void *glp_calloc(int n, int size); * * DESCRIPTION * * The routine glp_calloc allocates a memory block of (n*size) bytes * long. * * Note that being allocated the memory block contains arbitrary data * (not binary zeros). * * RETURNS * * The routine glp_calloc returns a pointer to the allocated block. * To free this block the routine glp_free (not free!) must be used. */ void *glp_calloc(int n, int size) { if (n < 1) xerror("glp_calloc: n = %d; invalid parameter\n", n); if (size < 1) xerror("glp_calloc: size = %d; invalid parameter\n", size); if (n > INT_MAX / size) xerror("glp_calloc: n = %d; size = %d; array too big\n", n, size); return xmalloc(n * size); } /*********************************************************************** * NAME * * glp_free - free memory block * * SYNOPSIS * * void glp_free(void *ptr); * * DESCRIPTION * * The routine glp_free frees a memory block pointed to by ptr, which * was previuosly allocated by the routine glp_malloc or glp_calloc. */ void glp_free(void *ptr) { ENV *env = get_env_ptr(); MEM *desc; int size_of_desc = align_datasize(sizeof(MEM)); if (ptr == NULL) xerror("glp_free: ptr = %p; null pointer\n", ptr); desc = (void *)((char *)ptr - size_of_desc); if (desc->flag != MEM_MAGIC) xerror("glp_free: ptr = %p; invalid pointer\n", ptr); if (env->mem_count == 0 || xlcmp(env->mem_total, xlset(desc->size)) < 0) xerror("glp_free: memory allocation error\n"); if (desc->prev == NULL) env->mem_ptr = desc->next; else desc->prev->next = desc->next; if (desc->next == NULL) ; else desc->next->prev = desc->prev; env->mem_count--; env->mem_total = xlsub(env->mem_total, xlset(desc->size)); memset(desc, '?', size_of_desc); free(desc); return; } /*********************************************************************** * NAME * * glp_mem_limit - set memory usage limit * * SYNOPSIS * * void glp_mem_limit(int limit); * * DESCRIPTION * * The routine glp_mem_limit limits the amount of memory available for * dynamic allocation (in GLPK routines) to limit megabytes. */ void glp_mem_limit(int limit) { ENV *env = get_env_ptr(); if (limit < 0) xerror("glp_mem_limit: limit = %d; invalid parameter\n", limit); env->mem_limit = xlmul(xlset(limit), xlset(1 << 20)); return; } /*********************************************************************** * NAME * * glp_mem_usage - get memory usage information * * SYNOPSIS * * void glp_mem_usage(int *count, int *cpeak, glp_long *total, * glp_long *tpeak); * * DESCRIPTION * * The routine glp_mem_usage reports some information about utilization * of the memory by GLPK routines. Information is stored to locations * specified by corresponding parameters (see below). Any parameter can * be specified as NULL, in which case corresponding information is not * stored. * * *count is the number of the memory blocks currently allocated by the * routines xmalloc and xcalloc (one call to xmalloc or xcalloc results * in allocating one memory block). * * *cpeak is the peak value of *count reached since the initialization * of the GLPK library environment. * * *total is the total amount, in bytes, of the memory blocks currently * allocated by the routines xmalloc and xcalloc. * * *tpeak is the peak value of *total reached since the initialization * of the GLPK library envirionment. */ void glp_mem_usage(int *count, int *cpeak, glp_long *total, glp_long *tpeak) { ENV *env = get_env_ptr(); if (count != NULL) *count = env->mem_count; if (cpeak != NULL) *cpeak = env->mem_cpeak; if (total != NULL) *total = env->mem_total; if (tpeak != NULL) *tpeak = env->mem_tpeak; return; } /* eof */ praat-6.0.04/external/glpk/glpenv06.c000066400000000000000000000111631261542461700173060ustar00rootroot00000000000000/* glpenv06.c (standard time) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifdef HAVE_CONFIG_H #include #endif #include "glpapi.h" /*********************************************************************** * NAME * * glp_time - determine current universal time * * SYNOPSIS * * glp_long glp_time(void); * * RETURNS * * The routine glp_time returns the current universal time (UTC), in * milliseconds, elapsed since 00:00:00 GMT January 1, 1970. */ static const int epoch = 2440588; /* = jday(1, 1, 1970) */ /* POSIX version ******************************************************/ #if defined(HAVE_SYS_TIME_H) && defined(HAVE_GETTIMEOFDAY) #include #include glp_long glp_time(void) { struct timeval tv; struct tm *tm; glp_long t; int j; gettimeofday(&tv, NULL); tm = gmtime(&tv.tv_sec); j = jday(tm->tm_mday, tm->tm_mon + 1, 1900 + tm->tm_year); xassert(j >= 0); t = xlset(j - epoch); t = xlmul(t, xlset(24)); t = xladd(t, xlset(tm->tm_hour)); t = xlmul(t, xlset(60)); t = xladd(t, xlset(tm->tm_min)); t = xlmul(t, xlset(60)); t = xladd(t, xlset(tm->tm_sec)); t = xlmul(t, xlset(1000)); t = xladd(t, xlset(tv.tv_usec / 1000)); return t; } /* Windows version ****************************************************/ #elif defined(__WOE__) #include glp_long glp_time(void) { SYSTEMTIME st; glp_long t; int j; GetSystemTime(&st); j = jday(st.wDay, st.wMonth, st.wYear); xassert(j >= 0); t = xlset(j - epoch); t = xlmul(t, xlset(24)); t = xladd(t, xlset(st.wHour)); t = xlmul(t, xlset(60)); t = xladd(t, xlset(st.wMinute)); t = xlmul(t, xlset(60)); t = xladd(t, xlset(st.wSecond)); t = xlmul(t, xlset(1000)); t = xladd(t, xlset(st.wMilliseconds)); return t; } /* portable ISO C version *********************************************/ #else #include glp_long glp_time(void) { time_t timer; struct tm *tm; glp_long t; int j; timer = time(NULL); tm = gmtime(&timer); j = jday(tm->tm_mday, tm->tm_mon + 1, 1900 + tm->tm_year); xassert(j >= 0); t = xlset(j - epoch); t = xlmul(t, xlset(24)); t = xladd(t, xlset(tm->tm_hour)); t = xlmul(t, xlset(60)); t = xladd(t, xlset(tm->tm_min)); t = xlmul(t, xlset(60)); t = xladd(t, xlset(tm->tm_sec)); t = xlmul(t, xlset(1000)); return t; } #endif /*********************************************************************** * NAME * * glp_difftime - compute difference between two time values * * SYNOPSIS * * double glp_difftime(glp_long t1, glp_long t0); * * RETURNS * * The routine glp_difftime returns the difference between two time * values t1 and t0, expressed in seconds. */ double glp_difftime(glp_long t1, glp_long t0) { return xltod(xlsub(t1, t0)) / 1000.0; } /**********************************************************************/ #if 0 int main(void) { glp_long t; glp_ldiv d; int ttt, ss, mm, hh, day, month, year; char s[50]; t = glp_time(); xprintf("t = %s\n", xltoa(t, s)); d = xldiv(t, xlset(1000)); ttt = d.rem.lo, t = d.quot; d = xldiv(t, xlset(60)); ss = d.rem.lo, t = d.quot; d = xldiv(t, xlset(60)); mm = d.rem.lo, t = d.quot; d = xldiv(t, xlset(24)); hh = d.rem.lo, t = d.quot; xassert(jdate(t.lo + epoch, &day, &month, &year) == 0); xprintf("%04d-%02d-%02d %02d:%02d:%02d.%03d\n", year, month, day, hh, mm, ss, ttt); return 0; } #endif /* eof */ praat-6.0.04/external/glpk/glpenv07.c000066400000000000000000000370251261542461700173140ustar00rootroot00000000000000/* glpenv07.c (stream input/output) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifdef HAVE_CONFIG_H #include #endif #include "glpenv.h" /*********************************************************************** * NAME * * lib_err_msg - save error message string * * SYNOPSIS * * #include "glpenv.h" * void lib_err_msg(const char *msg); * * DESCRIPTION * * The routine lib_err_msg saves an error message string specified by * the parameter msg. The message is obtained by some library routines * with a call to strerror(errno). */ void lib_err_msg(const char *msg) { ENV *env = get_env_ptr(); int len = strlen(msg); if (len >= IOERR_MSG_SIZE) len = IOERR_MSG_SIZE - 1; memcpy(env->ioerr_msg, msg, len); if (len > 0 && env->ioerr_msg[len-1] == '\n') len--; env->ioerr_msg[len] = '\0'; return; } /*********************************************************************** * NAME * * xerrmsg - retrieve error message string * * SYNOPSIS * * #include "glpenv.h" * const char *xerrmsg(void); * * RETURNS * * The routine xerrmsg returns a pointer to an error message string * previously set by some library routine to indicate an error. */ const char *xerrmsg(void) { ENV *env = get_env_ptr(); return env->ioerr_msg; } /*********************************************************************** * NAME * * xfopen - open a stream * * SYNOPSIS * * #include "glpenv.h" * XFILE *xfopen(const char *fname, const char *mode); * * DESCRIPTION * * The routine xfopen opens the file whose name is a string pointed to * by fname and associates a stream with it. * * The parameter mode points to a string, which indicates the open mode * and should be one of the following: * * "r" open text file for reading; * "w" truncate to zero length or create text file for writing; * "rb" open binary file for reading; * "wb" truncate to zero length or create binary file for writing. * * RETURNS * * The routine xfopen returns a pointer to the object controlling the * stream. If the open operation fails, xfopen returns NULL. */ static void *c_fopen(const char *fname, const char *mode); static void *z_fopen(const char *fname, const char *mode); static int is_gz_file(const char *fname) { char *ext = strrchr(fname, '.'); return ext != NULL && strcmp(ext, ".gz") == 0; } XFILE *xfopen(const char *fname, const char *mode) { ENV *env = get_env_ptr(); XFILE *fp; int type; void *fh; if (!is_gz_file(fname)) { type = FH_FILE; fh = c_fopen(fname, mode); } else { type = FH_ZLIB; fh = z_fopen(fname, mode); } if (fh == NULL) { fp = NULL; goto done; } fp = xmalloc(sizeof(XFILE)); fp->type = type; fp->fh = fh; fp->prev = NULL; fp->next = env->file_ptr; if (fp->next != NULL) fp->next->prev = fp; env->file_ptr = fp; done: return fp; } /*********************************************************************** * NAME * * xfgetc - read character from the stream * * SYNOPSIS * * #include "glpenv.h" * int xfgetc(XFILE *fp); * * DESCRIPTION * * If the end-of-file indicator for the input stream pointed to by fp * is not set and a next character is present, the routine xfgetc * obtains that character as an unsigned char converted to an int and * advances the associated file position indicator for the stream (if * defined). * * RETURNS * * If the end-of-file indicator for the stream is set, or if the * stream is at end-of-file, the end-of-file indicator for the stream * is set and the routine xfgetc returns XEOF. Otherwise, the routine * xfgetc returns the next character from the input stream pointed to * by fp. If a read error occurs, the error indicator for the stream is * set and the xfgetc routine returns XEOF. * * Note: An end-of-file and a read error can be distinguished by use of * the routines xfeof and xferror. */ static int c_fgetc(void *fh); static int z_fgetc(void *fh); int xfgetc(XFILE *fp) { int c; switch (fp->type) { case FH_FILE: c = c_fgetc(fp->fh); break; case FH_ZLIB: c = z_fgetc(fp->fh); break; default: xassert(fp != fp); } return c; } /*********************************************************************** * NAME * * xfputc - write character to the stream * * SYNOPSIS * * #include "glpenv.h" * int xfputc(int c, XFILE *fp); * * DESCRIPTION * * The routine xfputc writes the character specified by c (converted * to an unsigned char) to the output stream pointed to by fp, at the * position indicated by the associated file position indicator (if * defined), and advances the indicator appropriately. * * RETURNS * * The routine xfputc returns the character written. If a write error * occurs, the error indicator for the stream is set and xfputc returns * XEOF. */ static int c_fputc(int c, void *fh); static int z_fputc(int c, void *fh); int xfputc(int c, XFILE *fp) { switch (fp->type) { case FH_FILE: c = c_fputc(c, fp->fh); break; case FH_ZLIB: c = z_fputc(c, fp->fh); break; default: xassert(fp != fp); } return c; } /*********************************************************************** * NAME * * xferror - test error indicator for the stream * * SYNOPSIS * * #include "glpenv.h" * int xferror(XFILE *fp); * * DESCRIPTION * * The routine xferror tests the error indicator for the stream * pointed to by fp. * * RETURNS * * The routine xferror returns non-zero if and only if the error * indicator is set for the stream. */ static int c_ferror(void *fh); static int z_ferror(void *fh); int xferror(XFILE *fp) { int ret; switch (fp->type) { case FH_FILE: ret = c_ferror(fp->fh); break; case FH_ZLIB: ret = z_ferror(fp->fh); break; default: xassert(fp != fp); } return ret; } /*********************************************************************** * NAME * * xfeof - test end-of-file indicator for the stream * * SYNOPSIS * * #include "glpenv.h" * int xfeof(XFILE *fp); * * DESCRIPTION * * The routine xfeof tests the end-of-file indicator for the stream * pointed to by fp. * * RETURNS * * The routine xfeof returns non-zero if and only if the end-of-file * indicator is set for the stream. */ static int c_feof(void *fh); static int z_feof(void *fh); int xfeof(XFILE *fp) { int ret; switch (fp->type) { case FH_FILE: ret = c_feof(fp->fh); break; case FH_ZLIB: ret = z_feof(fp->fh); break; default: xassert(fp != fp); } return ret; } int xfprintf(XFILE *file, const char *fmt, ...) { ENV *env = get_env_ptr(); int cnt, j; va_list arg; va_start(arg, fmt); cnt = vsprintf(env->term_buf, fmt, arg); va_end(arg); for (j = 0; j < cnt; j++) { if (xfputc(env->term_buf[j], file) < 0) { cnt = -1; break; } } return cnt; } /*********************************************************************** * NAME * * xfflush - flush the stream * * SYNOPSIS * * #include "glpenv.h" * int xfflush(XFILE *fp); * * DESCRIPTION * * The routine xfflush causes any unwritten data for the output stream * pointed to by fp to be written to the associated file. * * RETURNS * * The routine xfflush returns zero if the stream was successfully * flushed. Otherwise, xfflush sets the error indicator for the stream * and returns XEOF. */ static int c_fflush(void *fh); static int z_fflush(void *fh); int xfflush(XFILE *fp) { int ret; switch (fp->type) { case FH_FILE: ret = c_fflush(fp->fh); break; case FH_ZLIB: ret = z_fflush(fp->fh); break; default: xassert(fp != fp); } return ret; } /*********************************************************************** * NAME * * xfclose - close the stream * * SYNOPSIS * * #include "glpenv.h" * int xfclose(XFILE *fp); * * DESCRIPTION * * A successful call to the routine xfclose causes the stream pointed * to by fp to be flushed and the associated file to be closed. Whether * or not the call succeeds, the stream is disassociated from the file. * * RETURNS * * The routine xfclose returns zero if the stream was successfully * closed, or XEOF if any errors were detected. */ static int c_fclose(void *fh); static int z_fclose(void *fh); int xfclose(XFILE *fp) { ENV *env = get_env_ptr(); int ret; switch (fp->type) { case FH_FILE: ret = c_fclose(fp->fh); break; case FH_ZLIB: ret = z_fclose(fp->fh); break; default: xassert(fp != fp); } fp->type = 0xF00BAD; if (fp->prev == NULL) env->file_ptr = fp->next; else fp->prev->next = fp->next; if (fp->next == NULL) ; else fp->next->prev = fp->prev; xfree(fp); return ret; } /*********************************************************************** * The following routines implement stream input/output based on the * standard C streams. */ static void *c_fopen(const char *fname, const char *mode) { FILE *fh; if (strcmp(fname, "/dev/stdin") == 0) fh = stdin; else if (strcmp(fname, "/dev/stdout") == 0) fh = stdout; else if (strcmp(fname, "/dev/stderr") == 0) fh = stderr; else fh = fopen(fname, mode); if (fh == NULL) lib_err_msg(strerror(errno)); return fh; } static int c_fgetc(void *_fh) { FILE *fh = _fh; int c; if (ferror(fh) || feof(fh)) { c = XEOF; goto done; } c = fgetc(fh); if (ferror(fh)) { lib_err_msg(strerror(errno)); c = XEOF; } else if (feof(fh)) c = XEOF; else xassert(0x00 <= c && c <= 0xFF); done: return c; } static int c_fputc(int c, void *_fh) { FILE *fh = _fh; if (ferror(fh)) { c = XEOF; goto done; } c = (unsigned char)c; fputc(c, fh); if (ferror(fh)) { lib_err_msg(strerror(errno)); c = XEOF; } done: return c; } static int c_ferror(void *_fh) { FILE *fh = _fh; return ferror(fh); } static int c_feof(void *_fh) { FILE *fh = _fh; return feof(fh); } static int c_fflush(void *_fh) { FILE *fh = _fh; int ret; ret = fflush(fh); if (ret != 0) { lib_err_msg(strerror(errno)); ret = XEOF; } return ret; } static int c_fclose(void *_fh) { FILE *fh = _fh; int ret; if (fh == stdin) ret = 0; else if (fh == stdout || fh == stderr) fflush(fh), ret = 0; else ret = fclose(fh); if (ret != 0) { lib_err_msg(strerror(errno)); ret = XEOF; } return ret; } /*********************************************************************** * The following routines implement stream input/output based on the * zlib library, which provides processing .gz files "on the fly". */ #ifndef HAVE_ZLIB static void *z_fopen(const char *fname, const char *mode) { xassert(fname == fname); xassert(mode == mode); lib_err_msg("Compressed files not supported"); return NULL; } static int z_fgetc(void *fh) { xassert(fh != fh); return 0; } static int z_fputc(int c, void *fh) { xassert(c != c); xassert(fh != fh); return 0; } static int z_ferror(void *fh) { xassert(fh != fh); return 0; } static int z_feof(void *fh) { xassert(fh != fh); return 0; } static int z_fflush(void *fh) { xassert(fh != fh); return 0; } static int z_fclose(void *fh) { xassert(fh != fh); return 0; } #else #include struct z_file { /* .gz file handle */ gzFile file; /* pointer to .gz stream */ int err; /* i/o error indicator */ int eof; /* end-of-file indicator */ }; static void *z_fopen(const char *fname, const char *mode) { struct z_file *fh; gzFile file; if (strcmp(mode, "r") == 0 || strcmp(mode, "rb") == 0) mode = "rb"; else if (strcmp(mode, "w") == 0 || strcmp(mode, "wb") == 0) mode = "wb"; else { lib_err_msg("Invalid open mode"); fh = NULL; goto done; } file = gzopen(fname, mode); if (file == NULL) { lib_err_msg(strerror(errno)); fh = NULL; goto done; } fh = xmalloc(sizeof(struct z_file)); fh->file = file; fh->err = fh->eof = 0; done: return fh; } static int z_fgetc(void *_fh) { struct z_file *fh = _fh; int c; if (fh->err || fh->eof) { c = XEOF; goto done; } c = gzgetc(fh->file); if (c < 0) { int errnum; const char *msg; msg = gzerror(fh->file, &errnum); if (errnum == Z_STREAM_END) fh->eof = 1; else if (errnum == Z_ERRNO) { fh->err = 1; lib_err_msg(strerror(errno)); } else { fh->err = 1; lib_err_msg(msg); } c = XEOF; } else xassert(0x00 <= c && c <= 0xFF); done: return c; } static int z_fputc(int c, void *_fh) { struct z_file *fh = _fh; if (fh->err) { c = XEOF; goto done; } c = (unsigned char)c; if (gzputc(fh->file, c) < 0) { int errnum; const char *msg; fh->err = 1; msg = gzerror(fh->file, &errnum); if (errnum == Z_ERRNO) lib_err_msg(strerror(errno)); else lib_err_msg(msg); c = XEOF; } done: return c; } static int z_ferror(void *_fh) { struct z_file *fh = _fh; return fh->err; } static int z_feof(void *_fh) { struct z_file *fh = _fh; return fh->eof; } static int z_fflush(void *_fh) { struct z_file *fh = _fh; int ret; ret = gzflush(fh->file, Z_FINISH); if (ret == Z_OK) ret = 0; else { int errnum; const char *msg; fh->err = 1; msg = gzerror(fh->file, &errnum); if (errnum == Z_ERRNO) lib_err_msg(strerror(errno)); else lib_err_msg(msg); ret = XEOF; } return ret; } static int z_fclose(void *_fh) { struct z_file *fh = _fh; gzclose(fh->file); xfree(fh); return 0; } #endif /* eof */ praat-6.0.04/external/glpk/glpenv08.c000066400000000000000000000074321261542461700173140ustar00rootroot00000000000000/* glpenv08.c (shared library support) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifdef HAVE_CONFIG_H #include #endif #include "glpenv.h" /* GNU version ********************************************************/ #if defined(HAVE_LTDL) #include void *xdlopen(const char *module) { void *h = NULL; if (lt_dlinit() != 0) { lib_err_msg(lt_dlerror()); goto done; } h = lt_dlopen(module); if (h == NULL) { lib_err_msg(lt_dlerror()); if (lt_dlexit() != 0) xerror("xdlopen: %s\n", lt_dlerror()); } done: return h; } void *xdlsym(void *h, const char *symbol) { void *ptr; xassert(h != NULL); ptr = lt_dlsym(h, symbol); if (ptr == NULL) xerror("xdlsym: %s: %s\n", symbol, lt_dlerror()); return ptr; } void xdlclose(void *h) { xassert(h != NULL); if (lt_dlclose(h) != 0) xerror("xdlclose: %s\n", lt_dlerror()); if (lt_dlexit() != 0) xerror("xdlclose: %s\n", lt_dlerror()); return; } /* POSIX version ******************************************************/ #elif defined(HAVE_DLFCN) #include void *xdlopen(const char *module) { void *h; h = dlopen(module, RTLD_NOW); if (h == NULL) lib_err_msg(dlerror()); return h; } void *xdlsym(void *h, const char *symbol) { void *ptr; xassert(h != NULL); ptr = dlsym(h, symbol); if (ptr == NULL) xerror("xdlsym: %s: %s\n", symbol, dlerror()); return ptr; } void xdlclose(void *h) { xassert(h != NULL); if (dlclose(h) != 0) xerror("xdlclose: %s\n", dlerror()); return; } /* Windows version ****************************************************/ #elif defined(__WOE__) #include void *xdlopen(const char *module) { void *h; h = LoadLibrary(module); if (h == NULL) { char msg[20]; sprintf(msg, "Error %d", GetLastError()); lib_err_msg(msg); } return h; } void *xdlsym(void *h, const char *symbol) { void *ptr; xassert(h != NULL); ptr = GetProcAddress(h, symbol); if (ptr == NULL) xerror("xdlsym: %s: Error %d\n", symbol, GetLastError()); return ptr; } void xdlclose(void *h) { xassert(h != NULL); if (!FreeLibrary(h)) xerror("xdlclose: Error %d\n", GetLastError()); return; } /* NULL version *******************************************************/ #else void *xdlopen(const char *module) { xassert(module == module); lib_err_msg("Shared libraries not supported"); return NULL; } void *xdlsym(void *h, const char *symbol) { xassert(h != h); xassert(symbol != symbol); return NULL; } void xdlclose(void *h) { xassert(h != h); return; } #endif /* eof */ praat-6.0.04/external/glpk/glpfhv.c000066400000000000000000000654201261542461700171400ustar00rootroot00000000000000/* glpfhv.c (LP basis factorization, FHV eta file version) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpfhv.h" #include "glpenv.h" #define xfault xerror /* CAUTION: DO NOT CHANGE THE LIMIT BELOW */ #define M_MAX 100000000 /* = 100*10^6 */ /* maximal order of the basis matrix */ /*********************************************************************** * NAME * * fhv_create_it - create LP basis factorization * * SYNOPSIS * * #include "glpfhv.h" * FHV *fhv_create_it(void); * * DESCRIPTION * * The routine fhv_create_it creates a program object, which represents * a factorization of LP basis. * * RETURNS * * The routine fhv_create_it returns a pointer to the object created. */ FHV *fhv_create_it(void) { FHV *fhv; fhv = xmalloc(sizeof(FHV)); fhv->m_max = fhv->m = 0; fhv->valid = 0; fhv->luf = luf_create_it(); fhv->hh_max = 50; fhv->hh_nfs = 0; fhv->hh_ind = fhv->hh_ptr = fhv->hh_len = NULL; fhv->p0_row = fhv->p0_col = NULL; fhv->cc_ind = NULL; fhv->cc_val = NULL; fhv->upd_tol = 1e-6; fhv->nnz_h = 0; return fhv; } /*********************************************************************** * NAME * * fhv_factorize - compute LP basis factorization * * SYNOPSIS * * #include "glpfhv.h" * int fhv_factorize(FHV *fhv, int m, int (*col)(void *info, int j, * int ind[], double val[]), void *info); * * DESCRIPTION * * The routine fhv_factorize computes the factorization of the basis * matrix B specified by the routine col. * * The parameter fhv specified the basis factorization data structure * created by the routine fhv_create_it. * * The parameter m specifies the order of B, m > 0. * * The formal routine col specifies the matrix B to be factorized. To * obtain j-th column of A the routine fhv_factorize calls the routine * col with the parameter j (1 <= j <= n). In response the routine col * should store row indices and numerical values of non-zero elements * of j-th column of B to locations ind[1,...,len] and val[1,...,len], * respectively, where len is the number of non-zeros in j-th column * returned on exit. Neither zero nor duplicate elements are allowed. * * The parameter info is a transit pointer passed to the routine col. * * RETURNS * * 0 The factorization has been successfully computed. * * FHV_ESING * The specified matrix is singular within the working precision. * * FHV_ECOND * The specified matrix is ill-conditioned. * * For more details see comments to the routine luf_factorize. * * ALGORITHM * * The routine fhv_factorize calls the routine luf_factorize (see the * module GLPLUF), which actually computes LU-factorization of the basis * matrix B in the form * * [B] = (F, V, P, Q), * * where F and V are such matrices that * * B = F * V, * * and P and Q are such permutation matrices that the matrix * * L = P * F * inv(P) * * is lower triangular with unity diagonal, and the matrix * * U = P * V * Q * * is upper triangular. * * In order to build the complete representation of the factorization * (see formula (1) in the file glpfhv.h) the routine fhv_factorize just * additionally sets H = I and P0 = P. */ int fhv_factorize(FHV *fhv, int m, int (*col)(void *info, int j, int ind[], double val[]), void *info) { int ret; if (m < 1) xfault("fhv_factorize: m = %d; invalid parameter\n", m); if (m > M_MAX) xfault("fhv_factorize: m = %d; matrix too big\n", m); fhv->m = m; /* invalidate the factorization */ fhv->valid = 0; /* allocate/reallocate arrays, if necessary */ if (fhv->hh_ind == NULL) fhv->hh_ind = xcalloc(1+fhv->hh_max, sizeof(int)); if (fhv->hh_ptr == NULL) fhv->hh_ptr = xcalloc(1+fhv->hh_max, sizeof(int)); if (fhv->hh_len == NULL) fhv->hh_len = xcalloc(1+fhv->hh_max, sizeof(int)); if (fhv->m_max < m) { if (fhv->p0_row != NULL) xfree(fhv->p0_row); if (fhv->p0_col != NULL) xfree(fhv->p0_col); if (fhv->cc_ind != NULL) xfree(fhv->cc_ind); if (fhv->cc_val != NULL) xfree(fhv->cc_val); fhv->m_max = m + 100; fhv->p0_row = xcalloc(1+fhv->m_max, sizeof(int)); fhv->p0_col = xcalloc(1+fhv->m_max, sizeof(int)); fhv->cc_ind = xcalloc(1+fhv->m_max, sizeof(int)); fhv->cc_val = xcalloc(1+fhv->m_max, sizeof(double)); } /* try to factorize the basis matrix */ switch (luf_factorize(fhv->luf, m, col, info)) { case 0: break; case LUF_ESING: ret = FHV_ESING; goto done; case LUF_ECOND: ret = FHV_ECOND; goto done; default: xassert(fhv != fhv); } /* the basis matrix has been successfully factorized */ fhv->valid = 1; /* H := I */ fhv->hh_nfs = 0; /* P0 := P */ memcpy(&fhv->p0_row[1], &fhv->luf->pp_row[1], sizeof(int) * m); memcpy(&fhv->p0_col[1], &fhv->luf->pp_col[1], sizeof(int) * m); /* currently H has no factors */ fhv->nnz_h = 0; ret = 0; done: /* return to the calling program */ return ret; } /*********************************************************************** * NAME * * fhv_h_solve - solve system H*x = b or H'*x = b * * SYNOPSIS * * #include "glpfhv.h" * void fhv_h_solve(FHV *fhv, int tr, double x[]); * * DESCRIPTION * * The routine fhv_h_solve solves either the system H*x = b (if the * flag tr is zero) or the system H'*x = b (if the flag tr is non-zero), * where the matrix H is a component of the factorization specified by * the parameter fhv, H' is a matrix transposed to H. * * On entry the array x should contain elements of the right-hand side * vector b in locations x[1], ..., x[m], where m is the order of the * matrix H. On exit this array will contain elements of the solution * vector x in the same locations. */ void fhv_h_solve(FHV *fhv, int tr, double x[]) { int nfs = fhv->hh_nfs; int *hh_ind = fhv->hh_ind; int *hh_ptr = fhv->hh_ptr; int *hh_len = fhv->hh_len; int *sv_ind = fhv->luf->sv_ind; double *sv_val = fhv->luf->sv_val; int i, k, beg, end, ptr; double temp; if (!fhv->valid) xfault("fhv_h_solve: the factorization is not valid\n"); if (!tr) { /* solve the system H*x = b */ for (k = 1; k <= nfs; k++) { i = hh_ind[k]; temp = x[i]; beg = hh_ptr[k]; end = beg + hh_len[k] - 1; for (ptr = beg; ptr <= end; ptr++) temp -= sv_val[ptr] * x[sv_ind[ptr]]; x[i] = temp; } } else { /* solve the system H'*x = b */ for (k = nfs; k >= 1; k--) { i = hh_ind[k]; temp = x[i]; if (temp == 0.0) continue; beg = hh_ptr[k]; end = beg + hh_len[k] - 1; for (ptr = beg; ptr <= end; ptr++) x[sv_ind[ptr]] -= sv_val[ptr] * temp; } } return; } /*********************************************************************** * NAME * * fhv_ftran - perform forward transformation (solve system B*x = b) * * SYNOPSIS * * #include "glpfhv.h" * void fhv_ftran(FHV *fhv, double x[]); * * DESCRIPTION * * The routine fhv_ftran performs forward transformation, i.e. solves * the system B*x = b, where B is the basis matrix, x is the vector of * unknowns to be computed, b is the vector of right-hand sides. * * On entry elements of the vector b should be stored in dense format * in locations x[1], ..., x[m], where m is the number of rows. On exit * the routine stores elements of the vector x in the same locations. */ void fhv_ftran(FHV *fhv, double x[]) { int *pp_row = fhv->luf->pp_row; int *pp_col = fhv->luf->pp_col; int *p0_row = fhv->p0_row; int *p0_col = fhv->p0_col; if (!fhv->valid) xfault("fhv_ftran: the factorization is not valid\n"); /* B = F*H*V, therefore inv(B) = inv(V)*inv(H)*inv(F) */ fhv->luf->pp_row = p0_row; fhv->luf->pp_col = p0_col; luf_f_solve(fhv->luf, 0, x); fhv->luf->pp_row = pp_row; fhv->luf->pp_col = pp_col; fhv_h_solve(fhv, 0, x); luf_v_solve(fhv->luf, 0, x); return; } /*********************************************************************** * NAME * * fhv_btran - perform backward transformation (solve system B'*x = b) * * SYNOPSIS * * #include "glpfhv.h" * void fhv_btran(FHV *fhv, double x[]); * * DESCRIPTION * * The routine fhv_btran performs backward transformation, i.e. solves * the system B'*x = b, where B' is a matrix transposed to the basis * matrix B, x is the vector of unknowns to be computed, b is the vector * of right-hand sides. * * On entry elements of the vector b should be stored in dense format * in locations x[1], ..., x[m], where m is the number of rows. On exit * the routine stores elements of the vector x in the same locations. */ void fhv_btran(FHV *fhv, double x[]) { int *pp_row = fhv->luf->pp_row; int *pp_col = fhv->luf->pp_col; int *p0_row = fhv->p0_row; int *p0_col = fhv->p0_col; if (!fhv->valid) xfault("fhv_btran: the factorization is not valid\n"); /* B = F*H*V, therefore inv(B') = inv(F')*inv(H')*inv(V') */ luf_v_solve(fhv->luf, 1, x); fhv_h_solve(fhv, 1, x); fhv->luf->pp_row = p0_row; fhv->luf->pp_col = p0_col; luf_f_solve(fhv->luf, 1, x); fhv->luf->pp_row = pp_row; fhv->luf->pp_col = pp_col; return; } /*********************************************************************** * NAME * * fhv_update_it - update LP basis factorization * * SYNOPSIS * * #include "glpfhv.h" * int fhv_update_it(FHV *fhv, int j, int len, const int ind[], * const double val[]); * * DESCRIPTION * * The routine fhv_update_it updates the factorization of the basis * matrix B after replacing its j-th column by a new vector. * * The parameter j specifies the number of column of B, which has been * replaced, 1 <= j <= m, where m is the order of B. * * Row indices and numerical values of non-zero elements of the new * column of B should be placed in locations ind[1], ..., ind[len] and * val[1], ..., val[len], resp., where len is the number of non-zeros * in the column. Neither zero nor duplicate elements are allowed. * * RETURNS * * 0 The factorization has been successfully updated. * * FHV_ESING * The adjacent basis matrix is structurally singular, since after * changing j-th column of matrix V by the new column (see algorithm * below) the case k1 > k2 occured. * * FHV_ECHECK * The factorization is inaccurate, since after transforming k2-th * row of matrix U = P*V*Q, its diagonal element u[k2,k2] is zero or * close to zero, * * FHV_ELIMIT * Maximal number of H factors has been reached. * * FHV_EROOM * Overflow of the sparse vector area. * * In case of non-zero return code the factorization becomes invalid. * It should not be used until it has been recomputed with the routine * fhv_factorize. * * ALGORITHM * * The routine fhv_update_it is based on the transformation proposed by * Forrest and Tomlin. * * Let j-th column of the basis matrix B have been replaced by new * column B[j]. In order to keep the equality B = F*H*V j-th column of * matrix V should be replaced by the column inv(F*H)*B[j]. * * From the standpoint of matrix U = P*V*Q, replacement of j-th column * of matrix V is equivalent to replacement of k1-th column of matrix U, * where k1 is determined by permutation matrix Q. Thus, matrix U loses * its upper triangular form and becomes the following: * * 1 k1 k2 m * 1 x x * x x x x x x x * . x * x x x x x x x * k1 . . * x x x x x x x * . . * x x x x x x x * . . * . x x x x x x * . . * . . x x x x x * . . * . . . x x x x * k2 . . * . . . . x x x * . . . . . . . . x x * m . . . . . . . . . x * * where row index k2 corresponds to the lowest non-zero element of * k1-th column. * * The routine moves rows and columns k1+1, k1+2, ..., k2 of matrix U * by one position to the left and upwards and moves k1-th row and k1-th * column to position k2. As the result of such symmetric permutations * matrix U becomes the following: * * 1 k1 k2 m * 1 x x x x x x x * x x * . x x x x x x * x x * k1 . . x x x x x * x x * . . . x x x x * x x * . . . . x x x * x x * . . . . . x x * x x * . . . . . . x * x x * k2 . . x x x x x * x x * . . . . . . . . x x * m . . . . . . . . . x * * Then the routine performs gaussian elimination to eliminate elements * u[k2,k1], u[k2,k1+1], ..., u[k2,k2-1] using diagonal elements * u[k1,k1], u[k1+1,k1+1], ..., u[k2-1,k2-1] as pivots in the same way * as described in comments to the routine luf_factorize (see the module * GLPLUF). Note that actually all operations are performed on matrix V, * not on matrix U. During the elimination process the routine permutes * neither rows nor columns, so only k2-th row of matrix U is changed. * * To keep the main equality B = F*H*V, each time when the routine * applies elementary gaussian transformation to the transformed row of * matrix V (which corresponds to k2-th row of matrix U), it also adds * a new element (gaussian multiplier) to the current row-like factor * of matrix H, which corresponds to the transformed row of matrix V. */ int fhv_update_it(FHV *fhv, int j, int len, const int ind[], const double val[]) { int m = fhv->m; LUF *luf = fhv->luf; int *vr_ptr = luf->vr_ptr; int *vr_len = luf->vr_len; int *vr_cap = luf->vr_cap; double *vr_piv = luf->vr_piv; int *vc_ptr = luf->vc_ptr; int *vc_len = luf->vc_len; int *vc_cap = luf->vc_cap; int *pp_row = luf->pp_row; int *pp_col = luf->pp_col; int *qq_row = luf->qq_row; int *qq_col = luf->qq_col; int *sv_ind = luf->sv_ind; double *sv_val = luf->sv_val; double *work = luf->work; double eps_tol = luf->eps_tol; int *hh_ind = fhv->hh_ind; int *hh_ptr = fhv->hh_ptr; int *hh_len = fhv->hh_len; int *p0_row = fhv->p0_row; int *p0_col = fhv->p0_col; int *cc_ind = fhv->cc_ind; double *cc_val = fhv->cc_val; double upd_tol = fhv->upd_tol; int i, i_beg, i_end, i_ptr, j_beg, j_end, j_ptr, k, k1, k2, p, q, p_beg, p_end, p_ptr, ptr, ret; double f, temp; if (!fhv->valid) xfault("fhv_update_it: the factorization is not valid\n"); if (!(1 <= j && j <= m)) xfault("fhv_update_it: j = %d; column number out of range\n", j); /* check if the new factor of matrix H can be created */ if (fhv->hh_nfs == fhv->hh_max) { /* maximal number of updates has been reached */ fhv->valid = 0; ret = FHV_ELIMIT; goto done; } /* convert new j-th column of B to dense format */ for (i = 1; i <= m; i++) cc_val[i] = 0.0; for (k = 1; k <= len; k++) { i = ind[k]; if (!(1 <= i && i <= m)) xfault("fhv_update_it: ind[%d] = %d; row number out of rang" "e\n", k, i); if (cc_val[i] != 0.0) xfault("fhv_update_it: ind[%d] = %d; duplicate row index no" "t allowed\n", k, i); if (val[k] == 0.0) xfault("fhv_update_it: val[%d] = %g; zero element not allow" "ed\n", k, val[k]); cc_val[i] = val[k]; } /* new j-th column of V := inv(F * H) * (new B[j]) */ fhv->luf->pp_row = p0_row; fhv->luf->pp_col = p0_col; luf_f_solve(fhv->luf, 0, cc_val); fhv->luf->pp_row = pp_row; fhv->luf->pp_col = pp_col; fhv_h_solve(fhv, 0, cc_val); /* convert new j-th column of V to sparse format */ len = 0; for (i = 1; i <= m; i++) { temp = cc_val[i]; if (temp == 0.0 || fabs(temp) < eps_tol) continue; len++, cc_ind[len] = i, cc_val[len] = temp; } /* clear old content of j-th column of matrix V */ j_beg = vc_ptr[j]; j_end = j_beg + vc_len[j] - 1; for (j_ptr = j_beg; j_ptr <= j_end; j_ptr++) { /* get row index of v[i,j] */ i = sv_ind[j_ptr]; /* find v[i,j] in the i-th row */ i_beg = vr_ptr[i]; i_end = i_beg + vr_len[i] - 1; for (i_ptr = i_beg; sv_ind[i_ptr] != j; i_ptr++) /* nop */; xassert(i_ptr <= i_end); /* remove v[i,j] from the i-th row */ sv_ind[i_ptr] = sv_ind[i_end]; sv_val[i_ptr] = sv_val[i_end]; vr_len[i]--; } /* now j-th column of matrix V is empty */ luf->nnz_v -= vc_len[j]; vc_len[j] = 0; /* add new elements of j-th column of matrix V to corresponding row lists; determine indices k1 and k2 */ k1 = qq_row[j], k2 = 0; for (ptr = 1; ptr <= len; ptr++) { /* get row index of v[i,j] */ i = cc_ind[ptr]; /* at least one unused location is needed in i-th row */ if (vr_len[i] + 1 > vr_cap[i]) { if (luf_enlarge_row(luf, i, vr_len[i] + 10)) { /* overflow of the sparse vector area */ fhv->valid = 0; luf->new_sva = luf->sv_size + luf->sv_size; xassert(luf->new_sva > luf->sv_size); ret = FHV_EROOM; goto done; } } /* add v[i,j] to i-th row */ i_ptr = vr_ptr[i] + vr_len[i]; sv_ind[i_ptr] = j; sv_val[i_ptr] = cc_val[ptr]; vr_len[i]++; /* adjust index k2 */ if (k2 < pp_col[i]) k2 = pp_col[i]; } /* capacity of j-th column (which is currently empty) should be not less than len locations */ if (vc_cap[j] < len) { if (luf_enlarge_col(luf, j, len)) { /* overflow of the sparse vector area */ fhv->valid = 0; luf->new_sva = luf->sv_size + luf->sv_size; xassert(luf->new_sva > luf->sv_size); ret = FHV_EROOM; goto done; } } /* add new elements of matrix V to j-th column list */ j_ptr = vc_ptr[j]; memmove(&sv_ind[j_ptr], &cc_ind[1], len * sizeof(int)); memmove(&sv_val[j_ptr], &cc_val[1], len * sizeof(double)); vc_len[j] = len; luf->nnz_v += len; /* if k1 > k2, diagonal element u[k2,k2] of matrix U is zero and therefore the adjacent basis matrix is structurally singular */ if (k1 > k2) { fhv->valid = 0; ret = FHV_ESING; goto done; } /* perform implicit symmetric permutations of rows and columns of matrix U */ i = pp_row[k1], j = qq_col[k1]; for (k = k1; k < k2; k++) { pp_row[k] = pp_row[k+1], pp_col[pp_row[k]] = k; qq_col[k] = qq_col[k+1], qq_row[qq_col[k]] = k; } pp_row[k2] = i, pp_col[i] = k2; qq_col[k2] = j, qq_row[j] = k2; /* now i-th row of the matrix V is k2-th row of matrix U; since no pivoting is used, only this row will be transformed */ /* copy elements of i-th row of matrix V to the working array and remove these elements from matrix V */ for (j = 1; j <= m; j++) work[j] = 0.0; i_beg = vr_ptr[i]; i_end = i_beg + vr_len[i] - 1; for (i_ptr = i_beg; i_ptr <= i_end; i_ptr++) { /* get column index of v[i,j] */ j = sv_ind[i_ptr]; /* store v[i,j] to the working array */ work[j] = sv_val[i_ptr]; /* find v[i,j] in the j-th column */ j_beg = vc_ptr[j]; j_end = j_beg + vc_len[j] - 1; for (j_ptr = j_beg; sv_ind[j_ptr] != i; j_ptr++) /* nop */; xassert(j_ptr <= j_end); /* remove v[i,j] from the j-th column */ sv_ind[j_ptr] = sv_ind[j_end]; sv_val[j_ptr] = sv_val[j_end]; vc_len[j]--; } /* now i-th row of matrix V is empty */ luf->nnz_v -= vr_len[i]; vr_len[i] = 0; /* create the next row-like factor of the matrix H; this factor corresponds to i-th (transformed) row */ fhv->hh_nfs++; hh_ind[fhv->hh_nfs] = i; /* hh_ptr[] will be set later */ hh_len[fhv->hh_nfs] = 0; /* up to (k2 - k1) free locations are needed to add new elements to the non-trivial row of the row-like factor */ if (luf->sv_end - luf->sv_beg < k2 - k1) { luf_defrag_sva(luf); if (luf->sv_end - luf->sv_beg < k2 - k1) { /* overflow of the sparse vector area */ fhv->valid = luf->valid = 0; luf->new_sva = luf->sv_size + luf->sv_size; xassert(luf->new_sva > luf->sv_size); ret = FHV_EROOM; goto done; } } /* eliminate subdiagonal elements of matrix U */ for (k = k1; k < k2; k++) { /* v[p,q] = u[k,k] */ p = pp_row[k], q = qq_col[k]; /* this is the crucial point, where even tiny non-zeros should not be dropped */ if (work[q] == 0.0) continue; /* compute gaussian multiplier f = v[i,q] / v[p,q] */ f = work[q] / vr_piv[p]; /* perform gaussian transformation: (i-th row) := (i-th row) - f * (p-th row) in order to eliminate v[i,q] = u[k2,k] */ p_beg = vr_ptr[p]; p_end = p_beg + vr_len[p] - 1; for (p_ptr = p_beg; p_ptr <= p_end; p_ptr++) work[sv_ind[p_ptr]] -= f * sv_val[p_ptr]; /* store new element (gaussian multiplier that corresponds to p-th row) in the current row-like factor */ luf->sv_end--; sv_ind[luf->sv_end] = p; sv_val[luf->sv_end] = f; hh_len[fhv->hh_nfs]++; } /* set pointer to the current row-like factor of the matrix H (if no elements were added to this factor, it is unity matrix and therefore can be discarded) */ if (hh_len[fhv->hh_nfs] == 0) fhv->hh_nfs--; else { hh_ptr[fhv->hh_nfs] = luf->sv_end; fhv->nnz_h += hh_len[fhv->hh_nfs]; } /* store new pivot which corresponds to u[k2,k2] */ vr_piv[i] = work[qq_col[k2]]; /* new elements of i-th row of matrix V (which are non-diagonal elements u[k2,k2+1], ..., u[k2,m] of matrix U = P*V*Q) now are contained in the working array; add them to matrix V */ len = 0; for (k = k2+1; k <= m; k++) { /* get column index and value of v[i,j] = u[k2,k] */ j = qq_col[k]; temp = work[j]; /* if v[i,j] is close to zero, skip it */ if (fabs(temp) < eps_tol) continue; /* at least one unused location is needed in j-th column */ if (vc_len[j] + 1 > vc_cap[j]) { if (luf_enlarge_col(luf, j, vc_len[j] + 10)) { /* overflow of the sparse vector area */ fhv->valid = 0; luf->new_sva = luf->sv_size + luf->sv_size; xassert(luf->new_sva > luf->sv_size); ret = FHV_EROOM; goto done; } } /* add v[i,j] to j-th column */ j_ptr = vc_ptr[j] + vc_len[j]; sv_ind[j_ptr] = i; sv_val[j_ptr] = temp; vc_len[j]++; /* also store v[i,j] to the auxiliary array */ len++, cc_ind[len] = j, cc_val[len] = temp; } /* capacity of i-th row (which is currently empty) should be not less than len locations */ if (vr_cap[i] < len) { if (luf_enlarge_row(luf, i, len)) { /* overflow of the sparse vector area */ fhv->valid = 0; luf->new_sva = luf->sv_size + luf->sv_size; xassert(luf->new_sva > luf->sv_size); ret = FHV_EROOM; goto done; } } /* add new elements to i-th row list */ i_ptr = vr_ptr[i]; memmove(&sv_ind[i_ptr], &cc_ind[1], len * sizeof(int)); memmove(&sv_val[i_ptr], &cc_val[1], len * sizeof(double)); vr_len[i] = len; luf->nnz_v += len; /* updating is finished; check that diagonal element u[k2,k2] is not very small in absolute value among other elements in k2-th row and k2-th column of matrix U = P*V*Q */ /* temp = max(|u[k2,*]|, |u[*,k2]|) */ temp = 0.0; /* walk through k2-th row of U which is i-th row of V */ i = pp_row[k2]; i_beg = vr_ptr[i]; i_end = i_beg + vr_len[i] - 1; for (i_ptr = i_beg; i_ptr <= i_end; i_ptr++) if (temp < fabs(sv_val[i_ptr])) temp = fabs(sv_val[i_ptr]); /* walk through k2-th column of U which is j-th column of V */ j = qq_col[k2]; j_beg = vc_ptr[j]; j_end = j_beg + vc_len[j] - 1; for (j_ptr = j_beg; j_ptr <= j_end; j_ptr++) if (temp < fabs(sv_val[j_ptr])) temp = fabs(sv_val[j_ptr]); /* check that u[k2,k2] is not very small */ if (fabs(vr_piv[i]) < upd_tol * temp) { /* the factorization seems to be inaccurate and therefore must be recomputed */ fhv->valid = 0; ret = FHV_ECHECK; goto done; } /* the factorization has been successfully updated */ ret = 0; done: /* return to the calling program */ return ret; } /*********************************************************************** * NAME * * fhv_delete_it - delete LP basis factorization * * SYNOPSIS * * #include "glpfhv.h" * void fhv_delete_it(FHV *fhv); * * DESCRIPTION * * The routine fhv_delete_it deletes LP basis factorization specified * by the parameter fhv and frees all memory allocated to this program * object. */ void fhv_delete_it(FHV *fhv) { luf_delete_it(fhv->luf); if (fhv->hh_ind != NULL) xfree(fhv->hh_ind); if (fhv->hh_ptr != NULL) xfree(fhv->hh_ptr); if (fhv->hh_len != NULL) xfree(fhv->hh_len); if (fhv->p0_row != NULL) xfree(fhv->p0_row); if (fhv->p0_col != NULL) xfree(fhv->p0_col); if (fhv->cc_ind != NULL) xfree(fhv->cc_ind); if (fhv->cc_val != NULL) xfree(fhv->cc_val); xfree(fhv); return; } /* eof */ praat-6.0.04/external/glpk/glpfhv.h000066400000000000000000000152231261542461700171410ustar00rootroot00000000000000/* glpfhv.h (LP basis factorization, FHV eta file version) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPFHV_H #define GLPFHV_H #include "glpluf.h" /*********************************************************************** * The structure FHV defines the factorization of the basis mxm-matrix * B, where m is the number of rows in corresponding problem instance. * * This factorization is the following sextet: * * [B] = (F, H, V, P0, P, Q), (1) * * where F, H, and V are such matrices that * * B = F * H * V, (2) * * and P0, P, and Q are such permutation matrices that the matrix * * L = P0 * F * inv(P0) (3) * * is lower triangular with unity diagonal, and the matrix * * U = P * V * Q (4) * * is upper triangular. All the matrices have the same order m, which * is the order of the basis matrix B. * * The matrices F, V, P, and Q are stored in the structure LUF (see the * module GLPLUF), which is a member of the structure FHV. * * The matrix H is stored in the form of eta file using row-like format * as follows: * * H = H[1] * H[2] * ... * H[nfs], (5) * * where H[k], k = 1, 2, ..., nfs, is a row-like factor, which differs * from the unity matrix only by one row, nfs is current number of row- * like factors. After the factorization has been built for some given * basis matrix B the matrix H has no factors and thus it is the unity * matrix. Then each time when the factorization is recomputed for an * adjacent basis matrix, the next factor H[k], k = 1, 2, ... is built * and added to the end of the eta file H. * * Being sparse vectors non-trivial rows of the factors H[k] are stored * in the right part of the sparse vector area (SVA) in the same manner * as rows and columns of the matrix F. * * For more details see the program documentation. */ typedef struct FHV FHV; struct FHV { /* LP basis factorization */ int m_max; /* maximal value of m (increased automatically, if necessary) */ int m; /* the order of matrices B, F, H, V, P0, P, Q */ int valid; /* the factorization is valid only if this flag is set */ LUF *luf; /* LU-factorization (contains the matrices F, V, P, Q) */ /*--------------------------------------------------------------*/ /* matrix H in the form of eta file */ int hh_max; /* maximal number of row-like factors (which limits the number of updates of the factorization) */ int hh_nfs; /* current number of row-like factors (0 <= hh_nfs <= hh_max) */ int *hh_ind; /* int hh_ind[1+hh_max]; */ /* hh_ind[k], k = 1, ..., nfs, is the number of a non-trivial row of factor H[k] */ int *hh_ptr; /* int hh_ptr[1+hh_max]; */ /* hh_ptr[k], k = 1, ..., nfs, is a pointer to the first element of the non-trivial row of factor H[k] in the SVA */ int *hh_len; /* int hh_len[1+hh_max]; */ /* hh_len[k], k = 1, ..., nfs, is the number of non-zero elements in the non-trivial row of factor H[k] */ /*--------------------------------------------------------------*/ /* matrix P0 */ int *p0_row; /* int p0_row[1+m_max]; */ /* p0_row[i] = j means that p0[i,j] = 1 */ int *p0_col; /* int p0_col[1+m_max]; */ /* p0_col[j] = i means that p0[i,j] = 1 */ /* if i-th row or column of the matrix F corresponds to i'-th row or column of the matrix L = P0*F*inv(P0), then p0_row[i'] = i and p0_col[i] = i' */ /*--------------------------------------------------------------*/ /* working arrays */ int *cc_ind; /* int cc_ind[1+m_max]; */ /* integer working array */ double *cc_val; /* double cc_val[1+m_max]; */ /* floating-point working array */ /*--------------------------------------------------------------*/ /* control parameters */ double upd_tol; /* update tolerance; if after updating the factorization absolute value of some diagonal element u[k,k] of matrix U = P*V*Q is less than upd_tol * max(|u[k,*]|, |u[*,k]|), the factorization is considered as inaccurate */ /*--------------------------------------------------------------*/ /* some statistics */ int nnz_h; /* current number of non-zeros in all factors of matrix H */ }; /* return codes: */ #define FHV_ESING 1 /* singular matrix */ #define FHV_ECOND 2 /* ill-conditioned matrix */ #define FHV_ECHECK 3 /* insufficient accuracy */ #define FHV_ELIMIT 4 /* update limit reached */ #define FHV_EROOM 5 /* SVA overflow */ #define fhv_create_it _glp_fhv_create_it FHV *fhv_create_it(void); /* create LP basis factorization */ #define fhv_factorize _glp_fhv_factorize int fhv_factorize(FHV *fhv, int m, int (*col)(void *info, int j, int ind[], double val[]), void *info); /* compute LP basis factorization */ #define fhv_h_solve _glp_fhv_h_solve void fhv_h_solve(FHV *fhv, int tr, double x[]); /* solve system H*x = b or H'*x = b */ #define fhv_ftran _glp_fhv_ftran void fhv_ftran(FHV *fhv, double x[]); /* perform forward transformation (solve system B*x = b) */ #define fhv_btran _glp_fhv_btran void fhv_btran(FHV *fhv, double x[]); /* perform backward transformation (solve system B'*x = b) */ #define fhv_update_it _glp_fhv_update_it int fhv_update_it(FHV *fhv, int j, int len, const int ind[], const double val[]); /* update LP basis factorization */ #define fhv_delete_it _glp_fhv_delete_it void fhv_delete_it(FHV *fhv); /* delete LP basis factorization */ #endif /* eof */ praat-6.0.04/external/glpk/glpgmp.c000066400000000000000000000756031261542461700171440ustar00rootroot00000000000000/* glpgmp.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #define _GLPSTD_STDIO #include "glpdmp.h" #include "glpgmp.h" #define xfault xerror #ifdef HAVE_GMP /* use GNU MP bignum library */ int gmp_pool_count(void) { return 0; } void gmp_free_mem(void) { return; } #else /* use GLPK bignum module */ static DMP *gmp_pool = NULL; static int gmp_size = 0; static unsigned short *gmp_work = NULL; void *gmp_get_atom(int size) { if (gmp_pool == NULL) gmp_pool = dmp_create_pool(); return dmp_get_atom(gmp_pool, size); } void gmp_free_atom(void *ptr, int size) { xassert(gmp_pool != NULL); dmp_free_atom(gmp_pool, ptr, size); return; } int gmp_pool_count(void) { if (gmp_pool == NULL) return 0; else return dmp_in_use(gmp_pool).lo; } unsigned short *gmp_get_work(int size) { xassert(size > 0); if (gmp_size < size) { if (gmp_size == 0) { xassert(gmp_work == NULL); gmp_size = 100; } else { xassert(gmp_work != NULL); xfree(gmp_work); } while (gmp_size < size) gmp_size += gmp_size; gmp_work = xcalloc(gmp_size, sizeof(unsigned short)); } return gmp_work; } void gmp_free_mem(void) { if (gmp_pool != NULL) dmp_delete_pool(gmp_pool); if (gmp_work != NULL) xfree(gmp_work); gmp_pool = NULL; gmp_size = 0; gmp_work = NULL; return; } /*====================================================================*/ mpz_t _mpz_init(void) { /* initialize x, and set its value to 0 */ mpz_t x; x = gmp_get_atom(sizeof(struct mpz)); x->val = 0; x->ptr = NULL; return x; } void mpz_clear(mpz_t x) { /* free the space occupied by x */ mpz_set_si(x, 0); xassert(x->ptr == NULL); /* free the number descriptor */ gmp_free_atom(x, sizeof(struct mpz)); return; } void mpz_set(mpz_t z, mpz_t x) { /* set the value of z from x */ struct mpz_seg *e, *ee, *es; if (z != x) { mpz_set_si(z, 0); z->val = x->val; xassert(z->ptr == NULL); for (e = x->ptr, es = NULL; e != NULL; e = e->next) { ee = gmp_get_atom(sizeof(struct mpz_seg)); memcpy(ee->d, e->d, 12); ee->next = NULL; if (z->ptr == NULL) z->ptr = ee; else es->next = ee; es = ee; } } return; } void mpz_set_si(mpz_t x, int val) { /* set the value of x to val */ struct mpz_seg *e; /* free existing segments, if any */ while (x->ptr != NULL) { e = x->ptr; x->ptr = e->next; gmp_free_atom(e, sizeof(struct mpz_seg)); } /* assign new value */ if (val == 0x80000000) { /* long format is needed */ x->val = -1; x->ptr = e = gmp_get_atom(sizeof(struct mpz_seg)); memset(e->d, 0, 12); e->d[1] = 0x8000; e->next = NULL; } else { /* short format is enough */ x->val = val; } return; } double mpz_get_d(mpz_t x) { /* convert x to a double, truncating if necessary */ struct mpz_seg *e; int j; double val, deg; if (x->ptr == NULL) val = (double)x->val; else { xassert(x->val != 0); val = 0.0; deg = 1.0; for (e = x->ptr; e != NULL; e = e->next) { for (j = 0; j <= 5; j++) { val += deg * (double)((int)e->d[j]); deg *= 65536.0; } } if (x->val < 0) val = - val; } return val; } double mpz_get_d_2exp(int *exp, mpz_t x) { /* convert x to a double, truncating if necessary (i.e. rounding towards zero), and returning the exponent separately; the return value is in the range 0.5 <= |d| < 1 and the exponent is stored to *exp; d*2^exp is the (truncated) x value; if x is zero, the return is 0.0 and 0 is stored to *exp; this is similar to the standard C frexp function */ struct mpz_seg *e; int j, n, n1; double val; if (x->ptr == NULL) val = (double)x->val, n = 0; else { xassert(x->val != 0); val = 0.0, n = 0; for (e = x->ptr; e != NULL; e = e->next) { for (j = 0; j <= 5; j++) { val += (double)((int)e->d[j]); val /= 65536.0, n += 16; } } if (x->val < 0) val = - val; } val = frexp(val, &n1); *exp = n + n1; return val; } void mpz_swap(mpz_t x, mpz_t y) { /* swap the values x and y efficiently */ int val; void *ptr; val = x->val, ptr = x->ptr; x->val = y->val, x->ptr = y->ptr; y->val = val, y->ptr = ptr; return; } static void normalize(mpz_t x) { /* normalize integer x that includes removing non-significant (leading) zeros and converting to short format, if possible */ struct mpz_seg *es, *e; /* if the integer is in short format, it remains unchanged */ if (x->ptr == NULL) { xassert(x->val != 0x80000000); goto done; } xassert(x->val == +1 || x->val == -1); /* find the last (most significant) non-zero segment */ es = NULL; for (e = x->ptr; e != NULL; e = e->next) { if (e->d[0] || e->d[1] || e->d[2] || e->d[3] || e->d[4] || e->d[5]) es = e; } /* if all segments contain zeros, the integer is zero */ if (es == NULL) { mpz_set_si(x, 0); goto done; } /* remove non-significant (leading) zero segments */ while (es->next != NULL) { e = es->next; es->next = e->next; gmp_free_atom(e, sizeof(struct mpz_seg)); } /* convert the integer to short format, if possible */ e = x->ptr; if (e->next == NULL && e->d[1] <= 0x7FFF && !e->d[2] && !e->d[3] && !e->d[4] && !e->d[5]) { int val; val = (int)e->d[0] + ((int)e->d[1] << 16); if (x->val < 0) val = - val; mpz_set_si(x, val); } done: return; } void mpz_add(mpz_t z, mpz_t x, mpz_t y) { /* set z to x + y */ static struct mpz_seg zero = { { 0, 0, 0, 0, 0, 0 }, NULL }; struct mpz_seg dumx, dumy, *ex, *ey, *ez, *es, *ee; int k, sx, sy, sz; unsigned int t; /* if [x] = 0 then [z] = [y] */ if (x->val == 0) { xassert(x->ptr == NULL); mpz_set(z, y); goto done; } /* if [y] = 0 then [z] = [x] */ if (y->val == 0) { xassert(y->ptr == NULL); mpz_set(z, x); goto done; } /* special case when both [x] and [y] are in short format */ if (x->ptr == NULL && y->ptr == NULL) { int xval = x->val, yval = y->val, zval = x->val + y->val; xassert(xval != 0x80000000 && yval != 0x80000000); if (!(xval > 0 && yval > 0 && zval <= 0 || xval < 0 && yval < 0 && zval >= 0)) { mpz_set_si(z, zval); goto done; } } /* convert [x] to long format, if necessary */ if (x->ptr == NULL) { xassert(x->val != 0x80000000); if (x->val >= 0) { sx = +1; t = (unsigned int)(+ x->val); } else { sx = -1; t = (unsigned int)(- x->val); } ex = &dumx; ex->d[0] = (unsigned short)t; ex->d[1] = (unsigned short)(t >> 16); ex->d[2] = ex->d[3] = ex->d[4] = ex->d[5] = 0; ex->next = NULL; } else { sx = x->val; xassert(sx == +1 || sx == -1); ex = x->ptr; } /* convert [y] to long format, if necessary */ if (y->ptr == NULL) { xassert(y->val != 0x80000000); if (y->val >= 0) { sy = +1; t = (unsigned int)(+ y->val); } else { sy = -1; t = (unsigned int)(- y->val); } ey = &dumy; ey->d[0] = (unsigned short)t; ey->d[1] = (unsigned short)(t >> 16); ey->d[2] = ey->d[3] = ey->d[4] = ey->d[5] = 0; ey->next = NULL; } else { sy = y->val; xassert(sy == +1 || sy == -1); ey = y->ptr; } /* main fragment */ sz = sx; ez = es = NULL; if (sx > 0 && sy > 0 || sx < 0 && sy < 0) { /* [x] and [y] have identical signs -- addition */ t = 0; for (; ex || ey; ex = ex->next, ey = ey->next) { if (ex == NULL) ex = &zero; if (ey == NULL) ey = &zero; ee = gmp_get_atom(sizeof(struct mpz_seg)); for (k = 0; k <= 5; k++) { t += (unsigned int)ex->d[k]; t += (unsigned int)ey->d[k]; ee->d[k] = (unsigned short)t; t >>= 16; } ee->next = NULL; if (ez == NULL) ez = ee; else es->next = ee; es = ee; } if (t) { /* overflow -- one extra digit is needed */ ee = gmp_get_atom(sizeof(struct mpz_seg)); ee->d[0] = 1; ee->d[1] = ee->d[2] = ee->d[3] = ee->d[4] = ee->d[5] = 0; ee->next = NULL; xassert(es != NULL); es->next = ee; } } else { /* [x] and [y] have different signs -- subtraction */ t = 1; for (; ex || ey; ex = ex->next, ey = ey->next) { if (ex == NULL) ex = &zero; if (ey == NULL) ey = &zero; ee = gmp_get_atom(sizeof(struct mpz_seg)); for (k = 0; k <= 5; k++) { t += (unsigned int)ex->d[k]; t += (0xFFFF - (unsigned int)ey->d[k]); ee->d[k] = (unsigned short)t; t >>= 16; } ee->next = NULL; if (ez == NULL) ez = ee; else es->next = ee; es = ee; } if (!t) { /* |[x]| < |[y]| -- result in complement coding */ sz = - sz; t = 1; for (ee = ez; ee != NULL; ee = ee->next) for (k = 0; k <= 5; k++) { t += (0xFFFF - (unsigned int)ee->d[k]); ee->d[k] = (unsigned short)t; t >>= 16; } } } /* contruct and normalize result */ mpz_set_si(z, 0); z->val = sz; z->ptr = ez; normalize(z); done: return; } void mpz_sub(mpz_t z, mpz_t x, mpz_t y) { /* set z to x - y */ if (x == y) mpz_set_si(z, 0); else { y->val = - y->val; mpz_add(z, x, y); if (y != z) y->val = - y->val; } return; } void mpz_mul(mpz_t z, mpz_t x, mpz_t y) { /* set z to x * y */ struct mpz_seg dumx, dumy, *ex, *ey, *es, *e; int sx, sy, k, nx, ny, n; unsigned int t; unsigned short *work, *wx, *wy; /* if [x] = 0 then [z] = 0 */ if (x->val == 0) { xassert(x->ptr == NULL); mpz_set_si(z, 0); goto done; } /* if [y] = 0 then [z] = 0 */ if (y->val == 0) { xassert(y->ptr == NULL); mpz_set_si(z, 0); goto done; } /* special case when both [x] and [y] are in short format */ if (x->ptr == NULL && y->ptr == NULL) { int xval = x->val, yval = y->val, sz = +1; xassert(xval != 0x80000000 && yval != 0x80000000); if (xval < 0) xval = - xval, sz = - sz; if (yval < 0) yval = - yval, sz = - sz; if (xval <= 0x7FFFFFFF / yval) { mpz_set_si(z, sz * (xval * yval)); goto done; } } /* convert [x] to long format, if necessary */ if (x->ptr == NULL) { xassert(x->val != 0x80000000); if (x->val >= 0) { sx = +1; t = (unsigned int)(+ x->val); } else { sx = -1; t = (unsigned int)(- x->val); } ex = &dumx; ex->d[0] = (unsigned short)t; ex->d[1] = (unsigned short)(t >> 16); ex->d[2] = ex->d[3] = ex->d[4] = ex->d[5] = 0; ex->next = NULL; } else { sx = x->val; xassert(sx == +1 || sx == -1); ex = x->ptr; } /* convert [y] to long format, if necessary */ if (y->ptr == NULL) { xassert(y->val != 0x80000000); if (y->val >= 0) { sy = +1; t = (unsigned int)(+ y->val); } else { sy = -1; t = (unsigned int)(- y->val); } ey = &dumy; ey->d[0] = (unsigned short)t; ey->d[1] = (unsigned short)(t >> 16); ey->d[2] = ey->d[3] = ey->d[4] = ey->d[5] = 0; ey->next = NULL; } else { sy = y->val; xassert(sy == +1 || sy == -1); ey = y->ptr; } /* determine the number of digits of [x] */ nx = n = 0; for (e = ex; e != NULL; e = e->next) for (k = 0; k <= 5; k++) { n++; if (e->d[k]) nx = n; } xassert(nx > 0); /* determine the number of digits of [y] */ ny = n = 0; for (e = ey; e != NULL; e = e->next) for (k = 0; k <= 5; k++) { n++; if (e->d[k]) ny = n; } xassert(ny > 0); /* we need working array containing at least nx+ny+ny places */ work = gmp_get_work(nx+ny+ny); /* load digits of [x] */ wx = &work[0]; for (n = 0; n < nx; n++) wx[ny+n] = 0; for (n = 0, e = ex; e != NULL; e = e->next) for (k = 0; k <= 5; k++, n++) if (e->d[k]) wx[ny+n] = e->d[k]; /* load digits of [y] */ wy = &work[nx+ny]; for (n = 0; n < ny; n++) wy[n] = 0; for (n = 0, e = ey; e != NULL; e = e->next) for (k = 0; k <= 5; k++, n++) if (e->d[k]) wy[n] = e->d[k]; /* compute [x] * [y] */ bigmul(nx, ny, wx, wy); /* construct and normalize result */ mpz_set_si(z, 0); z->val = sx * sy; es = NULL; k = 6; for (n = 0; n < nx+ny; n++) { if (k > 5) { e = gmp_get_atom(sizeof(struct mpz_seg)); e->d[0] = e->d[1] = e->d[2] = 0; e->d[3] = e->d[4] = e->d[5] = 0; e->next = NULL; if (z->ptr == NULL) z->ptr = e; else es->next = e; es = e; k = 0; } es->d[k++] = wx[n]; } normalize(z); done: return; } void mpz_neg(mpz_t z, mpz_t x) { /* set z to 0 - x */ mpz_set(z, x); z->val = - z->val; return; } void mpz_abs(mpz_t z, mpz_t x) { /* set z to the absolute value of x */ mpz_set(z, x); if (z->val < 0) z->val = - z->val; return; } void mpz_div(mpz_t q, mpz_t r, mpz_t x, mpz_t y) { /* divide x by y, forming quotient q and/or remainder r if q = NULL then quotient is not stored; if r = NULL then remainder is not stored the sign of quotient is determined as in algebra while the sign of remainder is the same as the sign of dividend: +26 : +7 = +3, remainder is +5 -26 : +7 = -3, remainder is -5 +26 : -7 = -3, remainder is +5 -26 : -7 = +3, remainder is -5 */ struct mpz_seg dumx, dumy, *ex, *ey, *es, *e; int sx, sy, k, nx, ny, n; unsigned int t; unsigned short *work, *wx, *wy; /* divide by zero is not allowed */ if (y->val == 0) { xassert(y->ptr == NULL); xfault("mpz_div: divide by zero not allowed\n"); } /* if [x] = 0 then [q] = [r] = 0 */ if (x->val == 0) { xassert(x->ptr == NULL); if (q != NULL) mpz_set_si(q, 0); if (r != NULL) mpz_set_si(r, 0); goto done; } /* special case when both [x] and [y] are in short format */ if (x->ptr == NULL && y->ptr == NULL) { int xval = x->val, yval = y->val; xassert(xval != 0x80000000 && yval != 0x80000000); if (q != NULL) mpz_set_si(q, xval / yval); if (r != NULL) mpz_set_si(r, xval % yval); goto done; } /* convert [x] to long format, if necessary */ if (x->ptr == NULL) { xassert(x->val != 0x80000000); if (x->val >= 0) { sx = +1; t = (unsigned int)(+ x->val); } else { sx = -1; t = (unsigned int)(- x->val); } ex = &dumx; ex->d[0] = (unsigned short)t; ex->d[1] = (unsigned short)(t >> 16); ex->d[2] = ex->d[3] = ex->d[4] = ex->d[5] = 0; ex->next = NULL; } else { sx = x->val; xassert(sx == +1 || sx == -1); ex = x->ptr; } /* convert [y] to long format, if necessary */ if (y->ptr == NULL) { xassert(y->val != 0x80000000); if (y->val >= 0) { sy = +1; t = (unsigned int)(+ y->val); } else { sy = -1; t = (unsigned int)(- y->val); } ey = &dumy; ey->d[0] = (unsigned short)t; ey->d[1] = (unsigned short)(t >> 16); ey->d[2] = ey->d[3] = ey->d[4] = ey->d[5] = 0; ey->next = NULL; } else { sy = y->val; xassert(sy == +1 || sy == -1); ey = y->ptr; } /* determine the number of digits of [x] */ nx = n = 0; for (e = ex; e != NULL; e = e->next) for (k = 0; k <= 5; k++) { n++; if (e->d[k]) nx = n; } xassert(nx > 0); /* determine the number of digits of [y] */ ny = n = 0; for (e = ey; e != NULL; e = e->next) for (k = 0; k <= 5; k++) { n++; if (e->d[k]) ny = n; } xassert(ny > 0); /* if nx < ny then [q] = 0 and [r] = [x] */ if (nx < ny) { if (r != NULL) mpz_set(r, x); if (q != NULL) mpz_set_si(q, 0); goto done; } /* we need working array containing at least nx+ny+1 places */ work = gmp_get_work(nx+ny+1); /* load digits of [x] */ wx = &work[0]; for (n = 0; n < nx; n++) wx[n] = 0; for (n = 0, e = ex; e != NULL; e = e->next) for (k = 0; k <= 5; k++, n++) if (e->d[k]) wx[n] = e->d[k]; /* load digits of [y] */ wy = &work[nx+1]; for (n = 0; n < ny; n++) wy[n] = 0; for (n = 0, e = ey; e != NULL; e = e->next) for (k = 0; k <= 5; k++, n++) if (e->d[k]) wy[n] = e->d[k]; /* compute quotient and remainder */ xassert(wy[ny-1] != 0); bigdiv(nx-ny, ny, wx, wy); /* construct and normalize quotient */ if (q != NULL) { mpz_set_si(q, 0); q->val = sx * sy; es = NULL; k = 6; for (n = ny; n <= nx; n++) { if (k > 5) { e = gmp_get_atom(sizeof(struct mpz_seg)); e->d[0] = e->d[1] = e->d[2] = 0; e->d[3] = e->d[4] = e->d[5] = 0; e->next = NULL; if (q->ptr == NULL) q->ptr = e; else es->next = e; es = e; k = 0; } es->d[k++] = wx[n]; } normalize(q); } /* construct and normalize remainder */ if (r != NULL) { mpz_set_si(r, 0); r->val = sx; es = NULL; k = 6; for (n = 0; n < ny; n++) { if (k > 5) { e = gmp_get_atom(sizeof(struct mpz_seg)); e->d[0] = e->d[1] = e->d[2] = 0; e->d[3] = e->d[4] = e->d[5] = 0; e->next = NULL; if (r->ptr == NULL) r->ptr = e; else es->next = e; es = e; k = 0; } es->d[k++] = wx[n]; } normalize(r); } done: return; } void mpz_gcd(mpz_t z, mpz_t x, mpz_t y) { /* set z to the greatest common divisor of x and y */ /* in case of arbitrary integers GCD(x, y) = GCD(|x|, |y|), and, in particular, GCD(0, 0) = 0 */ mpz_t u, v, r; mpz_init(u); mpz_init(v); mpz_init(r); mpz_abs(u, x); mpz_abs(v, y); while (mpz_sgn(v)) { mpz_div(NULL, r, u, v); mpz_set(u, v); mpz_set(v, r); } mpz_set(z, u); mpz_clear(u); mpz_clear(v); mpz_clear(r); return; } int mpz_cmp(mpz_t x, mpz_t y) { /* compare x and y; return a positive value if x > y, zero if x = y, or a nefative value if x < y */ static struct mpz_seg zero = { { 0, 0, 0, 0, 0, 0 }, NULL }; struct mpz_seg dumx, dumy, *ex, *ey; int cc, sx, sy, k; unsigned int t; if (x == y) { cc = 0; goto done; } /* special case when both [x] and [y] are in short format */ if (x->ptr == NULL && y->ptr == NULL) { int xval = x->val, yval = y->val; xassert(xval != 0x80000000 && yval != 0x80000000); cc = (xval > yval ? +1 : xval < yval ? -1 : 0); goto done; } /* special case when [x] and [y] have different signs */ if (x->val > 0 && y->val <= 0 || x->val == 0 && y->val < 0) { cc = +1; goto done; } if (x->val < 0 && y->val >= 0 || x->val == 0 && y->val > 0) { cc = -1; goto done; } /* convert [x] to long format, if necessary */ if (x->ptr == NULL) { xassert(x->val != 0x80000000); if (x->val >= 0) { sx = +1; t = (unsigned int)(+ x->val); } else { sx = -1; t = (unsigned int)(- x->val); } ex = &dumx; ex->d[0] = (unsigned short)t; ex->d[1] = (unsigned short)(t >> 16); ex->d[2] = ex->d[3] = ex->d[4] = ex->d[5] = 0; ex->next = NULL; } else { sx = x->val; xassert(sx == +1 || sx == -1); ex = x->ptr; } /* convert [y] to long format, if necessary */ if (y->ptr == NULL) { xassert(y->val != 0x80000000); if (y->val >= 0) { sy = +1; t = (unsigned int)(+ y->val); } else { sy = -1; t = (unsigned int)(- y->val); } ey = &dumy; ey->d[0] = (unsigned short)t; ey->d[1] = (unsigned short)(t >> 16); ey->d[2] = ey->d[3] = ey->d[4] = ey->d[5] = 0; ey->next = NULL; } else { sy = y->val; xassert(sy == +1 || sy == -1); ey = y->ptr; } /* main fragment */ xassert(sx > 0 && sy > 0 || sx < 0 && sy < 0); cc = 0; for (; ex || ey; ex = ex->next, ey = ey->next) { if (ex == NULL) ex = &zero; if (ey == NULL) ey = &zero; for (k = 0; k <= 5; k++) { if (ex->d[k] > ey->d[k]) cc = +1; if (ex->d[k] < ey->d[k]) cc = -1; } } if (sx < 0) cc = - cc; done: return cc; } int mpz_sgn(mpz_t x) { /* return +1 if x > 0, 0 if x = 0, and -1 if x < 0 */ int s; s = (x->val > 0 ? +1 : x->val < 0 ? -1 : 0); return s; } int mpz_out_str(void *_fp, int base, mpz_t x) { /* output x on stream fp, as a string in given base; the base may vary from 2 to 36; return the number of bytes written, or if an error occurred, return 0 */ FILE *fp = _fp; mpz_t b, y, r; int n, j, nwr = 0; unsigned char *d; static char *set = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; if (!(2 <= base && base <= 36)) xfault("mpz_out_str: base = %d; invalid base\n", base); mpz_init(b); mpz_set_si(b, base); mpz_init(y); mpz_init(r); /* determine the number of digits */ mpz_abs(y, x); for (n = 0; mpz_sgn(y) != 0; n++) mpz_div(y, NULL, y, b); if (n == 0) n = 1; /* compute the digits */ d = xmalloc(n); mpz_abs(y, x); for (j = 0; j < n; j++) { mpz_div(y, r, y, b); xassert(0 <= r->val && r->val < base && r->ptr == NULL); d[j] = (unsigned char)r->val; } /* output the integer to the stream */ if (fp == NULL) fp = stdout; if (mpz_sgn(x) < 0) fputc('-', fp), nwr++; for (j = n-1; j >= 0; j--) fputc(set[d[j]], fp), nwr++; if (ferror(fp)) nwr = 0; mpz_clear(b); mpz_clear(y); mpz_clear(r); xfree(d); return nwr; } /*====================================================================*/ mpq_t _mpq_init(void) { /* initialize x, and set its value to 0/1 */ mpq_t x; x = gmp_get_atom(sizeof(struct mpq)); x->p.val = 0; x->p.ptr = NULL; x->q.val = 1; x->q.ptr = NULL; return x; } void mpq_clear(mpq_t x) { /* free the space occupied by x */ mpz_set_si(&x->p, 0); xassert(x->p.ptr == NULL); mpz_set_si(&x->q, 0); xassert(x->q.ptr == NULL); /* free the number descriptor */ gmp_free_atom(x, sizeof(struct mpq)); return; } void mpq_canonicalize(mpq_t x) { /* remove any factors that are common to the numerator and denominator of x, and make the denominator positive */ mpz_t f; xassert(x->q.val != 0); if (x->q.val < 0) { mpz_neg(&x->p, &x->p); mpz_neg(&x->q, &x->q); } mpz_init(f); mpz_gcd(f, &x->p, &x->q); if (!(f->val == 1 && f->ptr == NULL)) { mpz_div(&x->p, NULL, &x->p, f); mpz_div(&x->q, NULL, &x->q, f); } mpz_clear(f); return; } void mpq_set(mpq_t z, mpq_t x) { /* set the value of z from x */ if (z != x) { mpz_set(&z->p, &x->p); mpz_set(&z->q, &x->q); } return; } void mpq_set_si(mpq_t x, int p, unsigned int q) { /* set the value of x to p/q */ if (q == 0) xfault("mpq_set_si: zero denominator not allowed\n"); mpz_set_si(&x->p, p); xassert(q <= 0x7FFFFFFF); mpz_set_si(&x->q, q); return; } double mpq_get_d(mpq_t x) { /* convert x to a double, truncating if necessary */ int np, nq; double p, q; p = mpz_get_d_2exp(&np, &x->p); q = mpz_get_d_2exp(&nq, &x->q); return ldexp(p / q, np - nq); } void mpq_set_d(mpq_t x, double val) { /* set x to val; there is no rounding, the conversion is exact */ int s, n, d, j; double f; mpz_t temp; xassert(-DBL_MAX <= val && val <= +DBL_MAX); mpq_set_si(x, 0, 1); if (val > 0.0) s = +1; else if (val < 0.0) s = -1; else goto done; f = frexp(fabs(val), &n); /* |val| = f * 2^n, where 0.5 <= f < 1.0 */ mpz_init(temp); while (f != 0.0) { f *= 16.0, n -= 4; d = (int)f; xassert(0 <= d && d <= 15); f -= (double)d; /* x := 16 * x + d */ mpz_set_si(temp, 16); mpz_mul(&x->p, &x->p, temp); mpz_set_si(temp, d); mpz_add(&x->p, &x->p, temp); } mpz_clear(temp); /* x := x * 2^n */ if (n > 0) { for (j = 1; j <= n; j++) mpz_add(&x->p, &x->p, &x->p); } else if (n < 0) { for (j = 1; j <= -n; j++) mpz_add(&x->q, &x->q, &x->q); mpq_canonicalize(x); } if (s < 0) mpq_neg(x, x); done: return; } void mpq_add(mpq_t z, mpq_t x, mpq_t y) { /* set z to x + y */ mpz_t p, q; mpz_init(p); mpz_init(q); mpz_mul(p, &x->p, &y->q); mpz_mul(q, &x->q, &y->p); mpz_add(p, p, q); mpz_mul(q, &x->q, &y->q); mpz_set(&z->p, p); mpz_set(&z->q, q); mpz_clear(p); mpz_clear(q); mpq_canonicalize(z); return; } void mpq_sub(mpq_t z, mpq_t x, mpq_t y) { /* set z to x - y */ mpz_t p, q; mpz_init(p); mpz_init(q); mpz_mul(p, &x->p, &y->q); mpz_mul(q, &x->q, &y->p); mpz_sub(p, p, q); mpz_mul(q, &x->q, &y->q); mpz_set(&z->p, p); mpz_set(&z->q, q); mpz_clear(p); mpz_clear(q); mpq_canonicalize(z); return; } void mpq_mul(mpq_t z, mpq_t x, mpq_t y) { /* set z to x * y */ mpz_mul(&z->p, &x->p, &y->p); mpz_mul(&z->q, &x->q, &y->q); mpq_canonicalize(z); return; } void mpq_div(mpq_t z, mpq_t x, mpq_t y) { /* set z to x / y */ mpz_t p, q; if (mpq_sgn(y) == 0) xfault("mpq_div: zero divisor not allowed\n"); mpz_init(p); mpz_init(q); mpz_mul(p, &x->p, &y->q); mpz_mul(q, &x->q, &y->p); mpz_set(&z->p, p); mpz_set(&z->q, q); mpz_clear(p); mpz_clear(q); mpq_canonicalize(z); return; } void mpq_neg(mpq_t z, mpq_t x) { /* set z to 0 - x */ mpq_set(z, x); mpz_neg(&z->p, &z->p); return; } void mpq_abs(mpq_t z, mpq_t x) { /* set z to the absolute value of x */ mpq_set(z, x); mpz_abs(&z->p, &z->p); xassert(mpz_sgn(&x->q) > 0); return; } int mpq_cmp(mpq_t x, mpq_t y) { /* compare x and y; return a positive value if x > y, zero if x = y, or a nefative value if x < y */ mpq_t temp; int s; mpq_init(temp); mpq_sub(temp, x, y); s = mpq_sgn(temp); mpq_clear(temp); return s; } int mpq_sgn(mpq_t x) { /* return +1 if x > 0, 0 if x = 0, and -1 if x < 0 */ int s; s = mpz_sgn(&x->p); xassert(mpz_sgn(&x->q) > 0); return s; } int mpq_out_str(void *_fp, int base, mpq_t x) { /* output x on stream fp, as a string in given base; the base may vary from 2 to 36; output is in the form 'num/den' or if the denominator is 1 then just 'num'; if the parameter fp is a null pointer, stdout is assumed; return the number of bytes written, or if an error occurred, return 0 */ FILE *fp = _fp; int nwr; if (!(2 <= base && base <= 36)) xfault("mpq_out_str: base = %d; invalid base\n", base); if (fp == NULL) fp = stdout; nwr = mpz_out_str(fp, base, &x->p); if (x->q.val == 1 && x->q.ptr == NULL) ; else { fputc('/', fp), nwr++; nwr += mpz_out_str(fp, base, &x->q); } if (ferror(fp)) nwr = 0; return nwr; } #endif /* eof */ praat-6.0.04/external/glpk/glpgmp.h000066400000000000000000000143151261542461700171420ustar00rootroot00000000000000/* glpgmp.h (bignum arithmetic) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPGMP_H #define GLPGMP_H #ifdef HAVE_CONFIG_H #include #endif #ifdef HAVE_GMP /* use GNU MP bignum library */ #include #define gmp_pool_count _glp_gmp_pool_count #define gmp_free_mem _glp_gmp_free_mem int gmp_pool_count(void); void gmp_free_mem(void); #else /* use GLPK bignum module */ /*---------------------------------------------------------------------- // INTEGER NUMBERS // // Depending on its magnitude an integer number of arbitrary precision // is represented either in short format or in long format. // // Short format corresponds to the int type and allows representing // integer numbers in the range [-(2^31-1), +(2^31-1)]. Note that for // the most negative number of int type the short format is not used. // // In long format integer numbers are represented using the positional // system with the base (radix) 2^16 = 65536: // // x = (-1)^s sum{j in 0..n-1} d[j] * 65536^j, // // where x is the integer to be represented, s is its sign (+1 or -1), // d[j] are its digits (0 <= d[j] <= 65535). // // RATIONAL NUMBERS // // A rational number is represented as an irreducible fraction: // // p / q, // // where p (numerator) and q (denominator) are integer numbers (q > 0) // having no common divisors. */ struct mpz { /* integer number */ int val; /* if ptr is a null pointer, the number is in short format, and val is its value; otherwise, the number is in long format, and val is its sign (+1 or -1) */ struct mpz_seg *ptr; /* pointer to the linked list of the number segments ordered in ascending of powers of the base */ }; struct mpz_seg { /* integer number segment */ unsigned short d[6]; /* six digits of the number ordered in ascending of powers of the base */ struct mpz_seg *next; /* pointer to the next number segment */ }; struct mpq { /* rational number (p / q) */ struct mpz p; /* numerator */ struct mpz q; /* denominator */ }; typedef struct mpz *mpz_t; typedef struct mpq *mpq_t; #define gmp_get_atom _glp_gmp_get_atom #define gmp_free_atom _glp_gmp_free_atom #define gmp_pool_count _glp_gmp_pool_count #define gmp_get_work _glp_gmp_get_work #define gmp_free_mem _glp_gmp_free_mem #define _mpz_init _glp_mpz_init #define mpz_clear _glp_mpz_clear #define mpz_set _glp_mpz_set #define mpz_set_si _glp_mpz_set_si #define mpz_get_d _glp_mpz_get_d #define mpz_get_d_2exp _glp_mpz_get_d_2exp #define mpz_swap _glp_mpz_swap #define mpz_add _glp_mpz_add #define mpz_sub _glp_mpz_sub #define mpz_mul _glp_mpz_mul #define mpz_neg _glp_mpz_neg #define mpz_abs _glp_mpz_abs #define mpz_div _glp_mpz_div #define mpz_gcd _glp_mpz_gcd #define mpz_cmp _glp_mpz_cmp #define mpz_sgn _glp_mpz_sgn #define mpz_out_str _glp_mpz_out_str #define _mpq_init _glp_mpq_init #define mpq_clear _glp_mpq_clear #define mpq_canonicalize _glp_mpq_canonicalize #define mpq_set _glp_mpq_set #define mpq_set_si _glp_mpq_set_si #define mpq_get_d _glp_mpq_get_d #define mpq_set_d _glp_mpq_set_d #define mpq_add _glp_mpq_add #define mpq_sub _glp_mpq_sub #define mpq_mul _glp_mpq_mul #define mpq_div _glp_mpq_div #define mpq_neg _glp_mpq_neg #define mpq_abs _glp_mpq_abs #define mpq_cmp _glp_mpq_cmp #define mpq_sgn _glp_mpq_sgn #define mpq_out_str _glp_mpq_out_str void *gmp_get_atom(int size); void gmp_free_atom(void *ptr, int size); int gmp_pool_count(void); unsigned short *gmp_get_work(int size); void gmp_free_mem(void); mpz_t _mpz_init(void); #define mpz_init(x) (void)((x) = _mpz_init()) void mpz_clear(mpz_t x); void mpz_set(mpz_t z, mpz_t x); void mpz_set_si(mpz_t x, int val); double mpz_get_d(mpz_t x); double mpz_get_d_2exp(int *exp, mpz_t x); void mpz_swap(mpz_t x, mpz_t y); void mpz_add(mpz_t, mpz_t, mpz_t); void mpz_sub(mpz_t, mpz_t, mpz_t); void mpz_mul(mpz_t, mpz_t, mpz_t); void mpz_neg(mpz_t z, mpz_t x); void mpz_abs(mpz_t z, mpz_t x); void mpz_div(mpz_t q, mpz_t r, mpz_t x, mpz_t y); void mpz_gcd(mpz_t z, mpz_t x, mpz_t y); int mpz_cmp(mpz_t x, mpz_t y); int mpz_sgn(mpz_t x); int mpz_out_str(void *fp, int base, mpz_t x); mpq_t _mpq_init(void); #define mpq_init(x) (void)((x) = _mpq_init()) void mpq_clear(mpq_t x); void mpq_canonicalize(mpq_t x); void mpq_set(mpq_t z, mpq_t x); void mpq_set_si(mpq_t x, int p, unsigned int q); double mpq_get_d(mpq_t x); void mpq_set_d(mpq_t x, double val); void mpq_add(mpq_t z, mpq_t x, mpq_t y); void mpq_sub(mpq_t z, mpq_t x, mpq_t y); void mpq_mul(mpq_t z, mpq_t x, mpq_t y); void mpq_div(mpq_t z, mpq_t x, mpq_t y); void mpq_neg(mpq_t z, mpq_t x); void mpq_abs(mpq_t z, mpq_t x); int mpq_cmp(mpq_t x, mpq_t y); int mpq_sgn(mpq_t x); int mpq_out_str(void *fp, int base, mpq_t x); #endif #endif /* eof */ praat-6.0.04/external/glpk/glphbm.c000066400000000000000000000455671261542461700171350ustar00rootroot00000000000000/* glphbm.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #define _GLPSTD_ERRNO #define _GLPSTD_STDIO #include "glphbm.h" #include "glpenv.h" /*********************************************************************** * NAME * * hbm_read_mat - read sparse matrix in Harwell-Boeing format * * SYNOPSIS * * #include "glphbm.h" * HBM *hbm_read_mat(const char *fname); * * DESCRIPTION * * The routine hbm_read_mat reads a sparse matrix in the Harwell-Boeing * format from a text file whose name is the character string fname. * * Detailed description of the Harwell-Boeing format recognised by this * routine is given in the following report: * * I.S.Duff, R.G.Grimes, J.G.Lewis. User's Guide for the Harwell-Boeing * Sparse Matrix Collection (Release I), TR/PA/92/86, October 1992. * * RETURNS * * If no error occured, the routine hbm_read_mat returns a pointer to * a data structure containing the matrix. In case of error the routine * prints an appropriate error message and returns NULL. */ struct dsa { /* working area used by routine hbm_read_mat */ const char *fname; /* name of input text file */ FILE *fp; /* stream assigned to input text file */ int seqn; /* card sequential number */ char card[80+1]; /* card image buffer */ int fmt_p; /* scale factor */ int fmt_k; /* iterator */ int fmt_f; /* format code */ int fmt_w; /* field width */ int fmt_d; /* number of decimal places after point */ }; /*********************************************************************** * read_card - read next data card * * This routine reads the next 80-column card from the input text file * and stores its image into the character string card. If the card was * read successfully, the routine returns zero, otherwise non-zero. */ static int read_card(struct dsa *dsa) { int k, c; dsa->seqn++; memset(dsa->card, ' ', 80), dsa->card[80] = '\0'; k = 0; for (;;) { c = fgetc(dsa->fp); if (ferror(dsa->fp)) { xprintf("%s:%d: read error - %s\n", dsa->fname, dsa->seqn, strerror(errno)); return 1; } if (feof(dsa->fp)) { if (k == 0) xprintf("%s:%d: unexpected EOF\n", dsa->fname, dsa->seqn); else xprintf("%s:%d: missing final LF\n", dsa->fname, dsa->seqn); return 1; } if (c == '\r') continue; if (c == '\n') break; if (iscntrl(c)) { xprintf("%s:%d: invalid control character 0x%02X\n", dsa->fname, dsa->seqn, c); return 1; } if (k == 80) { xprintf("%s:%d: card image too long\n", dsa->fname, dsa->seqn); return 1; } dsa->card[k++] = (char)c; } return 0; } /*********************************************************************** * scan_int - scan integer value from the current card * * This routine scans an integer value from the current card, where fld * is the name of the field, pos is the position of the field, width is * the width of the field, val points to a location to which the scanned * value should be stored. If the value was scanned successfully, the * routine returns zero, otherwise non-zero. */ static int scan_int(struct dsa *dsa, char *fld, int pos, int width, int *val) { char str[80+1]; xassert(1 <= width && width <= 80); memcpy(str, dsa->card + pos, width), str[width] = '\0'; if (str2int(strspx(str), val)) { xprintf("%s:%d: field `%s' contains invalid value `%s'\n", dsa->fname, dsa->seqn, fld, str); return 1; } return 0; } /*********************************************************************** * parse_fmt - parse Fortran format specification * * This routine parses the Fortran format specification represented as * character string which fmt points to and stores format elements into * appropriate static locations. Should note that not all valid Fortran * format specifications may be recognised. If the format specification * was recognised, the routine returns zero, otherwise non-zero. */ static int parse_fmt(struct dsa *dsa, char *fmt) { int k, s, val; char str[80+1]; /* first character should be left parenthesis */ if (fmt[0] != '(') fail: { xprintf("hbm_read_mat: format `%s' not recognised\n", fmt); return 1; } k = 1; /* optional scale factor */ dsa->fmt_p = 0; if (isdigit((unsigned char)fmt[k])) { s = 0; while (isdigit((unsigned char)fmt[k])) { if (s == 80) goto fail; str[s++] = fmt[k++]; } str[s] = '\0'; if (str2int(str, &val)) goto fail; if (toupper((unsigned char)fmt[k]) != 'P') goto iter; dsa->fmt_p = val, k++; if (!(0 <= dsa->fmt_p && dsa->fmt_p <= 255)) goto fail; /* optional comma may follow scale factor */ if (fmt[k] == ',') k++; } /* optional iterator */ dsa->fmt_k = 1; if (isdigit((unsigned char)fmt[k])) { s = 0; while (isdigit((unsigned char)fmt[k])) { if (s == 80) goto fail; str[s++] = fmt[k++]; } str[s] = '\0'; if (str2int(str, &val)) goto fail; iter: dsa->fmt_k = val; if (!(1 <= dsa->fmt_k && dsa->fmt_k <= 255)) goto fail; } /* format code */ dsa->fmt_f = toupper((unsigned char)fmt[k++]); if (!(dsa->fmt_f == 'D' || dsa->fmt_f == 'E' || dsa->fmt_f == 'F' || dsa->fmt_f == 'G' || dsa->fmt_f == 'I')) goto fail; /* field width */ if (!isdigit((unsigned char)fmt[k])) goto fail; s = 0; while (isdigit((unsigned char)fmt[k])) { if (s == 80) goto fail; str[s++] = fmt[k++]; } str[s] = '\0'; if (str2int(str, &dsa->fmt_w)) goto fail; if (!(1 <= dsa->fmt_w && dsa->fmt_w <= 255)) goto fail; /* optional number of decimal places after point */ dsa->fmt_d = 0; if (fmt[k] == '.') { k++; if (!isdigit((unsigned char)fmt[k])) goto fail; s = 0; while (isdigit((unsigned char)fmt[k])) { if (s == 80) goto fail; str[s++] = fmt[k++]; } str[s] = '\0'; if (str2int(str, &dsa->fmt_d)) goto fail; if (!(0 <= dsa->fmt_d && dsa->fmt_d <= 255)) goto fail; } /* last character should be right parenthesis */ if (!(fmt[k] == ')' && fmt[k+1] == '\0')) goto fail; return 0; } /*********************************************************************** * read_int_array - read array of integer type * * This routine reads an integer array from the input text file, where * name is array name, fmt is Fortran format specification that controls * reading, n is number of array elements, val is array of integer type. * If the array was read successful, the routine returns zero, otherwise * non-zero. */ static int read_int_array(struct dsa *dsa, char *name, char *fmt, int n, int val[]) { int k, pos; char str[80+1]; if (parse_fmt(dsa, fmt)) return 1; if (!(dsa->fmt_f == 'I' && dsa->fmt_w <= 80 && dsa->fmt_k * dsa->fmt_w <= 80)) { xprintf( "%s:%d: can't read array `%s' - invalid format `%s'\n", dsa->fname, dsa->seqn, name, fmt); return 1; } for (k = 1, pos = INT_MAX; k <= n; k++, pos++) { if (pos >= dsa->fmt_k) { if (read_card(dsa)) return 1; pos = 0; } memcpy(str, dsa->card + dsa->fmt_w * pos, dsa->fmt_w); str[dsa->fmt_w] = '\0'; strspx(str); if (str2int(str, &val[k])) { xprintf( "%s:%d: can't read array `%s' - invalid value `%s'\n", dsa->fname, dsa->seqn, name, str); return 1; } } return 0; } /*********************************************************************** * read_real_array - read array of real type * * This routine reads a real array from the input text file, where name * is array name, fmt is Fortran format specification that controls * reading, n is number of array elements, val is array of real type. * If the array was read successful, the routine returns zero, otherwise * non-zero. */ static int read_real_array(struct dsa *dsa, char *name, char *fmt, int n, double val[]) { int k, pos; char str[80+1], *ptr; if (parse_fmt(dsa, fmt)) return 1; if (!(dsa->fmt_f != 'I' && dsa->fmt_w <= 80 && dsa->fmt_k * dsa->fmt_w <= 80)) { xprintf( "%s:%d: can't read array `%s' - invalid format `%s'\n", dsa->fname, dsa->seqn, name, fmt); return 1; } for (k = 1, pos = INT_MAX; k <= n; k++, pos++) { if (pos >= dsa->fmt_k) { if (read_card(dsa)) return 1; pos = 0; } memcpy(str, dsa->card + dsa->fmt_w * pos, dsa->fmt_w); str[dsa->fmt_w] = '\0'; strspx(str); if (strchr(str, '.') == NULL && strcmp(str, "0")) { xprintf("%s(%d): can't read array `%s' - value `%s' has no " "decimal point\n", dsa->fname, dsa->seqn, name, str); return 1; } /* sometimes lower case letters appear */ for (ptr = str; *ptr; ptr++) *ptr = (char)toupper((unsigned char)*ptr); ptr = strchr(str, 'D'); if (ptr != NULL) *ptr = 'E'; /* value may appear with decimal exponent but without letters E or D (for example, -123.456-012), so missing letter should be inserted */ ptr = strchr(str+1, '+'); if (ptr == NULL) ptr = strchr(str+1, '-'); if (ptr != NULL && *(ptr-1) != 'E') { xassert(strlen(str) < 80); memmove(ptr+1, ptr, strlen(ptr)+1); *ptr = 'E'; } if (str2num(str, &val[k])) { xprintf( "%s:%d: can't read array `%s' - invalid value `%s'\n", dsa->fname, dsa->seqn, name, str); return 1; } } return 0; } HBM *hbm_read_mat(const char *fname) { struct dsa _dsa, *dsa = &_dsa; HBM *hbm = NULL; dsa->fname = fname; xprintf("hbm_read_mat: reading matrix from `%s'...\n", dsa->fname); dsa->fp = fopen(dsa->fname, "r"); if (dsa->fp == NULL) { xprintf("hbm_read_mat: unable to open `%s' - %s\n", dsa->fname, strerror(errno)); goto fail; } dsa->seqn = 0; hbm = xmalloc(sizeof(HBM)); memset(hbm, 0, sizeof(HBM)); /* read the first heading card */ if (read_card(dsa)) goto fail; memcpy(hbm->title, dsa->card, 72), hbm->title[72] = '\0'; strtrim(hbm->title); xprintf("%s\n", hbm->title); memcpy(hbm->key, dsa->card+72, 8), hbm->key[8] = '\0'; strspx(hbm->key); xprintf("key = %s\n", hbm->key); /* read the second heading card */ if (read_card(dsa)) goto fail; if (scan_int(dsa, "totcrd", 0, 14, &hbm->totcrd)) goto fail; if (scan_int(dsa, "ptrcrd", 14, 14, &hbm->ptrcrd)) goto fail; if (scan_int(dsa, "indcrd", 28, 14, &hbm->indcrd)) goto fail; if (scan_int(dsa, "valcrd", 42, 14, &hbm->valcrd)) goto fail; if (scan_int(dsa, "rhscrd", 56, 14, &hbm->rhscrd)) goto fail; xprintf("totcrd = %d; ptrcrd = %d; indcrd = %d; valcrd = %d; rhsc" "rd = %d\n", hbm->totcrd, hbm->ptrcrd, hbm->indcrd, hbm->valcrd, hbm->rhscrd); /* read the third heading card */ if (read_card(dsa)) goto fail; memcpy(hbm->mxtype, dsa->card, 3), hbm->mxtype[3] = '\0'; if (strchr("RCP", hbm->mxtype[0]) == NULL || strchr("SUHZR", hbm->mxtype[1]) == NULL || strchr("AE", hbm->mxtype[2]) == NULL) { xprintf("%s:%d: matrix type `%s' not recognised\n", dsa->fname, dsa->seqn, hbm->mxtype); goto fail; } if (scan_int(dsa, "nrow", 14, 14, &hbm->nrow)) goto fail; if (scan_int(dsa, "ncol", 28, 14, &hbm->ncol)) goto fail; if (scan_int(dsa, "nnzero", 42, 14, &hbm->nnzero)) goto fail; if (scan_int(dsa, "neltvl", 56, 14, &hbm->neltvl)) goto fail; xprintf("mxtype = %s; nrow = %d; ncol = %d; nnzero = %d; neltvl =" " %d\n", hbm->mxtype, hbm->nrow, hbm->ncol, hbm->nnzero, hbm->neltvl); /* read the fourth heading card */ if (read_card(dsa)) goto fail; memcpy(hbm->ptrfmt, dsa->card, 16), hbm->ptrfmt[16] = '\0'; strspx(hbm->ptrfmt); memcpy(hbm->indfmt, dsa->card+16, 16), hbm->indfmt[16] = '\0'; strspx(hbm->indfmt); memcpy(hbm->valfmt, dsa->card+32, 20), hbm->valfmt[20] = '\0'; strspx(hbm->valfmt); memcpy(hbm->rhsfmt, dsa->card+52, 20), hbm->rhsfmt[20] = '\0'; strspx(hbm->rhsfmt); xprintf("ptrfmt = %s; indfmt = %s; valfmt = %s; rhsfmt = %s\n", hbm->ptrfmt, hbm->indfmt, hbm->valfmt, hbm->rhsfmt); /* read the fifth heading card (optional) */ if (hbm->rhscrd <= 0) { strcpy(hbm->rhstyp, "???"); hbm->nrhs = 0; hbm->nrhsix = 0; } else { if (read_card(dsa)) goto fail; memcpy(hbm->rhstyp, dsa->card, 3), hbm->rhstyp[3] = '\0'; if (scan_int(dsa, "nrhs", 14, 14, &hbm->nrhs)) goto fail; if (scan_int(dsa, "nrhsix", 28, 14, &hbm->nrhsix)) goto fail; xprintf("rhstyp = `%s'; nrhs = %d; nrhsix = %d\n", hbm->rhstyp, hbm->nrhs, hbm->nrhsix); } /* read matrix structure */ hbm->colptr = xcalloc(1+hbm->ncol+1, sizeof(int)); if (read_int_array(dsa, "colptr", hbm->ptrfmt, hbm->ncol+1, hbm->colptr)) goto fail; hbm->rowind = xcalloc(1+hbm->nnzero, sizeof(int)); if (read_int_array(dsa, "rowind", hbm->indfmt, hbm->nnzero, hbm->rowind)) goto fail; /* read matrix values */ if (hbm->valcrd <= 0) goto done; if (hbm->mxtype[2] == 'A') { /* assembled matrix */ hbm->values = xcalloc(1+hbm->nnzero, sizeof(double)); if (read_real_array(dsa, "values", hbm->valfmt, hbm->nnzero, hbm->values)) goto fail; } else { /* elemental (unassembled) matrix */ hbm->values = xcalloc(1+hbm->neltvl, sizeof(double)); if (read_real_array(dsa, "values", hbm->valfmt, hbm->neltvl, hbm->values)) goto fail; } /* read right-hand sides */ if (hbm->nrhs <= 0) goto done; if (hbm->rhstyp[0] == 'F') { /* dense format */ hbm->nrhsvl = hbm->nrow * hbm->nrhs; hbm->rhsval = xcalloc(1+hbm->nrhsvl, sizeof(double)); if (read_real_array(dsa, "rhsval", hbm->rhsfmt, hbm->nrhsvl, hbm->rhsval)) goto fail; } else if (hbm->rhstyp[0] == 'M' && hbm->mxtype[2] == 'A') { /* sparse format */ /* read pointers */ hbm->rhsptr = xcalloc(1+hbm->nrhs+1, sizeof(int)); if (read_int_array(dsa, "rhsptr", hbm->ptrfmt, hbm->nrhs+1, hbm->rhsptr)) goto fail; /* read sparsity pattern */ hbm->rhsind = xcalloc(1+hbm->nrhsix, sizeof(int)); if (read_int_array(dsa, "rhsind", hbm->indfmt, hbm->nrhsix, hbm->rhsind)) goto fail; /* read values */ hbm->rhsval = xcalloc(1+hbm->nrhsix, sizeof(double)); if (read_real_array(dsa, "rhsval", hbm->rhsfmt, hbm->nrhsix, hbm->rhsval)) goto fail; } else if (hbm->rhstyp[0] == 'M' && hbm->mxtype[2] == 'E') { /* elemental format */ hbm->rhsval = xcalloc(1+hbm->nrhsvl, sizeof(double)); if (read_real_array(dsa, "rhsval", hbm->rhsfmt, hbm->nrhsvl, hbm->rhsval)) goto fail; } else { xprintf("%s:%d: right-hand side type `%c' not recognised\n", dsa->fname, dsa->seqn, hbm->rhstyp[0]); goto fail; } /* read starting guesses */ if (hbm->rhstyp[1] == 'G') { hbm->nguess = hbm->nrow * hbm->nrhs; hbm->sguess = xcalloc(1+hbm->nguess, sizeof(double)); if (read_real_array(dsa, "sguess", hbm->rhsfmt, hbm->nguess, hbm->sguess)) goto fail; } /* read solution vectors */ if (hbm->rhstyp[2] == 'X') { hbm->nexact = hbm->nrow * hbm->nrhs; hbm->xexact = xcalloc(1+hbm->nexact, sizeof(double)); if (read_real_array(dsa, "xexact", hbm->rhsfmt, hbm->nexact, hbm->xexact)) goto fail; } done: /* reading has been completed */ xprintf("hbm_read_mat: %d cards were read\n", dsa->seqn); fclose(dsa->fp); return hbm; fail: /* something wrong in Danish kingdom */ if (hbm != NULL) { if (hbm->colptr != NULL) xfree(hbm->colptr); if (hbm->rowind != NULL) xfree(hbm->rowind); if (hbm->rhsptr != NULL) xfree(hbm->rhsptr); if (hbm->rhsind != NULL) xfree(hbm->rhsind); if (hbm->values != NULL) xfree(hbm->values); if (hbm->rhsval != NULL) xfree(hbm->rhsval); if (hbm->sguess != NULL) xfree(hbm->sguess); if (hbm->xexact != NULL) xfree(hbm->xexact); xfree(hbm); } if (dsa->fp != NULL) fclose(dsa->fp); return NULL; } /*********************************************************************** * NAME * * hbm_free_mat - free sparse matrix in Harwell-Boeing format * * SYNOPSIS * * #include "glphbm.h" * void hbm_free_mat(HBM *hbm); * * DESCRIPTION * * The hbm_free_mat routine frees all the memory allocated to the data * structure containing a sparse matrix in the Harwell-Boeing format. */ void hbm_free_mat(HBM *hbm) { if (hbm->colptr != NULL) xfree(hbm->colptr); if (hbm->rowind != NULL) xfree(hbm->rowind); if (hbm->rhsptr != NULL) xfree(hbm->rhsptr); if (hbm->rhsind != NULL) xfree(hbm->rhsind); if (hbm->values != NULL) xfree(hbm->values); if (hbm->rhsval != NULL) xfree(hbm->rhsval); if (hbm->sguess != NULL) xfree(hbm->sguess); if (hbm->xexact != NULL) xfree(hbm->xexact); xfree(hbm); return; } /* eof */ praat-6.0.04/external/glpk/glphbm.h000066400000000000000000000110201261542461700171130ustar00rootroot00000000000000/* glphbm.h (Harwell-Boeing sparse matrix format) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPHBM_H #define GLPHBM_H typedef struct HBM HBM; struct HBM { /* sparse matrix in Harwell-Boeing format; for details see the report: I.S.Duff, R.G.Grimes, J.G.Lewis. User's Guide for the Harwell-Boeing Sparse Matrix Collection (Release I), 1992 */ char title[72+1]; /* matrix title (informative) */ char key[8+1]; /* matrix key (informative) */ char mxtype[3+1]; /* matrix type: R.. real matrix C.. complex matrix P.. pattern only (no numerical values supplied) .S. symmetric (lower triangle + main diagonal) .U. unsymmetric .H. hermitian (lower triangle + main diagonal) .Z. skew symmetric (lower triangle only) .R. rectangular ..A assembled ..E elemental (unassembled) */ char rhstyp[3+1]; /* optional types: F.. right-hand sides in dense format M.. right-hand sides in same format as matrix .G. starting vector(s) (guess) is supplied ..X exact solution vector(s) is supplied */ char ptrfmt[16+1]; /* format for pointers */ char indfmt[16+1]; /* format for row (or variable) indices */ char valfmt[20+1]; /* format for numerical values of coefficient matrix */ char rhsfmt[20+1]; /* format for numerical values of right-hand sides */ int totcrd; /* total number of cards excluding header */ int ptrcrd; /* number of cards for ponters */ int indcrd; /* number of cards for row (or variable) indices */ int valcrd; /* number of cards for numerical values */ int rhscrd; /* number of lines for right-hand sides; including starting guesses and solution vectors if present; zero indicates no right-hand side data is present */ int nrow; /* number of rows (or variables) */ int ncol; /* number of columns (or elements) */ int nnzero; /* number of row (or variable) indices; equal to number of entries for assembled matrix */ int neltvl; /* number of elemental matrix entries; zero in case of assembled matrix */ int nrhs; /* number of right-hand sides */ int nrhsix; /* number of row indices; ignored in case of unassembled matrix */ int nrhsvl; /* total number of entries in all right-hand sides */ int nguess; /* total number of entries in all starting guesses */ int nexact; /* total number of entries in all solution vectors */ int *colptr; /* alias: eltptr */ /* column pointers (in case of assembled matrix); elemental matrix pointers (in case of unassembled matrix) */ int *rowind; /* alias: varind */ /* row indices (in case of assembled matrix); variable indices (in case of unassembled matrix) */ int *rhsptr; /* right-hand side pointers */ int *rhsind; /* right-hand side indices */ double *values; /* matrix values */ double *rhsval; /* right-hand side values */ double *sguess; /* starting guess values */ double *xexact; /* solution vector values */ }; #define hbm_read_mat _glp_hbm_read_mat HBM *hbm_read_mat(const char *fname); /* read sparse matrix in Harwell-Boeing format */ #define hbm_free_mat _glp_hbm_free_mat void hbm_free_mat(HBM *hbm); /* free sparse matrix in Harwell-Boeing format */ #endif /* eof */ praat-6.0.04/external/glpk/glpini01.c000066400000000000000000000541511261542461700172740ustar00rootroot00000000000000/* glpini01.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpapi.h" /*---------------------------------------------------------------------- -- triang - find maximal triangular part of a rectangular matrix. -- -- *Synopsis* -- -- int triang(int m, int n, -- void *info, int (*mat)(void *info, int k, int ndx[]), -- int rn[], int cn[]); -- -- *Description* -- -- For a given rectangular (sparse) matrix A with m rows and n columns -- the routine triang tries to find such permutation matrices P and Q -- that the first rows and columns of the matrix B = P*A*Q form a lower -- triangular submatrix of as greatest size as possible: -- -- 1 n -- 1 * . . . . . . x x x x x x -- * * . . . . . x x x x x x -- * * * . . . . x x x x x x -- * * * * . . . x x x x x x -- B = P*A*Q = * * * * * . . x x x x x x -- * * * * * * . x x x x x x -- * * * * * * * x x x x x x -- x x x x x x x x x x x x x -- x x x x x x x x x x x x x -- m x x x x x x x x x x x x x -- -- where: '*' - elements of the lower triangular part, '.' - structural -- zeros, 'x' - other (either non-zero or zero) elements. -- -- The parameter info is a transit pointer passed to the formal routine -- mat (see below). -- -- The formal routine mat specifies the given matrix A in both row- and -- column-wise formats. In order to obtain an i-th row of the matrix A -- the routine triang calls the routine mat with the parameter k = +i, -- 1 <= i <= m. In response the routine mat should store column indices -- of (non-zero) elements of the i-th row to the locations ndx[1], ..., -- ndx[len], where len is number of non-zeros in the i-th row returned -- on exit. Analogously, in order to obtain a j-th column of the matrix -- A, the routine mat is called with the parameter k = -j, 1 <= j <= n, -- and should return pattern of the j-th column in the same way as for -- row patterns. Note that the routine mat may be called more than once -- for the same rows and columns. -- -- On exit the routine computes two resultant arrays rn and cn, which -- define the permutation matrices P and Q, respectively. The array rn -- should have at least 1+m locations, where rn[i] = i' (1 <= i <= m) -- means that i-th row of the original matrix A corresponds to i'-th row -- of the matrix B = P*A*Q. Similarly, the array cn should have at least -- 1+n locations, where cn[j] = j' (1 <= j <= n) means that j-th column -- of the matrix A corresponds to j'-th column of the matrix B. -- -- *Returns* -- -- The routine triang returns the size of the lower tringular part of -- the matrix B = P*A*Q (see the figure above). -- -- *Complexity* -- -- The time complexity of the routine triang is O(nnz), where nnz is -- number of non-zeros in the given matrix A. -- -- *Algorithm* -- -- The routine triang starts from the matrix B = P*Q*A, where P and Q -- are unity matrices, so initially B = A. -- -- Before the next iteration B = (B1 | B2 | B3), where B1 is partially -- built a lower triangular submatrix, B2 is the active submatrix, and -- B3 is a submatrix that contains rejected columns. Thus, the current -- matrix B looks like follows (initially k1 = 1 and k2 = n): -- -- 1 k1 k2 n -- 1 x . . . . . . . . . . . . . # # # -- x x . . . . . . . . . . . . # # # -- x x x . . . . . . . . . . # # # # -- x x x x . . . . . . . . . # # # # -- x x x x x . . . . . . . # # # # # -- k1 x x x x x * * * * * * * # # # # # -- x x x x x * * * * * * * # # # # # -- x x x x x * * * * * * * # # # # # -- x x x x x * * * * * * * # # # # # -- m x x x x x * * * * * * * # # # # # -- <--B1---> <----B2-----> <---B3--> -- -- On each iteartion the routine looks for a singleton row, i.e. some -- row that has the only non-zero in the active submatrix B2. If such -- row exists and the corresponding non-zero is b[i,j], where (by the -- definition) k1 <= i <= m and k1 <= j <= k2, the routine permutes -- k1-th and i-th rows and k1-th and j-th columns of the matrix B (in -- order to place the element in the position b[k1,k1]), removes the -- k1-th column from the active submatrix B2, and adds this column to -- the submatrix B1. If no row singletons exist, but B2 is not empty -- yet, the routine chooses a j-th column, which has maximal number of -- non-zeros among other columns of B2, removes this column from B2 and -- adds it to the submatrix B3 in the hope that new row singletons will -- appear in the active submatrix. */ static int triang(int m, int n, void *info, int (*mat)(void *info, int k, int ndx[]), int rn[], int cn[]) { int *ndx; /* int ndx[1+max(m,n)]; */ /* this array is used for querying row and column patterns of the given matrix A (the third parameter to the routine mat) */ int *rs_len; /* int rs_len[1+m]; */ /* rs_len[0] is not used; rs_len[i], 1 <= i <= m, is number of non-zeros in the i-th row of the matrix A, which (non-zeros) belong to the current active submatrix */ int *rs_head; /* int rs_head[1+n]; */ /* rs_head[len], 0 <= len <= n, is the number i of the first row of the matrix A, for which rs_len[i] = len */ int *rs_prev; /* int rs_prev[1+m]; */ /* rs_prev[0] is not used; rs_prev[i], 1 <= i <= m, is a number i' of the previous row of the matrix A, for which rs_len[i] = rs_len[i'] (zero marks the end of this linked list) */ int *rs_next; /* int rs_next[1+m]; */ /* rs_next[0] is not used; rs_next[i], 1 <= i <= m, is a number i' of the next row of the matrix A, for which rs_len[i] = rs_len[i'] (zero marks the end this linked list) */ int cs_head; /* is a number j of the first column of the matrix A, which has maximal number of non-zeros among other columns */ int *cs_prev; /* cs_prev[1+n]; */ /* cs_prev[0] is not used; cs_prev[j], 1 <= j <= n, is a number of the previous column of the matrix A with the same or greater number of non-zeros than in the j-th column (zero marks the end of this linked list) */ int *cs_next; /* cs_next[1+n]; */ /* cs_next[0] is not used; cs_next[j], 1 <= j <= n, is a number of the next column of the matrix A with the same or lesser number of non-zeros than in the j-th column (zero marks the end of this linked list) */ int i, j, ii, jj, k1, k2, len, t, size = 0; int *head, *rn_inv, *cn_inv; if (!(m > 0 && n > 0)) xerror("triang: m = %d; n = %d; invalid dimension\n", m, n); /* allocate working arrays */ ndx = xcalloc(1+(m >= n ? m : n), sizeof(int)); rs_len = xcalloc(1+m, sizeof(int)); rs_head = xcalloc(1+n, sizeof(int)); rs_prev = xcalloc(1+m, sizeof(int)); rs_next = xcalloc(1+m, sizeof(int)); cs_prev = xcalloc(1+n, sizeof(int)); cs_next = xcalloc(1+n, sizeof(int)); /* build linked lists of columns of the matrix A with the same number of non-zeros */ head = rs_len; /* currently rs_len is used as working array */ for (len = 0; len <= m; len ++) head[len] = 0; for (j = 1; j <= n; j++) { /* obtain length of the j-th column */ len = mat(info, -j, ndx); xassert(0 <= len && len <= m); /* include the j-th column in the corresponding linked list */ cs_prev[j] = head[len]; head[len] = j; } /* merge all linked lists of columns in one linked list, where columns are ordered by descending of their lengths */ cs_head = 0; for (len = 0; len <= m; len++) { for (j = head[len]; j != 0; j = cs_prev[j]) { cs_next[j] = cs_head; cs_head = j; } } jj = 0; for (j = cs_head; j != 0; j = cs_next[j]) { cs_prev[j] = jj; jj = j; } /* build initial doubly linked lists of rows of the matrix A with the same number of non-zeros */ for (len = 0; len <= n; len++) rs_head[len] = 0; for (i = 1; i <= m; i++) { /* obtain length of the i-th row */ rs_len[i] = len = mat(info, +i, ndx); xassert(0 <= len && len <= n); /* include the i-th row in the correspondng linked list */ rs_prev[i] = 0; rs_next[i] = rs_head[len]; if (rs_next[i] != 0) rs_prev[rs_next[i]] = i; rs_head[len] = i; } /* initially all rows and columns of the matrix A are active */ for (i = 1; i <= m; i++) rn[i] = 0; for (j = 1; j <= n; j++) cn[j] = 0; /* set initial bounds of the active submatrix */ k1 = 1, k2 = n; /* main loop starts here */ while (k1 <= k2) { i = rs_head[1]; if (i != 0) { /* the i-th row of the matrix A is a row singleton, since it has the only non-zero in the active submatrix */ xassert(rs_len[i] == 1); /* determine the number j of an active column of the matrix A, in which this non-zero is placed */ j = 0; t = mat(info, +i, ndx); xassert(0 <= t && t <= n); for (t = t; t >= 1; t--) { jj = ndx[t]; xassert(1 <= jj && jj <= n); if (cn[jj] == 0) { xassert(j == 0); j = jj; } } xassert(j != 0); /* the singleton is a[i,j]; move a[i,j] to the position b[k1,k1] of the matrix B */ rn[i] = cn[j] = k1; /* shift the left bound of the active submatrix */ k1++; /* increase the size of the lower triangular part */ size++; } else { /* the current active submatrix has no row singletons */ /* remove an active column with maximal number of non-zeros from the active submatrix */ j = cs_head; xassert(j != 0); cn[j] = k2; /* shift the right bound of the active submatrix */ k2--; } /* the j-th column of the matrix A has been removed from the active submatrix */ /* remove the j-th column from the linked list */ if (cs_prev[j] == 0) cs_head = cs_next[j]; else cs_next[cs_prev[j]] = cs_next[j]; if (cs_next[j] == 0) /* nop */; else cs_prev[cs_next[j]] = cs_prev[j]; /* go through non-zeros of the j-th columns and update active lengths of the corresponding rows */ t = mat(info, -j, ndx); xassert(0 <= t && t <= m); for (t = t; t >= 1; t--) { i = ndx[t]; xassert(1 <= i && i <= m); /* the non-zero a[i,j] has left the active submatrix */ len = rs_len[i]; xassert(len >= 1); /* remove the i-th row from the linked list of rows with active length len */ if (rs_prev[i] == 0) rs_head[len] = rs_next[i]; else rs_next[rs_prev[i]] = rs_next[i]; if (rs_next[i] == 0) /* nop */; else rs_prev[rs_next[i]] = rs_prev[i]; /* decrease the active length of the i-th row */ rs_len[i] = --len; /* return the i-th row to the corresponding linked list */ rs_prev[i] = 0; rs_next[i] = rs_head[len]; if (rs_next[i] != 0) rs_prev[rs_next[i]] = i; rs_head[len] = i; } } /* other rows of the matrix A, which are still active, correspond to rows k1, ..., m of the matrix B (in arbitrary order) */ for (i = 1; i <= m; i++) if (rn[i] == 0) rn[i] = k1++; /* but for columns this is not needed, because now the submatrix B2 has no columns */ for (j = 1; j <= n; j++) xassert(cn[j] != 0); /* perform some optional checks */ /* make sure that rn is a permutation of {1, ..., m} and cn is a permutation of {1, ..., n} */ rn_inv = rs_len; /* used as working array */ for (ii = 1; ii <= m; ii++) rn_inv[ii] = 0; for (i = 1; i <= m; i++) { ii = rn[i]; xassert(1 <= ii && ii <= m); xassert(rn_inv[ii] == 0); rn_inv[ii] = i; } cn_inv = rs_head; /* used as working array */ for (jj = 1; jj <= n; jj++) cn_inv[jj] = 0; for (j = 1; j <= n; j++) { jj = cn[j]; xassert(1 <= jj && jj <= n); xassert(cn_inv[jj] == 0); cn_inv[jj] = j; } /* make sure that the matrix B = P*A*Q really has the form, which was declared */ for (ii = 1; ii <= size; ii++) { int diag = 0; i = rn_inv[ii]; t = mat(info, +i, ndx); xassert(0 <= t && t <= n); for (t = t; t >= 1; t--) { j = ndx[t]; xassert(1 <= j && j <= n); jj = cn[j]; if (jj <= size) xassert(jj <= ii); if (jj == ii) { xassert(!diag); diag = 1; } } xassert(diag); } /* free working arrays */ xfree(ndx); xfree(rs_len); xfree(rs_head); xfree(rs_prev); xfree(rs_next); xfree(cs_prev); xfree(cs_next); /* return to the calling program */ return size; } /*---------------------------------------------------------------------- -- adv_basis - construct advanced initial LP basis. -- -- *Synopsis* -- -- #include "glpini.h" -- void adv_basis(glp_prob *lp); -- -- *Description* -- -- The routine adv_basis constructs an advanced initial basis for an LP -- problem object, which the parameter lp points to. -- -- In order to build the initial basis the routine does the following: -- -- 1) includes in the basis all non-fixed auxiliary variables; -- -- 2) includes in the basis as many as possible non-fixed structural -- variables preserving triangular form of the basis matrix; -- -- 3) includes in the basis appropriate (fixed) auxiliary variables -- in order to complete the basis. -- -- As a result the initial basis has minimum of fixed variables and the -- corresponding basis matrix is triangular. */ static int mat(void *info, int k, int ndx[]) { /* this auxiliary routine returns the pattern of a given row or a given column of the augmented constraint matrix A~ = (I|-A), in which columns of fixed variables are implicitly cleared */ LPX *lp = info; int m = lpx_get_num_rows(lp); int n = lpx_get_num_cols(lp); int typx, i, j, lll, len = 0; if (k > 0) { /* the pattern of the i-th row is required */ i = +k; xassert(1 <= i && i <= m); #if 0 /* 22/XII-2003 */ /* if the auxiliary variable x[i] is non-fixed, include its element (placed in the i-th column) in the pattern */ lpx_get_row_bnds(lp, i, &typx, NULL, NULL); if (typx != LPX_FX) ndx[++len] = i; /* include in the pattern elements placed in columns, which correspond to non-fixed structural varables */ i_beg = aa_ptr[i]; i_end = i_beg + aa_len[i] - 1; for (i_ptr = i_beg; i_ptr <= i_end; i_ptr++) { j = m + sv_ndx[i_ptr]; lpx_get_col_bnds(lp, j-m, &typx, NULL, NULL); if (typx != LPX_FX) ndx[++len] = j; } #else lll = lpx_get_mat_row(lp, i, ndx, NULL); for (k = 1; k <= lll; k++) { lpx_get_col_bnds(lp, ndx[k], &typx, NULL, NULL); if (typx != LPX_FX) ndx[++len] = m + ndx[k]; } lpx_get_row_bnds(lp, i, &typx, NULL, NULL); if (typx != LPX_FX) ndx[++len] = i; #endif } else { /* the pattern of the j-th column is required */ j = -k; xassert(1 <= j && j <= m+n); /* if the (auxiliary or structural) variable x[j] is fixed, the pattern of its column is empty */ if (j <= m) lpx_get_row_bnds(lp, j, &typx, NULL, NULL); else lpx_get_col_bnds(lp, j-m, &typx, NULL, NULL); if (typx != LPX_FX) { if (j <= m) { /* x[j] is non-fixed auxiliary variable */ ndx[++len] = j; } else { /* x[j] is non-fixed structural variables */ #if 0 /* 22/XII-2003 */ j_beg = aa_ptr[j]; j_end = j_beg + aa_len[j] - 1; for (j_ptr = j_beg; j_ptr <= j_end; j_ptr++) ndx[++len] = sv_ndx[j_ptr]; #else len = lpx_get_mat_col(lp, j-m, ndx, NULL); #endif } } } /* return the length of the row/column pattern */ return len; } static void adv_basis(glp_prob *lp) { int m = lpx_get_num_rows(lp); int n = lpx_get_num_cols(lp); int i, j, jj, k, size; int *rn, *cn, *rn_inv, *cn_inv; int typx, *tagx = xcalloc(1+m+n, sizeof(int)); double lb, ub; xprintf("Constructing initial basis...\n"); #if 0 /* 13/V-2009 */ if (m == 0) xerror("glp_adv_basis: problem has no rows\n"); if (n == 0) xerror("glp_adv_basis: problem has no columns\n"); #else if (m == 0 || n == 0) { glp_std_basis(lp); return; } #endif /* use the routine triang (see above) to find maximal triangular part of the augmented constraint matrix A~ = (I|-A); in order to prevent columns of fixed variables to be included in the triangular part, such columns are implictly removed from the matrix A~ by the routine adv_mat */ rn = xcalloc(1+m, sizeof(int)); cn = xcalloc(1+m+n, sizeof(int)); size = triang(m, m+n, lp, mat, rn, cn); if (lpx_get_int_parm(lp, LPX_K_MSGLEV) >= 3) xprintf("Size of triangular part = %d\n", size); /* the first size rows and columns of the matrix P*A~*Q (where P and Q are permutation matrices defined by the arrays rn and cn) form a lower triangular matrix; build the arrays (rn_inv and cn_inv), which define the matrices inv(P) and inv(Q) */ rn_inv = xcalloc(1+m, sizeof(int)); cn_inv = xcalloc(1+m+n, sizeof(int)); for (i = 1; i <= m; i++) rn_inv[rn[i]] = i; for (j = 1; j <= m+n; j++) cn_inv[cn[j]] = j; /* include the columns of the matrix A~, which correspond to the first size columns of the matrix P*A~*Q, in the basis */ for (k = 1; k <= m+n; k++) tagx[k] = -1; for (jj = 1; jj <= size; jj++) { j = cn_inv[jj]; /* the j-th column of A~ is the jj-th column of P*A~*Q */ tagx[j] = LPX_BS; } /* if size < m, we need to add appropriate columns of auxiliary variables to the basis */ for (jj = size + 1; jj <= m; jj++) { /* the jj-th column of P*A~*Q should be replaced by the column of the auxiliary variable, for which the only unity element is placed in the position [jj,jj] */ i = rn_inv[jj]; /* the jj-th row of P*A~*Q is the i-th row of A~, but in the i-th row of A~ the unity element belongs to the i-th column of A~; therefore the disired column corresponds to the i-th auxiliary variable (note that this column doesn't belong to the triangular part found by the routine triang) */ xassert(1 <= i && i <= m); xassert(cn[i] > size); tagx[i] = LPX_BS; } /* free working arrays */ xfree(rn); xfree(cn); xfree(rn_inv); xfree(cn_inv); /* build tags of non-basic variables */ for (k = 1; k <= m+n; k++) { if (tagx[k] != LPX_BS) { if (k <= m) lpx_get_row_bnds(lp, k, &typx, &lb, &ub); else lpx_get_col_bnds(lp, k-m, &typx, &lb, &ub); switch (typx) { case LPX_FR: tagx[k] = LPX_NF; break; case LPX_LO: tagx[k] = LPX_NL; break; case LPX_UP: tagx[k] = LPX_NU; break; case LPX_DB: tagx[k] = (fabs(lb) <= fabs(ub) ? LPX_NL : LPX_NU); break; case LPX_FX: tagx[k] = LPX_NS; break; default: xassert(typx != typx); } } } for (k = 1; k <= m+n; k++) { if (k <= m) lpx_set_row_stat(lp, k, tagx[k]); else lpx_set_col_stat(lp, k-m, tagx[k]); } xfree(tagx); return; } /*********************************************************************** * NAME * * glp_adv_basis - construct advanced initial LP basis * * SYNOPSIS * * void glp_adv_basis(glp_prob *lp, int flags); * * DESCRIPTION * * The routine glp_adv_basis constructs an advanced initial basis for * the specified problem object. * * The parameter flags is reserved for use in the future and must be * specified as zero. */ void glp_adv_basis(glp_prob *lp, int flags) { if (flags != 0) xerror("glp_adv_basis: flags = %d; invalid flags\n", flags); if (lp->m == 0 || lp->n == 0) glp_std_basis(lp); else adv_basis(lp); return; } /* eof */ praat-6.0.04/external/glpk/glpini02.c000066400000000000000000000214411261542461700172710ustar00rootroot00000000000000/* glpini02.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpapi.h" struct var { /* structural variable */ int j; /* ordinal number */ double q; /* penalty value */ }; static int fcmp(const void *ptr1, const void *ptr2) { /* this routine is passed to the qsort() function */ struct var *col1 = (void *)ptr1, *col2 = (void *)ptr2; if (col1->q < col2->q) return -1; if (col1->q > col2->q) return +1; return 0; } static int get_column(glp_prob *lp, int j, int ind[], double val[]) { /* Bixby's algorithm assumes that the constraint matrix is scaled such that the maximum absolute value in every non-zero row and column is 1 */ int k, len; double big; len = glp_get_mat_col(lp, j, ind, val); big = 0.0; for (k = 1; k <= len; k++) if (big < fabs(val[k])) big = fabs(val[k]); if (big == 0.0) big = 1.0; for (k = 1; k <= len; k++) val[k] /= big; return len; } static void cpx_basis(glp_prob *lp) { /* main routine */ struct var *C, *C2, *C3, *C4; int m, n, i, j, jk, k, l, ll, t, n2, n3, n4, type, len, *I, *r, *ind; double alpha, gamma, cmax, temp, *v, *val; xprintf("Constructing initial basis...\n"); /* determine the number of rows and columns */ m = glp_get_num_rows(lp); n = glp_get_num_cols(lp); /* allocate working arrays */ C = xcalloc(1+n, sizeof(struct var)); I = xcalloc(1+m, sizeof(int)); r = xcalloc(1+m, sizeof(int)); v = xcalloc(1+m, sizeof(double)); ind = xcalloc(1+m, sizeof(int)); val = xcalloc(1+m, sizeof(double)); /* make all auxiliary variables non-basic */ for (i = 1; i <= m; i++) { if (glp_get_row_type(lp, i) != GLP_DB) glp_set_row_stat(lp, i, GLP_NS); else if (fabs(glp_get_row_lb(lp, i)) <= fabs(glp_get_row_ub(lp, i))) glp_set_row_stat(lp, i, GLP_NL); else glp_set_row_stat(lp, i, GLP_NU); } /* make all structural variables non-basic */ for (j = 1; j <= n; j++) { if (glp_get_col_type(lp, j) != GLP_DB) glp_set_col_stat(lp, j, GLP_NS); else if (fabs(glp_get_col_lb(lp, j)) <= fabs(glp_get_col_ub(lp, j))) glp_set_col_stat(lp, j, GLP_NL); else glp_set_col_stat(lp, j, GLP_NU); } /* C2 is a set of free structural variables */ n2 = 0, C2 = C + 0; for (j = 1; j <= n; j++) { type = glp_get_col_type(lp, j); if (type == GLP_FR) { n2++; C2[n2].j = j; C2[n2].q = 0.0; } } /* C3 is a set of structural variables having excatly one (lower or upper) bound */ n3 = 0, C3 = C2 + n2; for (j = 1; j <= n; j++) { type = glp_get_col_type(lp, j); if (type == GLP_LO) { n3++; C3[n3].j = j; C3[n3].q = + glp_get_col_lb(lp, j); } else if (type == GLP_UP) { n3++; C3[n3].j = j; C3[n3].q = - glp_get_col_ub(lp, j); } } /* C4 is a set of structural variables having both (lower and upper) bounds */ n4 = 0, C4 = C3 + n3; for (j = 1; j <= n; j++) { type = glp_get_col_type(lp, j); if (type == GLP_DB) { n4++; C4[n4].j = j; C4[n4].q = glp_get_col_lb(lp, j) - glp_get_col_ub(lp, j); } } /* compute gamma = max{|c[j]|: 1 <= j <= n} */ gamma = 0.0; for (j = 1; j <= n; j++) { temp = fabs(glp_get_obj_coef(lp, j)); if (gamma < temp) gamma = temp; } /* compute cmax */ cmax = (gamma == 0.0 ? 1.0 : 1000.0 * gamma); /* compute final penalty for all structural variables within sets C2, C3, and C4 */ switch (glp_get_obj_dir(lp)) { case GLP_MIN: temp = +1.0; break; case GLP_MAX: temp = -1.0; break; default: xassert(lp != lp); } for (k = 1; k <= n2+n3+n4; k++) { j = C[k].j; C[k].q += (temp * glp_get_obj_coef(lp, j)) / cmax; } /* sort structural variables within C2, C3, and C4 in ascending order of penalty value */ qsort(C2+1, n2, sizeof(struct var), fcmp); for (k = 1; k < n2; k++) xassert(C2[k].q <= C2[k+1].q); qsort(C3+1, n3, sizeof(struct var), fcmp); for (k = 1; k < n3; k++) xassert(C3[k].q <= C3[k+1].q); qsort(C4+1, n4, sizeof(struct var), fcmp); for (k = 1; k < n4; k++) xassert(C4[k].q <= C4[k+1].q); /*** STEP 1 ***/ for (i = 1; i <= m; i++) { type = glp_get_row_type(lp, i); if (type != GLP_FX) { /* row i is either free or inequality constraint */ glp_set_row_stat(lp, i, GLP_BS); I[i] = 1; r[i] = 1; } else { /* row i is equality constraint */ I[i] = 0; r[i] = 0; } v[i] = +DBL_MAX; } /*** STEP 2 ***/ for (k = 1; k <= n2+n3+n4; k++) { jk = C[k].j; len = get_column(lp, jk, ind, val); /* let alpha = max{|A[l,jk]|: r[l] = 0} and let l' be such that alpha = |A[l',jk]| */ alpha = 0.0, ll = 0; for (t = 1; t <= len; t++) { l = ind[t]; if (r[l] == 0 && alpha < fabs(val[t])) alpha = fabs(val[t]), ll = l; } if (alpha >= 0.99) { /* B := B union {jk} */ glp_set_col_stat(lp, jk, GLP_BS); I[ll] = 1; v[ll] = alpha; /* r[l] := r[l] + 1 for all l such that |A[l,jk]| != 0 */ for (t = 1; t <= len; t++) { l = ind[t]; if (val[t] != 0.0) r[l]++; } /* continue to the next k */ continue; } /* if |A[l,jk]| > 0.01 * v[l] for some l, continue to the next k */ for (t = 1; t <= len; t++) { l = ind[t]; if (fabs(val[t]) > 0.01 * v[l]) break; } if (t <= len) continue; /* otherwise, let alpha = max{|A[l,jk]|: I[l] = 0} and let l' be such that alpha = |A[l',jk]| */ alpha = 0.0, ll = 0; for (t = 1; t <= len; t++) { l = ind[t]; if (I[l] == 0 && alpha < fabs(val[t])) alpha = fabs(val[t]), ll = l; } /* if alpha = 0, continue to the next k */ if (alpha == 0.0) continue; /* B := B union {jk} */ glp_set_col_stat(lp, jk, GLP_BS); I[ll] = 1; v[ll] = alpha; /* r[l] := r[l] + 1 for all l such that |A[l,jk]| != 0 */ for (t = 1; t <= len; t++) { l = ind[t]; if (val[t] != 0.0) r[l]++; } } /*** STEP 3 ***/ /* add an artificial variable (auxiliary variable for equality constraint) to cover each remaining uncovered row */ for (i = 1; i <= m; i++) if (I[i] == 0) glp_set_row_stat(lp, i, GLP_BS); /* free working arrays */ xfree(C); xfree(I); xfree(r); xfree(v); xfree(ind); xfree(val); return; } /*********************************************************************** * NAME * * glp_cpx_basis - construct Bixby's initial LP basis * * SYNOPSIS * * void glp_cpx_basis(glp_prob *lp); * * DESCRIPTION * * The routine glp_cpx_basis constructs an advanced initial basis for * the specified problem object. * * The routine is based on Bixby's algorithm described in the paper: * * Robert E. Bixby. Implementing the Simplex Method: The Initial Basis. * ORSA Journal on Computing, Vol. 4, No. 3, 1992, pp. 267-84. */ void glp_cpx_basis(glp_prob *lp) { if (lp->m == 0 || lp->n == 0) glp_std_basis(lp); else cpx_basis(lp); return; } /* eof */ praat-6.0.04/external/glpk/glpios.h000066400000000000000000000535661261542461700171640ustar00rootroot00000000000000/* glpios.h (integer optimization suite) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPIOS_H #define GLPIOS_H #define GLP_TREE_DEFINED typedef struct glp_tree glp_tree; #include "glpapi.h" typedef struct IOSLOT IOSLOT; typedef struct IOSNPD IOSNPD; typedef struct IOSBND IOSBND; typedef struct IOSTAT IOSTAT; typedef struct IOSROW IOSROW; typedef struct IOSAIJ IOSAIJ; typedef struct IOSPOOL IOSPOOL; typedef struct IOSCUT IOSCUT; struct glp_tree { /* branch-and-bound tree */ int magic; /* magic value used for debugging */ DMP *pool; /* memory pool to store all IOS components */ int n; /* number of columns (variables) */ /*--------------------------------------------------------------*/ /* problem components corresponding to the original MIP and its LP relaxation (used to restore the original problem object on exit from the solver) */ int orig_m; /* number of rows */ unsigned char *orig_type; /* uchar orig_type[1+orig_m+n]; */ /* types of all variables */ double *orig_lb; /* double orig_lb[1+orig_m+n]; */ /* lower bounds of all variables */ double *orig_ub; /* double orig_ub[1+orig_m+n]; */ /* upper bounds of all variables */ unsigned char *orig_stat; /* uchar orig_stat[1+orig_m+n]; */ /* statuses of all variables */ double *orig_prim; /* double orig_prim[1+orig_m+n]; */ /* primal values of all variables */ double *orig_dual; /* double orig_dual[1+orig_m+n]; */ /* dual values of all variables */ double orig_obj; /* optimal objective value for LP relaxation */ /*--------------------------------------------------------------*/ /* branch-and-bound tree */ int nslots; /* length of the array of slots (enlarged automatically) */ int avail; /* index of the first free slot; 0 means all slots are in use */ IOSLOT *slot; /* IOSLOT slot[1+nslots]; */ /* array of slots: slot[0] is not used; slot[p], 1 <= p <= nslots, either contains a pointer to some node of the branch-and-bound tree, in which case p is used on API level as the reference number of corresponding subproblem, or is free; all free slots are linked into single linked list; slot[1] always contains a pointer to the root node (it is free only if the tree is empty) */ IOSNPD *head; /* pointer to the head of the active list */ IOSNPD *tail; /* pointer to the tail of the active list */ /* the active list is a doubly linked list of active subproblems which correspond to leaves of the tree; all subproblems in the active list are ordered chronologically (each a new subproblem is always added to the tail of the list) */ int a_cnt; /* current number of active nodes (including the current one) */ int n_cnt; /* current number of all (active and inactive) nodes */ int t_cnt; /* total number of nodes including those which have been already removed from the tree; this count is increased by one whenever a new node is created and never decreased */ /*--------------------------------------------------------------*/ /* problem components corresponding to the root subproblem */ int root_m; /* number of rows */ unsigned char *root_type; /* uchar root_type[1+root_m+n]; */ /* types of all variables */ double *root_lb; /* double root_lb[1+root_m+n]; */ /* lower bounds of all variables */ double *root_ub; /* double root_ub[1+root_m+n]; */ /* upper bounds of all variables */ unsigned char *root_stat; /* uchar root_stat[1+root_m+n]; */ /* statuses of all variables */ /*--------------------------------------------------------------*/ /* current subproblem and its LP relaxation */ IOSNPD *curr; /* pointer to the current subproblem (which can be only active); NULL means the current subproblem does not exist */ glp_prob *mip; /* original problem object passed to the solver; if the current subproblem exists, its LP segment corresponds to LP relaxation of the current subproblem; if the current subproblem does not exist, its LP segment corresponds to LP relaxation of the root subproblem (note that the root subproblem may differ from the original MIP, because it may be preprocessed and/or may have additional rows) */ unsigned char *non_int; /* uchar non_int[1+n]; */ /* these column flags are set each time when LP relaxation of the current subproblem has been solved; non_int[0] is not used; non_int[j], 1 <= j <= n, is j-th column flag; if this flag is set, corresponding variable is required to be integer, but its value in basic solution is fractional */ /*--------------------------------------------------------------*/ /* problem components corresponding to the parent (predecessor) subproblem for the current subproblem; used to inspect changes on freezing the current subproblem */ int pred_m; /* number of rows */ int pred_max; /* length of the following four arrays (enlarged automatically), pred_max >= pred_m + n */ unsigned char *pred_type; /* uchar pred_type[1+pred_m+n]; */ /* types of all variables */ double *pred_lb; /* double pred_lb[1+pred_m+n]; */ /* lower bounds of all variables */ double *pred_ub; /* double pred_ub[1+pred_m+n]; */ /* upper bounds of all variables */ unsigned char *pred_stat; /* uchar pred_stat[1+pred_m+n]; */ /* statuses of all variables */ /****************************************************************/ /* built-in cut generators segment */ IOSPOOL *local; /* local cut pool */ void *mir_gen; /* pointer to working area used by the MIR cut generator */ void *clq_gen; /* pointer to working area used by the clique cut generator */ /*--------------------------------------------------------------*/ void *pcost; /* pointer to working area used on pseudocost branching */ int *iwrk; /* int iwrk[1+n]; */ /* working array */ double *dwrk; /* double dwrk[1+n]; */ /* working array */ /*--------------------------------------------------------------*/ /* control parameters and statistics */ const glp_iocp *parm; /* copy of control parameters passed to the solver */ glp_long tm_beg; /* starting time of the search, in seconds; the total time of the search is the difference between xtime() and tm_beg */ glp_long tm_lag; /* the most recent time, in seconds, at which the progress of the the search was displayed */ int sol_cnt; /* number of integer feasible solutions found */ /*--------------------------------------------------------------*/ /* advanced solver interface */ int reason; /* flag indicating the reason why the callback routine is being called (see glpk.h) */ int stop; /* flag indicating that the callback routine requires premature termination of the search */ int next_p; /* reference number of active subproblem selected to continue the search; 0 means no subproblem has been selected */ int reopt; /* flag indicating that the current LP relaxation needs to be re-optimized */ int reinv; /* flag indicating that some (non-active) rows were removed from the current LP relaxation, so if there no new rows appear, the basis must be re-factorized */ int br_var; /* the number of variable chosen to branch on */ int br_sel; /* flag indicating which branch (subproblem) is suggested to be selected to continue the search: GLP_DN_BRNCH - select down-branch GLP_UP_BRNCH - select up-branch GLP_NO_BRNCH - use general selection technique */ int child; /* subproblem reference number corresponding to br_sel */ }; struct IOSLOT { /* node subproblem slot */ IOSNPD *node; /* pointer to subproblem descriptor; NULL means free slot */ int next; /* index of another free slot (only if this slot is free) */ }; struct IOSNPD { /* node subproblem descriptor */ int p; /* subproblem reference number (it is the index to corresponding slot, i.e. slot[p] points to this descriptor) */ IOSNPD *up; /* pointer to the parent subproblem; NULL means this node is the root of the tree, in which case p = 1 */ int level; /* node level (the root node has level 0) */ int count; /* if count = 0, this subproblem is active; if count > 0, this subproblem is inactive, in which case count is the number of its child subproblems */ /* the following three linked lists are destroyed on reviving and built anew on freezing the subproblem: */ IOSBND *b_ptr; /* linked list of rows and columns of the parent subproblem whose types and bounds were changed */ IOSTAT *s_ptr; /* linked list of rows and columns of the parent subproblem whose statuses were changed */ IOSROW *r_ptr; /* linked list of rows (cuts) added to the parent subproblem */ int solved; /* how many times LP relaxation of this subproblem was solved; for inactive subproblem this count is always non-zero; for active subproblem, which is not current, this count may be non-zero, if the subproblem was temporarily suspended */ double lp_obj; /* optimal objective value to LP relaxation of this subproblem; on creating a subproblem this value is inherited from its parent; for the root subproblem, which has no parent, this value is initially set to -DBL_MAX (minimization) or +DBL_MAX (maximization); each time the subproblem is re-optimized, this value is appropriately changed */ double bound; /* local lower (minimization) or upper (maximization) bound for integer optimal solution to *this* subproblem; this bound is local in the sense that only subproblems in the subtree rooted at this node cannot have better integer feasible solutions; on creating a subproblem its local bound is inherited from its parent and then can be made stronger (never weaker); for the root subproblem its local bound is initially set to -DBL_MAX (minimization) or +DBL_MAX (maximization) and then improved as the root LP relaxation has been solved */ /* the following two quantities are defined only if LP relaxation of this subproblem was solved at least once (solved > 0): */ int ii_cnt; /* number of integer variables whose value in optimal solution to LP relaxation of this subproblem is fractional */ double ii_sum; /* sum of integer infeasibilities */ #if 1 /* 30/XI-2009 */ int changed; /* how many times this subproblem was re-formulated (by adding cutting plane constraints) */ #endif int br_var; /* ordinal number of branching variable, 1 <= br_var <= n, used to split this subproblem; 0 means that either this subproblem is active or branching was made on a constraint */ double br_val; /* (fractional) value of branching variable in optimal solution to final LP relaxation of this subproblem */ void *data; /* char data[tree->cb_size]; */ /* pointer to the application-specific data */ IOSNPD *temp; /* working pointer used by some routines */ IOSNPD *prev; /* pointer to previous subproblem in the active list */ IOSNPD *next; /* pointer to next subproblem in the active list */ }; struct IOSBND { /* bounds change entry */ int k; /* ordinal number of corresponding row (1 <= k <= m) or column (m+1 <= k <= m+n), where m and n are the number of rows and columns, resp., in the parent subproblem */ unsigned char type; /* new type */ double lb; /* new lower bound */ double ub; /* new upper bound */ IOSBND *next; /* pointer to next entry for the same subproblem */ }; struct IOSTAT { /* status change entry */ int k; /* ordinal number of corresponding row (1 <= k <= m) or column (m+1 <= k <= m+n), where m and n are the number of rows and columns, resp., in the parent subproblem */ unsigned char stat; /* new status */ IOSTAT *next; /* pointer to next entry for the same subproblem */ }; struct IOSROW { /* row (constraint) addition entry */ char *name; /* row name or NULL */ unsigned char origin; /* row origin flag (see glp_attr.origin) */ unsigned char klass; /* row class descriptor (see glp_attr.klass) */ unsigned char type; /* row type (GLP_LO, GLP_UP, etc.) */ double lb; /* row lower bound */ double ub; /* row upper bound */ IOSAIJ *ptr; /* pointer to the row coefficient list */ double rii; /* row scale factor */ unsigned char stat; /* row status (GLP_BS, GLP_NL, etc.) */ IOSROW *next; /* pointer to next entry for the same subproblem */ }; struct IOSAIJ { /* constraint coefficient */ int j; /* variable (column) number, 1 <= j <= n */ double val; /* non-zero coefficient value */ IOSAIJ *next; /* pointer to next coefficient for the same row */ }; struct IOSPOOL { /* cut pool */ int size; /* pool size = number of cuts in the pool */ IOSCUT *head; /* pointer to the first cut */ IOSCUT *tail; /* pointer to the last cut */ int ord; /* ordinal number of the current cut, 1 <= ord <= size */ IOSCUT *curr; /* pointer to the current cut */ }; struct IOSCUT { /* cut (cutting plane constraint) */ char *name; /* cut name or NULL */ unsigned char klass; /* cut class descriptor (see glp_attr.klass) */ IOSAIJ *ptr; /* pointer to the cut coefficient list */ unsigned char type; /* cut type: GLP_LO: sum a[j] * x[j] >= b GLP_UP: sum a[j] * x[j] <= b GLP_FX: sum a[j] * x[j] = b */ double rhs; /* cut right-hand side */ IOSCUT *prev; /* pointer to previous cut */ IOSCUT *next; /* pointer to next cut */ }; #define ios_create_tree _glp_ios_create_tree glp_tree *ios_create_tree(glp_prob *mip, const glp_iocp *parm); /* create branch-and-bound tree */ #define ios_revive_node _glp_ios_revive_node void ios_revive_node(glp_tree *tree, int p); /* revive specified subproblem */ #define ios_freeze_node _glp_ios_freeze_node void ios_freeze_node(glp_tree *tree); /* freeze current subproblem */ #define ios_clone_node _glp_ios_clone_node void ios_clone_node(glp_tree *tree, int p, int nnn, int ref[]); /* clone specified subproblem */ #define ios_delete_node _glp_ios_delete_node void ios_delete_node(glp_tree *tree, int p); /* delete specified subproblem */ #define ios_delete_tree _glp_ios_delete_tree void ios_delete_tree(glp_tree *tree); /* delete branch-and-bound tree */ #define ios_eval_degrad _glp_ios_eval_degrad void ios_eval_degrad(glp_tree *tree, int j, double *dn, double *up); /* estimate obj. degrad. for down- and up-branches */ #define ios_round_bound _glp_ios_round_bound double ios_round_bound(glp_tree *tree, double bound); /* improve local bound by rounding */ #define ios_is_hopeful _glp_ios_is_hopeful int ios_is_hopeful(glp_tree *tree, double bound); /* check if subproblem is hopeful */ #define ios_best_node _glp_ios_best_node int ios_best_node(glp_tree *tree); /* find active node with best local bound */ #define ios_relative_gap _glp_ios_relative_gap double ios_relative_gap(glp_tree *tree); /* compute relative mip gap */ #define ios_solve_node _glp_ios_solve_node int ios_solve_node(glp_tree *tree); /* solve LP relaxation of current subproblem */ #define ios_create_pool _glp_ios_create_pool IOSPOOL *ios_create_pool(glp_tree *tree); /* create cut pool */ #define ios_add_row _glp_ios_add_row int ios_add_row(glp_tree *tree, IOSPOOL *pool, const char *name, int klass, int flags, int len, const int ind[], const double val[], int type, double rhs); /* add row (constraint) to the cut pool */ #define ios_find_row _glp_ios_find_row IOSCUT *ios_find_row(IOSPOOL *pool, int i); /* find row (constraint) in the cut pool */ #define ios_del_row _glp_ios_del_row void ios_del_row(glp_tree *tree, IOSPOOL *pool, int i); /* remove row (constraint) from the cut pool */ #define ios_clear_pool _glp_ios_clear_pool void ios_clear_pool(glp_tree *tree, IOSPOOL *pool); /* remove all rows (constraints) from the cut pool */ #define ios_delete_pool _glp_ios_delete_pool void ios_delete_pool(glp_tree *tree, IOSPOOL *pool); /* delete cut pool */ #define ios_preprocess_node _glp_ios_preprocess_node int ios_preprocess_node(glp_tree *tree, int max_pass); /* preprocess current subproblem */ #define ios_driver _glp_ios_driver int ios_driver(glp_tree *tree); /* branch-and-bound driver */ /**********************************************************************/ typedef struct IOSVEC IOSVEC; struct IOSVEC { /* sparse vector v = (v[j]) */ int n; /* dimension, n >= 0 */ int nnz; /* number of non-zero components, 0 <= nnz <= n */ int *pos; /* int pos[1+n]; */ /* pos[j] = k, 1 <= j <= n, is position of (non-zero) v[j] in the arrays ind and val, where 1 <= k <= nnz; pos[j] = 0 means that v[j] is structural zero */ int *ind; /* int ind[1+n]; */ /* ind[k] = j, 1 <= k <= nnz, is index of v[j] */ double *val; /* double val[1+n]; */ /* val[k], 1 <= k <= nnz, is a numeric value of v[j] */ }; #define ios_create_vec _glp_ios_create_vec IOSVEC *ios_create_vec(int n); /* create sparse vector */ #define ios_check_vec _glp_ios_check_vec void ios_check_vec(IOSVEC *v); /* check that sparse vector has correct representation */ #define ios_get_vj _glp_ios_get_vj double ios_get_vj(IOSVEC *v, int j); /* retrieve component of sparse vector */ #define ios_set_vj _glp_ios_set_vj void ios_set_vj(IOSVEC *v, int j, double val); /* set/change component of sparse vector */ #define ios_clear_vec _glp_ios_clear_vec void ios_clear_vec(IOSVEC *v); /* set all components of sparse vector to zero */ #define ios_clean_vec _glp_ios_clean_vec void ios_clean_vec(IOSVEC *v, double eps); /* remove zero or small components from sparse vector */ #define ios_copy_vec _glp_ios_copy_vec void ios_copy_vec(IOSVEC *x, IOSVEC *y); /* copy sparse vector (x := y) */ #define ios_linear_comb _glp_ios_linear_comb void ios_linear_comb(IOSVEC *x, double a, IOSVEC *y); /* compute linear combination (x := x + a * y) */ #define ios_delete_vec _glp_ios_delete_vec void ios_delete_vec(IOSVEC *v); /* delete sparse vector */ /**********************************************************************/ #define ios_gmi_gen _glp_ios_gmi_gen void ios_gmi_gen(glp_tree *tree); /* generate Gomory's mixed integer cuts */ #define ios_mir_init _glp_ios_mir_init void *ios_mir_init(glp_tree *tree); /* initialize MIR cut generator */ #define ios_mir_gen _glp_ios_mir_gen void ios_mir_gen(glp_tree *tree, void *gen); /* generate MIR cuts */ #define ios_mir_term _glp_ios_mir_term void ios_mir_term(void *gen); /* terminate MIR cut generator */ #define ios_cov_gen _glp_ios_cov_gen void ios_cov_gen(glp_tree *tree); /* generate mixed cover cuts */ #define ios_clq_init _glp_ios_clq_init void *ios_clq_init(glp_tree *tree); /* initialize clique cut generator */ #define ios_clq_gen _glp_ios_clq_gen void ios_clq_gen(glp_tree *tree, void *gen); /* generate clique cuts */ #define ios_clq_term _glp_ios_clq_term void ios_clq_term(void *gen); /* terminate clique cut generator */ #define ios_pcost_init _glp_ios_pcost_init void *ios_pcost_init(glp_tree *tree); /* initialize working data used on pseudocost branching */ #define ios_pcost_branch _glp_ios_pcost_branch int ios_pcost_branch(glp_tree *T, int *next); /* choose branching variable with pseudocost branching */ #define ios_pcost_update _glp_ios_pcost_update void ios_pcost_update(glp_tree *tree); /* update history information for pseudocost branching */ #define ios_pcost_free _glp_ios_pcost_free void ios_pcost_free(glp_tree *tree); /* free working area used on pseudocost branching */ #define ios_feas_pump _glp_ios_feas_pump void ios_feas_pump(glp_tree *T); /* feasibility pump heuristic */ #define ios_process_cuts _glp_ios_process_cuts void ios_process_cuts(glp_tree *T); /* process cuts stored in the local cut pool */ #define ios_choose_node _glp_ios_choose_node int ios_choose_node(glp_tree *T); /* select subproblem to continue the search */ #define ios_choose_var _glp_ios_choose_var int ios_choose_var(glp_tree *T, int *next); /* select variable to branch on */ #endif /* eof */ praat-6.0.04/external/glpk/glpios01.c000066400000000000000000001501241261542461700173040ustar00rootroot00000000000000/* glpios01.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpios.h" /*********************************************************************** * NAME * * ios_create_tree - create branch-and-bound tree * * SYNOPSIS * * #include "glpios.h" * glp_tree *ios_create_tree(glp_prob *mip, const glp_iocp *parm); * * DESCRIPTION * * The routine ios_create_tree creates the branch-and-bound tree. * * Being created the tree consists of the only root subproblem whose * reference number is 1. Note that initially the root subproblem is in * frozen state and therefore needs to be revived. * * RETURNS * * The routine returns a pointer to the tree created. */ static IOSNPD *new_node(glp_tree *tree, IOSNPD *parent); glp_tree *ios_create_tree(glp_prob *mip, const glp_iocp *parm) { int m = mip->m; int n = mip->n; glp_tree *tree; int i, j; xassert(mip->tree == NULL); mip->tree = tree = xmalloc(sizeof(glp_tree)); tree->pool = dmp_create_pool(); tree->n = n; /* save original problem components */ tree->orig_m = m; tree->orig_type = xcalloc(1+m+n, sizeof(char)); tree->orig_lb = xcalloc(1+m+n, sizeof(double)); tree->orig_ub = xcalloc(1+m+n, sizeof(double)); tree->orig_stat = xcalloc(1+m+n, sizeof(char)); tree->orig_prim = xcalloc(1+m+n, sizeof(double)); tree->orig_dual = xcalloc(1+m+n, sizeof(double)); for (i = 1; i <= m; i++) { GLPROW *row = mip->row[i]; tree->orig_type[i] = (char)row->type; tree->orig_lb[i] = row->lb; tree->orig_ub[i] = row->ub; tree->orig_stat[i] = (char)row->stat; tree->orig_prim[i] = row->prim; tree->orig_dual[i] = row->dual; } for (j = 1; j <= n; j++) { GLPCOL *col = mip->col[j]; tree->orig_type[m+j] = (char)col->type; tree->orig_lb[m+j] = col->lb; tree->orig_ub[m+j] = col->ub; tree->orig_stat[m+j] = (char)col->stat; tree->orig_prim[m+j] = col->prim; tree->orig_dual[m+j] = col->dual; } tree->orig_obj = mip->obj_val; /* initialize the branch-and-bound tree */ tree->nslots = 0; tree->avail = 0; tree->slot = NULL; tree->head = tree->tail = NULL; tree->a_cnt = tree->n_cnt = tree->t_cnt = 0; /* the root subproblem is not solved yet, so its final components are unknown so far */ tree->root_m = 0; tree->root_type = NULL; tree->root_lb = tree->root_ub = NULL; tree->root_stat = NULL; /* the current subproblem does not exist yet */ tree->curr = NULL; tree->mip = mip; /*tree->solved = 0;*/ tree->non_int = xcalloc(1+n, sizeof(char)); memset(&tree->non_int[1], 0, n); /* arrays to save parent subproblem components will be allocated later */ tree->pred_m = tree->pred_max = 0; tree->pred_type = NULL; tree->pred_lb = tree->pred_ub = NULL; tree->pred_stat = NULL; /* cut generator */ tree->local = ios_create_pool(tree); /*tree->first_attempt = 1;*/ /*tree->max_added_cuts = 0;*/ /*tree->min_eff = 0.0;*/ /*tree->miss = 0;*/ /*tree->just_selected = 0;*/ tree->mir_gen = NULL; tree->clq_gen = NULL; /*tree->round = 0;*/ #if 0 /* create the conflict graph */ tree->n_ref = xcalloc(1+n, sizeof(int)); memset(&tree->n_ref[1], 0, n * sizeof(int)); tree->c_ref = xcalloc(1+n, sizeof(int)); memset(&tree->c_ref[1], 0, n * sizeof(int)); tree->g = scg_create_graph(0); tree->j_ref = xcalloc(1+tree->g->n_max, sizeof(int)); #endif /* pseudocost branching */ tree->pcost = NULL; tree->iwrk = xcalloc(1+n, sizeof(int)); tree->dwrk = xcalloc(1+n, sizeof(double)); /* initialize control parameters */ tree->parm = parm; tree->tm_beg = xtime(); tree->tm_lag = xlset(0); tree->sol_cnt = 0; /* initialize advanced solver interface */ tree->reason = 0; tree->reopt = 0; tree->reinv = 0; tree->br_var = 0; tree->br_sel = 0; tree->child = 0; tree->next_p = 0; /*tree->btrack = NULL;*/ tree->stop = 0; /* create the root subproblem, which initially is identical to the original MIP */ new_node(tree, NULL); return tree; } /*********************************************************************** * NAME * * ios_revive_node - revive specified subproblem * * SYNOPSIS * * #include "glpios.h" * void ios_revive_node(glp_tree *tree, int p); * * DESCRIPTION * * The routine ios_revive_node revives the specified subproblem, whose * reference number is p, and thereby makes it the current subproblem. * Note that the specified subproblem must be active. Besides, if the * current subproblem already exists, it must be frozen before reviving * another subproblem. */ void ios_revive_node(glp_tree *tree, int p) { glp_prob *mip = tree->mip; IOSNPD *node, *root; /* obtain pointer to the specified subproblem */ xassert(1 <= p && p <= tree->nslots); node = tree->slot[p].node; xassert(node != NULL); /* the specified subproblem must be active */ xassert(node->count == 0); /* the current subproblem must not exist */ xassert(tree->curr == NULL); /* the specified subproblem becomes current */ tree->curr = node; /*tree->solved = 0;*/ /* obtain pointer to the root subproblem */ root = tree->slot[1].node; xassert(root != NULL); /* at this point problem object components correspond to the root subproblem, so if the root subproblem should be revived, there is nothing more to do */ if (node == root) goto done; xassert(mip->m == tree->root_m); /* build path from the root to the current node */ node->temp = NULL; for (node = node; node != NULL; node = node->up) { if (node->up == NULL) xassert(node == root); else node->up->temp = node; } /* go down from the root to the current node and make necessary changes to restore components of the current subproblem */ for (node = root; node != NULL; node = node->temp) { int m = mip->m; int n = mip->n; /* if the current node is reached, the problem object at this point corresponds to its parent, so save attributes of rows and columns for the parent subproblem */ if (node->temp == NULL) { int i, j; tree->pred_m = m; /* allocate/reallocate arrays, if necessary */ if (tree->pred_max < m + n) { int new_size = m + n + 100; if (tree->pred_type != NULL) xfree(tree->pred_type); if (tree->pred_lb != NULL) xfree(tree->pred_lb); if (tree->pred_ub != NULL) xfree(tree->pred_ub); if (tree->pred_stat != NULL) xfree(tree->pred_stat); tree->pred_max = new_size; tree->pred_type = xcalloc(1+new_size, sizeof(char)); tree->pred_lb = xcalloc(1+new_size, sizeof(double)); tree->pred_ub = xcalloc(1+new_size, sizeof(double)); tree->pred_stat = xcalloc(1+new_size, sizeof(char)); } /* save row attributes */ for (i = 1; i <= m; i++) { GLPROW *row = mip->row[i]; tree->pred_type[i] = (char)row->type; tree->pred_lb[i] = row->lb; tree->pred_ub[i] = row->ub; tree->pred_stat[i] = (char)row->stat; } /* save column attributes */ for (j = 1; j <= n; j++) { GLPCOL *col = mip->col[j]; tree->pred_type[mip->m+j] = (char)col->type; tree->pred_lb[mip->m+j] = col->lb; tree->pred_ub[mip->m+j] = col->ub; tree->pred_stat[mip->m+j] = (char)col->stat; } } /* change bounds of rows and columns */ { IOSBND *b; for (b = node->b_ptr; b != NULL; b = b->next) { if (b->k <= m) glp_set_row_bnds(mip, b->k, b->type, b->lb, b->ub); else glp_set_col_bnds(mip, b->k-m, b->type, b->lb, b->ub); } } /* change statuses of rows and columns */ { IOSTAT *s; for (s = node->s_ptr; s != NULL; s = s->next) { if (s->k <= m) glp_set_row_stat(mip, s->k, s->stat); else glp_set_col_stat(mip, s->k-m, s->stat); } } /* add new rows */ if (node->r_ptr != NULL) { IOSROW *r; IOSAIJ *a; int i, len, *ind; double *val; ind = xcalloc(1+n, sizeof(int)); val = xcalloc(1+n, sizeof(double)); for (r = node->r_ptr; r != NULL; r = r->next) { i = glp_add_rows(mip, 1); glp_set_row_name(mip, i, r->name); #if 1 /* 20/IX-2008 */ xassert(mip->row[i]->level == 0); mip->row[i]->level = node->level; mip->row[i]->origin = r->origin; mip->row[i]->klass = r->klass; #endif glp_set_row_bnds(mip, i, r->type, r->lb, r->ub); len = 0; for (a = r->ptr; a != NULL; a = a->next) len++, ind[len] = a->j, val[len] = a->val; glp_set_mat_row(mip, i, len, ind, val); glp_set_rii(mip, i, r->rii); glp_set_row_stat(mip, i, r->stat); } xfree(ind); xfree(val); } #if 0 /* add new edges to the conflict graph */ /* add new cliques to the conflict graph */ /* (not implemented yet) */ xassert(node->own_nn == 0); xassert(node->own_nc == 0); xassert(node->e_ptr == NULL); #endif } /* the specified subproblem has been revived */ node = tree->curr; /* delete its bound change list */ while (node->b_ptr != NULL) { IOSBND *b; b = node->b_ptr; node->b_ptr = b->next; dmp_free_atom(tree->pool, b, sizeof(IOSBND)); } /* delete its status change list */ while (node->s_ptr != NULL) { IOSTAT *s; s = node->s_ptr; node->s_ptr = s->next; dmp_free_atom(tree->pool, s, sizeof(IOSTAT)); } #if 1 /* 20/XI-2009 */ /* delete its row addition list (additional rows may appear, for example, due to branching on GUB constraints */ while (node->r_ptr != NULL) { IOSROW *r; r = node->r_ptr; node->r_ptr = r->next; xassert(r->name == NULL); while (r->ptr != NULL) { IOSAIJ *a; a = r->ptr; r->ptr = a->next; dmp_free_atom(tree->pool, a, sizeof(IOSAIJ)); } dmp_free_atom(tree->pool, r, sizeof(IOSROW)); } #endif done: return; } /*********************************************************************** * NAME * * ios_freeze_node - freeze current subproblem * * SYNOPSIS * * #include "glpios.h" * void ios_freeze_node(glp_tree *tree); * * DESCRIPTION * * The routine ios_freeze_node freezes the current subproblem. */ void ios_freeze_node(glp_tree *tree) { glp_prob *mip = tree->mip; int m = mip->m; int n = mip->n; IOSNPD *node; /* obtain pointer to the current subproblem */ node = tree->curr; xassert(node != NULL); if (node->up == NULL) { /* freeze the root subproblem */ int k; xassert(node->p == 1); xassert(tree->root_m == 0); xassert(tree->root_type == NULL); xassert(tree->root_lb == NULL); xassert(tree->root_ub == NULL); xassert(tree->root_stat == NULL); tree->root_m = m; tree->root_type = xcalloc(1+m+n, sizeof(char)); tree->root_lb = xcalloc(1+m+n, sizeof(double)); tree->root_ub = xcalloc(1+m+n, sizeof(double)); tree->root_stat = xcalloc(1+m+n, sizeof(char)); for (k = 1; k <= m+n; k++) { if (k <= m) { GLPROW *row = mip->row[k]; tree->root_type[k] = (char)row->type; tree->root_lb[k] = row->lb; tree->root_ub[k] = row->ub; tree->root_stat[k] = (char)row->stat; } else { GLPCOL *col = mip->col[k-m]; tree->root_type[k] = (char)col->type; tree->root_lb[k] = col->lb; tree->root_ub[k] = col->ub; tree->root_stat[k] = (char)col->stat; } } } else { /* freeze non-root subproblem */ int root_m = tree->root_m; int pred_m = tree->pred_m; int i, j, k; xassert(pred_m <= m); /* build change lists for rows and columns which exist in the parent subproblem */ xassert(node->b_ptr == NULL); xassert(node->s_ptr == NULL); for (k = 1; k <= pred_m + n; k++) { int pred_type, pred_stat, type, stat; double pred_lb, pred_ub, lb, ub; /* determine attributes in the parent subproblem */ pred_type = tree->pred_type[k]; pred_lb = tree->pred_lb[k]; pred_ub = tree->pred_ub[k]; pred_stat = tree->pred_stat[k]; /* determine attributes in the current subproblem */ if (k <= pred_m) { GLPROW *row = mip->row[k]; type = row->type; lb = row->lb; ub = row->ub; stat = row->stat; } else { GLPCOL *col = mip->col[k - pred_m]; type = col->type; lb = col->lb; ub = col->ub; stat = col->stat; } /* save type and bounds of a row/column, if changed */ if (!(pred_type == type && pred_lb == lb && pred_ub == ub)) { IOSBND *b; b = dmp_get_atom(tree->pool, sizeof(IOSBND)); b->k = k; b->type = (unsigned char)type; b->lb = lb; b->ub = ub; b->next = node->b_ptr; node->b_ptr = b; } /* save status of a row/column, if changed */ if (pred_stat != stat) { IOSTAT *s; s = dmp_get_atom(tree->pool, sizeof(IOSTAT)); s->k = k; s->stat = (unsigned char)stat; s->next = node->s_ptr; node->s_ptr = s; } } /* save new rows added to the current subproblem */ xassert(node->r_ptr == NULL); if (pred_m < m) { int i, len, *ind; double *val; ind = xcalloc(1+n, sizeof(int)); val = xcalloc(1+n, sizeof(double)); for (i = m; i > pred_m; i--) { GLPROW *row = mip->row[i]; IOSROW *r; const char *name; r = dmp_get_atom(tree->pool, sizeof(IOSROW)); name = glp_get_row_name(mip, i); if (name == NULL) r->name = NULL; else { r->name = dmp_get_atom(tree->pool, strlen(name)+1); strcpy(r->name, name); } #if 1 /* 20/IX-2008 */ r->origin = row->origin; r->klass = row->klass; #endif r->type = (unsigned char)row->type; r->lb = row->lb; r->ub = row->ub; r->ptr = NULL; len = glp_get_mat_row(mip, i, ind, val); for (k = 1; k <= len; k++) { IOSAIJ *a; a = dmp_get_atom(tree->pool, sizeof(IOSAIJ)); a->j = ind[k]; a->val = val[k]; a->next = r->ptr; r->ptr = a; } r->rii = row->rii; r->stat = (unsigned char)row->stat; r->next = node->r_ptr; node->r_ptr = r; } xfree(ind); xfree(val); } /* remove all rows missing in the root subproblem */ if (m != root_m) { int nrs, *num; nrs = m - root_m; xassert(nrs > 0); num = xcalloc(1+nrs, sizeof(int)); for (i = 1; i <= nrs; i++) num[i] = root_m + i; glp_del_rows(mip, nrs, num); xfree(num); } m = mip->m; /* and restore attributes of all rows and columns for the root subproblem */ xassert(m == root_m); for (i = 1; i <= m; i++) { glp_set_row_bnds(mip, i, tree->root_type[i], tree->root_lb[i], tree->root_ub[i]); glp_set_row_stat(mip, i, tree->root_stat[i]); } for (j = 1; j <= n; j++) { glp_set_col_bnds(mip, j, tree->root_type[m+j], tree->root_lb[m+j], tree->root_ub[m+j]); glp_set_col_stat(mip, j, tree->root_stat[m+j]); } #if 1 /* remove all edges and cliques missing in the conflict graph for the root subproblem */ /* (not implemented yet) */ #endif } /* the current subproblem has been frozen */ tree->curr = NULL; return; } /*********************************************************************** * NAME * * ios_clone_node - clone specified subproblem * * SYNOPSIS * * #include "glpios.h" * void ios_clone_node(glp_tree *tree, int p, int nnn, int ref[]); * * DESCRIPTION * * The routine ios_clone_node clones the specified subproblem, whose * reference number is p, creating its nnn exact copies. Note that the * specified subproblem must be active and must be in the frozen state * (i.e. it must not be the current subproblem). * * Each clone, an exact copy of the specified subproblem, becomes a new * active subproblem added to the end of the active list. After cloning * the specified subproblem becomes inactive. * * The reference numbers of clone subproblems are stored to locations * ref[1], ..., ref[nnn]. */ static int get_slot(glp_tree *tree) { int p; /* if no free slots are available, increase the room */ if (tree->avail == 0) { int nslots = tree->nslots; IOSLOT *save = tree->slot; if (nslots == 0) tree->nslots = 20; else { tree->nslots = nslots + nslots; xassert(tree->nslots > nslots); } tree->slot = xcalloc(1+tree->nslots, sizeof(IOSLOT)); if (save != NULL) { memcpy(&tree->slot[1], &save[1], nslots * sizeof(IOSLOT)); xfree(save); } /* push more free slots into the stack */ for (p = tree->nslots; p > nslots; p--) { tree->slot[p].node = NULL; tree->slot[p].next = tree->avail; tree->avail = p; } } /* pull a free slot from the stack */ p = tree->avail; tree->avail = tree->slot[p].next; xassert(tree->slot[p].node == NULL); tree->slot[p].next = 0; return p; } static IOSNPD *new_node(glp_tree *tree, IOSNPD *parent) { IOSNPD *node; int p; /* pull a free slot for the new node */ p = get_slot(tree); /* create descriptor of the new subproblem */ node = dmp_get_atom(tree->pool, sizeof(IOSNPD)); tree->slot[p].node = node; node->p = p; node->up = parent; node->level = (parent == NULL ? 0 : parent->level + 1); node->count = 0; node->b_ptr = NULL; node->s_ptr = NULL; node->r_ptr = NULL; node->solved = 0; #if 0 node->own_nn = node->own_nc = 0; node->e_ptr = NULL; #endif #if 1 /* 04/X-2008 */ node->lp_obj = (parent == NULL ? (tree->mip->dir == GLP_MIN ? -DBL_MAX : +DBL_MAX) : parent->lp_obj); #endif node->bound = (parent == NULL ? (tree->mip->dir == GLP_MIN ? -DBL_MAX : +DBL_MAX) : parent->bound); node->br_var = 0; node->br_val = 0.0; node->ii_cnt = 0; node->ii_sum = 0.0; #if 1 /* 30/XI-2009 */ node->changed = 0; #endif if (tree->parm->cb_size == 0) node->data = NULL; else { node->data = dmp_get_atom(tree->pool, tree->parm->cb_size); memset(node->data, 0, tree->parm->cb_size); } node->temp = NULL; node->prev = tree->tail; node->next = NULL; /* add the new subproblem to the end of the active list */ if (tree->head == NULL) tree->head = node; else tree->tail->next = node; tree->tail = node; tree->a_cnt++; tree->n_cnt++; tree->t_cnt++; /* increase the number of child subproblems */ if (parent == NULL) xassert(p == 1); else parent->count++; return node; } void ios_clone_node(glp_tree *tree, int p, int nnn, int ref[]) { IOSNPD *node; int k; /* obtain pointer to the subproblem to be cloned */ xassert(1 <= p && p <= tree->nslots); node = tree->slot[p].node; xassert(node != NULL); /* the specified subproblem must be active */ xassert(node->count == 0); /* and must be in the frozen state */ xassert(tree->curr != node); /* remove the specified subproblem from the active list, because it becomes inactive */ if (node->prev == NULL) tree->head = node->next; else node->prev->next = node->next; if (node->next == NULL) tree->tail = node->prev; else node->next->prev = node->prev; node->prev = node->next = NULL; tree->a_cnt--; /* create clone subproblems */ xassert(nnn > 0); for (k = 1; k <= nnn; k++) ref[k] = new_node(tree, node)->p; return; } /*********************************************************************** * NAME * * ios_delete_node - delete specified subproblem * * SYNOPSIS * * #include "glpios.h" * void ios_delete_node(glp_tree *tree, int p); * * DESCRIPTION * * The routine ios_delete_node deletes the specified subproblem, whose * reference number is p. The subproblem must be active and must be in * the frozen state (i.e. it must not be the current subproblem). * * Note that deletion is performed recursively, i.e. if a subproblem to * be deleted is the only child of its parent, the parent subproblem is * also deleted, etc. */ void ios_delete_node(glp_tree *tree, int p) { IOSNPD *node, *temp; /* obtain pointer to the subproblem to be deleted */ xassert(1 <= p && p <= tree->nslots); node = tree->slot[p].node; xassert(node != NULL); /* the specified subproblem must be active */ xassert(node->count == 0); /* and must be in the frozen state */ xassert(tree->curr != node); /* remove the specified subproblem from the active list, because it is gone from the tree */ if (node->prev == NULL) tree->head = node->next; else node->prev->next = node->next; if (node->next == NULL) tree->tail = node->prev; else node->next->prev = node->prev; node->prev = node->next = NULL; tree->a_cnt--; loop: /* recursive deletion starts here */ /* delete the bound change list */ { IOSBND *b; while (node->b_ptr != NULL) { b = node->b_ptr; node->b_ptr = b->next; dmp_free_atom(tree->pool, b, sizeof(IOSBND)); } } /* delete the status change list */ { IOSTAT *s; while (node->s_ptr != NULL) { s = node->s_ptr; node->s_ptr = s->next; dmp_free_atom(tree->pool, s, sizeof(IOSTAT)); } } /* delete the row addition list */ while (node->r_ptr != NULL) { IOSROW *r; r = node->r_ptr; if (r->name != NULL) dmp_free_atom(tree->pool, r->name, strlen(r->name)+1); while (r->ptr != NULL) { IOSAIJ *a; a = r->ptr; r->ptr = a->next; dmp_free_atom(tree->pool, a, sizeof(IOSAIJ)); } node->r_ptr = r->next; dmp_free_atom(tree->pool, r, sizeof(IOSROW)); } #if 0 /* delete the edge addition list */ /* delete the clique addition list */ /* (not implemented yet) */ xassert(node->own_nn == 0); xassert(node->own_nc == 0); xassert(node->e_ptr == NULL); #endif /* free application-specific data */ if (tree->parm->cb_size == 0) xassert(node->data == NULL); else dmp_free_atom(tree->pool, node->data, tree->parm->cb_size); /* free the corresponding node slot */ p = node->p; xassert(tree->slot[p].node == node); tree->slot[p].node = NULL; tree->slot[p].next = tree->avail; tree->avail = p; /* save pointer to the parent subproblem */ temp = node->up; /* delete the subproblem descriptor */ dmp_free_atom(tree->pool, node, sizeof(IOSNPD)); tree->n_cnt--; /* take pointer to the parent subproblem */ node = temp; if (node != NULL) { /* the parent subproblem exists; decrease the number of its child subproblems */ xassert(node->count > 0); node->count--; /* if now the parent subproblem has no childs, it also must be deleted */ if (node->count == 0) goto loop; } return; } /*********************************************************************** * NAME * * ios_delete_tree - delete branch-and-bound tree * * SYNOPSIS * * #include "glpios.h" * void ios_delete_tree(glp_tree *tree); * * DESCRIPTION * * The routine ios_delete_tree deletes the branch-and-bound tree, which * the parameter tree points to, and frees all the memory allocated to * this program object. * * On exit components of the problem object are restored to correspond * to the original MIP passed to the routine ios_create_tree. */ void ios_delete_tree(glp_tree *tree) { glp_prob *mip = tree->mip; int i, j; int m = mip->m; int n = mip->n; xassert(mip->tree == tree); /* remove all additional rows */ if (m != tree->orig_m) { int nrs, *num; nrs = m - tree->orig_m; xassert(nrs > 0); num = xcalloc(1+nrs, sizeof(int)); for (i = 1; i <= nrs; i++) num[i] = tree->orig_m + i; glp_del_rows(mip, nrs, num); xfree(num); } m = tree->orig_m; /* restore original attributes of rows and columns */ xassert(m == tree->orig_m); xassert(n == tree->n); for (i = 1; i <= m; i++) { glp_set_row_bnds(mip, i, tree->orig_type[i], tree->orig_lb[i], tree->orig_ub[i]); glp_set_row_stat(mip, i, tree->orig_stat[i]); mip->row[i]->prim = tree->orig_prim[i]; mip->row[i]->dual = tree->orig_dual[i]; } for (j = 1; j <= n; j++) { glp_set_col_bnds(mip, j, tree->orig_type[m+j], tree->orig_lb[m+j], tree->orig_ub[m+j]); glp_set_col_stat(mip, j, tree->orig_stat[m+j]); mip->col[j]->prim = tree->orig_prim[m+j]; mip->col[j]->dual = tree->orig_dual[m+j]; } mip->pbs_stat = mip->dbs_stat = GLP_FEAS; mip->obj_val = tree->orig_obj; /* delete the branch-and-bound tree */ xassert(tree->local != NULL); ios_delete_pool(tree, tree->local); dmp_delete_pool(tree->pool); xfree(tree->orig_type); xfree(tree->orig_lb); xfree(tree->orig_ub); xfree(tree->orig_stat); xfree(tree->orig_prim); xfree(tree->orig_dual); xfree(tree->slot); if (tree->root_type != NULL) xfree(tree->root_type); if (tree->root_lb != NULL) xfree(tree->root_lb); if (tree->root_ub != NULL) xfree(tree->root_ub); if (tree->root_stat != NULL) xfree(tree->root_stat); xfree(tree->non_int); #if 0 xfree(tree->n_ref); xfree(tree->c_ref); xfree(tree->j_ref); #endif if (tree->pcost != NULL) ios_pcost_free(tree); xfree(tree->iwrk); xfree(tree->dwrk); #if 0 scg_delete_graph(tree->g); #endif if (tree->pred_type != NULL) xfree(tree->pred_type); if (tree->pred_lb != NULL) xfree(tree->pred_lb); if (tree->pred_ub != NULL) xfree(tree->pred_ub); if (tree->pred_stat != NULL) xfree(tree->pred_stat); #if 0 xassert(tree->cut_gen == NULL); #endif xassert(tree->mir_gen == NULL); xassert(tree->clq_gen == NULL); xfree(tree); mip->tree = NULL; return; } /*********************************************************************** * NAME * * ios_eval_degrad - estimate obj. degrad. for down- and up-branches * * SYNOPSIS * * #include "glpios.h" * void ios_eval_degrad(glp_tree *tree, int j, double *dn, double *up); * * DESCRIPTION * * Given optimal basis to LP relaxation of the current subproblem the * routine ios_eval_degrad performs the dual ratio test to compute the * objective values in the adjacent basis for down- and up-branches, * which are stored in locations *dn and *up, assuming that x[j] is a * variable chosen to branch upon. */ void ios_eval_degrad(glp_tree *tree, int j, double *dn, double *up) { glp_prob *mip = tree->mip; int m = mip->m, n = mip->n; int len, kase, k, t, stat; double alfa, beta, gamma, delta, dz; int *ind = tree->iwrk; double *val = tree->dwrk; /* current basis must be optimal */ xassert(glp_get_status(mip) == GLP_OPT); /* basis factorization must exist */ xassert(glp_bf_exists(mip)); /* obtain (fractional) value of x[j] in optimal basic solution to LP relaxation of the current subproblem */ xassert(1 <= j && j <= n); beta = mip->col[j]->prim; /* since the value of x[j] is fractional, it is basic; compute corresponding row of the simplex table */ len = lpx_eval_tab_row(mip, m+j, ind, val); /* kase < 0 means down-branch; kase > 0 means up-branch */ for (kase = -1; kase <= +1; kase += 2) { /* for down-branch we introduce new upper bound floor(beta) for x[j]; similarly, for up-branch we introduce new lower bound ceil(beta) for x[j]; in the current basis this new upper/lower bound is violated, so in the adjacent basis x[j] will leave the basis and go to its new upper/lower bound; we need to know which non-basic variable x[k] should enter the basis to keep dual feasibility */ #if 0 /* 23/XI-2009 */ k = lpx_dual_ratio_test(mip, len, ind, val, kase, 1e-7); #else k = lpx_dual_ratio_test(mip, len, ind, val, kase, 1e-9); #endif /* if no variable has been chosen, current basis being primal infeasible due to the new upper/lower bound of x[j] is dual unbounded, therefore, LP relaxation to corresponding branch has no primal feasible solution */ if (k == 0) { if (mip->dir == GLP_MIN) { if (kase < 0) *dn = +DBL_MAX; else *up = +DBL_MAX; } else if (mip->dir == GLP_MAX) { if (kase < 0) *dn = -DBL_MAX; else *up = -DBL_MAX; } else xassert(mip != mip); continue; } xassert(1 <= k && k <= m+n); /* row of the simplex table corresponding to specified basic variable x[j] is the following: x[j] = ... + alfa * x[k] + ... ; we need to know influence coefficient, alfa, at non-basic variable x[k] chosen with the dual ratio test */ for (t = 1; t <= len; t++) if (ind[t] == k) break; xassert(1 <= t && t <= len); alfa = val[t]; /* determine status and reduced cost of variable x[k] */ if (k <= m) { stat = mip->row[k]->stat; gamma = mip->row[k]->dual; } else { stat = mip->col[k-m]->stat; gamma = mip->col[k-m]->dual; } /* x[k] cannot be basic or fixed non-basic */ xassert(stat == GLP_NL || stat == GLP_NU || stat == GLP_NF); /* if the current basis is dual degenerative, some reduced costs, which are close to zero, may have wrong sign due to round-off errors, so correct the sign of gamma */ if (mip->dir == GLP_MIN) { if (stat == GLP_NL && gamma < 0.0 || stat == GLP_NU && gamma > 0.0 || stat == GLP_NF) gamma = 0.0; } else if (mip->dir == GLP_MAX) { if (stat == GLP_NL && gamma > 0.0 || stat == GLP_NU && gamma < 0.0 || stat == GLP_NF) gamma = 0.0; } else xassert(mip != mip); /* determine the change of x[j] in the adjacent basis: delta x[j] = new x[j] - old x[j] */ delta = (kase < 0 ? floor(beta) : ceil(beta)) - beta; /* compute the change of x[k] in the adjacent basis: delta x[k] = new x[k] - old x[k] = delta x[j] / alfa */ delta /= alfa; /* compute the change of the objective in the adjacent basis: delta z = new z - old z = gamma * delta x[k] */ dz = gamma * delta; if (mip->dir == GLP_MIN) xassert(dz >= 0.0); else if (mip->dir == GLP_MAX) xassert(dz <= 0.0); else xassert(mip != mip); /* compute the new objective value in the adjacent basis: new z = old z + delta z */ if (kase < 0) *dn = mip->obj_val + dz; else *up = mip->obj_val + dz; } /*xprintf("obj = %g; dn = %g; up = %g\n", mip->obj_val, *dn, *up);*/ return; } /*********************************************************************** * NAME * * ios_round_bound - improve local bound by rounding * * SYNOPSIS * * #include "glpios.h" * double ios_round_bound(glp_tree *tree, double bound); * * RETURNS * * For the given local bound for any integer feasible solution to the * current subproblem the routine ios_round_bound returns an improved * local bound for the same integer feasible solution. * * BACKGROUND * * Let the current subproblem has the following objective function: * * z = sum c[j] * x[j] + s >= b, (1) * j in J * * where J = {j: c[j] is non-zero and integer, x[j] is integer}, s is * the sum of terms corresponding to fixed variables, b is an initial * local bound (minimization). * * From (1) it follows that: * * d * sum (c[j] / d) * x[j] + s >= b, (2) * j in J * * or, equivalently, * * sum (c[j] / d) * x[j] >= (b - s) / d = h, (3) * j in J * * where d = gcd(c[j]). Since the left-hand side of (3) is integer, * h = (b - s) / d can be rounded up to the nearest integer: * * h' = ceil(h) = (b' - s) / d, (4) * * that gives an rounded, improved local bound: * * b' = d * h' + s. (5) * * In case of maximization '>=' in (1) should be replaced by '<=' that * leads to the following formula: * * h' = floor(h) = (b' - s) / d, (6) * * which should used in the same way as (4). * * NOTE: If b is a valid local bound for a child of the current * subproblem, b' is also valid for that child subproblem. */ double ios_round_bound(glp_tree *tree, double bound) { glp_prob *mip = tree->mip; int n = mip->n; int d, j, nn, *c = tree->iwrk; double s, h; /* determine c[j] and compute s */ nn = 0, s = mip->c0, d = 0; for (j = 1; j <= n; j++) { GLPCOL *col = mip->col[j]; if (col->coef == 0.0) continue; if (col->type == GLP_FX) { /* fixed variable */ s += col->coef * col->prim; } else { /* non-fixed variable */ if (col->kind != GLP_IV) goto skip; if (col->coef != floor(col->coef)) goto skip; if (fabs(col->coef) <= (double)INT_MAX) c[++nn] = (int)fabs(col->coef); else d = 1; } } /* compute d = gcd(c[1],...c[nn]) */ if (d == 0) { if (nn == 0) goto skip; d = gcdn(nn, c); } xassert(d > 0); /* compute new local bound */ if (mip->dir == GLP_MIN) { if (bound != +DBL_MAX) { h = (bound - s) / (double)d; if (h >= floor(h) + 0.001) { /* round up */ h = ceil(h); /*xprintf("d = %d; old = %g; ", d, bound);*/ bound = (double)d * h + s; /*xprintf("new = %g\n", bound);*/ } } } else if (mip->dir == GLP_MAX) { if (bound != -DBL_MAX) { h = (bound - s) / (double)d; if (h <= ceil(h) - 0.001) { /* round down */ h = floor(h); bound = (double)d * h + s; } } } else xassert(mip != mip); skip: return bound; } /*********************************************************************** * NAME * * ios_is_hopeful - check if subproblem is hopeful * * SYNOPSIS * * #include "glpios.h" * int ios_is_hopeful(glp_tree *tree, double bound); * * DESCRIPTION * * Given the local bound of a subproblem the routine ios_is_hopeful * checks if the subproblem can have an integer optimal solution which * is better than the best one currently known. * * RETURNS * * If the subproblem can have a better integer optimal solution, the * routine returns non-zero; otherwise, if the corresponding branch can * be pruned, the routine returns zero. */ int ios_is_hopeful(glp_tree *tree, double bound) { glp_prob *mip = tree->mip; int ret = 1; double eps; if (mip->mip_stat == GLP_FEAS) { eps = tree->parm->tol_obj * (1.0 + fabs(mip->mip_obj)); switch (mip->dir) { case GLP_MIN: if (bound >= mip->mip_obj - eps) ret = 0; break; case GLP_MAX: if (bound <= mip->mip_obj + eps) ret = 0; break; default: xassert(mip != mip); } } else { switch (mip->dir) { case GLP_MIN: if (bound == +DBL_MAX) ret = 0; break; case GLP_MAX: if (bound == -DBL_MAX) ret = 0; break; default: xassert(mip != mip); } } return ret; } /*********************************************************************** * NAME * * ios_best_node - find active node with best local bound * * SYNOPSIS * * #include "glpios.h" * int ios_best_node(glp_tree *tree); * * DESCRIPTION * * The routine ios_best_node finds an active node whose local bound is * best among other active nodes. * * It is understood that the integer optimal solution of the original * mip problem cannot be better than the best bound, so the best bound * is an lower (minimization) or upper (maximization) global bound for * the original problem. * * RETURNS * * The routine ios_best_node returns the subproblem reference number * for the best node. However, if the tree is empty, it returns zero. */ int ios_best_node(glp_tree *tree) { IOSNPD *node, *best = NULL; switch (tree->mip->dir) { case GLP_MIN: /* minimization */ for (node = tree->head; node != NULL; node = node->next) if (best == NULL || best->bound > node->bound) best = node; break; case GLP_MAX: /* maximization */ for (node = tree->head; node != NULL; node = node->next) if (best == NULL || best->bound < node->bound) best = node; break; default: xassert(tree != tree); } return best == NULL ? 0 : best->p; } /*********************************************************************** * NAME * * ios_relative_gap - compute relative mip gap * * SYNOPSIS * * #include "glpios.h" * double ios_relative_gap(glp_tree *tree); * * DESCRIPTION * * The routine ios_relative_gap computes the relative mip gap using the * formula: * * gap = |best_mip - best_bnd| / (|best_mip| + DBL_EPSILON), * * where best_mip is the best integer feasible solution found so far, * best_bnd is the best (global) bound. If no integer feasible solution * has been found yet, rel_gap is set to DBL_MAX. * * RETURNS * * The routine ios_relative_gap returns the relative mip gap. */ double ios_relative_gap(glp_tree *tree) { glp_prob *mip = tree->mip; int p; double best_mip, best_bnd, gap; if (mip->mip_stat == GLP_FEAS) { best_mip = mip->mip_obj; p = ios_best_node(tree); if (p == 0) { /* the tree is empty */ gap = 0.0; } else { best_bnd = tree->slot[p].node->bound; gap = fabs(best_mip - best_bnd) / (fabs(best_mip) + DBL_EPSILON); } } else { /* no integer feasible solution has been found yet */ gap = DBL_MAX; } return gap; } /*********************************************************************** * NAME * * ios_solve_node - solve LP relaxation of current subproblem * * SYNOPSIS * * #include "glpios.h" * int ios_solve_node(glp_tree *tree); * * DESCRIPTION * * The routine ios_solve_node re-optimizes LP relaxation of the current * subproblem using the dual simplex method. * * RETURNS * * The routine returns the code which is reported by glp_simplex. */ int ios_solve_node(glp_tree *tree) { glp_prob *mip = tree->mip; glp_smcp parm; int ret; /* the current subproblem must exist */ xassert(tree->curr != NULL); /* set some control parameters */ glp_init_smcp(&parm); switch (tree->parm->msg_lev) { case GLP_MSG_OFF: parm.msg_lev = GLP_MSG_OFF; break; case GLP_MSG_ERR: parm.msg_lev = GLP_MSG_ERR; break; case GLP_MSG_ON: case GLP_MSG_ALL: parm.msg_lev = GLP_MSG_ON; break; case GLP_MSG_DBG: parm.msg_lev = GLP_MSG_ALL; break; default: xassert(tree != tree); } parm.meth = GLP_DUALP; if (tree->parm->msg_lev < GLP_MSG_DBG) parm.out_dly = tree->parm->out_dly; else parm.out_dly = 0; /* if the incumbent objective value is already known, use it to prematurely terminate the dual simplex search */ if (mip->mip_stat == GLP_FEAS) { switch (tree->mip->dir) { case GLP_MIN: parm.obj_ul = mip->mip_obj; break; case GLP_MAX: parm.obj_ll = mip->mip_obj; break; default: xassert(mip != mip); } } /* try to solve/re-optimize the LP relaxation */ ret = glp_simplex(mip, &parm); tree->curr->solved++; #if 0 xprintf("ret = %d; status = %d; pbs = %d; dbs = %d; some = %d\n", ret, glp_get_status(mip), mip->pbs_stat, mip->dbs_stat, mip->some); lpx_print_sol(mip, "sol"); #endif return ret; } /**********************************************************************/ IOSPOOL *ios_create_pool(glp_tree *tree) { /* create cut pool */ IOSPOOL *pool; #if 0 pool = dmp_get_atom(tree->pool, sizeof(IOSPOOL)); #else xassert(tree == tree); pool = xmalloc(sizeof(IOSPOOL)); #endif pool->size = 0; pool->head = pool->tail = NULL; pool->ord = 0, pool->curr = NULL; return pool; } int ios_add_row(glp_tree *tree, IOSPOOL *pool, const char *name, int klass, int flags, int len, const int ind[], const double val[], int type, double rhs) { /* add row (constraint) to the cut pool */ IOSCUT *cut; IOSAIJ *aij; int k; xassert(pool != NULL); cut = dmp_get_atom(tree->pool, sizeof(IOSCUT)); if (name == NULL || name[0] == '\0') cut->name = NULL; else { for (k = 0; name[k] != '\0'; k++) { if (k == 256) xerror("glp_ios_add_row: cut name too long\n"); if (iscntrl((unsigned char)name[k])) xerror("glp_ios_add_row: cut name contains invalid chara" "cter(s)\n"); } cut->name = dmp_get_atom(tree->pool, strlen(name)+1); strcpy(cut->name, name); } if (!(0 <= klass && klass <= 255)) xerror("glp_ios_add_row: klass = %d; invalid cut class\n", klass); cut->klass = (unsigned char)klass; if (flags != 0) xerror("glp_ios_add_row: flags = %d; invalid cut flags\n", flags); cut->ptr = NULL; if (!(0 <= len && len <= tree->n)) xerror("glp_ios_add_row: len = %d; invalid cut length\n", len); for (k = 1; k <= len; k++) { aij = dmp_get_atom(tree->pool, sizeof(IOSAIJ)); if (!(1 <= ind[k] && ind[k] <= tree->n)) xerror("glp_ios_add_row: ind[%d] = %d; column index out of " "range\n", k, ind[k]); aij->j = ind[k]; aij->val = val[k]; aij->next = cut->ptr; cut->ptr = aij; } if (!(type == GLP_LO || type == GLP_UP || type == GLP_FX)) xerror("glp_ios_add_row: type = %d; invalid cut type\n", type); cut->type = (unsigned char)type; cut->rhs = rhs; cut->prev = pool->tail; cut->next = NULL; if (cut->prev == NULL) pool->head = cut; else cut->prev->next = cut; pool->tail = cut; pool->size++; return pool->size; } IOSCUT *ios_find_row(IOSPOOL *pool, int i) { /* find row (constraint) in the cut pool */ /* (smart linear search) */ xassert(pool != NULL); xassert(1 <= i && i <= pool->size); if (pool->ord == 0) { xassert(pool->curr == NULL); pool->ord = 1; pool->curr = pool->head; } xassert(pool->curr != NULL); if (i < pool->ord) { if (i < pool->ord - i) { pool->ord = 1; pool->curr = pool->head; while (pool->ord != i) { pool->ord++; xassert(pool->curr != NULL); pool->curr = pool->curr->next; } } else { while (pool->ord != i) { pool->ord--; xassert(pool->curr != NULL); pool->curr = pool->curr->prev; } } } else if (i > pool->ord) { if (i - pool->ord < pool->size - i) { while (pool->ord != i) { pool->ord++; xassert(pool->curr != NULL); pool->curr = pool->curr->next; } } else { pool->ord = pool->size; pool->curr = pool->tail; while (pool->ord != i) { pool->ord--; xassert(pool->curr != NULL); pool->curr = pool->curr->prev; } } } xassert(pool->ord == i); xassert(pool->curr != NULL); return pool->curr; } void ios_del_row(glp_tree *tree, IOSPOOL *pool, int i) { /* remove row (constraint) from the cut pool */ IOSCUT *cut; IOSAIJ *aij; xassert(pool != NULL); if (!(1 <= i && i <= pool->size)) xerror("glp_ios_del_row: i = %d; cut number out of range\n", i); cut = ios_find_row(pool, i); xassert(pool->curr == cut); if (cut->next != NULL) pool->curr = cut->next; else if (cut->prev != NULL) pool->ord--, pool->curr = cut->prev; else pool->ord = 0, pool->curr = NULL; if (cut->name != NULL) dmp_free_atom(tree->pool, cut->name, strlen(cut->name)+1); if (cut->prev == NULL) { xassert(pool->head == cut); pool->head = cut->next; } else { xassert(cut->prev->next == cut); cut->prev->next = cut->next; } if (cut->next == NULL) { xassert(pool->tail == cut); pool->tail = cut->prev; } else { xassert(cut->next->prev == cut); cut->next->prev = cut->prev; } while (cut->ptr != NULL) { aij = cut->ptr; cut->ptr = aij->next; dmp_free_atom(tree->pool, aij, sizeof(IOSAIJ)); } dmp_free_atom(tree->pool, cut, sizeof(IOSCUT)); pool->size--; return; } void ios_clear_pool(glp_tree *tree, IOSPOOL *pool) { /* remove all rows (constraints) from the cut pool */ xassert(pool != NULL); while (pool->head != NULL) { IOSCUT *cut = pool->head; pool->head = cut->next; if (cut->name != NULL) dmp_free_atom(tree->pool, cut->name, strlen(cut->name)+1); while (cut->ptr != NULL) { IOSAIJ *aij = cut->ptr; cut->ptr = aij->next; dmp_free_atom(tree->pool, aij, sizeof(IOSAIJ)); } dmp_free_atom(tree->pool, cut, sizeof(IOSCUT)); } pool->size = 0; pool->head = pool->tail = NULL; pool->ord = 0, pool->curr = NULL; return; } void ios_delete_pool(glp_tree *tree, IOSPOOL *pool) { /* delete cut pool */ xassert(pool != NULL); ios_clear_pool(tree, pool); xfree(pool); return; } /**********************************************************************/ #if 0 static int refer_to_node(glp_tree *tree, int j) { /* determine node number corresponding to binary variable x[j] or its complement */ glp_prob *mip = tree->mip; int n = mip->n; int *ref; if (j > 0) ref = tree->n_ref; else ref = tree->c_ref, j = - j; xassert(1 <= j && j <= n); if (ref[j] == 0) { /* new node is needed */ SCG *g = tree->g; int n_max = g->n_max; ref[j] = scg_add_nodes(g, 1); if (g->n_max > n_max) { int *save = tree->j_ref; tree->j_ref = xcalloc(1+g->n_max, sizeof(int)); memcpy(&tree->j_ref[1], &save[1], g->n * sizeof(int)); xfree(save); } xassert(ref[j] == g->n); tree->j_ref[ref[j]] = j; xassert(tree->curr != NULL); if (tree->curr->level > 0) tree->curr->own_nn++; } return ref[j]; } #endif #if 0 void ios_add_edge(glp_tree *tree, int j1, int j2) { /* add new edge to the conflict graph */ glp_prob *mip = tree->mip; int n = mip->n; SCGRIB *e; int first, i1, i2; xassert(-n <= j1 && j1 <= +n && j1 != 0); xassert(-n <= j2 && j2 <= +n && j2 != 0); xassert(j1 != j2); /* determine number of the first node, which was added for the current subproblem */ xassert(tree->curr != NULL); first = tree->g->n - tree->curr->own_nn + 1; /* determine node numbers for both endpoints */ i1 = refer_to_node(tree, j1); i2 = refer_to_node(tree, j2); /* add edge (i1,i2) to the conflict graph */ e = scg_add_edge(tree->g, i1, i2); /* if the current subproblem is not the root and both endpoints were created on some previous levels, save the edge */ if (tree->curr->level > 0 && i1 < first && i2 < first) { IOSRIB *rib; rib = dmp_get_atom(tree->pool, sizeof(IOSRIB)); rib->j1 = j1; rib->j2 = j2; rib->e = e; rib->next = tree->curr->e_ptr; tree->curr->e_ptr = rib; } return; } #endif /* eof */ praat-6.0.04/external/glpk/glpios02.c000066400000000000000000000645171261542461700173170ustar00rootroot00000000000000/* glpios02.c (preprocess current subproblem) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpios.h" /*********************************************************************** * prepare_row_info - prepare row info to determine implied bounds * * Given a row (linear form) * * n * sum a[j] * x[j] (1) * j=1 * * and bounds of columns (variables) * * l[j] <= x[j] <= u[j] (2) * * this routine computes f_min, j_min, f_max, j_max needed to determine * implied bounds. * * ALGORITHM * * Let J+ = {j : a[j] > 0} and J- = {j : a[j] < 0}. * * Parameters f_min and j_min are computed as follows: * * 1) if there is no x[k] such that k in J+ and l[k] = -inf or k in J- * and u[k] = +inf, then * * f_min := sum a[j] * l[j] + sum a[j] * u[j] * j in J+ j in J- * (3) * j_min := 0 * * 2) if there is exactly one x[k] such that k in J+ and l[k] = -inf * or k in J- and u[k] = +inf, then * * f_min := sum a[j] * l[j] + sum a[j] * u[j] * j in J+\{k} j in J-\{k} * (4) * j_min := k * * 3) if there are two or more x[k] such that k in J+ and l[k] = -inf * or k in J- and u[k] = +inf, then * * f_min := -inf * (5) * j_min := 0 * * Parameters f_max and j_max are computed in a similar way as follows: * * 1) if there is no x[k] such that k in J+ and u[k] = +inf or k in J- * and l[k] = -inf, then * * f_max := sum a[j] * u[j] + sum a[j] * l[j] * j in J+ j in J- * (6) * j_max := 0 * * 2) if there is exactly one x[k] such that k in J+ and u[k] = +inf * or k in J- and l[k] = -inf, then * * f_max := sum a[j] * u[j] + sum a[j] * l[j] * j in J+\{k} j in J-\{k} * (7) * j_max := k * * 3) if there are two or more x[k] such that k in J+ and u[k] = +inf * or k in J- and l[k] = -inf, then * * f_max := +inf * (8) * j_max := 0 */ struct f_info { int j_min, j_max; double f_min, f_max; }; static void prepare_row_info(int n, const double a[], const double l[], const double u[], struct f_info *f) { int j, j_min, j_max; double f_min, f_max; xassert(n >= 0); /* determine f_min and j_min */ f_min = 0.0, j_min = 0; for (j = 1; j <= n; j++) { if (a[j] > 0.0) { if (l[j] == -DBL_MAX) { if (j_min == 0) j_min = j; else { f_min = -DBL_MAX, j_min = 0; break; } } else f_min += a[j] * l[j]; } else if (a[j] < 0.0) { if (u[j] == +DBL_MAX) { if (j_min == 0) j_min = j; else { f_min = -DBL_MAX, j_min = 0; break; } } else f_min += a[j] * u[j]; } else xassert(a != a); } f->f_min = f_min, f->j_min = j_min; /* determine f_max and j_max */ f_max = 0.0, j_max = 0; for (j = 1; j <= n; j++) { if (a[j] > 0.0) { if (u[j] == +DBL_MAX) { if (j_max == 0) j_max = j; else { f_max = +DBL_MAX, j_max = 0; break; } } else f_max += a[j] * u[j]; } else if (a[j] < 0.0) { if (l[j] == -DBL_MAX) { if (j_max == 0) j_max = j; else { f_max = +DBL_MAX, j_max = 0; break; } } else f_max += a[j] * l[j]; } else xassert(a != a); } f->f_max = f_max, f->j_max = j_max; return; } /*********************************************************************** * row_implied_bounds - determine row implied bounds * * Given a row (linear form) * * n * sum a[j] * x[j] * j=1 * * and bounds of columns (variables) * * l[j] <= x[j] <= u[j] * * this routine determines implied bounds of the row. * * ALGORITHM * * Let J+ = {j : a[j] > 0} and J- = {j : a[j] < 0}. * * The implied lower bound of the row is computed as follows: * * L' := sum a[j] * l[j] + sum a[j] * u[j] (9) * j in J+ j in J- * * and as it follows from (3), (4), and (5): * * L' := if j_min = 0 then f_min else -inf (10) * * The implied upper bound of the row is computed as follows: * * U' := sum a[j] * u[j] + sum a[j] * l[j] (11) * j in J+ j in J- * * and as it follows from (6), (7), and (8): * * U' := if j_max = 0 then f_max else +inf (12) * * The implied bounds are stored in locations LL and UU. */ static void row_implied_bounds(const struct f_info *f, double *LL, double *UU) { *LL = (f->j_min == 0 ? f->f_min : -DBL_MAX); *UU = (f->j_max == 0 ? f->f_max : +DBL_MAX); return; } /*********************************************************************** * col_implied_bounds - determine column implied bounds * * Given a row (constraint) * * n * L <= sum a[j] * x[j] <= U (13) * j=1 * * and bounds of columns (variables) * * l[j] <= x[j] <= u[j] * * this routine determines implied bounds of variable x[k]. * * It is assumed that if L != -inf, the lower bound of the row can be * active, and if U != +inf, the upper bound of the row can be active. * * ALGORITHM * * From (13) it follows that * * L <= sum a[j] * x[j] + a[k] * x[k] <= U * j!=k * or * * L - sum a[j] * x[j] <= a[k] * x[k] <= U - sum a[j] * x[j] * j!=k j!=k * * Thus, if the row lower bound L can be active, implied lower bound of * term a[k] * x[k] can be determined as follows: * * ilb(a[k] * x[k]) = min(L - sum a[j] * x[j]) = * j!=k * (14) * = L - max sum a[j] * x[j] * j!=k * * where, as it follows from (6), (7), and (8) * * / f_max - a[k] * u[k], j_max = 0, a[k] > 0 * | * | f_max - a[k] * l[k], j_max = 0, a[k] < 0 * max sum a[j] * x[j] = { * j!=k | f_max, j_max = k * | * \ +inf, j_max != 0 * * and if the upper bound U can be active, implied upper bound of term * a[k] * x[k] can be determined as follows: * * iub(a[k] * x[k]) = max(U - sum a[j] * x[j]) = * j!=k * (15) * = U - min sum a[j] * x[j] * j!=k * * where, as it follows from (3), (4), and (5) * * / f_min - a[k] * l[k], j_min = 0, a[k] > 0 * | * | f_min - a[k] * u[k], j_min = 0, a[k] < 0 * min sum a[j] * x[j] = { * j!=k | f_min, j_min = k * | * \ -inf, j_min != 0 * * Since * * ilb(a[k] * x[k]) <= a[k] * x[k] <= iub(a[k] * x[k]) * * implied lower and upper bounds of x[k] are determined as follows: * * l'[k] := if a[k] > 0 then ilb / a[k] else ulb / a[k] (16) * * u'[k] := if a[k] > 0 then ulb / a[k] else ilb / a[k] (17) * * The implied bounds are stored in locations ll and uu. */ static void col_implied_bounds(const struct f_info *f, int n, const double a[], double L, double U, const double l[], const double u[], int k, double *ll, double *uu) { double ilb, iub; xassert(n >= 0); xassert(1 <= k && k <= n); /* determine implied lower bound of term a[k] * x[k] (14) */ if (L == -DBL_MAX || f->f_max == +DBL_MAX) ilb = -DBL_MAX; else if (f->j_max == 0) { if (a[k] > 0.0) { xassert(u[k] != +DBL_MAX); ilb = L - (f->f_max - a[k] * u[k]); } else if (a[k] < 0.0) { xassert(l[k] != -DBL_MAX); ilb = L - (f->f_max - a[k] * l[k]); } else xassert(a != a); } else if (f->j_max == k) ilb = L - f->f_max; else ilb = -DBL_MAX; /* determine implied upper bound of term a[k] * x[k] (15) */ if (U == +DBL_MAX || f->f_min == -DBL_MAX) iub = +DBL_MAX; else if (f->j_min == 0) { if (a[k] > 0.0) { xassert(l[k] != -DBL_MAX); iub = U - (f->f_min - a[k] * l[k]); } else if (a[k] < 0.0) { xassert(u[k] != +DBL_MAX); iub = U - (f->f_min - a[k] * u[k]); } else xassert(a != a); } else if (f->j_min == k) iub = U - f->f_min; else iub = +DBL_MAX; /* determine implied bounds of x[k] (16) and (17) */ #if 1 /* do not use a[k] if it has small magnitude to prevent wrong implied bounds; for example, 1e-15 * x1 >= x2 + x3, where x1 >= -10, x2, x3 >= 0, would lead to wrong conclusion that x1 >= 0 */ if (fabs(a[k]) < 1e-6) *ll = -DBL_MAX, *uu = +DBL_MAX; else #endif if (a[k] > 0.0) { *ll = (ilb == -DBL_MAX ? -DBL_MAX : ilb / a[k]); *uu = (iub == +DBL_MAX ? +DBL_MAX : iub / a[k]); } else if (a[k] < 0.0) { *ll = (iub == +DBL_MAX ? -DBL_MAX : iub / a[k]); *uu = (ilb == -DBL_MAX ? +DBL_MAX : ilb / a[k]); } else xassert(a != a); return; } /*********************************************************************** * check_row_bounds - check and relax original row bounds * * Given a row (constraint) * * n * L <= sum a[j] * x[j] <= U * j=1 * * and bounds of columns (variables) * * l[j] <= x[j] <= u[j] * * this routine checks the original row bounds L and U for feasibility * and redundancy. If the original lower bound L or/and upper bound U * cannot be active due to bounds of variables, the routine remove them * replacing by -inf or/and +inf, respectively. * * If no primal infeasibility is detected, the routine returns zero, * otherwise non-zero. */ static int check_row_bounds(const struct f_info *f, double *L_, double *U_) { int ret = 0; double L = *L_, U = *U_, LL, UU; /* determine implied bounds of the row */ row_implied_bounds(f, &LL, &UU); /* check if the original lower bound is infeasible */ if (L != -DBL_MAX) { double eps = 1e-3 * (1.0 + fabs(L)); if (UU < L - eps) { ret = 1; goto done; } } /* check if the original upper bound is infeasible */ if (U != +DBL_MAX) { double eps = 1e-3 * (1.0 + fabs(U)); if (LL > U + eps) { ret = 1; goto done; } } /* check if the original lower bound is redundant */ if (L != -DBL_MAX) { double eps = 1e-12 * (1.0 + fabs(L)); if (LL > L - eps) { /* it cannot be active, so remove it */ *L_ = -DBL_MAX; } } /* check if the original upper bound is redundant */ if (U != +DBL_MAX) { double eps = 1e-12 * (1.0 + fabs(U)); if (UU < U + eps) { /* it cannot be active, so remove it */ *U_ = +DBL_MAX; } } done: return ret; } /*********************************************************************** * check_col_bounds - check and tighten original column bounds * * Given a row (constraint) * * n * L <= sum a[j] * x[j] <= U * j=1 * * and bounds of columns (variables) * * l[j] <= x[j] <= u[j] * * for column (variable) x[j] this routine checks the original column * bounds l[j] and u[j] for feasibility and redundancy. If the original * lower bound l[j] or/and upper bound u[j] cannot be active due to * bounds of the constraint and other variables, the routine tighten * them replacing by corresponding implied bounds, if possible. * * NOTE: It is assumed that if L != -inf, the row lower bound can be * active, and if U != +inf, the row upper bound can be active. * * The flag means that variable x[j] is required to be integer. * * New actual bounds for x[j] are stored in locations lj and uj. * * If no primal infeasibility is detected, the routine returns zero, * otherwise non-zero. */ static int check_col_bounds(const struct f_info *f, int n, const double a[], double L, double U, const double l[], const double u[], int flag, int j, double *_lj, double *_uj) { int ret = 0; double lj, uj, ll, uu; xassert(n >= 0); xassert(1 <= j && j <= n); lj = l[j], uj = u[j]; /* determine implied bounds of the column */ col_implied_bounds(f, n, a, L, U, l, u, j, &ll, &uu); /* if x[j] is integral, round its implied bounds */ if (flag) { if (ll != -DBL_MAX) ll = (ll - floor(ll) < 1e-3 ? floor(ll) : ceil(ll)); if (uu != +DBL_MAX) uu = (ceil(uu) - uu < 1e-3 ? ceil(uu) : floor(uu)); } /* check if the original lower bound is infeasible */ if (lj != -DBL_MAX) { double eps = 1e-3 * (1.0 + fabs(lj)); if (uu < lj - eps) { ret = 1; goto done; } } /* check if the original upper bound is infeasible */ if (uj != +DBL_MAX) { double eps = 1e-3 * (1.0 + fabs(uj)); if (ll > uj + eps) { ret = 1; goto done; } } /* check if the original lower bound is redundant */ if (ll != -DBL_MAX) { double eps = 1e-3 * (1.0 + fabs(ll)); if (lj < ll - eps) { /* it cannot be active, so tighten it */ lj = ll; } } /* check if the original upper bound is redundant */ if (uu != +DBL_MAX) { double eps = 1e-3 * (1.0 + fabs(uu)); if (uj > uu + eps) { /* it cannot be active, so tighten it */ uj = uu; } } /* due to round-off errors it may happen that lj > uj (although lj < uj + eps, since no primal infeasibility is detected), so adjuct the new actual bounds to provide lj <= uj */ if (!(lj == -DBL_MAX || uj == +DBL_MAX)) { double t1 = fabs(lj), t2 = fabs(uj); double eps = 1e-10 * (1.0 + (t1 <= t2 ? t1 : t2)); if (lj > uj - eps) { if (lj == l[j]) uj = lj; else if (uj == u[j]) lj = uj; else if (t1 <= t2) uj = lj; else lj = uj; } } *_lj = lj, *_uj = uj; done: return ret; } /*********************************************************************** * check_efficiency - check if change in column bounds is efficient * * Given the original bounds of a column l and u and its new actual * bounds l' and u' (possibly tighten by the routine check_col_bounds) * this routine checks if the change in the column bounds is efficient * enough. If so, the routine returns non-zero, otherwise zero. * * The flag means that the variable is required to be integer. */ static int check_efficiency(int flag, double l, double u, double ll, double uu) { int eff = 0; /* check efficiency for lower bound */ if (l < ll) { if (flag || l == -DBL_MAX) eff++; else { double r; if (u == +DBL_MAX) r = 1.0 + fabs(l); else r = 1.0 + (u - l); if (ll - l >= 0.25 * r) eff++; } } /* check efficiency for upper bound */ if (u > uu) { if (flag || u == +DBL_MAX) eff++; else { double r; if (l == -DBL_MAX) r = 1.0 + fabs(u); else r = 1.0 + (u - l); if (u - uu >= 0.25 * r) eff++; } } return eff; } /*********************************************************************** * basic_preprocessing - perform basic preprocessing * * This routine performs basic preprocessing of the specified MIP that * includes relaxing some row bounds and tightening some column bounds. * * On entry the arrays L and U contains original row bounds, and the * arrays l and u contains original column bounds: * * L[0] is the lower bound of the objective row; * L[i], i = 1,...,m, is the lower bound of i-th row; * U[0] is the upper bound of the objective row; * U[i], i = 1,...,m, is the upper bound of i-th row; * l[0] is not used; * l[j], j = 1,...,n, is the lower bound of j-th column; * u[0] is not used; * u[j], j = 1,...,n, is the upper bound of j-th column. * * On exit the arrays L, U, l, and u contain new actual bounds of rows * and column in the same locations. * * The parameters nrs and num specify an initial list of rows to be * processed: * * nrs is the number of rows in the initial list, 0 <= nrs <= m+1; * num[0] is not used; * num[1,...,nrs] are row numbers (0 means the objective row). * * The parameter max_pass specifies the maximal number of times that * each row can be processed, max_pass > 0. * * If no primal infeasibility is detected, the routine returns zero, * otherwise non-zero. */ static int basic_preprocessing(glp_prob *mip, double L[], double U[], double l[], double u[], int nrs, const int num[], int max_pass) { int m = mip->m; int n = mip->n; struct f_info f; int i, j, k, len, size, ret = 0; int *ind, *list, *mark, *pass; double *val, *lb, *ub; xassert(0 <= nrs && nrs <= m+1); xassert(max_pass > 0); /* allocate working arrays */ ind = xcalloc(1+n, sizeof(int)); list = xcalloc(1+m+1, sizeof(int)); mark = xcalloc(1+m+1, sizeof(int)); memset(&mark[0], 0, (m+1) * sizeof(int)); pass = xcalloc(1+m+1, sizeof(int)); memset(&pass[0], 0, (m+1) * sizeof(int)); val = xcalloc(1+n, sizeof(double)); lb = xcalloc(1+n, sizeof(double)); ub = xcalloc(1+n, sizeof(double)); /* initialize the list of rows to be processed */ size = 0; for (k = 1; k <= nrs; k++) { i = num[k]; xassert(0 <= i && i <= m); /* duplicate row numbers are not allowed */ xassert(!mark[i]); list[++size] = i, mark[i] = 1; } xassert(size == nrs); /* process rows in the list until it becomes empty */ while (size > 0) { /* get a next row from the list */ i = list[size--], mark[i] = 0; /* increase the row processing count */ pass[i]++; /* if the row is free, skip it */ if (L[i] == -DBL_MAX && U[i] == +DBL_MAX) continue; /* obtain coefficients of the row */ len = 0; if (i == 0) { for (j = 1; j <= n; j++) { GLPCOL *col = mip->col[j]; if (col->coef != 0.0) len++, ind[len] = j, val[len] = col->coef; } } else { GLPROW *row = mip->row[i]; GLPAIJ *aij; for (aij = row->ptr; aij != NULL; aij = aij->r_next) len++, ind[len] = aij->col->j, val[len] = aij->val; } /* determine lower and upper bounds of columns corresponding to non-zero row coefficients */ for (k = 1; k <= len; k++) j = ind[k], lb[k] = l[j], ub[k] = u[j]; /* prepare the row info to determine implied bounds */ prepare_row_info(len, val, lb, ub, &f); /* check and relax bounds of the row */ if (check_row_bounds(&f, &L[i], &U[i])) { /* the feasible region is empty */ ret = 1; goto done; } /* if the row became free, drop it */ if (L[i] == -DBL_MAX && U[i] == +DBL_MAX) continue; /* process columns having non-zero coefficients in the row */ for (k = 1; k <= len; k++) { GLPCOL *col; int flag, eff; double ll, uu; /* take a next column in the row */ j = ind[k], col = mip->col[j]; flag = col->kind != GLP_CV; /* check and tighten bounds of the column */ if (check_col_bounds(&f, len, val, L[i], U[i], lb, ub, flag, k, &ll, &uu)) { /* the feasible region is empty */ ret = 1; goto done; } /* check if change in the column bounds is efficient */ eff = check_efficiency(flag, l[j], u[j], ll, uu); /* set new actual bounds of the column */ l[j] = ll, u[j] = uu; /* if the change is efficient, add all rows affected by the corresponding column, to the list */ if (eff > 0) { GLPAIJ *aij; for (aij = col->ptr; aij != NULL; aij = aij->c_next) { int ii = aij->row->i; /* if the row was processed maximal number of times, skip it */ if (pass[ii] >= max_pass) continue; /* if the row is free, skip it */ if (L[ii] == -DBL_MAX && U[ii] == +DBL_MAX) continue; /* put the row into the list */ if (mark[ii] == 0) { xassert(size <= m); list[++size] = ii, mark[ii] = 1; } } } } } done: /* free working arrays */ xfree(ind); xfree(list); xfree(mark); xfree(pass); xfree(val); xfree(lb); xfree(ub); return ret; } /*********************************************************************** * NAME * * ios_preprocess_node - preprocess current subproblem * * SYNOPSIS * * #include "glpios.h" * int ios_preprocess_node(glp_tree *tree, int max_pass); * * DESCRIPTION * * The routine ios_preprocess_node performs basic preprocessing of the * current subproblem. * * RETURNS * * If no primal infeasibility is detected, the routine returns zero, * otherwise non-zero. */ int ios_preprocess_node(glp_tree *tree, int max_pass) { glp_prob *mip = tree->mip; int m = mip->m; int n = mip->n; int i, j, nrs, *num, ret = 0; double *L, *U, *l, *u; /* the current subproblem must exist */ xassert(tree->curr != NULL); /* determine original row bounds */ L = xcalloc(1+m, sizeof(double)); U = xcalloc(1+m, sizeof(double)); switch (mip->mip_stat) { case GLP_UNDEF: L[0] = -DBL_MAX, U[0] = +DBL_MAX; break; case GLP_FEAS: switch (mip->dir) { case GLP_MIN: L[0] = -DBL_MAX, U[0] = mip->mip_obj - mip->c0; break; case GLP_MAX: L[0] = mip->mip_obj - mip->c0, U[0] = +DBL_MAX; break; default: xassert(mip != mip); } break; default: xassert(mip != mip); } for (i = 1; i <= m; i++) { L[i] = glp_get_row_lb(mip, i); U[i] = glp_get_row_ub(mip, i); } /* determine original column bounds */ l = xcalloc(1+n, sizeof(double)); u = xcalloc(1+n, sizeof(double)); for (j = 1; j <= n; j++) { l[j] = glp_get_col_lb(mip, j); u[j] = glp_get_col_ub(mip, j); } /* build the initial list of rows to be analyzed */ nrs = m + 1; num = xcalloc(1+nrs, sizeof(int)); for (i = 1; i <= nrs; i++) num[i] = i - 1; /* perform basic preprocessing */ if (basic_preprocessing(mip , L, U, l, u, nrs, num, max_pass)) { ret = 1; goto done; } /* set new actual (relaxed) row bounds */ for (i = 1; i <= m; i++) { /* consider only non-active rows to keep dual feasibility */ if (glp_get_row_stat(mip, i) == GLP_BS) { if (L[i] == -DBL_MAX && U[i] == +DBL_MAX) glp_set_row_bnds(mip, i, GLP_FR, 0.0, 0.0); else if (U[i] == +DBL_MAX) glp_set_row_bnds(mip, i, GLP_LO, L[i], 0.0); else if (L[i] == -DBL_MAX) glp_set_row_bnds(mip, i, GLP_UP, 0.0, U[i]); } } /* set new actual (tightened) column bounds */ for (j = 1; j <= n; j++) { int type; if (l[j] == -DBL_MAX && u[j] == +DBL_MAX) type = GLP_FR; else if (u[j] == +DBL_MAX) type = GLP_LO; else if (l[j] == -DBL_MAX) type = GLP_UP; else if (l[j] != u[j]) type = GLP_DB; else type = GLP_FX; glp_set_col_bnds(mip, j, type, l[j], u[j]); } done: /* free working arrays and return */ xfree(L); xfree(U); xfree(l); xfree(u); xfree(num); return ret; } /* eof */ praat-6.0.04/external/glpk/glpios03.c000066400000000000000000001243101261542461700173040ustar00rootroot00000000000000/* glpios03.c (branch-and-cut driver) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpios.h" /*********************************************************************** * show_progress - display current progress of the search * * This routine displays some information about current progress of the * search. * * The information includes: * * the current number of iterations performed by the simplex solver; * * the objective value for the best known integer feasible solution, * which is upper (minimization) or lower (maximization) global bound * for optimal solution of the original mip problem; * * the best local bound for active nodes, which is lower (minimization) * or upper (maximization) global bound for optimal solution of the * original mip problem; * * the relative mip gap, in percents; * * the number of open (active) subproblems; * * the number of completely explored subproblems, i.e. whose nodes have * been removed from the tree. */ static void show_progress(glp_tree *T, int bingo) { int p; double temp; char best_mip[50], best_bound[50], *rho, rel_gap[50]; /* format the best known integer feasible solution */ if (T->mip->mip_stat == GLP_FEAS) sprintf(best_mip, "%17.9e", T->mip->mip_obj); else sprintf(best_mip, "%17s", "not found yet"); /* determine reference number of an active subproblem whose local bound is best */ p = ios_best_node(T); /* format the best bound */ if (p == 0) sprintf(best_bound, "%17s", "tree is empty"); else { temp = T->slot[p].node->bound; if (temp == -DBL_MAX) sprintf(best_bound, "%17s", "-inf"); else if (temp == +DBL_MAX) sprintf(best_bound, "%17s", "+inf"); else sprintf(best_bound, "%17.9e", temp); } /* choose the relation sign between global bounds */ if (T->mip->dir == GLP_MIN) rho = ">="; else if (T->mip->dir == GLP_MAX) rho = "<="; else xassert(T != T); /* format the relative mip gap */ temp = ios_relative_gap(T); if (temp == 0.0) sprintf(rel_gap, " 0.0%%"); else if (temp < 0.001) sprintf(rel_gap, "< 0.1%%"); else if (temp <= 9.999) sprintf(rel_gap, "%5.1f%%", 100.0 * temp); else sprintf(rel_gap, "%6s", ""); /* display progress of the search */ xprintf("+%6d: %s %s %s %s %s (%d; %d)\n", T->mip->it_cnt, bingo ? ">>>>>" : "mip =", best_mip, rho, best_bound, rel_gap, T->a_cnt, T->t_cnt - T->n_cnt); T->tm_lag = xtime(); return; } /*********************************************************************** * is_branch_hopeful - check if specified branch is hopeful * * This routine checks if the specified subproblem can have an integer * optimal solution which is better than the best known one. * * The check is based on comparison of the local objective bound stored * in the subproblem descriptor and the incumbent objective value which * is the global objective bound. * * If there is a chance that the specified subproblem can have a better * integer optimal solution, the routine returns non-zero. Otherwise, if * the corresponding branch can pruned, zero is returned. */ static int is_branch_hopeful(glp_tree *T, int p) { xassert(1 <= p && p <= T->nslots); xassert(T->slot[p].node != NULL); return ios_is_hopeful(T, T->slot[p].node->bound); } /*********************************************************************** * check_integrality - check integrality of basic solution * * This routine checks if the basic solution of LP relaxation of the * current subproblem satisfies to integrality conditions, i.e. that all * variables of integer kind have integral primal values. (The solution * is assumed to be optimal.) * * For each variable of integer kind the routine computes the following * quantity: * * ii(x[j]) = min(x[j] - floor(x[j]), ceil(x[j]) - x[j]), (1) * * which is a measure of the integer infeasibility (non-integrality) of * x[j] (for example, ii(2.1) = 0.1, ii(3.7) = 0.3, ii(5.0) = 0). It is * understood that 0 <= ii(x[j]) <= 0.5, and variable x[j] is integer * feasible if ii(x[j]) = 0. However, due to floating-point arithmetic * the routine checks less restrictive condition: * * ii(x[j]) <= tol_int, (2) * * where tol_int is a given tolerance (small positive number) and marks * each variable which does not satisfy to (2) as integer infeasible by * setting its fractionality flag. * * In order to characterize integer infeasibility of the basic solution * in the whole the routine computes two parameters: ii_cnt, which is * the number of variables with the fractionality flag set, and ii_sum, * which is the sum of integer infeasibilities (1). */ static void check_integrality(glp_tree *T) { glp_prob *mip = T->mip; int j, type, ii_cnt = 0; double lb, ub, x, temp1, temp2, ii_sum = 0.0; /* walk through the set of columns (structural variables) */ for (j = 1; j <= mip->n; j++) { GLPCOL *col = mip->col[j]; T->non_int[j] = 0; /* if the column is not integer, skip it */ if (col->kind != GLP_IV) continue; /* if the column is non-basic, it is integer feasible */ if (col->stat != GLP_BS) continue; /* obtain the type and bounds of the column */ type = col->type, lb = col->lb, ub = col->ub; /* obtain value of the column in optimal basic solution */ x = col->prim; /* if the column's primal value is close to the lower bound, the column is integer feasible within given tolerance */ if (type == GLP_LO || type == GLP_DB || type == GLP_FX) { temp1 = lb - T->parm->tol_int; temp2 = lb + T->parm->tol_int; if (temp1 <= x && x <= temp2) continue; #if 0 /* the lower bound must not be violated */ xassert(x >= lb); #else if (x < lb) continue; #endif } /* if the column's primal value is close to the upper bound, the column is integer feasible within given tolerance */ if (type == GLP_UP || type == GLP_DB || type == GLP_FX) { temp1 = ub - T->parm->tol_int; temp2 = ub + T->parm->tol_int; if (temp1 <= x && x <= temp2) continue; #if 0 /* the upper bound must not be violated */ xassert(x <= ub); #else if (x > ub) continue; #endif } /* if the column's primal value is close to nearest integer, the column is integer feasible within given tolerance */ temp1 = floor(x + 0.5) - T->parm->tol_int; temp2 = floor(x + 0.5) + T->parm->tol_int; if (temp1 <= x && x <= temp2) continue; /* otherwise the column is integer infeasible */ T->non_int[j] = 1; /* increase the number of fractional-valued columns */ ii_cnt++; /* compute the sum of integer infeasibilities */ temp1 = x - floor(x); temp2 = ceil(x) - x; xassert(temp1 > 0.0 && temp2 > 0.0); ii_sum += (temp1 <= temp2 ? temp1 : temp2); } /* store ii_cnt and ii_sum to the current problem descriptor */ xassert(T->curr != NULL); T->curr->ii_cnt = ii_cnt; T->curr->ii_sum = ii_sum; /* and also display these parameters */ if (T->parm->msg_lev >= GLP_MSG_DBG) { if (ii_cnt == 0) xprintf("There are no fractional columns\n"); else if (ii_cnt == 1) xprintf("There is one fractional column, integer infeasibil" "ity is %.3e\n", ii_sum); else xprintf("There are %d fractional columns, integer infeasibi" "lity is %.3e\n", ii_cnt, ii_sum); } return; } /*********************************************************************** * record_solution - record better integer feasible solution * * This routine records optimal basic solution of LP relaxation of the * current subproblem, which being integer feasible is better than the * best known integer feasible solution. */ static void record_solution(glp_tree *T) { glp_prob *mip = T->mip; int i, j; mip->mip_stat = GLP_FEAS; mip->mip_obj = mip->obj_val; for (i = 1; i <= mip->m; i++) { GLPROW *row = mip->row[i]; row->mipx = row->prim; } for (j = 1; j <= mip->n; j++) { GLPCOL *col = mip->col[j]; if (col->kind == GLP_CV) col->mipx = col->prim; else if (col->kind == GLP_IV) { /* value of the integer column must be integral */ col->mipx = floor(col->prim + 0.5); } else xassert(col != col); } T->sol_cnt++; return; } /*********************************************************************** * fix_by_red_cost - fix non-basic integer columns by reduced costs * * This routine fixes some non-basic integer columns if their reduced * costs indicate that increasing (decreasing) the column at least by * one involves the objective value becoming worse than the incumbent * objective value. */ static void fix_by_red_cost(glp_tree *T) { glp_prob *mip = T->mip; int j, stat, fixed = 0; double obj, lb, ub, dj; /* the global bound must exist */ xassert(T->mip->mip_stat == GLP_FEAS); /* basic solution of LP relaxation must be optimal */ xassert(mip->pbs_stat == GLP_FEAS && mip->dbs_stat == GLP_FEAS); /* determine the objective function value */ obj = mip->obj_val; /* walk through the column list */ for (j = 1; j <= mip->n; j++) { GLPCOL *col = mip->col[j]; /* if the column is not integer, skip it */ if (col->kind != GLP_IV) continue; /* obtain bounds of j-th column */ lb = col->lb, ub = col->ub; /* and determine its status and reduced cost */ stat = col->stat, dj = col->dual; /* analyze the reduced cost */ switch (mip->dir) { case GLP_MIN: /* minimization */ if (stat == GLP_NL) { /* j-th column is non-basic on its lower bound */ if (dj < 0.0) dj = 0.0; if (obj + dj >= mip->mip_obj) glp_set_col_bnds(mip, j, GLP_FX, lb, lb), fixed++; } else if (stat == GLP_NU) { /* j-th column is non-basic on its upper bound */ if (dj > 0.0) dj = 0.0; if (obj - dj >= mip->mip_obj) glp_set_col_bnds(mip, j, GLP_FX, ub, ub), fixed++; } break; case GLP_MAX: /* maximization */ if (stat == GLP_NL) { /* j-th column is non-basic on its lower bound */ if (dj > 0.0) dj = 0.0; if (obj + dj <= mip->mip_obj) glp_set_col_bnds(mip, j, GLP_FX, lb, lb), fixed++; } else if (stat == GLP_NU) { /* j-th column is non-basic on its upper bound */ if (dj < 0.0) dj = 0.0; if (obj - dj <= mip->mip_obj) glp_set_col_bnds(mip, j, GLP_FX, ub, ub), fixed++; } break; default: xassert(T != T); } } if (T->parm->msg_lev >= GLP_MSG_DBG) { if (fixed == 0) /* nothing to say */; else if (fixed == 1) xprintf("One column has been fixed by reduced cost\n"); else xprintf("%d columns have been fixed by reduced costs\n", fixed); } /* fixing non-basic columns on their current bounds does not change the basic solution */ xassert(mip->pbs_stat == GLP_FEAS && mip->dbs_stat == GLP_FEAS); return; } /*********************************************************************** * branch_on - perform branching on specified variable * * This routine performs branching on j-th column (structural variable) * of the current subproblem. The specified column must be of integer * kind and must have a fractional value in optimal basic solution of * LP relaxation of the current subproblem (i.e. only columns for which * the flag non_int[j] is set are valid candidates to branch on). * * Let x be j-th structural variable, and beta be its primal fractional * value in the current basic solution. Branching on j-th variable is * dividing the current subproblem into two new subproblems, which are * identical to the current subproblem with the following exception: in * the first subproblem that begins the down-branch x has a new upper * bound x <= floor(beta), and in the second subproblem that begins the * up-branch x has a new lower bound x >= ceil(beta). * * Depending on estimation of local bounds for down- and up-branches * this routine returns the following: * * 0 - both branches have been created; * 1 - one branch is hopeless and has been pruned, so now the current * subproblem is other branch; * 2 - both branches are hopeless and have been pruned; new subproblem * selection is needed to continue the search. */ static int branch_on(glp_tree *T, int j, int next) { glp_prob *mip = T->mip; IOSNPD *node; int m = mip->m; int n = mip->n; int type, dn_type, up_type, dn_bad, up_bad, p, ret, clone[1+2]; double lb, ub, beta, new_ub, new_lb, dn_lp, up_lp, dn_bnd, up_bnd; /* determine bounds and value of x[j] in optimal solution to LP relaxation of the current subproblem */ xassert(1 <= j && j <= n); type = mip->col[j]->type; lb = mip->col[j]->lb; ub = mip->col[j]->ub; beta = mip->col[j]->prim; /* determine new bounds of x[j] for down- and up-branches */ new_ub = floor(beta); new_lb = ceil(beta); switch (type) { case GLP_FR: dn_type = GLP_UP; up_type = GLP_LO; break; case GLP_LO: xassert(lb <= new_ub); dn_type = (lb == new_ub ? GLP_FX : GLP_DB); xassert(lb + 1.0 <= new_lb); up_type = GLP_LO; break; case GLP_UP: xassert(new_ub <= ub - 1.0); dn_type = GLP_UP; xassert(new_lb <= ub); up_type = (new_lb == ub ? GLP_FX : GLP_DB); break; case GLP_DB: xassert(lb <= new_ub && new_ub <= ub - 1.0); dn_type = (lb == new_ub ? GLP_FX : GLP_DB); xassert(lb + 1.0 <= new_lb && new_lb <= ub); up_type = (new_lb == ub ? GLP_FX : GLP_DB); break; default: xassert(type != type); } /* compute local bounds to LP relaxation for both branches */ ios_eval_degrad(T, j, &dn_lp, &up_lp); /* and improve them by rounding */ dn_bnd = ios_round_bound(T, dn_lp); up_bnd = ios_round_bound(T, up_lp); /* check local bounds for down- and up-branches */ dn_bad = !ios_is_hopeful(T, dn_bnd); up_bad = !ios_is_hopeful(T, up_bnd); if (dn_bad && up_bad) { if (T->parm->msg_lev >= GLP_MSG_DBG) xprintf("Both down- and up-branches are hopeless\n"); ret = 2; goto done; } else if (up_bad) { if (T->parm->msg_lev >= GLP_MSG_DBG) xprintf("Up-branch is hopeless\n"); glp_set_col_bnds(mip, j, dn_type, lb, new_ub); T->curr->lp_obj = dn_lp; if (mip->dir == GLP_MIN) { if (T->curr->bound < dn_bnd) T->curr->bound = dn_bnd; } else if (mip->dir == GLP_MAX) { if (T->curr->bound > dn_bnd) T->curr->bound = dn_bnd; } else xassert(mip != mip); ret = 1; goto done; } else if (dn_bad) { if (T->parm->msg_lev >= GLP_MSG_DBG) xprintf("Down-branch is hopeless\n"); glp_set_col_bnds(mip, j, up_type, new_lb, ub); T->curr->lp_obj = up_lp; if (mip->dir == GLP_MIN) { if (T->curr->bound < up_bnd) T->curr->bound = up_bnd; } else if (mip->dir == GLP_MAX) { if (T->curr->bound > up_bnd) T->curr->bound = up_bnd; } else xassert(mip != mip); ret = 1; goto done; } /* both down- and up-branches seem to be hopeful */ if (T->parm->msg_lev >= GLP_MSG_DBG) xprintf("Branching on column %d, primal value is %.9e\n", j, beta); /* determine the reference number of the current subproblem */ xassert(T->curr != NULL); p = T->curr->p; T->curr->br_var = j; T->curr->br_val = beta; /* freeze the current subproblem */ ios_freeze_node(T); /* create two clones of the current subproblem; the first clone begins the down-branch, the second one begins the up-branch */ ios_clone_node(T, p, 2, clone); if (T->parm->msg_lev >= GLP_MSG_DBG) xprintf("Node %d begins down branch, node %d begins up branch " "\n", clone[1], clone[2]); /* set new upper bound of j-th column in the down-branch */ node = T->slot[clone[1]].node; xassert(node != NULL); xassert(node->up != NULL); xassert(node->b_ptr == NULL); node->b_ptr = dmp_get_atom(T->pool, sizeof(IOSBND)); node->b_ptr->k = m + j; node->b_ptr->type = (unsigned char)dn_type; node->b_ptr->lb = lb; node->b_ptr->ub = new_ub; node->b_ptr->next = NULL; node->lp_obj = dn_lp; if (mip->dir == GLP_MIN) { if (node->bound < dn_bnd) node->bound = dn_bnd; } else if (mip->dir == GLP_MAX) { if (node->bound > dn_bnd) node->bound = dn_bnd; } else xassert(mip != mip); /* set new lower bound of j-th column in the up-branch */ node = T->slot[clone[2]].node; xassert(node != NULL); xassert(node->up != NULL); xassert(node->b_ptr == NULL); node->b_ptr = dmp_get_atom(T->pool, sizeof(IOSBND)); node->b_ptr->k = m + j; node->b_ptr->type = (unsigned char)up_type; node->b_ptr->lb = new_lb; node->b_ptr->ub = ub; node->b_ptr->next = NULL; node->lp_obj = up_lp; if (mip->dir == GLP_MIN) { if (node->bound < up_bnd) node->bound = up_bnd; } else if (mip->dir == GLP_MAX) { if (node->bound > up_bnd) node->bound = up_bnd; } else xassert(mip != mip); /* suggest the subproblem to be solved next */ xassert(T->child == 0); if (next == GLP_NO_BRNCH) T->child = 0; else if (next == GLP_DN_BRNCH) T->child = clone[1]; else if (next == GLP_UP_BRNCH) T->child = clone[2]; else xassert(next != next); ret = 0; done: return ret; } /*********************************************************************** * cleanup_the_tree - prune hopeless branches from the tree * * This routine walks through the active list and checks the local * bound for every active subproblem. If the local bound indicates that * the subproblem cannot have integer optimal solution better than the * incumbent objective value, the routine deletes such subproblem that, * in turn, involves pruning the corresponding branch of the tree. */ static void cleanup_the_tree(glp_tree *T) { IOSNPD *node, *next_node; int count = 0; /* the global bound must exist */ xassert(T->mip->mip_stat == GLP_FEAS); /* walk through the list of active subproblems */ for (node = T->head; node != NULL; node = next_node) { /* deleting some active problem node may involve deleting its parents recursively; however, all its parents being created *before* it are always *precede* it in the node list, so the next problem node is never affected by such deletion */ next_node = node->next; /* if the branch is hopeless, prune it */ if (!is_branch_hopeful(T, node->p)) ios_delete_node(T, node->p), count++; } if (T->parm->msg_lev >= GLP_MSG_DBG) { if (count == 1) xprintf("One hopeless branch has been pruned\n"); else if (count > 1) xprintf("%d hopeless branches have been pruned\n", count); } return; } /**********************************************************************/ static void generate_cuts(glp_tree *T) { /* generate generic cuts with built-in generators */ if (!(T->parm->mir_cuts == GLP_ON || T->parm->gmi_cuts == GLP_ON || T->parm->cov_cuts == GLP_ON || T->parm->clq_cuts == GLP_ON)) goto done; #if 1 /* 20/IX-2008 */ { int i, max_cuts, added_cuts; max_cuts = T->n; if (max_cuts < 1000) max_cuts = 1000; added_cuts = 0; for (i = T->orig_m+1; i <= T->mip->m; i++) { if (T->mip->row[i]->origin == GLP_RF_CUT) added_cuts++; } /* xprintf("added_cuts = %d\n", added_cuts); */ if (added_cuts >= max_cuts) goto done; } #endif /* generate and add to POOL all cuts violated by x* */ if (T->parm->gmi_cuts == GLP_ON) { if (T->curr->changed < 5) ios_gmi_gen(T); } if (T->parm->mir_cuts == GLP_ON) { xassert(T->mir_gen != NULL); ios_mir_gen(T, T->mir_gen); } if (T->parm->cov_cuts == GLP_ON) { /* cover cuts works well along with mir cuts */ /*if (T->round <= 5)*/ ios_cov_gen(T); } if (T->parm->clq_cuts == GLP_ON) { if (T->clq_gen != NULL) { if (T->curr->level == 0 && T->curr->changed < 50 || T->curr->level > 0 && T->curr->changed < 5) ios_clq_gen(T, T->clq_gen); } } done: return; } /**********************************************************************/ static void remove_cuts(glp_tree *T) { /* remove inactive cuts (some valueable globally valid cut might be saved in the global cut pool) */ int i, cnt = 0, *num = NULL; xassert(T->curr != NULL); for (i = T->orig_m+1; i <= T->mip->m; i++) { if (T->mip->row[i]->origin == GLP_RF_CUT && T->mip->row[i]->level == T->curr->level && T->mip->row[i]->stat == GLP_BS) { if (num == NULL) num = xcalloc(1+T->mip->m, sizeof(int)); num[++cnt] = i; } } if (cnt > 0) { glp_del_rows(T->mip, cnt, num); #if 0 xprintf("%d inactive cut(s) removed\n", cnt); #endif xfree(num); xassert(glp_factorize(T->mip) == 0); } return; } /**********************************************************************/ static void display_cut_info(glp_tree *T) { glp_prob *mip = T->mip; int i, gmi = 0, mir = 0, cov = 0, clq = 0, app = 0; for (i = mip->m; i > 0; i--) { GLPROW *row; row = mip->row[i]; /* if (row->level < T->curr->level) break; */ if (row->origin == GLP_RF_CUT) { if (row->klass == GLP_RF_GMI) gmi++; else if (row->klass == GLP_RF_MIR) mir++; else if (row->klass == GLP_RF_COV) cov++; else if (row->klass == GLP_RF_CLQ) clq++; else app++; } } xassert(T->curr != NULL); if (gmi + mir + cov + clq + app > 0) { xprintf("Cuts on level %d:", T->curr->level); if (gmi > 0) xprintf(" gmi = %d;", gmi); if (mir > 0) xprintf(" mir = %d;", mir); if (cov > 0) xprintf(" cov = %d;", cov); if (clq > 0) xprintf(" clq = %d;", clq); if (app > 0) xprintf(" app = %d;", app); xprintf("\n"); } return; } /*********************************************************************** * NAME * * ios_driver - branch-and-cut driver * * SYNOPSIS * * #include "glpios.h" * int ios_driver(glp_tree *T); * * DESCRIPTION * * The routine ios_driver is a branch-and-cut driver. It controls the * MIP solution process. * * RETURNS * * 0 The MIP problem instance has been successfully solved. This code * does not necessarily mean that the solver has found optimal * solution. It only means that the solution process was successful. * * GLP_EFAIL * The search was prematurely terminated due to the solver failure. * * GLP_EMIPGAP * The search was prematurely terminated, because the relative mip * gap tolerance has been reached. * * GLP_ETMLIM * The search was prematurely terminated, because the time limit has * been exceeded. * * GLP_ESTOP * The search was prematurely terminated by application. */ int ios_driver(glp_tree *T) { int p, curr_p, p_stat, d_stat, ret; #if 1 /* carry out to glp_tree */ int pred_p = 0; /* if the current subproblem has been just created due to branching, pred_p is the reference number of its parent subproblem, otherwise pred_p is zero */ #endif glp_long ttt = T->tm_beg; #if 0 ((glp_iocp *)T->parm)->msg_lev = GLP_MSG_DBG; #endif /* on entry to the B&B driver it is assumed that the active list contains the only active (i.e. root) subproblem, which is the original MIP problem to be solved */ loop: /* main loop starts here */ /* at this point the current subproblem does not exist */ xassert(T->curr == NULL); /* if the active list is empty, the search is finished */ if (T->head == NULL) { if (T->parm->msg_lev >= GLP_MSG_DBG) xprintf("Active list is empty!\n"); xassert(dmp_in_use(T->pool).lo == 0); ret = 0; goto done; } /* select some active subproblem to continue the search */ xassert(T->next_p == 0); /* let the application program select subproblem */ if (T->parm->cb_func != NULL) { xassert(T->reason == 0); T->reason = GLP_ISELECT; T->parm->cb_func(T, T->parm->cb_info); T->reason = 0; if (T->stop) { ret = GLP_ESTOP; goto done; } } if (T->next_p != 0) { /* the application program has selected something */ ; } else if (T->a_cnt == 1) { /* the only active subproblem exists, so select it */ xassert(T->head->next == NULL); T->next_p = T->head->p; } else if (T->child != 0) { /* select one of branching childs suggested by the branching heuristic */ T->next_p = T->child; } else { /* select active subproblem as specified by the backtracking technique option */ T->next_p = ios_choose_node(T); } /* the active subproblem just selected becomes current */ ios_revive_node(T, T->next_p); T->next_p = T->child = 0; /* invalidate pred_p, if it is not the reference number of the parent of the current subproblem */ if (T->curr->up != NULL && T->curr->up->p != pred_p) pred_p = 0; /* determine the reference number of the current subproblem */ p = T->curr->p; if (T->parm->msg_lev >= GLP_MSG_DBG) { xprintf("-----------------------------------------------------" "-------------------\n"); xprintf("Processing node %d at level %d\n", p, T->curr->level); } /* if it is the root subproblem, initialize cut generators */ if (p == 1) { if (T->parm->gmi_cuts == GLP_ON) { if (T->parm->msg_lev >= GLP_MSG_ALL) xprintf("Gomory's cuts enabled\n"); } if (T->parm->mir_cuts == GLP_ON) { if (T->parm->msg_lev >= GLP_MSG_ALL) xprintf("MIR cuts enabled\n"); xassert(T->mir_gen == NULL); T->mir_gen = ios_mir_init(T); } if (T->parm->cov_cuts == GLP_ON) { if (T->parm->msg_lev >= GLP_MSG_ALL) xprintf("Cover cuts enabled\n"); } if (T->parm->clq_cuts == GLP_ON) { xassert(T->clq_gen == NULL); if (T->parm->msg_lev >= GLP_MSG_ALL) xprintf("Clique cuts enabled\n"); T->clq_gen = ios_clq_init(T); } } more: /* minor loop starts here */ /* at this point the current subproblem needs either to be solved for the first time or re-optimized due to reformulation */ /* display current progress of the search */ if (T->parm->msg_lev >= GLP_MSG_DBG || T->parm->msg_lev >= GLP_MSG_ON && (double)(T->parm->out_frq - 1) <= 1000.0 * xdifftime(xtime(), T->tm_lag)) show_progress(T, 0); if (T->parm->msg_lev >= GLP_MSG_ALL && xdifftime(xtime(), ttt) >= 60.0) { glp_long total; glp_mem_usage(NULL, NULL, &total, NULL); xprintf("Time used: %.1f secs. Memory used: %.1f Mb.\n", xdifftime(xtime(), T->tm_beg), xltod(total) / 1048576.0); ttt = xtime(); } /* check the mip gap */ if (T->parm->mip_gap > 0.0 && ios_relative_gap(T) <= T->parm->mip_gap) { if (T->parm->msg_lev >= GLP_MSG_DBG) xprintf("Relative gap tolerance reached; search terminated " "\n"); ret = GLP_EMIPGAP; goto done; } /* check if the time limit has been exhausted */ if (T->parm->tm_lim < INT_MAX && (double)(T->parm->tm_lim - 1) <= 1000.0 * xdifftime(xtime(), T->tm_beg)) { if (T->parm->msg_lev >= GLP_MSG_DBG) xprintf("Time limit exhausted; search terminated\n"); ret = GLP_ETMLIM; goto done; } /* let the application program preprocess the subproblem */ if (T->parm->cb_func != NULL) { xassert(T->reason == 0); T->reason = GLP_IPREPRO; T->parm->cb_func(T, T->parm->cb_info); T->reason = 0; if (T->stop) { ret = GLP_ESTOP; goto done; } } /* perform basic preprocessing */ if (T->parm->pp_tech == GLP_PP_NONE) ; else if (T->parm->pp_tech == GLP_PP_ROOT) { if (T->curr->level == 0) { if (ios_preprocess_node(T, 100)) goto fath; } } else if (T->parm->pp_tech == GLP_PP_ALL) { if (ios_preprocess_node(T, T->curr->level == 0 ? 100 : 10)) goto fath; } else xassert(T != T); /* preprocessing may improve the global bound */ if (!is_branch_hopeful(T, p)) { xprintf("*** not tested yet ***\n"); goto fath; } /* solve LP relaxation of the current subproblem */ if (T->parm->msg_lev >= GLP_MSG_DBG) xprintf("Solving LP relaxation...\n"); ret = ios_solve_node(T); if (!(ret == 0 || ret == GLP_EOBJLL || ret == GLP_EOBJUL)) { if (T->parm->msg_lev >= GLP_MSG_ERR) xprintf("ios_driver: unable to solve current LP relaxation;" " glp_simplex returned %d\n", ret); ret = GLP_EFAIL; goto done; } /* analyze status of the basic solution to LP relaxation found */ p_stat = T->mip->pbs_stat; d_stat = T->mip->dbs_stat; if (p_stat == GLP_FEAS && d_stat == GLP_FEAS) { /* LP relaxation has optimal solution */ if (T->parm->msg_lev >= GLP_MSG_DBG) xprintf("Found optimal solution to LP relaxation\n"); } else if (d_stat == GLP_NOFEAS) { /* LP relaxation has no dual feasible solution */ /* since the current subproblem cannot have a larger feasible region than its parent, there is something wrong */ if (T->parm->msg_lev >= GLP_MSG_ERR) xprintf("ios_driver: current LP relaxation has no dual feas" "ible solution\n"); ret = GLP_EFAIL; goto done; } else if (p_stat == GLP_INFEAS && d_stat == GLP_FEAS) { /* LP relaxation has no primal solution which is better than the incumbent objective value */ xassert(T->mip->mip_stat == GLP_FEAS); if (T->parm->msg_lev >= GLP_MSG_DBG) xprintf("LP relaxation has no solution better than incumben" "t objective value\n"); /* prune the branch */ goto fath; } else if (p_stat == GLP_NOFEAS) { /* LP relaxation has no primal feasible solution */ if (T->parm->msg_lev >= GLP_MSG_DBG) xprintf("LP relaxation has no feasible solution\n"); /* prune the branch */ goto fath; } else { /* other cases cannot appear */ xassert(T->mip != T->mip); } /* at this point basic solution to LP relaxation of the current subproblem is optimal */ xassert(p_stat == GLP_FEAS && d_stat == GLP_FEAS); xassert(T->curr != NULL); T->curr->lp_obj = T->mip->obj_val; /* thus, it defines a local bound to integer optimal solution of the current subproblem */ { double bound = T->mip->obj_val; /* some local bound to the current subproblem could be already set before, so we should only improve it */ bound = ios_round_bound(T, bound); if (T->mip->dir == GLP_MIN) { if (T->curr->bound < bound) T->curr->bound = bound; } else if (T->mip->dir == GLP_MAX) { if (T->curr->bound > bound) T->curr->bound = bound; } else xassert(T->mip != T->mip); if (T->parm->msg_lev >= GLP_MSG_DBG) xprintf("Local bound is %.9e\n", bound); } /* if the local bound indicates that integer optimal solution of the current subproblem cannot be better than the global bound, prune the branch */ if (!is_branch_hopeful(T, p)) { if (T->parm->msg_lev >= GLP_MSG_DBG) xprintf("Current branch is hopeless and can be pruned\n"); goto fath; } /* let the application program generate additional rows ("lazy" constraints) */ xassert(T->reopt == 0); xassert(T->reinv == 0); if (T->parm->cb_func != NULL) { xassert(T->reason == 0); T->reason = GLP_IROWGEN; T->parm->cb_func(T, T->parm->cb_info); T->reason = 0; if (T->stop) { ret = GLP_ESTOP; goto done; } if (T->reopt) { /* some rows were added; re-optimization is needed */ T->reopt = T->reinv = 0; goto more; } if (T->reinv) { /* no rows were added, however, some inactive rows were removed */ T->reinv = 0; xassert(glp_factorize(T->mip) == 0); } } /* check if the basic solution is integer feasible */ check_integrality(T); /* if the basic solution satisfies to all integrality conditions, it is a new, better integer feasible solution */ if (T->curr->ii_cnt == 0) { if (T->parm->msg_lev >= GLP_MSG_DBG) xprintf("New integer feasible solution found\n"); if (T->parm->msg_lev >= GLP_MSG_ALL) display_cut_info(T); record_solution(T); if (T->parm->msg_lev >= GLP_MSG_ON) show_progress(T, 1); /* make the application program happy */ if (T->parm->cb_func != NULL) { xassert(T->reason == 0); T->reason = GLP_IBINGO; T->parm->cb_func(T, T->parm->cb_info); T->reason = 0; if (T->stop) { ret = GLP_ESTOP; goto done; } } /* since the current subproblem has been fathomed, prune its branch */ goto fath; } /* at this point basic solution to LP relaxation of the current subproblem is optimal, but integer infeasible */ /* try to fix some non-basic structural variables of integer kind on their current bounds due to reduced costs */ if (T->mip->mip_stat == GLP_FEAS) fix_by_red_cost(T); /* let the application program try to find some solution to the original MIP with a primal heuristic */ if (T->parm->cb_func != NULL) { xassert(T->reason == 0); T->reason = GLP_IHEUR; T->parm->cb_func(T, T->parm->cb_info); T->reason = 0; if (T->stop) { ret = GLP_ESTOP; goto done; } /* check if the current branch became hopeless */ if (!is_branch_hopeful(T, p)) { if (T->parm->msg_lev >= GLP_MSG_DBG) xprintf("Current branch became hopeless and can be prune" "d\n"); goto fath; } } /* try to find solution with the feasibility pump heuristic */ if (T->parm->fp_heur) { xassert(T->reason == 0); T->reason = GLP_IHEUR; ios_feas_pump(T); T->reason = 0; /* check if the current branch became hopeless */ if (!is_branch_hopeful(T, p)) { if (T->parm->msg_lev >= GLP_MSG_DBG) xprintf("Current branch became hopeless and can be prune" "d\n"); goto fath; } } /* it's time to generate cutting planes */ xassert(T->local != NULL); xassert(T->local->size == 0); /* let the application program generate some cuts; note that it can add cuts either to the local cut pool or directly to the current subproblem */ if (T->parm->cb_func != NULL) { xassert(T->reason == 0); T->reason = GLP_ICUTGEN; T->parm->cb_func(T, T->parm->cb_info); T->reason = 0; if (T->stop) { ret = GLP_ESTOP; goto done; } } /* try to generate generic cuts with built-in generators (as suggested by Matteo Fischetti et al. the built-in cuts are not generated at each branching node; an intense attempt of generating new cuts is only made at the root node, and then a moderate effort is spent after each backtracking step) */ if (T->curr->level == 0 || pred_p == 0) { xassert(T->reason == 0); T->reason = GLP_ICUTGEN; generate_cuts(T); T->reason = 0; } /* if the local cut pool is not empty, select useful cuts and add them to the current subproblem */ if (T->local->size > 0) { xassert(T->reason == 0); T->reason = GLP_ICUTGEN; ios_process_cuts(T); T->reason = 0; } /* clear the local cut pool */ ios_clear_pool(T, T->local); /* perform re-optimization, if necessary */ if (T->reopt) { T->reopt = 0; T->curr->changed++; goto more; } /* no cuts were generated; remove inactive cuts */ remove_cuts(T); if (T->parm->msg_lev >= GLP_MSG_ALL && T->curr->level == 0) display_cut_info(T); /* update history information used on pseudocost branching */ if (T->pcost != NULL) ios_pcost_update(T); /* it's time to perform branching */ xassert(T->br_var == 0); xassert(T->br_sel == 0); /* let the application program choose variable to branch on */ if (T->parm->cb_func != NULL) { xassert(T->reason == 0); xassert(T->br_var == 0); xassert(T->br_sel == 0); T->reason = GLP_IBRANCH; T->parm->cb_func(T, T->parm->cb_info); T->reason = 0; if (T->stop) { ret = GLP_ESTOP; goto done; } } /* if nothing has been chosen, choose some variable as specified by the branching technique option */ if (T->br_var == 0) T->br_var = ios_choose_var(T, &T->br_sel); /* perform actual branching */ curr_p = T->curr->p; ret = branch_on(T, T->br_var, T->br_sel); T->br_var = T->br_sel = 0; if (ret == 0) { /* both branches have been created */ pred_p = curr_p; goto loop; } else if (ret == 1) { /* one branch is hopeless and has been pruned, so now the current subproblem is other branch */ /* the current subproblem should be considered as a new one, since one bound of the branching variable was changed */ T->curr->solved = T->curr->changed = 0; goto more; } else if (ret == 2) { /* both branches are hopeless and have been pruned; new subproblem selection is needed to continue the search */ goto fath; } else xassert(ret != ret); fath: /* the current subproblem has been fathomed */ if (T->parm->msg_lev >= GLP_MSG_DBG) xprintf("Node %d fathomed\n", p); /* freeze the current subproblem */ ios_freeze_node(T); /* and prune the corresponding branch of the tree */ ios_delete_node(T, p); /* if a new integer feasible solution has just been found, other branches may become hopeless and therefore must be pruned */ if (T->mip->mip_stat == GLP_FEAS) cleanup_the_tree(T); /* new subproblem selection is needed due to backtracking */ pred_p = 0; goto loop; done: /* display progress of the search on exit from the solver */ if (T->parm->msg_lev >= GLP_MSG_ON) show_progress(T, 0); if (T->mir_gen != NULL) ios_mir_term(T->mir_gen), T->mir_gen = NULL; if (T->clq_gen != NULL) ios_clq_term(T->clq_gen), T->clq_gen = NULL; /* return to the calling program */ return ret; } /* eof */ praat-6.0.04/external/glpk/glpios04.c000066400000000000000000000166401261542461700173130ustar00rootroot00000000000000/* glpios04.c (operations on sparse vectors) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpios.h" /*********************************************************************** * NAME * * ios_create_vec - create sparse vector * * SYNOPSIS * * #include "glpios.h" * IOSVEC *ios_create_vec(int n); * * DESCRIPTION * * The routine ios_create_vec creates a sparse vector of dimension n, * which initially is a null vector. * * RETURNS * * The routine returns a pointer to the vector created. */ IOSVEC *ios_create_vec(int n) { IOSVEC *v; xassert(n >= 0); v = xmalloc(sizeof(IOSVEC)); v->n = n; v->nnz = 0; v->pos = xcalloc(1+n, sizeof(int)); memset(&v->pos[1], 0, n * sizeof(int)); v->ind = xcalloc(1+n, sizeof(int)); v->val = xcalloc(1+n, sizeof(double)); return v; } /*********************************************************************** * NAME * * ios_check_vec - check that sparse vector has correct representation * * SYNOPSIS * * #include "glpios.h" * void ios_check_vec(IOSVEC *v); * * DESCRIPTION * * The routine ios_check_vec checks that a sparse vector specified by * the parameter v has correct representation. * * NOTE * * Complexity of this operation is O(n). */ void ios_check_vec(IOSVEC *v) { int j, k, nnz; xassert(v->n >= 0); nnz = 0; for (j = v->n; j >= 1; j--) { k = v->pos[j]; xassert(0 <= k && k <= v->nnz); if (k != 0) { xassert(v->ind[k] == j); nnz++; } } xassert(v->nnz == nnz); return; } /*********************************************************************** * NAME * * ios_get_vj - retrieve component of sparse vector * * SYNOPSIS * * #include "glpios.h" * double ios_get_vj(IOSVEC *v, int j); * * RETURNS * * The routine ios_get_vj returns j-th component of a sparse vector * specified by the parameter v. */ double ios_get_vj(IOSVEC *v, int j) { int k; xassert(1 <= j && j <= v->n); k = v->pos[j]; xassert(0 <= k && k <= v->nnz); return (k == 0 ? 0.0 : v->val[k]); } /*********************************************************************** * NAME * * ios_set_vj - set/change component of sparse vector * * SYNOPSIS * * #include "glpios.h" * void ios_set_vj(IOSVEC *v, int j, double val); * * DESCRIPTION * * The routine ios_set_vj assigns val to j-th component of a sparse * vector specified by the parameter v. */ void ios_set_vj(IOSVEC *v, int j, double val) { int k; xassert(1 <= j && j <= v->n); k = v->pos[j]; if (val == 0.0) { if (k != 0) { /* remove j-th component */ v->pos[j] = 0; if (k < v->nnz) { v->pos[v->ind[v->nnz]] = k; v->ind[k] = v->ind[v->nnz]; v->val[k] = v->val[v->nnz]; } v->nnz--; } } else { if (k == 0) { /* create j-th component */ k = ++(v->nnz); v->pos[j] = k; v->ind[k] = j; } v->val[k] = val; } return; } /*********************************************************************** * NAME * * ios_clear_vec - set all components of sparse vector to zero * * SYNOPSIS * * #include "glpios.h" * void ios_clear_vec(IOSVEC *v); * * DESCRIPTION * * The routine ios_clear_vec sets all components of a sparse vector * specified by the parameter v to zero. */ void ios_clear_vec(IOSVEC *v) { int k; for (k = 1; k <= v->nnz; k++) v->pos[v->ind[k]] = 0; v->nnz = 0; return; } /*********************************************************************** * NAME * * ios_clean_vec - remove zero or small components from sparse vector * * SYNOPSIS * * #include "glpios.h" * void ios_clean_vec(IOSVEC *v, double eps); * * DESCRIPTION * * The routine ios_clean_vec removes zero components and components * whose magnitude is less than eps from a sparse vector specified by * the parameter v. If eps is 0.0, only zero components are removed. */ void ios_clean_vec(IOSVEC *v, double eps) { int k, nnz; nnz = 0; for (k = 1; k <= v->nnz; k++) { if (fabs(v->val[k]) == 0.0 || fabs(v->val[k]) < eps) { /* remove component */ v->pos[v->ind[k]] = 0; } else { /* keep component */ nnz++; v->pos[v->ind[k]] = nnz; v->ind[nnz] = v->ind[k]; v->val[nnz] = v->val[k]; } } v->nnz = nnz; return; } /*********************************************************************** * NAME * * ios_copy_vec - copy sparse vector (x := y) * * SYNOPSIS * * #include "glpios.h" * void ios_copy_vec(IOSVEC *x, IOSVEC *y); * * DESCRIPTION * * The routine ios_copy_vec copies a sparse vector specified by the * parameter y to a sparse vector specified by the parameter x. */ void ios_copy_vec(IOSVEC *x, IOSVEC *y) { int j; xassert(x != y); xassert(x->n == y->n); ios_clear_vec(x); x->nnz = y->nnz; memcpy(&x->ind[1], &y->ind[1], x->nnz * sizeof(int)); memcpy(&x->val[1], &y->val[1], x->nnz * sizeof(double)); for (j = 1; j <= x->nnz; j++) x->pos[x->ind[j]] = j; return; } /*********************************************************************** * NAME * * ios_linear_comb - compute linear combination (x := x + a * y) * * SYNOPSIS * * #include "glpios.h" * void ios_linear_comb(IOSVEC *x, double a, IOSVEC *y); * * DESCRIPTION * * The routine ios_linear_comb computes the linear combination * * x := x + a * y, * * where x and y are sparse vectors, a is a scalar. */ void ios_linear_comb(IOSVEC *x, double a, IOSVEC *y) { int j, k; double xj, yj; xassert(x != y); xassert(x->n == y->n); for (k = 1; k <= y->nnz; k++) { j = y->ind[k]; xj = ios_get_vj(x, j); yj = y->val[k]; ios_set_vj(x, j, xj + a * yj); } return; } /*********************************************************************** * NAME * * ios_delete_vec - delete sparse vector * * SYNOPSIS * * #include "glpios.h" * void ios_delete_vec(IOSVEC *v); * * DESCRIPTION * * The routine ios_delete_vec deletes a sparse vector specified by the * parameter v freeing all the memory allocated to this object. */ void ios_delete_vec(IOSVEC *v) { /* delete sparse vector */ xfree(v->pos); xfree(v->ind); xfree(v->val); xfree(v); return; } /* eof */ praat-6.0.04/external/glpk/glpios05.c000066400000000000000000000236161261542461700173150ustar00rootroot00000000000000/* glpios05.c (Gomory's mixed integer cut generator) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpios.h" /*********************************************************************** * NAME * * ios_gmi_gen - generate Gomory's mixed integer cuts. * * SYNOPSIS * * #include "glpios.h" * void ios_gmi_gen(glp_tree *tree, IOSPOOL *pool); * * DESCRIPTION * * The routine ios_gmi_gen generates Gomory's mixed integer cuts for * the current point and adds them to the cut pool. */ #define MAXCUTS 50 /* maximal number of cuts to be generated for one round */ struct worka { /* Gomory's cut generator working area */ int *ind; /* int ind[1+n]; */ double *val; /* double val[1+n]; */ double *phi; /* double phi[1+m+n]; */ }; #define f(x) ((x) - floor(x)) /* compute fractional part of x */ static void gen_cut(glp_tree *tree, struct worka *worka, int j) { /* this routine tries to generate Gomory's mixed integer cut for specified structural variable x[m+j] of integer kind, which is basic and has fractional value in optimal solution to current LP relaxation */ glp_prob *mip = tree->mip; int m = mip->m; int n = mip->n; int *ind = worka->ind; double *val = worka->val; double *phi = worka->phi; int i, k, len, kind, stat; double lb, ub, alfa, beta, ksi, phi1, rhs; /* compute row of the simplex tableau, which (row) corresponds to specified basic variable xB[i] = x[m+j]; see (23) */ len = glp_eval_tab_row(mip, m+j, ind, val); /* determine beta[i], which a value of xB[i] in optimal solution to current LP relaxation; note that this value is the same as if it would be computed with formula (27); it is assumed that beta[i] is fractional enough */ beta = mip->col[j]->prim; /* compute cut coefficients phi and right-hand side rho, which correspond to formula (30); dense format is used, because rows of the simplex tableau is usually dense */ for (k = 1; k <= m+n; k++) phi[k] = 0.0; rhs = f(beta); /* initial value of rho; see (28), (32) */ for (j = 1; j <= len; j++) { /* determine original number of non-basic variable xN[j] */ k = ind[j]; xassert(1 <= k && k <= m+n); /* determine the kind, bounds and current status of xN[j] in optimal solution to LP relaxation */ if (k <= m) { /* auxiliary variable */ GLPROW *row = mip->row[k]; kind = GLP_CV; lb = row->lb; ub = row->ub; stat = row->stat; } else { /* structural variable */ GLPCOL *col = mip->col[k-m]; kind = col->kind; lb = col->lb; ub = col->ub; stat = col->stat; } /* xN[j] cannot be basic */ xassert(stat != GLP_BS); /* determine row coefficient ksi[i,j] at xN[j]; see (23) */ ksi = val[j]; /* if ksi[i,j] is too large in the magnitude, do not generate the cut */ if (fabs(ksi) > 1e+05) goto fini; /* if ksi[i,j] is too small in the magnitude, skip it */ if (fabs(ksi) < 1e-10) goto skip; /* compute row coefficient alfa[i,j] at y[j]; see (26) */ switch (stat) { case GLP_NF: /* xN[j] is free (unbounded) having non-zero ksi[i,j]; do not generate the cut */ goto fini; case GLP_NL: /* xN[j] has active lower bound */ alfa = - ksi; break; case GLP_NU: /* xN[j] has active upper bound */ alfa = + ksi; break; case GLP_NS: /* xN[j] is fixed; skip it */ goto skip; default: xassert(stat != stat); } /* compute cut coefficient phi'[j] at y[j]; see (21), (28) */ switch (kind) { case GLP_IV: /* y[j] is integer */ if (fabs(alfa - floor(alfa + 0.5)) < 1e-10) { /* alfa[i,j] is close to nearest integer; skip it */ goto skip; } else if (f(alfa) <= f(beta)) phi1 = f(alfa); else phi1 = (f(beta) / (1.0 - f(beta))) * (1.0 - f(alfa)); break; case GLP_CV: /* y[j] is continuous */ if (alfa >= 0.0) phi1 = + alfa; else phi1 = (f(beta) / (1.0 - f(beta))) * (- alfa); break; default: xassert(kind != kind); } /* compute cut coefficient phi[j] at xN[j] and update right- hand side rho; see (31), (32) */ switch (stat) { case GLP_NL: /* xN[j] has active lower bound */ phi[k] = + phi1; rhs += phi1 * lb; break; case GLP_NU: /* xN[j] has active upper bound */ phi[k] = - phi1; rhs -= phi1 * ub; break; default: xassert(stat != stat); } skip: ; } /* now the cut has the form sum_k phi[k] * x[k] >= rho, where cut coefficients are stored in the array phi in dense format; x[1,...,m] are auxiliary variables, x[m+1,...,m+n] are struc- tural variables; see (30) */ /* eliminate auxiliary variables in order to express the cut only through structural variables; see (33) */ for (i = 1; i <= m; i++) { GLPROW *row; GLPAIJ *aij; if (fabs(phi[i]) < 1e-10) continue; /* auxiliary variable x[i] has non-zero cut coefficient */ row = mip->row[i]; /* x[i] cannot be fixed */ xassert(row->type != GLP_FX); /* substitute x[i] = sum_j a[i,j] * x[m+j] */ for (aij = row->ptr; aij != NULL; aij = aij->r_next) phi[m+aij->col->j] += phi[i] * aij->val; } /* convert the final cut to sparse format and substitute fixed (structural) variables */ len = 0; for (j = 1; j <= n; j++) { GLPCOL *col; if (fabs(phi[m+j]) < 1e-10) continue; /* structural variable x[m+j] has non-zero cut coefficient */ col = mip->col[j]; if (col->type == GLP_FX) { /* eliminate x[m+j] */ rhs -= phi[m+j] * col->lb; } else { len++; ind[len] = j; val[len] = phi[m+j]; } } if (fabs(rhs) < 1e-12) rhs = 0.0; /* if the cut inequality seems to be badly scaled, reject it to avoid numeric difficulties */ for (k = 1; k <= len; k++) { if (fabs(val[k]) < 1e-03) goto fini; if (fabs(val[k]) > 1e+03) goto fini; } /* add the cut to the cut pool for further consideration */ #if 0 ios_add_cut_row(tree, pool, GLP_RF_GMI, len, ind, val, GLP_LO, rhs); #else glp_ios_add_row(tree, NULL, GLP_RF_GMI, 0, len, ind, val, GLP_LO, rhs); #endif fini: return; } struct var { int j; double f; }; static int fcmp(const void *p1, const void *p2) { const struct var *v1 = p1, *v2 = p2; if (v1->f > v2->f) return -1; if (v1->f < v2->f) return +1; return 0; } void ios_gmi_gen(glp_tree *tree) { /* main routine to generate Gomory's cuts */ glp_prob *mip = tree->mip; int m = mip->m; int n = mip->n; struct var *var; int k, nv, j, size; struct worka _worka, *worka = &_worka; /* allocate working arrays */ var = xcalloc(1+n, sizeof(struct var)); worka->ind = xcalloc(1+n, sizeof(int)); worka->val = xcalloc(1+n, sizeof(double)); worka->phi = xcalloc(1+m+n, sizeof(double)); /* build the list of integer structural variables, which are basic and have fractional value in optimal solution to current LP relaxation */ nv = 0; for (j = 1; j <= n; j++) { GLPCOL *col = mip->col[j]; double frac; if (col->kind != GLP_IV) continue; if (col->type == GLP_FX) continue; if (col->stat != GLP_BS) continue; frac = f(col->prim); if (!(0.05 <= frac && frac <= 0.95)) continue; /* add variable to the list */ nv++, var[nv].j = j, var[nv].f = frac; } /* order the list by descending fractionality */ qsort(&var[1], nv, sizeof(struct var), fcmp); /* try to generate cuts by one for each variable in the list, but not more than MAXCUTS cuts */ size = glp_ios_pool_size(tree); for (k = 1; k <= nv; k++) { if (glp_ios_pool_size(tree) - size >= MAXCUTS) break; gen_cut(tree, worka, var[k].j); } /* free working arrays */ xfree(var); xfree(worka->ind); xfree(worka->val); xfree(worka->phi); return; } /* eof */ praat-6.0.04/external/glpk/glpios06.c000066400000000000000000001375001261542461700173140ustar00rootroot00000000000000/* glpios06.c (MIR cut generator) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpios.h" #define _MIR_DEBUG 0 #define MAXAGGR 5 /* maximal number of rows which can be aggregated */ struct MIR { /* MIR cut generator working area */ /*--------------------------------------------------------------*/ /* global information valid for the root subproblem */ int m; /* number of rows (in the root subproblem) */ int n; /* number of columns */ char *skip; /* char skip[1+m]; */ /* skip[i], 1 <= i <= m, is a flag that means that row i should not be used because (1) it is not suitable, or (2) because it has been used in the aggregated constraint */ char *isint; /* char isint[1+m+n]; */ /* isint[k], 1 <= k <= m+n, is a flag that means that variable x[k] is integer (otherwise, continuous) */ double *lb; /* double lb[1+m+n]; */ /* lb[k], 1 <= k <= m+n, is lower bound of x[k]; -DBL_MAX means that x[k] has no lower bound */ int *vlb; /* int vlb[1+m+n]; */ /* vlb[k] = k', 1 <= k <= m+n, is the number of integer variable, which defines variable lower bound x[k] >= lb[k] * x[k']; zero means that x[k] has simple lower bound */ double *ub; /* double ub[1+m+n]; */ /* ub[k], 1 <= k <= m+n, is upper bound of x[k]; +DBL_MAX means that x[k] has no upper bound */ int *vub; /* int vub[1+m+n]; */ /* vub[k] = k', 1 <= k <= m+n, is the number of integer variable, which defines variable upper bound x[k] <= ub[k] * x[k']; zero means that x[k] has simple upper bound */ /*--------------------------------------------------------------*/ /* current (fractional) point to be separated */ double *x; /* double x[1+m+n]; */ /* x[k] is current value of auxiliary (1 <= k <= m) or structural (m+1 <= k <= m+n) variable */ /*--------------------------------------------------------------*/ /* aggregated constraint sum a[k] * x[k] = b, which is a linear combination of original constraints transformed to equalities by introducing auxiliary variables */ int agg_cnt; /* number of rows (original constraints) used to build aggregated constraint, 1 <= agg_cnt <= MAXAGGR */ int *agg_row; /* int agg_row[1+MAXAGGR]; */ /* agg_row[k], 1 <= k <= agg_cnt, is the row number used to build aggregated constraint */ IOSVEC *agg_vec; /* IOSVEC agg_vec[1:m+n]; */ /* sparse vector of aggregated constraint coefficients, a[k] */ double agg_rhs; /* right-hand side of the aggregated constraint, b */ /*--------------------------------------------------------------*/ /* bound substitution flags for modified constraint */ char *subst; /* char subst[1+m+n]; */ /* subst[k], 1 <= k <= m+n, is a bound substitution flag used for variable x[k]: '?' - x[k] is missing in modified constraint 'L' - x[k] = (lower bound) + x'[k] 'U' - x[k] = (upper bound) - x'[k] */ /*--------------------------------------------------------------*/ /* modified constraint sum a'[k] * x'[k] = b', where x'[k] >= 0, derived from aggregated constraint by substituting bounds; note that due to substitution of variable bounds there may be additional terms in the modified constraint */ IOSVEC *mod_vec; /* IOSVEC mod_vec[1:m+n]; */ /* sparse vector of modified constraint coefficients, a'[k] */ double mod_rhs; /* right-hand side of the modified constraint, b' */ /*--------------------------------------------------------------*/ /* cutting plane sum alpha[k] * x[k] <= beta */ IOSVEC *cut_vec; /* IOSVEC cut_vec[1:m+n]; */ /* sparse vector of cutting plane coefficients, alpha[k] */ double cut_rhs; /* right-hand size of the cutting plane, beta */ }; /*********************************************************************** * NAME * * ios_mir_init - initialize MIR cut generator * * SYNOPSIS * * #include "glpios.h" * void *ios_mir_init(glp_tree *tree); * * DESCRIPTION * * The routine ios_mir_init initializes the MIR cut generator assuming * that the current subproblem is the root subproblem. * * RETURNS * * The routine ios_mir_init returns a pointer to the MIR cut generator * working area. */ static void set_row_attrib(glp_tree *tree, struct MIR *mir) { /* set global row attributes */ glp_prob *mip = tree->mip; int m = mir->m; int k; for (k = 1; k <= m; k++) { GLPROW *row = mip->row[k]; mir->skip[k] = 0; mir->isint[k] = 0; switch (row->type) { case GLP_FR: mir->lb[k] = -DBL_MAX, mir->ub[k] = +DBL_MAX; break; case GLP_LO: mir->lb[k] = row->lb, mir->ub[k] = +DBL_MAX; break; case GLP_UP: mir->lb[k] = -DBL_MAX, mir->ub[k] = row->ub; break; case GLP_DB: mir->lb[k] = row->lb, mir->ub[k] = row->ub; break; case GLP_FX: mir->lb[k] = mir->ub[k] = row->lb; break; default: xassert(row != row); } mir->vlb[k] = mir->vub[k] = 0; } return; } static void set_col_attrib(glp_tree *tree, struct MIR *mir) { /* set global column attributes */ glp_prob *mip = tree->mip; int m = mir->m; int n = mir->n; int k; for (k = m+1; k <= m+n; k++) { GLPCOL *col = mip->col[k-m]; switch (col->kind) { case GLP_CV: mir->isint[k] = 0; break; case GLP_IV: mir->isint[k] = 1; break; default: xassert(col != col); } switch (col->type) { case GLP_FR: mir->lb[k] = -DBL_MAX, mir->ub[k] = +DBL_MAX; break; case GLP_LO: mir->lb[k] = col->lb, mir->ub[k] = +DBL_MAX; break; case GLP_UP: mir->lb[k] = -DBL_MAX, mir->ub[k] = col->ub; break; case GLP_DB: mir->lb[k] = col->lb, mir->ub[k] = col->ub; break; case GLP_FX: mir->lb[k] = mir->ub[k] = col->lb; break; default: xassert(col != col); } mir->vlb[k] = mir->vub[k] = 0; } return; } static void set_var_bounds(glp_tree *tree, struct MIR *mir) { /* set variable bounds */ glp_prob *mip = tree->mip; int m = mir->m; GLPAIJ *aij; int i, k1, k2; double a1, a2; for (i = 1; i <= m; i++) { /* we need the row to be '>= 0' or '<= 0' */ if (!(mir->lb[i] == 0.0 && mir->ub[i] == +DBL_MAX || mir->lb[i] == -DBL_MAX && mir->ub[i] == 0.0)) continue; /* take first term */ aij = mip->row[i]->ptr; if (aij == NULL) continue; k1 = m + aij->col->j, a1 = aij->val; /* take second term */ aij = aij->r_next; if (aij == NULL) continue; k2 = m + aij->col->j, a2 = aij->val; /* there must be only two terms */ if (aij->r_next != NULL) continue; /* interchange terms, if needed */ if (!mir->isint[k1] && mir->isint[k2]) ; else if (mir->isint[k1] && !mir->isint[k2]) { k2 = k1, a2 = a1; k1 = m + aij->col->j, a1 = aij->val; } else { /* both terms are either continuous or integer */ continue; } /* x[k2] should be double-bounded */ if (mir->lb[k2] == -DBL_MAX || mir->ub[k2] == +DBL_MAX || mir->lb[k2] == mir->ub[k2]) continue; /* change signs, if necessary */ if (mir->ub[i] == 0.0) a1 = - a1, a2 = - a2; /* now the row has the form a1 * x1 + a2 * x2 >= 0, where x1 is continuous, x2 is integer */ if (a1 > 0.0) { /* x1 >= - (a2 / a1) * x2 */ if (mir->vlb[k1] == 0) { /* set variable lower bound for x1 */ mir->lb[k1] = - a2 / a1; mir->vlb[k1] = k2; /* the row should not be used */ mir->skip[i] = 1; } } else /* a1 < 0.0 */ { /* x1 <= - (a2 / a1) * x2 */ if (mir->vub[k1] == 0) { /* set variable upper bound for x1 */ mir->ub[k1] = - a2 / a1; mir->vub[k1] = k2; /* the row should not be used */ mir->skip[i] = 1; } } } return; } static void mark_useless_rows(glp_tree *tree, struct MIR *mir) { /* mark rows which should not be used */ glp_prob *mip = tree->mip; int m = mir->m; GLPAIJ *aij; int i, k, nv; for (i = 1; i <= m; i++) { /* free rows should not be used */ if (mir->lb[i] == -DBL_MAX && mir->ub[i] == +DBL_MAX) { mir->skip[i] = 1; continue; } nv = 0; for (aij = mip->row[i]->ptr; aij != NULL; aij = aij->r_next) { k = m + aij->col->j; /* rows with free variables should not be used */ if (mir->lb[k] == -DBL_MAX && mir->ub[k] == +DBL_MAX) { mir->skip[i] = 1; break; } /* rows with integer variables having infinite (lower or upper) bound should not be used */ if (mir->isint[k] && mir->lb[k] == -DBL_MAX || mir->isint[k] && mir->ub[k] == +DBL_MAX) { mir->skip[i] = 1; break; } /* count non-fixed variables */ if (!(mir->vlb[k] == 0 && mir->vub[k] == 0 && mir->lb[k] == mir->ub[k])) nv++; } /* rows with all variables fixed should not be used */ if (nv == 0) { mir->skip[i] = 1; continue; } } return; } void *ios_mir_init(glp_tree *tree) { /* initialize MIR cut generator */ glp_prob *mip = tree->mip; int m = mip->m; int n = mip->n; struct MIR *mir; #if _MIR_DEBUG xprintf("ios_mir_init: warning: debug mode enabled\n"); #endif /* allocate working area */ mir = xmalloc(sizeof(struct MIR)); mir->m = m; mir->n = n; mir->skip = xcalloc(1+m, sizeof(char)); mir->isint = xcalloc(1+m+n, sizeof(char)); mir->lb = xcalloc(1+m+n, sizeof(double)); mir->vlb = xcalloc(1+m+n, sizeof(int)); mir->ub = xcalloc(1+m+n, sizeof(double)); mir->vub = xcalloc(1+m+n, sizeof(int)); mir->x = xcalloc(1+m+n, sizeof(double)); mir->agg_row = xcalloc(1+MAXAGGR, sizeof(int)); mir->agg_vec = ios_create_vec(m+n); mir->subst = xcalloc(1+m+n, sizeof(char)); mir->mod_vec = ios_create_vec(m+n); mir->cut_vec = ios_create_vec(m+n); /* set global row attributes */ set_row_attrib(tree, mir); /* set global column attributes */ set_col_attrib(tree, mir); /* set variable bounds */ set_var_bounds(tree, mir); /* mark rows which should not be used */ mark_useless_rows(tree, mir); return mir; } /*********************************************************************** * NAME * * ios_mir_gen - generate MIR cuts * * SYNOPSIS * * #include "glpios.h" * void ios_mir_gen(glp_tree *tree, void *gen, IOSPOOL *pool); * * DESCRIPTION * * The routine ios_mir_gen generates MIR cuts for the current point and * adds them to the cut pool. */ static void get_current_point(glp_tree *tree, struct MIR *mir) { /* obtain current point */ glp_prob *mip = tree->mip; int m = mir->m; int n = mir->n; int k; for (k = 1; k <= m; k++) mir->x[k] = mip->row[k]->prim; for (k = m+1; k <= m+n; k++) mir->x[k] = mip->col[k-m]->prim; return; } #if _MIR_DEBUG static void check_current_point(struct MIR *mir) { /* check current point */ int m = mir->m; int n = mir->n; int k, kk; double lb, ub, eps; for (k = 1; k <= m+n; k++) { /* determine lower bound */ lb = mir->lb[k]; kk = mir->vlb[k]; if (kk != 0) { xassert(lb != -DBL_MAX); xassert(!mir->isint[k]); xassert(mir->isint[kk]); lb *= mir->x[kk]; } /* check lower bound */ if (lb != -DBL_MAX) { eps = 1e-6 * (1.0 + fabs(lb)); xassert(mir->x[k] >= lb - eps); } /* determine upper bound */ ub = mir->ub[k]; kk = mir->vub[k]; if (kk != 0) { xassert(ub != +DBL_MAX); xassert(!mir->isint[k]); xassert(mir->isint[kk]); ub *= mir->x[kk]; } /* check upper bound */ if (ub != +DBL_MAX) { eps = 1e-6 * (1.0 + fabs(ub)); xassert(mir->x[k] <= ub + eps); } } return; } #endif static void initial_agg_row(glp_tree *tree, struct MIR *mir, int i) { /* use original i-th row as initial aggregated constraint */ glp_prob *mip = tree->mip; int m = mir->m; GLPAIJ *aij; xassert(1 <= i && i <= m); xassert(!mir->skip[i]); /* mark i-th row in order not to use it in the same aggregated constraint */ mir->skip[i] = 2; mir->agg_cnt = 1; mir->agg_row[1] = i; /* use x[i] - sum a[i,j] * x[m+j] = 0, where x[i] is auxiliary variable of row i, x[m+j] are structural variables */ ios_clear_vec(mir->agg_vec); ios_set_vj(mir->agg_vec, i, 1.0); for (aij = mip->row[i]->ptr; aij != NULL; aij = aij->r_next) ios_set_vj(mir->agg_vec, m + aij->col->j, - aij->val); mir->agg_rhs = 0.0; #if _MIR_DEBUG ios_check_vec(mir->agg_vec); #endif return; } #if _MIR_DEBUG static void check_agg_row(struct MIR *mir) { /* check aggregated constraint */ int m = mir->m; int n = mir->n; int j, k; double r, big; /* compute the residual r = sum a[k] * x[k] - b and determine big = max(1, |a[k]|, |b|) */ r = 0.0, big = 1.0; for (j = 1; j <= mir->agg_vec->nnz; j++) { k = mir->agg_vec->ind[j]; xassert(1 <= k && k <= m+n); r += mir->agg_vec->val[j] * mir->x[k]; if (big < fabs(mir->agg_vec->val[j])) big = fabs(mir->agg_vec->val[j]); } r -= mir->agg_rhs; if (big < fabs(mir->agg_rhs)) big = fabs(mir->agg_rhs); /* the residual must be close to zero */ xassert(fabs(r) <= 1e-6 * big); return; } #endif static void subst_fixed_vars(struct MIR *mir) { /* substitute fixed variables into aggregated constraint */ int m = mir->m; int n = mir->n; int j, k; for (j = 1; j <= mir->agg_vec->nnz; j++) { k = mir->agg_vec->ind[j]; xassert(1 <= k && k <= m+n); if (mir->vlb[k] == 0 && mir->vub[k] == 0 && mir->lb[k] == mir->ub[k]) { /* x[k] is fixed */ mir->agg_rhs -= mir->agg_vec->val[j] * mir->lb[k]; mir->agg_vec->val[j] = 0.0; } } /* remove terms corresponding to fixed variables */ ios_clean_vec(mir->agg_vec, DBL_EPSILON); #if _MIR_DEBUG ios_check_vec(mir->agg_vec); #endif return; } static void bound_subst_heur(struct MIR *mir) { /* bound substitution heuristic */ int m = mir->m; int n = mir->n; int j, k, kk; double d1, d2; for (j = 1; j <= mir->agg_vec->nnz; j++) { k = mir->agg_vec->ind[j]; xassert(1 <= k && k <= m+n); if (mir->isint[k]) continue; /* skip integer variable */ /* compute distance from x[k] to its lower bound */ kk = mir->vlb[k]; if (kk == 0) { if (mir->lb[k] == -DBL_MAX) d1 = DBL_MAX; else d1 = mir->x[k] - mir->lb[k]; } else { xassert(1 <= kk && kk <= m+n); xassert(mir->isint[kk]); xassert(mir->lb[k] != -DBL_MAX); d1 = mir->x[k] - mir->lb[k] * mir->x[kk]; } /* compute distance from x[k] to its upper bound */ kk = mir->vub[k]; if (kk == 0) { if (mir->vub[k] == +DBL_MAX) d2 = DBL_MAX; else d2 = mir->ub[k] - mir->x[k]; } else { xassert(1 <= kk && kk <= m+n); xassert(mir->isint[kk]); xassert(mir->ub[k] != +DBL_MAX); d2 = mir->ub[k] * mir->x[kk] - mir->x[k]; } /* x[k] cannot be free */ xassert(d1 != DBL_MAX || d2 != DBL_MAX); /* choose the bound which is closer to x[k] */ xassert(mir->subst[k] == '?'); if (d1 <= d2) mir->subst[k] = 'L'; else mir->subst[k] = 'U'; } return; } static void build_mod_row(struct MIR *mir) { /* substitute bounds and build modified constraint */ int m = mir->m; int n = mir->n; int j, jj, k, kk; /* initially modified constraint is aggregated constraint */ ios_copy_vec(mir->mod_vec, mir->agg_vec); mir->mod_rhs = mir->agg_rhs; #if _MIR_DEBUG ios_check_vec(mir->mod_vec); #endif /* substitute bounds for continuous variables; note that due to substitution of variable bounds additional terms may appear in modified constraint */ for (j = mir->mod_vec->nnz; j >= 1; j--) { k = mir->mod_vec->ind[j]; xassert(1 <= k && k <= m+n); if (mir->isint[k]) continue; /* skip integer variable */ if (mir->subst[k] == 'L') { /* x[k] = (lower bound) + x'[k] */ xassert(mir->lb[k] != -DBL_MAX); kk = mir->vlb[k]; if (kk == 0) { /* x[k] = lb[k] + x'[k] */ mir->mod_rhs -= mir->mod_vec->val[j] * mir->lb[k]; } else { /* x[k] = lb[k] * x[kk] + x'[k] */ xassert(mir->isint[kk]); jj = mir->mod_vec->pos[kk]; if (jj == 0) { ios_set_vj(mir->mod_vec, kk, 1.0); jj = mir->mod_vec->pos[kk]; mir->mod_vec->val[jj] = 0.0; } mir->mod_vec->val[jj] += mir->mod_vec->val[j] * mir->lb[k]; } } else if (mir->subst[k] == 'U') { /* x[k] = (upper bound) - x'[k] */ xassert(mir->ub[k] != +DBL_MAX); kk = mir->vub[k]; if (kk == 0) { /* x[k] = ub[k] - x'[k] */ mir->mod_rhs -= mir->mod_vec->val[j] * mir->ub[k]; } else { /* x[k] = ub[k] * x[kk] - x'[k] */ xassert(mir->isint[kk]); jj = mir->mod_vec->pos[kk]; if (jj == 0) { ios_set_vj(mir->mod_vec, kk, 1.0); jj = mir->mod_vec->pos[kk]; mir->mod_vec->val[jj] = 0.0; } mir->mod_vec->val[jj] += mir->mod_vec->val[j] * mir->ub[k]; } mir->mod_vec->val[j] = - mir->mod_vec->val[j]; } else xassert(k != k); } #if _MIR_DEBUG ios_check_vec(mir->mod_vec); #endif /* substitute bounds for integer variables */ for (j = 1; j <= mir->mod_vec->nnz; j++) { k = mir->mod_vec->ind[j]; xassert(1 <= k && k <= m+n); if (!mir->isint[k]) continue; /* skip continuous variable */ xassert(mir->subst[k] == '?'); xassert(mir->vlb[k] == 0 && mir->vub[k] == 0); xassert(mir->lb[k] != -DBL_MAX && mir->ub[k] != +DBL_MAX); if (fabs(mir->lb[k]) <= fabs(mir->ub[k])) { /* x[k] = lb[k] + x'[k] */ mir->subst[k] = 'L'; mir->mod_rhs -= mir->mod_vec->val[j] * mir->lb[k]; } else { /* x[k] = ub[k] - x'[k] */ mir->subst[k] = 'U'; mir->mod_rhs -= mir->mod_vec->val[j] * mir->ub[k]; mir->mod_vec->val[j] = - mir->mod_vec->val[j]; } } #if _MIR_DEBUG ios_check_vec(mir->mod_vec); #endif return; } #if _MIR_DEBUG static void check_mod_row(struct MIR *mir) { /* check modified constraint */ int m = mir->m; int n = mir->n; int j, k, kk; double r, big, x; /* compute the residual r = sum a'[k] * x'[k] - b' and determine big = max(1, |a[k]|, |b|) */ r = 0.0, big = 1.0; for (j = 1; j <= mir->mod_vec->nnz; j++) { k = mir->mod_vec->ind[j]; xassert(1 <= k && k <= m+n); if (mir->subst[k] == 'L') { /* x'[k] = x[k] - (lower bound) */ xassert(mir->lb[k] != -DBL_MAX); kk = mir->vlb[k]; if (kk == 0) x = mir->x[k] - mir->lb[k]; else x = mir->x[k] - mir->lb[k] * mir->x[kk]; } else if (mir->subst[k] == 'U') { /* x'[k] = (upper bound) - x[k] */ xassert(mir->ub[k] != +DBL_MAX); kk = mir->vub[k]; if (kk == 0) x = mir->ub[k] - mir->x[k]; else x = mir->ub[k] * mir->x[kk] - mir->x[k]; } else xassert(k != k); r += mir->mod_vec->val[j] * x; if (big < fabs(mir->mod_vec->val[j])) big = fabs(mir->mod_vec->val[j]); } r -= mir->mod_rhs; if (big < fabs(mir->mod_rhs)) big = fabs(mir->mod_rhs); /* the residual must be close to zero */ xassert(fabs(r) <= 1e-6 * big); return; } #endif /*********************************************************************** * mir_ineq - construct MIR inequality * * Given the single constraint mixed integer set * * |N| * X = {(x,s) in Z x R : sum a[j] * x[j] <= b + s}, * + + j in N * * this routine constructs the mixed integer rounding (MIR) inequality * * sum alpha[j] * x[j] <= beta + gamma * s, * j in N * * which is valid for X. * * If the MIR inequality has been successfully constructed, the routine * returns zero. Otherwise, if b is close to nearest integer, there may * be numeric difficulties due to big coefficients; so in this case the * routine returns non-zero. */ static int mir_ineq(const int n, const double a[], const double b, double alpha[], double *beta, double *gamma) { int j; double f, t; if (fabs(b - floor(b + .5)) < 0.01) return 1; f = b - floor(b); for (j = 1; j <= n; j++) { t = (a[j] - floor(a[j])) - f; if (t <= 0.0) alpha[j] = floor(a[j]); else alpha[j] = floor(a[j]) + t / (1.0 - f); } *beta = floor(b); *gamma = 1.0 / (1.0 - f); return 0; } /*********************************************************************** * cmir_ineq - construct c-MIR inequality * * Given the mixed knapsack set * * MK |N| * X = {(x,s) in Z x R : sum a[j] * x[j] <= b + s, * + + j in N * * x[j] <= u[j]}, * * a subset C of variables to be complemented, and a divisor delta > 0, * this routine constructs the complemented MIR (c-MIR) inequality * * sum alpha[j] * x[j] <= beta + gamma * s, * j in N * MK * which is valid for X . * * If the c-MIR inequality has been successfully constructed, the * routine returns zero. Otherwise, if there is a risk of numerical * difficulties due to big coefficients (see comments to the routine * mir_ineq), the routine cmir_ineq returns non-zero. */ static int cmir_ineq(const int n, const double a[], const double b, const double u[], const char cset[], const double delta, double alpha[], double *beta, double *gamma) { int j; double *aa, bb; aa = alpha, bb = b; for (j = 1; j <= n; j++) { aa[j] = a[j] / delta; if (cset[j]) aa[j] = - aa[j], bb -= a[j] * u[j]; } bb /= delta; if (mir_ineq(n, aa, bb, alpha, beta, gamma)) return 1; for (j = 1; j <= n; j++) { if (cset[j]) alpha[j] = - alpha[j], *beta += alpha[j] * u[j]; } *gamma /= delta; return 0; } /*********************************************************************** * cmir_sep - c-MIR separation heuristic * * Given the mixed knapsack set * * MK |N| * X = {(x,s) in Z x R : sum a[j] * x[j] <= b + s, * + + j in N * * x[j] <= u[j]} * * * * * and a fractional point (x , s ), this routine tries to construct * c-MIR inequality * * sum alpha[j] * x[j] <= beta + gamma * s, * j in N * MK * which is valid for X and has (desirably maximal) violation at the * fractional point given. This is attained by choosing an appropriate * set C of variables to be complemented and a divisor delta > 0, which * together define corresponding c-MIR inequality. * * If a violated c-MIR inequality has been successfully constructed, * the routine returns its violation: * * * * * sum alpha[j] * x [j] - beta - gamma * s , * j in N * * which is positive. In case of failure the routine returns zero. */ struct vset { int j; double v; }; static int cmir_cmp(const void *p1, const void *p2) { const struct vset *v1 = p1, *v2 = p2; if (v1->v < v2->v) return -1; if (v1->v > v2->v) return +1; return 0; } static double cmir_sep(const int n, const double a[], const double b, const double u[], const double x[], const double s, double alpha[], double *beta, double *gamma) { int fail, j, k, nv, v; double delta, eps, d_try[1+3], r, r_best; char *cset; struct vset *vset; /* allocate working arrays */ cset = xcalloc(1+n, sizeof(char)); vset = xcalloc(1+n, sizeof(struct vset)); /* choose initial C */ for (j = 1; j <= n; j++) cset[j] = (char)(x[j] >= 0.5 * u[j]); /* choose initial delta */ r_best = delta = 0.0; for (j = 1; j <= n; j++) { xassert(a[j] != 0.0); /* if x[j] is close to its bounds, skip it */ eps = 1e-9 * (1.0 + fabs(u[j])); if (x[j] < eps || x[j] > u[j] - eps) continue; /* try delta = |a[j]| to construct c-MIR inequality */ fail = cmir_ineq(n, a, b, u, cset, fabs(a[j]), alpha, beta, gamma); if (fail) continue; /* compute violation */ r = - (*beta) - (*gamma) * s; for (k = 1; k <= n; k++) r += alpha[k] * x[k]; if (r_best < r) r_best = r, delta = fabs(a[j]); } if (r_best < 0.001) r_best = 0.0; if (r_best == 0.0) goto done; xassert(delta > 0.0); /* try to increase violation by dividing delta by 2, 4, and 8, respectively */ d_try[1] = delta / 2.0; d_try[2] = delta / 4.0; d_try[3] = delta / 8.0; for (j = 1; j <= 3; j++) { /* construct c-MIR inequality */ fail = cmir_ineq(n, a, b, u, cset, d_try[j], alpha, beta, gamma); if (fail) continue; /* compute violation */ r = - (*beta) - (*gamma) * s; for (k = 1; k <= n; k++) r += alpha[k] * x[k]; if (r_best < r) r_best = r, delta = d_try[j]; } /* build subset of variables lying strictly between their bounds and order it by nondecreasing values of |x[j] - u[j]/2| */ nv = 0; for (j = 1; j <= n; j++) { /* if x[j] is close to its bounds, skip it */ eps = 1e-9 * (1.0 + fabs(u[j])); if (x[j] < eps || x[j] > u[j] - eps) continue; /* add x[j] to the subset */ nv++; vset[nv].j = j; vset[nv].v = fabs(x[j] - 0.5 * u[j]); } qsort(&vset[1], nv, sizeof(struct vset), cmir_cmp); /* try to increase violation by successively complementing each variable in the subset */ for (v = 1; v <= nv; v++) { j = vset[v].j; /* replace x[j] by its complement or vice versa */ cset[j] = (char)!cset[j]; /* construct c-MIR inequality */ fail = cmir_ineq(n, a, b, u, cset, delta, alpha, beta, gamma); /* restore the variable */ cset[j] = (char)!cset[j]; /* do not replace the variable in case of failure */ if (fail) continue; /* compute violation */ r = - (*beta) - (*gamma) * s; for (k = 1; k <= n; k++) r += alpha[k] * x[k]; if (r_best < r) r_best = r, cset[j] = (char)!cset[j]; } /* construct the best c-MIR inequality chosen */ fail = cmir_ineq(n, a, b, u, cset, delta, alpha, beta, gamma); xassert(!fail); done: /* free working arrays */ xfree(cset); xfree(vset); /* return to the calling routine */ return r_best; } static double generate(struct MIR *mir) { /* try to generate violated c-MIR cut for modified constraint */ int m = mir->m; int n = mir->n; int j, k, kk, nint; double s, *u, *x, *alpha, r_best = 0.0, b, beta, gamma; ios_copy_vec(mir->cut_vec, mir->mod_vec); mir->cut_rhs = mir->mod_rhs; /* remove small terms, which can appear due to substitution of variable bounds */ ios_clean_vec(mir->cut_vec, DBL_EPSILON); #if _MIR_DEBUG ios_check_vec(mir->cut_vec); #endif /* remove positive continuous terms to obtain MK relaxation */ for (j = 1; j <= mir->cut_vec->nnz; j++) { k = mir->cut_vec->ind[j]; xassert(1 <= k && k <= m+n); if (!mir->isint[k] && mir->cut_vec->val[j] > 0.0) mir->cut_vec->val[j] = 0.0; } ios_clean_vec(mir->cut_vec, 0.0); #if _MIR_DEBUG ios_check_vec(mir->cut_vec); #endif /* move integer terms to the beginning of the sparse vector and determine the number of integer variables */ nint = 0; for (j = 1; j <= mir->cut_vec->nnz; j++) { k = mir->cut_vec->ind[j]; xassert(1 <= k && k <= m+n); if (mir->isint[k]) { double temp; nint++; /* interchange elements [nint] and [j] */ kk = mir->cut_vec->ind[nint]; mir->cut_vec->pos[k] = nint; mir->cut_vec->pos[kk] = j; mir->cut_vec->ind[nint] = k; mir->cut_vec->ind[j] = kk; temp = mir->cut_vec->val[nint]; mir->cut_vec->val[nint] = mir->cut_vec->val[j]; mir->cut_vec->val[j] = temp; } } #if _MIR_DEBUG ios_check_vec(mir->cut_vec); #endif /* if there is no integer variable, nothing to generate */ if (nint == 0) goto done; /* allocate working arrays */ u = xcalloc(1+nint, sizeof(double)); x = xcalloc(1+nint, sizeof(double)); alpha = xcalloc(1+nint, sizeof(double)); /* determine u and x */ for (j = 1; j <= nint; j++) { k = mir->cut_vec->ind[j]; xassert(m+1 <= k && k <= m+n); xassert(mir->isint[k]); u[j] = mir->ub[k] - mir->lb[k]; xassert(u[j] >= 1.0); if (mir->subst[k] == 'L') x[j] = mir->x[k] - mir->lb[k]; else if (mir->subst[k] == 'U') x[j] = mir->ub[k] - mir->x[k]; else xassert(k != k); xassert(x[j] >= -0.001); if (x[j] < 0.0) x[j] = 0.0; } /* compute s = - sum of continuous terms */ s = 0.0; for (j = nint+1; j <= mir->cut_vec->nnz; j++) { double x; k = mir->cut_vec->ind[j]; xassert(1 <= k && k <= m+n); /* must be continuous */ xassert(!mir->isint[k]); if (mir->subst[k] == 'L') { xassert(mir->lb[k] != -DBL_MAX); kk = mir->vlb[k]; if (kk == 0) x = mir->x[k] - mir->lb[k]; else x = mir->x[k] - mir->lb[k] * mir->x[kk]; } else if (mir->subst[k] == 'U') { xassert(mir->ub[k] != +DBL_MAX); kk = mir->vub[k]; if (kk == 0) x = mir->ub[k] - mir->x[k]; else x = mir->ub[k] * mir->x[kk] - mir->x[k]; } else xassert(k != k); xassert(x >= -0.001); if (x < 0.0) x = 0.0; s -= mir->cut_vec->val[j] * x; } xassert(s >= 0.0); /* apply heuristic to obtain most violated c-MIR inequality */ b = mir->cut_rhs; r_best = cmir_sep(nint, mir->cut_vec->val, b, u, x, s, alpha, &beta, &gamma); if (r_best == 0.0) goto skip; xassert(r_best > 0.0); /* convert to raw cut */ /* sum alpha[j] * x[j] <= beta + gamma * s */ for (j = 1; j <= nint; j++) mir->cut_vec->val[j] = alpha[j]; for (j = nint+1; j <= mir->cut_vec->nnz; j++) { k = mir->cut_vec->ind[j]; if (k <= m+n) mir->cut_vec->val[j] *= gamma; } mir->cut_rhs = beta; #if _MIR_DEBUG ios_check_vec(mir->cut_vec); #endif skip: /* free working arrays */ xfree(u); xfree(x); xfree(alpha); done: return r_best; } #if _MIR_DEBUG static void check_raw_cut(struct MIR *mir, double r_best) { /* check raw cut before back bound substitution */ int m = mir->m; int n = mir->n; int j, k, kk; double r, big, x; /* compute the residual r = sum a[k] * x[k] - b and determine big = max(1, |a[k]|, |b|) */ r = 0.0, big = 1.0; for (j = 1; j <= mir->cut_vec->nnz; j++) { k = mir->cut_vec->ind[j]; xassert(1 <= k && k <= m+n); if (mir->subst[k] == 'L') { xassert(mir->lb[k] != -DBL_MAX); kk = mir->vlb[k]; if (kk == 0) x = mir->x[k] - mir->lb[k]; else x = mir->x[k] - mir->lb[k] * mir->x[kk]; } else if (mir->subst[k] == 'U') { xassert(mir->ub[k] != +DBL_MAX); kk = mir->vub[k]; if (kk == 0) x = mir->ub[k] - mir->x[k]; else x = mir->ub[k] * mir->x[kk] - mir->x[k]; } else xassert(k != k); r += mir->cut_vec->val[j] * x; if (big < fabs(mir->cut_vec->val[j])) big = fabs(mir->cut_vec->val[j]); } r -= mir->cut_rhs; if (big < fabs(mir->cut_rhs)) big = fabs(mir->cut_rhs); /* the residual must be close to r_best */ xassert(fabs(r - r_best) <= 1e-6 * big); return; } #endif static void back_subst(struct MIR *mir) { /* back substitution of original bounds */ int m = mir->m; int n = mir->n; int j, jj, k, kk; /* at first, restore bounds of integer variables (because on restoring variable bounds of continuous variables we need original, not shifted, bounds of integer variables) */ for (j = 1; j <= mir->cut_vec->nnz; j++) { k = mir->cut_vec->ind[j]; xassert(1 <= k && k <= m+n); if (!mir->isint[k]) continue; /* skip continuous */ if (mir->subst[k] == 'L') { /* x'[k] = x[k] - lb[k] */ xassert(mir->lb[k] != -DBL_MAX); xassert(mir->vlb[k] == 0); mir->cut_rhs += mir->cut_vec->val[j] * mir->lb[k]; } else if (mir->subst[k] == 'U') { /* x'[k] = ub[k] - x[k] */ xassert(mir->ub[k] != +DBL_MAX); xassert(mir->vub[k] == 0); mir->cut_rhs -= mir->cut_vec->val[j] * mir->ub[k]; mir->cut_vec->val[j] = - mir->cut_vec->val[j]; } else xassert(k != k); } /* now restore bounds of continuous variables */ for (j = 1; j <= mir->cut_vec->nnz; j++) { k = mir->cut_vec->ind[j]; xassert(1 <= k && k <= m+n); if (mir->isint[k]) continue; /* skip integer */ if (mir->subst[k] == 'L') { /* x'[k] = x[k] - (lower bound) */ xassert(mir->lb[k] != -DBL_MAX); kk = mir->vlb[k]; if (kk == 0) { /* x'[k] = x[k] - lb[k] */ mir->cut_rhs += mir->cut_vec->val[j] * mir->lb[k]; } else { /* x'[k] = x[k] - lb[k] * x[kk] */ jj = mir->cut_vec->pos[kk]; #if 0 xassert(jj != 0); #else if (jj == 0) { ios_set_vj(mir->cut_vec, kk, 1.0); jj = mir->cut_vec->pos[kk]; xassert(jj != 0); mir->cut_vec->val[jj] = 0.0; } #endif mir->cut_vec->val[jj] -= mir->cut_vec->val[j] * mir->lb[k]; } } else if (mir->subst[k] == 'U') { /* x'[k] = (upper bound) - x[k] */ xassert(mir->ub[k] != +DBL_MAX); kk = mir->vub[k]; if (kk == 0) { /* x'[k] = ub[k] - x[k] */ mir->cut_rhs -= mir->cut_vec->val[j] * mir->ub[k]; } else { /* x'[k] = ub[k] * x[kk] - x[k] */ jj = mir->cut_vec->pos[kk]; if (jj == 0) { ios_set_vj(mir->cut_vec, kk, 1.0); jj = mir->cut_vec->pos[kk]; xassert(jj != 0); mir->cut_vec->val[jj] = 0.0; } mir->cut_vec->val[jj] += mir->cut_vec->val[j] * mir->ub[k]; } mir->cut_vec->val[j] = - mir->cut_vec->val[j]; } else xassert(k != k); } #if _MIR_DEBUG ios_check_vec(mir->cut_vec); #endif return; } #if _MIR_DEBUG static void check_cut_row(struct MIR *mir, double r_best) { /* check the cut after back bound substitution or elimination of auxiliary variables */ int m = mir->m; int n = mir->n; int j, k; double r, big; /* compute the residual r = sum a[k] * x[k] - b and determine big = max(1, |a[k]|, |b|) */ r = 0.0, big = 1.0; for (j = 1; j <= mir->cut_vec->nnz; j++) { k = mir->cut_vec->ind[j]; xassert(1 <= k && k <= m+n); r += mir->cut_vec->val[j] * mir->x[k]; if (big < fabs(mir->cut_vec->val[j])) big = fabs(mir->cut_vec->val[j]); } r -= mir->cut_rhs; if (big < fabs(mir->cut_rhs)) big = fabs(mir->cut_rhs); /* the residual must be close to r_best */ xassert(fabs(r - r_best) <= 1e-6 * big); return; } #endif static void subst_aux_vars(glp_tree *tree, struct MIR *mir) { /* final substitution to eliminate auxiliary variables */ glp_prob *mip = tree->mip; int m = mir->m; int n = mir->n; GLPAIJ *aij; int j, k, kk, jj; for (j = mir->cut_vec->nnz; j >= 1; j--) { k = mir->cut_vec->ind[j]; xassert(1 <= k && k <= m+n); if (k > m) continue; /* skip structurals */ for (aij = mip->row[k]->ptr; aij != NULL; aij = aij->r_next) { kk = m + aij->col->j; /* structural */ jj = mir->cut_vec->pos[kk]; if (jj == 0) { ios_set_vj(mir->cut_vec, kk, 1.0); jj = mir->cut_vec->pos[kk]; mir->cut_vec->val[jj] = 0.0; } mir->cut_vec->val[jj] += mir->cut_vec->val[j] * aij->val; } mir->cut_vec->val[j] = 0.0; } ios_clean_vec(mir->cut_vec, 0.0); return; } static void add_cut(glp_tree *tree, struct MIR *mir) { /* add constructed cut inequality to the cut pool */ int m = mir->m; int n = mir->n; int j, k, len; int *ind = xcalloc(1+n, sizeof(int)); double *val = xcalloc(1+n, sizeof(double)); len = 0; for (j = mir->cut_vec->nnz; j >= 1; j--) { k = mir->cut_vec->ind[j]; xassert(m+1 <= k && k <= m+n); len++, ind[len] = k - m, val[len] = mir->cut_vec->val[j]; } #if 0 ios_add_cut_row(tree, pool, GLP_RF_MIR, len, ind, val, GLP_UP, mir->cut_rhs); #else glp_ios_add_row(tree, NULL, GLP_RF_MIR, 0, len, ind, val, GLP_UP, mir->cut_rhs); #endif xfree(ind); xfree(val); return; } static int aggregate_row(glp_tree *tree, struct MIR *mir) { /* try to aggregate another row */ glp_prob *mip = tree->mip; int m = mir->m; int n = mir->n; GLPAIJ *aij; IOSVEC *v; int ii, j, jj, k, kk, kappa = 0, ret = 0; double d1, d2, d, d_max = 0.0; /* choose appropriate structural variable in the aggregated row to be substituted */ for (j = 1; j <= mir->agg_vec->nnz; j++) { k = mir->agg_vec->ind[j]; xassert(1 <= k && k <= m+n); if (k <= m) continue; /* skip auxiliary var */ if (mir->isint[k]) continue; /* skip integer var */ if (fabs(mir->agg_vec->val[j]) < 0.001) continue; /* compute distance from x[k] to its lower bound */ kk = mir->vlb[k]; if (kk == 0) { if (mir->lb[k] == -DBL_MAX) d1 = DBL_MAX; else d1 = mir->x[k] - mir->lb[k]; } else { xassert(1 <= kk && kk <= m+n); xassert(mir->isint[kk]); xassert(mir->lb[k] != -DBL_MAX); d1 = mir->x[k] - mir->lb[k] * mir->x[kk]; } /* compute distance from x[k] to its upper bound */ kk = mir->vub[k]; if (kk == 0) { if (mir->vub[k] == +DBL_MAX) d2 = DBL_MAX; else d2 = mir->ub[k] - mir->x[k]; } else { xassert(1 <= kk && kk <= m+n); xassert(mir->isint[kk]); xassert(mir->ub[k] != +DBL_MAX); d2 = mir->ub[k] * mir->x[kk] - mir->x[k]; } /* x[k] cannot be free */ xassert(d1 != DBL_MAX || d2 != DBL_MAX); /* d = min(d1, d2) */ d = (d1 <= d2 ? d1 : d2); xassert(d != DBL_MAX); /* should not be close to corresponding bound */ if (d < 0.001) continue; if (d_max < d) d_max = d, kappa = k; } if (kappa == 0) { /* nothing chosen */ ret = 1; goto done; } /* x[kappa] has been chosen */ xassert(m+1 <= kappa && kappa <= m+n); xassert(!mir->isint[kappa]); /* find another row, which have not been used yet, to eliminate x[kappa] from the aggregated row */ for (ii = 1; ii <= m; ii++) { if (mir->skip[ii]) continue; for (aij = mip->row[ii]->ptr; aij != NULL; aij = aij->r_next) if (aij->col->j == kappa - m) break; if (aij != NULL && fabs(aij->val) >= 0.001) break; } if (ii > m) { /* nothing found */ ret = 2; goto done; } /* row ii has been found; include it in the aggregated list */ mir->agg_cnt++; xassert(mir->agg_cnt <= MAXAGGR); mir->agg_row[mir->agg_cnt] = ii; mir->skip[ii] = 2; /* v := new row */ v = ios_create_vec(m+n); ios_set_vj(v, ii, 1.0); for (aij = mip->row[ii]->ptr; aij != NULL; aij = aij->r_next) ios_set_vj(v, m + aij->col->j, - aij->val); #if _MIR_DEBUG ios_check_vec(v); #endif /* perform gaussian elimination to remove x[kappa] */ j = mir->agg_vec->pos[kappa]; xassert(j != 0); jj = v->pos[kappa]; xassert(jj != 0); ios_linear_comb(mir->agg_vec, - mir->agg_vec->val[j] / v->val[jj], v); ios_delete_vec(v); ios_set_vj(mir->agg_vec, kappa, 0.0); #if _MIR_DEBUG ios_check_vec(mir->agg_vec); #endif done: return ret; } void ios_mir_gen(glp_tree *tree, void *gen) { /* main routine to generate MIR cuts */ glp_prob *mip = tree->mip; struct MIR *mir = gen; int m = mir->m; int n = mir->n; int i; double r_best; xassert(mip->m >= m); xassert(mip->n == n); /* obtain current point */ get_current_point(tree, mir); #if _MIR_DEBUG /* check current point */ check_current_point(mir); #endif /* reset bound substitution flags */ memset(&mir->subst[1], '?', m+n); /* try to generate a set of violated MIR cuts */ for (i = 1; i <= m; i++) { if (mir->skip[i]) continue; /* use original i-th row as initial aggregated constraint */ initial_agg_row(tree, mir, i); loop: ; #if _MIR_DEBUG /* check aggregated row */ check_agg_row(mir); #endif /* substitute fixed variables into aggregated constraint */ subst_fixed_vars(mir); #if _MIR_DEBUG /* check aggregated row */ check_agg_row(mir); #endif #if _MIR_DEBUG /* check bound substitution flags */ { int k; for (k = 1; k <= m+n; k++) xassert(mir->subst[k] == '?'); } #endif /* apply bound substitution heuristic */ bound_subst_heur(mir); /* substitute bounds and build modified constraint */ build_mod_row(mir); #if _MIR_DEBUG /* check modified row */ check_mod_row(mir); #endif /* try to generate violated c-MIR cut for modified row */ r_best = generate(mir); if (r_best > 0.0) { /* success */ #if _MIR_DEBUG /* check raw cut before back bound substitution */ check_raw_cut(mir, r_best); #endif /* back substitution of original bounds */ back_subst(mir); #if _MIR_DEBUG /* check the cut after back bound substitution */ check_cut_row(mir, r_best); #endif /* final substitution to eliminate auxiliary variables */ subst_aux_vars(tree, mir); #if _MIR_DEBUG /* check the cut after elimination of auxiliaries */ check_cut_row(mir, r_best); #endif /* add constructed cut inequality to the cut pool */ add_cut(tree, mir); } /* reset bound substitution flags */ { int j, k; for (j = 1; j <= mir->mod_vec->nnz; j++) { k = mir->mod_vec->ind[j]; xassert(1 <= k && k <= m+n); xassert(mir->subst[k] != '?'); mir->subst[k] = '?'; } } if (r_best == 0.0) { /* failure */ if (mir->agg_cnt < MAXAGGR) { /* try to aggregate another row */ if (aggregate_row(tree, mir) == 0) goto loop; } } /* unmark rows used in the aggregated constraint */ { int k, ii; for (k = 1; k <= mir->agg_cnt; k++) { ii = mir->agg_row[k]; xassert(1 <= ii && ii <= m); xassert(mir->skip[ii] == 2); mir->skip[ii] = 0; } } } return; } /*********************************************************************** * NAME * * ios_mir_term - terminate MIR cut generator * * SYNOPSIS * * #include "glpios.h" * void ios_mir_term(void *gen); * * DESCRIPTION * * The routine ios_mir_term deletes the MIR cut generator working area * freeing all the memory allocated to it. */ void ios_mir_term(void *gen) { struct MIR *mir = gen; xfree(mir->skip); xfree(mir->isint); xfree(mir->lb); xfree(mir->vlb); xfree(mir->ub); xfree(mir->vub); xfree(mir->x); xfree(mir->agg_row); ios_delete_vec(mir->agg_vec); xfree(mir->subst); ios_delete_vec(mir->mod_vec); ios_delete_vec(mir->cut_vec); xfree(mir); return; } /* eof */ praat-6.0.04/external/glpk/glpios07.c000066400000000000000000000452311261542461700173140ustar00rootroot00000000000000/* glpios07.c (mixed cover cut generator) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpios.h" /*---------------------------------------------------------------------- -- COVER INEQUALITIES -- -- Consider the set of feasible solutions to 0-1 knapsack problem: -- -- sum a[j]*x[j] <= b, (1) -- j in J -- -- x[j] is binary, (2) -- -- where, wlog, we assume that a[j] > 0 (since 0-1 variables can be -- complemented) and a[j] <= b (since a[j] > b implies x[j] = 0). -- -- A set C within J is called a cover if -- -- sum a[j] > b. (3) -- j in C -- -- For any cover C the inequality -- -- sum x[j] <= |C| - 1 (4) -- j in C -- -- is called a cover inequality and is valid for (1)-(2). -- -- MIXED COVER INEQUALITIES -- -- Consider the set of feasible solutions to mixed knapsack problem: -- -- sum a[j]*x[j] + y <= b, (5) -- j in J -- -- x[j] is binary, (6) -- -- 0 <= y <= u is continuous, (7) -- -- where again we assume that a[j] > 0. -- -- Let C within J be some set. From (1)-(4) it follows that -- -- sum a[j] > b - y (8) -- j in C -- -- implies -- -- sum x[j] <= |C| - 1. (9) -- j in C -- -- Thus, we need to modify the inequality (9) in such a way that it be -- a constraint only if the condition (8) is satisfied. -- -- Consider the following inequality: -- -- sum x[j] <= |C| - t. (10) -- j in C -- -- If 0 < t <= 1, then (10) is equivalent to (9), because all x[j] are -- binary variables. On the other hand, if t <= 0, (10) being satisfied -- for any values of x[j] is not a constraint. -- -- Let -- -- t' = sum a[j] + y - b. (11) -- j in C -- -- It is understood that the condition t' > 0 is equivalent to (8). -- Besides, from (6)-(7) it follows that t' has an implied upper bound: -- -- t'max = sum a[j] + u - b. (12) -- j in C -- -- This allows to express the parameter t having desired properties: -- -- t = t' / t'max. (13) -- -- In fact, t <= 1 by definition, and t > 0 being equivalent to t' > 0 -- is equivalent to (8). -- -- Thus, the inequality (10), where t is given by formula (13) is valid -- for (5)-(7). -- -- Note that if u = 0, then y = 0, so t = 1, and the conditions (8) and -- (10) is transformed to the conditions (3) and (4). -- -- GENERATING MIXED COVER CUTS -- -- To generate a mixed cover cut in the form (10) we need to find such -- set C which satisfies to the inequality (8) and for which, in turn, -- the inequality (10) is violated in the current point. -- -- Substituting t from (13) to (10) gives: -- -- 1 -- sum x[j] <= |C| - ----- (sum a[j] + y - b), (14) -- j in C t'max j in C -- -- and finally we have the cut inequality in the standard form: -- -- sum x[j] + alfa * y <= beta, (15) -- j in C -- -- where: -- -- alfa = 1 / t'max, (16) -- -- beta = |C| - alfa * (sum a[j] - b). (17) -- j in C */ #if 1 #define MAXTRY 1000 #else #define MAXTRY 10000 #endif static int cover2(int n, double a[], double b, double u, double x[], double y, int cov[], double *_alfa, double *_beta) { /* try to generate mixed cover cut using two-element cover */ int i, j, try = 0, ret = 0; double eps, alfa, beta, temp, rmax = 0.001; eps = 0.001 * (1.0 + fabs(b)); for (i = 0+1; i <= n; i++) for (j = i+1; j <= n; j++) { /* C = {i, j} */ try++; if (try > MAXTRY) goto done; /* check if condition (8) is satisfied */ if (a[i] + a[j] + y > b + eps) { /* compute parameters for inequality (15) */ temp = a[i] + a[j] - b; alfa = 1.0 / (temp + u); beta = 2.0 - alfa * temp; /* compute violation of inequality (15) */ temp = x[i] + x[j] + alfa * y - beta; /* choose C providing maximum violation */ if (rmax < temp) { rmax = temp; cov[1] = i; cov[2] = j; *_alfa = alfa; *_beta = beta; ret = 1; } } } done: return ret; } static int cover3(int n, double a[], double b, double u, double x[], double y, int cov[], double *_alfa, double *_beta) { /* try to generate mixed cover cut using three-element cover */ int i, j, k, try = 0, ret = 0; double eps, alfa, beta, temp, rmax = 0.001; eps = 0.001 * (1.0 + fabs(b)); for (i = 0+1; i <= n; i++) for (j = i+1; j <= n; j++) for (k = j+1; k <= n; k++) { /* C = {i, j, k} */ try++; if (try > MAXTRY) goto done; /* check if condition (8) is satisfied */ if (a[i] + a[j] + a[k] + y > b + eps) { /* compute parameters for inequality (15) */ temp = a[i] + a[j] + a[k] - b; alfa = 1.0 / (temp + u); beta = 3.0 - alfa * temp; /* compute violation of inequality (15) */ temp = x[i] + x[j] + x[k] + alfa * y - beta; /* choose C providing maximum violation */ if (rmax < temp) { rmax = temp; cov[1] = i; cov[2] = j; cov[3] = k; *_alfa = alfa; *_beta = beta; ret = 1; } } } done: return ret; } static int cover4(int n, double a[], double b, double u, double x[], double y, int cov[], double *_alfa, double *_beta) { /* try to generate mixed cover cut using four-element cover */ int i, j, k, l, try = 0, ret = 0; double eps, alfa, beta, temp, rmax = 0.001; eps = 0.001 * (1.0 + fabs(b)); for (i = 0+1; i <= n; i++) for (j = i+1; j <= n; j++) for (k = j+1; k <= n; k++) for (l = k+1; l <= n; l++) { /* C = {i, j, k, l} */ try++; if (try > MAXTRY) goto done; /* check if condition (8) is satisfied */ if (a[i] + a[j] + a[k] + a[l] + y > b + eps) { /* compute parameters for inequality (15) */ temp = a[i] + a[j] + a[k] + a[l] - b; alfa = 1.0 / (temp + u); beta = 4.0 - alfa * temp; /* compute violation of inequality (15) */ temp = x[i] + x[j] + x[k] + x[l] + alfa * y - beta; /* choose C providing maximum violation */ if (rmax < temp) { rmax = temp; cov[1] = i; cov[2] = j; cov[3] = k; cov[4] = l; *_alfa = alfa; *_beta = beta; ret = 1; } } } done: return ret; } static int cover(int n, double a[], double b, double u, double x[], double y, int cov[], double *alfa, double *beta) { /* try to generate mixed cover cut; input (see (5)): n is the number of binary variables; a[1:n] are coefficients at binary variables; b is the right-hand side; u is upper bound of continuous variable; x[1:n] are values of binary variables at current point; y is value of continuous variable at current point; output (see (15), (16), (17)): cov[1:r] are indices of binary variables included in cover C, where r is the set cardinality returned on exit; alfa coefficient at continuous variable; beta is the right-hand side; */ int j; /* perform some sanity checks */ xassert(n >= 2); for (j = 1; j <= n; j++) xassert(a[j] > 0.0); #if 1 /* ??? */ xassert(b > -1e-5); #else xassert(b > 0.0); #endif xassert(u >= 0.0); for (j = 1; j <= n; j++) xassert(0.0 <= x[j] && x[j] <= 1.0); xassert(0.0 <= y && y <= u); /* try to generate mixed cover cut */ if (cover2(n, a, b, u, x, y, cov, alfa, beta)) return 2; if (cover3(n, a, b, u, x, y, cov, alfa, beta)) return 3; if (cover4(n, a, b, u, x, y, cov, alfa, beta)) return 4; return 0; } /*---------------------------------------------------------------------- -- lpx_cover_cut - generate mixed cover cut. -- -- SYNOPSIS -- -- #include "glplpx.h" -- int lpx_cover_cut(LPX *lp, int len, int ind[], double val[], -- double work[]); -- -- DESCRIPTION -- -- The routine lpx_cover_cut generates a mixed cover cut for a given -- row of the MIP problem. -- -- The given row of the MIP problem should be explicitly specified in -- the form: -- -- sum{j in J} a[j]*x[j] <= b. (1) -- -- On entry indices (ordinal numbers) of structural variables, which -- have non-zero constraint coefficients, should be placed in locations -- ind[1], ..., ind[len], and corresponding constraint coefficients -- should be placed in locations val[1], ..., val[len]. The right-hand -- side b should be stored in location val[0]. -- -- The working array work should have at least nb locations, where nb -- is the number of binary variables in (1). -- -- The routine generates a mixed cover cut in the same form as (1) and -- stores the cut coefficients and right-hand side in the same way as -- just described above. -- -- RETURNS -- -- If the cutting plane has been successfully generated, the routine -- returns 1 <= len' <= n, which is the number of non-zero coefficients -- in the inequality constraint. Otherwise, the routine returns zero. */ static int lpx_cover_cut(LPX *lp, int len, int ind[], double val[], double work[]) { int cov[1+4], j, k, nb, newlen, r; double f_min, f_max, alfa, beta, u, *x = work, y; /* substitute and remove fixed variables */ newlen = 0; for (k = 1; k <= len; k++) { j = ind[k]; if (lpx_get_col_type(lp, j) == LPX_FX) val[0] -= val[k] * lpx_get_col_lb(lp, j); else { newlen++; ind[newlen] = ind[k]; val[newlen] = val[k]; } } len = newlen; /* move binary variables to the beginning of the list so that elements 1, 2, ..., nb correspond to binary variables, and elements nb+1, nb+2, ..., len correspond to rest variables */ nb = 0; for (k = 1; k <= len; k++) { j = ind[k]; if (lpx_get_col_kind(lp, j) == LPX_IV && lpx_get_col_type(lp, j) == LPX_DB && lpx_get_col_lb(lp, j) == 0.0 && lpx_get_col_ub(lp, j) == 1.0) { /* binary variable */ int ind_k; double val_k; nb++; ind_k = ind[nb], val_k = val[nb]; ind[nb] = ind[k], val[nb] = val[k]; ind[k] = ind_k, val[k] = val_k; } } /* now the specified row has the form: sum a[j]*x[j] + sum a[j]*y[j] <= b, where x[j] are binary variables, y[j] are rest variables */ /* at least two binary variables are needed */ if (nb < 2) return 0; /* compute implied lower and upper bounds for sum a[j]*y[j] */ f_min = f_max = 0.0; for (k = nb+1; k <= len; k++) { j = ind[k]; /* both bounds must be finite */ if (lpx_get_col_type(lp, j) != LPX_DB) return 0; if (val[k] > 0.0) { f_min += val[k] * lpx_get_col_lb(lp, j); f_max += val[k] * lpx_get_col_ub(lp, j); } else { f_min += val[k] * lpx_get_col_ub(lp, j); f_max += val[k] * lpx_get_col_lb(lp, j); } } /* sum a[j]*x[j] + sum a[j]*y[j] <= b ===> sum a[j]*x[j] + (sum a[j]*y[j] - f_min) <= b - f_min ===> sum a[j]*x[j] + y <= b - f_min, where y = sum a[j]*y[j] - f_min; note that 0 <= y <= u, u = f_max - f_min */ /* determine upper bound of y */ u = f_max - f_min; /* determine value of y at the current point */ y = 0.0; for (k = nb+1; k <= len; k++) { j = ind[k]; y += val[k] * lpx_get_col_prim(lp, j); } y -= f_min; if (y < 0.0) y = 0.0; if (y > u) y = u; /* modify the right-hand side b */ val[0] -= f_min; /* now the transformed row has the form: sum a[j]*x[j] + y <= b, where 0 <= y <= u */ /* determine values of x[j] at the current point */ for (k = 1; k <= nb; k++) { j = ind[k]; x[k] = lpx_get_col_prim(lp, j); if (x[k] < 0.0) x[k] = 0.0; if (x[k] > 1.0) x[k] = 1.0; } /* if a[j] < 0, replace x[j] by its complement 1 - x'[j] */ for (k = 1; k <= nb; k++) { if (val[k] < 0.0) { ind[k] = - ind[k]; val[k] = - val[k]; val[0] += val[k]; x[k] = 1.0 - x[k]; } } /* try to generate a mixed cover cut for the transformed row */ r = cover(nb, val, val[0], u, x, y, cov, &alfa, &beta); if (r == 0) return 0; xassert(2 <= r && r <= 4); /* now the cut is in the form: sum{j in C} x[j] + alfa * y <= beta */ /* store the right-hand side beta */ ind[0] = 0, val[0] = beta; /* restore the original ordinal numbers of x[j] */ for (j = 1; j <= r; j++) cov[j] = ind[cov[j]]; /* store cut coefficients at binary variables complementing back the variables having negative row coefficients */ xassert(r <= nb); for (k = 1; k <= r; k++) { if (cov[k] > 0) { ind[k] = +cov[k]; val[k] = +1.0; } else { ind[k] = -cov[k]; val[k] = -1.0; val[0] -= 1.0; } } /* substitute y = sum a[j]*y[j] - f_min */ for (k = nb+1; k <= len; k++) { r++; ind[r] = ind[k]; val[r] = alfa * val[k]; } val[0] += alfa * f_min; xassert(r <= len); len = r; return len; } /*---------------------------------------------------------------------- -- lpx_eval_row - compute explictily specified row. -- -- SYNOPSIS -- -- #include "glplpx.h" -- double lpx_eval_row(LPX *lp, int len, int ind[], double val[]); -- -- DESCRIPTION -- -- The routine lpx_eval_row computes the primal value of an explicitly -- specified row using current values of structural variables. -- -- The explicitly specified row may be thought as a linear form: -- -- y = a[1]*x[m+1] + a[2]*x[m+2] + ... + a[n]*x[m+n], -- -- where y is an auxiliary variable for this row, a[j] are coefficients -- of the linear form, x[m+j] are structural variables. -- -- On entry column indices and numerical values of non-zero elements of -- the row should be stored in locations ind[1], ..., ind[len] and -- val[1], ..., val[len], where len is the number of non-zero elements. -- The array ind and val are not changed on exit. -- -- RETURNS -- -- The routine returns a computed value of y, the auxiliary variable of -- the specified row. */ static double lpx_eval_row(LPX *lp, int len, int ind[], double val[]) { int n = lpx_get_num_cols(lp); int j, k; double sum = 0.0; if (len < 0) xerror("lpx_eval_row: len = %d; invalid row length\n", len); for (k = 1; k <= len; k++) { j = ind[k]; if (!(1 <= j && j <= n)) xerror("lpx_eval_row: j = %d; column number out of range\n", j); sum += val[k] * lpx_get_col_prim(lp, j); } return sum; } /*********************************************************************** * NAME * * ios_cov_gen - generate mixed cover cuts * * SYNOPSIS * * #include "glpios.h" * void ios_cov_gen(glp_tree *tree); * * DESCRIPTION * * The routine ios_cov_gen generates mixed cover cuts for the current * point and adds them to the cut pool. */ void ios_cov_gen(glp_tree *tree) { glp_prob *prob = tree->mip; int m = lpx_get_num_rows(prob); int n = lpx_get_num_cols(prob); int i, k, type, kase, len, *ind; double r, *val, *work; xassert(lpx_get_status(prob) == LPX_OPT); /* allocate working arrays */ ind = xcalloc(1+n, sizeof(int)); val = xcalloc(1+n, sizeof(double)); work = xcalloc(1+n, sizeof(double)); /* look through all rows */ for (i = 1; i <= m; i++) for (kase = 1; kase <= 2; kase++) { type = lpx_get_row_type(prob, i); if (kase == 1) { /* consider rows of '<=' type */ if (!(type == LPX_UP || type == LPX_DB)) continue; len = lpx_get_mat_row(prob, i, ind, val); val[0] = lpx_get_row_ub(prob, i); } else { /* consider rows of '>=' type */ if (!(type == LPX_LO || type == LPX_DB)) continue; len = lpx_get_mat_row(prob, i, ind, val); for (k = 1; k <= len; k++) val[k] = - val[k]; val[0] = - lpx_get_row_lb(prob, i); } /* generate mixed cover cut: sum{j in J} a[j] * x[j] <= b */ len = lpx_cover_cut(prob, len, ind, val, work); if (len == 0) continue; /* at the current point the cut inequality is violated, i.e. sum{j in J} a[j] * x[j] - b > 0 */ r = lpx_eval_row(prob, len, ind, val) - val[0]; if (r < 1e-3) continue; /* add the cut to the cut pool */ glp_ios_add_row(tree, NULL, GLP_RF_COV, 0, len, ind, val, GLP_UP, val[0]); } /* free working arrays */ xfree(ind); xfree(val); xfree(work); return; } /* eof */ praat-6.0.04/external/glpk/glpios08.c000066400000000000000000000672021261542461700173170ustar00rootroot00000000000000/* glpios08.c (clique cut generator) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpios.h" static double get_row_lb(LPX *lp, int i) { /* this routine returns lower bound of row i or -DBL_MAX if the row has no lower bound */ double lb; switch (lpx_get_row_type(lp, i)) { case LPX_FR: case LPX_UP: lb = -DBL_MAX; break; case LPX_LO: case LPX_DB: case LPX_FX: lb = lpx_get_row_lb(lp, i); break; default: xassert(lp != lp); } return lb; } static double get_row_ub(LPX *lp, int i) { /* this routine returns upper bound of row i or +DBL_MAX if the row has no upper bound */ double ub; switch (lpx_get_row_type(lp, i)) { case LPX_FR: case LPX_LO: ub = +DBL_MAX; break; case LPX_UP: case LPX_DB: case LPX_FX: ub = lpx_get_row_ub(lp, i); break; default: xassert(lp != lp); } return ub; } static double get_col_lb(LPX *lp, int j) { /* this routine returns lower bound of column j or -DBL_MAX if the column has no lower bound */ double lb; switch (lpx_get_col_type(lp, j)) { case LPX_FR: case LPX_UP: lb = -DBL_MAX; break; case LPX_LO: case LPX_DB: case LPX_FX: lb = lpx_get_col_lb(lp, j); break; default: xassert(lp != lp); } return lb; } static double get_col_ub(LPX *lp, int j) { /* this routine returns upper bound of column j or +DBL_MAX if the column has no upper bound */ double ub; switch (lpx_get_col_type(lp, j)) { case LPX_FR: case LPX_LO: ub = +DBL_MAX; break; case LPX_UP: case LPX_DB: case LPX_FX: ub = lpx_get_col_ub(lp, j); break; default: xassert(lp != lp); } return ub; } static int is_binary(LPX *lp, int j) { /* this routine checks if variable x[j] is binary */ return lpx_get_col_kind(lp, j) == LPX_IV && lpx_get_col_type(lp, j) == LPX_DB && lpx_get_col_lb(lp, j) == 0.0 && lpx_get_col_ub(lp, j) == 1.0; } static double eval_lf_min(LPX *lp, int len, int ind[], double val[]) { /* this routine computes the minimum of a specified linear form sum a[j]*x[j] j using the formula: min = sum a[j]*lb[j] + sum a[j]*ub[j], j in J+ j in J- where J+ = {j: a[j] > 0}, J- = {j: a[j] < 0}, lb[j] and ub[j] are lower and upper bound of variable x[j], resp. */ int j, t; double lb, ub, sum; sum = 0.0; for (t = 1; t <= len; t++) { j = ind[t]; if (val[t] > 0.0) { lb = get_col_lb(lp, j); if (lb == -DBL_MAX) { sum = -DBL_MAX; break; } sum += val[t] * lb; } else if (val[t] < 0.0) { ub = get_col_ub(lp, j); if (ub == +DBL_MAX) { sum = -DBL_MAX; break; } sum += val[t] * ub; } else xassert(val != val); } return sum; } static double eval_lf_max(LPX *lp, int len, int ind[], double val[]) { /* this routine computes the maximum of a specified linear form sum a[j]*x[j] j using the formula: max = sum a[j]*ub[j] + sum a[j]*lb[j], j in J+ j in J- where J+ = {j: a[j] > 0}, J- = {j: a[j] < 0}, lb[j] and ub[j] are lower and upper bound of variable x[j], resp. */ int j, t; double lb, ub, sum; sum = 0.0; for (t = 1; t <= len; t++) { j = ind[t]; if (val[t] > 0.0) { ub = get_col_ub(lp, j); if (ub == +DBL_MAX) { sum = +DBL_MAX; break; } sum += val[t] * ub; } else if (val[t] < 0.0) { lb = get_col_lb(lp, j); if (lb == -DBL_MAX) { sum = +DBL_MAX; break; } sum += val[t] * lb; } else xassert(val != val); } return sum; } /*---------------------------------------------------------------------- -- probing - determine logical relation between binary variables. -- -- This routine tentatively sets a binary variable to 0 and then to 1 -- and examines whether another binary variable is caused to be fixed. -- -- The examination is based only on one row (constraint), which is the -- following: -- -- L <= sum a[j]*x[j] <= U. (1) -- j -- -- Let x[p] be a probing variable, x[q] be an examined variable. Then -- (1) can be written as: -- -- L <= sum a[j]*x[j] + a[p]*x[p] + a[q]*x[q] <= U, (2) -- j in J' -- -- where J' = {j: j != p and j != q}. -- -- Let -- -- L' = L - a[p]*x[p], (3) -- -- U' = U - a[p]*x[p], (4) -- -- where x[p] is assumed to be fixed at 0 or 1. So (2) can be rewritten -- as follows: -- -- L' <= sum a[j]*x[j] + a[q]*x[q] <= U', (5) -- j in J' -- -- from where we have: -- -- L' - sum a[j]*x[j] <= a[q]*x[q] <= U' - sum a[j]*x[j]. (6) -- j in J' j in J' -- -- Thus, -- -- min a[q]*x[q] = L' - MAX, (7) -- -- max a[q]*x[q] = U' - MIN, (8) -- -- where -- -- MIN = min sum a[j]*x[j], (9) -- j in J' -- -- MAX = max sum a[j]*x[j]. (10) -- j in J' -- -- Formulae (7) and (8) allows determining implied lower and upper -- bounds of x[q]. -- -- Parameters len, val, L and U specify the constraint (1). -- -- Parameters lf_min and lf_max specify implied lower and upper bounds -- of the linear form (1). It is assumed that these bounds are computed -- with the routines eval_lf_min and eval_lf_max (see above). -- -- Parameter p specifies the probing variable x[p], which is set to 0 -- (if set is 0) or to 1 (if set is 1). -- -- Parameter q specifies the examined variable x[q]. -- -- On exit the routine returns one of the following codes: -- -- 0 - there is no logical relation between x[p] and x[q]; -- 1 - x[q] can take only on value 0; -- 2 - x[q] can take only on value 1. */ static int probing(int len, double val[], double L, double U, double lf_min, double lf_max, int p, int set, int q) { double temp; xassert(1 <= p && p < q && q <= len); /* compute L' (3) */ if (L != -DBL_MAX && set) L -= val[p]; /* compute U' (4) */ if (U != +DBL_MAX && set) U -= val[p]; /* compute MIN (9) */ if (lf_min != -DBL_MAX) { if (val[p] < 0.0) lf_min -= val[p]; if (val[q] < 0.0) lf_min -= val[q]; } /* compute MAX (10) */ if (lf_max != +DBL_MAX) { if (val[p] > 0.0) lf_max -= val[p]; if (val[q] > 0.0) lf_max -= val[q]; } /* compute implied lower bound of x[q]; see (7), (8) */ if (val[q] > 0.0) { if (L == -DBL_MAX || lf_max == +DBL_MAX) temp = -DBL_MAX; else temp = (L - lf_max) / val[q]; } else { if (U == +DBL_MAX || lf_min == -DBL_MAX) temp = -DBL_MAX; else temp = (U - lf_min) / val[q]; } if (temp > 0.001) return 2; /* compute implied upper bound of x[q]; see (7), (8) */ if (val[q] > 0.0) { if (U == +DBL_MAX || lf_min == -DBL_MAX) temp = +DBL_MAX; else temp = (U - lf_min) / val[q]; } else { if (L == -DBL_MAX || lf_max == +DBL_MAX) temp = +DBL_MAX; else temp = (L - lf_max) / val[q]; } if (temp < 0.999) return 1; /* there is no logical relation between x[p] and x[q] */ return 0; } struct COG { /* conflict graph; it represents logical relations between binary variables and has a vertex for each binary variable and its complement, and an edge between two vertices when at most one of the variables represented by the vertices can equal one in an optimal solution */ int n; /* number of variables */ int nb; /* number of binary variables represented in the graph (note that not all binary variables can be represented); vertices which correspond to binary variables have numbers 1, ..., nb while vertices which correspond to complements of binary variables have numbers nb+1, ..., nb+nb */ int ne; /* number of edges in the graph */ int *vert; /* int vert[1+n]; */ /* if x[j] is a binary variable represented in the graph, vert[j] is the vertex number corresponding to x[j]; otherwise vert[j] is zero */ int *orig; /* int list[1:nb]; */ /* if vert[j] = k > 0, then orig[k] = j */ unsigned char *a; /* adjacency matrix of the graph having 2*nb rows and columns; only strict lower triangle is stored in dense packed form */ }; /*---------------------------------------------------------------------- -- lpx_create_cog - create the conflict graph. -- -- SYNOPSIS -- -- #include "glplpx.h" -- void *lpx_create_cog(LPX *lp); -- -- DESCRIPTION -- -- The routine lpx_create_cog creates the conflict graph for a given -- problem instance. -- -- RETURNS -- -- If the graph has been created, the routine returns a pointer to it. -- Otherwise the routine returns NULL. */ #define MAX_NB 4000 #define MAX_ROW_LEN 500 static void lpx_add_cog_edge(void *_cog, int i, int j); static void *lpx_create_cog(LPX *lp) { struct COG *cog = NULL; int m, n, nb, i, j, p, q, len, *ind, *vert, *orig; double L, U, lf_min, lf_max, *val; xprintf("Creating the conflict graph...\n"); m = lpx_get_num_rows(lp); n = lpx_get_num_cols(lp); /* determine which binary variables should be included in the conflict graph */ nb = 0; vert = xcalloc(1+n, sizeof(int)); for (j = 1; j <= n; j++) vert[j] = 0; orig = xcalloc(1+n, sizeof(int)); ind = xcalloc(1+n, sizeof(int)); val = xcalloc(1+n, sizeof(double)); for (i = 1; i <= m; i++) { L = get_row_lb(lp, i); U = get_row_ub(lp, i); if (L == -DBL_MAX && U == +DBL_MAX) continue; len = lpx_get_mat_row(lp, i, ind, val); if (len > MAX_ROW_LEN) continue; lf_min = eval_lf_min(lp, len, ind, val); lf_max = eval_lf_max(lp, len, ind, val); for (p = 1; p <= len; p++) { if (!is_binary(lp, ind[p])) continue; for (q = p+1; q <= len; q++) { if (!is_binary(lp, ind[q])) continue; if (probing(len, val, L, U, lf_min, lf_max, p, 0, q) || probing(len, val, L, U, lf_min, lf_max, p, 1, q)) { /* there is a logical relation */ /* include the first variable in the graph */ j = ind[p]; if (vert[j] == 0) nb++, vert[j] = nb, orig[nb] = j; /* incude the second variable in the graph */ j = ind[q]; if (vert[j] == 0) nb++, vert[j] = nb, orig[nb] = j; } } } } /* if the graph is either empty or has too many vertices, do not create it */ if (nb == 0 || nb > MAX_NB) { xprintf("The conflict graph is either empty or too big\n"); xfree(vert); xfree(orig); goto done; } /* create the conflict graph */ cog = xmalloc(sizeof(struct COG)); cog->n = n; cog->nb = nb; cog->ne = 0; cog->vert = vert; cog->orig = orig; len = nb + nb; /* number of vertices */ len = (len * (len - 1)) / 2; /* number of entries in triangle */ len = (len + (CHAR_BIT - 1)) / CHAR_BIT; /* bytes needed */ cog->a = xmalloc(len); memset(cog->a, 0, len); for (j = 1; j <= nb; j++) { /* add edge between variable and its complement */ lpx_add_cog_edge(cog, +orig[j], -orig[j]); } for (i = 1; i <= m; i++) { L = get_row_lb(lp, i); U = get_row_ub(lp, i); if (L == -DBL_MAX && U == +DBL_MAX) continue; len = lpx_get_mat_row(lp, i, ind, val); if (len > MAX_ROW_LEN) continue; lf_min = eval_lf_min(lp, len, ind, val); lf_max = eval_lf_max(lp, len, ind, val); for (p = 1; p <= len; p++) { if (!is_binary(lp, ind[p])) continue; for (q = p+1; q <= len; q++) { if (!is_binary(lp, ind[q])) continue; /* set x[p] to 0 and examine x[q] */ switch (probing(len, val, L, U, lf_min, lf_max, p, 0, q)) { case 0: /* no logical relation */ break; case 1: /* x[p] = 0 implies x[q] = 0 */ lpx_add_cog_edge(cog, -ind[p], +ind[q]); break; case 2: /* x[p] = 0 implies x[q] = 1 */ lpx_add_cog_edge(cog, -ind[p], -ind[q]); break; default: xassert(lp != lp); } /* set x[p] to 1 and examine x[q] */ switch (probing(len, val, L, U, lf_min, lf_max, p, 1, q)) { case 0: /* no logical relation */ break; case 1: /* x[p] = 1 implies x[q] = 0 */ lpx_add_cog_edge(cog, +ind[p], +ind[q]); break; case 2: /* x[p] = 1 implies x[q] = 1 */ lpx_add_cog_edge(cog, +ind[p], -ind[q]); break; default: xassert(lp != lp); } } } } xprintf("The conflict graph has 2*%d vertices and %d edges\n", cog->nb, cog->ne); done: xfree(ind); xfree(val); return cog; } /*---------------------------------------------------------------------- -- lpx_add_cog_edge - add edge to the conflict graph. -- -- SYNOPSIS -- -- #include "glplpx.h" -- void lpx_add_cog_edge(void *cog, int i, int j); -- -- DESCRIPTION -- -- The routine lpx_add_cog_edge adds an edge to the conflict graph. -- The edge connects x[i] (if i > 0) or its complement (if i < 0) and -- x[j] (if j > 0) or its complement (if j < 0), where i and j are -- original ordinal numbers of corresponding variables. */ static void lpx_add_cog_edge(void *_cog, int i, int j) { struct COG *cog = _cog; int k; xassert(i != j); /* determine indices of corresponding vertices */ if (i > 0) { xassert(1 <= i && i <= cog->n); i = cog->vert[i]; xassert(i != 0); } else { i = -i; xassert(1 <= i && i <= cog->n); i = cog->vert[i]; xassert(i != 0); i += cog->nb; } if (j > 0) { xassert(1 <= j && j <= cog->n); j = cog->vert[j]; xassert(j != 0); } else { j = -j; xassert(1 <= j && j <= cog->n); j = cog->vert[j]; xassert(j != 0); j += cog->nb; } /* only lower triangle is stored, so we need i > j */ if (i < j) k = i, i = j, j = k; k = ((i - 1) * (i - 2)) / 2 + (j - 1); cog->a[k / CHAR_BIT] |= (unsigned char)(1 << ((CHAR_BIT - 1) - k % CHAR_BIT)); cog->ne++; return; } /*---------------------------------------------------------------------- -- MAXIMUM WEIGHT CLIQUE -- -- Two subroutines sub() and wclique() below are intended to find a -- maximum weight clique in a given undirected graph. These subroutines -- are slightly modified version of the program WCLIQUE developed by -- Patric Ostergard and based -- on ideas from the article "P. R. J. Ostergard, A new algorithm for -- the maximum-weight clique problem, submitted for publication", which -- in turn is a generalization of the algorithm for unweighted graphs -- presented in "P. R. J. Ostergard, A fast algorithm for the maximum -- clique problem, submitted for publication". -- -- USED WITH PERMISSION OF THE AUTHOR OF THE ORIGINAL CODE. */ struct dsa { /* dynamic storage area */ int n; /* number of vertices */ int *wt; /* int wt[0:n-1]; */ /* weights */ unsigned char *a; /* adjacency matrix (packed lower triangle without main diag.) */ int record; /* weight of best clique */ int rec_level; /* number of vertices in best clique */ int *rec; /* int rec[0:n-1]; */ /* best clique so far */ int *clique; /* int clique[0:n-1]; */ /* table for pruning */ int *set; /* int set[0:n-1]; */ /* current clique */ }; #define n (dsa->n) #define wt (dsa->wt) #define a (dsa->a) #define record (dsa->record) #define rec_level (dsa->rec_level) #define rec (dsa->rec) #define clique (dsa->clique) #define set (dsa->set) #if 0 static int is_edge(struct dsa *dsa, int i, int j) { /* if there is arc (i,j), the routine returns true; otherwise false; 0 <= i, j < n */ int k; xassert(0 <= i && i < n); xassert(0 <= j && j < n); if (i == j) return 0; if (i < j) k = i, i = j, j = k; k = (i * (i - 1)) / 2 + j; return a[k / CHAR_BIT] & (unsigned char)(1 << ((CHAR_BIT - 1) - k % CHAR_BIT)); } #else #define is_edge(dsa, i, j) ((i) == (j) ? 0 : \ (i) > (j) ? is_edge1(i, j) : is_edge1(j, i)) #define is_edge1(i, j) is_edge2(((i) * ((i) - 1)) / 2 + (j)) #define is_edge2(k) (a[(k) / CHAR_BIT] & \ (unsigned char)(1 << ((CHAR_BIT - 1) - (k) % CHAR_BIT))) #endif static void sub(struct dsa *dsa, int ct, int table[], int level, int weight, int l_weight) { int i, j, k, curr_weight, left_weight, *p1, *p2, *newtable; newtable = xcalloc(n, sizeof(int)); if (ct <= 0) { /* 0 or 1 elements left; include these */ if (ct == 0) { set[level++] = table[0]; weight += l_weight; } if (weight > record) { record = weight; rec_level = level; for (i = 0; i < level; i++) rec[i] = set[i]; } goto done; } for (i = ct; i >= 0; i--) { if ((level == 0) && (i < ct)) goto done; k = table[i]; if ((level > 0) && (clique[k] <= (record - weight))) goto done; /* prune */ set[level] = k; curr_weight = weight + wt[k]; l_weight -= wt[k]; if (l_weight <= (record - curr_weight)) goto done; /* prune */ p1 = newtable; p2 = table; left_weight = 0; while (p2 < table + i) { j = *p2++; if (is_edge(dsa, j, k)) { *p1++ = j; left_weight += wt[j]; } } if (left_weight <= (record - curr_weight)) continue; sub(dsa, p1 - newtable - 1, newtable, level + 1, curr_weight, left_weight); } done: xfree(newtable); return; } static int wclique(int _n, int w[], unsigned char _a[], int sol[]) { struct dsa _dsa, *dsa = &_dsa; int i, j, p, max_wt, max_nwt, wth, *used, *nwt, *pos; glp_long timer; n = _n; wt = &w[1]; a = _a; record = 0; rec_level = 0; rec = &sol[1]; clique = xcalloc(n, sizeof(int)); set = xcalloc(n, sizeof(int)); used = xcalloc(n, sizeof(int)); nwt = xcalloc(n, sizeof(int)); pos = xcalloc(n, sizeof(int)); /* start timer */ timer = xtime(); /* order vertices */ for (i = 0; i < n; i++) { nwt[i] = 0; for (j = 0; j < n; j++) if (is_edge(dsa, i, j)) nwt[i] += wt[j]; } for (i = 0; i < n; i++) used[i] = 0; for (i = n-1; i >= 0; i--) { max_wt = -1; max_nwt = -1; for (j = 0; j < n; j++) { if ((!used[j]) && ((wt[j] > max_wt) || (wt[j] == max_wt && nwt[j] > max_nwt))) { max_wt = wt[j]; max_nwt = nwt[j]; p = j; } } pos[i] = p; used[p] = 1; for (j = 0; j < n; j++) if ((!used[j]) && (j != p) && (is_edge(dsa, p, j))) nwt[j] -= wt[p]; } /* main routine */ wth = 0; for (i = 0; i < n; i++) { wth += wt[pos[i]]; sub(dsa, i, pos, 0, 0, wth); clique[pos[i]] = record; #if 0 if (utime() >= timer + 5.0) #else if (xdifftime(xtime(), timer) >= 5.0 - 0.001) #endif { /* print current record and reset timer */ xprintf("level = %d (%d); best = %d\n", i+1, n, record); #if 0 timer = utime(); #else timer = xtime(); #endif } } xfree(clique); xfree(set); xfree(used); xfree(nwt); xfree(pos); /* return the solution found */ for (i = 1; i <= rec_level; i++) sol[i]++; return rec_level; } #undef n #undef wt #undef a #undef record #undef rec_level #undef rec #undef clique #undef set /*---------------------------------------------------------------------- -- lpx_clique_cut - generate cluque cut. -- -- SYNOPSIS -- -- #include "glplpx.h" -- int lpx_clique_cut(LPX *lp, void *cog, int ind[], double val[]); -- -- DESCRIPTION -- -- The routine lpx_clique_cut generates a clique cut using the conflict -- graph specified by the parameter cog. -- -- If a violated clique cut has been found, it has the following form: -- -- sum{j in J} a[j]*x[j] <= b. -- -- Variable indices j in J are stored in elements ind[1], ..., ind[len] -- while corresponding constraint coefficients are stored in elements -- val[1], ..., val[len], where len is returned on exit. The right-hand -- side b is stored in element val[0]. -- -- RETURNS -- -- If the cutting plane has been successfully generated, the routine -- returns 1 <= len <= n, which is the number of non-zero coefficients -- in the inequality constraint. Otherwise, the routine returns zero. */ static int lpx_clique_cut(LPX *lp, void *_cog, int ind[], double val[]) { struct COG *cog = _cog; int n = lpx_get_num_cols(lp); int j, t, v, card, temp, len = 0, *w, *sol; double x, sum, b, *vec; /* allocate working arrays */ w = xcalloc(1 + 2 * cog->nb, sizeof(int)); sol = xcalloc(1 + 2 * cog->nb, sizeof(int)); vec = xcalloc(1+n, sizeof(double)); /* assign weights to vertices of the conflict graph */ for (t = 1; t <= cog->nb; t++) { j = cog->orig[t]; x = lpx_get_col_prim(lp, j); temp = (int)(100.0 * x + 0.5); if (temp < 0) temp = 0; if (temp > 100) temp = 100; w[t] = temp; w[cog->nb + t] = 100 - temp; } /* find a clique of maximum weight */ card = wclique(2 * cog->nb, w, cog->a, sol); /* compute the clique weight for unscaled values */ sum = 0.0; for ( t = 1; t <= card; t++) { v = sol[t]; xassert(1 <= v && v <= 2 * cog->nb); if (v <= cog->nb) { /* vertex v corresponds to binary variable x[j] */ j = cog->orig[v]; x = lpx_get_col_prim(lp, j); sum += x; } else { /* vertex v corresponds to the complement of x[j] */ j = cog->orig[v - cog->nb]; x = lpx_get_col_prim(lp, j); sum += 1.0 - x; } } /* if the sum of binary variables and their complements in the clique greater than 1, the clique cut is violated */ if (sum >= 1.01) { /* construct the inquality */ for (j = 1; j <= n; j++) vec[j] = 0; b = 1.0; for (t = 1; t <= card; t++) { v = sol[t]; if (v <= cog->nb) { /* vertex v corresponds to binary variable x[j] */ j = cog->orig[v]; xassert(1 <= j && j <= n); vec[j] += 1.0; } else { /* vertex v corresponds to the complement of x[j] */ j = cog->orig[v - cog->nb]; xassert(1 <= j && j <= n); vec[j] -= 1.0; b -= 1.0; } } xassert(len == 0); for (j = 1; j <= n; j++) { if (vec[j] != 0.0) { len++; ind[len] = j, val[len] = vec[j]; } } ind[0] = 0, val[0] = b; } /* free working arrays */ xfree(w); xfree(sol); xfree(vec); /* return to the calling program */ return len; } /*---------------------------------------------------------------------- -- lpx_delete_cog - delete the conflict graph. -- -- SYNOPSIS -- -- #include "glplpx.h" -- void lpx_delete_cog(void *cog); -- -- DESCRIPTION -- -- The routine lpx_delete_cog deletes the conflict graph, which the -- parameter cog points to, freeing all the memory allocated to this -- object. */ static void lpx_delete_cog(void *_cog) { struct COG *cog = _cog; xfree(cog->vert); xfree(cog->orig); xfree(cog->a); xfree(cog); } /**********************************************************************/ void *ios_clq_init(glp_tree *tree) { /* initialize clique cut generator */ glp_prob *mip = tree->mip; xassert(mip != NULL); return lpx_create_cog(mip); } /*********************************************************************** * NAME * * ios_clq_gen - generate clique cuts * * SYNOPSIS * * #include "glpios.h" * void ios_clq_gen(glp_tree *tree, void *gen); * * DESCRIPTION * * The routine ios_clq_gen generates clique cuts for the current point * and adds them to the clique pool. */ void ios_clq_gen(glp_tree *tree, void *gen) { int n = lpx_get_num_cols(tree->mip); int len, *ind; double *val; xassert(gen != NULL); ind = xcalloc(1+n, sizeof(int)); val = xcalloc(1+n, sizeof(double)); len = lpx_clique_cut(tree->mip, gen, ind, val); if (len > 0) { /* xprintf("len = %d\n", len); */ glp_ios_add_row(tree, NULL, GLP_RF_CLQ, 0, len, ind, val, GLP_UP, val[0]); } xfree(ind); xfree(val); return; } /**********************************************************************/ void ios_clq_term(void *gen) { /* terminate clique cut generator */ xassert(gen != NULL); lpx_delete_cog(gen); return; } /* eof */ praat-6.0.04/external/glpk/glpios09.c000066400000000000000000000631301261542461700173140ustar00rootroot00000000000000/* glpios09.c (branching heuristics) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpios.h" /*********************************************************************** * NAME * * ios_choose_var - select variable to branch on * * SYNOPSIS * * #include "glpios.h" * int ios_choose_var(glp_tree *T, int *next); * * The routine ios_choose_var chooses a variable from the candidate * list to branch on. Additionally the routine provides a flag stored * in the location next to suggests which of the child subproblems * should be solved next. * * RETURNS * * The routine ios_choose_var returns the ordinal number of the column * choosen. */ static int branch_first(glp_tree *T, int *next); static int branch_last(glp_tree *T, int *next); static int branch_mostf(glp_tree *T, int *next); static int branch_drtom(glp_tree *T, int *next); int ios_choose_var(glp_tree *T, int *next) { int j; if (T->parm->br_tech == GLP_BR_FFV) { /* branch on first fractional variable */ j = branch_first(T, next); } else if (T->parm->br_tech == GLP_BR_LFV) { /* branch on last fractional variable */ j = branch_last(T, next); } else if (T->parm->br_tech == GLP_BR_MFV) { /* branch on most fractional variable */ j = branch_mostf(T, next); } else if (T->parm->br_tech == GLP_BR_DTH) { /* branch using the heuristic by Dreebeck and Tomlin */ j = branch_drtom(T, next); } else if (T->parm->br_tech == GLP_BR_PCH) { /* hybrid pseudocost heuristic */ j = ios_pcost_branch(T, next); } else xassert(T != T); return j; } /*********************************************************************** * branch_first - choose first branching variable * * This routine looks up the list of structural variables and chooses * the first one, which is of integer kind and has fractional value in * optimal solution to the current LP relaxation. * * This routine also selects the branch to be solved next where integer * infeasibility of the chosen variable is less than in other one. */ static int branch_first(glp_tree *T, int *_next) { int j, next; double beta; /* choose the column to branch on */ for (j = 1; j <= T->n; j++) if (T->non_int[j]) break; xassert(1 <= j && j <= T->n); /* select the branch to be solved next */ beta = glp_get_col_prim(T->mip, j); if (beta - floor(beta) < ceil(beta) - beta) next = GLP_DN_BRNCH; else next = GLP_UP_BRNCH; *_next = next; return j; } /*********************************************************************** * branch_last - choose last branching variable * * This routine looks up the list of structural variables and chooses * the last one, which is of integer kind and has fractional value in * optimal solution to the current LP relaxation. * * This routine also selects the branch to be solved next where integer * infeasibility of the chosen variable is less than in other one. */ static int branch_last(glp_tree *T, int *_next) { int j, next; double beta; /* choose the column to branch on */ for (j = T->n; j >= 1; j--) if (T->non_int[j]) break; xassert(1 <= j && j <= T->n); /* select the branch to be solved next */ beta = glp_get_col_prim(T->mip, j); if (beta - floor(beta) < ceil(beta) - beta) next = GLP_DN_BRNCH; else next = GLP_UP_BRNCH; *_next = next; return j; } /*********************************************************************** * branch_mostf - choose most fractional branching variable * * This routine looks up the list of structural variables and chooses * that one, which is of integer kind and has most fractional value in * optimal solution to the current LP relaxation. * * This routine also selects the branch to be solved next where integer * infeasibility of the chosen variable is less than in other one. * * (Alexander Martin notices that "...most infeasible is as good as * random...".) */ static int branch_mostf(glp_tree *T, int *_next) { int j, jj, next; double beta, most, temp; /* choose the column to branch on */ jj = 0, most = DBL_MAX; for (j = 1; j <= T->n; j++) { if (T->non_int[j]) { beta = glp_get_col_prim(T->mip, j); temp = floor(beta) + 0.5; if (most > fabs(beta - temp)) { jj = j, most = fabs(beta - temp); if (beta < temp) next = GLP_DN_BRNCH; else next = GLP_UP_BRNCH; } } } *_next = next; return jj; } /*********************************************************************** * branch_drtom - choose branching var using Driebeck-Tomlin heuristic * * This routine chooses a structural variable, which is required to be * integral and has fractional value in optimal solution of the current * LP relaxation, using a heuristic proposed by Driebeck and Tomlin. * * The routine also selects the branch to be solved next, again due to * Driebeck and Tomlin. * * This routine is based on the heuristic proposed in: * * Driebeck N.J. An algorithm for the solution of mixed-integer * programming problems, Management Science, 12: 576-87 (1966); * * and improved in: * * Tomlin J.A. Branch and bound methods for integer and non-convex * programming, in J.Abadie (ed.), Integer and Nonlinear Programming, * North-Holland, Amsterdam, pp. 437-50 (1970). * * Must note that this heuristic is time-expensive, because computing * one-step degradation (see the routine below) requires one BTRAN for * each fractional-valued structural variable. */ static int branch_drtom(glp_tree *T, int *_next) { glp_prob *mip = T->mip; int m = mip->m; int n = mip->n; unsigned char *non_int = T->non_int; int j, jj, k, t, next, kase, len, stat, *ind; double x, dk, alfa, delta_j, delta_k, delta_z, dz_dn, dz_up, dd_dn, dd_up, degrad, *val; /* basic solution of LP relaxation must be optimal */ xassert(glp_get_status(mip) == GLP_OPT); /* allocate working arrays */ ind = xcalloc(1+n, sizeof(int)); val = xcalloc(1+n, sizeof(double)); /* nothing has been chosen so far */ jj = 0, degrad = -1.0; /* walk through the list of columns (structural variables) */ for (j = 1; j <= n; j++) { /* if j-th column is not marked as fractional, skip it */ if (!non_int[j]) continue; /* obtain (fractional) value of j-th column in basic solution of LP relaxation */ x = glp_get_col_prim(mip, j); /* since the value of j-th column is fractional, the column is basic; compute corresponding row of the simplex table */ len = glp_eval_tab_row(mip, m+j, ind, val); /* the following fragment computes a change in the objective function: delta Z = new Z - old Z, where old Z is the objective value in the current optimal basis, and new Z is the objective value in the adjacent basis, for two cases: 1) if new upper bound ub' = floor(x[j]) is introduced for j-th column (down branch); 2) if new lower bound lb' = ceil(x[j]) is introduced for j-th column (up branch); since in both cases the solution remaining dual feasible becomes primal infeasible, one implicit simplex iteration is performed to determine the change delta Z; it is obvious that new Z, which is never better than old Z, is a lower (minimization) or upper (maximization) bound of the objective function for down- and up-branches. */ for (kase = -1; kase <= +1; kase += 2) { /* if kase < 0, the new upper bound of x[j] is introduced; in this case x[j] should decrease in order to leave the basis and go to its new upper bound */ /* if kase > 0, the new lower bound of x[j] is introduced; in this case x[j] should increase in order to leave the basis and go to its new lower bound */ /* apply the dual ratio test in order to determine which auxiliary or structural variable should enter the basis to keep dual feasibility */ k = glp_dual_rtest(mip, len, ind, val, kase, 1e-9); if (k != 0) k = ind[k]; /* if no non-basic variable has been chosen, LP relaxation of corresponding branch being primal infeasible and dual unbounded has no primal feasible solution; in this case the change delta Z is formally set to infinity */ if (k == 0) { delta_z = (T->mip->dir == GLP_MIN ? +DBL_MAX : -DBL_MAX); goto skip; } /* row of the simplex table that corresponds to non-basic variable x[k] choosen by the dual ratio test is: x[j] = ... + alfa * x[k] + ... where alfa is the influence coefficient (an element of the simplex table row) */ /* determine the coefficient alfa */ for (t = 1; t <= len; t++) if (ind[t] == k) break; xassert(1 <= t && t <= len); alfa = val[t]; /* since in the adjacent basis the variable x[j] becomes non-basic, knowing its value in the current basis we can determine its change delta x[j] = new x[j] - old x[j] */ delta_j = (kase < 0 ? floor(x) : ceil(x)) - x; /* and knowing the coefficient alfa we can determine the corresponding change delta x[k] = new x[k] - old x[k], where old x[k] is a value of x[k] in the current basis, and new x[k] is a value of x[k] in the adjacent basis */ delta_k = delta_j / alfa; /* Tomlin noticed that if the variable x[k] is of integer kind, its change cannot be less (eventually) than one in the magnitude */ if (k > m && glp_get_col_kind(mip, k-m) != GLP_CV) { /* x[k] is structural integer variable */ if (fabs(delta_k - floor(delta_k + 0.5)) > 1e-3) { if (delta_k > 0.0) delta_k = ceil(delta_k); /* +3.14 -> +4 */ else delta_k = floor(delta_k); /* -3.14 -> -4 */ } } /* now determine the status and reduced cost of x[k] in the current basis */ if (k <= m) { stat = glp_get_row_stat(mip, k); dk = glp_get_row_dual(mip, k); } else { stat = glp_get_col_stat(mip, k-m); dk = glp_get_col_dual(mip, k-m); } /* if the current basis is dual degenerate, some reduced costs which are close to zero may have wrong sign due to round-off errors, so correct the sign of d[k] */ switch (T->mip->dir) { case GLP_MIN: if (stat == GLP_NL && dk < 0.0 || stat == GLP_NU && dk > 0.0 || stat == GLP_NF) dk = 0.0; break; case GLP_MAX: if (stat == GLP_NL && dk > 0.0 || stat == GLP_NU && dk < 0.0 || stat == GLP_NF) dk = 0.0; break; default: xassert(T != T); } /* now knowing the change of x[k] and its reduced cost d[k] we can compute the corresponding change in the objective function delta Z = new Z - old Z = d[k] * delta x[k]; note that due to Tomlin's modification new Z can be even worse than in the adjacent basis */ delta_z = dk * delta_k; skip: /* new Z is never better than old Z, therefore the change delta Z is always non-negative (in case of minimization) or non-positive (in case of maximization) */ switch (T->mip->dir) { case GLP_MIN: xassert(delta_z >= 0.0); break; case GLP_MAX: xassert(delta_z <= 0.0); break; default: xassert(T != T); } /* save the change in the objective fnction for down- and up-branches, respectively */ if (kase < 0) dz_dn = delta_z; else dz_up = delta_z; } /* thus, in down-branch no integer feasible solution can be better than Z + dz_dn, and in up-branch no integer feasible solution can be better than Z + dz_up, where Z is value of the objective function in the current basis */ /* following the heuristic by Driebeck and Tomlin we choose a column (i.e. structural variable) which provides largest degradation of the objective function in some of branches; besides, we select the branch with smaller degradation to be solved next and keep other branch with larger degradation in the active list hoping to minimize the number of further backtrackings */ if (degrad < fabs(dz_dn) || degrad < fabs(dz_up)) { jj = j; if (fabs(dz_dn) < fabs(dz_up)) { /* select down branch to be solved next */ next = GLP_DN_BRNCH; degrad = fabs(dz_up); } else { /* select up branch to be solved next */ next = GLP_UP_BRNCH; degrad = fabs(dz_dn); } /* save the objective changes for printing */ dd_dn = dz_dn, dd_up = dz_up; /* if down- or up-branch has no feasible solution, we does not need to consider other candidates (in principle, the corresponding branch could be pruned right now) */ if (degrad == DBL_MAX) break; } } /* free working arrays */ xfree(ind); xfree(val); /* something must be chosen */ xassert(1 <= jj && jj <= n); #if 1 /* 02/XI-2009 */ if (degrad < 1e-6 * (1.0 + 0.001 * fabs(mip->obj_val))) { jj = branch_mostf(T, &next); goto done; } #endif if (T->parm->msg_lev >= GLP_MSG_DBG) { xprintf("branch_drtom: column %d chosen to branch on\n", jj); if (fabs(dd_dn) == DBL_MAX) xprintf("branch_drtom: down-branch is infeasible\n"); else xprintf("branch_drtom: down-branch bound is %.9e\n", lpx_get_obj_val(mip) + dd_dn); if (fabs(dd_up) == DBL_MAX) xprintf("branch_drtom: up-branch is infeasible\n"); else xprintf("branch_drtom: up-branch bound is %.9e\n", lpx_get_obj_val(mip) + dd_up); } done: *_next = next; return jj; } /**********************************************************************/ struct csa { /* common storage area */ int *dn_cnt; /* int dn_cnt[1+n]; */ /* dn_cnt[j] is the number of subproblems, whose LP relaxations have been solved and which are down-branches for variable x[j]; dn_cnt[j] = 0 means the down pseudocost is uninitialized */ double *dn_sum; /* double dn_sum[1+n]; */ /* dn_sum[j] is the sum of per unit degradations of the objective over all dn_cnt[j] subproblems */ int *up_cnt; /* int up_cnt[1+n]; */ /* up_cnt[j] is the number of subproblems, whose LP relaxations have been solved and which are up-branches for variable x[j]; up_cnt[j] = 0 means the up pseudocost is uninitialized */ double *up_sum; /* double up_sum[1+n]; */ /* up_sum[j] is the sum of per unit degradations of the objective over all up_cnt[j] subproblems */ }; void *ios_pcost_init(glp_tree *tree) { /* initialize working data used on pseudocost branching */ struct csa *csa; int n = tree->n, j; csa = xmalloc(sizeof(struct csa)); csa->dn_cnt = xcalloc(1+n, sizeof(int)); csa->dn_sum = xcalloc(1+n, sizeof(double)); csa->up_cnt = xcalloc(1+n, sizeof(int)); csa->up_sum = xcalloc(1+n, sizeof(double)); for (j = 1; j <= n; j++) { csa->dn_cnt[j] = csa->up_cnt[j] = 0; csa->dn_sum[j] = csa->up_sum[j] = 0.0; } return csa; } static double eval_degrad(glp_prob *P, int j, double bnd) { /* compute degradation of the objective on fixing x[j] at given value with a limited number of dual simplex iterations */ /* this routine fixes column x[j] at specified value bnd, solves resulting LP, and returns a lower bound to degradation of the objective, degrad >= 0 */ glp_prob *lp; glp_smcp parm; int ret; double degrad; /* the current basis must be optimal */ xassert(glp_get_status(P) == GLP_OPT); /* create a copy of P */ lp = glp_create_prob(); glp_copy_prob(lp, P, 0); /* fix column x[j] at specified value */ glp_set_col_bnds(lp, j, GLP_FX, bnd, bnd); /* try to solve resulting LP */ glp_init_smcp(&parm); parm.msg_lev = GLP_MSG_OFF; parm.meth = GLP_DUAL; parm.it_lim = 30; parm.out_dly = 1000; parm.meth = GLP_DUAL; ret = glp_simplex(lp, &parm); if (ret == 0 || ret == GLP_EITLIM) { if (glp_get_prim_stat(lp) == GLP_NOFEAS) { /* resulting LP has no primal feasible solution */ degrad = DBL_MAX; } else if (glp_get_dual_stat(lp) == GLP_FEAS) { /* resulting basis is optimal or at least dual feasible, so we have the correct lower bound to degradation */ if (P->dir == GLP_MIN) degrad = lp->obj_val - P->obj_val; else if (P->dir == GLP_MAX) degrad = P->obj_val - lp->obj_val; else xassert(P != P); /* degradation cannot be negative by definition */ /* note that the lower bound to degradation may be close to zero even if its exact value is zero due to round-off errors on computing the objective value */ if (degrad < 1e-6 * (1.0 + 0.001 * fabs(P->obj_val))) degrad = 0.0; } else { /* the final basis reported by the simplex solver is dual infeasible, so we cannot determine a non-trivial lower bound to degradation */ degrad = 0.0; } } else { /* the simplex solver failed */ degrad = 0.0; } /* delete the copy of P */ glp_delete_prob(lp); return degrad; } void ios_pcost_update(glp_tree *tree) { /* update history information for pseudocost branching */ /* this routine is called every time when LP relaxation of the current subproblem has been solved to optimality with all lazy and cutting plane constraints included */ int j; double dx, dz, psi; struct csa *csa = tree->pcost; xassert(csa != NULL); xassert(tree->curr != NULL); /* if the current subproblem is the root, skip updating */ if (tree->curr->up == NULL) goto skip; /* determine branching variable x[j], which was used in the parent subproblem to create the current subproblem */ j = tree->curr->up->br_var; xassert(1 <= j && j <= tree->n); /* determine the change dx[j] = new x[j] - old x[j], where new x[j] is a value of x[j] in optimal solution to LP relaxation of the current subproblem, old x[j] is a value of x[j] in optimal solution to LP relaxation of the parent subproblem */ dx = tree->mip->col[j]->prim - tree->curr->up->br_val; xassert(dx != 0.0); /* determine corresponding change dz = new dz - old dz in the objective function value */ dz = tree->mip->obj_val - tree->curr->up->lp_obj; /* determine per unit degradation of the objective function */ psi = fabs(dz / dx); /* update history information */ if (dx < 0.0) { /* the current subproblem is down-branch */ csa->dn_cnt[j]++; csa->dn_sum[j] += psi; } else /* dx > 0.0 */ { /* the current subproblem is up-branch */ csa->up_cnt[j]++; csa->up_sum[j] += psi; } skip: return; } void ios_pcost_free(glp_tree *tree) { /* free working area used on pseudocost branching */ struct csa *csa = tree->pcost; xassert(csa != NULL); xfree(csa->dn_cnt); xfree(csa->dn_sum); xfree(csa->up_cnt); xfree(csa->up_sum); xfree(csa); tree->pcost = NULL; return; } static double eval_psi(glp_tree *T, int j, int brnch) { /* compute estimation of pseudocost of variable x[j] for down- or up-branch */ struct csa *csa = T->pcost; double beta, degrad, psi; xassert(csa != NULL); xassert(1 <= j && j <= T->n); if (brnch == GLP_DN_BRNCH) { /* down-branch */ if (csa->dn_cnt[j] == 0) { /* initialize down pseudocost */ beta = T->mip->col[j]->prim; degrad = eval_degrad(T->mip, j, floor(beta)); if (degrad == DBL_MAX) { psi = DBL_MAX; goto done; } csa->dn_cnt[j] = 1; csa->dn_sum[j] = degrad / (beta - floor(beta)); } psi = csa->dn_sum[j] / (double)csa->dn_cnt[j]; } else if (brnch == GLP_UP_BRNCH) { /* up-branch */ if (csa->up_cnt[j] == 0) { /* initialize up pseudocost */ beta = T->mip->col[j]->prim; degrad = eval_degrad(T->mip, j, ceil(beta)); if (degrad == DBL_MAX) { psi = DBL_MAX; goto done; } csa->up_cnt[j] = 1; csa->up_sum[j] = degrad / (ceil(beta) - beta); } psi = csa->up_sum[j] / (double)csa->up_cnt[j]; } else xassert(brnch != brnch); done: return psi; } static void progress(glp_tree *T) { /* display progress of pseudocost initialization */ struct csa *csa = T->pcost; int j, nv = 0, ni = 0; for (j = 1; j <= T->n; j++) { if (glp_ios_can_branch(T, j)) { nv++; if (csa->dn_cnt[j] > 0 && csa->up_cnt[j] > 0) ni++; } } xprintf("Pseudocosts initialized for %d of %d variables\n", ni, nv); return; } int ios_pcost_branch(glp_tree *T, int *_next) { /* choose branching variable with pseudocost branching */ glp_long t = xtime(); int j, jjj, sel; double beta, psi, d1, d2, d, dmax; /* initialize the working arrays */ if (T->pcost == NULL) T->pcost = ios_pcost_init(T); /* nothing has been chosen so far */ jjj = 0, dmax = -1.0; /* go through the list of branching candidates */ for (j = 1; j <= T->n; j++) { if (!glp_ios_can_branch(T, j)) continue; /* determine primal value of x[j] in optimal solution to LP relaxation of the current subproblem */ beta = T->mip->col[j]->prim; /* estimate pseudocost of x[j] for down-branch */ psi = eval_psi(T, j, GLP_DN_BRNCH); if (psi == DBL_MAX) { /* down-branch has no primal feasible solution */ jjj = j, sel = GLP_DN_BRNCH; goto done; } /* estimate degradation of the objective for down-branch */ d1 = psi * (beta - floor(beta)); /* estimate pseudocost of x[j] for up-branch */ psi = eval_psi(T, j, GLP_UP_BRNCH); if (psi == DBL_MAX) { /* up-branch has no primal feasible solution */ jjj = j, sel = GLP_UP_BRNCH; goto done; } /* estimate degradation of the objective for up-branch */ d2 = psi * (ceil(beta) - beta); /* determine d = max(d1, d2) */ d = (d1 > d2 ? d1 : d2); /* choose x[j] which provides maximal estimated degradation of the objective either in down- or up-branch */ if (dmax < d) { dmax = d; jjj = j; /* continue the search from a subproblem, where degradation is less than in other one */ sel = (d1 <= d2 ? GLP_DN_BRNCH : GLP_UP_BRNCH); } /* display progress of pseudocost initialization */ if (T->parm->msg_lev >= GLP_ON) { if (xdifftime(xtime(), t) >= 10.0) { progress(T); t = xtime(); } } } if (dmax == 0.0) { /* no degradation is indicated; choose a variable having most fractional value */ jjj = branch_mostf(T, &sel); } done: *_next = sel; return jjj; } /* eof */ praat-6.0.04/external/glpk/glpios10.c000066400000000000000000000274551261542461700173160ustar00rootroot00000000000000/* glpios10.c (feasibility pump heuristic) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpios.h" #include "glprng.h" /*********************************************************************** * NAME * * ios_feas_pump - feasibility pump heuristic * * SYNOPSIS * * #include "glpios.h" * void ios_feas_pump(glp_tree *T); * * DESCRIPTION * * The routine ios_feas_pump is a simple implementation of the Feasi- * bility Pump heuristic. * * REFERENCES * * M.Fischetti, F.Glover, and A.Lodi. "The feasibility pump." Math. * Program., Ser. A 104, pp. 91-104 (2005). */ struct VAR { /* binary variable */ int j; /* ordinal number */ int x; /* value in the rounded solution (0 or 1) */ double d; /* sorting key */ }; static int fcmp(const void *x, const void *y) { /* comparison routine */ const struct VAR *vx = x, *vy = y; if (vx->d > vy->d) return -1; else if (vx->d < vy->d) return +1; else return 0; } void ios_feas_pump(glp_tree *T) { glp_prob *P = T->mip; int n = P->n; glp_prob *lp = NULL; struct VAR *var = NULL; RNG *rand = NULL; GLPCOL *col; glp_smcp parm; int j, k, new_x, nfail, npass, nv, ret, stalling; double dist, tol; xassert(glp_get_status(P) == GLP_OPT); /* this heuristic is applied only once on the root level */ if (!(T->curr->level == 0 && T->curr->solved == 1)) goto done; /* determine number of binary variables */ nv = 0; for (j = 1; j <= n; j++) { col = P->col[j]; /* if x[j] is continuous, skip it */ if (col->kind == GLP_CV) continue; /* if x[j] is fixed, skip it */ if (col->type == GLP_FX) continue; /* x[j] is non-fixed integer */ xassert(col->kind == GLP_IV); if (col->type == GLP_DB && col->lb == 0.0 && col->ub == 1.0) { /* x[j] is binary */ nv++; } else { /* x[j] is general integer */ if (T->parm->msg_lev >= GLP_MSG_ALL) xprintf("FPUMP heuristic cannot be applied due to genera" "l integer variables\n"); goto done; } } /* there must be at least one binary variable */ if (nv == 0) goto done; if (T->parm->msg_lev >= GLP_MSG_ALL) xprintf("Applying FPUMP heuristic...\n"); /* build the list of binary variables */ var = xcalloc(1+nv, sizeof(struct VAR)); k = 0; for (j = 1; j <= n; j++) { col = P->col[j]; if (col->kind == GLP_IV && col->type == GLP_DB) var[++k].j = j; } xassert(k == nv); /* create working problem object */ lp = glp_create_prob(); more: /* copy the original problem object to keep it intact */ glp_copy_prob(lp, P, GLP_OFF); /* we are interested to find an integer feasible solution, which is better than the best known one */ if (P->mip_stat == GLP_FEAS) { int *ind; double *val, bnd; /* add a row and make it identical to the objective row */ glp_add_rows(lp, 1); ind = xcalloc(1+n, sizeof(int)); val = xcalloc(1+n, sizeof(double)); for (j = 1; j <= n; j++) { ind[j] = j; val[j] = P->col[j]->coef; } glp_set_mat_row(lp, lp->m, n, ind, val); xfree(ind); xfree(val); /* introduce upper (minimization) or lower (maximization) bound to the original objective function; note that this additional constraint is not violated at the optimal point to LP relaxation */ #if 0 /* modified by xypron */ if (P->dir == GLP_MIN) { bnd = P->mip_obj - 0.10 * (1.0 + fabs(P->mip_obj)); if (bnd < P->obj_val) bnd = P->obj_val; glp_set_row_bnds(lp, lp->m, GLP_UP, 0.0, bnd - P->c0); } else if (P->dir == GLP_MAX) { bnd = P->mip_obj + 0.10 * (1.0 + fabs(P->mip_obj)); if (bnd > P->obj_val) bnd = P->obj_val; glp_set_row_bnds(lp, lp->m, GLP_LO, bnd - P->c0, 0.0); } else xassert(P != P); #else bnd = 0.1 * P->obj_val + 0.9 * P->mip_obj; /* xprintf("bnd = %f\n", bnd); */ if (P->dir == GLP_MIN) glp_set_row_bnds(lp, lp->m, GLP_UP, 0.0, bnd - P->c0); else if (P->dir == GLP_MAX) glp_set_row_bnds(lp, lp->m, GLP_LO, bnd - P->c0, 0.0); else xassert(P != P); #endif } /* reset pass count */ npass = 0; /* invalidate the rounded point */ for (k = 1; k <= nv; k++) var[k].x = -1; pass: /* next pass starts here */ npass++; if (T->parm->msg_lev >= GLP_MSG_ALL) xprintf("Pass %d\n", npass); /* initialize minimal distance between the basic point and the rounded one obtained during this pass */ dist = DBL_MAX; /* reset failure count (the number of succeeded iterations failed to improve the distance) */ nfail = 0; /* if it is not the first pass, perturb the last rounded point rather than construct it from the basic solution */ if (npass > 1) { double rho, temp; if (rand == NULL) rand = rng_create_rand(); for (k = 1; k <= nv; k++) { j = var[k].j; col = lp->col[j]; rho = rng_uniform(rand, -0.3, 0.7); if (rho < 0.0) rho = 0.0; temp = fabs((double)var[k].x - col->prim); if (temp + rho > 0.5) var[k].x = 1 - var[k].x; } goto skip; } loop: /* innermost loop begins here */ /* round basic solution (which is assumed primal feasible) */ stalling = 1; for (k = 1; k <= nv; k++) { col = lp->col[var[k].j]; if (col->prim < 0.5) { /* rounded value is 0 */ new_x = 0; } else { /* rounded value is 1 */ new_x = 1; } if (var[k].x != new_x) { stalling = 0; var[k].x = new_x; } } /* if the rounded point has not changed (stalling), choose and flip some its entries heuristically */ if (stalling) { /* compute d[j] = |x[j] - round(x[j])| */ for (k = 1; k <= nv; k++) { col = lp->col[var[k].j]; var[k].d = fabs(col->prim - (double)var[k].x); } /* sort the list of binary variables by descending d[j] */ qsort(&var[1], nv, sizeof(struct VAR), fcmp); /* choose and flip some rounded components */ for (k = 1; k <= nv; k++) { if (k >= 5 && var[k].d < 0.35 || k >= 10) break; var[k].x = 1 - var[k].x; } } skip: /* check if the time limit has been exhausted */ if (T->parm->tm_lim < INT_MAX && (double)(T->parm->tm_lim - 1) <= 1000.0 * xdifftime(xtime(), T->tm_beg)) goto done; /* build the objective, which is the distance between the current (basic) point and the rounded one */ lp->dir = GLP_MIN; lp->c0 = 0.0; for (j = 1; j <= n; j++) lp->col[j]->coef = 0.0; for (k = 1; k <= nv; k++) { j = var[k].j; if (var[k].x == 0) lp->col[j]->coef = +1.0; else { lp->col[j]->coef = -1.0; lp->c0 += 1.0; } } /* minimize the distance with the simplex method */ glp_init_smcp(&parm); if (T->parm->msg_lev <= GLP_MSG_ERR) parm.msg_lev = T->parm->msg_lev; else if (T->parm->msg_lev <= GLP_MSG_ALL) { parm.msg_lev = GLP_MSG_ON; parm.out_dly = 10000; } ret = glp_simplex(lp, &parm); if (ret != 0) { if (T->parm->msg_lev >= GLP_MSG_ERR) xprintf("Warning: glp_simplex returned %d\n", ret); goto done; } ret = glp_get_status(lp); if (ret != GLP_OPT) { if (T->parm->msg_lev >= GLP_MSG_ERR) xprintf("Warning: glp_get_status returned %d\n", ret); goto done; } if (T->parm->msg_lev >= GLP_MSG_DBG) xprintf("delta = %g\n", lp->obj_val); /* check if the basic solution is integer feasible; note that it may be so even if the minimial distance is positive */ tol = 0.3 * T->parm->tol_int; for (k = 1; k <= nv; k++) { col = lp->col[var[k].j]; if (tol < col->prim && col->prim < 1.0 - tol) break; } if (k > nv) { /* okay; the basic solution seems to be integer feasible */ double *x = xcalloc(1+n, sizeof(double)); for (j = 1; j <= n; j++) { x[j] = lp->col[j]->prim; if (P->col[j]->kind == GLP_IV) x[j] = floor(x[j] + 0.5); } #if 1 /* modified by xypron */ /* reset direction and right-hand side of objective */ lp->c0 = P->c0; lp->dir = P->dir; /* fix integer variables */ for (k = 1; k <= nv; k++) { lp->col[var[k].j]->lb = x[var[k].j]; lp->col[var[k].j]->ub = x[var[k].j]; lp->col[var[k].j]->type = GLP_FX; } /* copy original objective function */ for (j = 1; j <= n; j++) lp->col[j]->coef = P->col[j]->coef; /* solve original LP and copy result */ ret = glp_simplex(lp, &parm); if (ret != 0) { if (T->parm->msg_lev >= GLP_MSG_ERR) xprintf("Warning: glp_simplex returned %d\n", ret); goto done; } ret = glp_get_status(lp); if (ret != GLP_OPT) { if (T->parm->msg_lev >= GLP_MSG_ERR) xprintf("Warning: glp_get_status returned %d\n", ret); goto done; } for (j = 1; j <= n; j++) if (P->col[j]->kind != GLP_IV) x[j] = lp->col[j]->prim; #endif ret = glp_ios_heur_sol(T, x); xfree(x); if (ret == 0) { /* the integer solution is accepted */ if (ios_is_hopeful(T, T->curr->bound)) { /* it is reasonable to apply the heuristic once again */ goto more; } else { /* the best known integer feasible solution just found is close to optimal solution to LP relaxation */ goto done; } } } /* the basic solution is fractional */ if (dist == DBL_MAX || lp->obj_val <= dist - 1e-6 * (1.0 + dist)) { /* the distance is reducing */ nfail = 0, dist = lp->obj_val; } else { /* improving the distance failed */ nfail++; } if (nfail < 3) goto loop; if (npass < 5) goto pass; done: /* delete working objects */ if (lp != NULL) glp_delete_prob(lp); if (var != NULL) xfree(var); if (rand != NULL) rng_delete_rand(rand); return; } /* eof */ praat-6.0.04/external/glpk/glpios11.c000066400000000000000000000247161261542461700173140ustar00rootroot00000000000000/* glpios11.c (process cuts stored in the local cut pool) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpios.h" /*********************************************************************** * NAME * * ios_process_cuts - process cuts stored in the local cut pool * * SYNOPSIS * * #include "glpios.h" * void ios_process_cuts(glp_tree *T); * * DESCRIPTION * * The routine ios_process_cuts analyzes each cut currently stored in * the local cut pool, which must be non-empty, and either adds the cut * to the current subproblem or just discards it. All cuts are assumed * to be locally valid. On exit the local cut pool remains unchanged. * * REFERENCES * * 1. E.Balas, S.Ceria, G.Cornuejols, "Mixed 0-1 Programming by * Lift-and-Project in a Branch-and-Cut Framework", Management Sc., * 42 (1996) 1229-1246. * * 2. G.Andreello, A.Caprara, and M.Fischetti, "Embedding Cuts in * a Branch&Cut Framework: a Computational Study with {0,1/2}-Cuts", * Preliminary Draft, October 28, 2003, pp.6-8. */ struct info { /* estimated cut efficiency */ IOSCUT *cut; /* pointer to cut in the cut pool */ char flag; /* if this flag is set, the cut is included into the current subproblem */ double eff; /* cut efficacy (normalized residual) */ double deg; /* lower bound to objective degradation */ }; static int fcmp(const void *arg1, const void *arg2) { const struct info *info1 = arg1, *info2 = arg2; if (info1->deg == 0.0 && info2->deg == 0.0) { if (info1->eff > info2->eff) return -1; if (info1->eff < info2->eff) return +1; } else { if (info1->deg > info2->deg) return -1; if (info1->deg < info2->deg) return +1; } return 0; } static double parallel(IOSCUT *a, IOSCUT *b, double work[]); void ios_process_cuts(glp_tree *T) { IOSPOOL *pool; IOSCUT *cut; IOSAIJ *aij; struct info *info; int k, kk, max_cuts, len, ret, *ind; double *val, *work; /* the current subproblem must exist */ xassert(T->curr != NULL); /* the pool must exist and be non-empty */ pool = T->local; xassert(pool != NULL); xassert(pool->size > 0); /* allocate working arrays */ info = xcalloc(1+pool->size, sizeof(struct info)); ind = xcalloc(1+T->n, sizeof(int)); val = xcalloc(1+T->n, sizeof(double)); work = xcalloc(1+T->n, sizeof(double)); for (k = 1; k <= T->n; k++) work[k] = 0.0; /* build the list of cuts stored in the cut pool */ for (k = 0, cut = pool->head; cut != NULL; cut = cut->next) k++, info[k].cut = cut, info[k].flag = 0; xassert(k == pool->size); /* estimate efficiency of all cuts in the cut pool */ for (k = 1; k <= pool->size; k++) { double temp, dy, dz; cut = info[k].cut; /* build the vector of cut coefficients and compute its Euclidean norm */ len = 0; temp = 0.0; for (aij = cut->ptr; aij != NULL; aij = aij->next) { xassert(1 <= aij->j && aij->j <= T->n); len++, ind[len] = aij->j, val[len] = aij->val; temp += aij->val * aij->val; } if (temp < DBL_EPSILON * DBL_EPSILON) temp = DBL_EPSILON; /* transform the cut to express it only through non-basic (auxiliary and structural) variables */ len = glp_transform_row(T->mip, len, ind, val); /* determine change in the cut value and in the objective value for the adjacent basis by simulating one step of the dual simplex */ ret = _glp_analyze_row(T->mip, len, ind, val, cut->type, cut->rhs, 1e-9, NULL, NULL, NULL, NULL, &dy, &dz); /* determine normalized residual and lower bound to objective degradation */ if (ret == 0) { info[k].eff = fabs(dy) / sqrt(temp); /* if some reduced costs violates (slightly) their zero bounds (i.e. have wrong signs) due to round-off errors, dz also may have wrong sign being close to zero */ if (T->mip->dir == GLP_MIN) { if (dz < 0.0) dz = 0.0; info[k].deg = + dz; } else /* GLP_MAX */ { if (dz > 0.0) dz = 0.0; info[k].deg = - dz; } } else if (ret == 1) { /* the constraint is not violated at the current point */ info[k].eff = info[k].deg = 0.0; } else if (ret == 2) { /* no dual feasible adjacent basis exists */ info[k].eff = 1.0; info[k].deg = DBL_MAX; } else xassert(ret != ret); /* if the degradation is too small, just ignore it */ if (info[k].deg < 0.01) info[k].deg = 0.0; } /* sort the list of cuts by decreasing objective degradation and then by decreasing efficacy */ qsort(&info[1], pool->size, sizeof(struct info), fcmp); /* only first (most efficient) max_cuts in the list are qualified as candidates to be added to the current subproblem */ max_cuts = (T->curr->level == 0 ? 90 : 10); if (max_cuts > pool->size) max_cuts = pool->size; /* add cuts to the current subproblem */ #if 0 xprintf("*** adding cuts ***\n"); #endif for (k = 1; k <= max_cuts; k++) { int i, len; /* if this cut seems to be inefficient, skip it */ if (info[k].deg < 0.01 && info[k].eff < 0.01) continue; /* if the angle between this cut and every other cut included in the current subproblem is small, skip this cut */ for (kk = 1; kk < k; kk++) { if (info[kk].flag) { if (parallel(info[k].cut, info[kk].cut, work) > 0.90) break; } } if (kk < k) continue; /* add this cut to the current subproblem */ #if 0 xprintf("eff = %g; deg = %g\n", info[k].eff, info[k].deg); #endif cut = info[k].cut, info[k].flag = 1; i = glp_add_rows(T->mip, 1); if (cut->name != NULL) glp_set_row_name(T->mip, i, cut->name); xassert(T->mip->row[i]->origin == GLP_RF_CUT); T->mip->row[i]->klass = cut->klass; len = 0; for (aij = cut->ptr; aij != NULL; aij = aij->next) len++, ind[len] = aij->j, val[len] = aij->val; glp_set_mat_row(T->mip, i, len, ind, val); xassert(cut->type == GLP_LO || cut->type == GLP_UP); glp_set_row_bnds(T->mip, i, cut->type, cut->rhs, cut->rhs); } /* free working arrays */ xfree(info); xfree(ind); xfree(val); xfree(work); return; } #if 0 /*********************************************************************** * Given a cut a * x >= b (<= b) the routine efficacy computes the cut * efficacy as follows: * * eff = d * (a * x~ - b) / ||a||, * * where d is -1 (in case of '>= b') or +1 (in case of '<= b'), x~ is * the vector of values of structural variables in optimal solution to * LP relaxation of the current subproblem, ||a|| is the Euclidean norm * of the vector of cut coefficients. * * If the cut is violated at point x~, the efficacy eff is positive, * and its value is the Euclidean distance between x~ and the cut plane * a * x = b in the space of structural variables. * * Following geometrical intuition, it is quite natural to consider * this distance as a first-order measure of the expected efficacy of * the cut: the larger the distance the better the cut [1]. */ static double efficacy(glp_tree *T, IOSCUT *cut) { glp_prob *mip = T->mip; IOSAIJ *aij; double s = 0.0, t = 0.0, temp; for (aij = cut->ptr; aij != NULL; aij = aij->next) { xassert(1 <= aij->j && aij->j <= mip->n); s += aij->val * mip->col[aij->j]->prim; t += aij->val * aij->val; } temp = sqrt(t); if (temp < DBL_EPSILON) temp = DBL_EPSILON; if (cut->type == GLP_LO) temp = (s >= cut->rhs ? 0.0 : (cut->rhs - s) / temp); else if (cut->type == GLP_UP) temp = (s <= cut->rhs ? 0.0 : (s - cut->rhs) / temp); else xassert(cut != cut); return temp; } #endif /*********************************************************************** * Given two cuts a1 * x >= b1 (<= b1) and a2 * x >= b2 (<= b2) the * routine parallel computes the cosine of angle between the cut planes * a1 * x = b1 and a2 * x = b2 (which is the acute angle between two * normals to these planes) in the space of structural variables as * follows: * * cos phi = (a1' * a2) / (||a1|| * ||a2||), * * where (a1' * a2) is a dot product of vectors of cut coefficients, * ||a1|| and ||a2|| are Euclidean norms of vectors a1 and a2. * * Note that requirement cos phi = 0 forces the cuts to be orthogonal, * i.e. with disjoint support, while requirement cos phi <= 0.999 means * only avoiding duplicate (parallel) cuts [1]. */ static double parallel(IOSCUT *a, IOSCUT *b, double work[]) { IOSAIJ *aij; double s = 0.0, sa = 0.0, sb = 0.0, temp; for (aij = a->ptr; aij != NULL; aij = aij->next) { work[aij->j] = aij->val; sa += aij->val * aij->val; } for (aij = b->ptr; aij != NULL; aij = aij->next) { s += work[aij->j] * aij->val; sb += aij->val * aij->val; } for (aij = a->ptr; aij != NULL; aij = aij->next) work[aij->j] = 0.0; temp = sqrt(sa) * sqrt(sb); if (temp < DBL_EPSILON * DBL_EPSILON) temp = DBL_EPSILON; return s / temp; } /* eof */ praat-6.0.04/external/glpk/glpios12.c000066400000000000000000000132601261542461700173050ustar00rootroot00000000000000/* glpios12.c (node selection heuristics) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpios.h" /*********************************************************************** * NAME * * ios_choose_node - select subproblem to continue the search * * SYNOPSIS * * #include "glpios.h" * int ios_choose_node(glp_tree *T); * * DESCRIPTION * * The routine ios_choose_node selects a subproblem from the active * list to continue the search. The choice depends on the backtracking * technique option. * * RETURNS * * The routine ios_choose_node return the reference number of the * subproblem selected. */ static int most_feas(glp_tree *T); static int best_proj(glp_tree *T); static int best_node(glp_tree *T); int ios_choose_node(glp_tree *T) { int p; if (T->parm->bt_tech == GLP_BT_DFS) { /* depth first search */ xassert(T->tail != NULL); p = T->tail->p; } else if (T->parm->bt_tech == GLP_BT_BFS) { /* breadth first search */ xassert(T->head != NULL); p = T->head->p; } else if (T->parm->bt_tech == GLP_BT_BLB) { /* select node with best local bound */ p = best_node(T); } else if (T->parm->bt_tech == GLP_BT_BPH) { if (T->mip->mip_stat == GLP_UNDEF) { /* "most integer feasible" subproblem */ p = most_feas(T); } else { /* best projection heuristic */ p = best_proj(T); } } else xassert(T != T); return p; } static int most_feas(glp_tree *T) { /* select subproblem whose parent has minimal sum of integer infeasibilities */ IOSNPD *node; int p; double best; p = 0, best = DBL_MAX; for (node = T->head; node != NULL; node = node->next) { xassert(node->up != NULL); if (best > node->up->ii_sum) p = node->p, best = node->up->ii_sum; } return p; } static int best_proj(glp_tree *T) { /* select subproblem using the best projection heuristic */ IOSNPD *root, *node; int p; double best, deg, obj; /* the global bound must exist */ xassert(T->mip->mip_stat == GLP_FEAS); /* obtain pointer to the root node, which must exist */ root = T->slot[1].node; xassert(root != NULL); /* deg estimates degradation of the objective function per unit of the sum of integer infeasibilities */ xassert(root->ii_sum > 0.0); deg = (T->mip->mip_obj - root->bound) / root->ii_sum; /* nothing has been selected so far */ p = 0, best = DBL_MAX; /* walk through the list of active subproblems */ for (node = T->head; node != NULL; node = node->next) { xassert(node->up != NULL); /* obj estimates optimal objective value if the sum of integer infeasibilities were zero */ obj = node->up->bound + deg * node->up->ii_sum; if (T->mip->dir == GLP_MAX) obj = - obj; /* select the subproblem which has the best estimated optimal objective value */ if (best > obj) p = node->p, best = obj; } return p; } static int best_node(glp_tree *T) { /* select subproblem with best local bound */ IOSNPD *node, *best = NULL; double bound, eps; switch (T->mip->dir) { case GLP_MIN: bound = +DBL_MAX; for (node = T->head; node != NULL; node = node->next) if (bound > node->bound) bound = node->bound; xassert(bound != +DBL_MAX); eps = 0.001 * (1.0 + fabs(bound)); for (node = T->head; node != NULL; node = node->next) { if (node->bound <= bound + eps) { xassert(node->up != NULL); if (best == NULL || #if 1 best->up->ii_sum > node->up->ii_sum) best = node; #else best->lp_obj > node->lp_obj) best = node; #endif } } break; case GLP_MAX: bound = -DBL_MAX; for (node = T->head; node != NULL; node = node->next) if (bound < node->bound) bound = node->bound; xassert(bound != -DBL_MAX); eps = 0.001 * (1.0 + fabs(bound)); for (node = T->head; node != NULL; node = node->next) { if (node->bound >= bound - eps) { xassert(node->up != NULL); if (best == NULL || #if 1 best->up->ii_sum > node->up->ii_sum) best = node; #else best->lp_obj < node->lp_obj) best = node; #endif } } break; default: xassert(T != T); } xassert(best != NULL); return best->p; } /* eof */ praat-6.0.04/external/glpk/glpipm.c000066400000000000000000001141071261542461700171370ustar00rootroot00000000000000/* glpipm.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpipm.h" #include "glpmat.h" #define ITER_MAX 100 /* maximal number of iterations */ struct csa { /* common storage area */ /*--------------------------------------------------------------*/ /* LP data */ int m; /* number of rows (equality constraints) */ int n; /* number of columns (structural variables) */ int *A_ptr; /* int A_ptr[1+m+1]; */ int *A_ind; /* int A_ind[A_ptr[m+1]]; */ double *A_val; /* double A_val[A_ptr[m+1]]; */ /* mxn-matrix A in storage-by-rows format */ double *b; /* double b[1+m]; */ /* m-vector b of right-hand sides */ double *c; /* double c[1+n]; */ /* n-vector c of objective coefficients; c[0] is constant term of the objective function */ /*--------------------------------------------------------------*/ /* LP solution */ double *x; /* double x[1+n]; */ double *y; /* double y[1+m]; */ double *z; /* double z[1+n]; */ /* current point in primal-dual space; the best point on exit */ /*--------------------------------------------------------------*/ /* control parameters */ const glp_iptcp *parm; /*--------------------------------------------------------------*/ /* working arrays and variables */ double *D; /* double D[1+n]; */ /* diagonal nxn-matrix D = X*inv(Z), where X = diag(x[j]) and Z = diag(z[j]) */ int *P; /* int P[1+m+m]; */ /* permutation mxm-matrix P used to minimize fill-in in Cholesky factorization */ int *S_ptr; /* int S_ptr[1+m+1]; */ int *S_ind; /* int S_ind[S_ptr[m+1]]; */ double *S_val; /* double S_val[S_ptr[m+1]]; */ double *S_diag; /* double S_diag[1+m]; */ /* symmetric mxm-matrix S = P*A*D*A'*P' whose upper triangular part without diagonal elements is stored in S_ptr, S_ind, and S_val in storage-by-rows format, diagonal elements are stored in S_diag */ int *U_ptr; /* int U_ptr[1+m+1]; */ int *U_ind; /* int U_ind[U_ptr[m+1]]; */ double *U_val; /* double U_val[U_ptr[m+1]]; */ double *U_diag; /* double U_diag[1+m]; */ /* upper triangular mxm-matrix U defining Cholesky factorization S = U'*U; its non-diagonal elements are stored in U_ptr, U_ind, U_val in storage-by-rows format, diagonal elements are stored in U_diag */ int iter; /* iteration number (0, 1, 2, ...); iter = 0 corresponds to the initial point */ double obj; /* current value of the objective function */ double rpi; /* relative primal infeasibility rpi = ||A*x-b||/(1+||b||) */ double rdi; /* relative dual infeasibility rdi = ||A'*y+z-c||/(1+||c||) */ double gap; /* primal-dual gap = |c'*x-b'*y|/(1+|c'*x|) which is a relative difference between primal and dual objective functions */ double phi; /* merit function phi = ||A*x-b||/max(1,||b||) + + ||A'*y+z-c||/max(1,||c||) + + |c'*x-b'*y|/max(1,||b||,||c||) */ double mu; /* duality measure mu = x'*z/n (used as barrier parameter) */ double rmu; /* rmu = max(||A*x-b||,||A'*y+z-c||)/mu */ double rmu0; /* the initial value of rmu on iteration 0 */ double *phi_min; /* double phi_min[1+ITER_MAX]; */ /* phi_min[k] = min(phi[k]), where phi[k] is the value of phi on k-th iteration, 0 <= k <= iter */ int best_iter; /* iteration number, on which the value of phi reached its best (minimal) value */ double *best_x; /* double best_x[1+n]; */ double *best_y; /* double best_y[1+m]; */ double *best_z; /* double best_z[1+n]; */ /* best point (in the sense of the merit function phi) which has been reached on iteration iter_best */ double best_obj; /* objective value at the best point */ double *dx_aff; /* double dx_aff[1+n]; */ double *dy_aff; /* double dy_aff[1+m]; */ double *dz_aff; /* double dz_aff[1+n]; */ /* affine scaling direction */ double alfa_aff_p, alfa_aff_d; /* maximal primal and dual stepsizes in affine scaling direction, on which x and z are still non-negative */ double mu_aff; /* duality measure mu_aff = x_aff'*z_aff/n in the boundary point x_aff' = x+alfa_aff_p*dx_aff, z_aff' = z+alfa_aff_d*dz_aff */ double sigma; /* Mehrotra's heuristic parameter (0 <= sigma <= 1) */ double *dx_cc; /* double dx_cc[1+n]; */ double *dy_cc; /* double dy_cc[1+m]; */ double *dz_cc; /* double dz_cc[1+n]; */ /* centering corrector direction */ double *dx; /* double dx[1+n]; */ double *dy; /* double dy[1+m]; */ double *dz; /* double dz[1+n]; */ /* final combined direction dx = dx_aff+dx_cc, dy = dy_aff+dy_cc, dz = dz_aff+dz_cc */ double alfa_max_p; double alfa_max_d; /* maximal primal and dual stepsizes in combined direction, on which x and z are still non-negative */ }; /*********************************************************************** * initialize - allocate and initialize common storage area * * This routine allocates and initializes the common storage area (CSA) * used by interior-point method routines. */ static void initialize(struct csa *csa) { int m = csa->m; int n = csa->n; int i; if (csa->parm->msg_lev >= GLP_MSG_ALL) xprintf("Matrix A has %d non-zeros\n", csa->A_ptr[m+1]-1); csa->D = xcalloc(1+n, sizeof(double)); /* P := I */ csa->P = xcalloc(1+m+m, sizeof(int)); for (i = 1; i <= m; i++) csa->P[i] = csa->P[m+i] = i; /* S := A*A', symbolically */ csa->S_ptr = xcalloc(1+m+1, sizeof(int)); csa->S_ind = adat_symbolic(m, n, csa->P, csa->A_ptr, csa->A_ind, csa->S_ptr); if (csa->parm->msg_lev >= GLP_MSG_ALL) xprintf("Matrix S = A*A' has %d non-zeros (upper triangle)\n", csa->S_ptr[m+1]-1 + m); /* determine P using specified ordering algorithm */ if (csa->parm->ord_alg == GLP_ORD_NONE) { if (csa->parm->msg_lev >= GLP_MSG_ALL) xprintf("Original ordering is being used\n"); for (i = 1; i <= m; i++) csa->P[i] = csa->P[m+i] = i; } else if (csa->parm->ord_alg == GLP_ORD_QMD) { if (csa->parm->msg_lev >= GLP_MSG_ALL) xprintf("Minimum degree ordering (QMD)...\n"); min_degree(m, csa->S_ptr, csa->S_ind, csa->P); } else if (csa->parm->ord_alg == GLP_ORD_AMD) { if (csa->parm->msg_lev >= GLP_MSG_ALL) xprintf("Approximate minimum degree ordering (AMD)...\n"); amd_order1(m, csa->S_ptr, csa->S_ind, csa->P); } else if (csa->parm->ord_alg == GLP_ORD_SYMAMD) { if (csa->parm->msg_lev >= GLP_MSG_ALL) xprintf("Approximate minimum degree ordering (SYMAMD)...\n") ; symamd_ord(m, csa->S_ptr, csa->S_ind, csa->P); } else xassert(csa != csa); /* S := P*A*A'*P', symbolically */ xfree(csa->S_ind); csa->S_ind = adat_symbolic(m, n, csa->P, csa->A_ptr, csa->A_ind, csa->S_ptr); csa->S_val = xcalloc(csa->S_ptr[m+1], sizeof(double)); csa->S_diag = xcalloc(1+m, sizeof(double)); /* compute Cholesky factorization S = U'*U, symbolically */ if (csa->parm->msg_lev >= GLP_MSG_ALL) xprintf("Computing Cholesky factorization S = L*L'...\n"); csa->U_ptr = xcalloc(1+m+1, sizeof(int)); csa->U_ind = chol_symbolic(m, csa->S_ptr, csa->S_ind, csa->U_ptr); if (csa->parm->msg_lev >= GLP_MSG_ALL) xprintf("Matrix L has %d non-zeros\n", csa->U_ptr[m+1]-1 + m); csa->U_val = xcalloc(csa->U_ptr[m+1], sizeof(double)); csa->U_diag = xcalloc(1+m, sizeof(double)); csa->iter = 0; csa->obj = 0.0; csa->rpi = 0.0; csa->rdi = 0.0; csa->gap = 0.0; csa->phi = 0.0; csa->mu = 0.0; csa->rmu = 0.0; csa->rmu0 = 0.0; csa->phi_min = xcalloc(1+ITER_MAX, sizeof(double)); csa->best_iter = 0; csa->best_x = xcalloc(1+n, sizeof(double)); csa->best_y = xcalloc(1+m, sizeof(double)); csa->best_z = xcalloc(1+n, sizeof(double)); csa->best_obj = 0.0; csa->dx_aff = xcalloc(1+n, sizeof(double)); csa->dy_aff = xcalloc(1+m, sizeof(double)); csa->dz_aff = xcalloc(1+n, sizeof(double)); csa->alfa_aff_p = 0.0; csa->alfa_aff_d = 0.0; csa->mu_aff = 0.0; csa->sigma = 0.0; csa->dx_cc = xcalloc(1+n, sizeof(double)); csa->dy_cc = xcalloc(1+m, sizeof(double)); csa->dz_cc = xcalloc(1+n, sizeof(double)); csa->dx = csa->dx_aff; csa->dy = csa->dy_aff; csa->dz = csa->dz_aff; csa->alfa_max_p = 0.0; csa->alfa_max_d = 0.0; return; } /*********************************************************************** * A_by_vec - compute y = A*x * * This routine computes matrix-vector product y = A*x, where A is the * constraint matrix. */ static void A_by_vec(struct csa *csa, double x[], double y[]) { /* compute y = A*x */ int m = csa->m; int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; int i, t, beg, end; double temp; for (i = 1; i <= m; i++) { temp = 0.0; beg = A_ptr[i], end = A_ptr[i+1]; for (t = beg; t < end; t++) temp += A_val[t] * x[A_ind[t]]; y[i] = temp; } return; } /*********************************************************************** * AT_by_vec - compute y = A'*x * * This routine computes matrix-vector product y = A'*x, where A' is a * matrix transposed to the constraint matrix A. */ static void AT_by_vec(struct csa *csa, double x[], double y[]) { /* compute y = A'*x, where A' is transposed to A */ int m = csa->m; int n = csa->n; int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; int i, j, t, beg, end; double temp; for (j = 1; j <= n; j++) y[j] = 0.0; for (i = 1; i <= m; i++) { temp = x[i]; if (temp == 0.0) continue; beg = A_ptr[i], end = A_ptr[i+1]; for (t = beg; t < end; t++) y[A_ind[t]] += A_val[t] * temp; } return; } /*********************************************************************** * decomp_NE - numeric factorization of matrix S = P*A*D*A'*P' * * This routine implements numeric phase of Cholesky factorization of * the matrix S = P*A*D*A'*P', which is a permuted matrix of the normal * equation system. Matrix D is assumed to be already computed. */ static void decomp_NE(struct csa *csa) { adat_numeric(csa->m, csa->n, csa->P, csa->A_ptr, csa->A_ind, csa->A_val, csa->D, csa->S_ptr, csa->S_ind, csa->S_val, csa->S_diag); chol_numeric(csa->m, csa->S_ptr, csa->S_ind, csa->S_val, csa->S_diag, csa->U_ptr, csa->U_ind, csa->U_val, csa->U_diag); return; } /*********************************************************************** * solve_NE - solve normal equation system * * This routine solves the normal equation system: * * A*D*A'*y = h. * * It is assumed that the matrix A*D*A' has been previously factorized * by the routine decomp_NE. * * On entry the array y contains the vector of right-hand sides h. On * exit this array contains the computed vector of unknowns y. * * Once the vector y has been computed the routine checks for numeric * stability. If the residual vector: * * r = A*D*A'*y - h * * is relatively small, the routine returns zero, otherwise non-zero is * returned. */ static int solve_NE(struct csa *csa, double y[]) { int m = csa->m; int n = csa->n; int *P = csa->P; int i, j, ret = 0; double *h, *r, *w; /* save vector of right-hand sides h */ h = xcalloc(1+m, sizeof(double)); for (i = 1; i <= m; i++) h[i] = y[i]; /* solve normal equation system (A*D*A')*y = h */ /* since S = P*A*D*A'*P' = U'*U, then A*D*A' = P'*U'*U*P, so we have inv(A*D*A') = P'*inv(U)*inv(U')*P */ /* w := P*h */ w = xcalloc(1+m, sizeof(double)); for (i = 1; i <= m; i++) w[i] = y[P[i]]; /* w := inv(U')*w */ ut_solve(m, csa->U_ptr, csa->U_ind, csa->U_val, csa->U_diag, w); /* w := inv(U)*w */ u_solve(m, csa->U_ptr, csa->U_ind, csa->U_val, csa->U_diag, w); /* y := P'*w */ for (i = 1; i <= m; i++) y[i] = w[P[m+i]]; xfree(w); /* compute residual vector r = A*D*A'*y - h */ r = xcalloc(1+m, sizeof(double)); /* w := A'*y */ w = xcalloc(1+n, sizeof(double)); AT_by_vec(csa, y, w); /* w := D*w */ for (j = 1; j <= n; j++) w[j] *= csa->D[j]; /* r := A*w */ A_by_vec(csa, w, r); xfree(w); /* r := r - h */ for (i = 1; i <= m; i++) r[i] -= h[i]; /* check for numeric stability */ for (i = 1; i <= m; i++) { if (fabs(r[i]) / (1.0 + fabs(h[i])) > 1e-4) { ret = 1; break; } } xfree(h); xfree(r); return ret; } /*********************************************************************** * solve_NS - solve Newtonian system * * This routine solves the Newtonian system: * * A*dx = p * * A'*dy + dz = q * * Z*dx + X*dz = r * * where X = diag(x[j]), Z = diag(z[j]), by reducing it to the normal * equation system: * * (A*inv(Z)*X*A')*dy = A*inv(Z)*(X*q-r)+p * * (it is assumed that the matrix A*inv(Z)*X*A' has been factorized by * the routine decomp_NE). * * Once vector dy has been computed the routine computes vectors dx and * dz as follows: * * dx = inv(Z)*(X*(A'*dy-q)+r) * * dz = inv(X)*(r-Z*dx) * * The routine solve_NS returns the same code which was reported by the * routine solve_NE (see above). */ static int solve_NS(struct csa *csa, double p[], double q[], double r[], double dx[], double dy[], double dz[]) { int m = csa->m; int n = csa->n; double *x = csa->x; double *z = csa->z; int i, j, ret; double *w = dx; /* compute the vector of right-hand sides A*inv(Z)*(X*q-r)+p for the normal equation system */ for (j = 1; j <= n; j++) w[j] = (x[j] * q[j] - r[j]) / z[j]; A_by_vec(csa, w, dy); for (i = 1; i <= m; i++) dy[i] += p[i]; /* solve the normal equation system to compute vector dy */ ret = solve_NE(csa, dy); /* compute vectors dx and dz */ AT_by_vec(csa, dy, dx); for (j = 1; j <= n; j++) { dx[j] = (x[j] * (dx[j] - q[j]) + r[j]) / z[j]; dz[j] = (r[j] - z[j] * dx[j]) / x[j]; } return ret; } /*********************************************************************** * initial_point - choose initial point using Mehrotra's heuristic * * This routine chooses a starting point using a heuristic proposed in * the paper: * * S. Mehrotra. On the implementation of a primal-dual interior point * method. SIAM J. on Optim., 2(4), pp. 575-601, 1992. * * The starting point x in the primal space is chosen as a solution of * the following least squares problem: * * minimize ||x|| * * subject to A*x = b * * which can be computed explicitly as follows: * * x = A'*inv(A*A')*b * * Similarly, the starting point (y, z) in the dual space is chosen as * a solution of the following least squares problem: * * minimize ||z|| * * subject to A'*y + z = c * * which can be computed explicitly as follows: * * y = inv(A*A')*A*c * * z = c - A'*y * * However, some components of the vectors x and z may be non-positive * or close to zero, so the routine uses a Mehrotra's heuristic to find * a more appropriate starting point. */ static void initial_point(struct csa *csa) { int m = csa->m; int n = csa->n; double *b = csa->b; double *c = csa->c; double *x = csa->x; double *y = csa->y; double *z = csa->z; double *D = csa->D; int i, j; double dp, dd, ex, ez, xz; /* factorize A*A' */ for (j = 1; j <= n; j++) D[j] = 1.0; decomp_NE(csa); /* x~ = A'*inv(A*A')*b */ for (i = 1; i <= m; i++) y[i] = b[i]; solve_NE(csa, y); AT_by_vec(csa, y, x); /* y~ = inv(A*A')*A*c */ A_by_vec(csa, c, y); solve_NE(csa, y); /* z~ = c - A'*y~ */ AT_by_vec(csa, y,z); for (j = 1; j <= n; j++) z[j] = c[j] - z[j]; /* use Mehrotra's heuristic in order to choose more appropriate starting point with positive components of vectors x and z */ dp = dd = 0.0; for (j = 1; j <= n; j++) { if (dp < -1.5 * x[j]) dp = -1.5 * x[j]; if (dd < -1.5 * z[j]) dd = -1.5 * z[j]; } /* note that b = 0 involves x = 0, and c = 0 involves y = 0 and z = 0, so we need to be careful */ if (dp == 0.0) dp = 1.5; if (dd == 0.0) dd = 1.5; ex = ez = xz = 0.0; for (j = 1; j <= n; j++) { ex += (x[j] + dp); ez += (z[j] + dd); xz += (x[j] + dp) * (z[j] + dd); } dp += 0.5 * (xz / ez); dd += 0.5 * (xz / ex); for (j = 1; j <= n; j++) { x[j] += dp; z[j] += dd; xassert(x[j] > 0.0 && z[j] > 0.0); } return; } /*********************************************************************** * basic_info - perform basic computations at the current point * * This routine computes the following quantities at the current point: * * 1) value of the objective function: * * F = c'*x + c[0] * * 2) relative primal infeasibility: * * rpi = ||A*x-b|| / (1+||b||) * * 3) relative dual infeasibility: * * rdi = ||A'*y+z-c|| / (1+||c||) * * 4) primal-dual gap (relative difference between the primal and the * dual objective function values): * * gap = |c'*x-b'*y| / (1+|c'*x|) * * 5) merit function: * * phi = ||A*x-b|| / max(1,||b||) + ||A'*y+z-c|| / max(1,||c||) + * * + |c'*x-b'*y| / max(1,||b||,||c||) * * 6) duality measure: * * mu = x'*z / n * * 7) the ratio of infeasibility to mu: * * rmu = max(||A*x-b||,||A'*y+z-c||) / mu * * where ||*|| denotes euclidian norm, *' denotes transposition. */ static void basic_info(struct csa *csa) { int m = csa->m; int n = csa->n; double *b = csa->b; double *c = csa->c; double *x = csa->x; double *y = csa->y; double *z = csa->z; int i, j; double norm1, bnorm, norm2, cnorm, cx, by, *work, temp; /* compute value of the objective function */ temp = c[0]; for (j = 1; j <= n; j++) temp += c[j] * x[j]; csa->obj = temp; /* norm1 = ||A*x-b|| */ work = xcalloc(1+m, sizeof(double)); A_by_vec(csa, x, work); norm1 = 0.0; for (i = 1; i <= m; i++) norm1 += (work[i] - b[i]) * (work[i] - b[i]); norm1 = sqrt(norm1); xfree(work); /* bnorm = ||b|| */ bnorm = 0.0; for (i = 1; i <= m; i++) bnorm += b[i] * b[i]; bnorm = sqrt(bnorm); /* compute relative primal infeasibility */ csa->rpi = norm1 / (1.0 + bnorm); /* norm2 = ||A'*y+z-c|| */ work = xcalloc(1+n, sizeof(double)); AT_by_vec(csa, y, work); norm2 = 0.0; for (j = 1; j <= n; j++) norm2 += (work[j] + z[j] - c[j]) * (work[j] + z[j] - c[j]); norm2 = sqrt(norm2); xfree(work); /* cnorm = ||c|| */ cnorm = 0.0; for (j = 1; j <= n; j++) cnorm += c[j] * c[j]; cnorm = sqrt(cnorm); /* compute relative dual infeasibility */ csa->rdi = norm2 / (1.0 + cnorm); /* by = b'*y */ by = 0.0; for (i = 1; i <= m; i++) by += b[i] * y[i]; /* cx = c'*x */ cx = 0.0; for (j = 1; j <= n; j++) cx += c[j] * x[j]; /* compute primal-dual gap */ csa->gap = fabs(cx - by) / (1.0 + fabs(cx)); /* compute merit function */ csa->phi = 0.0; csa->phi += norm1 / (bnorm > 1.0 ? bnorm : 1.0); csa->phi += norm2 / (cnorm > 1.0 ? cnorm : 1.0); temp = 1.0; if (temp < bnorm) temp = bnorm; if (temp < cnorm) temp = cnorm; csa->phi += fabs(cx - by) / temp; /* compute duality measure */ temp = 0.0; for (j = 1; j <= n; j++) temp += x[j] * z[j]; csa->mu = temp / (double)n; /* compute the ratio of infeasibility to mu */ csa->rmu = (norm1 > norm2 ? norm1 : norm2) / csa->mu; return; } /*********************************************************************** * make_step - compute next point using Mehrotra's technique * * This routine computes the next point using the predictor-corrector * technique proposed in the paper: * * S. Mehrotra. On the implementation of a primal-dual interior point * method. SIAM J. on Optim., 2(4), pp. 575-601, 1992. * * At first, the routine computes so called affine scaling (predictor) * direction (dx_aff,dy_aff,dz_aff) which is a solution of the system: * * A*dx_aff = b - A*x * * A'*dy_aff + dz_aff = c - A'*y - z * * Z*dx_aff + X*dz_aff = - X*Z*e * * where (x,y,z) is the current point, X = diag(x[j]), Z = diag(z[j]), * e = (1,...,1)'. * * Then, the routine computes the centering parameter sigma, using the * following Mehrotra's heuristic: * * alfa_aff_p = inf{0 <= alfa <= 1 | x+alfa*dx_aff >= 0} * * alfa_aff_d = inf{0 <= alfa <= 1 | z+alfa*dz_aff >= 0} * * mu_aff = (x+alfa_aff_p*dx_aff)'*(z+alfa_aff_d*dz_aff)/n * * sigma = (mu_aff/mu)^3 * * where alfa_aff_p is the maximal stepsize along the affine scaling * direction in the primal space, alfa_aff_d is the maximal stepsize * along the same direction in the dual space. * * After determining sigma the routine computes so called centering * (corrector) direction (dx_cc,dy_cc,dz_cc) which is the solution of * the system: * * A*dx_cc = 0 * * A'*dy_cc + dz_cc = 0 * * Z*dx_cc + X*dz_cc = sigma*mu*e - X*Z*e * * Finally, the routine computes the combined direction * * (dx,dy,dz) = (dx_aff,dy_aff,dz_aff) + (dx_cc,dy_cc,dz_cc) * * and determines maximal primal and dual stepsizes along the combined * direction: * * alfa_max_p = inf{0 <= alfa <= 1 | x+alfa*dx >= 0} * * alfa_max_d = inf{0 <= alfa <= 1 | z+alfa*dz >= 0} * * In order to prevent the next point to be too close to the boundary * of the positive ortant, the routine decreases maximal stepsizes: * * alfa_p = gamma_p * alfa_max_p * * alfa_d = gamma_d * alfa_max_d * * where gamma_p and gamma_d are scaling factors, and computes the next * point: * * x_new = x + alfa_p * dx * * y_new = y + alfa_d * dy * * z_new = z + alfa_d * dz * * which becomes the current point on the next iteration. */ static int make_step(struct csa *csa) { int m = csa->m; int n = csa->n; double *b = csa->b; double *c = csa->c; double *x = csa->x; double *y = csa->y; double *z = csa->z; double *dx_aff = csa->dx_aff; double *dy_aff = csa->dy_aff; double *dz_aff = csa->dz_aff; double *dx_cc = csa->dx_cc; double *dy_cc = csa->dy_cc; double *dz_cc = csa->dz_cc; double *dx = csa->dx; double *dy = csa->dy; double *dz = csa->dz; int i, j, ret = 0; double temp, gamma_p, gamma_d, *p, *q, *r; /* allocate working arrays */ p = xcalloc(1+m, sizeof(double)); q = xcalloc(1+n, sizeof(double)); r = xcalloc(1+n, sizeof(double)); /* p = b - A*x */ A_by_vec(csa, x, p); for (i = 1; i <= m; i++) p[i] = b[i] - p[i]; /* q = c - A'*y - z */ AT_by_vec(csa, y,q); for (j = 1; j <= n; j++) q[j] = c[j] - q[j] - z[j]; /* r = - X * Z * e */ for (j = 1; j <= n; j++) r[j] = - x[j] * z[j]; /* solve the first Newtonian system */ if (solve_NS(csa, p, q, r, dx_aff, dy_aff, dz_aff)) { ret = 1; goto done; } /* alfa_aff_p = inf{0 <= alfa <= 1 | x + alfa*dx_aff >= 0} */ /* alfa_aff_d = inf{0 <= alfa <= 1 | z + alfa*dz_aff >= 0} */ csa->alfa_aff_p = csa->alfa_aff_d = 1.0; for (j = 1; j <= n; j++) { if (dx_aff[j] < 0.0) { temp = - x[j] / dx_aff[j]; if (csa->alfa_aff_p > temp) csa->alfa_aff_p = temp; } if (dz_aff[j] < 0.0) { temp = - z[j] / dz_aff[j]; if (csa->alfa_aff_d > temp) csa->alfa_aff_d = temp; } } /* mu_aff = (x+alfa_aff_p*dx_aff)' * (z+alfa_aff_d*dz_aff) / n */ temp = 0.0; for (j = 1; j <= n; j++) temp += (x[j] + csa->alfa_aff_p * dx_aff[j]) * (z[j] + csa->alfa_aff_d * dz_aff[j]); csa->mu_aff = temp / (double)n; /* sigma = (mu_aff/mu)^3 */ temp = csa->mu_aff / csa->mu; csa->sigma = temp * temp * temp; /* p = 0 */ for (i = 1; i <= m; i++) p[i] = 0.0; /* q = 0 */ for (j = 1; j <= n; j++) q[j] = 0.0; /* r = sigma * mu * e - X * Z * e */ for (j = 1; j <= n; j++) r[j] = csa->sigma * csa->mu - dx_aff[j] * dz_aff[j]; /* solve the second Newtonian system with the same coefficients but with altered right-hand sides */ if (solve_NS(csa, p, q, r, dx_cc, dy_cc, dz_cc)) { ret = 1; goto done; } /* (dx,dy,dz) = (dx_aff,dy_aff,dz_aff) + (dx_cc,dy_cc,dz_cc) */ for (j = 1; j <= n; j++) dx[j] = dx_aff[j] + dx_cc[j]; for (i = 1; i <= m; i++) dy[i] = dy_aff[i] + dy_cc[i]; for (j = 1; j <= n; j++) dz[j] = dz_aff[j] + dz_cc[j]; /* alfa_max_p = inf{0 <= alfa <= 1 | x + alfa*dx >= 0} */ /* alfa_max_d = inf{0 <= alfa <= 1 | z + alfa*dz >= 0} */ csa->alfa_max_p = csa->alfa_max_d = 1.0; for (j = 1; j <= n; j++) { if (dx[j] < 0.0) { temp = - x[j] / dx[j]; if (csa->alfa_max_p > temp) csa->alfa_max_p = temp; } if (dz[j] < 0.0) { temp = - z[j] / dz[j]; if (csa->alfa_max_d > temp) csa->alfa_max_d = temp; } } /* determine scale factors (not implemented yet) */ gamma_p = 0.90; gamma_d = 0.90; /* compute the next point */ for (j = 1; j <= n; j++) { x[j] += gamma_p * csa->alfa_max_p * dx[j]; xassert(x[j] > 0.0); } for (i = 1; i <= m; i++) y[i] += gamma_d * csa->alfa_max_d * dy[i]; for (j = 1; j <= n; j++) { z[j] += gamma_d * csa->alfa_max_d * dz[j]; xassert(z[j] > 0.0); } done: /* free working arrays */ xfree(p); xfree(q); xfree(r); return ret; } /*********************************************************************** * terminate - deallocate common storage area * * This routine frees all memory allocated to the common storage area * used by interior-point method routines. */ static void terminate(struct csa *csa) { xfree(csa->D); xfree(csa->P); xfree(csa->S_ptr); xfree(csa->S_ind); xfree(csa->S_val); xfree(csa->S_diag); xfree(csa->U_ptr); xfree(csa->U_ind); xfree(csa->U_val); xfree(csa->U_diag); xfree(csa->phi_min); xfree(csa->best_x); xfree(csa->best_y); xfree(csa->best_z); xfree(csa->dx_aff); xfree(csa->dy_aff); xfree(csa->dz_aff); xfree(csa->dx_cc); xfree(csa->dy_cc); xfree(csa->dz_cc); return; } /*********************************************************************** * ipm_main - main interior-point method routine * * This is a main routine of the primal-dual interior-point method. * * The routine ipm_main returns one of the following codes: * * 0 - optimal solution found; * 1 - problem has no feasible (primal or dual) solution; * 2 - no convergence; * 3 - iteration limit exceeded; * 4 - numeric instability on solving Newtonian system. * * In case of non-zero return code the routine returns the best point, * which has been reached during optimization. */ static int ipm_main(struct csa *csa) { int m = csa->m; int n = csa->n; int i, j, status; double temp; /* choose initial point using Mehrotra's heuristic */ if (csa->parm->msg_lev >= GLP_MSG_ALL) xprintf("Guessing initial point...\n"); initial_point(csa); /* main loop starts here */ if (csa->parm->msg_lev >= GLP_MSG_ALL) xprintf("Optimization begins...\n"); for (;;) { /* perform basic computations at the current point */ basic_info(csa); /* save initial value of rmu */ if (csa->iter == 0) csa->rmu0 = csa->rmu; /* accumulate values of min(phi[k]) and save the best point */ xassert(csa->iter <= ITER_MAX); if (csa->iter == 0 || csa->phi_min[csa->iter-1] > csa->phi) { csa->phi_min[csa->iter] = csa->phi; csa->best_iter = csa->iter; for (j = 1; j <= n; j++) csa->best_x[j] = csa->x[j]; for (i = 1; i <= m; i++) csa->best_y[i] = csa->y[i]; for (j = 1; j <= n; j++) csa->best_z[j] = csa->z[j]; csa->best_obj = csa->obj; } else csa->phi_min[csa->iter] = csa->phi_min[csa->iter-1]; /* display information at the current point */ if (csa->parm->msg_lev >= GLP_MSG_ON) xprintf("%3d: obj = %17.9e; rpi = %8.1e; rdi = %8.1e; gap =" " %8.1e\n", csa->iter, csa->obj, csa->rpi, csa->rdi, csa->gap); /* check if the current point is optimal */ if (csa->rpi < 1e-8 && csa->rdi < 1e-8 && csa->gap < 1e-8) { if (csa->parm->msg_lev >= GLP_MSG_ALL) xprintf("OPTIMAL SOLUTION FOUND\n"); status = 0; break; } /* check if the problem has no feasible solution */ temp = 1e5 * csa->phi_min[csa->iter]; if (temp < 1e-8) temp = 1e-8; if (csa->phi >= temp) { if (csa->parm->msg_lev >= GLP_MSG_ALL) xprintf("PROBLEM HAS NO FEASIBLE PRIMAL/DUAL SOLUTION\n") ; status = 1; break; } /* check for very slow convergence or divergence */ if (((csa->rpi >= 1e-8 || csa->rdi >= 1e-8) && csa->rmu / csa->rmu0 >= 1e6) || (csa->iter >= 30 && csa->phi_min[csa->iter] >= 0.5 * csa->phi_min[csa->iter - 30])) { if (csa->parm->msg_lev >= GLP_MSG_ALL) xprintf("NO CONVERGENCE; SEARCH TERMINATED\n"); status = 2; break; } /* check for maximal number of iterations */ if (csa->iter == ITER_MAX) { if (csa->parm->msg_lev >= GLP_MSG_ALL) xprintf("ITERATION LIMIT EXCEEDED; SEARCH TERMINATED\n"); status = 3; break; } /* start the next iteration */ csa->iter++; /* factorize normal equation system */ for (j = 1; j <= n; j++) csa->D[j] = csa->x[j] / csa->z[j]; decomp_NE(csa); /* compute the next point using Mehrotra's predictor-corrector technique */ if (make_step(csa)) { if (csa->parm->msg_lev >= GLP_MSG_ALL) xprintf("NUMERIC INSTABILITY; SEARCH TERMINATED\n"); status = 4; break; } } /* restore the best point */ if (status != 0) { for (j = 1; j <= n; j++) csa->x[j] = csa->best_x[j]; for (i = 1; i <= m; i++) csa->y[i] = csa->best_y[i]; for (j = 1; j <= n; j++) csa->z[j] = csa->best_z[j]; if (csa->parm->msg_lev >= GLP_MSG_ALL) xprintf("Best point %17.9e was reached on iteration %d\n", csa->best_obj, csa->best_iter); } /* return to the calling program */ return status; } /*********************************************************************** * NAME * * ipm_solve - core LP solver based on the interior-point method * * SYNOPSIS * * #include "glpipm.h" * int ipm_solve(glp_prob *P, const glp_iptcp *parm); * * DESCRIPTION * * The routine ipm_solve is a core LP solver based on the primal-dual * interior-point method. * * The routine assumes the following standard formulation of LP problem * to be solved: * * minimize * * F = c[0] + c[1]*x[1] + c[2]*x[2] + ... + c[n]*x[n] * * subject to linear constraints * * a[1,1]*x[1] + a[1,2]*x[2] + ... + a[1,n]*x[n] = b[1] * * a[2,1]*x[1] + a[2,2]*x[2] + ... + a[2,n]*x[n] = b[2] * * . . . . . . * * a[m,1]*x[1] + a[m,2]*x[2] + ... + a[m,n]*x[n] = b[m] * * and non-negative variables * * x[1] >= 0, x[2] >= 0, ..., x[n] >= 0 * * where: * F is the objective function; * x[1], ..., x[n] are (structural) variables; * c[0] is a constant term of the objective function; * c[1], ..., c[n] are objective coefficients; * a[1,1], ..., a[m,n] are constraint coefficients; * b[1], ..., b[n] are right-hand sides. * * The solution is three vectors x, y, and z, which are stored by the * routine in the arrays x, y, and z, respectively. These vectors * correspond to the best primal-dual point found during optimization. * They are approximate solution of the following system (which is the * Karush-Kuhn-Tucker optimality conditions): * * A*x = b (primal feasibility condition) * * A'*y + z = c (dual feasibility condition) * * x'*z = 0 (primal-dual complementarity condition) * * x >= 0, z >= 0 (non-negativity condition) * * where: * x[1], ..., x[n] are primal (structural) variables; * y[1], ..., y[m] are dual variables (Lagrange multipliers) for * equality constraints; * z[1], ..., z[n] are dual variables (Lagrange multipliers) for * non-negativity constraints. * * RETURNS * * 0 LP has been successfully solved. * * GLP_ENOCVG * No convergence. * * GLP_EITLIM * Iteration limit exceeded. * * GLP_EINSTAB * Numeric instability on solving Newtonian system. * * In case of non-zero return code the routine returns the best point, * which has been reached during optimization. */ int ipm_solve(glp_prob *P, const glp_iptcp *parm) { struct csa _dsa, *csa = &_dsa; int m = P->m; int n = P->n; int nnz = P->nnz; GLPROW *row; GLPCOL *col; GLPAIJ *aij; int i, j, loc, ret, *A_ind, *A_ptr; double dir, *A_val, *b, *c, *x, *y, *z; xassert(m > 0); xassert(n > 0); /* allocate working arrays */ A_ptr = xcalloc(1+m+1, sizeof(int)); A_ind = xcalloc(1+nnz, sizeof(int)); A_val = xcalloc(1+nnz, sizeof(double)); b = xcalloc(1+m, sizeof(double)); c = xcalloc(1+n, sizeof(double)); x = xcalloc(1+n, sizeof(double)); y = xcalloc(1+m, sizeof(double)); z = xcalloc(1+n, sizeof(double)); /* prepare rows and constraint coefficients */ loc = 1; for (i = 1; i <= m; i++) { row = P->row[i]; xassert(row->type == GLP_FX); b[i] = row->lb * row->rii; A_ptr[i] = loc; for (aij = row->ptr; aij != NULL; aij = aij->r_next) { A_ind[loc] = aij->col->j; A_val[loc] = row->rii * aij->val * aij->col->sjj; loc++; } } A_ptr[m+1] = loc; xassert(loc-1 == nnz); /* prepare columns and objective coefficients */ if (P->dir == GLP_MIN) dir = +1.0; else if (P->dir == GLP_MAX) dir = -1.0; else xassert(P != P); c[0] = dir * P->c0; for (j = 1; j <= n; j++) { col = P->col[j]; xassert(col->type == GLP_LO && col->lb == 0.0); c[j] = dir * col->coef * col->sjj; } /* allocate and initialize the common storage area */ csa->m = m; csa->n = n; csa->A_ptr = A_ptr; csa->A_ind = A_ind; csa->A_val = A_val; csa->b = b; csa->c = c; csa->x = x; csa->y = y; csa->z = z; csa->parm = parm; initialize(csa); /* solve LP with the interior-point method */ ret = ipm_main(csa); /* deallocate the common storage area */ terminate(csa); /* determine solution status */ if (ret == 0) { /* optimal solution found */ P->ipt_stat = GLP_OPT; ret = 0; } else if (ret == 1) { /* problem has no feasible (primal or dual) solution */ P->ipt_stat = GLP_NOFEAS; ret = 0; } else if (ret == 2) { /* no convergence */ P->ipt_stat = GLP_INFEAS; ret = GLP_ENOCVG; } else if (ret == 3) { /* iteration limit exceeded */ P->ipt_stat = GLP_INFEAS; ret = GLP_EITLIM; } else if (ret == 4) { /* numeric instability on solving Newtonian system */ P->ipt_stat = GLP_INFEAS; ret = GLP_EINSTAB; } else xassert(ret != ret); /* store row solution components */ for (i = 1; i <= m; i++) { row = P->row[i]; row->pval = row->lb; row->dval = dir * y[i] * row->rii; } /* store column solution components */ P->ipt_obj = P->c0; for (j = 1; j <= n; j++) { col = P->col[j]; col->pval = x[j] * col->sjj; col->dval = dir * z[j] / col->sjj; P->ipt_obj += col->coef * col->pval; } /* free working arrays */ xfree(A_ptr); xfree(A_ind); xfree(A_val); xfree(b); xfree(c); xfree(x); xfree(y); xfree(z); return ret; } /* eof */ praat-6.0.04/external/glpk/glpipm.h000066400000000000000000000024561261542461700171470ustar00rootroot00000000000000/* glpipm.h (primal-dual interior-point method) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPIPM_H #define GLPIPM_H #include "glpapi.h" #define ipm_solve _glp_ipm_solve int ipm_solve(glp_prob *P, const glp_iptcp *parm); /* core LP solver based on the interior-point method */ #endif /* eof */ praat-6.0.04/external/glpk/glpk.h000066400000000000000000001654271261542461700166240ustar00rootroot00000000000000/* glpk.h */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPK_H #define GLPK_H #include #include #if defined (__MINGW32__) && ! defined (DBL_EPSILON) #define DBL_EPSILON 2.2204460492503131e-16 // ppgb 20110903 #endif #ifdef __cplusplus extern "C" { #endif /* library version numbers: */ #define GLP_MAJOR_VERSION 4 #define GLP_MINOR_VERSION 44 #ifndef GLP_PROB_DEFINED #define GLP_PROB_DEFINED typedef struct { double _opaque_prob[100]; } glp_prob; /* LP/MIP problem object */ #endif /* optimization direction flag: */ #define GLP_MIN 1 /* minimization */ #define GLP_MAX 2 /* maximization */ /* kind of structural variable: */ #define GLP_CV 1 /* continuous variable */ #define GLP_IV 2 /* integer variable */ #define GLP_BV 3 /* binary variable */ /* type of auxiliary/structural variable: */ #define GLP_FR 1 /* free variable */ #define GLP_LO 2 /* variable with lower bound */ #define GLP_UP 3 /* variable with upper bound */ #define GLP_DB 4 /* double-bounded variable */ #define GLP_FX 5 /* fixed variable */ /* status of auxiliary/structural variable: */ #define GLP_BS 1 /* basic variable */ #define GLP_NL 2 /* non-basic variable on lower bound */ #define GLP_NU 3 /* non-basic variable on upper bound */ #define GLP_NF 4 /* non-basic free variable */ #define GLP_NS 5 /* non-basic fixed variable */ /* scaling options: */ #define GLP_SF_GM 0x01 /* perform geometric mean scaling */ #define GLP_SF_EQ 0x10 /* perform equilibration scaling */ #define GLP_SF_2N 0x20 /* round scale factors to power of two */ #define GLP_SF_SKIP 0x40 /* skip if problem is well scaled */ #define GLP_SF_AUTO 0x80 /* choose scaling options automatically */ /* solution indicator: */ #define GLP_SOL 1 /* basic solution */ #define GLP_IPT 2 /* interior-point solution */ #define GLP_MIP 3 /* mixed integer solution */ /* solution status: */ #define GLP_UNDEF 1 /* solution is undefined */ #define GLP_FEAS 2 /* solution is feasible */ #define GLP_INFEAS 3 /* solution is infeasible */ #define GLP_NOFEAS 4 /* no feasible solution exists */ #define GLP_OPT 5 /* solution is optimal */ #define GLP_UNBND 6 /* solution is unbounded */ typedef struct { /* basis factorization control parameters */ int msg_lev; /* (reserved) */ int type; /* factorization type: */ #define GLP_BF_FT 1 /* LUF + Forrest-Tomlin */ #define GLP_BF_BG 2 /* LUF + Schur compl. + Bartels-Golub */ #define GLP_BF_GR 3 /* LUF + Schur compl. + Givens rotation */ int lu_size; /* luf.sv_size */ double piv_tol; /* luf.piv_tol */ int piv_lim; /* luf.piv_lim */ int suhl; /* luf.suhl */ double eps_tol; /* luf.eps_tol */ double max_gro; /* luf.max_gro */ int nfs_max; /* fhv.hh_max */ double upd_tol; /* fhv.upd_tol */ int nrs_max; /* lpf.n_max */ int rs_size; /* lpf.v_size */ double foo_bar[38]; /* (reserved) */ } glp_bfcp; typedef struct { /* simplex method control parameters */ int msg_lev; /* message level: */ #define GLP_MSG_OFF 0 /* no output */ #define GLP_MSG_ERR 1 /* warning and error messages only */ #define GLP_MSG_ON 2 /* normal output */ #define GLP_MSG_ALL 3 /* full output */ #define GLP_MSG_DBG 4 /* debug output */ int meth; /* simplex method option: */ #define GLP_PRIMAL 1 /* use primal simplex */ #define GLP_DUALP 2 /* use dual; if it fails, use primal */ #define GLP_DUAL 3 /* use dual simplex */ int pricing; /* pricing technique: */ #define GLP_PT_STD 0x11 /* standard (Dantzig rule) */ #define GLP_PT_PSE 0x22 /* projected steepest edge */ int r_test; /* ratio test technique: */ #define GLP_RT_STD 0x11 /* standard (textbook) */ #define GLP_RT_HAR 0x22 /* two-pass Harris' ratio test */ double tol_bnd; /* spx.tol_bnd */ double tol_dj; /* spx.tol_dj */ double tol_piv; /* spx.tol_piv */ double obj_ll; /* spx.obj_ll */ double obj_ul; /* spx.obj_ul */ int it_lim; /* spx.it_lim */ int tm_lim; /* spx.tm_lim (milliseconds) */ int out_frq; /* spx.out_frq */ int out_dly; /* spx.out_dly (milliseconds) */ int presolve; /* enable/disable using LP presolver */ double foo_bar[36]; /* (reserved) */ } glp_smcp; typedef struct { /* interior-point solver control parameters */ int msg_lev; /* message level (see glp_smcp) */ int ord_alg; /* ordering algorithm: */ #define GLP_ORD_NONE 0 /* natural (original) ordering */ #define GLP_ORD_QMD 1 /* quotient minimum degree (QMD) */ #define GLP_ORD_AMD 2 /* approx. minimum degree (AMD) */ #define GLP_ORD_SYMAMD 3 /* approx. minimum degree (SYMAMD) */ double foo_bar[48]; /* (reserved) */ } glp_iptcp; #ifndef GLP_TREE_DEFINED #define GLP_TREE_DEFINED typedef struct { double _opaque_tree[100]; } glp_tree; /* branch-and-bound tree */ #endif typedef struct { /* integer optimizer control parameters */ int msg_lev; /* message level (see glp_smcp) */ int br_tech; /* branching technique: */ #define GLP_BR_FFV 1 /* first fractional variable */ #define GLP_BR_LFV 2 /* last fractional variable */ #define GLP_BR_MFV 3 /* most fractional variable */ #define GLP_BR_DTH 4 /* heuristic by Driebeck and Tomlin */ #define GLP_BR_PCH 5 /* hybrid pseudocost heuristic */ int bt_tech; /* backtracking technique: */ #define GLP_BT_DFS 1 /* depth first search */ #define GLP_BT_BFS 2 /* breadth first search */ #define GLP_BT_BLB 3 /* best local bound */ #define GLP_BT_BPH 4 /* best projection heuristic */ double tol_int; /* mip.tol_int */ double tol_obj; /* mip.tol_obj */ int tm_lim; /* mip.tm_lim (milliseconds) */ int out_frq; /* mip.out_frq (milliseconds) */ int out_dly; /* mip.out_dly (milliseconds) */ void (*cb_func)(glp_tree *T, void *info); /* mip.cb_func */ void *cb_info; /* mip.cb_info */ int cb_size; /* mip.cb_size */ int pp_tech; /* preprocessing technique: */ #define GLP_PP_NONE 0 /* disable preprocessing */ #define GLP_PP_ROOT 1 /* preprocessing only on root level */ #define GLP_PP_ALL 2 /* preprocessing on all levels */ double mip_gap; /* relative MIP gap tolerance */ int mir_cuts; /* MIR cuts (GLP_ON/GLP_OFF) */ int gmi_cuts; /* Gomory's cuts (GLP_ON/GLP_OFF) */ int cov_cuts; /* cover cuts (GLP_ON/GLP_OFF) */ int clq_cuts; /* clique cuts (GLP_ON/GLP_OFF) */ int presolve; /* enable/disable using MIP presolver */ int binarize; /* try to binarize integer variables */ int fp_heur; /* feasibility pump heuristic */ #if 1 /* 28/V-2010 */ int alien; /* use alien solver */ #endif double foo_bar[29]; /* (reserved) */ } glp_iocp; typedef struct { /* additional row attributes */ int level; /* subproblem level at which the row was added */ int origin; /* row origin flag: */ #define GLP_RF_REG 0 /* regular constraint */ #define GLP_RF_LAZY 1 /* "lazy" constraint */ #define GLP_RF_CUT 2 /* cutting plane constraint */ int klass; /* row class descriptor: */ #define GLP_RF_GMI 1 /* Gomory's mixed integer cut */ #define GLP_RF_MIR 2 /* mixed integer rounding cut */ #define GLP_RF_COV 3 /* mixed cover cut */ #define GLP_RF_CLQ 4 /* clique cut */ double foo_bar[7]; /* (reserved) */ } glp_attr; /* enable/disable flag: */ #define GLP_ON 1 /* enable something */ #define GLP_OFF 0 /* disable something */ /* reason codes: */ #define GLP_IROWGEN 0x01 /* request for row generation */ #define GLP_IBINGO 0x02 /* better integer solution found */ #define GLP_IHEUR 0x03 /* request for heuristic solution */ #define GLP_ICUTGEN 0x04 /* request for cut generation */ #define GLP_IBRANCH 0x05 /* request for branching */ #define GLP_ISELECT 0x06 /* request for subproblem selection */ #define GLP_IPREPRO 0x07 /* request for preprocessing */ /* branch selection indicator: */ #define GLP_NO_BRNCH 0 /* select no branch */ #define GLP_DN_BRNCH 1 /* select down-branch */ #define GLP_UP_BRNCH 2 /* select up-branch */ /* return codes: */ #define GLP_EBADB 0x01 /* invalid basis */ #define GLP_ESING 0x02 /* singular matrix */ #define GLP_ECOND 0x03 /* ill-conditioned matrix */ #define GLP_EBOUND 0x04 /* invalid bounds */ #define GLP_EFAIL 0x05 /* solver failed */ #define GLP_EOBJLL 0x06 /* objective lower limit reached */ #define GLP_EOBJUL 0x07 /* objective upper limit reached */ #define GLP_EITLIM 0x08 /* iteration limit exceeded */ #define GLP_ETMLIM 0x09 /* time limit exceeded */ #define GLP_ENOPFS 0x0A /* no primal feasible solution */ #define GLP_ENODFS 0x0B /* no dual feasible solution */ #define GLP_EROOT 0x0C /* root LP optimum not provided */ #define GLP_ESTOP 0x0D /* search terminated by application */ #define GLP_EMIPGAP 0x0E /* relative mip gap tolerance reached */ #define GLP_ENOFEAS 0x0F /* no primal/dual feasible solution */ #define GLP_ENOCVG 0x10 /* no convergence */ #define GLP_EINSTAB 0x11 /* numerical instability */ #define GLP_EDATA 0x12 /* invalid data */ #define GLP_ERANGE 0x13 /* result out of range */ /* condition indicator: */ #define GLP_KKT_PE 1 /* primal equalities */ #define GLP_KKT_PB 2 /* primal bounds */ #define GLP_KKT_DE 3 /* dual equalities */ #define GLP_KKT_DB 4 /* dual bounds */ #define GLP_KKT_CS 5 /* complementary slackness */ /* MPS file format: */ #define GLP_MPS_DECK 1 /* fixed (ancient) */ #define GLP_MPS_FILE 2 /* free (modern) */ typedef struct { /* MPS format control parameters */ int blank; /* character code to replace blanks in symbolic names */ char *obj_name; /* objective row name */ double tol_mps; /* zero tolerance for MPS data */ double foo_bar[17]; /* (reserved for use in the future) */ } glp_mpscp; typedef struct { /* CPLEX LP format control parameters */ double foo_bar[20]; /* (reserved for use in the future) */ } glp_cpxcp; #ifndef GLP_TRAN_DEFINED #define GLP_TRAN_DEFINED typedef struct { double _opaque_tran[100]; } glp_tran; /* MathProg translator workspace */ #endif glp_prob *glp_create_prob(void); /* create problem object */ void glp_set_prob_name(glp_prob *P, const char *name); /* assign (change) problem name */ void glp_set_obj_name(glp_prob *P, const char *name); /* assign (change) objective function name */ void glp_set_obj_dir(glp_prob *P, int dir); /* set (change) optimization direction flag */ int glp_add_rows(glp_prob *P, int nrs); /* add new rows to problem object */ int glp_add_cols(glp_prob *P, int ncs); /* add new columns to problem object */ void glp_set_row_name(glp_prob *P, int i, const char *name); /* assign (change) row name */ void glp_set_col_name(glp_prob *P, int j, const char *name); /* assign (change) column name */ void glp_set_row_bnds(glp_prob *P, int i, int type, double lb, double ub); /* set (change) row bounds */ void glp_set_col_bnds(glp_prob *P, int j, int type, double lb, double ub); /* set (change) column bounds */ void glp_set_obj_coef(glp_prob *P, int j, double coef); /* set (change) obj. coefficient or constant term */ void glp_set_mat_row(glp_prob *P, int i, int len, const int ind[], const double val[]); /* set (replace) row of the constraint matrix */ void glp_set_mat_col(glp_prob *P, int j, int len, const int ind[], const double val[]); /* set (replace) column of the constraint matrix */ void glp_load_matrix(glp_prob *P, int ne, const int ia[], const int ja[], const double ar[]); /* load (replace) the whole constraint matrix */ int glp_check_dup(int m, int n, int ne, const int ia[], const int ja[]); /* check for duplicate elements in sparse matrix */ void glp_sort_matrix(glp_prob *P); /* sort elements of the constraint matrix */ void glp_del_rows(glp_prob *P, int nrs, const int num[]); /* delete specified rows from problem object */ void glp_del_cols(glp_prob *P, int ncs, const int num[]); /* delete specified columns from problem object */ void glp_copy_prob(glp_prob *dest, glp_prob *prob, int names); /* copy problem object content */ void glp_erase_prob(glp_prob *P); /* erase problem object content */ void glp_delete_prob(glp_prob *P); /* delete problem object */ const char *glp_get_prob_name(glp_prob *P); /* retrieve problem name */ const char *glp_get_obj_name(glp_prob *P); /* retrieve objective function name */ int glp_get_obj_dir(glp_prob *P); /* retrieve optimization direction flag */ int glp_get_num_rows(glp_prob *P); /* retrieve number of rows */ int glp_get_num_cols(glp_prob *P); /* retrieve number of columns */ const char *glp_get_row_name(glp_prob *P, int i); /* retrieve row name */ const char *glp_get_col_name(glp_prob *P, int j); /* retrieve column name */ int glp_get_row_type(glp_prob *P, int i); /* retrieve row type */ double glp_get_row_lb(glp_prob *P, int i); /* retrieve row lower bound */ double glp_get_row_ub(glp_prob *P, int i); /* retrieve row upper bound */ int glp_get_col_type(glp_prob *P, int j); /* retrieve column type */ double glp_get_col_lb(glp_prob *P, int j); /* retrieve column lower bound */ double glp_get_col_ub(glp_prob *P, int j); /* retrieve column upper bound */ double glp_get_obj_coef(glp_prob *P, int j); /* retrieve obj. coefficient or constant term */ int glp_get_num_nz(glp_prob *P); /* retrieve number of constraint coefficients */ int glp_get_mat_row(glp_prob *P, int i, int ind[], double val[]); /* retrieve row of the constraint matrix */ int glp_get_mat_col(glp_prob *P, int j, int ind[], double val[]); /* retrieve column of the constraint matrix */ void glp_create_index(glp_prob *P); /* create the name index */ int glp_find_row(glp_prob *P, const char *name); /* find row by its name */ int glp_find_col(glp_prob *P, const char *name); /* find column by its name */ void glp_delete_index(glp_prob *P); /* delete the name index */ void glp_set_rii(glp_prob *P, int i, double rii); /* set (change) row scale factor */ void glp_set_sjj(glp_prob *P, int j, double sjj); /* set (change) column scale factor */ double glp_get_rii(glp_prob *P, int i); /* retrieve row scale factor */ double glp_get_sjj(glp_prob *P, int j); /* retrieve column scale factor */ void glp_scale_prob(glp_prob *P, int flags); /* scale problem data */ void glp_unscale_prob(glp_prob *P); /* unscale problem data */ void glp_set_row_stat(glp_prob *P, int i, int stat); /* set (change) row status */ void glp_set_col_stat(glp_prob *P, int j, int stat); /* set (change) column status */ void glp_std_basis(glp_prob *P); /* construct standard initial LP basis */ void glp_adv_basis(glp_prob *P, int flags); /* construct advanced initial LP basis */ void glp_cpx_basis(glp_prob *P); /* construct Bixby's initial LP basis */ int glp_simplex(glp_prob *P, const glp_smcp *parm); /* solve LP problem with the simplex method */ int glp_exact(glp_prob *P, const glp_smcp *parm); /* solve LP problem in exact arithmetic */ void glp_init_smcp(glp_smcp *parm); /* initialize simplex method control parameters */ int glp_get_status(glp_prob *P); /* retrieve generic status of basic solution */ int glp_get_prim_stat(glp_prob *P); /* retrieve status of primal basic solution */ int glp_get_dual_stat(glp_prob *P); /* retrieve status of dual basic solution */ double glp_get_obj_val(glp_prob *P); /* retrieve objective value (basic solution) */ int glp_get_row_stat(glp_prob *P, int i); /* retrieve row status */ double glp_get_row_prim(glp_prob *P, int i); /* retrieve row primal value (basic solution) */ double glp_get_row_dual(glp_prob *P, int i); /* retrieve row dual value (basic solution) */ int glp_get_col_stat(glp_prob *P, int j); /* retrieve column status */ double glp_get_col_prim(glp_prob *P, int j); /* retrieve column primal value (basic solution) */ double glp_get_col_dual(glp_prob *P, int j); /* retrieve column dual value (basic solution) */ int glp_get_unbnd_ray(glp_prob *P); /* determine variable causing unboundedness */ int glp_interior(glp_prob *P, const glp_iptcp *parm); /* solve LP problem with the interior-point method */ void glp_init_iptcp(glp_iptcp *parm); /* initialize interior-point solver control parameters */ int glp_ipt_status(glp_prob *P); /* retrieve status of interior-point solution */ double glp_ipt_obj_val(glp_prob *P); /* retrieve objective value (interior point) */ double glp_ipt_row_prim(glp_prob *P, int i); /* retrieve row primal value (interior point) */ double glp_ipt_row_dual(glp_prob *P, int i); /* retrieve row dual value (interior point) */ double glp_ipt_col_prim(glp_prob *P, int j); /* retrieve column primal value (interior point) */ double glp_ipt_col_dual(glp_prob *P, int j); /* retrieve column dual value (interior point) */ void glp_set_col_kind(glp_prob *P, int j, int kind); /* set (change) column kind */ int glp_get_col_kind(glp_prob *P, int j); /* retrieve column kind */ int glp_get_num_int(glp_prob *P); /* retrieve number of integer columns */ int glp_get_num_bin(glp_prob *P); /* retrieve number of binary columns */ int glp_intopt(glp_prob *P, const glp_iocp *parm); /* solve MIP problem with the branch-and-bound method */ void glp_init_iocp(glp_iocp *parm); /* initialize integer optimizer control parameters */ int glp_mip_status(glp_prob *P); /* retrieve status of MIP solution */ double glp_mip_obj_val(glp_prob *P); /* retrieve objective value (MIP solution) */ double glp_mip_row_val(glp_prob *P, int i); /* retrieve row value (MIP solution) */ double glp_mip_col_val(glp_prob *P, int j); /* retrieve column value (MIP solution) */ int glp_print_sol(glp_prob *P, const char *fname); /* write basic solution in printable format */ int glp_read_sol(glp_prob *P, const char *fname); /* read basic solution from text file */ int glp_write_sol(glp_prob *P, const char *fname); /* write basic solution to text file */ int glp_print_ranges(glp_prob *P, int len, const int list[], int flags, const char *fname); /* print sensitivity analysis report */ int glp_print_ipt(glp_prob *P, const char *fname); /* write interior-point solution in printable format */ int glp_read_ipt(glp_prob *P, const char *fname); /* read interior-point solution from text file */ int glp_write_ipt(glp_prob *P, const char *fname); /* write interior-point solution to text file */ int glp_print_mip(glp_prob *P, const char *fname); /* write MIP solution in printable format */ int glp_read_mip(glp_prob *P, const char *fname); /* read MIP solution from text file */ int glp_write_mip(glp_prob *P, const char *fname); /* write MIP solution to text file */ int glp_bf_exists(glp_prob *P); /* check if the basis factorization exists */ int glp_factorize(glp_prob *P); /* compute the basis factorization */ int glp_bf_updated(glp_prob *P); /* check if the basis factorization has been updated */ void glp_get_bfcp(glp_prob *P, glp_bfcp *parm); /* retrieve basis factorization control parameters */ void glp_set_bfcp(glp_prob *P, const glp_bfcp *parm); /* change basis factorization control parameters */ int glp_get_bhead(glp_prob *P, int k); /* retrieve the basis header information */ int glp_get_row_bind(glp_prob *P, int i); /* retrieve row index in the basis header */ int glp_get_col_bind(glp_prob *P, int j); /* retrieve column index in the basis header */ void glp_ftran(glp_prob *P, double x[]); /* perform forward transformation (solve system B*x = b) */ void glp_btran(glp_prob *P, double x[]); /* perform backward transformation (solve system B'*x = b) */ int glp_warm_up(glp_prob *P); /* "warm up" LP basis */ int glp_eval_tab_row(glp_prob *P, int k, int ind[], double val[]); /* compute row of the simplex tableau */ int glp_eval_tab_col(glp_prob *P, int k, int ind[], double val[]); /* compute column of the simplex tableau */ int glp_transform_row(glp_prob *P, int len, int ind[], double val[]); /* transform explicitly specified row */ int glp_transform_col(glp_prob *P, int len, int ind[], double val[]); /* transform explicitly specified column */ int glp_prim_rtest(glp_prob *P, int len, const int ind[], const double val[], int dir, double eps); /* perform primal ratio test */ int glp_dual_rtest(glp_prob *P, int len, const int ind[], const double val[], int dir, double eps); /* perform dual ratio test */ void glp_analyze_bound(glp_prob *P, int k, double *value1, int *var1, double *value2, int *var2); /* analyze active bound of non-basic variable */ void glp_analyze_coef(glp_prob *P, int k, double *coef1, int *var1, double *value1, double *coef2, int *var2, double *value2); /* analyze objective coefficient at basic variable */ int glp_ios_reason(glp_tree *T); /* determine reason for calling the callback routine */ glp_prob *glp_ios_get_prob(glp_tree *T); /* access the problem object */ void glp_ios_tree_size(glp_tree *T, int *a_cnt, int *n_cnt, int *t_cnt); /* determine size of the branch-and-bound tree */ int glp_ios_curr_node(glp_tree *T); /* determine current active subproblem */ int glp_ios_next_node(glp_tree *T, int p); /* determine next active subproblem */ int glp_ios_prev_node(glp_tree *T, int p); /* determine previous active subproblem */ int glp_ios_up_node(glp_tree *T, int p); /* determine parent subproblem */ int glp_ios_node_level(glp_tree *T, int p); /* determine subproblem level */ double glp_ios_node_bound(glp_tree *T, int p); /* determine subproblem local bound */ int glp_ios_best_node(glp_tree *T); /* find active subproblem with best local bound */ double glp_ios_mip_gap(glp_tree *T); /* compute relative MIP gap */ void *glp_ios_node_data(glp_tree *T, int p); /* access subproblem application-specific data */ void glp_ios_row_attr(glp_tree *T, int i, glp_attr *attr); /* retrieve additional row attributes */ int glp_ios_pool_size(glp_tree *T); /* determine current size of the cut pool */ int glp_ios_add_row(glp_tree *T, const char *name, int klass, int flags, int len, const int ind[], const double val[], int type, double rhs); /* add row (constraint) to the cut pool */ void glp_ios_del_row(glp_tree *T, int i); /* remove row (constraint) from the cut pool */ void glp_ios_clear_pool(glp_tree *T); /* remove all rows (constraints) from the cut pool */ int glp_ios_can_branch(glp_tree *T, int j); /* check if can branch upon specified variable */ void glp_ios_branch_upon(glp_tree *T, int j, int sel); /* choose variable to branch upon */ void glp_ios_select_node(glp_tree *T, int p); /* select subproblem to continue the search */ int glp_ios_heur_sol(glp_tree *T, const double x[]); /* provide solution found by heuristic */ void glp_ios_terminate(glp_tree *T); /* terminate the solution process */ void glp_init_mpscp(glp_mpscp *parm); /* initialize MPS format control parameters */ int glp_read_mps(glp_prob *P, int fmt, const glp_mpscp *parm, const char *fname); /* read problem data in MPS format */ int glp_write_mps(glp_prob *P, int fmt, const glp_mpscp *parm, const char *fname); /* write problem data in MPS format */ void glp_init_cpxcp(glp_cpxcp *parm); /* initialize CPLEX LP format control parameters */ int glp_read_lp(glp_prob *P, const glp_cpxcp *parm, const char *fname); /* read problem data in CPLEX LP format */ int glp_write_lp(glp_prob *P, const glp_cpxcp *parm, const char *fname); /* write problem data in CPLEX LP format */ int glp_read_prob(glp_prob *P, int flags, const char *fname); /* read problem data in GLPK format */ int glp_write_prob(glp_prob *P, int flags, const char *fname); /* write problem data in GLPK format */ glp_tran *glp_mpl_alloc_wksp(void); /* allocate the MathProg translator workspace */ int glp_mpl_read_model(glp_tran *tran, const char *fname, int skip); /* read and translate model section */ int glp_mpl_read_data(glp_tran *tran, const char *fname); /* read and translate data section */ int glp_mpl_generate(glp_tran *tran, const char *fname); /* generate the model */ void glp_mpl_build_prob(glp_tran *tran, glp_prob *prob); /* build LP/MIP problem instance from the model */ int glp_mpl_postsolve(glp_tran *tran, glp_prob *prob, int sol); /* postsolve the model */ void glp_mpl_free_wksp(glp_tran *tran); /* free the MathProg translator workspace */ int glp_main(int argc, const char *argv[]); /* stand-alone LP/MIP solver */ /**********************************************************************/ #ifndef GLP_LONG_DEFINED #define GLP_LONG_DEFINED typedef struct { int lo, hi; } glp_long; /* long integer data type */ #endif int glp_init_env(void); /* initialize GLPK environment */ const char *glp_version(void); /* determine library version */ int glp_free_env(void); /* free GLPK environment */ void glp_printf(const char *fmt, ...); /* write formatted output to terminal */ void glp_vprintf(const char *fmt, va_list arg); /* write formatted output to terminal */ int glp_term_out(int flag); /* enable/disable terminal output */ void glp_term_hook(int (*func)(void *info, const char *s), void *info); /* install hook to intercept terminal output */ int glp_open_tee(const char *fname); /* start copying terminal output to text file */ int glp_close_tee(void); /* stop copying terminal output to text file */ #ifndef GLP_ERROR_DEFINED #define GLP_ERROR_DEFINED typedef void (*_glp_error)(const char *fmt, ...); #endif #define glp_error glp_error_(__FILE__, __LINE__) _glp_error glp_error_(const char *file, int line); /* display error message and terminate execution */ #define glp_assert(expr) \ ((void)((expr) || (glp_assert_(#expr, __FILE__, __LINE__), 1))) void glp_assert_(const char *expr, const char *file, int line); /* check for logical condition */ void glp_error_hook(void (*func)(void *info), void *info); /* install hook to intercept abnormal termination */ void *glp_malloc(int size); /* allocate memory block */ void *glp_calloc(int n, int size); /* allocate memory block */ void glp_free(void *ptr); /* free memory block */ void glp_mem_limit(int limit); /* set memory usage limit */ void glp_mem_usage(int *count, int *cpeak, glp_long *total, glp_long *tpeak); /* get memory usage information */ glp_long glp_time(void); /* determine current universal time */ double glp_difftime(glp_long t1, glp_long t0); /* compute difference between two time values */ /**********************************************************************/ #ifndef GLP_DATA_DEFINED #define GLP_DATA_DEFINED typedef struct { double _opaque_data[100]; } glp_data; /* plain data file */ #endif glp_data *glp_sdf_open_file(const char *fname); /* open plain data file */ void glp_sdf_set_jump(glp_data *data, void *jump); /* set up error handling */ void glp_sdf_error(glp_data *data, const char *fmt, ...); /* print error message */ void glp_sdf_warning(glp_data *data, const char *fmt, ...); /* print warning message */ int glp_sdf_read_int(glp_data *data); /* read integer number */ double glp_sdf_read_num(glp_data *data); /* read floating-point number */ const char *glp_sdf_read_item(glp_data *data); /* read data item */ const char *glp_sdf_read_text(glp_data *data); /* read text until end of line */ int glp_sdf_line(glp_data *data); /* determine current line number */ void glp_sdf_close_file(glp_data *data); /* close plain data file */ /**********************************************************************/ typedef struct _glp_graph glp_graph; typedef struct _glp_vertex glp_vertex; typedef struct _glp_arc glp_arc; struct _glp_graph { /* graph descriptor */ void *pool; /* DMP *pool; */ /* memory pool to store graph components */ char *name; /* graph name (1 to 255 chars); NULL means no name is assigned to the graph */ int nv_max; /* length of the vertex list (enlarged automatically) */ int nv; /* number of vertices in the graph, 0 <= nv <= nv_max */ int na; /* number of arcs in the graph, na >= 0 */ glp_vertex **v; /* glp_vertex *v[1+nv_max]; */ /* v[i], 1 <= i <= nv, is a pointer to i-th vertex */ void *index; /* AVL *index; */ /* vertex index to find vertices by their names; NULL means the index does not exist */ int v_size; /* size of data associated with each vertex (0 to 256 bytes) */ int a_size; /* size of data associated with each arc (0 to 256 bytes) */ }; struct _glp_vertex { /* vertex descriptor */ int i; /* vertex ordinal number, 1 <= i <= nv */ char *name; /* vertex name (1 to 255 chars); NULL means no name is assigned to the vertex */ void *entry; /* AVLNODE *entry; */ /* pointer to corresponding entry in the vertex index; NULL means that either the index does not exist or the vertex has no name assigned */ void *data; /* pointer to data associated with the vertex */ void *temp; /* working pointer */ glp_arc *in; /* pointer to the (unordered) list of incoming arcs */ glp_arc *out; /* pointer to the (unordered) list of outgoing arcs */ }; struct _glp_arc { /* arc descriptor */ glp_vertex *tail; /* pointer to the tail endpoint */ glp_vertex *head; /* pointer to the head endpoint */ void *data; /* pointer to data associated with the arc */ void *temp; /* working pointer */ glp_arc *t_prev; /* pointer to previous arc having the same tail endpoint */ glp_arc *t_next; /* pointer to next arc having the same tail endpoint */ glp_arc *h_prev; /* pointer to previous arc having the same head endpoint */ glp_arc *h_next; /* pointer to next arc having the same head endpoint */ }; glp_graph *glp_create_graph(int v_size, int a_size); /* create graph */ void glp_set_graph_name(glp_graph *G, const char *name); /* assign (change) graph name */ int glp_add_vertices(glp_graph *G, int nadd); /* add new vertices to graph */ void glp_set_vertex_name(glp_graph *G, int i, const char *name); /* assign (change) vertex name */ glp_arc *glp_add_arc(glp_graph *G, int i, int j); /* add new arc to graph */ void glp_del_vertices(glp_graph *G, int ndel, const int num[]); /* delete vertices from graph */ void glp_del_arc(glp_graph *G, glp_arc *a); /* delete arc from graph */ void glp_erase_graph(glp_graph *G, int v_size, int a_size); /* erase graph content */ void glp_delete_graph(glp_graph *G); /* delete graph */ void glp_create_v_index(glp_graph *G); /* create vertex name index */ int glp_find_vertex(glp_graph *G, const char *name); /* find vertex by its name */ void glp_delete_v_index(glp_graph *G); /* delete vertex name index */ int glp_read_graph(glp_graph *G, const char *fname); /* read graph from plain text file */ int glp_write_graph(glp_graph *G, const char *fname); /* write graph to plain text file */ void glp_mincost_lp(glp_prob *P, glp_graph *G, int names, int v_rhs, int a_low, int a_cap, int a_cost); /* convert minimum cost flow problem to LP */ int glp_mincost_okalg(glp_graph *G, int v_rhs, int a_low, int a_cap, int a_cost, double *sol, int a_x, int v_pi); /* find minimum-cost flow with out-of-kilter algorithm */ void glp_maxflow_lp(glp_prob *P, glp_graph *G, int names, int s, int t, int a_cap); /* convert maximum flow problem to LP */ int glp_maxflow_ffalg(glp_graph *G, int s, int t, int a_cap, double *sol, int a_x, int v_cut); /* find maximal flow with Ford-Fulkerson algorithm */ int glp_check_asnprob(glp_graph *G, int v_set); /* check correctness of assignment problem data */ /* assignment problem formulation: */ #define GLP_ASN_MIN 1 /* perfect matching (minimization) */ #define GLP_ASN_MAX 2 /* perfect matching (maximization) */ #define GLP_ASN_MMP 3 /* maximum matching */ int glp_asnprob_lp(glp_prob *P, int form, glp_graph *G, int names, int v_set, int a_cost); /* convert assignment problem to LP */ int glp_asnprob_okalg(int form, glp_graph *G, int v_set, int a_cost, double *sol, int a_x); /* solve assignment problem with out-of-kilter algorithm */ int glp_asnprob_hall(glp_graph *G, int v_set, int a_x); /* find bipartite matching of maximum cardinality */ double glp_cpp(glp_graph *G, int v_t, int v_es, int v_ls); /* solve critical path problem */ int glp_read_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap, int a_cost, const char *fname); /* read min-cost flow problem data in DIMACS format */ int glp_write_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap, int a_cost, const char *fname); /* write min-cost flow problem data in DIMACS format */ int glp_read_maxflow(glp_graph *G, int *s, int *t, int a_cap, const char *fname); /* read maximum flow problem data in DIMACS format */ int glp_write_maxflow(glp_graph *G, int s, int t, int a_cap, const char *fname); /* write maximum flow problem data in DIMACS format */ int glp_read_asnprob(glp_graph *G, int v_set, int a_cost, const char *fname); /* read assignment problem data in DIMACS format */ int glp_write_asnprob(glp_graph *G, int v_set, int a_cost, const char *fname); /* write assignment problem data in DIMACS format */ int glp_read_ccdata(glp_graph *G, int v_wgt, const char *fname); /* read graph in DIMACS clique/coloring format */ int glp_write_ccdata(glp_graph *G, int v_wgt, const char *fname); /* write graph in DIMACS clique/coloring format */ int glp_netgen(glp_graph *G, int v_rhs, int a_cap, int a_cost, const int parm[1+15]); /* Klingman's network problem generator */ int glp_gridgen(glp_graph *G, int v_rhs, int a_cap, int a_cost, const int parm[1+14]); /* grid-like network problem generator */ int glp_rmfgen(glp_graph *G, int *s, int *t, int a_cap, const int parm[1+5]); /* Goldfarb's maximum flow problem generator */ int glp_weak_comp(glp_graph *G, int v_num); /* find all weakly connected components of graph */ int glp_strong_comp(glp_graph *G, int v_num); /* find all strongly connected components of graph */ int glp_top_sort(glp_graph *G, int v_num); /* topological sorting of acyclic digraph */ int glp_wclique_exact(glp_graph *G, int v_wgt, double *sol, int v_set); /* find maximum weight clique with exact algorithm */ /*********************************************************************** * NOTE: All symbols defined below are obsolete and kept here only for * backward compatibility. ***********************************************************************/ #define LPX glp_prob /* problem class: */ #define LPX_LP 100 /* linear programming (LP) */ #define LPX_MIP 101 /* mixed integer programming (MIP) */ /* type of auxiliary/structural variable: */ #define LPX_FR 110 /* free variable */ #define LPX_LO 111 /* variable with lower bound */ #define LPX_UP 112 /* variable with upper bound */ #define LPX_DB 113 /* double-bounded variable */ #define LPX_FX 114 /* fixed variable */ /* optimization direction flag: */ #define LPX_MIN 120 /* minimization */ #define LPX_MAX 121 /* maximization */ /* status of primal basic solution: */ #define LPX_P_UNDEF 132 /* primal solution is undefined */ #define LPX_P_FEAS 133 /* solution is primal feasible */ #define LPX_P_INFEAS 134 /* solution is primal infeasible */ #define LPX_P_NOFEAS 135 /* no primal feasible solution exists */ /* status of dual basic solution: */ #define LPX_D_UNDEF 136 /* dual solution is undefined */ #define LPX_D_FEAS 137 /* solution is dual feasible */ #define LPX_D_INFEAS 138 /* solution is dual infeasible */ #define LPX_D_NOFEAS 139 /* no dual feasible solution exists */ /* status of auxiliary/structural variable: */ #define LPX_BS 140 /* basic variable */ #define LPX_NL 141 /* non-basic variable on lower bound */ #define LPX_NU 142 /* non-basic variable on upper bound */ #define LPX_NF 143 /* non-basic free variable */ #define LPX_NS 144 /* non-basic fixed variable */ /* status of interior-point solution: */ #define LPX_T_UNDEF 150 /* interior solution is undefined */ #define LPX_T_OPT 151 /* interior solution is optimal */ /* kind of structural variable: */ #define LPX_CV 160 /* continuous variable */ #define LPX_IV 161 /* integer variable */ /* status of integer solution: */ #define LPX_I_UNDEF 170 /* integer solution is undefined */ #define LPX_I_OPT 171 /* integer solution is optimal */ #define LPX_I_FEAS 172 /* integer solution is feasible */ #define LPX_I_NOFEAS 173 /* no integer solution exists */ /* status codes reported by the routine lpx_get_status: */ #define LPX_OPT 180 /* optimal */ #define LPX_FEAS 181 /* feasible */ #define LPX_INFEAS 182 /* infeasible */ #define LPX_NOFEAS 183 /* no feasible */ #define LPX_UNBND 184 /* unbounded */ #define LPX_UNDEF 185 /* undefined */ /* exit codes returned by solver routines: */ #define LPX_E_OK 200 /* success */ #define LPX_E_EMPTY 201 /* empty problem */ #define LPX_E_BADB 202 /* invalid initial basis */ #define LPX_E_INFEAS 203 /* infeasible initial solution */ #define LPX_E_FAULT 204 /* unable to start the search */ #define LPX_E_OBJLL 205 /* objective lower limit reached */ #define LPX_E_OBJUL 206 /* objective upper limit reached */ #define LPX_E_ITLIM 207 /* iterations limit exhausted */ #define LPX_E_TMLIM 208 /* time limit exhausted */ #define LPX_E_NOFEAS 209 /* no feasible solution */ #define LPX_E_INSTAB 210 /* numerical instability */ #define LPX_E_SING 211 /* problems with basis matrix */ #define LPX_E_NOCONV 212 /* no convergence (interior) */ #define LPX_E_NOPFS 213 /* no primal feas. sol. (LP presolver) */ #define LPX_E_NODFS 214 /* no dual feas. sol. (LP presolver) */ #define LPX_E_MIPGAP 215 /* relative mip gap tolerance reached */ /* control parameter identifiers: */ #define LPX_K_MSGLEV 300 /* lp->msg_lev */ #define LPX_K_SCALE 301 /* lp->scale */ #define LPX_K_DUAL 302 /* lp->dual */ #define LPX_K_PRICE 303 /* lp->price */ #define LPX_K_RELAX 304 /* lp->relax */ #define LPX_K_TOLBND 305 /* lp->tol_bnd */ #define LPX_K_TOLDJ 306 /* lp->tol_dj */ #define LPX_K_TOLPIV 307 /* lp->tol_piv */ #define LPX_K_ROUND 308 /* lp->round */ #define LPX_K_OBJLL 309 /* lp->obj_ll */ #define LPX_K_OBJUL 310 /* lp->obj_ul */ #define LPX_K_ITLIM 311 /* lp->it_lim */ #define LPX_K_ITCNT 312 /* lp->it_cnt */ #define LPX_K_TMLIM 313 /* lp->tm_lim */ #define LPX_K_OUTFRQ 314 /* lp->out_frq */ #define LPX_K_OUTDLY 315 /* lp->out_dly */ #define LPX_K_BRANCH 316 /* lp->branch */ #define LPX_K_BTRACK 317 /* lp->btrack */ #define LPX_K_TOLINT 318 /* lp->tol_int */ #define LPX_K_TOLOBJ 319 /* lp->tol_obj */ #define LPX_K_MPSINFO 320 /* lp->mps_info */ #define LPX_K_MPSOBJ 321 /* lp->mps_obj */ #define LPX_K_MPSORIG 322 /* lp->mps_orig */ #define LPX_K_MPSWIDE 323 /* lp->mps_wide */ #define LPX_K_MPSFREE 324 /* lp->mps_free */ #define LPX_K_MPSSKIP 325 /* lp->mps_skip */ #define LPX_K_LPTORIG 326 /* lp->lpt_orig */ #define LPX_K_PRESOL 327 /* lp->presol */ #define LPX_K_BINARIZE 328 /* lp->binarize */ #define LPX_K_USECUTS 329 /* lp->use_cuts */ #define LPX_K_BFTYPE 330 /* lp->bfcp->type */ #define LPX_K_MIPGAP 331 /* lp->mip_gap */ #define LPX_C_COVER 0x01 /* mixed cover cuts */ #define LPX_C_CLIQUE 0x02 /* clique cuts */ #define LPX_C_GOMORY 0x04 /* Gomory's mixed integer cuts */ #define LPX_C_MIR 0x08 /* mixed integer rounding cuts */ #define LPX_C_ALL 0xFF /* all cuts */ typedef struct { /* this structure contains results reported by the routines which checks Karush-Kuhn-Tucker conditions (for details see comments to those routines) */ /*--------------------------------------------------------------*/ /* xR - A * xS = 0 (KKT.PE) */ double pe_ae_max; /* largest absolute error */ int pe_ae_row; /* number of row with largest absolute error */ double pe_re_max; /* largest relative error */ int pe_re_row; /* number of row with largest relative error */ int pe_quality; /* quality of primal solution: 'H' - high 'M' - medium 'L' - low '?' - primal solution is wrong */ /*--------------------------------------------------------------*/ /* l[k] <= x[k] <= u[k] (KKT.PB) */ double pb_ae_max; /* largest absolute error */ int pb_ae_ind; /* number of variable with largest absolute error */ double pb_re_max; /* largest relative error */ int pb_re_ind; /* number of variable with largest relative error */ int pb_quality; /* quality of primal feasibility: 'H' - high 'M' - medium 'L' - low '?' - primal solution is infeasible */ /*--------------------------------------------------------------*/ /* A' * (dR - cR) + (dS - cS) = 0 (KKT.DE) */ double de_ae_max; /* largest absolute error */ int de_ae_col; /* number of column with largest absolute error */ double de_re_max; /* largest relative error */ int de_re_col; /* number of column with largest relative error */ int de_quality; /* quality of dual solution: 'H' - high 'M' - medium 'L' - low '?' - dual solution is wrong */ /*--------------------------------------------------------------*/ /* d[k] >= 0 or d[k] <= 0 (KKT.DB) */ double db_ae_max; /* largest absolute error */ int db_ae_ind; /* number of variable with largest absolute error */ double db_re_max; /* largest relative error */ int db_re_ind; /* number of variable with largest relative error */ int db_quality; /* quality of dual feasibility: 'H' - high 'M' - medium 'L' - low '?' - dual solution is infeasible */ /*--------------------------------------------------------------*/ /* (x[k] - bound of x[k]) * d[k] = 0 (KKT.CS) */ double cs_ae_max; /* largest absolute error */ int cs_ae_ind; /* number of variable with largest absolute error */ double cs_re_max; /* largest relative error */ int cs_re_ind; /* number of variable with largest relative error */ int cs_quality; /* quality of complementary slackness: 'H' - high 'M' - medium 'L' - low '?' - primal and dual solutions are not complementary */ } LPXKKT; #define lpx_create_prob _glp_lpx_create_prob LPX *lpx_create_prob(void); /* create problem object */ #define lpx_set_prob_name _glp_lpx_set_prob_name void lpx_set_prob_name(LPX *lp, const char *name); /* assign (change) problem name */ #define lpx_set_obj_name _glp_lpx_set_obj_name void lpx_set_obj_name(LPX *lp, const char *name); /* assign (change) objective function name */ #define lpx_set_obj_dir _glp_lpx_set_obj_dir void lpx_set_obj_dir(LPX *lp, int dir); /* set (change) optimization direction flag */ #define lpx_add_rows _glp_lpx_add_rows int lpx_add_rows(LPX *lp, int nrs); /* add new rows to problem object */ #define lpx_add_cols _glp_lpx_add_cols int lpx_add_cols(LPX *lp, int ncs); /* add new columns to problem object */ #define lpx_set_row_name _glp_lpx_set_row_name void lpx_set_row_name(LPX *lp, int i, const char *name); /* assign (change) row name */ #define lpx_set_col_name _glp_lpx_set_col_name void lpx_set_col_name(LPX *lp, int j, const char *name); /* assign (change) column name */ #define lpx_set_row_bnds _glp_lpx_set_row_bnds void lpx_set_row_bnds(LPX *lp, int i, int type, double lb, double ub); /* set (change) row bounds */ #define lpx_set_col_bnds _glp_lpx_set_col_bnds void lpx_set_col_bnds(LPX *lp, int j, int type, double lb, double ub); /* set (change) column bounds */ #define lpx_set_obj_coef _glp_lpx_set_obj_coef void lpx_set_obj_coef(glp_prob *lp, int j, double coef); /* set (change) obj. coefficient or constant term */ #define lpx_set_mat_row _glp_lpx_set_mat_row void lpx_set_mat_row(LPX *lp, int i, int len, const int ind[], const double val[]); /* set (replace) row of the constraint matrix */ #define lpx_set_mat_col _glp_lpx_set_mat_col void lpx_set_mat_col(LPX *lp, int j, int len, const int ind[], const double val[]); /* set (replace) column of the constraint matrix */ #define lpx_load_matrix _glp_lpx_load_matrix void lpx_load_matrix(LPX *lp, int ne, const int ia[], const int ja[], const double ar[]); /* load (replace) the whole constraint matrix */ #define lpx_del_rows _glp_lpx_del_rows void lpx_del_rows(LPX *lp, int nrs, const int num[]); /* delete specified rows from problem object */ #define lpx_del_cols _glp_lpx_del_cols void lpx_del_cols(LPX *lp, int ncs, const int num[]); /* delete specified columns from problem object */ #define lpx_delete_prob _glp_lpx_delete_prob void lpx_delete_prob(LPX *lp); /* delete problem object */ #define lpx_get_prob_name _glp_lpx_get_prob_name const char *lpx_get_prob_name(LPX *lp); /* retrieve problem name */ #define lpx_get_obj_name _glp_lpx_get_obj_name const char *lpx_get_obj_name(LPX *lp); /* retrieve objective function name */ #define lpx_get_obj_dir _glp_lpx_get_obj_dir int lpx_get_obj_dir(LPX *lp); /* retrieve optimization direction flag */ #define lpx_get_num_rows _glp_lpx_get_num_rows int lpx_get_num_rows(LPX *lp); /* retrieve number of rows */ #define lpx_get_num_cols _glp_lpx_get_num_cols int lpx_get_num_cols(LPX *lp); /* retrieve number of columns */ #define lpx_get_row_name _glp_lpx_get_row_name const char *lpx_get_row_name(LPX *lp, int i); /* retrieve row name */ #define lpx_get_col_name _glp_lpx_get_col_name const char *lpx_get_col_name(LPX *lp, int j); /* retrieve column name */ #define lpx_get_row_type _glp_lpx_get_row_type int lpx_get_row_type(LPX *lp, int i); /* retrieve row type */ #define lpx_get_row_lb _glp_lpx_get_row_lb double lpx_get_row_lb(LPX *lp, int i); /* retrieve row lower bound */ #define lpx_get_row_ub _glp_lpx_get_row_ub double lpx_get_row_ub(LPX *lp, int i); /* retrieve row upper bound */ #define lpx_get_row_bnds _glp_lpx_get_row_bnds void lpx_get_row_bnds(LPX *lp, int i, int *typx, double *lb, double *ub); /* retrieve row bounds */ #define lpx_get_col_type _glp_lpx_get_col_type int lpx_get_col_type(LPX *lp, int j); /* retrieve column type */ #define lpx_get_col_lb _glp_lpx_get_col_lb double lpx_get_col_lb(LPX *lp, int j); /* retrieve column lower bound */ #define lpx_get_col_ub _glp_lpx_get_col_ub double lpx_get_col_ub(LPX *lp, int j); /* retrieve column upper bound */ #define lpx_get_col_bnds _glp_lpx_get_col_bnds void lpx_get_col_bnds(LPX *lp, int j, int *typx, double *lb, double *ub); /* retrieve column bounds */ #define lpx_get_obj_coef _glp_lpx_get_obj_coef double lpx_get_obj_coef(LPX *lp, int j); /* retrieve obj. coefficient or constant term */ #define lpx_get_num_nz _glp_lpx_get_num_nz int lpx_get_num_nz(LPX *lp); /* retrieve number of constraint coefficients */ #define lpx_get_mat_row _glp_lpx_get_mat_row int lpx_get_mat_row(LPX *lp, int i, int ind[], double val[]); /* retrieve row of the constraint matrix */ #define lpx_get_mat_col _glp_lpx_get_mat_col int lpx_get_mat_col(LPX *lp, int j, int ind[], double val[]); /* retrieve column of the constraint matrix */ #define lpx_create_index _glp_lpx_create_index void lpx_create_index(LPX *lp); /* create the name index */ #define lpx_find_row _glp_lpx_find_row int lpx_find_row(LPX *lp, const char *name); /* find row by its name */ #define lpx_find_col _glp_lpx_find_col int lpx_find_col(LPX *lp, const char *name); /* find column by its name */ #define lpx_delete_index _glp_lpx_delete_index void lpx_delete_index(LPX *lp); /* delete the name index */ #define lpx_scale_prob _glp_lpx_scale_prob void lpx_scale_prob(LPX *lp); /* scale problem data */ #define lpx_unscale_prob _glp_lpx_unscale_prob void lpx_unscale_prob(LPX *lp); /* unscale problem data */ #define lpx_set_row_stat _glp_lpx_set_row_stat void lpx_set_row_stat(LPX *lp, int i, int stat); /* set (change) row status */ #define lpx_set_col_stat _glp_lpx_set_col_stat void lpx_set_col_stat(LPX *lp, int j, int stat); /* set (change) column status */ #define lpx_std_basis _glp_lpx_std_basis void lpx_std_basis(LPX *lp); /* construct standard initial LP basis */ #define lpx_adv_basis _glp_lpx_adv_basis void lpx_adv_basis(LPX *lp); /* construct advanced initial LP basis */ #define lpx_cpx_basis _glp_lpx_cpx_basis void lpx_cpx_basis(LPX *lp); /* construct Bixby's initial LP basis */ #define lpx_simplex _glp_lpx_simplex int lpx_simplex(LPX *lp); /* easy-to-use driver to the simplex method */ #define lpx_exact _glp_lpx_exact int lpx_exact(LPX *lp); /* easy-to-use driver to the exact simplex method */ #define lpx_get_status _glp_lpx_get_status int lpx_get_status(LPX *lp); /* retrieve generic status of basic solution */ #define lpx_get_prim_stat _glp_lpx_get_prim_stat int lpx_get_prim_stat(LPX *lp); /* retrieve primal status of basic solution */ #define lpx_get_dual_stat _glp_lpx_get_dual_stat int lpx_get_dual_stat(LPX *lp); /* retrieve dual status of basic solution */ #define lpx_get_obj_val _glp_lpx_get_obj_val double lpx_get_obj_val(LPX *lp); /* retrieve objective value (basic solution) */ #define lpx_get_row_stat _glp_lpx_get_row_stat int lpx_get_row_stat(LPX *lp, int i); /* retrieve row status (basic solution) */ #define lpx_get_row_prim _glp_lpx_get_row_prim double lpx_get_row_prim(LPX *lp, int i); /* retrieve row primal value (basic solution) */ #define lpx_get_row_dual _glp_lpx_get_row_dual double lpx_get_row_dual(LPX *lp, int i); /* retrieve row dual value (basic solution) */ #define lpx_get_row_info _glp_lpx_get_row_info void lpx_get_row_info(LPX *lp, int i, int *tagx, double *vx, double *dx); /* obtain row solution information */ #define lpx_get_col_stat _glp_lpx_get_col_stat int lpx_get_col_stat(LPX *lp, int j); /* retrieve column status (basic solution) */ #define lpx_get_col_prim _glp_lpx_get_col_prim double lpx_get_col_prim(LPX *lp, int j); /* retrieve column primal value (basic solution) */ #define lpx_get_col_dual _glp_lpx_get_col_dual double lpx_get_col_dual(glp_prob *lp, int j); /* retrieve column dual value (basic solution) */ #define lpx_get_col_info _glp_lpx_get_col_info void lpx_get_col_info(LPX *lp, int j, int *tagx, double *vx, double *dx); /* obtain column solution information (obsolete) */ #define lpx_get_ray_info _glp_lpx_get_ray_info int lpx_get_ray_info(LPX *lp); /* determine what causes primal unboundness */ #define lpx_check_kkt _glp_lpx_check_kkt void lpx_check_kkt(LPX *lp, int scaled, LPXKKT *kkt); /* check Karush-Kuhn-Tucker conditions */ #define lpx_warm_up _glp_lpx_warm_up int lpx_warm_up(LPX *lp); /* "warm up" LP basis */ #define lpx_eval_tab_row _glp_lpx_eval_tab_row int lpx_eval_tab_row(LPX *lp, int k, int ind[], double val[]); /* compute row of the simplex table */ #define lpx_eval_tab_col _glp_lpx_eval_tab_col int lpx_eval_tab_col(LPX *lp, int k, int ind[], double val[]); /* compute column of the simplex table */ #define lpx_transform_row _glp_lpx_transform_row int lpx_transform_row(LPX *lp, int len, int ind[], double val[]); /* transform explicitly specified row */ #define lpx_transform_col _glp_lpx_transform_col int lpx_transform_col(LPX *lp, int len, int ind[], double val[]); /* transform explicitly specified column */ #define lpx_prim_ratio_test _glp_lpx_prim_ratio_test int lpx_prim_ratio_test(LPX *lp, int len, const int ind[], const double val[], int how, double tol); /* perform primal ratio test */ #define lpx_dual_ratio_test _glp_lpx_dual_ratio_test int lpx_dual_ratio_test(LPX *lp, int len, const int ind[], const double val[], int how, double tol); /* perform dual ratio test */ #define lpx_interior _glp_lpx_interior int lpx_interior(LPX *lp); /* easy-to-use driver to the interior point method */ #define lpx_ipt_status _glp_lpx_ipt_status int lpx_ipt_status(LPX *lp); /* retrieve status of interior-point solution */ #define lpx_ipt_obj_val _glp_lpx_ipt_obj_val double lpx_ipt_obj_val(LPX *lp); /* retrieve objective value (interior point) */ #define lpx_ipt_row_prim _glp_lpx_ipt_row_prim double lpx_ipt_row_prim(LPX *lp, int i); /* retrieve row primal value (interior point) */ #define lpx_ipt_row_dual _glp_lpx_ipt_row_dual double lpx_ipt_row_dual(LPX *lp, int i); /* retrieve row dual value (interior point) */ #define lpx_ipt_col_prim _glp_lpx_ipt_col_prim double lpx_ipt_col_prim(LPX *lp, int j); /* retrieve column primal value (interior point) */ #define lpx_ipt_col_dual _glp_lpx_ipt_col_dual double lpx_ipt_col_dual(LPX *lp, int j); /* retrieve column dual value (interior point) */ #define lpx_set_class _glp_lpx_set_class void lpx_set_class(LPX *lp, int klass); /* set problem class */ #define lpx_get_class _glp_lpx_get_class int lpx_get_class(LPX *lp); /* determine problem klass */ #define lpx_set_col_kind _glp_lpx_set_col_kind void lpx_set_col_kind(LPX *lp, int j, int kind); /* set (change) column kind */ #define lpx_get_col_kind _glp_lpx_get_col_kind int lpx_get_col_kind(LPX *lp, int j); /* retrieve column kind */ #define lpx_get_num_int _glp_lpx_get_num_int int lpx_get_num_int(LPX *lp); /* retrieve number of integer columns */ #define lpx_get_num_bin _glp_lpx_get_num_bin int lpx_get_num_bin(LPX *lp); /* retrieve number of binary columns */ #define lpx_integer _glp_lpx_integer int lpx_integer(LPX *lp); /* easy-to-use driver to the branch-and-bound method */ #define lpx_intopt _glp_lpx_intopt int lpx_intopt(LPX *lp); /* easy-to-use driver to the branch-and-bound method */ #define lpx_mip_status _glp_lpx_mip_status int lpx_mip_status(LPX *lp); /* retrieve status of MIP solution */ #define lpx_mip_obj_val _glp_lpx_mip_obj_val double lpx_mip_obj_val(LPX *lp); /* retrieve objective value (MIP solution) */ #define lpx_mip_row_val _glp_lpx_mip_row_val double lpx_mip_row_val(LPX *lp, int i); /* retrieve row value (MIP solution) */ #define lpx_mip_col_val _glp_lpx_mip_col_val double lpx_mip_col_val(LPX *lp, int j); /* retrieve column value (MIP solution) */ #define lpx_check_int _glp_lpx_check_int void lpx_check_int(LPX *lp, LPXKKT *kkt); /* check integer feasibility conditions */ #define lpx_reset_parms _glp_lpx_reset_parms void lpx_reset_parms(LPX *lp); /* reset control parameters to default values */ #define lpx_set_int_parm _glp_lpx_set_int_parm void lpx_set_int_parm(LPX *lp, int parm, int val); /* set (change) integer control parameter */ #define lpx_get_int_parm _glp_lpx_get_int_parm int lpx_get_int_parm(LPX *lp, int parm); /* query integer control parameter */ #define lpx_set_real_parm _glp_lpx_set_real_parm void lpx_set_real_parm(LPX *lp, int parm, double val); /* set (change) real control parameter */ #define lpx_get_real_parm _glp_lpx_get_real_parm double lpx_get_real_parm(LPX *lp, int parm); /* query real control parameter */ #define lpx_read_mps _glp_lpx_read_mps LPX *lpx_read_mps(const char *fname); /* read problem data in fixed MPS format */ #define lpx_write_mps _glp_lpx_write_mps int lpx_write_mps(LPX *lp, const char *fname); /* write problem data in fixed MPS format */ #define lpx_read_bas _glp_lpx_read_bas int lpx_read_bas(LPX *lp, const char *fname); /* read LP basis in fixed MPS format */ #define lpx_write_bas _glp_lpx_write_bas int lpx_write_bas(LPX *lp, const char *fname); /* write LP basis in fixed MPS format */ #define lpx_read_freemps _glp_lpx_read_freemps LPX *lpx_read_freemps(const char *fname); /* read problem data in free MPS format */ #define lpx_write_freemps _glp_lpx_write_freemps int lpx_write_freemps(LPX *lp, const char *fname); /* write problem data in free MPS format */ #define lpx_read_cpxlp _glp_lpx_read_cpxlp LPX *lpx_read_cpxlp(const char *fname); /* read problem data in CPLEX LP format */ #define lpx_write_cpxlp _glp_lpx_write_cpxlp int lpx_write_cpxlp(LPX *lp, const char *fname); /* write problem data in CPLEX LP format */ #define lpx_read_model _glp_lpx_read_model LPX *lpx_read_model(const char *model, const char *data, const char *output); /* read LP/MIP model written in GNU MathProg language */ #define lpx_print_prob _glp_lpx_print_prob int lpx_print_prob(LPX *lp, const char *fname); /* write problem data in plain text format */ #define lpx_print_sol _glp_lpx_print_sol int lpx_print_sol(LPX *lp, const char *fname); /* write LP problem solution in printable format */ #define lpx_print_sens_bnds _glp_lpx_print_sens_bnds int lpx_print_sens_bnds(LPX *lp, const char *fname); /* write bounds sensitivity information */ #define lpx_print_ips _glp_lpx_print_ips int lpx_print_ips(LPX *lp, const char *fname); /* write interior point solution in printable format */ #define lpx_print_mip _glp_lpx_print_mip int lpx_print_mip(LPX *lp, const char *fname); /* write MIP problem solution in printable format */ #define lpx_is_b_avail _glp_lpx_is_b_avail int lpx_is_b_avail(LPX *lp); /* check if LP basis is available */ #define lpx_write_pb _glp_lpx_write_pb int lpx_write_pb(LPX *lp, const char *fname, int normalized, int binarize); /* write problem data in (normalized) OPB format */ #define lpx_main _glp_lpx_main int lpx_main(int argc, const char *argv[]); /* stand-alone LP/MIP solver */ #ifdef __cplusplus } #endif #endif /* eof */ praat-6.0.04/external/glpk/glplib.h000066400000000000000000000076511261542461700171320ustar00rootroot00000000000000/* glplib.h (miscellaneous library routines) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPLIB_H #define GLPLIB_H #define bigmul _glp_lib_bigmul void bigmul(int n, int m, unsigned short x[], unsigned short y[]); /* multiply unsigned integer numbers of arbitrary precision */ #define bigdiv _glp_lib_bigdiv void bigdiv(int n, int m, unsigned short x[], unsigned short y[]); /* divide unsigned integer numbers of arbitrary precision */ #ifndef GLP_LONG_DEFINED #define GLP_LONG_DEFINED typedef struct { int lo, hi; } glp_long; /* long integer data type */ #endif typedef struct { glp_long quot, rem; } glp_ldiv; /* result of long integer division */ #define xlset _glp_lib_xlset glp_long xlset(int x); /* expand integer to long integer */ #define xlneg _glp_lib_xlneg glp_long xlneg(glp_long x); /* negate long integer */ #define xladd _glp_lib_xladd glp_long xladd(glp_long x, glp_long y); /* add long integers */ #define xlsub _glp_lib_xlsub glp_long xlsub(glp_long x, glp_long y); /* subtract long integers */ #define xlcmp _glp_lib_xlcmp int xlcmp(glp_long x, glp_long y); /* compare long integers */ #define xlmul _glp_lib_xlmul glp_long xlmul(glp_long x, glp_long y); /* multiply long integers */ #define xldiv _glp_lib_xldiv glp_ldiv xldiv(glp_long x, glp_long y); /* divide long integers */ #define xltod _glp_lib_xltod double xltod(glp_long x); /* convert long integer to double */ #define xltoa _glp_lib_xltoa char *xltoa(glp_long x, char *s); /* convert long integer to character string */ #define str2int _glp_lib_str2int int str2int(const char *str, int *val); /* convert character string to value of int type */ #define str2num _glp_lib_str2num int str2num(const char *str, double *val); /* convert character string to value of double type */ #define strspx _glp_lib_strspx char *strspx(char *str); /* remove all spaces from character string */ #define strtrim _glp_lib_strtrim char *strtrim(char *str); /* remove trailing spaces from character string */ #define strrev _glp_lib_strrev char *strrev(char *s); /* reverse character string */ #define gcd _glp_lib_gcd int gcd(int x, int y); /* find greatest common divisor of two integers */ #define gcdn _glp_lib_gcdn int gcdn(int n, int x[]); /* find greatest common divisor of n integers */ #define lcm _glp_lib_lcm int lcm(int x, int y); /* find least common multiple of two integers */ #define lcmn _glp_lib_lcmn int lcmn(int n, int x[]); /* find least common multiple of n integers */ #define round2n _glp_lib_round2n double round2n(double x); /* round floating-point number to nearest power of two */ #define fp2rat _glp_lib_fp2rat int fp2rat(double x, double eps, double *p, double *q); /* convert floating-point number to rational number */ #define jday _glp_lib_jday int jday(int d, int m, int y); /* convert calendar date to Julian day number */ #define jdate _glp_lib_jdate int jdate(int j, int *d, int *m, int *y); /* convert Julian day number to calendar date */ #endif /* eof */ praat-6.0.04/external/glpk/glplib01.c000066400000000000000000000225771261542461700172720ustar00rootroot00000000000000/* glplib01.c (bignum arithmetic) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpenv.h" #include "glplib.h" /*********************************************************************** * Two routines below are intended to multiply and divide unsigned * integer numbers of arbitrary precision. * * The routines assume that an unsigned integer number is represented in * the positional numeral system with the base 2^16 = 65536, i.e. each * "digit" of the number is in the range [0, 65535] and represented as * a 16-bit value of the unsigned short type. In other words, a number x * has the following representation: * * n-1 * x = sum d[j] * 65536^j, * j=0 * * where n is the number of places (positions), and d[j] is j-th "digit" * of x, 0 <= d[j] <= 65535. ***********************************************************************/ /*********************************************************************** * NAME * * bigmul - multiply unsigned integer numbers of arbitrary precision * * SYNOPSIS * * #include "glplib.h" * void bigmul(int n, int m, unsigned short x[], unsigned short y[]); * * DESCRIPTION * * The routine bigmul multiplies unsigned integer numbers of arbitrary * precision. * * n is the number of digits of multiplicand, n >= 1; * * m is the number of digits of multiplier, m >= 1; * * x is an array containing digits of the multiplicand in elements * x[m], x[m+1], ..., x[n+m-1]. Contents of x[0], x[1], ..., x[m-1] are * ignored on entry. * * y is an array containing digits of the multiplier in elements y[0], * y[1], ..., y[m-1]. * * On exit digits of the product are stored in elements x[0], x[1], ..., * x[n+m-1]. The array y is not changed. */ void bigmul(int n, int m, unsigned short x[], unsigned short y[]) { int i, j; unsigned int t; xassert(n >= 1); xassert(m >= 1); for (j = 0; j < m; j++) x[j] = 0; for (i = 0; i < n; i++) { if (x[i+m]) { t = 0; for (j = 0; j < m; j++) { t += (unsigned int)x[i+m] * (unsigned int)y[j] + (unsigned int)x[i+j]; x[i+j] = (unsigned short)t; t >>= 16; } x[i+m] = (unsigned short)t; } } return; } /*********************************************************************** * NAME * * bigdiv - divide unsigned integer numbers of arbitrary precision * * SYNOPSIS * * #include "glplib.h" * void bigdiv(int n, int m, unsigned short x[], unsigned short y[]); * * DESCRIPTION * * The routine bigdiv divides one unsigned integer number of arbitrary * precision by another with the algorithm described in [1]. * * n is the difference between the number of digits of dividend and the * number of digits of divisor, n >= 0. * * m is the number of digits of divisor, m >= 1. * * x is an array containing digits of the dividend in elements x[0], * x[1], ..., x[n+m-1]. * * y is an array containing digits of the divisor in elements y[0], * y[1], ..., y[m-1]. The highest digit y[m-1] must be non-zero. * * On exit n+1 digits of the quotient are stored in elements x[m], * x[m+1], ..., x[n+m], and m digits of the remainder are stored in * elements x[0], x[1], ..., x[m-1]. The array y is changed but then * restored. * * REFERENCES * * 1. D. Knuth. The Art of Computer Programming. Vol. 2: Seminumerical * Algorithms. Stanford University, 1969. */ void bigdiv(int n, int m, unsigned short x[], unsigned short y[]) { int i, j; unsigned int t; unsigned short d, q, r; xassert(n >= 0); xassert(m >= 1); xassert(y[m-1] != 0); /* special case when divisor has the only digit */ if (m == 1) { d = 0; for (i = n; i >= 0; i--) { t = ((unsigned int)d << 16) + (unsigned int)x[i]; x[i+1] = (unsigned short)(t / y[0]); d = (unsigned short)(t % y[0]); } x[0] = d; goto done; } /* multiply dividend and divisor by a normalizing coefficient in order to provide the condition y[m-1] >= base / 2 */ d = (unsigned short)(0x10000 / ((unsigned int)y[m-1] + 1)); if (d == 1) x[n+m] = 0; else { t = 0; for (i = 0; i < n+m; i++) { t += (unsigned int)x[i] * (unsigned int)d; x[i] = (unsigned short)t; t >>= 16; } x[n+m] = (unsigned short)t; t = 0; for (j = 0; j < m; j++) { t += (unsigned int)y[j] * (unsigned int)d; y[j] = (unsigned short)t; t >>= 16; } } /* main loop */ for (i = n; i >= 0; i--) { /* estimate and correct the current digit of quotient */ if (x[i+m] < y[m-1]) { t = ((unsigned int)x[i+m] << 16) + (unsigned int)x[i+m-1]; q = (unsigned short)(t / (unsigned int)y[m-1]); r = (unsigned short)(t % (unsigned int)y[m-1]); if (q == 0) goto putq; else goto test; } q = 0; r = x[i+m-1]; decr: q--; /* if q = 0 then q-- = 0xFFFF */ t = (unsigned int)r + (unsigned int)y[m-1]; r = (unsigned short)t; if (t > 0xFFFF) goto msub; test: t = (unsigned int)y[m-2] * (unsigned int)q; if ((unsigned short)(t >> 16) > r) goto decr; if ((unsigned short)(t >> 16) < r) goto msub; if ((unsigned short)t > x[i+m-2]) goto decr; msub: /* now subtract divisor multiplied by the current digit of quotient from the current dividend */ if (q == 0) goto putq; t = 0; for (j = 0; j < m; j++) { t += (unsigned int)y[j] * (unsigned int)q; if (x[i+j] < (unsigned short)t) t += 0x10000; x[i+j] -= (unsigned short)t; t >>= 16; } if (x[i+m] >= (unsigned short)t) goto putq; /* perform correcting addition, because the current digit of quotient is greater by one than its correct value */ q--; t = 0; for (j = 0; j < m; j++) { t += (unsigned int)x[i+j] + (unsigned int)y[j]; x[i+j] = (unsigned short)t; t >>= 16; } putq: /* store the current digit of quotient */ x[i+m] = q; } /* divide divisor and remainder by the normalizing coefficient in order to restore their original values */ if (d > 1) { t = 0; for (i = m-1; i >= 0; i--) { t = (t << 16) + (unsigned int)x[i]; x[i] = (unsigned short)(t / (unsigned int)d); t %= (unsigned int)d; } t = 0; for (j = m-1; j >= 0; j--) { t = (t << 16) + (unsigned int)y[j]; y[j] = (unsigned short)(t / (unsigned int)d); t %= (unsigned int)d; } } done: return; } /**********************************************************************/ #if 0 #include #include #include #include "glprng.h" #define N_MAX 7 /* maximal number of digits in multiplicand */ #define M_MAX 5 /* maximal number of digits in multiplier */ #define N_TEST 1000000 /* number of tests */ int main(void) { RNG *rand; int d, j, n, m, test; unsigned short x[N_MAX], y[M_MAX], z[N_MAX+M_MAX]; rand = rng_create_rand(); for (test = 1; test <= N_TEST; test++) { /* x[0,...,n-1] := multiplicand */ n = 1 + rng_unif_rand(rand, N_MAX-1); assert(1 <= n && n <= N_MAX); for (j = 0; j < n; j++) { d = rng_unif_rand(rand, 65536); assert(0 <= d && d <= 65535); x[j] = (unsigned short)d; } /* y[0,...,m-1] := multiplier */ m = 1 + rng_unif_rand(rand, M_MAX-1); assert(1 <= m && m <= M_MAX); for (j = 0; j < m; j++) { d = rng_unif_rand(rand, 65536); assert(0 <= d && d <= 65535); y[j] = (unsigned short)d; } if (y[m-1] == 0) y[m-1] = 1; /* z[0,...,n+m-1] := x * y */ for (j = 0; j < n; j++) z[m+j] = x[j]; bigmul(n, m, z, y); /* z[0,...,m-1] := z mod y, z[m,...,n+m-1] := z div y */ bigdiv(n, m, z, y); /* z mod y must be 0 */ for (j = 0; j < m; j++) assert(z[j] == 0); /* z div y must be x */ for (j = 0; j < n; j++) assert(z[m+j] == x[j]); } fprintf(stderr, "%d tests successfully passed\n", N_TEST); rng_delete_rand(rand); return 0; } #endif /* eof */ praat-6.0.04/external/glpk/glplib02.c000066400000000000000000000210301261542461700172520ustar00rootroot00000000000000/* glplib02.c (64-bit arithmetic) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpenv.h" #include "glplib.h" /*********************************************************************** * NAME * * xlset - expand integer to long integer * * SYNOPSIS * * #include "glplib.h" * glp_long xlset(int x); * * RETURNS * * The routine xlset returns x expanded to long integer. */ glp_long xlset(int x) { glp_long t; t.lo = x, t.hi = (x >= 0 ? 0 : -1); return t; } /*********************************************************************** * NAME * * xlneg - negate long integer * * SYNOPSIS * * #include "glplib.h" * glp_long xlneg(glp_long x); * * RETURNS * * The routine xlneg returns the difference 0 - x. */ glp_long xlneg(glp_long x) { if (x.lo) x.lo = - x.lo, x.hi = ~x.hi; else x.hi = - x.hi; return x; } /*********************************************************************** * NAME * * xladd - add long integers * * SYNOPSIS * * #include "glplib.h" * glp_long xladd(glp_long x, glp_long y); * * RETURNS * * The routine xladd returns the sum x + y. */ glp_long xladd(glp_long x, glp_long y) { if ((unsigned int)x.lo <= 0xFFFFFFFF - (unsigned int)y.lo) x.lo += y.lo, x.hi += y.hi; else x.lo += y.lo, x.hi += y.hi + 1; return x; } /*********************************************************************** * NAME * * xlsub - subtract long integers * * SYNOPSIS * * #include "glplib.h" * glp_long xlsub(glp_long x, glp_long y); * * RETURNS * * The routine xlsub returns the difference x - y. */ glp_long xlsub(glp_long x, glp_long y) { return xladd(x, xlneg(y)); } /*********************************************************************** * NAME * * xlcmp - compare long integers * * SYNOPSIS * * #include "glplib.h" * int xlcmp(glp_long x, glp_long y); * * RETURNS * * The routine xlcmp returns the sign of the difference x - y. */ int xlcmp(glp_long x, glp_long y) { if (x.hi >= 0 && y.hi < 0) return +1; if (x.hi < 0 && y.hi >= 0) return -1; if ((unsigned int)x.hi < (unsigned int)y.hi) return -1; if ((unsigned int)x.hi > (unsigned int)y.hi) return +1; if ((unsigned int)x.lo < (unsigned int)y.lo) return -1; if ((unsigned int)x.lo > (unsigned int)y.lo) return +1; return 0; } /*********************************************************************** * NAME * * xlmul - multiply long integers * * SYNOPSIS * * #include "glplib.h" * glp_long xlmul(glp_long x, glp_long y); * * RETURNS * * The routine xlmul returns the product x * y. */ glp_long xlmul(glp_long x, glp_long y) { unsigned short xx[8], yy[4]; xx[4] = (unsigned short)x.lo; xx[5] = (unsigned short)(x.lo >> 16); xx[6] = (unsigned short)x.hi; xx[7] = (unsigned short)(x.hi >> 16); yy[0] = (unsigned short)y.lo; yy[1] = (unsigned short)(y.lo >> 16); yy[2] = (unsigned short)y.hi; yy[3] = (unsigned short)(y.hi >> 16); bigmul(4, 4, xx, yy); x.lo = (unsigned int)xx[0] | ((unsigned int)xx[1] << 16); x.hi = (unsigned int)xx[2] | ((unsigned int)xx[3] << 16); return x; } /*********************************************************************** * NAME * * xldiv - divide long integers * * SYNOPSIS * * #include "glplib.h" * glp_ldiv xldiv(glp_long x, glp_long y); * * RETURNS * * The routine xldiv returns a structure of type glp_ldiv containing * members quot (the quotient) and rem (the remainder), both of type * glp_long. */ glp_ldiv xldiv(glp_long x, glp_long y) { glp_ldiv t; int m, sx, sy; unsigned short xx[8], yy[4]; /* sx := sign(x) */ sx = (x.hi < 0); /* sy := sign(y) */ sy = (y.hi < 0); /* x := |x| */ if (sx) x = xlneg(x); /* y := |y| */ if (sy) y = xlneg(y); /* compute x div y and x mod y */ xx[0] = (unsigned short)x.lo; xx[1] = (unsigned short)(x.lo >> 16); xx[2] = (unsigned short)x.hi; xx[3] = (unsigned short)(x.hi >> 16); yy[0] = (unsigned short)y.lo; yy[1] = (unsigned short)(y.lo >> 16); yy[2] = (unsigned short)y.hi; yy[3] = (unsigned short)(y.hi >> 16); if (yy[3]) m = 4; else if (yy[2]) m = 3; else if (yy[1]) m = 2; else if (yy[0]) m = 1; else xerror("xldiv: divide by zero\n"); bigdiv(4 - m, m, xx, yy); /* remainder in x[0], x[1], ..., x[m-1] */ t.rem.lo = (unsigned int)xx[0], t.rem.hi = 0; if (m >= 2) t.rem.lo |= (unsigned int)xx[1] << 16; if (m >= 3) t.rem.hi = (unsigned int)xx[2]; if (m >= 4) t.rem.hi |= (unsigned int)xx[3] << 16; if (sx) t.rem = xlneg(t.rem); /* quotient in x[m], x[m+1], ..., x[4] */ t.quot.lo = (unsigned int)xx[m], t.quot.hi = 0; if (m <= 3) t.quot.lo |= (unsigned int)xx[m+1] << 16; if (m <= 2) t.quot.hi = (unsigned int)xx[m+2]; if (m <= 1) t.quot.hi |= (unsigned int)xx[m+3] << 16; if (sx ^ sy) t.quot = xlneg(t.quot); return t; } /*********************************************************************** * NAME * * xltod - convert long integer to double * * SYNOPSIS * * #include "glplib.h" * double xltod(glp_long x); * * RETURNS * * The routine xltod returns x converted to double. */ double xltod(glp_long x) { double s, z; if (x.hi >= 0) s = +1.0; else s = -1.0, x = xlneg(x); if (x.hi >= 0) z = 4294967296.0 * (double)x.hi + (double)(unsigned int)x.lo; else { xassert(x.hi == 0x80000000 && x.lo == 0x00000000); z = 9223372036854775808.0; /* 2^63 */ } return s * z; } char *xltoa(glp_long x, char *s) { /* convert long integer to character string */ static const char *d = "0123456789"; glp_ldiv t; int neg, len; if (x.hi >= 0) neg = 0; else neg = 1, x = xlneg(x); if (x.hi >= 0) { len = 0; while (!(x.hi == 0 && x.lo == 0)) { t = xldiv(x, xlset(10)); xassert(0 <= t.rem.lo && t.rem.lo <= 9); s[len++] = d[t.rem.lo]; x = t.quot; } if (len == 0) s[len++] = d[0]; if (neg) s[len++] = '-'; s[len] = '\0'; strrev(s); } else strcpy(s, "-9223372036854775808"); /* -2^63 */ return s; } /**********************************************************************/ #if 0 #include "glprng.h" #define N_TEST 1000000 /* number of tests */ static glp_long myrand(RNG *rand) { glp_long x; int k; k = rng_unif_rand(rand, 4); xassert(0 <= k && k <= 3); x.lo = rng_unif_rand(rand, 65536); if (k == 1 || k == 3) { x.lo <<= 16; x.lo += rng_unif_rand(rand, 65536); } if (k <= 1) x.hi = 0; else x.hi = rng_unif_rand(rand, 65536); if (k == 3) { x.hi <<= 16; x.hi += rng_unif_rand(rand, 65536); } if (rng_unif_rand(rand, 2)) x = xlneg(x); return x; } int main(void) { RNG *rand; glp_long x, y; glp_ldiv z; int test; rand = rng_create_rand(); for (test = 1; test <= N_TEST; test++) { x = myrand(rand); y = myrand(rand); if (y.lo == 0 && y.hi == 0) y.lo = 1; /* z.quot := x div y, z.rem := x mod y */ z = xldiv(x, y); /* x must be equal to y * z.quot + z.rem */ xassert(xlcmp(x, xladd(xlmul(y, z.quot), z.rem)) == 0); } xprintf("%d tests successfully passed\n", N_TEST); rng_delete_rand(rand); return 0; } #endif /* eof */ praat-6.0.04/external/glpk/glplib03.c000066400000000000000000000433561261542461700172720ustar00rootroot00000000000000/* glplib03.c (miscellaneous library routines) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpenv.h" #include "glplib.h" /*********************************************************************** * NAME * * str2int - convert character string to value of int type * * SYNOPSIS * * #include "glplib.h" * int str2int(const char *str, int *val); * * DESCRIPTION * * The routine str2int converts the character string str to a value of * integer type and stores the value into location, which the parameter * val points to (in the case of error content of this location is not * changed). * * RETURNS * * The routine returns one of the following error codes: * * 0 - no error; * 1 - value out of range; * 2 - character string is syntactically incorrect. */ int str2int(const char *str, int *_val) { int d, k, s, val = 0; /* scan optional sign */ if (str[0] == '+') s = +1, k = 1; else if (str[0] == '-') s = -1, k = 1; else s = +1, k = 0; /* check for the first digit */ if (!isdigit((unsigned char)str[k])) return 2; /* scan digits */ while (isdigit((unsigned char)str[k])) { d = str[k++] - '0'; if (s > 0) { if (val > INT_MAX / 10) return 1; val *= 10; if (val > INT_MAX - d) return 1; val += d; } else { if (val < INT_MIN / 10) return 1; val *= 10; if (val < INT_MIN + d) return 1; val -= d; } } /* check for terminator */ if (str[k] != '\0') return 2; /* conversion has been done */ *_val = val; return 0; } /*********************************************************************** * NAME * * str2num - convert character string to value of double type * * SYNOPSIS * * #include "glplib.h" * int str2num(const char *str, double *val); * * DESCRIPTION * * The routine str2num converts the character string str to a value of * double type and stores the value into location, which the parameter * val points to (in the case of error content of this location is not * changed). * * RETURNS * * The routine returns one of the following error codes: * * 0 - no error; * 1 - value out of range; * 2 - character string is syntactically incorrect. */ int str2num(const char *str, double *_val) { int k; double val; /* scan optional sign */ k = (str[0] == '+' || str[0] == '-' ? 1 : 0); /* check for decimal point */ if (str[k] == '.') { k++; /* a digit should follow it */ if (!isdigit((unsigned char)str[k])) return 2; k++; goto frac; } /* integer part should start with a digit */ if (!isdigit((unsigned char)str[k])) return 2; /* scan integer part */ while (isdigit((unsigned char)str[k])) k++; /* check for decimal point */ if (str[k] == '.') k++; frac: /* scan optional fraction part */ while (isdigit((unsigned char)str[k])) k++; /* check for decimal exponent */ if (str[k] == 'E' || str[k] == 'e') { k++; /* scan optional sign */ if (str[k] == '+' || str[k] == '-') k++; /* a digit should follow E, E+ or E- */ if (!isdigit((unsigned char)str[k])) return 2; } /* scan optional exponent part */ while (isdigit((unsigned char)str[k])) k++; /* check for terminator */ if (str[k] != '\0') return 2; /* perform conversion */ { char *endptr; val = strtod(str, &endptr); if (*endptr != '\0') return 2; } /* check for overflow */ if (!(-DBL_MAX <= val && val <= +DBL_MAX)) return 1; /* check for underflow */ if (-DBL_MIN < val && val < +DBL_MIN) val = 0.0; /* conversion has been done */ *_val = val; return 0; } /*********************************************************************** * NAME * * strspx - remove all spaces from character string * * SYNOPSIS * * #include "glplib.h" * char *strspx(char *str); * * DESCRIPTION * * The routine strspx removes all spaces from the character string str. * * RETURNS * * The routine returns a pointer to the character string. * * EXAMPLES * * strspx(" Errare humanum est ") => "Errarehumanumest" * * strspx(" ") => "" */ char *strspx(char *str) { char *s, *t; for (s = t = str; *s; s++) if (*s != ' ') *t++ = *s; *t = '\0'; return str; } /*********************************************************************** * NAME * * strtrim - remove trailing spaces from character string * * SYNOPSIS * * #include "glplib.h" * char *strtrim(char *str); * * DESCRIPTION * * The routine strtrim removes trailing spaces from the character * string str. * * RETURNS * * The routine returns a pointer to the character string. * * EXAMPLES * * strtrim("Errare humanum est ") => "Errare humanum est" * * strtrim(" ") => "" */ char *strtrim(char *str) { char *t; for (t = strrchr(str, '\0') - 1; t >= str; t--) { if (*t != ' ') break; *t = '\0'; } return str; } /*********************************************************************** * NAME * * strrev - reverse character string * * SYNOPSIS * * #include "glplib.h" * char *strrev(char *s); * * DESCRIPTION * * The routine strrev changes characters in a character string s to the * reverse order, except the terminating null character. * * RETURNS * * The routine returns the pointer s. * * EXAMPLES * * strrev("") => "" * * strrev("Today is Monday") => "yadnoM si yadoT" */ char *strrev(char *s) { int i, j; char t; for (i = 0, j = strlen(s)-1; i < j; i++, j--) t = s[i], s[i] = s[j], s[j] = t; return s; } /*********************************************************************** * NAME * * gcd - find greatest common divisor of two integers * * SYNOPSIS * * #include "glplib.h" * int gcd(int x, int y); * * RETURNS * * The routine gcd returns gcd(x, y), the greatest common divisor of * the two positive integers given. * * ALGORITHM * * The routine gcd is based on Euclid's algorithm. * * REFERENCES * * Don Knuth, The Art of Computer Programming, Vol.2: Seminumerical * Algorithms, 3rd Edition, Addison-Wesley, 1997. Section 4.5.2: The * Greatest Common Divisor, pp. 333-56. */ int gcd(int x, int y) { int r; xassert(x > 0 && y > 0); while (y > 0) r = x % y, x = y, y = r; return x; } /*********************************************************************** * NAME * * gcdn - find greatest common divisor of n integers * * SYNOPSIS * * #include "glplib.h" * int gcdn(int n, int x[]); * * RETURNS * * The routine gcdn returns gcd(x[1], x[2], ..., x[n]), the greatest * common divisor of n positive integers given, n > 0. * * BACKGROUND * * The routine gcdn is based on the following identity: * * gcd(x, y, z) = gcd(gcd(x, y), z). * * REFERENCES * * Don Knuth, The Art of Computer Programming, Vol.2: Seminumerical * Algorithms, 3rd Edition, Addison-Wesley, 1997. Section 4.5.2: The * Greatest Common Divisor, pp. 333-56. */ int gcdn(int n, int x[]) { int d, j; xassert(n > 0); for (j = 1; j <= n; j++) { xassert(x[j] > 0); if (j == 1) d = x[1]; else d = gcd(d, x[j]); if (d == 1) break; } return d; } /*********************************************************************** * NAME * * lcm - find least common multiple of two integers * * SYNOPSIS * * #include "glplib.h" * int lcm(int x, int y); * * RETURNS * * The routine lcm returns lcm(x, y), the least common multiple of the * two positive integers given. In case of integer overflow the routine * returns zero. * * BACKGROUND * * The routine lcm is based on the following identity: * * lcm(x, y) = (x * y) / gcd(x, y) = x * [y / gcd(x, y)], * * where gcd(x, y) is the greatest common divisor of x and y. */ int lcm(int x, int y) { xassert(x > 0); xassert(y > 0); y /= gcd(x, y); if (x > INT_MAX / y) return 0; return x * y; } /*********************************************************************** * NAME * * lcmn - find least common multiple of n integers * * SYNOPSIS * * #include "glplib.h" * int lcmn(int n, int x[]); * * RETURNS * * The routine lcmn returns lcm(x[1], x[2], ..., x[n]), the least * common multiple of n positive integers given, n > 0. In case of * integer overflow the routine returns zero. * * BACKGROUND * * The routine lcmn is based on the following identity: * * lcmn(x, y, z) = lcm(lcm(x, y), z), * * where lcm(x, y) is the least common multiple of x and y. */ int lcmn(int n, int x[]) { int m, j; xassert(n > 0); for (j = 1; j <= n; j++) { xassert(x[j] > 0); if (j == 1) m = x[1]; else m = lcm(m, x[j]); if (m == 0) break; } return m; } /*********************************************************************** * NAME * * round2n - round floating-point number to nearest power of two * * SYNOPSIS * * #include "glplib.h" * double round2n(double x); * * RETURNS * * Given a positive floating-point value x the routine round2n returns * 2^n such that |x - 2^n| is minimal. * * EXAMPLES * * round2n(10.1) = 2^3 = 8 * round2n(15.3) = 2^4 = 16 * round2n(0.01) = 2^(-7) = 0.0078125 * * BACKGROUND * * Let x = f * 2^e, where 0.5 <= f < 1 is a normalized fractional part, * e is an integer exponent. Then, obviously, 0.5 * 2^e <= x < 2^e, so * if x - 0.5 * 2^e <= 2^e - x, we choose 0.5 * 2^e = 2^(e-1), and 2^e * otherwise. The latter condition can be written as 2 * x <= 1.5 * 2^e * or 2 * f * 2^e <= 1.5 * 2^e or, finally, f <= 0.75. */ double round2n(double x) { int e; double f; xassert(x > 0.0); f = frexp(x, &e); return ldexp(1.0, f <= 0.75 ? e-1 : e); } /*********************************************************************** * NAME * * fp2rat - convert floating-point number to rational number * * SYNOPSIS * * #include "glplib.h" * int fp2rat(double x, double eps, double *p, double *q); * * DESCRIPTION * * Given a floating-point number 0 <= x < 1 the routine fp2rat finds * its "best" rational approximation p / q, where p >= 0 and q > 0 are * integer numbers, such that |x - p / q| <= eps. * * RETURNS * * The routine fp2rat returns the number of iterations used to achieve * the specified precision eps. * * EXAMPLES * * For x = sqrt(2) - 1 = 0.414213562373095 and eps = 1e-6 the routine * gives p = 408 and q = 985, where 408 / 985 = 0.414213197969543. * * BACKGROUND * * It is well known that every positive real number x can be expressed * as the following continued fraction: * * x = b[0] + a[1] * ------------------------ * b[1] + a[2] * ----------------- * b[2] + a[3] * ---------- * b[3] + ... * * where: * * a[k] = 1, k = 0, 1, 2, ... * * b[k] = floor(x[k]), k = 0, 1, 2, ... * * x[0] = x, * * x[k] = 1 / frac(x[k-1]), k = 1, 2, 3, ... * * To find the "best" rational approximation of x the routine computes * partial fractions f[k] by dropping after k terms as follows: * * f[k] = A[k] / B[k], * * where: * * A[-1] = 1, A[0] = b[0], B[-1] = 0, B[0] = 1, * * A[k] = b[k] * A[k-1] + a[k] * A[k-2], * * B[k] = b[k] * B[k-1] + a[k] * B[k-2]. * * Once the condition * * |x - f[k]| <= eps * * has been satisfied, the routine reports p = A[k] and q = B[k] as the * final answer. * * In the table below here is some statistics obtained for one million * random numbers uniformly distributed in the range [0, 1). * * eps max p mean p max q mean q max k mean k * ------------------------------------------------------------- * 1e-1 8 1.6 9 3.2 3 1.4 * 1e-2 98 6.2 99 12.4 5 2.4 * 1e-3 997 20.7 998 41.5 8 3.4 * 1e-4 9959 66.6 9960 133.5 10 4.4 * 1e-5 97403 211.7 97404 424.2 13 5.3 * 1e-6 479669 669.9 479670 1342.9 15 6.3 * 1e-7 1579030 2127.3 3962146 4257.8 16 7.3 * 1e-8 26188823 6749.4 26188824 13503.4 19 8.2 * * REFERENCES * * W. B. Jones and W. J. Thron, "Continued Fractions: Analytic Theory * and Applications," Encyclopedia on Mathematics and Its Applications, * Addison-Wesley, 1980. */ int fp2rat(double x, double eps, double *p, double *q) { int k; double xk, Akm1, Ak, Bkm1, Bk, ak, bk, fk, temp; if (!(0.0 <= x && x < 1.0)) xerror("fp2rat: x = %g; number out of range\n", x); for (k = 0; ; k++) { xassert(k <= 100); if (k == 0) { /* x[0] = x */ xk = x; /* A[-1] = 1 */ Akm1 = 1.0; /* A[0] = b[0] = floor(x[0]) = 0 */ Ak = 0.0; /* B[-1] = 0 */ Bkm1 = 0.0; /* B[0] = 1 */ Bk = 1.0; } else { /* x[k] = 1 / frac(x[k-1]) */ temp = xk - floor(xk); xassert(temp != 0.0); xk = 1.0 / temp; /* a[k] = 1 */ ak = 1.0; /* b[k] = floor(x[k]) */ bk = floor(xk); /* A[k] = b[k] * A[k-1] + a[k] * A[k-2] */ temp = bk * Ak + ak * Akm1; Akm1 = Ak, Ak = temp; /* B[k] = b[k] * B[k-1] + a[k] * B[k-2] */ temp = bk * Bk + ak * Bkm1; Bkm1 = Bk, Bk = temp; } /* f[k] = A[k] / B[k] */ fk = Ak / Bk; #if 0 print("%.*g / %.*g = %.*g", DBL_DIG, Ak, DBL_DIG, Bk, DBL_DIG, fk); #endif if (fabs(x - fk) <= eps) break; } *p = Ak; *q = Bk; return k; } /*********************************************************************** * NAME * * jday - convert calendar date to Julian day number * * SYNOPSIS * * #include "glplib.h" * int jday(int d, int m, int y); * * DESCRIPTION * * The routine jday converts a calendar date, Gregorian calendar, to * corresponding Julian day number j. * * From the given day d, month m, and year y, the Julian day number j * is computed without using tables. * * The routine is valid for 1 <= y <= 4000. * * RETURNS * * The routine jday returns the Julian day number, or negative value if * the specified date is incorrect. * * REFERENCES * * R. G. Tantzen, Algorithm 199: conversions between calendar date and * Julian day number, Communications of the ACM, vol. 6, no. 8, p. 444, * Aug. 1963. */ int jday(int d, int m, int y) { int c, ya, j, dd; if (!(1 <= d && d <= 31 && 1 <= m && m <= 12 && 1 <= y && y <= 4000)) { j = -1; goto done; } if (m >= 3) m -= 3; else m += 9, y--; c = y / 100; ya = y - 100 * c; j = (146097 * c) / 4 + (1461 * ya) / 4 + (153 * m + 2) / 5 + d + 1721119; jdate(j, &dd, NULL, NULL); if (d != dd) j = -1; done: return j; } /*********************************************************************** * NAME * * jdate - convert Julian day number to calendar date * * SYNOPSIS * * #include "glplib.h" * void jdate(int j, int *d, int *m, int *y); * * DESCRIPTION * * The routine jdate converts a Julian day number j to corresponding * calendar date, Gregorian calendar. * * The day d, month m, and year y are computed without using tables and * stored in corresponding locations. * * The routine is valid for 1721426 <= j <= 3182395. * * RETURNS * * If the conversion is successful, the routine returns zero, otherwise * non-zero. * * REFERENCES * * R. G. Tantzen, Algorithm 199: conversions between calendar date and * Julian day number, Communications of the ACM, vol. 6, no. 8, p. 444, * Aug. 1963. */ int jdate(int j, int *_d, int *_m, int *_y) { int d, m, y, ret = 0; if (!(1721426 <= j && j <= 3182395)) { ret = 1; goto done; } j -= 1721119; y = (4 * j - 1) / 146097; j = (4 * j - 1) % 146097; d = j / 4; j = (4 * d + 3) / 1461; d = (4 * d + 3) % 1461; d = (d + 4) / 4; m = (5 * d - 3) / 153; d = (5 * d - 3) % 153; d = (d + 5) / 5; y = 100 * y + j; if (m <= 9) m += 3; else m -= 9, y++; if (_d != NULL) *_d = d; if (_m != NULL) *_m = m; if (_y != NULL) *_y = y; done: return ret; } #if 0 int main(void) { int jbeg, jend, j, d, m, y; jbeg = jday(1, 1, 1); jend = jday(31, 12, 4000); for (j = jbeg; j <= jend; j++) { xassert(jdate(j, &d, &m, &y) == 0); xassert(jday(d, m, y) == j); } xprintf("Routines jday and jdate work correctly.\n"); return 0; } #endif /* eof */ praat-6.0.04/external/glpk/glplpf.c000066400000000000000000000753301261542461700171370ustar00rootroot00000000000000/* glplpf.c (LP basis factorization, Schur complement version) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glplpf.h" #include "glpenv.h" #define xfault xerror #define _GLPLPF_DEBUG 0 /* CAUTION: DO NOT CHANGE THE LIMIT BELOW */ #define M_MAX 100000000 /* = 100*10^6 */ /* maximal order of the basis matrix */ /*********************************************************************** * NAME * * lpf_create_it - create LP basis factorization * * SYNOPSIS * * #include "glplpf.h" * LPF *lpf_create_it(void); * * DESCRIPTION * * The routine lpf_create_it creates a program object, which represents * a factorization of LP basis. * * RETURNS * * The routine lpf_create_it returns a pointer to the object created. */ LPF *lpf_create_it(void) { LPF *lpf; #if _GLPLPF_DEBUG xprintf("lpf_create_it: warning: debug mode enabled\n"); #endif lpf = xmalloc(sizeof(LPF)); lpf->valid = 0; lpf->m0_max = lpf->m0 = 0; lpf->luf = luf_create_it(); lpf->m = 0; lpf->B = NULL; lpf->n_max = 50; lpf->n = 0; lpf->R_ptr = lpf->R_len = NULL; lpf->S_ptr = lpf->S_len = NULL; lpf->scf = NULL; lpf->P_row = lpf->P_col = NULL; lpf->Q_row = lpf->Q_col = NULL; lpf->v_size = 1000; lpf->v_ptr = 0; lpf->v_ind = NULL; lpf->v_val = NULL; lpf->work1 = lpf->work2 = NULL; return lpf; } /*********************************************************************** * NAME * * lpf_factorize - compute LP basis factorization * * SYNOPSIS * * #include "glplpf.h" * int lpf_factorize(LPF *lpf, int m, const int bh[], int (*col) * (void *info, int j, int ind[], double val[]), void *info); * * DESCRIPTION * * The routine lpf_factorize computes the factorization of the basis * matrix B specified by the routine col. * * The parameter lpf specified the basis factorization data structure * created with the routine lpf_create_it. * * The parameter m specifies the order of B, m > 0. * * The array bh specifies the basis header: bh[j], 1 <= j <= m, is the * number of j-th column of B in some original matrix. The array bh is * optional and can be specified as NULL. * * The formal routine col specifies the matrix B to be factorized. To * obtain j-th column of A the routine lpf_factorize calls the routine * col with the parameter j (1 <= j <= n). In response the routine col * should store row indices and numerical values of non-zero elements * of j-th column of B to locations ind[1,...,len] and val[1,...,len], * respectively, where len is the number of non-zeros in j-th column * returned on exit. Neither zero nor duplicate elements are allowed. * * The parameter info is a transit pointer passed to the routine col. * * RETURNS * * 0 The factorization has been successfully computed. * * LPF_ESING * The specified matrix is singular within the working precision. * * LPF_ECOND * The specified matrix is ill-conditioned. * * For more details see comments to the routine luf_factorize. */ int lpf_factorize(LPF *lpf, int m, const int bh[], int (*col) (void *info, int j, int ind[], double val[]), void *info) { int k, ret; #if _GLPLPF_DEBUG int i, j, len, *ind; double *B, *val; #endif xassert(bh == bh); if (m < 1) xfault("lpf_factorize: m = %d; invalid parameter\n", m); if (m > M_MAX) xfault("lpf_factorize: m = %d; matrix too big\n", m); lpf->m0 = lpf->m = m; /* invalidate the factorization */ lpf->valid = 0; /* allocate/reallocate arrays, if necessary */ if (lpf->R_ptr == NULL) lpf->R_ptr = xcalloc(1+lpf->n_max, sizeof(int)); if (lpf->R_len == NULL) lpf->R_len = xcalloc(1+lpf->n_max, sizeof(int)); if (lpf->S_ptr == NULL) lpf->S_ptr = xcalloc(1+lpf->n_max, sizeof(int)); if (lpf->S_len == NULL) lpf->S_len = xcalloc(1+lpf->n_max, sizeof(int)); if (lpf->scf == NULL) lpf->scf = scf_create_it(lpf->n_max); if (lpf->v_ind == NULL) lpf->v_ind = xcalloc(1+lpf->v_size, sizeof(int)); if (lpf->v_val == NULL) lpf->v_val = xcalloc(1+lpf->v_size, sizeof(double)); if (lpf->m0_max < m) { if (lpf->P_row != NULL) xfree(lpf->P_row); if (lpf->P_col != NULL) xfree(lpf->P_col); if (lpf->Q_row != NULL) xfree(lpf->Q_row); if (lpf->Q_col != NULL) xfree(lpf->Q_col); if (lpf->work1 != NULL) xfree(lpf->work1); if (lpf->work2 != NULL) xfree(lpf->work2); lpf->m0_max = m + 100; lpf->P_row = xcalloc(1+lpf->m0_max+lpf->n_max, sizeof(int)); lpf->P_col = xcalloc(1+lpf->m0_max+lpf->n_max, sizeof(int)); lpf->Q_row = xcalloc(1+lpf->m0_max+lpf->n_max, sizeof(int)); lpf->Q_col = xcalloc(1+lpf->m0_max+lpf->n_max, sizeof(int)); lpf->work1 = xcalloc(1+lpf->m0_max+lpf->n_max, sizeof(double)); lpf->work2 = xcalloc(1+lpf->m0_max+lpf->n_max, sizeof(double)); } /* try to factorize the basis matrix */ switch (luf_factorize(lpf->luf, m, col, info)) { case 0: break; case LUF_ESING: ret = LPF_ESING; goto done; case LUF_ECOND: ret = LPF_ECOND; goto done; default: xassert(lpf != lpf); } /* the basis matrix has been successfully factorized */ lpf->valid = 1; #if _GLPLPF_DEBUG /* store the basis matrix for debugging */ if (lpf->B != NULL) xfree(lpf->B); xassert(m <= 32767); lpf->B = B = xcalloc(1+m*m, sizeof(double)); ind = xcalloc(1+m, sizeof(int)); val = xcalloc(1+m, sizeof(double)); for (k = 1; k <= m * m; k++) B[k] = 0.0; for (j = 1; j <= m; j++) { len = col(info, j, ind, val); xassert(0 <= len && len <= m); for (k = 1; k <= len; k++) { i = ind[k]; xassert(1 <= i && i <= m); xassert(B[(i - 1) * m + j] == 0.0); xassert(val[k] != 0.0); B[(i - 1) * m + j] = val[k]; } } xfree(ind); xfree(val); #endif /* B = B0, so there are no additional rows/columns */ lpf->n = 0; /* reset the Schur complement factorization */ scf_reset_it(lpf->scf); /* P := Q := I */ for (k = 1; k <= m; k++) { lpf->P_row[k] = lpf->P_col[k] = k; lpf->Q_row[k] = lpf->Q_col[k] = k; } /* make all SVA locations free */ lpf->v_ptr = 1; ret = 0; done: /* return to the calling program */ return ret; } /*********************************************************************** * The routine r_prod computes the product y := y + alpha * R * x, * where x is a n-vector, alpha is a scalar, y is a m0-vector. * * Since matrix R is available by columns, the product is computed as * a linear combination: * * y := y + alpha * (R[1] * x[1] + ... + R[n] * x[n]), * * where R[j] is j-th column of R. */ static void r_prod(LPF *lpf, double y[], double a, const double x[]) { int n = lpf->n; int *R_ptr = lpf->R_ptr; int *R_len = lpf->R_len; int *v_ind = lpf->v_ind; double *v_val = lpf->v_val; int j, beg, end, ptr; double t; for (j = 1; j <= n; j++) { if (x[j] == 0.0) continue; /* y := y + alpha * R[j] * x[j] */ t = a * x[j]; beg = R_ptr[j]; end = beg + R_len[j]; for (ptr = beg; ptr < end; ptr++) y[v_ind[ptr]] += t * v_val[ptr]; } return; } /*********************************************************************** * The routine rt_prod computes the product y := y + alpha * R' * x, * where R' is a matrix transposed to R, x is a m0-vector, alpha is a * scalar, y is a n-vector. * * Since matrix R is available by columns, the product components are * computed as inner products: * * y[j] := y[j] + alpha * (j-th column of R) * x * * for j = 1, 2, ..., n. */ static void rt_prod(LPF *lpf, double y[], double a, const double x[]) { int n = lpf->n; int *R_ptr = lpf->R_ptr; int *R_len = lpf->R_len; int *v_ind = lpf->v_ind; double *v_val = lpf->v_val; int j, beg, end, ptr; double t; for (j = 1; j <= n; j++) { /* t := (j-th column of R) * x */ t = 0.0; beg = R_ptr[j]; end = beg + R_len[j]; for (ptr = beg; ptr < end; ptr++) t += v_val[ptr] * x[v_ind[ptr]]; /* y[j] := y[j] + alpha * t */ y[j] += a * t; } return; } /*********************************************************************** * The routine s_prod computes the product y := y + alpha * S * x, * where x is a m0-vector, alpha is a scalar, y is a n-vector. * * Since matrix S is available by rows, the product components are * computed as inner products: * * y[i] = y[i] + alpha * (i-th row of S) * x * * for i = 1, 2, ..., n. */ static void s_prod(LPF *lpf, double y[], double a, const double x[]) { int n = lpf->n; int *S_ptr = lpf->S_ptr; int *S_len = lpf->S_len; int *v_ind = lpf->v_ind; double *v_val = lpf->v_val; int i, beg, end, ptr; double t; for (i = 1; i <= n; i++) { /* t := (i-th row of S) * x */ t = 0.0; beg = S_ptr[i]; end = beg + S_len[i]; for (ptr = beg; ptr < end; ptr++) t += v_val[ptr] * x[v_ind[ptr]]; /* y[i] := y[i] + alpha * t */ y[i] += a * t; } return; } /*********************************************************************** * The routine st_prod computes the product y := y + alpha * S' * x, * where S' is a matrix transposed to S, x is a n-vector, alpha is a * scalar, y is m0-vector. * * Since matrix R is available by rows, the product is computed as a * linear combination: * * y := y + alpha * (S'[1] * x[1] + ... + S'[n] * x[n]), * * where S'[i] is i-th row of S. */ static void st_prod(LPF *lpf, double y[], double a, const double x[]) { int n = lpf->n; int *S_ptr = lpf->S_ptr; int *S_len = lpf->S_len; int *v_ind = lpf->v_ind; double *v_val = lpf->v_val; int i, beg, end, ptr; double t; for (i = 1; i <= n; i++) { if (x[i] == 0.0) continue; /* y := y + alpha * S'[i] * x[i] */ t = a * x[i]; beg = S_ptr[i]; end = beg + S_len[i]; for (ptr = beg; ptr < end; ptr++) y[v_ind[ptr]] += t * v_val[ptr]; } return; } #if _GLPLPF_DEBUG /*********************************************************************** * The routine check_error computes the maximal relative error between * left- and right-hand sides for the system B * x = b (if tr is zero) * or B' * x = b (if tr is non-zero), where B' is a matrix transposed * to B. (This routine is intended for debugging only.) */ static void check_error(LPF *lpf, int tr, const double x[], const double b[]) { int m = lpf->m; double *B = lpf->B; int i, j; double d, dmax = 0.0, s, t, tmax; for (i = 1; i <= m; i++) { s = 0.0; tmax = 1.0; for (j = 1; j <= m; j++) { if (!tr) t = B[m * (i - 1) + j] * x[j]; else t = B[m * (j - 1) + i] * x[j]; if (tmax < fabs(t)) tmax = fabs(t); s += t; } d = fabs(s - b[i]) / tmax; if (dmax < d) dmax = d; } if (dmax > 1e-8) xprintf("%s: dmax = %g; relative error too large\n", !tr ? "lpf_ftran" : "lpf_btran", dmax); return; } #endif /*********************************************************************** * NAME * * lpf_ftran - perform forward transformation (solve system B*x = b) * * SYNOPSIS * * #include "glplpf.h" * void lpf_ftran(LPF *lpf, double x[]); * * DESCRIPTION * * The routine lpf_ftran performs forward transformation, i.e. solves * the system B*x = b, where B is the basis matrix, x is the vector of * unknowns to be computed, b is the vector of right-hand sides. * * On entry elements of the vector b should be stored in dense format * in locations x[1], ..., x[m], where m is the number of rows. On exit * the routine stores elements of the vector x in the same locations. * * BACKGROUND * * Solution of the system B * x = b can be obtained by solving the * following augmented system: * * ( B F^) ( x ) ( b ) * ( ) ( ) = ( ) * ( G^ H^) ( y ) ( 0 ) * * which, using the main equality, can be written as follows: * * ( L0 0 ) ( U0 R ) ( x ) ( b ) * P ( ) ( ) Q ( ) = ( ) * ( S I ) ( 0 C ) ( y ) ( 0 ) * * therefore, * * ( x ) ( U0 R )-1 ( L0 0 )-1 ( b ) * ( ) = Q' ( ) ( ) P' ( ) * ( y ) ( 0 C ) ( S I ) ( 0 ) * * Thus, computing the solution includes the following steps: * * 1. Compute * * ( f ) ( b ) * ( ) = P' ( ) * ( g ) ( 0 ) * * 2. Solve the system * * ( f1 ) ( L0 0 )-1 ( f ) ( L0 0 ) ( f1 ) ( f ) * ( ) = ( ) ( ) => ( ) ( ) = ( ) * ( g1 ) ( S I ) ( g ) ( S I ) ( g1 ) ( g ) * * from which it follows that: * * { L0 * f1 = f f1 = inv(L0) * f * { => * { S * f1 + g1 = g g1 = g - S * f1 * * 3. Solve the system * * ( f2 ) ( U0 R )-1 ( f1 ) ( U0 R ) ( f2 ) ( f1 ) * ( ) = ( ) ( ) => ( ) ( ) = ( ) * ( g2 ) ( 0 C ) ( g1 ) ( 0 C ) ( g2 ) ( g1 ) * * from which it follows that: * * { U0 * f2 + R * g2 = f1 f2 = inv(U0) * (f1 - R * g2) * { => * { C * g2 = g1 g2 = inv(C) * g1 * * 4. Compute * * ( x ) ( f2 ) * ( ) = Q' ( ) * ( y ) ( g2 ) */ void lpf_ftran(LPF *lpf, double x[]) { int m0 = lpf->m0; int m = lpf->m; int n = lpf->n; int *P_col = lpf->P_col; int *Q_col = lpf->Q_col; double *fg = lpf->work1; double *f = fg; double *g = fg + m0; int i, ii; #if _GLPLPF_DEBUG double *b; #endif if (!lpf->valid) xfault("lpf_ftran: the factorization is not valid\n"); xassert(0 <= m && m <= m0 + n); #if _GLPLPF_DEBUG /* save the right-hand side vector */ b = xcalloc(1+m, sizeof(double)); for (i = 1; i <= m; i++) b[i] = x[i]; #endif /* (f g) := inv(P) * (b 0) */ for (i = 1; i <= m0 + n; i++) fg[i] = ((ii = P_col[i]) <= m ? x[ii] : 0.0); /* f1 := inv(L0) * f */ luf_f_solve(lpf->luf, 0, f); /* g1 := g - S * f1 */ s_prod(lpf, g, -1.0, f); /* g2 := inv(C) * g1 */ scf_solve_it(lpf->scf, 0, g); /* f2 := inv(U0) * (f1 - R * g2) */ r_prod(lpf, f, -1.0, g); luf_v_solve(lpf->luf, 0, f); /* (x y) := inv(Q) * (f2 g2) */ for (i = 1; i <= m; i++) x[i] = fg[Q_col[i]]; #if _GLPLPF_DEBUG /* check relative error in solution */ check_error(lpf, 0, x, b); xfree(b); #endif return; } /*********************************************************************** * NAME * * lpf_btran - perform backward transformation (solve system B'*x = b) * * SYNOPSIS * * #include "glplpf.h" * void lpf_btran(LPF *lpf, double x[]); * * DESCRIPTION * * The routine lpf_btran performs backward transformation, i.e. solves * the system B'*x = b, where B' is a matrix transposed to the basis * matrix B, x is the vector of unknowns to be computed, b is the vector * of right-hand sides. * * On entry elements of the vector b should be stored in dense format * in locations x[1], ..., x[m], where m is the number of rows. On exit * the routine stores elements of the vector x in the same locations. * * BACKGROUND * * Solution of the system B' * x = b, where B' is a matrix transposed * to B, can be obtained by solving the following augmented system: * * ( B F^)T ( x ) ( b ) * ( ) ( ) = ( ) * ( G^ H^) ( y ) ( 0 ) * * which, using the main equality, can be written as follows: * * T ( U0 R )T ( L0 0 )T T ( x ) ( b ) * Q ( ) ( ) P ( ) = ( ) * ( 0 C ) ( S I ) ( y ) ( 0 ) * * or, equivalently, as follows: * * ( U'0 0 ) ( L'0 S') ( x ) ( b ) * Q' ( ) ( ) P' ( ) = ( ) * ( R' C') ( 0 I ) ( y ) ( 0 ) * * therefore, * * ( x ) ( L'0 S')-1 ( U'0 0 )-1 ( b ) * ( ) = P ( ) ( ) Q ( ) * ( y ) ( 0 I ) ( R' C') ( 0 ) * * Thus, computing the solution includes the following steps: * * 1. Compute * * ( f ) ( b ) * ( ) = Q ( ) * ( g ) ( 0 ) * * 2. Solve the system * * ( f1 ) ( U'0 0 )-1 ( f ) ( U'0 0 ) ( f1 ) ( f ) * ( ) = ( ) ( ) => ( ) ( ) = ( ) * ( g1 ) ( R' C') ( g ) ( R' C') ( g1 ) ( g ) * * from which it follows that: * * { U'0 * f1 = f f1 = inv(U'0) * f * { => * { R' * f1 + C' * g1 = g g1 = inv(C') * (g - R' * f1) * * 3. Solve the system * * ( f2 ) ( L'0 S')-1 ( f1 ) ( L'0 S') ( f2 ) ( f1 ) * ( ) = ( ) ( ) => ( ) ( ) = ( ) * ( g2 ) ( 0 I ) ( g1 ) ( 0 I ) ( g2 ) ( g1 ) * * from which it follows that: * * { L'0 * f2 + S' * g2 = f1 * { => f2 = inv(L'0) * ( f1 - S' * g2) * { g2 = g1 * * 4. Compute * * ( x ) ( f2 ) * ( ) = P ( ) * ( y ) ( g2 ) */ void lpf_btran(LPF *lpf, double x[]) { int m0 = lpf->m0; int m = lpf->m; int n = lpf->n; int *P_row = lpf->P_row; int *Q_row = lpf->Q_row; double *fg = lpf->work1; double *f = fg; double *g = fg + m0; int i, ii; #if _GLPLPF_DEBUG double *b; #endif if (!lpf->valid) xfault("lpf_btran: the factorization is not valid\n"); xassert(0 <= m && m <= m0 + n); #if _GLPLPF_DEBUG /* save the right-hand side vector */ b = xcalloc(1+m, sizeof(double)); for (i = 1; i <= m; i++) b[i] = x[i]; #endif /* (f g) := Q * (b 0) */ for (i = 1; i <= m0 + n; i++) fg[i] = ((ii = Q_row[i]) <= m ? x[ii] : 0.0); /* f1 := inv(U'0) * f */ luf_v_solve(lpf->luf, 1, f); /* g1 := inv(C') * (g - R' * f1) */ rt_prod(lpf, g, -1.0, f); scf_solve_it(lpf->scf, 1, g); /* g2 := g1 */ g = g; /* f2 := inv(L'0) * (f1 - S' * g2) */ st_prod(lpf, f, -1.0, g); luf_f_solve(lpf->luf, 1, f); /* (x y) := P * (f2 g2) */ for (i = 1; i <= m; i++) x[i] = fg[P_row[i]]; #if _GLPLPF_DEBUG /* check relative error in solution */ check_error(lpf, 1, x, b); xfree(b); #endif return; } /*********************************************************************** * The routine enlarge_sva enlarges the Sparse Vector Area to new_size * locations by reallocating the arrays v_ind and v_val. */ static void enlarge_sva(LPF *lpf, int new_size) { int v_size = lpf->v_size; int used = lpf->v_ptr - 1; int *v_ind = lpf->v_ind; double *v_val = lpf->v_val; xassert(v_size < new_size); while (v_size < new_size) v_size += v_size; lpf->v_size = v_size; lpf->v_ind = xcalloc(1+v_size, sizeof(int)); lpf->v_val = xcalloc(1+v_size, sizeof(double)); xassert(used >= 0); memcpy(&lpf->v_ind[1], &v_ind[1], used * sizeof(int)); memcpy(&lpf->v_val[1], &v_val[1], used * sizeof(double)); xfree(v_ind); xfree(v_val); return; } /*********************************************************************** * NAME * * lpf_update_it - update LP basis factorization * * SYNOPSIS * * #include "glplpf.h" * int lpf_update_it(LPF *lpf, int j, int bh, int len, const int ind[], * const double val[]); * * DESCRIPTION * * The routine lpf_update_it updates the factorization of the basis * matrix B after replacing its j-th column by a new vector. * * The parameter j specifies the number of column of B, which has been * replaced, 1 <= j <= m, where m is the order of B. * * The parameter bh specifies the basis header entry for the new column * of B, which is the number of the new column in some original matrix. * This parameter is optional and can be specified as 0. * * Row indices and numerical values of non-zero elements of the new * column of B should be placed in locations ind[1], ..., ind[len] and * val[1], ..., val[len], resp., where len is the number of non-zeros * in the column. Neither zero nor duplicate elements are allowed. * * RETURNS * * 0 The factorization has been successfully updated. * * LPF_ESING * New basis B is singular within the working precision. * * LPF_ELIMIT * Maximal number of additional rows and columns has been reached. * * BACKGROUND * * Let j-th column of the current basis matrix B have to be replaced by * a new column a. This replacement is equivalent to removing the old * j-th column by fixing it at zero and introducing the new column as * follows: * * ( B F^| a ) * ( B F^) ( | ) * ( ) ---> ( G^ H^| 0 ) * ( G^ H^) (-------+---) * ( e'j 0 | 0 ) * * where ej is a unit vector with 1 in j-th position which used to fix * the old j-th column of B (at zero). Then using the main equality we * have: * * ( B F^| a ) ( B0 F | f ) * ( | ) ( P 0 ) ( | ) ( Q 0 ) * ( G^ H^| 0 ) = ( ) ( G H | g ) ( ) = * (-------+---) ( 0 1 ) (-------+---) ( 0 1 ) * ( e'j 0 | 0 ) ( v' w'| 0 ) * * [ ( B0 F )| ( f ) ] [ ( B0 F ) | ( f ) ] * [ P ( )| P ( ) ] ( Q 0 ) [ P ( ) Q| P ( ) ] * = [ ( G H )| ( g ) ] ( ) = [ ( G H ) | ( g ) ] * [------------+-------- ] ( 0 1 ) [-------------+---------] * [ ( v' w')| 0 ] [ ( v' w') Q| 0 ] * * where: * * ( a ) ( f ) ( f ) ( a ) * ( ) = P ( ) => ( ) = P' * ( ) * ( 0 ) ( g ) ( g ) ( 0 ) * * ( ej ) ( v ) ( v ) ( ej ) * ( e'j 0 ) = ( v' w' ) Q => ( ) = Q' ( ) => ( ) = Q ( ) * ( 0 ) ( w ) ( w ) ( 0 ) * * On the other hand: * * ( B0| F f ) * ( P 0 ) (---+------) ( Q 0 ) ( B0 new F ) * ( ) ( G | H g ) ( ) = new P ( ) new Q * ( 0 1 ) ( | ) ( 0 1 ) ( new G new H ) * ( v'| w' 0 ) * * where: * ( G ) ( H g ) * new F = ( F f ), new G = ( ), new H = ( ), * ( v') ( w' 0 ) * * ( P 0 ) ( Q 0 ) * new P = ( ) , new Q = ( ) . * ( 0 1 ) ( 0 1 ) * * The factorization structure for the new augmented matrix remains the * same, therefore: * * ( B0 new F ) ( L0 0 ) ( U0 new R ) * new P ( ) new Q = ( ) ( ) * ( new G new H ) ( new S I ) ( 0 new C ) * * where: * * new F = L0 * new R => * * new R = inv(L0) * new F = inv(L0) * (F f) = ( R inv(L0)*f ) * * new G = new S * U0 => * * ( G ) ( S ) * new S = new G * inv(U0) = ( ) * inv(U0) = ( ) * ( v') ( v'*inv(U0) ) * * new H = new S * new R + new C => * * new C = new H - new S * new R = * * ( H g ) ( S ) * = ( ) - ( ) * ( R inv(L0)*f ) = * ( w' 0 ) ( v'*inv(U0) ) * * ( H - S*R g - S*inv(L0)*f ) ( C x ) * = ( ) = ( ) * ( w'- v'*inv(U0)*R -v'*inv(U0)*inv(L0)*f) ( y' z ) * * Note that new C is resulted by expanding old C with new column x, * row y', and diagonal element z, where: * * x = g - S * inv(L0) * f = g - S * (new column of R) * * y = w - R'* inv(U'0)* v = w - R'* (new row of S) * * z = - (new row of S) * (new column of R) * * Finally, to replace old B by new B we have to permute j-th and last * (just added) columns of the matrix * * ( B F^| a ) * ( | ) * ( G^ H^| 0 ) * (-------+---) * ( e'j 0 | 0 ) * * and to keep the main equality do the same for matrix Q. */ int lpf_update_it(LPF *lpf, int j, int bh, int len, const int ind[], const double val[]) { int m0 = lpf->m0; int m = lpf->m; #if _GLPLPF_DEBUG double *B = lpf->B; #endif int n = lpf->n; int *R_ptr = lpf->R_ptr; int *R_len = lpf->R_len; int *S_ptr = lpf->S_ptr; int *S_len = lpf->S_len; int *P_row = lpf->P_row; int *P_col = lpf->P_col; int *Q_row = lpf->Q_row; int *Q_col = lpf->Q_col; int v_ptr = lpf->v_ptr; int *v_ind = lpf->v_ind; double *v_val = lpf->v_val; double *a = lpf->work2; /* new column */ double *fg = lpf->work1, *f = fg, *g = fg + m0; double *vw = lpf->work2, *v = vw, *w = vw + m0; double *x = g, *y = w, z; int i, ii, k, ret; xassert(bh == bh); if (!lpf->valid) xfault("lpf_update_it: the factorization is not valid\n"); if (!(1 <= j && j <= m)) xfault("lpf_update_it: j = %d; column number out of range\n", j); xassert(0 <= m && m <= m0 + n); /* check if the basis factorization can be expanded */ if (n == lpf->n_max) { lpf->valid = 0; ret = LPF_ELIMIT; goto done; } /* convert new j-th column of B to dense format */ for (i = 1; i <= m; i++) a[i] = 0.0; for (k = 1; k <= len; k++) { i = ind[k]; if (!(1 <= i && i <= m)) xfault("lpf_update_it: ind[%d] = %d; row number out of rang" "e\n", k, i); if (a[i] != 0.0) xfault("lpf_update_it: ind[%d] = %d; duplicate row index no" "t allowed\n", k, i); if (val[k] == 0.0) xfault("lpf_update_it: val[%d] = %g; zero element not allow" "ed\n", k, val[k]); a[i] = val[k]; } #if _GLPLPF_DEBUG /* change column in the basis matrix for debugging */ for (i = 1; i <= m; i++) B[(i - 1) * m + j] = a[i]; #endif /* (f g) := inv(P) * (a 0) */ for (i = 1; i <= m0+n; i++) fg[i] = ((ii = P_col[i]) <= m ? a[ii] : 0.0); /* (v w) := Q * (ej 0) */ for (i = 1; i <= m0+n; i++) vw[i] = 0.0; vw[Q_col[j]] = 1.0; /* f1 := inv(L0) * f (new column of R) */ luf_f_solve(lpf->luf, 0, f); /* v1 := inv(U'0) * v (new row of S) */ luf_v_solve(lpf->luf, 1, v); /* we need at most 2 * m0 available locations in the SVA to store new column of matrix R and new row of matrix S */ if (lpf->v_size < v_ptr + m0 + m0) { enlarge_sva(lpf, v_ptr + m0 + m0); v_ind = lpf->v_ind; v_val = lpf->v_val; } /* store new column of R */ R_ptr[n+1] = v_ptr; for (i = 1; i <= m0; i++) { if (f[i] != 0.0) v_ind[v_ptr] = i, v_val[v_ptr] = f[i], v_ptr++; } R_len[n+1] = v_ptr - lpf->v_ptr; lpf->v_ptr = v_ptr; /* store new row of S */ S_ptr[n+1] = v_ptr; for (i = 1; i <= m0; i++) { if (v[i] != 0.0) v_ind[v_ptr] = i, v_val[v_ptr] = v[i], v_ptr++; } S_len[n+1] = v_ptr - lpf->v_ptr; lpf->v_ptr = v_ptr; /* x := g - S * f1 (new column of C) */ s_prod(lpf, x, -1.0, f); /* y := w - R' * v1 (new row of C) */ rt_prod(lpf, y, -1.0, v); /* z := - v1 * f1 (new diagonal element of C) */ z = 0.0; for (i = 1; i <= m0; i++) z -= v[i] * f[i]; /* update factorization of new matrix C */ switch (scf_update_exp(lpf->scf, x, y, z)) { case 0: break; case SCF_ESING: lpf->valid = 0; ret = LPF_ESING; goto done; case SCF_ELIMIT: xassert(lpf != lpf); default: xassert(lpf != lpf); } /* expand matrix P */ P_row[m0+n+1] = P_col[m0+n+1] = m0+n+1; /* expand matrix Q */ Q_row[m0+n+1] = Q_col[m0+n+1] = m0+n+1; /* permute j-th and last (just added) column of matrix Q */ i = Q_col[j], ii = Q_col[m0+n+1]; Q_row[i] = m0+n+1, Q_col[m0+n+1] = i; Q_row[ii] = j, Q_col[j] = ii; /* increase the number of additional rows and columns */ lpf->n++; xassert(lpf->n <= lpf->n_max); /* the factorization has been successfully updated */ ret = 0; done: /* return to the calling program */ return ret; } /*********************************************************************** * NAME * * lpf_delete_it - delete LP basis factorization * * SYNOPSIS * * #include "glplpf.h" * void lpf_delete_it(LPF *lpf) * * DESCRIPTION * * The routine lpf_delete_it deletes LP basis factorization specified * by the parameter lpf and frees all memory allocated to this program * object. */ void lpf_delete_it(LPF *lpf) { luf_delete_it(lpf->luf); #if _GLPLPF_DEBUG if (lpf->B != NULL) xfree(lpf->B); #else xassert(lpf->B == NULL); #endif if (lpf->R_ptr != NULL) xfree(lpf->R_ptr); if (lpf->R_len != NULL) xfree(lpf->R_len); if (lpf->S_ptr != NULL) xfree(lpf->S_ptr); if (lpf->S_len != NULL) xfree(lpf->S_len); if (lpf->scf != NULL) scf_delete_it(lpf->scf); if (lpf->P_row != NULL) xfree(lpf->P_row); if (lpf->P_col != NULL) xfree(lpf->P_col); if (lpf->Q_row != NULL) xfree(lpf->Q_row); if (lpf->Q_col != NULL) xfree(lpf->Q_col); if (lpf->v_ind != NULL) xfree(lpf->v_ind); if (lpf->v_val != NULL) xfree(lpf->v_val); if (lpf->work1 != NULL) xfree(lpf->work1); if (lpf->work2 != NULL) xfree(lpf->work2); xfree(lpf); return; } /* eof */ praat-6.0.04/external/glpk/glplpf.h000066400000000000000000000171221261542461700171370ustar00rootroot00000000000000/* glplpf.h (LP basis factorization, Schur complement version) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPLPF_H #define GLPLPF_H #include "glpscf.h" #include "glpluf.h" /*********************************************************************** * The structure LPF defines the factorization of the basis mxm matrix * B, where m is the number of rows in corresponding problem instance. * * This factorization is the following septet: * * [B] = (L0, U0, R, S, C, P, Q), (1) * * and is based on the following main equality: * * ( B F^) ( B0 F ) ( L0 0 ) ( U0 R ) * ( ) = P ( ) Q = P ( ) ( ) Q, (2) * ( G^ H^) ( G H ) ( S I ) ( 0 C ) * * where: * * B is the current basis matrix (not stored); * * F^, G^, H^ are some additional matrices (not stored); * * B0 is some initial basis matrix (not stored); * * F, G, H are some additional matrices (not stored); * * P, Q are permutation matrices (stored in both row- and column-like * formats); * * L0, U0 are some matrices that defines a factorization of the initial * basis matrix B0 = L0 * U0 (stored in an invertable form); * * R is a matrix defined from L0 * R = F, so R = inv(L0) * F (stored in * a column-wise sparse format); * * S is a matrix defined from S * U0 = G, so S = G * inv(U0) (stored in * a row-wise sparse format); * * C is the Schur complement for matrix (B0 F G H). It is defined from * S * R + C = H, so C = H - S * R = H - G * inv(U0) * inv(L0) * F = * = H - G * inv(B0) * F. Matrix C is stored in an invertable form. * * REFERENCES * * 1. M.A.Saunders, "LUSOL: A basis package for constrained optimiza- * tion," SCCM, Stanford University, 2006. * * 2. M.A.Saunders, "Notes 5: Basis Updates," CME 318, Stanford Univer- * sity, Spring 2006. * * 3. M.A.Saunders, "Notes 6: LUSOL---a Basis Factorization Package," * ibid. */ typedef struct LPF LPF; struct LPF { /* LP basis factorization */ int valid; /* the factorization is valid only if this flag is set */ /*--------------------------------------------------------------*/ /* initial basis matrix B0 */ int m0_max; /* maximal value of m0 (increased automatically, if necessary) */ int m0; /* the order of B0 */ LUF *luf; /* LU-factorization of B0 */ /*--------------------------------------------------------------*/ /* current basis matrix B */ int m; /* the order of B */ double *B; /* double B[1+m*m]; */ /* B in dense format stored by rows and used only for debugging; normally this array is not allocated */ /*--------------------------------------------------------------*/ /* augmented matrix (B0 F G H) of the order m0+n */ int n_max; /* maximal number of additional rows and columns */ int n; /* current number of additional rows and columns */ /*--------------------------------------------------------------*/ /* m0xn matrix R in column-wise format */ int *R_ptr; /* int R_ptr[1+n_max]; */ /* R_ptr[j], 1 <= j <= n, is a pointer to j-th column */ int *R_len; /* int R_len[1+n_max]; */ /* R_len[j], 1 <= j <= n, is the length of j-th column */ /*--------------------------------------------------------------*/ /* nxm0 matrix S in row-wise format */ int *S_ptr; /* int S_ptr[1+n_max]; */ /* S_ptr[i], 1 <= i <= n, is a pointer to i-th row */ int *S_len; /* int S_len[1+n_max]; */ /* S_len[i], 1 <= i <= n, is the length of i-th row */ /*--------------------------------------------------------------*/ /* Schur complement C of the order n */ SCF *scf; /* SCF scf[1:n_max]; */ /* factorization of the Schur complement */ /*--------------------------------------------------------------*/ /* matrix P of the order m0+n */ int *P_row; /* int P_row[1+m0_max+n_max]; */ /* P_row[i] = j means that P[i,j] = 1 */ int *P_col; /* int P_col[1+m0_max+n_max]; */ /* P_col[j] = i means that P[i,j] = 1 */ /*--------------------------------------------------------------*/ /* matrix Q of the order m0+n */ int *Q_row; /* int Q_row[1+m0_max+n_max]; */ /* Q_row[i] = j means that Q[i,j] = 1 */ int *Q_col; /* int Q_col[1+m0_max+n_max]; */ /* Q_col[j] = i means that Q[i,j] = 1 */ /*--------------------------------------------------------------*/ /* Sparse Vector Area (SVA) is a set of locations intended to store sparse vectors which represent columns of matrix R and rows of matrix S; each location is a doublet (ind, val), where ind is an index, val is a numerical value of a sparse vector element; in the whole each sparse vector is a set of adjacent locations defined by a pointer to its first element and its length, i.e. the number of its elements */ int v_size; /* the SVA size, in locations; locations are numbered by integers 1, 2, ..., v_size, and location 0 is not used */ int v_ptr; /* pointer to the first available location */ int *v_ind; /* int v_ind[1+v_size]; */ /* v_ind[k], 1 <= k <= v_size, is the index field of location k */ double *v_val; /* double v_val[1+v_size]; */ /* v_val[k], 1 <= k <= v_size, is the value field of location k */ /*--------------------------------------------------------------*/ double *work1; /* double work1[1+m0+n_max]; */ /* working array */ double *work2; /* double work2[1+m0+n_max]; */ /* working array */ }; /* return codes: */ #define LPF_ESING 1 /* singular matrix */ #define LPF_ECOND 2 /* ill-conditioned matrix */ #define LPF_ELIMIT 3 /* update limit reached */ #define lpf_create_it _glp_lpf_create_it LPF *lpf_create_it(void); /* create LP basis factorization */ #define lpf_factorize _glp_lpf_factorize int lpf_factorize(LPF *lpf, int m, const int bh[], int (*col) (void *info, int j, int ind[], double val[]), void *info); /* compute LP basis factorization */ #define lpf_ftran _glp_lpf_ftran void lpf_ftran(LPF *lpf, double x[]); /* perform forward transformation (solve system B*x = b) */ #define lpf_btran _glp_lpf_btran void lpf_btran(LPF *lpf, double x[]); /* perform backward transformation (solve system B'*x = b) */ #define lpf_update_it _glp_lpf_update_it int lpf_update_it(LPF *lpf, int j, int bh, int len, const int ind[], const double val[]); /* update LP basis factorization */ #define lpf_delete_it _glp_lpf_delete_it void lpf_delete_it(LPF *lpf); /* delete LP basis factorization */ #endif /* eof */ praat-6.0.04/external/glpk/glplpx01.c000066400000000000000000001375201261542461700173220ustar00rootroot00000000000000/* glplpx01.c (obsolete API routines) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpapi.h" struct LPXCPS { /* control parameters and statistics */ int msg_lev; /* level of messages output by the solver: 0 - no output 1 - error messages only 2 - normal output 3 - full output (includes informational messages) */ int scale; /* scaling option: 0 - no scaling 1 - equilibration scaling 2 - geometric mean scaling 3 - geometric mean scaling, then equilibration scaling */ int dual; /* dual simplex option: 0 - use primal simplex 1 - use dual simplex */ int price; /* pricing option (for both primal and dual simplex): 0 - textbook pricing 1 - steepest edge pricing */ double relax; /* relaxation parameter used in the ratio test; if it is zero, the textbook ratio test is used; if it is non-zero (should be positive), Harris' two-pass ratio test is used; in the latter case on the first pass basic variables (in the case of primal simplex) or reduced costs of non-basic variables (in the case of dual simplex) are allowed to slightly violate their bounds, but not more than (relax * tol_bnd) or (relax * tol_dj) (thus, relax is a percentage of tol_bnd or tol_dj) */ double tol_bnd; /* relative tolerance used to check if the current basic solution is primal feasible */ double tol_dj; /* absolute tolerance used to check if the current basic solution is dual feasible */ double tol_piv; /* relative tolerance used to choose eligible pivotal elements of the simplex table in the ratio test */ int round; /* solution rounding option: 0 - report all computed values and reduced costs "as is" 1 - if possible (allowed by the tolerances), replace computed values and reduced costs which are close to zero by exact zeros */ double obj_ll; /* lower limit of the objective function; if on the phase II the objective function reaches this limit and continues decreasing, the solver stops the search */ double obj_ul; /* upper limit of the objective function; if on the phase II the objective function reaches this limit and continues increasing, the solver stops the search */ int it_lim; /* simplex iterations limit; if this value is positive, it is decreased by one each time when one simplex iteration has been performed, and reaching zero value signals the solver to stop the search; negative value means no iterations limit */ double tm_lim; /* searching time limit, in seconds; if this value is positive, it is decreased each time when one simplex iteration has been performed by the amount of time spent for the iteration, and reaching zero value signals the solver to stop the search; negative value means no time limit */ int out_frq; /* output frequency, in iterations; this parameter specifies how frequently the solver sends information about the solution to the standard output */ double out_dly; /* output delay, in seconds; this parameter specifies how long the solver should delay sending information about the solution to the standard output; zero value means no delay */ int branch; /* MIP */ /* branching heuristic: 0 - branch on first variable 1 - branch on last variable 2 - branch using heuristic by Driebeck and Tomlin 3 - branch on most fractional variable */ int btrack; /* MIP */ /* backtracking heuristic: 0 - select most recent node (depth first search) 1 - select earliest node (breadth first search) 2 - select node using the best projection heuristic 3 - select node with best local bound */ double tol_int; /* MIP */ /* absolute tolerance used to check if the current basic solution is integer feasible */ double tol_obj; /* MIP */ /* relative tolerance used to check if the value of the objective function is not better than in the best known integer feasible solution */ int mps_info; /* lpx_write_mps */ /* if this flag is set, the routine lpx_write_mps outputs several comment cards that contains some information about the problem; otherwise the routine outputs no comment cards */ int mps_obj; /* lpx_write_mps */ /* this parameter tells the routine lpx_write_mps how to output the objective function row: 0 - never output objective function row 1 - always output objective function row 2 - output objective function row if and only if the problem has no free rows */ int mps_orig; /* lpx_write_mps */ /* if this flag is set, the routine lpx_write_mps uses original row and column symbolic names; otherwise the routine generates plain names using ordinal numbers of rows and columns */ int mps_wide; /* lpx_write_mps */ /* if this flag is set, the routine lpx_write_mps uses all data fields; otherwise the routine keeps fields 5 and 6 empty */ int mps_free; /* lpx_write_mps */ /* if this flag is set, the routine lpx_write_mps omits column and vector names everytime if possible (free style); otherwise the routine never omits these names (pedantic style) */ int mps_skip; /* lpx_write_mps */ /* if this flag is set, the routine lpx_write_mps skips empty columns (i.e. which has no constraint coefficients); otherwise the routine outputs all columns */ int lpt_orig; /* lpx_write_lpt */ /* if this flag is set, the routine lpx_write_lpt uses original row and column symbolic names; otherwise the routine generates plain names using ordinal numbers of rows and columns */ int presol; /* lpx_simplex */ /* LP presolver option: 0 - do not use LP presolver 1 - use LP presolver */ int binarize; /* lpx_intopt */ /* if this flag is set, the routine lpx_intopt replaces integer columns by binary ones */ int use_cuts; /* lpx_intopt */ /* if this flag is set, the routine lpx_intopt tries generating cutting planes: LPX_C_COVER - mixed cover cuts LPX_C_CLIQUE - clique cuts LPX_C_GOMORY - Gomory's mixed integer cuts LPX_C_ALL - all cuts */ double mip_gap; /* MIP */ /* relative MIP gap tolerance */ }; LPX *lpx_create_prob(void) { /* create problem object */ return glp_create_prob(); } void lpx_set_prob_name(LPX *lp, const char *name) { /* assign (change) problem name */ glp_set_prob_name(lp, name); return; } void lpx_set_obj_name(LPX *lp, const char *name) { /* assign (change) objective function name */ glp_set_obj_name(lp, name); return; } void lpx_set_obj_dir(LPX *lp, int dir) { /* set (change) optimization direction flag */ glp_set_obj_dir(lp, dir - LPX_MIN + GLP_MIN); return; } int lpx_add_rows(LPX *lp, int nrs) { /* add new rows to problem object */ return glp_add_rows(lp, nrs); } int lpx_add_cols(LPX *lp, int ncs) { /* add new columns to problem object */ return glp_add_cols(lp, ncs); } void lpx_set_row_name(LPX *lp, int i, const char *name) { /* assign (change) row name */ glp_set_row_name(lp, i, name); return; } void lpx_set_col_name(LPX *lp, int j, const char *name) { /* assign (change) column name */ glp_set_col_name(lp, j, name); return; } void lpx_set_row_bnds(LPX *lp, int i, int type, double lb, double ub) { /* set (change) row bounds */ glp_set_row_bnds(lp, i, type - LPX_FR + GLP_FR, lb, ub); return; } void lpx_set_col_bnds(LPX *lp, int j, int type, double lb, double ub) { /* set (change) column bounds */ glp_set_col_bnds(lp, j, type - LPX_FR + GLP_FR, lb, ub); return; } void lpx_set_obj_coef(glp_prob *lp, int j, double coef) { /* set (change) obj. coefficient or constant term */ glp_set_obj_coef(lp, j, coef); return; } void lpx_set_mat_row(LPX *lp, int i, int len, const int ind[], const double val[]) { /* set (replace) row of the constraint matrix */ glp_set_mat_row(lp, i, len, ind, val); return; } void lpx_set_mat_col(LPX *lp, int j, int len, const int ind[], const double val[]) { /* set (replace) column of the constraint matrix */ glp_set_mat_col(lp, j, len, ind, val); return; } void lpx_load_matrix(LPX *lp, int ne, const int ia[], const int ja[], const double ar[]) { /* load (replace) the whole constraint matrix */ glp_load_matrix(lp, ne, ia, ja, ar); return; } void lpx_del_rows(LPX *lp, int nrs, const int num[]) { /* delete specified rows from problem object */ glp_del_rows(lp, nrs, num); return; } void lpx_del_cols(LPX *lp, int ncs, const int num[]) { /* delete specified columns from problem object */ glp_del_cols(lp, ncs, num); return; } void lpx_delete_prob(LPX *lp) { /* delete problem object */ glp_delete_prob(lp); return; } const char *lpx_get_prob_name(LPX *lp) { /* retrieve problem name */ return glp_get_prob_name(lp); } const char *lpx_get_obj_name(LPX *lp) { /* retrieve objective function name */ return glp_get_obj_name(lp); } int lpx_get_obj_dir(LPX *lp) { /* retrieve optimization direction flag */ return glp_get_obj_dir(lp) - GLP_MIN + LPX_MIN; } int lpx_get_num_rows(LPX *lp) { /* retrieve number of rows */ return glp_get_num_rows(lp); } int lpx_get_num_cols(LPX *lp) { /* retrieve number of columns */ return glp_get_num_cols(lp); } const char *lpx_get_row_name(LPX *lp, int i) { /* retrieve row name */ return glp_get_row_name(lp, i); } const char *lpx_get_col_name(LPX *lp, int j) { /* retrieve column name */ return glp_get_col_name(lp, j); } int lpx_get_row_type(LPX *lp, int i) { /* retrieve row type */ return glp_get_row_type(lp, i) - GLP_FR + LPX_FR; } double lpx_get_row_lb(glp_prob *lp, int i) { /* retrieve row lower bound */ double lb; lb = glp_get_row_lb(lp, i); if (lb == -DBL_MAX) lb = 0.0; return lb; } double lpx_get_row_ub(glp_prob *lp, int i) { /* retrieve row upper bound */ double ub; ub = glp_get_row_ub(lp, i); if (ub == +DBL_MAX) ub = 0.0; return ub; } void lpx_get_row_bnds(glp_prob *lp, int i, int *typx, double *lb, double *ub) { /* retrieve row bounds */ if (typx != NULL) *typx = lpx_get_row_type(lp, i); if (lb != NULL) *lb = lpx_get_row_lb(lp, i); if (ub != NULL) *ub = lpx_get_row_ub(lp, i); return; } int lpx_get_col_type(LPX *lp, int j) { /* retrieve column type */ return glp_get_col_type(lp, j) - GLP_FR + LPX_FR; } double lpx_get_col_lb(glp_prob *lp, int j) { /* retrieve column lower bound */ double lb; lb = glp_get_col_lb(lp, j); if (lb == -DBL_MAX) lb = 0.0; return lb; } double lpx_get_col_ub(glp_prob *lp, int j) { /* retrieve column upper bound */ double ub; ub = glp_get_col_ub(lp, j); if (ub == +DBL_MAX) ub = 0.0; return ub; } void lpx_get_col_bnds(glp_prob *lp, int j, int *typx, double *lb, double *ub) { /* retrieve column bounds */ if (typx != NULL) *typx = lpx_get_col_type(lp, j); if (lb != NULL) *lb = lpx_get_col_lb(lp, j); if (ub != NULL) *ub = lpx_get_col_ub(lp, j); return; } double lpx_get_obj_coef(LPX *lp, int j) { /* retrieve obj. coefficient or constant term */ return glp_get_obj_coef(lp, j); } int lpx_get_num_nz(LPX *lp) { /* retrieve number of constraint coefficients */ return glp_get_num_nz(lp); } int lpx_get_mat_row(LPX *lp, int i, int ind[], double val[]) { /* retrieve row of the constraint matrix */ return glp_get_mat_row(lp, i, ind, val); } int lpx_get_mat_col(LPX *lp, int j, int ind[], double val[]) { /* retrieve column of the constraint matrix */ return glp_get_mat_col(lp, j, ind, val); } void lpx_create_index(LPX *lp) { /* create the name index */ glp_create_index(lp); return; } int lpx_find_row(LPX *lp, const char *name) { /* find row by its name */ return glp_find_row(lp, name); } int lpx_find_col(LPX *lp, const char *name) { /* find column by its name */ return glp_find_col(lp, name); } void lpx_delete_index(LPX *lp) { /* delete the name index */ glp_delete_index(lp); return; } void lpx_scale_prob(LPX *lp) { /* scale problem data */ switch (lpx_get_int_parm(lp, LPX_K_SCALE)) { case 0: /* no scaling */ glp_unscale_prob(lp); break; case 1: /* equilibration scaling */ glp_scale_prob(lp, GLP_SF_EQ); break; case 2: /* geometric mean scaling */ glp_scale_prob(lp, GLP_SF_GM); break; case 3: /* geometric mean scaling, then equilibration scaling */ glp_scale_prob(lp, GLP_SF_GM | GLP_SF_EQ); break; default: xassert(lp != lp); } return; } void lpx_unscale_prob(LPX *lp) { /* unscale problem data */ glp_unscale_prob(lp); return; } void lpx_set_row_stat(LPX *lp, int i, int stat) { /* set (change) row status */ glp_set_row_stat(lp, i, stat - LPX_BS + GLP_BS); return; } void lpx_set_col_stat(LPX *lp, int j, int stat) { /* set (change) column status */ glp_set_col_stat(lp, j, stat - LPX_BS + GLP_BS); return; } void lpx_std_basis(LPX *lp) { /* construct standard initial LP basis */ glp_std_basis(lp); return; } void lpx_adv_basis(LPX *lp) { /* construct advanced initial LP basis */ glp_adv_basis(lp, 0); return; } void lpx_cpx_basis(LPX *lp) { /* construct Bixby's initial LP basis */ glp_cpx_basis(lp); return; } static void fill_smcp(LPX *lp, glp_smcp *parm) { glp_init_smcp(parm); switch (lpx_get_int_parm(lp, LPX_K_MSGLEV)) { case 0: parm->msg_lev = GLP_MSG_OFF; break; case 1: parm->msg_lev = GLP_MSG_ERR; break; case 2: parm->msg_lev = GLP_MSG_ON; break; case 3: parm->msg_lev = GLP_MSG_ALL; break; default: xassert(lp != lp); } switch (lpx_get_int_parm(lp, LPX_K_DUAL)) { case 0: parm->meth = GLP_PRIMAL; break; case 1: parm->meth = GLP_DUAL; break; default: xassert(lp != lp); } switch (lpx_get_int_parm(lp, LPX_K_PRICE)) { case 0: parm->pricing = GLP_PT_STD; break; case 1: parm->pricing = GLP_PT_PSE; break; default: xassert(lp != lp); } if (lpx_get_real_parm(lp, LPX_K_RELAX) == 0.0) parm->r_test = GLP_RT_STD; else parm->r_test = GLP_RT_HAR; parm->tol_bnd = lpx_get_real_parm(lp, LPX_K_TOLBND); parm->tol_dj = lpx_get_real_parm(lp, LPX_K_TOLDJ); parm->tol_piv = lpx_get_real_parm(lp, LPX_K_TOLPIV); parm->obj_ll = lpx_get_real_parm(lp, LPX_K_OBJLL); parm->obj_ul = lpx_get_real_parm(lp, LPX_K_OBJUL); if (lpx_get_int_parm(lp, LPX_K_ITLIM) < 0) parm->it_lim = INT_MAX; else parm->it_lim = lpx_get_int_parm(lp, LPX_K_ITLIM); if (lpx_get_real_parm(lp, LPX_K_TMLIM) < 0.0) parm->tm_lim = INT_MAX; else parm->tm_lim = (int)(1000.0 * lpx_get_real_parm(lp, LPX_K_TMLIM)); parm->out_frq = lpx_get_int_parm(lp, LPX_K_OUTFRQ); parm->out_dly = (int)(1000.0 * lpx_get_real_parm(lp, LPX_K_OUTDLY)); switch (lpx_get_int_parm(lp, LPX_K_PRESOL)) { case 0: parm->presolve = GLP_OFF; break; case 1: parm->presolve = GLP_ON; break; default: xassert(lp != lp); } return; } int lpx_simplex(LPX *lp) { /* easy-to-use driver to the simplex method */ glp_smcp parm; int ret; fill_smcp(lp, &parm); ret = glp_simplex(lp, &parm); switch (ret) { case 0: ret = LPX_E_OK; break; case GLP_EBADB: case GLP_ESING: case GLP_ECOND: case GLP_EBOUND: ret = LPX_E_FAULT; break; case GLP_EFAIL: ret = LPX_E_SING; break; case GLP_EOBJLL: ret = LPX_E_OBJLL; break; case GLP_EOBJUL: ret = LPX_E_OBJUL; break; case GLP_EITLIM: ret = LPX_E_ITLIM; break; case GLP_ETMLIM: ret = LPX_E_TMLIM; break; case GLP_ENOPFS: ret = LPX_E_NOPFS; break; case GLP_ENODFS: ret = LPX_E_NODFS; break; default: xassert(ret != ret); } return ret; } int lpx_exact(LPX *lp) { /* easy-to-use driver to the exact simplex method */ glp_smcp parm; int ret; fill_smcp(lp, &parm); ret = glp_exact(lp, &parm); switch (ret) { case 0: ret = LPX_E_OK; break; case GLP_EBADB: case GLP_ESING: case GLP_EBOUND: case GLP_EFAIL: ret = LPX_E_FAULT; break; case GLP_EITLIM: ret = LPX_E_ITLIM; break; case GLP_ETMLIM: ret = LPX_E_TMLIM; break; default: xassert(ret != ret); } return ret; } int lpx_get_status(glp_prob *lp) { /* retrieve generic status of basic solution */ int status; switch (glp_get_status(lp)) { case GLP_OPT: status = LPX_OPT; break; case GLP_FEAS: status = LPX_FEAS; break; case GLP_INFEAS: status = LPX_INFEAS; break; case GLP_NOFEAS: status = LPX_NOFEAS; break; case GLP_UNBND: status = LPX_UNBND; break; case GLP_UNDEF: status = LPX_UNDEF; break; default: xassert(lp != lp); } return status; } int lpx_get_prim_stat(glp_prob *lp) { /* retrieve status of primal basic solution */ return glp_get_prim_stat(lp) - GLP_UNDEF + LPX_P_UNDEF; } int lpx_get_dual_stat(glp_prob *lp) { /* retrieve status of dual basic solution */ return glp_get_dual_stat(lp) - GLP_UNDEF + LPX_D_UNDEF; } double lpx_get_obj_val(LPX *lp) { /* retrieve objective value (basic solution) */ return glp_get_obj_val(lp); } int lpx_get_row_stat(LPX *lp, int i) { /* retrieve row status (basic solution) */ return glp_get_row_stat(lp, i) - GLP_BS + LPX_BS; } double lpx_get_row_prim(LPX *lp, int i) { /* retrieve row primal value (basic solution) */ return glp_get_row_prim(lp, i); } double lpx_get_row_dual(LPX *lp, int i) { /* retrieve row dual value (basic solution) */ return glp_get_row_dual(lp, i); } void lpx_get_row_info(glp_prob *lp, int i, int *tagx, double *vx, double *dx) { /* obtain row solution information */ if (tagx != NULL) *tagx = lpx_get_row_stat(lp, i); if (vx != NULL) *vx = lpx_get_row_prim(lp, i); if (dx != NULL) *dx = lpx_get_row_dual(lp, i); return; } int lpx_get_col_stat(LPX *lp, int j) { /* retrieve column status (basic solution) */ return glp_get_col_stat(lp, j) - GLP_BS + LPX_BS; } double lpx_get_col_prim(LPX *lp, int j) { /* retrieve column primal value (basic solution) */ return glp_get_col_prim(lp, j); } double lpx_get_col_dual(glp_prob *lp, int j) { /* retrieve column dual value (basic solution) */ return glp_get_col_dual(lp, j); } void lpx_get_col_info(glp_prob *lp, int j, int *tagx, double *vx, double *dx) { /* obtain column solution information */ if (tagx != NULL) *tagx = lpx_get_col_stat(lp, j); if (vx != NULL) *vx = lpx_get_col_prim(lp, j); if (dx != NULL) *dx = lpx_get_col_dual(lp, j); return; } int lpx_get_ray_info(LPX *lp) { /* determine what causes primal unboundness */ return glp_get_unbnd_ray(lp); } void lpx_check_kkt(LPX *lp, int scaled, LPXKKT *kkt) { /* check Karush-Kuhn-Tucker conditions */ int ae_ind, re_ind; double ae_max, re_max; xassert(scaled == scaled); _glp_check_kkt(lp, GLP_SOL, GLP_KKT_PE, &ae_max, &ae_ind, &re_max, &re_ind); kkt->pe_ae_max = ae_max; kkt->pe_ae_row = ae_ind; kkt->pe_re_max = re_max; kkt->pe_re_row = re_ind; if (re_max <= 1e-9) kkt->pe_quality = 'H'; else if (re_max <= 1e-6) kkt->pe_quality = 'M'; else if (re_max <= 1e-3) kkt->pe_quality = 'L'; else kkt->pe_quality = '?'; _glp_check_kkt(lp, GLP_SOL, GLP_KKT_PB, &ae_max, &ae_ind, &re_max, &re_ind); kkt->pb_ae_max = ae_max; kkt->pb_ae_ind = ae_ind; kkt->pb_re_max = re_max; kkt->pb_re_ind = re_ind; if (re_max <= 1e-9) kkt->pb_quality = 'H'; else if (re_max <= 1e-6) kkt->pb_quality = 'M'; else if (re_max <= 1e-3) kkt->pb_quality = 'L'; else kkt->pb_quality = '?'; _glp_check_kkt(lp, GLP_SOL, GLP_KKT_DE, &ae_max, &ae_ind, &re_max, &re_ind); kkt->de_ae_max = ae_max; if (ae_ind == 0) kkt->de_ae_col = 0; else kkt->de_ae_col = ae_ind - lp->m; kkt->de_re_max = re_max; if (re_ind == 0) kkt->de_re_col = 0; else kkt->de_re_col = ae_ind - lp->m; if (re_max <= 1e-9) kkt->de_quality = 'H'; else if (re_max <= 1e-6) kkt->de_quality = 'M'; else if (re_max <= 1e-3) kkt->de_quality = 'L'; else kkt->de_quality = '?'; _glp_check_kkt(lp, GLP_SOL, GLP_KKT_DB, &ae_max, &ae_ind, &re_max, &re_ind); kkt->db_ae_max = ae_max; kkt->db_ae_ind = ae_ind; kkt->db_re_max = re_max; kkt->db_re_ind = re_ind; if (re_max <= 1e-9) kkt->db_quality = 'H'; else if (re_max <= 1e-6) kkt->db_quality = 'M'; else if (re_max <= 1e-3) kkt->db_quality = 'L'; else kkt->db_quality = '?'; kkt->cs_ae_max = 0.0, kkt->cs_ae_ind = 0; kkt->cs_re_max = 0.0, kkt->cs_re_ind = 0; kkt->cs_quality = 'H'; return; } int lpx_warm_up(LPX *lp) { /* "warm up" LP basis */ int ret; ret = glp_warm_up(lp); if (ret == 0) ret = LPX_E_OK; else if (ret == GLP_EBADB) ret = LPX_E_BADB; else if (ret == GLP_ESING) ret = LPX_E_SING; else if (ret == GLP_ECOND) ret = LPX_E_SING; else xassert(ret != ret); return ret; } int lpx_eval_tab_row(LPX *lp, int k, int ind[], double val[]) { /* compute row of the simplex tableau */ return glp_eval_tab_row(lp, k, ind, val); } int lpx_eval_tab_col(LPX *lp, int k, int ind[], double val[]) { /* compute column of the simplex tableau */ return glp_eval_tab_col(lp, k, ind, val); } int lpx_transform_row(LPX *lp, int len, int ind[], double val[]) { /* transform explicitly specified row */ return glp_transform_row(lp, len, ind, val); } int lpx_transform_col(LPX *lp, int len, int ind[], double val[]) { /* transform explicitly specified column */ return glp_transform_col(lp, len, ind, val); } int lpx_prim_ratio_test(LPX *lp, int len, const int ind[], const double val[], int how, double tol) { /* perform primal ratio test */ int piv; piv = glp_prim_rtest(lp, len, ind, val, how, tol); xassert(0 <= piv && piv <= len); return piv == 0 ? 0 : ind[piv]; } int lpx_dual_ratio_test(LPX *lp, int len, const int ind[], const double val[], int how, double tol) { /* perform dual ratio test */ int piv; piv = glp_dual_rtest(lp, len, ind, val, how, tol); xassert(0 <= piv && piv <= len); return piv == 0 ? 0 : ind[piv]; } int lpx_interior(LPX *lp) { /* easy-to-use driver to the interior-point method */ int ret; ret = glp_interior(lp, NULL); switch (ret) { case 0: ret = LPX_E_OK; break; case GLP_EFAIL: ret = LPX_E_FAULT; break; case GLP_ENOFEAS: ret = LPX_E_NOFEAS; break; case GLP_ENOCVG: ret = LPX_E_NOCONV; break; case GLP_EITLIM: ret = LPX_E_ITLIM; break; case GLP_EINSTAB: ret = LPX_E_INSTAB; break; default: xassert(ret != ret); } return ret; } int lpx_ipt_status(glp_prob *lp) { /* retrieve status of interior-point solution */ int status; switch (glp_ipt_status(lp)) { case GLP_UNDEF: status = LPX_T_UNDEF; break; case GLP_OPT: status = LPX_T_OPT; break; default: xassert(lp != lp); } return status; } double lpx_ipt_obj_val(LPX *lp) { /* retrieve objective value (interior point) */ return glp_ipt_obj_val(lp); } double lpx_ipt_row_prim(LPX *lp, int i) { /* retrieve row primal value (interior point) */ return glp_ipt_row_prim(lp, i); } double lpx_ipt_row_dual(LPX *lp, int i) { /* retrieve row dual value (interior point) */ return glp_ipt_row_dual(lp, i); } double lpx_ipt_col_prim(LPX *lp, int j) { /* retrieve column primal value (interior point) */ return glp_ipt_col_prim(lp, j); } double lpx_ipt_col_dual(LPX *lp, int j) { /* retrieve column dual value (interior point) */ return glp_ipt_col_dual(lp, j); } void lpx_set_class(LPX *lp, int klass) { /* set problem class */ xassert(lp == lp); if (!(klass == LPX_LP || klass == LPX_MIP)) xerror("lpx_set_class: invalid problem class\n"); return; } int lpx_get_class(LPX *lp) { /* determine problem klass */ return glp_get_num_int(lp) == 0 ? LPX_LP : LPX_MIP; } void lpx_set_col_kind(LPX *lp, int j, int kind) { /* set (change) column kind */ glp_set_col_kind(lp, j, kind - LPX_CV + GLP_CV); return; } int lpx_get_col_kind(LPX *lp, int j) { /* retrieve column kind */ return glp_get_col_kind(lp, j) == GLP_CV ? LPX_CV : LPX_IV; } int lpx_get_num_int(LPX *lp) { /* retrieve number of integer columns */ return glp_get_num_int(lp); } int lpx_get_num_bin(LPX *lp) { /* retrieve number of binary columns */ return glp_get_num_bin(lp); } static int solve_mip(LPX *lp, int presolve) { glp_iocp parm; int ret; glp_init_iocp(&parm); switch (lpx_get_int_parm(lp, LPX_K_MSGLEV)) { case 0: parm.msg_lev = GLP_MSG_OFF; break; case 1: parm.msg_lev = GLP_MSG_ERR; break; case 2: parm.msg_lev = GLP_MSG_ON; break; case 3: parm.msg_lev = GLP_MSG_ALL; break; default: xassert(lp != lp); } switch (lpx_get_int_parm(lp, LPX_K_BRANCH)) { case 0: parm.br_tech = GLP_BR_FFV; break; case 1: parm.br_tech = GLP_BR_LFV; break; case 2: parm.br_tech = GLP_BR_DTH; break; case 3: parm.br_tech = GLP_BR_MFV; break; default: xassert(lp != lp); } switch (lpx_get_int_parm(lp, LPX_K_BTRACK)) { case 0: parm.bt_tech = GLP_BT_DFS; break; case 1: parm.bt_tech = GLP_BT_BFS; break; case 2: parm.bt_tech = GLP_BT_BPH; break; case 3: parm.bt_tech = GLP_BT_BLB; break; default: xassert(lp != lp); } parm.tol_int = lpx_get_real_parm(lp, LPX_K_TOLINT); parm.tol_obj = lpx_get_real_parm(lp, LPX_K_TOLOBJ); if (lpx_get_real_parm(lp, LPX_K_TMLIM) < 0.0 || lpx_get_real_parm(lp, LPX_K_TMLIM) > 1e6) parm.tm_lim = INT_MAX; else parm.tm_lim = (int)(1000.0 * lpx_get_real_parm(lp, LPX_K_TMLIM)); parm.mip_gap = lpx_get_real_parm(lp, LPX_K_MIPGAP); if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_GOMORY) parm.gmi_cuts = GLP_ON; else parm.gmi_cuts = GLP_OFF; if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_MIR) parm.mir_cuts = GLP_ON; else parm.mir_cuts = GLP_OFF; if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_COVER) parm.cov_cuts = GLP_ON; else parm.cov_cuts = GLP_OFF; if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_CLIQUE) parm.clq_cuts = GLP_ON; else parm.clq_cuts = GLP_OFF; parm.presolve = presolve; if (lpx_get_int_parm(lp, LPX_K_BINARIZE)) parm.binarize = GLP_ON; ret = glp_intopt(lp, &parm); switch (ret) { case 0: ret = LPX_E_OK; break; case GLP_ENOPFS: ret = LPX_E_NOPFS; break; case GLP_ENODFS: ret = LPX_E_NODFS; break; case GLP_EBOUND: case GLP_EROOT: ret = LPX_E_FAULT; break; case GLP_EFAIL: ret = LPX_E_SING; break; case GLP_EMIPGAP: ret = LPX_E_MIPGAP; break; case GLP_ETMLIM: ret = LPX_E_TMLIM; break; default: xassert(ret != ret); } return ret; } int lpx_integer(LPX *lp) { /* easy-to-use driver to the branch-and-bound method */ return solve_mip(lp, GLP_OFF); } int lpx_intopt(LPX *lp) { /* easy-to-use driver to the branch-and-bound method */ return solve_mip(lp, GLP_ON); } int lpx_mip_status(glp_prob *lp) { /* retrieve status of MIP solution */ int status; switch (glp_mip_status(lp)) { case GLP_UNDEF: status = LPX_I_UNDEF; break; case GLP_OPT: status = LPX_I_OPT; break; case GLP_FEAS: status = LPX_I_FEAS; break; case GLP_NOFEAS: status = LPX_I_NOFEAS; break; default: xassert(lp != lp); } return status; } double lpx_mip_obj_val(LPX *lp) { /* retrieve objective value (MIP solution) */ return glp_mip_obj_val(lp); } double lpx_mip_row_val(LPX *lp, int i) { /* retrieve row value (MIP solution) */ return glp_mip_row_val(lp, i); } double lpx_mip_col_val(LPX *lp, int j) { /* retrieve column value (MIP solution) */ return glp_mip_col_val(lp, j); } void lpx_check_int(LPX *lp, LPXKKT *kkt) { /* check integer feasibility conditions */ int ae_ind, re_ind; double ae_max, re_max; _glp_check_kkt(lp, GLP_MIP, GLP_KKT_PE, &ae_max, &ae_ind, &re_max, &re_ind); kkt->pe_ae_max = ae_max; kkt->pe_ae_row = ae_ind; kkt->pe_re_max = re_max; kkt->pe_re_row = re_ind; if (re_max <= 1e-9) kkt->pe_quality = 'H'; else if (re_max <= 1e-6) kkt->pe_quality = 'M'; else if (re_max <= 1e-3) kkt->pe_quality = 'L'; else kkt->pe_quality = '?'; _glp_check_kkt(lp, GLP_MIP, GLP_KKT_PB, &ae_max, &ae_ind, &re_max, &re_ind); kkt->pb_ae_max = ae_max; kkt->pb_ae_ind = ae_ind; kkt->pb_re_max = re_max; kkt->pb_re_ind = re_ind; if (re_max <= 1e-9) kkt->pb_quality = 'H'; else if (re_max <= 1e-6) kkt->pb_quality = 'M'; else if (re_max <= 1e-3) kkt->pb_quality = 'L'; else kkt->pb_quality = '?'; return; } #if 1 /* 17/XI-2009 */ static void reset_parms(LPX *lp) { /* reset control parameters to default values */ struct LPXCPS *cps = lp->parms; xassert(cps != NULL); cps->msg_lev = 3; cps->scale = 1; cps->dual = 0; cps->price = 1; cps->relax = 0.07; cps->tol_bnd = 1e-7; cps->tol_dj = 1e-7; cps->tol_piv = 1e-9; cps->round = 0; cps->obj_ll = -DBL_MAX; cps->obj_ul = +DBL_MAX; cps->it_lim = -1; lp->it_cnt = 0; cps->tm_lim = -1.0; cps->out_frq = 200; cps->out_dly = 0.0; cps->branch = 2; cps->btrack = 3; cps->tol_int = 1e-5; cps->tol_obj = 1e-7; cps->mps_info = 1; cps->mps_obj = 2; cps->mps_orig = 0; cps->mps_wide = 1; cps->mps_free = 0; cps->mps_skip = 0; cps->lpt_orig = 0; cps->presol = 0; cps->binarize = 0; cps->use_cuts = 0; cps->mip_gap = 0.0; return; } #endif #if 1 /* 17/XI-2009 */ static struct LPXCPS *access_parms(LPX *lp) { /* allocate and initialize control parameters, if necessary */ if (lp->parms == NULL) { lp->parms = xmalloc(sizeof(struct LPXCPS)); reset_parms(lp); } return lp->parms; } #endif #if 1 /* 17/XI-2009 */ void lpx_reset_parms(LPX *lp) { /* reset control parameters to default values */ access_parms(lp); reset_parms(lp); return; } #endif void lpx_set_int_parm(LPX *lp, int parm, int val) { /* set (change) integer control parameter */ #if 0 /* 17/XI-2009 */ struct LPXCPS *cps = lp->cps; #else struct LPXCPS *cps = access_parms(lp); #endif switch (parm) { case LPX_K_MSGLEV: if (!(0 <= val && val <= 3)) xerror("lpx_set_int_parm: MSGLEV = %d; invalid value\n", val); cps->msg_lev = val; break; case LPX_K_SCALE: if (!(0 <= val && val <= 3)) xerror("lpx_set_int_parm: SCALE = %d; invalid value\n", val); cps->scale = val; break; case LPX_K_DUAL: if (!(val == 0 || val == 1)) xerror("lpx_set_int_parm: DUAL = %d; invalid value\n", val); cps->dual = val; break; case LPX_K_PRICE: if (!(val == 0 || val == 1)) xerror("lpx_set_int_parm: PRICE = %d; invalid value\n", val); cps->price = val; break; case LPX_K_ROUND: if (!(val == 0 || val == 1)) xerror("lpx_set_int_parm: ROUND = %d; invalid value\n", val); cps->round = val; break; case LPX_K_ITLIM: cps->it_lim = val; break; case LPX_K_ITCNT: lp->it_cnt = val; break; case LPX_K_OUTFRQ: if (!(val > 0)) xerror("lpx_set_int_parm: OUTFRQ = %d; invalid value\n", val); cps->out_frq = val; break; case LPX_K_BRANCH: if (!(val == 0 || val == 1 || val == 2 || val == 3)) xerror("lpx_set_int_parm: BRANCH = %d; invalid value\n", val); cps->branch = val; break; case LPX_K_BTRACK: if (!(val == 0 || val == 1 || val == 2 || val == 3)) xerror("lpx_set_int_parm: BTRACK = %d; invalid value\n", val); cps->btrack = val; break; case LPX_K_MPSINFO: if (!(val == 0 || val == 1)) xerror("lpx_set_int_parm: MPSINFO = %d; invalid value\n", val); cps->mps_info = val; break; case LPX_K_MPSOBJ: if (!(val == 0 || val == 1 || val == 2)) xerror("lpx_set_int_parm: MPSOBJ = %d; invalid value\n", val); cps->mps_obj = val; break; case LPX_K_MPSORIG: if (!(val == 0 || val == 1)) xerror("lpx_set_int_parm: MPSORIG = %d; invalid value\n", val); cps->mps_orig = val; break; case LPX_K_MPSWIDE: if (!(val == 0 || val == 1)) xerror("lpx_set_int_parm: MPSWIDE = %d; invalid value\n", val); cps->mps_wide = val; break; case LPX_K_MPSFREE: if (!(val == 0 || val == 1)) xerror("lpx_set_int_parm: MPSFREE = %d; invalid value\n", val); cps->mps_free = val; break; case LPX_K_MPSSKIP: if (!(val == 0 || val == 1)) xerror("lpx_set_int_parm: MPSSKIP = %d; invalid value\n", val); cps->mps_skip = val; break; case LPX_K_LPTORIG: if (!(val == 0 || val == 1)) xerror("lpx_set_int_parm: LPTORIG = %d; invalid value\n", val); cps->lpt_orig = val; break; case LPX_K_PRESOL: if (!(val == 0 || val == 1)) xerror("lpx_set_int_parm: PRESOL = %d; invalid value\n", val); cps->presol = val; break; case LPX_K_BINARIZE: if (!(val == 0 || val == 1)) xerror("lpx_set_int_parm: BINARIZE = %d; invalid value\n" , val); cps->binarize = val; break; case LPX_K_USECUTS: if (val & ~LPX_C_ALL) xerror("lpx_set_int_parm: USECUTS = 0x%X; invalid value\n", val); cps->use_cuts = val; break; case LPX_K_BFTYPE: #if 0 if (!(1 <= val && val <= 3)) xerror("lpx_set_int_parm: BFTYPE = %d; invalid value\n", val); cps->bf_type = val; #else { glp_bfcp parm; glp_get_bfcp(lp, &parm); switch (val) { case 1: parm.type = GLP_BF_FT; break; case 2: parm.type = GLP_BF_BG; break; case 3: parm.type = GLP_BF_GR; break; default: xerror("lpx_set_int_parm: BFTYPE = %d; invalid val" "ue\n", val); } glp_set_bfcp(lp, &parm); } #endif break; default: xerror("lpx_set_int_parm: parm = %d; invalid parameter\n", parm); } return; } int lpx_get_int_parm(LPX *lp, int parm) { /* query integer control parameter */ #if 0 /* 17/XI-2009 */ struct LPXCPS *cps = lp->cps; #else struct LPXCPS *cps = access_parms(lp); #endif int val = 0; switch (parm) { case LPX_K_MSGLEV: val = cps->msg_lev; break; case LPX_K_SCALE: val = cps->scale; break; case LPX_K_DUAL: val = cps->dual; break; case LPX_K_PRICE: val = cps->price; break; case LPX_K_ROUND: val = cps->round; break; case LPX_K_ITLIM: val = cps->it_lim; break; case LPX_K_ITCNT: val = lp->it_cnt; break; case LPX_K_OUTFRQ: val = cps->out_frq; break; case LPX_K_BRANCH: val = cps->branch; break; case LPX_K_BTRACK: val = cps->btrack; break; case LPX_K_MPSINFO: val = cps->mps_info; break; case LPX_K_MPSOBJ: val = cps->mps_obj; break; case LPX_K_MPSORIG: val = cps->mps_orig; break; case LPX_K_MPSWIDE: val = cps->mps_wide; break; case LPX_K_MPSFREE: val = cps->mps_free; break; case LPX_K_MPSSKIP: val = cps->mps_skip; break; case LPX_K_LPTORIG: val = cps->lpt_orig; break; case LPX_K_PRESOL: val = cps->presol; break; case LPX_K_BINARIZE: val = cps->binarize; break; case LPX_K_USECUTS: val = cps->use_cuts; break; case LPX_K_BFTYPE: #if 0 val = cps->bf_type; break; #else { glp_bfcp parm; glp_get_bfcp(lp, &parm); switch (parm.type) { case GLP_BF_FT: val = 1; break; case GLP_BF_BG: val = 2; break; case GLP_BF_GR: val = 3; break; default: xassert(lp != lp); } } break; #endif default: xerror("lpx_get_int_parm: parm = %d; invalid parameter\n", parm); } return val; } void lpx_set_real_parm(LPX *lp, int parm, double val) { /* set (change) real control parameter */ #if 0 /* 17/XI-2009 */ struct LPXCPS *cps = lp->cps; #else struct LPXCPS *cps = access_parms(lp); #endif switch (parm) { case LPX_K_RELAX: if (!(0.0 <= val && val <= 1.0)) xerror("lpx_set_real_parm: RELAX = %g; invalid value\n", val); cps->relax = val; break; case LPX_K_TOLBND: if (!(DBL_EPSILON <= val && val <= 0.001)) xerror("lpx_set_real_parm: TOLBND = %g; invalid value\n", val); #if 0 if (cps->tol_bnd > val) { /* invalidate the basic solution */ lp->p_stat = LPX_P_UNDEF; lp->d_stat = LPX_D_UNDEF; } #endif cps->tol_bnd = val; break; case LPX_K_TOLDJ: if (!(DBL_EPSILON <= val && val <= 0.001)) xerror("lpx_set_real_parm: TOLDJ = %g; invalid value\n", val); #if 0 if (cps->tol_dj > val) { /* invalidate the basic solution */ lp->p_stat = LPX_P_UNDEF; lp->d_stat = LPX_D_UNDEF; } #endif cps->tol_dj = val; break; case LPX_K_TOLPIV: if (!(DBL_EPSILON <= val && val <= 0.001)) xerror("lpx_set_real_parm: TOLPIV = %g; invalid value\n", val); cps->tol_piv = val; break; case LPX_K_OBJLL: cps->obj_ll = val; break; case LPX_K_OBJUL: cps->obj_ul = val; break; case LPX_K_TMLIM: cps->tm_lim = val; break; case LPX_K_OUTDLY: cps->out_dly = val; break; case LPX_K_TOLINT: if (!(DBL_EPSILON <= val && val <= 0.001)) xerror("lpx_set_real_parm: TOLINT = %g; invalid value\n", val); cps->tol_int = val; break; case LPX_K_TOLOBJ: if (!(DBL_EPSILON <= val && val <= 0.001)) xerror("lpx_set_real_parm: TOLOBJ = %g; invalid value\n", val); cps->tol_obj = val; break; case LPX_K_MIPGAP: if (val < 0.0) xerror("lpx_set_real_parm: MIPGAP = %g; invalid value\n", val); cps->mip_gap = val; break; default: xerror("lpx_set_real_parm: parm = %d; invalid parameter\n", parm); } return; } double lpx_get_real_parm(LPX *lp, int parm) { /* query real control parameter */ #if 0 /* 17/XI-2009 */ struct LPXCPS *cps = lp->cps; #else struct LPXCPS *cps = access_parms(lp); #endif double val = 0.0; switch (parm) { case LPX_K_RELAX: val = cps->relax; break; case LPX_K_TOLBND: val = cps->tol_bnd; break; case LPX_K_TOLDJ: val = cps->tol_dj; break; case LPX_K_TOLPIV: val = cps->tol_piv; break; case LPX_K_OBJLL: val = cps->obj_ll; break; case LPX_K_OBJUL: val = cps->obj_ul; break; case LPX_K_TMLIM: val = cps->tm_lim; break; case LPX_K_OUTDLY: val = cps->out_dly; break; case LPX_K_TOLINT: val = cps->tol_int; break; case LPX_K_TOLOBJ: val = cps->tol_obj; break; case LPX_K_MIPGAP: val = cps->mip_gap; break; default: xerror("lpx_get_real_parm: parm = %d; invalid parameter\n", parm); } return val; } LPX *lpx_read_mps(const char *fname) { /* read problem data in fixed MPS format */ LPX *lp = lpx_create_prob(); if (glp_read_mps(lp, GLP_MPS_DECK, NULL, fname)) lpx_delete_prob(lp), lp = NULL; return lp; } int lpx_write_mps(LPX *lp, const char *fname) { /* write problem data in fixed MPS format */ return glp_write_mps(lp, GLP_MPS_DECK, NULL, fname); } int lpx_read_bas(LPX *lp, const char *fname) { /* read LP basis in fixed MPS format */ #if 0 /* 13/IV-2009 */ return read_bas(lp, fname); #else xassert(lp == lp); xassert(fname == fname); xerror("lpx_read_bas: operation not supported\n"); return 0; #endif } int lpx_write_bas(LPX *lp, const char *fname) { /* write LP basis in fixed MPS format */ #if 0 /* 13/IV-2009 */ return write_bas(lp, fname); #else xassert(lp == lp); xassert(fname == fname); xerror("lpx_write_bas: operation not supported\n"); return 0; #endif } LPX *lpx_read_freemps(const char *fname) { /* read problem data in free MPS format */ LPX *lp = lpx_create_prob(); if (glp_read_mps(lp, GLP_MPS_FILE, NULL, fname)) lpx_delete_prob(lp), lp = NULL; return lp; } int lpx_write_freemps(LPX *lp, const char *fname) { /* write problem data in free MPS format */ return glp_write_mps(lp, GLP_MPS_FILE, NULL, fname); } LPX *lpx_read_cpxlp(const char *fname) { /* read problem data in CPLEX LP format */ LPX *lp; lp = lpx_create_prob(); if (glp_read_lp(lp, NULL, fname)) lpx_delete_prob(lp), lp = NULL; return lp; } int lpx_write_cpxlp(LPX *lp, const char *fname) { /* write problem data in CPLEX LP format */ return glp_write_lp(lp, NULL, fname); } LPX *lpx_read_model(const char *model, const char *data, const char *output) { /* read LP/MIP model written in GNU MathProg language */ LPX *lp = NULL; glp_tran *tran; /* allocate the translator workspace */ tran = glp_mpl_alloc_wksp(); /* read model section and optional data section */ if (glp_mpl_read_model(tran, model, data != NULL)) goto done; /* read separate data section, if required */ if (data != NULL) if (glp_mpl_read_data(tran, data)) goto done; /* generate the model */ if (glp_mpl_generate(tran, output)) goto done; /* build the problem instance from the model */ lp = glp_create_prob(); glp_mpl_build_prob(tran, lp); done: /* free the translator workspace */ glp_mpl_free_wksp(tran); /* bring the problem object to the calling program */ return lp; } int lpx_print_prob(LPX *lp, const char *fname) { /* write problem data in plain text format */ return glp_write_lp(lp, NULL, fname); } int lpx_print_sol(LPX *lp, const char *fname) { /* write LP problem solution in printable format */ return glp_print_sol(lp, fname); } int lpx_print_sens_bnds(LPX *lp, const char *fname) { /* write bounds sensitivity information */ if (glp_get_status(lp) == GLP_OPT && !glp_bf_exists(lp)) glp_factorize(lp); return glp_print_ranges(lp, 0, NULL, 0, fname); } int lpx_print_ips(LPX *lp, const char *fname) { /* write interior point solution in printable format */ return glp_print_ipt(lp, fname); } int lpx_print_mip(LPX *lp, const char *fname) { /* write MIP problem solution in printable format */ return glp_print_mip(lp, fname); } int lpx_is_b_avail(glp_prob *lp) { /* check if LP basis is available */ return glp_bf_exists(lp); } int lpx_main(int argc, const char *argv[]) { /* stand-alone LP/MIP solver */ return glp_main(argc, argv); } /* eof */ praat-6.0.04/external/glpk/glplpx02.c000066400000000000000000000240321261542461700173140ustar00rootroot00000000000000#pragma GCC diagnostic ignored "-Wall" /* glplpx02.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpapi.h" /*********************************************************************** * NAME * * lpx_put_solution - store basic solution components * * SYNOPSIS * * void lpx_put_solution(glp_prob *lp, int inval, const int *p_stat, * const int *d_stat, const double *obj_val, const int r_stat[], * const double r_prim[], const double r_dual[], const int c_stat[], * const double c_prim[], const double c_dual[]) * * DESCRIPTION * * The routine lpx_put_solution stores basic solution components to the * specified problem object. * * The parameter inval is the basis factorization invalidity flag. * If this flag is clear, the current status of the basis factorization * remains unchanged. If this flag is set, the routine invalidates the * basis factorization. * * The parameter p_stat is a pointer to the status of primal basic * solution, which should be specified as follows: * * GLP_UNDEF - primal solution is undefined; * GLP_FEAS - primal solution is feasible; * GLP_INFEAS - primal solution is infeasible; * GLP_NOFEAS - no primal feasible solution exists. * * If the parameter p_stat is NULL, the current status of primal basic * solution remains unchanged. * * The parameter d_stat is a pointer to the status of dual basic * solution, which should be specified as follows: * * GLP_UNDEF - dual solution is undefined; * GLP_FEAS - dual solution is feasible; * GLP_INFEAS - dual solution is infeasible; * GLP_NOFEAS - no dual feasible solution exists. * * If the parameter d_stat is NULL, the current status of dual basic * solution remains unchanged. * * The parameter obj_val is a pointer to the objective function value. * If it is NULL, the current value of the objective function remains * unchanged. * * The array element r_stat[i], 1 <= i <= m (where m is the number of * rows in the problem object), specifies the status of i-th auxiliary * variable, which should be specified as follows: * * GLP_BS - basic variable; * GLP_NL - non-basic variable on lower bound; * GLP_NU - non-basic variable on upper bound; * GLP_NF - non-basic free variable; * GLP_NS - non-basic fixed variable. * * If the parameter r_stat is NULL, the current statuses of auxiliary * variables remain unchanged. * * The array element r_prim[i], 1 <= i <= m (where m is the number of * rows in the problem object), specifies a primal value of i-th * auxiliary variable. If the parameter r_prim is NULL, the current * primal values of auxiliary variables remain unchanged. * * The array element r_dual[i], 1 <= i <= m (where m is the number of * rows in the problem object), specifies a dual value (reduced cost) * of i-th auxiliary variable. If the parameter r_dual is NULL, the * current dual values of auxiliary variables remain unchanged. * * The array element c_stat[j], 1 <= j <= n (where n is the number of * columns in the problem object), specifies the status of j-th * structural variable, which should be specified as follows: * * GLP_BS - basic variable; * GLP_NL - non-basic variable on lower bound; * GLP_NU - non-basic variable on upper bound; * GLP_NF - non-basic free variable; * GLP_NS - non-basic fixed variable. * * If the parameter c_stat is NULL, the current statuses of structural * variables remain unchanged. * * The array element c_prim[j], 1 <= j <= n (where n is the number of * columns in the problem object), specifies a primal value of j-th * structural variable. If the parameter c_prim is NULL, the current * primal values of structural variables remain unchanged. * * The array element c_dual[j], 1 <= j <= n (where n is the number of * columns in the problem object), specifies a dual value (reduced cost) * of j-th structural variable. If the parameter c_dual is NULL, the * current dual values of structural variables remain unchanged. */ void lpx_put_solution(glp_prob *lp, int inval, const int *p_stat, const int *d_stat, const double *obj_val, const int r_stat[], const double r_prim[], const double r_dual[], const int c_stat[], const double c_prim[], const double c_dual[]) { GLPROW *row; GLPCOL *col; int i, j; /* invalidate the basis factorization, if required */ if (inval) lp->valid = 0; /* store primal status */ if (p_stat != NULL) { if (!(*p_stat == GLP_UNDEF || *p_stat == GLP_FEAS || *p_stat == GLP_INFEAS || *p_stat == GLP_NOFEAS)) xerror("lpx_put_solution: p_stat = %d; invalid primal statu" "s\n", *p_stat); lp->pbs_stat = *p_stat; } /* store dual status */ if (d_stat != NULL) { if (!(*d_stat == GLP_UNDEF || *d_stat == GLP_FEAS || *d_stat == GLP_INFEAS || *d_stat == GLP_NOFEAS)) xerror("lpx_put_solution: d_stat = %d; invalid dual status " "\n", *d_stat); lp->dbs_stat = *d_stat; } /* store objective function value */ if (obj_val != NULL) lp->obj_val = *obj_val; /* store row solution components */ for (i = 1; i <= lp->m; i++) { row = lp->row[i]; if (r_stat != NULL) { if (!(r_stat[i] == GLP_BS || row->type == GLP_FR && r_stat[i] == GLP_NF || row->type == GLP_LO && r_stat[i] == GLP_NL || row->type == GLP_UP && r_stat[i] == GLP_NU || row->type == GLP_DB && r_stat[i] == GLP_NL || row->type == GLP_DB && r_stat[i] == GLP_NU || row->type == GLP_FX && r_stat[i] == GLP_NS)) xerror("lpx_put_solution: r_stat[%d] = %d; invalid row s" "tatus\n", i, r_stat[i]); row->stat = r_stat[i]; } if (r_prim != NULL) row->prim = r_prim[i]; if (r_dual != NULL) row->dual = r_dual[i]; } /* store column solution components */ for (j = 1; j <= lp->n; j++) { col = lp->col[j]; if (c_stat != NULL) { if (!(c_stat[j] == GLP_BS || col->type == GLP_FR && c_stat[j] == GLP_NF || col->type == GLP_LO && c_stat[j] == GLP_NL || col->type == GLP_UP && c_stat[j] == GLP_NU || col->type == GLP_DB && c_stat[j] == GLP_NL || col->type == GLP_DB && c_stat[j] == GLP_NU || col->type == GLP_FX && c_stat[j] == GLP_NS)) xerror("lpx_put_solution: c_stat[%d] = %d; invalid colum" "n status\n", j, c_stat[j]); col->stat = c_stat[j]; } if (c_prim != NULL) col->prim = c_prim[j]; if (c_dual != NULL) col->dual = c_dual[j]; } return; } /*---------------------------------------------------------------------- -- lpx_put_mip_soln - store mixed integer solution components. -- -- *Synopsis* -- -- #include "glplpx.h" -- void lpx_put_mip_soln(glp_prob *lp, int i_stat, double row_mipx[], -- double col_mipx[]); -- -- *Description* -- -- The routine lpx_put_mip_soln stores solution components obtained by -- branch-and-bound solver into the specified problem object. -- -- NOTE: This routine is intended for internal use only. */ void lpx_put_mip_soln(glp_prob *lp, int i_stat, double row_mipx[], double col_mipx[]) { GLPROW *row; GLPCOL *col; int i, j; double sum; /* store mixed integer status */ #if 0 if (!(i_stat == LPX_I_UNDEF || i_stat == LPX_I_OPT || i_stat == LPX_I_FEAS || i_stat == LPX_I_NOFEAS)) fault("lpx_put_mip_soln: i_stat = %d; invalid mixed integer st" "atus", i_stat); lp->i_stat = i_stat; #else switch (i_stat) { case LPX_I_UNDEF: lp->mip_stat = GLP_UNDEF; break; case LPX_I_OPT: lp->mip_stat = GLP_OPT; break; case LPX_I_FEAS: lp->mip_stat = GLP_FEAS; break; case LPX_I_NOFEAS: lp->mip_stat = GLP_NOFEAS; break; default: xerror("lpx_put_mip_soln: i_stat = %d; invalid mixed intege" "r status\n", i_stat); } #endif /* store row solution components */ if (row_mipx != NULL) { for (i = 1; i <= lp->m; i++) { row = lp->row[i]; row->mipx = row_mipx[i]; } } /* store column solution components */ if (col_mipx != NULL) { for (j = 1; j <= lp->n; j++) { col = lp->col[j]; col->mipx = col_mipx[j]; } } /* if the solution is claimed to be integer feasible, check it */ if (lp->mip_stat == GLP_OPT || lp->mip_stat == GLP_FEAS) { for (j = 1; j <= lp->n; j++) { col = lp->col[j]; if (col->kind == GLP_IV && col->mipx != floor(col->mipx)) xerror("lpx_put_mip_soln: col_mipx[%d] = %.*g; must be i" "ntegral\n", j, DBL_DIG, col->mipx); } } /* compute the objective function value */ sum = lp->c0; for (j = 1; j <= lp->n; j++) { col = lp->col[j]; sum += col->coef * col->mipx; } lp->mip_obj = sum; return; } /* eof */ praat-6.0.04/external/glpk/glplpx03.c000066400000000000000000000212711261542461700173170ustar00rootroot00000000000000/* glplpx03.c (OPB format) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Author: Oscar Gustafsson . * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #define _GLPSTD_ERRNO #define _GLPSTD_STDIO #include "glpapi.h" #if 0 /* 24/XII-2009; by mao */ #include "glpipp.h" #endif /*---------------------------------------------------------------------- -- lpx_write_pb - write problem data in (normalized) OPB format. -- -- *Synopsis* -- -- #include "glplpx.h" -- int lpx_write_pb(LPX *lp, const char *fname, int normalized, -- int binarize); -- -- *Description* -- -- The routine lpx_write_pb writes problem data in OPB format -- to an output text file whose name is the character string fname. -- If normalized is non-zero the output will be generated in a -- normalized form with sequentially numbered variables, x1, x2 etc. -- If binarize, any integer variable will be repalzec by binary ones, -- see ipp_binarize -- -- *Returns* -- -- If the operation was successful, the routine returns zero. Otherwise -- the routine prints an error message and returns non-zero. */ #if 1 /* 24/XII-2009; by mao (disabled, because IPP was removed) */ int lpx_write_pb(LPX *lp, const char *fname, int normalized, int binarize) { xassert(lp == lp); xassert(fname == fname); xassert(normalized == normalized); xassert(binarize == binarize); xprintf("lpx_write_pb: sorry, currently this operation is not ava" "ilable\n"); return 1; } #else int lpx_write_pb(LPX *lp, const char *fname, int normalized, int binarize) { FILE* fp; int m,n,i,j,k,o,nonfree=0, obj_dir, dbl, *ndx, row_type, emptylhs=0; double coeff, *val, bound, constant/*=0.0*/; char* objconstname = "dummy_one"; char* emptylhsname = "dummy_zero"; /* Variables needed for possible binarization */ /*LPX* tlp;*/ IPP *ipp = NULL; /*tlp=lp;*/ if(binarize) /* Transform integer variables to binary ones */ { ipp = ipp_create_wksp(); ipp_load_orig(ipp, lp); ipp_binarize(ipp); lp = ipp_build_prob(ipp); } fp = fopen(fname, "w"); if(fp!= NULL) { xprintf( "lpx_write_pb: writing problem in %sOPB format to `%s'...\n", (normalized?"normalized ":""), fname); m = glp_get_num_rows(lp); n = glp_get_num_cols(lp); for(i=1;i<=m;i++) { switch(glp_get_row_type(lp,i)) { case GLP_LO: case GLP_UP: case GLP_FX: { nonfree += 1; break; } case GLP_DB: { nonfree += 2; break; } } } constant=glp_get_obj_coef(lp,0); fprintf(fp,"* #variables = %d #constraints = %d\n", n + (constant == 0?1:0), nonfree + (constant == 0?1:0)); /* Objective function */ obj_dir = glp_get_obj_dir(lp); fprintf(fp,"min: "); for(i=1;i<=n;i++) { coeff = glp_get_obj_coef(lp,i); if(coeff != 0.0) { if(obj_dir == GLP_MAX) coeff=-coeff; if(normalized) fprintf(fp, " %d x%d", (int)coeff, i); else fprintf(fp, " %d*%s", (int)coeff, glp_get_col_name(lp,i)); } } if(constant) { if(normalized) fprintf(fp, " %d x%d", (int)constant, n+1); else fprintf(fp, " %d*%s", (int)constant, objconstname); } fprintf(fp,";\n"); if(normalized && !binarize) /* Name substitution */ { fprintf(fp,"* Variable name substitution:\n"); for(j=1;j<=n;j++) { fprintf(fp, "* x%d = %s\n", j, glp_get_col_name(lp,j)); } if(constant) fprintf(fp, "* x%d = %s\n", n+1, objconstname); } ndx = xcalloc(1+n, sizeof(int)); val = xcalloc(1+n, sizeof(double)); /* Constraints */ for(j=1;j<=m;j++) { row_type=glp_get_row_type(lp,j); if(row_type!=GLP_FR) { if(row_type == GLP_DB) { dbl=2; row_type = GLP_UP; } else { dbl=1; } k=glp_get_mat_row(lp, j, ndx, val); for(o=1;o<=dbl;o++) { if(o==2) { row_type = GLP_LO; } if(k==0) /* Empty LHS */ { emptylhs = 1; if(normalized) { fprintf(fp, "0 x%d ", n+2); } else { fprintf(fp, "0*%s ", emptylhsname); } } for(i=1;i<=k;i++) { if(val[i] != 0.0) { if(normalized) { fprintf(fp, "%d x%d ", (row_type==GLP_UP)?(-(int)val[i]):((int)val[i]), ndx[i]); } else { fprintf(fp, "%d*%s ", (int)val[i], glp_get_col_name(lp,ndx[i])); } } } switch(row_type) { case GLP_LO: { fprintf(fp, ">="); bound = glp_get_row_lb(lp,j); break; } case GLP_UP: { if(normalized) { fprintf(fp, ">="); bound = -glp_get_row_ub(lp,j); } else { fprintf(fp, "<="); bound = glp_get_row_ub(lp,j); } break; } case GLP_FX: { fprintf(fp, "="); bound = glp_get_row_lb(lp,j); break; } } fprintf(fp," %d;\n",(int)bound); } } } xfree(ndx); xfree(val); if(constant) { xprintf( "lpx_write_pb: adding constant objective function variable\n"); if(normalized) fprintf(fp, "1 x%d = 1;\n", n+1); else fprintf(fp, "1*%s = 1;\n", objconstname); } if(emptylhs) { xprintf( "lpx_write_pb: adding dummy variable for empty left-hand si" "de constraint\n"); if(normalized) fprintf(fp, "1 x%d = 0;\n", n+2); else fprintf(fp, "1*%s = 0;\n", emptylhsname); } } else { xprintf("Problems opening file for writing: %s\n", fname); return(1); } fflush(fp); if (ferror(fp)) { xprintf("lpx_write_pb: can't write to `%s' - %s\n", fname, strerror(errno)); goto fail; } fclose(fp); if(binarize) { /* delete the resultant problem object */ if (lp != NULL) lpx_delete_prob(lp); /* delete MIP presolver workspace */ if (ipp != NULL) ipp_delete_wksp(ipp); /*lp=tlp;*/ } return 0; fail: if (fp != NULL) fclose(fp); return 1; } #endif /* eof */ praat-6.0.04/external/glpk/glpluf.c000066400000000000000000002135631261542461700171460ustar00rootroot00000000000000/* glpluf.c (LU-factorization) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpenv.h" #include "glpluf.h" #define xfault xerror /* CAUTION: DO NOT CHANGE THE LIMIT BELOW */ #define N_MAX 100000000 /* = 100*10^6 */ /* maximal order of the original matrix */ /*********************************************************************** * NAME * * luf_create_it - create LU-factorization * * SYNOPSIS * * #include "glpluf.h" * LUF *luf_create_it(void); * * DESCRIPTION * * The routine luf_create_it creates a program object, which represents * LU-factorization of a square matrix. * * RETURNS * * The routine luf_create_it returns a pointer to the object created. */ LUF *luf_create_it(void) { LUF *luf; luf = xmalloc(sizeof(LUF)); luf->n_max = luf->n = 0; luf->valid = 0; luf->fr_ptr = luf->fr_len = NULL; luf->fc_ptr = luf->fc_len = NULL; luf->vr_ptr = luf->vr_len = luf->vr_cap = NULL; luf->vr_piv = NULL; luf->vc_ptr = luf->vc_len = luf->vc_cap = NULL; luf->pp_row = luf->pp_col = NULL; luf->qq_row = luf->qq_col = NULL; luf->sv_size = 0; luf->sv_beg = luf->sv_end = 0; luf->sv_ind = NULL; luf->sv_val = NULL; luf->sv_head = luf->sv_tail = 0; luf->sv_prev = luf->sv_next = NULL; luf->vr_max = NULL; luf->rs_head = luf->rs_prev = luf->rs_next = NULL; luf->cs_head = luf->cs_prev = luf->cs_next = NULL; luf->flag = NULL; luf->work = NULL; luf->new_sva = 0; luf->piv_tol = 0.10; luf->piv_lim = 4; luf->suhl = 1; luf->eps_tol = 1e-15; luf->max_gro = 1e+10; luf->nnz_a = luf->nnz_f = luf->nnz_v = 0; luf->max_a = luf->big_v = 0.0; luf->rank = 0; return luf; } /*********************************************************************** * NAME * * luf_defrag_sva - defragment the sparse vector area * * SYNOPSIS * * #include "glpluf.h" * void luf_defrag_sva(LUF *luf); * * DESCRIPTION * * The routine luf_defrag_sva defragments the sparse vector area (SVA) * gathering all unused locations in one continuous extent. In order to * do that the routine moves all unused locations from the left part of * SVA (which contains rows and columns of the matrix V) to the middle * part (which contains free locations). This is attained by relocating * elements of rows and columns of the matrix V toward the beginning of * the left part. * * NOTE that this "garbage collection" involves changing row and column * pointers of the matrix V. */ void luf_defrag_sva(LUF *luf) { int n = luf->n; int *vr_ptr = luf->vr_ptr; int *vr_len = luf->vr_len; int *vr_cap = luf->vr_cap; int *vc_ptr = luf->vc_ptr; int *vc_len = luf->vc_len; int *vc_cap = luf->vc_cap; int *sv_ind = luf->sv_ind; double *sv_val = luf->sv_val; int *sv_next = luf->sv_next; int sv_beg = 1; int i, j, k; /* skip rows and columns, which do not need to be relocated */ for (k = luf->sv_head; k != 0; k = sv_next[k]) { if (k <= n) { /* i-th row of the matrix V */ i = k; if (vr_ptr[i] != sv_beg) break; vr_cap[i] = vr_len[i]; sv_beg += vr_cap[i]; } else { /* j-th column of the matrix V */ j = k - n; if (vc_ptr[j] != sv_beg) break; vc_cap[j] = vc_len[j]; sv_beg += vc_cap[j]; } } /* relocate other rows and columns in order to gather all unused locations in one continuous extent */ for (k = k; k != 0; k = sv_next[k]) { if (k <= n) { /* i-th row of the matrix V */ i = k; memmove(&sv_ind[sv_beg], &sv_ind[vr_ptr[i]], vr_len[i] * sizeof(int)); memmove(&sv_val[sv_beg], &sv_val[vr_ptr[i]], vr_len[i] * sizeof(double)); vr_ptr[i] = sv_beg; vr_cap[i] = vr_len[i]; sv_beg += vr_cap[i]; } else { /* j-th column of the matrix V */ j = k - n; memmove(&sv_ind[sv_beg], &sv_ind[vc_ptr[j]], vc_len[j] * sizeof(int)); memmove(&sv_val[sv_beg], &sv_val[vc_ptr[j]], vc_len[j] * sizeof(double)); vc_ptr[j] = sv_beg; vc_cap[j] = vc_len[j]; sv_beg += vc_cap[j]; } } /* set new pointer to the beginning of the free part */ luf->sv_beg = sv_beg; return; } /*********************************************************************** * NAME * * luf_enlarge_row - enlarge row capacity * * SYNOPSIS * * #include "glpluf.h" * int luf_enlarge_row(LUF *luf, int i, int cap); * * DESCRIPTION * * The routine luf_enlarge_row enlarges capacity of the i-th row of the * matrix V to cap locations (assuming that its current capacity is less * than cap). In order to do that the routine relocates elements of the * i-th row to the end of the left part of SVA (which contains rows and * columns of the matrix V) and then expands the left part by allocating * cap free locations from the free part. If there are less than cap * free locations, the routine defragments the sparse vector area. * * Due to "garbage collection" this operation may change row and column * pointers of the matrix V. * * RETURNS * * If no error occured, the routine returns zero. Otherwise, in case of * overflow of the sparse vector area, the routine returns non-zero. */ int luf_enlarge_row(LUF *luf, int i, int cap) { int n = luf->n; int *vr_ptr = luf->vr_ptr; int *vr_len = luf->vr_len; int *vr_cap = luf->vr_cap; int *vc_cap = luf->vc_cap; int *sv_ind = luf->sv_ind; double *sv_val = luf->sv_val; int *sv_prev = luf->sv_prev; int *sv_next = luf->sv_next; int ret = 0; int cur, k, kk; xassert(1 <= i && i <= n); xassert(vr_cap[i] < cap); /* if there are less than cap free locations, defragment SVA */ if (luf->sv_end - luf->sv_beg < cap) { luf_defrag_sva(luf); if (luf->sv_end - luf->sv_beg < cap) { ret = 1; goto done; } } /* save current capacity of the i-th row */ cur = vr_cap[i]; /* copy existing elements to the beginning of the free part */ memmove(&sv_ind[luf->sv_beg], &sv_ind[vr_ptr[i]], vr_len[i] * sizeof(int)); memmove(&sv_val[luf->sv_beg], &sv_val[vr_ptr[i]], vr_len[i] * sizeof(double)); /* set new pointer and new capacity of the i-th row */ vr_ptr[i] = luf->sv_beg; vr_cap[i] = cap; /* set new pointer to the beginning of the free part */ luf->sv_beg += cap; /* now the i-th row starts in the rightmost location among other rows and columns of the matrix V, so its node should be moved to the end of the row/column linked list */ k = i; /* remove the i-th row node from the linked list */ if (sv_prev[k] == 0) luf->sv_head = sv_next[k]; else { /* capacity of the previous row/column can be increased at the expense of old locations of the i-th row */ kk = sv_prev[k]; if (kk <= n) vr_cap[kk] += cur; else vc_cap[kk-n] += cur; sv_next[sv_prev[k]] = sv_next[k]; } if (sv_next[k] == 0) luf->sv_tail = sv_prev[k]; else sv_prev[sv_next[k]] = sv_prev[k]; /* insert the i-th row node to the end of the linked list */ sv_prev[k] = luf->sv_tail; sv_next[k] = 0; if (sv_prev[k] == 0) luf->sv_head = k; else sv_next[sv_prev[k]] = k; luf->sv_tail = k; done: return ret; } /*********************************************************************** * NAME * * luf_enlarge_col - enlarge column capacity * * SYNOPSIS * * #include "glpluf.h" * int luf_enlarge_col(LUF *luf, int j, int cap); * * DESCRIPTION * * The routine luf_enlarge_col enlarges capacity of the j-th column of * the matrix V to cap locations (assuming that its current capacity is * less than cap). In order to do that the routine relocates elements * of the j-th column to the end of the left part of SVA (which contains * rows and columns of the matrix V) and then expands the left part by * allocating cap free locations from the free part. If there are less * than cap free locations, the routine defragments the sparse vector * area. * * Due to "garbage collection" this operation may change row and column * pointers of the matrix V. * * RETURNS * * If no error occured, the routine returns zero. Otherwise, in case of * overflow of the sparse vector area, the routine returns non-zero. */ int luf_enlarge_col(LUF *luf, int j, int cap) { int n = luf->n; int *vr_cap = luf->vr_cap; int *vc_ptr = luf->vc_ptr; int *vc_len = luf->vc_len; int *vc_cap = luf->vc_cap; int *sv_ind = luf->sv_ind; double *sv_val = luf->sv_val; int *sv_prev = luf->sv_prev; int *sv_next = luf->sv_next; int ret = 0; int cur, k, kk; xassert(1 <= j && j <= n); xassert(vc_cap[j] < cap); /* if there are less than cap free locations, defragment SVA */ if (luf->sv_end - luf->sv_beg < cap) { luf_defrag_sva(luf); if (luf->sv_end - luf->sv_beg < cap) { ret = 1; goto done; } } /* save current capacity of the j-th column */ cur = vc_cap[j]; /* copy existing elements to the beginning of the free part */ memmove(&sv_ind[luf->sv_beg], &sv_ind[vc_ptr[j]], vc_len[j] * sizeof(int)); memmove(&sv_val[luf->sv_beg], &sv_val[vc_ptr[j]], vc_len[j] * sizeof(double)); /* set new pointer and new capacity of the j-th column */ vc_ptr[j] = luf->sv_beg; vc_cap[j] = cap; /* set new pointer to the beginning of the free part */ luf->sv_beg += cap; /* now the j-th column starts in the rightmost location among other rows and columns of the matrix V, so its node should be moved to the end of the row/column linked list */ k = n + j; /* remove the j-th column node from the linked list */ if (sv_prev[k] == 0) luf->sv_head = sv_next[k]; else { /* capacity of the previous row/column can be increased at the expense of old locations of the j-th column */ kk = sv_prev[k]; if (kk <= n) vr_cap[kk] += cur; else vc_cap[kk-n] += cur; sv_next[sv_prev[k]] = sv_next[k]; } if (sv_next[k] == 0) luf->sv_tail = sv_prev[k]; else sv_prev[sv_next[k]] = sv_prev[k]; /* insert the j-th column node to the end of the linked list */ sv_prev[k] = luf->sv_tail; sv_next[k] = 0; if (sv_prev[k] == 0) luf->sv_head = k; else sv_next[sv_prev[k]] = k; luf->sv_tail = k; done: return ret; } /*********************************************************************** * reallocate - reallocate LU-factorization arrays * * This routine reallocates arrays, whose size depends of n, the order * of the matrix A to be factorized. */ static void reallocate(LUF *luf, int n) { int n_max = luf->n_max; luf->n = n; if (n <= n_max) goto done; if (luf->fr_ptr != NULL) xfree(luf->fr_ptr); if (luf->fr_len != NULL) xfree(luf->fr_len); if (luf->fc_ptr != NULL) xfree(luf->fc_ptr); if (luf->fc_len != NULL) xfree(luf->fc_len); if (luf->vr_ptr != NULL) xfree(luf->vr_ptr); if (luf->vr_len != NULL) xfree(luf->vr_len); if (luf->vr_cap != NULL) xfree(luf->vr_cap); if (luf->vr_piv != NULL) xfree(luf->vr_piv); if (luf->vc_ptr != NULL) xfree(luf->vc_ptr); if (luf->vc_len != NULL) xfree(luf->vc_len); if (luf->vc_cap != NULL) xfree(luf->vc_cap); if (luf->pp_row != NULL) xfree(luf->pp_row); if (luf->pp_col != NULL) xfree(luf->pp_col); if (luf->qq_row != NULL) xfree(luf->qq_row); if (luf->qq_col != NULL) xfree(luf->qq_col); if (luf->sv_prev != NULL) xfree(luf->sv_prev); if (luf->sv_next != NULL) xfree(luf->sv_next); if (luf->vr_max != NULL) xfree(luf->vr_max); if (luf->rs_head != NULL) xfree(luf->rs_head); if (luf->rs_prev != NULL) xfree(luf->rs_prev); if (luf->rs_next != NULL) xfree(luf->rs_next); if (luf->cs_head != NULL) xfree(luf->cs_head); if (luf->cs_prev != NULL) xfree(luf->cs_prev); if (luf->cs_next != NULL) xfree(luf->cs_next); if (luf->flag != NULL) xfree(luf->flag); if (luf->work != NULL) xfree(luf->work); luf->n_max = n_max = n + 100; luf->fr_ptr = xcalloc(1+n_max, sizeof(int)); luf->fr_len = xcalloc(1+n_max, sizeof(int)); luf->fc_ptr = xcalloc(1+n_max, sizeof(int)); luf->fc_len = xcalloc(1+n_max, sizeof(int)); luf->vr_ptr = xcalloc(1+n_max, sizeof(int)); luf->vr_len = xcalloc(1+n_max, sizeof(int)); luf->vr_cap = xcalloc(1+n_max, sizeof(int)); luf->vr_piv = xcalloc(1+n_max, sizeof(double)); luf->vc_ptr = xcalloc(1+n_max, sizeof(int)); luf->vc_len = xcalloc(1+n_max, sizeof(int)); luf->vc_cap = xcalloc(1+n_max, sizeof(int)); luf->pp_row = xcalloc(1+n_max, sizeof(int)); luf->pp_col = xcalloc(1+n_max, sizeof(int)); luf->qq_row = xcalloc(1+n_max, sizeof(int)); luf->qq_col = xcalloc(1+n_max, sizeof(int)); luf->sv_prev = xcalloc(1+n_max+n_max, sizeof(int)); luf->sv_next = xcalloc(1+n_max+n_max, sizeof(int)); luf->vr_max = xcalloc(1+n_max, sizeof(double)); luf->rs_head = xcalloc(1+n_max, sizeof(int)); luf->rs_prev = xcalloc(1+n_max, sizeof(int)); luf->rs_next = xcalloc(1+n_max, sizeof(int)); luf->cs_head = xcalloc(1+n_max, sizeof(int)); luf->cs_prev = xcalloc(1+n_max, sizeof(int)); luf->cs_next = xcalloc(1+n_max, sizeof(int)); luf->flag = xcalloc(1+n_max, sizeof(int)); luf->work = xcalloc(1+n_max, sizeof(double)); done: return; } /*********************************************************************** * initialize - initialize LU-factorization data structures * * This routine initializes data structures for subsequent computing * the LU-factorization of a given matrix A, which is specified by the * formal routine col. On exit V = A and F = P = Q = I, where I is the * unity matrix. (Row-wise representation of the matrix F is not used * at the factorization stage and therefore is not initialized.) * * If no error occured, the routine returns zero. Otherwise, in case of * overflow of the sparse vector area, the routine returns non-zero. */ static int initialize(LUF *luf, int (*col)(void *info, int j, int rn[], double aj[]), void *info) { int n = luf->n; int *fc_ptr = luf->fc_ptr; int *fc_len = luf->fc_len; int *vr_ptr = luf->vr_ptr; int *vr_len = luf->vr_len; int *vr_cap = luf->vr_cap; int *vc_ptr = luf->vc_ptr; int *vc_len = luf->vc_len; int *vc_cap = luf->vc_cap; int *pp_row = luf->pp_row; int *pp_col = luf->pp_col; int *qq_row = luf->qq_row; int *qq_col = luf->qq_col; int *sv_ind = luf->sv_ind; double *sv_val = luf->sv_val; int *sv_prev = luf->sv_prev; int *sv_next = luf->sv_next; double *vr_max = luf->vr_max; int *rs_head = luf->rs_head; int *rs_prev = luf->rs_prev; int *rs_next = luf->rs_next; int *cs_head = luf->cs_head; int *cs_prev = luf->cs_prev; int *cs_next = luf->cs_next; int *flag = luf->flag; double *work = luf->work; int ret = 0; int i, i_ptr, j, j_beg, j_end, k, len, nnz, sv_beg, sv_end, ptr; double big, val; /* free all locations of the sparse vector area */ sv_beg = 1; sv_end = luf->sv_size + 1; /* (row-wise representation of the matrix F is not initialized, because it is not used at the factorization stage) */ /* build the matrix F in column-wise format (initially F = I) */ for (j = 1; j <= n; j++) { fc_ptr[j] = sv_end; fc_len[j] = 0; } /* clear rows of the matrix V; clear the flag array */ for (i = 1; i <= n; i++) vr_len[i] = vr_cap[i] = 0, flag[i] = 0; /* build the matrix V in column-wise format (initially V = A); count non-zeros in rows of this matrix; count total number of non-zeros; compute largest of absolute values of elements */ nnz = 0; big = 0.0; for (j = 1; j <= n; j++) { int *rn = pp_row; double *aj = work; /* obtain j-th column of the matrix A */ len = col(info, j, rn, aj); if (!(0 <= len && len <= n)) xfault("luf_factorize: j = %d; len = %d; invalid column len" "gth\n", j, len); /* check for free locations */ if (sv_end - sv_beg < len) { /* overflow of the sparse vector area */ ret = 1; goto done; } /* set pointer to the j-th column */ vc_ptr[j] = sv_beg; /* set length of the j-th column */ vc_len[j] = vc_cap[j] = len; /* count total number of non-zeros */ nnz += len; /* walk through elements of the j-th column */ for (ptr = 1; ptr <= len; ptr++) { /* get row index and numerical value of a[i,j] */ i = rn[ptr]; val = aj[ptr]; if (!(1 <= i && i <= n)) xfault("luf_factorize: i = %d; j = %d; invalid row index" "\n", i, j); if (flag[i]) xfault("luf_factorize: i = %d; j = %d; duplicate element" " not allowed\n", i, j); if (val == 0.0) xfault("luf_factorize: i = %d; j = %d; zero element not " "allowed\n", i, j); /* add new element v[i,j] = a[i,j] to j-th column */ sv_ind[sv_beg] = i; sv_val[sv_beg] = val; sv_beg++; /* big := max(big, |a[i,j]|) */ if (val < 0.0) val = - val; if (big < val) big = val; /* mark non-zero in the i-th position of the j-th column */ flag[i] = 1; /* increase length of the i-th row */ vr_cap[i]++; } /* reset all non-zero marks */ for (ptr = 1; ptr <= len; ptr++) flag[rn[ptr]] = 0; } /* allocate rows of the matrix V */ for (i = 1; i <= n; i++) { /* get length of the i-th row */ len = vr_cap[i]; /* check for free locations */ if (sv_end - sv_beg < len) { /* overflow of the sparse vector area */ ret = 1; goto done; } /* set pointer to the i-th row */ vr_ptr[i] = sv_beg; /* reserve locations for the i-th row */ sv_beg += len; } /* build the matrix V in row-wise format using representation of this matrix in column-wise format */ for (j = 1; j <= n; j++) { /* walk through elements of the j-th column */ j_beg = vc_ptr[j]; j_end = j_beg + vc_len[j] - 1; for (k = j_beg; k <= j_end; k++) { /* get row index and numerical value of v[i,j] */ i = sv_ind[k]; val = sv_val[k]; /* store element in the i-th row */ i_ptr = vr_ptr[i] + vr_len[i]; sv_ind[i_ptr] = j; sv_val[i_ptr] = val; /* increase count of the i-th row */ vr_len[i]++; } } /* initialize the matrices P and Q (initially P = Q = I) */ for (k = 1; k <= n; k++) pp_row[k] = pp_col[k] = qq_row[k] = qq_col[k] = k; /* set sva partitioning pointers */ luf->sv_beg = sv_beg; luf->sv_end = sv_end; /* the initial physical order of rows and columns of the matrix V is n+1, ..., n+n, 1, ..., n (firstly columns, then rows) */ luf->sv_head = n+1; luf->sv_tail = n; for (i = 1; i <= n; i++) { sv_prev[i] = i-1; sv_next[i] = i+1; } sv_prev[1] = n+n; sv_next[n] = 0; for (j = 1; j <= n; j++) { sv_prev[n+j] = n+j-1; sv_next[n+j] = n+j+1; } sv_prev[n+1] = 0; sv_next[n+n] = 1; /* clear working arrays */ for (k = 1; k <= n; k++) { flag[k] = 0; work[k] = 0.0; } /* initialize some statistics */ luf->nnz_a = nnz; luf->nnz_f = 0; luf->nnz_v = nnz; luf->max_a = big; luf->big_v = big; luf->rank = -1; /* initially the active submatrix is the entire matrix V */ /* largest of absolute values of elements in each active row is unknown yet */ for (i = 1; i <= n; i++) vr_max[i] = -1.0; /* build linked lists of active rows */ for (len = 0; len <= n; len++) rs_head[len] = 0; for (i = 1; i <= n; i++) { len = vr_len[i]; rs_prev[i] = 0; rs_next[i] = rs_head[len]; if (rs_next[i] != 0) rs_prev[rs_next[i]] = i; rs_head[len] = i; } /* build linked lists of active columns */ for (len = 0; len <= n; len++) cs_head[len] = 0; for (j = 1; j <= n; j++) { len = vc_len[j]; cs_prev[j] = 0; cs_next[j] = cs_head[len]; if (cs_next[j] != 0) cs_prev[cs_next[j]] = j; cs_head[len] = j; } done: /* return to the factorizing routine */ return ret; } /*********************************************************************** * find_pivot - choose a pivot element * * This routine chooses a pivot element in the active submatrix of the * matrix U = P*V*Q. * * It is assumed that on entry the matrix U has the following partially * triangularized form: * * 1 k n * 1 x x x x x x x x x x * . x x x x x x x x x * . . x x x x x x x x * . . . x x x x x x x * k . . . . * * * * * * * . . . . * * * * * * * . . . . * * * * * * * . . . . * * * * * * * . . . . * * * * * * * n . . . . * * * * * * * * where rows and columns k, k+1, ..., n belong to the active submatrix * (elements of the active submatrix are marked by '*'). * * Since the matrix U = P*V*Q is not stored, the routine works with the * matrix V. It is assumed that the row-wise representation corresponds * to the matrix V, but the column-wise representation corresponds to * the active submatrix of the matrix V, i.e. elements of the matrix V, * which doesn't belong to the active submatrix, are missing from the * column linked lists. It is also assumed that each active row of the * matrix V is in the set R[len], where len is number of non-zeros in * the row, and each active column of the matrix V is in the set C[len], * where len is number of non-zeros in the column (in the latter case * only elements of the active submatrix are counted; such elements are * marked by '*' on the figure above). * * For the reason of numerical stability the routine applies so called * threshold pivoting proposed by J.Reid. It is assumed that an element * v[i,j] can be selected as a pivot candidate if it is not very small * (in absolute value) among other elements in the same row, i.e. if it * satisfies to the stability condition |v[i,j]| >= tol * max|v[i,*]|, * where 0 < tol < 1 is a given tolerance. * * In order to keep sparsity of the matrix V the routine uses Markowitz * strategy, trying to choose such element v[p,q], which satisfies to * the stability condition (see above) and has smallest Markowitz cost * (nr[p]-1) * (nc[q]-1), where nr[p] and nc[q] are numbers of non-zero * elements, respectively, in the p-th row and in the q-th column of the * active submatrix. * * In order to reduce the search, i.e. not to walk through all elements * of the active submatrix, the routine exploits a technique proposed by * I.Duff. This technique is based on using the sets R[len] and C[len] * of active rows and columns. * * If the pivot element v[p,q] has been chosen, the routine stores its * indices to the locations *p and *q and returns zero. Otherwise, if * the active submatrix is empty and therefore the pivot element can't * be chosen, the routine returns non-zero. */ static int find_pivot(LUF *luf, int *_p, int *_q) { int n = luf->n; int *vr_ptr = luf->vr_ptr; int *vr_len = luf->vr_len; int *vc_ptr = luf->vc_ptr; int *vc_len = luf->vc_len; int *sv_ind = luf->sv_ind; double *sv_val = luf->sv_val; double *vr_max = luf->vr_max; int *rs_head = luf->rs_head; int *rs_next = luf->rs_next; int *cs_head = luf->cs_head; int *cs_prev = luf->cs_prev; int *cs_next = luf->cs_next; double piv_tol = luf->piv_tol; int piv_lim = luf->piv_lim; int suhl = luf->suhl; int p, q, len, i, i_beg, i_end, i_ptr, j, j_beg, j_end, j_ptr, ncand, next_j, min_p, min_q, min_len; double best, cost, big, temp; /* initially no pivot candidates have been found so far */ p = q = 0, best = DBL_MAX, ncand = 0; /* if in the active submatrix there is a column that has the only non-zero (column singleton), choose it as pivot */ j = cs_head[1]; if (j != 0) { xassert(vc_len[j] == 1); p = sv_ind[vc_ptr[j]], q = j; goto done; } /* if in the active submatrix there is a row that has the only non-zero (row singleton), choose it as pivot */ i = rs_head[1]; if (i != 0) { xassert(vr_len[i] == 1); p = i, q = sv_ind[vr_ptr[i]]; goto done; } /* there are no singletons in the active submatrix; walk through other non-empty rows and columns */ for (len = 2; len <= n; len++) { /* consider active columns that have len non-zeros */ for (j = cs_head[len]; j != 0; j = next_j) { /* the j-th column has len non-zeros */ j_beg = vc_ptr[j]; j_end = j_beg + vc_len[j] - 1; /* save pointer to the next column with the same length */ next_j = cs_next[j]; /* find an element in the j-th column, which is placed in a row with minimal number of non-zeros and satisfies to the stability condition (such element may not exist) */ min_p = min_q = 0, min_len = INT_MAX; for (j_ptr = j_beg; j_ptr <= j_end; j_ptr++) { /* get row index of v[i,j] */ i = sv_ind[j_ptr]; i_beg = vr_ptr[i]; i_end = i_beg + vr_len[i] - 1; /* if the i-th row is not shorter than that one, where minimal element is currently placed, skip v[i,j] */ if (vr_len[i] >= min_len) continue; /* determine the largest of absolute values of elements in the i-th row */ big = vr_max[i]; if (big < 0.0) { /* the largest value is unknown yet; compute it */ for (i_ptr = i_beg; i_ptr <= i_end; i_ptr++) { temp = sv_val[i_ptr]; if (temp < 0.0) temp = - temp; if (big < temp) big = temp; } vr_max[i] = big; } /* find v[i,j] in the i-th row */ for (i_ptr = vr_ptr[i]; sv_ind[i_ptr] != j; i_ptr++); xassert(i_ptr <= i_end); /* if v[i,j] doesn't satisfy to the stability condition, skip it */ temp = sv_val[i_ptr]; if (temp < 0.0) temp = - temp; if (temp < piv_tol * big) continue; /* v[i,j] is better than the current minimal element */ min_p = i, min_q = j, min_len = vr_len[i]; /* if Markowitz cost of the current minimal element is not greater than (len-1)**2, it can be chosen right now; this heuristic reduces the search and works well in many cases */ if (min_len <= len) { p = min_p, q = min_q; goto done; } } /* the j-th column has been scanned */ if (min_p != 0) { /* the minimal element is a next pivot candidate */ ncand++; /* compute its Markowitz cost */ cost = (double)(min_len - 1) * (double)(len - 1); /* choose between the minimal element and the current candidate */ if (cost < best) p = min_p, q = min_q, best = cost; /* if piv_lim candidates have been considered, there are doubts that a much better candidate exists; therefore it's time to terminate the search */ if (ncand == piv_lim) goto done; } else { /* the j-th column has no elements, which satisfy to the stability condition; Uwe Suhl suggests to exclude such column from the further consideration until it becomes a column singleton; in hard cases this significantly reduces a time needed for pivot searching */ if (suhl) { /* remove the j-th column from the active set */ if (cs_prev[j] == 0) cs_head[len] = cs_next[j]; else cs_next[cs_prev[j]] = cs_next[j]; if (cs_next[j] == 0) /* nop */; else cs_prev[cs_next[j]] = cs_prev[j]; /* the following assignment is used to avoid an error when the routine eliminate (see below) will try to remove the j-th column from the active set */ cs_prev[j] = cs_next[j] = j; } } } /* consider active rows that have len non-zeros */ for (i = rs_head[len]; i != 0; i = rs_next[i]) { /* the i-th row has len non-zeros */ i_beg = vr_ptr[i]; i_end = i_beg + vr_len[i] - 1; /* determine the largest of absolute values of elements in the i-th row */ big = vr_max[i]; if (big < 0.0) { /* the largest value is unknown yet; compute it */ for (i_ptr = i_beg; i_ptr <= i_end; i_ptr++) { temp = sv_val[i_ptr]; if (temp < 0.0) temp = - temp; if (big < temp) big = temp; } vr_max[i] = big; } /* find an element in the i-th row, which is placed in a column with minimal number of non-zeros and satisfies to the stability condition (such element always exists) */ min_p = min_q = 0, min_len = INT_MAX; for (i_ptr = i_beg; i_ptr <= i_end; i_ptr++) { /* get column index of v[i,j] */ j = sv_ind[i_ptr]; /* if the j-th column is not shorter than that one, where minimal element is currently placed, skip v[i,j] */ if (vc_len[j] >= min_len) continue; /* if v[i,j] doesn't satisfy to the stability condition, skip it */ temp = sv_val[i_ptr]; if (temp < 0.0) temp = - temp; if (temp < piv_tol * big) continue; /* v[i,j] is better than the current minimal element */ min_p = i, min_q = j, min_len = vc_len[j]; /* if Markowitz cost of the current minimal element is not greater than (len-1)**2, it can be chosen right now; this heuristic reduces the search and works well in many cases */ if (min_len <= len) { p = min_p, q = min_q; goto done; } } /* the i-th row has been scanned */ if (min_p != 0) { /* the minimal element is a next pivot candidate */ ncand++; /* compute its Markowitz cost */ cost = (double)(len - 1) * (double)(min_len - 1); /* choose between the minimal element and the current candidate */ if (cost < best) p = min_p, q = min_q, best = cost; /* if piv_lim candidates have been considered, there are doubts that a much better candidate exists; therefore it's time to terminate the search */ if (ncand == piv_lim) goto done; } else { /* this can't be because this can never be */ xassert(min_p != min_p); } } } done: /* bring the pivot to the factorizing routine */ *_p = p, *_q = q; return (p == 0); } /*********************************************************************** * eliminate - perform gaussian elimination. * * This routine performs elementary gaussian transformations in order * to eliminate subdiagonal elements in the k-th column of the matrix * U = P*V*Q using the pivot element u[k,k], where k is the number of * the current elimination step. * * The parameters p and q are, respectively, row and column indices of * the element v[p,q], which corresponds to the element u[k,k]. * * Each time when the routine applies the elementary transformation to * a non-pivot row of the matrix V, it stores the corresponding element * to the matrix F in order to keep the main equality A = F*V. * * The routine assumes that on entry the matrices L = P*F*inv(P) and * U = P*V*Q are the following: * * 1 k 1 k n * 1 1 . . . . . . . . . 1 x x x x x x x x x x * x 1 . . . . . . . . . x x x x x x x x x * x x 1 . . . . . . . . . x x x x x x x x * x x x 1 . . . . . . . . . x x x x x x x * k x x x x 1 . . . . . k . . . . * * * * * * * x x x x _ 1 . . . . . . . . # * * * * * * x x x x _ . 1 . . . . . . . # * * * * * * x x x x _ . . 1 . . . . . . # * * * * * * x x x x _ . . . 1 . . . . . # * * * * * * n x x x x _ . . . . 1 n . . . . # * * * * * * * matrix L matrix U * * where rows and columns of the matrix U with numbers k, k+1, ..., n * form the active submatrix (eliminated elements are marked by '#' and * other elements of the active submatrix are marked by '*'). Note that * each eliminated non-zero element u[i,k] of the matrix U gives the * corresponding element l[i,k] of the matrix L (marked by '_'). * * Actually all operations are performed on the matrix V. Should note * that the row-wise representation corresponds to the matrix V, but the * column-wise representation corresponds to the active submatrix of the * matrix V, i.e. elements of the matrix V, which doesn't belong to the * active submatrix, are missing from the column linked lists. * * Let u[k,k] = v[p,q] be the pivot. In order to eliminate subdiagonal * elements u[i',k] = v[i,q], i' = k+1, k+2, ..., n, the routine applies * the following elementary gaussian transformations: * * (i-th row of V) := (i-th row of V) - f[i,p] * (p-th row of V), * * where f[i,p] = v[i,q] / v[p,q] is a gaussian multiplier. * * Additionally, in order to keep the main equality A = F*V, each time * when the routine applies the transformation to i-th row of the matrix * V, it also adds f[i,p] as a new element to the matrix F. * * IMPORTANT: On entry the working arrays flag and work should contain * zeros. This status is provided by the routine on exit. * * If no error occured, the routine returns zero. Otherwise, in case of * overflow of the sparse vector area, the routine returns non-zero. */ static int eliminate(LUF *luf, int p, int q) { int n = luf->n; int *fc_ptr = luf->fc_ptr; int *fc_len = luf->fc_len; int *vr_ptr = luf->vr_ptr; int *vr_len = luf->vr_len; int *vr_cap = luf->vr_cap; double *vr_piv = luf->vr_piv; int *vc_ptr = luf->vc_ptr; int *vc_len = luf->vc_len; int *vc_cap = luf->vc_cap; int *sv_ind = luf->sv_ind; double *sv_val = luf->sv_val; int *sv_prev = luf->sv_prev; int *sv_next = luf->sv_next; double *vr_max = luf->vr_max; int *rs_head = luf->rs_head; int *rs_prev = luf->rs_prev; int *rs_next = luf->rs_next; int *cs_head = luf->cs_head; int *cs_prev = luf->cs_prev; int *cs_next = luf->cs_next; int *flag = luf->flag; double *work = luf->work; double eps_tol = luf->eps_tol; /* at this stage the row-wise representation of the matrix F is not used, so fr_len can be used as a working array */ int *ndx = luf->fr_len; int ret = 0; int len, fill, i, i_beg, i_end, i_ptr, j, j_beg, j_end, j_ptr, k, p_beg, p_end, p_ptr, q_beg, q_end, q_ptr; double fip, val, vpq, temp; xassert(1 <= p && p <= n); xassert(1 <= q && q <= n); /* remove the p-th (pivot) row from the active set; this row will never return there */ if (rs_prev[p] == 0) rs_head[vr_len[p]] = rs_next[p]; else rs_next[rs_prev[p]] = rs_next[p]; if (rs_next[p] == 0) ; else rs_prev[rs_next[p]] = rs_prev[p]; /* remove the q-th (pivot) column from the active set; this column will never return there */ if (cs_prev[q] == 0) cs_head[vc_len[q]] = cs_next[q]; else cs_next[cs_prev[q]] = cs_next[q]; if (cs_next[q] == 0) ; else cs_prev[cs_next[q]] = cs_prev[q]; /* find the pivot v[p,q] = u[k,k] in the p-th row */ p_beg = vr_ptr[p]; p_end = p_beg + vr_len[p] - 1; for (p_ptr = p_beg; sv_ind[p_ptr] != q; p_ptr++) /* nop */; xassert(p_ptr <= p_end); /* store value of the pivot */ vpq = (vr_piv[p] = sv_val[p_ptr]); /* remove the pivot from the p-th row */ sv_ind[p_ptr] = sv_ind[p_end]; sv_val[p_ptr] = sv_val[p_end]; vr_len[p]--; p_end--; /* find the pivot v[p,q] = u[k,k] in the q-th column */ q_beg = vc_ptr[q]; q_end = q_beg + vc_len[q] - 1; for (q_ptr = q_beg; sv_ind[q_ptr] != p; q_ptr++) /* nop */; xassert(q_ptr <= q_end); /* remove the pivot from the q-th column */ sv_ind[q_ptr] = sv_ind[q_end]; vc_len[q]--; q_end--; /* walk through the p-th (pivot) row, which doesn't contain the pivot v[p,q] already, and do the following... */ for (p_ptr = p_beg; p_ptr <= p_end; p_ptr++) { /* get column index of v[p,j] */ j = sv_ind[p_ptr]; /* store v[p,j] to the working array */ flag[j] = 1; work[j] = sv_val[p_ptr]; /* remove the j-th column from the active set; this column will return there later with new length */ if (cs_prev[j] == 0) cs_head[vc_len[j]] = cs_next[j]; else cs_next[cs_prev[j]] = cs_next[j]; if (cs_next[j] == 0) ; else cs_prev[cs_next[j]] = cs_prev[j]; /* find v[p,j] in the j-th column */ j_beg = vc_ptr[j]; j_end = j_beg + vc_len[j] - 1; for (j_ptr = j_beg; sv_ind[j_ptr] != p; j_ptr++) /* nop */; xassert(j_ptr <= j_end); /* since v[p,j] leaves the active submatrix, remove it from the j-th column; however, v[p,j] is kept in the p-th row */ sv_ind[j_ptr] = sv_ind[j_end]; vc_len[j]--; } /* walk through the q-th (pivot) column, which doesn't contain the pivot v[p,q] already, and perform gaussian elimination */ while (q_beg <= q_end) { /* element v[i,q] should be eliminated */ /* get row index of v[i,q] */ i = sv_ind[q_beg]; /* remove the i-th row from the active set; later this row will return there with new length */ if (rs_prev[i] == 0) rs_head[vr_len[i]] = rs_next[i]; else rs_next[rs_prev[i]] = rs_next[i]; if (rs_next[i] == 0) ; else rs_prev[rs_next[i]] = rs_prev[i]; /* find v[i,q] in the i-th row */ i_beg = vr_ptr[i]; i_end = i_beg + vr_len[i] - 1; for (i_ptr = i_beg; sv_ind[i_ptr] != q; i_ptr++) /* nop */; xassert(i_ptr <= i_end); /* compute gaussian multiplier f[i,p] = v[i,q] / v[p,q] */ fip = sv_val[i_ptr] / vpq; /* since v[i,q] should be eliminated, remove it from the i-th row */ sv_ind[i_ptr] = sv_ind[i_end]; sv_val[i_ptr] = sv_val[i_end]; vr_len[i]--; i_end--; /* and from the q-th column */ sv_ind[q_beg] = sv_ind[q_end]; vc_len[q]--; q_end--; /* perform gaussian transformation: (i-th row) := (i-th row) - f[i,p] * (p-th row) note that now the p-th row, which is in the working array, doesn't contain the pivot v[p,q], and the i-th row doesn't contain the eliminated element v[i,q] */ /* walk through the i-th row and transform existing non-zero elements */ fill = vr_len[p]; for (i_ptr = i_beg; i_ptr <= i_end; i_ptr++) { /* get column index of v[i,j] */ j = sv_ind[i_ptr]; /* v[i,j] := v[i,j] - f[i,p] * v[p,j] */ if (flag[j]) { /* v[p,j] != 0 */ temp = (sv_val[i_ptr] -= fip * work[j]); if (temp < 0.0) temp = - temp; flag[j] = 0; fill--; /* since both v[i,j] and v[p,j] exist */ if (temp == 0.0 || temp < eps_tol) { /* new v[i,j] is closer to zero; replace it by exact zero, i.e. remove it from the active submatrix */ /* remove v[i,j] from the i-th row */ sv_ind[i_ptr] = sv_ind[i_end]; sv_val[i_ptr] = sv_val[i_end]; vr_len[i]--; i_ptr--; i_end--; /* find v[i,j] in the j-th column */ j_beg = vc_ptr[j]; j_end = j_beg + vc_len[j] - 1; for (j_ptr = j_beg; sv_ind[j_ptr] != i; j_ptr++); xassert(j_ptr <= j_end); /* remove v[i,j] from the j-th column */ sv_ind[j_ptr] = sv_ind[j_end]; vc_len[j]--; } else { /* v_big := max(v_big, |v[i,j]|) */ if (luf->big_v < temp) luf->big_v = temp; } } } /* now flag is the pattern of the set v[p,*] \ v[i,*], and fill is number of non-zeros in this set; therefore up to fill new non-zeros may appear in the i-th row */ if (vr_len[i] + fill > vr_cap[i]) { /* enlarge the i-th row */ if (luf_enlarge_row(luf, i, vr_len[i] + fill)) { /* overflow of the sparse vector area */ ret = 1; goto done; } /* defragmentation may change row and column pointers of the matrix V */ p_beg = vr_ptr[p]; p_end = p_beg + vr_len[p] - 1; q_beg = vc_ptr[q]; q_end = q_beg + vc_len[q] - 1; } /* walk through the p-th (pivot) row and create new elements of the i-th row that appear due to fill-in; column indices of these new elements are accumulated in the array ndx */ len = 0; for (p_ptr = p_beg; p_ptr <= p_end; p_ptr++) { /* get column index of v[p,j], which may cause fill-in */ j = sv_ind[p_ptr]; if (flag[j]) { /* compute new non-zero v[i,j] = 0 - f[i,p] * v[p,j] */ temp = (val = - fip * work[j]); if (temp < 0.0) temp = - temp; if (temp == 0.0 || temp < eps_tol) /* if v[i,j] is closer to zero; just ignore it */; else { /* add v[i,j] to the i-th row */ i_ptr = vr_ptr[i] + vr_len[i]; sv_ind[i_ptr] = j; sv_val[i_ptr] = val; vr_len[i]++; /* remember column index of v[i,j] */ ndx[++len] = j; /* big_v := max(big_v, |v[i,j]|) */ if (luf->big_v < temp) luf->big_v = temp; } } else { /* there is no fill-in, because v[i,j] already exists in the i-th row; restore the flag of the element v[p,j], which was reset before */ flag[j] = 1; } } /* add new non-zeros v[i,j] to the corresponding columns */ for (k = 1; k <= len; k++) { /* get column index of new non-zero v[i,j] */ j = ndx[k]; /* one free location is needed in the j-th column */ if (vc_len[j] + 1 > vc_cap[j]) { /* enlarge the j-th column */ if (luf_enlarge_col(luf, j, vc_len[j] + 10)) { /* overflow of the sparse vector area */ ret = 1; goto done; } /* defragmentation may change row and column pointers of the matrix V */ p_beg = vr_ptr[p]; p_end = p_beg + vr_len[p] - 1; q_beg = vc_ptr[q]; q_end = q_beg + vc_len[q] - 1; } /* add new non-zero v[i,j] to the j-th column */ j_ptr = vc_ptr[j] + vc_len[j]; sv_ind[j_ptr] = i; vc_len[j]++; } /* now the i-th row has been completely transformed, therefore it can return to the active set with new length */ rs_prev[i] = 0; rs_next[i] = rs_head[vr_len[i]]; if (rs_next[i] != 0) rs_prev[rs_next[i]] = i; rs_head[vr_len[i]] = i; /* the largest of absolute values of elements in the i-th row is currently unknown */ vr_max[i] = -1.0; /* at least one free location is needed to store the gaussian multiplier */ if (luf->sv_end - luf->sv_beg < 1) { /* there are no free locations at all; defragment SVA */ luf_defrag_sva(luf); if (luf->sv_end - luf->sv_beg < 1) { /* overflow of the sparse vector area */ ret = 1; goto done; } /* defragmentation may change row and column pointers of the matrix V */ p_beg = vr_ptr[p]; p_end = p_beg + vr_len[p] - 1; q_beg = vc_ptr[q]; q_end = q_beg + vc_len[q] - 1; } /* add the element f[i,p], which is the gaussian multiplier, to the matrix F */ luf->sv_end--; sv_ind[luf->sv_end] = i; sv_val[luf->sv_end] = fip; fc_len[p]++; /* end of elimination loop */ } /* at this point the q-th (pivot) column should be empty */ xassert(vc_len[q] == 0); /* reset capacity of the q-th column */ vc_cap[q] = 0; /* remove node of the q-th column from the addressing list */ k = n + q; if (sv_prev[k] == 0) luf->sv_head = sv_next[k]; else sv_next[sv_prev[k]] = sv_next[k]; if (sv_next[k] == 0) luf->sv_tail = sv_prev[k]; else sv_prev[sv_next[k]] = sv_prev[k]; /* the p-th column of the matrix F has been completely built; set its pointer */ fc_ptr[p] = luf->sv_end; /* walk through the p-th (pivot) row and do the following... */ for (p_ptr = p_beg; p_ptr <= p_end; p_ptr++) { /* get column index of v[p,j] */ j = sv_ind[p_ptr]; /* erase v[p,j] from the working array */ flag[j] = 0; work[j] = 0.0; /* the j-th column has been completely transformed, therefore it can return to the active set with new length; however the special case c_prev[j] = c_next[j] = j means that the routine find_pivot excluded the j-th column from the active set due to Uwe Suhl's rule, and therefore in this case the column can return to the active set only if it is a column singleton */ if (!(vc_len[j] != 1 && cs_prev[j] == j && cs_next[j] == j)) { cs_prev[j] = 0; cs_next[j] = cs_head[vc_len[j]]; if (cs_next[j] != 0) cs_prev[cs_next[j]] = j; cs_head[vc_len[j]] = j; } } done: /* return to the factorizing routine */ return ret; } /*********************************************************************** * build_v_cols - build the matrix V in column-wise format * * This routine builds the column-wise representation of the matrix V * using its row-wise representation. * * If no error occured, the routine returns zero. Otherwise, in case of * overflow of the sparse vector area, the routine returns non-zero. */ static int build_v_cols(LUF *luf) { int n = luf->n; int *vr_ptr = luf->vr_ptr; int *vr_len = luf->vr_len; int *vc_ptr = luf->vc_ptr; int *vc_len = luf->vc_len; int *vc_cap = luf->vc_cap; int *sv_ind = luf->sv_ind; double *sv_val = luf->sv_val; int *sv_prev = luf->sv_prev; int *sv_next = luf->sv_next; int ret = 0; int i, i_beg, i_end, i_ptr, j, j_ptr, k, nnz; /* it is assumed that on entry all columns of the matrix V are empty, i.e. vc_len[j] = vc_cap[j] = 0 for all j = 1, ..., n, and have been removed from the addressing list */ /* count non-zeros in columns of the matrix V; count total number of non-zeros in this matrix */ nnz = 0; for (i = 1; i <= n; i++) { /* walk through elements of the i-th row and count non-zeros in the corresponding columns */ i_beg = vr_ptr[i]; i_end = i_beg + vr_len[i] - 1; for (i_ptr = i_beg; i_ptr <= i_end; i_ptr++) vc_cap[sv_ind[i_ptr]]++; /* count total number of non-zeros */ nnz += vr_len[i]; } /* store total number of non-zeros */ luf->nnz_v = nnz; /* check for free locations */ if (luf->sv_end - luf->sv_beg < nnz) { /* overflow of the sparse vector area */ ret = 1; goto done; } /* allocate columns of the matrix V */ for (j = 1; j <= n; j++) { /* set pointer to the j-th column */ vc_ptr[j] = luf->sv_beg; /* reserve locations for the j-th column */ luf->sv_beg += vc_cap[j]; } /* build the matrix V in column-wise format using this matrix in row-wise format */ for (i = 1; i <= n; i++) { /* walk through elements of the i-th row */ i_beg = vr_ptr[i]; i_end = i_beg + vr_len[i] - 1; for (i_ptr = i_beg; i_ptr <= i_end; i_ptr++) { /* get column index */ j = sv_ind[i_ptr]; /* store element in the j-th column */ j_ptr = vc_ptr[j] + vc_len[j]; sv_ind[j_ptr] = i; sv_val[j_ptr] = sv_val[i_ptr]; /* increase length of the j-th column */ vc_len[j]++; } } /* now columns are placed in the sparse vector area behind rows in the order n+1, n+2, ..., n+n; so insert column nodes in the addressing list using this order */ for (k = n+1; k <= n+n; k++) { sv_prev[k] = k-1; sv_next[k] = k+1; } sv_prev[n+1] = luf->sv_tail; sv_next[luf->sv_tail] = n+1; sv_next[n+n] = 0; luf->sv_tail = n+n; done: /* return to the factorizing routine */ return ret; } /*********************************************************************** * build_f_rows - build the matrix F in row-wise format * * This routine builds the row-wise representation of the matrix F using * its column-wise representation. * * If no error occured, the routine returns zero. Otherwise, in case of * overflow of the sparse vector area, the routine returns non-zero. */ static int build_f_rows(LUF *luf) { int n = luf->n; int *fr_ptr = luf->fr_ptr; int *fr_len = luf->fr_len; int *fc_ptr = luf->fc_ptr; int *fc_len = luf->fc_len; int *sv_ind = luf->sv_ind; double *sv_val = luf->sv_val; int ret = 0; int i, j, j_beg, j_end, j_ptr, ptr, nnz; /* clear rows of the matrix F */ for (i = 1; i <= n; i++) fr_len[i] = 0; /* count non-zeros in rows of the matrix F; count total number of non-zeros in this matrix */ nnz = 0; for (j = 1; j <= n; j++) { /* walk through elements of the j-th column and count non-zeros in the corresponding rows */ j_beg = fc_ptr[j]; j_end = j_beg + fc_len[j] - 1; for (j_ptr = j_beg; j_ptr <= j_end; j_ptr++) fr_len[sv_ind[j_ptr]]++; /* increase total number of non-zeros */ nnz += fc_len[j]; } /* store total number of non-zeros */ luf->nnz_f = nnz; /* check for free locations */ if (luf->sv_end - luf->sv_beg < nnz) { /* overflow of the sparse vector area */ ret = 1; goto done; } /* allocate rows of the matrix F */ for (i = 1; i <= n; i++) { /* set pointer to the end of the i-th row; later this pointer will be set to the beginning of the i-th row */ fr_ptr[i] = luf->sv_end; /* reserve locations for the i-th row */ luf->sv_end -= fr_len[i]; } /* build the matrix F in row-wise format using this matrix in column-wise format */ for (j = 1; j <= n; j++) { /* walk through elements of the j-th column */ j_beg = fc_ptr[j]; j_end = j_beg + fc_len[j] - 1; for (j_ptr = j_beg; j_ptr <= j_end; j_ptr++) { /* get row index */ i = sv_ind[j_ptr]; /* store element in the i-th row */ ptr = --fr_ptr[i]; sv_ind[ptr] = j; sv_val[ptr] = sv_val[j_ptr]; } } done: /* return to the factorizing routine */ return ret; } /*********************************************************************** * NAME * * luf_factorize - compute LU-factorization * * SYNOPSIS * * #include "glpluf.h" * int luf_factorize(LUF *luf, int n, int (*col)(void *info, int j, * int ind[], double val[]), void *info); * * DESCRIPTION * * The routine luf_factorize computes LU-factorization of a specified * square matrix A. * * The parameter luf specifies LU-factorization program object created * by the routine luf_create_it. * * The parameter n specifies the order of A, n > 0. * * The formal routine col specifies the matrix A to be factorized. To * obtain j-th column of A the routine luf_factorize calls the routine * col with the parameter j (1 <= j <= n). In response the routine col * should store row indices and numerical values of non-zero elements * of j-th column of A to locations ind[1,...,len] and val[1,...,len], * respectively, where len is the number of non-zeros in j-th column * returned on exit. Neither zero nor duplicate elements are allowed. * * The parameter info is a transit pointer passed to the routine col. * * RETURNS * * 0 LU-factorization has been successfully computed. * * LUF_ESING * The specified matrix is singular within the working precision. * (On some elimination step the active submatrix is exactly zero, * so no pivot can be chosen.) * * LUF_ECOND * The specified matrix is ill-conditioned. * (On some elimination step too intensive growth of elements of the * active submatix has been detected.) * * If matrix A is well scaled, the return code LUF_ECOND may also mean * that the threshold pivoting tolerance piv_tol should be increased. * * In case of non-zero return code the factorization becomes invalid. * It should not be used in other operations until the cause of failure * has been eliminated and the factorization has been recomputed again * with the routine luf_factorize. * * REPAIRING SINGULAR MATRIX * * If the routine luf_factorize returns non-zero code, it provides all * necessary information that can be used for "repairing" the matrix A, * where "repairing" means replacing linearly dependent columns of the * matrix A by appropriate columns of the unity matrix. This feature is * needed when this routine is used for factorizing the basis matrix * within the simplex method procedure. * * On exit linearly dependent columns of the (partially transformed) * matrix U have numbers rank+1, rank+2, ..., n, where rank is estimated * rank of the matrix A stored by the routine to the member luf->rank. * The correspondence between columns of A and U is the same as between * columns of V and U. Thus, linearly dependent columns of the matrix A * have numbers qq_col[rank+1], qq_col[rank+2], ..., qq_col[n], where * qq_col is the column-like representation of the permutation matrix Q. * It is understood that each j-th linearly dependent column of the * matrix U should be replaced by the unity vector, where all elements * are zero except the unity diagonal element u[j,j]. On the other hand * j-th row of the matrix U corresponds to the row of the matrix V (and * therefore of the matrix A) with the number pp_row[j], where pp_row is * the row-like representation of the permutation matrix P. Thus, each * j-th linearly dependent column of the matrix U should be replaced by * column of the unity matrix with the number pp_row[j]. * * The code that repairs the matrix A may look like follows: * * for (j = rank+1; j <= n; j++) * { replace the column qq_col[j] of the matrix A by the column * pp_row[j] of the unity matrix; * } * * where rank, pp_row, and qq_col are members of the structure LUF. */ int luf_factorize(LUF *luf, int n, int (*col)(void *info, int j, int ind[], double val[]), void *info) { int *pp_row, *pp_col, *qq_row, *qq_col; double max_gro = luf->max_gro; int i, j, k, p, q, t, ret; if (n < 1) xfault("luf_factorize: n = %d; invalid parameter\n", n); if (n > N_MAX) xfault("luf_factorize: n = %d; matrix too big\n", n); /* invalidate the factorization */ luf->valid = 0; /* reallocate arrays, if necessary */ reallocate(luf, n); pp_row = luf->pp_row; pp_col = luf->pp_col; qq_row = luf->qq_row; qq_col = luf->qq_col; /* estimate initial size of the SVA, if not specified */ if (luf->sv_size == 0 && luf->new_sva == 0) luf->new_sva = 5 * (n + 10); more: /* reallocate the sparse vector area, if required */ if (luf->new_sva > 0) { if (luf->sv_ind != NULL) xfree(luf->sv_ind); if (luf->sv_val != NULL) xfree(luf->sv_val); luf->sv_size = luf->new_sva; luf->sv_ind = xcalloc(1+luf->sv_size, sizeof(int)); luf->sv_val = xcalloc(1+luf->sv_size, sizeof(double)); luf->new_sva = 0; } /* initialize LU-factorization data structures */ if (initialize(luf, col, info)) { /* overflow of the sparse vector area */ luf->new_sva = luf->sv_size + luf->sv_size; xassert(luf->new_sva > luf->sv_size); goto more; } /* main elimination loop */ for (k = 1; k <= n; k++) { /* choose a pivot element v[p,q] */ if (find_pivot(luf, &p, &q)) { /* no pivot can be chosen, because the active submatrix is exactly zero */ luf->rank = k - 1; ret = LUF_ESING; goto done; } /* let v[p,q] correspond to u[i',j']; permute k-th and i'-th rows and k-th and j'-th columns of the matrix U = P*V*Q to move the element u[i',j'] to the position u[k,k] */ i = pp_col[p], j = qq_row[q]; xassert(k <= i && i <= n && k <= j && j <= n); /* permute k-th and i-th rows of the matrix U */ t = pp_row[k]; pp_row[i] = t, pp_col[t] = i; pp_row[k] = p, pp_col[p] = k; /* permute k-th and j-th columns of the matrix U */ t = qq_col[k]; qq_col[j] = t, qq_row[t] = j; qq_col[k] = q, qq_row[q] = k; /* eliminate subdiagonal elements of k-th column of the matrix U = P*V*Q using the pivot element u[k,k] = v[p,q] */ if (eliminate(luf, p, q)) { /* overflow of the sparse vector area */ luf->new_sva = luf->sv_size + luf->sv_size; xassert(luf->new_sva > luf->sv_size); goto more; } /* check relative growth of elements of the matrix V */ if (luf->big_v > max_gro * luf->max_a) { /* the growth is too intensive, therefore most probably the matrix A is ill-conditioned */ luf->rank = k - 1; ret = LUF_ECOND; goto done; } } /* now the matrix U = P*V*Q is upper triangular, the matrix V has been built in row-wise format, and the matrix F has been built in column-wise format */ /* defragment the sparse vector area in order to merge all free locations in one continuous extent */ luf_defrag_sva(luf); /* build the matrix V in column-wise format */ if (build_v_cols(luf)) { /* overflow of the sparse vector area */ luf->new_sva = luf->sv_size + luf->sv_size; xassert(luf->new_sva > luf->sv_size); goto more; } /* build the matrix F in row-wise format */ if (build_f_rows(luf)) { /* overflow of the sparse vector area */ luf->new_sva = luf->sv_size + luf->sv_size; xassert(luf->new_sva > luf->sv_size); goto more; } /* the LU-factorization has been successfully computed */ luf->valid = 1; luf->rank = n; ret = 0; /* if there are few free locations in the sparse vector area, try increasing its size in the future */ t = 3 * (n + luf->nnz_v) + 2 * luf->nnz_f; if (luf->sv_size < t) { luf->new_sva = luf->sv_size; while (luf->new_sva < t) { k = luf->new_sva; luf->new_sva = k + k; xassert(luf->new_sva > k); } } done: /* return to the calling program */ return ret; } /*********************************************************************** * NAME * * luf_f_solve - solve system F*x = b or F'*x = b * * SYNOPSIS * * #include "glpluf.h" * void luf_f_solve(LUF *luf, int tr, double x[]); * * DESCRIPTION * * The routine luf_f_solve solves either the system F*x = b (if the * flag tr is zero) or the system F'*x = b (if the flag tr is non-zero), * where the matrix F is a component of LU-factorization specified by * the parameter luf, F' is a matrix transposed to F. * * On entry the array x should contain elements of the right-hand side * vector b in locations x[1], ..., x[n], where n is the order of the * matrix F. On exit this array will contain elements of the solution * vector x in the same locations. */ void luf_f_solve(LUF *luf, int tr, double x[]) { int n = luf->n; int *fr_ptr = luf->fr_ptr; int *fr_len = luf->fr_len; int *fc_ptr = luf->fc_ptr; int *fc_len = luf->fc_len; int *pp_row = luf->pp_row; int *sv_ind = luf->sv_ind; double *sv_val = luf->sv_val; int i, j, k, beg, end, ptr; double xk; if (!luf->valid) xfault("luf_f_solve: LU-factorization is not valid\n"); if (!tr) { /* solve the system F*x = b */ for (j = 1; j <= n; j++) { k = pp_row[j]; xk = x[k]; if (xk != 0.0) { beg = fc_ptr[k]; end = beg + fc_len[k] - 1; for (ptr = beg; ptr <= end; ptr++) x[sv_ind[ptr]] -= sv_val[ptr] * xk; } } } else { /* solve the system F'*x = b */ for (i = n; i >= 1; i--) { k = pp_row[i]; xk = x[k]; if (xk != 0.0) { beg = fr_ptr[k]; end = beg + fr_len[k] - 1; for (ptr = beg; ptr <= end; ptr++) x[sv_ind[ptr]] -= sv_val[ptr] * xk; } } } return; } /*********************************************************************** * NAME * * luf_v_solve - solve system V*x = b or V'*x = b * * SYNOPSIS * * #include "glpluf.h" * void luf_v_solve(LUF *luf, int tr, double x[]); * * DESCRIPTION * * The routine luf_v_solve solves either the system V*x = b (if the * flag tr is zero) or the system V'*x = b (if the flag tr is non-zero), * where the matrix V is a component of LU-factorization specified by * the parameter luf, V' is a matrix transposed to V. * * On entry the array x should contain elements of the right-hand side * vector b in locations x[1], ..., x[n], where n is the order of the * matrix V. On exit this array will contain elements of the solution * vector x in the same locations. */ void luf_v_solve(LUF *luf, int tr, double x[]) { int n = luf->n; int *vr_ptr = luf->vr_ptr; int *vr_len = luf->vr_len; double *vr_piv = luf->vr_piv; int *vc_ptr = luf->vc_ptr; int *vc_len = luf->vc_len; int *pp_row = luf->pp_row; int *qq_col = luf->qq_col; int *sv_ind = luf->sv_ind; double *sv_val = luf->sv_val; double *b = luf->work; int i, j, k, beg, end, ptr; double temp; if (!luf->valid) xfault("luf_v_solve: LU-factorization is not valid\n"); for (k = 1; k <= n; k++) b[k] = x[k], x[k] = 0.0; if (!tr) { /* solve the system V*x = b */ for (k = n; k >= 1; k--) { i = pp_row[k], j = qq_col[k]; temp = b[i]; if (temp != 0.0) { x[j] = (temp /= vr_piv[i]); beg = vc_ptr[j]; end = beg + vc_len[j] - 1; for (ptr = beg; ptr <= end; ptr++) b[sv_ind[ptr]] -= sv_val[ptr] * temp; } } } else { /* solve the system V'*x = b */ for (k = 1; k <= n; k++) { i = pp_row[k], j = qq_col[k]; temp = b[j]; if (temp != 0.0) { x[i] = (temp /= vr_piv[i]); beg = vr_ptr[i]; end = beg + vr_len[i] - 1; for (ptr = beg; ptr <= end; ptr++) b[sv_ind[ptr]] -= sv_val[ptr] * temp; } } } return; } /*********************************************************************** * NAME * * luf_a_solve - solve system A*x = b or A'*x = b * * SYNOPSIS * * #include "glpluf.h" * void luf_a_solve(LUF *luf, int tr, double x[]); * * DESCRIPTION * * The routine luf_a_solve solves either the system A*x = b (if the * flag tr is zero) or the system A'*x = b (if the flag tr is non-zero), * where the parameter luf specifies LU-factorization of the matrix A, * A' is a matrix transposed to A. * * On entry the array x should contain elements of the right-hand side * vector b in locations x[1], ..., x[n], where n is the order of the * matrix A. On exit this array will contain elements of the solution * vector x in the same locations. */ void luf_a_solve(LUF *luf, int tr, double x[]) { if (!luf->valid) xfault("luf_a_solve: LU-factorization is not valid\n"); if (!tr) { /* A = F*V, therefore inv(A) = inv(V)*inv(F) */ luf_f_solve(luf, 0, x); luf_v_solve(luf, 0, x); } else { /* A' = V'*F', therefore inv(A') = inv(F')*inv(V') */ luf_v_solve(luf, 1, x); luf_f_solve(luf, 1, x); } return; } /*********************************************************************** * NAME * * luf_delete_it - delete LU-factorization * * SYNOPSIS * * #include "glpluf.h" * void luf_delete_it(LUF *luf); * * DESCRIPTION * * The routine luf_delete deletes LU-factorization specified by the * parameter luf and frees all the memory allocated to this program * object. */ void luf_delete_it(LUF *luf) { if (luf->fr_ptr != NULL) xfree(luf->fr_ptr); if (luf->fr_len != NULL) xfree(luf->fr_len); if (luf->fc_ptr != NULL) xfree(luf->fc_ptr); if (luf->fc_len != NULL) xfree(luf->fc_len); if (luf->vr_ptr != NULL) xfree(luf->vr_ptr); if (luf->vr_len != NULL) xfree(luf->vr_len); if (luf->vr_cap != NULL) xfree(luf->vr_cap); if (luf->vr_piv != NULL) xfree(luf->vr_piv); if (luf->vc_ptr != NULL) xfree(luf->vc_ptr); if (luf->vc_len != NULL) xfree(luf->vc_len); if (luf->vc_cap != NULL) xfree(luf->vc_cap); if (luf->pp_row != NULL) xfree(luf->pp_row); if (luf->pp_col != NULL) xfree(luf->pp_col); if (luf->qq_row != NULL) xfree(luf->qq_row); if (luf->qq_col != NULL) xfree(luf->qq_col); if (luf->sv_ind != NULL) xfree(luf->sv_ind); if (luf->sv_val != NULL) xfree(luf->sv_val); if (luf->sv_prev != NULL) xfree(luf->sv_prev); if (luf->sv_next != NULL) xfree(luf->sv_next); if (luf->vr_max != NULL) xfree(luf->vr_max); if (luf->rs_head != NULL) xfree(luf->rs_head); if (luf->rs_prev != NULL) xfree(luf->rs_prev); if (luf->rs_next != NULL) xfree(luf->rs_next); if (luf->cs_head != NULL) xfree(luf->cs_head); if (luf->cs_prev != NULL) xfree(luf->cs_prev); if (luf->cs_next != NULL) xfree(luf->cs_next); if (luf->flag != NULL) xfree(luf->flag); if (luf->work != NULL) xfree(luf->work); xfree(luf); return; } /* eof */ praat-6.0.04/external/glpk/glpluf.h000066400000000000000000000354621261542461700171530ustar00rootroot00000000000000/* glpluf.h (LU-factorization) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPLUF_H #define GLPLUF_H /*********************************************************************** * The structure LUF defines LU-factorization of a square matrix A and * is the following quartet: * * [A] = (F, V, P, Q), (1) * * where F and V are such matrices that * * A = F * V, (2) * * and P and Q are such permutation matrices that the matrix * * L = P * F * inv(P) (3) * * is lower triangular with unity diagonal, and the matrix * * U = P * V * Q (4) * * is upper triangular. All the matrices have the order n. * * Matrices F and V are stored in row- and column-wise sparse format * as row and column linked lists of non-zero elements. Unity elements * on the main diagonal of matrix F are not stored. Pivot elements of * matrix V (which correspond to diagonal elements of matrix U) are * stored separately in an ordinary array. * * Permutation matrices P and Q are stored in ordinary arrays in both * row- and column-like formats. * * Matrices L and U are completely defined by matrices F, V, P, and Q * and therefore not stored explicitly. * * The factorization (1)-(4) is a version of LU-factorization. Indeed, * from (3) and (4) it follows that: * * F = inv(P) * L * P, * * U = inv(P) * U * inv(Q), * * and substitution into (2) leads to: * * A = F * V = inv(P) * L * U * inv(Q). * * For more details see the program documentation. */ typedef struct LUF LUF; struct LUF { /* LU-factorization of a square matrix */ int n_max; /* maximal value of n (increased automatically, if necessary) */ int n; /* the order of matrices A, F, V, P, Q */ int valid; /* the factorization is valid only if this flag is set */ /*--------------------------------------------------------------*/ /* matrix F in row-wise format */ int *fr_ptr; /* int fr_ptr[1+n_max]; */ /* fr_ptr[i], i = 1,...,n, is a pointer to the first element of i-th row in SVA */ int *fr_len; /* int fr_len[1+n_max]; */ /* fr_len[i], i = 1,...,n, is the number of elements in i-th row (except unity diagonal element) */ /*--------------------------------------------------------------*/ /* matrix F in column-wise format */ int *fc_ptr; /* int fc_ptr[1+n_max]; */ /* fc_ptr[j], j = 1,...,n, is a pointer to the first element of j-th column in SVA */ int *fc_len; /* int fc_len[1+n_max]; */ /* fc_len[j], j = 1,...,n, is the number of elements in j-th column (except unity diagonal element) */ /*--------------------------------------------------------------*/ /* matrix V in row-wise format */ int *vr_ptr; /* int vr_ptr[1+n_max]; */ /* vr_ptr[i], i = 1,...,n, is a pointer to the first element of i-th row in SVA */ int *vr_len; /* int vr_len[1+n_max]; */ /* vr_len[i], i = 1,...,n, is the number of elements in i-th row (except pivot element) */ int *vr_cap; /* int vr_cap[1+n_max]; */ /* vr_cap[i], i = 1,...,n, is the capacity of i-th row, i.e. maximal number of elements which can be stored in the row without relocating it, vr_cap[i] >= vr_len[i] */ double *vr_piv; /* double vr_piv[1+n_max]; */ /* vr_piv[p], p = 1,...,n, is the pivot element v[p,q] which corresponds to a diagonal element of matrix U = P*V*Q */ /*--------------------------------------------------------------*/ /* matrix V in column-wise format */ int *vc_ptr; /* int vc_ptr[1+n_max]; */ /* vc_ptr[j], j = 1,...,n, is a pointer to the first element of j-th column in SVA */ int *vc_len; /* int vc_len[1+n_max]; */ /* vc_len[j], j = 1,...,n, is the number of elements in j-th column (except pivot element) */ int *vc_cap; /* int vc_cap[1+n_max]; */ /* vc_cap[j], j = 1,...,n, is the capacity of j-th column, i.e. maximal number of elements which can be stored in the column without relocating it, vc_cap[j] >= vc_len[j] */ /*--------------------------------------------------------------*/ /* matrix P */ int *pp_row; /* int pp_row[1+n_max]; */ /* pp_row[i] = j means that P[i,j] = 1 */ int *pp_col; /* int pp_col[1+n_max]; */ /* pp_col[j] = i means that P[i,j] = 1 */ /* if i-th row or column of matrix F is i'-th row or column of matrix L, or if i-th row of matrix V is i'-th row of matrix U, then pp_row[i'] = i and pp_col[i] = i' */ /*--------------------------------------------------------------*/ /* matrix Q */ int *qq_row; /* int qq_row[1+n_max]; */ /* qq_row[i] = j means that Q[i,j] = 1 */ int *qq_col; /* int qq_col[1+n_max]; */ /* qq_col[j] = i means that Q[i,j] = 1 */ /* if j-th column of matrix V is j'-th column of matrix U, then qq_row[j] = j' and qq_col[j'] = j */ /*--------------------------------------------------------------*/ /* the Sparse Vector Area (SVA) is a set of locations used to store sparse vectors representing rows and columns of matrices F and V; each location is a doublet (ind, val), where ind is an index, and val is a numerical value of a sparse vector element; in the whole each sparse vector is a set of adjacent locations defined by a pointer to the first element and the number of elements; these pointer and number are stored in the corresponding matrix data structure (see above); the left part of SVA is used to store rows and columns of matrix V, and its right part is used to store rows and columns of matrix F; the middle part of SVA contains free (unused) locations */ int sv_size; /* the size of SVA, in locations; all locations are numbered by integers 1, ..., n, and location 0 is not used; if necessary, the SVA size is automatically increased */ int sv_beg, sv_end; /* SVA partitioning pointers: locations from 1 to sv_beg-1 belong to the left part locations from sv_beg to sv_end-1 belong to the middle part locations from sv_end to sv_size belong to the right part the size of the middle part is (sv_end - sv_beg) */ int *sv_ind; /* sv_ind[1+sv_size]; */ /* sv_ind[k], 1 <= k <= sv_size, is the index field of k-th location */ double *sv_val; /* sv_val[1+sv_size]; */ /* sv_val[k], 1 <= k <= sv_size, is the value field of k-th location */ /*--------------------------------------------------------------*/ /* in order to efficiently defragment the left part of SVA there is a doubly linked list of rows and columns of matrix V, where rows are numbered by 1, ..., n, while columns are numbered by n+1, ..., n+n, that allows uniquely identifying each row and column of V by only one integer; in this list rows and columns are ordered by ascending their pointers vr_ptr and vc_ptr */ int sv_head; /* the number of leftmost row/column */ int sv_tail; /* the number of rightmost row/column */ int *sv_prev; /* int sv_prev[1+n_max+n_max]; */ /* sv_prev[k], k = 1,...,n+n, is the number of a row/column which precedes k-th row/column */ int *sv_next; /* int sv_next[1+n_max+n_max]; */ /* sv_next[k], k = 1,...,n+n, is the number of a row/column which succedes k-th row/column */ /*--------------------------------------------------------------*/ /* working segment (used only during factorization) */ double *vr_max; /* int vr_max[1+n_max]; */ /* vr_max[i], 1 <= i <= n, is used only if i-th row of matrix V is active (i.e. belongs to the active submatrix), and is the largest magnitude of elements in i-th row; if vr_max[i] < 0, the largest magnitude is not known yet and should be computed by the pivoting routine */ /*--------------------------------------------------------------*/ /* in order to efficiently implement Markowitz strategy and Duff search technique there are two families {R[0], R[1], ..., R[n]} and {C[0], C[1], ..., C[n]}; member R[k] is the set of active rows of matrix V, which have k non-zeros, and member C[k] is the set of active columns of V, which have k non-zeros in the active submatrix (i.e. in the active rows); each set R[k] and C[k] is implemented as a separate doubly linked list */ int *rs_head; /* int rs_head[1+n_max]; */ /* rs_head[k], 0 <= k <= n, is the number of first active row, which has k non-zeros */ int *rs_prev; /* int rs_prev[1+n_max]; */ /* rs_prev[i], 1 <= i <= n, is the number of previous row, which has the same number of non-zeros as i-th row */ int *rs_next; /* int rs_next[1+n_max]; */ /* rs_next[i], 1 <= i <= n, is the number of next row, which has the same number of non-zeros as i-th row */ int *cs_head; /* int cs_head[1+n_max]; */ /* cs_head[k], 0 <= k <= n, is the number of first active column, which has k non-zeros (in the active rows) */ int *cs_prev; /* int cs_prev[1+n_max]; */ /* cs_prev[j], 1 <= j <= n, is the number of previous column, which has the same number of non-zeros (in the active rows) as j-th column */ int *cs_next; /* int cs_next[1+n_max]; */ /* cs_next[j], 1 <= j <= n, is the number of next column, which has the same number of non-zeros (in the active rows) as j-th column */ /* (end of working segment) */ /*--------------------------------------------------------------*/ /* working arrays */ int *flag; /* int flag[1+n_max]; */ /* integer working array */ double *work; /* double work[1+n_max]; */ /* floating-point working array */ /*--------------------------------------------------------------*/ /* control parameters */ int new_sva; /* new required size of the sparse vector area, in locations; set automatically by the factorizing routine */ double piv_tol; /* threshold pivoting tolerance, 0 < piv_tol < 1; element v[i,j] of the active submatrix fits to be pivot if it satisfies to the stability criterion |v[i,j]| >= piv_tol * max |v[i,*]|, i.e. if it is not very small in the magnitude among other elements in the same row; decreasing this parameter gives better sparsity at the expense of numerical accuracy and vice versa */ int piv_lim; /* maximal allowable number of pivot candidates to be considered; if piv_lim pivot candidates have been considered, the pivoting routine terminates the search with the best candidate found */ int suhl; /* if this flag is set, the pivoting routine applies a heuristic proposed by Uwe Suhl: if a column of the active submatrix has no eligible pivot candidates (i.e. all its elements do not satisfy to the stability criterion), the routine excludes it from futher consideration until it becomes column singleton; in many cases this allows reducing the time needed for pivot searching */ double eps_tol; /* epsilon tolerance; each element of the active submatrix, whose magnitude is less than eps_tol, is replaced by exact zero */ double max_gro; /* maximal allowable growth of elements of matrix V during all the factorization process; if on some eliminaion step the ratio big_v / max_a (see below) becomes greater than max_gro, matrix A is considered as ill-conditioned (assuming that the pivoting tolerance piv_tol has an appropriate value) */ /*--------------------------------------------------------------*/ /* some statistics */ int nnz_a; /* the number of non-zeros in matrix A */ int nnz_f; /* the number of non-zeros in matrix F (except diagonal elements, which are not stored) */ int nnz_v; /* the number of non-zeros in matrix V (except its pivot elements, which are stored in a separate array) */ double max_a; /* the largest magnitude of elements of matrix A */ double big_v; /* the largest magnitude of elements of matrix V appeared in the active submatrix during all the factorization process */ int rank; /* estimated rank of matrix A */ }; /* return codes: */ #define LUF_ESING 1 /* singular matrix */ #define LUF_ECOND 2 /* ill-conditioned matrix */ #define luf_create_it _glp_luf_create_it LUF *luf_create_it(void); /* create LU-factorization */ #define luf_defrag_sva _glp_luf_defrag_sva void luf_defrag_sva(LUF *luf); /* defragment the sparse vector area */ #define luf_enlarge_row _glp_luf_enlarge_row int luf_enlarge_row(LUF *luf, int i, int cap); /* enlarge row capacity */ #define luf_enlarge_col _glp_luf_enlarge_col int luf_enlarge_col(LUF *luf, int j, int cap); /* enlarge column capacity */ #define luf_factorize _glp_luf_factorize int luf_factorize(LUF *luf, int n, int (*col)(void *info, int j, int ind[], double val[]), void *info); /* compute LU-factorization */ #define luf_f_solve _glp_luf_f_solve void luf_f_solve(LUF *luf, int tr, double x[]); /* solve system F*x = b or F'*x = b */ #define luf_v_solve _glp_luf_v_solve void luf_v_solve(LUF *luf, int tr, double x[]); /* solve system V*x = b or V'*x = b */ #define luf_a_solve _glp_luf_a_solve void luf_a_solve(LUF *luf, int tr, double x[]); /* solve system A*x = b or A'*x = b */ #define luf_delete_it _glp_luf_delete_it void luf_delete_it(LUF *luf); /* delete LU-factorization */ #endif /* eof */ praat-6.0.04/external/glpk/glplux.c000066400000000000000000001140001261542461700171520ustar00rootroot00000000000000/* glplux.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glplux.h" #define xfault xerror #define dmp_create_poolx(size) dmp_create_pool() /*---------------------------------------------------------------------- // lux_create - create LU-factorization. // // SYNOPSIS // // #include "glplux.h" // LUX *lux_create(int n); // // DESCRIPTION // // The routine lux_create creates LU-factorization data structure for // a matrix of the order n. Initially the factorization corresponds to // the unity matrix (F = V = P = Q = I, so A = I). // // RETURNS // // The routine returns a pointer to the created LU-factorization data // structure, which represents the unity matrix of the order n. */ LUX *lux_create(int n) { LUX *lux; int k; if (n < 1) xfault("lux_create: n = %d; invalid parameter\n", n); lux = xmalloc(sizeof(LUX)); lux->n = n; lux->pool = dmp_create_poolx(sizeof(LUXELM)); lux->F_row = xcalloc(1+n, sizeof(LUXELM *)); lux->F_col = xcalloc(1+n, sizeof(LUXELM *)); lux->V_piv = xcalloc(1+n, sizeof(mpq_t)); lux->V_row = xcalloc(1+n, sizeof(LUXELM *)); lux->V_col = xcalloc(1+n, sizeof(LUXELM *)); lux->P_row = xcalloc(1+n, sizeof(int)); lux->P_col = xcalloc(1+n, sizeof(int)); lux->Q_row = xcalloc(1+n, sizeof(int)); lux->Q_col = xcalloc(1+n, sizeof(int)); for (k = 1; k <= n; k++) { lux->F_row[k] = lux->F_col[k] = NULL; mpq_init(lux->V_piv[k]); mpq_set_si(lux->V_piv[k], 1, 1); lux->V_row[k] = lux->V_col[k] = NULL; lux->P_row[k] = lux->P_col[k] = k; lux->Q_row[k] = lux->Q_col[k] = k; } lux->rank = n; return lux; } /*---------------------------------------------------------------------- // initialize - initialize LU-factorization data structures. // // This routine initializes data structures for subsequent computing // the LU-factorization of a given matrix A, which is specified by the // formal routine col. On exit V = A and F = P = Q = I, where I is the // unity matrix. */ static void initialize(LUX *lux, int (*col)(void *info, int j, int ind[], mpq_t val[]), void *info, LUXWKA *wka) { int n = lux->n; DMP *pool = lux->pool; LUXELM **F_row = lux->F_row; LUXELM **F_col = lux->F_col; mpq_t *V_piv = lux->V_piv; LUXELM **V_row = lux->V_row; LUXELM **V_col = lux->V_col; int *P_row = lux->P_row; int *P_col = lux->P_col; int *Q_row = lux->Q_row; int *Q_col = lux->Q_col; int *R_len = wka->R_len; int *R_head = wka->R_head; int *R_prev = wka->R_prev; int *R_next = wka->R_next; int *C_len = wka->C_len; int *C_head = wka->C_head; int *C_prev = wka->C_prev; int *C_next = wka->C_next; LUXELM *fij, *vij; int i, j, k, len, *ind; mpq_t *val; /* F := I */ for (i = 1; i <= n; i++) { while (F_row[i] != NULL) { fij = F_row[i], F_row[i] = fij->r_next; mpq_clear(fij->val); dmp_free_atom(pool, fij, sizeof(LUXELM)); } } for (j = 1; j <= n; j++) F_col[j] = NULL; /* V := 0 */ for (k = 1; k <= n; k++) mpq_set_si(V_piv[k], 0, 1); for (i = 1; i <= n; i++) { while (V_row[i] != NULL) { vij = V_row[i], V_row[i] = vij->r_next; mpq_clear(vij->val); dmp_free_atom(pool, vij, sizeof(LUXELM)); } } for (j = 1; j <= n; j++) V_col[j] = NULL; /* V := A */ ind = xcalloc(1+n, sizeof(int)); val = xcalloc(1+n, sizeof(mpq_t)); for (k = 1; k <= n; k++) mpq_init(val[k]); for (j = 1; j <= n; j++) { /* obtain j-th column of matrix A */ len = col(info, j, ind, val); if (!(0 <= len && len <= n)) xfault("lux_decomp: j = %d: len = %d; invalid column length" "\n", j, len); /* copy elements of j-th column to matrix V */ for (k = 1; k <= len; k++) { /* get row index of a[i,j] */ i = ind[k]; if (!(1 <= i && i <= n)) xfault("lux_decomp: j = %d: i = %d; row index out of ran" "ge\n", j, i); /* check for duplicate indices */ if (V_row[i] != NULL && V_row[i]->j == j) xfault("lux_decomp: j = %d: i = %d; duplicate row indice" "s not allowed\n", j, i); /* check for zero value */ if (mpq_sgn(val[k]) == 0) xfault("lux_decomp: j = %d: i = %d; zero elements not al" "lowed\n", j, i); /* add new element v[i,j] = a[i,j] to V */ vij = dmp_get_atom(pool, sizeof(LUXELM)); vij->i = i, vij->j = j; mpq_init(vij->val); mpq_set(vij->val, val[k]); vij->r_prev = NULL; vij->r_next = V_row[i]; vij->c_prev = NULL; vij->c_next = V_col[j]; if (vij->r_next != NULL) vij->r_next->r_prev = vij; if (vij->c_next != NULL) vij->c_next->c_prev = vij; V_row[i] = V_col[j] = vij; } } xfree(ind); for (k = 1; k <= n; k++) mpq_clear(val[k]); xfree(val); /* P := Q := I */ for (k = 1; k <= n; k++) P_row[k] = P_col[k] = Q_row[k] = Q_col[k] = k; /* the rank of A and V is not determined yet */ lux->rank = -1; /* initially the entire matrix V is active */ /* determine its row lengths */ for (i = 1; i <= n; i++) { len = 0; for (vij = V_row[i]; vij != NULL; vij = vij->r_next) len++; R_len[i] = len; } /* build linked lists of active rows */ for (len = 0; len <= n; len++) R_head[len] = 0; for (i = 1; i <= n; i++) { len = R_len[i]; R_prev[i] = 0; R_next[i] = R_head[len]; if (R_next[i] != 0) R_prev[R_next[i]] = i; R_head[len] = i; } /* determine its column lengths */ for (j = 1; j <= n; j++) { len = 0; for (vij = V_col[j]; vij != NULL; vij = vij->c_next) len++; C_len[j] = len; } /* build linked lists of active columns */ for (len = 0; len <= n; len++) C_head[len] = 0; for (j = 1; j <= n; j++) { len = C_len[j]; C_prev[j] = 0; C_next[j] = C_head[len]; if (C_next[j] != 0) C_prev[C_next[j]] = j; C_head[len] = j; } return; } /*---------------------------------------------------------------------- // find_pivot - choose a pivot element. // // This routine chooses a pivot element v[p,q] in the active submatrix // of matrix U = P*V*Q. // // It is assumed that on entry the matrix U has the following partially // triangularized form: // // 1 k n // 1 x x x x x x x x x x // . x x x x x x x x x // . . x x x x x x x x // . . . x x x x x x x // k . . . . * * * * * * // . . . . * * * * * * // . . . . * * * * * * // . . . . * * * * * * // . . . . * * * * * * // n . . . . * * * * * * // // where rows and columns k, k+1, ..., n belong to the active submatrix // (elements of the active submatrix are marked by '*'). // // Since the matrix U = P*V*Q is not stored, the routine works with the // matrix V. It is assumed that the row-wise representation corresponds // to the matrix V, but the column-wise representation corresponds to // the active submatrix of the matrix V, i.e. elements of the matrix V, // which does not belong to the active submatrix, are missing from the // column linked lists. It is also assumed that each active row of the // matrix V is in the set R[len], where len is number of non-zeros in // the row, and each active column of the matrix V is in the set C[len], // where len is number of non-zeros in the column (in the latter case // only elements of the active submatrix are counted; such elements are // marked by '*' on the figure above). // // Due to exact arithmetic any non-zero element of the active submatrix // can be chosen as a pivot. However, to keep sparsity of the matrix V // the routine uses Markowitz strategy, trying to choose such element // v[p,q], which has smallest Markowitz cost (nr[p]-1) * (nc[q]-1), // where nr[p] and nc[q] are the number of non-zero elements, resp., in // p-th row and in q-th column of the active submatrix. // // In order to reduce the search, i.e. not to walk through all elements // of the active submatrix, the routine exploits a technique proposed by // I.Duff. This technique is based on using the sets R[len] and C[len] // of active rows and columns. // // On exit the routine returns a pointer to a pivot v[p,q] chosen, or // NULL, if the active submatrix is empty. */ static LUXELM *find_pivot(LUX *lux, LUXWKA *wka) { int n = lux->n; LUXELM **V_row = lux->V_row; LUXELM **V_col = lux->V_col; int *R_len = wka->R_len; int *R_head = wka->R_head; int *R_next = wka->R_next; int *C_len = wka->C_len; int *C_head = wka->C_head; int *C_next = wka->C_next; LUXELM *piv, *some, *vij; int i, j, len, min_len, ncand, piv_lim = 5; double best, cost; /* nothing is chosen so far */ piv = NULL, best = DBL_MAX, ncand = 0; /* if in the active submatrix there is a column that has the only non-zero (column singleton), choose it as a pivot */ j = C_head[1]; if (j != 0) { xassert(C_len[j] == 1); piv = V_col[j]; xassert(piv != NULL && piv->c_next == NULL); goto done; } /* if in the active submatrix there is a row that has the only non-zero (row singleton), choose it as a pivot */ i = R_head[1]; if (i != 0) { xassert(R_len[i] == 1); piv = V_row[i]; xassert(piv != NULL && piv->r_next == NULL); goto done; } /* there are no singletons in the active submatrix; walk through other non-empty rows and columns */ for (len = 2; len <= n; len++) { /* consider active columns having len non-zeros */ for (j = C_head[len]; j != 0; j = C_next[j]) { /* j-th column has len non-zeros */ /* find an element in the row of minimal length */ some = NULL, min_len = INT_MAX; for (vij = V_col[j]; vij != NULL; vij = vij->c_next) { if (min_len > R_len[vij->i]) some = vij, min_len = R_len[vij->i]; /* if Markowitz cost of this element is not greater than (len-1)**2, it can be chosen right now; this heuristic reduces the search and works well in many cases */ if (min_len <= len) { piv = some; goto done; } } /* j-th column has been scanned */ /* the minimal element found is a next pivot candidate */ xassert(some != NULL); ncand++; /* compute its Markowitz cost */ cost = (double)(min_len - 1) * (double)(len - 1); /* choose between the current candidate and this element */ if (cost < best) piv = some, best = cost; /* if piv_lim candidates have been considered, there is a doubt that a much better candidate exists; therefore it is the time to terminate the search */ if (ncand == piv_lim) goto done; } /* now consider active rows having len non-zeros */ for (i = R_head[len]; i != 0; i = R_next[i]) { /* i-th row has len non-zeros */ /* find an element in the column of minimal length */ some = NULL, min_len = INT_MAX; for (vij = V_row[i]; vij != NULL; vij = vij->r_next) { if (min_len > C_len[vij->j]) some = vij, min_len = C_len[vij->j]; /* if Markowitz cost of this element is not greater than (len-1)**2, it can be chosen right now; this heuristic reduces the search and works well in many cases */ if (min_len <= len) { piv = some; goto done; } } /* i-th row has been scanned */ /* the minimal element found is a next pivot candidate */ xassert(some != NULL); ncand++; /* compute its Markowitz cost */ cost = (double)(len - 1) * (double)(min_len - 1); /* choose between the current candidate and this element */ if (cost < best) piv = some, best = cost; /* if piv_lim candidates have been considered, there is a doubt that a much better candidate exists; therefore it is the time to terminate the search */ if (ncand == piv_lim) goto done; } } done: /* bring the pivot v[p,q] to the factorizing routine */ return piv; } /*---------------------------------------------------------------------- // eliminate - perform gaussian elimination. // // This routine performs elementary gaussian transformations in order // to eliminate subdiagonal elements in the k-th column of the matrix // U = P*V*Q using the pivot element u[k,k], where k is the number of // the current elimination step. // // The parameter piv specifies the pivot element v[p,q] = u[k,k]. // // Each time when the routine applies the elementary transformation to // a non-pivot row of the matrix V, it stores the corresponding element // to the matrix F in order to keep the main equality A = F*V. // // The routine assumes that on entry the matrices L = P*F*inv(P) and // U = P*V*Q are the following: // // 1 k 1 k n // 1 1 . . . . . . . . . 1 x x x x x x x x x x // x 1 . . . . . . . . . x x x x x x x x x // x x 1 . . . . . . . . . x x x x x x x x // x x x 1 . . . . . . . . . x x x x x x x // k x x x x 1 . . . . . k . . . . * * * * * * // x x x x _ 1 . . . . . . . . # * * * * * // x x x x _ . 1 . . . . . . . # * * * * * // x x x x _ . . 1 . . . . . . # * * * * * // x x x x _ . . . 1 . . . . . # * * * * * // n x x x x _ . . . . 1 n . . . . # * * * * * // // matrix L matrix U // // where rows and columns of the matrix U with numbers k, k+1, ..., n // form the active submatrix (eliminated elements are marked by '#' and // other elements of the active submatrix are marked by '*'). Note that // each eliminated non-zero element u[i,k] of the matrix U gives the // corresponding element l[i,k] of the matrix L (marked by '_'). // // Actually all operations are performed on the matrix V. Should note // that the row-wise representation corresponds to the matrix V, but the // column-wise representation corresponds to the active submatrix of the // matrix V, i.e. elements of the matrix V, which doesn't belong to the // active submatrix, are missing from the column linked lists. // // Let u[k,k] = v[p,q] be the pivot. In order to eliminate subdiagonal // elements u[i',k] = v[i,q], i' = k+1, k+2, ..., n, the routine applies // the following elementary gaussian transformations: // // (i-th row of V) := (i-th row of V) - f[i,p] * (p-th row of V), // // where f[i,p] = v[i,q] / v[p,q] is a gaussian multiplier. // // Additionally, in order to keep the main equality A = F*V, each time // when the routine applies the transformation to i-th row of the matrix // V, it also adds f[i,p] as a new element to the matrix F. // // IMPORTANT: On entry the working arrays flag and work should contain // zeros. This status is provided by the routine on exit. */ static void eliminate(LUX *lux, LUXWKA *wka, LUXELM *piv, int flag[], mpq_t work[]) { DMP *pool = lux->pool; LUXELM **F_row = lux->F_row; LUXELM **F_col = lux->F_col; mpq_t *V_piv = lux->V_piv; LUXELM **V_row = lux->V_row; LUXELM **V_col = lux->V_col; int *R_len = wka->R_len; int *R_head = wka->R_head; int *R_prev = wka->R_prev; int *R_next = wka->R_next; int *C_len = wka->C_len; int *C_head = wka->C_head; int *C_prev = wka->C_prev; int *C_next = wka->C_next; LUXELM *fip, *vij, *vpj, *viq, *next; mpq_t temp; int i, j, p, q; mpq_init(temp); /* determine row and column indices of the pivot v[p,q] */ xassert(piv != NULL); p = piv->i, q = piv->j; /* remove p-th (pivot) row from the active set; it will never return there */ if (R_prev[p] == 0) R_head[R_len[p]] = R_next[p]; else R_next[R_prev[p]] = R_next[p]; if (R_next[p] == 0) ; else R_prev[R_next[p]] = R_prev[p]; /* remove q-th (pivot) column from the active set; it will never return there */ if (C_prev[q] == 0) C_head[C_len[q]] = C_next[q]; else C_next[C_prev[q]] = C_next[q]; if (C_next[q] == 0) ; else C_prev[C_next[q]] = C_prev[q]; /* store the pivot value in a separate array */ mpq_set(V_piv[p], piv->val); /* remove the pivot from p-th row */ if (piv->r_prev == NULL) V_row[p] = piv->r_next; else piv->r_prev->r_next = piv->r_next; if (piv->r_next == NULL) ; else piv->r_next->r_prev = piv->r_prev; R_len[p]--; /* remove the pivot from q-th column */ if (piv->c_prev == NULL) V_col[q] = piv->c_next; else piv->c_prev->c_next = piv->c_next; if (piv->c_next == NULL) ; else piv->c_next->c_prev = piv->c_prev; C_len[q]--; /* free the space occupied by the pivot */ mpq_clear(piv->val); dmp_free_atom(pool, piv, sizeof(LUXELM)); /* walk through p-th (pivot) row, which already does not contain the pivot v[p,q], and do the following... */ for (vpj = V_row[p]; vpj != NULL; vpj = vpj->r_next) { /* get column index of v[p,j] */ j = vpj->j; /* store v[p,j] in the working array */ flag[j] = 1; mpq_set(work[j], vpj->val); /* remove j-th column from the active set; it will return there later with a new length */ if (C_prev[j] == 0) C_head[C_len[j]] = C_next[j]; else C_next[C_prev[j]] = C_next[j]; if (C_next[j] == 0) ; else C_prev[C_next[j]] = C_prev[j]; /* v[p,j] leaves the active submatrix, so remove it from j-th column; however, v[p,j] is kept in p-th row */ if (vpj->c_prev == NULL) V_col[j] = vpj->c_next; else vpj->c_prev->c_next = vpj->c_next; if (vpj->c_next == NULL) ; else vpj->c_next->c_prev = vpj->c_prev; C_len[j]--; } /* now walk through q-th (pivot) column, which already does not contain the pivot v[p,q], and perform gaussian elimination */ while (V_col[q] != NULL) { /* element v[i,q] has to be eliminated */ viq = V_col[q]; /* get row index of v[i,q] */ i = viq->i; /* remove i-th row from the active set; later it will return there with a new length */ if (R_prev[i] == 0) R_head[R_len[i]] = R_next[i]; else R_next[R_prev[i]] = R_next[i]; if (R_next[i] == 0) ; else R_prev[R_next[i]] = R_prev[i]; /* compute gaussian multiplier f[i,p] = v[i,q] / v[p,q] and store it in the matrix F */ fip = dmp_get_atom(pool, sizeof(LUXELM)); fip->i = i, fip->j = p; mpq_init(fip->val); mpq_div(fip->val, viq->val, V_piv[p]); fip->r_prev = NULL; fip->r_next = F_row[i]; fip->c_prev = NULL; fip->c_next = F_col[p]; if (fip->r_next != NULL) fip->r_next->r_prev = fip; if (fip->c_next != NULL) fip->c_next->c_prev = fip; F_row[i] = F_col[p] = fip; /* v[i,q] has to be eliminated, so remove it from i-th row */ if (viq->r_prev == NULL) V_row[i] = viq->r_next; else viq->r_prev->r_next = viq->r_next; if (viq->r_next == NULL) ; else viq->r_next->r_prev = viq->r_prev; R_len[i]--; /* and also from q-th column */ V_col[q] = viq->c_next; C_len[q]--; /* free the space occupied by v[i,q] */ mpq_clear(viq->val); dmp_free_atom(pool, viq, sizeof(LUXELM)); /* perform gaussian transformation: (i-th row) := (i-th row) - f[i,p] * (p-th row) note that now p-th row, which is in the working array, does not contain the pivot v[p,q], and i-th row does not contain the element v[i,q] to be eliminated */ /* walk through i-th row and transform existing non-zero elements */ for (vij = V_row[i]; vij != NULL; vij = next) { next = vij->r_next; /* get column index of v[i,j] */ j = vij->j; /* v[i,j] := v[i,j] - f[i,p] * v[p,j] */ if (flag[j]) { /* v[p,j] != 0 */ flag[j] = 0; mpq_mul(temp, fip->val, work[j]); mpq_sub(vij->val, vij->val, temp); if (mpq_sgn(vij->val) == 0) { /* new v[i,j] is zero, so remove it from the active submatrix */ /* remove v[i,j] from i-th row */ if (vij->r_prev == NULL) V_row[i] = vij->r_next; else vij->r_prev->r_next = vij->r_next; if (vij->r_next == NULL) ; else vij->r_next->r_prev = vij->r_prev; R_len[i]--; /* remove v[i,j] from j-th column */ if (vij->c_prev == NULL) V_col[j] = vij->c_next; else vij->c_prev->c_next = vij->c_next; if (vij->c_next == NULL) ; else vij->c_next->c_prev = vij->c_prev; C_len[j]--; /* free the space occupied by v[i,j] */ mpq_clear(vij->val); dmp_free_atom(pool, vij, sizeof(LUXELM)); } } } /* now flag is the pattern of the set v[p,*] \ v[i,*] */ /* walk through p-th (pivot) row and create new elements in i-th row, which appear due to fill-in */ for (vpj = V_row[p]; vpj != NULL; vpj = vpj->r_next) { j = vpj->j; if (flag[j]) { /* create new non-zero v[i,j] = 0 - f[i,p] * v[p,j] and add it to i-th row and j-th column */ vij = dmp_get_atom(pool, sizeof(LUXELM)); vij->i = i, vij->j = j; mpq_init(vij->val); mpq_mul(vij->val, fip->val, work[j]); mpq_neg(vij->val, vij->val); vij->r_prev = NULL; vij->r_next = V_row[i]; vij->c_prev = NULL; vij->c_next = V_col[j]; if (vij->r_next != NULL) vij->r_next->r_prev = vij; if (vij->c_next != NULL) vij->c_next->c_prev = vij; V_row[i] = V_col[j] = vij; R_len[i]++, C_len[j]++; } else { /* there is no fill-in, because v[i,j] already exists in i-th row; restore the flag, which was reset before */ flag[j] = 1; } } /* now i-th row has been completely transformed and can return to the active set with a new length */ R_prev[i] = 0; R_next[i] = R_head[R_len[i]]; if (R_next[i] != 0) R_prev[R_next[i]] = i; R_head[R_len[i]] = i; } /* at this point q-th (pivot) column must be empty */ xassert(C_len[q] == 0); /* walk through p-th (pivot) row again and do the following... */ for (vpj = V_row[p]; vpj != NULL; vpj = vpj->r_next) { /* get column index of v[p,j] */ j = vpj->j; /* erase v[p,j] from the working array */ flag[j] = 0; mpq_set_si(work[j], 0, 1); /* now j-th column has been completely transformed, so it can return to the active list with a new length */ C_prev[j] = 0; C_next[j] = C_head[C_len[j]]; if (C_next[j] != 0) C_prev[C_next[j]] = j; C_head[C_len[j]] = j; } mpq_clear(temp); /* return to the factorizing routine */ return; } /*---------------------------------------------------------------------- // lux_decomp - compute LU-factorization. // // SYNOPSIS // // #include "glplux.h" // int lux_decomp(LUX *lux, int (*col)(void *info, int j, int ind[], // mpq_t val[]), void *info); // // DESCRIPTION // // The routine lux_decomp computes LU-factorization of a given square // matrix A. // // The parameter lux specifies LU-factorization data structure built by // means of the routine lux_create. // // The formal routine col specifies the original matrix A. In order to // obtain j-th column of the matrix A the routine lux_decomp calls the // routine col with the parameter j (1 <= j <= n, where n is the order // of A). In response the routine col should store row indices and // numerical values of non-zero elements of j-th column of A to the // locations ind[1], ..., ind[len] and val[1], ..., val[len], resp., // where len is the number of non-zeros in j-th column, which should be // returned on exit. Neiter zero nor duplicate elements are allowed. // // The parameter info is a transit pointer passed to the formal routine // col; it can be used for various purposes. // // RETURNS // // The routine lux_decomp returns the singularity flag. Zero flag means // that the original matrix A is non-singular while non-zero flag means // that A is (exactly!) singular. // // Note that LU-factorization is valid in both cases, however, in case // of singularity some rows of the matrix V (including pivot elements) // will be empty. // // REPAIRING SINGULAR MATRIX // // If the routine lux_decomp returns non-zero flag, it provides all // necessary information that can be used for "repairing" the matrix A, // where "repairing" means replacing linearly dependent columns of the // matrix A by appropriate columns of the unity matrix. This feature is // needed when the routine lux_decomp is used for reinverting the basis // matrix within the simplex method procedure. // // On exit linearly dependent columns of the matrix U have the numbers // rank+1, rank+2, ..., n, where rank is the exact rank of the matrix A // stored by the routine to the member lux->rank. The correspondence // between columns of A and U is the same as between columns of V and U. // Thus, linearly dependent columns of the matrix A have the numbers // Q_col[rank+1], Q_col[rank+2], ..., Q_col[n], where Q_col is an array // representing the permutation matrix Q in column-like format. It is // understood that each j-th linearly dependent column of the matrix U // should be replaced by the unity vector, where all elements are zero // except the unity diagonal element u[j,j]. On the other hand j-th row // of the matrix U corresponds to the row of the matrix V (and therefore // of the matrix A) with the number P_row[j], where P_row is an array // representing the permutation matrix P in row-like format. Thus, each // j-th linearly dependent column of the matrix U should be replaced by // a column of the unity matrix with the number P_row[j]. // // The code that repairs the matrix A may look like follows: // // for (j = rank+1; j <= n; j++) // { replace column Q_col[j] of the matrix A by column P_row[j] of // the unity matrix; // } // // where rank, P_row, and Q_col are members of the structure LUX. */ int lux_decomp(LUX *lux, int (*col)(void *info, int j, int ind[], mpq_t val[]), void *info) { int n = lux->n; LUXELM **V_row = lux->V_row; LUXELM **V_col = lux->V_col; int *P_row = lux->P_row; int *P_col = lux->P_col; int *Q_row = lux->Q_row; int *Q_col = lux->Q_col; LUXELM *piv, *vij; LUXWKA *wka; int i, j, k, p, q, t, *flag; mpq_t *work; /* allocate working area */ wka = xmalloc(sizeof(LUXWKA)); wka->R_len = xcalloc(1+n, sizeof(int)); wka->R_head = xcalloc(1+n, sizeof(int)); wka->R_prev = xcalloc(1+n, sizeof(int)); wka->R_next = xcalloc(1+n, sizeof(int)); wka->C_len = xcalloc(1+n, sizeof(int)); wka->C_head = xcalloc(1+n, sizeof(int)); wka->C_prev = xcalloc(1+n, sizeof(int)); wka->C_next = xcalloc(1+n, sizeof(int)); /* initialize LU-factorization data structures */ initialize(lux, col, info, wka); /* allocate working arrays */ flag = xcalloc(1+n, sizeof(int)); work = xcalloc(1+n, sizeof(mpq_t)); for (k = 1; k <= n; k++) { flag[k] = 0; mpq_init(work[k]); } /* main elimination loop */ for (k = 1; k <= n; k++) { /* choose a pivot element v[p,q] */ piv = find_pivot(lux, wka); if (piv == NULL) { /* no pivot can be chosen, because the active submatrix is empty */ break; } /* determine row and column indices of the pivot element */ p = piv->i, q = piv->j; /* let v[p,q] correspond to u[i',j']; permute k-th and i'-th rows and k-th and j'-th columns of the matrix U = P*V*Q to move the element u[i',j'] to the position u[k,k] */ i = P_col[p], j = Q_row[q]; xassert(k <= i && i <= n && k <= j && j <= n); /* permute k-th and i-th rows of the matrix U */ t = P_row[k]; P_row[i] = t, P_col[t] = i; P_row[k] = p, P_col[p] = k; /* permute k-th and j-th columns of the matrix U */ t = Q_col[k]; Q_col[j] = t, Q_row[t] = j; Q_col[k] = q, Q_row[q] = k; /* eliminate subdiagonal elements of k-th column of the matrix U = P*V*Q using the pivot element u[k,k] = v[p,q] */ eliminate(lux, wka, piv, flag, work); } /* determine the rank of A (and V) */ lux->rank = k - 1; /* free working arrays */ xfree(flag); for (k = 1; k <= n; k++) mpq_clear(work[k]); xfree(work); /* build column lists of the matrix V using its row lists */ for (j = 1; j <= n; j++) xassert(V_col[j] == NULL); for (i = 1; i <= n; i++) { for (vij = V_row[i]; vij != NULL; vij = vij->r_next) { j = vij->j; vij->c_prev = NULL; vij->c_next = V_col[j]; if (vij->c_next != NULL) vij->c_next->c_prev = vij; V_col[j] = vij; } } /* free working area */ xfree(wka->R_len); xfree(wka->R_head); xfree(wka->R_prev); xfree(wka->R_next); xfree(wka->C_len); xfree(wka->C_head); xfree(wka->C_prev); xfree(wka->C_next); xfree(wka); /* return to the calling program */ return (lux->rank < n); } /*---------------------------------------------------------------------- // lux_f_solve - solve system F*x = b or F'*x = b. // // SYNOPSIS // // #include "glplux.h" // void lux_f_solve(LUX *lux, int tr, mpq_t x[]); // // DESCRIPTION // // The routine lux_f_solve solves either the system F*x = b (if the // flag tr is zero) or the system F'*x = b (if the flag tr is non-zero), // where the matrix F is a component of LU-factorization specified by // the parameter lux, F' is a matrix transposed to F. // // On entry the array x should contain elements of the right-hand side // vector b in locations x[1], ..., x[n], where n is the order of the // matrix F. On exit this array will contain elements of the solution // vector x in the same locations. */ void lux_f_solve(LUX *lux, int tr, mpq_t x[]) { int n = lux->n; LUXELM **F_row = lux->F_row; LUXELM **F_col = lux->F_col; int *P_row = lux->P_row; LUXELM *fik, *fkj; int i, j, k; mpq_t temp; mpq_init(temp); if (!tr) { /* solve the system F*x = b */ for (j = 1; j <= n; j++) { k = P_row[j]; if (mpq_sgn(x[k]) != 0) { for (fik = F_col[k]; fik != NULL; fik = fik->c_next) { mpq_mul(temp, fik->val, x[k]); mpq_sub(x[fik->i], x[fik->i], temp); } } } } else { /* solve the system F'*x = b */ for (i = n; i >= 1; i--) { k = P_row[i]; if (mpq_sgn(x[k]) != 0) { for (fkj = F_row[k]; fkj != NULL; fkj = fkj->r_next) { mpq_mul(temp, fkj->val, x[k]); mpq_sub(x[fkj->j], x[fkj->j], temp); } } } } mpq_clear(temp); return; } /*---------------------------------------------------------------------- // lux_v_solve - solve system V*x = b or V'*x = b. // // SYNOPSIS // // #include "glplux.h" // void lux_v_solve(LUX *lux, int tr, double x[]); // // DESCRIPTION // // The routine lux_v_solve solves either the system V*x = b (if the // flag tr is zero) or the system V'*x = b (if the flag tr is non-zero), // where the matrix V is a component of LU-factorization specified by // the parameter lux, V' is a matrix transposed to V. // // On entry the array x should contain elements of the right-hand side // vector b in locations x[1], ..., x[n], where n is the order of the // matrix V. On exit this array will contain elements of the solution // vector x in the same locations. */ void lux_v_solve(LUX *lux, int tr, mpq_t x[]) { int n = lux->n; mpq_t *V_piv = lux->V_piv; LUXELM **V_row = lux->V_row; LUXELM **V_col = lux->V_col; int *P_row = lux->P_row; int *Q_col = lux->Q_col; LUXELM *vij; int i, j, k; mpq_t *b, temp; b = xcalloc(1+n, sizeof(mpq_t)); for (k = 1; k <= n; k++) mpq_init(b[k]), mpq_set(b[k], x[k]), mpq_set_si(x[k], 0, 1); mpq_init(temp); if (!tr) { /* solve the system V*x = b */ for (k = n; k >= 1; k--) { i = P_row[k], j = Q_col[k]; if (mpq_sgn(b[i]) != 0) { mpq_set(x[j], b[i]); mpq_div(x[j], x[j], V_piv[i]); for (vij = V_col[j]; vij != NULL; vij = vij->c_next) { mpq_mul(temp, vij->val, x[j]); mpq_sub(b[vij->i], b[vij->i], temp); } } } } else { /* solve the system V'*x = b */ for (k = 1; k <= n; k++) { i = P_row[k], j = Q_col[k]; if (mpq_sgn(b[j]) != 0) { mpq_set(x[i], b[j]); mpq_div(x[i], x[i], V_piv[i]); for (vij = V_row[i]; vij != NULL; vij = vij->r_next) { mpq_mul(temp, vij->val, x[i]); mpq_sub(b[vij->j], b[vij->j], temp); } } } } for (k = 1; k <= n; k++) mpq_clear(b[k]); mpq_clear(temp); xfree(b); return; } /*---------------------------------------------------------------------- // lux_solve - solve system A*x = b or A'*x = b. // // SYNOPSIS // // #include "glplux.h" // void lux_solve(LUX *lux, int tr, mpq_t x[]); // // DESCRIPTION // // The routine lux_solve solves either the system A*x = b (if the flag // tr is zero) or the system A'*x = b (if the flag tr is non-zero), // where the parameter lux specifies LU-factorization of the matrix A, // A' is a matrix transposed to A. // // On entry the array x should contain elements of the right-hand side // vector b in locations x[1], ..., x[n], where n is the order of the // matrix A. On exit this array will contain elements of the solution // vector x in the same locations. */ void lux_solve(LUX *lux, int tr, mpq_t x[]) { if (lux->rank < lux->n) xfault("lux_solve: LU-factorization has incomplete rank\n"); if (!tr) { /* A = F*V, therefore inv(A) = inv(V)*inv(F) */ lux_f_solve(lux, 0, x); lux_v_solve(lux, 0, x); } else { /* A' = V'*F', therefore inv(A') = inv(F')*inv(V') */ lux_v_solve(lux, 1, x); lux_f_solve(lux, 1, x); } return; } /*---------------------------------------------------------------------- // lux_delete - delete LU-factorization. // // SYNOPSIS // // #include "glplux.h" // void lux_delete(LUX *lux); // // DESCRIPTION // // The routine lux_delete deletes LU-factorization data structure, // which the parameter lux points to, freeing all the memory allocated // to this object. */ void lux_delete(LUX *lux) { int n = lux->n; LUXELM *fij, *vij; int i; for (i = 1; i <= n; i++) { for (fij = lux->F_row[i]; fij != NULL; fij = fij->r_next) mpq_clear(fij->val); mpq_clear(lux->V_piv[i]); for (vij = lux->V_row[i]; vij != NULL; vij = vij->r_next) mpq_clear(vij->val); } dmp_delete_pool(lux->pool); xfree(lux->F_row); xfree(lux->F_col); xfree(lux->V_piv); xfree(lux->V_row); xfree(lux->V_col); xfree(lux->P_row); xfree(lux->P_col); xfree(lux->Q_row); xfree(lux->Q_col); xfree(lux); return; } /* eof */ praat-6.0.04/external/glpk/glplux.h000066400000000000000000000212221261542461700171620ustar00rootroot00000000000000/* glplux.h (LU-factorization, bignum arithmetic) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPLUX_H #define GLPLUX_H #include "glpdmp.h" #include "glpgmp.h" /*---------------------------------------------------------------------- // The structure LUX defines LU-factorization of a square matrix A, // which is the following quartet: // // [A] = (F, V, P, Q), (1) // // where F and V are such matrices that // // A = F * V, (2) // // and P and Q are such permutation matrices that the matrix // // L = P * F * inv(P) (3) // // is lower triangular with unity diagonal, and the matrix // // U = P * V * Q (4) // // is upper triangular. All the matrices have the order n. // // The matrices F and V are stored in row/column-wise sparse format as // row and column linked lists of non-zero elements. Unity elements on // the main diagonal of the matrix F are not stored. Pivot elements of // the matrix V (that correspond to diagonal elements of the matrix U) // are also missing from the row and column lists and stored separately // in an ordinary array. // // The permutation matrices P and Q are stored as ordinary arrays using // both row- and column-like formats. // // The matrices L and U being completely defined by the matrices F, V, // P, and Q are not stored explicitly. // // It is easy to show that the factorization (1)-(3) is some version of // LU-factorization. Indeed, from (3) and (4) it follows that: // // F = inv(P) * L * P, // // V = inv(P) * U * inv(Q), // // and substitution into (2) gives: // // A = F * V = inv(P) * L * U * inv(Q). // // For more details see the program documentation. */ typedef struct LUX LUX; typedef struct LUXELM LUXELM; typedef struct LUXWKA LUXWKA; struct LUX { /* LU-factorization of a square matrix */ int n; /* the order of matrices A, F, V, P, Q */ DMP *pool; /* memory pool for elements of matrices F and V */ LUXELM **F_row; /* LUXELM *F_row[1+n]; */ /* F_row[0] is not used; F_row[i], 1 <= i <= n, is a pointer to the list of elements in i-th row of matrix F (diagonal elements are not stored) */ LUXELM **F_col; /* LUXELM *F_col[1+n]; */ /* F_col[0] is not used; F_col[j], 1 <= j <= n, is a pointer to the list of elements in j-th column of matrix F (diagonal elements are not stored) */ mpq_t *V_piv; /* mpq_t V_piv[1+n]; */ /* V_piv[0] is not used; V_piv[p], 1 <= p <= n, is a pivot element v[p,q] corresponding to a diagonal element u[k,k] of matrix U = P*V*Q (used on k-th elimination step, k = 1, 2, ..., n) */ LUXELM **V_row; /* LUXELM *V_row[1+n]; */ /* V_row[0] is not used; V_row[i], 1 <= i <= n, is a pointer to the list of elements in i-th row of matrix V (except pivot elements) */ LUXELM **V_col; /* LUXELM *V_col[1+n]; */ /* V_col[0] is not used; V_col[j], 1 <= j <= n, is a pointer to the list of elements in j-th column of matrix V (except pivot elements) */ int *P_row; /* int P_row[1+n]; */ /* P_row[0] is not used; P_row[i] = j means that p[i,j] = 1, where p[i,j] is an element of permutation matrix P */ int *P_col; /* int P_col[1+n]; */ /* P_col[0] is not used; P_col[j] = i means that p[i,j] = 1, where p[i,j] is an element of permutation matrix P */ /* if i-th row or column of matrix F is i'-th row or column of matrix L = P*F*inv(P), or if i-th row of matrix V is i'-th row of matrix U = P*V*Q, then P_row[i'] = i and P_col[i] = i' */ int *Q_row; /* int Q_row[1+n]; */ /* Q_row[0] is not used; Q_row[i] = j means that q[i,j] = 1, where q[i,j] is an element of permutation matrix Q */ int *Q_col; /* int Q_col[1+n]; */ /* Q_col[0] is not used; Q_col[j] = i means that q[i,j] = 1, where q[i,j] is an element of permutation matrix Q */ /* if j-th column of matrix V is j'-th column of matrix U = P*V*Q, then Q_row[j] = j' and Q_col[j'] = j */ int rank; /* the (exact) rank of matrices A and V */ }; struct LUXELM { /* element of matrix F or V */ int i; /* row index, 1 <= i <= m */ int j; /* column index, 1 <= j <= n */ mpq_t val; /* numeric (non-zero) element value */ LUXELM *r_prev; /* pointer to previous element in the same row */ LUXELM *r_next; /* pointer to next element in the same row */ LUXELM *c_prev; /* pointer to previous element in the same column */ LUXELM *c_next; /* pointer to next element in the same column */ }; struct LUXWKA { /* working area (used only during factorization) */ /* in order to efficiently implement Markowitz strategy and Duff search technique there are two families {R[0], R[1], ..., R[n]} and {C[0], C[1], ..., C[n]}; member R[k] is a set of active rows of matrix V having k non-zeros, and member C[k] is a set of active columns of matrix V having k non-zeros (in the active submatrix); each set R[k] and C[k] is implemented as a separate doubly linked list */ int *R_len; /* int R_len[1+n]; */ /* R_len[0] is not used; R_len[i], 1 <= i <= n, is the number of non-zero elements in i-th row of matrix V (that is the length of i-th row) */ int *R_head; /* int R_head[1+n]; */ /* R_head[k], 0 <= k <= n, is the number of a first row, which is active and whose length is k */ int *R_prev; /* int R_prev[1+n]; */ /* R_prev[0] is not used; R_prev[i], 1 <= i <= n, is the number of a previous row, which is active and has the same length as i-th row */ int *R_next; /* int R_next[1+n]; */ /* R_prev[0] is not used; R_prev[i], 1 <= i <= n, is the number of a next row, which is active and has the same length as i-th row */ int *C_len; /* int C_len[1+n]; */ /* C_len[0] is not used; C_len[j], 1 <= j <= n, is the number of non-zero elements in j-th column of the active submatrix of matrix V (that is the length of j-th column in the active submatrix) */ int *C_head; /* int C_head[1+n]; */ /* C_head[k], 0 <= k <= n, is the number of a first column, which is active and whose length is k */ int *C_prev; /* int C_prev[1+n]; */ /* C_prev[0] is not used; C_prev[j], 1 <= j <= n, is the number of a previous column, which is active and has the same length as j-th column */ int *C_next; /* int C_next[1+n]; */ /* C_next[0] is not used; C_next[j], 1 <= j <= n, is the number of a next column, which is active and has the same length as j-th column */ }; #define lux_create _glp_lux_create #define lux_decomp _glp_lux_decomp #define lux_f_solve _glp_lux_f_solve #define lux_v_solve _glp_lux_v_solve #define lux_solve _glp_lux_solve #define lux_delete _glp_lux_delete LUX *lux_create(int n); /* create LU-factorization */ int lux_decomp(LUX *lux, int (*col)(void *info, int j, int ind[], mpq_t val[]), void *info); /* compute LU-factorization */ void lux_f_solve(LUX *lux, int tr, mpq_t x[]); /* solve system F*x = b or F'*x = b */ void lux_v_solve(LUX *lux, int tr, mpq_t x[]); /* solve system V*x = b or V'*x = b */ void lux_solve(LUX *lux, int tr, mpq_t x[]); /* solve system A*x = b or A'*x = b */ void lux_delete(LUX *lux); /* delete LU-factorization */ #endif /* eof */ praat-6.0.04/external/glpk/glpmat.c000066400000000000000000001003431261542461700171300ustar00rootroot00000000000000/* glpmat.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpenv.h" #include "glpmat.h" #include "glpqmd.h" #include "amd.h" #include "colamd.h" /*---------------------------------------------------------------------- -- check_fvs - check sparse vector in full-vector storage format. -- -- SYNOPSIS -- -- #include "glpmat.h" -- int check_fvs(int n, int nnz, int ind[], double vec[]); -- -- DESCRIPTION -- -- The routine check_fvs checks if a given vector of dimension n in -- full-vector storage format has correct representation. -- -- RETURNS -- -- The routine returns one of the following codes: -- -- 0 - the vector is correct; -- 1 - the number of elements (n) is negative; -- 2 - the number of non-zero elements (nnz) is negative; -- 3 - some element index is out of range; -- 4 - some element index is duplicate; -- 5 - some non-zero element is out of pattern. */ int check_fvs(int n, int nnz, int ind[], double vec[]) { int i, t, ret, *flag = NULL; /* check the number of elements */ if (n < 0) { ret = 1; goto done; } /* check the number of non-zero elements */ if (nnz < 0) { ret = 2; goto done; } /* check vector indices */ flag = xcalloc(1+n, sizeof(int)); for (i = 1; i <= n; i++) flag[i] = 0; for (t = 1; t <= nnz; t++) { i = ind[t]; if (!(1 <= i && i <= n)) { ret = 3; goto done; } if (flag[i]) { ret = 4; goto done; } flag[i] = 1; } /* check vector elements */ for (i = 1; i <= n; i++) { if (!flag[i] && vec[i] != 0.0) { ret = 5; goto done; } } /* the vector is ok */ ret = 0; done: if (flag != NULL) xfree(flag); return ret; } /*---------------------------------------------------------------------- -- check_pattern - check pattern of sparse matrix. -- -- SYNOPSIS -- -- #include "glpmat.h" -- int check_pattern(int m, int n, int A_ptr[], int A_ind[]); -- -- DESCRIPTION -- -- The routine check_pattern checks the pattern of a given mxn matrix -- in storage-by-rows format. -- -- RETURNS -- -- The routine returns one of the following codes: -- -- 0 - the pattern is correct; -- 1 - the number of rows (m) is negative; -- 2 - the number of columns (n) is negative; -- 3 - A_ptr[1] is not 1; -- 4 - some column index is out of range; -- 5 - some column indices are duplicate. */ int check_pattern(int m, int n, int A_ptr[], int A_ind[]) { int i, j, ptr, ret, *flag = NULL; /* check the number of rows */ if (m < 0) { ret = 1; goto done; } /* check the number of columns */ if (n < 0) { ret = 2; goto done; } /* check location A_ptr[1] */ if (A_ptr[1] != 1) { ret = 3; goto done; } /* check row patterns */ flag = xcalloc(1+n, sizeof(int)); for (j = 1; j <= n; j++) flag[j] = 0; for (i = 1; i <= m; i++) { /* check pattern of row i */ for (ptr = A_ptr[i]; ptr < A_ptr[i+1]; ptr++) { j = A_ind[ptr]; /* check column index */ if (!(1 <= j && j <= n)) { ret = 4; goto done; } /* check for duplication */ if (flag[j]) { ret = 5; goto done; } flag[j] = 1; } /* clear flags */ for (ptr = A_ptr[i]; ptr < A_ptr[i+1]; ptr++) { j = A_ind[ptr]; flag[j] = 0; } } /* the pattern is ok */ ret = 0; done: if (flag != NULL) xfree(flag); return ret; } /*---------------------------------------------------------------------- -- transpose - transpose sparse matrix. -- -- *Synopsis* -- -- #include "glpmat.h" -- void transpose(int m, int n, int A_ptr[], int A_ind[], -- double A_val[], int AT_ptr[], int AT_ind[], double AT_val[]); -- -- *Description* -- -- For a given mxn sparse matrix A the routine transpose builds a nxm -- sparse matrix A' which is a matrix transposed to A. -- -- The arrays A_ptr, A_ind, and A_val specify a given mxn matrix A to -- be transposed in storage-by-rows format. The parameter A_val can be -- NULL, in which case numeric values are not copied. The arrays A_ptr, -- A_ind, and A_val are not changed on exit. -- -- On entry the arrays AT_ptr, AT_ind, and AT_val must be allocated, -- but their content is ignored. On exit the routine stores a resultant -- nxm matrix A' in these arrays in storage-by-rows format. Note that -- if the parameter A_val is NULL, the array AT_val is not used. -- -- The routine transpose has a side effect that elements in rows of the -- resultant matrix A' follow in ascending their column indices. */ void transpose(int m, int n, int A_ptr[], int A_ind[], double A_val[], int AT_ptr[], int AT_ind[], double AT_val[]) { int i, j, t, beg, end, pos, len; /* determine row lengths of resultant matrix */ for (j = 1; j <= n; j++) AT_ptr[j] = 0; for (i = 1; i <= m; i++) { beg = A_ptr[i], end = A_ptr[i+1]; for (t = beg; t < end; t++) AT_ptr[A_ind[t]]++; } /* set up row pointers of resultant matrix */ pos = 1; for (j = 1; j <= n; j++) len = AT_ptr[j], pos += len, AT_ptr[j] = pos; AT_ptr[n+1] = pos; /* build resultant matrix */ for (i = m; i >= 1; i--) { beg = A_ptr[i], end = A_ptr[i+1]; for (t = beg; t < end; t++) { pos = --AT_ptr[A_ind[t]]; AT_ind[pos] = i; if (A_val != NULL) AT_val[pos] = A_val[t]; } } return; } /*---------------------------------------------------------------------- -- adat_symbolic - compute S = P*A*D*A'*P' (symbolic phase). -- -- *Synopsis* -- -- #include "glpmat.h" -- int *adat_symbolic(int m, int n, int P_per[], int A_ptr[], -- int A_ind[], int S_ptr[]); -- -- *Description* -- -- The routine adat_symbolic implements the symbolic phase to compute -- symmetric matrix S = P*A*D*A'*P', where P is a permutation matrix, -- A is a given sparse matrix, D is a diagonal matrix, A' is a matrix -- transposed to A, P' is an inverse of P. -- -- The parameter m is the number of rows in A and the order of P. -- -- The parameter n is the number of columns in A and the order of D. -- -- The array P_per specifies permutation matrix P. It is not changed on -- exit. -- -- The arrays A_ptr and A_ind specify the pattern of matrix A. They are -- not changed on exit. -- -- On exit the routine stores the pattern of upper triangular part of -- matrix S without diagonal elements in the arrays S_ptr and S_ind in -- storage-by-rows format. The array S_ptr should be allocated on entry, -- however, its content is ignored. The array S_ind is allocated by the -- routine itself which returns a pointer to it. -- -- *Returns* -- -- The routine returns a pointer to the array S_ind. */ int *adat_symbolic(int m, int n, int P_per[], int A_ptr[], int A_ind[], int S_ptr[]) { int i, j, t, ii, jj, tt, k, size, len; int *S_ind, *AT_ptr, *AT_ind, *ind, *map, *temp; /* build the pattern of A', which is a matrix transposed to A, to efficiently access A in column-wise manner */ AT_ptr = xcalloc(1+n+1, sizeof(int)); AT_ind = xcalloc(A_ptr[m+1], sizeof(int)); transpose(m, n, A_ptr, A_ind, NULL, AT_ptr, AT_ind, NULL); /* allocate the array S_ind */ size = A_ptr[m+1] - 1; if (size < m) size = m; S_ind = xcalloc(1+size, sizeof(int)); /* allocate and initialize working arrays */ ind = xcalloc(1+m, sizeof(int)); map = xcalloc(1+m, sizeof(int)); for (jj = 1; jj <= m; jj++) map[jj] = 0; /* compute pattern of S; note that symbolically S = B*B', where B = P*A, B' is matrix transposed to B */ S_ptr[1] = 1; for (ii = 1; ii <= m; ii++) { /* compute pattern of ii-th row of S */ len = 0; i = P_per[ii]; /* i-th row of A = ii-th row of B */ for (t = A_ptr[i]; t < A_ptr[i+1]; t++) { k = A_ind[t]; /* walk through k-th column of A */ for (tt = AT_ptr[k]; tt < AT_ptr[k+1]; tt++) { j = AT_ind[tt]; jj = P_per[m+j]; /* j-th row of A = jj-th row of B */ /* a[i,k] != 0 and a[j,k] != 0 ergo s[ii,jj] != 0 */ if (ii < jj && !map[jj]) ind[++len] = jj, map[jj] = 1; } } /* now (ind) is pattern of ii-th row of S */ S_ptr[ii+1] = S_ptr[ii] + len; /* at least (S_ptr[ii+1] - 1) locations should be available in the array S_ind */ if (S_ptr[ii+1] - 1 > size) { temp = S_ind; size += size; S_ind = xcalloc(1+size, sizeof(int)); memcpy(&S_ind[1], &temp[1], (S_ptr[ii] - 1) * sizeof(int)); xfree(temp); } xassert(S_ptr[ii+1] - 1 <= size); /* (ii-th row of S) := (ind) */ memcpy(&S_ind[S_ptr[ii]], &ind[1], len * sizeof(int)); /* clear the row pattern map */ for (t = 1; t <= len; t++) map[ind[t]] = 0; } /* free working arrays */ xfree(AT_ptr); xfree(AT_ind); xfree(ind); xfree(map); /* reallocate the array S_ind to free unused locations */ temp = S_ind; size = S_ptr[m+1] - 1; S_ind = xcalloc(1+size, sizeof(int)); memcpy(&S_ind[1], &temp[1], size * sizeof(int)); xfree(temp); return S_ind; } /*---------------------------------------------------------------------- -- adat_numeric - compute S = P*A*D*A'*P' (numeric phase). -- -- *Synopsis* -- -- #include "glpmat.h" -- void adat_numeric(int m, int n, int P_per[], -- int A_ptr[], int A_ind[], double A_val[], double D_diag[], -- int S_ptr[], int S_ind[], double S_val[], double S_diag[]); -- -- *Description* -- -- The routine adat_numeric implements the numeric phase to compute -- symmetric matrix S = P*A*D*A'*P', where P is a permutation matrix, -- A is a given sparse matrix, D is a diagonal matrix, A' is a matrix -- transposed to A, P' is an inverse of P. -- -- The parameter m is the number of rows in A and the order of P. -- -- The parameter n is the number of columns in A and the order of D. -- -- The matrix P is specified in the array P_per, which is not changed -- on exit. -- -- The matrix A is specified in the arrays A_ptr, A_ind, and A_val in -- storage-by-rows format. These arrays are not changed on exit. -- -- Diagonal elements of the matrix D are specified in the array D_diag, -- where D_diag[0] is not used, D_diag[i] = d[i,i] for i = 1, ..., n. -- The array D_diag is not changed on exit. -- -- The pattern of the upper triangular part of the matrix S without -- diagonal elements (previously computed by the routine adat_symbolic) -- is specified in the arrays S_ptr and S_ind, which are not changed on -- exit. Numeric values of non-diagonal elements of S are stored in -- corresponding locations of the array S_val, and values of diagonal -- elements of S are stored in locations S_diag[1], ..., S_diag[n]. */ void adat_numeric(int m, int n, int P_per[], int A_ptr[], int A_ind[], double A_val[], double D_diag[], int S_ptr[], int S_ind[], double S_val[], double S_diag[]) { int i, j, t, ii, jj, tt, beg, end, beg1, end1, k; double sum, *work; work = xcalloc(1+n, sizeof(double)); for (j = 1; j <= n; j++) work[j] = 0.0; /* compute S = B*D*B', where B = P*A, B' is a matrix transposed to B */ for (ii = 1; ii <= m; ii++) { i = P_per[ii]; /* i-th row of A = ii-th row of B */ /* (work) := (i-th row of A) */ beg = A_ptr[i], end = A_ptr[i+1]; for (t = beg; t < end; t++) work[A_ind[t]] = A_val[t]; /* compute ii-th row of S */ beg = S_ptr[ii], end = S_ptr[ii+1]; for (t = beg; t < end; t++) { jj = S_ind[t]; j = P_per[jj]; /* j-th row of A = jj-th row of B */ /* s[ii,jj] := sum a[i,k] * d[k,k] * a[j,k] */ sum = 0.0; beg1 = A_ptr[j], end1 = A_ptr[j+1]; for (tt = beg1; tt < end1; tt++) { k = A_ind[tt]; sum += work[k] * D_diag[k] * A_val[tt]; } S_val[t] = sum; } /* s[ii,ii] := sum a[i,k] * d[k,k] * a[i,k] */ sum = 0.0; beg = A_ptr[i], end = A_ptr[i+1]; for (t = beg; t < end; t++) { k = A_ind[t]; sum += A_val[t] * D_diag[k] * A_val[t]; work[k] = 0.0; } S_diag[ii] = sum; } xfree(work); return; } /*---------------------------------------------------------------------- -- min_degree - minimum degree ordering. -- -- *Synopsis* -- -- #include "glpmat.h" -- void min_degree(int n, int A_ptr[], int A_ind[], int P_per[]); -- -- *Description* -- -- The routine min_degree uses the minimum degree ordering algorithm -- to find a permutation matrix P for a given sparse symmetric positive -- matrix A which minimizes the number of non-zeros in upper triangular -- factor U for Cholesky factorization P*A*P' = U'*U. -- -- The parameter n is the order of matrices A and P. -- -- The pattern of the given matrix A is specified on entry in the arrays -- A_ptr and A_ind in storage-by-rows format. Only the upper triangular -- part without diagonal elements (which all are assumed to be non-zero) -- should be specified as if A were upper triangular. The arrays A_ptr -- and A_ind are not changed on exit. -- -- The permutation matrix P is stored by the routine in the array P_per -- on exit. -- -- *Algorithm* -- -- The routine min_degree is based on some subroutines from the package -- SPARSPAK (see comments in the module glpqmd). */ void min_degree(int n, int A_ptr[], int A_ind[], int P_per[]) { int i, j, ne, t, pos, len; int *xadj, *adjncy, *deg, *marker, *rchset, *nbrhd, *qsize, *qlink, nofsub; /* determine number of non-zeros in complete pattern */ ne = A_ptr[n+1] - 1; ne += ne; /* allocate working arrays */ xadj = xcalloc(1+n+1, sizeof(int)); adjncy = xcalloc(1+ne, sizeof(int)); deg = xcalloc(1+n, sizeof(int)); marker = xcalloc(1+n, sizeof(int)); rchset = xcalloc(1+n, sizeof(int)); nbrhd = xcalloc(1+n, sizeof(int)); qsize = xcalloc(1+n, sizeof(int)); qlink = xcalloc(1+n, sizeof(int)); /* determine row lengths in complete pattern */ for (i = 1; i <= n; i++) xadj[i] = 0; for (i = 1; i <= n; i++) { for (t = A_ptr[i]; t < A_ptr[i+1]; t++) { j = A_ind[t]; xassert(i < j && j <= n); xadj[i]++, xadj[j]++; } } /* set up row pointers for complete pattern */ pos = 1; for (i = 1; i <= n; i++) len = xadj[i], pos += len, xadj[i] = pos; xadj[n+1] = pos; xassert(pos - 1 == ne); /* construct complete pattern */ for (i = 1; i <= n; i++) { for (t = A_ptr[i]; t < A_ptr[i+1]; t++) { j = A_ind[t]; adjncy[--xadj[i]] = j, adjncy[--xadj[j]] = i; } } /* call the main minimimum degree ordering routine */ genqmd(&n, xadj, adjncy, P_per, P_per + n, deg, marker, rchset, nbrhd, qsize, qlink, &nofsub); /* make sure that permutation matrix P is correct */ for (i = 1; i <= n; i++) { j = P_per[i]; xassert(1 <= j && j <= n); xassert(P_per[n+j] == i); } /* free working arrays */ xfree(xadj); xfree(adjncy); xfree(deg); xfree(marker); xfree(rchset); xfree(nbrhd); xfree(qsize); xfree(qlink); return; } /**********************************************************************/ void amd_order1(int n, int A_ptr[], int A_ind[], int P_per[]) { /* approximate minimum degree ordering (AMD) */ int k, ret; double Control[AMD_CONTROL], Info[AMD_INFO]; /* get the default parameters */ amd_defaults(Control); #if 0 /* and print them */ amd_control(Control); #endif /* make all indices 0-based */ for (k = 1; k < A_ptr[n+1]; k++) A_ind[k]--; for (k = 1; k <= n+1; k++) A_ptr[k]--; /* call the ordering routine */ ret = amd_order(n, &A_ptr[1], &A_ind[1], &P_per[1], Control, Info) ; #if 0 amd_info(Info); #endif xassert(ret == AMD_OK || ret == AMD_OK_BUT_JUMBLED); /* retsore 1-based indices */ for (k = 1; k <= n+1; k++) A_ptr[k]++; for (k = 1; k < A_ptr[n+1]; k++) A_ind[k]++; /* patch up permutation matrix */ memset(&P_per[n+1], 0, n * sizeof(int)); for (k = 1; k <= n; k++) { P_per[k]++; xassert(1 <= P_per[k] && P_per[k] <= n); xassert(P_per[n+P_per[k]] == 0); P_per[n+P_per[k]] = k; } return; } /**********************************************************************/ static void *allocate(size_t n, size_t size) { void *ptr; ptr = xcalloc(n, size); memset(ptr, 0, n * size); return ptr; } static void release(void *ptr) { xfree(ptr); return; } void symamd_ord(int n, int A_ptr[], int A_ind[], int P_per[]) { /* approximate minimum degree ordering (SYMAMD) */ int k, ok; int stats[COLAMD_STATS]; /* make all indices 0-based */ for (k = 1; k < A_ptr[n+1]; k++) A_ind[k]--; for (k = 1; k <= n+1; k++) A_ptr[k]--; /* call the ordering routine */ ok = symamd(n, &A_ind[1], &A_ptr[1], &P_per[1], NULL, stats, allocate, release); #if 0 symamd_report(stats); #endif xassert(ok); /* restore 1-based indices */ for (k = 1; k <= n+1; k++) A_ptr[k]++; for (k = 1; k < A_ptr[n+1]; k++) A_ind[k]++; /* patch up permutation matrix */ memset(&P_per[n+1], 0, n * sizeof(int)); for (k = 1; k <= n; k++) { P_per[k]++; xassert(1 <= P_per[k] && P_per[k] <= n); xassert(P_per[n+P_per[k]] == 0); P_per[n+P_per[k]] = k; } return; } /*---------------------------------------------------------------------- -- chol_symbolic - compute Cholesky factorization (symbolic phase). -- -- *Synopsis* -- -- #include "glpmat.h" -- int *chol_symbolic(int n, int A_ptr[], int A_ind[], int U_ptr[]); -- -- *Description* -- -- The routine chol_symbolic implements the symbolic phase of Cholesky -- factorization A = U'*U, where A is a given sparse symmetric positive -- definite matrix, U is a resultant upper triangular factor, U' is a -- matrix transposed to U. -- -- The parameter n is the order of matrices A and U. -- -- The pattern of the given matrix A is specified on entry in the arrays -- A_ptr and A_ind in storage-by-rows format. Only the upper triangular -- part without diagonal elements (which all are assumed to be non-zero) -- should be specified as if A were upper triangular. The arrays A_ptr -- and A_ind are not changed on exit. -- -- The pattern of the matrix U without diagonal elements (which all are -- assumed to be non-zero) is stored on exit from the routine in the -- arrays U_ptr and U_ind in storage-by-rows format. The array U_ptr -- should be allocated on entry, however, its content is ignored. The -- array U_ind is allocated by the routine which returns a pointer to it -- on exit. -- -- *Returns* -- -- The routine returns a pointer to the array U_ind. -- -- *Method* -- -- The routine chol_symbolic computes the pattern of the matrix U in a -- row-wise manner. No pivoting is used. -- -- It is known that to compute the pattern of row k of the matrix U we -- need to merge the pattern of row k of the matrix A and the patterns -- of each row i of U, where u[i,k] is non-zero (these rows are already -- computed and placed above row k). -- -- However, to reduce the number of rows to be merged the routine uses -- an advanced algorithm proposed in: -- -- D.J.Rose, R.E.Tarjan, and G.S.Lueker. Algorithmic aspects of vertex -- elimination on graphs. SIAM J. Comput. 5, 1976, 266-83. -- -- The authors of the cited paper show that we have the same result if -- we merge row k of the matrix A and such rows of the matrix U (among -- rows 1, ..., k-1) whose leftmost non-diagonal non-zero element is -- placed in k-th column. This feature signficantly reduces the number -- of rows to be merged, especially on the final steps, where rows of -- the matrix U become quite dense. -- -- To determine rows, which should be merged on k-th step, for a fixed -- time the routine uses linked lists of row numbers of the matrix U. -- Location head[k] contains the number of a first row, whose leftmost -- non-diagonal non-zero element is placed in column k, and location -- next[i] contains the number of a next row with the same property as -- row i. */ int *chol_symbolic(int n, int A_ptr[], int A_ind[], int U_ptr[]) { int i, j, k, t, len, size, beg, end, min_j, *U_ind, *head, *next, *ind, *map, *temp; /* initially we assume that on computing the pattern of U fill-in will double the number of non-zeros in A */ size = A_ptr[n+1] - 1; if (size < n) size = n; size += size; U_ind = xcalloc(1+size, sizeof(int)); /* allocate and initialize working arrays */ head = xcalloc(1+n, sizeof(int)); for (i = 1; i <= n; i++) head[i] = 0; next = xcalloc(1+n, sizeof(int)); ind = xcalloc(1+n, sizeof(int)); map = xcalloc(1+n, sizeof(int)); for (j = 1; j <= n; j++) map[j] = 0; /* compute the pattern of matrix U */ U_ptr[1] = 1; for (k = 1; k <= n; k++) { /* compute the pattern of k-th row of U, which is the union of k-th row of A and those rows of U (among 1, ..., k-1) whose leftmost non-diagonal non-zero is placed in k-th column */ /* (ind) := (k-th row of A) */ len = A_ptr[k+1] - A_ptr[k]; memcpy(&ind[1], &A_ind[A_ptr[k]], len * sizeof(int)); for (t = 1; t <= len; t++) { j = ind[t]; xassert(k < j && j <= n); map[j] = 1; } /* walk through rows of U whose leftmost non-diagonal non-zero is placed in k-th column */ for (i = head[k]; i != 0; i = next[i]) { /* (ind) := (ind) union (i-th row of U) */ beg = U_ptr[i], end = U_ptr[i+1]; for (t = beg; t < end; t++) { j = U_ind[t]; if (j > k && !map[j]) ind[++len] = j, map[j] = 1; } } /* now (ind) is the pattern of k-th row of U */ U_ptr[k+1] = U_ptr[k] + len; /* at least (U_ptr[k+1] - 1) locations should be available in the array U_ind */ if (U_ptr[k+1] - 1 > size) { temp = U_ind; size += size; U_ind = xcalloc(1+size, sizeof(int)); memcpy(&U_ind[1], &temp[1], (U_ptr[k] - 1) * sizeof(int)); xfree(temp); } xassert(U_ptr[k+1] - 1 <= size); /* (k-th row of U) := (ind) */ memcpy(&U_ind[U_ptr[k]], &ind[1], len * sizeof(int)); /* determine column index of leftmost non-diagonal non-zero in k-th row of U and clear the row pattern map */ min_j = n + 1; for (t = 1; t <= len; t++) { j = ind[t], map[j] = 0; if (min_j > j) min_j = j; } /* include k-th row into corresponding linked list */ if (min_j <= n) next[k] = head[min_j], head[min_j] = k; } /* free working arrays */ xfree(head); xfree(next); xfree(ind); xfree(map); /* reallocate the array U_ind to free unused locations */ temp = U_ind; size = U_ptr[n+1] - 1; U_ind = xcalloc(1+size, sizeof(int)); memcpy(&U_ind[1], &temp[1], size * sizeof(int)); xfree(temp); return U_ind; } /*---------------------------------------------------------------------- -- chol_numeric - compute Cholesky factorization (numeric phase). -- -- *Synopsis* -- -- #include "glpmat.h" -- int chol_numeric(int n, -- int A_ptr[], int A_ind[], double A_val[], double A_diag[], -- int U_ptr[], int U_ind[], double U_val[], double U_diag[]); -- -- *Description* -- -- The routine chol_symbolic implements the numeric phase of Cholesky -- factorization A = U'*U, where A is a given sparse symmetric positive -- definite matrix, U is a resultant upper triangular factor, U' is a -- matrix transposed to U. -- -- The parameter n is the order of matrices A and U. -- -- Upper triangular part of the matrix A without diagonal elements is -- specified in the arrays A_ptr, A_ind, and A_val in storage-by-rows -- format. Diagonal elements of A are specified in the array A_diag, -- where A_diag[0] is not used, A_diag[i] = a[i,i] for i = 1, ..., n. -- The arrays A_ptr, A_ind, A_val, and A_diag are not changed on exit. -- -- The pattern of the matrix U without diagonal elements (previously -- computed with the routine chol_symbolic) is specified in the arrays -- U_ptr and U_ind, which are not changed on exit. Numeric values of -- non-diagonal elements of U are stored in corresponding locations of -- the array U_val, and values of diagonal elements of U are stored in -- locations U_diag[1], ..., U_diag[n]. -- -- *Returns* -- -- The routine returns the number of non-positive diagonal elements of -- the matrix U which have been replaced by a huge positive number (see -- the method description below). Zero return code means the matrix A -- has been successfully factorized. -- -- *Method* -- -- The routine chol_numeric computes the matrix U in a row-wise manner -- using standard gaussian elimination technique. No pivoting is used. -- -- Initially the routine sets U = A, and before k-th elimination step -- the matrix U is the following: -- -- 1 k n -- 1 x x x x x x x x x x -- . x x x x x x x x x -- . . x x x x x x x x -- . . . x x x x x x x -- k . . . . * * * * * * -- . . . . * * * * * * -- . . . . * * * * * * -- . . . . * * * * * * -- . . . . * * * * * * -- n . . . . * * * * * * -- -- where 'x' are elements of already computed rows, '*' are elements of -- the active submatrix. (Note that the lower triangular part of the -- active submatrix being symmetric is not stored and diagonal elements -- are stored separately in the array U_diag.) -- -- The matrix A is assumed to be positive definite. However, if it is -- close to semi-definite, on some elimination step a pivot u[k,k] may -- happen to be non-positive due to round-off errors. In this case the -- routine uses a technique proposed in: -- -- S.J.Wright. The Cholesky factorization in interior-point and barrier -- methods. Preprint MCS-P600-0596, Mathematics and Computer Science -- Division, Argonne National Laboratory, Argonne, Ill., May 1996. -- -- The routine just replaces non-positive u[k,k] by a huge positive -- number. This involves non-diagonal elements in k-th row of U to be -- close to zero that, in turn, involves k-th component of a solution -- vector to be close to zero. Note, however, that this technique works -- only if the system A*x = b is consistent. */ int chol_numeric(int n, int A_ptr[], int A_ind[], double A_val[], double A_diag[], int U_ptr[], int U_ind[], double U_val[], double U_diag[]) { int i, j, k, t, t1, beg, end, beg1, end1, count = 0; double ukk, uki, *work; work = xcalloc(1+n, sizeof(double)); for (j = 1; j <= n; j++) work[j] = 0.0; /* U := (upper triangle of A) */ /* note that the upper traingle of A is a subset of U */ for (i = 1; i <= n; i++) { beg = A_ptr[i], end = A_ptr[i+1]; for (t = beg; t < end; t++) j = A_ind[t], work[j] = A_val[t]; beg = U_ptr[i], end = U_ptr[i+1]; for (t = beg; t < end; t++) j = U_ind[t], U_val[t] = work[j], work[j] = 0.0; U_diag[i] = A_diag[i]; } /* main elimination loop */ for (k = 1; k <= n; k++) { /* transform k-th row of U */ ukk = U_diag[k]; if (ukk > 0.0) U_diag[k] = ukk = sqrt(ukk); else U_diag[k] = ukk = DBL_MAX, count++; /* (work) := (transformed k-th row) */ beg = U_ptr[k], end = U_ptr[k+1]; for (t = beg; t < end; t++) work[U_ind[t]] = (U_val[t] /= ukk); /* transform other rows of U */ for (t = beg; t < end; t++) { i = U_ind[t]; xassert(i > k); /* (i-th row) := (i-th row) - u[k,i] * (k-th row) */ uki = work[i]; beg1 = U_ptr[i], end1 = U_ptr[i+1]; for (t1 = beg1; t1 < end1; t1++) U_val[t1] -= uki * work[U_ind[t1]]; U_diag[i] -= uki * uki; } /* (work) := 0 */ for (t = beg; t < end; t++) work[U_ind[t]] = 0.0; } xfree(work); return count; } /*---------------------------------------------------------------------- -- u_solve - solve upper triangular system U*x = b. -- -- *Synopsis* -- -- #include "glpmat.h" -- void u_solve(int n, int U_ptr[], int U_ind[], double U_val[], -- double U_diag[], double x[]); -- -- *Description* -- -- The routine u_solve solves an linear system U*x = b, where U is an -- upper triangular matrix. -- -- The parameter n is the order of matrix U. -- -- The matrix U without diagonal elements is specified in the arrays -- U_ptr, U_ind, and U_val in storage-by-rows format. Diagonal elements -- of U are specified in the array U_diag, where U_diag[0] is not used, -- U_diag[i] = u[i,i] for i = 1, ..., n. All these four arrays are not -- changed on exit. -- -- The right-hand side vector b is specified on entry in the array x, -- where x[0] is not used, and x[i] = b[i] for i = 1, ..., n. On exit -- the routine stores computed components of the vector of unknowns x -- in the array x in the same manner. */ void u_solve(int n, int U_ptr[], int U_ind[], double U_val[], double U_diag[], double x[]) { int i, t, beg, end; double temp; for (i = n; i >= 1; i--) { temp = x[i]; beg = U_ptr[i], end = U_ptr[i+1]; for (t = beg; t < end; t++) temp -= U_val[t] * x[U_ind[t]]; xassert(U_diag[i] != 0.0); x[i] = temp / U_diag[i]; } return; } /*---------------------------------------------------------------------- -- ut_solve - solve lower triangular system U'*x = b. -- -- *Synopsis* -- -- #include "glpmat.h" -- void ut_solve(int n, int U_ptr[], int U_ind[], double U_val[], -- double U_diag[], double x[]); -- -- *Description* -- -- The routine ut_solve solves an linear system U'*x = b, where U is a -- matrix transposed to an upper triangular matrix. -- -- The parameter n is the order of matrix U. -- -- The matrix U without diagonal elements is specified in the arrays -- U_ptr, U_ind, and U_val in storage-by-rows format. Diagonal elements -- of U are specified in the array U_diag, where U_diag[0] is not used, -- U_diag[i] = u[i,i] for i = 1, ..., n. All these four arrays are not -- changed on exit. -- -- The right-hand side vector b is specified on entry in the array x, -- where x[0] is not used, and x[i] = b[i] for i = 1, ..., n. On exit -- the routine stores computed components of the vector of unknowns x -- in the array x in the same manner. */ void ut_solve(int n, int U_ptr[], int U_ind[], double U_val[], double U_diag[], double x[]) { int i, t, beg, end; double temp; for (i = 1; i <= n; i++) { xassert(U_diag[i] != 0.0); temp = (x[i] /= U_diag[i]); if (temp == 0.0) continue; beg = U_ptr[i], end = U_ptr[i+1]; for (t = beg; t < end; t++) x[U_ind[t]] -= U_val[t] * temp; } return; } /* eof */ praat-6.0.04/external/glpk/glpmat.h000066400000000000000000000164601261542461700171430ustar00rootroot00000000000000/* glpmat.h (linear algebra routines) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPMAT_H #define GLPMAT_H /*********************************************************************** * FULL-VECTOR STORAGE * * For a sparse vector x having n elements, ne of which are non-zero, * the full-vector storage format uses two arrays x_ind and x_vec, which * are set up as follows: * * x_ind is an integer array of length [1+ne]. Location x_ind[0] is * not used, and locations x_ind[1], ..., x_ind[ne] contain indices of * non-zero elements in vector x. * * x_vec is a floating-point array of length [1+n]. Location x_vec[0] * is not used, and locations x_vec[1], ..., x_vec[n] contain numeric * values of ALL elements in vector x, including its zero elements. * * Let, for example, the following sparse vector x be given: * * (0, 1, 0, 0, 2, 3, 0, 4) * * Then the arrays are: * * x_ind = { X; 2, 5, 6, 8 } * * x_vec = { X; 0, 1, 0, 0, 2, 3, 0, 4 } * * COMPRESSED-VECTOR STORAGE * * For a sparse vector x having n elements, ne of which are non-zero, * the compressed-vector storage format uses two arrays x_ind and x_vec, * which are set up as follows: * * x_ind is an integer array of length [1+ne]. Location x_ind[0] is * not used, and locations x_ind[1], ..., x_ind[ne] contain indices of * non-zero elements in vector x. * * x_vec is a floating-point array of length [1+ne]. Location x_vec[0] * is not used, and locations x_vec[1], ..., x_vec[ne] contain numeric * values of corresponding non-zero elements in vector x. * * Let, for example, the following sparse vector x be given: * * (0, 1, 0, 0, 2, 3, 0, 4) * * Then the arrays are: * * x_ind = { X; 2, 5, 6, 8 } * * x_vec = { X; 1, 2, 3, 4 } * * STORAGE-BY-ROWS * * For a sparse matrix A, which has m rows, n columns, and ne non-zero * elements the storage-by-rows format uses three arrays A_ptr, A_ind, * and A_val, which are set up as follows: * * A_ptr is an integer array of length [1+m+1] also called "row pointer * array". It contains the relative starting positions of each row of A * in the arrays A_ind and A_val, i.e. element A_ptr[i], 1 <= i <= m, * indicates where row i begins in the arrays A_ind and A_val. If all * elements in row i are zero, then A_ptr[i] = A_ptr[i+1]. Location * A_ptr[0] is not used, location A_ptr[1] must contain 1, and location * A_ptr[m+1] must contain ne+1 that indicates the position after the * last element in the arrays A_ind and A_val. * * A_ind is an integer array of length [1+ne]. Location A_ind[0] is not * used, and locations A_ind[1], ..., A_ind[ne] contain column indices * of (non-zero) elements in matrix A. * * A_val is a floating-point array of length [1+ne]. Location A_val[0] * is not used, and locations A_val[1], ..., A_val[ne] contain numeric * values of non-zero elements in matrix A. * * Non-zero elements of matrix A are stored contiguously, and the rows * of matrix A are stored consecutively from 1 to m in the arrays A_ind * and A_val. The elements in each row of A may be stored in any order * in A_ind and A_val. Note that elements with duplicate column indices * are not allowed. * * Let, for example, the following sparse matrix A be given: * * | 11 . 13 . . . | * | 21 22 . 24 . . | * | . 32 33 . . . | * | . . 43 44 . 46 | * | . . . . . . | * | 61 62 . . . 66 | * * Then the arrays are: * * A_ptr = { X; 1, 3, 6, 8, 11, 11; 14 } * * A_ind = { X; 1, 3; 4, 2, 1; 2, 3; 4, 3, 6; 1, 2, 6 } * * A_val = { X; 11, 13; 24, 22, 21; 32, 33; 44, 43, 46; 61, 62, 66 } * * PERMUTATION MATRICES * * Let P be a permutation matrix of the order n. It is represented as * an integer array P_per of length [1+n+n] as follows: if p[i,j] = 1, * then P_per[i] = j and P_per[n+j] = i. Location P_per[0] is not used. * * Let A' = P*A. If i-th row of A corresponds to i'-th row of A', then * P_per[i'] = i and P_per[n+i] = i'. * * References: * * 1. Gustavson F.G. Some basic techniques for solving sparse systems of * linear equations. In Rose and Willoughby (1972), pp. 41-52. * * 2. Basic Linear Algebra Subprograms Technical (BLAST) Forum Standard. * University of Tennessee (2001). */ #define check_fvs _glp_mat_check_fvs int check_fvs(int n, int nnz, int ind[], double vec[]); /* check sparse vector in full-vector storage format */ #define check_pattern _glp_mat_check_pattern int check_pattern(int m, int n, int A_ptr[], int A_ind[]); /* check pattern of sparse matrix */ #define transpose _glp_mat_transpose void transpose(int m, int n, int A_ptr[], int A_ind[], double A_val[], int AT_ptr[], int AT_ind[], double AT_val[]); /* transpose sparse matrix */ #define adat_symbolic _glp_mat_adat_symbolic int *adat_symbolic(int m, int n, int P_per[], int A_ptr[], int A_ind[], int S_ptr[]); /* compute S = P*A*D*A'*P' (symbolic phase) */ #define adat_numeric _glp_mat_adat_numeric void adat_numeric(int m, int n, int P_per[], int A_ptr[], int A_ind[], double A_val[], double D_diag[], int S_ptr[], int S_ind[], double S_val[], double S_diag[]); /* compute S = P*A*D*A'*P' (numeric phase) */ #define min_degree _glp_mat_min_degree void min_degree(int n, int A_ptr[], int A_ind[], int P_per[]); /* minimum degree ordering */ #define amd_order1 _glp_mat_amd_order1 void amd_order1(int n, int A_ptr[], int A_ind[], int P_per[]); /* approximate minimum degree ordering (AMD) */ #define symamd_ord _glp_mat_symamd_ord void symamd_ord(int n, int A_ptr[], int A_ind[], int P_per[]); /* approximate minimum degree ordering (SYMAMD) */ #define chol_symbolic _glp_mat_chol_symbolic int *chol_symbolic(int n, int A_ptr[], int A_ind[], int U_ptr[]); /* compute Cholesky factorization (symbolic phase) */ #define chol_numeric _glp_mat_chol_numeric int chol_numeric(int n, int A_ptr[], int A_ind[], double A_val[], double A_diag[], int U_ptr[], int U_ind[], double U_val[], double U_diag[]); /* compute Cholesky factorization (numeric phase) */ #define u_solve _glp_mat_u_solve void u_solve(int n, int U_ptr[], int U_ind[], double U_val[], double U_diag[], double x[]); /* solve upper triangular system U*x = b */ #define ut_solve _glp_mat_ut_solve void ut_solve(int n, int U_ptr[], int U_ind[], double U_val[], double U_diag[], double x[]); /* solve lower triangular system U'*x = b */ #endif /* eof */ praat-6.0.04/external/glpk/glpmpl.h000066400000000000000000002571571261542461700171640ustar00rootroot00000000000000/* glpmpl.h (GNU MathProg translator) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPMPL_H #define GLPMPL_H #include "glpavl.h" #include "glprng.h" typedef struct MPL MPL; typedef char STRING; typedef struct SYMBOL SYMBOL; typedef struct TUPLE TUPLE; typedef struct ARRAY ELEMSET; typedef struct ELEMVAR ELEMVAR; typedef struct FORMULA FORMULA; typedef struct ELEMCON ELEMCON; typedef union VALUE VALUE; typedef struct ARRAY ARRAY; typedef struct MEMBER MEMBER; #if 1 /* many C compilers have DOMAIN declared in :( */ #undef DOMAIN #define DOMAIN DOMAIN1 #endif typedef struct DOMAIN DOMAIN; typedef struct DOMAIN_BLOCK DOMAIN_BLOCK; typedef struct DOMAIN_SLOT DOMAIN_SLOT; typedef struct SET SET; typedef struct WITHIN WITHIN; typedef struct GADGET GADGET; typedef struct PARAMETER PARAMETER; typedef struct CONDITION CONDITION; typedef struct VARIABLE VARIABLE; typedef struct CONSTRAINT CONSTRAINT; typedef struct TABLE TABLE; typedef struct TABARG TABARG; typedef struct TABFLD TABFLD; typedef struct TABIN TABIN; typedef struct TABOUT TABOUT; typedef struct TABDCA TABDCA; typedef union OPERANDS OPERANDS; typedef struct ARG_LIST ARG_LIST; typedef struct CODE CODE; typedef struct CHECK CHECK; typedef struct DISPLAY DISPLAY; typedef struct DISPLAY1 DISPLAY1; typedef struct PRINTF PRINTF; typedef struct PRINTF1 PRINTF1; typedef struct FOR FOR; typedef struct STATEMENT STATEMENT; typedef struct TUPLE SLICE; /**********************************************************************/ /* * * TRANSLATOR DATABASE * * */ /**********************************************************************/ #define A_BINARY 101 /* something binary */ #define A_CHECK 102 /* check statement */ #define A_CONSTRAINT 103 /* model constraint */ #define A_DISPLAY 104 /* display statement */ #define A_ELEMCON 105 /* elemental constraint/objective */ #define A_ELEMSET 106 /* elemental set */ #define A_ELEMVAR 107 /* elemental variable */ #define A_EXPRESSION 108 /* expression */ #define A_FOR 109 /* for statement */ #define A_FORMULA 110 /* formula */ #define A_INDEX 111 /* dummy index */ #define A_INPUT 112 /* input table */ #define A_INTEGER 113 /* something integer */ #define A_LOGICAL 114 /* something logical */ #define A_MAXIMIZE 115 /* objective has to be maximized */ #define A_MINIMIZE 116 /* objective has to be minimized */ #define A_NONE 117 /* nothing */ #define A_NUMERIC 118 /* something numeric */ #define A_OUTPUT 119 /* output table */ #define A_PARAMETER 120 /* model parameter */ #define A_PRINTF 121 /* printf statement */ #define A_SET 122 /* model set */ #define A_SOLVE 123 /* solve statement */ #define A_SYMBOLIC 124 /* something symbolic */ #define A_TABLE 125 /* data table */ #define A_TUPLE 126 /* n-tuple */ #define A_VARIABLE 127 /* model variable */ #define MAX_LENGTH 100 /* maximal length of any symbolic value (this includes symbolic names, numeric and string literals, and all symbolic values that may appear during the evaluation phase) */ #define CONTEXT_SIZE 60 /* size of the context queue, in characters */ #define OUTBUF_SIZE 1024 /* size of the output buffer, in characters */ struct MPL { /* translator database */ /*--------------------------------------------------------------*/ /* scanning segment */ int line; /* number of the current text line */ int c; /* the current character or EOF */ int token; /* the current token: */ #define T_EOF 201 /* end of file */ #define T_NAME 202 /* symbolic name (model section only) */ #define T_SYMBOL 203 /* symbol (data section only) */ #define T_NUMBER 204 /* numeric literal */ #define T_STRING 205 /* string literal */ #define T_AND 206 /* and && */ #define T_BY 207 /* by */ #define T_CROSS 208 /* cross */ #define T_DIFF 209 /* diff */ #define T_DIV 210 /* div */ #define T_ELSE 211 /* else */ #define T_IF 212 /* if */ #define T_IN 213 /* in */ #define T_INFINITY 214 /* Infinity */ #define T_INTER 215 /* inter */ #define T_LESS 216 /* less */ #define T_MOD 217 /* mod */ #define T_NOT 218 /* not ! */ #define T_OR 219 /* or || */ #define T_SPTP 220 /* s.t. */ #define T_SYMDIFF 221 /* symdiff */ #define T_THEN 222 /* then */ #define T_UNION 223 /* union */ #define T_WITHIN 224 /* within */ #define T_PLUS 225 /* + */ #define T_MINUS 226 /* - */ #define T_ASTERISK 227 /* * */ #define T_SLASH 228 /* / */ #define T_POWER 229 /* ^ ** */ #define T_LT 230 /* < */ #define T_LE 231 /* <= */ #define T_EQ 232 /* = == */ #define T_GE 233 /* >= */ #define T_GT 234 /* > */ #define T_NE 235 /* <> != */ #define T_CONCAT 236 /* & */ #define T_BAR 237 /* | */ #define T_POINT 238 /* . */ #define T_COMMA 239 /* , */ #define T_COLON 240 /* : */ #define T_SEMICOLON 241 /* ; */ #define T_ASSIGN 242 /* := */ #define T_DOTS 243 /* .. */ #define T_LEFT 244 /* ( */ #define T_RIGHT 245 /* ) */ #define T_LBRACKET 246 /* [ */ #define T_RBRACKET 247 /* ] */ #define T_LBRACE 248 /* { */ #define T_RBRACE 249 /* } */ #define T_APPEND 250 /* >> */ #define T_TILDE 251 /* ~ */ #define T_INPUT 252 /* <- */ int imlen; /* length of the current token */ char *image; /* char image[MAX_LENGTH+1]; */ /* image of the current token */ double value; /* value of the current token (for T_NUMBER only) */ int b_token; /* the previous token */ int b_imlen; /* length of the previous token */ char *b_image; /* char b_image[MAX_LENGTH+1]; */ /* image of the previous token */ double b_value; /* value of the previous token (if token is T_NUMBER) */ int f_dots; /* if this flag is set, the next token should be recognized as T_DOTS, not as T_POINT */ int f_scan; /* if this flag is set, the next token is already scanned */ int f_token; /* the next token */ int f_imlen; /* length of the next token */ char *f_image; /* char f_image[MAX_LENGTH+1]; */ /* image of the next token */ double f_value; /* value of the next token (if token is T_NUMBER) */ char *context; /* char context[CONTEXT_SIZE]; */ /* context circular queue (not null-terminated!) */ int c_ptr; /* pointer to the current position in the context queue */ int flag_d; /* if this flag is set, the data section is being processed */ /*--------------------------------------------------------------*/ /* translating segment */ DMP *pool; /* memory pool used to allocate all data instances created during the translation phase */ AVL *tree; /* symbolic name table: node.type = A_INDEX => node.link -> DOMAIN_SLOT node.type = A_SET => node.link -> SET node.type = A_PARAMETER => node.link -> PARAMETER node.type = A_VARIABLE => node.link -> VARIABLE node.type = A_CONSTRANT => node.link -> CONSTRAINT */ STATEMENT *model; /* linked list of model statements in the original order */ int flag_x; /* if this flag is set, the current token being left parenthesis begins a slice that allows recognizing any undeclared symbolic names as dummy indices; this flag is automatically reset once the next token has been scanned */ int as_within; /* the warning "in understood as within" has been issued */ int as_in; /* the warning "within understood as in" has been issued */ int as_binary; /* the warning "logical understood as binary" has been issued */ int flag_s; /* if this flag is set, the solve statement has been parsed */ /*--------------------------------------------------------------*/ /* common segment */ DMP *strings; /* memory pool to allocate STRING data structures */ DMP *symbols; /* memory pool to allocate SYMBOL data structures */ DMP *tuples; /* memory pool to allocate TUPLE data structures */ DMP *arrays; /* memory pool to allocate ARRAY data structures */ DMP *members; /* memory pool to allocate MEMBER data structures */ DMP *elemvars; /* memory pool to allocate ELEMVAR data structures */ DMP *formulae; /* memory pool to allocate FORMULA data structures */ DMP *elemcons; /* memory pool to allocate ELEMCON data structures */ ARRAY *a_list; /* linked list of all arrays in the database */ char *sym_buf; /* char sym_buf[255+1]; */ /* working buffer used by the routine format_symbol */ char *tup_buf; /* char tup_buf[255+1]; */ /* working buffer used by the routine format_tuple */ /*--------------------------------------------------------------*/ /* generating/postsolving segment */ RNG *rand; /* pseudo-random number generator */ int flag_p; /* if this flag is set, the postsolving phase is in effect */ STATEMENT *stmt; /* model statement being currently executed */ TABDCA *dca; /* pointer to table driver communication area for table statement currently executed */ int m; /* number of rows in the problem, m >= 0 */ int n; /* number of columns in the problem, n >= 0 */ ELEMCON **row; /* ELEMCON *row[1+m]; */ /* row[0] is not used; row[i] is elemental constraint or objective, which corresponds to i-th row of the problem, 1 <= i <= m */ ELEMVAR **col; /* ELEMVAR *col[1+n]; */ /* col[0] is not used; col[j] is elemental variable, which corresponds to j-th column of the problem, 1 <= j <= n */ /*--------------------------------------------------------------*/ /* input/output segment */ XFILE *in_fp; /* stream assigned to the input text file */ char *in_file; /* name of the input text file */ XFILE *out_fp; /* stream assigned to the output text file used to write all data produced by display and printf statements; NULL means the data should be sent to stdout via the routine xprintf */ char *out_file; /* name of the output text file */ #if 0 /* 08/XI-2009 */ char *out_buf; /* char out_buf[OUTBUF_SIZE] */ /* buffer to accumulate output data */ int out_cnt; /* count of data bytes stored in the output buffer */ #endif XFILE *prt_fp; /* stream assigned to the print text file; may be NULL */ char *prt_file; /* name of the output print file */ /*--------------------------------------------------------------*/ /* solver interface segment */ jmp_buf jump; /* jump address for non-local go to in case of error */ int phase; /* phase of processing: 0 - database is being or has been initialized 1 - model section is being or has been read 2 - data section is being or has been read 3 - model is being or has been generated/postsolved 4 - model processing error has occurred */ char *mod_file; /* name of the input text file, which contains model section */ char *mpl_buf; /* char mpl_buf[255+1]; */ /* working buffer used by some interface routines */ }; /**********************************************************************/ /* * * PROCESSING MODEL SECTION * * */ /**********************************************************************/ #define alloc(type) ((type *)dmp_get_atomv(mpl->pool, sizeof(type))) /* allocate atom of given type */ #define enter_context _glp_mpl_enter_context void enter_context(MPL *mpl); /* enter current token into context queue */ #define print_context _glp_mpl_print_context void print_context(MPL *mpl); /* print current content of context queue */ #define get_char _glp_mpl_get_char void get_char(MPL *mpl); /* scan next character from input text file */ #define append_char _glp_mpl_append_char void append_char(MPL *mpl); /* append character to current token */ #define get_token _glp_mpl_get_token void get_token(MPL *mpl); /* scan next token from input text file */ #define unget_token _glp_mpl_unget_token void unget_token(MPL *mpl); /* return current token back to input stream */ #define is_keyword _glp_mpl_is_keyword int is_keyword(MPL *mpl, char *keyword); /* check if current token is given non-reserved keyword */ #define is_reserved _glp_mpl_is_reserved int is_reserved(MPL *mpl); /* check if current token is reserved keyword */ #define make_code _glp_mpl_make_code CODE *make_code(MPL *mpl, int op, OPERANDS *arg, int type, int dim); /* generate pseudo-code (basic routine) */ #define make_unary _glp_mpl_make_unary CODE *make_unary(MPL *mpl, int op, CODE *x, int type, int dim); /* generate pseudo-code for unary operation */ #define make_binary _glp_mpl_make_binary CODE *make_binary(MPL *mpl, int op, CODE *x, CODE *y, int type, int dim); /* generate pseudo-code for binary operation */ #define make_ternary _glp_mpl_make_ternary CODE *make_ternary(MPL *mpl, int op, CODE *x, CODE *y, CODE *z, int type, int dim); /* generate pseudo-code for ternary operation */ #define numeric_literal _glp_mpl_numeric_literal CODE *numeric_literal(MPL *mpl); /* parse reference to numeric literal */ #define string_literal _glp_mpl_string_literal CODE *string_literal(MPL *mpl); /* parse reference to string literal */ #define create_arg_list _glp_mpl_create_arg_list ARG_LIST *create_arg_list(MPL *mpl); /* create empty operands list */ #define expand_arg_list _glp_mpl_expand_arg_list ARG_LIST *expand_arg_list(MPL *mpl, ARG_LIST *list, CODE *x); /* append operand to operands list */ #define arg_list_len _glp_mpl_arg_list_len int arg_list_len(MPL *mpl, ARG_LIST *list); /* determine length of operands list */ #define subscript_list _glp_mpl_subscript_list ARG_LIST *subscript_list(MPL *mpl); /* parse subscript list */ #define object_reference _glp_mpl_object_reference CODE *object_reference(MPL *mpl); /* parse reference to named object */ #define numeric_argument _glp_mpl_numeric_argument CODE *numeric_argument(MPL *mpl, char *func); /* parse argument passed to built-in function */ #define symbolic_argument _glp_mpl_symbolic_argument CODE *symbolic_argument(MPL *mpl, char *func); #define elemset_argument _glp_mpl_elemset_argument CODE *elemset_argument(MPL *mpl, char *func); #define function_reference _glp_mpl_function_reference CODE *function_reference(MPL *mpl); /* parse reference to built-in function */ #define create_domain _glp_mpl_create_domain DOMAIN *create_domain(MPL *mpl); /* create empty domain */ #define create_block _glp_mpl_create_block DOMAIN_BLOCK *create_block(MPL *mpl); /* create empty domain block */ #define append_block _glp_mpl_append_block void append_block(MPL *mpl, DOMAIN *domain, DOMAIN_BLOCK *block); /* append domain block to specified domain */ #define append_slot _glp_mpl_append_slot DOMAIN_SLOT *append_slot(MPL *mpl, DOMAIN_BLOCK *block, char *name, CODE *code); /* create and append new slot to domain block */ #define expression_list _glp_mpl_expression_list CODE *expression_list(MPL *mpl); /* parse expression list */ #define literal_set _glp_mpl_literal_set CODE *literal_set(MPL *mpl, CODE *code); /* parse literal set */ #define indexing_expression _glp_mpl_indexing_expression DOMAIN *indexing_expression(MPL *mpl); /* parse indexing expression */ #define close_scope _glp_mpl_close_scope void close_scope(MPL *mpl, DOMAIN *domain); /* close scope of indexing expression */ #define iterated_expression _glp_mpl_iterated_expression CODE *iterated_expression(MPL *mpl); /* parse iterated expression */ #define domain_arity _glp_mpl_domain_arity int domain_arity(MPL *mpl, DOMAIN *domain); /* determine arity of domain */ #define set_expression _glp_mpl_set_expression CODE *set_expression(MPL *mpl); /* parse set expression */ #define branched_expression _glp_mpl_branched_expression CODE *branched_expression(MPL *mpl); /* parse conditional expression */ #define primary_expression _glp_mpl_primary_expression CODE *primary_expression(MPL *mpl); /* parse primary expression */ #define error_preceding _glp_mpl_error_preceding void error_preceding(MPL *mpl, char *opstr); /* raise error if preceding operand has wrong type */ #define error_following _glp_mpl_error_following void error_following(MPL *mpl, char *opstr); /* raise error if following operand has wrong type */ #define error_dimension _glp_mpl_error_dimension void error_dimension(MPL *mpl, char *opstr, int dim1, int dim2); /* raise error if operands have different dimension */ #define expression_0 _glp_mpl_expression_0 CODE *expression_0(MPL *mpl); /* parse expression of level 0 */ #define expression_1 _glp_mpl_expression_1 CODE *expression_1(MPL *mpl); /* parse expression of level 1 */ #define expression_2 _glp_mpl_expression_2 CODE *expression_2(MPL *mpl); /* parse expression of level 2 */ #define expression_3 _glp_mpl_expression_3 CODE *expression_3(MPL *mpl); /* parse expression of level 3 */ #define expression_4 _glp_mpl_expression_4 CODE *expression_4(MPL *mpl); /* parse expression of level 4 */ #define expression_5 _glp_mpl_expression_5 CODE *expression_5(MPL *mpl); /* parse expression of level 5 */ #define expression_6 _glp_mpl_expression_6 CODE *expression_6(MPL *mpl); /* parse expression of level 6 */ #define expression_7 _glp_mpl_expression_7 CODE *expression_7(MPL *mpl); /* parse expression of level 7 */ #define expression_8 _glp_mpl_expression_8 CODE *expression_8(MPL *mpl); /* parse expression of level 8 */ #define expression_9 _glp_mpl_expression_9 CODE *expression_9(MPL *mpl); /* parse expression of level 9 */ #define expression_10 _glp_mpl_expression_10 CODE *expression_10(MPL *mpl); /* parse expression of level 10 */ #define expression_11 _glp_mpl_expression_11 CODE *expression_11(MPL *mpl); /* parse expression of level 11 */ #define expression_12 _glp_mpl_expression_12 CODE *expression_12(MPL *mpl); /* parse expression of level 12 */ #define expression_13 _glp_mpl_expression_13 CODE *expression_13(MPL *mpl); /* parse expression of level 13 */ #define set_statement _glp_mpl_set_statement SET *set_statement(MPL *mpl); /* parse set statement */ #define parameter_statement _glp_mpl_parameter_statement PARAMETER *parameter_statement(MPL *mpl); /* parse parameter statement */ #define variable_statement _glp_mpl_variable_statement VARIABLE *variable_statement(MPL *mpl); /* parse variable statement */ #define constraint_statement _glp_mpl_constraint_statement CONSTRAINT *constraint_statement(MPL *mpl); /* parse constraint statement */ #define objective_statement _glp_mpl_objective_statement CONSTRAINT *objective_statement(MPL *mpl); /* parse objective statement */ #define table_statement _glp_mpl_table_statement TABLE *table_statement(MPL *mpl); /* parse table statement */ #define solve_statement _glp_mpl_solve_statement void *solve_statement(MPL *mpl); /* parse solve statement */ #define check_statement _glp_mpl_check_statement CHECK *check_statement(MPL *mpl); /* parse check statement */ #define display_statement _glp_mpl_display_statement DISPLAY *display_statement(MPL *mpl); /* parse display statement */ #define printf_statement _glp_mpl_printf_statement PRINTF *printf_statement(MPL *mpl); /* parse printf statement */ #define for_statement _glp_mpl_for_statement FOR *for_statement(MPL *mpl); /* parse for statement */ #define end_statement _glp_mpl_end_statement void end_statement(MPL *mpl); /* parse end statement */ #define simple_statement _glp_mpl_simple_statement STATEMENT *simple_statement(MPL *mpl, int spec); /* parse simple statement */ #define model_section _glp_mpl_model_section void model_section(MPL *mpl); /* parse model section */ /**********************************************************************/ /* * * PROCESSING DATA SECTION * * */ /**********************************************************************/ #if 2 + 2 == 5 struct SLICE /* see TUPLE */ { /* component of slice; the slice itself is associated with its first component; slices are similar to n-tuples with exception that some slice components (which are indicated by asterisks) don't refer to any symbols */ SYMBOL *sym; /* symbol, which this component refers to; can be NULL */ SLICE *next; /* the next component of slice */ }; #endif #define create_slice _glp_mpl_create_slice SLICE *create_slice(MPL *mpl); /* create slice */ #define expand_slice _glp_mpl_expand_slice SLICE *expand_slice ( MPL *mpl, SLICE *slice, /* destroyed */ SYMBOL *sym /* destroyed */ ); /* append new component to slice */ #define slice_dimen _glp_mpl_slice_dimen int slice_dimen ( MPL *mpl, SLICE *slice /* not changed */ ); /* determine dimension of slice */ #define slice_arity _glp_mpl_slice_arity int slice_arity ( MPL *mpl, SLICE *slice /* not changed */ ); /* determine arity of slice */ #define fake_slice _glp_mpl_fake_slice SLICE *fake_slice(MPL *mpl, int dim); /* create fake slice of all asterisks */ #define delete_slice _glp_mpl_delete_slice void delete_slice ( MPL *mpl, SLICE *slice /* destroyed */ ); /* delete slice */ #define is_number _glp_mpl_is_number int is_number(MPL *mpl); /* check if current token is number */ #define is_symbol _glp_mpl_is_symbol int is_symbol(MPL *mpl); /* check if current token is symbol */ #define is_literal _glp_mpl_is_literal int is_literal(MPL *mpl, char *literal); /* check if current token is given symbolic literal */ #define read_number _glp_mpl_read_number double read_number(MPL *mpl); /* read number */ #define read_symbol _glp_mpl_read_symbol SYMBOL *read_symbol(MPL *mpl); /* read symbol */ #define read_slice _glp_mpl_read_slice SLICE *read_slice ( MPL *mpl, char *name, /* not changed */ int dim ); /* read slice */ #define select_set _glp_mpl_select_set SET *select_set ( MPL *mpl, char *name /* not changed */ ); /* select set to saturate it with elemental sets */ #define simple_format _glp_mpl_simple_format void simple_format ( MPL *mpl, SET *set, /* not changed */ MEMBER *memb, /* modified */ SLICE *slice /* not changed */ ); /* read set data block in simple format */ #define matrix_format _glp_mpl_matrix_format void matrix_format ( MPL *mpl, SET *set, /* not changed */ MEMBER *memb, /* modified */ SLICE *slice, /* not changed */ int tr ); /* read set data block in matrix format */ #define set_data _glp_mpl_set_data void set_data(MPL *mpl); /* read set data */ #define select_parameter _glp_mpl_select_parameter PARAMETER *select_parameter ( MPL *mpl, char *name /* not changed */ ); /* select parameter to saturate it with data */ #define set_default _glp_mpl_set_default void set_default ( MPL *mpl, PARAMETER *par, /* not changed */ SYMBOL *altval /* destroyed */ ); /* set default parameter value */ #define read_value _glp_mpl_read_value MEMBER *read_value ( MPL *mpl, PARAMETER *par, /* not changed */ TUPLE *tuple /* destroyed */ ); /* read value and assign it to parameter member */ #define plain_format _glp_mpl_plain_format void plain_format ( MPL *mpl, PARAMETER *par, /* not changed */ SLICE *slice /* not changed */ ); /* read parameter data block in plain format */ #define tabular_format _glp_mpl_tabular_format void tabular_format ( MPL *mpl, PARAMETER *par, /* not changed */ SLICE *slice, /* not changed */ int tr ); /* read parameter data block in tabular format */ #define tabbing_format _glp_mpl_tabbing_format void tabbing_format ( MPL *mpl, SYMBOL *altval /* not changed */ ); /* read parameter data block in tabbing format */ #define parameter_data _glp_mpl_parameter_data void parameter_data(MPL *mpl); /* read parameter data */ #define data_section _glp_mpl_data_section void data_section(MPL *mpl); /* read data section */ /**********************************************************************/ /* * * FLOATING-POINT NUMBERS * * */ /**********************************************************************/ #define fp_add _glp_mpl_fp_add double fp_add(MPL *mpl, double x, double y); /* floating-point addition */ #define fp_sub _glp_mpl_fp_sub double fp_sub(MPL *mpl, double x, double y); /* floating-point subtraction */ #define fp_less _glp_mpl_fp_less double fp_less(MPL *mpl, double x, double y); /* floating-point non-negative subtraction */ #define fp_mul _glp_mpl_fp_mul double fp_mul(MPL *mpl, double x, double y); /* floating-point multiplication */ #define fp_div _glp_mpl_fp_div double fp_div(MPL *mpl, double x, double y); /* floating-point division */ #define fp_idiv _glp_mpl_fp_idiv double fp_idiv(MPL *mpl, double x, double y); /* floating-point quotient of exact division */ #define fp_mod _glp_mpl_fp_mod double fp_mod(MPL *mpl, double x, double y); /* floating-point remainder of exact division */ #define fp_power _glp_mpl_fp_power double fp_power(MPL *mpl, double x, double y); /* floating-point exponentiation (raise to power) */ #define fp_exp _glp_mpl_fp_exp double fp_exp(MPL *mpl, double x); /* floating-point base-e exponential */ #define fp_log _glp_mpl_fp_log double fp_log(MPL *mpl, double x); /* floating-point natural logarithm */ #define fp_log10 _glp_mpl_fp_log10 double fp_log10(MPL *mpl, double x); /* floating-point common (decimal) logarithm */ #define fp_sqrt _glp_mpl_fp_sqrt double fp_sqrt(MPL *mpl, double x); /* floating-point square root */ #define fp_sin _glp_mpl_fp_sin double fp_sin(MPL *mpl, double x); /* floating-point trigonometric sine */ #define fp_cos _glp_mpl_fp_cos double fp_cos(MPL *mpl, double x); /* floating-point trigonometric cosine */ #define fp_atan _glp_mpl_fp_atan double fp_atan(MPL *mpl, double x); /* floating-point trigonometric arctangent */ #define fp_atan2 _glp_mpl_fp_atan2 double fp_atan2(MPL *mpl, double y, double x); /* floating-point trigonometric arctangent */ #define fp_round _glp_mpl_fp_round double fp_round(MPL *mpl, double x, double n); /* round floating-point value to n fractional digits */ #define fp_trunc _glp_mpl_fp_trunc double fp_trunc(MPL *mpl, double x, double n); /* truncate floating-point value to n fractional digits */ /**********************************************************************/ /* * * PSEUDO-RANDOM NUMBER GENERATORS * * */ /**********************************************************************/ #define fp_irand224 _glp_mpl_fp_irand224 double fp_irand224(MPL *mpl); /* pseudo-random integer in the range [0, 2^24) */ #define fp_uniform01 _glp_mpl_fp_uniform01 double fp_uniform01(MPL *mpl); /* pseudo-random number in the range [0, 1) */ #define fp_uniform _glp_mpl_uniform double fp_uniform(MPL *mpl, double a, double b); /* pseudo-random number in the range [a, b) */ #define fp_normal01 _glp_mpl_fp_normal01 double fp_normal01(MPL *mpl); /* Gaussian random variate with mu = 0 and sigma = 1 */ #define fp_normal _glp_mpl_fp_normal double fp_normal(MPL *mpl, double mu, double sigma); /* Gaussian random variate with specified mu and sigma */ /**********************************************************************/ /* * * DATE/TIME * * */ /**********************************************************************/ #define fn_gmtime _glp_mpl_fn_gmtime double fn_gmtime(MPL *mpl); /* obtain the current calendar time (UTC) */ #define fn_str2time _glp_mpl_fn_str2time double fn_str2time(MPL *mpl, const char *str, const char *fmt); /* convert character string to the calendar time */ #define fn_time2str _glp_mpl_fn_time2str void fn_time2str(MPL *mpl, char *str, double t, const char *fmt); /* convert the calendar time to character string */ /**********************************************************************/ /* * * CHARACTER STRINGS * * */ /**********************************************************************/ #define create_string _glp_mpl_create_string STRING *create_string ( MPL *mpl, char buf[MAX_LENGTH+1] /* not changed */ ); /* create character string */ #define copy_string _glp_mpl_copy_string STRING *copy_string ( MPL *mpl, STRING *str /* not changed */ ); /* make copy of character string */ #define compare_strings _glp_mpl_compare_strings int compare_strings ( MPL *mpl, STRING *str1, /* not changed */ STRING *str2 /* not changed */ ); /* compare one character string with another */ #define fetch_string _glp_mpl_fetch_string char *fetch_string ( MPL *mpl, STRING *str, /* not changed */ char buf[MAX_LENGTH+1] /* modified */ ); /* extract content of character string */ #define delete_string _glp_mpl_delete_string void delete_string ( MPL *mpl, STRING *str /* destroyed */ ); /* delete character string */ /**********************************************************************/ /* * * SYMBOLS * * */ /**********************************************************************/ struct SYMBOL { /* symbol (numeric or abstract quantity) */ double num; /* numeric value of symbol (used only if str == NULL) */ STRING *str; /* abstract value of symbol (used only if str != NULL) */ }; #define create_symbol_num _glp_mpl_create_symbol_num SYMBOL *create_symbol_num(MPL *mpl, double num); /* create symbol of numeric type */ #define create_symbol_str _glp_mpl_create_symbol_str SYMBOL *create_symbol_str ( MPL *mpl, STRING *str /* destroyed */ ); /* create symbol of abstract type */ #define copy_symbol _glp_mpl_copy_symbol SYMBOL *copy_symbol ( MPL *mpl, SYMBOL *sym /* not changed */ ); /* make copy of symbol */ #define compare_symbols _glp_mpl_compare_symbols int compare_symbols ( MPL *mpl, SYMBOL *sym1, /* not changed */ SYMBOL *sym2 /* not changed */ ); /* compare one symbol with another */ #define delete_symbol _glp_mpl_delete_symbol void delete_symbol ( MPL *mpl, SYMBOL *sym /* destroyed */ ); /* delete symbol */ #define format_symbol _glp_mpl_format_symbol char *format_symbol ( MPL *mpl, SYMBOL *sym /* not changed */ ); /* format symbol for displaying or printing */ #define concat_symbols _glp_mpl_concat_symbols SYMBOL *concat_symbols ( MPL *mpl, SYMBOL *sym1, /* destroyed */ SYMBOL *sym2 /* destroyed */ ); /* concatenate one symbol with another */ /**********************************************************************/ /* * * N-TUPLES * * */ /**********************************************************************/ struct TUPLE { /* component of n-tuple; the n-tuple itself is associated with its first component; (note that 0-tuple has no components) */ SYMBOL *sym; /* symbol, which the component refers to; cannot be NULL */ TUPLE *next; /* the next component of n-tuple */ }; #define create_tuple _glp_mpl_create_tuple TUPLE *create_tuple(MPL *mpl); /* create n-tuple */ #define expand_tuple _glp_mpl_expand_tuple TUPLE *expand_tuple ( MPL *mpl, TUPLE *tuple, /* destroyed */ SYMBOL *sym /* destroyed */ ); /* append symbol to n-tuple */ #define tuple_dimen _glp_mpl_tuple_dimen int tuple_dimen ( MPL *mpl, TUPLE *tuple /* not changed */ ); /* determine dimension of n-tuple */ #define copy_tuple _glp_mpl_copy_tuple TUPLE *copy_tuple ( MPL *mpl, TUPLE *tuple /* not changed */ ); /* make copy of n-tuple */ #define compare_tuples _glp_mpl_compare_tuples int compare_tuples ( MPL *mpl, TUPLE *tuple1, /* not changed */ TUPLE *tuple2 /* not changed */ ); /* compare one n-tuple with another */ #define build_subtuple _glp_mpl_build_subtuple TUPLE *build_subtuple ( MPL *mpl, TUPLE *tuple, /* not changed */ int dim ); /* build subtuple of given n-tuple */ #define delete_tuple _glp_mpl_delete_tuple void delete_tuple ( MPL *mpl, TUPLE *tuple /* destroyed */ ); /* delete n-tuple */ #define format_tuple _glp_mpl_format_tuple char *format_tuple ( MPL *mpl, int c, TUPLE *tuple /* not changed */ ); /* format n-tuple for displaying or printing */ /**********************************************************************/ /* * * ELEMENTAL SETS * * */ /**********************************************************************/ #if 2 + 2 == 5 struct ELEMSET /* see ARRAY */ { /* elemental set of n-tuples; formally it is a "value" assigned to members of model sets (like numbers and symbols, which are values assigned to members of model parameters); note that a simple model set is not an elemental set, it is 0-dimensional array, the only member of which (if it exists) is assigned an elemental set */ #endif #define create_elemset _glp_mpl_create_elemset ELEMSET *create_elemset(MPL *mpl, int dim); /* create elemental set */ #define find_tuple _glp_mpl_find_tuple MEMBER *find_tuple ( MPL *mpl, ELEMSET *set, /* not changed */ TUPLE *tuple /* not changed */ ); /* check if elemental set contains given n-tuple */ #define add_tuple _glp_mpl_add_tuple MEMBER *add_tuple ( MPL *mpl, ELEMSET *set, /* modified */ TUPLE *tuple /* destroyed */ ); /* add new n-tuple to elemental set */ #define check_then_add _glp_mpl_check_then_add MEMBER *check_then_add ( MPL *mpl, ELEMSET *set, /* modified */ TUPLE *tuple /* destroyed */ ); /* check and add new n-tuple to elemental set */ #define copy_elemset _glp_mpl_copy_elemset ELEMSET *copy_elemset ( MPL *mpl, ELEMSET *set /* not changed */ ); /* make copy of elemental set */ #define delete_elemset _glp_mpl_delete_elemset void delete_elemset ( MPL *mpl, ELEMSET *set /* destroyed */ ); /* delete elemental set */ #define arelset_size _glp_mpl_arelset_size int arelset_size(MPL *mpl, double t0, double tf, double dt); /* compute size of "arithmetic" elemental set */ #define arelset_member _glp_mpl_arelset_member double arelset_member(MPL *mpl, double t0, double tf, double dt, int j); /* compute member of "arithmetic" elemental set */ #define create_arelset _glp_mpl_create_arelset ELEMSET *create_arelset(MPL *mpl, double t0, double tf, double dt); /* create "arithmetic" elemental set */ #define set_union _glp_mpl_set_union ELEMSET *set_union ( MPL *mpl, ELEMSET *X, /* destroyed */ ELEMSET *Y /* destroyed */ ); /* union of two elemental sets */ #define set_diff _glp_mpl_set_diff ELEMSET *set_diff ( MPL *mpl, ELEMSET *X, /* destroyed */ ELEMSET *Y /* destroyed */ ); /* difference between two elemental sets */ #define set_symdiff _glp_mpl_set_symdiff ELEMSET *set_symdiff ( MPL *mpl, ELEMSET *X, /* destroyed */ ELEMSET *Y /* destroyed */ ); /* symmetric difference between two elemental sets */ #define set_inter _glp_mpl_set_inter ELEMSET *set_inter ( MPL *mpl, ELEMSET *X, /* destroyed */ ELEMSET *Y /* destroyed */ ); /* intersection of two elemental sets */ #define set_cross _glp_mpl_set_cross ELEMSET *set_cross ( MPL *mpl, ELEMSET *X, /* destroyed */ ELEMSET *Y /* destroyed */ ); /* cross (Cartesian) product of two elemental sets */ /**********************************************************************/ /* * * ELEMENTAL VARIABLES * * */ /**********************************************************************/ struct ELEMVAR { /* elemental variable; formally it is a "value" assigned to members of model variables (like numbers and symbols, which are values assigned to members of model parameters) */ int j; /* LP column number assigned to this elemental variable */ VARIABLE *var; /* model variable, which contains this elemental variable */ MEMBER *memb; /* array member, which is assigned this elemental variable */ double lbnd; /* lower bound */ double ubnd; /* upper bound */ double temp; /* working quantity used in operations on linear forms; normally it contains floating-point zero */ #if 1 /* 15/V-2010 */ int stat; double prim, dual; /* solution components provided by the solver */ #endif }; /**********************************************************************/ /* * * LINEAR FORMS * * */ /**********************************************************************/ struct FORMULA { /* term of linear form c * x, where c is a coefficient, x is an elemental variable; the linear form itself is the sum of terms and is associated with its first term; (note that the linear form may be empty that means the sum is equal to zero) */ double coef; /* coefficient at elemental variable or constant term */ ELEMVAR *var; /* reference to elemental variable; NULL means constant term */ FORMULA *next; /* the next term of linear form */ }; #define constant_term _glp_mpl_constant_term FORMULA *constant_term(MPL *mpl, double coef); /* create constant term */ #define single_variable _glp_mpl_single_variable FORMULA *single_variable ( MPL *mpl, ELEMVAR *var /* referenced */ ); /* create single variable */ #define copy_formula _glp_mpl_copy_formula FORMULA *copy_formula ( MPL *mpl, FORMULA *form /* not changed */ ); /* make copy of linear form */ #define delete_formula _glp_mpl_delete_formula void delete_formula ( MPL *mpl, FORMULA *form /* destroyed */ ); /* delete linear form */ #define linear_comb _glp_mpl_linear_comb FORMULA *linear_comb ( MPL *mpl, double a, FORMULA *fx, /* destroyed */ double b, FORMULA *fy /* destroyed */ ); /* linear combination of two linear forms */ #define remove_constant _glp_mpl_remove_constant FORMULA *remove_constant ( MPL *mpl, FORMULA *form, /* destroyed */ double *coef /* modified */ ); /* remove constant term from linear form */ #define reduce_terms _glp_mpl_reduce_terms FORMULA *reduce_terms ( MPL *mpl, FORMULA *form /* destroyed */ ); /* reduce identical terms in linear form */ /**********************************************************************/ /* * * ELEMENTAL CONSTRAINTS * * */ /**********************************************************************/ struct ELEMCON { /* elemental constraint; formally it is a "value" assigned to members of model constraints (like numbers or symbols, which are values assigned to members of model parameters) */ int i; /* LP row number assigned to this elemental constraint */ CONSTRAINT *con; /* model constraint, which contains this elemental constraint */ MEMBER *memb; /* array member, which is assigned this elemental constraint */ FORMULA *form; /* linear form */ double lbnd; /* lower bound */ double ubnd; /* upper bound */ #if 1 /* 15/V-2010 */ int stat; double prim, dual; /* solution components provided by the solver */ #endif }; /**********************************************************************/ /* * * GENERIC VALUES * * */ /**********************************************************************/ union VALUE { /* generic value, which can be assigned to object member or be a result of evaluation of expression */ /* indicator that specifies the particular type of generic value is stored in the corresponding array or pseudo-code descriptor and can be one of the following: A_NONE - no value A_NUMERIC - floating-point number A_SYMBOLIC - symbol A_LOGICAL - logical value A_TUPLE - n-tuple A_ELEMSET - elemental set A_ELEMVAR - elemental variable A_FORMULA - linear form A_ELEMCON - elemental constraint */ void *none; /* null */ double num; /* value */ SYMBOL *sym; /* value */ int bit; /* value */ TUPLE *tuple; /* value */ ELEMSET *set; /* value */ ELEMVAR *var; /* reference */ FORMULA *form; /* value */ ELEMCON *con; /* reference */ }; #define delete_value _glp_mpl_delete_value void delete_value ( MPL *mpl, int type, VALUE *value /* content destroyed */ ); /* delete generic value */ /**********************************************************************/ /* * * SYMBOLICALLY INDEXED ARRAYS * * */ /**********************************************************************/ struct ARRAY { /* multi-dimensional array, a set of members indexed over simple or compound sets of symbols; arrays are used to represent the contents of model objects (i.e. sets, parameters, variables, constraints, and objectives); arrays also are used as "values" that are assigned to members of set objects, in which case the array itself represents an elemental set */ int type; /* type of generic values assigned to the array members: A_NONE - none (members have no assigned values) A_NUMERIC - floating-point numbers A_SYMBOLIC - symbols A_ELEMSET - elemental sets A_ELEMVAR - elemental variables A_ELEMCON - elemental constraints */ int dim; /* dimension of the array that determines number of components in n-tuples for all members of the array, dim >= 0; dim = 0 means the array is 0-dimensional */ int size; /* size of the array, i.e. number of its members */ MEMBER *head; /* the first array member; NULL means the array is empty */ MEMBER *tail; /* the last array member; NULL means the array is empty */ AVL *tree; /* the search tree intended to find array members for logarithmic time; NULL means the search tree doesn't exist */ ARRAY *prev; /* the previous array in the translator database */ ARRAY *next; /* the next array in the translator database */ }; struct MEMBER { /* array member */ TUPLE *tuple; /* n-tuple, which identifies the member; number of its components is the same for all members within the array and determined by the array dimension; duplicate members are not allowed */ MEMBER *next; /* the next array member */ VALUE value; /* generic value assigned to the member */ }; #define create_array _glp_mpl_create_array ARRAY *create_array(MPL *mpl, int type, int dim); /* create array */ #define find_member _glp_mpl_find_member MEMBER *find_member ( MPL *mpl, ARRAY *array, /* not changed */ TUPLE *tuple /* not changed */ ); /* find array member with given n-tuple */ #define add_member _glp_mpl_add_member MEMBER *add_member ( MPL *mpl, ARRAY *array, /* modified */ TUPLE *tuple /* destroyed */ ); /* add new member to array */ #define delete_array _glp_mpl_delete_array void delete_array ( MPL *mpl, ARRAY *array /* destroyed */ ); /* delete array */ /**********************************************************************/ /* * * DOMAINS AND DUMMY INDICES * * */ /**********************************************************************/ struct DOMAIN { /* domain (a simple or compound set); syntactically domain looks like '{ i in I, (j,k) in S, t in T : }'; domains are used to define sets, over which model objects are indexed, and also as constituents of iterated operators */ DOMAIN_BLOCK *list; /* linked list of domain blocks (in the example above such blocks are 'i in I', '(j,k) in S', and 't in T'); this list cannot be empty */ CODE *code; /* pseudo-code for computing the logical predicate, which follows the colon; NULL means no predicate is specified */ }; struct DOMAIN_BLOCK { /* domain block; syntactically domain blocks look like 'i in I', '(j,k) in S', and 't in T' in the example above (in the sequel sets like I, S, and T are called basic sets) */ DOMAIN_SLOT *list; /* linked list of domain slots (i.e. indexing positions); number of slots in this list is the same as dimension of n-tuples in the basic set; this list cannot be empty */ CODE *code; /* pseudo-code for computing basic set; cannot be NULL */ TUPLE *backup; /* if this n-tuple is not empty, current values of dummy indices in the domain block are the same as components of this n-tuple (note that this n-tuple may have larger dimension than number of dummy indices in this block, in which case extra components are ignored); this n-tuple is used to restore former values of dummy indices, if they were changed due to recursive calls to the domain block */ DOMAIN_BLOCK *next; /* the next block in the same domain */ }; struct DOMAIN_SLOT { /* domain slot; it specifies an individual indexing position and defines the corresponding dummy index */ char *name; /* symbolic name of the dummy index; null pointer means the dummy index is not explicitly specified */ CODE *code; /* pseudo-code for computing symbolic value, at which the dummy index is bound; NULL means the dummy index is free within the domain scope */ SYMBOL *value; /* current value assigned to the dummy index; NULL means no value is assigned at the moment */ CODE *list; /* linked list of pseudo-codes with operation O_INDEX referring to this slot; this linked list is used to invalidate resultant values of the operation, which depend on this dummy index */ DOMAIN_SLOT *next; /* the next slot in the same domain block */ }; #define assign_dummy_index _glp_mpl_assign_dummy_index void assign_dummy_index ( MPL *mpl, DOMAIN_SLOT *slot, /* modified */ SYMBOL *value /* not changed */ ); /* assign new value to dummy index */ #define update_dummy_indices _glp_mpl_update_dummy_indices void update_dummy_indices ( MPL *mpl, DOMAIN_BLOCK *block /* not changed */ ); /* update current values of dummy indices */ #define enter_domain_block _glp_mpl_enter_domain_block int enter_domain_block ( MPL *mpl, DOMAIN_BLOCK *block, /* not changed */ TUPLE *tuple, /* not changed */ void *info, void (*func)(MPL *mpl, void *info) ); /* enter domain block */ #define eval_within_domain _glp_mpl_eval_within_domain int eval_within_domain ( MPL *mpl, DOMAIN *domain, /* not changed */ TUPLE *tuple, /* not changed */ void *info, void (*func)(MPL *mpl, void *info) ); /* perform evaluation within domain scope */ #define loop_within_domain _glp_mpl_loop_within_domain void loop_within_domain ( MPL *mpl, DOMAIN *domain, /* not changed */ void *info, int (*func)(MPL *mpl, void *info) ); /* perform iterations within domain scope */ #define out_of_domain _glp_mpl_out_of_domain void out_of_domain ( MPL *mpl, char *name, /* not changed */ TUPLE *tuple /* not changed */ ); /* raise domain exception */ #define get_domain_tuple _glp_mpl_get_domain_tuple TUPLE *get_domain_tuple ( MPL *mpl, DOMAIN *domain /* not changed */ ); /* obtain current n-tuple from domain */ #define clean_domain _glp_mpl_clean_domain void clean_domain(MPL *mpl, DOMAIN *domain); /* clean domain */ /**********************************************************************/ /* * * MODEL SETS * * */ /**********************************************************************/ struct SET { /* model set */ char *name; /* symbolic name; cannot be NULL */ char *alias; /* alias; NULL means alias is not specified */ int dim; /* aka arity */ /* dimension (number of subscripts); dim = 0 means 0-dimensional (unsubscripted) set, dim > 0 means set of sets */ DOMAIN *domain; /* subscript domain; NULL for 0-dimensional set */ int dimen; /* dimension of n-tuples, which members of this set consist of (note that the model set itself is an array of elemental sets, which are its members; so, don't confuse this dimension with dimension of the model set); always non-zero */ WITHIN *within; /* list of supersets, which restrict each member of the set to be in every superset from this list; this list can be empty */ CODE *assign; /* pseudo-code for computing assigned value; can be NULL */ CODE *option; /* pseudo-code for computing default value; can be NULL */ GADGET *gadget; /* plain set used to initialize the array of sets; can be NULL */ int data; /* data status flag: 0 - no data are provided in the data section 1 - data are provided, but not checked yet 2 - data are provided and have been checked */ ARRAY *array; /* array of members, which are assigned elemental sets */ }; struct WITHIN { /* restricting superset list entry */ CODE *code; /* pseudo-code for computing the superset; cannot be NULL */ WITHIN *next; /* the next entry for the same set or parameter */ }; struct GADGET { /* plain set used to initialize the array of sets with data */ SET *set; /* pointer to plain set; cannot be NULL */ int ind[20]; /* ind[dim+dimen]; */ /* permutation of integers 1, 2, ..., dim+dimen */ }; #define check_elem_set _glp_mpl_check_elem_set void check_elem_set ( MPL *mpl, SET *set, /* not changed */ TUPLE *tuple, /* not changed */ ELEMSET *refer /* not changed */ ); /* check elemental set assigned to set member */ #define take_member_set _glp_mpl_take_member_set ELEMSET *take_member_set /* returns reference, not value */ ( MPL *mpl, SET *set, /* not changed */ TUPLE *tuple /* not changed */ ); /* obtain elemental set assigned to set member */ #define eval_member_set _glp_mpl_eval_member_set ELEMSET *eval_member_set /* returns reference, not value */ ( MPL *mpl, SET *set, /* not changed */ TUPLE *tuple /* not changed */ ); /* evaluate elemental set assigned to set member */ #define eval_whole_set _glp_mpl_eval_whole_set void eval_whole_set(MPL *mpl, SET *set); /* evaluate model set over entire domain */ #define clean_set _glp_mpl_clean_set void clean_set(MPL *mpl, SET *set); /* clean model set */ /**********************************************************************/ /* * * MODEL PARAMETERS * * */ /**********************************************************************/ struct PARAMETER { /* model parameter */ char *name; /* symbolic name; cannot be NULL */ char *alias; /* alias; NULL means alias is not specified */ int dim; /* aka arity */ /* dimension (number of subscripts); dim = 0 means 0-dimensional (unsubscripted) parameter */ DOMAIN *domain; /* subscript domain; NULL for 0-dimensional parameter */ int type; /* parameter type: A_NUMERIC - numeric A_INTEGER - integer A_BINARY - binary A_SYMBOLIC - symbolic */ CONDITION *cond; /* list of conditions, which restrict each parameter member to satisfy to every condition from this list; this list is used only for numeric parameters and can be empty */ WITHIN *in; /* list of supersets, which restrict each parameter member to be in every superset from this list; this list is used only for symbolic parameters and can be empty */ CODE *assign; /* pseudo-code for computing assigned value; can be NULL */ CODE *option; /* pseudo-code for computing default value; can be NULL */ int data; /* data status flag: 0 - no data are provided in the data section 1 - data are provided, but not checked yet 2 - data are provided and have been checked */ SYMBOL *defval; /* default value provided in the data section; can be NULL */ ARRAY *array; /* array of members, which are assigned numbers or symbols */ }; struct CONDITION { /* restricting condition list entry */ int rho; /* flag that specifies the form of the condition: O_LT - less than O_LE - less than or equal to O_EQ - equal to O_GE - greater than or equal to O_GT - greater than O_NE - not equal to */ CODE *code; /* pseudo-code for computing the reference value */ CONDITION *next; /* the next entry for the same parameter */ }; #define check_value_num _glp_mpl_check_value_num void check_value_num ( MPL *mpl, PARAMETER *par, /* not changed */ TUPLE *tuple, /* not changed */ double value ); /* check numeric value assigned to parameter member */ #define take_member_num _glp_mpl_take_member_num double take_member_num ( MPL *mpl, PARAMETER *par, /* not changed */ TUPLE *tuple /* not changed */ ); /* obtain numeric value assigned to parameter member */ #define eval_member_num _glp_mpl_eval_member_num double eval_member_num ( MPL *mpl, PARAMETER *par, /* not changed */ TUPLE *tuple /* not changed */ ); /* evaluate numeric value assigned to parameter member */ #define check_value_sym _glp_mpl_check_value_sym void check_value_sym ( MPL *mpl, PARAMETER *par, /* not changed */ TUPLE *tuple, /* not changed */ SYMBOL *value /* not changed */ ); /* check symbolic value assigned to parameter member */ #define take_member_sym _glp_mpl_take_member_sym SYMBOL *take_member_sym /* returns value, not reference */ ( MPL *mpl, PARAMETER *par, /* not changed */ TUPLE *tuple /* not changed */ ); /* obtain symbolic value assigned to parameter member */ #define eval_member_sym _glp_mpl_eval_member_sym SYMBOL *eval_member_sym /* returns value, not reference */ ( MPL *mpl, PARAMETER *par, /* not changed */ TUPLE *tuple /* not changed */ ); /* evaluate symbolic value assigned to parameter member */ #define eval_whole_par _glp_mpl_eval_whole_par void eval_whole_par(MPL *mpl, PARAMETER *par); /* evaluate model parameter over entire domain */ #define clean_parameter _glp_mpl_clean_parameter void clean_parameter(MPL *mpl, PARAMETER *par); /* clean model parameter */ /**********************************************************************/ /* * * MODEL VARIABLES * * */ /**********************************************************************/ struct VARIABLE { /* model variable */ char *name; /* symbolic name; cannot be NULL */ char *alias; /* alias; NULL means alias is not specified */ int dim; /* aka arity */ /* dimension (number of subscripts); dim = 0 means 0-dimensional (unsubscripted) variable */ DOMAIN *domain; /* subscript domain; NULL for 0-dimensional variable */ int type; /* variable type: A_NUMERIC - continuous A_INTEGER - integer A_BINARY - binary */ CODE *lbnd; /* pseudo-code for computing lower bound; NULL means lower bound is not specified */ CODE *ubnd; /* pseudo-code for computing upper bound; NULL means upper bound is not specified */ /* if both the pointers lbnd and ubnd refer to the same code, the variable is fixed at the corresponding value */ ARRAY *array; /* array of members, which are assigned elemental variables */ }; #define take_member_var _glp_mpl_take_member_var ELEMVAR *take_member_var /* returns reference */ ( MPL *mpl, VARIABLE *var, /* not changed */ TUPLE *tuple /* not changed */ ); /* obtain reference to elemental variable */ #define eval_member_var _glp_mpl_eval_member_var ELEMVAR *eval_member_var /* returns reference */ ( MPL *mpl, VARIABLE *var, /* not changed */ TUPLE *tuple /* not changed */ ); /* evaluate reference to elemental variable */ #define eval_whole_var _glp_mpl_eval_whole_var void eval_whole_var(MPL *mpl, VARIABLE *var); /* evaluate model variable over entire domain */ #define clean_variable _glp_mpl_clean_variable void clean_variable(MPL *mpl, VARIABLE *var); /* clean model variable */ /**********************************************************************/ /* * * MODEL CONSTRAINTS AND OBJECTIVES * * */ /**********************************************************************/ struct CONSTRAINT { /* model constraint or objective */ char *name; /* symbolic name; cannot be NULL */ char *alias; /* alias; NULL means alias is not specified */ int dim; /* aka arity */ /* dimension (number of subscripts); dim = 0 means 0-dimensional (unsubscripted) constraint */ DOMAIN *domain; /* subscript domain; NULL for 0-dimensional constraint */ int type; /* constraint type: A_CONSTRAINT - constraint A_MINIMIZE - objective (minimization) A_MAXIMIZE - objective (maximization) */ CODE *code; /* pseudo-code for computing main linear form; cannot be NULL */ CODE *lbnd; /* pseudo-code for computing lower bound; NULL means lower bound is not specified */ CODE *ubnd; /* pseudo-code for computing upper bound; NULL means upper bound is not specified */ /* if both the pointers lbnd and ubnd refer to the same code, the constraint has the form of equation */ ARRAY *array; /* array of members, which are assigned elemental constraints */ }; #define take_member_con _glp_mpl_take_member_con ELEMCON *take_member_con /* returns reference */ ( MPL *mpl, CONSTRAINT *con, /* not changed */ TUPLE *tuple /* not changed */ ); /* obtain reference to elemental constraint */ #define eval_member_con _glp_mpl_eval_member_con ELEMCON *eval_member_con /* returns reference */ ( MPL *mpl, CONSTRAINT *con, /* not changed */ TUPLE *tuple /* not changed */ ); /* evaluate reference to elemental constraint */ #define eval_whole_con _glp_mpl_eval_whole_con void eval_whole_con(MPL *mpl, CONSTRAINT *con); /* evaluate model constraint over entire domain */ #define clean_constraint _glp_mpl_clean_constraint void clean_constraint(MPL *mpl, CONSTRAINT *con); /* clean model constraint */ /**********************************************************************/ /* * * DATA TABLES * * */ /**********************************************************************/ struct TABLE { /* data table */ char *name; /* symbolic name; cannot be NULL */ char *alias; /* alias; NULL means alias is not specified */ int type; /* table type: A_INPUT - input table A_OUTPUT - output table */ TABARG *arg; /* argument list; cannot be empty */ union { struct { SET *set; /* input set; NULL means the set is not specified */ TABFLD *fld; /* field list; cannot be empty */ TABIN *list; /* input list; can be empty */ } in; struct { DOMAIN *domain; /* subscript domain; cannot be NULL */ TABOUT *list; /* output list; cannot be empty */ } out; } u; }; struct TABARG { /* table argument list entry */ CODE *code; /* pseudo-code for computing the argument */ TABARG *next; /* next entry for the same table */ }; struct TABFLD { /* table field list entry */ char *name; /* field name; cannot be NULL */ TABFLD *next; /* next entry for the same table */ }; struct TABIN { /* table input list entry */ PARAMETER *par; /* parameter to be read; cannot be NULL */ char *name; /* column name; cannot be NULL */ TABIN *next; /* next entry for the same table */ }; struct TABOUT { /* table output list entry */ CODE *code; /* pseudo-code for computing the value to be written */ char *name; /* column name; cannot be NULL */ TABOUT *next; /* next entry for the same table */ }; struct TABDCA { /* table driver communication area */ int id; /* driver identifier (set by mpl_tab_drv_open) */ void *link; /* driver link pointer (set by mpl_tab_drv_open) */ int na; /* number of arguments */ char **arg; /* char *arg[1+ns]; */ /* arg[k], 1 <= k <= ns, is pointer to k-th argument */ int nf; /* number of fields */ char **name; /* char *name[1+nc]; */ /* name[k], 1 <= k <= nc, is name of k-th field */ int *type; /* int type[1+nc]; */ /* type[k], 1 <= k <= nc, is type of k-th field: '?' - value not assigned 'N' - number 'S' - character string */ double *num; /* double num[1+nc]; */ /* num[k], 1 <= k <= nc, is numeric value of k-th field */ char **str; /* str[k], 1 <= k <= nc, is string value of k-th field */ }; #define mpl_tab_num_args _glp_mpl_tab_num_args int mpl_tab_num_args(TABDCA *dca); #define mpl_tab_get_arg _glp_mpl_tab_get_arg const char *mpl_tab_get_arg(TABDCA *dca, int k); #define mpl_tab_num_flds _glp_mpl_tab_num_flds int mpl_tab_num_flds(TABDCA *dca); #define mpl_tab_get_name _glp_mpl_tab_get_name const char *mpl_tab_get_name(TABDCA *dca, int k); #define mpl_tab_get_type _glp_mpl_tab_get_type int mpl_tab_get_type(TABDCA *dca, int k); #define mpl_tab_get_num _glp_mpl_tab_get_num double mpl_tab_get_num(TABDCA *dca, int k); #define mpl_tab_get_str _glp_mpl_tab_get_str const char *mpl_tab_get_str(TABDCA *dca, int k); #define mpl_tab_set_num _glp_mpl_tab_set_num void mpl_tab_set_num(TABDCA *dca, int k, double num); #define mpl_tab_set_str _glp_mpl_tab_set_str void mpl_tab_set_str(TABDCA *dca, int k, const char *str); #define mpl_tab_drv_open _glp_mpl_tab_drv_open void mpl_tab_drv_open(MPL *mpl, int mode); #define mpl_tab_drv_read _glp_mpl_tab_drv_read int mpl_tab_drv_read(MPL *mpl); #define mpl_tab_drv_write _glp_mpl_tab_drv_write void mpl_tab_drv_write(MPL *mpl); #define mpl_tab_drv_close _glp_mpl_tab_drv_close void mpl_tab_drv_close(MPL *mpl); /**********************************************************************/ /* * * PSEUDO-CODE * * */ /**********************************************************************/ union OPERANDS { /* operands that participate in pseudo-code operation (choice of particular operands depends on the operation code) */ /*--------------------------------------------------------------*/ double num; /* O_NUMBER */ /* floaing-point number to be taken */ /*--------------------------------------------------------------*/ char *str; /* O_STRING */ /* character string to be taken */ /*--------------------------------------------------------------*/ struct /* O_INDEX */ { DOMAIN_SLOT *slot; /* domain slot, which contains dummy index to be taken */ CODE *next; /* the next pseudo-code with op = O_INDEX, which refers to the same slot as this one; pointer to the beginning of this list is stored in the corresponding domain slot */ } index; /*--------------------------------------------------------------*/ struct /* O_MEMNUM, O_MEMSYM */ { PARAMETER *par; /* model parameter, which contains member to be taken */ ARG_LIST *list; /* list of subscripts; NULL for 0-dimensional parameter */ } par; /*--------------------------------------------------------------*/ struct /* O_MEMSET */ { SET *set; /* model set, which contains member to be taken */ ARG_LIST *list; /* list of subscripts; NULL for 0-dimensional set */ } set; /*--------------------------------------------------------------*/ struct /* O_MEMVAR */ { VARIABLE *var; /* model variable, which contains member to be taken */ ARG_LIST *list; /* list of subscripts; NULL for 0-dimensional variable */ #if 1 /* 15/V-2010 */ int suff; /* suffix specified: */ #define DOT_NONE 0x00 /* none (means variable itself) */ #define DOT_LB 0x01 /* .lb (lower bound) */ #define DOT_UB 0x02 /* .ub (upper bound) */ #define DOT_STATUS 0x03 /* .status (status) */ #define DOT_VAL 0x04 /* .val (primal value) */ #define DOT_DUAL 0x05 /* .dual (dual value) */ #endif } var; #if 1 /* 15/V-2010 */ /*--------------------------------------------------------------*/ struct /* O_MEMCON */ { CONSTRAINT *con; /* model constraint, which contains member to be taken */ ARG_LIST *list; /* list of subscripys; NULL for 0-dimensional constraint */ int suff; /* suffix specified (see O_MEMVAR above) */ } con; #endif /*--------------------------------------------------------------*/ ARG_LIST *list; /* O_TUPLE, O_MAKE, n-ary operations */ /* list of operands */ /*--------------------------------------------------------------*/ DOMAIN_BLOCK *slice; /* O_SLICE */ /* domain block, which specifies slice (i.e. n-tuple that contains free dummy indices); this operation is never evaluated */ /*--------------------------------------------------------------*/ struct /* unary, binary, ternary operations */ { CODE *x; /* pseudo-code for computing first operand */ CODE *y; /* pseudo-code for computing second operand */ CODE *z; /* pseudo-code for computing third operand */ } arg; /*--------------------------------------------------------------*/ struct /* iterated operations */ { DOMAIN *domain; /* domain, over which the operation is performed */ CODE *x; /* pseudo-code for computing "integrand" */ } loop; /*--------------------------------------------------------------*/ }; struct ARG_LIST { /* operands list entry */ CODE *x; /* pseudo-code for computing operand */ ARG_LIST *next; /* the next operand of the same operation */ }; struct CODE { /* pseudo-code (internal form of expressions) */ int op; /* operation code: */ #define O_NUMBER 301 /* take floating-point number */ #define O_STRING 302 /* take character string */ #define O_INDEX 303 /* take dummy index */ #define O_MEMNUM 304 /* take member of numeric parameter */ #define O_MEMSYM 305 /* take member of symbolic parameter */ #define O_MEMSET 306 /* take member of set */ #define O_MEMVAR 307 /* take member of variable */ #define O_MEMCON 308 /* take member of constraint */ #define O_TUPLE 309 /* make n-tuple */ #define O_MAKE 310 /* make elemental set of n-tuples */ #define O_SLICE 311 /* define domain block (dummy op) */ /* 0-ary operations --------------------*/ #define O_IRAND224 312 /* pseudo-random in [0, 2^24-1] */ #define O_UNIFORM01 313 /* pseudo-random in [0, 1) */ #define O_NORMAL01 314 /* gaussian random, mu = 0, sigma = 1 */ #define O_GMTIME 315 /* current calendar time (UTC) */ /* unary operations --------------------*/ #define O_CVTNUM 316 /* conversion to numeric */ #define O_CVTSYM 317 /* conversion to symbolic */ #define O_CVTLOG 318 /* conversion to logical */ #define O_CVTTUP 319 /* conversion to 1-tuple */ #define O_CVTLFM 320 /* conversion to linear form */ #define O_PLUS 321 /* unary plus */ #define O_MINUS 322 /* unary minus */ #define O_NOT 323 /* negation (logical "not") */ #define O_ABS 324 /* absolute value */ #define O_CEIL 325 /* round upward ("ceiling of x") */ #define O_FLOOR 326 /* round downward ("floor of x") */ #define O_EXP 327 /* base-e exponential */ #define O_LOG 328 /* natural logarithm */ #define O_LOG10 329 /* common (decimal) logarithm */ #define O_SQRT 330 /* square root */ #define O_SIN 331 /* trigonometric sine */ #define O_COS 332 /* trigonometric cosine */ #define O_ATAN 333 /* trigonometric arctangent */ #define O_ROUND 334 /* round to nearest integer */ #define O_TRUNC 335 /* truncate to nearest integer */ #define O_CARD 336 /* cardinality of set */ #define O_LENGTH 337 /* length of symbolic value */ /* binary operations -------------------*/ #define O_ADD 338 /* addition */ #define O_SUB 339 /* subtraction */ #define O_LESS 340 /* non-negative subtraction */ #define O_MUL 341 /* multiplication */ #define O_DIV 342 /* division */ #define O_IDIV 343 /* quotient of exact division */ #define O_MOD 344 /* remainder of exact division */ #define O_POWER 345 /* exponentiation (raise to power) */ #define O_ATAN2 346 /* trigonometric arctangent */ #define O_ROUND2 347 /* round to n fractional digits */ #define O_TRUNC2 348 /* truncate to n fractional digits */ #define O_UNIFORM 349 /* pseudo-random in [a, b) */ #define O_NORMAL 350 /* gaussian random, given mu and sigma */ #define O_CONCAT 351 /* concatenation */ #define O_LT 352 /* comparison on 'less than' */ #define O_LE 353 /* comparison on 'not greater than' */ #define O_EQ 354 /* comparison on 'equal to' */ #define O_GE 355 /* comparison on 'not less than' */ #define O_GT 356 /* comparison on 'greater than' */ #define O_NE 357 /* comparison on 'not equal to' */ #define O_AND 358 /* conjunction (logical "and") */ #define O_OR 359 /* disjunction (logical "or") */ #define O_UNION 360 /* union */ #define O_DIFF 361 /* difference */ #define O_SYMDIFF 362 /* symmetric difference */ #define O_INTER 363 /* intersection */ #define O_CROSS 364 /* cross (Cartesian) product */ #define O_IN 365 /* test on 'x in Y' */ #define O_NOTIN 366 /* test on 'x not in Y' */ #define O_WITHIN 367 /* test on 'X within Y' */ #define O_NOTWITHIN 368 /* test on 'X not within Y' */ #define O_SUBSTR 369 /* substring */ #define O_STR2TIME 370 /* convert string to time */ #define O_TIME2STR 371 /* convert time to string */ /* ternary operations ------------------*/ #define O_DOTS 372 /* build "arithmetic" set */ #define O_FORK 373 /* if-then-else */ #define O_SUBSTR3 374 /* substring */ /* n-ary operations --------------------*/ #define O_MIN 375 /* minimal value (n-ary) */ #define O_MAX 376 /* maximal value (n-ary) */ /* iterated operations -----------------*/ #define O_SUM 377 /* summation */ #define O_PROD 378 /* multiplication */ #define O_MINIMUM 379 /* minimum */ #define O_MAXIMUM 380 /* maximum */ #define O_FORALL 381 /* conjunction (A-quantification) */ #define O_EXISTS 382 /* disjunction (E-quantification) */ #define O_SETOF 383 /* compute elemental set */ #define O_BUILD 384 /* build elemental set */ OPERANDS arg; /* operands that participate in the operation */ int type; /* type of the resultant value: A_NUMERIC - numeric A_SYMBOLIC - symbolic A_LOGICAL - logical A_TUPLE - n-tuple A_ELEMSET - elemental set A_FORMULA - linear form */ int dim; /* dimension of the resultant value; for A_TUPLE and A_ELEMSET it is the dimension of the corresponding n-tuple(s) and cannot be zero; for other resultant types it is always zero */ CODE *up; /* parent pseudo-code, which refers to this pseudo-code as to its operand; NULL means this pseudo-code has no parent and defines an expression, which is not contained in another expression */ int vflag; /* volatile flag; being set this flag means that this operation has a side effect; for primary expressions this flag is set directly by corresponding parsing routines (for example, if primary expression is a reference to a function that generates pseudo-random numbers); in other cases this flag is inherited from operands */ int valid; /* if this flag is set, the resultant value, which is a temporary result of evaluating this operation on particular values of operands, is valid; if this flag is clear, the resultant value doesn't exist and therefore not valid; having been evaluated the resultant value is stored here and not destroyed until the dummy indices, which this value depends on, have been changed (and if it doesn't depend on dummy indices at all, it is never destroyed); thus, if the resultant value is valid, evaluating routine can immediately take its copy not computing the result from scratch; this mechanism is similar to moving invariants out of loops and allows improving efficiency at the expense of some extra memory needed to keep temporary results */ /* however, if the volatile flag (see above) is set, even if the resultant value is valid, evaluating routine computes it as if it were not valid, i.e. caching is not used in this case */ VALUE value; /* resultant value in generic format */ }; #define eval_numeric _glp_mpl_eval_numeric double eval_numeric(MPL *mpl, CODE *code); /* evaluate pseudo-code to determine numeric value */ #define eval_symbolic _glp_mpl_eval_symbolic SYMBOL *eval_symbolic(MPL *mpl, CODE *code); /* evaluate pseudo-code to determine symbolic value */ #define eval_logical _glp_mpl_eval_logical int eval_logical(MPL *mpl, CODE *code); /* evaluate pseudo-code to determine logical value */ #define eval_tuple _glp_mpl_eval_tuple TUPLE *eval_tuple(MPL *mpl, CODE *code); /* evaluate pseudo-code to construct n-tuple */ #define eval_elemset _glp_mpl_eval_elemset ELEMSET *eval_elemset(MPL *mpl, CODE *code); /* evaluate pseudo-code to construct elemental set */ #define is_member _glp_mpl_is_member int is_member(MPL *mpl, CODE *code, TUPLE *tuple); /* check if n-tuple is in set specified by pseudo-code */ #define eval_formula _glp_mpl_eval_formula FORMULA *eval_formula(MPL *mpl, CODE *code); /* evaluate pseudo-code to construct linear form */ #define clean_code _glp_mpl_clean_code void clean_code(MPL *mpl, CODE *code); /* clean pseudo-code */ /**********************************************************************/ /* * * MODEL STATEMENTS * * */ /**********************************************************************/ struct CHECK { /* check statement */ DOMAIN *domain; /* subscript domain; NULL means domain is not used */ CODE *code; /* code for computing the predicate to be checked */ }; struct DISPLAY { /* display statement */ DOMAIN *domain; /* subscript domain; NULL means domain is not used */ DISPLAY1 *list; /* display list; cannot be empty */ }; struct DISPLAY1 { /* display list entry */ int type; /* item type: A_INDEX - dummy index A_SET - model set A_PARAMETER - model parameter A_VARIABLE - model variable A_CONSTRAINT - model constraint/objective A_EXPRESSION - expression */ union { DOMAIN_SLOT *slot; SET *set; PARAMETER *par; VARIABLE *var; CONSTRAINT *con; CODE *code; } u; /* item to be displayed */ #if 0 /* 15/V-2010 */ ARG_LIST *list; /* optional subscript list (for constraint/objective only) */ #endif DISPLAY1 *next; /* the next entry for the same statement */ }; struct PRINTF { /* printf statement */ DOMAIN *domain; /* subscript domain; NULL means domain is not used */ CODE *fmt; /* pseudo-code for computing format string */ PRINTF1 *list; /* printf list; can be empty */ CODE *fname; /* pseudo-code for computing filename to redirect the output; NULL means the output goes to stdout */ int app; /* if this flag is set, the output is appended */ }; struct PRINTF1 { /* printf list entry */ CODE *code; /* pseudo-code for computing value to be printed */ PRINTF1 *next; /* the next entry for the same statement */ }; struct FOR { /* for statement */ DOMAIN *domain; /* subscript domain; cannot be NULL */ STATEMENT *list; /* linked list of model statements within this for statement in the original order */ }; struct STATEMENT { /* model statement */ int line; /* number of source text line, where statement begins */ int type; /* statement type: A_SET - set statement A_PARAMETER - parameter statement A_VARIABLE - variable statement A_CONSTRAINT - constraint/objective statement A_TABLE - table statement A_SOLVE - solve statement A_CHECK - check statement A_DISPLAY - display statement A_PRINTF - printf statement A_FOR - for statement */ union { SET *set; PARAMETER *par; VARIABLE *var; CONSTRAINT *con; TABLE *tab; void *slv; /* currently not used (set to NULL) */ CHECK *chk; DISPLAY *dpy; PRINTF *prt; FOR *fur; } u; /* specific part of statement */ STATEMENT *next; /* the next statement; in this list statements follow in the same order as they appear in the model section */ }; #define execute_table _glp_mpl_execute_table void execute_table(MPL *mpl, TABLE *tab); /* execute table statement */ #define free_dca _glp_mpl_free_dca void free_dca(MPL *mpl); /* free table driver communucation area */ #define clean_table _glp_mpl_clean_table void clean_table(MPL *mpl, TABLE *tab); /* clean table statement */ #define execute_check _glp_mpl_execute_check void execute_check(MPL *mpl, CHECK *chk); /* execute check statement */ #define clean_check _glp_mpl_clean_check void clean_check(MPL *mpl, CHECK *chk); /* clean check statement */ #define execute_display _glp_mpl_execute_display void execute_display(MPL *mpl, DISPLAY *dpy); /* execute display statement */ #define clean_display _glp_mpl_clean_display void clean_display(MPL *mpl, DISPLAY *dpy); /* clean display statement */ #define execute_printf _glp_mpl_execute_printf void execute_printf(MPL *mpl, PRINTF *prt); /* execute printf statement */ #define clean_printf _glp_mpl_clean_printf void clean_printf(MPL *mpl, PRINTF *prt); /* clean printf statement */ #define execute_for _glp_mpl_execute_for void execute_for(MPL *mpl, FOR *fur); /* execute for statement */ #define clean_for _glp_mpl_clean_for void clean_for(MPL *mpl, FOR *fur); /* clean for statement */ #define execute_statement _glp_mpl_execute_statement void execute_statement(MPL *mpl, STATEMENT *stmt); /* execute specified model statement */ #define clean_statement _glp_mpl_clean_statement void clean_statement(MPL *mpl, STATEMENT *stmt); /* clean specified model statement */ /**********************************************************************/ /* * * GENERATING AND POSTSOLVING MODEL * * */ /**********************************************************************/ #define alloc_content _glp_mpl_alloc_content void alloc_content(MPL *mpl); /* allocate content arrays for all model objects */ #define generate_model _glp_mpl_generate_model void generate_model(MPL *mpl); /* generate model */ #define build_problem _glp_mpl_build_problem void build_problem(MPL *mpl); /* build problem instance */ #define postsolve_model _glp_mpl_postsolve_model void postsolve_model(MPL *mpl); /* postsolve model */ #define clean_model _glp_mpl_clean_model void clean_model(MPL *mpl); /* clean model content */ /**********************************************************************/ /* * * INPUT/OUTPUT * * */ /**********************************************************************/ #define open_input _glp_mpl_open_input void open_input(MPL *mpl, char *file); /* open input text file */ #define read_char _glp_mpl_read_char int read_char(MPL *mpl); /* read next character from input text file */ #define close_input _glp_mpl_close_input void close_input(MPL *mpl); /* close input text file */ #define open_output _glp_mpl_open_output void open_output(MPL *mpl, char *file); /* open output text file */ #define write_char _glp_mpl_write_char void write_char(MPL *mpl, int c); /* write next character to output text file */ #define write_text _glp_mpl_write_text void write_text(MPL *mpl, char *fmt, ...); /* format and write text to output text file */ #define flush_output _glp_mpl_flush_output void flush_output(MPL *mpl); /* finalize writing data to output text file */ /**********************************************************************/ /* * * SOLVER INTERFACE * * */ /**********************************************************************/ #define MPL_FR 401 /* free (unbounded) */ #define MPL_LO 402 /* lower bound */ #define MPL_UP 403 /* upper bound */ #define MPL_DB 404 /* both lower and upper bounds */ #define MPL_FX 405 /* fixed */ #define MPL_ST 411 /* constraint */ #define MPL_MIN 412 /* objective (minimization) */ #define MPL_MAX 413 /* objective (maximization) */ #define MPL_NUM 421 /* continuous */ #define MPL_INT 422 /* integer */ #define MPL_BIN 423 /* binary */ #define mpl_error _glp_mpl_error void mpl_error(MPL *mpl, char *fmt, ...); /* print error message and terminate model processing */ #define warning _glp_mpl_warning void warning(MPL *mpl, char *fmt, ...); /* print warning message and continue model processing */ #define mpl_initialize _glp_mpl_initialize MPL *mpl_initialize(void); /* create and initialize translator database */ #define mpl_read_model _glp_mpl_read_model int mpl_read_model(MPL *mpl, char *file, int skip_data); /* read model section and optional data section */ #define mpl_read_data _glp_mpl_read_data int mpl_read_data(MPL *mpl, char *file); /* read data section */ #define mpl_generate _glp_mpl_generate int mpl_generate(MPL *mpl, char *file); /* generate model */ #define mpl_get_prob_name _glp_mpl_get_prob_name char *mpl_get_prob_name(MPL *mpl); /* obtain problem (model) name */ #define mpl_get_num_rows _glp_mpl_get_num_rows int mpl_get_num_rows(MPL *mpl); /* determine number of rows */ #define mpl_get_num_cols _glp_mpl_get_num_cols int mpl_get_num_cols(MPL *mpl); /* determine number of columns */ #define mpl_get_row_name _glp_mpl_get_row_name char *mpl_get_row_name(MPL *mpl, int i); /* obtain row name */ #define mpl_get_row_kind _glp_mpl_get_row_kind int mpl_get_row_kind(MPL *mpl, int i); /* determine row kind */ #define mpl_get_row_bnds _glp_mpl_get_row_bnds int mpl_get_row_bnds(MPL *mpl, int i, double *lb, double *ub); /* obtain row bounds */ #define mpl_get_mat_row _glp_mpl_get_mat_row int mpl_get_mat_row(MPL *mpl, int i, int ndx[], double val[]); /* obtain row of the constraint matrix */ #define mpl_get_row_c0 _glp_mpl_get_row_c0 double mpl_get_row_c0(MPL *mpl, int i); /* obtain constant term of free row */ #define mpl_get_col_name _glp_mpl_get_col_name char *mpl_get_col_name(MPL *mpl, int j); /* obtain column name */ #define mpl_get_col_kind _glp_mpl_get_col_kind int mpl_get_col_kind(MPL *mpl, int j); /* determine column kind */ #define mpl_get_col_bnds _glp_mpl_get_col_bnds int mpl_get_col_bnds(MPL *mpl, int j, double *lb, double *ub); /* obtain column bounds */ #define mpl_has_solve_stmt _glp_mpl_has_solve_stmt int mpl_has_solve_stmt(MPL *mpl); /* check if model has solve statement */ #if 1 /* 15/V-2010 */ #define mpl_put_row_soln _glp_mpl_put_row_soln void mpl_put_row_soln(MPL *mpl, int i, int stat, double prim, double dual); /* store row (constraint/objective) solution components */ #endif #if 1 /* 15/V-2010 */ #define mpl_put_col_soln _glp_mpl_put_col_soln void mpl_put_col_soln(MPL *mpl, int j, int stat, double prim, double dual); /* store column (variable) solution components */ #endif #if 0 /* 15/V-2010 */ #define mpl_put_col_value _glp_mpl_put_col_value void mpl_put_col_value(MPL *mpl, int j, double val); /* store column value */ #endif #define mpl_postsolve _glp_mpl_postsolve int mpl_postsolve(MPL *mpl); /* postsolve model */ #define mpl_terminate _glp_mpl_terminate void mpl_terminate(MPL *mpl); /* free all resources used by translator */ #endif /* eof */ praat-6.0.04/external/glpk/glpmpl01.c000066400000000000000000005306461261542461700173150ustar00rootroot00000000000000/* glpmpl01.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #define _GLPSTD_STDIO #include "glpmpl.h" #define dmp_get_atomv dmp_get_atom /**********************************************************************/ /* * * PROCESSING MODEL SECTION * * */ /**********************************************************************/ /*---------------------------------------------------------------------- -- enter_context - enter current token into context queue. -- -- This routine enters the current token into the context queue. */ void enter_context(MPL *mpl) { char *image, *s; if (mpl->token == T_EOF) image = "_|_"; else if (mpl->token == T_STRING) image = "'...'"; else image = mpl->image; xassert(0 <= mpl->c_ptr && mpl->c_ptr < CONTEXT_SIZE); mpl->context[mpl->c_ptr++] = ' '; if (mpl->c_ptr == CONTEXT_SIZE) mpl->c_ptr = 0; for (s = image; *s != '\0'; s++) { mpl->context[mpl->c_ptr++] = *s; if (mpl->c_ptr == CONTEXT_SIZE) mpl->c_ptr = 0; } return; } /*---------------------------------------------------------------------- -- print_context - print current content of context queue. -- -- This routine prints current content of the context queue. */ void print_context(MPL *mpl) { int c; while (mpl->c_ptr > 0) { mpl->c_ptr--; c = mpl->context[0]; memmove(mpl->context, mpl->context+1, CONTEXT_SIZE-1); mpl->context[CONTEXT_SIZE-1] = (char)c; } xprintf("Context: %s%.*s\n", mpl->context[0] == ' ' ? "" : "...", CONTEXT_SIZE, mpl->context); return; } /*---------------------------------------------------------------------- -- get_char - scan next character from input text file. -- -- This routine scans a next ASCII character from the input text file. -- In case of end-of-file, the character is assigned EOF. */ void get_char(MPL *mpl) { int c; if (mpl->c == EOF) goto done; if (mpl->c == '\n') mpl->line++; c = read_char(mpl); if (c == EOF) { if (mpl->c == '\n') mpl->line--; else warning(mpl, "final NL missing before end of file"); } else if (c == '\n') ; else if (isspace(c)) c = ' '; else if (iscntrl(c)) { enter_context(mpl); mpl_error(mpl, "control character 0x%02X not allowed", c); } mpl->c = c; done: return; } /*---------------------------------------------------------------------- -- append_char - append character to current token. -- -- This routine appends the current character to the current token and -- then scans a next character. */ void append_char(MPL *mpl) { xassert(0 <= mpl->imlen && mpl->imlen <= MAX_LENGTH); if (mpl->imlen == MAX_LENGTH) { switch (mpl->token) { case T_NAME: enter_context(mpl); mpl_error(mpl, "symbolic name %s... too long", mpl->image); case T_SYMBOL: enter_context(mpl); mpl_error(mpl, "symbol %s... too long", mpl->image); case T_NUMBER: enter_context(mpl); mpl_error(mpl, "numeric literal %s... too long", mpl->image); case T_STRING: enter_context(mpl); mpl_error(mpl, "string literal too long"); default: xassert(mpl != mpl); } } mpl->image[mpl->imlen++] = (char)mpl->c; mpl->image[mpl->imlen] = '\0'; get_char(mpl); return; } /*---------------------------------------------------------------------- -- get_token - scan next token from input text file. -- -- This routine scans a next token from the input text file using the -- standard finite automation technique. */ void get_token(MPL *mpl) { /* save the current token */ mpl->b_token = mpl->token; mpl->b_imlen = mpl->imlen; strcpy(mpl->b_image, mpl->image); mpl->b_value = mpl->value; /* if the next token is already scanned, make it current */ if (mpl->f_scan) { mpl->f_scan = 0; mpl->token = mpl->f_token; mpl->imlen = mpl->f_imlen; strcpy(mpl->image, mpl->f_image); mpl->value = mpl->f_value; goto done; } loop: /* nothing has been scanned so far */ mpl->token = 0; mpl->imlen = 0; mpl->image[0] = '\0'; mpl->value = 0.0; /* skip any uninteresting characters */ while (mpl->c == ' ' || mpl->c == '\n') get_char(mpl); /* recognize and construct the token */ if (mpl->c == EOF) { /* end-of-file reached */ mpl->token = T_EOF; } else if (mpl->c == '#') { /* comment; skip anything until end-of-line */ while (mpl->c != '\n' && mpl->c != EOF) get_char(mpl); goto loop; } else if (!mpl->flag_d && (isalpha(mpl->c) || mpl->c == '_')) { /* symbolic name or reserved keyword */ mpl->token = T_NAME; while (isalnum(mpl->c) || mpl->c == '_') append_char(mpl); if (strcmp(mpl->image, "and") == 0) mpl->token = T_AND; else if (strcmp(mpl->image, "by") == 0) mpl->token = T_BY; else if (strcmp(mpl->image, "cross") == 0) mpl->token = T_CROSS; else if (strcmp(mpl->image, "diff") == 0) mpl->token = T_DIFF; else if (strcmp(mpl->image, "div") == 0) mpl->token = T_DIV; else if (strcmp(mpl->image, "else") == 0) mpl->token = T_ELSE; else if (strcmp(mpl->image, "if") == 0) mpl->token = T_IF; else if (strcmp(mpl->image, "in") == 0) mpl->token = T_IN; #if 1 /* 21/VII-2006 */ else if (strcmp(mpl->image, "Infinity") == 0) mpl->token = T_INFINITY; #endif else if (strcmp(mpl->image, "inter") == 0) mpl->token = T_INTER; else if (strcmp(mpl->image, "less") == 0) mpl->token = T_LESS; else if (strcmp(mpl->image, "mod") == 0) mpl->token = T_MOD; else if (strcmp(mpl->image, "not") == 0) mpl->token = T_NOT; else if (strcmp(mpl->image, "or") == 0) mpl->token = T_OR; else if (strcmp(mpl->image, "s") == 0 && mpl->c == '.') { mpl->token = T_SPTP; append_char(mpl); if (mpl->c != 't') sptp: { enter_context(mpl); mpl_error(mpl, "keyword s.t. incomplete"); } append_char(mpl); if (mpl->c != '.') goto sptp; append_char(mpl); } else if (strcmp(mpl->image, "symdiff") == 0) mpl->token = T_SYMDIFF; else if (strcmp(mpl->image, "then") == 0) mpl->token = T_THEN; else if (strcmp(mpl->image, "union") == 0) mpl->token = T_UNION; else if (strcmp(mpl->image, "within") == 0) mpl->token = T_WITHIN; } else if (!mpl->flag_d && isdigit(mpl->c)) { /* numeric literal */ mpl->token = T_NUMBER; /* scan integer part */ while (isdigit(mpl->c)) append_char(mpl); /* scan optional fractional part */ if (mpl->c == '.') { append_char(mpl); if (mpl->c == '.') { /* hmm, it is not the fractional part, it is dots that follow the integer part */ mpl->imlen--; mpl->image[mpl->imlen] = '\0'; mpl->f_dots = 1; goto conv; } frac: while (isdigit(mpl->c)) append_char(mpl); } /* scan optional decimal exponent */ if (mpl->c == 'e' || mpl->c == 'E') { append_char(mpl); if (mpl->c == '+' || mpl->c == '-') append_char(mpl); if (!isdigit(mpl->c)) { enter_context(mpl); mpl_error(mpl, "numeric literal %s incomplete", mpl->image); } while (isdigit(mpl->c)) append_char(mpl); } /* there must be no letter following the numeric literal */ if (isalpha(mpl->c) || mpl->c == '_') { enter_context(mpl); mpl_error(mpl, "symbol %s%c... should be enclosed in quotes", mpl->image, mpl->c); } conv: /* convert numeric literal to floating-point */ if (str2num(mpl->image, &mpl->value)) err: { enter_context(mpl); mpl_error(mpl, "cannot convert numeric literal %s to floating-p" "oint number", mpl->image); } } else if (mpl->c == '\'' || mpl->c == '"') { /* character string */ int quote = mpl->c; mpl->token = T_STRING; get_char(mpl); for (;;) { if (mpl->c == '\n' || mpl->c == EOF) { enter_context(mpl); mpl_error(mpl, "unexpected end of line; string literal incom" "plete"); } if (mpl->c == quote) { get_char(mpl); if (mpl->c != quote) break; } append_char(mpl); } } else if (!mpl->flag_d && mpl->c == '+') mpl->token = T_PLUS, append_char(mpl); else if (!mpl->flag_d && mpl->c == '-') mpl->token = T_MINUS, append_char(mpl); else if (mpl->c == '*') { mpl->token = T_ASTERISK, append_char(mpl); if (mpl->c == '*') mpl->token = T_POWER, append_char(mpl); } else if (mpl->c == '/') { mpl->token = T_SLASH, append_char(mpl); if (mpl->c == '*') { /* comment sequence */ get_char(mpl); for (;;) { if (mpl->c == EOF) { /* do not call enter_context at this point */ mpl_error(mpl, "unexpected end of file; comment sequence " "incomplete"); } else if (mpl->c == '*') { get_char(mpl); if (mpl->c == '/') break; } else get_char(mpl); } get_char(mpl); goto loop; } } else if (mpl->c == '^') mpl->token = T_POWER, append_char(mpl); else if (mpl->c == '<') { mpl->token = T_LT, append_char(mpl); if (mpl->c == '=') mpl->token = T_LE, append_char(mpl); else if (mpl->c == '>') mpl->token = T_NE, append_char(mpl); #if 1 /* 11/II-2008 */ else if (mpl->c == '-') mpl->token = T_INPUT, append_char(mpl); #endif } else if (mpl->c == '=') { mpl->token = T_EQ, append_char(mpl); if (mpl->c == '=') append_char(mpl); } else if (mpl->c == '>') { mpl->token = T_GT, append_char(mpl); if (mpl->c == '=') mpl->token = T_GE, append_char(mpl); #if 1 /* 14/VII-2006 */ else if (mpl->c == '>') mpl->token = T_APPEND, append_char(mpl); #endif } else if (mpl->c == '!') { mpl->token = T_NOT, append_char(mpl); if (mpl->c == '=') mpl->token = T_NE, append_char(mpl); } else if (mpl->c == '&') { mpl->token = T_CONCAT, append_char(mpl); if (mpl->c == '&') mpl->token = T_AND, append_char(mpl); } else if (mpl->c == '|') { mpl->token = T_BAR, append_char(mpl); if (mpl->c == '|') mpl->token = T_OR, append_char(mpl); } else if (!mpl->flag_d && mpl->c == '.') { mpl->token = T_POINT, append_char(mpl); if (mpl->f_dots) { /* dots; the first dot was read on the previous call to the scanner, so the current character is the second dot */ mpl->token = T_DOTS; mpl->imlen = 2; strcpy(mpl->image, ".."); mpl->f_dots = 0; } else if (mpl->c == '.') mpl->token = T_DOTS, append_char(mpl); else if (isdigit(mpl->c)) { /* numeric literal that begins with the decimal point */ mpl->token = T_NUMBER, append_char(mpl); goto frac; } } else if (mpl->c == ',') mpl->token = T_COMMA, append_char(mpl); else if (mpl->c == ':') { mpl->token = T_COLON, append_char(mpl); if (mpl->c == '=') mpl->token = T_ASSIGN, append_char(mpl); } else if (mpl->c == ';') mpl->token = T_SEMICOLON, append_char(mpl); else if (mpl->c == '(') mpl->token = T_LEFT, append_char(mpl); else if (mpl->c == ')') mpl->token = T_RIGHT, append_char(mpl); else if (mpl->c == '[') mpl->token = T_LBRACKET, append_char(mpl); else if (mpl->c == ']') mpl->token = T_RBRACKET, append_char(mpl); else if (mpl->c == '{') mpl->token = T_LBRACE, append_char(mpl); else if (mpl->c == '}') mpl->token = T_RBRACE, append_char(mpl); #if 1 /* 11/II-2008 */ else if (mpl->c == '~') mpl->token = T_TILDE, append_char(mpl); #endif else if (isalnum(mpl->c) || strchr("+-._", mpl->c) != NULL) { /* symbol */ xassert(mpl->flag_d); mpl->token = T_SYMBOL; while (isalnum(mpl->c) || strchr("+-._", mpl->c) != NULL) append_char(mpl); switch (str2num(mpl->image, &mpl->value)) { case 0: mpl->token = T_NUMBER; break; case 1: goto err; case 2: break; default: xassert(mpl != mpl); } } else { enter_context(mpl); mpl_error(mpl, "character %c not allowed", mpl->c); } /* enter the current token into the context queue */ enter_context(mpl); /* reset the flag, which may be set by indexing_expression() and is used by expression_list() */ mpl->flag_x = 0; done: return; } /*---------------------------------------------------------------------- -- unget_token - return current token back to input stream. -- -- This routine returns the current token back to the input stream, so -- the previously scanned token becomes the current one. */ void unget_token(MPL *mpl) { /* save the current token, which becomes the next one */ xassert(!mpl->f_scan); mpl->f_scan = 1; mpl->f_token = mpl->token; mpl->f_imlen = mpl->imlen; strcpy(mpl->f_image, mpl->image); mpl->f_value = mpl->value; /* restore the previous token, which becomes the current one */ mpl->token = mpl->b_token; mpl->imlen = mpl->b_imlen; strcpy(mpl->image, mpl->b_image); mpl->value = mpl->b_value; return; } /*---------------------------------------------------------------------- -- is_keyword - check if current token is given non-reserved keyword. -- -- If the current token is given (non-reserved) keyword, this routine -- returns non-zero. Otherwise zero is returned. */ int is_keyword(MPL *mpl, char *keyword) { return mpl->token == T_NAME && strcmp(mpl->image, keyword) == 0; } /*---------------------------------------------------------------------- -- is_reserved - check if current token is reserved keyword. -- -- If the current token is a reserved keyword, this routine returns -- non-zero. Otherwise zero is returned. */ int is_reserved(MPL *mpl) { return mpl->token == T_AND && mpl->image[0] == 'a' || mpl->token == T_BY || mpl->token == T_CROSS || mpl->token == T_DIFF || mpl->token == T_DIV || mpl->token == T_ELSE || mpl->token == T_IF || mpl->token == T_IN || mpl->token == T_INTER || mpl->token == T_LESS || mpl->token == T_MOD || mpl->token == T_NOT && mpl->image[0] == 'n' || mpl->token == T_OR && mpl->image[0] == 'o' || mpl->token == T_SYMDIFF || mpl->token == T_THEN || mpl->token == T_UNION || mpl->token == T_WITHIN; } /*---------------------------------------------------------------------- -- make_code - generate pseudo-code (basic routine). -- -- This routine generates specified pseudo-code. It is assumed that all -- other translator routines use this basic routine. */ CODE *make_code(MPL *mpl, int op, OPERANDS *arg, int type, int dim) { CODE *code; DOMAIN *domain; DOMAIN_BLOCK *block; ARG_LIST *e; /* generate pseudo-code */ code = alloc(CODE); code->op = op; code->vflag = 0; /* is inherited from operand(s) */ /* copy operands and also make them referring to the pseudo-code being generated, because the latter becomes the parent for all its operands */ memset(&code->arg, '?', sizeof(OPERANDS)); switch (op) { case O_NUMBER: code->arg.num = arg->num; break; case O_STRING: code->arg.str = arg->str; break; case O_INDEX: code->arg.index.slot = arg->index.slot; code->arg.index.next = arg->index.next; break; case O_MEMNUM: case O_MEMSYM: for (e = arg->par.list; e != NULL; e = e->next) { xassert(e->x != NULL); xassert(e->x->up == NULL); e->x->up = code; code->vflag |= e->x->vflag; } code->arg.par.par = arg->par.par; code->arg.par.list = arg->par.list; break; case O_MEMSET: for (e = arg->set.list; e != NULL; e = e->next) { xassert(e->x != NULL); xassert(e->x->up == NULL); e->x->up = code; code->vflag |= e->x->vflag; } code->arg.set.set = arg->set.set; code->arg.set.list = arg->set.list; break; case O_MEMVAR: for (e = arg->var.list; e != NULL; e = e->next) { xassert(e->x != NULL); xassert(e->x->up == NULL); e->x->up = code; code->vflag |= e->x->vflag; } code->arg.var.var = arg->var.var; code->arg.var.list = arg->var.list; #if 1 /* 15/V-2010 */ code->arg.var.suff = arg->var.suff; #endif break; #if 1 /* 15/V-2010 */ case O_MEMCON: for (e = arg->con.list; e != NULL; e = e->next) { xassert(e->x != NULL); xassert(e->x->up == NULL); e->x->up = code; code->vflag |= e->x->vflag; } code->arg.con.con = arg->con.con; code->arg.con.list = arg->con.list; code->arg.con.suff = arg->con.suff; break; #endif case O_TUPLE: case O_MAKE: for (e = arg->list; e != NULL; e = e->next) { xassert(e->x != NULL); xassert(e->x->up == NULL); e->x->up = code; code->vflag |= e->x->vflag; } code->arg.list = arg->list; break; case O_SLICE: xassert(arg->slice != NULL); code->arg.slice = arg->slice; break; case O_IRAND224: case O_UNIFORM01: case O_NORMAL01: case O_GMTIME: code->vflag = 1; break; case O_CVTNUM: case O_CVTSYM: case O_CVTLOG: case O_CVTTUP: case O_CVTLFM: case O_PLUS: case O_MINUS: case O_NOT: case O_ABS: case O_CEIL: case O_FLOOR: case O_EXP: case O_LOG: case O_LOG10: case O_SQRT: case O_SIN: case O_COS: case O_ATAN: case O_ROUND: case O_TRUNC: case O_CARD: case O_LENGTH: /* unary operation */ xassert(arg->arg.x != NULL); xassert(arg->arg.x->up == NULL); arg->arg.x->up = code; code->vflag |= arg->arg.x->vflag; code->arg.arg.x = arg->arg.x; break; case O_ADD: case O_SUB: case O_LESS: case O_MUL: case O_DIV: case O_IDIV: case O_MOD: case O_POWER: case O_ATAN2: case O_ROUND2: case O_TRUNC2: case O_UNIFORM: if (op == O_UNIFORM) code->vflag = 1; case O_NORMAL: if (op == O_NORMAL) code->vflag = 1; case O_CONCAT: case O_LT: case O_LE: case O_EQ: case O_GE: case O_GT: case O_NE: case O_AND: case O_OR: case O_UNION: case O_DIFF: case O_SYMDIFF: case O_INTER: case O_CROSS: case O_IN: case O_NOTIN: case O_WITHIN: case O_NOTWITHIN: case O_SUBSTR: case O_STR2TIME: case O_TIME2STR: /* binary operation */ xassert(arg->arg.x != NULL); xassert(arg->arg.x->up == NULL); arg->arg.x->up = code; code->vflag |= arg->arg.x->vflag; xassert(arg->arg.y != NULL); xassert(arg->arg.y->up == NULL); arg->arg.y->up = code; code->vflag |= arg->arg.y->vflag; code->arg.arg.x = arg->arg.x; code->arg.arg.y = arg->arg.y; break; case O_DOTS: case O_FORK: case O_SUBSTR3: /* ternary operation */ xassert(arg->arg.x != NULL); xassert(arg->arg.x->up == NULL); arg->arg.x->up = code; code->vflag |= arg->arg.x->vflag; xassert(arg->arg.y != NULL); xassert(arg->arg.y->up == NULL); arg->arg.y->up = code; code->vflag |= arg->arg.y->vflag; if (arg->arg.z != NULL) { xassert(arg->arg.z->up == NULL); arg->arg.z->up = code; code->vflag |= arg->arg.z->vflag; } code->arg.arg.x = arg->arg.x; code->arg.arg.y = arg->arg.y; code->arg.arg.z = arg->arg.z; break; case O_MIN: case O_MAX: /* n-ary operation */ for (e = arg->list; e != NULL; e = e->next) { xassert(e->x != NULL); xassert(e->x->up == NULL); e->x->up = code; code->vflag |= e->x->vflag; } code->arg.list = arg->list; break; case O_SUM: case O_PROD: case O_MINIMUM: case O_MAXIMUM: case O_FORALL: case O_EXISTS: case O_SETOF: case O_BUILD: /* iterated operation */ domain = arg->loop.domain; xassert(domain != NULL); if (domain->code != NULL) { xassert(domain->code->up == NULL); domain->code->up = code; code->vflag |= domain->code->vflag; } for (block = domain->list; block != NULL; block = block->next) { xassert(block->code != NULL); xassert(block->code->up == NULL); block->code->up = code; code->vflag |= block->code->vflag; } if (arg->loop.x != NULL) { xassert(arg->loop.x->up == NULL); arg->loop.x->up = code; code->vflag |= arg->loop.x->vflag; } code->arg.loop.domain = arg->loop.domain; code->arg.loop.x = arg->loop.x; break; default: xassert(op != op); } /* set other attributes of the pseudo-code */ code->type = type; code->dim = dim; code->up = NULL; code->valid = 0; memset(&code->value, '?', sizeof(VALUE)); return code; } /*---------------------------------------------------------------------- -- make_unary - generate pseudo-code for unary operation. -- -- This routine generates pseudo-code for unary operation. */ CODE *make_unary(MPL *mpl, int op, CODE *x, int type, int dim) { CODE *code; OPERANDS arg; xassert(x != NULL); arg.arg.x = x; code = make_code(mpl, op, &arg, type, dim); return code; } /*---------------------------------------------------------------------- -- make_binary - generate pseudo-code for binary operation. -- -- This routine generates pseudo-code for binary operation. */ CODE *make_binary(MPL *mpl, int op, CODE *x, CODE *y, int type, int dim) { CODE *code; OPERANDS arg; xassert(x != NULL); xassert(y != NULL); arg.arg.x = x; arg.arg.y = y; code = make_code(mpl, op, &arg, type, dim); return code; } /*---------------------------------------------------------------------- -- make_ternary - generate pseudo-code for ternary operation. -- -- This routine generates pseudo-code for ternary operation. */ CODE *make_ternary(MPL *mpl, int op, CODE *x, CODE *y, CODE *z, int type, int dim) { CODE *code; OPERANDS arg; xassert(x != NULL); xassert(y != NULL); /* third operand can be NULL */ arg.arg.x = x; arg.arg.y = y; arg.arg.z = z; code = make_code(mpl, op, &arg, type, dim); return code; } /*---------------------------------------------------------------------- -- numeric_literal - parse reference to numeric literal. -- -- This routine parses primary expression using the syntax: -- -- ::= */ CODE *numeric_literal(MPL *mpl) { CODE *code; OPERANDS arg; xassert(mpl->token == T_NUMBER); arg.num = mpl->value; code = make_code(mpl, O_NUMBER, &arg, A_NUMERIC, 0); get_token(mpl /* */); return code; } /*---------------------------------------------------------------------- -- string_literal - parse reference to string literal. -- -- This routine parses primary expression using the syntax: -- -- ::= */ CODE *string_literal(MPL *mpl) { CODE *code; OPERANDS arg; xassert(mpl->token == T_STRING); arg.str = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); strcpy(arg.str, mpl->image); code = make_code(mpl, O_STRING, &arg, A_SYMBOLIC, 0); get_token(mpl /* */); return code; } /*---------------------------------------------------------------------- -- create_arg_list - create empty operands list. -- -- This routine creates operands list, which is initially empty. */ ARG_LIST *create_arg_list(MPL *mpl) { ARG_LIST *list; xassert(mpl == mpl); list = NULL; return list; } /*---------------------------------------------------------------------- -- expand_arg_list - append operand to operands list. -- -- This routine appends new operand to specified operands list. */ ARG_LIST *expand_arg_list(MPL *mpl, ARG_LIST *list, CODE *x) { ARG_LIST *tail, *temp; xassert(x != NULL); /* create new operands list entry */ tail = alloc(ARG_LIST); tail->x = x; tail->next = NULL; /* and append it to the operands list */ if (list == NULL) list = tail; else { for (temp = list; temp->next != NULL; temp = temp->next); temp->next = tail; } return list; } /*---------------------------------------------------------------------- -- arg_list_len - determine length of operands list. -- -- This routine returns the number of operands in operands list. */ int arg_list_len(MPL *mpl, ARG_LIST *list) { ARG_LIST *temp; int len; xassert(mpl == mpl); len = 0; for (temp = list; temp != NULL; temp = temp->next) len++; return len; } /*---------------------------------------------------------------------- -- subscript_list - parse subscript list. -- -- This routine parses subscript list using the syntax: -- -- ::= -- ::= , -- ::= */ ARG_LIST *subscript_list(MPL *mpl) { ARG_LIST *list; CODE *x; list = create_arg_list(mpl); for (;;) { /* parse subscript expression */ x = expression_5(mpl); /* convert it to symbolic type, if necessary */ if (x->type == A_NUMERIC) x = make_unary(mpl, O_CVTSYM, x, A_SYMBOLIC, 0); /* check that now the expression is of symbolic type */ if (x->type != A_SYMBOLIC) mpl_error(mpl, "subscript expression has invalid type"); xassert(x->dim == 0); /* and append it to the subscript list */ list = expand_arg_list(mpl, list, x); /* check a token that follows the subscript expression */ if (mpl->token == T_COMMA) get_token(mpl /* , */); else if (mpl->token == T_RBRACKET) break; else mpl_error(mpl, "syntax error in subscript list"); } return list; } #if 1 /* 15/V-2010 */ /*---------------------------------------------------------------------- -- object_reference - parse reference to named object. -- -- This routine parses primary expression using the syntax: -- -- ::= -- ::= -- ::= [ ] -- ::= -- ::= [ ] -- ::= -- ::= [ ] -- -- ::= -- ::= [ ] -- -- ::= -- ::= -- ::= -- ::= -- ::= -- ::= | .lb | .ub | .status | .val | .dual */ CODE *object_reference(MPL *mpl) { AVLNODE *node; DOMAIN_SLOT *slot; SET *set; PARAMETER *par; VARIABLE *var; CONSTRAINT *con; ARG_LIST *list; OPERANDS arg; CODE *code; char *name; int dim, suff; /* find the object in the symbolic name table */ xassert(mpl->token == T_NAME); node = avl_find_node(mpl->tree, mpl->image); if (node == NULL) mpl_error(mpl, "%s not defined", mpl->image); /* check the object type and obtain its dimension */ switch (avl_get_node_type(node)) { case A_INDEX: /* dummy index */ slot = (DOMAIN_SLOT *)avl_get_node_link(node); name = slot->name; dim = 0; break; case A_SET: /* model set */ set = (SET *)avl_get_node_link(node); name = set->name; dim = set->dim; /* if a set object is referenced in its own declaration and the dimen attribute is not specified yet, use dimen 1 by default */ if (set->dimen == 0) set->dimen = 1; break; case A_PARAMETER: /* model parameter */ par = (PARAMETER *)avl_get_node_link(node); name = par->name; dim = par->dim; break; case A_VARIABLE: /* model variable */ var = (VARIABLE *)avl_get_node_link(node); name = var->name; dim = var->dim; break; case A_CONSTRAINT: /* model constraint or objective */ con = (CONSTRAINT *)avl_get_node_link(node); name = con->name; dim = con->dim; break; default: xassert(node != node); } get_token(mpl /* */); /* parse optional subscript list */ if (mpl->token == T_LBRACKET) { /* subscript list is specified */ if (dim == 0) mpl_error(mpl, "%s cannot be subscripted", name); get_token(mpl /* [ */); list = subscript_list(mpl); if (dim != arg_list_len(mpl, list)) mpl_error(mpl, "%s must have %d subscript%s rather than %d", name, dim, dim == 1 ? "" : "s", arg_list_len(mpl, list)); xassert(mpl->token == T_RBRACKET); get_token(mpl /* ] */); } else { /* subscript list is not specified */ if (dim != 0) mpl_error(mpl, "%s must be subscripted", name); list = create_arg_list(mpl); } /* parse optional suffix */ if (!mpl->flag_s && avl_get_node_type(node) == A_VARIABLE) suff = DOT_NONE; else suff = DOT_VAL; if (mpl->token == T_POINT) { get_token(mpl /* . */); if (mpl->token != T_NAME) mpl_error(mpl, "invalid use of period"); if (!(avl_get_node_type(node) == A_VARIABLE || avl_get_node_type(node) == A_CONSTRAINT)) mpl_error(mpl, "%s cannot have a suffix", name); if (strcmp(mpl->image, "lb") == 0) suff = DOT_LB; else if (strcmp(mpl->image, "ub") == 0) suff = DOT_UB; else if (strcmp(mpl->image, "status") == 0) suff = DOT_STATUS; else if (strcmp(mpl->image, "val") == 0) suff = DOT_VAL; else if (strcmp(mpl->image, "dual") == 0) suff = DOT_DUAL; else mpl_error(mpl, "suffix .%s invalid", mpl->image); get_token(mpl /* suffix */); } /* generate pseudo-code to take value of the object */ switch (avl_get_node_type(node)) { case A_INDEX: arg.index.slot = slot; arg.index.next = slot->list; code = make_code(mpl, O_INDEX, &arg, A_SYMBOLIC, 0); slot->list = code; break; case A_SET: arg.set.set = set; arg.set.list = list; code = make_code(mpl, O_MEMSET, &arg, A_ELEMSET, set->dimen); break; case A_PARAMETER: arg.par.par = par; arg.par.list = list; if (par->type == A_SYMBOLIC) code = make_code(mpl, O_MEMSYM, &arg, A_SYMBOLIC, 0); else code = make_code(mpl, O_MEMNUM, &arg, A_NUMERIC, 0); break; case A_VARIABLE: if (!mpl->flag_s && (suff == DOT_STATUS || suff == DOT_VAL || suff == DOT_DUAL)) mpl_error(mpl, "invalid reference to status, primal value, o" "r dual value of variable %s above solve statement", var->name); arg.var.var = var; arg.var.list = list; arg.var.suff = suff; code = make_code(mpl, O_MEMVAR, &arg, suff == DOT_NONE ? A_FORMULA : A_NUMERIC, 0); break; case A_CONSTRAINT: if (!mpl->flag_s && (suff == DOT_STATUS || suff == DOT_VAL || suff == DOT_DUAL)) mpl_error(mpl, "invalid reference to status, primal value, o" "r dual value of %s %s above solve statement", con->type == A_CONSTRAINT ? "constraint" : "objective" , con->name); arg.con.con = con; arg.con.list = list; arg.con.suff = suff; code = make_code(mpl, O_MEMCON, &arg, A_NUMERIC, 0); break; default: xassert(node != node); } return code; } #endif /*---------------------------------------------------------------------- -- numeric_argument - parse argument passed to built-in function. -- -- This routine parses an argument passed to numeric built-in function -- using the syntax: -- -- ::= */ CODE *numeric_argument(MPL *mpl, char *func) { CODE *x; x = expression_5(mpl); /* convert the argument to numeric type, if necessary */ if (x->type == A_SYMBOLIC) x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); /* check that now the argument is of numeric type */ if (x->type != A_NUMERIC) mpl_error(mpl, "argument for %s has invalid type", func); xassert(x->dim == 0); return x; } #if 1 /* 15/VII-2006 */ CODE *symbolic_argument(MPL *mpl, char *func) { CODE *x; x = expression_5(mpl); /* convert the argument to symbolic type, if necessary */ if (x->type == A_NUMERIC) x = make_unary(mpl, O_CVTSYM, x, A_SYMBOLIC, 0); /* check that now the argument is of symbolic type */ if (x->type != A_SYMBOLIC) mpl_error(mpl, "argument for %s has invalid type", func); xassert(x->dim == 0); return x; } #endif #if 1 /* 15/VII-2006 */ CODE *elemset_argument(MPL *mpl, char *func) { CODE *x; x = expression_9(mpl); if (x->type != A_ELEMSET) mpl_error(mpl, "argument for %s has invalid type", func); xassert(x->dim > 0); return x; } #endif /*---------------------------------------------------------------------- -- function_reference - parse reference to built-in function. -- -- This routine parses primary expression using the syntax: -- -- ::= abs ( ) -- ::= ceil ( ) -- ::= floor ( ) -- ::= exp ( ) -- ::= log ( ) -- ::= log10 ( ) -- ::= max ( ) -- ::= min ( ) -- ::= sqrt ( ) -- ::= sin ( ) -- ::= cos ( ) -- ::= atan ( ) -- ::= atan2 ( , ) -- ::= round ( ) -- ::= round ( , ) -- ::= trunc ( ) -- ::= trunc ( , ) -- ::= Irand224 ( ) -- ::= Uniform01 ( ) -- ::= Uniform ( , ) -- ::= Normal01 ( ) -- ::= Normal ( , ) -- ::= card ( ) -- ::= length ( ) -- ::= substr ( , ) -- ::= substr ( , , ) -- ::= str2time ( , ) -- ::= time2str ( , ) -- ::= gmtime ( ) -- ::= -- ::= , */ CODE *function_reference(MPL *mpl) { CODE *code; OPERANDS arg; int op; char func[15+1]; /* determine operation code */ xassert(mpl->token == T_NAME); if (strcmp(mpl->image, "abs") == 0) op = O_ABS; else if (strcmp(mpl->image, "ceil") == 0) op = O_CEIL; else if (strcmp(mpl->image, "floor") == 0) op = O_FLOOR; else if (strcmp(mpl->image, "exp") == 0) op = O_EXP; else if (strcmp(mpl->image, "log") == 0) op = O_LOG; else if (strcmp(mpl->image, "log10") == 0) op = O_LOG10; else if (strcmp(mpl->image, "sqrt") == 0) op = O_SQRT; else if (strcmp(mpl->image, "sin") == 0) op = O_SIN; else if (strcmp(mpl->image, "cos") == 0) op = O_COS; else if (strcmp(mpl->image, "atan") == 0) op = O_ATAN; else if (strcmp(mpl->image, "min") == 0) op = O_MIN; else if (strcmp(mpl->image, "max") == 0) op = O_MAX; else if (strcmp(mpl->image, "round") == 0) op = O_ROUND; else if (strcmp(mpl->image, "trunc") == 0) op = O_TRUNC; else if (strcmp(mpl->image, "Irand224") == 0) op = O_IRAND224; else if (strcmp(mpl->image, "Uniform01") == 0) op = O_UNIFORM01; else if (strcmp(mpl->image, "Uniform") == 0) op = O_UNIFORM; else if (strcmp(mpl->image, "Normal01") == 0) op = O_NORMAL01; else if (strcmp(mpl->image, "Normal") == 0) op = O_NORMAL; else if (strcmp(mpl->image, "card") == 0) op = O_CARD; else if (strcmp(mpl->image, "length") == 0) op = O_LENGTH; else if (strcmp(mpl->image, "substr") == 0) op = O_SUBSTR; else if (strcmp(mpl->image, "str2time") == 0) op = O_STR2TIME; else if (strcmp(mpl->image, "time2str") == 0) op = O_TIME2STR; else if (strcmp(mpl->image, "gmtime") == 0) op = O_GMTIME; else mpl_error(mpl, "function %s unknown", mpl->image); /* save symbolic name of the function */ strcpy(func, mpl->image); xassert(strlen(func) < sizeof(func)); get_token(mpl /* */); /* check the left parenthesis that follows the function name */ xassert(mpl->token == T_LEFT); get_token(mpl /* ( */); /* parse argument list */ if (op == O_MIN || op == O_MAX) { /* min and max allow arbitrary number of arguments */ arg.list = create_arg_list(mpl); /* parse argument list */ for (;;) { /* parse argument and append it to the operands list */ arg.list = expand_arg_list(mpl, arg.list, numeric_argument(mpl, func)); /* check a token that follows the argument */ if (mpl->token == T_COMMA) get_token(mpl /* , */); else if (mpl->token == T_RIGHT) break; else mpl_error(mpl, "syntax error in argument list for %s", func); } } else if (op == O_IRAND224 || op == O_UNIFORM01 || op == O_NORMAL01 || op == O_GMTIME) { /* Irand224, Uniform01, Normal01, gmtime need no arguments */ if (mpl->token != T_RIGHT) mpl_error(mpl, "%s needs no arguments", func); } else if (op == O_UNIFORM || op == O_NORMAL) { /* Uniform and Normal need two arguments */ /* parse the first argument */ arg.arg.x = numeric_argument(mpl, func); /* check a token that follows the first argument */ if (mpl->token == T_COMMA) ; else if (mpl->token == T_RIGHT) mpl_error(mpl, "%s needs two arguments", func); else mpl_error(mpl, "syntax error in argument for %s", func); get_token(mpl /* , */); /* parse the second argument */ arg.arg.y = numeric_argument(mpl, func); /* check a token that follows the second argument */ if (mpl->token == T_COMMA) mpl_error(mpl, "%s needs two argument", func); else if (mpl->token == T_RIGHT) ; else mpl_error(mpl, "syntax error in argument for %s", func); } else if (op == O_ATAN || op == O_ROUND || op == O_TRUNC) { /* atan, round, and trunc need one or two arguments */ /* parse the first argument */ arg.arg.x = numeric_argument(mpl, func); /* parse the second argument, if specified */ if (mpl->token == T_COMMA) { switch (op) { case O_ATAN: op = O_ATAN2; break; case O_ROUND: op = O_ROUND2; break; case O_TRUNC: op = O_TRUNC2; break; default: xassert(op != op); } get_token(mpl /* , */); arg.arg.y = numeric_argument(mpl, func); } /* check a token that follows the last argument */ if (mpl->token == T_COMMA) mpl_error(mpl, "%s needs one or two arguments", func); else if (mpl->token == T_RIGHT) ; else mpl_error(mpl, "syntax error in argument for %s", func); } else if (op == O_SUBSTR) { /* substr needs two or three arguments */ /* parse the first argument */ arg.arg.x = symbolic_argument(mpl, func); /* check a token that follows the first argument */ if (mpl->token == T_COMMA) ; else if (mpl->token == T_RIGHT) mpl_error(mpl, "%s needs two or three arguments", func); else mpl_error(mpl, "syntax error in argument for %s", func); get_token(mpl /* , */); /* parse the second argument */ arg.arg.y = numeric_argument(mpl, func); /* parse the third argument, if specified */ if (mpl->token == T_COMMA) { op = O_SUBSTR3; get_token(mpl /* , */); arg.arg.z = numeric_argument(mpl, func); } /* check a token that follows the last argument */ if (mpl->token == T_COMMA) mpl_error(mpl, "%s needs two or three arguments", func); else if (mpl->token == T_RIGHT) ; else mpl_error(mpl, "syntax error in argument for %s", func); } else if (op == O_STR2TIME) { /* str2time needs two arguments, both symbolic */ /* parse the first argument */ arg.arg.x = symbolic_argument(mpl, func); /* check a token that follows the first argument */ if (mpl->token == T_COMMA) ; else if (mpl->token == T_RIGHT) mpl_error(mpl, "%s needs two arguments", func); else mpl_error(mpl, "syntax error in argument for %s", func); get_token(mpl /* , */); /* parse the second argument */ arg.arg.y = symbolic_argument(mpl, func); /* check a token that follows the second argument */ if (mpl->token == T_COMMA) mpl_error(mpl, "%s needs two argument", func); else if (mpl->token == T_RIGHT) ; else mpl_error(mpl, "syntax error in argument for %s", func); } else if (op == O_TIME2STR) { /* time2str needs two arguments, numeric and symbolic */ /* parse the first argument */ arg.arg.x = numeric_argument(mpl, func); /* check a token that follows the first argument */ if (mpl->token == T_COMMA) ; else if (mpl->token == T_RIGHT) mpl_error(mpl, "%s needs two arguments", func); else mpl_error(mpl, "syntax error in argument for %s", func); get_token(mpl /* , */); /* parse the second argument */ arg.arg.y = symbolic_argument(mpl, func); /* check a token that follows the second argument */ if (mpl->token == T_COMMA) mpl_error(mpl, "%s needs two argument", func); else if (mpl->token == T_RIGHT) ; else mpl_error(mpl, "syntax error in argument for %s", func); } else { /* other functions need one argument */ if (op == O_CARD) arg.arg.x = elemset_argument(mpl, func); else if (op == O_LENGTH) arg.arg.x = symbolic_argument(mpl, func); else arg.arg.x = numeric_argument(mpl, func); /* check a token that follows the argument */ if (mpl->token == T_COMMA) mpl_error(mpl, "%s needs one argument", func); else if (mpl->token == T_RIGHT) ; else mpl_error(mpl, "syntax error in argument for %s", func); } /* make pseudo-code to call the built-in function */ if (op == O_SUBSTR || op == O_SUBSTR3 || op == O_TIME2STR) code = make_code(mpl, op, &arg, A_SYMBOLIC, 0); else code = make_code(mpl, op, &arg, A_NUMERIC, 0); /* the reference ends with the right parenthesis */ xassert(mpl->token == T_RIGHT); get_token(mpl /* ) */); return code; } /*---------------------------------------------------------------------- -- create_domain - create empty domain. -- -- This routine creates empty domain, which is initially empty, i.e. -- has no domain blocks. */ DOMAIN *create_domain(MPL *mpl) { DOMAIN *domain; domain = alloc(DOMAIN); domain->list = NULL; domain->code = NULL; return domain; } /*---------------------------------------------------------------------- -- create_block - create empty domain block. -- -- This routine creates empty domain block, which is initially empty, -- i.e. has no domain slots. */ DOMAIN_BLOCK *create_block(MPL *mpl) { DOMAIN_BLOCK *block; block = alloc(DOMAIN_BLOCK); block->list = NULL; block->code = NULL; block->backup = NULL; block->next = NULL; return block; } /*---------------------------------------------------------------------- -- append_block - append domain block to specified domain. -- -- This routine adds given domain block to the end of the block list of -- specified domain. */ void append_block(MPL *mpl, DOMAIN *domain, DOMAIN_BLOCK *block) { DOMAIN_BLOCK *temp; xassert(mpl == mpl); xassert(domain != NULL); xassert(block != NULL); xassert(block->next == NULL); if (domain->list == NULL) domain->list = block; else { for (temp = domain->list; temp->next != NULL; temp = temp->next); temp->next = block; } return; } /*---------------------------------------------------------------------- -- append_slot - create and append new slot to domain block. -- -- This routine creates new domain slot and adds it to the end of slot -- list of specified domain block. -- -- The parameter name is symbolic name of the dummy index associated -- with the slot (the character string must be allocated). NULL means -- the dummy index is not explicitly specified. -- -- The parameter code is pseudo-code for computing symbolic value, at -- which the dummy index is bounded. NULL means the dummy index is free -- in the domain scope. */ DOMAIN_SLOT *append_slot(MPL *mpl, DOMAIN_BLOCK *block, char *name, CODE *code) { DOMAIN_SLOT *slot, *temp; xassert(block != NULL); slot = alloc(DOMAIN_SLOT); slot->name = name; slot->code = code; slot->value = NULL; slot->list = NULL; slot->next = NULL; if (block->list == NULL) block->list = slot; else { for (temp = block->list; temp->next != NULL; temp = temp->next); temp->next = slot; } return slot; } /*---------------------------------------------------------------------- -- expression_list - parse expression list. -- -- This routine parses a list of one or more expressions enclosed into -- the parentheses using the syntax: -- -- ::= ( ) -- ::= -- ::= , -- -- Note that this construction may have three different meanings: -- -- 1. If consists of only one expression, is a parenthesized expression, which may be of any -- valid type (not necessarily 1-tuple). -- -- 2. If consists of several expressions separated by -- commae, where no expression is undeclared symbolic name, is a n-tuple. -- -- 3. If consists of several expressions separated by -- commae, where at least one expression is undeclared symbolic name -- (that denotes a dummy index), is a slice and -- can be only used as constituent of indexing expression. */ #define max_dim 20 /* maximal number of components allowed within parentheses */ CODE *expression_list(MPL *mpl) { CODE *code; OPERANDS arg; struct { char *name; CODE *code; } list[1+max_dim]; int flag_x, next_token, dim, j, slice = 0; xassert(mpl->token == T_LEFT); /* the flag, which allows recognizing undeclared symbolic names as dummy indices, will be automatically reset by get_token(), so save it before scanning the next token */ flag_x = mpl->flag_x; get_token(mpl /* ( */); /* parse */ for (dim = 1; ; dim++) { if (dim > max_dim) mpl_error(mpl, "too many components within parentheses"); /* current component of can be either dummy index or expression */ if (mpl->token == T_NAME) { /* symbolic name is recognized as dummy index only if: the flag, which allows that, is set, and the name is followed by comma or right parenthesis, and the name is undeclared */ get_token(mpl /* */); next_token = mpl->token; unget_token(mpl); if (!(flag_x && (next_token == T_COMMA || next_token == T_RIGHT) && avl_find_node(mpl->tree, mpl->image) == NULL)) { /* this is not dummy index */ goto expr; } /* all dummy indices within the same slice must have unique symbolic names */ for (j = 1; j < dim; j++) { if (list[j].name != NULL && strcmp(list[j].name, mpl->image) == 0) mpl_error(mpl, "duplicate dummy index %s not allowed", mpl->image); } /* current component of is dummy index */ list[dim].name = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); strcpy(list[dim].name, mpl->image); list[dim].code = NULL; get_token(mpl /* */); /* is a slice, because at least one dummy index has appeared */ slice = 1; /* note that the context ( ) is not allowed, i.e. in this case is considered as a parenthesized expression */ if (dim == 1 && mpl->token == T_RIGHT) mpl_error(mpl, "%s not defined", list[dim].name); } else expr: { /* current component of is expression */ code = expression_13(mpl); /* if the current expression is followed by comma or it is not the very first expression, entire is n-tuple or slice, in which case the current expression should be converted to symbolic type, if necessary */ if (mpl->token == T_COMMA || dim > 1) { if (code->type == A_NUMERIC) code = make_unary(mpl, O_CVTSYM, code, A_SYMBOLIC, 0); /* now the expression must be of symbolic type */ if (code->type != A_SYMBOLIC) mpl_error(mpl, "component expression has invalid type"); xassert(code->dim == 0); } list[dim].name = NULL; list[dim].code = code; } /* check a token that follows the current component */ if (mpl->token == T_COMMA) get_token(mpl /* , */); else if (mpl->token == T_RIGHT) break; else mpl_error(mpl, "right parenthesis missing where expected"); } /* generate pseudo-code for */ if (dim == 1 && !slice) { /* is a parenthesized expression */ code = list[1].code; } else if (!slice) { /* is a n-tuple */ arg.list = create_arg_list(mpl); for (j = 1; j <= dim; j++) arg.list = expand_arg_list(mpl, arg.list, list[j].code); code = make_code(mpl, O_TUPLE, &arg, A_TUPLE, dim); } else { /* is a slice */ arg.slice = create_block(mpl); for (j = 1; j <= dim; j++) append_slot(mpl, arg.slice, list[j].name, list[j].code); /* note that actually pseudo-codes with op = O_SLICE are never evaluated */ code = make_code(mpl, O_SLICE, &arg, A_TUPLE, dim); } get_token(mpl /* ) */); /* if is a slice, there must be the keyword 'in', which follows the right parenthesis */ if (slice && mpl->token != T_IN) mpl_error(mpl, "keyword in missing where expected"); /* if the slice flag is set and there is the keyword 'in', which follows , the latter must be a slice */ if (flag_x && mpl->token == T_IN && !slice) { if (dim == 1) mpl_error(mpl, "syntax error in indexing expression"); else mpl_error(mpl, "0-ary slice not allowed"); } return code; } /*---------------------------------------------------------------------- -- literal set - parse literal set. -- -- This routine parses literal set using the syntax: -- -- ::= { } -- ::= -- ::= , -- ::= -- -- It is assumed that the left curly brace and the very first member -- expression that follows it are already parsed. The right curly brace -- remains unscanned on exit. */ CODE *literal_set(MPL *mpl, CODE *code) { OPERANDS arg; int j; xassert(code != NULL); arg.list = create_arg_list(mpl); /* parse */ for (j = 1; ; j++) { /* all member expressions must be n-tuples; so, if the current expression is not n-tuple, convert it to 1-tuple */ if (code->type == A_NUMERIC) code = make_unary(mpl, O_CVTSYM, code, A_SYMBOLIC, 0); if (code->type == A_SYMBOLIC) code = make_unary(mpl, O_CVTTUP, code, A_TUPLE, 1); /* now the expression must be n-tuple */ if (code->type != A_TUPLE) mpl_error(mpl, "member expression has invalid type"); /* all member expressions must have identical dimension */ if (arg.list != NULL && arg.list->x->dim != code->dim) mpl_error(mpl, "member %d has %d component%s while member %d ha" "s %d component%s", j-1, arg.list->x->dim, arg.list->x->dim == 1 ? "" : "s", j, code->dim, code->dim == 1 ? "" : "s"); /* append the current expression to the member list */ arg.list = expand_arg_list(mpl, arg.list, code); /* check a token that follows the current expression */ if (mpl->token == T_COMMA) get_token(mpl /* , */); else if (mpl->token == T_RBRACE) break; else mpl_error(mpl, "syntax error in literal set"); /* parse the next expression that follows the comma */ code = expression_5(mpl); } /* generate pseudo-code for */ code = make_code(mpl, O_MAKE, &arg, A_ELEMSET, arg.list->x->dim); return code; } /*---------------------------------------------------------------------- -- indexing_expression - parse indexing expression. -- -- This routine parses indexing expression using the syntax: -- -- ::= -- ::= { } -- ::= { : } -- ::= -- ::= , -- ::= -- ::= in -- ::= in -- ::= -- ::= ( ) -- ::= -- ::= -- -- This routine creates domain for , where each -- domain block corresponds to , and each domain slot -- corresponds to individual indexing position. */ DOMAIN *indexing_expression(MPL *mpl) { DOMAIN *domain; DOMAIN_BLOCK *block; DOMAIN_SLOT *slot; CODE *code; xassert(mpl->token == T_LBRACE); get_token(mpl /* { */); if (mpl->token == T_RBRACE) mpl_error(mpl, "empty indexing expression not allowed"); /* create domain to be constructed */ domain = create_domain(mpl); /* parse either or that follows the left brace */ for (;;) { /* domain block for is not created yet */ block = NULL; /* pseudo-code for is not generated yet */ code = NULL; /* check a token, which begins with */ if (mpl->token == T_NAME) { /* it is a symbolic name */ int next_token; char *name; /* symbolic name is recognized as dummy index only if it is followed by the keyword 'in' and not declared */ get_token(mpl /* */); next_token = mpl->token; unget_token(mpl); if (!(next_token == T_IN && avl_find_node(mpl->tree, mpl->image) == NULL)) { /* this is not dummy index; the symbolic name begins an expression, which is either or the very first in */ goto expr; } /* create domain block with one slot, which is assigned the dummy index */ block = create_block(mpl); name = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); strcpy(name, mpl->image); append_slot(mpl, block, name, NULL); get_token(mpl /* */); /* the keyword 'in' is already checked above */ xassert(mpl->token == T_IN); get_token(mpl /* in */); /* that follows the keyword 'in' will be parsed below */ } else if (mpl->token == T_LEFT) { /* it is the left parenthesis; parse expression that begins with this parenthesis (the flag is set in order to allow recognizing slices; see the routine expression_list) */ mpl->flag_x = 1; code = expression_9(mpl); if (code->op != O_SLICE) { /* this is either or the very first in */ goto expr; } /* this is a slice; besides the corresponding domain block is already created by expression_list() */ block = code->arg.slice; code = NULL; /* is not parsed yet */ /* the keyword 'in' following the slice is already checked by expression_list() */ xassert(mpl->token == T_IN); get_token(mpl /* in */); /* that follows the keyword 'in' will be parsed below */ } expr: /* parse expression that follows either the keyword 'in' (in which case it can be as well as the very first in ); note that this expression can be already parsed above */ if (code == NULL) code = expression_9(mpl); /* check the type of the expression just parsed */ if (code->type != A_ELEMSET) { /* it is not and therefore it can only be the very first in ; however, then there must be no dummy index neither slice between the left brace and this expression */ if (block != NULL) mpl_error(mpl, "domain expression has invalid type"); /* parse the rest part of and make this set be , i.e. the construction {a, b, c} is parsed as it were written as {A}, where A = {a, b, c} is a temporary elemental set */ code = literal_set(mpl, code); } /* now pseudo-code for has been built */ xassert(code != NULL); xassert(code->type == A_ELEMSET); xassert(code->dim > 0); /* if domain block for the current is still not created, create it for fake slice of the same dimension as */ if (block == NULL) { int j; block = create_block(mpl); for (j = 1; j <= code->dim; j++) append_slot(mpl, block, NULL, NULL); } /* number of indexing positions in must be the same as dimension of n-tuples in basic set */ { int dim = 0; for (slot = block->list; slot != NULL; slot = slot->next) dim++; if (dim != code->dim) mpl_error(mpl,"%d %s specified for set of dimension %d", dim, dim == 1 ? "index" : "indices", code->dim); } /* store pseudo-code for in the domain block */ xassert(block->code == NULL); block->code = code; /* and append the domain block to the domain */ append_block(mpl, domain, block); /* the current has been completely parsed; include all its dummy indices into the symbolic name table to make them available for referencing from expressions; implicit declarations of dummy indices remain valid while the corresponding domain scope is valid */ for (slot = block->list; slot != NULL; slot = slot->next) if (slot->name != NULL) { AVLNODE *node; xassert(avl_find_node(mpl->tree, slot->name) == NULL); node = avl_insert_node(mpl->tree, slot->name); avl_set_node_type(node, A_INDEX); avl_set_node_link(node, (void *)slot); } /* check a token that follows */ if (mpl->token == T_COMMA) get_token(mpl /* , */); else if (mpl->token == T_COLON || mpl->token == T_RBRACE) break; else mpl_error(mpl, "syntax error in indexing expression"); } /* parse that follows the colon */ if (mpl->token == T_COLON) { get_token(mpl /* : */); code = expression_13(mpl); /* convert the expression to logical type, if necessary */ if (code->type == A_SYMBOLIC) code = make_unary(mpl, O_CVTNUM, code, A_NUMERIC, 0); if (code->type == A_NUMERIC) code = make_unary(mpl, O_CVTLOG, code, A_LOGICAL, 0); /* now the expression must be of logical type */ if (code->type != A_LOGICAL) mpl_error(mpl, "expression following colon has invalid type"); xassert(code->dim == 0); domain->code = code; /* the right brace must follow the logical expression */ if (mpl->token != T_RBRACE) mpl_error(mpl, "syntax error in indexing expression"); } get_token(mpl /* } */); return domain; } /*---------------------------------------------------------------------- -- close_scope - close scope of indexing expression. -- -- The routine closes the scope of indexing expression specified by its -- domain and thereby makes all dummy indices introduced in the indexing -- expression no longer available for referencing. */ void close_scope(MPL *mpl, DOMAIN *domain) { DOMAIN_BLOCK *block; DOMAIN_SLOT *slot; AVLNODE *node; xassert(domain != NULL); /* remove all dummy indices from the symbolic names table */ for (block = domain->list; block != NULL; block = block->next) { for (slot = block->list; slot != NULL; slot = slot->next) { if (slot->name != NULL) { node = avl_find_node(mpl->tree, slot->name); xassert(node != NULL); xassert(avl_get_node_type(node) == A_INDEX); avl_delete_node(mpl->tree, node); } } } return; } /*---------------------------------------------------------------------- -- iterated_expression - parse iterated expression. -- -- This routine parses primary expression using the syntax: -- -- ::= -- ::= sum -- ::= prod -- ::= min -- ::= max -- ::= exists -- -- ::= forall -- -- ::= setof -- -- Note that parsing "integrand" depends on the iterated operator. */ #if 1 /* 07/IX-2008 */ static void link_up(CODE *code) { /* if we have something like sum{(i+1,j,k-1) in E} x[i,j,k], where i and k are dummy indices defined out of the iterated expression, we should link up pseudo-code for computing i+1 and k-1 to pseudo-code for computing the iterated expression; this is needed to invalidate current value of the iterated expression once i or k have been changed */ DOMAIN_BLOCK *block; DOMAIN_SLOT *slot; for (block = code->arg.loop.domain->list; block != NULL; block = block->next) { for (slot = block->list; slot != NULL; slot = slot->next) { if (slot->code != NULL) { xassert(slot->code->up == NULL); slot->code->up = code; } } } return; } #endif CODE *iterated_expression(MPL *mpl) { CODE *code; OPERANDS arg; int op; char opstr[8]; /* determine operation code */ xassert(mpl->token == T_NAME); if (strcmp(mpl->image, "sum") == 0) op = O_SUM; else if (strcmp(mpl->image, "prod") == 0) op = O_PROD; else if (strcmp(mpl->image, "min") == 0) op = O_MINIMUM; else if (strcmp(mpl->image, "max") == 0) op = O_MAXIMUM; else if (strcmp(mpl->image, "forall") == 0) op = O_FORALL; else if (strcmp(mpl->image, "exists") == 0) op = O_EXISTS; else if (strcmp(mpl->image, "setof") == 0) op = O_SETOF; else mpl_error(mpl, "operator %s unknown", mpl->image); strcpy(opstr, mpl->image); xassert(strlen(opstr) < sizeof(opstr)); get_token(mpl /* */); /* check the left brace that follows the operator name */ xassert(mpl->token == T_LBRACE); /* parse indexing expression that controls iterating */ arg.loop.domain = indexing_expression(mpl); /* parse "integrand" expression and generate pseudo-code */ switch (op) { case O_SUM: case O_PROD: case O_MINIMUM: case O_MAXIMUM: arg.loop.x = expression_3(mpl); /* convert the integrand to numeric type, if necessary */ if (arg.loop.x->type == A_SYMBOLIC) arg.loop.x = make_unary(mpl, O_CVTNUM, arg.loop.x, A_NUMERIC, 0); /* now the integrand must be of numeric type or linear form (the latter is only allowed for the sum operator) */ if (!(arg.loop.x->type == A_NUMERIC || op == O_SUM && arg.loop.x->type == A_FORMULA)) err: mpl_error(mpl, "integrand following %s{...} has invalid type" , opstr); xassert(arg.loop.x->dim == 0); /* generate pseudo-code */ code = make_code(mpl, op, &arg, arg.loop.x->type, 0); break; case O_FORALL: case O_EXISTS: arg.loop.x = expression_12(mpl); /* convert the integrand to logical type, if necessary */ if (arg.loop.x->type == A_SYMBOLIC) arg.loop.x = make_unary(mpl, O_CVTNUM, arg.loop.x, A_NUMERIC, 0); if (arg.loop.x->type == A_NUMERIC) arg.loop.x = make_unary(mpl, O_CVTLOG, arg.loop.x, A_LOGICAL, 0); /* now the integrand must be of logical type */ if (arg.loop.x->type != A_LOGICAL) goto err; xassert(arg.loop.x->dim == 0); /* generate pseudo-code */ code = make_code(mpl, op, &arg, A_LOGICAL, 0); break; case O_SETOF: arg.loop.x = expression_5(mpl); /* convert the integrand to 1-tuple, if necessary */ if (arg.loop.x->type == A_NUMERIC) arg.loop.x = make_unary(mpl, O_CVTSYM, arg.loop.x, A_SYMBOLIC, 0); if (arg.loop.x->type == A_SYMBOLIC) arg.loop.x = make_unary(mpl, O_CVTTUP, arg.loop.x, A_TUPLE, 1); /* now the integrand must be n-tuple */ if (arg.loop.x->type != A_TUPLE) goto err; xassert(arg.loop.x->dim > 0); /* generate pseudo-code */ code = make_code(mpl, op, &arg, A_ELEMSET, arg.loop.x->dim); break; default: xassert(op != op); } /* close the scope of the indexing expression */ close_scope(mpl, arg.loop.domain); #if 1 /* 07/IX-2008 */ link_up(code); #endif return code; } /*---------------------------------------------------------------------- -- domain_arity - determine arity of domain. -- -- This routine returns arity of specified domain, which is number of -- its free dummy indices. */ int domain_arity(MPL *mpl, DOMAIN *domain) { DOMAIN_BLOCK *block; DOMAIN_SLOT *slot; int arity; xassert(mpl == mpl); arity = 0; for (block = domain->list; block != NULL; block = block->next) for (slot = block->list; slot != NULL; slot = slot->next) if (slot->code == NULL) arity++; return arity; } /*---------------------------------------------------------------------- -- set_expression - parse set expression. -- -- This routine parses primary expression using the syntax: -- -- ::= { } -- ::= */ CODE *set_expression(MPL *mpl) { CODE *code; OPERANDS arg; xassert(mpl->token == T_LBRACE); get_token(mpl /* { */); /* check a token that follows the left brace */ if (mpl->token == T_RBRACE) { /* it is the right brace, so the resultant is an empty set of dimension 1 */ arg.list = NULL; /* generate pseudo-code to build the resultant set */ code = make_code(mpl, O_MAKE, &arg, A_ELEMSET, 1); get_token(mpl /* } */); } else { /* the next token begins an indexing expression */ unget_token(mpl); arg.loop.domain = indexing_expression(mpl); arg.loop.x = NULL; /* integrand is not used */ /* close the scope of the indexing expression */ close_scope(mpl, arg.loop.domain); /* generate pseudo-code to build the resultant set */ code = make_code(mpl, O_BUILD, &arg, A_ELEMSET, domain_arity(mpl, arg.loop.domain)); #if 1 /* 07/IX-2008 */ link_up(code); #endif } return code; } /*---------------------------------------------------------------------- -- branched_expression - parse conditional expression. -- -- This routine parses primary expression using the syntax: -- -- ::= -- ::= if then -- ::= if then -- else -- ::= */ CODE *branched_expression(MPL *mpl) { CODE *code, *x, *y, *z; xassert(mpl->token == T_IF); get_token(mpl /* if */); /* parse that follows 'if' */ x = expression_13(mpl); /* convert the expression to logical type, if necessary */ if (x->type == A_SYMBOLIC) x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); if (x->type == A_NUMERIC) x = make_unary(mpl, O_CVTLOG, x, A_LOGICAL, 0); /* now the expression must be of logical type */ if (x->type != A_LOGICAL) mpl_error(mpl, "expression following if has invalid type"); xassert(x->dim == 0); /* the keyword 'then' must follow the logical expression */ if (mpl->token != T_THEN) mpl_error(mpl, "keyword then missing where expected"); get_token(mpl /* then */); /* parse that follows 'then' and check its type */ y = expression_9(mpl); if (!(y->type == A_NUMERIC || y->type == A_SYMBOLIC || y->type == A_ELEMSET || y->type == A_FORMULA)) mpl_error(mpl, "expression following then has invalid type"); /* if the expression that follows the keyword 'then' is elemental set, the keyword 'else' cannot be omitted; otherwise else-part is optional */ if (mpl->token != T_ELSE) { if (y->type == A_ELEMSET) mpl_error(mpl, "keyword else missing where expected"); z = NULL; goto skip; } get_token(mpl /* else */); /* parse that follow 'else' and check its type */ z = expression_9(mpl); if (!(z->type == A_NUMERIC || z->type == A_SYMBOLIC || z->type == A_ELEMSET || z->type == A_FORMULA)) mpl_error(mpl, "expression following else has invalid type"); /* convert to identical types, if necessary */ if (y->type == A_FORMULA || z->type == A_FORMULA) { if (y->type == A_SYMBOLIC) y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); if (y->type == A_NUMERIC) y = make_unary(mpl, O_CVTLFM, y, A_FORMULA, 0); if (z->type == A_SYMBOLIC) z = make_unary(mpl, O_CVTNUM, z, A_NUMERIC, 0); if (z->type == A_NUMERIC) z = make_unary(mpl, O_CVTLFM, z, A_FORMULA, 0); } if (y->type == A_SYMBOLIC || z->type == A_SYMBOLIC) { if (y->type == A_NUMERIC) y = make_unary(mpl, O_CVTSYM, y, A_SYMBOLIC, 0); if (z->type == A_NUMERIC) z = make_unary(mpl, O_CVTSYM, z, A_SYMBOLIC, 0); } /* now both expressions must have identical types */ if (y->type != z->type) mpl_error(mpl, "expressions following then and else have incompati" "ble types"); /* and identical dimensions */ if (y->dim != z->dim) mpl_error(mpl, "expressions following then and else have different" " dimensions %d and %d, respectively", y->dim, z->dim); skip: /* generate pseudo-code to perform branching */ code = make_ternary(mpl, O_FORK, x, y, z, y->type, y->dim); return code; } /*---------------------------------------------------------------------- -- primary_expression - parse primary expression. -- -- This routine parses primary expression using the syntax: -- -- ::= -- ::= Infinity -- ::= -- ::= -- ::= -- ::= [ ] -- ::= -- ::= [ ] -- ::= -- ::= [ ] -- ::= ( ) -- ::= ( ) -- ::= -- ::= { } -- ::= -- ::= -- -- For complete list of syntactic rules for see -- comments to the corresponding parsing routines. */ CODE *primary_expression(MPL *mpl) { CODE *code; if (mpl->token == T_NUMBER) { /* parse numeric literal */ code = numeric_literal(mpl); } #if 1 /* 21/VII-2006 */ else if (mpl->token == T_INFINITY) { /* parse "infinity" */ OPERANDS arg; arg.num = DBL_MAX; code = make_code(mpl, O_NUMBER, &arg, A_NUMERIC, 0); get_token(mpl /* Infinity */); } #endif else if (mpl->token == T_STRING) { /* parse string literal */ code = string_literal(mpl); } else if (mpl->token == T_NAME) { int next_token; get_token(mpl /* */); next_token = mpl->token; unget_token(mpl); /* check a token that follows */ switch (next_token) { case T_LBRACKET: /* parse reference to subscripted object */ code = object_reference(mpl); break; case T_LEFT: /* parse reference to built-in function */ code = function_reference(mpl); break; case T_LBRACE: /* parse iterated expression */ code = iterated_expression(mpl); break; default: /* parse reference to unsubscripted object */ code = object_reference(mpl); break; } } else if (mpl->token == T_LEFT) { /* parse parenthesized expression */ code = expression_list(mpl); } else if (mpl->token == T_LBRACE) { /* parse set expression */ code = set_expression(mpl); } else if (mpl->token == T_IF) { /* parse conditional expression */ code = branched_expression(mpl); } else if (is_reserved(mpl)) { /* other reserved keywords cannot be used here */ mpl_error(mpl, "invalid use of reserved keyword %s", mpl->image); } else mpl_error(mpl, "syntax error in expression"); return code; } /*---------------------------------------------------------------------- -- error_preceding - raise error if preceding operand has wrong type. -- -- This routine is called to raise error if operand that precedes some -- infix operator has invalid type. */ void error_preceding(MPL *mpl, char *opstr) { mpl_error(mpl, "operand preceding %s has invalid type", opstr); /* no return */ } /*---------------------------------------------------------------------- -- error_following - raise error if following operand has wrong type. -- -- This routine is called to raise error if operand that follows some -- infix operator has invalid type. */ void error_following(MPL *mpl, char *opstr) { mpl_error(mpl, "operand following %s has invalid type", opstr); /* no return */ } /*---------------------------------------------------------------------- -- error_dimension - raise error if operands have different dimension. -- -- This routine is called to raise error if two operands of some infix -- operator have different dimension. */ void error_dimension(MPL *mpl, char *opstr, int dim1, int dim2) { mpl_error(mpl, "operands preceding and following %s have different di" "mensions %d and %d, respectively", opstr, dim1, dim2); /* no return */ } /*---------------------------------------------------------------------- -- expression_0 - parse expression of level 0. -- -- This routine parses expression of level 0 using the syntax: -- -- ::= */ CODE *expression_0(MPL *mpl) { CODE *code; code = primary_expression(mpl); return code; } /*---------------------------------------------------------------------- -- expression_1 - parse expression of level 1. -- -- This routine parses expression of level 1 using the syntax: -- -- ::= -- ::= -- ::= -- ::= ^ | ** */ CODE *expression_1(MPL *mpl) { CODE *x, *y; char opstr[8]; x = expression_0(mpl); if (mpl->token == T_POWER) { strcpy(opstr, mpl->image); xassert(strlen(opstr) < sizeof(opstr)); if (x->type == A_SYMBOLIC) x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); if (x->type != A_NUMERIC) error_preceding(mpl, opstr); get_token(mpl /* ^ | ** */); if (mpl->token == T_PLUS || mpl->token == T_MINUS) y = expression_2(mpl); else y = expression_1(mpl); if (y->type == A_SYMBOLIC) y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); if (y->type != A_NUMERIC) error_following(mpl, opstr); x = make_binary(mpl, O_POWER, x, y, A_NUMERIC, 0); } return x; } /*---------------------------------------------------------------------- -- expression_2 - parse expression of level 2. -- -- This routine parses expression of level 2 using the syntax: -- -- ::= -- ::= + -- ::= - */ CODE *expression_2(MPL *mpl) { CODE *x; if (mpl->token == T_PLUS) { get_token(mpl /* + */); x = expression_1(mpl); if (x->type == A_SYMBOLIC) x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); if (!(x->type == A_NUMERIC || x->type == A_FORMULA)) error_following(mpl, "+"); x = make_unary(mpl, O_PLUS, x, x->type, 0); } else if (mpl->token == T_MINUS) { get_token(mpl /* - */); x = expression_1(mpl); if (x->type == A_SYMBOLIC) x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); if (!(x->type == A_NUMERIC || x->type == A_FORMULA)) error_following(mpl, "-"); x = make_unary(mpl, O_MINUS, x, x->type, 0); } else x = expression_1(mpl); return x; } /*---------------------------------------------------------------------- -- expression_3 - parse expression of level 3. -- -- This routine parses expression of level 3 using the syntax: -- -- ::= -- ::= * -- ::= / -- ::= div -- ::= mod */ CODE *expression_3(MPL *mpl) { CODE *x, *y; x = expression_2(mpl); for (;;) { if (mpl->token == T_ASTERISK) { if (x->type == A_SYMBOLIC) x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); if (!(x->type == A_NUMERIC || x->type == A_FORMULA)) error_preceding(mpl, "*"); get_token(mpl /* * */); y = expression_2(mpl); if (y->type == A_SYMBOLIC) y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); if (!(y->type == A_NUMERIC || y->type == A_FORMULA)) error_following(mpl, "*"); if (x->type == A_FORMULA && y->type == A_FORMULA) mpl_error(mpl, "multiplication of linear forms not allowed"); if (x->type == A_NUMERIC && y->type == A_NUMERIC) x = make_binary(mpl, O_MUL, x, y, A_NUMERIC, 0); else x = make_binary(mpl, O_MUL, x, y, A_FORMULA, 0); } else if (mpl->token == T_SLASH) { if (x->type == A_SYMBOLIC) x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); if (!(x->type == A_NUMERIC || x->type == A_FORMULA)) error_preceding(mpl, "/"); get_token(mpl /* / */); y = expression_2(mpl); if (y->type == A_SYMBOLIC) y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); if (y->type != A_NUMERIC) error_following(mpl, "/"); if (x->type == A_NUMERIC) x = make_binary(mpl, O_DIV, x, y, A_NUMERIC, 0); else x = make_binary(mpl, O_DIV, x, y, A_FORMULA, 0); } else if (mpl->token == T_DIV) { if (x->type == A_SYMBOLIC) x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); if (x->type != A_NUMERIC) error_preceding(mpl, "div"); get_token(mpl /* div */); y = expression_2(mpl); if (y->type == A_SYMBOLIC) y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); if (y->type != A_NUMERIC) error_following(mpl, "div"); x = make_binary(mpl, O_IDIV, x, y, A_NUMERIC, 0); } else if (mpl->token == T_MOD) { if (x->type == A_SYMBOLIC) x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); if (x->type != A_NUMERIC) error_preceding(mpl, "mod"); get_token(mpl /* mod */); y = expression_2(mpl); if (y->type == A_SYMBOLIC) y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); if (y->type != A_NUMERIC) error_following(mpl, "mod"); x = make_binary(mpl, O_MOD, x, y, A_NUMERIC, 0); } else break; } return x; } /*---------------------------------------------------------------------- -- expression_4 - parse expression of level 4. -- -- This routine parses expression of level 4 using the syntax: -- -- ::= -- ::= + -- ::= - -- ::= less */ CODE *expression_4(MPL *mpl) { CODE *x, *y; x = expression_3(mpl); for (;;) { if (mpl->token == T_PLUS) { if (x->type == A_SYMBOLIC) x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); if (!(x->type == A_NUMERIC || x->type == A_FORMULA)) error_preceding(mpl, "+"); get_token(mpl /* + */); y = expression_3(mpl); if (y->type == A_SYMBOLIC) y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); if (!(y->type == A_NUMERIC || y->type == A_FORMULA)) error_following(mpl, "+"); if (x->type == A_NUMERIC && y->type == A_FORMULA) x = make_unary(mpl, O_CVTLFM, x, A_FORMULA, 0); if (x->type == A_FORMULA && y->type == A_NUMERIC) y = make_unary(mpl, O_CVTLFM, y, A_FORMULA, 0); x = make_binary(mpl, O_ADD, x, y, x->type, 0); } else if (mpl->token == T_MINUS) { if (x->type == A_SYMBOLIC) x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); if (!(x->type == A_NUMERIC || x->type == A_FORMULA)) error_preceding(mpl, "-"); get_token(mpl /* - */); y = expression_3(mpl); if (y->type == A_SYMBOLIC) y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); if (!(y->type == A_NUMERIC || y->type == A_FORMULA)) error_following(mpl, "-"); if (x->type == A_NUMERIC && y->type == A_FORMULA) x = make_unary(mpl, O_CVTLFM, x, A_FORMULA, 0); if (x->type == A_FORMULA && y->type == A_NUMERIC) y = make_unary(mpl, O_CVTLFM, y, A_FORMULA, 0); x = make_binary(mpl, O_SUB, x, y, x->type, 0); } else if (mpl->token == T_LESS) { if (x->type == A_SYMBOLIC) x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); if (x->type != A_NUMERIC) error_preceding(mpl, "less"); get_token(mpl /* less */); y = expression_3(mpl); if (y->type == A_SYMBOLIC) y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); if (y->type != A_NUMERIC) error_following(mpl, "less"); x = make_binary(mpl, O_LESS, x, y, A_NUMERIC, 0); } else break; } return x; } /*---------------------------------------------------------------------- -- expression_5 - parse expression of level 5. -- -- This routine parses expression of level 5 using the syntax: -- -- ::= -- ::= & */ CODE *expression_5(MPL *mpl) { CODE *x, *y; x = expression_4(mpl); for (;;) { if (mpl->token == T_CONCAT) { if (x->type == A_NUMERIC) x = make_unary(mpl, O_CVTSYM, x, A_SYMBOLIC, 0); if (x->type != A_SYMBOLIC) error_preceding(mpl, "&"); get_token(mpl /* & */); y = expression_4(mpl); if (y->type == A_NUMERIC) y = make_unary(mpl, O_CVTSYM, y, A_SYMBOLIC, 0); if (y->type != A_SYMBOLIC) error_following(mpl, "&"); x = make_binary(mpl, O_CONCAT, x, y, A_SYMBOLIC, 0); } else break; } return x; } /*---------------------------------------------------------------------- -- expression_6 - parse expression of level 6. -- -- This routine parses expression of level 6 using the syntax: -- -- ::= -- ::= .. -- ::= .. by -- */ CODE *expression_6(MPL *mpl) { CODE *x, *y, *z; x = expression_5(mpl); if (mpl->token == T_DOTS) { if (x->type == A_SYMBOLIC) x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); if (x->type != A_NUMERIC) error_preceding(mpl, ".."); get_token(mpl /* .. */); y = expression_5(mpl); if (y->type == A_SYMBOLIC) y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); if (y->type != A_NUMERIC) error_following(mpl, ".."); if (mpl->token == T_BY) { get_token(mpl /* by */); z = expression_5(mpl); if (z->type == A_SYMBOLIC) z = make_unary(mpl, O_CVTNUM, z, A_NUMERIC, 0); if (z->type != A_NUMERIC) error_following(mpl, "by"); } else z = NULL; x = make_ternary(mpl, O_DOTS, x, y, z, A_ELEMSET, 1); } return x; } /*---------------------------------------------------------------------- -- expression_7 - parse expression of level 7. -- -- This routine parses expression of level 7 using the syntax: -- -- ::= -- ::= cross */ CODE *expression_7(MPL *mpl) { CODE *x, *y; x = expression_6(mpl); for (;;) { if (mpl->token == T_CROSS) { if (x->type != A_ELEMSET) error_preceding(mpl, "cross"); get_token(mpl /* cross */); y = expression_6(mpl); if (y->type != A_ELEMSET) error_following(mpl, "cross"); x = make_binary(mpl, O_CROSS, x, y, A_ELEMSET, x->dim + y->dim); } else break; } return x; } /*---------------------------------------------------------------------- -- expression_8 - parse expression of level 8. -- -- This routine parses expression of level 8 using the syntax: -- -- ::= -- ::= inter */ CODE *expression_8(MPL *mpl) { CODE *x, *y; x = expression_7(mpl); for (;;) { if (mpl->token == T_INTER) { if (x->type != A_ELEMSET) error_preceding(mpl, "inter"); get_token(mpl /* inter */); y = expression_7(mpl); if (y->type != A_ELEMSET) error_following(mpl, "inter"); if (x->dim != y->dim) error_dimension(mpl, "inter", x->dim, y->dim); x = make_binary(mpl, O_INTER, x, y, A_ELEMSET, x->dim); } else break; } return x; } /*---------------------------------------------------------------------- -- expression_9 - parse expression of level 9. -- -- This routine parses expression of level 9 using the syntax: -- -- ::= -- ::= union -- ::= diff -- ::= symdiff */ CODE *expression_9(MPL *mpl) { CODE *x, *y; x = expression_8(mpl); for (;;) { if (mpl->token == T_UNION) { if (x->type != A_ELEMSET) error_preceding(mpl, "union"); get_token(mpl /* union */); y = expression_8(mpl); if (y->type != A_ELEMSET) error_following(mpl, "union"); if (x->dim != y->dim) error_dimension(mpl, "union", x->dim, y->dim); x = make_binary(mpl, O_UNION, x, y, A_ELEMSET, x->dim); } else if (mpl->token == T_DIFF) { if (x->type != A_ELEMSET) error_preceding(mpl, "diff"); get_token(mpl /* diff */); y = expression_8(mpl); if (y->type != A_ELEMSET) error_following(mpl, "diff"); if (x->dim != y->dim) error_dimension(mpl, "diff", x->dim, y->dim); x = make_binary(mpl, O_DIFF, x, y, A_ELEMSET, x->dim); } else if (mpl->token == T_SYMDIFF) { if (x->type != A_ELEMSET) error_preceding(mpl, "symdiff"); get_token(mpl /* symdiff */); y = expression_8(mpl); if (y->type != A_ELEMSET) error_following(mpl, "symdiff"); if (x->dim != y->dim) error_dimension(mpl, "symdiff", x->dim, y->dim); x = make_binary(mpl, O_SYMDIFF, x, y, A_ELEMSET, x->dim); } else break; } return x; } /*---------------------------------------------------------------------- -- expression_10 - parse expression of level 10. -- -- This routine parses expression of level 10 using the syntax: -- -- ::= -- ::= -- ::= < | <= | = | == | >= | > | <> | != | in | not in | ! in | -- within | not within | ! within */ CODE *expression_10(MPL *mpl) { CODE *x, *y; int op = -1; char opstr[16]; x = expression_9(mpl); strcpy(opstr, ""); switch (mpl->token) { case T_LT: op = O_LT; break; case T_LE: op = O_LE; break; case T_EQ: op = O_EQ; break; case T_GE: op = O_GE; break; case T_GT: op = O_GT; break; case T_NE: op = O_NE; break; case T_IN: op = O_IN; break; case T_WITHIN: op = O_WITHIN; break; case T_NOT: strcpy(opstr, mpl->image); get_token(mpl /* not | ! */); if (mpl->token == T_IN) op = O_NOTIN; else if (mpl->token == T_WITHIN) op = O_NOTWITHIN; else mpl_error(mpl, "invalid use of %s", opstr); strcat(opstr, " "); break; default: goto done; } strcat(opstr, mpl->image); xassert(strlen(opstr) < sizeof(opstr)); switch (op) { case O_EQ: case O_NE: #if 1 /* 02/VIII-2008 */ case O_LT: case O_LE: case O_GT: case O_GE: #endif if (!(x->type == A_NUMERIC || x->type == A_SYMBOLIC)) error_preceding(mpl, opstr); get_token(mpl /* */); y = expression_9(mpl); if (!(y->type == A_NUMERIC || y->type == A_SYMBOLIC)) error_following(mpl, opstr); if (x->type == A_NUMERIC && y->type == A_SYMBOLIC) x = make_unary(mpl, O_CVTSYM, x, A_SYMBOLIC, 0); if (x->type == A_SYMBOLIC && y->type == A_NUMERIC) y = make_unary(mpl, O_CVTSYM, y, A_SYMBOLIC, 0); x = make_binary(mpl, op, x, y, A_LOGICAL, 0); break; #if 0 /* 02/VIII-2008 */ case O_LT: case O_LE: case O_GT: case O_GE: if (x->type == A_SYMBOLIC) x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); if (x->type != A_NUMERIC) error_preceding(mpl, opstr); get_token(mpl /* */); y = expression_9(mpl); if (y->type == A_SYMBOLIC) y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); if (y->type != A_NUMERIC) error_following(mpl, opstr); x = make_binary(mpl, op, x, y, A_LOGICAL, 0); break; #endif case O_IN: case O_NOTIN: if (x->type == A_NUMERIC) x = make_unary(mpl, O_CVTSYM, x, A_SYMBOLIC, 0); if (x->type == A_SYMBOLIC) x = make_unary(mpl, O_CVTTUP, x, A_TUPLE, 1); if (x->type != A_TUPLE) error_preceding(mpl, opstr); get_token(mpl /* */); y = expression_9(mpl); if (y->type != A_ELEMSET) error_following(mpl, opstr); if (x->dim != y->dim) error_dimension(mpl, opstr, x->dim, y->dim); x = make_binary(mpl, op, x, y, A_LOGICAL, 0); break; case O_WITHIN: case O_NOTWITHIN: if (x->type != A_ELEMSET) error_preceding(mpl, opstr); get_token(mpl /* */); y = expression_9(mpl); if (y->type != A_ELEMSET) error_following(mpl, opstr); if (x->dim != y->dim) error_dimension(mpl, opstr, x->dim, y->dim); x = make_binary(mpl, op, x, y, A_LOGICAL, 0); break; default: xassert(op != op); } done: return x; } /*---------------------------------------------------------------------- -- expression_11 - parse expression of level 11. -- -- This routine parses expression of level 11 using the syntax: -- -- ::= -- ::= not -- ::= ! */ CODE *expression_11(MPL *mpl) { CODE *x; char opstr[8]; if (mpl->token == T_NOT) { strcpy(opstr, mpl->image); xassert(strlen(opstr) < sizeof(opstr)); get_token(mpl /* not | ! */); x = expression_10(mpl); if (x->type == A_SYMBOLIC) x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); if (x->type == A_NUMERIC) x = make_unary(mpl, O_CVTLOG, x, A_LOGICAL, 0); if (x->type != A_LOGICAL) error_following(mpl, opstr); x = make_unary(mpl, O_NOT, x, A_LOGICAL, 0); } else x = expression_10(mpl); return x; } /*---------------------------------------------------------------------- -- expression_12 - parse expression of level 12. -- -- This routine parses expression of level 12 using the syntax: -- -- ::= -- ::= and -- ::= && */ CODE *expression_12(MPL *mpl) { CODE *x, *y; char opstr[8]; x = expression_11(mpl); for (;;) { if (mpl->token == T_AND) { strcpy(opstr, mpl->image); xassert(strlen(opstr) < sizeof(opstr)); if (x->type == A_SYMBOLIC) x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); if (x->type == A_NUMERIC) x = make_unary(mpl, O_CVTLOG, x, A_LOGICAL, 0); if (x->type != A_LOGICAL) error_preceding(mpl, opstr); get_token(mpl /* and | && */); y = expression_11(mpl); if (y->type == A_SYMBOLIC) y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); if (y->type == A_NUMERIC) y = make_unary(mpl, O_CVTLOG, y, A_LOGICAL, 0); if (y->type != A_LOGICAL) error_following(mpl, opstr); x = make_binary(mpl, O_AND, x, y, A_LOGICAL, 0); } else break; } return x; } /*---------------------------------------------------------------------- -- expression_13 - parse expression of level 13. -- -- This routine parses expression of level 13 using the syntax: -- -- ::= -- ::= or -- ::= || */ CODE *expression_13(MPL *mpl) { CODE *x, *y; char opstr[8]; x = expression_12(mpl); for (;;) { if (mpl->token == T_OR) { strcpy(opstr, mpl->image); xassert(strlen(opstr) < sizeof(opstr)); if (x->type == A_SYMBOLIC) x = make_unary(mpl, O_CVTNUM, x, A_NUMERIC, 0); if (x->type == A_NUMERIC) x = make_unary(mpl, O_CVTLOG, x, A_LOGICAL, 0); if (x->type != A_LOGICAL) error_preceding(mpl, opstr); get_token(mpl /* or | || */); y = expression_12(mpl); if (y->type == A_SYMBOLIC) y = make_unary(mpl, O_CVTNUM, y, A_NUMERIC, 0); if (y->type == A_NUMERIC) y = make_unary(mpl, O_CVTLOG, y, A_LOGICAL, 0); if (y->type != A_LOGICAL) error_following(mpl, opstr); x = make_binary(mpl, O_OR, x, y, A_LOGICAL, 0); } else break; } return x; } /*---------------------------------------------------------------------- -- set_statement - parse set statement. -- -- This routine parses set statement using the syntax: -- -- ::= set -- ; -- ::= -- ::= -- ::= -- ::= -- ::= -- ::= , dimen -- ::= , within -- ::= , := -- ::= , default -- -- Commae in are optional and may be omitted anywhere. */ SET *set_statement(MPL *mpl) { SET *set; int dimen_used = 0; xassert(is_keyword(mpl, "set")); get_token(mpl /* set */); /* symbolic name must follow the keyword 'set' */ if (mpl->token == T_NAME) ; else if (is_reserved(mpl)) mpl_error(mpl, "invalid use of reserved keyword %s", mpl->image); else mpl_error(mpl, "symbolic name missing where expected"); /* there must be no other object with the same name */ if (avl_find_node(mpl->tree, mpl->image) != NULL) mpl_error(mpl, "%s multiply declared", mpl->image); /* create model set */ set = alloc(SET); set->name = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); strcpy(set->name, mpl->image); set->alias = NULL; set->dim = 0; set->domain = NULL; set->dimen = 0; set->within = NULL; set->assign = NULL; set->option = NULL; set->gadget = NULL; set->data = 0; set->array = NULL; get_token(mpl /* */); /* parse optional alias */ if (mpl->token == T_STRING) { set->alias = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); strcpy(set->alias, mpl->image); get_token(mpl /* */); } /* parse optional indexing expression */ if (mpl->token == T_LBRACE) { set->domain = indexing_expression(mpl); set->dim = domain_arity(mpl, set->domain); } /* include the set name in the symbolic names table */ { AVLNODE *node; node = avl_insert_node(mpl->tree, set->name); avl_set_node_type(node, A_SET); avl_set_node_link(node, (void *)set); } /* parse the list of optional attributes */ for (;;) { if (mpl->token == T_COMMA) get_token(mpl /* , */); else if (mpl->token == T_SEMICOLON) break; if (is_keyword(mpl, "dimen")) { /* dimension of set members */ int dimen; get_token(mpl /* dimen */); if (!(mpl->token == T_NUMBER && 1.0 <= mpl->value && mpl->value <= 20.0 && floor(mpl->value) == mpl->value)) mpl_error(mpl, "dimension must be integer between 1 and 20"); dimen = (int)(mpl->value + 0.5); if (dimen_used) mpl_error(mpl, "at most one dimension attribute allowed"); if (set->dimen > 0) mpl_error(mpl, "dimension %d conflicts with dimension %d alr" "eady determined", dimen, set->dimen); set->dimen = dimen; dimen_used = 1; get_token(mpl /* */); } else if (mpl->token == T_WITHIN || mpl->token == T_IN) { /* restricting superset */ WITHIN *within, *temp; if (mpl->token == T_IN && !mpl->as_within) { warning(mpl, "keyword in understood as within"); mpl->as_within = 1; } get_token(mpl /* within */); /* create new restricting superset list entry and append it to the within-list */ within = alloc(WITHIN); within->code = NULL; within->next = NULL; if (set->within == NULL) set->within = within; else { for (temp = set->within; temp->next != NULL; temp = temp->next); temp->next = within; } /* parse an expression that follows 'within' */ within->code = expression_9(mpl); if (within->code->type != A_ELEMSET) mpl_error(mpl, "expression following within has invalid type" ); xassert(within->code->dim > 0); /* check/set dimension of set members */ if (set->dimen == 0) set->dimen = within->code->dim; if (set->dimen != within->code->dim) mpl_error(mpl, "set expression following within must have di" "mension %d rather than %d", set->dimen, within->code->dim); } else if (mpl->token == T_ASSIGN) { /* assignment expression */ if (!(set->assign == NULL && set->option == NULL && set->gadget == NULL)) err: mpl_error(mpl, "at most one := or default/data allowed"); get_token(mpl /* := */); /* parse an expression that follows ':=' */ set->assign = expression_9(mpl); if (set->assign->type != A_ELEMSET) mpl_error(mpl, "expression following := has invalid type"); xassert(set->assign->dim > 0); /* check/set dimension of set members */ if (set->dimen == 0) set->dimen = set->assign->dim; if (set->dimen != set->assign->dim) mpl_error(mpl, "set expression following := must have dimens" "ion %d rather than %d", set->dimen, set->assign->dim); } else if (is_keyword(mpl, "default")) { /* expression for default value */ if (!(set->assign == NULL && set->option == NULL)) goto err; get_token(mpl /* := */); /* parse an expression that follows 'default' */ set->option = expression_9(mpl); if (set->option->type != A_ELEMSET) mpl_error(mpl, "expression following default has invalid typ" "e"); xassert(set->option->dim > 0); /* check/set dimension of set members */ if (set->dimen == 0) set->dimen = set->option->dim; if (set->dimen != set->option->dim) mpl_error(mpl, "set expression following default must have d" "imension %d rather than %d", set->dimen, set->option->dim); } #if 1 /* 12/XII-2008 */ else if (is_keyword(mpl, "data")) { /* gadget to initialize the set by data from plain set */ GADGET *gadget; AVLNODE *node; int i, k, fff[20]; if (!(set->assign == NULL && set->gadget == NULL)) goto err; get_token(mpl /* data */); set->gadget = gadget = alloc(GADGET); /* set name must follow the keyword 'data' */ if (mpl->token == T_NAME) ; else if (is_reserved(mpl)) mpl_error(mpl, "invalid use of reserved keyword %s", mpl->image); else mpl_error(mpl, "set name missing where expected"); /* find the set in the symbolic name table */ node = avl_find_node(mpl->tree, mpl->image); if (node == NULL) mpl_error(mpl, "%s not defined", mpl->image); if (avl_get_node_type(node) != A_SET) err1: mpl_error(mpl, "%s not a plain set", mpl->image); gadget->set = avl_get_node_link(node); if (gadget->set->dim != 0) goto err1; if (gadget->set == set) mpl_error(mpl, "set cannot be initialized by itself"); /* check and set dimensions */ if (set->dim >= gadget->set->dimen) err2: mpl_error(mpl, "dimension of %s too small", mpl->image); if (set->dimen == 0) set->dimen = gadget->set->dimen - set->dim; if (set->dim + set->dimen > gadget->set->dimen) goto err2; else if (set->dim + set->dimen < gadget->set->dimen) mpl_error(mpl, "dimension of %s too big", mpl->image); get_token(mpl /* set name */); /* left parenthesis must follow the set name */ if (mpl->token == T_LEFT) get_token(mpl /* ( */); else mpl_error(mpl, "left parenthesis missing where expected"); /* parse permutation of component numbers */ for (k = 0; k < gadget->set->dimen; k++) fff[k] = 0; k = 0; for (;;) { if (mpl->token != T_NUMBER) mpl_error(mpl, "component number missing where expected"); if (str2int(mpl->image, &i) != 0) err3: mpl_error(mpl, "component number must be integer between " "1 and %d", gadget->set->dimen); if (!(1 <= i && i <= gadget->set->dimen)) goto err3; if (fff[i-1] != 0) mpl_error(mpl, "component %d multiply specified", i); gadget->ind[k++] = i, fff[i-1] = 1; xassert(k <= gadget->set->dimen); get_token(mpl /* number */); if (mpl->token == T_COMMA) get_token(mpl /* , */); else if (mpl->token == T_RIGHT) break; else mpl_error(mpl, "syntax error in data attribute"); } if (k < gadget->set->dimen) mpl_error(mpl, "there are must be %d components rather than " "%d", gadget->set->dimen, k); get_token(mpl /* ) */); } #endif else mpl_error(mpl, "syntax error in set statement"); } /* close the domain scope */ if (set->domain != NULL) close_scope(mpl, set->domain); /* if dimension of set members is still unknown, set it to 1 */ if (set->dimen == 0) set->dimen = 1; /* the set statement has been completely parsed */ xassert(mpl->token == T_SEMICOLON); get_token(mpl /* ; */); return set; } /*---------------------------------------------------------------------- -- parameter_statement - parse parameter statement. -- -- This routine parses parameter statement using the syntax: -- -- ::= param -- ; -- ::= -- ::= -- ::= -- ::= -- ::= -- ::= , integer -- ::= , binary -- ::= , symbolic -- ::= , -- ::= , in -- ::= , := -- ::= , default -- ::= < | <= | = | == | >= | > | <> | != -- -- Commae in are optional and may be omitted anywhere. */ PARAMETER *parameter_statement(MPL *mpl) { PARAMETER *par; int integer_used = 0, binary_used = 0, symbolic_used = 0; xassert(is_keyword(mpl, "param")); get_token(mpl /* param */); /* symbolic name must follow the keyword 'param' */ if (mpl->token == T_NAME) ; else if (is_reserved(mpl)) mpl_error(mpl, "invalid use of reserved keyword %s", mpl->image); else mpl_error(mpl, "symbolic name missing where expected"); /* there must be no other object with the same name */ if (avl_find_node(mpl->tree, mpl->image) != NULL) mpl_error(mpl, "%s multiply declared", mpl->image); /* create model parameter */ par = alloc(PARAMETER); par->name = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); strcpy(par->name, mpl->image); par->alias = NULL; par->dim = 0; par->domain = NULL; par->type = A_NUMERIC; par->cond = NULL; par->in = NULL; par->assign = NULL; par->option = NULL; par->data = 0; par->defval = NULL; par->array = NULL; get_token(mpl /* */); /* parse optional alias */ if (mpl->token == T_STRING) { par->alias = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); strcpy(par->alias, mpl->image); get_token(mpl /* */); } /* parse optional indexing expression */ if (mpl->token == T_LBRACE) { par->domain = indexing_expression(mpl); par->dim = domain_arity(mpl, par->domain); } /* include the parameter name in the symbolic names table */ { AVLNODE *node; node = avl_insert_node(mpl->tree, par->name); avl_set_node_type(node, A_PARAMETER); avl_set_node_link(node, (void *)par); } /* parse the list of optional attributes */ for (;;) { if (mpl->token == T_COMMA) get_token(mpl /* , */); else if (mpl->token == T_SEMICOLON) break; if (is_keyword(mpl, "integer")) { if (integer_used) mpl_error(mpl, "at most one integer allowed"); if (par->type == A_SYMBOLIC) mpl_error(mpl, "symbolic parameter cannot be integer"); if (par->type != A_BINARY) par->type = A_INTEGER; integer_used = 1; get_token(mpl /* integer */); } else if (is_keyword(mpl, "binary")) bin: { if (binary_used) mpl_error(mpl, "at most one binary allowed"); if (par->type == A_SYMBOLIC) mpl_error(mpl, "symbolic parameter cannot be binary"); par->type = A_BINARY; binary_used = 1; get_token(mpl /* binary */); } else if (is_keyword(mpl, "logical")) { if (!mpl->as_binary) { warning(mpl, "keyword logical understood as binary"); mpl->as_binary = 1; } goto bin; } else if (is_keyword(mpl, "symbolic")) { if (symbolic_used) mpl_error(mpl, "at most one symbolic allowed"); if (par->type != A_NUMERIC) mpl_error(mpl, "integer or binary parameter cannot be symbol" "ic"); /* the parameter may be referenced from expressions given in the same parameter declaration, so its type must be completed before parsing that expressions */ if (!(par->cond == NULL && par->in == NULL && par->assign == NULL && par->option == NULL)) mpl_error(mpl, "keyword symbolic must precede any other para" "meter attributes"); par->type = A_SYMBOLIC; symbolic_used = 1; get_token(mpl /* symbolic */); } else if (mpl->token == T_LT || mpl->token == T_LE || mpl->token == T_EQ || mpl->token == T_GE || mpl->token == T_GT || mpl->token == T_NE) { /* restricting condition */ CONDITION *cond, *temp; char opstr[8]; /* create new restricting condition list entry and append it to the conditions list */ cond = alloc(CONDITION); switch (mpl->token) { case T_LT: cond->rho = O_LT, strcpy(opstr, mpl->image); break; case T_LE: cond->rho = O_LE, strcpy(opstr, mpl->image); break; case T_EQ: cond->rho = O_EQ, strcpy(opstr, mpl->image); break; case T_GE: cond->rho = O_GE, strcpy(opstr, mpl->image); break; case T_GT: cond->rho = O_GT, strcpy(opstr, mpl->image); break; case T_NE: cond->rho = O_NE, strcpy(opstr, mpl->image); break; default: xassert(mpl->token != mpl->token); } xassert(strlen(opstr) < sizeof(opstr)); cond->code = NULL; cond->next = NULL; if (par->cond == NULL) par->cond = cond; else { for (temp = par->cond; temp->next != NULL; temp = temp->next); temp->next = cond; } #if 0 /* 13/VIII-2008 */ if (par->type == A_SYMBOLIC && !(cond->rho == O_EQ || cond->rho == O_NE)) mpl_error(mpl, "inequality restriction not allowed"); #endif get_token(mpl /* rho */); /* parse an expression that follows relational operator */ cond->code = expression_5(mpl); if (!(cond->code->type == A_NUMERIC || cond->code->type == A_SYMBOLIC)) mpl_error(mpl, "expression following %s has invalid type", opstr); xassert(cond->code->dim == 0); /* convert to the parameter type, if necessary */ if (par->type != A_SYMBOLIC && cond->code->type == A_SYMBOLIC) cond->code = make_unary(mpl, O_CVTNUM, cond->code, A_NUMERIC, 0); if (par->type == A_SYMBOLIC && cond->code->type != A_SYMBOLIC) cond->code = make_unary(mpl, O_CVTSYM, cond->code, A_SYMBOLIC, 0); } else if (mpl->token == T_IN || mpl->token == T_WITHIN) { /* restricting superset */ WITHIN *in, *temp; if (mpl->token == T_WITHIN && !mpl->as_in) { warning(mpl, "keyword within understood as in"); mpl->as_in = 1; } get_token(mpl /* in */); /* create new restricting superset list entry and append it to the in-list */ in = alloc(WITHIN); in->code = NULL; in->next = NULL; if (par->in == NULL) par->in = in; else { for (temp = par->in; temp->next != NULL; temp = temp->next); temp->next = in; } /* parse an expression that follows 'in' */ in->code = expression_9(mpl); if (in->code->type != A_ELEMSET) mpl_error(mpl, "expression following in has invalid type"); xassert(in->code->dim > 0); if (in->code->dim != 1) mpl_error(mpl, "set expression following in must have dimens" "ion 1 rather than %d", in->code->dim); } else if (mpl->token == T_ASSIGN) { /* assignment expression */ if (!(par->assign == NULL && par->option == NULL)) err: mpl_error(mpl, "at most one := or default allowed"); get_token(mpl /* := */); /* parse an expression that follows ':=' */ par->assign = expression_5(mpl); /* the expression must be of numeric/symbolic type */ if (!(par->assign->type == A_NUMERIC || par->assign->type == A_SYMBOLIC)) mpl_error(mpl, "expression following := has invalid type"); xassert(par->assign->dim == 0); /* convert to the parameter type, if necessary */ if (par->type != A_SYMBOLIC && par->assign->type == A_SYMBOLIC) par->assign = make_unary(mpl, O_CVTNUM, par->assign, A_NUMERIC, 0); if (par->type == A_SYMBOLIC && par->assign->type != A_SYMBOLIC) par->assign = make_unary(mpl, O_CVTSYM, par->assign, A_SYMBOLIC, 0); } else if (is_keyword(mpl, "default")) { /* expression for default value */ if (!(par->assign == NULL && par->option == NULL)) goto err; get_token(mpl /* default */); /* parse an expression that follows 'default' */ par->option = expression_5(mpl); if (!(par->option->type == A_NUMERIC || par->option->type == A_SYMBOLIC)) mpl_error(mpl, "expression following default has invalid typ" "e"); xassert(par->option->dim == 0); /* convert to the parameter type, if necessary */ if (par->type != A_SYMBOLIC && par->option->type == A_SYMBOLIC) par->option = make_unary(mpl, O_CVTNUM, par->option, A_NUMERIC, 0); if (par->type == A_SYMBOLIC && par->option->type != A_SYMBOLIC) par->option = make_unary(mpl, O_CVTSYM, par->option, A_SYMBOLIC, 0); } else mpl_error(mpl, "syntax error in parameter statement"); } /* close the domain scope */ if (par->domain != NULL) close_scope(mpl, par->domain); /* the parameter statement has been completely parsed */ xassert(mpl->token == T_SEMICOLON); get_token(mpl /* ; */); return par; } /*---------------------------------------------------------------------- -- variable_statement - parse variable statement. -- -- This routine parses variable statement using the syntax: -- -- ::= var -- ; -- ::= -- ::= -- ::= -- ::= -- ::= -- ::= , integer -- ::= , binary -- ::= , -- ::= >= | <= | = | == -- -- Commae in are optional and may be omitted anywhere. */ VARIABLE *variable_statement(MPL *mpl) { VARIABLE *var; int integer_used = 0, binary_used = 0; xassert(is_keyword(mpl, "var")); if (mpl->flag_s) mpl_error(mpl, "variable statement must precede solve statement"); get_token(mpl /* var */); /* symbolic name must follow the keyword 'var' */ if (mpl->token == T_NAME) ; else if (is_reserved(mpl)) mpl_error(mpl, "invalid use of reserved keyword %s", mpl->image); else mpl_error(mpl, "symbolic name missing where expected"); /* there must be no other object with the same name */ if (avl_find_node(mpl->tree, mpl->image) != NULL) mpl_error(mpl, "%s multiply declared", mpl->image); /* create model variable */ var = alloc(VARIABLE); var->name = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); strcpy(var->name, mpl->image); var->alias = NULL; var->dim = 0; var->domain = NULL; var->type = A_NUMERIC; var->lbnd = NULL; var->ubnd = NULL; var->array = NULL; get_token(mpl /* */); /* parse optional alias */ if (mpl->token == T_STRING) { var->alias = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); strcpy(var->alias, mpl->image); get_token(mpl /* */); } /* parse optional indexing expression */ if (mpl->token == T_LBRACE) { var->domain = indexing_expression(mpl); var->dim = domain_arity(mpl, var->domain); } /* include the variable name in the symbolic names table */ { AVLNODE *node; node = avl_insert_node(mpl->tree, var->name); avl_set_node_type(node, A_VARIABLE); avl_set_node_link(node, (void *)var); } /* parse the list of optional attributes */ for (;;) { if (mpl->token == T_COMMA) get_token(mpl /* , */); else if (mpl->token == T_SEMICOLON) break; if (is_keyword(mpl, "integer")) { if (integer_used) mpl_error(mpl, "at most one integer allowed"); if (var->type != A_BINARY) var->type = A_INTEGER; integer_used = 1; get_token(mpl /* integer */); } else if (is_keyword(mpl, "binary")) bin: { if (binary_used) mpl_error(mpl, "at most one binary allowed"); var->type = A_BINARY; binary_used = 1; get_token(mpl /* binary */); } else if (is_keyword(mpl, "logical")) { if (!mpl->as_binary) { warning(mpl, "keyword logical understood as binary"); mpl->as_binary = 1; } goto bin; } else if (is_keyword(mpl, "symbolic")) mpl_error(mpl, "variable cannot be symbolic"); else if (mpl->token == T_GE) { /* lower bound */ if (var->lbnd != NULL) { if (var->lbnd == var->ubnd) mpl_error(mpl, "both fixed value and lower bound not allo" "wed"); else mpl_error(mpl, "at most one lower bound allowed"); } get_token(mpl /* >= */); /* parse an expression that specifies the lower bound */ var->lbnd = expression_5(mpl); if (var->lbnd->type == A_SYMBOLIC) var->lbnd = make_unary(mpl, O_CVTNUM, var->lbnd, A_NUMERIC, 0); if (var->lbnd->type != A_NUMERIC) mpl_error(mpl, "expression following >= has invalid type"); xassert(var->lbnd->dim == 0); } else if (mpl->token == T_LE) { /* upper bound */ if (var->ubnd != NULL) { if (var->ubnd == var->lbnd) mpl_error(mpl, "both fixed value and upper bound not allo" "wed"); else mpl_error(mpl, "at most one upper bound allowed"); } get_token(mpl /* <= */); /* parse an expression that specifies the upper bound */ var->ubnd = expression_5(mpl); if (var->ubnd->type == A_SYMBOLIC) var->ubnd = make_unary(mpl, O_CVTNUM, var->ubnd, A_NUMERIC, 0); if (var->ubnd->type != A_NUMERIC) mpl_error(mpl, "expression following <= has invalid type"); xassert(var->ubnd->dim == 0); } else if (mpl->token == T_EQ) { /* fixed value */ char opstr[8]; if (!(var->lbnd == NULL && var->ubnd == NULL)) { if (var->lbnd == var->ubnd) mpl_error(mpl, "at most one fixed value allowed"); else if (var->lbnd != NULL) mpl_error(mpl, "both lower bound and fixed value not allo" "wed"); else mpl_error(mpl, "both upper bound and fixed value not allo" "wed"); } strcpy(opstr, mpl->image); xassert(strlen(opstr) < sizeof(opstr)); get_token(mpl /* = | == */); /* parse an expression that specifies the fixed value */ var->lbnd = expression_5(mpl); if (var->lbnd->type == A_SYMBOLIC) var->lbnd = make_unary(mpl, O_CVTNUM, var->lbnd, A_NUMERIC, 0); if (var->lbnd->type != A_NUMERIC) mpl_error(mpl, "expression following %s has invalid type", opstr); xassert(var->lbnd->dim == 0); /* indicate that the variable is fixed, not bounded */ var->ubnd = var->lbnd; } else if (mpl->token == T_LT || mpl->token == T_GT || mpl->token == T_NE) mpl_error(mpl, "strict bound not allowed"); else mpl_error(mpl, "syntax error in variable statement"); } /* close the domain scope */ if (var->domain != NULL) close_scope(mpl, var->domain); /* the variable statement has been completely parsed */ xassert(mpl->token == T_SEMICOLON); get_token(mpl /* ; */); return var; } /*---------------------------------------------------------------------- -- constraint_statement - parse constraint statement. -- -- This routine parses constraint statement using the syntax: -- -- ::= -- : ; -- ::= -- ::= subject to -- ::= subj to -- ::= s.t. -- ::= -- ::= -- ::= -- ::= -- ::= , >= -- ::= , <= -- ::= , = -- ::= , <= , <= -- ::= , >= , >= -- ::= -- -- Commae in are optional and may be omitted anywhere. */ CONSTRAINT *constraint_statement(MPL *mpl) { CONSTRAINT *con; CODE *first, *second, *third; int rho; char opstr[8]; if (mpl->flag_s) mpl_error(mpl, "constraint statement must precede solve statement") ; if (is_keyword(mpl, "subject")) { get_token(mpl /* subject */); if (!is_keyword(mpl, "to")) mpl_error(mpl, "keyword subject to incomplete"); get_token(mpl /* to */); } else if (is_keyword(mpl, "subj")) { get_token(mpl /* subj */); if (!is_keyword(mpl, "to")) mpl_error(mpl, "keyword subj to incomplete"); get_token(mpl /* to */); } else if (mpl->token == T_SPTP) get_token(mpl /* s.t. */); /* the current token must be symbolic name of constraint */ if (mpl->token == T_NAME) ; else if (is_reserved(mpl)) mpl_error(mpl, "invalid use of reserved keyword %s", mpl->image); else mpl_error(mpl, "symbolic name missing where expected"); /* there must be no other object with the same name */ if (avl_find_node(mpl->tree, mpl->image) != NULL) mpl_error(mpl, "%s multiply declared", mpl->image); /* create model constraint */ con = alloc(CONSTRAINT); con->name = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); strcpy(con->name, mpl->image); con->alias = NULL; con->dim = 0; con->domain = NULL; con->type = A_CONSTRAINT; con->code = NULL; con->lbnd = NULL; con->ubnd = NULL; con->array = NULL; get_token(mpl /* */); /* parse optional alias */ if (mpl->token == T_STRING) { con->alias = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); strcpy(con->alias, mpl->image); get_token(mpl /* */); } /* parse optional indexing expression */ if (mpl->token == T_LBRACE) { con->domain = indexing_expression(mpl); con->dim = domain_arity(mpl, con->domain); } /* include the constraint name in the symbolic names table */ { AVLNODE *node; node = avl_insert_node(mpl->tree, con->name); avl_set_node_type(node, A_CONSTRAINT); avl_set_node_link(node, (void *)con); } /* the colon must precede the first expression */ if (mpl->token != T_COLON) mpl_error(mpl, "colon missing where expected"); get_token(mpl /* : */); /* parse the first expression */ first = expression_5(mpl); if (first->type == A_SYMBOLIC) first = make_unary(mpl, O_CVTNUM, first, A_NUMERIC, 0); if (!(first->type == A_NUMERIC || first->type == A_FORMULA)) mpl_error(mpl, "expression following colon has invalid type"); xassert(first->dim == 0); /* relational operator must follow the first expression */ if (mpl->token == T_COMMA) get_token(mpl /* , */); switch (mpl->token) { case T_LE: case T_GE: case T_EQ: break; case T_LT: case T_GT: case T_NE: mpl_error(mpl, "strict inequality not allowed"); case T_SEMICOLON: mpl_error(mpl, "constraint must be equality or inequality"); default: goto err; } rho = mpl->token; strcpy(opstr, mpl->image); xassert(strlen(opstr) < sizeof(opstr)); get_token(mpl /* rho */); /* parse the second expression */ second = expression_5(mpl); if (second->type == A_SYMBOLIC) second = make_unary(mpl, O_CVTNUM, second, A_NUMERIC, 0); if (!(second->type == A_NUMERIC || second->type == A_FORMULA)) mpl_error(mpl, "expression following %s has invalid type", opstr); xassert(second->dim == 0); /* check a token that follow the second expression */ if (mpl->token == T_COMMA) { get_token(mpl /* , */); if (mpl->token == T_SEMICOLON) goto err; } if (mpl->token == T_LT || mpl->token == T_LE || mpl->token == T_EQ || mpl->token == T_GE || mpl->token == T_GT || mpl->token == T_NE) { /* it is another relational operator, therefore the constraint is double inequality */ if (rho == T_EQ || mpl->token != rho) mpl_error(mpl, "double inequality must be ... <= ... <= ... or " "... >= ... >= ..."); /* the first expression cannot be linear form */ if (first->type == A_FORMULA) mpl_error(mpl, "leftmost expression in double inequality cannot" " be linear form"); get_token(mpl /* rho */); /* parse the third expression */ third = expression_5(mpl); if (third->type == A_SYMBOLIC) third = make_unary(mpl, O_CVTNUM, second, A_NUMERIC, 0); if (!(third->type == A_NUMERIC || third->type == A_FORMULA)) mpl_error(mpl, "rightmost expression in double inequality const" "raint has invalid type"); xassert(third->dim == 0); /* the third expression also cannot be linear form */ if (third->type == A_FORMULA) mpl_error(mpl, "rightmost expression in double inequality canno" "t be linear form"); } else { /* the constraint is equality or single inequality */ third = NULL; } /* close the domain scope */ if (con->domain != NULL) close_scope(mpl, con->domain); /* convert all expressions to linear form, if necessary */ if (first->type != A_FORMULA) first = make_unary(mpl, O_CVTLFM, first, A_FORMULA, 0); if (second->type != A_FORMULA) second = make_unary(mpl, O_CVTLFM, second, A_FORMULA, 0); if (third != NULL) third = make_unary(mpl, O_CVTLFM, third, A_FORMULA, 0); /* arrange expressions in the constraint */ if (third == NULL) { /* the constraint is equality or single inequality */ switch (rho) { case T_LE: /* first <= second */ con->code = first; con->lbnd = NULL; con->ubnd = second; break; case T_GE: /* first >= second */ con->code = first; con->lbnd = second; con->ubnd = NULL; break; case T_EQ: /* first = second */ con->code = first; con->lbnd = second; con->ubnd = second; break; default: xassert(rho != rho); } } else { /* the constraint is double inequality */ switch (rho) { case T_LE: /* first <= second <= third */ con->code = second; con->lbnd = first; con->ubnd = third; break; case T_GE: /* first >= second >= third */ con->code = second; con->lbnd = third; con->ubnd = first; break; default: xassert(rho != rho); } } /* the constraint statement has been completely parsed */ if (mpl->token != T_SEMICOLON) err: mpl_error(mpl, "syntax error in constraint statement"); get_token(mpl /* ; */); return con; } /*---------------------------------------------------------------------- -- objective_statement - parse objective statement. -- -- This routine parses objective statement using the syntax: -- -- ::= : -- ; -- ::= minimize -- ::= maximize -- ::= -- ::= -- ::= -- ::= -- ::= */ CONSTRAINT *objective_statement(MPL *mpl) { CONSTRAINT *obj; int type; if (is_keyword(mpl, "minimize")) type = A_MINIMIZE; else if (is_keyword(mpl, "maximize")) type = A_MAXIMIZE; else xassert(mpl != mpl); if (mpl->flag_s) mpl_error(mpl, "objective statement must precede solve statement"); get_token(mpl /* minimize | maximize */); /* symbolic name must follow the verb 'minimize' or 'maximize' */ if (mpl->token == T_NAME) ; else if (is_reserved(mpl)) mpl_error(mpl, "invalid use of reserved keyword %s", mpl->image); else mpl_error(mpl, "symbolic name missing where expected"); /* there must be no other object with the same name */ if (avl_find_node(mpl->tree, mpl->image) != NULL) mpl_error(mpl, "%s multiply declared", mpl->image); /* create model objective */ obj = alloc(CONSTRAINT); obj->name = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); strcpy(obj->name, mpl->image); obj->alias = NULL; obj->dim = 0; obj->domain = NULL; obj->type = type; obj->code = NULL; obj->lbnd = NULL; obj->ubnd = NULL; obj->array = NULL; get_token(mpl /* */); /* parse optional alias */ if (mpl->token == T_STRING) { obj->alias = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); strcpy(obj->alias, mpl->image); get_token(mpl /* */); } /* parse optional indexing expression */ if (mpl->token == T_LBRACE) { obj->domain = indexing_expression(mpl); obj->dim = domain_arity(mpl, obj->domain); } /* include the constraint name in the symbolic names table */ { AVLNODE *node; node = avl_insert_node(mpl->tree, obj->name); avl_set_node_type(node, A_CONSTRAINT); avl_set_node_link(node, (void *)obj); } /* the colon must precede the objective expression */ if (mpl->token != T_COLON) mpl_error(mpl, "colon missing where expected"); get_token(mpl /* : */); /* parse the objective expression */ obj->code = expression_5(mpl); if (obj->code->type == A_SYMBOLIC) obj->code = make_unary(mpl, O_CVTNUM, obj->code, A_NUMERIC, 0); if (obj->code->type == A_NUMERIC) obj->code = make_unary(mpl, O_CVTLFM, obj->code, A_FORMULA, 0); if (obj->code->type != A_FORMULA) mpl_error(mpl, "expression following colon has invalid type"); xassert(obj->code->dim == 0); /* close the domain scope */ if (obj->domain != NULL) close_scope(mpl, obj->domain); /* the objective statement has been completely parsed */ if (mpl->token != T_SEMICOLON) mpl_error(mpl, "syntax error in objective statement"); get_token(mpl /* ; */); return obj; } #if 1 /* 11/II-2008 */ /*********************************************************************** * table_statement - parse table statement * * This routine parses table statement using the syntax: * * ::= *
::= * * ::= * table
IN : * [ ] , ; * ::= * ::= * ::= * ::= * ::= , * ::= * ::= <- * ::= * ::= , * ::= * ::= , * ::= * ::= ~ * * ::= * table
OUT : * ; * ::= * ::= * ::= , * ::= * ::= ~ */ TABLE *table_statement(MPL *mpl) { TABLE *tab; TABARG *last_arg, *arg; TABFLD *last_fld, *fld; TABIN *last_in, *in; TABOUT *last_out, *out; AVLNODE *node; int nflds; char name[MAX_LENGTH+1]; xassert(is_keyword(mpl, "table")); get_token(mpl /* solve */); /* symbolic name must follow the keyword table */ if (mpl->token == T_NAME) ; else if (is_reserved(mpl)) mpl_error(mpl, "invalid use of reserved keyword %s", mpl->image); else mpl_error(mpl, "symbolic name missing where expected"); /* there must be no other object with the same name */ if (avl_find_node(mpl->tree, mpl->image) != NULL) mpl_error(mpl, "%s multiply declared", mpl->image); /* create data table */ tab = alloc(TABLE); tab->name = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); strcpy(tab->name, mpl->image); get_token(mpl /* */); /* parse optional alias */ if (mpl->token == T_STRING) { tab->alias = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); strcpy(tab->alias, mpl->image); get_token(mpl /* */); } else tab->alias = NULL; /* parse optional indexing expression */ if (mpl->token == T_LBRACE) { /* this is output table */ tab->type = A_OUTPUT; tab->u.out.domain = indexing_expression(mpl); if (!is_keyword(mpl, "OUT")) mpl_error(mpl, "keyword OUT missing where expected"); get_token(mpl /* OUT */); } else { /* this is input table */ tab->type = A_INPUT; if (!is_keyword(mpl, "IN")) mpl_error(mpl, "keyword IN missing where expected"); get_token(mpl /* IN */); } /* parse argument list */ tab->arg = last_arg = NULL; for (;;) { /* create argument list entry */ arg = alloc(TABARG); /* parse argument expression */ if (mpl->token == T_COMMA || mpl->token == T_COLON || mpl->token == T_SEMICOLON) mpl_error(mpl, "argument expression missing where expected"); arg->code = expression_5(mpl); /* convert the result to symbolic type, if necessary */ if (arg->code->type == A_NUMERIC) arg->code = make_unary(mpl, O_CVTSYM, arg->code, A_SYMBOLIC, 0); /* check that now the result is of symbolic type */ if (arg->code->type != A_SYMBOLIC) mpl_error(mpl, "argument expression has invalid type"); /* add the entry to the end of the list */ arg->next = NULL; if (last_arg == NULL) tab->arg = arg; else last_arg->next = arg; last_arg = arg; /* argument expression has been parsed */ if (mpl->token == T_COMMA) get_token(mpl /* , */); else if (mpl->token == T_COLON || mpl->token == T_SEMICOLON) break; } xassert(tab->arg != NULL); /* argument list must end with colon */ if (mpl->token == T_COLON) get_token(mpl /* : */); else mpl_error(mpl, "colon missing where expected"); /* parse specific part of the table statement */ switch (tab->type) { case A_INPUT: goto input_table; case A_OUTPUT: goto output_table; default: xassert(tab != tab); } input_table: /* parse optional set name */ if (mpl->token == T_NAME) { node = avl_find_node(mpl->tree, mpl->image); if (node == NULL) mpl_error(mpl, "%s not defined", mpl->image); if (avl_get_node_type(node) != A_SET) mpl_error(mpl, "%s not a set", mpl->image); tab->u.in.set = (SET *)avl_get_node_link(node); if (tab->u.in.set->assign != NULL) mpl_error(mpl, "%s needs no data", mpl->image); if (tab->u.in.set->dim != 0) mpl_error(mpl, "%s must be a simple set", mpl->image); get_token(mpl /* */); if (mpl->token == T_INPUT) get_token(mpl /* <- */); else mpl_error(mpl, "delimiter <- missing where expected"); } else if (is_reserved(mpl)) mpl_error(mpl, "invalid use of reserved keyword %s", mpl->image); else tab->u.in.set = NULL; /* parse field list */ tab->u.in.fld = last_fld = NULL; nflds = 0; if (mpl->token == T_LBRACKET) get_token(mpl /* [ */); else mpl_error(mpl, "field list missing where expected"); for (;;) { /* create field list entry */ fld = alloc(TABFLD); /* parse field name */ if (mpl->token == T_NAME) ; else if (is_reserved(mpl)) mpl_error(mpl, "invalid use of reserved keyword %s", mpl->image); else mpl_error(mpl, "field name missing where expected"); fld->name = dmp_get_atomv(mpl->pool, strlen(mpl->image)+1); strcpy(fld->name, mpl->image); get_token(mpl /* */); /* add the entry to the end of the list */ fld->next = NULL; if (last_fld == NULL) tab->u.in.fld = fld; else last_fld->next = fld; last_fld = fld; nflds++; /* field name has been parsed */ if (mpl->token == T_COMMA) get_token(mpl /* , */); else if (mpl->token == T_RBRACKET) break; else mpl_error(mpl, "syntax error in field list"); } /* check that the set dimen is equal to the number of fields */ if (tab->u.in.set != NULL && tab->u.in.set->dimen != nflds) mpl_error(mpl, "there must be %d field%s rather than %d", tab->u.in.set->dimen, tab->u.in.set->dimen == 1 ? "" : "s", nflds); get_token(mpl /* ] */); /* parse optional input list */ tab->u.in.list = last_in = NULL; while (mpl->token == T_COMMA) { get_token(mpl /* , */); /* create input list entry */ in = alloc(TABIN); /* parse parameter name */ if (mpl->token == T_NAME) ; else if (is_reserved(mpl)) mpl_error(mpl, "invalid use of reserved keyword %s", mpl->image); else mpl_error(mpl, "parameter name missing where expected"); node = avl_find_node(mpl->tree, mpl->image); if (node == NULL) mpl_error(mpl, "%s not defined", mpl->image); if (avl_get_node_type(node) != A_PARAMETER) mpl_error(mpl, "%s not a parameter", mpl->image); in->par = (PARAMETER *)avl_get_node_link(node); if (in->par->dim != nflds) mpl_error(mpl, "%s must have %d subscript%s rather than %d", mpl->image, nflds, nflds == 1 ? "" : "s", in->par->dim); if (in->par->assign != NULL) mpl_error(mpl, "%s needs no data", mpl->image); get_token(mpl /* */); /* parse optional field name */ if (mpl->token == T_TILDE) { get_token(mpl /* ~ */); /* parse field name */ if (mpl->token == T_NAME) ; else if (is_reserved(mpl)) mpl_error(mpl, "invalid use of reserved keyword %s", mpl->image); else mpl_error(mpl, "field name missing where expected"); xassert(strlen(mpl->image) < sizeof(name)); strcpy(name, mpl->image); get_token(mpl /* */); } else { /* field name is the same as the parameter name */ xassert(strlen(in->par->name) < sizeof(name)); strcpy(name, in->par->name); } /* assign field name */ in->name = dmp_get_atomv(mpl->pool, strlen(name)+1); strcpy(in->name, name); /* add the entry to the end of the list */ in->next = NULL; if (last_in == NULL) tab->u.in.list = in; else last_in->next = in; last_in = in; } goto end_of_table; output_table: /* parse output list */ tab->u.out.list = last_out = NULL; for (;;) { /* create output list entry */ out = alloc(TABOUT); /* parse expression */ if (mpl->token == T_COMMA || mpl->token == T_SEMICOLON) mpl_error(mpl, "expression missing where expected"); if (mpl->token == T_NAME) { xassert(strlen(mpl->image) < sizeof(name)); strcpy(name, mpl->image); } else name[0] = '\0'; out->code = expression_5(mpl); /* parse optional field name */ if (mpl->token == T_TILDE) { get_token(mpl /* ~ */); /* parse field name */ if (mpl->token == T_NAME) ; else if (is_reserved(mpl)) mpl_error(mpl, "invalid use of reserved keyword %s", mpl->image); else mpl_error(mpl, "field name missing where expected"); xassert(strlen(mpl->image) < sizeof(name)); strcpy(name, mpl->image); get_token(mpl /* */); } /* assign field name */ if (name[0] == '\0') mpl_error(mpl, "field name required"); out->name = dmp_get_atomv(mpl->pool, strlen(name)+1); strcpy(out->name, name); /* add the entry to the end of the list */ out->next = NULL; if (last_out == NULL) tab->u.out.list = out; else last_out->next = out; last_out = out; /* output item has been parsed */ if (mpl->token == T_COMMA) get_token(mpl /* , */); else if (mpl->token == T_SEMICOLON) break; else mpl_error(mpl, "syntax error in output list"); } /* close the domain scope */ close_scope(mpl,tab->u.out.domain); end_of_table: /* the table statement must end with semicolon */ if (mpl->token != T_SEMICOLON) mpl_error(mpl, "syntax error in table statement"); get_token(mpl /* ; */); return tab; } #endif /*---------------------------------------------------------------------- -- solve_statement - parse solve statement. -- -- This routine parses solve statement using the syntax: -- -- ::= solve ; -- -- The solve statement can be used at most once. */ void *solve_statement(MPL *mpl) { xassert(is_keyword(mpl, "solve")); if (mpl->flag_s) mpl_error(mpl, "at most one solve statement allowed"); mpl->flag_s = 1; get_token(mpl /* solve */); /* semicolon must follow solve statement */ if (mpl->token != T_SEMICOLON) mpl_error(mpl, "syntax error in solve statement"); get_token(mpl /* ; */); return NULL; } /*---------------------------------------------------------------------- -- check_statement - parse check statement. -- -- This routine parses check statement using the syntax: -- -- ::= check : ; -- ::= -- ::= -- -- If is omitted, colon following it may also be omitted. */ CHECK *check_statement(MPL *mpl) { CHECK *chk; xassert(is_keyword(mpl, "check")); /* create check descriptor */ chk = alloc(CHECK); chk->domain = NULL; chk->code = NULL; get_token(mpl /* check */); /* parse optional indexing expression */ if (mpl->token == T_LBRACE) { chk->domain = indexing_expression(mpl); #if 0 if (mpl->token != T_COLON) mpl_error(mpl, "colon missing where expected"); #endif } /* skip optional colon */ if (mpl->token == T_COLON) get_token(mpl /* : */); /* parse logical expression */ chk->code = expression_13(mpl); if (chk->code->type != A_LOGICAL) mpl_error(mpl, "expression has invalid type"); xassert(chk->code->dim == 0); /* close the domain scope */ if (chk->domain != NULL) close_scope(mpl, chk->domain); /* the check statement has been completely parsed */ if (mpl->token != T_SEMICOLON) mpl_error(mpl, "syntax error in check statement"); get_token(mpl /* ; */); return chk; } #if 1 /* 15/V-2010 */ /*---------------------------------------------------------------------- -- display_statement - parse display statement. -- -- This routine parses display statement using the syntax: -- -- ::= display : ; -- ::= display ; -- ::= -- ::= -- ::= -- ::= , -- ::= -- ::= -- ::= [ ] -- ::= -- ::= [ ] -- ::= -- ::= [ ] -- ::= -- ::= [ ] -- ::= */ DISPLAY *display_statement(MPL *mpl) { DISPLAY *dpy; DISPLAY1 *entry, *last_entry; xassert(is_keyword(mpl, "display")); /* create display descriptor */ dpy = alloc(DISPLAY); dpy->domain = NULL; dpy->list = last_entry = NULL; get_token(mpl /* display */); /* parse optional indexing expression */ if (mpl->token == T_LBRACE) dpy->domain = indexing_expression(mpl); /* skip optional colon */ if (mpl->token == T_COLON) get_token(mpl /* : */); /* parse display list */ for (;;) { /* create new display entry */ entry = alloc(DISPLAY1); entry->type = 0; entry->next = NULL; /* and append it to the display list */ if (dpy->list == NULL) dpy->list = entry; else last_entry->next = entry; last_entry = entry; /* parse display entry */ if (mpl->token == T_NAME) { AVLNODE *node; int next_token; get_token(mpl /* */); next_token = mpl->token; unget_token(mpl); if (!(next_token == T_COMMA || next_token == T_SEMICOLON)) { /* symbolic name begins expression */ goto expr; } /* display entry is dummy index or model object */ node = avl_find_node(mpl->tree, mpl->image); if (node == NULL) mpl_error(mpl, "%s not defined", mpl->image); entry->type = avl_get_node_type(node); switch (avl_get_node_type(node)) { case A_INDEX: entry->u.slot = (DOMAIN_SLOT *)avl_get_node_link(node); break; case A_SET: entry->u.set = (SET *)avl_get_node_link(node); break; case A_PARAMETER: entry->u.par = (PARAMETER *)avl_get_node_link(node); break; case A_VARIABLE: entry->u.var = (VARIABLE *)avl_get_node_link(node); if (!mpl->flag_s) mpl_error(mpl, "invalid reference to variable %s above" " solve statement", entry->u.var->name); break; case A_CONSTRAINT: entry->u.con = (CONSTRAINT *)avl_get_node_link(node); if (!mpl->flag_s) mpl_error(mpl, "invalid reference to %s %s above solve" " statement", entry->u.con->type == A_CONSTRAINT ? "constraint" : "objective", entry->u.con->name); break; default: xassert(node != node); } get_token(mpl /* */); } else expr: { /* display entry is expression */ entry->type = A_EXPRESSION; entry->u.code = expression_13(mpl); } /* check a token that follows the entry parsed */ if (mpl->token == T_COMMA) get_token(mpl /* , */); else break; } /* close the domain scope */ if (dpy->domain != NULL) close_scope(mpl, dpy->domain); /* the display statement has been completely parsed */ if (mpl->token != T_SEMICOLON) mpl_error(mpl, "syntax error in display statement"); get_token(mpl /* ; */); return dpy; } #endif /*---------------------------------------------------------------------- -- printf_statement - parse printf statement. -- -- This routine parses print statement using the syntax: -- -- ::= ; -- ::= > ; -- ::= >> ; -- ::= printf : -- ::= printf -- ::= -- ::= -- ::= -- ::= -- ::= , -- ::= -- ::= */ PRINTF *printf_statement(MPL *mpl) { PRINTF *prt; PRINTF1 *entry, *last_entry; xassert(is_keyword(mpl, "printf")); /* create printf descriptor */ prt = alloc(PRINTF); prt->domain = NULL; prt->fmt = NULL; prt->list = last_entry = NULL; get_token(mpl /* printf */); /* parse optional indexing expression */ if (mpl->token == T_LBRACE) { prt->domain = indexing_expression(mpl); #if 0 if (mpl->token != T_COLON) mpl_error(mpl, "colon missing where expected"); #endif } /* skip optional colon */ if (mpl->token == T_COLON) get_token(mpl /* : */); /* parse expression for format string */ prt->fmt = expression_5(mpl); /* convert it to symbolic type, if necessary */ if (prt->fmt->type == A_NUMERIC) prt->fmt = make_unary(mpl, O_CVTSYM, prt->fmt, A_SYMBOLIC, 0); /* check that now the expression is of symbolic type */ if (prt->fmt->type != A_SYMBOLIC) mpl_error(mpl, "format expression has invalid type"); /* parse printf list */ while (mpl->token == T_COMMA) { get_token(mpl /* , */); /* create new printf entry */ entry = alloc(PRINTF1); entry->code = NULL; entry->next = NULL; /* and append it to the printf list */ if (prt->list == NULL) prt->list = entry; else last_entry->next = entry; last_entry = entry; /* parse printf entry */ entry->code = expression_9(mpl); if (!(entry->code->type == A_NUMERIC || entry->code->type == A_SYMBOLIC || entry->code->type == A_LOGICAL)) mpl_error(mpl, "only numeric, symbolic, or logical expression a" "llowed"); } /* close the domain scope */ if (prt->domain != NULL) close_scope(mpl, prt->domain); #if 1 /* 14/VII-2006 */ /* parse optional redirection */ prt->fname = NULL, prt->app = 0; if (mpl->token == T_GT || mpl->token == T_APPEND) { prt->app = (mpl->token == T_APPEND); get_token(mpl /* > or >> */); /* parse expression for file name string */ prt->fname = expression_5(mpl); /* convert it to symbolic type, if necessary */ if (prt->fname->type == A_NUMERIC) prt->fname = make_unary(mpl, O_CVTSYM, prt->fname, A_SYMBOLIC, 0); /* check that now the expression is of symbolic type */ if (prt->fname->type != A_SYMBOLIC) mpl_error(mpl, "file name expression has invalid type"); } #endif /* the printf statement has been completely parsed */ if (mpl->token != T_SEMICOLON) mpl_error(mpl, "syntax error in printf statement"); get_token(mpl /* ; */); return prt; } /*---------------------------------------------------------------------- -- for_statement - parse for statement. -- -- This routine parses for statement using the syntax: -- -- ::= for -- ::= for { } -- ::= -- ::= -- ::= -- ::= -- ::= -- ::= -- ::= */ FOR *for_statement(MPL *mpl) { FOR *fur; STATEMENT *stmt, *last_stmt; xassert(is_keyword(mpl, "for")); /* create for descriptor */ fur = alloc(FOR); fur->domain = NULL; fur->list = last_stmt = NULL; get_token(mpl /* for */); /* parse indexing expression */ if (mpl->token != T_LBRACE) mpl_error(mpl, "indexing expression missing where expected"); fur->domain = indexing_expression(mpl); /* skip optional colon */ if (mpl->token == T_COLON) get_token(mpl /* : */); /* parse for statement body */ if (mpl->token != T_LBRACE) { /* parse simple statement */ fur->list = simple_statement(mpl, 1); } else { /* parse compound statement */ get_token(mpl /* { */); while (mpl->token != T_RBRACE) { /* parse statement */ stmt = simple_statement(mpl, 1); /* and append it to the end of the statement list */ if (last_stmt == NULL) fur->list = stmt; else last_stmt->next = stmt; last_stmt = stmt; } get_token(mpl /* } */); } /* close the domain scope */ xassert(fur->domain != NULL); close_scope(mpl, fur->domain); /* the for statement has been completely parsed */ return fur; } /*---------------------------------------------------------------------- -- end_statement - parse end statement. -- -- This routine parses end statement using the syntax: -- -- ::= end ; */ void end_statement(MPL *mpl) { if (!mpl->flag_d && is_keyword(mpl, "end") || mpl->flag_d && is_literal(mpl, "end")) { get_token(mpl /* end */); if (mpl->token == T_SEMICOLON) get_token(mpl /* ; */); else warning(mpl, "no semicolon following end statement; missing" " semicolon inserted"); } else warning(mpl, "unexpected end of file; missing end statement in" "serted"); if (mpl->token != T_EOF) warning(mpl, "some text detected beyond end statement; text ig" "nored"); return; } /*---------------------------------------------------------------------- -- simple_statement - parse simple statement. -- -- This routine parses simple statement using the syntax: -- -- ::= -- ::= -- ::= -- ::= -- ::= -- ::= -- ::= -- ::= -- ::= -- ::= -- -- If the flag spec is set, some statements cannot be used. */ STATEMENT *simple_statement(MPL *mpl, int spec) { STATEMENT *stmt; stmt = alloc(STATEMENT); stmt->line = mpl->line; stmt->next = NULL; if (is_keyword(mpl, "set")) { if (spec) mpl_error(mpl, "set statement not allowed here"); stmt->type = A_SET; stmt->u.set = set_statement(mpl); } else if (is_keyword(mpl, "param")) { if (spec) mpl_error(mpl, "parameter statement not allowed here"); stmt->type = A_PARAMETER; stmt->u.par = parameter_statement(mpl); } else if (is_keyword(mpl, "var")) { if (spec) mpl_error(mpl, "variable statement not allowed here"); stmt->type = A_VARIABLE; stmt->u.var = variable_statement(mpl); } else if (is_keyword(mpl, "subject") || is_keyword(mpl, "subj") || mpl->token == T_SPTP) { if (spec) mpl_error(mpl, "constraint statement not allowed here"); stmt->type = A_CONSTRAINT; stmt->u.con = constraint_statement(mpl); } else if (is_keyword(mpl, "minimize") || is_keyword(mpl, "maximize")) { if (spec) mpl_error(mpl, "objective statement not allowed here"); stmt->type = A_CONSTRAINT; stmt->u.con = objective_statement(mpl); } #if 1 /* 11/II-2008 */ else if (is_keyword(mpl, "table")) { if (spec) mpl_error(mpl, "table statement not allowed here"); stmt->type = A_TABLE; stmt->u.tab = table_statement(mpl); } #endif else if (is_keyword(mpl, "solve")) { if (spec) mpl_error(mpl, "solve statement not allowed here"); stmt->type = A_SOLVE; stmt->u.slv = solve_statement(mpl); } else if (is_keyword(mpl, "check")) { stmt->type = A_CHECK; stmt->u.chk = check_statement(mpl); } else if (is_keyword(mpl, "display")) { stmt->type = A_DISPLAY; stmt->u.dpy = display_statement(mpl); } else if (is_keyword(mpl, "printf")) { stmt->type = A_PRINTF; stmt->u.prt = printf_statement(mpl); } else if (is_keyword(mpl, "for")) { stmt->type = A_FOR; stmt->u.fur = for_statement(mpl); } else if (mpl->token == T_NAME) { if (spec) mpl_error(mpl, "constraint statement not allowed here"); stmt->type = A_CONSTRAINT; stmt->u.con = constraint_statement(mpl); } else if (is_reserved(mpl)) mpl_error(mpl, "invalid use of reserved keyword %s", mpl->image); else mpl_error(mpl, "syntax error in model section"); return stmt; } /*---------------------------------------------------------------------- -- model_section - parse model section. -- -- This routine parses model section using the syntax: -- -- ::= -- ::= -- -- Parsing model section is terminated by either the keyword 'data', or -- the keyword 'end', or the end of file. */ void model_section(MPL *mpl) { STATEMENT *stmt, *last_stmt; xassert(mpl->model == NULL); last_stmt = NULL; while (!(mpl->token == T_EOF || is_keyword(mpl, "data") || is_keyword(mpl, "end"))) { /* parse statement */ stmt = simple_statement(mpl, 0); /* and append it to the end of the statement list */ if (last_stmt == NULL) mpl->model = stmt; else last_stmt->next = stmt; last_stmt = stmt; } return; } /* eof */ praat-6.0.04/external/glpk/glpmpl02.c000066400000000000000000001312421261542461700173030ustar00rootroot00000000000000/* glpmpl02.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #define _GLPSTD_STDIO #include "glpenv.h" #include "glpmpl.h" /**********************************************************************/ /* * * PROCESSING DATA SECTION * * */ /**********************************************************************/ /*---------------------------------------------------------------------- -- create_slice - create slice. -- -- This routine creates a slice, which initially has no components. */ SLICE *create_slice(MPL *mpl) { SLICE *slice; xassert(mpl == mpl); slice = NULL; return slice; } /*---------------------------------------------------------------------- -- expand_slice - append new component to slice. -- -- This routine expands slice appending to it either a given symbol or -- null component, which becomes the last component of the slice. */ SLICE *expand_slice ( MPL *mpl, SLICE *slice, /* destroyed */ SYMBOL *sym /* destroyed */ ) { SLICE *tail, *temp; /* create a new component */ tail = dmp_get_atom(mpl->tuples, sizeof(SLICE)); tail->sym = sym; tail->next = NULL; /* and append it to the component list */ if (slice == NULL) slice = tail; else { for (temp = slice; temp->next != NULL; temp = temp->next); temp->next = tail; } return slice; } /*---------------------------------------------------------------------- -- slice_dimen - determine dimension of slice. -- -- This routine returns dimension of slice, which is number of all its -- components including null ones. */ int slice_dimen ( MPL *mpl, SLICE *slice /* not changed */ ) { SLICE *temp; int dim; xassert(mpl == mpl); dim = 0; for (temp = slice; temp != NULL; temp = temp->next) dim++; return dim; } /*---------------------------------------------------------------------- -- slice_arity - determine arity of slice. -- -- This routine returns arity of slice, i.e. number of null components -- (indicated by asterisks) in the slice. */ int slice_arity ( MPL *mpl, SLICE *slice /* not changed */ ) { SLICE *temp; int arity; xassert(mpl == mpl); arity = 0; for (temp = slice; temp != NULL; temp = temp->next) if (temp->sym == NULL) arity++; return arity; } /*---------------------------------------------------------------------- -- fake_slice - create fake slice of all asterisks. -- -- This routine creates a fake slice of given dimension, which contains -- asterisks in all components. Zero dimension is allowed. */ SLICE *fake_slice(MPL *mpl, int dim) { SLICE *slice; slice = create_slice(mpl); while (dim-- > 0) slice = expand_slice(mpl, slice, NULL); return slice; } /*---------------------------------------------------------------------- -- delete_slice - delete slice. -- -- This routine deletes specified slice. */ void delete_slice ( MPL *mpl, SLICE *slice /* destroyed */ ) { SLICE *temp; while (slice != NULL) { temp = slice; slice = temp->next; if (temp->sym != NULL) delete_symbol(mpl, temp->sym); xassert(sizeof(SLICE) == sizeof(TUPLE)); dmp_free_atom(mpl->tuples, temp, sizeof(TUPLE)); } return; } /*---------------------------------------------------------------------- -- is_number - check if current token is number. -- -- If the current token is a number, this routine returns non-zero. -- Otherwise zero is returned. */ int is_number(MPL *mpl) { return mpl->token == T_NUMBER; } /*---------------------------------------------------------------------- -- is_symbol - check if current token is symbol. -- -- If the current token is suitable to be a symbol, the routine returns -- non-zero. Otherwise zero is returned. */ int is_symbol(MPL *mpl) { return mpl->token == T_NUMBER || mpl->token == T_SYMBOL || mpl->token == T_STRING; } /*---------------------------------------------------------------------- -- is_literal - check if current token is given symbolic literal. -- -- If the current token is given symbolic literal, this routine returns -- non-zero. Otherwise zero is returned. -- -- This routine is used on processing the data section in the same way -- as the routine is_keyword on processing the model section. */ int is_literal(MPL *mpl, char *literal) { return is_symbol(mpl) && strcmp(mpl->image, literal) == 0; } /*---------------------------------------------------------------------- -- read_number - read number. -- -- This routine reads the current token, which must be a number, and -- returns its numeric value. */ double read_number(MPL *mpl) { double num; xassert(is_number(mpl)); num = mpl->value; get_token(mpl /* */); return num; } /*---------------------------------------------------------------------- -- read_symbol - read symbol. -- -- This routine reads the current token, which must be a symbol, and -- returns its symbolic value. */ SYMBOL *read_symbol(MPL *mpl) { SYMBOL *sym; xassert(is_symbol(mpl)); if (is_number(mpl)) sym = create_symbol_num(mpl, mpl->value); else sym = create_symbol_str(mpl, create_string(mpl, mpl->image)); get_token(mpl /* */); return sym; } /*---------------------------------------------------------------------- -- read_slice - read slice. -- -- This routine reads slice using the syntax: -- -- ::= [ ] -- ::= ( ) -- ::= -- ::= , -- ::= -- ::= * -- -- The bracketed form of slice is used for members of multi-dimensional -- objects while the parenthesized form is used for elemental sets. */ SLICE *read_slice ( MPL *mpl, char *name, /* not changed */ int dim ) { SLICE *slice; int close; xassert(name != NULL); switch (mpl->token) { case T_LBRACKET: close = T_RBRACKET; break; case T_LEFT: xassert(dim > 0); close = T_RIGHT; break; default: xassert(mpl != mpl); } if (dim == 0) mpl_error(mpl, "%s cannot be subscripted", name); get_token(mpl /* ( | [ */); /* read slice components */ slice = create_slice(mpl); for (;;) { /* the current token must be a symbol or asterisk */ if (is_symbol(mpl)) slice = expand_slice(mpl, slice, read_symbol(mpl)); else if (mpl->token == T_ASTERISK) { slice = expand_slice(mpl, slice, NULL); get_token(mpl /* * */); } else mpl_error(mpl, "number, symbol, or asterisk missing where expec" "ted"); /* check a token that follows the symbol */ if (mpl->token == T_COMMA) get_token(mpl /* , */); else if (mpl->token == close) break; else mpl_error(mpl, "syntax error in slice"); } /* number of slice components must be the same as the appropriate dimension */ if (slice_dimen(mpl, slice) != dim) { switch (close) { case T_RBRACKET: mpl_error(mpl, "%s must have %d subscript%s, not %d", name, dim, dim == 1 ? "" : "s", slice_dimen(mpl, slice)); break; case T_RIGHT: mpl_error(mpl, "%s has dimension %d, not %d", name, dim, slice_dimen(mpl, slice)); break; default: xassert(close != close); } } get_token(mpl /* ) | ] */); return slice; } /*---------------------------------------------------------------------- -- select_set - select set to saturate it with elemental sets. -- -- This routine selects set to saturate it with elemental sets provided -- in the data section. */ SET *select_set ( MPL *mpl, char *name /* not changed */ ) { SET *set; AVLNODE *node; xassert(name != NULL); node = avl_find_node(mpl->tree, name); if (node == NULL || avl_get_node_type(node) != A_SET) mpl_error(mpl, "%s not a set", name); set = (SET *)avl_get_node_link(node); if (set->assign != NULL || set->gadget != NULL) mpl_error(mpl, "%s needs no data", name); set->data = 1; return set; } /*---------------------------------------------------------------------- -- simple_format - read set data block in simple format. -- -- This routine reads set data block using the syntax: -- -- ::= , , ... , -- -- where are used to construct a complete n-tuple, which is -- included in elemental set assigned to the set member. Commae between -- symbols are optional and may be omitted anywhere. -- -- Number of components in the slice must be the same as dimension of -- n-tuples in elemental sets assigned to the set members. To construct -- complete n-tuple the routine replaces null positions in the slice by -- corresponding . -- -- If the slice contains at least one null position, the current token -- must be symbol. Otherwise, the routine reads no symbols to construct -- the n-tuple, so the current token is not checked. */ void simple_format ( MPL *mpl, SET *set, /* not changed */ MEMBER *memb, /* modified */ SLICE *slice /* not changed */ ) { TUPLE *tuple; SLICE *temp; SYMBOL *sym, *with = NULL; xassert(set != NULL); xassert(memb != NULL); xassert(slice != NULL); xassert(set->dimen == slice_dimen(mpl, slice)); xassert(memb->value.set->dim == set->dimen); if (slice_arity(mpl, slice) > 0) xassert(is_symbol(mpl)); /* read symbols and construct complete n-tuple */ tuple = create_tuple(mpl); for (temp = slice; temp != NULL; temp = temp->next) { if (temp->sym == NULL) { /* substitution is needed; read symbol */ if (!is_symbol(mpl)) { int lack = slice_arity(mpl, temp); /* with cannot be null due to assertion above */ xassert(with != NULL); if (lack == 1) mpl_error(mpl, "one item missing in data group beginning " "with %s", format_symbol(mpl, with)); else mpl_error(mpl, "%d items missing in data group beginning " "with %s", lack, format_symbol(mpl, with)); } sym = read_symbol(mpl); if (with == NULL) with = sym; } else { /* copy symbol from the slice */ sym = copy_symbol(mpl, temp->sym); } /* append the symbol to the n-tuple */ tuple = expand_tuple(mpl, tuple, sym); /* skip optional comma *between* */ if (temp->next != NULL && mpl->token == T_COMMA) get_token(mpl /* , */); } /* add constructed n-tuple to elemental set */ check_then_add(mpl, memb->value.set, tuple); return; } /*---------------------------------------------------------------------- -- matrix_format - read set data block in matrix format. -- -- This routine reads set data block using the syntax: -- -- ::= ... := -- +/- +/- ... +/- -- +/- +/- ... +/- -- . . . . . . . . . . . -- +/- +/- ... +/- -- -- where are symbols that denote rows of the matrix, -- are symbols that denote columns of the matrix, "+" and "-" indicate -- whether corresponding n-tuple needs to be included in the elemental -- set or not, respectively. -- -- Number of the slice components must be the same as dimension of the -- elemental set. The slice must have two null positions. To construct -- complete n-tuple for particular element of the matrix the routine -- replaces first null position of the slice by the corresponding -- (or , if the flag tr is on) and second null position by the -- corresponding (or by , if the flag tr is on). */ void matrix_format ( MPL *mpl, SET *set, /* not changed */ MEMBER *memb, /* modified */ SLICE *slice, /* not changed */ int tr ) { SLICE *list, *col, *temp; TUPLE *tuple; SYMBOL *row; xassert(set != NULL); xassert(memb != NULL); xassert(slice != NULL); xassert(set->dimen == slice_dimen(mpl, slice)); xassert(memb->value.set->dim == set->dimen); xassert(slice_arity(mpl, slice) == 2); /* read the matrix heading that contains column symbols (there may be no columns at all) */ list = create_slice(mpl); while (mpl->token != T_ASSIGN) { /* read column symbol and append it to the column list */ if (!is_symbol(mpl)) mpl_error(mpl, "number, symbol, or := missing where expected"); list = expand_slice(mpl, list, read_symbol(mpl)); } get_token(mpl /* := */); /* read zero or more rows that contain matrix data */ while (is_symbol(mpl)) { /* read row symbol (if the matrix has no columns, row symbols are just ignored) */ row = read_symbol(mpl); /* read the matrix row accordingly to the column list */ for (col = list; col != NULL; col = col->next) { int which = 0; /* check indicator */ if (is_literal(mpl, "+")) ; else if (is_literal(mpl, "-")) { get_token(mpl /* - */); continue; } else { int lack = slice_dimen(mpl, col); if (lack == 1) mpl_error(mpl, "one item missing in data group beginning " "with %s", format_symbol(mpl, row)); else mpl_error(mpl, "%d items missing in data group beginning " "with %s", lack, format_symbol(mpl, row)); } /* construct complete n-tuple */ tuple = create_tuple(mpl); for (temp = slice; temp != NULL; temp = temp->next) { if (temp->sym == NULL) { /* substitution is needed */ switch (++which) { case 1: /* substitute in the first null position */ tuple = expand_tuple(mpl, tuple, copy_symbol(mpl, tr ? col->sym : row)); break; case 2: /* substitute in the second null position */ tuple = expand_tuple(mpl, tuple, copy_symbol(mpl, tr ? row : col->sym)); break; default: xassert(which != which); } } else { /* copy symbol from the slice */ tuple = expand_tuple(mpl, tuple, copy_symbol(mpl, temp->sym)); } } xassert(which == 2); /* add constructed n-tuple to elemental set */ check_then_add(mpl, memb->value.set, tuple); get_token(mpl /* + */); } /* delete the row symbol */ delete_symbol(mpl, row); } /* delete the column list */ delete_slice(mpl, list); return; } /*---------------------------------------------------------------------- -- set_data - read set data. -- -- This routine reads set data using the syntax: -- -- ::= set ; -- ::= set [ ] ; -- ::= -- ::= -- ::= , := -- ::= , ( ) -- ::= , -- ::= , : -- ::= , (tr) -- ::= , (tr) : -- -- Commae in are optional and may be omitted anywhere. */ void set_data(MPL *mpl) { SET *set; TUPLE *tuple; MEMBER *memb; SLICE *slice; int tr = 0; xassert(is_literal(mpl, "set")); get_token(mpl /* set */); /* symbolic name of set must follows the keyword 'set' */ if (!is_symbol(mpl)) mpl_error(mpl, "set name missing where expected"); /* select the set to saturate it with data */ set = select_set(mpl, mpl->image); get_token(mpl /* */); /* read optional subscript list, which identifies member of the set to be read */ tuple = create_tuple(mpl); if (mpl->token == T_LBRACKET) { /* subscript list is specified */ if (set->dim == 0) mpl_error(mpl, "%s cannot be subscripted", set->name); get_token(mpl /* [ */); /* read symbols and construct subscript list */ for (;;) { if (!is_symbol(mpl)) mpl_error(mpl, "number or symbol missing where expected"); tuple = expand_tuple(mpl, tuple, read_symbol(mpl)); if (mpl->token == T_COMMA) get_token(mpl /* , */); else if (mpl->token == T_RBRACKET) break; else mpl_error(mpl, "syntax error in subscript list"); } if (set->dim != tuple_dimen(mpl, tuple)) mpl_error(mpl, "%s must have %d subscript%s rather than %d", set->name, set->dim, set->dim == 1 ? "" : "s", tuple_dimen(mpl, tuple)); get_token(mpl /* ] */); } else { /* subscript list is not specified */ if (set->dim != 0) mpl_error(mpl, "%s must be subscripted", set->name); } /* there must be no member with the same subscript list */ if (find_member(mpl, set->array, tuple) != NULL) mpl_error(mpl, "%s%s already defined", set->name, format_tuple(mpl, '[', tuple)); /* add new member to the set and assign it empty elemental set */ memb = add_member(mpl, set->array, tuple); memb->value.set = create_elemset(mpl, set->dimen); /* create an initial fake slice of all asterisks */ slice = fake_slice(mpl, set->dimen); /* read zero or more data assignments */ for (;;) { /* skip optional comma */ if (mpl->token == T_COMMA) get_token(mpl /* , */); /* process assignment element */ if (mpl->token == T_ASSIGN) { /* assignment ligature is non-significant element */ get_token(mpl /* := */); } else if (mpl->token == T_LEFT) { /* left parenthesis begins either new slice or "transpose" indicator */ int is_tr; get_token(mpl /* ( */); is_tr = is_literal(mpl, "tr"); unget_token(mpl /* ( */); if (is_tr) goto left; /* delete the current slice and read new one */ delete_slice(mpl, slice); slice = read_slice(mpl, set->name, set->dimen); /* each new slice resets the "transpose" indicator */ tr = 0; /* if the new slice is 0-ary, formally there is one 0-tuple (in the simple format) that follows it */ if (slice_arity(mpl, slice) == 0) simple_format(mpl, set, memb, slice); } else if (is_symbol(mpl)) { /* number or symbol begins data in the simple format */ simple_format(mpl, set, memb, slice); } else if (mpl->token == T_COLON) { /* colon begins data in the matrix format */ if (slice_arity(mpl, slice) != 2) err1: mpl_error(mpl, "slice currently used must specify 2 asterisk" "s, not %d", slice_arity(mpl, slice)); get_token(mpl /* : */); /* read elemental set data in the matrix format */ matrix_format(mpl, set, memb, slice, tr); } else if (mpl->token == T_LEFT) left: { /* left parenthesis begins the "transpose" indicator, which is followed by data in the matrix format */ get_token(mpl /* ( */); if (!is_literal(mpl, "tr")) err2: mpl_error(mpl, "transpose indicator (tr) incomplete"); if (slice_arity(mpl, slice) != 2) goto err1; get_token(mpl /* tr */); if (mpl->token != T_RIGHT) goto err2; get_token(mpl /* ) */); /* in this case the colon is optional */ if (mpl->token == T_COLON) get_token(mpl /* : */); /* set the "transpose" indicator */ tr = 1; /* read elemental set data in the matrix format */ matrix_format(mpl, set, memb, slice, tr); } else if (mpl->token == T_SEMICOLON) { /* semicolon terminates the data block */ get_token(mpl /* ; */); break; } else mpl_error(mpl, "syntax error in set data block"); } /* delete the current slice */ delete_slice(mpl, slice); return; } /*---------------------------------------------------------------------- -- select_parameter - select parameter to saturate it with data. -- -- This routine selects parameter to saturate it with data provided in -- the data section. */ PARAMETER *select_parameter ( MPL *mpl, char *name /* not changed */ ) { PARAMETER *par; AVLNODE *node; xassert(name != NULL); node = avl_find_node(mpl->tree, name); if (node == NULL || avl_get_node_type(node) != A_PARAMETER) mpl_error(mpl, "%s not a parameter", name); par = (PARAMETER *)avl_get_node_link(node); if (par->assign != NULL) mpl_error(mpl, "%s needs no data", name); if (par->data) mpl_error(mpl, "%s already provided with data", name); par->data = 1; return par; } /*---------------------------------------------------------------------- -- set_default - set default parameter value. -- -- This routine sets default value for specified parameter. */ void set_default ( MPL *mpl, PARAMETER *par, /* not changed */ SYMBOL *altval /* destroyed */ ) { xassert(par != NULL); xassert(altval != NULL); if (par->option != NULL) mpl_error(mpl, "default value for %s already specified in model se" "ction", par->name); xassert(par->defval == NULL); par->defval = altval; return; } /*---------------------------------------------------------------------- -- read_value - read value and assign it to parameter member. -- -- This routine reads numeric or symbolic value from the input stream -- and assigns to new parameter member specified by its n-tuple, which -- (the member) is created and added to the parameter array. */ MEMBER *read_value ( MPL *mpl, PARAMETER *par, /* not changed */ TUPLE *tuple /* destroyed */ ) { MEMBER *memb; xassert(par != NULL); xassert(is_symbol(mpl)); /* there must be no member with the same n-tuple */ if (find_member(mpl, par->array, tuple) != NULL) mpl_error(mpl, "%s%s already defined", par->name, format_tuple(mpl, '[', tuple)); /* create new parameter member with given n-tuple */ memb = add_member(mpl, par->array, tuple); /* read value and assigns it to the new parameter member */ switch (par->type) { case A_NUMERIC: case A_INTEGER: case A_BINARY: if (!is_number(mpl)) mpl_error(mpl, "%s requires numeric data", par->name); memb->value.num = read_number(mpl); break; case A_SYMBOLIC: memb->value.sym = read_symbol(mpl); break; default: xassert(par != par); } return memb; } /*---------------------------------------------------------------------- -- plain_format - read parameter data block in plain format. -- -- This routine reads parameter data block using the syntax: -- -- ::= , , ... , , -- -- where are used to determine a complete subscript list for -- parameter member, is a numeric or symbolic value assigned to -- the parameter member. Commae between data items are optional and may -- be omitted anywhere. -- -- Number of components in the slice must be the same as dimension of -- the parameter. To construct the complete subscript list the routine -- replaces null positions in the slice by corresponding . */ void plain_format ( MPL *mpl, PARAMETER *par, /* not changed */ SLICE *slice /* not changed */ ) { TUPLE *tuple; SLICE *temp; SYMBOL *sym, *with = NULL; xassert(par != NULL); xassert(par->dim == slice_dimen(mpl, slice)); xassert(is_symbol(mpl)); /* read symbols and construct complete subscript list */ tuple = create_tuple(mpl); for (temp = slice; temp != NULL; temp = temp->next) { if (temp->sym == NULL) { /* substitution is needed; read symbol */ if (!is_symbol(mpl)) { int lack = slice_arity(mpl, temp) + 1; xassert(with != NULL); xassert(lack > 1); mpl_error(mpl, "%d items missing in data group beginning wit" "h %s", lack, format_symbol(mpl, with)); } sym = read_symbol(mpl); if (with == NULL) with = sym; } else { /* copy symbol from the slice */ sym = copy_symbol(mpl, temp->sym); } /* append the symbol to the subscript list */ tuple = expand_tuple(mpl, tuple, sym); /* skip optional comma */ if (mpl->token == T_COMMA) get_token(mpl /* , */); } /* read value and assign it to new parameter member */ if (!is_symbol(mpl)) { xassert(with != NULL); mpl_error(mpl, "one item missing in data group beginning with %s", format_symbol(mpl, with)); } read_value(mpl, par, tuple); return; } /*---------------------------------------------------------------------- -- tabular_format - read parameter data block in tabular format. -- -- This routine reads parameter data block using the syntax: -- -- ::= ... := -- ... -- ... -- . . . . . . . . . . . -- ... -- -- where are symbols that denote rows of the table, -- are symbols that denote columns of the table, are numeric -- or symbolic values assigned to the corresponding parameter members. -- If is specified as single point, no value is provided. -- -- Number of components in the slice must be the same as dimension of -- the parameter. The slice must have two null positions. To construct -- complete subscript list for particular the routine replaces -- the first null position of the slice by the corresponding (or -- , if the flag tr is on) and the second null position by the -- corresponding (or by , if the flag tr is on). */ void tabular_format ( MPL *mpl, PARAMETER *par, /* not changed */ SLICE *slice, /* not changed */ int tr ) { SLICE *list, *col, *temp; TUPLE *tuple; SYMBOL *row; xassert(par != NULL); xassert(par->dim == slice_dimen(mpl, slice)); xassert(slice_arity(mpl, slice) == 2); /* read the table heading that contains column symbols (the table may have no columns) */ list = create_slice(mpl); while (mpl->token != T_ASSIGN) { /* read column symbol and append it to the column list */ if (!is_symbol(mpl)) mpl_error(mpl, "number, symbol, or := missing where expected"); list = expand_slice(mpl, list, read_symbol(mpl)); } get_token(mpl /* := */); /* read zero or more rows that contain tabular data */ while (is_symbol(mpl)) { /* read row symbol (if the table has no columns, these symbols are just ignored) */ row = read_symbol(mpl); /* read values accordingly to the column list */ for (col = list; col != NULL; col = col->next) { int which = 0; /* if the token is single point, no value is provided */ if (is_literal(mpl, ".")) { get_token(mpl /* . */); continue; } /* construct complete subscript list */ tuple = create_tuple(mpl); for (temp = slice; temp != NULL; temp = temp->next) { if (temp->sym == NULL) { /* substitution is needed */ switch (++which) { case 1: /* substitute in the first null position */ tuple = expand_tuple(mpl, tuple, copy_symbol(mpl, tr ? col->sym : row)); break; case 2: /* substitute in the second null position */ tuple = expand_tuple(mpl, tuple, copy_symbol(mpl, tr ? row : col->sym)); break; default: xassert(which != which); } } else { /* copy symbol from the slice */ tuple = expand_tuple(mpl, tuple, copy_symbol(mpl, temp->sym)); } } xassert(which == 2); /* read value and assign it to new parameter member */ if (!is_symbol(mpl)) { int lack = slice_dimen(mpl, col); if (lack == 1) mpl_error(mpl, "one item missing in data group beginning " "with %s", format_symbol(mpl, row)); else mpl_error(mpl, "%d items missing in data group beginning " "with %s", lack, format_symbol(mpl, row)); } read_value(mpl, par, tuple); } /* delete the row symbol */ delete_symbol(mpl, row); } /* delete the column list */ delete_slice(mpl, list); return; } /*---------------------------------------------------------------------- -- tabbing_format - read parameter data block in tabbing format. -- -- This routine reads parameter data block using the syntax: -- -- ::= , ... , , := , -- , ... , , , ... , , -- , ... , , , ... , , -- . . . . . . . . . . . . . . . . . -- , ... , , , ... , -- ::= -- ::= : -- -- where are names of parameters (all the parameters must be -- subscripted and have identical dimensions), are symbols -- used to define subscripts of parameter members, are numeric -- or symbolic values assigned to the corresponding parameter members. -- Optional may specify a simple set, in which case n-tuples -- built of for each row of the data table (i.e. subscripts -- of parameter members) are added to the specified set. Commae between -- data items are optional and may be omitted anywhere. -- -- If the parameter altval is not NULL, it specifies a default value -- provided for all the parameters specified in the data block. */ void tabbing_format ( MPL *mpl, SYMBOL *altval /* not changed */ ) { SET *set = NULL; PARAMETER *par; SLICE *list, *col; TUPLE *tuple; int next_token, j, dim = 0; char *last_name = NULL; /* read the optional */ if (is_symbol(mpl)) { get_token(mpl /* */); next_token = mpl->token; unget_token(mpl /* */); if (next_token == T_COLON) { /* select the set to saturate it with data */ set = select_set(mpl, mpl->image); /* the set must be simple (i.e. not set of sets) */ if (set->dim != 0) mpl_error(mpl, "%s must be a simple set", set->name); /* and must not be defined yet */ if (set->array->head != NULL) mpl_error(mpl, "%s already defined", set->name); /* add new (the only) member to the set and assign it empty elemental set */ add_member(mpl, set->array, NULL)->value.set = create_elemset(mpl, set->dimen); last_name = set->name, dim = set->dimen; get_token(mpl /* */); xassert(mpl->token == T_COLON); get_token(mpl /* : */); } } /* read the table heading that contains parameter names */ list = create_slice(mpl); while (mpl->token != T_ASSIGN) { /* there must be symbolic name of parameter */ if (!is_symbol(mpl)) mpl_error(mpl, "parameter name or := missing where expected"); /* select the parameter to saturate it with data */ par = select_parameter(mpl, mpl->image); /* the parameter must be subscripted */ if (par->dim == 0) mpl_error(mpl, "%s not a subscripted parameter", mpl->image); /* the set (if specified) and all the parameters in the data block must have identical dimension */ if (dim != 0 && par->dim != dim) { xassert(last_name != NULL); mpl_error(mpl, "%s has dimension %d while %s has dimension %d", last_name, dim, par->name, par->dim); } /* set default value for the parameter (if specified) */ if (altval != NULL) set_default(mpl, par, copy_symbol(mpl, altval)); /* append the parameter to the column list */ list = expand_slice(mpl, list, (SYMBOL *)par); last_name = par->name, dim = par->dim; get_token(mpl /* */); /* skip optional comma */ if (mpl->token == T_COMMA) get_token(mpl /* , */); } if (slice_dimen(mpl, list) == 0) mpl_error(mpl, "at least one parameter name required"); get_token(mpl /* := */); /* skip optional comma */ if (mpl->token == T_COMMA) get_token(mpl /* , */); /* read rows that contain tabbing data */ while (is_symbol(mpl)) { /* read subscript list */ tuple = create_tuple(mpl); for (j = 1; j <= dim; j++) { /* read j-th subscript */ if (!is_symbol(mpl)) { int lack = slice_dimen(mpl, list) + dim - j + 1; xassert(tuple != NULL); xassert(lack > 1); mpl_error(mpl, "%d items missing in data group beginning wit" "h %s", lack, format_symbol(mpl, tuple->sym)); } /* read and append j-th subscript to the n-tuple */ tuple = expand_tuple(mpl, tuple, read_symbol(mpl)); /* skip optional comma *between* */ if (j < dim && mpl->token == T_COMMA) get_token(mpl /* , */); } /* if the set is specified, add to it new n-tuple, which is a copy of the subscript list just read */ if (set != NULL) check_then_add(mpl, set->array->head->value.set, copy_tuple(mpl, tuple)); /* skip optional comma between and */ if (mpl->token == T_COMMA) get_token(mpl /* , */); /* read values accordingly to the column list */ for (col = list; col != NULL; col = col->next) { /* if the token is single point, no value is provided */ if (is_literal(mpl, ".")) { get_token(mpl /* . */); continue; } /* read value and assign it to new parameter member */ if (!is_symbol(mpl)) { int lack = slice_dimen(mpl, col); xassert(tuple != NULL); if (lack == 1) mpl_error(mpl, "one item missing in data group beginning " "with %s", format_symbol(mpl, tuple->sym)); else mpl_error(mpl, "%d items missing in data group beginning " "with %s", lack, format_symbol(mpl, tuple->sym)); } read_value(mpl, (PARAMETER *)col->sym, copy_tuple(mpl, tuple)); /* skip optional comma preceding the next value */ if (col->next != NULL && mpl->token == T_COMMA) get_token(mpl /* , */); } /* delete the original subscript list */ delete_tuple(mpl, tuple); /* skip optional comma (only if there is next data group) */ if (mpl->token == T_COMMA) { get_token(mpl /* , */); if (!is_symbol(mpl)) unget_token(mpl /* , */); } } /* delete the column list (it contains parameters, not symbols, so nullify it before) */ for (col = list; col != NULL; col = col->next) col->sym = NULL; delete_slice(mpl, list); return; } /*---------------------------------------------------------------------- -- parameter_data - read parameter data. -- -- This routine reads parameter data using the syntax: -- -- ::= param : ; -- ::= param -- ; -- ::= -- ::= -- ::= default -- ::= -- ::= , := -- ::= , [ ] -- ::= , -- ::= , : -- ::= , (tr) -- ::= , (tr) : -- -- Commae in are optional and may be omitted anywhere. */ void parameter_data(MPL *mpl) { PARAMETER *par; SYMBOL *altval = NULL; SLICE *slice; int tr = 0; xassert(is_literal(mpl, "param")); get_token(mpl /* param */); /* read optional default value */ if (is_literal(mpl, "default")) { get_token(mpl /* default */); if (!is_symbol(mpl)) mpl_error(mpl, "default value missing where expected"); altval = read_symbol(mpl); /* if the default value follows the keyword 'param', the next token must be only the colon */ if (mpl->token != T_COLON) mpl_error(mpl, "colon missing where expected"); } /* being used after the keyword 'param' or the optional default value the colon begins data in the tabbing format */ if (mpl->token == T_COLON) { get_token(mpl /* : */); /* skip optional comma */ if (mpl->token == T_COMMA) get_token(mpl /* , */); /* read parameter data in the tabbing format */ tabbing_format(mpl, altval); /* on reading data in the tabbing format the default value is always copied, so delete the original symbol */ if (altval != NULL) delete_symbol(mpl, altval); /* the next token must be only semicolon */ if (mpl->token != T_SEMICOLON) mpl_error(mpl, "symbol, number, or semicolon missing where expe" "cted"); get_token(mpl /* ; */); goto done; } /* in other cases there must be symbolic name of parameter, which follows the keyword 'param' */ if (!is_symbol(mpl)) mpl_error(mpl, "parameter name missing where expected"); /* select the parameter to saturate it with data */ par = select_parameter(mpl, mpl->image); get_token(mpl /* */); /* read optional default value */ if (is_literal(mpl, "default")) { get_token(mpl /* default */); if (!is_symbol(mpl)) mpl_error(mpl, "default value missing where expected"); altval = read_symbol(mpl); /* set default value for the parameter */ set_default(mpl, par, altval); } /* create initial fake slice of all asterisks */ slice = fake_slice(mpl, par->dim); /* read zero or more data assignments */ for (;;) { /* skip optional comma */ if (mpl->token == T_COMMA) get_token(mpl /* , */); /* process current assignment */ if (mpl->token == T_ASSIGN) { /* assignment ligature is non-significant element */ get_token(mpl /* := */); } else if (mpl->token == T_LBRACKET) { /* left bracket begins new slice; delete the current slice and read new one */ delete_slice(mpl, slice); slice = read_slice(mpl, par->name, par->dim); /* each new slice resets the "transpose" indicator */ tr = 0; } else if (is_symbol(mpl)) { /* number or symbol begins data in the plain format */ plain_format(mpl, par, slice); } else if (mpl->token == T_COLON) { /* colon begins data in the tabular format */ if (par->dim == 0) err1: mpl_error(mpl, "%s not a subscripted parameter", par->name); if (slice_arity(mpl, slice) != 2) err2: mpl_error(mpl, "slice currently used must specify 2 asterisk" "s, not %d", slice_arity(mpl, slice)); get_token(mpl /* : */); /* read parameter data in the tabular format */ tabular_format(mpl, par, slice, tr); } else if (mpl->token == T_LEFT) { /* left parenthesis begins the "transpose" indicator, which is followed by data in the tabular format */ get_token(mpl /* ( */); if (!is_literal(mpl, "tr")) err3: mpl_error(mpl, "transpose indicator (tr) incomplete"); if (par->dim == 0) goto err1; if (slice_arity(mpl, slice) != 2) goto err2; get_token(mpl /* tr */); if (mpl->token != T_RIGHT) goto err3; get_token(mpl /* ) */); /* in this case the colon is optional */ if (mpl->token == T_COLON) get_token(mpl /* : */); /* set the "transpose" indicator */ tr = 1; /* read parameter data in the tabular format */ tabular_format(mpl, par, slice, tr); } else if (mpl->token == T_SEMICOLON) { /* semicolon terminates the data block */ get_token(mpl /* ; */); break; } else mpl_error(mpl, "syntax error in parameter data block"); } /* delete the current slice */ delete_slice(mpl, slice); done: return; } /*---------------------------------------------------------------------- -- data_section - read data section. -- -- This routine reads data section using the syntax: -- -- ::= -- ::= ; -- ::= -- ::= -- -- Reading data section is terminated by either the keyword 'end' or -- the end of file. */ void data_section(MPL *mpl) { while (!(mpl->token == T_EOF || is_literal(mpl, "end"))) { if (is_literal(mpl, "set")) set_data(mpl); else if (is_literal(mpl, "param")) parameter_data(mpl); else mpl_error(mpl, "syntax error in data section"); } return; } /* eof */ praat-6.0.04/external/glpk/glpmpl03.c000066400000000000000000006454101261542461700173130ustar00rootroot00000000000000/* glpmpl03.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #define _GLPSTD_ERRNO #define _GLPSTD_STDIO #include "glpenv.h" #include "glpmpl.h" /**********************************************************************/ /* * * FLOATING-POINT NUMBERS * * */ /**********************************************************************/ /*---------------------------------------------------------------------- -- fp_add - floating-point addition. -- -- This routine computes the sum x + y. */ double fp_add(MPL *mpl, double x, double y) { if (x > 0.0 && y > 0.0 && x > + 0.999 * DBL_MAX - y || x < 0.0 && y < 0.0 && x < - 0.999 * DBL_MAX - y) mpl_error(mpl, "%.*g + %.*g; floating-point overflow", DBL_DIG, x, DBL_DIG, y); return x + y; } /*---------------------------------------------------------------------- -- fp_sub - floating-point subtraction. -- -- This routine computes the difference x - y. */ double fp_sub(MPL *mpl, double x, double y) { if (x > 0.0 && y < 0.0 && x > + 0.999 * DBL_MAX + y || x < 0.0 && y > 0.0 && x < - 0.999 * DBL_MAX + y) mpl_error(mpl, "%.*g - %.*g; floating-point overflow", DBL_DIG, x, DBL_DIG, y); return x - y; } /*---------------------------------------------------------------------- -- fp_less - floating-point non-negative subtraction. -- -- This routine computes the non-negative difference max(0, x - y). */ double fp_less(MPL *mpl, double x, double y) { if (x < y) return 0.0; if (x > 0.0 && y < 0.0 && x > + 0.999 * DBL_MAX + y) mpl_error(mpl, "%.*g less %.*g; floating-point overflow", DBL_DIG, x, DBL_DIG, y); return x - y; } /*---------------------------------------------------------------------- -- fp_mul - floating-point multiplication. -- -- This routine computes the product x * y. */ double fp_mul(MPL *mpl, double x, double y) { if (fabs(y) > 1.0 && fabs(x) > (0.999 * DBL_MAX) / fabs(y)) mpl_error(mpl, "%.*g * %.*g; floating-point overflow", DBL_DIG, x, DBL_DIG, y); return x * y; } /*---------------------------------------------------------------------- -- fp_div - floating-point division. -- -- This routine computes the quotient x / y. */ double fp_div(MPL *mpl, double x, double y) { if (fabs(y) < DBL_MIN) mpl_error(mpl, "%.*g / %.*g; floating-point zero divide", DBL_DIG, x, DBL_DIG, y); if (fabs(y) < 1.0 && fabs(x) > (0.999 * DBL_MAX) * fabs(y)) mpl_error(mpl, "%.*g / %.*g; floating-point overflow", DBL_DIG, x, DBL_DIG, y); return x / y; } /*---------------------------------------------------------------------- -- fp_idiv - floating-point quotient of exact division. -- -- This routine computes the quotient of exact division x div y. */ double fp_idiv(MPL *mpl, double x, double y) { if (fabs(y) < DBL_MIN) mpl_error(mpl, "%.*g div %.*g; floating-point zero divide", DBL_DIG, x, DBL_DIG, y); if (fabs(y) < 1.0 && fabs(x) > (0.999 * DBL_MAX) * fabs(y)) mpl_error(mpl, "%.*g div %.*g; floating-point overflow", DBL_DIG, x, DBL_DIG, y); x /= y; return x > 0.0 ? floor(x) : x < 0.0 ? ceil(x) : 0.0; } /*---------------------------------------------------------------------- -- fp_mod - floating-point remainder of exact division. -- -- This routine computes the remainder of exact division x mod y. -- -- NOTE: By definition x mod y = x - y * floor(x / y). */ double fp_mod(MPL *mpl, double x, double y) { double r; xassert(mpl == mpl); if (x == 0.0) r = 0.0; else if (y == 0.0) r = x; else { r = fmod(fabs(x), fabs(y)); if (r != 0.0) { if (x < 0.0) r = - r; if (x > 0.0 && y < 0.0 || x < 0.0 && y > 0.0) r += y; } } return r; } /*---------------------------------------------------------------------- -- fp_power - floating-point exponentiation (raise to power). -- -- This routine computes the exponentiation x ** y. */ double fp_power(MPL *mpl, double x, double y) { double r; if (x == 0.0 && y <= 0.0 || x < 0.0 && y != floor(y)) mpl_error(mpl, "%.*g ** %.*g; result undefined", DBL_DIG, x, DBL_DIG, y); if (x == 0.0) goto eval; if (fabs(x) > 1.0 && y > +1.0 && +log(fabs(x)) > (0.999 * log(DBL_MAX)) / y || fabs(x) < 1.0 && y < -1.0 && +log(fabs(x)) < (0.999 * log(DBL_MAX)) / y) mpl_error(mpl, "%.*g ** %.*g; floating-point overflow", DBL_DIG, x, DBL_DIG, y); if (fabs(x) > 1.0 && y < -1.0 && -log(fabs(x)) < (0.999 * log(DBL_MAX)) / y || fabs(x) < 1.0 && y > +1.0 && -log(fabs(x)) > (0.999 * log(DBL_MAX)) / y) r = 0.0; else eval: r = pow(x, y); return r; } /*---------------------------------------------------------------------- -- fp_exp - floating-point base-e exponential. -- -- This routine computes the base-e exponential e ** x. */ double fp_exp(MPL *mpl, double x) { if (x > 0.999 * log(DBL_MAX)) mpl_error(mpl, "exp(%.*g); floating-point overflow", DBL_DIG, x); return exp(x); } /*---------------------------------------------------------------------- -- fp_log - floating-point natural logarithm. -- -- This routine computes the natural logarithm log x. */ double fp_log(MPL *mpl, double x) { if (x <= 0.0) mpl_error(mpl, "log(%.*g); non-positive argument", DBL_DIG, x); return log(x); } /*---------------------------------------------------------------------- -- fp_log10 - floating-point common (decimal) logarithm. -- -- This routine computes the common (decimal) logarithm lg x. */ double fp_log10(MPL *mpl, double x) { if (x <= 0.0) mpl_error(mpl, "log10(%.*g); non-positive argument", DBL_DIG, x); return log10(x); } /*---------------------------------------------------------------------- -- fp_sqrt - floating-point square root. -- -- This routine computes the square root x ** 0.5. */ double fp_sqrt(MPL *mpl, double x) { if (x < 0.0) mpl_error(mpl, "sqrt(%.*g); negative argument", DBL_DIG, x); return sqrt(x); } /*---------------------------------------------------------------------- -- fp_sin - floating-point trigonometric sine. -- -- This routine computes the trigonometric sine sin(x). */ double fp_sin(MPL *mpl, double x) { if (!(-1e6 <= x && x <= +1e6)) mpl_error(mpl, "sin(%.*g); argument too large", DBL_DIG, x); return sin(x); } /*---------------------------------------------------------------------- -- fp_cos - floating-point trigonometric cosine. -- -- This routine computes the trigonometric cosine cos(x). */ double fp_cos(MPL *mpl, double x) { if (!(-1e6 <= x && x <= +1e6)) mpl_error(mpl, "cos(%.*g); argument too large", DBL_DIG, x); return cos(x); } /*---------------------------------------------------------------------- -- fp_atan - floating-point trigonometric arctangent. -- -- This routine computes the trigonometric arctangent atan(x). */ double fp_atan(MPL *mpl, double x) { xassert(mpl == mpl); return atan(x); } /*---------------------------------------------------------------------- -- fp_atan2 - floating-point trigonometric arctangent. -- -- This routine computes the trigonometric arctangent atan(y / x). */ double fp_atan2(MPL *mpl, double y, double x) { xassert(mpl == mpl); return atan2(y, x); } /*---------------------------------------------------------------------- -- fp_round - round floating-point value to n fractional digits. -- -- This routine rounds given floating-point value x to n fractional -- digits with the formula: -- -- round(x, n) = floor(x * 10^n + 0.5) / 10^n. -- -- The parameter n is assumed to be integer. */ double fp_round(MPL *mpl, double x, double n) { double ten_to_n; if (n != floor(n)) mpl_error(mpl, "round(%.*g, %.*g); non-integer second argument", DBL_DIG, x, DBL_DIG, n); if (n <= DBL_DIG + 2) { ten_to_n = pow(10.0, n); if (fabs(x) < (0.999 * DBL_MAX) / ten_to_n) { x = floor(x * ten_to_n + 0.5); if (x != 0.0) x /= ten_to_n; } } return x; } /*---------------------------------------------------------------------- -- fp_trunc - truncate floating-point value to n fractional digits. -- -- This routine truncates given floating-point value x to n fractional -- digits with the formula: -- -- ( floor(x * 10^n) / 10^n, if x >= 0 -- trunc(x, n) = < -- ( ceil(x * 10^n) / 10^n, if x < 0 -- -- The parameter n is assumed to be integer. */ double fp_trunc(MPL *mpl, double x, double n) { double ten_to_n; if (n != floor(n)) mpl_error(mpl, "trunc(%.*g, %.*g); non-integer second argument", DBL_DIG, x, DBL_DIG, n); if (n <= DBL_DIG + 2) { ten_to_n = pow(10.0, n); if (fabs(x) < (0.999 * DBL_MAX) / ten_to_n) { x = (x >= 0.0 ? floor(x * ten_to_n) : ceil(x * ten_to_n)); if (x != 0.0) x /= ten_to_n; } } return x; } /**********************************************************************/ /* * * PSEUDO-RANDOM NUMBER GENERATORS * * */ /**********************************************************************/ /*---------------------------------------------------------------------- -- fp_irand224 - pseudo-random integer in the range [0, 2^24). -- -- This routine returns a next pseudo-random integer (converted to -- floating-point) which is uniformly distributed between 0 and 2^24-1, -- inclusive. */ #define two_to_the_24 0x1000000 double fp_irand224(MPL *mpl) { return (double)rng_unif_rand(mpl->rand, two_to_the_24); } /*---------------------------------------------------------------------- -- fp_uniform01 - pseudo-random number in the range [0, 1). -- -- This routine returns a next pseudo-random number which is uniformly -- distributed in the range [0, 1). */ #define two_to_the_31 ((unsigned int)0x80000000) double fp_uniform01(MPL *mpl) { return (double)rng_next_rand(mpl->rand) / (double)two_to_the_31; } /*---------------------------------------------------------------------- -- fp_uniform - pseudo-random number in the range [a, b). -- -- This routine returns a next pseudo-random number which is uniformly -- distributed in the range [a, b). */ double fp_uniform(MPL *mpl, double a, double b) { double x; if (a >= b) mpl_error(mpl, "Uniform(%.*g, %.*g); invalid range", DBL_DIG, a, DBL_DIG, b); x = fp_uniform01(mpl); #if 0 x = a * (1.0 - x) + b * x; #else x = fp_add(mpl, a * (1.0 - x), b * x); #endif return x; } /*---------------------------------------------------------------------- -- fp_normal01 - Gaussian random variate with mu = 0 and sigma = 1. -- -- This routine returns a Gaussian random variate with zero mean and -- unit standard deviation. The polar (Box-Mueller) method is used. -- -- This code is a modified version of the routine gsl_ran_gaussian from -- the GNU Scientific Library Version 1.0. */ double fp_normal01(MPL *mpl) { double x, y, r2; do { /* choose x, y in uniform square (-1,-1) to (+1,+1) */ x = -1.0 + 2.0 * fp_uniform01(mpl); y = -1.0 + 2.0 * fp_uniform01(mpl); /* see if it is in the unit circle */ r2 = x * x + y * y; } while (r2 > 1.0 || r2 == 0.0); /* Box-Muller transform */ return y * sqrt(-2.0 * log (r2) / r2); } /*---------------------------------------------------------------------- -- fp_normal - Gaussian random variate with specified mu and sigma. -- -- This routine returns a Gaussian random variate with mean mu and -- standard deviation sigma. */ double fp_normal(MPL *mpl, double mu, double sigma) { double x; #if 0 x = mu + sigma * fp_normal01(mpl); #else x = fp_add(mpl, mu, fp_mul(mpl, sigma, fp_normal01(mpl))); #endif return x; } /**********************************************************************/ /* * * SEGMENTED CHARACTER STRINGS * * */ /**********************************************************************/ /*---------------------------------------------------------------------- -- create_string - create character string. -- -- This routine creates a segmented character string, which is exactly -- equivalent to specified character string. */ STRING *create_string ( MPL *mpl, char buf[MAX_LENGTH+1] /* not changed */ ) #if 0 { STRING *head, *tail; int i, j; xassert(buf != NULL); xassert(strlen(buf) <= MAX_LENGTH); head = tail = dmp_get_atom(mpl->strings, sizeof(STRING)); for (i = j = 0; ; i++) { if ((tail->seg[j++] = buf[i]) == '\0') break; if (j == STRSEG_SIZE) tail = (tail->next = dmp_get_atom(mpl->strings, sizeof(STRING))), j = 0; } tail->next = NULL; return head; } #else { STRING *str; xassert(strlen(buf) <= MAX_LENGTH); str = dmp_get_atom(mpl->strings, strlen(buf)+1); strcpy(str, buf); return str; } #endif /*---------------------------------------------------------------------- -- copy_string - make copy of character string. -- -- This routine returns an exact copy of segmented character string. */ STRING *copy_string ( MPL *mpl, STRING *str /* not changed */ ) #if 0 { STRING *head, *tail; xassert(str != NULL); head = tail = dmp_get_atom(mpl->strings, sizeof(STRING)); for (; str != NULL; str = str->next) { memcpy(tail->seg, str->seg, STRSEG_SIZE); if (str->next != NULL) tail = (tail->next = dmp_get_atom(mpl->strings, sizeof(STRING))); } tail->next = NULL; return head; } #else { xassert(mpl == mpl); return create_string(mpl, str); } #endif /*---------------------------------------------------------------------- -- compare_strings - compare one character string with another. -- -- This routine compares one segmented character strings with another -- and returns the result of comparison as follows: -- -- = 0 - both strings are identical; -- < 0 - the first string precedes the second one; -- > 0 - the first string follows the second one. */ int compare_strings ( MPL *mpl, STRING *str1, /* not changed */ STRING *str2 /* not changed */ ) #if 0 { int j, c1, c2; xassert(mpl == mpl); for (;; str1 = str1->next, str2 = str2->next) { xassert(str1 != NULL); xassert(str2 != NULL); for (j = 0; j < STRSEG_SIZE; j++) { c1 = (unsigned char)str1->seg[j]; c2 = (unsigned char)str2->seg[j]; if (c1 < c2) return -1; if (c1 > c2) return +1; if (c1 == '\0') goto done; } } done: return 0; } #else { xassert(mpl == mpl); return strcmp(str1, str2); } #endif /*---------------------------------------------------------------------- -- fetch_string - extract content of character string. -- -- This routine returns a character string, which is exactly equivalent -- to specified segmented character string. */ char *fetch_string ( MPL *mpl, STRING *str, /* not changed */ char buf[MAX_LENGTH+1] /* modified */ ) #if 0 { int i, j; xassert(mpl == mpl); xassert(buf != NULL); for (i = 0; ; str = str->next) { xassert(str != NULL); for (j = 0; j < STRSEG_SIZE; j++) if ((buf[i++] = str->seg[j]) == '\0') goto done; } done: xassert(strlen(buf) <= MAX_LENGTH); return buf; } #else { xassert(mpl == mpl); return strcpy(buf, str); } #endif /*---------------------------------------------------------------------- -- delete_string - delete character string. -- -- This routine deletes specified segmented character string. */ void delete_string ( MPL *mpl, STRING *str /* destroyed */ ) #if 0 { STRING *temp; xassert(str != NULL); while (str != NULL) { temp = str; str = str->next; dmp_free_atom(mpl->strings, temp, sizeof(STRING)); } return; } #else { dmp_free_atom(mpl->strings, str, strlen(str)+1); return; } #endif /**********************************************************************/ /* * * SYMBOLS * * */ /**********************************************************************/ /*---------------------------------------------------------------------- -- create_symbol_num - create symbol of numeric type. -- -- This routine creates a symbol, which has a numeric value specified -- as floating-point number. */ SYMBOL *create_symbol_num(MPL *mpl, double num) { SYMBOL *sym; sym = dmp_get_atom(mpl->symbols, sizeof(SYMBOL)); sym->num = num; sym->str = NULL; return sym; } /*---------------------------------------------------------------------- -- create_symbol_str - create symbol of abstract type. -- -- This routine creates a symbol, which has an abstract value specified -- as segmented character string. */ SYMBOL *create_symbol_str ( MPL *mpl, STRING *str /* destroyed */ ) { SYMBOL *sym; xassert(str != NULL); sym = dmp_get_atom(mpl->symbols, sizeof(SYMBOL)); sym->num = 0.0; sym->str = str; return sym; } /*---------------------------------------------------------------------- -- copy_symbol - make copy of symbol. -- -- This routine returns an exact copy of symbol. */ SYMBOL *copy_symbol ( MPL *mpl, SYMBOL *sym /* not changed */ ) { SYMBOL *copy; xassert(sym != NULL); copy = dmp_get_atom(mpl->symbols, sizeof(SYMBOL)); if (sym->str == NULL) { copy->num = sym->num; copy->str = NULL; } else { copy->num = 0.0; copy->str = copy_string(mpl, sym->str); } return copy; } /*---------------------------------------------------------------------- -- compare_symbols - compare one symbol with another. -- -- This routine compares one symbol with another and returns the result -- of comparison as follows: -- -- = 0 - both symbols are identical; -- < 0 - the first symbol precedes the second one; -- > 0 - the first symbol follows the second one. -- -- Note that the linear order, in which symbols follow each other, is -- implementation-dependent. It may be not an alphabetical order. */ int compare_symbols ( MPL *mpl, SYMBOL *sym1, /* not changed */ SYMBOL *sym2 /* not changed */ ) { xassert(sym1 != NULL); xassert(sym2 != NULL); /* let all numeric quantities precede all symbolic quantities */ if (sym1->str == NULL && sym2->str == NULL) { if (sym1->num < sym2->num) return -1; if (sym1->num > sym2->num) return +1; return 0; } if (sym1->str == NULL) return -1; if (sym2->str == NULL) return +1; return compare_strings(mpl, sym1->str, sym2->str); } /*---------------------------------------------------------------------- -- delete_symbol - delete symbol. -- -- This routine deletes specified symbol. */ void delete_symbol ( MPL *mpl, SYMBOL *sym /* destroyed */ ) { xassert(sym != NULL); if (sym->str != NULL) delete_string(mpl, sym->str); dmp_free_atom(mpl->symbols, sym, sizeof(SYMBOL)); return; } /*---------------------------------------------------------------------- -- format_symbol - format symbol for displaying or printing. -- -- This routine converts specified symbol to a charater string, which -- is suitable for displaying or printing. -- -- The resultant string is never longer than 255 characters. If it gets -- longer, it is truncated from the right and appended by dots. */ char *format_symbol ( MPL *mpl, SYMBOL *sym /* not changed */ ) { char *buf = mpl->sym_buf; xassert(sym != NULL); if (sym->str == NULL) sprintf(buf, "%.*g", DBL_DIG, sym->num); else { char str[MAX_LENGTH+1]; int quoted, j, len; fetch_string(mpl, sym->str, str); if (!(isalpha((unsigned char)str[0]) || str[0] == '_')) quoted = 1; else { quoted = 0; for (j = 1; str[j] != '\0'; j++) { if (!(isalnum((unsigned char)str[j]) || strchr("+-._", (unsigned char)str[j]) != NULL)) { quoted = 1; break; } } } # define safe_append(c) \ (void)(len < 255 ? (buf[len++] = (char)(c)) : 0) buf[0] = '\0', len = 0; if (quoted) safe_append('\''); for (j = 0; str[j] != '\0'; j++) { if (quoted && str[j] == '\'') safe_append('\''); safe_append(str[j]); } if (quoted) safe_append('\''); # undef safe_append buf[len] = '\0'; if (len == 255) strcpy(buf+252, "..."); } xassert(strlen(buf) <= 255); return buf; } /*---------------------------------------------------------------------- -- concat_symbols - concatenate one symbol with another. -- -- This routine concatenates values of two given symbols and assigns -- the resultant character string to a new symbol, which is returned on -- exit. Both original symbols are destroyed. */ SYMBOL *concat_symbols ( MPL *mpl, SYMBOL *sym1, /* destroyed */ SYMBOL *sym2 /* destroyed */ ) { char str1[MAX_LENGTH+1], str2[MAX_LENGTH+1]; xassert(MAX_LENGTH >= DBL_DIG + DBL_DIG); if (sym1->str == NULL) sprintf(str1, "%.*g", DBL_DIG, sym1->num); else fetch_string(mpl, sym1->str, str1); if (sym2->str == NULL) sprintf(str2, "%.*g", DBL_DIG, sym2->num); else fetch_string(mpl, sym2->str, str2); if (strlen(str1) + strlen(str2) > MAX_LENGTH) { char buf[255+1]; strcpy(buf, format_symbol(mpl, sym1)); xassert(strlen(buf) < sizeof(buf)); mpl_error(mpl, "%s & %s; resultant symbol exceeds %d characters", buf, format_symbol(mpl, sym2), MAX_LENGTH); } delete_symbol(mpl, sym1); delete_symbol(mpl, sym2); return create_symbol_str(mpl, create_string(mpl, strcat(str1, str2))); } /**********************************************************************/ /* * * N-TUPLES * * */ /**********************************************************************/ /*---------------------------------------------------------------------- -- create_tuple - create n-tuple. -- -- This routine creates a n-tuple, which initially has no components, -- i.e. which is 0-tuple. */ TUPLE *create_tuple(MPL *mpl) { TUPLE *tuple; xassert(mpl == mpl); tuple = NULL; return tuple; } /*---------------------------------------------------------------------- -- expand_tuple - append symbol to n-tuple. -- -- This routine expands n-tuple appending to it a given symbol, which -- becomes its new last component. */ TUPLE *expand_tuple ( MPL *mpl, TUPLE *tuple, /* destroyed */ SYMBOL *sym /* destroyed */ ) { TUPLE *tail, *temp; xassert(sym != NULL); /* create a new component */ tail = dmp_get_atom(mpl->tuples, sizeof(TUPLE)); tail->sym = sym; tail->next = NULL; /* and append it to the component list */ if (tuple == NULL) tuple = tail; else { for (temp = tuple; temp->next != NULL; temp = temp->next); temp->next = tail; } return tuple; } /*---------------------------------------------------------------------- -- tuple_dimen - determine dimension of n-tuple. -- -- This routine returns dimension of n-tuple, i.e. number of components -- in the n-tuple. */ int tuple_dimen ( MPL *mpl, TUPLE *tuple /* not changed */ ) { TUPLE *temp; int dim = 0; xassert(mpl == mpl); for (temp = tuple; temp != NULL; temp = temp->next) dim++; return dim; } /*---------------------------------------------------------------------- -- copy_tuple - make copy of n-tuple. -- -- This routine returns an exact copy of n-tuple. */ TUPLE *copy_tuple ( MPL *mpl, TUPLE *tuple /* not changed */ ) { TUPLE *head, *tail; if (tuple == NULL) head = NULL; else { head = tail = dmp_get_atom(mpl->tuples, sizeof(TUPLE)); for (; tuple != NULL; tuple = tuple->next) { xassert(tuple->sym != NULL); tail->sym = copy_symbol(mpl, tuple->sym); if (tuple->next != NULL) tail = (tail->next = dmp_get_atom(mpl->tuples, sizeof(TUPLE))); } tail->next = NULL; } return head; } /*---------------------------------------------------------------------- -- compare_tuples - compare one n-tuple with another. -- -- This routine compares two given n-tuples, which must have the same -- dimension (not checked for the sake of efficiency), and returns one -- of the following codes: -- -- = 0 - both n-tuples are identical; -- < 0 - the first n-tuple precedes the second one; -- > 0 - the first n-tuple follows the second one. -- -- Note that the linear order, in which n-tuples follow each other, is -- implementation-dependent. It may be not an alphabetical order. */ int compare_tuples ( MPL *mpl, TUPLE *tuple1, /* not changed */ TUPLE *tuple2 /* not changed */ ) { TUPLE *item1, *item2; int ret; xassert(mpl == mpl); for (item1 = tuple1, item2 = tuple2; item1 != NULL; item1 = item1->next, item2 = item2->next) { xassert(item2 != NULL); xassert(item1->sym != NULL); xassert(item2->sym != NULL); ret = compare_symbols(mpl, item1->sym, item2->sym); if (ret != 0) return ret; } xassert(item2 == NULL); return 0; } /*---------------------------------------------------------------------- -- build_subtuple - build subtuple of given n-tuple. -- -- This routine builds subtuple, which consists of first dim components -- of given n-tuple. */ TUPLE *build_subtuple ( MPL *mpl, TUPLE *tuple, /* not changed */ int dim ) { TUPLE *head, *temp; int j; head = create_tuple(mpl); for (j = 1, temp = tuple; j <= dim; j++, temp = temp->next) { xassert(temp != NULL); head = expand_tuple(mpl, head, copy_symbol(mpl, temp->sym)); } return head; } /*---------------------------------------------------------------------- -- delete_tuple - delete n-tuple. -- -- This routine deletes specified n-tuple. */ void delete_tuple ( MPL *mpl, TUPLE *tuple /* destroyed */ ) { TUPLE *temp; while (tuple != NULL) { temp = tuple; tuple = temp->next; xassert(temp->sym != NULL); delete_symbol(mpl, temp->sym); dmp_free_atom(mpl->tuples, temp, sizeof(TUPLE)); } return; } /*---------------------------------------------------------------------- -- format_tuple - format n-tuple for displaying or printing. -- -- This routine converts specified n-tuple to a character string, which -- is suitable for displaying or printing. -- -- The resultant string is never longer than 255 characters. If it gets -- longer, it is truncated from the right and appended by dots. */ char *format_tuple ( MPL *mpl, int c, TUPLE *tuple /* not changed */ ) { TUPLE *temp; int dim, j, len; char *buf = mpl->tup_buf, str[255+1], *save; # define safe_append(c) \ (void)(len < 255 ? (buf[len++] = (char)(c)) : 0) buf[0] = '\0', len = 0; dim = tuple_dimen(mpl, tuple); if (c == '[' && dim > 0) safe_append('['); if (c == '(' && dim > 1) safe_append('('); for (temp = tuple; temp != NULL; temp = temp->next) { if (temp != tuple) safe_append(','); xassert(temp->sym != NULL); save = mpl->sym_buf; mpl->sym_buf = str; format_symbol(mpl, temp->sym); mpl->sym_buf = save; xassert(strlen(str) < sizeof(str)); for (j = 0; str[j] != '\0'; j++) safe_append(str[j]); } if (c == '[' && dim > 0) safe_append(']'); if (c == '(' && dim > 1) safe_append(')'); # undef safe_append buf[len] = '\0'; if (len == 255) strcpy(buf+252, "..."); xassert(strlen(buf) <= 255); return buf; } /**********************************************************************/ /* * * ELEMENTAL SETS * * */ /**********************************************************************/ /*---------------------------------------------------------------------- -- create_elemset - create elemental set. -- -- This routine creates an elemental set, whose members are n-tuples of -- specified dimension. Being created the set is initially empty. */ ELEMSET *create_elemset(MPL *mpl, int dim) { ELEMSET *set; xassert(dim > 0); set = create_array(mpl, A_NONE, dim); return set; } /*---------------------------------------------------------------------- -- find_tuple - check if elemental set contains given n-tuple. -- -- This routine finds given n-tuple in specified elemental set in order -- to check if the set contains that n-tuple. If the n-tuple is found, -- the routine returns pointer to corresponding array member. Otherwise -- null pointer is returned. */ MEMBER *find_tuple ( MPL *mpl, ELEMSET *set, /* not changed */ TUPLE *tuple /* not changed */ ) { xassert(set != NULL); xassert(set->type == A_NONE); xassert(set->dim == tuple_dimen(mpl, tuple)); return find_member(mpl, set, tuple); } /*---------------------------------------------------------------------- -- add_tuple - add new n-tuple to elemental set. -- -- This routine adds given n-tuple to specified elemental set. -- -- For the sake of efficiency this routine doesn't check whether the -- set already contains the same n-tuple or not. Therefore the calling -- program should use the routine find_tuple (if necessary) in order to -- make sure that the given n-tuple is not contained in the set, since -- duplicate n-tuples within the same set are not allowed. */ MEMBER *add_tuple ( MPL *mpl, ELEMSET *set, /* modified */ TUPLE *tuple /* destroyed */ ) { MEMBER *memb; xassert(set != NULL); xassert(set->type == A_NONE); xassert(set->dim == tuple_dimen(mpl, tuple)); memb = add_member(mpl, set, tuple); memb->value.none = NULL; return memb; } /*---------------------------------------------------------------------- -- check_then_add - check and add new n-tuple to elemental set. -- -- This routine is equivalent to the routine add_tuple except that it -- does check for duplicate n-tuples. */ MEMBER *check_then_add ( MPL *mpl, ELEMSET *set, /* modified */ TUPLE *tuple /* destroyed */ ) { if (find_tuple(mpl, set, tuple) != NULL) mpl_error(mpl, "duplicate tuple %s detected", format_tuple(mpl, '(', tuple)); return add_tuple(mpl, set, tuple); } /*---------------------------------------------------------------------- -- copy_elemset - make copy of elemental set. -- -- This routine makes an exact copy of elemental set. */ ELEMSET *copy_elemset ( MPL *mpl, ELEMSET *set /* not changed */ ) { ELEMSET *copy; MEMBER *memb; xassert(set != NULL); xassert(set->type == A_NONE); xassert(set->dim > 0); copy = create_elemset(mpl, set->dim); for (memb = set->head; memb != NULL; memb = memb->next) add_tuple(mpl, copy, copy_tuple(mpl, memb->tuple)); return copy; } /*---------------------------------------------------------------------- -- delete_elemset - delete elemental set. -- -- This routine deletes specified elemental set. */ void delete_elemset ( MPL *mpl, ELEMSET *set /* destroyed */ ) { xassert(set != NULL); xassert(set->type == A_NONE); delete_array(mpl, set); return; } /*---------------------------------------------------------------------- -- arelset_size - compute size of "arithmetic" elemental set. -- -- This routine computes the size of "arithmetic" elemental set, which -- is specified in the form of arithmetic progression: -- -- { t0 .. tf by dt }. -- -- The size is computed using the formula: -- -- n = max(0, floor((tf - t0) / dt) + 1). */ int arelset_size(MPL *mpl, double t0, double tf, double dt) { double temp; if (dt == 0.0) mpl_error(mpl, "%.*g .. %.*g by %.*g; zero stride not allowed", DBL_DIG, t0, DBL_DIG, tf, DBL_DIG, dt); if (tf > 0.0 && t0 < 0.0 && tf > + 0.999 * DBL_MAX + t0) temp = +DBL_MAX; else if (tf < 0.0 && t0 > 0.0 && tf < - 0.999 * DBL_MAX + t0) temp = -DBL_MAX; else temp = tf - t0; if (fabs(dt) < 1.0 && fabs(temp) > (0.999 * DBL_MAX) * fabs(dt)) { if (temp > 0.0 && dt > 0.0 || temp < 0.0 && dt < 0.0) temp = +DBL_MAX; else temp = 0.0; } else { temp = floor(temp / dt) + 1.0; if (temp < 0.0) temp = 0.0; } xassert(temp >= 0.0); if (temp > (double)(INT_MAX - 1)) mpl_error(mpl, "%.*g .. %.*g by %.*g; set too large", DBL_DIG, t0, DBL_DIG, tf, DBL_DIG, dt); return (int)(temp + 0.5); } /*---------------------------------------------------------------------- -- arelset_member - compute member of "arithmetic" elemental set. -- -- This routine returns a numeric value of symbol, which is equivalent -- to j-th member of given "arithmetic" elemental set specified in the -- form of arithmetic progression: -- -- { t0 .. tf by dt }. -- -- The symbol value is computed with the formula: -- -- j-th member = t0 + (j - 1) * dt, -- -- The number j must satisfy to the restriction 1 <= j <= n, where n is -- the set size computed by the routine arelset_size. */ double arelset_member(MPL *mpl, double t0, double tf, double dt, int j) { xassert(1 <= j && j <= arelset_size(mpl, t0, tf, dt)); return t0 + (double)(j - 1) * dt; } /*---------------------------------------------------------------------- -- create_arelset - create "arithmetic" elemental set. -- -- This routine creates "arithmetic" elemental set, which is specified -- in the form of arithmetic progression: -- -- { t0 .. tf by dt }. -- -- Components of this set are 1-tuples. */ ELEMSET *create_arelset(MPL *mpl, double t0, double tf, double dt) { ELEMSET *set; int j, n; set = create_elemset(mpl, 1); n = arelset_size(mpl, t0, tf, dt); for (j = 1; j <= n; j++) { add_tuple ( mpl, set, expand_tuple ( mpl, create_tuple(mpl), create_symbol_num ( mpl, arelset_member(mpl, t0, tf, dt, j) ) ) ); } return set; } /*---------------------------------------------------------------------- -- set_union - union of two elemental sets. -- -- This routine computes the union: -- -- X U Y = { j | (j in X) or (j in Y) }, -- -- where X and Y are given elemental sets (destroyed on exit). */ ELEMSET *set_union ( MPL *mpl, ELEMSET *X, /* destroyed */ ELEMSET *Y /* destroyed */ ) { MEMBER *memb; xassert(X != NULL); xassert(X->type == A_NONE); xassert(X->dim > 0); xassert(Y != NULL); xassert(Y->type == A_NONE); xassert(Y->dim > 0); xassert(X->dim == Y->dim); for (memb = Y->head; memb != NULL; memb = memb->next) { if (find_tuple(mpl, X, memb->tuple) == NULL) add_tuple(mpl, X, copy_tuple(mpl, memb->tuple)); } delete_elemset(mpl, Y); return X; } /*---------------------------------------------------------------------- -- set_diff - difference between two elemental sets. -- -- This routine computes the difference: -- -- X \ Y = { j | (j in X) and (j not in Y) }, -- -- where X and Y are given elemental sets (destroyed on exit). */ ELEMSET *set_diff ( MPL *mpl, ELEMSET *X, /* destroyed */ ELEMSET *Y /* destroyed */ ) { ELEMSET *Z; MEMBER *memb; xassert(X != NULL); xassert(X->type == A_NONE); xassert(X->dim > 0); xassert(Y != NULL); xassert(Y->type == A_NONE); xassert(Y->dim > 0); xassert(X->dim == Y->dim); Z = create_elemset(mpl, X->dim); for (memb = X->head; memb != NULL; memb = memb->next) { if (find_tuple(mpl, Y, memb->tuple) == NULL) add_tuple(mpl, Z, copy_tuple(mpl, memb->tuple)); } delete_elemset(mpl, X); delete_elemset(mpl, Y); return Z; } /*---------------------------------------------------------------------- -- set_symdiff - symmetric difference between two elemental sets. -- -- This routine computes the symmetric difference: -- -- X (+) Y = (X \ Y) U (Y \ X), -- -- where X and Y are given elemental sets (destroyed on exit). */ ELEMSET *set_symdiff ( MPL *mpl, ELEMSET *X, /* destroyed */ ELEMSET *Y /* destroyed */ ) { ELEMSET *Z; MEMBER *memb; xassert(X != NULL); xassert(X->type == A_NONE); xassert(X->dim > 0); xassert(Y != NULL); xassert(Y->type == A_NONE); xassert(Y->dim > 0); xassert(X->dim == Y->dim); /* Z := X \ Y */ Z = create_elemset(mpl, X->dim); for (memb = X->head; memb != NULL; memb = memb->next) { if (find_tuple(mpl, Y, memb->tuple) == NULL) add_tuple(mpl, Z, copy_tuple(mpl, memb->tuple)); } /* Z := Z U (Y \ X) */ for (memb = Y->head; memb != NULL; memb = memb->next) { if (find_tuple(mpl, X, memb->tuple) == NULL) add_tuple(mpl, Z, copy_tuple(mpl, memb->tuple)); } delete_elemset(mpl, X); delete_elemset(mpl, Y); return Z; } /*---------------------------------------------------------------------- -- set_inter - intersection of two elemental sets. -- -- This routine computes the intersection: -- -- X ^ Y = { j | (j in X) and (j in Y) }, -- -- where X and Y are given elemental sets (destroyed on exit). */ ELEMSET *set_inter ( MPL *mpl, ELEMSET *X, /* destroyed */ ELEMSET *Y /* destroyed */ ) { ELEMSET *Z; MEMBER *memb; xassert(X != NULL); xassert(X->type == A_NONE); xassert(X->dim > 0); xassert(Y != NULL); xassert(Y->type == A_NONE); xassert(Y->dim > 0); xassert(X->dim == Y->dim); Z = create_elemset(mpl, X->dim); for (memb = X->head; memb != NULL; memb = memb->next) { if (find_tuple(mpl, Y, memb->tuple) != NULL) add_tuple(mpl, Z, copy_tuple(mpl, memb->tuple)); } delete_elemset(mpl, X); delete_elemset(mpl, Y); return Z; } /*---------------------------------------------------------------------- -- set_cross - cross (Cartesian) product of two elemental sets. -- -- This routine computes the cross (Cartesian) product: -- -- X x Y = { (i,j) | (i in X) and (j in Y) }, -- -- where X and Y are given elemental sets (destroyed on exit). */ ELEMSET *set_cross ( MPL *mpl, ELEMSET *X, /* destroyed */ ELEMSET *Y /* destroyed */ ) { ELEMSET *Z; MEMBER *memx, *memy; TUPLE *tuple, *temp; xassert(X != NULL); xassert(X->type == A_NONE); xassert(X->dim > 0); xassert(Y != NULL); xassert(Y->type == A_NONE); xassert(Y->dim > 0); Z = create_elemset(mpl, X->dim + Y->dim); for (memx = X->head; memx != NULL; memx = memx->next) { for (memy = Y->head; memy != NULL; memy = memy->next) { tuple = copy_tuple(mpl, memx->tuple); for (temp = memy->tuple; temp != NULL; temp = temp->next) tuple = expand_tuple(mpl, tuple, copy_symbol(mpl, temp->sym)); add_tuple(mpl, Z, tuple); } } delete_elemset(mpl, X); delete_elemset(mpl, Y); return Z; } /**********************************************************************/ /* * * ELEMENTAL VARIABLES * * */ /**********************************************************************/ /* (there are no specific routines for elemental variables) */ /**********************************************************************/ /* * * LINEAR FORMS * * */ /**********************************************************************/ /*---------------------------------------------------------------------- -- constant_term - create constant term. -- -- This routine creates the linear form, which is a constant term. */ FORMULA *constant_term(MPL *mpl, double coef) { FORMULA *form; if (coef == 0.0) form = NULL; else { form = dmp_get_atom(mpl->formulae, sizeof(FORMULA)); form->coef = coef; form->var = NULL; form->next = NULL; } return form; } /*---------------------------------------------------------------------- -- single_variable - create single variable. -- -- This routine creates the linear form, which is a single elemental -- variable. */ FORMULA *single_variable ( MPL *mpl, ELEMVAR *var /* referenced */ ) { FORMULA *form; xassert(var != NULL); form = dmp_get_atom(mpl->formulae, sizeof(FORMULA)); form->coef = 1.0; form->var = var; form->next = NULL; return form; } /*---------------------------------------------------------------------- -- copy_formula - make copy of linear form. -- -- This routine returns an exact copy of linear form. */ FORMULA *copy_formula ( MPL *mpl, FORMULA *form /* not changed */ ) { FORMULA *head, *tail; if (form == NULL) head = NULL; else { head = tail = dmp_get_atom(mpl->formulae, sizeof(FORMULA)); for (; form != NULL; form = form->next) { tail->coef = form->coef; tail->var = form->var; if (form->next != NULL) tail = (tail->next = dmp_get_atom(mpl->formulae, sizeof(FORMULA))); } tail->next = NULL; } return head; } /*---------------------------------------------------------------------- -- delete_formula - delete linear form. -- -- This routine deletes specified linear form. */ void delete_formula ( MPL *mpl, FORMULA *form /* destroyed */ ) { FORMULA *temp; while (form != NULL) { temp = form; form = form->next; dmp_free_atom(mpl->formulae, temp, sizeof(FORMULA)); } return; } /*---------------------------------------------------------------------- -- linear_comb - linear combination of two linear forms. -- -- This routine computes the linear combination: -- -- a * fx + b * fy, -- -- where a and b are numeric coefficients, fx and fy are linear forms -- (destroyed on exit). */ FORMULA *linear_comb ( MPL *mpl, double a, FORMULA *fx, /* destroyed */ double b, FORMULA *fy /* destroyed */ ) { FORMULA *form = NULL, *term, *temp; double c0 = 0.0; for (term = fx; term != NULL; term = term->next) { if (term->var == NULL) c0 = fp_add(mpl, c0, fp_mul(mpl, a, term->coef)); else term->var->temp = fp_add(mpl, term->var->temp, fp_mul(mpl, a, term->coef)); } for (term = fy; term != NULL; term = term->next) { if (term->var == NULL) c0 = fp_add(mpl, c0, fp_mul(mpl, b, term->coef)); else term->var->temp = fp_add(mpl, term->var->temp, fp_mul(mpl, b, term->coef)); } for (term = fx; term != NULL; term = term->next) { if (term->var != NULL && term->var->temp != 0.0) { temp = dmp_get_atom(mpl->formulae, sizeof(FORMULA)); temp->coef = term->var->temp, temp->var = term->var; temp->next = form, form = temp; term->var->temp = 0.0; } } for (term = fy; term != NULL; term = term->next) { if (term->var != NULL && term->var->temp != 0.0) { temp = dmp_get_atom(mpl->formulae, sizeof(FORMULA)); temp->coef = term->var->temp, temp->var = term->var; temp->next = form, form = temp; term->var->temp = 0.0; } } if (c0 != 0.0) { temp = dmp_get_atom(mpl->formulae, sizeof(FORMULA)); temp->coef = c0, temp->var = NULL; temp->next = form, form = temp; } delete_formula(mpl, fx); delete_formula(mpl, fy); return form; } /*---------------------------------------------------------------------- -- remove_constant - remove constant term from linear form. -- -- This routine removes constant term from linear form and stores its -- value to given location. */ FORMULA *remove_constant ( MPL *mpl, FORMULA *form, /* destroyed */ double *coef /* modified */ ) { FORMULA *head = NULL, *temp; *coef = 0.0; while (form != NULL) { temp = form; form = form->next; if (temp->var == NULL) { /* constant term */ *coef = fp_add(mpl, *coef, temp->coef); dmp_free_atom(mpl->formulae, temp, sizeof(FORMULA)); } else { /* linear term */ temp->next = head; head = temp; } } return head; } /*---------------------------------------------------------------------- -- reduce_terms - reduce identical terms in linear form. -- -- This routine reduces identical terms in specified linear form. */ FORMULA *reduce_terms ( MPL *mpl, FORMULA *form /* destroyed */ ) { FORMULA *term, *next_term; double c0 = 0.0; for (term = form; term != NULL; term = term->next) { if (term->var == NULL) c0 = fp_add(mpl, c0, term->coef); else term->var->temp = fp_add(mpl, term->var->temp, term->coef); } next_term = form, form = NULL; for (term = next_term; term != NULL; term = next_term) { next_term = term->next; if (term->var == NULL && c0 != 0.0) { term->coef = c0, c0 = 0.0; term->next = form, form = term; } else if (term->var != NULL && term->var->temp != 0.0) { term->coef = term->var->temp, term->var->temp = 0.0; term->next = form, form = term; } else dmp_free_atom(mpl->formulae, term, sizeof(FORMULA)); } return form; } /**********************************************************************/ /* * * ELEMENTAL CONSTRAINTS * * */ /**********************************************************************/ /* (there are no specific routines for elemental constraints) */ /**********************************************************************/ /* * * GENERIC VALUES * * */ /**********************************************************************/ /*---------------------------------------------------------------------- -- delete_value - delete generic value. -- -- This routine deletes specified generic value. -- -- NOTE: The generic value to be deleted must be valid. */ void delete_value ( MPL *mpl, int type, VALUE *value /* content destroyed */ ) { xassert(value != NULL); switch (type) { case A_NONE: value->none = NULL; break; case A_NUMERIC: value->num = 0.0; break; case A_SYMBOLIC: delete_symbol(mpl, value->sym), value->sym = NULL; break; case A_LOGICAL: value->bit = 0; break; case A_TUPLE: delete_tuple(mpl, value->tuple), value->tuple = NULL; break; case A_ELEMSET: delete_elemset(mpl, value->set), value->set = NULL; break; case A_ELEMVAR: value->var = NULL; break; case A_FORMULA: delete_formula(mpl, value->form), value->form = NULL; break; case A_ELEMCON: value->con = NULL; break; default: xassert(type != type); } return; } /**********************************************************************/ /* * * SYMBOLICALLY INDEXED ARRAYS * * */ /**********************************************************************/ /*---------------------------------------------------------------------- -- create_array - create array. -- -- This routine creates an array of specified type and dimension. Being -- created the array is initially empty. -- -- The type indicator determines generic values, which can be assigned -- to the array members: -- -- A_NONE - none (members have no assigned values) -- A_NUMERIC - floating-point numbers -- A_SYMBOLIC - symbols -- A_ELEMSET - elemental sets -- A_ELEMVAR - elemental variables -- A_ELEMCON - elemental constraints -- -- The dimension may be 0, in which case the array consists of the only -- member (such arrays represent 0-dimensional objects). */ ARRAY *create_array(MPL *mpl, int type, int dim) { ARRAY *array; xassert(type == A_NONE || type == A_NUMERIC || type == A_SYMBOLIC || type == A_ELEMSET || type == A_ELEMVAR || type == A_ELEMCON); xassert(dim >= 0); array = dmp_get_atom(mpl->arrays, sizeof(ARRAY)); array->type = type; array->dim = dim; array->size = 0; array->head = NULL; array->tail = NULL; array->tree = NULL; array->prev = NULL; array->next = mpl->a_list; /* include the array in the global array list */ if (array->next != NULL) array->next->prev = array; mpl->a_list = array; return array; } /*---------------------------------------------------------------------- -- find_member - find array member with given n-tuple. -- -- This routine finds an array member, which has given n-tuple. If the -- array is short, the linear search is used. Otherwise the routine -- autimatically creates the search tree (i.e. the array index) to find -- members for logarithmic time. */ static int compare_member_tuples(void *info, const void *key1, const void *key2) { /* this is an auxiliary routine used to compare keys, which are n-tuples assigned to array members */ return compare_tuples((MPL *)info, (TUPLE *)key1, (TUPLE *)key2); } MEMBER *find_member ( MPL *mpl, ARRAY *array, /* not changed */ TUPLE *tuple /* not changed */ ) { MEMBER *memb; xassert(array != NULL); /* the n-tuple must have the same dimension as the array */ xassert(tuple_dimen(mpl, tuple) == array->dim); /* if the array is large enough, create the search tree and index all existing members of the array */ if (array->size > 30 && array->tree == NULL) { array->tree = avl_create_tree(compare_member_tuples, mpl); for (memb = array->head; memb != NULL; memb = memb->next) avl_set_node_link(avl_insert_node(array->tree, memb->tuple), (void *)memb); } /* find a member, which has the given tuple */ if (array->tree == NULL) { /* the search tree doesn't exist; use the linear search */ for (memb = array->head; memb != NULL; memb = memb->next) if (compare_tuples(mpl, memb->tuple, tuple) == 0) break; } else { /* the search tree exists; use the binary search */ AVLNODE *node; node = avl_find_node(array->tree, tuple); memb = (MEMBER *)(node == NULL ? NULL : avl_get_node_link(node)); } return memb; } /*---------------------------------------------------------------------- -- add_member - add new member to array. -- -- This routine creates a new member with given n-tuple and adds it to -- specified array. -- -- For the sake of efficiency this routine doesn't check whether the -- array already contains a member with the given n-tuple or not. Thus, -- if necessary, the calling program should use the routine find_member -- in order to be sure that the array contains no member with the same -- n-tuple, because members with duplicate n-tuples are not allowed. -- -- This routine assigns no generic value to the new member, because the -- calling program must do that. */ MEMBER *add_member ( MPL *mpl, ARRAY *array, /* modified */ TUPLE *tuple /* destroyed */ ) { MEMBER *memb; xassert(array != NULL); /* the n-tuple must have the same dimension as the array */ xassert(tuple_dimen(mpl, tuple) == array->dim); /* create new member */ memb = dmp_get_atom(mpl->members, sizeof(MEMBER)); memb->tuple = tuple; memb->next = NULL; memset(&memb->value, '?', sizeof(VALUE)); /* and append it to the member list */ array->size++; if (array->head == NULL) array->head = memb; else array->tail->next = memb; array->tail = memb; /* if the search tree exists, index the new member */ if (array->tree != NULL) avl_set_node_link(avl_insert_node(array->tree, memb->tuple), (void *)memb); return memb; } /*---------------------------------------------------------------------- -- delete_array - delete array. -- -- This routine deletes specified array. -- -- Generic values assigned to the array members are not deleted by this -- routine. The calling program itself must delete all assigned generic -- values before deleting the array. */ void delete_array ( MPL *mpl, ARRAY *array /* destroyed */ ) { MEMBER *memb; xassert(array != NULL); /* delete all existing array members */ while (array->head != NULL) { memb = array->head; array->head = memb->next; delete_tuple(mpl, memb->tuple); dmp_free_atom(mpl->members, memb, sizeof(MEMBER)); } /* if the search tree exists, also delete it */ if (array->tree != NULL) avl_delete_tree(array->tree); /* remove the array from the global array list */ if (array->prev == NULL) mpl->a_list = array->next; else array->prev->next = array->next; if (array->next == NULL) ; else array->next->prev = array->prev; /* delete the array descriptor */ dmp_free_atom(mpl->arrays, array, sizeof(ARRAY)); return; } /**********************************************************************/ /* * * DOMAINS AND DUMMY INDICES * * */ /**********************************************************************/ /*---------------------------------------------------------------------- -- assign_dummy_index - assign new value to dummy index. -- -- This routine assigns new value to specified dummy index and, that is -- important, invalidates all temporary resultant values, which depends -- on that dummy index. */ void assign_dummy_index ( MPL *mpl, DOMAIN_SLOT *slot, /* modified */ SYMBOL *value /* not changed */ ) { CODE *leaf, *code; xassert(slot != NULL); xassert(value != NULL); /* delete the current value assigned to the dummy index */ if (slot->value != NULL) { /* if the current value and the new one are identical, actual assignment is not needed */ if (compare_symbols(mpl, slot->value, value) == 0) goto done; /* delete a symbol, which is the current value */ delete_symbol(mpl, slot->value), slot->value = NULL; } /* now walk through all the pseudo-codes with op = O_INDEX, which refer to the dummy index to be changed (these pseudo-codes are leaves in the forest of *all* expressions in the database) */ for (leaf = slot->list; leaf != NULL; leaf = leaf->arg.index. next) { xassert(leaf->op == O_INDEX); /* invalidate all resultant values, which depend on the dummy index, walking from the current leaf toward the root of the corresponding expression tree */ for (code = leaf; code != NULL; code = code->up) { if (code->valid) { /* invalidate and delete resultant value */ code->valid = 0; delete_value(mpl, code->type, &code->value); } } } /* assign new value to the dummy index */ slot->value = copy_symbol(mpl, value); done: return; } /*---------------------------------------------------------------------- -- update_dummy_indices - update current values of dummy indices. -- -- This routine assigns components of "backup" n-tuple to dummy indices -- of specified domain block. If no "backup" n-tuple is defined for the -- domain block, values of the dummy indices remain untouched. */ void update_dummy_indices ( MPL *mpl, DOMAIN_BLOCK *block /* not changed */ ) { DOMAIN_SLOT *slot; TUPLE *temp; if (block->backup != NULL) { for (slot = block->list, temp = block->backup; slot != NULL; slot = slot->next, temp = temp->next) { xassert(temp != NULL); xassert(temp->sym != NULL); assign_dummy_index(mpl, slot, temp->sym); } } return; } /*---------------------------------------------------------------------- -- enter_domain_block - enter domain block. -- -- Let specified domain block have the form: -- -- { ..., (j1, j2, ..., jn) in J, ... } -- -- where j1, j2, ..., jn are dummy indices, J is a basic set. -- -- This routine does the following: -- -- 1. Checks if the given n-tuple is a member of the basic set J. Note -- that J being *out of the scope* of the domain block cannot depend -- on the dummy indices in the same and inner domain blocks, so it -- can be computed before the dummy indices are assigned new values. -- If this check fails, the routine returns with non-zero code. -- -- 2. Saves current values of the dummy indices j1, j2, ..., jn. -- -- 3. Assigns new values, which are components of the given n-tuple, to -- the dummy indices j1, j2, ..., jn. If dimension of the n-tuple is -- larger than n, its extra components n+1, n+2, ... are not used. -- -- 4. Calls the formal routine func which either enters the next domain -- block or evaluates some code within the domain scope. -- -- 5. Restores former values of the dummy indices j1, j2, ..., jn. -- -- Since current values assigned to the dummy indices on entry to this -- routine are restored on exit, the formal routine func is allowed to -- call this routine recursively. */ int enter_domain_block ( MPL *mpl, DOMAIN_BLOCK *block, /* not changed */ TUPLE *tuple, /* not changed */ void *info, void (*func)(MPL *mpl, void *info) ) { TUPLE *backup; int ret = 0; /* check if the given n-tuple is a member of the basic set */ xassert(block->code != NULL); if (!is_member(mpl, block->code, tuple)) { ret = 1; goto done; } /* save reference to "backup" n-tuple, which was used to assign current values of the dummy indices (it is sufficient to save reference, not value, because that n-tuple is defined in some outer level of recursion and therefore cannot be changed on this and deeper recursive calls) */ backup = block->backup; /* set up new "backup" n-tuple, which defines new values of the dummy indices */ block->backup = tuple; /* assign new values to the dummy indices */ update_dummy_indices(mpl, block); /* call the formal routine that does the rest part of the job */ func(mpl, info); /* restore reference to the former "backup" n-tuple */ block->backup = backup; /* restore former values of the dummy indices; note that if the domain block just escaped has no other active instances which may exist due to recursion (it is indicated by a null pointer to the former n-tuple), former values of the dummy indices are undefined; therefore in this case the routine keeps currently assigned values of the dummy indices that involves keeping all dependent temporary results and thereby, if this domain block is not used recursively, allows improving efficiency */ update_dummy_indices(mpl, block); done: return ret; } /*---------------------------------------------------------------------- -- eval_within_domain - perform evaluation within domain scope. -- -- This routine assigns new values (symbols) to all dummy indices of -- specified domain and calls the formal routine func, which is used to -- evaluate some code in the domain scope. Each free dummy index in the -- domain is assigned a value specified in the corresponding component -- of given n-tuple. Non-free dummy indices are assigned values, which -- are computed by this routine. -- -- Number of components in the given n-tuple must be the same as number -- of free indices in the domain. -- -- If the given n-tuple is not a member of the domain set, the routine -- func is not called, and non-zero code is returned. -- -- For the sake of convenience it is allowed to specify domain as NULL -- (then n-tuple also must be 0-tuple, i.e. empty), in which case this -- routine just calls the routine func and returns zero. -- -- This routine allows recursive calls from the routine func providing -- correct values of dummy indices for each instance. -- -- NOTE: The n-tuple passed to this routine must not be changed by any -- other routines called from the formal routine func until this -- routine has returned. */ struct eval_domain_info { /* working info used by the routine eval_within_domain */ DOMAIN *domain; /* domain, which has to be entered */ DOMAIN_BLOCK *block; /* domain block, which is currently processed */ TUPLE *tuple; /* tail of original n-tuple, whose components have to be assigned to free dummy indices in the current domain block */ void *info; /* transit pointer passed to the formal routine func */ void (*func)(MPL *mpl, void *info); /* routine, which has to be executed in the domain scope */ int failure; /* this flag indicates that given n-tuple is not a member of the domain set */ }; static void eval_domain_func(MPL *mpl, void *_my_info) { /* this routine recursively enters into the domain scope and then calls the routine func */ struct eval_domain_info *my_info = _my_info; if (my_info->block != NULL) { /* the current domain block to be entered exists */ DOMAIN_BLOCK *block; DOMAIN_SLOT *slot; TUPLE *tuple = NULL, *temp = NULL; /* save pointer to the current domain block */ block = my_info->block; /* and get ready to enter the next block (if it exists) */ my_info->block = block->next; /* construct temporary n-tuple, whose components correspond to dummy indices (slots) of the current domain; components of the temporary n-tuple that correspond to free dummy indices are assigned references (not values!) to symbols specified in the corresponding components of the given n-tuple, while other components that correspond to non-free dummy indices are assigned symbolic values computed here */ for (slot = block->list; slot != NULL; slot = slot->next) { /* create component that corresponds to the current slot */ if (tuple == NULL) tuple = temp = dmp_get_atom(mpl->tuples, sizeof(TUPLE)); else temp = (temp->next = dmp_get_atom(mpl->tuples, sizeof(TUPLE))); if (slot->code == NULL) { /* dummy index is free; take reference to symbol, which is specified in the corresponding component of given n-tuple */ xassert(my_info->tuple != NULL); temp->sym = my_info->tuple->sym; xassert(temp->sym != NULL); my_info->tuple = my_info->tuple->next; } else { /* dummy index is non-free; compute symbolic value to be temporarily assigned to the dummy index */ temp->sym = eval_symbolic(mpl, slot->code); } } temp->next = NULL; /* enter the current domain block */ if (enter_domain_block(mpl, block, tuple, my_info, eval_domain_func)) my_info->failure = 1; /* delete temporary n-tuple as well as symbols that correspond to non-free dummy indices (they were computed here) */ for (slot = block->list; slot != NULL; slot = slot->next) { xassert(tuple != NULL); temp = tuple; tuple = tuple->next; if (slot->code != NULL) { /* dummy index is non-free; delete symbolic value */ delete_symbol(mpl, temp->sym); } /* delete component that corresponds to the current slot */ dmp_free_atom(mpl->tuples, temp, sizeof(TUPLE)); } } else { /* there are no more domain blocks, i.e. we have reached the domain scope */ xassert(my_info->tuple == NULL); /* check optional predicate specified for the domain */ if (my_info->domain->code != NULL && !eval_logical(mpl, my_info->domain->code)) { /* the predicate is false */ my_info->failure = 2; } else { /* the predicate is true; do the job */ my_info->func(mpl, my_info->info); } } return; } int eval_within_domain ( MPL *mpl, DOMAIN *domain, /* not changed */ TUPLE *tuple, /* not changed */ void *info, void (*func)(MPL *mpl, void *info) ) { /* this routine performs evaluation within domain scope */ struct eval_domain_info _my_info, *my_info = &_my_info; if (domain == NULL) { xassert(tuple == NULL); func(mpl, info); my_info->failure = 0; } else { xassert(tuple != NULL); my_info->domain = domain; my_info->block = domain->list; my_info->tuple = tuple; my_info->info = info; my_info->func = func; my_info->failure = 0; /* enter the very first domain block */ eval_domain_func(mpl, my_info); } return my_info->failure; } /*---------------------------------------------------------------------- -- loop_within_domain - perform iterations within domain scope. -- -- This routine iteratively assigns new values (symbols) to the dummy -- indices of specified domain by enumerating all n-tuples, which are -- members of the domain set, and for every n-tuple it calls the formal -- routine func to evaluate some code within the domain scope. -- -- If the routine func returns non-zero, enumeration within the domain -- is prematurely terminated. -- -- For the sake of convenience it is allowed to specify domain as NULL, -- in which case this routine just calls the routine func only once and -- returns zero. -- -- This routine allows recursive calls from the routine func providing -- correct values of dummy indices for each instance. */ struct loop_domain_info { /* working info used by the routine loop_within_domain */ DOMAIN *domain; /* domain, which has to be entered */ DOMAIN_BLOCK *block; /* domain block, which is currently processed */ int looping; /* clearing this flag leads to terminating enumeration */ void *info; /* transit pointer passed to the formal routine func */ int (*func)(MPL *mpl, void *info); /* routine, which needs to be executed in the domain scope */ }; static void loop_domain_func(MPL *mpl, void *_my_info) { /* this routine enumerates all n-tuples in the basic set of the current domain block, enters recursively into the domain scope for every n-tuple, and then calls the routine func */ struct loop_domain_info *my_info = _my_info; if (my_info->block != NULL) { /* the current domain block to be entered exists */ DOMAIN_BLOCK *block; DOMAIN_SLOT *slot; TUPLE *bound; /* save pointer to the current domain block */ block = my_info->block; /* and get ready to enter the next block (if it exists) */ my_info->block = block->next; /* compute symbolic values, at which non-free dummy indices of the current domain block are bound; since that values don't depend on free dummy indices of the current block, they can be computed once out of the enumeration loop */ bound = create_tuple(mpl); for (slot = block->list; slot != NULL; slot = slot->next) { if (slot->code != NULL) bound = expand_tuple(mpl, bound, eval_symbolic(mpl, slot->code)); } /* start enumeration */ xassert(block->code != NULL); if (block->code->op == O_DOTS) { /* the basic set is "arithmetic", in which case it doesn't need to be computed explicitly */ TUPLE *tuple; int n, j; double t0, tf, dt; /* compute "parameters" of the basic set */ t0 = eval_numeric(mpl, block->code->arg.arg.x); tf = eval_numeric(mpl, block->code->arg.arg.y); if (block->code->arg.arg.z == NULL) dt = 1.0; else dt = eval_numeric(mpl, block->code->arg.arg.z); /* determine cardinality of the basic set */ n = arelset_size(mpl, t0, tf, dt); /* create dummy 1-tuple for members of the basic set */ tuple = expand_tuple(mpl, create_tuple(mpl), create_symbol_num(mpl, 0.0)); /* in case of "arithmetic" set there is exactly one dummy index, which cannot be non-free */ xassert(bound == NULL); /* walk through 1-tuples of the basic set */ for (j = 1; j <= n && my_info->looping; j++) { /* construct dummy 1-tuple for the current member */ tuple->sym->num = arelset_member(mpl, t0, tf, dt, j); /* enter the current domain block */ enter_domain_block(mpl, block, tuple, my_info, loop_domain_func); } /* delete dummy 1-tuple */ delete_tuple(mpl, tuple); } else { /* the basic set is of general kind, in which case it needs to be explicitly computed */ ELEMSET *set; MEMBER *memb; TUPLE *temp1, *temp2; /* compute the basic set */ set = eval_elemset(mpl, block->code); /* walk through all n-tuples of the basic set */ for (memb = set->head; memb != NULL && my_info->looping; memb = memb->next) { /* all components of the current n-tuple that correspond to non-free dummy indices must be feasible; otherwise the n-tuple is not in the basic set */ temp1 = memb->tuple; temp2 = bound; for (slot = block->list; slot != NULL; slot = slot->next) { xassert(temp1 != NULL); if (slot->code != NULL) { /* non-free dummy index */ xassert(temp2 != NULL); if (compare_symbols(mpl, temp1->sym, temp2->sym) != 0) { /* the n-tuple is not in the basic set */ goto skip; } temp2 = temp2->next; } temp1 = temp1->next; } xassert(temp1 == NULL); xassert(temp2 == NULL); /* enter the current domain block */ enter_domain_block(mpl, block, memb->tuple, my_info, loop_domain_func); skip: ; } /* delete the basic set */ delete_elemset(mpl, set); } /* delete symbolic values binding non-free dummy indices */ delete_tuple(mpl, bound); /* restore pointer to the current domain block */ my_info->block = block; } else { /* there are no more domain blocks, i.e. we have reached the domain scope */ /* check optional predicate specified for the domain */ if (my_info->domain->code != NULL && !eval_logical(mpl, my_info->domain->code)) { /* the predicate is false */ /* nop */; } else { /* the predicate is true; do the job */ my_info->looping = !my_info->func(mpl, my_info->info); } } return; } void loop_within_domain ( MPL *mpl, DOMAIN *domain, /* not changed */ void *info, int (*func)(MPL *mpl, void *info) ) { /* this routine performs iterations within domain scope */ struct loop_domain_info _my_info, *my_info = &_my_info; if (domain == NULL) func(mpl, info); else { my_info->domain = domain; my_info->block = domain->list; my_info->looping = 1; my_info->info = info; my_info->func = func; /* enter the very first domain block */ loop_domain_func(mpl, my_info); } return; } /*---------------------------------------------------------------------- -- out_of_domain - raise domain exception. -- -- This routine is called when a reference is made to a member of some -- model object, but its n-tuple is out of the object domain. */ void out_of_domain ( MPL *mpl, char *name, /* not changed */ TUPLE *tuple /* not changed */ ) { xassert(name != NULL); xassert(tuple != NULL); mpl_error(mpl, "%s%s out of domain", name, format_tuple(mpl, '[', tuple)); /* no return */ } /*---------------------------------------------------------------------- -- get_domain_tuple - obtain current n-tuple from domain. -- -- This routine constructs n-tuple, whose components are current values -- assigned to *free* dummy indices of specified domain. -- -- For the sake of convenience it is allowed to specify domain as NULL, -- in which case this routine returns 0-tuple. -- -- NOTE: This routine must not be called out of domain scope. */ TUPLE *get_domain_tuple ( MPL *mpl, DOMAIN *domain /* not changed */ ) { DOMAIN_BLOCK *block; DOMAIN_SLOT *slot; TUPLE *tuple; tuple = create_tuple(mpl); if (domain != NULL) { for (block = domain->list; block != NULL; block = block->next) { for (slot = block->list; slot != NULL; slot = slot->next) { if (slot->code == NULL) { xassert(slot->value != NULL); tuple = expand_tuple(mpl, tuple, copy_symbol(mpl, slot->value)); } } } } return tuple; } /*---------------------------------------------------------------------- -- clean_domain - clean domain. -- -- This routine cleans specified domain that assumes deleting all stuff -- dynamically allocated during the generation phase. */ void clean_domain(MPL *mpl, DOMAIN *domain) { DOMAIN_BLOCK *block; DOMAIN_SLOT *slot; /* if no domain is specified, do nothing */ if (domain == NULL) goto done; /* clean all domain blocks */ for (block = domain->list; block != NULL; block = block->next) { /* clean all domain slots */ for (slot = block->list; slot != NULL; slot = slot->next) { /* clean pseudo-code for computing bound value */ clean_code(mpl, slot->code); /* delete symbolic value assigned to dummy index */ if (slot->value != NULL) delete_symbol(mpl, slot->value), slot->value = NULL; } /* clean pseudo-code for computing basic set */ clean_code(mpl, block->code); } /* clean pseudo-code for computing domain predicate */ clean_code(mpl, domain->code); done: return; } /**********************************************************************/ /* * * MODEL SETS * * */ /**********************************************************************/ /*---------------------------------------------------------------------- -- check_elem_set - check elemental set assigned to set member. -- -- This routine checks if given elemental set being assigned to member -- of specified model set satisfies to all restrictions. -- -- NOTE: This routine must not be called out of domain scope. */ void check_elem_set ( MPL *mpl, SET *set, /* not changed */ TUPLE *tuple, /* not changed */ ELEMSET *refer /* not changed */ ) { WITHIN *within; MEMBER *memb; int eqno; /* elemental set must be within all specified supersets */ for (within = set->within, eqno = 1; within != NULL; within = within->next, eqno++) { xassert(within->code != NULL); for (memb = refer->head; memb != NULL; memb = memb->next) { if (!is_member(mpl, within->code, memb->tuple)) { char buf[255+1]; strcpy(buf, format_tuple(mpl, '(', memb->tuple)); xassert(strlen(buf) < sizeof(buf)); mpl_error(mpl, "%s%s contains %s which not within specified " "set; see (%d)", set->name, format_tuple(mpl, '[', tuple), buf, eqno); } } } return; } /*---------------------------------------------------------------------- -- take_member_set - obtain elemental set assigned to set member. -- -- This routine obtains a reference to elemental set assigned to given -- member of specified model set and returns it on exit. -- -- NOTE: This routine must not be called out of domain scope. */ ELEMSET *take_member_set /* returns reference, not value */ ( MPL *mpl, SET *set, /* not changed */ TUPLE *tuple /* not changed */ ) { MEMBER *memb; ELEMSET *refer; /* find member in the set array */ memb = find_member(mpl, set->array, tuple); if (memb != NULL) { /* member exists, so just take the reference */ refer = memb->value.set; } else if (set->assign != NULL) { /* compute value using assignment expression */ refer = eval_elemset(mpl, set->assign); add: /* check that the elemental set satisfies to all restrictions, assign it to new member, and add the member to the array */ check_elem_set(mpl, set, tuple, refer); memb = add_member(mpl, set->array, copy_tuple(mpl, tuple)); memb->value.set = refer; } else if (set->option != NULL) { /* compute default elemental set */ refer = eval_elemset(mpl, set->option); goto add; } else { /* no value (elemental set) is provided */ mpl_error(mpl, "no value for %s%s", set->name, format_tuple(mpl, '[', tuple)); } return refer; } /*---------------------------------------------------------------------- -- eval_member_set - evaluate elemental set assigned to set member. -- -- This routine evaluates a reference to elemental set assigned to given -- member of specified model set and returns it on exit. */ struct eval_set_info { /* working info used by the routine eval_member_set */ SET *set; /* model set */ TUPLE *tuple; /* n-tuple, which defines set member */ MEMBER *memb; /* normally this pointer is NULL; the routine uses this pointer to check data provided in the data section, in which case it points to a member currently checked; this check is performed automatically only once when a reference to any member occurs for the first time */ ELEMSET *refer; /* evaluated reference to elemental set */ }; static void eval_set_func(MPL *mpl, void *_info) { /* this is auxiliary routine to work within domain scope */ struct eval_set_info *info = _info; if (info->memb != NULL) { /* checking call; check elemental set being assigned */ check_elem_set(mpl, info->set, info->memb->tuple, info->memb->value.set); } else { /* normal call; evaluate member, which has given n-tuple */ info->refer = take_member_set(mpl, info->set, info->tuple); } return; } #if 1 /* 12/XII-2008 */ static void saturate_set(MPL *mpl, SET *set) { GADGET *gadget = set->gadget; ELEMSET *data; MEMBER *elem, *memb; TUPLE *tuple, *work[20]; int i; xprintf("Generating %s...\n", set->name); eval_whole_set(mpl, gadget->set); /* gadget set must have exactly one member */ xassert(gadget->set->array != NULL); xassert(gadget->set->array->head != NULL); xassert(gadget->set->array->head == gadget->set->array->tail); data = gadget->set->array->head->value.set; xassert(data->type == A_NONE); xassert(data->dim == gadget->set->dimen); /* walk thru all elements of the plain set */ for (elem = data->head; elem != NULL; elem = elem->next) { /* create a copy of n-tuple */ tuple = copy_tuple(mpl, elem->tuple); /* rearrange component of the n-tuple */ for (i = 0; i < gadget->set->dimen; i++) work[i] = NULL; for (i = 0; tuple != NULL; tuple = tuple->next) work[gadget->ind[i++]-1] = tuple; xassert(i == gadget->set->dimen); for (i = 0; i < gadget->set->dimen; i++) { xassert(work[i] != NULL); work[i]->next = work[i+1]; } /* construct subscript list from first set->dim components */ if (set->dim == 0) tuple = NULL; else tuple = work[0], work[set->dim-1]->next = NULL; /* find corresponding member of the set to be initialized */ memb = find_member(mpl, set->array, tuple); if (memb == NULL) { /* not found; add new member to the set and assign it empty elemental set */ memb = add_member(mpl, set->array, tuple); memb->value.set = create_elemset(mpl, set->dimen); } else { /* found; free subscript list */ delete_tuple(mpl, tuple); } /* construct new n-tuple from rest set->dimen components */ tuple = work[set->dim]; xassert(set->dim + set->dimen == gadget->set->dimen); work[gadget->set->dimen-1]->next = NULL; /* and add it to the elemental set assigned to the member (no check for duplicates is needed) */ add_tuple(mpl, memb->value.set, tuple); } /* the set has been saturated with data */ set->data = 1; return; } #endif ELEMSET *eval_member_set /* returns reference, not value */ ( MPL *mpl, SET *set, /* not changed */ TUPLE *tuple /* not changed */ ) { /* this routine evaluates set member */ struct eval_set_info _info, *info = &_info; xassert(set->dim == tuple_dimen(mpl, tuple)); info->set = set; info->tuple = tuple; #if 1 /* 12/XII-2008 */ if (set->gadget != NULL && set->data == 0) { /* initialize the set with data from a plain set */ saturate_set(mpl, set); } #endif if (set->data == 1) { /* check data, which are provided in the data section, but not checked yet */ /* save pointer to the last array member; note that during the check new members may be added beyond the last member due to references to the same parameter from default expression as well as from expressions that define restricting supersets; however, values assigned to the new members will be checked by other routine, so we don't need to check them here */ MEMBER *tail = set->array->tail; /* change the data status to prevent infinite recursive loop due to references to the same set during the check */ set->data = 2; /* check elemental sets assigned to array members in the data section until the marked member has been reached */ for (info->memb = set->array->head; info->memb != NULL; info->memb = info->memb->next) { if (eval_within_domain(mpl, set->domain, info->memb->tuple, info, eval_set_func)) out_of_domain(mpl, set->name, info->memb->tuple); if (info->memb == tail) break; } /* the check has been finished */ } /* evaluate member, which has given n-tuple */ info->memb = NULL; if (eval_within_domain(mpl, info->set->domain, info->tuple, info, eval_set_func)) out_of_domain(mpl, set->name, info->tuple); /* bring evaluated reference to the calling program */ return info->refer; } /*---------------------------------------------------------------------- -- eval_whole_set - evaluate model set over entire domain. -- -- This routine evaluates all members of specified model set over entire -- domain. */ static int whole_set_func(MPL *mpl, void *info) { /* this is auxiliary routine to work within domain scope */ SET *set = (SET *)info; TUPLE *tuple = get_domain_tuple(mpl, set->domain); eval_member_set(mpl, set, tuple); delete_tuple(mpl, tuple); return 0; } void eval_whole_set(MPL *mpl, SET *set) { loop_within_domain(mpl, set->domain, set, whole_set_func); return; } /*---------------------------------------------------------------------- -- clean set - clean model set. -- -- This routine cleans specified model set that assumes deleting all -- stuff dynamically allocated during the generation phase. */ void clean_set(MPL *mpl, SET *set) { WITHIN *within; MEMBER *memb; /* clean subscript domain */ clean_domain(mpl, set->domain); /* clean pseudo-code for computing supersets */ for (within = set->within; within != NULL; within = within->next) clean_code(mpl, within->code); /* clean pseudo-code for computing assigned value */ clean_code(mpl, set->assign); /* clean pseudo-code for computing default value */ clean_code(mpl, set->option); /* reset data status flag */ set->data = 0; /* delete content array */ for (memb = set->array->head; memb != NULL; memb = memb->next) delete_value(mpl, set->array->type, &memb->value); delete_array(mpl, set->array), set->array = NULL; return; } /**********************************************************************/ /* * * MODEL PARAMETERS * * */ /**********************************************************************/ /*---------------------------------------------------------------------- -- check_value_num - check numeric value assigned to parameter member. -- -- This routine checks if numeric value being assigned to some member -- of specified numeric model parameter satisfies to all restrictions. -- -- NOTE: This routine must not be called out of domain scope. */ void check_value_num ( MPL *mpl, PARAMETER *par, /* not changed */ TUPLE *tuple, /* not changed */ double value ) { CONDITION *cond; WITHIN *in; int eqno; /* the value must satisfy to the parameter type */ switch (par->type) { case A_NUMERIC: break; case A_INTEGER: if (value != floor(value)) mpl_error(mpl, "%s%s = %.*g not integer", par->name, format_tuple(mpl, '[', tuple), DBL_DIG, value); break; case A_BINARY: if (!(value == 0.0 || value == 1.0)) mpl_error(mpl, "%s%s = %.*g not binary", par->name, format_tuple(mpl, '[', tuple), DBL_DIG, value); break; default: xassert(par != par); } /* the value must satisfy to all specified conditions */ for (cond = par->cond, eqno = 1; cond != NULL; cond = cond->next, eqno++) { double bound; char *rho; xassert(cond->code != NULL); bound = eval_numeric(mpl, cond->code); switch (cond->rho) { case O_LT: if (!(value < bound)) { rho = "<"; err: mpl_error(mpl, "%s%s = %.*g not %s %.*g; see (%d)", par->name, format_tuple(mpl, '[', tuple), DBL_DIG, value, rho, DBL_DIG, bound, eqno); } break; case O_LE: if (!(value <= bound)) { rho = "<="; goto err; } break; case O_EQ: if (!(value == bound)) { rho = "="; goto err; } break; case O_GE: if (!(value >= bound)) { rho = ">="; goto err; } break; case O_GT: if (!(value > bound)) { rho = ">"; goto err; } break; case O_NE: if (!(value != bound)) { rho = "<>"; goto err; } break; default: xassert(cond != cond); } } /* the value must be in all specified supersets */ for (in = par->in, eqno = 1; in != NULL; in = in->next, eqno++) { TUPLE *dummy; xassert(in->code != NULL); xassert(in->code->dim == 1); dummy = expand_tuple(mpl, create_tuple(mpl), create_symbol_num(mpl, value)); if (!is_member(mpl, in->code, dummy)) mpl_error(mpl, "%s%s = %.*g not in specified set; see (%d)", par->name, format_tuple(mpl, '[', tuple), DBL_DIG, value, eqno); delete_tuple(mpl, dummy); } return; } /*---------------------------------------------------------------------- -- take_member_num - obtain num. value assigned to parameter member. -- -- This routine obtains a numeric value assigned to member of specified -- numeric model parameter and returns it on exit. -- -- NOTE: This routine must not be called out of domain scope. */ double take_member_num ( MPL *mpl, PARAMETER *par, /* not changed */ TUPLE *tuple /* not changed */ ) { MEMBER *memb; double value; /* find member in the parameter array */ memb = find_member(mpl, par->array, tuple); if (memb != NULL) { /* member exists, so just take its value */ value = memb->value.num; } else if (par->assign != NULL) { /* compute value using assignment expression */ value = eval_numeric(mpl, par->assign); add: /* check that the value satisfies to all restrictions, assign it to new member, and add the member to the array */ check_value_num(mpl, par, tuple, value); memb = add_member(mpl, par->array, copy_tuple(mpl, tuple)); memb->value.num = value; } else if (par->option != NULL) { /* compute default value */ value = eval_numeric(mpl, par->option); goto add; } else if (par->defval != NULL) { /* take default value provided in the data section */ if (par->defval->str != NULL) mpl_error(mpl, "cannot convert %s to floating-point number", format_symbol(mpl, par->defval)); value = par->defval->num; goto add; } else { /* no value is provided */ mpl_error(mpl, "no value for %s%s", par->name, format_tuple(mpl, '[', tuple)); } return value; } /*---------------------------------------------------------------------- -- eval_member_num - evaluate num. value assigned to parameter member. -- -- This routine evaluates a numeric value assigned to given member of -- specified numeric model parameter and returns it on exit. */ struct eval_num_info { /* working info used by the routine eval_member_num */ PARAMETER *par; /* model parameter */ TUPLE *tuple; /* n-tuple, which defines parameter member */ MEMBER *memb; /* normally this pointer is NULL; the routine uses this pointer to check data provided in the data section, in which case it points to a member currently checked; this check is performed automatically only once when a reference to any member occurs for the first time */ double value; /* evaluated numeric value */ }; static void eval_num_func(MPL *mpl, void *_info) { /* this is auxiliary routine to work within domain scope */ struct eval_num_info *info = _info; if (info->memb != NULL) { /* checking call; check numeric value being assigned */ check_value_num(mpl, info->par, info->memb->tuple, info->memb->value.num); } else { /* normal call; evaluate member, which has given n-tuple */ info->value = take_member_num(mpl, info->par, info->tuple); } return; } double eval_member_num ( MPL *mpl, PARAMETER *par, /* not changed */ TUPLE *tuple /* not changed */ ) { /* this routine evaluates numeric parameter member */ struct eval_num_info _info, *info = &_info; xassert(par->type == A_NUMERIC || par->type == A_INTEGER || par->type == A_BINARY); xassert(par->dim == tuple_dimen(mpl, tuple)); info->par = par; info->tuple = tuple; if (par->data == 1) { /* check data, which are provided in the data section, but not checked yet */ /* save pointer to the last array member; note that during the check new members may be added beyond the last member due to references to the same parameter from default expression as well as from expressions that define restricting conditions; however, values assigned to the new members will be checked by other routine, so we don't need to check them here */ MEMBER *tail = par->array->tail; /* change the data status to prevent infinite recursive loop due to references to the same parameter during the check */ par->data = 2; /* check values assigned to array members in the data section until the marked member has been reached */ for (info->memb = par->array->head; info->memb != NULL; info->memb = info->memb->next) { if (eval_within_domain(mpl, par->domain, info->memb->tuple, info, eval_num_func)) out_of_domain(mpl, par->name, info->memb->tuple); if (info->memb == tail) break; } /* the check has been finished */ } /* evaluate member, which has given n-tuple */ info->memb = NULL; if (eval_within_domain(mpl, info->par->domain, info->tuple, info, eval_num_func)) out_of_domain(mpl, par->name, info->tuple); /* bring evaluated value to the calling program */ return info->value; } /*---------------------------------------------------------------------- -- check_value_sym - check symbolic value assigned to parameter member. -- -- This routine checks if symbolic value being assigned to some member -- of specified symbolic model parameter satisfies to all restrictions. -- -- NOTE: This routine must not be called out of domain scope. */ void check_value_sym ( MPL *mpl, PARAMETER *par, /* not changed */ TUPLE *tuple, /* not changed */ SYMBOL *value /* not changed */ ) { CONDITION *cond; WITHIN *in; int eqno; /* the value must satisfy to all specified conditions */ for (cond = par->cond, eqno = 1; cond != NULL; cond = cond->next, eqno++) { SYMBOL *bound; char buf[255+1]; xassert(cond->code != NULL); bound = eval_symbolic(mpl, cond->code); switch (cond->rho) { #if 1 /* 13/VIII-2008 */ case O_LT: if (!(compare_symbols(mpl, value, bound) < 0)) { strcpy(buf, format_symbol(mpl, bound)); xassert(strlen(buf) < sizeof(buf)); mpl_error(mpl, "%s%s = %s not < %s", par->name, format_tuple(mpl, '[', tuple), format_symbol(mpl, value), buf, eqno); } break; case O_LE: if (!(compare_symbols(mpl, value, bound) <= 0)) { strcpy(buf, format_symbol(mpl, bound)); xassert(strlen(buf) < sizeof(buf)); mpl_error(mpl, "%s%s = %s not <= %s", par->name, format_tuple(mpl, '[', tuple), format_symbol(mpl, value), buf, eqno); } break; #endif case O_EQ: if (!(compare_symbols(mpl, value, bound) == 0)) { strcpy(buf, format_symbol(mpl, bound)); xassert(strlen(buf) < sizeof(buf)); mpl_error(mpl, "%s%s = %s not = %s", par->name, format_tuple(mpl, '[', tuple), format_symbol(mpl, value), buf, eqno); } break; #if 1 /* 13/VIII-2008 */ case O_GE: if (!(compare_symbols(mpl, value, bound) >= 0)) { strcpy(buf, format_symbol(mpl, bound)); xassert(strlen(buf) < sizeof(buf)); mpl_error(mpl, "%s%s = %s not >= %s", par->name, format_tuple(mpl, '[', tuple), format_symbol(mpl, value), buf, eqno); } break; case O_GT: if (!(compare_symbols(mpl, value, bound) > 0)) { strcpy(buf, format_symbol(mpl, bound)); xassert(strlen(buf) < sizeof(buf)); mpl_error(mpl, "%s%s = %s not > %s", par->name, format_tuple(mpl, '[', tuple), format_symbol(mpl, value), buf, eqno); } break; #endif case O_NE: if (!(compare_symbols(mpl, value, bound) != 0)) { strcpy(buf, format_symbol(mpl, bound)); xassert(strlen(buf) < sizeof(buf)); mpl_error(mpl, "%s%s = %s not <> %s", par->name, format_tuple(mpl, '[', tuple), format_symbol(mpl, value), buf, eqno); } break; default: xassert(cond != cond); } delete_symbol(mpl, bound); } /* the value must be in all specified supersets */ for (in = par->in, eqno = 1; in != NULL; in = in->next, eqno++) { TUPLE *dummy; xassert(in->code != NULL); xassert(in->code->dim == 1); dummy = expand_tuple(mpl, create_tuple(mpl), copy_symbol(mpl, value)); if (!is_member(mpl, in->code, dummy)) mpl_error(mpl, "%s%s = %s not in specified set; see (%d)", par->name, format_tuple(mpl, '[', tuple), format_symbol(mpl, value), eqno); delete_tuple(mpl, dummy); } return; } /*---------------------------------------------------------------------- -- take_member_sym - obtain symb. value assigned to parameter member. -- -- This routine obtains a symbolic value assigned to member of specified -- symbolic model parameter and returns it on exit. -- -- NOTE: This routine must not be called out of domain scope. */ SYMBOL *take_member_sym /* returns value, not reference */ ( MPL *mpl, PARAMETER *par, /* not changed */ TUPLE *tuple /* not changed */ ) { MEMBER *memb; SYMBOL *value; /* find member in the parameter array */ memb = find_member(mpl, par->array, tuple); if (memb != NULL) { /* member exists, so just take its value */ value = copy_symbol(mpl, memb->value.sym); } else if (par->assign != NULL) { /* compute value using assignment expression */ value = eval_symbolic(mpl, par->assign); add: /* check that the value satisfies to all restrictions, assign it to new member, and add the member to the array */ check_value_sym(mpl, par, tuple, value); memb = add_member(mpl, par->array, copy_tuple(mpl, tuple)); memb->value.sym = copy_symbol(mpl, value); } else if (par->option != NULL) { /* compute default value */ value = eval_symbolic(mpl, par->option); goto add; } else if (par->defval != NULL) { /* take default value provided in the data section */ value = copy_symbol(mpl, par->defval); goto add; } else { /* no value is provided */ mpl_error(mpl, "no value for %s%s", par->name, format_tuple(mpl, '[', tuple)); } return value; } /*---------------------------------------------------------------------- -- eval_member_sym - evaluate symb. value assigned to parameter member. -- -- This routine evaluates a symbolic value assigned to given member of -- specified symbolic model parameter and returns it on exit. */ struct eval_sym_info { /* working info used by the routine eval_member_sym */ PARAMETER *par; /* model parameter */ TUPLE *tuple; /* n-tuple, which defines parameter member */ MEMBER *memb; /* normally this pointer is NULL; the routine uses this pointer to check data provided in the data section, in which case it points to a member currently checked; this check is performed automatically only once when a reference to any member occurs for the first time */ SYMBOL *value; /* evaluated symbolic value */ }; static void eval_sym_func(MPL *mpl, void *_info) { /* this is auxiliary routine to work within domain scope */ struct eval_sym_info *info = _info; if (info->memb != NULL) { /* checking call; check symbolic value being assigned */ check_value_sym(mpl, info->par, info->memb->tuple, info->memb->value.sym); } else { /* normal call; evaluate member, which has given n-tuple */ info->value = take_member_sym(mpl, info->par, info->tuple); } return; } SYMBOL *eval_member_sym /* returns value, not reference */ ( MPL *mpl, PARAMETER *par, /* not changed */ TUPLE *tuple /* not changed */ ) { /* this routine evaluates symbolic parameter member */ struct eval_sym_info _info, *info = &_info; xassert(par->type == A_SYMBOLIC); xassert(par->dim == tuple_dimen(mpl, tuple)); info->par = par; info->tuple = tuple; if (par->data == 1) { /* check data, which are provided in the data section, but not checked yet */ /* save pointer to the last array member; note that during the check new members may be added beyond the last member due to references to the same parameter from default expression as well as from expressions that define restricting conditions; however, values assigned to the new members will be checked by other routine, so we don't need to check them here */ MEMBER *tail = par->array->tail; /* change the data status to prevent infinite recursive loop due to references to the same parameter during the check */ par->data = 2; /* check values assigned to array members in the data section until the marked member has been reached */ for (info->memb = par->array->head; info->memb != NULL; info->memb = info->memb->next) { if (eval_within_domain(mpl, par->domain, info->memb->tuple, info, eval_sym_func)) out_of_domain(mpl, par->name, info->memb->tuple); if (info->memb == tail) break; } /* the check has been finished */ } /* evaluate member, which has given n-tuple */ info->memb = NULL; if (eval_within_domain(mpl, info->par->domain, info->tuple, info, eval_sym_func)) out_of_domain(mpl, par->name, info->tuple); /* bring evaluated value to the calling program */ return info->value; } /*---------------------------------------------------------------------- -- eval_whole_par - evaluate model parameter over entire domain. -- -- This routine evaluates all members of specified model parameter over -- entire domain. */ static int whole_par_func(MPL *mpl, void *info) { /* this is auxiliary routine to work within domain scope */ PARAMETER *par = (PARAMETER *)info; TUPLE *tuple = get_domain_tuple(mpl, par->domain); switch (par->type) { case A_NUMERIC: case A_INTEGER: case A_BINARY: eval_member_num(mpl, par, tuple); break; case A_SYMBOLIC: delete_symbol(mpl, eval_member_sym(mpl, par, tuple)); break; default: xassert(par != par); } delete_tuple(mpl, tuple); return 0; } void eval_whole_par(MPL *mpl, PARAMETER *par) { loop_within_domain(mpl, par->domain, par, whole_par_func); return; } /*---------------------------------------------------------------------- -- clean_parameter - clean model parameter. -- -- This routine cleans specified model parameter that assumes deleting -- all stuff dynamically allocated during the generation phase. */ void clean_parameter(MPL *mpl, PARAMETER *par) { CONDITION *cond; WITHIN *in; MEMBER *memb; /* clean subscript domain */ clean_domain(mpl, par->domain); /* clean pseudo-code for computing restricting conditions */ for (cond = par->cond; cond != NULL; cond = cond->next) clean_code(mpl, cond->code); /* clean pseudo-code for computing restricting supersets */ for (in = par->in; in != NULL; in = in->next) clean_code(mpl, in->code); /* clean pseudo-code for computing assigned value */ clean_code(mpl, par->assign); /* clean pseudo-code for computing default value */ clean_code(mpl, par->option); /* reset data status flag */ par->data = 0; /* delete default symbolic value */ if (par->defval != NULL) delete_symbol(mpl, par->defval), par->defval = NULL; /* delete content array */ for (memb = par->array->head; memb != NULL; memb = memb->next) delete_value(mpl, par->array->type, &memb->value); delete_array(mpl, par->array), par->array = NULL; return; } /**********************************************************************/ /* * * MODEL VARIABLES * * */ /**********************************************************************/ /*---------------------------------------------------------------------- -- take_member_var - obtain reference to elemental variable. -- -- This routine obtains a reference to elemental variable assigned to -- given member of specified model variable and returns it on exit. If -- necessary, new elemental variable is created. -- -- NOTE: This routine must not be called out of domain scope. */ ELEMVAR *take_member_var /* returns reference */ ( MPL *mpl, VARIABLE *var, /* not changed */ TUPLE *tuple /* not changed */ ) { MEMBER *memb; ELEMVAR *refer; /* find member in the variable array */ memb = find_member(mpl, var->array, tuple); if (memb != NULL) { /* member exists, so just take the reference */ refer = memb->value.var; } else { /* member is referenced for the first time and therefore does not exist; create new elemental variable, assign it to new member, and add the member to the variable array */ memb = add_member(mpl, var->array, copy_tuple(mpl, tuple)); refer = (memb->value.var = dmp_get_atom(mpl->elemvars, sizeof(ELEMVAR))); refer->j = 0; refer->var = var; refer->memb = memb; /* compute lower bound */ if (var->lbnd == NULL) refer->lbnd = 0.0; else refer->lbnd = eval_numeric(mpl, var->lbnd); /* compute upper bound */ if (var->ubnd == NULL) refer->ubnd = 0.0; else if (var->ubnd == var->lbnd) refer->ubnd = refer->lbnd; else refer->ubnd = eval_numeric(mpl, var->ubnd); /* nullify working quantity */ refer->temp = 0.0; #if 1 /* 15/V-2010 */ /* solution has not been obtained by the solver yet */ refer->stat = 0; refer->prim = refer->dual = 0.0; #endif } return refer; } /*---------------------------------------------------------------------- -- eval_member_var - evaluate reference to elemental variable. -- -- This routine evaluates a reference to elemental variable assigned to -- member of specified model variable and returns it on exit. */ struct eval_var_info { /* working info used by the routine eval_member_var */ VARIABLE *var; /* model variable */ TUPLE *tuple; /* n-tuple, which defines variable member */ ELEMVAR *refer; /* evaluated reference to elemental variable */ }; static void eval_var_func(MPL *mpl, void *_info) { /* this is auxiliary routine to work within domain scope */ struct eval_var_info *info = _info; info->refer = take_member_var(mpl, info->var, info->tuple); return; } ELEMVAR *eval_member_var /* returns reference */ ( MPL *mpl, VARIABLE *var, /* not changed */ TUPLE *tuple /* not changed */ ) { /* this routine evaluates variable member */ struct eval_var_info _info, *info = &_info; xassert(var->dim == tuple_dimen(mpl, tuple)); info->var = var; info->tuple = tuple; /* evaluate member, which has given n-tuple */ if (eval_within_domain(mpl, info->var->domain, info->tuple, info, eval_var_func)) out_of_domain(mpl, var->name, info->tuple); /* bring evaluated reference to the calling program */ return info->refer; } /*---------------------------------------------------------------------- -- eval_whole_var - evaluate model variable over entire domain. -- -- This routine evaluates all members of specified model variable over -- entire domain. */ static int whole_var_func(MPL *mpl, void *info) { /* this is auxiliary routine to work within domain scope */ VARIABLE *var = (VARIABLE *)info; TUPLE *tuple = get_domain_tuple(mpl, var->domain); eval_member_var(mpl, var, tuple); delete_tuple(mpl, tuple); return 0; } void eval_whole_var(MPL *mpl, VARIABLE *var) { loop_within_domain(mpl, var->domain, var, whole_var_func); return; } /*---------------------------------------------------------------------- -- clean_variable - clean model variable. -- -- This routine cleans specified model variable that assumes deleting -- all stuff dynamically allocated during the generation phase. */ void clean_variable(MPL *mpl, VARIABLE *var) { MEMBER *memb; /* clean subscript domain */ clean_domain(mpl, var->domain); /* clean code for computing lower bound */ clean_code(mpl, var->lbnd); /* clean code for computing upper bound */ if (var->ubnd != var->lbnd) clean_code(mpl, var->ubnd); /* delete content array */ for (memb = var->array->head; memb != NULL; memb = memb->next) dmp_free_atom(mpl->elemvars, memb->value.var, sizeof(ELEMVAR)); delete_array(mpl, var->array), var->array = NULL; return; } /**********************************************************************/ /* * * MODEL CONSTRAINTS AND OBJECTIVES * * */ /**********************************************************************/ /*---------------------------------------------------------------------- -- take_member_con - obtain reference to elemental constraint. -- -- This routine obtains a reference to elemental constraint assigned -- to given member of specified model constraint and returns it on exit. -- If necessary, new elemental constraint is created. -- -- NOTE: This routine must not be called out of domain scope. */ ELEMCON *take_member_con /* returns reference */ ( MPL *mpl, CONSTRAINT *con, /* not changed */ TUPLE *tuple /* not changed */ ) { MEMBER *memb; ELEMCON *refer; /* find member in the constraint array */ memb = find_member(mpl, con->array, tuple); if (memb != NULL) { /* member exists, so just take the reference */ refer = memb->value.con; } else { /* member is referenced for the first time and therefore does not exist; create new elemental constraint, assign it to new member, and add the member to the constraint array */ memb = add_member(mpl, con->array, copy_tuple(mpl, tuple)); refer = (memb->value.con = dmp_get_atom(mpl->elemcons, sizeof(ELEMCON))); refer->i = 0; refer->con = con; refer->memb = memb; /* compute linear form */ xassert(con->code != NULL); refer->form = eval_formula(mpl, con->code); /* compute lower and upper bounds */ if (con->lbnd == NULL && con->ubnd == NULL) { /* objective has no bounds */ double temp; xassert(con->type == A_MINIMIZE || con->type == A_MAXIMIZE); /* carry the constant term to the right-hand side */ refer->form = remove_constant(mpl, refer->form, &temp); refer->lbnd = refer->ubnd = - temp; } else if (con->lbnd != NULL && con->ubnd == NULL) { /* constraint a * x + b >= c * y + d is transformed to the standard form a * x - c * y >= d - b */ double temp; xassert(con->type == A_CONSTRAINT); refer->form = linear_comb(mpl, +1.0, refer->form, -1.0, eval_formula(mpl, con->lbnd)); refer->form = remove_constant(mpl, refer->form, &temp); refer->lbnd = - temp; refer->ubnd = 0.0; } else if (con->lbnd == NULL && con->ubnd != NULL) { /* constraint a * x + b <= c * y + d is transformed to the standard form a * x - c * y <= d - b */ double temp; xassert(con->type == A_CONSTRAINT); refer->form = linear_comb(mpl, +1.0, refer->form, -1.0, eval_formula(mpl, con->ubnd)); refer->form = remove_constant(mpl, refer->form, &temp); refer->lbnd = 0.0; refer->ubnd = - temp; } else if (con->lbnd == con->ubnd) { /* constraint a * x + b = c * y + d is transformed to the standard form a * x - c * y = d - b */ double temp; xassert(con->type == A_CONSTRAINT); refer->form = linear_comb(mpl, +1.0, refer->form, -1.0, eval_formula(mpl, con->lbnd)); refer->form = remove_constant(mpl, refer->form, &temp); refer->lbnd = refer->ubnd = - temp; } else { /* ranged constraint c <= a * x + b <= d is transformed to the standard form c - b <= a * x <= d - b */ double temp, temp1, temp2; xassert(con->type == A_CONSTRAINT); refer->form = remove_constant(mpl, refer->form, &temp); xassert(remove_constant(mpl, eval_formula(mpl, con->lbnd), &temp1) == NULL); xassert(remove_constant(mpl, eval_formula(mpl, con->ubnd), &temp2) == NULL); refer->lbnd = fp_sub(mpl, temp1, temp); refer->ubnd = fp_sub(mpl, temp2, temp); } #if 1 /* 15/V-2010 */ /* solution has not been obtained by the solver yet */ refer->stat = 0; refer->prim = refer->dual = 0.0; #endif } return refer; } /*---------------------------------------------------------------------- -- eval_member_con - evaluate reference to elemental constraint. -- -- This routine evaluates a reference to elemental constraint assigned -- to member of specified model constraint and returns it on exit. */ struct eval_con_info { /* working info used by the routine eval_member_con */ CONSTRAINT *con; /* model constraint */ TUPLE *tuple; /* n-tuple, which defines constraint member */ ELEMCON *refer; /* evaluated reference to elemental constraint */ }; static void eval_con_func(MPL *mpl, void *_info) { /* this is auxiliary routine to work within domain scope */ struct eval_con_info *info = _info; info->refer = take_member_con(mpl, info->con, info->tuple); return; } ELEMCON *eval_member_con /* returns reference */ ( MPL *mpl, CONSTRAINT *con, /* not changed */ TUPLE *tuple /* not changed */ ) { /* this routine evaluates constraint member */ struct eval_con_info _info, *info = &_info; xassert(con->dim == tuple_dimen(mpl, tuple)); info->con = con; info->tuple = tuple; /* evaluate member, which has given n-tuple */ if (eval_within_domain(mpl, info->con->domain, info->tuple, info, eval_con_func)) out_of_domain(mpl, con->name, info->tuple); /* bring evaluated reference to the calling program */ return info->refer; } /*---------------------------------------------------------------------- -- eval_whole_con - evaluate model constraint over entire domain. -- -- This routine evaluates all members of specified model constraint over -- entire domain. */ static int whole_con_func(MPL *mpl, void *info) { /* this is auxiliary routine to work within domain scope */ CONSTRAINT *con = (CONSTRAINT *)info; TUPLE *tuple = get_domain_tuple(mpl, con->domain); eval_member_con(mpl, con, tuple); delete_tuple(mpl, tuple); return 0; } void eval_whole_con(MPL *mpl, CONSTRAINT *con) { loop_within_domain(mpl, con->domain, con, whole_con_func); return; } /*---------------------------------------------------------------------- -- clean_constraint - clean model constraint. -- -- This routine cleans specified model constraint that assumes deleting -- all stuff dynamically allocated during the generation phase. */ void clean_constraint(MPL *mpl, CONSTRAINT *con) { MEMBER *memb; /* clean subscript domain */ clean_domain(mpl, con->domain); /* clean code for computing main linear form */ clean_code(mpl, con->code); /* clean code for computing lower bound */ clean_code(mpl, con->lbnd); /* clean code for computing upper bound */ if (con->ubnd != con->lbnd) clean_code(mpl, con->ubnd); /* delete content array */ for (memb = con->array->head; memb != NULL; memb = memb->next) { delete_formula(mpl, memb->value.con->form); dmp_free_atom(mpl->elemcons, memb->value.con, sizeof(ELEMCON)); } delete_array(mpl, con->array), con->array = NULL; return; } /**********************************************************************/ /* * * PSEUDO-CODE * * */ /**********************************************************************/ /*---------------------------------------------------------------------- -- eval_numeric - evaluate pseudo-code to determine numeric value. -- -- This routine evaluates specified pseudo-code to determine resultant -- numeric value, which is returned on exit. */ struct iter_num_info { /* working info used by the routine iter_num_func */ CODE *code; /* pseudo-code for iterated operation to be performed */ double value; /* resultant value */ }; static int iter_num_func(MPL *mpl, void *_info) { /* this is auxiliary routine used to perform iterated operation on numeric "integrand" within domain scope */ struct iter_num_info *info = _info; double temp; temp = eval_numeric(mpl, info->code->arg.loop.x); switch (info->code->op) { case O_SUM: /* summation over domain */ info->value = fp_add(mpl, info->value, temp); break; case O_PROD: /* multiplication over domain */ info->value = fp_mul(mpl, info->value, temp); break; case O_MINIMUM: /* minimum over domain */ if (info->value > temp) info->value = temp; break; case O_MAXIMUM: /* maximum over domain */ if (info->value < temp) info->value = temp; break; default: xassert(info != info); } return 0; } double eval_numeric(MPL *mpl, CODE *code) { double value; xassert(code != NULL); xassert(code->type == A_NUMERIC); xassert(code->dim == 0); /* if the operation has a side effect, invalidate and delete the resultant value */ if (code->vflag && code->valid) { code->valid = 0; delete_value(mpl, code->type, &code->value); } /* if resultant value is valid, no evaluation is needed */ if (code->valid) { value = code->value.num; goto done; } /* evaluate pseudo-code recursively */ switch (code->op) { case O_NUMBER: /* take floating-point number */ value = code->arg.num; break; case O_MEMNUM: /* take member of numeric parameter */ { TUPLE *tuple; ARG_LIST *e; tuple = create_tuple(mpl); for (e = code->arg.par.list; e != NULL; e = e->next) tuple = expand_tuple(mpl, tuple, eval_symbolic(mpl, e->x)); value = eval_member_num(mpl, code->arg.par.par, tuple); delete_tuple(mpl, tuple); } break; case O_MEMVAR: /* take computed value of elemental variable */ { TUPLE *tuple; ARG_LIST *e; #if 1 /* 15/V-2010 */ ELEMVAR *var; #endif tuple = create_tuple(mpl); for (e = code->arg.var.list; e != NULL; e = e->next) tuple = expand_tuple(mpl, tuple, eval_symbolic(mpl, e->x)); #if 0 /* 15/V-2010 */ value = eval_member_var(mpl, code->arg.var.var, tuple) ->value; #else var = eval_member_var(mpl, code->arg.var.var, tuple); switch (code->arg.var.suff) { case DOT_LB: if (var->var->lbnd == NULL) value = -DBL_MAX; else value = var->lbnd; break; case DOT_UB: if (var->var->ubnd == NULL) value = +DBL_MAX; else value = var->ubnd; break; case DOT_STATUS: value = var->stat; break; case DOT_VAL: value = var->prim; break; case DOT_DUAL: value = var->dual; break; default: xassert(code != code); } #endif delete_tuple(mpl, tuple); } break; #if 1 /* 15/V-2010 */ case O_MEMCON: /* take computed value of elemental constraint */ { TUPLE *tuple; ARG_LIST *e; ELEMCON *con; tuple = create_tuple(mpl); for (e = code->arg.con.list; e != NULL; e = e->next) tuple = expand_tuple(mpl, tuple, eval_symbolic(mpl, e->x)); con = eval_member_con(mpl, code->arg.con.con, tuple); switch (code->arg.con.suff) { case DOT_LB: if (con->con->lbnd == NULL) value = -DBL_MAX; else value = con->lbnd; break; case DOT_UB: if (con->con->ubnd == NULL) value = +DBL_MAX; else value = con->ubnd; break; case DOT_STATUS: value = con->stat; break; case DOT_VAL: value = con->prim; break; case DOT_DUAL: value = con->dual; break; default: xassert(code != code); } delete_tuple(mpl, tuple); } break; #endif case O_IRAND224: /* pseudo-random in [0, 2^24-1] */ value = fp_irand224(mpl); break; case O_UNIFORM01: /* pseudo-random in [0, 1) */ value = fp_uniform01(mpl); break; case O_NORMAL01: /* gaussian random, mu = 0, sigma = 1 */ value = fp_normal01(mpl); break; case O_GMTIME: /* current calendar time */ value = fn_gmtime(mpl); break; case O_CVTNUM: /* conversion to numeric */ { SYMBOL *sym; sym = eval_symbolic(mpl, code->arg.arg.x); #if 0 /* 23/XI-2008 */ if (sym->str != NULL) mpl_error(mpl, "cannot convert %s to floating-point numbe" "r", format_symbol(mpl, sym)); value = sym->num; #else if (sym->str == NULL) value = sym->num; else { if (str2num(sym->str, &value)) mpl_error(mpl, "cannot convert %s to floating-point nu" "mber", format_symbol(mpl, sym)); } #endif delete_symbol(mpl, sym); } break; case O_PLUS: /* unary plus */ value = + eval_numeric(mpl, code->arg.arg.x); break; case O_MINUS: /* unary minus */ value = - eval_numeric(mpl, code->arg.arg.x); break; case O_ABS: /* absolute value */ value = fabs(eval_numeric(mpl, code->arg.arg.x)); break; case O_CEIL: /* round upward ("ceiling of x") */ value = ceil(eval_numeric(mpl, code->arg.arg.x)); break; case O_FLOOR: /* round downward ("floor of x") */ value = floor(eval_numeric(mpl, code->arg.arg.x)); break; case O_EXP: /* base-e exponential */ value = fp_exp(mpl, eval_numeric(mpl, code->arg.arg.x)); break; case O_LOG: /* natural logarithm */ value = fp_log(mpl, eval_numeric(mpl, code->arg.arg.x)); break; case O_LOG10: /* common (decimal) logarithm */ value = fp_log10(mpl, eval_numeric(mpl, code->arg.arg.x)); break; case O_SQRT: /* square root */ value = fp_sqrt(mpl, eval_numeric(mpl, code->arg.arg.x)); break; case O_SIN: /* trigonometric sine */ value = fp_sin(mpl, eval_numeric(mpl, code->arg.arg.x)); break; case O_COS: /* trigonometric cosine */ value = fp_cos(mpl, eval_numeric(mpl, code->arg.arg.x)); break; case O_ATAN: /* trigonometric arctangent (one argument) */ value = fp_atan(mpl, eval_numeric(mpl, code->arg.arg.x)); break; case O_ATAN2: /* trigonometric arctangent (two arguments) */ value = fp_atan2(mpl, eval_numeric(mpl, code->arg.arg.x), eval_numeric(mpl, code->arg.arg.y)); break; case O_ROUND: /* round to nearest integer */ value = fp_round(mpl, eval_numeric(mpl, code->arg.arg.x), 0.0); break; case O_ROUND2: /* round to n fractional digits */ value = fp_round(mpl, eval_numeric(mpl, code->arg.arg.x), eval_numeric(mpl, code->arg.arg.y)); break; case O_TRUNC: /* truncate to nearest integer */ value = fp_trunc(mpl, eval_numeric(mpl, code->arg.arg.x), 0.0); break; case O_TRUNC2: /* truncate to n fractional digits */ value = fp_trunc(mpl, eval_numeric(mpl, code->arg.arg.x), eval_numeric(mpl, code->arg.arg.y)); break; case O_ADD: /* addition */ value = fp_add(mpl, eval_numeric(mpl, code->arg.arg.x), eval_numeric(mpl, code->arg.arg.y)); break; case O_SUB: /* subtraction */ value = fp_sub(mpl, eval_numeric(mpl, code->arg.arg.x), eval_numeric(mpl, code->arg.arg.y)); break; case O_LESS: /* non-negative subtraction */ value = fp_less(mpl, eval_numeric(mpl, code->arg.arg.x), eval_numeric(mpl, code->arg.arg.y)); break; case O_MUL: /* multiplication */ value = fp_mul(mpl, eval_numeric(mpl, code->arg.arg.x), eval_numeric(mpl, code->arg.arg.y)); break; case O_DIV: /* division */ value = fp_div(mpl, eval_numeric(mpl, code->arg.arg.x), eval_numeric(mpl, code->arg.arg.y)); break; case O_IDIV: /* quotient of exact division */ value = fp_idiv(mpl, eval_numeric(mpl, code->arg.arg.x), eval_numeric(mpl, code->arg.arg.y)); break; case O_MOD: /* remainder of exact division */ value = fp_mod(mpl, eval_numeric(mpl, code->arg.arg.x), eval_numeric(mpl, code->arg.arg.y)); break; case O_POWER: /* exponentiation (raise to power) */ value = fp_power(mpl, eval_numeric(mpl, code->arg.arg.x), eval_numeric(mpl, code->arg.arg.y)); break; case O_UNIFORM: /* pseudo-random in [a, b) */ value = fp_uniform(mpl, eval_numeric(mpl, code->arg.arg.x), eval_numeric(mpl, code->arg.arg.y)); break; case O_NORMAL: /* gaussian random, given mu and sigma */ value = fp_normal(mpl, eval_numeric(mpl, code->arg.arg.x), eval_numeric(mpl, code->arg.arg.y)); break; case O_CARD: { ELEMSET *set; set = eval_elemset(mpl, code->arg.arg.x); value = set->size; delete_array(mpl, set); } break; case O_LENGTH: { SYMBOL *sym; char str[MAX_LENGTH+1]; sym = eval_symbolic(mpl, code->arg.arg.x); if (sym->str == NULL) sprintf(str, "%.*g", DBL_DIG, sym->num); else fetch_string(mpl, sym->str, str); delete_symbol(mpl, sym); value = strlen(str); } break; case O_STR2TIME: { SYMBOL *sym; char str[MAX_LENGTH+1], fmt[MAX_LENGTH+1]; sym = eval_symbolic(mpl, code->arg.arg.x); if (sym->str == NULL) sprintf(str, "%.*g", DBL_DIG, sym->num); else fetch_string(mpl, sym->str, str); delete_symbol(mpl, sym); sym = eval_symbolic(mpl, code->arg.arg.y); if (sym->str == NULL) sprintf(fmt, "%.*g", DBL_DIG, sym->num); else fetch_string(mpl, sym->str, fmt); delete_symbol(mpl, sym); value = fn_str2time(mpl, str, fmt); } break; case O_FORK: /* if-then-else */ if (eval_logical(mpl, code->arg.arg.x)) value = eval_numeric(mpl, code->arg.arg.y); else if (code->arg.arg.z == NULL) value = 0.0; else value = eval_numeric(mpl, code->arg.arg.z); break; case O_MIN: /* minimal value (n-ary) */ { ARG_LIST *e; double temp; value = +DBL_MAX; for (e = code->arg.list; e != NULL; e = e->next) { temp = eval_numeric(mpl, e->x); if (value > temp) value = temp; } } break; case O_MAX: /* maximal value (n-ary) */ { ARG_LIST *e; double temp; value = -DBL_MAX; for (e = code->arg.list; e != NULL; e = e->next) { temp = eval_numeric(mpl, e->x); if (value < temp) value = temp; } } break; case O_SUM: /* summation over domain */ { struct iter_num_info _info, *info = &_info; info->code = code; info->value = 0.0; loop_within_domain(mpl, code->arg.loop.domain, info, iter_num_func); value = info->value; } break; case O_PROD: /* multiplication over domain */ { struct iter_num_info _info, *info = &_info; info->code = code; info->value = 1.0; loop_within_domain(mpl, code->arg.loop.domain, info, iter_num_func); value = info->value; } break; case O_MINIMUM: /* minimum over domain */ { struct iter_num_info _info, *info = &_info; info->code = code; info->value = +DBL_MAX; loop_within_domain(mpl, code->arg.loop.domain, info, iter_num_func); if (info->value == +DBL_MAX) mpl_error(mpl, "min{} over empty set; result undefined"); value = info->value; } break; case O_MAXIMUM: /* maximum over domain */ { struct iter_num_info _info, *info = &_info; info->code = code; info->value = -DBL_MAX; loop_within_domain(mpl, code->arg.loop.domain, info, iter_num_func); if (info->value == -DBL_MAX) mpl_error(mpl, "max{} over empty set; result undefined"); value = info->value; } break; default: xassert(code != code); } /* save resultant value */ xassert(!code->valid); code->valid = 1; code->value.num = value; done: return value; } /*---------------------------------------------------------------------- -- eval_symbolic - evaluate pseudo-code to determine symbolic value. -- -- This routine evaluates specified pseudo-code to determine resultant -- symbolic value, which is returned on exit. */ SYMBOL *eval_symbolic(MPL *mpl, CODE *code) { SYMBOL *value; xassert(code != NULL); xassert(code->type == A_SYMBOLIC); xassert(code->dim == 0); /* if the operation has a side effect, invalidate and delete the resultant value */ if (code->vflag && code->valid) { code->valid = 0; delete_value(mpl, code->type, &code->value); } /* if resultant value is valid, no evaluation is needed */ if (code->valid) { value = copy_symbol(mpl, code->value.sym); goto done; } /* evaluate pseudo-code recursively */ switch (code->op) { case O_STRING: /* take character string */ value = create_symbol_str(mpl, create_string(mpl, code->arg.str)); break; case O_INDEX: /* take dummy index */ xassert(code->arg.index.slot->value != NULL); value = copy_symbol(mpl, code->arg.index.slot->value); break; case O_MEMSYM: /* take member of symbolic parameter */ { TUPLE *tuple; ARG_LIST *e; tuple = create_tuple(mpl); for (e = code->arg.par.list; e != NULL; e = e->next) tuple = expand_tuple(mpl, tuple, eval_symbolic(mpl, e->x)); value = eval_member_sym(mpl, code->arg.par.par, tuple); delete_tuple(mpl, tuple); } break; case O_CVTSYM: /* conversion to symbolic */ value = create_symbol_num(mpl, eval_numeric(mpl, code->arg.arg.x)); break; case O_CONCAT: /* concatenation */ value = concat_symbols(mpl, eval_symbolic(mpl, code->arg.arg.x), eval_symbolic(mpl, code->arg.arg.y)); break; case O_FORK: /* if-then-else */ if (eval_logical(mpl, code->arg.arg.x)) value = eval_symbolic(mpl, code->arg.arg.y); else if (code->arg.arg.z == NULL) value = create_symbol_num(mpl, 0.0); else value = eval_symbolic(mpl, code->arg.arg.z); break; case O_SUBSTR: case O_SUBSTR3: { double pos, len; char str[MAX_LENGTH+1]; value = eval_symbolic(mpl, code->arg.arg.x); if (value->str == NULL) sprintf(str, "%.*g", DBL_DIG, value->num); else fetch_string(mpl, value->str, str); delete_symbol(mpl, value); if (code->op == O_SUBSTR) { pos = eval_numeric(mpl, code->arg.arg.y); if (pos != floor(pos)) mpl_error(mpl, "substr('...', %.*g); non-integer secon" "d argument", DBL_DIG, pos); if (pos < 1 || pos > strlen(str) + 1) mpl_error(mpl, "substr('...', %.*g); substring out of " "range", DBL_DIG, pos); } else { pos = eval_numeric(mpl, code->arg.arg.y); len = eval_numeric(mpl, code->arg.arg.z); if (pos != floor(pos) || len != floor(len)) mpl_error(mpl, "substr('...', %.*g, %.*g); non-integer" " second and/or third argument", DBL_DIG, pos, DBL_DIG, len); if (pos < 1 || len < 0 || pos + len > strlen(str) + 1) mpl_error(mpl, "substr('...', %.*g, %.*g); substring o" "ut of range", DBL_DIG, pos, DBL_DIG, len); str[(int)pos + (int)len - 1] = '\0'; } value = create_symbol_str(mpl, create_string(mpl, str + (int)pos - 1)); } break; case O_TIME2STR: { double num; SYMBOL *sym; char str[MAX_LENGTH+1], fmt[MAX_LENGTH+1]; num = eval_numeric(mpl, code->arg.arg.x); sym = eval_symbolic(mpl, code->arg.arg.y); if (sym->str == NULL) sprintf(fmt, "%.*g", DBL_DIG, sym->num); else fetch_string(mpl, sym->str, fmt); delete_symbol(mpl, sym); fn_time2str(mpl, str, num, fmt); value = create_symbol_str(mpl, create_string(mpl, str)); } break; default: xassert(code != code); } /* save resultant value */ xassert(!code->valid); code->valid = 1; code->value.sym = copy_symbol(mpl, value); done: return value; } /*---------------------------------------------------------------------- -- eval_logical - evaluate pseudo-code to determine logical value. -- -- This routine evaluates specified pseudo-code to determine resultant -- logical value, which is returned on exit. */ struct iter_log_info { /* working info used by the routine iter_log_func */ CODE *code; /* pseudo-code for iterated operation to be performed */ int value; /* resultant value */ }; static int iter_log_func(MPL *mpl, void *_info) { /* this is auxiliary routine used to perform iterated operation on logical "integrand" within domain scope */ struct iter_log_info *info = _info; int ret = 0; switch (info->code->op) { case O_FORALL: /* conjunction over domain */ info->value &= eval_logical(mpl, info->code->arg.loop.x); if (!info->value) ret = 1; break; case O_EXISTS: /* disjunction over domain */ info->value |= eval_logical(mpl, info->code->arg.loop.x); if (info->value) ret = 1; break; default: xassert(info != info); } return ret; } int eval_logical(MPL *mpl, CODE *code) { int value; xassert(code->type == A_LOGICAL); xassert(code->dim == 0); /* if the operation has a side effect, invalidate and delete the resultant value */ if (code->vflag && code->valid) { code->valid = 0; delete_value(mpl, code->type, &code->value); } /* if resultant value is valid, no evaluation is needed */ if (code->valid) { value = code->value.bit; goto done; } /* evaluate pseudo-code recursively */ switch (code->op) { case O_CVTLOG: /* conversion to logical */ value = (eval_numeric(mpl, code->arg.arg.x) != 0.0); break; case O_NOT: /* negation (logical "not") */ value = !eval_logical(mpl, code->arg.arg.x); break; case O_LT: /* comparison on 'less than' */ #if 0 /* 02/VIII-2008 */ value = (eval_numeric(mpl, code->arg.arg.x) < eval_numeric(mpl, code->arg.arg.y)); #else xassert(code->arg.arg.x != NULL); if (code->arg.arg.x->type == A_NUMERIC) value = (eval_numeric(mpl, code->arg.arg.x) < eval_numeric(mpl, code->arg.arg.y)); else { SYMBOL *sym1 = eval_symbolic(mpl, code->arg.arg.x); SYMBOL *sym2 = eval_symbolic(mpl, code->arg.arg.y); value = (compare_symbols(mpl, sym1, sym2) < 0); delete_symbol(mpl, sym1); delete_symbol(mpl, sym2); } #endif break; case O_LE: /* comparison on 'not greater than' */ #if 0 /* 02/VIII-2008 */ value = (eval_numeric(mpl, code->arg.arg.x) <= eval_numeric(mpl, code->arg.arg.y)); #else xassert(code->arg.arg.x != NULL); if (code->arg.arg.x->type == A_NUMERIC) value = (eval_numeric(mpl, code->arg.arg.x) <= eval_numeric(mpl, code->arg.arg.y)); else { SYMBOL *sym1 = eval_symbolic(mpl, code->arg.arg.x); SYMBOL *sym2 = eval_symbolic(mpl, code->arg.arg.y); value = (compare_symbols(mpl, sym1, sym2) <= 0); delete_symbol(mpl, sym1); delete_symbol(mpl, sym2); } #endif break; case O_EQ: /* comparison on 'equal to' */ xassert(code->arg.arg.x != NULL); if (code->arg.arg.x->type == A_NUMERIC) value = (eval_numeric(mpl, code->arg.arg.x) == eval_numeric(mpl, code->arg.arg.y)); else { SYMBOL *sym1 = eval_symbolic(mpl, code->arg.arg.x); SYMBOL *sym2 = eval_symbolic(mpl, code->arg.arg.y); value = (compare_symbols(mpl, sym1, sym2) == 0); delete_symbol(mpl, sym1); delete_symbol(mpl, sym2); } break; case O_GE: /* comparison on 'not less than' */ #if 0 /* 02/VIII-2008 */ value = (eval_numeric(mpl, code->arg.arg.x) >= eval_numeric(mpl, code->arg.arg.y)); #else xassert(code->arg.arg.x != NULL); if (code->arg.arg.x->type == A_NUMERIC) value = (eval_numeric(mpl, code->arg.arg.x) >= eval_numeric(mpl, code->arg.arg.y)); else { SYMBOL *sym1 = eval_symbolic(mpl, code->arg.arg.x); SYMBOL *sym2 = eval_symbolic(mpl, code->arg.arg.y); value = (compare_symbols(mpl, sym1, sym2) >= 0); delete_symbol(mpl, sym1); delete_symbol(mpl, sym2); } #endif break; case O_GT: /* comparison on 'greater than' */ #if 0 /* 02/VIII-2008 */ value = (eval_numeric(mpl, code->arg.arg.x) > eval_numeric(mpl, code->arg.arg.y)); #else xassert(code->arg.arg.x != NULL); if (code->arg.arg.x->type == A_NUMERIC) value = (eval_numeric(mpl, code->arg.arg.x) > eval_numeric(mpl, code->arg.arg.y)); else { SYMBOL *sym1 = eval_symbolic(mpl, code->arg.arg.x); SYMBOL *sym2 = eval_symbolic(mpl, code->arg.arg.y); value = (compare_symbols(mpl, sym1, sym2) > 0); delete_symbol(mpl, sym1); delete_symbol(mpl, sym2); } #endif break; case O_NE: /* comparison on 'not equal to' */ xassert(code->arg.arg.x != NULL); if (code->arg.arg.x->type == A_NUMERIC) value = (eval_numeric(mpl, code->arg.arg.x) != eval_numeric(mpl, code->arg.arg.y)); else { SYMBOL *sym1 = eval_symbolic(mpl, code->arg.arg.x); SYMBOL *sym2 = eval_symbolic(mpl, code->arg.arg.y); value = (compare_symbols(mpl, sym1, sym2) != 0); delete_symbol(mpl, sym1); delete_symbol(mpl, sym2); } break; case O_AND: /* conjunction (logical "and") */ value = eval_logical(mpl, code->arg.arg.x) && eval_logical(mpl, code->arg.arg.y); break; case O_OR: /* disjunction (logical "or") */ value = eval_logical(mpl, code->arg.arg.x) || eval_logical(mpl, code->arg.arg.y); break; case O_IN: /* test on 'x in Y' */ { TUPLE *tuple; tuple = eval_tuple(mpl, code->arg.arg.x); value = is_member(mpl, code->arg.arg.y, tuple); delete_tuple(mpl, tuple); } break; case O_NOTIN: /* test on 'x not in Y' */ { TUPLE *tuple; tuple = eval_tuple(mpl, code->arg.arg.x); value = !is_member(mpl, code->arg.arg.y, tuple); delete_tuple(mpl, tuple); } break; case O_WITHIN: /* test on 'X within Y' */ { ELEMSET *set; MEMBER *memb; set = eval_elemset(mpl, code->arg.arg.x); value = 1; for (memb = set->head; memb != NULL; memb = memb->next) { if (!is_member(mpl, code->arg.arg.y, memb->tuple)) { value = 0; break; } } delete_elemset(mpl, set); } break; case O_NOTWITHIN: /* test on 'X not within Y' */ { ELEMSET *set; MEMBER *memb; set = eval_elemset(mpl, code->arg.arg.x); value = 1; for (memb = set->head; memb != NULL; memb = memb->next) { if (is_member(mpl, code->arg.arg.y, memb->tuple)) { value = 0; break; } } delete_elemset(mpl, set); } break; case O_FORALL: /* conjunction (A-quantification) */ { struct iter_log_info _info, *info = &_info; info->code = code; info->value = 1; loop_within_domain(mpl, code->arg.loop.domain, info, iter_log_func); value = info->value; } break; case O_EXISTS: /* disjunction (E-quantification) */ { struct iter_log_info _info, *info = &_info; info->code = code; info->value = 0; loop_within_domain(mpl, code->arg.loop.domain, info, iter_log_func); value = info->value; } break; default: xassert(code != code); } /* save resultant value */ xassert(!code->valid); code->valid = 1; code->value.bit = value; done: return value; } /*---------------------------------------------------------------------- -- eval_tuple - evaluate pseudo-code to construct n-tuple. -- -- This routine evaluates specified pseudo-code to construct resultant -- n-tuple, which is returned on exit. */ TUPLE *eval_tuple(MPL *mpl, CODE *code) { TUPLE *value; xassert(code != NULL); xassert(code->type == A_TUPLE); xassert(code->dim > 0); /* if the operation has a side effect, invalidate and delete the resultant value */ if (code->vflag && code->valid) { code->valid = 0; delete_value(mpl, code->type, &code->value); } /* if resultant value is valid, no evaluation is needed */ if (code->valid) { value = copy_tuple(mpl, code->value.tuple); goto done; } /* evaluate pseudo-code recursively */ switch (code->op) { case O_TUPLE: /* make n-tuple */ { ARG_LIST *e; value = create_tuple(mpl); for (e = code->arg.list; e != NULL; e = e->next) value = expand_tuple(mpl, value, eval_symbolic(mpl, e->x)); } break; case O_CVTTUP: /* convert to 1-tuple */ value = expand_tuple(mpl, create_tuple(mpl), eval_symbolic(mpl, code->arg.arg.x)); break; default: xassert(code != code); } /* save resultant value */ xassert(!code->valid); code->valid = 1; code->value.tuple = copy_tuple(mpl, value); done: return value; } /*---------------------------------------------------------------------- -- eval_elemset - evaluate pseudo-code to construct elemental set. -- -- This routine evaluates specified pseudo-code to construct resultant -- elemental set, which is returned on exit. */ struct iter_set_info { /* working info used by the routine iter_set_func */ CODE *code; /* pseudo-code for iterated operation to be performed */ ELEMSET *value; /* resultant value */ }; static int iter_set_func(MPL *mpl, void *_info) { /* this is auxiliary routine used to perform iterated operation on n-tuple "integrand" within domain scope */ struct iter_set_info *info = _info; TUPLE *tuple; switch (info->code->op) { case O_SETOF: /* compute next n-tuple and add it to the set; in this case duplicate n-tuples are silently ignored */ tuple = eval_tuple(mpl, info->code->arg.loop.x); if (find_tuple(mpl, info->value, tuple) == NULL) add_tuple(mpl, info->value, tuple); else delete_tuple(mpl, tuple); break; case O_BUILD: /* construct next n-tuple using current values assigned to *free* dummy indices as its components and add it to the set; in this case duplicate n-tuples cannot appear */ add_tuple(mpl, info->value, get_domain_tuple(mpl, info->code->arg.loop.domain)); break; default: xassert(info != info); } return 0; } ELEMSET *eval_elemset(MPL *mpl, CODE *code) { ELEMSET *value; xassert(code != NULL); xassert(code->type == A_ELEMSET); xassert(code->dim > 0); /* if the operation has a side effect, invalidate and delete the resultant value */ if (code->vflag && code->valid) { code->valid = 0; delete_value(mpl, code->type, &code->value); } /* if resultant value is valid, no evaluation is needed */ if (code->valid) { value = copy_elemset(mpl, code->value.set); goto done; } /* evaluate pseudo-code recursively */ switch (code->op) { case O_MEMSET: /* take member of set */ { TUPLE *tuple; ARG_LIST *e; tuple = create_tuple(mpl); for (e = code->arg.set.list; e != NULL; e = e->next) tuple = expand_tuple(mpl, tuple, eval_symbolic(mpl, e->x)); value = copy_elemset(mpl, eval_member_set(mpl, code->arg.set.set, tuple)); delete_tuple(mpl, tuple); } break; case O_MAKE: /* make elemental set of n-tuples */ { ARG_LIST *e; value = create_elemset(mpl, code->dim); for (e = code->arg.list; e != NULL; e = e->next) check_then_add(mpl, value, eval_tuple(mpl, e->x)); } break; case O_UNION: /* union of two elemental sets */ value = set_union(mpl, eval_elemset(mpl, code->arg.arg.x), eval_elemset(mpl, code->arg.arg.y)); break; case O_DIFF: /* difference between two elemental sets */ value = set_diff(mpl, eval_elemset(mpl, code->arg.arg.x), eval_elemset(mpl, code->arg.arg.y)); break; case O_SYMDIFF: /* symmetric difference between two elemental sets */ value = set_symdiff(mpl, eval_elemset(mpl, code->arg.arg.x), eval_elemset(mpl, code->arg.arg.y)); break; case O_INTER: /* intersection of two elemental sets */ value = set_inter(mpl, eval_elemset(mpl, code->arg.arg.x), eval_elemset(mpl, code->arg.arg.y)); break; case O_CROSS: /* cross (Cartesian) product of two elemental sets */ value = set_cross(mpl, eval_elemset(mpl, code->arg.arg.x), eval_elemset(mpl, code->arg.arg.y)); break; case O_DOTS: /* build "arithmetic" elemental set */ value = create_arelset(mpl, eval_numeric(mpl, code->arg.arg.x), eval_numeric(mpl, code->arg.arg.y), code->arg.arg.z == NULL ? 1.0 : eval_numeric(mpl, code->arg.arg.z)); break; case O_FORK: /* if-then-else */ if (eval_logical(mpl, code->arg.arg.x)) value = eval_elemset(mpl, code->arg.arg.y); else value = eval_elemset(mpl, code->arg.arg.z); break; case O_SETOF: /* compute elemental set */ { struct iter_set_info _info, *info = &_info; info->code = code; info->value = create_elemset(mpl, code->dim); loop_within_domain(mpl, code->arg.loop.domain, info, iter_set_func); value = info->value; } break; case O_BUILD: /* build elemental set identical to domain set */ { struct iter_set_info _info, *info = &_info; info->code = code; info->value = create_elemset(mpl, code->dim); loop_within_domain(mpl, code->arg.loop.domain, info, iter_set_func); value = info->value; } break; default: xassert(code != code); } /* save resultant value */ xassert(!code->valid); code->valid = 1; code->value.set = copy_elemset(mpl, value); done: return value; } /*---------------------------------------------------------------------- -- is_member - check if n-tuple is in set specified by pseudo-code. -- -- This routine checks if given n-tuple is a member of elemental set -- specified in the form of pseudo-code (i.e. by expression). -- -- The n-tuple may have more components that dimension of the elemental -- set, in which case the extra components are ignored. */ static void null_func(MPL *mpl, void *info) { /* this is dummy routine used to enter the domain scope */ xassert(mpl == mpl); xassert(info == NULL); return; } int is_member(MPL *mpl, CODE *code, TUPLE *tuple) { int value; xassert(code != NULL); xassert(code->type == A_ELEMSET); xassert(code->dim > 0); xassert(tuple != NULL); switch (code->op) { case O_MEMSET: /* check if given n-tuple is member of elemental set, which is assigned to member of model set */ { ARG_LIST *e; TUPLE *temp; ELEMSET *set; /* evaluate reference to elemental set */ temp = create_tuple(mpl); for (e = code->arg.set.list; e != NULL; e = e->next) temp = expand_tuple(mpl, temp, eval_symbolic(mpl, e->x)); set = eval_member_set(mpl, code->arg.set.set, temp); delete_tuple(mpl, temp); /* check if the n-tuple is contained in the set array */ temp = build_subtuple(mpl, tuple, set->dim); value = (find_tuple(mpl, set, temp) != NULL); delete_tuple(mpl, temp); } break; case O_MAKE: /* check if given n-tuple is member of literal set */ { ARG_LIST *e; TUPLE *temp, *that; value = 0; temp = build_subtuple(mpl, tuple, code->dim); for (e = code->arg.list; e != NULL; e = e->next) { that = eval_tuple(mpl, e->x); value = (compare_tuples(mpl, temp, that) == 0); delete_tuple(mpl, that); if (value) break; } delete_tuple(mpl, temp); } break; case O_UNION: value = is_member(mpl, code->arg.arg.x, tuple) || is_member(mpl, code->arg.arg.y, tuple); break; case O_DIFF: value = is_member(mpl, code->arg.arg.x, tuple) && !is_member(mpl, code->arg.arg.y, tuple); break; case O_SYMDIFF: { int in1 = is_member(mpl, code->arg.arg.x, tuple); int in2 = is_member(mpl, code->arg.arg.y, tuple); value = (in1 && !in2) || (!in1 && in2); } break; case O_INTER: value = is_member(mpl, code->arg.arg.x, tuple) && is_member(mpl, code->arg.arg.y, tuple); break; case O_CROSS: { int j; value = is_member(mpl, code->arg.arg.x, tuple); if (value) { for (j = 1; j <= code->arg.arg.x->dim; j++) { xassert(tuple != NULL); tuple = tuple->next; } value = is_member(mpl, code->arg.arg.y, tuple); } } break; case O_DOTS: /* check if given 1-tuple is member of "arithmetic" set */ { int j; double x, t0, tf, dt; xassert(code->dim == 1); /* compute "parameters" of the "arithmetic" set */ t0 = eval_numeric(mpl, code->arg.arg.x); tf = eval_numeric(mpl, code->arg.arg.y); if (code->arg.arg.z == NULL) dt = 1.0; else dt = eval_numeric(mpl, code->arg.arg.z); /* make sure the parameters are correct */ arelset_size(mpl, t0, tf, dt); /* if component of 1-tuple is symbolic, not numeric, the 1-tuple cannot be member of "arithmetic" set */ xassert(tuple->sym != NULL); if (tuple->sym->str != NULL) { value = 0; break; } /* determine numeric value of the component */ x = tuple->sym->num; /* if the component value is out of the set range, the 1-tuple is not in the set */ if (dt > 0.0 && !(t0 <= x && x <= tf) || dt < 0.0 && !(tf <= x && x <= t0)) { value = 0; break; } /* estimate ordinal number of the 1-tuple in the set */ j = (int)(((x - t0) / dt) + 0.5) + 1; /* perform the main check */ value = (arelset_member(mpl, t0, tf, dt, j) == x); } break; case O_FORK: /* check if given n-tuple is member of conditional set */ if (eval_logical(mpl, code->arg.arg.x)) value = is_member(mpl, code->arg.arg.y, tuple); else value = is_member(mpl, code->arg.arg.z, tuple); break; case O_SETOF: /* check if given n-tuple is member of computed set */ /* it is not clear how to efficiently perform the check not computing the entire elemental set :+( */ mpl_error(mpl, "implementation restriction; in/within setof{} n" "ot allowed"); break; case O_BUILD: /* check if given n-tuple is member of domain set */ { TUPLE *temp; temp = build_subtuple(mpl, tuple, code->dim); /* try to enter the domain scope; if it is successful, the n-tuple is in the domain set */ value = (eval_within_domain(mpl, code->arg.loop.domain, temp, NULL, null_func) == 0); delete_tuple(mpl, temp); } break; default: xassert(code != code); } return value; } /*---------------------------------------------------------------------- -- eval_formula - evaluate pseudo-code to construct linear form. -- -- This routine evaluates specified pseudo-code to construct resultant -- linear form, which is returned on exit. */ struct iter_form_info { /* working info used by the routine iter_form_func */ CODE *code; /* pseudo-code for iterated operation to be performed */ FORMULA *value; /* resultant value */ FORMULA *tail; /* pointer to the last term */ }; static int iter_form_func(MPL *mpl, void *_info) { /* this is auxiliary routine used to perform iterated operation on linear form "integrand" within domain scope */ struct iter_form_info *info = _info; switch (info->code->op) { case O_SUM: /* summation over domain */ #if 0 info->value = linear_comb(mpl, +1.0, info->value, +1.0, eval_formula(mpl, info->code->arg.loop.x)); #else /* the routine linear_comb needs to look through all terms of both linear forms to reduce identical terms, so using it here is not a good idea (for example, evaluation of sum{i in 1..n} x[i] required quadratic time); the better idea is to gather all terms of the integrand in one list and reduce identical terms only once after all terms of the resultant linear form have been evaluated */ { FORMULA *form, *term; form = eval_formula(mpl, info->code->arg.loop.x); if (info->value == NULL) { xassert(info->tail == NULL); info->value = form; } else { xassert(info->tail != NULL); info->tail->next = form; } for (term = form; term != NULL; term = term->next) info->tail = term; } #endif break; default: xassert(info != info); } return 0; } FORMULA *eval_formula(MPL *mpl, CODE *code) { FORMULA *value; xassert(code != NULL); xassert(code->type == A_FORMULA); xassert(code->dim == 0); /* if the operation has a side effect, invalidate and delete the resultant value */ if (code->vflag && code->valid) { code->valid = 0; delete_value(mpl, code->type, &code->value); } /* if resultant value is valid, no evaluation is needed */ if (code->valid) { value = copy_formula(mpl, code->value.form); goto done; } /* evaluate pseudo-code recursively */ switch (code->op) { case O_MEMVAR: /* take member of variable */ { TUPLE *tuple; ARG_LIST *e; tuple = create_tuple(mpl); for (e = code->arg.var.list; e != NULL; e = e->next) tuple = expand_tuple(mpl, tuple, eval_symbolic(mpl, e->x)); #if 1 /* 15/V-2010 */ xassert(code->arg.var.suff == DOT_NONE); #endif value = single_variable(mpl, eval_member_var(mpl, code->arg.var.var, tuple)); delete_tuple(mpl, tuple); } break; case O_CVTLFM: /* convert to linear form */ value = constant_term(mpl, eval_numeric(mpl, code->arg.arg.x)); break; case O_PLUS: /* unary plus */ value = linear_comb(mpl, 0.0, constant_term(mpl, 0.0), +1.0, eval_formula(mpl, code->arg.arg.x)); break; case O_MINUS: /* unary minus */ value = linear_comb(mpl, 0.0, constant_term(mpl, 0.0), -1.0, eval_formula(mpl, code->arg.arg.x)); break; case O_ADD: /* addition */ value = linear_comb(mpl, +1.0, eval_formula(mpl, code->arg.arg.x), +1.0, eval_formula(mpl, code->arg.arg.y)); break; case O_SUB: /* subtraction */ value = linear_comb(mpl, +1.0, eval_formula(mpl, code->arg.arg.x), -1.0, eval_formula(mpl, code->arg.arg.y)); break; case O_MUL: /* multiplication */ xassert(code->arg.arg.x != NULL); xassert(code->arg.arg.y != NULL); if (code->arg.arg.x->type == A_NUMERIC) { xassert(code->arg.arg.y->type == A_FORMULA); value = linear_comb(mpl, eval_numeric(mpl, code->arg.arg.x), eval_formula(mpl, code->arg.arg.y), 0.0, constant_term(mpl, 0.0)); } else { xassert(code->arg.arg.x->type == A_FORMULA); xassert(code->arg.arg.y->type == A_NUMERIC); value = linear_comb(mpl, eval_numeric(mpl, code->arg.arg.y), eval_formula(mpl, code->arg.arg.x), 0.0, constant_term(mpl, 0.0)); } break; case O_DIV: /* division */ value = linear_comb(mpl, fp_div(mpl, 1.0, eval_numeric(mpl, code->arg.arg.y)), eval_formula(mpl, code->arg.arg.x), 0.0, constant_term(mpl, 0.0)); break; case O_FORK: /* if-then-else */ if (eval_logical(mpl, code->arg.arg.x)) value = eval_formula(mpl, code->arg.arg.y); else if (code->arg.arg.z == NULL) value = constant_term(mpl, 0.0); else value = eval_formula(mpl, code->arg.arg.z); break; case O_SUM: /* summation over domain */ { struct iter_form_info _info, *info = &_info; info->code = code; info->value = constant_term(mpl, 0.0); info->tail = NULL; loop_within_domain(mpl, code->arg.loop.domain, info, iter_form_func); value = reduce_terms(mpl, info->value); } break; default: xassert(code != code); } /* save resultant value */ xassert(!code->valid); code->valid = 1; code->value.form = copy_formula(mpl, value); done: return value; } /*---------------------------------------------------------------------- -- clean_code - clean pseudo-code. -- -- This routine recursively cleans specified pseudo-code that assumes -- deleting all temporary resultant values. */ void clean_code(MPL *mpl, CODE *code) { ARG_LIST *e; /* if no pseudo-code is specified, do nothing */ if (code == NULL) goto done; /* if resultant value is valid (exists), delete it */ if (code->valid) { code->valid = 0; delete_value(mpl, code->type, &code->value); } /* recursively clean pseudo-code for operands */ switch (code->op) { case O_NUMBER: case O_STRING: case O_INDEX: break; case O_MEMNUM: case O_MEMSYM: for (e = code->arg.par.list; e != NULL; e = e->next) clean_code(mpl, e->x); break; case O_MEMSET: for (e = code->arg.set.list; e != NULL; e = e->next) clean_code(mpl, e->x); break; case O_MEMVAR: for (e = code->arg.var.list; e != NULL; e = e->next) clean_code(mpl, e->x); break; #if 1 /* 15/V-2010 */ case O_MEMCON: for (e = code->arg.con.list; e != NULL; e = e->next) clean_code(mpl, e->x); break; #endif case O_TUPLE: case O_MAKE: for (e = code->arg.list; e != NULL; e = e->next) clean_code(mpl, e->x); break; case O_SLICE: xassert(code != code); case O_IRAND224: case O_UNIFORM01: case O_NORMAL01: case O_GMTIME: break; case O_CVTNUM: case O_CVTSYM: case O_CVTLOG: case O_CVTTUP: case O_CVTLFM: case O_PLUS: case O_MINUS: case O_NOT: case O_ABS: case O_CEIL: case O_FLOOR: case O_EXP: case O_LOG: case O_LOG10: case O_SQRT: case O_SIN: case O_COS: case O_ATAN: case O_ROUND: case O_TRUNC: case O_CARD: case O_LENGTH: /* unary operation */ clean_code(mpl, code->arg.arg.x); break; case O_ADD: case O_SUB: case O_LESS: case O_MUL: case O_DIV: case O_IDIV: case O_MOD: case O_POWER: case O_ATAN2: case O_ROUND2: case O_TRUNC2: case O_UNIFORM: case O_NORMAL: case O_CONCAT: case O_LT: case O_LE: case O_EQ: case O_GE: case O_GT: case O_NE: case O_AND: case O_OR: case O_UNION: case O_DIFF: case O_SYMDIFF: case O_INTER: case O_CROSS: case O_IN: case O_NOTIN: case O_WITHIN: case O_NOTWITHIN: case O_SUBSTR: case O_STR2TIME: case O_TIME2STR: /* binary operation */ clean_code(mpl, code->arg.arg.x); clean_code(mpl, code->arg.arg.y); break; case O_DOTS: case O_FORK: case O_SUBSTR3: /* ternary operation */ clean_code(mpl, code->arg.arg.x); clean_code(mpl, code->arg.arg.y); clean_code(mpl, code->arg.arg.z); break; case O_MIN: case O_MAX: /* n-ary operation */ for (e = code->arg.list; e != NULL; e = e->next) clean_code(mpl, e->x); break; case O_SUM: case O_PROD: case O_MINIMUM: case O_MAXIMUM: case O_FORALL: case O_EXISTS: case O_SETOF: case O_BUILD: /* iterated operation */ clean_domain(mpl, code->arg.loop.domain); clean_code(mpl, code->arg.loop.x); break; default: xassert(code->op != code->op); } done: return; } #if 1 /* 11/II-2008 */ /**********************************************************************/ /* * * DATA TABLES * * */ /**********************************************************************/ int mpl_tab_num_args(TABDCA *dca) { /* returns the number of arguments */ return dca->na; } const char *mpl_tab_get_arg(TABDCA *dca, int k) { /* returns pointer to k-th argument */ xassert(1 <= k && k <= dca->na); return dca->arg[k]; } int mpl_tab_num_flds(TABDCA *dca) { /* returns the number of fields */ return dca->nf; } const char *mpl_tab_get_name(TABDCA *dca, int k) { /* returns pointer to name of k-th field */ xassert(1 <= k && k <= dca->nf); return dca->name[k]; } int mpl_tab_get_type(TABDCA *dca, int k) { /* returns type of k-th field */ xassert(1 <= k && k <= dca->nf); return dca->type[k]; } double mpl_tab_get_num(TABDCA *dca, int k) { /* returns numeric value of k-th field */ xassert(1 <= k && k <= dca->nf); xassert(dca->type[k] == 'N'); return dca->num[k]; } const char *mpl_tab_get_str(TABDCA *dca, int k) { /* returns pointer to string value of k-th field */ xassert(1 <= k && k <= dca->nf); xassert(dca->type[k] == 'S'); xassert(dca->str[k] != NULL); return dca->str[k]; } void mpl_tab_set_num(TABDCA *dca, int k, double num) { /* assign numeric value to k-th field */ xassert(1 <= k && k <= dca->nf); xassert(dca->type[k] == '?'); dca->type[k] = 'N'; dca->num[k] = num; return; } void mpl_tab_set_str(TABDCA *dca, int k, const char *str) { /* assign string value to k-th field */ xassert(1 <= k && k <= dca->nf); xassert(dca->type[k] == '?'); xassert(strlen(str) <= MAX_LENGTH); xassert(dca->str[k] != NULL); dca->type[k] = 'S'; strcpy(dca->str[k], str); return; } static int write_func(MPL *mpl, void *info) { /* this is auxiliary routine to work within domain scope */ TABLE *tab = info; TABDCA *dca = mpl->dca; TABOUT *out; SYMBOL *sym; int k; char buf[MAX_LENGTH+1]; /* evaluate field values */ k = 0; for (out = tab->u.out.list; out != NULL; out = out->next) { k++; switch (out->code->type) { case A_NUMERIC: dca->type[k] = 'N'; dca->num[k] = eval_numeric(mpl, out->code); dca->str[k][0] = '\0'; break; case A_SYMBOLIC: sym = eval_symbolic(mpl, out->code); if (sym->str == NULL) { dca->type[k] = 'N'; dca->num[k] = sym->num; dca->str[k][0] = '\0'; } else { dca->type[k] = 'S'; dca->num[k] = 0.0; fetch_string(mpl, sym->str, buf); strcpy(dca->str[k], buf); } delete_symbol(mpl, sym); break; default: xassert(out != out); } } /* write record to output table */ mpl_tab_drv_write(mpl); return 0; } void execute_table(MPL *mpl, TABLE *tab) { /* execute table statement */ TABARG *arg; TABFLD *fld; TABIN *in; TABOUT *out; TABDCA *dca; SET *set; int k; char buf[MAX_LENGTH+1]; /* allocate table driver communication area */ xassert(mpl->dca == NULL); mpl->dca = dca = xmalloc(sizeof(TABDCA)); dca->id = 0; dca->link = NULL; dca->na = 0; dca->arg = NULL; dca->nf = 0; dca->name = NULL; dca->type = NULL; dca->num = NULL; dca->str = NULL; /* allocate arguments */ xassert(dca->na == 0); for (arg = tab->arg; arg != NULL; arg = arg->next) dca->na++; dca->arg = xcalloc(1+dca->na, sizeof(char *)); #if 1 /* 28/IX-2008 */ for (k = 1; k <= dca->na; k++) dca->arg[k] = NULL; #endif /* evaluate argument values */ k = 0; for (arg = tab->arg; arg != NULL; arg = arg->next) { SYMBOL *sym; k++; xassert(arg->code->type == A_SYMBOLIC); sym = eval_symbolic(mpl, arg->code); if (sym->str == NULL) sprintf(buf, "%.*g", DBL_DIG, sym->num); else fetch_string(mpl, sym->str, buf); delete_symbol(mpl, sym); dca->arg[k] = xmalloc(strlen(buf)+1); strcpy(dca->arg[k], buf); } /* perform table input/output */ switch (tab->type) { case A_INPUT: goto read_table; case A_OUTPUT: goto write_table; default: xassert(tab != tab); } read_table: /* read data from input table */ /* add the only member to the control set and assign it empty elemental set */ set = tab->u.in.set; if (set != NULL) { if (set->data) mpl_error(mpl, "%s already provided with data", set->name); xassert(set->array->head == NULL); add_member(mpl, set->array, NULL)->value.set = create_elemset(mpl, set->dimen); set->data = 1; } /* check parameters specified in the input list */ for (in = tab->u.in.list; in != NULL; in = in->next) { if (in->par->data) mpl_error(mpl, "%s already provided with data", in->par->name); in->par->data = 1; } /* allocate and initialize fields */ xassert(dca->nf == 0); for (fld = tab->u.in.fld; fld != NULL; fld = fld->next) dca->nf++; for (in = tab->u.in.list; in != NULL; in = in->next) dca->nf++; dca->name = xcalloc(1+dca->nf, sizeof(char *)); dca->type = xcalloc(1+dca->nf, sizeof(int)); dca->num = xcalloc(1+dca->nf, sizeof(double)); dca->str = xcalloc(1+dca->nf, sizeof(char *)); k = 0; for (fld = tab->u.in.fld; fld != NULL; fld = fld->next) { k++; dca->name[k] = fld->name; dca->type[k] = '?'; dca->num[k] = 0.0; dca->str[k] = xmalloc(MAX_LENGTH+1); dca->str[k][0] = '\0'; } for (in = tab->u.in.list; in != NULL; in = in->next) { k++; dca->name[k] = in->name; dca->type[k] = '?'; dca->num[k] = 0.0; dca->str[k] = xmalloc(MAX_LENGTH+1); dca->str[k][0] = '\0'; } /* open input table */ mpl_tab_drv_open(mpl, 'R'); /* read and process records */ for (;;) { TUPLE *tup; /* reset field types */ for (k = 1; k <= dca->nf; k++) dca->type[k] = '?'; /* read next record */ if (mpl_tab_drv_read(mpl)) break; /* all fields must be set by the driver */ for (k = 1; k <= dca->nf; k++) { if (dca->type[k] == '?') mpl_error(mpl, "field %s missing in input table", dca->name[k]); } /* construct n-tuple */ tup = create_tuple(mpl); k = 0; for (fld = tab->u.in.fld; fld != NULL; fld = fld->next) { k++; xassert(k <= dca->nf); switch (dca->type[k]) { case 'N': tup = expand_tuple(mpl, tup, create_symbol_num(mpl, dca->num[k])); break; case 'S': xassert(strlen(dca->str[k]) <= MAX_LENGTH); tup = expand_tuple(mpl, tup, create_symbol_str(mpl, create_string(mpl, dca->str[k]))); break; default: xassert(dca != dca); } } /* add n-tuple just read to the control set */ if (tab->u.in.set != NULL) check_then_add(mpl, tab->u.in.set->array->head->value.set, copy_tuple(mpl, tup)); /* assign values to the parameters in the input list */ for (in = tab->u.in.list; in != NULL; in = in->next) { MEMBER *memb; k++; xassert(k <= dca->nf); /* there must be no member with the same n-tuple */ if (find_member(mpl, in->par->array, tup) != NULL) mpl_error(mpl, "%s%s already defined", in->par->name, format_tuple(mpl, '[', tup)); /* create new parameter member with given n-tuple */ memb = add_member(mpl, in->par->array, copy_tuple(mpl, tup)) ; /* assign value to the parameter member */ switch (in->par->type) { case A_NUMERIC: case A_INTEGER: case A_BINARY: if (dca->type[k] != 'N') mpl_error(mpl, "%s requires numeric data", in->par->name); memb->value.num = dca->num[k]; break; case A_SYMBOLIC: switch (dca->type[k]) { case 'N': memb->value.sym = create_symbol_num(mpl, dca->num[k]); break; case 'S': xassert(strlen(dca->str[k]) <= MAX_LENGTH); memb->value.sym = create_symbol_str(mpl, create_string(mpl,dca->str[k])); break; default: xassert(dca != dca); } break; default: xassert(in != in); } } /* n-tuple is no more needed */ delete_tuple(mpl, tup); } /* close input table */ mpl_tab_drv_close(mpl); goto done; write_table: /* write data to output table */ /* allocate and initialize fields */ xassert(dca->nf == 0); for (out = tab->u.out.list; out != NULL; out = out->next) dca->nf++; dca->name = xcalloc(1+dca->nf, sizeof(char *)); dca->type = xcalloc(1+dca->nf, sizeof(int)); dca->num = xcalloc(1+dca->nf, sizeof(double)); dca->str = xcalloc(1+dca->nf, sizeof(char *)); k = 0; for (out = tab->u.out.list; out != NULL; out = out->next) { k++; dca->name[k] = out->name; dca->type[k] = '?'; dca->num[k] = 0.0; dca->str[k] = xmalloc(MAX_LENGTH+1); dca->str[k][0] = '\0'; } /* open output table */ mpl_tab_drv_open(mpl, 'W'); /* evaluate fields and write records */ loop_within_domain(mpl, tab->u.out.domain, tab, write_func); /* close output table */ mpl_tab_drv_close(mpl); done: /* free table driver communication area */ free_dca(mpl); return; } void free_dca(MPL *mpl) { /* free table driver communucation area */ TABDCA *dca = mpl->dca; int k; if (dca != NULL) { if (dca->link != NULL) mpl_tab_drv_close(mpl); if (dca->arg != NULL) { for (k = 1; k <= dca->na; k++) #if 1 /* 28/IX-2008 */ if (dca->arg[k] != NULL) #endif xfree(dca->arg[k]); xfree(dca->arg); } if (dca->name != NULL) xfree(dca->name); if (dca->type != NULL) xfree(dca->type); if (dca->num != NULL) xfree(dca->num); if (dca->str != NULL) { for (k = 1; k <= dca->nf; k++) xfree(dca->str[k]); xfree(dca->str); } xfree(dca), mpl->dca = NULL; } return; } void clean_table(MPL *mpl, TABLE *tab) { /* clean table statement */ TABARG *arg; TABOUT *out; /* clean string list */ for (arg = tab->arg; arg != NULL; arg = arg->next) clean_code(mpl, arg->code); switch (tab->type) { case A_INPUT: break; case A_OUTPUT: /* clean subscript domain */ clean_domain(mpl, tab->u.out.domain); /* clean output list */ for (out = tab->u.out.list; out != NULL; out = out->next) clean_code(mpl, out->code); break; default: xassert(tab != tab); } return; } #endif /**********************************************************************/ /* * * MODEL STATEMENTS * * */ /**********************************************************************/ /*---------------------------------------------------------------------- -- execute_check - execute check statement. -- -- This routine executes specified check statement. */ static int check_func(MPL *mpl, void *info) { /* this is auxiliary routine to work within domain scope */ CHECK *chk = (CHECK *)info; if (!eval_logical(mpl, chk->code)) mpl_error(mpl, "check%s failed", format_tuple(mpl, '[', get_domain_tuple(mpl, chk->domain))); return 0; } void execute_check(MPL *mpl, CHECK *chk) { loop_within_domain(mpl, chk->domain, chk, check_func); return; } /*---------------------------------------------------------------------- -- clean_check - clean check statement. -- -- This routine cleans specified check statement that assumes deleting -- all stuff dynamically allocated on generating/postsolving phase. */ void clean_check(MPL *mpl, CHECK *chk) { /* clean subscript domain */ clean_domain(mpl, chk->domain); /* clean pseudo-code for computing predicate */ clean_code(mpl, chk->code); return; } /*---------------------------------------------------------------------- -- execute_display - execute display statement. -- -- This routine executes specified display statement. */ static void display_set(MPL *mpl, SET *set, MEMBER *memb) { /* display member of model set */ ELEMSET *s = memb->value.set; MEMBER *m; write_text(mpl, "%s%s%s\n", set->name, format_tuple(mpl, '[', memb->tuple), s->head == NULL ? " is empty" : ":"); for (m = s->head; m != NULL; m = m->next) write_text(mpl, " %s\n", format_tuple(mpl, '(', m->tuple)); return; } static void display_par(MPL *mpl, PARAMETER *par, MEMBER *memb) { /* display member of model parameter */ switch (par->type) { case A_NUMERIC: case A_INTEGER: case A_BINARY: write_text(mpl, "%s%s = %.*g\n", par->name, format_tuple(mpl, '[', memb->tuple), DBL_DIG, memb->value.num); break; case A_SYMBOLIC: write_text(mpl, "%s%s = %s\n", par->name, format_tuple(mpl, '[', memb->tuple), format_symbol(mpl, memb->value.sym)); break; default: xassert(par != par); } return; } #if 1 /* 15/V-2010 */ static void display_var(MPL *mpl, VARIABLE *var, MEMBER *memb, int suff) { /* display member of model variable */ if (suff == DOT_NONE || suff == DOT_VAL) write_text(mpl, "%s%s.val = %.*g\n", var->name, format_tuple(mpl, '[', memb->tuple), DBL_DIG, memb->value.var->prim); else if (suff == DOT_LB) write_text(mpl, "%s%s.lb = %.*g\n", var->name, format_tuple(mpl, '[', memb->tuple), DBL_DIG, memb->value.var->var->lbnd == NULL ? -DBL_MAX : memb->value.var->lbnd); else if (suff == DOT_UB) write_text(mpl, "%s%s.ub = %.*g\n", var->name, format_tuple(mpl, '[', memb->tuple), DBL_DIG, memb->value.var->var->ubnd == NULL ? +DBL_MAX : memb->value.var->ubnd); else if (suff == DOT_STATUS) write_text(mpl, "%s%s.status = %d\n", var->name, format_tuple (mpl, '[', memb->tuple), memb->value.var->stat); else if (suff == DOT_DUAL) write_text(mpl, "%s%s.dual = %.*g\n", var->name, format_tuple(mpl, '[', memb->tuple), DBL_DIG, memb->value.var->dual); else xassert(suff != suff); return; } #endif #if 1 /* 15/V-2010 */ static void display_con(MPL *mpl, CONSTRAINT *con, MEMBER *memb, int suff) { /* display member of model constraint */ if (suff == DOT_NONE || suff == DOT_VAL) write_text(mpl, "%s%s.val = %.*g\n", con->name, format_tuple(mpl, '[', memb->tuple), DBL_DIG, memb->value.con->prim); else if (suff == DOT_LB) write_text(mpl, "%s%s.lb = %.*g\n", con->name, format_tuple(mpl, '[', memb->tuple), DBL_DIG, memb->value.con->con->lbnd == NULL ? -DBL_MAX : memb->value.con->lbnd); else if (suff == DOT_UB) write_text(mpl, "%s%s.ub = %.*g\n", con->name, format_tuple(mpl, '[', memb->tuple), DBL_DIG, memb->value.con->con->ubnd == NULL ? +DBL_MAX : memb->value.con->ubnd); else if (suff == DOT_STATUS) write_text(mpl, "%s%s.status = %d\n", con->name, format_tuple (mpl, '[', memb->tuple), memb->value.con->stat); else if (suff == DOT_DUAL) write_text(mpl, "%s%s.dual = %.*g\n", con->name, format_tuple(mpl, '[', memb->tuple), DBL_DIG, memb->value.con->dual); else xassert(suff != suff); return; } #endif static void display_memb(MPL *mpl, CODE *code) { /* display member specified by pseudo-code */ MEMBER memb; ARG_LIST *e; xassert(code->op == O_MEMNUM || code->op == O_MEMSYM || code->op == O_MEMSET || code->op == O_MEMVAR || code->op == O_MEMCON); memb.tuple = create_tuple(mpl); for (e = code->arg.par.list; e != NULL; e = e->next) memb.tuple = expand_tuple(mpl, memb.tuple, eval_symbolic(mpl, e->x)); switch (code->op) { case O_MEMNUM: memb.value.num = eval_member_num(mpl, code->arg.par.par, memb.tuple); display_par(mpl, code->arg.par.par, &memb); break; case O_MEMSYM: memb.value.sym = eval_member_sym(mpl, code->arg.par.par, memb.tuple); display_par(mpl, code->arg.par.par, &memb); delete_symbol(mpl, memb.value.sym); break; case O_MEMSET: memb.value.set = eval_member_set(mpl, code->arg.set.set, memb.tuple); display_set(mpl, code->arg.set.set, &memb); break; case O_MEMVAR: memb.value.var = eval_member_var(mpl, code->arg.var.var, memb.tuple); display_var (mpl, code->arg.var.var, &memb, code->arg.var.suff); break; case O_MEMCON: memb.value.con = eval_member_con(mpl, code->arg.con.con, memb.tuple); display_con (mpl, code->arg.con.con, &memb, code->arg.con.suff); break; default: xassert(code != code); } delete_tuple(mpl, memb.tuple); return; } static void display_code(MPL *mpl, CODE *code) { /* display value of expression */ switch (code->type) { case A_NUMERIC: /* numeric value */ { double num; num = eval_numeric(mpl, code); write_text(mpl, "%.*g\n", DBL_DIG, num); } break; case A_SYMBOLIC: /* symbolic value */ { SYMBOL *sym; sym = eval_symbolic(mpl, code); write_text(mpl, "%s\n", format_symbol(mpl, sym)); delete_symbol(mpl, sym); } break; case A_LOGICAL: /* logical value */ { int bit; bit = eval_logical(mpl, code); write_text(mpl, "%s\n", bit ? "true" : "false"); } break; case A_TUPLE: /* n-tuple */ { TUPLE *tuple; tuple = eval_tuple(mpl, code); write_text(mpl, "%s\n", format_tuple(mpl, '(', tuple)); delete_tuple(mpl, tuple); } break; case A_ELEMSET: /* elemental set */ { ELEMSET *set; MEMBER *memb; set = eval_elemset(mpl, code); if (set->head == 0) write_text(mpl, "set is empty\n"); for (memb = set->head; memb != NULL; memb = memb->next) write_text(mpl, " %s\n", format_tuple(mpl, '(', memb->tuple)); delete_elemset(mpl, set); } break; case A_FORMULA: /* linear form */ { FORMULA *form, *term; form = eval_formula(mpl, code); if (form == NULL) write_text(mpl, "linear form is empty\n"); for (term = form; term != NULL; term = term->next) { if (term->var == NULL) write_text(mpl, " %.*g\n", term->coef); else write_text(mpl, " %.*g %s%s\n", DBL_DIG, term->coef, term->var->var->name, format_tuple(mpl, '[', term->var->memb->tuple)); } delete_formula(mpl, form); } break; default: xassert(code != code); } return; } static int display_func(MPL *mpl, void *info) { /* this is auxiliary routine to work within domain scope */ DISPLAY *dpy = (DISPLAY *)info; DISPLAY1 *entry; for (entry = dpy->list; entry != NULL; entry = entry->next) { if (entry->type == A_INDEX) { /* dummy index */ DOMAIN_SLOT *slot = entry->u.slot; write_text(mpl, "%s = %s\n", slot->name, format_symbol(mpl, slot->value)); } else if (entry->type == A_SET) { /* model set */ SET *set = entry->u.set; MEMBER *memb; if (set->assign != NULL) { /* the set has assignment expression; evaluate all its members over entire domain */ eval_whole_set(mpl, set); } else { /* the set has no assignment expression; refer to its any existing member ignoring resultant value to check the data provided the data section */ #if 1 /* 12/XII-2008 */ if (set->gadget != NULL && set->data == 0) { /* initialize the set with data from a plain set */ saturate_set(mpl, set); } #endif if (set->array->head != NULL) eval_member_set(mpl, set, set->array->head->tuple); } /* display all members of the set array */ if (set->array->head == NULL) write_text(mpl, "%s has empty content\n", set->name); for (memb = set->array->head; memb != NULL; memb = memb->next) display_set(mpl, set, memb); } else if (entry->type == A_PARAMETER) { /* model parameter */ PARAMETER *par = entry->u.par; MEMBER *memb; if (par->assign != NULL) { /* the parameter has an assignment expression; evaluate all its member over entire domain */ eval_whole_par(mpl, par); } else { /* the parameter has no assignment expression; refer to its any existing member ignoring resultant value to check the data provided in the data section */ if (par->array->head != NULL) { if (par->type != A_SYMBOLIC) eval_member_num(mpl, par, par->array->head->tuple); else delete_symbol(mpl, eval_member_sym(mpl, par, par->array->head->tuple)); } } /* display all members of the parameter array */ if (par->array->head == NULL) write_text(mpl, "%s has empty content\n", par->name); for (memb = par->array->head; memb != NULL; memb = memb->next) display_par(mpl, par, memb); } else if (entry->type == A_VARIABLE) { /* model variable */ VARIABLE *var = entry->u.var; MEMBER *memb; xassert(mpl->flag_p); /* display all members of the variable array */ if (var->array->head == NULL) write_text(mpl, "%s has empty content\n", var->name); for (memb = var->array->head; memb != NULL; memb = memb->next) display_var(mpl, var, memb, DOT_NONE); } else if (entry->type == A_CONSTRAINT) { /* model constraint */ CONSTRAINT *con = entry->u.con; MEMBER *memb; xassert(mpl->flag_p); /* display all members of the constraint array */ if (con->array->head == NULL) write_text(mpl, "%s has empty content\n", con->name); for (memb = con->array->head; memb != NULL; memb = memb->next) display_con(mpl, con, memb, DOT_NONE); } else if (entry->type == A_EXPRESSION) { /* expression */ CODE *code = entry->u.code; if (code->op == O_MEMNUM || code->op == O_MEMSYM || code->op == O_MEMSET || code->op == O_MEMVAR || code->op == O_MEMCON) display_memb(mpl, code); else display_code(mpl, code); } else xassert(entry != entry); } return 0; } void execute_display(MPL *mpl, DISPLAY *dpy) { loop_within_domain(mpl, dpy->domain, dpy, display_func); return; } /*---------------------------------------------------------------------- -- clean_display - clean display statement. -- -- This routine cleans specified display statement that assumes deleting -- all stuff dynamically allocated on generating/postsolving phase. */ void clean_display(MPL *mpl, DISPLAY *dpy) { DISPLAY1 *d; #if 0 /* 15/V-2010 */ ARG_LIST *e; #endif /* clean subscript domain */ clean_domain(mpl, dpy->domain); /* clean display list */ for (d = dpy->list; d != NULL; d = d->next) { /* clean pseudo-code for computing expression */ if (d->type == A_EXPRESSION) clean_code(mpl, d->u.code); #if 0 /* 15/V-2010 */ /* clean pseudo-code for computing subscripts */ for (e = d->list; e != NULL; e = e->next) clean_code(mpl, e->x); #endif } return; } /*---------------------------------------------------------------------- -- execute_printf - execute printf statement. -- -- This routine executes specified printf statement. */ #if 1 /* 14/VII-2006 */ static void print_char(MPL *mpl, int c) { if (mpl->prt_fp == NULL) write_char(mpl, c); else xfputc(c, mpl->prt_fp); return; } static void print_text(MPL *mpl, char *fmt, ...) { va_list arg; char buf[OUTBUF_SIZE], *c; va_start(arg, fmt); vsprintf(buf, fmt, arg); xassert(strlen(buf) < sizeof(buf)); va_end(arg); for (c = buf; *c != '\0'; c++) print_char(mpl, *c); return; } #endif static int printf_func(MPL *mpl, void *info) { /* this is auxiliary routine to work within domain scope */ PRINTF *prt = (PRINTF *)info; PRINTF1 *entry; SYMBOL *sym; char fmt[MAX_LENGTH+1], *c, *from, save; /* evaluate format control string */ sym = eval_symbolic(mpl, prt->fmt); if (sym->str == NULL) sprintf(fmt, "%.*g", DBL_DIG, sym->num); else fetch_string(mpl, sym->str, fmt); delete_symbol(mpl, sym); /* scan format control string and perform formatting output */ entry = prt->list; for (c = fmt; *c != '\0'; c++) { if (*c == '%') { /* scan format specifier */ from = c++; if (*c == '%') { print_char(mpl, '%'); continue; } if (entry == NULL) break; /* scan optional flags */ while (*c == '-' || *c == '+' || *c == ' ' || *c == '#' || *c == '0') c++; /* scan optional minimum field width */ while (isdigit((unsigned char)*c)) c++; /* scan optional precision */ if (*c == '.') { c++; while (isdigit((unsigned char)*c)) c++; } /* scan conversion specifier and perform formatting */ save = *(c+1), *(c+1) = '\0'; if (*c == 'd' || *c == 'i' || *c == 'e' || *c == 'E' || *c == 'f' || *c == 'F' || *c == 'g' || *c == 'G') { /* the specifier requires numeric value */ double value; xassert(entry != NULL); switch (entry->code->type) { case A_NUMERIC: value = eval_numeric(mpl, entry->code); break; case A_SYMBOLIC: sym = eval_symbolic(mpl, entry->code); if (sym->str != NULL) mpl_error(mpl, "cannot convert %s to floating-point" " number", format_symbol(mpl, sym)); value = sym->num; delete_symbol(mpl, sym); break; case A_LOGICAL: if (eval_logical(mpl, entry->code)) value = 1.0; else value = 0.0; break; default: xassert(entry != entry); } if (*c == 'd' || *c == 'i') { double int_max = (double)INT_MAX; if (!(-int_max <= value && value <= +int_max)) mpl_error(mpl, "cannot convert %.*g to integer", DBL_DIG, value); print_text(mpl, from, (int)floor(value + 0.5)); } else print_text(mpl, from, value); } else if (*c == 's') { /* the specifier requires symbolic value */ char value[MAX_LENGTH+1]; switch (entry->code->type) { case A_NUMERIC: sprintf(value, "%.*g", DBL_DIG, eval_numeric(mpl, entry->code)); break; case A_LOGICAL: if (eval_logical(mpl, entry->code)) strcpy(value, "T"); else strcpy(value, "F"); break; case A_SYMBOLIC: sym = eval_symbolic(mpl, entry->code); if (sym->str == NULL) sprintf(value, "%.*g", DBL_DIG, sym->num); else fetch_string(mpl, sym->str, value); delete_symbol(mpl, sym); break; default: xassert(entry != entry); } print_text(mpl, from, value); } else mpl_error(mpl, "format specifier missing or invalid"); *(c+1) = save; entry = entry->next; } else if (*c == '\\') { /* write some control character */ c++; if (*c == 't') print_char(mpl, '\t'); else if (*c == 'n') print_char(mpl, '\n'); else print_char(mpl, *c); } else { /* write character without formatting */ print_char(mpl, *c); } } return 0; } #if 0 /* 14/VII-2006 */ void execute_printf(MPL *mpl, PRINTF *prt) { loop_within_domain(mpl, prt->domain, prt, printf_func); return; } #else void execute_printf(MPL *mpl, PRINTF *prt) { if (prt->fname == NULL) { /* switch to the standard output */ if (mpl->prt_fp != NULL) { xfclose(mpl->prt_fp), mpl->prt_fp = NULL; xfree(mpl->prt_file), mpl->prt_file = NULL; } } else { /* evaluate file name string */ SYMBOL *sym; char fname[MAX_LENGTH+1]; sym = eval_symbolic(mpl, prt->fname); if (sym->str == NULL) sprintf(fname, "%.*g", DBL_DIG, sym->num); else fetch_string(mpl, sym->str, fname); delete_symbol(mpl, sym); /* close the current print file, if necessary */ if (mpl->prt_fp != NULL && (!prt->app || strcmp(mpl->prt_file, fname) != 0)) { xfclose(mpl->prt_fp), mpl->prt_fp = NULL; xfree(mpl->prt_file), mpl->prt_file = NULL; } /* open the specified print file, if necessary */ if (mpl->prt_fp == NULL) { mpl->prt_fp = xfopen(fname, prt->app ? "a" : "w"); if (mpl->prt_fp == NULL) mpl_error(mpl, "unable to open `%s' for writing - %s", fname, xerrmsg()); mpl->prt_file = xmalloc(strlen(fname)+1); strcpy(mpl->prt_file, fname); } } loop_within_domain(mpl, prt->domain, prt, printf_func); if (mpl->prt_fp != NULL) { xfflush(mpl->prt_fp); if (xferror(mpl->prt_fp)) mpl_error(mpl, "writing error to `%s' - %s", mpl->prt_file, xerrmsg()); } return; } #endif /*---------------------------------------------------------------------- -- clean_printf - clean printf statement. -- -- This routine cleans specified printf statement that assumes deleting -- all stuff dynamically allocated on generating/postsolving phase. */ void clean_printf(MPL *mpl, PRINTF *prt) { PRINTF1 *p; /* clean subscript domain */ clean_domain(mpl, prt->domain); /* clean pseudo-code for computing format string */ clean_code(mpl, prt->fmt); /* clean printf list */ for (p = prt->list; p != NULL; p = p->next) { /* clean pseudo-code for computing value to be printed */ clean_code(mpl, p->code); } #if 1 /* 14/VII-2006 */ /* clean pseudo-code for computing file name string */ clean_code(mpl, prt->fname); #endif return; } /*---------------------------------------------------------------------- -- execute_for - execute for statement. -- -- This routine executes specified for statement. */ static int for_func(MPL *mpl, void *info) { /* this is auxiliary routine to work within domain scope */ FOR *fur = (FOR *)info; STATEMENT *stmt, *save; save = mpl->stmt; for (stmt = fur->list; stmt != NULL; stmt = stmt->next) execute_statement(mpl, stmt); mpl->stmt = save; return 0; } void execute_for(MPL *mpl, FOR *fur) { loop_within_domain(mpl, fur->domain, fur, for_func); return; } /*---------------------------------------------------------------------- -- clean_for - clean for statement. -- -- This routine cleans specified for statement that assumes deleting all -- stuff dynamically allocated on generating/postsolving phase. */ void clean_for(MPL *mpl, FOR *fur) { STATEMENT *stmt; /* clean subscript domain */ clean_domain(mpl, fur->domain); /* clean all sub-statements */ for (stmt = fur->list; stmt != NULL; stmt = stmt->next) clean_statement(mpl, stmt); return; } /*---------------------------------------------------------------------- -- execute_statement - execute specified model statement. -- -- This routine executes specified model statement. */ void execute_statement(MPL *mpl, STATEMENT *stmt) { mpl->stmt = stmt; switch (stmt->type) { case A_SET: case A_PARAMETER: case A_VARIABLE: break; case A_CONSTRAINT: xprintf("Generating %s...\n", stmt->u.con->name); eval_whole_con(mpl, stmt->u.con); break; case A_TABLE: switch (stmt->u.tab->type) { case A_INPUT: xprintf("Reading %s...\n", stmt->u.tab->name); break; case A_OUTPUT: xprintf("Writing %s...\n", stmt->u.tab->name); break; default: xassert(stmt != stmt); } execute_table(mpl, stmt->u.tab); break; case A_SOLVE: break; case A_CHECK: xprintf("Checking (line %d)...\n", stmt->line); execute_check(mpl, stmt->u.chk); break; case A_DISPLAY: write_text(mpl, "Display statement at line %d\n", stmt->line); execute_display(mpl, stmt->u.dpy); break; case A_PRINTF: execute_printf(mpl, stmt->u.prt); break; case A_FOR: execute_for(mpl, stmt->u.fur); break; default: xassert(stmt != stmt); } return; } /*---------------------------------------------------------------------- -- clean_statement - clean specified model statement. -- -- This routine cleans specified model statement that assumes deleting -- all stuff dynamically allocated on generating/postsolving phase. */ void clean_statement(MPL *mpl, STATEMENT *stmt) { switch(stmt->type) { case A_SET: clean_set(mpl, stmt->u.set); break; case A_PARAMETER: clean_parameter(mpl, stmt->u.par); break; case A_VARIABLE: clean_variable(mpl, stmt->u.var); break; case A_CONSTRAINT: clean_constraint(mpl, stmt->u.con); break; #if 1 /* 11/II-2008 */ case A_TABLE: clean_table(mpl, stmt->u.tab); break; #endif case A_SOLVE: break; case A_CHECK: clean_check(mpl, stmt->u.chk); break; case A_DISPLAY: clean_display(mpl, stmt->u.dpy); break; case A_PRINTF: clean_printf(mpl, stmt->u.prt); break; case A_FOR: clean_for(mpl, stmt->u.fur); break; default: xassert(stmt != stmt); } return; } /* eof */ praat-6.0.04/external/glpk/glpmpl04.c000066400000000000000000001342411261542461700173070ustar00rootroot00000000000000/* glpmpl04.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #define _GLPSTD_ERRNO #define _GLPSTD_STDIO #include "glpmpl.h" #define xfault xerror #define dmp_create_poolx(size) dmp_create_pool() /**********************************************************************/ /* * * GENERATING AND POSTSOLVING MODEL * * */ /**********************************************************************/ /*---------------------------------------------------------------------- -- alloc_content - allocate content arrays for all model objects. -- -- This routine allocates content arrays for all existing model objects -- and thereby finalizes creating model. -- -- This routine must be called immediately after reading model section, -- i.e. before reading data section or generating model. */ void alloc_content(MPL *mpl) { STATEMENT *stmt; /* walk through all model statements */ for (stmt = mpl->model; stmt != NULL; stmt = stmt->next) { switch (stmt->type) { case A_SET: /* model set */ xassert(stmt->u.set->array == NULL); stmt->u.set->array = create_array(mpl, A_ELEMSET, stmt->u.set->dim); break; case A_PARAMETER: /* model parameter */ xassert(stmt->u.par->array == NULL); switch (stmt->u.par->type) { case A_NUMERIC: case A_INTEGER: case A_BINARY: stmt->u.par->array = create_array(mpl, A_NUMERIC, stmt->u.par->dim); break; case A_SYMBOLIC: stmt->u.par->array = create_array(mpl, A_SYMBOLIC, stmt->u.par->dim); break; default: xassert(stmt != stmt); } break; case A_VARIABLE: /* model variable */ xassert(stmt->u.var->array == NULL); stmt->u.var->array = create_array(mpl, A_ELEMVAR, stmt->u.var->dim); break; case A_CONSTRAINT: /* model constraint/objective */ xassert(stmt->u.con->array == NULL); stmt->u.con->array = create_array(mpl, A_ELEMCON, stmt->u.con->dim); break; #if 1 /* 11/II-2008 */ case A_TABLE: #endif case A_SOLVE: case A_CHECK: case A_DISPLAY: case A_PRINTF: case A_FOR: /* functional statements have no content array */ break; default: xassert(stmt != stmt); } } return; } /*---------------------------------------------------------------------- -- generate_model - generate model. -- -- This routine executes the model statements which precede the solve -- statement. */ void generate_model(MPL *mpl) { STATEMENT *stmt; xassert(!mpl->flag_p); for (stmt = mpl->model; stmt != NULL; stmt = stmt->next) { execute_statement(mpl, stmt); if (mpl->stmt->type == A_SOLVE) break; } mpl->stmt = stmt; return; } /*---------------------------------------------------------------------- -- build_problem - build problem instance. -- -- This routine builds lists of rows and columns for problem instance, -- which corresponds to the generated model. */ void build_problem(MPL *mpl) { STATEMENT *stmt; MEMBER *memb; VARIABLE *v; CONSTRAINT *c; FORMULA *t; int i, j; xassert(mpl->m == 0); xassert(mpl->n == 0); xassert(mpl->row == NULL); xassert(mpl->col == NULL); /* check that all elemental variables has zero column numbers */ for (stmt = mpl->model; stmt != NULL; stmt = stmt->next) { if (stmt->type == A_VARIABLE) { v = stmt->u.var; for (memb = v->array->head; memb != NULL; memb = memb->next) xassert(memb->value.var->j == 0); } } /* assign row numbers to elemental constraints and objectives */ for (stmt = mpl->model; stmt != NULL; stmt = stmt->next) { if (stmt->type == A_CONSTRAINT) { c = stmt->u.con; for (memb = c->array->head; memb != NULL; memb = memb->next) { xassert(memb->value.con->i == 0); memb->value.con->i = ++mpl->m; /* walk through linear form and mark elemental variables, which are referenced at least once */ for (t = memb->value.con->form; t != NULL; t = t->next) { xassert(t->var != NULL); t->var->memb->value.var->j = -1; } } } } /* assign column numbers to marked elemental variables */ for (stmt = mpl->model; stmt != NULL; stmt = stmt->next) { if (stmt->type == A_VARIABLE) { v = stmt->u.var; for (memb = v->array->head; memb != NULL; memb = memb->next) if (memb->value.var->j != 0) memb->value.var->j = ++mpl->n; } } /* build list of rows */ mpl->row = xcalloc(1+mpl->m, sizeof(ELEMCON *)); for (i = 1; i <= mpl->m; i++) mpl->row[i] = NULL; for (stmt = mpl->model; stmt != NULL; stmt = stmt->next) { if (stmt->type == A_CONSTRAINT) { c = stmt->u.con; for (memb = c->array->head; memb != NULL; memb = memb->next) { i = memb->value.con->i; xassert(1 <= i && i <= mpl->m); xassert(mpl->row[i] == NULL); mpl->row[i] = memb->value.con; } } } for (i = 1; i <= mpl->m; i++) xassert(mpl->row[i] != NULL); /* build list of columns */ mpl->col = xcalloc(1+mpl->n, sizeof(ELEMVAR *)); for (j = 1; j <= mpl->n; j++) mpl->col[j] = NULL; for (stmt = mpl->model; stmt != NULL; stmt = stmt->next) { if (stmt->type == A_VARIABLE) { v = stmt->u.var; for (memb = v->array->head; memb != NULL; memb = memb->next) { j = memb->value.var->j; if (j == 0) continue; xassert(1 <= j && j <= mpl->n); xassert(mpl->col[j] == NULL); mpl->col[j] = memb->value.var; } } } for (j = 1; j <= mpl->n; j++) xassert(mpl->col[j] != NULL); return; } /*---------------------------------------------------------------------- -- postsolve_model - postsolve model. -- -- This routine executes the model statements which follow the solve -- statement. */ void postsolve_model(MPL *mpl) { STATEMENT *stmt; xassert(!mpl->flag_p); mpl->flag_p = 1; for (stmt = mpl->stmt; stmt != NULL; stmt = stmt->next) execute_statement(mpl, stmt); mpl->stmt = NULL; return; } /*---------------------------------------------------------------------- -- clean_model - clean model content. -- -- This routine cleans the model content that assumes deleting all stuff -- dynamically allocated on generating/postsolving phase. -- -- Actually cleaning model content is not needed. This function is used -- mainly to be sure that there were no logical errors on using dynamic -- memory pools during the generation phase. -- -- NOTE: This routine must not be called if any errors were detected on -- the generation phase. */ void clean_model(MPL *mpl) { STATEMENT *stmt; for (stmt = mpl->model; stmt != NULL; stmt = stmt->next) clean_statement(mpl, stmt); /* check that all atoms have been returned to their pools */ if (dmp_in_use(mpl->strings).lo != 0) mpl_error(mpl, "internal logic error: %d string segment(s) were lo" "st", dmp_in_use(mpl->strings).lo); if (dmp_in_use(mpl->symbols).lo != 0) mpl_error(mpl, "internal logic error: %d symbol(s) were lost", dmp_in_use(mpl->symbols).lo); if (dmp_in_use(mpl->tuples).lo != 0) mpl_error(mpl, "internal logic error: %d n-tuple component(s) were" " lost", dmp_in_use(mpl->tuples).lo); if (dmp_in_use(mpl->arrays).lo != 0) mpl_error(mpl, "internal logic error: %d array(s) were lost", dmp_in_use(mpl->arrays).lo); if (dmp_in_use(mpl->members).lo != 0) mpl_error(mpl, "internal logic error: %d array member(s) were lost" , dmp_in_use(mpl->members).lo); if (dmp_in_use(mpl->elemvars).lo != 0) mpl_error(mpl, "internal logic error: %d elemental variable(s) wer" "e lost", dmp_in_use(mpl->elemvars).lo); if (dmp_in_use(mpl->formulae).lo != 0) mpl_error(mpl, "internal logic error: %d linear term(s) were lost", dmp_in_use(mpl->formulae).lo); if (dmp_in_use(mpl->elemcons).lo != 0) mpl_error(mpl, "internal logic error: %d elemental constraint(s) w" "ere lost", dmp_in_use(mpl->elemcons).lo); return; } /**********************************************************************/ /* * * INPUT/OUTPUT * * */ /**********************************************************************/ /*---------------------------------------------------------------------- -- open_input - open input text file. -- -- This routine opens the input text file for scanning. */ void open_input(MPL *mpl, char *file) { mpl->line = 0; mpl->c = '\n'; mpl->token = 0; mpl->imlen = 0; mpl->image[0] = '\0'; mpl->value = 0.0; mpl->b_token = T_EOF; mpl->b_imlen = 0; mpl->b_image[0] = '\0'; mpl->b_value = 0.0; mpl->f_dots = 0; mpl->f_scan = 0; mpl->f_token = 0; mpl->f_imlen = 0; mpl->f_image[0] = '\0'; mpl->f_value = 0.0; memset(mpl->context, ' ', CONTEXT_SIZE); mpl->c_ptr = 0; xassert(mpl->in_fp == NULL); mpl->in_fp = xfopen(file, "r"); if (mpl->in_fp == NULL) mpl_error(mpl, "unable to open %s - %s", file, xerrmsg()); mpl->in_file = file; /* scan the very first character */ get_char(mpl); /* scan the very first token */ get_token(mpl); return; } /*---------------------------------------------------------------------- -- read_char - read next character from input text file. -- -- This routine returns a next ASCII character read from the input text -- file. If the end of file has been reached, EOF is returned. */ int read_char(MPL *mpl) { int c; xassert(mpl->in_fp != NULL); c = xfgetc(mpl->in_fp); if (c < 0) { if (xferror(mpl->in_fp)) mpl_error(mpl, "read error on %s - %s", mpl->in_file, xerrmsg()); c = EOF; } return c; } /*---------------------------------------------------------------------- -- close_input - close input text file. -- -- This routine closes the input text file. */ void close_input(MPL *mpl) { xassert(mpl->in_fp != NULL); xfclose(mpl->in_fp); mpl->in_fp = NULL; mpl->in_file = NULL; return; } /*---------------------------------------------------------------------- -- open_output - open output text file. -- -- This routine opens the output text file for writing data produced by -- display and printf statements. */ void open_output(MPL *mpl, char *file) { xassert(mpl->out_fp == NULL); if (file == NULL) { file = ""; mpl->out_fp = (void *)stdout; } else { mpl->out_fp = xfopen(file, "w"); if (mpl->out_fp == NULL) mpl_error(mpl, "unable to create %s - %s", file, xerrmsg()); } mpl->out_file = xmalloc(strlen(file)+1); strcpy(mpl->out_file, file); return; } /*---------------------------------------------------------------------- -- write_char - write next character to output text file. -- -- This routine writes an ASCII character to the output text file. */ void write_char(MPL *mpl, int c) { xassert(mpl->out_fp != NULL); if (mpl->out_fp == (void *)stdout) xprintf("%c", c); else xfprintf(mpl->out_fp, "%c", c); return; } /*---------------------------------------------------------------------- -- write_text - format and write text to output text file. -- -- This routine formats a text using the format control string and then -- writes this text to the output text file. */ void write_text(MPL *mpl, char *fmt, ...) { va_list arg; char buf[OUTBUF_SIZE], *c; va_start(arg, fmt); vsprintf(buf, fmt, arg); xassert(strlen(buf) < sizeof(buf)); va_end(arg); for (c = buf; *c != '\0'; c++) write_char(mpl, *c); return; } /*---------------------------------------------------------------------- -- flush_output - finalize writing data to output text file. -- -- This routine finalizes writing data to the output text file. */ void flush_output(MPL *mpl) { xassert(mpl->out_fp != NULL); if (mpl->out_fp != (void *)stdout) { xfflush(mpl->out_fp); if (xferror(mpl->out_fp)) mpl_error(mpl, "write error on %s - %s", mpl->out_file, xerrmsg()); } return; } /**********************************************************************/ /* * * SOLVER INTERFACE * * */ /**********************************************************************/ /*---------------------------------------------------------------------- -- error - print error message and terminate model processing. -- -- This routine formats and prints an error message and then terminates -- model processing. */ void mpl_error(MPL *mpl, char *fmt, ...) { va_list arg; char msg[4095+1]; va_start(arg, fmt); vsprintf(msg, fmt, arg); xassert(strlen(msg) < sizeof(msg)); va_end(arg); switch (mpl->phase) { case 1: case 2: /* translation phase */ xprintf("%s:%d: %s\n", mpl->in_file == NULL ? "(unknown)" : mpl->in_file, mpl->line, msg); print_context(mpl); break; case 3: /* generation/postsolve phase */ xprintf("%s:%d: %s\n", mpl->mod_file == NULL ? "(unknown)" : mpl->mod_file, mpl->stmt == NULL ? 0 : mpl->stmt->line, msg); break; default: xassert(mpl != mpl); } mpl->phase = 4; longjmp(mpl->jump, 1); /* no return */ } /*---------------------------------------------------------------------- -- warning - print warning message and continue model processing. -- -- This routine formats and prints a warning message and returns to the -- calling program. */ void warning(MPL *mpl, char *fmt, ...) { va_list arg; char msg[4095+1]; va_start(arg, fmt); vsprintf(msg, fmt, arg); xassert(strlen(msg) < sizeof(msg)); va_end(arg); switch (mpl->phase) { case 1: case 2: /* translation phase */ xprintf("%s:%d: warning: %s\n", mpl->in_file == NULL ? "(unknown)" : mpl->in_file, mpl->line, msg); break; case 3: /* generation/postsolve phase */ xprintf("%s:%d: warning: %s\n", mpl->mod_file == NULL ? "(unknown)" : mpl->mod_file, mpl->stmt == NULL ? 0 : mpl->stmt->line, msg); break; default: xassert(mpl != mpl); } return; } /*---------------------------------------------------------------------- -- mpl_initialize - create and initialize translator database. -- -- *Synopsis* -- -- #include "glpmpl.h" -- MPL *mpl_initialize(void); -- -- *Description* -- -- The routine mpl_initialize creates and initializes the database used -- by the GNU MathProg translator. -- -- *Returns* -- -- The routine returns a pointer to the database created. */ MPL *mpl_initialize(void) { MPL *mpl; mpl = xmalloc(sizeof(MPL)); /* scanning segment */ mpl->line = 0; mpl->c = 0; mpl->token = 0; mpl->imlen = 0; mpl->image = xcalloc(MAX_LENGTH+1, sizeof(char)); mpl->image[0] = '\0'; mpl->value = 0.0; mpl->b_token = 0; mpl->b_imlen = 0; mpl->b_image = xcalloc(MAX_LENGTH+1, sizeof(char)); mpl->b_image[0] = '\0'; mpl->b_value = 0.0; mpl->f_dots = 0; mpl->f_scan = 0; mpl->f_token = 0; mpl->f_imlen = 0; mpl->f_image = xcalloc(MAX_LENGTH+1, sizeof(char)); mpl->f_image[0] = '\0'; mpl->f_value = 0.0; mpl->context = xcalloc(CONTEXT_SIZE, sizeof(char)); memset(mpl->context, ' ', CONTEXT_SIZE); mpl->c_ptr = 0; mpl->flag_d = 0; /* translating segment */ mpl->pool = dmp_create_poolx(0); mpl->tree = avl_create_tree(avl_strcmp, NULL); mpl->model = NULL; mpl->flag_x = 0; mpl->as_within = 0; mpl->as_in = 0; mpl->as_binary = 0; mpl->flag_s = 0; /* common segment */ mpl->strings = dmp_create_poolx(sizeof(STRING)); mpl->symbols = dmp_create_poolx(sizeof(SYMBOL)); mpl->tuples = dmp_create_poolx(sizeof(TUPLE)); mpl->arrays = dmp_create_poolx(sizeof(ARRAY)); mpl->members = dmp_create_poolx(sizeof(MEMBER)); mpl->elemvars = dmp_create_poolx(sizeof(ELEMVAR)); mpl->formulae = dmp_create_poolx(sizeof(FORMULA)); mpl->elemcons = dmp_create_poolx(sizeof(ELEMCON)); mpl->a_list = NULL; mpl->sym_buf = xcalloc(255+1, sizeof(char)); mpl->sym_buf[0] = '\0'; mpl->tup_buf = xcalloc(255+1, sizeof(char)); mpl->tup_buf[0] = '\0'; /* generating/postsolving segment */ mpl->rand = rng_create_rand(); mpl->flag_p = 0; mpl->stmt = NULL; #if 1 /* 11/II-2008 */ mpl->dca = NULL; #endif mpl->m = 0; mpl->n = 0; mpl->row = NULL; mpl->col = NULL; /* input/output segment */ mpl->in_fp = NULL; mpl->in_file = NULL; mpl->out_fp = NULL; mpl->out_file = NULL; mpl->prt_fp = NULL; mpl->prt_file = NULL; /* solver interface segment */ if (setjmp(mpl->jump)) xassert(mpl != mpl); mpl->phase = 0; mpl->mod_file = NULL; mpl->mpl_buf = xcalloc(255+1, sizeof(char)); mpl->mpl_buf[0] = '\0'; return mpl; } /*---------------------------------------------------------------------- -- mpl_read_model - read model section and optional data section. -- -- *Synopsis* -- -- #include "glpmpl.h" -- int mpl_read_model(MPL *mpl, char *file, int skip_data); -- -- *Description* -- -- The routine mpl_read_model reads model section and optionally data -- section, which may follow the model section, from the text file, -- whose name is the character string file, performs translating model -- statements and data blocks, and stores all the information in the -- translator database. -- -- The parameter skip_data is a flag. If the input file contains the -- data section and this flag is set, the data section is not read as -- if there were no data section and a warning message is issued. This -- allows reading the data section from another input file. -- -- This routine should be called once after the routine mpl_initialize -- and before other API routines. -- -- *Returns* -- -- The routine mpl_read_model returns one the following codes: -- -- 1 - translation successful. The input text file contains only model -- section. In this case the calling program may call the routine -- mpl_read_data to read data section from another file. -- 2 - translation successful. The input text file contains both model -- and data section. -- 4 - processing failed due to some errors. In this case the calling -- program should call the routine mpl_terminate to terminate model -- processing. */ int mpl_read_model(MPL *mpl, char *file, int skip_data) { if (mpl->phase != 0) xfault("mpl_read_model: invalid call sequence\n"); if (file == NULL) xfault("mpl_read_model: no input filename specified\n"); /* set up error handler */ if (setjmp(mpl->jump)) goto done; /* translate model section */ mpl->phase = 1; xprintf("Reading model section from %s...\n", file); open_input(mpl, file); model_section(mpl); if (mpl->model == NULL) mpl_error(mpl, "empty model section not allowed"); /* save name of the input text file containing model section for error diagnostics during the generation phase */ mpl->mod_file = xcalloc(strlen(file)+1, sizeof(char)); strcpy(mpl->mod_file, mpl->in_file); /* allocate content arrays for all model objects */ alloc_content(mpl); /* optional data section may begin with the keyword 'data' */ if (is_keyword(mpl, "data")) { if (skip_data) { warning(mpl, "data section ignored"); goto skip; } mpl->flag_d = 1; get_token(mpl /* data */); if (mpl->token != T_SEMICOLON) mpl_error(mpl, "semicolon missing where expected"); get_token(mpl /* ; */); /* translate data section */ mpl->phase = 2; xprintf("Reading data section from %s...\n", file); data_section(mpl); } /* process end statement */ end_statement(mpl); skip: xprintf("%d line%s were read\n", mpl->line, mpl->line == 1 ? "" : "s"); close_input(mpl); done: /* return to the calling program */ return mpl->phase; } /*---------------------------------------------------------------------- -- mpl_read_data - read data section. -- -- *Synopsis* -- -- #include "glpmpl.h" -- int mpl_read_data(MPL *mpl, char *file); -- -- *Description* -- -- The routine mpl_read_data reads data section from the text file, -- whose name is the character string file, performs translating data -- blocks, and stores the data read in the translator database. -- -- If this routine is used, it should be called once after the routine -- mpl_read_model and if the latter returned the code 1. -- -- *Returns* -- -- The routine mpl_read_data returns one of the following codes: -- -- 2 - data section has been successfully processed. -- 4 - processing failed due to some errors. In this case the calling -- program should call the routine mpl_terminate to terminate model -- processing. */ int mpl_read_data(MPL *mpl, char *file) #if 0 /* 02/X-2008 */ { if (mpl->phase != 1) #else { if (!(mpl->phase == 1 || mpl->phase == 2)) #endif xfault("mpl_read_data: invalid call sequence\n"); if (file == NULL) xfault("mpl_read_data: no input filename specified\n"); /* set up error handler */ if (setjmp(mpl->jump)) goto done; /* process data section */ mpl->phase = 2; xprintf("Reading data section from %s...\n", file); mpl->flag_d = 1; open_input(mpl, file); /* in this case the keyword 'data' is optional */ if (is_literal(mpl, "data")) { get_token(mpl /* data */); if (mpl->token != T_SEMICOLON) mpl_error(mpl, "semicolon missing where expected"); get_token(mpl /* ; */); } data_section(mpl); /* process end statement */ end_statement(mpl); xprintf("%d line%s were read\n", mpl->line, mpl->line == 1 ? "" : "s"); close_input(mpl); done: /* return to the calling program */ return mpl->phase; } /*---------------------------------------------------------------------- -- mpl_generate - generate model. -- -- *Synopsis* -- -- #include "glpmpl.h" -- int mpl_generate(MPL *mpl, char *file); -- -- *Description* -- -- The routine mpl_generate generates the model using its description -- stored in the translator database. This phase means generating all -- variables, constraints, and objectives, executing check and display -- statements, which precede the solve statement (if it is presented), -- and building the problem instance. -- -- The character string file specifies the name of output text file, to -- which output produced by display statements should be written. It is -- allowed to specify NULL, in which case the output goes to stdout via -- the routine print. -- -- This routine should be called once after the routine mpl_read_model -- or mpl_read_data and if one of the latters returned the code 2. -- -- *Returns* -- -- The routine mpl_generate returns one of the following codes: -- -- 3 - model has been successfully generated. In this case the calling -- program may call other api routines to obtain components of the -- problem instance from the translator database. -- 4 - processing failed due to some errors. In this case the calling -- program should call the routine mpl_terminate to terminate model -- processing. */ int mpl_generate(MPL *mpl, char *file) { if (!(mpl->phase == 1 || mpl->phase == 2)) xfault("mpl_generate: invalid call sequence\n"); /* set up error handler */ if (setjmp(mpl->jump)) goto done; /* generate model */ mpl->phase = 3; open_output(mpl, file); generate_model(mpl); flush_output(mpl); /* build problem instance */ build_problem(mpl); /* generation phase has been finished */ xprintf("Model has been successfully generated\n"); done: /* return to the calling program */ return mpl->phase; } /*---------------------------------------------------------------------- -- mpl_get_prob_name - obtain problem (model) name. -- -- *Synopsis* -- -- #include "glpmpl.h" -- char *mpl_get_prob_name(MPL *mpl); -- -- *Returns* -- -- The routine mpl_get_prob_name returns a pointer to internal buffer, -- which contains symbolic name of the problem (model). -- -- *Note* -- -- Currently MathProg has no feature to assign a symbolic name to the -- model. Therefore the routine mpl_get_prob_name tries to construct -- such name using the name of input text file containing model section, -- although this is not a good idea (due to portability problems). */ char *mpl_get_prob_name(MPL *mpl) { char *name = mpl->mpl_buf; char *file = mpl->mod_file; int k; if (mpl->phase != 3) xfault("mpl_get_prob_name: invalid call sequence\n"); for (;;) { if (strchr(file, '/') != NULL) file = strchr(file, '/') + 1; else if (strchr(file, '\\') != NULL) file = strchr(file, '\\') + 1; else if (strchr(file, ':') != NULL) file = strchr(file, ':') + 1; else break; } for (k = 0; ; k++) { if (k == 255) break; if (!(isalnum((unsigned char)*file) || *file == '_')) break; name[k] = *file++; } if (k == 0) strcpy(name, "Unknown"); else name[k] = '\0'; xassert(strlen(name) <= 255); return name; } /*---------------------------------------------------------------------- -- mpl_get_num_rows - determine number of rows. -- -- *Synopsis* -- -- #include "glpmpl.h" -- int mpl_get_num_rows(MPL *mpl); -- -- *Returns* -- -- The routine mpl_get_num_rows returns total number of rows in the -- problem, where each row is an individual constraint or objective. */ int mpl_get_num_rows(MPL *mpl) { if (mpl->phase != 3) xfault("mpl_get_num_rows: invalid call sequence\n"); return mpl->m; } /*---------------------------------------------------------------------- -- mpl_get_num_cols - determine number of columns. -- -- *Synopsis* -- -- #include "glpmpl.h" -- int mpl_get_num_cols(MPL *mpl); -- -- *Returns* -- -- The routine mpl_get_num_cols returns total number of columns in the -- problem, where each column is an individual variable. */ int mpl_get_num_cols(MPL *mpl) { if (mpl->phase != 3) xfault("mpl_get_num_cols: invalid call sequence\n"); return mpl->n; } /*---------------------------------------------------------------------- -- mpl_get_row_name - obtain row name. -- -- *Synopsis* -- -- #include "glpmpl.h" -- char *mpl_get_row_name(MPL *mpl, int i); -- -- *Returns* -- -- The routine mpl_get_row_name returns a pointer to internal buffer, -- which contains symbolic name of i-th row of the problem. */ char *mpl_get_row_name(MPL *mpl, int i) { char *name = mpl->mpl_buf, *t; int len; if (mpl->phase != 3) xfault("mpl_get_row_name: invalid call sequence\n"); if (!(1 <= i && i <= mpl->m)) xfault("mpl_get_row_name: i = %d; row number out of range\n", i); strcpy(name, mpl->row[i]->con->name); len = strlen(name); xassert(len <= 255); t = format_tuple(mpl, '[', mpl->row[i]->memb->tuple); while (*t) { if (len == 255) break; name[len++] = *t++; } name[len] = '\0'; if (len == 255) strcpy(name+252, "..."); xassert(strlen(name) <= 255); return name; } /*---------------------------------------------------------------------- -- mpl_get_row_kind - determine row kind. -- -- *Synopsis* -- -- #include "glpmpl.h" -- int mpl_get_row_kind(MPL *mpl, int i); -- -- *Returns* -- -- The routine mpl_get_row_kind returns the kind of i-th row, which can -- be one of the following: -- -- MPL_ST - non-free (constraint) row; -- MPL_MIN - free (objective) row to be minimized; -- MPL_MAX - free (objective) row to be maximized. */ int mpl_get_row_kind(MPL *mpl, int i) { int kind; if (mpl->phase != 3) xfault("mpl_get_row_kind: invalid call sequence\n"); if (!(1 <= i && i <= mpl->m)) xfault("mpl_get_row_kind: i = %d; row number out of range\n", i); switch (mpl->row[i]->con->type) { case A_CONSTRAINT: kind = MPL_ST; break; case A_MINIMIZE: kind = MPL_MIN; break; case A_MAXIMIZE: kind = MPL_MAX; break; default: xassert(mpl != mpl); } return kind; } /*---------------------------------------------------------------------- -- mpl_get_row_bnds - obtain row bounds. -- -- *Synopsis* -- -- #include "glpmpl.h" -- int mpl_get_row_bnds(MPL *mpl, int i, double *lb, double *ub); -- -- *Description* -- -- The routine mpl_get_row_bnds stores lower and upper bounds of i-th -- row of the problem to the locations, which the parameters lb and ub -- point to, respectively. Besides the routine returns the type of the -- i-th row. -- -- If some of the parameters lb and ub is NULL, the corresponding bound -- value is not stored. -- -- Types and bounds have the following meaning: -- -- Type Bounds Note -- ----------------------------------------------------------- -- MPL_FR -inf < f(x) < +inf Free linear form -- MPL_LO lb <= f(x) < +inf Inequality f(x) >= lb -- MPL_UP -inf < f(x) <= ub Inequality f(x) <= ub -- MPL_DB lb <= f(x) <= ub Inequality lb <= f(x) <= ub -- MPL_FX f(x) = lb Equality f(x) = lb -- -- where f(x) is the corresponding linear form of the i-th row. -- -- If the row has no lower bound, *lb is set to zero; if the row has -- no upper bound, *ub is set to zero; and if the row is of fixed type, -- both *lb and *ub are set to the same value. -- -- *Returns* -- -- The routine returns the type of the i-th row as it is stated in the -- table above. */ int mpl_get_row_bnds(MPL *mpl, int i, double *_lb, double *_ub) { ELEMCON *con; int type; double lb, ub; if (mpl->phase != 3) xfault("mpl_get_row_bnds: invalid call sequence\n"); if (!(1 <= i && i <= mpl->m)) xfault("mpl_get_row_bnds: i = %d; row number out of range\n", i); con = mpl->row[i]; #if 0 /* 21/VII-2006 */ if (con->con->lbnd == NULL && con->con->ubnd == NULL) type = MPL_FR, lb = ub = 0.0; else if (con->con->ubnd == NULL) type = MPL_LO, lb = con->lbnd, ub = 0.0; else if (con->con->lbnd == NULL) type = MPL_UP, lb = 0.0, ub = con->ubnd; else if (con->con->lbnd != con->con->ubnd) type = MPL_DB, lb = con->lbnd, ub = con->ubnd; else type = MPL_FX, lb = ub = con->lbnd; #else lb = (con->con->lbnd == NULL ? -DBL_MAX : con->lbnd); ub = (con->con->ubnd == NULL ? +DBL_MAX : con->ubnd); if (lb == -DBL_MAX && ub == +DBL_MAX) type = MPL_FR, lb = ub = 0.0; else if (ub == +DBL_MAX) type = MPL_LO, ub = 0.0; else if (lb == -DBL_MAX) type = MPL_UP, lb = 0.0; else if (con->con->lbnd != con->con->ubnd) type = MPL_DB; else type = MPL_FX; #endif if (_lb != NULL) *_lb = lb; if (_ub != NULL) *_ub = ub; return type; } /*---------------------------------------------------------------------- -- mpl_get_mat_row - obtain row of the constraint matrix. -- -- *Synopsis* -- -- #include "glpmpl.h" -- int mpl_get_mat_row(MPL *mpl, int i, int ndx[], double val[]); -- -- *Description* -- -- The routine mpl_get_mat_row stores column indices and numeric values -- of constraint coefficients for the i-th row to locations ndx[1], ..., -- ndx[len] and val[1], ..., val[len], respectively, where 0 <= len <= n -- is number of (structural) non-zero constraint coefficients, and n is -- number of columns in the problem. -- -- If the parameter ndx is NULL, column indices are not stored. If the -- parameter val is NULL, numeric values are not stored. -- -- Note that free rows may have constant terms, which are not part of -- the constraint matrix and therefore not reported by this routine. The -- constant term of a particular row can be obtained, if necessary, via -- the routine mpl_get_row_c0. -- -- *Returns* -- -- The routine mpl_get_mat_row returns len, which is length of i-th row -- of the constraint matrix (i.e. number of non-zero coefficients). */ int mpl_get_mat_row(MPL *mpl, int i, int ndx[], double val[]) { FORMULA *term; int len = 0; if (mpl->phase != 3) xfault("mpl_get_mat_row: invalid call sequence\n"); if (!(1 <= i && i <= mpl->m)) xfault("mpl_get_mat_row: i = %d; row number out of range\n", i); for (term = mpl->row[i]->form; term != NULL; term = term->next) { xassert(term->var != NULL); len++; xassert(len <= mpl->n); if (ndx != NULL) ndx[len] = term->var->j; if (val != NULL) val[len] = term->coef; } return len; } /*---------------------------------------------------------------------- -- mpl_get_row_c0 - obtain constant term of free row. -- -- *Synopsis* -- -- #include "glpmpl.h" -- double mpl_get_row_c0(MPL *mpl, int i); -- -- *Returns* -- -- The routine mpl_get_row_c0 returns numeric value of constant term of -- i-th row. -- -- Note that only free rows may have non-zero constant terms. Therefore -- if i-th row is not free, the routine returns zero. */ double mpl_get_row_c0(MPL *mpl, int i) { ELEMCON *con; double c0; if (mpl->phase != 3) xfault("mpl_get_row_c0: invalid call sequence\n"); if (!(1 <= i && i <= mpl->m)) xfault("mpl_get_row_c0: i = %d; row number out of range\n", i); con = mpl->row[i]; if (con->con->lbnd == NULL && con->con->ubnd == NULL) c0 = - con->lbnd; else c0 = 0.0; return c0; } /*---------------------------------------------------------------------- -- mpl_get_col_name - obtain column name. -- -- *Synopsis* -- -- #include "glpmpl.h" -- char *mpl_get_col_name(MPL *mpl, int j); -- -- *Returns* -- -- The routine mpl_get_col_name returns a pointer to internal buffer, -- which contains symbolic name of j-th column of the problem. */ char *mpl_get_col_name(MPL *mpl, int j) { char *name = mpl->mpl_buf, *t; int len; if (mpl->phase != 3) xfault("mpl_get_col_name: invalid call sequence\n"); if (!(1 <= j && j <= mpl->n)) xfault("mpl_get_col_name: j = %d; column number out of range\n" , j); strcpy(name, mpl->col[j]->var->name); len = strlen(name); xassert(len <= 255); t = format_tuple(mpl, '[', mpl->col[j]->memb->tuple); while (*t) { if (len == 255) break; name[len++] = *t++; } name[len] = '\0'; if (len == 255) strcpy(name+252, "..."); xassert(strlen(name) <= 255); return name; } /*---------------------------------------------------------------------- -- mpl_get_col_kind - determine column kind. -- -- *Synopsis* -- -- #include "glpmpl.h" -- int mpl_get_col_kind(MPL *mpl, int j); -- -- *Returns* -- -- The routine mpl_get_col_kind returns the kind of j-th column, which -- can be one of the following: -- -- MPL_NUM - continuous variable; -- MPL_INT - integer variable; -- MPL_BIN - binary variable. -- -- Note that column kinds are defined independently on type and bounds -- (reported by the routine mpl_get_col_bnds) of corresponding columns. -- This means, in particular, that bounds of an integer column may be -- fractional, or a binary column may have lower and upper bounds that -- are not 0 and 1 (or it may have no lower/upper bound at all). */ int mpl_get_col_kind(MPL *mpl, int j) { int kind; if (mpl->phase != 3) xfault("mpl_get_col_kind: invalid call sequence\n"); if (!(1 <= j && j <= mpl->n)) xfault("mpl_get_col_kind: j = %d; column number out of range\n" , j); switch (mpl->col[j]->var->type) { case A_NUMERIC: kind = MPL_NUM; break; case A_INTEGER: kind = MPL_INT; break; case A_BINARY: kind = MPL_BIN; break; default: xassert(mpl != mpl); } return kind; } /*---------------------------------------------------------------------- -- mpl_get_col_bnds - obtain column bounds. -- -- *Synopsis* -- -- #include "glpmpl.h" -- int mpl_get_col_bnds(MPL *mpl, int j, double *lb, double *ub); -- -- *Description* -- -- The routine mpl_get_col_bnds stores lower and upper bound of j-th -- column of the problem to the locations, which the parameters lb and -- ub point to, respectively. Besides the routine returns the type of -- the j-th column. -- -- If some of the parameters lb and ub is NULL, the corresponding bound -- value is not stored. -- -- Types and bounds have the following meaning: -- -- Type Bounds Note -- ------------------------------------------------------ -- MPL_FR -inf < x < +inf Free (unbounded) variable -- MPL_LO lb <= x < +inf Variable with lower bound -- MPL_UP -inf < x <= ub Variable with upper bound -- MPL_DB lb <= x <= ub Double-bounded variable -- MPL_FX x = lb Fixed variable -- -- where x is individual variable corresponding to the j-th column. -- -- If the column has no lower bound, *lb is set to zero; if the column -- has no upper bound, *ub is set to zero; and if the column is of fixed -- type, both *lb and *ub are set to the same value. -- -- *Returns* -- -- The routine returns the type of the j-th column as it is stated in -- the table above. */ int mpl_get_col_bnds(MPL *mpl, int j, double *_lb, double *_ub) { ELEMVAR *var; int type; double lb, ub; if (mpl->phase != 3) xfault("mpl_get_col_bnds: invalid call sequence\n"); if (!(1 <= j && j <= mpl->n)) xfault("mpl_get_col_bnds: j = %d; column number out of range\n" , j); var = mpl->col[j]; #if 0 /* 21/VII-2006 */ if (var->var->lbnd == NULL && var->var->ubnd == NULL) type = MPL_FR, lb = ub = 0.0; else if (var->var->ubnd == NULL) type = MPL_LO, lb = var->lbnd, ub = 0.0; else if (var->var->lbnd == NULL) type = MPL_UP, lb = 0.0, ub = var->ubnd; else if (var->var->lbnd != var->var->ubnd) type = MPL_DB, lb = var->lbnd, ub = var->ubnd; else type = MPL_FX, lb = ub = var->lbnd; #else lb = (var->var->lbnd == NULL ? -DBL_MAX : var->lbnd); ub = (var->var->ubnd == NULL ? +DBL_MAX : var->ubnd); if (lb == -DBL_MAX && ub == +DBL_MAX) type = MPL_FR, lb = ub = 0.0; else if (ub == +DBL_MAX) type = MPL_LO, ub = 0.0; else if (lb == -DBL_MAX) type = MPL_UP, lb = 0.0; else if (var->var->lbnd != var->var->ubnd) type = MPL_DB; else type = MPL_FX; #endif if (_lb != NULL) *_lb = lb; if (_ub != NULL) *_ub = ub; return type; } /*---------------------------------------------------------------------- -- mpl_has_solve_stmt - check if model has solve statement. -- -- *Synopsis* -- -- #include "glpmpl.h" -- int mpl_has_solve_stmt(MPL *mpl); -- -- *Returns* -- -- If the model has the solve statement, the routine returns non-zero, -- otherwise zero is returned. */ int mpl_has_solve_stmt(MPL *mpl) { if (mpl->phase != 3) xfault("mpl_has_solve_stmt: invalid call sequence\n"); return mpl->flag_s; } #if 1 /* 15/V-2010 */ void mpl_put_row_soln(MPL *mpl, int i, int stat, double prim, double dual) { /* store row (constraint/objective) solution components */ xassert(mpl->phase == 3); xassert(1 <= i && i <= mpl->m); mpl->row[i]->stat = stat; mpl->row[i]->prim = prim; mpl->row[i]->dual = dual; return; } #endif #if 1 /* 15/V-2010 */ void mpl_put_col_soln(MPL *mpl, int j, int stat, double prim, double dual) { /* store column (variable) solution components */ xassert(mpl->phase == 3); xassert(1 <= j && j <= mpl->n); mpl->col[j]->stat = stat; mpl->col[j]->prim = prim; mpl->col[j]->dual = dual; return; } #endif #if 0 /* 15/V-2010 */ /*---------------------------------------------------------------------- -- mpl_put_col_value - store column value. -- -- *Synopsis* -- -- #include "glpmpl.h" -- void mpl_put_col_value(MPL *mpl, int j, double val); -- -- *Description* -- -- The routine mpl_put_col_value stores numeric value of j-th column -- into the translator database. It is assumed that the column value is -- provided by the solver. */ void mpl_put_col_value(MPL *mpl, int j, double val) { if (mpl->phase != 3) xfault("mpl_put_col_value: invalid call sequence\n"); if (!(1 <= j && j <= mpl->n)) xfault( "mpl_put_col_value: j = %d; column number out of range\n", j); mpl->col[j]->prim = val; return; } #endif /*---------------------------------------------------------------------- -- mpl_postsolve - postsolve model. -- -- *Synopsis* -- -- #include "glpmpl.h" -- int mpl_postsolve(MPL *mpl); -- -- *Description* -- -- The routine mpl_postsolve performs postsolving of the model using -- its description stored in the translator database. This phase means -- executing statements, which follow the solve statement. -- -- If this routine is used, it should be called once after the routine -- mpl_generate and if the latter returned the code 3. -- -- *Returns* -- -- The routine mpl_postsolve returns one of the following codes: -- -- 3 - model has been successfully postsolved. -- 4 - processing failed due to some errors. In this case the calling -- program should call the routine mpl_terminate to terminate model -- processing. */ int mpl_postsolve(MPL *mpl) { if (!(mpl->phase == 3 && !mpl->flag_p)) xfault("mpl_postsolve: invalid call sequence\n"); /* set up error handler */ if (setjmp(mpl->jump)) goto done; /* perform postsolving */ postsolve_model(mpl); flush_output(mpl); /* postsolving phase has been finished */ xprintf("Model has been successfully processed\n"); done: /* return to the calling program */ return mpl->phase; } /*---------------------------------------------------------------------- -- mpl_terminate - free all resources used by translator. -- -- *Synopsis* -- -- #include "glpmpl.h" -- void mpl_terminate(MPL *mpl); -- -- *Description* -- -- The routine mpl_terminate frees all the resources used by the GNU -- MathProg translator. */ void mpl_terminate(MPL *mpl) { if (setjmp(mpl->jump)) xassert(mpl != mpl); switch (mpl->phase) { case 0: case 1: case 2: case 3: /* there were no errors; clean the model content */ clean_model(mpl); xassert(mpl->a_list == NULL); #if 1 /* 11/II-2008 */ xassert(mpl->dca == NULL); #endif break; case 4: /* model processing has been finished due to error; delete search trees, which may be created for some arrays */ { ARRAY *a; for (a = mpl->a_list; a != NULL; a = a->next) if (a->tree != NULL) avl_delete_tree(a->tree); } #if 1 /* 11/II-2008 */ free_dca(mpl); #endif break; default: xassert(mpl != mpl); } /* delete the translator database */ xfree(mpl->image); xfree(mpl->b_image); xfree(mpl->f_image); xfree(mpl->context); dmp_delete_pool(mpl->pool); avl_delete_tree(mpl->tree); dmp_delete_pool(mpl->strings); dmp_delete_pool(mpl->symbols); dmp_delete_pool(mpl->tuples); dmp_delete_pool(mpl->arrays); dmp_delete_pool(mpl->members); dmp_delete_pool(mpl->elemvars); dmp_delete_pool(mpl->formulae); dmp_delete_pool(mpl->elemcons); xfree(mpl->sym_buf); xfree(mpl->tup_buf); rng_delete_rand(mpl->rand); if (mpl->row != NULL) xfree(mpl->row); if (mpl->col != NULL) xfree(mpl->col); if (mpl->in_fp != NULL) xfclose(mpl->in_fp); if (mpl->out_fp != NULL && mpl->out_fp != (void *)stdout) xfclose(mpl->out_fp); if (mpl->out_file != NULL) xfree(mpl->out_file); if (mpl->prt_fp != NULL) xfclose(mpl->prt_fp); if (mpl->prt_file != NULL) xfree(mpl->prt_file); if (mpl->mod_file != NULL) xfree(mpl->mod_file); xfree(mpl->mpl_buf); xfree(mpl); return; } /* eof */ praat-6.0.04/external/glpk/glpmpl05.c000066400000000000000000000533541261542461700173150ustar00rootroot00000000000000/* glpmpl05.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Authors: Andrew Makhorin * Heinrich Schuchardt * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #define _GLPSTD_STDIO #define _GLPSTD_TIME #include "glpmpl.h" double fn_gmtime(MPL *mpl) { /* obtain the current calendar time (UTC) */ time_t timer; struct tm *tm; int j; time(&timer); if (timer == (time_t)(-1)) err: mpl_error(mpl, "gmtime(); unable to obtain current calendar time"); tm = gmtime(&timer); if (tm == NULL) goto err; j = jday(tm->tm_mday, tm->tm_mon + 1, 1900 + tm->tm_year); if (j < 0) goto err; return (((double)(j - jday(1, 1, 1970)) * 24.0 + (double)tm->tm_hour) * 60.0 + (double)tm->tm_min) * 60.0 + (double)tm->tm_sec; } static char *week[] = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }; static char *moon[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; static void error1(MPL *mpl, const char *str, const char *s, const char *fmt, const char *f, const char *msg) { xprintf("Input string passed to str2time:\n"); xprintf("%s\n", str); xprintf("%*s\n", (s - str) + 1, "^"); xprintf("Format string passed to str2time:\n"); xprintf("%s\n", fmt); xprintf("%*s\n", (f - fmt) + 1, "^"); mpl_error(mpl, "%s", msg); /* no return */ } double fn_str2time(MPL *mpl, const char *str, const char *fmt) { /* convert character string to the calendar time */ int j, year, month, day, hh, mm, ss, zone; const char *s, *f; year = month = day = hh = mm = ss = -1, zone = INT_MAX; s = str; for (f = fmt; *f != '\0'; f++) { if (*f == '%') { f++; if (*f == 'b' || *f == 'h') { /* the abbreviated month name */ int k; char *name; if (month >= 0) error1(mpl, str, s, fmt, f, "month multiply specified" ); while (*s == ' ') s++; for (month = 1; month <= 12; month++) { name = moon[month-1]; for (k = 0; k <= 2; k++) { if (toupper((unsigned char)s[k]) != toupper((unsigned char)name[k])) goto next; } s += 3; for (k = 3; name[k] != '\0'; k++) { if (toupper((unsigned char)*s) != toupper((unsigned char)name[k])) break; s++; } break; next: ; } if (month > 12) error1(mpl, str, s, fmt, f, "abbreviated month name m" "issing or invalid"); } else if (*f == 'd') { /* the day of the month as a decimal number (01..31) */ if (day >= 0) error1(mpl, str, s, fmt, f, "day multiply specified"); while (*s == ' ') s++; if (!('0' <= *s && *s <= '9')) error1(mpl, str, s, fmt, f, "day missing or invalid"); day = (*s++) - '0'; if ('0' <= *s && *s <= '9') day = 10 * day + ((*s++) - '0'); if (!(1 <= day && day <= 31)) error1(mpl, str, s, fmt, f, "day out of range"); } else if (*f == 'H') { /* the hour as a decimal number, using a 24-hour clock (00..23) */ if (hh >= 0) error1(mpl, str, s, fmt, f, "hour multiply specified") ; while (*s == ' ') s++; if (!('0' <= *s && *s <= '9')) error1(mpl, str, s, fmt, f, "hour missing or invalid") ; hh = (*s++) - '0'; if ('0' <= *s && *s <= '9') hh = 10 * hh + ((*s++) - '0'); if (!(0 <= hh && hh <= 23)) error1(mpl, str, s, fmt, f, "hour out of range"); } else if (*f == 'm') { /* the month as a decimal number (01..12) */ if (month >= 0) error1(mpl, str, s, fmt, f, "month multiply specified" ); while (*s == ' ') s++; if (!('0' <= *s && *s <= '9')) error1(mpl, str, s, fmt, f, "month missing or invalid" ); month = (*s++) - '0'; if ('0' <= *s && *s <= '9') month = 10 * month + ((*s++) - '0'); if (!(1 <= month && month <= 12)) error1(mpl, str, s, fmt, f, "month out of range"); } else if (*f == 'M') { /* the minute as a decimal number (00..59) */ if (mm >= 0) error1(mpl, str, s, fmt, f, "minute multiply specifie" "d"); while (*s == ' ') s++; if (!('0' <= *s && *s <= '9')) error1(mpl, str, s, fmt, f, "minute missing or invali" "d"); mm = (*s++) - '0'; if ('0' <= *s && *s <= '9') mm = 10 * mm + ((*s++) - '0'); if (!(0 <= mm && mm <= 59)) error1(mpl, str, s, fmt, f, "minute out of range"); } else if (*f == 'S') { /* the second as a decimal number (00..60) */ if (ss >= 0) error1(mpl, str, s, fmt, f, "second multiply specifie" "d"); while (*s == ' ') s++; if (!('0' <= *s && *s <= '9')) error1(mpl, str, s, fmt, f, "second missing or invali" "d"); ss = (*s++) - '0'; if ('0' <= *s && *s <= '9') ss = 10 * ss + ((*s++) - '0'); if (!(0 <= ss && ss <= 60)) error1(mpl, str, s, fmt, f, "second out of range"); } else if (*f == 'y') { /* the year without a century as a decimal number (00..99); the values 00 to 68 mean the years 2000 to 2068 while the values 69 to 99 mean the years 1969 to 1999 */ if (year >= 0) error1(mpl, str, s, fmt, f, "year multiply specified") ; while (*s == ' ') s++; if (!('0' <= *s && *s <= '9')) error1(mpl, str, s, fmt, f, "year missing or invalid") ; year = (*s++) - '0'; if ('0' <= *s && *s <= '9') year = 10 * year + ((*s++) - '0'); year += (year >= 69 ? 1900 : 2000); } else if (*f == 'Y') { /* the year as a decimal number, using the Gregorian calendar */ if (year >= 0) error1(mpl, str, s, fmt, f, "year multiply specified") ; while (*s == ' ') s++; if (!('0' <= *s && *s <= '9')) error1(mpl, str, s, fmt, f, "year missing or invalid") ; year = 0; for (j = 1; j <= 4; j++) { if (!('0' <= *s && *s <= '9')) break; year = 10 * year + ((*s++) - '0'); } if (!(1 <= year && year <= 4000)) error1(mpl, str, s, fmt, f, "year out of range"); } else if (*f == 'z') { /* time zone offset in the form zhhmm */ int z, hh, mm; if (zone != INT_MAX) error1(mpl, str, s, fmt, f, "time zone offset multipl" "y specified"); while (*s == ' ') s++; if (*s == 'Z') { z = hh = mm = 0, s++; goto skip; } if (*s == '+') z = +1, s++; else if (*s == '-') z = -1, s++; else error1(mpl, str, s, fmt, f, "time zone offset sign mi" "ssing"); hh = 0; for (j = 1; j <= 2; j++) { if (!('0' <= *s && *s <= '9')) err1: error1(mpl, str, s, fmt, f, "time zone offset valu" "e incomplete or invalid"); hh = 10 * hh + ((*s++) - '0'); } if (hh > 23) err2: error1(mpl, str, s, fmt, f, "time zone offset value o" "ut of range"); if (*s == ':') { s++; if (!('0' <= *s && *s <= '9')) goto err1; } mm = 0; if (!('0' <= *s && *s <= '9')) goto skip; for (j = 1; j <= 2; j++) { if (!('0' <= *s && *s <= '9')) goto err1; mm = 10 * mm + ((*s++) - '0'); } if (mm > 59) goto err2; skip: zone = z * (60 * hh + mm); } else if (*f == '%') { /* literal % character */ goto test; } else error1(mpl, str, s, fmt, f, "invalid conversion specifie" "r"); } else if (*f == ' ') ; else test: { /* check a matching character in the input string */ if (*s != *f) error1(mpl, str, s, fmt, f, "character mismatch"); s++; } } if (year < 0) year = 1970; if (month < 0) month = 1; if (day < 0) day = 1; if (hh < 0) hh = 0; if (mm < 0) mm = 0; if (ss < 0) ss = 0; if (zone == INT_MAX) zone = 0; j = jday(day, month, year); xassert(j >= 0); return (((double)(j - jday(1, 1, 1970)) * 24.0 + (double)hh) * 60.0 + (double)mm) * 60.0 + (double)ss - 60.0 * (double)zone; } static void error2(MPL *mpl, const char *fmt, const char *f, const char *msg) { xprintf("Format string passed to time2str:\n"); xprintf("%s\n", fmt); xprintf("%*s\n", (f - fmt) + 1, "^"); mpl_error(mpl, "%s", msg); /* no return */ } static int weekday(int j) { /* determine weekday number (1 = Mon, ..., 7 = Sun) */ return (j + jday(1, 1, 1970)) % 7 + 1; } static int firstday(int year) { /* determine the first day of the first week for a specified year according to ISO 8601 */ int j; /* if 1 January is Monday, Tuesday, Wednesday or Thursday, it is in week 01; if 1 January is Friday, Saturday or Sunday, it is in week 52 or 53 of the previous year */ j = jday(1, 1, year) - jday(1, 1, 1970); switch (weekday(j)) { case 1: /* 1 Jan is Mon */ j += 0; break; case 2: /* 1 Jan is Tue */ j -= 1; break; case 3: /* 1 Jan is Wed */ j -= 2; break; case 4: /* 1 Jan is Thu */ j -= 3; break; case 5: /* 1 Jan is Fri */ j += 3; break; case 6: /* 1 Jan is Sat */ j += 2; break; case 7: /* 1 Jan is Sun */ j += 1; break; default: xassert(j != j); } /* the first day of the week must be Monday */ xassert(weekday(j) == 1); return j; } void fn_time2str(MPL *mpl, char *str, double t, const char *fmt) { /* convert the calendar time to character string */ int j, year, month, day, hh, mm, ss, len; double temp; const char *f; char buf[MAX_LENGTH+1]; if (!(-62135596800.0 <= t && t <= 64092211199.0)) mpl_error(mpl, "time2str(%.*g,...); argument out of range", DBL_DIG, t); t = floor(t + 0.5); temp = fabs(t) / 86400.0; j = (int)floor(temp); if (t < 0.0) { if (temp == floor(temp)) j = - j; else j = - (j + 1); } xassert(jdate(j + jday(1, 1, 1970), &day, &month, &year) == 0); ss = (int)(t - 86400.0 * (double)j); xassert(0 <= ss && ss < 86400); mm = ss / 60, ss %= 60; hh = mm / 60, mm %= 60; len = 0; for (f = fmt; *f != '\0'; f++) { if (*f == '%') { f++; if (*f == 'a') { /* the abbreviated weekday name */ memcpy(buf, week[weekday(j)-1], 3), buf[3] = '\0'; } else if (*f == 'A') { /* the full weekday name */ strcpy(buf, week[weekday(j)-1]); } else if (*f == 'b' || *f == 'h') { /* the abbreviated month name */ memcpy(buf, moon[month-1], 3), buf[3] = '\0'; } else if (*f == 'B') { /* the full month name */ strcpy(buf, moon[month-1]); } else if (*f == 'C') { /* the century of the year */ sprintf(buf, "%02d", year / 100); } else if (*f == 'd') { /* the day of the month as a decimal number (01..31) */ sprintf(buf, "%02d", day); } else if (*f == 'D') { /* the date using the format %m/%d/%y */ sprintf(buf, "%02d/%02d/%02d", month, day, year % 100); } else if (*f == 'e') { /* the day of the month like with %d, but padded with blank (1..31) */ sprintf(buf, "%2d", day); } else if (*f == 'F') { /* the date using the format %Y-%m-%d */ sprintf(buf, "%04d-%02d-%02d", year, month, day); } else if (*f == 'g') { /* the year corresponding to the ISO week number, but without the century (range 00 through 99); this has the same format and value as %y, except that if the ISO week number (see %V) belongs to the previous or next year, that year is used instead */ int iso; if (j < firstday(year)) iso = year - 1; else if (j < firstday(year + 1)) iso = year; else iso = year + 1; sprintf(buf, "%02d", iso % 100); } else if (*f == 'G') { /* the year corresponding to the ISO week number; this has the same format and value as %Y, excepth that if the ISO week number (see %V) belongs to the previous or next year, that year is used instead */ int iso; if (j < firstday(year)) iso = year - 1; else if (j < firstday(year + 1)) iso = year; else iso = year + 1; sprintf(buf, "%04d", iso); } else if (*f == 'H') { /* the hour as a decimal number, using a 24-hour clock (00..23) */ sprintf(buf, "%02d", hh); } else if (*f == 'I') { /* the hour as a decimal number, using a 12-hour clock (01..12) */ sprintf(buf, "%02d", hh == 0 ? 12 : hh <= 12 ? hh : hh - 12); } else if (*f == 'j') { /* the day of the year as a decimal number (001..366) */ sprintf(buf, "%03d", jday(day, month, year) - jday(1, 1, year) + 1); } else if (*f == 'k') { /* the hour as a decimal number, using a 24-hour clock like %H, but padded with blank (0..23) */ sprintf(buf, "%2d", hh); } else if (*f == 'l') { /* the hour as a decimal number, using a 12-hour clock like %I, but padded with blank (1..12) */ sprintf(buf, "%2d", hh == 0 ? 12 : hh <= 12 ? hh : hh - 12); } else if (*f == 'm') { /* the month as a decimal number (01..12) */ sprintf(buf, "%02d", month); } else if (*f == 'M') { /* the minute as a decimal number (00..59) */ sprintf(buf, "%02d", mm); } else if (*f == 'p') { /* either AM or PM, according to the given time value; noon is treated as PM and midnight as AM */ strcpy(buf, hh <= 11 ? "AM" : "PM"); } else if (*f == 'P') { /* either am or pm, according to the given time value; noon is treated as pm and midnight as am */ strcpy(buf, hh <= 11 ? "am" : "pm"); } else if (*f == 'r') { /* the calendar time using the format %I:%M:%S %p */ sprintf(buf, "%02d:%02d:%02d %s", hh == 0 ? 12 : hh <= 12 ? hh : hh - 12, mm, ss, hh <= 11 ? "AM" : "PM"); } else if (*f == 'R') { /* the hour and minute using the format %H:%M */ sprintf(buf, "%02d:%02d", hh, mm); } else if (*f == 'S') { /* the second as a decimal number (00..59) */ sprintf(buf, "%02d", ss); } else if (*f == 'T') { /* the time of day using the format %H:%M:%S */ sprintf(buf, "%02d:%02d:%02d", hh, mm, ss); } else if (*f == 'u') { /* the day of the week as a decimal number (1..7), Monday being 1 */ sprintf(buf, "%d", weekday(j)); } else if (*f == 'U') { /* the week number of the current year as a decimal number (range 00 through 53), starting with the first Sunday as the first day of the first week; days preceding the first Sunday in the year are considered to be in week 00 */ #if 1 /* 09/I-2009 */ #undef sun /* causes compilation error in SunOS */ #endif int sun; /* sun = the first Sunday of the year */ sun = jday(1, 1, year) - jday(1, 1, 1970); sun += (7 - weekday(sun)); sprintf(buf, "%02d", (j + 7 - sun) / 7); } else if (*f == 'V') { /* the ISO week number as a decimal number (range 01 through 53); ISO weeks start with Monday and end with Sunday; week 01 of a year is the first week which has the majority of its days in that year; week 01 of a year can contain days from the previous year; the week before week 01 of a year is the last week (52 or 53) of the previous year even if it contains days from the new year */ int iso; if (j < firstday(year)) iso = j - firstday(year - 1); else if (j < firstday(year + 1)) iso = j - firstday(year); else iso = j - firstday(year + 1); sprintf(buf, "%02d", iso / 7 + 1); } else if (*f == 'w') { /* the day of the week as a decimal number (0..6), Sunday being 0 */ sprintf(buf, "%d", weekday(j) % 7); } else if (*f == 'W') { /* the week number of the current year as a decimal number (range 00 through 53), starting with the first Monday as the first day of the first week; days preceding the first Monday in the year are considered to be in week 00 */ int mon; /* mon = the first Monday of the year */ mon = jday(1, 1, year) - jday(1, 1, 1970); mon += (8 - weekday(mon)) % 7; sprintf(buf, "%02d", (j + 7 - mon) / 7); } else if (*f == 'y') { /* the year without a century as a decimal number (00..99) */ sprintf(buf, "%02d", year % 100); } else if (*f == 'Y') { /* the year as a decimal number, using the Gregorian calendar */ sprintf(buf, "%04d", year); } else if (*f == '%') { /* a literal % character */ buf[0] = '%', buf[1] = '\0'; } else error2(mpl, fmt, f, "invalid conversion specifier"); } else buf[0] = *f, buf[1] = '\0'; if (len + strlen(buf) > MAX_LENGTH) mpl_error(mpl, "time2str; output string length exceeds %d chara" "cters", MAX_LENGTH); memcpy(str+len, buf, strlen(buf)); len += strlen(buf); } str[len] = '\0'; return; } /* eof */ praat-6.0.04/external/glpk/glpmpl06.c000066400000000000000000000751621261542461700173170ustar00rootroot00000000000000/* glpmpl06.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #define _GLPSTD_ERRNO #define _GLPSTD_STDIO #include "glpmpl.h" #include "glpsql.h" /**********************************************************************/ #define CSV_FIELD_MAX 50 /* maximal number of fields in record */ #define CSV_FDLEN_MAX 100 /* maximal field length */ struct csv { /* comma-separated values file */ int mode; /* 'R' = reading; 'W' = writing */ char *fname; /* name of csv file */ FILE *fp; /* stream assigned to csv file */ jmp_buf jump; /* address for non-local go to in case of error */ int count; /* record count */ /*--------------------------------------------------------------*/ /* used only for input csv file */ int c; /* current character or EOF */ int what; /* current marker: */ #define CSV_EOF 0 /* end-of-file */ #define CSV_EOR 1 /* end-of-record */ #define CSV_NUM 2 /* floating-point number */ #define CSV_STR 3 /* character string */ char field[CSV_FDLEN_MAX+1]; /* current field just read */ int nf; /* number of fields in the csv file */ int ref[1+CSV_FIELD_MAX]; /* ref[k] = k', if k-th field of the csv file corresponds to k'-th field in the table statement; if ref[k] = 0, k-th field of the csv file is ignored */ #if 1 /* 01/VI-2010 */ int nskip; /* number of comment records preceding the header record */ #endif }; #undef read_char static void read_char(struct csv *csv) { /* read character from csv data file */ int c; xassert(csv->c != EOF); if (csv->c == '\n') csv->count++; loop: c = fgetc(csv->fp); if (ferror(csv->fp)) { xprintf("%s:%d: read error - %s\n", csv->fname, csv->count, strerror(errno)); longjmp(csv->jump, 0); } if (feof(csv->fp)) { if (csv->c == '\n') { csv->count--; c = EOF; } else { xprintf("%s:%d: warning: missing final end-of-line\n", csv->fname, csv->count); c = '\n'; } } else if (c == '\r') goto loop; else if (c == '\n') ; else if (iscntrl(c)) { xprintf("%s:%d: invalid control character 0x%02X\n", csv->fname, csv->count, c); longjmp(csv->jump, 0); } csv->c = c; return; } static void read_field(struct csv *csv) { /* read field from csv data file */ /* check for end of file */ if (csv->c == EOF) { csv->what = CSV_EOF; strcpy(csv->field, "EOF"); goto done; } /* check for end of record */ if (csv->c == '\n') { csv->what = CSV_EOR; strcpy(csv->field, "EOR"); read_char(csv); if (csv->c == ',') err1: { xprintf("%s:%d: empty field not allowed\n", csv->fname, csv->count); longjmp(csv->jump, 0); } if (csv->c == '\n') { xprintf("%s:%d: empty record not allowed\n", csv->fname, csv->count); longjmp(csv->jump, 0); } #if 1 /* 01/VI-2010 */ /* skip comment records; may appear only before the very first record containing field names */ if (csv->c == '#' && csv->count == 1) { while (csv->c == '#') { while (csv->c != '\n') read_char(csv); read_char(csv); csv->nskip++; } } #endif goto done; } /* skip comma before next field */ if (csv->c == ',') read_char(csv); /* read field */ if (csv->c == '\'' || csv->c == '"') { /* read a field enclosed in quotes */ int quote = csv->c, len = 0; csv->what = CSV_STR; /* skip opening quote */ read_char(csv); /* read field characters within quotes */ for (;;) { /* check for closing quote and read it */ if (csv->c == quote) { read_char(csv); if (csv->c == quote) ; else if (csv->c == ',' || csv->c == '\n') break; else { xprintf("%s:%d: invalid field\n", csv->fname, csv->count); longjmp(csv->jump, 0); } } /* check the current field length */ if (len == CSV_FDLEN_MAX) err2: { xprintf("%s:%d: field too long\n", csv->fname, csv->count); longjmp(csv->jump, 0); } /* add the current character to the field */ csv->field[len++] = (char)csv->c; /* read the next character */ read_char(csv); } /* the field has been read */ if (len == 0) goto err1; csv->field[len] = '\0'; } else { /* read a field not enclosed in quotes */ int len = 0; double temp; csv->what = CSV_NUM; while (!(csv->c == ',' || csv->c == '\n')) { /* quotes within the field are not allowed */ if (csv->c == '\'' || csv->c == '"') { xprintf("%s:%d: invalid use of single or double quote wi" "thin field\n", csv->fname, csv->count); longjmp(csv->jump, 0); } /* check the current field length */ if (len == CSV_FDLEN_MAX) goto err2; /* add the current character to the field */ csv->field[len++] = (char)csv->c; /* read the next character */ read_char(csv); } /* the field has been read */ if (len == 0) goto err1; csv->field[len] = '\0'; /* check the field type */ if (str2num(csv->field, &temp)) csv->what = CSV_STR; } done: return; } static struct csv *csv_open_file(TABDCA *dca, int mode) { /* open csv data file */ struct csv *csv; /* create control structure */ csv = xmalloc(sizeof(struct csv)); csv->mode = mode; csv->fname = NULL; csv->fp = NULL; if (setjmp(csv->jump)) goto fail; csv->count = 0; csv->c = '\n'; csv->what = 0; csv->field[0] = '\0'; csv->nf = 0; /* try to open the csv data file */ if (mpl_tab_num_args(dca) < 2) { xprintf("csv_driver: file name not specified\n"); longjmp(csv->jump, 0); } csv->fname = xmalloc(strlen(mpl_tab_get_arg(dca, 2))+1); strcpy(csv->fname, mpl_tab_get_arg(dca, 2)); if (mode == 'R') { /* open the file for reading */ int k; csv->fp = fopen(csv->fname, "r"); if (csv->fp == NULL) { xprintf("csv_driver: unable to open %s - %s\n", csv->fname, strerror(errno)); longjmp(csv->jump, 0); } #if 1 /* 01/VI-2010 */ csv->nskip = 0; #endif /* skip fake new-line */ read_field(csv); xassert(csv->what == CSV_EOR); /* read field names */ xassert(csv->nf == 0); for (;;) { read_field(csv); if (csv->what == CSV_EOR) break; if (csv->what != CSV_STR) { xprintf("%s:%d: invalid field name\n", csv->fname, csv->count); longjmp(csv->jump, 0); } if (csv->nf == CSV_FIELD_MAX) { xprintf("%s:%d: too many fields\n", csv->fname, csv->count); longjmp(csv->jump, 0); } csv->nf++; /* find corresponding field in the table statement */ for (k = mpl_tab_num_flds(dca); k >= 1; k--) { if (strcmp(mpl_tab_get_name(dca, k), csv->field) == 0) break; } csv->ref[csv->nf] = k; } /* find dummy RECNO field in the table statement */ for (k = mpl_tab_num_flds(dca); k >= 1; k--) if (strcmp(mpl_tab_get_name(dca, k), "RECNO") == 0) break; csv->ref[0] = k; } else if (mode == 'W') { /* open the file for writing */ int k, nf; csv->fp = fopen(csv->fname, "w"); if (csv->fp == NULL) { xprintf("csv_driver: unable to create %s - %s\n", csv->fname, strerror(errno)); longjmp(csv->jump, 0); } /* write field names */ nf = mpl_tab_num_flds(dca); for (k = 1; k <= nf; k++) fprintf(csv->fp, "%s%c", mpl_tab_get_name(dca, k), k < nf ? ',' : '\n'); csv->count++; } else xassert(mode != mode); /* the file has been open */ return csv; fail: /* the file cannot be open */ if (csv->fname != NULL) xfree(csv->fname); if (csv->fp != NULL) fclose(csv->fp); xfree(csv); return NULL; } static int csv_read_record(TABDCA *dca, struct csv *csv) { /* read next record from csv data file */ int k, ret = 0; xassert(csv->mode == 'R'); if (setjmp(csv->jump)) { ret = 1; goto done; } /* read dummy RECNO field */ if (csv->ref[0] > 0) #if 0 /* 01/VI-2010 */ mpl_tab_set_num(dca, csv->ref[0], csv->count-1); #else mpl_tab_set_num(dca, csv->ref[0], csv->count-csv->nskip-1); #endif /* read fields */ for (k = 1; k <= csv->nf; k++) { read_field(csv); if (csv->what == CSV_EOF) { /* end-of-file reached */ xassert(k == 1); ret = -1; goto done; } else if (csv->what == CSV_EOR) { /* end-of-record reached */ int lack = csv->nf - k + 1; if (lack == 1) xprintf("%s:%d: one field missing\n", csv->fname, csv->count); else xprintf("%s:%d: %d fields missing\n", csv->fname, csv->count, lack); longjmp(csv->jump, 0); } else if (csv->what == CSV_NUM) { /* floating-point number */ if (csv->ref[k] > 0) { double num; xassert(str2num(csv->field, &num) == 0); mpl_tab_set_num(dca, csv->ref[k], num); } } else if (csv->what == CSV_STR) { /* character string */ if (csv->ref[k] > 0) mpl_tab_set_str(dca, csv->ref[k], csv->field); } else xassert(csv != csv); } /* now there must be NL */ read_field(csv); xassert(csv->what != CSV_EOF); if (csv->what != CSV_EOR) { xprintf("%s:%d: too many fields\n", csv->fname, csv->count); longjmp(csv->jump, 0); } done: return ret; } static int csv_write_record(TABDCA *dca, struct csv *csv) { /* write next record to csv data file */ int k, nf, ret = 0; const char *c; xassert(csv->mode == 'W'); nf = mpl_tab_num_flds(dca); for (k = 1; k <= nf; k++) { switch (mpl_tab_get_type(dca, k)) { case 'N': fprintf(csv->fp, "%.*g", DBL_DIG, mpl_tab_get_num(dca, k)); break; case 'S': fputc('"', csv->fp); for (c = mpl_tab_get_str(dca, k); *c != '\0'; c++) { if (*c == '"') fputc('"', csv->fp), fputc('"', csv->fp); else fputc(*c, csv->fp); } fputc('"', csv->fp); break; default: xassert(dca != dca); } fputc(k < nf ? ',' : '\n', csv->fp); } csv->count++; if (ferror(csv->fp)) { xprintf("%s:%d: write error - %s\n", csv->fname, csv->count, strerror(errno)); ret = 1; } return ret; } static int csv_close_file(TABDCA *dca, struct csv *csv) { /* close csv data file */ int ret = 0; xassert(dca == dca); if (csv->mode == 'W') { fflush(csv->fp); if (ferror(csv->fp)) { xprintf("%s:%d: write error - %s\n", csv->fname, csv->count, strerror(errno)); ret = 1; } } xfree(csv->fname); fclose(csv->fp); xfree(csv); return ret; } /**********************************************************************/ #define DBF_FIELD_MAX 50 /* maximal number of fields in record */ #define DBF_FDLEN_MAX 100 /* maximal field length */ struct dbf { /* xBASE data file */ int mode; /* 'R' = reading; 'W' = writing */ char *fname; /* name of xBASE file */ FILE *fp; /* stream assigned to xBASE file */ jmp_buf jump; /* address for non-local go to in case of error */ int offset; /* offset of a byte to be read next */ int count; /* record count */ int nf; /* number of fields */ int ref[1+DBF_FIELD_MAX]; /* ref[k] = k', if k-th field of the csv file corresponds to k'-th field in the table statement; if ref[k] = 0, k-th field of the csv file is ignored */ int type[1+DBF_FIELD_MAX]; /* type[k] is type of k-th field */ int len[1+DBF_FIELD_MAX]; /* len[k] is length of k-th field */ int prec[1+DBF_FIELD_MAX]; /* prec[k] is precision of k-th field */ }; static int read_byte(struct dbf *dbf) { /* read byte from xBASE data file */ int b; b = fgetc(dbf->fp); if (ferror(dbf->fp)) { xprintf("%s:0x%X: read error - %s\n", dbf->fname, dbf->offset, strerror(errno)); longjmp(dbf->jump, 0); } if (feof(dbf->fp)) { xprintf("%s:0x%X: unexpected end of file\n", dbf->fname, dbf->offset); longjmp(dbf->jump, 0); } xassert(0x00 <= b && b <= 0xFF); dbf->offset++; return b; } static void read_header(TABDCA *dca, struct dbf *dbf) { /* read xBASE data file header */ int b, j, k, recl; char name[10+1]; /* (ignored) */ for (j = 1; j <= 10; j++) read_byte(dbf); /* length of each record, in bytes */ recl = read_byte(dbf); recl += read_byte(dbf) << 8; /* (ignored) */ for (j = 1; j <= 20; j++) read_byte(dbf); /* field descriptor array */ xassert(dbf->nf == 0); for (;;) { /* check for end of array */ b = read_byte(dbf); if (b == 0x0D) break; if (dbf->nf == DBF_FIELD_MAX) { xprintf("%s:0x%X: too many fields\n", dbf->fname, dbf->offset); longjmp(dbf->jump, 0); } dbf->nf++; /* field name */ name[0] = (char)b; for (j = 1; j < 10; j++) { b = read_byte(dbf); name[j] = (char)b; } name[10] = '\0'; b = read_byte(dbf); if (b != 0x00) { xprintf("%s:0x%X: invalid field name\n", dbf->fname, dbf->offset); longjmp(dbf->jump, 0); } /* find corresponding field in the table statement */ for (k = mpl_tab_num_flds(dca); k >= 1; k--) if (strcmp(mpl_tab_get_name(dca, k), name) == 0) break; dbf->ref[dbf->nf] = k; /* field type */ b = read_byte(dbf); if (!(b == 'C' || b == 'N')) { xprintf("%s:0x%X: invalid field type\n", dbf->fname, dbf->offset); longjmp(dbf->jump, 0); } dbf->type[dbf->nf] = b; /* (ignored) */ for (j = 1; j <= 4; j++) read_byte(dbf); /* field length */ b = read_byte(dbf); if (b == 0) { xprintf("%s:0x%X: invalid field length\n", dbf->fname, dbf->offset); longjmp(dbf->jump, 0); } if (b > DBF_FDLEN_MAX) { xprintf("%s:0x%X: field too long\n", dbf->fname, dbf->offset); longjmp(dbf->jump, 0); } dbf->len[dbf->nf] = b; recl -= b; /* (ignored) */ for (j = 1; j <= 15; j++) read_byte(dbf); } if (recl != 1) { xprintf("%s:0x%X: invalid file header\n", dbf->fname, dbf->offset); longjmp(dbf->jump, 0); } /* find dummy RECNO field in the table statement */ for (k = mpl_tab_num_flds(dca); k >= 1; k--) if (strcmp(mpl_tab_get_name(dca, k), "RECNO") == 0) break; dbf->ref[0] = k; return; } static void parse_third_arg(TABDCA *dca, struct dbf *dbf) { /* parse xBASE file format (third argument) */ int j, k, temp; const char *arg; dbf->nf = mpl_tab_num_flds(dca); arg = mpl_tab_get_arg(dca, 3), j = 0; for (k = 1; k <= dbf->nf; k++) { /* parse specification of k-th field */ if (arg[j] == '\0') { xprintf("xBASE driver: field %s: specification missing\n", mpl_tab_get_name(dca, k)); longjmp(dbf->jump, 0); } /* parse field type */ if (arg[j] == 'C' || arg[j] == 'N') dbf->type[k] = arg[j], j++; else { xprintf("xBASE driver: field %s: invalid field type\n", mpl_tab_get_name(dca, k)); longjmp(dbf->jump, 0); } /* check for left parenthesis */ if (arg[j] == '(') j++; else err: { xprintf("xBASE driver: field %s: invalid field format\n", mpl_tab_get_name(dca, k)); longjmp(dbf->jump, 0); } /* parse field length */ temp = 0; while (isdigit(arg[j])) { if (temp > DBF_FDLEN_MAX) break; temp = 10 * temp + (arg[j] - '0'), j++; } if (!(1 <= temp && temp <= DBF_FDLEN_MAX)) { xprintf("xBASE driver: field %s: invalid field length\n", mpl_tab_get_name(dca, k)); longjmp(dbf->jump, 0); } dbf->len[k] = temp; /* parse optional field precision */ if (dbf->type[k] == 'N' && arg[j] == ',') { j++; temp = 0; while (isdigit(arg[j])) { if (temp > dbf->len[k]) break; temp = 10 * temp + (arg[j] - '0'), j++; } if (temp > dbf->len[k]) { xprintf("xBASE driver: field %s: invalid field precision" "\n", mpl_tab_get_name(dca, k)); longjmp(dbf->jump, 0); } dbf->prec[k] = temp; } else dbf->prec[k] = 0; /* check for right parenthesis */ if (arg[j] == ')') j++; else goto err; } /* ignore other specifications */ return; } static void write_byte(struct dbf *dbf, int b) { /* write byte to xBASE data file */ fputc(b, dbf->fp); dbf->offset++; return; } static void write_header(TABDCA *dca, struct dbf *dbf) { /* write xBASE data file header */ int j, k, temp; const char *name; /* version number */ write_byte(dbf, 0x03 /* file without DBT */); /* date of last update (YYMMDD) */ write_byte(dbf, 70 /* 1970 */); write_byte(dbf, 1 /* January */); write_byte(dbf, 1 /* 1st */); /* number of records (unknown so far) */ for (j = 1; j <= 4; j++) write_byte(dbf, 0xFF); /* length of the header, in bytes */ temp = 32 + dbf->nf * 32 + 1; write_byte(dbf, temp); write_byte(dbf, temp >> 8); /* length of each record, in bytes */ temp = 1; for (k = 1; k <= dbf->nf; k++) temp += dbf->len[k]; write_byte(dbf, temp); write_byte(dbf, temp >> 8); /* (reserved) */ for (j = 1; j <= 20; j++) write_byte(dbf, 0x00); /* field descriptor array */ for (k = 1; k <= dbf->nf; k++) { /* field name (terminated by 0x00) */ name = mpl_tab_get_name(dca, k); for (j = 0; j < 10 && name[j] != '\0'; j++) write_byte(dbf, name[j]); for (j = j; j < 11; j++) write_byte(dbf, 0x00); /* field type */ write_byte(dbf, dbf->type[k]); /* (reserved) */ for (j = 1; j <= 4; j++) write_byte(dbf, 0x00); /* field length */ write_byte(dbf, dbf->len[k]); /* field precision */ write_byte(dbf, dbf->prec[k]); /* (reserved) */ for (j = 1; j <= 14; j++) write_byte(dbf, 0x00); } /* end of header */ write_byte(dbf, 0x0D); return; } static struct dbf *dbf_open_file(TABDCA *dca, int mode) { /* open xBASE data file */ struct dbf *dbf; /* create control structure */ dbf = xmalloc(sizeof(struct dbf)); dbf->mode = mode; dbf->fname = NULL; dbf->fp = NULL; if (setjmp(dbf->jump)) goto fail; dbf->offset = 0; dbf->count = 0; dbf->nf = 0; /* try to open the xBASE data file */ if (mpl_tab_num_args(dca) < 2) { xprintf("xBASE driver: file name not specified\n"); longjmp(dbf->jump, 0); } dbf->fname = xmalloc(strlen(mpl_tab_get_arg(dca, 2))+1); strcpy(dbf->fname, mpl_tab_get_arg(dca, 2)); if (mode == 'R') { /* open the file for reading */ dbf->fp = fopen(dbf->fname, "rb"); if (dbf->fp == NULL) { xprintf("xBASE driver: unable to open %s - %s\n", dbf->fname, strerror(errno)); longjmp(dbf->jump, 0); } read_header(dca, dbf); } else if (mode == 'W') { /* open the file for writing */ if (mpl_tab_num_args(dca) < 3) { xprintf("xBASE driver: file format not specified\n"); longjmp(dbf->jump, 0); } parse_third_arg(dca, dbf); dbf->fp = fopen(dbf->fname, "wb"); if (dbf->fp == NULL) { xprintf("xBASE driver: unable to create %s - %s\n", dbf->fname, strerror(errno)); longjmp(dbf->jump, 0); } write_header(dca, dbf); } else xassert(mode != mode); /* the file has been open */ return dbf; fail: /* the file cannot be open */ if (dbf->fname != NULL) xfree(dbf->fname); if (dbf->fp != NULL) fclose(dbf->fp); xfree(dbf); return NULL; } static int dbf_read_record(TABDCA *dca, struct dbf *dbf) { /* read next record from xBASE data file */ int b, j, k, ret = 0; char buf[DBF_FDLEN_MAX+1]; xassert(dbf->mode == 'R'); if (setjmp(dbf->jump)) { ret = 1; goto done; } /* check record flag */ b = read_byte(dbf); if (b == 0x1A) { /* end of data */ ret = -1; goto done; } if (b != 0x20) { xprintf("%s:0x%X: invalid record flag\n", dbf->fname, dbf->offset); longjmp(dbf->jump, 0); } /* read dummy RECNO field */ if (dbf->ref[0] > 0) mpl_tab_set_num(dca, dbf->ref[0], dbf->count+1); /* read fields */ for (k = 1; k <= dbf->nf; k++) { /* read k-th field */ for (j = 0; j < dbf->len[k]; j++) buf[j] = (char)read_byte(dbf); buf[dbf->len[k]] = '\0'; /* set field value */ if (dbf->type[k] == 'C') { /* character field */ if (dbf->ref[k] > 0) mpl_tab_set_str(dca, dbf->ref[k], strtrim(buf)); } else if (dbf->type[k] == 'N') { /* numeric field */ if (dbf->ref[k] > 0) { double num; strspx(buf); xassert(str2num(buf, &num) == 0); mpl_tab_set_num(dca, dbf->ref[k], num); } } else xassert(dbf != dbf); } /* increase record count */ dbf->count++; done: return ret; } static int dbf_write_record(TABDCA *dca, struct dbf *dbf) { /* write next record to xBASE data file */ int j, k, ret = 0; char buf[255+1]; xassert(dbf->mode == 'W'); if (setjmp(dbf->jump)) { ret = 1; goto done; } /* record flag */ write_byte(dbf, 0x20); xassert(dbf->nf == mpl_tab_num_flds(dca)); for (k = 1; k <= dbf->nf; k++) { if (dbf->type[k] == 'C') { /* character field */ const char *str; if (mpl_tab_get_type(dca, k) == 'N') { sprintf(buf, "%.*g", DBL_DIG, mpl_tab_get_num(dca, k)); str = buf; } else if (mpl_tab_get_type(dca, k) == 'S') str = mpl_tab_get_str(dca, k); else xassert(dca != dca); if ((int)strlen(str) > dbf->len[k]) { xprintf("xBASE driver: field %s: cannot convert %.15s..." " to field format\n", mpl_tab_get_name(dca, k), str); longjmp(dbf->jump, 0); } for (j = 0; j < dbf->len[k] && str[j] != '\0'; j++) write_byte(dbf, str[j]); for (j = j; j < dbf->len[k]; j++) write_byte(dbf, ' '); } else if (dbf->type[k] == 'N') { /* numeric field */ double num = mpl_tab_get_num(dca, k); if (fabs(num) > 1e20) err: { xprintf("xBASE driver: field %s: cannot convert %g to fi" "eld format\n", mpl_tab_get_name(dca, k), num); longjmp(dbf->jump, 0); } sprintf(buf, "%*.*f", dbf->len[k], dbf->prec[k], num); xassert(strlen(buf) < sizeof(buf)); if ((int)strlen(buf) != dbf->len[k]) goto err; for (j = 0; j < dbf->len[k]; j++) write_byte(dbf, buf[j]); } else xassert(dbf != dbf); } /* increase record count */ dbf->count++; done: return ret; } static int dbf_close_file(TABDCA *dca, struct dbf *dbf) { /* close xBASE data file */ int ret = 0; xassert(dca == dca); if (dbf->mode == 'W') { if (setjmp(dbf->jump)) { ret = 1; goto skip; } /* end-of-file flag */ write_byte(dbf, 0x1A); /* number of records */ dbf->offset = 4; if (fseek(dbf->fp, dbf->offset, SEEK_SET)) { xprintf("%s:0x%X: seek error - %s\n", dbf->fname, dbf->offset, strerror(errno)); longjmp(dbf->jump, 0); } write_byte(dbf, dbf->count); write_byte(dbf, dbf->count >> 8); write_byte(dbf, dbf->count >> 16); write_byte(dbf, dbf->count >> 24); fflush(dbf->fp); if (ferror(dbf->fp)) { xprintf("%s:0x%X: write error - %s\n", dbf->fname, dbf->offset, strerror(errno)); longjmp(dbf->jump, 0); } skip: ; } xfree(dbf->fname); fclose(dbf->fp); xfree(dbf); return ret; } /**********************************************************************/ #define TAB_CSV 1 #define TAB_XBASE 2 #define TAB_ODBC 3 #define TAB_MYSQL 4 void mpl_tab_drv_open(MPL *mpl, int mode) { TABDCA *dca = mpl->dca; xassert(dca->id == 0); xassert(dca->link == NULL); xassert(dca->na >= 1); if (strcmp(dca->arg[1], "CSV") == 0) { dca->id = TAB_CSV; dca->link = csv_open_file(dca, mode); } else if (strcmp(dca->arg[1], "xBASE") == 0) { dca->id = TAB_XBASE; dca->link = dbf_open_file(dca, mode); } else if (strcmp(dca->arg[1], "ODBC") == 0 || strcmp(dca->arg[1], "iODBC") == 0) { dca->id = TAB_ODBC; dca->link = db_iodbc_open(dca, mode); } else if (strcmp(dca->arg[1], "MySQL") == 0) { dca->id = TAB_MYSQL; dca->link = db_mysql_open(dca, mode); } else xprintf("Invalid table driver `%s'\n", dca->arg[1]); if (dca->link == NULL) mpl_error(mpl, "error on opening table %s", mpl->stmt->u.tab->name); return; } int mpl_tab_drv_read(MPL *mpl) { TABDCA *dca = mpl->dca; int ret; switch (dca->id) { case TAB_CSV: ret = csv_read_record(dca, dca->link); break; case TAB_XBASE: ret = dbf_read_record(dca, dca->link); break; case TAB_ODBC: ret = db_iodbc_read(dca, dca->link); break; case TAB_MYSQL: ret = db_mysql_read(dca, dca->link); break; default: xassert(dca != dca); } if (ret > 0) mpl_error(mpl, "error on reading data from table %s", mpl->stmt->u.tab->name); return ret; } void mpl_tab_drv_write(MPL *mpl) { TABDCA *dca = mpl->dca; int ret; switch (dca->id) { case TAB_CSV: ret = csv_write_record(dca, dca->link); break; case TAB_XBASE: ret = dbf_write_record(dca, dca->link); break; case TAB_ODBC: ret = db_iodbc_write(dca, dca->link); break; case TAB_MYSQL: ret = db_mysql_write(dca, dca->link); break; default: xassert(dca != dca); } if (ret) mpl_error(mpl, "error on writing data to table %s", mpl->stmt->u.tab->name); return; } void mpl_tab_drv_close(MPL *mpl) { TABDCA *dca = mpl->dca; int ret; switch (dca->id) { case TAB_CSV: ret = csv_close_file(dca, dca->link); break; case TAB_XBASE: ret = dbf_close_file(dca, dca->link); break; case TAB_ODBC: ret = db_iodbc_close(dca, dca->link); break; case TAB_MYSQL: ret = db_mysql_close(dca, dca->link); break; default: xassert(dca != dca); } dca->id = 0; dca->link = NULL; if (ret) mpl_error(mpl, "error on closing table %s", mpl->stmt->u.tab->name); return; } /* eof */ praat-6.0.04/external/glpk/glpmps.c000066400000000000000000001332501261542461700171510ustar00rootroot00000000000000/* glpmps.c (MPS format routines) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpapi.h" /*********************************************************************** * NAME * * glp_init_mpscp - initialize MPS format control parameters * * SYNOPSIS * * void glp_init_mpscp(glp_mpscp *parm); * * DESCRIPTION * * The routine glp_init_mpscp initializes control parameters, which are * used by the MPS input/output routines glp_read_mps and glp_write_mps, * with default values. * * Default values of the control parameters are stored in the glp_mpscp * structure, which the parameter parm points to. */ void glp_init_mpscp(glp_mpscp *parm) { parm->blank = '\0'; parm->obj_name = NULL; parm->tol_mps = 1e-12; return; } static void check_parm(const char *func, const glp_mpscp *parm) { /* check control parameters */ if (!(0x00 <= parm->blank && parm->blank <= 0xFF) || !(parm->blank == '\0' || isprint(parm->blank))) xerror("%s: blank = 0x%02X; invalid parameter\n", func, parm->blank); if (!(parm->obj_name == NULL || strlen(parm->obj_name) <= 255)) xerror("%s: obj_name = \"%.12s...\"; parameter too long\n", func, parm->obj_name); if (!(0.0 <= parm->tol_mps && parm->tol_mps < 1.0)) xerror("%s: tol_mps = %g; invalid parameter\n", func, parm->tol_mps); return; } /*********************************************************************** * NAME * * glp_read_mps - read problem data in MPS format * * SYNOPSIS * * int glp_read_mps(glp_prob *P, int fmt, const glp_mpscp *parm, * const char *fname); * * DESCRIPTION * * The routine glp_read_mps reads problem data in MPS format from a * text file. * * The parameter fmt specifies the version of MPS format: * * GLP_MPS_DECK - fixed (ancient) MPS format; * GLP_MPS_FILE - free (modern) MPS format. * * The parameter parm is a pointer to the structure glp_mpscp, which * specifies control parameters used by the routine. If parm is NULL, * the routine uses default settings. * * The character string fname specifies a name of the text file to be * read. * * Note that before reading data the current content of the problem * object is completely erased with the routine glp_erase_prob. * * RETURNS * * If the operation was successful, the routine glp_read_mps returns * zero. Otherwise, it prints an error message and returns non-zero. */ struct csa { /* common storage area */ glp_prob *P; /* pointer to problem object */ int deck; /* MPS format (0 - free, 1 - fixed) */ const glp_mpscp *parm; /* pointer to control parameters */ const char *fname; /* name of input MPS file */ XFILE *fp; /* stream assigned to input MPS file */ jmp_buf jump; /* label for go to in case of error */ int recno; /* current record (card) number */ int recpos; /* current record (card) position */ int c; /* current character */ int fldno; /* current field number */ char field[255+1]; /* current field content */ int w80; /* warning 'record must not be longer than 80 chars' issued */ int wef; /* warning 'extra fields detected beyond field 6' issued */ int obj_row; /* objective row number */ void *work1, *work2, *work3; /* working arrays */ }; static void error(struct csa *csa, const char *fmt, ...) { /* print error message and terminate processing */ va_list arg; xprintf("%s:%d: ", csa->fname, csa->recno); va_start(arg, fmt); xvprintf(fmt, arg); va_end(arg); longjmp(csa->jump, 1); /* no return */ } static void warning(struct csa *csa, const char *fmt, ...) { /* print warning message and continue processing */ va_list arg; xprintf("%s:%d: warning: ", csa->fname, csa->recno); va_start(arg, fmt); xvprintf(fmt, arg); va_end(arg); return; } static void read_char(struct csa *csa) { /* read next character */ int c; if (csa->c == '\n') csa->recno++, csa->recpos = 0; csa->recpos++; read: c = xfgetc(csa->fp); if (c < 0) { if (xferror(csa->fp)) error(csa, "read error - %s\n", xerrmsg()); else if (csa->c == '\n') error(csa, "unexpected end of file\n"); else { warning(csa, "missing final end of line\n"); c = '\n'; } } else if (c == '\n') ; else if (csa->c == '\r') { c = '\r'; goto badc; } else if (csa->deck && c == '\r') { csa->c = '\r'; goto read; } else if (c == ' ') ; else if (isspace(c)) { if (csa->deck) badc: error(csa, "in fixed MPS format white-space character 0x%02" "X is not allowed\n", c); c = ' '; } else if (iscntrl(c)) error(csa, "invalid control character 0x%02X\n", c); if (csa->deck && csa->recpos == 81 && c != '\n' && csa->w80 < 1) { warning(csa, "in fixed MPS format record must not be longer th" "an 80 characters\n"); csa->w80++; } csa->c = c; return; } static int indicator(struct csa *csa, int name) { /* skip comment records and read possible indicator record */ int ret; /* reset current field number */ csa->fldno = 0; loop: /* read the very first character of the next record */ xassert(csa->c == '\n'); read_char(csa); if (csa->c == ' ' || csa->c == '\n') { /* data record */ ret = 0; } else if (csa->c == '*') { /* comment record */ while (csa->c != '\n') read_char(csa); goto loop; } else { /* indicator record */ int len = 0; while (csa->c != ' ' && csa->c != '\n' && len < 12) { csa->field[len++] = (char)csa->c; read_char(csa); } csa->field[len] = '\0'; if (!(strcmp(csa->field, "NAME") == 0 || strcmp(csa->field, "ROWS") == 0 || strcmp(csa->field, "COLUMNS") == 0 || strcmp(csa->field, "RHS") == 0 || strcmp(csa->field, "RANGES") == 0 || strcmp(csa->field, "BOUNDS") == 0 || strcmp(csa->field, "ENDATA") == 0)) error(csa, "invalid indicator record\n"); if (!name) { while (csa->c != '\n') read_char(csa); } ret = 1; } return ret; } static void read_field(struct csa *csa) { /* read next field of the current data record */ csa->fldno++; if (csa->deck) { /* fixed MPS format */ int beg, end, pos; /* determine predefined field positions */ if (csa->fldno == 1) beg = 2, end = 3; else if (csa->fldno == 2) beg = 5, end = 12; else if (csa->fldno == 3) beg = 15, end = 22; else if (csa->fldno == 4) beg = 25, end = 36; else if (csa->fldno == 5) beg = 40, end = 47; else if (csa->fldno == 6) beg = 50, end = 61; else xassert(csa != csa); /* skip blanks preceding the current field */ if (csa->c != '\n') { pos = csa->recpos; while (csa->recpos < beg) { if (csa->c == ' ') ; else if (csa->c == '\n') break; else error(csa, "in fixed MPS format positions %d-%d must " "be blank\n", pos, beg-1); read_char(csa); } } /* skip possible comment beginning in the field 3 or 5 */ if ((csa->fldno == 3 || csa->fldno == 5) && csa->c == '$') { while (csa->c != '\n') read_char(csa); } /* read the current field */ for (pos = beg; pos <= end; pos++) { if (csa->c == '\n') break; csa->field[pos-beg] = (char)csa->c; read_char(csa); } csa->field[pos-beg] = '\0'; strtrim(csa->field); /* skip blanks following the last field */ if (csa->fldno == 6 && csa->c != '\n') { while (csa->recpos <= 72) { if (csa->c == ' ') ; else if (csa->c == '\n') break; else error(csa, "in fixed MPS format positions 62-72 must " "be blank\n"); read_char(csa); } while (csa->c != '\n') read_char(csa); } } else { /* free MPS format */ int len; /* skip blanks preceding the current field */ while (csa->c == ' ') read_char(csa); /* skip possible comment */ if (csa->c == '$') { while (csa->c != '\n') read_char(csa); } /* read the current field */ len = 0; while (!(csa->c == ' ' || csa->c == '\n')) { if (len == 255) error(csa, "length of field %d exceeds 255 characters\n", csa->fldno++); csa->field[len++] = (char)csa->c; read_char(csa); } csa->field[len] = '\0'; /* skip anything following the last field (any extra fields are considered to be comments) */ if (csa->fldno == 6) { while (csa->c == ' ') read_char(csa); if (csa->c != '$' && csa->c != '\n' && csa->wef < 1) { warning(csa, "some extra field(s) detected beyond field " "6; field(s) ignored\n"); csa->wef++; } while (csa->c != '\n') read_char(csa); } } return; } static void patch_name(struct csa *csa, char *name) { /* process embedded blanks in symbolic name */ int blank = csa->parm->blank; if (blank == '\0') { /* remove emedded blanks */ strspx(name); } else { /* replace embedded blanks by specified character */ for (; *name != '\0'; name++) if (*name == ' ') *name = (char)blank; } return; } static double read_number(struct csa *csa) { /* read next field and convert it to floating-point number */ double x; char *s; /* read next field */ read_field(csa); xassert(csa->fldno == 4 || csa->fldno == 6); if (csa->field[0] == '\0') error(csa, "missing numeric value in field %d\n", csa->fldno); /* skip initial spaces of the field */ for (s = csa->field; *s == ' '; s++) ; /* perform conversion */ if (str2num(s, &x) != 0) error(csa, "cannot convert `%s' to floating-point number\n", s); return x; } static void skip_field(struct csa *csa) { /* read and skip next field (assumed to be blank) */ read_field(csa); if (csa->field[0] != '\0') error(csa, "field %d must be blank\n", csa->fldno); return; } static void read_name(struct csa *csa) { /* read NAME indicator record */ if (!(indicator(csa, 1) && strcmp(csa->field, "NAME") == 0)) error(csa, "missing NAME indicator record\n"); /* this indicator record looks like a data record; simulate that fields 1 and 2 were read */ csa->fldno = 2; /* field 3: model name */ read_field(csa), patch_name(csa, csa->field); if (csa->field[0] == '\0') warning(csa, "missing model name in field 3\n"); else glp_set_prob_name(csa->P, csa->field); /* skip anything following field 3 */ while (csa->c != '\n') read_char(csa); return; } static void read_rows(struct csa *csa) { /* read ROWS section */ int i, type; loop: if (indicator(csa, 0)) goto done; /* field 1: row type */ read_field(csa), strspx(csa->field); if (strcmp(csa->field, "N") == 0) type = GLP_FR; else if (strcmp(csa->field, "G") == 0) type = GLP_LO; else if (strcmp(csa->field, "L") == 0) type = GLP_UP; else if (strcmp(csa->field, "E") == 0) type = GLP_FX; else if (csa->field[0] == '\0') error(csa, "missing row type in field 1\n"); else error(csa, "invalid row type in field 1\n"); /* field 2: row name */ read_field(csa), patch_name(csa, csa->field); if (csa->field[0] == '\0') error(csa, "missing row name in field 2\n"); if (glp_find_row(csa->P, csa->field) != 0) error(csa, "row `%s' multiply specified\n", csa->field); i = glp_add_rows(csa->P, 1); glp_set_row_name(csa->P, i, csa->field); glp_set_row_bnds(csa->P, i, type, 0.0, 0.0); /* fields 3, 4, 5, and 6 must be blank */ skip_field(csa); skip_field(csa); skip_field(csa); skip_field(csa); goto loop; done: return; } static void read_columns(struct csa *csa) { /* read COLUMNS section */ int i, j, f, len, kind = GLP_CV, *ind; double aij, *val; char name[255+1], *flag; /* allocate working arrays */ csa->work1 = ind = xcalloc(1+csa->P->m, sizeof(int)); csa->work2 = val = xcalloc(1+csa->P->m, sizeof(double)); csa->work3 = flag = xcalloc(1+csa->P->m, sizeof(char)); memset(&flag[1], 0, csa->P->m); /* no current column exists */ j = 0, len = 0; loop: if (indicator(csa, 0)) goto done; /* field 1 must be blank */ if (csa->deck) { read_field(csa); if (csa->field[0] != '\0') error(csa, "field 1 must be blank\n"); } else csa->fldno++; /* field 2: column or kind name */ read_field(csa), patch_name(csa, csa->field); strcpy(name, csa->field); /* field 3: row name or keyword 'MARKER' */ read_field(csa), patch_name(csa, csa->field); if (strcmp(csa->field, "'MARKER'") == 0) { /* process kind data record */ /* field 4 must be blank */ if (csa->deck) { read_field(csa); if (csa->field[0] != '\0') error(csa, "field 4 must be blank\n"); } else csa->fldno++; /* field 5: keyword 'INTORG' or 'INTEND' */ read_field(csa), patch_name(csa, csa->field); if (strcmp(csa->field, "'INTORG'") == 0) kind = GLP_IV; else if (strcmp(csa->field, "'INTEND'") == 0) kind = GLP_CV; else if (csa->field[0] == '\0') error(csa, "missing keyword in field 5\n"); else error(csa, "invalid keyword in field 5\n"); /* field 6 must be blank */ skip_field(csa); goto loop; } /* process column name specified in field 2 */ if (name[0] == '\0') { /* the same column as in previous data record */ if (j == 0) error(csa, "missing column name in field 2\n"); } else if (j != 0 && strcmp(name, csa->P->col[j]->name) == 0) { /* the same column as in previous data record */ xassert(j != 0); } else { /* store the current column */ if (j != 0) { glp_set_mat_col(csa->P, j, len, ind, val); while (len > 0) flag[ind[len--]] = 0; } /* create new column */ if (glp_find_col(csa->P, name) != 0) error(csa, "column `%s' multiply specified\n", name); j = glp_add_cols(csa->P, 1); glp_set_col_name(csa->P, j, name); glp_set_col_kind(csa->P, j, kind); if (kind == GLP_CV) glp_set_col_bnds(csa->P, j, GLP_LO, 0.0, 0.0); else if (kind == GLP_IV) glp_set_col_bnds(csa->P, j, GLP_DB, 0.0, 1.0); else xassert(kind != kind); } /* process fields 3-4 and 5-6 */ for (f = 3; f <= 5; f += 2) { /* field 3 or 5: row name */ if (f == 3) { if (csa->field[0] == '\0') error(csa, "missing row name in field 3\n"); } else { read_field(csa), patch_name(csa, csa->field); if (csa->field[0] == '\0') { /* if field 5 is blank, field 6 also must be blank */ skip_field(csa); continue; } } i = glp_find_row(csa->P, csa->field); if (i == 0) error(csa, "row `%s' not found\n", csa->field); if (flag[i]) error(csa, "duplicate coefficient in row `%s'\n", csa->field); /* field 4 or 6: coefficient value */ aij = read_number(csa); if (fabs(aij) < csa->parm->tol_mps) aij = 0.0; len++, ind[len] = i, val[len] = aij, flag[i] = 1; } goto loop; done: /* store the last column */ if (j != 0) glp_set_mat_col(csa->P, j, len, ind, val); /* free working arrays */ xfree(ind); xfree(val); xfree(flag); csa->work1 = csa->work2 = csa->work3 = NULL; return; } static void read_rhs(struct csa *csa) { /* read RHS section */ int i, f, v, type; double rhs; char name[255+1], *flag; /* allocate working array */ csa->work3 = flag = xcalloc(1+csa->P->m, sizeof(char)); memset(&flag[1], 0, csa->P->m); /* no current RHS vector exists */ v = 0; loop: if (indicator(csa, 0)) goto done; /* field 1 must be blank */ if (csa->deck) { read_field(csa); if (csa->field[0] != '\0') error(csa, "field 1 must be blank\n"); } else csa->fldno++; /* field 2: RHS vector name */ read_field(csa), patch_name(csa, csa->field); if (csa->field[0] == '\0') { /* the same RHS vector as in previous data record */ if (v == 0) { warning(csa, "missing RHS vector name in field 2\n"); goto blnk; } } else if (v != 0 && strcmp(csa->field, name) == 0) { /* the same RHS vector as in previous data record */ xassert(v != 0); } else blnk: { /* new RHS vector */ if (v != 0) error(csa, "multiple RHS vectors not supported\n"); v++; strcpy(name, csa->field); } /* process fields 3-4 and 5-6 */ for (f = 3; f <= 5; f += 2) { /* field 3 or 5: row name */ read_field(csa), patch_name(csa, csa->field); if (csa->field[0] == '\0') { if (f == 3) error(csa, "missing row name in field 3\n"); else { /* if field 5 is blank, field 6 also must be blank */ skip_field(csa); continue; } } i = glp_find_row(csa->P, csa->field); if (i == 0) error(csa, "row `%s' not found\n", csa->field); if (flag[i]) error(csa, "duplicate right-hand side for row `%s'\n", csa->field); /* field 4 or 6: right-hand side value */ rhs = read_number(csa); if (fabs(rhs) < csa->parm->tol_mps) rhs = 0.0; type = csa->P->row[i]->type; if (type == GLP_FR) { if (i == csa->obj_row) glp_set_obj_coef(csa->P, 0, rhs); else if (rhs != 0.0) warning(csa, "non-zero right-hand side for free row `%s'" " ignored\n", csa->P->row[i]->name); } else glp_set_row_bnds(csa->P, i, type, rhs, rhs); flag[i] = 1; } goto loop; done: /* free working array */ xfree(flag); csa->work3 = NULL; return; } static void read_ranges(struct csa *csa) { /* read RANGES section */ int i, f, v, type; double rhs, rng; char name[255+1], *flag; /* allocate working array */ csa->work3 = flag = xcalloc(1+csa->P->m, sizeof(char)); memset(&flag[1], 0, csa->P->m); /* no current RANGES vector exists */ v = 0; loop: if (indicator(csa, 0)) goto done; /* field 1 must be blank */ if (csa->deck) { read_field(csa); if (csa->field[0] != '\0') error(csa, "field 1 must be blank\n"); } else csa->fldno++; /* field 2: RANGES vector name */ read_field(csa), patch_name(csa, csa->field); if (csa->field[0] == '\0') { /* the same RANGES vector as in previous data record */ if (v == 0) { warning(csa, "missing RANGES vector name in field 2\n"); goto blnk; } } else if (v != 0 && strcmp(csa->field, name) == 0) { /* the same RANGES vector as in previous data record */ xassert(v != 0); } else blnk: { /* new RANGES vector */ if (v != 0) error(csa, "multiple RANGES vectors not supported\n"); v++; strcpy(name, csa->field); } /* process fields 3-4 and 5-6 */ for (f = 3; f <= 5; f += 2) { /* field 3 or 5: row name */ read_field(csa), patch_name(csa, csa->field); if (csa->field[0] == '\0') { if (f == 3) error(csa, "missing row name in field 3\n"); else { /* if field 5 is blank, field 6 also must be blank */ skip_field(csa); continue; } } i = glp_find_row(csa->P, csa->field); if (i == 0) error(csa, "row `%s' not found\n", csa->field); if (flag[i]) error(csa, "duplicate range for row `%s'\n", csa->field); /* field 4 or 6: range value */ rng = read_number(csa); if (fabs(rng) < csa->parm->tol_mps) rng = 0.0; type = csa->P->row[i]->type; if (type == GLP_FR) warning(csa, "range for free row `%s' ignored\n", csa->P->row[i]->name); else if (type == GLP_LO) { rhs = csa->P->row[i]->lb; glp_set_row_bnds(csa->P, i, rhs == 0.0 ? GLP_FX : GLP_DB, rhs, rhs + fabs(rng)); } else if (type == GLP_UP) { rhs = csa->P->row[i]->ub; glp_set_row_bnds(csa->P, i, rhs == 0.0 ? GLP_FX : GLP_DB, rhs - fabs(rng), rhs); } else if (type == GLP_FX) { rhs = csa->P->row[i]->lb; if (rng > 0.0) glp_set_row_bnds(csa->P, i, GLP_DB, rhs, rhs + rng); else if (rng < 0.0) glp_set_row_bnds(csa->P, i, GLP_DB, rhs + rng, rhs); } else xassert(type != type); flag[i] = 1; } goto loop; done: /* free working array */ xfree(flag); csa->work3 = NULL; return; } static void read_bounds(struct csa *csa) { /* read BOUNDS section */ GLPCOL *col; int j, v, mask, data; double bnd, lb, ub; char type[2+1], name[255+1], *flag; /* allocate working array */ csa->work3 = flag = xcalloc(1+csa->P->n, sizeof(char)); memset(&flag[1], 0, csa->P->n); /* no current BOUNDS vector exists */ v = 0; loop: if (indicator(csa, 0)) goto done; /* field 1: bound type */ read_field(csa); if (strcmp(csa->field, "LO") == 0) mask = 0x01, data = 1; else if (strcmp(csa->field, "UP") == 0) mask = 0x10, data = 1; else if (strcmp(csa->field, "FX") == 0) mask = 0x11, data = 1; else if (strcmp(csa->field, "FR") == 0) mask = 0x11, data = 0; else if (strcmp(csa->field, "MI") == 0) mask = 0x01, data = 0; else if (strcmp(csa->field, "PL") == 0) mask = 0x10, data = 0; else if (strcmp(csa->field, "LI") == 0) mask = 0x01, data = 1; else if (strcmp(csa->field, "UI") == 0) mask = 0x10, data = 1; else if (strcmp(csa->field, "BV") == 0) mask = 0x11, data = 0; else if (csa->field[0] == '\0') error(csa, "missing bound type in field 1\n"); else error(csa, "invalid bound type in field 1\n"); strcpy(type, csa->field); /* field 2: BOUNDS vector name */ read_field(csa), patch_name(csa, csa->field); if (csa->field[0] == '\0') { /* the same BOUNDS vector as in previous data record */ if (v == 0) { warning(csa, "missing BOUNDS vector name in field 2\n"); goto blnk; } } else if (v != 0 && strcmp(csa->field, name) == 0) { /* the same BOUNDS vector as in previous data record */ xassert(v != 0); } else blnk: { /* new BOUNDS vector */ if (v != 0) error(csa, "multiple BOUNDS vectors not supported\n"); v++; strcpy(name, csa->field); } /* field 3: column name */ read_field(csa), patch_name(csa, csa->field); if (csa->field[0] == '\0') error(csa, "missing column name in field 3\n"); j = glp_find_col(csa->P, csa->field); if (j == 0) error(csa, "column `%s' not found\n", csa->field); if ((flag[j] & mask) == 0x01) error(csa, "duplicate lower bound for column `%s'\n", csa->field); if ((flag[j] & mask) == 0x10) error(csa, "duplicate upper bound for column `%s'\n", csa->field); xassert((flag[j] & mask) == 0x00); /* field 4: bound value */ if (data) { bnd = read_number(csa); if (fabs(bnd) < csa->parm->tol_mps) bnd = 0.0; } else read_field(csa), bnd = 0.0; /* get current column bounds */ col = csa->P->col[j]; if (col->type == GLP_FR) lb = -DBL_MAX, ub = +DBL_MAX; else if (col->type == GLP_LO) lb = col->lb, ub = +DBL_MAX; else if (col->type == GLP_UP) lb = -DBL_MAX, ub = col->ub; else if (col->type == GLP_DB) lb = col->lb, ub = col->ub; else if (col->type == GLP_FX) lb = ub = col->lb; else xassert(col != col); /* change column bounds */ if (strcmp(type, "LO") == 0) lb = bnd; else if (strcmp(type, "UP") == 0) ub = bnd; else if (strcmp(type, "FX") == 0) lb = ub = bnd; else if (strcmp(type, "FR") == 0) lb = -DBL_MAX, ub = +DBL_MAX; else if (strcmp(type, "MI") == 0) lb = -DBL_MAX; else if (strcmp(type, "PL") == 0) ub = +DBL_MAX; else if (strcmp(type, "LI") == 0) { glp_set_col_kind(csa->P, j, GLP_IV); lb = ceil(bnd); } else if (strcmp(type, "UI") == 0) { glp_set_col_kind(csa->P, j, GLP_IV); ub = floor(bnd); } else if (strcmp(type, "BV") == 0) { glp_set_col_kind(csa->P, j, GLP_IV); lb = 0.0, ub = 1.0; } else xassert(type != type); /* set new column bounds */ if (lb == -DBL_MAX && ub == +DBL_MAX) glp_set_col_bnds(csa->P, j, GLP_FR, lb, ub); else if (ub == +DBL_MAX) glp_set_col_bnds(csa->P, j, GLP_LO, lb, ub); else if (lb == -DBL_MAX) glp_set_col_bnds(csa->P, j, GLP_UP, lb, ub); else if (lb != ub) glp_set_col_bnds(csa->P, j, GLP_DB, lb, ub); else glp_set_col_bnds(csa->P, j, GLP_FX, lb, ub); flag[j] |= (char)mask; /* fields 5 and 6 must be blank */ skip_field(csa); skip_field(csa); goto loop; done: /* free working array */ xfree(flag); csa->work3 = NULL; return; } int glp_read_mps(glp_prob *P, int fmt, const glp_mpscp *parm, const char *fname) { /* read problem data in MPS format */ glp_mpscp _parm; struct csa _csa, *csa = &_csa; int ret; xprintf("Reading problem data from `%s'...\n", fname); if (!(fmt == GLP_MPS_DECK || fmt == GLP_MPS_FILE)) xerror("glp_read_mps: fmt = %d; invalid parameter\n", fmt); if (parm == NULL) glp_init_mpscp(&_parm), parm = &_parm; /* check control parameters */ check_parm("glp_read_mps", parm); /* initialize common storage area */ csa->P = P; csa->deck = (fmt == GLP_MPS_DECK); csa->parm = parm; csa->fname = fname; csa->fp = NULL; if (setjmp(csa->jump)) { ret = 1; goto done; } csa->recno = csa->recpos = 0; csa->c = '\n'; csa->fldno = 0; csa->field[0] = '\0'; csa->w80 = csa->wef = 0; csa->obj_row = 0; csa->work1 = csa->work2 = csa->work3 = NULL; /* erase problem object */ glp_erase_prob(P); glp_create_index(P); /* open input MPS file */ csa->fp = xfopen(fname, "r"); if (csa->fp == NULL) { xprintf("Unable to open `%s' - %s\n", fname, xerrmsg()); ret = 1; goto done; } /* read NAME indicator record */ read_name(csa); if (P->name != NULL) xprintf("Problem: %s\n", P->name); /* read ROWS section */ if (!(indicator(csa, 0) && strcmp(csa->field, "ROWS") == 0)) error(csa, "missing ROWS indicator record\n"); read_rows(csa); /* determine objective row */ if (parm->obj_name == NULL || parm->obj_name[0] == '\0') { /* use the first row of N type */ int i; for (i = 1; i <= P->m; i++) { if (P->row[i]->type == GLP_FR) { csa->obj_row = i; break; } } if (csa->obj_row == 0) warning(csa, "unable to determine objective row\n"); } else { /* use a row with specified name */ int i; for (i = 1; i <= P->m; i++) { xassert(P->row[i]->name != NULL); if (strcmp(parm->obj_name, P->row[i]->name) == 0) { csa->obj_row = i; break; } } if (csa->obj_row == 0) error(csa, "objective row `%s' not found\n", parm->obj_name); } if (csa->obj_row != 0) { glp_set_obj_name(P, P->row[csa->obj_row]->name); xprintf("Objective: %s\n", P->obj); } /* read COLUMNS section */ if (strcmp(csa->field, "COLUMNS") != 0) error(csa, "missing COLUMNS indicator record\n"); read_columns(csa); /* set objective coefficients */ if (csa->obj_row != 0) { GLPAIJ *aij; for (aij = P->row[csa->obj_row]->ptr; aij != NULL; aij = aij->r_next) glp_set_obj_coef(P, aij->col->j, aij->val); } /* read optional RHS section */ if (strcmp(csa->field, "RHS") == 0) read_rhs(csa); /* read optional RANGES section */ if (strcmp(csa->field, "RANGES") == 0) read_ranges(csa); /* read optional BOUNDS section */ if (strcmp(csa->field, "BOUNDS") == 0) read_bounds(csa); /* read ENDATA indicator record */ if (strcmp(csa->field, "ENDATA") != 0) error(csa, "invalid use of %s indicator record\n", csa->field); /* print some statistics */ xprintf("%d row%s, %d column%s, %d non-zero%s\n", P->m, P->m == 1 ? "" : "s", P->n, P->n == 1 ? "" : "s", P->nnz, P->nnz == 1 ? "" : "s"); if (glp_get_num_int(P) > 0) { int ni = glp_get_num_int(P); int nb = glp_get_num_bin(P); if (ni == 1) { if (nb == 0) xprintf("One variable is integer\n"); else xprintf("One variable is binary\n"); } else { xprintf("%d integer variables, ", ni); if (nb == 0) xprintf("none"); else if (nb == 1) xprintf("one"); else if (nb == ni) xprintf("all"); else xprintf("%d", nb); xprintf(" of which %s binary\n", nb == 1 ? "is" : "are"); } } xprintf("%d records were read\n", csa->recno); /* problem data has been successfully read */ glp_delete_index(P); glp_sort_matrix(P); ret = 0; done: if (csa->fp != NULL) xfclose(csa->fp); if (csa->work1 != NULL) xfree(csa->work1); if (csa->work2 != NULL) xfree(csa->work2); if (csa->work3 != NULL) xfree(csa->work3); if (ret != 0) glp_erase_prob(P); return ret; } /*********************************************************************** * NAME * * glp_write_mps - write problem data in MPS format * * SYNOPSIS * * int glp_write_mps(glp_prob *P, int fmt, const glp_mpscp *parm, * const char *fname); * * DESCRIPTION * * The routine glp_write_mps writes problem data in MPS format to a * text file. * * The parameter fmt specifies the version of MPS format: * * GLP_MPS_DECK - fixed (ancient) MPS format; * GLP_MPS_FILE - free (modern) MPS format. * * The parameter parm is a pointer to the structure glp_mpscp, which * specifies control parameters used by the routine. If parm is NULL, * the routine uses default settings. * * The character string fname specifies a name of the text file to be * written. * * RETURNS * * If the operation was successful, the routine glp_read_mps returns * zero. Otherwise, it prints an error message and returns non-zero. */ #define csa csa1 struct csa { /* common storage area */ glp_prob *P; /* pointer to problem object */ int deck; /* MPS format (0 - free, 1 - fixed) */ const glp_mpscp *parm; /* pointer to control parameters */ char field[255+1]; /* field buffer */ }; static char *mps_name(struct csa *csa) { /* make problem name */ char *f; if (csa->P->name == NULL) csa->field[0] = '\0'; else if (csa->deck) { strncpy(csa->field, csa->P->name, 8); csa->field[8] = '\0'; } else strcpy(csa->field, csa->P->name); for (f = csa->field; *f != '\0'; f++) if (*f == ' ') *f = '_'; return csa->field; } static char *row_name(struct csa *csa, int i) { /* make i-th row name */ char *f; xassert(0 <= i && i <= csa->P->m); if (i == 0 || csa->P->row[i]->name == NULL || csa->deck && strlen(csa->P->row[i]->name) > 8) sprintf(csa->field, "R%07d", i); else { strcpy(csa->field, csa->P->row[i]->name); for (f = csa->field; *f != '\0'; f++) if (*f == ' ') *f = '_'; } return csa->field; } static char *col_name(struct csa *csa, int j) { /* make j-th column name */ char *f; xassert(1 <= j && j <= csa->P->n); if (csa->P->col[j]->name == NULL || csa->deck && strlen(csa->P->col[j]->name) > 8) sprintf(csa->field, "C%07d", j); else { strcpy(csa->field, csa->P->col[j]->name); for (f = csa->field; *f != '\0'; f++) if (*f == ' ') *f = '_'; } return csa->field; } static char *mps_numb(struct csa *csa, double val) { /* format floating-point number */ int dig; char *exp; for (dig = 12; dig >= 6; dig--) { if (val != 0.0 && fabs(val) < 0.002) sprintf(csa->field, "%.*E", dig-1, val); else sprintf(csa->field, "%.*G", dig, val); exp = strchr(csa->field, 'E'); if (exp != NULL) sprintf(exp+1, "%d", atoi(exp+1)); if (strlen(csa->field) <= 12) break; } xassert(strlen(csa->field) <= 12); return csa->field; } int glp_write_mps(glp_prob *P, int fmt, const glp_mpscp *parm, const char *fname) { /* write problem data in MPS format */ glp_mpscp _parm; struct csa _csa, *csa = &_csa; XFILE *fp; int out_obj, one_col = 0, empty = 0; int i, j, recno, marker, count, gap, ret; xprintf("Writing problem data to `%s'...\n", fname); if (!(fmt == GLP_MPS_DECK || fmt == GLP_MPS_FILE)) xerror("glp_write_mps: fmt = %d; invalid parameter\n", fmt); if (parm == NULL) glp_init_mpscp(&_parm), parm = &_parm; /* check control parameters */ check_parm("glp_write_mps", parm); /* initialize common storage area */ csa->P = P; csa->deck = (fmt == GLP_MPS_DECK); csa->parm = parm; /* create output MPS file */ fp = xfopen(fname, "w"), recno = 0; if (fp == NULL) { xprintf("Unable to create `%s' - %s\n", fname, xerrmsg()); ret = 1; goto done; } /* write comment records */ xfprintf(fp, "* %-*s%s\n", P->name == NULL ? 1 : 12, "Problem:", P->name == NULL ? "" : P->name), recno++; xfprintf(fp, "* %-12s%s\n", "Class:", glp_get_num_int(P) == 0 ? "LP" : "MIP"), recno++; xfprintf(fp, "* %-12s%d\n", "Rows:", P->m), recno++; if (glp_get_num_int(P) == 0) xfprintf(fp, "* %-12s%d\n", "Columns:", P->n), recno++; else xfprintf(fp, "* %-12s%d (%d integer, %d binary)\n", "Columns:", P->n, glp_get_num_int(P), glp_get_num_bin(P)), recno++; xfprintf(fp, "* %-12s%d\n", "Non-zeros:", P->nnz), recno++; xfprintf(fp, "* %-12s%s\n", "Format:", csa->deck ? "Fixed MPS" : "Free MPS"), recno++; xfprintf(fp, "*\n", recno++); /* write NAME indicator record */ xfprintf(fp, "NAME%*s%s\n", P->name == NULL ? 0 : csa->deck ? 10 : 1, "", mps_name(csa)), recno++; #if 1 /* determine whether to write the objective row */ out_obj = 1; for (i = 1; i <= P->m; i++) { if (P->row[i]->type == GLP_FR) { out_obj = 0; break; } } #endif /* write ROWS section */ xfprintf(fp, "ROWS\n"), recno++; for (i = (out_obj ? 0 : 1); i <= P->m; i++) { int type; type = (i == 0 ? GLP_FR : P->row[i]->type); if (type == GLP_FR) type = 'N'; else if (type == GLP_LO) type = 'G'; else if (type == GLP_UP) type = 'L'; else if (type == GLP_DB || type == GLP_FX) type = 'E'; else xassert(type != type); xfprintf(fp, " %c%*s%s\n", type, csa->deck ? 2 : 1, "", row_name(csa, i)), recno++; } /* write COLUMNS section */ xfprintf(fp, "COLUMNS\n"), recno++; marker = 0; for (j = 1; j <= P->n; j++) { GLPAIJ cj, *aij; int kind; kind = P->col[j]->kind; if (kind == GLP_CV) { if (marker % 2 == 1) { /* close current integer block */ marker++; xfprintf(fp, "%*sM%07d%*s'MARKER'%*s'INTEND'\n", csa->deck ? 4 : 1, "", marker, csa->deck ? 2 : 1, "", csa->deck ? 17 : 1, ""), recno++; } } else if (kind == GLP_IV) { if (marker % 2 == 0) { /* open new integer block */ marker++; xfprintf(fp, "%*sM%07d%*s'MARKER'%*s'INTORG'\n", csa->deck ? 4 : 1, "", marker, csa->deck ? 2 : 1, "", csa->deck ? 17 : 1, ""), recno++; } } else xassert(kind != kind); if (out_obj && P->col[j]->coef != 0.0) { /* make fake objective coefficient */ aij = &cj; aij->row = NULL; aij->val = P->col[j]->coef; aij->c_next = P->col[j]->ptr; } else aij = P->col[j]->ptr; #if 1 /* FIXME */ if (aij == NULL) { /* empty column */ empty++; xfprintf(fp, "%*s%-*s", csa->deck ? 4 : 1, "", csa->deck ? 8 : 1, col_name(csa, j)); /* we need a row */ xassert(P->m > 0); xfprintf(fp, "%*s%-*s", csa->deck ? 2 : 1, "", csa->deck ? 8 : 1, row_name(csa, 1)); xfprintf(fp, "%*s0%*s$ empty column\n", csa->deck ? 13 : 1, "", csa->deck ? 3 : 1, ""), recno++; } #endif count = 0; for (aij = aij; aij != NULL; aij = aij->c_next) { if (one_col || count % 2 == 0) xfprintf(fp, "%*s%-*s", csa->deck ? 4 : 1, "", csa->deck ? 8 : 1, col_name(csa, j)); gap = (one_col || count % 2 == 0 ? 2 : 3); xfprintf(fp, "%*s%-*s", csa->deck ? gap : 1, "", csa->deck ? 8 : 1, row_name(csa, aij->row == NULL ? 0 : aij->row->i)); xfprintf(fp, "%*s%*s", csa->deck ? 2 : 1, "", csa->deck ? 12 : 1, mps_numb(csa, aij->val)), count++; if (one_col || count % 2 == 0) xfprintf(fp, "\n"), recno++; } if (!(one_col || count % 2 == 0)) xfprintf(fp, "\n"), recno++; } if (marker % 2 == 1) { /* close last integer block */ marker++; xfprintf(fp, "%*sM%07d%*s'MARKER'%*s'INTEND'\n", csa->deck ? 4 : 1, "", marker, csa->deck ? 2 : 1, "", csa->deck ? 17 : 1, ""), recno++; } #if 1 if (empty > 0) xprintf("Warning: problem has %d empty column(s)\n", empty); #endif /* write RHS section */ xfprintf(fp, "RHS\n"), recno++; count = 0; for (i = (out_obj ? 0 : 1); i <= P->m; i++) { int type; double rhs; if (i == 0) rhs = P->c0; else { type = P->row[i]->type; if (type == GLP_FR) rhs = 0.0; else if (type == GLP_LO) rhs = P->row[i]->lb; else if (type == GLP_UP) rhs = P->row[i]->ub; else if (type == GLP_DB || type == GLP_FX) rhs = P->row[i]->lb; else xassert(type != type); } if (rhs != 0.0) { if (one_col || count % 2 == 0) xfprintf(fp, "%*s%-*s", csa->deck ? 4 : 1, "", csa->deck ? 8 : 1, "RHS1"); gap = (one_col || count % 2 == 0 ? 2 : 3); xfprintf(fp, "%*s%-*s", csa->deck ? gap : 1, "", csa->deck ? 8 : 1, row_name(csa, i)); xfprintf(fp, "%*s%*s", csa->deck ? 2 : 1, "", csa->deck ? 12 : 1, mps_numb(csa, rhs)), count++; if (one_col || count % 2 == 0) xfprintf(fp, "\n"), recno++; } } if (!(one_col || count % 2 == 0)) xfprintf(fp, "\n"), recno++; /* write RANGES section */ for (i = P->m; i >= 1; i--) if (P->row[i]->type == GLP_DB) break; if (i == 0) goto bnds; xfprintf(fp, "RANGES\n"), recno++; count = 0; for (i = 1; i <= P->m; i++) { if (P->row[i]->type == GLP_DB) { if (one_col || count % 2 == 0) xfprintf(fp, "%*s%-*s", csa->deck ? 4 : 1, "", csa->deck ? 8 : 1, "RNG1"); gap = (one_col || count % 2 == 0 ? 2 : 3); xfprintf(fp, "%*s%-*s", csa->deck ? gap : 1, "", csa->deck ? 8 : 1, row_name(csa, i)); xfprintf(fp, "%*s%*s", csa->deck ? 2 : 1, "", csa->deck ? 12 : 1, mps_numb(csa, P->row[i]->ub - P->row[i]->lb)), count++; if (one_col || count % 2 == 0) xfprintf(fp, "\n"), recno++; } } if (!(one_col || count % 2 == 0)) xfprintf(fp, "\n"), recno++; bnds: /* write BOUNDS section */ for (j = P->n; j >= 1; j--) if (!(P->col[j]->type == GLP_LO && P->col[j]->lb == 0.0)) break; if (j == 0) goto endt; xfprintf(fp, "BOUNDS\n"), recno++; for (j = 1; j <= P->n; j++) { int type, data[2]; double bnd[2]; char *spec[2]; spec[0] = spec[1] = NULL; type = P->col[j]->type; if (type == GLP_FR) spec[0] = "FR", data[0] = 0; else if (type == GLP_LO) { if (P->col[j]->lb != 0.0) spec[0] = "LO", data[0] = 1, bnd[0] = P->col[j]->lb; if (P->col[j]->kind == GLP_IV) spec[1] = "PL", data[1] = 0; } else if (type == GLP_UP) { spec[0] = "MI", data[0] = 0; spec[1] = "UP", data[1] = 1, bnd[1] = P->col[j]->ub; } else if (type == GLP_DB) { if (P->col[j]->lb != 0.0) spec[0] = "LO", data[0] = 1, bnd[0] = P->col[j]->lb; spec[1] = "UP", data[1] = 1, bnd[1] = P->col[j]->ub; } else if (type == GLP_FX) spec[0] = "FX", data[0] = 1, bnd[0] = P->col[j]->lb; else xassert(type != type); for (i = 0; i <= 1; i++) { if (spec[i] != NULL) { xfprintf(fp, " %s %-*s%*s%-*s", spec[i], csa->deck ? 8 : 1, "BND1", csa->deck ? 2 : 1, "", csa->deck ? 8 : 1, col_name(csa, j)); if (data[i]) xfprintf(fp, "%*s%*s", csa->deck ? 2 : 1, "", csa->deck ? 12 : 1, mps_numb(csa, bnd[i])); xfprintf(fp, "\n"), recno++; } } } endt: /* write ENDATA indicator record */ xfprintf(fp, "ENDATA\n"), recno++; xfflush(fp); if (xferror(fp)) { xprintf("Write error on `%s' - %s\n", fname, xerrmsg()); ret = 1; goto done; } /* problem data has been successfully written */ xprintf("%d records were written\n", recno); ret = 0; done: if (fp != NULL) xfclose(fp); return ret; } /* eof */ praat-6.0.04/external/glpk/glpnet.h000066400000000000000000000043731261542461700171500ustar00rootroot00000000000000/* glpnet.h (graph and network algorithms) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPNET_H #define GLPNET_H #define mc21a _glp_mc21a int mc21a(int n, const int icn[], const int ip[], const int lenr[], int iperm[], int pr[], int arp[], int cv[], int out[]); /* permutations for zero-free diagonal */ #define mc13d _glp_mc13d int mc13d(int n, const int icn[], const int ip[], const int lenr[], int ior[], int ib[], int lowl[], int numb[], int prev[]); /* permutations to block triangular form */ #define okalg _glp_okalg int okalg(int nv, int na, const int tail[], const int head[], const int low[], const int cap[], const int cost[], int x[], int pi[]); /* out-of-kilter algorithm */ #define ffalg _glp_ffalg void ffalg(int nv, int na, const int tail[], const int head[], int s, int t, const int cap[], int x[], char cut[]); /* Ford-Fulkerson algorithm */ #define wclique _glp_wclique int wclique(int n, const int w[], const unsigned char a[], int ind[]); /* find maximum weight clique with Ostergard's algorithm */ #define kellerman _glp_kellerman int kellerman(int n, int (*func)(void *info, int i, int ind[]), void *info, void /* glp_graph */ *H); /* cover edges by cliques with Kellerman's heuristic */ #endif /* eof */ praat-6.0.04/external/glpk/glpnet01.c000066400000000000000000000233501261542461700173000ustar00rootroot00000000000000/* glpnet01.c (permutations for zero-free diagonal) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * This code is the result of translation of the Fortran subroutines * MC21A and MC21B associated with the following paper: * * I.S.Duff, Algorithm 575: Permutations for zero-free diagonal, ACM * Trans. on Math. Softw. 7 (1981), 387-390. * * Use of ACM Algorithms is subject to the ACM Software Copyright and * License Agreement. See . * * The translation was made by Andrew Makhorin . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpnet.h" /*********************************************************************** * NAME * * mc21a - permutations for zero-free diagonal * * SYNOPSIS * * #include "glpnet.h" * int mc21a(int n, const int icn[], const int ip[], const int lenr[], * int iperm[], int pr[], int arp[], int cv[], int out[]); * * DESCRIPTION * * Given the pattern of nonzeros of a sparse matrix, the routine mc21a * attempts to find a permutation of its rows that makes the matrix have * no zeros on its diagonal. * * INPUT PARAMETERS * * n order of matrix. * * icn array containing the column indices of the non-zeros. Those * belonging to a single row must be contiguous but the ordering * of column indices within each row is unimportant and wasted * space between rows is permitted. * * ip ip[i], i = 1,2,...,n, is the position in array icn of the * first column index of a non-zero in row i. * * lenr lenr[i], i = 1,2,...,n, is the number of non-zeros in row i. * * OUTPUT PARAMETER * * iperm contains permutation to make diagonal have the smallest * number of zeros on it. Elements (iperm[i], i), i = 1,2,...,n, * are non-zero at the end of the algorithm unless the matrix is * structurally singular. In this case, (iperm[i], i) will be * zero for n - numnz entries. * * WORKING ARRAYS * * pr working array of length [1+n], where pr[0] is not used. * pr[i] is the previous row to i in the depth first search. * * arp working array of length [1+n], where arp[0] is not used. * arp[i] is one less than the number of non-zeros in row i which * have not been scanned when looking for a cheap assignment. * * cv working array of length [1+n], where cv[0] is not used. * cv[i] is the most recent row extension at which column i was * visited. * * out working array of length [1+n], where out[0] is not used. * out[i] is one less than the number of non-zeros in row i * which have not been scanned during one pass through the main * loop. * * RETURNS * * The routine mc21a returns numnz, the number of non-zeros on diagonal * of permuted matrix. */ int mc21a(int n, const int icn[], const int ip[], const int lenr[], int iperm[], int pr[], int arp[], int cv[], int out[]) { int i, ii, in1, in2, j, j1, jord, k, kk, numnz; /* Initialization of arrays. */ for (i = 1; i <= n; i++) { arp[i] = lenr[i] - 1; cv[i] = iperm[i] = 0; } numnz = 0; /* Main loop. */ /* Each pass round this loop either results in a new assignment or gives a row with no assignment. */ for (jord = 1; jord <= n; jord++) { j = jord; pr[j] = -1; for (k = 1; k <= jord; k++) { /* Look for a cheap assignment. */ in1 = arp[j]; if (in1 >= 0) { in2 = ip[j] + lenr[j] - 1; in1 = in2 - in1; for (ii = in1; ii <= in2; ii++) { i = icn[ii]; if (iperm[i] == 0) goto L110; } /* No cheap assignment in row. */ arp[j] = -1; } /* Begin looking for assignment chain starting with row j.*/ out[j] = lenr[j] - 1; /* Inner loop. Extends chain by one or backtracks. */ for (kk = 1; kk <= jord; kk++) { in1 = out[j]; if (in1 >= 0) { in2 = ip[j] + lenr[j] - 1; in1 = in2 - in1; /* Forward scan. */ for (ii = in1; ii <= in2; ii++) { i = icn[ii]; if (cv[i] != jord) { /* Column i has not yet been accessed during this pass. */ j1 = j; j = iperm[i]; cv[i] = jord; pr[j] = j1; out[j1] = in2 - ii - 1; goto L100; } } } /* Backtracking step. */ j = pr[j]; if (j == -1) goto L130; } L100: ; } L110: /* New assignment is made. */ iperm[i] = j; arp[j] = in2 - ii - 1; numnz++; for (k = 1; k <= jord; k++) { j = pr[j]; if (j == -1) break; ii = ip[j] + lenr[j] - out[j] - 2; i = icn[ii]; iperm[i] = j; } L130: ; } /* If matrix is structurally singular, we now complete the permutation iperm. */ if (numnz < n) { for (i = 1; i <= n; i++) arp[i] = 0; k = 0; for (i = 1; i <= n; i++) { if (iperm[i] == 0) out[++k] = i; else arp[iperm[i]] = i; } k = 0; for (i = 1; i <= n; i++) { if (arp[i] == 0) iperm[out[++k]] = i; } } return numnz; } /**********************************************************************/ #if 0 #include "glplib.h" int sing; void ranmat(int m, int n, int icn[], int iptr[], int nnnp1, int *knum, int iw[]); void fa01bs(int max, int *nrand); int main(void) { /* test program for the routine mc21a */ /* these runs on random matrices cause all possible statements in mc21a to be executed */ int i, iold, j, j1, j2, jj, knum, l, licn, n, nov4, num, numnz; int ip[1+21], icn[1+1000], iperm[1+20], lenr[1+20], iw1[1+80]; licn = 1000; /* run on random matrices of orders 1 through 20 */ for (n = 1; n <= 20; n++) { nov4 = n / 4; if (nov4 < 1) nov4 = 1; L10: fa01bs(nov4, &l); knum = l * n; /* knum is requested number of non-zeros in random matrix */ if (knum > licn) goto L10; /* if sing is false, matrix is guaranteed structurally non-singular */ sing = ((n / 2) * 2 == n); /* call to subroutine to generate random matrix */ ranmat(n, n, icn, ip, n+1, &knum, iw1); /* knum is now actual number of non-zeros in random matrix */ if (knum > licn) goto L10; xprintf("n = %2d; nz = %4d; sing = %d\n", n, knum, sing); /* set up array of row lengths */ for (i = 1; i <= n; i++) lenr[i] = ip[i+1] - ip[i]; /* call to mc21a */ numnz = mc21a(n, icn, ip, lenr, iperm, &iw1[0], &iw1[n], &iw1[n+n], &iw1[n+n+n]); /* testing to see if there are numnz non-zeros on the diagonal of the permuted matrix. */ num = 0; for (i = 1; i <= n; i++) { iold = iperm[i]; j1 = ip[iold]; j2 = j1 + lenr[iold] - 1; if (j2 < j1) continue; for (jj = j1; jj <= j2; jj++) { j = icn[jj]; if (j == i) { num++; break; } } } if (num != numnz) xprintf("Failure in mc21a, numnz = %d instead of %d\n", numnz, num); } return 0; } void ranmat(int m, int n, int icn[], int iptr[], int nnnp1, int *knum, int iw[]) { /* subroutine to generate random matrix */ int i, ii, inum, j, lrow, matnum; inum = (*knum / n) * 2; if (inum > n-1) inum = n-1; matnum = 1; /* each pass through this loop generates a row of the matrix */ for (j = 1; j <= m; j++) { iptr[j] = matnum; if (!(sing || j > n)) icn[matnum++] = j; if (n == 1) continue; for (i = 1; i <= n; i++) iw[i] = 0; if (!sing) iw[j] = 1; fa01bs(inum, &lrow); lrow--; if (lrow == 0) continue; /* lrow off-diagonal non-zeros in row j of the matrix */ for (ii = 1; ii <= lrow; ii++) { for (;;) { fa01bs(n, &i); if (iw[i] != 1) break; } iw[i] = 1; icn[matnum++] = i; } } for (i = m+1; i <= nnnp1; i++) iptr[i] = matnum; *knum = matnum - 1; return; } double g = 1431655765.0; double fa01as(int i) { /* random number generator */ g = fmod(g * 9228907.0, 4294967296.0); if (i >= 0) return g / 4294967296.0; else return 2.0 * g / 4294967296.0 - 1.0; } void fa01bs(int max, int *nrand) { *nrand = (int)(fa01as(1) * (double)max) + 1; return; } #endif /* eof */ praat-6.0.04/external/glpk/glpnet02.c000066400000000000000000000244361261542461700173070ustar00rootroot00000000000000/* glpnet02.c (permutations to block triangular form) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * This code is the result of translation of the Fortran subroutines * MC13D and MC13E associated with the following paper: * * I.S.Duff, J.K.Reid, Algorithm 529: Permutations to block triangular * form, ACM Trans. on Math. Softw. 4 (1978), 189-192. * * Use of ACM Algorithms is subject to the ACM Software Copyright and * License Agreement. See . * * The translation was made by Andrew Makhorin . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpnet.h" /*********************************************************************** * NAME * * mc13d - permutations to block triangular form * * SYNOPSIS * * #include "glpnet.h" * int mc13d(int n, const int icn[], const int ip[], const int lenr[], * int ior[], int ib[], int lowl[], int numb[], int prev[]); * * DESCRIPTION * * Given the column numbers of the nonzeros in each row of the sparse * matrix, the routine mc13d finds a symmetric permutation that makes * the matrix block lower triangular. * * INPUT PARAMETERS * * n order of the matrix. * * icn array containing the column indices of the non-zeros. Those * belonging to a single row must be contiguous but the ordering * of column indices within each row is unimportant and wasted * space between rows is permitted. * * ip ip[i], i = 1,2,...,n, is the position in array icn of the * first column index of a non-zero in row i. * * lenr lenr[i], i = 1,2,...,n, is the number of non-zeros in row i. * * OUTPUT PARAMETERS * * ior ior[i], i = 1,2,...,n, gives the position on the original * ordering of the row or column which is in position i in the * permuted form. * * ib ib[i], i = 1,2,...,num, is the row number in the permuted * matrix of the beginning of block i, 1 <= num <= n. * * WORKING ARRAYS * * arp working array of length [1+n], where arp[0] is not used. * arp[i] is one less than the number of unsearched edges leaving * node i. At the end of the algorithm it is set to a permutation * which puts the matrix in block lower triangular form. * * ib working array of length [1+n], where ib[0] is not used. * ib[i] is the position in the ordering of the start of the ith * block. ib[n+1-i] holds the node number of the ith node on the * stack. * * lowl working array of length [1+n], where lowl[0] is not used. * lowl[i] is the smallest stack position of any node to which a * path from node i has been found. It is set to n+1 when node i * is removed from the stack. * * numb working array of length [1+n], where numb[0] is not used. * numb[i] is the position of node i in the stack if it is on it, * is the permuted order of node i for those nodes whose final * position has been found and is otherwise zero. * * prev working array of length [1+n], where prev[0] is not used. * prev[i] is the node at the end of the path when node i was * placed on the stack. * * RETURNS * * The routine mc13d returns num, the number of blocks found. */ int mc13d(int n, const int icn[], const int ip[], const int lenr[], int ior[], int ib[], int lowl[], int numb[], int prev[]) { int *arp = ior; int dummy, i, i1, i2, icnt, ii, isn, ist, ist1, iv, iw, j, lcnt, nnm1, num, stp; /* icnt is the number of nodes whose positions in final ordering have been found. */ icnt = 0; /* num is the number of blocks that have been found. */ num = 0; nnm1 = n + n - 1; /* Initialization of arrays. */ for (j = 1; j <= n; j++) { numb[j] = 0; arp[j] = lenr[j] - 1; } for (isn = 1; isn <= n; isn++) { /* Look for a starting node. */ if (numb[isn] != 0) continue; iv = isn; /* ist is the number of nodes on the stack ... it is the stack pointer. */ ist = 1; /* Put node iv at beginning of stack. */ lowl[iv] = numb[iv] = 1; ib[n] = iv; /* The body of this loop puts a new node on the stack or backtracks. */ for (dummy = 1; dummy <= nnm1; dummy++) { i1 = arp[iv]; /* Have all edges leaving node iv been searched? */ if (i1 >= 0) { i2 = ip[iv] + lenr[iv] - 1; i1 = i2 - i1; /* Look at edges leaving node iv until one enters a new node or all edges are exhausted. */ for (ii = i1; ii <= i2; ii++) { iw = icn[ii]; /* Has node iw been on stack already? */ if (numb[iw] == 0) goto L70; /* Update value of lowl[iv] if necessary. */ if (lowl[iw] < lowl[iv]) lowl[iv] = lowl[iw]; } /* There are no more edges leaving node iv. */ arp[iv] = -1; } /* Is node iv the root of a block? */ if (lowl[iv] < numb[iv]) goto L60; /* Order nodes in a block. */ num++; ist1 = n + 1 - ist; lcnt = icnt + 1; /* Peel block off the top of the stack starting at the top and working down to the root of the block. */ for (stp = ist1; stp <= n; stp++) { iw = ib[stp]; lowl[iw] = n + 1; numb[iw] = ++icnt; if (iw == iv) break; } ist = n - stp; ib[num] = lcnt; /* Are there any nodes left on the stack? */ if (ist != 0) goto L60; /* Have all the nodes been ordered? */ if (icnt < n) break; goto L100; L60: /* Backtrack to previous node on path. */ iw = iv; iv = prev[iv]; /* Update value of lowl[iv] if necessary. */ if (lowl[iw] < lowl[iv]) lowl[iv] = lowl[iw]; continue; L70: /* Put new node on the stack. */ arp[iv] = i2 - ii - 1; prev[iw] = iv; iv = iw; lowl[iv] = numb[iv] = ++ist; ib[n+1-ist] = iv; } } L100: /* Put permutation in the required form. */ for (i = 1; i <= n; i++) arp[numb[i]] = i; return num; } /**********************************************************************/ #if 0 #include "glplib.h" void test(int n, int ipp); int main(void) { /* test program for routine mc13d */ test( 1, 0); test( 2, 1); test( 2, 2); test( 3, 3); test( 4, 4); test( 5, 10); test(10, 10); test(10, 20); test(20, 20); test(20, 50); test(50, 50); test(50, 200); return 0; } void fa01bs(int max, int *nrand); void setup(int n, char a[1+50][1+50], int ip[], int icn[], int lenr[]); void test(int n, int ipp) { int ip[1+50], icn[1+1000], ior[1+50], ib[1+51], iw[1+150], lenr[1+50]; char a[1+50][1+50], hold[1+100]; int i, ii, iblock, ij, index, j, jblock, jj, k9, num; xprintf("\n\n\nMatrix is of order %d and has %d off-diagonal non-" "zeros\n", n, ipp); for (j = 1; j <= n; j++) { for (i = 1; i <= n; i++) a[i][j] = 0; a[j][j] = 1; } for (k9 = 1; k9 <= ipp; k9++) { /* these statements should be replaced by calls to your favorite random number generator to place two pseudo-random numbers between 1 and n in the variables i and j */ for (;;) { fa01bs(n, &i); fa01bs(n, &j); if (!a[i][j]) break; } a[i][j] = 1; } /* setup converts matrix a[i,j] to required sparsity-oriented storage format */ setup(n, a, ip, icn, lenr); num = mc13d(n, icn, ip, lenr, ior, ib, &iw[0], &iw[n], &iw[n+n]); /* output reordered matrix with blocking to improve clarity */ xprintf("\nThe reordered matrix which has %d block%s is of the fo" "rm\n", num, num == 1 ? "" : "s"); ib[num+1] = n + 1; index = 100; iblock = 1; for (i = 1; i <= n; i++) { for (ij = 1; ij <= index; ij++) hold[ij] = ' '; if (i == ib[iblock]) { xprintf("\n"); iblock++; } jblock = 1; index = 0; for (j = 1; j <= n; j++) { if (j == ib[jblock]) { hold[++index] = ' '; jblock++; } ii = ior[i]; jj = ior[j]; hold[++index] = (char)(a[ii][jj] ? 'X' : '0'); } xprintf("%.*s\n", index, &hold[1]); } xprintf("\nThe starting point for each block is given by\n"); for (i = 1; i <= num; i++) { if ((i - 1) % 12 == 0) xprintf("\n"); xprintf(" %4d", ib[i]); } xprintf("\n"); return; } void setup(int n, char a[1+50][1+50], int ip[], int icn[], int lenr[]) { int i, j, ind; for (i = 1; i <= n; i++) lenr[i] = 0; ind = 1; for (i = 1; i <= n; i++) { ip[i] = ind; for (j = 1; j <= n; j++) { if (a[i][j]) { lenr[i]++; icn[ind++] = j; } } } return; } double g = 1431655765.0; double fa01as(int i) { /* random number generator */ g = fmod(g * 9228907.0, 4294967296.0); if (i >= 0) return g / 4294967296.0; else return 2.0 * g / 4294967296.0 - 1.0; } void fa01bs(int max, int *nrand) { *nrand = (int)(fa01as(1) * (double)max) + 1; return; } #endif /* eof */ praat-6.0.04/external/glpk/glpnet03.c000066400000000000000000000604051261542461700173040ustar00rootroot00000000000000/* glpnet03.c (Klingman's network problem generator) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * This code is the result of translation of the Fortran program NETGEN * developed by Dr. Darwin Klingman, which is publically available from * NETLIB at . * * The translation was made by Andrew Makhorin . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpapi.h" /*********************************************************************** * NAME * * glp_netgen - Klingman's network problem generator * * SYNOPSIS * * int glp_netgen(glp_graph *G, int v_rhs, int a_cap, int a_cost, * const int parm[1+15]); * * DESCRIPTION * * The routine glp_netgen is a network problem generator developed by * Dr. Darwin Klingman. It can create capacitated and uncapacitated * minimum cost flow (or transshipment), transportation, and assignment * problems. * * The parameter G specifies the graph object, to which the generated * problem data have to be stored. Note that on entry the graph object * is erased with the routine glp_erase_graph. * * The parameter v_rhs specifies an offset of the field of type double * in the vertex data block, to which the routine stores the supply or * demand value. If v_rhs < 0, the value is not stored. * * The parameter a_cap specifies an offset of the field of type double * in the arc data block, to which the routine stores the arc capacity. * If a_cap < 0, the capacity is not stored. * * The parameter a_cost specifies an offset of the field of type double * in the arc data block, to which the routine stores the per-unit cost * if the arc flow. If a_cost < 0, the cost is not stored. * * The array parm contains description of the network to be generated: * * parm[0] not used * parm[1] (iseed) 8-digit positive random number seed * parm[2] (nprob) 8-digit problem id number * parm[3] (nodes) total number of nodes * parm[4] (nsorc) total number of source nodes (including * transshipment nodes) * parm[5] (nsink) total number of sink nodes (including * transshipment nodes) * parm[6] (iarcs) number of arcs * parm[7] (mincst) minimum cost for arcs * parm[8] (maxcst) maximum cost for arcs * parm[9] (itsup) total supply * parm[10] (ntsorc) number of transshipment source nodes * parm[11] (ntsink) number of transshipment sink nodes * parm[12] (iphic) percentage of skeleton arcs to be given * the maximum cost * parm[13] (ipcap) percentage of arcs to be capacitated * parm[14] (mincap) minimum upper bound for capacitated arcs * parm[15] (maxcap) maximum upper bound for capacitated arcs * * The routine generates a transportation problem if: * * nsorc + nsink = nodes, ntsorc = 0, and ntsink = 0. * * The routine generates an assignment problem if the requirements for * a transportation problem are met and: * * nsorc = nsink and itsup = nsorc. * * RETURNS * * If the instance was successfully generated, the routine glp_netgen * returns zero; otherwise, if specified parameters are inconsistent, * the routine returns a non-zero error code. * * REFERENCES * * D.Klingman, A.Napier, and J.Stutz. NETGEN: A program for generating * large scale capacitated assignment, transportation, and minimum cost * flow networks. Management Science 20 (1974), 814-20. */ struct csa { /* common storage area */ glp_graph *G; int v_rhs, a_cap, a_cost; int nodes, iarcs, mincst, maxcst, itsup, nsorc, nsink, nonsor, nfsink, narcs, nsort, nftsor, ipcap, mincap, maxcap, ktl, nodlft, *ipred, *ihead, *itail, *iflag, *isup, *lsinks, mult, modul, i15, i16, jran; }; #define G (csa->G) #define v_rhs (csa->v_rhs) #define a_cap (csa->a_cap) #define a_cost (csa->a_cost) #define nodes (csa->nodes) #define iarcs (csa->iarcs) #define mincst (csa->mincst) #define maxcst (csa->maxcst) #define itsup (csa->itsup) #define nsorc (csa->nsorc) #define nsink (csa->nsink) #define nonsor (csa->nonsor) #define nfsink (csa->nfsink) #define narcs (csa->narcs) #define nsort (csa->nsort) #define nftsor (csa->nftsor) #define ipcap (csa->ipcap) #define mincap (csa->mincap) #define maxcap (csa->maxcap) #define ktl (csa->ktl) #define nodlft (csa->nodlft) #if 0 /* spent a day to find out this bug */ #define ist (csa->ist) #else #define ist (ipred[0]) #endif #define ipred (csa->ipred) #define ihead (csa->ihead) #define itail (csa->itail) #define iflag (csa->iflag) #define isup (csa->isup) #define lsinks (csa->lsinks) #define mult (csa->mult) #define modul (csa->modul) #define i15 (csa->i15) #define i16 (csa->i16) #define jran (csa->jran) static void cresup(struct csa *csa); static void chain(struct csa *csa, int lpick, int lsorc); static void chnarc(struct csa *csa, int lsorc); static void sort(struct csa *csa); static void pickj(struct csa *csa, int it); static void assign(struct csa *csa); static void setran(struct csa *csa, int iseed); static int iran(struct csa *csa, int ilow, int ihigh); int glp_netgen(glp_graph *G_, int _v_rhs, int _a_cap, int _a_cost, const int parm[1+15]) { struct csa _csa, *csa = &_csa; int iseed, nprob, ntsorc, ntsink, iphic, i, nskel, nltr, ltsink, ntrans, npsink, nftr, npsorc, ntravl, ntrrem, lsorc, lpick, nsksr, nsrchn, j, item, l, ks, k, ksp, li, n, ii, it, ih, icap, jcap, icost, jcost, ret; G = G_; v_rhs = _v_rhs; a_cap = _a_cap; a_cost = _a_cost; if (G != NULL) { if (v_rhs >= 0 && v_rhs > G->v_size - (int)sizeof(double)) xerror("glp_netgen: v_rhs = %d; invalid offset\n", v_rhs); if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) xerror("glp_netgen: a_cap = %d; invalid offset\n", a_cap); if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) xerror("glp_netgen: a_cost = %d; invalid offset\n", a_cost); } /* Input the user's random number seed and fix it if non-positive. */ iseed = parm[1]; nprob = parm[2]; if (iseed <= 0) iseed = 13502460; setran(csa, iseed); /* Input the user's problem characteristics. */ nodes = parm[3]; nsorc = parm[4]; nsink = parm[5]; iarcs = parm[6]; mincst = parm[7]; maxcst = parm[8]; itsup = parm[9]; ntsorc = parm[10]; ntsink = parm[11]; iphic = parm[12]; ipcap = parm[13]; mincap = parm[14]; maxcap = parm[15]; /* Check the size of the problem. */ if (!(10 <= nodes && nodes <= 100000)) { ret = 1; goto done; } /* Check user supplied parameters for consistency. */ if (!(nsorc >= 0 && nsink >= 0 && nsorc + nsink <= nodes)) { ret = 2; goto done; } if (iarcs < 0) { ret = 3; goto done; } if (mincst > maxcst) { ret = 4; goto done; } if (itsup < 0) { ret = 5; goto done; } if (!(0 <= ntsorc && ntsorc <= nsorc)) { ret = 6; goto done; } if (!(0 <= ntsink && ntsink <= nsink)) { ret = 7; goto done; } if (!(0 <= iphic && iphic <= 100)) { ret = 8; goto done; } if (!(0 <= ipcap && ipcap <= 100)) { ret = 9; goto done; } if (mincap > maxcap) { ret = 10; goto done; } /* Initailize the graph object. */ if (G != NULL) { glp_erase_graph(G, G->v_size, G->a_size); glp_add_vertices(G, nodes); if (v_rhs >= 0) { double zero = 0.0; for (i = 1; i <= nodes; i++) { glp_vertex *v = G->v[i]; memcpy((char *)v->data + v_rhs, &zero, sizeof(double)); } } } /* Allocate working arrays. */ ipred = xcalloc(1+nodes, sizeof(int)); ihead = xcalloc(1+nodes, sizeof(int)); itail = xcalloc(1+nodes, sizeof(int)); iflag = xcalloc(1+nodes, sizeof(int)); isup = xcalloc(1+nodes, sizeof(int)); lsinks = xcalloc(1+nodes, sizeof(int)); /* Print the problem documentation records. */ if (G == NULL) { xprintf("BEGIN\n"); xprintf("NETGEN PROBLEM%8d%10s%10d NODES AND%10d ARCS\n", nprob, "", nodes, iarcs); xprintf("USER:%11d%11d%11d%11d%11d%11d\nDATA:%11d%11d%11d%11d%" "11d%11d\n", iseed, nsorc, nsink, mincst, maxcst, itsup, ntsorc, ntsink, iphic, ipcap, mincap, maxcap); } else glp_set_graph_name(G, "NETGEN"); /* Set various constants used in the program. */ narcs = 0; nskel = 0; nltr = nodes - nsink; ltsink = nltr + ntsink; ntrans = nltr - nsorc; nfsink = nltr + 1; nonsor = nodes - nsorc + ntsorc; npsink = nsink - ntsink; nodlft = nodes - nsink + ntsink; nftr = nsorc + 1; nftsor = nsorc - ntsorc + 1; npsorc = nsorc - ntsorc; /* Randomly distribute the supply among the source nodes. */ if (npsorc + npsink == nodes && npsorc == npsink && itsup == nsorc) { assign(csa); nskel = nsorc; goto L390; } cresup(csa); /* Print the supply records. */ if (G == NULL) { xprintf("SUPPLY\n"); for (i = 1; i <= nsorc; i++) xprintf("%6s%6d%18s%10d\n", "", i, "", isup[i]); xprintf("ARCS\n"); } else { if (v_rhs >= 0) { for (i = 1; i <= nsorc; i++) { double temp = (double)isup[i]; glp_vertex *v = G->v[i]; memcpy((char *)v->data + v_rhs, &temp, sizeof(double)); } } } /* Make the sources point to themselves in ipred array. */ for (i = 1; i <= nsorc; i++) ipred[i] = i; if (ntrans == 0) goto L170; /* Chain the transshipment nodes together in the ipred array. */ ist = nftr; ipred[nltr] = 0; for (i = nftr; i < nltr; i++) ipred[i] = i+1; /* Form even length chains for 60 percent of the transshipments.*/ ntravl = 6 * ntrans / 10; ntrrem = ntrans - ntravl; L140: lsorc = 1; while (ntravl != 0) { lpick = iran(csa, 1, ntravl + ntrrem); ntravl--; chain(csa, lpick, lsorc); if (lsorc == nsorc) goto L140; lsorc++; } /* Add the remaining transshipments to the chains. */ while (ntrrem != 0) { lpick = iran(csa, 1, ntrrem); ntrrem--; lsorc = iran(csa, 1, nsorc); chain(csa, lpick, lsorc); } L170: /* Set all demands equal to zero. */ for (i = nfsink; i <= nodes; i++) ipred[i] = 0; /* The following loop takes one chain at a time (through the use of logic contained in the loop and calls to other routines) and creates the remaining network arcs. */ for (lsorc = 1; lsorc <= nsorc; lsorc++) { chnarc(csa, lsorc); for (i = nfsink; i <= nodes; i++) iflag[i] = 0; /* Choose the number of sinks to be hooked up to the current chain. */ if (ntrans != 0) nsksr = (nsort * 2 * nsink) / ntrans; else nsksr = nsink / nsorc + 1; if (nsksr < 2) nsksr = 2; if (nsksr > nsink) nsksr = nsink; nsrchn = nsort; /* Randomly pick nsksr sinks and put their names in lsinks. */ ktl = nsink; for (j = 1; j <= nsksr; j++) { item = iran(csa, 1, ktl); ktl--; for (l = nfsink; l <= nodes; l++) { if (iflag[l] != 1) { item--; if (item == 0) goto L230; } } break; L230: lsinks[j] = l; iflag[l] = 1; } /* If last source chain, add all sinks with zero demand to lsinks list. */ if (lsorc == nsorc) { for (j = nfsink; j <= nodes; j++) { if (ipred[j] == 0 && iflag[j] != 1) { nsksr++; lsinks[nsksr] = j; iflag[j] = 1; } } } /* Create demands for group of sinks in lsinks. */ ks = isup[lsorc] / nsksr; k = ipred[lsorc]; for (i = 1; i <= nsksr; i++) { nsort++; ksp = iran(csa, 1, ks); j = iran(csa, 1, nsksr); itail[nsort] = k; li = lsinks[i]; ihead[nsort] = li; ipred[li] += ksp; li = lsinks[j]; ipred[li] += ks - ksp; n = iran(csa, 1, nsrchn); k = lsorc; for (ii = 1; ii <= n; ii++) k = ipred[k]; } li = lsinks[1]; ipred[li] += isup[lsorc] - ks * nsksr; nskel += nsort; /* Sort the arcs in the chain from source lsorc using itail as sort key. */ sort(csa); /* Print this part of skeleton and create the arcs for these nodes. */ i = 1; itail[nsort+1] = 0; L300: for (j = nftsor; j <= nodes; j++) iflag[j] = 0; ktl = nonsor - 1; it = itail[i]; iflag[it] = 1; L320: ih = ihead[i]; iflag[ih] = 1; narcs++; ktl--; /* Determine if this skeleton arc should be capacitated. */ icap = itsup; jcap = iran(csa, 1, 100); if (jcap <= ipcap) { icap = isup[lsorc]; if (mincap > icap) icap = mincap; } /* Determine if this skeleton arc should have the maximum cost. */ icost = maxcst; jcost = iran(csa, 1, 100); if (jcost > iphic) icost = iran(csa, mincst, maxcst); if (G == NULL) xprintf("%6s%6d%6d%2s%10d%10d\n", "", it, ih, "", icost, icap); else { glp_arc *a = glp_add_arc(G, it, ih); if (a_cap >= 0) { double temp = (double)icap; memcpy((char *)a->data + a_cap, &temp, sizeof(double)); } if (a_cost >= 0) { double temp = (double)icost; memcpy((char *)a->data + a_cost, &temp, sizeof(double)); } } i++; if (itail[i] == it) goto L320; pickj(csa, it); if (i <= nsort) goto L300; } /* Create arcs from the transshipment sinks. */ if (ntsink != 0) { for (i = nfsink; i <= ltsink; i++) { for (j = nftsor; j <= nodes; j++) iflag[j] = 0; ktl = nonsor - 1; iflag[i] = 1; pickj(csa, i); } } L390: /* Print the demand records and end record. */ if (G == NULL) { xprintf("DEMAND\n"); for (i = nfsink; i <= nodes; i++) xprintf("%6s%6d%18s%10d\n", "", i, "", ipred[i]); xprintf("END\n"); } else { if (v_rhs >= 0) { for (i = nfsink; i <= nodes; i++) { double temp = - (double)ipred[i]; glp_vertex *v = G->v[i]; memcpy((char *)v->data + v_rhs, &temp, sizeof(double)); } } } /* Free working arrays. */ xfree(ipred); xfree(ihead); xfree(itail); xfree(iflag); xfree(isup); xfree(lsinks); /* The instance has been successfully generated. */ ret = 0; done: return ret; } /*********************************************************************** * The routine cresup randomly distributes the total supply among the * source nodes. */ static void cresup(struct csa *csa) { int i, j, ks, ksp; xassert(itsup > nsorc); ks = itsup / nsorc; for (i = 1; i <= nsorc; i++) isup[i] = 0; for (i = 1; i <= nsorc; i++) { ksp = iran(csa, 1, ks); j = iran(csa, 1, nsorc); isup[i] += ksp; isup[j] += ks - ksp; } j = iran(csa, 1, nsorc); isup[j] += itsup - ks * nsorc; return; } /*********************************************************************** * The routine chain adds node lpick to the end of the chain with source * node lsorc. */ static void chain(struct csa *csa, int lpick, int lsorc) { int i, j, k, l, m; k = 0; m = ist; for (i = 1; i <= lpick; i++) { l = k; k = m; m = ipred[k]; } ipred[l] = m; j = ipred[lsorc]; ipred[k] = j; ipred[lsorc] = k; return; } /*********************************************************************** * The routine chnarc puts the arcs in the chain from source lsorc into * the ihead and itail arrays for sorting. */ static void chnarc(struct csa *csa, int lsorc) { int ito, ifrom; nsort = 0; ito = ipred[lsorc]; L10: if (ito == lsorc) return; nsort++; ifrom = ipred[ito]; ihead[nsort] = ito; itail[nsort] = ifrom; ito = ifrom; goto L10; } /*********************************************************************** * The routine sort sorts the nsort arcs in the ihead and itail arrays. * ihead is used as the sort key (i.e. forward star sort order). */ static void sort(struct csa *csa) { int i, j, k, l, m, n, it; n = nsort; m = n; L10: m /= 2; if (m == 0) return; k = n - m; j = 1; L20: i = j; L30: l = i + m; if (itail[i] <= itail[l]) goto L40; it = itail[i]; itail[i] = itail[l]; itail[l] = it; it = ihead[i]; ihead[i] = ihead[l]; ihead[l] = it; i -= m; if (i >= 1) goto L30; L40: j++; if (j <= k) goto L20; goto L10; } /*********************************************************************** * The routine pickj creates a random number of arcs out of node 'it'. * Various parameters are dynamically adjusted in an attempt to ensure * that the generated network has the correct number of arcs. */ static void pickj(struct csa *csa, int it) { int j, k, l, nn, nupbnd, icap, jcap, icost; if ((nodlft - 1) * 2 > iarcs - narcs - 1) { nodlft--; return; } if ((iarcs - narcs + nonsor - ktl - 1) / nodlft - nonsor + 1 >= 0) k = nonsor; else { nupbnd = (iarcs - narcs - nodlft) / nodlft * 2; L40: k = iran(csa, 1, nupbnd); if (nodlft == 1) k = iarcs - narcs; if ((nodlft - 1) * (nonsor - 1) < iarcs - narcs - k) goto L40; } nodlft--; for (j = 1; j <= k; j++) { nn = iran(csa, 1, ktl); ktl--; for (l = nftsor; l <= nodes; l++) { if (iflag[l] != 1) { nn--; if (nn == 0) goto L70; } } return; L70: iflag[l] = 1; icap = itsup; jcap = iran(csa, 1, 100); if (jcap <= ipcap) icap = iran(csa, mincap, maxcap); icost = iran(csa, mincst, maxcst); if (G == NULL) xprintf("%6s%6d%6d%2s%10d%10d\n", "", it, l, "", icost, icap); else { glp_arc *a = glp_add_arc(G, it, l); if (a_cap >= 0) { double temp = (double)icap; memcpy((char *)a->data + a_cap, &temp, sizeof(double)); } if (a_cost >= 0) { double temp = (double)icost; memcpy((char *)a->data + a_cost, &temp, sizeof(double)); } } narcs++; } return; } /*********************************************************************** * The routine assign generate assignment problems. It defines the unit * supplies, builds a skeleton, then calls pickj to create the arcs. */ static void assign(struct csa *csa) { int i, it, nn, l, ll, icost; if (G == NULL) xprintf("SUPPLY\n"); for (i = 1; i <= nsorc; i++) { isup[i] = 1; iflag[i] = 0; if (G == NULL) xprintf("%6s%6d%18s%10d\n", "", i, "", isup[i]); else { if (v_rhs >= 0) { double temp = (double)isup[i]; glp_vertex *v = G->v[i]; memcpy((char *)v->data + v_rhs, &temp, sizeof(double)); } } } if (G == NULL) xprintf("ARCS\n"); for (i = nfsink; i <= nodes; i++) ipred[i] = 1; for (it = 1; it <= nsorc; it++) { for (i = nfsink; i <= nodes; i++) iflag[i] = 0; ktl = nsink - 1; nn = iran(csa, 1, nsink - it + 1); for (l = 1; l <= nsorc; l++) { if (iflag[l] != 1) { nn--; if (nn == 0) break; } } narcs++; ll = nsorc + l; icost = iran(csa, mincst, maxcst); if (G == NULL) xprintf("%6s%6d%6d%2s%10d%10d\n", "", it, ll, "", icost, isup[1]); else { glp_arc *a = glp_add_arc(G, it, ll); if (a_cap >= 0) { double temp = (double)isup[1]; memcpy((char *)a->data + a_cap, &temp, sizeof(double)); } if (a_cost >= 0) { double temp = (double)icost; memcpy((char *)a->data + a_cost, &temp, sizeof(double)); } } iflag[l] = 1; iflag[ll] = 1; pickj(csa, it); } return; } /*********************************************************************** * Portable congruential (uniform) random number generator: * * next_value = ((7**5) * previous_value) modulo ((2**31)-1) * * This generator consists of three routines: * * (1) setran - initializes constants and seed * (2) iran - generates an integer random number * (3) rran - generates a real random number * * The generator requires a machine with at least 32 bits of precision. * The seed (iseed) must be in the range [1,(2**31)-1]. */ static void setran(struct csa *csa, int iseed) { xassert(iseed >= 1); mult = 16807; modul = 2147483647; i15 = 1 << 15; i16 = 1 << 16; jran = iseed; return; } /*********************************************************************** * The routine iran generates an integer random number between ilow and * ihigh. If ilow > ihigh then iran returns ihigh. */ static int iran(struct csa *csa, int ilow, int ihigh) { int ixhi, ixlo, ixalo, leftlo, ixahi, ifulhi, irtlo, iover, irthi, j; ixhi = jran / i16; ixlo = jran - ixhi * i16; ixalo = ixlo * mult; leftlo = ixalo / i16; ixahi = ixhi * mult; ifulhi = ixahi + leftlo; irtlo = ixalo - leftlo * i16; iover = ifulhi / i15; irthi = ifulhi - iover * i15; jran = ((irtlo - modul) + irthi * i16) + iover; if (jran < 0) jran += modul; j = ihigh - ilow + 1; if (j > 0) return jran % j + ilow; else return ihigh; } /**********************************************************************/ #if 0 static int scan(char card[80+1], int pos, int len) { char buf[10+1]; memcpy(buf, &card[pos-1], len); buf[len] = '\0'; return atoi(buf); } int main(void) { int parm[1+15]; char card[80+1]; xassert(fgets(card, sizeof(card), stdin) == card); parm[1] = scan(card, 1, 8); parm[2] = scan(card, 9, 8); xassert(fgets(card, sizeof(card), stdin) == card); parm[3] = scan(card, 1, 5); parm[4] = scan(card, 6, 5); parm[5] = scan(card, 11, 5); parm[6] = scan(card, 16, 5); parm[7] = scan(card, 21, 5); parm[8] = scan(card, 26, 5); parm[9] = scan(card, 31, 10); parm[10] = scan(card, 41, 5); parm[11] = scan(card, 46, 5); parm[12] = scan(card, 51, 5); parm[13] = scan(card, 56, 5); parm[14] = scan(card, 61, 10); parm[15] = scan(card, 71, 10); glp_netgen(NULL, 0, 0, 0, parm); return 0; } #endif /* eof */ praat-6.0.04/external/glpk/glpnet04.c000066400000000000000000000621371261542461700173110ustar00rootroot00000000000000/* glpnet04.c (grid-like network problem generator) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * This code is a modified version of the program GRIDGEN, a grid-like * network problem generator developed by Yusin Lee and Jim Orlin. * The original code is publically available on the DIMACS ftp site at: * . * * All changes concern only the program interface, so this modified * version produces exactly the same instances as the original version. * * Changes were made by Andrew Makhorin . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpapi.h" /*********************************************************************** * NAME * * glp_gridgen - grid-like network problem generator * * SYNOPSIS * * int glp_gridgen(glp_graph *G, int v_rhs, int a_cap, int a_cost, * const int parm[1+14]); * * DESCRIPTION * * The routine glp_gridgen is a grid-like network problem generator * developed by Yusin Lee and Jim Orlin. * * The parameter G specifies the graph object, to which the generated * problem data have to be stored. Note that on entry the graph object * is erased with the routine glp_erase_graph. * * The parameter v_rhs specifies an offset of the field of type double * in the vertex data block, to which the routine stores the supply or * demand value. If v_rhs < 0, the value is not stored. * * The parameter a_cap specifies an offset of the field of type double * in the arc data block, to which the routine stores the arc capacity. * If a_cap < 0, the capacity is not stored. * * The parameter a_cost specifies an offset of the field of type double * in the arc data block, to which the routine stores the per-unit cost * if the arc flow. If a_cost < 0, the cost is not stored. * * The array parm contains description of the network to be generated: * * parm[0] not used * parm[1] two-ways arcs indicator: * 1 - if links in both direction should be generated * 0 - otherwise * parm[2] random number seed (a positive integer) * parm[3] number of nodes (the number of nodes generated might be * slightly different to make the network a grid) * parm[4] grid width * parm[5] number of sources * parm[6] number of sinks * parm[7] average degree * parm[8] total flow * parm[9] distribution of arc costs: * 1 - uniform * 2 - exponential * parm[10] lower bound for arc cost (uniform) * 100 * lambda (exponential) * parm[11] upper bound for arc cost (uniform) * not used (exponential) * parm[12] distribution of arc capacities: * 1 - uniform * 2 - exponential * parm[13] lower bound for arc capacity (uniform) * 100 * lambda (exponential) * parm[14] upper bound for arc capacity (uniform) * not used (exponential) * * RETURNS * * If the instance was successfully generated, the routine glp_gridgen * returns zero; otherwise, if specified parameters are inconsistent, * the routine returns a non-zero error code. * * COMMENTS * * This network generator generates a grid-like network plus a super * node. In additional to the arcs connecting the nodes in the grid, * there is an arc from each supply node to the super node and from the * super node to each demand node to guarantee feasiblity. These arcs * have very high costs and very big capacities. * * The idea of this network generator is as follows: First, a grid of * n1 * n2 is generated. For example, 5 * 3. The nodes are numbered as * 1 to 15, and the supernode is numbered as n1*n2+1. Then arcs between * adjacent nodes are generated. For these arcs, the user is allowed to * specify either to generate two-way arcs or one-way arcs. If two-way * arcs are to be generated, two arcs, one in each direction, will be * generated between each adjacent node pairs. Otherwise, only one arc * will be generated. If this is the case, the arcs will be generated * in alterntive directions as shown below. * * 1 ---> 2 ---> 3 ---> 4 ---> 5 * | ^ | ^ | * | | | | | * V | V | V * 6 <--- 7 <--- 8 <--- 9 <--- 10 * | ^ | ^ | * | | | | | * V | V | V * 11 --->12 --->13 --->14 ---> 15 * * Then the arcs between the super node and the source/sink nodes are * added as mentioned before. If the number of arcs still doesn't reach * the requirement, additional arcs will be added by uniformly picking * random node pairs. There is no checking to prevent multiple arcs * between any pair of nodes. However, there will be no self-arcs (arcs * that poins back to its tail node) in the network. * * The source and sink nodes are selected uniformly in the network, and * the imbalances of each source/sink node are also assigned by uniform * distribution. */ struct stat_para { /* structure for statistical distributions */ int distribution; /* the distribution: */ #define UNIFORM 1 /* uniform distribution */ #define EXPONENTIAL 2 /* exponential distribution */ double parameter[5]; /* the parameters of the distribution */ }; struct arcs { int from; /* the FROM node of that arc */ int to; /* the TO node of that arc */ int cost; /* original cost of that arc */ int u; /* capacity of the arc */ }; struct imbalance { int node; /* Node ID */ int supply; /* Supply of that node */ }; struct csa { /* common storage area */ glp_graph *G; int v_rhs, a_cap, a_cost; int seed; /* random number seed */ int seed_original; /* the original seed from input */ int two_way; /* 0: generate arcs in both direction for the basic grid, except for the arcs to/from the super node. 1: o/w */ int n_node; /* total number of nodes in the network, numbered 1 to n_node, including the super node, which is the last one */ int n_arc; /* total number of arcs in the network, counting EVERY arc. */ int n_grid_arc; /* number of arcs in the basic grid, including the arcs to/from the super node */ int n_source, n_sink; /* number of source and sink nodes */ int avg_degree; /* average degree, arcs to and from the super node are counted */ int t_supply; /* total supply in the network */ int n1, n2; /* the two edges of the network grid. n1 >= n2 */ struct imbalance *source_list, *sink_list; /* head of the array of source/sink nodes */ struct stat_para arc_costs; /* the distribution of arc costs */ struct stat_para capacities; /* distribution of the capacities of the arcs */ struct arcs *arc_list; /* head of the arc list array. Arcs in this array are in the order of grid_arcs, arcs to/from super node, and other arcs */ }; #define G (csa->G) #define v_rhs (csa->v_rhs) #define a_cap (csa->a_cap) #define a_cost (csa->a_cost) #define seed (csa->seed) #define seed_original (csa->seed_original) #define two_way (csa->two_way) #define n_node (csa->n_node) #define n_arc (csa->n_arc) #define n_grid_arc (csa->n_grid_arc) #define n_source (csa->n_source) #define n_sink (csa->n_sink) #define avg_degree (csa->avg_degree) #define t_supply (csa->t_supply) #define n1 (csa->n1) #define n2 (csa->n2) #define source_list (csa->source_list) #define sink_list (csa->sink_list) #define arc_costs (csa->arc_costs) #define capacities (csa->capacities) #define arc_list (csa->arc_list) static void assign_capacities(struct csa *csa); static void assign_costs(struct csa *csa); static void assign_imbalance(struct csa *csa); static int exponential(struct csa *csa, double lambda[1]); static struct arcs *gen_additional_arcs(struct csa *csa, struct arcs *arc_ptr); static struct arcs *gen_basic_grid(struct csa *csa, struct arcs *arc_ptr); static void gen_more_arcs(struct csa *csa, struct arcs *arc_ptr); static void generate(struct csa *csa); static void output(struct csa *csa); static double randy(struct csa *csa); static void select_source_sinks(struct csa *csa); static int uniform(struct csa *csa, double a[2]); int glp_gridgen(glp_graph *G_, int _v_rhs, int _a_cap, int _a_cost, const int parm[1+14]) { struct csa _csa, *csa = &_csa; int n, ret; G = G_; v_rhs = _v_rhs; a_cap = _a_cap; a_cost = _a_cost; if (G != NULL) { if (v_rhs >= 0 && v_rhs > G->v_size - (int)sizeof(double)) xerror("glp_gridgen: v_rhs = %d; invalid offset\n", v_rhs); if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) xerror("glp_gridgen: a_cap = %d; invalid offset\n", a_cap); if (a_cost >= 0 && a_cost > G->a_size - (int)sizeof(double)) xerror("glp_gridgen: a_cost = %d; invalid offset\n", a_cost) ; } /* Check the parameters for consistency. */ if (!(parm[1] == 0 || parm[1] == 1)) { ret = 1; goto done; } if (parm[2] < 1) { ret = 2; goto done; } if (!(10 <= parm[3] && parm[3] <= 40000)) { ret = 3; goto done; } if (!(1 <= parm[4] && parm[4] <= 40000)) { ret = 4; goto done; } if (!(parm[5] >= 0 && parm[6] >= 0 && parm[5] + parm[6] <= parm[3])) { ret = 5; goto done; } if (!(1 <= parm[7] && parm[7] <= parm[3])) { ret = 6; goto done; } if (parm[8] < 0) { ret = 7; goto done; } if (!(parm[9] == 1 || parm[9] == 2)) { ret = 8; goto done; } if (parm[9] == 1 && parm[10] > parm[11] || parm[9] == 2 && parm[10] < 1) { ret = 9; goto done; } if (!(parm[12] == 1 || parm[12] == 2)) { ret = 10; goto done; } if (parm[12] == 1 && !(0 <= parm[13] && parm[13] <= parm[14]) || parm[12] == 2 && parm[13] < 1) { ret = 11; goto done; } /* Initialize the graph object. */ if (G != NULL) { glp_erase_graph(G, G->v_size, G->a_size); glp_set_graph_name(G, "GRIDGEN"); } /* Copy the generator parameters. */ two_way = parm[1]; seed_original = seed = parm[2]; n_node = parm[3]; n = parm[4]; n_source = parm[5]; n_sink = parm[6]; avg_degree = parm[7]; t_supply = parm[8]; arc_costs.distribution = parm[9]; if (parm[9] == 1) { arc_costs.parameter[0] = parm[10]; arc_costs.parameter[1] = parm[11]; } else { arc_costs.parameter[0] = (double)parm[10] / 100.0; arc_costs.parameter[1] = 0.0; } capacities.distribution = parm[12]; if (parm[12] == 1) { capacities.parameter[0] = parm[13]; capacities.parameter[1] = parm[14]; } else { capacities.parameter[0] = (double)parm[13] / 100.0; capacities.parameter[1] = 0.0; } /* Calculate the edge lengths of the grid according to the input. */ if (n * n >= n_node) { n1 = n; n2 = (int)((double)n_node / (double)n + 0.5); } else { n2 = n; n1 = (int)((double)n_node / (double)n + 0.5); } /* Recalculate the total number of nodes and plus 1 for the super node. */ n_node = n1 * n2 + 1; n_arc = n_node * avg_degree; n_grid_arc = (two_way + 1) * ((n1 - 1) * n2 + (n2 - 1) * n1) + n_source + n_sink; if (n_grid_arc > n_arc) n_arc = n_grid_arc; arc_list = xcalloc(n_arc, sizeof(struct arcs)); source_list = xcalloc(n_source, sizeof(struct imbalance)); sink_list = xcalloc(n_sink, sizeof(struct imbalance)); /* Generate a random network. */ generate(csa); /* Output the network. */ output(csa); /* Free all allocated memory. */ xfree(arc_list); xfree(source_list); xfree(sink_list); /* The instance has been successfully generated. */ ret = 0; done: return ret; } #undef random static void assign_capacities(struct csa *csa) { /* Assign a capacity to each arc. */ struct arcs *arc_ptr = arc_list; int (*random)(struct csa *csa, double *); int i; /* Determine the random number generator to use. */ switch (arc_costs.distribution) { case UNIFORM: random = uniform; break; case EXPONENTIAL: random = exponential; break; default: xassert(csa != csa); } /* Assign capacities to grid arcs. */ for (i = n_source + n_sink; i < n_grid_arc; i++, arc_ptr++) arc_ptr->u = random(csa, capacities.parameter); i = i - n_source - n_sink; /* Assign capacities to arcs to/from supernode. */ for (; i < n_grid_arc; i++, arc_ptr++) arc_ptr->u = t_supply; /* Assign capacities to all other arcs. */ for (; i < n_arc; i++, arc_ptr++) arc_ptr->u = random(csa, capacities.parameter); return; } static void assign_costs(struct csa *csa) { /* Assign a cost to each arc. */ struct arcs *arc_ptr = arc_list; int (*random)(struct csa *csa, double *); int i; /* A high cost assigned to arcs to/from the supernode. */ int high_cost; /* The maximum cost assigned to arcs in the base grid. */ int max_cost = 0; /* Determine the random number generator to use. */ switch (arc_costs.distribution) { case UNIFORM: random = uniform; break; case EXPONENTIAL: random = exponential; break; default: xassert(csa != csa); } /* Assign costs to arcs in the base grid. */ for (i = n_source + n_sink; i < n_grid_arc; i++, arc_ptr++) { arc_ptr->cost = random(csa, arc_costs.parameter); if (max_cost < arc_ptr->cost) max_cost = arc_ptr->cost; } i = i - n_source - n_sink; /* Assign costs to arcs to/from the super node. */ high_cost = max_cost * 2; for (; i < n_grid_arc; i++, arc_ptr++) arc_ptr->cost = high_cost; /* Assign costs to all other arcs. */ for (; i < n_arc; i++, arc_ptr++) arc_ptr->cost = random(csa, arc_costs.parameter); return; } static void assign_imbalance(struct csa *csa) { /* Assign an imbalance to each node. */ int total, i; double avg; struct imbalance *ptr; /* assign the supply nodes */ avg = 2.0 * t_supply / n_source; do { for (i = 1, total = t_supply, ptr = source_list + 1; i < n_source; i++, ptr++) { ptr->supply = (int)(randy(csa) * avg + 0.5); total -= ptr->supply; } source_list->supply = total; } /* redo all if the assignment "overshooted" */ while (total <= 0); /* assign the demand nodes */ avg = -2.0 * t_supply / n_sink; do { for (i = 1, total = t_supply, ptr = sink_list + 1; i < n_sink; i++, ptr++) { ptr->supply = (int)(randy(csa) * avg - 0.5); total += ptr->supply; } sink_list->supply = - total; } while (total <= 0); return; } static int exponential(struct csa *csa, double lambda[1]) { /* Returns an "exponentially distributed" integer with parameter lambda. */ return ((int)(- lambda[0] * log((double)randy(csa)) + 0.5)); } static struct arcs *gen_additional_arcs(struct csa *csa, struct arcs *arc_ptr) { /* Generate an arc from each source to the supernode and from supernode to each sink. */ int i; for (i = 0; i < n_source; i++, arc_ptr++) { arc_ptr->from = source_list[i].node; arc_ptr->to = n_node; } for (i = 0; i < n_sink; i++, arc_ptr++) { arc_ptr->to = sink_list[i].node; arc_ptr->from = n_node; } return arc_ptr; } static struct arcs *gen_basic_grid(struct csa *csa, struct arcs *arc_ptr) { /* Generate the basic grid. */ int direction = 1, i, j, k; if (two_way) { /* Generate an arc in each direction. */ for (i = 1; i < n_node; i += n1) { for (j = i, k = j + n1 - 1; j < k; j++) { arc_ptr->from = j; arc_ptr->to = j + 1; arc_ptr++; arc_ptr->from = j + 1; arc_ptr->to = j; arc_ptr++; } } for (i = 1; i <= n1; i++) { for (j = i + n1; j < n_node; j += n1) { arc_ptr->from = j; arc_ptr->to = j - n1; arc_ptr++; arc_ptr->from = j - n1; arc_ptr->to = j; arc_ptr++; } } } else { /* Generate one arc in each direction. */ for (i = 1; i < n_node; i += n1) { if (direction == 1) j = i; else j = i + 1; for (k = j + n1 - 1; j < k; j++) { arc_ptr->from = j; arc_ptr->to = j + direction; arc_ptr++; } direction = - direction; } for (i = 1; i <= n1; i++) { j = i + n1; if (direction == 1) { for (; j < n_node; j += n1) { arc_ptr->from = j - n1; arc_ptr->to = j; arc_ptr++; } } else { for (; j < n_node; j += n1) { arc_ptr->from = j - n1; arc_ptr->to = j; arc_ptr++; } } direction = - direction; } } return arc_ptr; } static void gen_more_arcs(struct csa *csa, struct arcs *arc_ptr) { /* Generate random arcs to meet the specified density. */ int i; double ab[2]; ab[0] = 0.9; ab[1] = n_node - 0.99; /* upper limit is n_node-1 because the supernode cannot be selected */ for (i = n_grid_arc; i < n_arc; i++, arc_ptr++) { arc_ptr->from = uniform(csa, ab); arc_ptr->to = uniform(csa, ab); if (arc_ptr->from == arc_ptr->to) { arc_ptr--; i--; } } return; } static void generate(struct csa *csa) { /* Generate a random network. */ struct arcs *arc_ptr = arc_list; arc_ptr = gen_basic_grid(csa, arc_ptr); select_source_sinks(csa); arc_ptr = gen_additional_arcs(csa, arc_ptr); gen_more_arcs(csa, arc_ptr); assign_costs(csa); assign_capacities(csa); assign_imbalance(csa); return; } static void output(struct csa *csa) { /* Output the network in DIMACS format. */ struct arcs *arc_ptr; struct imbalance *imb_ptr; int i; if (G != NULL) goto skip; /* Output "c", "p" records. */ xprintf("c generated by GRIDGEN\n"); xprintf("c seed %d\n", seed_original); xprintf("c nodes %d\n", n_node); xprintf("c grid size %d X %d\n", n1, n2); xprintf("c sources %d sinks %d\n", n_source, n_sink); xprintf("c avg. degree %d\n", avg_degree); xprintf("c supply %d\n", t_supply); switch (arc_costs.distribution) { case UNIFORM: xprintf("c arc costs: UNIFORM distr. min %d max %d\n", (int)arc_costs.parameter[0], (int)arc_costs.parameter[1]); break; case EXPONENTIAL: xprintf("c arc costs: EXPONENTIAL distr. lambda %d\n", (int)arc_costs.parameter[0]); break; default: xassert(csa != csa); } switch (capacities.distribution) { case UNIFORM: xprintf("c arc caps : UNIFORM distr. min %d max %d\n", (int)capacities.parameter[0], (int)capacities.parameter[1]); break; case EXPONENTIAL: xprintf("c arc caps : EXPONENTIAL distr. %d lambda %d\n", (int)capacities.parameter[0]); break; default: xassert(csa != csa); } skip: if (G == NULL) xprintf("p min %d %d\n", n_node, n_arc); else { glp_add_vertices(G, n_node); if (v_rhs >= 0) { double zero = 0.0; for (i = 1; i <= n_node; i++) { glp_vertex *v = G->v[i]; memcpy((char *)v->data + v_rhs, &zero, sizeof(double)); } } } /* Output "n node supply". */ for (i = 0, imb_ptr = source_list; i < n_source; i++, imb_ptr++) { if (G == NULL) xprintf("n %d %d\n", imb_ptr->node, imb_ptr->supply); else { if (v_rhs >= 0) { double temp = (double)imb_ptr->supply; glp_vertex *v = G->v[imb_ptr->node]; memcpy((char *)v->data + v_rhs, &temp, sizeof(double)); } } } for (i = 0, imb_ptr = sink_list; i < n_sink; i++, imb_ptr++) { if (G == NULL) xprintf("n %d %d\n", imb_ptr->node, imb_ptr->supply); else { if (v_rhs >= 0) { double temp = (double)imb_ptr->supply; glp_vertex *v = G->v[imb_ptr->node]; memcpy((char *)v->data + v_rhs, &temp, sizeof(double)); } } } /* Output "a from to lowcap=0 hicap cost". */ for (i = 0, arc_ptr = arc_list; i < n_arc; i++, arc_ptr++) { if (G == NULL) xprintf("a %d %d 0 %d %d\n", arc_ptr->from, arc_ptr->to, arc_ptr->u, arc_ptr->cost); else { glp_arc *a = glp_add_arc(G, arc_ptr->from, arc_ptr->to); if (a_cap >= 0) { double temp = (double)arc_ptr->u; memcpy((char *)a->data + a_cap, &temp, sizeof(double)); } if (a_cost >= 0) { double temp = (double)arc_ptr->cost; memcpy((char *)a->data + a_cost, &temp, sizeof(double)); } } } return; } static double randy(struct csa *csa) { /* Returns a random number between 0.0 and 1.0. See Ward Cheney & David Kincaid, "Numerical Mathematics and Computing," 2Ed, pp. 335. */ seed = 16807 * seed % 2147483647; if (seed < 0) seed = - seed; return seed * 4.6566128752459e-10; } static void select_source_sinks(struct csa *csa) { /* Randomly select the source nodes and sink nodes. */ int i, *int_ptr; int *temp_list; /* a temporary list of nodes */ struct imbalance *ptr; double ab[2]; /* parameter for random number generator */ ab[0] = 0.9; ab[1] = n_node - 0.99; /* upper limit is n_node-1 because the supernode cannot be selected */ temp_list = xcalloc(n_node, sizeof(int)); for (i = 0, int_ptr = temp_list; i < n_node; i++, int_ptr++) *int_ptr = 0; /* Select the source nodes. */ for (i = 0, ptr = source_list; i < n_source; i++, ptr++) { ptr->node = uniform(csa, ab); if (temp_list[ptr->node] == 1) /* check for duplicates */ { ptr--; i--; } else temp_list[ptr->node] = 1; } /* Select the sink nodes. */ for (i = 0, ptr = sink_list; i < n_sink; i++, ptr++) { ptr->node = uniform(csa, ab); if (temp_list[ptr->node] == 1) { ptr--; i--; } else temp_list[ptr->node] = 1; } xfree(temp_list); return; } int uniform(struct csa *csa, double a[2]) { /* Generates an integer uniformly selected from [a[0],a[1]]. */ return (int)((a[1] - a[0]) * randy(csa) + a[0] + 0.5); } /**********************************************************************/ #if 0 int main(void) { int parm[1+14]; double temp; scanf("%d", &parm[1]); scanf("%d", &parm[2]); scanf("%d", &parm[3]); scanf("%d", &parm[4]); scanf("%d", &parm[5]); scanf("%d", &parm[6]); scanf("%d", &parm[7]); scanf("%d", &parm[8]); scanf("%d", &parm[9]); if (parm[9] == 1) { scanf("%d", &parm[10]); scanf("%d", &parm[11]); } else { scanf("%le", &temp); parm[10] = (int)(100.0 * temp + .5); parm[11] = 0; } scanf("%d", &parm[12]); if (parm[12] == 1) { scanf("%d", &parm[13]); scanf("%d", &parm[14]); } else { scanf("%le", &temp); parm[13] = (int)(100.0 * temp + .5); parm[14] = 0; } glp_gridgen(NULL, 0, 0, 0, parm); return 0; } #endif /* eof */ praat-6.0.04/external/glpk/glpnet05.c000066400000000000000000000260051261542461700173040ustar00rootroot00000000000000/* glpnet05.c (Goldfarb's maximum flow problem generator) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * This code is a modified version of the program RMFGEN, a maxflow * problem generator developed by D.Goldfarb and M.Grigoriadis, and * originally implemented by Tamas Badics . * The original code is publically available on the DIMACS ftp site at: * . * * All changes concern only the program interface, so this modified * version produces exactly the same instances as the original version. * * Changes were made by Andrew Makhorin . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpapi.h" #include "glprng.h" /*********************************************************************** * NAME * * glp_rmfgen - Goldfarb's maximum flow problem generator * * SYNOPSIS * * int glp_rmfgen(glp_graph *G, int *s, int *t, int a_cap, * const int parm[1+5]); * * DESCRIPTION * * The routine glp_rmfgen is a maximum flow problem generator developed * by D.Goldfarb and M.Grigoriadis. * * The parameter G specifies the graph object, to which the generated * problem data have to be stored. Note that on entry the graph object * is erased with the routine glp_erase_graph. * * The pointer s specifies a location, to which the routine stores the * source node number. If s is NULL, the node number is not stored. * * The pointer t specifies a location, to which the routine stores the * sink node number. If t is NULL, the node number is not stored. * * The parameter a_cap specifies an offset of the field of type double * in the arc data block, to which the routine stores the arc capacity. * If a_cap < 0, the capacity is not stored. * * The array parm contains description of the network to be generated: * * parm[0] not used * parm[1] (seed) random number seed (a positive integer) * parm[2] (a) frame size * parm[3] (b) depth * parm[4] (c1) minimal arc capacity * parm[5] (c2) maximal arc capacity * * RETURNS * * If the instance was successfully generated, the routine glp_netgen * returns zero; otherwise, if specified parameters are inconsistent, * the routine returns a non-zero error code. * * COMMENTS * * The generated network is as follows. It has b pieces of frames of * size a * a. (So alltogether the number of vertices is a * a * b) * * In each frame all the vertices are connected with their neighbours * (forth and back). In addition the vertices of a frame are connected * one to one with the vertices of next frame using a random permutation * of those vertices. * * The source is the lower left vertex of the first frame, the sink is * the upper right vertex of the b'th frame. * * t * +-------+ * | .| * | . | * / | / | * +-------+/ -+ b * | | |/. * a | -v- |/ * | | |/ * +-------+ 1 * s a * * The capacities are randomly chosen integers from the range of [c1,c2] * in the case of interconnecting edges, and c2 * a * a for the in-frame * edges. * * REFERENCES * * D.Goldfarb and M.D.Grigoriadis, "A computational comparison of the * Dinic and network simplex methods for maximum flow." Annals of Op. * Res. 13 (1988), pp. 83-123. * * U.Derigs and W.Meier, "Implementing Goldberg's max-flow algorithm: * A computational investigation." Zeitschrift fuer Operations Research * 33 (1989), pp. 383-403. */ typedef struct VERTEX { struct EDGE **edgelist; /* Pointer to the list of pointers to the adjacent edges. (No matter that to or from edges) */ struct EDGE **current; /* Pointer to the current edge */ int degree; /* Number of adjacent edges (both direction) */ int index; } vertex; typedef struct EDGE { int from; int to; int cap; /* Capacity */ } edge; typedef struct NETWORK { struct NETWORK *next, *prev; int vertnum; int edgenum; vertex *verts; /* Vertex array[1..vertnum] */ edge *edges; /* Edge array[1..edgenum] */ int source; /* Pointer to the source */ int sink; /* Pointer to the sink */ } network; struct csa { /* common storage area */ glp_graph *G; int *s, *t, a_cap; RNG *rand; network *N; int *Parr; int A, AA, C2AA, Ec; }; #define G (csa->G) #define s (csa->s) #define t (csa->t) #define a_cap (csa->a_cap) #define N (csa->N) #define Parr (csa->Parr) #define A (csa->A) #define AA (csa->AA) #define C2AA (csa->C2AA) #define Ec (csa->Ec) #undef random #define random(A) (int)(rng_unif_01(csa->rand) * (double)(A)) #define RANDOM(A, B) (int)(random((B) - (A) + 1) + (A)) #define sgn(A) (((A) > 0) ? 1 : ((A) == 0) ? 0 : -1) static void make_edge(struct csa *csa, int from, int to, int c1, int c2) { Ec++; N->edges[Ec].from = from; N->edges[Ec].to = to; N->edges[Ec].cap = RANDOM(c1, c2); return; } static void permute(struct csa *csa) { int i, j, tmp; for (i = 1; i < AA; i++) { j = RANDOM(i, AA); tmp = Parr[i]; Parr[i] = Parr[j]; Parr[j] = tmp; } return; } static void connect(struct csa *csa, int offset, int cv, int x1, int y1) { int cv1; cv1 = offset + (x1 - 1) * A + y1; Ec++; N->edges[Ec].from = cv; N->edges[Ec].to = cv1; N->edges[Ec].cap = C2AA; return; } static network *gen_rmf(struct csa *csa, int a, int b, int c1, int c2) { /* generates a network with a*a*b nodes and 6a*a*b-4ab-2a*a edges random_frame network: Derigs & Meier, Methods & Models of OR (1989), 33:383-403 */ int x, y, z, offset, cv; A = a; AA = a * a; C2AA = c2 * AA; Ec = 0; N = (network *)xmalloc(sizeof(network)); N->vertnum = AA * b; N->edgenum = 5 * AA * b - 4 * A * b - AA; N->edges = (edge *)xcalloc(N->edgenum + 1, sizeof(edge)); N->source = 1; N->sink = N->vertnum; Parr = (int *)xcalloc(AA + 1, sizeof(int)); for (x = 1; x <= AA; x++) Parr[x] = x; for (z = 1; z <= b; z++) { offset = AA * (z - 1); if (z != b) permute(csa); for (x = 1; x <= A; x++) { for (y = 1; y <= A; y++) { cv = offset + (x - 1) * A + y; if (z != b) make_edge(csa, cv, offset + AA + Parr[cv - offset], c1, c2); /* the intermediate edges */ if (y < A) connect(csa, offset, cv, x, y + 1); if (y > 1) connect(csa, offset, cv, x, y - 1); if (x < A) connect(csa, offset, cv, x + 1, y); if (x > 1) connect(csa, offset, cv, x - 1, y); } } } xfree(Parr); return N; } static void print_max_format(struct csa *csa, network *n, char *comm[], int dim) { /* prints a network heading with dim lines of comments (no \n needs at the ends) */ int i, vnum, e_num; edge *e; vnum = n->vertnum; e_num = n->edgenum; if (G == NULL) { for (i = 0; i < dim; i++) xprintf("c %s\n", comm[i]); xprintf("p max %7d %10d\n", vnum, e_num); xprintf("n %7d s\n", n->source); xprintf("n %7d t\n", n->sink); } else { glp_add_vertices(G, vnum); if (s != NULL) *s = n->source; if (t != NULL) *t = n->sink; } for (i = 1; i <= e_num; i++) { e = &n->edges[i]; if (G == NULL) xprintf("a %7d %7d %10d\n", e->from, e->to, (int)e->cap); else { glp_arc *a = glp_add_arc(G, e->from, e->to); if (a_cap >= 0) { double temp = (double)e->cap; memcpy((char *)a->data + a_cap, &temp, sizeof(double)); } } } return; } static void gen_free_net(network *n) { xfree(n->edges); xfree(n); return; } int glp_rmfgen(glp_graph *G_, int *_s, int *_t, int _a_cap, const int parm[1+5]) { struct csa _csa, *csa = &_csa; network *n; char comm[10][80], *com1[10]; int seed, a, b, c1, c2, ret; G = G_; s = _s; t = _t; a_cap = _a_cap; if (G != NULL) { if (a_cap >= 0 && a_cap > G->a_size - (int)sizeof(double)) xerror("glp_rmfgen: a_cap = %d; invalid offset\n", a_cap); } seed = parm[1]; a = parm[2]; b = parm[3]; c1 = parm[4]; c2 = parm[5]; if (!(seed > 0 && 1 <= a && a <= 1000 && 1 <= b && b <= 1000 && 0 <= c1 && c1 <= c2 && c2 <= 1000)) { ret = 1; goto done; } if (G != NULL) { glp_erase_graph(G, G->v_size, G->a_size); glp_set_graph_name(G, "RMFGEN"); } csa->rand = rng_create_rand(); rng_init_rand(csa->rand, seed); n = gen_rmf(csa, a, b, c1, c2); sprintf(comm[0], "This file was generated by genrmf."); sprintf(comm[1], "The parameters are: a: %d b: %d c1: %d c2: %d", a, b, c1, c2); com1[0] = comm[0]; com1[1] = comm[1]; print_max_format(csa, n, com1, 2); gen_free_net(n); rng_delete_rand(csa->rand); ret = 0; done: return ret; } /**********************************************************************/ #if 0 int main(int argc, char *argv[]) { int seed, a, b, c1, c2, i, parm[1+5]; seed = 123; a = b = c1 = c2 = -1; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-seed") == 0) seed = atoi(argv[++i]); else if (strcmp(argv[i], "-a") == 0) a = atoi(argv[++i]); else if (strcmp(argv[i], "-b") == 0) b = atoi(argv[++i]); else if (strcmp(argv[i], "-c1") == 0) c1 = atoi(argv[++i]); else if (strcmp(argv[i], "-c2") == 0) c2 = atoi(argv[++i]); } if (a < 0 || b < 0 || c1 < 0 || c2 < 0) { xprintf("Usage:\n"); xprintf("genrmf [-seed seed] -a frame_size -b depth\n"); xprintf(" -c1 cap_range1 -c2 cap_range2\n"); } else { parm[1] = seed; parm[2] = a; parm[3] = b; parm[4] = c1; parm[5] = c2; glp_rmfgen(NULL, NULL, NULL, 0, parm); } return 0; } #endif /* eof */ praat-6.0.04/external/glpk/glpnet06.c000066400000000000000000000306061261542461700173070ustar00rootroot00000000000000/* glpnet06.c (out-of-kilter algorithm) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpenv.h" #include "glpnet.h" /*********************************************************************** * NAME * * okalg - out-of-kilter algorithm * * SYNOPSIS * * #include "glpnet.h" * int okalg(int nv, int na, const int tail[], const int head[], * const int low[], const int cap[], const int cost[], int x[], * int pi[]); * * DESCRIPTION * * The routine okalg implements the out-of-kilter algorithm to find a * minimal-cost circulation in the specified flow network. * * INPUT PARAMETERS * * nv is the number of nodes, nv >= 0. * * na is the number of arcs, na >= 0. * * tail[a], a = 1,...,na, is the index of tail node of arc a. * * head[a], a = 1,...,na, is the index of head node of arc a. * * low[a], a = 1,...,na, is an lower bound to the flow through arc a. * * cap[a], a = 1,...,na, is an upper bound to the flow through arc a, * which is the capacity of the arc. * * cost[a], a = 1,...,na, is a per-unit cost of the flow through arc a. * * NOTES * * 1. Multiple arcs are allowed, but self-loops are not allowed. * * 2. It is required that 0 <= low[a] <= cap[a] for all arcs. * * 3. Arc costs may have any sign. * * OUTPUT PARAMETERS * * x[a], a = 1,...,na, is optimal value of the flow through arc a. * * pi[i], i = 1,...,nv, is Lagrange multiplier for flow conservation * equality constraint corresponding to node i (the node potential). * * RETURNS * * 0 optimal circulation found; * * 1 there is no feasible circulation; * * 2 integer overflow occured; * * 3 optimality test failed (logic error). * * REFERENCES * * L.R.Ford, Jr., and D.R.Fulkerson, "Flows in Networks," The RAND * Corp., Report R-375-PR (August 1962), Chap. III "Minimal Cost Flow * Problems," pp.113-26. */ static int overflow(int u, int v) { /* check for integer overflow on computing u + v */ if (u > 0 && v > 0 && u + v < 0) return 1; if (u < 0 && v < 0 && u + v > 0) return 1; return 0; } int okalg(int nv, int na, const int tail[], const int head[], const int low[], const int cap[], const int cost[], int x[], int pi[]) { int a, aok, delta, i, j, k, lambda, pos1, pos2, s, t, temp, ret, *ptr, *arc, *link, *list; /* sanity checks */ xassert(nv >= 0); xassert(na >= 0); for (a = 1; a <= na; a++) { i = tail[a], j = head[a]; xassert(1 <= i && i <= nv); xassert(1 <= j && j <= nv); xassert(i != j); xassert(0 <= low[a] && low[a] <= cap[a]); } /* allocate working arrays */ ptr = xcalloc(1+nv+1, sizeof(int)); arc = xcalloc(1+na+na, sizeof(int)); link = xcalloc(1+nv, sizeof(int)); list = xcalloc(1+nv, sizeof(int)); /* ptr[i] := (degree of node i) */ for (i = 1; i <= nv; i++) ptr[i] = 0; for (a = 1; a <= na; a++) { ptr[tail[a]]++; ptr[head[a]]++; } /* initialize arc pointers */ ptr[1]++; for (i = 1; i < nv; i++) ptr[i+1] += ptr[i]; ptr[nv+1] = ptr[nv]; /* build arc lists */ for (a = 1; a <= na; a++) { arc[--ptr[tail[a]]] = a; arc[--ptr[head[a]]] = a; } xassert(ptr[1] == 1); xassert(ptr[nv+1] == na+na+1); /* now the indices of arcs incident to node i are stored in locations arc[ptr[i]], arc[ptr[i]+1], ..., arc[ptr[i+1]-1] */ /* initialize arc flows and node potentials */ for (a = 1; a <= na; a++) x[a] = 0; for (i = 1; i <= nv; i++) pi[i] = 0; loop: /* main loop starts here */ /* find out-of-kilter arc */ aok = 0; for (a = 1; a <= na; a++) { i = tail[a], j = head[a]; if (overflow(cost[a], pi[i] - pi[j])) { ret = 2; goto done; } lambda = cost[a] + (pi[i] - pi[j]); if (x[a] < low[a] || lambda < 0 && x[a] < cap[a]) { /* arc a = i->j is out of kilter, and we need to increase the flow through this arc */ aok = a, s = j, t = i; break; } if (x[a] > cap[a] || lambda > 0 && x[a] > low[a]) { /* arc a = i->j is out of kilter, and we need to decrease the flow through this arc */ aok = a, s = i, t = j; break; } } if (aok == 0) { /* all arcs are in kilter */ /* check for feasibility */ for (a = 1; a <= na; a++) { if (!(low[a] <= x[a] && x[a] <= cap[a])) { ret = 3; goto done; } } for (i = 1; i <= nv; i++) { temp = 0; for (k = ptr[i]; k < ptr[i+1]; k++) { a = arc[k]; if (tail[a] == i) { /* a is outgoing arc */ temp += x[a]; } else if (head[a] == i) { /* a is incoming arc */ temp -= x[a]; } else xassert(a != a); } if (temp != 0) { ret = 3; goto done; } } /* check for optimality */ for (a = 1; a <= na; a++) { i = tail[a], j = head[a]; lambda = cost[a] + (pi[i] - pi[j]); if (lambda > 0 && x[a] != low[a] || lambda < 0 && x[a] != cap[a]) { ret = 3; goto done; } } /* current circulation is optimal */ ret = 0; goto done; } /* now we need to find a cycle (t, a, s, ..., t), which allows increasing the flow along it, where a is the out-of-kilter arc just found */ /* link[i] = 0 means that node i is not labelled yet; link[i] = a means that arc a immediately precedes node i */ /* initially only node s is labelled */ for (i = 1; i <= nv; i++) link[i] = 0; link[s] = aok, list[1] = s, pos1 = pos2 = 1; /* breadth first search */ while (pos1 <= pos2) { /* dequeue node i */ i = list[pos1++]; /* consider all arcs incident to node i */ for (k = ptr[i]; k < ptr[i+1]; k++) { a = arc[k]; if (tail[a] == i) { /* a = i->j is a forward arc from s to t */ j = head[a]; /* if node j has been labelled, skip the arc */ if (link[j] != 0) continue; /* if the arc does not allow increasing the flow through it, skip the arc */ if (x[a] >= cap[a]) continue; if (overflow(cost[a], pi[i] - pi[j])) { ret = 2; goto done; } lambda = cost[a] + (pi[i] - pi[j]); if (lambda > 0 && x[a] >= low[a]) continue; } else if (head[a] == i) { /* a = i<-j is a backward arc from s to t */ j = tail[a]; /* if node j has been labelled, skip the arc */ if (link[j] != 0) continue; /* if the arc does not allow decreasing the flow through it, skip the arc */ if (x[a] <= low[a]) continue; if (overflow(cost[a], pi[j] - pi[i])) { ret = 2; goto done; } lambda = cost[a] + (pi[j] - pi[i]); if (lambda < 0 && x[a] <= cap[a]) continue; } else xassert(a != a); /* label node j and enqueue it */ link[j] = a, list[++pos2] = j; /* check for breakthrough */ if (j == t) goto brkt; } } /* NONBREAKTHROUGH */ /* consider all arcs, whose one endpoint is labelled and other is not, and determine maximal change of node potentials */ delta = 0; for (a = 1; a <= na; a++) { i = tail[a], j = head[a]; if (link[i] != 0 && link[j] == 0) { /* a = i->j, where node i is labelled, node j is not */ if (overflow(cost[a], pi[i] - pi[j])) { ret = 2; goto done; } lambda = cost[a] + (pi[i] - pi[j]); if (x[a] <= cap[a] && lambda > 0) if (delta == 0 || delta > + lambda) delta = + lambda; } else if (link[i] == 0 && link[j] != 0) { /* a = j<-i, where node j is labelled, node i is not */ if (overflow(cost[a], pi[i] - pi[j])) { ret = 2; goto done; } lambda = cost[a] + (pi[i] - pi[j]); if (x[a] >= low[a] && lambda < 0) if (delta == 0 || delta > - lambda) delta = - lambda; } } if (delta == 0) { /* there is no feasible circulation */ ret = 1; goto done; } /* increase potentials of all unlabelled nodes */ for (i = 1; i <= nv; i++) { if (link[i] == 0) { if (overflow(pi[i], delta)) { ret = 2; goto done; } pi[i] += delta; } } goto loop; brkt: /* BREAKTHROUGH */ /* walk through arcs of the cycle (t, a, s, ..., t) found in the reverse order and determine maximal change of the flow */ delta = 0; for (j = t;; j = i) { /* arc a immediately precedes node j in the cycle */ a = link[j]; if (head[a] == j) { /* a = i->j is a forward arc of the cycle */ i = tail[a]; lambda = cost[a] + (pi[i] - pi[j]); if (lambda > 0 && x[a] < low[a]) { /* x[a] may be increased until its lower bound */ temp = low[a] - x[a]; } else if (lambda <= 0 && x[a] < cap[a]) { /* x[a] may be increased until its upper bound */ temp = cap[a] - x[a]; } else xassert(a != a); } else if (tail[a] == j) { /* a = i<-j is a backward arc of the cycle */ i = head[a]; lambda = cost[a] + (pi[j] - pi[i]); if (lambda < 0 && x[a] > cap[a]) { /* x[a] may be decreased until its upper bound */ temp = x[a] - cap[a]; } else if (lambda >= 0 && x[a] > low[a]) { /* x[a] may be decreased until its lower bound */ temp = x[a] - low[a]; } else xassert(a != a); } else xassert(a != a); if (delta == 0 || delta > temp) delta = temp; /* check for end of the cycle */ if (i == t) break; } xassert(delta > 0); /* increase the flow along the cycle */ for (j = t;; j = i) { /* arc a immediately precedes node j in the cycle */ a = link[j]; if (head[a] == j) { /* a = i->j is a forward arc of the cycle */ i = tail[a]; /* overflow cannot occur */ x[a] += delta; } else if (tail[a] == j) { /* a = i<-j is a backward arc of the cycle */ i = head[a]; /* overflow cannot occur */ x[a] -= delta; } else xassert(a != a); /* check for end of the cycle */ if (i == t) break; } goto loop; done: /* free working arrays */ xfree(ptr); xfree(arc); xfree(link); xfree(list); return ret; } /* eof */ praat-6.0.04/external/glpk/glpnet07.c000066400000000000000000000165341261542461700173140ustar00rootroot00000000000000/* glpnet07.c (Ford-Fulkerson algorithm) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpenv.h" #include "glpnet.h" /*********************************************************************** * NAME * * ffalg - Ford-Fulkerson algorithm * * SYNOPSIS * * #include "glpnet.h" * void ffalg(int nv, int na, const int tail[], const int head[], * int s, int t, const int cap[], int x[], char cut[]); * * DESCRIPTION * * The routine ffalg implements the Ford-Fulkerson algorithm to find a * maximal flow in the specified flow network. * * INPUT PARAMETERS * * nv is the number of nodes, nv >= 2. * * na is the number of arcs, na >= 0. * * tail[a], a = 1,...,na, is the index of tail node of arc a. * * head[a], a = 1,...,na, is the index of head node of arc a. * * s is the source node index, 1 <= s <= nv. * * t is the sink node index, 1 <= t <= nv, t != s. * * cap[a], a = 1,...,na, is the capacity of arc a, cap[a] >= 0. * * NOTE: Multiple arcs are allowed, but self-loops are not allowed. * * OUTPUT PARAMETERS * * x[a], a = 1,...,na, is optimal value of the flow through arc a. * * cut[i], i = 1,...,nv, is 1 if node i is labelled, and 0 otherwise. * The set of arcs, whose one endpoint is labelled and other is not, * defines the minimal cut corresponding to the maximal flow found. * If the parameter cut is NULL, the cut information are not stored. * * REFERENCES * * L.R.Ford, Jr., and D.R.Fulkerson, "Flows in Networks," The RAND * Corp., Report R-375-PR (August 1962), Chap. I "Static Maximal Flow," * pp.30-33. */ void ffalg(int nv, int na, const int tail[], const int head[], int s, int t, const int cap[], int x[], char cut[]) { int a, delta, i, j, k, pos1, pos2, temp, *ptr, *arc, *link, *list; /* sanity checks */ xassert(nv >= 2); xassert(na >= 0); xassert(1 <= s && s <= nv); xassert(1 <= t && t <= nv); xassert(s != t); for (a = 1; a <= na; a++) { i = tail[a], j = head[a]; xassert(1 <= i && i <= nv); xassert(1 <= j && j <= nv); xassert(i != j); xassert(cap[a] >= 0); } /* allocate working arrays */ ptr = xcalloc(1+nv+1, sizeof(int)); arc = xcalloc(1+na+na, sizeof(int)); link = xcalloc(1+nv, sizeof(int)); list = xcalloc(1+nv, sizeof(int)); /* ptr[i] := (degree of node i) */ for (i = 1; i <= nv; i++) ptr[i] = 0; for (a = 1; a <= na; a++) { ptr[tail[a]]++; ptr[head[a]]++; } /* initialize arc pointers */ ptr[1]++; for (i = 1; i < nv; i++) ptr[i+1] += ptr[i]; ptr[nv+1] = ptr[nv]; /* build arc lists */ for (a = 1; a <= na; a++) { arc[--ptr[tail[a]]] = a; arc[--ptr[head[a]]] = a; } xassert(ptr[1] == 1); xassert(ptr[nv+1] == na+na+1); /* now the indices of arcs incident to node i are stored in locations arc[ptr[i]], arc[ptr[i]+1], ..., arc[ptr[i+1]-1] */ /* initialize arc flows */ for (a = 1; a <= na; a++) x[a] = 0; loop: /* main loop starts here */ /* build augmenting tree rooted at s */ /* link[i] = 0 means that node i is not labelled yet; link[i] = a means that arc a immediately precedes node i */ /* initially node s is labelled as the root */ for (i = 1; i <= nv; i++) link[i] = 0; link[s] = -1, list[1] = s, pos1 = pos2 = 1; /* breadth first search */ while (pos1 <= pos2) { /* dequeue node i */ i = list[pos1++]; /* consider all arcs incident to node i */ for (k = ptr[i]; k < ptr[i+1]; k++) { a = arc[k]; if (tail[a] == i) { /* a = i->j is a forward arc from s to t */ j = head[a]; /* if node j has been labelled, skip the arc */ if (link[j] != 0) continue; /* if the arc does not allow increasing the flow through it, skip the arc */ if (x[a] == cap[a]) continue; } else if (head[a] == i) { /* a = i<-j is a backward arc from s to t */ j = tail[a]; /* if node j has been labelled, skip the arc */ if (link[j] != 0) continue; /* if the arc does not allow decreasing the flow through it, skip the arc */ if (x[a] == 0) continue; } else xassert(a != a); /* label node j and enqueue it */ link[j] = a, list[++pos2] = j; /* check for breakthrough */ if (j == t) goto brkt; } } /* NONBREAKTHROUGH */ /* no augmenting path exists; current flow is maximal */ /* store minimal cut information, if necessary */ if (cut != NULL) { for (i = 1; i <= nv; i++) cut[i] = (char)(link[i] != 0); } goto done; brkt: /* BREAKTHROUGH */ /* walk through arcs of the augmenting path (s, ..., t) found in the reverse order and determine maximal change of the flow */ delta = 0; for (j = t; j != s; j = i) { /* arc a immediately precedes node j in the path */ a = link[j]; if (head[a] == j) { /* a = i->j is a forward arc of the cycle */ i = tail[a]; /* x[a] may be increased until its upper bound */ temp = cap[a] - x[a]; } else if (tail[a] == j) { /* a = i<-j is a backward arc of the cycle */ i = head[a]; /* x[a] may be decreased until its lower bound */ temp = x[a]; } else xassert(a != a); if (delta == 0 || delta > temp) delta = temp; } xassert(delta > 0); /* increase the flow along the path */ for (j = t; j != s; j = i) { /* arc a immediately precedes node j in the path */ a = link[j]; if (head[a] == j) { /* a = i->j is a forward arc of the cycle */ i = tail[a]; x[a] += delta; } else if (tail[a] == j) { /* a = i<-j is a backward arc of the cycle */ i = head[a]; x[a] -= delta; } else xassert(a != a); } goto loop; done: /* free working arrays */ xfree(ptr); xfree(arc); xfree(link); xfree(list); return; } /* eof */ praat-6.0.04/external/glpk/glpnet08.c000066400000000000000000000164261261542461700173150ustar00rootroot00000000000000/* glpnet08.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Two subroutines sub() and wclique() below are intended to find a * maximum weight clique in a given undirected graph. These subroutines * are slightly modified version of the program WCLIQUE developed by * Patric Ostergard and based * on ideas from the article "P. R. J. Ostergard, A new algorithm for * the maximum-weight clique problem, submitted for publication", which * in turn is a generalization of the algorithm for unweighted graphs * presented in "P. R. J. Ostergard, A fast algorithm for the maximum * clique problem, submitted for publication". * * USED WITH PERMISSION OF THE AUTHOR OF THE ORIGINAL CODE. * * Changes were made by Andrew Makhorin . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpenv.h" #include "glpnet.h" /*********************************************************************** * NAME * * wclique - find maximum weight clique with Ostergard's algorithm * * SYNOPSIS * * int wclique(int n, const int w[], const unsigned char a[], * int ind[]); * * DESCRIPTION * * The routine wclique finds a maximum weight clique in an undirected * graph with Ostergard's algorithm. * * INPUT PARAMETERS * * n is the number of vertices, n > 0. * * w[i], i = 1,...,n, is a weight of vertex i. * * a[*] is the strict (without main diagonal) lower triangle of the * graph adjacency matrix in packed format. * * OUTPUT PARAMETER * * ind[k], k = 1,...,size, is the number of a vertex included in the * clique found, 1 <= ind[k] <= n, where size is the number of vertices * in the clique returned on exit. * * RETURNS * * The routine returns the clique size, i.e. the number of vertices in * the clique. */ struct csa { /* common storage area */ int n; /* number of vertices */ const int *wt; /* int wt[0:n-1]; */ /* weights */ const unsigned char *a; /* adjacency matrix (packed lower triangle without main diag.) */ int record; /* weight of best clique */ int rec_level; /* number of vertices in best clique */ int *rec; /* int rec[0:n-1]; */ /* best clique so far */ int *clique; /* int clique[0:n-1]; */ /* table for pruning */ int *set; /* int set[0:n-1]; */ /* current clique */ }; #define n (csa->n) #define wt (csa->wt) #define a (csa->a) #define record (csa->record) #define rec_level (csa->rec_level) #define rec (csa->rec) #define clique (csa->clique) #define set (csa->set) #if 0 static int is_edge(struct csa *csa, int i, int j) { /* if there is arc (i,j), the routine returns true; otherwise false; 0 <= i, j < n */ int k; xassert(0 <= i && i < n); xassert(0 <= j && j < n); if (i == j) return 0; if (i < j) k = i, i = j, j = k; k = (i * (i - 1)) / 2 + j; return a[k / CHAR_BIT] & (unsigned char)(1 << ((CHAR_BIT - 1) - k % CHAR_BIT)); } #else #define is_edge(csa, i, j) ((i) == (j) ? 0 : \ (i) > (j) ? is_edge1(i, j) : is_edge1(j, i)) #define is_edge1(i, j) is_edge2(((i) * ((i) - 1)) / 2 + (j)) #define is_edge2(k) (a[(k) / CHAR_BIT] & \ (unsigned char)(1 << ((CHAR_BIT - 1) - (k) % CHAR_BIT))) #endif static void sub(struct csa *csa, int ct, int table[], int level, int weight, int l_weight) { int i, j, k, curr_weight, left_weight, *p1, *p2, *newtable; newtable = xcalloc(n, sizeof(int)); if (ct <= 0) { /* 0 or 1 elements left; include these */ if (ct == 0) { set[level++] = table[0]; weight += l_weight; } if (weight > record) { record = weight; rec_level = level; for (i = 0; i < level; i++) rec[i] = set[i]; } goto done; } for (i = ct; i >= 0; i--) { if ((level == 0) && (i < ct)) goto done; k = table[i]; if ((level > 0) && (clique[k] <= (record - weight))) goto done; /* prune */ set[level] = k; curr_weight = weight + wt[k]; l_weight -= wt[k]; if (l_weight <= (record - curr_weight)) goto done; /* prune */ p1 = newtable; p2 = table; left_weight = 0; while (p2 < table + i) { j = *p2++; if (is_edge(csa, j, k)) { *p1++ = j; left_weight += wt[j]; } } if (left_weight <= (record - curr_weight)) continue; sub(csa, p1 - newtable - 1, newtable, level + 1, curr_weight, left_weight); } done: xfree(newtable); return; } int wclique(int _n, const int w[], const unsigned char _a[], int ind[]) { struct csa _csa, *csa = &_csa; int i, j, p, max_wt, max_nwt, wth, *used, *nwt, *pos; glp_long timer; n = _n; xassert(n > 0); wt = &w[1]; a = _a; record = 0; rec_level = 0; rec = &ind[1]; clique = xcalloc(n, sizeof(int)); set = xcalloc(n, sizeof(int)); used = xcalloc(n, sizeof(int)); nwt = xcalloc(n, sizeof(int)); pos = xcalloc(n, sizeof(int)); /* start timer */ timer = xtime(); /* order vertices */ for (i = 0; i < n; i++) { nwt[i] = 0; for (j = 0; j < n; j++) if (is_edge(csa, i, j)) nwt[i] += wt[j]; } for (i = 0; i < n; i++) used[i] = 0; for (i = n-1; i >= 0; i--) { max_wt = -1; max_nwt = -1; for (j = 0; j < n; j++) { if ((!used[j]) && ((wt[j] > max_wt) || (wt[j] == max_wt && nwt[j] > max_nwt))) { max_wt = wt[j]; max_nwt = nwt[j]; p = j; } } pos[i] = p; used[p] = 1; for (j = 0; j < n; j++) if ((!used[j]) && (j != p) && (is_edge(csa, p, j))) nwt[j] -= wt[p]; } /* main routine */ wth = 0; for (i = 0; i < n; i++) { wth += wt[pos[i]]; sub(csa, i, pos, 0, 0, wth); clique[pos[i]] = record; if (xdifftime(xtime(), timer) >= 5.0 - 0.001) { /* print current record and reset timer */ xprintf("level = %d (%d); best = %d\n", i+1, n, record); timer = xtime(); } } xfree(clique); xfree(set); xfree(used); xfree(nwt); xfree(pos); /* return the solution found */ for (i = 1; i <= rec_level; i++) ind[i]++; return rec_level; } #undef n #undef wt #undef a #undef record #undef rec_level #undef rec #undef clique #undef set /* eof */ praat-6.0.04/external/glpk/glpnet09.c000066400000000000000000000223011261542461700173030ustar00rootroot00000000000000/* glpnet09.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpapi.h" #include "glpnet.h" /*********************************************************************** * NAME * * kellerman - cover edges by cliques with Kellerman's heuristic * * SYNOPSIS * * #include "glpnet.h" * int kellerman(int n, int (*func)(void *info, int i, int ind[]), * void *info, glp_graph *H); * * DESCRIPTION * * The routine kellerman implements Kellerman's heuristic algorithm * to find a minimal set of cliques which cover all edges of specified * graph G = (V, E). * * The parameter n specifies the number of vertices |V|, n >= 0. * * Formal routine func specifies the set of edges E in the following * way. Running the routine kellerman calls the routine func and passes * to it parameter i, which is the number of some vertex, 1 <= i <= n. * In response the routine func should store numbers of all vertices * adjacent to vertex i to locations ind[1], ind[2], ..., ind[len] and * return the value of len, which is the number of adjacent vertices, * 0 <= len <= n. Self-loops are allowed, but ignored. Multiple edges * are not allowed. * * The parameter info is a transit pointer (magic cookie) passed to the * formal routine func as its first parameter. * * The result provided by the routine kellerman is the bipartite graph * H = (V union C, F), which defines the covering found. (The program * object of type glp_graph specified by the parameter H should be * previously created with the routine glp_create_graph. On entry the * routine kellerman erases the content of this object with the routine * glp_erase_graph.) Vertices of first part V correspond to vertices of * the graph G and have the same ordinal numbers 1, 2, ..., n. Vertices * of second part C correspond to cliques and have ordinal numbers * n+1, n+2, ..., n+k, where k is the total number of cliques in the * edge covering found. Every edge f in F in the program object H is * represented as arc f = (i->j), where i in V and j in C, which means * that vertex i of the graph G is in clique C[j], 1 <= j <= k. (Thus, * if two vertices of the graph G are in the same clique, these vertices * are adjacent in G, and corresponding edge is covered by that clique.) * * RETURNS * * The routine Kellerman returns k, the total number of cliques in the * edge covering found. * * REFERENCE * * For more details see: glpk/doc/notes/keller.pdf (in Russian). */ struct set { /* set of vertices */ int size; /* size (cardinality) of the set, 0 <= card <= n */ int *list; /* int list[1+n]; */ /* the set contains vertices list[1,...,size] */ int *pos; /* int pos[1+n]; */ /* pos[i] > 0 means that vertex i is in the set and list[pos[i]] = i; pos[i] = 0 means that vertex i is not in the set */ }; int kellerman(int n, int (*func)(void *info, int i, int ind[]), void *info, void /* glp_graph */ *H_) { glp_graph *H = H_; struct set W_, *W = &W_, V_, *V = &V_; glp_arc *a; int i, j, k, m, t, len, card, best; xassert(n >= 0); /* H := (V, 0; 0), where V is the set of vertices of graph G */ glp_erase_graph(H, H->v_size, H->a_size); glp_add_vertices(H, n); /* W := 0 */ W->size = 0; W->list = xcalloc(1+n, sizeof(int)); W->pos = xcalloc(1+n, sizeof(int)); memset(&W->pos[1], 0, sizeof(int) * n); /* V := 0 */ V->size = 0; V->list = xcalloc(1+n, sizeof(int)); V->pos = xcalloc(1+n, sizeof(int)); memset(&V->pos[1], 0, sizeof(int) * n); /* main loop */ for (i = 1; i <= n; i++) { /* W must be empty */ xassert(W->size == 0); /* W := { j : i > j and (i,j) in E } */ len = func(info, i, W->list); xassert(0 <= len && len <= n); for (t = 1; t <= len; t++) { j = W->list[t]; xassert(1 <= j && j <= n); if (j >= i) continue; xassert(W->pos[j] == 0); W->list[++W->size] = j, W->pos[j] = W->size; } /* on i-th iteration we need to cover edges (i,j) for all j in W */ /* if W is empty, it is a special case */ if (W->size == 0) { /* set k := k + 1 and create new clique C[k] = { i } */ k = glp_add_vertices(H, 1) - n; glp_add_arc(H, i, n + k); continue; } /* try to include vertex i into existing cliques */ /* V must be empty */ xassert(V->size == 0); /* k is the number of cliques found so far */ k = H->nv - n; for (m = 1; m <= k; m++) { /* do while V != W; since here V is within W, we can use equivalent condition: do while |V| < |W| */ if (V->size == W->size) break; /* check if C[m] is within W */ for (a = H->v[n + m]->in; a != NULL; a = a->h_next) { j = a->tail->i; if (W->pos[j] == 0) break; } if (a != NULL) continue; /* C[m] is within W, expand clique C[m] with vertex i */ /* C[m] := C[m] union {i} */ glp_add_arc(H, i, n + m); /* V is a set of vertices whose incident edges are already covered by existing cliques */ /* V := V union C[m] */ for (a = H->v[n + m]->in; a != NULL; a = a->h_next) { j = a->tail->i; if (V->pos[j] == 0) V->list[++V->size] = j, V->pos[j] = V->size; } } /* remove from set W the vertices whose incident edges are already covered by existing cliques */ /* W := W \ V, V := 0 */ for (t = 1; t <= V->size; t++) { j = V->list[t], V->pos[j] = 0; if (W->pos[j] != 0) { /* remove vertex j from W */ if (W->pos[j] != W->size) { int jj = W->list[W->size]; W->list[W->pos[j]] = jj; W->pos[jj] = W->pos[j]; } W->size--, W->pos[j] = 0; } } V->size = 0; /* now set W contains only vertices whose incident edges are still not covered by existing cliques; create new cliques to cover remaining edges until set W becomes empty */ while (W->size > 0) { /* find clique C[m], 1 <= m <= k, which shares maximal number of vertices with W; to break ties choose clique having smallest number m */ m = 0, best = -1; k = H->nv - n; for (t = 1; t <= k; t++) { /* compute cardinality of intersection of W and C[t] */ card = 0; for (a = H->v[n + t]->in; a != NULL; a = a->h_next) { j = a->tail->i; if (W->pos[j] != 0) card++; } if (best < card) m = t, best = card; } xassert(m > 0); /* set k := k + 1 and create new clique: C[k] := (W intersect C[m]) union { i }, which covers all edges incident to vertices from (W intersect C[m]) */ k = glp_add_vertices(H, 1) - n; for (a = H->v[n + m]->in; a != NULL; a = a->h_next) { j = a->tail->i; if (W->pos[j] != 0) { /* vertex j is in both W and C[m]; include it in new clique C[k] */ glp_add_arc(H, j, n + k); /* remove vertex j from W, since edge (i,j) will be covered by new clique C[k] */ if (W->pos[j] != W->size) { int jj = W->list[W->size]; W->list[W->pos[j]] = jj; W->pos[jj] = W->pos[j]; } W->size--, W->pos[j] = 0; } } /* include vertex i to new clique C[k] to cover edges (i,j) incident to all vertices j just removed from W */ glp_add_arc(H, i, n + k); } } /* free working arrays */ xfree(W->list); xfree(W->pos); xfree(V->list); xfree(V->pos); /* return the number of cliques in the edge covering found */ return H->nv - n; } /* eof */ praat-6.0.04/external/glpk/glpnpp.h000066400000000000000000000433161261542461700171570ustar00rootroot00000000000000/* glpnpp.h (LP/MIP preprocessor) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPNPP_H #define GLPNPP_H #include "glpapi.h" typedef struct NPP NPP; typedef struct NPPROW NPPROW; typedef struct NPPCOL NPPCOL; typedef struct NPPAIJ NPPAIJ; typedef struct NPPTSE NPPTSE; typedef struct NPPLFE NPPLFE; struct NPP { /* LP/MIP preprocessor workspace */ /*--------------------------------------------------------------*/ /* original problem segment */ int orig_dir; /* optimization direction flag: GLP_MIN - minimization GLP_MAX - maximization */ int orig_m; /* number of rows */ int orig_n; /* number of columns */ int orig_nnz; /* number of non-zero constraint coefficients */ /*--------------------------------------------------------------*/ /* transformed problem segment (always minimization) */ DMP *pool; /* memory pool to store problem components */ char *name; /* problem name (1 to 255 chars); NULL means no name is assigned to the problem */ char *obj; /* objective function name (1 to 255 chars); NULL means no name is assigned to the objective function */ double c0; /* constant term of the objective function */ int nrows; /* number of rows introduced into the problem; this count increases by one every time a new row is added and never decreases; thus, actual number of rows may be less than nrows due to row deletions */ int ncols; /* number of columns introduced into the problem; this count increases by one every time a new column is added and never decreases; thus, actual number of column may be less than ncols due to column deletions */ NPPROW *r_head; /* pointer to the beginning of the row list */ NPPROW *r_tail; /* pointer to the end of the row list */ NPPCOL *c_head; /* pointer to the beginning of the column list */ NPPCOL *c_tail; /* pointer to the end of the column list */ /*--------------------------------------------------------------*/ /* transformation history */ DMP *stack; /* memory pool to store transformation entries */ NPPTSE *top; /* pointer to most recent transformation entry */ #if 0 /* 16/XII-2009 */ int count[1+25]; /* transformation statistics */ #endif /*--------------------------------------------------------------*/ /* resultant (preprocessed) problem segment */ int m; /* number of rows */ int n; /* number of columns */ int nnz; /* number of non-zero constraint coefficients */ int *row_ref; /* int row_ref[1+m]; */ /* row_ref[i], 1 <= i <= m, is the reference number assigned to a row, which is i-th row of the resultant problem */ int *col_ref; /* int col_ref[1+n]; */ /* col_ref[j], 1 <= j <= n, is the reference number assigned to a column, which is j-th column of the resultant problem */ /*--------------------------------------------------------------*/ /* recovered solution segment */ int sol; /* solution indicator: GLP_SOL - basic solution GLP_IPT - interior-point solution GLP_MIP - mixed integer solution */ int scaling; /* scaling option: GLP_OFF - scaling is disabled GLP_ON - scaling is enabled */ int p_stat; /* status of primal basic solution: GLP_UNDEF - primal solution is undefined GLP_FEAS - primal solution is feasible GLP_INFEAS - primal solution is infeasible GLP_NOFEAS - no primal feasible solution exists */ int d_stat; /* status of dual basic solution: GLP_UNDEF - dual solution is undefined GLP_FEAS - dual solution is feasible GLP_INFEAS - dual solution is infeasible GLP_NOFEAS - no dual feasible solution exists */ int t_stat; /* status of interior-point solution: GLP_UNDEF - interior solution is undefined GLP_OPT - interior solution is optimal */ int i_stat; /* status of mixed integer solution: GLP_UNDEF - integer solution is undefined GLP_OPT - integer solution is optimal GLP_FEAS - integer solution is feasible GLP_NOFEAS - no integer solution exists */ char *r_stat; /* char r_stat[1+nrows]; */ /* r_stat[i], 1 <= i <= nrows, is status of i-th row: GLP_BS - inactive constraint GLP_NL - active constraint on lower bound GLP_NU - active constraint on upper bound GLP_NF - active free row GLP_NS - active equality constraint */ char *c_stat; /* char c_stat[1+nrows]; */ /* c_stat[j], 1 <= j <= nrows, is status of j-th column: GLP_BS - basic variable GLP_NL - non-basic variable on lower bound GLP_NU - non-basic variable on upper bound GLP_NF - non-basic free variable GLP_NS - non-basic fixed variable */ double *r_pi; /* double r_pi[1+nrows]; */ /* r_pi[i], 1 <= i <= nrows, is Lagrange multiplier (dual value) for i-th row (constraint) */ double *c_value; /* double c_value[1+ncols]; */ /* c_value[j], 1 <= j <= ncols, is primal value of j-th column (structural variable) */ }; struct NPPROW { /* row (constraint) */ int i; /* reference number assigned to the row, 1 <= i <= nrows */ char *name; /* row name (1 to 255 chars); NULL means no name is assigned to the row */ double lb; /* lower bound; -DBL_MAX means the row has no lower bound */ double ub; /* upper bound; +DBL_MAX means the row has no upper bound */ NPPAIJ *ptr; /* pointer to the linked list of constraint coefficients */ int temp; /* working field used by preprocessor routines */ NPPROW *prev; /* pointer to previous row in the row list */ NPPROW *next; /* pointer to next row in the row list */ }; struct NPPCOL { /* column (variable) */ int j; /* reference number assigned to the column, 1 <= j <= ncols */ char *name; /* column name (1 to 255 chars); NULL means no name is assigned to the column */ char is_int; /* 0 means continuous variable; 1 means integer variable */ double lb; /* lower bound; -DBL_MAX means the column has no lower bound */ double ub; /* upper bound; +DBL_MAX means the column has no upper bound */ double coef; /* objective coefficient */ NPPAIJ *ptr; /* pointer to the linked list of constraint coefficients */ int temp; /* working field used by preprocessor routines */ #if 1 /* 28/XII-2009 */ union { double ll; /* implied column lower bound */ int pos; /* vertex ordinal number corresponding to this binary column in the conflict graph (0, if the vertex does not exist) */ } ll; union { double uu; /* implied column upper bound */ int neg; /* vertex ordinal number corresponding to complement of this binary column in the conflict graph (0, if the vertex does not exist) */ } uu; #endif NPPCOL *prev; /* pointer to previous column in the column list */ NPPCOL *next; /* pointer to next column in the column list */ }; struct NPPAIJ { /* constraint coefficient */ NPPROW *row; /* pointer to corresponding row */ NPPCOL *col; /* pointer to corresponding column */ double val; /* (non-zero) coefficient value */ NPPAIJ *r_prev; /* pointer to previous coefficient in the same row */ NPPAIJ *r_next; /* pointer to next coefficient in the same row */ NPPAIJ *c_prev; /* pointer to previous coefficient in the same column */ NPPAIJ *c_next; /* pointer to next coefficient in the same column */ }; struct NPPTSE { /* transformation stack entry */ int (*func)(NPP *npp, void *info); /* pointer to routine performing back transformation */ void *info; /* pointer to specific info (depends on the transformation) */ NPPTSE *link; /* pointer to another entry created *before* this entry */ }; struct NPPLFE { /* linear form element */ int ref; /* row/column reference number */ double val; /* (non-zero) coefficient value */ NPPLFE *next; /* pointer to another element */ }; #define npp_create_wksp _glp_npp_create_wksp NPP *npp_create_wksp(void); /* create LP/MIP preprocessor workspace */ #define npp_insert_row _glp_npp_insert_row void npp_insert_row(NPP *npp, NPPROW *row, int where); /* insert row to the row list */ #define npp_remove_row _glp_npp_remove_row void npp_remove_row(NPP *npp, NPPROW *row); /* remove row from the row list */ #define npp_activate_row _glp_npp_activate_row void npp_activate_row(NPP *npp, NPPROW *row); /* make row active */ #define npp_deactivate_row _glp_npp_deactivate_row void npp_deactivate_row(NPP *npp, NPPROW *row); /* make row inactive */ #define npp_insert_col _glp_npp_insert_col void npp_insert_col(NPP *npp, NPPCOL *col, int where); /* insert column to the column list */ #define npp_remove_col _glp_npp_remove_col void npp_remove_col(NPP *npp, NPPCOL *col); /* remove column from the column list */ #define npp_activate_col _glp_npp_activate_col void npp_activate_col(NPP *npp, NPPCOL *col); /* make column active */ #define npp_deactivate_col _glp_npp_deactivate_col void npp_deactivate_col(NPP *npp, NPPCOL *col); /* make column inactive */ #define npp_add_row _glp_npp_add_row NPPROW *npp_add_row(NPP *npp); /* add new row to the current problem */ #define npp_add_col _glp_npp_add_col NPPCOL *npp_add_col(NPP *npp); /* add new column to the current problem */ #define npp_add_aij _glp_npp_add_aij NPPAIJ *npp_add_aij(NPP *npp, NPPROW *row, NPPCOL *col, double val); /* add new element to the constraint matrix */ #define npp_row_nnz _glp_npp_row_nnz int npp_row_nnz(NPP *npp, NPPROW *row); /* count number of non-zero coefficients in row */ #define npp_col_nnz _glp_npp_col_nnz int npp_col_nnz(NPP *npp, NPPCOL *col); /* count number of non-zero coefficients in column */ #define npp_push_tse _glp_npp_push_tse void *npp_push_tse(NPP *npp, int (*func)(NPP *npp, void *info), int size); /* push new entry to the transformation stack */ #define npp_erase_row _glp_npp_erase_row void npp_erase_row(NPP *npp, NPPROW *row); /* erase row content to make it empty */ #define npp_del_row _glp_npp_del_row void npp_del_row(NPP *npp, NPPROW *row); /* remove row from the current problem */ #define npp_del_col _glp_npp_del_col void npp_del_col(NPP *npp, NPPCOL *col); /* remove column from the current problem */ #define npp_del_aij _glp_npp_del_aij void npp_del_aij(NPP *npp, NPPAIJ *aij); /* remove element from the constraint matrix */ #define npp_load_prob _glp_npp_load_prob void npp_load_prob(NPP *npp, glp_prob *orig, int names, int sol, int scaling); /* load original problem into the preprocessor workspace */ #define npp_build_prob _glp_npp_build_prob void npp_build_prob(NPP *npp, glp_prob *prob); /* build resultant (preprocessed) problem */ #define npp_postprocess _glp_npp_postprocess void npp_postprocess(NPP *npp, glp_prob *prob); /* postprocess solution from the resultant problem */ #define npp_unload_sol _glp_npp_unload_sol void npp_unload_sol(NPP *npp, glp_prob *orig); /* store solution to the original problem */ #define npp_delete_wksp _glp_npp_delete_wksp void npp_delete_wksp(NPP *npp); /* delete LP/MIP preprocessor workspace */ #define npp_error() #define npp_free_row _glp_npp_free_row void npp_free_row(NPP *npp, NPPROW *p); /* process free (unbounded) row */ #define npp_geq_row _glp_npp_geq_row void npp_geq_row(NPP *npp, NPPROW *p); /* process row of 'not less than' type */ #define npp_leq_row _glp_npp_leq_row void npp_leq_row(NPP *npp, NPPROW *p); /* process row of 'not greater than' type */ #define npp_free_col _glp_npp_free_col void npp_free_col(NPP *npp, NPPCOL *q); /* process free (unbounded) column */ #define npp_lbnd_col _glp_npp_lbnd_col void npp_lbnd_col(NPP *npp, NPPCOL *q); /* process column with (non-zero) lower bound */ #define npp_ubnd_col _glp_npp_ubnd_col void npp_ubnd_col(NPP *npp, NPPCOL *q); /* process column with upper bound */ #define npp_dbnd_col _glp_npp_dbnd_col void npp_dbnd_col(NPP *npp, NPPCOL *q); /* process non-negative column with upper bound */ #define npp_fixed_col _glp_npp_fixed_col void npp_fixed_col(NPP *npp, NPPCOL *q); /* process fixed column */ #define npp_make_equality _glp_npp_make_equality int npp_make_equality(NPP *npp, NPPROW *p); /* process row with almost identical bounds */ #define npp_make_fixed _glp_npp_make_fixed int npp_make_fixed(NPP *npp, NPPCOL *q); /* process column with almost identical bounds */ #define npp_empty_row _glp_npp_empty_row int npp_empty_row(NPP *npp, NPPROW *p); /* process empty row */ #define npp_empty_col _glp_npp_empty_col int npp_empty_col(NPP *npp, NPPCOL *q); /* process empty column */ #define npp_implied_value _glp_npp_implied_value int npp_implied_value(NPP *npp, NPPCOL *q, double s); /* process implied column value */ #define npp_eq_singlet _glp_npp_eq_singlet int npp_eq_singlet(NPP *npp, NPPROW *p); /* process row singleton (equality constraint) */ #define npp_implied_lower _glp_npp_implied_lower int npp_implied_lower(NPP *npp, NPPCOL *q, double l); /* process implied column lower bound */ #define npp_implied_upper _glp_npp_implied_upper int npp_implied_upper(NPP *npp, NPPCOL *q, double u); /* process implied upper bound of column */ #define npp_ineq_singlet _glp_npp_ineq_singlet int npp_ineq_singlet(NPP *npp, NPPROW *p); /* process row singleton (inequality constraint) */ #define npp_implied_slack _glp_npp_implied_slack void npp_implied_slack(NPP *npp, NPPCOL *q); /* process column singleton (implied slack variable) */ #define npp_implied_free _glp_npp_implied_free int npp_implied_free(NPP *npp, NPPCOL *q); /* process column singleton (implied free variable) */ #define npp_eq_doublet _glp_npp_eq_doublet NPPCOL *npp_eq_doublet(NPP *npp, NPPROW *p); /* process row doubleton (equality constraint) */ #define npp_forcing_row _glp_npp_forcing_row int npp_forcing_row(NPP *npp, NPPROW *p, int at); /* process forcing row */ #define npp_analyze_row _glp_npp_analyze_row int npp_analyze_row(NPP *npp, NPPROW *p); /* perform general row analysis */ #define npp_inactive_bound _glp_npp_inactive_bound void npp_inactive_bound(NPP *npp, NPPROW *p, int which); /* remove row lower/upper inactive bound */ #define npp_implied_bounds _glp_npp_implied_bounds void npp_implied_bounds(NPP *npp, NPPROW *p); /* determine implied column bounds */ #define npp_binarize_prob _glp_npp_binarize_prob int npp_binarize_prob(NPP *npp); /* binarize MIP problem */ #define npp_is_packing _glp_npp_is_packing int npp_is_packing(NPP *npp, NPPROW *row); /* test if constraint is packing inequality */ #define npp_hidden_packing _glp_npp_hidden_packing int npp_hidden_packing(NPP *npp, NPPROW *row); /* identify hidden packing inequality */ #define npp_implied_packing _glp_npp_implied_packing int npp_implied_packing(NPP *npp, NPPROW *row, int which, NPPCOL *var[], char set[]); /* identify implied packing inequality */ #define npp_is_covering _glp_npp_is_covering int npp_is_covering(NPP *npp, NPPROW *row); /* test if constraint is covering inequality */ #define npp_hidden_covering _glp_npp_hidden_covering int npp_hidden_covering(NPP *npp, NPPROW *row); /* identify hidden covering inequality */ #define npp_is_partitioning _glp_npp_is_partitioning int npp_is_partitioning(NPP *npp, NPPROW *row); /* test if constraint is partitioning equality */ #define npp_reduce_ineq_coef _glp_npp_reduce_ineq_coef int npp_reduce_ineq_coef(NPP *npp, NPPROW *row); /* reduce inequality constraint coefficients */ #define npp_clean_prob _glp_npp_clean_prob void npp_clean_prob(NPP *npp); /* perform initial LP/MIP processing */ #define npp_process_row _glp_npp_process_row int npp_process_row(NPP *npp, NPPROW *row, int hard); /* perform basic row processing */ #define npp_improve_bounds _glp_npp_improve_bounds int npp_improve_bounds(NPP *npp, NPPROW *row, int flag); /* improve current column bounds */ #define npp_process_col _glp_npp_process_col int npp_process_col(NPP *npp, NPPCOL *col); /* perform basic column processing */ #define npp_process_prob _glp_npp_process_prob int npp_process_prob(NPP *npp, int hard); /* perform basic LP/MIP processing */ #define npp_simplex _glp_npp_simplex int npp_simplex(NPP *npp, const glp_smcp *parm); /* process LP prior to applying primal/dual simplex method */ #define npp_integer _glp_npp_integer int npp_integer(NPP *npp, const glp_iocp *parm); /* process MIP prior to applying branch-and-bound method */ #endif /* eof */ praat-6.0.04/external/glpk/glpnpp01.c000066400000000000000000000706471261542461700173220ustar00rootroot00000000000000/* glpnpp01.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpnpp.h" NPP *npp_create_wksp(void) { /* create LP/MIP preprocessor workspace */ NPP *npp; npp = xmalloc(sizeof(NPP)); npp->orig_dir = 0; npp->orig_m = npp->orig_n = npp->orig_nnz = 0; npp->pool = dmp_create_pool(); npp->name = npp->obj = NULL; npp->c0 = 0.0; npp->nrows = npp->ncols = 0; npp->r_head = npp->r_tail = NULL; npp->c_head = npp->c_tail = NULL; npp->stack = dmp_create_pool(); npp->top = NULL; #if 0 /* 16/XII-2009 */ memset(&npp->count, 0, sizeof(npp->count)); #endif npp->m = npp->n = npp->nnz = 0; npp->row_ref = npp->col_ref = NULL; npp->sol = npp->scaling = 0; npp->p_stat = npp->d_stat = npp->t_stat = npp->i_stat = 0; npp->r_stat = NULL; /*npp->r_prim =*/ npp->r_pi = NULL; npp->c_stat = NULL; npp->c_value = /*npp->c_dual =*/ NULL; return npp; } void npp_insert_row(NPP *npp, NPPROW *row, int where) { /* insert row to the row list */ if (where == 0) { /* insert row to the beginning of the row list */ row->prev = NULL; row->next = npp->r_head; if (row->next == NULL) npp->r_tail = row; else row->next->prev = row; npp->r_head = row; } else { /* insert row to the end of the row list */ row->prev = npp->r_tail; row->next = NULL; if (row->prev == NULL) npp->r_head = row; else row->prev->next = row; npp->r_tail = row; } return; } void npp_remove_row(NPP *npp, NPPROW *row) { /* remove row from the row list */ if (row->prev == NULL) npp->r_head = row->next; else row->prev->next = row->next; if (row->next == NULL) npp->r_tail = row->prev; else row->next->prev = row->prev; return; } void npp_activate_row(NPP *npp, NPPROW *row) { /* make row active */ if (!row->temp) { row->temp = 1; /* move the row to the beginning of the row list */ npp_remove_row(npp, row); npp_insert_row(npp, row, 0); } return; } void npp_deactivate_row(NPP *npp, NPPROW *row) { /* make row inactive */ if (row->temp) { row->temp = 0; /* move the row to the end of the row list */ npp_remove_row(npp, row); npp_insert_row(npp, row, 1); } return; } void npp_insert_col(NPP *npp, NPPCOL *col, int where) { /* insert column to the column list */ if (where == 0) { /* insert column to the beginning of the column list */ col->prev = NULL; col->next = npp->c_head; if (col->next == NULL) npp->c_tail = col; else col->next->prev = col; npp->c_head = col; } else { /* insert column to the end of the column list */ col->prev = npp->c_tail; col->next = NULL; if (col->prev == NULL) npp->c_head = col; else col->prev->next = col; npp->c_tail = col; } return; } void npp_remove_col(NPP *npp, NPPCOL *col) { /* remove column from the column list */ if (col->prev == NULL) npp->c_head = col->next; else col->prev->next = col->next; if (col->next == NULL) npp->c_tail = col->prev; else col->next->prev = col->prev; return; } void npp_activate_col(NPP *npp, NPPCOL *col) { /* make column active */ if (!col->temp) { col->temp = 1; /* move the column to the beginning of the column list */ npp_remove_col(npp, col); npp_insert_col(npp, col, 0); } return; } void npp_deactivate_col(NPP *npp, NPPCOL *col) { /* make column inactive */ if (col->temp) { col->temp = 0; /* move the column to the end of the column list */ npp_remove_col(npp, col); npp_insert_col(npp, col, 1); } return; } NPPROW *npp_add_row(NPP *npp) { /* add new row to the current problem */ NPPROW *row; row = dmp_get_atom(npp->pool, sizeof(NPPROW)); row->i = ++(npp->nrows); row->name = NULL; row->lb = -DBL_MAX, row->ub = +DBL_MAX; row->ptr = NULL; row->temp = 0; npp_insert_row(npp, row, 1); return row; } NPPCOL *npp_add_col(NPP *npp) { /* add new column to the current problem */ NPPCOL *col; col = dmp_get_atom(npp->pool, sizeof(NPPCOL)); col->j = ++(npp->ncols); col->name = NULL; #if 0 col->kind = GLP_CV; #else col->is_int = 0; #endif col->lb = col->ub = col->coef = 0.0; col->ptr = NULL; col->temp = 0; npp_insert_col(npp, col, 1); return col; } NPPAIJ *npp_add_aij(NPP *npp, NPPROW *row, NPPCOL *col, double val) { /* add new element to the constraint matrix */ NPPAIJ *aij; aij = dmp_get_atom(npp->pool, sizeof(NPPAIJ)); aij->row = row; aij->col = col; aij->val = val; aij->r_prev = NULL; aij->r_next = row->ptr; aij->c_prev = NULL; aij->c_next = col->ptr; if (aij->r_next != NULL) aij->r_next->r_prev = aij; if (aij->c_next != NULL) aij->c_next->c_prev = aij; row->ptr = col->ptr = aij; return aij; } int npp_row_nnz(NPP *npp, NPPROW *row) { /* count number of non-zero coefficients in row */ NPPAIJ *aij; int nnz; xassert(npp == npp); nnz = 0; for (aij = row->ptr; aij != NULL; aij = aij->r_next) nnz++; return nnz; } int npp_col_nnz(NPP *npp, NPPCOL *col) { /* count number of non-zero coefficients in column */ NPPAIJ *aij; int nnz; xassert(npp == npp); nnz = 0; for (aij = col->ptr; aij != NULL; aij = aij->c_next) nnz++; return nnz; } void *npp_push_tse(NPP *npp, int (*func)(NPP *npp, void *info), int size) { /* push new entry to the transformation stack */ NPPTSE *tse; tse = dmp_get_atom(npp->stack, sizeof(NPPTSE)); tse->func = func; tse->info = dmp_get_atom(npp->stack, size); tse->link = npp->top; npp->top = tse; return tse->info; } #if 1 /* 23/XII-2009 */ void npp_erase_row(NPP *npp, NPPROW *row) { /* erase row content to make it empty */ NPPAIJ *aij; while (row->ptr != NULL) { aij = row->ptr; row->ptr = aij->r_next; if (aij->c_prev == NULL) aij->col->ptr = aij->c_next; else aij->c_prev->c_next = aij->c_next; if (aij->c_next == NULL) ; else aij->c_next->c_prev = aij->c_prev; dmp_free_atom(npp->pool, aij, sizeof(NPPAIJ)); } return; } #endif void npp_del_row(NPP *npp, NPPROW *row) { /* remove row from the current problem */ #if 0 /* 23/XII-2009 */ NPPAIJ *aij; #endif if (row->name != NULL) dmp_free_atom(npp->pool, row->name, strlen(row->name)+1); #if 0 /* 23/XII-2009 */ while (row->ptr != NULL) { aij = row->ptr; row->ptr = aij->r_next; if (aij->c_prev == NULL) aij->col->ptr = aij->c_next; else aij->c_prev->c_next = aij->c_next; if (aij->c_next == NULL) ; else aij->c_next->c_prev = aij->c_prev; dmp_free_atom(npp->pool, aij, sizeof(NPPAIJ)); } #else npp_erase_row(npp, row); #endif npp_remove_row(npp, row); dmp_free_atom(npp->pool, row, sizeof(NPPROW)); return; } void npp_del_col(NPP *npp, NPPCOL *col) { /* remove column from the current problem */ NPPAIJ *aij; if (col->name != NULL) dmp_free_atom(npp->pool, col->name, strlen(col->name)+1); while (col->ptr != NULL) { aij = col->ptr; col->ptr = aij->c_next; if (aij->r_prev == NULL) aij->row->ptr = aij->r_next; else aij->r_prev->r_next = aij->r_next; if (aij->r_next == NULL) ; else aij->r_next->r_prev = aij->r_prev; dmp_free_atom(npp->pool, aij, sizeof(NPPAIJ)); } npp_remove_col(npp, col); dmp_free_atom(npp->pool, col, sizeof(NPPCOL)); return; } void npp_del_aij(NPP *npp, NPPAIJ *aij) { /* remove element from the constraint matrix */ if (aij->r_prev == NULL) aij->row->ptr = aij->r_next; else aij->r_prev->r_next = aij->r_next; if (aij->r_next == NULL) ; else aij->r_next->r_prev = aij->r_prev; if (aij->c_prev == NULL) aij->col->ptr = aij->c_next; else aij->c_prev->c_next = aij->c_next; if (aij->c_next == NULL) ; else aij->c_next->c_prev = aij->c_prev; dmp_free_atom(npp->pool, aij, sizeof(NPPAIJ)); return; } void npp_load_prob(NPP *npp, glp_prob *orig, int names, int sol, int scaling) { /* load original problem into the preprocessor workspace */ int m = orig->m; int n = orig->n; NPPROW **link; int i, j; double dir; xassert(names == GLP_OFF || names == GLP_ON); xassert(sol == GLP_SOL || sol == GLP_IPT || sol == GLP_MIP); xassert(scaling == GLP_OFF || scaling == GLP_ON); if (sol == GLP_MIP) xassert(!scaling); npp->orig_dir = orig->dir; if (npp->orig_dir == GLP_MIN) dir = +1.0; else if (npp->orig_dir == GLP_MAX) dir = -1.0; else xassert(npp != npp); npp->orig_m = m; npp->orig_n = n; npp->orig_nnz = orig->nnz; if (names && orig->name != NULL) { npp->name = dmp_get_atom(npp->pool, strlen(orig->name)+1); strcpy(npp->name, orig->name); } if (names && orig->obj != NULL) { npp->obj = dmp_get_atom(npp->pool, strlen(orig->obj)+1); strcpy(npp->obj, orig->obj); } npp->c0 = dir * orig->c0; /* load rows */ link = xcalloc(1+m, sizeof(NPPROW *)); for (i = 1; i <= m; i++) { GLPROW *rrr = orig->row[i]; NPPROW *row; link[i] = row = npp_add_row(npp); xassert(row->i == i); if (names && rrr->name != NULL) { row->name = dmp_get_atom(npp->pool, strlen(rrr->name)+1); strcpy(row->name, rrr->name); } if (!scaling) { if (rrr->type == GLP_FR) row->lb = -DBL_MAX, row->ub = +DBL_MAX; else if (rrr->type == GLP_LO) row->lb = rrr->lb, row->ub = +DBL_MAX; else if (rrr->type == GLP_UP) row->lb = -DBL_MAX, row->ub = rrr->ub; else if (rrr->type == GLP_DB) row->lb = rrr->lb, row->ub = rrr->ub; else if (rrr->type == GLP_FX) row->lb = row->ub = rrr->lb; else xassert(rrr != rrr); } else { double rii = rrr->rii; if (rrr->type == GLP_FR) row->lb = -DBL_MAX, row->ub = +DBL_MAX; else if (rrr->type == GLP_LO) row->lb = rrr->lb * rii, row->ub = +DBL_MAX; else if (rrr->type == GLP_UP) row->lb = -DBL_MAX, row->ub = rrr->ub * rii; else if (rrr->type == GLP_DB) row->lb = rrr->lb * rii, row->ub = rrr->ub * rii; else if (rrr->type == GLP_FX) row->lb = row->ub = rrr->lb * rii; else xassert(rrr != rrr); } } /* load columns and constraint coefficients */ for (j = 1; j <= n; j++) { GLPCOL *ccc = orig->col[j]; GLPAIJ *aaa; NPPCOL *col; col = npp_add_col(npp); xassert(col->j == j); if (names && ccc->name != NULL) { col->name = dmp_get_atom(npp->pool, strlen(ccc->name)+1); strcpy(col->name, ccc->name); } if (sol == GLP_MIP) #if 0 col->kind = ccc->kind; #else col->is_int = (char)(ccc->kind == GLP_IV); #endif if (!scaling) { if (ccc->type == GLP_FR) col->lb = -DBL_MAX, col->ub = +DBL_MAX; else if (ccc->type == GLP_LO) col->lb = ccc->lb, col->ub = +DBL_MAX; else if (ccc->type == GLP_UP) col->lb = -DBL_MAX, col->ub = ccc->ub; else if (ccc->type == GLP_DB) col->lb = ccc->lb, col->ub = ccc->ub; else if (ccc->type == GLP_FX) col->lb = col->ub = ccc->lb; else xassert(ccc != ccc); col->coef = dir * ccc->coef; for (aaa = ccc->ptr; aaa != NULL; aaa = aaa->c_next) npp_add_aij(npp, link[aaa->row->i], col, aaa->val); } else { double sjj = ccc->sjj; if (ccc->type == GLP_FR) col->lb = -DBL_MAX, col->ub = +DBL_MAX; else if (ccc->type == GLP_LO) col->lb = ccc->lb / sjj, col->ub = +DBL_MAX; else if (ccc->type == GLP_UP) col->lb = -DBL_MAX, col->ub = ccc->ub / sjj; else if (ccc->type == GLP_DB) col->lb = ccc->lb / sjj, col->ub = ccc->ub / sjj; else if (ccc->type == GLP_FX) col->lb = col->ub = ccc->lb / sjj; else xassert(ccc != ccc); col->coef = dir * ccc->coef * sjj; for (aaa = ccc->ptr; aaa != NULL; aaa = aaa->c_next) npp_add_aij(npp, link[aaa->row->i], col, aaa->row->rii * aaa->val * sjj); } } xfree(link); /* keep solution indicator and scaling option */ npp->sol = sol; npp->scaling = scaling; return; } void npp_build_prob(NPP *npp, glp_prob *prob) { /* build resultant (preprocessed) problem */ NPPROW *row; NPPCOL *col; NPPAIJ *aij; int i, j, type, len, *ind; double dir, *val; glp_erase_prob(prob); glp_set_prob_name(prob, npp->name); glp_set_obj_name(prob, npp->obj); glp_set_obj_dir(prob, npp->orig_dir); if (npp->orig_dir == GLP_MIN) dir = +1.0; else if (npp->orig_dir == GLP_MAX) dir = -1.0; else xassert(npp != npp); glp_set_obj_coef(prob, 0, dir * npp->c0); /* build rows */ for (row = npp->r_head; row != NULL; row = row->next) { row->temp = i = glp_add_rows(prob, 1); glp_set_row_name(prob, i, row->name); if (row->lb == -DBL_MAX && row->ub == +DBL_MAX) type = GLP_FR; else if (row->ub == +DBL_MAX) type = GLP_LO; else if (row->lb == -DBL_MAX) type = GLP_UP; else if (row->lb != row->ub) type = GLP_DB; else type = GLP_FX; glp_set_row_bnds(prob, i, type, row->lb, row->ub); } /* build columns and the constraint matrix */ ind = xcalloc(1+prob->m, sizeof(int)); val = xcalloc(1+prob->m, sizeof(double)); for (col = npp->c_head; col != NULL; col = col->next) { j = glp_add_cols(prob, 1); glp_set_col_name(prob, j, col->name); #if 0 glp_set_col_kind(prob, j, col->kind); #else glp_set_col_kind(prob, j, col->is_int ? GLP_IV : GLP_CV); #endif if (col->lb == -DBL_MAX && col->ub == +DBL_MAX) type = GLP_FR; else if (col->ub == +DBL_MAX) type = GLP_LO; else if (col->lb == -DBL_MAX) type = GLP_UP; else if (col->lb != col->ub) type = GLP_DB; else type = GLP_FX; glp_set_col_bnds(prob, j, type, col->lb, col->ub); glp_set_obj_coef(prob, j, dir * col->coef); len = 0; for (aij = col->ptr; aij != NULL; aij = aij->c_next) { len++; ind[len] = aij->row->temp; val[len] = aij->val; } glp_set_mat_col(prob, j, len, ind, val); } xfree(ind); xfree(val); /* resultant problem has been built */ npp->m = prob->m; npp->n = prob->n; npp->nnz = prob->nnz; npp->row_ref = xcalloc(1+npp->m, sizeof(int)); npp->col_ref = xcalloc(1+npp->n, sizeof(int)); for (row = npp->r_head, i = 0; row != NULL; row = row->next) npp->row_ref[++i] = row->i; for (col = npp->c_head, j = 0; col != NULL; col = col->next) npp->col_ref[++j] = col->j; /* transformed problem segment is no longer needed */ dmp_delete_pool(npp->pool), npp->pool = NULL; npp->name = npp->obj = NULL; npp->c0 = 0.0; npp->r_head = npp->r_tail = NULL; npp->c_head = npp->c_tail = NULL; return; } void npp_postprocess(NPP *npp, glp_prob *prob) { /* postprocess solution from the resultant problem */ GLPROW *row; GLPCOL *col; NPPTSE *tse; int i, j, k; double dir; xassert(npp->orig_dir == prob->dir); if (npp->orig_dir == GLP_MIN) dir = +1.0; else if (npp->orig_dir == GLP_MAX) dir = -1.0; else xassert(npp != npp); xassert(npp->m == prob->m); xassert(npp->n == prob->n); xassert(npp->nnz == prob->nnz); /* copy solution status */ if (npp->sol == GLP_SOL) { npp->p_stat = prob->pbs_stat; npp->d_stat = prob->dbs_stat; } else if (npp->sol == GLP_IPT) npp->t_stat = prob->ipt_stat; else if (npp->sol == GLP_MIP) npp->i_stat = prob->mip_stat; else xassert(npp != npp); /* allocate solution arrays */ if (npp->sol == GLP_SOL) { if (npp->r_stat == NULL) npp->r_stat = xcalloc(1+npp->nrows, sizeof(char)); for (i = 1; i <= npp->nrows; i++) npp->r_stat[i] = 0; if (npp->c_stat == NULL) npp->c_stat = xcalloc(1+npp->ncols, sizeof(char)); for (j = 1; j <= npp->ncols; j++) npp->c_stat[j] = 0; } #if 0 if (npp->r_prim == NULL) npp->r_prim = xcalloc(1+npp->nrows, sizeof(double)); for (i = 1; i <= npp->nrows; i++) npp->r_prim[i] = DBL_MAX; #endif if (npp->c_value == NULL) npp->c_value = xcalloc(1+npp->ncols, sizeof(double)); for (j = 1; j <= npp->ncols; j++) npp->c_value[j] = DBL_MAX; if (npp->sol != GLP_MIP) { if (npp->r_pi == NULL) npp->r_pi = xcalloc(1+npp->nrows, sizeof(double)); for (i = 1; i <= npp->nrows; i++) npp->r_pi[i] = DBL_MAX; #if 0 if (npp->c_dual == NULL) npp->c_dual = xcalloc(1+npp->ncols, sizeof(double)); for (j = 1; j <= npp->ncols; j++) npp->c_dual[j] = DBL_MAX; #endif } /* copy solution components from the resultant problem */ if (npp->sol == GLP_SOL) { for (i = 1; i <= npp->m; i++) { row = prob->row[i]; k = npp->row_ref[i]; npp->r_stat[k] = (char)row->stat; /*npp->r_prim[k] = row->prim;*/ npp->r_pi[k] = dir * row->dual; } for (j = 1; j <= npp->n; j++) { col = prob->col[j]; k = npp->col_ref[j]; npp->c_stat[k] = (char)col->stat; npp->c_value[k] = col->prim; /*npp->c_dual[k] = dir * col->dual;*/ } } else if (npp->sol == GLP_IPT) { for (i = 1; i <= npp->m; i++) { row = prob->row[i]; k = npp->row_ref[i]; /*npp->r_prim[k] = row->pval;*/ npp->r_pi[k] = dir * row->dval; } for (j = 1; j <= npp->n; j++) { col = prob->col[j]; k = npp->col_ref[j]; npp->c_value[k] = col->pval; /*npp->c_dual[k] = dir * col->dval;*/ } } else if (npp->sol == GLP_MIP) { #if 0 for (i = 1; i <= npp->m; i++) { row = prob->row[i]; k = npp->row_ref[i]; /*npp->r_prim[k] = row->mipx;*/ } #endif for (j = 1; j <= npp->n; j++) { col = prob->col[j]; k = npp->col_ref[j]; npp->c_value[k] = col->mipx; } } else xassert(npp != npp); /* perform postprocessing to construct solution to the original problem */ for (tse = npp->top; tse != NULL; tse = tse->link) { xassert(tse->func != NULL); xassert(tse->func(npp, tse->info) == 0); } return; } void npp_unload_sol(NPP *npp, glp_prob *orig) { /* store solution to the original problem */ GLPROW *row; GLPCOL *col; int i, j; double dir; xassert(npp->orig_dir == orig->dir); if (npp->orig_dir == GLP_MIN) dir = +1.0; else if (npp->orig_dir == GLP_MAX) dir = -1.0; else xassert(npp != npp); xassert(npp->orig_m == orig->m); xassert(npp->orig_n == orig->n); xassert(npp->orig_nnz == orig->nnz); if (npp->sol == GLP_SOL) { /* store basic solution */ orig->valid = 0; orig->pbs_stat = npp->p_stat; orig->dbs_stat = npp->d_stat; orig->obj_val = orig->c0; orig->some = 0; for (i = 1; i <= orig->m; i++) { row = orig->row[i]; row->stat = npp->r_stat[i]; if (!npp->scaling) { /*row->prim = npp->r_prim[i];*/ row->dual = dir * npp->r_pi[i]; } else { /*row->prim = npp->r_prim[i] / row->rii;*/ row->dual = dir * npp->r_pi[i] * row->rii; } if (row->stat == GLP_BS) row->dual = 0.0; else if (row->stat == GLP_NL) { xassert(row->type == GLP_LO || row->type == GLP_DB); row->prim = row->lb; } else if (row->stat == GLP_NU) { xassert(row->type == GLP_UP || row->type == GLP_DB); row->prim = row->ub; } else if (row->stat == GLP_NF) { xassert(row->type == GLP_FR); row->prim = 0.0; } else if (row->stat == GLP_NS) { xassert(row->type == GLP_FX); row->prim = row->lb; } else xassert(row != row); } for (j = 1; j <= orig->n; j++) { col = orig->col[j]; col->stat = npp->c_stat[j]; if (!npp->scaling) { col->prim = npp->c_value[j]; /*col->dual = dir * npp->c_dual[j];*/ } else { col->prim = npp->c_value[j] * col->sjj; /*col->dual = dir * npp->c_dual[j] / col->sjj;*/ } if (col->stat == GLP_BS) col->dual = 0.0; #if 1 else if (col->stat == GLP_NL) { xassert(col->type == GLP_LO || col->type == GLP_DB); col->prim = col->lb; } else if (col->stat == GLP_NU) { xassert(col->type == GLP_UP || col->type == GLP_DB); col->prim = col->ub; } else if (col->stat == GLP_NF) { xassert(col->type == GLP_FR); col->prim = 0.0; } else if (col->stat == GLP_NS) { xassert(col->type == GLP_FX); col->prim = col->lb; } else xassert(col != col); #endif orig->obj_val += col->coef * col->prim; } #if 1 /* compute primal values of inactive rows */ for (i = 1; i <= orig->m; i++) { row = orig->row[i]; if (row->stat == GLP_BS) { GLPAIJ *aij; double temp; temp = 0.0; for (aij = row->ptr; aij != NULL; aij = aij->r_next) temp += aij->val * aij->col->prim; row->prim = temp; } } /* compute reduced costs of active columns */ for (j = 1; j <= orig->n; j++) { col = orig->col[j]; if (col->stat != GLP_BS) { GLPAIJ *aij; double temp; temp = col->coef; for (aij = col->ptr; aij != NULL; aij = aij->c_next) temp -= aij->val * aij->row->dual; col->dual = temp; } } #endif } else if (npp->sol == GLP_IPT) { /* store interior-point solution */ orig->ipt_stat = npp->t_stat; orig->ipt_obj = orig->c0; for (i = 1; i <= orig->m; i++) { row = orig->row[i]; if (!npp->scaling) { /*row->pval = npp->r_prim[i];*/ row->dval = dir * npp->r_pi[i]; } else { /*row->pval = npp->r_prim[i] / row->rii;*/ row->dval = dir * npp->r_pi[i] * row->rii; } } for (j = 1; j <= orig->n; j++) { col = orig->col[j]; if (!npp->scaling) { col->pval = npp->c_value[j]; /*col->dval = dir * npp->c_dual[j];*/ } else { col->pval = npp->c_value[j] * col->sjj; /*col->dval = dir * npp->c_dual[j] / col->sjj;*/ } orig->ipt_obj += col->coef * col->pval; } #if 1 /* compute row primal values */ for (i = 1; i <= orig->m; i++) { row = orig->row[i]; { GLPAIJ *aij; double temp; temp = 0.0; for (aij = row->ptr; aij != NULL; aij = aij->r_next) temp += aij->val * aij->col->pval; row->pval = temp; } } /* compute column dual values */ for (j = 1; j <= orig->n; j++) { col = orig->col[j]; { GLPAIJ *aij; double temp; temp = col->coef; for (aij = col->ptr; aij != NULL; aij = aij->c_next) temp -= aij->val * aij->row->dval; col->dval = temp; } } #endif } else if (npp->sol == GLP_MIP) { /* store MIP solution */ xassert(!npp->scaling); orig->mip_stat = npp->i_stat; orig->mip_obj = orig->c0; #if 0 for (i = 1; i <= orig->m; i++) { row = orig->row[i]; /*row->mipx = npp->r_prim[i];*/ } #endif for (j = 1; j <= orig->n; j++) { col = orig->col[j]; col->mipx = npp->c_value[j]; if (col->kind == GLP_IV) xassert(col->mipx == floor(col->mipx)); orig->mip_obj += col->coef * col->mipx; } #if 1 /* compute row primal values */ for (i = 1; i <= orig->m; i++) { row = orig->row[i]; { GLPAIJ *aij; double temp; temp = 0.0; for (aij = row->ptr; aij != NULL; aij = aij->r_next) temp += aij->val * aij->col->mipx; row->mipx = temp; } } #endif } else xassert(npp != npp); return; } void npp_delete_wksp(NPP *npp) { /* delete LP/MIP preprocessor workspace */ if (npp->pool != NULL) dmp_delete_pool(npp->pool); if (npp->stack != NULL) dmp_delete_pool(npp->stack); if (npp->row_ref != NULL) xfree(npp->row_ref); if (npp->col_ref != NULL) xfree(npp->col_ref); if (npp->r_stat != NULL) xfree(npp->r_stat); #if 0 if (npp->r_prim != NULL) xfree(npp->r_prim); #endif if (npp->r_pi != NULL) xfree(npp->r_pi); if (npp->c_stat != NULL) xfree(npp->c_stat); if (npp->c_value != NULL) xfree(npp->c_value); #if 0 if (npp->c_dual != NULL) xfree(npp->c_dual); #endif xfree(npp); return; } /* eof */ praat-6.0.04/external/glpk/glpnpp02.c000066400000000000000000001262341261542461700173150ustar00rootroot00000000000000/* glpnpp02.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpnpp.h" /*********************************************************************** * NAME * * npp_free_row - process free (unbounded) row * * SYNOPSIS * * #include "glpnpp.h" * void npp_free_row(NPP *npp, NPPROW *p); * * DESCRIPTION * * The routine npp_free_row processes row p, which is free (i.e. has * no finite bounds): * * -inf < sum a[p,j] x[j] < +inf. (1) * j * * PROBLEM TRANSFORMATION * * Constraint (1) cannot be active, so it is redundant and can be * removed from the original problem. * * Removing row p leads to removing a column of multiplier pi[p] for * this row in the dual system. Since row p has no bounds, pi[p] = 0, * so removing the column does not affect the dual solution. * * RECOVERING BASIC SOLUTION * * In solution to the original problem row p is inactive constraint, * so it is assigned status GLP_BS, and multiplier pi[p] is assigned * zero value. * * RECOVERING INTERIOR-POINT SOLUTION * * In solution to the original problem row p is inactive constraint, * so its multiplier pi[p] is assigned zero value. * * RECOVERING MIP SOLUTION * * None needed. */ struct free_row { /* free (unbounded) row */ int p; /* row reference number */ }; static int rcv_free_row(NPP *npp, void *info); void npp_free_row(NPP *npp, NPPROW *p) { /* process free (unbounded) row */ struct free_row *info; /* the row must be free */ xassert(p->lb == -DBL_MAX && p->ub == +DBL_MAX); /* create transformation stack entry */ info = npp_push_tse(npp, rcv_free_row, sizeof(struct free_row)); info->p = p->i; /* remove the row from the problem */ npp_del_row(npp, p); return; } static int rcv_free_row(NPP *npp, void *_info) { /* recover free (unbounded) row */ struct free_row *info = _info; if (npp->sol == GLP_SOL) npp->r_stat[info->p] = GLP_BS; if (npp->sol != GLP_MIP) npp->r_pi[info->p] = 0.0; return 0; } /*********************************************************************** * NAME * * npp_geq_row - process row of 'not less than' type * * SYNOPSIS * * #include "glpnpp.h" * void npp_geq_row(NPP *npp, NPPROW *p); * * DESCRIPTION * * The routine npp_geq_row processes row p, which is 'not less than' * inequality constraint: * * L[p] <= sum a[p,j] x[j] (<= U[p]), (1) * j * * where L[p] < U[p], and upper bound may not exist (U[p] = +oo). * * PROBLEM TRANSFORMATION * * Constraint (1) can be replaced by equality constraint: * * sum a[p,j] x[j] - s = L[p], (2) * j * * where * * 0 <= s (<= U[p] - L[p]) (3) * * is a non-negative surplus variable. * * Since in the primal system there appears column s having the only * non-zero coefficient in row p, in the dual system there appears a * new row: * * (-1) pi[p] + lambda = 0, (4) * * where (-1) is coefficient of column s in row p, pi[p] is multiplier * of row p, lambda is multiplier of column q, 0 is coefficient of * column s in the objective row. * * RECOVERING BASIC SOLUTION * * Status of row p in solution to the original problem is determined * by its status and status of column q in solution to the transformed * problem as follows: * * +--------------------------------------+------------------+ * | Transformed problem | Original problem | * +-----------------+--------------------+------------------+ * | Status of row p | Status of column s | Status of row p | * +-----------------+--------------------+------------------+ * | GLP_BS | GLP_BS | N/A | * | GLP_BS | GLP_NL | GLP_BS | * | GLP_BS | GLP_NU | GLP_BS | * | GLP_NS | GLP_BS | GLP_BS | * | GLP_NS | GLP_NL | GLP_NL | * | GLP_NS | GLP_NU | GLP_NU | * +-----------------+--------------------+------------------+ * * Value of row multiplier pi[p] in solution to the original problem * is the same as in solution to the transformed problem. * * 1. In solution to the transformed problem row p and column q cannot * be basic at the same time; otherwise the basis matrix would have * two linear dependent columns: unity column of auxiliary variable * of row p and unity column of variable s. * * 2. Though in the transformed problem row p is equality constraint, * it may be basic due to primal degenerate solution. * * RECOVERING INTERIOR-POINT SOLUTION * * Value of row multiplier pi[p] in solution to the original problem * is the same as in solution to the transformed problem. * * RECOVERING MIP SOLUTION * * None needed. */ struct ineq_row { /* inequality constraint row */ int p; /* row reference number */ int s; /* column reference number for slack/surplus variable */ }; static int rcv_geq_row(NPP *npp, void *info); void npp_geq_row(NPP *npp, NPPROW *p) { /* process row of 'not less than' type */ struct ineq_row *info; NPPCOL *s; /* the row must have lower bound */ xassert(p->lb != -DBL_MAX); xassert(p->lb < p->ub); /* create column for surplus variable */ s = npp_add_col(npp); s->lb = 0.0; s->ub = (p->ub == +DBL_MAX ? +DBL_MAX : p->ub - p->lb); /* and add it to the transformed problem */ npp_add_aij(npp, p, s, -1.0); /* create transformation stack entry */ info = npp_push_tse(npp, rcv_geq_row, sizeof(struct ineq_row)); info->p = p->i; info->s = s->j; /* replace the row by equality constraint */ p->ub = p->lb; return; } static int rcv_geq_row(NPP *npp, void *_info) { /* recover row of 'not less than' type */ struct ineq_row *info = _info; if (npp->sol == GLP_SOL) { if (npp->r_stat[info->p] == GLP_BS) { if (npp->c_stat[info->s] == GLP_BS) { npp_error(); return 1; } else if (npp->c_stat[info->s] == GLP_NL || npp->c_stat[info->s] == GLP_NU) npp->r_stat[info->p] = GLP_BS; else { npp_error(); return 1; } } else if (npp->r_stat[info->p] == GLP_NS) { if (npp->c_stat[info->s] == GLP_BS) npp->r_stat[info->p] = GLP_BS; else if (npp->c_stat[info->s] == GLP_NL) npp->r_stat[info->p] = GLP_NL; else if (npp->c_stat[info->s] == GLP_NU) npp->r_stat[info->p] = GLP_NU; else { npp_error(); return 1; } } else { npp_error(); return 1; } } return 0; } /*********************************************************************** * NAME * * npp_leq_row - process row of 'not greater than' type * * SYNOPSIS * * #include "glpnpp.h" * void npp_leq_row(NPP *npp, NPPROW *p); * * DESCRIPTION * * The routine npp_leq_row processes row p, which is 'not greater than' * inequality constraint: * * (L[p] <=) sum a[p,j] x[j] <= U[p], (1) * j * * where L[p] < U[p], and lower bound may not exist (L[p] = +oo). * * PROBLEM TRANSFORMATION * * Constraint (1) can be replaced by equality constraint: * * sum a[p,j] x[j] + s = L[p], (2) * j * * where * * 0 <= s (<= U[p] - L[p]) (3) * * is a non-negative slack variable. * * Since in the primal system there appears column s having the only * non-zero coefficient in row p, in the dual system there appears a * new row: * * (+1) pi[p] + lambda = 0, (4) * * where (+1) is coefficient of column s in row p, pi[p] is multiplier * of row p, lambda is multiplier of column q, 0 is coefficient of * column s in the objective row. * * RECOVERING BASIC SOLUTION * * Status of row p in solution to the original problem is determined * by its status and status of column q in solution to the transformed * problem as follows: * * +--------------------------------------+------------------+ * | Transformed problem | Original problem | * +-----------------+--------------------+------------------+ * | Status of row p | Status of column s | Status of row p | * +-----------------+--------------------+------------------+ * | GLP_BS | GLP_BS | N/A | * | GLP_BS | GLP_NL | GLP_BS | * | GLP_BS | GLP_NU | GLP_BS | * | GLP_NS | GLP_BS | GLP_BS | * | GLP_NS | GLP_NL | GLP_NU | * | GLP_NS | GLP_NU | GLP_NL | * +-----------------+--------------------+------------------+ * * Value of row multiplier pi[p] in solution to the original problem * is the same as in solution to the transformed problem. * * 1. In solution to the transformed problem row p and column q cannot * be basic at the same time; otherwise the basis matrix would have * two linear dependent columns: unity column of auxiliary variable * of row p and unity column of variable s. * * 2. Though in the transformed problem row p is equality constraint, * it may be basic due to primal degeneracy. * * RECOVERING INTERIOR-POINT SOLUTION * * Value of row multiplier pi[p] in solution to the original problem * is the same as in solution to the transformed problem. * * RECOVERING MIP SOLUTION * * None needed. */ static int rcv_leq_row(NPP *npp, void *info); void npp_leq_row(NPP *npp, NPPROW *p) { /* process row of 'not greater than' type */ struct ineq_row *info; NPPCOL *s; /* the row must have upper bound */ xassert(p->ub != +DBL_MAX); xassert(p->lb < p->ub); /* create column for slack variable */ s = npp_add_col(npp); s->lb = 0.0; s->ub = (p->lb == -DBL_MAX ? +DBL_MAX : p->ub - p->lb); /* and add it to the transformed problem */ npp_add_aij(npp, p, s, +1.0); /* create transformation stack entry */ info = npp_push_tse(npp, rcv_leq_row, sizeof(struct ineq_row)); info->p = p->i; info->s = s->j; /* replace the row by equality constraint */ p->lb = p->ub; return; } static int rcv_leq_row(NPP *npp, void *_info) { /* recover row of 'not greater than' type */ struct ineq_row *info = _info; if (npp->sol == GLP_SOL) { if (npp->r_stat[info->p] == GLP_BS) { if (npp->c_stat[info->s] == GLP_BS) { npp_error(); return 1; } else if (npp->c_stat[info->s] == GLP_NL || npp->c_stat[info->s] == GLP_NU) npp->r_stat[info->p] = GLP_BS; else { npp_error(); return 1; } } else if (npp->r_stat[info->p] == GLP_NS) { if (npp->c_stat[info->s] == GLP_BS) npp->r_stat[info->p] = GLP_BS; else if (npp->c_stat[info->s] == GLP_NL) npp->r_stat[info->p] = GLP_NU; else if (npp->c_stat[info->s] == GLP_NU) npp->r_stat[info->p] = GLP_NL; else { npp_error(); return 1; } } else { npp_error(); return 1; } } return 0; } /*********************************************************************** * NAME * * npp_free_col - process free (unbounded) column * * SYNOPSIS * * #include "glpnpp.h" * void npp_free_col(NPP *npp, NPPCOL *q); * * DESCRIPTION * * The routine npp_free_col processes column q, which is free (i.e. has * no finite bounds): * * -oo < x[q] < +oo. (1) * * PROBLEM TRANSFORMATION * * Free (unbounded) variable can be replaced by the difference of two * non-negative variables: * * x[q] = s' - s'', s', s'' >= 0. (2) * * Assuming that in the transformed problem x[q] becomes s', * transformation (2) causes new column s'' to appear, which differs * from column s' only in the sign of coefficients in constraint and * objective rows. Thus, if in the dual system the following row * corresponds to column s': * * sum a[i,q] pi[i] + lambda' = c[q], (3) * i * * the row which corresponds to column s'' is the following: * * sum (-a[i,q]) pi[i] + lambda'' = -c[q]. (4) * i * * Then from (3) and (4) it follows that: * * lambda' + lambda'' = 0 => lambda' = lmabda'' = 0, (5) * * where lambda' and lambda'' are multipliers for columns s' and s'', * resp. * * RECOVERING BASIC SOLUTION * * With respect to (5) status of column q in solution to the original * problem is determined by statuses of columns s' and s'' in solution * to the transformed problem as follows: * * +--------------------------------------+------------------+ * | Transformed problem | Original problem | * +------------------+-------------------+------------------+ * | Status of col s' | Status of col s'' | Status of col q | * +------------------+-------------------+------------------+ * | GLP_BS | GLP_BS | N/A | * | GLP_BS | GLP_NL | GLP_BS | * | GLP_NL | GLP_BS | GLP_BS | * | GLP_NL | GLP_NL | GLP_NF | * +------------------+-------------------+------------------+ * * Value of column q is computed with formula (2). * * 1. In solution to the transformed problem columns s' and s'' cannot * be basic at the same time, because they differ only in the sign, * hence, are linear dependent. * * 2. Though column q is free, it can be non-basic due to dual * degeneracy. * * 3. If column q is integral, columns s' and s'' are also integral. * * RECOVERING INTERIOR-POINT SOLUTION * * Value of column q is computed with formula (2). * * RECOVERING MIP SOLUTION * * Value of column q is computed with formula (2). */ struct free_col { /* free (unbounded) column */ int q; /* column reference number for variables x[q] and s' */ int s; /* column reference number for variable s'' */ }; static int rcv_free_col(NPP *npp, void *info); void npp_free_col(NPP *npp, NPPCOL *q) { /* process free (unbounded) column */ struct free_col *info; NPPCOL *s; NPPAIJ *aij; /* the column must be free */ xassert(q->lb == -DBL_MAX && q->ub == +DBL_MAX); /* variable x[q] becomes s' */ q->lb = 0.0, q->ub = +DBL_MAX; /* create variable s'' */ s = npp_add_col(npp); s->is_int = q->is_int; s->lb = 0.0, s->ub = +DBL_MAX; /* duplicate objective coefficient */ s->coef = -q->coef; /* duplicate column of the constraint matrix */ for (aij = q->ptr; aij != NULL; aij = aij->c_next) npp_add_aij(npp, aij->row, s, -aij->val); /* create transformation stack entry */ info = npp_push_tse(npp, rcv_free_col, sizeof(struct free_col)); info->q = q->j; info->s = s->j; return; } static int rcv_free_col(NPP *npp, void *_info) { /* recover free (unbounded) column */ struct free_col *info = _info; if (npp->sol == GLP_SOL) { if (npp->c_stat[info->q] == GLP_BS) { if (npp->c_stat[info->s] == GLP_BS) { npp_error(); return 1; } else if (npp->c_stat[info->s] == GLP_NL) npp->c_stat[info->q] = GLP_BS; else { npp_error(); return -1; } } else if (npp->c_stat[info->q] == GLP_NL) { if (npp->c_stat[info->s] == GLP_BS) npp->c_stat[info->q] = GLP_BS; else if (npp->c_stat[info->s] == GLP_NL) npp->c_stat[info->q] = GLP_NF; else { npp_error(); return -1; } } else { npp_error(); return -1; } } /* compute value of x[q] with formula (2) */ npp->c_value[info->q] -= npp->c_value[info->s]; return 0; } /*********************************************************************** * NAME * * npp_lbnd_col - process column with (non-zero) lower bound * * SYNOPSIS * * #include "glpnpp.h" * void npp_lbnd_col(NPP *npp, NPPCOL *q); * * DESCRIPTION * * The routine npp_lbnd_col processes column q, which has (non-zero) * lower bound: * * l[q] <= x[q] (<= u[q]), (1) * * where l[q] < u[q], and upper bound may not exist (u[q] = +oo). * * PROBLEM TRANSFORMATION * * Column q can be replaced as follows: * * x[q] = l[q] + s, (2) * * where * * 0 <= s (<= u[q] - l[q]) (3) * * is a non-negative variable. * * Substituting x[q] from (2) into the objective row, we have: * * z = sum c[j] x[j] + c0 = * j * * = sum c[j] x[j] + c[q] x[q] + c0 = * j!=q * * = sum c[j] x[j] + c[q] (l[q] + s) + c0 = * j!=q * * = sum c[j] x[j] + c[q] s + c~0, * * where * * c~0 = c0 + c[q] l[q] (4) * * is the constant term of the objective in the transformed problem. * Similarly, substituting x[q] into constraint row i, we have: * * L[i] <= sum a[i,j] x[j] <= U[i] ==> * j * * L[i] <= sum a[i,j] x[j] + a[i,q] x[q] <= U[i] ==> * j!=q * * L[i] <= sum a[i,j] x[j] + a[i,q] (l[q] + s) <= U[i] ==> * j!=q * * L~[i] <= sum a[i,j] x[j] + a[i,q] s <= U~[i], * j!=q * * where * * L~[i] = L[i] - a[i,q] l[q], U~[i] = U[i] - a[i,q] l[q] (5) * * are lower and upper bounds of row i in the transformed problem, * resp. * * Transformation (2) does not affect the dual system. * * RECOVERING BASIC SOLUTION * * Status of column q in solution to the original problem is the same * as in solution to the transformed problem (GLP_BS, GLP_NL or GLP_NU). * Value of column q is computed with formula (2). * * RECOVERING INTERIOR-POINT SOLUTION * * Value of column q is computed with formula (2). * * RECOVERING MIP SOLUTION * * Value of column q is computed with formula (2). */ struct bnd_col { /* bounded column */ int q; /* column reference number for variables x[q] and s */ double bnd; /* lower/upper bound l[q] or u[q] */ }; static int rcv_lbnd_col(NPP *npp, void *info); void npp_lbnd_col(NPP *npp, NPPCOL *q) { /* process column with (non-zero) lower bound */ struct bnd_col *info; NPPROW *i; NPPAIJ *aij; /* the column must have non-zero lower bound */ xassert(q->lb != 0.0); xassert(q->lb != -DBL_MAX); xassert(q->lb < q->ub); /* create transformation stack entry */ info = npp_push_tse(npp, rcv_lbnd_col, sizeof(struct bnd_col)); info->q = q->j; info->bnd = q->lb; /* substitute x[q] into objective row */ npp->c0 += q->coef * q->lb; /* substitute x[q] into constraint rows */ for (aij = q->ptr; aij != NULL; aij = aij->c_next) { i = aij->row; if (i->lb == i->ub) i->ub = (i->lb -= aij->val * q->lb); else { if (i->lb != -DBL_MAX) i->lb -= aij->val * q->lb; if (i->ub != +DBL_MAX) i->ub -= aij->val * q->lb; } } /* column x[q] becomes column s */ if (q->ub != +DBL_MAX) q->ub -= q->lb; q->lb = 0.0; return; } static int rcv_lbnd_col(NPP *npp, void *_info) { /* recover column with (non-zero) lower bound */ struct bnd_col *info = _info; if (npp->sol == GLP_SOL) { if (npp->c_stat[info->q] == GLP_BS || npp->c_stat[info->q] == GLP_NL || npp->c_stat[info->q] == GLP_NU) npp->c_stat[info->q] = npp->c_stat[info->q]; else { npp_error(); return 1; } } /* compute value of x[q] with formula (2) */ npp->c_value[info->q] = info->bnd + npp->c_value[info->q]; return 0; } /*********************************************************************** * NAME * * npp_ubnd_col - process column with upper bound * * SYNOPSIS * * #include "glpnpp.h" * void npp_ubnd_col(NPP *npp, NPPCOL *q); * * DESCRIPTION * * The routine npp_ubnd_col processes column q, which has upper bound: * * (l[q] <=) x[q] <= u[q], (1) * * where l[q] < u[q], and lower bound may not exist (l[q] = -oo). * * PROBLEM TRANSFORMATION * * Column q can be replaced as follows: * * x[q] = u[q] - s, (2) * * where * * 0 <= s (<= u[q] - l[q]) (3) * * is a non-negative variable. * * Substituting x[q] from (2) into the objective row, we have: * * z = sum c[j] x[j] + c0 = * j * * = sum c[j] x[j] + c[q] x[q] + c0 = * j!=q * * = sum c[j] x[j] + c[q] (u[q] - s) + c0 = * j!=q * * = sum c[j] x[j] - c[q] s + c~0, * * where * * c~0 = c0 + c[q] u[q] (4) * * is the constant term of the objective in the transformed problem. * Similarly, substituting x[q] into constraint row i, we have: * * L[i] <= sum a[i,j] x[j] <= U[i] ==> * j * * L[i] <= sum a[i,j] x[j] + a[i,q] x[q] <= U[i] ==> * j!=q * * L[i] <= sum a[i,j] x[j] + a[i,q] (u[q] - s) <= U[i] ==> * j!=q * * L~[i] <= sum a[i,j] x[j] - a[i,q] s <= U~[i], * j!=q * * where * * L~[i] = L[i] - a[i,q] u[q], U~[i] = U[i] - a[i,q] u[q] (5) * * are lower and upper bounds of row i in the transformed problem, * resp. * * Note that in the transformed problem coefficients c[q] and a[i,q] * change their sign. Thus, the row of the dual system corresponding to * column q: * * sum a[i,q] pi[i] + lambda[q] = c[q] (6) * i * * in the transformed problem becomes the following: * * sum (-a[i,q]) pi[i] + lambda[s] = -c[q]. (7) * i * * Therefore: * * lambda[q] = - lambda[s], (8) * * where lambda[q] is multiplier for column q, lambda[s] is multiplier * for column s. * * RECOVERING BASIC SOLUTION * * With respect to (8) status of column q in solution to the original * problem is determined by status of column s in solution to the * transformed problem as follows: * * +-----------------------+--------------------+ * | Status of column s | Status of column q | * | (transformed problem) | (original problem) | * +-----------------------+--------------------+ * | GLP_BS | GLP_BS | * | GLP_NL | GLP_NU | * | GLP_NU | GLP_NL | * +-----------------------+--------------------+ * * Value of column q is computed with formula (2). * * RECOVERING INTERIOR-POINT SOLUTION * * Value of column q is computed with formula (2). * * RECOVERING MIP SOLUTION * * Value of column q is computed with formula (2). */ static int rcv_ubnd_col(NPP *npp, void *info); void npp_ubnd_col(NPP *npp, NPPCOL *q) { /* process column with upper bound */ struct bnd_col *info; NPPROW *i; NPPAIJ *aij; /* the column must have upper bound */ xassert(q->ub != +DBL_MAX); xassert(q->lb < q->ub); /* create transformation stack entry */ info = npp_push_tse(npp, rcv_ubnd_col, sizeof(struct bnd_col)); info->q = q->j; info->bnd = q->ub; /* substitute x[q] into objective row */ npp->c0 += q->coef * q->ub; q->coef = -q->coef; /* substitute x[q] into constraint rows */ for (aij = q->ptr; aij != NULL; aij = aij->c_next) { i = aij->row; if (i->lb == i->ub) i->ub = (i->lb -= aij->val * q->ub); else { if (i->lb != -DBL_MAX) i->lb -= aij->val * q->ub; if (i->ub != +DBL_MAX) i->ub -= aij->val * q->ub; } aij->val = -aij->val; } /* column x[q] becomes column s */ if (q->lb != -DBL_MAX) q->ub -= q->lb; else q->ub = +DBL_MAX; q->lb = 0.0; return; } static int rcv_ubnd_col(NPP *npp, void *_info) { /* recover column with upper bound */ struct bnd_col *info = _info; if (npp->sol == GLP_BS) { if (npp->c_stat[info->q] == GLP_BS) npp->c_stat[info->q] = GLP_BS; else if (npp->c_stat[info->q] == GLP_NL) npp->c_stat[info->q] = GLP_NU; else if (npp->c_stat[info->q] == GLP_NU) npp->c_stat[info->q] = GLP_NL; else { npp_error(); return 1; } } /* compute value of x[q] with formula (2) */ npp->c_value[info->q] = info->bnd - npp->c_value[info->q]; return 0; } /*********************************************************************** * NAME * * npp_dbnd_col - process non-negative column with upper bound * * SYNOPSIS * * #include "glpnpp.h" * void npp_dbnd_col(NPP *npp, NPPCOL *q); * * DESCRIPTION * * The routine npp_dbnd_col processes column q, which is non-negative * and has upper bound: * * 0 <= x[q] <= u[q], (1) * * where u[q] > 0. * * PROBLEM TRANSFORMATION * * Upper bound of column q can be replaced by the following equality * constraint: * * x[q] + s = u[q], (2) * * where s >= 0 is a non-negative complement variable. * * Since in the primal system along with new row (2) there appears a * new column s having the only non-zero coefficient in this row, in * the dual system there appears a new row: * * (+1)pi + lambda[s] = 0, (3) * * where (+1) is coefficient at column s in row (2), pi is multiplier * for row (2), lambda[s] is multiplier for column s, 0 is coefficient * at column s in the objective row. * * RECOVERING BASIC SOLUTION * * Status of column q in solution to the original problem is determined * by its status and status of column s in solution to the transformed * problem as follows: * * +-----------------------------------+------------------+ * | Transformed problem | Original problem | * +-----------------+-----------------+------------------+ * | Status of col q | Status of col s | Status of col q | * +-----------------+-----------------+------------------+ * | GLP_BS | GLP_BS | GLP_BS | * | GLP_BS | GLP_NL | GLP_NU | * | GLP_NL | GLP_BS | GLP_NL | * | GLP_NL | GLP_NL | GLP_NL (*) | * +-----------------+-----------------+------------------+ * * Value of column q in solution to the original problem is the same as * in solution to the transformed problem. * * 1. Formally, in solution to the transformed problem columns q and s * cannot be non-basic at the same time, since the constraint (2) * would be violated. However, if u[q] is close to zero, violation * may be less than a working precision even if both columns q and s * are non-basic. In this degenerate case row (2) can be only basic, * i.e. non-active constraint (otherwise corresponding row of the * basis matrix would be zero). This allows to pivot out auxiliary * variable and pivot in column s, in which case the row becomes * active while column s becomes basic. * * 2. If column q is integral, column s is also integral. * * RECOVERING INTERIOR-POINT SOLUTION * * Value of column q in solution to the original problem is the same as * in solution to the transformed problem. * * RECOVERING MIP SOLUTION * * Value of column q in solution to the original problem is the same as * in solution to the transformed problem. */ struct dbnd_col { /* double-bounded column */ int q; /* column reference number for variable x[q] */ int s; /* column reference number for complement variable s */ }; static int rcv_dbnd_col(NPP *npp, void *info); void npp_dbnd_col(NPP *npp, NPPCOL *q) { /* process non-negative column with upper bound */ struct dbnd_col *info; NPPROW *p; NPPCOL *s; /* the column must be non-negative with upper bound */ xassert(q->lb == 0.0); xassert(q->ub > 0.0); xassert(q->ub != +DBL_MAX); /* create variable s */ s = npp_add_col(npp); s->is_int = q->is_int; s->lb = 0.0, s->ub = +DBL_MAX; /* create equality constraint (2) */ p = npp_add_row(npp); p->lb = p->ub = q->ub; npp_add_aij(npp, p, q, +1.0); npp_add_aij(npp, p, s, +1.0); /* create transformation stack entry */ info = npp_push_tse(npp, rcv_dbnd_col, sizeof(struct dbnd_col)); info->q = q->j; info->s = s->j; /* remove upper bound of x[q] */ q->ub = +DBL_MAX; return; } static int rcv_dbnd_col(NPP *npp, void *_info) { /* recover non-negative column with upper bound */ struct dbnd_col *info = _info; if (npp->sol == GLP_BS) { if (npp->c_stat[info->q] == GLP_BS) { if (npp->c_stat[info->s] == GLP_BS) npp->c_stat[info->q] = GLP_BS; else if (npp->c_stat[info->s] == GLP_NL) npp->c_stat[info->q] = GLP_NU; else { npp_error(); return 1; } } else if (npp->c_stat[info->q] == GLP_NL) { if (npp->c_stat[info->s] == GLP_BS || npp->c_stat[info->s] == GLP_NL) npp->c_stat[info->q] = GLP_NL; else { npp_error(); return 1; } } else { npp_error(); return 1; } } return 0; } /*********************************************************************** * NAME * * npp_fixed_col - process fixed column * * SYNOPSIS * * #include "glpnpp.h" * void npp_fixed_col(NPP *npp, NPPCOL *q); * * DESCRIPTION * * The routine npp_fixed_col processes column q, which is fixed: * * x[q] = s[q], (1) * * where s[q] is a fixed column value. * * PROBLEM TRANSFORMATION * * The value of a fixed column can be substituted into the objective * and constraint rows that allows removing the column from the problem. * * Substituting x[q] = s[q] into the objective row, we have: * * z = sum c[j] x[j] + c0 = * j * * = sum c[j] x[j] + c[q] x[q] + c0 = * j!=q * * = sum c[j] x[j] + c[q] s[q] + c0 = * j!=q * * = sum c[j] x[j] + c~0, * j!=q * * where * * c~0 = c0 + c[q] s[q] (2) * * is the constant term of the objective in the transformed problem. * Similarly, substituting x[q] = s[q] into constraint row i, we have: * * L[i] <= sum a[i,j] x[j] <= U[i] ==> * j * * L[i] <= sum a[i,j] x[j] + a[i,q] x[q] <= U[i] ==> * j!=q * * L[i] <= sum a[i,j] x[j] + a[i,q] s[q] <= U[i] ==> * j!=q * * L~[i] <= sum a[i,j] x[j] + a[i,q] s <= U~[i], * j!=q * * where * * L~[i] = L[i] - a[i,q] s[q], U~[i] = U[i] - a[i,q] s[q] (3) * * are lower and upper bounds of row i in the transformed problem, * resp. * * RECOVERING BASIC SOLUTION * * Column q is assigned status GLP_NS and its value is assigned s[q]. * * RECOVERING INTERIOR-POINT SOLUTION * * Value of column q is assigned s[q]. * * RECOVERING MIP SOLUTION * * Value of column q is assigned s[q]. */ struct fixed_col { /* fixed column */ int q; /* column reference number for variable x[q] */ double s; /* value, at which x[q] is fixed */ }; static int rcv_fixed_col(NPP *npp, void *info); void npp_fixed_col(NPP *npp, NPPCOL *q) { /* process fixed column */ struct fixed_col *info; NPPROW *i; NPPAIJ *aij; /* the column must be fixed */ xassert(q->lb == q->ub); /* create transformation stack entry */ info = npp_push_tse(npp, rcv_fixed_col, sizeof(struct fixed_col)); info->q = q->j; info->s = q->lb; /* substitute x[q] = s[q] into objective row */ npp->c0 += q->coef * q->lb; /* substitute x[q] = s[q] into constraint rows */ for (aij = q->ptr; aij != NULL; aij = aij->c_next) { i = aij->row; if (i->lb == i->ub) i->ub = (i->lb -= aij->val * q->lb); else { if (i->lb != -DBL_MAX) i->lb -= aij->val * q->lb; if (i->ub != +DBL_MAX) i->ub -= aij->val * q->lb; } } /* remove the column from the problem */ npp_del_col(npp, q); return; } static int rcv_fixed_col(NPP *npp, void *_info) { /* recover fixed column */ struct fixed_col *info = _info; if (npp->sol == GLP_SOL) npp->c_stat[info->q] = GLP_NS; npp->c_value[info->q] = info->s; return 0; } /*********************************************************************** * NAME * * npp_make_equality - process row with almost identical bounds * * SYNOPSIS * * #include "glpnpp.h" * int npp_make_equality(NPP *npp, NPPROW *p); * * DESCRIPTION * * The routine npp_make_equality processes row p: * * L[p] <= sum a[p,j] x[j] <= U[p], (1) * j * * where -oo < L[p] < U[p] < +oo, i.e. which is double-sided inequality * constraint. * * RETURNS * * 0 - row bounds have not been changed; * * 1 - row has been replaced by equality constraint. * * PROBLEM TRANSFORMATION * * If bounds of row (1) are very close to each other: * * U[p] - L[p] <= eps, (2) * * where eps is an absolute tolerance for row value, the row can be * replaced by the following almost equivalent equiality constraint: * * sum a[p,j] x[j] = b, (3) * j * * where b = (L[p] + U[p]) / 2. If the right-hand side in (3) happens * to be very close to its nearest integer: * * |b - floor(b + 0.5)| <= eps, (4) * * it is reasonable to use this nearest integer as the right-hand side. * * RECOVERING BASIC SOLUTION * * Status of row p in solution to the original problem is determined * by its status and the sign of its multiplier pi[p] in solution to * the transformed problem as follows: * * +-----------------------+---------+--------------------+ * | Status of row p | Sign of | Status of row p | * | (transformed problem) | pi[p] | (original problem) | * +-----------------------+---------+--------------------+ * | GLP_BS | + / - | GLP_BS | * | GLP_NS | + | GLP_NL | * | GLP_NS | - | GLP_NU | * +-----------------------+---------+--------------------+ * * Value of row multiplier pi[p] in solution to the original problem is * the same as in solution to the transformed problem. * * RECOVERING INTERIOR POINT SOLUTION * * Value of row multiplier pi[p] in solution to the original problem is * the same as in solution to the transformed problem. * * RECOVERING MIP SOLUTION * * None needed. */ struct make_equality { /* row with almost identical bounds */ int p; /* row reference number */ }; static int rcv_make_equality(NPP *npp, void *info); int npp_make_equality(NPP *npp, NPPROW *p) { /* process row with almost identical bounds */ struct make_equality *info; double b, eps, nint; /* the row must be double-sided inequality */ xassert(p->lb != -DBL_MAX); xassert(p->ub != +DBL_MAX); xassert(p->lb < p->ub); /* check row bounds */ eps = 1e-9 + 1e-12 * fabs(p->lb); if (p->ub - p->lb > eps) return 0; /* row bounds are very close to each other */ /* create transformation stack entry */ info = npp_push_tse(npp, rcv_make_equality, sizeof(struct make_equality)); info->p = p->i; /* compute right-hand side */ b = 0.5 * (p->ub + p->lb); nint = floor(b + 0.5); if (fabs(b - nint) <= eps) b = nint; /* replace row p by almost equivalent equality constraint */ p->lb = p->ub = b; return 1; } int rcv_make_equality(NPP *npp, void *_info) { /* recover row with almost identical bounds */ struct make_equality *info = _info; if (npp->sol == GLP_SOL) { if (npp->r_stat[info->p] == GLP_BS) npp->r_stat[info->p] = GLP_BS; else if (npp->r_stat[info->p] == GLP_NS) { if (npp->r_pi[info->p] >= 0.0) npp->r_stat[info->p] = GLP_NL; else npp->r_stat[info->p] = GLP_NU; } else { npp_error(); return 1; } } return 0; } /*********************************************************************** * NAME * * npp_make_fixed - process column with almost identical bounds * * SYNOPSIS * * #include "glpnpp.h" * int npp_make_fixed(NPP *npp, NPPCOL *q); * * DESCRIPTION * * The routine npp_make_fixed processes column q: * * l[q] <= x[q] <= u[q], (1) * * where -oo < l[q] < u[q] < +oo, i.e. which has both lower and upper * bounds. * * RETURNS * * 0 - column bounds have not been changed; * * 1 - column has been fixed. * * PROBLEM TRANSFORMATION * * If bounds of column (1) are very close to each other: * * u[q] - l[q] <= eps, (2) * * where eps is an absolute tolerance for column value, the column can * be fixed: * * x[q] = s[q], (3) * * where s[q] = (l[q] + u[q]) / 2. And if the fixed column value s[q] * happens to be very close to its nearest integer: * * |s[q] - floor(s[q] + 0.5)| <= eps, (4) * * it is reasonable to use this nearest integer as the fixed value. * * RECOVERING BASIC SOLUTION * * In the dual system of the original (as well as transformed) problem * column q corresponds to the following row: * * sum a[i,q] pi[i] + lambda[q] = c[q]. (5) * i * * Since multipliers pi[i] are known for all rows from solution to the * transformed problem, formula (5) allows computing value of multiplier * (reduced cost) for column q: * * lambda[q] = c[q] - sum a[i,q] pi[i]. (6) * i * * Status of column q in solution to the original problem is determined * by its status and the sign of its multiplier lambda[q] in solution to * the transformed problem as follows: * * +-----------------------+-----------+--------------------+ * | Status of column q | Sign of | Status of column q | * | (transformed problem) | lambda[q] | (original problem) | * +-----------------------+-----------+--------------------+ * | GLP_BS | + / - | GLP_BS | * | GLP_NS | + | GLP_NL | * | GLP_NS | - | GLP_NU | * +-----------------------+-----------+--------------------+ * * Value of column q in solution to the original problem is the same as * in solution to the transformed problem. * * RECOVERING INTERIOR POINT SOLUTION * * Value of column q in solution to the original problem is the same as * in solution to the transformed problem. * * RECOVERING MIP SOLUTION * * None needed. */ struct make_fixed { /* column with almost identical bounds */ int q; /* column reference number */ double c; /* objective coefficient at x[q] */ NPPLFE *ptr; /* list of non-zero coefficients a[i,q] */ }; static int rcv_make_fixed(NPP *npp, void *info); int npp_make_fixed(NPP *npp, NPPCOL *q) { /* process column with almost identical bounds */ struct make_fixed *info; NPPAIJ *aij; NPPLFE *lfe; double s, eps, nint; /* the column must be double-bounded */ xassert(q->lb != -DBL_MAX); xassert(q->ub != +DBL_MAX); xassert(q->lb < q->ub); /* check column bounds */ eps = 1e-9 + 1e-12 * fabs(q->lb); if (q->ub - q->lb > eps) return 0; /* column bounds are very close to each other */ /* create transformation stack entry */ info = npp_push_tse(npp, rcv_make_fixed, sizeof(struct make_fixed)); info->q = q->j; info->c = q->coef; info->ptr = NULL; /* save column coefficients a[i,q] (needed for basic solution only) */ if (npp->sol == GLP_SOL) { for (aij = q->ptr; aij != NULL; aij = aij->c_next) { lfe = dmp_get_atom(npp->stack, sizeof(NPPLFE)); lfe->ref = aij->row->i; lfe->val = aij->val; lfe->next = info->ptr; info->ptr = lfe; } } /* compute column fixed value */ s = 0.5 * (q->ub + q->lb); nint = floor(s + 0.5); if (fabs(s - nint) <= eps) s = nint; /* make column q fixed */ q->lb = q->ub = s; return 1; } static int rcv_make_fixed(NPP *npp, void *_info) { /* recover column with almost identical bounds */ struct make_fixed *info = _info; NPPLFE *lfe; double lambda; if (npp->sol == GLP_SOL) { if (npp->c_stat[info->q] == GLP_BS) npp->c_stat[info->q] = GLP_BS; else if (npp->c_stat[info->q] == GLP_NS) { /* compute multiplier for column q with formula (6) */ lambda = info->c; for (lfe = info->ptr; lfe != NULL; lfe = lfe->next) lambda -= lfe->val * npp->r_pi[lfe->ref]; /* assign status to non-basic column */ if (lambda >= 0.0) npp->c_stat[info->q] = GLP_NL; else npp->c_stat[info->q] = GLP_NU; } else { npp_error(); return 1; } } return 0; } /* eof */ praat-6.0.04/external/glpk/glpnpp03.c000066400000000000000000003007471261542461700173210ustar00rootroot00000000000000/* glpnpp03.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpnpp.h" /*********************************************************************** * NAME * * npp_empty_row - process empty row * * SYNOPSIS * * #include "glpnpp.h" * int npp_empty_row(NPP *npp, NPPROW *p); * * DESCRIPTION * * The routine npp_empty_row processes row p, which is empty, i.e. * coefficients at all columns in this row are zero: * * L[p] <= sum 0 x[j] <= U[p], (1) * * where L[p] <= U[p]. * * RETURNS * * 0 - success; * * 1 - problem has no primal feasible solution. * * PROBLEM TRANSFORMATION * * If the following conditions hold: * * L[p] <= +eps, U[p] >= -eps, (2) * * where eps is an absolute tolerance for row value, the row p is * redundant. In this case it can be replaced by equivalent redundant * row, which is free (unbounded), and then removed from the problem. * Otherwise, the row p is infeasible and, thus, the problem has no * primal feasible solution. * * RECOVERING BASIC SOLUTION * * See the routine npp_free_row. * * RECOVERING INTERIOR-POINT SOLUTION * * See the routine npp_free_row. * * RECOVERING MIP SOLUTION * * None needed. */ int npp_empty_row(NPP *npp, NPPROW *p) { /* process empty row */ double eps = 1e-3; /* the row must be empty */ xassert(p->ptr == NULL); /* check primal feasibility */ if (p->lb > +eps || p->ub < -eps) return 1; /* replace the row by equivalent free (unbounded) row */ p->lb = -DBL_MAX, p->ub = +DBL_MAX; /* and process it */ npp_free_row(npp, p); return 0; } /*********************************************************************** * NAME * * npp_empty_col - process empty column * * SYNOPSIS * * #include "glpnpp.h" * int npp_empty_col(NPP *npp, NPPCOL *q); * * DESCRIPTION * * The routine npp_empty_col processes column q: * * l[q] <= x[q] <= u[q], (1) * * where l[q] <= u[q], which is empty, i.e. has zero coefficients in * all constraint rows. * * RETURNS * * 0 - success; * * 1 - problem has no dual feasible solution. * * PROBLEM TRANSFORMATION * * The row of the dual system corresponding to the empty column is the * following: * * sum 0 pi[i] + lambda[q] = c[q], (2) * i * * from which it follows that: * * lambda[q] = c[q]. (3) * * If the following condition holds: * * c[q] < - eps, (4) * * where eps is an absolute tolerance for column multiplier, the lower * column bound l[q] must be active to provide dual feasibility (note * that being preprocessed the problem is always minimization). In this * case the column can be fixed on its lower bound and removed from the * problem (if the column is integral, its bounds are also assumed to * be integral). And if the column has no lower bound (l[q] = -oo), the * problem has no dual feasible solution. * * If the following condition holds: * * c[q] > + eps, (5) * * the upper column bound u[q] must be active to provide dual * feasibility. In this case the column can be fixed on its upper bound * and removed from the problem. And if the column has no upper bound * (u[q] = +oo), the problem has no dual feasible solution. * * Finally, if the following condition holds: * * - eps <= c[q] <= +eps, (6) * * dual feasibility does not depend on a particular value of column q. * In this case the column can be fixed either on its lower bound (if * l[q] > -oo) or on its upper bound (if u[q] < +oo) or at zero (if the * column is unbounded) and then removed from the problem. * * RECOVERING BASIC SOLUTION * * See the routine npp_fixed_col. Having been recovered the column * is assigned status GLP_NS. However, if actually it is not fixed * (l[q] < u[q]), its status should be changed to GLP_NL, GLP_NU, or * GLP_NF depending on which bound it was fixed on transformation stage. * * RECOVERING INTERIOR-POINT SOLUTION * * See the routine npp_fixed_col. * * RECOVERING MIP SOLUTION * * See the routine npp_fixed_col. */ struct empty_col { /* empty column */ int q; /* column reference number */ char stat; /* status in basic solution */ }; static int rcv_empty_col(NPP *npp, void *info); int npp_empty_col(NPP *npp, NPPCOL *q) { /* process empty column */ struct empty_col *info; double eps = 1e-3; /* the column must be empty */ xassert(q->ptr == NULL); /* check dual feasibility */ if (q->coef > +eps && q->lb == -DBL_MAX) return 1; if (q->coef < -eps && q->ub == +DBL_MAX) return 1; /* create transformation stack entry */ info = npp_push_tse(npp, rcv_empty_col, sizeof(struct empty_col)); info->q = q->j; /* fix the column */ if (q->lb == -DBL_MAX && q->ub == +DBL_MAX) { /* free column */ info->stat = GLP_NF; q->lb = q->ub = 0.0; } else if (q->ub == +DBL_MAX) lo: { /* column with lower bound */ info->stat = GLP_NL; q->ub = q->lb; } else if (q->lb == -DBL_MAX) up: { /* column with upper bound */ info->stat = GLP_NU; q->lb = q->ub; } else if (q->lb != q->ub) { /* double-bounded column */ if (q->coef >= +DBL_EPSILON) goto lo; if (q->coef <= -DBL_EPSILON) goto up; if (fabs(q->lb) <= fabs(q->ub)) goto lo; else goto up; } else { /* fixed column */ info->stat = GLP_NS; } /* process fixed column */ npp_fixed_col(npp, q); return 0; } static int rcv_empty_col(NPP *npp, void *_info) { /* recover empty column */ struct empty_col *info = _info; if (npp->sol == GLP_SOL) npp->c_stat[info->q] = info->stat; return 0; } /*********************************************************************** * NAME * * npp_implied_value - process implied column value * * SYNOPSIS * * #include "glpnpp.h" * int npp_implied_value(NPP *npp, NPPCOL *q, double s); * * DESCRIPTION * * For column q: * * l[q] <= x[q] <= u[q], (1) * * where l[q] < u[q], the routine npp_implied_value processes its * implied value s[q]. If this implied value satisfies to the current * column bounds and integrality condition, the routine fixes column q * at the given point. Note that the column is kept in the problem in * any case. * * RETURNS * * 0 - column has been fixed; * * 1 - implied value violates to current column bounds; * * 2 - implied value violates integrality condition. * * ALGORITHM * * Implied column value s[q] satisfies to the current column bounds if * the following condition holds: * * l[q] - eps <= s[q] <= u[q] + eps, (2) * * where eps is an absolute tolerance for column value. If the column * is integral, the following condition also must hold: * * |s[q] - floor(s[q]+0.5)| <= eps, (3) * * where floor(s[q]+0.5) is the nearest integer to s[q]. * * If both condition (2) and (3) are satisfied, the column can be fixed * at the value s[q], or, if it is integral, at floor(s[q]+0.5). * Otherwise, if s[q] violates (2) or (3), the problem has no feasible * solution. * * Note: If s[q] is close to l[q] or u[q], it seems to be reasonable to * fix the column at its lower or upper bound, resp. rather than at the * implied value. */ int npp_implied_value(NPP *npp, NPPCOL *q, double s) { /* process implied column value */ double eps, nint; xassert(npp == npp); /* column must not be fixed */ xassert(q->lb < q->ub); /* check integrality */ if (q->is_int) { nint = floor(s + 0.5); if (fabs(s - nint) <= 1e-5) s = nint; else return 2; } /* check current column lower bound */ if (q->lb != -DBL_MAX) { eps = (q->is_int ? 1e-5 : 1e-5 + 1e-8 * fabs(q->lb)); if (s < q->lb - eps) return 1; /* if s[q] is close to l[q], fix column at its lower bound rather than at the implied value */ if (s < q->lb + 1e-3 * eps) { q->ub = q->lb; return 0; } } /* check current column upper bound */ if (q->ub != +DBL_MAX) { eps = (q->is_int ? 1e-5 : 1e-5 + 1e-8 * fabs(q->ub)); if (s > q->ub + eps) return 1; /* if s[q] is close to u[q], fix column at its upper bound rather than at the implied value */ if (s > q->ub - 1e-3 * eps) { q->lb = q->ub; return 0; } } /* fix column at the implied value */ q->lb = q->ub = s; return 0; } /*********************************************************************** * NAME * * npp_eq_singlet - process row singleton (equality constraint) * * SYNOPSIS * * #include "glpnpp.h" * int npp_eq_singlet(NPP *npp, NPPROW *p); * * DESCRIPTION * * The routine npp_eq_singlet processes row p, which is equiality * constraint having the only non-zero coefficient: * * a[p,q] x[q] = b. (1) * * RETURNS * * 0 - success; * * 1 - problem has no primal feasible solution; * * 2 - problem has no integer feasible solution. * * PROBLEM TRANSFORMATION * * The equality constraint defines implied value of column q: * * x[q] = s[q] = b / a[p,q]. (2) * * If the implied value s[q] satisfies to the column bounds (see the * routine npp_implied_value), the column can be fixed at s[q] and * removed from the problem. In this case row p becomes redundant, so * it can be replaced by equivalent free row and also removed from the * problem. * * Note that the routine removes from the problem only row p. Column q * becomes fixed, however, it is kept in the problem. * * RECOVERING BASIC SOLUTION * * In solution to the original problem row p is assigned status GLP_NS * (active equality constraint), and column q is assigned status GLP_BS * (basic column). * * Multiplier for row p can be computed as follows. In the dual system * of the original problem column q corresponds to the following row: * * sum a[i,q] pi[i] + lambda[q] = c[q] ==> * i * * sum a[i,q] pi[i] + a[p,q] pi[p] + lambda[q] = c[q]. * i!=p * * Therefore: * * 1 * pi[p] = ------ (c[q] - lambda[q] - sum a[i,q] pi[i]), (3) * a[p,q] i!=q * * where lambda[q] = 0 (since column[q] is basic), and pi[i] for all * i != p are known in solution to the transformed problem. * * Value of column q in solution to the original problem is assigned * its implied value s[q]. * * RECOVERING INTERIOR-POINT SOLUTION * * Multiplier for row p is computed with formula (3). Value of column * q is assigned its implied value s[q]. * * RECOVERING MIP SOLUTION * * Value of column q is assigned its implied value s[q]. */ struct eq_singlet { /* row singleton (equality constraint) */ int p; /* row reference number */ int q; /* column reference number */ double apq; /* constraint coefficient a[p,q] */ double c; /* objective coefficient at x[q] */ NPPLFE *ptr; /* list of non-zero coefficients a[i,q], i != p */ }; static int rcv_eq_singlet(NPP *npp, void *info); int npp_eq_singlet(NPP *npp, NPPROW *p) { /* process row singleton (equality constraint) */ struct eq_singlet *info; NPPCOL *q; NPPAIJ *aij; NPPLFE *lfe; int ret; double s; /* the row must be singleton equality constraint */ xassert(p->lb == p->ub); xassert(p->ptr != NULL && p->ptr->r_next == NULL); /* compute and process implied column value */ aij = p->ptr; q = aij->col; s = p->lb / aij->val; ret = npp_implied_value(npp, q, s); xassert(0 <= ret && ret <= 2); if (ret != 0) return ret; /* create transformation stack entry */ info = npp_push_tse(npp, rcv_eq_singlet, sizeof(struct eq_singlet)); info->p = p->i; info->q = q->j; info->apq = aij->val; info->c = q->coef; info->ptr = NULL; /* save column coefficients a[i,q], i != p (not needed for MIP solution) */ if (npp->sol != GLP_MIP) { for (aij = q->ptr; aij != NULL; aij = aij->c_next) { if (aij->row == p) continue; /* skip a[p,q] */ lfe = dmp_get_atom(npp->stack, sizeof(NPPLFE)); lfe->ref = aij->row->i; lfe->val = aij->val; lfe->next = info->ptr; info->ptr = lfe; } } /* remove the row from the problem */ npp_del_row(npp, p); return 0; } static int rcv_eq_singlet(NPP *npp, void *_info) { /* recover row singleton (equality constraint) */ struct eq_singlet *info = _info; NPPLFE *lfe; double temp; if (npp->sol == GLP_SOL) { /* column q must be already recovered as GLP_NS */ if (npp->c_stat[info->q] != GLP_NS) { npp_error(); return 1; } npp->r_stat[info->p] = GLP_NS; npp->c_stat[info->q] = GLP_BS; } if (npp->sol != GLP_MIP) { /* compute multiplier for row p with formula (3) */ temp = info->c; for (lfe = info->ptr; lfe != NULL; lfe = lfe->next) temp -= lfe->val * npp->r_pi[lfe->ref]; npp->r_pi[info->p] = temp / info->apq; } return 0; } /*********************************************************************** * NAME * * npp_implied_lower - process implied column lower bound * * SYNOPSIS * * #include "glpnpp.h" * int npp_implied_lower(NPP *npp, NPPCOL *q, double l); * * DESCRIPTION * * For column q: * * l[q] <= x[q] <= u[q], (1) * * where l[q] < u[q], the routine npp_implied_lower processes its * implied lower bound l'[q]. As the result the current column lower * bound may increase. Note that the column is kept in the problem in * any case. * * RETURNS * * 0 - current column lower bound has not changed; * * 1 - current column lower bound has changed, but not significantly; * * 2 - current column lower bound has significantly changed; * * 3 - column has been fixed on its upper bound; * * 4 - implied lower bound violates current column upper bound. * * ALGORITHM * * If column q is integral, before processing its implied lower bound * should be rounded up: * * ( floor(l'[q]+0.5), if |l'[q] - floor(l'[q]+0.5)| <= eps * l'[q] := < (2) * ( ceil(l'[q]), otherwise * * where floor(l'[q]+0.5) is the nearest integer to l'[q], ceil(l'[q]) * is smallest integer not less than l'[q], and eps is an absolute * tolerance for column value. * * Processing implied column lower bound l'[q] includes the following * cases: * * 1) if l'[q] < l[q] + eps, implied lower bound is redundant; * * 2) if l[q] + eps <= l[q] <= u[q] + eps, current column lower bound * l[q] can be strengthened by replacing it with l'[q]. If in this * case new column lower bound becomes close to current column upper * bound u[q], the column can be fixed on its upper bound; * * 3) if l'[q] > u[q] + eps, implied lower bound violates current * column upper bound u[q], in which case the problem has no primal * feasible solution. */ int npp_implied_lower(NPP *npp, NPPCOL *q, double l) { /* process implied column lower bound */ int ret; double eps, nint; xassert(npp == npp); /* column must not be fixed */ xassert(q->lb < q->ub); /* implied lower bound must be finite */ xassert(l != -DBL_MAX); /* if column is integral, round up l'[q] */ if (q->is_int) { nint = floor(l + 0.5); if (fabs(l - nint) <= 1e-5) l = nint; else l = ceil(l); } /* check current column lower bound */ if (q->lb != -DBL_MAX) { eps = (q->is_int ? 1e-3 : 1e-3 + 1e-6 * fabs(q->lb)); if (l < q->lb + eps) { ret = 0; /* redundant */ goto done; } } /* check current column upper bound */ if (q->ub != +DBL_MAX) { eps = (q->is_int ? 1e-5 : 1e-5 + 1e-8 * fabs(q->ub)); if (l > q->ub + eps) { ret = 4; /* infeasible */ goto done; } /* if l'[q] is close to u[q], fix column at its upper bound */ if (l > q->ub - 1e-3 * eps) { q->lb = q->ub; ret = 3; /* fixed */ goto done; } } /* check if column lower bound changes significantly */ if (q->lb == -DBL_MAX) ret = 2; /* significantly */ else if (q->is_int && l > q->lb + 0.5) ret = 2; /* significantly */ else if (l > q->lb + 0.30 * (1.0 + fabs(q->lb))) ret = 2; /* significantly */ else ret = 1; /* not significantly */ /* set new column lower bound */ q->lb = l; done: return ret; } /*********************************************************************** * NAME * * npp_implied_upper - process implied column upper bound * * SYNOPSIS * * #include "glpnpp.h" * int npp_implied_upper(NPP *npp, NPPCOL *q, double u); * * DESCRIPTION * * For column q: * * l[q] <= x[q] <= u[q], (1) * * where l[q] < u[q], the routine npp_implied_upper processes its * implied upper bound u'[q]. As the result the current column upper * bound may decrease. Note that the column is kept in the problem in * any case. * * RETURNS * * 0 - current column upper bound has not changed; * * 1 - current column upper bound has changed, but not significantly; * * 2 - current column upper bound has significantly changed; * * 3 - column has been fixed on its lower bound; * * 4 - implied upper bound violates current column lower bound. * * ALGORITHM * * If column q is integral, before processing its implied upper bound * should be rounded down: * * ( floor(u'[q]+0.5), if |u'[q] - floor(l'[q]+0.5)| <= eps * u'[q] := < (2) * ( floor(l'[q]), otherwise * * where floor(u'[q]+0.5) is the nearest integer to u'[q], * floor(u'[q]) is largest integer not greater than u'[q], and eps is * an absolute tolerance for column value. * * Processing implied column upper bound u'[q] includes the following * cases: * * 1) if u'[q] > u[q] - eps, implied upper bound is redundant; * * 2) if l[q] - eps <= u[q] <= u[q] - eps, current column upper bound * u[q] can be strengthened by replacing it with u'[q]. If in this * case new column upper bound becomes close to current column lower * bound, the column can be fixed on its lower bound; * * 3) if u'[q] < l[q] - eps, implied upper bound violates current * column lower bound l[q], in which case the problem has no primal * feasible solution. */ int npp_implied_upper(NPP *npp, NPPCOL *q, double u) { int ret; double eps, nint; xassert(npp == npp); /* column must not be fixed */ xassert(q->lb < q->ub); /* implied upper bound must be finite */ xassert(u != +DBL_MAX); /* if column is integral, round down u'[q] */ if (q->is_int) { nint = floor(u + 0.5); if (fabs(u - nint) <= 1e-5) u = nint; else u = floor(u); } /* check current column upper bound */ if (q->ub != +DBL_MAX) { eps = (q->is_int ? 1e-3 : 1e-3 + 1e-6 * fabs(q->ub)); if (u > q->ub - eps) { ret = 0; /* redundant */ goto done; } } /* check current column lower bound */ if (q->lb != -DBL_MAX) { eps = (q->is_int ? 1e-5 : 1e-5 + 1e-8 * fabs(q->lb)); if (u < q->lb - eps) { ret = 4; /* infeasible */ goto done; } /* if u'[q] is close to l[q], fix column at its lower bound */ if (u < q->lb + 1e-3 * eps) { q->ub = q->lb; ret = 3; /* fixed */ goto done; } } /* check if column upper bound changes significantly */ if (q->ub == +DBL_MAX) ret = 2; /* significantly */ else if (q->is_int && u < q->ub - 0.5) ret = 2; /* significantly */ else if (u < q->ub - 0.30 * (1.0 + fabs(q->ub))) ret = 2; /* significantly */ else ret = 1; /* not significantly */ /* set new column upper bound */ q->ub = u; done: return ret; } /*********************************************************************** * NAME * * npp_ineq_singlet - process row singleton (inequality constraint) * * SYNOPSIS * * #include "glpnpp.h" * int npp_ineq_singlet(NPP *npp, NPPROW *p); * * DESCRIPTION * * The routine npp_ineq_singlet processes row p, which is inequality * constraint having the only non-zero coefficient: * * L[p] <= a[p,q] * x[q] <= U[p], (1) * * where L[p] < U[p], L[p] > -oo and/or U[p] < +oo. * * RETURNS * * 0 - current column bounds have not changed; * * 1 - current column bounds have changed, but not significantly; * * 2 - current column bounds have significantly changed; * * 3 - column has been fixed on its lower or upper bound; * * 4 - problem has no primal feasible solution. * * PROBLEM TRANSFORMATION * * Inequality constraint (1) defines implied bounds of column q: * * ( L[p] / a[p,q], if a[p,q] > 0 * l'[q] = < (2) * ( U[p] / a[p,q], if a[p,q] < 0 * * ( U[p] / a[p,q], if a[p,q] > 0 * u'[q] = < (3) * ( L[p] / a[p,q], if a[p,q] < 0 * * If these implied bounds do not violate current bounds of column q: * * l[q] <= x[q] <= u[q], (4) * * they can be used to strengthen the current column bounds: * * l[q] := max(l[q], l'[q]), (5) * * u[q] := min(u[q], u'[q]). (6) * * (See the routines npp_implied_lower and npp_implied_upper.) * * Once bounds of row p (1) have been carried over column q, the row * becomes redundant, so it can be replaced by equivalent free row and * removed from the problem. * * Note that the routine removes from the problem only row p. Column q, * even it has been fixed, is kept in the problem. * * RECOVERING BASIC SOLUTION * * Note that the row in the dual system corresponding to column q is * the following: * * sum a[i,q] pi[i] + lambda[q] = c[q] ==> * i * (7) * sum a[i,q] pi[i] + a[p,q] pi[p] + lambda[q] = c[q], * i!=p * * where pi[i] for all i != p are known in solution to the transformed * problem. Row p does not exist in the transformed problem, so it has * zero multiplier there. This allows computing multiplier for column q * in solution to the transformed problem: * * lambda~[q] = c[q] - sum a[i,q] pi[i]. (8) * i!=p * * Let in solution to the transformed problem column q be non-basic * with lower bound active (GLP_NL, lambda~[q] >= 0), and this lower * bound be implied one l'[q]. From the original problem's standpoint * this then means that actually the original column lower bound l[q] * is inactive, and active is that row bound L[p] or U[p] that defines * the implied bound l'[q] (2). In this case in solution to the * original problem column q is assigned status GLP_BS while row p is * assigned status GLP_NL (if a[p,q] > 0) or GLP_NU (if a[p,q] < 0). * Since now column q is basic, its multiplier lambda[q] is zero. This * allows using (7) and (8) to find multiplier for row p in solution to * the original problem: * * 1 * pi[p] = ------ (c[q] - sum a[i,q] pi[i]) = lambda~[q] / a[p,q] (9) * a[p,q] i!=p * * Now let in solution to the transformed problem column q be non-basic * with upper bound active (GLP_NU, lambda~[q] <= 0), and this upper * bound be implied one u'[q]. As in the previous case this then means * that from the original problem's standpoint actually the original * column upper bound u[q] is inactive, and active is that row bound * L[p] or U[p] that defines the implied bound u'[q] (3). In this case * in solution to the original problem column q is assigned status * GLP_BS, row p is assigned status GLP_NU (if a[p,q] > 0) or GLP_NL * (if a[p,q] < 0), and its multiplier is computed with formula (9). * * Strengthening bounds of column q according to (5) and (6) may make * it fixed. Thus, if in solution to the transformed problem column q is * non-basic and fixed (GLP_NS), we can suppose that if lambda~[q] > 0, * column q has active lower bound (GLP_NL), and if lambda~[q] < 0, * column q has active upper bound (GLP_NU), reducing this case to two * previous ones. If, however, lambda~[q] is close to zero or * corresponding bound of row p does not exist (this may happen if * lambda~[q] has wrong sign due to round-off errors, in which case it * is expected to be close to zero, since solution is assumed to be dual * feasible), column q can be assigned status GLP_BS (basic), and row p * can be made active on its existing bound. In the latter case row * multiplier pi[p] computed with formula (9) will be also close to * zero, and dual feasibility will be kept. * * In all other cases, namely, if in solution to the transformed * problem column q is basic (GLP_BS), or non-basic with original lower * bound l[q] active (GLP_NL), or non-basic with original upper bound * u[q] active (GLP_NU), constraint (1) is inactive. So in solution to * the original problem status of column q remains unchanged, row p is * assigned status GLP_BS, and its multiplier pi[p] is assigned zero * value. * * RECOVERING INTERIOR-POINT SOLUTION * * First, value of multiplier for column q in solution to the original * problem is computed with formula (8). If lambda~[q] > 0 and column q * has implied lower bound, or if lambda~[q] < 0 and column q has * implied upper bound, this means that from the original problem's * standpoint actually row p has corresponding active bound, in which * case its multiplier pi[p] is computed with formula (9). In other * cases, when the sign of lambda~[q] corresponds to original bound of * column q, or when lambda~[q] =~ 0, value of row multiplier pi[p] is * assigned zero value. * * RECOVERING MIP SOLUTION * * None needed. */ struct ineq_singlet { /* row singleton (inequality constraint) */ int p; /* row reference number */ int q; /* column reference number */ double apq; /* constraint coefficient a[p,q] */ double c; /* objective coefficient at x[q] */ double lb; /* row lower bound */ double ub; /* row upper bound */ char lb_changed; /* this flag is set if column lower bound was changed */ char ub_changed; /* this flag is set if column upper bound was changed */ NPPLFE *ptr; /* list of non-zero coefficients a[i,q], i != p */ }; static int rcv_ineq_singlet(NPP *npp, void *info); int npp_ineq_singlet(NPP *npp, NPPROW *p) { /* process row singleton (inequality constraint) */ struct ineq_singlet *info; NPPCOL *q; NPPAIJ *apq, *aij; NPPLFE *lfe; int lb_changed, ub_changed; double ll, uu; /* the row must be singleton inequality constraint */ xassert(p->lb != -DBL_MAX || p->ub != +DBL_MAX); xassert(p->lb < p->ub); xassert(p->ptr != NULL && p->ptr->r_next == NULL); /* compute implied column bounds */ apq = p->ptr; q = apq->col; xassert(q->lb < q->ub); if (apq->val > 0.0) { ll = (p->lb == -DBL_MAX ? -DBL_MAX : p->lb / apq->val); uu = (p->ub == +DBL_MAX ? +DBL_MAX : p->ub / apq->val); } else { ll = (p->ub == +DBL_MAX ? -DBL_MAX : p->ub / apq->val); uu = (p->lb == -DBL_MAX ? +DBL_MAX : p->lb / apq->val); } /* process implied column lower bound */ if (ll == -DBL_MAX) lb_changed = 0; else { lb_changed = npp_implied_lower(npp, q, ll); xassert(0 <= lb_changed && lb_changed <= 4); if (lb_changed == 4) return 4; /* infeasible */ } /* process implied column upper bound */ if (uu == +DBL_MAX) ub_changed = 0; else if (lb_changed == 3) { /* column was fixed on its upper bound due to l'[q] = u[q] */ /* note that L[p] < U[p], so l'[q] = u[q] < u'[q] */ ub_changed = 0; } else { ub_changed = npp_implied_upper(npp, q, uu); xassert(0 <= ub_changed && ub_changed <= 4); if (ub_changed == 4) return 4; /* infeasible */ } /* if neither lower nor upper column bound was changed, the row is originally redundant and can be replaced by free row */ if (!lb_changed && !ub_changed) { p->lb = -DBL_MAX, p->ub = +DBL_MAX; npp_free_row(npp, p); return 0; } /* create transformation stack entry */ info = npp_push_tse(npp, rcv_ineq_singlet, sizeof(struct ineq_singlet)); info->p = p->i; info->q = q->j; info->apq = apq->val; info->c = q->coef; info->lb = p->lb; info->ub = p->ub; info->lb_changed = (char)lb_changed; info->ub_changed = (char)ub_changed; info->ptr = NULL; /* save column coefficients a[i,q], i != p (not needed for MIP solution) */ if (npp->sol != GLP_MIP) { for (aij = q->ptr; aij != NULL; aij = aij->c_next) { if (aij == apq) continue; /* skip a[p,q] */ lfe = dmp_get_atom(npp->stack, sizeof(NPPLFE)); lfe->ref = aij->row->i; lfe->val = aij->val; lfe->next = info->ptr; info->ptr = lfe; } } /* remove the row from the problem */ npp_del_row(npp, p); return lb_changed >= ub_changed ? lb_changed : ub_changed; } static int rcv_ineq_singlet(NPP *npp, void *_info) { /* recover row singleton (inequality constraint) */ struct ineq_singlet *info = _info; NPPLFE *lfe; double lambda; if (npp->sol == GLP_MIP) goto done; /* compute lambda~[q] in solution to the transformed problem with formula (8) */ lambda = info->c; for (lfe = info->ptr; lfe != NULL; lfe = lfe->next) lambda -= lfe->val * npp->r_pi[lfe->ref]; if (npp->sol == GLP_SOL) { /* recover basic solution */ if (npp->c_stat[info->q] == GLP_BS) { /* column q is basic, so row p is inactive */ npp->r_stat[info->p] = GLP_BS; npp->r_pi[info->p] = 0.0; } else if (npp->c_stat[info->q] == GLP_NL) nl: { /* column q is non-basic with lower bound active */ if (info->lb_changed) { /* it is implied bound, so actually row p is active while column q is basic */ npp->r_stat[info->p] = (char)(info->apq > 0.0 ? GLP_NL : GLP_NU); npp->c_stat[info->q] = GLP_BS; npp->r_pi[info->p] = lambda / info->apq; } else { /* it is original bound, so row p is inactive */ npp->r_stat[info->p] = GLP_BS; npp->r_pi[info->p] = 0.0; } } else if (npp->c_stat[info->q] == GLP_NU) nu: { /* column q is non-basic with upper bound active */ if (info->ub_changed) { /* it is implied bound, so actually row p is active while column q is basic */ npp->r_stat[info->p] = (char)(info->apq > 0.0 ? GLP_NU : GLP_NL); npp->c_stat[info->q] = GLP_BS; npp->r_pi[info->p] = lambda / info->apq; } else { /* it is original bound, so row p is inactive */ npp->r_stat[info->p] = GLP_BS; npp->r_pi[info->p] = 0.0; } } else if (npp->c_stat[info->q] == GLP_NS) { /* column q is non-basic and fixed; note, however, that in in the original problem it is non-fixed */ if (lambda > +1e-7) { if (info->apq > 0.0 && info->lb != -DBL_MAX || info->apq < 0.0 && info->ub != +DBL_MAX || !info->lb_changed) { /* either corresponding bound of row p exists or column q remains non-basic with its original lower bound active */ npp->c_stat[info->q] = GLP_NL; goto nl; } } if (lambda < -1e-7) { if (info->apq > 0.0 && info->ub != +DBL_MAX || info->apq < 0.0 && info->lb != -DBL_MAX || !info->ub_changed) { /* either corresponding bound of row p exists or column q remains non-basic with its original upper bound active */ npp->c_stat[info->q] = GLP_NU; goto nu; } } /* either lambda~[q] is close to zero, or corresponding bound of row p does not exist, because lambda~[q] has wrong sign due to round-off errors; in the latter case lambda~[q] is also assumed to be close to zero; so, we can make row p active on its existing bound and column q basic; pi[p] will have wrong sign, but it also will be close to zero (rarus casus of dual degeneracy) */ if (info->lb != -DBL_MAX && info->ub == +DBL_MAX) { /* row lower bound exists, but upper bound doesn't */ npp->r_stat[info->p] = GLP_NL; } else if (info->lb == -DBL_MAX && info->ub != +DBL_MAX) { /* row upper bound exists, but lower bound doesn't */ npp->r_stat[info->p] = GLP_NU; } else if (info->lb != -DBL_MAX && info->ub != +DBL_MAX) { /* both row lower and upper bounds exist */ /* to choose proper active row bound we should not use lambda~[q], because its value being close to zero is unreliable; so we choose that bound which provides primal feasibility for original constraint (1) */ if (info->apq * npp->c_value[info->q] <= 0.5 * (info->lb + info->ub)) npp->r_stat[info->p] = GLP_NL; else npp->r_stat[info->p] = GLP_NU; } else { npp_error(); return 1; } npp->c_stat[info->q] = GLP_BS; npp->r_pi[info->p] = lambda / info->apq; } else { npp_error(); return 1; } } if (npp->sol == GLP_IPT) { /* recover interior-point solution */ if (lambda > +DBL_EPSILON && info->lb_changed || lambda < -DBL_EPSILON && info->ub_changed) { /* actually row p has corresponding active bound */ npp->r_pi[info->p] = lambda / info->apq; } else { /* either bounds of column q are both inactive or its original bound is active */ npp->r_pi[info->p] = 0.0; } } done: return 0; } /*********************************************************************** * NAME * * npp_implied_slack - process column singleton (implied slack variable) * * SYNOPSIS * * #include "glpnpp.h" * void npp_implied_slack(NPP *npp, NPPCOL *q); * * DESCRIPTION * * The routine npp_implied_slack processes column q: * * l[q] <= x[q] <= u[q], (1) * * where l[q] < u[q], having the only non-zero coefficient in row p, * which is equality constraint: * * sum a[p,j] x[j] + a[p,q] x[q] = b. (2) * j!=q * * PROBLEM TRANSFORMATION * * (If x[q] is integral, this transformation must not be used.) * * The term a[p,q] x[q] in constraint (2) can be considered as a slack * variable that allows to carry bounds of column q over row p and then * remove column q from the problem. * * Constraint (2) can be written as follows: * * sum a[p,j] x[j] = b - a[p,q] x[q]. (3) * j!=q * * According to (1) constraint (3) is equivalent to the following * inequality constraint: * * L[p] <= sum a[p,j] x[j] <= U[p], (4) * j!=q * * where * * ( b - a[p,q] u[q], if a[p,q] > 0 * L[p] = < (5) * ( b - a[p,q] l[q], if a[p,q] < 0 * * ( b - a[p,q] l[q], if a[p,q] > 0 * U[p] = < (6) * ( b - a[p,q] u[q], if a[p,q] < 0 * * From (2) it follows that: * * 1 * x[q] = ------ (b - sum a[p,j] x[j]). (7) * a[p,q] j!=q * * In order to eliminate x[q] from the objective row we substitute it * from (6) to that row: * * z = sum c[j] x[j] + c[q] x[q] + c[0] = * j!=q * 1 * = sum c[j] x[j] + c[q] [------ (b - sum a[p,j] x[j])] + c0 = * j!=q a[p,q] j!=q * * = sum c~[j] x[j] + c~[0], * j!=q * a[p,j] b * c~[j] = c[j] - c[q] ------, c~0 = c0 - c[q] ------ (8) * a[p,q] a[p,q] * * are values of objective coefficients and constant term, resp., in * the transformed problem. * * Note that column q is column singleton, so in the dual system of the * original problem it corresponds to the following row singleton: * * a[p,q] pi[p] + lambda[q] = c[q]. (9) * * In the transformed problem row (9) would be the following: * * a[p,q] pi~[p] + lambda[q] = c~[q] = 0. (10) * * Subtracting (10) from (9) we have: * * a[p,q] (pi[p] - pi~[p]) = c[q] * * that gives the following formula to compute multiplier for row p in * solution to the original problem using its value in solution to the * transformed problem: * * pi[p] = pi~[p] + c[q] / a[p,q]. (11) * * RECOVERING BASIC SOLUTION * * Status of column q in solution to the original problem is defined * by status of row p in solution to the transformed problem and the * sign of coefficient a[p,q] in the original inequality constraint (2) * as follows: * * +-----------------------+---------+--------------------+ * | Status of row p | Sign of | Status of column q | * | (transformed problem) | a[p,q] | (original problem) | * +-----------------------+---------+--------------------+ * | GLP_BS | + / - | GLP_BS | * | GLP_NL | + | GLP_NU | * | GLP_NL | - | GLP_NL | * | GLP_NU | + | GLP_NL | * | GLP_NU | - | GLP_NU | * | GLP_NF | + / - | GLP_NF | * +-----------------------+---------+--------------------+ * * Value of column q is computed with formula (7). Since originally row * p is equality constraint, its status is assigned GLP_NS, and value of * its multiplier pi[p] is computed with formula (11). * * RECOVERING INTERIOR-POINT SOLUTION * * Value of column q is computed with formula (7). Row multiplier value * pi[p] is computed with formula (11). * * RECOVERING MIP SOLUTION * * Value of column q is computed with formula (7). */ struct implied_slack { /* column singleton (implied slack variable) */ int p; /* row reference number */ int q; /* column reference number */ double apq; /* constraint coefficient a[p,q] */ double b; /* right-hand side of original equality constraint */ double c; /* original objective coefficient at x[q] */ NPPLFE *ptr; /* list of non-zero coefficients a[p,j], j != q */ }; static int rcv_implied_slack(NPP *npp, void *info); void npp_implied_slack(NPP *npp, NPPCOL *q) { /* process column singleton (implied slack variable) */ struct implied_slack *info; NPPROW *p; NPPAIJ *aij; NPPLFE *lfe; /* the column must be non-integral non-fixed singleton */ xassert(!q->is_int); xassert(q->lb < q->ub); xassert(q->ptr != NULL && q->ptr->c_next == NULL); /* corresponding row must be equality constraint */ aij = q->ptr; p = aij->row; xassert(p->lb == p->ub); /* create transformation stack entry */ info = npp_push_tse(npp, rcv_implied_slack, sizeof(struct implied_slack)); info->p = p->i; info->q = q->j; info->apq = aij->val; info->b = p->lb; info->c = q->coef; info->ptr = NULL; /* save row coefficients a[p,j], j != q, and substitute x[q] into the objective row */ for (aij = p->ptr; aij != NULL; aij = aij->r_next) { if (aij->col == q) continue; /* skip a[p,q] */ lfe = dmp_get_atom(npp->stack, sizeof(NPPLFE)); lfe->ref = aij->col->j; lfe->val = aij->val; lfe->next = info->ptr; info->ptr = lfe; aij->col->coef -= info->c * (aij->val / info->apq); } npp->c0 += info->c * (info->b / info->apq); /* compute new row bounds */ if (info->apq > 0.0) { p->lb = (q->ub == +DBL_MAX ? -DBL_MAX : info->b - info->apq * q->ub); p->ub = (q->lb == -DBL_MAX ? +DBL_MAX : info->b - info->apq * q->lb); } else { p->lb = (q->lb == -DBL_MAX ? -DBL_MAX : info->b - info->apq * q->lb); p->ub = (q->ub == +DBL_MAX ? +DBL_MAX : info->b - info->apq * q->ub); } /* remove the column from the problem */ npp_del_col(npp, q); return; } static int rcv_implied_slack(NPP *npp, void *_info) { /* recover column singleton (implied slack variable) */ struct implied_slack *info = _info; NPPLFE *lfe; double temp; if (npp->sol == GLP_SOL) { /* assign statuses to row p and column q */ if (npp->r_stat[info->p] == GLP_BS || npp->r_stat[info->p] == GLP_NF) npp->c_stat[info->q] = npp->r_stat[info->p]; else if (npp->r_stat[info->p] == GLP_NL) npp->c_stat[info->q] = (char)(info->apq > 0.0 ? GLP_NU : GLP_NL); else if (npp->r_stat[info->p] == GLP_NU) npp->c_stat[info->q] = (char)(info->apq > 0.0 ? GLP_NL : GLP_NU); else { npp_error(); return 1; } npp->r_stat[info->p] = GLP_NS; } if (npp->sol != GLP_MIP) { /* compute multiplier for row p */ npp->r_pi[info->p] += info->c / info->apq; } /* compute value of column q */ temp = info->b; for (lfe = info->ptr; lfe != NULL; lfe = lfe->next) temp -= lfe->val * npp->c_value[lfe->ref]; npp->c_value[info->q] = temp / info->apq; return 0; } /*********************************************************************** * NAME * * npp_implied_free - process column singleton (implied free variable) * * SYNOPSIS * * #include "glpnpp.h" * int npp_implied_free(NPP *npp, NPPCOL *q); * * DESCRIPTION * * The routine npp_implied_free processes column q: * * l[q] <= x[q] <= u[q], (1) * * having non-zero coefficient in the only row p, which is inequality * constraint: * * L[p] <= sum a[p,j] x[j] + a[p,q] x[q] <= U[p], (2) * j!=q * * where l[q] < u[q], L[p] < U[p], L[p] > -oo and/or U[p] < +oo. * * RETURNS * * 0 - success; * * 1 - column lower and/or upper bound(s) can be active; * * 2 - problem has no dual feasible solution. * * PROBLEM TRANSFORMATION * * Constraint (2) can be written as follows: * * L[p] - sum a[p,j] x[j] <= a[p,q] x[q] <= U[p] - sum a[p,j] x[j], * j!=q j!=q * * from which it follows that: * * alfa <= a[p,q] x[q] <= beta, (3) * * where * * alfa = inf(L[p] - sum a[p,j] x[j]) = * j!=q * * = L[p] - sup sum a[p,j] x[j] = (4) * j!=q * * = L[p] - sum a[p,j] u[j] - sum a[p,j] l[j], * j in Jp j in Jn * * beta = sup(L[p] - sum a[p,j] x[j]) = * j!=q * * = L[p] - inf sum a[p,j] x[j] = (5) * j!=q * * = L[p] - sum a[p,j] l[j] - sum a[p,j] u[j], * j in Jp j in Jn * * Jp = {j != q: a[p,j] > 0}, Jn = {j != q: a[p,j] < 0}. (6) * * Inequality (3) defines implied bounds of variable x[q]: * * l'[q] <= x[q] <= u'[q], (7) * * where * * ( alfa / a[p,q], if a[p,q] > 0 * l'[q] = < (8a) * ( beta / a[p,q], if a[p,q] < 0 * * ( beta / a[p,q], if a[p,q] > 0 * u'[q] = < (8b) * ( alfa / a[p,q], if a[p,q] < 0 * * Thus, if l'[q] > l[q] - eps and u'[q] < u[q] + eps, where eps is * an absolute tolerance for column value, column bounds (1) cannot be * active, in which case column q can be replaced by equivalent free * (unbounded) column. * * Note that column q is column singleton, so in the dual system of the * original problem it corresponds to the following row singleton: * * a[p,q] pi[p] + lambda[q] = c[q], (9) * * from which it follows that: * * pi[p] = (c[q] - lambda[q]) / a[p,q]. (10) * * Let x[q] be implied free (unbounded) variable. Then column q can be * only basic, so its multiplier lambda[q] is equal to zero, and from * (10) we have: * * pi[p] = c[q] / a[p,q]. (11) * * There are possible three cases: * * 1) pi[p] < -eps, where eps is an absolute tolerance for row * multiplier. In this case, to provide dual feasibility of the * original problem, row p must be active on its lower bound, and * if its lower bound does not exist (L[p] = -oo), the problem has * no dual feasible solution; * * 2) pi[p] > +eps. In this case row p must be active on its upper * bound, and if its upper bound does not exist (U[p] = +oo), the * problem has no dual feasible solution; * * 3) -eps <= pi[p] <= +eps. In this case any (either lower or upper) * bound of row p can be active, because this does not affect dual * feasibility. * * Thus, in all three cases original inequality constraint (2) can be * replaced by equality constraint, where the right-hand side is either * lower or upper bound of row p, and bounds of column q can be removed * that makes it free (unbounded). (May note that this transformation * can be followed by transformation "Column singleton (implied slack * variable)" performed by the routine npp_implied_slack.) * * RECOVERING BASIC SOLUTION * * Status of row p in solution to the original problem is determined * by its status in solution to the transformed problem and its bound, * which was choosen to be active: * * +-----------------------+--------+--------------------+ * | Status of row p | Active | Status of row p | * | (transformed problem) | bound | (original problem) | * +-----------------------+--------+--------------------+ * | GLP_BS | L[p] | GLP_BS | * | GLP_BS | U[p] | GLP_BS | * | GLP_NS | L[p] | GLP_NL | * | GLP_NS | U[p] | GLP_NU | * +-----------------------+--------+--------------------+ * * Value of row multiplier pi[p] (as well as value of column q) in * solution to the original problem is the same as in solution to the * transformed problem. * * RECOVERING INTERIOR-POINT SOLUTION * * Value of row multiplier pi[p] in solution to the original problem is * the same as in solution to the transformed problem. * * RECOVERING MIP SOLUTION * * None needed. */ struct implied_free { /* column singleton (implied free variable) */ int p; /* row reference number */ char stat; /* row status: GLP_NL - active constraint on lower bound GLP_NU - active constraint on upper bound */ }; static int rcv_implied_free(NPP *npp, void *info); int npp_implied_free(NPP *npp, NPPCOL *q) { /* process column singleton (implied free variable) */ struct implied_free *info; NPPROW *p; NPPAIJ *apq, *aij; double alfa, beta, l, u, pi, eps; /* the column must be non-fixed singleton */ xassert(q->lb < q->ub); xassert(q->ptr != NULL && q->ptr->c_next == NULL); /* corresponding row must be inequality constraint */ apq = q->ptr; p = apq->row; xassert(p->lb != -DBL_MAX || p->ub != +DBL_MAX); xassert(p->lb < p->ub); /* compute alfa */ alfa = p->lb; if (alfa != -DBL_MAX) { for (aij = p->ptr; aij != NULL; aij = aij->r_next) { if (aij == apq) continue; /* skip a[p,q] */ if (aij->val > 0.0) { if (aij->col->ub == +DBL_MAX) { alfa = -DBL_MAX; break; } alfa -= aij->val * aij->col->ub; } else /* < 0.0 */ { if (aij->col->lb == -DBL_MAX) { alfa = -DBL_MAX; break; } alfa -= aij->val * aij->col->lb; } } } /* compute beta */ beta = p->ub; if (beta != +DBL_MAX) { for (aij = p->ptr; aij != NULL; aij = aij->r_next) { if (aij == apq) continue; /* skip a[p,q] */ if (aij->val > 0.0) { if (aij->col->lb == -DBL_MAX) { beta = +DBL_MAX; break; } beta -= aij->val * aij->col->lb; } else /* < 0.0 */ { if (aij->col->ub == +DBL_MAX) { beta = +DBL_MAX; break; } beta -= aij->val * aij->col->ub; } } } /* compute implied column lower bound l'[q] */ if (apq->val > 0.0) l = (alfa == -DBL_MAX ? -DBL_MAX : alfa / apq->val); else /* < 0.0 */ l = (beta == +DBL_MAX ? -DBL_MAX : beta / apq->val); /* compute implied column upper bound u'[q] */ if (apq->val > 0.0) u = (beta == +DBL_MAX ? +DBL_MAX : beta / apq->val); else u = (alfa == -DBL_MAX ? +DBL_MAX : alfa / apq->val); /* check if column lower bound l[q] can be active */ if (q->lb != -DBL_MAX) { eps = 1e-9 + 1e-12 * fabs(q->lb); if (l < q->lb - eps) return 1; /* yes, it can */ } /* check if column upper bound u[q] can be active */ if (q->ub != +DBL_MAX) { eps = 1e-9 + 1e-12 * fabs(q->ub); if (u > q->ub + eps) return 1; /* yes, it can */ } /* okay; make column q free (unbounded) */ q->lb = -DBL_MAX, q->ub = +DBL_MAX; /* create transformation stack entry */ info = npp_push_tse(npp, rcv_implied_free, sizeof(struct implied_free)); info->p = p->i; info->stat = -1; /* compute row multiplier pi[p] */ pi = q->coef / apq->val; /* check dual feasibility for row p */ if (pi > +DBL_EPSILON) { /* lower bound L[p] must be active */ if (p->lb != -DBL_MAX) nl: { info->stat = GLP_NL; p->ub = p->lb; } else { if (pi > +1e-5) return 2; /* dual infeasibility */ /* take a chance on U[p] */ xassert(p->ub != +DBL_MAX); goto nu; } } else if (pi < -DBL_EPSILON) { /* upper bound U[p] must be active */ if (p->ub != +DBL_MAX) nu: { info->stat = GLP_NU; p->lb = p->ub; } else { if (pi < -1e-5) return 2; /* dual infeasibility */ /* take a chance on L[p] */ xassert(p->lb != -DBL_MAX); goto nl; } } else { /* any bound (either L[p] or U[p]) can be made active */ if (p->ub == +DBL_MAX) { xassert(p->lb != -DBL_MAX); goto nl; } if (p->lb == -DBL_MAX) { xassert(p->ub != +DBL_MAX); goto nu; } if (fabs(p->lb) <= fabs(p->ub)) goto nl; else goto nu; } return 0; } static int rcv_implied_free(NPP *npp, void *_info) { /* recover column singleton (implied free variable) */ struct implied_free *info = _info; if (npp->sol == GLP_SOL) { if (npp->r_stat[info->p] == GLP_BS) npp->r_stat[info->p] = GLP_BS; else if (npp->r_stat[info->p] == GLP_NS) { xassert(info->stat == GLP_NL || info->stat == GLP_NU); npp->r_stat[info->p] = info->stat; } else { npp_error(); return 1; } } return 0; } /*********************************************************************** * NAME * * npp_eq_doublet - process row doubleton (equality constraint) * * SYNOPSIS * * #include "glpnpp.h" * NPPCOL *npp_eq_doublet(NPP *npp, NPPROW *p); * * DESCRIPTION * * The routine npp_eq_doublet processes row p, which is equality * constraint having exactly two non-zero coefficients: * * a[p,q] x[q] + a[p,r] x[r] = b. (1) * * As the result of processing one of columns q or r is eliminated from * all other rows and, thus, becomes column singleton of type "implied * slack variable". Row p is not changed and along with column q and r * remains in the problem. * * RETURNS * * The routine npp_eq_doublet returns pointer to the descriptor of that * column q or r which has been eliminated. If, due to some reason, the * elimination was not performed, the routine returns NULL. * * PROBLEM TRANSFORMATION * * First, we decide which column q or r will be eliminated. Let it be * column q. Consider i-th constraint row, where column q has non-zero * coefficient a[i,q] != 0: * * L[i] <= sum a[i,j] x[j] <= U[i]. (2) * j * * In order to eliminate column q from row (2) we subtract from it row * (1) multiplied by gamma[i] = a[i,q] / a[p,q], i.e. we replace in the * transformed problem row (2) by its linear combination with row (1). * This transformation changes only coefficients in columns q and r, * and bounds of row i as follows: * * a~[i,q] = a[i,q] - gamma[i] a[p,q] = 0, (3) * * a~[i,r] = a[i,r] - gamma[i] a[p,r], (4) * * L~[i] = L[i] - gamma[i] b, (5) * * U~[i] = U[i] - gamma[i] b. (6) * * RECOVERING BASIC SOLUTION * * The transformation of the primal system of the original problem: * * L <= A x <= U (7) * * is equivalent to multiplying from the left a transformation matrix F * by components of this primal system, which in the transformed problem * becomes the following: * * F L <= F A x <= F U ==> L~ <= A~x <= U~. (8) * * The matrix F has the following structure: * * ( 1 -gamma[1] ) * ( ) * ( 1 -gamma[2] ) * ( ) * ( ... ... ) * ( ) * F = ( 1 -gamma[p-1] ) (9) * ( ) * ( 1 ) * ( ) * ( -gamma[p+1] 1 ) * ( ) * ( ... ... ) * * where its column containing elements -gamma[i] corresponds to row p * of the primal system. * * From (8) it follows that the dual system of the original problem: * * A'pi + lambda = c, (10) * * in the transformed problem becomes the following: * * A'F'inv(F')pi + lambda = c ==> (A~)'pi~ + lambda = c, (11) * * where: * * pi~ = inv(F')pi (12) * * is the vector of row multipliers in the transformed problem. Thus: * * pi = F'pi~. (13) * * Therefore, as it follows from (13), value of multiplier for row p in * solution to the original problem can be computed as follows: * * pi[p] = pi~[p] - sum gamma[i] pi~[i], (14) * i * * where pi~[i] = pi[i] is multiplier for row i (i != p). * * Note that the statuses of all rows and columns are not changed. * * RECOVERING INTERIOR-POINT SOLUTION * * Multiplier for row p in solution to the original problem is computed * with formula (14). * * RECOVERING MIP SOLUTION * * None needed. */ struct eq_doublet { /* row doubleton (equality constraint) */ int p; /* row reference number */ double apq; /* constraint coefficient a[p,q] */ NPPLFE *ptr; /* list of non-zero coefficients a[i,q], i != p */ }; static int rcv_eq_doublet(NPP *npp, void *info); NPPCOL *npp_eq_doublet(NPP *npp, NPPROW *p) { /* process row doubleton (equality constraint) */ struct eq_doublet *info; NPPROW *i; NPPCOL *q, *r; NPPAIJ *apq, *apr, *aiq, *air, *next; NPPLFE *lfe; double gamma; /* the row must be doubleton equality constraint */ xassert(p->lb == p->ub); xassert(p->ptr != NULL && p->ptr->r_next != NULL && p->ptr->r_next->r_next == NULL); /* choose column to be eliminated */ { NPPAIJ *a1, *a2; a1 = p->ptr, a2 = a1->r_next; if (fabs(a2->val) < 0.001 * fabs(a1->val)) { /* only first column can be eliminated, because second one has too small constraint coefficient */ apq = a1, apr = a2; } else if (fabs(a1->val) < 0.001 * fabs(a2->val)) { /* only second column can be eliminated, because first one has too small constraint coefficient */ apq = a2, apr = a1; } else { /* both columns are appropriate; choose that one which is shorter to minimize fill-in */ if (npp_col_nnz(npp, a1->col) <= npp_col_nnz(npp, a2->col)) { /* first column is shorter */ apq = a1, apr = a2; } else { /* second column is shorter */ apq = a2, apr = a1; } } } /* now columns q and r have been chosen */ q = apq->col, r = apr->col; /* create transformation stack entry */ info = npp_push_tse(npp, rcv_eq_doublet, sizeof(struct eq_doublet)); info->p = p->i; info->apq = apq->val; info->ptr = NULL; /* transform each row i (i != p), where a[i,q] != 0, to eliminate column q */ for (aiq = q->ptr; aiq != NULL; aiq = next) { next = aiq->c_next; if (aiq == apq) continue; /* skip row p */ i = aiq->row; /* row i to be transformed */ /* save constraint coefficient a[i,q] */ if (npp->sol != GLP_MIP) { lfe = dmp_get_atom(npp->stack, sizeof(NPPLFE)); lfe->ref = i->i; lfe->val = aiq->val; lfe->next = info->ptr; info->ptr = lfe; } /* find coefficient a[i,r] in row i */ for (air = i->ptr; air != NULL; air = air->r_next) if (air->col == r) break; /* if a[i,r] does not exist, create a[i,r] = 0 */ if (air == NULL) air = npp_add_aij(npp, i, r, 0.0); /* compute gamma[i] = a[i,q] / a[p,q] */ gamma = aiq->val / apq->val; /* (row i) := (row i) - gamma[i] * (row p); see (3)-(6) */ /* new a[i,q] is exact zero due to elimnation; remove it from row i */ npp_del_aij(npp, aiq); /* compute new a[i,r] */ air->val -= gamma * apr->val; /* if new a[i,r] is close to zero due to numeric cancelation, remove it from row i */ if (fabs(air->val) <= 1e-10) npp_del_aij(npp, air); /* compute new lower and upper bounds of row i */ if (i->lb == i->ub) i->lb = i->ub = (i->lb - gamma * p->lb); else { if (i->lb != -DBL_MAX) i->lb -= gamma * p->lb; if (i->ub != +DBL_MAX) i->ub -= gamma * p->lb; } } return q; } static int rcv_eq_doublet(NPP *npp, void *_info) { /* recover row doubleton (equality constraint) */ struct eq_doublet *info = _info; NPPLFE *lfe; double gamma, temp; /* we assume that processing row p is followed by processing column q as singleton of type "implied slack variable", in which case row p must always be active equality constraint */ if (npp->sol == GLP_SOL) { if (npp->r_stat[info->p] != GLP_NS) { npp_error(); return 1; } } if (npp->sol != GLP_MIP) { /* compute value of multiplier for row p; see (14) */ temp = npp->r_pi[info->p]; for (lfe = info->ptr; lfe != NULL; lfe = lfe->next) { gamma = lfe->val / info->apq; /* a[i,q] / a[p,q] */ temp -= gamma * npp->r_pi[lfe->ref]; } npp->r_pi[info->p] = temp; } return 0; } /*********************************************************************** * NAME * * npp_forcing_row - process forcing row * * SYNOPSIS * * #include "glpnpp.h" * int npp_forcing_row(NPP *npp, NPPROW *p, int at); * * DESCRIPTION * * The routine npp_forcing row processes row p of general format: * * L[p] <= sum a[p,j] x[j] <= U[p], (1) * j * * l[j] <= x[j] <= u[j], (2) * * where L[p] <= U[p] and l[j] < u[j] for all a[p,j] != 0. It is also * assumed that: * * 1) if at = 0 then |L[p] - U'[p]| <= eps, where U'[p] is implied * row upper bound (see below), eps is an absolute tolerance for row * value; * * 2) if at = 1 then |U[p] - L'[p]| <= eps, where L'[p] is implied * row lower bound (see below). * * RETURNS * * 0 - success; * * 1 - cannot fix columns due to too small constraint coefficients. * * PROBLEM TRANSFORMATION * * Implied lower and upper bounds of row (1) are determined by bounds * of corresponding columns (variables) as follows: * * L'[p] = inf sum a[p,j] x[j] = * j * (3) * = sum a[p,j] l[j] + sum a[p,j] u[j], * j in Jp j in Jn * * U'[p] = sup sum a[p,j] x[j] = * (4) * = sum a[p,j] u[j] + sum a[p,j] l[j], * j in Jp j in Jn * * Jp = {j: a[p,j] > 0}, Jn = {j: a[p,j] < 0}. (5) * * If L[p] =~ U'[p] (at = 0), solution can be primal feasible only when * all variables take their boundary values as defined by (4): * * ( u[j], if j in Jp * x[j] = < (6) * ( l[j], if j in Jn * * Similarly, if U[p] =~ L'[p] (at = 1), solution can be primal feasible * only when all variables take their boundary values as defined by (3): * * ( l[j], if j in Jp * x[j] = < (7) * ( u[j], if j in Jn * * Condition (6) or (7) allows fixing all columns (variables x[j]) * in row (1) on their bounds and then removing them from the problem * (see the routine npp_fixed_col). Due to this row p becomes redundant, * so it can be replaced by equivalent free (unbounded) row and also * removed from the problem (see the routine npp_free_row). * * 1. To apply this transformation row (1) should not have coefficients * whose magnitude is too small, i.e. all a[p,j] should satisfy to * the following condition: * * |a[p,j]| >= eps * max(1, |a[p,k]|), (8) * k * where eps is a relative tolerance for constraint coefficients. * Otherwise, fixing columns may be numerically unreliable and may * lead to wrong solution. * * 2. The routine fixes columns and remove bounds of row p, however, * it does not remove the row and columns from the problem. * * RECOVERING BASIC SOLUTION * * In the transformed problem row p being inactive constraint is * assigned status GLP_BS (as the result of transformation of free * row), and all columns in this row are assigned status GLP_NS (as the * result of transformation of fixed columns). * * Note that in the dual system of the transformed (as well as original) * problem every column j in row p corresponds to the following row: * * sum a[i,j] pi[i] + a[p,j] pi[p] + lambda[j] = c[j], (9) * i!=p * * from which it follows that: * * lambda[j] = c[j] - sum a[i,j] pi[i] - a[p,j] pi[p]. (10) * i!=p * * In the transformed problem values of all multipliers pi[i] are known * (including pi[i], whose value is zero, since row p is inactive). * Thus, using formula (10) it is possible to compute values of * multipliers lambda[j] for all columns in row p. * * Note also that in the original problem all columns in row p are * bounded, not fixed. So status GLP_NS assigned to every such column * must be changed to GLP_NL or GLP_NU depending on which bound the * corresponding column has been fixed. This status change may lead to * dual feasibility violation for solution of the original problem, * because now column multipliers must satisfy to the following * condition: * * ( >= 0, if status of column j is GLP_NL, * lambda[j] < (11) * ( <= 0, if status of column j is GLP_NU. * * If this condition holds, solution to the original problem is the * same as to the transformed problem. Otherwise, we have to perform * one degenerate pivoting step of the primal simplex method to obtain * dual feasible (hence, optimal) solution to the original problem as * follows. If, on problem transformation, row p was made active on its * lower bound (case at = 0), we change its status to GLP_NL (or GLP_NS) * and start increasing its multiplier pi[p]. Otherwise, if row p was * made active on its upper bound (case at = 1), we change its status * to GLP_NU (or GLP_NS) and start decreasing pi[p]. From (10) it * follows that: * * delta lambda[j] = - a[p,j] * delta pi[p] = - a[p,j] pi[p]. (12) * * Simple analysis of formulae (3)-(5) shows that changing pi[p] in the * specified direction causes increasing lambda[j] for every column j * assigned status GLP_NL (delta lambda[j] > 0) and decreasing lambda[j] * for every column j assigned status GLP_NU (delta lambda[j] < 0). It * is understood that once the last lambda[q], which violates condition * (11), has reached zero, multipliers lambda[j] for all columns get * valid signs. Such column q can be determined as follows. Let d[j] be * initial value of lambda[j] (i.e. reduced cost of column j) in the * transformed problem computed with formula (10) when pi[p] = 0. Then * lambda[j] = d[j] + delta lambda[j], and from (12) it follows that * lambda[j] becomes zero if: * * delta lambda[j] = - a[p,j] pi[p] = - d[j] ==> * (13) * pi[p] = d[j] / a[p,j]. * * Therefore, the last column q, for which lambda[q] becomes zero, can * be determined from the following condition: * * |d[q] / a[p,q]| = max |pi[p]| = max |d[j] / a[p,j]|, (14) * j in D j in D * * where D is a set of columns j whose, reduced costs d[j] have invalid * signs, i.e. violate condition (11). (Thus, if D is empty, solution * to the original problem is the same as solution to the transformed * problem, and no correction is needed as was noticed above.) In * solution to the original problem column q is assigned status GLP_BS, * since it replaces column of auxiliary variable of row p (becoming * active) in the basis, and multiplier for row p is assigned its new * value, which is pi[p] = d[q] / a[p,q]. Note that due to primal * degeneracy values of all columns having non-zero coefficients in row * p remain unchanged. * * RECOVERING INTERIOR-POINT SOLUTION * * Value of multiplier pi[p] in solution to the original problem is * corrected in the same way as for basic solution. Values of all * columns having non-zero coefficients in row p remain unchanged. * * RECOVERING MIP SOLUTION * * None needed. */ struct forcing_col { /* column fixed on its bound by forcing row */ int j; /* column reference number */ char stat; /* original column status: GLP_NL - fixed on lower bound GLP_NU - fixed on upper bound */ double a; /* constraint coefficient a[p,j] */ double c; /* objective coefficient c[j] */ NPPLFE *ptr; /* list of non-zero coefficients a[i,j], i != p */ struct forcing_col *next; /* pointer to another column fixed by forcing row */ }; struct forcing_row { /* forcing row */ int p; /* row reference number */ char stat; /* status assigned to the row if it becomes active: GLP_NS - active equality constraint GLP_NL - inequality constraint with lower bound active GLP_NU - inequality constraint with upper bound active */ struct forcing_col *ptr; /* list of all columns having non-zero constraint coefficient a[p,j] in the forcing row */ }; static int rcv_forcing_row(NPP *npp, void *info); int npp_forcing_row(NPP *npp, NPPROW *p, int at) { /* process forcing row */ struct forcing_row *info; struct forcing_col *col = NULL; NPPCOL *j; NPPAIJ *apj, *aij; NPPLFE *lfe; double big; xassert(at == 0 || at == 1); /* determine maximal magnitude of the row coefficients */ big = 1.0; for (apj = p->ptr; apj != NULL; apj = apj->r_next) if (big < fabs(apj->val)) big = fabs(apj->val); /* if there are too small coefficients in the row, transformation should not be applied */ for (apj = p->ptr; apj != NULL; apj = apj->r_next) if (fabs(apj->val) < 1e-7 * big) return 1; /* create transformation stack entry */ info = npp_push_tse(npp, rcv_forcing_row, sizeof(struct forcing_row)); info->p = p->i; if (p->lb == p->ub) { /* equality constraint */ info->stat = GLP_NS; } else if (at == 0) { /* inequality constraint; case L[p] = U'[p] */ info->stat = GLP_NL; xassert(p->lb != -DBL_MAX); } else /* at == 1 */ { /* inequality constraint; case U[p] = L'[p] */ info->stat = GLP_NU; xassert(p->ub != +DBL_MAX); } info->ptr = NULL; /* scan the forcing row, fix columns at corresponding bounds, and save column information (the latter is not needed for MIP) */ for (apj = p->ptr; apj != NULL; apj = apj->r_next) { /* column j has non-zero coefficient in the forcing row */ j = apj->col; /* it must be non-fixed */ xassert(j->lb < j->ub); /* allocate stack entry to save column information */ if (npp->sol != GLP_MIP) { col = dmp_get_atom(npp->stack, sizeof(struct forcing_col)); col->j = j->j; col->stat = -1; /* will be set below */ col->a = apj->val; col->c = j->coef; col->ptr = NULL; col->next = info->ptr; info->ptr = col; } /* fix column j */ if (at == 0 && apj->val < 0.0 || at != 0 && apj->val > 0.0) { /* at its lower bound */ if (npp->sol != GLP_MIP) col->stat = GLP_NL; xassert(j->lb != -DBL_MAX); j->ub = j->lb; } else { /* at its upper bound */ if (npp->sol != GLP_MIP) col->stat = GLP_NU; xassert(j->ub != +DBL_MAX); j->lb = j->ub; } /* save column coefficients a[i,j], i != p */ if (npp->sol != GLP_MIP) { for (aij = j->ptr; aij != NULL; aij = aij->c_next) { if (aij == apj) continue; /* skip a[p,j] */ lfe = dmp_get_atom(npp->stack, sizeof(NPPLFE)); lfe->ref = aij->row->i; lfe->val = aij->val; lfe->next = col->ptr; col->ptr = lfe; } } } /* make the row free (unbounded) */ p->lb = -DBL_MAX, p->ub = +DBL_MAX; return 0; } static int rcv_forcing_row(NPP *npp, void *_info) { /* recover forcing row */ struct forcing_row *info = _info; struct forcing_col *col, *piv; NPPLFE *lfe; double d, big, temp; if (npp->sol == GLP_MIP) goto done; /* initially solution to the original problem is the same as to the transformed problem, where row p is inactive constraint with pi[p] = 0, and all columns are non-basic */ if (npp->sol == GLP_SOL) { if (npp->r_stat[info->p] != GLP_BS) { npp_error(); return 1; } for (col = info->ptr; col != NULL; col = col->next) { if (npp->c_stat[col->j] != GLP_NS) { npp_error(); return 1; } npp->c_stat[col->j] = col->stat; /* original status */ } } /* compute reduced costs d[j] for all columns with formula (10) and store them in col.c instead objective coefficients */ for (col = info->ptr; col != NULL; col = col->next) { d = col->c; for (lfe = col->ptr; lfe != NULL; lfe = lfe->next) d -= lfe->val * npp->r_pi[lfe->ref]; col->c = d; } /* consider columns j, whose multipliers lambda[j] has wrong sign in solution to the transformed problem (where lambda[j] = d[j]), and choose column q, whose multipler lambda[q] reaches zero last on changing row multiplier pi[p]; see (14) */ piv = NULL, big = 0.0; for (col = info->ptr; col != NULL; col = col->next) { d = col->c; /* d[j] */ temp = fabs(d / col->a); if (col->stat == GLP_NL) { /* column j has active lower bound */ if (d < 0.0 && big < temp) piv = col, big = temp; } else if (col->stat == GLP_NU) { /* column j has active upper bound */ if (d > 0.0 && big < temp) piv = col, big = temp; } else { npp_error(); return 1; } } /* if column q does not exist, no correction is needed */ if (piv != NULL) { /* correct solution; row p becomes active constraint while column q becomes basic */ if (npp->sol == GLP_SOL) { npp->r_stat[info->p] = info->stat; npp->c_stat[piv->j] = GLP_BS; } /* assign new value to row multiplier pi[p] = d[p] / a[p,q] */ npp->r_pi[info->p] = piv->c / piv->a; } done: return 0; } /*********************************************************************** * NAME * * npp_analyze_row - perform general row analysis * * SYNOPSIS * * #include "glpnpp.h" * int npp_analyze_row(NPP *npp, NPPROW *p); * * DESCRIPTION * * The routine npp_analyze_row performs analysis of row p of general * format: * * L[p] <= sum a[p,j] x[j] <= U[p], (1) * j * * l[j] <= x[j] <= u[j], (2) * * where L[p] <= U[p] and l[j] <= u[j] for all a[p,j] != 0. * * RETURNS * * 0x?0 - row lower bound does not exist or is redundant; * * 0x?1 - row lower bound can be active; * * 0x?2 - row lower bound is a forcing bound; * * 0x0? - row upper bound does not exist or is redundant; * * 0x1? - row upper bound can be active; * * 0x2? - row upper bound is a forcing bound; * * 0x33 - row bounds are inconsistent with column bounds. * * ALGORITHM * * Analysis of row (1) is based on analysis of its implied lower and * upper bounds, which are determined by bounds of corresponding columns * (variables) as follows: * * L'[p] = inf sum a[p,j] x[j] = * j * (3) * = sum a[p,j] l[j] + sum a[p,j] u[j], * j in Jp j in Jn * * U'[p] = sup sum a[p,j] x[j] = * (4) * = sum a[p,j] u[j] + sum a[p,j] l[j], * j in Jp j in Jn * * Jp = {j: a[p,j] > 0}, Jn = {j: a[p,j] < 0}. (5) * * (Note that bounds of all columns in row p are assumed to be correct, * so L'[p] <= U'[p].) * * Analysis of row lower bound L[p] includes the following cases: * * 1) if L[p] > U'[p] + eps, where eps is an absolute tolerance for row * value, row lower bound L[p] and implied row upper bound U'[p] are * inconsistent, ergo, the problem has no primal feasible solution; * * 2) if U'[p] - eps <= L[p] <= U'[p] + eps, i.e. if L[p] =~ U'[p], * the row is a forcing row on its lower bound (see description of * the routine npp_forcing_row); * * 3) if L[p] > L'[p] + eps, row lower bound L[p] can be active (this * conclusion does not account other rows in the problem); * * 4) if L[p] <= L'[p] + eps, row lower bound L[p] cannot be active, so * it is redundant and can be removed (replaced by -oo). * * Analysis of row upper bound U[p] is performed in a similar way and * includes the following cases: * * 1) if U[p] < L'[p] - eps, row upper bound U[p] and implied row lower * bound L'[p] are inconsistent, ergo the problem has no primal * feasible solution; * * 2) if L'[p] - eps <= U[p] <= L'[p] + eps, i.e. if U[p] =~ L'[p], * the row is a forcing row on its upper bound (see description of * the routine npp_forcing_row); * * 3) if U[p] < U'[p] - eps, row upper bound U[p] can be active (this * conclusion does not account other rows in the problem); * * 4) if U[p] >= U'[p] - eps, row upper bound U[p] cannot be active, so * it is redundant and can be removed (replaced by +oo). */ int npp_analyze_row(NPP *npp, NPPROW *p) { /* perform general row analysis */ NPPAIJ *aij; int ret = 0x00; double l, u, eps; xassert(npp == npp); /* compute implied lower bound L'[p]; see (3) */ l = 0.0; for (aij = p->ptr; aij != NULL; aij = aij->r_next) { if (aij->val > 0.0) { if (aij->col->lb == -DBL_MAX) { l = -DBL_MAX; break; } l += aij->val * aij->col->lb; } else /* aij->val < 0.0 */ { if (aij->col->ub == +DBL_MAX) { l = -DBL_MAX; break; } l += aij->val * aij->col->ub; } } /* compute implied upper bound U'[p]; see (4) */ u = 0.0; for (aij = p->ptr; aij != NULL; aij = aij->r_next) { if (aij->val > 0.0) { if (aij->col->ub == +DBL_MAX) { u = +DBL_MAX; break; } u += aij->val * aij->col->ub; } else /* aij->val < 0.0 */ { if (aij->col->lb == -DBL_MAX) { u = +DBL_MAX; break; } u += aij->val * aij->col->lb; } } /* column bounds are assumed correct, so L'[p] <= U'[p] */ /* check if row lower bound is consistent */ if (p->lb != -DBL_MAX) { eps = 1e-3 + 1e-6 * fabs(p->lb); if (p->lb - eps > u) { ret = 0x33; goto done; } } /* check if row upper bound is consistent */ if (p->ub != +DBL_MAX) { eps = 1e-3 + 1e-6 * fabs(p->ub); if (p->ub + eps < l) { ret = 0x33; goto done; } } /* check if row lower bound can be active/forcing */ if (p->lb != -DBL_MAX) { eps = 1e-9 + 1e-12 * fabs(p->lb); if (p->lb - eps > l) { if (p->lb + eps <= u) ret |= 0x01; else ret |= 0x02; } } /* check if row upper bound can be active/forcing */ if (p->ub != +DBL_MAX) { eps = 1e-9 + 1e-12 * fabs(p->ub); if (p->ub + eps < u) { /* check if the upper bound is forcing */ if (p->ub - eps >= l) ret |= 0x10; else ret |= 0x20; } } done: return ret; } /*********************************************************************** * NAME * * npp_inactive_bound - remove row lower/upper inactive bound * * SYNOPSIS * * #include "glpnpp.h" * void npp_inactive_bound(NPP *npp, NPPROW *p, int which); * * DESCRIPTION * * The routine npp_inactive_bound removes lower (if which = 0) or upper * (if which = 1) bound of row p: * * L[p] <= sum a[p,j] x[j] <= U[p], * * which (bound) is assumed to be redundant. * * PROBLEM TRANSFORMATION * * If which = 0, current lower bound L[p] of row p is assigned -oo. * If which = 1, current upper bound U[p] of row p is assigned +oo. * * RECOVERING BASIC SOLUTION * * If in solution to the transformed problem row p is inactive * constraint (GLP_BS), its status is not changed in solution to the * original problem. Otherwise, status of row p in solution to the * original problem is defined by its type before transformation and * its status in solution to the transformed problem as follows: * * +---------------------+-------+---------------+---------------+ * | Row | Flag | Row status in | Row status in | * | type | which | transfmd soln | original soln | * +---------------------+-------+---------------+---------------+ * | sum >= L[p] | 0 | GLP_NF | GLP_NL | * | sum <= U[p] | 1 | GLP_NF | GLP_NU | * | L[p] <= sum <= U[p] | 0 | GLP_NU | GLP_NU | * | L[p] <= sum <= U[p] | 1 | GLP_NL | GLP_NL | * | sum = L[p] = U[p] | 0 | GLP_NU | GLP_NS | * | sum = L[p] = U[p] | 1 | GLP_NL | GLP_NS | * +---------------------+-------+---------------+---------------+ * * RECOVERING INTERIOR-POINT SOLUTION * * None needed. * * RECOVERING MIP SOLUTION * * None needed. */ struct inactive_bound { /* row inactive bound */ int p; /* row reference number */ char stat; /* row status (if active constraint) */ }; static int rcv_inactive_bound(NPP *npp, void *info); void npp_inactive_bound(NPP *npp, NPPROW *p, int which) { /* remove row lower/upper inactive bound */ struct inactive_bound *info; if (npp->sol == GLP_SOL) { /* create transformation stack entry */ info = npp_push_tse(npp, rcv_inactive_bound, sizeof(struct inactive_bound)); info->p = p->i; if (p->ub == +DBL_MAX) info->stat = GLP_NL; else if (p->lb == -DBL_MAX) info->stat = GLP_NU; else if (p->lb != p->ub) info->stat = (char)(which == 0 ? GLP_NU : GLP_NL); else info->stat = GLP_NS; } /* remove row inactive bound */ if (which == 0) { xassert(p->lb != -DBL_MAX); p->lb = -DBL_MAX; } else if (which == 1) { xassert(p->ub != +DBL_MAX); p->ub = +DBL_MAX; } else xassert(which != which); return; } static int rcv_inactive_bound(NPP *npp, void *_info) { /* recover row status */ struct inactive_bound *info = _info; if (npp->sol != GLP_SOL) { npp_error(); return 1; } if (npp->r_stat[info->p] == GLP_BS) npp->r_stat[info->p] = GLP_BS; else npp->r_stat[info->p] = info->stat; return 0; } /*********************************************************************** * NAME * * npp_implied_bounds - determine implied column bounds * * SYNOPSIS * * #include "glpnpp.h" * void npp_implied_bounds(NPP *npp, NPPROW *p); * * DESCRIPTION * * The routine npp_implied_bounds inspects general row (constraint) p: * * L[p] <= sum a[p,j] x[j] <= U[p], (1) * * l[j] <= x[j] <= u[j], (2) * * where L[p] <= U[p] and l[j] <= u[j] for all a[p,j] != 0, to compute * implied bounds of columns (variables x[j]) in this row. * * The routine stores implied column bounds l'[j] and u'[j] in column * descriptors (NPPCOL); it does not change current column bounds l[j] * and u[j]. (Implied column bounds can be then used to strengthen the * current column bounds; see the routines npp_implied_lower and * npp_implied_upper). * * ALGORITHM * * Current column bounds (2) define implied lower and upper bounds of * row (1) as follows: * * L'[p] = inf sum a[p,j] x[j] = * j * (3) * = sum a[p,j] l[j] + sum a[p,j] u[j], * j in Jp j in Jn * * U'[p] = sup sum a[p,j] x[j] = * (4) * = sum a[p,j] u[j] + sum a[p,j] l[j], * j in Jp j in Jn * * Jp = {j: a[p,j] > 0}, Jn = {j: a[p,j] < 0}. (5) * * (Note that bounds of all columns in row p are assumed to be correct, * so L'[p] <= U'[p].) * * If L[p] > L'[p] and/or U[p] < U'[p], the lower and/or upper bound of * row (1) can be active, in which case such row defines implied bounds * of its variables. * * Let x[k] be some variable having in row (1) coefficient a[p,k] != 0. * Consider a case when row lower bound can be active (L[p] > L'[p]): * * sum a[p,j] x[j] >= L[p] ==> * j * * sum a[p,j] x[j] + a[p,k] x[k] >= L[p] ==> * j!=k * (6) * a[p,k] x[k] >= L[p] - sum a[p,j] x[j] ==> * j!=k * * a[p,k] x[k] >= L[p,k], * * where * * L[p,k] = inf(L[p] - sum a[p,j] x[j]) = * j!=k * * = L[p] - sup sum a[p,j] x[j] = (7) * j!=k * * = L[p] - sum a[p,j] u[j] - sum a[p,j] l[j]. * j in Jp\{k} j in Jn\{k} * * Thus: * * x[k] >= l'[k] = L[p,k] / a[p,k], if a[p,k] > 0, (8) * * x[k] <= u'[k] = L[p,k] / a[p,k], if a[p,k] < 0. (9) * * where l'[k] and u'[k] are implied lower and upper bounds of variable * x[k], resp. * * Now consider a similar case when row upper bound can be active * (U[p] < U'[p]): * * sum a[p,j] x[j] <= U[p] ==> * j * * sum a[p,j] x[j] + a[p,k] x[k] <= U[p] ==> * j!=k * (10) * a[p,k] x[k] <= U[p] - sum a[p,j] x[j] ==> * j!=k * * a[p,k] x[k] <= U[p,k], * * where: * * U[p,k] = sup(U[p] - sum a[p,j] x[j]) = * j!=k * * = U[p] - inf sum a[p,j] x[j] = (11) * j!=k * * = U[p] - sum a[p,j] l[j] - sum a[p,j] u[j]. * j in Jp\{k} j in Jn\{k} * * Thus: * * x[k] <= u'[k] = U[p,k] / a[p,k], if a[p,k] > 0, (12) * * x[k] >= l'[k] = U[p,k] / a[p,k], if a[p,k] < 0. (13) * * Note that in formulae (8), (9), (12), and (13) coefficient a[p,k] * must not be too small in magnitude relatively to other non-zero * coefficients in row (1), i.e. the following condition must hold: * * |a[p,k]| >= eps * max(1, |a[p,j]|), (14) * j * * where eps is a relative tolerance for constraint coefficients. * Otherwise the implied column bounds can be numerical inreliable. For * example, using formula (8) for the following inequality constraint: * * 1e-12 x1 - x2 - x3 >= 0, * * where x1 >= -1, x2, x3, >= 0, may lead to numerically unreliable * conclusion that x1 >= 0. * * Using formulae (8), (9), (12), and (13) to compute implied bounds * for one variable requires |J| operations, where J = {j: a[p,j] != 0}, * because this needs computing L[p,k] and U[p,k]. Thus, computing * implied bounds for all variables in row (1) would require |J|^2 * operations, that is not a good technique. However, the total number * of operations can be reduced to |J| as follows. * * Let a[p,k] > 0. Then from (7) and (11) we have: * * L[p,k] = L[p] - (U'[p] - a[p,k] u[k]) = * * = L[p] - U'[p] + a[p,k] u[k], * * U[p,k] = U[p] - (L'[p] - a[p,k] l[k]) = * * = U[p] - L'[p] + a[p,k] l[k], * * where L'[p] and U'[p] are implied row lower and upper bounds defined * by formulae (3) and (4). Substituting these expressions into (8) and * (12) gives: * * l'[k] = L[p,k] / a[p,k] = u[k] + (L[p] - U'[p]) / a[p,k], (15) * * u'[k] = U[p,k] / a[p,k] = l[k] + (U[p] - L'[p]) / a[p,k]. (16) * * Similarly, if a[p,k] < 0, according to (7) and (11) we have: * * L[p,k] = L[p] - (U'[p] - a[p,k] l[k]) = * * = L[p] - U'[p] + a[p,k] l[k], * * U[p,k] = U[p] - (L'[p] - a[p,k] u[k]) = * * = U[p] - L'[p] + a[p,k] u[k], * * and substituting these expressions into (8) and (12) gives: * * l'[k] = U[p,k] / a[p,k] = u[k] + (U[p] - L'[p]) / a[p,k], (17) * * u'[k] = L[p,k] / a[p,k] = l[k] + (L[p] - U'[p]) / a[p,k]. (18) * * Note that formulae (15)-(18) can be used only if L'[p] and U'[p] * exist. However, if for some variable x[j] it happens that l[j] = -oo * and/or u[j] = +oo, values of L'[p] (if a[p,j] > 0) and/or U'[p] (if * a[p,j] < 0) are undefined. Consider, therefore, the most general * situation, when some column bounds (2) may not exist. * * Let: * * J' = {j : (a[p,j] > 0 and l[j] = -oo) or * (19) * (a[p,j] < 0 and u[j] = +oo)}. * * Then (assuming that row upper bound U[p] can be active) the following * three cases are possible: * * 1) |J'| = 0. In this case L'[p] exists, thus, for all variables x[j] * in row (1) we can use formulae (16) and (17); * * 2) J' = {k}. In this case L'[p] = -oo, however, U[p,k] (11) exists, * so for variable x[k] we can use formulae (12) and (13). Note that * for all other variables x[j] (j != k) l'[j] = -oo (if a[p,j] < 0) * or u'[j] = +oo (if a[p,j] > 0); * * 3) |J'| > 1. In this case for all variables x[j] in row [1] we have * l'[j] = -oo (if a[p,j] < 0) or u'[j] = +oo (if a[p,j] > 0). * * Similarly, let: * * J'' = {j : (a[p,j] > 0 and u[j] = +oo) or * (20) * (a[p,j] < 0 and l[j] = -oo)}. * * Then (assuming that row lower bound L[p] can be active) the following * three cases are possible: * * 1) |J''| = 0. In this case U'[p] exists, thus, for all variables x[j] * in row (1) we can use formulae (15) and (18); * * 2) J'' = {k}. In this case U'[p] = +oo, however, L[p,k] (7) exists, * so for variable x[k] we can use formulae (8) and (9). Note that * for all other variables x[j] (j != k) l'[j] = -oo (if a[p,j] > 0) * or u'[j] = +oo (if a[p,j] < 0); * * 3) |J''| > 1. In this case for all variables x[j] in row (1) we have * l'[j] = -oo (if a[p,j] > 0) or u'[j] = +oo (if a[p,j] < 0). */ void npp_implied_bounds(NPP *npp, NPPROW *p) { NPPAIJ *apj, *apk; double big, eps, temp; xassert(npp == npp); /* initialize implied bounds for all variables and determine maximal magnitude of row coefficients a[p,j] */ big = 1.0; for (apj = p->ptr; apj != NULL; apj = apj->r_next) { apj->col->ll.ll = -DBL_MAX, apj->col->uu.uu = +DBL_MAX; if (big < fabs(apj->val)) big = fabs(apj->val); } eps = 1e-6 * big; /* process row lower bound (assuming that it can be active) */ if (p->lb != -DBL_MAX) { apk = NULL; for (apj = p->ptr; apj != NULL; apj = apj->r_next) { if (apj->val > 0.0 && apj->col->ub == +DBL_MAX || apj->val < 0.0 && apj->col->lb == -DBL_MAX) { if (apk == NULL) apk = apj; else goto skip1; } } /* if a[p,k] = NULL then |J'| = 0 else J' = { k } */ temp = p->lb; for (apj = p->ptr; apj != NULL; apj = apj->r_next) { if (apj == apk) /* skip a[p,k] */; else if (apj->val > 0.0) temp -= apj->val * apj->col->ub; else /* apj->val < 0.0 */ temp -= apj->val * apj->col->lb; } /* compute column implied bounds */ if (apk == NULL) { /* temp = L[p] - U'[p] */ for (apj = p->ptr; apj != NULL; apj = apj->r_next) { if (apj->val >= +eps) { /* l'[j] := u[j] + (L[p] - U'[p]) / a[p,j] */ apj->col->ll.ll = apj->col->ub + temp / apj->val; } else if (apj->val <= -eps) { /* u'[j] := l[j] + (L[p] - U'[p]) / a[p,j] */ apj->col->uu.uu = apj->col->lb + temp / apj->val; } } } else { /* temp = L[p,k] */ if (apk->val >= +eps) { /* l'[k] := L[p,k] / a[p,k] */ apk->col->ll.ll = temp / apk->val; } else if (apk->val <= -eps) { /* u'[k] := L[p,k] / a[p,k] */ apk->col->uu.uu = temp / apk->val; } } skip1: ; } /* process row upper bound (assuming that it can be active) */ if (p->ub != +DBL_MAX) { apk = NULL; for (apj = p->ptr; apj != NULL; apj = apj->r_next) { if (apj->val > 0.0 && apj->col->lb == -DBL_MAX || apj->val < 0.0 && apj->col->ub == +DBL_MAX) { if (apk == NULL) apk = apj; else goto skip2; } } /* if a[p,k] = NULL then |J''| = 0 else J'' = { k } */ temp = p->ub; for (apj = p->ptr; apj != NULL; apj = apj->r_next) { if (apj == apk) /* skip a[p,k] */; else if (apj->val > 0.0) temp -= apj->val * apj->col->lb; else /* apj->val < 0.0 */ temp -= apj->val * apj->col->ub; } /* compute column implied bounds */ if (apk == NULL) { /* temp = U[p] - L'[p] */ for (apj = p->ptr; apj != NULL; apj = apj->r_next) { if (apj->val >= +eps) { /* u'[j] := l[j] + (U[p] - L'[p]) / a[p,j] */ apj->col->uu.uu = apj->col->lb + temp / apj->val; } else if (apj->val <= -eps) { /* l'[j] := u[j] + (U[p] - L'[p]) / a[p,j] */ apj->col->ll.ll = apj->col->ub + temp / apj->val; } } } else { /* temp = U[p,k] */ if (apk->val >= +eps) { /* u'[k] := U[p,k] / a[p,k] */ apk->col->uu.uu = temp / apk->val; } else if (apk->val <= -eps) { /* l'[k] := U[p,k] / a[p,k] */ apk->col->ll.ll = temp / apk->val; } } skip2: ; } return; } /* eof */ praat-6.0.04/external/glpk/glpnpp04.c000066400000000000000000001425311261542461700173150ustar00rootroot00000000000000/* glpnpp04.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpnpp.h" /*********************************************************************** * NAME * * npp_binarize_prob - binarize MIP problem * * SYNOPSIS * * #include "glpnpp.h" * int npp_binarize_prob(NPP *npp); * * DESCRIPTION * * The routine npp_binarize_prob replaces in the original MIP problem * every integer variable: * * l[q] <= x[q] <= u[q], (1) * * where l[q] < u[q], by an equivalent sum of binary variables. * * RETURNS * * The routine returns the number of integer variables for which the * transformation failed, because u[q] - l[q] > d_max. * * PROBLEM TRANSFORMATION * * If variable x[q] has non-zero lower bound, it is first processed * with the routine npp_lbnd_col. Thus, we can assume that: * * 0 <= x[q] <= u[q]. (2) * * If u[q] = 1, variable x[q] is already binary, so further processing * is not needed. Let, therefore, that 2 <= u[q] <= d_max, and n be a * smallest integer such that u[q] <= 2^n - 1 (n >= 2, since u[q] >= 2). * Then variable x[q] can be replaced by the following sum: * * n-1 * x[q] = sum 2^k x[k], (3) * k=0 * * where x[k] are binary columns (variables). If u[q] < 2^n - 1, the * following additional inequality constraint must be also included in * the transformed problem: * * n-1 * sum 2^k x[k] <= u[q]. (4) * k=0 * * Note: Assuming that in the transformed problem x[q] becomes binary * variable x[0], this transformation causes new n-1 binary variables * to appear. * * Substituting x[q] from (3) to the objective row gives: * * z = sum c[j] x[j] + c[0] = * j * * = sum c[j] x[j] + c[q] x[q] + c[0] = * j!=q * n-1 * = sum c[j] x[j] + c[q] sum 2^k x[k] + c[0] = * j!=q k=0 * n-1 * = sum c[j] x[j] + sum c[k] x[k] + c[0], * j!=q k=0 * * where: * * c[k] = 2^k c[q], k = 0, ..., n-1. (5) * * And substituting x[q] from (3) to i-th constraint row i gives: * * L[i] <= sum a[i,j] x[j] <= U[i] ==> * j * * L[i] <= sum a[i,j] x[j] + a[i,q] x[q] <= U[i] ==> * j!=q * n-1 * L[i] <= sum a[i,j] x[j] + a[i,q] sum 2^k x[k] <= U[i] ==> * j!=q k=0 * n-1 * L[i] <= sum a[i,j] x[j] + sum a[i,k] x[k] <= U[i], * j!=q k=0 * * where: * * a[i,k] = 2^k a[i,q], k = 0, ..., n-1. (6) * * RECOVERING SOLUTION * * Value of variable x[q] is computed with formula (3). */ struct binarize { int q; /* column reference number for x[q] = x[0] */ int j; /* column reference number for x[1]; x[2] has reference number j+1, x[3] - j+2, etc. */ int n; /* total number of binary variables, n >= 2 */ }; static int rcv_binarize_prob(NPP *npp, void *info); int npp_binarize_prob(NPP *npp) { /* binarize MIP problem */ struct binarize *info; NPPROW *row; NPPCOL *col, *bin; NPPAIJ *aij; int u, n, k, temp, nfails, nvars, nbins, nrows; /* new variables will be added to the end of the column list, so we go from the end to beginning of the column list */ nfails = nvars = nbins = nrows = 0; for (col = npp->c_tail; col != NULL; col = col->prev) { /* skip continuous variable */ if (!col->is_int) continue; /* skip fixed variable */ if (col->lb == col->ub) continue; /* skip binary variable */ if (col->lb == 0.0 && col->ub == 1.0) continue; /* check if the transformation is applicable */ if (col->lb < -1e6 || col->ub > +1e6 || col->ub - col->lb > 4095.0) { /* unfortunately, not */ nfails++; continue; } /* process integer non-binary variable x[q] */ nvars++; /* make x[q] non-negative, if its lower bound is non-zero */ if (col->lb != 0.0) npp_lbnd_col(npp, col); /* now 0 <= x[q] <= u[q] */ xassert(col->lb == 0.0); u = (int)col->ub; xassert(col->ub == (double)u); /* if x[q] is binary, further processing is not needed */ if (u == 1) continue; /* determine smallest n such that u <= 2^n - 1 (thus, n is the number of binary variables needed) */ n = 2, temp = 4; while (u >= temp) n++, temp += temp; nbins += n; /* create transformation stack entry */ info = npp_push_tse(npp, rcv_binarize_prob, sizeof(struct binarize)); info->q = col->j; info->j = 0; /* will be set below */ info->n = n; /* if u < 2^n - 1, we need one additional row for (4) */ if (u < temp - 1) { row = npp_add_row(npp), nrows++; row->lb = -DBL_MAX, row->ub = u; } else row = NULL; /* in the transformed problem variable x[q] becomes binary variable x[0], so its objective and constraint coefficients are not changed */ col->ub = 1.0; /* include x[0] into constraint (4) */ if (row != NULL) npp_add_aij(npp, row, col, 1.0); /* add other binary variables x[1], ..., x[n-1] */ for (k = 1, temp = 2; k < n; k++, temp += temp) { /* add new binary variable x[k] */ bin = npp_add_col(npp); bin->is_int = 1; bin->lb = 0.0, bin->ub = 1.0; bin->coef = (double)temp * col->coef; /* store column reference number for x[1] */ if (info->j == 0) info->j = bin->j; else xassert(info->j + (k-1) == bin->j); /* duplicate constraint coefficients for x[k]; this also automatically includes x[k] into constraint (4) */ for (aij = col->ptr; aij != NULL; aij = aij->c_next) npp_add_aij(npp, aij->row, bin, (double)temp * aij->val); } } if (nvars > 0) xprintf("%d integer variable(s) were replaced by %d binary one" "s\n", nvars, nbins); if (nrows > 0) xprintf("%d row(s) were added due to binarization\n", nrows); if (nfails > 0) xprintf("Binarization failed for %d integer variable(s)\n", nfails); return nfails; } static int rcv_binarize_prob(NPP *npp, void *_info) { /* recovery binarized variable */ struct binarize *info = _info; int k, temp; double sum; /* compute value of x[q]; see formula (3) */ sum = npp->c_value[info->q]; for (k = 1, temp = 2; k < info->n; k++, temp += temp) sum += (double)temp * npp->c_value[info->j + (k-1)]; npp->c_value[info->q] = sum; return 0; } /**********************************************************************/ struct elem { /* linear form element a[j] x[j] */ double aj; /* non-zero coefficient value */ NPPCOL *xj; /* pointer to variable (column) */ struct elem *next; /* pointer to another term */ }; static struct elem *copy_form(NPP *npp, NPPROW *row, double s) { /* copy linear form */ NPPAIJ *aij; struct elem *ptr, *e; ptr = NULL; for (aij = row->ptr; aij != NULL; aij = aij->r_next) { e = dmp_get_atom(npp->pool, sizeof(struct elem)); e->aj = s * aij->val; e->xj = aij->col; e->next = ptr; ptr = e; } return ptr; } static void drop_form(NPP *npp, struct elem *ptr) { /* drop linear form */ struct elem *e; while (ptr != NULL) { e = ptr; ptr = e->next; dmp_free_atom(npp->pool, e, sizeof(struct elem)); } return; } /*********************************************************************** * NAME * * npp_is_packing - test if constraint is packing inequality * * SYNOPSIS * * #include "glpnpp.h" * int npp_is_packing(NPP *npp, NPPROW *row); * * RETURNS * * If the specified row (constraint) is packing inequality (see below), * the routine npp_is_packing returns non-zero. Otherwise, it returns * zero. * * PACKING INEQUALITIES * * In canonical format the packing inequality is the following: * * sum x[j] <= 1, (1) * j in J * * where all variables x[j] are binary. This inequality expresses the * condition that in any integer feasible solution at most one variable * from set J can take non-zero (unity) value while other variables * must be equal to zero. W.l.o.g. it is assumed that |J| >= 2, because * if J is empty or |J| = 1, the inequality (1) is redundant. * * In general case the packing inequality may include original variables * x[j] as well as their complements x~[j]: * * sum x[j] + sum x~[j] <= 1, (2) * j in Jp j in Jn * * where Jp and Jn are not intersected. Therefore, using substitution * x~[j] = 1 - x[j] gives the packing inequality in generalized format: * * sum x[j] - sum x[j] <= 1 - |Jn|. (3) * j in Jp j in Jn */ int npp_is_packing(NPP *npp, NPPROW *row) { /* test if constraint is packing inequality */ NPPCOL *col; NPPAIJ *aij; int b; xassert(npp == npp); if (!(row->lb == -DBL_MAX && row->ub != +DBL_MAX)) return 0; b = 1; for (aij = row->ptr; aij != NULL; aij = aij->r_next) { col = aij->col; if (!(col->is_int && col->lb == 0.0 && col->ub == 1.0)) return 0; if (aij->val == +1.0) ; else if (aij->val == -1.0) b--; else return 0; } if (row->ub != (double)b) return 0; return 1; } /*********************************************************************** * NAME * * npp_hidden_packing - identify hidden packing inequality * * SYNOPSIS * * #include "glpnpp.h" * int npp_hidden_packing(NPP *npp, NPPROW *row); * * DESCRIPTION * * The routine npp_hidden_packing processes specified inequality * constraint, which includes only binary variables, and the number of * the variables is not less than two. If the original inequality is * equivalent to a packing inequality, the routine replaces it by this * equivalent inequality. If the original constraint is double-sided * inequality, it is replaced by a pair of single-sided inequalities, * if necessary. * * RETURNS * * If the original inequality constraint was replaced by equivalent * packing inequality, the routine npp_hidden_packing returns non-zero. * Otherwise, it returns zero. * * PROBLEM TRANSFORMATION * * Consider an inequality constraint: * * sum a[j] x[j] <= b, (1) * j in J * * where all variables x[j] are binary, and |J| >= 2. (In case of '>=' * inequality it can be transformed to '<=' format by multiplying both * its sides by -1.) * * Let Jp = {j: a[j] > 0}, Jn = {j: a[j] < 0}. Performing substitution * x[j] = 1 - x~[j] for all j in Jn, we have: * * sum a[j] x[j] <= b ==> * j in J * * sum a[j] x[j] + sum a[j] x[j] <= b ==> * j in Jp j in Jn * * sum a[j] x[j] + sum a[j] (1 - x~[j]) <= b ==> * j in Jp j in Jn * * sum a[j] x[j] - sum a[j] x~[j] <= b - sum a[j]. * j in Jp j in Jn j in Jn * * Thus, meaning the transformation above, we can assume that in * inequality (1) all coefficients a[j] are positive. Moreover, we can * assume that a[j] <= b. In fact, let a[j] > b; then the following * three cases are possible: * * 1) b < 0. In this case inequality (1) is infeasible, so the problem * has no feasible solution (see the routine npp_analyze_row); * * 2) b = 0. In this case inequality (1) is a forcing inequality on its * upper bound (see the routine npp_forcing row), from which it * follows that all variables x[j] should be fixed at zero; * * 3) b > 0. In this case inequality (1) defines an implied zero upper * bound for variable x[j] (see the routine npp_implied_bounds), from * which it follows that x[j] should be fixed at zero. * * It is assumed that all three cases listed above have been recognized * by the routine npp_process_prob, which performs basic MIP processing * prior to a call the routine npp_hidden_packing. So, if one of these * cases occurs, we should just skip processing such constraint. * * Thus, let 0 < a[j] <= b. Then it is obvious that constraint (1) is * equivalent to packing inquality only if: * * a[j] + a[k] > b + eps (2) * * for all j, k in J, j != k, where eps is an absolute tolerance for * row (linear form) value. Checking the condition (2) for all j and k, * j != k, requires time O(|J|^2). However, this time can be reduced to * O(|J|), if use minimal a[j] and a[k], in which case it is sufficient * to check the condition (2) only once. * * Once the original inequality (1) is replaced by equivalent packing * inequality, we need to perform back substitution x~[j] = 1 - x[j] for * all j in Jn (see above). * * RECOVERING SOLUTION * * None needed. */ static int hidden_packing(NPP *npp, struct elem *ptr, double *_b) { /* process inequality constraint: sum a[j] x[j] <= b; 0 - specified row is NOT hidden packing inequality; 1 - specified row is packing inequality; 2 - specified row is hidden packing inequality. */ struct elem *e, *ej, *ek; int neg; double b = *_b, eps; xassert(npp == npp); /* a[j] must be non-zero, x[j] must be binary, for all j in J */ for (e = ptr; e != NULL; e = e->next) { xassert(e->aj != 0.0); xassert(e->xj->is_int); xassert(e->xj->lb == 0.0 && e->xj->ub == 1.0); } /* check if the specified inequality constraint already has the form of packing inequality */ neg = 0; /* neg is |Jn| */ for (e = ptr; e != NULL; e = e->next) { if (e->aj == +1.0) ; else if (e->aj == -1.0) neg++; else break; } if (e == NULL) { /* all coefficients a[j] are +1 or -1; check rhs b */ if (b == (double)(1 - neg)) { /* it is packing inequality; no processing is needed */ return 1; } } /* substitute x[j] = 1 - x~[j] for all j in Jn to make all a[j] positive; the result is a~[j] = |a[j]| and new rhs b */ for (e = ptr; e != NULL; e = e->next) if (e->aj < 0) b -= e->aj; /* now a[j] > 0 for all j in J (actually |a[j]| are used) */ /* if a[j] > b, skip processing--this case must not appear */ for (e = ptr; e != NULL; e = e->next) if (fabs(e->aj) > b) return 0; /* now 0 < a[j] <= b for all j in J */ /* find two minimal coefficients a[j] and a[k], j != k */ ej = NULL; for (e = ptr; e != NULL; e = e->next) if (ej == NULL || fabs(ej->aj) > fabs(e->aj)) ej = e; xassert(ej != NULL); ek = NULL; for (e = ptr; e != NULL; e = e->next) if (e != ej) if (ek == NULL || fabs(ek->aj) > fabs(e->aj)) ek = e; xassert(ek != NULL); /* the specified constraint is equivalent to packing inequality iff a[j] + a[k] > b + eps */ eps = 1e-3 + 1e-6 * fabs(b); if (fabs(ej->aj) + fabs(ek->aj) <= b + eps) return 0; /* perform back substitution x~[j] = 1 - x[j] and construct the final equivalent packing inequality in generalized format */ b = 1.0; for (e = ptr; e != NULL; e = e->next) { if (e->aj > 0.0) e->aj = +1.0; else /* e->aj < 0.0 */ e->aj = -1.0, b -= 1.0; } *_b = b; return 2; } int npp_hidden_packing(NPP *npp, NPPROW *row) { /* identify hidden packing inequality */ NPPROW *copy; NPPAIJ *aij; struct elem *ptr, *e; int kase, ret, count = 0; double b; /* the row must be inequality constraint */ xassert(row->lb < row->ub); for (kase = 0; kase <= 1; kase++) { if (kase == 0) { /* process row upper bound */ if (row->ub == +DBL_MAX) continue; ptr = copy_form(npp, row, +1.0); b = + row->ub; } else { /* process row lower bound */ if (row->lb == -DBL_MAX) continue; ptr = copy_form(npp, row, -1.0); b = - row->lb; } /* now the inequality has the form "sum a[j] x[j] <= b" */ ret = hidden_packing(npp, ptr, &b); xassert(0 <= ret && ret <= 2); if (kase == 1 && ret == 1 || ret == 2) { /* the original inequality has been identified as hidden packing inequality */ count++; #ifdef GLP_DEBUG xprintf("Original constraint:\n"); for (aij = row->ptr; aij != NULL; aij = aij->r_next) xprintf(" %+g x%d", aij->val, aij->col->j); if (row->lb != -DBL_MAX) xprintf(", >= %g", row->lb); if (row->ub != +DBL_MAX) xprintf(", <= %g", row->ub); xprintf("\n"); xprintf("Equivalent packing inequality:\n"); for (e = ptr; e != NULL; e = e->next) xprintf(" %sx%d", e->aj > 0.0 ? "+" : "-", e->xj->j); xprintf(", <= %g\n", b); #endif if (row->lb == -DBL_MAX || row->ub == +DBL_MAX) { /* the original row is single-sided inequality; no copy is needed */ copy = NULL; } else { /* the original row is double-sided inequality; we need to create its copy for other bound before replacing it with the equivalent inequality */ copy = npp_add_row(npp); if (kase == 0) { /* the copy is for lower bound */ copy->lb = row->lb, copy->ub = +DBL_MAX; } else { /* the copy is for upper bound */ copy->lb = -DBL_MAX, copy->ub = row->ub; } /* copy original row coefficients */ for (aij = row->ptr; aij != NULL; aij = aij->r_next) npp_add_aij(npp, copy, aij->col, aij->val); } /* replace the original inequality by equivalent one */ npp_erase_row(npp, row); row->lb = -DBL_MAX, row->ub = b; for (e = ptr; e != NULL; e = e->next) npp_add_aij(npp, row, e->xj, e->aj); /* continue processing lower bound for the copy */ if (copy != NULL) row = copy; } drop_form(npp, ptr); } return count; } /*********************************************************************** * NAME * * npp_implied_packing - identify implied packing inequality * * SYNOPSIS * * #include "glpnpp.h" * int npp_implied_packing(NPP *npp, NPPROW *row, int which, * NPPCOL *var[], char set[]); * * DESCRIPTION * * The routine npp_implied_packing processes specified row (constraint) * of general format: * * L <= sum a[j] x[j] <= U. (1) * j * * If which = 0, only lower bound L, which must exist, is considered, * while upper bound U is ignored. Similarly, if which = 1, only upper * bound U, which must exist, is considered, while lower bound L is * ignored. Thus, if the specified row is a double-sided inequality or * equality constraint, this routine should be called twice for both * lower and upper bounds. * * The routine npp_implied_packing attempts to find a non-trivial (i.e. * having not less than two binary variables) packing inequality: * * sum x[j] - sum x[j] <= 1 - |Jn|, (2) * j in Jp j in Jn * * which is relaxation of the constraint (1) in the sense that any * solution satisfying to that constraint also satisfies to the packing * inequality (2). If such relaxation exists, the routine stores * pointers to descriptors of corresponding binary variables and their * flags, resp., to locations var[1], var[2], ..., var[len] and set[1], * set[2], ..., set[len], where set[j] = 0 means that j in Jp and * set[j] = 1 means that j in Jn. * * RETURNS * * The routine npp_implied_packing returns len, which is the total * number of binary variables in the packing inequality found, len >= 2. * However, if the relaxation does not exist, the routine returns zero. * * ALGORITHM * * If which = 0, the constraint coefficients (1) are multiplied by -1 * and b is assigned -L; if which = 1, the constraint coefficients (1) * are not changed and b is assigned +U. In both cases the specified * constraint gets the following format: * * sum a[j] x[j] <= b. (3) * j * * (Note that (3) is a relaxation of (1), because one of bounds L or U * is ignored.) * * Let J be set of binary variables, Kp be set of non-binary (integer * or continuous) variables with a[j] > 0, and Kn be set of non-binary * variables with a[j] < 0. Then the inequality (3) can be written as * follows: * * sum a[j] x[j] <= b - sum a[j] x[j] - sum a[j] x[j]. (4) * j in J j in Kp j in Kn * * To get rid of non-binary variables we can replace the inequality (4) * by the following relaxed inequality: * * sum a[j] x[j] <= b~, (5) * j in J * * where: * * b~ = sup(b - sum a[j] x[j] - sum a[j] x[j]) = * j in Kp j in Kn * * = b - inf sum a[j] x[j] - inf sum a[j] x[j] = (6) * j in Kp j in Kn * * = b - sum a[j] l[j] - sum a[j] u[j]. * j in Kp j in Kn * * Note that if lower bound l[j] (if j in Kp) or upper bound u[j] * (if j in Kn) of some non-binary variable x[j] does not exist, then * formally b = +oo, in which case further analysis is not performed. * * Let Bp = {j in J: a[j] > 0}, Bn = {j in J: a[j] < 0}. To make all * the inequality coefficients in (5) positive, we replace all x[j] in * Bn by their complementaries, substituting x[j] = 1 - x~[j] for all * j in Bn, that gives: * * sum a[j] x[j] - sum a[j] x~[j] <= b~ - sum a[j]. (7) * j in Bp j in Bn j in Bn * * This inequality is a relaxation of the original constraint (1), and * it is a binary knapsack inequality. Writing it in the standard format * we have: * * sum alfa[j] z[j] <= beta, (8) * j in J * * where: * ( + a[j], if j in Bp, * alfa[j] = < (9) * ( - a[j], if j in Bn, * * ( x[j], if j in Bp, * z[j] = < (10) * ( 1 - x[j], if j in Bn, * * beta = b~ - sum a[j]. (11) * j in Bn * * In the inequality (8) all coefficients are positive, therefore, the * packing relaxation to be found for this inequality is the following: * * sum z[j] <= 1. (12) * j in P * * It is obvious that set P within J, which we would like to find, must * satisfy to the following condition: * * alfa[j] + alfa[k] > beta + eps for all j, k in P, j != k, (13) * * where eps is an absolute tolerance for value of the linear form. * Thus, it is natural to take P = {j: alpha[j] > (beta + eps) / 2}. * Moreover, if in the equality (8) there exist coefficients alfa[k], * for which alfa[k] <= (beta + eps) / 2, but which, nevertheless, * satisfies to the condition (13) for all j in P, *one* corresponding * variable z[k] (having, for example, maximal coefficient alfa[k]) can * be included in set P, that allows increasing the number of binary * variables in (12) by one. * * Once the set P has been built, for the inequality (12) we need to * perform back substitution according to (10) in order to express it * through the original binary variables. As the result of such back * substitution the relaxed packing inequality get its final format (2), * where Jp = J intersect Bp, and Jn = J intersect Bn. */ int npp_implied_packing(NPP *npp, NPPROW *row, int which, NPPCOL *var[], char set[]) { struct elem *ptr, *e, *i, *k; int len = 0; double b, eps; /* build inequality (3) */ if (which == 0) { ptr = copy_form(npp, row, -1.0); xassert(row->lb != -DBL_MAX); b = - row->lb; } else if (which == 1) { ptr = copy_form(npp, row, +1.0); xassert(row->ub != +DBL_MAX); b = + row->ub; } /* remove non-binary variables to build relaxed inequality (5); compute its right-hand side b~ with formula (6) */ for (e = ptr; e != NULL; e = e->next) { if (!(e->xj->is_int && e->xj->lb == 0.0 && e->xj->ub == 1.0)) { /* x[j] is non-binary variable */ if (e->aj > 0.0) { if (e->xj->lb == -DBL_MAX) goto done; b -= e->aj * e->xj->lb; } else /* e->aj < 0.0 */ { if (e->xj->ub == +DBL_MAX) goto done; b -= e->aj * e->xj->ub; } /* a[j] = 0 means that variable x[j] is removed */ e->aj = 0.0; } } /* substitute x[j] = 1 - x~[j] to build knapsack inequality (8); compute its right-hand side beta with formula (11) */ for (e = ptr; e != NULL; e = e->next) if (e->aj < 0.0) b -= e->aj; /* if beta is close to zero, the knapsack inequality is either infeasible or forcing inequality; this must never happen, so we skip further analysis */ if (b < 1e-3) goto done; /* build set P as well as sets Jp and Jn, and determine x[k] as explained above in comments to the routine */ eps = 1e-3 + 1e-6 * b; i = k = NULL; for (e = ptr; e != NULL; e = e->next) { /* note that alfa[j] = |a[j]| */ if (fabs(e->aj) > 0.5 * (b + eps)) { /* alfa[j] > (b + eps) / 2; include x[j] in set P, i.e. in set Jp or Jn */ var[++len] = e->xj; set[len] = (char)(e->aj > 0.0 ? 0 : 1); /* alfa[i] = min alfa[j] over all j included in set P */ if (i == NULL || fabs(i->aj) > fabs(e->aj)) i = e; } else if (fabs(e->aj) >= 1e-3) { /* alfa[k] = max alfa[j] over all j not included in set P; we skip coefficient a[j] if it is close to zero to avoid numerically unreliable results */ if (k == NULL || fabs(k->aj) < fabs(e->aj)) k = e; } } /* if alfa[k] satisfies to condition (13) for all j in P, include x[k] in P */ if (i != NULL && k != NULL && fabs(i->aj) + fabs(k->aj) > b + eps) { var[++len] = k->xj; set[len] = (char)(k->aj > 0.0 ? 0 : 1); } /* trivial packing inequality being redundant must never appear, so we just ignore it */ if (len < 2) len = 0; done: drop_form(npp, ptr); return len; } /*********************************************************************** * NAME * * npp_is_covering - test if constraint is covering inequality * * SYNOPSIS * * #include "glpnpp.h" * int npp_is_covering(NPP *npp, NPPROW *row); * * RETURNS * * If the specified row (constraint) is covering inequality (see below), * the routine npp_is_covering returns non-zero. Otherwise, it returns * zero. * * COVERING INEQUALITIES * * In canonical format the covering inequality is the following: * * sum x[j] >= 1, (1) * j in J * * where all variables x[j] are binary. This inequality expresses the * condition that in any integer feasible solution variables in set J * cannot be all equal to zero at the same time, i.e. at least one * variable must take non-zero (unity) value. W.l.o.g. it is assumed * that |J| >= 2, because if J is empty, the inequality (1) is * infeasible, and if |J| = 1, the inequality (1) is a forcing row. * * In general case the covering inequality may include original * variables x[j] as well as their complements x~[j]: * * sum x[j] + sum x~[j] >= 1, (2) * j in Jp j in Jn * * where Jp and Jn are not intersected. Therefore, using substitution * x~[j] = 1 - x[j] gives the packing inequality in generalized format: * * sum x[j] - sum x[j] >= 1 - |Jn|. (3) * j in Jp j in Jn * * (May note that the inequality (3) cuts off infeasible solutions, * where x[j] = 0 for all j in Jp and x[j] = 1 for all j in Jn.) * * NOTE: If |J| = 2, the inequality (3) is equivalent to packing * inequality (see the routine npp_is_packing). */ int npp_is_covering(NPP *npp, NPPROW *row) { /* test if constraint is covering inequality */ NPPCOL *col; NPPAIJ *aij; int b; xassert(npp == npp); if (!(row->lb != -DBL_MAX && row->ub == +DBL_MAX)) return 0; b = 1; for (aij = row->ptr; aij != NULL; aij = aij->r_next) { col = aij->col; if (!(col->is_int && col->lb == 0.0 && col->ub == 1.0)) return 0; if (aij->val == +1.0) ; else if (aij->val == -1.0) b--; else return 0; } if (row->lb != (double)b) return 0; return 1; } /*********************************************************************** * NAME * * npp_hidden_covering - identify hidden covering inequality * * SYNOPSIS * * #include "glpnpp.h" * int npp_hidden_covering(NPP *npp, NPPROW *row); * * DESCRIPTION * * The routine npp_hidden_covering processes specified inequality * constraint, which includes only binary variables, and the number of * the variables is not less than three. If the original inequality is * equivalent to a covering inequality (see below), the routine * replaces it by the equivalent inequality. If the original constraint * is double-sided inequality, it is replaced by a pair of single-sided * inequalities, if necessary. * * RETURNS * * If the original inequality constraint was replaced by equivalent * covering inequality, the routine npp_hidden_covering returns * non-zero. Otherwise, it returns zero. * * PROBLEM TRANSFORMATION * * Consider an inequality constraint: * * sum a[j] x[j] >= b, (1) * j in J * * where all variables x[j] are binary, and |J| >= 3. (In case of '<=' * inequality it can be transformed to '>=' format by multiplying both * its sides by -1.) * * Let Jp = {j: a[j] > 0}, Jn = {j: a[j] < 0}. Performing substitution * x[j] = 1 - x~[j] for all j in Jn, we have: * * sum a[j] x[j] >= b ==> * j in J * * sum a[j] x[j] + sum a[j] x[j] >= b ==> * j in Jp j in Jn * * sum a[j] x[j] + sum a[j] (1 - x~[j]) >= b ==> * j in Jp j in Jn * * sum m a[j] x[j] - sum a[j] x~[j] >= b - sum a[j]. * j in Jp j in Jn j in Jn * * Thus, meaning the transformation above, we can assume that in * inequality (1) all coefficients a[j] are positive. Moreover, we can * assume that b > 0, because otherwise the inequality (1) would be * redundant (see the routine npp_analyze_row). It is then obvious that * constraint (1) is equivalent to covering inequality only if: * * a[j] >= b, (2) * * for all j in J. * * Once the original inequality (1) is replaced by equivalent covering * inequality, we need to perform back substitution x~[j] = 1 - x[j] for * all j in Jn (see above). * * RECOVERING SOLUTION * * None needed. */ static int hidden_covering(NPP *npp, struct elem *ptr, double *_b) { /* process inequality constraint: sum a[j] x[j] >= b; 0 - specified row is NOT hidden covering inequality; 1 - specified row is covering inequality; 2 - specified row is hidden covering inequality. */ struct elem *e; int neg; double b = *_b, eps; xassert(npp == npp); /* a[j] must be non-zero, x[j] must be binary, for all j in J */ for (e = ptr; e != NULL; e = e->next) { xassert(e->aj != 0.0); xassert(e->xj->is_int); xassert(e->xj->lb == 0.0 && e->xj->ub == 1.0); } /* check if the specified inequality constraint already has the form of covering inequality */ neg = 0; /* neg is |Jn| */ for (e = ptr; e != NULL; e = e->next) { if (e->aj == +1.0) ; else if (e->aj == -1.0) neg++; else break; } if (e == NULL) { /* all coefficients a[j] are +1 or -1; check rhs b */ if (b == (double)(1 - neg)) { /* it is covering inequality; no processing is needed */ return 1; } } /* substitute x[j] = 1 - x~[j] for all j in Jn to make all a[j] positive; the result is a~[j] = |a[j]| and new rhs b */ for (e = ptr; e != NULL; e = e->next) if (e->aj < 0) b -= e->aj; /* now a[j] > 0 for all j in J (actually |a[j]| are used) */ /* if b <= 0, skip processing--this case must not appear */ if (b < 1e-3) return 0; /* now a[j] > 0 for all j in J, and b > 0 */ /* the specified constraint is equivalent to covering inequality iff a[j] >= b for all j in J */ eps = 1e-9 + 1e-12 * fabs(b); for (e = ptr; e != NULL; e = e->next) if (fabs(e->aj) < b - eps) return 0; /* perform back substitution x~[j] = 1 - x[j] and construct the final equivalent covering inequality in generalized format */ b = 1.0; for (e = ptr; e != NULL; e = e->next) { if (e->aj > 0.0) e->aj = +1.0; else /* e->aj < 0.0 */ e->aj = -1.0, b -= 1.0; } *_b = b; return 2; } int npp_hidden_covering(NPP *npp, NPPROW *row) { /* identify hidden covering inequality */ NPPROW *copy; NPPAIJ *aij; struct elem *ptr, *e; int kase, ret, count = 0; double b; /* the row must be inequality constraint */ xassert(row->lb < row->ub); for (kase = 0; kase <= 1; kase++) { if (kase == 0) { /* process row lower bound */ if (row->lb == -DBL_MAX) continue; ptr = copy_form(npp, row, +1.0); b = + row->lb; } else { /* process row upper bound */ if (row->ub == +DBL_MAX) continue; ptr = copy_form(npp, row, -1.0); b = - row->ub; } /* now the inequality has the form "sum a[j] x[j] >= b" */ ret = hidden_covering(npp, ptr, &b); xassert(0 <= ret && ret <= 2); if (kase == 1 && ret == 1 || ret == 2) { /* the original inequality has been identified as hidden covering inequality */ count++; #ifdef GLP_DEBUG xprintf("Original constraint:\n"); for (aij = row->ptr; aij != NULL; aij = aij->r_next) xprintf(" %+g x%d", aij->val, aij->col->j); if (row->lb != -DBL_MAX) xprintf(", >= %g", row->lb); if (row->ub != +DBL_MAX) xprintf(", <= %g", row->ub); xprintf("\n"); xprintf("Equivalent covering inequality:\n"); for (e = ptr; e != NULL; e = e->next) xprintf(" %sx%d", e->aj > 0.0 ? "+" : "-", e->xj->j); xprintf(", >= %g\n", b); #endif if (row->lb == -DBL_MAX || row->ub == +DBL_MAX) { /* the original row is single-sided inequality; no copy is needed */ copy = NULL; } else { /* the original row is double-sided inequality; we need to create its copy for other bound before replacing it with the equivalent inequality */ copy = npp_add_row(npp); if (kase == 0) { /* the copy is for upper bound */ copy->lb = -DBL_MAX, copy->ub = row->ub; } else { /* the copy is for lower bound */ copy->lb = row->lb, copy->ub = +DBL_MAX; } /* copy original row coefficients */ for (aij = row->ptr; aij != NULL; aij = aij->r_next) npp_add_aij(npp, copy, aij->col, aij->val); } /* replace the original inequality by equivalent one */ npp_erase_row(npp, row); row->lb = b, row->ub = +DBL_MAX; for (e = ptr; e != NULL; e = e->next) npp_add_aij(npp, row, e->xj, e->aj); /* continue processing upper bound for the copy */ if (copy != NULL) row = copy; } drop_form(npp, ptr); } return count; } /*********************************************************************** * NAME * * npp_is_partitioning - test if constraint is partitioning equality * * SYNOPSIS * * #include "glpnpp.h" * int npp_is_partitioning(NPP *npp, NPPROW *row); * * RETURNS * * If the specified row (constraint) is partitioning equality (see * below), the routine npp_is_partitioning returns non-zero. Otherwise, * it returns zero. * * PARTITIONING EQUALITIES * * In canonical format the partitioning equality is the following: * * sum x[j] = 1, (1) * j in J * * where all variables x[j] are binary. This equality expresses the * condition that in any integer feasible solution exactly one variable * in set J must take non-zero (unity) value while other variables must * be equal to zero. W.l.o.g. it is assumed that |J| >= 2, because if * J is empty, the inequality (1) is infeasible, and if |J| = 1, the * inequality (1) is a fixing row. * * In general case the partitioning equality may include original * variables x[j] as well as their complements x~[j]: * * sum x[j] + sum x~[j] = 1, (2) * j in Jp j in Jn * * where Jp and Jn are not intersected. Therefore, using substitution * x~[j] = 1 - x[j] leads to the partitioning equality in generalized * format: * * sum x[j] - sum x[j] = 1 - |Jn|. (3) * j in Jp j in Jn */ int npp_is_partitioning(NPP *npp, NPPROW *row) { /* test if constraint is partitioning equality */ NPPCOL *col; NPPAIJ *aij; int b; xassert(npp == npp); if (row->lb != row->ub) return 0; b = 1; for (aij = row->ptr; aij != NULL; aij = aij->r_next) { col = aij->col; if (!(col->is_int && col->lb == 0.0 && col->ub == 1.0)) return 0; if (aij->val == +1.0) ; else if (aij->val == -1.0) b--; else return 0; } if (row->lb != (double)b) return 0; return 1; } /*********************************************************************** * NAME * * npp_reduce_ineq_coef - reduce inequality constraint coefficients * * SYNOPSIS * * #include "glpnpp.h" * int npp_reduce_ineq_coef(NPP *npp, NPPROW *row); * * DESCRIPTION * * The routine npp_reduce_ineq_coef processes specified inequality * constraint attempting to replace it by an equivalent constraint, * where magnitude of coefficients at binary variables is smaller than * in the original constraint. If the inequality is double-sided, it is * replaced by a pair of single-sided inequalities, if necessary. * * RETURNS * * The routine npp_reduce_ineq_coef returns the number of coefficients * reduced. * * BACKGROUND * * Consider an inequality constraint: * * sum a[j] x[j] >= b. (1) * j in J * * (In case of '<=' inequality it can be transformed to '>=' format by * multiplying both its sides by -1.) Let x[k] be a binary variable; * other variables can be integer as well as continuous. We can write * constraint (1) as follows: * * a[k] x[k] + t[k] >= b, (2) * * where: * * t[k] = sum a[j] x[j]. (3) * j in J\{k} * * Since x[k] is binary, constraint (2) is equivalent to disjunction of * the following two constraints: * * x[k] = 0, t[k] >= b (4) * * OR * * x[k] = 1, t[k] >= b - a[k]. (5) * * Let also that for the partial sum t[k] be known some its implied * lower bound inf t[k]. * * Case a[k] > 0. Let inf t[k] < b, since otherwise both constraints * (4) and (5) and therefore constraint (2) are redundant. * If inf t[k] > b - a[k], only constraint (5) is redundant, in which * case it can be replaced with the following redundant and therefore * equivalent constraint: * * t[k] >= b - a'[k] = inf t[k], (6) * * where: * * a'[k] = b - inf t[k]. (7) * * Thus, the original constraint (2) is equivalent to the following * constraint with coefficient at variable x[k] changed: * * a'[k] x[k] + t[k] >= b. (8) * * From inf t[k] < b it follows that a'[k] > 0, i.e. the coefficient * at x[k] keeps its sign. And from inf t[k] > b - a[k] it follows that * a'[k] < a[k], i.e. the coefficient reduces in magnitude. * * Case a[k] < 0. Let inf t[k] < b - a[k], since otherwise both * constraints (4) and (5) and therefore constraint (2) are redundant. * If inf t[k] > b, only constraint (4) is redundant, in which case it * can be replaced with the following redundant and therefore equivalent * constraint: * * t[k] >= b' = inf t[k]. (9) * * Rewriting constraint (5) as follows: * * t[k] >= b - a[k] = b' - a'[k], (10) * * where: * * a'[k] = a[k] + b' - b = a[k] + inf t[k] - b, (11) * * we can see that disjunction of constraint (9) and (10) is equivalent * to disjunction of constraint (4) and (5), from which it follows that * the original constraint (2) is equivalent to the following constraint * with both coefficient at variable x[k] and right-hand side changed: * * a'[k] x[k] + t[k] >= b'. (12) * * From inf t[k] < b - a[k] it follows that a'[k] < 0, i.e. the * coefficient at x[k] keeps its sign. And from inf t[k] > b it follows * that a'[k] > a[k], i.e. the coefficient reduces in magnitude. * * PROBLEM TRANSFORMATION * * In the routine npp_reduce_ineq_coef the following implied lower * bound of the partial sum (3) is used: * * inf t[k] = sum a[j] l[j] + sum a[j] u[j], (13) * j in Jp\{k} k in Jn\{k} * * where Jp = {j : a[j] > 0}, Jn = {j : a[j] < 0}, l[j] and u[j] are * lower and upper bounds, resp., of variable x[j]. * * In order to compute inf t[k] more efficiently, the following formula, * which is equivalent to (13), is actually used: * * ( h - a[k] l[k] = h, if a[k] > 0, * inf t[k] = < (14) * ( h - a[k] u[k] = h - a[k], if a[k] < 0, * * where: * * h = sum a[j] l[j] + sum a[j] u[j] (15) * j in Jp j in Jn * * is the implied lower bound of row (1). * * Reduction of positive coefficient (a[k] > 0) does not change value * of h, since l[k] = 0. In case of reduction of negative coefficient * (a[k] < 0) from (11) it follows that: * * delta a[k] = a'[k] - a[k] = inf t[k] - b (> 0), (16) * * so new value of h (accounting that u[k] = 1) can be computed as * follows: * * h := h + delta a[k] = h + (inf t[k] - b). (17) * * RECOVERING SOLUTION * * None needed. */ static int reduce_ineq_coef(NPP *npp, struct elem *ptr, double *_b) { /* process inequality constraint: sum a[j] x[j] >= b */ /* returns: the number of coefficients reduced */ struct elem *e; int count = 0; double h, inf_t, new_a, b = *_b; xassert(npp == npp); /* compute h; see (15) */ h = 0.0; for (e = ptr; e != NULL; e = e->next) { if (e->aj > 0.0) { if (e->xj->lb == -DBL_MAX) goto done; h += e->aj * e->xj->lb; } else /* e->aj < 0.0 */ { if (e->xj->ub == +DBL_MAX) goto done; h += e->aj * e->xj->ub; } } /* perform reduction of coefficients at binary variables */ for (e = ptr; e != NULL; e = e->next) { /* skip non-binary variable */ if (!(e->xj->is_int && e->xj->lb == 0.0 && e->xj->ub == 1.0)) continue; if (e->aj > 0.0) { /* compute inf t[k]; see (14) */ inf_t = h; if (b - e->aj < inf_t && inf_t < b) { /* compute reduced coefficient a'[k]; see (7) */ new_a = b - inf_t; if (new_a >= +1e-3 && e->aj - new_a >= 0.01 * (1.0 + e->aj)) { /* accept a'[k] */ #ifdef GLP_DEBUG xprintf("+"); #endif e->aj = new_a; count++; } } } else /* e->aj < 0.0 */ { /* compute inf t[k]; see (14) */ inf_t = h - e->aj; if (b < inf_t && inf_t < b - e->aj) { /* compute reduced coefficient a'[k]; see (11) */ new_a = e->aj + (inf_t - b); if (new_a <= -1e-3 && new_a - e->aj >= 0.01 * (1.0 - e->aj)) { /* accept a'[k] */ #ifdef GLP_DEBUG xprintf("-"); #endif e->aj = new_a; /* update h; see (17) */ h += (inf_t - b); /* compute b'; see (9) */ b = inf_t; count++; } } } } *_b = b; done: return count; } int npp_reduce_ineq_coef(NPP *npp, NPPROW *row) { /* reduce inequality constraint coefficients */ NPPROW *copy; NPPAIJ *aij; struct elem *ptr, *e; int kase, count[2]; double b; /* the row must be inequality constraint */ xassert(row->lb < row->ub); count[0] = count[1] = 0; for (kase = 0; kase <= 1; kase++) { if (kase == 0) { /* process row lower bound */ if (row->lb == -DBL_MAX) continue; #ifdef GLP_DEBUG xprintf("L"); #endif ptr = copy_form(npp, row, +1.0); b = + row->lb; } else { /* process row upper bound */ if (row->ub == +DBL_MAX) continue; #ifdef GLP_DEBUG xprintf("U"); #endif ptr = copy_form(npp, row, -1.0); b = - row->ub; } /* now the inequality has the form "sum a[j] x[j] >= b" */ count[kase] = reduce_ineq_coef(npp, ptr, &b); if (count[kase] > 0) { /* the original inequality has been replaced by equivalent one with coefficients reduced */ if (row->lb == -DBL_MAX || row->ub == +DBL_MAX) { /* the original row is single-sided inequality; no copy is needed */ copy = NULL; } else { /* the original row is double-sided inequality; we need to create its copy for other bound before replacing it with the equivalent inequality */ #ifdef GLP_DEBUG xprintf("*"); #endif copy = npp_add_row(npp); if (kase == 0) { /* the copy is for upper bound */ copy->lb = -DBL_MAX, copy->ub = row->ub; } else { /* the copy is for lower bound */ copy->lb = row->lb, copy->ub = +DBL_MAX; } /* copy original row coefficients */ for (aij = row->ptr; aij != NULL; aij = aij->r_next) npp_add_aij(npp, copy, aij->col, aij->val); } /* replace the original inequality by equivalent one */ npp_erase_row(npp, row); row->lb = b, row->ub = +DBL_MAX; for (e = ptr; e != NULL; e = e->next) npp_add_aij(npp, row, e->xj, e->aj); /* continue processing upper bound for the copy */ if (copy != NULL) row = copy; } drop_form(npp, ptr); } return count[0] + count[1]; } /* eof */ praat-6.0.04/external/glpk/glpnpp05.c000066400000000000000000000637751261542461700173320ustar00rootroot00000000000000/* glpnpp05.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpnpp.h" /*********************************************************************** * NAME * * npp_clean_prob - perform initial LP/MIP processing * * SYNOPSIS * * #include "glpnpp.h" * void npp_clean_prob(NPP *npp); * * DESCRIPTION * * The routine npp_clean_prob performs initial LP/MIP processing that * currently includes: * * 1) removing free rows; * * 2) replacing double-sided constraint rows with almost identical * bounds, by equality constraint rows; * * 3) removing fixed columns; * * 4) replacing double-bounded columns with almost identical bounds by * fixed columns and removing those columns; * * 5) initial processing constraint coefficients (not implemented); * * 6) initial processing objective coefficients (not implemented). */ void npp_clean_prob(NPP *npp) { /* perform initial LP/MIP processing */ NPPROW *row, *next_row; NPPCOL *col, *next_col; int ret; xassert(npp == npp); /* process rows which originally are free */ for (row = npp->r_head; row != NULL; row = next_row) { next_row = row->next; if (row->lb == -DBL_MAX && row->ub == +DBL_MAX) { /* process free row */ #ifdef GLP_DEBUG xprintf("1"); #endif npp_free_row(npp, row); /* row was deleted */ } } /* process rows which originally are double-sided inequalities */ for (row = npp->r_head; row != NULL; row = next_row) { next_row = row->next; if (row->lb != -DBL_MAX && row->ub != +DBL_MAX && row->lb < row->ub) { ret = npp_make_equality(npp, row); if (ret == 0) ; else if (ret == 1) { /* row was replaced by equality constraint */ #ifdef GLP_DEBUG xprintf("2"); #endif } else xassert(ret != ret); } } /* process columns which are originally fixed */ for (col = npp->c_head; col != NULL; col = next_col) { next_col = col->next; if (col->lb == col->ub) { /* process fixed column */ #ifdef GLP_DEBUG xprintf("3"); #endif npp_fixed_col(npp, col); /* column was deleted */ } } /* process columns which are originally double-bounded */ for (col = npp->c_head; col != NULL; col = next_col) { next_col = col->next; if (col->lb != -DBL_MAX && col->ub != +DBL_MAX && col->lb < col->ub) { ret = npp_make_fixed(npp, col); if (ret == 0) ; else if (ret == 1) { /* column was replaced by fixed column; process it */ #ifdef GLP_DEBUG xprintf("4"); #endif npp_fixed_col(npp, col); /* column was deleted */ } } } return; } /*********************************************************************** * NAME * * npp_process_row - perform basic row processing * * SYNOPSIS * * #include "glpnpp.h" * int npp_process_row(NPP *npp, NPPROW *row, int hard); * * DESCRIPTION * * The routine npp_process_row performs basic row processing that * currently includes: * * 1) removing empty row; * * 2) removing equality constraint row singleton and corresponding * column; * * 3) removing inequality constraint row singleton and corresponding * column if it was fixed; * * 4) performing general row analysis; * * 5) removing redundant row bounds; * * 6) removing forcing row and corresponding columns; * * 7) removing row which becomes free due to redundant bounds; * * 8) computing implied bounds for all columns in the row and using * them to strengthen current column bounds (MIP only, optional, * performed if the flag hard is on). * * Additionally the routine may activate affected rows and/or columns * for further processing. * * RETURNS * * 0 success; * * GLP_ENOPFS primal/integer infeasibility detected; * * GLP_ENODFS dual infeasibility detected. */ int npp_process_row(NPP *npp, NPPROW *row, int hard) { /* perform basic row processing */ NPPCOL *col; NPPAIJ *aij, *next_aij, *aaa; int ret; /* row must not be free */ xassert(!(row->lb == -DBL_MAX && row->ub == +DBL_MAX)); /* start processing row */ if (row->ptr == NULL) { /* empty row */ ret = npp_empty_row(npp, row); if (ret == 0) { /* row was deleted */ #ifdef GLP_DEBUG xprintf("A"); #endif return 0; } else if (ret == 1) { /* primal infeasibility */ return GLP_ENOPFS; } else xassert(ret != ret); } if (row->ptr->r_next == NULL) { /* row singleton */ col = row->ptr->col; if (row->lb == row->ub) { /* equality constraint */ ret = npp_eq_singlet(npp, row); if (ret == 0) { /* column was fixed, row was deleted */ #ifdef GLP_DEBUG xprintf("B"); #endif /* activate rows affected by column */ for (aij = col->ptr; aij != NULL; aij = aij->c_next) npp_activate_row(npp, aij->row); /* process fixed column */ npp_fixed_col(npp, col); /* column was deleted */ return 0; } else if (ret == 1 || ret == 2) { /* primal/integer infeasibility */ return GLP_ENOPFS; } else xassert(ret != ret); } else { /* inequality constraint */ ret = npp_ineq_singlet(npp, row); if (0 <= ret && ret <= 3) { /* row was deleted */ #ifdef GLP_DEBUG xprintf("C"); #endif /* activate column, since its length was changed due to row deletion */ npp_activate_col(npp, col); if (ret >= 2) { /* column bounds changed significantly or column was fixed */ /* activate rows affected by column */ for (aij = col->ptr; aij != NULL; aij = aij->c_next) npp_activate_row(npp, aij->row); } if (ret == 3) { /* column was fixed; process it */ #ifdef GLP_DEBUG xprintf("D"); #endif npp_fixed_col(npp, col); /* column was deleted */ } return 0; } else if (ret == 4) { /* primal infeasibility */ return GLP_ENOPFS; } else xassert(ret != ret); } } #if 0 /* sometimes this causes too large round-off errors; probably pivot coefficient should be chosen more carefully */ if (row->ptr->r_next->r_next == NULL) { /* row doubleton */ if (row->lb == row->ub) { /* equality constraint */ if (!(row->ptr->col->is_int || row->ptr->r_next->col->is_int)) { /* both columns are continuous */ NPPCOL *q; q = npp_eq_doublet(npp, row); if (q != NULL) { /* column q was eliminated */ #ifdef GLP_DEBUG xprintf("E"); #endif /* now column q is singleton of type "implied slack variable"; we process it here to make sure that on recovering basic solution the row is always active equality constraint (as required by the routine rcv_eq_doublet) */ xassert(npp_process_col(npp, q) == 0); /* column q was deleted; note that row p also may be deleted */ return 0; } } } } #endif /* general row analysis */ ret = npp_analyze_row(npp, row); xassert(0x00 <= ret && ret <= 0xFF); if (ret == 0x33) { /* row bounds are inconsistent with column bounds */ return GLP_ENOPFS; } if ((ret & 0x0F) == 0x00) { /* row lower bound does not exist or redundant */ if (row->lb != -DBL_MAX) { /* remove redundant row lower bound */ #ifdef GLP_DEBUG xprintf("F"); #endif npp_inactive_bound(npp, row, 0); } } else if ((ret & 0x0F) == 0x01) { /* row lower bound can be active */ /* see below */ } else if ((ret & 0x0F) == 0x02) { /* row lower bound is a forcing bound */ #ifdef GLP_DEBUG xprintf("G"); #endif /* process forcing row */ if (npp_forcing_row(npp, row, 0) == 0) fixup: { /* columns were fixed, row was made free */ for (aij = row->ptr; aij != NULL; aij = next_aij) { /* process column fixed by forcing row */ #ifdef GLP_DEBUG xprintf("H"); #endif col = aij->col; next_aij = aij->r_next; /* activate rows affected by column */ for (aaa = col->ptr; aaa != NULL; aaa = aaa->c_next) npp_activate_row(npp, aaa->row); /* process fixed column */ npp_fixed_col(npp, col); /* column was deleted */ } /* process free row (which now is empty due to deletion of all its columns) */ npp_free_row(npp, row); /* row was deleted */ return 0; } } else xassert(ret != ret); if ((ret & 0xF0) == 0x00) { /* row upper bound does not exist or redundant */ if (row->ub != +DBL_MAX) { /* remove redundant row upper bound */ #ifdef GLP_DEBUG xprintf("I"); #endif npp_inactive_bound(npp, row, 1); } } else if ((ret & 0xF0) == 0x10) { /* row upper bound can be active */ /* see below */ } else if ((ret & 0xF0) == 0x20) { /* row upper bound is a forcing bound */ #ifdef GLP_DEBUG xprintf("J"); #endif /* process forcing row */ if (npp_forcing_row(npp, row, 1) == 0) goto fixup; } else xassert(ret != ret); if (row->lb == -DBL_MAX && row->ub == +DBL_MAX) { /* row became free due to redundant bounds removal */ #ifdef GLP_DEBUG xprintf("K"); #endif /* activate its columns, since their length will change due to row deletion */ for (aij = row->ptr; aij != NULL; aij = aij->r_next) npp_activate_col(npp, aij->col); /* process free row */ npp_free_row(npp, row); /* row was deleted */ return 0; } #if 1 /* 23/XII-2009 */ /* row lower and/or upper bounds can be active */ if (npp->sol == GLP_MIP && hard) { /* improve current column bounds (optional) */ if (npp_improve_bounds(npp, row, 1) < 0) return GLP_ENOPFS; } #endif return 0; } /*********************************************************************** * NAME * * npp_improve_bounds - improve current column bounds * * SYNOPSIS * * #include "glpnpp.h" * int npp_improve_bounds(NPP *npp, NPPROW *row, int flag); * * DESCRIPTION * * The routine npp_improve_bounds analyzes specified row (inequality * or equality constraint) to determine implied column bounds and then * uses these bounds to improve (strengthen) current column bounds. * * If the flag is on and current column bounds changed significantly * or the column was fixed, the routine activate rows affected by the * column for further processing. (This feature is intended to be used * in the main loop of the routine npp_process_row.) * * NOTE: This operation can be used for MIP problem only. * * RETURNS * * The routine npp_improve_bounds returns the number of significantly * changed bounds plus the number of column having been fixed due to * bound improvements. However, if the routine detects primal/integer * infeasibility, it returns a negative value. */ int npp_improve_bounds(NPP *npp, NPPROW *row, int flag) { /* improve current column bounds */ NPPCOL *col; NPPAIJ *aij, *next_aij, *aaa; int kase, ret, count = 0; double lb, ub; xassert(npp->sol == GLP_MIP); /* row must not be free */ xassert(!(row->lb == -DBL_MAX && row->ub == +DBL_MAX)); /* determine implied column bounds */ npp_implied_bounds(npp, row); /* and use these bounds to strengthen current column bounds */ for (aij = row->ptr; aij != NULL; aij = next_aij) { col = aij->col; next_aij = aij->r_next; for (kase = 0; kase <= 1; kase++) { /* save current column bounds */ lb = col->lb, ub = col->ub; if (kase == 0) { /* process implied column lower bound */ if (col->ll.ll == -DBL_MAX) continue; ret = npp_implied_lower(npp, col, col->ll.ll); } else { /* process implied column upper bound */ if (col->uu.uu == +DBL_MAX) continue; ret = npp_implied_upper(npp, col, col->uu.uu); } if (ret == 0 || ret == 1) { /* current column bounds did not change or changed, but not significantly; restore current column bounds */ col->lb = lb, col->ub = ub; } else if (ret == 2 || ret == 3) { /* current column bounds changed significantly or column was fixed */ #ifdef GLP_DEBUG xprintf("L"); #endif count++; /* activate other rows affected by column, if required */ if (flag) { for (aaa = col->ptr; aaa != NULL; aaa = aaa->c_next) { if (aaa->row != row) npp_activate_row(npp, aaa->row); } } if (ret == 3) { /* process fixed column */ #ifdef GLP_DEBUG xprintf("M"); #endif npp_fixed_col(npp, col); /* column was deleted */ break; /* for kase */ } } else if (ret == 4) { /* primal/integer infeasibility */ return -1; } else xassert(ret != ret); } } return count; } /*********************************************************************** * NAME * * npp_process_col - perform basic column processing * * SYNOPSIS * * #include "glpnpp.h" * int npp_process_col(NPP *npp, NPPCOL *col); * * DESCRIPTION * * The routine npp_process_col performs basic column processing that * currently includes: * * 1) fixing and removing empty column; * * 2) removing column singleton, which is implied slack variable, and * corresponding row if it becomes free; * * 3) removing bounds of column, which is implied free variable, and * replacing corresponding row by equality constraint. * * Additionally the routine may activate affected rows and/or columns * for further processing. * * RETURNS * * 0 success; * * GLP_ENOPFS primal/integer infeasibility detected; * * GLP_ENODFS dual infeasibility detected. */ int npp_process_col(NPP *npp, NPPCOL *col) { /* perform basic column processing */ NPPROW *row; NPPAIJ *aij; int ret; /* column must not be fixed */ xassert(col->lb < col->ub); /* start processing column */ if (col->ptr == NULL) { /* empty column */ ret = npp_empty_col(npp, col); if (ret == 0) { /* column was fixed and deleted */ #ifdef GLP_DEBUG xprintf("N"); #endif return 0; } else if (ret == 1) { /* dual infeasibility */ return GLP_ENODFS; } else xassert(ret != ret); } if (col->ptr->c_next == NULL) { /* column singleton */ row = col->ptr->row; if (row->lb == row->ub) { /* equality constraint */ if (!col->is_int) slack: { /* implied slack variable */ #ifdef GLP_DEBUG xprintf("O"); #endif npp_implied_slack(npp, col); /* column was deleted */ if (row->lb == -DBL_MAX && row->ub == +DBL_MAX) { /* row became free due to implied slack variable */ #ifdef GLP_DEBUG xprintf("P"); #endif /* activate columns affected by row */ for (aij = row->ptr; aij != NULL; aij = aij->r_next) npp_activate_col(npp, aij->col); /* process free row */ npp_free_row(npp, row); /* row was deleted */ } else { /* row became inequality constraint; activate it since its length changed due to column deletion */ npp_activate_row(npp, row); } return 0; } } else { /* inequality constraint */ if (!col->is_int) { ret = npp_implied_free(npp, col); if (ret == 0) { /* implied free variable */ #ifdef GLP_DEBUG xprintf("Q"); #endif /* column bounds were removed, row was replaced by equality constraint */ goto slack; } else if (ret == 1) { /* column is not implied free variable, because its lower and/or upper bounds can be active */ } else if (ret == 2) { /* dual infeasibility */ return GLP_ENODFS; } } } } /* column still exists */ return 0; } /*********************************************************************** * NAME * * npp_process_prob - perform basic LP/MIP processing * * SYNOPSIS * * #include "glpnpp.h" * int npp_process_prob(NPP *npp, int hard); * * DESCRIPTION * * The routine npp_process_prob performs basic LP/MIP processing that * currently includes: * * 1) initial LP/MIP processing (see the routine npp_clean_prob), * * 2) basic row processing (see the routine npp_process_row), and * * 3) basic column processing (see the routine npp_process_col). * * If the flag hard is on, the routine attempts to improve current * column bounds multiple times within the main processing loop, in * which case this feature may take a time. Otherwise, if the flag hard * is off, improving column bounds is performed only once at the end of * the main loop. (Note that this feature is used for MIP only.) * * The routine uses two sets: the set of active rows and the set of * active columns. Rows/columns are marked by a flag (the field temp in * NPPROW/NPPCOL). If the flag is non-zero, the row/column is active, * in which case it is placed in the beginning of the row/column list; * otherwise, if the flag is zero, the row/column is inactive, in which * case it is placed in the end of the row/column list. If a row/column * being currently processed may affect other rows/columns, the latters * are activated for further processing. * * RETURNS * * 0 success; * * GLP_ENOPFS primal/integer infeasibility detected; * * GLP_ENODFS dual infeasibility detected. */ int npp_process_prob(NPP *npp, int hard) { /* perform basic LP/MIP processing */ NPPROW *row; NPPCOL *col; int processing, ret; /* perform initial LP/MIP processing */ npp_clean_prob(npp); /* activate all remaining rows and columns */ for (row = npp->r_head; row != NULL; row = row->next) row->temp = 1; for (col = npp->c_head; col != NULL; col = col->next) col->temp = 1; /* main processing loop */ processing = 1; while (processing) { processing = 0; /* process all active rows */ for (;;) { row = npp->r_head; if (row == NULL || !row->temp) break; npp_deactivate_row(npp, row); ret = npp_process_row(npp, row, hard); if (ret != 0) goto done; processing = 1; } /* process all active columns */ for (;;) { col = npp->c_head; if (col == NULL || !col->temp) break; npp_deactivate_col(npp, col); ret = npp_process_col(npp, col); if (ret != 0) goto done; processing = 1; } } #if 1 /* 23/XII-2009 */ if (npp->sol == GLP_MIP && !hard) { /* improve current column bounds (optional) */ for (row = npp->r_head; row != NULL; row = row->next) { if (npp_improve_bounds(npp, row, 0) < 0) { ret = GLP_ENOPFS; goto done; } } } #endif /* all seems ok */ ret = 0; done: xassert(ret == 0 || ret == GLP_ENOPFS || ret == GLP_ENODFS); #ifdef GLP_DEBUG xprintf("\n"); #endif return ret; } /**********************************************************************/ int npp_simplex(NPP *npp, const glp_smcp *parm) { /* process LP prior to applying primal/dual simplex method */ int ret; xassert(npp->sol == GLP_SOL); xassert(parm == parm); ret = npp_process_prob(npp, 0); return ret; } /**********************************************************************/ int npp_integer(NPP *npp, const glp_iocp *parm) { /* process MIP prior to applying branch-and-bound method */ NPPROW *row, *prev_row; NPPCOL *col; NPPAIJ *aij; int count, ret; xassert(npp->sol == GLP_MIP); xassert(parm == parm); /*==============================================================*/ /* perform basic MIP processing */ ret = npp_process_prob(npp, 1); if (ret != 0) goto done; /*==============================================================*/ /* binarize problem, if required */ if (parm->binarize) npp_binarize_prob(npp); /*==============================================================*/ /* identify hidden packing inequalities */ count = 0; /* new rows will be added to the end of the row list, so we go from the end to beginning of the row list */ for (row = npp->r_tail; row != NULL; row = prev_row) { prev_row = row->prev; /* skip free row */ if (row->lb == -DBL_MAX && row->ub == +DBL_MAX) continue; /* skip equality constraint */ if (row->lb == row->ub) continue; /* skip row having less than two variables */ if (row->ptr == NULL || row->ptr->r_next == NULL) continue; /* skip row having non-binary variables */ for (aij = row->ptr; aij != NULL; aij = aij->r_next) { col = aij->col; if (!(col->is_int && col->lb == 0.0 && col->ub == 1.0)) break; } if (aij != NULL) continue; count += npp_hidden_packing(npp, row); } if (count > 0) xprintf("%d hidden packing inequaliti(es) were detected\n", count); /*==============================================================*/ /* identify hidden covering inequalities */ count = 0; /* new rows will be added to the end of the row list, so we go from the end to beginning of the row list */ for (row = npp->r_tail; row != NULL; row = prev_row) { prev_row = row->prev; /* skip free row */ if (row->lb == -DBL_MAX && row->ub == +DBL_MAX) continue; /* skip equality constraint */ if (row->lb == row->ub) continue; /* skip row having less than three variables */ if (row->ptr == NULL || row->ptr->r_next == NULL || row->ptr->r_next->r_next == NULL) continue; /* skip row having non-binary variables */ for (aij = row->ptr; aij != NULL; aij = aij->r_next) { col = aij->col; if (!(col->is_int && col->lb == 0.0 && col->ub == 1.0)) break; } if (aij != NULL) continue; count += npp_hidden_covering(npp, row); } if (count > 0) xprintf("%d hidden covering inequaliti(es) were detected\n", count); /*==============================================================*/ /* reduce inequality constraint coefficients */ count = 0; /* new rows will be added to the end of the row list, so we go from the end to beginning of the row list */ for (row = npp->r_tail; row != NULL; row = prev_row) { prev_row = row->prev; /* skip equality constraint */ if (row->lb == row->ub) continue; count += npp_reduce_ineq_coef(npp, row); } if (count > 0) xprintf("%d constraint coefficient(s) were reduced\n", count); /*==============================================================*/ #ifdef GLP_DEBUG routine(npp); #endif /*==============================================================*/ /* all seems ok */ ret = 0; done: return ret; } /* eof */ praat-6.0.04/external/glpk/glpqmd.c000066400000000000000000000435651261542461700171440ustar00rootroot00000000000000/* glpqmd.c (quotient minimum degree algorithm) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * THIS CODE IS THE RESULT OF TRANSLATION OF THE FORTRAN SUBROUTINES * GENQMD, QMDRCH, QMDQT, QMDUPD, AND QMDMRG FROM THE BOOK: * * ALAN GEORGE, JOSEPH W-H LIU. COMPUTER SOLUTION OF LARGE SPARSE * POSITIVE DEFINITE SYSTEMS. PRENTICE-HALL, 1981. * * THE TRANSLATION HAS BEEN DONE WITH THE PERMISSION OF THE AUTHORS * OF THE ORIGINAL FORTRAN SUBROUTINES: ALAN GEORGE AND JOSEPH LIU, * UNIVERSITY OF WATERLOO, WATERLOO, ONTARIO, CANADA. * * The translation was made by Andrew Makhorin . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpqmd.h" /*********************************************************************** * NAME * * genqmd - GENeral Quotient Minimum Degree algorithm * * SYNOPSIS * * #include "glpqmd.h" * void genqmd(int *neqns, int xadj[], int adjncy[], int perm[], * int invp[], int deg[], int marker[], int rchset[], int nbrhd[], * int qsize[], int qlink[], int *nofsub); * * PURPOSE * * This routine implements the minimum degree algorithm. It makes use * of the implicit representation of the elimination graph by quotient * graphs, and the notion of indistinguishable nodes. * * CAUTION * * The adjancy vector adjncy will be destroyed. * * INPUT PARAMETERS * * neqns - number of equations; * (xadj, adjncy) - * the adjancy structure. * * OUTPUT PARAMETERS * * perm - the minimum degree ordering; * invp - the inverse of perm. * * WORKING PARAMETERS * * deg - the degree vector. deg[i] is negative means node i has been * numbered; * marker - a marker vector, where marker[i] is negative means node i * has been merged with another nodeand thus can be ignored; * rchset - vector used for the reachable set; * nbrhd - vector used for neighborhood set; * qsize - vector used to store the size of indistinguishable * supernodes; * qlink - vector used to store indistinguishable nodes, i, qlink[i], * qlink[qlink[i]], ... are the members of the supernode * represented by i. * * PROGRAM SUBROUTINES * * qmdrch, qmdqt, qmdupd. ***********************************************************************/ void genqmd(int *_neqns, int xadj[], int adjncy[], int perm[], int invp[], int deg[], int marker[], int rchset[], int nbrhd[], int qsize[], int qlink[], int *_nofsub) { int inode, ip, irch, j, mindeg, ndeg, nhdsze, node, np, num, nump1, nxnode, rchsze, search, thresh; # define neqns (*_neqns) # define nofsub (*_nofsub) /* Initialize degree vector and other working variables. */ mindeg = neqns; nofsub = 0; for (node = 1; node <= neqns; node++) { perm[node] = node; invp[node] = node; marker[node] = 0; qsize[node] = 1; qlink[node] = 0; ndeg = xadj[node+1] - xadj[node]; deg[node] = ndeg; if (ndeg < mindeg) mindeg = ndeg; } num = 0; /* Perform threshold search to get a node of min degree. Variable search point to where search should start. */ s200: search = 1; thresh = mindeg; mindeg = neqns; s300: nump1 = num + 1; if (nump1 > search) search = nump1; for (j = search; j <= neqns; j++) { node = perm[j]; if (marker[node] >= 0) { ndeg = deg[node]; if (ndeg <= thresh) goto s500; if (ndeg < mindeg) mindeg = ndeg; } } goto s200; /* Node has minimum degree. Find its reachable sets by calling qmdrch. */ s500: search = j; nofsub += deg[node]; marker[node] = 1; qmdrch(&node, xadj, adjncy, deg, marker, &rchsze, rchset, &nhdsze, nbrhd); /* Eliminate all nodes indistinguishable from node. They are given by node, qlink[node], ... . */ nxnode = node; s600: num++; np = invp[nxnode]; ip = perm[num]; perm[np] = ip; invp[ip] = np; perm[num] = nxnode; invp[nxnode] = num; deg[nxnode] = -1; nxnode = qlink[nxnode]; if (nxnode > 0) goto s600; if (rchsze > 0) { /* Update the degrees of the nodes in the reachable set and identify indistinguishable nodes. */ qmdupd(xadj, adjncy, &rchsze, rchset, deg, qsize, qlink, marker, &rchset[rchsze+1], &nbrhd[nhdsze+1]); /* Reset marker value of nodes in reach set. Update threshold value for cyclic search. Also call qmdqt to form new quotient graph. */ marker[node] = 0; for (irch = 1; irch <= rchsze; irch++) { inode = rchset[irch]; if (marker[inode] >= 0) { marker[inode] = 0; ndeg = deg[inode]; if (ndeg < mindeg) mindeg = ndeg; if (ndeg <= thresh) { mindeg = thresh; thresh = ndeg; search = invp[inode]; } } } if (nhdsze > 0) qmdqt(&node, xadj, adjncy, marker, &rchsze, rchset, nbrhd); } if (num < neqns) goto s300; return; # undef neqns # undef nofsub } /*********************************************************************** * NAME * * qmdrch - Quotient MD ReaCHable set * * SYNOPSIS * * #include "glpqmd.h" * void qmdrch(int *root, int xadj[], int adjncy[], int deg[], * int marker[], int *rchsze, int rchset[], int *nhdsze, * int nbrhd[]); * * PURPOSE * * This subroutine determines the reachable set of a node through a * given subset. The adjancy structure is assumed to be stored in a * quotient graph format. * * INPUT PARAMETERS * * root - the given node not in the subset; * (xadj, adjncy) - * the adjancy structure pair; * deg - the degree vector. deg[i] < 0 means the node belongs to the * given subset. * * OUTPUT PARAMETERS * * (rchsze, rchset) - * the reachable set; * (nhdsze, nbrhd) - * the neighborhood set. * * UPDATED PARAMETERS * * marker - the marker vector for reach and nbrhd sets. > 0 means the * node is in reach set. < 0 means the node has been merged * with others in the quotient or it is in nbrhd set. ***********************************************************************/ void qmdrch(int *_root, int xadj[], int adjncy[], int deg[], int marker[], int *_rchsze, int rchset[], int *_nhdsze, int nbrhd[]) { int i, istop, istrt, j, jstop, jstrt, nabor, node; # define root (*_root) # define rchsze (*_rchsze) # define nhdsze (*_nhdsze) /* Loop through the neighbors of root in the quotient graph. */ nhdsze = 0; rchsze = 0; istrt = xadj[root]; istop = xadj[root+1] - 1; if (istop < istrt) return; for (i = istrt; i <= istop; i++) { nabor = adjncy[i]; if (nabor == 0) return; if (marker[nabor] == 0) { if (deg[nabor] >= 0) { /* Include nabor into the reachable set. */ rchsze++; rchset[rchsze] = nabor; marker[nabor] = 1; goto s600; } /* nabor has been eliminated. Find nodes reachable from it. */ marker[nabor] = -1; nhdsze++; nbrhd[nhdsze] = nabor; s300: jstrt = xadj[nabor]; jstop = xadj[nabor+1] - 1; for (j = jstrt; j <= jstop; j++) { node = adjncy[j]; nabor = - node; if (node < 0) goto s300; if (node == 0) goto s600; if (marker[node] == 0) { rchsze++; rchset[rchsze] = node; marker[node] = 1; } } } s600: ; } return; # undef root # undef rchsze # undef nhdsze } /*********************************************************************** * NAME * * qmdqt - Quotient MD Quotient graph Transformation * * SYNOPSIS * * #include "glpqmd.h" * void qmdqt(int *root, int xadj[], int adjncy[], int marker[], * int *rchsze, int rchset[], int nbrhd[]); * * PURPOSE * * This subroutine performs the quotient graph transformation after a * node has been eliminated. * * INPUT PARAMETERS * * root - the node just eliminated. It becomes the representative of * the new supernode; * (xadj, adjncy) - * the adjancy structure; * (rchsze, rchset) - * the reachable set of root in the old quotient graph; * nbrhd - the neighborhood set which will be merged with root to form * the new supernode; * marker - the marker vector. * * UPDATED PARAMETERS * * adjncy - becomes the adjncy of the quotient graph. ***********************************************************************/ void qmdqt(int *_root, int xadj[], int adjncy[], int marker[], int *_rchsze, int rchset[], int nbrhd[]) { int inhd, irch, j, jstop, jstrt, link, nabor, node; # define root (*_root) # define rchsze (*_rchsze) irch = 0; inhd = 0; node = root; s100: jstrt = xadj[node]; jstop = xadj[node+1] - 2; if (jstop >= jstrt) { /* Place reach nodes into the adjacent list of node. */ for (j = jstrt; j <= jstop; j++) { irch++; adjncy[j] = rchset[irch]; if (irch >= rchsze) goto s400; } } /* Link to other space provided by the nbrhd set. */ link = adjncy[jstop+1]; node = - link; if (link >= 0) { inhd++; node = nbrhd[inhd]; adjncy[jstop+1] = - node; } goto s100; /* All reachable nodes have been saved. End the adjacent list. Add root to the neighborhood list of each node in the reach set. */ s400: adjncy[j+1] = 0; for (irch = 1; irch <= rchsze; irch++) { node = rchset[irch]; if (marker[node] >= 0) { jstrt = xadj[node]; jstop = xadj[node+1] - 1; for (j = jstrt; j <= jstop; j++) { nabor = adjncy[j]; if (marker[nabor] < 0) { adjncy[j] = root; goto s600; } } } s600: ; } return; # undef root # undef rchsze } /*********************************************************************** * NAME * * qmdupd - Quotient MD UPDate * * SYNOPSIS * * #include "glpqmd.h" * void qmdupd(int xadj[], int adjncy[], int *nlist, int list[], * int deg[], int qsize[], int qlink[], int marker[], int rchset[], * int nbrhd[]); * * PURPOSE * * This routine performs degree update for a set of nodes in the minimum * degree algorithm. * * INPUT PARAMETERS * * (xadj, adjncy) - * the adjancy structure; * (nlist, list) - * the list of nodes whose degree has to be updated. * * UPDATED PARAMETERS * * deg - the degree vector; * qsize - size of indistinguishable supernodes; * qlink - linked list for indistinguishable nodes; * marker - used to mark those nodes in reach/nbrhd sets. * * WORKING PARAMETERS * * rchset - the reachable set; * nbrhd - the neighborhood set. * * PROGRAM SUBROUTINES * * qmdmrg. ***********************************************************************/ void qmdupd(int xadj[], int adjncy[], int *_nlist, int list[], int deg[], int qsize[], int qlink[], int marker[], int rchset[], int nbrhd[]) { int deg0, deg1, il, inhd, inode, irch, j, jstop, jstrt, mark, nabor, nhdsze, node, rchsze; # define nlist (*_nlist) /* Find all eliminated supernodes that are adjacent to some nodes in the given list. Put them into (nhdsze, nbrhd). deg0 contains the number of nodes in the list. */ if (nlist <= 0) return; deg0 = 0; nhdsze = 0; for (il = 1; il <= nlist; il++) { node = list[il]; deg0 += qsize[node]; jstrt = xadj[node]; jstop = xadj[node+1] - 1; for (j = jstrt; j <= jstop; j++) { nabor = adjncy[j]; if (marker[nabor] == 0 && deg[nabor] < 0) { marker[nabor] = -1; nhdsze++; nbrhd[nhdsze] = nabor; } } } /* Merge indistinguishable nodes in the list by calling the subroutine qmdmrg. */ if (nhdsze > 0) qmdmrg(xadj, adjncy, deg, qsize, qlink, marker, °0, &nhdsze, nbrhd, rchset, &nbrhd[nhdsze+1]); /* Find the new degrees of the nodes that have not been merged. */ for (il = 1; il <= nlist; il++) { node = list[il]; mark = marker[node]; if (mark == 0 || mark == 1) { marker[node] = 2; qmdrch(&node, xadj, adjncy, deg, marker, &rchsze, rchset, &nhdsze, nbrhd); deg1 = deg0; if (rchsze > 0) { for (irch = 1; irch <= rchsze; irch++) { inode = rchset[irch]; deg1 += qsize[inode]; marker[inode] = 0; } } deg[node] = deg1 - 1; if (nhdsze > 0) { for (inhd = 1; inhd <= nhdsze; inhd++) { inode = nbrhd[inhd]; marker[inode] = 0; } } } } return; # undef nlist } /*********************************************************************** * NAME * * qmdmrg - Quotient MD MeRGe * * SYNOPSIS * * #include "qmdmrg.h" * void qmdmrg(int xadj[], int adjncy[], int deg[], int qsize[], * int qlink[], int marker[], int *deg0, int *nhdsze, int nbrhd[], * int rchset[], int ovrlp[]); * * PURPOSE * * This routine merges indistinguishable nodes in the minimum degree * ordering algorithm. It also computes the new degrees of these new * supernodes. * * INPUT PARAMETERS * * (xadj, adjncy) - * the adjancy structure; * deg0 - the number of nodes in the given set; * (nhdsze, nbrhd) - * the set of eliminated supernodes adjacent to some nodes in * the set. * * UPDATED PARAMETERS * * deg - the degree vector; * qsize - size of indistinguishable nodes; * qlink - linked list for indistinguishable nodes; * marker - the given set is given by those nodes with marker value set * to 1. Those nodes with degree updated will have marker value * set to 2. * * WORKING PARAMETERS * * rchset - the reachable set; * ovrlp - temp vector to store the intersection of two reachable sets. ***********************************************************************/ void qmdmrg(int xadj[], int adjncy[], int deg[], int qsize[], int qlink[], int marker[], int *_deg0, int *_nhdsze, int nbrhd[], int rchset[], int ovrlp[]) { int deg1, head, inhd, iov, irch, j, jstop, jstrt, link, lnode, mark, mrgsze, nabor, node, novrlp, rchsze, root; # define deg0 (*_deg0) # define nhdsze (*_nhdsze) /* Initialization. */ if (nhdsze <= 0) return; for (inhd = 1; inhd <= nhdsze; inhd++) { root = nbrhd[inhd]; marker[root] = 0; } /* Loop through each eliminated supernode in the set (nhdsze, nbrhd). */ for (inhd = 1; inhd <= nhdsze; inhd++) { root = nbrhd[inhd]; marker[root] = -1; rchsze = 0; novrlp = 0; deg1 = 0; s200: jstrt = xadj[root]; jstop = xadj[root+1] - 1; /* Determine the reachable set and its intersection with the input reachable set. */ for (j = jstrt; j <= jstop; j++) { nabor = adjncy[j]; root = - nabor; if (nabor < 0) goto s200; if (nabor == 0) break; mark = marker[nabor]; if (mark == 0) { rchsze++; rchset[rchsze] = nabor; deg1 += qsize[nabor]; marker[nabor] = 1; } else if (mark == 1) { novrlp++; ovrlp[novrlp] = nabor; marker[nabor] = 2; } } /* From the overlapped set, determine the nodes that can be merged together. */ head = 0; mrgsze = 0; for (iov = 1; iov <= novrlp; iov++) { node = ovrlp[iov]; jstrt = xadj[node]; jstop = xadj[node+1] - 1; for (j = jstrt; j <= jstop; j++) { nabor = adjncy[j]; if (marker[nabor] == 0) { marker[node] = 1; goto s1100; } } /* Node belongs to the new merged supernode. Update the vectors qlink and qsize. */ mrgsze += qsize[node]; marker[node] = -1; lnode = node; s900: link = qlink[lnode]; if (link > 0) { lnode = link; goto s900; } qlink[lnode] = head; head = node; s1100: ; } if (head > 0) { qsize[head] = mrgsze; deg[head] = deg0 + deg1 - 1; marker[head] = 2; } /* Reset marker values. */ root = nbrhd[inhd]; marker[root] = 0; if (rchsze > 0) { for (irch = 1; irch <= rchsze; irch++) { node = rchset[irch]; marker[node] = 0; } } } return; # undef deg0 # undef nhdsze } /* eof */ praat-6.0.04/external/glpk/glpqmd.h000066400000000000000000000043051261542461700171360ustar00rootroot00000000000000/* glpqmd.h (quotient minimum degree algorithm) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPQMD_H #define GLPQMD_H #define genqmd _glp_qmd_genqmd void genqmd(int *neqns, int xadj[], int adjncy[], int perm[], int invp[], int deg[], int marker[], int rchset[], int nbrhd[], int qsize[], int qlink[], int *nofsub); /* GENeral Quotient Minimum Degree algorithm */ #define qmdrch _glp_qmd_qmdrch void qmdrch(int *root, int xadj[], int adjncy[], int deg[], int marker[], int *rchsze, int rchset[], int *nhdsze, int nbrhd[]); /* Quotient MD ReaCHable set */ #define qmdqt _glp_qmd_qmdqt void qmdqt(int *root, int xadj[], int adjncy[], int marker[], int *rchsze, int rchset[], int nbrhd[]); /* Quotient MD Quotient graph Transformation */ #define qmdupd _glp_qmd_qmdupd void qmdupd(int xadj[], int adjncy[], int *nlist, int list[], int deg[], int qsize[], int qlink[], int marker[], int rchset[], int nbrhd[]); /* Quotient MD UPDate */ #define qmdmrg _glp_qmd_qmdmrg void qmdmrg(int xadj[], int adjncy[], int deg[], int qsize[], int qlink[], int marker[], int *deg0, int *nhdsze, int nbrhd[], int rchset[], int ovrlp[]); /* Quotient MD MeRGe */ #endif /* eof */ praat-6.0.04/external/glpk/glprgr.c000066400000000000000000000141541261542461700171450ustar00rootroot00000000000000/* glprgr.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #define _GLPSTD_ERRNO #define _GLPSTD_STDIO #include "glpenv.h" #include "glprgr.h" #define xfault xerror /*********************************************************************** * NAME * * rgr_write_bmp16 - write 16-color raster image in BMP file format * * SYNOPSIS * * #include "glprgr.h" * int rgr_write_bmp16(const char *fname, int m, int n, const char * map[]); * * DESCRIPTION * * The routine rgr_write_bmp16 writes 16-color raster image in * uncompressed BMP file format (Windows bitmap) to a binary file whose * name is specified by the character string fname. * * The parameters m and n specify, respectively, the number of rows and * the numbers of columns (i.e. height and width) of the raster image. * * The character array map has m*n elements. Elements map[0, ..., n-1] * correspond to the first (top) scanline, elements map[n, ..., 2*n-1] * correspond to the second scanline, etc. * * Each element of the array map specifies a color of the corresponding * pixel as 8-bit binary number XXXXIRGB, where four high-order bits (X) * are ignored, I is high intensity bit, R is red color bit, G is green * color bit, and B is blue color bit. Thus, all 16 possible colors are * coded as following hexadecimal numbers: * * 0x00 = black 0x08 = dark gray * 0x01 = blue 0x09 = bright blue * 0x02 = green 0x0A = bright green * 0x03 = cyan 0x0B = bright cyan * 0x04 = red 0x0C = bright red * 0x05 = magenta 0x0D = bright magenta * 0x06 = brown 0x0E = yellow * 0x07 = light gray 0x0F = white * * RETURNS * * If no error occured, the routine returns zero; otherwise, it prints * an appropriate error message and returns non-zero. */ static void put_byte(FILE *fp, int c) { fputc(c, fp); return; } static void put_word(FILE *fp, int w) { /* big endian */ put_byte(fp, w); put_byte(fp, w >> 8); return; } static void put_dword(FILE *fp, int d) { /* big endian */ put_word(fp, d); put_word(fp, d >> 16); return; } int rgr_write_bmp16(const char *fname, int m, int n, const char map[]) { FILE *fp; int offset, bmsize, i, j, b, ret = 0; if (!(1 <= m && m <= 32767)) xfault("rgr_write_bmp16: m = %d; invalid height\n", m); if (!(1 <= n && n <= 32767)) xfault("rgr_write_bmp16: n = %d; invalid width\n", n); fp = fopen(fname, "wb"); if (fp == NULL) { xprintf("rgr_write_bmp16: unable to create `%s' - %s\n", fname, strerror(errno)); ret = 1; goto fini; } offset = 14 + 40 + 16 * 4; bmsize = (4 * n + 31) / 32; /* struct BMPFILEHEADER (14 bytes) */ /* UINT bfType */ put_byte(fp, 'B'), put_byte(fp, 'M'); /* DWORD bfSize */ put_dword(fp, offset + bmsize * 4); /* UINT bfReserved1 */ put_word(fp, 0); /* UNIT bfReserved2 */ put_word(fp, 0); /* DWORD bfOffBits */ put_dword(fp, offset); /* struct BMPINFOHEADER (40 bytes) */ /* DWORD biSize */ put_dword(fp, 40); /* LONG biWidth */ put_dword(fp, n); /* LONG biHeight */ put_dword(fp, m); /* WORD biPlanes */ put_word(fp, 1); /* WORD biBitCount */ put_word(fp, 4); /* DWORD biCompression */ put_dword(fp, 0 /* BI_RGB */); /* DWORD biSizeImage */ put_dword(fp, 0); /* LONG biXPelsPerMeter */ put_dword(fp, 2953 /* 75 dpi */); /* LONG biYPelsPerMeter */ put_dword(fp, 2953 /* 75 dpi */); /* DWORD biClrUsed */ put_dword(fp, 0); /* DWORD biClrImportant */ put_dword(fp, 0); /* struct RGBQUAD (16 * 4 = 64 bytes) */ /* CGA-compatible colors: */ /* 0x00 = black */ put_dword(fp, 0x000000); /* 0x01 = blue */ put_dword(fp, 0x000080); /* 0x02 = green */ put_dword(fp, 0x008000); /* 0x03 = cyan */ put_dword(fp, 0x008080); /* 0x04 = red */ put_dword(fp, 0x800000); /* 0x05 = magenta */ put_dword(fp, 0x800080); /* 0x06 = brown */ put_dword(fp, 0x808000); /* 0x07 = light gray */ put_dword(fp, 0xC0C0C0); /* 0x08 = dark gray */ put_dword(fp, 0x808080); /* 0x09 = bright blue */ put_dword(fp, 0x0000FF); /* 0x0A = bright green */ put_dword(fp, 0x00FF00); /* 0x0B = bright cyan */ put_dword(fp, 0x00FFFF); /* 0x0C = bright red */ put_dword(fp, 0xFF0000); /* 0x0D = bright magenta */ put_dword(fp, 0xFF00FF); /* 0x0E = yellow */ put_dword(fp, 0xFFFF00); /* 0x0F = white */ put_dword(fp, 0xFFFFFF); /* pixel data bits */ b = 0; for (i = m - 1; i >= 0; i--) { for (j = 0; j < ((n + 7) / 8) * 8; j++) { b <<= 4; b |= (j < n ? map[i * n + j] & 15 : 0); if (j & 1) put_byte(fp, b); } } fflush(fp); if (ferror(fp)) { xprintf("rgr_write_bmp16: write error on `%s' - %s\n", fname, strerror(errno)); ret = 1; } fini: if (fp != NULL) fclose(fp); return ret; } /* eof */ praat-6.0.04/external/glpk/glprgr.h000066400000000000000000000024451261542461700171520ustar00rootroot00000000000000/* glprgr.h (raster graphics) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPRGR_H #define GLPRGR_H #define rgr_write_bmp16 _glp_rgr_write_bmp16 int rgr_write_bmp16(const char *fname, int m, int n, const char map[]); /* write 16-color raster image in BMP file format */ #endif /* eof */ praat-6.0.04/external/glpk/glprng.h000066400000000000000000000043461261542461700171500ustar00rootroot00000000000000/* glprng.h (pseudo-random number generator) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPRNG_H #define GLPRNG_H typedef struct RNG RNG; struct RNG { /* Knuth's portable pseudo-random number generator */ int A[56]; /* pseudo-random values */ int *fptr; /* the next A value to be exported */ }; #define rng_create_rand _glp_rng_create_rand RNG *rng_create_rand(void); /* create pseudo-random number generator */ #define rng_init_rand _glp_rng_init_rand void rng_init_rand(RNG *rand, int seed); /* initialize pseudo-random number generator */ #define rng_next_rand _glp_rng_next_rand int rng_next_rand(RNG *rand); /* obtain pseudo-random integer in the range [0, 2^31-1] */ #define rng_unif_rand _glp_rng_unif_rand int rng_unif_rand(RNG *rand, int m); /* obtain pseudo-random integer in the range [0, m-1] */ #define rng_delete_rand _glp_rng_delete_rand void rng_delete_rand(RNG *rand); /* delete pseudo-random number generator */ #define rng_unif_01 _glp_rng_unif_01 double rng_unif_01(RNG *rand); /* obtain pseudo-random number in the range [0, 1] */ #define rng_uniform _glp_rng_uniform double rng_uniform(RNG *rand, double a, double b); /* obtain pseudo-random number in the range [a, b] */ #endif /* eof */ praat-6.0.04/external/glpk/glprng01.c000066400000000000000000000141331261542461700172770ustar00rootroot00000000000000/* glprng01.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * This code is a modified version of the module GB_FLIP, a portable * pseudo-random number generator. The original version of GB_FLIP is * a part of The Stanford GraphBase developed by Donald E. Knuth (see * http://www-cs-staff.stanford.edu/~knuth/sgb.html). * * Note that all changes concern only external names, so this modified * version produces exactly the same results as the original version. * * Changes were made by Andrew Makhorin . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpenv.h" #include "glprng.h" #if 0 int A[56] = { -1 }; #else #define A (rand->A) #endif /* pseudo-random values */ #if 0 int *fptr = A; #else #define fptr (rand->fptr) #endif /* the next A value to be exported */ #define mod_diff(x, y) (((x) - (y)) & 0x7FFFFFFF) /* difference modulo 2^31 */ static int flip_cycle(RNG *rand) { /* this is an auxiliary routine to do 55 more steps of the basic recurrence, at high speed, and to reset fptr */ int *ii, *jj; for (ii = &A[1], jj = &A[32]; jj <= &A[55]; ii++, jj++) *ii = mod_diff(*ii, *jj); for (jj = &A[1]; ii <= &A[55]; ii++, jj++) *ii = mod_diff(*ii, *jj); fptr = &A[54]; return A[55]; } /*********************************************************************** * NAME * * rng_create_rand - create pseudo-random number generator * * SYNOPSIS * * #include "glprng.h" * RNG *rng_create_rand(void); * * DESCRIPTION * * The routine rng_create_rand creates and initializes a pseudo-random * number generator. * * RETURNS * * The routine returns a pointer to the generator created. */ RNG *rng_create_rand(void) { RNG *rand; int i; rand = xmalloc(sizeof(RNG)); A[0] = -1; for (i = 1; i <= 55; i++) A[i] = 0; fptr = A; rng_init_rand(rand, 1); return rand; } /*********************************************************************** * NAME * * rng_init_rand - initialize pseudo-random number generator * * SYNOPSIS * * #include "glprng.h" * void rng_init_rand(RNG *rand, int seed); * * DESCRIPTION * * The routine rng_init_rand initializes the pseudo-random number * generator. The parameter seed may be any integer number. Note that * on creating the generator this routine is called with the parameter * seed equal to 1. */ void rng_init_rand(RNG *rand, int seed) { int i; int prev = seed, next = 1; seed = prev = mod_diff(prev, 0); A[55] = prev; for (i = 21; i; i = (i + 21) % 55) { A[i] = next; next = mod_diff(prev, next); if (seed & 1) seed = 0x40000000 + (seed >> 1); else seed >>= 1; next = mod_diff(next, seed); prev = A[i]; } flip_cycle(rand); flip_cycle(rand); flip_cycle(rand); flip_cycle(rand); flip_cycle(rand); return; } /*********************************************************************** * NAME * * rng_next_rand - obtain pseudo-random integer in the range [0, 2^31-1] * * SYNOPSIS * * #include "glprng.h" * int rng_next_rand(RNG *rand); * * RETURNS * * The routine rng_next_rand returns a next pseudo-random integer which * is uniformly distributed between 0 and 2^31-1, inclusive. The period * length of the generated numbers is 2^85 - 2^30. The low order bits of * the generated numbers are just as random as the high-order bits. */ int rng_next_rand(RNG *rand) { return *fptr >= 0 ? *fptr-- : flip_cycle(rand); } /*********************************************************************** * NAME * * rng_unif_rand - obtain pseudo-random integer in the range [0, m-1] * * SYNOPSIS * * #include "glprng.h" * int rng_unif_rand(RNG *rand, int m); * * RETURNS * * The routine rng_unif_rand returns a next pseudo-random integer which * is uniformly distributed between 0 and m-1, inclusive, where m is any * positive integer less than 2^31. */ #define two_to_the_31 ((unsigned int)0x80000000) int rng_unif_rand(RNG *rand, int m) { unsigned int t = two_to_the_31 - (two_to_the_31 % m); int r; xassert(m > 0); do { r = rng_next_rand(rand); } while (t <= (unsigned int)r); return r % m; } /*********************************************************************** * NAME * * rng_delete_rand - delete pseudo-random number generator * * SYNOPSIS * * #include "glprng.h" * void rng_delete_rand(RNG *rand); * * DESCRIPTION * * The routine rng_delete_rand frees all the memory allocated to the * specified pseudo-random number generator. */ void rng_delete_rand(RNG *rand) { xfree(rand); return; } /**********************************************************************/ #if 0 /* To be sure that this modified version produces the same results as the original version, run this validation program. */ int main(void) { RNG *rand; int j; rand = rng_create_rand(); rng_init_rand(rand, -314159); if (rng_next_rand(rand) != 119318998) { fprintf(stderr, "Failure on the first try!\n"); return -1; } for (j = 1; j <= 133; j++) rng_next_rand(rand); if (rng_unif_rand(rand, 0x55555555) != 748103812) { fprintf(stderr, "Failure on the second try!\n"); return -2; } fprintf(stderr, "OK, the random-number generator routines seem to" " work!\n"); rng_delete_rand(rand); return 0; } #endif /* eof */ praat-6.0.04/external/glpk/glprng02.c000066400000000000000000000044071261542461700173030ustar00rootroot00000000000000/* glprng02.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpenv.h" #include "glprng.h" #define xfault xerror /*********************************************************************** * NAME * * rng_unif_01 - obtain pseudo-random number in the range [0, 1] * * SYNOPSIS * * #include "glprng.h" * double rng_unif_01(RNG *rand); * * RETURNS * * The routine rng_unif_01 returns a next pseudo-random number which is * uniformly distributed in the range [0, 1]. */ double rng_unif_01(RNG *rand) { double x; x = (double)rng_next_rand(rand) / 2147483647.0; xassert(0.0 <= x && x <= 1.0); return x; } /*********************************************************************** * NAME * * rng_uniform - obtain pseudo-random number in the range [a, b] * * SYNOPSIS * * #include "glprng.h" * double rng_uniform(RNG *rand, double a, double b); * * RETURNS * * The routine rng_uniform returns a next pseudo-random number which is * uniformly distributed in the range [a, b]. */ double rng_uniform(RNG *rand, double a, double b) { double x; if (a >= b) xfault("rng_uniform: a = %g, b = %g; invalid range\n", a, b); x = rng_unif_01(rand); x = a * (1.0 - x) + b * x; xassert(a <= x && x <= b); return x; } /* eof */ praat-6.0.04/external/glpk/glpscf.c000066400000000000000000000475731261542461700171410ustar00rootroot00000000000000/* glpscf.c (Schur complement factorization) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpenv.h" #include "glpscf.h" #define xfault xerror #define _GLPSCF_DEBUG 0 #define eps 1e-10 /*********************************************************************** * NAME * * scf_create_it - create Schur complement factorization * * SYNOPSIS * * #include "glpscf.h" * SCF *scf_create_it(int n_max); * * DESCRIPTION * * The routine scf_create_it creates the factorization of matrix C, * which initially has no rows and columns. * * The parameter n_max specifies the maximal order of matrix C to be * factorized, 1 <= n_max <= 32767. * * RETURNS * * The routine scf_create_it returns a pointer to the structure SCF, * which defines the factorization. */ SCF *scf_create_it(int n_max) { SCF *scf; #if _GLPSCF_DEBUG xprintf("scf_create_it: warning: debug mode enabled\n"); #endif if (!(1 <= n_max && n_max <= 32767)) xfault("scf_create_it: n_max = %d; invalid parameter\n", n_max); scf = xmalloc(sizeof(SCF)); scf->n_max = n_max; scf->n = 0; scf->f = xcalloc(1 + n_max * n_max, sizeof(double)); scf->u = xcalloc(1 + n_max * (n_max + 1) / 2, sizeof(double)); scf->p = xcalloc(1 + n_max, sizeof(int)); scf->t_opt = SCF_TBG; scf->rank = 0; #if _GLPSCF_DEBUG scf->c = xcalloc(1 + n_max * n_max, sizeof(double)); #else scf->c = NULL; #endif scf->w = xcalloc(1 + n_max, sizeof(double)); return scf; } /*********************************************************************** * The routine f_loc determines location of matrix element F[i,j] in * the one-dimensional array f. */ static int f_loc(SCF *scf, int i, int j) { int n_max = scf->n_max; int n = scf->n; xassert(1 <= i && i <= n); xassert(1 <= j && j <= n); return (i - 1) * n_max + j; } /*********************************************************************** * The routine u_loc determines location of matrix element U[i,j] in * the one-dimensional array u. */ static int u_loc(SCF *scf, int i, int j) { int n_max = scf->n_max; int n = scf->n; xassert(1 <= i && i <= n); xassert(i <= j && j <= n); return (i - 1) * n_max + j - i * (i - 1) / 2; } /*********************************************************************** * The routine bg_transform applies Bartels-Golub version of gaussian * elimination to restore triangular structure of matrix U. * * On entry matrix U has the following structure: * * 1 k n * 1 * * * * * * * * * * * . * * * * * * * * * * . . * * * * * * * * * . . . * * * * * * * * k . . . . * * * * * * * . . . . . * * * * * * . . . . . . * * * * * . . . . . . . * * * * . . . . . . . . * * * n . . . . # # # # # # * * where '#' is a row spike to be eliminated. * * Elements of n-th row are passed separately in locations un[k], ..., * un[n]. On exit the content of the array un is destroyed. * * REFERENCES * * R.H.Bartels, G.H.Golub, "The Simplex Method of Linear Programming * Using LU-decomposition", Comm. ACM, 12, pp. 266-68, 1969. */ static void bg_transform(SCF *scf, int k, double un[]) { int n = scf->n; double *f = scf->f; double *u = scf->u; int j, k1, kj, kk, n1, nj; double t; xassert(1 <= k && k <= n); /* main elimination loop */ for (k = k; k < n; k++) { /* determine location of U[k,k] */ kk = u_loc(scf, k, k); /* determine location of F[k,1] */ k1 = f_loc(scf, k, 1); /* determine location of F[n,1] */ n1 = f_loc(scf, n, 1); /* if |U[k,k]| < |U[n,k]|, interchange k-th and n-th rows to provide |U[k,k]| >= |U[n,k]| */ if (fabs(u[kk]) < fabs(un[k])) { /* interchange k-th and n-th rows of matrix U */ for (j = k, kj = kk; j <= n; j++, kj++) t = u[kj], u[kj] = un[j], un[j] = t; /* interchange k-th and n-th rows of matrix F to keep the main equality F * C = U * P */ for (j = 1, kj = k1, nj = n1; j <= n; j++, kj++, nj++) t = f[kj], f[kj] = f[nj], f[nj] = t; } /* now |U[k,k]| >= |U[n,k]| */ /* if U[k,k] is too small in the magnitude, replace U[k,k] and U[n,k] by exact zero */ if (fabs(u[kk]) < eps) u[kk] = un[k] = 0.0; /* if U[n,k] is already zero, elimination is not needed */ if (un[k] == 0.0) continue; /* compute gaussian multiplier t = U[n,k] / U[k,k] */ t = un[k] / u[kk]; /* apply gaussian elimination to nullify U[n,k] */ /* (n-th row of U) := (n-th row of U) - t * (k-th row of U) */ for (j = k+1, kj = kk+1; j <= n; j++, kj++) un[j] -= t * u[kj]; /* (n-th row of F) := (n-th row of F) - t * (k-th row of F) to keep the main equality F * C = U * P */ for (j = 1, kj = k1, nj = n1; j <= n; j++, kj++, nj++) f[nj] -= t * f[kj]; } /* if U[n,n] is too small in the magnitude, replace it by exact zero */ if (fabs(un[n]) < eps) un[n] = 0.0; /* store U[n,n] in a proper location */ u[u_loc(scf, n, n)] = un[n]; return; } /*********************************************************************** * The routine givens computes the parameters of Givens plane rotation * c = cos(teta) and s = sin(teta) such that: * * ( c -s ) ( a ) ( r ) * ( ) ( ) = ( ) , * ( s c ) ( b ) ( 0 ) * * where a and b are given scalars. * * REFERENCES * * G.H.Golub, C.F.Van Loan, "Matrix Computations", 2nd ed. */ static void givens(double a, double b, double *c, double *s) { double t; if (b == 0.0) (*c) = 1.0, (*s) = 0.0; else if (fabs(a) <= fabs(b)) t = - a / b, (*s) = 1.0 / sqrt(1.0 + t * t), (*c) = (*s) * t; else t = - b / a, (*c) = 1.0 / sqrt(1.0 + t * t), (*s) = (*c) * t; return; } /*---------------------------------------------------------------------- * The routine gr_transform applies Givens plane rotations to restore * triangular structure of matrix U. * * On entry matrix U has the following structure: * * 1 k n * 1 * * * * * * * * * * * . * * * * * * * * * * . . * * * * * * * * * . . . * * * * * * * * k . . . . * * * * * * * . . . . . * * * * * * . . . . . . * * * * * . . . . . . . * * * * . . . . . . . . * * * n . . . . # # # # # # * * where '#' is a row spike to be eliminated. * * Elements of n-th row are passed separately in locations un[k], ..., * un[n]. On exit the content of the array un is destroyed. * * REFERENCES * * R.H.Bartels, G.H.Golub, "The Simplex Method of Linear Programming * Using LU-decomposition", Comm. ACM, 12, pp. 266-68, 1969. */ static void gr_transform(SCF *scf, int k, double un[]) { int n = scf->n; double *f = scf->f; double *u = scf->u; int j, k1, kj, kk, n1, nj; double c, s; xassert(1 <= k && k <= n); /* main elimination loop */ for (k = k; k < n; k++) { /* determine location of U[k,k] */ kk = u_loc(scf, k, k); /* determine location of F[k,1] */ k1 = f_loc(scf, k, 1); /* determine location of F[n,1] */ n1 = f_loc(scf, n, 1); /* if both U[k,k] and U[n,k] are too small in the magnitude, replace them by exact zero */ if (fabs(u[kk]) < eps && fabs(un[k]) < eps) u[kk] = un[k] = 0.0; /* if U[n,k] is already zero, elimination is not needed */ if (un[k] == 0.0) continue; /* compute the parameters of Givens plane rotation */ givens(u[kk], un[k], &c, &s); /* apply Givens rotation to k-th and n-th rows of matrix U */ for (j = k, kj = kk; j <= n; j++, kj++) { double ukj = u[kj], unj = un[j]; u[kj] = c * ukj - s * unj; un[j] = s * ukj + c * unj; } /* apply Givens rotation to k-th and n-th rows of matrix F to keep the main equality F * C = U * P */ for (j = 1, kj = k1, nj = n1; j <= n; j++, kj++, nj++) { double fkj = f[kj], fnj = f[nj]; f[kj] = c * fkj - s * fnj; f[nj] = s * fkj + c * fnj; } } /* if U[n,n] is too small in the magnitude, replace it by exact zero */ if (fabs(un[n]) < eps) un[n] = 0.0; /* store U[n,n] in a proper location */ u[u_loc(scf, n, n)] = un[n]; return; } /*********************************************************************** * The routine transform restores triangular structure of matrix U. * It is a driver to the routines bg_transform and gr_transform (see * comments to these routines above). */ static void transform(SCF *scf, int k, double un[]) { switch (scf->t_opt) { case SCF_TBG: bg_transform(scf, k, un); break; case SCF_TGR: gr_transform(scf, k, un); break; default: xassert(scf != scf); } return; } /*********************************************************************** * The routine estimate_rank estimates the rank of matrix C. * * Since all transformations applied to matrix F are non-singular, * and F is assumed to be well conditioned, from the main equaility * F * C = U * P it follows that rank(C) = rank(U), where rank(U) is * estimated as the number of non-zero diagonal elements of U. */ static int estimate_rank(SCF *scf) { int n_max = scf->n_max; int n = scf->n; double *u = scf->u; int i, ii, inc, rank = 0; for (i = 1, ii = u_loc(scf, i, i), inc = n_max; i <= n; i++, ii += inc, inc--) if (u[ii] != 0.0) rank++; return rank; } #if _GLPSCF_DEBUG /*********************************************************************** * The routine check_error computes the maximal relative error between * left- and right-hand sides of the main equality F * C = U * P. (This * routine is intended only for debugging.) */ static void check_error(SCF *scf, const char *func) { int n = scf->n; double *f = scf->f; double *u = scf->u; int *p = scf->p; double *c = scf->c; int i, j, k; double d, dmax = 0.0, s, t; xassert(c != NULL); for (i = 1; i <= n; i++) { for (j = 1; j <= n; j++) { /* compute element (i,j) of product F * C */ s = 0.0; for (k = 1; k <= n; k++) s += f[f_loc(scf, i, k)] * c[f_loc(scf, k, j)]; /* compute element (i,j) of product U * P */ k = p[j]; t = (i <= k ? u[u_loc(scf, i, k)] : 0.0); /* compute the maximal relative error */ d = fabs(s - t) / (1.0 + fabs(t)); if (dmax < d) dmax = d; } } if (dmax > 1e-8) xprintf("%s: dmax = %g; relative error too large\n", func, dmax); return; } #endif /*********************************************************************** * NAME * * scf_update_exp - update factorization on expanding C * * SYNOPSIS * * #include "glpscf.h" * int scf_update_exp(SCF *scf, const double x[], const double y[], * double z); * * DESCRIPTION * * The routine scf_update_exp updates the factorization of matrix C on * expanding it by adding a new row and column as follows: * * ( C x ) * new C = ( ) * ( y' z ) * * where x[1,...,n] is a new column, y[1,...,n] is a new row, and z is * a new diagonal element. * * If on entry the factorization is empty, the parameters x and y can * be specified as NULL. * * RETURNS * * 0 The factorization has been successfully updated. * * SCF_ESING * The factorization has been successfully updated, however, new * matrix C is singular within working precision. Note that the new * factorization remains valid. * * SCF_ELIMIT * There is not enough room to expand the factorization, because * n = n_max. The factorization remains unchanged. * * ALGORITHM * * We can see that: * * ( F 0 ) ( C x ) ( FC Fx ) ( UP Fx ) * ( ) ( ) = ( ) = ( ) = * ( 0 1 ) ( y' z ) ( y' z ) ( y' z ) * * ( U Fx ) ( P 0 ) * = ( ) ( ), * ( y'P' z ) ( 0 1 ) * * therefore to keep the main equality F * C = U * P we can take: * * ( F 0 ) ( U Fx ) ( P 0 ) * new F = ( ), new U = ( ), new P = ( ), * ( 0 1 ) ( y'P' z ) ( 0 1 ) * * and eliminate the row spike y'P' in the last row of new U to restore * its upper triangular structure. */ int scf_update_exp(SCF *scf, const double x[], const double y[], double z) { int n_max = scf->n_max; int n = scf->n; double *f = scf->f; double *u = scf->u; int *p = scf->p; #if _GLPSCF_DEBUG double *c = scf->c; #endif double *un = scf->w; int i, ij, in, j, k, nj, ret = 0; double t; /* check if the factorization can be expanded */ if (n == n_max) { /* there is not enough room */ ret = SCF_ELIMIT; goto done; } /* increase the order of the factorization */ scf->n = ++n; /* fill new zero column of matrix F */ for (i = 1, in = f_loc(scf, i, n); i < n; i++, in += n_max) f[in] = 0.0; /* fill new zero row of matrix F */ for (j = 1, nj = f_loc(scf, n, j); j < n; j++, nj++) f[nj] = 0.0; /* fill new unity diagonal element of matrix F */ f[f_loc(scf, n, n)] = 1.0; /* compute new column of matrix U, which is (old F) * x */ for (i = 1; i < n; i++) { /* u[i,n] := (i-th row of old F) * x */ t = 0.0; for (j = 1, ij = f_loc(scf, i, 1); j < n; j++, ij++) t += f[ij] * x[j]; u[u_loc(scf, i, n)] = t; } /* compute new (spiked) row of matrix U, which is (old P) * y */ for (j = 1; j < n; j++) un[j] = y[p[j]]; /* store new diagonal element of matrix U, which is z */ un[n] = z; /* expand matrix P */ p[n] = n; #if _GLPSCF_DEBUG /* expand matrix C */ /* fill its new column, which is x */ for (i = 1, in = f_loc(scf, i, n); i < n; i++, in += n_max) c[in] = x[i]; /* fill its new row, which is y */ for (j = 1, nj = f_loc(scf, n, j); j < n; j++, nj++) c[nj] = y[j]; /* fill its new diagonal element, which is z */ c[f_loc(scf, n, n)] = z; #endif /* restore upper triangular structure of matrix U */ for (k = 1; k < n; k++) if (un[k] != 0.0) break; transform(scf, k, un); /* estimate the rank of matrices C and U */ scf->rank = estimate_rank(scf); if (scf->rank != n) ret = SCF_ESING; #if _GLPSCF_DEBUG /* check that the factorization is accurate enough */ check_error(scf, "scf_update_exp"); #endif done: return ret; } /*********************************************************************** * The routine solve solves the system C * x = b. * * From the main equation F * C = U * P it follows that: * * C * x = b => F * C * x = F * b => U * P * x = F * b => * * P * x = inv(U) * F * b => x = P' * inv(U) * F * b. * * On entry the array x contains right-hand side vector b. On exit this * array contains solution vector x. */ static void solve(SCF *scf, double x[]) { int n = scf->n; double *f = scf->f; double *u = scf->u; int *p = scf->p; double *y = scf->w; int i, j, ij; double t; /* y := F * b */ for (i = 1; i <= n; i++) { /* y[i] = (i-th row of F) * b */ t = 0.0; for (j = 1, ij = f_loc(scf, i, 1); j <= n; j++, ij++) t += f[ij] * x[j]; y[i] = t; } /* y := inv(U) * y */ for (i = n; i >= 1; i--) { t = y[i]; for (j = n, ij = u_loc(scf, i, n); j > i; j--, ij--) t -= u[ij] * y[j]; y[i] = t / u[ij]; } /* x := P' * y */ for (i = 1; i <= n; i++) x[p[i]] = y[i]; return; } /*********************************************************************** * The routine tsolve solves the transposed system C' * x = b. * * From the main equation F * C = U * P it follows that: * * C' * F' = P' * U', * * therefore: * * C' * x = b => C' * F' * inv(F') * x = b => * * P' * U' * inv(F') * x = b => U' * inv(F') * x = P * b => * * inv(F') * x = inv(U') * P * b => x = F' * inv(U') * P * b. * * On entry the array x contains right-hand side vector b. On exit this * array contains solution vector x. */ static void tsolve(SCF *scf, double x[]) { int n = scf->n; double *f = scf->f; double *u = scf->u; int *p = scf->p; double *y = scf->w; int i, j, ij; double t; /* y := P * b */ for (i = 1; i <= n; i++) y[i] = x[p[i]]; /* y := inv(U') * y */ for (i = 1; i <= n; i++) { /* compute y[i] */ ij = u_loc(scf, i, i); t = (y[i] /= u[ij]); /* substitute y[i] in other equations */ for (j = i+1, ij++; j <= n; j++, ij++) y[j] -= u[ij] * t; } /* x := F' * y (computed as linear combination of rows of F) */ for (j = 1; j <= n; j++) x[j] = 0.0; for (i = 1; i <= n; i++) { t = y[i]; /* coefficient of linear combination */ for (j = 1, ij = f_loc(scf, i, 1); j <= n; j++, ij++) x[j] += f[ij] * t; } return; } /*********************************************************************** * NAME * * scf_solve_it - solve either system C * x = b or C' * x = b * * SYNOPSIS * * #include "glpscf.h" * void scf_solve_it(SCF *scf, int tr, double x[]); * * DESCRIPTION * * The routine scf_solve_it solves either the system C * x = b (if tr * is zero) or the system C' * x = b, where C' is a matrix transposed * to C (if tr is non-zero). C is assumed to be non-singular. * * On entry the array x should contain the right-hand side vector b in * locations x[1], ..., x[n], where n is the order of matrix C. On exit * the array x contains the solution vector x in the same locations. */ void scf_solve_it(SCF *scf, int tr, double x[]) { if (scf->rank < scf->n) xfault("scf_solve_it: singular matrix\n"); if (!tr) solve(scf, x); else tsolve(scf, x); return; } void scf_reset_it(SCF *scf) { /* reset factorization for empty matrix C */ scf->n = scf->rank = 0; return; } /*********************************************************************** * NAME * * scf_delete_it - delete Schur complement factorization * * SYNOPSIS * * #include "glpscf.h" * void scf_delete_it(SCF *scf); * * DESCRIPTION * * The routine scf_delete_it deletes the specified factorization and * frees all the memory allocated to this object. */ void scf_delete_it(SCF *scf) { xfree(scf->f); xfree(scf->u); xfree(scf->p); #if _GLPSCF_DEBUG xfree(scf->c); #endif xfree(scf->w); xfree(scf); return; } /* eof */ praat-6.0.04/external/glpk/glpscf.h000066400000000000000000000107441261542461700171340ustar00rootroot00000000000000/* glpscf.h (Schur complement factorization) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPSCF_H #define GLPSCF_H /*********************************************************************** * The structure SCF defines the following factorization of a square * nxn matrix C (which is the Schur complement): * * F * C = U * P, * * where F is a square transforming matrix, U is an upper triangular * matrix, P is a permutation matrix. * * It is assumed that matrix C is small and dense, so matrices F and U * are stored in the dense format by rows as follows: * * 1 n n_max 1 n n_max * 1 * * * * * * x x x x 1 * * * * * * x x x x * * * * * * * x x x x . * * * * * x x x x * * * * * * * x x x x . . * * * * x x x x * * * * * * * x x x x . . . * * * x x x x * * * * * * * x x x x . . . . * * x x x x * n * * * * * * x x x x n . . . . . * x x x x * x x x x x x x x x x . . . . . . x x x x * x x x x x x x x x x . . . . . . . x x x * x x x x x x x x x x . . . . . . . . x x * n_max x x x x x x x x x x n_max . . . . . . . . . x * * matrix F matrix U * * where '*' are matrix elements, 'x' are reserved locations. * * Permutation matrix P is stored in row-like format. * * Matrix C normally is not stored. * * REFERENCES * * 1. M.A.Saunders, "LUSOL: A basis package for constrained optimiza- * tion," SCCM, Stanford University, 2006. * * 2. M.A.Saunders, "Notes 5: Basis Updates," CME 318, Stanford Univer- * sity, Spring 2006. * * 3. M.A.Saunders, "Notes 6: LUSOL---a Basis Factorization Package," * ibid. */ typedef struct SCF SCF; struct SCF { /* Schur complement factorization */ int n_max; /* maximal order of matrices C, F, U, P; n_max >= 1 */ int n; /* current order of matrices C, F, U, P; n >= 0 */ double *f; /* double f[1+n_max*n_max]; */ /* matrix F stored by rows */ double *u; /* double u[1+n_max*(n_max+1)/2]; */ /* upper triangle of matrix U stored by rows */ int *p; /* int p[1+n_max]; */ /* matrix P; p[i] = j means that P[i,j] = 1 */ int t_opt; /* type of transformation used to restore triangular structure of matrix U: */ #define SCF_TBG 1 /* Bartels-Golub elimination */ #define SCF_TGR 2 /* Givens plane rotation */ int rank; /* estimated rank of matrices C and U */ double *c; /* double c[1+n_max*n_max]; */ /* matrix C stored in the same format as matrix F and used only for debugging; normally this array is not allocated */ double *w; /* double w[1+n_max]; */ /* working array */ }; /* return codes: */ #define SCF_ESING 1 /* singular matrix */ #define SCF_ELIMIT 2 /* update limit reached */ #define scf_create_it _glp_scf_create_it SCF *scf_create_it(int n_max); /* create Schur complement factorization */ #define scf_update_exp _glp_scf_update_exp int scf_update_exp(SCF *scf, const double x[], const double y[], double z); /* update factorization on expanding C */ #define scf_solve_it _glp_scf_solve_it void scf_solve_it(SCF *scf, int tr, double x[]); /* solve either system C * x = b or C' * x = b */ #define scf_reset_it _glp_scf_reset_it void scf_reset_it(SCF *scf); /* reset factorization for empty matrix C */ #define scf_delete_it _glp_scf_delete_it void scf_delete_it(SCF *scf); /* delete Schur complement factorization */ #endif /* eof */ praat-6.0.04/external/glpk/glpscl.c000066400000000000000000000372321261542461700171360ustar00rootroot00000000000000/* glpscl.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpapi.h" /*********************************************************************** * min_row_aij - determine minimal |a[i,j]| in i-th row * * This routine returns minimal magnitude of (non-zero) constraint * coefficients in i-th row of the constraint matrix. * * If the parameter scaled is zero, the original constraint matrix A is * assumed. Otherwise, the scaled constraint matrix R*A*S is assumed. * * If i-th row of the matrix is empty, the routine returns 1. */ static double min_row_aij(glp_prob *lp, int i, int scaled) { GLPAIJ *aij; double min_aij, temp; xassert(1 <= i && i <= lp->m); min_aij = 1.0; for (aij = lp->row[i]->ptr; aij != NULL; aij = aij->r_next) { temp = fabs(aij->val); if (scaled) temp *= (aij->row->rii * aij->col->sjj); if (aij->r_prev == NULL || min_aij > temp) min_aij = temp; } return min_aij; } /*********************************************************************** * max_row_aij - determine maximal |a[i,j]| in i-th row * * This routine returns maximal magnitude of (non-zero) constraint * coefficients in i-th row of the constraint matrix. * * If the parameter scaled is zero, the original constraint matrix A is * assumed. Otherwise, the scaled constraint matrix R*A*S is assumed. * * If i-th row of the matrix is empty, the routine returns 1. */ static double max_row_aij(glp_prob *lp, int i, int scaled) { GLPAIJ *aij; double max_aij, temp; xassert(1 <= i && i <= lp->m); max_aij = 1.0; for (aij = lp->row[i]->ptr; aij != NULL; aij = aij->r_next) { temp = fabs(aij->val); if (scaled) temp *= (aij->row->rii * aij->col->sjj); if (aij->r_prev == NULL || max_aij < temp) max_aij = temp; } return max_aij; } /*********************************************************************** * min_col_aij - determine minimal |a[i,j]| in j-th column * * This routine returns minimal magnitude of (non-zero) constraint * coefficients in j-th column of the constraint matrix. * * If the parameter scaled is zero, the original constraint matrix A is * assumed. Otherwise, the scaled constraint matrix R*A*S is assumed. * * If j-th column of the matrix is empty, the routine returns 1. */ static double min_col_aij(glp_prob *lp, int j, int scaled) { GLPAIJ *aij; double min_aij, temp; xassert(1 <= j && j <= lp->n); min_aij = 1.0; for (aij = lp->col[j]->ptr; aij != NULL; aij = aij->c_next) { temp = fabs(aij->val); if (scaled) temp *= (aij->row->rii * aij->col->sjj); if (aij->c_prev == NULL || min_aij > temp) min_aij = temp; } return min_aij; } /*********************************************************************** * max_col_aij - determine maximal |a[i,j]| in j-th column * * This routine returns maximal magnitude of (non-zero) constraint * coefficients in j-th column of the constraint matrix. * * If the parameter scaled is zero, the original constraint matrix A is * assumed. Otherwise, the scaled constraint matrix R*A*S is assumed. * * If j-th column of the matrix is empty, the routine returns 1. */ static double max_col_aij(glp_prob *lp, int j, int scaled) { GLPAIJ *aij; double max_aij, temp; xassert(1 <= j && j <= lp->n); max_aij = 1.0; for (aij = lp->col[j]->ptr; aij != NULL; aij = aij->c_next) { temp = fabs(aij->val); if (scaled) temp *= (aij->row->rii * aij->col->sjj); if (aij->c_prev == NULL || max_aij < temp) max_aij = temp; } return max_aij; } /*********************************************************************** * min_mat_aij - determine minimal |a[i,j]| in constraint matrix * * This routine returns minimal magnitude of (non-zero) constraint * coefficients in the constraint matrix. * * If the parameter scaled is zero, the original constraint matrix A is * assumed. Otherwise, the scaled constraint matrix R*A*S is assumed. * * If the matrix is empty, the routine returns 1. */ static double min_mat_aij(glp_prob *lp, int scaled) { int i; double min_aij, temp; min_aij = 1.0; for (i = 1; i <= lp->m; i++) { temp = min_row_aij(lp, i, scaled); if (i == 1 || min_aij > temp) min_aij = temp; } return min_aij; } /*********************************************************************** * max_mat_aij - determine maximal |a[i,j]| in constraint matrix * * This routine returns maximal magnitude of (non-zero) constraint * coefficients in the constraint matrix. * * If the parameter scaled is zero, the original constraint matrix A is * assumed. Otherwise, the scaled constraint matrix R*A*S is assumed. * * If the matrix is empty, the routine returns 1. */ static double max_mat_aij(glp_prob *lp, int scaled) { int i; double max_aij, temp; max_aij = 1.0; for (i = 1; i <= lp->m; i++) { temp = max_row_aij(lp, i, scaled); if (i == 1 || max_aij < temp) max_aij = temp; } return max_aij; } /*********************************************************************** * eq_scaling - perform equilibration scaling * * This routine performs equilibration scaling of rows and columns of * the constraint matrix. * * If the parameter flag is zero, the routine scales rows at first and * then columns. Otherwise, the routine scales columns and then rows. * * Rows are scaled as follows: * * n * a'[i,j] = a[i,j] / max |a[i,j]|, i = 1,...,m. * j=1 * * This makes the infinity (maximum) norm of each row of the matrix * equal to 1. * * Columns are scaled as follows: * * n * a'[i,j] = a[i,j] / max |a[i,j]|, j = 1,...,n. * i=1 * * This makes the infinity (maximum) norm of each column of the matrix * equal to 1. */ static void eq_scaling(glp_prob *lp, int flag) { int i, j, pass; double temp; xassert(flag == 0 || flag == 1); for (pass = 0; pass <= 1; pass++) { if (pass == flag) { /* scale rows */ for (i = 1; i <= lp->m; i++) { temp = max_row_aij(lp, i, 1); glp_set_rii(lp, i, glp_get_rii(lp, i) / temp); } } else { /* scale columns */ for (j = 1; j <= lp->n; j++) { temp = max_col_aij(lp, j, 1); glp_set_sjj(lp, j, glp_get_sjj(lp, j) / temp); } } } return; } /*********************************************************************** * gm_scaling - perform geometric mean scaling * * This routine performs geometric mean scaling of rows and columns of * the constraint matrix. * * If the parameter flag is zero, the routine scales rows at first and * then columns. Otherwise, the routine scales columns and then rows. * * Rows are scaled as follows: * * a'[i,j] = a[i,j] / sqrt(alfa[i] * beta[i]), i = 1,...,m, * * where: * n n * alfa[i] = min |a[i,j]|, beta[i] = max |a[i,j]|. * j=1 j=1 * * This allows decreasing the ratio beta[i] / alfa[i] for each row of * the matrix. * * Columns are scaled as follows: * * a'[i,j] = a[i,j] / sqrt(alfa[j] * beta[j]), j = 1,...,n, * * where: * m m * alfa[j] = min |a[i,j]|, beta[j] = max |a[i,j]|. * i=1 i=1 * * This allows decreasing the ratio beta[j] / alfa[j] for each column * of the matrix. */ static void gm_scaling(glp_prob *lp, int flag) { int i, j, pass; double temp; xassert(flag == 0 || flag == 1); for (pass = 0; pass <= 1; pass++) { if (pass == flag) { /* scale rows */ for (i = 1; i <= lp->m; i++) { temp = min_row_aij(lp, i, 1) * max_row_aij(lp, i, 1); glp_set_rii(lp, i, glp_get_rii(lp, i) / sqrt(temp)); } } else { /* scale columns */ for (j = 1; j <= lp->n; j++) { temp = min_col_aij(lp, j, 1) * max_col_aij(lp, j, 1); glp_set_sjj(lp, j, glp_get_sjj(lp, j) / sqrt(temp)); } } } return; } /*********************************************************************** * max_row_ratio - determine worst scaling "quality" for rows * * This routine returns the worst scaling "quality" for rows of the * currently scaled constraint matrix: * * m * ratio = max ratio[i], * i=1 * where: * n n * ratio[i] = max |a[i,j]| / min |a[i,j]|, 1 <= i <= m, * j=1 j=1 * * is the scaling "quality" of i-th row. */ static double max_row_ratio(glp_prob *lp) { int i; double ratio, temp; ratio = 1.0; for (i = 1; i <= lp->m; i++) { temp = max_row_aij(lp, i, 1) / min_row_aij(lp, i, 1); if (i == 1 || ratio < temp) ratio = temp; } return ratio; } /*********************************************************************** * max_col_ratio - determine worst scaling "quality" for columns * * This routine returns the worst scaling "quality" for columns of the * currently scaled constraint matrix: * * n * ratio = max ratio[j], * j=1 * where: * m m * ratio[j] = max |a[i,j]| / min |a[i,j]|, 1 <= j <= n, * i=1 i=1 * * is the scaling "quality" of j-th column. */ static double max_col_ratio(glp_prob *lp) { int j; double ratio, temp; ratio = 1.0; for (j = 1; j <= lp->n; j++) { temp = max_col_aij(lp, j, 1) / min_col_aij(lp, j, 1); if (j == 1 || ratio < temp) ratio = temp; } return ratio; } /*********************************************************************** * gm_iterate - perform iterative geometric mean scaling * * This routine performs iterative geometric mean scaling of rows and * columns of the constraint matrix. * * The parameter it_max specifies the maximal number of iterations. * Recommended value of it_max is 15. * * The parameter tau specifies a minimal improvement of the scaling * "quality" on each iteration, 0 < tau < 1. It means than the scaling * process continues while the following condition is satisfied: * * ratio[k] <= tau * ratio[k-1], * * where ratio = max |a[i,j]| / min |a[i,j]| is the scaling "quality" * to be minimized, k is the iteration number. Recommended value of tau * is 0.90. */ static void gm_iterate(glp_prob *lp, int it_max, double tau) { int k, flag; double ratio = 0.0, r_old; /* if the scaling "quality" for rows is better than for columns, the rows are scaled first; otherwise, the columns are scaled first */ flag = (max_row_ratio(lp) > max_col_ratio(lp)); for (k = 1; k <= it_max; k++) { /* save the scaling "quality" from previous iteration */ r_old = ratio; /* determine the current scaling "quality" */ ratio = max_mat_aij(lp, 1) / min_mat_aij(lp, 1); #if 0 xprintf("k = %d; ratio = %g\n", k, ratio); #endif /* if improvement is not enough, terminate scaling */ if (k > 1 && ratio > tau * r_old) break; /* otherwise, perform another iteration */ gm_scaling(lp, flag); } return; } /*********************************************************************** * NAME * * scale_prob - scale problem data * * SYNOPSIS * * #include "glpscl.h" * void scale_prob(glp_prob *lp, int flags); * * DESCRIPTION * * The routine scale_prob performs automatic scaling of problem data * for the specified problem object. */ static void scale_prob(glp_prob *lp, int flags) { static const char *fmt = "%s: min|aij| = %10.3e max|aij| = %10.3e ratio = %10.3e\n"; double min_aij, max_aij, ratio; xprintf("Scaling...\n"); /* cancel the current scaling effect */ glp_unscale_prob(lp); /* report original scaling "quality" */ min_aij = min_mat_aij(lp, 1); max_aij = max_mat_aij(lp, 1); ratio = max_aij / min_aij; xprintf(fmt, " A", min_aij, max_aij, ratio); /* check if the problem is well scaled */ if (min_aij >= 0.10 && max_aij <= 10.0) { xprintf("Problem data seem to be well scaled\n"); /* skip scaling, if required */ if (flags & GLP_SF_SKIP) goto done; } /* perform iterative geometric mean scaling, if required */ if (flags & GLP_SF_GM) { gm_iterate(lp, 15, 0.90); min_aij = min_mat_aij(lp, 1); max_aij = max_mat_aij(lp, 1); ratio = max_aij / min_aij; xprintf(fmt, "GM", min_aij, max_aij, ratio); } /* perform equilibration scaling, if required */ if (flags & GLP_SF_EQ) { eq_scaling(lp, max_row_ratio(lp) > max_col_ratio(lp)); min_aij = min_mat_aij(lp, 1); max_aij = max_mat_aij(lp, 1); ratio = max_aij / min_aij; xprintf(fmt, "EQ", min_aij, max_aij, ratio); } /* round scale factors to nearest power of two, if required */ if (flags & GLP_SF_2N) { int i, j; for (i = 1; i <= lp->m; i++) glp_set_rii(lp, i, round2n(glp_get_rii(lp, i))); for (j = 1; j <= lp->n; j++) glp_set_sjj(lp, j, round2n(glp_get_sjj(lp, j))); min_aij = min_mat_aij(lp, 1); max_aij = max_mat_aij(lp, 1); ratio = max_aij / min_aij; xprintf(fmt, "2N", min_aij, max_aij, ratio); } done: return; } /*********************************************************************** * NAME * * glp_scale_prob - scale problem data * * SYNOPSIS * * void glp_scale_prob(glp_prob *lp, int flags); * * DESCRIPTION * * The routine glp_scale_prob performs automatic scaling of problem * data for the specified problem object. * * The parameter flags specifies scaling options used by the routine. * Options can be combined with the bitwise OR operator and may be the * following: * * GLP_SF_GM perform geometric mean scaling; * GLP_SF_EQ perform equilibration scaling; * GLP_SF_2N round scale factors to nearest power of two; * GLP_SF_SKIP skip scaling, if the problem is well scaled. * * The parameter flags may be specified as GLP_SF_AUTO, in which case * the routine chooses scaling options automatically. */ void glp_scale_prob(glp_prob *lp, int flags) { if (flags & ~(GLP_SF_GM | GLP_SF_EQ | GLP_SF_2N | GLP_SF_SKIP | GLP_SF_AUTO)) xerror("glp_scale_prob: flags = 0x%02X; invalid scaling option" "s\n", flags); if (flags & GLP_SF_AUTO) flags = (GLP_SF_GM | GLP_SF_EQ | GLP_SF_SKIP); scale_prob(lp, flags); return; } /* eof */ praat-6.0.04/external/glpk/glpsdf.c000066400000000000000000000157631261542461700171360ustar00rootroot00000000000000/* glpsdf.c (plain data file reading routines) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #define GLPSDF_H #define GLP_DATA_DEFINED typedef struct glp_data glp_data; #include "glpapi.h" struct glp_data { /* plain data file */ char *fname; /* name of data file */ XFILE *fp; /* stream assigned to data file */ void *jump; /* jmp_buf jump; */ /* label for go to in case of error */ int count; /* line count */ int c; /* current character of XEOF */ char item[255+1]; /* current data item */ }; static void next_char(glp_data *data); glp_data *glp_sdf_open_file(const char *fname) { /* open plain data file */ glp_data *data = NULL; XFILE *fp; jmp_buf jump; fp = xfopen(fname, "r"); if (fp == NULL) { xprintf("Unable to open `%s' - %s\n", fname, xerrmsg()); goto done; } data = xmalloc(sizeof(glp_data)); data->fname = xmalloc(strlen(fname)+1); strcpy(data->fname, fname); data->fp = fp; data->jump = NULL; data->count = 0; data->c = '\n'; data->item[0] = '\0'; /* read the very first character */ if (setjmp(jump)) { glp_sdf_close_file(data); data = NULL; goto done; } data->jump = jump; next_char(data); data->jump = NULL; done: return data; } void glp_sdf_set_jump(glp_data *data, void *jump) { /* set up error handling */ data->jump = jump; return; } void glp_sdf_error(glp_data *data, const char *fmt, ...) { /* print error message */ va_list arg; xprintf("%s:%d: ", data->fname, data->count); va_start(arg, fmt); xvprintf(fmt, arg); va_end(arg); if (data->jump == NULL) xerror(""); else longjmp(data->jump, 1); /* no return */ } void glp_sdf_warning(glp_data *data, const char *fmt, ...) { /* print warning message */ va_list arg; xprintf("%s:%d: warning: ", data->fname, data->count); va_start(arg, fmt); xvprintf(fmt, arg); va_end(arg); return; } static void next_char(glp_data *data) { /* read next character */ int c; if (data->c == XEOF) glp_sdf_error(data, "unexpected end of file\n"); else if (data->c == '\n') data->count++; c = xfgetc(data->fp); if (c < 0) { if (xferror(data->fp)) glp_sdf_error(data, "read error - %s\n", xerrmsg()); else if (data->c == '\n') c = XEOF; else { glp_sdf_warning(data, "missing final end of line\n"); c = '\n'; } } else if (c == '\n') ; else if (isspace(c)) c = ' '; else if (iscntrl(c)) glp_sdf_error(data, "invalid control character 0x%02X\n", c); data->c = c; return; } static void skip_pad(glp_data *data) { /* skip uninteresting characters and comments */ loop: while (data->c == ' ' || data->c == '\n') next_char(data); if (data->c == '/') { next_char(data); if (data->c != '*') glp_sdf_error(data, "invalid use of slash\n"); next_char(data); for (;;) { if (data->c == '*') { next_char(data); if (data->c == '/') { next_char(data); break; } } next_char(data); } goto loop; } return; } static void next_item(glp_data *data) { /* read next item */ int len; skip_pad(data); len = 0; while (!(data->c == ' ' || data->c == '\n')) { data->item[len++] = (char)data->c; if (len == sizeof(data->item)) glp_sdf_error(data, "data item `%.31s...' too long\n", data->item); next_char(data); } data->item[len] = '\0'; return; } int glp_sdf_read_int(glp_data *data) { /* read integer number */ int x; next_item(data); switch (str2int(data->item, &x)) { case 0: break; case 1: glp_sdf_error(data, "integer `%s' out of range\n", data->item); case 2: glp_sdf_error(data, "cannot convert `%s' to integer\n", data->item); default: xassert(data != data); } return x; } double glp_sdf_read_num(glp_data *data) { /* read floating-point number */ double x; next_item(data); switch (str2num(data->item, &x)) { case 0: break; case 1: glp_sdf_error(data, "number `%s' out of range\n", data->item); case 2: glp_sdf_error(data, "cannot convert `%s' to number\n", data->item); default: xassert(data != data); } return x; } const char *glp_sdf_read_item(glp_data *data) { /* read data item */ next_item(data); return data->item; } const char *glp_sdf_read_text(glp_data *data) { /* read text until end of line */ int c, len = 0; for (;;) { c = data->c; next_char(data); if (c == ' ') { /* ignore initial spaces */ if (len == 0) continue; /* and multiple ones */ if (data->item[len-1] == ' ') continue; } else if (c == '\n') { /* remove trailing space */ if (len > 0 && data->item[len-1] == ' ') len--; /* and stop reading */ break; } /* add current character to the buffer */ data->item[len++] = (char)c; if (len == sizeof(data->item)) glp_sdf_error(data, "line too long\n", data->item); } data->item[len] = '\0'; return data->item; } int glp_sdf_line(glp_data *data) { /* determine current line number */ return data->count; } void glp_sdf_close_file(glp_data *data) { /* close plain data file */ xfclose(data->fp); xfree(data->fname); xfree(data); return; } /* eof */ praat-6.0.04/external/glpk/glpspm.c000066400000000000000000000604731261542461700171570ustar00rootroot00000000000000/* glpspm.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glphbm.h" #include "glprgr.h" #include "glpspm.h" /*********************************************************************** * NAME * * spm_create_mat - create general sparse matrix * * SYNOPSIS * * #include "glpspm.h" * SPM *spm_create_mat(int m, int n); * * DESCRIPTION * * The routine spm_create_mat creates a general sparse matrix having * m rows and n columns. Being created the matrix is zero (empty), i.e. * has no elements. * * RETURNS * * The routine returns a pointer to the matrix created. */ SPM *spm_create_mat(int m, int n) { SPM *A; xassert(0 <= m && m < INT_MAX); xassert(0 <= n && n < INT_MAX); A = xmalloc(sizeof(SPM)); A->m = m; A->n = n; if (m == 0 || n == 0) { A->pool = NULL; A->row = NULL; A->col = NULL; } else { int i, j; A->pool = dmp_create_pool(); A->row = xcalloc(1+m, sizeof(SPME *)); for (i = 1; i <= m; i++) A->row[i] = NULL; A->col = xcalloc(1+n, sizeof(SPME *)); for (j = 1; j <= n; j++) A->col[j] = NULL; } return A; } /*********************************************************************** * NAME * * spm_new_elem - add new element to sparse matrix * * SYNOPSIS * * #include "glpspm.h" * SPME *spm_new_elem(SPM *A, int i, int j, double val); * * DESCRIPTION * * The routine spm_new_elem adds a new element to the specified sparse * matrix. Parameters i, j, and val specify the row number, the column * number, and a numerical value of the element, respectively. * * RETURNS * * The routine returns a pointer to the new element added. */ SPME *spm_new_elem(SPM *A, int i, int j, double val) { SPME *e; xassert(1 <= i && i <= A->m); xassert(1 <= j && j <= A->n); e = dmp_get_atom(A->pool, sizeof(SPME)); e->i = i; e->j = j; e->val = val; e->r_prev = NULL; e->r_next = A->row[i]; if (e->r_next != NULL) e->r_next->r_prev = e; e->c_prev = NULL; e->c_next = A->col[j]; if (e->c_next != NULL) e->c_next->c_prev = e; A->row[i] = A->col[j] = e; return e; } /*********************************************************************** * NAME * * spm_delete_mat - delete general sparse matrix * * SYNOPSIS * * #include "glpspm.h" * void spm_delete_mat(SPM *A); * * DESCRIPTION * * The routine deletes the specified general sparse matrix freeing all * the memory allocated to this object. */ void spm_delete_mat(SPM *A) { /* delete sparse matrix */ if (A->pool != NULL) dmp_delete_pool(A->pool); if (A->row != NULL) xfree(A->row); if (A->col != NULL) xfree(A->col); xfree(A); return; } /*********************************************************************** * NAME * * spm_test_mat_e - create test sparse matrix of E(n,c) class * * SYNOPSIS * * #include "glpspm.h" * SPM *spm_test_mat_e(int n, int c); * * DESCRIPTION * * The routine spm_test_mat_e creates a test sparse matrix of E(n,c) * class as described in the book: Ole 0sterby, Zahari Zlatev. Direct * Methods for Sparse Matrices. Springer-Verlag, 1983. * * Matrix of E(n,c) class is a symmetric positive definite matrix of * the order n. It has the number 4 on its main diagonal and the number * -1 on its four co-diagonals, two of which are neighbour to the main * diagonal and two others are shifted from the main diagonal on the * distance c. * * It is necessary that n >= 3 and 2 <= c <= n-1. * * RETURNS * * The routine returns a pointer to the matrix created. */ SPM *spm_test_mat_e(int n, int c) { SPM *A; int i; xassert(n >= 3 && 2 <= c && c <= n-1); A = spm_create_mat(n, n); for (i = 1; i <= n; i++) spm_new_elem(A, i, i, 4.0); for (i = 1; i <= n-1; i++) { spm_new_elem(A, i, i+1, -1.0); spm_new_elem(A, i+1, i, -1.0); } for (i = 1; i <= n-c; i++) { spm_new_elem(A, i, i+c, -1.0); spm_new_elem(A, i+c, i, -1.0); } return A; } /*********************************************************************** * NAME * * spm_test_mat_d - create test sparse matrix of D(n,c) class * * SYNOPSIS * * #include "glpspm.h" * SPM *spm_test_mat_d(int n, int c); * * DESCRIPTION * * The routine spm_test_mat_d creates a test sparse matrix of D(n,c) * class as described in the book: Ole 0sterby, Zahari Zlatev. Direct * Methods for Sparse Matrices. Springer-Verlag, 1983. * * Matrix of D(n,c) class is a non-singular matrix of the order n. It * has unity main diagonal, three co-diagonals above the main diagonal * on the distance c, which are cyclically continued below the main * diagonal, and a triangle block of the size 10x10 in the upper right * corner. * * It is necessary that n >= 14 and 1 <= c <= n-13. * * RETURNS * * The routine returns a pointer to the matrix created. */ SPM *spm_test_mat_d(int n, int c) { SPM *A; int i, j; xassert(n >= 14 && 1 <= c && c <= n-13); A = spm_create_mat(n, n); for (i = 1; i <= n; i++) spm_new_elem(A, i, i, 1.0); for (i = 1; i <= n-c; i++) spm_new_elem(A, i, i+c, (double)(i+1)); for (i = n-c+1; i <= n; i++) spm_new_elem(A, i, i-n+c, (double)(i+1)); for (i = 1; i <= n-c-1; i++) spm_new_elem(A, i, i+c+1, (double)(-i)); for (i = n-c; i <= n; i++) spm_new_elem(A, i, i-n+c+1, (double)(-i)); for (i = 1; i <= n-c-2; i++) spm_new_elem(A, i, i+c+2, 16.0); for (i = n-c-1; i <= n; i++) spm_new_elem(A, i, i-n+c+2, 16.0); for (j = 1; j <= 10; j++) for (i = 1; i <= 11-j; i++) spm_new_elem(A, i, n-11+i+j, 100.0 * (double)j); return A; } /*********************************************************************** * NAME * * spm_show_mat - write sparse matrix pattern in BMP file format * * SYNOPSIS * * #include "glpspm.h" * int spm_show_mat(const SPM *A, const char *fname); * * DESCRIPTION * * The routine spm_show_mat writes pattern of the specified sparse * matrix in uncompressed BMP file format (Windows bitmap) to a binary * file whose name is specified by the character string fname. * * Each pixel corresponds to one matrix element. The pixel colors have * the following meaning: * * Black structurally zero element * White positive element * Cyan negative element * Green zero element * Red duplicate element * * RETURNS * * If no error occured, the routine returns zero. Otherwise, it prints * an appropriate error message and returns non-zero. */ int spm_show_mat(const SPM *A, const char *fname) { int m = A->m; int n = A->n; int i, j, k, ret; char *map; xprintf("spm_show_mat: writing matrix pattern to `%s'...\n", fname); xassert(1 <= m && m <= 32767); xassert(1 <= n && n <= 32767); map = xmalloc(m * n); memset(map, 0x08, m * n); for (i = 1; i <= m; i++) { SPME *e; for (e = A->row[i]; e != NULL; e = e->r_next) { j = e->j; xassert(1 <= j && j <= n); k = n * (i - 1) + (j - 1); if (map[k] != 0x08) map[k] = 0x0C; else if (e->val > 0.0) map[k] = 0x0F; else if (e->val < 0.0) map[k] = 0x0B; else map[k] = 0x0A; } } ret = rgr_write_bmp16(fname, m, n, map); xfree(map); return ret; } /*********************************************************************** * NAME * * spm_read_hbm - read sparse matrix in Harwell-Boeing format * * SYNOPSIS * * #include "glpspm.h" * SPM *spm_read_hbm(const char *fname); * * DESCRIPTION * * The routine spm_read_hbm reads a sparse matrix in the Harwell-Boeing * format from a text file whose name is the character string fname. * * Detailed description of the Harwell-Boeing format recognised by this * routine can be found in the following report: * * I.S.Duff, R.G.Grimes, J.G.Lewis. User's Guide for the Harwell-Boeing * Sparse Matrix Collection (Release I), TR/PA/92/86, October 1992. * * NOTE * * The routine spm_read_hbm reads the matrix "as is", due to which zero * and/or duplicate elements can appear in the matrix. * * RETURNS * * If no error occured, the routine returns a pointer to the matrix * created. Otherwise, the routine prints an appropriate error message * and returns NULL. */ SPM *spm_read_hbm(const char *fname) { SPM *A = NULL; HBM *hbm; int nrow, ncol, nnzero, i, j, beg, end, ptr, *colptr, *rowind; double val, *values; char *mxtype; hbm = hbm_read_mat(fname); if (hbm == NULL) { xprintf("spm_read_hbm: unable to read matrix\n"); goto fini; } mxtype = hbm->mxtype; nrow = hbm->nrow; ncol = hbm->ncol; nnzero = hbm->nnzero; colptr = hbm->colptr; rowind = hbm->rowind; values = hbm->values; if (!(strcmp(mxtype, "RSA") == 0 || strcmp(mxtype, "PSA") == 0 || strcmp(mxtype, "RUA") == 0 || strcmp(mxtype, "PUA") == 0 || strcmp(mxtype, "RRA") == 0 || strcmp(mxtype, "PRA") == 0)) { xprintf("spm_read_hbm: matrix type `%s' not supported\n", mxtype); goto fini; } A = spm_create_mat(nrow, ncol); if (mxtype[1] == 'S' || mxtype[1] == 'U') xassert(nrow == ncol); for (j = 1; j <= ncol; j++) { beg = colptr[j]; end = colptr[j+1]; xassert(1 <= beg && beg <= end && end <= nnzero + 1); for (ptr = beg; ptr < end; ptr++) { i = rowind[ptr]; xassert(1 <= i && i <= nrow); if (mxtype[0] == 'R') val = values[ptr]; else val = 1.0; spm_new_elem(A, i, j, val); if (mxtype[1] == 'S' && i != j) spm_new_elem(A, j, i, val); } } fini: if (hbm != NULL) hbm_free_mat(hbm); return A; } /*********************************************************************** * NAME * * spm_count_nnz - determine number of non-zeros in sparse matrix * * SYNOPSIS * * #include "glpspm.h" * int spm_count_nnz(const SPM *A); * * RETURNS * * The routine spm_count_nnz returns the number of structural non-zero * elements in the specified sparse matrix. */ int spm_count_nnz(const SPM *A) { SPME *e; int i, nnz = 0; for (i = 1; i <= A->m; i++) for (e = A->row[i]; e != NULL; e = e->r_next) nnz++; return nnz; } /*********************************************************************** * NAME * * spm_drop_zeros - remove zero elements from sparse matrix * * SYNOPSIS * * #include "glpspm.h" * int spm_drop_zeros(SPM *A, double eps); * * DESCRIPTION * * The routine spm_drop_zeros removes all elements from the specified * sparse matrix, whose absolute value is less than eps. * * If the parameter eps is 0, only zero elements are removed from the * matrix. * * RETURNS * * The routine returns the number of elements removed. */ int spm_drop_zeros(SPM *A, double eps) { SPME *e, *next; int i, count = 0; for (i = 1; i <= A->m; i++) { for (e = A->row[i]; e != NULL; e = next) { next = e->r_next; if (e->val == 0.0 || fabs(e->val) < eps) { /* remove element from the row list */ if (e->r_prev == NULL) A->row[e->i] = e->r_next; else e->r_prev->r_next = e->r_next; if (e->r_next == NULL) ; else e->r_next->r_prev = e->r_prev; /* remove element from the column list */ if (e->c_prev == NULL) A->col[e->j] = e->c_next; else e->c_prev->c_next = e->c_next; if (e->c_next == NULL) ; else e->c_next->c_prev = e->c_prev; /* return element to the memory pool */ dmp_free_atom(A->pool, e, sizeof(SPME)); count++; } } } return count; } /*********************************************************************** * NAME * * spm_read_mat - read sparse matrix from text file * * SYNOPSIS * * #include "glpspm.h" * SPM *spm_read_mat(const char *fname); * * DESCRIPTION * * The routine reads a sparse matrix from a text file whose name is * specified by the parameter fname. * * For the file format see description of the routine spm_write_mat. * * RETURNS * * On success the routine returns a pointer to the matrix created, * otherwise NULL. */ #if 1 SPM *spm_read_mat(const char *fname) { xassert(fname != fname); return NULL; } #else SPM *spm_read_mat(const char *fname) { SPM *A = NULL; PDS *pds; jmp_buf jump; int i, j, k, m, n, nnz, fail = 0; double val; xprintf("spm_read_mat: reading matrix from `%s'...\n", fname); pds = pds_open_file(fname); if (pds == NULL) { xprintf("spm_read_mat: unable to open `%s' - %s\n", fname, strerror(errno)); fail = 1; goto done; } if (setjmp(jump)) { fail = 1; goto done; } pds_set_jump(pds, jump); /* number of rows, number of columns, number of non-zeros */ m = pds_scan_int(pds); if (m < 0) pds_error(pds, "invalid number of rows\n"); n = pds_scan_int(pds); if (n < 0) pds_error(pds, "invalid number of columns\n"); nnz = pds_scan_int(pds); if (nnz < 0) pds_error(pds, "invalid number of non-zeros\n"); /* create matrix */ xprintf("spm_read_mat: %d rows, %d columns, %d non-zeros\n", m, n, nnz); A = spm_create_mat(m, n); /* read matrix elements */ for (k = 1; k <= nnz; k++) { /* row index, column index, element value */ i = pds_scan_int(pds); if (!(1 <= i && i <= m)) pds_error(pds, "row index out of range\n"); j = pds_scan_int(pds); if (!(1 <= j && j <= n)) pds_error(pds, "column index out of range\n"); val = pds_scan_num(pds); /* add new element to the matrix */ spm_new_elem(A, i, j, val); } xprintf("spm_read_mat: %d lines were read\n", pds->count); done: if (pds != NULL) pds_close_file(pds); if (fail && A != NULL) spm_delete_mat(A), A = NULL; return A; } #endif /*********************************************************************** * NAME * * spm_write_mat - write sparse matrix to text file * * SYNOPSIS * * #include "glpspm.h" * int spm_write_mat(const SPM *A, const char *fname); * * DESCRIPTION * * The routine spm_write_mat writes the specified sparse matrix to a * text file whose name is specified by the parameter fname. This file * can be read back with the routine spm_read_mat. * * RETURNS * * On success the routine returns zero, otherwise non-zero. * * FILE FORMAT * * The file created by the routine spm_write_mat is a plain text file, * which contains the following information: * * m n nnz * row[1] col[1] val[1] * row[2] col[2] val[2] * . . . * row[nnz] col[nnz] val[nnz] * * where: * m is the number of rows; * n is the number of columns; * nnz is the number of non-zeros; * row[k], k = 1,...,nnz, are row indices; * col[k], k = 1,...,nnz, are column indices; * val[k], k = 1,...,nnz, are element values. */ #if 1 int spm_write_mat(const SPM *A, const char *fname) { xassert(A != A); xassert(fname != fname); return 0; } #else int spm_write_mat(const SPM *A, const char *fname) { FILE *fp; int i, nnz, ret = 0; xprintf("spm_write_mat: writing matrix to `%s'...\n", fname); fp = fopen(fname, "w"); if (fp == NULL) { xprintf("spm_write_mat: unable to create `%s' - %s\n", fname, strerror(errno)); ret = 1; goto done; } /* number of rows, number of columns, number of non-zeros */ nnz = spm_count_nnz(A); fprintf(fp, "%d %d %d\n", A->m, A->n, nnz); /* walk through rows of the matrix */ for (i = 1; i <= A->m; i++) { SPME *e; /* walk through elements of i-th row */ for (e = A->row[i]; e != NULL; e = e->r_next) { /* row index, column index, element value */ fprintf(fp, "%d %d %.*g\n", e->i, e->j, DBL_DIG, e->val); } } fflush(fp); if (ferror(fp)) { xprintf("spm_write_mat: writing error on `%s' - %s\n", fname, strerror(errno)); ret = 1; goto done; } xprintf("spm_write_mat: %d lines were written\n", 1 + nnz); done: if (fp != NULL) fclose(fp); return ret; } #endif /*********************************************************************** * NAME * * spm_transpose - transpose sparse matrix * * SYNOPSIS * * #include "glpspm.h" * SPM *spm_transpose(const SPM *A); * * RETURNS * * The routine computes and returns sparse matrix B, which is a matrix * transposed to sparse matrix A. */ SPM *spm_transpose(const SPM *A) { SPM *B; int i; B = spm_create_mat(A->n, A->m); for (i = 1; i <= A->m; i++) { SPME *e; for (e = A->row[i]; e != NULL; e = e->r_next) spm_new_elem(B, e->j, i, e->val); } return B; } SPM *spm_add_sym(const SPM *A, const SPM *B) { /* add two sparse matrices (symbolic phase) */ SPM *C; int i, j, *flag; xassert(A->m == B->m); xassert(A->n == B->n); /* create resultant matrix */ C = spm_create_mat(A->m, A->n); /* allocate and clear the flag array */ flag = xcalloc(1+C->n, sizeof(int)); for (j = 1; j <= C->n; j++) flag[j] = 0; /* compute pattern of C = A + B */ for (i = 1; i <= C->m; i++) { SPME *e; /* at the beginning i-th row of C is empty */ /* (i-th row of C) := (i-th row of C) union (i-th row of A) */ for (e = A->row[i]; e != NULL; e = e->r_next) { /* (note that i-th row of A may have duplicate elements) */ j = e->j; if (!flag[j]) { spm_new_elem(C, i, j, 0.0); flag[j] = 1; } } /* (i-th row of C) := (i-th row of C) union (i-th row of B) */ for (e = B->row[i]; e != NULL; e = e->r_next) { /* (note that i-th row of B may have duplicate elements) */ j = e->j; if (!flag[j]) { spm_new_elem(C, i, j, 0.0); flag[j] = 1; } } /* reset the flag array */ for (e = C->row[i]; e != NULL; e = e->r_next) flag[e->j] = 0; } /* check and deallocate the flag array */ for (j = 1; j <= C->n; j++) xassert(!flag[j]); xfree(flag); return C; } void spm_add_num(SPM *C, double alfa, const SPM *A, double beta, const SPM *B) { /* add two sparse matrices (numeric phase) */ int i, j; double *work; /* allocate and clear the working array */ work = xcalloc(1+C->n, sizeof(double)); for (j = 1; j <= C->n; j++) work[j] = 0.0; /* compute matrix C = alfa * A + beta * B */ for (i = 1; i <= C->n; i++) { SPME *e; /* work := alfa * (i-th row of A) + beta * (i-th row of B) */ /* (note that A and/or B may have duplicate elements) */ for (e = A->row[i]; e != NULL; e = e->r_next) work[e->j] += alfa * e->val; for (e = B->row[i]; e != NULL; e = e->r_next) work[e->j] += beta * e->val; /* (i-th row of C) := work, work := 0 */ for (e = C->row[i]; e != NULL; e = e->r_next) { j = e->j; e->val = work[j]; work[j] = 0.0; } } /* check and deallocate the working array */ for (j = 1; j <= C->n; j++) xassert(work[j] == 0.0); xfree(work); return; } SPM *spm_add_mat(double alfa, const SPM *A, double beta, const SPM *B) { /* add two sparse matrices (driver routine) */ SPM *C; C = spm_add_sym(A, B); spm_add_num(C, alfa, A, beta, B); return C; } SPM *spm_mul_sym(const SPM *A, const SPM *B) { /* multiply two sparse matrices (symbolic phase) */ int i, j, k, *flag; SPM *C; xassert(A->n == B->m); /* create resultant matrix */ C = spm_create_mat(A->m, B->n); /* allocate and clear the flag array */ flag = xcalloc(1+C->n, sizeof(int)); for (j = 1; j <= C->n; j++) flag[j] = 0; /* compute pattern of C = A * B */ for (i = 1; i <= C->m; i++) { SPME *e, *ee; /* compute pattern of i-th row of C */ for (e = A->row[i]; e != NULL; e = e->r_next) { k = e->j; for (ee = B->row[k]; ee != NULL; ee = ee->r_next) { j = ee->j; /* if a[i,k] != 0 and b[k,j] != 0 then c[i,j] != 0 */ if (!flag[j]) { /* c[i,j] does not exist, so create it */ spm_new_elem(C, i, j, 0.0); flag[j] = 1; } } } /* reset the flag array */ for (e = C->row[i]; e != NULL; e = e->r_next) flag[e->j] = 0; } /* check and deallocate the flag array */ for (j = 1; j <= C->n; j++) xassert(!flag[j]); xfree(flag); return C; } void spm_mul_num(SPM *C, const SPM *A, const SPM *B) { /* multiply two sparse matrices (numeric phase) */ int i, j; double *work; /* allocate and clear the working array */ work = xcalloc(1+A->n, sizeof(double)); for (j = 1; j <= A->n; j++) work[j] = 0.0; /* compute matrix C = A * B */ for (i = 1; i <= C->m; i++) { SPME *e, *ee; double temp; /* work := (i-th row of A) */ /* (note that A may have duplicate elements) */ for (e = A->row[i]; e != NULL; e = e->r_next) work[e->j] += e->val; /* compute i-th row of C */ for (e = C->row[i]; e != NULL; e = e->r_next) { j = e->j; /* c[i,j] := work * (j-th column of B) */ temp = 0.0; for (ee = B->col[j]; ee != NULL; ee = ee->c_next) temp += work[ee->i] * ee->val; e->val = temp; } /* reset the working array */ for (e = A->row[i]; e != NULL; e = e->r_next) work[e->j] = 0.0; } /* check and deallocate the working array */ for (j = 1; j <= A->n; j++) xassert(work[j] == 0.0); xfree(work); return; } SPM *spm_mul_mat(const SPM *A, const SPM *B) { /* multiply two sparse matrices (driver routine) */ SPM *C; C = spm_mul_sym(A, B); spm_mul_num(C, A, B); return C; } PER *spm_create_per(int n) { /* create permutation matrix */ PER *P; int k; xassert(n >= 0); P = xmalloc(sizeof(PER)); P->n = n; P->row = xcalloc(1+n, sizeof(int)); P->col = xcalloc(1+n, sizeof(int)); /* initially it is identity matrix */ for (k = 1; k <= n; k++) P->row[k] = P->col[k] = k; return P; } void spm_check_per(PER *P) { /* check permutation matrix for correctness */ int i, j; xassert(P->n >= 0); for (i = 1; i <= P->n; i++) { j = P->row[i]; xassert(1 <= j && j <= P->n); xassert(P->col[j] == i); } return; } void spm_delete_per(PER *P) { /* delete permutation matrix */ xfree(P->row); xfree(P->col); xfree(P); return; } /* eof */ praat-6.0.04/external/glpk/glpspm.h000066400000000000000000000117401261542461700171550ustar00rootroot00000000000000/* glpspm.h (general sparse matrix) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPSPM_H #define GLPSPM_H #include "glpdmp.h" typedef struct SPM SPM; typedef struct SPME SPME; struct SPM { /* general sparse matrix */ int m; /* number of rows, m >= 0 */ int n; /* number of columns, n >= 0 */ DMP *pool; /* memory pool to store matrix elements */ SPME **row; /* SPME *row[1+m]; */ /* row[i], 1 <= i <= m, is a pointer to i-th row list */ SPME **col; /* SPME *col[1+n]; */ /* col[j], 1 <= j <= n, is a pointer to j-th column list */ }; struct SPME { /* sparse matrix element */ int i; /* row number */ int j; /* column number */ double val; /* element value */ SPME *r_prev; /* pointer to previous element in the same row */ SPME *r_next; /* pointer to next element in the same row */ SPME *c_prev; /* pointer to previous element in the same column */ SPME *c_next; /* pointer to next element in the same column */ }; typedef struct PER PER; struct PER { /* permutation matrix */ int n; /* matrix order, n >= 0 */ int *row; /* int row[1+n]; */ /* row[i] = j means p[i,j] = 1 */ int *col; /* int col[1+n]; */ /* col[j] = i means p[i,j] = 1 */ }; #define spm_create_mat _glp_spm_create_mat SPM *spm_create_mat(int m, int n); /* create general sparse matrix */ #define spm_new_elem _glp_spm_new_elem SPME *spm_new_elem(SPM *A, int i, int j, double val); /* add new element to sparse matrix */ #define spm_delete_mat _glp_spm_delete_mat void spm_delete_mat(SPM *A); /* delete general sparse matrix */ #define spm_test_mat_e _glp_spm_test_mat_e SPM *spm_test_mat_e(int n, int c); /* create test sparse matrix of E(n,c) class */ #define spm_test_mat_d _glp_spm_test_mat_d SPM *spm_test_mat_d(int n, int c); /* create test sparse matrix of D(n,c) class */ #define spm_show_mat _glp_spm_show_mat int spm_show_mat(const SPM *A, const char *fname); /* write sparse matrix pattern in BMP file format */ #define spm_read_hbm _glp_spm_read_hbm SPM *spm_read_hbm(const char *fname); /* read sparse matrix in Harwell-Boeing format */ #define spm_count_nnz _glp_spm_count_nnz int spm_count_nnz(const SPM *A); /* determine number of non-zeros in sparse matrix */ #define spm_drop_zeros _glp_spm_drop_zeros int spm_drop_zeros(SPM *A, double eps); /* remove zero elements from sparse matrix */ #define spm_read_mat _glp_spm_read_mat SPM *spm_read_mat(const char *fname); /* read sparse matrix from text file */ #define spm_write_mat _glp_spm_write_mat int spm_write_mat(const SPM *A, const char *fname); /* write sparse matrix to text file */ #define spm_transpose _glp_spm_transpose SPM *spm_transpose(const SPM *A); /* transpose sparse matrix */ #define spm_add_sym _glp_spm_add_sym SPM *spm_add_sym(const SPM *A, const SPM *B); /* add two sparse matrices (symbolic phase) */ #define spm_add_num _glp_spm_add_num void spm_add_num(SPM *C, double alfa, const SPM *A, double beta, const SPM *B); /* add two sparse matrices (numeric phase) */ #define spm_add_mat _glp_spm_add_mat SPM *spm_add_mat(double alfa, const SPM *A, double beta, const SPM *B); /* add two sparse matrices (driver routine) */ #define spm_mul_sym _glp_spm_mul_sym SPM *spm_mul_sym(const SPM *A, const SPM *B); /* multiply two sparse matrices (symbolic phase) */ #define spm_mul_num _glp_spm_mul_num void spm_mul_num(SPM *C, const SPM *A, const SPM *B); /* multiply two sparse matrices (numeric phase) */ #define spm_mul_mat _glp_spm_mul_mat SPM *spm_mul_mat(const SPM *A, const SPM *B); /* multiply two sparse matrices (driver routine) */ #define spm_create_per _glp_spm_create_per PER *spm_create_per(int n); /* create permutation matrix */ #define spm_check_per _glp_spm_check_per void spm_check_per(PER *P); /* check permutation matrix for correctness */ #define spm_delete_per _glp_spm_delete_per void spm_delete_per(PER *P); /* delete permutation matrix */ #endif /* eof */ praat-6.0.04/external/glpk/glpspx.h000066400000000000000000000026541261542461700171740ustar00rootroot00000000000000/* glpspx.h (core simplex solvers) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPSPX_H #define GLPSPX_H #include "glpapi.h" #define spx_primal _glp_spx_primal int spx_primal(glp_prob *lp, const glp_smcp *parm); /* core LP solver based on the primal simplex method */ #define spx_dual _glp_spx_dual int spx_dual(glp_prob *lp, const glp_smcp *parm); /* core LP solver based on the dual simplex method */ #endif /* eof */ praat-6.0.04/external/glpk/glpspx01.c000066400000000000000000003011651261542461700173270ustar00rootroot00000000000000/* glpspx01.c (primal simplex method) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpspx.h" struct csa { /* common storage area */ /*--------------------------------------------------------------*/ /* LP data */ int m; /* number of rows (auxiliary variables), m > 0 */ int n; /* number of columns (structural variables), n > 0 */ char *type; /* char type[1+m+n]; */ /* type[0] is not used; type[k], 1 <= k <= m+n, is the type of variable x[k]: GLP_FR - free variable GLP_LO - variable with lower bound GLP_UP - variable with upper bound GLP_DB - double-bounded variable GLP_FX - fixed variable */ double *lb; /* double lb[1+m+n]; */ /* lb[0] is not used; lb[k], 1 <= k <= m+n, is an lower bound of variable x[k]; if x[k] has no lower bound, lb[k] is zero */ double *ub; /* double ub[1+m+n]; */ /* ub[0] is not used; ub[k], 1 <= k <= m+n, is an upper bound of variable x[k]; if x[k] has no upper bound, ub[k] is zero; if x[k] is of fixed type, ub[k] is the same as lb[k] */ double *coef; /* double coef[1+m+n]; */ /* coef[0] is not used; coef[k], 1 <= k <= m+n, is an objective coefficient at variable x[k] (note that on phase I auxiliary variables also may have non-zero objective coefficients) */ /*--------------------------------------------------------------*/ /* original objective function */ double *obj; /* double obj[1+n]; */ /* obj[0] is a constant term of the original objective function; obj[j], 1 <= j <= n, is an original objective coefficient at structural variable x[m+j] */ double zeta; /* factor used to scale original objective coefficients; its sign defines original optimization direction: zeta > 0 means minimization, zeta < 0 means maximization */ /*--------------------------------------------------------------*/ /* constraint matrix A; it has m rows and n columns and is stored by columns */ int *A_ptr; /* int A_ptr[1+n+1]; */ /* A_ptr[0] is not used; A_ptr[j], 1 <= j <= n, is starting position of j-th column in arrays A_ind and A_val; note that A_ptr[1] is always 1; A_ptr[n+1] indicates the position after the last element in arrays A_ind and A_val */ int *A_ind; /* int A_ind[A_ptr[n+1]]; */ /* row indices */ double *A_val; /* double A_val[A_ptr[n+1]]; */ /* non-zero element values */ /*--------------------------------------------------------------*/ /* basis header */ int *head; /* int head[1+m+n]; */ /* head[0] is not used; head[i], 1 <= i <= m, is the ordinal number of basic variable xB[i]; head[i] = k means that xB[i] = x[k] and i-th column of matrix B is k-th column of matrix (I|-A); head[m+j], 1 <= j <= n, is the ordinal number of non-basic variable xN[j]; head[m+j] = k means that xN[j] = x[k] and j-th column of matrix N is k-th column of matrix (I|-A) */ char *stat; /* char stat[1+n]; */ /* stat[0] is not used; stat[j], 1 <= j <= n, is the status of non-basic variable xN[j], which defines its active bound: GLP_NL - lower bound is active GLP_NU - upper bound is active GLP_NF - free variable GLP_NS - fixed variable */ /*--------------------------------------------------------------*/ /* matrix B is the basis matrix; it is composed from columns of the augmented constraint matrix (I|-A) corresponding to basic variables and stored in a factorized (invertable) form */ int valid; /* factorization is valid only if this flag is set */ BFD *bfd; /* BFD bfd[1:m,1:m]; */ /* factorized (invertable) form of the basis matrix */ /*--------------------------------------------------------------*/ /* matrix N is a matrix composed from columns of the augmented constraint matrix (I|-A) corresponding to non-basic variables except fixed ones; it is stored by rows and changes every time the basis changes */ int *N_ptr; /* int N_ptr[1+m+1]; */ /* N_ptr[0] is not used; N_ptr[i], 1 <= i <= m, is starting position of i-th row in arrays N_ind and N_val; note that N_ptr[1] is always 1; N_ptr[m+1] indicates the position after the last element in arrays N_ind and N_val */ int *N_len; /* int N_len[1+m]; */ /* N_len[0] is not used; N_len[i], 1 <= i <= m, is length of i-th row (0 to n) */ int *N_ind; /* int N_ind[N_ptr[m+1]]; */ /* column indices */ double *N_val; /* double N_val[N_ptr[m+1]]; */ /* non-zero element values */ /*--------------------------------------------------------------*/ /* working parameters */ int phase; /* search phase: 0 - not determined yet 1 - search for primal feasible solution 2 - search for optimal solution */ glp_long tm_beg; /* time value at the beginning of the search */ int it_beg; /* simplex iteration count at the beginning of the search */ int it_cnt; /* simplex iteration count; it increases by one every time the basis changes (including the case when a non-basic variable jumps to its opposite bound) */ int it_dpy; /* simplex iteration count at the most recent display output */ /*--------------------------------------------------------------*/ /* basic solution components */ double *bbar; /* double bbar[1+m]; */ /* bbar[0] is not used; bbar[i], 1 <= i <= m, is primal value of basic variable xB[i] (if xB[i] is free, its primal value is not updated) */ double *cbar; /* double cbar[1+n]; */ /* cbar[0] is not used; cbar[j], 1 <= j <= n, is reduced cost of non-basic variable xN[j] (if xN[j] is fixed, its reduced cost is not updated) */ /*--------------------------------------------------------------*/ /* the following pricing technique options may be used: GLP_PT_STD - standard ("textbook") pricing; GLP_PT_PSE - projected steepest edge; GLP_PT_DVX - Devex pricing (not implemented yet); in case of GLP_PT_STD the reference space is not used, and all steepest edge coefficients are set to 1 */ int refct; /* this count is set to an initial value when the reference space is defined and decreases by one every time the basis changes; once this count reaches zero, the reference space is redefined again */ char *refsp; /* char refsp[1+m+n]; */ /* refsp[0] is not used; refsp[k], 1 <= k <= m+n, is the flag which means that variable x[k] belongs to the current reference space */ double *gamma; /* double gamma[1+n]; */ /* gamma[0] is not used; gamma[j], 1 <= j <= n, is the steepest edge coefficient for non-basic variable xN[j]; if xN[j] is fixed, gamma[j] is not used and just set to 1 */ /*--------------------------------------------------------------*/ /* non-basic variable xN[q] chosen to enter the basis */ int q; /* index of the non-basic variable xN[q] chosen, 1 <= q <= n; if the set of eligible non-basic variables is empty and thus no variable has been chosen, q is set to 0 */ /*--------------------------------------------------------------*/ /* pivot column of the simplex table corresponding to non-basic variable xN[q] chosen is the following vector: T * e[q] = - inv(B) * N * e[q] = - inv(B) * N[q], where B is the current basis matrix, N[q] is a column of the matrix (I|-A) corresponding to xN[q] */ int tcol_nnz; /* number of non-zero components, 0 <= nnz <= m */ int *tcol_ind; /* int tcol_ind[1+m]; */ /* tcol_ind[0] is not used; tcol_ind[t], 1 <= t <= nnz, is an index of non-zero component, i.e. tcol_ind[t] = i means that tcol_vec[i] != 0 */ double *tcol_vec; /* double tcol_vec[1+m]; */ /* tcol_vec[0] is not used; tcol_vec[i], 1 <= i <= m, is a numeric value of i-th component of the column */ double tcol_max; /* infinity (maximum) norm of the column (max |tcol_vec[i]|) */ int tcol_num; /* number of significant non-zero components, which means that: |tcol_vec[i]| >= eps for i in tcol_ind[1,...,num], |tcol_vec[i]| < eps for i in tcol_ind[num+1,...,nnz], where eps is a pivot tolerance */ /*--------------------------------------------------------------*/ /* basic variable xB[p] chosen to leave the basis */ int p; /* index of the basic variable xB[p] chosen, 1 <= p <= m; p = 0 means that no basic variable reaches its bound; p < 0 means that non-basic variable xN[q] reaches its opposite bound before any basic variable */ int p_stat; /* new status (GLP_NL, GLP_NU, or GLP_NS) to be assigned to xB[p] once it has left the basis */ double teta; /* change of non-basic variable xN[q] (see above), on which xB[p] (or, if p < 0, xN[q] itself) reaches its bound */ /*--------------------------------------------------------------*/ /* pivot row of the simplex table corresponding to basic variable xB[p] chosen is the following vector: T' * e[p] = - N' * inv(B') * e[p] = - N' * rho, where B' is a matrix transposed to the current basis matrix, N' is a matrix, whose rows are columns of the matrix (I|-A) corresponding to non-basic non-fixed variables */ int trow_nnz; /* number of non-zero components, 0 <= nnz <= n */ int *trow_ind; /* int trow_ind[1+n]; */ /* trow_ind[0] is not used; trow_ind[t], 1 <= t <= nnz, is an index of non-zero component, i.e. trow_ind[t] = j means that trow_vec[j] != 0 */ double *trow_vec; /* int trow_vec[1+n]; */ /* trow_vec[0] is not used; trow_vec[j], 1 <= j <= n, is a numeric value of j-th component of the row */ /*--------------------------------------------------------------*/ /* working arrays */ double *work1; /* double work1[1+m]; */ double *work2; /* double work2[1+m]; */ double *work3; /* double work3[1+m]; */ double *work4; /* double work4[1+m]; */ }; static const double kappa = 0.10; /*********************************************************************** * alloc_csa - allocate common storage area * * This routine allocates all arrays in the common storage area (CSA) * and returns a pointer to the CSA. */ static struct csa *alloc_csa(glp_prob *lp) { struct csa *csa; int m = lp->m; int n = lp->n; int nnz = lp->nnz; csa = xmalloc(sizeof(struct csa)); xassert(m > 0 && n > 0); csa->m = m; csa->n = n; csa->type = xcalloc(1+m+n, sizeof(char)); csa->lb = xcalloc(1+m+n, sizeof(double)); csa->ub = xcalloc(1+m+n, sizeof(double)); csa->coef = xcalloc(1+m+n, sizeof(double)); csa->obj = xcalloc(1+n, sizeof(double)); csa->A_ptr = xcalloc(1+n+1, sizeof(int)); csa->A_ind = xcalloc(1+nnz, sizeof(int)); csa->A_val = xcalloc(1+nnz, sizeof(double)); csa->head = xcalloc(1+m+n, sizeof(int)); csa->stat = xcalloc(1+n, sizeof(char)); csa->N_ptr = xcalloc(1+m+1, sizeof(int)); csa->N_len = xcalloc(1+m, sizeof(int)); csa->N_ind = NULL; /* will be allocated later */ csa->N_val = NULL; /* will be allocated later */ csa->bbar = xcalloc(1+m, sizeof(double)); csa->cbar = xcalloc(1+n, sizeof(double)); csa->refsp = xcalloc(1+m+n, sizeof(char)); csa->gamma = xcalloc(1+n, sizeof(double)); csa->tcol_ind = xcalloc(1+m, sizeof(int)); csa->tcol_vec = xcalloc(1+m, sizeof(double)); csa->trow_ind = xcalloc(1+n, sizeof(int)); csa->trow_vec = xcalloc(1+n, sizeof(double)); csa->work1 = xcalloc(1+m, sizeof(double)); csa->work2 = xcalloc(1+m, sizeof(double)); csa->work3 = xcalloc(1+m, sizeof(double)); csa->work4 = xcalloc(1+m, sizeof(double)); return csa; } /*********************************************************************** * init_csa - initialize common storage area * * This routine initializes all data structures in the common storage * area (CSA). */ static void alloc_N(struct csa *csa); static void build_N(struct csa *csa); static void init_csa(struct csa *csa, glp_prob *lp) { int m = csa->m; int n = csa->n; char *type = csa->type; double *lb = csa->lb; double *ub = csa->ub; double *coef = csa->coef; double *obj = csa->obj; int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; int *head = csa->head; char *stat = csa->stat; char *refsp = csa->refsp; double *gamma = csa->gamma; int i, j, k, loc; double cmax; /* auxiliary variables */ for (i = 1; i <= m; i++) { GLPROW *row = lp->row[i]; type[i] = (char)row->type; lb[i] = row->lb * row->rii; ub[i] = row->ub * row->rii; coef[i] = 0.0; } /* structural variables */ for (j = 1; j <= n; j++) { GLPCOL *col = lp->col[j]; type[m+j] = (char)col->type; lb[m+j] = col->lb / col->sjj; ub[m+j] = col->ub / col->sjj; coef[m+j] = col->coef * col->sjj; } /* original objective function */ obj[0] = lp->c0; memcpy(&obj[1], &coef[m+1], n * sizeof(double)); /* factor used to scale original objective coefficients */ cmax = 0.0; for (j = 1; j <= n; j++) if (cmax < fabs(obj[j])) cmax = fabs(obj[j]); if (cmax == 0.0) cmax = 1.0; switch (lp->dir) { case GLP_MIN: csa->zeta = + 1.0 / cmax; break; case GLP_MAX: csa->zeta = - 1.0 / cmax; break; default: xassert(lp != lp); } #if 1 if (fabs(csa->zeta) < 1.0) csa->zeta *= 1000.0; #endif /* matrix A (by columns) */ loc = 1; for (j = 1; j <= n; j++) { GLPAIJ *aij; A_ptr[j] = loc; for (aij = lp->col[j]->ptr; aij != NULL; aij = aij->c_next) { A_ind[loc] = aij->row->i; A_val[loc] = aij->row->rii * aij->val * aij->col->sjj; loc++; } } A_ptr[n+1] = loc; xassert(loc == lp->nnz+1); /* basis header */ xassert(lp->valid); memcpy(&head[1], &lp->head[1], m * sizeof(int)); k = 0; for (i = 1; i <= m; i++) { GLPROW *row = lp->row[i]; if (row->stat != GLP_BS) { k++; xassert(k <= n); head[m+k] = i; stat[k] = (char)row->stat; } } for (j = 1; j <= n; j++) { GLPCOL *col = lp->col[j]; if (col->stat != GLP_BS) { k++; xassert(k <= n); head[m+k] = m + j; stat[k] = (char)col->stat; } } xassert(k == n); /* factorization of matrix B */ csa->valid = 1, lp->valid = 0; csa->bfd = lp->bfd, lp->bfd = NULL; /* matrix N (by rows) */ alloc_N(csa); build_N(csa); /* working parameters */ csa->phase = 0; csa->tm_beg = xtime(); csa->it_beg = csa->it_cnt = lp->it_cnt; csa->it_dpy = -1; /* reference space and steepest edge coefficients */ csa->refct = 0; memset(&refsp[1], 0, (m+n) * sizeof(char)); for (j = 1; j <= n; j++) gamma[j] = 1.0; return; } /*********************************************************************** * invert_B - compute factorization of the basis matrix * * This routine computes factorization of the current basis matrix B. * * If the operation is successful, the routine returns zero, otherwise * non-zero. */ static int inv_col(void *info, int i, int ind[], double val[]) { /* this auxiliary routine returns row indices and numeric values of non-zero elements of i-th column of the basis matrix */ struct csa *csa = info; int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; int *head = csa->head; int k, len, ptr, t; #ifdef GLP_DEBUG xassert(1 <= i && i <= m); #endif k = head[i]; /* B[i] is k-th column of (I|-A) */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif if (k <= m) { /* B[i] is k-th column of submatrix I */ len = 1; ind[1] = k; val[1] = 1.0; } else { /* B[i] is (k-m)-th column of submatrix (-A) */ ptr = A_ptr[k-m]; len = A_ptr[k-m+1] - ptr; memcpy(&ind[1], &A_ind[ptr], len * sizeof(int)); memcpy(&val[1], &A_val[ptr], len * sizeof(double)); for (t = 1; t <= len; t++) val[t] = - val[t]; } return len; } static int invert_B(struct csa *csa) { int ret; ret = bfd_factorize(csa->bfd, csa->m, NULL, inv_col, csa); csa->valid = (ret == 0); return ret; } /*********************************************************************** * update_B - update factorization of the basis matrix * * This routine replaces i-th column of the basis matrix B by k-th * column of the augmented constraint matrix (I|-A) and then updates * the factorization of B. * * If the factorization has been successfully updated, the routine * returns zero, otherwise non-zero. */ static int update_B(struct csa *csa, int i, int k) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif int ret; #ifdef GLP_DEBUG xassert(1 <= i && i <= m); xassert(1 <= k && k <= m+n); #endif if (k <= m) { /* new i-th column of B is k-th column of I */ int ind[1+1]; double val[1+1]; ind[1] = k; val[1] = 1.0; xassert(csa->valid); ret = bfd_update_it(csa->bfd, i, 0, 1, ind, val); } else { /* new i-th column of B is (k-m)-th column of (-A) */ int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; double *val = csa->work1; int beg, end, ptr, len; beg = A_ptr[k-m]; end = A_ptr[k-m+1]; len = 0; for (ptr = beg; ptr < end; ptr++) val[++len] = - A_val[ptr]; xassert(csa->valid); ret = bfd_update_it(csa->bfd, i, 0, len, &A_ind[beg-1], val); } csa->valid = (ret == 0); return ret; } /*********************************************************************** * error_ftran - compute residual vector r = h - B * x * * This routine computes the residual vector r = h - B * x, where B is * the current basis matrix, h is the vector of right-hand sides, x is * the solution vector. */ static void error_ftran(struct csa *csa, double h[], double x[], double r[]) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; int *head = csa->head; int i, k, beg, end, ptr; double temp; /* compute the residual vector: r = h - B * x = h - B[1] * x[1] - ... - B[m] * x[m], where B[1], ..., B[m] are columns of matrix B */ memcpy(&r[1], &h[1], m * sizeof(double)); for (i = 1; i <= m; i++) { temp = x[i]; if (temp == 0.0) continue; k = head[i]; /* B[i] is k-th column of (I|-A) */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif if (k <= m) { /* B[i] is k-th column of submatrix I */ r[k] -= temp; } else { /* B[i] is (k-m)-th column of submatrix (-A) */ beg = A_ptr[k-m]; end = A_ptr[k-m+1]; for (ptr = beg; ptr < end; ptr++) r[A_ind[ptr]] += A_val[ptr] * temp; } } return; } /*********************************************************************** * refine_ftran - refine solution of B * x = h * * This routine performs one iteration to refine the solution of * the system B * x = h, where B is the current basis matrix, h is the * vector of right-hand sides, x is the solution vector. */ static void refine_ftran(struct csa *csa, double h[], double x[]) { int m = csa->m; double *r = csa->work1; double *d = csa->work1; int i; /* compute the residual vector r = h - B * x */ error_ftran(csa, h, x, r); /* compute the correction vector d = inv(B) * r */ xassert(csa->valid); bfd_ftran(csa->bfd, d); /* refine the solution vector (new x) = (old x) + d */ for (i = 1; i <= m; i++) x[i] += d[i]; return; } /*********************************************************************** * error_btran - compute residual vector r = h - B'* x * * This routine computes the residual vector r = h - B'* x, where B' * is a matrix transposed to the current basis matrix, h is the vector * of right-hand sides, x is the solution vector. */ static void error_btran(struct csa *csa, double h[], double x[], double r[]) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; int *head = csa->head; int i, k, beg, end, ptr; double temp; /* compute the residual vector r = b - B'* x */ for (i = 1; i <= m; i++) { /* r[i] := b[i] - (i-th column of B)'* x */ k = head[i]; /* B[i] is k-th column of (I|-A) */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif temp = h[i]; if (k <= m) { /* B[i] is k-th column of submatrix I */ temp -= x[k]; } else { /* B[i] is (k-m)-th column of submatrix (-A) */ beg = A_ptr[k-m]; end = A_ptr[k-m+1]; for (ptr = beg; ptr < end; ptr++) temp += A_val[ptr] * x[A_ind[ptr]]; } r[i] = temp; } return; } /*********************************************************************** * refine_btran - refine solution of B'* x = h * * This routine performs one iteration to refine the solution of the * system B'* x = h, where B' is a matrix transposed to the current * basis matrix, h is the vector of right-hand sides, x is the solution * vector. */ static void refine_btran(struct csa *csa, double h[], double x[]) { int m = csa->m; double *r = csa->work1; double *d = csa->work1; int i; /* compute the residual vector r = h - B'* x */ error_btran(csa, h, x, r); /* compute the correction vector d = inv(B') * r */ xassert(csa->valid); bfd_btran(csa->bfd, d); /* refine the solution vector (new x) = (old x) + d */ for (i = 1; i <= m; i++) x[i] += d[i]; return; } /*********************************************************************** * alloc_N - allocate matrix N * * This routine determines maximal row lengths of matrix N, sets its * row pointers, and then allocates arrays N_ind and N_val. * * Note that some fixed structural variables may temporarily become * double-bounded, so corresponding columns of matrix A should not be * ignored on calculating maximal row lengths of matrix N. */ static void alloc_N(struct csa *csa) { int m = csa->m; int n = csa->n; int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; int *N_ptr = csa->N_ptr; int *N_len = csa->N_len; int i, j, beg, end, ptr; /* determine number of non-zeros in each row of the augmented constraint matrix (I|-A) */ for (i = 1; i <= m; i++) N_len[i] = 1; for (j = 1; j <= n; j++) { beg = A_ptr[j]; end = A_ptr[j+1]; for (ptr = beg; ptr < end; ptr++) N_len[A_ind[ptr]]++; } /* determine maximal row lengths of matrix N and set its row pointers */ N_ptr[1] = 1; for (i = 1; i <= m; i++) { /* row of matrix N cannot have more than n non-zeros */ if (N_len[i] > n) N_len[i] = n; N_ptr[i+1] = N_ptr[i] + N_len[i]; } /* now maximal number of non-zeros in matrix N is known */ csa->N_ind = xcalloc(N_ptr[m+1], sizeof(int)); csa->N_val = xcalloc(N_ptr[m+1], sizeof(double)); return; } /*********************************************************************** * add_N_col - add column of matrix (I|-A) to matrix N * * This routine adds j-th column to matrix N which is k-th column of * the augmented constraint matrix (I|-A). (It is assumed that old j-th * column was previously removed from matrix N.) */ static void add_N_col(struct csa *csa, int j, int k) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif int *N_ptr = csa->N_ptr; int *N_len = csa->N_len; int *N_ind = csa->N_ind; double *N_val = csa->N_val; int pos; #ifdef GLP_DEBUG xassert(1 <= j && j <= n); xassert(1 <= k && k <= m+n); #endif if (k <= m) { /* N[j] is k-th column of submatrix I */ pos = N_ptr[k] + (N_len[k]++); #ifdef GLP_DEBUG xassert(pos < N_ptr[k+1]); #endif N_ind[pos] = j; N_val[pos] = 1.0; } else { /* N[j] is (k-m)-th column of submatrix (-A) */ int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; int i, beg, end, ptr; beg = A_ptr[k-m]; end = A_ptr[k-m+1]; for (ptr = beg; ptr < end; ptr++) { i = A_ind[ptr]; /* row number */ pos = N_ptr[i] + (N_len[i]++); #ifdef GLP_DEBUG xassert(pos < N_ptr[i+1]); #endif N_ind[pos] = j; N_val[pos] = - A_val[ptr]; } } return; } /*********************************************************************** * del_N_col - remove column of matrix (I|-A) from matrix N * * This routine removes j-th column from matrix N which is k-th column * of the augmented constraint matrix (I|-A). */ static void del_N_col(struct csa *csa, int j, int k) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif int *N_ptr = csa->N_ptr; int *N_len = csa->N_len; int *N_ind = csa->N_ind; double *N_val = csa->N_val; int pos, head, tail; #ifdef GLP_DEBUG xassert(1 <= j && j <= n); xassert(1 <= k && k <= m+n); #endif if (k <= m) { /* N[j] is k-th column of submatrix I */ /* find element in k-th row of N */ head = N_ptr[k]; for (pos = head; N_ind[pos] != j; pos++) /* nop */; /* and remove it from the row list */ tail = head + (--N_len[k]); #ifdef GLP_DEBUG xassert(pos <= tail); #endif N_ind[pos] = N_ind[tail]; N_val[pos] = N_val[tail]; } else { /* N[j] is (k-m)-th column of submatrix (-A) */ int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; int i, beg, end, ptr; beg = A_ptr[k-m]; end = A_ptr[k-m+1]; for (ptr = beg; ptr < end; ptr++) { i = A_ind[ptr]; /* row number */ /* find element in i-th row of N */ head = N_ptr[i]; for (pos = head; N_ind[pos] != j; pos++) /* nop */; /* and remove it from the row list */ tail = head + (--N_len[i]); #ifdef GLP_DEBUG xassert(pos <= tail); #endif N_ind[pos] = N_ind[tail]; N_val[pos] = N_val[tail]; } } return; } /*********************************************************************** * build_N - build matrix N for current basis * * This routine builds matrix N for the current basis from columns * of the augmented constraint matrix (I|-A) corresponding to non-basic * non-fixed variables. */ static void build_N(struct csa *csa) { int m = csa->m; int n = csa->n; int *head = csa->head; char *stat = csa->stat; int *N_len = csa->N_len; int j, k; /* N := empty matrix */ memset(&N_len[1], 0, m * sizeof(int)); /* go through non-basic columns of matrix (I|-A) */ for (j = 1; j <= n; j++) { if (stat[j] != GLP_NS) { /* xN[j] is non-fixed; add j-th column to matrix N which is k-th column of matrix (I|-A) */ k = head[m+j]; /* x[k] = xN[j] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif add_N_col(csa, j, k); } } return; } /*********************************************************************** * get_xN - determine current value of non-basic variable xN[j] * * This routine returns the current value of non-basic variable xN[j], * which is a value of its active bound. */ static double get_xN(struct csa *csa, int j) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif double *lb = csa->lb; double *ub = csa->ub; int *head = csa->head; char *stat = csa->stat; int k; double xN; #ifdef GLP_DEBUG xassert(1 <= j && j <= n); #endif k = head[m+j]; /* x[k] = xN[j] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif switch (stat[j]) { case GLP_NL: /* x[k] is on its lower bound */ xN = lb[k]; break; case GLP_NU: /* x[k] is on its upper bound */ xN = ub[k]; break; case GLP_NF: /* x[k] is free non-basic variable */ xN = 0.0; break; case GLP_NS: /* x[k] is fixed non-basic variable */ xN = lb[k]; break; default: xassert(stat != stat); } return xN; } /*********************************************************************** * eval_beta - compute primal values of basic variables * * This routine computes current primal values of all basic variables: * * beta = - inv(B) * N * xN, * * where B is the current basis matrix, N is a matrix built of columns * of matrix (I|-A) corresponding to non-basic variables, and xN is the * vector of current values of non-basic variables. */ static void eval_beta(struct csa *csa, double beta[]) { int m = csa->m; int n = csa->n; int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; int *head = csa->head; double *h = csa->work2; int i, j, k, beg, end, ptr; double xN; /* compute the right-hand side vector: h := - N * xN = - N[1] * xN[1] - ... - N[n] * xN[n], where N[1], ..., N[n] are columns of matrix N */ for (i = 1; i <= m; i++) h[i] = 0.0; for (j = 1; j <= n; j++) { k = head[m+j]; /* x[k] = xN[j] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif /* determine current value of xN[j] */ xN = get_xN(csa, j); if (xN == 0.0) continue; if (k <= m) { /* N[j] is k-th column of submatrix I */ h[k] -= xN; } else { /* N[j] is (k-m)-th column of submatrix (-A) */ beg = A_ptr[k-m]; end = A_ptr[k-m+1]; for (ptr = beg; ptr < end; ptr++) h[A_ind[ptr]] += xN * A_val[ptr]; } } /* solve system B * beta = h */ memcpy(&beta[1], &h[1], m * sizeof(double)); xassert(csa->valid); bfd_ftran(csa->bfd, beta); /* and refine the solution */ refine_ftran(csa, h, beta); return; } /*********************************************************************** * eval_pi - compute vector of simplex multipliers * * This routine computes the vector of current simplex multipliers: * * pi = inv(B') * cB, * * where B' is a matrix transposed to the current basis matrix, cB is * a subvector of objective coefficients at basic variables. */ static void eval_pi(struct csa *csa, double pi[]) { int m = csa->m; double *c = csa->coef; int *head = csa->head; double *cB = csa->work2; int i; /* construct the right-hand side vector cB */ for (i = 1; i <= m; i++) cB[i] = c[head[i]]; /* solve system B'* pi = cB */ memcpy(&pi[1], &cB[1], m * sizeof(double)); xassert(csa->valid); bfd_btran(csa->bfd, pi); /* and refine the solution */ refine_btran(csa, cB, pi); return; } /*********************************************************************** * eval_cost - compute reduced cost of non-basic variable xN[j] * * This routine computes the current reduced cost of non-basic variable * xN[j]: * * d[j] = cN[j] - N'[j] * pi, * * where cN[j] is the objective coefficient at variable xN[j], N[j] is * a column of the augmented constraint matrix (I|-A) corresponding to * xN[j], pi is the vector of simplex multipliers. */ static double eval_cost(struct csa *csa, double pi[], int j) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif double *coef = csa->coef; int *head = csa->head; int k; double dj; #ifdef GLP_DEBUG xassert(1 <= j && j <= n); #endif k = head[m+j]; /* x[k] = xN[j] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif dj = coef[k]; if (k <= m) { /* N[j] is k-th column of submatrix I */ dj -= pi[k]; } else { /* N[j] is (k-m)-th column of submatrix (-A) */ int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; int beg, end, ptr; beg = A_ptr[k-m]; end = A_ptr[k-m+1]; for (ptr = beg; ptr < end; ptr++) dj += A_val[ptr] * pi[A_ind[ptr]]; } return dj; } /*********************************************************************** * eval_bbar - compute and store primal values of basic variables * * This routine computes primal values of all basic variables and then * stores them in the solution array. */ static void eval_bbar(struct csa *csa) { eval_beta(csa, csa->bbar); return; } /*********************************************************************** * eval_cbar - compute and store reduced costs of non-basic variables * * This routine computes reduced costs of all non-basic variables and * then stores them in the solution array. */ static void eval_cbar(struct csa *csa) { #ifdef GLP_DEBUG int m = csa->m; #endif int n = csa->n; #ifdef GLP_DEBUG int *head = csa->head; #endif double *cbar = csa->cbar; double *pi = csa->work3; int j; #ifdef GLP_DEBUG int k; #endif /* compute simplex multipliers */ eval_pi(csa, pi); /* compute and store reduced costs */ for (j = 1; j <= n; j++) { #ifdef GLP_DEBUG k = head[m+j]; /* x[k] = xN[j] */ xassert(1 <= k && k <= m+n); #endif cbar[j] = eval_cost(csa, pi, j); } return; } /*********************************************************************** * reset_refsp - reset the reference space * * This routine resets (redefines) the reference space used in the * projected steepest edge pricing algorithm. */ static void reset_refsp(struct csa *csa) { int m = csa->m; int n = csa->n; int *head = csa->head; char *refsp = csa->refsp; double *gamma = csa->gamma; int j, k; xassert(csa->refct == 0); csa->refct = 1000; memset(&refsp[1], 0, (m+n) * sizeof(char)); for (j = 1; j <= n; j++) { k = head[m+j]; /* x[k] = xN[j] */ refsp[k] = 1; gamma[j] = 1.0; } return; } /*********************************************************************** * eval_gamma - compute steepest edge coefficient * * This routine computes the steepest edge coefficient for non-basic * variable xN[j] using its direct definition: * * gamma[j] = delta[j] + sum alfa[i,j]^2, * i in R * * where delta[j] = 1, if xN[j] is in the current reference space, * and 0 otherwise; R is a set of basic variables xB[i], which are in * the current reference space; alfa[i,j] are elements of the current * simplex table. * * NOTE: The routine is intended only for debugginig purposes. */ static double eval_gamma(struct csa *csa, int j) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif int *head = csa->head; char *refsp = csa->refsp; double *alfa = csa->work3; double *h = csa->work3; int i, k; double gamma; #ifdef GLP_DEBUG xassert(1 <= j && j <= n); #endif k = head[m+j]; /* x[k] = xN[j] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif /* construct the right-hand side vector h = - N[j] */ for (i = 1; i <= m; i++) h[i] = 0.0; if (k <= m) { /* N[j] is k-th column of submatrix I */ h[k] = -1.0; } else { /* N[j] is (k-m)-th column of submatrix (-A) */ int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; int beg, end, ptr; beg = A_ptr[k-m]; end = A_ptr[k-m+1]; for (ptr = beg; ptr < end; ptr++) h[A_ind[ptr]] = A_val[ptr]; } /* solve system B * alfa = h */ xassert(csa->valid); bfd_ftran(csa->bfd, alfa); /* compute gamma */ gamma = (refsp[k] ? 1.0 : 0.0); for (i = 1; i <= m; i++) { k = head[i]; #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif if (refsp[k]) gamma += alfa[i] * alfa[i]; } return gamma; } /*********************************************************************** * chuzc - choose non-basic variable (column of the simplex table) * * This routine chooses non-basic variable xN[q], which has largest * weighted reduced cost: * * |d[q]| / sqrt(gamma[q]) = max |d[j]| / sqrt(gamma[j]), * j in J * * where J is a subset of eligible non-basic variables xN[j], d[j] is * reduced cost of xN[j], gamma[j] is the steepest edge coefficient. * * The working objective function is always minimized, so the sign of * d[q] determines direction, in which xN[q] has to change: * * if d[q] < 0, xN[q] has to increase; * * if d[q] > 0, xN[q] has to decrease. * * If |d[j]| <= tol_dj, where tol_dj is a specified tolerance, xN[j] * is not included in J and therefore ignored. (It is assumed that the * working objective row is appropriately scaled, i.e. max|c[k]| = 1.) * * If J is empty and no variable has been chosen, q is set to 0. */ static void chuzc(struct csa *csa, double tol_dj) { int n = csa->n; char *stat = csa->stat; double *cbar = csa->cbar; double *gamma = csa->gamma; int j, q; double dj, best, temp; /* nothing is chosen so far */ q = 0, best = 0.0; /* look through the list of non-basic variables */ for (j = 1; j <= n; j++) { dj = cbar[j]; switch (stat[j]) { case GLP_NL: /* xN[j] can increase */ if (dj >= - tol_dj) continue; break; case GLP_NU: /* xN[j] can decrease */ if (dj <= + tol_dj) continue; break; case GLP_NF: /* xN[j] can change in any direction */ if (- tol_dj <= dj && dj <= + tol_dj) continue; break; case GLP_NS: /* xN[j] cannot change at all */ continue; default: xassert(stat != stat); } /* xN[j] is eligible non-basic variable; choose one which has largest weighted reduced cost */ #ifdef GLP_DEBUG xassert(gamma[j] > 0.0); #endif temp = (dj * dj) / gamma[j]; if (best < temp) q = j, best = temp; } /* store the index of non-basic variable xN[q] chosen */ csa->q = q; return; } /*********************************************************************** * eval_tcol - compute pivot column of the simplex table * * This routine computes the pivot column of the simplex table, which * corresponds to non-basic variable xN[q] chosen. * * The pivot column is the following vector: * * tcol = T * e[q] = - inv(B) * N * e[q] = - inv(B) * N[q], * * where B is the current basis matrix, N[q] is a column of the matrix * (I|-A) corresponding to variable xN[q]. */ static void eval_tcol(struct csa *csa) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif int *head = csa->head; int q = csa->q; int *tcol_ind = csa->tcol_ind; double *tcol_vec = csa->tcol_vec; double *h = csa->tcol_vec; int i, k, nnz; #ifdef GLP_DEBUG xassert(1 <= q && q <= n); #endif k = head[m+q]; /* x[k] = xN[q] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif /* construct the right-hand side vector h = - N[q] */ for (i = 1; i <= m; i++) h[i] = 0.0; if (k <= m) { /* N[q] is k-th column of submatrix I */ h[k] = -1.0; } else { /* N[q] is (k-m)-th column of submatrix (-A) */ int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; int beg, end, ptr; beg = A_ptr[k-m]; end = A_ptr[k-m+1]; for (ptr = beg; ptr < end; ptr++) h[A_ind[ptr]] = A_val[ptr]; } /* solve system B * tcol = h */ xassert(csa->valid); bfd_ftran(csa->bfd, tcol_vec); /* construct sparse pattern of the pivot column */ nnz = 0; for (i = 1; i <= m; i++) { if (tcol_vec[i] != 0.0) tcol_ind[++nnz] = i; } csa->tcol_nnz = nnz; return; } /*********************************************************************** * refine_tcol - refine pivot column of the simplex table * * This routine refines the pivot column of the simplex table assuming * that it was previously computed by the routine eval_tcol. */ static void refine_tcol(struct csa *csa) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif int *head = csa->head; int q = csa->q; int *tcol_ind = csa->tcol_ind; double *tcol_vec = csa->tcol_vec; double *h = csa->work3; int i, k, nnz; #ifdef GLP_DEBUG xassert(1 <= q && q <= n); #endif k = head[m+q]; /* x[k] = xN[q] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif /* construct the right-hand side vector h = - N[q] */ for (i = 1; i <= m; i++) h[i] = 0.0; if (k <= m) { /* N[q] is k-th column of submatrix I */ h[k] = -1.0; } else { /* N[q] is (k-m)-th column of submatrix (-A) */ int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; int beg, end, ptr; beg = A_ptr[k-m]; end = A_ptr[k-m+1]; for (ptr = beg; ptr < end; ptr++) h[A_ind[ptr]] = A_val[ptr]; } /* refine solution of B * tcol = h */ refine_ftran(csa, h, tcol_vec); /* construct sparse pattern of the pivot column */ nnz = 0; for (i = 1; i <= m; i++) { if (tcol_vec[i] != 0.0) tcol_ind[++nnz] = i; } csa->tcol_nnz = nnz; return; } /*********************************************************************** * sort_tcol - sort pivot column of the simplex table * * This routine reorders the list of non-zero elements of the pivot * column to put significant elements, whose magnitude is not less than * a specified tolerance, in front of the list, and stores the number * of significant elements in tcol_num. */ static void sort_tcol(struct csa *csa, double tol_piv) { #ifdef GLP_DEBUG int m = csa->m; #endif int nnz = csa->tcol_nnz; int *tcol_ind = csa->tcol_ind; double *tcol_vec = csa->tcol_vec; int i, num, pos; double big, eps, temp; /* compute infinity (maximum) norm of the column */ big = 0.0; for (pos = 1; pos <= nnz; pos++) { #ifdef GLP_DEBUG i = tcol_ind[pos]; xassert(1 <= i && i <= m); #endif temp = fabs(tcol_vec[tcol_ind[pos]]); if (big < temp) big = temp; } csa->tcol_max = big; /* determine absolute pivot tolerance */ eps = tol_piv * (1.0 + 0.01 * big); /* move significant column components to front of the list */ for (num = 0; num < nnz; ) { i = tcol_ind[nnz]; if (fabs(tcol_vec[i]) < eps) nnz--; else { num++; tcol_ind[nnz] = tcol_ind[num]; tcol_ind[num] = i; } } csa->tcol_num = num; return; } /*********************************************************************** * chuzr - choose basic variable (row of the simplex table) * * This routine chooses basic variable xB[p], which reaches its bound * first on changing non-basic variable xN[q] in valid direction. * * The parameter rtol is a relative tolerance used to relax bounds of * basic variables. If rtol = 0, the routine implements the standard * ratio test. Otherwise, if rtol > 0, the routine implements Harris' * two-pass ratio test. In the latter case rtol should be about three * times less than a tolerance used to check primal feasibility. */ static void chuzr(struct csa *csa, double rtol) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif char *type = csa->type; double *lb = csa->lb; double *ub = csa->ub; double *coef = csa->coef; int *head = csa->head; int phase = csa->phase; double *bbar = csa->bbar; double *cbar = csa->cbar; int q = csa->q; int *tcol_ind = csa->tcol_ind; double *tcol_vec = csa->tcol_vec; int tcol_num = csa->tcol_num; int i, i_stat, k, p, p_stat, pos; double alfa, big, delta, s, t, teta, tmax; #ifdef GLP_DEBUG xassert(1 <= q && q <= n); #endif /* s := - sign(d[q]), where d[q] is reduced cost of xN[q] */ #ifdef GLP_DEBUG xassert(cbar[q] != 0.0); #endif s = (cbar[q] > 0.0 ? -1.0 : +1.0); /*** FIRST PASS ***/ k = head[m+q]; /* x[k] = xN[q] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif if (type[k] == GLP_DB) { /* xN[q] has both lower and upper bounds */ p = -1, p_stat = 0, teta = ub[k] - lb[k], big = 1.0; } else { /* xN[q] has no opposite bound */ p = 0, p_stat = 0, teta = DBL_MAX, big = 0.0; } /* walk through significant elements of the pivot column */ for (pos = 1; pos <= tcol_num; pos++) { i = tcol_ind[pos]; #ifdef GLP_DEBUG xassert(1 <= i && i <= m); #endif k = head[i]; /* x[k] = xB[i] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif alfa = s * tcol_vec[i]; #ifdef GLP_DEBUG xassert(alfa != 0.0); #endif /* xB[i] = ... + alfa * xN[q] + ..., and due to s we need to consider the only case when xN[q] is increasing */ if (alfa > 0.0) { /* xB[i] is increasing */ if (phase == 1 && coef[k] < 0.0) { /* xB[i] violates its lower bound, which plays the role of an upper bound on phase I */ delta = rtol * (1.0 + kappa * fabs(lb[k])); t = ((lb[k] + delta) - bbar[i]) / alfa; i_stat = GLP_NL; } else if (phase == 1 && coef[k] > 0.0) { /* xB[i] violates its upper bound, which plays the role of an lower bound on phase I */ continue; } else if (type[k] == GLP_UP || type[k] == GLP_DB || type[k] == GLP_FX) { /* xB[i] is within its bounds and has an upper bound */ delta = rtol * (1.0 + kappa * fabs(ub[k])); t = ((ub[k] + delta) - bbar[i]) / alfa; i_stat = GLP_NU; } else { /* xB[i] is within its bounds and has no upper bound */ continue; } } else { /* xB[i] is decreasing */ if (phase == 1 && coef[k] > 0.0) { /* xB[i] violates its upper bound, which plays the role of an lower bound on phase I */ delta = rtol * (1.0 + kappa * fabs(ub[k])); t = ((ub[k] - delta) - bbar[i]) / alfa; i_stat = GLP_NU; } else if (phase == 1 && coef[k] < 0.0) { /* xB[i] violates its lower bound, which plays the role of an upper bound on phase I */ continue; } else if (type[k] == GLP_LO || type[k] == GLP_DB || type[k] == GLP_FX) { /* xB[i] is within its bounds and has an lower bound */ delta = rtol * (1.0 + kappa * fabs(lb[k])); t = ((lb[k] - delta) - bbar[i]) / alfa; i_stat = GLP_NL; } else { /* xB[i] is within its bounds and has no lower bound */ continue; } } /* t is a change of xN[q], on which xB[i] reaches its bound (possibly relaxed); since the basic solution is assumed to be primal feasible (or pseudo feasible on phase I), t has to be non-negative by definition; however, it may happen that xB[i] slightly (i.e. within a tolerance) violates its bound, that leads to negative t; in the latter case, if xB[i] is chosen, negative t means that xN[q] changes in wrong direction; if pivot alfa[i,q] is close to zero, even small bound violation of xB[i] may lead to a large change of xN[q] in wrong direction; let, for example, xB[i] >= 0 and in the current basis its value be -5e-9; let also xN[q] be on its zero bound and should increase; from the ratio test rule it follows that the pivot alfa[i,q] < 0; however, if alfa[i,q] is, say, -1e-9, the change of xN[q] in wrong direction is 5e-9 / (-1e-9) = -5, and using it for updating values of other basic variables will give absolutely wrong results; therefore, if t is negative, we should replace it by exact zero assuming that xB[i] is exactly on its bound, and the violation appears due to round-off errors */ if (t < 0.0) t = 0.0; /* apply minimal ratio test */ if (teta > t || teta == t && big < fabs(alfa)) p = i, p_stat = i_stat, teta = t, big = fabs(alfa); } /* the second pass is skipped in the following cases: */ /* if the standard ratio test is used */ if (rtol == 0.0) goto done; /* if xN[q] reaches its opposite bound or if no basic variable has been chosen on the first pass */ if (p <= 0) goto done; /* if xB[p] is a blocking variable, i.e. if it prevents xN[q] from any change */ if (teta == 0.0) goto done; /*** SECOND PASS ***/ /* here tmax is a maximal change of xN[q], on which the solution remains primal feasible (or pseudo feasible on phase I) within a tolerance */ #if 0 tmax = (1.0 + 10.0 * DBL_EPSILON) * teta; #else tmax = teta; #endif /* nothing is chosen so far */ p = 0, p_stat = 0, teta = DBL_MAX, big = 0.0; /* walk through significant elements of the pivot column */ for (pos = 1; pos <= tcol_num; pos++) { i = tcol_ind[pos]; #ifdef GLP_DEBUG xassert(1 <= i && i <= m); #endif k = head[i]; /* x[k] = xB[i] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif alfa = s * tcol_vec[i]; #ifdef GLP_DEBUG xassert(alfa != 0.0); #endif /* xB[i] = ... + alfa * xN[q] + ..., and due to s we need to consider the only case when xN[q] is increasing */ if (alfa > 0.0) { /* xB[i] is increasing */ if (phase == 1 && coef[k] < 0.0) { /* xB[i] violates its lower bound, which plays the role of an upper bound on phase I */ t = (lb[k] - bbar[i]) / alfa; i_stat = GLP_NL; } else if (phase == 1 && coef[k] > 0.0) { /* xB[i] violates its upper bound, which plays the role of an lower bound on phase I */ continue; } else if (type[k] == GLP_UP || type[k] == GLP_DB || type[k] == GLP_FX) { /* xB[i] is within its bounds and has an upper bound */ t = (ub[k] - bbar[i]) / alfa; i_stat = GLP_NU; } else { /* xB[i] is within its bounds and has no upper bound */ continue; } } else { /* xB[i] is decreasing */ if (phase == 1 && coef[k] > 0.0) { /* xB[i] violates its upper bound, which plays the role of an lower bound on phase I */ t = (ub[k] - bbar[i]) / alfa; i_stat = GLP_NU; } else if (phase == 1 && coef[k] < 0.0) { /* xB[i] violates its lower bound, which plays the role of an upper bound on phase I */ continue; } else if (type[k] == GLP_LO || type[k] == GLP_DB || type[k] == GLP_FX) { /* xB[i] is within its bounds and has an lower bound */ t = (lb[k] - bbar[i]) / alfa; i_stat = GLP_NL; } else { /* xB[i] is within its bounds and has no lower bound */ continue; } } /* (see comments for the first pass) */ if (t < 0.0) t = 0.0; /* t is a change of xN[q], on which xB[i] reaches its bound; if t <= tmax, all basic variables can violate their bounds only within relaxation tolerance delta; we can use this freedom and choose basic variable having largest influence coefficient to avoid possible numeric instability */ if (t <= tmax && big < fabs(alfa)) p = i, p_stat = i_stat, teta = t, big = fabs(alfa); } /* something must be chosen on the second pass */ xassert(p != 0); done: /* store the index and status of basic variable xB[p] chosen */ csa->p = p; if (p > 0 && type[head[p]] == GLP_FX) csa->p_stat = GLP_NS; else csa->p_stat = p_stat; /* store corresponding change of non-basic variable xN[q] */ #ifdef GLP_DEBUG xassert(teta >= 0.0); #endif csa->teta = s * teta; return; } /*********************************************************************** * eval_rho - compute pivot row of the inverse * * This routine computes the pivot (p-th) row of the inverse inv(B), * which corresponds to basic variable xB[p] chosen: * * rho = inv(B') * e[p], * * where B' is a matrix transposed to the current basis matrix, e[p] * is unity vector. */ static void eval_rho(struct csa *csa, double rho[]) { int m = csa->m; int p = csa->p; double *e = rho; int i; #ifdef GLP_DEBUG xassert(1 <= p && p <= m); #endif /* construct the right-hand side vector e[p] */ for (i = 1; i <= m; i++) e[i] = 0.0; e[p] = 1.0; /* solve system B'* rho = e[p] */ xassert(csa->valid); bfd_btran(csa->bfd, rho); return; } /*********************************************************************** * refine_rho - refine pivot row of the inverse * * This routine refines the pivot row of the inverse inv(B) assuming * that it was previously computed by the routine eval_rho. */ static void refine_rho(struct csa *csa, double rho[]) { int m = csa->m; int p = csa->p; double *e = csa->work3; int i; #ifdef GLP_DEBUG xassert(1 <= p && p <= m); #endif /* construct the right-hand side vector e[p] */ for (i = 1; i <= m; i++) e[i] = 0.0; e[p] = 1.0; /* refine solution of B'* rho = e[p] */ refine_btran(csa, e, rho); return; } /*********************************************************************** * eval_trow - compute pivot row of the simplex table * * This routine computes the pivot row of the simplex table, which * corresponds to basic variable xB[p] chosen. * * The pivot row is the following vector: * * trow = T'* e[p] = - N'* inv(B') * e[p] = - N' * rho, * * where rho is the pivot row of the inverse inv(B) previously computed * by the routine eval_rho. * * Note that elements of the pivot row corresponding to fixed non-basic * variables are not computed. */ static void eval_trow(struct csa *csa, double rho[]) { int m = csa->m; int n = csa->n; #ifdef GLP_DEBUG char *stat = csa->stat; #endif int *N_ptr = csa->N_ptr; int *N_len = csa->N_len; int *N_ind = csa->N_ind; double *N_val = csa->N_val; int *trow_ind = csa->trow_ind; double *trow_vec = csa->trow_vec; int i, j, beg, end, ptr, nnz; double temp; /* clear the pivot row */ for (j = 1; j <= n; j++) trow_vec[j] = 0.0; /* compute the pivot row as a linear combination of rows of the matrix N: trow = - rho[1] * N'[1] - ... - rho[m] * N'[m] */ for (i = 1; i <= m; i++) { temp = rho[i]; if (temp == 0.0) continue; /* trow := trow - rho[i] * N'[i] */ beg = N_ptr[i]; end = beg + N_len[i]; for (ptr = beg; ptr < end; ptr++) { #ifdef GLP_DEBUG j = N_ind[ptr]; xassert(1 <= j && j <= n); xassert(stat[j] != GLP_NS); #endif trow_vec[N_ind[ptr]] -= temp * N_val[ptr]; } } /* construct sparse pattern of the pivot row */ nnz = 0; for (j = 1; j <= n; j++) { if (trow_vec[j] != 0.0) trow_ind[++nnz] = j; } csa->trow_nnz = nnz; return; } /*********************************************************************** * update_bbar - update values of basic variables * * This routine updates values of all basic variables for the adjacent * basis. */ static void update_bbar(struct csa *csa) { #ifdef GLP_DEBUG int m = csa->m; int n = csa->n; #endif double *bbar = csa->bbar; int q = csa->q; int tcol_nnz = csa->tcol_nnz; int *tcol_ind = csa->tcol_ind; double *tcol_vec = csa->tcol_vec; int p = csa->p; double teta = csa->teta; int i, pos; #ifdef GLP_DEBUG xassert(1 <= q && q <= n); xassert(p < 0 || 1 <= p && p <= m); #endif /* if xN[q] leaves the basis, compute its value in the adjacent basis, where it will replace xB[p] */ if (p > 0) bbar[p] = get_xN(csa, q) + teta; /* update values of other basic variables (except xB[p], because it will be replaced by xN[q]) */ if (teta == 0.0) goto done; for (pos = 1; pos <= tcol_nnz; pos++) { i = tcol_ind[pos]; /* skip xB[p] */ if (i == p) continue; /* (change of xB[i]) = alfa[i,q] * (change of xN[q]) */ bbar[i] += tcol_vec[i] * teta; } done: return; } /*********************************************************************** * reeval_cost - recompute reduced cost of non-basic variable xN[q] * * This routine recomputes reduced cost of non-basic variable xN[q] for * the current basis more accurately using its direct definition: * * d[q] = cN[q] - N'[q] * pi = * * = cN[q] - N'[q] * (inv(B') * cB) = * * = cN[q] - (cB' * inv(B) * N[q]) = * * = cN[q] + cB' * (pivot column). * * It is assumed that the pivot column of the simplex table is already * computed. */ static double reeval_cost(struct csa *csa) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif double *coef = csa->coef; int *head = csa->head; int q = csa->q; int tcol_nnz = csa->tcol_nnz; int *tcol_ind = csa->tcol_ind; double *tcol_vec = csa->tcol_vec; int i, pos; double dq; #ifdef GLP_DEBUG xassert(1 <= q && q <= n); #endif dq = coef[head[m+q]]; for (pos = 1; pos <= tcol_nnz; pos++) { i = tcol_ind[pos]; #ifdef GLP_DEBUG xassert(1 <= i && i <= m); #endif dq += coef[head[i]] * tcol_vec[i]; } return dq; } /*********************************************************************** * update_cbar - update reduced costs of non-basic variables * * This routine updates reduced costs of all (except fixed) non-basic * variables for the adjacent basis. */ static void update_cbar(struct csa *csa) { #ifdef GLP_DEBUG int n = csa->n; #endif double *cbar = csa->cbar; int q = csa->q; int trow_nnz = csa->trow_nnz; int *trow_ind = csa->trow_ind; double *trow_vec = csa->trow_vec; int j, pos; double new_dq; #ifdef GLP_DEBUG xassert(1 <= q && q <= n); #endif /* compute reduced cost of xB[p] in the adjacent basis, where it will replace xN[q] */ #ifdef GLP_DEBUG xassert(trow_vec[q] != 0.0); #endif new_dq = (cbar[q] /= trow_vec[q]); /* update reduced costs of other non-basic variables (except xN[q], because it will be replaced by xB[p]) */ for (pos = 1; pos <= trow_nnz; pos++) { j = trow_ind[pos]; /* skip xN[q] */ if (j == q) continue; cbar[j] -= trow_vec[j] * new_dq; } return; } /*********************************************************************** * update_gamma - update steepest edge coefficients * * This routine updates steepest-edge coefficients for the adjacent * basis. */ static void update_gamma(struct csa *csa) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif char *type = csa->type; int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; int *head = csa->head; char *refsp = csa->refsp; double *gamma = csa->gamma; int q = csa->q; int tcol_nnz = csa->tcol_nnz; int *tcol_ind = csa->tcol_ind; double *tcol_vec = csa->tcol_vec; int p = csa->p; int trow_nnz = csa->trow_nnz; int *trow_ind = csa->trow_ind; double *trow_vec = csa->trow_vec; double *u = csa->work3; int i, j, k, pos, beg, end, ptr; double gamma_q, delta_q, pivot, s, t, t1, t2; #ifdef GLP_DEBUG xassert(1 <= p && p <= m); xassert(1 <= q && q <= n); #endif /* the basis changes, so decrease the count */ xassert(csa->refct > 0); csa->refct--; /* recompute gamma[q] for the current basis more accurately and compute auxiliary vector u */ gamma_q = delta_q = (refsp[head[m+q]] ? 1.0 : 0.0); for (i = 1; i <= m; i++) u[i] = 0.0; for (pos = 1; pos <= tcol_nnz; pos++) { i = tcol_ind[pos]; if (refsp[head[i]]) { u[i] = t = tcol_vec[i]; gamma_q += t * t; } else u[i] = 0.0; } xassert(csa->valid); bfd_btran(csa->bfd, u); /* update gamma[k] for other non-basic variables (except fixed variables and xN[q], because it will be replaced by xB[p]) */ pivot = trow_vec[q]; #ifdef GLP_DEBUG xassert(pivot != 0.0); #endif for (pos = 1; pos <= trow_nnz; pos++) { j = trow_ind[pos]; /* skip xN[q] */ if (j == q) continue; /* compute t */ t = trow_vec[j] / pivot; /* compute inner product s = N'[j] * u */ k = head[m+j]; /* x[k] = xN[j] */ if (k <= m) s = u[k]; else { s = 0.0; beg = A_ptr[k-m]; end = A_ptr[k-m+1]; for (ptr = beg; ptr < end; ptr++) s -= A_val[ptr] * u[A_ind[ptr]]; } /* compute gamma[k] for the adjacent basis */ t1 = gamma[j] + t * t * gamma_q + 2.0 * t * s; t2 = (refsp[k] ? 1.0 : 0.0) + delta_q * t * t; gamma[j] = (t1 >= t2 ? t1 : t2); if (gamma[j] < DBL_EPSILON) gamma[j] = DBL_EPSILON; } /* compute gamma[q] for the adjacent basis */ if (type[head[p]] == GLP_FX) gamma[q] = 1.0; else { gamma[q] = gamma_q / (pivot * pivot); if (gamma[q] < DBL_EPSILON) gamma[q] = DBL_EPSILON; } return; } /*********************************************************************** * err_in_bbar - compute maximal relative error in primal solution * * This routine returns maximal relative error: * * max |beta[i] - bbar[i]| / (1 + |beta[i]|), * * where beta and bbar are, respectively, directly computed and the * current (updated) values of basic variables. * * NOTE: The routine is intended only for debugginig purposes. */ static double err_in_bbar(struct csa *csa) { int m = csa->m; double *bbar = csa->bbar; int i; double e, emax, *beta; beta = xcalloc(1+m, sizeof(double)); eval_beta(csa, beta); emax = 0.0; for (i = 1; i <= m; i++) { e = fabs(beta[i] - bbar[i]) / (1.0 + fabs(beta[i])); if (emax < e) emax = e; } xfree(beta); return emax; } /*********************************************************************** * err_in_cbar - compute maximal relative error in dual solution * * This routine returns maximal relative error: * * max |cost[j] - cbar[j]| / (1 + |cost[j]|), * * where cost and cbar are, respectively, directly computed and the * current (updated) reduced costs of non-basic non-fixed variables. * * NOTE: The routine is intended only for debugginig purposes. */ static double err_in_cbar(struct csa *csa) { int m = csa->m; int n = csa->n; char *stat = csa->stat; double *cbar = csa->cbar; int j; double e, emax, cost, *pi; pi = xcalloc(1+m, sizeof(double)); eval_pi(csa, pi); emax = 0.0; for (j = 1; j <= n; j++) { if (stat[j] == GLP_NS) continue; cost = eval_cost(csa, pi, j); e = fabs(cost - cbar[j]) / (1.0 + fabs(cost)); if (emax < e) emax = e; } xfree(pi); return emax; } /*********************************************************************** * err_in_gamma - compute maximal relative error in steepest edge cff. * * This routine returns maximal relative error: * * max |gamma'[j] - gamma[j]| / (1 + |gamma'[j]), * * where gamma'[j] and gamma[j] are, respectively, directly computed * and the current (updated) steepest edge coefficients for non-basic * non-fixed variable x[j]. * * NOTE: The routine is intended only for debugginig purposes. */ static double err_in_gamma(struct csa *csa) { int n = csa->n; char *stat = csa->stat; double *gamma = csa->gamma; int j; double e, emax, temp; emax = 0.0; for (j = 1; j <= n; j++) { if (stat[j] == GLP_NS) { xassert(gamma[j] == 1.0); continue; } temp = eval_gamma(csa, j); e = fabs(temp - gamma[j]) / (1.0 + fabs(temp)); if (emax < e) emax = e; } return emax; } /*********************************************************************** * change_basis - change basis header * * This routine changes the basis header to make it corresponding to * the adjacent basis. */ static void change_basis(struct csa *csa) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; char *type = csa->type; #endif int *head = csa->head; char *stat = csa->stat; int q = csa->q; int p = csa->p; int p_stat = csa->p_stat; int k; #ifdef GLP_DEBUG xassert(1 <= q && q <= n); #endif if (p < 0) { /* xN[q] goes to its opposite bound */ #ifdef GLP_DEBUG k = head[m+q]; /* x[k] = xN[q] */ xassert(1 <= k && k <= m+n); xassert(type[k] == GLP_DB); #endif switch (stat[q]) { case GLP_NL: /* xN[q] increases */ stat[q] = GLP_NU; break; case GLP_NU: /* xN[q] decreases */ stat[q] = GLP_NL; break; default: xassert(stat != stat); } } else { /* xB[p] leaves the basis, xN[q] enters the basis */ #ifdef GLP_DEBUG xassert(1 <= p && p <= m); k = head[p]; /* x[k] = xB[p] */ switch (p_stat) { case GLP_NL: /* xB[p] goes to its lower bound */ xassert(type[k] == GLP_LO || type[k] == GLP_DB); break; case GLP_NU: /* xB[p] goes to its upper bound */ xassert(type[k] == GLP_UP || type[k] == GLP_DB); break; case GLP_NS: /* xB[p] goes to its fixed value */ xassert(type[k] == GLP_NS); break; default: xassert(p_stat != p_stat); } #endif /* xB[p] <-> xN[q] */ k = head[p], head[p] = head[m+q], head[m+q] = k; stat[q] = (char)p_stat; } return; } /*********************************************************************** * set_aux_obj - construct auxiliary objective function * * The auxiliary objective function is a separable piecewise linear * convex function, which is the sum of primal infeasibilities: * * z = t[1] + ... + t[m+n] -> minimize, * * where: * * / lb[k] - x[k], if x[k] < lb[k] * | * t[k] = < 0, if lb[k] <= x[k] <= ub[k] * | * \ x[k] - ub[k], if x[k] > ub[k] * * This routine computes objective coefficients for the current basis * and returns the number of non-zero terms t[k]. */ static int set_aux_obj(struct csa *csa, double tol_bnd) { int m = csa->m; int n = csa->n; char *type = csa->type; double *lb = csa->lb; double *ub = csa->ub; double *coef = csa->coef; int *head = csa->head; double *bbar = csa->bbar; int i, k, cnt = 0; double eps; /* use a bit more restrictive tolerance */ tol_bnd *= 0.90; /* clear all objective coefficients */ for (k = 1; k <= m+n; k++) coef[k] = 0.0; /* walk through the list of basic variables */ for (i = 1; i <= m; i++) { k = head[i]; /* x[k] = xB[i] */ if (type[k] == GLP_LO || type[k] == GLP_DB || type[k] == GLP_FX) { /* x[k] has lower bound */ eps = tol_bnd * (1.0 + kappa * fabs(lb[k])); if (bbar[i] < lb[k] - eps) { /* and violates it */ coef[k] = -1.0; cnt++; } } if (type[k] == GLP_UP || type[k] == GLP_DB || type[k] == GLP_FX) { /* x[k] has upper bound */ eps = tol_bnd * (1.0 + kappa * fabs(ub[k])); if (bbar[i] > ub[k] + eps) { /* and violates it */ coef[k] = +1.0; cnt++; } } } return cnt; } /*********************************************************************** * set_orig_obj - restore original objective function * * This routine assigns scaled original objective coefficients to the * working objective function. */ static void set_orig_obj(struct csa *csa) { int m = csa->m; int n = csa->n; double *coef = csa->coef; double *obj = csa->obj; double zeta = csa->zeta; int i, j; for (i = 1; i <= m; i++) coef[i] = 0.0; for (j = 1; j <= n; j++) coef[m+j] = zeta * obj[j]; return; } /*********************************************************************** * check_stab - check numerical stability of basic solution * * If the current basic solution is primal feasible (or pseudo feasible * on phase I) within a tolerance, this routine returns zero, otherwise * it returns non-zero. */ static int check_stab(struct csa *csa, double tol_bnd) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif char *type = csa->type; double *lb = csa->lb; double *ub = csa->ub; double *coef = csa->coef; int *head = csa->head; int phase = csa->phase; double *bbar = csa->bbar; int i, k; double eps; /* walk through the list of basic variables */ for (i = 1; i <= m; i++) { k = head[i]; /* x[k] = xB[i] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif if (phase == 1 && coef[k] < 0.0) { /* x[k] must not be greater than its lower bound */ #ifdef GLP_DEBUG xassert(type[k] == GLP_LO || type[k] == GLP_DB || type[k] == GLP_FX); #endif eps = tol_bnd * (1.0 + kappa * fabs(lb[k])); if (bbar[i] > lb[k] + eps) return 1; } else if (phase == 1 && coef[k] > 0.0) { /* x[k] must not be less than its upper bound */ #ifdef GLP_DEBUG xassert(type[k] == GLP_UP || type[k] == GLP_DB || type[k] == GLP_FX); #endif eps = tol_bnd * (1.0 + kappa * fabs(ub[k])); if (bbar[i] < ub[k] - eps) return 1; } else { /* either phase = 1 and coef[k] = 0, or phase = 2 */ if (type[k] == GLP_LO || type[k] == GLP_DB || type[k] == GLP_FX) { /* x[k] must not be less than its lower bound */ eps = tol_bnd * (1.0 + kappa * fabs(lb[k])); if (bbar[i] < lb[k] - eps) return 1; } if (type[k] == GLP_UP || type[k] == GLP_DB || type[k] == GLP_FX) { /* x[k] must not be greater then its upper bound */ eps = tol_bnd * (1.0 + kappa * fabs(ub[k])); if (bbar[i] > ub[k] + eps) return 1; } } } /* basic solution is primal feasible within a tolerance */ return 0; } /*********************************************************************** * check_feas - check primal feasibility of basic solution * * If the current basic solution is primal feasible within a tolerance, * this routine returns zero, otherwise it returns non-zero. */ static int check_feas(struct csa *csa, double tol_bnd) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; char *type = csa->type; #endif double *lb = csa->lb; double *ub = csa->ub; double *coef = csa->coef; int *head = csa->head; double *bbar = csa->bbar; int i, k; double eps; xassert(csa->phase == 1); /* walk through the list of basic variables */ for (i = 1; i <= m; i++) { k = head[i]; /* x[k] = xB[i] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif if (coef[k] < 0.0) { /* check if x[k] still violates its lower bound */ #ifdef GLP_DEBUG xassert(type[k] == GLP_LO || type[k] == GLP_DB || type[k] == GLP_FX); #endif eps = tol_bnd * (1.0 + kappa * fabs(lb[k])); if (bbar[i] < lb[k] - eps) return 1; } else if (coef[k] > 0.0) { /* check if x[k] still violates its upper bound */ #ifdef GLP_DEBUG xassert(type[k] == GLP_UP || type[k] == GLP_DB || type[k] == GLP_FX); #endif eps = tol_bnd * (1.0 + kappa * fabs(ub[k])); if (bbar[i] > ub[k] + eps) return 1; } } /* basic solution is primal feasible within a tolerance */ return 0; } /*********************************************************************** * eval_obj - compute original objective function * * This routine computes the current value of the original objective * function. */ static double eval_obj(struct csa *csa) { int m = csa->m; int n = csa->n; double *obj = csa->obj; int *head = csa->head; double *bbar = csa->bbar; int i, j, k; double sum; sum = obj[0]; /* walk through the list of basic variables */ for (i = 1; i <= m; i++) { k = head[i]; /* x[k] = xB[i] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif if (k > m) sum += obj[k-m] * bbar[i]; } /* walk through the list of non-basic variables */ for (j = 1; j <= n; j++) { k = head[m+j]; /* x[k] = xN[j] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif if (k > m) sum += obj[k-m] * get_xN(csa, j); } return sum; } /*********************************************************************** * display - display the search progress * * This routine displays some information about the search progress * that includes: * * the search phase; * * the number of simplex iterations performed by the solver; * * the original objective value; * * the sum of (scaled) primal infeasibilities; * * the number of basic fixed variables. */ static void display(struct csa *csa, const glp_smcp *parm, int spec) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif char *type = csa->type; double *lb = csa->lb; double *ub = csa->ub; int phase = csa->phase; int *head = csa->head; double *bbar = csa->bbar; int i, k, cnt; double sum; if (parm->msg_lev < GLP_MSG_ON) goto skip; if (parm->out_dly > 0 && 1000.0 * xdifftime(xtime(), csa->tm_beg) < parm->out_dly) goto skip; if (csa->it_cnt == csa->it_dpy) goto skip; if (!spec && csa->it_cnt % parm->out_frq != 0) goto skip; /* compute the sum of primal infeasibilities and determine the number of basic fixed variables */ sum = 0.0, cnt = 0; for (i = 1; i <= m; i++) { k = head[i]; /* x[k] = xB[i] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif if (type[k] == GLP_LO || type[k] == GLP_DB || type[k] == GLP_FX) { /* x[k] has lower bound */ if (bbar[i] < lb[k]) sum += (lb[k] - bbar[i]); } if (type[k] == GLP_UP || type[k] == GLP_DB || type[k] == GLP_FX) { /* x[k] has upper bound */ if (bbar[i] > ub[k]) sum += (bbar[i] - ub[k]); } if (type[k] == GLP_FX) cnt++; } xprintf("%c%6d: obj = %17.9e infeas = %10.3e (%d)\n", phase == 1 ? ' ' : '*', csa->it_cnt, eval_obj(csa), sum, cnt); csa->it_dpy = csa->it_cnt; skip: return; } /*********************************************************************** * store_sol - store basic solution back to the problem object * * This routine stores basic solution components back to the problem * object. */ static void store_sol(struct csa *csa, glp_prob *lp, int p_stat, int d_stat, int ray) { int m = csa->m; int n = csa->n; double zeta = csa->zeta; int *head = csa->head; char *stat = csa->stat; double *bbar = csa->bbar; double *cbar = csa->cbar; int i, j, k; #ifdef GLP_DEBUG xassert(lp->m == m); xassert(lp->n == n); #endif /* basis factorization */ #ifdef GLP_DEBUG xassert(!lp->valid && lp->bfd == NULL); xassert(csa->valid && csa->bfd != NULL); #endif lp->valid = 1, csa->valid = 0; lp->bfd = csa->bfd, csa->bfd = NULL; memcpy(&lp->head[1], &head[1], m * sizeof(int)); /* basic solution status */ lp->pbs_stat = p_stat; lp->dbs_stat = d_stat; /* objective function value */ lp->obj_val = eval_obj(csa); /* simplex iteration count */ lp->it_cnt = csa->it_cnt; /* unbounded ray */ lp->some = ray; /* basic variables */ for (i = 1; i <= m; i++) { k = head[i]; /* x[k] = xB[i] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif if (k <= m) { GLPROW *row = lp->row[k]; row->stat = GLP_BS; row->bind = i; row->prim = bbar[i] / row->rii; row->dual = 0.0; } else { GLPCOL *col = lp->col[k-m]; col->stat = GLP_BS; col->bind = i; col->prim = bbar[i] * col->sjj; col->dual = 0.0; } } /* non-basic variables */ for (j = 1; j <= n; j++) { k = head[m+j]; /* x[k] = xN[j] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif if (k <= m) { GLPROW *row = lp->row[k]; row->stat = stat[j]; row->bind = 0; #if 0 row->prim = get_xN(csa, j) / row->rii; #else switch (stat[j]) { case GLP_NL: row->prim = row->lb; break; case GLP_NU: row->prim = row->ub; break; case GLP_NF: row->prim = 0.0; break; case GLP_NS: row->prim = row->lb; break; default: xassert(stat != stat); } #endif row->dual = (cbar[j] * row->rii) / zeta; } else { GLPCOL *col = lp->col[k-m]; col->stat = stat[j]; col->bind = 0; #if 0 col->prim = get_xN(csa, j) * col->sjj; #else switch (stat[j]) { case GLP_NL: col->prim = col->lb; break; case GLP_NU: col->prim = col->ub; break; case GLP_NF: col->prim = 0.0; break; case GLP_NS: col->prim = col->lb; break; default: xassert(stat != stat); } #endif col->dual = (cbar[j] / col->sjj) / zeta; } } return; } /*********************************************************************** * free_csa - deallocate common storage area * * This routine frees all the memory allocated to arrays in the common * storage area (CSA). */ static void free_csa(struct csa *csa) { xfree(csa->type); xfree(csa->lb); xfree(csa->ub); xfree(csa->coef); xfree(csa->obj); xfree(csa->A_ptr); xfree(csa->A_ind); xfree(csa->A_val); xfree(csa->head); xfree(csa->stat); xfree(csa->N_ptr); xfree(csa->N_len); xfree(csa->N_ind); xfree(csa->N_val); xfree(csa->bbar); xfree(csa->cbar); xfree(csa->refsp); xfree(csa->gamma); xfree(csa->tcol_ind); xfree(csa->tcol_vec); xfree(csa->trow_ind); xfree(csa->trow_vec); xfree(csa->work1); xfree(csa->work2); xfree(csa->work3); xfree(csa->work4); xfree(csa); return; } /*********************************************************************** * spx_primal - core LP solver based on the primal simplex method * * SYNOPSIS * * #include "glpspx.h" * int spx_primal(glp_prob *lp, const glp_smcp *parm); * * DESCRIPTION * * The routine spx_primal is a core LP solver based on the two-phase * primal simplex method. * * RETURNS * * 0 LP instance has been successfully solved. * * GLP_EITLIM * Iteration limit has been exhausted. * * GLP_ETMLIM * Time limit has been exhausted. * * GLP_EFAIL * The solver failed to solve LP instance. */ int spx_primal(glp_prob *lp, const glp_smcp *parm) { struct csa *csa; int binv_st = 2; /* status of basis matrix factorization: 0 - invalid; 1 - just computed; 2 - updated */ int bbar_st = 0; /* status of primal values of basic variables: 0 - invalid; 1 - just computed; 2 - updated */ int cbar_st = 0; /* status of reduced costs of non-basic variables: 0 - invalid; 1 - just computed; 2 - updated */ int rigorous = 0; /* rigorous mode flag; this flag is used to enable iterative refinement on computing pivot rows and columns of the simplex table */ int check = 0; int p_stat, d_stat, ret; /* allocate and initialize the common storage area */ csa = alloc_csa(lp); init_csa(csa, lp); if (parm->msg_lev >= GLP_MSG_DBG) xprintf("Objective scale factor = %g\n", csa->zeta); loop: /* main loop starts here */ /* compute factorization of the basis matrix */ if (binv_st == 0) { ret = invert_B(csa); if (ret != 0) { if (parm->msg_lev >= GLP_MSG_ERR) { xprintf("Error: unable to factorize the basis matrix (%d" ")\n", ret); xprintf("Sorry, basis recovery procedure not implemented" " yet\n"); } xassert(!lp->valid && lp->bfd == NULL); lp->bfd = csa->bfd, csa->bfd = NULL; lp->pbs_stat = lp->dbs_stat = GLP_UNDEF; lp->obj_val = 0.0; lp->it_cnt = csa->it_cnt; lp->some = 0; ret = GLP_EFAIL; goto done; } csa->valid = 1; binv_st = 1; /* just computed */ /* invalidate basic solution components */ bbar_st = cbar_st = 0; } /* compute primal values of basic variables */ if (bbar_st == 0) { eval_bbar(csa); bbar_st = 1; /* just computed */ /* determine the search phase, if not determined yet */ if (csa->phase == 0) { if (set_aux_obj(csa, parm->tol_bnd) > 0) { /* current basic solution is primal infeasible */ /* start to minimize the sum of infeasibilities */ csa->phase = 1; } else { /* current basic solution is primal feasible */ /* start to minimize the original objective function */ set_orig_obj(csa); csa->phase = 2; } xassert(check_stab(csa, parm->tol_bnd) == 0); /* working objective coefficients have been changed, so invalidate reduced costs */ cbar_st = 0; display(csa, parm, 1); } /* make sure that the current basic solution remains primal feasible (or pseudo feasible on phase I) */ if (check_stab(csa, parm->tol_bnd)) { /* there are excessive bound violations due to round-off errors */ if (parm->msg_lev >= GLP_MSG_ERR) xprintf("Warning: numerical instability (primal simplex," " phase %s)\n", csa->phase == 1 ? "I" : "II"); /* restart the search */ csa->phase = 0; binv_st = 0; rigorous = 5; goto loop; } } xassert(csa->phase == 1 || csa->phase == 2); /* on phase I we do not need to wait until the current basic solution becomes dual feasible; it is sufficient to make sure that no basic variable violates its bounds */ if (csa->phase == 1 && !check_feas(csa, parm->tol_bnd)) { /* the current basis is primal feasible; switch to phase II */ csa->phase = 2; set_orig_obj(csa); cbar_st = 0; display(csa, parm, 1); } /* compute reduced costs of non-basic variables */ if (cbar_st == 0) { eval_cbar(csa); cbar_st = 1; /* just computed */ } /* redefine the reference space, if required */ switch (parm->pricing) { case GLP_PT_STD: break; case GLP_PT_PSE: if (csa->refct == 0) reset_refsp(csa); break; default: xassert(parm != parm); } /* at this point the basis factorization and all basic solution components are valid */ xassert(binv_st && bbar_st && cbar_st); /* check accuracy of current basic solution components (only for debugging) */ if (check) { double e_bbar = err_in_bbar(csa); double e_cbar = err_in_cbar(csa); double e_gamma = (parm->pricing == GLP_PT_PSE ? err_in_gamma(csa) : 0.0); xprintf("e_bbar = %10.3e; e_cbar = %10.3e; e_gamma = %10.3e\n", e_bbar, e_cbar, e_gamma); xassert(e_bbar <= 1e-5 && e_cbar <= 1e-5 && e_gamma <= 1e-3); } /* check if the iteration limit has been exhausted */ if (parm->it_lim < INT_MAX && csa->it_cnt - csa->it_beg >= parm->it_lim) { if (bbar_st != 1 || csa->phase == 2 && cbar_st != 1) { if (bbar_st != 1) bbar_st = 0; if (csa->phase == 2 && cbar_st != 1) cbar_st = 0; goto loop; } display(csa, parm, 1); if (parm->msg_lev >= GLP_MSG_ALL) xprintf("ITERATION LIMIT EXCEEDED; SEARCH TERMINATED\n"); switch (csa->phase) { case 1: p_stat = GLP_INFEAS; set_orig_obj(csa); eval_cbar(csa); break; case 2: p_stat = GLP_FEAS; break; default: xassert(csa != csa); } chuzc(csa, parm->tol_dj); d_stat = (csa->q == 0 ? GLP_FEAS : GLP_INFEAS); store_sol(csa, lp, p_stat, d_stat, 0); ret = GLP_EITLIM; goto done; } /* check if the time limit has been exhausted */ if (parm->tm_lim < INT_MAX && 1000.0 * xdifftime(xtime(), csa->tm_beg) >= parm->tm_lim) { if (bbar_st != 1 || csa->phase == 2 && cbar_st != 1) { if (bbar_st != 1) bbar_st = 0; if (csa->phase == 2 && cbar_st != 1) cbar_st = 0; goto loop; } display(csa, parm, 1); if (parm->msg_lev >= GLP_MSG_ALL) xprintf("TIME LIMIT EXCEEDED; SEARCH TERMINATED\n"); switch (csa->phase) { case 1: p_stat = GLP_INFEAS; set_orig_obj(csa); eval_cbar(csa); break; case 2: p_stat = GLP_FEAS; break; default: xassert(csa != csa); } chuzc(csa, parm->tol_dj); d_stat = (csa->q == 0 ? GLP_FEAS : GLP_INFEAS); store_sol(csa, lp, p_stat, d_stat, 0); ret = GLP_ETMLIM; goto done; } /* display the search progress */ display(csa, parm, 0); /* choose non-basic variable xN[q] */ chuzc(csa, parm->tol_dj); if (csa->q == 0) { if (bbar_st != 1 || cbar_st != 1) { if (bbar_st != 1) bbar_st = 0; if (cbar_st != 1) cbar_st = 0; goto loop; } display(csa, parm, 1); switch (csa->phase) { case 1: if (parm->msg_lev >= GLP_MSG_ALL) xprintf("PROBLEM HAS NO FEASIBLE SOLUTION\n"); p_stat = GLP_NOFEAS; set_orig_obj(csa); eval_cbar(csa); chuzc(csa, parm->tol_dj); d_stat = (csa->q == 0 ? GLP_FEAS : GLP_INFEAS); break; case 2: if (parm->msg_lev >= GLP_MSG_ALL) xprintf("OPTIMAL SOLUTION FOUND\n"); p_stat = d_stat = GLP_FEAS; break; default: xassert(csa != csa); } store_sol(csa, lp, p_stat, d_stat, 0); ret = 0; goto done; } /* compute pivot column of the simplex table */ eval_tcol(csa); if (rigorous) refine_tcol(csa); sort_tcol(csa, parm->tol_piv); /* check accuracy of the reduced cost of xN[q] */ { double d1 = csa->cbar[csa->q]; /* less accurate */ double d2 = reeval_cost(csa); /* more accurate */ xassert(d1 != 0.0); if (fabs(d1 - d2) > 1e-5 * (1.0 + fabs(d2)) || !(d1 < 0.0 && d2 < 0.0 || d1 > 0.0 && d2 > 0.0)) { if (parm->msg_lev >= GLP_MSG_DBG) xprintf("d1 = %.12g; d2 = %.12g\n", d1, d2); if (cbar_st != 1 || !rigorous) { if (cbar_st != 1) cbar_st = 0; rigorous = 5; goto loop; } } /* replace cbar[q] by more accurate value keeping its sign */ if (d1 > 0.0) csa->cbar[csa->q] = (d2 > 0.0 ? d2 : +DBL_EPSILON); else csa->cbar[csa->q] = (d2 < 0.0 ? d2 : -DBL_EPSILON); } /* choose basic variable xB[p] */ switch (parm->r_test) { case GLP_RT_STD: chuzr(csa, 0.0); break; case GLP_RT_HAR: chuzr(csa, 0.30 * parm->tol_bnd); break; default: xassert(parm != parm); } if (csa->p == 0) { if (bbar_st != 1 || cbar_st != 1 || !rigorous) { if (bbar_st != 1) bbar_st = 0; if (cbar_st != 1) cbar_st = 0; rigorous = 1; goto loop; } display(csa, parm, 1); switch (csa->phase) { case 1: if (parm->msg_lev >= GLP_MSG_ERR) xprintf("Error: unable to choose basic variable on ph" "ase I\n"); xassert(!lp->valid && lp->bfd == NULL); lp->bfd = csa->bfd, csa->bfd = NULL; lp->pbs_stat = lp->dbs_stat = GLP_UNDEF; lp->obj_val = 0.0; lp->it_cnt = csa->it_cnt; lp->some = 0; ret = GLP_EFAIL; break; case 2: if (parm->msg_lev >= GLP_MSG_ALL) xprintf("PROBLEM HAS UNBOUNDED SOLUTION\n"); store_sol(csa, lp, GLP_FEAS, GLP_NOFEAS, csa->head[csa->m+csa->q]); ret = 0; break; default: xassert(csa != csa); } goto done; } /* check if the pivot element is acceptable */ if (csa->p > 0) { double piv = csa->tcol_vec[csa->p]; double eps = 1e-5 * (1.0 + 0.01 * csa->tcol_max); if (fabs(piv) < eps) { if (parm->msg_lev >= GLP_MSG_DBG) xprintf("piv = %.12g; eps = %g\n", piv, eps); if (!rigorous) { rigorous = 5; goto loop; } } } /* now xN[q] and xB[p] have been chosen anyhow */ /* compute pivot row of the simplex table */ if (csa->p > 0) { double *rho = csa->work4; eval_rho(csa, rho); if (rigorous) refine_rho(csa, rho); eval_trow(csa, rho); } /* accuracy check based on the pivot element */ if (csa->p > 0) { double piv1 = csa->tcol_vec[csa->p]; /* more accurate */ double piv2 = csa->trow_vec[csa->q]; /* less accurate */ xassert(piv1 != 0.0); if (fabs(piv1 - piv2) > 1e-8 * (1.0 + fabs(piv1)) || !(piv1 > 0.0 && piv2 > 0.0 || piv1 < 0.0 && piv2 < 0.0)) { if (parm->msg_lev >= GLP_MSG_DBG) xprintf("piv1 = %.12g; piv2 = %.12g\n", piv1, piv2); if (binv_st != 1 || !rigorous) { if (binv_st != 1) binv_st = 0; rigorous = 5; goto loop; } /* use more accurate version in the pivot row */ if (csa->trow_vec[csa->q] == 0.0) { csa->trow_nnz++; xassert(csa->trow_nnz <= csa->n); csa->trow_ind[csa->trow_nnz] = csa->q; } csa->trow_vec[csa->q] = piv1; } } /* update primal values of basic variables */ update_bbar(csa); bbar_st = 2; /* updated */ /* update reduced costs of non-basic variables */ if (csa->p > 0) { update_cbar(csa); cbar_st = 2; /* updated */ /* on phase I objective coefficient of xB[p] in the adjacent basis becomes zero */ if (csa->phase == 1) { int k = csa->head[csa->p]; /* x[k] = xB[p] -> xN[q] */ csa->cbar[csa->q] -= csa->coef[k]; csa->coef[k] = 0.0; } } /* update steepest edge coefficients */ if (csa->p > 0) { switch (parm->pricing) { case GLP_PT_STD: break; case GLP_PT_PSE: if (csa->refct > 0) update_gamma(csa); break; default: xassert(parm != parm); } } /* update factorization of the basis matrix */ if (csa->p > 0) { ret = update_B(csa, csa->p, csa->head[csa->m+csa->q]); if (ret == 0) binv_st = 2; /* updated */ else { csa->valid = 0; binv_st = 0; /* invalid */ } } /* update matrix N */ if (csa->p > 0) { del_N_col(csa, csa->q, csa->head[csa->m+csa->q]); if (csa->type[csa->head[csa->p]] != GLP_FX) add_N_col(csa, csa->q, csa->head[csa->p]); } /* change the basis header */ change_basis(csa); /* iteration complete */ csa->it_cnt++; if (rigorous > 0) rigorous--; goto loop; done: /* deallocate the common storage area */ free_csa(csa); /* return to the calling program */ return ret; } /* eof */ praat-6.0.04/external/glpk/glpspx02.c000066400000000000000000003060761261542461700173360ustar00rootroot00000000000000/* glpspx02.c (dual simplex method) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpspx.h" #define GLP_DEBUG 1 #if 0 #define GLP_LONG_STEP 1 #endif struct csa { /* common storage area */ /*--------------------------------------------------------------*/ /* LP data */ int m; /* number of rows (auxiliary variables), m > 0 */ int n; /* number of columns (structural variables), n > 0 */ char *type; /* char type[1+m+n]; */ /* type[0] is not used; type[k], 1 <= k <= m+n, is the type of variable x[k]: GLP_FR - free variable GLP_LO - variable with lower bound GLP_UP - variable with upper bound GLP_DB - double-bounded variable GLP_FX - fixed variable */ double *lb; /* double lb[1+m+n]; */ /* lb[0] is not used; lb[k], 1 <= k <= m+n, is an lower bound of variable x[k]; if x[k] has no lower bound, lb[k] is zero */ double *ub; /* double ub[1+m+n]; */ /* ub[0] is not used; ub[k], 1 <= k <= m+n, is an upper bound of variable x[k]; if x[k] has no upper bound, ub[k] is zero; if x[k] is of fixed type, ub[k] is the same as lb[k] */ double *coef; /* double coef[1+m+n]; */ /* coef[0] is not used; coef[k], 1 <= k <= m+n, is an objective coefficient at variable x[k] */ /*--------------------------------------------------------------*/ /* original bounds of variables */ char *orig_type; /* char orig_type[1+m+n]; */ double *orig_lb; /* double orig_lb[1+m+n]; */ double *orig_ub; /* double orig_ub[1+m+n]; */ /*--------------------------------------------------------------*/ /* original objective function */ double *obj; /* double obj[1+n]; */ /* obj[0] is a constant term of the original objective function; obj[j], 1 <= j <= n, is an original objective coefficient at structural variable x[m+j] */ double zeta; /* factor used to scale original objective coefficients; its sign defines original optimization direction: zeta > 0 means minimization, zeta < 0 means maximization */ /*--------------------------------------------------------------*/ /* constraint matrix A; it has m rows and n columns and is stored by columns */ int *A_ptr; /* int A_ptr[1+n+1]; */ /* A_ptr[0] is not used; A_ptr[j], 1 <= j <= n, is starting position of j-th column in arrays A_ind and A_val; note that A_ptr[1] is always 1; A_ptr[n+1] indicates the position after the last element in arrays A_ind and A_val */ int *A_ind; /* int A_ind[A_ptr[n+1]]; */ /* row indices */ double *A_val; /* double A_val[A_ptr[n+1]]; */ /* non-zero element values */ #if 1 /* 06/IV-2009 */ /* constraint matrix A stored by rows */ int *AT_ptr; /* int AT_ptr[1+m+1]; /* AT_ptr[0] is not used; AT_ptr[i], 1 <= i <= m, is starting position of i-th row in arrays AT_ind and AT_val; note that AT_ptr[1] is always 1; AT_ptr[m+1] indicates the position after the last element in arrays AT_ind and AT_val */ int *AT_ind; /* int AT_ind[AT_ptr[m+1]]; */ /* column indices */ double *AT_val; /* double AT_val[AT_ptr[m+1]]; */ /* non-zero element values */ #endif /*--------------------------------------------------------------*/ /* basis header */ int *head; /* int head[1+m+n]; */ /* head[0] is not used; head[i], 1 <= i <= m, is the ordinal number of basic variable xB[i]; head[i] = k means that xB[i] = x[k] and i-th column of matrix B is k-th column of matrix (I|-A); head[m+j], 1 <= j <= n, is the ordinal number of non-basic variable xN[j]; head[m+j] = k means that xN[j] = x[k] and j-th column of matrix N is k-th column of matrix (I|-A) */ #if 1 /* 06/IV-2009 */ int *bind; /* int bind[1+m+n]; */ /* bind[0] is not used; bind[k], 1 <= k <= m+n, is the position of k-th column of the matrix (I|-A) in the matrix (B|N); that is, bind[k] = k' means that head[k'] = k */ #endif char *stat; /* char stat[1+n]; */ /* stat[0] is not used; stat[j], 1 <= j <= n, is the status of non-basic variable xN[j], which defines its active bound: GLP_NL - lower bound is active GLP_NU - upper bound is active GLP_NF - free variable GLP_NS - fixed variable */ /*--------------------------------------------------------------*/ /* matrix B is the basis matrix; it is composed from columns of the augmented constraint matrix (I|-A) corresponding to basic variables and stored in a factorized (invertable) form */ int valid; /* factorization is valid only if this flag is set */ BFD *bfd; /* BFD bfd[1:m,1:m]; */ /* factorized (invertable) form of the basis matrix */ #if 0 /* 06/IV-2009 */ /*--------------------------------------------------------------*/ /* matrix N is a matrix composed from columns of the augmented constraint matrix (I|-A) corresponding to non-basic variables except fixed ones; it is stored by rows and changes every time the basis changes */ int *N_ptr; /* int N_ptr[1+m+1]; */ /* N_ptr[0] is not used; N_ptr[i], 1 <= i <= m, is starting position of i-th row in arrays N_ind and N_val; note that N_ptr[1] is always 1; N_ptr[m+1] indicates the position after the last element in arrays N_ind and N_val */ int *N_len; /* int N_len[1+m]; */ /* N_len[0] is not used; N_len[i], 1 <= i <= m, is length of i-th row (0 to n) */ int *N_ind; /* int N_ind[N_ptr[m+1]]; */ /* column indices */ double *N_val; /* double N_val[N_ptr[m+1]]; */ /* non-zero element values */ #endif /*--------------------------------------------------------------*/ /* working parameters */ int phase; /* search phase: 0 - not determined yet 1 - search for dual feasible solution 2 - search for optimal solution */ glp_long tm_beg; /* time value at the beginning of the search */ int it_beg; /* simplex iteration count at the beginning of the search */ int it_cnt; /* simplex iteration count; it increases by one every time the basis changes */ int it_dpy; /* simplex iteration count at the most recent display output */ /*--------------------------------------------------------------*/ /* basic solution components */ double *bbar; /* double bbar[1+m]; */ /* bbar[0] is not used on phase I; on phase II it is the current value of the original objective function; bbar[i], 1 <= i <= m, is primal value of basic variable xB[i] (if xB[i] is free, its primal value is not updated) */ double *cbar; /* double cbar[1+n]; */ /* cbar[0] is not used; cbar[j], 1 <= j <= n, is reduced cost of non-basic variable xN[j] (if xN[j] is fixed, its reduced cost is not updated) */ /*--------------------------------------------------------------*/ /* the following pricing technique options may be used: GLP_PT_STD - standard ("textbook") pricing; GLP_PT_PSE - projected steepest edge; GLP_PT_DVX - Devex pricing (not implemented yet); in case of GLP_PT_STD the reference space is not used, and all steepest edge coefficients are set to 1 */ int refct; /* this count is set to an initial value when the reference space is defined and decreases by one every time the basis changes; once this count reaches zero, the reference space is redefined again */ char *refsp; /* char refsp[1+m+n]; */ /* refsp[0] is not used; refsp[k], 1 <= k <= m+n, is the flag which means that variable x[k] belongs to the current reference space */ double *gamma; /* double gamma[1+m]; */ /* gamma[0] is not used; gamma[i], 1 <= i <= n, is the steepest edge coefficient for basic variable xB[i]; if xB[i] is free, gamma[i] is not used and just set to 1 */ /*--------------------------------------------------------------*/ /* basic variable xB[p] chosen to leave the basis */ int p; /* index of the basic variable xB[p] chosen, 1 <= p <= m; if the set of eligible basic variables is empty (i.e. if the current basic solution is primal feasible within a tolerance) and thus no variable has been chosen, p is set to 0 */ double delta; /* change of xB[p] in the adjacent basis; delta > 0 means that xB[p] violates its lower bound and will increase to achieve it in the adjacent basis; delta < 0 means that xB[p] violates its upper bound and will decrease to achieve it in the adjacent basis */ /*--------------------------------------------------------------*/ /* pivot row of the simplex table corresponding to basic variable xB[p] chosen is the following vector: T' * e[p] = - N' * inv(B') * e[p] = - N' * rho, where B' is a matrix transposed to the current basis matrix, N' is a matrix, whose rows are columns of the matrix (I|-A) corresponding to non-basic non-fixed variables */ int trow_nnz; /* number of non-zero components, 0 <= nnz <= n */ int *trow_ind; /* int trow_ind[1+n]; */ /* trow_ind[0] is not used; trow_ind[t], 1 <= t <= nnz, is an index of non-zero component, i.e. trow_ind[t] = j means that trow_vec[j] != 0 */ double *trow_vec; /* int trow_vec[1+n]; */ /* trow_vec[0] is not used; trow_vec[j], 1 <= j <= n, is a numeric value of j-th component of the row */ double trow_max; /* infinity (maximum) norm of the row (max |trow_vec[j]|) */ int trow_num; /* number of significant non-zero components, which means that: |trow_vec[j]| >= eps for j in trow_ind[1,...,num], |tcol_vec[j]| < eps for j in trow_ind[num+1,...,nnz], where eps is a pivot tolerance */ /*--------------------------------------------------------------*/ #ifdef GLP_LONG_STEP /* 07/IV-2009 */ int nbps; /* number of breakpoints, 0 <= nbps <= n */ struct bkpt { int j; /* index of non-basic variable xN[j], 1 <= j <= n */ double t; /* value of dual ray parameter at breakpoint, t >= 0 */ double dz; /* dz = zeta(t = t[k]) - zeta(t = 0) */ } *bkpt; /* struct bkpt bkpt[1+n]; */ /* bkpt[0] is not used; bkpt[k], 1 <= k <= nbps, is k-th breakpoint of the dual objective */ #endif /*--------------------------------------------------------------*/ /* non-basic variable xN[q] chosen to enter the basis */ int q; /* index of the non-basic variable xN[q] chosen, 1 <= q <= n; if no variable has been chosen, q is set to 0 */ double new_dq; /* reduced cost of xN[q] in the adjacent basis (it is the change of lambdaB[p]) */ /*--------------------------------------------------------------*/ /* pivot column of the simplex table corresponding to non-basic variable xN[q] chosen is the following vector: T * e[q] = - inv(B) * N * e[q] = - inv(B) * N[q], where B is the current basis matrix, N[q] is a column of the matrix (I|-A) corresponding to xN[q] */ int tcol_nnz; /* number of non-zero components, 0 <= nnz <= m */ int *tcol_ind; /* int tcol_ind[1+m]; */ /* tcol_ind[0] is not used; tcol_ind[t], 1 <= t <= nnz, is an index of non-zero component, i.e. tcol_ind[t] = i means that tcol_vec[i] != 0 */ double *tcol_vec; /* double tcol_vec[1+m]; */ /* tcol_vec[0] is not used; tcol_vec[i], 1 <= i <= m, is a numeric value of i-th component of the column */ /*--------------------------------------------------------------*/ /* working arrays */ double *work1; /* double work1[1+m]; */ double *work2; /* double work2[1+m]; */ double *work3; /* double work3[1+m]; */ double *work4; /* double work4[1+m]; */ }; static const double kappa = 0.10; /*********************************************************************** * alloc_csa - allocate common storage area * * This routine allocates all arrays in the common storage area (CSA) * and returns a pointer to the CSA. */ static struct csa *alloc_csa(glp_prob *lp) { struct csa *csa; int m = lp->m; int n = lp->n; int nnz = lp->nnz; csa = xmalloc(sizeof(struct csa)); xassert(m > 0 && n > 0); csa->m = m; csa->n = n; csa->type = xcalloc(1+m+n, sizeof(char)); csa->lb = xcalloc(1+m+n, sizeof(double)); csa->ub = xcalloc(1+m+n, sizeof(double)); csa->coef = xcalloc(1+m+n, sizeof(double)); csa->orig_type = xcalloc(1+m+n, sizeof(char)); csa->orig_lb = xcalloc(1+m+n, sizeof(double)); csa->orig_ub = xcalloc(1+m+n, sizeof(double)); csa->obj = xcalloc(1+n, sizeof(double)); csa->A_ptr = xcalloc(1+n+1, sizeof(int)); csa->A_ind = xcalloc(1+nnz, sizeof(int)); csa->A_val = xcalloc(1+nnz, sizeof(double)); #if 1 /* 06/IV-2009 */ csa->AT_ptr = xcalloc(1+m+1, sizeof(int)); csa->AT_ind = xcalloc(1+nnz, sizeof(int)); csa->AT_val = xcalloc(1+nnz, sizeof(double)); #endif csa->head = xcalloc(1+m+n, sizeof(int)); #if 1 /* 06/IV-2009 */ csa->bind = xcalloc(1+m+n, sizeof(int)); #endif csa->stat = xcalloc(1+n, sizeof(char)); #if 0 /* 06/IV-2009 */ csa->N_ptr = xcalloc(1+m+1, sizeof(int)); csa->N_len = xcalloc(1+m, sizeof(int)); csa->N_ind = NULL; /* will be allocated later */ csa->N_val = NULL; /* will be allocated later */ #endif csa->bbar = xcalloc(1+m, sizeof(double)); csa->cbar = xcalloc(1+n, sizeof(double)); csa->refsp = xcalloc(1+m+n, sizeof(char)); csa->gamma = xcalloc(1+m, sizeof(double)); csa->trow_ind = xcalloc(1+n, sizeof(int)); csa->trow_vec = xcalloc(1+n, sizeof(double)); #ifdef GLP_LONG_STEP /* 07/IV-2009 */ csa->bkpt = xcalloc(1+n, sizeof(struct bkpt)); #endif csa->tcol_ind = xcalloc(1+m, sizeof(int)); csa->tcol_vec = xcalloc(1+m, sizeof(double)); csa->work1 = xcalloc(1+m, sizeof(double)); csa->work2 = xcalloc(1+m, sizeof(double)); csa->work3 = xcalloc(1+m, sizeof(double)); csa->work4 = xcalloc(1+m, sizeof(double)); return csa; } /*********************************************************************** * init_csa - initialize common storage area * * This routine initializes all data structures in the common storage * area (CSA). */ static void init_csa(struct csa *csa, glp_prob *lp) { int m = csa->m; int n = csa->n; char *type = csa->type; double *lb = csa->lb; double *ub = csa->ub; double *coef = csa->coef; char *orig_type = csa->orig_type; double *orig_lb = csa->orig_lb; double *orig_ub = csa->orig_ub; double *obj = csa->obj; int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; #if 1 /* 06/IV-2009 */ int *AT_ptr = csa->AT_ptr; int *AT_ind = csa->AT_ind; double *AT_val = csa->AT_val; #endif int *head = csa->head; #if 1 /* 06/IV-2009 */ int *bind = csa->bind; #endif char *stat = csa->stat; char *refsp = csa->refsp; double *gamma = csa->gamma; int i, j, k, loc; double cmax; /* auxiliary variables */ for (i = 1; i <= m; i++) { GLPROW *row = lp->row[i]; type[i] = (char)row->type; lb[i] = row->lb * row->rii; ub[i] = row->ub * row->rii; coef[i] = 0.0; } /* structural variables */ for (j = 1; j <= n; j++) { GLPCOL *col = lp->col[j]; type[m+j] = (char)col->type; lb[m+j] = col->lb / col->sjj; ub[m+j] = col->ub / col->sjj; coef[m+j] = col->coef * col->sjj; } /* original bounds of variables */ memcpy(&orig_type[1], &type[1], (m+n) * sizeof(char)); memcpy(&orig_lb[1], &lb[1], (m+n) * sizeof(double)); memcpy(&orig_ub[1], &ub[1], (m+n) * sizeof(double)); /* original objective function */ obj[0] = lp->c0; memcpy(&obj[1], &coef[m+1], n * sizeof(double)); /* factor used to scale original objective coefficients */ cmax = 0.0; for (j = 1; j <= n; j++) if (cmax < fabs(obj[j])) cmax = fabs(obj[j]); if (cmax == 0.0) cmax = 1.0; switch (lp->dir) { case GLP_MIN: csa->zeta = + 1.0 / cmax; break; case GLP_MAX: csa->zeta = - 1.0 / cmax; break; default: xassert(lp != lp); } #if 1 if (fabs(csa->zeta) < 1.0) csa->zeta *= 1000.0; #endif /* scale working objective coefficients */ for (j = 1; j <= n; j++) coef[m+j] *= csa->zeta; /* matrix A (by columns) */ loc = 1; for (j = 1; j <= n; j++) { GLPAIJ *aij; A_ptr[j] = loc; for (aij = lp->col[j]->ptr; aij != NULL; aij = aij->c_next) { A_ind[loc] = aij->row->i; A_val[loc] = aij->row->rii * aij->val * aij->col->sjj; loc++; } } A_ptr[n+1] = loc; xassert(loc-1 == lp->nnz); #if 1 /* 06/IV-2009 */ /* matrix A (by rows) */ loc = 1; for (i = 1; i <= m; i++) { GLPAIJ *aij; AT_ptr[i] = loc; for (aij = lp->row[i]->ptr; aij != NULL; aij = aij->r_next) { AT_ind[loc] = aij->col->j; AT_val[loc] = aij->row->rii * aij->val * aij->col->sjj; loc++; } } AT_ptr[m+1] = loc; xassert(loc-1 == lp->nnz); #endif /* basis header */ xassert(lp->valid); memcpy(&head[1], &lp->head[1], m * sizeof(int)); k = 0; for (i = 1; i <= m; i++) { GLPROW *row = lp->row[i]; if (row->stat != GLP_BS) { k++; xassert(k <= n); head[m+k] = i; stat[k] = (char)row->stat; } } for (j = 1; j <= n; j++) { GLPCOL *col = lp->col[j]; if (col->stat != GLP_BS) { k++; xassert(k <= n); head[m+k] = m + j; stat[k] = (char)col->stat; } } xassert(k == n); #if 1 /* 06/IV-2009 */ for (k = 1; k <= m+n; k++) bind[head[k]] = k; #endif /* factorization of matrix B */ csa->valid = 1, lp->valid = 0; csa->bfd = lp->bfd, lp->bfd = NULL; #if 0 /* 06/IV-2009 */ /* matrix N (by rows) */ alloc_N(csa); build_N(csa); #endif /* working parameters */ csa->phase = 0; csa->tm_beg = xtime(); csa->it_beg = csa->it_cnt = lp->it_cnt; csa->it_dpy = -1; /* reference space and steepest edge coefficients */ csa->refct = 0; memset(&refsp[1], 0, (m+n) * sizeof(char)); for (i = 1; i <= m; i++) gamma[i] = 1.0; return; } #if 1 /* copied from primal */ /*********************************************************************** * invert_B - compute factorization of the basis matrix * * This routine computes factorization of the current basis matrix B. * * If the operation is successful, the routine returns zero, otherwise * non-zero. */ static int inv_col(void *info, int i, int ind[], double val[]) { /* this auxiliary routine returns row indices and numeric values of non-zero elements of i-th column of the basis matrix */ struct csa *csa = info; int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; int *head = csa->head; int k, len, ptr, t; #ifdef GLP_DEBUG xassert(1 <= i && i <= m); #endif k = head[i]; /* B[i] is k-th column of (I|-A) */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif if (k <= m) { /* B[i] is k-th column of submatrix I */ len = 1; ind[1] = k; val[1] = 1.0; } else { /* B[i] is (k-m)-th column of submatrix (-A) */ ptr = A_ptr[k-m]; len = A_ptr[k-m+1] - ptr; memcpy(&ind[1], &A_ind[ptr], len * sizeof(int)); memcpy(&val[1], &A_val[ptr], len * sizeof(double)); for (t = 1; t <= len; t++) val[t] = - val[t]; } return len; } static int invert_B(struct csa *csa) { int ret; ret = bfd_factorize(csa->bfd, csa->m, NULL, inv_col, csa); csa->valid = (ret == 0); return ret; } #endif #if 1 /* copied from primal */ /*********************************************************************** * update_B - update factorization of the basis matrix * * This routine replaces i-th column of the basis matrix B by k-th * column of the augmented constraint matrix (I|-A) and then updates * the factorization of B. * * If the factorization has been successfully updated, the routine * returns zero, otherwise non-zero. */ static int update_B(struct csa *csa, int i, int k) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif int ret; #ifdef GLP_DEBUG xassert(1 <= i && i <= m); xassert(1 <= k && k <= m+n); #endif if (k <= m) { /* new i-th column of B is k-th column of I */ int ind[1+1]; double val[1+1]; ind[1] = k; val[1] = 1.0; xassert(csa->valid); ret = bfd_update_it(csa->bfd, i, 0, 1, ind, val); } else { /* new i-th column of B is (k-m)-th column of (-A) */ int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; double *val = csa->work1; int beg, end, ptr, len; beg = A_ptr[k-m]; end = A_ptr[k-m+1]; len = 0; for (ptr = beg; ptr < end; ptr++) val[++len] = - A_val[ptr]; xassert(csa->valid); ret = bfd_update_it(csa->bfd, i, 0, len, &A_ind[beg-1], val); } csa->valid = (ret == 0); return ret; } #endif #if 1 /* copied from primal */ /*********************************************************************** * error_ftran - compute residual vector r = h - B * x * * This routine computes the residual vector r = h - B * x, where B is * the current basis matrix, h is the vector of right-hand sides, x is * the solution vector. */ static void error_ftran(struct csa *csa, double h[], double x[], double r[]) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; int *head = csa->head; int i, k, beg, end, ptr; double temp; /* compute the residual vector: r = h - B * x = h - B[1] * x[1] - ... - B[m] * x[m], where B[1], ..., B[m] are columns of matrix B */ memcpy(&r[1], &h[1], m * sizeof(double)); for (i = 1; i <= m; i++) { temp = x[i]; if (temp == 0.0) continue; k = head[i]; /* B[i] is k-th column of (I|-A) */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif if (k <= m) { /* B[i] is k-th column of submatrix I */ r[k] -= temp; } else { /* B[i] is (k-m)-th column of submatrix (-A) */ beg = A_ptr[k-m]; end = A_ptr[k-m+1]; for (ptr = beg; ptr < end; ptr++) r[A_ind[ptr]] += A_val[ptr] * temp; } } return; } #endif #if 1 /* copied from primal */ /*********************************************************************** * refine_ftran - refine solution of B * x = h * * This routine performs one iteration to refine the solution of * the system B * x = h, where B is the current basis matrix, h is the * vector of right-hand sides, x is the solution vector. */ static void refine_ftran(struct csa *csa, double h[], double x[]) { int m = csa->m; double *r = csa->work1; double *d = csa->work1; int i; /* compute the residual vector r = h - B * x */ error_ftran(csa, h, x, r); /* compute the correction vector d = inv(B) * r */ xassert(csa->valid); bfd_ftran(csa->bfd, d); /* refine the solution vector (new x) = (old x) + d */ for (i = 1; i <= m; i++) x[i] += d[i]; return; } #endif #if 1 /* copied from primal */ /*********************************************************************** * error_btran - compute residual vector r = h - B'* x * * This routine computes the residual vector r = h - B'* x, where B' * is a matrix transposed to the current basis matrix, h is the vector * of right-hand sides, x is the solution vector. */ static void error_btran(struct csa *csa, double h[], double x[], double r[]) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; int *head = csa->head; int i, k, beg, end, ptr; double temp; /* compute the residual vector r = b - B'* x */ for (i = 1; i <= m; i++) { /* r[i] := b[i] - (i-th column of B)'* x */ k = head[i]; /* B[i] is k-th column of (I|-A) */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif temp = h[i]; if (k <= m) { /* B[i] is k-th column of submatrix I */ temp -= x[k]; } else { /* B[i] is (k-m)-th column of submatrix (-A) */ beg = A_ptr[k-m]; end = A_ptr[k-m+1]; for (ptr = beg; ptr < end; ptr++) temp += A_val[ptr] * x[A_ind[ptr]]; } r[i] = temp; } return; } #endif #if 1 /* copied from primal */ /*********************************************************************** * refine_btran - refine solution of B'* x = h * * This routine performs one iteration to refine the solution of the * system B'* x = h, where B' is a matrix transposed to the current * basis matrix, h is the vector of right-hand sides, x is the solution * vector. */ static void refine_btran(struct csa *csa, double h[], double x[]) { int m = csa->m; double *r = csa->work1; double *d = csa->work1; int i; /* compute the residual vector r = h - B'* x */ error_btran(csa, h, x, r); /* compute the correction vector d = inv(B') * r */ xassert(csa->valid); bfd_btran(csa->bfd, d); /* refine the solution vector (new x) = (old x) + d */ for (i = 1; i <= m; i++) x[i] += d[i]; return; } #endif #if 1 /* copied from primal */ /*********************************************************************** * get_xN - determine current value of non-basic variable xN[j] * * This routine returns the current value of non-basic variable xN[j], * which is a value of its active bound. */ static double get_xN(struct csa *csa, int j) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif double *lb = csa->lb; double *ub = csa->ub; int *head = csa->head; char *stat = csa->stat; int k; double xN; #ifdef GLP_DEBUG xassert(1 <= j && j <= n); #endif k = head[m+j]; /* x[k] = xN[j] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif switch (stat[j]) { case GLP_NL: /* x[k] is on its lower bound */ xN = lb[k]; break; case GLP_NU: /* x[k] is on its upper bound */ xN = ub[k]; break; case GLP_NF: /* x[k] is free non-basic variable */ xN = 0.0; break; case GLP_NS: /* x[k] is fixed non-basic variable */ xN = lb[k]; break; default: xassert(stat != stat); } return xN; } #endif #if 1 /* copied from primal */ /*********************************************************************** * eval_beta - compute primal values of basic variables * * This routine computes current primal values of all basic variables: * * beta = - inv(B) * N * xN, * * where B is the current basis matrix, N is a matrix built of columns * of matrix (I|-A) corresponding to non-basic variables, and xN is the * vector of current values of non-basic variables. */ static void eval_beta(struct csa *csa, double beta[]) { int m = csa->m; int n = csa->n; int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; int *head = csa->head; double *h = csa->work2; int i, j, k, beg, end, ptr; double xN; /* compute the right-hand side vector: h := - N * xN = - N[1] * xN[1] - ... - N[n] * xN[n], where N[1], ..., N[n] are columns of matrix N */ for (i = 1; i <= m; i++) h[i] = 0.0; for (j = 1; j <= n; j++) { k = head[m+j]; /* x[k] = xN[j] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif /* determine current value of xN[j] */ xN = get_xN(csa, j); if (xN == 0.0) continue; if (k <= m) { /* N[j] is k-th column of submatrix I */ h[k] -= xN; } else { /* N[j] is (k-m)-th column of submatrix (-A) */ beg = A_ptr[k-m]; end = A_ptr[k-m+1]; for (ptr = beg; ptr < end; ptr++) h[A_ind[ptr]] += xN * A_val[ptr]; } } /* solve system B * beta = h */ memcpy(&beta[1], &h[1], m * sizeof(double)); xassert(csa->valid); bfd_ftran(csa->bfd, beta); /* and refine the solution */ refine_ftran(csa, h, beta); return; } #endif #if 1 /* copied from primal */ /*********************************************************************** * eval_pi - compute vector of simplex multipliers * * This routine computes the vector of current simplex multipliers: * * pi = inv(B') * cB, * * where B' is a matrix transposed to the current basis matrix, cB is * a subvector of objective coefficients at basic variables. */ static void eval_pi(struct csa *csa, double pi[]) { int m = csa->m; double *c = csa->coef; int *head = csa->head; double *cB = csa->work2; int i; /* construct the right-hand side vector cB */ for (i = 1; i <= m; i++) cB[i] = c[head[i]]; /* solve system B'* pi = cB */ memcpy(&pi[1], &cB[1], m * sizeof(double)); xassert(csa->valid); bfd_btran(csa->bfd, pi); /* and refine the solution */ refine_btran(csa, cB, pi); return; } #endif #if 1 /* copied from primal */ /*********************************************************************** * eval_cost - compute reduced cost of non-basic variable xN[j] * * This routine computes the current reduced cost of non-basic variable * xN[j]: * * d[j] = cN[j] - N'[j] * pi, * * where cN[j] is the objective coefficient at variable xN[j], N[j] is * a column of the augmented constraint matrix (I|-A) corresponding to * xN[j], pi is the vector of simplex multipliers. */ static double eval_cost(struct csa *csa, double pi[], int j) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif double *coef = csa->coef; int *head = csa->head; int k; double dj; #ifdef GLP_DEBUG xassert(1 <= j && j <= n); #endif k = head[m+j]; /* x[k] = xN[j] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif dj = coef[k]; if (k <= m) { /* N[j] is k-th column of submatrix I */ dj -= pi[k]; } else { /* N[j] is (k-m)-th column of submatrix (-A) */ int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; int beg, end, ptr; beg = A_ptr[k-m]; end = A_ptr[k-m+1]; for (ptr = beg; ptr < end; ptr++) dj += A_val[ptr] * pi[A_ind[ptr]]; } return dj; } #endif #if 1 /* copied from primal */ /*********************************************************************** * eval_bbar - compute and store primal values of basic variables * * This routine computes primal values of all basic variables and then * stores them in the solution array. */ static void eval_bbar(struct csa *csa) { eval_beta(csa, csa->bbar); return; } #endif #if 1 /* copied from primal */ /*********************************************************************** * eval_cbar - compute and store reduced costs of non-basic variables * * This routine computes reduced costs of all non-basic variables and * then stores them in the solution array. */ static void eval_cbar(struct csa *csa) { #ifdef GLP_DEBUG int m = csa->m; #endif int n = csa->n; #ifdef GLP_DEBUG int *head = csa->head; #endif double *cbar = csa->cbar; double *pi = csa->work3; int j; #ifdef GLP_DEBUG int k; #endif /* compute simplex multipliers */ eval_pi(csa, pi); /* compute and store reduced costs */ for (j = 1; j <= n; j++) { #ifdef GLP_DEBUG k = head[m+j]; /* x[k] = xN[j] */ xassert(1 <= k && k <= m+n); #endif cbar[j] = eval_cost(csa, pi, j); } return; } #endif /*********************************************************************** * reset_refsp - reset the reference space * * This routine resets (redefines) the reference space used in the * projected steepest edge pricing algorithm. */ static void reset_refsp(struct csa *csa) { int m = csa->m; int n = csa->n; int *head = csa->head; char *refsp = csa->refsp; double *gamma = csa->gamma; int i, k; xassert(csa->refct == 0); csa->refct = 1000; memset(&refsp[1], 0, (m+n) * sizeof(char)); for (i = 1; i <= m; i++) { k = head[i]; /* x[k] = xB[i] */ refsp[k] = 1; gamma[i] = 1.0; } return; } /*********************************************************************** * eval_gamma - compute steepest edge coefficients * * This routine computes the vector of steepest edge coefficients for * all basic variables (except free ones) using its direct definition: * * gamma[i] = eta[i] + sum alfa[i,j]^2, i = 1,...,m, * j in C * * where eta[i] = 1 means that xB[i] is in the current reference space, * and 0 otherwise; C is a set of non-basic non-fixed variables xN[j], * which are in the current reference space; alfa[i,j] are elements of * the current simplex table. * * NOTE: The routine is intended only for debugginig purposes. */ static void eval_gamma(struct csa *csa, double gamma[]) { int m = csa->m; int n = csa->n; char *type = csa->type; int *head = csa->head; char *refsp = csa->refsp; double *alfa = csa->work3; double *h = csa->work3; int i, j, k; /* gamma[i] := eta[i] (or 1, if xB[i] is free) */ for (i = 1; i <= m; i++) { k = head[i]; /* x[k] = xB[i] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif if (type[k] == GLP_FR) gamma[i] = 1.0; else gamma[i] = (refsp[k] ? 1.0 : 0.0); } /* compute columns of the current simplex table */ for (j = 1; j <= n; j++) { k = head[m+j]; /* x[k] = xN[j] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif /* skip column, if xN[j] is not in C */ if (!refsp[k]) continue; #ifdef GLP_DEBUG /* set C must not contain fixed variables */ xassert(type[k] != GLP_FX); #endif /* construct the right-hand side vector h = - N[j] */ for (i = 1; i <= m; i++) h[i] = 0.0; if (k <= m) { /* N[j] is k-th column of submatrix I */ h[k] = -1.0; } else { /* N[j] is (k-m)-th column of submatrix (-A) */ int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; int beg, end, ptr; beg = A_ptr[k-m]; end = A_ptr[k-m+1]; for (ptr = beg; ptr < end; ptr++) h[A_ind[ptr]] = A_val[ptr]; } /* solve system B * alfa = h */ xassert(csa->valid); bfd_ftran(csa->bfd, alfa); /* gamma[i] := gamma[i] + alfa[i,j]^2 */ for (i = 1; i <= m; i++) { k = head[i]; /* x[k] = xB[i] */ if (type[k] != GLP_FR) gamma[i] += alfa[i] * alfa[i]; } } return; } /*********************************************************************** * chuzr - choose basic variable (row of the simplex table) * * This routine chooses basic variable xB[p] having largest weighted * bound violation: * * |r[p]| / sqrt(gamma[p]) = max |r[i]| / sqrt(gamma[i]), * i in I * * / lB[i] - beta[i], if beta[i] < lB[i] * | * r[i] = < 0, if lB[i] <= beta[i] <= uB[i] * | * \ uB[i] - beta[i], if beta[i] > uB[i] * * where beta[i] is primal value of xB[i] in the current basis, lB[i] * and uB[i] are lower and upper bounds of xB[i], I is a subset of * eligible basic variables, which significantly violates their bounds, * gamma[i] is the steepest edge coefficient. * * If |r[i]| is less than a specified tolerance, xB[i] is not included * in I and therefore ignored. * * If I is empty and no variable has been chosen, p is set to 0. */ static void chuzr(struct csa *csa, double tol_bnd) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif char *type = csa->type; double *lb = csa->lb; double *ub = csa->ub; int *head = csa->head; double *bbar = csa->bbar; double *gamma = csa->gamma; int i, k, p; double delta, best, eps, ri, temp; /* nothing is chosen so far */ p = 0, delta = 0.0, best = 0.0; /* look through the list of basic variables */ for (i = 1; i <= m; i++) { k = head[i]; /* x[k] = xB[i] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif /* determine bound violation ri[i] */ ri = 0.0; if (type[k] == GLP_LO || type[k] == GLP_DB || type[k] == GLP_FX) { /* xB[i] has lower bound */ eps = tol_bnd * (1.0 + kappa * fabs(lb[k])); if (bbar[i] < lb[k] - eps) { /* and significantly violates it */ ri = lb[k] - bbar[i]; } } if (type[k] == GLP_UP || type[k] == GLP_DB || type[k] == GLP_FX) { /* xB[i] has upper bound */ eps = tol_bnd * (1.0 + kappa * fabs(ub[k])); if (bbar[i] > ub[k] + eps) { /* and significantly violates it */ ri = ub[k] - bbar[i]; } } /* if xB[i] is not eligible, skip it */ if (ri == 0.0) continue; /* xB[i] is eligible basic variable; choose one with largest weighted bound violation */ #ifdef GLP_DEBUG xassert(gamma[i] >= 0.0); #endif temp = gamma[i]; if (temp < DBL_EPSILON) temp = DBL_EPSILON; temp = (ri * ri) / temp; if (best < temp) p = i, delta = ri, best = temp; } /* store the index of basic variable xB[p] chosen and its change in the adjacent basis */ csa->p = p; csa->delta = delta; return; } #if 1 /* copied from primal */ /*********************************************************************** * eval_rho - compute pivot row of the inverse * * This routine computes the pivot (p-th) row of the inverse inv(B), * which corresponds to basic variable xB[p] chosen: * * rho = inv(B') * e[p], * * where B' is a matrix transposed to the current basis matrix, e[p] * is unity vector. */ static void eval_rho(struct csa *csa, double rho[]) { int m = csa->m; int p = csa->p; double *e = rho; int i; #ifdef GLP_DEBUG xassert(1 <= p && p <= m); #endif /* construct the right-hand side vector e[p] */ for (i = 1; i <= m; i++) e[i] = 0.0; e[p] = 1.0; /* solve system B'* rho = e[p] */ xassert(csa->valid); bfd_btran(csa->bfd, rho); return; } #endif #if 1 /* copied from primal */ /*********************************************************************** * refine_rho - refine pivot row of the inverse * * This routine refines the pivot row of the inverse inv(B) assuming * that it was previously computed by the routine eval_rho. */ static void refine_rho(struct csa *csa, double rho[]) { int m = csa->m; int p = csa->p; double *e = csa->work3; int i; #ifdef GLP_DEBUG xassert(1 <= p && p <= m); #endif /* construct the right-hand side vector e[p] */ for (i = 1; i <= m; i++) e[i] = 0.0; e[p] = 1.0; /* refine solution of B'* rho = e[p] */ refine_btran(csa, e, rho); return; } #endif #if 1 /* 06/IV-2009 */ /*********************************************************************** * eval_trow - compute pivot row of the simplex table * * This routine computes the pivot row of the simplex table, which * corresponds to basic variable xB[p] chosen. * * The pivot row is the following vector: * * trow = T'* e[p] = - N'* inv(B') * e[p] = - N' * rho, * * where rho is the pivot row of the inverse inv(B) previously computed * by the routine eval_rho. * * Note that elements of the pivot row corresponding to fixed non-basic * variables are not computed. * * NOTES * * Computing pivot row of the simplex table is one of the most time * consuming operations, and for some instances it may take more than * 50% of the total solution time. * * In the current implementation there are two routines to compute the * pivot row. The routine eval_trow1 computes elements of the pivot row * as inner products of columns of the matrix N and the vector rho; it * is used when the vector rho is relatively dense. The routine * eval_trow2 computes the pivot row as a linear combination of rows of * the matrix N; it is used when the vector rho is relatively sparse. */ static void eval_trow1(struct csa *csa, double rho[]) { int m = csa->m; int n = csa->n; int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; int *head = csa->head; char *stat = csa->stat; int *trow_ind = csa->trow_ind; double *trow_vec = csa->trow_vec; int j, k, beg, end, ptr, nnz; double temp; /* compute the pivot row as inner products of columns of the matrix N and vector rho: trow[j] = - rho * N[j] */ nnz = 0; for (j = 1; j <= n; j++) { if (stat[j] == GLP_NS) { /* xN[j] is fixed */ trow_vec[j] = 0.0; continue; } k = head[m+j]; /* x[k] = xN[j] */ if (k <= m) { /* N[j] is k-th column of submatrix I */ temp = - rho[k]; } else { /* N[j] is (k-m)-th column of submatrix (-A) */ beg = A_ptr[k-m], end = A_ptr[k-m+1]; temp = 0.0; for (ptr = beg; ptr < end; ptr++) temp += rho[A_ind[ptr]] * A_val[ptr]; } if (temp != 0.0) trow_ind[++nnz] = j; trow_vec[j] = temp; } csa->trow_nnz = nnz; return; } static void eval_trow2(struct csa *csa, double rho[]) { int m = csa->m; int n = csa->n; int *AT_ptr = csa->AT_ptr; int *AT_ind = csa->AT_ind; double *AT_val = csa->AT_val; int *bind = csa->bind; char *stat = csa->stat; int *trow_ind = csa->trow_ind; double *trow_vec = csa->trow_vec; int i, j, beg, end, ptr, nnz; double temp; /* clear the pivot row */ for (j = 1; j <= n; j++) trow_vec[j] = 0.0; /* compute the pivot row as a linear combination of rows of the matrix N: trow = - rho[1] * N'[1] - ... - rho[m] * N'[m] */ for (i = 1; i <= m; i++) { temp = rho[i]; if (temp == 0.0) continue; /* trow := trow - rho[i] * N'[i] */ j = bind[i] - m; /* x[i] = xN[j] */ if (j >= 1 && stat[j] != GLP_NS) trow_vec[j] -= temp; beg = AT_ptr[i], end = AT_ptr[i+1]; for (ptr = beg; ptr < end; ptr++) { j = bind[m + AT_ind[ptr]] - m; /* x[k] = xN[j] */ if (j >= 1 && stat[j] != GLP_NS) trow_vec[j] += temp * AT_val[ptr]; } } /* construct sparse pattern of the pivot row */ nnz = 0; for (j = 1; j <= n; j++) { if (trow_vec[j] != 0.0) trow_ind[++nnz] = j; } csa->trow_nnz = nnz; return; } static void eval_trow(struct csa *csa, double rho[]) { int m = csa->m; int i, nnz; double dens; /* determine the density of the vector rho */ nnz = 0; for (i = 1; i <= m; i++) if (rho[i] != 0.0) nnz++; dens = (double)nnz / (double)m; if (dens >= 0.20) { /* rho is relatively dense */ eval_trow1(csa, rho); } else { /* rho is relatively sparse */ eval_trow2(csa, rho); } return; } #endif /*********************************************************************** * sort_trow - sort pivot row of the simplex table * * This routine reorders the list of non-zero elements of the pivot * row to put significant elements, whose magnitude is not less than * a specified tolerance, in front of the list, and stores the number * of significant elements in trow_num. */ static void sort_trow(struct csa *csa, double tol_piv) { #ifdef GLP_DEBUG int n = csa->n; char *stat = csa->stat; #endif int nnz = csa->trow_nnz; int *trow_ind = csa->trow_ind; double *trow_vec = csa->trow_vec; int j, num, pos; double big, eps, temp; /* compute infinity (maximum) norm of the row */ big = 0.0; for (pos = 1; pos <= nnz; pos++) { #ifdef GLP_DEBUG j = trow_ind[pos]; xassert(1 <= j && j <= n); xassert(stat[j] != GLP_NS); #endif temp = fabs(trow_vec[trow_ind[pos]]); if (big < temp) big = temp; } csa->trow_max = big; /* determine absolute pivot tolerance */ eps = tol_piv * (1.0 + 0.01 * big); /* move significant row components to the front of the list */ for (num = 0; num < nnz; ) { j = trow_ind[nnz]; if (fabs(trow_vec[j]) < eps) nnz--; else { num++; trow_ind[nnz] = trow_ind[num]; trow_ind[num] = j; } } csa->trow_num = num; return; } #ifdef GLP_LONG_STEP /* 07/IV-2009 */ static int ls_func(const void *p1_, const void *p2_) { const struct bkpt *p1 = p1_, *p2 = p2_; if (p1->t < p2->t) return -1; if (p1->t > p2->t) return +1; return 0; } static int ls_func1(const void *p1_, const void *p2_) { const struct bkpt *p1 = p1_, *p2 = p2_; if (p1->dz < p2->dz) return -1; if (p1->dz > p2->dz) return +1; return 0; } static void long_step(struct csa *csa) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif char *type = csa->type; double *lb = csa->lb; double *ub = csa->ub; int *head = csa->head; char *stat = csa->stat; double *cbar = csa->cbar; double delta = csa->delta; int *trow_ind = csa->trow_ind; double *trow_vec = csa->trow_vec; int trow_num = csa->trow_num; struct bkpt *bkpt = csa->bkpt; int j, k, kk, nbps, pos; double alfa, s, slope, dzmax; /* delta > 0 means that xB[p] violates its lower bound, so to increase the dual objective lambdaB[p] must increase; delta < 0 means that xB[p] violates its upper bound, so to increase the dual objective lambdaB[p] must decrease */ /* s := sign(delta) */ s = (delta > 0.0 ? +1.0 : -1.0); /* determine breakpoints of the dual objective */ nbps = 0; for (pos = 1; pos <= trow_num; pos++) { j = trow_ind[pos]; #ifdef GLP_DEBUG xassert(1 <= j && j <= n); xassert(stat[j] != GLP_NS); #endif /* if there is free non-basic variable, switch to the standard ratio test */ if (stat[j] == GLP_NF) { nbps = 0; goto done; } /* lambdaN[j] = ... - alfa * t - ..., where t = s * lambdaB[i] is the dual ray parameter, t >= 0 */ alfa = s * trow_vec[j]; #ifdef GLP_DEBUG xassert(alfa != 0.0); xassert(stat[j] == GLP_NL || stat[j] == GLP_NU); #endif if (alfa > 0.0 && stat[j] == GLP_NL || alfa < 0.0 && stat[j] == GLP_NU) { /* either lambdaN[j] >= 0 (if stat = GLP_NL) and decreases or lambdaN[j] <= 0 (if stat = GLP_NU) and increases; in both cases we have a breakpoint */ nbps++; #ifdef GLP_DEBUG xassert(nbps <= n); #endif bkpt[nbps].j = j; bkpt[nbps].t = cbar[j] / alfa; /* if (stat[j] == GLP_NL && cbar[j] < 0.0 || stat[j] == GLP_NU && cbar[j] > 0.0) xprintf("%d %g\n", stat[j], cbar[j]); */ /* if t is negative, replace it by exact zero (see comments in the routine chuzc) */ if (bkpt[nbps].t < 0.0) bkpt[nbps].t = 0.0; } } /* if there are less than two breakpoints, switch to the standard ratio test */ if (nbps < 2) { nbps = 0; goto done; } /* sort breakpoints by ascending the dual ray parameter, t */ qsort(&bkpt[1], nbps, sizeof(struct bkpt), ls_func); /* determine last breakpoint, at which the dual objective still greater than at t = 0 */ dzmax = 0.0; slope = fabs(delta); /* initial slope */ for (kk = 1; kk <= nbps; kk++) { if (kk == 1) bkpt[kk].dz = 0.0 + slope * (bkpt[kk].t - 0.0); else bkpt[kk].dz = bkpt[kk-1].dz + slope * (bkpt[kk].t - bkpt[kk-1].t); if (dzmax < bkpt[kk].dz) dzmax = bkpt[kk].dz; else if (bkpt[kk].dz < 0.05 * (1.0 + dzmax)) { nbps = kk - 1; break; } j = bkpt[kk].j; k = head[m+j]; /* x[k] = xN[j] */ if (type[k] == GLP_DB) slope -= fabs(trow_vec[j]) * (ub[k] - lb[k]); else { nbps = kk; break; } } /* if there are less than two breakpoints, switch to the standard ratio test */ if (nbps < 2) { nbps = 0; goto done; } /* sort breakpoints by ascending the dual change, dz */ qsort(&bkpt[1], nbps, sizeof(struct bkpt), ls_func1); /* for (kk = 1; kk <= nbps; kk++) xprintf("%d; t = %g; dz = %g\n", kk, bkpt[kk].t, bkpt[kk].dz); */ done: csa->nbps = nbps; return; } #endif /*********************************************************************** * chuzc - choose non-basic variable (column of the simplex table) * * This routine chooses non-basic variable xN[q], which being entered * in the basis keeps dual feasibility of the basic solution. * * The parameter rtol is a relative tolerance used to relax zero bounds * of reduced costs of non-basic variables. If rtol = 0, the routine * implements the standard ratio test. Otherwise, if rtol > 0, the * routine implements Harris' two-pass ratio test. In the latter case * rtol should be about three times less than a tolerance used to check * dual feasibility. */ static void chuzc(struct csa *csa, double rtol) { #ifdef GLP_DEBUG int m = csa->m; int n = csa->n; #endif char *stat = csa->stat; double *cbar = csa->cbar; #ifdef GLP_DEBUG int p = csa->p; #endif double delta = csa->delta; int *trow_ind = csa->trow_ind; double *trow_vec = csa->trow_vec; int trow_num = csa->trow_num; int j, pos, q; double alfa, big, s, t, teta, tmax; #ifdef GLP_DEBUG xassert(1 <= p && p <= m); #endif /* delta > 0 means that xB[p] violates its lower bound and goes to it in the adjacent basis, so lambdaB[p] is increasing from its lower zero bound; delta < 0 means that xB[p] violates its upper bound and goes to it in the adjacent basis, so lambdaB[p] is decreasing from its upper zero bound */ #ifdef GLP_DEBUG xassert(delta != 0.0); #endif /* s := sign(delta) */ s = (delta > 0.0 ? +1.0 : -1.0); /*** FIRST PASS ***/ /* nothing is chosen so far */ q = 0, teta = DBL_MAX, big = 0.0; /* walk through significant elements of the pivot row */ for (pos = 1; pos <= trow_num; pos++) { j = trow_ind[pos]; #ifdef GLP_DEBUG xassert(1 <= j && j <= n); #endif alfa = s * trow_vec[j]; #ifdef GLP_DEBUG xassert(alfa != 0.0); #endif /* lambdaN[j] = ... - alfa * lambdaB[p] - ..., and due to s we need to consider only increasing lambdaB[p] */ if (alfa > 0.0) { /* lambdaN[j] is decreasing */ if (stat[j] == GLP_NL || stat[j] == GLP_NF) { /* lambdaN[j] has zero lower bound */ t = (cbar[j] + rtol) / alfa; } else { /* lambdaN[j] has no lower bound */ continue; } } else { /* lambdaN[j] is increasing */ if (stat[j] == GLP_NU || stat[j] == GLP_NF) { /* lambdaN[j] has zero upper bound */ t = (cbar[j] - rtol) / alfa; } else { /* lambdaN[j] has no upper bound */ continue; } } /* t is a change of lambdaB[p], on which lambdaN[j] reaches its zero bound (possibly relaxed); since the basic solution is assumed to be dual feasible, t has to be non-negative by definition; however, it may happen that lambdaN[j] slightly (i.e. within a tolerance) violates its zero bound, that leads to negative t; in the latter case, if xN[j] is chosen, negative t means that lambdaB[p] changes in wrong direction that may cause wrong results on updating reduced costs; thus, if t is negative, we should replace it by exact zero assuming that lambdaN[j] is exactly on its zero bound, and violation appears due to round-off errors */ if (t < 0.0) t = 0.0; /* apply minimal ratio test */ if (teta > t || teta == t && big < fabs(alfa)) q = j, teta = t, big = fabs(alfa); } /* the second pass is skipped in the following cases: */ /* if the standard ratio test is used */ if (rtol == 0.0) goto done; /* if no non-basic variable has been chosen on the first pass */ if (q == 0) goto done; /* if lambdaN[q] prevents lambdaB[p] from any change */ if (teta == 0.0) goto done; /*** SECOND PASS ***/ /* here tmax is a maximal change of lambdaB[p], on which the solution remains dual feasible within a tolerance */ #if 0 tmax = (1.0 + 10.0 * DBL_EPSILON) * teta; #else tmax = teta; #endif /* nothing is chosen so far */ q = 0, teta = DBL_MAX, big = 0.0; /* walk through significant elements of the pivot row */ for (pos = 1; pos <= trow_num; pos++) { j = trow_ind[pos]; #ifdef GLP_DEBUG xassert(1 <= j && j <= n); #endif alfa = s * trow_vec[j]; #ifdef GLP_DEBUG xassert(alfa != 0.0); #endif /* lambdaN[j] = ... - alfa * lambdaB[p] - ..., and due to s we need to consider only increasing lambdaB[p] */ if (alfa > 0.0) { /* lambdaN[j] is decreasing */ if (stat[j] == GLP_NL || stat[j] == GLP_NF) { /* lambdaN[j] has zero lower bound */ t = cbar[j] / alfa; } else { /* lambdaN[j] has no lower bound */ continue; } } else { /* lambdaN[j] is increasing */ if (stat[j] == GLP_NU || stat[j] == GLP_NF) { /* lambdaN[j] has zero upper bound */ t = cbar[j] / alfa; } else { /* lambdaN[j] has no upper bound */ continue; } } /* (see comments for the first pass) */ if (t < 0.0) t = 0.0; /* t is a change of lambdaB[p], on which lambdaN[j] reaches its zero (lower or upper) bound; if t <= tmax, all reduced costs can violate their zero bounds only within relaxation tolerance rtol, so we can choose non-basic variable having largest influence coefficient to avoid possible numerical instability */ if (t <= tmax && big < fabs(alfa)) q = j, teta = t, big = fabs(alfa); } /* something must be chosen on the second pass */ xassert(q != 0); done: /* store the index of non-basic variable xN[q] chosen */ csa->q = q; /* store reduced cost of xN[q] in the adjacent basis */ csa->new_dq = s * teta; return; } #if 1 /* copied from primal */ /*********************************************************************** * eval_tcol - compute pivot column of the simplex table * * This routine computes the pivot column of the simplex table, which * corresponds to non-basic variable xN[q] chosen. * * The pivot column is the following vector: * * tcol = T * e[q] = - inv(B) * N * e[q] = - inv(B) * N[q], * * where B is the current basis matrix, N[q] is a column of the matrix * (I|-A) corresponding to variable xN[q]. */ static void eval_tcol(struct csa *csa) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif int *head = csa->head; int q = csa->q; int *tcol_ind = csa->tcol_ind; double *tcol_vec = csa->tcol_vec; double *h = csa->tcol_vec; int i, k, nnz; #ifdef GLP_DEBUG xassert(1 <= q && q <= n); #endif k = head[m+q]; /* x[k] = xN[q] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif /* construct the right-hand side vector h = - N[q] */ for (i = 1; i <= m; i++) h[i] = 0.0; if (k <= m) { /* N[q] is k-th column of submatrix I */ h[k] = -1.0; } else { /* N[q] is (k-m)-th column of submatrix (-A) */ int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; int beg, end, ptr; beg = A_ptr[k-m]; end = A_ptr[k-m+1]; for (ptr = beg; ptr < end; ptr++) h[A_ind[ptr]] = A_val[ptr]; } /* solve system B * tcol = h */ xassert(csa->valid); bfd_ftran(csa->bfd, tcol_vec); /* construct sparse pattern of the pivot column */ nnz = 0; for (i = 1; i <= m; i++) { if (tcol_vec[i] != 0.0) tcol_ind[++nnz] = i; } csa->tcol_nnz = nnz; return; } #endif #if 1 /* copied from primal */ /*********************************************************************** * refine_tcol - refine pivot column of the simplex table * * This routine refines the pivot column of the simplex table assuming * that it was previously computed by the routine eval_tcol. */ static void refine_tcol(struct csa *csa) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif int *head = csa->head; int q = csa->q; int *tcol_ind = csa->tcol_ind; double *tcol_vec = csa->tcol_vec; double *h = csa->work3; int i, k, nnz; #ifdef GLP_DEBUG xassert(1 <= q && q <= n); #endif k = head[m+q]; /* x[k] = xN[q] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif /* construct the right-hand side vector h = - N[q] */ for (i = 1; i <= m; i++) h[i] = 0.0; if (k <= m) { /* N[q] is k-th column of submatrix I */ h[k] = -1.0; } else { /* N[q] is (k-m)-th column of submatrix (-A) */ int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; int beg, end, ptr; beg = A_ptr[k-m]; end = A_ptr[k-m+1]; for (ptr = beg; ptr < end; ptr++) h[A_ind[ptr]] = A_val[ptr]; } /* refine solution of B * tcol = h */ refine_ftran(csa, h, tcol_vec); /* construct sparse pattern of the pivot column */ nnz = 0; for (i = 1; i <= m; i++) { if (tcol_vec[i] != 0.0) tcol_ind[++nnz] = i; } csa->tcol_nnz = nnz; return; } #endif /*********************************************************************** * update_cbar - update reduced costs of non-basic variables * * This routine updates reduced costs of all (except fixed) non-basic * variables for the adjacent basis. */ static void update_cbar(struct csa *csa) { #ifdef GLP_DEBUG int n = csa->n; #endif double *cbar = csa->cbar; int trow_nnz = csa->trow_nnz; int *trow_ind = csa->trow_ind; double *trow_vec = csa->trow_vec; int q = csa->q; double new_dq = csa->new_dq; int j, pos; #ifdef GLP_DEBUG xassert(1 <= q && q <= n); #endif /* set new reduced cost of xN[q] */ cbar[q] = new_dq; /* update reduced costs of other non-basic variables */ if (new_dq == 0.0) goto done; for (pos = 1; pos <= trow_nnz; pos++) { j = trow_ind[pos]; #ifdef GLP_DEBUG xassert(1 <= j && j <= n); #endif if (j != q) cbar[j] -= trow_vec[j] * new_dq; } done: return; } /*********************************************************************** * update_bbar - update values of basic variables * * This routine updates values of all basic variables for the adjacent * basis. */ static void update_bbar(struct csa *csa) { #ifdef GLP_DEBUG int m = csa->m; int n = csa->n; #endif double *bbar = csa->bbar; int p = csa->p; double delta = csa->delta; int q = csa->q; int tcol_nnz = csa->tcol_nnz; int *tcol_ind = csa->tcol_ind; double *tcol_vec = csa->tcol_vec; int i, pos; double teta; #ifdef GLP_DEBUG xassert(1 <= p && p <= m); xassert(1 <= q && q <= n); #endif /* determine the change of xN[q] in the adjacent basis */ #ifdef GLP_DEBUG xassert(tcol_vec[p] != 0.0); #endif teta = delta / tcol_vec[p]; /* set new primal value of xN[q] */ bbar[p] = get_xN(csa, q) + teta; /* update primal values of other basic variables */ if (teta == 0.0) goto done; for (pos = 1; pos <= tcol_nnz; pos++) { i = tcol_ind[pos]; #ifdef GLP_DEBUG xassert(1 <= i && i <= m); #endif if (i != p) bbar[i] += tcol_vec[i] * teta; } done: return; } /*********************************************************************** * update_gamma - update steepest edge coefficients * * This routine updates steepest-edge coefficients for the adjacent * basis. */ static void update_gamma(struct csa *csa) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif char *type = csa->type; int *head = csa->head; char *refsp = csa->refsp; double *gamma = csa->gamma; int p = csa->p; int trow_nnz = csa->trow_nnz; int *trow_ind = csa->trow_ind; double *trow_vec = csa->trow_vec; int q = csa->q; int tcol_nnz = csa->tcol_nnz; int *tcol_ind = csa->tcol_ind; double *tcol_vec = csa->tcol_vec; double *u = csa->work3; int i, j, k,pos; double gamma_p, eta_p, pivot, t, t1, t2; #ifdef GLP_DEBUG xassert(1 <= p && p <= m); xassert(1 <= q && q <= n); #endif /* the basis changes, so decrease the count */ xassert(csa->refct > 0); csa->refct--; /* recompute gamma[p] for the current basis more accurately and compute auxiliary vector u */ #ifdef GLP_DEBUG xassert(type[head[p]] != GLP_FR); #endif gamma_p = eta_p = (refsp[head[p]] ? 1.0 : 0.0); for (i = 1; i <= m; i++) u[i] = 0.0; for (pos = 1; pos <= trow_nnz; pos++) { j = trow_ind[pos]; #ifdef GLP_DEBUG xassert(1 <= j && j <= n); #endif k = head[m+j]; /* x[k] = xN[j] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); xassert(type[k] != GLP_FX); #endif if (!refsp[k]) continue; t = trow_vec[j]; gamma_p += t * t; /* u := u + N[j] * delta[j] * trow[j] */ if (k <= m) { /* N[k] = k-j stolbec submatrix I */ u[k] += t; } else { /* N[k] = k-m-k stolbec (-A) */ int *A_ptr = csa->A_ptr; int *A_ind = csa->A_ind; double *A_val = csa->A_val; int beg, end, ptr; beg = A_ptr[k-m]; end = A_ptr[k-m+1]; for (ptr = beg; ptr < end; ptr++) u[A_ind[ptr]] -= t * A_val[ptr]; } } xassert(csa->valid); bfd_ftran(csa->bfd, u); /* update gamma[i] for other basic variables (except xB[p] and free variables) */ pivot = tcol_vec[p]; #ifdef GLP_DEBUG xassert(pivot != 0.0); #endif for (pos = 1; pos <= tcol_nnz; pos++) { i = tcol_ind[pos]; #ifdef GLP_DEBUG xassert(1 <= i && i <= m); #endif k = head[i]; #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif /* skip xB[p] */ if (i == p) continue; /* skip free basic variable */ if (type[head[i]] == GLP_FR) { #ifdef GLP_DEBUG xassert(gamma[i] == 1.0); #endif continue; } /* compute gamma[i] for the adjacent basis */ t = tcol_vec[i] / pivot; t1 = gamma[i] + t * t * gamma_p + 2.0 * t * u[i]; t2 = (refsp[k] ? 1.0 : 0.0) + eta_p * t * t; gamma[i] = (t1 >= t2 ? t1 : t2); /* (though gamma[i] can be exact zero, because the reference space does not include non-basic fixed variables) */ if (gamma[i] < DBL_EPSILON) gamma[i] = DBL_EPSILON; } /* compute gamma[p] for the adjacent basis */ if (type[head[m+q]] == GLP_FR) gamma[p] = 1.0; else { gamma[p] = gamma_p / (pivot * pivot); if (gamma[p] < DBL_EPSILON) gamma[p] = DBL_EPSILON; } /* if xB[p], which becomes xN[q] in the adjacent basis, is fixed and belongs to the reference space, remove it from there, and change all gamma's appropriately */ k = head[p]; if (type[k] == GLP_FX && refsp[k]) { refsp[k] = 0; for (pos = 1; pos <= tcol_nnz; pos++) { i = tcol_ind[pos]; if (i == p) { if (type[head[m+q]] == GLP_FR) continue; t = 1.0 / tcol_vec[p]; } else { if (type[head[i]] == GLP_FR) continue; t = tcol_vec[i] / tcol_vec[p]; } gamma[i] -= t * t; if (gamma[i] < DBL_EPSILON) gamma[i] = DBL_EPSILON; } } return; } #if 1 /* copied from primal */ /*********************************************************************** * err_in_bbar - compute maximal relative error in primal solution * * This routine returns maximal relative error: * * max |beta[i] - bbar[i]| / (1 + |beta[i]|), * * where beta and bbar are, respectively, directly computed and the * current (updated) values of basic variables. * * NOTE: The routine is intended only for debugginig purposes. */ static double err_in_bbar(struct csa *csa) { int m = csa->m; double *bbar = csa->bbar; int i; double e, emax, *beta; beta = xcalloc(1+m, sizeof(double)); eval_beta(csa, beta); emax = 0.0; for (i = 1; i <= m; i++) { e = fabs(beta[i] - bbar[i]) / (1.0 + fabs(beta[i])); if (emax < e) emax = e; } xfree(beta); return emax; } #endif #if 1 /* copied from primal */ /*********************************************************************** * err_in_cbar - compute maximal relative error in dual solution * * This routine returns maximal relative error: * * max |cost[j] - cbar[j]| / (1 + |cost[j]|), * * where cost and cbar are, respectively, directly computed and the * current (updated) reduced costs of non-basic non-fixed variables. * * NOTE: The routine is intended only for debugginig purposes. */ static double err_in_cbar(struct csa *csa) { int m = csa->m; int n = csa->n; char *stat = csa->stat; double *cbar = csa->cbar; int j; double e, emax, cost, *pi; pi = xcalloc(1+m, sizeof(double)); eval_pi(csa, pi); emax = 0.0; for (j = 1; j <= n; j++) { if (stat[j] == GLP_NS) continue; cost = eval_cost(csa, pi, j); e = fabs(cost - cbar[j]) / (1.0 + fabs(cost)); if (emax < e) emax = e; } xfree(pi); return emax; } #endif /*********************************************************************** * err_in_gamma - compute maximal relative error in steepest edge cff. * * This routine returns maximal relative error: * * max |gamma'[j] - gamma[j]| / (1 + |gamma'[j]), * * where gamma'[j] and gamma[j] are, respectively, directly computed * and the current (updated) steepest edge coefficients for non-basic * non-fixed variable x[j]. * * NOTE: The routine is intended only for debugginig purposes. */ static double err_in_gamma(struct csa *csa) { int m = csa->m; char *type = csa->type; int *head = csa->head; double *gamma = csa->gamma; double *exact = csa->work4; int i; double e, emax, temp; eval_gamma(csa, exact); emax = 0.0; for (i = 1; i <= m; i++) { if (type[head[i]] == GLP_FR) { xassert(gamma[i] == 1.0); xassert(exact[i] == 1.0); continue; } temp = exact[i]; e = fabs(temp - gamma[i]) / (1.0 + fabs(temp)); if (emax < e) emax = e; } return emax; } /*********************************************************************** * change_basis - change basis header * * This routine changes the basis header to make it corresponding to * the adjacent basis. */ static void change_basis(struct csa *csa) { int m = csa->m; #ifdef GLP_DEBUG int n = csa->n; #endif char *type = csa->type; int *head = csa->head; #if 1 /* 06/IV-2009 */ int *bind = csa->bind; #endif char *stat = csa->stat; int p = csa->p; double delta = csa->delta; int q = csa->q; int k; /* xB[p] leaves the basis, xN[q] enters the basis */ #ifdef GLP_DEBUG xassert(1 <= p && p <= m); xassert(1 <= q && q <= n); #endif /* xB[p] <-> xN[q] */ k = head[p], head[p] = head[m+q], head[m+q] = k; #if 1 /* 06/IV-2009 */ bind[head[p]] = p, bind[head[m+q]] = m + q; #endif if (type[k] == GLP_FX) stat[q] = GLP_NS; else if (delta > 0.0) { #ifdef GLP_DEBUG xassert(type[k] == GLP_LO || type[k] == GLP_DB); #endif stat[q] = GLP_NL; } else /* delta < 0.0 */ { #ifdef GLP_DEBUG xassert(type[k] == GLP_UP || type[k] == GLP_DB); #endif stat[q] = GLP_NU; } return; } /*********************************************************************** * check_feas - check dual feasibility of basic solution * * If the current basic solution is dual feasible within a tolerance, * this routine returns zero, otherwise it returns non-zero. */ static int check_feas(struct csa *csa, double tol_dj) { int m = csa->m; int n = csa->n; char *orig_type = csa->orig_type; int *head = csa->head; double *cbar = csa->cbar; int j, k; for (j = 1; j <= n; j++) { k = head[m+j]; /* x[k] = xN[j] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif if (cbar[j] < - tol_dj) if (orig_type[k] == GLP_LO || orig_type[k] == GLP_FR) return 1; if (cbar[j] > + tol_dj) if (orig_type[k] == GLP_UP || orig_type[k] == GLP_FR) return 1; } return 0; } /*********************************************************************** * set_aux_bnds - assign auxiliary bounds to variables * * This routine assigns auxiliary bounds to variables to construct an * LP problem solved on phase I. */ static void set_aux_bnds(struct csa *csa) { int m = csa->m; int n = csa->n; char *type = csa->type; double *lb = csa->lb; double *ub = csa->ub; char *orig_type = csa->orig_type; int *head = csa->head; char *stat = csa->stat; double *cbar = csa->cbar; int j, k; for (k = 1; k <= m+n; k++) { switch (orig_type[k]) { case GLP_FR: #if 0 type[k] = GLP_DB, lb[k] = -1.0, ub[k] = +1.0; #else /* to force free variables to enter the basis */ type[k] = GLP_DB, lb[k] = -1e3, ub[k] = +1e3; #endif break; case GLP_LO: type[k] = GLP_DB, lb[k] = 0.0, ub[k] = +1.0; break; case GLP_UP: type[k] = GLP_DB, lb[k] = -1.0, ub[k] = 0.0; break; case GLP_DB: case GLP_FX: type[k] = GLP_FX, lb[k] = ub[k] = 0.0; break; default: xassert(orig_type != orig_type); } } for (j = 1; j <= n; j++) { k = head[m+j]; /* x[k] = xN[j] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif if (type[k] == GLP_FX) stat[j] = GLP_NS; else if (cbar[j] >= 0.0) stat[j] = GLP_NL; else stat[j] = GLP_NU; } return; } /*********************************************************************** * set_orig_bnds - restore original bounds of variables * * This routine restores original types and bounds of variables and * determines statuses of non-basic variables assuming that the current * basis is dual feasible. */ static void set_orig_bnds(struct csa *csa) { int m = csa->m; int n = csa->n; char *type = csa->type; double *lb = csa->lb; double *ub = csa->ub; char *orig_type = csa->orig_type; double *orig_lb = csa->orig_lb; double *orig_ub = csa->orig_ub; int *head = csa->head; char *stat = csa->stat; double *cbar = csa->cbar; int j, k; memcpy(&type[1], &orig_type[1], (m+n) * sizeof(char)); memcpy(&lb[1], &orig_lb[1], (m+n) * sizeof(double)); memcpy(&ub[1], &orig_ub[1], (m+n) * sizeof(double)); for (j = 1; j <= n; j++) { k = head[m+j]; /* x[k] = xN[j] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif switch (type[k]) { case GLP_FR: stat[j] = GLP_NF; break; case GLP_LO: stat[j] = GLP_NL; break; case GLP_UP: stat[j] = GLP_NU; break; case GLP_DB: if (cbar[j] >= +DBL_EPSILON) stat[j] = GLP_NL; else if (cbar[j] <= -DBL_EPSILON) stat[j] = GLP_NU; else if (fabs(lb[k]) <= fabs(ub[k])) stat[j] = GLP_NL; else stat[j] = GLP_NU; break; case GLP_FX: stat[j] = GLP_NS; break; default: xassert(type != type); } } return; } /*********************************************************************** * check_stab - check numerical stability of basic solution * * If the current basic solution is dual feasible within a tolerance, * this routine returns zero, otherwise it returns non-zero. */ static int check_stab(struct csa *csa, double tol_dj) { int n = csa->n; char *stat = csa->stat; double *cbar = csa->cbar; int j; for (j = 1; j <= n; j++) { if (cbar[j] < - tol_dj) if (stat[j] == GLP_NL || stat[j] == GLP_NF) return 1; if (cbar[j] > + tol_dj) if (stat[j] == GLP_NU || stat[j] == GLP_NF) return 1; } return 0; } #if 1 /* copied from primal */ /*********************************************************************** * eval_obj - compute original objective function * * This routine computes the current value of the original objective * function. */ static double eval_obj(struct csa *csa) { int m = csa->m; int n = csa->n; double *obj = csa->obj; int *head = csa->head; double *bbar = csa->bbar; int i, j, k; double sum; sum = obj[0]; /* walk through the list of basic variables */ for (i = 1; i <= m; i++) { k = head[i]; /* x[k] = xB[i] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif if (k > m) sum += obj[k-m] * bbar[i]; } /* walk through the list of non-basic variables */ for (j = 1; j <= n; j++) { k = head[m+j]; /* x[k] = xN[j] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif if (k > m) sum += obj[k-m] * get_xN(csa, j); } return sum; } #endif /*********************************************************************** * display - display the search progress * * This routine displays some information about the search progress. */ static void display(struct csa *csa, const glp_smcp *parm, int spec) { int m = csa->m; int n = csa->n; double *coef = csa->coef; char *orig_type = csa->orig_type; int *head = csa->head; char *stat = csa->stat; int phase = csa->phase; double *bbar = csa->bbar; double *cbar = csa->cbar; int i, j, cnt; double sum; if (parm->msg_lev < GLP_MSG_ON) goto skip; if (parm->out_dly > 0 && 1000.0 * xdifftime(xtime(), csa->tm_beg) < parm->out_dly) goto skip; if (csa->it_cnt == csa->it_dpy) goto skip; if (!spec && csa->it_cnt % parm->out_frq != 0) goto skip; /* compute the sum of dual infeasibilities */ sum = 0.0; if (phase == 1) { for (i = 1; i <= m; i++) sum -= coef[head[i]] * bbar[i]; for (j = 1; j <= n; j++) sum -= coef[head[m+j]] * get_xN(csa, j); } else { for (j = 1; j <= n; j++) { if (cbar[j] < 0.0) if (stat[j] == GLP_NL || stat[j] == GLP_NF) sum -= cbar[j]; if (cbar[j] > 0.0) if (stat[j] == GLP_NU || stat[j] == GLP_NF) sum += cbar[j]; } } /* determine the number of basic fixed variables */ cnt = 0; for (i = 1; i <= m; i++) if (orig_type[head[i]] == GLP_FX) cnt++; if (csa->phase == 1) xprintf(" %6d: %24s infeas = %10.3e (%d)\n", csa->it_cnt, "", sum, cnt); else xprintf("|%6d: obj = %17.9e infeas = %10.3e (%d)\n", csa->it_cnt, eval_obj(csa), sum, cnt); csa->it_dpy = csa->it_cnt; skip: return; } #if 1 /* copied from primal */ /*********************************************************************** * store_sol - store basic solution back to the problem object * * This routine stores basic solution components back to the problem * object. */ static void store_sol(struct csa *csa, glp_prob *lp, int p_stat, int d_stat, int ray) { int m = csa->m; int n = csa->n; double zeta = csa->zeta; int *head = csa->head; char *stat = csa->stat; double *bbar = csa->bbar; double *cbar = csa->cbar; int i, j, k; #ifdef GLP_DEBUG xassert(lp->m == m); xassert(lp->n == n); #endif /* basis factorization */ #ifdef GLP_DEBUG xassert(!lp->valid && lp->bfd == NULL); xassert(csa->valid && csa->bfd != NULL); #endif lp->valid = 1, csa->valid = 0; lp->bfd = csa->bfd, csa->bfd = NULL; memcpy(&lp->head[1], &head[1], m * sizeof(int)); /* basic solution status */ lp->pbs_stat = p_stat; lp->dbs_stat = d_stat; /* objective function value */ lp->obj_val = eval_obj(csa); /* simplex iteration count */ lp->it_cnt = csa->it_cnt; /* unbounded ray */ lp->some = ray; /* basic variables */ for (i = 1; i <= m; i++) { k = head[i]; /* x[k] = xB[i] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif if (k <= m) { GLPROW *row = lp->row[k]; row->stat = GLP_BS; row->bind = i; row->prim = bbar[i] / row->rii; row->dual = 0.0; } else { GLPCOL *col = lp->col[k-m]; col->stat = GLP_BS; col->bind = i; col->prim = bbar[i] * col->sjj; col->dual = 0.0; } } /* non-basic variables */ for (j = 1; j <= n; j++) { k = head[m+j]; /* x[k] = xN[j] */ #ifdef GLP_DEBUG xassert(1 <= k && k <= m+n); #endif if (k <= m) { GLPROW *row = lp->row[k]; row->stat = stat[j]; row->bind = 0; #if 0 row->prim = get_xN(csa, j) / row->rii; #else switch (stat[j]) { case GLP_NL: row->prim = row->lb; break; case GLP_NU: row->prim = row->ub; break; case GLP_NF: row->prim = 0.0; break; case GLP_NS: row->prim = row->lb; break; default: xassert(stat != stat); } #endif row->dual = (cbar[j] * row->rii) / zeta; } else { GLPCOL *col = lp->col[k-m]; col->stat = stat[j]; col->bind = 0; #if 0 col->prim = get_xN(csa, j) * col->sjj; #else switch (stat[j]) { case GLP_NL: col->prim = col->lb; break; case GLP_NU: col->prim = col->ub; break; case GLP_NF: col->prim = 0.0; break; case GLP_NS: col->prim = col->lb; break; default: xassert(stat != stat); } #endif col->dual = (cbar[j] / col->sjj) / zeta; } } return; } #endif /*********************************************************************** * free_csa - deallocate common storage area * * This routine frees all the memory allocated to arrays in the common * storage area (CSA). */ static void free_csa(struct csa *csa) { xfree(csa->type); xfree(csa->lb); xfree(csa->ub); xfree(csa->coef); xfree(csa->orig_type); xfree(csa->orig_lb); xfree(csa->orig_ub); xfree(csa->obj); xfree(csa->A_ptr); xfree(csa->A_ind); xfree(csa->A_val); #if 1 /* 06/IV-2009 */ xfree(csa->AT_ptr); xfree(csa->AT_ind); xfree(csa->AT_val); #endif xfree(csa->head); #if 1 /* 06/IV-2009 */ xfree(csa->bind); #endif xfree(csa->stat); #if 0 /* 06/IV-2009 */ xfree(csa->N_ptr); xfree(csa->N_len); xfree(csa->N_ind); xfree(csa->N_val); #endif xfree(csa->bbar); xfree(csa->cbar); xfree(csa->refsp); xfree(csa->gamma); xfree(csa->trow_ind); xfree(csa->trow_vec); #ifdef GLP_LONG_STEP /* 07/IV-2009 */ xfree(csa->bkpt); #endif xfree(csa->tcol_ind); xfree(csa->tcol_vec); xfree(csa->work1); xfree(csa->work2); xfree(csa->work3); xfree(csa->work4); xfree(csa); return; } /*********************************************************************** * spx_dual - core LP solver based on the dual simplex method * * SYNOPSIS * * #include "glpspx.h" * int spx_dual(glp_prob *lp, const glp_smcp *parm); * * DESCRIPTION * * The routine spx_dual is a core LP solver based on the two-phase dual * simplex method. * * RETURNS * * 0 LP instance has been successfully solved. * * GLP_EOBJLL * Objective lower limit has been reached (maximization). * * GLP_EOBJUL * Objective upper limit has been reached (minimization). * * GLP_EITLIM * Iteration limit has been exhausted. * * GLP_ETMLIM * Time limit has been exhausted. * * GLP_EFAIL * The solver failed to solve LP instance. */ int spx_dual(glp_prob *lp, const glp_smcp *parm) { struct csa *csa; int binv_st = 2; /* status of basis matrix factorization: 0 - invalid; 1 - just computed; 2 - updated */ int bbar_st = 0; /* status of primal values of basic variables: 0 - invalid; 1 - just computed; 2 - updated */ int cbar_st = 0; /* status of reduced costs of non-basic variables: 0 - invalid; 1 - just computed; 2 - updated */ int rigorous = 0; /* rigorous mode flag; this flag is used to enable iterative refinement on computing pivot rows and columns of the simplex table */ int check = 0; int p_stat, d_stat, ret; /* allocate and initialize the common storage area */ csa = alloc_csa(lp); init_csa(csa, lp); if (parm->msg_lev >= GLP_MSG_DBG) xprintf("Objective scale factor = %g\n", csa->zeta); loop: /* main loop starts here */ /* compute factorization of the basis matrix */ if (binv_st == 0) { ret = invert_B(csa); if (ret != 0) { if (parm->msg_lev >= GLP_MSG_ERR) { xprintf("Error: unable to factorize the basis matrix (%d" ")\n", ret); xprintf("Sorry, basis recovery procedure not implemented" " yet\n"); } xassert(!lp->valid && lp->bfd == NULL); lp->bfd = csa->bfd, csa->bfd = NULL; lp->pbs_stat = lp->dbs_stat = GLP_UNDEF; lp->obj_val = 0.0; lp->it_cnt = csa->it_cnt; lp->some = 0; ret = GLP_EFAIL; goto done; } csa->valid = 1; binv_st = 1; /* just computed */ /* invalidate basic solution components */ bbar_st = cbar_st = 0; } /* compute reduced costs of non-basic variables */ if (cbar_st == 0) { eval_cbar(csa); cbar_st = 1; /* just computed */ /* determine the search phase, if not determined yet */ if (csa->phase == 0) { if (check_feas(csa, 0.90 * parm->tol_dj) != 0) { /* current basic solution is dual infeasible */ /* start searching for dual feasible solution */ csa->phase = 1; set_aux_bnds(csa); } else { /* current basic solution is dual feasible */ /* start searching for optimal solution */ csa->phase = 2; set_orig_bnds(csa); } xassert(check_stab(csa, parm->tol_dj) == 0); /* some non-basic double-bounded variables might become fixed (on phase I) or vice versa (on phase II) */ #if 0 /* 06/IV-2009 */ build_N(csa); #endif csa->refct = 0; /* bounds of non-basic variables have been changed, so invalidate primal values */ bbar_st = 0; } /* make sure that the current basic solution remains dual feasible */ if (check_stab(csa, parm->tol_dj) != 0) { if (parm->msg_lev >= GLP_MSG_ERR) xprintf("Warning: numerical instability (dual simplex, p" "hase %s)\n", csa->phase == 1 ? "I" : "II"); #if 1 if (parm->meth == GLP_DUALP) { store_sol(csa, lp, GLP_UNDEF, GLP_UNDEF, 0); ret = GLP_EFAIL; goto done; } #endif /* restart the search */ csa->phase = 0; binv_st = 0; rigorous = 5; goto loop; } } xassert(csa->phase == 1 || csa->phase == 2); /* on phase I we do not need to wait until the current basic solution becomes primal feasible; it is sufficient to make sure that all reduced costs have correct signs */ if (csa->phase == 1 && check_feas(csa, parm->tol_dj) == 0) { /* the current basis is dual feasible; switch to phase II */ display(csa, parm, 1); csa->phase = 2; if (cbar_st != 1) { eval_cbar(csa); cbar_st = 1; } set_orig_bnds(csa); #if 0 /* 06/IV-2009 */ build_N(csa); #endif csa->refct = 0; bbar_st = 0; } /* compute primal values of basic variables */ if (bbar_st == 0) { eval_bbar(csa); if (csa->phase == 2) csa->bbar[0] = eval_obj(csa); bbar_st = 1; /* just computed */ } /* redefine the reference space, if required */ switch (parm->pricing) { case GLP_PT_STD: break; case GLP_PT_PSE: if (csa->refct == 0) reset_refsp(csa); break; default: xassert(parm != parm); } /* at this point the basis factorization and all basic solution components are valid */ xassert(binv_st && bbar_st && cbar_st); /* check accuracy of current basic solution components (only for debugging) */ if (check) { double e_bbar = err_in_bbar(csa); double e_cbar = err_in_cbar(csa); double e_gamma = (parm->pricing == GLP_PT_PSE ? err_in_gamma(csa) : 0.0); xprintf("e_bbar = %10.3e; e_cbar = %10.3e; e_gamma = %10.3e\n", e_bbar, e_cbar, e_gamma); xassert(e_bbar <= 1e-5 && e_cbar <= 1e-5 && e_gamma <= 1e-3); } /* if the objective has to be maximized, check if it has reached its lower limit */ if (csa->phase == 2 && csa->zeta < 0.0 && parm->obj_ll > -DBL_MAX && csa->bbar[0] <= parm->obj_ll) { if (bbar_st != 1 || cbar_st != 1) { if (bbar_st != 1) bbar_st = 0; if (cbar_st != 1) cbar_st = 0; goto loop; } display(csa, parm, 1); if (parm->msg_lev >= GLP_MSG_ALL) xprintf("OBJECTIVE LOWER LIMIT REACHED; SEARCH TERMINATED\n" ); store_sol(csa, lp, GLP_INFEAS, GLP_FEAS, 0); ret = GLP_EOBJLL; goto done; } /* if the objective has to be minimized, check if it has reached its upper limit */ if (csa->phase == 2 && csa->zeta > 0.0 && parm->obj_ul < +DBL_MAX && csa->bbar[0] >= parm->obj_ul) { if (bbar_st != 1 || cbar_st != 1) { if (bbar_st != 1) bbar_st = 0; if (cbar_st != 1) cbar_st = 0; goto loop; } display(csa, parm, 1); if (parm->msg_lev >= GLP_MSG_ALL) xprintf("OBJECTIVE UPPER LIMIT REACHED; SEARCH TERMINATED\n" ); store_sol(csa, lp, GLP_INFEAS, GLP_FEAS, 0); ret = GLP_EOBJUL; goto done; } /* check if the iteration limit has been exhausted */ if (parm->it_lim < INT_MAX && csa->it_cnt - csa->it_beg >= parm->it_lim) { if (csa->phase == 2 && bbar_st != 1 || cbar_st != 1) { if (csa->phase == 2 && bbar_st != 1) bbar_st = 0; if (cbar_st != 1) cbar_st = 0; goto loop; } display(csa, parm, 1); if (parm->msg_lev >= GLP_MSG_ALL) xprintf("ITERATION LIMIT EXCEEDED; SEARCH TERMINATED\n"); switch (csa->phase) { case 1: d_stat = GLP_INFEAS; set_orig_bnds(csa); eval_bbar(csa); break; case 2: d_stat = GLP_FEAS; break; default: xassert(csa != csa); } store_sol(csa, lp, GLP_INFEAS, d_stat, 0); ret = GLP_EITLIM; goto done; } /* check if the time limit has been exhausted */ if (parm->tm_lim < INT_MAX && 1000.0 * xdifftime(xtime(), csa->tm_beg) >= parm->tm_lim) { if (csa->phase == 2 && bbar_st != 1 || cbar_st != 1) { if (csa->phase == 2 && bbar_st != 1) bbar_st = 0; if (cbar_st != 1) cbar_st = 0; goto loop; } display(csa, parm, 1); if (parm->msg_lev >= GLP_MSG_ALL) xprintf("TIME LIMIT EXCEEDED; SEARCH TERMINATED\n"); switch (csa->phase) { case 1: d_stat = GLP_INFEAS; set_orig_bnds(csa); eval_bbar(csa); break; case 2: d_stat = GLP_FEAS; break; default: xassert(csa != csa); } store_sol(csa, lp, GLP_INFEAS, d_stat, 0); ret = GLP_ETMLIM; goto done; } /* display the search progress */ display(csa, parm, 0); /* choose basic variable xB[p] */ chuzr(csa, parm->tol_bnd); if (csa->p == 0) { if (bbar_st != 1 || cbar_st != 1) { if (bbar_st != 1) bbar_st = 0; if (cbar_st != 1) cbar_st = 0; goto loop; } display(csa, parm, 1); switch (csa->phase) { case 1: if (parm->msg_lev >= GLP_MSG_ALL) xprintf("PROBLEM HAS NO DUAL FEASIBLE SOLUTION\n"); set_orig_bnds(csa); eval_bbar(csa); p_stat = GLP_INFEAS, d_stat = GLP_NOFEAS; break; case 2: if (parm->msg_lev >= GLP_MSG_ALL) xprintf("OPTIMAL SOLUTION FOUND\n"); p_stat = d_stat = GLP_FEAS; break; default: xassert(csa != csa); } store_sol(csa, lp, p_stat, d_stat, 0); ret = 0; goto done; } /* compute pivot row of the simplex table */ { double *rho = csa->work4; eval_rho(csa, rho); if (rigorous) refine_rho(csa, rho); eval_trow(csa, rho); sort_trow(csa, parm->tol_bnd); } /* unlike primal simplex there is no need to check accuracy of the primal value of xB[p] (which might be computed using the pivot row), since bbar is a result of FTRAN */ #ifdef GLP_LONG_STEP /* 07/IV-2009 */ long_step(csa); if (csa->nbps > 0) { csa->q = csa->bkpt[csa->nbps].j; if (csa->delta > 0.0) csa->new_dq = + csa->bkpt[csa->nbps].t; else csa->new_dq = - csa->bkpt[csa->nbps].t; } else #endif /* choose non-basic variable xN[q] */ switch (parm->r_test) { case GLP_RT_STD: chuzc(csa, 0.0); break; case GLP_RT_HAR: chuzc(csa, 0.30 * parm->tol_dj); break; default: xassert(parm != parm); } if (csa->q == 0) { if (bbar_st != 1 || cbar_st != 1 || !rigorous) { if (bbar_st != 1) bbar_st = 0; if (cbar_st != 1) cbar_st = 0; rigorous = 1; goto loop; } display(csa, parm, 1); switch (csa->phase) { case 1: if (parm->msg_lev >= GLP_MSG_ERR) xprintf("Error: unable to choose basic variable on ph" "ase I\n"); xassert(!lp->valid && lp->bfd == NULL); lp->bfd = csa->bfd, csa->bfd = NULL; lp->pbs_stat = lp->dbs_stat = GLP_UNDEF; lp->obj_val = 0.0; lp->it_cnt = csa->it_cnt; lp->some = 0; ret = GLP_EFAIL; break; case 2: if (parm->msg_lev >= GLP_MSG_ALL) xprintf("PROBLEM HAS NO FEASIBLE SOLUTION\n"); store_sol(csa, lp, GLP_NOFEAS, GLP_FEAS, csa->head[csa->p]); ret = 0; break; default: xassert(csa != csa); } goto done; } /* check if the pivot element is acceptable */ { double piv = csa->trow_vec[csa->q]; double eps = 1e-5 * (1.0 + 0.01 * csa->trow_max); if (fabs(piv) < eps) { if (parm->msg_lev >= GLP_MSG_DBG) xprintf("piv = %.12g; eps = %g\n", piv, eps); if (!rigorous) { rigorous = 5; goto loop; } } } /* now xN[q] and xB[p] have been chosen anyhow */ /* compute pivot column of the simplex table */ eval_tcol(csa); if (rigorous) refine_tcol(csa); /* accuracy check based on the pivot element */ { double piv1 = csa->tcol_vec[csa->p]; /* more accurate */ double piv2 = csa->trow_vec[csa->q]; /* less accurate */ xassert(piv1 != 0.0); if (fabs(piv1 - piv2) > 1e-8 * (1.0 + fabs(piv1)) || !(piv1 > 0.0 && piv2 > 0.0 || piv1 < 0.0 && piv2 < 0.0)) { if (parm->msg_lev >= GLP_MSG_DBG) xprintf("piv1 = %.12g; piv2 = %.12g\n", piv1, piv2); if (binv_st != 1 || !rigorous) { if (binv_st != 1) binv_st = 0; rigorous = 5; goto loop; } /* (not a good idea; should be revised later) */ if (csa->tcol_vec[csa->p] == 0.0) { csa->tcol_nnz++; xassert(csa->tcol_nnz <= csa->m); csa->tcol_ind[csa->tcol_nnz] = csa->p; } csa->tcol_vec[csa->p] = piv2; } } /* update primal values of basic variables */ #ifdef GLP_LONG_STEP /* 07/IV-2009 */ if (csa->nbps > 0) { int kk, j, k; for (kk = 1; kk < csa->nbps; kk++) { if (csa->bkpt[kk].t >= csa->bkpt[csa->nbps].t) continue; j = csa->bkpt[kk].j; k = csa->head[csa->m + j]; xassert(csa->type[k] == GLP_DB); if (csa->stat[j] == GLP_NL) csa->stat[j] = GLP_NU; else csa->stat[j] = GLP_NL; } } bbar_st = 0; #else update_bbar(csa); if (csa->phase == 2) csa->bbar[0] += (csa->cbar[csa->q] / csa->zeta) * (csa->delta / csa->tcol_vec[csa->p]); bbar_st = 2; /* updated */ #endif /* update reduced costs of non-basic variables */ update_cbar(csa); cbar_st = 2; /* updated */ /* update steepest edge coefficients */ switch (parm->pricing) { case GLP_PT_STD: break; case GLP_PT_PSE: if (csa->refct > 0) update_gamma(csa); break; default: xassert(parm != parm); } /* update factorization of the basis matrix */ ret = update_B(csa, csa->p, csa->head[csa->m+csa->q]); if (ret == 0) binv_st = 2; /* updated */ else { csa->valid = 0; binv_st = 0; /* invalid */ } #if 0 /* 06/IV-2009 */ /* update matrix N */ del_N_col(csa, csa->q, csa->head[csa->m+csa->q]); if (csa->type[csa->head[csa->p]] != GLP_FX) add_N_col(csa, csa->q, csa->head[csa->p]); #endif /* change the basis header */ change_basis(csa); /* iteration complete */ csa->it_cnt++; if (rigorous > 0) rigorous--; goto loop; done: /* deallocate the common storage area */ free_csa(csa); /* return to the calling program */ return ret; } /* eof */ praat-6.0.04/external/glpk/glpsql.c000066400000000000000000001311711261542461700171510ustar00rootroot00000000000000/* glpsql.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Author: Heinrich Schuchardt . * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifdef HAVE_CONFIG_H #include #endif #include "glpmpl.h" #include "glpsql.h" #ifdef ODBC_DLNAME #define HAVE_ODBC #define libodbc ODBC_DLNAME #define h_odbc (get_env_ptr()->h_odbc) #endif #ifdef MYSQL_DLNAME #define HAVE_MYSQL #define libmysql MYSQL_DLNAME #define h_mysql (get_env_ptr()->h_mysql) #endif static void *db_iodbc_open_int(TABDCA *dca, int mode, const char **sqllines); static void *db_mysql_open_int(TABDCA *dca, int mode, const char **sqllines); /**********************************************************************/ #if defined(HAVE_ODBC) || defined(HAVE_MYSQL) #define SQL_FIELD_MAX 100 /* maximal field count */ #define SQL_FDLEN_MAX 255 /* maximal field length */ /*********************************************************************** * NAME * * args_concat - concatenate arguments * * SYNOPSIS * * static char **args_concat(TABDCA *dca); * * DESCRIPTION * * The arguments passed in dca are SQL statements. A SQL statement may * be split over multiple arguments. The last argument of a SQL * statement will be terminated with a semilocon. Each SQL statement is * merged into a single zero terminated string. Boundaries between * arguments are replaced by space. * * RETURNS * * Buffer with SQL statements */ static char **args_concat(TABDCA *dca) { const char *arg; int i; int j; int j0; int j1; int len; int lentot; int narg; int nline = 0; void *ret; char **sqllines = NULL; narg = mpl_tab_num_args(dca); /* The SQL statements start with argument 3. */ if (narg < 3) return NULL; /* Count the SQL statements */ for (j = 3; j <= narg; j++) { arg = mpl_tab_get_arg(dca, j); len = strlen(arg); if (arg[len-1] == ';' || j == narg) nline ++; } /* Allocate string buffer. */ sqllines = (char **) xmalloc((nline+1) * sizeof(char **)); /* Join arguments */ sqllines[0] = NULL; j0 = 3; i = 0; lentot = 0; for (j = 3; j <= narg; j++) { arg = mpl_tab_get_arg(dca, j); len = strlen(arg); lentot += len; if (arg[len-1] == ';' || j == narg) { /* Join arguments for a single SQL statement */ sqllines[i] = xmalloc(lentot+1); sqllines[i+1] = NULL; sqllines[i][0] = 0x00; for (j1 = j0; j1 <= j; j1++) { if(j1>j0) strcat(sqllines[i], " "); strcat(sqllines[i], mpl_tab_get_arg(dca, j1)); } len = strlen(sqllines[i]); if (sqllines[i][len-1] == ';') sqllines[i][len-1] = 0x00; j0 = j+1; i++; lentot = 0; } } return sqllines; } /*********************************************************************** * NAME * * free_buffer - free multiline string buffer * * SYNOPSIS * * static void free_buffer(char **buf); * * DESCRIPTION * * buf is a list of strings terminated by NULL. * The memory for the strings and for the list is released. */ static void free_buffer(char **buf) { int i; for(i = 0; buf[i] != NULL; i++) xfree(buf[i]); xfree(buf); } static int db_escaped_string_length(const char* from) /* length of escaped string */ { int count; const char *pointer; for (pointer = from, count = 0; *pointer != (char) '\0'; pointer++, count++) { switch (*pointer) { case '\'': count++; break; } } return count; } static int db_escape_string (char *to, const char *from) /* escape string*/ { const char *source = from; char *target = to; unsigned int remaining; remaining = strlen(from); if (to == NULL) to = (char *) (from + remaining); while (remaining > 0) { switch (*source) { case '\'': *target = '\''; target++; *target = '\''; break; default: *target = *source; } source++; target++; remaining--; } /* Write the terminating NUL character. */ *target = '\0'; return target - to; } static char *db_generate_select_stmt(TABDCA *dca) /* generate select statement */ { char *arg; char const *field; char *query; int j; int narg; int nf; int total; total = 50; nf = mpl_tab_num_flds(dca); narg = mpl_tab_num_args(dca); for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++) { field = mpl_tab_get_name(dca, j); total += strlen(field); total += 2; } arg = (char *) mpl_tab_get_arg(dca, narg); total += strlen(arg); query = xmalloc( total * sizeof(char)); strcpy (query, "SELECT "); for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++) { field = mpl_tab_get_name(dca, j); strcat(query, field); if ( j < nf ) strcat(query, ", "); } strcat(query, " FROM "); strcat(query, arg); return query; } static char *db_generate_insert_stmt(TABDCA *dca) /* generate insert statement */ { char *arg; char const *field; char *query; int j; int narg; int nf; int total; total = 50; nf = mpl_tab_num_flds(dca); narg = mpl_tab_num_args(dca); for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++) { field = mpl_tab_get_name(dca, j); total += strlen(field); total += 5; } arg = (char *) mpl_tab_get_arg(dca, narg); total += strlen(arg); query = xmalloc( (total+1) * sizeof(char)); strcpy (query, "INSERT INTO "); strcat(query, arg); strcat(query, " ( "); for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++) { field = mpl_tab_get_name(dca, j); strcat(query, field); if ( j < nf ) strcat(query, ", "); } strcat(query, " ) VALUES ( "); for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++) { strcat(query, "?"); if ( j < nf ) strcat(query, ", "); } strcat(query, " )"); return query; } #endif /**********************************************************************/ #ifndef HAVE_ODBC void *db_iodbc_open(TABDCA *dca, int mode) { xassert(dca == dca); xassert(mode == mode); xprintf("iODBC table driver not supported\n"); return NULL; } int db_iodbc_read(TABDCA *dca, void *link) { xassert(dca != dca); xassert(link != link); return 0; } int db_iodbc_write(TABDCA *dca, void *link) { xassert(dca != dca); xassert(link != link); return 0; } int db_iodbc_close(TABDCA *dca, void *link) { xassert(dca != dca); xassert(link != link); return 0; } #else #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__WOE__) #include #endif #include #include struct db_odbc { int mode; /*'R' = Read, 'W' = Write*/ SQLHDBC hdbc; /*connection handle*/ SQLHENV henv; /*environment handle*/ SQLHSTMT hstmt; /*statement handle*/ SQLSMALLINT nresultcols; /* columns in result*/ SQLULEN collen[SQL_FIELD_MAX+1]; SQLLEN outlen[SQL_FIELD_MAX+1]; SQLSMALLINT coltype[SQL_FIELD_MAX+1]; SQLCHAR data[SQL_FIELD_MAX+1][SQL_FDLEN_MAX+1]; SQLCHAR colname[SQL_FIELD_MAX+1][SQL_FDLEN_MAX+1]; int isnumeric[SQL_FIELD_MAX+1]; int nf; /* number of fields in the csv file */ int ref[1+SQL_FIELD_MAX]; /* ref[k] = k', if k-th field of the csv file corresponds to k'-th field in the table statement; if ref[k] = 0, k-th field of the csv file is ignored */ SQLCHAR *query; /* query generated by db_iodbc_open */ }; SQLRETURN SQL_API dl_SQLAllocHandle ( SQLSMALLINT HandleType, SQLHANDLE InputHandle, SQLHANDLE *OutputHandle) { typedef SQLRETURN SQL_API ep_SQLAllocHandle( SQLSMALLINT HandleType, SQLHANDLE InputHandle, SQLHANDLE *OutputHandle); ep_SQLAllocHandle *fn; fn = (ep_SQLAllocHandle *) xdlsym(h_odbc, "SQLAllocHandle"); xassert(fn != NULL); return (*fn)(HandleType, InputHandle, OutputHandle); } SQLRETURN SQL_API dl_SQLBindCol ( SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, SQLPOINTER TargetValue, SQLLEN BufferLength, SQLLEN *StrLen_or_Ind) { typedef SQLRETURN SQL_API ep_SQLBindCol( SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, SQLPOINTER TargetValue, SQLLEN BufferLength, SQLLEN *StrLen_or_Ind); ep_SQLBindCol *fn; fn = (ep_SQLBindCol *) xdlsym(h_odbc, "SQLBindCol"); xassert(fn != NULL); return (*fn)(StatementHandle, ColumnNumber, TargetType, TargetValue, BufferLength, StrLen_or_Ind); } SQLRETURN SQL_API dl_SQLCloseCursor ( SQLHSTMT StatementHandle) { typedef SQLRETURN SQL_API ep_SQLCloseCursor ( SQLHSTMT StatementHandle); ep_SQLCloseCursor *fn; fn = (ep_SQLCloseCursor *) xdlsym(h_odbc, "SQLCloseCursor"); xassert(fn != NULL); return (*fn)(StatementHandle); } SQLRETURN SQL_API dl_SQLDisconnect ( SQLHDBC ConnectionHandle) { typedef SQLRETURN SQL_API ep_SQLDisconnect( SQLHDBC ConnectionHandle); ep_SQLDisconnect *fn; fn = (ep_SQLDisconnect *) xdlsym(h_odbc, "SQLDisconnect"); xassert(fn != NULL); return (*fn)(ConnectionHandle); } SQLRETURN SQL_API dl_SQLDriverConnect ( SQLHDBC hdbc, SQLHWND hwnd, SQLCHAR *szConnStrIn, SQLSMALLINT cbConnStrIn, SQLCHAR *szConnStrOut, SQLSMALLINT cbConnStrOutMax, SQLSMALLINT *pcbConnStrOut, SQLUSMALLINT fDriverCompletion) { typedef SQLRETURN SQL_API ep_SQLDriverConnect( SQLHDBC hdbc, SQLHWND hwnd, SQLCHAR * szConnStrIn, SQLSMALLINT cbConnStrIn, SQLCHAR * szConnStrOut, SQLSMALLINT cbConnStrOutMax, SQLSMALLINT * pcbConnStrOut, SQLUSMALLINT fDriverCompletion); ep_SQLDriverConnect *fn; fn = (ep_SQLDriverConnect *) xdlsym(h_odbc, "SQLDriverConnect"); xassert(fn != NULL); return (*fn)(hdbc, hwnd, szConnStrIn, cbConnStrIn, szConnStrOut, cbConnStrOutMax, pcbConnStrOut, fDriverCompletion); } SQLRETURN SQL_API dl_SQLEndTran ( SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT CompletionType) { typedef SQLRETURN SQL_API ep_SQLEndTran ( SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT CompletionType); ep_SQLEndTran *fn; fn = (ep_SQLEndTran *) xdlsym(h_odbc, "SQLEndTran"); xassert(fn != NULL); return (*fn)(HandleType, Handle, CompletionType); } SQLRETURN SQL_API dl_SQLExecDirect ( SQLHSTMT StatementHandle, SQLCHAR * StatementText, SQLINTEGER TextLength) { typedef SQLRETURN SQL_API ep_SQLExecDirect ( SQLHSTMT StatementHandle, SQLCHAR * StatementText, SQLINTEGER TextLength); ep_SQLExecDirect *fn; fn = (ep_SQLExecDirect *) xdlsym(h_odbc, "SQLExecDirect"); xassert(fn != NULL); return (*fn)(StatementHandle, StatementText, TextLength); } SQLRETURN SQL_API dl_SQLFetch ( SQLHSTMT StatementHandle) { typedef SQLRETURN SQL_API ep_SQLFetch ( SQLHSTMT StatementHandle); ep_SQLFetch *fn; fn = (ep_SQLFetch*) xdlsym(h_odbc, "SQLFetch"); xassert(fn != NULL); return (*fn)(StatementHandle); } SQLRETURN SQL_API dl_SQLFreeHandle ( SQLSMALLINT HandleType, SQLHANDLE Handle) { typedef SQLRETURN SQL_API ep_SQLFreeHandle ( SQLSMALLINT HandleType, SQLHANDLE Handle); ep_SQLFreeHandle *fn; fn = (ep_SQLFreeHandle *) xdlsym(h_odbc, "SQLFreeHandle"); xassert(fn != NULL); return (*fn)(HandleType, Handle); } SQLRETURN SQL_API dl_SQLDescribeCol ( SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLCHAR * ColumnName, SQLSMALLINT BufferLength, SQLSMALLINT * NameLength, SQLSMALLINT * DataType, SQLULEN * ColumnSize, SQLSMALLINT * DecimalDigits, SQLSMALLINT * Nullable) { typedef SQLRETURN SQL_API ep_SQLDescribeCol ( SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLCHAR *ColumnName, SQLSMALLINT BufferLength, SQLSMALLINT *NameLength, SQLSMALLINT *DataType, SQLULEN *ColumnSize, SQLSMALLINT *DecimalDigits, SQLSMALLINT *Nullable); ep_SQLDescribeCol *fn; fn = (ep_SQLDescribeCol *) xdlsym(h_odbc, "SQLDescribeCol"); xassert(fn != NULL); return (*fn)(StatementHandle, ColumnNumber, ColumnName, BufferLength, NameLength, DataType, ColumnSize, DecimalDigits, Nullable); } SQLRETURN SQL_API dl_SQLGetDiagRec ( SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT RecNumber, SQLCHAR *Sqlstate, SQLINTEGER *NativeError, SQLCHAR *MessageText, SQLSMALLINT BufferLength, SQLSMALLINT *TextLength) { typedef SQLRETURN SQL_API ep_SQLGetDiagRec ( SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT RecNumber, SQLCHAR *Sqlstate, SQLINTEGER *NativeError, SQLCHAR *MessageText, SQLSMALLINT BufferLength, SQLSMALLINT *TextLength); ep_SQLGetDiagRec *fn; fn = (ep_SQLGetDiagRec *) xdlsym(h_odbc, "SQLGetDiagRec"); xassert(fn != NULL); return (*fn)(HandleType, Handle, RecNumber, Sqlstate, NativeError, MessageText, BufferLength, TextLength); } SQLRETURN SQL_API dl_SQLGetInfo ( SQLHDBC ConnectionHandle, SQLUSMALLINT InfoType, SQLPOINTER InfoValue, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength) { typedef SQLRETURN SQL_API ep_SQLGetInfo ( SQLHDBC ConnectionHandle, SQLUSMALLINT InfoType, SQLPOINTER InfoValue, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength); ep_SQLGetInfo *fn; fn = (ep_SQLGetInfo *) xdlsym(h_odbc, "SQLGetInfo"); xassert(fn != NULL); return (*fn)(ConnectionHandle, InfoType, InfoValue, BufferLength, StringLength); } SQLRETURN SQL_API dl_SQLNumResultCols ( SQLHSTMT StatementHandle, SQLSMALLINT *ColumnCount) { typedef SQLRETURN SQL_API ep_SQLNumResultCols ( SQLHSTMT StatementHandle, SQLSMALLINT *ColumnCount); ep_SQLNumResultCols *fn; fn = (ep_SQLNumResultCols *) xdlsym(h_odbc, "SQLNumResultCols"); xassert(fn != NULL); return (*fn)(StatementHandle, ColumnCount); } SQLRETURN SQL_API dl_SQLSetConnectAttr ( SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength) { typedef SQLRETURN SQL_API ep_SQLSetConnectAttr ( SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength); ep_SQLSetConnectAttr *fn; fn = (ep_SQLSetConnectAttr *) xdlsym(h_odbc, "SQLSetConnectAttr"); xassert(fn != NULL); return (*fn)(ConnectionHandle, Attribute, Value, StringLength); } SQLRETURN SQL_API dl_SQLSetEnvAttr ( SQLHENV EnvironmentHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength) { typedef SQLRETURN SQL_API ep_SQLSetEnvAttr ( SQLHENV EnvironmentHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength); ep_SQLSetEnvAttr *fn; fn = (ep_SQLSetEnvAttr *) xdlsym(h_odbc, "SQLSetEnvAttr"); xassert(fn != NULL); return (*fn)(EnvironmentHandle, Attribute, Value, StringLength); } static void extract_error( char *fn, SQLHANDLE handle, SQLSMALLINT type); static int is_numeric( SQLSMALLINT coltype); /*********************************************************************** * NAME * * db_iodbc_open - open connection to ODBC data base * * SYNOPSIS * * #include "glpsql.h" * void *db_iodbc_open(TABDCA *dca, int mode); * * DESCRIPTION * * The routine db_iodbc_open opens a connection to an ODBC data base. * It then executes the sql statements passed. * * In the case of table read the SELECT statement is executed. * * In the case of table write the INSERT statement is prepared. * RETURNS * * The routine returns a pointer to data storage area created. */ void *db_iodbc_open(TABDCA *dca, int mode) { void *ret; char **sqllines; sqllines = args_concat(dca); if (sqllines == NULL) { xprintf("Missing arguments in table statement.\n" "Please, supply table driver, dsn, and query.\n"); return NULL; } ret = db_iodbc_open_int(dca, mode, (const char **) sqllines); free_buffer(sqllines); return ret; } static void *db_iodbc_open_int(TABDCA *dca, int mode, const char **sqllines) { struct db_odbc *sql; SQLRETURN ret; SQLCHAR FAR *dsn; SQLCHAR info[256]; SQLSMALLINT colnamelen; SQLSMALLINT nullable; SQLSMALLINT scale; const char *arg; int narg; int i, j; int total; if (libodbc == NULL) { xprintf("No loader for shared ODBC library available\n"); return NULL; } if (h_odbc == NULL) { h_odbc = xdlopen(libodbc); if (h_odbc == NULL) { xprintf("unable to open library %s\n", libodbc); xprintf("%s\n", xerrmsg()); return NULL; } } sql = (struct db_odbc *) xmalloc(sizeof(struct db_odbc)); if (sql == NULL) return NULL; sql->mode = mode; sql->hdbc = NULL; sql->henv = NULL; sql->hstmt = NULL; sql->query = NULL; narg = mpl_tab_num_args(dca); dsn = (SQLCHAR FAR *) mpl_tab_get_arg(dca, 2); /* allocate an environment handle */ ret = dl_SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &(sql->henv)); /* set attribute to enable application to run as ODBC 3.0 application */ ret = dl_SQLSetEnvAttr(sql->henv, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0); /* allocate a connection handle */ ret = dl_SQLAllocHandle(SQL_HANDLE_DBC, sql->henv, &(sql->hdbc)); /* connect */ ret = dl_SQLDriverConnect(sql->hdbc, NULL, dsn, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE); if (SQL_SUCCEEDED(ret)) { /* output information about data base connection */ xprintf("Connected to "); dl_SQLGetInfo(sql->hdbc, SQL_DBMS_NAME, (SQLPOINTER)info, sizeof(info), NULL); xprintf("%s ", info); dl_SQLGetInfo(sql->hdbc, SQL_DBMS_VER, (SQLPOINTER)info, sizeof(info), NULL); xprintf("%s - ", info); dl_SQLGetInfo(sql->hdbc, SQL_DATABASE_NAME, (SQLPOINTER)info, sizeof(info), NULL); xprintf("%s\n", info); } else { /* describe error */ xprintf("Failed to connect\n"); extract_error("SQLDriverConnect", sql->hdbc, SQL_HANDLE_DBC); dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc); dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv); xfree(sql); return NULL; } /* set AUTOCOMMIT on*/ ret = dl_SQLSetConnectAttr(sql->hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, 0); /* allocate a statement handle */ ret = dl_SQLAllocHandle(SQL_HANDLE_STMT, sql->hdbc, &(sql->hstmt)); /* initialization queries */ for(j = 0; sqllines[j+1] != NULL; j++) { sql->query = (SQLCHAR *) sqllines[j]; xprintf("%s\n", sql->query); ret = dl_SQLExecDirect(sql->hstmt, sql->query, SQL_NTS); switch (ret) { case SQL_SUCCESS: case SQL_SUCCESS_WITH_INFO: case SQL_NO_DATA_FOUND: break; default: xprintf("db_iodbc_open: Query\n\"%s\"\nfailed.\n", sql->query); extract_error("SQLExecDirect", sql->hstmt, SQL_HANDLE_STMT); dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt); dl_SQLDisconnect(sql->hdbc); dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc); dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv); xfree(sql); return NULL; } /* commit statement */ dl_SQLEndTran(SQL_HANDLE_ENV, sql->henv, SQL_COMMIT); } if ( sql->mode == 'R' ) { sql->nf = mpl_tab_num_flds(dca); for(j = 0; sqllines[j] != NULL; j++) arg = sqllines[j]; total = strlen(arg); if (total > 7 && 0 == strncmp(arg, "SELECT ", 7)) { total = strlen(arg); sql->query = xmalloc( (total+1) * sizeof(char)); strcpy (sql->query, arg); } else { sql->query = db_generate_select_stmt(dca); } xprintf("%s\n", sql->query); if (dl_SQLExecDirect(sql->hstmt, sql->query, SQL_NTS) != SQL_SUCCESS) { xprintf("db_iodbc_open: Query\n\"%s\"\nfailed.\n", sql->query); extract_error("SQLExecDirect", sql->hstmt, SQL_HANDLE_STMT); dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt); dl_SQLDisconnect(sql->hdbc); dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc); dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv); xfree(sql->query); xfree(sql); return NULL; } xfree(sql->query); /* determine number of result columns */ ret = dl_SQLNumResultCols(sql->hstmt, &sql->nresultcols); total = sql->nresultcols; if (total > SQL_FIELD_MAX) { xprintf("db_iodbc_open: Too many fields (> %d) in query.\n" "\"%s\"\n", SQL_FIELD_MAX, sql->query); dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt); dl_SQLDisconnect(sql->hdbc); dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc); dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv); xfree(sql->query); return NULL; } for (i = 1; i <= total; i++) { /* return a set of attributes for a column */ ret = dl_SQLDescribeCol(sql->hstmt, (SQLSMALLINT) i, sql->colname[i], SQL_FDLEN_MAX, &colnamelen, &(sql->coltype[i]), &(sql->collen[i]), &scale, &nullable); sql->isnumeric[i] = is_numeric(sql->coltype[i]); /* bind columns to program vars, converting all types to CHAR*/ dl_SQLBindCol(sql->hstmt, i, SQL_CHAR, sql->data[i], SQL_FDLEN_MAX, &(sql->outlen[i])); for (j = sql->nf; j >= 1; j--) { if (strcmp(mpl_tab_get_name(dca, j), sql->colname[i]) == 0) break; } sql->ref[i] = j; } } else if ( sql->mode == 'W' ) { for(j = 0; sqllines[j] != NULL; j++) arg = sqllines[j]; if ( NULL != strchr(arg, '?') ) { total = strlen(arg); sql->query = xmalloc( (total+1) * sizeof(char)); strcpy (sql->query, arg); } else { sql->query = db_generate_insert_stmt(dca); } xprintf("%s\n", sql->query); } return sql; } int db_iodbc_read(TABDCA *dca, void *link) { struct db_odbc *sql; SQLRETURN ret; char buf[SQL_FDLEN_MAX+1]; int i; int len; double num; sql = (struct db_odbc *) link; xassert(sql != NULL); xassert(sql->mode == 'R'); ret=dl_SQLFetch(sql->hstmt); if (ret== SQL_ERROR) return -1; if (ret== SQL_NO_DATA_FOUND) return -1; /*EOF*/ for (i=1; i <= sql->nresultcols; i++) { if (sql->ref[i] > 0) { len = sql->outlen[i]; if (len != SQL_NULL_DATA) { if (len > SQL_FDLEN_MAX) len = SQL_FDLEN_MAX; else if (len < 0) len = 0; strncpy(buf, (const char *) sql->data[i], len); buf[len] = 0x00; if (0 != (sql->isnumeric[i])) { strspx(buf); /* remove spaces*/ if (str2num(buf, &num) != 0) { xprintf("'%s' cannot be converted to a number.\n", buf); return 1; } mpl_tab_set_num(dca, sql->ref[i], num); } else { mpl_tab_set_str(dca, sql->ref[i], strtrim(buf)); } } } } return 0; } int db_iodbc_write(TABDCA *dca, void *link) { struct db_odbc *sql; char *part; char *query; char *template; char num[50]; int k; int len; int nf; sql = (struct db_odbc *) link; xassert(sql != NULL); xassert(sql->mode == 'W'); len = strlen(sql->query); template = (char *) xmalloc( (len + 1) * sizeof(char) ); strcpy(template, sql->query); nf = mpl_tab_num_flds(dca); for (k = 1; k <= nf; k++) { switch (mpl_tab_get_type(dca, k)) { case 'N': len += 20; break; case 'S': len += db_escaped_string_length(mpl_tab_get_str(dca, k)); len += 2; break; default: xassert(dca != dca); } } query = xmalloc( (len + 1 ) * sizeof(char) ); query[0] = 0x00; for (k = 1, part = strtok (template, "?"); (part != NULL); part = strtok (NULL, "?"), k++) { if (k > nf) break; strcat( query, part ); switch (mpl_tab_get_type(dca, k)) { case 'N': sprintf(num, "%-18g",mpl_tab_get_num(dca, k)); strcat( query, num ); break; case 'S': strcat( query, "'"); db_escape_string( query + strlen(query), mpl_tab_get_str(dca, k) ); strcat( query, "'"); break; default: xassert(dca != dca); } } if (part != NULL) strcat(query, part); if (dl_SQLExecDirect(sql->hstmt, (SQLCHAR *) query, SQL_NTS) != SQL_SUCCESS) { xprintf("db_iodbc_write: Query\n\"%s\"\nfailed.\n", query); extract_error("SQLExecDirect", sql->hdbc, SQL_HANDLE_DBC); xfree(query); xfree(template); return 1; } xfree(query); xfree(template); return 0; } int db_iodbc_close(TABDCA *dca, void *link) { struct db_odbc *sql; sql = (struct db_odbc *) link; xassert(sql != NULL); /* Commit */ if ( sql->mode == 'W' ) dl_SQLEndTran(SQL_HANDLE_ENV, sql->henv, SQL_COMMIT); if ( sql->mode == 'R' ) dl_SQLCloseCursor(sql->hstmt); dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt); dl_SQLDisconnect(sql->hdbc); dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc); dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv); if ( sql->mode == 'W' ) xfree(sql->query); xfree(sql); dca->link = NULL; return 0; } static void extract_error( char *fn, SQLHANDLE handle, SQLSMALLINT type) { SQLINTEGER i = 0; SQLINTEGER native; SQLCHAR state[ 7 ]; SQLCHAR text[256]; SQLSMALLINT len; SQLRETURN ret; xprintf("\nThe driver reported the following diagnostics whilst " "running %s\n", fn); do { ret = dl_SQLGetDiagRec(type, handle, ++i, state, &native, text, sizeof(text), &len ); if (SQL_SUCCEEDED(ret)) xprintf("%s:%ld:%ld:%s\n", state, i, native, text); } while( ret == SQL_SUCCESS ); } static int is_numeric(SQLSMALLINT coltype) { int ret = 0; switch (coltype) { case SQL_DECIMAL: case SQL_NUMERIC: case SQL_SMALLINT: case SQL_INTEGER: case SQL_REAL: case SQL_FLOAT: case SQL_DOUBLE: case SQL_TINYINT: case SQL_BIGINT: ret = 1; break; } return ret; } #endif /**********************************************************************/ #ifndef HAVE_MYSQL void *db_mysql_open(TABDCA *dca, int mode) { xassert(dca == dca); xassert(mode == mode); xprintf("MySQL table driver not supported\n"); return NULL; } int db_mysql_read(TABDCA *dca, void *link) { xassert(dca != dca); xassert(link != link); return 0; } int db_mysql_write(TABDCA *dca, void *link) { xassert(dca != dca); xassert(link != link); return 0; } int db_mysql_close(TABDCA *dca, void *link) { xassert(dca != dca); xassert(link != link); return 0; } #else #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__WOE__) #include #endif #ifdef __CYGWIN__ #define byte_defined 1 #endif #include #include #include struct db_mysql { int mode; /*'R' = Read, 'W' = Write*/ MYSQL *con; /*connection*/ MYSQL_RES *res; /*result*/ int nf; /* number of fields in the csv file */ int ref[1+SQL_FIELD_MAX]; /* ref[k] = k', if k-th field of the csv file corresponds to k'-th field in the table statement; if ref[k] = 0, k-th field of the csv file is ignored */ char *query; /* query generated by db_mysql_open */ }; void STDCALL dl_mysql_close(MYSQL *sock) { typedef void STDCALL ep_mysql_close(MYSQL *sock); ep_mysql_close *fn; fn = (ep_mysql_close *) xdlsym(h_mysql, "mysql_close"); xassert(fn != NULL); return (*fn)(sock); } const char * STDCALL dl_mysql_error(MYSQL *mysql) { typedef const char * STDCALL ep_mysql_error(MYSQL *mysql); ep_mysql_error *fn; fn = (ep_mysql_error *) xdlsym(h_mysql, "mysql_error"); xassert(fn != NULL); return (*fn)(mysql); } MYSQL_FIELD * STDCALL dl_mysql_fetch_fields(MYSQL_RES *res) { typedef MYSQL_FIELD * STDCALL ep_mysql_fetch_fields(MYSQL_RES *res); ep_mysql_fetch_fields *fn; fn = (ep_mysql_fetch_fields *) xdlsym(h_mysql, "mysql_fetch_fields"); xassert(fn != NULL); return (*fn)(res); } unsigned long * STDCALL dl_mysql_fetch_lengths(MYSQL_RES *result) { typedef unsigned long * STDCALL ep_mysql_fetch_lengths(MYSQL_RES *result); ep_mysql_fetch_lengths *fn; fn = (ep_mysql_fetch_lengths *) xdlsym(h_mysql, "mysql_fetch_lengths"); xassert(fn != NULL); return (*fn)(result); } MYSQL_ROW STDCALL dl_mysql_fetch_row(MYSQL_RES *result) { typedef MYSQL_ROW STDCALL ep_mysql_fetch_row(MYSQL_RES *result); ep_mysql_fetch_row *fn; fn = (ep_mysql_fetch_row *) xdlsym(h_mysql, "mysql_fetch_row"); xassert(fn != NULL); return (*fn)(result); } unsigned int STDCALL dl_mysql_field_count(MYSQL *mysql) { typedef unsigned int STDCALL ep_mysql_field_count(MYSQL *mysql); ep_mysql_field_count *fn; fn = (ep_mysql_field_count *) xdlsym(h_mysql, "mysql_field_count"); xassert(fn != NULL); return (*fn)(mysql); } MYSQL * STDCALL dl_mysql_init(MYSQL *mysql) { typedef MYSQL * STDCALL ep_mysql_init(MYSQL *mysql); ep_mysql_init *fn; fn = (ep_mysql_init *) xdlsym(h_mysql, "mysql_init"); xassert(fn != NULL); return (*fn)(mysql); } unsigned int STDCALL dl_mysql_num_fields(MYSQL_RES *res) { typedef unsigned int STDCALL ep_mysql_num_fields(MYSQL_RES *res); ep_mysql_num_fields *fn; fn = (ep_mysql_num_fields *) xdlsym(h_mysql, "mysql_num_fields"); xassert(fn != NULL); return (*fn)(res); } int STDCALL dl_mysql_query(MYSQL *mysql, const char *q) { typedef int STDCALL ep_mysql_query(MYSQL *mysql, const char *q); ep_mysql_query *fn; fn = (ep_mysql_query *) xdlsym(h_mysql, "mysql_query"); xassert(fn != NULL); return (*fn)(mysql, q); } MYSQL * STDCALL dl_mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long clientflag) { typedef MYSQL * STDCALL ep_mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long clientflag); ep_mysql_real_connect *fn; fn = (ep_mysql_real_connect *) xdlsym(h_mysql, "mysql_real_connect"); xassert(fn != NULL); return (*fn)(mysql, host, user, passwd, db, port, unix_socket, clientflag); } MYSQL_RES * STDCALL dl_mysql_use_result(MYSQL *mysql) { typedef MYSQL_RES * STDCALL ep_mysql_use_result(MYSQL *mysql); ep_mysql_use_result *fn; fn = (ep_mysql_use_result *) xdlsym(h_mysql, "mysql_use_result"); xassert(fn != NULL); return (*fn)(mysql); } /*********************************************************************** * NAME * * db_mysql_open - open connection to ODBC data base * * SYNOPSIS * * #include "glpsql.h" * void *db_mysql_open(TABDCA *dca, int mode); * * DESCRIPTION * * The routine db_mysql_open opens a connection to a MySQL data base. * It then executes the sql statements passed. * * In the case of table read the SELECT statement is executed. * * In the case of table write the INSERT statement is prepared. * RETURNS * * The routine returns a pointer to data storage area created. */ void *db_mysql_open(TABDCA *dca, int mode) { void *ret; char **sqllines; sqllines = args_concat(dca); if (sqllines == NULL) { xprintf("Missing arguments in table statement.\n" "Please, supply table driver, dsn, and query.\n"); return NULL; } ret = db_mysql_open_int(dca, mode, (const char **) sqllines); free_buffer(sqllines); return ret; } static void *db_mysql_open_int(TABDCA *dca, int mode, const char **sqllines) { struct db_mysql *sql = NULL; char *arg = NULL; const char *field; MYSQL_FIELD *fields; char *keyword; char *value; char *query; char *dsn; /* "Server=[server_name];Database=[database_name];UID=[username];*/ /* PWD=[password];Port=[port]"*/ char *server = NULL; /* Server */ char *user = NULL; /* UID */ char *password = NULL; /* PWD */ char *database = NULL; /* Database */ unsigned int port = 0; /* Port */ int narg; int i, j, total; if (libmysql == NULL) { xprintf("No loader for shared MySQL library available\n"); return NULL; } if (h_mysql == NULL) { h_mysql = xdlopen(libmysql); if (h_mysql == NULL) { xprintf("unable to open library %s\n", libmysql); xprintf("%s\n", xerrmsg()); return NULL; } } sql = (struct db_mysql *) xmalloc(sizeof(struct db_mysql)); if (sql == NULL) return NULL; sql->mode = mode; sql->res = NULL; sql->query = NULL; sql->nf = mpl_tab_num_flds(dca); narg = mpl_tab_num_args(dca); if (narg < 3 ) xprintf("MySQL driver: string list too short \n"); /* get connection string*/ dsn = (char *) mpl_tab_get_arg(dca, 2); /* copy connection string*/ i = strlen(dsn); i++; arg = xmalloc(i * sizeof(char)); strcpy(arg, dsn); /*tokenize connection string*/ for (i = 1, keyword = strtok (arg, "="); (keyword != NULL); keyword = strtok (NULL, "="), i++) { value = strtok (NULL, ";"); if (value==NULL) { xprintf("db_mysql_open: Missing value for keyword %s\n", keyword); xfree(arg); xfree(sql); return NULL; } if (0 == strcmp(keyword, "Server")) server = value; else if (0 == strcmp(keyword, "Database")) database = value; else if (0 == strcmp(keyword, "UID")) user = value; else if (0 == strcmp(keyword, "PWD")) password = value; else if (0 == strcmp(keyword, "Port")) port = (unsigned int) atol(value); } /* Connect to database */ sql->con = dl_mysql_init(NULL); if (!dl_mysql_real_connect(sql->con, server, user, password, database, port, NULL, 0)) { xprintf("db_mysql_open: Connect failed\n"); xprintf("%s\n", dl_mysql_error(sql->con)); xfree(arg); xfree(sql); return NULL; } xfree(arg); for(j = 0; sqllines[j+1] != NULL; j++) { query = (char *) sqllines[j]; xprintf("%s\n", query); if (dl_mysql_query(sql->con, query)) { xprintf("db_mysql_open: Query\n\"%s\"\nfailed.\n", query); xprintf("%s\n",dl_mysql_error(sql->con)); dl_mysql_close(sql->con); xfree(sql); return NULL; } } if ( sql->mode == 'R' ) { sql->nf = mpl_tab_num_flds(dca); for(j = 0; sqllines[j] != NULL; j++) arg = (char *) sqllines[j]; total = strlen(arg); if (total > 7 && 0 == strncmp(arg, "SELECT ", 7)) { total = strlen(arg); query = xmalloc( (total+1) * sizeof(char)); strcpy (query, arg); } else { query = db_generate_select_stmt(dca); } xprintf("%s\n", query); if (dl_mysql_query(sql->con, query)) { xprintf("db_mysql_open: Query\n\"%s\"\nfailed.\n", query); xprintf("%s\n",dl_mysql_error(sql->con)); dl_mysql_close(sql->con); xfree(query); xfree(sql); return NULL; } xfree(query); sql->res = dl_mysql_use_result(sql->con); if (sql->res) { /* create references between query results and table fields*/ total = dl_mysql_num_fields(sql->res); if (total > SQL_FIELD_MAX) { xprintf("db_mysql_open: Too many fields (> %d) in query.\n" "\"%s\"\n", SQL_FIELD_MAX, query); xprintf("%s\n",dl_mysql_error(sql->con)); dl_mysql_close(sql->con); xfree(query); xfree(sql); return NULL; } fields = dl_mysql_fetch_fields(sql->res); for (i = 1; i <= total; i++) { for (j = sql->nf; j >= 1; j--) { if (strcmp(mpl_tab_get_name(dca, j), fields[i-1].name) == 0) break; } sql->ref[i] = j; } } else { if(dl_mysql_field_count(sql->con) == 0) { xprintf("db_mysql_open: Query was not a SELECT\n\"%s\"\n", query); xprintf("%s\n",dl_mysql_error(sql->con)); xfree(query); xfree(sql); return NULL; } else { xprintf("db_mysql_open: Query\n\"%s\"\nfailed.\n", query); xprintf("%s\n",dl_mysql_error(sql->con)); xfree(query); xfree(sql); return NULL; } } } else if ( sql->mode == 'W' ) { for(j = 0; sqllines[j] != NULL; j++) arg = (char *) sqllines[j]; if ( NULL != strchr(arg, '?') ) { total = strlen(arg); query = xmalloc( (total+1) * sizeof(char)); strcpy (query, arg); } else query = db_generate_insert_stmt(dca); sql->query = query; xprintf("%s\n", query); } return sql; } int db_mysql_read(TABDCA *dca, void *link) { struct db_mysql *sql; char buf[255+1]; char **row; unsigned long *lengths; MYSQL_FIELD *fields; double num; int len; unsigned long num_fields; int i; sql = (struct db_mysql *) link; xassert(sql != NULL); xassert(sql->mode == 'R'); if (NULL == sql->res) { xprintf("db_mysql_read: no result set available"); return 1; } if (NULL==(row = (char **)dl_mysql_fetch_row(sql->res))) { return -1; /*EOF*/ } lengths = dl_mysql_fetch_lengths(sql->res); fields = dl_mysql_fetch_fields(sql->res); num_fields = dl_mysql_num_fields(sql->res); for (i=1; i <= num_fields; i++) { if (row[i-1] != NULL) { len = (size_t) lengths[i-1]; if (len > 255) len = 255; strncpy(buf, (const char *) row[i-1], len); buf[len] = 0x00; if (0 != (fields[i-1].flags & NUM_FLAG)) { strspx(buf); /* remove spaces*/ if (str2num(buf, &num) != 0) { xprintf("'%s' cannot be converted to a number.\n", buf); return 1; } if (sql->ref[i] > 0) mpl_tab_set_num(dca, sql->ref[i], num); } else { if (sql->ref[i] > 0) mpl_tab_set_str(dca, sql->ref[i], strtrim(buf)); } } } return 0; } int db_mysql_write(TABDCA *dca, void *link) { struct db_mysql *sql; char *part; char *query; char *template; char num[50]; int k; int len; int nf; sql = (struct db_mysql *) link; xassert(sql != NULL); xassert(sql->mode == 'W'); len = strlen(sql->query); template = (char *) xmalloc( (len + 1) * sizeof(char) ); strcpy(template, sql->query); nf = mpl_tab_num_flds(dca); for (k = 1; k <= nf; k++) { switch (mpl_tab_get_type(dca, k)) { case 'N': len += 20; break; case 'S': len += db_escaped_string_length(mpl_tab_get_str(dca, k)); len += 2; break; default: xassert(dca != dca); } } query = xmalloc( (len + 1 ) * sizeof(char) ); query[0] = 0x00; for (k = 1, part = strtok (template, "?"); (part != NULL); part = strtok (NULL, "?"), k++) { if (k > nf) break; strcat( query, part ); switch (mpl_tab_get_type(dca, k)) { case 'N': sprintf(num, "%-18g",mpl_tab_get_num(dca, k)); strcat( query, num ); break; case 'S': strcat( query, "'"); db_escape_string( query + strlen(query), mpl_tab_get_str(dca, k) ); strcat( query, "'"); break; default: xassert(dca != dca); } } if (part != NULL) strcat(query, part); if (dl_mysql_query(sql->con, query)) { xprintf("db_mysql_write: Query\n\"%s\"\nfailed.\n", query); xprintf("%s\n",dl_mysql_error(sql->con)); xfree(query); xfree(template); return 1; } xfree(query); xfree(template); return 0; } int db_mysql_close(TABDCA *dca, void *link) { struct db_mysql *sql; sql = (struct db_mysql *) link; xassert(sql != NULL); dl_mysql_close(sql->con); if ( sql->mode == 'W' ) xfree(sql->query); xfree(sql); dca->link = NULL; return 0; } #endif /* eof */ praat-6.0.04/external/glpk/glpsql.h000066400000000000000000000041431261542461700171540ustar00rootroot00000000000000/* glpsql.h */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Author: Heinrich Schuchardt . * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPSQL_H #define GLPSQL_H #define db_iodbc_open _glp_db_iodbc_open void *db_iodbc_open(TABDCA *dca, int mode); /* open iODBC database connection */ #define db_iodbc_read _glp_db_iodbc_read int db_iodbc_read(TABDCA *dca, void *link); /* read data from iODBC */ #define db_iodbc_write _glp_db_iodbc_write int db_iodbc_write(TABDCA *dca, void *link); /* write data to iODBC */ #define db_iodbc_close _glp_db_iodbc_close int db_iodbc_close(TABDCA *dca, void *link); /* close iODBC database connection */ #define db_mysql_open _glp_db_mysql_open void *db_mysql_open(TABDCA *dca, int mode); /* open MySQL database connection */ #define db_mysql_read _glp_db_mysql_read int db_mysql_read(TABDCA *dca, void *link); /* read data from MySQL */ #define db_mysql_write _glp_db_mysql_write int db_mysql_write(TABDCA *dca, void *link); /* write data to MySQL */ #define db_mysql_close _glp_db_mysql_close int db_mysql_close(TABDCA *dca, void *link); /* close MySQL database connection */ #endif /* eof */ praat-6.0.04/external/glpk/glpssx.h000066400000000000000000000401301261542461700171660ustar00rootroot00000000000000/* glpssx.h (simplex method, bignum arithmetic) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPSSX_H #define GLPSSX_H #include "glpbfx.h" #include "glpenv.h" typedef struct SSX SSX; struct SSX { /* simplex solver workspace */ /*---------------------------------------------------------------------- // LP PROBLEM DATA // // It is assumed that LP problem has the following statement: // // minimize (or maximize) // // z = c[1]*x[1] + ... + c[m+n]*x[m+n] + c[0] (1) // // subject to equality constraints // // x[1] - a[1,1]*x[m+1] - ... - a[1,n]*x[m+n] = 0 // // . . . . . . . (2) // // x[m] - a[m,1]*x[m+1] + ... - a[m,n]*x[m+n] = 0 // // and bounds of variables // // l[1] <= x[1] <= u[1] // // . . . . . . . (3) // // l[m+n] <= x[m+n] <= u[m+n] // // where: // x[1], ..., x[m] - auxiliary variables; // x[m+1], ..., x[m+n] - structural variables; // z - objective function; // c[1], ..., c[m+n] - coefficients of the objective function; // c[0] - constant term of the objective function; // a[1,1], ..., a[m,n] - constraint coefficients; // l[1], ..., l[m+n] - lower bounds of variables; // u[1], ..., u[m+n] - upper bounds of variables. // // Bounds of variables can be finite as well as inifinite. Besides, // lower and upper bounds can be equal to each other. So the following // five types of variables are possible: // // Bounds of variable Type of variable // ------------------------------------------------- // -inf < x[k] < +inf Free (unbounded) variable // l[k] <= x[k] < +inf Variable with lower bound // -inf < x[k] <= u[k] Variable with upper bound // l[k] <= x[k] <= u[k] Double-bounded variable // l[k] = x[k] = u[k] Fixed variable // // Using vector-matrix notations the LP problem (1)-(3) can be written // as follows: // // minimize (or maximize) // // z = c * x + c[0] (4) // // subject to equality constraints // // xR - A * xS = 0 (5) // // and bounds of variables // // l <= x <= u (6) // // where: // xR - vector of auxiliary variables; // xS - vector of structural variables; // x = (xR, xS) - vector of all variables; // z - objective function; // c - vector of objective coefficients; // c[0] - constant term of the objective function; // A - matrix of constraint coefficients (has m rows // and n columns); // l - vector of lower bounds of variables; // u - vector of upper bounds of variables. // // The simplex method makes no difference between auxiliary and // structural variables, so it is convenient to think the system of // equality constraints (5) written in a homogeneous form: // // (I | -A) * x = 0, (7) // // where (I | -A) is an augmented (m+n)xm constraint matrix, I is mxm // unity matrix whose columns correspond to auxiliary variables, and A // is the original mxn constraint matrix whose columns correspond to // structural variables. Note that only the matrix A is stored. ----------------------------------------------------------------------*/ int m; /* number of rows (auxiliary variables), m > 0 */ int n; /* number of columns (structural variables), n > 0 */ int *type; /* int type[1+m+n]; */ /* type[0] is not used; type[k], 1 <= k <= m+n, is the type of variable x[k]: */ #define SSX_FR 0 /* free (unbounded) variable */ #define SSX_LO 1 /* variable with lower bound */ #define SSX_UP 2 /* variable with upper bound */ #define SSX_DB 3 /* double-bounded variable */ #define SSX_FX 4 /* fixed variable */ mpq_t *lb; /* mpq_t lb[1+m+n]; alias: l */ /* lb[0] is not used; lb[k], 1 <= k <= m+n, is an lower bound of variable x[k]; if x[k] has no lower bound, lb[k] is zero */ mpq_t *ub; /* mpq_t ub[1+m+n]; alias: u */ /* ub[0] is not used; ub[k], 1 <= k <= m+n, is an upper bound of variable x[k]; if x[k] has no upper bound, ub[k] is zero; if x[k] is of fixed type, ub[k] is equal to lb[k] */ int dir; /* optimization direction (sense of the objective function): */ #define SSX_MIN 0 /* minimization */ #define SSX_MAX 1 /* maximization */ mpq_t *coef; /* mpq_t coef[1+m+n]; alias: c */ /* coef[0] is a constant term of the objective function; coef[k], 1 <= k <= m+n, is a coefficient of the objective function at variable x[k]; note that auxiliary variables also may have non-zero objective coefficients */ int *A_ptr; /* int A_ptr[1+n+1]; */ int *A_ind; /* int A_ind[A_ptr[n+1]]; */ mpq_t *A_val; /* mpq_t A_val[A_ptr[n+1]]; */ /* constraint matrix A (see (5)) in storage-by-columns format */ /*---------------------------------------------------------------------- // LP BASIS AND CURRENT BASIC SOLUTION // // The LP basis is defined by the following partition of the augmented // constraint matrix (7): // // (B | N) = (I | -A) * Q, (8) // // where B is a mxm non-singular basis matrix whose columns correspond // to basic variables xB, N is a mxn matrix whose columns correspond to // non-basic variables xN, and Q is a permutation (m+n)x(m+n) matrix. // // From (7) and (8) it follows that // // (I | -A) * x = (I | -A) * Q * Q' * x = (B | N) * (xB, xN), // // therefore // // (xB, xN) = Q' * x, (9) // // where x is the vector of all variables in the original order, xB is // a vector of basic variables, xN is a vector of non-basic variables, // Q' = inv(Q) is a matrix transposed to Q. // // Current values of non-basic variables xN[j], j = 1, ..., n, are not // stored; they are defined implicitly by their statuses as follows: // // 0, if xN[j] is free variable // lN[j], if xN[j] is on its lower bound (10) // uN[j], if xN[j] is on its upper bound // lN[j] = uN[j], if xN[j] is fixed variable // // where lN[j] and uN[j] are lower and upper bounds of xN[j]. // // Current values of basic variables xB[i], i = 1, ..., m, are computed // as follows: // // beta = - inv(B) * N * xN, (11) // // where current values of xN are defined by (10). // // Current values of simplex multipliers pi[i], i = 1, ..., m (which // are values of Lagrange multipliers for equality constraints (7) also // called shadow prices) are computed as follows: // // pi = inv(B') * cB, (12) // // where B' is a matrix transposed to B, cB is a vector of objective // coefficients at basic variables xB. // // Current values of reduced costs d[j], j = 1, ..., n, (which are // values of Langrange multipliers for active inequality constraints // corresponding to non-basic variables) are computed as follows: // // d = cN - N' * pi, (13) // // where N' is a matrix transposed to N, cN is a vector of objective // coefficients at non-basic variables xN. ----------------------------------------------------------------------*/ int *stat; /* int stat[1+m+n]; */ /* stat[0] is not used; stat[k], 1 <= k <= m+n, is the status of variable x[k]: */ #define SSX_BS 0 /* basic variable */ #define SSX_NL 1 /* non-basic variable on lower bound */ #define SSX_NU 2 /* non-basic variable on upper bound */ #define SSX_NF 3 /* non-basic free variable */ #define SSX_NS 4 /* non-basic fixed variable */ int *Q_row; /* int Q_row[1+m+n]; */ /* matrix Q in row-like format; Q_row[0] is not used; Q_row[i] = j means that q[i,j] = 1 */ int *Q_col; /* int Q_col[1+m+n]; */ /* matrix Q in column-like format; Q_col[0] is not used; Q_col[j] = i means that q[i,j] = 1 */ /* if k-th column of the matrix (I | A) is k'-th column of the matrix (B | N), then Q_row[k] = k' and Q_col[k'] = k; if x[k] is xB[i], then Q_row[k] = i and Q_col[i] = k; if x[k] is xN[j], then Q_row[k] = m+j and Q_col[m+j] = k */ BFX *binv; /* invertable form of the basis matrix B */ mpq_t *bbar; /* mpq_t bbar[1+m]; alias: beta */ /* bbar[0] is a value of the objective function; bbar[i], 1 <= i <= m, is a value of basic variable xB[i] */ mpq_t *pi; /* mpq_t pi[1+m]; */ /* pi[0] is not used; pi[i], 1 <= i <= m, is a simplex multiplier corresponding to i-th row (equality constraint) */ mpq_t *cbar; /* mpq_t cbar[1+n]; alias: d */ /* cbar[0] is not used; cbar[j], 1 <= j <= n, is a reduced cost of non-basic variable xN[j] */ /*---------------------------------------------------------------------- // SIMPLEX TABLE // // Due to (8) and (9) the system of equality constraints (7) for the // current basis can be written as follows: // // xB = A~ * xN, (14) // // where // // A~ = - inv(B) * N (15) // // is a mxn matrix called the simplex table. // // The revised simplex method uses only two components of A~, namely, // pivot column corresponding to non-basic variable xN[q] chosen to // enter the basis, and pivot row corresponding to basic variable xB[p] // chosen to leave the basis. // // Pivot column alfa_q is q-th column of A~, so // // alfa_q = A~ * e[q] = - inv(B) * N * e[q] = - inv(B) * N[q], (16) // // where N[q] is q-th column of the matrix N. // // Pivot row alfa_p is p-th row of A~ or, equivalently, p-th column of // A~', a matrix transposed to A~, so // // alfa_p = A~' * e[p] = - N' * inv(B') * e[p] = - N' * rho_p, (17) // // where (*)' means transposition, and // // rho_p = inv(B') * e[p], (18) // // is p-th column of inv(B') or, that is the same, p-th row of inv(B). ----------------------------------------------------------------------*/ int p; /* number of basic variable xB[p], 1 <= p <= m, chosen to leave the basis */ mpq_t *rho; /* mpq_t rho[1+m]; */ /* p-th row of the inverse inv(B); see (18) */ mpq_t *ap; /* mpq_t ap[1+n]; */ /* p-th row of the simplex table; see (17) */ int q; /* number of non-basic variable xN[q], 1 <= q <= n, chosen to enter the basis */ mpq_t *aq; /* mpq_t aq[1+m]; */ /* q-th column of the simplex table; see (16) */ /*--------------------------------------------------------------------*/ int q_dir; /* direction in which non-basic variable xN[q] should change on moving to the adjacent vertex of the polyhedron: +1 means that xN[q] increases -1 means that xN[q] decreases */ int p_stat; /* non-basic status which should be assigned to basic variable xB[p] when it has left the basis and become xN[q] */ mpq_t delta; /* actual change of xN[q] in the adjacent basis (it has the same sign as q_dir) */ /*--------------------------------------------------------------------*/ int it_lim; /* simplex iterations limit; if this value is positive, it is decreased by one each time when one simplex iteration has been performed, and reaching zero value signals the solver to stop the search; negative value means no iterations limit */ int it_cnt; /* simplex iterations count; this count is increased by one each time when one simplex iteration has been performed */ double tm_lim; /* searching time limit, in seconds; if this value is positive, it is decreased each time when one simplex iteration has been performed by the amount of time spent for the iteration, and reaching zero value signals the solver to stop the search; negative value means no time limit */ double out_frq; /* output frequency, in seconds; this parameter specifies how frequently the solver sends information about the progress of the search to the standard output */ glp_long tm_beg; /* starting time of the search, in seconds; the total time of the search is the difference between xtime() and tm_beg */ glp_long tm_lag; /* the most recent time, in seconds, at which the progress of the the search was displayed */ }; #define ssx_create _glp_ssx_create #define ssx_factorize _glp_ssx_factorize #define ssx_get_xNj _glp_ssx_get_xNj #define ssx_eval_bbar _glp_ssx_eval_bbar #define ssx_eval_pi _glp_ssx_eval_pi #define ssx_eval_dj _glp_ssx_eval_dj #define ssx_eval_cbar _glp_ssx_eval_cbar #define ssx_eval_rho _glp_ssx_eval_rho #define ssx_eval_row _glp_ssx_eval_row #define ssx_eval_col _glp_ssx_eval_col #define ssx_chuzc _glp_ssx_chuzc #define ssx_chuzr _glp_ssx_chuzr #define ssx_update_bbar _glp_ssx_update_bbar #define ssx_update_pi _glp_ssx_update_pi #define ssx_update_cbar _glp_ssx_update_cbar #define ssx_change_basis _glp_ssx_change_basis #define ssx_delete _glp_ssx_delete #define ssx_phase_I _glp_ssx_phase_I #define ssx_phase_II _glp_ssx_phase_II #define ssx_driver _glp_ssx_driver SSX *ssx_create(int m, int n, int nnz); /* create simplex solver workspace */ int ssx_factorize(SSX *ssx); /* factorize the current basis matrix */ void ssx_get_xNj(SSX *ssx, int j, mpq_t x); /* determine value of non-basic variable */ void ssx_eval_bbar(SSX *ssx); /* compute values of basic variables */ void ssx_eval_pi(SSX *ssx); /* compute values of simplex multipliers */ void ssx_eval_dj(SSX *ssx, int j, mpq_t dj); /* compute reduced cost of non-basic variable */ void ssx_eval_cbar(SSX *ssx); /* compute reduced costs of all non-basic variables */ void ssx_eval_rho(SSX *ssx); /* compute p-th row of the inverse */ void ssx_eval_row(SSX *ssx); /* compute pivot row of the simplex table */ void ssx_eval_col(SSX *ssx); /* compute pivot column of the simplex table */ void ssx_chuzc(SSX *ssx); /* choose pivot column */ void ssx_chuzr(SSX *ssx); /* choose pivot row */ void ssx_update_bbar(SSX *ssx); /* update values of basic variables */ void ssx_update_pi(SSX *ssx); /* update simplex multipliers */ void ssx_update_cbar(SSX *ssx); /* update reduced costs of non-basic variables */ void ssx_change_basis(SSX *ssx); /* change current basis to adjacent one */ void ssx_delete(SSX *ssx); /* delete simplex solver workspace */ int ssx_phase_I(SSX *ssx); /* find primal feasible solution */ int ssx_phase_II(SSX *ssx); /* find optimal solution */ int ssx_driver(SSX *ssx); /* base driver to exact simplex method */ #endif /* eof */ praat-6.0.04/external/glpk/glpssx01.c000066400000000000000000000661541261542461700173400ustar00rootroot00000000000000/* glpssx01.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpenv.h" #include "glpssx.h" #define xfault xerror /*---------------------------------------------------------------------- // ssx_create - create simplex solver workspace. // // This routine creates the workspace used by simplex solver routines, // and returns a pointer to it. // // Parameters m, n, and nnz specify, respectively, the number of rows, // columns, and non-zero constraint coefficients. // // This routine only allocates the memory for the workspace components, // so the workspace needs to be saturated by data. */ SSX *ssx_create(int m, int n, int nnz) { SSX *ssx; int i, j, k; if (m < 1) xfault("ssx_create: m = %d; invalid number of rows\n", m); if (n < 1) xfault("ssx_create: n = %d; invalid number of columns\n", n); if (nnz < 0) xfault("ssx_create: nnz = %d; invalid number of non-zero const" "raint coefficients\n", nnz); ssx = xmalloc(sizeof(SSX)); ssx->m = m; ssx->n = n; ssx->type = xcalloc(1+m+n, sizeof(int)); ssx->lb = xcalloc(1+m+n, sizeof(mpq_t)); for (k = 1; k <= m+n; k++) mpq_init(ssx->lb[k]); ssx->ub = xcalloc(1+m+n, sizeof(mpq_t)); for (k = 1; k <= m+n; k++) mpq_init(ssx->ub[k]); ssx->coef = xcalloc(1+m+n, sizeof(mpq_t)); for (k = 0; k <= m+n; k++) mpq_init(ssx->coef[k]); ssx->A_ptr = xcalloc(1+n+1, sizeof(int)); ssx->A_ptr[n+1] = nnz+1; ssx->A_ind = xcalloc(1+nnz, sizeof(int)); ssx->A_val = xcalloc(1+nnz, sizeof(mpq_t)); for (k = 1; k <= nnz; k++) mpq_init(ssx->A_val[k]); ssx->stat = xcalloc(1+m+n, sizeof(int)); ssx->Q_row = xcalloc(1+m+n, sizeof(int)); ssx->Q_col = xcalloc(1+m+n, sizeof(int)); ssx->binv = bfx_create_binv(); ssx->bbar = xcalloc(1+m, sizeof(mpq_t)); for (i = 0; i <= m; i++) mpq_init(ssx->bbar[i]); ssx->pi = xcalloc(1+m, sizeof(mpq_t)); for (i = 1; i <= m; i++) mpq_init(ssx->pi[i]); ssx->cbar = xcalloc(1+n, sizeof(mpq_t)); for (j = 1; j <= n; j++) mpq_init(ssx->cbar[j]); ssx->rho = xcalloc(1+m, sizeof(mpq_t)); for (i = 1; i <= m; i++) mpq_init(ssx->rho[i]); ssx->ap = xcalloc(1+n, sizeof(mpq_t)); for (j = 1; j <= n; j++) mpq_init(ssx->ap[j]); ssx->aq = xcalloc(1+m, sizeof(mpq_t)); for (i = 1; i <= m; i++) mpq_init(ssx->aq[i]); mpq_init(ssx->delta); return ssx; } /*---------------------------------------------------------------------- // ssx_factorize - factorize the current basis matrix. // // This routine computes factorization of the current basis matrix B // and returns the singularity flag. If the matrix B is non-singular, // the flag is zero, otherwise non-zero. */ static int basis_col(void *info, int j, int ind[], mpq_t val[]) { /* this auxiliary routine provides row indices and numeric values of non-zero elements in j-th column of the matrix B */ SSX *ssx = info; int m = ssx->m; int n = ssx->n; int *A_ptr = ssx->A_ptr; int *A_ind = ssx->A_ind; mpq_t *A_val = ssx->A_val; int *Q_col = ssx->Q_col; int k, len, ptr; xassert(1 <= j && j <= m); k = Q_col[j]; /* x[k] = xB[j] */ xassert(1 <= k && k <= m+n); /* j-th column of the matrix B is k-th column of the augmented constraint matrix (I | -A) */ if (k <= m) { /* it is a column of the unity matrix I */ len = 1, ind[1] = k, mpq_set_si(val[1], 1, 1); } else { /* it is a column of the original constraint matrix -A */ len = 0; for (ptr = A_ptr[k-m]; ptr < A_ptr[k-m+1]; ptr++) { len++; ind[len] = A_ind[ptr]; mpq_neg(val[len], A_val[ptr]); } } return len; } int ssx_factorize(SSX *ssx) { int ret; ret = bfx_factorize(ssx->binv, ssx->m, basis_col, ssx); return ret; } /*---------------------------------------------------------------------- // ssx_get_xNj - determine value of non-basic variable. // // This routine determines the value of non-basic variable xN[j] in the // current basic solution defined as follows: // // 0, if xN[j] is free variable // lN[j], if xN[j] is on its lower bound // uN[j], if xN[j] is on its upper bound // lN[j] = uN[j], if xN[j] is fixed variable // // where lN[j] and uN[j] are lower and upper bounds of xN[j]. */ void ssx_get_xNj(SSX *ssx, int j, mpq_t x) { int m = ssx->m; int n = ssx->n; mpq_t *lb = ssx->lb; mpq_t *ub = ssx->ub; int *stat = ssx->stat; int *Q_col = ssx->Q_col; int k; xassert(1 <= j && j <= n); k = Q_col[m+j]; /* x[k] = xN[j] */ xassert(1 <= k && k <= m+n); switch (stat[k]) { case SSX_NL: /* xN[j] is on its lower bound */ mpq_set(x, lb[k]); break; case SSX_NU: /* xN[j] is on its upper bound */ mpq_set(x, ub[k]); break; case SSX_NF: /* xN[j] is free variable */ mpq_set_si(x, 0, 1); break; case SSX_NS: /* xN[j] is fixed variable */ mpq_set(x, lb[k]); break; default: xassert(stat != stat); } return; } /*---------------------------------------------------------------------- // ssx_eval_bbar - compute values of basic variables. // // This routine computes values of basic variables xB in the current // basic solution as follows: // // beta = - inv(B) * N * xN, // // where B is the basis matrix, N is the matrix of non-basic columns, // xN is a vector of current values of non-basic variables. */ void ssx_eval_bbar(SSX *ssx) { int m = ssx->m; int n = ssx->n; mpq_t *coef = ssx->coef; int *A_ptr = ssx->A_ptr; int *A_ind = ssx->A_ind; mpq_t *A_val = ssx->A_val; int *Q_col = ssx->Q_col; mpq_t *bbar = ssx->bbar; int i, j, k, ptr; mpq_t x, temp; mpq_init(x); mpq_init(temp); /* bbar := 0 */ for (i = 1; i <= m; i++) mpq_set_si(bbar[i], 0, 1); /* bbar := - N * xN = - N[1] * xN[1] - ... - N[n] * xN[n] */ for (j = 1; j <= n; j++) { ssx_get_xNj(ssx, j, x); if (mpq_sgn(x) == 0) continue; k = Q_col[m+j]; /* x[k] = xN[j] */ if (k <= m) { /* N[j] is a column of the unity matrix I */ mpq_sub(bbar[k], bbar[k], x); } else { /* N[j] is a column of the original constraint matrix -A */ for (ptr = A_ptr[k-m]; ptr < A_ptr[k-m+1]; ptr++) { mpq_mul(temp, A_val[ptr], x); mpq_add(bbar[A_ind[ptr]], bbar[A_ind[ptr]], temp); } } } /* bbar := inv(B) * bbar */ bfx_ftran(ssx->binv, bbar, 0); #if 1 /* compute value of the objective function */ /* bbar[0] := c[0] */ mpq_set(bbar[0], coef[0]); /* bbar[0] := bbar[0] + sum{i in B} cB[i] * xB[i] */ for (i = 1; i <= m; i++) { k = Q_col[i]; /* x[k] = xB[i] */ if (mpq_sgn(coef[k]) == 0) continue; mpq_mul(temp, coef[k], bbar[i]); mpq_add(bbar[0], bbar[0], temp); } /* bbar[0] := bbar[0] + sum{j in N} cN[j] * xN[j] */ for (j = 1; j <= n; j++) { k = Q_col[m+j]; /* x[k] = xN[j] */ if (mpq_sgn(coef[k]) == 0) continue; ssx_get_xNj(ssx, j, x); mpq_mul(temp, coef[k], x); mpq_add(bbar[0], bbar[0], temp); } #endif mpq_clear(x); mpq_clear(temp); return; } /*---------------------------------------------------------------------- // ssx_eval_pi - compute values of simplex multipliers. // // This routine computes values of simplex multipliers (shadow prices) // pi in the current basic solution as follows: // // pi = inv(B') * cB, // // where B' is a matrix transposed to the basis matrix B, cB is a vector // of objective coefficients at basic variables xB. */ void ssx_eval_pi(SSX *ssx) { int m = ssx->m; mpq_t *coef = ssx->coef; int *Q_col = ssx->Q_col; mpq_t *pi = ssx->pi; int i; /* pi := cB */ for (i = 1; i <= m; i++) mpq_set(pi[i], coef[Q_col[i]]); /* pi := inv(B') * cB */ bfx_btran(ssx->binv, pi); return; } /*---------------------------------------------------------------------- // ssx_eval_dj - compute reduced cost of non-basic variable. // // This routine computes reduced cost d[j] of non-basic variable xN[j] // in the current basic solution as follows: // // d[j] = cN[j] - N[j] * pi, // // where cN[j] is an objective coefficient at xN[j], N[j] is a column // of the augmented constraint matrix (I | -A) corresponding to xN[j], // pi is the vector of simplex multipliers (shadow prices). */ void ssx_eval_dj(SSX *ssx, int j, mpq_t dj) { int m = ssx->m; int n = ssx->n; mpq_t *coef = ssx->coef; int *A_ptr = ssx->A_ptr; int *A_ind = ssx->A_ind; mpq_t *A_val = ssx->A_val; int *Q_col = ssx->Q_col; mpq_t *pi = ssx->pi; int k, ptr, end; mpq_t temp; mpq_init(temp); xassert(1 <= j && j <= n); k = Q_col[m+j]; /* x[k] = xN[j] */ xassert(1 <= k && k <= m+n); /* j-th column of the matrix N is k-th column of the augmented constraint matrix (I | -A) */ if (k <= m) { /* it is a column of the unity matrix I */ mpq_sub(dj, coef[k], pi[k]); } else { /* it is a column of the original constraint matrix -A */ mpq_set(dj, coef[k]); for (ptr = A_ptr[k-m], end = A_ptr[k-m+1]; ptr < end; ptr++) { mpq_mul(temp, A_val[ptr], pi[A_ind[ptr]]); mpq_add(dj, dj, temp); } } mpq_clear(temp); return; } /*---------------------------------------------------------------------- // ssx_eval_cbar - compute reduced costs of all non-basic variables. // // This routine computes the vector of reduced costs pi in the current // basic solution for all non-basic variables, including fixed ones. */ void ssx_eval_cbar(SSX *ssx) { int n = ssx->n; mpq_t *cbar = ssx->cbar; int j; for (j = 1; j <= n; j++) ssx_eval_dj(ssx, j, cbar[j]); return; } /*---------------------------------------------------------------------- // ssx_eval_rho - compute p-th row of the inverse. // // This routine computes p-th row of the matrix inv(B), where B is the // current basis matrix. // // p-th row of the inverse is computed using the following formula: // // rho = inv(B') * e[p], // // where B' is a matrix transposed to B, e[p] is a unity vector, which // contains one in p-th position. */ void ssx_eval_rho(SSX *ssx) { int m = ssx->m; int p = ssx->p; mpq_t *rho = ssx->rho; int i; xassert(1 <= p && p <= m); /* rho := 0 */ for (i = 1; i <= m; i++) mpq_set_si(rho[i], 0, 1); /* rho := e[p] */ mpq_set_si(rho[p], 1, 1); /* rho := inv(B') * rho */ bfx_btran(ssx->binv, rho); return; } /*---------------------------------------------------------------------- // ssx_eval_row - compute pivot row of the simplex table. // // This routine computes p-th (pivot) row of the current simplex table // A~ = - inv(B) * N using the following formula: // // A~[p] = - N' * inv(B') * e[p] = - N' * rho[p], // // where N' is a matrix transposed to the matrix N, rho[p] is p-th row // of the inverse inv(B). */ void ssx_eval_row(SSX *ssx) { int m = ssx->m; int n = ssx->n; int *A_ptr = ssx->A_ptr; int *A_ind = ssx->A_ind; mpq_t *A_val = ssx->A_val; int *Q_col = ssx->Q_col; mpq_t *rho = ssx->rho; mpq_t *ap = ssx->ap; int j, k, ptr; mpq_t temp; mpq_init(temp); for (j = 1; j <= n; j++) { /* ap[j] := - N'[j] * rho (inner product) */ k = Q_col[m+j]; /* x[k] = xN[j] */ if (k <= m) mpq_neg(ap[j], rho[k]); else { mpq_set_si(ap[j], 0, 1); for (ptr = A_ptr[k-m]; ptr < A_ptr[k-m+1]; ptr++) { mpq_mul(temp, A_val[ptr], rho[A_ind[ptr]]); mpq_add(ap[j], ap[j], temp); } } } mpq_clear(temp); return; } /*---------------------------------------------------------------------- // ssx_eval_col - compute pivot column of the simplex table. // // This routine computes q-th (pivot) column of the current simplex // table A~ = - inv(B) * N using the following formula: // // A~[q] = - inv(B) * N[q], // // where N[q] is q-th column of the matrix N corresponding to chosen // non-basic variable xN[q]. */ void ssx_eval_col(SSX *ssx) { int m = ssx->m; int n = ssx->n; int *A_ptr = ssx->A_ptr; int *A_ind = ssx->A_ind; mpq_t *A_val = ssx->A_val; int *Q_col = ssx->Q_col; int q = ssx->q; mpq_t *aq = ssx->aq; int i, k, ptr; xassert(1 <= q && q <= n); /* aq := 0 */ for (i = 1; i <= m; i++) mpq_set_si(aq[i], 0, 1); /* aq := N[q] */ k = Q_col[m+q]; /* x[k] = xN[q] */ if (k <= m) { /* N[q] is a column of the unity matrix I */ mpq_set_si(aq[k], 1, 1); } else { /* N[q] is a column of the original constraint matrix -A */ for (ptr = A_ptr[k-m]; ptr < A_ptr[k-m+1]; ptr++) mpq_neg(aq[A_ind[ptr]], A_val[ptr]); } /* aq := inv(B) * aq */ bfx_ftran(ssx->binv, aq, 1); /* aq := - aq */ for (i = 1; i <= m; i++) mpq_neg(aq[i], aq[i]); return; } /*---------------------------------------------------------------------- // ssx_chuzc - choose pivot column. // // This routine chooses non-basic variable xN[q] whose reduced cost // indicates possible improving of the objective function to enter it // in the basis. // // Currently the standard (textbook) pricing is used, i.e. that // non-basic variable is preferred which has greatest reduced cost (in // magnitude). // // If xN[q] has been chosen, the routine stores its number q and also // sets the flag q_dir that indicates direction in which xN[q] has to // change (+1 means increasing, -1 means decreasing). // // If the choice cannot be made, because the current basic solution is // dual feasible, the routine sets the number q to 0. */ void ssx_chuzc(SSX *ssx) { int m = ssx->m; int n = ssx->n; int dir = (ssx->dir == SSX_MIN ? +1 : -1); int *Q_col = ssx->Q_col; int *stat = ssx->stat; mpq_t *cbar = ssx->cbar; int j, k, s, q, q_dir; double best, temp; /* nothing is chosen so far */ q = 0, q_dir = 0, best = 0.0; /* look through the list of non-basic variables */ for (j = 1; j <= n; j++) { k = Q_col[m+j]; /* x[k] = xN[j] */ s = dir * mpq_sgn(cbar[j]); if ((stat[k] == SSX_NF || stat[k] == SSX_NL) && s < 0 || (stat[k] == SSX_NF || stat[k] == SSX_NU) && s > 0) { /* reduced cost of xN[j] indicates possible improving of the objective function */ temp = fabs(mpq_get_d(cbar[j])); xassert(temp != 0.0); if (q == 0 || best < temp) q = j, q_dir = - s, best = temp; } } ssx->q = q, ssx->q_dir = q_dir; return; } /*---------------------------------------------------------------------- // ssx_chuzr - choose pivot row. // // This routine looks through elements of q-th column of the simplex // table and chooses basic variable xB[p] which should leave the basis. // // The choice is based on the standard (textbook) ratio test. // // If xB[p] has been chosen, the routine stores its number p and also // sets its non-basic status p_stat which should be assigned to xB[p] // when it has left the basis and become xN[q]. // // Special case p < 0 means that xN[q] is double-bounded variable and // it reaches its opposite bound before any basic variable does that, // so the current basis remains unchanged. // // If the choice cannot be made, because xN[q] can infinitely change in // the feasible direction, the routine sets the number p to 0. */ void ssx_chuzr(SSX *ssx) { int m = ssx->m; int n = ssx->n; int *type = ssx->type; mpq_t *lb = ssx->lb; mpq_t *ub = ssx->ub; int *Q_col = ssx->Q_col; mpq_t *bbar = ssx->bbar; int q = ssx->q; mpq_t *aq = ssx->aq; int q_dir = ssx->q_dir; int i, k, s, t, p, p_stat; mpq_t teta, temp; mpq_init(teta); mpq_init(temp); xassert(1 <= q && q <= n); xassert(q_dir == +1 || q_dir == -1); /* nothing is chosen so far */ p = 0, p_stat = 0; /* look through the list of basic variables */ for (i = 1; i <= m; i++) { s = q_dir * mpq_sgn(aq[i]); if (s < 0) { /* xB[i] decreases */ k = Q_col[i]; /* x[k] = xB[i] */ t = type[k]; if (t == SSX_LO || t == SSX_DB || t == SSX_FX) { /* xB[i] has finite lower bound */ mpq_sub(temp, bbar[i], lb[k]); mpq_div(temp, temp, aq[i]); mpq_abs(temp, temp); if (p == 0 || mpq_cmp(teta, temp) > 0) { p = i; p_stat = (t == SSX_FX ? SSX_NS : SSX_NL); mpq_set(teta, temp); } } } else if (s > 0) { /* xB[i] increases */ k = Q_col[i]; /* x[k] = xB[i] */ t = type[k]; if (t == SSX_UP || t == SSX_DB || t == SSX_FX) { /* xB[i] has finite upper bound */ mpq_sub(temp, bbar[i], ub[k]); mpq_div(temp, temp, aq[i]); mpq_abs(temp, temp); if (p == 0 || mpq_cmp(teta, temp) > 0) { p = i; p_stat = (t == SSX_FX ? SSX_NS : SSX_NU); mpq_set(teta, temp); } } } /* if something has been chosen and the ratio test indicates exact degeneracy, the search can be finished */ if (p != 0 && mpq_sgn(teta) == 0) break; } /* if xN[q] is double-bounded, check if it can reach its opposite bound before any basic variable */ k = Q_col[m+q]; /* x[k] = xN[q] */ if (type[k] == SSX_DB) { mpq_sub(temp, ub[k], lb[k]); if (p == 0 || mpq_cmp(teta, temp) > 0) { p = -1; p_stat = -1; mpq_set(teta, temp); } } ssx->p = p; ssx->p_stat = p_stat; /* if xB[p] has been chosen, determine its actual change in the adjacent basis (it has the same sign as q_dir) */ if (p != 0) { xassert(mpq_sgn(teta) >= 0); if (q_dir > 0) mpq_set(ssx->delta, teta); else mpq_neg(ssx->delta, teta); } mpq_clear(teta); mpq_clear(temp); return; } /*---------------------------------------------------------------------- // ssx_update_bbar - update values of basic variables. // // This routine recomputes the current values of basic variables for // the adjacent basis. // // The simplex table for the current basis is the following: // // xB[i] = sum{j in 1..n} alfa[i,j] * xN[q], i = 1,...,m // // therefore // // delta xB[i] = alfa[i,q] * delta xN[q], i = 1,...,m // // where delta xN[q] = xN.new[q] - xN[q] is the change of xN[q] in the // adjacent basis, and delta xB[i] = xB.new[i] - xB[i] is the change of // xB[i]. This gives formulae for recomputing values of xB[i]: // // xB.new[p] = xN[q] + delta xN[q] // // (because xN[q] becomes xB[p] in the adjacent basis), and // // xB.new[i] = xB[i] + alfa[i,q] * delta xN[q], i != p // // for other basic variables. */ void ssx_update_bbar(SSX *ssx) { int m = ssx->m; int n = ssx->n; mpq_t *bbar = ssx->bbar; mpq_t *cbar = ssx->cbar; int p = ssx->p; int q = ssx->q; mpq_t *aq = ssx->aq; int i; mpq_t temp; mpq_init(temp); xassert(1 <= q && q <= n); if (p < 0) { /* xN[q] is double-bounded and goes to its opposite bound */ /* nop */; } else { /* xN[q] becomes xB[p] in the adjacent basis */ /* xB.new[p] = xN[q] + delta xN[q] */ xassert(1 <= p && p <= m); ssx_get_xNj(ssx, q, temp); mpq_add(bbar[p], temp, ssx->delta); } /* update values of other basic variables depending on xN[q] */ for (i = 1; i <= m; i++) { if (i == p) continue; /* xB.new[i] = xB[i] + alfa[i,q] * delta xN[q] */ if (mpq_sgn(aq[i]) == 0) continue; mpq_mul(temp, aq[i], ssx->delta); mpq_add(bbar[i], bbar[i], temp); } #if 1 /* update value of the objective function */ /* z.new = z + d[q] * delta xN[q] */ mpq_mul(temp, cbar[q], ssx->delta); mpq_add(bbar[0], bbar[0], temp); #endif mpq_clear(temp); return; } /*---------------------------------------------------------------------- -- ssx_update_pi - update simplex multipliers. -- -- This routine recomputes the vector of simplex multipliers for the -- adjacent basis. */ void ssx_update_pi(SSX *ssx) { int m = ssx->m; int n = ssx->n; mpq_t *pi = ssx->pi; mpq_t *cbar = ssx->cbar; int p = ssx->p; int q = ssx->q; mpq_t *aq = ssx->aq; mpq_t *rho = ssx->rho; int i; mpq_t new_dq, temp; mpq_init(new_dq); mpq_init(temp); xassert(1 <= p && p <= m); xassert(1 <= q && q <= n); /* compute d[q] in the adjacent basis */ mpq_div(new_dq, cbar[q], aq[p]); /* update the vector of simplex multipliers */ for (i = 1; i <= m; i++) { if (mpq_sgn(rho[i]) == 0) continue; mpq_mul(temp, new_dq, rho[i]); mpq_sub(pi[i], pi[i], temp); } mpq_clear(new_dq); mpq_clear(temp); return; } /*---------------------------------------------------------------------- // ssx_update_cbar - update reduced costs of non-basic variables. // // This routine recomputes the vector of reduced costs of non-basic // variables for the adjacent basis. */ void ssx_update_cbar(SSX *ssx) { int m = ssx->m; int n = ssx->n; mpq_t *cbar = ssx->cbar; int p = ssx->p; int q = ssx->q; mpq_t *ap = ssx->ap; int j; mpq_t temp; mpq_init(temp); xassert(1 <= p && p <= m); xassert(1 <= q && q <= n); /* compute d[q] in the adjacent basis */ /* d.new[q] = d[q] / alfa[p,q] */ mpq_div(cbar[q], cbar[q], ap[q]); /* update reduced costs of other non-basic variables */ for (j = 1; j <= n; j++) { if (j == q) continue; /* d.new[j] = d[j] - (alfa[p,j] / alfa[p,q]) * d[q] */ if (mpq_sgn(ap[j]) == 0) continue; mpq_mul(temp, ap[j], cbar[q]); mpq_sub(cbar[j], cbar[j], temp); } mpq_clear(temp); return; } /*---------------------------------------------------------------------- // ssx_change_basis - change current basis to adjacent one. // // This routine changes the current basis to the adjacent one swapping // basic variable xB[p] and non-basic variable xN[q]. */ void ssx_change_basis(SSX *ssx) { int m = ssx->m; int n = ssx->n; int *type = ssx->type; int *stat = ssx->stat; int *Q_row = ssx->Q_row; int *Q_col = ssx->Q_col; int p = ssx->p; int q = ssx->q; int p_stat = ssx->p_stat; int k, kp, kq; if (p < 0) { /* special case: xN[q] goes to its opposite bound */ xassert(1 <= q && q <= n); k = Q_col[m+q]; /* x[k] = xN[q] */ xassert(type[k] == SSX_DB); switch (stat[k]) { case SSX_NL: stat[k] = SSX_NU; break; case SSX_NU: stat[k] = SSX_NL; break; default: xassert(stat != stat); } } else { /* xB[p] leaves the basis, xN[q] enters the basis */ xassert(1 <= p && p <= m); xassert(1 <= q && q <= n); kp = Q_col[p]; /* x[kp] = xB[p] */ kq = Q_col[m+q]; /* x[kq] = xN[q] */ /* check non-basic status of xB[p] which becomes xN[q] */ switch (type[kp]) { case SSX_FR: xassert(p_stat == SSX_NF); break; case SSX_LO: xassert(p_stat == SSX_NL); break; case SSX_UP: xassert(p_stat == SSX_NU); break; case SSX_DB: xassert(p_stat == SSX_NL || p_stat == SSX_NU); break; case SSX_FX: xassert(p_stat == SSX_NS); break; default: xassert(type != type); } /* swap xB[p] and xN[q] */ stat[kp] = (char)p_stat, stat[kq] = SSX_BS; Q_row[kp] = m+q, Q_row[kq] = p; Q_col[p] = kq, Q_col[m+q] = kp; /* update factorization of the basis matrix */ if (bfx_update(ssx->binv, p)) { if (ssx_factorize(ssx)) xassert(("Internal error: basis matrix is singular", 0)); } } return; } /*---------------------------------------------------------------------- // ssx_delete - delete simplex solver workspace. // // This routine deletes the simplex solver workspace freeing all the // memory allocated to this object. */ void ssx_delete(SSX *ssx) { int m = ssx->m; int n = ssx->n; int nnz = ssx->A_ptr[n+1]-1; int i, j, k; xfree(ssx->type); for (k = 1; k <= m+n; k++) mpq_clear(ssx->lb[k]); xfree(ssx->lb); for (k = 1; k <= m+n; k++) mpq_clear(ssx->ub[k]); xfree(ssx->ub); for (k = 0; k <= m+n; k++) mpq_clear(ssx->coef[k]); xfree(ssx->coef); xfree(ssx->A_ptr); xfree(ssx->A_ind); for (k = 1; k <= nnz; k++) mpq_clear(ssx->A_val[k]); xfree(ssx->A_val); xfree(ssx->stat); xfree(ssx->Q_row); xfree(ssx->Q_col); bfx_delete_binv(ssx->binv); for (i = 0; i <= m; i++) mpq_clear(ssx->bbar[i]); xfree(ssx->bbar); for (i = 1; i <= m; i++) mpq_clear(ssx->pi[i]); xfree(ssx->pi); for (j = 1; j <= n; j++) mpq_clear(ssx->cbar[j]); xfree(ssx->cbar); for (i = 1; i <= m; i++) mpq_clear(ssx->rho[i]); xfree(ssx->rho); for (j = 1; j <= n; j++) mpq_clear(ssx->ap[j]); xfree(ssx->ap); for (i = 1; i <= m; i++) mpq_clear(ssx->aq[i]); xfree(ssx->aq); mpq_clear(ssx->delta); xfree(ssx); return; } /* eof */ praat-6.0.04/external/glpk/glpssx02.c000066400000000000000000000407031261542461700173310ustar00rootroot00000000000000/* glpssx02.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #include "glpenv.h" #include "glpssx.h" static void show_progress(SSX *ssx, int phase) { /* this auxiliary routine displays information about progress of the search */ int i, def = 0; for (i = 1; i <= ssx->m; i++) if (ssx->type[ssx->Q_col[i]] == SSX_FX) def++; xprintf("%s%6d: %s = %22.15g (%d)\n", phase == 1 ? " " : "*", ssx->it_cnt, phase == 1 ? "infsum" : "objval", mpq_get_d(ssx->bbar[0]), def); #if 0 ssx->tm_lag = utime(); #else ssx->tm_lag = xtime(); #endif return; } /*---------------------------------------------------------------------- // ssx_phase_I - find primal feasible solution. // // This routine implements phase I of the primal simplex method. // // On exit the routine returns one of the following codes: // // 0 - feasible solution found; // 1 - problem has no feasible solution; // 2 - iterations limit exceeded; // 3 - time limit exceeded. ----------------------------------------------------------------------*/ int ssx_phase_I(SSX *ssx) { int m = ssx->m; int n = ssx->n; int *type = ssx->type; mpq_t *lb = ssx->lb; mpq_t *ub = ssx->ub; mpq_t *coef = ssx->coef; int *A_ptr = ssx->A_ptr; int *A_ind = ssx->A_ind; mpq_t *A_val = ssx->A_val; int *Q_col = ssx->Q_col; mpq_t *bbar = ssx->bbar; mpq_t *pi = ssx->pi; mpq_t *cbar = ssx->cbar; int *orig_type, orig_dir; mpq_t *orig_lb, *orig_ub, *orig_coef; int i, k, ret; /* save components of the original LP problem, which are changed by the routine */ orig_type = xcalloc(1+m+n, sizeof(int)); orig_lb = xcalloc(1+m+n, sizeof(mpq_t)); orig_ub = xcalloc(1+m+n, sizeof(mpq_t)); orig_coef = xcalloc(1+m+n, sizeof(mpq_t)); for (k = 1; k <= m+n; k++) { orig_type[k] = type[k]; mpq_init(orig_lb[k]); mpq_set(orig_lb[k], lb[k]); mpq_init(orig_ub[k]); mpq_set(orig_ub[k], ub[k]); } orig_dir = ssx->dir; for (k = 0; k <= m+n; k++) { mpq_init(orig_coef[k]); mpq_set(orig_coef[k], coef[k]); } /* build an artificial basic solution, which is primal feasible, and also build an auxiliary objective function to minimize the sum of infeasibilities for the original problem */ ssx->dir = SSX_MIN; for (k = 0; k <= m+n; k++) mpq_set_si(coef[k], 0, 1); mpq_set_si(bbar[0], 0, 1); for (i = 1; i <= m; i++) { int t; k = Q_col[i]; /* x[k] = xB[i] */ t = type[k]; if (t == SSX_LO || t == SSX_DB || t == SSX_FX) { /* in the original problem x[k] has lower bound */ if (mpq_cmp(bbar[i], lb[k]) < 0) { /* which is violated */ type[k] = SSX_UP; mpq_set(ub[k], lb[k]); mpq_set_si(lb[k], 0, 1); mpq_set_si(coef[k], -1, 1); mpq_add(bbar[0], bbar[0], ub[k]); mpq_sub(bbar[0], bbar[0], bbar[i]); } } if (t == SSX_UP || t == SSX_DB || t == SSX_FX) { /* in the original problem x[k] has upper bound */ if (mpq_cmp(bbar[i], ub[k]) > 0) { /* which is violated */ type[k] = SSX_LO; mpq_set(lb[k], ub[k]); mpq_set_si(ub[k], 0, 1); mpq_set_si(coef[k], +1, 1); mpq_add(bbar[0], bbar[0], bbar[i]); mpq_sub(bbar[0], bbar[0], lb[k]); } } } /* now the initial basic solution should be primal feasible due to changes of bounds of some basic variables, which turned to implicit artifical variables */ /* compute simplex multipliers and reduced costs */ ssx_eval_pi(ssx); ssx_eval_cbar(ssx); /* display initial progress of the search */ show_progress(ssx, 1); /* main loop starts here */ for (;;) { /* display current progress of the search */ #if 0 if (utime() - ssx->tm_lag >= ssx->out_frq - 0.001) #else if (xdifftime(xtime(), ssx->tm_lag) >= ssx->out_frq - 0.001) #endif show_progress(ssx, 1); /* we do not need to wait until all artificial variables have left the basis */ if (mpq_sgn(bbar[0]) == 0) { /* the sum of infeasibilities is zero, therefore the current solution is primal feasible for the original problem */ ret = 0; break; } /* check if the iterations limit has been exhausted */ if (ssx->it_lim == 0) { ret = 2; break; } /* check if the time limit has been exhausted */ #if 0 if (ssx->tm_lim >= 0.0 && ssx->tm_lim <= utime() - ssx->tm_beg) #else if (ssx->tm_lim >= 0.0 && ssx->tm_lim <= xdifftime(xtime(), ssx->tm_beg)) #endif { ret = 3; break; } /* choose non-basic variable xN[q] */ ssx_chuzc(ssx); /* if xN[q] cannot be chosen, the sum of infeasibilities is minimal but non-zero; therefore the original problem has no primal feasible solution */ if (ssx->q == 0) { ret = 1; break; } /* compute q-th column of the simplex table */ ssx_eval_col(ssx); /* choose basic variable xB[p] */ ssx_chuzr(ssx); /* the sum of infeasibilities cannot be negative, therefore the auxiliary lp problem cannot have unbounded solution */ xassert(ssx->p != 0); /* update values of basic variables */ ssx_update_bbar(ssx); if (ssx->p > 0) { /* compute p-th row of the inverse inv(B) */ ssx_eval_rho(ssx); /* compute p-th row of the simplex table */ ssx_eval_row(ssx); xassert(mpq_cmp(ssx->aq[ssx->p], ssx->ap[ssx->q]) == 0); /* update simplex multipliers */ ssx_update_pi(ssx); /* update reduced costs of non-basic variables */ ssx_update_cbar(ssx); } /* xB[p] is leaving the basis; if it is implicit artificial variable, the corresponding residual vanishes; therefore bounds of this variable should be restored to the original values */ if (ssx->p > 0) { k = Q_col[ssx->p]; /* x[k] = xB[p] */ if (type[k] != orig_type[k]) { /* x[k] is implicit artificial variable */ type[k] = orig_type[k]; mpq_set(lb[k], orig_lb[k]); mpq_set(ub[k], orig_ub[k]); xassert(ssx->p_stat == SSX_NL || ssx->p_stat == SSX_NU); ssx->p_stat = (ssx->p_stat == SSX_NL ? SSX_NU : SSX_NL); if (type[k] == SSX_FX) ssx->p_stat = SSX_NS; /* nullify the objective coefficient at x[k] */ mpq_set_si(coef[k], 0, 1); /* since coef[k] has been changed, we need to compute new reduced cost of x[k], which it will have in the adjacent basis */ /* the formula d[j] = cN[j] - pi' * N[j] is used (note that the vector pi is not changed, because it depends on objective coefficients at basic variables, but in the adjacent basis, for which the vector pi has been just recomputed, x[k] is non-basic) */ if (k <= m) { /* x[k] is auxiliary variable */ mpq_neg(cbar[ssx->q], pi[k]); } else { /* x[k] is structural variable */ int ptr; mpq_t temp; mpq_init(temp); mpq_set_si(cbar[ssx->q], 0, 1); for (ptr = A_ptr[k-m]; ptr < A_ptr[k-m+1]; ptr++) { mpq_mul(temp, pi[A_ind[ptr]], A_val[ptr]); mpq_add(cbar[ssx->q], cbar[ssx->q], temp); } mpq_clear(temp); } } } /* jump to the adjacent vertex of the polyhedron */ ssx_change_basis(ssx); /* one simplex iteration has been performed */ if (ssx->it_lim > 0) ssx->it_lim--; ssx->it_cnt++; } /* display final progress of the search */ show_progress(ssx, 1); /* restore components of the original problem, which were changed by the routine */ for (k = 1; k <= m+n; k++) { type[k] = orig_type[k]; mpq_set(lb[k], orig_lb[k]); mpq_clear(orig_lb[k]); mpq_set(ub[k], orig_ub[k]); mpq_clear(orig_ub[k]); } ssx->dir = orig_dir; for (k = 0; k <= m+n; k++) { mpq_set(coef[k], orig_coef[k]); mpq_clear(orig_coef[k]); } xfree(orig_type); xfree(orig_lb); xfree(orig_ub); xfree(orig_coef); /* return to the calling program */ return ret; } /*---------------------------------------------------------------------- // ssx_phase_II - find optimal solution. // // This routine implements phase II of the primal simplex method. // // On exit the routine returns one of the following codes: // // 0 - optimal solution found; // 1 - problem has unbounded solution; // 2 - iterations limit exceeded; // 3 - time limit exceeded. ----------------------------------------------------------------------*/ int ssx_phase_II(SSX *ssx) { int ret; /* display initial progress of the search */ show_progress(ssx, 2); /* main loop starts here */ for (;;) { /* display current progress of the search */ #if 0 if (utime() - ssx->tm_lag >= ssx->out_frq - 0.001) #else if (xdifftime(xtime(), ssx->tm_lag) >= ssx->out_frq - 0.001) #endif show_progress(ssx, 2); /* check if the iterations limit has been exhausted */ if (ssx->it_lim == 0) { ret = 2; break; } /* check if the time limit has been exhausted */ #if 0 if (ssx->tm_lim >= 0.0 && ssx->tm_lim <= utime() - ssx->tm_beg) #else if (ssx->tm_lim >= 0.0 && ssx->tm_lim <= xdifftime(xtime(), ssx->tm_beg)) #endif { ret = 3; break; } /* choose non-basic variable xN[q] */ ssx_chuzc(ssx); /* if xN[q] cannot be chosen, the current basic solution is dual feasible and therefore optimal */ if (ssx->q == 0) { ret = 0; break; } /* compute q-th column of the simplex table */ ssx_eval_col(ssx); /* choose basic variable xB[p] */ ssx_chuzr(ssx); /* if xB[p] cannot be chosen, the problem has no dual feasible solution (i.e. unbounded) */ if (ssx->p == 0) { ret = 1; break; } /* update values of basic variables */ ssx_update_bbar(ssx); if (ssx->p > 0) { /* compute p-th row of the inverse inv(B) */ ssx_eval_rho(ssx); /* compute p-th row of the simplex table */ ssx_eval_row(ssx); xassert(mpq_cmp(ssx->aq[ssx->p], ssx->ap[ssx->q]) == 0); #if 0 /* update simplex multipliers */ ssx_update_pi(ssx); #endif /* update reduced costs of non-basic variables */ ssx_update_cbar(ssx); } /* jump to the adjacent vertex of the polyhedron */ ssx_change_basis(ssx); /* one simplex iteration has been performed */ if (ssx->it_lim > 0) ssx->it_lim--; ssx->it_cnt++; } /* display final progress of the search */ show_progress(ssx, 2); /* return to the calling program */ return ret; } /*---------------------------------------------------------------------- // ssx_driver - base driver to exact simplex method. // // This routine is a base driver to a version of the primal simplex // method using exact (bignum) arithmetic. // // On exit the routine returns one of the following codes: // // 0 - optimal solution found; // 1 - problem has no feasible solution; // 2 - problem has unbounded solution; // 3 - iterations limit exceeded (phase I); // 4 - iterations limit exceeded (phase II); // 5 - time limit exceeded (phase I); // 6 - time limit exceeded (phase II); // 7 - initial basis matrix is exactly singular. ----------------------------------------------------------------------*/ int ssx_driver(SSX *ssx) { int m = ssx->m; int *type = ssx->type; mpq_t *lb = ssx->lb; mpq_t *ub = ssx->ub; int *Q_col = ssx->Q_col; mpq_t *bbar = ssx->bbar; int i, k, ret; ssx->tm_beg = xtime(); /* factorize the initial basis matrix */ if (ssx_factorize(ssx)) { xprintf("Initial basis matrix is singular\n"); ret = 7; goto done; } /* compute values of basic variables */ ssx_eval_bbar(ssx); /* check if the initial basic solution is primal feasible */ for (i = 1; i <= m; i++) { int t; k = Q_col[i]; /* x[k] = xB[i] */ t = type[k]; if (t == SSX_LO || t == SSX_DB || t == SSX_FX) { /* x[k] has lower bound */ if (mpq_cmp(bbar[i], lb[k]) < 0) { /* which is violated */ break; } } if (t == SSX_UP || t == SSX_DB || t == SSX_FX) { /* x[k] has upper bound */ if (mpq_cmp(bbar[i], ub[k]) > 0) { /* which is violated */ break; } } } if (i > m) { /* no basic variable violates its bounds */ ret = 0; goto skip; } /* phase I: find primal feasible solution */ ret = ssx_phase_I(ssx); switch (ret) { case 0: ret = 0; break; case 1: xprintf("PROBLEM HAS NO FEASIBLE SOLUTION\n"); ret = 1; break; case 2: xprintf("ITERATIONS LIMIT EXCEEDED; SEARCH TERMINATED\n"); ret = 3; break; case 3: xprintf("TIME LIMIT EXCEEDED; SEARCH TERMINATED\n"); ret = 5; break; default: xassert(ret != ret); } /* compute values of basic variables (actually only the objective value needs to be computed) */ ssx_eval_bbar(ssx); skip: /* compute simplex multipliers */ ssx_eval_pi(ssx); /* compute reduced costs of non-basic variables */ ssx_eval_cbar(ssx); /* if phase I failed, do not start phase II */ if (ret != 0) goto done; /* phase II: find optimal solution */ ret = ssx_phase_II(ssx); switch (ret) { case 0: xprintf("OPTIMAL SOLUTION FOUND\n"); ret = 0; break; case 1: xprintf("PROBLEM HAS UNBOUNDED SOLUTION\n"); ret = 2; break; case 2: xprintf("ITERATIONS LIMIT EXCEEDED; SEARCH TERMINATED\n"); ret = 4; break; case 3: xprintf("TIME LIMIT EXCEEDED; SEARCH TERMINATED\n"); ret = 6; break; default: xassert(ret != ret); } done: /* decrease the time limit by the spent amount of time */ if (ssx->tm_lim >= 0.0) #if 0 { ssx->tm_lim -= utime() - ssx->tm_beg; #else { ssx->tm_lim -= xdifftime(xtime(), ssx->tm_beg); #endif if (ssx->tm_lim < 0.0) ssx->tm_lim = 0.0; } return ret; } /* eof */ praat-6.0.04/external/glpk/glpstd.h000066400000000000000000000025461261542461700171540ustar00rootroot00000000000000/* glpstd.h (standard C headers) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPSTD_H #define GLPSTD_H #include #include #include #include #include #include #include #include #include #include #include #include #endif /* eof */ praat-6.0.04/external/glpk/glptsp.c000066400000000000000000000570701261542461700171650ustar00rootroot00000000000000/* glptsp.c */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #define _GLPSTD_ERRNO #define _GLPSTD_STDIO #include "glpenv.h" #include "glptsp.h" #define xfault xerror /*---------------------------------------------------------------------- -- tsp_read_data - read TSP instance data. -- -- *Synopsis* -- -- #include "glptsp.h" -- TSP *tsp_read_data(char *fname); -- -- *Description* -- -- The routine tsp_read_data reads a TSP (or related problem) instance -- data from the text file, whose name is the character string fname. -- -- For detailed description of the format recognized by the routine see -- the report: G.Reinelt, TSPLIB 95. -- -- *Returns* -- -- If no error occurred, the routine tsp_read_data returns a pointer to -- the TSP instance data block, which contains loaded data. In the case -- of error the routine prints an error message and returns NULL. */ struct dsa { /* dynamic storage area used by the routine tsp_read_data */ char *fname; /* name of the input text file */ FILE *fp; /* stream assigned to the input text file */ int seqn; /* line sequential number */ int c; /* current character */ char token[255+1]; /* current token */ }; static int get_char(struct dsa *dsa) { dsa->c = fgetc(dsa->fp); if (ferror(dsa->fp)) { xprintf("%s:%d: read error - %s\n", dsa->fname, dsa->seqn, strerror(errno)); return 1; } if (feof(dsa->fp)) dsa->c = EOF; else if (dsa->c == '\n') dsa->seqn++; else if (isspace(dsa->c)) dsa->c = ' '; else if (iscntrl(dsa->c)) { xprintf("%s:%d: invalid control character 0x%02X\n", dsa->fname, dsa->seqn, dsa->c); return 1; } return 0; } static int skip_spaces(struct dsa *dsa, int across) { while (dsa->c == ' ' || (across && dsa->c == '\n')) if (get_char(dsa)) return 1; return 0; } static int scan_keyword(struct dsa *dsa) { int len = 0; if (skip_spaces(dsa, 0)) return 1; dsa->token[0] = '\0'; while (isalnum(dsa->c) || dsa->c == '_') { if (len == 31) { xprintf("%s:%d: keyword `%s...' too long\n", dsa->fname, dsa->seqn, dsa->token); return 1; } dsa->token[len++] = (char)dsa->c, dsa->token[len] = '\0'; if (get_char(dsa)) return 1; } if (len == 0) { xprintf("%s:%d: missing keyword\n", dsa->fname, dsa->seqn); return 1; } return 0; } static int check_colon(struct dsa *dsa) { if (skip_spaces(dsa, 0)) return 1; if (dsa->c != ':') { xprintf("%s:%d: missing colon after `%s'\n", dsa->fname, dsa->seqn, dsa->token); return 1; } if (get_char(dsa)) return 1; return 0; } static int scan_token(struct dsa *dsa, int across) { int len = 0; if (skip_spaces(dsa, across)) return 1; dsa->token[0] = '\0'; while (!(dsa->c == EOF || dsa->c == '\n' || dsa->c == ' ')) { if (len == 255) { dsa->token[31] = '\0'; xprintf("%s:%d: token `%s...' too long\n", dsa->fname, dsa->seqn, dsa->token); return 1; } dsa->token[len++] = (char)dsa->c, dsa->token[len] = '\0'; if (get_char(dsa)) return 1; } return 0; } static int check_newline(struct dsa *dsa) { if (skip_spaces(dsa, 0)) return 1; if (!(dsa->c == EOF || dsa->c == '\n')) { xprintf("%s:%d: extra symbols detected\n", dsa->fname, dsa->seqn); return 1; } if (get_char(dsa)) return 1; return 0; } static int scan_comment(struct dsa *dsa) { int len = 0; if (skip_spaces(dsa, 0)) return 1; dsa->token[0] = '\0'; while (!(dsa->c == EOF || dsa->c == '\n')) { if (len == 255) { xprintf("%s:%d: comment too long\n", dsa->fname, dsa->seqn) ; return 1; } dsa->token[len++] = (char)dsa->c, dsa->token[len] = '\0'; if (get_char(dsa)) return 1; } return 0; } static int scan_integer(struct dsa *dsa, int across, int *val) { if (scan_token(dsa, across)) return 1; if (strlen(dsa->token) == 0) { xprintf("%s:%d: missing integer\n", dsa->fname, dsa->seqn); return 1; } if (str2int(dsa->token, val)) { xprintf("%s:%d: integer `%s' invalid\n", dsa->fname, dsa->seqn , dsa->token); return 1; } return 0; } static int scan_number(struct dsa *dsa, int across, double *val) { if (scan_token(dsa, across)) return 1; if (strlen(dsa->token) == 0) { xprintf("%s:%d: missing number\n", dsa->fname, dsa->seqn); return 1; } if (str2num(dsa->token, val)) { xprintf("%s:%d: number `%s' invalid\n", dsa->fname, dsa->seqn, dsa->token); return 1; } return 0; } TSP *tsp_read_data(char *fname) { struct dsa _dsa, *dsa = &_dsa; TSP *tsp = NULL; dsa->fname = fname; xprintf("tsp_read_data: reading TSP data from `%s'...\n", dsa->fname); dsa->fp = fopen(dsa->fname, "r"); if (dsa->fp == NULL) { xprintf("tsp_read_data: unable to open `%s' - %s\n", dsa->fname, strerror(errno)); goto fail; } tsp = xmalloc(sizeof(TSP)); tsp->name = NULL; tsp->type = TSP_UNDEF; tsp->comment = NULL; tsp->dimension = 0; tsp->edge_weight_type = TSP_UNDEF; tsp->edge_weight_format = TSP_UNDEF; tsp->display_data_type = TSP_UNDEF; tsp->node_x_coord = NULL; tsp->node_y_coord = NULL; tsp->dply_x_coord = NULL; tsp->dply_y_coord = NULL; tsp->tour = NULL; tsp->edge_weight = NULL; dsa->seqn = 1; if (get_char(dsa)) goto fail; loop: if (scan_keyword(dsa)) goto fail; if (strcmp(dsa->token, "NAME") == 0) { if (tsp->name != NULL) { xprintf("%s:%d: NAME entry multiply defined\n", dsa->fname, dsa->seqn); goto fail; } if (check_colon(dsa)) goto fail; if (scan_token(dsa, 0)) goto fail; if (strlen(dsa->token) == 0) { xprintf("%s:%d: NAME entry incomplete\n", dsa->fname, dsa->seqn); goto fail; } tsp->name = xmalloc(strlen(dsa->token) + 1); strcpy(tsp->name, dsa->token); xprintf("tsp_read_data: NAME: %s\n", tsp->name); if (check_newline(dsa)) goto fail; } else if (strcmp(dsa->token, "TYPE") == 0) { if (tsp->type != TSP_UNDEF) { xprintf("%s:%d: TYPE entry multiply defined\n", dsa->fname, dsa->seqn); goto fail; } if (check_colon(dsa)) goto fail; if (scan_keyword(dsa)) goto fail; if (strcmp(dsa->token, "TSP") == 0) tsp->type = TSP_TSP; else if (strcmp(dsa->token, "ATSP") == 0) tsp->type = TSP_ATSP; else if (strcmp(dsa->token, "TOUR") == 0) tsp->type = TSP_TOUR; else { xprintf("%s:%d: data type `%s' not recognized\n", dsa->fname, dsa->seqn, dsa->token); goto fail; } xprintf("tsp_read_data: TYPE: %s\n", dsa->token); if (check_newline(dsa)) goto fail; } else if (strcmp(dsa->token, "COMMENT") == 0) { if (tsp->comment != NULL) { xprintf("%s:%d: COMMENT entry multiply defined\n", dsa->fname, dsa->seqn); goto fail; } if (check_colon(dsa)) goto fail; if (scan_comment(dsa)) goto fail; tsp->comment = xmalloc(strlen(dsa->token) + 1); strcpy(tsp->comment, dsa->token); xprintf("tsp_read_data: COMMENT: %s\n", tsp->comment); if (check_newline(dsa)) goto fail; } else if (strcmp(dsa->token, "DIMENSION") == 0) { if (tsp->dimension != 0) { xprintf("%s:%d: DIMENSION entry multiply defined\n", dsa->fname, dsa->seqn); goto fail; } if (check_colon(dsa)) goto fail; if (scan_integer(dsa, 0, &tsp->dimension)) goto fail; if (tsp->dimension < 1) { xprintf("%s:%d: invalid dimension\n", dsa->fname, dsa->seqn); goto fail; } xprintf("tsp_read_data: DIMENSION: %d\n", tsp->dimension); if (check_newline(dsa)) goto fail; } else if (strcmp(dsa->token, "EDGE_WEIGHT_TYPE") == 0) { if (tsp->edge_weight_type != TSP_UNDEF) { xprintf("%s:%d: EDGE_WEIGHT_TYPE entry multiply defined\n", dsa->fname, dsa->seqn); goto fail; } if (check_colon(dsa)) goto fail; if (scan_keyword(dsa)) goto fail; if (strcmp(dsa->token, "GEO") == 0) tsp->edge_weight_type = TSP_GEO; else if (strcmp(dsa->token, "EUC_2D") == 0) tsp->edge_weight_type = TSP_EUC_2D; else if (strcmp(dsa->token, "ATT") == 0) tsp->edge_weight_type = TSP_ATT; else if (strcmp(dsa->token, "EXPLICIT") == 0) tsp->edge_weight_type = TSP_EXPLICIT; else if (strcmp(dsa->token, "CEIL_2D") == 0) tsp->edge_weight_type = TSP_CEIL_2D; else { xprintf("%s:%d: edge weight type `%s' not recognized\n", dsa->fname, dsa->seqn, dsa->token); goto fail; } xprintf("tsp_read_data: EDGE_WEIGHT_TYPE: %s\n", dsa->token); if (check_newline(dsa)) goto fail; } else if (strcmp(dsa->token, "EDGE_WEIGHT_FORMAT") == 0) { if (tsp->edge_weight_format != TSP_UNDEF) { xprintf( "%s:%d: EDGE_WEIGHT_FORMAT entry multiply defined\n", dsa->fname, dsa->seqn); goto fail; } if (check_colon(dsa)) goto fail; if (scan_keyword(dsa)) goto fail; if (strcmp(dsa->token, "UPPER_ROW") == 0) tsp->edge_weight_format = TSP_UPPER_ROW; else if (strcmp(dsa->token, "FULL_MATRIX") == 0) tsp->edge_weight_format = TSP_FULL_MATRIX; else if (strcmp(dsa->token, "FUNCTION") == 0) tsp->edge_weight_format = TSP_FUNCTION; else if (strcmp(dsa->token, "LOWER_DIAG_ROW") == 0) tsp->edge_weight_format = TSP_LOWER_DIAG_ROW; else { xprintf("%s:%d: edge weight format `%s' not recognized\n", dsa->fname, dsa->seqn, dsa->token); goto fail; } xprintf("tsp_read_data: EDGE_WEIGHT_FORMAT: %s\n", dsa->token); if (check_newline(dsa)) goto fail; } else if (strcmp(dsa->token, "DISPLAY_DATA_TYPE") == 0) { if (tsp->display_data_type != TSP_UNDEF) { xprintf("%s:%d: DISPLAY_DATA_TYPE entry multiply defined\n", dsa->fname, dsa->seqn); goto fail; } if (check_colon(dsa)) goto fail; if (scan_keyword(dsa)) goto fail; if (strcmp(dsa->token, "COORD_DISPLAY") == 0) tsp->display_data_type = TSP_COORD_DISPLAY; else if (strcmp(dsa->token, "TWOD_DISPLAY") == 0) tsp->display_data_type = TSP_TWOD_DISPLAY; else { xprintf("%s:%d: display data type `%s' not recognized\n", dsa->fname, dsa->seqn, dsa->token); goto fail; } xprintf("tsp_read_data: DISPLAY_DATA_TYPE: %s\n", dsa->token); if (check_newline(dsa)) goto fail; } else if (strcmp(dsa->token, "NODE_COORD_SECTION") == 0) { int n = tsp->dimension, k, node; if (n == 0) { xprintf("%s:%d: DIMENSION entry not specified\n", dsa->fname, dsa->seqn); goto fail; } if (tsp->node_x_coord != NULL) { xprintf("%s:%d: NODE_COORD_SECTION multiply specified\n", dsa->fname, dsa->seqn); goto fail; } if (check_newline(dsa)) goto fail; tsp->node_x_coord = xcalloc(1+n, sizeof(double)); tsp->node_y_coord = xcalloc(1+n, sizeof(double)); for (node = 1; node <= n; node++) tsp->node_x_coord[node] = tsp->node_y_coord[node] = DBL_MAX; for (k = 1; k <= n; k++) { if (scan_integer(dsa, 0, &node)) goto fail; if (!(1 <= node && node <= n)) { xprintf("%s:%d: invalid node number %d\n", dsa->fname, dsa->seqn, node); goto fail; } if (tsp->node_x_coord[node] != DBL_MAX) { xprintf("%s:%d: node number %d multiply specified\n", dsa->fname, dsa->seqn, node); goto fail; } if (scan_number(dsa, 0, &tsp->node_x_coord[node])) goto fail; if (scan_number(dsa, 0, &tsp->node_y_coord[node])) goto fail; if (check_newline(dsa)) goto fail; } } else if (strcmp(dsa->token, "DISPLAY_DATA_SECTION") == 0) { int n = tsp->dimension, k, node; if (n == 0) { xprintf("%s:%d: DIMENSION entry not specified\n", dsa->fname, dsa->seqn); goto fail; } if (tsp->dply_x_coord != NULL) { xprintf("%s:%d: DISPLAY_DATA_SECTION multiply specified\n", dsa->fname, dsa->seqn); goto fail; } if (check_newline(dsa)) goto fail; tsp->dply_x_coord = xcalloc(1+n, sizeof(double)); tsp->dply_y_coord = xcalloc(1+n, sizeof(double)); for (node = 1; node <= n; node++) tsp->dply_x_coord[node] = tsp->dply_y_coord[node] = DBL_MAX; for (k = 1; k <= n; k++) { if (scan_integer(dsa, 0, &node)) goto fail; if (!(1 <= node && node <= n)) { xprintf("%s:%d: invalid node number %d\n", dsa->fname, dsa->seqn, node); goto fail; } if (tsp->dply_x_coord[node] != DBL_MAX) { xprintf("%s:%d: node number %d multiply specified\n", dsa->fname, dsa->seqn, node); goto fail; } if (scan_number(dsa, 0, &tsp->dply_x_coord[node])) goto fail; if (scan_number(dsa, 0, &tsp->dply_y_coord[node])) goto fail; if (check_newline(dsa)) goto fail; } } else if (strcmp(dsa->token, "TOUR_SECTION") == 0) { int n = tsp->dimension, k, node; if (n == 0) { xprintf("%s:%d: DIMENSION entry not specified\n", dsa->fname, dsa->seqn); goto fail; } if (tsp->tour != NULL) { xprintf("%s:%d: TOUR_SECTION multiply specified\n", dsa->fname, dsa->seqn); goto fail; } if (check_newline(dsa)) goto fail; tsp->tour = xcalloc(1+n, sizeof(int)); for (k = 1; k <= n; k++) { if (scan_integer(dsa, 1, &node)) goto fail; if (!(1 <= node && node <= n)) { xprintf("%s:%d: invalid node number %d\n", dsa->fname, dsa->seqn, node); goto fail; } tsp->tour[k] = node; } if (scan_integer(dsa, 1, &node)) goto fail; if (node != -1) { xprintf("%s:%d: extra node(s) detected\n", dsa->fname, dsa->seqn); goto fail; } if (check_newline(dsa)) goto fail; } else if (strcmp(dsa->token, "EDGE_WEIGHT_SECTION") == 0) { int n = tsp->dimension, i, j, temp; if (n == 0) { xprintf("%s:%d: DIMENSION entry not specified\n", dsa->fname, dsa->seqn); goto fail; } if (tsp->edge_weight_format == TSP_UNDEF) { xprintf("%s:%d: EDGE_WEIGHT_FORMAT entry not specified\n", dsa->fname, dsa->seqn); goto fail; } if (tsp->edge_weight != NULL) { xprintf("%s:%d: EDGE_WEIGHT_SECTION multiply specified\n", dsa->fname, dsa->seqn); goto fail; } if (check_newline(dsa)) goto fail; tsp->edge_weight = xcalloc(1+n*n, sizeof(int)); switch (tsp->edge_weight_format) { case TSP_FULL_MATRIX: for (i = 1; i <= n; i++) { for (j = 1; j <= n; j++) { if (scan_integer(dsa, 1, &temp)) goto fail; tsp->edge_weight[(i - 1) * n + j] = temp; } } break; case TSP_UPPER_ROW: for (i = 1; i <= n; i++) { tsp->edge_weight[(i - 1) * n + i] = 0; for (j = i + 1; j <= n; j++) { if (scan_integer(dsa, 1, &temp)) goto fail; tsp->edge_weight[(i - 1) * n + j] = temp; tsp->edge_weight[(j - 1) * n + i] = temp; } } break; case TSP_LOWER_DIAG_ROW: for (i = 1; i <= n; i++) { for (j = 1; j <= i; j++) { if (scan_integer(dsa, 1, &temp)) goto fail; tsp->edge_weight[(i - 1) * n + j] = temp; tsp->edge_weight[(j - 1) * n + i] = temp; } } break; default: goto fail; } if (check_newline(dsa)) goto fail; } else if (strcmp(dsa->token, "EOF") == 0) { if (check_newline(dsa)) goto fail; goto done; } else { xprintf("%s:%d: keyword `%s' not recognized\n", dsa->fname, dsa->seqn, dsa->token); goto fail; } goto loop; done: xprintf("tsp_read_data: %d lines were read\n", dsa->seqn-1); fclose(dsa->fp); return tsp; fail: if (tsp != NULL) { if (tsp->name != NULL) xfree(tsp->name); if (tsp->comment != NULL) xfree(tsp->comment); if (tsp->node_x_coord != NULL) xfree(tsp->node_x_coord); if (tsp->node_y_coord != NULL) xfree(tsp->node_y_coord); if (tsp->dply_x_coord != NULL) xfree(tsp->dply_x_coord); if (tsp->dply_y_coord != NULL) xfree(tsp->dply_y_coord); if (tsp->tour != NULL) xfree(tsp->tour); if (tsp->edge_weight != NULL) xfree(tsp->edge_weight); xfree(tsp); } if (dsa->fp != NULL) fclose(dsa->fp); return NULL; } /*---------------------------------------------------------------------- -- tsp_free_data - free TSP instance data. -- -- *Synopsis* -- -- #include "glptsp.h" -- void tsp_free_data(TSP *tsp); -- -- *Description* -- -- The routine tsp_free_data frees all the memory allocated to the TSP -- instance data block, which the parameter tsp points to. */ void tsp_free_data(TSP *tsp) { if (tsp->name != NULL) xfree(tsp->name); if (tsp->comment != NULL) xfree(tsp->comment); if (tsp->node_x_coord != NULL) xfree(tsp->node_x_coord); if (tsp->node_y_coord != NULL) xfree(tsp->node_y_coord); if (tsp->dply_x_coord != NULL) xfree(tsp->dply_x_coord); if (tsp->dply_y_coord != NULL) xfree(tsp->dply_y_coord); if (tsp->tour != NULL) xfree(tsp->tour); if (tsp->edge_weight != NULL) xfree(tsp->edge_weight); xfree(tsp); return; } /*---------------------------------------------------------------------- -- tsp_distance - compute distance between two nodes. -- -- *Synopsis* -- -- #include "glptsp.h" -- int tsp_distance(TSP *tsp, int i, int j); -- -- *Description* -- -- The routine tsp_distance computes the distance between i-th and j-th -- nodes for the TSP instance, which tsp points to. -- -- *Returns* -- -- The routine tsp_distance returns the computed distance. */ #define nint(x) ((int)((x) + 0.5)) static double rad(double x) { /* convert input coordinate to longitude/latitude, in radians */ double pi = 3.141592, deg, min; deg = (int)x; min = x - deg; return pi * (deg + 5.0 * min / 3.0) / 180.0; } int tsp_distance(TSP *tsp, int i, int j) { int n = tsp->dimension, dij; if (!(tsp->type == TSP_TSP || tsp->type == TSP_ATSP)) xfault("tsp_distance: invalid TSP instance\n"); if (!(1 <= i && i <= n && 1 <= j && j <= n)) xfault("tsp_distance: node number out of range\n"); switch (tsp->edge_weight_type) { case TSP_UNDEF: xfault("tsp_distance: edge weight type not specified\n"); case TSP_EXPLICIT: if (tsp->edge_weight == NULL) xfault("tsp_distance: edge weights not specified\n"); dij = tsp->edge_weight[(i - 1) * n + j]; break; case TSP_EUC_2D: if (tsp->node_x_coord == NULL || tsp->node_y_coord == NULL) xfault("tsp_distance: node coordinates not specified\n"); { double xd, yd; xd = tsp->node_x_coord[i] - tsp->node_x_coord[j]; yd = tsp->node_y_coord[i] - tsp->node_y_coord[j]; dij = nint(sqrt(xd * xd + yd * yd)); } break; case TSP_CEIL_2D: if (tsp->node_x_coord == NULL || tsp->node_y_coord == NULL) xfault("tsp_distance: node coordinates not specified\n"); { double xd, yd; xd = tsp->node_x_coord[i] - tsp->node_x_coord[j]; yd = tsp->node_y_coord[i] - tsp->node_y_coord[j]; dij = (int)ceil(sqrt(xd * xd + yd * yd)); } break; case TSP_GEO: if (tsp->node_x_coord == NULL || tsp->node_y_coord == NULL) xfault("tsp_distance: node coordinates not specified\n"); { double rrr = 6378.388; double latitude_i = rad(tsp->node_x_coord[i]); double latitude_j = rad(tsp->node_x_coord[j]); double longitude_i = rad(tsp->node_y_coord[i]); double longitude_j = rad(tsp->node_y_coord[j]); double q1 = cos(longitude_i - longitude_j); double q2 = cos(latitude_i - latitude_j); double q3 = cos(latitude_i + latitude_j); dij = (int)(rrr * acos(0.5 * ((1.0 + q1) * q2 - (1.0 - q1) *q3)) + 1.0); } break; case TSP_ATT: if (tsp->node_x_coord == NULL || tsp->node_y_coord == NULL) xfault("tsp_distance: node coordinates not specified\n"); { int tij; double xd, yd, rij; xd = tsp->node_x_coord[i] - tsp->node_x_coord[j]; yd = tsp->node_y_coord[i] - tsp->node_y_coord[j]; rij = sqrt((xd * xd + yd * yd) / 10.0); tij = nint(rij); if (tij < rij) dij = tij + 1; else dij = tij; } break; default: xassert(tsp->edge_weight_type != tsp->edge_weight_type); } return dij; } /* eof */ praat-6.0.04/external/glpk/glptsp.h000066400000000000000000000105171261542461700171650ustar00rootroot00000000000000/* glptsp.h (TSP format) */ /*********************************************************************** * This code is part of GLPK (GNU Linear Programming Kit). * * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, * Moscow Aviation Institute, Moscow, Russia. All rights reserved. * E-mail: . * * GLPK is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPK is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License * along with GLPK. If not, see . ***********************************************************************/ #ifndef GLPTSP_H #define GLPTSP_H typedef struct TSP TSP; struct TSP { /* TSP (or related problem) instance in the format described in the report [G.Reinelt, TSPLIB 95] */ /*--------------------------------------------------------------*/ /* the specification part */ char *name; /* identifies the data file */ int type; /* specifies the type of data: */ #define TSP_UNDEF 0 /* undefined */ #define TSP_TSP 1 /* symmetric TSP */ #define TSP_ATSP 2 /* asymmetric TSP */ #define TSP_TOUR 3 /* collection of tours */ char *comment; /* additional comments (usually the name of the contributor or creator of the problem instance is given here) */ int dimension; /* for a TSP or ATSP, the dimension is the number of its nodes for a TOUR it is the dimension of the corresponding problem */ int edge_weight_type; /* specifies how the edge weights (or distances) are given: */ #define TSP_UNDEF 0 /* undefined */ #define TSP_EXPLICIT 1 /* listed explicitly */ #define TSP_EUC_2D 2 /* Eucl. distances in 2-D */ #define TSP_CEIL_2D 3 /* Eucl. distances in 2-D rounded up */ #define TSP_GEO 4 /* geographical distances */ #define TSP_ATT 5 /* special distance function */ int edge_weight_format; /* describes the format of the edge weights if they are given explicitly: */ #define TSP_UNDEF 0 /* undefined */ #define TSP_FUNCTION 1 /* given by a function */ #define TSP_FULL_MATRIX 2 /* given by a full matrix */ #define TSP_UPPER_ROW 3 /* upper triangulat matrix (row-wise without diagonal entries) */ #define TSP_LOWER_DIAG_ROW 4 /* lower triangular matrix (row-wise including diagonal entries) */ int display_data_type; /* specifies how a graphical display of the nodes can be obtained: */ #define TSP_UNDEF 0 /* undefined */ #define TSP_COORD_DISPLAY 1 /* display is generated from the node coordinates */ #define TSP_TWOD_DISPLAY 2 /* explicit coordinates in 2-D are given */ /*--------------------------------------------------------------*/ /* data part */ /* NODE_COORD_SECTION: */ double *node_x_coord; /* double node_x_coord[1+dimension]; */ double *node_y_coord; /* double node_y_coord[1+dimension]; */ /* DISPLAY_DATA_SECTION: */ double *dply_x_coord; /* double dply_x_coord[1+dimension]; */ double *dply_y_coord; /* double dply_y_coord[1+dimension]; */ /* TOUR_SECTION: */ int *tour; /* int tour[1+dimension]; */ /* EDGE_WEIGHT_SECTION: */ int *edge_weight; /* int edge_weight[1+dimension*dimension]; */ }; #define tsp_read_data _glp_tsp_read_data #define tsp_free_data _glp_tsp_free_data #define tsp_distance _glp_tsp_distance TSP *tsp_read_data(char *fname); /* read TSP instance data */ void tsp_free_data(TSP *tsp); /* free TSP instance data */ int tsp_distance(TSP *tsp, int i, int j); /* compute distance between two nodes */ #endif /* eof */ praat-6.0.04/external/gsl/000077500000000000000000000000001261542461700153275ustar00rootroot00000000000000praat-6.0.04/external/gsl/Makefile000066400000000000000000000335561261542461700170030ustar00rootroot00000000000000# Makefile for library gsl. This file was generated by the program flatten_gsl.py # David Weenink, 22 February 2010 include ../../makefile.defs CPPFLAGS = -I ../../sys -I ../../dwsys OBJECTS = gsl_blas__blas.o gsl_block__block.o gsl_block__file.o \ gsl_block__init.o gsl_bspline__bspline.o gsl_cblas__caxpy.o \ gsl_cblas__ccopy.o gsl_cblas__cdotc_sub.o gsl_cblas__cdotu_sub.o \ gsl_cblas__cgbmv.o gsl_cblas__cgemm.o gsl_cblas__cgemv.o \ gsl_cblas__cgerc.o gsl_cblas__cgeru.o gsl_cblas__chbmv.o \ gsl_cblas__chemm.o gsl_cblas__chemv.o gsl_cblas__cher.o \ gsl_cblas__cher2.o gsl_cblas__cher2k.o gsl_cblas__cherk.o \ gsl_cblas__chpmv.o gsl_cblas__chpr.o gsl_cblas__chpr2.o \ gsl_cblas__cscal.o gsl_cblas__csscal.o gsl_cblas__cswap.o \ gsl_cblas__csymm.o gsl_cblas__csyr2k.o gsl_cblas__csyrk.o \ gsl_cblas__ctbmv.o gsl_cblas__ctbsv.o gsl_cblas__ctpmv.o \ gsl_cblas__ctpsv.o gsl_cblas__ctrmm.o gsl_cblas__ctrmv.o \ gsl_cblas__ctrsm.o gsl_cblas__ctrsv.o gsl_cblas__dasum.o \ gsl_cblas__daxpy.o gsl_cblas__dcopy.o gsl_cblas__ddot.o \ gsl_cblas__dgbmv.o gsl_cblas__dgemm.o gsl_cblas__dgemv.o \ gsl_cblas__dger.o gsl_cblas__dnrm2.o gsl_cblas__drot.o \ gsl_cblas__drotg.o gsl_cblas__drotm.o gsl_cblas__drotmg.o \ gsl_cblas__dsbmv.o gsl_cblas__dscal.o gsl_cblas__dsdot.o \ gsl_cblas__dspmv.o gsl_cblas__dspr.o gsl_cblas__dspr2.o \ gsl_cblas__dswap.o gsl_cblas__dsymm.o gsl_cblas__dsymv.o \ gsl_cblas__dsyr.o gsl_cblas__dsyr2.o gsl_cblas__dsyr2k.o \ gsl_cblas__dsyrk.o gsl_cblas__dtbmv.o gsl_cblas__dtbsv.o \ gsl_cblas__dtpmv.o gsl_cblas__dtpsv.o gsl_cblas__dtrmm.o \ gsl_cblas__dtrmv.o gsl_cblas__dtrsm.o gsl_cblas__dtrsv.o \ gsl_cblas__dzasum.o gsl_cblas__dznrm2.o gsl_cblas__icamax.o \ gsl_cblas__idamax.o gsl_cblas__isamax.o gsl_cblas__izamax.o \ gsl_cblas__sasum.o gsl_cblas__saxpy.o gsl_cblas__scasum.o \ gsl_cblas__scnrm2.o gsl_cblas__scopy.o gsl_cblas__sdot.o \ gsl_cblas__sdsdot.o gsl_cblas__sgbmv.o gsl_cblas__sgemm.o \ gsl_cblas__sgemv.o gsl_cblas__sger.o gsl_cblas__snrm2.o \ gsl_cblas__srot.o gsl_cblas__srotg.o gsl_cblas__srotm.o \ gsl_cblas__srotmg.o gsl_cblas__ssbmv.o gsl_cblas__sscal.o \ gsl_cblas__sspmv.o gsl_cblas__sspr.o gsl_cblas__sspr2.o \ gsl_cblas__sswap.o gsl_cblas__ssymm.o gsl_cblas__ssymv.o \ gsl_cblas__ssyr.o gsl_cblas__ssyr2.o gsl_cblas__ssyr2k.o \ gsl_cblas__ssyrk.o gsl_cblas__stbmv.o gsl_cblas__stbsv.o \ gsl_cblas__stpmv.o gsl_cblas__stpsv.o gsl_cblas__strmm.o \ gsl_cblas__strmv.o gsl_cblas__strsm.o gsl_cblas__strsv.o \ gsl_cblas__xerbla.o gsl_cblas__zaxpy.o gsl_cblas__zcopy.o \ gsl_cblas__zdotc_sub.o gsl_cblas__zdotu_sub.o gsl_cblas__zdscal.o \ gsl_cblas__zgbmv.o gsl_cblas__zgemm.o gsl_cblas__zgemv.o \ gsl_cblas__zgerc.o gsl_cblas__zgeru.o gsl_cblas__zhbmv.o \ gsl_cblas__zhemm.o gsl_cblas__zhemv.o gsl_cblas__zher.o \ gsl_cblas__zher2.o gsl_cblas__zher2k.o gsl_cblas__zherk.o \ gsl_cblas__zhpmv.o gsl_cblas__zhpr.o gsl_cblas__zhpr2.o \ gsl_cblas__zscal.o gsl_cblas__zswap.o gsl_cblas__zsymm.o \ gsl_cblas__zsyr2k.o gsl_cblas__zsyrk.o gsl_cblas__ztbmv.o \ gsl_cblas__ztbsv.o gsl_cblas__ztpmv.o gsl_cblas__ztpsv.o \ gsl_cblas__ztrmm.o gsl_cblas__ztrmv.o gsl_cblas__ztrsm.o \ gsl_cblas__ztrsv.o gsl_cdf__beta.o gsl_cdf__betainv.o \ gsl_cdf__binomial.o gsl_cdf__cauchy.o gsl_cdf__cauchyinv.o \ gsl_cdf__chisq.o gsl_cdf__chisqinv.o gsl_cdf__exponential.o \ gsl_cdf__exponentialinv.o gsl_cdf__exppow.o gsl_cdf__fdist.o \ gsl_cdf__fdistinv.o gsl_cdf__flat.o gsl_cdf__flatinv.o \ gsl_cdf__gamma.o gsl_cdf__gammainv.o gsl_cdf__gauss.o \ gsl_cdf__gaussinv.o gsl_cdf__geometric.o gsl_cdf__gumbel1.o \ gsl_cdf__gumbel1inv.o gsl_cdf__gumbel2.o gsl_cdf__gumbel2inv.o \ gsl_cdf__hypergeometric.o gsl_cdf__laplace.o gsl_cdf__laplaceinv.o \ gsl_cdf__logistic.o gsl_cdf__logisticinv.o gsl_cdf__lognormal.o \ gsl_cdf__lognormalinv.o gsl_cdf__nbinomial.o gsl_cdf__pareto.o \ gsl_cdf__paretoinv.o gsl_cdf__pascal.o gsl_cdf__poisson.o \ gsl_cdf__rayleigh.o gsl_cdf__rayleighinv.o gsl_cdf__tdist.o \ gsl_cdf__tdistinv.o gsl_cdf__weibull.o gsl_cdf__weibullinv.o \ gsl_combination__combination.o gsl_combination__file.o gsl_combination__init.o \ gsl_complex__math.o gsl_deriv__deriv.o gsl_dht__dht.o \ gsl_diff__diff.o gsl_eigen__francis.o gsl_eigen__gen.o \ gsl_eigen__genherm.o gsl_eigen__genhermv.o gsl_eigen__gensymm.o \ gsl_eigen__gensymmv.o gsl_eigen__genv.o gsl_eigen__herm.o \ gsl_eigen__hermv.o gsl_eigen__jacobi.o gsl_eigen__nonsymm.o \ gsl_eigen__nonsymmv.o gsl_eigen__schur.o gsl_eigen__sort.o \ gsl_eigen__symm.o gsl_eigen__symmv.o gsl_err__error.o \ gsl_err__message.o gsl_err__stream.o gsl_err__strerror.o \ gsl_fft__dft.o gsl_fft__fft.o gsl_fft__signals.o \ gsl_fit__linear.o gsl_histogram__add.o gsl_histogram__add2d.o \ gsl_histogram__calloc_range.o gsl_histogram__calloc_range2d.o gsl_histogram__copy.o \ gsl_histogram__copy2d.o gsl_histogram__file.o gsl_histogram__file2d.o \ gsl_histogram__get.o gsl_histogram__get2d.o gsl_histogram__init.o \ gsl_histogram__init2d.o gsl_histogram__maxval.o gsl_histogram__maxval2d.o \ gsl_histogram__oper.o gsl_histogram__oper2d.o gsl_histogram__params.o \ gsl_histogram__params2d.o gsl_histogram__pdf.o gsl_histogram__pdf2d.o \ gsl_histogram__reset.o gsl_histogram__reset2d.o gsl_histogram__stat.o \ gsl_histogram__stat2d.o gsl_ieee-utils__env.o gsl_ieee-utils__fp.o \ gsl_ieee-utils__make_rep.o gsl_ieee-utils__print.o gsl_ieee-utils__read.o \ gsl_integration__qag.o gsl_integration__qagp.o gsl_integration__qags.o \ gsl_integration__qawc.o gsl_integration__qawf.o gsl_integration__qawo.o \ gsl_integration__qaws.o gsl_integration__qcheb.o gsl_integration__qk.o \ gsl_integration__qk15.o gsl_integration__qk21.o gsl_integration__qk31.o \ gsl_integration__qk41.o gsl_integration__qk51.o gsl_integration__qk61.o \ gsl_integration__qmomo.o gsl_integration__qmomof.o gsl_integration__qng.o \ gsl_integration__workspace.o gsl_linalg__balance.o gsl_linalg__balancemat.o \ gsl_linalg__bidiag.o gsl_linalg__cholesky.o gsl_linalg__choleskyc.o \ gsl_linalg__exponential.o gsl_linalg__hermtd.o gsl_linalg__hessenberg.o \ gsl_linalg__hesstri.o gsl_linalg__hh.o gsl_linalg__householder.o \ gsl_linalg__householdercomplex.o gsl_linalg__lq.o gsl_linalg__lu.o \ gsl_linalg__luc.o gsl_linalg__multiply.o gsl_linalg__ptlq.o \ gsl_linalg__qr.o gsl_linalg__qrpt.o gsl_linalg__svd.o \ gsl_linalg__symmtd.o gsl_linalg__tridiag.o gsl_matrix__copy.o \ gsl_matrix__file.o gsl_matrix__getset.o gsl_matrix__init.o \ gsl_matrix__matrix.o gsl_matrix__minmax.o gsl_matrix__oper.o \ gsl_matrix__prop.o gsl_matrix__rowcol.o gsl_matrix__submatrix.o \ gsl_matrix__swap.o gsl_matrix__view.o gsl_min__bracketing.o \ gsl_min__brent.o gsl_min__convergence.o gsl_min__fsolver.o \ gsl_min__golden.o gsl_monte__miser.o gsl_monte__plain.o \ gsl_monte__vegas.o gsl_multifit__convergence.o gsl_multifit__covar.o \ gsl_multifit__fdfsolver.o gsl_multifit__fsolver.o gsl_multifit__gradient.o \ gsl_multifit__lmder.o gsl_multifit__multilinear.o gsl_multifit__work.o \ gsl_multimin__conjugate_fr.o gsl_multimin__conjugate_pr.o gsl_multimin__convergence.o \ gsl_multimin__diff.o gsl_multimin__fdfminimizer.o gsl_multimin__fminimizer.o \ gsl_multimin__simplex.o gsl_multimin__steepest_descent.o gsl_multimin__vector_bfgs.o \ gsl_multimin__vector_bfgs2.o gsl_multiroots__broyden.o gsl_multiroots__convergence.o \ gsl_multiroots__dnewton.o gsl_multiroots__fdfsolver.o gsl_multiroots__fdjac.o \ gsl_multiroots__fsolver.o gsl_multiroots__gnewton.o gsl_multiroots__hybrid.o \ gsl_multiroots__hybridj.o gsl_multiroots__newton.o gsl_ntuple__ntuple.o \ gsl_ode-initval__bsimp.o gsl_ode-initval__control.o gsl_ode-initval__cscal.o \ gsl_ode-initval__cstd.o gsl_ode-initval__evolve.o gsl_ode-initval__gear1.o \ gsl_ode-initval__gear2.o gsl_ode-initval__rk2.o gsl_ode-initval__rk2imp.o \ gsl_ode-initval__rk2simp.o gsl_ode-initval__rk4.o gsl_ode-initval__rk4imp.o \ gsl_ode-initval__rk8pd.o gsl_ode-initval__rkck.o gsl_ode-initval__rkf45.o \ gsl_ode-initval__step.o gsl_permutation__canonical.o gsl_permutation__file.o \ gsl_permutation__init.o gsl_permutation__permutation.o gsl_permutation__permute.o \ gsl_poly__dd.o gsl_poly__eval.o gsl_poly__solve_cubic.o \ gsl_poly__solve_quadratic.o gsl_poly__zsolve.o gsl_poly__zsolve_cubic.o \ gsl_poly__zsolve_init.o gsl_poly__zsolve_quadratic.o gsl_qrng__niederreiter-2.o \ gsl_qrng__qrng.o gsl_qrng__sobol.o gsl_randist__bernoulli.o \ gsl_randist__beta.o gsl_randist__bigauss.o gsl_randist__binomial.o \ gsl_randist__binomial_tpe.o gsl_randist__cauchy.o gsl_randist__chisq.o \ gsl_randist__dirichlet.o gsl_randist__discrete.o gsl_randist__erlang.o \ gsl_randist__exponential.o gsl_randist__exppow.o gsl_randist__fdist.o \ gsl_randist__flat.o gsl_randist__gamma.o gsl_randist__gauss.o \ gsl_randist__gausstail.o gsl_randist__gausszig.o gsl_randist__geometric.o \ gsl_randist__gumbel.o gsl_randist__hyperg.o gsl_randist__landau.o \ gsl_randist__laplace.o gsl_randist__levy.o gsl_randist__logarithmic.o \ gsl_randist__logistic.o gsl_randist__lognormal.o gsl_randist__multinomial.o \ gsl_randist__nbinomial.o gsl_randist__pareto.o gsl_randist__pascal.o \ gsl_randist__poisson.o gsl_randist__rayleigh.o gsl_randist__shuffle.o \ gsl_randist__sphere.o gsl_randist__tdist.o gsl_randist__weibull.o \ gsl_rng__borosh13.o gsl_rng__cmrg.o gsl_rng__coveyou.o \ gsl_rng__default.o gsl_rng__file.o gsl_rng__fishman18.o \ gsl_rng__fishman20.o gsl_rng__fishman2x.o gsl_rng__gfsr4.o \ gsl_rng__knuthran.o gsl_rng__knuthran2.o gsl_rng__knuthran2002.o \ gsl_rng__lecuyer21.o gsl_rng__minstd.o gsl_rng__mrg.o \ gsl_rng__mt.o gsl_rng__r250.o gsl_rng__ran0.o \ gsl_rng__ran1.o gsl_rng__ran2.o gsl_rng__ran3.o \ gsl_rng__rand.o gsl_rng__rand48.o gsl_rng__random.o \ gsl_rng__randu.o gsl_rng__ranf.o gsl_rng__ranlux.o \ gsl_rng__ranlxd.o gsl_rng__ranlxs.o gsl_rng__ranmar.o \ gsl_rng__rng.o gsl_rng__slatec.o gsl_rng__taus.o \ gsl_rng__taus113.o gsl_rng__transputer.o gsl_rng__tt.o \ gsl_rng__types.o gsl_rng__uni.o gsl_rng__uni32.o \ gsl_rng__vax.o gsl_rng__waterman14.o gsl_rng__zuf.o \ gsl_roots__bisection.o gsl_roots__brent.o gsl_roots__convergence.o \ gsl_roots__falsepos.o gsl_roots__fdfsolver.o gsl_roots__fsolver.o \ gsl_roots__newton.o gsl_roots__secant.o gsl_roots__steffenson.o \ gsl_siman__siman.o gsl_sort__sort.o gsl_sort__sortind.o \ gsl_sort__sortvec.o gsl_sort__sortvecind.o gsl_sort__subset.o \ gsl_sort__subsetind.o gsl_specfunc__airy.o gsl_specfunc__airy_der.o \ gsl_specfunc__airy_zero.o gsl_specfunc__atanint.o gsl_specfunc__bessel.o \ gsl_specfunc__bessel_I0.o gsl_specfunc__bessel_I1.o gsl_specfunc__bessel_In.o \ gsl_specfunc__bessel_Inu.o gsl_specfunc__bessel_J0.o gsl_specfunc__bessel_J1.o \ gsl_specfunc__bessel_Jn.o gsl_specfunc__bessel_Jnu.o gsl_specfunc__bessel_K0.o \ gsl_specfunc__bessel_K1.o gsl_specfunc__bessel_Kn.o gsl_specfunc__bessel_Knu.o \ gsl_specfunc__bessel_Y0.o gsl_specfunc__bessel_Y1.o gsl_specfunc__bessel_Yn.o \ gsl_specfunc__bessel_Ynu.o gsl_specfunc__bessel_amp_phase.o gsl_specfunc__bessel_i.o \ gsl_specfunc__bessel_j.o gsl_specfunc__bessel_k.o gsl_specfunc__bessel_olver.o \ gsl_specfunc__bessel_sequence.o gsl_specfunc__bessel_temme.o gsl_specfunc__bessel_y.o \ gsl_specfunc__bessel_zero.o gsl_specfunc__beta.o gsl_specfunc__beta_inc.o \ gsl_specfunc__clausen.o gsl_specfunc__coulomb.o gsl_specfunc__coulomb_bound.o \ gsl_specfunc__coupling.o gsl_specfunc__dawson.o gsl_specfunc__debye.o \ gsl_specfunc__dilog.o gsl_specfunc__elementary.o gsl_specfunc__ellint.o \ gsl_specfunc__elljac.o gsl_specfunc__erfc.o gsl_specfunc__exp.o \ gsl_specfunc__expint.o gsl_specfunc__expint3.o gsl_specfunc__fermi_dirac.o \ gsl_specfunc__gamma.o gsl_specfunc__gamma_inc.o gsl_specfunc__gegenbauer.o \ gsl_specfunc__hyperg.o gsl_specfunc__hyperg_0F1.o gsl_specfunc__hyperg_1F1.o \ gsl_specfunc__hyperg_2F0.o gsl_specfunc__hyperg_2F1.o gsl_specfunc__hyperg_U.o \ gsl_specfunc__laguerre.o gsl_specfunc__lambert.o gsl_specfunc__legendre_H3d.o \ gsl_specfunc__legendre_Qn.o gsl_specfunc__legendre_con.o gsl_specfunc__legendre_poly.o \ gsl_specfunc__log.o gsl_specfunc__mathieu_angfunc.o gsl_specfunc__mathieu_charv.o \ gsl_specfunc__mathieu_coeff.o gsl_specfunc__mathieu_radfunc.o gsl_specfunc__mathieu_workspace.o \ gsl_specfunc__poch.o gsl_specfunc__pow_int.o gsl_specfunc__psi.o \ gsl_specfunc__result.o gsl_specfunc__shint.o gsl_specfunc__sinint.o \ gsl_specfunc__synchrotron.o gsl_specfunc__transport.o gsl_specfunc__trig.o \ gsl_specfunc__zeta.o gsl_statistics__absdev.o gsl_statistics__covariance.o \ gsl_statistics__kurtosis.o gsl_statistics__lag1.o gsl_statistics__mean.o \ gsl_statistics__median.o gsl_statistics__minmax.o gsl_statistics__p_variance.o \ gsl_statistics__quantiles.o gsl_statistics__skew.o gsl_statistics__ttest.o \ gsl_statistics__variance.o gsl_statistics__wabsdev.o gsl_statistics__wkurtosis.o \ gsl_statistics__wmean.o gsl_statistics__wskew.o gsl_statistics__wvariance.o \ gsl_sum__levin_u.o gsl_sum__levin_utrunc.o gsl_sum__work_u.o \ gsl_sum__work_utrunc.o gsl_sys__coerce.o gsl_sys__expm1.o \ gsl_sys__fcmp.o gsl_sys__fdiv.o gsl_sys__hypot.o \ gsl_sys__infnan.o gsl_sys__invhyp.o gsl_sys__ldfrexp.o \ gsl_sys__log1p.o gsl_sys__minmax.o gsl_sys__pow_int.o \ gsl_sys__prec.o gsl_vector__copy.o gsl_vector__file.o \ gsl_vector__init.o gsl_vector__minmax.o gsl_vector__oper.o \ gsl_vector__prop.o gsl_vector__reim.o gsl_vector__subvector.o \ gsl_vector__swap.o gsl_vector__vector.o gsl_vector__view.o \ gsl_wavelet__bspline.o gsl_wavelet__daubechies.o gsl_wavelet__dwt.o \ gsl_wavelet__haar.o gsl_wavelet__wavelet.o .PHONY: all clean all: libgsl.a clean: $(RM) $(OBJECTS) $(RM) libgsl.a libgsl.a: $(OBJECTS) touch libgsl.a rm libgsl.a $(AR) cq libgsl.a $(OBJECTS) $(RANLIB) libgsl.a $(OBJECTS): *.h praat-6.0.04/external/gsl/flatten_gsl.py000077500000000000000000000270121261542461700202100ustar00rootroot00000000000000#!/usr/bin/python # # djmw 20080323, 20120511, 20120515, 20120809 # # Makes the directory structure of gsl flat by renaming all files and references by #include # E.g. the file 'd/a.c' will be renamed as: gsl_d__a.c # djmw 20100223 New makefile layout # import os, sys, glob, re, time, shutil version = '1.10' date = time.strftime('%Y%m%d') gslconfigh = 'gsl__config.h' fromdir = '/home/david/praat/gsl/gsl-' + version + '/' todir = '/home/david/praat/gsl/GSL-' + version + '/' log = open (todir + 'flatten_gsl' + version + '.log', 'w') gslconfigh = 'gsl__config.h' print >> log, date dirs = ['blas', 'block', 'bspline', 'cblas', 'cdf', 'combination', 'complex', 'const', 'deriv', 'dht', 'diff', 'doc', 'eigen', 'err', 'fft', 'fit', 'gsl', 'histogram', 'ieee-utils', 'integration', 'linalg', 'matrix', 'min', 'monte', 'multifit', 'multimin', 'multiroots', 'ntuple', 'ode-initval', 'permutation', 'poly', 'qrng', 'randist', 'rng', 'roots', 'siman', 'sort', 'specfunc', 'statistics', 'sum', 'sys', 'vector', 'wavelet'] # left out: utils test itype = 0 imake = 1 idist = 2 iname = 3 icount = 4 ihrep = 5 # per file: [type inmakefile indist renamed_as ntimesincluded headerreplacement] # type = c h def write_to_file (todir, basename, multilinetext): f = open (todir + basename, 'w') f.write (multilinetext) f.close() def dict_from_list (dict, dir, list, type = 'c', inmake = 'y', indist = 'y'): for item in list: newname = 'gsl_' + dir + '__' + item if dir == 'gsl': newname = item dict[dir + '/' + item] = [type, inmake, indist, newname, 0 , ''] def get_all_files (dirs): files = {'./config.h': ['h', 'n', 'y', gslconfigh, 0, ''], \ './templates_on.h':['h', 'n', 'y', 'templates_on.h', 0, ''], \ './templates_off.h':['h', 'n', 'y', 'templates_off.h', 0, '']} for dir in dirs: os.chdir (fromdir + dir) dict_from_list (files, dir, glob.glob('*.c'), 'c', 'y') dict_from_list (files, dir, glob.glob('*.h'), 'h', 'n') return files def quoted_include_get_newname (dict, key): if dict.has_key(key): dict[key][imake] = 'n' if dict[key][ihrep]: newname = dict[key][ihrep] dict['gsl/' + newname][icount] += 1 print >> log, 'Corrected an include header error ' + key + ' ' + newname else: newname = dict[key][iname] dict[key][icount] += 1 return '"' + newname + '"' return None # #include ..... # rewrite to "file.h" # -> # "file.(c|h)" -> "gsl_dir__file.(c|h)" def process_files (dict): include = re.compile (r'^(\s*\#\s*include\s+)([^\s]+)') # 2 groups delim = re.compile (r'(<|")\s*([^\s]+)\s*(>|")') for key, val in dict.items(): (dir, base) = os.path.split (key) if dir == '.': # config.h will be/was done by hand, don't overwrite continue file_in_name = fromdir + key file_in = open (file_in_name, 'r') file_out_name = val[iname] output_lines = '' for line in file_in: minclude = include.search (line) if minclude: headerfile = minclude.group(2) mheader = delim.search (headerfile) header = mheader.group(2) if mheader.group(1) == '<': if header[0:4] == 'gsl/': newname = '"' + header[4:] +'"' dict[header][icount] += 1 elif header == 'config.h': newname = '"' + gslconfigh + '"' dict['./'+header][icount] += 1 else: newname = '<' + header + '>' else: newkey = dir + '/' + header newname = quoted_include_get_newname (dict, newkey) if not newname: newkey = './' + header newname = quoted_include_get_newname (dict, newkey) if not newname: newname = header print >> log, 'File does not exist: '+ header + ' From: ' + key output_lines += minclude.group(1) + newname + '\n' else: output_lines += line if val[idist] == 'y': write_to_file (todir, file_out_name, output_lines) else: dict[key][imake] = 'n' return dict def gen_make_objects (dict, suffix, endofline): make_objects = '' (i , imax) = (0, 3) keysd = dict.keys() keysd.sort() for key in keysd: val = dict[key] if val[imake] == 'n': continue i += 1 post = ' ' if i%imax == 0: post = endofline (root, ext) = os.path.splitext (val[iname]) make_objects += root + suffix + post return make_objects def gen_sconscript(dict): make_objects = gen_make_objects (dict, '.c', ' \n ') sconscript = '''# SConscript for library gsl. This file was generated by the program flatten_gsl.py # djmw ''' + date + ''' sources = Split(""" ''' + make_objects + '''""") Import ('env') env.Library ('GSL', sources) # End of SConscript ''' write_to_file (todir, 'SConscript', sconscript) def gen_makefile (dict): make_objects = gen_make_objects (dict, '.o', ' \\\n ') makefile = """# Makefile for library gsl. This file was generated by the program flatten_gsl.py # djmw """ + date + """ include ../makefile.defs CPPFLAGS = -I ../sys -I ../dwsys OBJECTS = """ + make_objects + """ .PHONY: all clean all: libgsl.a clean: $(RM) $(OBJECTS) $(RM) libgsl.a $(OBJECTS): *.h ../sys/*.h ../dwsys/*.h libgsl.a: $(OBJECTS) touch libgsl.a rm libgsl.a ar cq libgsl.a $(OBJECTS) $(RANLIB) libgsl.a # end of Makefile """ write_to_file (todir, 'Makefile', makefile) def copy_file (fromdir, todir, file): text = open(fromdir + file).read() write_to_file (todir, file, text) def preprocessing (current_gsl_version): if not os.path.exists (todir + gslconfigh): if not os.path.exists (fromdir + 'config.h'): sys.exit(todir + gslconfigh + ' and ' + fromdir + "config.h don't exist. Please run configure first!!") else: text = open(fromdir + 'config.h').read() write_to_file (todir, gslconfigh, text) print >> log, '----------- gsl__config.h created ------------------' copy_file (fromdir,todir, 'templates_on.h') copy_file (fromdir,todir, 'templates_off.h') print >> log, """ Post/Preprocesing The layout of config.h/gsl__config.h varies from one version of gsl to the other Do it by hand in """ + todir + """gsl__config.h: Replace the #define "haves" with #define HAVE_IEEEFP_H 0 #if defined(linux) #define HAVE_DECL_EXPM1 1 #else #define HAVE_DECL_EXPM1 0 #endif #if defined(linux) || defined (_WIN32) #define HAVE_DECL_FINITE 1 #else #define HAVE_DECL_FINITE 0 #endif #if defined(linux) #define HAVE_DECL_HYPOT 1 #else #define HAVE_DECL_HYPOT 0 #endif #if defined(linux) #define HAVE_DECL_ISFINITE 0 #else #define HAVE_DECL_ISFINITE 0 #endif #if defined(linux) #define HAVE_DECL_LOG1P 1 #else #define HAVE_DECL_LOG1P 0 #endif #if defined(linux) #define HAVE_STRDUP 1 #else #define HAVE_STRDUP 0 #endif #if defined(linux) #define HAVE_STRTOL 1 #else #define HAVE_STRTOL 0 #endif #if defined(linux) #define HAVE_STRTOUL 1 #else #define HAVE_STRTOUL 0 #endif #if defined(linux) #define HAVE_DLFCN_H 1 #else #define HAVE_DLFCN_H 0 #endif #if defined(linux) #define HAVE_DECL_FEENABLEEXCEPT 1 #else #define HAVE_DECL_FEENABLEEXCEPT 0 #endif # 3.Inlines: #undef HAVE_INLINE #ifdef sgi #define inline #endif #if defined(linux) || defined (macintosh) || defined (_WIN32) #define HAVE_DECL_ISINF 1 #else #define HAVE_DECL_ISINF 0 #endif #if defined(linux) || defined (macintosh) || defined (_WIN32) #define HAVE_DECL_ISNAN 1 #else #define HAVE_DECL_ISNAN 0 #endif # 4. #if defined(linux) #define HAVE_GNUX86_IEEE_INTERFACE 1 #endif #undef HAVE_GNUSPARC_IEEE_INTERFACE #undef HAVE_GNUM68K_IEEE_INTERFACE #undef HAVE_GNUPPC_IEEE_INTERFACE #undef HAVE_SUNOS4_IEEE_INTERFACE #undef HAVE_SOLARIS_IEEE_INTERFACE #undef HAVE_HPUX11_IEEE_INTERFACE #undef HAVE_HPUX_IEEE_INTERFACE #undef HAVE_TRU64_IEEE_INTERFACE #undef HAVE_IRIX_IEEE_INTERFACE #undef HAVE_AIX_IEEE_INTERFACE #undef HAVE_FREEBSD_IEEE_INTERFACE #undef HAVE_OS2EMX_IEEE_INTERFACE #undef HAVE_NETBSD_IEEE_INTERFACE #undef HAVE_OPENBSD_IEEE_INTERFACE #undef HAVE_DARWIN_IEEE_INTERFACE #undef HAVE_DARWIN86_IEEE_INTERFACE #define GSL_DISABLE_DEPRECATED 1 #define USE_BLAS 0 By hand: Corrected in the fromdir/specfun/coupling.c: #if ! defined (GSL_DISABLE_DEPRECATED) gsl_sf_coupling_6j_INCORRECT_e .... #endif #if ! defined (GSL_DISABLE_DEPRECATED) gsl_sf_coupling_6j_INCORRECT .... #endif """ def post_processing (current_gsl_version): def correct_missing_prototypes (file, linenumber, prototype): f = open (file, 'r') lines = f.readlines () lines.insert (linenumber, prototype + '\n') f.close () f = open (file, 'w') f.writelines (lines) f.close () print >> log, 'Inserted prototype in file '+ file print >> log, ' ' + prototype if current_gsl_version == '1.10': here = todir + '/' correct_missing_prototypes (here + 'gsl_matrix_complex_double.h', 235, \ 'int gsl_matrix_complex_isnonneg (const gsl_matrix_complex * m);') correct_missing_prototypes (here + 'gsl_matrix_complex_float.h', 235, \ 'int gsl_matrix_complex_float_isnonneg (const gsl_matrix_complex_float * m);') correct_missing_prototypes (here + 'gsl_matrix_complex_long_double.h', 235, \ 'int gsl_matrix_complex_long_double_isnonneg (const gsl_matrix_complex_long_double * m);') correct_missing_prototypes (here + 'gsl_vector_complex_double.h', 181, \ 'int gsl_vector_complex_isnonneg (const gsl_vector_complex * v);') correct_missing_prototypes (here + 'gsl_vector_complex_float.h', 181, \ 'int gsl_vector_complex_float_isnonneg (const gsl_vector_complex_float * v);') correct_missing_prototypes (here + 'gsl_vector_complex_long_double.h', 181, \ 'int gsl_vector_complex_long_double_isnonneg (const gsl_vector_complex_long_double * v);') def remove_double_header_files (dict): num = 0 for key,val in dict.items(): (dir, base) = os.path.split (key) if dir == 'gsl': continue newkey = 'gsl/' + base if dict.has_key (newkey): f = open (fromdir + key, 'r') lines1 = f.read() f.close () f = open (fromdir + newkey, 'r') lines2 = f.read() f.close () if lines1 == lines2: num += 1 dict[key][idist] = 'n' dict[key][ihrep] = base print >> log, 'Also in gsl/: ' + key return num def exclude_test_files (dict): starts_with_test = re.compile (r'^test') for key in dict.keys (): (dir, base) = os.path.split (key) if starts_with_test.search (base): dict[key][idist] = 'n' dict['siman/siman_tsp.c'][idist] = 'n' def print_file_selection (dict, type = 'c', inmake = 'n', indist = 'y'): selection = {} for key, val in dict.items(): if val[itype] == type and val[imake] == inmake and val[idist] == indist: selection[key] = val[icount] keyss = selection.keys() keyss.sort() for key in keyss: print >> log, '%3d %s' % (selection[key], key) return len (keyss) preprocessing (version) files = get_all_files (dirs) exclude_test_files (files) print >> log, 'The following header files already exist in the gsl/ directory:' ll = remove_double_header_files (files) print >> log, 'Number of files = %d' % ll print >> log, '\n\n process files' process_files (files) print >> log, '\n\n corect some header files:' post_processing (version) gen_sconscript (files) gen_makefile (files) print >> log, '\n\n header-files' ll = print_file_selection (files, type = 'h') print >> log, 'Number of files = %d' % ll print >> log, '\n\n c-files' ll = print_file_selection (files, type = 'c', inmake = 'y', indist = 'y') print >> log, 'Number of files = %d' % ll print >> log, '\n\n c-files included in other files' ll = print_file_selection (files, type = 'c', inmake = 'n', indist = 'y') print >> log, 'Number of files = %d' % ll print >> log, '\n\n unused header-files' ll = print_file_selection (files, type = 'h', indist = 'n') print >> log, 'Number of files = %d' % ll print >> log, '\n\n unused c-files' ll = print_file_selection (files, type = 'c', indist = 'n') print >> log, 'Number of files = %d' % ll #print str(files) praat-6.0.04/external/gsl/gsl__config.h000066400000000000000000000213641261542461700177570ustar00rootroot00000000000000/* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the declaration of `acosh', and to 0 if you don't. */ #define HAVE_DECL_ACOSH 1 /* Define to 1 if you have the declaration of `asinh', and to 0 if you don't. */ #define HAVE_DECL_ASINH 1 /* Define to 1 if you have the declaration of `atanh', and to 0 if you don't. */ #define HAVE_DECL_ATANH 1 /* Define to 1 if you have the declaration of `expm1', and to 0 if you don't. */ #if defined(linux) || defined (_WIN32) #define HAVE_DECL_EXPM1 1 #else #define HAVE_DECL_EXPM1 0 #endif /* Define to 1 if you have the declaration of `feenableexcept', and to 0 if you don't. */ #if defined(linux) #define HAVE_DECL_FEENABLEEXCEPT 1 #else #define HAVE_DECL_FEENABLEEXCEPT 0 #endif /* Define to 1 if you have the declaration of `fesettrapenable', and to 0 if you don't. */ #define HAVE_DECL_FESETTRAPENABLE 0 /* Define to 1 if you have the declaration of `finite', and to 0 if you don't. */ #if defined(linux) || defined (_WIN32) #define HAVE_DECL_FINITE 1 #else #define HAVE_DECL_FINITE 0 #endif /* Define to 1 if you have the declaration of `frexp', and to 0 if you don't. */ #define HAVE_DECL_FREXP 1 /* Define to 1 if you have the declaration of `hypot', and to 0 if you don't. */ #define HAVE_DECL_HYPOT 1 /* Define to 1 if you have the declaration of `isfinite', and to 0 if you don't. */ #if defined(linux) #define HAVE_DECL_ISFINITE 0 #else #define HAVE_DECL_ISFINITE 0 #endif /* Define to 1 if you have the declaration of `isinf', and to 0 if you don't. */ #if defined(linux) || defined (macintosh) || defined (_WIN32) #define HAVE_DECL_ISINF 1 #else #define HAVE_DECL_ISINF 0 #endif /* Define to 1 if you have the declaration of `isnan', and to 0 if you don't. */ #if defined(linux) || defined (macintosh) || defined (_WIN32) #define HAVE_DECL_ISNAN 1 #else #define HAVE_DECL_ISNAN 0 #endif /* Define to 1 if you have the declaration of `ldexp', and to 0 if you don't. */ #define HAVE_DECL_LDEXP 1 /* Define to 1 if you have the declaration of `log1p', and to 0 if you don't. */ #define HAVE_DECL_LOG1P 1 /* Define to 1 if you have the header file. */ #if defined(linux) #define HAVE_DLFCN_H 1 #else #define HAVE_DLFCN_H 0 #endif /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ /* #undef HAVE_DOPRNT */ /* Defined if you have ansi EXIT_SUCCESS and EXIT_FAILURE in stdlib.h */ #define HAVE_EXIT_SUCCESS_AND_FAILURE 1 /* Defined on architectures with excess floating-point precision */ #define HAVE_EXTENDED_PRECISION_REGISTERS 1 /* Define if x86 processor has sse extensions. */ #define HAVE_FPU_X86_SSE 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_IEEEFP_H */ #define HAVE_IEEEFP_H 0 /* Define this if IEEE comparisons work correctly (e.g. NaN != NaN) */ #define HAVE_IEEE_COMPARISONS 1 /* Define this if IEEE denormalized numbers are available */ #define HAVE_IEEE_DENORMALS 1 /* Define if you have inline */ #undef HAVE_INLINE #ifdef sgi #define inline #endif /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the `m' library (-lm). */ #define HAVE_LIBM 1 /* Define to 1 if you have the `memcpy' function. */ #define HAVE_MEMCPY 1 /* Define to 1 if you have the `memmove' function. */ #define HAVE_MEMMOVE 1 /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 /* Define this if printf can handle %Lf for long double */ #define HAVE_PRINTF_LONGDOUBLE 1 /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the `strdup' function. */ #if defined(linux) #define HAVE_STRDUP 1 #else #define HAVE_STRDUP 0 #endif /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the `strtol' function. */ #if defined(linux) #define HAVE_STRTOL 1 #else #define HAVE_STRTOL 0 #endif /* Define to 1 if you have the `strtoul' function. */ #if defined(linux) #define HAVE_STRTOUL 1 #else #define HAVE_STRTOUL 0 #endif /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to 1 if you have the `vprintf' function. */ #define HAVE_VPRINTF 1 /* Name of package */ #define PACKAGE "gsl" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "" /* Define to the full name of this package. */ #define PACKAGE_NAME "gsl" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "gsl 1.10" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "gsl" /* Define to the version of this package. */ #define PACKAGE_VERSION "1.10" /* Defined if this is an official release */ #define RELEASED /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ #define VERSION "1.10" /* Define to 1 if type `char' is unsigned and you are not using gcc. */ #ifndef __CHAR_UNSIGNED__ /* # undef __CHAR_UNSIGNED__ */ #endif /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus /* #undef inline */ #endif /* Define to `unsigned int' if does not define. */ /* #undef size_t */ /* Define to empty if the keyword `volatile' does not work. Warning: valid code using `volatile' can become incorrect without. Disable with care. */ /* #undef volatile */ /* Define if you need to hide the static definitions of inline functions */ /* #undef HIDE_INLINE_STATIC */ /* Use 0 and 1 for EXIT_SUCCESS and EXIT_FAILURE if we don't have them */ #if !HAVE_EXIT_SUCCESS_AND_FAILURE #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 #endif /* Define one of these if you have a known IEEE arithmetic interface */ /* #undef HAVE_GNUSPARC_IEEE_INTERFACE */ /* #undef HAVE_GNUM68K_IEEE_INTERFACE */ /* #undef HAVE_GNUPPC_IEEE_INTERFACE */ /* #undef HAVE_GNUX86_IEEE_INTERFACE */ /* #undef HAVE_SUNOS4_IEEE_INTERFACE */ /* #undef HAVE_SOLARIS_IEEE_INTERFACE */ /* #undef HAVE_HPUX11_IEEE_INTERFACE */ /* #undef HAVE_HPUX_IEEE_INTERFACE */ /* #undef HAVE_TRU64_IEEE_INTERFACE */ /* #undef HAVE_IRIX_IEEE_INTERFACE */ /* #undef HAVE_AIX_IEEE_INTERFACE */ /* #undef HAVE_FREEBSD_IEEE_INTERFACE */ /* #undef HAVE_OS2EMX_IEEE_INTERFACE */ /* #undef HAVE_NETBSD_IEEE_INTERFACE */ /* #undef HAVE_OPENBSD_IEEE_INTERFACE */ /* #undef HAVE_DARWIN_IEEE_INTERFACE */ /* #undef HAVE_DARWIN86_IEEE_INTERFACE */ /* Define a rounding function which moves extended precision values out of registers and rounds them to double-precision. This should be used *sparingly*, in places where it is necessary to keep double-precision rounding for critical expressions while running in extended precision. For example, the following code should ensure exact equality, even when extended precision registers are in use, double q = GSL_COERCE_DBL(3.0/7.0) ; if (q == GSL_COERCE_DBL(3.0/7.0)) { ... } ; It carries a penalty even when the program is running in double precision mode unless you compile a separate version of the library with HAVE_EXTENDED_PRECISION_REGISTERS turned off. */ #if HAVE_EXTENDED_PRECISION_REGISTERS #define GSL_COERCE_DBL(x) (gsl_coerce_double(x)) #else #define GSL_COERCE_DBL(x) (x) #endif /* Substitute gsl functions for missing system functions */ #if !HAVE_DECL_HYPOT #define hypot gsl_hypot #endif #if !HAVE_DECL_LOG1P #define log1p gsl_log1p #endif #if !HAVE_DECL_EXPM1 #define expm1 gsl_expm1 #endif #if !HAVE_DECL_ACOSH #define acosh gsl_acosh #endif #if !HAVE_DECL_ASINH #define asinh gsl_asinh #endif #if !HAVE_DECL_ATANH #define atanh gsl_atanh #endif #if !HAVE_DECL_LDEXP #define ldexp gsl_ldexp #endif #if !HAVE_DECL_FREXP #define frexp gsl_frexp #endif #if !HAVE_DECL_ISINF #define isinf gsl_isinf #endif #if !HAVE_DECL_FINITE #define finite gsl_finite #endif #if !HAVE_DECL_ISNAN #define isnan gsl_isnan #endif #ifdef __GNUC__ #define DISCARD_POINTER(p) do { ; } while(p ? 0 : 0); #else #define DISCARD_POINTER(p) /* ignoring discarded pointer */ #endif #if defined(GSL_RANGE_CHECK_OFF) || !defined(GSL_RANGE_CHECK) #define GSL_RANGE_CHECK 0 /* turn off range checking by default internally */ #endif /* Disable deprecated functions and enums while building */ #define GSL_DISABLE_DEPRECATED 1 // 20110502 #define USE_BLAS 0 praat-6.0.04/external/gsl/gsl_blas.h000066400000000000000000000526421261542461700172770ustar00rootroot00000000000000/* blas/gsl_blas.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Author: G. Jungman */ #ifndef __GSL_BLAS_H__ #define __GSL_BLAS_H__ #include "gsl_vector.h" #include "gsl_matrix.h" #include "gsl_blas_types.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* ======================================================================== * Level 1 * ======================================================================== */ int gsl_blas_sdsdot (float alpha, const gsl_vector_float * X, const gsl_vector_float * Y, float * result ); int gsl_blas_dsdot (const gsl_vector_float * X, const gsl_vector_float * Y, double * result ); int gsl_blas_sdot (const gsl_vector_float * X, const gsl_vector_float * Y, float * result ); int gsl_blas_ddot (const gsl_vector * X, const gsl_vector * Y, double * result ); int gsl_blas_cdotu (const gsl_vector_complex_float * X, const gsl_vector_complex_float * Y, gsl_complex_float * dotu); int gsl_blas_cdotc (const gsl_vector_complex_float * X, const gsl_vector_complex_float * Y, gsl_complex_float * dotc); int gsl_blas_zdotu (const gsl_vector_complex * X, const gsl_vector_complex * Y, gsl_complex * dotu); int gsl_blas_zdotc (const gsl_vector_complex * X, const gsl_vector_complex * Y, gsl_complex * dotc); float gsl_blas_snrm2 (const gsl_vector_float * X); float gsl_blas_sasum (const gsl_vector_float * X); double gsl_blas_dnrm2 (const gsl_vector * X); double gsl_blas_dasum (const gsl_vector * X); float gsl_blas_scnrm2 (const gsl_vector_complex_float * X); float gsl_blas_scasum (const gsl_vector_complex_float * X); double gsl_blas_dznrm2 (const gsl_vector_complex * X); double gsl_blas_dzasum (const gsl_vector_complex * X); CBLAS_INDEX_t gsl_blas_isamax (const gsl_vector_float * X); CBLAS_INDEX_t gsl_blas_idamax (const gsl_vector * X); CBLAS_INDEX_t gsl_blas_icamax (const gsl_vector_complex_float * X); CBLAS_INDEX_t gsl_blas_izamax (const gsl_vector_complex * X); int gsl_blas_sswap (gsl_vector_float * X, gsl_vector_float * Y); int gsl_blas_scopy (const gsl_vector_float * X, gsl_vector_float * Y); int gsl_blas_saxpy (float alpha, const gsl_vector_float * X, gsl_vector_float * Y); int gsl_blas_dswap (gsl_vector * X, gsl_vector * Y); int gsl_blas_dcopy (const gsl_vector * X, gsl_vector * Y); int gsl_blas_daxpy (double alpha, const gsl_vector * X, gsl_vector * Y); int gsl_blas_cswap (gsl_vector_complex_float * X, gsl_vector_complex_float * Y); int gsl_blas_ccopy (const gsl_vector_complex_float * X, gsl_vector_complex_float * Y); int gsl_blas_caxpy (const gsl_complex_float alpha, const gsl_vector_complex_float * X, gsl_vector_complex_float * Y); int gsl_blas_zswap (gsl_vector_complex * X, gsl_vector_complex * Y); int gsl_blas_zcopy (const gsl_vector_complex * X, gsl_vector_complex * Y); int gsl_blas_zaxpy (const gsl_complex alpha, const gsl_vector_complex * X, gsl_vector_complex * Y); int gsl_blas_srotg (float a[], float b[], float c[], float s[]); int gsl_blas_srotmg (float d1[], float d2[], float b1[], float b2, float P[]); int gsl_blas_srot (gsl_vector_float * X, gsl_vector_float * Y, float c, float s); int gsl_blas_srotm (gsl_vector_float * X, gsl_vector_float * Y, const float P[]); int gsl_blas_drotg (double a[], double b[], double c[], double s[]); int gsl_blas_drotmg (double d1[], double d2[], double b1[], double b2, double P[]); int gsl_blas_drot (gsl_vector * X, gsl_vector * Y, const double c, const double s); int gsl_blas_drotm (gsl_vector * X, gsl_vector * Y, const double P[]); void gsl_blas_sscal (float alpha, gsl_vector_float * X); void gsl_blas_dscal (double alpha, gsl_vector * X); void gsl_blas_cscal (const gsl_complex_float alpha, gsl_vector_complex_float * X); void gsl_blas_zscal (const gsl_complex alpha, gsl_vector_complex * X); void gsl_blas_csscal (float alpha, gsl_vector_complex_float * X); void gsl_blas_zdscal (double alpha, gsl_vector_complex * X); /* =========================================================================== * Level 2 * =========================================================================== */ /* * Routines with standard 4 prefixes (S, D, C, Z) */ int gsl_blas_sgemv (CBLAS_TRANSPOSE_t TransA, float alpha, const gsl_matrix_float * A, const gsl_vector_float * X, float beta, gsl_vector_float * Y); int gsl_blas_strmv (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, const gsl_matrix_float * A, gsl_vector_float * X); int gsl_blas_strsv (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, const gsl_matrix_float * A, gsl_vector_float * X); int gsl_blas_dgemv (CBLAS_TRANSPOSE_t TransA, double alpha, const gsl_matrix * A, const gsl_vector * X, double beta, gsl_vector * Y); int gsl_blas_dtrmv (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, const gsl_matrix * A, gsl_vector * X); int gsl_blas_dtrsv (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, const gsl_matrix * A, gsl_vector * X); int gsl_blas_cgemv (CBLAS_TRANSPOSE_t TransA, const gsl_complex_float alpha, const gsl_matrix_complex_float * A, const gsl_vector_complex_float * X, const gsl_complex_float beta, gsl_vector_complex_float * Y); int gsl_blas_ctrmv (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, const gsl_matrix_complex_float * A, gsl_vector_complex_float * X); int gsl_blas_ctrsv (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, const gsl_matrix_complex_float * A, gsl_vector_complex_float * X); int gsl_blas_zgemv (CBLAS_TRANSPOSE_t TransA, const gsl_complex alpha, const gsl_matrix_complex * A, const gsl_vector_complex * X, const gsl_complex beta, gsl_vector_complex * Y); int gsl_blas_ztrmv (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, const gsl_matrix_complex * A, gsl_vector_complex * X); int gsl_blas_ztrsv (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, const gsl_matrix_complex * A, gsl_vector_complex *X); /* * Routines with S and D prefixes only */ int gsl_blas_ssymv (CBLAS_UPLO_t Uplo, float alpha, const gsl_matrix_float * A, const gsl_vector_float * X, float beta, gsl_vector_float * Y); int gsl_blas_sger (float alpha, const gsl_vector_float * X, const gsl_vector_float * Y, gsl_matrix_float * A); int gsl_blas_ssyr (CBLAS_UPLO_t Uplo, float alpha, const gsl_vector_float * X, gsl_matrix_float * A); int gsl_blas_ssyr2 (CBLAS_UPLO_t Uplo, float alpha, const gsl_vector_float * X, const gsl_vector_float * Y, gsl_matrix_float * A); int gsl_blas_dsymv (CBLAS_UPLO_t Uplo, double alpha, const gsl_matrix * A, const gsl_vector * X, double beta, gsl_vector * Y); int gsl_blas_dger (double alpha, const gsl_vector * X, const gsl_vector * Y, gsl_matrix * A); int gsl_blas_dsyr (CBLAS_UPLO_t Uplo, double alpha, const gsl_vector * X, gsl_matrix * A); int gsl_blas_dsyr2 (CBLAS_UPLO_t Uplo, double alpha, const gsl_vector * X, const gsl_vector * Y, gsl_matrix * A); /* * Routines with C and Z prefixes only */ int gsl_blas_chemv (CBLAS_UPLO_t Uplo, const gsl_complex_float alpha, const gsl_matrix_complex_float * A, const gsl_vector_complex_float * X, const gsl_complex_float beta, gsl_vector_complex_float * Y); int gsl_blas_cgeru (const gsl_complex_float alpha, const gsl_vector_complex_float * X, const gsl_vector_complex_float * Y, gsl_matrix_complex_float * A); int gsl_blas_cgerc (const gsl_complex_float alpha, const gsl_vector_complex_float * X, const gsl_vector_complex_float * Y, gsl_matrix_complex_float * A); int gsl_blas_cher (CBLAS_UPLO_t Uplo, float alpha, const gsl_vector_complex_float * X, gsl_matrix_complex_float * A); int gsl_blas_cher2 (CBLAS_UPLO_t Uplo, const gsl_complex_float alpha, const gsl_vector_complex_float * X, const gsl_vector_complex_float * Y, gsl_matrix_complex_float * A); int gsl_blas_zhemv (CBLAS_UPLO_t Uplo, const gsl_complex alpha, const gsl_matrix_complex * A, const gsl_vector_complex * X, const gsl_complex beta, gsl_vector_complex * Y); int gsl_blas_zgeru (const gsl_complex alpha, const gsl_vector_complex * X, const gsl_vector_complex * Y, gsl_matrix_complex * A); int gsl_blas_zgerc (const gsl_complex alpha, const gsl_vector_complex * X, const gsl_vector_complex * Y, gsl_matrix_complex * A); int gsl_blas_zher (CBLAS_UPLO_t Uplo, double alpha, const gsl_vector_complex * X, gsl_matrix_complex * A); int gsl_blas_zher2 (CBLAS_UPLO_t Uplo, const gsl_complex alpha, const gsl_vector_complex * X, const gsl_vector_complex * Y, gsl_matrix_complex * A); /* * =========================================================================== * Prototypes for level 3 BLAS * =========================================================================== */ /* * Routines with standard 4 prefixes (S, D, C, Z) */ int gsl_blas_sgemm (CBLAS_TRANSPOSE_t TransA, CBLAS_TRANSPOSE_t TransB, float alpha, const gsl_matrix_float * A, const gsl_matrix_float * B, float beta, gsl_matrix_float * C); int gsl_blas_ssymm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, float alpha, const gsl_matrix_float * A, const gsl_matrix_float * B, float beta, gsl_matrix_float * C); int gsl_blas_ssyrk (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, float alpha, const gsl_matrix_float * A, float beta, gsl_matrix_float * C); int gsl_blas_ssyr2k (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, float alpha, const gsl_matrix_float * A, const gsl_matrix_float * B, float beta, gsl_matrix_float * C); int gsl_blas_strmm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, float alpha, const gsl_matrix_float * A, gsl_matrix_float * B); int gsl_blas_strsm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, float alpha, const gsl_matrix_float * A, gsl_matrix_float * B); int gsl_blas_dgemm (CBLAS_TRANSPOSE_t TransA, CBLAS_TRANSPOSE_t TransB, double alpha, const gsl_matrix * A, const gsl_matrix * B, double beta, gsl_matrix * C); int gsl_blas_dsymm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, double alpha, const gsl_matrix * A, const gsl_matrix * B, double beta, gsl_matrix * C); int gsl_blas_dsyrk (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, double alpha, const gsl_matrix * A, double beta, gsl_matrix * C); int gsl_blas_dsyr2k (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, double alpha, const gsl_matrix * A, const gsl_matrix * B, double beta, gsl_matrix * C); int gsl_blas_dtrmm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, double alpha, const gsl_matrix * A, gsl_matrix * B); int gsl_blas_dtrsm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, double alpha, const gsl_matrix * A, gsl_matrix * B); int gsl_blas_cgemm (CBLAS_TRANSPOSE_t TransA, CBLAS_TRANSPOSE_t TransB, const gsl_complex_float alpha, const gsl_matrix_complex_float * A, const gsl_matrix_complex_float * B, const gsl_complex_float beta, gsl_matrix_complex_float * C); int gsl_blas_csymm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, const gsl_complex_float alpha, const gsl_matrix_complex_float * A, const gsl_matrix_complex_float * B, const gsl_complex_float beta, gsl_matrix_complex_float * C); int gsl_blas_csyrk (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, const gsl_complex_float alpha, const gsl_matrix_complex_float * A, const gsl_complex_float beta, gsl_matrix_complex_float * C); int gsl_blas_csyr2k (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, const gsl_complex_float alpha, const gsl_matrix_complex_float * A, const gsl_matrix_complex_float * B, const gsl_complex_float beta, gsl_matrix_complex_float * C); int gsl_blas_ctrmm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, const gsl_complex_float alpha, const gsl_matrix_complex_float * A, gsl_matrix_complex_float * B); int gsl_blas_ctrsm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, const gsl_complex_float alpha, const gsl_matrix_complex_float * A, gsl_matrix_complex_float * B); int gsl_blas_zgemm (CBLAS_TRANSPOSE_t TransA, CBLAS_TRANSPOSE_t TransB, const gsl_complex alpha, const gsl_matrix_complex * A, const gsl_matrix_complex * B, const gsl_complex beta, gsl_matrix_complex * C); int gsl_blas_zsymm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, const gsl_complex alpha, const gsl_matrix_complex * A, const gsl_matrix_complex * B, const gsl_complex beta, gsl_matrix_complex * C); int gsl_blas_zsyrk (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, const gsl_complex alpha, const gsl_matrix_complex * A, const gsl_complex beta, gsl_matrix_complex * C); int gsl_blas_zsyr2k (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, const gsl_complex alpha, const gsl_matrix_complex * A, const gsl_matrix_complex * B, const gsl_complex beta, gsl_matrix_complex *C); int gsl_blas_ztrmm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, const gsl_complex alpha, const gsl_matrix_complex * A, gsl_matrix_complex * B); int gsl_blas_ztrsm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, const gsl_complex alpha, const gsl_matrix_complex * A, gsl_matrix_complex * B); /* * Routines with prefixes C and Z only */ int gsl_blas_chemm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, const gsl_complex_float alpha, const gsl_matrix_complex_float * A, const gsl_matrix_complex_float * B, const gsl_complex_float beta, gsl_matrix_complex_float * C); int gsl_blas_cherk (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, float alpha, const gsl_matrix_complex_float * A, float beta, gsl_matrix_complex_float * C); int gsl_blas_cher2k (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, const gsl_complex_float alpha, const gsl_matrix_complex_float * A, const gsl_matrix_complex_float * B, float beta, gsl_matrix_complex_float * C); int gsl_blas_zhemm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, const gsl_complex alpha, const gsl_matrix_complex * A, const gsl_matrix_complex * B, const gsl_complex beta, gsl_matrix_complex * C); int gsl_blas_zherk (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, double alpha, const gsl_matrix_complex * A, double beta, gsl_matrix_complex * C); int gsl_blas_zher2k (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, const gsl_complex alpha, const gsl_matrix_complex * A, const gsl_matrix_complex * B, double beta, gsl_matrix_complex * C); __END_DECLS #endif /* __GSL_BLAS_H__ */ praat-6.0.04/external/gsl/gsl_blas__blas.c000066400000000000000000001577511261542461700204410ustar00rootroot00000000000000/* blas/blas.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 Gerard Jungman & Brian * Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* GSL implementation of BLAS operations for vectors and dense * matrices. Note that GSL native storage is row-major. */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_cblas.h" #include "gsl_cblas.h" #include "gsl_blas_types.h" #include "gsl_blas.h" /* ======================================================================== * Level 1 * ======================================================================== */ /* CBLAS defines vector sizes in terms of int. GSL defines sizes in terms of size_t, so we need to convert these into integers. There is the possibility of overflow here. FIXME: Maybe this could be caught */ #define INT(X) ((int)(X)) int gsl_blas_sdsdot (float alpha, const gsl_vector_float * X, const gsl_vector_float * Y, float *result) { if (X->size == Y->size) { *result = cblas_sdsdot (INT (X->size), alpha, X->data, INT (X->stride), Y->data, INT (Y->stride)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_dsdot (const gsl_vector_float * X, const gsl_vector_float * Y, double *result) { if (X->size == Y->size) { *result = cblas_dsdot (INT (X->size), X->data, INT (X->stride), Y->data, INT (Y->stride)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_sdot (const gsl_vector_float * X, const gsl_vector_float * Y, float *result) { if (X->size == Y->size) { *result = cblas_sdot (INT (X->size), X->data, INT (X->stride), Y->data, INT (Y->stride)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_ddot (const gsl_vector * X, const gsl_vector * Y, double *result) { if (X->size == Y->size) { *result = cblas_ddot (INT (X->size), X->data, INT (X->stride), Y->data, INT (Y->stride)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_cdotu (const gsl_vector_complex_float * X, const gsl_vector_complex_float * Y, gsl_complex_float * dotu) { if (X->size == Y->size) { cblas_cdotu_sub (INT (X->size), X->data, INT (X->stride), Y->data, INT (Y->stride), GSL_COMPLEX_P (dotu)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_cdotc (const gsl_vector_complex_float * X, const gsl_vector_complex_float * Y, gsl_complex_float * dotc) { if (X->size == Y->size) { cblas_cdotc_sub (INT (X->size), X->data, INT (X->stride), Y->data, INT (Y->stride), GSL_COMPLEX_P (dotc)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_zdotu (const gsl_vector_complex * X, const gsl_vector_complex * Y, gsl_complex * dotu) { if (X->size == Y->size) { cblas_zdotu_sub (INT (X->size), X->data, INT (X->stride), Y->data, INT (Y->stride), GSL_COMPLEX_P (dotu)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_zdotc (const gsl_vector_complex * X, const gsl_vector_complex * Y, gsl_complex * dotc) { if (X->size == Y->size) { cblas_zdotc_sub (INT (X->size), X->data, INT (X->stride), Y->data, INT (Y->stride), GSL_COMPLEX_P (dotc)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } /* Norms of vectors */ float gsl_blas_snrm2 (const gsl_vector_float * X) { return cblas_snrm2 (INT (X->size), X->data, INT (X->stride)); } double gsl_blas_dnrm2 (const gsl_vector * X) { return cblas_dnrm2 (INT (X->size), X->data, INT (X->stride)); } float gsl_blas_scnrm2 (const gsl_vector_complex_float * X) { return cblas_scnrm2 (INT (X->size), X->data, INT (X->stride)); } double gsl_blas_dznrm2 (const gsl_vector_complex * X) { return cblas_dznrm2 (INT (X->size), X->data, INT (X->stride)); } /* Absolute sums of vectors */ float gsl_blas_sasum (const gsl_vector_float * X) { return cblas_sasum (INT (X->size), X->data, INT (X->stride)); } double gsl_blas_dasum (const gsl_vector * X) { return cblas_dasum (INT (X->size), X->data, INT (X->stride)); } float gsl_blas_scasum (const gsl_vector_complex_float * X) { return cblas_scasum (INT (X->size), X->data, INT (X->stride)); } double gsl_blas_dzasum (const gsl_vector_complex * X) { return cblas_dzasum (INT (X->size), X->data, INT (X->stride)); } /* Maximum elements of vectors */ CBLAS_INDEX_t gsl_blas_isamax (const gsl_vector_float * X) { return cblas_isamax (INT (X->size), X->data, INT (X->stride)); } CBLAS_INDEX_t gsl_blas_idamax (const gsl_vector * X) { return cblas_idamax (INT (X->size), X->data, INT (X->stride)); } CBLAS_INDEX_t gsl_blas_icamax (const gsl_vector_complex_float * X) { return cblas_icamax (INT (X->size), X->data, INT (X->stride)); } CBLAS_INDEX_t gsl_blas_izamax (const gsl_vector_complex * X) { return cblas_izamax (INT (X->size), X->data, INT (X->stride)); } /* Swap vectors */ int gsl_blas_sswap (gsl_vector_float * X, gsl_vector_float * Y) { if (X->size == Y->size) { cblas_sswap (INT (X->size), X->data, INT (X->stride), Y->data, INT (Y->stride)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_dswap (gsl_vector * X, gsl_vector * Y) { if (X->size == Y->size) { cblas_dswap (INT (X->size), X->data, INT (X->stride), Y->data, INT (Y->stride)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); }; } int gsl_blas_cswap (gsl_vector_complex_float * X, gsl_vector_complex_float * Y) { if (X->size == Y->size) { cblas_cswap (INT (X->size), X->data, INT (X->stride), Y->data, INT (Y->stride)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_zswap (gsl_vector_complex * X, gsl_vector_complex * Y) { if (X->size == Y->size) { cblas_zswap (INT (X->size), X->data, INT (X->stride), Y->data, INT (Y->stride)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } /* Copy vectors */ int gsl_blas_scopy (const gsl_vector_float * X, gsl_vector_float * Y) { if (X->size == Y->size) { cblas_scopy (INT (X->size), X->data, INT (X->stride), Y->data, INT (Y->stride)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_dcopy (const gsl_vector * X, gsl_vector * Y) { if (X->size == Y->size) { cblas_dcopy (INT (X->size), X->data, INT (X->stride), Y->data, INT (Y->stride)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_ccopy (const gsl_vector_complex_float * X, gsl_vector_complex_float * Y) { if (X->size == Y->size) { cblas_ccopy (INT (X->size), X->data, INT (X->stride), Y->data, INT (Y->stride)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_zcopy (const gsl_vector_complex * X, gsl_vector_complex * Y) { if (X->size == Y->size) { cblas_zcopy (INT (X->size), X->data, INT (X->stride), Y->data, INT (Y->stride)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } /* Compute Y = alpha X + Y */ int gsl_blas_saxpy (float alpha, const gsl_vector_float * X, gsl_vector_float * Y) { if (X->size == Y->size) { cblas_saxpy (INT (X->size), alpha, X->data, INT (X->stride), Y->data, INT (Y->stride)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_daxpy (double alpha, const gsl_vector * X, gsl_vector * Y) { if (X->size == Y->size) { cblas_daxpy (INT (X->size), alpha, X->data, INT (X->stride), Y->data, INT (Y->stride)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_caxpy (const gsl_complex_float alpha, const gsl_vector_complex_float * X, gsl_vector_complex_float * Y) { if (X->size == Y->size) { cblas_caxpy (INT (X->size), GSL_COMPLEX_P (&alpha), X->data, INT (X->stride), Y->data, INT (Y->stride)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_zaxpy (const gsl_complex alpha, const gsl_vector_complex * X, gsl_vector_complex * Y) { if (X->size == Y->size) { cblas_zaxpy (INT (X->size), GSL_COMPLEX_P (&alpha), X->data, INT (X->stride), Y->data, INT (Y->stride)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } /* Generate rotation */ int gsl_blas_srotg (float a[], float b[], float c[], float s[]) { cblas_srotg (a, b, c, s); return GSL_SUCCESS; } int gsl_blas_drotg (double a[], double b[], double c[], double s[]) { cblas_drotg (a, b, c, s); return GSL_SUCCESS; } /* Apply rotation to vectors */ int gsl_blas_srot (gsl_vector_float * X, gsl_vector_float * Y, float c, float s) { if (X->size == Y->size) { cblas_srot (INT (X->size), X->data, INT (X->stride), Y->data, INT (Y->stride), c, s); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_drot (gsl_vector * X, gsl_vector * Y, const double c, const double s) { if (X->size == Y->size) { cblas_drot (INT (X->size), X->data, INT (X->stride), Y->data, INT (Y->stride), c, s); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } /* Generate modified rotation */ int gsl_blas_srotmg (float d1[], float d2[], float b1[], float b2, float P[]) { cblas_srotmg (d1, d2, b1, b2, P); return GSL_SUCCESS; } int gsl_blas_drotmg (double d1[], double d2[], double b1[], double b2, double P[]) { cblas_drotmg (d1, d2, b1, b2, P); return GSL_SUCCESS; } /* Apply modified rotation */ int gsl_blas_srotm (gsl_vector_float * X, gsl_vector_float * Y, const float P[]) { if (X->size == Y->size) { cblas_srotm (INT (X->size), X->data, INT (X->stride), Y->data, INT (Y->stride), P); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_drotm (gsl_vector * X, gsl_vector * Y, const double P[]) { if (X->size != Y->size) { cblas_drotm (INT (X->size), X->data, INT (X->stride), Y->data, INT (Y->stride), P); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } /* Scale vector */ void gsl_blas_sscal (float alpha, gsl_vector_float * X) { cblas_sscal (INT (X->size), alpha, X->data, INT (X->stride)); } void gsl_blas_dscal (double alpha, gsl_vector * X) { cblas_dscal (INT (X->size), alpha, X->data, INT (X->stride)); } void gsl_blas_cscal (const gsl_complex_float alpha, gsl_vector_complex_float * X) { cblas_cscal (INT (X->size), GSL_COMPLEX_P (&alpha), X->data, INT (X->stride)); } void gsl_blas_zscal (const gsl_complex alpha, gsl_vector_complex * X) { cblas_zscal (INT (X->size), GSL_COMPLEX_P (&alpha), X->data, INT (X->stride)); } void gsl_blas_csscal (float alpha, gsl_vector_complex_float * X) { cblas_csscal (INT (X->size), alpha, X->data, INT (X->stride)); } void gsl_blas_zdscal (double alpha, gsl_vector_complex * X) { cblas_zdscal (INT (X->size), alpha, X->data, INT (X->stride)); } /* =========================================================================== * Level 2 * =========================================================================== */ /* GEMV */ int gsl_blas_sgemv (CBLAS_TRANSPOSE_t TransA, float alpha, const gsl_matrix_float * A, const gsl_vector_float * X, float beta, gsl_vector_float * Y) { const size_t M = A->size1; const size_t N = A->size2; if ((TransA == CblasNoTrans && N == X->size && M == Y->size) || (TransA == CblasTrans && M == X->size && N == Y->size)) { cblas_sgemv (CblasRowMajor, TransA, INT (M), INT (N), alpha, A->data, INT (A->tda), X->data, INT (X->stride), beta, Y->data, INT (Y->stride)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_dgemv (CBLAS_TRANSPOSE_t TransA, double alpha, const gsl_matrix * A, const gsl_vector * X, double beta, gsl_vector * Y) { const size_t M = A->size1; const size_t N = A->size2; if ((TransA == CblasNoTrans && N == X->size && M == Y->size) || (TransA == CblasTrans && M == X->size && N == Y->size)) { cblas_dgemv (CblasRowMajor, TransA, INT (M), INT (N), alpha, A->data, INT (A->tda), X->data, INT (X->stride), beta, Y->data, INT (Y->stride)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_cgemv (CBLAS_TRANSPOSE_t TransA, const gsl_complex_float alpha, const gsl_matrix_complex_float * A, const gsl_vector_complex_float * X, const gsl_complex_float beta, gsl_vector_complex_float * Y) { const size_t M = A->size1; const size_t N = A->size2; if ((TransA == CblasNoTrans && N == X->size && M == Y->size) || (TransA == CblasTrans && M == X->size && N == Y->size) || (TransA == CblasConjTrans && M == X->size && N == Y->size)) { cblas_cgemv (CblasRowMajor, TransA, INT (M), INT (N), GSL_COMPLEX_P (&alpha), A->data, INT (A->tda), X->data, INT (X->stride), GSL_COMPLEX_P (&beta), Y->data, INT (Y->stride)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_zgemv (CBLAS_TRANSPOSE_t TransA, const gsl_complex alpha, const gsl_matrix_complex * A, const gsl_vector_complex * X, const gsl_complex beta, gsl_vector_complex * Y) { const size_t M = A->size1; const size_t N = A->size2; if ((TransA == CblasNoTrans && N == X->size && M == Y->size) || (TransA == CblasTrans && M == X->size && N == Y->size) || (TransA == CblasConjTrans && M == X->size && N == Y->size)) { cblas_zgemv (CblasRowMajor, TransA, INT (M), INT (N), GSL_COMPLEX_P (&alpha), A->data, INT (A->tda), X->data, INT (X->stride), GSL_COMPLEX_P (&beta), Y->data, INT (Y->stride)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } /* HEMV */ int gsl_blas_chemv (CBLAS_UPLO_t Uplo, const gsl_complex_float alpha, const gsl_matrix_complex_float * A, const gsl_vector_complex_float * X, const gsl_complex_float beta, gsl_vector_complex_float * Y) { const size_t M = A->size1; const size_t N = A->size2; if (M != N) { GSL_ERROR ("matrix must be square", GSL_ENOTSQR); } else if (N != X->size || N != Y->size) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_chemv (CblasRowMajor, Uplo, INT (N), GSL_COMPLEX_P (&alpha), A->data, INT (A->tda), X->data, INT (X->stride), GSL_COMPLEX_P (&beta), Y->data, INT (Y->stride)); return GSL_SUCCESS; } int gsl_blas_zhemv (CBLAS_UPLO_t Uplo, const gsl_complex alpha, const gsl_matrix_complex * A, const gsl_vector_complex * X, const gsl_complex beta, gsl_vector_complex * Y) { const size_t M = A->size1; const size_t N = A->size2; if (M != N) { GSL_ERROR ("matrix must be square", GSL_ENOTSQR); } else if (N != X->size || N != Y->size) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_zhemv (CblasRowMajor, Uplo, INT (N), GSL_COMPLEX_P (&alpha), A->data, INT (A->tda), X->data, INT (X->stride), GSL_COMPLEX_P (&beta), Y->data, INT (Y->stride)); return GSL_SUCCESS; } /* SYMV */ int gsl_blas_ssymv (CBLAS_UPLO_t Uplo, float alpha, const gsl_matrix_float * A, const gsl_vector_float * X, float beta, gsl_vector_float * Y) { const size_t M = A->size1; const size_t N = A->size2; if (M != N) { GSL_ERROR ("matrix must be square", GSL_ENOTSQR); } else if (N != X->size || N != Y->size) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_ssymv (CblasRowMajor, Uplo, INT (N), alpha, A->data, INT (A->tda), X->data, INT (X->stride), beta, Y->data, INT (Y->stride)); return GSL_SUCCESS; } int gsl_blas_dsymv (CBLAS_UPLO_t Uplo, double alpha, const gsl_matrix * A, const gsl_vector * X, double beta, gsl_vector * Y) { const size_t M = A->size1; const size_t N = A->size2; if (M != N) { GSL_ERROR ("matrix must be square", GSL_ENOTSQR); } else if (N != X->size || N != Y->size) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_dsymv (CblasRowMajor, Uplo, INT (N), alpha, A->data, INT (A->tda), X->data, INT (X->stride), beta, Y->data, INT (Y->stride)); return GSL_SUCCESS; } /* TRMV */ int gsl_blas_strmv (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, const gsl_matrix_float * A, gsl_vector_float * X) { const size_t M = A->size1; const size_t N = A->size2; if (M != N) { GSL_ERROR ("matrix must be square", GSL_ENOTSQR); } else if (N != X->size) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_strmv (CblasRowMajor, Uplo, TransA, Diag, INT (N), A->data, INT (A->tda), X->data, INT (X->stride)); return GSL_SUCCESS; } int gsl_blas_dtrmv (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, const gsl_matrix * A, gsl_vector * X) { const size_t M = A->size1; const size_t N = A->size2; if (M != N) { GSL_ERROR ("matrix must be square", GSL_ENOTSQR); } else if (N != X->size) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_dtrmv (CblasRowMajor, Uplo, TransA, Diag, INT (N), A->data, INT (A->tda), X->data, INT (X->stride)); return GSL_SUCCESS; } int gsl_blas_ctrmv (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, const gsl_matrix_complex_float * A, gsl_vector_complex_float * X) { const size_t M = A->size1; const size_t N = A->size2; if (M != N) { GSL_ERROR ("matrix must be square", GSL_ENOTSQR); } else if (N != X->size) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_ctrmv (CblasRowMajor, Uplo, TransA, Diag, INT (N), A->data, INT (A->tda), X->data, INT (X->stride)); return GSL_SUCCESS; } int gsl_blas_ztrmv (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, const gsl_matrix_complex * A, gsl_vector_complex * X) { const size_t M = A->size1; const size_t N = A->size2; if (M != N) { GSL_ERROR ("matrix must be square", GSL_ENOTSQR); } else if (N != X->size) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_ztrmv (CblasRowMajor, Uplo, TransA, Diag, INT (N), A->data, INT (A->tda), X->data, INT (X->stride)); return GSL_SUCCESS; } /* TRSV */ int gsl_blas_strsv (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, const gsl_matrix_float * A, gsl_vector_float * X) { const size_t M = A->size1; const size_t N = A->size2; if (M != N) { GSL_ERROR ("matrix must be square", GSL_ENOTSQR); } else if (N != X->size) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_strsv (CblasRowMajor, Uplo, TransA, Diag, INT (N), A->data, INT (A->tda), X->data, INT (X->stride)); return GSL_SUCCESS; } int gsl_blas_dtrsv (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, const gsl_matrix * A, gsl_vector * X) { const size_t M = A->size1; const size_t N = A->size2; if (M != N) { GSL_ERROR ("matrix must be square", GSL_ENOTSQR); } else if (N != X->size) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_dtrsv (CblasRowMajor, Uplo, TransA, Diag, INT (N), A->data, INT (A->tda), X->data, INT (X->stride)); return GSL_SUCCESS; } int gsl_blas_ctrsv (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, const gsl_matrix_complex_float * A, gsl_vector_complex_float * X) { const size_t M = A->size1; const size_t N = A->size2; if (M != N) { GSL_ERROR ("matrix must be square", GSL_ENOTSQR); } else if (N != X->size) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_ctrsv (CblasRowMajor, Uplo, TransA, Diag, INT (N), A->data, INT (A->tda), X->data, INT (X->stride)); return GSL_SUCCESS; } int gsl_blas_ztrsv (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, const gsl_matrix_complex * A, gsl_vector_complex * X) { const size_t M = A->size1; const size_t N = A->size2; if (M != N) { GSL_ERROR ("matrix must be square", GSL_ENOTSQR); } else if (N != X->size) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_ztrsv (CblasRowMajor, Uplo, TransA, Diag, INT (N), A->data, INT (A->tda), X->data, INT (X->stride)); return GSL_SUCCESS; } /* GER */ int gsl_blas_sger (float alpha, const gsl_vector_float * X, const gsl_vector_float * Y, gsl_matrix_float * A) { const size_t M = A->size1; const size_t N = A->size2; if (X->size == M && Y->size == N) { cblas_sger (CblasRowMajor, INT (M), INT (N), alpha, X->data, INT (X->stride), Y->data, INT (Y->stride), A->data, INT (A->tda)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_dger (double alpha, const gsl_vector * X, const gsl_vector * Y, gsl_matrix * A) { const size_t M = A->size1; const size_t N = A->size2; if (X->size == M && Y->size == N) { cblas_dger (CblasRowMajor, INT (M), INT (N), alpha, X->data, INT (X->stride), Y->data, INT (Y->stride), A->data, INT (A->tda)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } /* GERU */ int gsl_blas_cgeru (const gsl_complex_float alpha, const gsl_vector_complex_float * X, const gsl_vector_complex_float * Y, gsl_matrix_complex_float * A) { const size_t M = A->size1; const size_t N = A->size2; if (X->size == M && Y->size == N) { cblas_cgeru (CblasRowMajor, INT (M), INT (N), GSL_COMPLEX_P (&alpha), X->data, INT (X->stride), Y->data, INT (Y->stride), A->data, INT (A->tda)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_zgeru (const gsl_complex alpha, const gsl_vector_complex * X, const gsl_vector_complex * Y, gsl_matrix_complex * A) { const size_t M = A->size1; const size_t N = A->size2; if (X->size == M && Y->size == N) { cblas_zgeru (CblasRowMajor, INT (M), INT (N), GSL_COMPLEX_P (&alpha), X->data, INT (X->stride), Y->data, INT (Y->stride), A->data, INT (A->tda)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } /* GERC */ int gsl_blas_cgerc (const gsl_complex_float alpha, const gsl_vector_complex_float * X, const gsl_vector_complex_float * Y, gsl_matrix_complex_float * A) { const size_t M = A->size1; const size_t N = A->size2; if (X->size == M && Y->size == N) { cblas_cgerc (CblasRowMajor, INT (M), INT (N), GSL_COMPLEX_P (&alpha), X->data, INT (X->stride), Y->data, INT (Y->stride), A->data, INT (A->tda)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_zgerc (const gsl_complex alpha, const gsl_vector_complex * X, const gsl_vector_complex * Y, gsl_matrix_complex * A) { const size_t M = A->size1; const size_t N = A->size2; if (X->size == M && Y->size == N) { cblas_zgerc (CblasRowMajor, INT (M), INT (N), GSL_COMPLEX_P (&alpha), X->data, INT (X->stride), Y->data, INT (Y->stride), A->data, INT (A->tda)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } /* HER */ int gsl_blas_cher (CBLAS_UPLO_t Uplo, float alpha, const gsl_vector_complex_float * X, gsl_matrix_complex_float * A) { const size_t M = A->size1; const size_t N = A->size2; if (M != N) { GSL_ERROR ("matrix must be square", GSL_ENOTSQR); } else if (X->size != N) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_cher (CblasRowMajor, Uplo, INT (M), alpha, X->data, INT (X->stride), A->data, INT (A->tda)); return GSL_SUCCESS; } int gsl_blas_zher (CBLAS_UPLO_t Uplo, double alpha, const gsl_vector_complex * X, gsl_matrix_complex * A) { const size_t M = A->size1; const size_t N = A->size2; if (M != N) { GSL_ERROR ("matrix must be square", GSL_ENOTSQR); } else if (X->size != N) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_zher (CblasRowMajor, Uplo, INT (N), alpha, X->data, INT (X->stride), A->data, INT (A->tda)); return GSL_SUCCESS; } /* HER2 */ int gsl_blas_cher2 (CBLAS_UPLO_t Uplo, const gsl_complex_float alpha, const gsl_vector_complex_float * X, const gsl_vector_complex_float * Y, gsl_matrix_complex_float * A) { const size_t M = A->size1; const size_t N = A->size2; if (M != N) { GSL_ERROR ("matrix must be square", GSL_ENOTSQR); } else if (X->size != N || Y->size != N) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_cher2 (CblasRowMajor, Uplo, INT (N), GSL_COMPLEX_P (&alpha), X->data, INT (X->stride), Y->data, INT (Y->stride), A->data, INT (A->tda)); return GSL_SUCCESS; } int gsl_blas_zher2 (CBLAS_UPLO_t Uplo, const gsl_complex alpha, const gsl_vector_complex * X, const gsl_vector_complex * Y, gsl_matrix_complex * A) { const size_t M = A->size1; const size_t N = A->size2; if (M != N) { GSL_ERROR ("matrix must be square", GSL_ENOTSQR); } else if (X->size != N || Y->size != N) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_zher2 (CblasRowMajor, Uplo, INT (N), GSL_COMPLEX_P (&alpha), X->data, INT (X->stride), Y->data, INT (Y->stride), A->data, INT (A->tda)); return GSL_SUCCESS; } /* SYR */ int gsl_blas_ssyr (CBLAS_UPLO_t Uplo, float alpha, const gsl_vector_float * X, gsl_matrix_float * A) { const size_t M = A->size1; const size_t N = A->size2; if (M != N) { GSL_ERROR ("matrix must be square", GSL_ENOTSQR); } else if (X->size != N) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_ssyr (CblasRowMajor, Uplo, INT (N), alpha, X->data, INT (X->stride), A->data, INT (A->tda)); return GSL_SUCCESS; } int gsl_blas_dsyr (CBLAS_UPLO_t Uplo, double alpha, const gsl_vector * X, gsl_matrix * A) { const size_t M = A->size1; const size_t N = A->size2; if (M != N) { GSL_ERROR ("matrix must be square", GSL_ENOTSQR); } else if (X->size != N) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_dsyr (CblasRowMajor, Uplo, INT (N), alpha, X->data, INT (X->stride), A->data, INT (A->tda)); return GSL_SUCCESS; } /* SYR2 */ int gsl_blas_ssyr2 (CBLAS_UPLO_t Uplo, float alpha, const gsl_vector_float * X, const gsl_vector_float * Y, gsl_matrix_float * A) { const size_t M = A->size1; const size_t N = A->size2; if (M != N) { GSL_ERROR ("matrix must be square", GSL_ENOTSQR); } else if (X->size != N || Y->size != N) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_ssyr2 (CblasRowMajor, Uplo, INT (N), alpha, X->data, INT (X->stride), Y->data, INT (Y->stride), A->data, INT (A->tda)); return GSL_SUCCESS; } int gsl_blas_dsyr2 (CBLAS_UPLO_t Uplo, double alpha, const gsl_vector * X, const gsl_vector * Y, gsl_matrix * A) { const size_t M = A->size1; const size_t N = A->size2; if (M != N) { GSL_ERROR ("matrix must be square", GSL_ENOTSQR); } else if (X->size != N || Y->size != N) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_dsyr2 (CblasRowMajor, Uplo, INT (N), alpha, X->data, INT (X->stride), Y->data, INT (Y->stride), A->data, INT (A->tda)); return GSL_SUCCESS; } /* * =========================================================================== * Prototypes for level 3 BLAS * =========================================================================== */ /* GEMM */ int gsl_blas_sgemm (CBLAS_TRANSPOSE_t TransA, CBLAS_TRANSPOSE_t TransB, float alpha, const gsl_matrix_float * A, const gsl_matrix_float * B, float beta, gsl_matrix_float * C) { const size_t M = C->size1; const size_t N = C->size2; const size_t MA = (TransA == CblasNoTrans) ? A->size1 : A->size2; const size_t NA = (TransA == CblasNoTrans) ? A->size2 : A->size1; const size_t MB = (TransB == CblasNoTrans) ? B->size1 : B->size2; const size_t NB = (TransB == CblasNoTrans) ? B->size2 : B->size1; if (M == MA && N == NB && NA == MB) /* [MxN] = [MAxNA][MBxNB] */ { cblas_sgemm (CblasRowMajor, TransA, TransB, INT (M), INT (N), INT (NA), alpha, A->data, INT (A->tda), B->data, INT (B->tda), beta, C->data, INT (C->tda)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_dgemm (CBLAS_TRANSPOSE_t TransA, CBLAS_TRANSPOSE_t TransB, double alpha, const gsl_matrix * A, const gsl_matrix * B, double beta, gsl_matrix * C) { const size_t M = C->size1; const size_t N = C->size2; const size_t MA = (TransA == CblasNoTrans) ? A->size1 : A->size2; const size_t NA = (TransA == CblasNoTrans) ? A->size2 : A->size1; const size_t MB = (TransB == CblasNoTrans) ? B->size1 : B->size2; const size_t NB = (TransB == CblasNoTrans) ? B->size2 : B->size1; if (M == MA && N == NB && NA == MB) /* [MxN] = [MAxNA][MBxNB] */ { cblas_dgemm (CblasRowMajor, TransA, TransB, INT (M), INT (N), INT (NA), alpha, A->data, INT (A->tda), B->data, INT (B->tda), beta, C->data, INT (C->tda)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_cgemm (CBLAS_TRANSPOSE_t TransA, CBLAS_TRANSPOSE_t TransB, const gsl_complex_float alpha, const gsl_matrix_complex_float * A, const gsl_matrix_complex_float * B, const gsl_complex_float beta, gsl_matrix_complex_float * C) { const size_t M = C->size1; const size_t N = C->size2; const size_t MA = (TransA == CblasNoTrans) ? A->size1 : A->size2; const size_t NA = (TransA == CblasNoTrans) ? A->size2 : A->size1; const size_t MB = (TransB == CblasNoTrans) ? B->size1 : B->size2; const size_t NB = (TransB == CblasNoTrans) ? B->size2 : B->size1; if (M == MA && N == NB && NA == MB) /* [MxN] = [MAxNA][MBxNB] */ { cblas_cgemm (CblasRowMajor, TransA, TransB, INT (M), INT (N), INT (NA), GSL_COMPLEX_P (&alpha), A->data, INT (A->tda), B->data, INT (B->tda), GSL_COMPLEX_P (&beta), C->data, INT (C->tda)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_zgemm (CBLAS_TRANSPOSE_t TransA, CBLAS_TRANSPOSE_t TransB, const gsl_complex alpha, const gsl_matrix_complex * A, const gsl_matrix_complex * B, const gsl_complex beta, gsl_matrix_complex * C) { const size_t M = C->size1; const size_t N = C->size2; const size_t MA = (TransA == CblasNoTrans) ? A->size1 : A->size2; const size_t NA = (TransA == CblasNoTrans) ? A->size2 : A->size1; const size_t MB = (TransB == CblasNoTrans) ? B->size1 : B->size2; const size_t NB = (TransB == CblasNoTrans) ? B->size2 : B->size1; if (M == MA && N == NB && NA == MB) /* [MxN] = [MAxNA][MBxNB] */ { cblas_zgemm (CblasRowMajor, TransA, TransB, INT (M), INT (N), INT (NA), GSL_COMPLEX_P (&alpha), A->data, INT (A->tda), B->data, INT (B->tda), GSL_COMPLEX_P (&beta), C->data, INT (C->tda)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } /* SYMM */ int gsl_blas_ssymm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, float alpha, const gsl_matrix_float * A, const gsl_matrix_float * B, float beta, gsl_matrix_float * C) { const size_t M = C->size1; const size_t N = C->size2; const size_t MA = A->size1; const size_t NA = A->size2; const size_t MB = B->size1; const size_t NB = B->size2; if (MA != NA) { GSL_ERROR ("matrix A must be square", GSL_ENOTSQR); } if ((Side == CblasLeft && (M == MA && N == NB && NA == MB)) || (Side == CblasRight && (M == MB && N == NA && NB == MA))) { cblas_ssymm (CblasRowMajor, Side, Uplo, INT (M), INT (N), alpha, A->data, INT (A->tda), B->data, INT (B->tda), beta, C->data, INT (C->tda)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_dsymm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, double alpha, const gsl_matrix * A, const gsl_matrix * B, double beta, gsl_matrix * C) { const size_t M = C->size1; const size_t N = C->size2; const size_t MA = A->size1; const size_t NA = A->size2; const size_t MB = B->size1; const size_t NB = B->size2; if (MA != NA) { GSL_ERROR ("matrix A must be square", GSL_ENOTSQR); } if ((Side == CblasLeft && (M == MA && N == NB && NA == MB)) || (Side == CblasRight && (M == MB && N == NA && NB == MA))) { cblas_dsymm (CblasRowMajor, Side, Uplo, INT (M), INT (N), alpha, A->data, INT (A->tda), B->data, INT (B->tda), beta, C->data, INT (C->tda)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_csymm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, const gsl_complex_float alpha, const gsl_matrix_complex_float * A, const gsl_matrix_complex_float * B, const gsl_complex_float beta, gsl_matrix_complex_float * C) { const size_t M = C->size1; const size_t N = C->size2; const size_t MA = A->size1; const size_t NA = A->size2; const size_t MB = B->size1; const size_t NB = B->size2; if (MA != NA) { GSL_ERROR ("matrix A must be square", GSL_ENOTSQR); } if ((Side == CblasLeft && (M == MA && N == NB && NA == MB)) || (Side == CblasRight && (M == MB && N == NA && NB == MA))) { cblas_csymm (CblasRowMajor, Side, Uplo, INT (M), INT (N), GSL_COMPLEX_P (&alpha), A->data, INT (A->tda), B->data, INT (B->tda), GSL_COMPLEX_P (&beta), C->data, INT (C->tda)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_zsymm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, const gsl_complex alpha, const gsl_matrix_complex * A, const gsl_matrix_complex * B, const gsl_complex beta, gsl_matrix_complex * C) { const size_t M = C->size1; const size_t N = C->size2; const size_t MA = A->size1; const size_t NA = A->size2; const size_t MB = B->size1; const size_t NB = B->size2; if (MA != NA) { GSL_ERROR ("matrix A must be square", GSL_ENOTSQR); } if ((Side == CblasLeft && (M == MA && N == NB && NA == MB)) || (Side == CblasRight && (M == MB && N == NA && NB == MA))) { cblas_zsymm (CblasRowMajor, Side, Uplo, INT (M), INT (N), GSL_COMPLEX_P (&alpha), A->data, INT (A->tda), B->data, INT (B->tda), GSL_COMPLEX_P (&beta), C->data, INT (C->tda)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } /* HEMM */ int gsl_blas_chemm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, const gsl_complex_float alpha, const gsl_matrix_complex_float * A, const gsl_matrix_complex_float * B, const gsl_complex_float beta, gsl_matrix_complex_float * C) { const size_t M = C->size1; const size_t N = C->size2; const size_t MA = A->size1; const size_t NA = A->size2; const size_t MB = B->size1; const size_t NB = B->size2; if (MA != NA) { GSL_ERROR ("matrix A must be square", GSL_ENOTSQR); } if ((Side == CblasLeft && (M == MA && N == NB && NA == MB)) || (Side == CblasRight && (M == MB && N == NA && NB == MA))) { cblas_chemm (CblasRowMajor, Side, Uplo, INT (M), INT (N), GSL_COMPLEX_P (&alpha), A->data, INT (A->tda), B->data, INT (B->tda), GSL_COMPLEX_P (&beta), C->data, INT (C->tda)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_zhemm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, const gsl_complex alpha, const gsl_matrix_complex * A, const gsl_matrix_complex * B, const gsl_complex beta, gsl_matrix_complex * C) { const size_t M = C->size1; const size_t N = C->size2; const size_t MA = A->size1; const size_t NA = A->size2; const size_t MB = B->size1; const size_t NB = B->size2; if (MA != NA) { GSL_ERROR ("matrix A must be square", GSL_ENOTSQR); } if ((Side == CblasLeft && (M == MA && N == NB && NA == MB)) || (Side == CblasRight && (M == MB && N == NA && NB == MA))) { cblas_zhemm (CblasRowMajor, Side, Uplo, INT (M), INT (N), GSL_COMPLEX_P (&alpha), A->data, INT (A->tda), B->data, INT (B->tda), GSL_COMPLEX_P (&beta), C->data, INT (C->tda)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } /* SYRK */ int gsl_blas_ssyrk (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, float alpha, const gsl_matrix_float * A, float beta, gsl_matrix_float * C) { const size_t M = C->size1; const size_t N = C->size2; const size_t J = (Trans == CblasNoTrans) ? A->size1 : A->size2; const size_t K = (Trans == CblasNoTrans) ? A->size2 : A->size1; if (M != N) { GSL_ERROR ("matrix C must be square", GSL_ENOTSQR); } else if (N != J) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_ssyrk (CblasRowMajor, Uplo, Trans, INT (N), INT (K), alpha, A->data, INT (A->tda), beta, C->data, INT (C->tda)); return GSL_SUCCESS; } int gsl_blas_dsyrk (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, double alpha, const gsl_matrix * A, double beta, gsl_matrix * C) { const size_t M = C->size1; const size_t N = C->size2; const size_t J = (Trans == CblasNoTrans) ? A->size1 : A->size2; const size_t K = (Trans == CblasNoTrans) ? A->size2 : A->size1; if (M != N) { GSL_ERROR ("matrix C must be square", GSL_ENOTSQR); } else if (N != J) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_dsyrk (CblasRowMajor, Uplo, Trans, INT (N), INT (K), alpha, A->data, INT (A->tda), beta, C->data, INT (C->tda)); return GSL_SUCCESS; } int gsl_blas_csyrk (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, const gsl_complex_float alpha, const gsl_matrix_complex_float * A, const gsl_complex_float beta, gsl_matrix_complex_float * C) { const size_t M = C->size1; const size_t N = C->size2; const size_t J = (Trans == CblasNoTrans) ? A->size1 : A->size2; const size_t K = (Trans == CblasNoTrans) ? A->size2 : A->size1; if (M != N) { GSL_ERROR ("matrix C must be square", GSL_ENOTSQR); } else if (N != J) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_csyrk (CblasRowMajor, Uplo, Trans, INT (N), INT (K), GSL_COMPLEX_P (&alpha), A->data, INT (A->tda), GSL_COMPLEX_P (&beta), C->data, INT (C->tda)); return GSL_SUCCESS; } int gsl_blas_zsyrk (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, const gsl_complex alpha, const gsl_matrix_complex * A, const gsl_complex beta, gsl_matrix_complex * C) { const size_t M = C->size1; const size_t N = C->size2; const size_t J = (Trans == CblasNoTrans) ? A->size1 : A->size2; const size_t K = (Trans == CblasNoTrans) ? A->size2 : A->size1; if (M != N) { GSL_ERROR ("matrix C must be square", GSL_ENOTSQR); } else if (N != J) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_zsyrk (CblasRowMajor, Uplo, Trans, INT (N), INT (K), GSL_COMPLEX_P (&alpha), A->data, INT (A->tda), GSL_COMPLEX_P (&beta), C->data, INT (C->tda)); return GSL_SUCCESS; } /* HERK */ int gsl_blas_cherk (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, float alpha, const gsl_matrix_complex_float * A, float beta, gsl_matrix_complex_float * C) { const size_t M = C->size1; const size_t N = C->size2; const size_t J = (Trans == CblasNoTrans) ? A->size1 : A->size2; const size_t K = (Trans == CblasNoTrans) ? A->size2 : A->size1; if (M != N) { GSL_ERROR ("matrix C must be square", GSL_ENOTSQR); } else if (N != J) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_cherk (CblasRowMajor, Uplo, Trans, INT (N), INT (K), alpha, A->data, INT (A->tda), beta, C->data, INT (C->tda)); return GSL_SUCCESS; } int gsl_blas_zherk (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, double alpha, const gsl_matrix_complex * A, double beta, gsl_matrix_complex * C) { const size_t M = C->size1; const size_t N = C->size2; const size_t J = (Trans == CblasNoTrans) ? A->size1 : A->size2; const size_t K = (Trans == CblasNoTrans) ? A->size2 : A->size1; if (M != N) { GSL_ERROR ("matrix C must be square", GSL_ENOTSQR); } else if (N != J) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_zherk (CblasRowMajor, Uplo, Trans, INT (N), INT (K), alpha, A->data, INT (A->tda), beta, C->data, INT (C->tda)); return GSL_SUCCESS; } /* SYR2K */ int gsl_blas_ssyr2k (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, float alpha, const gsl_matrix_float * A, const gsl_matrix_float * B, float beta, gsl_matrix_float * C) { const size_t M = C->size1; const size_t N = C->size2; const size_t MA = (Trans == CblasNoTrans) ? A->size1 : A->size2; const size_t NA = (Trans == CblasNoTrans) ? A->size2 : A->size1; const size_t MB = (Trans == CblasNoTrans) ? B->size1 : B->size2; const size_t NB = (Trans == CblasNoTrans) ? B->size2 : B->size1; if (M != N) { GSL_ERROR ("matrix C must be square", GSL_ENOTSQR); } else if (N != MA || N != MB || NA != NB) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_ssyr2k (CblasRowMajor, Uplo, Trans, INT (N), INT (NA), alpha, A->data, INT (A->tda), B->data, INT (B->tda), beta, C->data, INT (C->tda)); return GSL_SUCCESS; } int gsl_blas_dsyr2k (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, double alpha, const gsl_matrix * A, const gsl_matrix * B, double beta, gsl_matrix * C) { const size_t M = C->size1; const size_t N = C->size2; const size_t MA = (Trans == CblasNoTrans) ? A->size1 : A->size2; const size_t NA = (Trans == CblasNoTrans) ? A->size2 : A->size1; const size_t MB = (Trans == CblasNoTrans) ? B->size1 : B->size2; const size_t NB = (Trans == CblasNoTrans) ? B->size2 : B->size1; if (M != N) { GSL_ERROR ("matrix C must be square", GSL_ENOTSQR); } else if (N != MA || N != MB || NA != NB) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_dsyr2k (CblasRowMajor, Uplo, Trans, INT (N), INT (NA), alpha, A->data, INT (A->tda), B->data, INT (B->tda), beta, C->data, INT (C->tda)); return GSL_SUCCESS; } int gsl_blas_csyr2k (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, const gsl_complex_float alpha, const gsl_matrix_complex_float * A, const gsl_matrix_complex_float * B, const gsl_complex_float beta, gsl_matrix_complex_float * C) { const size_t M = C->size1; const size_t N = C->size2; const size_t MA = (Trans == CblasNoTrans) ? A->size1 : A->size2; const size_t NA = (Trans == CblasNoTrans) ? A->size2 : A->size1; const size_t MB = (Trans == CblasNoTrans) ? B->size1 : B->size2; const size_t NB = (Trans == CblasNoTrans) ? B->size2 : B->size1; if (M != N) { GSL_ERROR ("matrix C must be square", GSL_ENOTSQR); } else if (N != MA || N != MB || NA != NB) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_csyr2k (CblasRowMajor, Uplo, Trans, INT (N), INT (NA), GSL_COMPLEX_P (&alpha), A->data, INT (A->tda), B->data, INT (B->tda), GSL_COMPLEX_P (&beta), C->data, INT (C->tda)); return GSL_SUCCESS; } int gsl_blas_zsyr2k (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, const gsl_complex alpha, const gsl_matrix_complex * A, const gsl_matrix_complex * B, const gsl_complex beta, gsl_matrix_complex * C) { const size_t M = C->size1; const size_t N = C->size2; const size_t MA = (Trans == CblasNoTrans) ? A->size1 : A->size2; const size_t NA = (Trans == CblasNoTrans) ? A->size2 : A->size1; const size_t MB = (Trans == CblasNoTrans) ? B->size1 : B->size2; const size_t NB = (Trans == CblasNoTrans) ? B->size2 : B->size1; if (M != N) { GSL_ERROR ("matrix C must be square", GSL_ENOTSQR); } else if (N != MA || N != MB || NA != NB) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_zsyr2k (CblasRowMajor, Uplo, Trans, INT (N), INT (NA), GSL_COMPLEX_P (&alpha), A->data, INT (A->tda), B->data, INT (B->tda), GSL_COMPLEX_P (&beta), C->data, INT (C->tda)); return GSL_SUCCESS; } /* HER2K */ int gsl_blas_cher2k (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, const gsl_complex_float alpha, const gsl_matrix_complex_float * A, const gsl_matrix_complex_float * B, float beta, gsl_matrix_complex_float * C) { const size_t M = C->size1; const size_t N = C->size2; const size_t MA = (Trans == CblasNoTrans) ? A->size1 : A->size2; const size_t NA = (Trans == CblasNoTrans) ? A->size2 : A->size1; const size_t MB = (Trans == CblasNoTrans) ? B->size1 : B->size2; const size_t NB = (Trans == CblasNoTrans) ? B->size2 : B->size1; if (M != N) { GSL_ERROR ("matrix C must be square", GSL_ENOTSQR); } else if (N != MA || N != MB || NA != NB) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_cher2k (CblasRowMajor, Uplo, Trans, INT (N), INT (NA), GSL_COMPLEX_P (&alpha), A->data, INT (A->tda), B->data, INT (B->tda), beta, C->data, INT (C->tda)); return GSL_SUCCESS; } int gsl_blas_zher2k (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, const gsl_complex alpha, const gsl_matrix_complex * A, const gsl_matrix_complex * B, double beta, gsl_matrix_complex * C) { const size_t M = C->size1; const size_t N = C->size2; const size_t MA = (Trans == CblasNoTrans) ? A->size1 : A->size2; const size_t NA = (Trans == CblasNoTrans) ? A->size2 : A->size1; const size_t MB = (Trans == CblasNoTrans) ? B->size1 : B->size2; const size_t NB = (Trans == CblasNoTrans) ? B->size2 : B->size1; if (M != N) { GSL_ERROR ("matrix C must be square", GSL_ENOTSQR); } else if (N != MA || N != MB || NA != NB) { GSL_ERROR ("invalid length", GSL_EBADLEN); } cblas_zher2k (CblasRowMajor, Uplo, Trans, INT (N), INT (NA), GSL_COMPLEX_P (&alpha), A->data, INT (A->tda), B->data, INT (B->tda), beta, C->data, INT (C->tda)); return GSL_SUCCESS; } /* TRMM */ int gsl_blas_strmm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, float alpha, const gsl_matrix_float * A, gsl_matrix_float * B) { const size_t M = B->size1; const size_t N = B->size2; const size_t MA = A->size1; const size_t NA = A->size2; if (MA != NA) { GSL_ERROR ("matrix A must be square", GSL_ENOTSQR); } if ((Side == CblasLeft && M == MA) || (Side == CblasRight && N == MA)) { cblas_strmm (CblasRowMajor, Side, Uplo, TransA, Diag, INT (M), INT (N), alpha, A->data, INT (A->tda), B->data, INT (B->tda)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_dtrmm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, double alpha, const gsl_matrix * A, gsl_matrix * B) { const size_t M = B->size1; const size_t N = B->size2; const size_t MA = A->size1; const size_t NA = A->size2; if (MA != NA) { GSL_ERROR ("matrix A must be square", GSL_ENOTSQR); } if ((Side == CblasLeft && M == MA) || (Side == CblasRight && N == MA)) { cblas_dtrmm (CblasRowMajor, Side, Uplo, TransA, Diag, INT (M), INT (N), alpha, A->data, INT (A->tda), B->data, INT (B->tda)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_ctrmm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, const gsl_complex_float alpha, const gsl_matrix_complex_float * A, gsl_matrix_complex_float * B) { const size_t M = B->size1; const size_t N = B->size2; const size_t MA = A->size1; const size_t NA = A->size2; if (MA != NA) { GSL_ERROR ("matrix A must be square", GSL_ENOTSQR); } if ((Side == CblasLeft && M == MA) || (Side == CblasRight && N == MA)) { cblas_ctrmm (CblasRowMajor, Side, Uplo, TransA, Diag, INT (M), INT (N), GSL_COMPLEX_P (&alpha), A->data, INT (A->tda), B->data, INT (B->tda)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_ztrmm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, const gsl_complex alpha, const gsl_matrix_complex * A, gsl_matrix_complex * B) { const size_t M = B->size1; const size_t N = B->size2; const size_t MA = A->size1; const size_t NA = A->size2; if (MA != NA) { GSL_ERROR ("matrix A must be square", GSL_ENOTSQR); } if ((Side == CblasLeft && M == MA) || (Side == CblasRight && N == MA)) { cblas_ztrmm (CblasRowMajor, Side, Uplo, TransA, Diag, INT (M), INT (N), GSL_COMPLEX_P (&alpha), A->data, INT (A->tda), B->data, INT (B->tda)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } /* TRSM */ int gsl_blas_strsm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, float alpha, const gsl_matrix_float * A, gsl_matrix_float * B) { const size_t M = B->size1; const size_t N = B->size2; const size_t MA = A->size1; const size_t NA = A->size2; if (MA != NA) { GSL_ERROR ("matrix A must be square", GSL_ENOTSQR); } if ((Side == CblasLeft && M == MA) || (Side == CblasRight && N == MA)) { cblas_strsm (CblasRowMajor, Side, Uplo, TransA, Diag, INT (M), INT (N), alpha, A->data, INT (A->tda), B->data, INT (B->tda)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_dtrsm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, double alpha, const gsl_matrix * A, gsl_matrix * B) { const size_t M = B->size1; const size_t N = B->size2; const size_t MA = A->size1; const size_t NA = A->size2; if (MA != NA) { GSL_ERROR ("matrix A must be square", GSL_ENOTSQR); } if ((Side == CblasLeft && M == MA) || (Side == CblasRight && N == MA)) { cblas_dtrsm (CblasRowMajor, Side, Uplo, TransA, Diag, INT (M), INT (N), alpha, A->data, INT (A->tda), B->data, INT (B->tda)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_ctrsm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, const gsl_complex_float alpha, const gsl_matrix_complex_float * A, gsl_matrix_complex_float * B) { const size_t M = B->size1; const size_t N = B->size2; const size_t MA = A->size1; const size_t NA = A->size2; if (MA != NA) { GSL_ERROR ("matrix A must be square", GSL_ENOTSQR); } if ((Side == CblasLeft && M == MA) || (Side == CblasRight && N == MA)) { cblas_ctrsm (CblasRowMajor, Side, Uplo, TransA, Diag, INT (M), INT (N), GSL_COMPLEX_P (&alpha), A->data, INT (A->tda), B->data, INT (B->tda)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } int gsl_blas_ztrsm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, const gsl_complex alpha, const gsl_matrix_complex * A, gsl_matrix_complex * B) { const size_t M = B->size1; const size_t N = B->size2; const size_t MA = A->size1; const size_t NA = A->size2; if (MA != NA) { GSL_ERROR ("matrix A must be square", GSL_ENOTSQR); } if ((Side == CblasLeft && M == MA) || (Side == CblasRight && N == MA)) { cblas_ztrsm (CblasRowMajor, Side, Uplo, TransA, Diag, INT (M), INT (N), GSL_COMPLEX_P (&alpha), A->data, INT (A->tda), B->data, INT (B->tda)); return GSL_SUCCESS; } else { GSL_ERROR ("invalid length", GSL_EBADLEN); } } praat-6.0.04/external/gsl/gsl_blas_types.h000066400000000000000000000030471261542461700205160ustar00rootroot00000000000000/* blas/gsl_blas_types.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Author: G. Jungman */ /* Based on draft BLAST C interface specification [Jul 7 1998] */ #ifndef __GSL_BLAS_TYPES_H__ #define __GSL_BLAS_TYPES_H__ #include "gsl_cblas.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef CBLAS_INDEX CBLAS_INDEX_t; typedef enum CBLAS_ORDER CBLAS_ORDER_t; typedef enum CBLAS_TRANSPOSE CBLAS_TRANSPOSE_t; typedef enum CBLAS_UPLO CBLAS_UPLO_t; typedef enum CBLAS_DIAG CBLAS_DIAG_t; typedef enum CBLAS_SIDE CBLAS_SIDE_t; /* typedef gsl_complex COMPLEX; */ __END_DECLS #endif /* __GSL_BLAS_TYPES_H__ */ praat-6.0.04/external/gsl/gsl_block.h000066400000000000000000000010141261542461700174330ustar00rootroot00000000000000#ifndef __GSL_BLOCK_H__ #define __GSL_BLOCK_H__ #include "gsl_block_complex_long_double.h" #include "gsl_block_complex_double.h" #include "gsl_block_complex_float.h" #include "gsl_block_long_double.h" #include "gsl_block_double.h" #include "gsl_block_float.h" #include "gsl_block_ulong.h" #include "gsl_block_long.h" #include "gsl_block_uint.h" #include "gsl_block_int.h" #include "gsl_block_ushort.h" #include "gsl_block_short.h" #include "gsl_block_uchar.h" #include "gsl_block_char.h" #endif /* __GSL_BLOCK_H__ */ praat-6.0.04/external/gsl/gsl_block__block.c000066400000000000000000000036251261542461700207510ustar00rootroot00000000000000#include "gsl__config.h" #include "gsl_errno.h" #include "gsl_block.h" #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_block__block_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_block__block_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_block__block_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_block__block_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_block__block_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_block__block_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_block__block_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_block__block_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_block__block_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_block__block_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_block__block_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_block__block_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_block__block_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_block__block_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_block__block_source.c000066400000000000000000000017561261542461700223340ustar00rootroot00000000000000/* block/block_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ size_t FUNCTION(gsl_block,size) (const TYPE(gsl_block) * b) { return b->size ; } ATOMIC * FUNCTION(gsl_block,data) (const TYPE(gsl_block) * b) { return b->data ; } praat-6.0.04/external/gsl/gsl_block__file.c000066400000000000000000000047301261542461700205740ustar00rootroot00000000000000#include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_block.h" #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_block__fwrite_source.c" #include "gsl_block__fprintf_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_block__fwrite_source.c" #include "gsl_block__fprintf_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_block__fwrite_source.c" #include "gsl_block__fprintf_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_block__fwrite_source.c" #include "gsl_block__fprintf_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_block__fwrite_source.c" #include "gsl_block__fprintf_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_block__fwrite_source.c" #include "gsl_block__fprintf_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_block__fwrite_source.c" #include "gsl_block__fprintf_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_block__fwrite_source.c" #include "gsl_block__fprintf_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_block__fwrite_source.c" #include "gsl_block__fprintf_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_block__fwrite_source.c" #include "gsl_block__fprintf_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_block__fwrite_source.c" #include "gsl_block__fprintf_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_block__fwrite_source.c" #include "gsl_block__fprintf_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_block__fwrite_source.c" #include "gsl_block__fprintf_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_block__fwrite_source.c" #include "gsl_block__fprintf_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_block__fprintf_source.c000066400000000000000000000075701261542461700227120ustar00rootroot00000000000000/* block/fprintf_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #if !(USES_LONGDOUBLE && !HAVE_PRINTF_LONGDOUBLE) int FUNCTION (gsl_block, fprintf) (FILE * stream, const TYPE(gsl_block) * b, const char *format) { size_t n = b->size ; ATOMIC * data = b->data ; size_t i; for (i = 0; i < n; i++) { int k; int status; for (k = 0; k < MULTIPLICITY; k++) { if (k > 0) { status = putc (' ', stream); if (status == EOF) { GSL_ERROR ("putc failed", GSL_EFAILED); } } status = fprintf (stream, format, data[MULTIPLICITY * i + k]); if (status < 0) { GSL_ERROR ("fprintf failed", GSL_EFAILED); } } status = putc ('\n', stream); if (status == EOF) { GSL_ERROR ("putc failed", GSL_EFAILED); } } return 0; } int FUNCTION (gsl_block, fscanf) (FILE * stream, TYPE(gsl_block) * b) { size_t n = b->size ; ATOMIC * data = b->data ; size_t i; for (i = 0; i < n; i++) { int k; for (k = 0; k < MULTIPLICITY; k++) { ATOMIC_IO tmp ; int status = fscanf (stream, IN_FORMAT, &tmp) ; data [MULTIPLICITY * i + k] = tmp; if (status != 1) { GSL_ERROR ("fscanf failed", GSL_EFAILED); } } } return GSL_SUCCESS; } int FUNCTION (gsl_block, raw_fprintf) (FILE * stream, const ATOMIC * data, const size_t n, const size_t stride, const char *format) { size_t i; for (i = 0; i < n; i++) { int k; int status; for (k = 0; k < MULTIPLICITY; k++) { if (k > 0) { status = putc (' ', stream); if (status == EOF) { GSL_ERROR ("putc failed", GSL_EFAILED); } } status = fprintf (stream, format, data[MULTIPLICITY * i * stride + k]); if (status < 0) { GSL_ERROR ("fprintf failed", GSL_EFAILED); } } status = putc ('\n', stream); if (status == EOF) { GSL_ERROR ("putc failed", GSL_EFAILED); } } return 0; } int FUNCTION (gsl_block, raw_fscanf) (FILE * stream, ATOMIC * data, const size_t n, const size_t stride) { size_t i; for (i = 0; i < n; i++) { int k; for (k = 0; k < MULTIPLICITY; k++) { ATOMIC_IO tmp; int status = fscanf (stream, IN_FORMAT, &tmp) ; data [MULTIPLICITY * i * stride + k] = tmp; if (status != 1) GSL_ERROR ("fscanf failed", GSL_EFAILED); } } return GSL_SUCCESS; } #endif praat-6.0.04/external/gsl/gsl_block__fwrite_source.c000066400000000000000000000055131261542461700225350ustar00rootroot00000000000000/* block/fwrite_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ int FUNCTION (gsl_block, fread) (FILE * stream, TYPE(gsl_block) * b) { size_t n = b->size ; ATOMIC * data = b->data ; size_t items = fread (data, MULTIPLICITY * sizeof (ATOMIC), n, stream); if (items != n) { GSL_ERROR ("fread failed", GSL_EFAILED); } return 0; } int FUNCTION (gsl_block, fwrite) (FILE * stream, const TYPE(gsl_block) * b) { size_t n = b->size ; ATOMIC * data = b->data ; size_t items = fwrite (data, MULTIPLICITY * sizeof (ATOMIC), n, stream); if (items != n) { GSL_ERROR ("fwrite failed", GSL_EFAILED); } return 0; } int FUNCTION (gsl_block, raw_fread) (FILE * stream, ATOMIC * data, const size_t n, const size_t stride) { if (stride == 1) { size_t items = fread (data, MULTIPLICITY * sizeof (ATOMIC), n, stream); if (items != n) { GSL_ERROR ("fread failed", GSL_EFAILED); } } else { size_t i; for (i = 0; i < n; i++) { size_t item = fread (data + MULTIPLICITY * i * stride, MULTIPLICITY * sizeof (ATOMIC), 1, stream); if (item != 1) { GSL_ERROR ("fread failed", GSL_EFAILED); } } } return GSL_SUCCESS; } int FUNCTION (gsl_block, raw_fwrite) (FILE * stream, const ATOMIC * data, const size_t n, const size_t stride) { if (stride == 1) { size_t items = fwrite (data, MULTIPLICITY * sizeof (ATOMIC), n, stream); if (items != n) { GSL_ERROR ("fwrite failed", GSL_EFAILED); } } else { size_t i; for (i = 0; i < n; i++) { size_t item = fwrite (data + MULTIPLICITY * i * stride, MULTIPLICITY * sizeof (ATOMIC), 1, stream); if (item != 1) { GSL_ERROR ("fwrite failed", GSL_EFAILED); } } } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_block__init.c000066400000000000000000000036041261542461700206170ustar00rootroot00000000000000#include "gsl__config.h" #include #include "gsl_block.h" #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_block__init_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_block__init_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_block__init_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_block__init_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_block__init_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_block__init_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_block__init_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_block__init_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_block__init_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_block__init_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_block__init_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_block__init_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_block__init_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_block__init_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_block__init_source.c000066400000000000000000000036351261542461700222030ustar00rootroot00000000000000/* block/init_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ TYPE (gsl_block) * FUNCTION (gsl_block, alloc) (const size_t n) { TYPE (gsl_block) * b; if (n == 0) { GSL_ERROR_VAL ("block length n must be positive integer", GSL_EINVAL, 0); } b = (TYPE (gsl_block) *) malloc (sizeof (TYPE (gsl_block))); if (b == 0) { GSL_ERROR_VAL ("failed to allocate space for block struct", GSL_ENOMEM, 0); } b->data = (ATOMIC *) malloc (MULTIPLICITY * n * sizeof (ATOMIC)); if (b->data == 0) { free (b); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for block data", GSL_ENOMEM, 0); } b->size = n; return b; } TYPE (gsl_block) * FUNCTION (gsl_block, calloc) (const size_t n) { size_t i; TYPE (gsl_block) * b = FUNCTION (gsl_block, alloc) (n); if (b == 0) return 0; /* initialize block to zero */ for (i = 0; i < MULTIPLICITY * n; i++) { b->data[i] = 0; } return b; } void FUNCTION (gsl_block, free) (TYPE (gsl_block) * b) { free (b->data); free (b); } praat-6.0.04/external/gsl/gsl_block_char.h000066400000000000000000000043561261542461700204440ustar00rootroot00000000000000/* block/gsl_block_char.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_BLOCK_CHAR_H__ #define __GSL_BLOCK_CHAR_H__ #include #include "gsl_errno.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS struct gsl_block_char_struct { size_t size; char *data; }; typedef struct gsl_block_char_struct gsl_block_char; gsl_block_char *gsl_block_char_alloc (const size_t n); gsl_block_char *gsl_block_char_calloc (const size_t n); void gsl_block_char_free (gsl_block_char * b); int gsl_block_char_fread (FILE * stream, gsl_block_char * b); int gsl_block_char_fwrite (FILE * stream, const gsl_block_char * b); int gsl_block_char_fscanf (FILE * stream, gsl_block_char * b); int gsl_block_char_fprintf (FILE * stream, const gsl_block_char * b, const char *format); int gsl_block_char_raw_fread (FILE * stream, char * b, const size_t n, const size_t stride); int gsl_block_char_raw_fwrite (FILE * stream, const char * b, const size_t n, const size_t stride); int gsl_block_char_raw_fscanf (FILE * stream, char * b, const size_t n, const size_t stride); int gsl_block_char_raw_fprintf (FILE * stream, const char * b, const size_t n, const size_t stride, const char *format); size_t gsl_block_char_size (const gsl_block_char * b); char * gsl_block_char_data (const gsl_block_char * b); __END_DECLS #endif /* __GSL_BLOCK_CHAR_H__ */ praat-6.0.04/external/gsl/gsl_block_complex_double.h000066400000000000000000000045551261542461700225310ustar00rootroot00000000000000/* block/gsl_block_complex_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_BLOCK_COMPLEX_DOUBLE_H__ #define __GSL_BLOCK_COMPLEX_DOUBLE_H__ #include #include "gsl_errno.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS struct gsl_block_complex_struct { size_t size; double *data; }; typedef struct gsl_block_complex_struct gsl_block_complex; gsl_block_complex *gsl_block_complex_alloc (const size_t n); gsl_block_complex *gsl_block_complex_calloc (const size_t n); void gsl_block_complex_free (gsl_block_complex * b); int gsl_block_complex_fread (FILE * stream, gsl_block_complex * b); int gsl_block_complex_fwrite (FILE * stream, const gsl_block_complex * b); int gsl_block_complex_fscanf (FILE * stream, gsl_block_complex * b); int gsl_block_complex_fprintf (FILE * stream, const gsl_block_complex * b, const char *format); int gsl_block_complex_raw_fread (FILE * stream, double * b, const size_t n, const size_t stride); int gsl_block_complex_raw_fwrite (FILE * stream, const double * b, const size_t n, const size_t stride); int gsl_block_complex_raw_fscanf (FILE * stream, double * b, const size_t n, const size_t stride); int gsl_block_complex_raw_fprintf (FILE * stream, const double * b, const size_t n, const size_t stride, const char *format); size_t gsl_block_complex_size (const gsl_block_complex * b); double * gsl_block_complex_data (const gsl_block_complex * b); __END_DECLS #endif /* __GSL_BLOCK_COMPLEX_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_block_complex_float.h000066400000000000000000000047711261542461700223640ustar00rootroot00000000000000/* block/gsl_block_complex_float.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_BLOCK_COMPLEX_FLOAT_H__ #define __GSL_BLOCK_COMPLEX_FLOAT_H__ #include #include "gsl_errno.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS struct gsl_block_complex_float_struct { size_t size; float *data; }; typedef struct gsl_block_complex_float_struct gsl_block_complex_float; gsl_block_complex_float *gsl_block_complex_float_alloc (const size_t n); gsl_block_complex_float *gsl_block_complex_float_calloc (const size_t n); void gsl_block_complex_float_free (gsl_block_complex_float * b); int gsl_block_complex_float_fread (FILE * stream, gsl_block_complex_float * b); int gsl_block_complex_float_fwrite (FILE * stream, const gsl_block_complex_float * b); int gsl_block_complex_float_fscanf (FILE * stream, gsl_block_complex_float * b); int gsl_block_complex_float_fprintf (FILE * stream, const gsl_block_complex_float * b, const char *format); int gsl_block_complex_float_raw_fread (FILE * stream, float * b, const size_t n, const size_t stride); int gsl_block_complex_float_raw_fwrite (FILE * stream, const float * b, const size_t n, const size_t stride); int gsl_block_complex_float_raw_fscanf (FILE * stream, float * b, const size_t n, const size_t stride); int gsl_block_complex_float_raw_fprintf (FILE * stream, const float * b, const size_t n, const size_t stride, const char *format); size_t gsl_block_complex_float_size (const gsl_block_complex_float * b); float * gsl_block_complex_float_data (const gsl_block_complex_float * b); __END_DECLS #endif /* __GSL_BLOCK_COMPLEX_FLOAT_H__ */ praat-6.0.04/external/gsl/gsl_block_complex_long_double.h000066400000000000000000000053131261542461700235410ustar00rootroot00000000000000/* block/gsl_block_complex_long_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_BLOCK_COMPLEX_LONG_DOUBLE_H__ #define __GSL_BLOCK_COMPLEX_LONG_DOUBLE_H__ #include #include "gsl_errno.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS struct gsl_block_complex_long_double_struct { size_t size; long double *data; }; typedef struct gsl_block_complex_long_double_struct gsl_block_complex_long_double; gsl_block_complex_long_double *gsl_block_complex_long_double_alloc (const size_t n); gsl_block_complex_long_double *gsl_block_complex_long_double_calloc (const size_t n); void gsl_block_complex_long_double_free (gsl_block_complex_long_double * b); int gsl_block_complex_long_double_fread (FILE * stream, gsl_block_complex_long_double * b); int gsl_block_complex_long_double_fwrite (FILE * stream, const gsl_block_complex_long_double * b); int gsl_block_complex_long_double_fscanf (FILE * stream, gsl_block_complex_long_double * b); int gsl_block_complex_long_double_fprintf (FILE * stream, const gsl_block_complex_long_double * b, const char *format); int gsl_block_complex_long_double_raw_fread (FILE * stream, long double * b, const size_t n, const size_t stride); int gsl_block_complex_long_double_raw_fwrite (FILE * stream, const long double * b, const size_t n, const size_t stride); int gsl_block_complex_long_double_raw_fscanf (FILE * stream, long double * b, const size_t n, const size_t stride); int gsl_block_complex_long_double_raw_fprintf (FILE * stream, const long double * b, const size_t n, const size_t stride, const char *format); size_t gsl_block_complex_long_double_size (const gsl_block_complex_long_double * b); long double * gsl_block_complex_long_double_data (const gsl_block_complex_long_double * b); __END_DECLS #endif /* __GSL_BLOCK_COMPLEX_LONG_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_block_double.h000066400000000000000000000042051261542461700207720ustar00rootroot00000000000000/* block/gsl_block_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_BLOCK_DOUBLE_H__ #define __GSL_BLOCK_DOUBLE_H__ #include #include "gsl_errno.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS struct gsl_block_struct { size_t size; double *data; }; typedef struct gsl_block_struct gsl_block; gsl_block *gsl_block_alloc (const size_t n); gsl_block *gsl_block_calloc (const size_t n); void gsl_block_free (gsl_block * b); int gsl_block_fread (FILE * stream, gsl_block * b); int gsl_block_fwrite (FILE * stream, const gsl_block * b); int gsl_block_fscanf (FILE * stream, gsl_block * b); int gsl_block_fprintf (FILE * stream, const gsl_block * b, const char *format); int gsl_block_raw_fread (FILE * stream, double * b, const size_t n, const size_t stride); int gsl_block_raw_fwrite (FILE * stream, const double * b, const size_t n, const size_t stride); int gsl_block_raw_fscanf (FILE * stream, double * b, const size_t n, const size_t stride); int gsl_block_raw_fprintf (FILE * stream, const double * b, const size_t n, const size_t stride, const char *format); size_t gsl_block_size (const gsl_block * b); double * gsl_block_data (const gsl_block * b); __END_DECLS #endif /* __GSL_BLOCK_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_block_float.h000066400000000000000000000044211261542461700206250ustar00rootroot00000000000000/* block/gsl_block_float.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_BLOCK_FLOAT_H__ #define __GSL_BLOCK_FLOAT_H__ #include #include "gsl_errno.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS struct gsl_block_float_struct { size_t size; float *data; }; typedef struct gsl_block_float_struct gsl_block_float; gsl_block_float *gsl_block_float_alloc (const size_t n); gsl_block_float *gsl_block_float_calloc (const size_t n); void gsl_block_float_free (gsl_block_float * b); int gsl_block_float_fread (FILE * stream, gsl_block_float * b); int gsl_block_float_fwrite (FILE * stream, const gsl_block_float * b); int gsl_block_float_fscanf (FILE * stream, gsl_block_float * b); int gsl_block_float_fprintf (FILE * stream, const gsl_block_float * b, const char *format); int gsl_block_float_raw_fread (FILE * stream, float * b, const size_t n, const size_t stride); int gsl_block_float_raw_fwrite (FILE * stream, const float * b, const size_t n, const size_t stride); int gsl_block_float_raw_fscanf (FILE * stream, float * b, const size_t n, const size_t stride); int gsl_block_float_raw_fprintf (FILE * stream, const float * b, const size_t n, const size_t stride, const char *format); size_t gsl_block_float_size (const gsl_block_float * b); float * gsl_block_float_data (const gsl_block_float * b); __END_DECLS #endif /* __GSL_BLOCK_FLOAT_H__ */ praat-6.0.04/external/gsl/gsl_block_int.h000066400000000000000000000043131261542461700203120ustar00rootroot00000000000000/* block/gsl_block_int.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_BLOCK_INT_H__ #define __GSL_BLOCK_INT_H__ #include #include "gsl_errno.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS struct gsl_block_int_struct { size_t size; int *data; }; typedef struct gsl_block_int_struct gsl_block_int; gsl_block_int *gsl_block_int_alloc (const size_t n); gsl_block_int *gsl_block_int_calloc (const size_t n); void gsl_block_int_free (gsl_block_int * b); int gsl_block_int_fread (FILE * stream, gsl_block_int * b); int gsl_block_int_fwrite (FILE * stream, const gsl_block_int * b); int gsl_block_int_fscanf (FILE * stream, gsl_block_int * b); int gsl_block_int_fprintf (FILE * stream, const gsl_block_int * b, const char *format); int gsl_block_int_raw_fread (FILE * stream, int * b, const size_t n, const size_t stride); int gsl_block_int_raw_fwrite (FILE * stream, const int * b, const size_t n, const size_t stride); int gsl_block_int_raw_fscanf (FILE * stream, int * b, const size_t n, const size_t stride); int gsl_block_int_raw_fprintf (FILE * stream, const int * b, const size_t n, const size_t stride, const char *format); size_t gsl_block_int_size (const gsl_block_int * b); int * gsl_block_int_data (const gsl_block_int * b); __END_DECLS #endif /* __GSL_BLOCK_INT_H__ */ praat-6.0.04/external/gsl/gsl_block_long.h000066400000000000000000000043561261542461700204660ustar00rootroot00000000000000/* block/gsl_block_long.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_BLOCK_LONG_H__ #define __GSL_BLOCK_LONG_H__ #include #include "gsl_errno.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS struct gsl_block_long_struct { size_t size; long *data; }; typedef struct gsl_block_long_struct gsl_block_long; gsl_block_long *gsl_block_long_alloc (const size_t n); gsl_block_long *gsl_block_long_calloc (const size_t n); void gsl_block_long_free (gsl_block_long * b); int gsl_block_long_fread (FILE * stream, gsl_block_long * b); int gsl_block_long_fwrite (FILE * stream, const gsl_block_long * b); int gsl_block_long_fscanf (FILE * stream, gsl_block_long * b); int gsl_block_long_fprintf (FILE * stream, const gsl_block_long * b, const char *format); int gsl_block_long_raw_fread (FILE * stream, long * b, const size_t n, const size_t stride); int gsl_block_long_raw_fwrite (FILE * stream, const long * b, const size_t n, const size_t stride); int gsl_block_long_raw_fscanf (FILE * stream, long * b, const size_t n, const size_t stride); int gsl_block_long_raw_fprintf (FILE * stream, const long * b, const size_t n, const size_t stride, const char *format); size_t gsl_block_long_size (const gsl_block_long * b); long * gsl_block_long_data (const gsl_block_long * b); __END_DECLS #endif /* __GSL_BLOCK_LONG_H__ */ praat-6.0.04/external/gsl/gsl_block_long_double.h000066400000000000000000000047431261542461700220200ustar00rootroot00000000000000/* block/gsl_block_long_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_BLOCK_LONG_DOUBLE_H__ #define __GSL_BLOCK_LONG_DOUBLE_H__ #include #include "gsl_errno.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS struct gsl_block_long_double_struct { size_t size; long double *data; }; typedef struct gsl_block_long_double_struct gsl_block_long_double; gsl_block_long_double *gsl_block_long_double_alloc (const size_t n); gsl_block_long_double *gsl_block_long_double_calloc (const size_t n); void gsl_block_long_double_free (gsl_block_long_double * b); int gsl_block_long_double_fread (FILE * stream, gsl_block_long_double * b); int gsl_block_long_double_fwrite (FILE * stream, const gsl_block_long_double * b); int gsl_block_long_double_fscanf (FILE * stream, gsl_block_long_double * b); int gsl_block_long_double_fprintf (FILE * stream, const gsl_block_long_double * b, const char *format); int gsl_block_long_double_raw_fread (FILE * stream, long double * b, const size_t n, const size_t stride); int gsl_block_long_double_raw_fwrite (FILE * stream, const long double * b, const size_t n, const size_t stride); int gsl_block_long_double_raw_fscanf (FILE * stream, long double * b, const size_t n, const size_t stride); int gsl_block_long_double_raw_fprintf (FILE * stream, const long double * b, const size_t n, const size_t stride, const char *format); size_t gsl_block_long_double_size (const gsl_block_long_double * b); long double * gsl_block_long_double_data (const gsl_block_long_double * b); __END_DECLS #endif /* __GSL_BLOCK_LONG_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_block_short.h000066400000000000000000000044211261542461700206570ustar00rootroot00000000000000/* block/gsl_block_short.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_BLOCK_SHORT_H__ #define __GSL_BLOCK_SHORT_H__ #include #include "gsl_errno.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS struct gsl_block_short_struct { size_t size; short *data; }; typedef struct gsl_block_short_struct gsl_block_short; gsl_block_short *gsl_block_short_alloc (const size_t n); gsl_block_short *gsl_block_short_calloc (const size_t n); void gsl_block_short_free (gsl_block_short * b); int gsl_block_short_fread (FILE * stream, gsl_block_short * b); int gsl_block_short_fwrite (FILE * stream, const gsl_block_short * b); int gsl_block_short_fscanf (FILE * stream, gsl_block_short * b); int gsl_block_short_fprintf (FILE * stream, const gsl_block_short * b, const char *format); int gsl_block_short_raw_fread (FILE * stream, short * b, const size_t n, const size_t stride); int gsl_block_short_raw_fwrite (FILE * stream, const short * b, const size_t n, const size_t stride); int gsl_block_short_raw_fscanf (FILE * stream, short * b, const size_t n, const size_t stride); int gsl_block_short_raw_fprintf (FILE * stream, const short * b, const size_t n, const size_t stride, const char *format); size_t gsl_block_short_size (const gsl_block_short * b); short * gsl_block_short_data (const gsl_block_short * b); __END_DECLS #endif /* __GSL_BLOCK_SHORT_H__ */ praat-6.0.04/external/gsl/gsl_block_uchar.h000066400000000000000000000045011261542461700206210ustar00rootroot00000000000000/* block/gsl_block_uchar.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_BLOCK_UCHAR_H__ #define __GSL_BLOCK_UCHAR_H__ #include #include "gsl_errno.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS struct gsl_block_uchar_struct { size_t size; unsigned char *data; }; typedef struct gsl_block_uchar_struct gsl_block_uchar; gsl_block_uchar *gsl_block_uchar_alloc (const size_t n); gsl_block_uchar *gsl_block_uchar_calloc (const size_t n); void gsl_block_uchar_free (gsl_block_uchar * b); int gsl_block_uchar_fread (FILE * stream, gsl_block_uchar * b); int gsl_block_uchar_fwrite (FILE * stream, const gsl_block_uchar * b); int gsl_block_uchar_fscanf (FILE * stream, gsl_block_uchar * b); int gsl_block_uchar_fprintf (FILE * stream, const gsl_block_uchar * b, const char *format); int gsl_block_uchar_raw_fread (FILE * stream, unsigned char * b, const size_t n, const size_t stride); int gsl_block_uchar_raw_fwrite (FILE * stream, const unsigned char * b, const size_t n, const size_t stride); int gsl_block_uchar_raw_fscanf (FILE * stream, unsigned char * b, const size_t n, const size_t stride); int gsl_block_uchar_raw_fprintf (FILE * stream, const unsigned char * b, const size_t n, const size_t stride, const char *format); size_t gsl_block_uchar_size (const gsl_block_uchar * b); unsigned char * gsl_block_uchar_data (const gsl_block_uchar * b); __END_DECLS #endif /* __GSL_BLOCK_UCHAR_H__ */ praat-6.0.04/external/gsl/gsl_block_uint.h000066400000000000000000000044361261542461700205050ustar00rootroot00000000000000/* block/gsl_block_uint.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_BLOCK_UINT_H__ #define __GSL_BLOCK_UINT_H__ #include #include "gsl_errno.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS struct gsl_block_uint_struct { size_t size; unsigned int *data; }; typedef struct gsl_block_uint_struct gsl_block_uint; gsl_block_uint *gsl_block_uint_alloc (const size_t n); gsl_block_uint *gsl_block_uint_calloc (const size_t n); void gsl_block_uint_free (gsl_block_uint * b); int gsl_block_uint_fread (FILE * stream, gsl_block_uint * b); int gsl_block_uint_fwrite (FILE * stream, const gsl_block_uint * b); int gsl_block_uint_fscanf (FILE * stream, gsl_block_uint * b); int gsl_block_uint_fprintf (FILE * stream, const gsl_block_uint * b, const char *format); int gsl_block_uint_raw_fread (FILE * stream, unsigned int * b, const size_t n, const size_t stride); int gsl_block_uint_raw_fwrite (FILE * stream, const unsigned int * b, const size_t n, const size_t stride); int gsl_block_uint_raw_fscanf (FILE * stream, unsigned int * b, const size_t n, const size_t stride); int gsl_block_uint_raw_fprintf (FILE * stream, const unsigned int * b, const size_t n, const size_t stride, const char *format); size_t gsl_block_uint_size (const gsl_block_uint * b); unsigned int * gsl_block_uint_data (const gsl_block_uint * b); __END_DECLS #endif /* __GSL_BLOCK_UINT_H__ */ praat-6.0.04/external/gsl/gsl_block_ulong.h000066400000000000000000000045011261542461700206430ustar00rootroot00000000000000/* block/gsl_block_ulong.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_BLOCK_ULONG_H__ #define __GSL_BLOCK_ULONG_H__ #include #include "gsl_errno.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS struct gsl_block_ulong_struct { size_t size; unsigned long *data; }; typedef struct gsl_block_ulong_struct gsl_block_ulong; gsl_block_ulong *gsl_block_ulong_alloc (const size_t n); gsl_block_ulong *gsl_block_ulong_calloc (const size_t n); void gsl_block_ulong_free (gsl_block_ulong * b); int gsl_block_ulong_fread (FILE * stream, gsl_block_ulong * b); int gsl_block_ulong_fwrite (FILE * stream, const gsl_block_ulong * b); int gsl_block_ulong_fscanf (FILE * stream, gsl_block_ulong * b); int gsl_block_ulong_fprintf (FILE * stream, const gsl_block_ulong * b, const char *format); int gsl_block_ulong_raw_fread (FILE * stream, unsigned long * b, const size_t n, const size_t stride); int gsl_block_ulong_raw_fwrite (FILE * stream, const unsigned long * b, const size_t n, const size_t stride); int gsl_block_ulong_raw_fscanf (FILE * stream, unsigned long * b, const size_t n, const size_t stride); int gsl_block_ulong_raw_fprintf (FILE * stream, const unsigned long * b, const size_t n, const size_t stride, const char *format); size_t gsl_block_ulong_size (const gsl_block_ulong * b); unsigned long * gsl_block_ulong_data (const gsl_block_ulong * b); __END_DECLS #endif /* __GSL_BLOCK_ULONG_H__ */ praat-6.0.04/external/gsl/gsl_block_ushort.h000066400000000000000000000045441261542461700210520ustar00rootroot00000000000000/* block/gsl_block_ushort.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_BLOCK_USHORT_H__ #define __GSL_BLOCK_USHORT_H__ #include #include "gsl_errno.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS struct gsl_block_ushort_struct { size_t size; unsigned short *data; }; typedef struct gsl_block_ushort_struct gsl_block_ushort; gsl_block_ushort *gsl_block_ushort_alloc (const size_t n); gsl_block_ushort *gsl_block_ushort_calloc (const size_t n); void gsl_block_ushort_free (gsl_block_ushort * b); int gsl_block_ushort_fread (FILE * stream, gsl_block_ushort * b); int gsl_block_ushort_fwrite (FILE * stream, const gsl_block_ushort * b); int gsl_block_ushort_fscanf (FILE * stream, gsl_block_ushort * b); int gsl_block_ushort_fprintf (FILE * stream, const gsl_block_ushort * b, const char *format); int gsl_block_ushort_raw_fread (FILE * stream, unsigned short * b, const size_t n, const size_t stride); int gsl_block_ushort_raw_fwrite (FILE * stream, const unsigned short * b, const size_t n, const size_t stride); int gsl_block_ushort_raw_fscanf (FILE * stream, unsigned short * b, const size_t n, const size_t stride); int gsl_block_ushort_raw_fprintf (FILE * stream, const unsigned short * b, const size_t n, const size_t stride, const char *format); size_t gsl_block_ushort_size (const gsl_block_ushort * b); unsigned short * gsl_block_ushort_data (const gsl_block_ushort * b); __END_DECLS #endif /* __GSL_BLOCK_USHORT_H__ */ praat-6.0.04/external/gsl/gsl_bspline.h000066400000000000000000000044201261542461700200010ustar00rootroot00000000000000/* bspline/gsl_bspline.h * * Copyright (C) 2006 Patrick Alken * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_BSPLINE_H__ #define __GSL_BSPLINE_H__ #include #include "gsl_math.h" #include "gsl_vector.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t k; /* spline order */ size_t km1; /* k - 1 (polynomial order) */ size_t l; /* number of polynomial pieces on interval */ size_t nbreak; /* number of breakpoints (l + 1) */ size_t n; /* number of bspline basis functions (l + k - 1) */ gsl_vector *knots; /* knots vector */ gsl_vector *deltal; /* left delta */ gsl_vector *deltar; /* right delta */ gsl_vector *B; /* temporary spline results */ } gsl_bspline_workspace; gsl_bspline_workspace * gsl_bspline_alloc(const size_t k, const size_t nbreak); void gsl_bspline_free(gsl_bspline_workspace *w); size_t gsl_bspline_ncoeffs (gsl_bspline_workspace * w); size_t gsl_bspline_order (gsl_bspline_workspace * w); size_t gsl_bspline_nbreak (gsl_bspline_workspace * w); double gsl_bspline_breakpoint (size_t i, gsl_bspline_workspace * w); int gsl_bspline_knots(const gsl_vector *breakpts, gsl_bspline_workspace *w); int gsl_bspline_knots_uniform(const double a, const double b, gsl_bspline_workspace *w); int gsl_bspline_eval(const double x, gsl_vector *B, gsl_bspline_workspace *w); __END_DECLS #endif /* __GSL_BSPLINE_H__ */ praat-6.0.04/external/gsl/gsl_bspline__bspline.c000066400000000000000000000300171261542461700216500ustar00rootroot00000000000000/* bspline/bspline.c * * Copyright (C) 2006 Patrick Alken * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_bspline.h" /* * This module contains routines related to calculating B-splines. * The algorithms used are described in * * [1] Carl de Boor, "A Practical Guide to Splines", Springer * Verlag, 1978. */ static int bspline_eval_all(const double x, gsl_vector *B, size_t *idx, gsl_bspline_workspace *w); static inline size_t bspline_find_interval(const double x, int *flag, gsl_bspline_workspace *w); /* gsl_bspline_alloc() Allocate space for a bspline workspace. The size of the workspace is O(5k + nbreak) Inputs: k - spline order (cubic = 4) nbreak - number of breakpoints Return: pointer to workspace */ gsl_bspline_workspace * gsl_bspline_alloc(const size_t k, const size_t nbreak) { if (k == 0) { GSL_ERROR_NULL("k must be at least 1", GSL_EINVAL); } else if (nbreak < 2) { GSL_ERROR_NULL("nbreak must be at least 2", GSL_EINVAL); } else { gsl_bspline_workspace *w; w = (gsl_bspline_workspace *) calloc(1, sizeof(gsl_bspline_workspace)); if (w == 0) { GSL_ERROR_NULL("failed to allocate space for workspace", GSL_ENOMEM); } w->k = k; w->km1 = k - 1; w->nbreak = nbreak; w->l = nbreak - 1; w->n = w->l + k - 1; w->knots = gsl_vector_alloc(w->n + k); if (w->knots == 0) { gsl_bspline_free(w); GSL_ERROR_NULL("failed to allocate space for knots vector", GSL_ENOMEM); } w->deltal = gsl_vector_alloc(k); w->deltar = gsl_vector_alloc(k); if (!w->deltal || !w->deltar) { gsl_bspline_free(w); GSL_ERROR_NULL("failed to allocate space for delta vectors", GSL_ENOMEM); } w->B = gsl_vector_alloc(k); if (w->B == 0) { gsl_bspline_free(w); GSL_ERROR_NULL("failed to allocate space for temporary spline vector", GSL_ENOMEM); } return (w); } } /* gsl_bspline_alloc() */ /* Return number of coefficients */ size_t gsl_bspline_ncoeffs (gsl_bspline_workspace * w) { return w->n; } /* Return order */ size_t gsl_bspline_order (gsl_bspline_workspace * w) { return w->k; } /* Return number of breakpoints */ size_t gsl_bspline_nbreak (gsl_bspline_workspace * w) { return w->nbreak; } double gsl_bspline_breakpoint (size_t i, gsl_bspline_workspace * w) { size_t j = i + w->k - 1; return gsl_vector_get(w->knots, j); } /* gsl_bspline_free() Free a bspline workspace Inputs: w - workspace to free Return: none */ void gsl_bspline_free(gsl_bspline_workspace *w) { if (!w) return; if (w->knots) gsl_vector_free(w->knots); if (w->deltal) gsl_vector_free(w->deltal); if (w->deltar) gsl_vector_free(w->deltar); if (w->B) gsl_vector_free(w->B); free(w); } /* gsl_bspline_free() */ /* gsl_bspline_knots() Compute the knots from the given breakpoints: knots(1:k) = breakpts(1) knots(k+1:k+l-1) = breakpts(i), i = 2 .. l knots(n+1:n+k) = breakpts(l + 1) where l is the number of polynomial pieces (l = nbreak - 1) and n = k + l - 1 (using matlab syntax for the arrays) The repeated knots at the beginning and end of the interval correspond to the continuity condition there. See pg. 119 of [1]. Inputs: breakpts - breakpoints w - bspline workspace Return: success or error */ int gsl_bspline_knots(const gsl_vector *breakpts, gsl_bspline_workspace *w) { if (breakpts->size != w->nbreak) { GSL_ERROR("breakpts vector has wrong size", GSL_EBADLEN); } else { size_t i; /* looping */ for (i = 0; i < w->k; ++i) gsl_vector_set(w->knots, i, gsl_vector_get(breakpts, 0)); for (i = 1; i < w->l; ++i) { gsl_vector_set(w->knots, w->k - 1 + i, gsl_vector_get(breakpts, i)); } for (i = w->n; i < w->n + w->k; ++i) gsl_vector_set(w->knots, i, gsl_vector_get(breakpts, w->l)); return GSL_SUCCESS; } } /* gsl_bspline_knots() */ /* gsl_bspline_knots_uniform() Construct uniformly spaced knots on the interval [a,b] using the previously specified number of breakpoints. 'a' is the position of the first breakpoint and 'b' is the position of the last breakpoint. Inputs: a - left side of interval b - right side of interval w - bspline workspace Return: success or error Notes: 1) w->knots is modified to contain the uniformly spaced knots 2) The knots vector is set up as follows (using octave syntax): knots(1:k) = a knots(k+1:k+l-1) = a + i*delta, i = 1 .. l - 1 knots(n+1:n+k) = b */ int gsl_bspline_knots_uniform(const double a, const double b, gsl_bspline_workspace *w) { size_t i; /* looping */ double delta; /* interval spacing */ double x; delta = (b - a) / (double) w->l; for (i = 0; i < w->k; ++i) gsl_vector_set(w->knots, i, a); x = a + delta; for (i = 0; i < w->l - 1; ++i) { gsl_vector_set(w->knots, w->k + i, x); x += delta; } for (i = w->n; i < w->n + w->k; ++i) gsl_vector_set(w->knots, i, b); return GSL_SUCCESS; } /* gsl_bspline_knots_uniform() */ /* gsl_bspline_eval() Evaluate the basis functions B_i(x) for all i. This is basically a wrapper function for bspline_eval_all() which formats the output in a nice way. Inputs: x - point for evaluation B - (output) where to store B_i(x) values the length of this vector is n = nbreak + k - 2 = l + k - 1 = w->n w - bspline workspace Return: success or error Notes: The w->knots vector must be initialized prior to calling this function (see gsl_bspline_knots()) */ int gsl_bspline_eval(const double x, gsl_vector *B, gsl_bspline_workspace *w) { if (B->size != w->n) { GSL_ERROR("B vector length does not match n", GSL_EBADLEN); } else { size_t i; /* looping */ size_t idx = 0; size_t start; /* first non-zero spline */ /* find all non-zero B_i(x) values */ bspline_eval_all(x, w->B, &idx, w); /* store values in appropriate part of given vector */ start = idx - w->k + 1; for (i = 0; i < start; ++i) gsl_vector_set(B, i, 0.0); for (i = start; i <= idx; ++i) gsl_vector_set(B, i, gsl_vector_get(w->B, i - start)); for (i = idx + 1; i < w->n; ++i) gsl_vector_set(B, i, 0.0); return GSL_SUCCESS; } } /* gsl_bspline_eval() */ /**************************************** * INTERNAL ROUTINES * ****************************************/ /* bspline_eval_all() Evaluate all non-zero B-splines B_i(x) using algorithm (8) of chapter X of [1] The idea is something like this. Given x \in [t_i, t_{i+1}] with t_i < t_{i+1} and the t_i are knots, the values of the B-splines not automatically zero fit into a triangular array as follows: 0 0 0 B_{i-2,3} B_{i-1,2} B_{i,1} B_{i-1,3} ... B_{i,2} 0 B_{i,3} 0 0 where B_{i,k} is the ith B-spline of order k. The boundary 0s indicate that those B-splines not in the table vanish at x. To compute the non-zero B-splines of a given order k, we use Eqs. (4) and (5) of chapter X of [1]: (4) B_{i,1}(x) = { 1, t_i <= x < t_{i+1} 0, else } (5) B_{i,k}(x) = (x - t_i) ----------------- B_{i,k-1}(x) (t_{i+k-1} - t_i) t_{i+k} - x + ----------------- B_{i+1,k-1}(x) t_{i+k} - t_{i+1} So (4) gives us the first column of the table and we can use the recurrence relation (5) to get the rest of the columns. Inputs: x - point at which to evaluate splines B - (output) where to store B-spline values (length k) idx - (output) B-spline function index of last output value (B_{idx}(x) is stored in the last slot of 'B') w - bspline workspace Return: success or error Notes: 1) the w->knots vector must be initialized before calling this function 2) On output, B contains: B = [B_{i-k+1,k}, B_{i-k+2,k}, ..., B_{i-1,k}, B_{i,k}] where 'i' is stored in 'idx' on output 3) based on PPPACK bsplvb */ static int bspline_eval_all(const double x, gsl_vector *B, size_t *idx, gsl_bspline_workspace *w) { if (B->size != w->k) { GSL_ERROR("B vector not of length k", GSL_EBADLEN); } else { size_t i; /* spline index */ size_t j; /* looping */ size_t ii; /* looping */ int flag = 0; /* error flag */ double saved; double term; i = bspline_find_interval(x, &flag, w); if (flag == -1) { GSL_ERROR("x outside of knot interval", GSL_EINVAL); } else if (flag == 1) { if (x <= gsl_vector_get(w->knots, i) + GSL_DBL_EPSILON) { --i; } else { GSL_ERROR("x outside of knot interval", GSL_EINVAL); } } *idx = i; gsl_vector_set(B, 0, 1.0); for (j = 0; j < w->k - 1; ++j) { gsl_vector_set(w->deltar, j, gsl_vector_get(w->knots, i + j + 1) - x); gsl_vector_set(w->deltal, j, x - gsl_vector_get(w->knots, i - j)); saved = 0.0; for (ii = 0; ii <= j; ++ii) { term = gsl_vector_get(B, ii) / (gsl_vector_get(w->deltar, ii) + gsl_vector_get(w->deltal, j - ii)); gsl_vector_set(B, ii, saved + gsl_vector_get(w->deltar, ii) * term); saved = gsl_vector_get(w->deltal, j - ii) * term; } gsl_vector_set(B, j + 1, saved); } return GSL_SUCCESS; } } /* bspline_eval_all() */ /* bspline_find_interval() Find knot interval such that t_i <= x < t_{i + 1} where the t_i are knot values. Inputs: x - x value flag - (output) error flag w - bspline workspace Return: i (index in w->knots corresponding to left limit of interval) Notes: The error conditions are reported as follows: Condition Return value Flag --------- ------------ ---- x < t_0 0 -1 t_i <= x < t_{i+1} i 0 t_{n+k-1} <= x l+k-1 +1 */ static inline size_t bspline_find_interval(const double x, int *flag, gsl_bspline_workspace *w) { size_t i; if (x < gsl_vector_get(w->knots, 0)) { *flag = -1; return 0; } /* find i such that t_i <= x < t_{i+1} */ for (i = w->k - 1; i < w->k + w->l - 1; ++i) { const double ti = gsl_vector_get(w->knots, i); const double tip1 = gsl_vector_get(w->knots, i + 1); if (tip1 < ti) { GSL_ERROR("knots vector is not increasing", GSL_EINVAL); } if (ti <= x && x < tip1) break; } if (i == w->k + w->l - 1) *flag = 1; else *flag = 0; return i; } /* bspline_find_interval() */ praat-6.0.04/external/gsl/gsl_cblas.h000066400000000000000000001016151261542461700174350ustar00rootroot00000000000000/* blas/gsl_cblas.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* This is a copy of the CBLAS standard header. * We carry this around so we do not have to * break our model for flexible BLAS functionality. */ #ifndef __GSL_CBLAS_H__ #define __GSL_CBLAS_H__ #include #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS /* empty */ #define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* * Enumerated and derived types */ #define CBLAS_INDEX size_t /* this may vary between platforms */ enum CBLAS_ORDER {CblasRowMajor=101, CblasColMajor=102}; enum CBLAS_TRANSPOSE {CblasNoTrans=111, CblasTrans=112, CblasConjTrans=113}; enum CBLAS_UPLO {CblasUpper=121, CblasLower=122}; enum CBLAS_DIAG {CblasNonUnit=131, CblasUnit=132}; enum CBLAS_SIDE {CblasLeft=141, CblasRight=142}; /* * =========================================================================== * Prototypes for level 1 BLAS functions (complex are recast as routines) * =========================================================================== */ float cblas_sdsdot(const int N, const float alpha, const float *X, const int incX, const float *Y, const int incY); double cblas_dsdot(const int N, const float *X, const int incX, const float *Y, const int incY); float cblas_sdot(const int N, const float *X, const int incX, const float *Y, const int incY); double cblas_ddot(const int N, const double *X, const int incX, const double *Y, const int incY); /* * Functions having prefixes Z and C only */ void cblas_cdotu_sub(const int N, const void *X, const int incX, const void *Y, const int incY, void *dotu); void cblas_cdotc_sub(const int N, const void *X, const int incX, const void *Y, const int incY, void *dotc); void cblas_zdotu_sub(const int N, const void *X, const int incX, const void *Y, const int incY, void *dotu); void cblas_zdotc_sub(const int N, const void *X, const int incX, const void *Y, const int incY, void *dotc); /* * Functions having prefixes S D SC DZ */ float cblas_snrm2(const int N, const float *X, const int incX); float cblas_sasum(const int N, const float *X, const int incX); double cblas_dnrm2(const int N, const double *X, const int incX); double cblas_dasum(const int N, const double *X, const int incX); float cblas_scnrm2(const int N, const void *X, const int incX); float cblas_scasum(const int N, const void *X, const int incX); double cblas_dznrm2(const int N, const void *X, const int incX); double cblas_dzasum(const int N, const void *X, const int incX); /* * Functions having standard 4 prefixes (S D C Z) */ CBLAS_INDEX cblas_isamax(const int N, const float *X, const int incX); CBLAS_INDEX cblas_idamax(const int N, const double *X, const int incX); CBLAS_INDEX cblas_icamax(const int N, const void *X, const int incX); CBLAS_INDEX cblas_izamax(const int N, const void *X, const int incX); /* * =========================================================================== * Prototypes for level 1 BLAS routines * =========================================================================== */ /* * Routines with standard 4 prefixes (s, d, c, z) */ void cblas_sswap(const int N, float *X, const int incX, float *Y, const int incY); void cblas_scopy(const int N, const float *X, const int incX, float *Y, const int incY); void cblas_saxpy(const int N, const float alpha, const float *X, const int incX, float *Y, const int incY); void cblas_dswap(const int N, double *X, const int incX, double *Y, const int incY); void cblas_dcopy(const int N, const double *X, const int incX, double *Y, const int incY); void cblas_daxpy(const int N, const double alpha, const double *X, const int incX, double *Y, const int incY); void cblas_cswap(const int N, void *X, const int incX, void *Y, const int incY); void cblas_ccopy(const int N, const void *X, const int incX, void *Y, const int incY); void cblas_caxpy(const int N, const void *alpha, const void *X, const int incX, void *Y, const int incY); void cblas_zswap(const int N, void *X, const int incX, void *Y, const int incY); void cblas_zcopy(const int N, const void *X, const int incX, void *Y, const int incY); void cblas_zaxpy(const int N, const void *alpha, const void *X, const int incX, void *Y, const int incY); /* * Routines with S and D prefix only */ void cblas_srotg(float *a, float *b, float *c, float *s); void cblas_srotmg(float *d1, float *d2, float *b1, const float b2, float *P); void cblas_srot(const int N, float *X, const int incX, float *Y, const int incY, const float c, const float s); void cblas_srotm(const int N, float *X, const int incX, float *Y, const int incY, const float *P); void cblas_drotg(double *a, double *b, double *c, double *s); void cblas_drotmg(double *d1, double *d2, double *b1, const double b2, double *P); void cblas_drot(const int N, double *X, const int incX, double *Y, const int incY, const double c, const double s); void cblas_drotm(const int N, double *X, const int incX, double *Y, const int incY, const double *P); /* * Routines with S D C Z CS and ZD prefixes */ void cblas_sscal(const int N, const float alpha, float *X, const int incX); void cblas_dscal(const int N, const double alpha, double *X, const int incX); void cblas_cscal(const int N, const void *alpha, void *X, const int incX); void cblas_zscal(const int N, const void *alpha, void *X, const int incX); void cblas_csscal(const int N, const float alpha, void *X, const int incX); void cblas_zdscal(const int N, const double alpha, void *X, const int incX); /* * =========================================================================== * Prototypes for level 2 BLAS * =========================================================================== */ /* * Routines with standard 4 prefixes (S, D, C, Z) */ void cblas_sgemv(const enum CBLAS_ORDER order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const float alpha, const float *A, const int lda, const float *X, const int incX, const float beta, float *Y, const int incY); void cblas_sgbmv(const enum CBLAS_ORDER order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const int KL, const int KU, const float alpha, const float *A, const int lda, const float *X, const int incX, const float beta, float *Y, const int incY); void cblas_strmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const float *A, const int lda, float *X, const int incX); void cblas_stbmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const int K, const float *A, const int lda, float *X, const int incX); void cblas_stpmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const float *Ap, float *X, const int incX); void cblas_strsv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const float *A, const int lda, float *X, const int incX); void cblas_stbsv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const int K, const float *A, const int lda, float *X, const int incX); void cblas_stpsv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const float *Ap, float *X, const int incX); void cblas_dgemv(const enum CBLAS_ORDER order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const double alpha, const double *A, const int lda, const double *X, const int incX, const double beta, double *Y, const int incY); void cblas_dgbmv(const enum CBLAS_ORDER order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const int KL, const int KU, const double alpha, const double *A, const int lda, const double *X, const int incX, const double beta, double *Y, const int incY); void cblas_dtrmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const double *A, const int lda, double *X, const int incX); void cblas_dtbmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const int K, const double *A, const int lda, double *X, const int incX); void cblas_dtpmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const double *Ap, double *X, const int incX); void cblas_dtrsv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const double *A, const int lda, double *X, const int incX); void cblas_dtbsv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const int K, const double *A, const int lda, double *X, const int incX); void cblas_dtpsv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const double *Ap, double *X, const int incX); void cblas_cgemv(const enum CBLAS_ORDER order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const void *alpha, const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY); void cblas_cgbmv(const enum CBLAS_ORDER order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const int KL, const int KU, const void *alpha, const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY); void cblas_ctrmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const void *A, const int lda, void *X, const int incX); void cblas_ctbmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const int K, const void *A, const int lda, void *X, const int incX); void cblas_ctpmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const void *Ap, void *X, const int incX); void cblas_ctrsv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const void *A, const int lda, void *X, const int incX); void cblas_ctbsv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const int K, const void *A, const int lda, void *X, const int incX); void cblas_ctpsv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const void *Ap, void *X, const int incX); void cblas_zgemv(const enum CBLAS_ORDER order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const void *alpha, const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY); void cblas_zgbmv(const enum CBLAS_ORDER order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const int KL, const int KU, const void *alpha, const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY); void cblas_ztrmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const void *A, const int lda, void *X, const int incX); void cblas_ztbmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const int K, const void *A, const int lda, void *X, const int incX); void cblas_ztpmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const void *Ap, void *X, const int incX); void cblas_ztrsv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const void *A, const int lda, void *X, const int incX); void cblas_ztbsv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const int K, const void *A, const int lda, void *X, const int incX); void cblas_ztpsv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const void *Ap, void *X, const int incX); /* * Routines with S and D prefixes only */ void cblas_ssymv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const float alpha, const float *A, const int lda, const float *X, const int incX, const float beta, float *Y, const int incY); void cblas_ssbmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const int K, const float alpha, const float *A, const int lda, const float *X, const int incX, const float beta, float *Y, const int incY); void cblas_sspmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const float alpha, const float *Ap, const float *X, const int incX, const float beta, float *Y, const int incY); void cblas_sger(const enum CBLAS_ORDER order, const int M, const int N, const float alpha, const float *X, const int incX, const float *Y, const int incY, float *A, const int lda); void cblas_ssyr(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const float alpha, const float *X, const int incX, float *A, const int lda); void cblas_sspr(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const float alpha, const float *X, const int incX, float *Ap); void cblas_ssyr2(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const float alpha, const float *X, const int incX, const float *Y, const int incY, float *A, const int lda); void cblas_sspr2(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const float alpha, const float *X, const int incX, const float *Y, const int incY, float *A); void cblas_dsymv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const double alpha, const double *A, const int lda, const double *X, const int incX, const double beta, double *Y, const int incY); void cblas_dsbmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const int K, const double alpha, const double *A, const int lda, const double *X, const int incX, const double beta, double *Y, const int incY); void cblas_dspmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const double alpha, const double *Ap, const double *X, const int incX, const double beta, double *Y, const int incY); void cblas_dger(const enum CBLAS_ORDER order, const int M, const int N, const double alpha, const double *X, const int incX, const double *Y, const int incY, double *A, const int lda); void cblas_dsyr(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const double alpha, const double *X, const int incX, double *A, const int lda); void cblas_dspr(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const double alpha, const double *X, const int incX, double *Ap); void cblas_dsyr2(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const double alpha, const double *X, const int incX, const double *Y, const int incY, double *A, const int lda); void cblas_dspr2(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const double alpha, const double *X, const int incX, const double *Y, const int incY, double *A); /* * Routines with C and Z prefixes only */ void cblas_chemv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const void *alpha, const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY); void cblas_chbmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const int K, const void *alpha, const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY); void cblas_chpmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const void *alpha, const void *Ap, const void *X, const int incX, const void *beta, void *Y, const int incY); void cblas_cgeru(const enum CBLAS_ORDER order, const int M, const int N, const void *alpha, const void *X, const int incX, const void *Y, const int incY, void *A, const int lda); void cblas_cgerc(const enum CBLAS_ORDER order, const int M, const int N, const void *alpha, const void *X, const int incX, const void *Y, const int incY, void *A, const int lda); void cblas_cher(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const float alpha, const void *X, const int incX, void *A, const int lda); void cblas_chpr(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const float alpha, const void *X, const int incX, void *A); void cblas_cher2(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const void *alpha, const void *X, const int incX, const void *Y, const int incY, void *A, const int lda); void cblas_chpr2(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const void *alpha, const void *X, const int incX, const void *Y, const int incY, void *Ap); void cblas_zhemv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const void *alpha, const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY); void cblas_zhbmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const int K, const void *alpha, const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY); void cblas_zhpmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const void *alpha, const void *Ap, const void *X, const int incX, const void *beta, void *Y, const int incY); void cblas_zgeru(const enum CBLAS_ORDER order, const int M, const int N, const void *alpha, const void *X, const int incX, const void *Y, const int incY, void *A, const int lda); void cblas_zgerc(const enum CBLAS_ORDER order, const int M, const int N, const void *alpha, const void *X, const int incX, const void *Y, const int incY, void *A, const int lda); void cblas_zher(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const double alpha, const void *X, const int incX, void *A, const int lda); void cblas_zhpr(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const double alpha, const void *X, const int incX, void *A); void cblas_zher2(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const void *alpha, const void *X, const int incX, const void *Y, const int incY, void *A, const int lda); void cblas_zhpr2(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const void *alpha, const void *X, const int incX, const void *Y, const int incY, void *Ap); /* * =========================================================================== * Prototypes for level 3 BLAS * =========================================================================== */ /* * Routines with standard 4 prefixes (S, D, C, Z) */ void cblas_sgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB, const int M, const int N, const int K, const float alpha, const float *A, const int lda, const float *B, const int ldb, const float beta, float *C, const int ldc); void cblas_ssymm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const int M, const int N, const float alpha, const float *A, const int lda, const float *B, const int ldb, const float beta, float *C, const int ldc); void cblas_ssyrk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const float alpha, const float *A, const int lda, const float beta, float *C, const int ldc); void cblas_ssyr2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const float alpha, const float *A, const int lda, const float *B, const int ldb, const float beta, float *C, const int ldc); void cblas_strmm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int M, const int N, const float alpha, const float *A, const int lda, float *B, const int ldb); void cblas_strsm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int M, const int N, const float alpha, const float *A, const int lda, float *B, const int ldb); void cblas_dgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB, const int M, const int N, const int K, const double alpha, const double *A, const int lda, const double *B, const int ldb, const double beta, double *C, const int ldc); void cblas_dsymm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const int M, const int N, const double alpha, const double *A, const int lda, const double *B, const int ldb, const double beta, double *C, const int ldc); void cblas_dsyrk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const double alpha, const double *A, const int lda, const double beta, double *C, const int ldc); void cblas_dsyr2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const double alpha, const double *A, const int lda, const double *B, const int ldb, const double beta, double *C, const int ldc); void cblas_dtrmm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int M, const int N, const double alpha, const double *A, const int lda, double *B, const int ldb); void cblas_dtrsm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int M, const int N, const double alpha, const double *A, const int lda, double *B, const int ldb); void cblas_cgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB, const int M, const int N, const int K, const void *alpha, const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc); void cblas_csymm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const int M, const int N, const void *alpha, const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc); void cblas_csyrk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const void *alpha, const void *A, const int lda, const void *beta, void *C, const int ldc); void cblas_csyr2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const void *alpha, const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc); void cblas_ctrmm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int M, const int N, const void *alpha, const void *A, const int lda, void *B, const int ldb); void cblas_ctrsm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int M, const int N, const void *alpha, const void *A, const int lda, void *B, const int ldb); void cblas_zgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB, const int M, const int N, const int K, const void *alpha, const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc); void cblas_zsymm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const int M, const int N, const void *alpha, const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc); void cblas_zsyrk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const void *alpha, const void *A, const int lda, const void *beta, void *C, const int ldc); void cblas_zsyr2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const void *alpha, const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc); void cblas_ztrmm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int M, const int N, const void *alpha, const void *A, const int lda, void *B, const int ldb); void cblas_ztrsm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int M, const int N, const void *alpha, const void *A, const int lda, void *B, const int ldb); /* * Routines with prefixes C and Z only */ void cblas_chemm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const int M, const int N, const void *alpha, const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc); void cblas_cherk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const float alpha, const void *A, const int lda, const float beta, void *C, const int ldc); void cblas_cher2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const void *alpha, const void *A, const int lda, const void *B, const int ldb, const float beta, void *C, const int ldc); void cblas_zhemm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const int M, const int N, const void *alpha, const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc); void cblas_zherk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const double alpha, const void *A, const int lda, const double beta, void *C, const int ldc); void cblas_zher2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const void *alpha, const void *A, const int lda, const void *B, const int ldb, const double beta, void *C, const int ldc); void cblas_xerbla(int p, const char *rout, const char *form, ...); __END_DECLS #endif /* __GSL_CBLAS_H__ */ praat-6.0.04/external/gsl/gsl_cblas__caxpy.c000066400000000000000000000004141261542461700207660ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_caxpy (const int N, const void *alpha, const void *X, const int incX, void *Y, const int incY) { #define BASE float #include "gsl_cblas__source_axpy_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__cblas.h000066400000000000000000000017041261542461700207360ustar00rootroot00000000000000#define INDEX int #define OFFSET(N, incX) ((incX) > 0 ? 0 : ((N) - 1) * (-(incX))) #define BLAS_ERROR(x) cblas_xerbla(0, __FILE__, x); #define CONJUGATE(x) ((x) == CblasConjTrans) #define TRANSPOSE(x) ((x) == CblasTrans || (x) == CblasConjTrans) #define UPPER(x) ((x) == CblasUpper) #define LOWER(x) ((x) == CblasLower) /* Handling of packed complex types... */ #define REAL(a,i) (((BASE *) a)[2*(i)]) #define IMAG(a,i) (((BASE *) a)[2*(i)+1]) #define REAL0(a) (((BASE *)a)[0]) #define IMAG0(a) (((BASE *)a)[1]) #define CONST_REAL(a,i) (((const BASE *) a)[2*(i)]) #define CONST_IMAG(a,i) (((const BASE *) a)[2*(i)+1]) #define CONST_REAL0(a) (((const BASE *)a)[0]) #define CONST_IMAG0(a) (((const BASE *)a)[1]) #define GB(KU,KL,lda,i,j) ((KU+1+(i-j))*lda + j) #define TRCOUNT(N,i) ((((i)+1)*(2*(N)-(i)))/2) /* #define TBUP(N,i,j) */ /* #define TBLO(N,i,j) */ #define TPUP(N,i,j) (TRCOUNT(N,(i)-1)+(j)-(i)) #define TPLO(N,i,j) (((i)*((i)+1))/2 + (j)) praat-6.0.04/external/gsl/gsl_cblas__ccopy.c000066400000000000000000000003711261542461700207610ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_ccopy (const int N, const void *X, const int incX, void *Y, const int incY) { #define BASE float #include "gsl_cblas__source_copy_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__cdotc_sub.c000066400000000000000000000004721261542461700216130ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_cdotc_sub (const int N, const void *X, const int incX, const void *Y, const int incY, void *result) { #define BASE float #define CONJ_SIGN (-1.0) #include "gsl_cblas__source_dot_c.h" #undef CONJ_SIGN #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__cdotu_sub.c000066400000000000000000000004671261542461700216410ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_cdotu_sub (const int N, const void *X, const int incX, const void *Y, const int incY, void *result) { #define BASE float #define CONJ_SIGN 1.0 #include "gsl_cblas__source_dot_c.h" #undef CONJ_SIGN #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__cgbmv.c000066400000000000000000000007001261542461700207360ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_cgbmv (const enum CBLAS_ORDER order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const int KL, const int KU, const void *alpha, const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY) { #define BASE float #include "gsl_cblas__source_gbmv_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__cgemm.c000066400000000000000000000007371261542461700207420ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_cgemm (const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB, const int M, const int N, const int K, const void *alpha, const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc) { #define BASE float #include "gsl_cblas__source_gemm_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__cgemv.c000066400000000000000000000006441261542461700207500ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_cgemv (const enum CBLAS_ORDER order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const void *alpha, const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY) { #define BASE float #include "gsl_cblas__source_gemv_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__cgerc.c000066400000000000000000000005401261542461700207250ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_cgerc (const enum CBLAS_ORDER order, const int M, const int N, const void *alpha, const void *X, const int incX, const void *Y, const int incY, void *A, const int lda) { #define BASE float #include "gsl_cblas__source_gerc.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__cgeru.c000066400000000000000000000005401261542461700207470ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_cgeru (const enum CBLAS_ORDER order, const int M, const int N, const void *alpha, const void *X, const int incX, const void *Y, const int incY, void *A, const int lda) { #define BASE float #include "gsl_cblas__source_geru.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__chbmv.c000066400000000000000000000006331261542461700207440ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_chbmv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const int K, const void *alpha, const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY) { #define BASE float #include "gsl_cblas__source_hbmv.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__chemm.c000066400000000000000000000006651261542461700207430ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_chemm (const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const int M, const int N, const void *alpha, const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc) { #define BASE float #include "gsl_cblas__source_hemm.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__chemv.c000066400000000000000000000006161261542461700207500ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_chemv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const void *alpha, const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY) { #define BASE float #include "gsl_cblas__source_hemv.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__cher.c000066400000000000000000000005141261542461700205640ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_cher (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const float alpha, const void *X, const int incX, void *A, const int lda) { #define BASE float #include "gsl_cblas__source_her.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__cher2.c000066400000000000000000000005571261542461700206550ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_cher2 (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const void *alpha, const void *X, const int incX, const void *Y, const int incY, void *A, const int lda) { #define BASE float #include "gsl_cblas__source_her2.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__cher2k.c000066400000000000000000000007001261542461700210160ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_cher2k (const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const void *alpha, const void *A, const int lda, const void *B, const int ldb, const float beta, void *C, const int ldc) { #define BASE float #include "gsl_cblas__source_her2k.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__cherk.c000066400000000000000000000006351261542461700207430ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_cherk (const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const float alpha, const void *A, const int lda, const float beta, void *C, const int ldc) { #define BASE float #include "gsl_cblas__source_herk.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__chpmv.c000066400000000000000000000005631261542461700207640ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_chpmv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const void *alpha, const void *Ap, const void *X, const int incX, const void *beta, void *Y, const int incY) { #define BASE float #include "gsl_cblas__source_hpmv.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__chpr.c000066400000000000000000000004761261542461700206060ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_chpr (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const float alpha, const void *X, const int incX, void *Ap) { #define BASE float #include "gsl_cblas__source_hpr.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__chpr2.c000066400000000000000000000005411261542461700206610ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_chpr2 (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const void *alpha, const void *X, const int incX, const void *Y, const int incY, void *Ap) { #define BASE float #include "gsl_cblas__source_hpr2.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__cscal.c000066400000000000000000000003401261542461700207250ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_cscal (const int N, const void *alpha, void *X, const int incX) { #define BASE float #include "gsl_cblas__source_scal_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__csscal.c000066400000000000000000000003431261542461700211130ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_csscal (const int N, const float alpha, void *X, const int incX) { #define BASE float #include "gsl_cblas__source_scal_c_s.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__cswap.c000066400000000000000000000003461261542461700207630ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_cswap (const int N, void *X, const int incX, void *Y, const int incY) { #define BASE float #include "gsl_cblas__source_swap_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__csymm.c000066400000000000000000000006671261542461700210040ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_csymm (const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const int M, const int N, const void *alpha, const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc) { #define BASE float #include "gsl_cblas__source_symm_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__csyr2k.c000066400000000000000000000007021261542461700210570ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_csyr2k (const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const void *alpha, const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc) { #define BASE float #include "gsl_cblas__source_syr2k_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__csyrk.c000066400000000000000000000006371261542461700210040ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_csyrk (const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const void *alpha, const void *A, const int lda, const void *beta, void *C, const int ldc) { #define BASE float #include "gsl_cblas__source_syrk_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__ctbmv.c000066400000000000000000000006301261542461700207550ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_ctbmv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const int K, const void *A, const int lda, void *X, const int incX) { #define BASE float #include "gsl_cblas__source_tbmv_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__ctbsv.c000066400000000000000000000006671261542461700207750ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" #include "gsl_cblas__hypot.c" void cblas_ctbsv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const int K, const void *A, const int lda, void *X, const int incX) { #define BASE float #include "gsl_cblas__source_tbsv_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__ctpmv.c000066400000000000000000000005601261542461700207750ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_ctpmv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const void *Ap, void *X, const int incX) { #define BASE float #include "gsl_cblas__source_tpmv_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__ctpsv.c000066400000000000000000000006171261542461700210060ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" #include "gsl_cblas__hypot.c" void cblas_ctpsv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const void *Ap, void *X, const int incX) { #define BASE float #include "gsl_cblas__source_tpsv_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__ctrmm.c000066400000000000000000000007231261542461700207670ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_ctrmm (const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int M, const int N, const void *alpha, const void *A, const int lda, void *B, const int ldb) { #define BASE float #include "gsl_cblas__source_trmm_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__ctrmv.c000066400000000000000000000006131261542461700207760ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_ctrmv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const void *A, const int lda, void *X, const int incX) { #define BASE float #include "gsl_cblas__source_trmv_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__ctrsm.c000066400000000000000000000007621261542461700210000ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" #include "gsl_cblas__hypot.c" void cblas_ctrsm (const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int M, const int N, const void *alpha, const void *A, const int lda, void *B, const int ldb) { #define BASE float #include "gsl_cblas__source_trsm_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__ctrsv.c000066400000000000000000000006521261542461700210070ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" #include "gsl_cblas__hypot.c" void cblas_ctrsv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const void *A, const int lda, void *X, const int incX) { #define BASE float #include "gsl_cblas__source_trsv_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dasum.c000066400000000000000000000003301261542461700207500ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" double cblas_dasum (const int N, const double *X, const int incX) { #define BASE double #include "gsl_cblas__source_asum_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__daxpy.c000066400000000000000000000004221261542461700207660ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_daxpy (const int N, const double alpha, const double *X, const int incX, double *Y, const int incY) { #define BASE double #include "gsl_cblas__source_axpy_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dcopy.c000066400000000000000000000003761261542461700207670ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_dcopy (const int N, const double *X, const int incX, double *Y, const int incY) { #define BASE double #include "gsl_cblas__source_copy_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__ddot.c000066400000000000000000000005221261542461700205740ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" double cblas_ddot (const int N, const double *X, const int incX, const double *Y, const int incY) { #define INIT_VAL 0.0 #define ACC_TYPE double #define BASE double #include "gsl_cblas__source_dot_r.h" #undef ACC_TYPE #undef BASE #undef INIT_VAL } praat-6.0.04/external/gsl/gsl_cblas__dgbmv.c000066400000000000000000000007261261542461700207470ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_dgbmv (const enum CBLAS_ORDER order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const int KL, const int KU, const double alpha, const double *A, const int lda, const double *X, const int incX, const double beta, double *Y, const int incY) { #define BASE double #include "gsl_cblas__source_gbmv_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dgemm.c000066400000000000000000000007501261542461700207360ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_dgemm (const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB, const int M, const int N, const int K, const double alpha, const double *A, const int lda, const double *B, const int ldb, const double beta, double *C, const int ldc) { #define BASE double #include "gsl_cblas__source_gemm_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dgemv.c000066400000000000000000000006551261542461700207530ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_dgemv (const enum CBLAS_ORDER order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const double alpha, const double *A, const int lda, const double *X, const int incX, const double beta, double *Y, const int incY) { #define BASE double #include "gsl_cblas__source_gemv_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dger.c000066400000000000000000000005441261542461700205670ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_dger (const enum CBLAS_ORDER order, const int M, const int N, const double alpha, const double *X, const int incX, const double *Y, const int incY, double *A, const int lda) { #define BASE double #include "gsl_cblas__source_ger.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dnrm2.c000066400000000000000000000003301261542461700206610ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" double cblas_dnrm2 (const int N, const double *X, const int incX) { #define BASE double #include "gsl_cblas__source_nrm2_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__drot.c000066400000000000000000000004231261542461700206120ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_drot (const int N, double *X, const int incX, double *Y, const int incY, const double c, const double s) { #define BASE double #include "gsl_cblas__source_rot.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__drotg.c000066400000000000000000000003221261542461700207570ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_drotg (double *a, double *b, double *c, double *s) { #define BASE double #include "gsl_cblas__source_rotg.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__drotm.c000066400000000000000000000004071261542461700207710ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_drotm (const int N, double *X, const int incX, double *Y, const int incY, const double *P) { #define BASE double #include "gsl_cblas__source_rotm.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__drotmg.c000066400000000000000000000003501261542461700211350ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_drotmg (double *d1, double *d2, double *b1, const double b2, double *P) { #define BASE double #include "gsl_cblas__source_rotmg.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dsbmv.c000066400000000000000000000006441261542461700207620ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_dsbmv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const int K, const double alpha, const double *A, const int lda, const double *X, const int incX, const double beta, double *Y, const int incY) { #define BASE double #include "gsl_cblas__source_sbmv.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dscal.c000066400000000000000000000003441261542461700207320ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_dscal (const int N, const double alpha, double *X, const int incX) { #define BASE double #include "gsl_cblas__source_scal_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dsdot.c000066400000000000000000000005211261542461700207560ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" double cblas_dsdot (const int N, const float *X, const int incX, const float *Y, const int incY) { #define INIT_VAL 0.0 #define ACC_TYPE double #define BASE float #include "gsl_cblas__source_dot_r.h" #undef ACC_TYPE #undef BASE #undef INIT_VAL } praat-6.0.04/external/gsl/gsl_cblas__dspmv.c000066400000000000000000000006111261542461700207720ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_dspmv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const double alpha, const double *Ap, const double *X, const int incX, const double beta, double *Y, const int incY) { #define BASE double #include "gsl_cblas__source_spmv.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dspr.c000066400000000000000000000005041261542461700206120ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_dspr (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const double alpha, const double *X, const int incX, double *Ap) { #define BASE double #include "gsl_cblas__source_spr.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dspr2.c000066400000000000000000000005511261542461700206760ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_dspr2 (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const double alpha, const double *X, const int incX, const double *Y, const int incY, double *Ap) { #define BASE double #include "gsl_cblas__source_spr2.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dswap.c000066400000000000000000000003701261542461700207610ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_dswap (const int N, double *X, const int incX, double *Y, const int incY) { #define BASE double #include "gsl_cblas__source_swap_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dsymm.c000066400000000000000000000007151261542461700207770ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_dsymm (const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const int M, const int N, const double alpha, const double *A, const int lda, const double *B, const int ldb, const double beta, double *C, const int ldc) { #define BASE double #include "gsl_cblas__source_symm_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dsymv.c000066400000000000000000000006271261542461700210120ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_dsymv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const double alpha, const double *A, const int lda, const double *X, const int incX, const double beta, double *Y, const int incY) { #define BASE double #include "gsl_cblas__source_symv.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dsyr.c000066400000000000000000000005221261542461700206230ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_dsyr (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const double alpha, const double *X, const int incX, double *A, const int lda) { #define BASE double #include "gsl_cblas__source_syr.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dsyr2.c000066400000000000000000000005671261542461700207160ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_dsyr2 (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const double alpha, const double *X, const int incX, const double *Y, const int incY, double *A, const int lda) { #define BASE double #include "gsl_cblas__source_syr2.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dsyr2k.c000066400000000000000000000007311261542461700210620ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_dsyr2k (const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const double alpha, const double *A, const int lda, const double *B, const int ldb, const double beta, double *C, const int ldc) { #define BASE double #include "gsl_cblas__source_syr2k_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dsyrk.c000066400000000000000000000006461261542461700210050ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_dsyrk (const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const double alpha, const double *A, const int lda, const double beta, double *C, const int ldc) { #define BASE double #include "gsl_cblas__source_syrk_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dtbmv.c000066400000000000000000000006351261542461700207630ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_dtbmv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const int K, const double *A, const int lda, double *X, const int incX) { #define BASE double #include "gsl_cblas__source_tbmv_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dtbsv.c000066400000000000000000000006351261542461700207710ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_dtbsv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const int K, const double *A, const int lda, double *X, const int incX) { #define BASE double #include "gsl_cblas__source_tbsv_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dtpmv.c000066400000000000000000000005651261542461700210030ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_dtpmv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const double *Ap, double *X, const int incX) { #define BASE double #include "gsl_cblas__source_tpmv_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dtpsv.c000066400000000000000000000005651261542461700210110ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_dtpsv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const double *Ap, double *X, const int incX) { #define BASE double #include "gsl_cblas__source_tpsv_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dtrmm.c000066400000000000000000000007311261542461700207670ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_dtrmm (const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int M, const int N, const double alpha, const double *A, const int lda, double *B, const int ldb) { #define BASE double #include "gsl_cblas__source_trmm_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dtrmv.c000066400000000000000000000006201261542461700207750ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_dtrmv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const double *A, const int lda, double *X, const int incX) { #define BASE double #include "gsl_cblas__source_trmv_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dtrsm.c000066400000000000000000000007311261542461700207750ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_dtrsm (const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int M, const int N, const double alpha, const double *A, const int lda, double *B, const int ldb) { #define BASE double #include "gsl_cblas__source_trsm_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dtrsv.c000066400000000000000000000006201261542461700210030ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_dtrsv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const double *A, const int lda, double *X, const int incX) { #define BASE double #include "gsl_cblas__source_trsv_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dzasum.c000066400000000000000000000003271261542461700211500ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" double cblas_dzasum (const int N, const void *X, const int incX) { #define BASE double #include "gsl_cblas__source_asum_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__dznrm2.c000066400000000000000000000003271261542461700210610ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" double cblas_dznrm2 (const int N, const void *X, const int incX) { #define BASE double #include "gsl_cblas__source_nrm2_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__hypot.c000066400000000000000000000006561261542461700210150ustar00rootroot00000000000000#include static double xhypot (const double x, const double y); static double xhypot (const double x, const double y) { double xabs = fabs(x) ; double yabs = fabs(y) ; double min, max; if (xabs < yabs) { min = xabs ; max = yabs ; } else { min = yabs ; max = xabs ; } if (min == 0) { return max ; } { double u = min / max ; return max * sqrt (1 + u * u) ; } } praat-6.0.04/external/gsl/gsl_cblas__icamax.c000066400000000000000000000003341261542461700211050ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" CBLAS_INDEX cblas_icamax (const int N, const void *X, const int incX) { #define BASE float #include "gsl_cblas__source_iamax_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__idamax.c000066400000000000000000000003371261542461700211110ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" CBLAS_INDEX cblas_idamax (const int N, const double *X, const int incX) { #define BASE double #include "gsl_cblas__source_iamax_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__isamax.c000066400000000000000000000003351261542461700211260ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" CBLAS_INDEX cblas_isamax (const int N, const float *X, const int incX) { #define BASE float #include "gsl_cblas__source_iamax_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__izamax.c000066400000000000000000000003351261542461700211350ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" CBLAS_INDEX cblas_izamax (const int N, const void *X, const int incX) { #define BASE double #include "gsl_cblas__source_iamax_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__sasum.c000066400000000000000000000003251261542461700207730ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" float cblas_sasum (const int N, const float *X, const int incX) { #define BASE float #include "gsl_cblas__source_asum_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__saxpy.c000066400000000000000000000004161261542461700210100ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_saxpy (const int N, const float alpha, const float *X, const int incX, float *Y, const int incY) { #define BASE float #include "gsl_cblas__source_axpy_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__scasum.c000066400000000000000000000003251261542461700211360ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" float cblas_scasum (const int N, const void *X, const int incX) { #define BASE float #include "gsl_cblas__source_asum_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__scnrm2.c000066400000000000000000000003251261542461700210470ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" float cblas_scnrm2 (const int N, const void *X, const int incX) { #define BASE float #include "gsl_cblas__source_nrm2_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__scopy.c000066400000000000000000000003731261542461700210030ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_scopy (const int N, const float *X, const int incX, float *Y, const int incY) { #define BASE float #include "gsl_cblas__source_copy_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__sdot.c000066400000000000000000000005151261542461700206150ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" float cblas_sdot (const int N, const float *X, const int incX, const float *Y, const int incY) { #define INIT_VAL 0.0 #define ACC_TYPE float #define BASE float #include "gsl_cblas__source_dot_r.h" #undef ACC_TYPE #undef BASE #undef INIT_VAL } praat-6.0.04/external/gsl/gsl_cblas__sdsdot.c000066400000000000000000000005471261542461700211510ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" float cblas_sdsdot (const int N, const float alpha, const float *X, const int incX, const float *Y, const int incY) { #define INIT_VAL alpha #define ACC_TYPE double #define BASE float #include "gsl_cblas__source_dot_r.h" #undef ACC_TYPE #undef BASE #undef INIT_VAL } praat-6.0.04/external/gsl/gsl_cblas__sgbmv.c000066400000000000000000000007031261542461700207610ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_sgbmv (const enum CBLAS_ORDER order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const int KL, const int KU, const float alpha, const float *A, const int lda, const float *X, const int incX, const float beta, float *Y, const int incY) { #define BASE float #include "gsl_cblas__source_gbmv_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__sgemm.c000066400000000000000000000007421261542461700207560ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_sgemm (const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB, const int M, const int N, const int K, const float alpha, const float *A, const int lda, const float *B, const int ldb, const float beta, float *C, const int ldc) { #define BASE float #include "gsl_cblas__source_gemm_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__sgemv.c000066400000000000000000000006471261542461700207730ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_sgemv (const enum CBLAS_ORDER order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const float alpha, const float *A, const int lda, const float *X, const int incX, const float beta, float *Y, const int incY) { #define BASE float #include "gsl_cblas__source_gemv_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__sger.c000066400000000000000000000005371261542461700206100ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_sger (const enum CBLAS_ORDER order, const int M, const int N, const float alpha, const float *X, const int incX, const float *Y, const int incY, float *A, const int lda) { #define BASE float #include "gsl_cblas__source_ger.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__snrm2.c000066400000000000000000000003251261542461700207040ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" float cblas_snrm2 (const int N, const float *X, const int incX) { #define BASE float #include "gsl_cblas__source_nrm2_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__source_asum_c.h000066400000000000000000000020001261542461700224670ustar00rootroot00000000000000/* blas/source_asum_c.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { BASE r = 0.0; INDEX i; INDEX ix = 0; if (incX <= 0) { return 0; } for (i = 0; i < N; i++) { r += fabs(CONST_REAL(X, ix)) + fabs(CONST_IMAG(X, ix)); ix += incX; } return r; } praat-6.0.04/external/gsl/gsl_cblas__source_asum_r.h000066400000000000000000000017321261542461700225210ustar00rootroot00000000000000/* blas/source_asum_r.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { BASE r = 0.0; INDEX i; INDEX ix = 0; if (incX <= 0) { return 0; } for (i = 0; i < N; i++) { r += fabs(X[ix]); ix += incX; } return r; } praat-6.0.04/external/gsl/gsl_cblas__source_axpy_c.h000066400000000000000000000024721261542461700225200ustar00rootroot00000000000000/* blas/source_axpy_c.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i; INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); const BASE alpha_real = CONST_REAL0(alpha); const BASE alpha_imag = CONST_IMAG0(alpha); if (fabs(alpha_real) == 0 && fabs(alpha_imag) == 0) { return; } for (i = 0; i < N; i++) { const BASE x_real = CONST_REAL(X, ix); const BASE x_imag = CONST_IMAG(X, ix); REAL(Y, iy) += (alpha_real * x_real - alpha_imag * x_imag); IMAG(Y, iy) += (alpha_real * x_imag + alpha_imag * x_real); ix += incX; iy += incY; } } praat-6.0.04/external/gsl/gsl_cblas__source_axpy_r.h000066400000000000000000000025171261542461700225370ustar00rootroot00000000000000/* blas/source_axpy_r.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i; if (alpha == 0.0) { return; } if (incX == 1 && incY == 1) { const INDEX m = N % 4; for (i = 0; i < m; i++) { Y[i] += alpha * X[i]; } for (i = m; i + 3 < N; i += 4) { Y[i] += alpha * X[i]; Y[i + 1] += alpha * X[i + 1]; Y[i + 2] += alpha * X[i + 2]; Y[i + 3] += alpha * X[i + 3]; } } else { INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { Y[iy] += alpha * X[ix]; ix += incX; iy += incY; } } } praat-6.0.04/external/gsl/gsl_cblas__source_copy_c.h000066400000000000000000000020101261542461700224750ustar00rootroot00000000000000/* blas/source_copy_c.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i; INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { REAL(Y, iy) = CONST_REAL(X, ix); IMAG(Y, iy) = CONST_IMAG(X, ix); ix += incX; iy += incY; } } praat-6.0.04/external/gsl/gsl_cblas__source_copy_r.h000066400000000000000000000017211261542461700225240ustar00rootroot00000000000000/* blas/source_copy_r.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i; INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { Y[iy] = X[ix]; ix += incX; iy += incY; } } praat-6.0.04/external/gsl/gsl_cblas__source_dot_c.h000066400000000000000000000025001261542461700223150ustar00rootroot00000000000000/* blas/source_dot_c.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { BASE r_real = 0.0; BASE r_imag = 0.0; INDEX i; INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { const BASE x_real = CONST_REAL(X, ix); const BASE x_imag = CONST_IMAG(X, ix); const BASE y_real = CONST_REAL(Y, iy); const BASE y_imag = CONST_IMAG(Y, iy); r_real += x_real * y_real - CONJ_SIGN * x_imag * y_imag; r_imag += x_real * y_imag + CONJ_SIGN * x_imag * y_real; ix += incX; iy += incY; } REAL0(result) = r_real; IMAG0(result) = r_imag; } praat-6.0.04/external/gsl/gsl_cblas__source_dot_r.h000066400000000000000000000017731261542461700223470ustar00rootroot00000000000000/* blas/source_dot_r.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { ACC_TYPE r = INIT_VAL; INDEX i; INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { r += X[ix] * Y[iy]; ix += incX; iy += incY; } return r; } praat-6.0.04/external/gsl/gsl_cblas__source_gbmv_c.h000066400000000000000000000134251261542461700224720ustar00rootroot00000000000000/* blas/source_gbmv_c.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j; INDEX lenX, lenY, L, U; const BASE alpha_real = CONST_REAL0(alpha); const BASE alpha_imag = CONST_IMAG0(alpha); const BASE beta_real = CONST_REAL0(beta); const BASE beta_imag = CONST_IMAG0(beta); if (M == 0 || N == 0) return; if ((alpha_real == 0.0 && alpha_imag == 0.0) && (beta_real == 1.0 && beta_imag == 0.0)) return; if (TransA == CblasNoTrans) { lenX = N; lenY = M; L = KL; U = KU; } else { lenX = M; lenY = N; L = KU; U = KL; } /* form y := beta*y */ if (beta_real == 0.0 && beta_imag == 0.0) { INDEX iy = OFFSET(lenY, incY); for (i = 0; i < lenY; i++) { REAL(Y, iy) = 0.0; IMAG(Y, iy) = 0.0; iy += incY; } } else if (!(beta_real == 1.0 && beta_imag == 0.0)) { INDEX iy = OFFSET(lenY, incY); for (i = 0; i < lenY; i++) { const BASE y_real = REAL(Y, iy); const BASE y_imag = IMAG(Y, iy); const BASE tmpR = y_real * beta_real - y_imag * beta_imag; const BASE tmpI = y_real * beta_imag + y_imag * beta_real; REAL(Y, iy) = tmpR; IMAG(Y, iy) = tmpI; iy += incY; } } if (alpha_real == 0.0 && alpha_imag == 0.0) return; if ((order == CblasRowMajor && TransA == CblasNoTrans) || (order == CblasColMajor && TransA == CblasTrans)) { /* form y := alpha*A*x + y */ INDEX iy = OFFSET(lenY, incY); for (i = 0; i < lenY; i++) { BASE dotR = 0.0; BASE dotI = 0.0; const INDEX j_min = (i > L ? i - L : 0); const INDEX j_max = GSL_MIN(lenX, i + U + 1); INDEX ix = OFFSET(lenX, incX) + j_min * incX; for (j = j_min; j < j_max; j++) { const BASE x_real = CONST_REAL(X, ix); const BASE x_imag = CONST_IMAG(X, ix); const BASE A_real = CONST_REAL(A, lda * i + (L + j - i)); const BASE A_imag = CONST_IMAG(A, lda * i + (L + j - i)); dotR += A_real * x_real - A_imag * x_imag; dotI += A_real * x_imag + A_imag * x_real; ix += incX; } REAL(Y, iy) += alpha_real * dotR - alpha_imag * dotI; IMAG(Y, iy) += alpha_real * dotI + alpha_imag * dotR; iy += incY; } } else if ((order == CblasRowMajor && TransA == CblasTrans) || (order == CblasColMajor && TransA == CblasNoTrans)) { /* form y := alpha*A'*x + y */ INDEX ix = OFFSET(lenX, incX); for (j = 0; j < lenX; j++) { const BASE x_real = CONST_REAL(X, ix); const BASE x_imag = CONST_IMAG(X, ix); BASE tmpR = alpha_real * x_real - alpha_imag * x_imag; BASE tmpI = alpha_real * x_imag + alpha_imag * x_real; if (!(tmpR == 0.0 && tmpI == 0.0)) { const INDEX i_min = (j > U ? j - U : 0); const INDEX i_max = GSL_MIN(lenY, j + L + 1); INDEX iy = OFFSET(lenY, incY) + i_min * incY; for (i = i_min; i < i_max; i++) { const BASE A_real = CONST_REAL(A, lda * j + (U + i - j)); const BASE A_imag = CONST_IMAG(A, lda * j + (U + i - j)); REAL(Y, iy) += A_real * tmpR - A_imag * tmpI; IMAG(Y, iy) += A_real * tmpI + A_imag * tmpR; iy += incY; } } ix += incX; } } else if (order == CblasRowMajor && TransA == CblasConjTrans) { /* form y := alpha*A^H*x + y */ INDEX ix = OFFSET(lenX, incX); for (j = 0; j < lenX; j++) { const BASE x_real = CONST_REAL(X, ix); const BASE x_imag = CONST_IMAG(X, ix); BASE tmpR = alpha_real * x_real - alpha_imag * x_imag; BASE tmpI = alpha_real * x_imag + alpha_imag * x_real; if (!(tmpR == 0.0 && tmpI == 0.0)) { const INDEX i_min = (j > U ? j - U : 0); const INDEX i_max = GSL_MIN(lenY, j + L + 1); INDEX iy = OFFSET(lenY, incY) + i_min * incY; for (i = i_min; i < i_max; i++) { const BASE A_real = CONST_REAL(A, lda * j + (U + i - j)); const BASE A_imag = CONST_IMAG(A, lda * j + (U + i - j)); REAL(Y, iy) += A_real * tmpR - (-A_imag) * tmpI; IMAG(Y, iy) += A_real * tmpI + (-A_imag) * tmpR; iy += incY; } } ix += incX; } } else if (order == CblasColMajor && TransA == CblasConjTrans) { /* form y := alpha*A^H*x + y */ INDEX iy = OFFSET(lenY, incY); for (i = 0; i < lenY; i++) { BASE dotR = 0.0; BASE dotI = 0.0; const INDEX j_min = (i > L ? i - L : 0); const INDEX j_max = GSL_MIN(lenX, i + U + 1); INDEX ix = OFFSET(lenX, incX) + j_min * incX; for (j = j_min; j < j_max; j++) { const BASE x_real = CONST_REAL(X, ix); const BASE x_imag = CONST_IMAG(X, ix); const BASE A_real = CONST_REAL(A, lda * i + (L + j - i)); const BASE A_imag = CONST_IMAG(A, lda * i + (L + j - i)); dotR += A_real * x_real - (-A_imag) * x_imag; dotI += A_real * x_imag + (-A_imag) * x_real; ix += incX; } REAL(Y, iy) += alpha_real * dotR - alpha_imag * dotI; IMAG(Y, iy) += alpha_real * dotI + alpha_imag * dotR; iy += incY; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_gbmv_r.h000066400000000000000000000052631261542461700225120ustar00rootroot00000000000000/* blas/source_gbmv_r.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j; INDEX lenX, lenY, L, U; const int Trans = (TransA != CblasConjTrans) ? TransA : CblasTrans; if (M == 0 || N == 0) return; if (alpha == 0.0 && beta == 1.0) return; if (Trans == CblasNoTrans) { lenX = N; lenY = M; L = KL; U = KU; } else { lenX = M; lenY = N; L = KU; U = KL; } /* form y := beta*y */ if (beta == 0.0) { INDEX iy = OFFSET(lenY, incY); for (i = 0; i < lenY; i++) { Y[iy] = 0; iy += incY; } } else if (beta != 1.0) { INDEX iy = OFFSET(lenY, incY); for (i = 0; i < lenY; i++) { Y[iy] *= beta; iy += incY; } } if (alpha == 0.0) return; if ((order == CblasRowMajor && Trans == CblasNoTrans) || (order == CblasColMajor && Trans == CblasTrans)) { /* form y := alpha*A*x + y */ INDEX iy = OFFSET(lenY, incY); for (i = 0; i < lenY; i++) { BASE temp = 0.0; const INDEX j_min = (i > L ? i - L : 0); const INDEX j_max = GSL_MIN(lenX, i + U + 1); INDEX jx = OFFSET(lenX, incX) + j_min * incX; for (j = j_min; j < j_max; j++) { temp += X[jx] * A[(L - i + j) + i * lda]; jx += incX; } Y[iy] += alpha * temp; iy += incY; } } else if ((order == CblasRowMajor && Trans == CblasTrans) || (order == CblasColMajor && Trans == CblasNoTrans)) { /* form y := alpha*A'*x + y */ INDEX jx = OFFSET(lenX, incX); for (j = 0; j < lenX; j++) { const BASE temp = alpha * X[jx]; if (temp != 0.0) { const INDEX i_min = (j > U ? j - U : 0); const INDEX i_max = GSL_MIN(lenY, j + L + 1); INDEX iy = OFFSET(lenY, incY) + i_min * incY; for (i = i_min; i < i_max; i++) { Y[iy] += temp * A[lda * j + (U + i - j)]; iy += incY; } } jx += incX; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_gemm_c.h000066400000000000000000000135271261542461700224670ustar00rootroot00000000000000/* blas/source_gemm_c.h * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j, k; INDEX n1, n2; INDEX ldf, ldg; int conjF, conjG, TransF, TransG; const BASE *F, *G; const BASE alpha_real = CONST_REAL0(alpha); const BASE alpha_imag = CONST_IMAG0(alpha); const BASE beta_real = CONST_REAL0(beta); const BASE beta_imag = CONST_IMAG0(beta); if ((alpha_real == 0.0 && alpha_imag == 0.0) && (beta_real == 1.0 && beta_imag == 0.0)) return; if (Order == CblasRowMajor) { n1 = M; n2 = N; F = (const BASE *)A; ldf = lda; conjF = (TransA == CblasConjTrans) ? -1 : 1; TransF = (TransA == CblasNoTrans) ? CblasNoTrans : CblasTrans; G = (const BASE *)B; ldg = ldb; conjG = (TransB == CblasConjTrans) ? -1 : 1; TransG = (TransB == CblasNoTrans) ? CblasNoTrans : CblasTrans; } else { n1 = N; n2 = M; F = (const BASE *)B; ldf = ldb; conjF = (TransB == CblasConjTrans) ? -1 : 1; TransF = (TransB == CblasNoTrans) ? CblasNoTrans : CblasTrans; G = (const BASE *)A; ldg = lda; conjG = (TransA == CblasConjTrans) ? -1 : 1; TransG = (TransA == CblasNoTrans) ? CblasNoTrans : CblasTrans; } /* form y := beta*y */ if (beta_real == 0.0 && beta_imag == 0.0) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { REAL(C, ldc * i + j) = 0.0; IMAG(C, ldc * i + j) = 0.0; } } } else if (!(beta_real == 1.0 && beta_imag == 0.0)) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { const BASE Cij_real = REAL(C, ldc * i + j); const BASE Cij_imag = IMAG(C, ldc * i + j); REAL(C, ldc * i + j) = beta_real * Cij_real - beta_imag * Cij_imag; IMAG(C, ldc * i + j) = beta_real * Cij_imag + beta_imag * Cij_real; } } } if (alpha_real == 0.0 && alpha_imag == 0.0) return; if (TransF == CblasNoTrans && TransG == CblasNoTrans) { /* form C := alpha*A*B + C */ for (k = 0; k < K; k++) { for (i = 0; i < n1; i++) { const BASE Fik_real = CONST_REAL(F, ldf * i + k); const BASE Fik_imag = conjF * CONST_IMAG(F, ldf * i + k); const BASE temp_real = alpha_real * Fik_real - alpha_imag * Fik_imag; const BASE temp_imag = alpha_real * Fik_imag + alpha_imag * Fik_real; if (!(temp_real == 0.0 && temp_imag == 0.0)) { for (j = 0; j < n2; j++) { const BASE Gkj_real = CONST_REAL(G, ldg * k + j); const BASE Gkj_imag = conjG * CONST_IMAG(G, ldg * k + j); REAL(C, ldc * i + j) += temp_real * Gkj_real - temp_imag * Gkj_imag; IMAG(C, ldc * i + j) += temp_real * Gkj_imag + temp_imag * Gkj_real; } } } } } else if (TransF == CblasNoTrans && TransG == CblasTrans) { /* form C := alpha*A*B' + C */ for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { BASE temp_real = 0.0; BASE temp_imag = 0.0; for (k = 0; k < K; k++) { const BASE Fik_real = CONST_REAL(F, ldf * i + k); const BASE Fik_imag = conjF * CONST_IMAG(F, ldf * i + k); const BASE Gjk_real = CONST_REAL(G, ldg * j + k); const BASE Gjk_imag = conjG * CONST_IMAG(G, ldg * j + k); temp_real += Fik_real * Gjk_real - Fik_imag * Gjk_imag; temp_imag += Fik_real * Gjk_imag + Fik_imag * Gjk_real; } REAL(C, ldc * i + j) += alpha_real * temp_real - alpha_imag * temp_imag; IMAG(C, ldc * i + j) += alpha_real * temp_imag + alpha_imag * temp_real; } } } else if (TransF == CblasTrans && TransG == CblasNoTrans) { for (k = 0; k < K; k++) { for (i = 0; i < n1; i++) { const BASE Fki_real = CONST_REAL(F, ldf * k + i); const BASE Fki_imag = conjF * CONST_IMAG(F, ldf * k + i); const BASE temp_real = alpha_real * Fki_real - alpha_imag * Fki_imag; const BASE temp_imag = alpha_real * Fki_imag + alpha_imag * Fki_real; if (!(temp_real == 0.0 && temp_imag == 0.0)) { for (j = 0; j < n2; j++) { const BASE Gkj_real = CONST_REAL(G, ldg * k + j); const BASE Gkj_imag = conjG * CONST_IMAG(G, ldg * k + j); REAL(C, ldc * i + j) += temp_real * Gkj_real - temp_imag * Gkj_imag; IMAG(C, ldc * i + j) += temp_real * Gkj_imag + temp_imag * Gkj_real; } } } } } else if (TransF == CblasTrans && TransG == CblasTrans) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { BASE temp_real = 0.0; BASE temp_imag = 0.0; for (k = 0; k < K; k++) { const BASE Fki_real = CONST_REAL(F, ldf * k + i); const BASE Fki_imag = conjF * CONST_IMAG(F, ldf * k + i); const BASE Gjk_real = CONST_REAL(G, ldg * j + k); const BASE Gjk_imag = conjG * CONST_IMAG(G, ldg * j + k); temp_real += Fki_real * Gjk_real - Fki_imag * Gjk_imag; temp_imag += Fki_real * Gjk_imag + Fki_imag * Gjk_real; } REAL(C, ldc * i + j) += alpha_real * temp_real - alpha_imag * temp_imag; IMAG(C, ldc * i + j) += alpha_real * temp_imag + alpha_imag * temp_real; } } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_gemm_r.h000066400000000000000000000060561261542461700225050ustar00rootroot00000000000000/* blas/source_gemm_r.h * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j, k; INDEX n1, n2; INDEX ldf, ldg; int TransF, TransG; const BASE *F, *G; if (alpha == 0.0 && beta == 1.0) return; if (Order == CblasRowMajor) { n1 = M; n2 = N; F = A; ldf = lda; TransF = (TransA == CblasConjTrans) ? CblasTrans : TransA; G = B; ldg = ldb; TransG = (TransB == CblasConjTrans) ? CblasTrans : TransB; } else { n1 = N; n2 = M; F = B; ldf = ldb; TransF = (TransB == CblasConjTrans) ? CblasTrans : TransB; G = A; ldg = lda; TransG = (TransA == CblasConjTrans) ? CblasTrans : TransA; } /* form y := beta*y */ if (beta == 0.0) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { C[ldc * i + j] = 0.0; } } } else if (beta != 1.0) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { C[ldc * i + j] *= beta; } } } if (alpha == 0.0) return; if (TransF == CblasNoTrans && TransG == CblasNoTrans) { /* form C := alpha*A*B + C */ for (k = 0; k < K; k++) { for (i = 0; i < n1; i++) { const BASE temp = alpha * F[ldf * i + k]; if (temp != 0.0) { for (j = 0; j < n2; j++) { C[ldc * i + j] += temp * G[ldg * k + j]; } } } } } else if (TransF == CblasNoTrans && TransG == CblasTrans) { /* form C := alpha*A*B' + C */ for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { BASE temp = 0.0; for (k = 0; k < K; k++) { temp += F[ldf * i + k] * G[ldg * j + k]; } C[ldc * i + j] += alpha * temp; } } } else if (TransF == CblasTrans && TransG == CblasNoTrans) { for (k = 0; k < K; k++) { for (i = 0; i < n1; i++) { const BASE temp = alpha * F[ldf * k + i]; if (temp != 0.0) { for (j = 0; j < n2; j++) { C[ldc * i + j] += temp * G[ldg * k + j]; } } } } } else if (TransF == CblasTrans && TransG == CblasTrans) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { BASE temp = 0.0; for (k = 0; k < K; k++) { temp += F[ldf * k + i] * G[ldg * j + k]; } C[ldc * i + j] += alpha * temp; } } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_gemv_c.h000066400000000000000000000120211261542461700224640ustar00rootroot00000000000000/* blas/source_gemv_c.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j; INDEX lenX, lenY; const BASE alpha_real = CONST_REAL0(alpha); const BASE alpha_imag = CONST_IMAG0(alpha); const BASE beta_real = CONST_REAL0(beta); const BASE beta_imag = CONST_IMAG0(beta); if (M == 0 || N == 0) return; if ((alpha_real == 0.0 && alpha_imag == 0.0) && (beta_real == 1.0 && beta_imag == 0.0)) return; if (TransA == CblasNoTrans) { lenX = N; lenY = M; } else { lenX = M; lenY = N; } /* form y := beta*y */ if (beta_real == 0.0 && beta_imag == 0.0) { INDEX iy = OFFSET(lenY, incY); for (i = 0; i < lenY; i++) { REAL(Y, iy) = 0.0; IMAG(Y, iy) = 0.0; iy += incY; } } else if (!(beta_real == 1.0 && beta_imag == 0.0)) { INDEX iy = OFFSET(lenY, incY); for (i = 0; i < lenY; i++) { const BASE y_real = REAL(Y, iy); const BASE y_imag = IMAG(Y, iy); const BASE tmpR = y_real * beta_real - y_imag * beta_imag; const BASE tmpI = y_real * beta_imag + y_imag * beta_real; REAL(Y, iy) = tmpR; IMAG(Y, iy) = tmpI; iy += incY; } } if (alpha_real == 0.0 && alpha_imag == 0.0) return; if ((order == CblasRowMajor && TransA == CblasNoTrans) || (order == CblasColMajor && TransA == CblasTrans)) { /* form y := alpha*A*x + y */ INDEX iy = OFFSET(lenY, incY); for (i = 0; i < lenY; i++) { BASE dotR = 0.0; BASE dotI = 0.0; INDEX ix = OFFSET(lenX, incX); for (j = 0; j < lenX; j++) { const BASE x_real = CONST_REAL(X, ix); const BASE x_imag = CONST_IMAG(X, ix); const BASE A_real = CONST_REAL(A, lda * i + j); const BASE A_imag = CONST_IMAG(A, lda * i + j); dotR += A_real * x_real - A_imag * x_imag; dotI += A_real * x_imag + A_imag * x_real; ix += incX; } REAL(Y, iy) += alpha_real * dotR - alpha_imag * dotI; IMAG(Y, iy) += alpha_real * dotI + alpha_imag * dotR; iy += incY; } } else if ((order == CblasRowMajor && TransA == CblasTrans) || (order == CblasColMajor && TransA == CblasNoTrans)) { /* form y := alpha*A'*x + y */ INDEX ix = OFFSET(lenX, incX); for (j = 0; j < lenX; j++) { BASE x_real = CONST_REAL(X, ix); BASE x_imag = CONST_IMAG(X, ix); BASE tmpR = alpha_real * x_real - alpha_imag * x_imag; BASE tmpI = alpha_real * x_imag + alpha_imag * x_real; INDEX iy = OFFSET(lenY, incY); for (i = 0; i < lenY; i++) { const BASE A_real = CONST_REAL(A, lda * j + i); const BASE A_imag = CONST_IMAG(A, lda * j + i); REAL(Y, iy) += A_real * tmpR - A_imag * tmpI; IMAG(Y, iy) += A_real * tmpI + A_imag * tmpR; iy += incY; } ix += incX; } } else if (order == CblasRowMajor && TransA == CblasConjTrans) { /* form y := alpha*A^H*x + y */ INDEX ix = OFFSET(lenX, incX); for (j = 0; j < lenX; j++) { BASE x_real = CONST_REAL(X, ix); BASE x_imag = CONST_IMAG(X, ix); BASE tmpR = alpha_real * x_real - alpha_imag * x_imag; BASE tmpI = alpha_real * x_imag + alpha_imag * x_real; INDEX iy = OFFSET(lenY, incY); for (i = 0; i < lenY; i++) { const BASE A_real = CONST_REAL(A, lda * j + i); const BASE A_imag = CONST_IMAG(A, lda * j + i); REAL(Y, iy) += A_real * tmpR - (-A_imag) * tmpI; IMAG(Y, iy) += A_real * tmpI + (-A_imag) * tmpR; iy += incY; } ix += incX; } } else if (order == CblasColMajor && TransA == CblasConjTrans) { /* form y := alpha*A^H*x + y */ INDEX iy = OFFSET(lenY, incY); for (i = 0; i < lenY; i++) { BASE dotR = 0.0; BASE dotI = 0.0; INDEX ix = OFFSET(lenX, incX); for (j = 0; j < lenX; j++) { const BASE x_real = CONST_REAL(X, ix); const BASE x_imag = CONST_IMAG(X, ix); const BASE A_real = CONST_REAL(A, lda * i + j); const BASE A_imag = CONST_IMAG(A, lda * i + j); dotR += A_real * x_real - (-A_imag) * x_imag; dotI += A_real * x_imag + (-A_imag) * x_real; ix += incX; } REAL(Y, iy) += alpha_real * dotR - alpha_imag * dotI; IMAG(Y, iy) += alpha_real * dotI + alpha_imag * dotR; iy += incY; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_gemv_r.h000066400000000000000000000045711261542461700225160ustar00rootroot00000000000000/* blas/source_gemv_r.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j; INDEX lenX, lenY; const int Trans = (TransA != CblasConjTrans) ? TransA : CblasTrans; if (M == 0 || N == 0) return; if (alpha == 0.0 && beta == 1.0) return; if (Trans == CblasNoTrans) { lenX = N; lenY = M; } else { lenX = M; lenY = N; } /* form y := beta*y */ if (beta == 0.0) { INDEX iy = OFFSET(lenY, incY); for (i = 0; i < lenY; i++) { Y[iy] = 0.0; iy += incY; } } else if (beta != 1.0) { INDEX iy = OFFSET(lenY, incY); for (i = 0; i < lenY; i++) { Y[iy] *= beta; iy += incY; } } if (alpha == 0.0) return; if ((order == CblasRowMajor && Trans == CblasNoTrans) || (order == CblasColMajor && Trans == CblasTrans)) { /* form y := alpha*A*x + y */ INDEX iy = OFFSET(lenY, incY); for (i = 0; i < lenY; i++) { BASE temp = 0.0; INDEX ix = OFFSET(lenX, incX); for (j = 0; j < lenX; j++) { temp += X[ix] * A[lda * i + j]; ix += incX; } Y[iy] += alpha * temp; iy += incY; } } else if ((order == CblasRowMajor && Trans == CblasTrans) || (order == CblasColMajor && Trans == CblasNoTrans)) { /* form y := alpha*A'*x + y */ INDEX ix = OFFSET(lenX, incX); for (j = 0; j < lenX; j++) { const BASE temp = alpha * X[ix]; if (temp != 0.0) { INDEX iy = OFFSET(lenY, incY); for (i = 0; i < lenY; i++) { Y[iy] += temp * A[lda * j + i]; iy += incY; } } ix += incX; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_ger.h000066400000000000000000000027041261542461700220100ustar00rootroot00000000000000/* blas/source_ger.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j; if (order == CblasRowMajor) { INDEX ix = OFFSET(M, incX); for (i = 0; i < M; i++) { const BASE tmp = alpha * X[ix]; INDEX jy = OFFSET(N, incY); for (j = 0; j < N; j++) { A[lda * i + j] += Y[jy] * tmp; jy += incY; } ix += incX; } } else if (order == CblasColMajor) { INDEX jy = OFFSET(N, incY); for (j = 0; j < N; j++) { const BASE tmp = alpha * Y[jy]; INDEX ix = OFFSET(M, incX); for (i = 0; i < M; i++) { A[i + lda * j] += X[ix] * tmp; ix += incX; } jy += incY; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_gerc.h000066400000000000000000000044621261542461700221560ustar00rootroot00000000000000/* blas/source_gerc.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j; const BASE alpha_real = CONST_REAL0(alpha); const BASE alpha_imag = CONST_IMAG0(alpha); if (order == CblasRowMajor) { INDEX ix = OFFSET(M, incX); for (i = 0; i < M; i++) { const BASE X_real = CONST_REAL(X, ix); const BASE X_imag = CONST_IMAG(X, ix); const BASE tmp_real = alpha_real * X_real - alpha_imag * X_imag; const BASE tmp_imag = alpha_imag * X_real + alpha_real * X_imag; INDEX jy = OFFSET(N, incY); for (j = 0; j < N; j++) { const BASE Y_real = CONST_REAL(Y, jy); const BASE Y_imag = -CONST_IMAG(Y, jy); REAL(A, lda * i + j) += Y_real * tmp_real - Y_imag * tmp_imag; IMAG(A, lda * i + j) += Y_imag * tmp_real + Y_real * tmp_imag; jy += incY; } ix += incX; } } else if (order == CblasColMajor) { INDEX jy = OFFSET(N, incY); for (j = 0; j < N; j++) { const BASE Y_real = CONST_REAL(Y, jy); const BASE Y_imag = -CONST_IMAG(Y, jy); const BASE tmp_real = alpha_real * Y_real - alpha_imag * Y_imag; const BASE tmp_imag = alpha_imag * Y_real + alpha_real * Y_imag; INDEX ix = OFFSET(M, incX); for (i = 0; i < M; i++) { const BASE X_real = CONST_REAL(X, ix); const BASE X_imag = CONST_IMAG(X, ix); REAL(A, i + lda * j) += X_real * tmp_real - X_imag * tmp_imag; IMAG(A, i + lda * j) += X_imag * tmp_real + X_real * tmp_imag; ix += incX; } jy += incY; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_geru.h000066400000000000000000000044571261542461700222040ustar00rootroot00000000000000/* blas/source_geru.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j; const BASE alpha_real = CONST_REAL0(alpha); const BASE alpha_imag = CONST_IMAG0(alpha); if (order == CblasRowMajor) { INDEX ix = OFFSET(M, incX); for (i = 0; i < M; i++) { const BASE X_real = CONST_REAL(X, ix); const BASE X_imag = CONST_IMAG(X, ix); const BASE tmp_real = alpha_real * X_real - alpha_imag * X_imag; const BASE tmp_imag = alpha_imag * X_real + alpha_real * X_imag; INDEX jy = OFFSET(N, incY); for (j = 0; j < N; j++) { const BASE Y_real = CONST_REAL(Y, jy); const BASE Y_imag = CONST_IMAG(Y, jy); REAL(A, lda * i + j) += Y_real * tmp_real - Y_imag * tmp_imag; IMAG(A, lda * i + j) += Y_imag * tmp_real + Y_real * tmp_imag; jy += incY; } ix += incX; } } else if (order == CblasColMajor) { INDEX jy = OFFSET(N, incY); for (j = 0; j < N; j++) { const BASE Y_real = CONST_REAL(Y, jy); const BASE Y_imag = CONST_IMAG(Y, jy); const BASE tmp_real = alpha_real * Y_real - alpha_imag * Y_imag; const BASE tmp_imag = alpha_imag * Y_real + alpha_real * Y_imag; INDEX ix = OFFSET(M, incX); for (i = 0; i < M; i++) { const BASE X_real = CONST_REAL(X, ix); const BASE X_imag = CONST_IMAG(X, ix); REAL(A, i + lda * j) += X_real * tmp_real - X_imag * tmp_imag; IMAG(A, i + lda * j) += X_imag * tmp_real + X_real * tmp_imag; ix += incX; } jy += incY; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_hbmv.h000066400000000000000000000120211261542461700221600ustar00rootroot00000000000000/* blas/source_hbmv.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j; const int conj = (order == CblasColMajor) ? -1 : 1; const BASE alpha_real = CONST_REAL0(alpha); const BASE alpha_imag = CONST_IMAG0(alpha); const BASE beta_real = CONST_REAL0(beta); const BASE beta_imag = CONST_IMAG0(beta); if (N == 0) return; if ((alpha_real == 0.0 && alpha_imag == 0.0) && (beta_real == 1.0 && beta_imag == 0.0)) return; /* form y := beta*y */ if (beta_real == 0.0 && beta_imag == 0.0) { INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { REAL(Y, iy) = 0.0; IMAG(Y, iy) = 0.0; iy += incY; } } else if (!(beta_real == 1.0 && beta_imag == 0.0)) { INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { const BASE y_real = REAL(Y, iy); const BASE y_imag = IMAG(Y, iy); const BASE tmpR = y_real * beta_real - y_imag * beta_imag; const BASE tmpI = y_real * beta_imag + y_imag * beta_real; REAL(Y, iy) = tmpR; IMAG(Y, iy) = tmpI; iy += incY; } } if (alpha_real == 0.0 && alpha_imag == 0.0) return; /* form y := alpha*A*x + y */ if ((order == CblasRowMajor && Uplo == CblasUpper) || (order == CblasColMajor && Uplo == CblasLower)) { INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { BASE x_real = CONST_REAL(X, ix); BASE x_imag = CONST_IMAG(X, ix); BASE temp1_real = alpha_real * x_real - alpha_imag * x_imag; BASE temp1_imag = alpha_real * x_imag + alpha_imag * x_real; BASE temp2_real = 0.0; BASE temp2_imag = 0.0; const INDEX j_min = i + 1; const INDEX j_max = GSL_MIN(N, i + K + 1); INDEX jx = OFFSET(N, incX) + j_min * incX; INDEX jy = OFFSET(N, incY) + j_min * incY; BASE Aii_real = CONST_REAL(A, lda * i + 0); /* Aii_imag is zero */ REAL(Y, iy) += temp1_real * Aii_real; IMAG(Y, iy) += temp1_imag * Aii_real; for (j = j_min; j < j_max; j++) { BASE Aij_real = CONST_REAL(A, lda * i + (j - i)); BASE Aij_imag = conj * CONST_IMAG(A, lda * i + (j - i)); REAL(Y, jy) += temp1_real * Aij_real - temp1_imag * (-Aij_imag); IMAG(Y, jy) += temp1_real * (-Aij_imag) + temp1_imag * Aij_real; x_real = CONST_REAL(X, jx); x_imag = CONST_IMAG(X, jx); temp2_real += x_real * Aij_real - x_imag * Aij_imag; temp2_imag += x_real * Aij_imag + x_imag * Aij_real; jx += incX; jy += incY; } REAL(Y, iy) += alpha_real * temp2_real - alpha_imag * temp2_imag; IMAG(Y, iy) += alpha_real * temp2_imag + alpha_imag * temp2_real; ix += incX; iy += incY; } } else if ((order == CblasRowMajor && Uplo == CblasLower) || (order == CblasColMajor && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { BASE x_real = CONST_REAL(X, ix); BASE x_imag = CONST_IMAG(X, ix); BASE temp1_real = alpha_real * x_real - alpha_imag * x_imag; BASE temp1_imag = alpha_real * x_imag + alpha_imag * x_real; BASE temp2_real = 0.0; BASE temp2_imag = 0.0; const INDEX j_min = (K > i ? 0 : i - K); const INDEX j_max = i; INDEX jx = OFFSET(N, incX) + j_min * incX; INDEX jy = OFFSET(N, incY) + j_min * incY; for (j = j_min; j < j_max; j++) { BASE Aij_real = CONST_REAL(A, i * lda + (K - i + j)); BASE Aij_imag = conj * CONST_IMAG(A, i * lda + (K - i + j)); REAL(Y, jy) += temp1_real * Aij_real - temp1_imag * (-Aij_imag); IMAG(Y, jy) += temp1_real * (-Aij_imag) + temp1_imag * Aij_real; x_real = CONST_REAL(X, jx); x_imag = CONST_IMAG(X, jx); temp2_real += x_real * Aij_real - x_imag * Aij_imag; temp2_imag += x_real * Aij_imag + x_imag * Aij_real; jx += incX; jy += incY; } { BASE Aii_real = CONST_REAL(A, lda * i + K); /* Aii_imag is zero */ REAL(Y, iy) += temp1_real * Aii_real; IMAG(Y, iy) += temp1_imag * Aii_real; } REAL(Y, iy) += alpha_real * temp2_real - alpha_imag * temp2_imag; IMAG(Y, iy) += alpha_real * temp2_imag + alpha_imag * temp2_real; ix += incX; iy += incY; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_hemm.h000066400000000000000000000176621261542461700221720ustar00rootroot00000000000000/* blas/source_hemm.h * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j, k; INDEX n1, n2; int uplo, side; const BASE alpha_real = CONST_REAL0(alpha); const BASE alpha_imag = CONST_IMAG0(alpha); const BASE beta_real = CONST_REAL0(beta); const BASE beta_imag = CONST_IMAG0(beta); if ((alpha_real == 0.0 && alpha_imag == 0.0) && (beta_real == 1.0 && beta_imag == 0.0)) return; if (Order == CblasRowMajor) { n1 = M; n2 = N; uplo = Uplo; side = Side; } else { n1 = N; n2 = M; uplo = (Uplo == CblasUpper) ? CblasLower : CblasUpper; side = (Side == CblasLeft) ? CblasRight : CblasLeft; } /* form y := beta*y */ if (beta_real == 0.0 && beta_imag == 0.0) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { REAL(C, ldc * i + j) = 0.0; IMAG(C, ldc * i + j) = 0.0; } } } else if (!(beta_real == 1.0 && beta_imag == 0.0)) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { const BASE Cij_real = REAL(C, ldc * i + j); const BASE Cij_imag = IMAG(C, ldc * i + j); REAL(C, ldc * i + j) = beta_real * Cij_real - beta_imag * Cij_imag; IMAG(C, ldc * i + j) = beta_real * Cij_imag + beta_imag * Cij_real; } } } if (alpha_real == 0.0 && alpha_imag == 0.0) return; if (side == CblasLeft && uplo == CblasUpper) { /* form C := alpha*A*B + C */ for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { const BASE Bij_real = CONST_REAL(B, ldb * i + j); const BASE Bij_imag = CONST_IMAG(B, ldb * i + j); const BASE temp1_real = alpha_real * Bij_real - alpha_imag * Bij_imag; const BASE temp1_imag = alpha_real * Bij_imag + alpha_imag * Bij_real; BASE temp2_real = 0.0; BASE temp2_imag = 0.0; { const BASE Aii_real = CONST_REAL(A, i * lda + i); /* const BASE Aii_imag = 0.0; */ REAL(C, i * ldc + j) += temp1_real * Aii_real; IMAG(C, i * ldc + j) += temp1_imag * Aii_real; } for (k = i + 1; k < n1; k++) { const BASE Aik_real = CONST_REAL(A, i * lda + k); const BASE Aik_imag = CONST_IMAG(A, i * lda + k); const BASE Bkj_real = CONST_REAL(B, ldb * k + j); const BASE Bkj_imag = CONST_IMAG(B, ldb * k + j); REAL(C, k * ldc + j) += Aik_real * temp1_real - (-Aik_imag) * temp1_imag; IMAG(C, k * ldc + j) += Aik_real * temp1_imag + (-Aik_imag) * temp1_real; temp2_real += Aik_real * Bkj_real - Aik_imag * Bkj_imag; temp2_imag += Aik_real * Bkj_imag + Aik_imag * Bkj_real; } REAL(C, i * ldc + j) += alpha_real * temp2_real - alpha_imag * temp2_imag; IMAG(C, i * ldc + j) += alpha_real * temp2_imag + alpha_imag * temp2_real; } } } else if (side == CblasLeft && uplo == CblasLower) { /* form C := alpha*A*B + C */ for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { const BASE Bij_real = CONST_REAL(B, ldb * i + j); const BASE Bij_imag = CONST_IMAG(B, ldb * i + j); const BASE temp1_real = alpha_real * Bij_real - alpha_imag * Bij_imag; const BASE temp1_imag = alpha_real * Bij_imag + alpha_imag * Bij_real; BASE temp2_real = 0.0; BASE temp2_imag = 0.0; for (k = 0; k < i; k++) { const BASE Aik_real = CONST_REAL(A, i * lda + k); const BASE Aik_imag = CONST_IMAG(A, i * lda + k); const BASE Bkj_real = CONST_REAL(B, ldb * k + j); const BASE Bkj_imag = CONST_IMAG(B, ldb * k + j); REAL(C, k * ldc + j) += Aik_real * temp1_real - (-Aik_imag) * temp1_imag; IMAG(C, k * ldc + j) += Aik_real * temp1_imag + (-Aik_imag) * temp1_real; temp2_real += Aik_real * Bkj_real - Aik_imag * Bkj_imag; temp2_imag += Aik_real * Bkj_imag + Aik_imag * Bkj_real; } { const BASE Aii_real = CONST_REAL(A, i * lda + i); /* const BASE Aii_imag = 0.0; */ REAL(C, i * ldc + j) += temp1_real * Aii_real; IMAG(C, i * ldc + j) += temp1_imag * Aii_real; } REAL(C, i * ldc + j) += alpha_real * temp2_real - alpha_imag * temp2_imag; IMAG(C, i * ldc + j) += alpha_real * temp2_imag + alpha_imag * temp2_real; } } } else if (side == CblasRight && uplo == CblasUpper) { /* form C := alpha*B*A + C */ for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { const BASE Bij_real = CONST_REAL(B, ldb * i + j); const BASE Bij_imag = CONST_IMAG(B, ldb * i + j); const BASE temp1_real = alpha_real * Bij_real - alpha_imag * Bij_imag; const BASE temp1_imag = alpha_real * Bij_imag + alpha_imag * Bij_real; BASE temp2_real = 0.0; BASE temp2_imag = 0.0; { const BASE Ajj_real = CONST_REAL(A, j * lda + j); /* const BASE Ajj_imag = 0.0; */ REAL(C, i * ldc + j) += temp1_real * Ajj_real; IMAG(C, i * ldc + j) += temp1_imag * Ajj_real; } for (k = j + 1; k < n2; k++) { const BASE Ajk_real = CONST_REAL(A, j * lda + k); const BASE Ajk_imag = CONST_IMAG(A, j * lda + k); const BASE Bik_real = CONST_REAL(B, ldb * i + k); const BASE Bik_imag = CONST_IMAG(B, ldb * i + k); REAL(C, i * ldc + k) += temp1_real * Ajk_real - temp1_imag * Ajk_imag; IMAG(C, i * ldc + k) += temp1_real * Ajk_imag + temp1_imag * Ajk_real; temp2_real += Bik_real * Ajk_real - Bik_imag * (-Ajk_imag); temp2_imag += Bik_real * (-Ajk_imag) + Bik_imag * Ajk_real; } REAL(C, i * ldc + j) += alpha_real * temp2_real - alpha_imag * temp2_imag; IMAG(C, i * ldc + j) += alpha_real * temp2_imag + alpha_imag * temp2_real; } } } else if (side == CblasRight && uplo == CblasLower) { /* form C := alpha*B*A + C */ for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { const BASE Bij_real = CONST_REAL(B, ldb * i + j); const BASE Bij_imag = CONST_IMAG(B, ldb * i + j); const BASE temp1_real = alpha_real * Bij_real - alpha_imag * Bij_imag; const BASE temp1_imag = alpha_real * Bij_imag + alpha_imag * Bij_real; BASE temp2_real = 0.0; BASE temp2_imag = 0.0; for (k = 0; k < j; k++) { const BASE Ajk_real = CONST_REAL(A, j * lda + k); const BASE Ajk_imag = CONST_IMAG(A, j * lda + k); const BASE Bik_real = CONST_REAL(B, ldb * i + k); const BASE Bik_imag = CONST_IMAG(B, ldb * i + k); REAL(C, i * ldc + k) += temp1_real * Ajk_real - temp1_imag * Ajk_imag; IMAG(C, i * ldc + k) += temp1_real * Ajk_imag + temp1_imag * Ajk_real; temp2_real += Bik_real * Ajk_real - Bik_imag * (-Ajk_imag); temp2_imag += Bik_real * (-Ajk_imag) + Bik_imag * Ajk_real; } { const BASE Ajj_real = CONST_REAL(A, j * lda + j); /* const BASE Ajj_imag = 0.0; */ REAL(C, i * ldc + j) += temp1_real * Ajj_real; IMAG(C, i * ldc + j) += temp1_imag * Ajj_real; } REAL(C, i * ldc + j) += alpha_real * temp2_real - alpha_imag * temp2_imag; IMAG(C, i * ldc + j) += alpha_real * temp2_imag + alpha_imag * temp2_real; } } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_hemv.h000066400000000000000000000116441261542461700221750ustar00rootroot00000000000000/* blas/source_hemv.h * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { const int conj = (order == CblasColMajor) ? -1 : 1; INDEX i, j; const BASE alpha_real = CONST_REAL0(alpha); const BASE alpha_imag = CONST_IMAG0(alpha); const BASE beta_real = CONST_REAL0(beta); const BASE beta_imag = CONST_IMAG0(beta); if ((alpha_real == 0.0 && alpha_imag == 0.0) && (beta_real == 1.0 && beta_imag == 0.0)) return; /* form y := beta*y */ if (beta_real == 0.0 && beta_imag == 0.0) { INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { REAL(Y, iy) = 0.0; IMAG(Y, iy) = 0.0; iy += incY; } } else if (!(beta_real == 1.0 && beta_imag == 0.0)) { INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { const BASE y_real = REAL(Y, iy); const BASE y_imag = IMAG(Y, iy); const BASE tmpR = y_real * beta_real - y_imag * beta_imag; const BASE tmpI = y_real * beta_imag + y_imag * beta_real; REAL(Y, iy) = tmpR; IMAG(Y, iy) = tmpI; iy += incY; } } if (alpha_real == 0.0 && alpha_imag == 0.0) return; /* form y := alpha*A*x + y */ if ((order == CblasRowMajor && Uplo == CblasUpper) || (order == CblasColMajor && Uplo == CblasLower)) { INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { BASE x_real = CONST_REAL(X, ix); BASE x_imag = CONST_IMAG(X, ix); BASE temp1_real = alpha_real * x_real - alpha_imag * x_imag; BASE temp1_imag = alpha_real * x_imag + alpha_imag * x_real; BASE temp2_real = 0.0; BASE temp2_imag = 0.0; const INDEX j_min = i + 1; const INDEX j_max = N; INDEX jx = OFFSET(N, incX) + j_min * incX; INDEX jy = OFFSET(N, incY) + j_min * incY; BASE Aii_real = CONST_REAL(A, lda * i + i); /* Aii_imag is zero */ REAL(Y, iy) += temp1_real * Aii_real; IMAG(Y, iy) += temp1_imag * Aii_real; for (j = j_min; j < j_max; j++) { BASE Aij_real = CONST_REAL(A, lda * i + j); BASE Aij_imag = conj * CONST_IMAG(A, lda * i + j); REAL(Y, jy) += temp1_real * Aij_real - temp1_imag * (-Aij_imag); IMAG(Y, jy) += temp1_real * (-Aij_imag) + temp1_imag * Aij_real; x_real = CONST_REAL(X, jx); x_imag = CONST_IMAG(X, jx); temp2_real += x_real * Aij_real - x_imag * Aij_imag; temp2_imag += x_real * Aij_imag + x_imag * Aij_real; jx += incX; jy += incY; } REAL(Y, iy) += alpha_real * temp2_real - alpha_imag * temp2_imag; IMAG(Y, iy) += alpha_real * temp2_imag + alpha_imag * temp2_real; ix += incX; iy += incY; } } else if ((order == CblasRowMajor && Uplo == CblasLower) || (order == CblasColMajor && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX) + (N - 1) * incX; INDEX iy = OFFSET(N, incY) + (N - 1) * incY; for (i = N; i > 0 && i--;) { BASE x_real = CONST_REAL(X, ix); BASE x_imag = CONST_IMAG(X, ix); BASE temp1_real = alpha_real * x_real - alpha_imag * x_imag; BASE temp1_imag = alpha_real * x_imag + alpha_imag * x_real; BASE temp2_real = 0.0; BASE temp2_imag = 0.0; const INDEX j_min = 0; const INDEX j_max = i; INDEX jx = OFFSET(N, incX) + j_min * incX; INDEX jy = OFFSET(N, incY) + j_min * incY; BASE Aii_real = CONST_REAL(A, lda * i + i); /* Aii_imag is zero */ REAL(Y, iy) += temp1_real * Aii_real; IMAG(Y, iy) += temp1_imag * Aii_real; for (j = j_min; j < j_max; j++) { BASE Aij_real = CONST_REAL(A, lda * i + j); BASE Aij_imag = conj * CONST_IMAG(A, lda * i + j); REAL(Y, jy) += temp1_real * Aij_real - temp1_imag * (-Aij_imag); IMAG(Y, jy) += temp1_real * (-Aij_imag) + temp1_imag * Aij_real; x_real = CONST_REAL(X, jx); x_imag = CONST_IMAG(X, jx); temp2_real += x_real * Aij_real - x_imag * Aij_imag; temp2_imag += x_real * Aij_imag + x_imag * Aij_real; jx += incX; jy += incY; } REAL(Y, iy) += alpha_real * temp2_real - alpha_imag * temp2_imag; IMAG(Y, iy) += alpha_real * temp2_imag + alpha_imag * temp2_real; ix -= incX; iy -= incY; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_her.h000066400000000000000000000053331261542461700220120ustar00rootroot00000000000000/* blas/source_her.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { const int conj = (order == CblasColMajor) ? -1 : 1; INDEX i, j; if (alpha == 0.0) return; if ((order == CblasRowMajor && Uplo == CblasUpper) || (order == CblasColMajor && Uplo == CblasLower)) { INDEX ix = OFFSET(N, incX); for (i = 0; i < N; i++) { const BASE tmp_real = alpha * CONST_REAL(X, ix); const BASE tmp_imag = alpha * conj * CONST_IMAG(X, ix); INDEX jx = ix; { const BASE X_real = CONST_REAL(X, jx); const BASE X_imag = -conj * CONST_IMAG(X, jx); REAL(A, lda * i + i) += X_real * tmp_real - X_imag * tmp_imag; IMAG(A, lda * i + i) = 0; jx += incX; } for (j = i + 1; j < N; j++) { const BASE X_real = CONST_REAL(X, jx); const BASE X_imag = -conj * CONST_IMAG(X, jx); REAL(A, lda * i + j) += X_real * tmp_real - X_imag * tmp_imag; IMAG(A, lda * i + j) += X_imag * tmp_real + X_real * tmp_imag; jx += incX; } ix += incX; } } else if ((order == CblasRowMajor && Uplo == CblasLower) || (order == CblasColMajor && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX); for (i = 0; i < N; i++) { const BASE tmp_real = alpha * CONST_REAL(X, ix); const BASE tmp_imag = alpha * conj * CONST_IMAG(X, ix); INDEX jx = OFFSET(N, incX); for (j = 0; j < i; j++) { const BASE X_real = CONST_REAL(X, jx); const BASE X_imag = -conj * CONST_IMAG(X, jx); REAL(A, lda * i + j) += X_real * tmp_real - X_imag * tmp_imag; IMAG(A, lda * i + j) += X_imag * tmp_real + X_real * tmp_imag; jx += incX; } { const BASE X_real = CONST_REAL(X, jx); const BASE X_imag = -conj * CONST_IMAG(X, jx); REAL(A, lda * i + i) += X_real * tmp_real - X_imag * tmp_imag; IMAG(A, lda * i + i) = 0; jx += incX; } ix += incX; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_her2.h000066400000000000000000000103221261542461700220660ustar00rootroot00000000000000/* blas/source_her2.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { const int conj = (order == CblasColMajor) ? -1 : 1; INDEX i, j; const BASE alpha_real = CONST_REAL0(alpha); const BASE alpha_imag = CONST_IMAG0(alpha); if (alpha_real == 0.0 && alpha_imag == 0.0) return; if ((order == CblasRowMajor && Uplo == CblasUpper) || (order == CblasColMajor && Uplo == CblasLower)) { INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { const BASE Xi_real = CONST_REAL(X, ix); const BASE Xi_imag = CONST_IMAG(X, ix); /* tmp1 = alpha Xi */ const BASE tmp1_real = alpha_real * Xi_real - alpha_imag * Xi_imag; const BASE tmp1_imag = alpha_imag * Xi_real + alpha_real * Xi_imag; const BASE Yi_real = CONST_REAL(Y, iy); const BASE Yi_imag = CONST_IMAG(Y, iy); /* tmp2 = conj(alpha) Yi */ const BASE tmp2_real = alpha_real * Yi_real + alpha_imag * Yi_imag; const BASE tmp2_imag = -alpha_imag * Yi_real + alpha_real * Yi_imag; INDEX jx = ix + incX; INDEX jy = iy + incY; /* Aij = alpha*Xi*conj(Yj) + conj(alpha)*Yi*conj(Xj) */ REAL(A, lda * i + i) += 2 * (tmp1_real * Yi_real + tmp1_imag * Yi_imag); IMAG(A, lda * i + i) = 0; for (j = i + 1; j < N; j++) { const BASE Xj_real = CONST_REAL(X, jx); const BASE Xj_imag = CONST_IMAG(X, jx); const BASE Yj_real = CONST_REAL(Y, jy); const BASE Yj_imag = CONST_IMAG(Y, jy); REAL(A, lda * i + j) += ((tmp1_real * Yj_real + tmp1_imag * Yj_imag) + (tmp2_real * Xj_real + tmp2_imag * Xj_imag)); IMAG(A, lda * i + j) += conj * ((tmp1_imag * Yj_real - tmp1_real * Yj_imag) + (tmp2_imag * Xj_real - tmp2_real * Xj_imag)); jx += incX; jy += incY; } ix += incX; iy += incY; } } else if ((order == CblasRowMajor && Uplo == CblasLower) || (order == CblasColMajor && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { const BASE Xi_real = CONST_REAL(X, ix); const BASE Xi_imag = CONST_IMAG(X, ix); const BASE tmp1_real = alpha_real * Xi_real - alpha_imag * Xi_imag; const BASE tmp1_imag = alpha_imag * Xi_real + alpha_real * Xi_imag; const BASE Yi_real = CONST_REAL(Y, iy); const BASE Yi_imag = CONST_IMAG(Y, iy); const BASE tmp2_real = alpha_real * Yi_real + alpha_imag * Yi_imag; const BASE tmp2_imag = -alpha_imag * Yi_real + alpha_real * Yi_imag; INDEX jx = OFFSET(N, incX); INDEX jy = OFFSET(N, incY); /* Aij = alpha*Xi*conj(Yj) + conj(alpha)*Yi*conj(Xj) */ for (j = 0; j < i; j++) { const BASE Xj_real = CONST_REAL(X, jx); const BASE Xj_imag = CONST_IMAG(X, jx); const BASE Yj_real = CONST_REAL(Y, jy); const BASE Yj_imag = CONST_IMAG(Y, jy); REAL(A, lda * i + j) += ((tmp1_real * Yj_real + tmp1_imag * Yj_imag) + (tmp2_real * Xj_real + tmp2_imag * Xj_imag)); IMAG(A, lda * i + j) += conj * ((tmp1_imag * Yj_real - tmp1_real * Yj_imag) + (tmp2_imag * Xj_real - tmp2_real * Xj_imag)); jx += incX; jy += incY; } REAL(A, lda * i + i) += 2 * (tmp1_real * Yi_real + tmp1_imag * Yi_imag); IMAG(A, lda * i + i) = 0; ix += incX; iy += incY; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_her2k.h000066400000000000000000000244341261542461700222520ustar00rootroot00000000000000/* blas/source_her2k_c.h * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j, k; int uplo, trans; const BASE alpha_real = CONST_REAL0(alpha); BASE alpha_imag = CONST_IMAG0(alpha); if (beta == 1.0 && ((alpha_real == 0.0 && alpha_imag == 0.0) || K == 0)) return; if (Order == CblasRowMajor) { uplo = Uplo; trans = Trans; } else { uplo = (Uplo == CblasUpper) ? CblasLower : CblasUpper; trans = (Trans == CblasNoTrans) ? CblasConjTrans : CblasNoTrans; alpha_imag *= -1; /* conjugate alpha */ } /* form C := beta*C */ if (beta == 0.0) { if (uplo == CblasUpper) { for (i = 0; i < N; i++) { for (j = i; j < N; j++) { REAL(C, ldc * i + j) = 0.0; IMAG(C, ldc * i + j) = 0.0; } } } else { for (i = 0; i < N; i++) { for (j = 0; j <= i; j++) { REAL(C, ldc * i + j) = 0.0; IMAG(C, ldc * i + j) = 0.0; } } } } else if (beta != 1.0) { if (uplo == CblasUpper) { for (i = 0; i < N; i++) { REAL(C, ldc * i + i) *= beta; IMAG(C, ldc * i + i) = 0.0; for (j = i + 1; j < N; j++) { REAL(C, ldc * i + j) *= beta; IMAG(C, ldc * i + j) *= beta; } } } else { for (i = 0; i < N; i++) { for (j = 0; j < i; j++) { REAL(C, ldc * i + j) *= beta; IMAG(C, ldc * i + j) *= beta; } REAL(C, ldc * i + i) *= beta; IMAG(C, ldc * i + i) = 0.0; } } } else { for (i = 0; i < N; i++) { IMAG(C, ldc * i + i) = 0.0; } } if (alpha_real == 0.0 && alpha_imag == 0.0) return; if (uplo == CblasUpper && trans == CblasNoTrans) { for (i = 0; i < N; i++) { /* Cii += alpha Aik conj(Bik) + conj(alpha) Bik conj(Aik) */ { BASE temp_real = 0.0; /* BASE temp_imag = 0.0; */ for (k = 0; k < K; k++) { const BASE Aik_real = CONST_REAL(A, i * lda + k); const BASE Aik_imag = CONST_IMAG(A, i * lda + k); /* temp1 = alpha * Aik */ const BASE temp1_real = alpha_real * Aik_real - alpha_imag * Aik_imag; const BASE temp1_imag = alpha_real * Aik_imag + alpha_imag * Aik_real; const BASE Bik_real = CONST_REAL(B, i * ldb + k); const BASE Bik_imag = CONST_IMAG(B, i * ldb + k); temp_real += temp1_real * Bik_real + temp1_imag * Bik_imag; } REAL(C, i * ldc + i) += 2 * temp_real; IMAG(C, i * ldc + i) = 0.0; } /* Cij += alpha Aik conj(Bjk) + conj(alpha) Bik conj(Ajk) */ for (j = i + 1; j < N; j++) { BASE temp_real = 0.0; BASE temp_imag = 0.0; for (k = 0; k < K; k++) { const BASE Aik_real = CONST_REAL(A, i * lda + k); const BASE Aik_imag = CONST_IMAG(A, i * lda + k); /* temp1 = alpha * Aik */ const BASE temp1_real = alpha_real * Aik_real - alpha_imag * Aik_imag; const BASE temp1_imag = alpha_real * Aik_imag + alpha_imag * Aik_real; const BASE Bik_real = CONST_REAL(B, i * ldb + k); const BASE Bik_imag = CONST_IMAG(B, i * ldb + k); const BASE Ajk_real = CONST_REAL(A, j * lda + k); const BASE Ajk_imag = CONST_IMAG(A, j * lda + k); /* temp2 = alpha * Ajk */ const BASE temp2_real = alpha_real * Ajk_real - alpha_imag * Ajk_imag; const BASE temp2_imag = alpha_real * Ajk_imag + alpha_imag * Ajk_real; const BASE Bjk_real = CONST_REAL(B, j * ldb + k); const BASE Bjk_imag = CONST_IMAG(B, j * ldb + k); /* Cij += alpha * Aik * conj(Bjk) + conj(alpha) * Bik * conj(Ajk) */ temp_real += ((temp1_real * Bjk_real + temp1_imag * Bjk_imag) + (Bik_real * temp2_real + Bik_imag * temp2_imag)); temp_imag += ((temp1_real * (-Bjk_imag) + temp1_imag * Bjk_real) + (Bik_real * (-temp2_imag) + Bik_imag * temp2_real)); } REAL(C, i * ldc + j) += temp_real; IMAG(C, i * ldc + j) += temp_imag; } } } else if (uplo == CblasUpper && trans == CblasConjTrans) { for (k = 0; k < K; k++) { for (i = 0; i < N; i++) { BASE Aki_real = CONST_REAL(A, k * lda + i); BASE Aki_imag = CONST_IMAG(A, k * lda + i); BASE Bki_real = CONST_REAL(B, k * ldb + i); BASE Bki_imag = CONST_IMAG(B, k * ldb + i); /* temp1 = alpha * conj(Aki) */ BASE temp1_real = alpha_real * Aki_real - alpha_imag * (-Aki_imag); BASE temp1_imag = alpha_real * (-Aki_imag) + alpha_imag * Aki_real; /* temp2 = conj(alpha) * conj(Bki) */ BASE temp2_real = alpha_real * Bki_real - alpha_imag * Bki_imag; BASE temp2_imag = -(alpha_real * Bki_imag + alpha_imag * Bki_real); /* Cii += alpha * conj(Aki) * Bki + conj(alpha) * conj(Bki) * Aki */ { REAL(C, i * lda + i) += 2 * (temp1_real * Bki_real - temp1_imag * Bki_imag); IMAG(C, i * lda + i) = 0.0; } for (j = i + 1; j < N; j++) { BASE Akj_real = CONST_REAL(A, k * lda + j); BASE Akj_imag = CONST_IMAG(A, k * lda + j); BASE Bkj_real = CONST_REAL(B, k * ldb + j); BASE Bkj_imag = CONST_IMAG(B, k * ldb + j); /* Cij += alpha * conj(Aki) * Bkj + conj(alpha) * conj(Bki) * Akj */ REAL(C, i * lda + j) += (temp1_real * Bkj_real - temp1_imag * Bkj_imag) + (temp2_real * Akj_real - temp2_imag * Akj_imag); IMAG(C, i * lda + j) += (temp1_real * Bkj_imag + temp1_imag * Bkj_real) + (temp2_real * Akj_imag + temp2_imag * Akj_real); } } } } else if (uplo == CblasLower && trans == CblasNoTrans) { for (i = 0; i < N; i++) { /* Cij += alpha Aik conj(Bjk) + conj(alpha) Bik conj(Ajk) */ for (j = 0; j < i; j++) { BASE temp_real = 0.0; BASE temp_imag = 0.0; for (k = 0; k < K; k++) { const BASE Aik_real = CONST_REAL(A, i * lda + k); const BASE Aik_imag = CONST_IMAG(A, i * lda + k); /* temp1 = alpha * Aik */ const BASE temp1_real = alpha_real * Aik_real - alpha_imag * Aik_imag; const BASE temp1_imag = alpha_real * Aik_imag + alpha_imag * Aik_real; const BASE Bik_real = CONST_REAL(B, i * ldb + k); const BASE Bik_imag = CONST_IMAG(B, i * ldb + k); const BASE Ajk_real = CONST_REAL(A, j * lda + k); const BASE Ajk_imag = CONST_IMAG(A, j * lda + k); /* temp2 = alpha * Ajk */ const BASE temp2_real = alpha_real * Ajk_real - alpha_imag * Ajk_imag; const BASE temp2_imag = alpha_real * Ajk_imag + alpha_imag * Ajk_real; const BASE Bjk_real = CONST_REAL(B, j * ldb + k); const BASE Bjk_imag = CONST_IMAG(B, j * ldb + k); /* Cij += alpha * Aik * conj(Bjk) + conj(alpha) * Bik * conj(Ajk) */ temp_real += ((temp1_real * Bjk_real + temp1_imag * Bjk_imag) + (Bik_real * temp2_real + Bik_imag * temp2_imag)); temp_imag += ((temp1_real * (-Bjk_imag) + temp1_imag * Bjk_real) + (Bik_real * (-temp2_imag) + Bik_imag * temp2_real)); } REAL(C, i * ldc + j) += temp_real; IMAG(C, i * ldc + j) += temp_imag; } /* Cii += alpha Aik conj(Bik) + conj(alpha) Bik conj(Aik) */ { BASE temp_real = 0.0; /* BASE temp_imag = 0.0; */ for (k = 0; k < K; k++) { const BASE Aik_real = CONST_REAL(A, i * lda + k); const BASE Aik_imag = CONST_IMAG(A, i * lda + k); /* temp1 = alpha * Aik */ const BASE temp1_real = alpha_real * Aik_real - alpha_imag * Aik_imag; const BASE temp1_imag = alpha_real * Aik_imag + alpha_imag * Aik_real; const BASE Bik_real = CONST_REAL(B, i * ldb + k); const BASE Bik_imag = CONST_IMAG(B, i * ldb + k); temp_real += temp1_real * Bik_real + temp1_imag * Bik_imag; } REAL(C, i * ldc + i) += 2 * temp_real; IMAG(C, i * ldc + i) = 0.0; } } } else if (uplo == CblasLower && trans == CblasConjTrans) { for (k = 0; k < K; k++) { for (i = 0; i < N; i++) { BASE Aki_real = CONST_REAL(A, k * lda + i); BASE Aki_imag = CONST_IMAG(A, k * lda + i); BASE Bki_real = CONST_REAL(B, k * ldb + i); BASE Bki_imag = CONST_IMAG(B, k * ldb + i); /* temp1 = alpha * conj(Aki) */ BASE temp1_real = alpha_real * Aki_real - alpha_imag * (-Aki_imag); BASE temp1_imag = alpha_real * (-Aki_imag) + alpha_imag * Aki_real; /* temp2 = conj(alpha) * conj(Bki) */ BASE temp2_real = alpha_real * Bki_real - alpha_imag * Bki_imag; BASE temp2_imag = -(alpha_real * Bki_imag + alpha_imag * Bki_real); for (j = 0; j < i; j++) { BASE Akj_real = CONST_REAL(A, k * lda + j); BASE Akj_imag = CONST_IMAG(A, k * lda + j); BASE Bkj_real = CONST_REAL(B, k * ldb + j); BASE Bkj_imag = CONST_IMAG(B, k * ldb + j); /* Cij += alpha * conj(Aki) * Bkj + conj(alpha) * conj(Bki) * Akj */ REAL(C, i * lda + j) += (temp1_real * Bkj_real - temp1_imag * Bkj_imag) + (temp2_real * Akj_real - temp2_imag * Akj_imag); IMAG(C, i * lda + j) += (temp1_real * Bkj_imag + temp1_imag * Bkj_real) + (temp2_real * Akj_imag + temp2_imag * Akj_real); } /* Cii += alpha * conj(Aki) * Bki + conj(alpha) * conj(Bki) * Aki */ { REAL(C, i * lda + i) += 2 * (temp1_real * Bki_real - temp1_imag * Bki_imag); IMAG(C, i * lda + i) = 0.0; } } } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_herk.h000066400000000000000000000120551261542461700221640ustar00rootroot00000000000000/* blas/source_herk.h * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j, k; int uplo, trans; if (beta == 1.0 && (alpha == 0.0 || K == 0)) return; if (Order == CblasRowMajor) { uplo = Uplo; trans = Trans; } else { uplo = (Uplo == CblasUpper) ? CblasLower : CblasUpper; trans = (Trans == CblasNoTrans) ? CblasConjTrans : CblasNoTrans; } /* form y := beta*y */ if (beta == 0.0) { if (uplo == CblasUpper) { for (i = 0; i < N; i++) { for (j = i; j < N; j++) { REAL(C, ldc * i + j) = 0.0; IMAG(C, ldc * i + j) = 0.0; } } } else { for (i = 0; i < N; i++) { for (j = 0; j <= i; j++) { REAL(C, ldc * i + j) = 0.0; IMAG(C, ldc * i + j) = 0.0; } } } } else if (beta != 1.0) { if (uplo == CblasUpper) { for (i = 0; i < N; i++) { REAL(C, ldc * i + i) *= beta; IMAG(C, ldc * i + i) = 0; for (j = i + 1; j < N; j++) { REAL(C, ldc * i + j) *= beta; IMAG(C, ldc * i + j) *= beta; } } } else { for (i = 0; i < N; i++) { for (j = 0; j < i; j++) { REAL(C, ldc * i + j) *= beta; IMAG(C, ldc * i + j) *= beta; } REAL(C, ldc * i + i) *= beta; IMAG(C, ldc * i + i) = 0; } } } else { /* set imaginary part of Aii to zero */ for (i = 0; i < N; i++) { IMAG(C, ldc * i + i) = 0.0; } } if (alpha == 0.0) return; if (uplo == CblasUpper && trans == CblasNoTrans) { for (i = 0; i < N; i++) { for (j = i; j < N; j++) { BASE temp_real = 0.0; BASE temp_imag = 0.0; for (k = 0; k < K; k++) { const BASE Aik_real = CONST_REAL(A, i * lda + k); const BASE Aik_imag = CONST_IMAG(A, i * lda + k); const BASE Ajk_real = CONST_REAL(A, j * lda + k); const BASE Ajk_imag = -CONST_IMAG(A, j * lda + k); temp_real += Aik_real * Ajk_real - Aik_imag * Ajk_imag; temp_imag += Aik_real * Ajk_imag + Aik_imag * Ajk_real; } REAL(C, i * ldc + j) += alpha * temp_real; IMAG(C, i * ldc + j) += alpha * temp_imag; } } } else if (uplo == CblasUpper && trans == CblasConjTrans) { for (i = 0; i < N; i++) { for (j = i; j < N; j++) { BASE temp_real = 0.0; BASE temp_imag = 0.0; for (k = 0; k < K; k++) { const BASE Aki_real = CONST_REAL(A, k * lda + i); const BASE Aki_imag = -CONST_IMAG(A, k * lda + i); const BASE Akj_real = CONST_REAL(A, k * lda + j); const BASE Akj_imag = CONST_IMAG(A, k * lda + j); temp_real += Aki_real * Akj_real - Aki_imag * Akj_imag; temp_imag += Aki_real * Akj_imag + Aki_imag * Akj_real; } REAL(C, i * ldc + j) += alpha * temp_real; IMAG(C, i * ldc + j) += alpha * temp_imag; } } } else if (uplo == CblasLower && trans == CblasNoTrans) { for (i = 0; i < N; i++) { for (j = 0; j <= i; j++) { BASE temp_real = 0.0; BASE temp_imag = 0.0; for (k = 0; k < K; k++) { const BASE Aik_real = CONST_REAL(A, i * lda + k); const BASE Aik_imag = CONST_IMAG(A, i * lda + k); const BASE Ajk_real = CONST_REAL(A, j * lda + k); const BASE Ajk_imag = -CONST_IMAG(A, j * lda + k); temp_real += Aik_real * Ajk_real - Aik_imag * Ajk_imag; temp_imag += Aik_real * Ajk_imag + Aik_imag * Ajk_real; } REAL(C, i * ldc + j) += alpha * temp_real; IMAG(C, i * ldc + j) += alpha * temp_imag; } } } else if (uplo == CblasLower && trans == CblasConjTrans) { for (i = 0; i < N; i++) { for (j = 0; j <= i; j++) { BASE temp_real = 0.0; BASE temp_imag = 0.0; for (k = 0; k < K; k++) { const BASE Aki_real = CONST_REAL(A, k * lda + i); const BASE Aki_imag = -CONST_IMAG(A, k * lda + i); const BASE Akj_real = CONST_REAL(A, k * lda + j); const BASE Akj_imag = CONST_IMAG(A, k * lda + j); temp_real += Aki_real * Akj_real - Aki_imag * Akj_imag; temp_imag += Aki_real * Akj_imag + Aki_imag * Akj_real; } REAL(C, i * ldc + j) += alpha * temp_real; IMAG(C, i * ldc + j) += alpha * temp_imag; } } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_hpmv.h000066400000000000000000000116501261542461700222050ustar00rootroot00000000000000/* blas/source_hpmv.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { const int conj = (order == CblasColMajor) ? -1 : 1; INDEX i, j; const BASE alpha_real = CONST_REAL0(alpha); const BASE alpha_imag = CONST_IMAG0(alpha); const BASE beta_real = CONST_REAL0(beta); const BASE beta_imag = CONST_IMAG0(beta); if ((alpha_real == 0.0 && alpha_imag == 0.0) && (beta_real == 1.0 && beta_imag == 0.0)) return; /* form y := beta*y */ if (beta_real == 0.0 && beta_imag == 0.0) { INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { REAL(Y, iy) = 0.0; IMAG(Y, iy) = 0.0; iy += incY; } } else if (!(beta_real == 1.0 && beta_imag == 0.0)) { INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { const BASE y_real = REAL(Y, iy); const BASE y_imag = IMAG(Y, iy); const BASE tmpR = y_real * beta_real - y_imag * beta_imag; const BASE tmpI = y_real * beta_imag + y_imag * beta_real; REAL(Y, iy) = tmpR; IMAG(Y, iy) = tmpI; iy += incY; } } if (alpha_real == 0.0 && alpha_imag == 0.0) return; /* form y := alpha*A*x + y */ if ((order == CblasRowMajor && Uplo == CblasUpper) || (order == CblasColMajor && Uplo == CblasLower)) { INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { BASE x_real = CONST_REAL(X, ix); BASE x_imag = CONST_IMAG(X, ix); BASE temp1_real = alpha_real * x_real - alpha_imag * x_imag; BASE temp1_imag = alpha_real * x_imag + alpha_imag * x_real; BASE temp2_real = 0.0; BASE temp2_imag = 0.0; const INDEX j_min = i + 1; const INDEX j_max = N; INDEX jx = OFFSET(N, incX) + j_min * incX; INDEX jy = OFFSET(N, incY) + j_min * incY; BASE Aii_real = CONST_REAL(Ap, TPUP(N, i, i)); /* Aii_imag is zero */ REAL(Y, iy) += temp1_real * Aii_real; IMAG(Y, iy) += temp1_imag * Aii_real; for (j = j_min; j < j_max; j++) { BASE Aij_real = CONST_REAL(Ap, TPUP(N, i, j)); BASE Aij_imag = conj * CONST_IMAG(Ap, TPUP(N, i, j)); REAL(Y, jy) += temp1_real * Aij_real - temp1_imag * (-Aij_imag); IMAG(Y, jy) += temp1_real * (-Aij_imag) + temp1_imag * Aij_real; x_real = CONST_REAL(X, jx); x_imag = CONST_IMAG(X, jx); temp2_real += x_real * Aij_real - x_imag * Aij_imag; temp2_imag += x_real * Aij_imag + x_imag * Aij_real; jx += incX; jy += incY; } REAL(Y, iy) += alpha_real * temp2_real - alpha_imag * temp2_imag; IMAG(Y, iy) += alpha_real * temp2_imag + alpha_imag * temp2_real; ix += incX; iy += incY; } } else if ((order == CblasRowMajor && Uplo == CblasLower) || (order == CblasColMajor && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { BASE x_real = CONST_REAL(X, ix); BASE x_imag = CONST_IMAG(X, ix); BASE temp1_real = alpha_real * x_real - alpha_imag * x_imag; BASE temp1_imag = alpha_real * x_imag + alpha_imag * x_real; BASE temp2_real = 0.0; BASE temp2_imag = 0.0; const INDEX j_min = 0; const INDEX j_max = i; INDEX jx = OFFSET(N, incX) + j_min * incX; INDEX jy = OFFSET(N, incY) + j_min * incY; BASE Aii_real = CONST_REAL(Ap, TPLO(N, i, i)); /* Aii_imag is zero */ REAL(Y, iy) += temp1_real * Aii_real; IMAG(Y, iy) += temp1_imag * Aii_real; for (j = j_min; j < j_max; j++) { BASE Aij_real = CONST_REAL(Ap, TPLO(N, i, j)); BASE Aij_imag = conj * CONST_IMAG(Ap, TPLO(N, i, j)); REAL(Y, jy) += temp1_real * Aij_real - temp1_imag * (-Aij_imag); IMAG(Y, jy) += temp1_real * (-Aij_imag) + temp1_imag * Aij_real; x_real = CONST_REAL(X, jx); x_imag = CONST_IMAG(X, jx); temp2_real += x_real * Aij_real - x_imag * Aij_imag; temp2_imag += x_real * Aij_imag + x_imag * Aij_real; jx += incX; jy += incY; } REAL(Y, iy) += alpha_real * temp2_real - alpha_imag * temp2_imag; IMAG(Y, iy) += alpha_real * temp2_imag + alpha_imag * temp2_real; ix += incX; iy += incY; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_hpr.h000066400000000000000000000053631261542461700220300ustar00rootroot00000000000000/* blas/source_hpr.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { const int conj = (order == CblasColMajor) ? -1 : 1; INDEX i, j; if (alpha == 0.0) return; if ((order == CblasRowMajor && Uplo == CblasUpper) || (order == CblasColMajor && Uplo == CblasLower)) { INDEX ix = OFFSET(N, incX); for (i = 0; i < N; i++) { const BASE tmp_real = alpha * CONST_REAL(X, ix); const BASE tmp_imag = alpha * conj * CONST_IMAG(X, ix); INDEX jx = ix; { const BASE X_real = CONST_REAL(X, jx); const BASE X_imag = -conj * CONST_IMAG(X, jx); REAL(Ap, TPUP(N, i, i)) += X_real * tmp_real - X_imag * tmp_imag; IMAG(Ap, TPUP(N, i, i)) = 0; jx += incX; } for (j = i + 1; j < N; j++) { const BASE X_real = CONST_REAL(X, jx); const BASE X_imag = -conj * CONST_IMAG(X, jx); REAL(Ap, TPUP(N, i, j)) += X_real * tmp_real - X_imag * tmp_imag; IMAG(Ap, TPUP(N, i, j)) += X_imag * tmp_real + X_real * tmp_imag; jx += incX; } ix += incX; } } else if ((order == CblasRowMajor && Uplo == CblasLower) || (order == CblasColMajor && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX); for (i = 0; i < N; i++) { const BASE tmp_real = alpha * CONST_REAL(X, ix); const BASE tmp_imag = alpha * conj * CONST_IMAG(X, ix); INDEX jx = OFFSET(N, incX); for (j = 0; j < i; j++) { const BASE X_real = CONST_REAL(X, jx); const BASE X_imag = -conj * CONST_IMAG(X, jx); REAL(Ap, TPLO(N, i, j)) += X_real * tmp_real - X_imag * tmp_imag; IMAG(Ap, TPLO(N, i, j)) += X_imag * tmp_real + X_real * tmp_imag; jx += incX; } { const BASE X_real = CONST_REAL(X, jx); const BASE X_imag = -conj * CONST_IMAG(X, jx); REAL(Ap, TPLO(N, i, i)) += X_real * tmp_real - X_imag * tmp_imag; IMAG(Ap, TPLO(N, i, i)) = 0; jx += incX; } ix += incX; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_hpr2.h000066400000000000000000000103601261542461700221030ustar00rootroot00000000000000/* blas/source_hpr2.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { const int conj = (order == CblasColMajor) ? -1 : 1; INDEX i, j; const BASE alpha_real = CONST_REAL0(alpha); const BASE alpha_imag = CONST_IMAG0(alpha); if (alpha_real == 0.0 && alpha_imag == 0.0) return; if ((order == CblasRowMajor && Uplo == CblasUpper) || (order == CblasColMajor && Uplo == CblasLower)) { INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { const BASE Xi_real = CONST_REAL(X, ix); const BASE Xi_imag = CONST_IMAG(X, ix); /* tmp1 = alpha Xi */ const BASE tmp1_real = alpha_real * Xi_real - alpha_imag * Xi_imag; const BASE tmp1_imag = alpha_imag * Xi_real + alpha_real * Xi_imag; const BASE Yi_real = CONST_REAL(Y, iy); const BASE Yi_imag = CONST_IMAG(Y, iy); /* tmp2 = conj(alpha) Yi */ const BASE tmp2_real = alpha_real * Yi_real + alpha_imag * Yi_imag; const BASE tmp2_imag = -alpha_imag * Yi_real + alpha_real * Yi_imag; INDEX jx = ix + incX; INDEX jy = iy + incY; /* Aij = alpha*Xi*conj(Yj) + conj(alpha)*Yi*conj(Xj) */ REAL(Ap, TPUP(N, i, i)) += 2 * (tmp1_real * Yi_real + tmp1_imag * Yi_imag); IMAG(Ap, TPUP(N, i, i)) = 0; for (j = i + 1; j < N; j++) { const BASE Xj_real = CONST_REAL(X, jx); const BASE Xj_imag = CONST_IMAG(X, jx); const BASE Yj_real = CONST_REAL(Y, jy); const BASE Yj_imag = CONST_IMAG(Y, jy); REAL(Ap, TPUP(N, i, j)) += ((tmp1_real * Yj_real + tmp1_imag * Yj_imag) + (tmp2_real * Xj_real + tmp2_imag * Xj_imag)); IMAG(Ap, TPUP(N, i, j)) += conj * ((tmp1_imag * Yj_real - tmp1_real * Yj_imag) + (tmp2_imag * Xj_real - tmp2_real * Xj_imag)); jx += incX; jy += incY; } ix += incX; iy += incY; } } else if ((order == CblasRowMajor && Uplo == CblasLower) || (order == CblasColMajor && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { const BASE Xi_real = CONST_REAL(X, ix); const BASE Xi_imag = CONST_IMAG(X, ix); const BASE tmp1_real = alpha_real * Xi_real - alpha_imag * Xi_imag; const BASE tmp1_imag = alpha_imag * Xi_real + alpha_real * Xi_imag; const BASE Yi_real = CONST_REAL(Y, iy); const BASE Yi_imag = CONST_IMAG(Y, iy); const BASE tmp2_real = alpha_real * Yi_real + alpha_imag * Yi_imag; const BASE tmp2_imag = -alpha_imag * Yi_real + alpha_real * Yi_imag; INDEX jx = OFFSET(N, incX); INDEX jy = OFFSET(N, incY); /* Aij = alpha*Xi*conj(Yj) + conj(alpha)*Yi*conj(Xj) */ for (j = 0; j < i; j++) { const BASE Xj_real = CONST_REAL(X, jx); const BASE Xj_imag = CONST_IMAG(X, jx); const BASE Yj_real = CONST_REAL(Y, jy); const BASE Yj_imag = CONST_IMAG(Y, jy); REAL(Ap, TPLO(N, i, j)) += ((tmp1_real * Yj_real + tmp1_imag * Yj_imag) + (tmp2_real * Xj_real + tmp2_imag * Xj_imag)); IMAG(Ap, TPLO(N, i, j)) += conj * ((tmp1_imag * Yj_real - tmp1_real * Yj_imag) + (tmp2_imag * Xj_real - tmp2_real * Xj_imag)); jx += incX; jy += incY; } REAL(Ap, TPLO(N, i, i)) += 2 * (tmp1_real * Yi_real + tmp1_imag * Yi_imag); IMAG(Ap, TPLO(N, i, i)) = 0; ix += incX; iy += incY; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_iamax_c.h000066400000000000000000000021501261542461700226270ustar00rootroot00000000000000/* blas/source_iamax_c.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { BASE max = 0.0; INDEX ix = 0; INDEX i; CBLAS_INDEX result = 0; if (incX <= 0) { return 0; } for (i = 0; i < N; i++) { const BASE a = fabs(CONST_REAL(X, ix)) + fabs(CONST_IMAG(X, ix)); if (a > max) { max = a; result = i; } ix += incX; } return result; } praat-6.0.04/external/gsl/gsl_cblas__source_iamax_r.h000066400000000000000000000020651261542461700226530ustar00rootroot00000000000000/* blas/source_iamax_r.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { BASE max = 0.0; INDEX ix = 0; INDEX i; CBLAS_INDEX result = 0; if (incX <= 0) { return 0; } for (i = 0; i < N; i++) { if (fabs(X[ix]) > max) { max = fabs(X[ix]); result = i; } ix += incX; } return result; } praat-6.0.04/external/gsl/gsl_cblas__source_nrm2_c.h000066400000000000000000000030031261542461700224040ustar00rootroot00000000000000/* blas/source_nrm2_c.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { BASE scale = 0.0; BASE ssq = 1.0; INDEX i; INDEX ix = 0; if (N == 0 || incX < 1) { return 0; } for (i = 0; i < N; i++) { const BASE x = CONST_REAL(X, ix); const BASE y = CONST_IMAG(X, ix); if (x != 0.0) { const BASE ax = fabs(x); if (scale < ax) { ssq = 1.0 + ssq * (scale / ax) * (scale / ax); scale = ax; } else { ssq += (ax / scale) * (ax / scale); } } if (y != 0.0) { const BASE ay = fabs(y); if (scale < ay) { ssq = 1.0 + ssq * (scale / ay) * (scale / ay); scale = ay; } else { ssq += (ay / scale) * (ay / scale); } } ix += incX; } return scale * sqrt(ssq); } praat-6.0.04/external/gsl/gsl_cblas__source_nrm2_r.h000066400000000000000000000024371261542461700224350ustar00rootroot00000000000000/* blas/source_nrm2_r.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { BASE scale = 0.0; BASE ssq = 1.0; INDEX i; INDEX ix = 0; if (N <= 0 || incX <= 0) { return 0; } else if (N == 1) { return fabs(X[0]); } for (i = 0; i < N; i++) { const BASE x = X[ix]; if (x != 0.0) { const BASE ax = fabs(x); if (scale < ax) { ssq = 1.0 + ssq * (scale / ax) * (scale / ax); scale = ax; } else { ssq += (ax / scale) * (ax / scale); } } ix += incX; } return scale * sqrt(ssq); } praat-6.0.04/external/gsl/gsl_cblas__source_rot.h000066400000000000000000000020451261542461700220350ustar00rootroot00000000000000/* blas/source_rot.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i; INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { const BASE x = X[ix]; const BASE y = Y[iy]; X[ix] = c * x + s * y; Y[iy] = -s * x + c * y; ix += incX; iy += incY; } } praat-6.0.04/external/gsl/gsl_cblas__source_rotg.h000066400000000000000000000024651261542461700222120ustar00rootroot00000000000000/* blas/source_rotg.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { const BASE roe = (fabs(*a) > fabs(*b) ? *a : *b); const BASE scale = fabs(*a) + fabs(*b); BASE r, z; if (scale != 0.0) { const BASE aos = *a / scale; const BASE bos = *b / scale; r = scale * sqrt(aos * aos + bos * bos); r = GSL_SIGN(roe) * r; *c = *a / r; *s = *b / r; z = 1.0; if (fabs(*a) > fabs(*b)) z = *s; if (fabs(*b) >= fabs(*a) && *c != 0.0) z = 1.0 / (*c); } else { *c = 1.0; *s = 0.0; r = 0.0; z = 0.0; } *a = r; *b = z; } praat-6.0.04/external/gsl/gsl_cblas__source_rotm.h000066400000000000000000000027051261542461700222150ustar00rootroot00000000000000/* blas/source_rotmg.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX n; INDEX i = OFFSET(N, incX); INDEX j = OFFSET(N, incY); BASE h11, h21, h12, h22; if (P[0] == -1.0) { h11 = P[1]; h21 = P[2]; h12 = P[3]; h22 = P[4]; } else if (P[0] == 0.0) { h11 = 1.0; h21 = P[2]; h12 = P[3]; h22 = 1.0; } else if (P[0] == 1.0) { h11 = P[1]; h21 = -1.0; h12 = 1.0; h22 = P[4]; } else if (P[0] == -2.0) { return; } else { BLAS_ERROR("unrecognized value of P[0]"); return; } for (n = 0; n < N; n++) { const BASE w = X[i]; const BASE z = Y[j]; X[i] = h11 * w + h12 * z; Y[j] = h21 * w + h22 * z; i += incX; j += incY; } } praat-6.0.04/external/gsl/gsl_cblas__source_rotmg.h000066400000000000000000000055201261542461700223620ustar00rootroot00000000000000/* blas/source_rotmg.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { const BASE G = 4096.0, G2 = G * G; BASE D1 = *d1, D2 = *d2, x = *b1, y = b2; BASE h11, h12, h21, h22, u; BASE c, s; /* case of d1 < 0, appendix A, second to last paragraph */ if (D1 < 0.0) { P[0] = -1; P[1] = 0; P[2] = 0; P[3] = 0; P[4] = 0; *d1 = 0; *d2 = 0; *b1 = 0; return; } if (D2 * y == 0.0) { P[0] = -2; /* case of H = I, page 315 */ return; } c = fabs(D1 * x * x); s = fabs(D2 * y * y); if (c > s) { /* case of equation A6 */ P[0] = 0.0; h11 = 1; h12 = (D2 * y) / (D1 * x); h21 = -y / x; h22 = 1; u = 1 - h21 * h12; if (u <= 0.0) { /* the case u <= 0 is rejected */ P[0] = -1; P[1] = 0; P[2] = 0; P[3] = 0; P[4] = 0; *d1 = 0; *d2 = 0; *b1 = 0; return; } D1 /= u; D2 /= u; x *= u; } else { /* case of equation A7 */ if (D2 * y * y < 0.0) { P[0] = -1; P[1] = 0; P[2] = 0; P[3] = 0; P[4] = 0; *d1 = 0; *d2 = 0; *b1 = 0; return; } P[0] = 1; h11 = (D1 * x) / (D2 * y); h12 = 1; h21 = -1; h22 = x / y; u = 1 + h11 * h22; D1 /= u; D2 /= u; { BASE tmp = D2; D2 = D1; D1 = tmp; } x = y * u; } /* rescale D1 to range [1/G2,G2] */ while (D1 <= 1.0 / G2 && D1 != 0.0) { P[0] = -1; D1 *= G2; x /= G; h11 /= G; h12 /= G; } while (D1 >= G2) { P[0] = -1; D1 /= G2; x *= G; h11 *= G; h12 *= G; } /* rescale D2 to range [1/G2,G2] */ while (fabs(D2) <= 1.0 / G2 && D2 != 0.0) { P[0] = -1; D2 *= G2; h21 /= G; h22 /= G; } while (fabs(D2) >= G2) { P[0] = -1; D2 /= G2; h21 *= G; h22 *= G; } *d1 = D1; *d2 = D2; *b1 = x; if (P[0] == -1.0) { P[1] = h11; P[2] = h21; P[3] = h12; P[4] = h22; } else if (P[0] == 0.0) { P[2] = h21; P[3] = h12; } else if (P[0] == 1.0) { P[1] = h11; P[4] = h22; } } praat-6.0.04/external/gsl/gsl_cblas__source_sbmv.h000066400000000000000000000053631261542461700222060ustar00rootroot00000000000000/* blas/source_sbmv.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j; if (N == 0) return; if (alpha == 0.0 && beta == 1.0) return; /* form y := beta*y */ if (beta == 0.0) { INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { Y[iy] = 0.0; iy += incY; } } else if (beta != 1.0) { INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { Y[iy] *= beta; iy += incY; } } if (alpha == 0.0) return; /* form y := alpha*A*x + y */ if ((order == CblasRowMajor && Uplo == CblasUpper) || (order == CblasColMajor && Uplo == CblasLower)) { INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { BASE tmp1 = alpha * X[ix]; BASE tmp2 = 0.0; const INDEX j_min = i + 1; const INDEX j_max = GSL_MIN(N, i + K + 1); INDEX jx = OFFSET(N, incX) + j_min * incX; INDEX jy = OFFSET(N, incY) + j_min * incY; Y[iy] += tmp1 * A[0 + i * lda]; for (j = j_min; j < j_max; j++) { BASE Aij = A[(j - i) + i * lda]; Y[jy] += tmp1 * Aij; tmp2 += Aij * X[jx]; jx += incX; jy += incY; } Y[iy] += alpha * tmp2; ix += incX; iy += incY; } } else if ((order == CblasRowMajor && Uplo == CblasLower) || (order == CblasColMajor && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { BASE tmp1 = alpha * X[ix]; BASE tmp2 = 0.0; const INDEX j_min = (i > K) ? i - K : 0; const INDEX j_max = i; INDEX jx = OFFSET(N, incX) + j_min * incX; INDEX jy = OFFSET(N, incY) + j_min * incY; for (j = j_min; j < j_max; j++) { BASE Aij = A[(K - i + j) + i * lda]; Y[jy] += tmp1 * Aij; tmp2 += Aij * X[jx]; jx += incX; jy += incY; } Y[iy] += tmp1 * A[K + i * lda] + alpha * tmp2; ix += incX; iy += incY; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_scal_c.h000066400000000000000000000023331261542461700224550ustar00rootroot00000000000000/* blas/source_scal_c.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i; INDEX ix; const BASE alpha_real = CONST_REAL0(alpha); const BASE alpha_imag = CONST_IMAG0(alpha); if (incX <= 0) { return; } ix = OFFSET(N, incX); for (i = 0; i < N; i++) { const BASE x_real = REAL(X, ix); const BASE x_imag = IMAG(X, ix); REAL(X, ix) = x_real * alpha_real - x_imag * alpha_imag; IMAG(X, ix) = x_real * alpha_imag + x_imag * alpha_real; ix += incX; } } praat-6.0.04/external/gsl/gsl_cblas__source_scal_c_s.h000066400000000000000000000017611261542461700230030ustar00rootroot00000000000000/* blas/source_scal_c_s.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i; INDEX ix; if (incX <= 0) { return; } ix = OFFSET(N, incX); for (i = 0; i < N; i++) { REAL(X, ix) *= alpha; IMAG(X, ix) *= alpha; ix += incX; } } praat-6.0.04/external/gsl/gsl_cblas__source_scal_r.h000066400000000000000000000017171261542461700225010ustar00rootroot00000000000000/* blas/source_scal_r.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i; INDEX ix; if (incX <= 0) { return; } ix = OFFSET(N, incX); for (i = 0; i < N; i++) { X[ix] *= alpha; ix += incX; } } praat-6.0.04/external/gsl/gsl_cblas__source_spmv.h000066400000000000000000000053131261542461700222170ustar00rootroot00000000000000/* blas/source_spmv.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j; if (alpha == 0.0 && beta == 1.0) return; /* form y := beta*y */ if (beta == 0.0) { INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { Y[iy] = 0.0; iy += incY; } } else if (beta != 1.0) { INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { Y[iy] *= beta; iy += incY; } } if (alpha == 0.0) return; /* form y := alpha*A*x + y */ if ((order == CblasRowMajor && Uplo == CblasUpper) || (order == CblasColMajor && Uplo == CblasLower)) { INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { BASE tmp1 = alpha * X[ix]; BASE tmp2 = 0.0; const INDEX j_min = i + 1; const INDEX j_max = N; INDEX jx = OFFSET(N, incX) + j_min * incX; INDEX jy = OFFSET(N, incY) + j_min * incY; Y[iy] += tmp1 * Ap[TPUP(N, i, i)]; for (j = j_min; j < j_max; j++) { const BASE apk = Ap[TPUP(N, i, j)]; Y[jy] += tmp1 * apk; tmp2 += apk * X[jx]; jy += incY; jx += incX; } Y[iy] += alpha * tmp2; ix += incX; iy += incY; } } else if ((order == CblasRowMajor && Uplo == CblasLower) || (order == CblasColMajor && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { BASE tmp1 = alpha * X[ix]; BASE tmp2 = 0.0; const INDEX j_min = 0; const INDEX j_max = i; INDEX jx = OFFSET(N, incX) + j_min * incX; INDEX jy = OFFSET(N, incY) + j_min * incY; Y[iy] += tmp1 * Ap[TPLO(N, i, i)]; for (j = j_min; j < j_max; j++) { const BASE apk = Ap[TPLO(N, i, j)]; Y[jy] += tmp1 * apk; tmp2 += apk * X[jx]; jy += incY; jx += incX; } Y[iy] += alpha * tmp2; ix += incX; iy += incY; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_spr.h000066400000000000000000000032411261542461700220340ustar00rootroot00000000000000/* blas/source_spr.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j; if (N == 0) return; if (alpha == 0.0) return; if ((order == CblasRowMajor && Uplo == CblasUpper) || (order == CblasColMajor && Uplo == CblasLower)) { INDEX ix = OFFSET(N, incX); for (i = 0; i < N; i++) { const BASE tmp = alpha * X[ix]; INDEX jx = ix; for (j = i; j < N; j++) { Ap[TPUP(N, i, j)] += X[jx] * tmp; jx += incX; } ix += incX; } } else if ((order == CblasRowMajor && Uplo == CblasLower) || (order == CblasColMajor && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX); for (i = 0; i < N; i++) { const BASE tmp = alpha * X[ix]; INDEX jx = OFFSET(N, incX); for (j = 0; j <= i; j++) { Ap[TPLO(N, i, j)] += X[jx] * tmp; jx += incX; } ix += incX; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_spr2.h000066400000000000000000000037251261542461700221250ustar00rootroot00000000000000/* blas/source_spr2.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j; if (N == 0) return; if (alpha == 0.0) return; if ((order == CblasRowMajor && Uplo == CblasUpper) || (order == CblasColMajor && Uplo == CblasLower)) { INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { const BASE tmp1 = alpha * X[ix]; const BASE tmp2 = alpha * Y[iy]; INDEX jx = ix; INDEX jy = iy; for (j = i; j < N; j++) { Ap[TPUP(N, i, j)] += tmp1 * Y[jy] + tmp2 * X[jx]; jx += incX; jy += incY; } ix += incX; iy += incY; } } else if ((order == CblasRowMajor && Uplo == CblasLower) || (order == CblasColMajor && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { const BASE tmp1 = alpha * X[ix]; const BASE tmp2 = alpha * Y[iy]; INDEX jx = OFFSET(N, incX); INDEX jy = OFFSET(N, incY); for (j = 0; j <= i; j++) { Ap[TPLO(N, i, j)] += tmp1 * Y[jy] + tmp2 * X[jx]; jx += incX; jy += incY; } ix += incX; iy += incY; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_swap_c.h000066400000000000000000000022021261542461700225000ustar00rootroot00000000000000/* blas/source_swap_c.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i; INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { const BASE tmp_real = REAL(X, ix); const BASE tmp_imag = IMAG(X, ix); REAL(X, ix) = REAL(Y, iy); IMAG(X, ix) = IMAG(Y, iy); REAL(Y, iy) = tmp_real; IMAG(Y, iy) = tmp_imag; ix += incX; iy += incY; } } praat-6.0.04/external/gsl/gsl_cblas__source_swap_r.h000066400000000000000000000017751261542461700225350ustar00rootroot00000000000000/* blas/source_swap_r.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i; INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { const BASE tmp = X[ix]; X[ix] = Y[iy]; Y[iy] = tmp; ix += incX; iy += incY; } } praat-6.0.04/external/gsl/gsl_cblas__source_symm_c.h000066400000000000000000000202371261542461700225230ustar00rootroot00000000000000/* blas/source_symm_c.h * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j, k; INDEX n1, n2; int uplo, side; const BASE alpha_real = CONST_REAL0(alpha); const BASE alpha_imag = CONST_IMAG0(alpha); const BASE beta_real = CONST_REAL0(beta); const BASE beta_imag = CONST_IMAG0(beta); if ((alpha_real == 0.0 && alpha_imag == 0.0) && (beta_real == 1.0 && beta_imag == 0.0)) return; if (Order == CblasRowMajor) { n1 = M; n2 = N; uplo = Uplo; side = Side; } else { n1 = N; n2 = M; uplo = (Uplo == CblasUpper) ? CblasLower : CblasUpper; side = (Side == CblasLeft) ? CblasRight : CblasLeft; } /* form y := beta*y */ if (beta_real == 0.0 && beta_imag == 0.0) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { REAL(C, ldc * i + j) = 0.0; IMAG(C, ldc * i + j) = 0.0; } } } else if (!(beta_real == 1.0 && beta_imag == 0.0)) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { const BASE Cij_real = REAL(C, ldc * i + j); const BASE Cij_imag = IMAG(C, ldc * i + j); REAL(C, ldc * i + j) = beta_real * Cij_real - beta_imag * Cij_imag; IMAG(C, ldc * i + j) = beta_real * Cij_imag + beta_imag * Cij_real; } } } if (alpha_real == 0.0 && alpha_imag == 0.0) return; if (side == CblasLeft && uplo == CblasUpper) { /* form C := alpha*A*B + C */ for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { const BASE Bij_real = CONST_REAL(B, ldb * i + j); const BASE Bij_imag = CONST_IMAG(B, ldb * i + j); const BASE temp1_real = alpha_real * Bij_real - alpha_imag * Bij_imag; const BASE temp1_imag = alpha_real * Bij_imag + alpha_imag * Bij_real; BASE temp2_real = 0.0; BASE temp2_imag = 0.0; { const BASE Aii_real = CONST_REAL(A, i * lda + i); const BASE Aii_imag = CONST_IMAG(A, i * lda + i); REAL(C, i * ldc + j) += temp1_real * Aii_real - temp1_imag * Aii_imag; IMAG(C, i * ldc + j) += temp1_real * Aii_imag + temp1_imag * Aii_real; } for (k = i + 1; k < n1; k++) { const BASE Aik_real = CONST_REAL(A, i * lda + k); const BASE Aik_imag = CONST_IMAG(A, i * lda + k); const BASE Bkj_real = CONST_REAL(B, ldb * k + j); const BASE Bkj_imag = CONST_IMAG(B, ldb * k + j); REAL(C, k * ldc + j) += Aik_real * temp1_real - Aik_imag * temp1_imag; IMAG(C, k * ldc + j) += Aik_real * temp1_imag + Aik_imag * temp1_real; temp2_real += Aik_real * Bkj_real - Aik_imag * Bkj_imag; temp2_imag += Aik_real * Bkj_imag + Aik_imag * Bkj_real; } REAL(C, i * ldc + j) += alpha_real * temp2_real - alpha_imag * temp2_imag; IMAG(C, i * ldc + j) += alpha_real * temp2_imag + alpha_imag * temp2_real; } } } else if (side == CblasLeft && uplo == CblasLower) { /* form C := alpha*A*B + C */ for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { const BASE Bij_real = CONST_REAL(B, ldb * i + j); const BASE Bij_imag = CONST_IMAG(B, ldb * i + j); const BASE temp1_real = alpha_real * Bij_real - alpha_imag * Bij_imag; const BASE temp1_imag = alpha_real * Bij_imag + alpha_imag * Bij_real; BASE temp2_real = 0.0; BASE temp2_imag = 0.0; for (k = 0; k < i; k++) { const BASE Aik_real = CONST_REAL(A, i * lda + k); const BASE Aik_imag = CONST_IMAG(A, i * lda + k); const BASE Bkj_real = CONST_REAL(B, ldb * k + j); const BASE Bkj_imag = CONST_IMAG(B, ldb * k + j); REAL(C, k * ldc + j) += Aik_real * temp1_real - Aik_imag * temp1_imag; IMAG(C, k * ldc + j) += Aik_real * temp1_imag + Aik_imag * temp1_real; temp2_real += Aik_real * Bkj_real - Aik_imag * Bkj_imag; temp2_imag += Aik_real * Bkj_imag + Aik_imag * Bkj_real; } { const BASE Aii_real = CONST_REAL(A, i * lda + i); const BASE Aii_imag = CONST_IMAG(A, i * lda + i); REAL(C, i * ldc + j) += temp1_real * Aii_real - temp1_imag * Aii_imag; IMAG(C, i * ldc + j) += temp1_real * Aii_imag + temp1_imag * Aii_real; } REAL(C, i * ldc + j) += alpha_real * temp2_real - alpha_imag * temp2_imag; IMAG(C, i * ldc + j) += alpha_real * temp2_imag + alpha_imag * temp2_real; } } } else if (side == CblasRight && uplo == CblasUpper) { /* form C := alpha*B*A + C */ for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { const BASE Bij_real = CONST_REAL(B, ldb * i + j); const BASE Bij_imag = CONST_IMAG(B, ldb * i + j); const BASE temp1_real = alpha_real * Bij_real - alpha_imag * Bij_imag; const BASE temp1_imag = alpha_real * Bij_imag + alpha_imag * Bij_real; BASE temp2_real = 0.0; BASE temp2_imag = 0.0; { const BASE Ajj_real = CONST_REAL(A, j * lda + j); const BASE Ajj_imag = CONST_IMAG(A, j * lda + j); REAL(C, i * ldc + j) += temp1_real * Ajj_real - temp1_imag * Ajj_imag; IMAG(C, i * ldc + j) += temp1_real * Ajj_imag + temp1_imag * Ajj_real; } for (k = j + 1; k < n2; k++) { const BASE Ajk_real = CONST_REAL(A, j * lda + k); const BASE Ajk_imag = CONST_IMAG(A, j * lda + k); const BASE Bik_real = CONST_REAL(B, ldb * i + k); const BASE Bik_imag = CONST_IMAG(B, ldb * i + k); REAL(C, i * ldc + k) += temp1_real * Ajk_real - temp1_imag * Ajk_imag; IMAG(C, i * ldc + k) += temp1_real * Ajk_imag + temp1_imag * Ajk_real; temp2_real += Bik_real * Ajk_real - Bik_imag * Ajk_imag; temp2_imag += Bik_real * Ajk_imag + Bik_imag * Ajk_real; } REAL(C, i * ldc + j) += alpha_real * temp2_real - alpha_imag * temp2_imag; IMAG(C, i * ldc + j) += alpha_real * temp2_imag + alpha_imag * temp2_real; } } } else if (side == CblasRight && uplo == CblasLower) { /* form C := alpha*B*A + C */ for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { const BASE Bij_real = CONST_REAL(B, ldb * i + j); const BASE Bij_imag = CONST_IMAG(B, ldb * i + j); const BASE temp1_real = alpha_real * Bij_real - alpha_imag * Bij_imag; const BASE temp1_imag = alpha_real * Bij_imag + alpha_imag * Bij_real; BASE temp2_real = 0.0; BASE temp2_imag = 0.0; for (k = 0; k < j; k++) { const BASE Ajk_real = CONST_REAL(A, j * lda + k); const BASE Ajk_imag = CONST_IMAG(A, j * lda + k); const BASE Bik_real = CONST_REAL(B, ldb * i + k); const BASE Bik_imag = CONST_IMAG(B, ldb * i + k); REAL(C, i * ldc + k) += temp1_real * Ajk_real - temp1_imag * Ajk_imag; IMAG(C, i * ldc + k) += temp1_real * Ajk_imag + temp1_imag * Ajk_real; temp2_real += Bik_real * Ajk_real - Bik_imag * Ajk_imag; temp2_imag += Bik_real * Ajk_imag + Bik_imag * Ajk_real; } { const BASE Ajj_real = CONST_REAL(A, j * lda + j); const BASE Ajj_imag = CONST_IMAG(A, j * lda + j); REAL(C, i * ldc + j) += temp1_real * Ajj_real - temp1_imag * Ajj_imag; IMAG(C, i * ldc + j) += temp1_real * Ajj_imag + temp1_imag * Ajj_real; } REAL(C, i * ldc + j) += alpha_real * temp2_real - alpha_imag * temp2_imag; IMAG(C, i * ldc + j) += alpha_real * temp2_imag + alpha_imag * temp2_real; } } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_symm_r.h000066400000000000000000000067061261542461700225470ustar00rootroot00000000000000/* blas/source_symm_r.h * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j, k; INDEX n1, n2; int uplo, side; if (alpha == 0.0 && beta == 1.0) return; if (Order == CblasRowMajor) { n1 = M; n2 = N; uplo = Uplo; side = Side; } else { n1 = N; n2 = M; uplo = (Uplo == CblasUpper) ? CblasLower : CblasUpper; side = (Side == CblasLeft) ? CblasRight : CblasLeft; } /* form y := beta*y */ if (beta == 0.0) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { C[ldc * i + j] = 0.0; } } } else if (beta != 1.0) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { C[ldc * i + j] *= beta; } } } if (alpha == 0.0) return; if (side == CblasLeft && uplo == CblasUpper) { /* form C := alpha*A*B + C */ for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { const BASE temp1 = alpha * B[ldb * i + j]; BASE temp2 = 0.0; C[i * ldc + j] += temp1 * A[i * lda + i]; for (k = i + 1; k < n1; k++) { const BASE Aik = A[i * lda + k]; C[k * ldc + j] += Aik * temp1; temp2 += Aik * B[ldb * k + j]; } C[i * ldc + j] += alpha * temp2; } } } else if (side == CblasLeft && uplo == CblasLower) { /* form C := alpha*A*B + C */ for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { const BASE temp1 = alpha * B[ldb * i + j]; BASE temp2 = 0.0; for (k = 0; k < i; k++) { const BASE Aik = A[i * lda + k]; C[k * ldc + j] += Aik * temp1; temp2 += Aik * B[ldb * k + j]; } C[i * ldc + j] += temp1 * A[i * lda + i] + alpha * temp2; } } } else if (side == CblasRight && uplo == CblasUpper) { /* form C := alpha*B*A + C */ for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { const BASE temp1 = alpha * B[ldb * i + j]; BASE temp2 = 0.0; C[i * ldc + j] += temp1 * A[j * lda + j]; for (k = j + 1; k < n2; k++) { const BASE Ajk = A[j * lda + k]; C[i * ldc + k] += temp1 * Ajk; temp2 += B[ldb * i + k] * Ajk; } C[i * ldc + j] += alpha * temp2; } } } else if (side == CblasRight && uplo == CblasLower) { /* form C := alpha*B*A + C */ for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { const BASE temp1 = alpha * B[ldb * i + j]; BASE temp2 = 0.0; for (k = 0; k < j; k++) { const BASE Ajk = A[j * lda + k]; C[i * ldc + k] += temp1 * Ajk; temp2 += B[ldb * i + k] * Ajk; } C[i * ldc + j] += temp1 * A[j * lda + j] + alpha * temp2; } } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_symv.h000066400000000000000000000053041261542461700222300ustar00rootroot00000000000000/* blas/source_symv.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j; if (alpha == 0.0 && beta == 1.0) return; /* form y := beta*y */ if (beta == 0.0) { INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { Y[iy] = 0.0; iy += incY; } } else if (beta != 1.0) { INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { Y[iy] *= beta; iy += incY; } } if (alpha == 0.0) return; /* form y := alpha*A*x + y */ if ((order == CblasRowMajor && Uplo == CblasUpper) || (order == CblasColMajor && Uplo == CblasLower)) { INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { BASE temp1 = alpha * X[ix]; BASE temp2 = 0.0; const INDEX j_min = i + 1; const INDEX j_max = N; INDEX jx = OFFSET(N, incX) + j_min * incX; INDEX jy = OFFSET(N, incY) + j_min * incY; Y[iy] += temp1 * A[lda * i + i]; for (j = j_min; j < j_max; j++) { Y[jy] += temp1 * A[lda * i + j]; temp2 += X[jx] * A[lda * i + j]; jx += incX; jy += incY; } Y[iy] += alpha * temp2; ix += incX; iy += incY; } } else if ((order == CblasRowMajor && Uplo == CblasLower) || (order == CblasColMajor && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX) + (N - 1) * incX; INDEX iy = OFFSET(N, incY) + (N - 1) * incY; for (i = N; i > 0 && i--;) { BASE temp1 = alpha * X[ix]; BASE temp2 = 0.0; const INDEX j_min = 0; const INDEX j_max = i; INDEX jx = OFFSET(N, incX) + j_min * incX; INDEX jy = OFFSET(N, incY) + j_min * incY; Y[iy] += temp1 * A[lda * i + i]; for (j = j_min; j < j_max; j++) { Y[jy] += temp1 * A[lda * i + j]; temp2 += X[jx] * A[lda * i + j]; jx += incX; jy += incY; } Y[iy] += alpha * temp2; ix -= incX; iy -= incY; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_syr.h000066400000000000000000000032331261542461700220460ustar00rootroot00000000000000/* blas/source_syr.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j; if (N == 0) return; if (alpha == 0.0) return; if ((order == CblasRowMajor && Uplo == CblasUpper) || (order == CblasColMajor && Uplo == CblasLower)) { INDEX ix = OFFSET(N, incX); for (i = 0; i < N; i++) { const BASE tmp = alpha * X[ix]; INDEX jx = ix; for (j = i; j < N; j++) { A[lda * i + j] += X[jx] * tmp; jx += incX; } ix += incX; } } else if ((order == CblasRowMajor && Uplo == CblasLower) || (order == CblasColMajor && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX); for (i = 0; i < N; i++) { const BASE tmp = alpha * X[ix]; INDEX jx = OFFSET(N, incX); for (j = 0; j <= i; j++) { A[lda * i + j] += X[jx] * tmp; jx += incX; } ix += incX; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_syr2.h000066400000000000000000000037171261542461700221370ustar00rootroot00000000000000/* blas/source_syr2.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j; if (N == 0) return; if (alpha == 0.0) return; if ((order == CblasRowMajor && Uplo == CblasUpper) || (order == CblasColMajor && Uplo == CblasLower)) { INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { const BASE tmp1 = alpha * X[ix]; const BASE tmp2 = alpha * Y[iy]; INDEX jx = ix; INDEX jy = iy; for (j = i; j < N; j++) { A[lda * i + j] += tmp1 * Y[jy] + tmp2 * X[jx]; jx += incX; jy += incY; } ix += incX; iy += incY; } } else if ((order == CblasRowMajor && Uplo == CblasLower) || (order == CblasColMajor && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX); INDEX iy = OFFSET(N, incY); for (i = 0; i < N; i++) { const BASE tmp1 = alpha * X[ix]; const BASE tmp2 = alpha * Y[iy]; INDEX jx = OFFSET(N, incX); INDEX jy = OFFSET(N, incY); for (j = 0; j <= i; j++) { A[lda * i + j] += tmp1 * Y[jy] + tmp2 * X[jx]; jx += incX; jy += incY; } ix += incX; iy += incY; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_syr2k_c.h000066400000000000000000000163611261542461700226130ustar00rootroot00000000000000/* blas/source_syr2k_c.h * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j, k; int uplo, trans; const BASE alpha_real = CONST_REAL0(alpha); const BASE alpha_imag = CONST_IMAG0(alpha); const BASE beta_real = CONST_REAL0(beta); const BASE beta_imag = CONST_IMAG0(beta); if ((alpha_real == 0.0 && alpha_imag == 0.0) && (beta_real == 1.0 && beta_imag == 0.0)) return; if (Order == CblasRowMajor) { uplo = Uplo; trans = Trans; } else { uplo = (Uplo == CblasUpper) ? CblasLower : CblasUpper; trans = (Trans == CblasNoTrans) ? CblasTrans : CblasNoTrans; } /* form C := beta*C */ if (beta_real == 0.0 && beta_imag == 0.0) { if (uplo == CblasUpper) { for (i = 0; i < N; i++) { for (j = i; j < N; j++) { REAL(C, ldc * i + j) = 0.0; IMAG(C, ldc * i + j) = 0.0; } } } else { for (i = 0; i < N; i++) { for (j = 0; j <= i; j++) { REAL(C, ldc * i + j) = 0.0; IMAG(C, ldc * i + j) = 0.0; } } } } else if (!(beta_real == 1.0 && beta_imag == 0.0)) { if (uplo == CblasUpper) { for (i = 0; i < N; i++) { for (j = i; j < N; j++) { const BASE Cij_real = REAL(C, ldc * i + j); const BASE Cij_imag = IMAG(C, ldc * i + j); REAL(C, ldc * i + j) = beta_real * Cij_real - beta_imag * Cij_imag; IMAG(C, ldc * i + j) = beta_real * Cij_imag + beta_imag * Cij_real; } } } else { for (i = 0; i < N; i++) { for (j = 0; j <= i; j++) { const BASE Cij_real = REAL(C, ldc * i + j); const BASE Cij_imag = IMAG(C, ldc * i + j); REAL(C, ldc * i + j) = beta_real * Cij_real - beta_imag * Cij_imag; IMAG(C, ldc * i + j) = beta_real * Cij_imag + beta_imag * Cij_real; } } } } if (alpha_real == 0.0 && alpha_imag == 0.0) return; if (uplo == CblasUpper && trans == CblasNoTrans) { for (i = 0; i < N; i++) { for (j = i; j < N; j++) { BASE temp_real = 0.0; BASE temp_imag = 0.0; for (k = 0; k < K; k++) { const BASE Aik_real = CONST_REAL(A, i * lda + k); const BASE Aik_imag = CONST_IMAG(A, i * lda + k); const BASE Bik_real = CONST_REAL(B, i * ldb + k); const BASE Bik_imag = CONST_IMAG(B, i * ldb + k); const BASE Ajk_real = CONST_REAL(A, j * lda + k); const BASE Ajk_imag = CONST_IMAG(A, j * lda + k); const BASE Bjk_real = CONST_REAL(B, j * ldb + k); const BASE Bjk_imag = CONST_IMAG(B, j * ldb + k); temp_real += ((Aik_real * Bjk_real - Aik_imag * Bjk_imag) + (Bik_real * Ajk_real - Bik_imag * Ajk_imag)); temp_imag += ((Aik_real * Bjk_imag + Aik_imag * Bjk_real) + (Bik_real * Ajk_imag + Bik_imag * Ajk_real)); } REAL(C, i * ldc + j) += alpha_real * temp_real - alpha_imag * temp_imag; IMAG(C, i * ldc + j) += alpha_real * temp_imag + alpha_imag * temp_real; } } } else if (uplo == CblasUpper && trans == CblasTrans) { for (k = 0; k < K; k++) { for (i = 0; i < N; i++) { BASE Aki_real = CONST_REAL(A, k * lda + i); BASE Aki_imag = CONST_IMAG(A, k * lda + i); BASE Bki_real = CONST_REAL(B, k * ldb + i); BASE Bki_imag = CONST_IMAG(B, k * ldb + i); BASE temp1_real = alpha_real * Aki_real - alpha_imag * Aki_imag; BASE temp1_imag = alpha_real * Aki_imag + alpha_imag * Aki_real; BASE temp2_real = alpha_real * Bki_real - alpha_imag * Bki_imag; BASE temp2_imag = alpha_real * Bki_imag + alpha_imag * Bki_real; for (j = i; j < N; j++) { BASE Akj_real = CONST_REAL(A, k * lda + j); BASE Akj_imag = CONST_IMAG(A, k * lda + j); BASE Bkj_real = CONST_REAL(B, k * ldb + j); BASE Bkj_imag = CONST_IMAG(B, k * ldb + j); REAL(C, i * lda + j) += (temp1_real * Bkj_real - temp1_imag * Bkj_imag) + (temp2_real * Akj_real - temp2_imag * Akj_imag); IMAG(C, i * lda + j) += (temp1_real * Bkj_imag + temp1_imag * Bkj_real) + (temp2_real * Akj_imag + temp2_imag * Akj_real); } } } } else if (uplo == CblasLower && trans == CblasNoTrans) { for (i = 0; i < N; i++) { for (j = 0; j <= i; j++) { BASE temp_real = 0.0; BASE temp_imag = 0.0; for (k = 0; k < K; k++) { const BASE Aik_real = CONST_REAL(A, i * lda + k); const BASE Aik_imag = CONST_IMAG(A, i * lda + k); const BASE Bik_real = CONST_REAL(B, i * ldb + k); const BASE Bik_imag = CONST_IMAG(B, i * ldb + k); const BASE Ajk_real = CONST_REAL(A, j * lda + k); const BASE Ajk_imag = CONST_IMAG(A, j * lda + k); const BASE Bjk_real = CONST_REAL(B, j * ldb + k); const BASE Bjk_imag = CONST_IMAG(B, j * ldb + k); temp_real += ((Aik_real * Bjk_real - Aik_imag * Bjk_imag) + (Bik_real * Ajk_real - Bik_imag * Ajk_imag)); temp_imag += ((Aik_real * Bjk_imag + Aik_imag * Bjk_real) + (Bik_real * Ajk_imag + Bik_imag * Ajk_real)); } REAL(C, i * ldc + j) += alpha_real * temp_real - alpha_imag * temp_imag; IMAG(C, i * ldc + j) += alpha_real * temp_imag + alpha_imag * temp_real; } } } else if (uplo == CblasLower && trans == CblasTrans) { for (k = 0; k < K; k++) { for (i = 0; i < N; i++) { BASE Aki_real = CONST_REAL(A, k * lda + i); BASE Aki_imag = CONST_IMAG(A, k * lda + i); BASE Bki_real = CONST_REAL(B, k * ldb + i); BASE Bki_imag = CONST_IMAG(B, k * ldb + i); BASE temp1_real = alpha_real * Aki_real - alpha_imag * Aki_imag; BASE temp1_imag = alpha_real * Aki_imag + alpha_imag * Aki_real; BASE temp2_real = alpha_real * Bki_real - alpha_imag * Bki_imag; BASE temp2_imag = alpha_real * Bki_imag + alpha_imag * Bki_real; for (j = 0; j <= i; j++) { BASE Akj_real = CONST_REAL(A, k * lda + j); BASE Akj_imag = CONST_IMAG(A, k * lda + j); BASE Bkj_real = CONST_REAL(B, k * ldb + j); BASE Bkj_imag = CONST_IMAG(B, k * ldb + j); REAL(C, i * lda + j) += (temp1_real * Bkj_real - temp1_imag * Bkj_imag) + (temp2_real * Akj_real - temp2_imag * Akj_imag); IMAG(C, i * lda + j) += (temp1_real * Bkj_imag + temp1_imag * Bkj_real) + (temp2_real * Akj_imag + temp2_imag * Akj_real); } } } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_syr2k_r.h000066400000000000000000000064121261542461700226260ustar00rootroot00000000000000/* blas/source_syr2k_r.h * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j, k; int uplo, trans; if (alpha == 0.0 && beta == 1.0) return; if (Order == CblasRowMajor) { uplo = Uplo; trans = (Trans == CblasConjTrans) ? CblasTrans : Trans; } else { uplo = (Uplo == CblasUpper) ? CblasLower : CblasUpper; if (Trans == CblasTrans || Trans == CblasConjTrans) { trans = CblasNoTrans; } else { trans = CblasTrans; } } /* form C := beta*C */ if (beta == 0.0) { if (uplo == CblasUpper) { for (i = 0; i < N; i++) { for (j = i; j < N; j++) { C[ldc * i + j] = 0.0; } } } else { for (i = 0; i < N; i++) { for (j = 0; j <= i; j++) { C[ldc * i + j] = 0.0; } } } } else if (beta != 1.0) { if (uplo == CblasUpper) { for (i = 0; i < N; i++) { for (j = i; j < N; j++) { C[ldc * i + j] *= beta; } } } else { for (i = 0; i < N; i++) { for (j = 0; j <= i; j++) { C[ldc * i + j] *= beta; } } } } if (alpha == 0.0) return; if (uplo == CblasUpper && trans == CblasNoTrans) { for (i = 0; i < N; i++) { for (j = i; j < N; j++) { BASE temp = 0.0; for (k = 0; k < K; k++) { temp += (A[i * lda + k] * B[j * ldb + k] + B[i * ldb + k] * A[j * lda + k]); } C[i * ldc + j] += alpha * temp; } } } else if (uplo == CblasUpper && trans == CblasTrans) { for (k = 0; k < K; k++) { for (i = 0; i < N; i++) { BASE temp1 = alpha * A[k * lda + i]; BASE temp2 = alpha * B[k * ldb + i]; for (j = i; j < N; j++) { C[i * lda + j] += temp1 * B[k * ldb + j] + temp2 * A[k * lda + j]; } } } } else if (uplo == CblasLower && trans == CblasNoTrans) { for (i = 0; i < N; i++) { for (j = 0; j <= i; j++) { BASE temp = 0.0; for (k = 0; k < K; k++) { temp += (A[i * lda + k] * B[j * ldb + k] + B[i * ldb + k] * A[j * lda + k]); } C[i * ldc + j] += alpha * temp; } } } else if (uplo == CblasLower && trans == CblasTrans) { for (k = 0; k < K; k++) { for (i = 0; i < N; i++) { BASE temp1 = alpha * A[k * lda + i]; BASE temp2 = alpha * B[k * ldb + i]; for (j = 0; j <= i; j++) { C[i * lda + j] += temp1 * B[k * ldb + j] + temp2 * A[k * lda + j]; } } } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_syrk_c.h000066400000000000000000000134521261542461700225270ustar00rootroot00000000000000/* blas/source_syrk_r.h * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j, k; int uplo, trans; const BASE alpha_real = CONST_REAL0(alpha); const BASE alpha_imag = CONST_IMAG0(alpha); const BASE beta_real = CONST_REAL0(beta); const BASE beta_imag = CONST_IMAG0(beta); if ((alpha_real == 0.0 && alpha_imag == 0.0) && (beta_real == 1.0 && beta_imag == 0.0)) return; if (Order == CblasRowMajor) { uplo = Uplo; /* FIXME: original blas does not make distinction between Trans and ConjTrans?? */ trans = (Trans == CblasNoTrans) ? CblasNoTrans : CblasTrans; } else { uplo = (Uplo == CblasUpper) ? CblasLower : CblasUpper; trans = (Trans == CblasNoTrans) ? CblasTrans : CblasNoTrans; } /* form y := beta*y */ if (beta_real == 0.0 && beta_imag == 0.0) { if (uplo == CblasUpper) { for (i = 0; i < N; i++) { for (j = i; j < N; j++) { REAL(C, ldc * i + j) = 0.0; IMAG(C, ldc * i + j) = 0.0; } } } else { for (i = 0; i < N; i++) { for (j = 0; j <= i; j++) { REAL(C, ldc * i + j) = 0.0; IMAG(C, ldc * i + j) = 0.0; } } } } else if (!(beta_real == 1.0 && beta_imag == 0.0)) { if (uplo == CblasUpper) { for (i = 0; i < N; i++) { for (j = i; j < N; j++) { const BASE Cij_real = REAL(C, ldc * i + j); const BASE Cij_imag = IMAG(C, ldc * i + j); REAL(C, ldc * i + j) = beta_real * Cij_real - beta_imag * Cij_imag; IMAG(C, ldc * i + j) = beta_real * Cij_imag + beta_imag * Cij_real; } } } else { for (i = 0; i < N; i++) { for (j = 0; j <= i; j++) { const BASE Cij_real = REAL(C, ldc * i + j); const BASE Cij_imag = IMAG(C, ldc * i + j); REAL(C, ldc * i + j) = beta_real * Cij_real - beta_imag * Cij_imag; IMAG(C, ldc * i + j) = beta_real * Cij_imag + beta_imag * Cij_real; } } } } if (alpha_real == 0.0 && alpha_imag == 0.0) return; if (uplo == CblasUpper && trans == CblasNoTrans) { for (i = 0; i < N; i++) { for (j = i; j < N; j++) { BASE temp_real = 0.0; BASE temp_imag = 0.0; for (k = 0; k < K; k++) { const BASE Aik_real = CONST_REAL(A, i * lda + k); const BASE Aik_imag = CONST_IMAG(A, i * lda + k); const BASE Ajk_real = CONST_REAL(A, j * lda + k); const BASE Ajk_imag = CONST_IMAG(A, j * lda + k); temp_real += Aik_real * Ajk_real - Aik_imag * Ajk_imag; temp_imag += Aik_real * Ajk_imag + Aik_imag * Ajk_real; } REAL(C, i * ldc + j) += alpha_real * temp_real - alpha_imag * temp_imag; IMAG(C, i * ldc + j) += alpha_real * temp_imag + alpha_imag * temp_real; } } } else if (uplo == CblasUpper && trans == CblasTrans) { for (i = 0; i < N; i++) { for (j = i; j < N; j++) { BASE temp_real = 0.0; BASE temp_imag = 0.0; for (k = 0; k < K; k++) { const BASE Aki_real = CONST_REAL(A, k * lda + i); const BASE Aki_imag = CONST_IMAG(A, k * lda + i); const BASE Akj_real = CONST_REAL(A, k * lda + j); const BASE Akj_imag = CONST_IMAG(A, k * lda + j); temp_real += Aki_real * Akj_real - Aki_imag * Akj_imag; temp_imag += Aki_real * Akj_imag + Aki_imag * Akj_real; } REAL(C, i * ldc + j) += alpha_real * temp_real - alpha_imag * temp_imag; IMAG(C, i * ldc + j) += alpha_real * temp_imag + alpha_imag * temp_real; } } } else if (uplo == CblasLower && trans == CblasNoTrans) { for (i = 0; i < N; i++) { for (j = 0; j <= i; j++) { BASE temp_real = 0.0; BASE temp_imag = 0.0; for (k = 0; k < K; k++) { const BASE Aik_real = CONST_REAL(A, i * lda + k); const BASE Aik_imag = CONST_IMAG(A, i * lda + k); const BASE Ajk_real = CONST_REAL(A, j * lda + k); const BASE Ajk_imag = CONST_IMAG(A, j * lda + k); temp_real += Aik_real * Ajk_real - Aik_imag * Ajk_imag; temp_imag += Aik_real * Ajk_imag + Aik_imag * Ajk_real; } REAL(C, i * ldc + j) += alpha_real * temp_real - alpha_imag * temp_imag; IMAG(C, i * ldc + j) += alpha_real * temp_imag + alpha_imag * temp_real; } } } else if (uplo == CblasLower && trans == CblasTrans) { for (i = 0; i < N; i++) { for (j = 0; j <= i; j++) { BASE temp_real = 0.0; BASE temp_imag = 0.0; for (k = 0; k < K; k++) { const BASE Aki_real = CONST_REAL(A, k * lda + i); const BASE Aki_imag = CONST_IMAG(A, k * lda + i); const BASE Akj_real = CONST_REAL(A, k * lda + j); const BASE Akj_imag = CONST_IMAG(A, k * lda + j); temp_real += Aki_real * Akj_real - Aki_imag * Akj_imag; temp_imag += Aki_real * Akj_imag + Aki_imag * Akj_real; } REAL(C, i * ldc + j) += alpha_real * temp_real - alpha_imag * temp_imag; IMAG(C, i * ldc + j) += alpha_real * temp_imag + alpha_imag * temp_real; } } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_syrk_r.h000066400000000000000000000060631261542461700225460ustar00rootroot00000000000000/* blas/source_syrk_r.h * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j, k; int uplo, trans; if (alpha == 0.0 && beta == 1.0) return; if (Order == CblasRowMajor) { uplo = Uplo; trans = (Trans == CblasConjTrans) ? CblasTrans : Trans; } else { uplo = (Uplo == CblasUpper) ? CblasLower : CblasUpper; if (Trans == CblasTrans || Trans == CblasConjTrans) { trans = CblasNoTrans; } else { trans = CblasTrans; } } /* form y := beta*y */ if (beta == 0.0) { if (uplo == CblasUpper) { for (i = 0; i < N; i++) { for (j = i; j < N; j++) { C[ldc * i + j] = 0.0; } } } else { for (i = 0; i < N; i++) { for (j = 0; j <= i; j++) { C[ldc * i + j] = 0.0; } } } } else if (beta != 1.0) { if (uplo == CblasUpper) { for (i = 0; i < N; i++) { for (j = i; j < N; j++) { C[ldc * i + j] *= beta; } } } else { for (i = 0; i < N; i++) { for (j = 0; j <= i; j++) { C[ldc * i + j] *= beta; } } } } if (alpha == 0.0) return; if (uplo == CblasUpper && trans == CblasNoTrans) { for (i = 0; i < N; i++) { for (j = i; j < N; j++) { BASE temp = 0.0; for (k = 0; k < K; k++) { temp += A[i * lda + k] * A[j * lda + k]; } C[i * ldc + j] += alpha * temp; } } } else if (uplo == CblasUpper && trans == CblasTrans) { for (i = 0; i < N; i++) { for (j = i; j < N; j++) { BASE temp = 0.0; for (k = 0; k < K; k++) { temp += A[k * lda + i] * A[k * lda + j]; } C[i * ldc + j] += alpha * temp; } } } else if (uplo == CblasLower && trans == CblasNoTrans) { for (i = 0; i < N; i++) { for (j = 0; j <= i; j++) { BASE temp = 0.0; for (k = 0; k < K; k++) { temp += A[i * lda + k] * A[j * lda + k]; } C[i * ldc + j] += alpha * temp; } } } else if (uplo == CblasLower && trans == CblasTrans) { for (i = 0; i < N; i++) { for (j = 0; j <= i; j++) { BASE temp = 0.0; for (k = 0; k < K; k++) { temp += A[k * lda + i] * A[k * lda + j]; } C[i * ldc + j] += alpha * temp; } } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_tbmv_c.h000066400000000000000000000142271261542461700225100ustar00rootroot00000000000000/* blas/source_tbmv_c.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { const int conj = (TransA == CblasConjTrans) ? -1 : 1; const int Trans = (TransA != CblasConjTrans) ? TransA : CblasTrans; const int nonunit = (Diag == CblasNonUnit); INDEX i, j; if ((order == CblasRowMajor && Trans == CblasNoTrans && Uplo == CblasUpper) || (order == CblasColMajor && Trans == CblasTrans && Uplo == CblasLower)) { /* form x := A*x */ INDEX ix = OFFSET(N, incX); for (i = 0; i < N; i++) { BASE temp_r = 0.0; BASE temp_i = 0.0; const INDEX j_min = i + 1; const INDEX j_max = GSL_MIN(N, i + K + 1); INDEX jx = OFFSET(N, incX) + incX * j_min; for (j = j_min; j < j_max; j++) { const BASE x_real = REAL(X, jx); const BASE x_imag = IMAG(X, jx); const BASE A_real = CONST_REAL(A, lda * i + (j - i)); const BASE A_imag = conj * CONST_IMAG(A, lda * i + (j - i)); temp_r += A_real * x_real - A_imag * x_imag; temp_i += A_real * x_imag + A_imag * x_real; jx += incX; } if (nonunit) { const BASE x_real = REAL(X, ix); const BASE x_imag = IMAG(X, ix); const BASE A_real = CONST_REAL(A, lda * i + 0); const BASE A_imag = conj * CONST_IMAG(A, lda * i + 0); REAL(X, ix) = temp_r + (A_real * x_real - A_imag * x_imag); IMAG(X, ix) = temp_i + (A_real * x_imag + A_imag * x_real); } else { REAL(X, ix) += temp_r; IMAG(X, ix) += temp_i; } ix += incX; } } else if ((order == CblasRowMajor && Trans == CblasNoTrans && Uplo == CblasLower) || (order == CblasColMajor && Trans == CblasTrans && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX) + (N - 1) * incX; for (i = N; i > 0 && i--;) { /* N-1 ... 0 */ BASE temp_r = 0.0; BASE temp_i = 0.0; const INDEX j_min = (K > i ? 0 : i - K); const INDEX j_max = i; INDEX jx = OFFSET(N, incX) + j_min * incX; for (j = j_min; j < j_max; j++) { const BASE x_real = REAL(X, jx); const BASE x_imag = IMAG(X, jx); const BASE A_real = CONST_REAL(A, lda * i + (K - i + j)); const BASE A_imag = conj * CONST_IMAG(A, lda * i + (K - i + j)); temp_r += A_real * x_real - A_imag * x_imag; temp_i += A_real * x_imag + A_imag * x_real; jx += incX; } if (nonunit) { const BASE x_real = REAL(X, ix); const BASE x_imag = IMAG(X, ix); const BASE A_real = CONST_REAL(A, lda * i + K); const BASE A_imag = conj * CONST_IMAG(A, lda * i + K); REAL(X, ix) = temp_r + (A_real * x_real - A_imag * x_imag); IMAG(X, ix) = temp_i + (A_real * x_imag + A_imag * x_real); } else { REAL(X, ix) += temp_r; IMAG(X, ix) += temp_i; } ix -= incX; } } else if ((order == CblasRowMajor && Trans == CblasTrans && Uplo == CblasUpper) || (order == CblasColMajor && Trans == CblasNoTrans && Uplo == CblasLower)) { /* form x := A'*x */ INDEX ix = OFFSET(N, incX) + (N - 1) * incX; for (i = N; i > 0 && i--;) { /* N-1 ... 0 */ BASE temp_r = 0.0; BASE temp_i = 0.0; const INDEX j_min = (K > i ? 0 : i - K); const INDEX j_max = i; INDEX jx = OFFSET(N, incX) + j_min * incX; for (j = j_min; j < j_max; j++) { const BASE x_real = REAL(X, jx); const BASE x_imag = IMAG(X, jx); const BASE A_real = CONST_REAL(A, lda * j + (i - j)); const BASE A_imag = conj * CONST_IMAG(A, lda * j + (i - j)); temp_r += A_real * x_real - A_imag * x_imag; temp_i += A_real * x_imag + A_imag * x_real; jx += incX; } if (nonunit) { const BASE x_real = REAL(X, ix); const BASE x_imag = IMAG(X, ix); const BASE A_real = CONST_REAL(A, lda * i + 0); const BASE A_imag = conj * CONST_IMAG(A, lda * i + 0); REAL(X, ix) = temp_r + (A_real * x_real - A_imag * x_imag); IMAG(X, ix) = temp_i + (A_real * x_imag + A_imag * x_real); } else { REAL(X, ix) += temp_r; IMAG(X, ix) += temp_i; } ix -= incX; } } else if ((order == CblasRowMajor && Trans == CblasTrans && Uplo == CblasLower) || (order == CblasColMajor && Trans == CblasNoTrans && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX); for (i = 0; i < N; i++) { BASE temp_r = 0.0; BASE temp_i = 0.0; const INDEX j_min = i + 1; const INDEX j_max = GSL_MIN(N, i + K + 1); INDEX jx = OFFSET(N, incX) + j_min * incX; for (j = j_min; j < j_max; j++) { const BASE x_real = REAL(X, jx); const BASE x_imag = IMAG(X, jx); const BASE A_real = CONST_REAL(A, lda * j + (K - j + i)); const BASE A_imag = conj * CONST_IMAG(A, lda * j + (K - j + i)); temp_r += A_real * x_real - A_imag * x_imag; temp_i += A_real * x_imag + A_imag * x_real; jx += incX; } if (nonunit) { const BASE x_real = REAL(X, ix); const BASE x_imag = IMAG(X, ix); const BASE A_real = CONST_REAL(A, lda * i + K); const BASE A_imag = conj * CONST_IMAG(A, lda * i + K); REAL(X, ix) = temp_r + (A_real * x_real - A_imag * x_imag); IMAG(X, ix) = temp_i + (A_real * x_imag + A_imag * x_real); } else { REAL(X, ix) += temp_r; IMAG(X, ix) += temp_i; } ix += incX; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_tbmv_r.h000066400000000000000000000066761261542461700225400ustar00rootroot00000000000000/* blas/source_tbmv_r.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j; const int nonunit = (Diag == CblasNonUnit); const int Trans = (TransA != CblasConjTrans) ? TransA : CblasTrans; if (N == 0) return; if ((order == CblasRowMajor && Trans == CblasNoTrans && Uplo == CblasUpper) || (order == CblasColMajor && Trans == CblasTrans && Uplo == CblasLower)) { /* form x := A*x */ INDEX ix = OFFSET(N, incX); for (i = 0; i < N; i++) { BASE temp = (nonunit ? A[lda * i + 0] : 1.0) * X[ix]; const INDEX j_min = i + 1; const INDEX j_max = GSL_MIN(N, i + K + 1); INDEX jx = OFFSET(N, incX) + j_min * incX; for (j = j_min; j < j_max; j++) { temp += X[jx] * A[lda * i + (j - i)]; jx += incX; } X[ix] = temp; ix += incX; } } else if ((order == CblasRowMajor && Trans == CblasNoTrans && Uplo == CblasLower) || (order == CblasColMajor && Trans == CblasTrans && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX) + (N - 1) * incX; for (i = N; i > 0 && i--;) { BASE temp = (nonunit ? A[lda * i + K] : 1.0) * X[ix]; const INDEX j_min = (i > K ? i - K : 0); const INDEX j_max = i; INDEX jx = OFFSET(N, incX) + j_min * incX; for (j = j_min; j < j_max; j++) { temp += X[jx] * A[lda * i + (K - i + j)]; jx += incX; } X[ix] = temp; ix -= incX; } } else if ((order == CblasRowMajor && Trans == CblasTrans && Uplo == CblasUpper) || (order == CblasColMajor && Trans == CblasNoTrans && Uplo == CblasLower)) { /* form x := A'*x */ INDEX ix = OFFSET(N, incX) + (N - 1) * incX; for (i = N; i > 0 && i--;) { BASE temp = 0.0; const INDEX j_min = (K > i ? 0 : i - K); const INDEX j_max = i; INDEX jx = OFFSET(N, incX) + j_min * incX; for (j = j_min; j < j_max; j++) { temp += X[jx] * A[lda * j + (i - j)]; jx += incX; } if (nonunit) { X[ix] = temp + X[ix] * A[lda * i + 0]; } else { X[ix] += temp; } ix -= incX; } } else if ((order == CblasRowMajor && Trans == CblasTrans && Uplo == CblasLower) || (order == CblasColMajor && Trans == CblasNoTrans && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX); for (i = 0; i < N; i++) { BASE temp = 0.0; const INDEX j_min = i + 1; const INDEX j_max = GSL_MIN(N, i + K + 1); INDEX jx = OFFSET(N, incX) + j_min * incX; for (j = j_min; j < j_max; j++) { temp += X[jx] * A[lda * j + (K - j + i)]; jx += incX; } if (nonunit) { X[ix] = temp + X[ix] * A[lda * i + K]; } else { X[ix] += temp; } ix += incX; } } } praat-6.0.04/external/gsl/gsl_cblas__source_tbsv_c.h000066400000000000000000000150511261542461700225120ustar00rootroot00000000000000/* blas/source_tbsv_c.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { const int conj = (TransA == CblasConjTrans) ? -1 : 1; const int Trans = (TransA != CblasConjTrans) ? TransA : CblasTrans; const int nonunit = (Diag == CblasNonUnit); INDEX i, j; if (N == 0) return; /* form x := inv( A )*x */ if ((order == CblasRowMajor && Trans == CblasNoTrans && Uplo == CblasUpper) || (order == CblasColMajor && Trans == CblasTrans && Uplo == CblasLower)) { INDEX ix = OFFSET(N, incX) + incX * (N - 1); for (i = N; i > 0 && i--;) { BASE tmp_real = REAL(X, ix); BASE tmp_imag = IMAG(X, ix); const INDEX j_min = i + 1; const INDEX j_max = GSL_MIN(N, i + K + 1); INDEX jx = OFFSET(N, incX) + j_min * incX; for (j = j_min; j < j_max; j++) { const BASE Aij_real = CONST_REAL(A, lda * i + (j - i)); const BASE Aij_imag = conj * CONST_IMAG(A, lda * i + (j - i)); const BASE x_real = REAL(X, jx); const BASE x_imag = IMAG(X, jx); tmp_real -= Aij_real * x_real - Aij_imag * x_imag; tmp_imag -= Aij_real * x_imag + Aij_imag * x_real; jx += incX; } if (nonunit) { const BASE a_real = CONST_REAL(A, lda * i + 0); const BASE a_imag = conj * CONST_IMAG(A, lda * i + 0); const BASE s = xhypot(a_real, a_imag); const BASE b_real = a_real / s; const BASE b_imag = a_imag / s; REAL(X, ix) = (tmp_real * b_real + tmp_imag * b_imag) / s; IMAG(X, ix) = (tmp_imag * b_real - tmp_real * b_imag) / s; } else { REAL(X, ix) = tmp_real; IMAG(X, ix) = tmp_imag; } ix -= incX; } } else if ((order == CblasRowMajor && Trans == CblasNoTrans && Uplo == CblasLower) || (order == CblasColMajor && Trans == CblasTrans && Uplo == CblasUpper)) { /* forward substitution */ INDEX ix = OFFSET(N, incX); for (i = 0; i < N; i++) { BASE tmp_real = REAL(X, ix); BASE tmp_imag = IMAG(X, ix); const INDEX j_min = (K > i ? 0 : i - K); const INDEX j_max = i; INDEX jx = OFFSET(N, incX) + j_min * incX; for (j = j_min; j < j_max; j++) { const BASE Aij_real = CONST_REAL(A, lda * i + (K + j - i)); const BASE Aij_imag = conj * CONST_IMAG(A, lda * i + (K + j - i)); const BASE x_real = REAL(X, jx); const BASE x_imag = IMAG(X, jx); tmp_real -= Aij_real * x_real - Aij_imag * x_imag; tmp_imag -= Aij_real * x_imag + Aij_imag * x_real; jx += incX; } if (nonunit) { const BASE a_real = CONST_REAL(A, lda * i + K); const BASE a_imag = conj * CONST_IMAG(A, lda * i + K); const BASE s = xhypot(a_real, a_imag); const BASE b_real = a_real / s; const BASE b_imag = a_imag / s; REAL(X, ix) = (tmp_real * b_real + tmp_imag * b_imag) / s; IMAG(X, ix) = (tmp_imag * b_real - tmp_real * b_imag) / s; } else { REAL(X, ix) = tmp_real; IMAG(X, ix) = tmp_imag; } ix += incX; } } else if ((order == CblasRowMajor && Trans == CblasTrans && Uplo == CblasUpper) || (order == CblasColMajor && Trans == CblasNoTrans && Uplo == CblasLower)) { /* form x := inv( A' )*x */ /* forward substitution */ INDEX ix = OFFSET(N, incX); for (i = 0; i < N; i++) { BASE tmp_real = REAL(X, ix); BASE tmp_imag = IMAG(X, ix); const INDEX j_min = (K > i ? 0 : i - K); const INDEX j_max = i; INDEX jx = OFFSET(N, incX) + j_min * incX; for (j = j_min; j < j_max; j++) { const BASE Aij_real = CONST_REAL(A, (i - j) + lda * j); const BASE Aij_imag = conj * CONST_IMAG(A, (i - j) + lda * j); const BASE x_real = REAL(X, jx); const BASE x_imag = IMAG(X, jx); tmp_real -= Aij_real * x_real - Aij_imag * x_imag; tmp_imag -= Aij_real * x_imag + Aij_imag * x_real; jx += incX; } if (nonunit) { const BASE a_real = CONST_REAL(A, 0 + lda * i); const BASE a_imag = conj * CONST_IMAG(A, 0 + lda * i); const BASE s = xhypot(a_real, a_imag); const BASE b_real = a_real / s; const BASE b_imag = a_imag / s; REAL(X, ix) = (tmp_real * b_real + tmp_imag * b_imag) / s; IMAG(X, ix) = (tmp_imag * b_real - tmp_real * b_imag) / s; } else { REAL(X, ix) = tmp_real; IMAG(X, ix) = tmp_imag; } ix += incX; } } else if ((order == CblasRowMajor && Trans == CblasTrans && Uplo == CblasLower) || (order == CblasColMajor && Trans == CblasNoTrans && Uplo == CblasUpper)) { /* backsubstitution */ INDEX ix = OFFSET(N, incX) + incX * (N - 1); for (i = N; i > 0 && i--;) { BASE tmp_real = REAL(X, ix); BASE tmp_imag = IMAG(X, ix); const INDEX j_min = i + 1; const INDEX j_max = GSL_MIN(N, i + K + 1); INDEX jx = OFFSET(N, incX) + j_min * incX; for (j = j_min; j < j_max; j++) { const BASE Aij_real = CONST_REAL(A, (K + i - j) + lda * j); const BASE Aij_imag = conj * CONST_IMAG(A, (K + i - j) + lda * j); const BASE x_real = REAL(X, jx); const BASE x_imag = IMAG(X, jx); tmp_real -= Aij_real * x_real - Aij_imag * x_imag; tmp_imag -= Aij_real * x_imag + Aij_imag * x_real; jx += incX; } if (nonunit) { const BASE a_real = CONST_REAL(A, K + lda * i); const BASE a_imag = conj * CONST_IMAG(A, K + lda * i); const BASE s = xhypot(a_real, a_imag); const BASE b_real = a_real / s; const BASE b_imag = a_imag / s; REAL(X, ix) = (tmp_real * b_real + tmp_imag * b_imag) / s; IMAG(X, ix) = (tmp_imag * b_real - tmp_real * b_imag) / s; } else { REAL(X, ix) = tmp_real; IMAG(X, ix) = tmp_imag; } ix -= incX; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_tbsv_r.h000066400000000000000000000074601261542461700225360ustar00rootroot00000000000000/* blas/source_tbsv_r.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { const int nonunit = (Diag == CblasNonUnit); INDEX i, j; const int Trans = (TransA != CblasConjTrans) ? TransA : CblasTrans; if (N == 0) return; /* form x := inv( A )*x */ if ((order == CblasRowMajor && Trans == CblasNoTrans && Uplo == CblasUpper) || (order == CblasColMajor && Trans == CblasTrans && Uplo == CblasLower)) { /* backsubstitution */ INDEX ix = OFFSET(N, incX) + incX * (N - 1); for (i = N; i > 0 && i--;) { BASE tmp = X[ix]; const INDEX j_min = i + 1; const INDEX j_max = GSL_MIN(N, i + K + 1); INDEX jx = OFFSET(N, incX) + j_min * incX; for (j = j_min; j < j_max; j++) { const BASE Aij = A[lda * i + (j - i)]; tmp -= Aij * X[jx]; jx += incX; } if (nonunit) { X[ix] = tmp / A[lda * i + 0]; } else { X[ix] = tmp; } ix -= incX; } } else if ((order == CblasRowMajor && Trans == CblasNoTrans && Uplo == CblasLower) || (order == CblasColMajor && Trans == CblasTrans && Uplo == CblasUpper)) { /* forward substitution */ INDEX ix = OFFSET(N, incX); for (i = 0; i < N; i++) { BASE tmp = X[ix]; const INDEX j_min = (i > K ? i - K : 0); const INDEX j_max = i; INDEX jx = OFFSET(N, incX) + j_min * incX; for (j = j_min; j < j_max; j++) { const BASE Aij = A[lda * i + (K + j - i)]; tmp -= Aij * X[jx]; jx += incX; } if (nonunit) { X[ix] = tmp / A[lda * i + K]; } else { X[ix] = tmp; } ix += incX; } } else if ((order == CblasRowMajor && Trans == CblasTrans && Uplo == CblasUpper) || (order == CblasColMajor && Trans == CblasNoTrans && Uplo == CblasLower)) { /* form x := inv( A' )*x */ /* forward substitution */ INDEX ix = OFFSET(N, incX); for (i = 0; i < N; i++) { BASE tmp = X[ix]; const INDEX j_min = (K > i ? 0 : i - K); const INDEX j_max = i; INDEX jx = OFFSET(N, incX) + j_min * incX; for (j = j_min; j < j_max; j++) { const BASE Aji = A[(i - j) + lda * j]; tmp -= Aji * X[jx]; jx += incX; } if (nonunit) { X[ix] = tmp / A[0 + lda * i]; } else { X[ix] = tmp; } ix += incX; } } else if ((order == CblasRowMajor && Trans == CblasTrans && Uplo == CblasLower) || (order == CblasColMajor && Trans == CblasNoTrans && Uplo == CblasUpper)) { /* backsubstitution */ INDEX ix = OFFSET(N, incX) + (N - 1) * incX; for (i = N; i > 0 && i--;) { BASE tmp = X[ix]; const INDEX j_min = i + 1; const INDEX j_max = GSL_MIN(N, i + K + 1); INDEX jx = OFFSET(N, incX) + j_min * incX; for (j = j_min; j < j_max; j++) { const BASE Aji = A[(K + i - j) + lda * j]; tmp -= Aji * X[jx]; jx += incX; } if (nonunit) { X[ix] = tmp / A[K + lda * i]; } else { X[ix] = tmp; } ix -= incX; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_tpmv_c.h000066400000000000000000000136121261542461700225230ustar00rootroot00000000000000/* blas/source_tpmv_c.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j; const int conj = (TransA == CblasConjTrans) ? -1 : 1; const int Trans = (TransA != CblasConjTrans) ? TransA : CblasTrans; const int nonunit = (Diag == CblasNonUnit); if ((order == CblasRowMajor && Trans == CblasNoTrans && Uplo == CblasUpper) || (order == CblasColMajor && Trans == CblasTrans && Uplo == CblasLower)) { /* form x:= A*x */ INDEX ix = OFFSET(N, incX); for (i = 0; i < N; i++) { const BASE Aii_real = CONST_REAL(Ap, TPUP(N, i, i)); const BASE Aii_imag = conj * CONST_IMAG(Ap, TPUP(N, i, i)); BASE temp_r; BASE temp_i; if (nonunit) { BASE x_real = REAL(X, ix); BASE x_imag = IMAG(X, ix); temp_r = Aii_real * x_real - Aii_imag * x_imag; temp_i = Aii_real * x_imag + Aii_imag * x_real; } else { temp_r = REAL(X, ix); temp_i = IMAG(X, ix); } { INDEX jx = OFFSET(N, incX) + (i + 1) * incX; for (j = i + 1; j < N; j++) { const BASE Aij_real = CONST_REAL(Ap, TPUP(N, i, j)); const BASE Aij_imag = conj * CONST_IMAG(Ap, TPUP(N, i, j)); BASE x_real = REAL(X, jx); BASE x_imag = IMAG(X, jx); temp_r += Aij_real * x_real - Aij_imag * x_imag; temp_i += Aij_real * x_imag + Aij_imag * x_real; jx += incX; } } REAL(X, ix) = temp_r; IMAG(X, ix) = temp_i; ix += incX; } } else if ((order == CblasRowMajor && Trans == CblasNoTrans && Uplo == CblasLower) || (order == CblasColMajor && Trans == CblasTrans && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX) + incX * (N - 1); for (i = N; i > 0 && i--;) { const BASE Aii_real = CONST_REAL(Ap, TPLO(N, i, i)); const BASE Aii_imag = conj * CONST_IMAG(Ap, TPLO(N, i, i)); BASE temp_r; BASE temp_i; if (nonunit) { BASE x_real = REAL(X, ix); BASE x_imag = IMAG(X, ix); temp_r = Aii_real * x_real - Aii_imag * x_imag; temp_i = Aii_real * x_imag + Aii_imag * x_real; } else { temp_r = REAL(X, ix); temp_i = IMAG(X, ix); } { INDEX jx = OFFSET(N, incX); for (j = 0; j < i; j++) { const BASE Aij_real = CONST_REAL(Ap, TPLO(N, i, j)); const BASE Aij_imag = conj * CONST_IMAG(Ap, TPLO(N, i, j)); BASE x_real = REAL(X, jx); BASE x_imag = IMAG(X, jx); temp_r += Aij_real * x_real - Aij_imag * x_imag; temp_i += Aij_real * x_imag + Aij_imag * x_real; jx += incX; } } REAL(X, ix) = temp_r; IMAG(X, ix) = temp_i; ix -= incX; } } else if ((order == CblasRowMajor && Trans == CblasTrans && Uplo == CblasUpper) || (order == CblasColMajor && Trans == CblasNoTrans && Uplo == CblasLower)) { /* form x := A'*x */ INDEX ix = OFFSET(N, incX) + incX * (N - 1); for (i = N; i > 0 && i--;) { const BASE Aii_real = CONST_REAL(Ap, TPUP(N, i, i)); const BASE Aii_imag = conj * CONST_IMAG(Ap, TPUP(N, i, i)); BASE temp_r; BASE temp_i; if (nonunit) { BASE x_real = REAL(X, ix); BASE x_imag = IMAG(X, ix); temp_r = Aii_real * x_real - Aii_imag * x_imag; temp_i = Aii_real * x_imag + Aii_imag * x_real; } else { temp_r = REAL(X, ix); temp_i = IMAG(X, ix); } { INDEX jx = OFFSET(N, incX); for (j = 0; j < i; j++) { BASE x_real = REAL(X, jx); BASE x_imag = IMAG(X, jx); const BASE Aji_real = CONST_REAL(Ap, TPUP(N, j, i)); const BASE Aji_imag = conj * CONST_IMAG(Ap, TPUP(N, j, i)); temp_r += Aji_real * x_real - Aji_imag * x_imag; temp_i += Aji_real * x_imag + Aji_imag * x_real; jx += incX; } } REAL(X, ix) = temp_r; IMAG(X, ix) = temp_i; ix -= incX; } } else if ((order == CblasRowMajor && Trans == CblasTrans && Uplo == CblasLower) || (order == CblasColMajor && Trans == CblasNoTrans && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX); for (i = 0; i < N; i++) { const BASE Aii_real = CONST_REAL(Ap, TPLO(N, i, i)); const BASE Aii_imag = conj * CONST_IMAG(Ap, TPLO(N, i, i)); BASE temp_r; BASE temp_i; if (nonunit) { BASE x_real = REAL(X, ix); BASE x_imag = IMAG(X, ix); temp_r = Aii_real * x_real - Aii_imag * x_imag; temp_i = Aii_real * x_imag + Aii_imag * x_real; } else { temp_r = REAL(X, ix); temp_i = IMAG(X, ix); } { INDEX jx = OFFSET(N, incX) + (i + 1) * incX; for (j = i + 1; j < N; j++) { BASE x_real = REAL(X, jx); BASE x_imag = IMAG(X, jx); const BASE Aji_real = CONST_REAL(Ap, TPLO(N, j, i)); const BASE Aji_imag = conj * CONST_IMAG(Ap, TPLO(N, j, i)); temp_r += Aji_real * x_real - Aji_imag * x_imag; temp_i += Aji_real * x_imag + Aji_imag * x_real; jx += incX; } } REAL(X, ix) = temp_r; IMAG(X, ix) = temp_i; ix += incX; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_tpmv_r.h000066400000000000000000000063031261542461700225410ustar00rootroot00000000000000/* blas/source_tpmv_r.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j; const int nonunit = (Diag == CblasNonUnit); const int Trans = (TransA != CblasConjTrans) ? TransA : CblasTrans; if (N == 0) return; if ((order == CblasRowMajor && Trans == CblasNoTrans && Uplo == CblasUpper) || (order == CblasColMajor && Trans == CblasTrans && Uplo == CblasLower)) { /* form x:= A*x */ INDEX ix = OFFSET(N, incX); for (i = 0; i < N; i++) { BASE atmp = Ap[TPUP(N, i, i)]; BASE temp = (nonunit ? X[ix] * atmp : X[ix]); INDEX jx = OFFSET(N, incX) + (i + 1) * incX; for (j = i + 1; j < N; j++) { atmp = Ap[TPUP(N, i, j)]; temp += atmp * X[jx]; jx += incX; } X[ix] = temp; ix += incX; } } else if ((order == CblasRowMajor && Trans == CblasNoTrans && Uplo == CblasLower) || (order == CblasColMajor && Trans == CblasTrans && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX) + (N - 1) * incX; for (i = N; i > 0 && i--;) { BASE atmp = Ap[TPLO(N, i, i)]; BASE temp = (nonunit ? X[ix] * atmp : X[ix]); INDEX jx = OFFSET(N, incX); for (j = 0; j < i; j++) { atmp = Ap[TPLO(N, i, j)]; temp += atmp * X[jx]; jx += incX; } X[ix] = temp; ix -= incX; } } else if ((order == CblasRowMajor && Trans == CblasTrans && Uplo == CblasUpper) || (order == CblasColMajor && Trans == CblasNoTrans && Uplo == CblasLower)) { /* form x := A'*x */ INDEX ix = OFFSET(N, incX) + (N - 1) * incX; for (i = N; i > 0 && i--;) { BASE atmp = Ap[TPUP(N, i, i)]; BASE temp = (nonunit ? X[ix] * atmp : X[ix]); INDEX jx = OFFSET(N, incX); for (j = 0; j < i; j++) { atmp = Ap[TPUP(N, j, i)]; temp += atmp * X[jx]; jx += incX; } X[ix] = temp; ix -= incX; } } else if ((order == CblasRowMajor && Trans == CblasTrans && Uplo == CblasLower) || (order == CblasColMajor && Trans == CblasNoTrans && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX); for (i = 0; i < N; i++) { BASE atmp = Ap[TPLO(N, i, i)]; BASE temp = (nonunit ? X[ix] * atmp : X[ix]); INDEX jx = OFFSET(N, incX) + (i + 1) * incX; for (j = i + 1; j < N; j++) { atmp = Ap[TPLO(N, j, i)]; temp += atmp * X[jx]; jx += incX; } X[ix] = temp; ix += incX; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_tpsv_c.h000066400000000000000000000201111261542461700225210ustar00rootroot00000000000000/* blas/source_tpsv_c.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { const int conj = (TransA == CblasConjTrans) ? -1 : 1; const int Trans = (TransA != CblasConjTrans) ? TransA : CblasTrans; const int nonunit = (Diag == CblasNonUnit); INDEX i, j; if (N == 0) return; /* form x := inv( A )*x */ if ((order == CblasRowMajor && Trans == CblasNoTrans && Uplo == CblasUpper) || (order == CblasColMajor && Trans == CblasTrans && Uplo == CblasLower)) { INDEX ix = OFFSET(N, incX) + incX * (N - 1); if (nonunit) { const BASE a_real = CONST_REAL(Ap, TPUP(N, (N - 1), (N - 1))); const BASE a_imag = conj * CONST_IMAG(Ap, TPUP(N, (N - 1), (N - 1))); const BASE x_real = REAL(X, ix); const BASE x_imag = IMAG(X, ix); const BASE s = xhypot(a_real, a_imag); const BASE b_real = a_real / s; const BASE b_imag = a_imag / s; REAL(X, ix) = (x_real * b_real + x_imag * b_imag) / s; IMAG(X, ix) = (x_imag * b_real - b_imag * x_real) / s; } ix -= incX; for (i = N - 1; i > 0 && i--;) { BASE tmp_real = REAL(X, ix); BASE tmp_imag = IMAG(X, ix); INDEX jx = ix + incX; for (j = i + 1; j < N; j++) { const BASE Aij_real = CONST_REAL(Ap, TPUP(N, i, j)); const BASE Aij_imag = conj * CONST_IMAG(Ap, TPUP(N, i, j)); const BASE x_real = REAL(X, jx); const BASE x_imag = IMAG(X, jx); tmp_real -= Aij_real * x_real - Aij_imag * x_imag; tmp_imag -= Aij_real * x_imag + Aij_imag * x_real; jx += incX; } if (nonunit) { const BASE a_real = CONST_REAL(Ap, TPUP(N, i, i)); const BASE a_imag = conj * CONST_IMAG(Ap, TPUP(N, i, i)); const BASE s = xhypot(a_real, a_imag); const BASE b_real = a_real / s; const BASE b_imag = a_imag / s; REAL(X, ix) = (tmp_real * b_real + tmp_imag * b_imag) / s; IMAG(X, ix) = (tmp_imag * b_real - tmp_real * b_imag) / s; } else { REAL(X, ix) = tmp_real; IMAG(X, ix) = tmp_imag; } ix -= incX; } } else if ((order == CblasRowMajor && Trans == CblasNoTrans && Uplo == CblasLower) || (order == CblasColMajor && Trans == CblasTrans && Uplo == CblasUpper)) { /* forward substitution */ INDEX ix = OFFSET(N, incX); if (nonunit) { const BASE a_real = CONST_REAL(Ap, TPLO(N, 0, 0)); const BASE a_imag = conj * CONST_IMAG(Ap, TPLO(N, 0, 0)); const BASE x_real = REAL(X, ix); const BASE x_imag = IMAG(X, ix); const BASE s = xhypot(a_real, a_imag); const BASE b_real = a_real / s; const BASE b_imag = a_imag / s; REAL(X, ix) = (x_real * b_real + x_imag * b_imag) / s; IMAG(X, ix) = (x_imag * b_real - b_imag * x_real) / s; } ix += incX; for (i = 1; i < N; i++) { BASE tmp_real = REAL(X, ix); BASE tmp_imag = IMAG(X, ix); INDEX jx = OFFSET(N, incX); for (j = 0; j < i; j++) { const BASE Aij_real = CONST_REAL(Ap, TPLO(N, i, j)); const BASE Aij_imag = conj * CONST_IMAG(Ap, TPLO(N, i, j)); const BASE x_real = REAL(X, jx); const BASE x_imag = IMAG(X, jx); tmp_real -= Aij_real * x_real - Aij_imag * x_imag; tmp_imag -= Aij_real * x_imag + Aij_imag * x_real; jx += incX; } if (nonunit) { const BASE a_real = CONST_REAL(Ap, TPLO(N, i, i)); const BASE a_imag = conj * CONST_IMAG(Ap, TPLO(N, i, i)); const BASE s = xhypot(a_real, a_imag); const BASE b_real = a_real / s; const BASE b_imag = a_imag / s; REAL(X, ix) = (tmp_real * b_real + tmp_imag * b_imag) / s; IMAG(X, ix) = (tmp_imag * b_real - tmp_real * b_imag) / s; } else { REAL(X, ix) = tmp_real; IMAG(X, ix) = tmp_imag; } ix += incX; } } else if ((order == CblasRowMajor && Trans == CblasTrans && Uplo == CblasUpper) || (order == CblasColMajor && Trans == CblasNoTrans && Uplo == CblasLower)) { /* form x := inv( A' )*x */ /* forward substitution */ INDEX ix = OFFSET(N, incX); if (nonunit) { const BASE a_real = CONST_REAL(Ap, TPUP(N, 0, 0)); const BASE a_imag = conj * CONST_IMAG(Ap, TPUP(N, 0, 0)); const BASE x_real = REAL(X, ix); const BASE x_imag = IMAG(X, ix); const BASE s = xhypot(a_real, a_imag); const BASE b_real = a_real / s; const BASE b_imag = a_imag / s; REAL(X, ix) = (x_real * b_real + x_imag * b_imag) / s; IMAG(X, ix) = (x_imag * b_real - b_imag * x_real) / s; } ix += incX; for (i = 1; i < N; i++) { BASE tmp_real = REAL(X, ix); BASE tmp_imag = IMAG(X, ix); INDEX jx = OFFSET(N, incX); for (j = 0; j < i; j++) { const BASE Aij_real = CONST_REAL(Ap, TPUP(N, j, i)); const BASE Aij_imag = conj * CONST_IMAG(Ap, TPUP(N, j, i)); const BASE x_real = REAL(X, jx); const BASE x_imag = IMAG(X, jx); tmp_real -= Aij_real * x_real - Aij_imag * x_imag; tmp_imag -= Aij_real * x_imag + Aij_imag * x_real; jx += incX; } if (nonunit) { const BASE a_real = CONST_REAL(Ap, TPUP(N, i, i)); const BASE a_imag = conj * CONST_IMAG(Ap, TPUP(N, i, i)); const BASE s = xhypot(a_real, a_imag); const BASE b_real = a_real / s; const BASE b_imag = a_imag / s; REAL(X, ix) = (tmp_real * b_real + tmp_imag * b_imag) / s; IMAG(X, ix) = (tmp_imag * b_real - tmp_real * b_imag) / s; } else { REAL(X, ix) = tmp_real; IMAG(X, ix) = tmp_imag; } ix += incX; } } else if ((order == CblasRowMajor && Trans == CblasTrans && Uplo == CblasLower) || (order == CblasColMajor && Trans == CblasNoTrans && Uplo == CblasUpper)) { /* backsubstitution */ INDEX ix = OFFSET(N, incX) + incX * (N - 1); if (nonunit) { const BASE a_real = CONST_REAL(Ap, TPLO(N, (N - 1), (N - 1))); const BASE a_imag = conj * CONST_IMAG(Ap, TPLO(N, (N - 1), (N - 1))); const BASE x_real = REAL(X, ix); const BASE x_imag = IMAG(X, ix); const BASE s = xhypot(a_real, a_imag); const BASE b_real = a_real / s; const BASE b_imag = a_imag / s; REAL(X, ix) = (x_real * b_real + x_imag * b_imag) / s; IMAG(X, ix) = (x_imag * b_real - b_imag * x_real) / s; } ix -= incX; for (i = N - 1; i > 0 && i--;) { BASE tmp_real = REAL(X, ix); BASE tmp_imag = IMAG(X, ix); INDEX jx = ix + incX; for (j = i + 1; j < N; j++) { const BASE Aij_real = CONST_REAL(Ap, TPLO(N, j, i)); const BASE Aij_imag = conj * CONST_IMAG(Ap, TPLO(N, j, i)); const BASE x_real = REAL(X, jx); const BASE x_imag = IMAG(X, jx); tmp_real -= Aij_real * x_real - Aij_imag * x_imag; tmp_imag -= Aij_real * x_imag + Aij_imag * x_real; jx += incX; } if (nonunit) { const BASE a_real = CONST_REAL(Ap, TPLO(N, i, i)); const BASE a_imag = conj * CONST_IMAG(Ap, TPLO(N, i, i)); const BASE s = xhypot(a_real, a_imag); const BASE b_real = a_real / s; const BASE b_imag = a_imag / s; REAL(X, ix) = (tmp_real * b_real + tmp_imag * b_imag) / s; IMAG(X, ix) = (tmp_imag * b_real - tmp_real * b_imag) / s; } else { REAL(X, ix) = tmp_real; IMAG(X, ix) = tmp_imag; } ix -= incX; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_tpsv_r.h000066400000000000000000000073641261542461700225570ustar00rootroot00000000000000/* blas/source_tpsv_r.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j; const int nonunit = (Diag == CblasNonUnit); const int Trans = (TransA != CblasConjTrans) ? TransA : CblasTrans; if (N == 0) return; /* form x := inv( A )*x */ if ((order == CblasRowMajor && Trans == CblasNoTrans && Uplo == CblasUpper) || (order == CblasColMajor && Trans == CblasTrans && Uplo == CblasLower)) { /* backsubstitution */ INDEX ix = OFFSET(N, incX) + incX * (N - 1); if (nonunit) { X[ix] = X[ix] / Ap[TPUP(N, (N - 1), (N - 1))]; } ix -= incX; for (i = N - 1; i > 0 && i--;) { BASE tmp = X[ix]; INDEX jx = ix + incX; for (j = i + 1; j < N; j++) { const BASE Aij = Ap[TPUP(N, i, j)]; tmp -= Aij * X[jx]; jx += incX; } if (nonunit) { X[ix] = tmp / Ap[TPUP(N, i, i)]; } else { X[ix] = tmp; } ix -= incX; } } else if ((order == CblasRowMajor && Trans == CblasNoTrans && Uplo == CblasLower) || (order == CblasColMajor && Trans == CblasTrans && Uplo == CblasUpper)) { /* forward substitution */ INDEX ix = OFFSET(N, incX); if (nonunit) { X[ix] = X[ix] / Ap[TPLO(N, 0, 0)]; } ix += incX; for (i = 1; i < N; i++) { BASE tmp = X[ix]; INDEX jx = OFFSET(N, incX); for (j = 0; j < i; j++) { const BASE Aij = Ap[TPLO(N, i, j)]; tmp -= Aij * X[jx]; jx += incX; } if (nonunit) { X[ix] = tmp / Ap[TPLO(N, i, j)]; } else { X[ix] = tmp; } ix += incX; } } else if ((order == CblasRowMajor && Trans == CblasTrans && Uplo == CblasUpper) || (order == CblasColMajor && Trans == CblasNoTrans && Uplo == CblasLower)) { /* form x := inv( A' )*x */ /* forward substitution */ INDEX ix = OFFSET(N, incX); if (nonunit) { X[ix] = X[ix] / Ap[TPUP(N, 0, 0)]; } ix += incX; for (i = 1; i < N; i++) { BASE tmp = X[ix]; INDEX jx = OFFSET(N, incX); for (j = 0; j < i; j++) { const BASE Aji = Ap[TPUP(N, j, i)]; tmp -= Aji * X[jx]; jx += incX; } if (nonunit) { X[ix] = tmp / Ap[TPUP(N, i, i)]; } else { X[ix] = tmp; } ix += incX; } } else if ((order == CblasRowMajor && Trans == CblasTrans && Uplo == CblasLower) || (order == CblasColMajor && Trans == CblasNoTrans && Uplo == CblasUpper)) { /* backsubstitution */ INDEX ix = OFFSET(N, incX) + (N - 1) * incX; if (nonunit) { X[ix] = X[ix] / Ap[TPLO(N, (N - 1), (N - 1))]; } ix -= incX; for (i = N - 1; i > 0 && i--;) { BASE tmp = X[ix]; INDEX jx = ix + incX; for (j = i + 1; j < N; j++) { const BASE Aji = Ap[TPLO(N, j, i)]; tmp -= Aji * X[jx]; jx += incX; } if (nonunit) { X[ix] = tmp / Ap[TPLO(N, i, i)]; } else { X[ix] = tmp; } ix -= incX; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_trmm_c.h000066400000000000000000000300301261542461700225050ustar00rootroot00000000000000/* blas/source_trmm_c.h * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j, k; INDEX n1, n2; const int nonunit = (Diag == CblasNonUnit); const int conj = (TransA == CblasConjTrans) ? -1 : 1; int side, uplo, trans; const BASE alpha_real = CONST_REAL0(alpha); const BASE alpha_imag = CONST_IMAG0(alpha); if (Order == CblasRowMajor) { n1 = M; n2 = N; side = Side; uplo = Uplo; trans = (TransA == CblasNoTrans) ? CblasNoTrans : CblasTrans; } else { n1 = N; n2 = M; side = (Side == CblasLeft) ? CblasRight : CblasLeft; /* exchanged */ uplo = (Uplo == CblasUpper) ? CblasLower : CblasUpper; /* exchanged */ trans = (TransA == CblasNoTrans) ? CblasNoTrans : CblasTrans; /* same */ } if (side == CblasLeft && uplo == CblasUpper && trans == CblasNoTrans) { /* form B := alpha * TriU(A)*B */ for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { BASE temp_real = 0.0; BASE temp_imag = 0.0; if (nonunit) { const BASE Aii_real = CONST_REAL(A, i * lda + i); const BASE Aii_imag = conj * CONST_IMAG(A, i * lda + i); const BASE Bij_real = REAL(B, i * ldb + j); const BASE Bij_imag = IMAG(B, i * ldb + j); temp_real = Aii_real * Bij_real - Aii_imag * Bij_imag; temp_imag = Aii_real * Bij_imag + Aii_imag * Bij_real; } else { temp_real = REAL(B, i * ldb + j); temp_imag = IMAG(B, i * ldb + j); } for (k = i + 1; k < n1; k++) { const BASE Aik_real = CONST_REAL(A, i * lda + k); const BASE Aik_imag = conj * CONST_IMAG(A, i * lda + k); const BASE Bkj_real = REAL(B, k * ldb + j); const BASE Bkj_imag = IMAG(B, k * ldb + j); temp_real += Aik_real * Bkj_real - Aik_imag * Bkj_imag; temp_imag += Aik_real * Bkj_imag + Aik_imag * Bkj_real; } REAL(B, ldb * i + j) = alpha_real * temp_real - alpha_imag * temp_imag; IMAG(B, ldb * i + j) = alpha_real * temp_imag + alpha_imag * temp_real; } } } else if (side == CblasLeft && uplo == CblasUpper && trans == CblasTrans) { /* form B := alpha * (TriU(A))' *B */ for (i = n1; i > 0 && i--;) { for (j = 0; j < n2; j++) { BASE temp_real = 0.0; BASE temp_imag = 0.0; for (k = 0; k < i; k++) { const BASE Aki_real = CONST_REAL(A, k * lda + i); const BASE Aki_imag = conj * CONST_IMAG(A, k * lda + i); const BASE Bkj_real = REAL(B, k * ldb + j); const BASE Bkj_imag = IMAG(B, k * ldb + j); temp_real += Aki_real * Bkj_real - Aki_imag * Bkj_imag; temp_imag += Aki_real * Bkj_imag + Aki_imag * Bkj_real; } if (nonunit) { const BASE Aii_real = CONST_REAL(A, i * lda + i); const BASE Aii_imag = conj * CONST_IMAG(A, i * lda + i); const BASE Bij_real = REAL(B, i * ldb + j); const BASE Bij_imag = IMAG(B, i * ldb + j); temp_real += Aii_real * Bij_real - Aii_imag * Bij_imag; temp_imag += Aii_real * Bij_imag + Aii_imag * Bij_real; } else { temp_real += REAL(B, i * ldb + j); temp_imag += IMAG(B, i * ldb + j); } REAL(B, ldb * i + j) = alpha_real * temp_real - alpha_imag * temp_imag; IMAG(B, ldb * i + j) = alpha_real * temp_imag + alpha_imag * temp_real; } } } else if (side == CblasLeft && uplo == CblasLower && trans == CblasNoTrans) { /* form B := alpha * TriL(A)*B */ for (i = n1; i > 0 && i--;) { for (j = 0; j < n2; j++) { BASE temp_real = 0.0; BASE temp_imag = 0.0; for (k = 0; k < i; k++) { const BASE Aik_real = CONST_REAL(A, i * lda + k); const BASE Aik_imag = conj * CONST_IMAG(A, i * lda + k); const BASE Bkj_real = REAL(B, k * ldb + j); const BASE Bkj_imag = IMAG(B, k * ldb + j); temp_real += Aik_real * Bkj_real - Aik_imag * Bkj_imag; temp_imag += Aik_real * Bkj_imag + Aik_imag * Bkj_real; } if (nonunit) { const BASE Aii_real = CONST_REAL(A, i * lda + i); const BASE Aii_imag = conj * CONST_IMAG(A, i * lda + i); const BASE Bij_real = REAL(B, i * ldb + j); const BASE Bij_imag = IMAG(B, i * ldb + j); temp_real += Aii_real * Bij_real - Aii_imag * Bij_imag; temp_imag += Aii_real * Bij_imag + Aii_imag * Bij_real; } else { temp_real += REAL(B, i * ldb + j); temp_imag += IMAG(B, i * ldb + j); } REAL(B, ldb * i + j) = alpha_real * temp_real - alpha_imag * temp_imag; IMAG(B, ldb * i + j) = alpha_real * temp_imag + alpha_imag * temp_real; } } } else if (side == CblasLeft && uplo == CblasLower && trans == CblasTrans) { /* form B := alpha * TriL(A)' *B */ for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { BASE temp_real = 0.0; BASE temp_imag = 0.0; if (nonunit) { const BASE Aii_real = CONST_REAL(A, i * lda + i); const BASE Aii_imag = conj * CONST_IMAG(A, i * lda + i); const BASE Bij_real = REAL(B, i * ldb + j); const BASE Bij_imag = IMAG(B, i * ldb + j); temp_real = Aii_real * Bij_real - Aii_imag * Bij_imag; temp_imag = Aii_real * Bij_imag + Aii_imag * Bij_real; } else { temp_real = REAL(B, i * ldb + j); temp_imag = IMAG(B, i * ldb + j); } for (k = i + 1; k < n1; k++) { const BASE Aki_real = CONST_REAL(A, k * lda + i); const BASE Aki_imag = conj * CONST_IMAG(A, k * lda + i); const BASE Bkj_real = REAL(B, k * ldb + j); const BASE Bkj_imag = IMAG(B, k * ldb + j); temp_real += Aki_real * Bkj_real - Aki_imag * Bkj_imag; temp_imag += Aki_real * Bkj_imag + Aki_imag * Bkj_real; } REAL(B, ldb * i + j) = alpha_real * temp_real - alpha_imag * temp_imag; IMAG(B, ldb * i + j) = alpha_real * temp_imag + alpha_imag * temp_real; } } } else if (side == CblasRight && uplo == CblasUpper && trans == CblasNoTrans) { /* form B := alpha * B * TriU(A) */ for (i = 0; i < n1; i++) { for (j = n2; j > 0 && j--;) { BASE temp_real = 0.0; BASE temp_imag = 0.0; for (k = 0; k < j; k++) { const BASE Akj_real = CONST_REAL(A, k * lda + j); const BASE Akj_imag = conj * CONST_IMAG(A, k * lda + j); const BASE Bik_real = REAL(B, i * ldb + k); const BASE Bik_imag = IMAG(B, i * ldb + k); temp_real += Akj_real * Bik_real - Akj_imag * Bik_imag; temp_imag += Akj_real * Bik_imag + Akj_imag * Bik_real; } if (nonunit) { const BASE Ajj_real = CONST_REAL(A, j * lda + j); const BASE Ajj_imag = conj * CONST_IMAG(A, j * lda + j); const BASE Bij_real = REAL(B, i * ldb + j); const BASE Bij_imag = IMAG(B, i * ldb + j); temp_real += Ajj_real * Bij_real - Ajj_imag * Bij_imag; temp_imag += Ajj_real * Bij_imag + Ajj_imag * Bij_real; } else { temp_real += REAL(B, i * ldb + j); temp_imag += IMAG(B, i * ldb + j); } REAL(B, ldb * i + j) = alpha_real * temp_real - alpha_imag * temp_imag; IMAG(B, ldb * i + j) = alpha_real * temp_imag + alpha_imag * temp_real; } } } else if (side == CblasRight && uplo == CblasUpper && trans == CblasTrans) { /* form B := alpha * B * (TriU(A))' */ for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { BASE temp_real = 0.0; BASE temp_imag = 0.0; if (nonunit) { const BASE Ajj_real = CONST_REAL(A, j * lda + j); const BASE Ajj_imag = conj * CONST_IMAG(A, j * lda + j); const BASE Bij_real = REAL(B, i * ldb + j); const BASE Bij_imag = IMAG(B, i * ldb + j); temp_real = Ajj_real * Bij_real - Ajj_imag * Bij_imag; temp_imag = Ajj_real * Bij_imag + Ajj_imag * Bij_real; } else { temp_real = REAL(B, i * ldb + j); temp_imag = IMAG(B, i * ldb + j); } for (k = j + 1; k < n2; k++) { const BASE Ajk_real = CONST_REAL(A, j * lda + k); const BASE Ajk_imag = conj * CONST_IMAG(A, j * lda + k); const BASE Bik_real = REAL(B, i * ldb + k); const BASE Bik_imag = IMAG(B, i * ldb + k); temp_real += Ajk_real * Bik_real - Ajk_imag * Bik_imag; temp_imag += Ajk_real * Bik_imag + Ajk_imag * Bik_real; } REAL(B, ldb * i + j) = alpha_real * temp_real - alpha_imag * temp_imag; IMAG(B, ldb * i + j) = alpha_real * temp_imag + alpha_imag * temp_real; } } } else if (side == CblasRight && uplo == CblasLower && trans == CblasNoTrans) { /* form B := alpha *B * TriL(A) */ for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { BASE temp_real = 0.0; BASE temp_imag = 0.0; if (nonunit) { const BASE Ajj_real = CONST_REAL(A, j * lda + j); const BASE Ajj_imag = conj * CONST_IMAG(A, j * lda + j); const BASE Bij_real = REAL(B, i * ldb + j); const BASE Bij_imag = IMAG(B, i * ldb + j); temp_real = Ajj_real * Bij_real - Ajj_imag * Bij_imag; temp_imag = Ajj_real * Bij_imag + Ajj_imag * Bij_real; } else { temp_real = REAL(B, i * ldb + j); temp_imag = IMAG(B, i * ldb + j); } for (k = j + 1; k < n2; k++) { const BASE Akj_real = CONST_REAL(A, k * lda + j); const BASE Akj_imag = conj * CONST_IMAG(A, k * lda + j); const BASE Bik_real = REAL(B, i * ldb + k); const BASE Bik_imag = IMAG(B, i * ldb + k); temp_real += Akj_real * Bik_real - Akj_imag * Bik_imag; temp_imag += Akj_real * Bik_imag + Akj_imag * Bik_real; } REAL(B, ldb * i + j) = alpha_real * temp_real - alpha_imag * temp_imag; IMAG(B, ldb * i + j) = alpha_real * temp_imag + alpha_imag * temp_real; } } } else if (side == CblasRight && uplo == CblasLower && trans == CblasTrans) { /* form B := alpha * B * TriL(A)' */ for (i = 0; i < n1; i++) { for (j = n2; j > 0 && j--;) { BASE temp_real = 0.0; BASE temp_imag = 0.0; for (k = 0; k < j; k++) { const BASE Ajk_real = CONST_REAL(A, j * lda + k); const BASE Ajk_imag = conj * CONST_IMAG(A, j * lda + k); const BASE Bik_real = REAL(B, i * ldb + k); const BASE Bik_imag = IMAG(B, i * ldb + k); temp_real += Ajk_real * Bik_real - Ajk_imag * Bik_imag; temp_imag += Ajk_real * Bik_imag + Ajk_imag * Bik_real; } if (nonunit) { const BASE Ajj_real = CONST_REAL(A, j * lda + j); const BASE Ajj_imag = conj * CONST_IMAG(A, j * lda + j); const BASE Bij_real = REAL(B, i * ldb + j); const BASE Bij_imag = IMAG(B, i * ldb + j); temp_real += Ajj_real * Bij_real - Ajj_imag * Bij_imag; temp_imag += Ajj_real * Bij_imag + Ajj_imag * Bij_real; } else { temp_real += REAL(B, i * ldb + j); temp_imag += IMAG(B, i * ldb + j); } REAL(B, ldb * i + j) = alpha_real * temp_real - alpha_imag * temp_imag; IMAG(B, ldb * i + j) = alpha_real * temp_imag + alpha_imag * temp_real; } } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_trmm_r.h000066400000000000000000000123471261542461700225370ustar00rootroot00000000000000/* blas/source_trmm_r.h * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j, k; INDEX n1, n2; const int nonunit = (Diag == CblasNonUnit); int side, uplo, trans; if (Order == CblasRowMajor) { n1 = M; n2 = N; side = Side; uplo = Uplo; trans = (TransA == CblasConjTrans) ? CblasTrans : TransA; } else { n1 = N; n2 = M; side = (Side == CblasLeft) ? CblasRight : CblasLeft; uplo = (Uplo == CblasUpper) ? CblasLower : CblasUpper; trans = (TransA == CblasConjTrans) ? CblasTrans : TransA; } if (side == CblasLeft && uplo == CblasUpper && trans == CblasNoTrans) { /* form B := alpha * TriU(A)*B */ for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { BASE temp = 0.0; if (nonunit) { temp = A[i * lda + i] * B[i * ldb + j]; } else { temp = B[i * ldb + j]; } for (k = i + 1; k < n1; k++) { temp += A[lda * i + k] * B[k * ldb + j]; } B[ldb * i + j] = alpha * temp; } } } else if (side == CblasLeft && uplo == CblasUpper && trans == CblasTrans) { /* form B := alpha * (TriU(A))' *B */ for (i = n1; i > 0 && i--;) { for (j = 0; j < n2; j++) { BASE temp = 0.0; for (k = 0; k < i; k++) { temp += A[lda * k + i] * B[k * ldb + j]; } if (nonunit) { temp += A[i * lda + i] * B[i * ldb + j]; } else { temp += B[i * ldb + j]; } B[ldb * i + j] = alpha * temp; } } } else if (side == CblasLeft && uplo == CblasLower && trans == CblasNoTrans) { /* form B := alpha * TriL(A)*B */ for (i = n1; i > 0 && i--;) { for (j = 0; j < n2; j++) { BASE temp = 0.0; for (k = 0; k < i; k++) { temp += A[lda * i + k] * B[k * ldb + j]; } if (nonunit) { temp += A[i * lda + i] * B[i * ldb + j]; } else { temp += B[i * ldb + j]; } B[ldb * i + j] = alpha * temp; } } } else if (side == CblasLeft && uplo == CblasLower && trans == CblasTrans) { /* form B := alpha * TriL(A)' *B */ for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { BASE temp = 0.0; if (nonunit) { temp = A[i * lda + i] * B[i * ldb + j]; } else { temp = B[i * ldb + j]; } for (k = i + 1; k < n1; k++) { temp += A[lda * k + i] * B[k * ldb + j]; } B[ldb * i + j] = alpha * temp; } } } else if (side == CblasRight && uplo == CblasUpper && trans == CblasNoTrans) { /* form B := alpha * B * TriU(A) */ for (i = 0; i < n1; i++) { for (j = n2; j > 0 && j--;) { BASE temp = 0.0; for (k = 0; k < j; k++) { temp += A[lda * k + j] * B[i * ldb + k]; } if (nonunit) { temp += A[j * lda + j] * B[i * ldb + j]; } else { temp += B[i * ldb + j]; } B[ldb * i + j] = alpha * temp; } } } else if (side == CblasRight && uplo == CblasUpper && trans == CblasTrans) { /* form B := alpha * B * (TriU(A))' */ for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { BASE temp = 0.0; if (nonunit) { temp = A[j * lda + j] * B[i * ldb + j]; } else { temp = B[i * ldb + j]; } for (k = j + 1; k < n2; k++) { temp += A[lda * j + k] * B[i * ldb + k]; } B[ldb * i + j] = alpha * temp; } } } else if (side == CblasRight && uplo == CblasLower && trans == CblasNoTrans) { /* form B := alpha *B * TriL(A) */ for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { BASE temp = 0.0; if (nonunit) { temp = A[j * lda + j] * B[i * ldb + j]; } else { temp = B[i * ldb + j]; } for (k = j + 1; k < n2; k++) { temp += A[lda * k + j] * B[i * ldb + k]; } B[ldb * i + j] = alpha * temp; } } } else if (side == CblasRight && uplo == CblasLower && trans == CblasTrans) { /* form B := alpha * B * TriL(A)' */ for (i = 0; i < n1; i++) { for (j = n2; j > 0 && j--;) { BASE temp = 0.0; for (k = 0; k < j; k++) { temp += A[lda * j + k] * B[i * ldb + k]; } if (nonunit) { temp += A[j * lda + j] * B[i * ldb + j]; } else { temp += B[i * ldb + j]; } B[ldb * i + j] = alpha * temp; } } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_trmv_c.h000066400000000000000000000134731261542461700225320ustar00rootroot00000000000000/* blas/source_tbmv_c.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { const int conj = (TransA == CblasConjTrans) ? -1 : 1; const int Trans = (TransA != CblasConjTrans) ? TransA : CblasTrans; const int nonunit = (Diag == CblasNonUnit); INDEX i, j; if ((order == CblasRowMajor && Trans == CblasNoTrans && Uplo == CblasUpper) || (order == CblasColMajor && Trans == CblasTrans && Uplo == CblasLower)) { /* form x := A*x */ INDEX ix = OFFSET(N, incX); for (i = 0; i < N; i++) { BASE temp_r = 0.0; BASE temp_i = 0.0; const INDEX j_min = i + 1; INDEX jx = OFFSET(N, incX) + incX * j_min; for (j = j_min; j < N; j++) { const BASE x_real = REAL(X, jx); const BASE x_imag = IMAG(X, jx); const BASE A_real = CONST_REAL(A, lda * i + j); const BASE A_imag = conj * CONST_IMAG(A, lda * i + j); temp_r += A_real * x_real - A_imag * x_imag; temp_i += A_real * x_imag + A_imag * x_real; jx += incX; } if (nonunit) { const BASE x_real = REAL(X, ix); const BASE x_imag = IMAG(X, ix); const BASE A_real = CONST_REAL(A, lda * i + i); const BASE A_imag = conj * CONST_IMAG(A, lda * i + i); REAL(X, ix) = temp_r + (A_real * x_real - A_imag * x_imag); IMAG(X, ix) = temp_i + (A_real * x_imag + A_imag * x_real); } else { REAL(X, ix) += temp_r; IMAG(X, ix) += temp_i; } ix += incX; } } else if ((order == CblasRowMajor && Trans == CblasNoTrans && Uplo == CblasLower) || (order == CblasColMajor && Trans == CblasTrans && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX) + (N - 1) * incX; for (i = N; i > 0 && i--;) { BASE temp_r = 0.0; BASE temp_i = 0.0; const INDEX j_max = i; INDEX jx = OFFSET(N, incX); for (j = 0; j < j_max; j++) { const BASE x_real = REAL(X, jx); const BASE x_imag = IMAG(X, jx); const BASE A_real = CONST_REAL(A, lda * i + j); const BASE A_imag = conj * CONST_IMAG(A, lda * i + j); temp_r += A_real * x_real - A_imag * x_imag; temp_i += A_real * x_imag + A_imag * x_real; jx += incX; } if (nonunit) { const BASE x_real = REAL(X, ix); const BASE x_imag = IMAG(X, ix); const BASE A_real = CONST_REAL(A, lda * i + i); const BASE A_imag = conj * CONST_IMAG(A, lda * i + i); REAL(X, ix) = temp_r + (A_real * x_real - A_imag * x_imag); IMAG(X, ix) = temp_i + (A_real * x_imag + A_imag * x_real); } else { REAL(X, ix) += temp_r; IMAG(X, ix) += temp_i; } ix -= incX; } } else if ((order == CblasRowMajor && Trans == CblasTrans && Uplo == CblasUpper) || (order == CblasColMajor && Trans == CblasNoTrans && Uplo == CblasLower)) { /* form x := A'*x */ INDEX ix = OFFSET(N, incX) + (N - 1) * incX; for (i = N; i > 0 && i--;) { BASE temp_r = 0.0; BASE temp_i = 0.0; const INDEX j_max = i; INDEX jx = OFFSET(N, incX); for (j = 0; j < j_max; j++) { const BASE x_real = REAL(X, jx); const BASE x_imag = IMAG(X, jx); const BASE A_real = CONST_REAL(A, lda * j + i); const BASE A_imag = conj * CONST_IMAG(A, lda * j + i); temp_r += A_real * x_real - A_imag * x_imag; temp_i += A_real * x_imag + A_imag * x_real; jx += incX; } if (nonunit) { const BASE x_real = REAL(X, ix); const BASE x_imag = IMAG(X, ix); const BASE A_real = CONST_REAL(A, lda * i + i); const BASE A_imag = conj * CONST_IMAG(A, lda * i + i); REAL(X, ix) = temp_r + (A_real * x_real - A_imag * x_imag); IMAG(X, ix) = temp_i + (A_real * x_imag + A_imag * x_real); } else { REAL(X, ix) += temp_r; IMAG(X, ix) += temp_i; } ix -= incX; } } else if ((order == CblasRowMajor && Trans == CblasTrans && Uplo == CblasLower) || (order == CblasColMajor && Trans == CblasNoTrans && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX); for (i = 0; i < N; i++) { BASE temp_r = 0.0; BASE temp_i = 0.0; const INDEX j_min = i + 1; INDEX jx = OFFSET(N, incX) + j_min * incX; for (j = j_min; j < N; j++) { const BASE x_real = REAL(X, jx); const BASE x_imag = IMAG(X, jx); const BASE A_real = CONST_REAL(A, lda * j + i); const BASE A_imag = conj * CONST_IMAG(A, lda * j + i); temp_r += A_real * x_real - A_imag * x_imag; temp_i += A_real * x_imag + A_imag * x_real; jx += incX; } if (nonunit) { const BASE x_real = REAL(X, ix); const BASE x_imag = IMAG(X, ix); const BASE A_real = CONST_REAL(A, lda * i + i); const BASE A_imag = conj * CONST_IMAG(A, lda * i + i); REAL(X, ix) = temp_r + (A_real * x_real - A_imag * x_imag); IMAG(X, ix) = temp_i + (A_real * x_imag + A_imag * x_real); } else { REAL(X, ix) += temp_r; IMAG(X, ix) += temp_i; } ix += incX; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_trmv_r.h000066400000000000000000000067321261542461700225510ustar00rootroot00000000000000/* blas/source_trmv_r.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j; const int nonunit = (Diag == CblasNonUnit); const int Trans = (TransA != CblasConjTrans) ? TransA : CblasTrans; if ((order == CblasRowMajor && Trans == CblasNoTrans && Uplo == CblasUpper) || (order == CblasColMajor && Trans == CblasTrans && Uplo == CblasLower)) { /* form x := A*x */ INDEX ix = OFFSET(N, incX); for (i = 0; i < N; i++) { BASE temp = 0.0; const INDEX j_min = i + 1; const INDEX j_max = N; INDEX jx = OFFSET(N, incX) + j_min * incX; for (j = j_min; j < j_max; j++) { temp += X[jx] * A[lda * i + j]; jx += incX; } if (nonunit) { X[ix] = temp + X[ix] * A[lda * i + i]; } else { X[ix] += temp; } ix += incX; } } else if ((order == CblasRowMajor && Trans == CblasNoTrans && Uplo == CblasLower) || (order == CblasColMajor && Trans == CblasTrans && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX) + (N - 1) * incX; for (i = N; i > 0 && i--;) { BASE temp = 0.0; const INDEX j_min = 0; const INDEX j_max = i; INDEX jx = OFFSET(N, incX) + j_min * incX; for (j = j_min; j < j_max; j++) { temp += X[jx] * A[lda * i + j]; jx += incX; } if (nonunit) { X[ix] = temp + X[ix] * A[lda * i + i]; } else { X[ix] += temp; } ix -= incX; } } else if ((order == CblasRowMajor && Trans == CblasTrans && Uplo == CblasUpper) || (order == CblasColMajor && Trans == CblasNoTrans && Uplo == CblasLower)) { /* form x := A'*x */ INDEX ix = OFFSET(N, incX) + (N - 1) * incX; for (i = N; i > 0 && i--;) { BASE temp = 0.0; const INDEX j_min = 0; const INDEX j_max = i; INDEX jx = OFFSET(N, incX) + j_min * incX; for (j = j_min; j < j_max; j++) { temp += X[jx] * A[lda * j + i]; jx += incX; } if (nonunit) { X[ix] = temp + X[ix] * A[lda * i + i]; } else { X[ix] += temp; } ix -= incX; } } else if ((order == CblasRowMajor && Trans == CblasTrans && Uplo == CblasLower) || (order == CblasColMajor && Trans == CblasNoTrans && Uplo == CblasUpper)) { INDEX ix = OFFSET(N, incX); for (i = 0; i < N; i++) { BASE temp = 0.0; const INDEX j_min = i + 1; const INDEX j_max = N; INDEX jx = OFFSET(N, incX) + (i + 1) * incX; for (j = j_min; j < j_max; j++) { temp += X[jx] * A[lda * j + i]; jx += incX; } if (nonunit) { X[ix] = temp + X[ix] * A[lda * i + i]; } else { X[ix] += temp; } ix += incX; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_trsm_c.h000066400000000000000000000347231261542461700225300ustar00rootroot00000000000000/* blas/source_trsm_c.h * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j, k; INDEX n1, n2; const int nonunit = (Diag == CblasNonUnit); const int conj = (TransA == CblasConjTrans) ? -1 : 1; int side, uplo, trans; const BASE alpha_real = CONST_REAL0(alpha); const BASE alpha_imag = CONST_IMAG0(alpha); if (Order == CblasRowMajor) { n1 = M; n2 = N; side = Side; uplo = Uplo; trans = TransA; trans = (TransA == CblasNoTrans) ? CblasNoTrans : CblasTrans; } else { n1 = N; n2 = M; side = (Side == CblasLeft) ? CblasRight : CblasLeft; /* exchanged */ uplo = (Uplo == CblasUpper) ? CblasLower : CblasUpper; /* exchanged */ trans = (TransA == CblasNoTrans) ? CblasNoTrans : CblasTrans; /* same */ } if (side == CblasLeft && uplo == CblasUpper && trans == CblasNoTrans) { /* form B := alpha * inv(TriU(A)) *B */ if (!(alpha_real == 1.0 && alpha_imag == 0.0)) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { const BASE Bij_real = REAL(B, ldb * i + j); const BASE Bij_imag = IMAG(B, ldb * i + j); REAL(B, ldb * i + j) = alpha_real * Bij_real - alpha_imag * Bij_imag; IMAG(B, ldb * i + j) = alpha_real * Bij_imag + alpha_imag * Bij_real; } } } for (i = n1; i > 0 && i--;) { if (nonunit) { const BASE Aii_real = CONST_REAL(A, lda * i + i); const BASE Aii_imag = conj * CONST_IMAG(A, lda * i + i); const BASE s = xhypot(Aii_real, Aii_imag); const BASE a_real = Aii_real / s; const BASE a_imag = Aii_imag / s; for (j = 0; j < n2; j++) { const BASE Bij_real = REAL(B, ldb * i + j); const BASE Bij_imag = IMAG(B, ldb * i + j); REAL(B, ldb * i + j) = (Bij_real * a_real + Bij_imag * a_imag) / s; IMAG(B, ldb * i + j) = (Bij_imag * a_real - Bij_real * a_imag) / s; } } for (k = 0; k < i; k++) { const BASE Aki_real = CONST_REAL(A, k * lda + i); const BASE Aki_imag = conj * CONST_IMAG(A, k * lda + i); for (j = 0; j < n2; j++) { const BASE Bij_real = REAL(B, ldb * i + j); const BASE Bij_imag = IMAG(B, ldb * i + j); REAL(B, ldb * k + j) -= Aki_real * Bij_real - Aki_imag * Bij_imag; IMAG(B, ldb * k + j) -= Aki_real * Bij_imag + Aki_imag * Bij_real; } } } } else if (side == CblasLeft && uplo == CblasUpper && trans == CblasTrans) { /* form B := alpha * inv(TriU(A))' *B */ if (!(alpha_real == 1.0 && alpha_imag == 0.0)) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { const BASE Bij_real = REAL(B, ldb * i + j); const BASE Bij_imag = IMAG(B, ldb * i + j); REAL(B, ldb * i + j) = alpha_real * Bij_real - alpha_imag * Bij_imag; IMAG(B, ldb * i + j) = alpha_real * Bij_imag + alpha_imag * Bij_real; } } } for (i = 0; i < n1; i++) { if (nonunit) { const BASE Aii_real = CONST_REAL(A, lda * i + i); const BASE Aii_imag = conj * CONST_IMAG(A, lda * i + i); const BASE s = xhypot(Aii_real, Aii_imag); const BASE a_real = Aii_real / s; const BASE a_imag = Aii_imag / s; for (j = 0; j < n2; j++) { const BASE Bij_real = REAL(B, ldb * i + j); const BASE Bij_imag = IMAG(B, ldb * i + j); REAL(B, ldb * i + j) = (Bij_real * a_real + Bij_imag * a_imag) / s; IMAG(B, ldb * i + j) = (Bij_imag * a_real - Bij_real * a_imag) / s; } } for (k = i + 1; k < n1; k++) { const BASE Aik_real = CONST_REAL(A, i * lda + k); const BASE Aik_imag = conj * CONST_IMAG(A, i * lda + k); for (j = 0; j < n2; j++) { const BASE Bij_real = REAL(B, ldb * i + j); const BASE Bij_imag = IMAG(B, ldb * i + j); REAL(B, ldb * k + j) -= Aik_real * Bij_real - Aik_imag * Bij_imag; IMAG(B, ldb * k + j) -= Aik_real * Bij_imag + Aik_imag * Bij_real; } } } } else if (side == CblasLeft && uplo == CblasLower && trans == CblasNoTrans) { /* form B := alpha * inv(TriL(A))*B */ if (!(alpha_real == 1.0 && alpha_imag == 0.0)) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { const BASE Bij_real = REAL(B, ldb * i + j); const BASE Bij_imag = IMAG(B, ldb * i + j); REAL(B, ldb * i + j) = alpha_real * Bij_real - alpha_imag * Bij_imag; IMAG(B, ldb * i + j) = alpha_real * Bij_imag + alpha_imag * Bij_real; } } } for (i = 0; i < n1; i++) { if (nonunit) { const BASE Aii_real = CONST_REAL(A, lda * i + i); const BASE Aii_imag = conj * CONST_IMAG(A, lda * i + i); const BASE s = xhypot(Aii_real, Aii_imag); const BASE a_real = Aii_real / s; const BASE a_imag = Aii_imag / s; for (j = 0; j < n2; j++) { const BASE Bij_real = REAL(B, ldb * i + j); const BASE Bij_imag = IMAG(B, ldb * i + j); REAL(B, ldb * i + j) = (Bij_real * a_real + Bij_imag * a_imag) / s; IMAG(B, ldb * i + j) = (Bij_imag * a_real - Bij_real * a_imag) / s; } } for (k = i + 1; k < n1; k++) { const BASE Aki_real = CONST_REAL(A, k * lda + i); const BASE Aki_imag = conj * CONST_IMAG(A, k * lda + i); for (j = 0; j < n2; j++) { const BASE Bij_real = REAL(B, ldb * i + j); const BASE Bij_imag = IMAG(B, ldb * i + j); REAL(B, ldb * k + j) -= Aki_real * Bij_real - Aki_imag * Bij_imag; IMAG(B, ldb * k + j) -= Aki_real * Bij_imag + Aki_imag * Bij_real; } } } } else if (side == CblasLeft && uplo == CblasLower && trans == CblasTrans) { /* form B := alpha * TriL(A)' *B */ if (!(alpha_real == 1.0 && alpha_imag == 0.0)) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { const BASE Bij_real = REAL(B, ldb * i + j); const BASE Bij_imag = IMAG(B, ldb * i + j); REAL(B, ldb * i + j) = alpha_real * Bij_real - alpha_imag * Bij_imag; IMAG(B, ldb * i + j) = alpha_real * Bij_imag + alpha_imag * Bij_real; } } } for (i = n1; i > 0 && i--;) { if (nonunit) { const BASE Aii_real = CONST_REAL(A, lda * i + i); const BASE Aii_imag = conj * CONST_IMAG(A, lda * i + i); const BASE s = xhypot(Aii_real, Aii_imag); const BASE a_real = Aii_real / s; const BASE a_imag = Aii_imag / s; for (j = 0; j < n2; j++) { const BASE Bij_real = REAL(B, ldb * i + j); const BASE Bij_imag = IMAG(B, ldb * i + j); REAL(B, ldb * i + j) = (Bij_real * a_real + Bij_imag * a_imag) / s; IMAG(B, ldb * i + j) = (Bij_imag * a_real - Bij_real * a_imag) / s; } } for (k = 0; k < i; k++) { const BASE Aik_real = CONST_REAL(A, i * lda + k); const BASE Aik_imag = conj * CONST_IMAG(A, i * lda + k); for (j = 0; j < n2; j++) { const BASE Bij_real = REAL(B, ldb * i + j); const BASE Bij_imag = IMAG(B, ldb * i + j); REAL(B, ldb * k + j) -= Aik_real * Bij_real - Aik_imag * Bij_imag; IMAG(B, ldb * k + j) -= Aik_real * Bij_imag + Aik_imag * Bij_real; } } } } else if (side == CblasRight && uplo == CblasUpper && trans == CblasNoTrans) { /* form B := alpha * B * inv(TriU(A)) */ if (!(alpha_real == 1.0 && alpha_imag == 0.0)) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { const BASE Bij_real = REAL(B, ldb * i + j); const BASE Bij_imag = IMAG(B, ldb * i + j); REAL(B, ldb * i + j) = alpha_real * Bij_real - alpha_imag * Bij_imag; IMAG(B, ldb * i + j) = alpha_real * Bij_imag + alpha_imag * Bij_real; } } } for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { if (nonunit) { const BASE Ajj_real = CONST_REAL(A, lda * j + j); const BASE Ajj_imag = conj * CONST_IMAG(A, lda * j + j); const BASE s = xhypot(Ajj_real, Ajj_imag); const BASE a_real = Ajj_real / s; const BASE a_imag = Ajj_imag / s; const BASE Bij_real = REAL(B, ldb * i + j); const BASE Bij_imag = IMAG(B, ldb * i + j); REAL(B, ldb * i + j) = (Bij_real * a_real + Bij_imag * a_imag) / s; IMAG(B, ldb * i + j) = (Bij_imag * a_real - Bij_real * a_imag) / s; } { const BASE Bij_real = REAL(B, ldb * i + j); const BASE Bij_imag = IMAG(B, ldb * i + j); for (k = j + 1; k < n2; k++) { const BASE Ajk_real = CONST_REAL(A, j * lda + k); const BASE Ajk_imag = conj * CONST_IMAG(A, j * lda + k); REAL(B, ldb * i + k) -= Ajk_real * Bij_real - Ajk_imag * Bij_imag; IMAG(B, ldb * i + k) -= Ajk_real * Bij_imag + Ajk_imag * Bij_real; } } } } } else if (side == CblasRight && uplo == CblasUpper && trans == CblasTrans) { /* form B := alpha * B * inv(TriU(A))' */ if (!(alpha_real == 1.0 && alpha_imag == 0.0)) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { const BASE Bij_real = REAL(B, ldb * i + j); const BASE Bij_imag = IMAG(B, ldb * i + j); REAL(B, ldb * i + j) = alpha_real * Bij_real - alpha_imag * Bij_imag; IMAG(B, ldb * i + j) = alpha_real * Bij_imag + alpha_imag * Bij_real; } } } for (i = 0; i < n1; i++) { for (j = n2; j > 0 && j--;) { if (nonunit) { const BASE Ajj_real = CONST_REAL(A, lda * j + j); const BASE Ajj_imag = conj * CONST_IMAG(A, lda * j + j); const BASE s = xhypot(Ajj_real, Ajj_imag); const BASE a_real = Ajj_real / s; const BASE a_imag = Ajj_imag / s; const BASE Bij_real = REAL(B, ldb * i + j); const BASE Bij_imag = IMAG(B, ldb * i + j); REAL(B, ldb * i + j) = (Bij_real * a_real + Bij_imag * a_imag) / s; IMAG(B, ldb * i + j) = (Bij_imag * a_real - Bij_real * a_imag) / s; } { const BASE Bij_real = REAL(B, ldb * i + j); const BASE Bij_imag = IMAG(B, ldb * i + j); for (k = 0; k < j; k++) { const BASE Akj_real = CONST_REAL(A, k * lda + j); const BASE Akj_imag = conj * CONST_IMAG(A, k * lda + j); REAL(B, ldb * i + k) -= Akj_real * Bij_real - Akj_imag * Bij_imag; IMAG(B, ldb * i + k) -= Akj_real * Bij_imag + Akj_imag * Bij_real; } } } } } else if (side == CblasRight && uplo == CblasLower && trans == CblasNoTrans) { /* form B := alpha * B * inv(TriL(A)) */ if (!(alpha_real == 1.0 && alpha_imag == 0.0)) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { const BASE Bij_real = REAL(B, ldb * i + j); const BASE Bij_imag = IMAG(B, ldb * i + j); REAL(B, ldb * i + j) = alpha_real * Bij_real - alpha_imag * Bij_imag; IMAG(B, ldb * i + j) = alpha_real * Bij_imag + alpha_imag * Bij_real; } } } for (i = 0; i < n1; i++) { for (j = n2; j > 0 && j--;) { if (nonunit) { const BASE Ajj_real = CONST_REAL(A, lda * j + j); const BASE Ajj_imag = conj * CONST_IMAG(A, lda * j + j); const BASE s = xhypot(Ajj_real, Ajj_imag); const BASE a_real = Ajj_real / s; const BASE a_imag = Ajj_imag / s; const BASE Bij_real = REAL(B, ldb * i + j); const BASE Bij_imag = IMAG(B, ldb * i + j); REAL(B, ldb * i + j) = (Bij_real * a_real + Bij_imag * a_imag) / s; IMAG(B, ldb * i + j) = (Bij_imag * a_real - Bij_real * a_imag) / s; } { const BASE Bij_real = REAL(B, ldb * i + j); const BASE Bij_imag = IMAG(B, ldb * i + j); for (k = 0; k < j; k++) { const BASE Ajk_real = CONST_REAL(A, j * lda + k); const BASE Ajk_imag = conj * CONST_IMAG(A, j * lda + k); REAL(B, ldb * i + k) -= Ajk_real * Bij_real - Ajk_imag * Bij_imag; IMAG(B, ldb * i + k) -= Ajk_real * Bij_imag + Ajk_imag * Bij_real; } } } } } else if (side == CblasRight && uplo == CblasLower && trans == CblasTrans) { /* form B := alpha * B * inv(TriL(A))' */ if (!(alpha_real == 1.0 && alpha_imag == 0.0)) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { const BASE Bij_real = REAL(B, ldb * i + j); const BASE Bij_imag = IMAG(B, ldb * i + j); REAL(B, ldb * i + j) = alpha_real * Bij_real - alpha_imag * Bij_imag; IMAG(B, ldb * i + j) = alpha_real * Bij_imag + alpha_imag * Bij_real; } } } for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { if (nonunit) { const BASE Ajj_real = CONST_REAL(A, lda * j + j); const BASE Ajj_imag = conj * CONST_IMAG(A, lda * j + j); const BASE s = xhypot(Ajj_real, Ajj_imag); const BASE a_real = Ajj_real / s; const BASE a_imag = Ajj_imag / s; const BASE Bij_real = REAL(B, ldb * i + j); const BASE Bij_imag = IMAG(B, ldb * i + j); REAL(B, ldb * i + j) = (Bij_real * a_real + Bij_imag * a_imag) / s; IMAG(B, ldb * i + j) = (Bij_imag * a_real - Bij_real * a_imag) / s; } { const BASE Bij_real = REAL(B, ldb * i + j); const BASE Bij_imag = IMAG(B, ldb * i + j); for (k = j + 1; k < n2; k++) { const BASE Akj_real = CONST_REAL(A, k * lda + j); const BASE Akj_imag = conj * CONST_IMAG(A, k * lda + j); REAL(B, ldb * i + k) -= Akj_real * Bij_real - Akj_imag * Bij_imag; IMAG(B, ldb * i + k) -= Akj_real * Bij_imag + Akj_imag * Bij_real; } } } } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_trsm_r.h000066400000000000000000000143701261542461700225430ustar00rootroot00000000000000/* blas/source_trsm_r.h * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { INDEX i, j, k; INDEX n1, n2; const int nonunit = (Diag == CblasNonUnit); int side, uplo, trans; if (Order == CblasRowMajor) { n1 = M; n2 = N; side = Side; uplo = Uplo; trans = (TransA == CblasConjTrans) ? CblasTrans : TransA; } else { n1 = N; n2 = M; side = (Side == CblasLeft) ? CblasRight : CblasLeft; uplo = (Uplo == CblasUpper) ? CblasLower : CblasUpper; trans = (TransA == CblasConjTrans) ? CblasTrans : TransA; } if (side == CblasLeft && uplo == CblasUpper && trans == CblasNoTrans) { /* form B := alpha * inv(TriU(A)) *B */ if (alpha != 1.0) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { B[ldb * i + j] *= alpha; } } } for (i = n1; i > 0 && i--;) { if (nonunit) { BASE Aii = A[lda * i + i]; for (j = 0; j < n2; j++) { B[ldb * i + j] /= Aii; } } for (k = 0; k < i; k++) { const BASE Aki = A[k * lda + i]; for (j = 0; j < n2; j++) { B[ldb * k + j] -= Aki * B[ldb * i + j]; } } } } else if (side == CblasLeft && uplo == CblasUpper && trans == CblasTrans) { /* form B := alpha * inv(TriU(A))' *B */ if (alpha != 1.0) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { B[ldb * i + j] *= alpha; } } } for (i = 0; i < n1; i++) { if (nonunit) { BASE Aii = A[lda * i + i]; for (j = 0; j < n2; j++) { B[ldb * i + j] /= Aii; } } for (k = i + 1; k < n1; k++) { const BASE Aik = A[i * lda + k]; for (j = 0; j < n2; j++) { B[ldb * k + j] -= Aik * B[ldb * i + j]; } } } } else if (side == CblasLeft && uplo == CblasLower && trans == CblasNoTrans) { /* form B := alpha * inv(TriL(A))*B */ if (alpha != 1.0) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { B[ldb * i + j] *= alpha; } } } for (i = 0; i < n1; i++) { if (nonunit) { BASE Aii = A[lda * i + i]; for (j = 0; j < n2; j++) { B[ldb * i + j] /= Aii; } } for (k = i + 1; k < n1; k++) { const BASE Aki = A[k * lda + i]; for (j = 0; j < n2; j++) { B[ldb * k + j] -= Aki * B[ldb * i + j]; } } } } else if (side == CblasLeft && uplo == CblasLower && trans == CblasTrans) { /* form B := alpha * TriL(A)' *B */ if (alpha != 1.0) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { B[ldb * i + j] *= alpha; } } } for (i = n1; i > 0 && i--;) { if (nonunit) { BASE Aii = A[lda * i + i]; for (j = 0; j < n2; j++) { B[ldb * i + j] /= Aii; } } for (k = 0; k < i; k++) { const BASE Aik = A[i * lda + k]; for (j = 0; j < n2; j++) { B[ldb * k + j] -= Aik * B[ldb * i + j]; } } } } else if (side == CblasRight && uplo == CblasUpper && trans == CblasNoTrans) { /* form B := alpha * B * inv(TriU(A)) */ if (alpha != 1.0) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { B[ldb * i + j] *= alpha; } } } for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { if (nonunit) { BASE Ajj = A[lda * j + j]; B[ldb * i + j] /= Ajj; } { BASE Bij = B[ldb * i + j]; for (k = j + 1; k < n2; k++) { B[ldb * i + k] -= A[j * lda + k] * Bij; } } } } } else if (side == CblasRight && uplo == CblasUpper && trans == CblasTrans) { /* form B := alpha * B * inv(TriU(A))' */ if (alpha != 1.0) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { B[ldb * i + j] *= alpha; } } } for (i = 0; i < n1; i++) { for (j = n2; j > 0 && j--;) { if (nonunit) { BASE Ajj = A[lda * j + j]; B[ldb * i + j] /= Ajj; } { BASE Bij = B[ldb * i + j]; for (k = 0; k < j; k++) { B[ldb * i + k] -= A[k * lda + j] * Bij; } } } } } else if (side == CblasRight && uplo == CblasLower && trans == CblasNoTrans) { /* form B := alpha * B * inv(TriL(A)) */ if (alpha != 1.0) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { B[ldb * i + j] *= alpha; } } } for (i = 0; i < n1; i++) { for (j = n2; j > 0 && j--;) { if (nonunit) { BASE Ajj = A[lda * j + j]; B[ldb * i + j] /= Ajj; } { BASE Bij = B[ldb * i + j]; for (k = 0; k < j; k++) { B[ldb * i + k] -= A[j * lda + k] * Bij; } } } } } else if (side == CblasRight && uplo == CblasLower && trans == CblasTrans) { /* form B := alpha * B * inv(TriL(A))' */ if (alpha != 1.0) { for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { B[ldb * i + j] *= alpha; } } } for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { if (nonunit) { BASE Ajj = A[lda * j + j]; B[ldb * i + j] /= Ajj; } { BASE Bij = B[ldb * i + j]; for (k = j + 1; k < n2; k++) { B[ldb * i + k] -= A[k * lda + j] * Bij; } } } } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_trsv_c.h000066400000000000000000000177411261542461700225420ustar00rootroot00000000000000/* blas/source_trsv_c.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { const int conj = (TransA == CblasConjTrans) ? -1 : 1; const int Trans = (TransA != CblasConjTrans) ? TransA : CblasTrans; const int nonunit = (Diag == CblasNonUnit); INDEX i, j; INDEX ix, jx; if (N == 0) return; /* form x := inv( A )*x */ if ((order == CblasRowMajor && Trans == CblasNoTrans && Uplo == CblasUpper) || (order == CblasColMajor && Trans == CblasTrans && Uplo == CblasLower)) { ix = OFFSET(N, incX) + incX * (N - 1); if (nonunit) { const BASE a_real = CONST_REAL(A, lda * (N - 1) + (N - 1)); const BASE a_imag = conj * CONST_IMAG(A, lda * (N - 1) + (N - 1)); const BASE x_real = REAL(X, ix); const BASE x_imag = IMAG(X, ix); const BASE s = xhypot(a_real, a_imag); const BASE b_real = a_real / s; const BASE b_imag = a_imag / s; REAL(X, ix) = (x_real * b_real + x_imag * b_imag) / s; IMAG(X, ix) = (x_imag * b_real - b_imag * x_real) / s; } ix -= incX; for (i = N - 1; i > 0 && i--;) { BASE tmp_real = REAL(X, ix); BASE tmp_imag = IMAG(X, ix); jx = ix + incX; for (j = i + 1; j < N; j++) { const BASE Aij_real = CONST_REAL(A, lda * i + j); const BASE Aij_imag = conj * CONST_IMAG(A, lda * i + j); const BASE x_real = REAL(X, jx); const BASE x_imag = IMAG(X, jx); tmp_real -= Aij_real * x_real - Aij_imag * x_imag; tmp_imag -= Aij_real * x_imag + Aij_imag * x_real; jx += incX; } if (nonunit) { const BASE a_real = CONST_REAL(A, lda * i + i); const BASE a_imag = conj * CONST_IMAG(A, lda * i + i); const BASE s = xhypot(a_real, a_imag); const BASE b_real = a_real / s; const BASE b_imag = a_imag / s; REAL(X, ix) = (tmp_real * b_real + tmp_imag * b_imag) / s; IMAG(X, ix) = (tmp_imag * b_real - tmp_real * b_imag) / s; } else { REAL(X, ix) = tmp_real; IMAG(X, ix) = tmp_imag; } ix -= incX; } } else if ((order == CblasRowMajor && Trans == CblasNoTrans && Uplo == CblasLower) || (order == CblasColMajor && Trans == CblasTrans && Uplo == CblasUpper)) { /* forward substitution */ ix = OFFSET(N, incX); if (nonunit) { const BASE a_real = CONST_REAL(A, lda * 0 + 0); const BASE a_imag = conj * CONST_IMAG(A, lda * 0 + 0); const BASE x_real = REAL(X, ix); const BASE x_imag = IMAG(X, ix); const BASE s = xhypot(a_real, a_imag); const BASE b_real = a_real / s; const BASE b_imag = a_imag / s; REAL(X, ix) = (x_real * b_real + x_imag * b_imag) / s; IMAG(X, ix) = (x_imag * b_real - b_imag * x_real) / s; } ix += incX; for (i = 1; i < N; i++) { BASE tmp_real = REAL(X, ix); BASE tmp_imag = IMAG(X, ix); jx = OFFSET(N, incX); for (j = 0; j < i; j++) { const BASE Aij_real = CONST_REAL(A, lda * i + j); const BASE Aij_imag = conj * CONST_IMAG(A, lda * i + j); const BASE x_real = REAL(X, jx); const BASE x_imag = IMAG(X, jx); tmp_real -= Aij_real * x_real - Aij_imag * x_imag; tmp_imag -= Aij_real * x_imag + Aij_imag * x_real; jx += incX; } if (nonunit) { const BASE a_real = CONST_REAL(A, lda * i + i); const BASE a_imag = conj * CONST_IMAG(A, lda * i + i); const BASE s = xhypot(a_real, a_imag); const BASE b_real = a_real / s; const BASE b_imag = a_imag / s; REAL(X, ix) = (tmp_real * b_real + tmp_imag * b_imag) / s; IMAG(X, ix) = (tmp_imag * b_real - tmp_real * b_imag) / s; } else { REAL(X, ix) = tmp_real; IMAG(X, ix) = tmp_imag; } ix += incX; } } else if ((order == CblasRowMajor && Trans == CblasTrans && Uplo == CblasUpper) || (order == CblasColMajor && Trans == CblasNoTrans && Uplo == CblasLower)) { /* form x := inv( A' )*x */ /* forward substitution */ ix = OFFSET(N, incX); if (nonunit) { const BASE a_real = CONST_REAL(A, lda * 0 + 0); const BASE a_imag = conj * CONST_IMAG(A, lda * 0 + 0); const BASE x_real = REAL(X, ix); const BASE x_imag = IMAG(X, ix); const BASE s = xhypot(a_real, a_imag); const BASE b_real = a_real / s; const BASE b_imag = a_imag / s; REAL(X, ix) = (x_real * b_real + x_imag * b_imag) / s; IMAG(X, ix) = (x_imag * b_real - b_imag * x_real) / s; } ix += incX; for (i = 1; i < N; i++) { BASE tmp_real = REAL(X, ix); BASE tmp_imag = IMAG(X, ix); jx = OFFSET(N, incX); for (j = 0; j < i; j++) { const BASE Aij_real = CONST_REAL(A, lda * j + i); const BASE Aij_imag = conj * CONST_IMAG(A, lda * j + i); const BASE x_real = REAL(X, jx); const BASE x_imag = IMAG(X, jx); tmp_real -= Aij_real * x_real - Aij_imag * x_imag; tmp_imag -= Aij_real * x_imag + Aij_imag * x_real; jx += incX; } if (nonunit) { const BASE a_real = CONST_REAL(A, lda * i + i); const BASE a_imag = conj * CONST_IMAG(A, lda * i + i); const BASE s = xhypot(a_real, a_imag); const BASE b_real = a_real / s; const BASE b_imag = a_imag / s; REAL(X, ix) = (tmp_real * b_real + tmp_imag * b_imag) / s; IMAG(X, ix) = (tmp_imag * b_real - tmp_real * b_imag) / s; } else { REAL(X, ix) = tmp_real; IMAG(X, ix) = tmp_imag; } ix += incX; } } else if ((order == CblasRowMajor && Trans == CblasTrans && Uplo == CblasLower) || (order == CblasColMajor && Trans == CblasNoTrans && Uplo == CblasUpper)) { /* backsubstitution */ ix = OFFSET(N, incX) + incX * (N - 1); if (nonunit) { const BASE a_real = CONST_REAL(A, lda * (N - 1) + (N - 1)); const BASE a_imag = conj * CONST_IMAG(A, lda * (N - 1) + (N - 1)); const BASE x_real = REAL(X, ix); const BASE x_imag = IMAG(X, ix); const BASE s = xhypot(a_real, a_imag); const BASE b_real = a_real / s; const BASE b_imag = a_imag / s; REAL(X, ix) = (x_real * b_real + x_imag * b_imag) / s; IMAG(X, ix) = (x_imag * b_real - b_imag * x_real) / s; } ix -= incX; for (i = N - 1; i > 0 && i--;) { BASE tmp_real = REAL(X, ix); BASE tmp_imag = IMAG(X, ix); jx = ix + incX; for (j = i + 1; j < N; j++) { const BASE Aij_real = CONST_REAL(A, lda * j + i); const BASE Aij_imag = conj * CONST_IMAG(A, lda * j + i); const BASE x_real = REAL(X, jx); const BASE x_imag = IMAG(X, jx); tmp_real -= Aij_real * x_real - Aij_imag * x_imag; tmp_imag -= Aij_real * x_imag + Aij_imag * x_real; jx += incX; } if (nonunit) { const BASE a_real = CONST_REAL(A, lda * i + i); const BASE a_imag = conj * CONST_IMAG(A, lda * i + i); const BASE s = xhypot(a_real, a_imag); const BASE b_real = a_real / s; const BASE b_imag = a_imag / s; REAL(X, ix) = (tmp_real * b_real + tmp_imag * b_imag) / s; IMAG(X, ix) = (tmp_imag * b_real - tmp_real * b_imag) / s; } else { REAL(X, ix) = tmp_real; IMAG(X, ix) = tmp_imag; } ix -= incX; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__source_trsv_r.h000066400000000000000000000072601261542461700225540ustar00rootroot00000000000000/* blas/source_trsv_r.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ { const int nonunit = (Diag == CblasNonUnit); INDEX ix, jx; INDEX i, j; const int Trans = (TransA != CblasConjTrans) ? TransA : CblasTrans; if (N == 0) return; /* form x := inv( A )*x */ if ((order == CblasRowMajor && Trans == CblasNoTrans && Uplo == CblasUpper) || (order == CblasColMajor && Trans == CblasTrans && Uplo == CblasLower)) { /* backsubstitution */ ix = OFFSET(N, incX) + incX * (N - 1); if (nonunit) { X[ix] = X[ix] / A[lda * (N - 1) + (N - 1)]; } ix -= incX; for (i = N - 1; i > 0 && i--;) { BASE tmp = X[ix]; jx = ix + incX; for (j = i + 1; j < N; j++) { const BASE Aij = A[lda * i + j]; tmp -= Aij * X[jx]; jx += incX; } if (nonunit) { X[ix] = tmp / A[lda * i + i]; } else { X[ix] = tmp; } ix -= incX; } } else if ((order == CblasRowMajor && Trans == CblasNoTrans && Uplo == CblasLower) || (order == CblasColMajor && Trans == CblasTrans && Uplo == CblasUpper)) { /* forward substitution */ ix = OFFSET(N, incX); if (nonunit) { X[ix] = X[ix] / A[lda * 0 + 0]; } ix += incX; for (i = 1; i < N; i++) { BASE tmp = X[ix]; jx = OFFSET(N, incX); for (j = 0; j < i; j++) { const BASE Aij = A[lda * i + j]; tmp -= Aij * X[jx]; jx += incX; } if (nonunit) { X[ix] = tmp / A[lda * i + i]; } else { X[ix] = tmp; } ix += incX; } } else if ((order == CblasRowMajor && Trans == CblasTrans && Uplo == CblasUpper) || (order == CblasColMajor && Trans == CblasNoTrans && Uplo == CblasLower)) { /* form x := inv( A' )*x */ /* forward substitution */ ix = OFFSET(N, incX); if (nonunit) { X[ix] = X[ix] / A[lda * 0 + 0]; } ix += incX; for (i = 1; i < N; i++) { BASE tmp = X[ix]; jx = OFFSET(N, incX); for (j = 0; j < i; j++) { const BASE Aji = A[lda * j + i]; tmp -= Aji * X[jx]; jx += incX; } if (nonunit) { X[ix] = tmp / A[lda * i + i]; } else { X[ix] = tmp; } ix += incX; } } else if ((order == CblasRowMajor && Trans == CblasTrans && Uplo == CblasLower) || (order == CblasColMajor && Trans == CblasNoTrans && Uplo == CblasUpper)) { /* backsubstitution */ ix = OFFSET(N, incX) + (N - 1) * incX; if (nonunit) { X[ix] = X[ix] / A[lda * (N - 1) + (N - 1)]; } ix -= incX; for (i = N - 1; i > 0 && i--;) { BASE tmp = X[ix]; jx = ix + incX; for (j = i + 1; j < N; j++) { const BASE Aji = A[lda * j + i]; tmp -= Aji * X[jx]; jx += incX; } if (nonunit) { X[ix] = tmp / A[lda * i + i]; } else { X[ix] = tmp; } ix -= incX; } } else { BLAS_ERROR("unrecognized operation"); } } praat-6.0.04/external/gsl/gsl_cblas__srot.c000066400000000000000000000004161261542461700206330ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_srot (const int N, float *X, const int incX, float *Y, const int incY, const float c, const float s) { #define BASE float #include "gsl_cblas__source_rot.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__srotg.c000066400000000000000000000003151261542461700210000ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_srotg (float *a, float *b, float *c, float *s) { #define BASE float #include "gsl_cblas__source_rotg.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__srotm.c000066400000000000000000000004031261542461700210040ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_srotm (const int N, float *X, const int incX, float *Y, const int incY, const float *P) { #define BASE float #include "gsl_cblas__source_rotm.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__srotmg.c000066400000000000000000000003421261542461700211550ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_srotmg (float *d1, float *d2, float *b1, const float b2, float *P) { #define BASE float #include "gsl_cblas__source_rotmg.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__ssbmv.c000066400000000000000000000006361261542461700210020ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_ssbmv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const int K, const float alpha, const float *A, const int lda, const float *X, const int incX, const float beta, float *Y, const int incY) { #define BASE float #include "gsl_cblas__source_sbmv.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__sscal.c000066400000000000000000000003411261542461700207460ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_sscal (const int N, const float alpha, float *X, const int incX) { #define BASE float #include "gsl_cblas__source_scal_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__sspmv.c000066400000000000000000000005661261542461700210220ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_sspmv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const float alpha, const float *Ap, const float *X, const int incX, const float beta, float *Y, const int incY) { #define BASE float #include "gsl_cblas__source_spmv.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__sspr.c000066400000000000000000000005001261542461700206250ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_sspr (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const float alpha, const float *X, const int incX, float *Ap) { #define BASE float #include "gsl_cblas__source_spr.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__sspr2.c000066400000000000000000000005451261542461700207200ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_sspr2 (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const float alpha, const float *X, const int incX, const float *Y, const int incY, float *Ap) { #define BASE double #include "gsl_cblas__source_spr2.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__sswap.c000066400000000000000000000003501261542461700207760ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_sswap (const int N, float *X, const int incX, float *Y, const int incY) { #define BASE float #include "gsl_cblas__source_swap_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__ssymm.c000066400000000000000000000006721261542461700210200ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_ssymm (const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const int M, const int N, const float alpha, const float *A, const int lda, const float *B, const int ldb, const float beta, float *C, const int ldc) { #define BASE float #include "gsl_cblas__source_symm_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__ssymv.c000066400000000000000000000006211261542461700210230ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_ssymv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const float alpha, const float *A, const int lda, const float *X, const int incX, const float beta, float *Y, const int incY) { #define BASE float #include "gsl_cblas__source_symv.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__ssyr.c000066400000000000000000000005161261542461700206450ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_ssyr (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const float alpha, const float *X, const int incX, float *A, const int lda) { #define BASE float #include "gsl_cblas__source_syr.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__ssyr2.c000066400000000000000000000005621261542461700207300ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_ssyr2 (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const float alpha, const float *X, const int incX, const float *Y, const int incY, float *A, const int lda) { #define BASE float #include "gsl_cblas__source_syr2.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__ssyr2k.c000066400000000000000000000007231261542461700211020ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_ssyr2k (const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const float alpha, const float *A, const int lda, const float *B, const int ldb, const float beta, float *C, const int ldc) { #define BASE float #include "gsl_cblas__source_syr2k_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__ssyrk.c000066400000000000000000000006421261542461700210200ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_ssyrk (const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const float alpha, const float *A, const int lda, const float beta, float *C, const int ldc) { #define BASE float #include "gsl_cblas__source_syrk_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__stbmv.c000066400000000000000000000006321261542461700207770ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_stbmv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const int K, const float *A, const int lda, float *X, const int incX) { #define BASE float #include "gsl_cblas__source_tbmv_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__stbsv.c000066400000000000000000000006321261542461700210050ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_stbsv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const int K, const float *A, const int lda, float *X, const int incX) { #define BASE float #include "gsl_cblas__source_tbsv_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__stpmv.c000066400000000000000000000005621261542461700210170ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_stpmv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const float *Ap, float *X, const int incX) { #define BASE float #include "gsl_cblas__source_tpmv_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__stpsv.c000066400000000000000000000005621261542461700210250ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_stpsv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const float *Ap, float *X, const int incX) { #define BASE float #include "gsl_cblas__source_tpsv_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__strmm.c000066400000000000000000000007251261542461700210110ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_strmm (const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int M, const int N, const float alpha, const float *A, const int lda, float *B, const int ldb) { #define BASE float #include "gsl_cblas__source_trmm_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__strmv.c000066400000000000000000000006151261542461700210200ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_strmv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const float *A, const int lda, float *X, const int incX) { #define BASE float #include "gsl_cblas__source_trmv_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__strsm.c000066400000000000000000000007251261542461700210170ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_strsm (const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int M, const int N, const float alpha, const float *A, const int lda, float *B, const int ldb) { #define BASE float #include "gsl_cblas__source_trsm_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__strsv.c000066400000000000000000000006151261542461700210260ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_strsv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const float *A, const int lda, float *X, const int incX) { #define BASE float #include "gsl_cblas__source_trsv_r.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__xerbla.c000066400000000000000000000023021261542461700211150ustar00rootroot00000000000000/* xerbla.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_xerbla (int p, const char *rout, const char *form, ...) { va_list ap; va_start (ap, form); if (p) { fprintf (stderr, "Parameter %d to routine %s was incorrect\n", p, rout); } vfprintf (stderr, form, ap); va_end (ap); abort (); } praat-6.0.04/external/gsl/gsl_cblas__zaxpy.c000066400000000000000000000004151261542461700210160ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_zaxpy (const int N, const void *alpha, const void *X, const int incX, void *Y, const int incY) { #define BASE double #include "gsl_cblas__source_axpy_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__zcopy.c000066400000000000000000000003721261542461700210110ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_zcopy (const int N, const void *X, const int incX, void *Y, const int incY) { #define BASE double #include "gsl_cblas__source_copy_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__zdotc_sub.c000066400000000000000000000004731261542461700216430ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_zdotc_sub (const int N, const void *X, const int incX, const void *Y, const int incY, void *result) { #define BASE double #define CONJ_SIGN (-1.0) #include "gsl_cblas__source_dot_c.h" #undef CONJ_SIGN #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__zdotu_sub.c000066400000000000000000000004701261542461700216620ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_zdotu_sub (const int N, const void *X, const int incX, const void *Y, const int incY, void *result) { #define BASE double #define CONJ_SIGN 1.0 #include "gsl_cblas__source_dot_c.h" #undef CONJ_SIGN #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__zdscal.c000066400000000000000000000003451261542461700211250ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_zdscal (const int N, const double alpha, void *X, const int incX) { #define BASE double #include "gsl_cblas__source_scal_c_s.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__zgbmv.c000066400000000000000000000007011261542461700207660ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_zgbmv (const enum CBLAS_ORDER order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const int KL, const int KU, const void *alpha, const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY) { #define BASE double #include "gsl_cblas__source_gbmv_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__zgemm.c000066400000000000000000000007401261542461700207630ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_zgemm (const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB, const int M, const int N, const int K, const void *alpha, const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc) { #define BASE double #include "gsl_cblas__source_gemm_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__zgemv.c000066400000000000000000000006451261542461700210000ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_zgemv (const enum CBLAS_ORDER order, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const void *alpha, const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY) { #define BASE double #include "gsl_cblas__source_gemv_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__zgerc.c000066400000000000000000000005411261542461700207550ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_zgerc (const enum CBLAS_ORDER order, const int M, const int N, const void *alpha, const void *X, const int incX, const void *Y, const int incY, void *A, const int lda) { #define BASE double #include "gsl_cblas__source_gerc.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__zgeru.c000066400000000000000000000005411261542461700207770ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_zgeru (const enum CBLAS_ORDER order, const int M, const int N, const void *alpha, const void *X, const int incX, const void *Y, const int incY, void *A, const int lda) { #define BASE double #include "gsl_cblas__source_geru.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__zhbmv.c000066400000000000000000000006341261542461700207740ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_zhbmv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const int K, const void *alpha, const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY) { #define BASE double #include "gsl_cblas__source_hbmv.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__zhemm.c000066400000000000000000000006661261542461700207730ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_zhemm (const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const int M, const int N, const void *alpha, const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc) { #define BASE double #include "gsl_cblas__source_hemm.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__zhemv.c000066400000000000000000000006171261542461700210000ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_zhemv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const void *alpha, const void *A, const int lda, const void *X, const int incX, const void *beta, void *Y, const int incY) { #define BASE double #include "gsl_cblas__source_hemv.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__zher.c000066400000000000000000000005161261542461700206150ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_zher (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const double alpha, const void *X, const int incX, void *A, const int lda) { #define BASE double #include "gsl_cblas__source_her.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__zher2.c000066400000000000000000000005601261542461700206760ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_zher2 (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const void *alpha, const void *X, const int incX, const void *Y, const int incY, void *A, const int lda) { #define BASE double #include "gsl_cblas__source_her2.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__zher2k.c000066400000000000000000000007021261542461700210470ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_zher2k (const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const void *alpha, const void *A, const int lda, const void *B, const int ldb, const double beta, void *C, const int ldc) { #define BASE double #include "gsl_cblas__source_her2k.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__zherk.c000066400000000000000000000006401261542461700207660ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_zherk (const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const double alpha, const void *A, const int lda, const double beta, void *C, const int ldc) { #define BASE double #include "gsl_cblas__source_herk.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__zhpmv.c000066400000000000000000000005641261542461700210140ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_zhpmv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const void *alpha, const void *Ap, const void *X, const int incX, const void *beta, void *Y, const int incY) { #define BASE double #include "gsl_cblas__source_hpmv.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__zhpr.c000066400000000000000000000005001261542461700206210ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_zhpr (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const double alpha, const void *X, const int incX, void *Ap) { #define BASE double #include "gsl_cblas__source_hpr.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__zhpr2.c000066400000000000000000000005421261542461700207110ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_zhpr2 (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, const void *alpha, const void *X, const int incX, const void *Y, const int incY, void *Ap) { #define BASE double #include "gsl_cblas__source_hpr2.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__zscal.c000066400000000000000000000003411261542461700207550ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_zscal (const int N, const void *alpha, void *X, const int incX) { #define BASE double #include "gsl_cblas__source_scal_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__zswap.c000066400000000000000000000003471261542461700210130ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_zswap (const int N, void *X, const int incX, void *Y, const int incY) { #define BASE double #include "gsl_cblas__source_swap_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__zsymm.c000066400000000000000000000006701261542461700210250ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_zsymm (const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const int M, const int N, const void *alpha, const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc) { #define BASE double #include "gsl_cblas__source_symm_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__zsyr2k.c000066400000000000000000000007031261542461700211070ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_zsyr2k (const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const void *alpha, const void *A, const int lda, const void *B, const int ldb, const void *beta, void *C, const int ldc) { #define BASE double #include "gsl_cblas__source_syr2k_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__zsyrk.c000066400000000000000000000006401261542461700210250ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_zsyrk (const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const void *alpha, const void *A, const int lda, const void *beta, void *C, const int ldc) { #define BASE double #include "gsl_cblas__source_syrk_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__ztbmv.c000066400000000000000000000006311261542461700210050ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_ztbmv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const int K, const void *A, const int lda, void *X, const int incX) { #define BASE double #include "gsl_cblas__source_tbmv_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__ztbsv.c000066400000000000000000000006701261542461700210160ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" #include "gsl_cblas__hypot.c" void cblas_ztbsv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const int K, const void *A, const int lda, void *X, const int incX) { #define BASE double #include "gsl_cblas__source_tbsv_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__ztpmv.c000066400000000000000000000005611261542461700210250ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_ztpmv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const void *Ap, void *X, const int incX) { #define BASE double #include "gsl_cblas__source_tpmv_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__ztpsv.c000066400000000000000000000006201261542461700210270ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" #include "gsl_cblas__hypot.c" void cblas_ztpsv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const void *Ap, void *X, const int incX) { #define BASE double #include "gsl_cblas__source_tpsv_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__ztrmm.c000066400000000000000000000007241261542461700210170ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_ztrmm (const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int M, const int N, const void *alpha, const void *A, const int lda, void *B, const int ldb) { #define BASE double #include "gsl_cblas__source_trmm_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__ztrmv.c000066400000000000000000000006141261542461700210260ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" void cblas_ztrmv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const void *A, const int lda, void *X, const int incX) { #define BASE double #include "gsl_cblas__source_trmv_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__ztrsm.c000066400000000000000000000007631261542461700210300ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" #include "gsl_cblas__hypot.c" void cblas_ztrsm (const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int M, const int N, const void *alpha, const void *A, const int lda, void *B, const int ldb) { #define BASE double #include "gsl_cblas__source_trsm_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cblas__ztrsv.c000066400000000000000000000006531261542461700210370ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_cblas.h" #include "gsl_cblas__cblas.h" #include "gsl_cblas__hypot.c" void cblas_ztrsv (const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int N, const void *A, const int lda, void *X, const int incX) { #define BASE double #include "gsl_cblas__source_trsv_c.h" #undef BASE } praat-6.0.04/external/gsl/gsl_cdf.h000066400000000000000000000163111261542461700171030ustar00rootroot00000000000000/* cdf/gsl_cdf.h * * Copyright (C) 2002 Jason H. Stover. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /* Author: J. Stover */ #ifndef __GSL_CDF_H__ #define __GSL_CDF_H__ #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS double gsl_cdf_ugaussian_P (const double x); double gsl_cdf_ugaussian_Q (const double x); double gsl_cdf_ugaussian_Pinv (const double P); double gsl_cdf_ugaussian_Qinv (const double Q); double gsl_cdf_gaussian_P (const double x, const double sigma); double gsl_cdf_gaussian_Q (const double x, const double sigma); double gsl_cdf_gaussian_Pinv (const double P, const double sigma); double gsl_cdf_gaussian_Qinv (const double Q, const double sigma); double gsl_cdf_gamma_P (const double x, const double a, const double b); double gsl_cdf_gamma_Q (const double x, const double a, const double b); double gsl_cdf_gamma_Pinv (const double P, const double a, const double b); double gsl_cdf_gamma_Qinv (const double Q, const double a, const double b); double gsl_cdf_cauchy_P (const double x, const double a); double gsl_cdf_cauchy_Q (const double x, const double a); double gsl_cdf_cauchy_Pinv (const double P, const double a); double gsl_cdf_cauchy_Qinv (const double Q, const double a); double gsl_cdf_laplace_P (const double x, const double a); double gsl_cdf_laplace_Q (const double x, const double a); double gsl_cdf_laplace_Pinv (const double P, const double a); double gsl_cdf_laplace_Qinv (const double Q, const double a); double gsl_cdf_rayleigh_P (const double x, const double sigma); double gsl_cdf_rayleigh_Q (const double x, const double sigma); double gsl_cdf_rayleigh_Pinv (const double P, const double sigma); double gsl_cdf_rayleigh_Qinv (const double Q, const double sigma); double gsl_cdf_chisq_P (const double x, const double nu); double gsl_cdf_chisq_Q (const double x, const double nu); double gsl_cdf_chisq_Pinv (const double P, const double nu); double gsl_cdf_chisq_Qinv (const double Q, const double nu); double gsl_cdf_exponential_P (const double x, const double mu); double gsl_cdf_exponential_Q (const double x, const double mu); double gsl_cdf_exponential_Pinv (const double P, const double mu); double gsl_cdf_exponential_Qinv (const double Q, const double mu); double gsl_cdf_exppow_P (const double x, const double a, const double b); double gsl_cdf_exppow_Q (const double x, const double a, const double b); double gsl_cdf_tdist_P (const double x, const double nu); double gsl_cdf_tdist_Q (const double x, const double nu); double gsl_cdf_tdist_Pinv (const double P, const double nu); double gsl_cdf_tdist_Qinv (const double Q, const double nu); double gsl_cdf_fdist_P (const double x, const double nu1, const double nu2); double gsl_cdf_fdist_Q (const double x, const double nu1, const double nu2); double gsl_cdf_fdist_Pinv (const double P, const double nu1, const double nu2); double gsl_cdf_fdist_Qinv (const double Q, const double nu1, const double nu2); double gsl_cdf_beta_P (const double x, const double a, const double b); double gsl_cdf_beta_Q (const double x, const double a, const double b); double gsl_cdf_beta_Pinv (const double P, const double a, const double b); double gsl_cdf_beta_Qinv (const double Q, const double a, const double b); double gsl_cdf_flat_P (const double x, const double a, const double b); double gsl_cdf_flat_Q (const double x, const double a, const double b); double gsl_cdf_flat_Pinv (const double P, const double a, const double b); double gsl_cdf_flat_Qinv (const double Q, const double a, const double b); double gsl_cdf_lognormal_P (const double x, const double zeta, const double sigma); double gsl_cdf_lognormal_Q (const double x, const double zeta, const double sigma); double gsl_cdf_lognormal_Pinv (const double P, const double zeta, const double sigma); double gsl_cdf_lognormal_Qinv (const double Q, const double zeta, const double sigma); double gsl_cdf_gumbel1_P (const double x, const double a, const double b); double gsl_cdf_gumbel1_Q (const double x, const double a, const double b); double gsl_cdf_gumbel1_Pinv (const double P, const double a, const double b); double gsl_cdf_gumbel1_Qinv (const double Q, const double a, const double b); double gsl_cdf_gumbel2_P (const double x, const double a, const double b); double gsl_cdf_gumbel2_Q (const double x, const double a, const double b); double gsl_cdf_gumbel2_Pinv (const double P, const double a, const double b); double gsl_cdf_gumbel2_Qinv (const double Q, const double a, const double b); double gsl_cdf_weibull_P (const double x, const double a, const double b); double gsl_cdf_weibull_Q (const double x, const double a, const double b); double gsl_cdf_weibull_Pinv (const double P, const double a, const double b); double gsl_cdf_weibull_Qinv (const double Q, const double a, const double b); double gsl_cdf_pareto_P (const double x, const double a, const double b); double gsl_cdf_pareto_Q (const double x, const double a, const double b); double gsl_cdf_pareto_Pinv (const double P, const double a, const double b); double gsl_cdf_pareto_Qinv (const double Q, const double a, const double b); double gsl_cdf_logistic_P (const double x, const double a); double gsl_cdf_logistic_Q (const double x, const double a); double gsl_cdf_logistic_Pinv (const double P, const double a); double gsl_cdf_logistic_Qinv (const double Q, const double a); double gsl_cdf_binomial_P (const unsigned int k, const double p, const unsigned int n); double gsl_cdf_binomial_Q (const unsigned int k, const double p, const unsigned int n); double gsl_cdf_poisson_P (const unsigned int k, const double mu); double gsl_cdf_poisson_Q (const unsigned int k, const double mu); double gsl_cdf_geometric_P (const unsigned int k, const double p); double gsl_cdf_geometric_Q (const unsigned int k, const double p); double gsl_cdf_negative_binomial_P (const unsigned int k, const double p, const double n); double gsl_cdf_negative_binomial_Q (const unsigned int k, const double p, const double n); double gsl_cdf_pascal_P (const unsigned int k, const double p, const unsigned int n); double gsl_cdf_pascal_Q (const unsigned int k, const double p, const unsigned int n); double gsl_cdf_hypergeometric_P (const unsigned int k, const unsigned int n1, const unsigned int n2, const unsigned int t); double gsl_cdf_hypergeometric_Q (const unsigned int k, const unsigned int n1, const unsigned int n2, const unsigned int t); __END_DECLS #endif /* __GSL_CDF_H__ */ praat-6.0.04/external/gsl/gsl_cdf__beta.c000066400000000000000000000026051261542461700202310ustar00rootroot00000000000000/* cdf/cdf_beta.c * * Copyright (C) 2003, 2007 Brian Gough. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #include "gsl__config.h" #include #include "gsl_cdf.h" #include "gsl_sf_gamma.h" #include "gsl_math.h" #include "gsl_cdf__beta_inc.c" double gsl_cdf_beta_P (const double x, const double a, const double b) { double P; if (x <= 0.0 ) { return 0.0; } if ( x >= 1.0 ) { return 1.0; } P = beta_inc_AXPY (1.0, 0.0, a, b, x); return P; } double gsl_cdf_beta_Q (const double x, const double a, const double b) { double Q; if ( x >= 1.0) { return 0.0; } if ( x <= 0.0 ) { return 1.0; } Q = beta_inc_AXPY (-1.0, 1.0, a, b, x); return Q; } praat-6.0.04/external/gsl/gsl_cdf__beta_inc.c000066400000000000000000000110461261542461700210610ustar00rootroot00000000000000/* specfunc/beta_inc.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ /* Modified for cdfs by Brian Gough, June 2003 */ static double beta_cont_frac (const double a, const double b, const double x, const double epsabs) { const unsigned int max_iter = 512; /* control iterations */ const double cutoff = 2.0 * GSL_DBL_MIN; /* control the zero cutoff */ unsigned int iter_count = 0; double cf; /* standard initialization for continued fraction */ double num_term = 1.0; double den_term = 1.0 - (a + b) * x / (a + 1.0); if (fabs (den_term) < cutoff) den_term = GSL_NAN; den_term = 1.0 / den_term; cf = den_term; while (iter_count < max_iter) { const int k = iter_count + 1; double coeff = k * (b - k) * x / (((a - 1.0) + 2 * k) * (a + 2 * k)); double delta_frac; /* first step */ den_term = 1.0 + coeff * den_term; num_term = 1.0 + coeff / num_term; if (fabs (den_term) < cutoff) den_term = GSL_NAN; if (fabs (num_term) < cutoff) num_term = GSL_NAN; den_term = 1.0 / den_term; delta_frac = den_term * num_term; cf *= delta_frac; coeff = -(a + k) * (a + b + k) * x / ((a + 2 * k) * (a + 2 * k + 1.0)); /* second step */ den_term = 1.0 + coeff * den_term; num_term = 1.0 + coeff / num_term; if (fabs (den_term) < cutoff) den_term = GSL_NAN; if (fabs (num_term) < cutoff) num_term = GSL_NAN; den_term = 1.0 / den_term; delta_frac = den_term * num_term; cf *= delta_frac; if (fabs (delta_frac - 1.0) < 2.0 * GSL_DBL_EPSILON) break; if (cf * fabs (delta_frac - 1.0) < epsabs) break; ++iter_count; } if (iter_count >= max_iter) return GSL_NAN; return cf; } /* The function beta_inc_AXPY(A,Y,a,b,x) computes A * beta_inc(a,b,x) + Y taking account of possible cancellations when using the hypergeometric transformation beta_inc(a,b,x)=1-beta_inc(b,a,1-x). It also adjusts the accuracy of beta_inc() to fit the overall absolute error when A*beta_inc is added to Y. (e.g. if Y >> A*beta_inc then the accuracy of beta_inc can be reduced) */ static double beta_inc_AXPY (const double A, const double Y, const double a, const double b, const double x) { if (x == 0.0) { return A * 0 + Y; } else if (x == 1.0) { return A * 1 + Y; } else { double ln_beta = gsl_sf_lnbeta (a, b); double ln_pre = -ln_beta + a * log (x) + b * log1p (-x); double prefactor = exp (ln_pre); if (x < (a + 1.0) / (a + b + 2.0)) { /* Apply continued fraction directly. */ double epsabs = fabs (Y / (A * prefactor / a)) * GSL_DBL_EPSILON; double cf = beta_cont_frac (a, b, x, epsabs); return A * (prefactor * cf / a) + Y; } else { /* Apply continued fraction after hypergeometric transformation. */ double epsabs = fabs ((A + Y) / (A * prefactor / b)) * GSL_DBL_EPSILON; double cf = beta_cont_frac (b, a, 1.0 - x, epsabs); double term = prefactor * cf / b; if (A == -Y) { return -A * term; } else { return A * (1 - term) + Y; } } } } /* Direct series evaluation for testing purposes only */ #if 0 static double beta_series (const double a, const double b, const double x, const double epsabs) { double f = x / (1 - x); double c = (b - 1) / (a + 1) * f; double s = 1; double n = 0; s += c; do { n++; c *= -f * (2 + n - b) / (2 + n + a); s += c; } while (n < 512 && fabs (c) > GSL_DBL_EPSILON * fabs (s) + epsabs); s /= (1 - x); return s; } #endif praat-6.0.04/external/gsl/gsl_cdf__betainv.c000066400000000000000000000112521261542461700207440ustar00rootroot00000000000000/* cdf/betainv.c * * Copyright (C) 2004 Free Software Foundation, Inc. * Copyright (C) 2006, 2007 Brian Gough * Written by Jason H. Stover. * Modified for GSL by Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /* * Invert the Beta distribution. * * References: * * Roger W. Abernathy and Robert P. Smith. "Applying Series Expansion * to the Inverse Beta Distribution to Find Percentiles of the * F-Distribution," ACM Transactions on Mathematical Software, volume * 19, number 4, December 1993, pages 474-480. * * G.W. Hill and A.W. Davis. "Generalized asymptotic expansions of a * Cornish-Fisher type," Annals of Mathematical Statistics, volume 39, * number 8, August 1968, pages 1264-1273. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_gamma.h" #include "gsl_cdf.h" #include "gsl_randist.h" #include "gsl_cdf__error.h" static double bisect (double x, double P, double a, double b, double xtol, double Ptol) { double x0 = 0, x1 = 1, Px; while (fabs(x1 - x0) > xtol) { Px = gsl_cdf_beta_P (x, a, b); if (fabs(Px - P) < Ptol) { /* return as soon as approximation is good enough, including on the first iteration */ return x; } else if (Px < P) { x0 = x; } else if (Px > P) { x1 = x; } x = 0.5 * (x0 + x1); } return x; } double gsl_cdf_beta_Pinv (const double P, const double a, const double b) { double x, mean; if (P < 0.0 || P > 1.0) { CDF_ERROR ("P must be in range 0 < P < 1", GSL_EDOM); } if (a < 0.0) { CDF_ERROR ("a < 0", GSL_EDOM); } if (b < 0.0) { CDF_ERROR ("b < 0", GSL_EDOM); } if (P == 0.0) { return 0.0; } if (P == 1.0) { return 1.0; } if (P > 0.5) { return gsl_cdf_beta_Qinv (1 - P, a, b); } mean = a / (a + b); if (P < 0.1) { /* small x */ double lg_ab = gsl_sf_lngamma (a + b); double lg_a = gsl_sf_lngamma (a); double lg_b = gsl_sf_lngamma (b); double lx = (log (a) + lg_a + lg_b - lg_ab + log (P)) / a; if (lx <= 0) { x = exp (lx); /* first approximation */ x *= pow (1 - x, -(b - 1) / a); /* second approximation */ } else { x = mean; } if (x > mean) x = mean; } else { /* Use expected value as first guess */ x = mean; } /* Do bisection to get closer */ x = bisect (x, P, a, b, 0.01, 0.01); { double lambda, dP, phi; unsigned int n = 0; start: dP = P - gsl_cdf_beta_P (x, a, b); phi = gsl_ran_beta_pdf (x, a, b); if (dP == 0.0 || n++ > 64) goto end; lambda = dP / GSL_MAX (2 * fabs (dP / x), phi); { double step0 = lambda; double step1 = -((a - 1) / x - (b - 1) / (1 - x)) * lambda * lambda / 2; double step = step0; if (fabs (step1) < fabs (step0)) { step += step1; } else { /* scale back step to a reasonable size when too large */ step *= 2 * fabs (step0 / step1); }; if (x + step > 0 && x + step < 1) { x += step; } else { x = sqrt (x) * sqrt (mean); /* try a new starting point */ } if (fabs (step0) > 1e-10 * x) goto start; } end: if (fabs(dP) > GSL_SQRT_DBL_EPSILON * P) { GSL_ERROR_VAL("inverse failed to converge", GSL_EFAILED, GSL_NAN); } return x; } } double gsl_cdf_beta_Qinv (const double Q, const double a, const double b) { if (Q < 0.0 || Q > 1.0) { CDF_ERROR ("Q must be inside range 0 < Q < 1", GSL_EDOM); } if (a < 0.0) { CDF_ERROR ("a < 0", GSL_EDOM); } if (b < 0.0) { CDF_ERROR ("b < 0", GSL_EDOM); } if (Q == 0.0) { return 1.0; } if (Q == 1.0) { return 0.0; } if (Q > 0.5) { return gsl_cdf_beta_Pinv (1 - Q, a, b); } else { return 1 - gsl_cdf_beta_Pinv (Q, b, a); }; } praat-6.0.04/external/gsl/gsl_cdf__binomial.c000066400000000000000000000047171261542461700211160ustar00rootroot00000000000000/* cdf/binomial.c * * Copyright (C) 2004 Jason H. Stover. * Copyright (C) 2004 Giulio Bottazzi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_cdf.h" #include "gsl_sf_gamma.h" #include "gsl_cdf__error.h" /* Computes the cumulative distribution function for a binomial random variable. For a binomial random variable X with n trials and success probability p, Pr( X <= k ) = Pr( Y >= p ) where Y is a beta random variable with parameters k+1 and n-k. The binomial distribution has the form, prob(k) = n!/(k!(n-k)!) * p^k (1-p)^(n-k) for k = 0, 1, ..., n The cumulated distributions can be expressed in terms of normalized incomplete beta functions (see Abramowitz & Stegun eq. 26.5.26 and eq. 6.6.3). Reference: W. Feller, "An Introduction to Probability and Its Applications," volume 1. Wiley, 1968. Exercise 45, page 173, chapter 6. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_cdf.h" double gsl_cdf_binomial_P (const unsigned int k, const double p, const unsigned int n) { double P; double a; double b; if (p > 1.0 || p < 0.0) { CDF_ERROR ("p < 0 or p > 1", GSL_EDOM); } if (k >= n) { P = 1.0; } else { a = (double) k + 1.0; b = (double) n - k; P = gsl_cdf_beta_Q (p, a, b); } return P; } double gsl_cdf_binomial_Q (const unsigned int k, const double p, const unsigned int n) { double Q; double a; double b; if (p > 1.0 || p < 0.0) { CDF_ERROR ("p < 0 or p > 1", GSL_EDOM); } if (k >= n) { Q = 0.0; } else { a = (double) k + 1.0; b = (double) n - k; Q = gsl_cdf_beta_P (p, a, b); } return Q; } praat-6.0.04/external/gsl/gsl_cdf__cauchy.c000066400000000000000000000024331261542461700205710ustar00rootroot00000000000000/* cdf/cauchy.c * * Copyright (C) 2003, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_cdf.h" double gsl_cdf_cauchy_P (const double x, const double a) { double P; double u = x / a; if (u > -1) { P = 0.5 + atan (u) / M_PI; } else { P = atan(-1/u) / M_PI; } return P; } double gsl_cdf_cauchy_Q (const double x, const double a) { double Q; double u = x / a; if (u < 1) { Q = 0.5 - atan (u) / M_PI; } else { Q = atan(1/u) / M_PI; } return Q; } praat-6.0.04/external/gsl/gsl_cdf__cauchyinv.c000066400000000000000000000027511261542461700213110ustar00rootroot00000000000000/* cdf/cauchyinv.c * * Copyright (C) 2003, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_cdf.h" double gsl_cdf_cauchy_Pinv (const double P, const double a) { double x; if (P == 1.0) { return GSL_POSINF; } else if (P == 0.0) { return GSL_NEGINF; } if (P > 0.5) { x = a * tan (M_PI * (P - 0.5)); } else { x = -a / tan (M_PI * P); } return x; } double gsl_cdf_cauchy_Qinv (const double Q, const double a) { double x; if (Q == 0.0) { return GSL_POSINF; } else if (Q == 1.0) { return GSL_NEGINF; } if (Q > 0.5) { x = a * tan (M_PI * (0.5 - Q)); } else { x = a / tan (M_PI * Q); } return x; } praat-6.0.04/external/gsl/gsl_cdf__chisq.c000066400000000000000000000020561261542461700204250ustar00rootroot00000000000000/* cdf/cdf_chisq.c * * Copyright (C) 2003, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #include "gsl__config.h" #include "gsl_cdf.h" #include "gsl_sf_gamma.h" double gsl_cdf_chisq_P (const double x, const double nu) { return gsl_cdf_gamma_P (x, nu / 2, 2.0); } double gsl_cdf_chisq_Q (const double x, const double nu) { return gsl_cdf_gamma_Q (x, nu / 2, 2.0); } praat-6.0.04/external/gsl/gsl_cdf__chisqinv.c000066400000000000000000000020711261542461700211370ustar00rootroot00000000000000/* cdf/chisqinv.c * * Copyright (C) 2003, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #include "gsl__config.h" #include "gsl_cdf.h" #include "gsl_sf_gamma.h" double gsl_cdf_chisq_Pinv (const double P, const double nu) { return gsl_cdf_gamma_Pinv (P, nu / 2, 2.0); } double gsl_cdf_chisq_Qinv (const double Q, const double nu) { return gsl_cdf_gamma_Qinv (Q, nu / 2, 2.0); } praat-6.0.04/external/gsl/gsl_cdf__error.h000066400000000000000000000002141261542461700204460ustar00rootroot00000000000000/* CDF_ERROR: call the error handler, and return a NAN. */ #define CDF_ERROR(reason, gsl_errno) GSL_ERROR_VAL(reason, gsl_errno, GSL_NAN) praat-6.0.04/external/gsl/gsl_cdf__exponential.c000066400000000000000000000024761261542461700216520ustar00rootroot00000000000000/* cdf/exponential.c * * Copyright (C) 2003, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_cdf.h" /* The exponential distribution has the form p(x) dx = exp(-x/mu) dx/mu for x = 0 ... +infty */ double gsl_cdf_exponential_P (const double x, const double mu) { if (x < 0) { return 0; } else { double P = -expm1 (-x / mu); return P; } } double gsl_cdf_exponential_Q (const double x, const double mu) { if (x < 0) { return 1; } else { double Q = exp (-x / mu); return Q; } } praat-6.0.04/external/gsl/gsl_cdf__exponentialinv.c000066400000000000000000000021261261542461700223570ustar00rootroot00000000000000/* cdf/exponentialinv.c * * Copyright (C) 2003, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_cdf.h" double gsl_cdf_exponential_Pinv (const double P, const double mu) { double x = -mu * log1p (-P); return x; } double gsl_cdf_exponential_Qinv (const double Q, const double mu) { double x = -mu * log (Q); return x; } praat-6.0.04/external/gsl/gsl_cdf__exppow.c000066400000000000000000000034461261542461700206440ustar00rootroot00000000000000/* cdf/exppow.c * * Copyright (C) 2004 Giulio Bottazzi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_cdf.h" #include "gsl_sf_gamma.h" /* The exponential power density is parametrized according to p(x) dx = (1/(2 a Gamma(1 + 1/b))) * exp(-|x/a|^b) dx so that the distribution reads / x<0 0.5 - Gamma_inc_P(1/b,|x/a|^b) P(x) = | x=0 0.5 \ x>0 0.5 + Gamma_inc_P(1/b,|x/a|^b) for x in (-infty,+infty) */ double gsl_cdf_exppow_P (const double x, const double a, const double b) { const double u = x / a; if (u < 0) { double P = 0.5 * gsl_sf_gamma_inc_Q (1.0 / b, pow (-u, b)); return P; } else { double P = 0.5 * (1.0 + gsl_sf_gamma_inc_P (1.0 / b, pow (u, b))); return P; } } double gsl_cdf_exppow_Q (const double x, const double a, const double b) { const double u = x / a; if (u < 0) { double Q = 0.5 * (1.0 + gsl_sf_gamma_inc_P (1.0 / b, pow (-u, b))); return Q; } else { double Q = 0.5 * gsl_sf_gamma_inc_Q (1.0 / b, pow (u, b)); return Q; } } praat-6.0.04/external/gsl/gsl_cdf__fdist.c000066400000000000000000000034111261542461700204230ustar00rootroot00000000000000/* cdf/fdist.c * * Copyright (C) 2002 Przemyslaw Sliwa and Jason H. Stover. * Copyright (C) 2006, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #include "gsl__config.h" #include #include "gsl_cdf.h" #include "gsl_sf_gamma.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_cdf__error.h" #include "gsl_cdf__beta_inc.c" /* * Lower tail. */ double gsl_cdf_fdist_P (const double x, const double nu1, const double nu2) { double P; double r = nu2 / nu1; if (x < r) { double u = x / (r + x); P = beta_inc_AXPY (1.0, 0.0, nu1 / 2.0, nu2 / 2.0, u); } else { double u = r / (r + x); P = beta_inc_AXPY (-1.0, 1.0, nu2 / 2.0, nu1 / 2.0, u); } return P; } /* * Upper tail. */ double gsl_cdf_fdist_Q (const double x, const double nu1, const double nu2) { double Q; double r = nu2 / nu1; if (x < r) { double u = x / (r + x); Q = beta_inc_AXPY (-1.0, 1.0, nu1 / 2.0, nu2 / 2.0, u); } else { double u = r / (r + x); Q = beta_inc_AXPY (1.0, 0.0, nu2 / 2.0, nu1 / 2.0, u); } return Q; } praat-6.0.04/external/gsl/gsl_cdf__fdistinv.c000066400000000000000000000043151261542461700211440ustar00rootroot00000000000000/* cdf/fdistinv.c * * Copyright (C) 2002 Przemyslaw Sliwa and Jason H. Stover. * Copyright (C) 2006, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #include "gsl__config.h" #include "gsl_cdf.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_cdf__error.h" double gsl_cdf_fdist_Pinv (const double P, const double nu1, const double nu2) { double result; double y; if (P < 0.0) { CDF_ERROR ("P < 0.0", GSL_EDOM); } if (P > 1.0) { CDF_ERROR ("P > 1.0", GSL_EDOM); } if (nu1 < 1.0) { CDF_ERROR ("nu1 < 1", GSL_EDOM); } if (nu2 < 1.0) { CDF_ERROR ("nu2 < 1", GSL_EDOM); } if (P < 0.5) { y = gsl_cdf_beta_Pinv (P, nu1 / 2.0, nu2 / 2.0); result = nu2 * y / (nu1 * (1.0 - y)); } else { y = gsl_cdf_beta_Qinv (P, nu2 / 2.0, nu1 / 2.0); result = nu2 * (1 - y) / (nu1 * y); } return result; } double gsl_cdf_fdist_Qinv (const double Q, const double nu1, const double nu2) { double result; double y; if (Q < 0.0) { CDF_ERROR ("Q < 0.0", GSL_EDOM); } if (Q > 1.0) { CDF_ERROR ("Q > 1.0", GSL_EDOM); } if (nu1 < 1.0) { CDF_ERROR ("nu1 < 1", GSL_EDOM); } if (nu2 < 1.0) { CDF_ERROR ("nu2 < 1", GSL_EDOM); } if (Q > 0.5) { y = gsl_cdf_beta_Qinv (Q, nu1 / 2.0, nu2 / 2.0); result = nu2 * y / (nu1 * (1.0 - y)); } else { y = gsl_cdf_beta_Pinv (Q, nu2 / 2.0, nu1 / 2.0); result = nu2 * (1 - y) / (nu1 * y); } return result; } praat-6.0.04/external/gsl/gsl_cdf__flat.c000066400000000000000000000024531261542461700202450ustar00rootroot00000000000000/* cdf/flat.c * * Copyright (C) 2003, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_cdf.h" double gsl_cdf_flat_P (const double x, const double a, const double b) { double P; if (x < a) { P = 0; } else if (x > b) { P = 1; } else { P = (x-a)/(b-a); } return P; } double gsl_cdf_flat_Q (const double x, const double a, const double b) { double Q; if (x < a) { Q = 1; } else if (x > b) { Q = 0; } else { Q = (b-x)/(b-a); } return Q; } praat-6.0.04/external/gsl/gsl_cdf__flatinv.c000066400000000000000000000024101261542461700207530ustar00rootroot00000000000000/* cdf/flatinv.c * * Copyright (C) 2003, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_cdf.h" double gsl_cdf_flat_Pinv (const double P, const double a, const double b) { double x; if (P == 1.0) { return b; } else if (P == 0.0) { return a; } x = (1 - P) * a + P * b; return x; } double gsl_cdf_flat_Qinv (const double Q, const double a, const double b) { double x; if (Q == 0.0) { return b; } else if (Q == 1.0) { return a; } x = Q * a + (1 - Q) * b; return x; } praat-6.0.04/external/gsl/gsl_cdf__gamma.c000066400000000000000000000027461261542461700204060ustar00rootroot00000000000000/* cdf/cdf_gamma.c * * Copyright (C) 2003 Jason Stover. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /* * Author: J. Stover */ #include "gsl__config.h" #include #include "gsl_cdf.h" #include "gsl_math.h" #include "gsl_sf_gamma.h" double gsl_cdf_gamma_P (const double x, const double a, const double b) { double P; double y = x / b; if (x <= 0.0) { return 0.0; } if (y > a) { P = 1 - gsl_sf_gamma_inc_Q (a, y); } else { P = gsl_sf_gamma_inc_P (a, y); } return P; } double gsl_cdf_gamma_Q (const double x, const double a, const double b) { double Q; double y = x / b; if (x <= 0.0) { return 1.0; } if (y < a) { Q = 1 - gsl_sf_gamma_inc_P (a, y); } else { Q = gsl_sf_gamma_inc_Q (a, y); } return Q; } praat-6.0.04/external/gsl/gsl_cdf__gammainv.c000066400000000000000000000101151261542461700211100ustar00rootroot00000000000000/* cdf/gammainv.c * * Copyright (C) 2003, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #include "gsl__config.h" #include #include "gsl_cdf.h" #include "gsl_math.h" #include "gsl_randist.h" #include "gsl_sf_gamma.h" #include double gsl_cdf_gamma_Pinv (const double P, const double a, const double b) { double x; if (P == 1.0) { return GSL_POSINF; } else if (P == 0.0) { return 0.0; } /* Consider, small, large and intermediate cases separately. The boundaries at 0.05 and 0.95 have not been optimised, but seem ok for an initial approximation. */ if (P < 0.05) { double x0 = exp ((gsl_sf_lngamma (a) + log (P)) / a); x = x0; } else if (P > 0.95) { double x0 = -log1p (-P) + gsl_sf_lngamma (a); x = x0; } else { double xg = gsl_cdf_ugaussian_Pinv (P); double x0 = (xg < -sqrt (a)) ? a : sqrt (a) * xg + a; x = x0; } /* Use Lagrange's interpolation for E(x)/phi(x0) to work backwards to an improved value of x (Abramowitz & Stegun, 3.6.6) where E(x)=P-integ(phi(u),u,x0,x) and phi(u) is the pdf. */ { double lambda, dP, phi; unsigned int n = 0; start: dP = P - gsl_cdf_gamma_P (x, a, 1.0); phi = gsl_ran_gamma_pdf (x, a, 1.0); if (dP == 0.0 || n++ > 32) goto end; lambda = dP / GSL_MAX (2 * fabs (dP / x), phi); { double step0 = lambda; double step1 = -((a - 1) / x - 1) * lambda * lambda / 4.0; double step = step0; if (fabs (step1) < fabs (step0)) step += step1; if (x + step > 0) x += step; else { x /= 2.0; } if (fabs (step0) > 1e-10 * x) goto start; } end: if (fabs(dP) > GSL_SQRT_DBL_EPSILON * P) { GSL_ERROR_VAL("inverse failed to converge", GSL_EFAILED, GSL_NAN); } return b * x; } } double gsl_cdf_gamma_Qinv (const double Q, const double a, const double b) { double x; if (Q == 1.0) { return 0.0; } else if (Q == 0.0) { return GSL_POSINF; } /* Consider, small, large and intermediate cases separately. The boundaries at 0.05 and 0.95 have not been optimised, but seem ok for an initial approximation. */ if (Q < 0.05) { double x0 = -log (Q) + gsl_sf_lngamma (a); x = x0; } else if (Q > 0.95) { double x0 = exp ((gsl_sf_lngamma (a) + log1p (-Q)) / a); x = x0; } else { double xg = gsl_cdf_ugaussian_Qinv (Q); double x0 = (xg < -sqrt (a)) ? a : sqrt (a) * xg + a; x = x0; } /* Use Lagrange's interpolation for E(x)/phi(x0) to work backwards to an improved value of x (Abramowitz & Stegun, 3.6.6) where E(x)=P-integ(phi(u),u,x0,x) and phi(u) is the pdf. */ { double lambda, dQ, phi; unsigned int n = 0; start: dQ = Q - gsl_cdf_gamma_Q (x, a, 1.0); phi = gsl_ran_gamma_pdf (x, a, 1.0); if (dQ == 0.0 || n++ > 32) goto end; lambda = -dQ / GSL_MAX (2 * fabs (dQ / x), phi); { double step0 = lambda; double step1 = -((a - 1) / x - 1) * lambda * lambda / 4.0; double step = step0; if (fabs (step1) < fabs (step0)) step += step1; if (x + step > 0) x += step; else { x /= 2.0; } if (fabs (step0) > 1e-10 * x) goto start; } } end: return b * x; } praat-6.0.04/external/gsl/gsl_cdf__gauss.c000066400000000000000000000157611261542461700204470ustar00rootroot00000000000000/* cdf/gauss.c * * Copyright (C) 2002, 2004 Jason H. Stover. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /* * Computes the cumulative distribution function for the Gaussian * distribution using a rational function approximation. The * computation is for the standard Normal distribution, i.e., mean 0 * and standard deviation 1. If you want to compute Pr(X < t) for a * Gaussian random variable X with non-zero mean m and standard * deviation sd not equal to 1, find gsl_cdf_ugaussian ((t-m)/sd). * This approximation is accurate to at least double precision. The * accuracy was verified with a pari-gp script. The largest error * found was about 1.4E-20. The coefficients were derived by Cody. * * References: * * W.J. Cody. "Rational Chebyshev Approximations for the Error * Function," Mathematics of Computation, v23 n107 1969, 631-637. * * W. Fraser, J.F Hart. "On the Computation of Rational Approximations * to Continuous Functions," Communications of the ACM, v5 1962. * * W.J. Kennedy Jr., J.E. Gentle. "Statistical Computing." Marcel Dekker. 1980. * * */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_cdf.h" #ifndef M_1_SQRT2PI #define M_1_SQRT2PI (M_2_SQRTPI * M_SQRT1_2 / 2.0) #endif #define SQRT32 (4.0 * M_SQRT2) /* * IEEE double precision dependent constants. * * GAUSS_EPSILON: Smallest positive value such that * gsl_cdf_gaussian(x) > 0.5. * GAUSS_XUPPER: Largest value x such that gsl_cdf_gaussian(x) < 1.0. * GAUSS_XLOWER: Smallest value x such that gsl_cdf_gaussian(x) > 0.0. */ #define GAUSS_EPSILON (GSL_DBL_EPSILON / 2) #define GAUSS_XUPPER (8.572) #define GAUSS_XLOWER (-37.519) #define GAUSS_SCALE (16.0) static double get_del (double x, double rational) { double xsq = 0.0; double del = 0.0; double result = 0.0; xsq = floor (x * GAUSS_SCALE) / GAUSS_SCALE; del = (x - xsq) * (x + xsq); del *= 0.5; result = exp (-0.5 * xsq * xsq) * exp (-1.0 * del) * rational; return result; } /* * Normal cdf for fabs(x) < 0.66291 */ static double gauss_small (const double x) { unsigned int i; double result = 0.0; double xsq; double xnum; double xden; const double a[5] = { 2.2352520354606839287, 161.02823106855587881, 1067.6894854603709582, 18154.981253343561249, 0.065682337918207449113 }; const double b[4] = { 47.20258190468824187, 976.09855173777669322, 10260.932208618978205, 45507.789335026729956 }; xsq = x * x; xnum = a[4] * xsq; xden = xsq; for (i = 0; i < 3; i++) { xnum = (xnum + a[i]) * xsq; xden = (xden + b[i]) * xsq; } result = x * (xnum + a[3]) / (xden + b[3]); return result; } /* * Normal cdf for 0.66291 < fabs(x) < sqrt(32). */ static double gauss_medium (const double x) { unsigned int i; double temp = 0.0; double result = 0.0; double xnum; double xden; double absx; const double c[9] = { 0.39894151208813466764, 8.8831497943883759412, 93.506656132177855979, 597.27027639480026226, 2494.5375852903726711, 6848.1904505362823326, 11602.651437647350124, 9842.7148383839780218, 1.0765576773720192317e-8 }; const double d[8] = { 22.266688044328115691, 235.38790178262499861, 1519.377599407554805, 6485.558298266760755, 18615.571640885098091, 34900.952721145977266, 38912.003286093271411, 19685.429676859990727 }; absx = fabs (x); xnum = c[8] * absx; xden = absx; for (i = 0; i < 7; i++) { xnum = (xnum + c[i]) * absx; xden = (xden + d[i]) * absx; } temp = (xnum + c[7]) / (xden + d[7]); result = get_del (x, temp); return result; } /* * Normal cdf for * {sqrt(32) < x < GAUSS_XUPPER} union { GAUSS_XLOWER < x < -sqrt(32) }. */ static double gauss_large (const double x) { int i; double result; double xsq; double temp; double xnum; double xden; double absx; const double p[6] = { 0.21589853405795699, 0.1274011611602473639, 0.022235277870649807, 0.001421619193227893466, 2.9112874951168792e-5, 0.02307344176494017303 }; const double q[5] = { 1.28426009614491121, 0.468238212480865118, 0.0659881378689285515, 0.00378239633202758244, 7.29751555083966205e-5 }; absx = fabs (x); xsq = 1.0 / (x * x); xnum = p[5] * xsq; xden = xsq; for (i = 0; i < 4; i++) { xnum = (xnum + p[i]) * xsq; xden = (xden + q[i]) * xsq; } temp = xsq * (xnum + p[4]) / (xden + q[4]); temp = (M_1_SQRT2PI - temp) / absx; result = get_del (x, temp); return result; } double gsl_cdf_ugaussian_P (const double x) { double result; double absx = fabs (x); if (absx < GAUSS_EPSILON) { result = 0.5; return result; } else if (absx < 0.66291) { result = 0.5 + gauss_small (x); return result; } else if (absx < SQRT32) { result = gauss_medium (x); if (x > 0.0) { result = 1.0 - result; } return result; } else if (x > GAUSS_XUPPER) { result = 1.0; return result; } else if (x < GAUSS_XLOWER) { result = 0.0; return result; } else { result = gauss_large (x); if (x > 0.0) { result = 1.0 - result; } } return result; } double gsl_cdf_ugaussian_Q (const double x) { double result; double absx = fabs (x); if (absx < GAUSS_EPSILON) { result = 0.5; return result; } else if (absx < 0.66291) { result = gauss_small (x); if (x < 0.0) { result = fabs (result) + 0.5; } else { result = 0.5 - result; } return result; } else if (absx < SQRT32) { result = gauss_medium (x); if (x < 0.0) { result = 1.0 - result; } return result; } else if (x > -(GAUSS_XLOWER)) { result = 0.0; return result; } else if (x < -(GAUSS_XUPPER)) { result = 1.0; return result; } else { result = gauss_large (x); if (x < 0.0) { result = 1.0 - result; } } return result; } double gsl_cdf_gaussian_P (const double x, const double sigma) { return gsl_cdf_ugaussian_P (x / sigma); } double gsl_cdf_gaussian_Q (const double x, const double sigma) { return gsl_cdf_ugaussian_Q (x / sigma); } praat-6.0.04/external/gsl/gsl_cdf__gaussinv.c000066400000000000000000000100441261542461700211510ustar00rootroot00000000000000/* cdf/inverse_normal.c * * Copyright (C) 2002 Przemyslaw Sliwa and Jason H. Stover. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /* * Computes the inverse normal cumulative distribution function * according to the algorithm shown in * * Wichura, M.J. (1988). * Algorithm AS 241: The Percentage Points of the Normal Distribution. * Applied Statistics, 37, 477-484. */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_math.h" #include "gsl_cdf.h" #include "gsl_cdf__rat_eval.h" static double small (double q) { const double a[8] = { 3.387132872796366608, 133.14166789178437745, 1971.5909503065514427, 13731.693765509461125, 45921.953931549871457, 67265.770927008700853, 33430.575583588128105, 2509.0809287301226727 }; const double b[8] = { 1.0, 42.313330701600911252, 687.1870074920579083, 5394.1960214247511077, 21213.794301586595867, 39307.89580009271061, 28729.085735721942674, 5226.495278852854561 }; double r = 0.180625 - q * q; double x = q * rat_eval (a, 8, b, 8, r); return x; } static double intermediate (double r) { const double a[] = { 1.42343711074968357734, 4.6303378461565452959, 5.7694972214606914055, 3.64784832476320460504, 1.27045825245236838258, 0.24178072517745061177, 0.0227238449892691845833, 7.7454501427834140764e-4 }; const double b[] = { 1.0, 2.05319162663775882187, 1.6763848301838038494, 0.68976733498510000455, 0.14810397642748007459, 0.0151986665636164571966, 5.475938084995344946e-4, 1.05075007164441684324e-9 }; double x = rat_eval (a, 8, b, 8, (r - 1.6)); return x; } static double tail (double r) { const double a[] = { 6.6579046435011037772, 5.4637849111641143699, 1.7848265399172913358, 0.29656057182850489123, 0.026532189526576123093, 0.0012426609473880784386, 2.71155556874348757815e-5, 2.01033439929228813265e-7 }; const double b[] = { 1.0, 0.59983220655588793769, 0.13692988092273580531, 0.0148753612908506148525, 7.868691311456132591e-4, 1.8463183175100546818e-5, 1.4215117583164458887e-7, 2.04426310338993978564e-15 }; double x = rat_eval (a, 8, b, 8, (r - 5.0)); return x; } double gsl_cdf_ugaussian_Pinv (const double P) { double r, x, pp; double dP = P - 0.5; if (P == 1.0) { return GSL_POSINF; } else if (P == 0.0) { return GSL_NEGINF; } if (fabs (dP) <= 0.425) { x = small (dP); return x; } pp = (P < 0.5) ? P : 1.0 - P; r = sqrt (-log (pp)); if (r <= 5.0) { x = intermediate (r); } else { x = tail (r); } if (P < 0.5) { return -x; } else { return x; } } double gsl_cdf_ugaussian_Qinv (const double Q) { double r, x, pp; double dQ = Q - 0.5; if (Q == 1.0) { return GSL_NEGINF; } else if (Q == 0.0) { return GSL_POSINF; } if (fabs (dQ) <= 0.425) { x = small (dQ); return -x; } pp = (Q < 0.5) ? Q : 1.0 - Q; r = sqrt (-log (pp)); if (r <= 5.0) { x = intermediate (r); } else { x = tail (r); } if (Q < 0.5) { return x; } else { return -x; } } double gsl_cdf_gaussian_Pinv (const double P, const double sigma) { return sigma * gsl_cdf_ugaussian_Pinv (P); } double gsl_cdf_gaussian_Qinv (const double Q, const double sigma) { return sigma * gsl_cdf_ugaussian_Qinv (Q); } praat-6.0.04/external/gsl/gsl_cdf__geometric.c000066400000000000000000000033301261542461700212700ustar00rootroot00000000000000/* cdf/geometric.c * * Copyright (C) 2004 Jason H. Stover. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_cdf.h" #include "gsl_cdf__error.h" /* Pr (X <= k), i.e., the probability of n or fewer failures until the first success. */ double gsl_cdf_geometric_P (const unsigned int k, const double p) { double P, a, q; if (p > 1.0 || p < 0.0) { CDF_ERROR ("p < 0 or p > 1", GSL_EDOM); } if (k < 1) { return 0.0; } q = 1.0 - p; a = (double) k; if (p < 0.5) { P = -expm1 (a * log1p (-p)); } else { P = 1.0 - pow (q, a); } return P; } double gsl_cdf_geometric_Q (const unsigned int k, const double p) { double Q, a, q; if (p > 1.0 || p < 0.0) { CDF_ERROR ("p < 0 or p > 1", GSL_EDOM); } if (k < 1) { Q = 1.0; } q = 1.0 - p; a = (double) k; if (p < 0.5) { Q = exp (a * log1p (-p)); } else { Q = pow (q, a); } return Q; } praat-6.0.04/external/gsl/gsl_cdf__gumbel1.c000066400000000000000000000023601261542461700206500ustar00rootroot00000000000000/* cdf/gumbel1.c * * Copyright (C) 2003, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_cdf.h" double gsl_cdf_gumbel1_P (const double x, const double a, const double b) { double P = pow(exp (-b), exp (-a * x)); return P; } double gsl_cdf_gumbel1_Q (const double x, const double a, const double b) { double u = exp (-a * x); double Q; double P = pow(exp (-b), u); if (P < 0.5) { Q = 1 - P; } else { Q = -expm1 (-b * u); } return Q; } praat-6.0.04/external/gsl/gsl_cdf__gumbel1inv.c000066400000000000000000000025421261542461700213670ustar00rootroot00000000000000/* cdf/gumbel1inv.c * * Copyright (C) 2003, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_cdf.h" double gsl_cdf_gumbel1_Pinv (const double P, const double a, const double b) { double x; if (P == 1.0) { return GSL_POSINF; } else if (P == 0.0) { return GSL_NEGINF; } x = log(-b / log(P)) / a; return x; } double gsl_cdf_gumbel1_Qinv (const double Q, const double a, const double b) { double x; if (Q == 0.0) { return GSL_POSINF; } else if (Q == 1.0) { return GSL_NEGINF; } x = log(-b / log1p(-Q)) / a; return x; } praat-6.0.04/external/gsl/gsl_cdf__gumbel2.c000066400000000000000000000024371261542461700206560ustar00rootroot00000000000000/* cdf/gumbel2.c * * Copyright (C) 2003, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_cdf.h" double gsl_cdf_gumbel2_P (const double x, const double a, const double b) { double P; if (x == 0) { P = 0; } else { double u = pow (x, a); P = exp (-b / u); } return P; } double gsl_cdf_gumbel2_Q (const double x, const double a, const double b) { double Q; if (x == 0) { Q = 1; } else { double u = pow (x, a); Q = -expm1 (-b / u); } return Q; } praat-6.0.04/external/gsl/gsl_cdf__gumbel2inv.c000066400000000000000000000025321261542461700213670ustar00rootroot00000000000000/* cdf/gumbel2inv.c * * Copyright (C) 2003, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_cdf.h" double gsl_cdf_gumbel2_Pinv (const double P, const double a, const double b) { double x; if (P == 1.0) { return GSL_POSINF; } else if (P == 0.0) { return 0.0; } x = pow(b / (-log(P)), 1/a); return x; } double gsl_cdf_gumbel2_Qinv (const double Q, const double a, const double b) { double x; if (Q == 0.0) { return GSL_POSINF; } else if (Q == 1.0) { return 0.0; } x = pow(b / (-log1p(-Q)), 1/a); return x; } praat-6.0.04/external/gsl/gsl_cdf__hypergeometric.c000066400000000000000000000101441261542461700223410ustar00rootroot00000000000000/* cdf/hypergeometric.c * * Copyright (C) 2004 Jason H. Stover. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /* * Computes the cumulative distribution function for a hypergeometric * random variable. A hypergeometric random variable X is the number * of elements of type 1 in a sample of size t, drawn from a population * of size n1 + n2, in which n1 are of type 1 and n2 are of type 2. * * This algorithm computes Pr( X <= k ) by summing the terms from * the mass function, Pr( X = k ). * * References: * * T. Wu. An accurate computation of the hypergeometric distribution * function. ACM Transactions on Mathematical Software. Volume 19, number 1, * March 1993. * This algorithm is not used, since it requires factoring the * numerator and denominator, then cancelling. It is more accurate * than the algorithm used here, but the cancellation requires more * time than the algorithm used here. * * W. Feller. An Introduction to Probability Theory and Its Applications, * third edition. 1968. Chapter 2, section 6. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_cdf.h" #include "gsl_randist.h" #include "gsl_cdf__error.h" static double lower_tail (const unsigned int k, const unsigned int n1, const unsigned int n2, const unsigned int t) { double relerr; int i = k; double s, P; s = gsl_ran_hypergeometric_pdf (i, n1, n2, t); P = s; while (i > 0) { double factor = (i / (n1 - i + 1.0)) * ((n2 + i - t) / (t - i + 1.0)); s *= factor; P += s; relerr = s / P; if (relerr < GSL_DBL_EPSILON) break; i--; } return P; } static double upper_tail (const unsigned int k, const unsigned int n1, const unsigned int n2, const unsigned int t) { double relerr; unsigned int i = k + 1; double s, Q; s = gsl_ran_hypergeometric_pdf (i, n1, n2, t); Q = s; while (i < t) { double factor = ((n1 - i) / (i + 1.0)) * ((t - i) / (n2 + i + 1.0 - t)); s *= factor; Q += s; relerr = s / Q; if (relerr < GSL_DBL_EPSILON) break; i++; } return Q; } /* * Pr (X <= k) */ double gsl_cdf_hypergeometric_P (const unsigned int k, const unsigned int n1, const unsigned int n2, const unsigned int t) { double P; if (t > (n1 + n2)) { CDF_ERROR ("t larger than population size", GSL_EDOM); } else if (k >= n1 || k >= t) { P = 1.0; } else if (k < 0.0) { P = 0.0; } else { double midpoint = (int) (t * n1 / (n1 + n2)); if (k >= midpoint) { P = 1 - upper_tail (k, n1, n2, t); } else { P = lower_tail (k, n1, n2, t); } } return P; } /* * Pr (X > k) */ double gsl_cdf_hypergeometric_Q (const unsigned int k, const unsigned int n1, const unsigned int n2, const unsigned int t) { double Q; if (t > (n1 + n2)) { CDF_ERROR ("t larger than population size", GSL_EDOM); } else if (k >= n1 || k >= t) { Q = 0.0; } else if (k < 0.0) { Q = 1.0; } else { double midpoint = (int) (t * n1 / (n1 + n2)); if (k < midpoint) { Q = 1 - lower_tail (k, n1, n2, t); } else { Q = upper_tail (k, n1, n2, t); } } return Q; } praat-6.0.04/external/gsl/gsl_cdf__laplace.c000066400000000000000000000024221261542461700207140ustar00rootroot00000000000000/* cdf/laplace.c * * Copyright (C) 2003, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_cdf.h" double gsl_cdf_laplace_P (const double x, const double a) { double P; double u = x / a; if (u > 0) { P = 0.5 + 0.5*(1 - exp(-u)) ; } else { P = 0.5 * exp(u); } return P; } double gsl_cdf_laplace_Q (const double x, const double a) { double Q; double u = x / a; if (u > 0) { Q = 0.5 * exp(-u); } else { Q = 1 - 0.5 *exp(u); } return Q; } praat-6.0.04/external/gsl/gsl_cdf__laplaceinv.c000066400000000000000000000027151261542461700214360ustar00rootroot00000000000000/* cdf/laplaceinv.c * * Copyright (C) 2003, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_cdf.h" double gsl_cdf_laplace_Pinv (const double P, const double a) { double x; if (P == 1.0) { return GSL_POSINF; } else if (P == 0.0) { return GSL_NEGINF; } if (P < 0.5) { x = a * log(2*P); } else { x = -a * log(2*(1-P)); } return x; } double gsl_cdf_laplace_Qinv (const double Q, const double a) { double x; if (Q == 0.0) { return GSL_POSINF; } else if (Q == 1.0) { return GSL_NEGINF; } if (Q < 0.5) { x = -a * log(2*Q); } else { x = a * log(2*(1-Q)); } return x; } praat-6.0.04/external/gsl/gsl_cdf__logistic.c000066400000000000000000000024461261542461700211360ustar00rootroot00000000000000/* cdf/logistic.c * * Copyright (C) 2003, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_cdf.h" double gsl_cdf_logistic_P (const double x, const double a) { double P; double u = x / a; if (u >= 0) { P = 1 / (1 + exp (-u)); } else { P = exp (u) / (1 + exp (u)); } return P; } double gsl_cdf_logistic_Q (const double x, const double a) { double Q; double u = x / a; if (u >= 0) { Q = exp (-u) / (1 + exp (-u)); } else { Q = 1 / (1 + exp (u)); } return Q; } praat-6.0.04/external/gsl/gsl_cdf__logisticinv.c000066400000000000000000000024721261542461700216520ustar00rootroot00000000000000/* cdf/logisticinv.c * * Copyright (C) 2003, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_cdf.h" double gsl_cdf_logistic_Pinv (const double P, const double a) { double x; if (P == 1.0) { return GSL_POSINF; } else if (P == 0.0) { return GSL_NEGINF; } x = a * log(P/(1-P)); return x; } double gsl_cdf_logistic_Qinv (const double Q, const double a) { double x; if (Q == 0.0) { return GSL_POSINF; } else if (Q == 1.0) { return GSL_NEGINF; } x = a * log((1-Q)/Q); return x; } praat-6.0.04/external/gsl/gsl_cdf__lognormal.c000066400000000000000000000023201261542461700213020ustar00rootroot00000000000000/* cdf/lognormal.c * * Copyright (C) 2003, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_cdf.h" double gsl_cdf_lognormal_P (const double x, const double zeta, const double sigma) { double u = (log (x) - zeta) / sigma; double P = gsl_cdf_ugaussian_P (u); return P; } double gsl_cdf_lognormal_Q (const double x, const double zeta, const double sigma) { double u = (log (x) - zeta) / sigma; double Q = gsl_cdf_ugaussian_Q (u); return Q; } praat-6.0.04/external/gsl/gsl_cdf__lognormalinv.c000066400000000000000000000026651261542461700220330ustar00rootroot00000000000000/* cdf/lognormalinv.c * * Copyright (C) 2003, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_cdf.h" double gsl_cdf_lognormal_Pinv (const double P, const double zeta, const double sigma) { double x, u; if (P == 1.0) { return GSL_POSINF; } else if (P == 0.0) { return 0.0; } u = gsl_cdf_ugaussian_Pinv (P); x = exp (zeta + sigma * u); return x; } double gsl_cdf_lognormal_Qinv (const double Q, const double zeta, const double sigma) { double x, u; if (Q == 0.0) { return GSL_POSINF; } else if (Q == 1.0) { return 0.0; } u = gsl_cdf_ugaussian_Qinv (Q); x = exp (zeta + sigma * u); return x; } praat-6.0.04/external/gsl/gsl_cdf__nbinomial.c000066400000000000000000000034221261542461700212640ustar00rootroot00000000000000/* cdf/negbinom.c * * Copyright (C) 2004 Jason H. Stover. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_cdf.h" #include "gsl_cdf__error.h" /* * Pr(X <= k) for a negative binomial random variable X, i.e., * the probability of k or fewer failuers before success n. */ double gsl_cdf_negative_binomial_P (const unsigned int k, const double p, const double n) { double P; double a; double b; if (p > 1.0 || p < 0.0) { CDF_ERROR ("p < 0 or p > 1", GSL_EDOM); } if (n < 0) { CDF_ERROR ("n < 0", GSL_EDOM); } a = (double) n; b = (double) k + 1.0; P = gsl_cdf_beta_P (p, a, b); return P; } /* * Pr ( X > k ). */ double gsl_cdf_negative_binomial_Q (const unsigned int k, const double p, const double n) { double Q; double a; double b; if (p > 1.0 || p < 0.0) { CDF_ERROR ("p < 0 or p > 1", GSL_EDOM); } if (n < 0) { CDF_ERROR ("n < 0", GSL_EDOM); } a = (double) n; b = (double) k + 1.0; Q = gsl_cdf_beta_Q (p, a, b); return Q; } praat-6.0.04/external/gsl/gsl_cdf__pareto.c000066400000000000000000000023401261542461700206040ustar00rootroot00000000000000/* cdf/pareto.c * * Copyright (C) 2003, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_cdf.h" double gsl_cdf_pareto_P (const double x, const double a, const double b) { double P; if (x < b) { P = 0; } else { P = 1 - pow(b/x, a); } return P; } double gsl_cdf_pareto_Q (const double x, const double a, const double b) { double Q; if (x < b) { Q = 1; } else { Q = pow(b/x, a); } return Q; } praat-6.0.04/external/gsl/gsl_cdf__paretoinv.c000066400000000000000000000025131261542461700213230ustar00rootroot00000000000000/* cdf/paretoinv.c * * Copyright (C) 2003, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_cdf.h" double gsl_cdf_pareto_Pinv (const double P, const double a, const double b) { double x; if (P == 1.0) { return GSL_POSINF; } else if (P == 0.0) { return b; } x = b * exp(-log1p(-P)/a); return x; } double gsl_cdf_pareto_Qinv (const double Q, const double a, const double b) { double x; if (Q == 0.0) { return GSL_POSINF; } else if (Q == 1.0) { return b; } x = b * exp(-log(Q) / a); return x; } praat-6.0.04/external/gsl/gsl_cdf__pascal.c000066400000000000000000000023761261542461700205660ustar00rootroot00000000000000/* cdf/pascal.c * * Copyright (C) 2006, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_cdf.h" /* The Pascal distribution is a negative binomial with valued integer n */ double gsl_cdf_pascal_P (const unsigned int k, const double p, const unsigned int n) { double P = gsl_cdf_negative_binomial_P (k, p, (double) n); return P; } double gsl_cdf_pascal_Q (const unsigned int k, const double p, const unsigned int n) { double Q = gsl_cdf_negative_binomial_Q (k, p, (double) n); return Q; } praat-6.0.04/external/gsl/gsl_cdf__poisson.c000066400000000000000000000035741261542461700210160ustar00rootroot00000000000000/* cdf/poisson.c * * Copyright (C) 2004 Jason H. Stover. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /* * Computes the cumulative distribution function for a Poisson * random variable. For a Poisson random variable X with parameter * mu, * * Pr( X <= k ) = Pr( Y >= p ) * * where Y is a gamma random variable with parameters k+1 and 1. * * Reference: * * W. Feller, "An Introduction to Probability and Its * Applications," volume 1. Wiley, 1968. Exercise 46, page 173, * chapter 6. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_cdf.h" #include "gsl_cdf__error.h" /* * Pr (X <= k) for a Poisson random variable X. */ double gsl_cdf_poisson_P (const unsigned int k, const double mu) { double P; double a; if (mu <= 0.0) { CDF_ERROR ("mu <= 0", GSL_EDOM); } a = (double) k + 1.0; P = gsl_cdf_gamma_Q (mu, a, 1.0); return P; } /* * Pr ( X > k ) for a Possion random variable X. */ double gsl_cdf_poisson_Q (const unsigned int k, const double mu) { double Q; double a; if (mu <= 0.0) { CDF_ERROR ("mu <= 0", GSL_EDOM); } a = (double) k + 1.0; Q = gsl_cdf_gamma_P (mu, a, 1.0); return Q; } praat-6.0.04/external/gsl/gsl_cdf__rat_eval.h000066400000000000000000000005541261542461700211210ustar00rootroot00000000000000static double rat_eval (const double a[], const size_t na, const double b[], const size_t nb, const double x) { size_t i, j; double u, v, r; u = a[na - 1]; for (i = na - 1; i > 0; i--) { u = x * u + a[i - 1]; } v = b[nb - 1]; for (j = nb - 1; j > 0; j--) { v = x * v + b[j - 1]; } r = u / v; return r; } praat-6.0.04/external/gsl/gsl_cdf__rayleigh.c000066400000000000000000000021661261542461700211240ustar00rootroot00000000000000/* cdf/rayleigh.c * * Copyright (C) 2003, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_cdf.h" double gsl_cdf_rayleigh_P (const double x, const double sigma) { double u = x / sigma; double P = -expm1 (-u*u/2); return P; } double gsl_cdf_rayleigh_Q (const double x, const double sigma) { double u = x / sigma; double Q = exp (-u*u/2); return Q; } praat-6.0.04/external/gsl/gsl_cdf__rayleighinv.c000066400000000000000000000025311261542461700216350ustar00rootroot00000000000000/* cdf/rayleighinv.c * * Copyright (C) 2003, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_cdf.h" double gsl_cdf_rayleigh_Pinv (const double P, const double sigma) { double x; if (P == 1.0) { return GSL_POSINF; } else if (P == 0.0) { return 0.0; } x = sigma * M_SQRT2 * sqrt (-log1p (-P)); return x; } double gsl_cdf_rayleigh_Qinv (const double Q, const double sigma) { double x; if (Q == 0.0) { return GSL_POSINF; } else if (Q == 1.0) { return 0.0; } x = sigma * M_SQRT2 * sqrt (-log (Q)); return x; } praat-6.0.04/external/gsl/gsl_cdf__tdist.c000066400000000000000000000131241261542461700204430ustar00rootroot00000000000000/* cdf/tdist.c * * Copyright (C) 2002 Jason H. Stover. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /* * Computes the Student's t cumulative distribution function using * the method detailed in * * W.J. Kennedy and J.E. Gentle, "Statistical Computing." 1980. * Marcel Dekker. ISBN 0-8247-6898-1. * * G.W. Hill and A.W. Davis. "Generalized asymptotic expansions * of Cornish-Fisher type." Annals of Mathematical Statistics, * vol. 39, 1264-1273. 1968. * * G.W. Hill. "Algorithm 395: Student's t-distribution," Communications * of the ACM, volume 13, number 10, page 617. October 1970. * * G.W. Hill, "Remark on algorithm 395: Student's t-distribution," * Transactions on Mathematical Software, volume 7, number 2, page * 247. June 1982. */ #include "gsl__config.h" #include "gsl_cdf.h" #include "gsl_sf_gamma.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_cdf__beta_inc.c" static double poly_eval (const double c[], unsigned int n, double x) { unsigned int i; double y = c[0] * x; for (i = 1; i < n; i++) { y = x * (y + c[i]); } y += c[n]; return y; } /* * Use the Cornish-Fisher asymptotic expansion to find a point u such * that gsl_cdf_gauss(y) = tcdf(t). * */ static double cornish_fisher (double t, double n) { const double coeffs6[10] = { 0.265974025974025974026, 5.449696969696969696970, 122.20294372294372294372, 2354.7298701298701298701, 37625.00902597402597403, 486996.1392857142857143, 4960870.65, 37978595.55, 201505390.875, 622437908.625 }; const double coeffs5[8] = { 0.2742857142857142857142, 4.499047619047619047619, 78.45142857142857142857, 1118.710714285714285714, 12387.6, 101024.55, 559494.0, 1764959.625 }; const double coeffs4[6] = { 0.3047619047619047619048, 3.752380952380952380952, 46.67142857142857142857, 427.5, 2587.5, 8518.5 }; const double coeffs3[4] = { 0.4, 3.3, 24.0, 85.5 }; double a = n - 0.5; double b = 48.0 * a * a; double z2 = a * log1p (t * t / n); double z = sqrt (z2); double p5 = z * poly_eval (coeffs6, 9, z2); double p4 = -z * poly_eval (coeffs5, 7, z2); double p3 = z * poly_eval (coeffs4, 5, z2); double p2 = -z * poly_eval (coeffs3, 3, z2); double p1 = z * (z2 + 3.0); double p0 = z; double y = p5; y = (y / b) + p4; y = (y / b) + p3; y = (y / b) + p2; y = (y / b) + p1; y = (y / b) + p0; if (t < 0) y *= -1; return y; } #if 0 /* * Series approximation for t > 4.0. This needs to be fixed; * it shouldn't subtract the result from 1.0. A better way is * to use two different series expansions. Figuring this out * means rummaging through Fisher's paper in Metron, v5, 1926, * "Expansion of Student's integral in powers of n^{-1}." */ #define MAXI 40 static double normal_approx (const double x, const double nu) { double y; double num; double diff; double q; int i; double lg1, lg2; y = 1 / sqrt (1 + x * x / nu); num = 1.0; q = 0.0; diff = 2 * GSL_DBL_EPSILON; for (i = 2; (i < MAXI) && (diff > GSL_DBL_EPSILON); i += 2) { diff = q; num *= y * y * (i - 1) / i; q += num / (nu + i); diff = q - diff; } q += 1 / nu; lg1 = gsl_sf_lngamma (nu / 2.0); lg2 = gsl_sf_lngamma ((nu + 1.0) / 2.0); diff = lg2 - lg1; q *= pow (y, nu) * exp (diff) / sqrt (M_PI); return q; } #endif double gsl_cdf_tdist_P (const double x, const double nu) { double P; double x2 = x * x; if (nu > 30 && x2 < 10 * nu) { double u = cornish_fisher (x, nu); P = gsl_cdf_ugaussian_P (u); return P; } if (x2 < nu) { double u = x2 / nu; double eps = u / (1 + u); if (x >= 0) { P = beta_inc_AXPY (0.5, 0.5, 0.5, nu / 2.0, eps); } else { P = beta_inc_AXPY (-0.5, 0.5, 0.5, nu / 2.0, eps); } } else { double v = nu / (x * x); double eps = v / (1 + v); if (x >= 0) { P = beta_inc_AXPY (-0.5, 1.0, nu / 2.0, 0.5, eps); } else { P = beta_inc_AXPY (0.5, 0.0, nu / 2.0, 0.5, eps); } } return P; } double gsl_cdf_tdist_Q (const double x, const double nu) { double Q; double x2 = x * x; if (nu > 30 && x2 < 10 * nu) { double u = cornish_fisher (x, nu); Q = gsl_cdf_ugaussian_Q (u); return Q; } if (x2 < nu) { double u = x2 / nu; double eps = u / (1 + u); if (x >= 0) { Q = beta_inc_AXPY (-0.5, 0.5, 0.5, nu / 2.0, eps); } else { Q = beta_inc_AXPY (0.5, 0.5, 0.5, nu / 2.0, eps); } } else { double v = nu / (x * x); double eps = v / (1 + v); if (x >= 0) { Q = beta_inc_AXPY (0.5, 0.0, nu / 2.0, 0.5, eps); } else { Q = beta_inc_AXPY (-0.5, 1.0, nu / 2.0, 0.5, eps); } } return Q; } praat-6.0.04/external/gsl/gsl_cdf__tdistinv.c000066400000000000000000000120051261542461700211550ustar00rootroot00000000000000/* cdf/tdistinv.c * * Copyright (C) 2007 Brian Gough * Copyright (C) 2002 Jason H. Stover. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #include "gsl__config.h" #include #include "gsl_cdf.h" #include "gsl_math.h" #include "gsl_randist.h" #include "gsl_sf_gamma.h" #include static double inv_cornish_fisher (double z, double nu) { double a = 1 / (nu - 0.5); double b = 48.0 / (a * a); double cf1 = z * (3 + z * z); double cf2 = z * (945 + z * z * (360 + z * z * (63 + z * z * 4))); double y = z - cf1 / b + cf2 / (10 * b * b); double t = GSL_SIGN (z) * sqrt (nu * expm1 (a * y * y)); return t; } double gsl_cdf_tdist_Pinv (const double P, const double nu) { double x, ptail; if (P == 1.0) { return GSL_POSINF; } else if (P == 0.0) { return GSL_NEGINF; } if (nu == 1.0) { x = tan (M_PI * (P - 0.5)); } else if (nu == 2.0) { double a = 2 * P - 1; x = a / sqrt (2 * (1 - a * a)); } ptail = (P < 0.5) ? P : 1 - P; if (sqrt (M_PI * nu / 2) * ptail > pow (0.05, nu / 2)) { double xg = gsl_cdf_ugaussian_Pinv (P); x = inv_cornish_fisher (xg, nu); } else { /* Use an asymptotic expansion of the tail of integral */ double beta = gsl_sf_beta (0.5, nu / 2); if (P < 0.5) { x = -sqrt (nu) * pow (beta * nu * P, -1.0 / nu); } else { x = sqrt (nu) * pow (beta * nu * (1 - P), -1.0 / nu); } /* Correct nu -> nu/(1+nu/x^2) in the leading term to account for higher order terms. This avoids overestimating x, which makes the iteration unstable due to the rapidly decreasing tails of the distribution. */ x /= sqrt (1 + nu / (x * x)); } { double dP, phi; unsigned int n = 0; start: dP = P - gsl_cdf_tdist_P (x, nu); phi = gsl_ran_tdist_pdf (x, nu); if (dP == 0.0 || n++ > 32) goto end; { double lambda = dP / phi; double step0 = lambda; double step1 = ((nu + 1) * x / (x * x + nu)) * (lambda * lambda / 4.0); double step = step0; if (fabs (step1) < fabs (step0)) { step += step1; } if (P > 0.5 && x + step < 0) x /= 2; else if (P < 0.5 && x + step > 0) x /= 2; else x += step; if (fabs (step) > 1e-10 * fabs (x)) goto start; } end: if (fabs(dP) > GSL_SQRT_DBL_EPSILON * P) { GSL_ERROR_VAL("inverse failed to converge", GSL_EFAILED, GSL_NAN); } return x; } } double gsl_cdf_tdist_Qinv (const double Q, const double nu) { double x, qtail; if (Q == 0.0) { return GSL_POSINF; } else if (Q == 1.0) { return GSL_NEGINF; } if (nu == 1.0) { x = tan (M_PI * (0.5 - Q)); } else if (nu == 2.0) { double a = 2 * (1 - Q) - 1; x = a / sqrt (2 * (1 - a * a)); } qtail = (Q < 0.5) ? Q : 1 - Q; if (sqrt (M_PI * nu / 2) * qtail > pow (0.05, nu / 2)) { double xg = gsl_cdf_ugaussian_Qinv (Q); x = inv_cornish_fisher (xg, nu); } else { /* Use an asymptotic expansion of the tail of integral */ double beta = gsl_sf_beta (0.5, nu / 2); if (Q < 0.5) { x = sqrt (nu) * pow (beta * nu * Q, -1.0 / nu); } else { x = -sqrt (nu) * pow (beta * nu * (1 - Q), -1.0 / nu); } /* Correct nu -> nu/(1+nu/x^2) in the leading term to account for higher order terms. This avoids overestimating x, which makes the iteration unstable due to the rapidly decreasing tails of the distribution. */ x /= sqrt (1 + nu / (x * x)); } { double dQ, phi; unsigned int n = 0; start: dQ = Q - gsl_cdf_tdist_Q (x, nu); phi = gsl_ran_tdist_pdf (x, nu); if (dQ == 0.0 || n++ > 32) goto end; { double lambda = - dQ / phi; double step0 = lambda; double step1 = ((nu + 1) * x / (x * x + nu)) * (lambda * lambda / 4.0); double step = step0; if (fabs (step1) < fabs (step0)) { step += step1; } if (Q < 0.5 && x + step < 0) x /= 2; else if (Q > 0.5 && x + step > 0) x /= 2; else x += step; if (fabs (step) > 1e-10 * fabs (x)) goto start; } } end: return x; } praat-6.0.04/external/gsl/gsl_cdf__weibull.c000066400000000000000000000021471261542461700207620ustar00rootroot00000000000000/* cdf/weibull.c * * Copyright (C) 2003, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_cdf.h" double gsl_cdf_weibull_P (const double x, const double a, const double b) { double P = -expm1 (-pow(x/a, b)); return P; } double gsl_cdf_weibull_Q (const double x, const double a, const double b) { double Q = exp (-pow(x/a, b)); return Q; } praat-6.0.04/external/gsl/gsl_cdf__weibullinv.c000066400000000000000000000025261261542461700215000ustar00rootroot00000000000000/* cdf/weibullinv.c * * Copyright (C) 2003, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_cdf.h" double gsl_cdf_weibull_Pinv (const double P, const double a, const double b) { double x; if (P == 1.0) { return GSL_POSINF; } else if (P == 0.0) { return 0.0; } x = a * pow(-log1p(-P), 1/b); return x; } double gsl_cdf_weibull_Qinv (const double Q, const double a, const double b) { double x; if (Q == 0.0) { return GSL_POSINF; } else if (Q == 1.0) { return 0.0; } x = a * pow(-log(Q), 1/b); return x; } praat-6.0.04/external/gsl/gsl_chebyshev.h000066400000000000000000000102541261542461700203270ustar00rootroot00000000000000/* cheb/gsl_chebyshev.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_CHEBYSHEV_H__ #define __GSL_CHEBYSHEV_H__ #include "gsl_math.h" #include "gsl_mode.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* data for a Chebyshev series over a given interval */ struct gsl_cheb_series_struct { double * c; /* coefficients */ size_t order; /* order of expansion */ double a; /* lower interval point */ double b; /* upper interval point */ /* The following exists (mostly) for the benefit * of the implementation. It is an effective single * precision order, for use in single precision * evaluation. Users can use it if they like, but * only they know how to calculate it, since it is * specific to the approximated function. By default, * order_sp = order. * It is used explicitly only by the gsl_cheb_eval_mode * functions, which are not meant for casual use. */ size_t order_sp; /* Additional elements not used by specfunc */ double * f; /* function evaluated at chebyschev points */ }; typedef struct gsl_cheb_series_struct gsl_cheb_series; /* Calculate a Chebyshev series of specified order over * a specified interval, for a given function. * Return 0 on failure. */ gsl_cheb_series * gsl_cheb_alloc(const size_t order); /* Free a Chebyshev series previously calculated with gsl_cheb_alloc(). */ void gsl_cheb_free(gsl_cheb_series * cs); /* Calculate a Chebyshev series using the storage provided. * Uses the interval (a,b) and the order with which it * was initially created. * */ int gsl_cheb_init(gsl_cheb_series * cs, const gsl_function * func, const double a, const double b); /* Evaluate a Chebyshev series at a given point. * No errors can occur for a struct obtained from gsl_cheb_new(). */ double gsl_cheb_eval(const gsl_cheb_series * cs, const double x); int gsl_cheb_eval_err(const gsl_cheb_series * cs, const double x, double * result, double * abserr); /* Evaluate a Chebyshev series at a given point, to (at most) the given order. * No errors can occur for a struct obtained from gsl_cheb_new(). */ double gsl_cheb_eval_n(const gsl_cheb_series * cs, const size_t order, const double x); int gsl_cheb_eval_n_err(const gsl_cheb_series * cs, const size_t order, const double x, double * result, double * abserr); /* Evaluate a Chebyshev series at a given point, using the default * order for double precision mode(s) and the single precision * order for other modes. * No errors can occur for a struct obtained from gsl_cheb_new(). */ double gsl_cheb_eval_mode(const gsl_cheb_series * cs, const double x, gsl_mode_t mode); int gsl_cheb_eval_mode_e(const gsl_cheb_series * cs, const double x, gsl_mode_t mode, double * result, double * abserr); /* Compute the derivative of a Chebyshev series. */ int gsl_cheb_calc_deriv(gsl_cheb_series * deriv, const gsl_cheb_series * cs); /* Compute the integral of a Chebyshev series. The * integral is fixed by the condition that it equals zero at * the left end-point, ie it is precisely * Integrate[cs(t; a,b), {t, a, x}] */ int gsl_cheb_calc_integ(gsl_cheb_series * integ, const gsl_cheb_series * cs); __END_DECLS #endif /* __GSL_CHEBYSHEV_H__ */ praat-6.0.04/external/gsl/gsl_check_range.h000066400000000000000000000030471261542461700206020ustar00rootroot00000000000000/* vector/gsl_check_range.h * * Copyright (C) 2003, 2004, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_CHECK_RANGE_H__ #define __GSL_CHECK_RANGE_H__ #include #include "gsl_types.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS GSL_VAR int gsl_check_range; /* Turn range checking on by default, unless the user defines GSL_RANGE_CHECK_OFF, or defines GSL_RANGE_CHECK to 0 explicitly */ #ifdef GSL_RANGE_CHECK_OFF # ifndef GSL_RANGE_CHECK # define GSL_RANGE_CHECK 0 # else # error "cannot set both GSL_RANGE_CHECK and GSL_RANGE_CHECK_OFF" # endif #else # ifndef GSL_RANGE_CHECK # define GSL_RANGE_CHECK 1 # endif #endif __END_DECLS #endif /* __GSL_CHECK_RANGE_H__ */ praat-6.0.04/external/gsl/gsl_combination.h000066400000000000000000000053051261542461700206520ustar00rootroot00000000000000/* combination/gsl_combination.h * based on permutation/gsl_permutation.h by Brian Gough * * Copyright (C) 2001 Szymon Jaroszewicz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_COMBINATION_H__ #define __GSL_COMBINATION_H__ #include #include "gsl_errno.h" #include "gsl_types.h" #include "gsl_check_range.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS struct gsl_combination_struct { size_t n; size_t k; size_t *data; }; typedef struct gsl_combination_struct gsl_combination; gsl_combination *gsl_combination_alloc (const size_t n, const size_t k); gsl_combination *gsl_combination_calloc (const size_t n, const size_t k); void gsl_combination_init_first (gsl_combination * c); void gsl_combination_init_last (gsl_combination * c); void gsl_combination_free (gsl_combination * c); int gsl_combination_memcpy (gsl_combination * dest, const gsl_combination * src); int gsl_combination_fread (FILE * stream, gsl_combination * c); int gsl_combination_fwrite (FILE * stream, const gsl_combination * c); int gsl_combination_fscanf (FILE * stream, gsl_combination * c); int gsl_combination_fprintf (FILE * stream, const gsl_combination * c, const char *format); size_t gsl_combination_n (const gsl_combination * c); size_t gsl_combination_k (const gsl_combination * c); size_t * gsl_combination_data (const gsl_combination * c); size_t gsl_combination_get (const gsl_combination * c, const size_t i); int gsl_combination_valid (gsl_combination * c); int gsl_combination_next (gsl_combination * c); int gsl_combination_prev (gsl_combination * c); #ifdef HAVE_INLINE extern inline size_t gsl_combination_get (const gsl_combination * c, const size_t i) { #if GSL_RANGE_CHECK if (i >= c->k) { GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); } #endif return c->data[i]; } #endif /* HAVE_INLINE */ __END_DECLS #endif /* __GSL_COMBINATION_H__ */ praat-6.0.04/external/gsl/gsl_combination__combination.c000066400000000000000000000075651261542461700234000ustar00rootroot00000000000000/* combination/combination.c * based on permutation/permutation.c by Brian Gough * * Copyright (C) 2001 Szymon Jaroszewicz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_combination.h" size_t gsl_combination_n (const gsl_combination * c) { return c->n ; } size_t gsl_combination_k (const gsl_combination * c) { return c->k ; } size_t * gsl_combination_data (const gsl_combination * c) { return c->data ; } #ifndef HIDE_INLINE_STATIC size_t gsl_combination_get (const gsl_combination * c, const size_t i) { if (gsl_check_range) { if (i >= c->k) /* size_t is unsigned, can't be negative */ { GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); } } return c->data[i]; } #endif int gsl_combination_valid (gsl_combination * c) { const size_t n = c->n ; const size_t k = c->k ; size_t i, j ; if( k > n ) { GSL_ERROR("combination has k greater than n", GSL_FAILURE) ; } for (i = 0; i < k; i++) { const size_t ci = c->data[i]; if (ci >= n) { GSL_ERROR("combination index outside range", GSL_FAILURE) ; } for (j = 0; j < i; j++) { if (c->data[j] == ci) { GSL_ERROR("duplicate combination index", GSL_FAILURE) ; } if (c->data[j] > ci) { GSL_ERROR("combination indices not in increasing order", GSL_FAILURE) ; } } } return GSL_SUCCESS; } int gsl_combination_next (gsl_combination * c) { /* Replaces c with the next combination (in the standard lexicographical * ordering). Returns GSL_FAILURE if there is no next combination. */ const size_t n = c->n; const size_t k = c->k; size_t *data = c->data; size_t i; if(k == 0) { return GSL_FAILURE; } i = k - 1; while(i > 0 && data[i] == n - k + i) { i--; } if(i == 0 && data[i] == n - k) { return GSL_FAILURE; } data[i]++; for(; i < k - 1; i++) { data[i + 1] = data[i] + 1; } return GSL_SUCCESS; } int gsl_combination_prev (gsl_combination * c) { /* Replaces c with the previous combination (in the standard * lexicographical ordering). Returns GSL_FAILURE if there is no * previous combination. */ const size_t n = c->n; const size_t k = c->k; size_t *data = c->data; size_t i; if(k == 0) { return GSL_FAILURE; } i = k - 1; while(i > 0 && data[i] == data[i-1] + 1) { i--; } if(i == 0 && data[i] == 0) { return GSL_FAILURE; } data[i++]--; for(; i < k; i++) { data[i] = n - k + i; } return GSL_SUCCESS; } int gsl_combination_memcpy (gsl_combination * dest, const gsl_combination * src) { const size_t src_n = src->n; const size_t src_k = src->k; const size_t dest_n = dest->n; const size_t dest_k = dest->k; if (src_n != dest_n || src_k != dest_k) { GSL_ERROR ("combination lengths are not equal", GSL_EBADLEN); } { size_t j; for (j = 0; j < src_k; j++) { dest->data[j] = src->data[j]; } } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_combination__file.c000066400000000000000000000046411261542461700220050ustar00rootroot00000000000000/* combination/file.c * based on permutation/file.c by Brian Gough * * Copyright (C) 2001 Szymon Jaroszewicz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_combination.h" #define IN_FORMAT "%lu" int gsl_combination_fread (FILE * stream, gsl_combination * c) { size_t k = c->k ; size_t * data = c->data ; size_t items = fread (data, sizeof (size_t), k, stream); if (items != k) { GSL_ERROR ("fread failed", GSL_EFAILED); } return GSL_SUCCESS; } int gsl_combination_fwrite (FILE * stream, const gsl_combination * c) { size_t k = c->k ; size_t * data = c->data ; size_t items = fwrite (data, sizeof (size_t), k, stream); if (items != k) { GSL_ERROR ("fwrite failed", GSL_EFAILED); } return GSL_SUCCESS; } int gsl_combination_fprintf (FILE * stream, const gsl_combination * c, const char *format) { size_t k = c->k ; size_t * data = c->data ; size_t i; for (i = 0; i < k; i++) { int status = fprintf (stream, format, data[i]); if (status < 0) { GSL_ERROR ("fprintf failed", GSL_EFAILED); } } return GSL_SUCCESS; } int gsl_combination_fscanf (FILE * stream, gsl_combination * c) { size_t k = c->k ; size_t * data = c->data ; size_t i; for (i = 0; i < k; i++) { unsigned long j ; /* FIXME: what if size_t != unsigned long ??? want read in size_t but have to read in unsigned long to avoid error from compiler */ int status = fscanf (stream, IN_FORMAT, &j); if (status != 1) { GSL_ERROR ("fscanf failed", GSL_EFAILED); } data[i] = j; } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_combination__init.c000066400000000000000000000053001261542461700220220ustar00rootroot00000000000000/* combination/init.c * based on permutation/init.c by Brian Gough * * Copyright (C) 2001 Szymon Jaroszewicz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_combination.h" gsl_combination * gsl_combination_alloc (const size_t n, const size_t k) { gsl_combination * c; if (n == 0) { GSL_ERROR_VAL ("combination parameter n must be positive integer", GSL_EDOM, 0); } if (k > n) { GSL_ERROR_VAL ("combination length k must be an integer less than or equal to n", GSL_EDOM, 0); } c = (gsl_combination *) malloc (sizeof (gsl_combination)); if (c == 0) { GSL_ERROR_VAL ("failed to allocate space for combination struct", GSL_ENOMEM, 0); } if (k > 0) { c->data = (size_t *) malloc (k * sizeof (size_t)); if (c->data == 0) { free (c); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for combination data", GSL_ENOMEM, 0); } } else { c->data = 0; } c->n = n; c->k = k; return c; } gsl_combination * gsl_combination_calloc (const size_t n, const size_t k) { size_t i; gsl_combination * c = gsl_combination_alloc (n, k); if (c == 0) return 0; /* initialize combination to identity */ for (i = 0; i < k; i++) { c->data[i] = i; } return c; } void gsl_combination_init_first (gsl_combination * c) { const size_t k = c->k ; size_t i; /* initialize combination to identity */ for (i = 0; i < k; i++) { c->data[i] = i; } } void gsl_combination_init_last (gsl_combination * c) { const size_t k = c->k ; size_t i; size_t n = c->n; /* initialize combination to identity */ for (i = 0; i < k; i++) { c->data[i] = n - k + i; } } void gsl_combination_free (gsl_combination * c) { if (c->k > 0) free (c->data); free (c); } praat-6.0.04/external/gsl/gsl_complex.h000066400000000000000000000064561261542461700200270ustar00rootroot00000000000000/* complex/gsl_complex.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_COMPLEX_H__ #define __GSL_COMPLEX_H__ #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* two consecutive built-in types as a complex number */ typedef double * gsl_complex_packed ; typedef float * gsl_complex_packed_float ; typedef long double * gsl_complex_packed_long_double ; typedef const double * gsl_const_complex_packed ; typedef const float * gsl_const_complex_packed_float ; typedef const long double * gsl_const_complex_packed_long_double ; /* 2N consecutive built-in types as N complex numbers */ typedef double * gsl_complex_packed_array ; typedef float * gsl_complex_packed_array_float ; typedef long double * gsl_complex_packed_array_long_double ; typedef const double * gsl_const_complex_packed_array ; typedef const float * gsl_const_complex_packed_array_float ; typedef const long double * gsl_const_complex_packed_array_long_double ; /* Yes... this seems weird. Trust us. The point is just that sometimes you want to make it obvious that something is an output value. The fact that it lacks a 'const' may not be enough of a clue for people in some contexts. */ typedef double * gsl_complex_packed_ptr ; typedef float * gsl_complex_packed_float_ptr ; typedef long double * gsl_complex_packed_long_double_ptr ; typedef const double * gsl_const_complex_packed_ptr ; typedef const float * gsl_const_complex_packed_float_ptr ; typedef const long double * gsl_const_complex_packed_long_double_ptr ; typedef struct { long double dat[2]; } gsl_complex_long_double; typedef struct { double dat[2]; } gsl_complex; typedef struct { float dat[2]; } gsl_complex_float; #define GSL_REAL(z) ((z).dat[0]) #define GSL_IMAG(z) ((z).dat[1]) #define GSL_COMPLEX_P(zp) ((zp)->dat) #define GSL_COMPLEX_P_REAL(zp) ((zp)->dat[0]) #define GSL_COMPLEX_P_IMAG(zp) ((zp)->dat[1]) #define GSL_COMPLEX_EQ(z1,z2) (((z1).dat[0] == (z2).dat[0]) && ((z1).dat[1] == (z2).dat[1])) #define GSL_SET_COMPLEX(zp,x,y) do {(zp)->dat[0]=(x); (zp)->dat[1]=(y);} while(0) #define GSL_SET_REAL(zp,x) do {(zp)->dat[0]=(x);} while(0) #define GSL_SET_IMAG(zp,y) do {(zp)->dat[1]=(y);} while(0) #define GSL_SET_COMPLEX_PACKED(zp,n,x,y) do {*((zp)+2*(n))=(x); *((zp)+(2*(n)+1))=(y);} while(0) __END_DECLS #endif /* __GSL_COMPLEX_H__ */ praat-6.0.04/external/gsl/gsl_complex__math.c000066400000000000000000000560161261542461700211670ustar00rootroot00000000000000/* complex/math.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jorma Olavi Thtinen, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Basic complex arithmetic functions * Original version by Jorma Olavi Thtinen * * Modified for GSL by Brian Gough, 3/2000 */ /* The following references describe the methods used in these * functions, * * T. E. Hull and Thomas F. Fairgrieve and Ping Tak Peter Tang, * "Implementing Complex Elementary Functions Using Exception * Handling", ACM Transactions on Mathematical Software, Volume 20 * (1994), pp 215-244, Corrigenda, p553 * * Hull et al, "Implementing the complex arcsin and arccosine * functions using exception handling", ACM Transactions on * Mathematical Software, Volume 23 (1997) pp 299-335 * * Abramowitz and Stegun, Handbook of Mathematical Functions, "Inverse * Circular Functions in Terms of Real and Imaginary Parts", Formulas * 4.4.37, 4.4.38, 4.4.39 */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_complex.h" #include "gsl_complex_math.h" /********************************************************************** * Complex numbers **********************************************************************/ #ifndef HIDE_INLINE_STATIC gsl_complex gsl_complex_rect (double x, double y) { /* return z = x + i y */ gsl_complex z; GSL_SET_COMPLEX (&z, x, y); return z; } #endif gsl_complex gsl_complex_polar (double r, double theta) { /* return z = r exp(i theta) */ gsl_complex z; GSL_SET_COMPLEX (&z, r * cos (theta), r * sin (theta)); return z; } /********************************************************************** * Properties of complex numbers **********************************************************************/ double gsl_complex_arg (gsl_complex z) { /* return arg(z), -pi < arg(z) <= +pi */ double x = GSL_REAL (z); double y = GSL_IMAG (z); if (x == 0.0 && y == 0.0) { return 0; } return atan2 (y, x); } double gsl_complex_abs (gsl_complex z) { /* return |z| */ return hypot (GSL_REAL (z), GSL_IMAG (z)); } double gsl_complex_abs2 (gsl_complex z) { /* return |z|^2 */ double x = GSL_REAL (z); double y = GSL_IMAG (z); return (x * x + y * y); } double gsl_complex_logabs (gsl_complex z) { /* return log|z| */ double xabs = fabs (GSL_REAL (z)); double yabs = fabs (GSL_IMAG (z)); double max, u; if (xabs >= yabs) { max = xabs; u = yabs / xabs; } else { max = yabs; u = xabs / yabs; } /* Handle underflow when u is close to 0 */ return log (max) + 0.5 * log1p (u * u); } /*********************************************************************** * Complex arithmetic operators ***********************************************************************/ gsl_complex gsl_complex_add (gsl_complex a, gsl_complex b) { /* z=a+b */ double ar = GSL_REAL (a), ai = GSL_IMAG (a); double br = GSL_REAL (b), bi = GSL_IMAG (b); gsl_complex z; GSL_SET_COMPLEX (&z, ar + br, ai + bi); return z; } gsl_complex gsl_complex_add_real (gsl_complex a, double x) { /* z=a+x */ gsl_complex z; GSL_SET_COMPLEX (&z, GSL_REAL (a) + x, GSL_IMAG (a)); return z; } gsl_complex gsl_complex_add_imag (gsl_complex a, double y) { /* z=a+iy */ gsl_complex z; GSL_SET_COMPLEX (&z, GSL_REAL (a), GSL_IMAG (a) + y); return z; } gsl_complex gsl_complex_sub (gsl_complex a, gsl_complex b) { /* z=a-b */ double ar = GSL_REAL (a), ai = GSL_IMAG (a); double br = GSL_REAL (b), bi = GSL_IMAG (b); gsl_complex z; GSL_SET_COMPLEX (&z, ar - br, ai - bi); return z; } gsl_complex gsl_complex_sub_real (gsl_complex a, double x) { /* z=a-x */ gsl_complex z; GSL_SET_COMPLEX (&z, GSL_REAL (a) - x, GSL_IMAG (a)); return z; } gsl_complex gsl_complex_sub_imag (gsl_complex a, double y) { /* z=a-iy */ gsl_complex z; GSL_SET_COMPLEX (&z, GSL_REAL (a), GSL_IMAG (a) - y); return z; } gsl_complex gsl_complex_mul (gsl_complex a, gsl_complex b) { /* z=a*b */ double ar = GSL_REAL (a), ai = GSL_IMAG (a); double br = GSL_REAL (b), bi = GSL_IMAG (b); gsl_complex z; GSL_SET_COMPLEX (&z, ar * br - ai * bi, ar * bi + ai * br); return z; } gsl_complex gsl_complex_mul_real (gsl_complex a, double x) { /* z=a*x */ gsl_complex z; GSL_SET_COMPLEX (&z, x * GSL_REAL (a), x * GSL_IMAG (a)); return z; } gsl_complex gsl_complex_mul_imag (gsl_complex a, double y) { /* z=a*iy */ gsl_complex z; GSL_SET_COMPLEX (&z, -y * GSL_IMAG (a), y * GSL_REAL (a)); return z; } gsl_complex gsl_complex_div (gsl_complex a, gsl_complex b) { /* z=a/b */ double ar = GSL_REAL (a), ai = GSL_IMAG (a); double br = GSL_REAL (b), bi = GSL_IMAG (b); double s = 1.0 / gsl_complex_abs (b); double sbr = s * br; double sbi = s * bi; double zr = (ar * sbr + ai * sbi) * s; double zi = (ai * sbr - ar * sbi) * s; gsl_complex z; GSL_SET_COMPLEX (&z, zr, zi); return z; } gsl_complex gsl_complex_div_real (gsl_complex a, double x) { /* z=a/x */ gsl_complex z; GSL_SET_COMPLEX (&z, GSL_REAL (a) / x, GSL_IMAG (a) / x); return z; } gsl_complex gsl_complex_div_imag (gsl_complex a, double y) { /* z=a/(iy) */ gsl_complex z; GSL_SET_COMPLEX (&z, GSL_IMAG (a) / y, - GSL_REAL (a) / y); return z; } gsl_complex gsl_complex_conjugate (gsl_complex a) { /* z=conj(a) */ gsl_complex z; GSL_SET_COMPLEX (&z, GSL_REAL (a), -GSL_IMAG (a)); return z; } gsl_complex gsl_complex_negative (gsl_complex a) { /* z=-a */ gsl_complex z; GSL_SET_COMPLEX (&z, -GSL_REAL (a), -GSL_IMAG (a)); return z; } gsl_complex gsl_complex_inverse (gsl_complex a) { /* z=1/a */ double s = 1.0 / gsl_complex_abs (a); gsl_complex z; GSL_SET_COMPLEX (&z, (GSL_REAL (a) * s) * s, -(GSL_IMAG (a) * s) * s); return z; } /********************************************************************** * Elementary complex functions **********************************************************************/ gsl_complex gsl_complex_sqrt (gsl_complex a) { /* z=sqrt(a) */ gsl_complex z; if (GSL_REAL (a) == 0.0 && GSL_IMAG (a) == 0.0) { GSL_SET_COMPLEX (&z, 0, 0); } else { double x = fabs (GSL_REAL (a)); double y = fabs (GSL_IMAG (a)); double w; if (x >= y) { double t = y / x; w = sqrt (x) * sqrt (0.5 * (1.0 + sqrt (1.0 + t * t))); } else { double t = x / y; w = sqrt (y) * sqrt (0.5 * (t + sqrt (1.0 + t * t))); } if (GSL_REAL (a) >= 0.0) { double ai = GSL_IMAG (a); GSL_SET_COMPLEX (&z, w, ai / (2.0 * w)); } else { double ai = GSL_IMAG (a); double vi = (ai >= 0) ? w : -w; GSL_SET_COMPLEX (&z, ai / (2.0 * vi), vi); } } return z; } gsl_complex gsl_complex_sqrt_real (double x) { /* z=sqrt(x) */ gsl_complex z; if (x >= 0) { GSL_SET_COMPLEX (&z, sqrt (x), 0.0); } else { GSL_SET_COMPLEX (&z, 0.0, sqrt (-x)); } return z; } gsl_complex gsl_complex_exp (gsl_complex a) { /* z=exp(a) */ double rho = exp (GSL_REAL (a)); double theta = GSL_IMAG (a); gsl_complex z; GSL_SET_COMPLEX (&z, rho * cos (theta), rho * sin (theta)); return z; } gsl_complex gsl_complex_pow (gsl_complex a, gsl_complex b) { /* z=a^b */ gsl_complex z; if (GSL_REAL (a) == 0 && GSL_IMAG (a) == 0.0) { if (GSL_REAL (b) == 0 && GSL_IMAG (b) == 0.0) { GSL_SET_COMPLEX (&z, 1.0, 0.0); } else { GSL_SET_COMPLEX (&z, 0.0, 0.0); } } else if (GSL_REAL (b) == 1.0 && GSL_IMAG (b) == 0.0) { return a; } else if (GSL_REAL (b) == -1.0 && GSL_IMAG (b) == 0.0) { return gsl_complex_inverse (a); } else { double logr = gsl_complex_logabs (a); double theta = gsl_complex_arg (a); double br = GSL_REAL (b), bi = GSL_IMAG (b); double rho = exp (logr * br - bi * theta); double beta = theta * br + bi * logr; GSL_SET_COMPLEX (&z, rho * cos (beta), rho * sin (beta)); } return z; } gsl_complex gsl_complex_pow_real (gsl_complex a, double b) { /* z=a^b */ gsl_complex z; if (GSL_REAL (a) == 0 && GSL_IMAG (a) == 0) { GSL_SET_COMPLEX (&z, 0, 0); } else { double logr = gsl_complex_logabs (a); double theta = gsl_complex_arg (a); double rho = exp (logr * b); double beta = theta * b; GSL_SET_COMPLEX (&z, rho * cos (beta), rho * sin (beta)); } return z; } gsl_complex gsl_complex_log (gsl_complex a) { /* z=log(a) */ double logr = gsl_complex_logabs (a); double theta = gsl_complex_arg (a); gsl_complex z; GSL_SET_COMPLEX (&z, logr, theta); return z; } gsl_complex gsl_complex_log10 (gsl_complex a) { /* z = log10(a) */ return gsl_complex_mul_real (gsl_complex_log (a), 1 / log (10.)); } gsl_complex gsl_complex_log_b (gsl_complex a, gsl_complex b) { return gsl_complex_div (gsl_complex_log (a), gsl_complex_log (b)); } /*********************************************************************** * Complex trigonometric functions ***********************************************************************/ gsl_complex gsl_complex_sin (gsl_complex a) { /* z = sin(a) */ double R = GSL_REAL (a), I = GSL_IMAG (a); gsl_complex z; if (I == 0.0) { /* avoid returing negative zero (-0.0) for the imaginary part */ GSL_SET_COMPLEX (&z, sin (R), 0.0); } else { GSL_SET_COMPLEX (&z, sin (R) * cosh (I), cos (R) * sinh (I)); } return z; } gsl_complex gsl_complex_cos (gsl_complex a) { /* z = cos(a) */ double R = GSL_REAL (a), I = GSL_IMAG (a); gsl_complex z; if (I == 0.0) { /* avoid returing negative zero (-0.0) for the imaginary part */ GSL_SET_COMPLEX (&z, cos (R), 0.0); } else { GSL_SET_COMPLEX (&z, cos (R) * cosh (I), sin (R) * sinh (-I)); } return z; } gsl_complex gsl_complex_tan (gsl_complex a) { /* z = tan(a) */ double R = GSL_REAL (a), I = GSL_IMAG (a); gsl_complex z; if (fabs (I) < 1) { double D = pow (cos (R), 2.0) + pow (sinh (I), 2.0); GSL_SET_COMPLEX (&z, 0.5 * sin (2 * R) / D, 0.5 * sinh (2 * I) / D); } else { double u = exp (-I); double C = 2 * u / (1 - pow (u, 2.0)); double D = 1 + pow (cos (R), 2.0) * pow (C, 2.0); double S = pow (C, 2.0); double T = 1.0 / tanh (I); GSL_SET_COMPLEX (&z, 0.5 * sin (2 * R) * S / D, T / D); } return z; } gsl_complex gsl_complex_sec (gsl_complex a) { /* z = sec(a) */ gsl_complex z = gsl_complex_cos (a); return gsl_complex_inverse (z); } gsl_complex gsl_complex_csc (gsl_complex a) { /* z = csc(a) */ gsl_complex z = gsl_complex_sin (a); return gsl_complex_inverse(z); } gsl_complex gsl_complex_cot (gsl_complex a) { /* z = cot(a) */ gsl_complex z = gsl_complex_tan (a); return gsl_complex_inverse (z); } /********************************************************************** * Inverse Complex Trigonometric Functions **********************************************************************/ gsl_complex gsl_complex_arcsin (gsl_complex a) { /* z = arcsin(a) */ double R = GSL_REAL (a), I = GSL_IMAG (a); gsl_complex z; if (I == 0) { z = gsl_complex_arcsin_real (R); } else { double x = fabs (R), y = fabs (I); double r = hypot (x + 1, y), s = hypot (x - 1, y); double A = 0.5 * (r + s); double B = x / A; double y2 = y * y; double real, imag; const double A_crossover = 1.5, B_crossover = 0.6417; if (B <= B_crossover) { real = asin (B); } else { if (x <= 1) { double D = 0.5 * (A + x) * (y2 / (r + x + 1) + (s + (1 - x))); real = atan (x / sqrt (D)); } else { double Apx = A + x; double D = 0.5 * (Apx / (r + x + 1) + Apx / (s + (x - 1))); real = atan (x / (y * sqrt (D))); } } if (A <= A_crossover) { double Am1; if (x < 1) { Am1 = 0.5 * (y2 / (r + (x + 1)) + y2 / (s + (1 - x))); } else { Am1 = 0.5 * (y2 / (r + (x + 1)) + (s + (x - 1))); } imag = log1p (Am1 + sqrt (Am1 * (A + 1))); } else { imag = log (A + sqrt (A * A - 1)); } GSL_SET_COMPLEX (&z, (R >= 0) ? real : -real, (I >= 0) ? imag : -imag); } return z; } gsl_complex gsl_complex_arcsin_real (double a) { /* z = arcsin(a) */ gsl_complex z; if (fabs (a) <= 1.0) { GSL_SET_COMPLEX (&z, asin (a), 0.0); } else { if (a < 0.0) { GSL_SET_COMPLEX (&z, -M_PI_2, acosh (-a)); } else { GSL_SET_COMPLEX (&z, M_PI_2, -acosh (a)); } } return z; } gsl_complex gsl_complex_arccos (gsl_complex a) { /* z = arccos(a) */ double R = GSL_REAL (a), I = GSL_IMAG (a); gsl_complex z; if (I == 0) { z = gsl_complex_arccos_real (R); } else { double x = fabs (R), y = fabs (I); double r = hypot (x + 1, y), s = hypot (x - 1, y); double A = 0.5 * (r + s); double B = x / A; double y2 = y * y; double real, imag; const double A_crossover = 1.5, B_crossover = 0.6417; if (B <= B_crossover) { real = acos (B); } else { if (x <= 1) { double D = 0.5 * (A + x) * (y2 / (r + x + 1) + (s + (1 - x))); real = atan (sqrt (D) / x); } else { double Apx = A + x; double D = 0.5 * (Apx / (r + x + 1) + Apx / (s + (x - 1))); real = atan ((y * sqrt (D)) / x); } } if (A <= A_crossover) { double Am1; if (x < 1) { Am1 = 0.5 * (y2 / (r + (x + 1)) + y2 / (s + (1 - x))); } else { Am1 = 0.5 * (y2 / (r + (x + 1)) + (s + (x - 1))); } imag = log1p (Am1 + sqrt (Am1 * (A + 1))); } else { imag = log (A + sqrt (A * A - 1)); } GSL_SET_COMPLEX (&z, (R >= 0) ? real : M_PI - real, (I >= 0) ? -imag : imag); } return z; } gsl_complex gsl_complex_arccos_real (double a) { /* z = arccos(a) */ gsl_complex z; if (fabs (a) <= 1.0) { GSL_SET_COMPLEX (&z, acos (a), 0); } else { if (a < 0.0) { GSL_SET_COMPLEX (&z, M_PI, -acosh (-a)); } else { GSL_SET_COMPLEX (&z, 0, acosh (a)); } } return z; } gsl_complex gsl_complex_arctan (gsl_complex a) { /* z = arctan(a) */ double R = GSL_REAL (a), I = GSL_IMAG (a); gsl_complex z; if (I == 0) { GSL_SET_COMPLEX (&z, atan (R), 0); } else { /* FIXME: This is a naive implementation which does not fully take into account cancellation errors, overflow, underflow etc. It would benefit from the Hull et al treatment. */ double r = hypot (R, I); double imag; double u = 2 * I / (1 + r * r); /* FIXME: the following cross-over should be optimized but 0.1 seems to work ok */ if (fabs (u) < 0.1) { imag = 0.25 * (log1p (u) - log1p (-u)); } else { double A = hypot (R, I + 1); double B = hypot (R, I - 1); imag = 0.5 * log (A / B); } if (R == 0) { if (I > 1) { GSL_SET_COMPLEX (&z, M_PI_2, imag); } else if (I < -1) { GSL_SET_COMPLEX (&z, -M_PI_2, imag); } else { GSL_SET_COMPLEX (&z, 0, imag); }; } else { GSL_SET_COMPLEX (&z, 0.5 * atan2 (2 * R, ((1 + r) * (1 - r))), imag); } } return z; } gsl_complex gsl_complex_arcsec (gsl_complex a) { /* z = arcsec(a) */ gsl_complex z = gsl_complex_inverse (a); return gsl_complex_arccos (z); } gsl_complex gsl_complex_arcsec_real (double a) { /* z = arcsec(a) */ gsl_complex z; if (a <= -1.0 || a >= 1.0) { GSL_SET_COMPLEX (&z, acos (1 / a), 0.0); } else { if (a >= 0.0) { GSL_SET_COMPLEX (&z, 0, acosh (1 / a)); } else { GSL_SET_COMPLEX (&z, M_PI, -acosh (-1 / a)); } } return z; } gsl_complex gsl_complex_arccsc (gsl_complex a) { /* z = arccsc(a) */ gsl_complex z = gsl_complex_inverse (a); return gsl_complex_arcsin (z); } gsl_complex gsl_complex_arccsc_real (double a) { /* z = arccsc(a) */ gsl_complex z; if (a <= -1.0 || a >= 1.0) { GSL_SET_COMPLEX (&z, asin (1 / a), 0.0); } else { if (a >= 0.0) { GSL_SET_COMPLEX (&z, M_PI_2, -acosh (1 / a)); } else { GSL_SET_COMPLEX (&z, -M_PI_2, acosh (-1 / a)); } } return z; } gsl_complex gsl_complex_arccot (gsl_complex a) { /* z = arccot(a) */ gsl_complex z; if (GSL_REAL (a) == 0.0 && GSL_IMAG (a) == 0.0) { GSL_SET_COMPLEX (&z, M_PI_2, 0); } else { z = gsl_complex_inverse (a); z = gsl_complex_arctan (z); } return z; } /********************************************************************** * Complex Hyperbolic Functions **********************************************************************/ gsl_complex gsl_complex_sinh (gsl_complex a) { /* z = sinh(a) */ double R = GSL_REAL (a), I = GSL_IMAG (a); gsl_complex z; GSL_SET_COMPLEX (&z, sinh (R) * cos (I), cosh (R) * sin (I)); return z; } gsl_complex gsl_complex_cosh (gsl_complex a) { /* z = cosh(a) */ double R = GSL_REAL (a), I = GSL_IMAG (a); gsl_complex z; GSL_SET_COMPLEX (&z, cosh (R) * cos (I), sinh (R) * sin (I)); return z; } gsl_complex gsl_complex_tanh (gsl_complex a) { /* z = tanh(a) */ double R = GSL_REAL (a), I = GSL_IMAG (a); gsl_complex z; if (fabs(R) < 1.0) { double D = pow (cos (I), 2.0) + pow (sinh (R), 2.0); GSL_SET_COMPLEX (&z, sinh (R) * cosh (R) / D, 0.5 * sin (2 * I) / D); } else { double D = pow (cos (I), 2.0) + pow (sinh (R), 2.0); double F = 1 + pow (cos (I) / sinh (R), 2.0); GSL_SET_COMPLEX (&z, 1.0 / (tanh (R) * F), 0.5 * sin (2 * I) / D); } return z; } gsl_complex gsl_complex_sech (gsl_complex a) { /* z = sech(a) */ gsl_complex z = gsl_complex_cosh (a); return gsl_complex_inverse (z); } gsl_complex gsl_complex_csch (gsl_complex a) { /* z = csch(a) */ gsl_complex z = gsl_complex_sinh (a); return gsl_complex_inverse (z); } gsl_complex gsl_complex_coth (gsl_complex a) { /* z = coth(a) */ gsl_complex z = gsl_complex_tanh (a); return gsl_complex_inverse (z); } /********************************************************************** * Inverse Complex Hyperbolic Functions **********************************************************************/ gsl_complex gsl_complex_arcsinh (gsl_complex a) { /* z = arcsinh(a) */ gsl_complex z = gsl_complex_mul_imag(a, 1.0); z = gsl_complex_arcsin (z); z = gsl_complex_mul_imag (z, -1.0); return z; } gsl_complex gsl_complex_arccosh (gsl_complex a) { /* z = arccosh(a) */ gsl_complex z = gsl_complex_arccos (a); z = gsl_complex_mul_imag (z, GSL_IMAG(z) > 0 ? -1.0 : 1.0); return z; } gsl_complex gsl_complex_arccosh_real (double a) { /* z = arccosh(a) */ gsl_complex z; if (a >= 1) { GSL_SET_COMPLEX (&z, acosh (a), 0); } else { if (a >= -1.0) { GSL_SET_COMPLEX (&z, 0, acos (a)); } else { GSL_SET_COMPLEX (&z, acosh (-a), M_PI); } } return z; } gsl_complex gsl_complex_arctanh (gsl_complex a) { /* z = arctanh(a) */ if (GSL_IMAG (a) == 0.0) { return gsl_complex_arctanh_real (GSL_REAL (a)); } else { gsl_complex z = gsl_complex_mul_imag(a, 1.0); z = gsl_complex_arctan (z); z = gsl_complex_mul_imag (z, -1.0); return z; } } gsl_complex gsl_complex_arctanh_real (double a) { /* z = arctanh(a) */ gsl_complex z; if (a > -1.0 && a < 1.0) { GSL_SET_COMPLEX (&z, atanh (a), 0); } else { GSL_SET_COMPLEX (&z, atanh (1 / a), (a < 0) ? M_PI_2 : -M_PI_2); } return z; } gsl_complex gsl_complex_arcsech (gsl_complex a) { /* z = arcsech(a); */ gsl_complex t = gsl_complex_inverse (a); return gsl_complex_arccosh (t); } gsl_complex gsl_complex_arccsch (gsl_complex a) { /* z = arccsch(a) */ gsl_complex t = gsl_complex_inverse (a); return gsl_complex_arcsinh (t); } gsl_complex gsl_complex_arccoth (gsl_complex a) { /* z = arccoth(a) */ gsl_complex t = gsl_complex_inverse (a); return gsl_complex_arctanh (t); } praat-6.0.04/external/gsl/gsl_complex__results.h000066400000000000000000017236721261542461700217560ustar00rootroot00000000000000 {FN (sqrt), ARG(0.0e+00,0.0e+00), RES(0e0, 0.0)}, {FN (sqrt), ARG(0.0e+00,1.19209289550781250e-07), RES(2.44140625e-4, 2.44140625e-4)}, {FN (sqrt), ARG(0.0e+00,-1.19209289550781250e-07), RES(2.44140625e-4, -2.44140625e-4)}, {FN (sqrt), ARG(0.0e+00,5.0e-01), RES(5e-1, 5e-1)}, {FN (sqrt), ARG(0.0e+00,-5.0e-01), RES(5e-1, -5e-1)}, {FN (sqrt), ARG(0.0e+00,1.0e+00), RES(7.0710678118654752440e-1, 7.0710678118654752440e-1)}, {FN (sqrt), ARG(0.0e+00,-1.0e+00), RES(7.0710678118654752440e-1, -7.0710678118654752440e-1)}, {FN (sqrt), ARG(0.0e+00,2.0e+00), RES(1, 1)}, {FN (sqrt), ARG(0.0e+00,-2.0e+00), RES(1, -1)}, {FN (sqrt), ARG(0.0e+00,8.3886080e+06), RES(2048, 2048)}, {FN (sqrt), ARG(0.0e+00,-8.3886080e+06), RES(2048, -2048)}, {FN (sqrt), ARG(1.19209289550781250e-07,0.0e+00), RES(3.4526698300124390840e-4, 0.0)}, {FN (sqrt), ARG(-1.19209289550781250e-07,0.0e+00), RES(0, 3.4526698300124390840e-4)}, {FN (sqrt), ARG(1.19209289550781250e-07,1.19209289550781250e-07), RES(3.7933934912842707699e-4, 1.5712750315077700799e-4)}, {FN (sqrt), ARG(1.19209289550781250e-07,-1.19209289550781250e-07), RES(3.7933934912842707699e-4, -1.5712750315077700799e-4)}, {FN (sqrt), ARG(-1.19209289550781250e-07,1.19209289550781250e-07), RES(1.5712750315077700799e-4, 3.7933934912842707699e-4)}, {FN (sqrt), ARG(-1.19209289550781250e-07,-1.19209289550781250e-07), RES(1.5712750315077700799e-4, -3.7933934912842707699e-4)}, {FN (sqrt), ARG(1.19209289550781250e-07,5.0e-01), RES(5.0000005960464832810e-1, 4.9999994039535877732e-1)}, {FN (sqrt), ARG(1.19209289550781250e-07,-5.0e-01), RES(5.0000005960464832810e-1, -4.9999994039535877732e-1)}, {FN (sqrt), ARG(-1.19209289550781250e-07,5.0e-01), RES(4.9999994039535877732e-1, 5.0000005960464832810e-1)}, {FN (sqrt), ARG(-1.19209289550781250e-07,-5.0e-01), RES(4.9999994039535877732e-1, -5.0000005960464832810e-1)}, {FN (sqrt), ARG(1.19209289550781250e-07,1.0e+00), RES(7.0710682333339729137e-1, 7.0710673903970026958e-1)}, {FN (sqrt), ARG(1.19209289550781250e-07,-1.0e+00), RES(7.0710682333339729137e-1, -7.0710673903970026958e-1)}, {FN (sqrt), ARG(-1.19209289550781250e-07,1.0e+00), RES(7.0710673903970026958e-1, 7.0710682333339729137e-1)}, {FN (sqrt), ARG(-1.19209289550781250e-07,-1.0e+00), RES(7.0710673903970026958e-1, -7.0710682333339729137e-1)}, {FN (sqrt), ARG(1.19209289550781250e-07,2.0e+00), RES(1.0000000298023228318e0, 9.9999997019767805639e-1)}, {FN (sqrt), ARG(1.19209289550781250e-07,-2.0e+00), RES(1.0000000298023228318e0, -9.9999997019767805639e-1)}, {FN (sqrt), ARG(-1.19209289550781250e-07,2.0e+00), RES(9.9999997019767805639e-1, 1.0000000298023228318e0)}, {FN (sqrt), ARG(-1.19209289550781250e-07,-2.0e+00), RES(9.9999997019767805639e-1, -1.0000000298023228318e0)}, {FN (sqrt), ARG(1.19209289550781250e-07,8.3886080e+06), RES(2.0480000000000145519e3, 2.0479999999999854481e3)}, {FN (sqrt), ARG(1.19209289550781250e-07,-8.3886080e+06), RES(2.0480000000000145519e3, -2.0479999999999854481e3)}, {FN (sqrt), ARG(-1.19209289550781250e-07,8.3886080e+06), RES(2.0479999999999854481e3, 2.0480000000000145519e3)}, {FN (sqrt), ARG(-1.19209289550781250e-07,-8.3886080e+06), RES(2.0479999999999854481e3, -2.0480000000000145519e3)}, {FN (sqrt), ARG(5.0e-01,0.0e+00), RES(7.0710678118654752440e-1, 0.0)}, {FN (sqrt), ARG(-5.0e-01,0.0e+00), RES(0, 7.0710678118654752440e-1)}, {FN (sqrt), ARG(5.0e-01,1.19209289550781250e-07), RES(7.0710678118655254870e-1, 8.4293697021787464631e-8)}, {FN (sqrt), ARG(5.0e-01,-1.19209289550781250e-07), RES(7.0710678118655254870e-1, -8.4293697021787464631e-8)}, {FN (sqrt), ARG(-5.0e-01,1.19209289550781250e-07), RES(8.4293697021787464631e-8, 7.0710678118655254870e-1)}, {FN (sqrt), ARG(-5.0e-01,-1.19209289550781250e-07), RES(8.4293697021787464631e-8, -7.0710678118655254870e-1)}, {FN (sqrt), ARG(5.0e-01,5.0e-01), RES(7.7688698701501865367e-1, 3.2179712645279131237e-1)}, {FN (sqrt), ARG(5.0e-01,-5.0e-01), RES(7.7688698701501865367e-1, -3.2179712645279131237e-1)}, {FN (sqrt), ARG(-5.0e-01,5.0e-01), RES(3.2179712645279131237e-1, 7.7688698701501865367e-1)}, {FN (sqrt), ARG(-5.0e-01,-5.0e-01), RES(3.2179712645279131237e-1, -7.7688698701501865367e-1)}, {FN (sqrt), ARG(5.0e-01,1.0e+00), RES(8.9945371997393363613e-1, 5.5589297025142117199e-1)}, {FN (sqrt), ARG(5.0e-01,-1.0e+00), RES(8.9945371997393363613e-1, -5.5589297025142117199e-1)}, {FN (sqrt), ARG(-5.0e-01,1.0e+00), RES(5.5589297025142117199e-1, 8.9945371997393363613e-1)}, {FN (sqrt), ARG(-5.0e-01,-1.0e+00), RES(5.5589297025142117199e-1, -8.9945371997393363613e-1)}, {FN (sqrt), ARG(5.0e-01,2.0e+00), RES(1.1317139242778694103e0, 8.8361553087551326576e-1)}, {FN (sqrt), ARG(5.0e-01,-2.0e+00), RES(1.1317139242778694103e0, -8.8361553087551326576e-1)}, {FN (sqrt), ARG(-5.0e-01,2.0e+00), RES(8.8361553087551326576e-1, 1.1317139242778694103e0)}, {FN (sqrt), ARG(-5.0e-01,-2.0e+00), RES(8.8361553087551326576e-1, -1.1317139242778694103e0)}, {FN (sqrt), ARG(5.0e-01,8.3886080e+06), RES(2.0480000610351571595e3, 2.0479999389648446595e3)}, {FN (sqrt), ARG(5.0e-01,-8.3886080e+06), RES(2.0480000610351571595e3, -2.0479999389648446595e3)}, {FN (sqrt), ARG(-5.0e-01,8.3886080e+06), RES(2.0479999389648446595e3, 2.0480000610351571595e3)}, {FN (sqrt), ARG(-5.0e-01,-8.3886080e+06), RES(2.0479999389648446595e3, -2.0480000610351571595e3)}, {FN (sqrt), ARG(1.0e+00,0.0e+00), RES(1e0, 0.0)}, {FN (sqrt), ARG(-1.0e+00,0.0e+00), RES(0, 1)}, {FN (sqrt), ARG(1.0e+00,1.19209289550781250e-07), RES(1.0000000000000017764e0, 5.9604644775390519121e-8)}, {FN (sqrt), ARG(1.0e+00,-1.19209289550781250e-07), RES(1.0000000000000017764e0, -5.9604644775390519121e-8)}, {FN (sqrt), ARG(-1.0e+00,1.19209289550781250e-07), RES(5.9604644775390519121e-8, 1.0000000000000017764e0)}, {FN (sqrt), ARG(-1.0e+00,-1.19209289550781250e-07), RES(5.9604644775390519121e-8, -1.0000000000000017764e0)}, {FN (sqrt), ARG(1.0e+00,5.0e-01), RES(1.0290855136357461252e0, 2.4293413587832283909e-1)}, {FN (sqrt), ARG(1.0e+00,-5.0e-01), RES(1.0290855136357461252e0, -2.4293413587832283909e-1)}, {FN (sqrt), ARG(-1.0e+00,5.0e-01), RES(2.4293413587832283909e-1, 1.0290855136357461252e0)}, {FN (sqrt), ARG(-1.0e+00,-5.0e-01), RES(2.4293413587832283909e-1, -1.0290855136357461252e0)}, {FN (sqrt), ARG(1.0e+00,1.0e+00), RES(1.0986841134678099660e0, 4.5508986056222734130e-1)}, {FN (sqrt), ARG(1.0e+00,-1.0e+00), RES(1.0986841134678099660e0, -4.5508986056222734130e-1)}, {FN (sqrt), ARG(-1.0e+00,1.0e+00), RES(4.5508986056222734130e-1, 1.0986841134678099660e0)}, {FN (sqrt), ARG(-1.0e+00,-1.0e+00), RES(4.5508986056222734130e-1, -1.0986841134678099660e0)}, {FN (sqrt), ARG(1.0e+00,2.0e+00), RES(1.2720196495140689643e0, 7.8615137775742328607e-1)}, {FN (sqrt), ARG(1.0e+00,-2.0e+00), RES(1.2720196495140689643e0, -7.8615137775742328607e-1)}, {FN (sqrt), ARG(-1.0e+00,2.0e+00), RES(7.8615137775742328607e-1, 1.2720196495140689643e0)}, {FN (sqrt), ARG(-1.0e+00,-2.0e+00), RES(7.8615137775742328607e-1, -1.2720196495140689643e0)}, {FN (sqrt), ARG(1.0e+00,8.3886080e+06), RES(2.0480001220703161380e3, 2.0479998779296911380e3)}, {FN (sqrt), ARG(1.0e+00,-8.3886080e+06), RES(2.0480001220703161380e3, -2.0479998779296911380e3)}, {FN (sqrt), ARG(-1.0e+00,8.3886080e+06), RES(2.0479998779296911380e3, 2.0480001220703161380e3)}, {FN (sqrt), ARG(-1.0e+00,-8.3886080e+06), RES(2.0479998779296911380e3, -2.0480001220703161380e3)}, {FN (sqrt), ARG(2.0e+00,0.0e+00), RES(1.4142135623730950488e0, 0.0)}, {FN (sqrt), ARG(-2.0e+00,0.0e+00), RES(0, 1.4142135623730950488e0)}, {FN (sqrt), ARG(2.0e+00,1.19209289550781250e-07), RES(1.4142135623730956768e0, 4.2146848510894013070e-8)}, {FN (sqrt), ARG(2.0e+00,-1.19209289550781250e-07), RES(1.4142135623730956768e0, -4.2146848510894013070e-8)}, {FN (sqrt), ARG(-2.0e+00,1.19209289550781250e-07), RES(4.2146848510894013070e-8, 1.4142135623730956768e0)}, {FN (sqrt), ARG(-2.0e+00,-1.19209289550781250e-07), RES(4.2146848510894013070e-8, -1.4142135623730956768e0)}, {FN (sqrt), ARG(2.0e+00,5.0e-01), RES(1.4250531240639470060e0, 1.7543205637629383228e-1)}, {FN (sqrt), ARG(2.0e+00,-5.0e-01), RES(1.4250531240639470060e0, -1.7543205637629383228e-1)}, {FN (sqrt), ARG(-2.0e+00,5.0e-01), RES(1.7543205637629383228e-1, 1.4250531240639470060e0)}, {FN (sqrt), ARG(-2.0e+00,-5.0e-01), RES(1.7543205637629383228e-1, -1.4250531240639470060e0)}, {FN (sqrt), ARG(2.0e+00,1.0e+00), RES(1.4553466902253548081e0, 3.4356074972251246414e-1)}, {FN (sqrt), ARG(2.0e+00,-1.0e+00), RES(1.4553466902253548081e0, -3.4356074972251246414e-1)}, {FN (sqrt), ARG(-2.0e+00,1.0e+00), RES(3.4356074972251246414e-1, 1.4553466902253548081e0)}, {FN (sqrt), ARG(-2.0e+00,-1.0e+00), RES(3.4356074972251246414e-1, -1.4553466902253548081e0)}, {FN (sqrt), ARG(2.0e+00,2.0e+00), RES(1.5537739740300373073e0, 6.4359425290558262474e-1)}, {FN (sqrt), ARG(2.0e+00,-2.0e+00), RES(1.5537739740300373073e0, -6.4359425290558262474e-1)}, {FN (sqrt), ARG(-2.0e+00,2.0e+00), RES(6.4359425290558262474e-1, 1.5537739740300373073e0)}, {FN (sqrt), ARG(-2.0e+00,-2.0e+00), RES(6.4359425290558262474e-1, -1.5537739740300373073e0)}, {FN (sqrt), ARG(2.0e+00,8.3886080e+06), RES(2.0480002441406395519e3, 2.0479997558593895519e3)}, {FN (sqrt), ARG(2.0e+00,-8.3886080e+06), RES(2.0480002441406395519e3, -2.0479997558593895519e3)}, {FN (sqrt), ARG(-2.0e+00,8.3886080e+06), RES(2.0479997558593895519e3, 2.0480002441406395519e3)}, {FN (sqrt), ARG(-2.0e+00,-8.3886080e+06), RES(2.0479997558593895519e3, -2.0480002441406395519e3)}, {FN (sqrt), ARG(8.3886080e+06,0.0e+00), RES(2.8963093757400986599e3, 0.0)}, {FN (sqrt), ARG(-8.3886080e+06,0.0e+00), RES(0, 2.8963093757400986599e3)}, {FN (sqrt), ARG(8.3886080e+06,1.19209289550781250e-07), RES(2.8963093757400986599e3, 2.0579515874459976458e-11)}, {FN (sqrt), ARG(8.3886080e+06,-1.19209289550781250e-07), RES(2.8963093757400986599e3, -2.0579515874459976458e-11)}, {FN (sqrt), ARG(-8.3886080e+06,1.19209289550781250e-07), RES(2.0579515874459976458e-11, 2.8963093757400986599e3)}, {FN (sqrt), ARG(-8.3886080e+06,-1.19209289550781250e-07), RES(2.0579515874459976458e-11, -2.8963093757400986599e3)}, {FN (sqrt), ARG(8.3886080e+06,5.0e-01), RES(2.8963093757400999462e3, 8.6316745750310938767e-5)}, {FN (sqrt), ARG(8.3886080e+06,-5.0e-01), RES(2.8963093757400999462e3, -8.6316745750310938767e-5)}, {FN (sqrt), ARG(-8.3886080e+06,5.0e-01), RES(8.6316745750310938767e-5, 2.8963093757400999462e3)}, {FN (sqrt), ARG(-8.3886080e+06,-5.0e-01), RES(8.6316745750310938767e-5, -2.8963093757400999462e3)}, {FN (sqrt), ARG(8.3886080e+06,1.0e+00), RES(2.8963093757401038048e3, 1.7263349150062164754e-4)}, {FN (sqrt), ARG(8.3886080e+06,-1.0e+00), RES(2.8963093757401038048e3, -1.7263349150062164754e-4)}, {FN (sqrt), ARG(-8.3886080e+06,1.0e+00), RES(1.7263349150062164754e-4, 2.8963093757401038048e3)}, {FN (sqrt), ARG(-8.3886080e+06,-1.0e+00), RES(1.7263349150062164754e-4, -2.8963093757401038048e3)}, {FN (sqrt), ARG(8.3886080e+06,2.0e+00), RES(2.8963093757401192395e3, 3.4526698300124145513e-4)}, {FN (sqrt), ARG(8.3886080e+06,-2.0e+00), RES(2.8963093757401192395e3, -3.4526698300124145513e-4)}, {FN (sqrt), ARG(-8.3886080e+06,2.0e+00), RES(3.4526698300124145513e-4, 2.8963093757401192395e3)}, {FN (sqrt), ARG(-8.3886080e+06,-2.0e+00), RES(3.4526698300124145513e-4, -2.8963093757401192395e3)}, {FN (sqrt), ARG(8.3886080e+06,8.3886080e+06), RES(3.1821290988135164054e3, 1.3180810299506332155e3)}, {FN (sqrt), ARG(8.3886080e+06,-8.3886080e+06), RES(3.1821290988135164054e3, -1.3180810299506332155e3)}, {FN (sqrt), ARG(-8.3886080e+06,8.3886080e+06), RES(1.3180810299506332155e3, 3.1821290988135164054e3)}, {FN (sqrt), ARG(-8.3886080e+06,-8.3886080e+06), RES(1.3180810299506332155e3, -3.1821290988135164054e3)}, {FN (log), ARG(1.19209289550781250e-07,0.0e+00), RES(-1.5942385152878742117e1, 0.0)}, {FN (log), ARG(-1.19209289550781250e-07,0.0e+00), RES(-1.5942385152878742117e1, 3.1415926535897932385e0)}, {FN (log), ARG(1.19209289550781250e-07,1.19209289550781250e-07), RES(-1.5595811562598769462e1, 7.8539816339744830962e-1)}, {FN (log), ARG(1.19209289550781250e-07,-1.19209289550781250e-07), RES(-1.5595811562598769462e1, -7.8539816339744830962e-1)}, {FN (log), ARG(-1.19209289550781250e-07,1.19209289550781250e-07), RES(-1.5595811562598769462e1, 2.3561944901923449288e0)}, {FN (log), ARG(-1.19209289550781250e-07,-1.19209289550781250e-07), RES(-1.5595811562598769462e1, -2.3561944901923449288e0)}, {FN (log), ARG(1.19209289550781250e-07,5.0e-01), RES(-6.9314718055991688771e-1, 1.5707960883763175177e0)}, {FN (log), ARG(1.19209289550781250e-07,-5.0e-01), RES(-6.9314718055991688771e-1, -1.5707960883763175177e0)}, {FN (log), ARG(-1.19209289550781250e-07,5.0e-01), RES(-6.9314718055991688771e-1, 1.5707965652134757208e0)}, {FN (log), ARG(-1.19209289550781250e-07,-5.0e-01), RES(-6.9314718055991688771e-1, -1.5707965652134757208e0)}, {FN (log), ARG(1.19209289550781250e-07,1.0e+00), RES(7.1054273576009513716e-15, 1.5707962075856070685e0)}, {FN (log), ARG(1.19209289550781250e-07,-1.0e+00), RES(7.1054273576009513716e-15, -1.5707962075856070685e0)}, {FN (log), ARG(-1.19209289550781250e-07,1.0e+00), RES(7.1054273576009513716e-15, 1.570796446004186170e0)}, {FN (log), ARG(-1.19209289550781250e-07,-1.0e+00), RES(7.1054273576009513716e-15, -1.570796446004186170e0)}, {FN (log), ARG(1.19209289550781250e-07,2.0e+00), RES(6.9314718055994708577e-1, 1.5707962671902518438e0)}, {FN (log), ARG(1.19209289550781250e-07,-2.0e+00), RES(6.9314718055994708577e-1, -1.5707962671902518438e0)}, {FN (log), ARG(-1.19209289550781250e-07,2.0e+00), RES(6.9314718055994708577e-1, 1.5707963863995413946e0)}, {FN (log), ARG(-1.19209289550781250e-07,-2.0e+00), RES(6.9314718055994708577e-1, -1.5707963863995413946e0)}, {FN (log), ARG(1.19209289550781250e-07,8.3886080e+06), RES(1.5942385152878742117e1, 1.5707963267948824084e0)}, {FN (log), ARG(1.19209289550781250e-07,-8.3886080e+06), RES(1.5942385152878742117e1, -1.5707963267948824084e0)}, {FN (log), ARG(-1.19209289550781250e-07,8.3886080e+06), RES(1.5942385152878742117e1, 1.5707963267949108301e0)}, {FN (log), ARG(-1.19209289550781250e-07,-8.3886080e+06), RES(1.5942385152878742117e1, -1.5707963267949108301e0)}, {FN (log), ARG(5.0e-01,0.0e+00), RES(-6.9314718055994530942e-1, 0.0)}, {FN (log), ARG(-5.0e-01,0.0e+00), RES(-6.9314718055994530942e-1, 3.1415926535897932385e0)}, {FN (log), ARG(5.0e-01,1.19209289550781250e-07), RES(-6.9314718055991688771e-1, 2.3841857910155798249e-7)}, {FN (log), ARG(5.0e-01,-1.19209289550781250e-07), RES(-6.9314718055991688771e-1, -2.3841857910155798249e-7)}, {FN (log), ARG(-5.0e-01,1.19209289550781250e-07), RES(-6.9314718055991688771e-1, 3.1415924151712141369e0)}, {FN (log), ARG(-5.0e-01,-1.19209289550781250e-07), RES(-6.9314718055991688771e-1, -3.1415924151712141369e0)}, {FN (log), ARG(5.0e-01,5.0e-01), RES(-3.4657359027997265471e-1, 7.8539816339744830962e-1)}, {FN (log), ARG(5.0e-01,-5.0e-01), RES(-3.4657359027997265471e-1, -7.8539816339744830962e-1)}, {FN (log), ARG(-5.0e-01,5.0e-01), RES(-3.4657359027997265471e-1, 2.3561944901923449288e0)}, {FN (log), ARG(-5.0e-01,-5.0e-01), RES(-3.4657359027997265471e-1, -2.3561944901923449288e0)}, {FN (log), ARG(5.0e-01,1.0e+00), RES(1.1157177565710487788e-1, 1.1071487177940905030e0)}, {FN (log), ARG(5.0e-01,-1.0e+00), RES(1.1157177565710487788e-1, -1.1071487177940905030e0)}, {FN (log), ARG(-5.0e-01,1.0e+00), RES(1.1157177565710487788e-1, 2.0344439357957027354e0)}, {FN (log), ARG(-5.0e-01,-1.0e+00), RES(1.1157177565710487788e-1, -2.0344439357957027354e0)}, {FN (log), ARG(5.0e-01,2.0e+00), RES(7.2345949146816273071e-1, 1.3258176636680324651e0)}, {FN (log), ARG(5.0e-01,-2.0e+00), RES(7.2345949146816273071e-1, -1.3258176636680324651e0)}, {FN (log), ARG(-5.0e-01,2.0e+00), RES(7.2345949146816273071e-1, 1.8157749899217607734e0)}, {FN (log), ARG(-5.0e-01,-2.0e+00), RES(7.2345949146816273071e-1, -1.8157749899217607734e0)}, {FN (log), ARG(5.0e-01,8.3886080e+06), RES(1.5942385152878743893e1, 1.5707962671902518438e0)}, {FN (log), ARG(5.0e-01,-8.3886080e+06), RES(1.5942385152878743893e1, -1.5707962671902518438e0)}, {FN (log), ARG(-5.0e-01,8.3886080e+06), RES(1.5942385152878743893e1, 1.5707963863995413946e0)}, {FN (log), ARG(-5.0e-01,-8.3886080e+06), RES(1.5942385152878743893e1, -1.5707963863995413946e0)}, {FN (log), ARG(1.0e+00,0.0e+00), RES(0e0, 0.0)}, {FN (log), ARG(-1.0e+00,0.0e+00), RES(0, 3.1415926535897932385e0)}, {FN (log), ARG(1.0e+00,1.19209289550781250e-07), RES(7.1054273576009513716e-15, 1.1920928955078068531e-7)}, {FN (log), ARG(1.0e+00,-1.19209289550781250e-07), RES(7.1054273576009513716e-15, -1.1920928955078068531e-7)}, {FN (log), ARG(-1.0e+00,1.19209289550781250e-07), RES(7.1054273576009513716e-15, 3.1415925343805036877e0)}, {FN (log), ARG(-1.0e+00,-1.19209289550781250e-07), RES(7.1054273576009513716e-15, -3.1415925343805036877e0)}, {FN (log), ARG(1.0e+00,5.0e-01), RES(1.1157177565710487788e-1, 4.6364760900080611621e-1)}, {FN (log), ARG(1.0e+00,-5.0e-01), RES(1.1157177565710487788e-1, -4.6364760900080611621e-1)}, {FN (log), ARG(-1.0e+00,5.0e-01), RES(1.1157177565710487788e-1, 2.6779450445889871222e0)}, {FN (log), ARG(-1.0e+00,-5.0e-01), RES(1.1157177565710487788e-1, -2.6779450445889871222e0)}, {FN (log), ARG(1.0e+00,1.0e+00), RES(3.4657359027997265471e-1, 7.8539816339744830962e-1)}, {FN (log), ARG(1.0e+00,-1.0e+00), RES(3.4657359027997265471e-1, -7.8539816339744830962e-1)}, {FN (log), ARG(-1.0e+00,1.0e+00), RES(3.4657359027997265471e-1, 2.3561944901923449288e0)}, {FN (log), ARG(-1.0e+00,-1.0e+00), RES(3.4657359027997265471e-1, -2.3561944901923449288e0)}, {FN (log), ARG(1.0e+00,2.0e+00), RES(8.0471895621705018730e-1, 1.1071487177940905030e0)}, {FN (log), ARG(1.0e+00,-2.0e+00), RES(8.0471895621705018730e-1, -1.1071487177940905030e0)}, {FN (log), ARG(-1.0e+00,2.0e+00), RES(8.0471895621705018730e-1, 2.0344439357957027354e0)}, {FN (log), ARG(-1.0e+00,-2.0e+00), RES(8.0471895621705018730e-1, -2.0344439357957027354e0)}, {FN (log), ARG(1.0e+00,8.3886080e+06), RES(1.5942385152878749222e1, 1.5707962075856070685e0)}, {FN (log), ARG(1.0e+00,-8.3886080e+06), RES(1.5942385152878749222e1, -1.5707962075856070685e0)}, {FN (log), ARG(-1.0e+00,8.3886080e+06), RES(1.5942385152878749222e1, 1.570796446004186170e0)}, {FN (log), ARG(-1.0e+00,-8.3886080e+06), RES(1.5942385152878749222e1, -1.570796446004186170e0)}, {FN (log), ARG(2.0e+00,0.0e+00), RES(6.9314718055994530942e-1, 0.0)}, {FN (log), ARG(-2.0e+00,0.0e+00), RES(6.9314718055994530942e-1, 3.1415926535897932385e0)}, {FN (log), ARG(2.0e+00,1.19209289550781250e-07), RES(6.9314718055994708577e-1, 5.9604644775390554414e-8)}, {FN (log), ARG(2.0e+00,-1.19209289550781250e-07), RES(6.9314718055994708577e-1, -5.9604644775390554414e-8)}, {FN (log), ARG(-2.0e+00,1.19209289550781250e-07), RES(6.9314718055994708577e-1, 3.1415925939851484631e0)}, {FN (log), ARG(-2.0e+00,-1.19209289550781250e-07), RES(6.9314718055994708577e-1, -3.1415925939851484631e0)}, {FN (log), ARG(2.0e+00,5.0e-01), RES(7.2345949146816273071e-1, 2.4497866312686415417e-1)}, {FN (log), ARG(2.0e+00,-5.0e-01), RES(7.2345949146816273071e-1, -2.4497866312686415417e-1)}, {FN (log), ARG(-2.0e+00,5.0e-01), RES(7.2345949146816273071e-1, 2.8966139904629290843e0)}, {FN (log), ARG(-2.0e+00,-5.0e-01), RES(7.2345949146816273071e-1, -2.8966139904629290843e0)}, {FN (log), ARG(2.0e+00,1.0e+00), RES(8.0471895621705018730e-1, 4.6364760900080611621e-1)}, {FN (log), ARG(2.0e+00,-1.0e+00), RES(8.0471895621705018730e-1, -4.6364760900080611621e-1)}, {FN (log), ARG(-2.0e+00,1.0e+00), RES(8.0471895621705018730e-1, 2.6779450445889871222e0)}, {FN (log), ARG(-2.0e+00,-1.0e+00), RES(8.0471895621705018730e-1, -2.6779450445889871222e0)}, {FN (log), ARG(2.0e+00,2.0e+00), RES(1.0397207708399179641e0, 7.8539816339744830962e-1)}, {FN (log), ARG(2.0e+00,-2.0e+00), RES(1.0397207708399179641e0, -7.8539816339744830962e-1)}, {FN (log), ARG(-2.0e+00,2.0e+00), RES(1.0397207708399179641e0, 2.3561944901923449288e0)}, {FN (log), ARG(-2.0e+00,-2.0e+00), RES(1.0397207708399179641e0, -2.3561944901923449288e0)}, {FN (log), ARG(2.0e+00,8.3886080e+06), RES(1.5942385152878770538e1, 1.5707960883763175177e0)}, {FN (log), ARG(2.0e+00,-8.3886080e+06), RES(1.5942385152878770538e1, -1.5707960883763175177e0)}, {FN (log), ARG(-2.0e+00,8.3886080e+06), RES(1.5942385152878770538e1, 1.5707965652134757208e0)}, {FN (log), ARG(-2.0e+00,-8.3886080e+06), RES(1.5942385152878770538e1, -1.5707965652134757208e0)}, {FN (log), ARG(8.3886080e+06,0.0e+00), RES(1.5942385152878742117e1, 0.0)}, {FN (log), ARG(-8.3886080e+06,0.0e+00), RES(1.5942385152878742117e1, 3.1415926535897932385e0)}, {FN (log), ARG(8.3886080e+06,1.19209289550781250e-07), RES(1.5942385152878742117e1, 1.4210854715202003717e-14)}, {FN (log), ARG(8.3886080e+06,-1.19209289550781250e-07), RES(1.5942385152878742117e1, -1.4210854715202003717e-14)}, {FN (log), ARG(-8.3886080e+06,1.19209289550781250e-07), RES(1.5942385152878742117e1, 3.1415926535897790276e0)}, {FN (log), ARG(-8.3886080e+06,-1.19209289550781250e-07), RES(1.5942385152878742117e1, -3.1415926535897790276e0)}, {FN (log), ARG(8.3886080e+06,5.0e-01), RES(1.5942385152878743893e1, 5.9604644775390554414e-8)}, {FN (log), ARG(8.3886080e+06,-5.0e-01), RES(1.5942385152878743893e1, -5.9604644775390554414e-8)}, {FN (log), ARG(-8.3886080e+06,5.0e-01), RES(1.5942385152878743893e1, 3.1415925939851484631e0)}, {FN (log), ARG(-8.3886080e+06,-5.0e-01), RES(1.5942385152878743893e1, -3.1415925939851484631e0)}, {FN (log), ARG(8.3886080e+06,1.0e+00), RES(1.5942385152878749222e1, 1.1920928955078068531e-7)}, {FN (log), ARG(8.3886080e+06,-1.0e+00), RES(1.5942385152878749222e1, -1.1920928955078068531e-7)}, {FN (log), ARG(-8.3886080e+06,1.0e+00), RES(1.5942385152878749222e1, 3.1415925343805036877e0)}, {FN (log), ARG(-8.3886080e+06,-1.0e+00), RES(1.5942385152878749222e1, -3.1415925343805036877e0)}, {FN (log), ARG(8.3886080e+06,2.0e+00), RES(1.5942385152878770538e1, 2.3841857910155798249e-7)}, {FN (log), ARG(8.3886080e+06,-2.0e+00), RES(1.5942385152878770538e1, -2.3841857910155798249e-7)}, {FN (log), ARG(-8.3886080e+06,2.0e+00), RES(1.5942385152878770538e1, 3.1415924151712141369e0)}, {FN (log), ARG(-8.3886080e+06,-2.0e+00), RES(1.5942385152878770538e1, -3.1415924151712141369e0)}, {FN (log), ARG(8.3886080e+06,8.3886080e+06), RES(1.6288958743158714771e1, 7.8539816339744830962e-1)}, {FN (log), ARG(8.3886080e+06,-8.3886080e+06), RES(1.6288958743158714771e1, -7.8539816339744830962e-1)}, {FN (log), ARG(-8.3886080e+06,8.3886080e+06), RES(1.6288958743158714771e1, 2.3561944901923449288e0)}, {FN (log), ARG(-8.3886080e+06,-8.3886080e+06), RES(1.6288958743158714771e1, -2.3561944901923449288e0)}, {FN (log), ARG(0.0e+00,1.19209289550781250e-07), RES(-1.5942385152878742117e1, 1.5707963267948966192e0)}, {FN (log), ARG(0.0e+00,-1.19209289550781250e-07), RES(-1.5942385152878742117e1, -1.5707963267948966192e0)}, {FN (log), ARG(0.0e+00,5.0e-01), RES(-6.9314718055994530942e-1, 1.5707963267948966192e0)}, {FN (log), ARG(0.0e+00,-5.0e-01), RES(-6.9314718055994530942e-1, -1.5707963267948966192e0)}, {FN (log), ARG(0.0e+00,1.0e+00), RES(0, 1.5707963267948966192e0)}, {FN (log), ARG(0.0e+00,-1.0e+00), RES(0, -1.5707963267948966192e0)}, {FN (log), ARG(0.0e+00,2.0e+00), RES(6.9314718055994530942e-1, 1.5707963267948966192e0)}, {FN (log), ARG(0.0e+00,-2.0e+00), RES(6.9314718055994530942e-1, -1.5707963267948966192e0)}, {FN (log), ARG(0.0e+00,8.3886080e+06), RES(1.5942385152878742117e1, 1.5707963267948966192e0)}, {FN (log), ARG(0.0e+00,-8.3886080e+06), RES(1.5942385152878742117e1, -1.5707963267948966192e0)}, {FN (log), ARG(1.19209289550781250e-07,1.19209289550781250e-07), RES(-1.5595811562598769462e1, 7.8539816339744830962e-1)}, {FN (log), ARG(1.19209289550781250e-07,-1.19209289550781250e-07), RES(-1.5595811562598769462e1, -7.8539816339744830962e-1)}, {FN (log), ARG(-1.19209289550781250e-07,1.19209289550781250e-07), RES(-1.5595811562598769462e1, 2.3561944901923449288e0)}, {FN (log), ARG(-1.19209289550781250e-07,-1.19209289550781250e-07), RES(-1.5595811562598769462e1, -2.3561944901923449288e0)}, {FN (log), ARG(1.19209289550781250e-07,5.0e-01), RES(-6.9314718055991688771e-1, 1.5707960883763175177e0)}, {FN (log), ARG(1.19209289550781250e-07,-5.0e-01), RES(-6.9314718055991688771e-1, -1.5707960883763175177e0)}, {FN (log), ARG(-1.19209289550781250e-07,5.0e-01), RES(-6.9314718055991688771e-1, 1.5707965652134757208e0)}, {FN (log), ARG(-1.19209289550781250e-07,-5.0e-01), RES(-6.9314718055991688771e-1, -1.5707965652134757208e0)}, {FN (log), ARG(1.19209289550781250e-07,1.0e+00), RES(7.1054273576009513716e-15, 1.5707962075856070685e0)}, {FN (log), ARG(1.19209289550781250e-07,-1.0e+00), RES(7.1054273576009513716e-15, -1.5707962075856070685e0)}, {FN (log), ARG(-1.19209289550781250e-07,1.0e+00), RES(7.1054273576009513716e-15, 1.570796446004186170e0)}, {FN (log), ARG(-1.19209289550781250e-07,-1.0e+00), RES(7.1054273576009513716e-15, -1.570796446004186170e0)}, {FN (log), ARG(1.19209289550781250e-07,2.0e+00), RES(6.9314718055994708577e-1, 1.5707962671902518438e0)}, {FN (log), ARG(1.19209289550781250e-07,-2.0e+00), RES(6.9314718055994708577e-1, -1.5707962671902518438e0)}, {FN (log), ARG(-1.19209289550781250e-07,2.0e+00), RES(6.9314718055994708577e-1, 1.5707963863995413946e0)}, {FN (log), ARG(-1.19209289550781250e-07,-2.0e+00), RES(6.9314718055994708577e-1, -1.5707963863995413946e0)}, {FN (log), ARG(1.19209289550781250e-07,8.3886080e+06), RES(1.5942385152878742117e1, 1.5707963267948824084e0)}, {FN (log), ARG(1.19209289550781250e-07,-8.3886080e+06), RES(1.5942385152878742117e1, -1.5707963267948824084e0)}, {FN (log), ARG(-1.19209289550781250e-07,8.3886080e+06), RES(1.5942385152878742117e1, 1.5707963267949108301e0)}, {FN (log), ARG(-1.19209289550781250e-07,-8.3886080e+06), RES(1.5942385152878742117e1, -1.5707963267949108301e0)}, {FN (log), ARG(5.0e-01,1.19209289550781250e-07), RES(-6.9314718055991688771e-1, 2.3841857910155798249e-7)}, {FN (log), ARG(5.0e-01,-1.19209289550781250e-07), RES(-6.9314718055991688771e-1, -2.3841857910155798249e-7)}, {FN (log), ARG(-5.0e-01,1.19209289550781250e-07), RES(-6.9314718055991688771e-1, 3.1415924151712141369e0)}, {FN (log), ARG(-5.0e-01,-1.19209289550781250e-07), RES(-6.9314718055991688771e-1, -3.1415924151712141369e0)}, {FN (log), ARG(5.0e-01,5.0e-01), RES(-3.4657359027997265471e-1, 7.8539816339744830962e-1)}, {FN (log), ARG(5.0e-01,-5.0e-01), RES(-3.4657359027997265471e-1, -7.8539816339744830962e-1)}, {FN (log), ARG(-5.0e-01,5.0e-01), RES(-3.4657359027997265471e-1, 2.3561944901923449288e0)}, {FN (log), ARG(-5.0e-01,-5.0e-01), RES(-3.4657359027997265471e-1, -2.3561944901923449288e0)}, {FN (log), ARG(5.0e-01,1.0e+00), RES(1.1157177565710487788e-1, 1.1071487177940905030e0)}, {FN (log), ARG(5.0e-01,-1.0e+00), RES(1.1157177565710487788e-1, -1.1071487177940905030e0)}, {FN (log), ARG(-5.0e-01,1.0e+00), RES(1.1157177565710487788e-1, 2.0344439357957027354e0)}, {FN (log), ARG(-5.0e-01,-1.0e+00), RES(1.1157177565710487788e-1, -2.0344439357957027354e0)}, {FN (log), ARG(5.0e-01,2.0e+00), RES(7.2345949146816273071e-1, 1.3258176636680324651e0)}, {FN (log), ARG(5.0e-01,-2.0e+00), RES(7.2345949146816273071e-1, -1.3258176636680324651e0)}, {FN (log), ARG(-5.0e-01,2.0e+00), RES(7.2345949146816273071e-1, 1.8157749899217607734e0)}, {FN (log), ARG(-5.0e-01,-2.0e+00), RES(7.2345949146816273071e-1, -1.8157749899217607734e0)}, {FN (log), ARG(5.0e-01,8.3886080e+06), RES(1.5942385152878743893e1, 1.5707962671902518438e0)}, {FN (log), ARG(5.0e-01,-8.3886080e+06), RES(1.5942385152878743893e1, -1.5707962671902518438e0)}, {FN (log), ARG(-5.0e-01,8.3886080e+06), RES(1.5942385152878743893e1, 1.5707963863995413946e0)}, {FN (log), ARG(-5.0e-01,-8.3886080e+06), RES(1.5942385152878743893e1, -1.5707963863995413946e0)}, {FN (log), ARG(1.0e+00,1.19209289550781250e-07), RES(7.1054273576009513716e-15, 1.1920928955078068531e-7)}, {FN (log), ARG(1.0e+00,-1.19209289550781250e-07), RES(7.1054273576009513716e-15, -1.1920928955078068531e-7)}, {FN (log), ARG(-1.0e+00,1.19209289550781250e-07), RES(7.1054273576009513716e-15, 3.1415925343805036877e0)}, {FN (log), ARG(-1.0e+00,-1.19209289550781250e-07), RES(7.1054273576009513716e-15, -3.1415925343805036877e0)}, {FN (log), ARG(1.0e+00,5.0e-01), RES(1.1157177565710487788e-1, 4.6364760900080611621e-1)}, {FN (log), ARG(1.0e+00,-5.0e-01), RES(1.1157177565710487788e-1, -4.6364760900080611621e-1)}, {FN (log), ARG(-1.0e+00,5.0e-01), RES(1.1157177565710487788e-1, 2.6779450445889871222e0)}, {FN (log), ARG(-1.0e+00,-5.0e-01), RES(1.1157177565710487788e-1, -2.6779450445889871222e0)}, {FN (log), ARG(1.0e+00,1.0e+00), RES(3.4657359027997265471e-1, 7.8539816339744830962e-1)}, {FN (log), ARG(1.0e+00,-1.0e+00), RES(3.4657359027997265471e-1, -7.8539816339744830962e-1)}, {FN (log), ARG(-1.0e+00,1.0e+00), RES(3.4657359027997265471e-1, 2.3561944901923449288e0)}, {FN (log), ARG(-1.0e+00,-1.0e+00), RES(3.4657359027997265471e-1, -2.3561944901923449288e0)}, {FN (log), ARG(1.0e+00,2.0e+00), RES(8.0471895621705018730e-1, 1.1071487177940905030e0)}, {FN (log), ARG(1.0e+00,-2.0e+00), RES(8.0471895621705018730e-1, -1.1071487177940905030e0)}, {FN (log), ARG(-1.0e+00,2.0e+00), RES(8.0471895621705018730e-1, 2.0344439357957027354e0)}, {FN (log), ARG(-1.0e+00,-2.0e+00), RES(8.0471895621705018730e-1, -2.0344439357957027354e0)}, {FN (log), ARG(1.0e+00,8.3886080e+06), RES(1.5942385152878749222e1, 1.5707962075856070685e0)}, {FN (log), ARG(1.0e+00,-8.3886080e+06), RES(1.5942385152878749222e1, -1.5707962075856070685e0)}, {FN (log), ARG(-1.0e+00,8.3886080e+06), RES(1.5942385152878749222e1, 1.570796446004186170e0)}, {FN (log), ARG(-1.0e+00,-8.3886080e+06), RES(1.5942385152878749222e1, -1.570796446004186170e0)}, {FN (log), ARG(2.0e+00,1.19209289550781250e-07), RES(6.9314718055994708577e-1, 5.9604644775390554414e-8)}, {FN (log), ARG(2.0e+00,-1.19209289550781250e-07), RES(6.9314718055994708577e-1, -5.9604644775390554414e-8)}, {FN (log), ARG(-2.0e+00,1.19209289550781250e-07), RES(6.9314718055994708577e-1, 3.1415925939851484631e0)}, {FN (log), ARG(-2.0e+00,-1.19209289550781250e-07), RES(6.9314718055994708577e-1, -3.1415925939851484631e0)}, {FN (log), ARG(2.0e+00,5.0e-01), RES(7.2345949146816273071e-1, 2.4497866312686415417e-1)}, {FN (log), ARG(2.0e+00,-5.0e-01), RES(7.2345949146816273071e-1, -2.4497866312686415417e-1)}, {FN (log), ARG(-2.0e+00,5.0e-01), RES(7.2345949146816273071e-1, 2.8966139904629290843e0)}, {FN (log), ARG(-2.0e+00,-5.0e-01), RES(7.2345949146816273071e-1, -2.8966139904629290843e0)}, {FN (log), ARG(2.0e+00,1.0e+00), RES(8.0471895621705018730e-1, 4.6364760900080611621e-1)}, {FN (log), ARG(2.0e+00,-1.0e+00), RES(8.0471895621705018730e-1, -4.6364760900080611621e-1)}, {FN (log), ARG(-2.0e+00,1.0e+00), RES(8.0471895621705018730e-1, 2.6779450445889871222e0)}, {FN (log), ARG(-2.0e+00,-1.0e+00), RES(8.0471895621705018730e-1, -2.6779450445889871222e0)}, {FN (log), ARG(2.0e+00,2.0e+00), RES(1.0397207708399179641e0, 7.8539816339744830962e-1)}, {FN (log), ARG(2.0e+00,-2.0e+00), RES(1.0397207708399179641e0, -7.8539816339744830962e-1)}, {FN (log), ARG(-2.0e+00,2.0e+00), RES(1.0397207708399179641e0, 2.3561944901923449288e0)}, {FN (log), ARG(-2.0e+00,-2.0e+00), RES(1.0397207708399179641e0, -2.3561944901923449288e0)}, {FN (log), ARG(2.0e+00,8.3886080e+06), RES(1.5942385152878770538e1, 1.5707960883763175177e0)}, {FN (log), ARG(2.0e+00,-8.3886080e+06), RES(1.5942385152878770538e1, -1.5707960883763175177e0)}, {FN (log), ARG(-2.0e+00,8.3886080e+06), RES(1.5942385152878770538e1, 1.5707965652134757208e0)}, {FN (log), ARG(-2.0e+00,-8.3886080e+06), RES(1.5942385152878770538e1, -1.5707965652134757208e0)}, {FN (log), ARG(8.3886080e+06,1.19209289550781250e-07), RES(1.5942385152878742117e1, 1.4210854715202003717e-14)}, {FN (log), ARG(8.3886080e+06,-1.19209289550781250e-07), RES(1.5942385152878742117e1, -1.4210854715202003717e-14)}, {FN (log), ARG(-8.3886080e+06,1.19209289550781250e-07), RES(1.5942385152878742117e1, 3.1415926535897790276e0)}, {FN (log), ARG(-8.3886080e+06,-1.19209289550781250e-07), RES(1.5942385152878742117e1, -3.1415926535897790276e0)}, {FN (log), ARG(8.3886080e+06,5.0e-01), RES(1.5942385152878743893e1, 5.9604644775390554414e-8)}, {FN (log), ARG(8.3886080e+06,-5.0e-01), RES(1.5942385152878743893e1, -5.9604644775390554414e-8)}, {FN (log), ARG(-8.3886080e+06,5.0e-01), RES(1.5942385152878743893e1, 3.1415925939851484631e0)}, {FN (log), ARG(-8.3886080e+06,-5.0e-01), RES(1.5942385152878743893e1, -3.1415925939851484631e0)}, {FN (log), ARG(8.3886080e+06,1.0e+00), RES(1.5942385152878749222e1, 1.1920928955078068531e-7)}, {FN (log), ARG(8.3886080e+06,-1.0e+00), RES(1.5942385152878749222e1, -1.1920928955078068531e-7)}, {FN (log), ARG(-8.3886080e+06,1.0e+00), RES(1.5942385152878749222e1, 3.1415925343805036877e0)}, {FN (log), ARG(-8.3886080e+06,-1.0e+00), RES(1.5942385152878749222e1, -3.1415925343805036877e0)}, {FN (log), ARG(8.3886080e+06,2.0e+00), RES(1.5942385152878770538e1, 2.3841857910155798249e-7)}, {FN (log), ARG(8.3886080e+06,-2.0e+00), RES(1.5942385152878770538e1, -2.3841857910155798249e-7)}, {FN (log), ARG(-8.3886080e+06,2.0e+00), RES(1.5942385152878770538e1, 3.1415924151712141369e0)}, {FN (log), ARG(-8.3886080e+06,-2.0e+00), RES(1.5942385152878770538e1, -3.1415924151712141369e0)}, {FN (log), ARG(8.3886080e+06,8.3886080e+06), RES(1.6288958743158714771e1, 7.8539816339744830962e-1)}, {FN (log), ARG(8.3886080e+06,-8.3886080e+06), RES(1.6288958743158714771e1, -7.8539816339744830962e-1)}, {FN (log), ARG(-8.3886080e+06,8.3886080e+06), RES(1.6288958743158714771e1, 2.3561944901923449288e0)}, {FN (log), ARG(-8.3886080e+06,-8.3886080e+06), RES(1.6288958743158714771e1, -2.3561944901923449288e0)}, {FN (log10), ARG(1.19209289550781250e-07,0.0e+00), RES(-6.9236899002715674899e0, 0.0)}, {FN (log10), ARG(-1.19209289550781250e-07,0.0e+00), RES(-6.9236899002715674899e0, 1.3643763538418413475e0)}, {FN (log10), ARG(1.19209289550781250e-07,1.19209289550781250e-07), RES(-6.7731749024395768923e0, 3.4109408846046033687e-1)}, {FN (log10), ARG(1.19209289550781250e-07,-1.19209289550781250e-07), RES(-6.7731749024395768923e0, -3.4109408846046033687e-1)}, {FN (log10), ARG(-1.19209289550781250e-07,1.19209289550781250e-07), RES(-6.7731749024395768923e0, 1.0232822653813810106e0)}, {FN (log10), ARG(-1.19209289550781250e-07,-1.19209289550781250e-07), RES(-6.7731749024395768923e0, -1.0232822653813810106e0)}, {FN (log10), ARG(1.19209289550781250e-07,5.0e-01), RES(-3.0102999566396885182e-1, 6.8218807337704738672e-1)}, {FN (log10), ARG(1.19209289550781250e-07,-5.0e-01), RES(-3.0102999566396885182e-1, -6.8218807337704738672e-1)}, {FN (log10), ARG(-1.19209289550781250e-07,5.0e-01), RES(-3.0102999566396885182e-1, 6.8218828046479396076e-1)}, {FN (log10), ARG(-1.19209289550781250e-07,-5.0e-01), RES(-3.0102999566396885182e-1, -6.8218828046479396076e-1)}, {FN (log10), ARG(1.19209289550781250e-07,1.0e+00), RES(3.0858478929704968280e-15, 6.8218812514898403023e-1)}, {FN (log10), ARG(1.19209289550781250e-07,-1.0e+00), RES(3.0858478929704968280e-15, -6.8218812514898403023e-1)}, {FN (log10), ARG(-1.19209289550781250e-07,1.0e+00), RES(3.0858478929704968280e-15, 6.8218822869285731725e-1)}, {FN (log10), ARG(-1.19209289550781250e-07,-1.0e+00), RES(3.0858478929704968280e-15, -6.8218822869285731725e-1)}, {FN (log10), ARG(1.19209289550781250e-07,2.0e+00), RES(3.0102999566398196668e-1, 6.8218815103495235199e-1)}, {FN (log10), ARG(1.19209289550781250e-07,-2.0e+00), RES(3.0102999566398196668e-1, -6.8218815103495235199e-1)}, {FN (log10), ARG(-1.19209289550781250e-07,2.0e+00), RES(3.0102999566398196668e-1, 6.8218820280688899550e-1)}, {FN (log10), ARG(-1.19209289550781250e-07,-2.0e+00), RES(3.0102999566398196668e-1, -6.8218820280688899550e-1)}, {FN (log10), ARG(1.19209289550781250e-07,8.3886080e+06), RES(6.9236899002715674899e0, 6.8218817692091450205e-1)}, {FN (log10), ARG(1.19209289550781250e-07,-8.3886080e+06), RES(6.9236899002715674899e0, -6.8218817692091450205e-1)}, {FN (log10), ARG(-1.19209289550781250e-07,8.3886080e+06), RES(6.9236899002715674899e0, 6.8218817692092684544e-1)}, {FN (log10), ARG(-1.19209289550781250e-07,-8.3886080e+06), RES(6.9236899002715674899e0, -6.8218817692092684544e-1)}, {FN (log10), ARG(5.0e-01,0.0e+00), RES(-3.0102999566398119521e-1, 0.0)}, {FN (log10), ARG(-5.0e-01,0.0e+00), RES(-3.0102999566398119521e-1, 1.3643763538418413475e0)}, {FN (log10), ARG(5.0e-01,1.19209289550781250e-07), RES(-3.0102999566396885182e-1, 1.0354387328702058762e-7)}, {FN (log10), ARG(5.0e-01,-1.19209289550781250e-07), RES(-3.0102999566396885182e-1, -1.0354387328702058762e-7)}, {FN (log10), ARG(-5.0e-01,1.19209289550781250e-07), RES(-3.0102999566396885182e-1, 1.3643762502979680605e0)}, {FN (log10), ARG(-5.0e-01,-1.19209289550781250e-07), RES(-3.0102999566396885182e-1, -1.3643762502979680605e0)}, {FN (log10), ARG(5.0e-01,5.0e-01), RES(-1.5051499783199059761e-1, 3.4109408846046033687e-1)}, {FN (log10), ARG(5.0e-01,-5.0e-01), RES(-1.5051499783199059761e-1, -3.4109408846046033687e-1)}, {FN (log10), ARG(-5.0e-01,5.0e-01), RES(-1.5051499783199059761e-1, 1.0232822653813810106e0)}, {FN (log10), ARG(-5.0e-01,-5.0e-01), RES(-1.5051499783199059761e-1, -1.0232822653813810106e0)}, {FN (log10), ARG(5.0e-01,1.0e+00), RES(4.8455006504028207179e-2, 4.8082857878423410270e-1)}, {FN (log10), ARG(5.0e-01,-1.0e+00), RES(4.8455006504028207179e-2, -4.8082857878423410270e-1)}, {FN (log10), ARG(-5.0e-01,1.0e+00), RES(4.8455006504028207179e-2, 8.8354777505760724478e-1)}, {FN (log10), ARG(-5.0e-01,-1.0e+00), RES(4.8455006504028207179e-2, -8.8354777505760724478e-1)}, {FN (log10), ARG(5.0e-01,2.0e+00), RES(3.1419446502515576906e-1, 5.7579529534088794354e-1)}, {FN (log10), ARG(5.0e-01,-2.0e+00), RES(3.1419446502515576906e-1, -5.7579529534088794354e-1)}, {FN (log10), ARG(-5.0e-01,2.0e+00), RES(3.1419446502515576906e-1, 7.8858105850095340394e-1)}, {FN (log10), ARG(-5.0e-01,-2.0e+00), RES(3.1419446502515576906e-1, -7.8858105850095340394e-1)}, {FN (log10), ARG(5.0e-01,8.3886080e+06), RES(6.9236899002715682614e0, 6.8218815103495235199e-1)}, {FN (log10), ARG(5.0e-01,-8.3886080e+06), RES(6.9236899002715682614e0, -6.8218815103495235199e-1)}, {FN (log10), ARG(-5.0e-01,8.3886080e+06), RES(6.9236899002715682614e0, 6.8218820280688899550e-1)}, {FN (log10), ARG(-5.0e-01,-8.3886080e+06), RES(6.9236899002715682614e0, -6.8218820280688899550e-1)}, {FN (log10), ARG(1.0e+00,0.0e+00), RES(0e0, 0.0)}, {FN (log10), ARG(-1.0e+00,0.0e+00), RES(0, 1.3643763538418413475e0)}, {FN (log10), ARG(1.0e+00,1.19209289550781250e-07), RES(3.0858478929704968280e-15, 5.1771936643511029532e-8)}, {FN (log10), ARG(1.0e+00,-1.19209289550781250e-07), RES(3.0858478929704968280e-15, -5.1771936643511029532e-8)}, {FN (log10), ARG(-1.0e+00,1.19209289550781250e-07), RES(3.0858478929704968280e-15, 1.3643763020699047040e0)}, {FN (log10), ARG(-1.0e+00,-1.19209289550781250e-07), RES(3.0858478929704968280e-15, -1.3643763020699047040e0)}, {FN (log10), ARG(1.0e+00,5.0e-01), RES(4.8455006504028207179e-2, 2.0135959813668657104e-1)}, {FN (log10), ARG(1.0e+00,-5.0e-01), RES(4.8455006504028207179e-2, -2.0135959813668657104e-1)}, {FN (log10), ARG(-1.0e+00,5.0e-01), RES(4.8455006504028207179e-2, 1.1630167557051547764e0)}, {FN (log10), ARG(-1.0e+00,-5.0e-01), RES(4.8455006504028207179e-2, -1.1630167557051547764e0)}, {FN (log10), ARG(1.0e+00,1.0e+00), RES(1.5051499783199059761e-1, 3.4109408846046033687e-1)}, {FN (log10), ARG(1.0e+00,-1.0e+00), RES(1.5051499783199059761e-1, -3.4109408846046033687e-1)}, {FN (log10), ARG(-1.0e+00,1.0e+00), RES(1.5051499783199059761e-1, 1.0232822653813810106e0)}, {FN (log10), ARG(-1.0e+00,-1.0e+00), RES(1.5051499783199059761e-1, -1.0232822653813810106e0)}, {FN (log10), ARG(1.0e+00,2.0e+00), RES(3.4948500216800940239e-1, 4.8082857878423410270e-1)}, {FN (log10), ARG(1.0e+00,-2.0e+00), RES(3.4948500216800940239e-1, -4.8082857878423410270e-1)}, {FN (log10), ARG(-1.0e+00,2.0e+00), RES(3.4948500216800940239e-1, 8.8354777505760724478e-1)}, {FN (log10), ARG(-1.0e+00,-2.0e+00), RES(3.4948500216800940239e-1, -8.8354777505760724478e-1)}, {FN (log10), ARG(1.0e+00,8.3886080e+06), RES(6.9236899002715705758e0, 6.8218812514898403023e-1)}, {FN (log10), ARG(1.0e+00,-8.3886080e+06), RES(6.9236899002715705758e0, -6.8218812514898403023e-1)}, {FN (log10), ARG(-1.0e+00,8.3886080e+06), RES(6.9236899002715705758e0, 6.8218822869285731725e-1)}, {FN (log10), ARG(-1.0e+00,-8.3886080e+06), RES(6.9236899002715705758e0, -6.8218822869285731725e-1)}, {FN (log10), ARG(2.0e+00,0.0e+00), RES(3.0102999566398119521e-1, 0.0)}, {FN (log10), ARG(-2.0e+00,0.0e+00), RES(3.0102999566398119521e-1, 1.3643763538418413475e0)}, {FN (log10), ARG(2.0e+00,1.19209289550781250e-07), RES(3.0102999566398196668e-1, 2.5885968321755606731e-8)}, {FN (log10), ARG(2.0e+00,-1.19209289550781250e-07), RES(3.0102999566398196668e-1, -2.5885968321755606731e-8)}, {FN (log10), ARG(-2.0e+00,1.19209289550781250e-07), RES(3.0102999566398196668e-1, 1.3643763279558730257e0)}, {FN (log10), ARG(-2.0e+00,-1.19209289550781250e-07), RES(3.0102999566398196668e-1, -1.3643763279558730257e0)}, {FN (log10), ARG(2.0e+00,5.0e-01), RES(3.1419446502515576906e-1, 1.0639288158003273020e-1)}, {FN (log10), ARG(2.0e+00,-5.0e-01), RES(3.1419446502515576906e-1, -1.0639288158003273020e-1)}, {FN (log10), ARG(-2.0e+00,5.0e-01), RES(3.1419446502515576906e-1, 1.2579834722618086173e0)}, {FN (log10), ARG(-2.0e+00,-5.0e-01), RES(3.1419446502515576906e-1, -1.2579834722618086173e0)}, {FN (log10), ARG(2.0e+00,1.0e+00), RES(3.4948500216800940239e-1, 2.0135959813668657104e-1)}, {FN (log10), ARG(2.0e+00,-1.0e+00), RES(3.4948500216800940239e-1, -2.0135959813668657104e-1)}, {FN (log10), ARG(-2.0e+00,1.0e+00), RES(3.4948500216800940239e-1, 1.1630167557051547764e0)}, {FN (log10), ARG(-2.0e+00,-1.0e+00), RES(3.4948500216800940239e-1, -1.1630167557051547764e0)}, {FN (log10), ARG(2.0e+00,2.0e+00), RES(4.5154499349597179282e-1, 3.4109408846046033687e-1)}, {FN (log10), ARG(2.0e+00,-2.0e+00), RES(4.5154499349597179282e-1, -3.4109408846046033687e-1)}, {FN (log10), ARG(-2.0e+00,2.0e+00), RES(4.5154499349597179282e-1, 1.0232822653813810106e0)}, {FN (log10), ARG(-2.0e+00,-2.0e+00), RES(4.5154499349597179282e-1, -1.0232822653813810106e0)}, {FN (log10), ARG(2.0e+00,8.3886080e+06), RES(6.9236899002715798333e0, 6.8218807337704738672e-1)}, {FN (log10), ARG(2.0e+00,-8.3886080e+06), RES(6.9236899002715798333e0, -6.8218807337704738672e-1)}, {FN (log10), ARG(-2.0e+00,8.3886080e+06), RES(6.9236899002715798333e0, 6.8218828046479396076e-1)}, {FN (log10), ARG(-2.0e+00,-8.3886080e+06), RES(6.9236899002715798333e0, -6.8218828046479396076e-1)}, {FN (log10), ARG(8.3886080e+06,0.0e+00), RES(6.9236899002715674899e0, 0.0)}, {FN (log10), ARG(-8.3886080e+06,0.0e+00), RES(6.9236899002715674899e0, 1.3643763538418413475e0)}, {FN (log10), ARG(8.3886080e+06,1.19209289550781250e-07), RES(6.9236899002715674899e0, 6.1716957859410375086e-15)}, {FN (log10), ARG(8.3886080e+06,-1.19209289550781250e-07), RES(6.9236899002715674899e0, -6.1716957859410375086e-15)}, {FN (log10), ARG(-8.3886080e+06,1.19209289550781250e-07), RES(6.9236899002715674899e0, 1.3643763538418351758e0)}, {FN (log10), ARG(-8.3886080e+06,-1.19209289550781250e-07), RES(6.9236899002715674899e0, -1.3643763538418351758e0)}, {FN (log10), ARG(8.3886080e+06,5.0e-01), RES(6.9236899002715682614e0, 2.5885968321755606731e-8)}, {FN (log10), ARG(8.3886080e+06,-5.0e-01), RES(6.9236899002715682614e0, -2.5885968321755606731e-8)}, {FN (log10), ARG(-8.3886080e+06,5.0e-01), RES(6.9236899002715682614e0, 1.3643763279558730257e0)}, {FN (log10), ARG(-8.3886080e+06,-5.0e-01), RES(6.9236899002715682614e0, -1.3643763279558730257e0)}, {FN (log10), ARG(8.3886080e+06,1.0e+00), RES(6.9236899002715705758e0, 5.1771936643511029532e-8)}, {FN (log10), ARG(8.3886080e+06,-1.0e+00), RES(6.9236899002715705758e0, -5.1771936643511029532e-8)}, {FN (log10), ARG(-8.3886080e+06,1.0e+00), RES(6.9236899002715705758e0, 1.3643763020699047040e0)}, {FN (log10), ARG(-8.3886080e+06,-1.0e+00), RES(6.9236899002715705758e0, -1.3643763020699047040e0)}, {FN (log10), ARG(8.3886080e+06,2.0e+00), RES(6.9236899002715798333e0, 1.0354387328702058762e-7)}, {FN (log10), ARG(8.3886080e+06,-2.0e+00), RES(6.9236899002715798333e0, -1.0354387328702058762e-7)}, {FN (log10), ARG(-8.3886080e+06,2.0e+00), RES(6.9236899002715798333e0, 1.3643762502979680605e0)}, {FN (log10), ARG(-8.3886080e+06,-2.0e+00), RES(6.9236899002715798333e0, -1.3643762502979680605e0)}, {FN (log10), ARG(8.3886080e+06,8.3886080e+06), RES(7.0742048981035580875e0, 3.4109408846046033687e-1)}, {FN (log10), ARG(8.3886080e+06,-8.3886080e+06), RES(7.0742048981035580875e0, -3.4109408846046033687e-1)}, {FN (log10), ARG(-8.3886080e+06,8.3886080e+06), RES(7.0742048981035580875e0, 1.0232822653813810106e0)}, {FN (log10), ARG(-8.3886080e+06,-8.3886080e+06), RES(7.0742048981035580875e0, -1.0232822653813810106e0)}, {FN (log10), ARG(0.0e+00,1.19209289550781250e-07), RES(-6.9236899002715674899e0, 6.8218817692092067374e-1)}, {FN (log10), ARG(0.0e+00,-1.19209289550781250e-07), RES(-6.9236899002715674899e0, -6.8218817692092067374e-1)}, {FN (log10), ARG(0.0e+00,5.0e-01), RES(-3.0102999566398119521e-1, 6.8218817692092067374e-1)}, {FN (log10), ARG(0.0e+00,-5.0e-01), RES(-3.0102999566398119521e-1, -6.8218817692092067374e-1)}, {FN (log10), ARG(0.0e+00,1.0e+00), RES(0, 6.8218817692092067374e-1)}, {FN (log10), ARG(0.0e+00,-1.0e+00), RES(0, -6.8218817692092067374e-1)}, {FN (log10), ARG(0.0e+00,2.0e+00), RES(3.0102999566398119521e-1, 6.8218817692092067374e-1)}, {FN (log10), ARG(0.0e+00,-2.0e+00), RES(3.0102999566398119521e-1, -6.8218817692092067374e-1)}, {FN (log10), ARG(0.0e+00,8.3886080e+06), RES(6.9236899002715674899e0, 6.8218817692092067374e-1)}, {FN (log10), ARG(0.0e+00,-8.3886080e+06), RES(6.9236899002715674899e0, -6.8218817692092067374e-1)}, {FN (log10), ARG(1.19209289550781250e-07,1.19209289550781250e-07), RES(-6.7731749024395768923e0, 3.4109408846046033687e-1)}, {FN (log10), ARG(1.19209289550781250e-07,-1.19209289550781250e-07), RES(-6.7731749024395768923e0, -3.4109408846046033687e-1)}, {FN (log10), ARG(-1.19209289550781250e-07,1.19209289550781250e-07), RES(-6.7731749024395768923e0, 1.0232822653813810106e0)}, {FN (log10), ARG(-1.19209289550781250e-07,-1.19209289550781250e-07), RES(-6.7731749024395768923e0, -1.0232822653813810106e0)}, {FN (log10), ARG(1.19209289550781250e-07,5.0e-01), RES(-3.0102999566396885182e-1, 6.8218807337704738672e-1)}, {FN (log10), ARG(1.19209289550781250e-07,-5.0e-01), RES(-3.0102999566396885182e-1, -6.8218807337704738672e-1)}, {FN (log10), ARG(-1.19209289550781250e-07,5.0e-01), RES(-3.0102999566396885182e-1, 6.8218828046479396076e-1)}, {FN (log10), ARG(-1.19209289550781250e-07,-5.0e-01), RES(-3.0102999566396885182e-1, -6.8218828046479396076e-1)}, {FN (log10), ARG(1.19209289550781250e-07,1.0e+00), RES(3.0858478929704968280e-15, 6.8218812514898403023e-1)}, {FN (log10), ARG(1.19209289550781250e-07,-1.0e+00), RES(3.0858478929704968280e-15, -6.8218812514898403023e-1)}, {FN (log10), ARG(-1.19209289550781250e-07,1.0e+00), RES(3.0858478929704968280e-15, 6.8218822869285731725e-1)}, {FN (log10), ARG(-1.19209289550781250e-07,-1.0e+00), RES(3.0858478929704968280e-15, -6.8218822869285731725e-1)}, {FN (log10), ARG(1.19209289550781250e-07,2.0e+00), RES(3.0102999566398196668e-1, 6.8218815103495235199e-1)}, {FN (log10), ARG(1.19209289550781250e-07,-2.0e+00), RES(3.0102999566398196668e-1, -6.8218815103495235199e-1)}, {FN (log10), ARG(-1.19209289550781250e-07,2.0e+00), RES(3.0102999566398196668e-1, 6.8218820280688899550e-1)}, {FN (log10), ARG(-1.19209289550781250e-07,-2.0e+00), RES(3.0102999566398196668e-1, -6.8218820280688899550e-1)}, {FN (log10), ARG(1.19209289550781250e-07,8.3886080e+06), RES(6.9236899002715674899e0, 6.8218817692091450205e-1)}, {FN (log10), ARG(1.19209289550781250e-07,-8.3886080e+06), RES(6.9236899002715674899e0, -6.8218817692091450205e-1)}, {FN (log10), ARG(-1.19209289550781250e-07,8.3886080e+06), RES(6.9236899002715674899e0, 6.8218817692092684544e-1)}, {FN (log10), ARG(-1.19209289550781250e-07,-8.3886080e+06), RES(6.9236899002715674899e0, -6.8218817692092684544e-1)}, {FN (log10), ARG(5.0e-01,1.19209289550781250e-07), RES(-3.0102999566396885182e-1, 1.0354387328702058762e-7)}, {FN (log10), ARG(5.0e-01,-1.19209289550781250e-07), RES(-3.0102999566396885182e-1, -1.0354387328702058762e-7)}, {FN (log10), ARG(-5.0e-01,1.19209289550781250e-07), RES(-3.0102999566396885182e-1, 1.3643762502979680605e0)}, {FN (log10), ARG(-5.0e-01,-1.19209289550781250e-07), RES(-3.0102999566396885182e-1, -1.3643762502979680605e0)}, {FN (log10), ARG(5.0e-01,5.0e-01), RES(-1.5051499783199059761e-1, 3.4109408846046033687e-1)}, {FN (log10), ARG(5.0e-01,-5.0e-01), RES(-1.5051499783199059761e-1, -3.4109408846046033687e-1)}, {FN (log10), ARG(-5.0e-01,5.0e-01), RES(-1.5051499783199059761e-1, 1.0232822653813810106e0)}, {FN (log10), ARG(-5.0e-01,-5.0e-01), RES(-1.5051499783199059761e-1, -1.0232822653813810106e0)}, {FN (log10), ARG(5.0e-01,1.0e+00), RES(4.8455006504028207179e-2, 4.8082857878423410270e-1)}, {FN (log10), ARG(5.0e-01,-1.0e+00), RES(4.8455006504028207179e-2, -4.8082857878423410270e-1)}, {FN (log10), ARG(-5.0e-01,1.0e+00), RES(4.8455006504028207179e-2, 8.8354777505760724478e-1)}, {FN (log10), ARG(-5.0e-01,-1.0e+00), RES(4.8455006504028207179e-2, -8.8354777505760724478e-1)}, {FN (log10), ARG(5.0e-01,2.0e+00), RES(3.1419446502515576906e-1, 5.7579529534088794354e-1)}, {FN (log10), ARG(5.0e-01,-2.0e+00), RES(3.1419446502515576906e-1, -5.7579529534088794354e-1)}, {FN (log10), ARG(-5.0e-01,2.0e+00), RES(3.1419446502515576906e-1, 7.8858105850095340394e-1)}, {FN (log10), ARG(-5.0e-01,-2.0e+00), RES(3.1419446502515576906e-1, -7.8858105850095340394e-1)}, {FN (log10), ARG(5.0e-01,8.3886080e+06), RES(6.9236899002715682614e0, 6.8218815103495235199e-1)}, {FN (log10), ARG(5.0e-01,-8.3886080e+06), RES(6.9236899002715682614e0, -6.8218815103495235199e-1)}, {FN (log10), ARG(-5.0e-01,8.3886080e+06), RES(6.9236899002715682614e0, 6.8218820280688899550e-1)}, {FN (log10), ARG(-5.0e-01,-8.3886080e+06), RES(6.9236899002715682614e0, -6.8218820280688899550e-1)}, {FN (log10), ARG(1.0e+00,1.19209289550781250e-07), RES(3.0858478929704968280e-15, 5.1771936643511029532e-8)}, {FN (log10), ARG(1.0e+00,-1.19209289550781250e-07), RES(3.0858478929704968280e-15, -5.1771936643511029532e-8)}, {FN (log10), ARG(-1.0e+00,1.19209289550781250e-07), RES(3.0858478929704968280e-15, 1.3643763020699047040e0)}, {FN (log10), ARG(-1.0e+00,-1.19209289550781250e-07), RES(3.0858478929704968280e-15, -1.3643763020699047040e0)}, {FN (log10), ARG(1.0e+00,5.0e-01), RES(4.8455006504028207179e-2, 2.0135959813668657104e-1)}, {FN (log10), ARG(1.0e+00,-5.0e-01), RES(4.8455006504028207179e-2, -2.0135959813668657104e-1)}, {FN (log10), ARG(-1.0e+00,5.0e-01), RES(4.8455006504028207179e-2, 1.1630167557051547764e0)}, {FN (log10), ARG(-1.0e+00,-5.0e-01), RES(4.8455006504028207179e-2, -1.1630167557051547764e0)}, {FN (log10), ARG(1.0e+00,1.0e+00), RES(1.5051499783199059761e-1, 3.4109408846046033687e-1)}, {FN (log10), ARG(1.0e+00,-1.0e+00), RES(1.5051499783199059761e-1, -3.4109408846046033687e-1)}, {FN (log10), ARG(-1.0e+00,1.0e+00), RES(1.5051499783199059761e-1, 1.0232822653813810106e0)}, {FN (log10), ARG(-1.0e+00,-1.0e+00), RES(1.5051499783199059761e-1, -1.0232822653813810106e0)}, {FN (log10), ARG(1.0e+00,2.0e+00), RES(3.4948500216800940239e-1, 4.8082857878423410270e-1)}, {FN (log10), ARG(1.0e+00,-2.0e+00), RES(3.4948500216800940239e-1, -4.8082857878423410270e-1)}, {FN (log10), ARG(-1.0e+00,2.0e+00), RES(3.4948500216800940239e-1, 8.8354777505760724478e-1)}, {FN (log10), ARG(-1.0e+00,-2.0e+00), RES(3.4948500216800940239e-1, -8.8354777505760724478e-1)}, {FN (log10), ARG(1.0e+00,8.3886080e+06), RES(6.9236899002715705758e0, 6.8218812514898403023e-1)}, {FN (log10), ARG(1.0e+00,-8.3886080e+06), RES(6.9236899002715705758e0, -6.8218812514898403023e-1)}, {FN (log10), ARG(-1.0e+00,8.3886080e+06), RES(6.9236899002715705758e0, 6.8218822869285731725e-1)}, {FN (log10), ARG(-1.0e+00,-8.3886080e+06), RES(6.9236899002715705758e0, -6.8218822869285731725e-1)}, {FN (log10), ARG(2.0e+00,1.19209289550781250e-07), RES(3.0102999566398196668e-1, 2.5885968321755606731e-8)}, {FN (log10), ARG(2.0e+00,-1.19209289550781250e-07), RES(3.0102999566398196668e-1, -2.5885968321755606731e-8)}, {FN (log10), ARG(-2.0e+00,1.19209289550781250e-07), RES(3.0102999566398196668e-1, 1.3643763279558730257e0)}, {FN (log10), ARG(-2.0e+00,-1.19209289550781250e-07), RES(3.0102999566398196668e-1, -1.3643763279558730257e0)}, {FN (log10), ARG(2.0e+00,5.0e-01), RES(3.1419446502515576906e-1, 1.0639288158003273020e-1)}, {FN (log10), ARG(2.0e+00,-5.0e-01), RES(3.1419446502515576906e-1, -1.0639288158003273020e-1)}, {FN (log10), ARG(-2.0e+00,5.0e-01), RES(3.1419446502515576906e-1, 1.2579834722618086173e0)}, {FN (log10), ARG(-2.0e+00,-5.0e-01), RES(3.1419446502515576906e-1, -1.2579834722618086173e0)}, {FN (log10), ARG(2.0e+00,1.0e+00), RES(3.4948500216800940239e-1, 2.0135959813668657104e-1)}, {FN (log10), ARG(2.0e+00,-1.0e+00), RES(3.4948500216800940239e-1, -2.0135959813668657104e-1)}, {FN (log10), ARG(-2.0e+00,1.0e+00), RES(3.4948500216800940239e-1, 1.1630167557051547764e0)}, {FN (log10), ARG(-2.0e+00,-1.0e+00), RES(3.4948500216800940239e-1, -1.1630167557051547764e0)}, {FN (log10), ARG(2.0e+00,2.0e+00), RES(4.5154499349597179282e-1, 3.4109408846046033687e-1)}, {FN (log10), ARG(2.0e+00,-2.0e+00), RES(4.5154499349597179282e-1, -3.4109408846046033687e-1)}, {FN (log10), ARG(-2.0e+00,2.0e+00), RES(4.5154499349597179282e-1, 1.0232822653813810106e0)}, {FN (log10), ARG(-2.0e+00,-2.0e+00), RES(4.5154499349597179282e-1, -1.0232822653813810106e0)}, {FN (log10), ARG(2.0e+00,8.3886080e+06), RES(6.9236899002715798333e0, 6.8218807337704738672e-1)}, {FN (log10), ARG(2.0e+00,-8.3886080e+06), RES(6.9236899002715798333e0, -6.8218807337704738672e-1)}, {FN (log10), ARG(-2.0e+00,8.3886080e+06), RES(6.9236899002715798333e0, 6.8218828046479396076e-1)}, {FN (log10), ARG(-2.0e+00,-8.3886080e+06), RES(6.9236899002715798333e0, -6.8218828046479396076e-1)}, {FN (log10), ARG(8.3886080e+06,1.19209289550781250e-07), RES(6.9236899002715674899e0, 6.1716957859410375086e-15)}, {FN (log10), ARG(8.3886080e+06,-1.19209289550781250e-07), RES(6.9236899002715674899e0, -6.1716957859410375086e-15)}, {FN (log10), ARG(-8.3886080e+06,1.19209289550781250e-07), RES(6.9236899002715674899e0, 1.3643763538418351758e0)}, {FN (log10), ARG(-8.3886080e+06,-1.19209289550781250e-07), RES(6.9236899002715674899e0, -1.3643763538418351758e0)}, {FN (log10), ARG(8.3886080e+06,5.0e-01), RES(6.9236899002715682614e0, 2.5885968321755606731e-8)}, {FN (log10), ARG(8.3886080e+06,-5.0e-01), RES(6.9236899002715682614e0, -2.5885968321755606731e-8)}, {FN (log10), ARG(-8.3886080e+06,5.0e-01), RES(6.9236899002715682614e0, 1.3643763279558730257e0)}, {FN (log10), ARG(-8.3886080e+06,-5.0e-01), RES(6.9236899002715682614e0, -1.3643763279558730257e0)}, {FN (log10), ARG(8.3886080e+06,1.0e+00), RES(6.9236899002715705758e0, 5.1771936643511029532e-8)}, {FN (log10), ARG(8.3886080e+06,-1.0e+00), RES(6.9236899002715705758e0, -5.1771936643511029532e-8)}, {FN (log10), ARG(-8.3886080e+06,1.0e+00), RES(6.9236899002715705758e0, 1.3643763020699047040e0)}, {FN (log10), ARG(-8.3886080e+06,-1.0e+00), RES(6.9236899002715705758e0, -1.3643763020699047040e0)}, {FN (log10), ARG(8.3886080e+06,2.0e+00), RES(6.9236899002715798333e0, 1.0354387328702058762e-7)}, {FN (log10), ARG(8.3886080e+06,-2.0e+00), RES(6.9236899002715798333e0, -1.0354387328702058762e-7)}, {FN (log10), ARG(-8.3886080e+06,2.0e+00), RES(6.9236899002715798333e0, 1.3643762502979680605e0)}, {FN (log10), ARG(-8.3886080e+06,-2.0e+00), RES(6.9236899002715798333e0, -1.3643762502979680605e0)}, {FN (log10), ARG(8.3886080e+06,8.3886080e+06), RES(7.0742048981035580875e0, 3.4109408846046033687e-1)}, {FN (log10), ARG(8.3886080e+06,-8.3886080e+06), RES(7.0742048981035580875e0, -3.4109408846046033687e-1)}, {FN (log10), ARG(-8.3886080e+06,8.3886080e+06), RES(7.0742048981035580875e0, 1.0232822653813810106e0)}, {FN (log10), ARG(-8.3886080e+06,-8.3886080e+06), RES(7.0742048981035580875e0, -1.0232822653813810106e0)}, {FN (exp), ARG(0.0e+00,-3.45266983001243932001e-04), RES(9.9999994039535581673e-1, -3.4526697614140534807e-4)}, {FN (exp), ARG(0.0e+00,3.45266983001243932001e-04), RES(9.9999994039535581673e-1, 3.4526697614140534807e-4)}, {FN (exp), ARG(0.0e+00,1.57045105981189525579e+00), RES(3.4526697614152485627e-4, 9.9999994039535581669e-1)}, {FN (exp), ARG(0.0e+00,-1.57045105981189525579e+00), RES(3.4526697614152485627e-4, -9.9999994039535581669e-1)}, {FN (exp), ARG(0.0e+00,1.57114159377789786021e+00), RES(-3.4526697614140239160e-4, 9.9999994039535581673e-1)}, {FN (exp), ARG(0.0e+00,-1.57114159377789786021e+00), RES(-3.4526697614140239160e-4, -9.9999994039535581673e-1)}, {FN (exp), ARG(0.0e+00,3.14124738660679181379e+00), RES(-9.9999994039535581667e-1, 3.4526697614158608860e-4)}, {FN (exp), ARG(0.0e+00,-3.14124738660679181379e+00), RES(-9.9999994039535581667e-1, -3.4526697614158608860e-4)}, {FN (exp), ARG(0.0e+00,3.14193792057279441821e+00), RES(-9.9999994039535581675e-1, -3.4526697614134115926e-4)}, {FN (exp), ARG(0.0e+00,-3.14193792057279441821e+00), RES(-9.9999994039535581675e-1, 3.4526697614134115926e-4)}, {FN (exp), ARG(0.0e+00,4.71204371340168837179e+00), RES(-3.4526697614164732094e-4, -9.9999994039535581664e-1)}, {FN (exp), ARG(0.0e+00,-4.71204371340168837179e+00), RES(-3.4526697614164732094e-4, 9.9999994039535581664e-1)}, {FN (exp), ARG(0.0e+00,4.71273424736769097620e+00), RES(3.4526697614127992692e-4, -9.9999994039535581677e-1)}, {FN (exp), ARG(0.0e+00,-4.71273424736769097620e+00), RES(3.4526697614127992692e-4, 9.9999994039535581677e-1)}, {FN (exp), ARG(0.0e+00,6.28284004019658492979e+00), RES(9.9999994039535581662e-1, -3.4526697614170855328e-4)}, {FN (exp), ARG(0.0e+00,-6.28284004019658492979e+00), RES(9.9999994039535581662e-1, 3.4526697614170855328e-4)}, {FN (exp), ARG(0.0e+00,6.28353057416258753420e+00), RES(9.9999994039535581679e-1, 3.4526697614121869459e-4)}, {FN (exp), ARG(0.0e+00,-6.28353057416258753420e+00), RES(9.9999994039535581679e-1, -3.4526697614121869459e-4)}, {FN (exp), ARG(0.0e+00,9.42443269378637893396e+00), RES(-9.9999994039535581689e-1, 3.4526697614094283958e-4)}, {FN (exp), ARG(0.0e+00,-9.42443269378637893396e+00), RES(-9.9999994039535581689e-1, -3.4526697614094283958e-4)}, {FN (exp), ARG(0.0e+00,9.42512322775237976202e+00), RES(-9.9999994039535581714e-1, -3.4526697614020805155e-4)}, {FN (exp), ARG(0.0e+00,-9.42512322775237976202e+00), RES(-9.9999994039535581714e-1, 3.4526697614020805155e-4)}, {FN (exp), ARG(1.19209289550781250e-07,-3.45266983001243932001e-04), RES(1.0000000596046453675e0, -3.4526701730043873250e-4)}, {FN (exp), ARG(1.19209289550781250e-07,3.45266983001243932001e-04), RES(1.0000000596046453675e0, 3.4526701730043873250e-4)}, {FN (exp), ARG(-1.19209289550781250e-07,-3.45266983001243932001e-04), RES(9.9999982118608047680e-1, -3.4526693498237687017e-4)}, {FN (exp), ARG(-1.19209289550781250e-07,3.45266983001243932001e-04), RES(9.9999982118608047680e-1, 3.4526693498237687017e-4)}, {FN (exp), ARG(1.19209289550781250e-07,1.57045105981189525579e+00), RES(3.4526701730055824072e-4, 1.0000000596046453675e0)}, {FN (exp), ARG(1.19209289550781250e-07,-1.57045105981189525579e+00), RES(3.4526701730055824072e-4, -1.0000000596046453675e0)}, {FN (exp), ARG(-1.19209289550781250e-07,1.57045105981189525579e+00), RES(3.4526693498249637836e-4, 9.9999982118608047676e-1)}, {FN (exp), ARG(-1.19209289550781250e-07,-1.57045105981189525579e+00), RES(3.4526693498249637836e-4, -9.9999982118608047676e-1)}, {FN (exp), ARG(1.19209289550781250e-07,1.57114159377789786021e+00), RES(-3.4526701730043577603e-4, 1.0000000596046453675e0)}, {FN (exp), ARG(1.19209289550781250e-07,-1.57114159377789786021e+00), RES(-3.4526701730043577603e-4, -1.0000000596046453675e0)}, {FN (exp), ARG(-1.19209289550781250e-07,1.57114159377789786021e+00), RES(-3.4526693498237391370e-4, 9.9999982118608047680e-1)}, {FN (exp), ARG(-1.19209289550781250e-07,-1.57114159377789786021e+00), RES(-3.4526693498237391370e-4, -9.9999982118608047680e-1)}, {FN (exp), ARG(1.19209289550781250e-07,3.14124738660679181379e+00), RES(-1.0000000596046453674e0, 3.4526701730061947306e-4)}, {FN (exp), ARG(1.19209289550781250e-07,-3.14124738660679181379e+00), RES(-1.0000000596046453674e0, -3.4526701730061947306e-4)}, {FN (exp), ARG(-1.19209289550781250e-07,3.14124738660679181379e+00), RES(-9.9999982118608047674e-1, 3.4526693498255761069e-4)}, {FN (exp), ARG(-1.19209289550781250e-07,-3.14124738660679181379e+00), RES(-9.9999982118608047674e-1, -3.4526693498255761069e-4)}, {FN (exp), ARG(1.19209289550781250e-07,3.14193792057279441821e+00), RES(-1.0000000596046453675e0, -3.4526701730037454368e-4)}, {FN (exp), ARG(1.19209289550781250e-07,-3.14193792057279441821e+00), RES(-1.0000000596046453675e0, 3.4526701730037454368e-4)}, {FN (exp), ARG(-1.19209289550781250e-07,3.14193792057279441821e+00), RES(-9.9999982118608047682e-1, -3.4526693498231268137e-4)}, {FN (exp), ARG(-1.19209289550781250e-07,-3.14193792057279441821e+00), RES(-9.9999982118608047682e-1, 3.4526693498231268137e-4)}, {FN (exp), ARG(1.19209289550781250e-07,4.71204371340168837179e+00), RES(-3.4526701730068070540e-4, -1.0000000596046453674e0)}, {FN (exp), ARG(1.19209289550781250e-07,-4.71204371340168837179e+00), RES(-3.4526701730068070540e-4, 1.0000000596046453674e0)}, {FN (exp), ARG(-1.19209289550781250e-07,4.71204371340168837179e+00), RES(-3.4526693498261884302e-4, -9.9999982118608047672e-1)}, {FN (exp), ARG(-1.19209289550781250e-07,-4.71204371340168837179e+00), RES(-3.4526693498261884302e-4, 9.9999982118608047672e-1)}, {FN (exp), ARG(1.19209289550781250e-07,4.71273424736769097620e+00), RES(3.4526701730031331134e-4, -1.0000000596046453676e0)}, {FN (exp), ARG(1.19209289550781250e-07,-4.71273424736769097620e+00), RES(3.4526701730031331134e-4, 1.0000000596046453676e0)}, {FN (exp), ARG(-1.19209289550781250e-07,4.71273424736769097620e+00), RES(3.4526693498225144904e-4, -9.9999982118608047684e-1)}, {FN (exp), ARG(-1.19209289550781250e-07,-4.71273424736769097620e+00), RES(3.4526693498225144904e-4, 9.9999982118608047684e-1)}, {FN (exp), ARG(1.19209289550781250e-07,6.28284004019658492979e+00), RES(1.0000000596046453674e0, -3.4526701730074193775e-4)}, {FN (exp), ARG(1.19209289550781250e-07,-6.28284004019658492979e+00), RES(1.0000000596046453674e0, 3.4526701730074193775e-4)}, {FN (exp), ARG(-1.19209289550781250e-07,6.28284004019658492979e+00), RES(9.9999982118608047670e-1, -3.4526693498268007535e-4)}, {FN (exp), ARG(-1.19209289550781250e-07,-6.28284004019658492979e+00), RES(9.9999982118608047670e-1, 3.4526693498268007535e-4)}, {FN (exp), ARG(1.19209289550781250e-07,6.28353057416258753420e+00), RES(1.0000000596046453676e0, 3.452670173002520790e-4)}, {FN (exp), ARG(1.19209289550781250e-07,-6.28353057416258753420e+00), RES(1.0000000596046453676e0, -3.452670173002520790e-4)}, {FN (exp), ARG(-1.19209289550781250e-07,6.28353057416258753420e+00), RES(9.9999982118608047687e-1, 3.4526693498219021671e-4)}, {FN (exp), ARG(-1.19209289550781250e-07,-6.28353057416258753420e+00), RES(9.9999982118608047687e-1, -3.4526693498219021671e-4)}, {FN (exp), ARG(1.19209289550781250e-07,9.42443269378637893396e+00), RES(-1.0000000596046453677e0, 3.4526701729997622396e-4)}, {FN (exp), ARG(1.19209289550781250e-07,-9.42443269378637893396e+00), RES(-1.0000000596046453677e0, -3.4526701729997622396e-4)}, {FN (exp), ARG(-1.19209289550781250e-07,9.42443269378637893396e+00), RES(-9.9999982118608047696e-1, 3.4526693498191436174e-4)}, {FN (exp), ARG(-1.19209289550781250e-07,-9.42443269378637893396e+00), RES(-9.9999982118608047696e-1, -3.4526693498191436174e-4)}, {FN (exp), ARG(1.19209289550781250e-07,9.42512322775237976202e+00), RES(-1.0000000596046453679e0, -3.4526701729924143584e-4)}, {FN (exp), ARG(1.19209289550781250e-07,-9.42512322775237976202e+00), RES(-1.0000000596046453679e0, 3.4526701729924143584e-4)}, {FN (exp), ARG(-1.19209289550781250e-07,9.42512322775237976202e+00), RES(-9.9999982118608047721e-1, -3.4526693498117957380e-4)}, {FN (exp), ARG(-1.19209289550781250e-07,-9.42512322775237976202e+00), RES(-9.9999982118608047721e-1, 3.4526693498117957380e-4)}, {FN (exp), ARG(5.0e-01,-3.45266983001243932001e-04), RES(1.6487211724286834494e0, -5.6924900763464865323e-4)}, {FN (exp), ARG(5.0e-01,3.45266983001243932001e-04), RES(1.6487211724286834494e0, 5.6924900763464865323e-4)}, {FN (exp), ARG(-5.0e-01,-3.45266983001243932001e-04), RES(6.0653062356058926519e-1, -2.0941500681603265022e-4)}, {FN (exp), ARG(-5.0e-01,3.45266983001243932001e-04), RES(6.0653062356058926519e-1, 2.0941500681603265022e-4)}, {FN (exp), ARG(5.0e-01,1.57045105981189525579e+00), RES(5.6924900763484568894e-4, 1.6487211724286834493e0)}, {FN (exp), ARG(5.0e-01,-1.57045105981189525579e+00), RES(5.6924900763484568894e-4, -1.6487211724286834493e0)}, {FN (exp), ARG(-5.0e-01,1.57045105981189525579e+00), RES(2.0941500681610513560e-4, 6.0653062356058926516e-1)}, {FN (exp), ARG(-5.0e-01,-1.57045105981189525579e+00), RES(2.0941500681610513560e-4, -6.0653062356058926516e-1)}, {FN (exp), ARG(5.0e-01,1.57114159377789786021e+00), RES(-5.6924900763464377883e-4, 1.6487211724286834494e0)}, {FN (exp), ARG(5.0e-01,-1.57114159377789786021e+00), RES(-5.6924900763464377883e-4, -1.6487211724286834494e0)}, {FN (exp), ARG(-5.0e-01,1.57114159377789786021e+00), RES(-2.0941500681603085702e-4, 6.0653062356058926519e-1)}, {FN (exp), ARG(-5.0e-01,-1.57114159377789786021e+00), RES(-2.0941500681603085702e-4, -6.0653062356058926519e-1)}, {FN (exp), ARG(5.0e-01,3.14124738660679181379e+00), RES(-1.6487211724286834493e0, 5.6924900763494664399e-4)}, {FN (exp), ARG(5.0e-01,-3.14124738660679181379e+00), RES(-1.6487211724286834493e0, -5.6924900763494664399e-4)}, {FN (exp), ARG(-5.0e-01,3.14124738660679181379e+00), RES(-6.0653062356058926515e-1, 2.0941500681614227489e-4)}, {FN (exp), ARG(-5.0e-01,-3.14124738660679181379e+00), RES(-6.0653062356058926515e-1, -2.0941500681614227489e-4)}, {FN (exp), ARG(5.0e-01,3.14193792057279441821e+00), RES(-1.6487211724286834494e0, -5.6924900763454282377e-4)}, {FN (exp), ARG(5.0e-01,-3.14193792057279441821e+00), RES(-1.6487211724286834494e0, 5.6924900763454282377e-4)}, {FN (exp), ARG(-5.0e-01,3.14193792057279441821e+00), RES(-6.0653062356058926520e-1, -2.0941500681599371773e-4)}, {FN (exp), ARG(-5.0e-01,-3.14193792057279441821e+00), RES(-6.0653062356058926520e-1, 2.0941500681599371773e-4)}, {FN (exp), ARG(5.0e-01,4.71204371340168837179e+00), RES(-5.6924900763504759905e-4, -1.6487211724286834492e0)}, {FN (exp), ARG(5.0e-01,-4.71204371340168837179e+00), RES(-5.6924900763504759905e-4, 1.6487211724286834492e0)}, {FN (exp), ARG(-5.0e-01,4.71204371340168837179e+00), RES(-2.0941500681617941418e-4, -6.0653062356058926514e-1)}, {FN (exp), ARG(-5.0e-01,-4.71204371340168837179e+00), RES(-2.0941500681617941418e-4, 6.0653062356058926514e-1)}, {FN (exp), ARG(5.0e-01,4.71273424736769097620e+00), RES(5.6924900763444186872e-4, -1.6487211724286834494e0)}, {FN (exp), ARG(5.0e-01,-4.71273424736769097620e+00), RES(5.6924900763444186872e-4, 1.6487211724286834494e0)}, {FN (exp), ARG(-5.0e-01,4.71273424736769097620e+00), RES(2.0941500681595657844e-4, -6.0653062356058926521e-1)}, {FN (exp), ARG(-5.0e-01,-4.71273424736769097620e+00), RES(2.0941500681595657844e-4, 6.0653062356058926521e-1)}, {FN (exp), ARG(5.0e-01,6.28284004019658492979e+00), RES(1.6487211724286834492e0, -5.6924900763514855410e-4)}, {FN (exp), ARG(5.0e-01,-6.28284004019658492979e+00), RES(1.6487211724286834492e0, 5.6924900763514855410e-4)}, {FN (exp), ARG(-5.0e-01,6.28284004019658492979e+00), RES(6.0653062356058926512e-1, -2.0941500681621655347e-4)}, {FN (exp), ARG(-5.0e-01,-6.28284004019658492979e+00), RES(6.0653062356058926512e-1, 2.0941500681621655347e-4)}, {FN (exp), ARG(5.0e-01,6.28353057416258753420e+00), RES(1.6487211724286834495e0, 5.6924900763434091366e-4)}, {FN (exp), ARG(5.0e-01,-6.28353057416258753420e+00), RES(1.6487211724286834495e0, -5.6924900763434091366e-4)}, {FN (exp), ARG(-5.0e-01,6.28353057416258753420e+00), RES(6.0653062356058926523e-1, 2.0941500681591943916e-4)}, {FN (exp), ARG(-5.0e-01,-6.28353057416258753420e+00), RES(6.0653062356058926523e-1, -2.0941500681591943916e-4)}, {FN (exp), ARG(5.0e-01,9.42443269378637893396e+00), RES(-1.6487211724286834496e0, 5.6924900763388610565e-4)}, {FN (exp), ARG(5.0e-01,-9.42443269378637893396e+00), RES(-1.6487211724286834496e0, -5.6924900763388610565e-4)}, {FN (exp), ARG(-5.0e-01,9.42443269378637893396e+00), RES(-6.0653062356058926528e-1, 2.0941500681575212464e-4)}, {FN (exp), ARG(-5.0e-01,-9.42443269378637893396e+00), RES(-6.0653062356058926528e-1, -2.0941500681575212464e-4)}, {FN (exp), ARG(5.0e-01,9.42512322775237976202e+00), RES(-1.6487211724286834501e0, -5.6924900763267464498e-4)}, {FN (exp), ARG(5.0e-01,-9.42512322775237976202e+00), RES(-1.6487211724286834501e0, 5.6924900763267464498e-4)}, {FN (exp), ARG(-5.0e-01,9.42512322775237976202e+00), RES(-6.0653062356058926544e-1, -2.0941500681530645317e-4)}, {FN (exp), ARG(-5.0e-01,-9.42512322775237976202e+00), RES(-6.0653062356058926544e-1, 2.0941500681530645317e-4)}, {FN (exp), ARG(1.0e+00,-3.45266983001243932001e-04), RES(2.7182816664368240602e0, -9.3853294721218487636e-4)}, {FN (exp), ARG(1.0e+00,3.45266983001243932001e-04), RES(2.7182816664368240602e0, 9.3853294721218487636e-4)}, {FN (exp), ARG(-1.0e+00,-3.45266983001243932001e-04), RES(3.6787941924411912823e-1, -1.2701662223785390836e-4)}, {FN (exp), ARG(-1.0e+00,3.45266983001243932001e-04), RES(3.6787941924411912823e-1, 1.2701662223785390836e-4)}, {FN (exp), ARG(1.0e+00,1.57045105981189525579e+00), RES(9.3853294721250973333e-4, 2.7182816664368240601e0)}, {FN (exp), ARG(1.0e+00,-1.57045105981189525579e+00), RES(9.3853294721250973333e-4, -2.7182816664368240601e0)}, {FN (exp), ARG(-1.0e+00,1.57045105981189525579e+00), RES(1.2701662223789787297e-4, 3.6787941924411912822e-1)}, {FN (exp), ARG(-1.0e+00,-1.57045105981189525579e+00), RES(1.2701662223789787297e-4, -3.6787941924411912822e-1)}, {FN (exp), ARG(1.0e+00,1.57114159377789786021e+00), RES(-9.3853294721217683983e-4, 2.7182816664368240602e0)}, {FN (exp), ARG(1.0e+00,-1.57114159377789786021e+00), RES(-9.3853294721217683983e-4, -2.7182816664368240602e0)}, {FN (exp), ARG(-1.0e+00,1.57114159377789786021e+00), RES(-1.2701662223785282074e-4, 3.6787941924411912823e-1)}, {FN (exp), ARG(-1.0e+00,-1.57114159377789786021e+00), RES(-1.2701662223785282074e-4, -3.6787941924411912823e-1)}, {FN (exp), ARG(1.0e+00,3.14124738660679181379e+00), RES(-2.718281666436824060e0, 9.3853294721267618008e-4)}, {FN (exp), ARG(1.0e+00,-3.14124738660679181379e+00), RES(-2.718281666436824060e0, -9.3853294721267618008e-4)}, {FN (exp), ARG(-1.0e+00,3.14124738660679181379e+00), RES(-3.6787941924411912821e-1, 1.2701662223792039909e-4)}, {FN (exp), ARG(-1.0e+00,-3.14124738660679181379e+00), RES(-3.6787941924411912821e-1, -1.2701662223792039909e-4)}, {FN (exp), ARG(1.0e+00,3.14193792057279441821e+00), RES(-2.7182816664368240603e0, -9.3853294721201039309e-4)}, {FN (exp), ARG(1.0e+00,-3.14193792057279441821e+00), RES(-2.7182816664368240603e0, 9.3853294721201039309e-4)}, {FN (exp), ARG(-1.0e+00,3.14193792057279441821e+00), RES(-3.6787941924411912824e-1, -1.2701662223783029462e-4)}, {FN (exp), ARG(-1.0e+00,-3.14193792057279441821e+00), RES(-3.6787941924411912824e-1, 1.2701662223783029462e-4)}, {FN (exp), ARG(1.0e+00,4.71204371340168837179e+00), RES(-9.3853294721284262682e-4, -2.718281666436824060e0)}, {FN (exp), ARG(1.0e+00,-4.71204371340168837179e+00), RES(-9.3853294721284262682e-4, 2.718281666436824060e0)}, {FN (exp), ARG(-1.0e+00,4.71204371340168837179e+00), RES(-1.2701662223794292521e-4, -3.6787941924411912820e-1)}, {FN (exp), ARG(-1.0e+00,-4.71204371340168837179e+00), RES(-1.2701662223794292521e-4, 3.6787941924411912820e-1)}, {FN (exp), ARG(1.0e+00,4.71273424736769097620e+00), RES(9.3853294721184394634e-4, -2.7182816664368240603e0)}, {FN (exp), ARG(1.0e+00,-4.71273424736769097620e+00), RES(9.3853294721184394634e-4, 2.7182816664368240603e0)}, {FN (exp), ARG(-1.0e+00,4.71273424736769097620e+00), RES(1.2701662223780776850e-4, -3.6787941924411912825e-1)}, {FN (exp), ARG(-1.0e+00,-4.71273424736769097620e+00), RES(1.2701662223780776850e-4, 3.6787941924411912825e-1)}, {FN (exp), ARG(1.0e+00,6.28284004019658492979e+00), RES(2.7182816664368240599e0, -9.3853294721300907357e-4)}, {FN (exp), ARG(1.0e+00,-6.28284004019658492979e+00), RES(2.7182816664368240599e0, 9.3853294721300907357e-4)}, {FN (exp), ARG(-1.0e+00,6.28284004019658492979e+00), RES(3.6787941924411912819e-1, -1.2701662223796545132e-4)}, {FN (exp), ARG(-1.0e+00,-6.28284004019658492979e+00), RES(3.6787941924411912819e-1, 1.2701662223796545132e-4)}, {FN (exp), ARG(1.0e+00,6.28353057416258753420e+00), RES(2.7182816664368240604e0, 9.3853294721167749959e-4)}, {FN (exp), ARG(1.0e+00,-6.28353057416258753420e+00), RES(2.7182816664368240604e0, -9.3853294721167749959e-4)}, {FN (exp), ARG(-1.0e+00,6.28353057416258753420e+00), RES(3.6787941924411912825e-1, 1.2701662223778524238e-4)}, {FN (exp), ARG(-1.0e+00,-6.28353057416258753420e+00), RES(3.6787941924411912825e-1, -1.2701662223778524238e-4)}, {FN (exp), ARG(1.0e+00,9.42443269378637893396e+00), RES(-2.7182816664368240606e0, 9.3853294721092764795e-4)}, {FN (exp), ARG(1.0e+00,-9.42443269378637893396e+00), RES(-2.7182816664368240606e0, -9.3853294721092764795e-4)}, {FN (exp), ARG(-1.0e+00,9.42443269378637893396e+00), RES(-3.6787941924411912829e-1, 1.270166222376837610e-4)}, {FN (exp), ARG(-1.0e+00,-9.42443269378637893396e+00), RES(-3.6787941924411912829e-1, -1.270166222376837610e-4)}, {FN (exp), ARG(1.0e+00,9.42512322775237976202e+00), RES(-2.7182816664368240613e0, -9.3853294720893028698e-4)}, {FN (exp), ARG(1.0e+00,-9.42512322775237976202e+00), RES(-2.7182816664368240613e0, 9.3853294720893028698e-4)}, {FN (exp), ARG(-1.0e+00,9.42512322775237976202e+00), RES(-3.6787941924411912838e-1, -1.2701662223741344759e-4)}, {FN (exp), ARG(-1.0e+00,-9.42512322775237976202e+00), RES(-3.6787941924411912838e-1, 1.2701662223741344759e-4)}, {FN (exp), ARG(2.0e+00,-3.45266983001243932001e-04), RES(7.3890556585085906002e0, -2.5511970558169944872e-3)}, {FN (exp), ARG(2.0e+00,3.45266983001243932001e-04), RES(7.3890556585085906002e0, 2.5511970558169944872e-3)}, {FN (exp), ARG(-2.0e+00,-3.45266983001243932001e-04), RES(1.3533527517000128913e-1, -4.6726804008345889445e-5)}, {FN (exp), ARG(-2.0e+00,3.45266983001243932001e-04), RES(1.3533527517000128913e-1, 4.6726804008345889445e-5)}, {FN (exp), ARG(2.0e+00,1.57045105981189525579e+00), RES(2.551197055817877540e-3, 7.3890556585085905999e0)}, {FN (exp), ARG(2.0e+00,-1.57045105981189525579e+00), RES(2.551197055817877540e-3, -7.3890556585085905999e0)}, {FN (exp), ARG(-2.0e+00,1.57045105981189525579e+00), RES(4.6726804008362063122e-5, 1.3533527517000128913e-1)}, {FN (exp), ARG(-2.0e+00,-1.57045105981189525579e+00), RES(4.6726804008362063122e-5, -1.3533527517000128913e-1)}, {FN (exp), ARG(2.0e+00,1.57114159377789786021e+00), RES(-2.5511970558169726417e-3, 7.3890556585085906002e0)}, {FN (exp), ARG(2.0e+00,-1.57114159377789786021e+00), RES(-2.5511970558169726417e-3, -7.3890556585085906002e0)}, {FN (exp), ARG(-2.0e+00,1.57114159377789786021e+00), RES(-4.6726804008345489330e-5, 1.3533527517000128913e-1)}, {FN (exp), ARG(-2.0e+00,-1.57114159377789786021e+00), RES(-4.6726804008345489330e-5, -1.3533527517000128913e-1)}, {FN (exp), ARG(2.0e+00,3.14124738660679181379e+00), RES(-7.3890556585085905998e0, 2.5511970558183299892e-3)}, {FN (exp), ARG(2.0e+00,-3.14124738660679181379e+00), RES(-7.3890556585085905998e0, -2.5511970558183299892e-3)}, {FN (exp), ARG(-2.0e+00,3.14124738660679181379e+00), RES(-1.3533527517000128912e-1, 4.6726804008370350017e-5)}, {FN (exp), ARG(-2.0e+00,-3.14124738660679181379e+00), RES(-1.3533527517000128912e-1, -4.6726804008370350017e-5)}, {FN (exp), ARG(2.0e+00,3.14193792057279441821e+00), RES(-7.3890556585085906004e0, -2.5511970558165201925e-3)}, {FN (exp), ARG(2.0e+00,-3.14193792057279441821e+00), RES(-7.3890556585085906004e0, 2.5511970558165201925e-3)}, {FN (exp), ARG(-2.0e+00,3.14193792057279441821e+00), RES(-1.3533527517000128914e-1, -4.6726804008337202435e-5)}, {FN (exp), ARG(-2.0e+00,-3.14193792057279441821e+00), RES(-1.3533527517000128914e-1, 4.6726804008337202435e-5)}, {FN (exp), ARG(2.0e+00,4.71204371340168837179e+00), RES(-2.5511970558187824384e-3, -7.3890556585085905996e0)}, {FN (exp), ARG(2.0e+00,-4.71204371340168837179e+00), RES(-2.5511970558187824384e-3, 7.3890556585085905996e0)}, {FN (exp), ARG(-2.0e+00,4.71204371340168837179e+00), RES(-4.6726804008378636913e-5, -1.3533527517000128912e-1)}, {FN (exp), ARG(-2.0e+00,-4.71204371340168837179e+00), RES(-4.6726804008378636913e-5, 1.3533527517000128912e-1)}, {FN (exp), ARG(2.0e+00,4.71273424736769097620e+00), RES(2.5511970558160677434e-3, -7.3890556585085906006e0)}, {FN (exp), ARG(2.0e+00,-4.71273424736769097620e+00), RES(2.5511970558160677434e-3, 7.3890556585085906006e0)}, {FN (exp), ARG(-2.0e+00,4.71273424736769097620e+00), RES(4.6726804008328915539e-5, -1.3533527517000128914e-1)}, {FN (exp), ARG(-2.0e+00,-4.71273424736769097620e+00), RES(4.6726804008328915539e-5, 1.3533527517000128914e-1)}, {FN (exp), ARG(2.0e+00,6.28284004019658492979e+00), RES(7.3890556585085905995e0, -2.5511970558192348875e-3)}, {FN (exp), ARG(2.0e+00,-6.28284004019658492979e+00), RES(7.3890556585085905995e0, 2.5511970558192348875e-3)}, {FN (exp), ARG(-2.0e+00,6.28284004019658492979e+00), RES(1.3533527517000128912e-1, -4.6726804008386923808e-5)}, {FN (exp), ARG(-2.0e+00,-6.28284004019658492979e+00), RES(1.3533527517000128912e-1, 4.6726804008386923808e-5)}, {FN (exp), ARG(2.0e+00,6.28353057416258753420e+00), RES(7.3890556585085906007e0, 2.5511970558156152942e-3)}, {FN (exp), ARG(2.0e+00,-6.28353057416258753420e+00), RES(7.3890556585085906007e0, -2.5511970558156152942e-3)}, {FN (exp), ARG(-2.0e+00,6.28353057416258753420e+00), RES(1.3533527517000128914e-1, 4.6726804008320628644e-5)}, {FN (exp), ARG(-2.0e+00,-6.28353057416258753420e+00), RES(1.3533527517000128914e-1, -4.6726804008320628644e-5)}, {FN (exp), ARG(2.0e+00,9.42443269378637893396e+00), RES(-7.3890556585085906014e0, 2.5511970558135769861e-3)}, {FN (exp), ARG(2.0e+00,-9.42443269378637893396e+00), RES(-7.3890556585085906014e0, -2.5511970558135769861e-3)}, {FN (exp), ARG(-2.0e+00,9.42443269378637893396e+00), RES(-1.3533527517000128916e-1, 4.6726804008283295729e-5)}, {FN (exp), ARG(-2.0e+00,-9.42443269378637893396e+00), RES(-1.3533527517000128916e-1, -4.6726804008283295729e-5)}, {FN (exp), ARG(2.0e+00,9.42512322775237976202e+00), RES(-7.3890556585085906033e0, -2.5511970558081475961e-3)}, {FN (exp), ARG(2.0e+00,-9.42512322775237976202e+00), RES(-7.3890556585085906033e0, 2.5511970558081475961e-3)}, {FN (exp), ARG(-2.0e+00,9.42512322775237976202e+00), RES(-1.3533527517000128919e-1, -4.6726804008183852982e-5)}, {FN (exp), ARG(-2.0e+00,-9.42512322775237976202e+00), RES(-1.3533527517000128919e-1, 4.6726804008183852982e-5)}, {FN (sin), ARG(-3.45266983001243932001e-04,0.0e+00), RES(-3.4526697614140534807e-4, 0.0)}, {FN (sin), ARG(3.45266983001243932001e-04,0.0e+00), RES(3.4526697614140534807e-4, 0.0)}, {FN (sin), ARG(-3.45266983001243932001e-04,1.19209289550781250e-07), RES(-3.4526697614140780134e-4, 1.1920928244535424533e-7)}, {FN (sin), ARG(-3.45266983001243932001e-04,-1.19209289550781250e-07), RES(-3.4526697614140780134e-4, -1.1920928244535424533e-7)}, {FN (sin), ARG(3.45266983001243932001e-04,1.19209289550781250e-07), RES(3.4526697614140780134e-4, 1.1920928244535424533e-7)}, {FN (sin), ARG(3.45266983001243932001e-04,-1.19209289550781250e-07), RES(3.4526697614140780134e-4, -1.1920928244535424533e-7)}, {FN (sin), ARG(-3.45266983001243932001e-04,5.0e-01), RES(-3.8933200722534065172e-4, 5.2109527443404709209e-1)}, {FN (sin), ARG(-3.45266983001243932001e-04,-5.0e-01), RES(-3.8933200722534065172e-4, -5.2109527443404709209e-1)}, {FN (sin), ARG(3.45266983001243932001e-04,5.0e-01), RES(3.8933200722534065172e-4, 5.2109527443404709209e-1)}, {FN (sin), ARG(3.45266983001243932001e-04,-5.0e-01), RES(3.8933200722534065172e-4, -5.2109527443404709209e-1)}, {FN (sin), ARG(-3.45266983001243932001e-04,1.0e+00), RES(-5.3277478472501939236e-4, 1.1752011235963524660e0)}, {FN (sin), ARG(-3.45266983001243932001e-04,-1.0e+00), RES(-5.3277478472501939236e-4, -1.1752011235963524660e0)}, {FN (sin), ARG(3.45266983001243932001e-04,1.0e+00), RES(5.3277478472501939236e-4, 1.1752011235963524660e0)}, {FN (sin), ARG(3.45266983001243932001e-04,-1.0e+00), RES(5.3277478472501939236e-4, -1.1752011235963524660e0)}, {FN (sin), ARG(-3.45266983001243932001e-04,2.0e+00), RES(-1.2989619299126701883e-3, 3.6268601916692946556e0)}, {FN (sin), ARG(-3.45266983001243932001e-04,-2.0e+00), RES(-1.2989619299126701883e-3, -3.6268601916692946556e0)}, {FN (sin), ARG(3.45266983001243932001e-04,2.0e+00), RES(1.2989619299126701883e-3, 3.6268601916692946556e0)}, {FN (sin), ARG(3.45266983001243932001e-04,-2.0e+00), RES(1.2989619299126701883e-3, -3.6268601916692946556e0)}, {FN (sin), ARG(1.57045105981189525579e+00,0.0e+00), RES(9.9999994039535581669e-1, 0.0)}, {FN (sin), ARG(-1.57045105981189525579e+00,0.0e+00), RES(-9.9999994039535581669e-1, 0.0)}, {FN (sin), ARG(1.57045105981189525579e+00,1.19209289550781250e-07), RES(9.9999994039536292211e-1, 4.1159030931177815679e-11)}, {FN (sin), ARG(1.57045105981189525579e+00,-1.19209289550781250e-07), RES(9.9999994039536292211e-1, -4.1159030931177815679e-11)}, {FN (sin), ARG(-1.57045105981189525579e+00,1.19209289550781250e-07), RES(-9.9999994039536292211e-1, 4.1159030931177815679e-11)}, {FN (sin), ARG(-1.57045105981189525579e+00,-1.19209289550781250e-07), RES(-9.9999994039536292211e-1, -4.1159030931177815679e-11)}, {FN (sin), ARG(1.57045105981189525579e+00,5.0e-01), RES(1.1276258979946363572e0, 1.7991700040937027667e-4)}, {FN (sin), ARG(1.57045105981189525579e+00,-5.0e-01), RES(1.1276258979946363572e0, -1.7991700040937027667e-4)}, {FN (sin), ARG(-1.57045105981189525579e+00,5.0e-01), RES(-1.1276258979946363572e0, 1.7991700040937027667e-4)}, {FN (sin), ARG(-1.57045105981189525579e+00,-5.0e-01), RES(-1.1276258979946363572e0, -1.7991700040937027667e-4)}, {FN (sin), ARG(1.57045105981189525579e+00,1.0e+00), RES(1.5430805428404715942e0, 4.0575816248730593018e-4)}, {FN (sin), ARG(1.57045105981189525579e+00,-1.0e+00), RES(1.5430805428404715942e0, -4.0575816248730593018e-4)}, {FN (sin), ARG(-1.57045105981189525579e+00,1.0e+00), RES(-1.5430805428404715942e0, 4.0575816248730593018e-4)}, {FN (sin), ARG(-1.57045105981189525579e+00,-1.0e+00), RES(-1.5430805428404715942e0, -4.0575816248730593018e-4)}, {FN (sin), ARG(1.57045105981189525579e+00,2.0e+00), RES(3.7621954668392959445e0, 1.2522351259047577385e-3)}, {FN (sin), ARG(1.57045105981189525579e+00,-2.0e+00), RES(3.7621954668392959445e0, -1.2522351259047577385e-3)}, {FN (sin), ARG(-1.57045105981189525579e+00,2.0e+00), RES(-3.7621954668392959445e0, 1.2522351259047577385e-3)}, {FN (sin), ARG(-1.57045105981189525579e+00,-2.0e+00), RES(-3.7621954668392959445e0, -1.2522351259047577385e-3)}, {FN (sin), ARG(1.57114159377789786021e+00,0.0e+00), RES(9.9999994039535581673e-1, 0.0)}, {FN (sin), ARG(-1.57114159377789786021e+00,0.0e+00), RES(-9.9999994039535581673e-1, 0.0)}, {FN (sin), ARG(1.57114159377789786021e+00,1.19209289550781250e-07), RES(9.9999994039536292216e-1, -4.1159030931163216752e-11)}, {FN (sin), ARG(1.57114159377789786021e+00,-1.19209289550781250e-07), RES(9.9999994039536292216e-1, 4.1159030931163216752e-11)}, {FN (sin), ARG(-1.57114159377789786021e+00,1.19209289550781250e-07), RES(-9.9999994039536292216e-1, -4.1159030931163216752e-11)}, {FN (sin), ARG(-1.57114159377789786021e+00,-1.19209289550781250e-07), RES(-9.9999994039536292216e-1, 4.1159030931163216752e-11)}, {FN (sin), ARG(1.57114159377789786021e+00,5.0e-01), RES(1.1276258979946363573e0, -1.7991700040930646090e-4)}, {FN (sin), ARG(1.57114159377789786021e+00,-5.0e-01), RES(1.1276258979946363573e0, 1.7991700040930646090e-4)}, {FN (sin), ARG(-1.57114159377789786021e+00,5.0e-01), RES(-1.1276258979946363573e0, -1.7991700040930646090e-4)}, {FN (sin), ARG(-1.57114159377789786021e+00,-5.0e-01), RES(-1.1276258979946363573e0, 1.7991700040930646090e-4)}, {FN (sin), ARG(1.57114159377789786021e+00,1.0e+00), RES(1.5430805428404715942e0, -4.0575816248716200955e-4)}, {FN (sin), ARG(1.57114159377789786021e+00,-1.0e+00), RES(1.5430805428404715942e0, 4.0575816248716200955e-4)}, {FN (sin), ARG(-1.57114159377789786021e+00,1.0e+00), RES(-1.5430805428404715942e0, -4.0575816248716200955e-4)}, {FN (sin), ARG(-1.57114159377789786021e+00,-1.0e+00), RES(-1.5430805428404715942e0, 4.0575816248716200955e-4)}, {FN (sin), ARG(1.57114159377789786021e+00,2.0e+00), RES(3.7621954668392959447e0, -1.2522351259043135762e-3)}, {FN (sin), ARG(1.57114159377789786021e+00,-2.0e+00), RES(3.7621954668392959447e0, 1.2522351259043135762e-3)}, {FN (sin), ARG(-1.57114159377789786021e+00,2.0e+00), RES(-3.7621954668392959447e0, -1.2522351259043135762e-3)}, {FN (sin), ARG(-1.57114159377789786021e+00,-2.0e+00), RES(-3.7621954668392959447e0, 1.2522351259043135762e-3)}, {FN (sin), ARG(3.14124738660679181379e+00,0.0e+00), RES(3.4526697614158608860e-4, 0.0)}, {FN (sin), ARG(-3.14124738660679181379e+00,0.0e+00), RES(-3.4526697614158608860e-4, 0.0)}, {FN (sin), ARG(3.14124738660679181379e+00,1.19209289550781250e-07), RES(3.4526697614158854187e-4, -1.1920928244535424532e-7)}, {FN (sin), ARG(3.14124738660679181379e+00,-1.19209289550781250e-07), RES(3.4526697614158854187e-4, 1.1920928244535424532e-7)}, {FN (sin), ARG(-3.14124738660679181379e+00,1.19209289550781250e-07), RES(-3.4526697614158854187e-4, -1.1920928244535424532e-7)}, {FN (sin), ARG(-3.14124738660679181379e+00,-1.19209289550781250e-07), RES(-3.4526697614158854187e-4, 1.1920928244535424532e-7)}, {FN (sin), ARG(3.14124738660679181379e+00,5.0e-01), RES(3.8933200722554445944e-4, -5.2109527443404709206e-1)}, {FN (sin), ARG(3.14124738660679181379e+00,-5.0e-01), RES(3.8933200722554445944e-4, 5.2109527443404709206e-1)}, {FN (sin), ARG(-3.14124738660679181379e+00,5.0e-01), RES(-3.8933200722554445944e-4, -5.2109527443404709206e-1)}, {FN (sin), ARG(-3.14124738660679181379e+00,-5.0e-01), RES(-3.8933200722554445944e-4, 5.2109527443404709206e-1)}, {FN (sin), ARG(3.14124738660679181379e+00,1.0e+00), RES(5.3277478472529828958e-4, -1.1752011235963524659e0)}, {FN (sin), ARG(3.14124738660679181379e+00,-1.0e+00), RES(5.3277478472529828958e-4, 1.1752011235963524659e0)}, {FN (sin), ARG(-3.14124738660679181379e+00,1.0e+00), RES(-5.3277478472529828958e-4, -1.1752011235963524659e0)}, {FN (sin), ARG(-3.14124738660679181379e+00,-1.0e+00), RES(-5.3277478472529828958e-4, 1.1752011235963524659e0)}, {FN (sin), ARG(3.14124738660679181379e+00,2.0e+00), RES(1.2989619299133501696e-3, -3.6268601916692946553e0)}, {FN (sin), ARG(3.14124738660679181379e+00,-2.0e+00), RES(1.2989619299133501696e-3, 3.6268601916692946553e0)}, {FN (sin), ARG(-3.14124738660679181379e+00,2.0e+00), RES(-1.2989619299133501696e-3, -3.6268601916692946553e0)}, {FN (sin), ARG(-3.14124738660679181379e+00,-2.0e+00), RES(-1.2989619299133501696e-3, 3.6268601916692946553e0)}, {FN (sin), ARG(3.14193792057279441821e+00,0.0e+00), RES(-3.4526697614134115926e-4, 0.0)}, {FN (sin), ARG(-3.14193792057279441821e+00,0.0e+00), RES(3.4526697614134115926e-4, 0.0)}, {FN (sin), ARG(3.14193792057279441821e+00,1.19209289550781250e-07), RES(-3.4526697614134361253e-4, -1.1920928244535424533e-7)}, {FN (sin), ARG(3.14193792057279441821e+00,-1.19209289550781250e-07), RES(-3.4526697614134361253e-4, 1.1920928244535424533e-7)}, {FN (sin), ARG(-3.14193792057279441821e+00,1.19209289550781250e-07), RES(3.4526697614134361253e-4, -1.1920928244535424533e-7)}, {FN (sin), ARG(-3.14193792057279441821e+00,-1.19209289550781250e-07), RES(3.4526697614134361253e-4, 1.1920928244535424533e-7)}, {FN (sin), ARG(3.14193792057279441821e+00,5.0e-01), RES(-3.8933200722526827075e-4, -5.2109527443404709211e-1)}, {FN (sin), ARG(3.14193792057279441821e+00,-5.0e-01), RES(-3.8933200722526827075e-4, 5.2109527443404709211e-1)}, {FN (sin), ARG(-3.14193792057279441821e+00,5.0e-01), RES(3.8933200722526827075e-4, -5.2109527443404709211e-1)}, {FN (sin), ARG(-3.14193792057279441821e+00,-5.0e-01), RES(3.8933200722526827075e-4, 5.2109527443404709211e-1)}, {FN (sin), ARG(3.14193792057279441821e+00,1.0e+00), RES(-5.3277478472492034385e-4, -1.1752011235963524660e0)}, {FN (sin), ARG(3.14193792057279441821e+00,-1.0e+00), RES(-5.3277478472492034385e-4, 1.1752011235963524660e0)}, {FN (sin), ARG(-3.14193792057279441821e+00,1.0e+00), RES(5.3277478472492034385e-4, -1.1752011235963524660e0)}, {FN (sin), ARG(-3.14193792057279441821e+00,-1.0e+00), RES(5.3277478472492034385e-4, 1.1752011235963524660e0)}, {FN (sin), ARG(3.14193792057279441821e+00,2.0e+00), RES(-1.2989619299124286975e-3, -3.6268601916692946556e0)}, {FN (sin), ARG(3.14193792057279441821e+00,-2.0e+00), RES(-1.2989619299124286975e-3, 3.6268601916692946556e0)}, {FN (sin), ARG(-3.14193792057279441821e+00,2.0e+00), RES(1.2989619299124286975e-3, -3.6268601916692946556e0)}, {FN (sin), ARG(-3.14193792057279441821e+00,-2.0e+00), RES(1.2989619299124286975e-3, 3.6268601916692946556e0)}, {FN (sin), ARG(4.71204371340168837179e+00,0.0e+00), RES(-9.9999994039535581664e-1, 0.0)}, {FN (sin), ARG(-4.71204371340168837179e+00,0.0e+00), RES(9.9999994039535581664e-1, 0.0)}, {FN (sin), ARG(4.71204371340168837179e+00,1.19209289550781250e-07), RES(-9.9999994039536292207e-1, -4.1159030931192414605e-11)}, {FN (sin), ARG(4.71204371340168837179e+00,-1.19209289550781250e-07), RES(-9.9999994039536292207e-1, 4.1159030931192414605e-11)}, {FN (sin), ARG(-4.71204371340168837179e+00,1.19209289550781250e-07), RES(9.9999994039536292207e-1, -4.1159030931192414605e-11)}, {FN (sin), ARG(-4.71204371340168837179e+00,-1.19209289550781250e-07), RES(9.9999994039536292207e-1, 4.1159030931192414605e-11)}, {FN (sin), ARG(4.71204371340168837179e+00,5.0e-01), RES(-1.1276258979946363572e0, -1.7991700040943409243e-4)}, {FN (sin), ARG(4.71204371340168837179e+00,-5.0e-01), RES(-1.1276258979946363572e0, 1.7991700040943409243e-4)}, {FN (sin), ARG(-4.71204371340168837179e+00,5.0e-01), RES(1.1276258979946363572e0, -1.7991700040943409243e-4)}, {FN (sin), ARG(-4.71204371340168837179e+00,-5.0e-01), RES(1.1276258979946363572e0, 1.7991700040943409243e-4)}, {FN (sin), ARG(4.71204371340168837179e+00,1.0e+00), RES(-1.5430805428404715941e0, -4.0575816248744985081e-4)}, {FN (sin), ARG(4.71204371340168837179e+00,-1.0e+00), RES(-1.5430805428404715941e0, 4.0575816248744985081e-4)}, {FN (sin), ARG(-4.71204371340168837179e+00,1.0e+00), RES(1.5430805428404715941e0, -4.0575816248744985081e-4)}, {FN (sin), ARG(-4.71204371340168837179e+00,-1.0e+00), RES(1.5430805428404715941e0, 4.0575816248744985081e-4)}, {FN (sin), ARG(4.71204371340168837179e+00,2.0e+00), RES(-3.7621954668392959444e0, -1.2522351259052019007e-3)}, {FN (sin), ARG(4.71204371340168837179e+00,-2.0e+00), RES(-3.7621954668392959444e0, 1.2522351259052019007e-3)}, {FN (sin), ARG(-4.71204371340168837179e+00,2.0e+00), RES(3.7621954668392959444e0, -1.2522351259052019007e-3)}, {FN (sin), ARG(-4.71204371340168837179e+00,-2.0e+00), RES(3.7621954668392959444e0, 1.2522351259052019007e-3)}, {FN (sin), ARG(4.71273424736769097620e+00,0.0e+00), RES(-9.9999994039535581677e-1, 0.0)}, {FN (sin), ARG(-4.71273424736769097620e+00,0.0e+00), RES(9.9999994039535581677e-1, 0.0)}, {FN (sin), ARG(4.71273424736769097620e+00,1.19209289550781250e-07), RES(-9.9999994039536292220e-1, 4.1159030931148617825e-11)}, {FN (sin), ARG(4.71273424736769097620e+00,-1.19209289550781250e-07), RES(-9.9999994039536292220e-1, -4.1159030931148617825e-11)}, {FN (sin), ARG(-4.71273424736769097620e+00,1.19209289550781250e-07), RES(9.9999994039536292220e-1, 4.1159030931148617825e-11)}, {FN (sin), ARG(-4.71273424736769097620e+00,-1.19209289550781250e-07), RES(9.9999994039536292220e-1, -4.1159030931148617825e-11)}, {FN (sin), ARG(4.71273424736769097620e+00,5.0e-01), RES(-1.1276258979946363573e0, 1.7991700040924264514e-4)}, {FN (sin), ARG(4.71273424736769097620e+00,-5.0e-01), RES(-1.1276258979946363573e0, -1.7991700040924264514e-4)}, {FN (sin), ARG(-4.71273424736769097620e+00,5.0e-01), RES(1.1276258979946363573e0, 1.7991700040924264514e-4)}, {FN (sin), ARG(-4.71273424736769097620e+00,-5.0e-01), RES(1.1276258979946363573e0, -1.7991700040924264514e-4)}, {FN (sin), ARG(4.71273424736769097620e+00,1.0e+00), RES(-1.5430805428404715943e0, 4.0575816248701808892e-4)}, {FN (sin), ARG(4.71273424736769097620e+00,-1.0e+00), RES(-1.5430805428404715943e0, -4.0575816248701808892e-4)}, {FN (sin), ARG(-4.71273424736769097620e+00,1.0e+00), RES(1.5430805428404715943e0, 4.0575816248701808892e-4)}, {FN (sin), ARG(-4.71273424736769097620e+00,-1.0e+00), RES(1.5430805428404715943e0, -4.0575816248701808892e-4)}, {FN (sin), ARG(4.71273424736769097620e+00,2.0e+00), RES(-3.7621954668392959448e0, 1.2522351259038694139e-3)}, {FN (sin), ARG(4.71273424736769097620e+00,-2.0e+00), RES(-3.7621954668392959448e0, -1.2522351259038694139e-3)}, {FN (sin), ARG(-4.71273424736769097620e+00,2.0e+00), RES(3.7621954668392959448e0, 1.2522351259038694139e-3)}, {FN (sin), ARG(-4.71273424736769097620e+00,-2.0e+00), RES(3.7621954668392959448e0, -1.2522351259038694139e-3)}, {FN (sin), ARG(6.28284004019658492979e+00,0.0e+00), RES(-3.4526697614170855328e-4, 0.0)}, {FN (sin), ARG(-6.28284004019658492979e+00,0.0e+00), RES(3.4526697614170855328e-4, 0.0)}, {FN (sin), ARG(6.28284004019658492979e+00,1.19209289550781250e-07), RES(-3.4526697614171100655e-4, 1.1920928244535424532e-7)}, {FN (sin), ARG(6.28284004019658492979e+00,-1.19209289550781250e-07), RES(-3.4526697614171100655e-4, -1.1920928244535424532e-7)}, {FN (sin), ARG(-6.28284004019658492979e+00,1.19209289550781250e-07), RES(3.4526697614171100655e-4, 1.1920928244535424532e-7)}, {FN (sin), ARG(-6.28284004019658492979e+00,-1.19209289550781250e-07), RES(3.4526697614171100655e-4, -1.1920928244535424532e-7)}, {FN (sin), ARG(6.28284004019658492979e+00,5.0e-01), RES(-3.8933200722568255379e-4, 5.2109527443404709204e-1)}, {FN (sin), ARG(6.28284004019658492979e+00,-5.0e-01), RES(-3.8933200722568255379e-4, -5.2109527443404709204e-1)}, {FN (sin), ARG(-6.28284004019658492979e+00,5.0e-01), RES(3.8933200722568255379e-4, 5.2109527443404709204e-1)}, {FN (sin), ARG(-6.28284004019658492979e+00,-5.0e-01), RES(3.8933200722568255379e-4, -5.2109527443404709204e-1)}, {FN (sin), ARG(6.28284004019658492979e+00,1.0e+00), RES(-5.3277478472548726245e-4, 1.1752011235963524659e0)}, {FN (sin), ARG(6.28284004019658492979e+00,-1.0e+00), RES(-5.3277478472548726245e-4, -1.1752011235963524659e0)}, {FN (sin), ARG(-6.28284004019658492979e+00,1.0e+00), RES(5.3277478472548726245e-4, 1.1752011235963524659e0)}, {FN (sin), ARG(-6.28284004019658492979e+00,-1.0e+00), RES(5.3277478472548726245e-4, -1.1752011235963524659e0)}, {FN (sin), ARG(6.28284004019658492979e+00,2.0e+00), RES(-1.2989619299138109057e-3, 3.6268601916692946552e0)}, {FN (sin), ARG(6.28284004019658492979e+00,-2.0e+00), RES(-1.2989619299138109057e-3, -3.6268601916692946552e0)}, {FN (sin), ARG(-6.28284004019658492979e+00,2.0e+00), RES(1.2989619299138109057e-3, 3.6268601916692946552e0)}, {FN (sin), ARG(-6.28284004019658492979e+00,-2.0e+00), RES(1.2989619299138109057e-3, -3.6268601916692946552e0)}, {FN (sin), ARG(6.28353057416258753420e+00,0.0e+00), RES(3.4526697614121869459e-4, 0.0)}, {FN (sin), ARG(-6.28353057416258753420e+00,0.0e+00), RES(-3.4526697614121869459e-4, 0.0)}, {FN (sin), ARG(6.28353057416258753420e+00,1.19209289550781250e-07), RES(3.4526697614122114786e-4, 1.1920928244535424534e-7)}, {FN (sin), ARG(6.28353057416258753420e+00,-1.19209289550781250e-07), RES(3.4526697614122114786e-4, -1.1920928244535424534e-7)}, {FN (sin), ARG(-6.28353057416258753420e+00,1.19209289550781250e-07), RES(-3.4526697614122114786e-4, 1.1920928244535424534e-7)}, {FN (sin), ARG(-6.28353057416258753420e+00,-1.19209289550781250e-07), RES(-3.4526697614122114786e-4, -1.1920928244535424534e-7)}, {FN (sin), ARG(6.28353057416258753420e+00,5.0e-01), RES(3.8933200722513017641e-4, 5.2109527443404709213e-1)}, {FN (sin), ARG(6.28353057416258753420e+00,-5.0e-01), RES(3.8933200722513017641e-4, -5.2109527443404709213e-1)}, {FN (sin), ARG(-6.28353057416258753420e+00,5.0e-01), RES(-3.8933200722513017641e-4, 5.2109527443404709213e-1)}, {FN (sin), ARG(-6.28353057416258753420e+00,-5.0e-01), RES(-3.8933200722513017641e-4, -5.2109527443404709213e-1)}, {FN (sin), ARG(6.28353057416258753420e+00,1.0e+00), RES(5.3277478472473137099e-4, 1.1752011235963524661e0)}, {FN (sin), ARG(6.28353057416258753420e+00,-1.0e+00), RES(5.3277478472473137099e-4, -1.1752011235963524661e0)}, {FN (sin), ARG(-6.28353057416258753420e+00,1.0e+00), RES(-5.3277478472473137099e-4, 1.1752011235963524661e0)}, {FN (sin), ARG(-6.28353057416258753420e+00,-1.0e+00), RES(-5.3277478472473137099e-4, -1.1752011235963524661e0)}, {FN (sin), ARG(6.28353057416258753420e+00,2.0e+00), RES(1.2989619299119679614e-3, 3.6268601916692946558e0)}, {FN (sin), ARG(6.28353057416258753420e+00,-2.0e+00), RES(1.2989619299119679614e-3, -3.6268601916692946558e0)}, {FN (sin), ARG(-6.28353057416258753420e+00,2.0e+00), RES(-1.2989619299119679614e-3, 3.6268601916692946558e0)}, {FN (sin), ARG(-6.28353057416258753420e+00,-2.0e+00), RES(-1.2989619299119679614e-3, -3.6268601916692946558e0)}, {FN (sin), ARG(9.42443269378637893396e+00,0.0e+00), RES(3.4526697614094283958e-4, 0.0)}, {FN (sin), ARG(-9.42443269378637893396e+00,0.0e+00), RES(-3.4526697614094283958e-4, 0.0)}, {FN (sin), ARG(9.42443269378637893396e+00,1.19209289550781250e-07), RES(3.4526697614094529285e-4, -1.1920928244535424535e-7)}, {FN (sin), ARG(9.42443269378637893396e+00,-1.19209289550781250e-07), RES(3.4526697614094529285e-4, 1.1920928244535424535e-7)}, {FN (sin), ARG(-9.42443269378637893396e+00,1.19209289550781250e-07), RES(-3.4526697614094529285e-4, -1.1920928244535424535e-7)}, {FN (sin), ARG(-9.42443269378637893396e+00,-1.19209289550781250e-07), RES(-3.4526697614094529285e-4, 1.1920928244535424535e-7)}, {FN (sin), ARG(9.42443269378637893396e+00,5.0e-01), RES(3.8933200722481911514e-4, -5.2109527443404709218e-1)}, {FN (sin), ARG(9.42443269378637893396e+00,-5.0e-01), RES(3.8933200722481911514e-4, 5.2109527443404709218e-1)}, {FN (sin), ARG(-9.42443269378637893396e+00,5.0e-01), RES(-3.8933200722481911514e-4, -5.2109527443404709218e-1)}, {FN (sin), ARG(-9.42443269378637893396e+00,-5.0e-01), RES(-3.8933200722481911514e-4, 5.2109527443404709218e-1)}, {FN (sin), ARG(9.42443269378637893396e+00,1.0e+00), RES(5.3277478472430570447e-4, -1.1752011235963524662e0)}, {FN (sin), ARG(9.42443269378637893396e+00,-1.0e+00), RES(5.3277478472430570447e-4, 1.1752011235963524662e0)}, {FN (sin), ARG(-9.42443269378637893396e+00,1.0e+00), RES(-5.3277478472430570447e-4, -1.1752011235963524662e0)}, {FN (sin), ARG(-9.42443269378637893396e+00,-1.0e+00), RES(-5.3277478472430570447e-4, 1.1752011235963524662e0)}, {FN (sin), ARG(9.42443269378637893396e+00,2.0e+00), RES(1.2989619299109301409e-3, -3.6268601916692946561e0)}, {FN (sin), ARG(9.42443269378637893396e+00,-2.0e+00), RES(1.2989619299109301409e-3, 3.6268601916692946561e0)}, {FN (sin), ARG(-9.42443269378637893396e+00,2.0e+00), RES(-1.2989619299109301409e-3, -3.6268601916692946561e0)}, {FN (sin), ARG(-9.42443269378637893396e+00,-2.0e+00), RES(-1.2989619299109301409e-3, 3.6268601916692946561e0)}, {FN (sin), ARG(9.42512322775237976202e+00,0.0e+00), RES(-3.4526697614020805155e-4, 0.0)}, {FN (sin), ARG(-9.42512322775237976202e+00,0.0e+00), RES(3.4526697614020805155e-4, 0.0)}, {FN (sin), ARG(9.42512322775237976202e+00,1.19209289550781250e-07), RES(-3.4526697614021050482e-4, -1.1920928244535424538e-7)}, {FN (sin), ARG(9.42512322775237976202e+00,-1.19209289550781250e-07), RES(-3.4526697614021050482e-4, 1.1920928244535424538e-7)}, {FN (sin), ARG(-9.42512322775237976202e+00,1.19209289550781250e-07), RES(3.4526697614021050482e-4, -1.1920928244535424538e-7)}, {FN (sin), ARG(-9.42512322775237976202e+00,-1.19209289550781250e-07), RES(3.4526697614021050482e-4, 1.1920928244535424538e-7)}, {FN (sin), ARG(9.42512322775237976202e+00,5.0e-01), RES(-3.8933200722399054908e-4, -5.2109527443404709231e-1)}, {FN (sin), ARG(9.42512322775237976202e+00,-5.0e-01), RES(-3.8933200722399054908e-4, 5.2109527443404709231e-1)}, {FN (sin), ARG(-9.42512322775237976202e+00,5.0e-01), RES(3.8933200722399054908e-4, -5.2109527443404709231e-1)}, {FN (sin), ARG(-9.42512322775237976202e+00,-5.0e-01), RES(3.8933200722399054908e-4, 5.2109527443404709231e-1)}, {FN (sin), ARG(9.42512322775237976202e+00,1.0e+00), RES(-5.3277478472317186729e-4, -1.1752011235963524665e0)}, {FN (sin), ARG(9.42512322775237976202e+00,-1.0e+00), RES(-5.3277478472317186729e-4, 1.1752011235963524665e0)}, {FN (sin), ARG(-9.42512322775237976202e+00,1.0e+00), RES(5.3277478472317186729e-4, -1.1752011235963524665e0)}, {FN (sin), ARG(-9.42512322775237976202e+00,-1.0e+00), RES(5.3277478472317186729e-4, 1.1752011235963524665e0)}, {FN (sin), ARG(9.42512322775237976202e+00,2.0e+00), RES(-1.2989619299081657245e-3, -3.6268601916692946571e0)}, {FN (sin), ARG(9.42512322775237976202e+00,-2.0e+00), RES(-1.2989619299081657245e-3, 3.6268601916692946571e0)}, {FN (sin), ARG(-9.42512322775237976202e+00,2.0e+00), RES(1.2989619299081657245e-3, -3.6268601916692946571e0)}, {FN (sin), ARG(-9.42512322775237976202e+00,-2.0e+00), RES(1.2989619299081657245e-3, 3.6268601916692946571e0)}, {FN (cos), ARG(-3.45266983001243932001e-04,0.0e+00), RES(9.9999994039535581673e-1, 0.0)}, {FN (cos), ARG(3.45266983001243932001e-04,0.0e+00), RES(9.9999994039535581673e-1, 0.0)}, {FN (cos), ARG(-3.45266983001243932001e-04,1.19209289550781250e-07), RES(9.9999994039536292216e-1, 4.1159030931163569191e-11)}, {FN (cos), ARG(-3.45266983001243932001e-04,-1.19209289550781250e-07), RES(9.9999994039536292216e-1, -4.1159030931163569191e-11)}, {FN (cos), ARG(3.45266983001243932001e-04,1.19209289550781250e-07), RES(9.9999994039536292216e-1, -4.1159030931163569191e-11)}, {FN (cos), ARG(3.45266983001243932001e-04,-1.19209289550781250e-07), RES(9.9999994039536292216e-1, 4.1159030931163569191e-11)}, {FN (cos), ARG(-3.45266983001243932001e-04,5.0e-01), RES(1.1276258979946363573e0, 1.7991700040930800151e-4)}, {FN (cos), ARG(-3.45266983001243932001e-04,-5.0e-01), RES(1.1276258979946363573e0, -1.7991700040930800151e-4)}, {FN (cos), ARG(3.45266983001243932001e-04,5.0e-01), RES(1.1276258979946363573e0, -1.7991700040930800151e-4)}, {FN (cos), ARG(3.45266983001243932001e-04,-5.0e-01), RES(1.1276258979946363573e0, 1.7991700040930800151e-4)}, {FN (cos), ARG(-3.45266983001243932001e-04,1.0e+00), RES(1.5430805428404715942e0, 4.057581624871654840e-4)}, {FN (cos), ARG(-3.45266983001243932001e-04,-1.0e+00), RES(1.5430805428404715942e0, -4.057581624871654840e-4)}, {FN (cos), ARG(3.45266983001243932001e-04,1.0e+00), RES(1.5430805428404715942e0, -4.057581624871654840e-4)}, {FN (cos), ARG(3.45266983001243932001e-04,-1.0e+00), RES(1.5430805428404715942e0, 4.057581624871654840e-4)}, {FN (cos), ARG(-3.45266983001243932001e-04,2.0e+00), RES(3.7621954668392959447e0, 1.2522351259043242989e-3)}, {FN (cos), ARG(-3.45266983001243932001e-04,-2.0e+00), RES(3.7621954668392959447e0, -1.2522351259043242989e-3)}, {FN (cos), ARG(3.45266983001243932001e-04,2.0e+00), RES(3.7621954668392959447e0, -1.2522351259043242989e-3)}, {FN (cos), ARG(3.45266983001243932001e-04,-2.0e+00), RES(3.7621954668392959447e0, 1.2522351259043242989e-3)}, {FN (cos), ARG(1.57045105981189525579e+00,0.0e+00), RES(3.4526697614152485627e-4, 0.0)}, {FN (cos), ARG(-1.57045105981189525579e+00,0.0e+00), RES(3.4526697614152485627e-4, 0.0)}, {FN (cos), ARG(1.57045105981189525579e+00,1.19209289550781250e-07), RES(3.4526697614152730954e-4, -1.1920928244535424532e-7)}, {FN (cos), ARG(1.57045105981189525579e+00,-1.19209289550781250e-07), RES(3.4526697614152730954e-4, 1.1920928244535424532e-7)}, {FN (cos), ARG(-1.57045105981189525579e+00,1.19209289550781250e-07), RES(3.4526697614152730954e-4, 1.1920928244535424532e-7)}, {FN (cos), ARG(-1.57045105981189525579e+00,-1.19209289550781250e-07), RES(3.4526697614152730954e-4, -1.1920928244535424532e-7)}, {FN (cos), ARG(1.57045105981189525579e+00,5.0e-01), RES(3.8933200722547541227e-4, -5.2109527443404709207e-1)}, {FN (cos), ARG(1.57045105981189525579e+00,-5.0e-01), RES(3.8933200722547541227e-4, 5.2109527443404709207e-1)}, {FN (cos), ARG(-1.57045105981189525579e+00,5.0e-01), RES(3.8933200722547541227e-4, 5.2109527443404709207e-1)}, {FN (cos), ARG(-1.57045105981189525579e+00,-5.0e-01), RES(3.8933200722547541227e-4, -5.2109527443404709207e-1)}, {FN (cos), ARG(1.57045105981189525579e+00,1.0e+00), RES(5.3277478472520380315e-4, -1.1752011235963524659e0)}, {FN (cos), ARG(1.57045105981189525579e+00,-1.0e+00), RES(5.3277478472520380315e-4, 1.1752011235963524659e0)}, {FN (cos), ARG(-1.57045105981189525579e+00,1.0e+00), RES(5.3277478472520380315e-4, 1.1752011235963524659e0)}, {FN (cos), ARG(-1.57045105981189525579e+00,-1.0e+00), RES(5.3277478472520380315e-4, -1.1752011235963524659e0)}, {FN (cos), ARG(1.57045105981189525579e+00,2.0e+00), RES(1.2989619299131198016e-3, -3.6268601916692946554e0)}, {FN (cos), ARG(1.57045105981189525579e+00,-2.0e+00), RES(1.2989619299131198016e-3, 3.6268601916692946554e0)}, {FN (cos), ARG(-1.57045105981189525579e+00,2.0e+00), RES(1.2989619299131198016e-3, 3.6268601916692946554e0)}, {FN (cos), ARG(-1.57045105981189525579e+00,-2.0e+00), RES(1.2989619299131198016e-3, -3.6268601916692946554e0)}, {FN (cos), ARG(1.57114159377789786021e+00,0.0e+00), RES(-3.4526697614140239160e-4, 0.0)}, {FN (cos), ARG(-1.57114159377789786021e+00,0.0e+00), RES(-3.4526697614140239160e-4, 0.0)}, {FN (cos), ARG(1.57114159377789786021e+00,1.19209289550781250e-07), RES(-3.4526697614140484486e-4, -1.1920928244535424533e-7)}, {FN (cos), ARG(1.57114159377789786021e+00,-1.19209289550781250e-07), RES(-3.4526697614140484486e-4, 1.1920928244535424533e-7)}, {FN (cos), ARG(-1.57114159377789786021e+00,1.19209289550781250e-07), RES(-3.4526697614140484486e-4, 1.1920928244535424533e-7)}, {FN (cos), ARG(-1.57114159377789786021e+00,-1.19209289550781250e-07), RES(-3.4526697614140484486e-4, -1.1920928244535424533e-7)}, {FN (cos), ARG(1.57114159377789786021e+00,5.0e-01), RES(-3.8933200722533731792e-4, -5.2109527443404709209e-1)}, {FN (cos), ARG(1.57114159377789786021e+00,-5.0e-01), RES(-3.8933200722533731792e-4, 5.2109527443404709209e-1)}, {FN (cos), ARG(-1.57114159377789786021e+00,5.0e-01), RES(-3.8933200722533731792e-4, 5.2109527443404709209e-1)}, {FN (cos), ARG(-1.57114159377789786021e+00,-5.0e-01), RES(-3.8933200722533731792e-4, -5.2109527443404709209e-1)}, {FN (cos), ARG(1.57114159377789786021e+00,1.0e+00), RES(-5.3277478472501483029e-4, -1.1752011235963524660e0)}, {FN (cos), ARG(1.57114159377789786021e+00,-1.0e+00), RES(-5.3277478472501483029e-4, 1.1752011235963524660e0)}, {FN (cos), ARG(-1.57114159377789786021e+00,1.0e+00), RES(-5.3277478472501483029e-4, 1.1752011235963524660e0)}, {FN (cos), ARG(-1.57114159377789786021e+00,-1.0e+00), RES(-5.3277478472501483029e-4, -1.1752011235963524660e0)}, {FN (cos), ARG(1.57114159377789786021e+00,2.0e+00), RES(-1.2989619299126590655e-3, -3.6268601916692946556e0)}, {FN (cos), ARG(1.57114159377789786021e+00,-2.0e+00), RES(-1.2989619299126590655e-3, 3.6268601916692946556e0)}, {FN (cos), ARG(-1.57114159377789786021e+00,2.0e+00), RES(-1.2989619299126590655e-3, 3.6268601916692946556e0)}, {FN (cos), ARG(-1.57114159377789786021e+00,-2.0e+00), RES(-1.2989619299126590655e-3, -3.6268601916692946556e0)}, {FN (cos), ARG(3.14124738660679181379e+00,0.0e+00), RES(-9.9999994039535581667e-1, 0.0)}, {FN (cos), ARG(-3.14124738660679181379e+00,0.0e+00), RES(-9.9999994039535581667e-1, 0.0)}, {FN (cos), ARG(3.14124738660679181379e+00,1.19209289550781250e-07), RES(-9.9999994039536292209e-1, -4.1159030931185115142e-11)}, {FN (cos), ARG(3.14124738660679181379e+00,-1.19209289550781250e-07), RES(-9.9999994039536292209e-1, 4.1159030931185115142e-11)}, {FN (cos), ARG(-3.14124738660679181379e+00,1.19209289550781250e-07), RES(-9.9999994039536292209e-1, 4.1159030931185115142e-11)}, {FN (cos), ARG(-3.14124738660679181379e+00,-1.19209289550781250e-07), RES(-9.9999994039536292209e-1, -4.1159030931185115142e-11)}, {FN (cos), ARG(3.14124738660679181379e+00,5.0e-01), RES(-1.1276258979946363572e0, -1.7991700040940218455e-4)}, {FN (cos), ARG(3.14124738660679181379e+00,-5.0e-01), RES(-1.1276258979946363572e0, 1.7991700040940218455e-4)}, {FN (cos), ARG(-3.14124738660679181379e+00,5.0e-01), RES(-1.1276258979946363572e0, 1.7991700040940218455e-4)}, {FN (cos), ARG(-3.14124738660679181379e+00,-5.0e-01), RES(-1.1276258979946363572e0, -1.7991700040940218455e-4)}, {FN (cos), ARG(3.14124738660679181379e+00,1.0e+00), RES(-1.5430805428404715941e0, -4.0575816248737789049e-4)}, {FN (cos), ARG(3.14124738660679181379e+00,-1.0e+00), RES(-1.5430805428404715941e0, 4.0575816248737789049e-4)}, {FN (cos), ARG(-3.14124738660679181379e+00,1.0e+00), RES(-1.5430805428404715941e0, 4.0575816248737789049e-4)}, {FN (cos), ARG(-3.14124738660679181379e+00,-1.0e+00), RES(-1.5430805428404715941e0, -4.0575816248737789049e-4)}, {FN (cos), ARG(3.14124738660679181379e+00,2.0e+00), RES(-3.7621954668392959444e0, -1.2522351259049798196e-3)}, {FN (cos), ARG(3.14124738660679181379e+00,-2.0e+00), RES(-3.7621954668392959444e0, 1.2522351259049798196e-3)}, {FN (cos), ARG(-3.14124738660679181379e+00,2.0e+00), RES(-3.7621954668392959444e0, 1.2522351259049798196e-3)}, {FN (cos), ARG(-3.14124738660679181379e+00,-2.0e+00), RES(-3.7621954668392959444e0, -1.2522351259049798196e-3)}, {FN (cos), ARG(3.14193792057279441821e+00,0.0e+00), RES(-9.9999994039535581675e-1, 0.0)}, {FN (cos), ARG(-3.14193792057279441821e+00,0.0e+00), RES(-9.9999994039535581675e-1, 0.0)}, {FN (cos), ARG(3.14193792057279441821e+00,1.19209289550781250e-07), RES(-9.9999994039536292218e-1, 4.1159030931155917289e-11)}, {FN (cos), ARG(3.14193792057279441821e+00,-1.19209289550781250e-07), RES(-9.9999994039536292218e-1, -4.1159030931155917289e-11)}, {FN (cos), ARG(-3.14193792057279441821e+00,1.19209289550781250e-07), RES(-9.9999994039536292218e-1, -4.1159030931155917289e-11)}, {FN (cos), ARG(-3.14193792057279441821e+00,-1.19209289550781250e-07), RES(-9.9999994039536292218e-1, 4.1159030931155917289e-11)}, {FN (cos), ARG(3.14193792057279441821e+00,5.0e-01), RES(-1.1276258979946363573e0, 1.7991700040927455302e-4)}, {FN (cos), ARG(3.14193792057279441821e+00,-5.0e-01), RES(-1.1276258979946363573e0, -1.7991700040927455302e-4)}, {FN (cos), ARG(-3.14193792057279441821e+00,5.0e-01), RES(-1.1276258979946363573e0, -1.7991700040927455302e-4)}, {FN (cos), ARG(-3.14193792057279441821e+00,-5.0e-01), RES(-1.1276258979946363573e0, 1.7991700040927455302e-4)}, {FN (cos), ARG(3.14193792057279441821e+00,1.0e+00), RES(-1.5430805428404715943e0, 4.0575816248709004923e-4)}, {FN (cos), ARG(3.14193792057279441821e+00,-1.0e+00), RES(-1.5430805428404715943e0, -4.0575816248709004923e-4)}, {FN (cos), ARG(-3.14193792057279441821e+00,1.0e+00), RES(-1.5430805428404715943e0, -4.0575816248709004923e-4)}, {FN (cos), ARG(-3.14193792057279441821e+00,-1.0e+00), RES(-1.5430805428404715943e0, 4.0575816248709004923e-4)}, {FN (cos), ARG(3.14193792057279441821e+00,2.0e+00), RES(-3.7621954668392959448e0, 1.2522351259040914950e-3)}, {FN (cos), ARG(3.14193792057279441821e+00,-2.0e+00), RES(-3.7621954668392959448e0, -1.2522351259040914950e-3)}, {FN (cos), ARG(-3.14193792057279441821e+00,2.0e+00), RES(-3.7621954668392959448e0, -1.2522351259040914950e-3)}, {FN (cos), ARG(-3.14193792057279441821e+00,-2.0e+00), RES(-3.7621954668392959448e0, 1.2522351259040914950e-3)}, {FN (cos), ARG(4.71204371340168837179e+00,0.0e+00), RES(-3.4526697614164732094e-4, 0.0)}, {FN (cos), ARG(-4.71204371340168837179e+00,0.0e+00), RES(-3.4526697614164732094e-4, 0.0)}, {FN (cos), ARG(4.71204371340168837179e+00,1.19209289550781250e-07), RES(-3.4526697614164977421e-4, 1.1920928244535424532e-7)}, {FN (cos), ARG(4.71204371340168837179e+00,-1.19209289550781250e-07), RES(-3.4526697614164977421e-4, -1.1920928244535424532e-7)}, {FN (cos), ARG(-4.71204371340168837179e+00,1.19209289550781250e-07), RES(-3.4526697614164977421e-4, -1.1920928244535424532e-7)}, {FN (cos), ARG(-4.71204371340168837179e+00,-1.19209289550781250e-07), RES(-3.4526697614164977421e-4, 1.1920928244535424532e-7)}, {FN (cos), ARG(4.71204371340168837179e+00,5.0e-01), RES(-3.8933200722561350661e-4, 5.2109527443404709205e-1)}, {FN (cos), ARG(4.71204371340168837179e+00,-5.0e-01), RES(-3.8933200722561350661e-4, -5.2109527443404709205e-1)}, {FN (cos), ARG(-4.71204371340168837179e+00,5.0e-01), RES(-3.8933200722561350661e-4, -5.2109527443404709205e-1)}, {FN (cos), ARG(-4.71204371340168837179e+00,-5.0e-01), RES(-3.8933200722561350661e-4, 5.2109527443404709205e-1)}, {FN (cos), ARG(4.71204371340168837179e+00,1.0e+00), RES(-5.3277478472539277601e-4, 1.1752011235963524659e0)}, {FN (cos), ARG(4.71204371340168837179e+00,-1.0e+00), RES(-5.3277478472539277601e-4, -1.1752011235963524659e0)}, {FN (cos), ARG(-4.71204371340168837179e+00,1.0e+00), RES(-5.3277478472539277601e-4, -1.1752011235963524659e0)}, {FN (cos), ARG(-4.71204371340168837179e+00,-1.0e+00), RES(-5.3277478472539277601e-4, 1.1752011235963524659e0)}, {FN (cos), ARG(4.71204371340168837179e+00,2.0e+00), RES(-1.2989619299135805376e-3, 3.6268601916692946552e0)}, {FN (cos), ARG(4.71204371340168837179e+00,-2.0e+00), RES(-1.2989619299135805376e-3, -3.6268601916692946552e0)}, {FN (cos), ARG(-4.71204371340168837179e+00,2.0e+00), RES(-1.2989619299135805376e-3, -3.6268601916692946552e0)}, {FN (cos), ARG(-4.71204371340168837179e+00,-2.0e+00), RES(-1.2989619299135805376e-3, 3.6268601916692946552e0)}, {FN (cos), ARG(4.71273424736769097620e+00,0.0e+00), RES(3.4526697614127992692e-4, 0.0)}, {FN (cos), ARG(-4.71273424736769097620e+00,0.0e+00), RES(3.4526697614127992692e-4, 0.0)}, {FN (cos), ARG(4.71273424736769097620e+00,1.19209289550781250e-07), RES(3.4526697614128238019e-4, 1.1920928244535424533e-7)}, {FN (cos), ARG(4.71273424736769097620e+00,-1.19209289550781250e-07), RES(3.4526697614128238019e-4, -1.1920928244535424533e-7)}, {FN (cos), ARG(-4.71273424736769097620e+00,1.19209289550781250e-07), RES(3.4526697614128238019e-4, -1.1920928244535424533e-7)}, {FN (cos), ARG(-4.71273424736769097620e+00,-1.19209289550781250e-07), RES(3.4526697614128238019e-4, 1.1920928244535424533e-7)}, {FN (cos), ARG(4.71273424736769097620e+00,5.0e-01), RES(3.8933200722519922358e-4, 5.2109527443404709212e-1)}, {FN (cos), ARG(4.71273424736769097620e+00,-5.0e-01), RES(3.8933200722519922358e-4, -5.2109527443404709212e-1)}, {FN (cos), ARG(-4.71273424736769097620e+00,5.0e-01), RES(3.8933200722519922358e-4, -5.2109527443404709212e-1)}, {FN (cos), ARG(-4.71273424736769097620e+00,-5.0e-01), RES(3.8933200722519922358e-4, 5.2109527443404709212e-1)}, {FN (cos), ARG(4.71273424736769097620e+00,1.0e+00), RES(5.3277478472482585742e-4, 1.1752011235963524660e0)}, {FN (cos), ARG(4.71273424736769097620e+00,-1.0e+00), RES(5.3277478472482585742e-4, -1.1752011235963524660e0)}, {FN (cos), ARG(-4.71273424736769097620e+00,1.0e+00), RES(5.3277478472482585742e-4, -1.1752011235963524660e0)}, {FN (cos), ARG(-4.71273424736769097620e+00,-1.0e+00), RES(5.3277478472482585742e-4, 1.1752011235963524660e0)}, {FN (cos), ARG(4.71273424736769097620e+00,2.0e+00), RES(1.2989619299121983294e-3, 3.6268601916692946557e0)}, {FN (cos), ARG(4.71273424736769097620e+00,-2.0e+00), RES(1.2989619299121983294e-3, -3.6268601916692946557e0)}, {FN (cos), ARG(-4.71273424736769097620e+00,2.0e+00), RES(1.2989619299121983294e-3, -3.6268601916692946557e0)}, {FN (cos), ARG(-4.71273424736769097620e+00,-2.0e+00), RES(1.2989619299121983294e-3, 3.6268601916692946557e0)}, {FN (cos), ARG(6.28284004019658492979e+00,0.0e+00), RES(9.9999994039535581662e-1, 0.0)}, {FN (cos), ARG(-6.28284004019658492979e+00,0.0e+00), RES(9.9999994039535581662e-1, 0.0)}, {FN (cos), ARG(6.28284004019658492979e+00,1.19209289550781250e-07), RES(9.9999994039536292205e-1, 4.1159030931199714069e-11)}, {FN (cos), ARG(6.28284004019658492979e+00,-1.19209289550781250e-07), RES(9.9999994039536292205e-1, -4.1159030931199714069e-11)}, {FN (cos), ARG(-6.28284004019658492979e+00,1.19209289550781250e-07), RES(9.9999994039536292205e-1, -4.1159030931199714069e-11)}, {FN (cos), ARG(-6.28284004019658492979e+00,-1.19209289550781250e-07), RES(9.9999994039536292205e-1, 4.1159030931199714069e-11)}, {FN (cos), ARG(6.28284004019658492979e+00,5.0e-01), RES(1.1276258979946363572e0, 1.7991700040946600032e-4)}, {FN (cos), ARG(6.28284004019658492979e+00,-5.0e-01), RES(1.1276258979946363572e0, -1.7991700040946600032e-4)}, {FN (cos), ARG(-6.28284004019658492979e+00,5.0e-01), RES(1.1276258979946363572e0, -1.7991700040946600032e-4)}, {FN (cos), ARG(-6.28284004019658492979e+00,-5.0e-01), RES(1.1276258979946363572e0, 1.7991700040946600032e-4)}, {FN (cos), ARG(6.28284004019658492979e+00,1.0e+00), RES(1.5430805428404715941e0, 4.0575816248752181112e-4)}, {FN (cos), ARG(6.28284004019658492979e+00,-1.0e+00), RES(1.5430805428404715941e0, -4.0575816248752181112e-4)}, {FN (cos), ARG(-6.28284004019658492979e+00,1.0e+00), RES(1.5430805428404715941e0, -4.0575816248752181112e-4)}, {FN (cos), ARG(-6.28284004019658492979e+00,-1.0e+00), RES(1.5430805428404715941e0, 4.0575816248752181112e-4)}, {FN (cos), ARG(6.28284004019658492979e+00,2.0e+00), RES(3.7621954668392959443e0, 1.2522351259054239819e-3)}, {FN (cos), ARG(6.28284004019658492979e+00,-2.0e+00), RES(3.7621954668392959443e0, -1.2522351259054239819e-3)}, {FN (cos), ARG(-6.28284004019658492979e+00,2.0e+00), RES(3.7621954668392959443e0, -1.2522351259054239819e-3)}, {FN (cos), ARG(-6.28284004019658492979e+00,-2.0e+00), RES(3.7621954668392959443e0, 1.2522351259054239819e-3)}, {FN (cos), ARG(6.28353057416258753420e+00,0.0e+00), RES(9.9999994039535581679e-1, 0.0)}, {FN (cos), ARG(-6.28353057416258753420e+00,0.0e+00), RES(9.9999994039535581679e-1, 0.0)}, {FN (cos), ARG(6.28353057416258753420e+00,1.19209289550781250e-07), RES(9.9999994039536292222e-1, -4.1159030931141318362e-11)}, {FN (cos), ARG(6.28353057416258753420e+00,-1.19209289550781250e-07), RES(9.9999994039536292222e-1, 4.1159030931141318362e-11)}, {FN (cos), ARG(-6.28353057416258753420e+00,1.19209289550781250e-07), RES(9.9999994039536292222e-1, 4.1159030931141318362e-11)}, {FN (cos), ARG(-6.28353057416258753420e+00,-1.19209289550781250e-07), RES(9.9999994039536292222e-1, -4.1159030931141318362e-11)}, {FN (cos), ARG(6.28353057416258753420e+00,5.0e-01), RES(1.1276258979946363574e0, -1.7991700040921073725e-4)}, {FN (cos), ARG(6.28353057416258753420e+00,-5.0e-01), RES(1.1276258979946363574e0, 1.7991700040921073725e-4)}, {FN (cos), ARG(-6.28353057416258753420e+00,5.0e-01), RES(1.1276258979946363574e0, 1.7991700040921073725e-4)}, {FN (cos), ARG(-6.28353057416258753420e+00,-5.0e-01), RES(1.1276258979946363574e0, -1.7991700040921073725e-4)}, {FN (cos), ARG(6.28353057416258753420e+00,1.0e+00), RES(1.5430805428404715943e0, -4.0575816248694612861e-4)}, {FN (cos), ARG(6.28353057416258753420e+00,-1.0e+00), RES(1.5430805428404715943e0, 4.0575816248694612861e-4)}, {FN (cos), ARG(-6.28353057416258753420e+00,1.0e+00), RES(1.5430805428404715943e0, 4.0575816248694612861e-4)}, {FN (cos), ARG(-6.28353057416258753420e+00,-1.0e+00), RES(1.5430805428404715943e0, -4.0575816248694612861e-4)}, {FN (cos), ARG(6.28353057416258753420e+00,2.0e+00), RES(3.7621954668392959449e0, -1.2522351259036473328e-3)}, {FN (cos), ARG(6.28353057416258753420e+00,-2.0e+00), RES(3.7621954668392959449e0, 1.2522351259036473328e-3)}, {FN (cos), ARG(-6.28353057416258753420e+00,2.0e+00), RES(3.7621954668392959449e0, 1.2522351259036473328e-3)}, {FN (cos), ARG(-6.28353057416258753420e+00,-2.0e+00), RES(3.7621954668392959449e0, -1.2522351259036473328e-3)}, {FN (cos), ARG(9.42443269378637893396e+00,0.0e+00), RES(-9.9999994039535581689e-1, 0.0)}, {FN (cos), ARG(-9.42443269378637893396e+00,0.0e+00), RES(-9.9999994039535581689e-1, 0.0)}, {FN (cos), ARG(9.42443269378637893396e+00,1.19209289550781250e-07), RES(-9.9999994039536292231e-1, -4.1159030931108433883e-11)}, {FN (cos), ARG(9.42443269378637893396e+00,-1.19209289550781250e-07), RES(-9.9999994039536292231e-1, 4.1159030931108433883e-11)}, {FN (cos), ARG(-9.42443269378637893396e+00,1.19209289550781250e-07), RES(-9.9999994039536292231e-1, 4.1159030931108433883e-11)}, {FN (cos), ARG(-9.42443269378637893396e+00,-1.19209289550781250e-07), RES(-9.9999994039536292231e-1, -4.1159030931108433883e-11)}, {FN (cos), ARG(9.42443269378637893396e+00,5.0e-01), RES(-1.1276258979946363575e0, -1.7991700040906699050e-4)}, {FN (cos), ARG(9.42443269378637893396e+00,-5.0e-01), RES(-1.1276258979946363575e0, 1.7991700040906699050e-4)}, {FN (cos), ARG(-9.42443269378637893396e+00,5.0e-01), RES(-1.1276258979946363575e0, 1.7991700040906699050e-4)}, {FN (cos), ARG(-9.42443269378637893396e+00,-5.0e-01), RES(-1.1276258979946363575e0, -1.7991700040906699050e-4)}, {FN (cos), ARG(9.42443269378637893396e+00,1.0e+00), RES(-1.5430805428404715945e0, -4.0575816248662194348e-4)}, {FN (cos), ARG(9.42443269378637893396e+00,-1.0e+00), RES(-1.5430805428404715945e0, 4.0575816248662194348e-4)}, {FN (cos), ARG(-9.42443269378637893396e+00,1.0e+00), RES(-1.5430805428404715945e0, 4.0575816248662194348e-4)}, {FN (cos), ARG(-9.42443269378637893396e+00,-1.0e+00), RES(-1.5430805428404715945e0, -4.0575816248662194348e-4)}, {FN (cos), ARG(9.42443269378637893396e+00,2.0e+00), RES(-3.7621954668392959453e0, -1.2522351259026468452e-3)}, {FN (cos), ARG(9.42443269378637893396e+00,-2.0e+00), RES(-3.7621954668392959453e0, 1.2522351259026468452e-3)}, {FN (cos), ARG(-9.42443269378637893396e+00,2.0e+00), RES(-3.7621954668392959453e0, 1.2522351259026468452e-3)}, {FN (cos), ARG(-9.42443269378637893396e+00,-2.0e+00), RES(-3.7621954668392959453e0, -1.2522351259026468452e-3)}, {FN (cos), ARG(9.42512322775237976202e+00,0.0e+00), RES(-9.9999994039535581714e-1, 0.0)}, {FN (cos), ARG(-9.42512322775237976202e+00,0.0e+00), RES(-9.9999994039535581714e-1, 0.0)}, {FN (cos), ARG(9.42512322775237976202e+00,1.19209289550781250e-07), RES(-9.9999994039536292257e-1, 4.1159030931020840323e-11)}, {FN (cos), ARG(9.42512322775237976202e+00,-1.19209289550781250e-07), RES(-9.9999994039536292257e-1, -4.1159030931020840323e-11)}, {FN (cos), ARG(-9.42512322775237976202e+00,1.19209289550781250e-07), RES(-9.9999994039536292257e-1, -4.1159030931020840323e-11)}, {FN (cos), ARG(-9.42512322775237976202e+00,-1.19209289550781250e-07), RES(-9.9999994039536292257e-1, 4.1159030931020840323e-11)}, {FN (cos), ARG(9.42512322775237976202e+00,5.0e-01), RES(-1.1276258979946363577e0, 1.7991700040868409591e-4)}, {FN (cos), ARG(9.42512322775237976202e+00,-5.0e-01), RES(-1.1276258979946363577e0, -1.7991700040868409591e-4)}, {FN (cos), ARG(-9.42512322775237976202e+00,5.0e-01), RES(-1.1276258979946363577e0, -1.7991700040868409591e-4)}, {FN (cos), ARG(-9.42512322775237976202e+00,-5.0e-01), RES(-1.1276258979946363577e0, 1.7991700040868409591e-4)}, {FN (cos), ARG(9.42512322775237976202e+00,1.0e+00), RES(-1.5430805428404715949e0, 4.0575816248575841970e-4)}, {FN (cos), ARG(9.42512322775237976202e+00,-1.0e+00), RES(-1.5430805428404715949e0, -4.0575816248575841970e-4)}, {FN (cos), ARG(-9.42512322775237976202e+00,1.0e+00), RES(-1.5430805428404715949e0, -4.0575816248575841970e-4)}, {FN (cos), ARG(-9.42512322775237976202e+00,-1.0e+00), RES(-1.5430805428404715949e0, 4.0575816248575841970e-4)}, {FN (cos), ARG(9.42512322775237976202e+00,2.0e+00), RES(-3.7621954668392959462e0, 1.2522351258999818715e-3)}, {FN (cos), ARG(9.42512322775237976202e+00,-2.0e+00), RES(-3.7621954668392959462e0, -1.2522351258999818715e-3)}, {FN (cos), ARG(-9.42512322775237976202e+00,2.0e+00), RES(-3.7621954668392959462e0, -1.2522351258999818715e-3)}, {FN (cos), ARG(-9.42512322775237976202e+00,-2.0e+00), RES(-3.7621954668392959462e0, 1.2522351258999818715e-3)}, {FN (tan), ARG(-3.45266983001243932001e-04,0.0e+00), RES(-3.4526699672092183585e-4, 0.0)}, {FN (tan), ARG(3.45266983001243932001e-04,0.0e+00), RES(3.4526699672092183585e-4, 0.0)}, {FN (tan), ARG(-3.45266983001243932001e-04,1.19209289550781250e-07), RES(-3.4526699672091692931e-4, 1.1920930376163652989e-7)}, {FN (tan), ARG(-3.45266983001243932001e-04,-1.19209289550781250e-07), RES(-3.4526699672091692931e-4, -1.1920930376163652989e-7)}, {FN (tan), ARG(3.45266983001243932001e-04,1.19209289550781250e-07), RES(3.4526699672091692931e-4, 1.1920930376163652989e-7)}, {FN (tan), ARG(3.45266983001243932001e-04,-1.19209289550781250e-07), RES(3.4526699672091692931e-4, -1.1920930376163652989e-7)}, {FN (tan), ARG(-3.45266983001243932001e-04,5.0e-01), RES(-2.7153443992655805934e-4, 4.6211720058436229979e-1)}, {FN (tan), ARG(-3.45266983001243932001e-04,-5.0e-01), RES(-2.7153443992655805934e-4, -4.6211720058436229979e-1)}, {FN (tan), ARG(3.45266983001243932001e-04,5.0e-01), RES(2.7153443992655805934e-4, 4.6211720058436229979e-1)}, {FN (tan), ARG(3.45266983001243932001e-04,-5.0e-01), RES(2.7153443992655805934e-4, -4.6211720058436229979e-1)}, {FN (tan), ARG(-3.45266983001243932001e-04,1.0e+00), RES(-1.4500326960274960880e-4, 7.6159419408485704836e-1)}, {FN (tan), ARG(-3.45266983001243932001e-04,-1.0e+00), RES(-1.4500326960274960880e-4, -7.6159419408485704836e-1)}, {FN (tan), ARG(3.45266983001243932001e-04,1.0e+00), RES(1.4500326960274960880e-4, 7.6159419408485704836e-1)}, {FN (tan), ARG(3.45266983001243932001e-04,-1.0e+00), RES(1.4500326960274960880e-4, -7.6159419408485704836e-1)}, {FN (tan), ARG(-3.45266983001243932001e-04,2.0e+00), RES(-2.4393395410435306874e-5, 9.6402758819508310556e-1)}, {FN (tan), ARG(-3.45266983001243932001e-04,-2.0e+00), RES(-2.4393395410435306874e-5, -9.6402758819508310556e-1)}, {FN (tan), ARG(3.45266983001243932001e-04,2.0e+00), RES(2.4393395410435306874e-5, 9.6402758819508310556e-1)}, {FN (tan), ARG(3.45266983001243932001e-04,-2.0e+00), RES(2.4393395410435306874e-5, -9.6402758819508310556e-1)}, {FN (tan), ARG(1.57045105981189525579e+00,0.0e+00), RES(2.8963092606501007060e3, 0.0)}, {FN (tan), ARG(-1.57045105981189525579e+00,0.0e+00), RES(-2.8963092606501007060e3, 0.0)}, {FN (tan), ARG(1.57045105981189525579e+00,1.19209289550781250e-07), RES(2.8963089153831588642e3, 9.9999992052646305569e-1)}, {FN (tan), ARG(1.57045105981189525579e+00,-1.19209289550781250e-07), RES(2.8963089153831588642e3, -9.9999992052646305569e-1)}, {FN (tan), ARG(-1.57045105981189525579e+00,1.19209289550781250e-07), RES(-2.8963089153831588642e3, 9.9999992052646305569e-1)}, {FN (tan), ARG(-1.57045105981189525579e+00,-1.19209289550781250e-07), RES(-2.8963089153831588642e3, -9.9999992052646305569e-1)}, {FN (tan), ARG(1.57045105981189525579e+00,5.0e-01), RES(1.2715121175455623363e-3, 2.1639524637389325996e0)}, {FN (tan), ARG(1.57045105981189525579e+00,-5.0e-01), RES(1.2715121175455623363e-3, -2.1639524637389325996e0)}, {FN (tan), ARG(-1.57045105981189525579e+00,5.0e-01), RES(-1.2715121175455623363e-3, 2.1639524637389325996e0)}, {FN (tan), ARG(-1.57045105981189525579e+00,-5.0e-01), RES(-1.2715121175455623363e-3, -2.1639524637389325996e0)}, {FN (tan), ARG(1.57045105981189525579e+00,1.0e+00), RES(2.4999454374276273814e-4, 1.3130351721648674823e0)}, {FN (tan), ARG(1.57045105981189525579e+00,-1.0e+00), RES(2.4999454374276273814e-4, -1.3130351721648674823e0)}, {FN (tan), ARG(-1.57045105981189525579e+00,1.0e+00), RES(-2.4999454374276273814e-4, 1.3130351721648674823e0)}, {FN (tan), ARG(-1.57045105981189525579e+00,-1.0e+00), RES(-2.4999454374276273814e-4, -1.3130351721648674823e0)}, {FN (tan), ARG(1.57045105981189525579e+00,2.0e+00), RES(2.6247825506572821595e-5, 1.0373147113268752620e0)}, {FN (tan), ARG(1.57045105981189525579e+00,-2.0e+00), RES(2.6247825506572821595e-5, -1.0373147113268752620e0)}, {FN (tan), ARG(-1.57045105981189525579e+00,2.0e+00), RES(-2.6247825506572821595e-5, 1.0373147113268752620e0)}, {FN (tan), ARG(-1.57045105981189525579e+00,-2.0e+00), RES(-2.6247825506572821595e-5, -1.0373147113268752620e0)}, {FN (tan), ARG(1.57114159377789786021e+00,0.0e+00), RES(-2.8963092606511280143e3, 0.0)}, {FN (tan), ARG(-1.57114159377789786021e+00,0.0e+00), RES(2.8963092606511280143e3, 0.0)}, {FN (tan), ARG(1.57114159377789786021e+00,1.19209289550781250e-07), RES(-2.8963089153841861720e3, 9.9999992052717244672e-1)}, {FN (tan), ARG(1.57114159377789786021e+00,-1.19209289550781250e-07), RES(-2.8963089153841861720e3, -9.9999992052717244672e-1)}, {FN (tan), ARG(-1.57114159377789786021e+00,1.19209289550781250e-07), RES(2.8963089153841861720e3, 9.9999992052717244672e-1)}, {FN (tan), ARG(-1.57114159377789786021e+00,-1.19209289550781250e-07), RES(2.8963089153841861720e3, -9.9999992052717244672e-1)}, {FN (tan), ARG(1.57114159377789786021e+00,5.0e-01), RES(-1.2715121175451113370e-3, 2.1639524637389326002e0)}, {FN (tan), ARG(1.57114159377789786021e+00,-5.0e-01), RES(-1.2715121175451113370e-3, -2.1639524637389326002e0)}, {FN (tan), ARG(-1.57114159377789786021e+00,5.0e-01), RES(1.2715121175451113370e-3, 2.1639524637389326002e0)}, {FN (tan), ARG(-1.57114159377789786021e+00,-5.0e-01), RES(1.2715121175451113370e-3, -2.1639524637389326002e0)}, {FN (tan), ARG(1.57114159377789786021e+00,1.0e+00), RES(-2.4999454374267406620e-4, 1.3130351721648674824e0)}, {FN (tan), ARG(1.57114159377789786021e+00,-1.0e+00), RES(-2.4999454374267406620e-4, -1.3130351721648674824e0)}, {FN (tan), ARG(-1.57114159377789786021e+00,1.0e+00), RES(2.4999454374267406620e-4, 1.3130351721648674824e0)}, {FN (tan), ARG(-1.57114159377789786021e+00,-1.0e+00), RES(2.4999454374267406620e-4, -1.3130351721648674824e0)}, {FN (tan), ARG(1.57114159377789786021e+00,2.0e+00), RES(-2.6247825506563511609e-5, 1.0373147113268752620e0)}, {FN (tan), ARG(1.57114159377789786021e+00,-2.0e+00), RES(-2.6247825506563511609e-5, -1.0373147113268752620e0)}, {FN (tan), ARG(-1.57114159377789786021e+00,2.0e+00), RES(2.6247825506563511609e-5, 1.0373147113268752620e0)}, {FN (tan), ARG(-1.57114159377789786021e+00,-2.0e+00), RES(2.6247825506563511609e-5, -1.0373147113268752620e0)}, {FN (tan), ARG(3.14124738660679181379e+00,0.0e+00), RES(-3.4526699672110257641e-4, 0.0)}, {FN (tan), ARG(-3.14124738660679181379e+00,0.0e+00), RES(3.4526699672110257641e-4, 0.0)}, {FN (tan), ARG(3.14124738660679181379e+00,1.19209289550781250e-07), RES(-3.4526699672109766987e-4, 1.1920930376163652991e-7)}, {FN (tan), ARG(3.14124738660679181379e+00,-1.19209289550781250e-07), RES(-3.4526699672109766987e-4, -1.1920930376163652991e-7)}, {FN (tan), ARG(-3.14124738660679181379e+00,1.19209289550781250e-07), RES(3.4526699672109766987e-4, 1.1920930376163652991e-7)}, {FN (tan), ARG(-3.14124738660679181379e+00,-1.19209289550781250e-07), RES(3.4526699672109766987e-4, -1.1920930376163652991e-7)}, {FN (tan), ARG(3.14124738660679181379e+00,5.0e-01), RES(-2.7153443992670020234e-4, 4.6211720058436229984e-1)}, {FN (tan), ARG(3.14124738660679181379e+00,-5.0e-01), RES(-2.7153443992670020234e-4, -4.6211720058436229984e-1)}, {FN (tan), ARG(-3.14124738660679181379e+00,5.0e-01), RES(2.7153443992670020234e-4, 4.6211720058436229984e-1)}, {FN (tan), ARG(-3.14124738660679181379e+00,-5.0e-01), RES(2.7153443992670020234e-4, -4.6211720058436229984e-1)}, {FN (tan), ARG(3.14124738660679181379e+00,1.0e+00), RES(-1.4500326960282551519e-4, 7.6159419408485704840e-1)}, {FN (tan), ARG(3.14124738660679181379e+00,-1.0e+00), RES(-1.4500326960282551519e-4, -7.6159419408485704840e-1)}, {FN (tan), ARG(-3.14124738660679181379e+00,1.0e+00), RES(1.4500326960282551519e-4, 7.6159419408485704840e-1)}, {FN (tan), ARG(-3.14124738660679181379e+00,-1.0e+00), RES(1.4500326960282551519e-4, -7.6159419408485704840e-1)}, {FN (tan), ARG(3.14124738660679181379e+00,2.0e+00), RES(-2.4393395410448076340e-5, 9.6402758819508310557e-1)}, {FN (tan), ARG(3.14124738660679181379e+00,-2.0e+00), RES(-2.4393395410448076340e-5, -9.6402758819508310557e-1)}, {FN (tan), ARG(-3.14124738660679181379e+00,2.0e+00), RES(2.4393395410448076340e-5, 9.6402758819508310557e-1)}, {FN (tan), ARG(-3.14124738660679181379e+00,-2.0e+00), RES(2.4393395410448076340e-5, -9.6402758819508310557e-1)}, {FN (tan), ARG(3.14193792057279441821e+00,0.0e+00), RES(3.4526699672085764703e-4, 0.0)}, {FN (tan), ARG(-3.14193792057279441821e+00,0.0e+00), RES(-3.4526699672085764703e-4, 0.0)}, {FN (tan), ARG(3.14193792057279441821e+00,1.19209289550781250e-07), RES(3.4526699672085274049e-4, 1.1920930376163652989e-7)}, {FN (tan), ARG(3.14193792057279441821e+00,-1.19209289550781250e-07), RES(3.4526699672085274049e-4, -1.1920930376163652989e-7)}, {FN (tan), ARG(-3.14193792057279441821e+00,1.19209289550781250e-07), RES(-3.4526699672085274049e-4, 1.1920930376163652989e-7)}, {FN (tan), ARG(-3.14193792057279441821e+00,-1.19209289550781250e-07), RES(-3.4526699672085274049e-4, -1.1920930376163652989e-7)}, {FN (tan), ARG(3.14193792057279441821e+00,5.0e-01), RES(2.7153443992650757820e-4, 4.6211720058436229978e-1)}, {FN (tan), ARG(3.14193792057279441821e+00,-5.0e-01), RES(2.7153443992650757820e-4, -4.6211720058436229978e-1)}, {FN (tan), ARG(-3.14193792057279441821e+00,5.0e-01), RES(-2.7153443992650757820e-4, 4.6211720058436229978e-1)}, {FN (tan), ARG(-3.14193792057279441821e+00,-5.0e-01), RES(-2.7153443992650757820e-4, -4.6211720058436229978e-1)}, {FN (tan), ARG(3.14193792057279441821e+00,1.0e+00), RES(1.4500326960272265115e-4, 7.6159419408485704835e-1)}, {FN (tan), ARG(3.14193792057279441821e+00,-1.0e+00), RES(1.4500326960272265115e-4, -7.6159419408485704835e-1)}, {FN (tan), ARG(-3.14193792057279441821e+00,1.0e+00), RES(-1.4500326960272265115e-4, 7.6159419408485704835e-1)}, {FN (tan), ARG(-3.14193792057279441821e+00,-1.0e+00), RES(-1.4500326960272265115e-4, -7.6159419408485704835e-1)}, {FN (tan), ARG(3.14193792057279441821e+00,2.0e+00), RES(2.4393395410430771882e-5, 9.6402758819508310556e-1)}, {FN (tan), ARG(3.14193792057279441821e+00,-2.0e+00), RES(2.4393395410430771882e-5, -9.6402758819508310556e-1)}, {FN (tan), ARG(-3.14193792057279441821e+00,2.0e+00), RES(-2.4393395410430771882e-5, 9.6402758819508310556e-1)}, {FN (tan), ARG(-3.14193792057279441821e+00,-2.0e+00), RES(-2.4393395410430771882e-5, -9.6402758819508310556e-1)}, {FN (tan), ARG(4.71204371340168837179e+00,0.0e+00), RES(2.8963092606490733978e3, 0.0)}, {FN (tan), ARG(-4.71204371340168837179e+00,0.0e+00), RES(-2.8963092606490733978e3, 0.0)}, {FN (tan), ARG(4.71204371340168837179e+00,1.19209289550781250e-07), RES(2.8963089153821315563e3, 9.9999992052575366466e-1)}, {FN (tan), ARG(4.71204371340168837179e+00,-1.19209289550781250e-07), RES(2.8963089153821315563e3, -9.9999992052575366466e-1)}, {FN (tan), ARG(-4.71204371340168837179e+00,1.19209289550781250e-07), RES(-2.8963089153821315563e3, 9.9999992052575366466e-1)}, {FN (tan), ARG(-4.71204371340168837179e+00,-1.19209289550781250e-07), RES(-2.8963089153821315563e3, -9.9999992052575366466e-1)}, {FN (tan), ARG(4.71204371340168837179e+00,5.0e-01), RES(1.2715121175460133355e-3, 2.1639524637389325989e0)}, {FN (tan), ARG(4.71204371340168837179e+00,-5.0e-01), RES(1.2715121175460133355e-3, -2.1639524637389325989e0)}, {FN (tan), ARG(-4.71204371340168837179e+00,5.0e-01), RES(-1.2715121175460133355e-3, 2.1639524637389325989e0)}, {FN (tan), ARG(-4.71204371340168837179e+00,-5.0e-01), RES(-1.2715121175460133355e-3, -2.1639524637389325989e0)}, {FN (tan), ARG(4.71204371340168837179e+00,1.0e+00), RES(2.4999454374285141007e-4, 1.3130351721648674822e0)}, {FN (tan), ARG(4.71204371340168837179e+00,-1.0e+00), RES(2.4999454374285141007e-4, -1.3130351721648674822e0)}, {FN (tan), ARG(-4.71204371340168837179e+00,1.0e+00), RES(-2.4999454374285141007e-4, 1.3130351721648674822e0)}, {FN (tan), ARG(-4.71204371340168837179e+00,-1.0e+00), RES(-2.4999454374285141007e-4, -1.3130351721648674822e0)}, {FN (tan), ARG(4.71204371340168837179e+00,2.0e+00), RES(2.6247825506582131582e-5, 1.0373147113268752620e0)}, {FN (tan), ARG(4.71204371340168837179e+00,-2.0e+00), RES(2.6247825506582131582e-5, -1.0373147113268752620e0)}, {FN (tan), ARG(-4.71204371340168837179e+00,2.0e+00), RES(-2.6247825506582131582e-5, 1.0373147113268752620e0)}, {FN (tan), ARG(-4.71204371340168837179e+00,-2.0e+00), RES(-2.6247825506582131582e-5, -1.0373147113268752620e0)}, {FN (tan), ARG(4.71273424736769097620e+00,0.0e+00), RES(-2.8963092606521553225e3, 0.0)}, {FN (tan), ARG(-4.71273424736769097620e+00,0.0e+00), RES(2.8963092606521553225e3, 0.0)}, {FN (tan), ARG(4.71273424736769097620e+00,1.19209289550781250e-07), RES(-2.8963089153852134799e3, 9.9999992052788183776e-1)}, {FN (tan), ARG(4.71273424736769097620e+00,-1.19209289550781250e-07), RES(-2.8963089153852134799e3, -9.9999992052788183776e-1)}, {FN (tan), ARG(-4.71273424736769097620e+00,1.19209289550781250e-07), RES(2.8963089153852134799e3, 9.9999992052788183776e-1)}, {FN (tan), ARG(-4.71273424736769097620e+00,-1.19209289550781250e-07), RES(2.8963089153852134799e3, -9.9999992052788183776e-1)}, {FN (tan), ARG(4.71273424736769097620e+00,5.0e-01), RES(-1.2715121175446603377e-3, 2.1639524637389326009e0)}, {FN (tan), ARG(4.71273424736769097620e+00,-5.0e-01), RES(-1.2715121175446603377e-3, -2.1639524637389326009e0)}, {FN (tan), ARG(-4.71273424736769097620e+00,5.0e-01), RES(1.2715121175446603377e-3, 2.1639524637389326009e0)}, {FN (tan), ARG(-4.71273424736769097620e+00,-5.0e-01), RES(1.2715121175446603377e-3, -2.1639524637389326009e0)}, {FN (tan), ARG(4.71273424736769097620e+00,1.0e+00), RES(-2.4999454374258539427e-4, 1.3130351721648674825e0)}, {FN (tan), ARG(4.71273424736769097620e+00,-1.0e+00), RES(-2.4999454374258539427e-4, -1.3130351721648674825e0)}, {FN (tan), ARG(-4.71273424736769097620e+00,1.0e+00), RES(2.4999454374258539427e-4, 1.3130351721648674825e0)}, {FN (tan), ARG(-4.71273424736769097620e+00,-1.0e+00), RES(2.4999454374258539427e-4, -1.3130351721648674825e0)}, {FN (tan), ARG(4.71273424736769097620e+00,2.0e+00), RES(-2.6247825506554201622e-5, 1.0373147113268752620e0)}, {FN (tan), ARG(4.71273424736769097620e+00,-2.0e+00), RES(-2.6247825506554201622e-5, -1.0373147113268752620e0)}, {FN (tan), ARG(-4.71273424736769097620e+00,2.0e+00), RES(2.6247825506554201622e-5, 1.0373147113268752620e0)}, {FN (tan), ARG(-4.71273424736769097620e+00,-2.0e+00), RES(2.6247825506554201622e-5, -1.0373147113268752620e0)}, {FN (tan), ARG(6.28284004019658492979e+00,0.0e+00), RES(-3.4526699672122504111e-4, 0.0)}, {FN (tan), ARG(-6.28284004019658492979e+00,0.0e+00), RES(3.4526699672122504111e-4, 0.0)}, {FN (tan), ARG(6.28284004019658492979e+00,1.19209289550781250e-07), RES(-3.4526699672122013457e-4, 1.1920930376163652992e-7)}, {FN (tan), ARG(6.28284004019658492979e+00,-1.19209289550781250e-07), RES(-3.4526699672122013457e-4, -1.1920930376163652992e-7)}, {FN (tan), ARG(-6.28284004019658492979e+00,1.19209289550781250e-07), RES(3.4526699672122013457e-4, 1.1920930376163652992e-7)}, {FN (tan), ARG(-6.28284004019658492979e+00,-1.19209289550781250e-07), RES(3.4526699672122013457e-4, -1.1920930376163652992e-7)}, {FN (tan), ARG(6.28284004019658492979e+00,5.0e-01), RES(-2.7153443992679651442e-4, 4.6211720058436229987e-1)}, {FN (tan), ARG(6.28284004019658492979e+00,-5.0e-01), RES(-2.7153443992679651442e-4, -4.6211720058436229987e-1)}, {FN (tan), ARG(-6.28284004019658492979e+00,5.0e-01), RES(2.7153443992679651442e-4, 4.6211720058436229987e-1)}, {FN (tan), ARG(-6.28284004019658492979e+00,-5.0e-01), RES(2.7153443992679651442e-4, -4.6211720058436229987e-1)}, {FN (tan), ARG(6.28284004019658492979e+00,1.0e+00), RES(-1.4500326960287694721e-4, 7.6159419408485704843e-1)}, {FN (tan), ARG(6.28284004019658492979e+00,-1.0e+00), RES(-1.4500326960287694721e-4, -7.6159419408485704843e-1)}, {FN (tan), ARG(-6.28284004019658492979e+00,1.0e+00), RES(1.4500326960287694721e-4, 7.6159419408485704843e-1)}, {FN (tan), ARG(-6.28284004019658492979e+00,-1.0e+00), RES(1.4500326960287694721e-4, -7.6159419408485704843e-1)}, {FN (tan), ARG(6.28284004019658492979e+00,2.0e+00), RES(-2.4393395410456728569e-5, 9.6402758819508310558e-1)}, {FN (tan), ARG(6.28284004019658492979e+00,-2.0e+00), RES(-2.4393395410456728569e-5, -9.6402758819508310558e-1)}, {FN (tan), ARG(-6.28284004019658492979e+00,2.0e+00), RES(2.4393395410456728569e-5, 9.6402758819508310558e-1)}, {FN (tan), ARG(-6.28284004019658492979e+00,-2.0e+00), RES(2.4393395410456728569e-5, -9.6402758819508310558e-1)}, {FN (tan), ARG(6.28353057416258753420e+00,0.0e+00), RES(3.4526699672073518233e-4, 0.0)}, {FN (tan), ARG(-6.28353057416258753420e+00,0.0e+00), RES(-3.4526699672073518233e-4, 0.0)}, {FN (tan), ARG(6.28353057416258753420e+00,1.19209289550781250e-07), RES(3.4526699672073027579e-4, 1.1920930376163652988e-7)}, {FN (tan), ARG(6.28353057416258753420e+00,-1.19209289550781250e-07), RES(3.4526699672073027579e-4, -1.1920930376163652988e-7)}, {FN (tan), ARG(-6.28353057416258753420e+00,1.19209289550781250e-07), RES(-3.4526699672073027579e-4, 1.1920930376163652988e-7)}, {FN (tan), ARG(-6.28353057416258753420e+00,-1.19209289550781250e-07), RES(-3.4526699672073027579e-4, -1.1920930376163652988e-7)}, {FN (tan), ARG(6.28353057416258753420e+00,5.0e-01), RES(2.7153443992641126612e-4, 4.6211720058436229974e-1)}, {FN (tan), ARG(6.28353057416258753420e+00,-5.0e-01), RES(2.7153443992641126612e-4, -4.6211720058436229974e-1)}, {FN (tan), ARG(-6.28353057416258753420e+00,5.0e-01), RES(-2.7153443992641126612e-4, 4.6211720058436229974e-1)}, {FN (tan), ARG(-6.28353057416258753420e+00,-5.0e-01), RES(-2.7153443992641126612e-4, -4.6211720058436229974e-1)}, {FN (tan), ARG(6.28353057416258753420e+00,1.0e+00), RES(1.4500326960267121913e-4, 7.6159419408485704832e-1)}, {FN (tan), ARG(6.28353057416258753420e+00,-1.0e+00), RES(1.4500326960267121913e-4, -7.6159419408485704832e-1)}, {FN (tan), ARG(-6.28353057416258753420e+00,1.0e+00), RES(-1.4500326960267121913e-4, 7.6159419408485704832e-1)}, {FN (tan), ARG(-6.28353057416258753420e+00,-1.0e+00), RES(-1.4500326960267121913e-4, -7.6159419408485704832e-1)}, {FN (tan), ARG(6.28353057416258753420e+00,2.0e+00), RES(2.4393395410422119654e-5, 9.6402758819508310555e-1)}, {FN (tan), ARG(6.28353057416258753420e+00,-2.0e+00), RES(2.4393395410422119654e-5, -9.6402758819508310555e-1)}, {FN (tan), ARG(-6.28353057416258753420e+00,2.0e+00), RES(-2.4393395410422119654e-5, 9.6402758819508310555e-1)}, {FN (tan), ARG(-6.28353057416258753420e+00,-2.0e+00), RES(-2.4393395410422119654e-5, -9.6402758819508310555e-1)}, {FN (tan), ARG(9.42443269378637893396e+00,0.0e+00), RES(-3.4526699672045932728e-4, 0.0)}, {FN (tan), ARG(-9.42443269378637893396e+00,0.0e+00), RES(3.4526699672045932728e-4, 0.0)}, {FN (tan), ARG(9.42443269378637893396e+00,1.19209289550781250e-07), RES(-3.4526699672045442074e-4, 1.1920930376163652985e-7)}, {FN (tan), ARG(9.42443269378637893396e+00,-1.19209289550781250e-07), RES(-3.4526699672045442074e-4, -1.1920930376163652985e-7)}, {FN (tan), ARG(-9.42443269378637893396e+00,1.19209289550781250e-07), RES(3.4526699672045442074e-4, 1.1920930376163652985e-7)}, {FN (tan), ARG(-9.42443269378637893396e+00,-1.19209289550781250e-07), RES(3.4526699672045442074e-4, -1.1920930376163652985e-7)}, {FN (tan), ARG(9.42443269378637893396e+00,5.0e-01), RES(-2.7153443992619432056e-4, 4.6211720058436229968e-1)}, {FN (tan), ARG(9.42443269378637893396e+00,-5.0e-01), RES(-2.7153443992619432056e-4, -4.6211720058436229968e-1)}, {FN (tan), ARG(-9.42443269378637893396e+00,5.0e-01), RES(2.7153443992619432056e-4, 4.6211720058436229968e-1)}, {FN (tan), ARG(-9.42443269378637893396e+00,-5.0e-01), RES(2.7153443992619432056e-4, -4.6211720058436229968e-1)}, {FN (tan), ARG(9.42443269378637893396e+00,1.0e+00), RES(-1.4500326960255536711e-4, 7.6159419408485704826e-1)}, {FN (tan), ARG(9.42443269378637893396e+00,-1.0e+00), RES(-1.4500326960255536711e-4, -7.6159419408485704826e-1)}, {FN (tan), ARG(-9.42443269378637893396e+00,1.0e+00), RES(1.4500326960255536711e-4, 7.6159419408485704826e-1)}, {FN (tan), ARG(-9.42443269378637893396e+00,-1.0e+00), RES(1.4500326960255536711e-4, -7.6159419408485704826e-1)}, {FN (tan), ARG(9.42443269378637893396e+00,2.0e+00), RES(-2.4393395410402630273e-5, 9.6402758819508310554e-1)}, {FN (tan), ARG(9.42443269378637893396e+00,-2.0e+00), RES(-2.4393395410402630273e-5, -9.6402758819508310554e-1)}, {FN (tan), ARG(-9.42443269378637893396e+00,2.0e+00), RES(2.4393395410402630273e-5, 9.6402758819508310554e-1)}, {FN (tan), ARG(-9.42443269378637893396e+00,-2.0e+00), RES(2.4393395410402630273e-5, -9.6402758819508310554e-1)}, {FN (tan), ARG(9.42512322775237976202e+00,0.0e+00), RES(3.4526699671972453911e-4, 0.0)}, {FN (tan), ARG(-9.42512322775237976202e+00,0.0e+00), RES(-3.4526699671972453911e-4, 0.0)}, {FN (tan), ARG(9.42512322775237976202e+00,1.19209289550781250e-07), RES(3.4526699671971963257e-4, 1.1920930376163652979e-7)}, {FN (tan), ARG(9.42512322775237976202e+00,-1.19209289550781250e-07), RES(3.4526699671971963257e-4, -1.1920930376163652979e-7)}, {FN (tan), ARG(-9.42512322775237976202e+00,1.19209289550781250e-07), RES(-3.4526699671971963257e-4, 1.1920930376163652979e-7)}, {FN (tan), ARG(-9.42512322775237976202e+00,-1.19209289550781250e-07), RES(-3.4526699671971963257e-4, -1.1920930376163652979e-7)}, {FN (tan), ARG(9.42512322775237976202e+00,5.0e-01), RES(2.7153443992561644811e-4, 4.6211720058436229949e-1)}, {FN (tan), ARG(9.42512322775237976202e+00,-5.0e-01), RES(2.7153443992561644811e-4, -4.6211720058436229949e-1)}, {FN (tan), ARG(-9.42512322775237976202e+00,5.0e-01), RES(-2.7153443992561644811e-4, 4.6211720058436229949e-1)}, {FN (tan), ARG(-9.42512322775237976202e+00,-5.0e-01), RES(-2.7153443992561644811e-4, -4.6211720058436229949e-1)}, {FN (tan), ARG(9.42512322775237976202e+00,1.0e+00), RES(1.450032696022467750e-4, 7.6159419408485704810e-1)}, {FN (tan), ARG(9.42512322775237976202e+00,-1.0e+00), RES(1.450032696022467750e-4, -7.6159419408485704810e-1)}, {FN (tan), ARG(-9.42512322775237976202e+00,1.0e+00), RES(-1.450032696022467750e-4, 7.6159419408485704810e-1)}, {FN (tan), ARG(-9.42512322775237976202e+00,-1.0e+00), RES(-1.450032696022467750e-4, -7.6159419408485704810e-1)}, {FN (tan), ARG(9.42512322775237976202e+00,2.0e+00), RES(2.439339541035071690e-5, 9.6402758819508310550e-1)}, {FN (tan), ARG(9.42512322775237976202e+00,-2.0e+00), RES(2.439339541035071690e-5, -9.6402758819508310550e-1)}, {FN (tan), ARG(-9.42512322775237976202e+00,2.0e+00), RES(-2.439339541035071690e-5, 9.6402758819508310550e-1)}, {FN (tan), ARG(-9.42512322775237976202e+00,-2.0e+00), RES(-2.439339541035071690e-5, -9.6402758819508310550e-1)}, {FN (arcsin), ARG(0.0e+00,0.0e+00), RES(0e0, 0.0)}, {FN (arcsin), ARG(0.0e+00,1.19209289550781250e-07), RES(0, 1.1920928955078096766e-7)}, {FN (arcsin), ARG(0.0e+00,-1.19209289550781250e-07), RES(0, -1.1920928955078096766e-7)}, {FN (arcsin), ARG(0.0e+00,5.0e-01), RES(0, 4.8121182505960344750e-1)}, {FN (arcsin), ARG(0.0e+00,-5.0e-01), RES(0, -4.8121182505960344750e-1)}, {FN (arcsin), ARG(0.0e+00,1.0e+00), RES(0, 8.8137358701954302523e-1)}, {FN (arcsin), ARG(0.0e+00,-1.0e+00), RES(0, -8.8137358701954302523e-1)}, {FN (arcsin), ARG(0.0e+00,2.0e+00), RES(0, 1.4436354751788103425e0)}, {FN (arcsin), ARG(0.0e+00,-2.0e+00), RES(0, -1.4436354751788103425e0)}, {FN (arcsin), ARG(0.0e+00,8.3886080e+06), RES(0, 1.6635532333438690979e1)}, {FN (arcsin), ARG(0.0e+00,-8.3886080e+06), RES(0, -1.6635532333438690979e1)}, {FN (arcsin), ARG(1.19209289550781250e-07,0.0e+00), RES(1.1920928955078153234e-7, 0.0)}, {FN (arcsin), ARG(-1.19209289550781250e-07,0.0e+00), RES(-1.1920928955078153234e-7, 0.0)}, {FN (arcsin), ARG(1.19209289550781250e-07,1.19209289550781250e-07), RES(1.1920928955078068531e-7, 1.1920928955078181469e-7)}, {FN (arcsin), ARG(1.19209289550781250e-07,-1.19209289550781250e-07), RES(1.1920928955078068531e-7, -1.1920928955078181469e-7)}, {FN (arcsin), ARG(-1.19209289550781250e-07,1.19209289550781250e-07), RES(-1.1920928955078068531e-7, 1.1920928955078181469e-7)}, {FN (arcsin), ARG(-1.19209289550781250e-07,-1.19209289550781250e-07), RES(-1.1920928955078068531e-7, -1.1920928955078181469e-7)}, {FN (arcsin), ARG(1.19209289550781250e-07,5.0e-01), RES(1.0662402999400097805e-7, 4.8121182505960598961e-1)}, {FN (arcsin), ARG(1.19209289550781250e-07,-5.0e-01), RES(1.0662402999400097805e-7, -4.8121182505960598961e-1)}, {FN (arcsin), ARG(-1.19209289550781250e-07,5.0e-01), RES(-1.0662402999400097805e-7, 4.8121182505960598961e-1)}, {FN (arcsin), ARG(-1.19209289550781250e-07,-5.0e-01), RES(-1.0662402999400097805e-7, -4.8121182505960598961e-1)}, {FN (arcsin), ARG(1.19209289550781250e-07,1.0e+00), RES(8.4293697021788013662e-8, 8.8137358701954553738e-1)}, {FN (arcsin), ARG(1.19209289550781250e-07,-1.0e+00), RES(8.4293697021788013662e-8, -8.8137358701954553738e-1)}, {FN (arcsin), ARG(-1.19209289550781250e-07,1.0e+00), RES(-8.4293697021788013662e-8, 8.8137358701954553738e-1)}, {FN (arcsin), ARG(-1.19209289550781250e-07,-1.0e+00), RES(-8.4293697021788013662e-8, -8.8137358701954553738e-1)}, {FN (arcsin), ARG(1.19209289550781250e-07,2.0e+00), RES(5.3312014997000413263e-8, 1.4436354751788116136e0)}, {FN (arcsin), ARG(1.19209289550781250e-07,-2.0e+00), RES(5.3312014997000413263e-8, -1.4436354751788116136e0)}, {FN (arcsin), ARG(-1.19209289550781250e-07,2.0e+00), RES(-5.3312014997000413263e-8, 1.4436354751788116136e0)}, {FN (arcsin), ARG(-1.19209289550781250e-07,-2.0e+00), RES(-5.3312014997000413263e-8, -1.4436354751788116136e0)}, {FN (arcsin), ARG(1.19209289550781250e-07,8.3886080e+06), RES(1.4210854715201902743e-14, 1.6635532333438690979e1)}, {FN (arcsin), ARG(1.19209289550781250e-07,-8.3886080e+06), RES(1.4210854715201902743e-14, -1.6635532333438690979e1)}, {FN (arcsin), ARG(-1.19209289550781250e-07,8.3886080e+06), RES(-1.4210854715201902743e-14, 1.6635532333438690979e1)}, {FN (arcsin), ARG(-1.19209289550781250e-07,-8.3886080e+06), RES(-1.4210854715201902743e-14, -1.6635532333438690979e1)}, {FN (arcsin), ARG(5.0e-01,0.0e+00), RES(5.2359877559829887308e-1, 0.0)}, {FN (arcsin), ARG(-5.0e-01,0.0e+00), RES(-5.2359877559829887308e-1, 0.0)}, {FN (arcsin), ARG(5.0e-01,1.19209289550781250e-07), RES(5.2359877559829340332e-1, 1.3765103082409432364e-7)}, {FN (arcsin), ARG(5.0e-01,-1.19209289550781250e-07), RES(5.2359877559829340332e-1, -1.3765103082409432364e-7)}, {FN (arcsin), ARG(-5.0e-01,1.19209289550781250e-07), RES(-5.2359877559829340332e-1, 1.3765103082409432364e-7)}, {FN (arcsin), ARG(-5.0e-01,-1.19209289550781250e-07), RES(-5.2359877559829340332e-1, -1.3765103082409432364e-7)}, {FN (arcsin), ARG(5.0e-01,5.0e-01), RES(4.5227844715119068206e-1, 5.3063753095251782602e-1)}, {FN (arcsin), ARG(5.0e-01,-5.0e-01), RES(4.5227844715119068206e-1, -5.3063753095251782602e-1)}, {FN (arcsin), ARG(-5.0e-01,5.0e-01), RES(-4.5227844715119068206e-1, 5.3063753095251782602e-1)}, {FN (arcsin), ARG(-5.0e-01,-5.0e-01), RES(-4.5227844715119068206e-1, -5.3063753095251782602e-1)}, {FN (arcsin), ARG(5.0e-01,1.0e+00), RES(3.4943906285721329363e-1, 9.2613303135018242455e-1)}, {FN (arcsin), ARG(5.0e-01,-1.0e+00), RES(3.4943906285721329363e-1, -9.2613303135018242455e-1)}, {FN (arcsin), ARG(-5.0e-01,1.0e+00), RES(-3.4943906285721329363e-1, 9.2613303135018242455e-1)}, {FN (arcsin), ARG(-5.0e-01,-1.0e+00), RES(-3.4943906285721329363e-1, -9.2613303135018242455e-1)}, {FN (arcsin), ARG(5.0e-01,2.0e+00), RES(2.2101863562288385890e-1, 1.4657153519472905218e0)}, {FN (arcsin), ARG(5.0e-01,-2.0e+00), RES(2.2101863562288385890e-1, -1.4657153519472905218e0)}, {FN (arcsin), ARG(-5.0e-01,2.0e+00), RES(-2.2101863562288385890e-1, 1.4657153519472905218e0)}, {FN (arcsin), ARG(-5.0e-01,-2.0e+00), RES(-2.2101863562288385890e-1, -1.4657153519472905218e0)}, {FN (arcsin), ARG(5.0e-01,8.3886080e+06), RES(5.9604644775390130897e-8, 1.6635532333438692755e1)}, {FN (arcsin), ARG(5.0e-01,-8.3886080e+06), RES(5.9604644775390130897e-8, -1.6635532333438692755e1)}, {FN (arcsin), ARG(-5.0e-01,8.3886080e+06), RES(-5.9604644775390130897e-8, 1.6635532333438692755e1)}, {FN (arcsin), ARG(-5.0e-01,-8.3886080e+06), RES(-5.9604644775390130897e-8, -1.6635532333438692755e1)}, {FN (arcsin), ARG(1.0e+00,0.0e+00), RES(1.5707963267948966192e0, 0.0)}, {FN (arcsin), ARG(-1.0e+00,0.0e+00), RES(-1.5707963267948966192e0, 0.0)}, {FN (arcsin), ARG(1.0e+00,1.19209289550781250e-07), RES(1.5704510598153252947e0, 3.4526698643116312881e-4)}, {FN (arcsin), ARG(1.0e+00,-1.19209289550781250e-07), RES(1.5704510598153252947e0, -3.4526698643116312881e-4)}, {FN (arcsin), ARG(-1.0e+00,1.19209289550781250e-07), RES(-1.5704510598153252947e0, 3.4526698643116312881e-4)}, {FN (arcsin), ARG(-1.0e+00,-1.19209289550781250e-07), RES(-1.5704510598153252947e0, -3.4526698643116312881e-4)}, {FN (arcsin), ARG(1.0e+00,5.0e-01), RES(8.9590748120889023907e-1, 7.3285767597364526089e-1)}, {FN (arcsin), ARG(1.0e+00,-5.0e-01), RES(8.9590748120889023907e-1, -7.3285767597364526089e-1)}, {FN (arcsin), ARG(-1.0e+00,5.0e-01), RES(-8.9590748120889023907e-1, 7.3285767597364526089e-1)}, {FN (arcsin), ARG(-1.0e+00,-5.0e-01), RES(-8.9590748120889023907e-1, -7.3285767597364526089e-1)}, {FN (arcsin), ARG(1.0e+00,1.0e+00), RES(6.6623943249251525510e-1, 1.0612750619050356520e0)}, {FN (arcsin), ARG(1.0e+00,-1.0e+00), RES(6.6623943249251525510e-1, -1.0612750619050356520e0)}, {FN (arcsin), ARG(-1.0e+00,1.0e+00), RES(-6.6623943249251525510e-1, 1.0612750619050356520e0)}, {FN (arcsin), ARG(-1.0e+00,-1.0e+00), RES(-6.6623943249251525510e-1, -1.0612750619050356520e0)}, {FN (arcsin), ARG(1.0e+00,2.0e+00), RES(4.2707858639247612548e-1, 1.5285709194809981613e0)}, {FN (arcsin), ARG(1.0e+00,-2.0e+00), RES(4.2707858639247612548e-1, -1.5285709194809981613e0)}, {FN (arcsin), ARG(-1.0e+00,2.0e+00), RES(-4.2707858639247612548e-1, 1.5285709194809981613e0)}, {FN (arcsin), ARG(-1.0e+00,-2.0e+00), RES(-4.2707858639247612548e-1, -1.5285709194809981613e0)}, {FN (arcsin), ARG(1.0e+00,8.3886080e+06), RES(1.1920928955077983828e-7, 1.6635532333438698084e1)}, {FN (arcsin), ARG(1.0e+00,-8.3886080e+06), RES(1.1920928955077983828e-7, -1.6635532333438698084e1)}, {FN (arcsin), ARG(-1.0e+00,8.3886080e+06), RES(-1.1920928955077983828e-7, 1.6635532333438698084e1)}, {FN (arcsin), ARG(-1.0e+00,-8.3886080e+06), RES(-1.1920928955077983828e-7, -1.6635532333438698084e1)}, {FN (arcsin), ARG(2.0e+00,0.0e+00), RES(1.5707963267948966192e0, -1.3169578969248167086e0)}, {FN (arcsin), ARG(-2.0e+00,0.0e+00), RES(-1.5707963267948966192e0, 1.3169578969248167086e0)}, {FN (arcsin), ARG(2.0e+00,1.19209289550781250e-07), RES(1.5707962579693812072e0, 1.3169578969248194435e0)}, {FN (arcsin), ARG(2.0e+00,-1.19209289550781250e-07), RES(1.5707962579693812072e0, -1.3169578969248194435e0)}, {FN (arcsin), ARG(-2.0e+00,1.19209289550781250e-07), RES(-1.5707962579693812072e0, 1.3169578969248194435e0)}, {FN (arcsin), ARG(-2.0e+00,-1.19209289550781250e-07), RES(-1.5707962579693812072e0, -1.3169578969248194435e0)}, {FN (arcsin), ARG(2.0e+00,5.0e-01), RES(1.2930420702371826591e0, 1.3618009008578457882e0)}, {FN (arcsin), ARG(2.0e+00,-5.0e-01), RES(1.2930420702371826591e0, -1.3618009008578457882e0)}, {FN (arcsin), ARG(-2.0e+00,5.0e-01), RES(-1.2930420702371826591e0, 1.3618009008578457882e0)}, {FN (arcsin), ARG(-2.0e+00,-5.0e-01), RES(-1.2930420702371826591e0, -1.3618009008578457882e0)}, {FN (arcsin), ARG(2.0e+00,1.0e+00), RES(1.0634400235777520562e0, 1.4693517443681852733e0)}, {FN (arcsin), ARG(2.0e+00,-1.0e+00), RES(1.0634400235777520562e0, -1.4693517443681852733e0)}, {FN (arcsin), ARG(-2.0e+00,1.0e+00), RES(-1.0634400235777520562e0, 1.4693517443681852733e0)}, {FN (arcsin), ARG(-2.0e+00,-1.0e+00), RES(-1.0634400235777520562e0, -1.4693517443681852733e0)}, {FN (arcsin), ARG(2.0e+00,2.0e+00), RES(7.5424914469804604071e-1, 1.7343245214879664480e0)}, {FN (arcsin), ARG(2.0e+00,-2.0e+00), RES(7.5424914469804604071e-1, -1.7343245214879664480e0)}, {FN (arcsin), ARG(-2.0e+00,2.0e+00), RES(-7.5424914469804604071e-1, 1.7343245214879664480e0)}, {FN (arcsin), ARG(-2.0e+00,-2.0e+00), RES(-7.5424914469804604071e-1, -1.7343245214879664480e0)}, {FN (arcsin), ARG(2.0e+00,8.3886080e+06), RES(2.3841857910155628843e-7, 1.663553233343871940e1)}, {FN (arcsin), ARG(2.0e+00,-8.3886080e+06), RES(2.3841857910155628843e-7, -1.663553233343871940e1)}, {FN (arcsin), ARG(-2.0e+00,8.3886080e+06), RES(-2.3841857910155628843e-7, 1.663553233343871940e1)}, {FN (arcsin), ARG(-2.0e+00,-8.3886080e+06), RES(-2.3841857910155628843e-7, -1.663553233343871940e1)}, {FN (arcsin), ARG(8.3886080e+06,0.0e+00), RES(1.5707963267948966192e0, -1.6635532333438683873e1)}, {FN (arcsin), ARG(-8.3886080e+06,0.0e+00), RES(-1.5707963267948966192e0, 1.6635532333438683873e1)}, {FN (arcsin), ARG(8.3886080e+06,1.19209289550781250e-07), RES(1.5707963267948824084e0, 1.6635532333438683873e1)}, {FN (arcsin), ARG(8.3886080e+06,-1.19209289550781250e-07), RES(1.5707963267948824084e0, -1.6635532333438683873e1)}, {FN (arcsin), ARG(-8.3886080e+06,1.19209289550781250e-07), RES(-1.5707963267948824084e0, 1.6635532333438683873e1)}, {FN (arcsin), ARG(-8.3886080e+06,-1.19209289550781250e-07), RES(-1.5707963267948824084e0, -1.6635532333438683873e1)}, {FN (arcsin), ARG(8.3886080e+06,5.0e-01), RES(1.5707962671902518438e0, 1.6635532333438685650e1)}, {FN (arcsin), ARG(8.3886080e+06,-5.0e-01), RES(1.5707962671902518438e0, -1.6635532333438685650e1)}, {FN (arcsin), ARG(-8.3886080e+06,5.0e-01), RES(-1.5707962671902518438e0, 1.6635532333438685650e1)}, {FN (arcsin), ARG(-8.3886080e+06,-5.0e-01), RES(-1.5707962671902518438e0, -1.6635532333438685650e1)}, {FN (arcsin), ARG(8.3886080e+06,1.0e+00), RES(1.5707962075856070684e0, 1.6635532333438690979e1)}, {FN (arcsin), ARG(8.3886080e+06,-1.0e+00), RES(1.5707962075856070684e0, -1.6635532333438690979e1)}, {FN (arcsin), ARG(-8.3886080e+06,1.0e+00), RES(-1.5707962075856070684e0, 1.6635532333438690979e1)}, {FN (arcsin), ARG(-8.3886080e+06,-1.0e+00), RES(-1.5707962075856070684e0, -1.6635532333438690979e1)}, {FN (arcsin), ARG(8.3886080e+06,2.0e+00), RES(1.5707960883763175177e0, 1.6635532333438712295e1)}, {FN (arcsin), ARG(8.3886080e+06,-2.0e+00), RES(1.5707960883763175177e0, -1.6635532333438712295e1)}, {FN (arcsin), ARG(-8.3886080e+06,2.0e+00), RES(-1.5707960883763175177e0, 1.6635532333438712295e1)}, {FN (arcsin), ARG(-8.3886080e+06,-2.0e+00), RES(-1.5707960883763175177e0, -1.6635532333438712295e1)}, {FN (arcsin), ARG(8.3886080e+06,8.3886080e+06), RES(7.8539816339744653326e-1, 1.6982105923718660081e1)}, {FN (arcsin), ARG(8.3886080e+06,-8.3886080e+06), RES(7.8539816339744653326e-1, -1.6982105923718660081e1)}, {FN (arcsin), ARG(-8.3886080e+06,8.3886080e+06), RES(-7.8539816339744653326e-1, 1.6982105923718660081e1)}, {FN (arcsin), ARG(-8.3886080e+06,-8.3886080e+06), RES(-7.8539816339744653326e-1, -1.6982105923718660081e1)}, {FN (arccos), ARG(0.0e+00,0.0e+00), RES(1.5707963267948966192e0, 0.0)}, {FN (arccos), ARG(0.0e+00,1.19209289550781250e-07), RES(1.5707963267948966192e0, -1.1920928955078096766e-7)}, {FN (arccos), ARG(0.0e+00,-1.19209289550781250e-07), RES(1.5707963267948966192e0, 1.1920928955078096766e-7)}, {FN (arccos), ARG(0.0e+00,5.0e-01), RES(1.5707963267948966192e0, -4.8121182505960344750e-1)}, {FN (arccos), ARG(0.0e+00,-5.0e-01), RES(1.5707963267948966192e0, 4.8121182505960344750e-1)}, {FN (arccos), ARG(0.0e+00,1.0e+00), RES(1.5707963267948966192e0, -8.8137358701954302523e-1)}, {FN (arccos), ARG(0.0e+00,-1.0e+00), RES(1.5707963267948966192e0, 8.8137358701954302523e-1)}, {FN (arccos), ARG(0.0e+00,2.0e+00), RES(1.5707963267948966192e0, -1.4436354751788103425e0)}, {FN (arccos), ARG(0.0e+00,-2.0e+00), RES(1.5707963267948966192e0, 1.4436354751788103425e0)}, {FN (arccos), ARG(0.0e+00,8.3886080e+06), RES(1.5707963267948966192e0, -1.6635532333438690979e1)}, {FN (arccos), ARG(0.0e+00,-8.3886080e+06), RES(1.5707963267948966192e0, 1.6635532333438690979e1)}, {FN (arccos), ARG(1.19209289550781250e-07,0.0e+00), RES(1.5707962075856070684e0, 0.0)}, {FN (arccos), ARG(-1.19209289550781250e-07,0.0e+00), RES(1.570796446004186170e0, 0.0)}, {FN (arccos), ARG(1.19209289550781250e-07,1.19209289550781250e-07), RES(1.5707962075856070685e0, -1.1920928955078181469e-7)}, {FN (arccos), ARG(1.19209289550781250e-07,-1.19209289550781250e-07), RES(1.5707962075856070685e0, 1.1920928955078181469e-7)}, {FN (arccos), ARG(-1.19209289550781250e-07,1.19209289550781250e-07), RES(1.570796446004186170e0, -1.1920928955078181469e-7)}, {FN (arccos), ARG(-1.19209289550781250e-07,-1.19209289550781250e-07), RES(1.570796446004186170e0, 1.1920928955078181469e-7)}, {FN (arccos), ARG(1.19209289550781250e-07,5.0e-01), RES(1.5707962201708666252e0, -4.8121182505960598961e-1)}, {FN (arccos), ARG(1.19209289550781250e-07,-5.0e-01), RES(1.5707962201708666252e0, 4.8121182505960598961e-1)}, {FN (arccos), ARG(-1.19209289550781250e-07,5.0e-01), RES(1.5707964334189266132e0, -4.8121182505960598961e-1)}, {FN (arccos), ARG(-1.19209289550781250e-07,-5.0e-01), RES(1.5707964334189266132e0, 4.8121182505960598961e-1)}, {FN (arccos), ARG(1.19209289550781250e-07,1.0e+00), RES(1.5707962425011995974e0, -8.8137358701954553738e-1)}, {FN (arccos), ARG(1.19209289550781250e-07,-1.0e+00), RES(1.5707962425011995974e0, 8.8137358701954553738e-1)}, {FN (arccos), ARG(-1.19209289550781250e-07,1.0e+00), RES(1.5707964110885936410e0, -8.8137358701954553738e-1)}, {FN (arccos), ARG(-1.19209289550781250e-07,-1.0e+00), RES(1.5707964110885936410e0, 8.8137358701954553738e-1)}, {FN (arccos), ARG(1.19209289550781250e-07,2.0e+00), RES(1.5707962734828816222e0, -1.4436354751788116136e0)}, {FN (arccos), ARG(1.19209289550781250e-07,-2.0e+00), RES(1.5707962734828816222e0, 1.4436354751788116136e0)}, {FN (arccos), ARG(-1.19209289550781250e-07,2.0e+00), RES(1.5707963801069116162e0, -1.4436354751788116136e0)}, {FN (arccos), ARG(-1.19209289550781250e-07,-2.0e+00), RES(1.5707963801069116162e0, 1.4436354751788116136e0)}, {FN (arccos), ARG(1.19209289550781250e-07,8.3886080e+06), RES(1.5707963267948824084e0, -1.6635532333438690979e1)}, {FN (arccos), ARG(1.19209289550781250e-07,-8.3886080e+06), RES(1.5707963267948824084e0, 1.6635532333438690979e1)}, {FN (arccos), ARG(-1.19209289550781250e-07,8.3886080e+06), RES(1.5707963267949108301e0, -1.6635532333438690979e1)}, {FN (arccos), ARG(-1.19209289550781250e-07,-8.3886080e+06), RES(1.5707963267949108301e0, 1.6635532333438690979e1)}, {FN (arccos), ARG(5.0e-01,0.0e+00), RES(1.0471975511965977462e0, 0.0)}, {FN (arccos), ARG(-5.0e-01,0.0e+00), RES(2.0943951023931954923e0, 0.0)}, {FN (arccos), ARG(5.0e-01,1.19209289550781250e-07), RES(1.0471975511966032159e0, -1.3765103082409432364e-7)}, {FN (arccos), ARG(5.0e-01,-1.19209289550781250e-07), RES(1.0471975511966032159e0, 1.3765103082409432364e-7)}, {FN (arccos), ARG(-5.0e-01,1.19209289550781250e-07), RES(2.0943951023931900225e0, -1.3765103082409432364e-7)}, {FN (arccos), ARG(-5.0e-01,-1.19209289550781250e-07), RES(2.0943951023931900225e0, 1.3765103082409432364e-7)}, {FN (arccos), ARG(5.0e-01,5.0e-01), RES(1.1185178796437059372e0, -5.3063753095251782602e-1)}, {FN (arccos), ARG(5.0e-01,-5.0e-01), RES(1.1185178796437059372e0, 5.3063753095251782602e-1)}, {FN (arccos), ARG(-5.0e-01,5.0e-01), RES(2.0230747739460873013e0, -5.3063753095251782602e-1)}, {FN (arccos), ARG(-5.0e-01,-5.0e-01), RES(2.0230747739460873013e0, 5.3063753095251782602e-1)}, {FN (arccos), ARG(5.0e-01,1.0e+00), RES(1.2213572639376833256e0, -9.2613303135018242455e-1)}, {FN (arccos), ARG(5.0e-01,-1.0e+00), RES(1.2213572639376833256e0, 9.2613303135018242455e-1)}, {FN (arccos), ARG(-5.0e-01,1.0e+00), RES(1.9202353896521099129e0, -9.2613303135018242455e-1)}, {FN (arccos), ARG(-5.0e-01,-1.0e+00), RES(1.9202353896521099129e0, 9.2613303135018242455e-1)}, {FN (arccos), ARG(5.0e-01,2.0e+00), RES(1.3497776911720127603e0, -1.4657153519472905218e0)}, {FN (arccos), ARG(5.0e-01,-2.0e+00), RES(1.3497776911720127603e0, 1.4657153519472905218e0)}, {FN (arccos), ARG(-5.0e-01,2.0e+00), RES(1.7918149624177804781e0, -1.4657153519472905218e0)}, {FN (arccos), ARG(-5.0e-01,-2.0e+00), RES(1.7918149624177804781e0, 1.4657153519472905218e0)}, {FN (arccos), ARG(5.0e-01,8.3886080e+06), RES(1.5707962671902518438e0, -1.6635532333438692755e1)}, {FN (arccos), ARG(5.0e-01,-8.3886080e+06), RES(1.5707962671902518438e0, 1.6635532333438692755e1)}, {FN (arccos), ARG(-5.0e-01,8.3886080e+06), RES(1.5707963863995413946e0, -1.6635532333438692755e1)}, {FN (arccos), ARG(-5.0e-01,-8.3886080e+06), RES(1.5707963863995413946e0, 1.6635532333438692755e1)}, {FN (arccos), ARG(1.0e+00,0.0e+00), RES(0e0, 0.0)}, {FN (arccos), ARG(-1.0e+00,0.0e+00), RES(3.1415926535897932385e0, 0.0)}, {FN (arccos), ARG(1.0e+00,1.19209289550781250e-07), RES(3.4526697957132450399e-4, -3.4526698643116312881e-4)}, {FN (arccos), ARG(1.0e+00,-1.19209289550781250e-07), RES(3.4526697957132450399e-4, 3.4526698643116312881e-4)}, {FN (arccos), ARG(-1.0e+00,1.19209289550781250e-07), RES(3.1412473866102219140e0, -3.4526698643116312881e-4)}, {FN (arccos), ARG(-1.0e+00,-1.19209289550781250e-07), RES(3.1412473866102219140e0, 3.4526698643116312881e-4)}, {FN (arccos), ARG(1.0e+00,5.0e-01), RES(6.7488884558600638016e-1, -7.3285767597364526089e-1)}, {FN (arccos), ARG(1.0e+00,-5.0e-01), RES(6.7488884558600638016e-1, 7.3285767597364526089e-1)}, {FN (arccos), ARG(-1.0e+00,5.0e-01), RES(2.4667038080037868583e0, -7.3285767597364526089e-1)}, {FN (arccos), ARG(-1.0e+00,-5.0e-01), RES(2.4667038080037868583e0, 7.3285767597364526089e-1)}, {FN (arccos), ARG(1.0e+00,1.0e+00), RES(9.0455689430238136413e-1, -1.0612750619050356520e0)}, {FN (arccos), ARG(1.0e+00,-1.0e+00), RES(9.0455689430238136413e-1, 1.0612750619050356520e0)}, {FN (arccos), ARG(-1.0e+00,1.0e+00), RES(2.2370357592874118743e0, -1.0612750619050356520e0)}, {FN (arccos), ARG(-1.0e+00,-1.0e+00), RES(2.2370357592874118743e0, 1.0612750619050356520e0)}, {FN (arccos), ARG(1.0e+00,2.0e+00), RES(1.1437177404024204938e0, -1.5285709194809981613e0)}, {FN (arccos), ARG(1.0e+00,-2.0e+00), RES(1.1437177404024204938e0, 1.5285709194809981613e0)}, {FN (arccos), ARG(-1.0e+00,2.0e+00), RES(1.9978749131873727447e0, -1.5285709194809981613e0)}, {FN (arccos), ARG(-1.0e+00,-2.0e+00), RES(1.9978749131873727447e0, 1.5285709194809981613e0)}, {FN (arccos), ARG(1.0e+00,8.3886080e+06), RES(1.5707962075856070685e0, -1.6635532333438698084e1)}, {FN (arccos), ARG(1.0e+00,-8.3886080e+06), RES(1.5707962075856070685e0, 1.6635532333438698084e1)}, {FN (arccos), ARG(-1.0e+00,8.3886080e+06), RES(1.570796446004186170e0, -1.6635532333438698084e1)}, {FN (arccos), ARG(-1.0e+00,-8.3886080e+06), RES(1.570796446004186170e0, 1.6635532333438698084e1)}, {FN (arccos), ARG(2.0e+00,0.0e+00), RES(0, 1.3169578969248167086e0)}, {FN (arccos), ARG(-2.0e+00,0.0e+00), RES(3.1415926535897932385e0, -1.3169578969248167086e0)}, {FN (arccos), ARG(2.0e+00,1.19209289550781250e-07), RES(6.8825515412047433504e-8, -1.3169578969248194435e0)}, {FN (arccos), ARG(2.0e+00,-1.19209289550781250e-07), RES(6.8825515412047433504e-8, 1.3169578969248194435e0)}, {FN (arccos), ARG(-2.0e+00,1.19209289550781250e-07), RES(3.1415925847642778264e0, -1.3169578969248194435e0)}, {FN (arccos), ARG(-2.0e+00,-1.19209289550781250e-07), RES(3.1415925847642778264e0, 1.3169578969248194435e0)}, {FN (arccos), ARG(2.0e+00,5.0e-01), RES(2.7775425655771396018e-1, -1.3618009008578457882e0)}, {FN (arccos), ARG(2.0e+00,-5.0e-01), RES(2.7775425655771396018e-1, 1.3618009008578457882e0)}, {FN (arccos), ARG(-2.0e+00,5.0e-01), RES(2.8638383970320792783e0, -1.3618009008578457882e0)}, {FN (arccos), ARG(-2.0e+00,-5.0e-01), RES(2.8638383970320792783e0, 1.3618009008578457882e0)}, {FN (arccos), ARG(2.0e+00,1.0e+00), RES(5.0735630321714456304e-1, -1.4693517443681852733e0)}, {FN (arccos), ARG(2.0e+00,-1.0e+00), RES(5.0735630321714456304e-1, 1.4693517443681852733e0)}, {FN (arccos), ARG(-2.0e+00,1.0e+00), RES(2.6342363503726486754e0, -1.4693517443681852733e0)}, {FN (arccos), ARG(-2.0e+00,-1.0e+00), RES(2.6342363503726486754e0, 1.4693517443681852733e0)}, {FN (arccos), ARG(2.0e+00,2.0e+00), RES(8.1654718209685057852e-1, -1.7343245214879664480e0)}, {FN (arccos), ARG(2.0e+00,-2.0e+00), RES(8.1654718209685057852e-1, 1.7343245214879664480e0)}, {FN (arccos), ARG(-2.0e+00,2.0e+00), RES(2.3250454714929426599e0, -1.7343245214879664480e0)}, {FN (arccos), ARG(-2.0e+00,-2.0e+00), RES(2.3250454714929426599e0, 1.7343245214879664480e0)}, {FN (arccos), ARG(2.0e+00,8.3886080e+06), RES(1.5707960883763175177e0, -1.663553233343871940e1)}, {FN (arccos), ARG(2.0e+00,-8.3886080e+06), RES(1.5707960883763175177e0, 1.663553233343871940e1)}, {FN (arccos), ARG(-2.0e+00,8.3886080e+06), RES(1.5707965652134757208e0, -1.663553233343871940e1)}, {FN (arccos), ARG(-2.0e+00,-8.3886080e+06), RES(1.5707965652134757208e0, 1.663553233343871940e1)}, {FN (arccos), ARG(8.3886080e+06,0.0e+00), RES(0, 1.6635532333438683873e1)}, {FN (arccos), ARG(-8.3886080e+06,0.0e+00), RES(3.1415926535897932385e0, -1.6635532333438683873e1)}, {FN (arccos), ARG(8.3886080e+06,1.19209289550781250e-07), RES(1.4210854715202104692e-14, -1.6635532333438683873e1)}, {FN (arccos), ARG(8.3886080e+06,-1.19209289550781250e-07), RES(1.4210854715202104692e-14, 1.6635532333438683873e1)}, {FN (arccos), ARG(-8.3886080e+06,1.19209289550781250e-07), RES(3.1415926535897790276e0, -1.6635532333438683873e1)}, {FN (arccos), ARG(-8.3886080e+06,-1.19209289550781250e-07), RES(3.1415926535897790276e0, 1.6635532333438683873e1)}, {FN (arccos), ARG(8.3886080e+06,5.0e-01), RES(5.9604644775390977930e-8, -1.6635532333438685650e1)}, {FN (arccos), ARG(8.3886080e+06,-5.0e-01), RES(5.9604644775390977930e-8, 1.6635532333438685650e1)}, {FN (arccos), ARG(-8.3886080e+06,5.0e-01), RES(3.1415925939851484631e0, -1.6635532333438685650e1)}, {FN (arccos), ARG(-8.3886080e+06,-5.0e-01), RES(3.1415925939851484631e0, 1.6635532333438685650e1)}, {FN (arccos), ARG(8.3886080e+06,1.0e+00), RES(1.1920928955078153234e-7, -1.6635532333438690979e1)}, {FN (arccos), ARG(8.3886080e+06,-1.0e+00), RES(1.1920928955078153234e-7, 1.6635532333438690979e1)}, {FN (arccos), ARG(-8.3886080e+06,1.0e+00), RES(3.1415925343805036877e0, -1.6635532333438690979e1)}, {FN (arccos), ARG(-8.3886080e+06,-1.0e+00), RES(3.1415925343805036877e0, 1.6635532333438690979e1)}, {FN (arccos), ARG(8.3886080e+06,2.0e+00), RES(2.3841857910155967656e-7, -1.6635532333438712295e1)}, {FN (arccos), ARG(8.3886080e+06,-2.0e+00), RES(2.3841857910155967656e-7, 1.6635532333438712295e1)}, {FN (arccos), ARG(-8.3886080e+06,2.0e+00), RES(3.1415924151712141369e0, -1.6635532333438712295e1)}, {FN (arccos), ARG(-8.3886080e+06,-2.0e+00), RES(3.1415924151712141369e0, 1.6635532333438712295e1)}, {FN (arccos), ARG(8.3886080e+06,8.3886080e+06), RES(7.8539816339745008597e-1, -1.6982105923718660081e1)}, {FN (arccos), ARG(8.3886080e+06,-8.3886080e+06), RES(7.8539816339745008597e-1, 1.6982105923718660081e1)}, {FN (arccos), ARG(-8.3886080e+06,8.3886080e+06), RES(2.3561944901923431525e0, -1.6982105923718660081e1)}, {FN (arccos), ARG(-8.3886080e+06,-8.3886080e+06), RES(2.3561944901923431525e0, 1.6982105923718660081e1)}, {FN (arctan), ARG(0.0e+00,0.0e+00), RES(0e0, 0.0)}, {FN (arctan), ARG(0.0e+00,1.19209289550781250e-07), RES(0, 1.1920928955078181469e-7)}, {FN (arctan), ARG(0.0e+00,-1.19209289550781250e-07), RES(0, -1.1920928955078181469e-7)}, {FN (arctan), ARG(0.0e+00,5.0e-01), RES(0, 5.4930614433405484570e-1)}, {FN (arctan), ARG(0.0e+00,-5.0e-01), RES(0, -5.4930614433405484570e-1)}, {FN (arctan), ARG(0.0e+00,2.0e+00), RES(1.5707963267948966192e0, 5.4930614433405484570e-1)}, {FN (arctan), ARG(0.0e+00,-2.0e+00), RES(-1.5707963267948966192e0, -5.4930614433405484570e-1)}, {FN (arctan), ARG(0.0e+00,8.3886080e+06), RES(1.5707963267948966192e0, 1.1920928955078181469e-7)}, {FN (arctan), ARG(0.0e+00,-8.3886080e+06), RES(-1.5707963267948966192e0, -1.1920928955078181469e-7)}, {FN (arctan), ARG(1.19209289550781250e-07,0.0e+00), RES(1.1920928955078068531e-7, 0.0)}, {FN (arctan), ARG(-1.19209289550781250e-07,0.0e+00), RES(-1.1920928955078068531e-7, 0.0)}, {FN (arctan), ARG(1.19209289550781250e-07,1.19209289550781250e-07), RES(1.1920928955078237938e-7, 1.1920928955078012062e-7)}, {FN (arctan), ARG(1.19209289550781250e-07,-1.19209289550781250e-07), RES(1.1920928955078237938e-7, -1.1920928955078012062e-7)}, {FN (arctan), ARG(-1.19209289550781250e-07,1.19209289550781250e-07), RES(-1.1920928955078237938e-7, 1.1920928955078012062e-7)}, {FN (arctan), ARG(-1.19209289550781250e-07,-1.19209289550781250e-07), RES(-1.1920928955078237938e-7, -1.1920928955078012062e-7)}, {FN (arctan), ARG(1.19209289550781250e-07,5.0e-01), RES(1.5894571940103932425e-7, 5.4930614433404221383e-1)}, {FN (arctan), ARG(1.19209289550781250e-07,-5.0e-01), RES(1.5894571940103932425e-7, -5.4930614433404221383e-1)}, {FN (arctan), ARG(-1.19209289550781250e-07,5.0e-01), RES(-1.5894571940103932425e-7, 5.4930614433404221383e-1)}, {FN (arctan), ARG(-1.19209289550781250e-07,-5.0e-01), RES(-1.5894571940103932425e-7, -5.4930614433404221383e-1)}, {FN (arctan), ARG(1.19209289550781250e-07,1.0e+00), RES(7.8539819319977069731e-1, 8.3177661667193446012e0)}, {FN (arctan), ARG(1.19209289550781250e-07,-1.0e+00), RES(7.8539819319977069731e-1, -8.3177661667193446012e0)}, {FN (arctan), ARG(-1.19209289550781250e-07,1.0e+00), RES(-7.8539819319977069731e-1, 8.3177661667193446012e0)}, {FN (arctan), ARG(-1.19209289550781250e-07,-1.0e+00), RES(-7.8539819319977069731e-1, -8.3177661667193446012e0)}, {FN (arctan), ARG(1.19209289550781250e-07,2.0e+00), RES(1.5707962870584667690e0, 5.4930614433405168773e-1)}, {FN (arctan), ARG(1.19209289550781250e-07,-2.0e+00), RES(1.5707962870584667690e0, -5.4930614433405168773e-1)}, {FN (arctan), ARG(-1.19209289550781250e-07,2.0e+00), RES(-1.5707962870584667690e0, 5.4930614433405168773e-1)}, {FN (arctan), ARG(-1.19209289550781250e-07,-2.0e+00), RES(-1.5707962870584667690e0, -5.4930614433405168773e-1)}, {FN (arctan), ARG(1.19209289550781250e-07,8.3886080e+06), RES(1.5707963267948966192e0, 1.1920928955078181469e-7)}, {FN (arctan), ARG(1.19209289550781250e-07,-8.3886080e+06), RES(1.5707963267948966192e0, -1.1920928955078181469e-7)}, {FN (arctan), ARG(-1.19209289550781250e-07,8.3886080e+06), RES(-1.5707963267948966192e0, 1.1920928955078181469e-7)}, {FN (arctan), ARG(-1.19209289550781250e-07,-8.3886080e+06), RES(-1.5707963267948966192e0, -1.1920928955078181469e-7)}, {FN (arctan), ARG(5.0e-01,0.0e+00), RES(4.6364760900080611621e-1, 0.0)}, {FN (arctan), ARG(-5.0e-01,0.0e+00), RES(-4.6364760900080611621e-1, 0.0)}, {FN (arctan), ARG(5.0e-01,1.19209289550781250e-07), RES(4.6364760900081066369e-1, 9.5367431640625072280e-8)}, {FN (arctan), ARG(5.0e-01,-1.19209289550781250e-07), RES(4.6364760900081066369e-1, -9.5367431640625072280e-8)}, {FN (arctan), ARG(-5.0e-01,1.19209289550781250e-07), RES(-4.6364760900081066369e-1, 9.5367431640625072280e-8)}, {FN (arctan), ARG(-5.0e-01,-1.19209289550781250e-07), RES(-4.6364760900081066369e-1, -9.5367431640625072280e-8)}, {FN (arctan), ARG(5.0e-01,5.0e-01), RES(5.5357435889704525151e-1, 4.0235947810852509365e-1)}, {FN (arctan), ARG(5.0e-01,-5.0e-01), RES(5.5357435889704525151e-1, -4.0235947810852509365e-1)}, {FN (arctan), ARG(-5.0e-01,5.0e-01), RES(-5.5357435889704525151e-1, 4.0235947810852509365e-1)}, {FN (arctan), ARG(-5.0e-01,-5.0e-01), RES(-5.5357435889704525151e-1, -4.0235947810852509365e-1)}, {FN (arctan), ARG(5.0e-01,1.0e+00), RES(9.0788749496088038670e-1, 7.0830333601405402006e-1)}, {FN (arctan), ARG(5.0e-01,-1.0e+00), RES(9.0788749496088038670e-1, -7.0830333601405402006e-1)}, {FN (arctan), ARG(-5.0e-01,1.0e+00), RES(-9.0788749496088038670e-1, 7.0830333601405402006e-1)}, {FN (arctan), ARG(-5.0e-01,-1.0e+00), RES(-9.0788749496088038670e-1, -7.0830333601405402006e-1)}, {FN (arctan), ARG(5.0e-01,2.0e+00), RES(1.4215468610018069803e0, 5.0037000005253101744e-1)}, {FN (arctan), ARG(5.0e-01,-2.0e+00), RES(1.4215468610018069803e0, -5.0037000005253101744e-1)}, {FN (arctan), ARG(-5.0e-01,2.0e+00), RES(-1.4215468610018069803e0, 5.0037000005253101744e-1)}, {FN (arctan), ARG(-5.0e-01,-2.0e+00), RES(-1.4215468610018069803e0, -5.0037000005253101744e-1)}, {FN (arctan), ARG(5.0e-01,8.3886080e+06), RES(1.5707963267948895138e0, 1.1920928955078139117e-7)}, {FN (arctan), ARG(5.0e-01,-8.3886080e+06), RES(1.5707963267948895138e0, -1.1920928955078139117e-7)}, {FN (arctan), ARG(-5.0e-01,8.3886080e+06), RES(-1.5707963267948895138e0, 1.1920928955078139117e-7)}, {FN (arctan), ARG(-5.0e-01,-8.3886080e+06), RES(-1.5707963267948895138e0, -1.1920928955078139117e-7)}, {FN (arctan), ARG(1.0e+00,0.0e+00), RES(7.8539816339744830962e-1, 0.0)}, {FN (arctan), ARG(-1.0e+00,0.0e+00), RES(-7.8539816339744830962e-1, 0.0)}, {FN (arctan), ARG(1.0e+00,1.19209289550781250e-07), RES(7.8539816339745186233e-1, 5.9604644775390483828e-8)}, {FN (arctan), ARG(1.0e+00,-1.19209289550781250e-07), RES(7.8539816339745186233e-1, -5.9604644775390483828e-8)}, {FN (arctan), ARG(-1.0e+00,1.19209289550781250e-07), RES(-7.8539816339745186233e-1, 5.9604644775390483828e-8)}, {FN (arctan), ARG(-1.0e+00,-1.19209289550781250e-07), RES(-7.8539816339745186233e-1, -5.9604644775390483828e-8)}, {FN (arctan), ARG(1.0e+00,5.0e-01), RES(8.4757566067082902713e-1, 2.3887786125685909036e-1)}, {FN (arctan), ARG(1.0e+00,-5.0e-01), RES(8.4757566067082902713e-1, -2.3887786125685909036e-1)}, {FN (arctan), ARG(-1.0e+00,5.0e-01), RES(-8.4757566067082902713e-1, 2.3887786125685909036e-1)}, {FN (arctan), ARG(-1.0e+00,-5.0e-01), RES(-8.4757566067082902713e-1, -2.3887786125685909036e-1)}, {FN (arctan), ARG(1.0e+00,1.0e+00), RES(1.0172219678978513677e0, 4.0235947810852509365e-1)}, {FN (arctan), ARG(1.0e+00,-1.0e+00), RES(1.0172219678978513677e0, -4.0235947810852509365e-1)}, {FN (arctan), ARG(-1.0e+00,1.0e+00), RES(-1.0172219678978513677e0, 4.0235947810852509365e-1)}, {FN (arctan), ARG(-1.0e+00,-1.0e+00), RES(-1.0172219678978513677e0, -4.0235947810852509365e-1)}, {FN (arctan), ARG(1.0e+00,2.0e+00), RES(1.3389725222944935611e0, 4.0235947810852509365e-1)}, {FN (arctan), ARG(1.0e+00,-2.0e+00), RES(1.3389725222944935611e0, -4.0235947810852509365e-1)}, {FN (arctan), ARG(-1.0e+00,2.0e+00), RES(-1.3389725222944935611e0, 4.0235947810852509365e-1)}, {FN (arctan), ARG(-1.0e+00,-2.0e+00), RES(-1.3389725222944935611e0, -4.0235947810852509365e-1)}, {FN (arctan), ARG(1.0e+00,8.3886080e+06), RES(1.5707963267948824084e0, 1.1920928955078012062e-7)}, {FN (arctan), ARG(1.0e+00,-8.3886080e+06), RES(1.5707963267948824084e0, -1.1920928955078012062e-7)}, {FN (arctan), ARG(-1.0e+00,8.3886080e+06), RES(-1.5707963267948824084e0, 1.1920928955078012062e-7)}, {FN (arctan), ARG(-1.0e+00,-8.3886080e+06), RES(-1.5707963267948824084e0, -1.1920928955078012062e-7)}, {FN (arctan), ARG(2.0e+00,0.0e+00), RES(1.1071487177940905030e0, 0.0)}, {FN (arctan), ARG(-2.0e+00,0.0e+00), RES(-1.1071487177940905030e0, 0.0)}, {FN (arctan), ARG(2.0e+00,1.19209289550781250e-07), RES(1.1071487177940916399e0, 2.3841857910156200307e-8)}, {FN (arctan), ARG(2.0e+00,-1.19209289550781250e-07), RES(1.1071487177940916399e0, -2.3841857910156200307e-8)}, {FN (arctan), ARG(-2.0e+00,1.19209289550781250e-07), RES(-1.1071487177940916399e0, 2.3841857910156200307e-8)}, {FN (arctan), ARG(-2.0e+00,-1.19209289550781250e-07), RES(-1.1071487177940916399e0, -2.3841857910156200307e-8)}, {FN (arctan), ARG(2.0e+00,5.0e-01), RES(1.1265564408348223487e0, 9.6415620202996167238e-2)}, {FN (arctan), ARG(2.0e+00,-5.0e-01), RES(1.1265564408348223487e0, -9.6415620202996167238e-2)}, {FN (arctan), ARG(-2.0e+00,5.0e-01), RES(-1.1265564408348223487e0, 9.6415620202996167238e-2)}, {FN (arctan), ARG(-2.0e+00,-5.0e-01), RES(-1.1265564408348223487e0, -9.6415620202996167238e-2)}, {FN (arctan), ARG(2.0e+00,1.0e+00), RES(1.1780972450961724644e0, 1.7328679513998632735e-1)}, {FN (arctan), ARG(2.0e+00,-1.0e+00), RES(1.1780972450961724644e0, -1.7328679513998632735e-1)}, {FN (arctan), ARG(-2.0e+00,1.0e+00), RES(-1.1780972450961724644e0, 1.7328679513998632735e-1)}, {FN (arctan), ARG(-2.0e+00,-1.0e+00), RES(-1.1780972450961724644e0, -1.7328679513998632735e-1)}, {FN (arctan), ARG(2.0e+00,2.0e+00), RES(1.3112232696716351433e0, 2.3887786125685909036e-1)}, {FN (arctan), ARG(2.0e+00,-2.0e+00), RES(1.3112232696716351433e0, -2.3887786125685909036e-1)}, {FN (arctan), ARG(-2.0e+00,2.0e+00), RES(-1.3112232696716351433e0, 2.3887786125685909036e-1)}, {FN (arctan), ARG(-2.0e+00,-2.0e+00), RES(-1.3112232696716351433e0, -2.3887786125685909036e-1)}, {FN (arctan), ARG(2.0e+00,8.3886080e+06), RES(1.5707963267948681975e0, 1.1920928955077503843e-7)}, {FN (arctan), ARG(2.0e+00,-8.3886080e+06), RES(1.5707963267948681975e0, -1.1920928955077503843e-7)}, {FN (arctan), ARG(-2.0e+00,8.3886080e+06), RES(-1.5707963267948681975e0, 1.1920928955077503843e-7)}, {FN (arctan), ARG(-2.0e+00,-8.3886080e+06), RES(-1.5707963267948681975e0, -1.1920928955077503843e-7)}, {FN (arctan), ARG(8.3886080e+06,0.0e+00), RES(1.5707962075856070685e0, 0.0)}, {FN (arctan), ARG(-8.3886080e+06,0.0e+00), RES(-1.5707962075856070685e0, 0.0)}, {FN (arctan), ARG(8.3886080e+06,1.19209289550781250e-07), RES(1.5707962075856070685e0, 1.6940658945085766040e-21)}, {FN (arctan), ARG(8.3886080e+06,-1.19209289550781250e-07), RES(1.5707962075856070685e0, -1.6940658945085766040e-21)}, {FN (arctan), ARG(-8.3886080e+06,1.19209289550781250e-07), RES(-1.5707962075856070685e0, 1.6940658945085766040e-21)}, {FN (arctan), ARG(-8.3886080e+06,-1.19209289550781250e-07), RES(-1.5707962075856070685e0, -1.6940658945085766040e-21)}, {FN (arctan), ARG(8.3886080e+06,5.0e-01), RES(1.5707962075856070685e0, 7.1054273576008756410e-15)}, {FN (arctan), ARG(8.3886080e+06,-5.0e-01), RES(1.5707962075856070685e0, -7.1054273576008756410e-15)}, {FN (arctan), ARG(-8.3886080e+06,5.0e-01), RES(-1.5707962075856070685e0, 7.1054273576008756410e-15)}, {FN (arctan), ARG(-8.3886080e+06,-5.0e-01), RES(-1.5707962075856070685e0, -7.1054273576008756410e-15)}, {FN (arctan), ARG(8.3886080e+06,1.0e+00), RES(1.5707962075856070685e0, 1.4210854715201599821e-14)}, {FN (arctan), ARG(8.3886080e+06,-1.0e+00), RES(1.5707962075856070685e0, -1.4210854715201599821e-14)}, {FN (arctan), ARG(-8.3886080e+06,1.0e+00), RES(-1.5707962075856070685e0, 1.4210854715201599821e-14)}, {FN (arctan), ARG(-8.3886080e+06,-1.0e+00), RES(-1.5707962075856070685e0, -1.4210854715201599821e-14)}, {FN (arctan), ARG(8.3886080e+06,2.0e+00), RES(1.5707962075856070685e0, 2.8421709430401987951e-14)}, {FN (arctan), ARG(8.3886080e+06,-2.0e+00), RES(1.5707962075856070685e0, -2.8421709430401987951e-14)}, {FN (arctan), ARG(-8.3886080e+06,2.0e+00), RES(-1.5707962075856070685e0, 2.8421709430401987951e-14)}, {FN (arctan), ARG(-8.3886080e+06,-2.0e+00), RES(-1.5707962075856070685e0, -2.8421709430401987951e-14)}, {FN (arctan), ARG(8.3886080e+06,8.3886080e+06), RES(1.5707962671902518438e0, 5.9604644775390483828e-8)}, {FN (arctan), ARG(8.3886080e+06,-8.3886080e+06), RES(1.5707962671902518438e0, -5.9604644775390483828e-8)}, {FN (arctan), ARG(-8.3886080e+06,8.3886080e+06), RES(-1.5707962671902518438e0, 5.9604644775390483828e-8)}, {FN (arctan), ARG(-8.3886080e+06,-8.3886080e+06), RES(-1.5707962671902518438e0, -5.9604644775390483828e-8)}, {FN (sinh), ARG(0.0e+00,-3.45266983001243932001e-04), RES(0, -3.4526697614140534807e-4)}, {FN (sinh), ARG(0.0e+00,3.45266983001243932001e-04), RES(0, 3.4526697614140534807e-4)}, {FN (sinh), ARG(0.0e+00,1.57045105981189525579e+00), RES(0, 9.9999994039535581669e-1)}, {FN (sinh), ARG(0.0e+00,-1.57045105981189525579e+00), RES(0, -9.9999994039535581669e-1)}, {FN (sinh), ARG(0.0e+00,1.57114159377789786021e+00), RES(0, 9.9999994039535581673e-1)}, {FN (sinh), ARG(0.0e+00,-1.57114159377789786021e+00), RES(0, -9.9999994039535581673e-1)}, {FN (sinh), ARG(0.0e+00,3.14124738660679181379e+00), RES(0, 3.4526697614158608860e-4)}, {FN (sinh), ARG(0.0e+00,-3.14124738660679181379e+00), RES(0, -3.4526697614158608860e-4)}, {FN (sinh), ARG(0.0e+00,3.14193792057279441821e+00), RES(0, -3.4526697614134115926e-4)}, {FN (sinh), ARG(0.0e+00,-3.14193792057279441821e+00), RES(0, 3.4526697614134115926e-4)}, {FN (sinh), ARG(0.0e+00,4.71204371340168837179e+00), RES(0, -9.9999994039535581664e-1)}, {FN (sinh), ARG(0.0e+00,-4.71204371340168837179e+00), RES(0, 9.9999994039535581664e-1)}, {FN (sinh), ARG(0.0e+00,4.71273424736769097620e+00), RES(0, -9.9999994039535581677e-1)}, {FN (sinh), ARG(0.0e+00,-4.71273424736769097620e+00), RES(0, 9.9999994039535581677e-1)}, {FN (sinh), ARG(0.0e+00,6.28284004019658492979e+00), RES(0, -3.4526697614170855328e-4)}, {FN (sinh), ARG(0.0e+00,-6.28284004019658492979e+00), RES(0, 3.4526697614170855328e-4)}, {FN (sinh), ARG(0.0e+00,6.28353057416258753420e+00), RES(0, 3.4526697614121869459e-4)}, {FN (sinh), ARG(0.0e+00,-6.28353057416258753420e+00), RES(0, -3.4526697614121869459e-4)}, {FN (sinh), ARG(0.0e+00,9.42443269378637893396e+00), RES(0, 3.4526697614094283958e-4)}, {FN (sinh), ARG(0.0e+00,-9.42443269378637893396e+00), RES(0, -3.4526697614094283958e-4)}, {FN (sinh), ARG(0.0e+00,9.42512322775237976202e+00), RES(0, -3.4526697614020805155e-4)}, {FN (sinh), ARG(0.0e+00,-9.42512322775237976202e+00), RES(0, 3.4526697614020805155e-4)}, {FN (sinh), ARG(1.19209289550781250e-07,-3.45266983001243932001e-04), RES(1.1920928244535424533e-7, -3.4526697614140780134e-4)}, {FN (sinh), ARG(1.19209289550781250e-07,3.45266983001243932001e-04), RES(1.1920928244535424533e-7, 3.4526697614140780134e-4)}, {FN (sinh), ARG(-1.19209289550781250e-07,-3.45266983001243932001e-04), RES(-1.1920928244535424533e-7, -3.4526697614140780134e-4)}, {FN (sinh), ARG(-1.19209289550781250e-07,3.45266983001243932001e-04), RES(-1.1920928244535424533e-7, 3.4526697614140780134e-4)}, {FN (sinh), ARG(1.19209289550781250e-07,1.57045105981189525579e+00), RES(4.1159030931177815679e-11, 9.9999994039536292211e-1)}, {FN (sinh), ARG(1.19209289550781250e-07,-1.57045105981189525579e+00), RES(4.1159030931177815679e-11, -9.9999994039536292211e-1)}, {FN (sinh), ARG(-1.19209289550781250e-07,1.57045105981189525579e+00), RES(-4.1159030931177815679e-11, 9.9999994039536292211e-1)}, {FN (sinh), ARG(-1.19209289550781250e-07,-1.57045105981189525579e+00), RES(-4.1159030931177815679e-11, -9.9999994039536292211e-1)}, {FN (sinh), ARG(1.19209289550781250e-07,1.57114159377789786021e+00), RES(-4.1159030931163216752e-11, 9.9999994039536292216e-1)}, {FN (sinh), ARG(1.19209289550781250e-07,-1.57114159377789786021e+00), RES(-4.1159030931163216752e-11, -9.9999994039536292216e-1)}, {FN (sinh), ARG(-1.19209289550781250e-07,1.57114159377789786021e+00), RES(4.1159030931163216752e-11, 9.9999994039536292216e-1)}, {FN (sinh), ARG(-1.19209289550781250e-07,-1.57114159377789786021e+00), RES(4.1159030931163216752e-11, -9.9999994039536292216e-1)}, {FN (sinh), ARG(1.19209289550781250e-07,3.14124738660679181379e+00), RES(-1.1920928244535424532e-7, 3.4526697614158854187e-4)}, {FN (sinh), ARG(1.19209289550781250e-07,-3.14124738660679181379e+00), RES(-1.1920928244535424532e-7, -3.4526697614158854187e-4)}, {FN (sinh), ARG(-1.19209289550781250e-07,3.14124738660679181379e+00), RES(1.1920928244535424532e-7, 3.4526697614158854187e-4)}, {FN (sinh), ARG(-1.19209289550781250e-07,-3.14124738660679181379e+00), RES(1.1920928244535424532e-7, -3.4526697614158854187e-4)}, {FN (sinh), ARG(1.19209289550781250e-07,3.14193792057279441821e+00), RES(-1.1920928244535424533e-7, -3.4526697614134361253e-4)}, {FN (sinh), ARG(1.19209289550781250e-07,-3.14193792057279441821e+00), RES(-1.1920928244535424533e-7, 3.4526697614134361253e-4)}, {FN (sinh), ARG(-1.19209289550781250e-07,3.14193792057279441821e+00), RES(1.1920928244535424533e-7, -3.4526697614134361253e-4)}, {FN (sinh), ARG(-1.19209289550781250e-07,-3.14193792057279441821e+00), RES(1.1920928244535424533e-7, 3.4526697614134361253e-4)}, {FN (sinh), ARG(1.19209289550781250e-07,4.71204371340168837179e+00), RES(-4.1159030931192414605e-11, -9.9999994039536292207e-1)}, {FN (sinh), ARG(1.19209289550781250e-07,-4.71204371340168837179e+00), RES(-4.1159030931192414605e-11, 9.9999994039536292207e-1)}, {FN (sinh), ARG(-1.19209289550781250e-07,4.71204371340168837179e+00), RES(4.1159030931192414605e-11, -9.9999994039536292207e-1)}, {FN (sinh), ARG(-1.19209289550781250e-07,-4.71204371340168837179e+00), RES(4.1159030931192414605e-11, 9.9999994039536292207e-1)}, {FN (sinh), ARG(1.19209289550781250e-07,4.71273424736769097620e+00), RES(4.1159030931148617825e-11, -9.9999994039536292220e-1)}, {FN (sinh), ARG(1.19209289550781250e-07,-4.71273424736769097620e+00), RES(4.1159030931148617825e-11, 9.9999994039536292220e-1)}, {FN (sinh), ARG(-1.19209289550781250e-07,4.71273424736769097620e+00), RES(-4.1159030931148617825e-11, -9.9999994039536292220e-1)}, {FN (sinh), ARG(-1.19209289550781250e-07,-4.71273424736769097620e+00), RES(-4.1159030931148617825e-11, 9.9999994039536292220e-1)}, {FN (sinh), ARG(1.19209289550781250e-07,6.28284004019658492979e+00), RES(1.1920928244535424532e-7, -3.4526697614171100655e-4)}, {FN (sinh), ARG(1.19209289550781250e-07,-6.28284004019658492979e+00), RES(1.1920928244535424532e-7, 3.4526697614171100655e-4)}, {FN (sinh), ARG(-1.19209289550781250e-07,6.28284004019658492979e+00), RES(-1.1920928244535424532e-7, -3.4526697614171100655e-4)}, {FN (sinh), ARG(-1.19209289550781250e-07,-6.28284004019658492979e+00), RES(-1.1920928244535424532e-7, 3.4526697614171100655e-4)}, {FN (sinh), ARG(1.19209289550781250e-07,6.28353057416258753420e+00), RES(1.1920928244535424534e-7, 3.4526697614122114786e-4)}, {FN (sinh), ARG(1.19209289550781250e-07,-6.28353057416258753420e+00), RES(1.1920928244535424534e-7, -3.4526697614122114786e-4)}, {FN (sinh), ARG(-1.19209289550781250e-07,6.28353057416258753420e+00), RES(-1.1920928244535424534e-7, 3.4526697614122114786e-4)}, {FN (sinh), ARG(-1.19209289550781250e-07,-6.28353057416258753420e+00), RES(-1.1920928244535424534e-7, -3.4526697614122114786e-4)}, {FN (sinh), ARG(1.19209289550781250e-07,9.42443269378637893396e+00), RES(-1.1920928244535424535e-7, 3.4526697614094529285e-4)}, {FN (sinh), ARG(1.19209289550781250e-07,-9.42443269378637893396e+00), RES(-1.1920928244535424535e-7, -3.4526697614094529285e-4)}, {FN (sinh), ARG(-1.19209289550781250e-07,9.42443269378637893396e+00), RES(1.1920928244535424535e-7, 3.4526697614094529285e-4)}, {FN (sinh), ARG(-1.19209289550781250e-07,-9.42443269378637893396e+00), RES(1.1920928244535424535e-7, -3.4526697614094529285e-4)}, {FN (sinh), ARG(1.19209289550781250e-07,9.42512322775237976202e+00), RES(-1.1920928244535424538e-7, -3.4526697614021050482e-4)}, {FN (sinh), ARG(1.19209289550781250e-07,-9.42512322775237976202e+00), RES(-1.1920928244535424538e-7, 3.4526697614021050482e-4)}, {FN (sinh), ARG(-1.19209289550781250e-07,9.42512322775237976202e+00), RES(1.1920928244535424538e-7, -3.4526697614021050482e-4)}, {FN (sinh), ARG(-1.19209289550781250e-07,-9.42512322775237976202e+00), RES(1.1920928244535424538e-7, 3.4526697614021050482e-4)}, {FN (sinh), ARG(5.0e-01,-3.45266983001243932001e-04), RES(5.2109527443404709209e-1, -3.8933200722534065172e-4)}, {FN (sinh), ARG(5.0e-01,3.45266983001243932001e-04), RES(5.2109527443404709209e-1, 3.8933200722534065172e-4)}, {FN (sinh), ARG(-5.0e-01,-3.45266983001243932001e-04), RES(-5.2109527443404709209e-1, -3.8933200722534065172e-4)}, {FN (sinh), ARG(-5.0e-01,3.45266983001243932001e-04), RES(-5.2109527443404709209e-1, 3.8933200722534065172e-4)}, {FN (sinh), ARG(5.0e-01,1.57045105981189525579e+00), RES(1.7991700040937027667e-4, 1.1276258979946363572e0)}, {FN (sinh), ARG(5.0e-01,-1.57045105981189525579e+00), RES(1.7991700040937027667e-4, -1.1276258979946363572e0)}, {FN (sinh), ARG(-5.0e-01,1.57045105981189525579e+00), RES(-1.7991700040937027667e-4, 1.1276258979946363572e0)}, {FN (sinh), ARG(-5.0e-01,-1.57045105981189525579e+00), RES(-1.7991700040937027667e-4, -1.1276258979946363572e0)}, {FN (sinh), ARG(5.0e-01,1.57114159377789786021e+00), RES(-1.7991700040930646090e-4, 1.1276258979946363573e0)}, {FN (sinh), ARG(5.0e-01,-1.57114159377789786021e+00), RES(-1.7991700040930646090e-4, -1.1276258979946363573e0)}, {FN (sinh), ARG(-5.0e-01,1.57114159377789786021e+00), RES(1.7991700040930646090e-4, 1.1276258979946363573e0)}, {FN (sinh), ARG(-5.0e-01,-1.57114159377789786021e+00), RES(1.7991700040930646090e-4, -1.1276258979946363573e0)}, {FN (sinh), ARG(5.0e-01,3.14124738660679181379e+00), RES(-5.2109527443404709206e-1, 3.8933200722554445944e-4)}, {FN (sinh), ARG(5.0e-01,-3.14124738660679181379e+00), RES(-5.2109527443404709206e-1, -3.8933200722554445944e-4)}, {FN (sinh), ARG(-5.0e-01,3.14124738660679181379e+00), RES(5.2109527443404709206e-1, 3.8933200722554445944e-4)}, {FN (sinh), ARG(-5.0e-01,-3.14124738660679181379e+00), RES(5.2109527443404709206e-1, -3.8933200722554445944e-4)}, {FN (sinh), ARG(5.0e-01,3.14193792057279441821e+00), RES(-5.2109527443404709211e-1, -3.8933200722526827075e-4)}, {FN (sinh), ARG(5.0e-01,-3.14193792057279441821e+00), RES(-5.2109527443404709211e-1, 3.8933200722526827075e-4)}, {FN (sinh), ARG(-5.0e-01,3.14193792057279441821e+00), RES(5.2109527443404709211e-1, -3.8933200722526827075e-4)}, {FN (sinh), ARG(-5.0e-01,-3.14193792057279441821e+00), RES(5.2109527443404709211e-1, 3.8933200722526827075e-4)}, {FN (sinh), ARG(5.0e-01,4.71204371340168837179e+00), RES(-1.7991700040943409243e-4, -1.1276258979946363572e0)}, {FN (sinh), ARG(5.0e-01,-4.71204371340168837179e+00), RES(-1.7991700040943409243e-4, 1.1276258979946363572e0)}, {FN (sinh), ARG(-5.0e-01,4.71204371340168837179e+00), RES(1.7991700040943409243e-4, -1.1276258979946363572e0)}, {FN (sinh), ARG(-5.0e-01,-4.71204371340168837179e+00), RES(1.7991700040943409243e-4, 1.1276258979946363572e0)}, {FN (sinh), ARG(5.0e-01,4.71273424736769097620e+00), RES(1.7991700040924264514e-4, -1.1276258979946363573e0)}, {FN (sinh), ARG(5.0e-01,-4.71273424736769097620e+00), RES(1.7991700040924264514e-4, 1.1276258979946363573e0)}, {FN (sinh), ARG(-5.0e-01,4.71273424736769097620e+00), RES(-1.7991700040924264514e-4, -1.1276258979946363573e0)}, {FN (sinh), ARG(-5.0e-01,-4.71273424736769097620e+00), RES(-1.7991700040924264514e-4, 1.1276258979946363573e0)}, {FN (sinh), ARG(5.0e-01,6.28284004019658492979e+00), RES(5.2109527443404709204e-1, -3.8933200722568255379e-4)}, {FN (sinh), ARG(5.0e-01,-6.28284004019658492979e+00), RES(5.2109527443404709204e-1, 3.8933200722568255379e-4)}, {FN (sinh), ARG(-5.0e-01,6.28284004019658492979e+00), RES(-5.2109527443404709204e-1, -3.8933200722568255379e-4)}, {FN (sinh), ARG(-5.0e-01,-6.28284004019658492979e+00), RES(-5.2109527443404709204e-1, 3.8933200722568255379e-4)}, {FN (sinh), ARG(5.0e-01,6.28353057416258753420e+00), RES(5.2109527443404709213e-1, 3.8933200722513017641e-4)}, {FN (sinh), ARG(5.0e-01,-6.28353057416258753420e+00), RES(5.2109527443404709213e-1, -3.8933200722513017641e-4)}, {FN (sinh), ARG(-5.0e-01,6.28353057416258753420e+00), RES(-5.2109527443404709213e-1, 3.8933200722513017641e-4)}, {FN (sinh), ARG(-5.0e-01,-6.28353057416258753420e+00), RES(-5.2109527443404709213e-1, -3.8933200722513017641e-4)}, {FN (sinh), ARG(5.0e-01,9.42443269378637893396e+00), RES(-5.2109527443404709218e-1, 3.8933200722481911514e-4)}, {FN (sinh), ARG(5.0e-01,-9.42443269378637893396e+00), RES(-5.2109527443404709218e-1, -3.8933200722481911514e-4)}, {FN (sinh), ARG(-5.0e-01,9.42443269378637893396e+00), RES(5.2109527443404709218e-1, 3.8933200722481911514e-4)}, {FN (sinh), ARG(-5.0e-01,-9.42443269378637893396e+00), RES(5.2109527443404709218e-1, -3.8933200722481911514e-4)}, {FN (sinh), ARG(5.0e-01,9.42512322775237976202e+00), RES(-5.2109527443404709231e-1, -3.8933200722399054908e-4)}, {FN (sinh), ARG(5.0e-01,-9.42512322775237976202e+00), RES(-5.2109527443404709231e-1, 3.8933200722399054908e-4)}, {FN (sinh), ARG(-5.0e-01,9.42512322775237976202e+00), RES(5.2109527443404709231e-1, -3.8933200722399054908e-4)}, {FN (sinh), ARG(-5.0e-01,-9.42512322775237976202e+00), RES(5.2109527443404709231e-1, 3.8933200722399054908e-4)}, {FN (sinh), ARG(1.0e+00,-3.45266983001243932001e-04), RES(1.1752011235963524660e0, -5.3277478472501939236e-4)}, {FN (sinh), ARG(1.0e+00,3.45266983001243932001e-04), RES(1.1752011235963524660e0, 5.3277478472501939236e-4)}, {FN (sinh), ARG(-1.0e+00,-3.45266983001243932001e-04), RES(-1.1752011235963524660e0, -5.3277478472501939236e-4)}, {FN (sinh), ARG(-1.0e+00,3.45266983001243932001e-04), RES(-1.1752011235963524660e0, 5.3277478472501939236e-4)}, {FN (sinh), ARG(1.0e+00,1.57045105981189525579e+00), RES(4.0575816248730593018e-4, 1.5430805428404715942e0)}, {FN (sinh), ARG(1.0e+00,-1.57045105981189525579e+00), RES(4.0575816248730593018e-4, -1.5430805428404715942e0)}, {FN (sinh), ARG(-1.0e+00,1.57045105981189525579e+00), RES(-4.0575816248730593018e-4, 1.5430805428404715942e0)}, {FN (sinh), ARG(-1.0e+00,-1.57045105981189525579e+00), RES(-4.0575816248730593018e-4, -1.5430805428404715942e0)}, {FN (sinh), ARG(1.0e+00,1.57114159377789786021e+00), RES(-4.0575816248716200955e-4, 1.5430805428404715942e0)}, {FN (sinh), ARG(1.0e+00,-1.57114159377789786021e+00), RES(-4.0575816248716200955e-4, -1.5430805428404715942e0)}, {FN (sinh), ARG(-1.0e+00,1.57114159377789786021e+00), RES(4.0575816248716200955e-4, 1.5430805428404715942e0)}, {FN (sinh), ARG(-1.0e+00,-1.57114159377789786021e+00), RES(4.0575816248716200955e-4, -1.5430805428404715942e0)}, {FN (sinh), ARG(1.0e+00,3.14124738660679181379e+00), RES(-1.1752011235963524659e0, 5.3277478472529828958e-4)}, {FN (sinh), ARG(1.0e+00,-3.14124738660679181379e+00), RES(-1.1752011235963524659e0, -5.3277478472529828958e-4)}, {FN (sinh), ARG(-1.0e+00,3.14124738660679181379e+00), RES(1.1752011235963524659e0, 5.3277478472529828958e-4)}, {FN (sinh), ARG(-1.0e+00,-3.14124738660679181379e+00), RES(1.1752011235963524659e0, -5.3277478472529828958e-4)}, {FN (sinh), ARG(1.0e+00,3.14193792057279441821e+00), RES(-1.1752011235963524660e0, -5.3277478472492034385e-4)}, {FN (sinh), ARG(1.0e+00,-3.14193792057279441821e+00), RES(-1.1752011235963524660e0, 5.3277478472492034385e-4)}, {FN (sinh), ARG(-1.0e+00,3.14193792057279441821e+00), RES(1.1752011235963524660e0, -5.3277478472492034385e-4)}, {FN (sinh), ARG(-1.0e+00,-3.14193792057279441821e+00), RES(1.1752011235963524660e0, 5.3277478472492034385e-4)}, {FN (sinh), ARG(1.0e+00,4.71204371340168837179e+00), RES(-4.0575816248744985081e-4, -1.5430805428404715941e0)}, {FN (sinh), ARG(1.0e+00,-4.71204371340168837179e+00), RES(-4.0575816248744985081e-4, 1.5430805428404715941e0)}, {FN (sinh), ARG(-1.0e+00,4.71204371340168837179e+00), RES(4.0575816248744985081e-4, -1.5430805428404715941e0)}, {FN (sinh), ARG(-1.0e+00,-4.71204371340168837179e+00), RES(4.0575816248744985081e-4, 1.5430805428404715941e0)}, {FN (sinh), ARG(1.0e+00,4.71273424736769097620e+00), RES(4.0575816248701808892e-4, -1.5430805428404715943e0)}, {FN (sinh), ARG(1.0e+00,-4.71273424736769097620e+00), RES(4.0575816248701808892e-4, 1.5430805428404715943e0)}, {FN (sinh), ARG(-1.0e+00,4.71273424736769097620e+00), RES(-4.0575816248701808892e-4, -1.5430805428404715943e0)}, {FN (sinh), ARG(-1.0e+00,-4.71273424736769097620e+00), RES(-4.0575816248701808892e-4, 1.5430805428404715943e0)}, {FN (sinh), ARG(1.0e+00,6.28284004019658492979e+00), RES(1.1752011235963524659e0, -5.3277478472548726245e-4)}, {FN (sinh), ARG(1.0e+00,-6.28284004019658492979e+00), RES(1.1752011235963524659e0, 5.3277478472548726245e-4)}, {FN (sinh), ARG(-1.0e+00,6.28284004019658492979e+00), RES(-1.1752011235963524659e0, -5.3277478472548726245e-4)}, {FN (sinh), ARG(-1.0e+00,-6.28284004019658492979e+00), RES(-1.1752011235963524659e0, 5.3277478472548726245e-4)}, {FN (sinh), ARG(1.0e+00,6.28353057416258753420e+00), RES(1.1752011235963524661e0, 5.3277478472473137099e-4)}, {FN (sinh), ARG(1.0e+00,-6.28353057416258753420e+00), RES(1.1752011235963524661e0, -5.3277478472473137099e-4)}, {FN (sinh), ARG(-1.0e+00,6.28353057416258753420e+00), RES(-1.1752011235963524661e0, 5.3277478472473137099e-4)}, {FN (sinh), ARG(-1.0e+00,-6.28353057416258753420e+00), RES(-1.1752011235963524661e0, -5.3277478472473137099e-4)}, {FN (sinh), ARG(1.0e+00,9.42443269378637893396e+00), RES(-1.1752011235963524662e0, 5.3277478472430570447e-4)}, {FN (sinh), ARG(1.0e+00,-9.42443269378637893396e+00), RES(-1.1752011235963524662e0, -5.3277478472430570447e-4)}, {FN (sinh), ARG(-1.0e+00,9.42443269378637893396e+00), RES(1.1752011235963524662e0, 5.3277478472430570447e-4)}, {FN (sinh), ARG(-1.0e+00,-9.42443269378637893396e+00), RES(1.1752011235963524662e0, -5.3277478472430570447e-4)}, {FN (sinh), ARG(1.0e+00,9.42512322775237976202e+00), RES(-1.1752011235963524665e0, -5.3277478472317186729e-4)}, {FN (sinh), ARG(1.0e+00,-9.42512322775237976202e+00), RES(-1.1752011235963524665e0, 5.3277478472317186729e-4)}, {FN (sinh), ARG(-1.0e+00,9.42512322775237976202e+00), RES(1.1752011235963524665e0, -5.3277478472317186729e-4)}, {FN (sinh), ARG(-1.0e+00,-9.42512322775237976202e+00), RES(1.1752011235963524665e0, 5.3277478472317186729e-4)}, {FN (sinh), ARG(2.0e+00,-3.45266983001243932001e-04), RES(3.6268601916692946556e0, -1.2989619299126701883e-3)}, {FN (sinh), ARG(2.0e+00,3.45266983001243932001e-04), RES(3.6268601916692946556e0, 1.2989619299126701883e-3)}, {FN (sinh), ARG(-2.0e+00,-3.45266983001243932001e-04), RES(-3.6268601916692946556e0, -1.2989619299126701883e-3)}, {FN (sinh), ARG(-2.0e+00,3.45266983001243932001e-04), RES(-3.6268601916692946556e0, 1.2989619299126701883e-3)}, {FN (sinh), ARG(2.0e+00,1.57045105981189525579e+00), RES(1.2522351259047577385e-3, 3.7621954668392959445e0)}, {FN (sinh), ARG(2.0e+00,-1.57045105981189525579e+00), RES(1.2522351259047577385e-3, -3.7621954668392959445e0)}, {FN (sinh), ARG(-2.0e+00,1.57045105981189525579e+00), RES(-1.2522351259047577385e-3, 3.7621954668392959445e0)}, {FN (sinh), ARG(-2.0e+00,-1.57045105981189525579e+00), RES(-1.2522351259047577385e-3, -3.7621954668392959445e0)}, {FN (sinh), ARG(2.0e+00,1.57114159377789786021e+00), RES(-1.2522351259043135762e-3, 3.7621954668392959447e0)}, {FN (sinh), ARG(2.0e+00,-1.57114159377789786021e+00), RES(-1.2522351259043135762e-3, -3.7621954668392959447e0)}, {FN (sinh), ARG(-2.0e+00,1.57114159377789786021e+00), RES(1.2522351259043135762e-3, 3.7621954668392959447e0)}, {FN (sinh), ARG(-2.0e+00,-1.57114159377789786021e+00), RES(1.2522351259043135762e-3, -3.7621954668392959447e0)}, {FN (sinh), ARG(2.0e+00,3.14124738660679181379e+00), RES(-3.6268601916692946553e0, 1.2989619299133501696e-3)}, {FN (sinh), ARG(2.0e+00,-3.14124738660679181379e+00), RES(-3.6268601916692946553e0, -1.2989619299133501696e-3)}, {FN (sinh), ARG(-2.0e+00,3.14124738660679181379e+00), RES(3.6268601916692946553e0, 1.2989619299133501696e-3)}, {FN (sinh), ARG(-2.0e+00,-3.14124738660679181379e+00), RES(3.6268601916692946553e0, -1.2989619299133501696e-3)}, {FN (sinh), ARG(2.0e+00,3.14193792057279441821e+00), RES(-3.6268601916692946556e0, -1.2989619299124286975e-3)}, {FN (sinh), ARG(2.0e+00,-3.14193792057279441821e+00), RES(-3.6268601916692946556e0, 1.2989619299124286975e-3)}, {FN (sinh), ARG(-2.0e+00,3.14193792057279441821e+00), RES(3.6268601916692946556e0, -1.2989619299124286975e-3)}, {FN (sinh), ARG(-2.0e+00,-3.14193792057279441821e+00), RES(3.6268601916692946556e0, 1.2989619299124286975e-3)}, {FN (sinh), ARG(2.0e+00,4.71204371340168837179e+00), RES(-1.2522351259052019007e-3, -3.7621954668392959444e0)}, {FN (sinh), ARG(2.0e+00,-4.71204371340168837179e+00), RES(-1.2522351259052019007e-3, 3.7621954668392959444e0)}, {FN (sinh), ARG(-2.0e+00,4.71204371340168837179e+00), RES(1.2522351259052019007e-3, -3.7621954668392959444e0)}, {FN (sinh), ARG(-2.0e+00,-4.71204371340168837179e+00), RES(1.2522351259052019007e-3, 3.7621954668392959444e0)}, {FN (sinh), ARG(2.0e+00,4.71273424736769097620e+00), RES(1.2522351259038694139e-3, -3.7621954668392959448e0)}, {FN (sinh), ARG(2.0e+00,-4.71273424736769097620e+00), RES(1.2522351259038694139e-3, 3.7621954668392959448e0)}, {FN (sinh), ARG(-2.0e+00,4.71273424736769097620e+00), RES(-1.2522351259038694139e-3, -3.7621954668392959448e0)}, {FN (sinh), ARG(-2.0e+00,-4.71273424736769097620e+00), RES(-1.2522351259038694139e-3, 3.7621954668392959448e0)}, {FN (sinh), ARG(2.0e+00,6.28284004019658492979e+00), RES(3.6268601916692946552e0, -1.2989619299138109057e-3)}, {FN (sinh), ARG(2.0e+00,-6.28284004019658492979e+00), RES(3.6268601916692946552e0, 1.2989619299138109057e-3)}, {FN (sinh), ARG(-2.0e+00,6.28284004019658492979e+00), RES(-3.6268601916692946552e0, -1.2989619299138109057e-3)}, {FN (sinh), ARG(-2.0e+00,-6.28284004019658492979e+00), RES(-3.6268601916692946552e0, 1.2989619299138109057e-3)}, {FN (sinh), ARG(2.0e+00,6.28353057416258753420e+00), RES(3.6268601916692946558e0, 1.2989619299119679614e-3)}, {FN (sinh), ARG(2.0e+00,-6.28353057416258753420e+00), RES(3.6268601916692946558e0, -1.2989619299119679614e-3)}, {FN (sinh), ARG(-2.0e+00,6.28353057416258753420e+00), RES(-3.6268601916692946558e0, 1.2989619299119679614e-3)}, {FN (sinh), ARG(-2.0e+00,-6.28353057416258753420e+00), RES(-3.6268601916692946558e0, -1.2989619299119679614e-3)}, {FN (sinh), ARG(2.0e+00,9.42443269378637893396e+00), RES(-3.6268601916692946561e0, 1.2989619299109301409e-3)}, {FN (sinh), ARG(2.0e+00,-9.42443269378637893396e+00), RES(-3.6268601916692946561e0, -1.2989619299109301409e-3)}, {FN (sinh), ARG(-2.0e+00,9.42443269378637893396e+00), RES(3.6268601916692946561e0, 1.2989619299109301409e-3)}, {FN (sinh), ARG(-2.0e+00,-9.42443269378637893396e+00), RES(3.6268601916692946561e0, -1.2989619299109301409e-3)}, {FN (sinh), ARG(2.0e+00,9.42512322775237976202e+00), RES(-3.6268601916692946571e0, -1.2989619299081657245e-3)}, {FN (sinh), ARG(2.0e+00,-9.42512322775237976202e+00), RES(-3.6268601916692946571e0, 1.2989619299081657245e-3)}, {FN (sinh), ARG(-2.0e+00,9.42512322775237976202e+00), RES(3.6268601916692946571e0, -1.2989619299081657245e-3)}, {FN (sinh), ARG(-2.0e+00,-9.42512322775237976202e+00), RES(3.6268601916692946571e0, 1.2989619299081657245e-3)}, {FN (cosh), ARG(0.0e+00,-3.45266983001243932001e-04), RES(9.9999994039535581673e-1, 0.0)}, {FN (cosh), ARG(0.0e+00,3.45266983001243932001e-04), RES(9.9999994039535581673e-1, 0.0)}, {FN (cosh), ARG(0.0e+00,1.57045105981189525579e+00), RES(3.4526697614152485627e-4, 0.0)}, {FN (cosh), ARG(0.0e+00,-1.57045105981189525579e+00), RES(3.4526697614152485627e-4, 0.0)}, {FN (cosh), ARG(0.0e+00,1.57114159377789786021e+00), RES(-3.4526697614140239160e-4, 0.0)}, {FN (cosh), ARG(0.0e+00,-1.57114159377789786021e+00), RES(-3.4526697614140239160e-4, 0.0)}, {FN (cosh), ARG(0.0e+00,3.14124738660679181379e+00), RES(-9.9999994039535581667e-1, 0.0)}, {FN (cosh), ARG(0.0e+00,-3.14124738660679181379e+00), RES(-9.9999994039535581667e-1, 0.0)}, {FN (cosh), ARG(0.0e+00,3.14193792057279441821e+00), RES(-9.9999994039535581675e-1, 0.0)}, {FN (cosh), ARG(0.0e+00,-3.14193792057279441821e+00), RES(-9.9999994039535581675e-1, 0.0)}, {FN (cosh), ARG(0.0e+00,4.71204371340168837179e+00), RES(-3.4526697614164732094e-4, 0.0)}, {FN (cosh), ARG(0.0e+00,-4.71204371340168837179e+00), RES(-3.4526697614164732094e-4, 0.0)}, {FN (cosh), ARG(0.0e+00,4.71273424736769097620e+00), RES(3.4526697614127992692e-4, 0.0)}, {FN (cosh), ARG(0.0e+00,-4.71273424736769097620e+00), RES(3.4526697614127992692e-4, 0.0)}, {FN (cosh), ARG(0.0e+00,6.28284004019658492979e+00), RES(9.9999994039535581662e-1, 0.0)}, {FN (cosh), ARG(0.0e+00,-6.28284004019658492979e+00), RES(9.9999994039535581662e-1, 0.0)}, {FN (cosh), ARG(0.0e+00,6.28353057416258753420e+00), RES(9.9999994039535581679e-1, 0.0)}, {FN (cosh), ARG(0.0e+00,-6.28353057416258753420e+00), RES(9.9999994039535581679e-1, 0.0)}, {FN (cosh), ARG(0.0e+00,9.42443269378637893396e+00), RES(-9.9999994039535581689e-1, 0.0)}, {FN (cosh), ARG(0.0e+00,-9.42443269378637893396e+00), RES(-9.9999994039535581689e-1, 0.0)}, {FN (cosh), ARG(0.0e+00,9.42512322775237976202e+00), RES(-9.9999994039535581714e-1, 0.0)}, {FN (cosh), ARG(0.0e+00,-9.42512322775237976202e+00), RES(-9.9999994039535581714e-1, 0.0)}, {FN (cosh), ARG(1.19209289550781250e-07,-3.45266983001243932001e-04), RES(9.9999994039536292216e-1, -4.1159030931163569191e-11)}, {FN (cosh), ARG(1.19209289550781250e-07,3.45266983001243932001e-04), RES(9.9999994039536292216e-1, 4.1159030931163569191e-11)}, {FN (cosh), ARG(-1.19209289550781250e-07,-3.45266983001243932001e-04), RES(9.9999994039536292216e-1, 4.1159030931163569191e-11)}, {FN (cosh), ARG(-1.19209289550781250e-07,3.45266983001243932001e-04), RES(9.9999994039536292216e-1, -4.1159030931163569191e-11)}, {FN (cosh), ARG(1.19209289550781250e-07,1.57045105981189525579e+00), RES(3.4526697614152730954e-4, 1.1920928244535424532e-7)}, {FN (cosh), ARG(1.19209289550781250e-07,-1.57045105981189525579e+00), RES(3.4526697614152730954e-4, -1.1920928244535424532e-7)}, {FN (cosh), ARG(-1.19209289550781250e-07,1.57045105981189525579e+00), RES(3.4526697614152730954e-4, -1.1920928244535424532e-7)}, {FN (cosh), ARG(-1.19209289550781250e-07,-1.57045105981189525579e+00), RES(3.4526697614152730954e-4, 1.1920928244535424532e-7)}, {FN (cosh), ARG(1.19209289550781250e-07,1.57114159377789786021e+00), RES(-3.4526697614140484486e-4, 1.1920928244535424533e-7)}, {FN (cosh), ARG(1.19209289550781250e-07,-1.57114159377789786021e+00), RES(-3.4526697614140484486e-4, -1.1920928244535424533e-7)}, {FN (cosh), ARG(-1.19209289550781250e-07,1.57114159377789786021e+00), RES(-3.4526697614140484486e-4, -1.1920928244535424533e-7)}, {FN (cosh), ARG(-1.19209289550781250e-07,-1.57114159377789786021e+00), RES(-3.4526697614140484486e-4, 1.1920928244535424533e-7)}, {FN (cosh), ARG(1.19209289550781250e-07,3.14124738660679181379e+00), RES(-9.9999994039536292209e-1, 4.1159030931185115142e-11)}, {FN (cosh), ARG(1.19209289550781250e-07,-3.14124738660679181379e+00), RES(-9.9999994039536292209e-1, -4.1159030931185115142e-11)}, {FN (cosh), ARG(-1.19209289550781250e-07,3.14124738660679181379e+00), RES(-9.9999994039536292209e-1, -4.1159030931185115142e-11)}, {FN (cosh), ARG(-1.19209289550781250e-07,-3.14124738660679181379e+00), RES(-9.9999994039536292209e-1, 4.1159030931185115142e-11)}, {FN (cosh), ARG(1.19209289550781250e-07,3.14193792057279441821e+00), RES(-9.9999994039536292218e-1, -4.1159030931155917289e-11)}, {FN (cosh), ARG(1.19209289550781250e-07,-3.14193792057279441821e+00), RES(-9.9999994039536292218e-1, 4.1159030931155917289e-11)}, {FN (cosh), ARG(-1.19209289550781250e-07,3.14193792057279441821e+00), RES(-9.9999994039536292218e-1, 4.1159030931155917289e-11)}, {FN (cosh), ARG(-1.19209289550781250e-07,-3.14193792057279441821e+00), RES(-9.9999994039536292218e-1, -4.1159030931155917289e-11)}, {FN (cosh), ARG(1.19209289550781250e-07,4.71204371340168837179e+00), RES(-3.4526697614164977421e-4, -1.1920928244535424532e-7)}, {FN (cosh), ARG(1.19209289550781250e-07,-4.71204371340168837179e+00), RES(-3.4526697614164977421e-4, 1.1920928244535424532e-7)}, {FN (cosh), ARG(-1.19209289550781250e-07,4.71204371340168837179e+00), RES(-3.4526697614164977421e-4, 1.1920928244535424532e-7)}, {FN (cosh), ARG(-1.19209289550781250e-07,-4.71204371340168837179e+00), RES(-3.4526697614164977421e-4, -1.1920928244535424532e-7)}, {FN (cosh), ARG(1.19209289550781250e-07,4.71273424736769097620e+00), RES(3.4526697614128238019e-4, -1.1920928244535424533e-7)}, {FN (cosh), ARG(1.19209289550781250e-07,-4.71273424736769097620e+00), RES(3.4526697614128238019e-4, 1.1920928244535424533e-7)}, {FN (cosh), ARG(-1.19209289550781250e-07,4.71273424736769097620e+00), RES(3.4526697614128238019e-4, 1.1920928244535424533e-7)}, {FN (cosh), ARG(-1.19209289550781250e-07,-4.71273424736769097620e+00), RES(3.4526697614128238019e-4, -1.1920928244535424533e-7)}, {FN (cosh), ARG(1.19209289550781250e-07,6.28284004019658492979e+00), RES(9.9999994039536292205e-1, -4.1159030931199714069e-11)}, {FN (cosh), ARG(1.19209289550781250e-07,-6.28284004019658492979e+00), RES(9.9999994039536292205e-1, 4.1159030931199714069e-11)}, {FN (cosh), ARG(-1.19209289550781250e-07,6.28284004019658492979e+00), RES(9.9999994039536292205e-1, 4.1159030931199714069e-11)}, {FN (cosh), ARG(-1.19209289550781250e-07,-6.28284004019658492979e+00), RES(9.9999994039536292205e-1, -4.1159030931199714069e-11)}, {FN (cosh), ARG(1.19209289550781250e-07,6.28353057416258753420e+00), RES(9.9999994039536292222e-1, 4.1159030931141318362e-11)}, {FN (cosh), ARG(1.19209289550781250e-07,-6.28353057416258753420e+00), RES(9.9999994039536292222e-1, -4.1159030931141318362e-11)}, {FN (cosh), ARG(-1.19209289550781250e-07,6.28353057416258753420e+00), RES(9.9999994039536292222e-1, -4.1159030931141318362e-11)}, {FN (cosh), ARG(-1.19209289550781250e-07,-6.28353057416258753420e+00), RES(9.9999994039536292222e-1, 4.1159030931141318362e-11)}, {FN (cosh), ARG(1.19209289550781250e-07,9.42443269378637893396e+00), RES(-9.9999994039536292231e-1, 4.1159030931108433883e-11)}, {FN (cosh), ARG(1.19209289550781250e-07,-9.42443269378637893396e+00), RES(-9.9999994039536292231e-1, -4.1159030931108433883e-11)}, {FN (cosh), ARG(-1.19209289550781250e-07,9.42443269378637893396e+00), RES(-9.9999994039536292231e-1, -4.1159030931108433883e-11)}, {FN (cosh), ARG(-1.19209289550781250e-07,-9.42443269378637893396e+00), RES(-9.9999994039536292231e-1, 4.1159030931108433883e-11)}, {FN (cosh), ARG(1.19209289550781250e-07,9.42512322775237976202e+00), RES(-9.9999994039536292257e-1, -4.1159030931020840323e-11)}, {FN (cosh), ARG(1.19209289550781250e-07,-9.42512322775237976202e+00), RES(-9.9999994039536292257e-1, 4.1159030931020840323e-11)}, {FN (cosh), ARG(-1.19209289550781250e-07,9.42512322775237976202e+00), RES(-9.9999994039536292257e-1, 4.1159030931020840323e-11)}, {FN (cosh), ARG(-1.19209289550781250e-07,-9.42512322775237976202e+00), RES(-9.9999994039536292257e-1, -4.1159030931020840323e-11)}, {FN (cosh), ARG(5.0e-01,-3.45266983001243932001e-04), RES(1.1276258979946363573e0, -1.7991700040930800151e-4)}, {FN (cosh), ARG(5.0e-01,3.45266983001243932001e-04), RES(1.1276258979946363573e0, 1.7991700040930800151e-4)}, {FN (cosh), ARG(-5.0e-01,-3.45266983001243932001e-04), RES(1.1276258979946363573e0, 1.7991700040930800151e-4)}, {FN (cosh), ARG(-5.0e-01,3.45266983001243932001e-04), RES(1.1276258979946363573e0, -1.7991700040930800151e-4)}, {FN (cosh), ARG(5.0e-01,1.57045105981189525579e+00), RES(3.8933200722547541227e-4, 5.2109527443404709207e-1)}, {FN (cosh), ARG(5.0e-01,-1.57045105981189525579e+00), RES(3.8933200722547541227e-4, -5.2109527443404709207e-1)}, {FN (cosh), ARG(-5.0e-01,1.57045105981189525579e+00), RES(3.8933200722547541227e-4, -5.2109527443404709207e-1)}, {FN (cosh), ARG(-5.0e-01,-1.57045105981189525579e+00), RES(3.8933200722547541227e-4, 5.2109527443404709207e-1)}, {FN (cosh), ARG(5.0e-01,1.57114159377789786021e+00), RES(-3.8933200722533731792e-4, 5.2109527443404709209e-1)}, {FN (cosh), ARG(5.0e-01,-1.57114159377789786021e+00), RES(-3.8933200722533731792e-4, -5.2109527443404709209e-1)}, {FN (cosh), ARG(-5.0e-01,1.57114159377789786021e+00), RES(-3.8933200722533731792e-4, -5.2109527443404709209e-1)}, {FN (cosh), ARG(-5.0e-01,-1.57114159377789786021e+00), RES(-3.8933200722533731792e-4, 5.2109527443404709209e-1)}, {FN (cosh), ARG(5.0e-01,3.14124738660679181379e+00), RES(-1.1276258979946363572e0, 1.7991700040940218455e-4)}, {FN (cosh), ARG(5.0e-01,-3.14124738660679181379e+00), RES(-1.1276258979946363572e0, -1.7991700040940218455e-4)}, {FN (cosh), ARG(-5.0e-01,3.14124738660679181379e+00), RES(-1.1276258979946363572e0, -1.7991700040940218455e-4)}, {FN (cosh), ARG(-5.0e-01,-3.14124738660679181379e+00), RES(-1.1276258979946363572e0, 1.7991700040940218455e-4)}, {FN (cosh), ARG(5.0e-01,3.14193792057279441821e+00), RES(-1.1276258979946363573e0, -1.7991700040927455302e-4)}, {FN (cosh), ARG(5.0e-01,-3.14193792057279441821e+00), RES(-1.1276258979946363573e0, 1.7991700040927455302e-4)}, {FN (cosh), ARG(-5.0e-01,3.14193792057279441821e+00), RES(-1.1276258979946363573e0, 1.7991700040927455302e-4)}, {FN (cosh), ARG(-5.0e-01,-3.14193792057279441821e+00), RES(-1.1276258979946363573e0, -1.7991700040927455302e-4)}, {FN (cosh), ARG(5.0e-01,4.71204371340168837179e+00), RES(-3.8933200722561350661e-4, -5.2109527443404709205e-1)}, {FN (cosh), ARG(5.0e-01,-4.71204371340168837179e+00), RES(-3.8933200722561350661e-4, 5.2109527443404709205e-1)}, {FN (cosh), ARG(-5.0e-01,4.71204371340168837179e+00), RES(-3.8933200722561350661e-4, 5.2109527443404709205e-1)}, {FN (cosh), ARG(-5.0e-01,-4.71204371340168837179e+00), RES(-3.8933200722561350661e-4, -5.2109527443404709205e-1)}, {FN (cosh), ARG(5.0e-01,4.71273424736769097620e+00), RES(3.8933200722519922358e-4, -5.2109527443404709212e-1)}, {FN (cosh), ARG(5.0e-01,-4.71273424736769097620e+00), RES(3.8933200722519922358e-4, 5.2109527443404709212e-1)}, {FN (cosh), ARG(-5.0e-01,4.71273424736769097620e+00), RES(3.8933200722519922358e-4, 5.2109527443404709212e-1)}, {FN (cosh), ARG(-5.0e-01,-4.71273424736769097620e+00), RES(3.8933200722519922358e-4, -5.2109527443404709212e-1)}, {FN (cosh), ARG(5.0e-01,6.28284004019658492979e+00), RES(1.1276258979946363572e0, -1.7991700040946600032e-4)}, {FN (cosh), ARG(5.0e-01,-6.28284004019658492979e+00), RES(1.1276258979946363572e0, 1.7991700040946600032e-4)}, {FN (cosh), ARG(-5.0e-01,6.28284004019658492979e+00), RES(1.1276258979946363572e0, 1.7991700040946600032e-4)}, {FN (cosh), ARG(-5.0e-01,-6.28284004019658492979e+00), RES(1.1276258979946363572e0, -1.7991700040946600032e-4)}, {FN (cosh), ARG(5.0e-01,6.28353057416258753420e+00), RES(1.1276258979946363574e0, 1.7991700040921073725e-4)}, {FN (cosh), ARG(5.0e-01,-6.28353057416258753420e+00), RES(1.1276258979946363574e0, -1.7991700040921073725e-4)}, {FN (cosh), ARG(-5.0e-01,6.28353057416258753420e+00), RES(1.1276258979946363574e0, -1.7991700040921073725e-4)}, {FN (cosh), ARG(-5.0e-01,-6.28353057416258753420e+00), RES(1.1276258979946363574e0, 1.7991700040921073725e-4)}, {FN (cosh), ARG(5.0e-01,9.42443269378637893396e+00), RES(-1.1276258979946363575e0, 1.7991700040906699050e-4)}, {FN (cosh), ARG(5.0e-01,-9.42443269378637893396e+00), RES(-1.1276258979946363575e0, -1.7991700040906699050e-4)}, {FN (cosh), ARG(-5.0e-01,9.42443269378637893396e+00), RES(-1.1276258979946363575e0, -1.7991700040906699050e-4)}, {FN (cosh), ARG(-5.0e-01,-9.42443269378637893396e+00), RES(-1.1276258979946363575e0, 1.7991700040906699050e-4)}, {FN (cosh), ARG(5.0e-01,9.42512322775237976202e+00), RES(-1.1276258979946363577e0, -1.7991700040868409591e-4)}, {FN (cosh), ARG(5.0e-01,-9.42512322775237976202e+00), RES(-1.1276258979946363577e0, 1.7991700040868409591e-4)}, {FN (cosh), ARG(-5.0e-01,9.42512322775237976202e+00), RES(-1.1276258979946363577e0, 1.7991700040868409591e-4)}, {FN (cosh), ARG(-5.0e-01,-9.42512322775237976202e+00), RES(-1.1276258979946363577e0, -1.7991700040868409591e-4)}, {FN (cosh), ARG(1.0e+00,-3.45266983001243932001e-04), RES(1.5430805428404715942e0, -4.057581624871654840e-4)}, {FN (cosh), ARG(1.0e+00,3.45266983001243932001e-04), RES(1.5430805428404715942e0, 4.057581624871654840e-4)}, {FN (cosh), ARG(-1.0e+00,-3.45266983001243932001e-04), RES(1.5430805428404715942e0, 4.057581624871654840e-4)}, {FN (cosh), ARG(-1.0e+00,3.45266983001243932001e-04), RES(1.5430805428404715942e0, -4.057581624871654840e-4)}, {FN (cosh), ARG(1.0e+00,1.57045105981189525579e+00), RES(5.3277478472520380315e-4, 1.1752011235963524659e0)}, {FN (cosh), ARG(1.0e+00,-1.57045105981189525579e+00), RES(5.3277478472520380315e-4, -1.1752011235963524659e0)}, {FN (cosh), ARG(-1.0e+00,1.57045105981189525579e+00), RES(5.3277478472520380315e-4, -1.1752011235963524659e0)}, {FN (cosh), ARG(-1.0e+00,-1.57045105981189525579e+00), RES(5.3277478472520380315e-4, 1.1752011235963524659e0)}, {FN (cosh), ARG(1.0e+00,1.57114159377789786021e+00), RES(-5.3277478472501483029e-4, 1.1752011235963524660e0)}, {FN (cosh), ARG(1.0e+00,-1.57114159377789786021e+00), RES(-5.3277478472501483029e-4, -1.1752011235963524660e0)}, {FN (cosh), ARG(-1.0e+00,1.57114159377789786021e+00), RES(-5.3277478472501483029e-4, -1.1752011235963524660e0)}, {FN (cosh), ARG(-1.0e+00,-1.57114159377789786021e+00), RES(-5.3277478472501483029e-4, 1.1752011235963524660e0)}, {FN (cosh), ARG(1.0e+00,3.14124738660679181379e+00), RES(-1.5430805428404715941e0, 4.0575816248737789049e-4)}, {FN (cosh), ARG(1.0e+00,-3.14124738660679181379e+00), RES(-1.5430805428404715941e0, -4.0575816248737789049e-4)}, {FN (cosh), ARG(-1.0e+00,3.14124738660679181379e+00), RES(-1.5430805428404715941e0, -4.0575816248737789049e-4)}, {FN (cosh), ARG(-1.0e+00,-3.14124738660679181379e+00), RES(-1.5430805428404715941e0, 4.0575816248737789049e-4)}, {FN (cosh), ARG(1.0e+00,3.14193792057279441821e+00), RES(-1.5430805428404715943e0, -4.0575816248709004923e-4)}, {FN (cosh), ARG(1.0e+00,-3.14193792057279441821e+00), RES(-1.5430805428404715943e0, 4.0575816248709004923e-4)}, {FN (cosh), ARG(-1.0e+00,3.14193792057279441821e+00), RES(-1.5430805428404715943e0, 4.0575816248709004923e-4)}, {FN (cosh), ARG(-1.0e+00,-3.14193792057279441821e+00), RES(-1.5430805428404715943e0, -4.0575816248709004923e-4)}, {FN (cosh), ARG(1.0e+00,4.71204371340168837179e+00), RES(-5.3277478472539277601e-4, -1.1752011235963524659e0)}, {FN (cosh), ARG(1.0e+00,-4.71204371340168837179e+00), RES(-5.3277478472539277601e-4, 1.1752011235963524659e0)}, {FN (cosh), ARG(-1.0e+00,4.71204371340168837179e+00), RES(-5.3277478472539277601e-4, 1.1752011235963524659e0)}, {FN (cosh), ARG(-1.0e+00,-4.71204371340168837179e+00), RES(-5.3277478472539277601e-4, -1.1752011235963524659e0)}, {FN (cosh), ARG(1.0e+00,4.71273424736769097620e+00), RES(5.3277478472482585742e-4, -1.1752011235963524660e0)}, {FN (cosh), ARG(1.0e+00,-4.71273424736769097620e+00), RES(5.3277478472482585742e-4, 1.1752011235963524660e0)}, {FN (cosh), ARG(-1.0e+00,4.71273424736769097620e+00), RES(5.3277478472482585742e-4, 1.1752011235963524660e0)}, {FN (cosh), ARG(-1.0e+00,-4.71273424736769097620e+00), RES(5.3277478472482585742e-4, -1.1752011235963524660e0)}, {FN (cosh), ARG(1.0e+00,6.28284004019658492979e+00), RES(1.5430805428404715941e0, -4.0575816248752181112e-4)}, {FN (cosh), ARG(1.0e+00,-6.28284004019658492979e+00), RES(1.5430805428404715941e0, 4.0575816248752181112e-4)}, {FN (cosh), ARG(-1.0e+00,6.28284004019658492979e+00), RES(1.5430805428404715941e0, 4.0575816248752181112e-4)}, {FN (cosh), ARG(-1.0e+00,-6.28284004019658492979e+00), RES(1.5430805428404715941e0, -4.0575816248752181112e-4)}, {FN (cosh), ARG(1.0e+00,6.28353057416258753420e+00), RES(1.5430805428404715943e0, 4.0575816248694612861e-4)}, {FN (cosh), ARG(1.0e+00,-6.28353057416258753420e+00), RES(1.5430805428404715943e0, -4.0575816248694612861e-4)}, {FN (cosh), ARG(-1.0e+00,6.28353057416258753420e+00), RES(1.5430805428404715943e0, -4.0575816248694612861e-4)}, {FN (cosh), ARG(-1.0e+00,-6.28353057416258753420e+00), RES(1.5430805428404715943e0, 4.0575816248694612861e-4)}, {FN (cosh), ARG(1.0e+00,9.42443269378637893396e+00), RES(-1.5430805428404715945e0, 4.0575816248662194348e-4)}, {FN (cosh), ARG(1.0e+00,-9.42443269378637893396e+00), RES(-1.5430805428404715945e0, -4.0575816248662194348e-4)}, {FN (cosh), ARG(-1.0e+00,9.42443269378637893396e+00), RES(-1.5430805428404715945e0, -4.0575816248662194348e-4)}, {FN (cosh), ARG(-1.0e+00,-9.42443269378637893396e+00), RES(-1.5430805428404715945e0, 4.0575816248662194348e-4)}, {FN (cosh), ARG(1.0e+00,9.42512322775237976202e+00), RES(-1.5430805428404715949e0, -4.0575816248575841970e-4)}, {FN (cosh), ARG(1.0e+00,-9.42512322775237976202e+00), RES(-1.5430805428404715949e0, 4.0575816248575841970e-4)}, {FN (cosh), ARG(-1.0e+00,9.42512322775237976202e+00), RES(-1.5430805428404715949e0, 4.0575816248575841970e-4)}, {FN (cosh), ARG(-1.0e+00,-9.42512322775237976202e+00), RES(-1.5430805428404715949e0, -4.0575816248575841970e-4)}, {FN (cosh), ARG(2.0e+00,-3.45266983001243932001e-04), RES(3.7621954668392959447e0, -1.2522351259043242989e-3)}, {FN (cosh), ARG(2.0e+00,3.45266983001243932001e-04), RES(3.7621954668392959447e0, 1.2522351259043242989e-3)}, {FN (cosh), ARG(-2.0e+00,-3.45266983001243932001e-04), RES(3.7621954668392959447e0, 1.2522351259043242989e-3)}, {FN (cosh), ARG(-2.0e+00,3.45266983001243932001e-04), RES(3.7621954668392959447e0, -1.2522351259043242989e-3)}, {FN (cosh), ARG(2.0e+00,1.57045105981189525579e+00), RES(1.2989619299131198016e-3, 3.6268601916692946554e0)}, {FN (cosh), ARG(2.0e+00,-1.57045105981189525579e+00), RES(1.2989619299131198016e-3, -3.6268601916692946554e0)}, {FN (cosh), ARG(-2.0e+00,1.57045105981189525579e+00), RES(1.2989619299131198016e-3, -3.6268601916692946554e0)}, {FN (cosh), ARG(-2.0e+00,-1.57045105981189525579e+00), RES(1.2989619299131198016e-3, 3.6268601916692946554e0)}, {FN (cosh), ARG(2.0e+00,1.57114159377789786021e+00), RES(-1.2989619299126590655e-3, 3.6268601916692946556e0)}, {FN (cosh), ARG(2.0e+00,-1.57114159377789786021e+00), RES(-1.2989619299126590655e-3, -3.6268601916692946556e0)}, {FN (cosh), ARG(-2.0e+00,1.57114159377789786021e+00), RES(-1.2989619299126590655e-3, -3.6268601916692946556e0)}, {FN (cosh), ARG(-2.0e+00,-1.57114159377789786021e+00), RES(-1.2989619299126590655e-3, 3.6268601916692946556e0)}, {FN (cosh), ARG(2.0e+00,3.14124738660679181379e+00), RES(-3.7621954668392959444e0, 1.2522351259049798196e-3)}, {FN (cosh), ARG(2.0e+00,-3.14124738660679181379e+00), RES(-3.7621954668392959444e0, -1.2522351259049798196e-3)}, {FN (cosh), ARG(-2.0e+00,3.14124738660679181379e+00), RES(-3.7621954668392959444e0, -1.2522351259049798196e-3)}, {FN (cosh), ARG(-2.0e+00,-3.14124738660679181379e+00), RES(-3.7621954668392959444e0, 1.2522351259049798196e-3)}, {FN (cosh), ARG(2.0e+00,3.14193792057279441821e+00), RES(-3.7621954668392959448e0, -1.2522351259040914950e-3)}, {FN (cosh), ARG(2.0e+00,-3.14193792057279441821e+00), RES(-3.7621954668392959448e0, 1.2522351259040914950e-3)}, {FN (cosh), ARG(-2.0e+00,3.14193792057279441821e+00), RES(-3.7621954668392959448e0, 1.2522351259040914950e-3)}, {FN (cosh), ARG(-2.0e+00,-3.14193792057279441821e+00), RES(-3.7621954668392959448e0, -1.2522351259040914950e-3)}, {FN (cosh), ARG(2.0e+00,4.71204371340168837179e+00), RES(-1.2989619299135805376e-3, -3.6268601916692946552e0)}, {FN (cosh), ARG(2.0e+00,-4.71204371340168837179e+00), RES(-1.2989619299135805376e-3, 3.6268601916692946552e0)}, {FN (cosh), ARG(-2.0e+00,4.71204371340168837179e+00), RES(-1.2989619299135805376e-3, 3.6268601916692946552e0)}, {FN (cosh), ARG(-2.0e+00,-4.71204371340168837179e+00), RES(-1.2989619299135805376e-3, -3.6268601916692946552e0)}, {FN (cosh), ARG(2.0e+00,4.71273424736769097620e+00), RES(1.2989619299121983294e-3, -3.6268601916692946557e0)}, {FN (cosh), ARG(2.0e+00,-4.71273424736769097620e+00), RES(1.2989619299121983294e-3, 3.6268601916692946557e0)}, {FN (cosh), ARG(-2.0e+00,4.71273424736769097620e+00), RES(1.2989619299121983294e-3, 3.6268601916692946557e0)}, {FN (cosh), ARG(-2.0e+00,-4.71273424736769097620e+00), RES(1.2989619299121983294e-3, -3.6268601916692946557e0)}, {FN (cosh), ARG(2.0e+00,6.28284004019658492979e+00), RES(3.7621954668392959443e0, -1.2522351259054239819e-3)}, {FN (cosh), ARG(2.0e+00,-6.28284004019658492979e+00), RES(3.7621954668392959443e0, 1.2522351259054239819e-3)}, {FN (cosh), ARG(-2.0e+00,6.28284004019658492979e+00), RES(3.7621954668392959443e0, 1.2522351259054239819e-3)}, {FN (cosh), ARG(-2.0e+00,-6.28284004019658492979e+00), RES(3.7621954668392959443e0, -1.2522351259054239819e-3)}, {FN (cosh), ARG(2.0e+00,6.28353057416258753420e+00), RES(3.7621954668392959449e0, 1.2522351259036473328e-3)}, {FN (cosh), ARG(2.0e+00,-6.28353057416258753420e+00), RES(3.7621954668392959449e0, -1.2522351259036473328e-3)}, {FN (cosh), ARG(-2.0e+00,6.28353057416258753420e+00), RES(3.7621954668392959449e0, -1.2522351259036473328e-3)}, {FN (cosh), ARG(-2.0e+00,-6.28353057416258753420e+00), RES(3.7621954668392959449e0, 1.2522351259036473328e-3)}, {FN (cosh), ARG(2.0e+00,9.42443269378637893396e+00), RES(-3.7621954668392959453e0, 1.2522351259026468452e-3)}, {FN (cosh), ARG(2.0e+00,-9.42443269378637893396e+00), RES(-3.7621954668392959453e0, -1.2522351259026468452e-3)}, {FN (cosh), ARG(-2.0e+00,9.42443269378637893396e+00), RES(-3.7621954668392959453e0, -1.2522351259026468452e-3)}, {FN (cosh), ARG(-2.0e+00,-9.42443269378637893396e+00), RES(-3.7621954668392959453e0, 1.2522351259026468452e-3)}, {FN (cosh), ARG(2.0e+00,9.42512322775237976202e+00), RES(-3.7621954668392959462e0, -1.2522351258999818715e-3)}, {FN (cosh), ARG(2.0e+00,-9.42512322775237976202e+00), RES(-3.7621954668392959462e0, 1.2522351258999818715e-3)}, {FN (cosh), ARG(-2.0e+00,9.42512322775237976202e+00), RES(-3.7621954668392959462e0, 1.2522351258999818715e-3)}, {FN (cosh), ARG(-2.0e+00,-9.42512322775237976202e+00), RES(-3.7621954668392959462e0, -1.2522351258999818715e-3)}, {FN (tanh), ARG(0.0e+00,-3.45266983001243932001e-04), RES(0, -3.4526699672092183585e-4)}, {FN (tanh), ARG(0.0e+00,3.45266983001243932001e-04), RES(0, 3.4526699672092183585e-4)}, {FN (tanh), ARG(0.0e+00,1.57045105981189525579e+00), RES(0, 2.8963092606501007060e3)}, {FN (tanh), ARG(0.0e+00,-1.57045105981189525579e+00), RES(0, -2.8963092606501007060e3)}, {FN (tanh), ARG(0.0e+00,1.57114159377789786021e+00), RES(0, -2.8963092606511280143e3)}, {FN (tanh), ARG(0.0e+00,-1.57114159377789786021e+00), RES(0, 2.8963092606511280143e3)}, {FN (tanh), ARG(0.0e+00,3.14124738660679181379e+00), RES(0, -3.4526699672110257641e-4)}, {FN (tanh), ARG(0.0e+00,-3.14124738660679181379e+00), RES(0, 3.4526699672110257641e-4)}, {FN (tanh), ARG(0.0e+00,3.14193792057279441821e+00), RES(0, 3.4526699672085764703e-4)}, {FN (tanh), ARG(0.0e+00,-3.14193792057279441821e+00), RES(0, -3.4526699672085764703e-4)}, {FN (tanh), ARG(0.0e+00,4.71204371340168837179e+00), RES(0, 2.8963092606490733978e3)}, {FN (tanh), ARG(0.0e+00,-4.71204371340168837179e+00), RES(0, -2.8963092606490733978e3)}, {FN (tanh), ARG(0.0e+00,4.71273424736769097620e+00), RES(0, -2.8963092606521553225e3)}, {FN (tanh), ARG(0.0e+00,-4.71273424736769097620e+00), RES(0, 2.8963092606521553225e3)}, {FN (tanh), ARG(0.0e+00,6.28284004019658492979e+00), RES(0, -3.4526699672122504111e-4)}, {FN (tanh), ARG(0.0e+00,-6.28284004019658492979e+00), RES(0, 3.4526699672122504111e-4)}, {FN (tanh), ARG(0.0e+00,6.28353057416258753420e+00), RES(0, 3.4526699672073518233e-4)}, {FN (tanh), ARG(0.0e+00,-6.28353057416258753420e+00), RES(0, -3.4526699672073518233e-4)}, {FN (tanh), ARG(0.0e+00,9.42443269378637893396e+00), RES(0, -3.4526699672045932728e-4)}, {FN (tanh), ARG(0.0e+00,-9.42443269378637893396e+00), RES(0, 3.4526699672045932728e-4)}, {FN (tanh), ARG(0.0e+00,9.42512322775237976202e+00), RES(0, 3.4526699671972453911e-4)}, {FN (tanh), ARG(0.0e+00,-9.42512322775237976202e+00), RES(0, -3.4526699671972453911e-4)}, {FN (tanh), ARG(1.19209289550781250e-07,-3.45266983001243932001e-04), RES(1.1920930376163652989e-7, -3.4526699672091692931e-4)}, {FN (tanh), ARG(1.19209289550781250e-07,3.45266983001243932001e-04), RES(1.1920930376163652989e-7, 3.4526699672091692931e-4)}, {FN (tanh), ARG(-1.19209289550781250e-07,-3.45266983001243932001e-04), RES(-1.1920930376163652989e-7, -3.4526699672091692931e-4)}, {FN (tanh), ARG(-1.19209289550781250e-07,3.45266983001243932001e-04), RES(-1.1920930376163652989e-7, 3.4526699672091692931e-4)}, {FN (tanh), ARG(1.19209289550781250e-07,1.57045105981189525579e+00), RES(9.9999992052646305569e-1, 2.8963089153831588642e3)}, {FN (tanh), ARG(1.19209289550781250e-07,-1.57045105981189525579e+00), RES(9.9999992052646305569e-1, -2.8963089153831588642e3)}, {FN (tanh), ARG(-1.19209289550781250e-07,1.57045105981189525579e+00), RES(-9.9999992052646305569e-1, 2.8963089153831588642e3)}, {FN (tanh), ARG(-1.19209289550781250e-07,-1.57045105981189525579e+00), RES(-9.9999992052646305569e-1, -2.8963089153831588642e3)}, {FN (tanh), ARG(1.19209289550781250e-07,1.57114159377789786021e+00), RES(9.9999992052717244672e-1, -2.8963089153841861720e3)}, {FN (tanh), ARG(1.19209289550781250e-07,-1.57114159377789786021e+00), RES(9.9999992052717244672e-1, 2.8963089153841861720e3)}, {FN (tanh), ARG(-1.19209289550781250e-07,1.57114159377789786021e+00), RES(-9.9999992052717244672e-1, -2.8963089153841861720e3)}, {FN (tanh), ARG(-1.19209289550781250e-07,-1.57114159377789786021e+00), RES(-9.9999992052717244672e-1, 2.8963089153841861720e3)}, {FN (tanh), ARG(1.19209289550781250e-07,3.14124738660679181379e+00), RES(1.1920930376163652991e-7, -3.4526699672109766987e-4)}, {FN (tanh), ARG(1.19209289550781250e-07,-3.14124738660679181379e+00), RES(1.1920930376163652991e-7, 3.4526699672109766987e-4)}, {FN (tanh), ARG(-1.19209289550781250e-07,3.14124738660679181379e+00), RES(-1.1920930376163652991e-7, -3.4526699672109766987e-4)}, {FN (tanh), ARG(-1.19209289550781250e-07,-3.14124738660679181379e+00), RES(-1.1920930376163652991e-7, 3.4526699672109766987e-4)}, {FN (tanh), ARG(1.19209289550781250e-07,3.14193792057279441821e+00), RES(1.1920930376163652989e-7, 3.4526699672085274049e-4)}, {FN (tanh), ARG(1.19209289550781250e-07,-3.14193792057279441821e+00), RES(1.1920930376163652989e-7, -3.4526699672085274049e-4)}, {FN (tanh), ARG(-1.19209289550781250e-07,3.14193792057279441821e+00), RES(-1.1920930376163652989e-7, 3.4526699672085274049e-4)}, {FN (tanh), ARG(-1.19209289550781250e-07,-3.14193792057279441821e+00), RES(-1.1920930376163652989e-7, -3.4526699672085274049e-4)}, {FN (tanh), ARG(1.19209289550781250e-07,4.71204371340168837179e+00), RES(9.9999992052575366466e-1, 2.8963089153821315563e3)}, {FN (tanh), ARG(1.19209289550781250e-07,-4.71204371340168837179e+00), RES(9.9999992052575366466e-1, -2.8963089153821315563e3)}, {FN (tanh), ARG(-1.19209289550781250e-07,4.71204371340168837179e+00), RES(-9.9999992052575366466e-1, 2.8963089153821315563e3)}, {FN (tanh), ARG(-1.19209289550781250e-07,-4.71204371340168837179e+00), RES(-9.9999992052575366466e-1, -2.8963089153821315563e3)}, {FN (tanh), ARG(1.19209289550781250e-07,4.71273424736769097620e+00), RES(9.9999992052788183776e-1, -2.8963089153852134799e3)}, {FN (tanh), ARG(1.19209289550781250e-07,-4.71273424736769097620e+00), RES(9.9999992052788183776e-1, 2.8963089153852134799e3)}, {FN (tanh), ARG(-1.19209289550781250e-07,4.71273424736769097620e+00), RES(-9.9999992052788183776e-1, -2.8963089153852134799e3)}, {FN (tanh), ARG(-1.19209289550781250e-07,-4.71273424736769097620e+00), RES(-9.9999992052788183776e-1, 2.8963089153852134799e3)}, {FN (tanh), ARG(1.19209289550781250e-07,6.28284004019658492979e+00), RES(1.1920930376163652992e-7, -3.4526699672122013457e-4)}, {FN (tanh), ARG(1.19209289550781250e-07,-6.28284004019658492979e+00), RES(1.1920930376163652992e-7, 3.4526699672122013457e-4)}, {FN (tanh), ARG(-1.19209289550781250e-07,6.28284004019658492979e+00), RES(-1.1920930376163652992e-7, -3.4526699672122013457e-4)}, {FN (tanh), ARG(-1.19209289550781250e-07,-6.28284004019658492979e+00), RES(-1.1920930376163652992e-7, 3.4526699672122013457e-4)}, {FN (tanh), ARG(1.19209289550781250e-07,6.28353057416258753420e+00), RES(1.1920930376163652988e-7, 3.4526699672073027579e-4)}, {FN (tanh), ARG(1.19209289550781250e-07,-6.28353057416258753420e+00), RES(1.1920930376163652988e-7, -3.4526699672073027579e-4)}, {FN (tanh), ARG(-1.19209289550781250e-07,6.28353057416258753420e+00), RES(-1.1920930376163652988e-7, 3.4526699672073027579e-4)}, {FN (tanh), ARG(-1.19209289550781250e-07,-6.28353057416258753420e+00), RES(-1.1920930376163652988e-7, -3.4526699672073027579e-4)}, {FN (tanh), ARG(1.19209289550781250e-07,9.42443269378637893396e+00), RES(1.1920930376163652985e-7, -3.4526699672045442074e-4)}, {FN (tanh), ARG(1.19209289550781250e-07,-9.42443269378637893396e+00), RES(1.1920930376163652985e-7, 3.4526699672045442074e-4)}, {FN (tanh), ARG(-1.19209289550781250e-07,9.42443269378637893396e+00), RES(-1.1920930376163652985e-7, -3.4526699672045442074e-4)}, {FN (tanh), ARG(-1.19209289550781250e-07,-9.42443269378637893396e+00), RES(-1.1920930376163652985e-7, 3.4526699672045442074e-4)}, {FN (tanh), ARG(1.19209289550781250e-07,9.42512322775237976202e+00), RES(1.1920930376163652979e-7, 3.4526699671971963257e-4)}, {FN (tanh), ARG(1.19209289550781250e-07,-9.42512322775237976202e+00), RES(1.1920930376163652979e-7, -3.4526699671971963257e-4)}, {FN (tanh), ARG(-1.19209289550781250e-07,9.42512322775237976202e+00), RES(-1.1920930376163652979e-7, 3.4526699671971963257e-4)}, {FN (tanh), ARG(-1.19209289550781250e-07,-9.42512322775237976202e+00), RES(-1.1920930376163652979e-7, -3.4526699671971963257e-4)}, {FN (tanh), ARG(5.0e-01,-3.45266983001243932001e-04), RES(4.6211720058436229979e-1, -2.7153443992655805934e-4)}, {FN (tanh), ARG(5.0e-01,3.45266983001243932001e-04), RES(4.6211720058436229979e-1, 2.7153443992655805934e-4)}, {FN (tanh), ARG(-5.0e-01,-3.45266983001243932001e-04), RES(-4.6211720058436229979e-1, -2.7153443992655805934e-4)}, {FN (tanh), ARG(-5.0e-01,3.45266983001243932001e-04), RES(-4.6211720058436229979e-1, 2.7153443992655805934e-4)}, {FN (tanh), ARG(5.0e-01,1.57045105981189525579e+00), RES(2.1639524637389325996e0, 1.2715121175455623363e-3)}, {FN (tanh), ARG(5.0e-01,-1.57045105981189525579e+00), RES(2.1639524637389325996e0, -1.2715121175455623363e-3)}, {FN (tanh), ARG(-5.0e-01,1.57045105981189525579e+00), RES(-2.1639524637389325996e0, 1.2715121175455623363e-3)}, {FN (tanh), ARG(-5.0e-01,-1.57045105981189525579e+00), RES(-2.1639524637389325996e0, -1.2715121175455623363e-3)}, {FN (tanh), ARG(5.0e-01,1.57114159377789786021e+00), RES(2.1639524637389326002e0, -1.2715121175451113370e-3)}, {FN (tanh), ARG(5.0e-01,-1.57114159377789786021e+00), RES(2.1639524637389326002e0, 1.2715121175451113370e-3)}, {FN (tanh), ARG(-5.0e-01,1.57114159377789786021e+00), RES(-2.1639524637389326002e0, -1.2715121175451113370e-3)}, {FN (tanh), ARG(-5.0e-01,-1.57114159377789786021e+00), RES(-2.1639524637389326002e0, 1.2715121175451113370e-3)}, {FN (tanh), ARG(5.0e-01,3.14124738660679181379e+00), RES(4.6211720058436229984e-1, -2.7153443992670020234e-4)}, {FN (tanh), ARG(5.0e-01,-3.14124738660679181379e+00), RES(4.6211720058436229984e-1, 2.7153443992670020234e-4)}, {FN (tanh), ARG(-5.0e-01,3.14124738660679181379e+00), RES(-4.6211720058436229984e-1, -2.7153443992670020234e-4)}, {FN (tanh), ARG(-5.0e-01,-3.14124738660679181379e+00), RES(-4.6211720058436229984e-1, 2.7153443992670020234e-4)}, {FN (tanh), ARG(5.0e-01,3.14193792057279441821e+00), RES(4.6211720058436229978e-1, 2.7153443992650757820e-4)}, {FN (tanh), ARG(5.0e-01,-3.14193792057279441821e+00), RES(4.6211720058436229978e-1, -2.7153443992650757820e-4)}, {FN (tanh), ARG(-5.0e-01,3.14193792057279441821e+00), RES(-4.6211720058436229978e-1, 2.7153443992650757820e-4)}, {FN (tanh), ARG(-5.0e-01,-3.14193792057279441821e+00), RES(-4.6211720058436229978e-1, -2.7153443992650757820e-4)}, {FN (tanh), ARG(5.0e-01,4.71204371340168837179e+00), RES(2.1639524637389325989e0, 1.2715121175460133355e-3)}, {FN (tanh), ARG(5.0e-01,-4.71204371340168837179e+00), RES(2.1639524637389325989e0, -1.2715121175460133355e-3)}, {FN (tanh), ARG(-5.0e-01,4.71204371340168837179e+00), RES(-2.1639524637389325989e0, 1.2715121175460133355e-3)}, {FN (tanh), ARG(-5.0e-01,-4.71204371340168837179e+00), RES(-2.1639524637389325989e0, -1.2715121175460133355e-3)}, {FN (tanh), ARG(5.0e-01,4.71273424736769097620e+00), RES(2.1639524637389326009e0, -1.2715121175446603377e-3)}, {FN (tanh), ARG(5.0e-01,-4.71273424736769097620e+00), RES(2.1639524637389326009e0, 1.2715121175446603377e-3)}, {FN (tanh), ARG(-5.0e-01,4.71273424736769097620e+00), RES(-2.1639524637389326009e0, -1.2715121175446603377e-3)}, {FN (tanh), ARG(-5.0e-01,-4.71273424736769097620e+00), RES(-2.1639524637389326009e0, 1.2715121175446603377e-3)}, {FN (tanh), ARG(5.0e-01,6.28284004019658492979e+00), RES(4.6211720058436229987e-1, -2.7153443992679651442e-4)}, {FN (tanh), ARG(5.0e-01,-6.28284004019658492979e+00), RES(4.6211720058436229987e-1, 2.7153443992679651442e-4)}, {FN (tanh), ARG(-5.0e-01,6.28284004019658492979e+00), RES(-4.6211720058436229987e-1, -2.7153443992679651442e-4)}, {FN (tanh), ARG(-5.0e-01,-6.28284004019658492979e+00), RES(-4.6211720058436229987e-1, 2.7153443992679651442e-4)}, {FN (tanh), ARG(5.0e-01,6.28353057416258753420e+00), RES(4.6211720058436229974e-1, 2.7153443992641126612e-4)}, {FN (tanh), ARG(5.0e-01,-6.28353057416258753420e+00), RES(4.6211720058436229974e-1, -2.7153443992641126612e-4)}, {FN (tanh), ARG(-5.0e-01,6.28353057416258753420e+00), RES(-4.6211720058436229974e-1, 2.7153443992641126612e-4)}, {FN (tanh), ARG(-5.0e-01,-6.28353057416258753420e+00), RES(-4.6211720058436229974e-1, -2.7153443992641126612e-4)}, {FN (tanh), ARG(5.0e-01,9.42443269378637893396e+00), RES(4.6211720058436229968e-1, -2.7153443992619432056e-4)}, {FN (tanh), ARG(5.0e-01,-9.42443269378637893396e+00), RES(4.6211720058436229968e-1, 2.7153443992619432056e-4)}, {FN (tanh), ARG(-5.0e-01,9.42443269378637893396e+00), RES(-4.6211720058436229968e-1, -2.7153443992619432056e-4)}, {FN (tanh), ARG(-5.0e-01,-9.42443269378637893396e+00), RES(-4.6211720058436229968e-1, 2.7153443992619432056e-4)}, {FN (tanh), ARG(5.0e-01,9.42512322775237976202e+00), RES(4.6211720058436229949e-1, 2.7153443992561644811e-4)}, {FN (tanh), ARG(5.0e-01,-9.42512322775237976202e+00), RES(4.6211720058436229949e-1, -2.7153443992561644811e-4)}, {FN (tanh), ARG(-5.0e-01,9.42512322775237976202e+00), RES(-4.6211720058436229949e-1, 2.7153443992561644811e-4)}, {FN (tanh), ARG(-5.0e-01,-9.42512322775237976202e+00), RES(-4.6211720058436229949e-1, -2.7153443992561644811e-4)}, {FN (tanh), ARG(1.0e+00,-3.45266983001243932001e-04), RES(7.6159419408485704836e-1, -1.4500326960274960880e-4)}, {FN (tanh), ARG(1.0e+00,3.45266983001243932001e-04), RES(7.6159419408485704836e-1, 1.4500326960274960880e-4)}, {FN (tanh), ARG(-1.0e+00,-3.45266983001243932001e-04), RES(-7.6159419408485704836e-1, -1.4500326960274960880e-4)}, {FN (tanh), ARG(-1.0e+00,3.45266983001243932001e-04), RES(-7.6159419408485704836e-1, 1.4500326960274960880e-4)}, {FN (tanh), ARG(1.0e+00,1.57045105981189525579e+00), RES(1.3130351721648674823e0, 2.4999454374276273814e-4)}, {FN (tanh), ARG(1.0e+00,-1.57045105981189525579e+00), RES(1.3130351721648674823e0, -2.4999454374276273814e-4)}, {FN (tanh), ARG(-1.0e+00,1.57045105981189525579e+00), RES(-1.3130351721648674823e0, 2.4999454374276273814e-4)}, {FN (tanh), ARG(-1.0e+00,-1.57045105981189525579e+00), RES(-1.3130351721648674823e0, -2.4999454374276273814e-4)}, {FN (tanh), ARG(1.0e+00,1.57114159377789786021e+00), RES(1.3130351721648674824e0, -2.4999454374267406620e-4)}, {FN (tanh), ARG(1.0e+00,-1.57114159377789786021e+00), RES(1.3130351721648674824e0, 2.4999454374267406620e-4)}, {FN (tanh), ARG(-1.0e+00,1.57114159377789786021e+00), RES(-1.3130351721648674824e0, -2.4999454374267406620e-4)}, {FN (tanh), ARG(-1.0e+00,-1.57114159377789786021e+00), RES(-1.3130351721648674824e0, 2.4999454374267406620e-4)}, {FN (tanh), ARG(1.0e+00,3.14124738660679181379e+00), RES(7.6159419408485704840e-1, -1.4500326960282551519e-4)}, {FN (tanh), ARG(1.0e+00,-3.14124738660679181379e+00), RES(7.6159419408485704840e-1, 1.4500326960282551519e-4)}, {FN (tanh), ARG(-1.0e+00,3.14124738660679181379e+00), RES(-7.6159419408485704840e-1, -1.4500326960282551519e-4)}, {FN (tanh), ARG(-1.0e+00,-3.14124738660679181379e+00), RES(-7.6159419408485704840e-1, 1.4500326960282551519e-4)}, {FN (tanh), ARG(1.0e+00,3.14193792057279441821e+00), RES(7.6159419408485704835e-1, 1.4500326960272265115e-4)}, {FN (tanh), ARG(1.0e+00,-3.14193792057279441821e+00), RES(7.6159419408485704835e-1, -1.4500326960272265115e-4)}, {FN (tanh), ARG(-1.0e+00,3.14193792057279441821e+00), RES(-7.6159419408485704835e-1, 1.4500326960272265115e-4)}, {FN (tanh), ARG(-1.0e+00,-3.14193792057279441821e+00), RES(-7.6159419408485704835e-1, -1.4500326960272265115e-4)}, {FN (tanh), ARG(1.0e+00,4.71204371340168837179e+00), RES(1.3130351721648674822e0, 2.4999454374285141007e-4)}, {FN (tanh), ARG(1.0e+00,-4.71204371340168837179e+00), RES(1.3130351721648674822e0, -2.4999454374285141007e-4)}, {FN (tanh), ARG(-1.0e+00,4.71204371340168837179e+00), RES(-1.3130351721648674822e0, 2.4999454374285141007e-4)}, {FN (tanh), ARG(-1.0e+00,-4.71204371340168837179e+00), RES(-1.3130351721648674822e0, -2.4999454374285141007e-4)}, {FN (tanh), ARG(1.0e+00,4.71273424736769097620e+00), RES(1.3130351721648674825e0, -2.4999454374258539427e-4)}, {FN (tanh), ARG(1.0e+00,-4.71273424736769097620e+00), RES(1.3130351721648674825e0, 2.4999454374258539427e-4)}, {FN (tanh), ARG(-1.0e+00,4.71273424736769097620e+00), RES(-1.3130351721648674825e0, -2.4999454374258539427e-4)}, {FN (tanh), ARG(-1.0e+00,-4.71273424736769097620e+00), RES(-1.3130351721648674825e0, 2.4999454374258539427e-4)}, {FN (tanh), ARG(1.0e+00,6.28284004019658492979e+00), RES(7.6159419408485704843e-1, -1.4500326960287694721e-4)}, {FN (tanh), ARG(1.0e+00,-6.28284004019658492979e+00), RES(7.6159419408485704843e-1, 1.4500326960287694721e-4)}, {FN (tanh), ARG(-1.0e+00,6.28284004019658492979e+00), RES(-7.6159419408485704843e-1, -1.4500326960287694721e-4)}, {FN (tanh), ARG(-1.0e+00,-6.28284004019658492979e+00), RES(-7.6159419408485704843e-1, 1.4500326960287694721e-4)}, {FN (tanh), ARG(1.0e+00,6.28353057416258753420e+00), RES(7.6159419408485704832e-1, 1.4500326960267121913e-4)}, {FN (tanh), ARG(1.0e+00,-6.28353057416258753420e+00), RES(7.6159419408485704832e-1, -1.4500326960267121913e-4)}, {FN (tanh), ARG(-1.0e+00,6.28353057416258753420e+00), RES(-7.6159419408485704832e-1, 1.4500326960267121913e-4)}, {FN (tanh), ARG(-1.0e+00,-6.28353057416258753420e+00), RES(-7.6159419408485704832e-1, -1.4500326960267121913e-4)}, {FN (tanh), ARG(1.0e+00,9.42443269378637893396e+00), RES(7.6159419408485704826e-1, -1.4500326960255536711e-4)}, {FN (tanh), ARG(1.0e+00,-9.42443269378637893396e+00), RES(7.6159419408485704826e-1, 1.4500326960255536711e-4)}, {FN (tanh), ARG(-1.0e+00,9.42443269378637893396e+00), RES(-7.6159419408485704826e-1, -1.4500326960255536711e-4)}, {FN (tanh), ARG(-1.0e+00,-9.42443269378637893396e+00), RES(-7.6159419408485704826e-1, 1.4500326960255536711e-4)}, {FN (tanh), ARG(1.0e+00,9.42512322775237976202e+00), RES(7.6159419408485704810e-1, 1.450032696022467750e-4)}, {FN (tanh), ARG(1.0e+00,-9.42512322775237976202e+00), RES(7.6159419408485704810e-1, -1.450032696022467750e-4)}, {FN (tanh), ARG(-1.0e+00,9.42512322775237976202e+00), RES(-7.6159419408485704810e-1, 1.450032696022467750e-4)}, {FN (tanh), ARG(-1.0e+00,-9.42512322775237976202e+00), RES(-7.6159419408485704810e-1, -1.450032696022467750e-4)}, {FN (tanh), ARG(2.0e+00,-3.45266983001243932001e-04), RES(9.6402758819508310556e-1, -2.4393395410435306874e-5)}, {FN (tanh), ARG(2.0e+00,3.45266983001243932001e-04), RES(9.6402758819508310556e-1, 2.4393395410435306874e-5)}, {FN (tanh), ARG(-2.0e+00,-3.45266983001243932001e-04), RES(-9.6402758819508310556e-1, -2.4393395410435306874e-5)}, {FN (tanh), ARG(-2.0e+00,3.45266983001243932001e-04), RES(-9.6402758819508310556e-1, 2.4393395410435306874e-5)}, {FN (tanh), ARG(2.0e+00,1.57045105981189525579e+00), RES(1.0373147113268752620e0, 2.6247825506572821595e-5)}, {FN (tanh), ARG(2.0e+00,-1.57045105981189525579e+00), RES(1.0373147113268752620e0, -2.6247825506572821595e-5)}, {FN (tanh), ARG(-2.0e+00,1.57045105981189525579e+00), RES(-1.0373147113268752620e0, 2.6247825506572821595e-5)}, {FN (tanh), ARG(-2.0e+00,-1.57045105981189525579e+00), RES(-1.0373147113268752620e0, -2.6247825506572821595e-5)}, {FN (tanh), ARG(2.0e+00,1.57114159377789786021e+00), RES(1.0373147113268752620e0, -2.6247825506563511609e-5)}, {FN (tanh), ARG(2.0e+00,-1.57114159377789786021e+00), RES(1.0373147113268752620e0, 2.6247825506563511609e-5)}, {FN (tanh), ARG(-2.0e+00,1.57114159377789786021e+00), RES(-1.0373147113268752620e0, -2.6247825506563511609e-5)}, {FN (tanh), ARG(-2.0e+00,-1.57114159377789786021e+00), RES(-1.0373147113268752620e0, 2.6247825506563511609e-5)}, {FN (tanh), ARG(2.0e+00,3.14124738660679181379e+00), RES(9.6402758819508310557e-1, -2.4393395410448076340e-5)}, {FN (tanh), ARG(2.0e+00,-3.14124738660679181379e+00), RES(9.6402758819508310557e-1, 2.4393395410448076340e-5)}, {FN (tanh), ARG(-2.0e+00,3.14124738660679181379e+00), RES(-9.6402758819508310557e-1, -2.4393395410448076340e-5)}, {FN (tanh), ARG(-2.0e+00,-3.14124738660679181379e+00), RES(-9.6402758819508310557e-1, 2.4393395410448076340e-5)}, {FN (tanh), ARG(2.0e+00,3.14193792057279441821e+00), RES(9.6402758819508310556e-1, 2.4393395410430771882e-5)}, {FN (tanh), ARG(2.0e+00,-3.14193792057279441821e+00), RES(9.6402758819508310556e-1, -2.4393395410430771882e-5)}, {FN (tanh), ARG(-2.0e+00,3.14193792057279441821e+00), RES(-9.6402758819508310556e-1, 2.4393395410430771882e-5)}, {FN (tanh), ARG(-2.0e+00,-3.14193792057279441821e+00), RES(-9.6402758819508310556e-1, -2.4393395410430771882e-5)}, {FN (tanh), ARG(2.0e+00,4.71204371340168837179e+00), RES(1.0373147113268752620e0, 2.6247825506582131582e-5)}, {FN (tanh), ARG(2.0e+00,-4.71204371340168837179e+00), RES(1.0373147113268752620e0, -2.6247825506582131582e-5)}, {FN (tanh), ARG(-2.0e+00,4.71204371340168837179e+00), RES(-1.0373147113268752620e0, 2.6247825506582131582e-5)}, {FN (tanh), ARG(-2.0e+00,-4.71204371340168837179e+00), RES(-1.0373147113268752620e0, -2.6247825506582131582e-5)}, {FN (tanh), ARG(2.0e+00,4.71273424736769097620e+00), RES(1.0373147113268752620e0, -2.6247825506554201622e-5)}, {FN (tanh), ARG(2.0e+00,-4.71273424736769097620e+00), RES(1.0373147113268752620e0, 2.6247825506554201622e-5)}, {FN (tanh), ARG(-2.0e+00,4.71273424736769097620e+00), RES(-1.0373147113268752620e0, -2.6247825506554201622e-5)}, {FN (tanh), ARG(-2.0e+00,-4.71273424736769097620e+00), RES(-1.0373147113268752620e0, 2.6247825506554201622e-5)}, {FN (tanh), ARG(2.0e+00,6.28284004019658492979e+00), RES(9.6402758819508310558e-1, -2.4393395410456728569e-5)}, {FN (tanh), ARG(2.0e+00,-6.28284004019658492979e+00), RES(9.6402758819508310558e-1, 2.4393395410456728569e-5)}, {FN (tanh), ARG(-2.0e+00,6.28284004019658492979e+00), RES(-9.6402758819508310558e-1, -2.4393395410456728569e-5)}, {FN (tanh), ARG(-2.0e+00,-6.28284004019658492979e+00), RES(-9.6402758819508310558e-1, 2.4393395410456728569e-5)}, {FN (tanh), ARG(2.0e+00,6.28353057416258753420e+00), RES(9.6402758819508310555e-1, 2.4393395410422119654e-5)}, {FN (tanh), ARG(2.0e+00,-6.28353057416258753420e+00), RES(9.6402758819508310555e-1, -2.4393395410422119654e-5)}, {FN (tanh), ARG(-2.0e+00,6.28353057416258753420e+00), RES(-9.6402758819508310555e-1, 2.4393395410422119654e-5)}, {FN (tanh), ARG(-2.0e+00,-6.28353057416258753420e+00), RES(-9.6402758819508310555e-1, -2.4393395410422119654e-5)}, {FN (tanh), ARG(2.0e+00,9.42443269378637893396e+00), RES(9.6402758819508310554e-1, -2.4393395410402630273e-5)}, {FN (tanh), ARG(2.0e+00,-9.42443269378637893396e+00), RES(9.6402758819508310554e-1, 2.4393395410402630273e-5)}, {FN (tanh), ARG(-2.0e+00,9.42443269378637893396e+00), RES(-9.6402758819508310554e-1, -2.4393395410402630273e-5)}, {FN (tanh), ARG(-2.0e+00,-9.42443269378637893396e+00), RES(-9.6402758819508310554e-1, 2.4393395410402630273e-5)}, {FN (tanh), ARG(2.0e+00,9.42512322775237976202e+00), RES(9.6402758819508310550e-1, 2.439339541035071690e-5)}, {FN (tanh), ARG(2.0e+00,-9.42512322775237976202e+00), RES(9.6402758819508310550e-1, -2.439339541035071690e-5)}, {FN (tanh), ARG(-2.0e+00,9.42512322775237976202e+00), RES(-9.6402758819508310550e-1, 2.439339541035071690e-5)}, {FN (tanh), ARG(-2.0e+00,-9.42512322775237976202e+00), RES(-9.6402758819508310550e-1, -2.439339541035071690e-5)}, {FN (arcsinh), ARG(0.0e+00,0.0e+00), RES(0e0, 0.0)}, {FN (arcsinh), ARG(0.0e+00,1.19209289550781250e-07), RES(0, 1.1920928955078153234e-7)}, {FN (arcsinh), ARG(0.0e+00,-1.19209289550781250e-07), RES(0, -1.1920928955078153234e-7)}, {FN (arcsinh), ARG(0.0e+00,5.0e-01), RES(0, 5.2359877559829887308e-1)}, {FN (arcsinh), ARG(0.0e+00,-5.0e-01), RES(0, -5.2359877559829887308e-1)}, {FN (arcsinh), ARG(0.0e+00,1.0e+00), RES(0, 1.5707963267948966192e0)}, {FN (arcsinh), ARG(0.0e+00,-1.0e+00), RES(0, -1.5707963267948966192e0)}, {FN (arcsinh), ARG(0.0e+00,2.0e+00), RES(1.3169578969248167086e0, 1.5707963267948966192e0)}, {FN (arcsinh), ARG(0.0e+00,-2.0e+00), RES(-1.3169578969248167086e0, -1.5707963267948966192e0)}, {FN (arcsinh), ARG(0.0e+00,8.3886080e+06), RES(1.6635532333438683873e1, 1.5707963267948966192e0)}, {FN (arcsinh), ARG(0.0e+00,-8.3886080e+06), RES(-1.6635532333438683873e1, -1.5707963267948966192e0)}, {FN (arcsinh), ARG(1.19209289550781250e-07,0.0e+00), RES(1.1920928955078096766e-7, 0.0)}, {FN (arcsinh), ARG(-1.19209289550781250e-07,0.0e+00), RES(-1.1920928955078096766e-7, 0.0)}, {FN (arcsinh), ARG(1.19209289550781250e-07,1.19209289550781250e-07), RES(1.1920928955078181469e-7, 1.1920928955078068531e-7)}, {FN (arcsinh), ARG(1.19209289550781250e-07,-1.19209289550781250e-07), RES(1.1920928955078181469e-7, -1.1920928955078068531e-7)}, {FN (arcsinh), ARG(-1.19209289550781250e-07,1.19209289550781250e-07), RES(-1.1920928955078181469e-7, 1.1920928955078068531e-7)}, {FN (arcsinh), ARG(-1.19209289550781250e-07,-1.19209289550781250e-07), RES(-1.1920928955078181469e-7, -1.1920928955078068531e-7)}, {FN (arcsinh), ARG(1.19209289550781250e-07,5.0e-01), RES(1.3765103082409432364e-7, 5.2359877559829340332e-1)}, {FN (arcsinh), ARG(1.19209289550781250e-07,-5.0e-01), RES(1.3765103082409432364e-7, -5.2359877559829340332e-1)}, {FN (arcsinh), ARG(-1.19209289550781250e-07,5.0e-01), RES(-1.3765103082409432364e-7, 5.2359877559829340332e-1)}, {FN (arcsinh), ARG(-1.19209289550781250e-07,-5.0e-01), RES(-1.3765103082409432364e-7, -5.2359877559829340332e-1)}, {FN (arcsinh), ARG(1.19209289550781250e-07,1.0e+00), RES(3.4526698643116312881e-4, 1.5704510598153252947e0)}, {FN (arcsinh), ARG(1.19209289550781250e-07,-1.0e+00), RES(3.4526698643116312881e-4, -1.5704510598153252947e0)}, {FN (arcsinh), ARG(-1.19209289550781250e-07,1.0e+00), RES(-3.4526698643116312881e-4, 1.5704510598153252947e0)}, {FN (arcsinh), ARG(-1.19209289550781250e-07,-1.0e+00), RES(-3.4526698643116312881e-4, -1.5704510598153252947e0)}, {FN (arcsinh), ARG(1.19209289550781250e-07,2.0e+00), RES(1.3169578969248194435e0, 1.5707962579693812072e0)}, {FN (arcsinh), ARG(1.19209289550781250e-07,-2.0e+00), RES(1.3169578969248194435e0, -1.5707962579693812072e0)}, {FN (arcsinh), ARG(-1.19209289550781250e-07,2.0e+00), RES(-1.3169578969248194435e0, 1.5707962579693812072e0)}, {FN (arcsinh), ARG(-1.19209289550781250e-07,-2.0e+00), RES(-1.3169578969248194435e0, -1.5707962579693812072e0)}, {FN (arcsinh), ARG(1.19209289550781250e-07,8.3886080e+06), RES(1.6635532333438683873e1, 1.5707963267948824084e0)}, {FN (arcsinh), ARG(1.19209289550781250e-07,-8.3886080e+06), RES(1.6635532333438683873e1, -1.5707963267948824084e0)}, {FN (arcsinh), ARG(-1.19209289550781250e-07,8.3886080e+06), RES(-1.6635532333438683873e1, 1.5707963267948824084e0)}, {FN (arcsinh), ARG(-1.19209289550781250e-07,-8.3886080e+06), RES(-1.6635532333438683873e1, -1.5707963267948824084e0)}, {FN (arcsinh), ARG(5.0e-01,0.0e+00), RES(4.8121182505960344750e-1, 0.0)}, {FN (arcsinh), ARG(-5.0e-01,0.0e+00), RES(-4.8121182505960344750e-1, 0.0)}, {FN (arcsinh), ARG(5.0e-01,1.19209289550781250e-07), RES(4.8121182505960598961e-1, 1.0662402999400097805e-7)}, {FN (arcsinh), ARG(5.0e-01,-1.19209289550781250e-07), RES(4.8121182505960598961e-1, -1.0662402999400097805e-7)}, {FN (arcsinh), ARG(-5.0e-01,1.19209289550781250e-07), RES(-4.8121182505960598961e-1, 1.0662402999400097805e-7)}, {FN (arcsinh), ARG(-5.0e-01,-1.19209289550781250e-07), RES(-4.8121182505960598961e-1, -1.0662402999400097805e-7)}, {FN (arcsinh), ARG(5.0e-01,5.0e-01), RES(5.3063753095251782602e-1, 4.5227844715119068206e-1)}, {FN (arcsinh), ARG(5.0e-01,-5.0e-01), RES(5.3063753095251782602e-1, -4.5227844715119068206e-1)}, {FN (arcsinh), ARG(-5.0e-01,5.0e-01), RES(-5.3063753095251782602e-1, 4.5227844715119068206e-1)}, {FN (arcsinh), ARG(-5.0e-01,-5.0e-01), RES(-5.3063753095251782602e-1, -4.5227844715119068206e-1)}, {FN (arcsinh), ARG(5.0e-01,1.0e+00), RES(7.3285767597364526089e-1, 8.9590748120889023907e-1)}, {FN (arcsinh), ARG(5.0e-01,-1.0e+00), RES(7.3285767597364526089e-1, -8.9590748120889023907e-1)}, {FN (arcsinh), ARG(-5.0e-01,1.0e+00), RES(-7.3285767597364526089e-1, 8.9590748120889023907e-1)}, {FN (arcsinh), ARG(-5.0e-01,-1.0e+00), RES(-7.3285767597364526089e-1, -8.9590748120889023907e-1)}, {FN (arcsinh), ARG(5.0e-01,2.0e+00), RES(1.3618009008578457882e0, 1.2930420702371826591e0)}, {FN (arcsinh), ARG(5.0e-01,-2.0e+00), RES(1.3618009008578457882e0, -1.2930420702371826591e0)}, {FN (arcsinh), ARG(-5.0e-01,2.0e+00), RES(-1.3618009008578457882e0, 1.2930420702371826591e0)}, {FN (arcsinh), ARG(-5.0e-01,-2.0e+00), RES(-1.3618009008578457882e0, -1.2930420702371826591e0)}, {FN (arcsinh), ARG(5.0e-01,8.3886080e+06), RES(1.6635532333438685650e1, 1.5707962671902518438e0)}, {FN (arcsinh), ARG(5.0e-01,-8.3886080e+06), RES(1.6635532333438685650e1, -1.5707962671902518438e0)}, {FN (arcsinh), ARG(-5.0e-01,8.3886080e+06), RES(-1.6635532333438685650e1, 1.5707962671902518438e0)}, {FN (arcsinh), ARG(-5.0e-01,-8.3886080e+06), RES(-1.6635532333438685650e1, -1.5707962671902518438e0)}, {FN (arcsinh), ARG(1.0e+00,0.0e+00), RES(8.8137358701954302523e-1, 0.0)}, {FN (arcsinh), ARG(-1.0e+00,0.0e+00), RES(-8.8137358701954302523e-1, 0.0)}, {FN (arcsinh), ARG(1.0e+00,1.19209289550781250e-07), RES(8.8137358701954553738e-1, 8.4293697021788013662e-8)}, {FN (arcsinh), ARG(1.0e+00,-1.19209289550781250e-07), RES(8.8137358701954553738e-1, -8.4293697021788013662e-8)}, {FN (arcsinh), ARG(-1.0e+00,1.19209289550781250e-07), RES(-8.8137358701954553738e-1, 8.4293697021788013662e-8)}, {FN (arcsinh), ARG(-1.0e+00,-1.19209289550781250e-07), RES(-8.8137358701954553738e-1, -8.4293697021788013662e-8)}, {FN (arcsinh), ARG(1.0e+00,5.0e-01), RES(9.2613303135018242455e-1, 3.4943906285721329363e-1)}, {FN (arcsinh), ARG(1.0e+00,-5.0e-01), RES(9.2613303135018242455e-1, -3.4943906285721329363e-1)}, {FN (arcsinh), ARG(-1.0e+00,5.0e-01), RES(-9.2613303135018242455e-1, 3.4943906285721329363e-1)}, {FN (arcsinh), ARG(-1.0e+00,-5.0e-01), RES(-9.2613303135018242455e-1, -3.4943906285721329363e-1)}, {FN (arcsinh), ARG(1.0e+00,1.0e+00), RES(1.0612750619050356520e0, 6.6623943249251525510e-1)}, {FN (arcsinh), ARG(1.0e+00,-1.0e+00), RES(1.0612750619050356520e0, -6.6623943249251525510e-1)}, {FN (arcsinh), ARG(-1.0e+00,1.0e+00), RES(-1.0612750619050356520e0, 6.6623943249251525510e-1)}, {FN (arcsinh), ARG(-1.0e+00,-1.0e+00), RES(-1.0612750619050356520e0, -6.6623943249251525510e-1)}, {FN (arcsinh), ARG(1.0e+00,2.0e+00), RES(1.4693517443681852733e0, 1.0634400235777520562e0)}, {FN (arcsinh), ARG(1.0e+00,-2.0e+00), RES(1.4693517443681852733e0, -1.0634400235777520562e0)}, {FN (arcsinh), ARG(-1.0e+00,2.0e+00), RES(-1.4693517443681852733e0, 1.0634400235777520562e0)}, {FN (arcsinh), ARG(-1.0e+00,-2.0e+00), RES(-1.4693517443681852733e0, -1.0634400235777520562e0)}, {FN (arcsinh), ARG(1.0e+00,8.3886080e+06), RES(1.6635532333438690979e1, 1.5707962075856070684e0)}, {FN (arcsinh), ARG(1.0e+00,-8.3886080e+06), RES(1.6635532333438690979e1, -1.5707962075856070684e0)}, {FN (arcsinh), ARG(-1.0e+00,8.3886080e+06), RES(-1.6635532333438690979e1, 1.5707962075856070684e0)}, {FN (arcsinh), ARG(-1.0e+00,-8.3886080e+06), RES(-1.6635532333438690979e1, -1.5707962075856070684e0)}, {FN (arcsinh), ARG(2.0e+00,0.0e+00), RES(1.4436354751788103425e0, 0.0)}, {FN (arcsinh), ARG(-2.0e+00,0.0e+00), RES(-1.4436354751788103425e0, 0.0)}, {FN (arcsinh), ARG(2.0e+00,1.19209289550781250e-07), RES(1.4436354751788116136e0, 5.3312014997000413263e-8)}, {FN (arcsinh), ARG(2.0e+00,-1.19209289550781250e-07), RES(1.4436354751788116136e0, -5.3312014997000413263e-8)}, {FN (arcsinh), ARG(-2.0e+00,1.19209289550781250e-07), RES(-1.4436354751788116136e0, 5.3312014997000413263e-8)}, {FN (arcsinh), ARG(-2.0e+00,-1.19209289550781250e-07), RES(-1.4436354751788116136e0, -5.3312014997000413263e-8)}, {FN (arcsinh), ARG(2.0e+00,5.0e-01), RES(1.4657153519472905218e0, 2.2101863562288385890e-1)}, {FN (arcsinh), ARG(2.0e+00,-5.0e-01), RES(1.4657153519472905218e0, -2.2101863562288385890e-1)}, {FN (arcsinh), ARG(-2.0e+00,5.0e-01), RES(-1.4657153519472905218e0, 2.2101863562288385890e-1)}, {FN (arcsinh), ARG(-2.0e+00,-5.0e-01), RES(-1.4657153519472905218e0, -2.2101863562288385890e-1)}, {FN (arcsinh), ARG(2.0e+00,1.0e+00), RES(1.5285709194809981613e0, 4.2707858639247612548e-1)}, {FN (arcsinh), ARG(2.0e+00,-1.0e+00), RES(1.5285709194809981613e0, -4.2707858639247612548e-1)}, {FN (arcsinh), ARG(-2.0e+00,1.0e+00), RES(-1.5285709194809981613e0, 4.2707858639247612548e-1)}, {FN (arcsinh), ARG(-2.0e+00,-1.0e+00), RES(-1.5285709194809981613e0, -4.2707858639247612548e-1)}, {FN (arcsinh), ARG(2.0e+00,2.0e+00), RES(1.7343245214879664480e0, 7.5424914469804604071e-1)}, {FN (arcsinh), ARG(2.0e+00,-2.0e+00), RES(1.7343245214879664480e0, -7.5424914469804604071e-1)}, {FN (arcsinh), ARG(-2.0e+00,2.0e+00), RES(-1.7343245214879664480e0, 7.5424914469804604071e-1)}, {FN (arcsinh), ARG(-2.0e+00,-2.0e+00), RES(-1.7343245214879664480e0, -7.5424914469804604071e-1)}, {FN (arcsinh), ARG(2.0e+00,8.3886080e+06), RES(1.6635532333438712295e1, 1.5707960883763175177e0)}, {FN (arcsinh), ARG(2.0e+00,-8.3886080e+06), RES(1.6635532333438712295e1, -1.5707960883763175177e0)}, {FN (arcsinh), ARG(-2.0e+00,8.3886080e+06), RES(-1.6635532333438712295e1, 1.5707960883763175177e0)}, {FN (arcsinh), ARG(-2.0e+00,-8.3886080e+06), RES(-1.6635532333438712295e1, -1.5707960883763175177e0)}, {FN (arcsinh), ARG(8.3886080e+06,0.0e+00), RES(1.6635532333438690979e1, 0.0)}, {FN (arcsinh), ARG(-8.3886080e+06,0.0e+00), RES(-1.6635532333438690979e1, 0.0)}, {FN (arcsinh), ARG(8.3886080e+06,1.19209289550781250e-07), RES(1.6635532333438690979e1, 1.4210854715201902743e-14)}, {FN (arcsinh), ARG(8.3886080e+06,-1.19209289550781250e-07), RES(1.6635532333438690979e1, -1.4210854715201902743e-14)}, {FN (arcsinh), ARG(-8.3886080e+06,1.19209289550781250e-07), RES(-1.6635532333438690979e1, 1.4210854715201902743e-14)}, {FN (arcsinh), ARG(-8.3886080e+06,-1.19209289550781250e-07), RES(-1.6635532333438690979e1, -1.4210854715201902743e-14)}, {FN (arcsinh), ARG(8.3886080e+06,5.0e-01), RES(1.6635532333438692755e1, 5.9604644775390130897e-8)}, {FN (arcsinh), ARG(8.3886080e+06,-5.0e-01), RES(1.6635532333438692755e1, -5.9604644775390130897e-8)}, {FN (arcsinh), ARG(-8.3886080e+06,5.0e-01), RES(-1.6635532333438692755e1, 5.9604644775390130897e-8)}, {FN (arcsinh), ARG(-8.3886080e+06,-5.0e-01), RES(-1.6635532333438692755e1, -5.9604644775390130897e-8)}, {FN (arcsinh), ARG(8.3886080e+06,1.0e+00), RES(1.6635532333438698084e1, 1.1920928955077983828e-7)}, {FN (arcsinh), ARG(8.3886080e+06,-1.0e+00), RES(1.6635532333438698084e1, -1.1920928955077983828e-7)}, {FN (arcsinh), ARG(-8.3886080e+06,1.0e+00), RES(-1.6635532333438698084e1, 1.1920928955077983828e-7)}, {FN (arcsinh), ARG(-8.3886080e+06,-1.0e+00), RES(-1.6635532333438698084e1, -1.1920928955077983828e-7)}, {FN (arcsinh), ARG(8.3886080e+06,2.0e+00), RES(1.663553233343871940e1, 2.3841857910155628843e-7)}, {FN (arcsinh), ARG(8.3886080e+06,-2.0e+00), RES(1.663553233343871940e1, -2.3841857910155628843e-7)}, {FN (arcsinh), ARG(-8.3886080e+06,2.0e+00), RES(-1.663553233343871940e1, 2.3841857910155628843e-7)}, {FN (arcsinh), ARG(-8.3886080e+06,-2.0e+00), RES(-1.663553233343871940e1, -2.3841857910155628843e-7)}, {FN (arcsinh), ARG(8.3886080e+06,8.3886080e+06), RES(1.6982105923718660081e1, 7.8539816339744653326e-1)}, {FN (arcsinh), ARG(8.3886080e+06,-8.3886080e+06), RES(1.6982105923718660081e1, -7.8539816339744653326e-1)}, {FN (arcsinh), ARG(-8.3886080e+06,8.3886080e+06), RES(-1.6982105923718660081e1, 7.8539816339744653326e-1)}, {FN (arcsinh), ARG(-8.3886080e+06,-8.3886080e+06), RES(-1.6982105923718660081e1, -7.8539816339744653326e-1)}, {FN (arccosh), ARG(0.0e+00,0.0e+00), RES(0, 1.5707963267948966192e0)}, {FN (arccosh), ARG(0.0e+00,1.19209289550781250e-07), RES(1.1920928955078096766e-7, 1.5707963267948966192e0)}, {FN (arccosh), ARG(0.0e+00,-1.19209289550781250e-07), RES(1.1920928955078096766e-7, -1.5707963267948966192e0)}, {FN (arccosh), ARG(0.0e+00,5.0e-01), RES(4.8121182505960344750e-1, 1.5707963267948966192e0)}, {FN (arccosh), ARG(0.0e+00,-5.0e-01), RES(4.8121182505960344750e-1, -1.5707963267948966192e0)}, {FN (arccosh), ARG(0.0e+00,1.0e+00), RES(8.8137358701954302523e-1, 1.5707963267948966192e0)}, {FN (arccosh), ARG(0.0e+00,-1.0e+00), RES(8.8137358701954302523e-1, -1.5707963267948966192e0)}, {FN (arccosh), ARG(0.0e+00,2.0e+00), RES(1.4436354751788103425e0, 1.5707963267948966192e0)}, {FN (arccosh), ARG(0.0e+00,-2.0e+00), RES(1.4436354751788103425e0, -1.5707963267948966192e0)}, {FN (arccosh), ARG(0.0e+00,8.3886080e+06), RES(1.6635532333438690979e1, 1.5707963267948966192e0)}, {FN (arccosh), ARG(0.0e+00,-8.3886080e+06), RES(1.6635532333438690979e1, -1.5707963267948966192e0)}, {FN (arccosh), ARG(1.19209289550781250e-07,0.0e+00), RES(0, 1.5707962075856070684e0)}, {FN (arccosh), ARG(-1.19209289550781250e-07,0.0e+00), RES(0, 1.570796446004186170e0)}, {FN (arccosh), ARG(1.19209289550781250e-07,1.19209289550781250e-07), RES(1.1920928955078181469e-7, 1.5707962075856070685e0)}, {FN (arccosh), ARG(1.19209289550781250e-07,-1.19209289550781250e-07), RES(1.1920928955078181469e-7, -1.5707962075856070685e0)}, {FN (arccosh), ARG(-1.19209289550781250e-07,1.19209289550781250e-07), RES(1.1920928955078181469e-7, 1.570796446004186170e0)}, {FN (arccosh), ARG(-1.19209289550781250e-07,-1.19209289550781250e-07), RES(1.1920928955078181469e-7, -1.570796446004186170e0)}, {FN (arccosh), ARG(1.19209289550781250e-07,5.0e-01), RES(4.8121182505960598961e-1, 1.5707962201708666252e0)}, {FN (arccosh), ARG(1.19209289550781250e-07,-5.0e-01), RES(4.8121182505960598961e-1, -1.5707962201708666252e0)}, {FN (arccosh), ARG(-1.19209289550781250e-07,5.0e-01), RES(4.8121182505960598961e-1, 1.5707964334189266132e0)}, {FN (arccosh), ARG(-1.19209289550781250e-07,-5.0e-01), RES(4.8121182505960598961e-1, -1.5707964334189266132e0)}, {FN (arccosh), ARG(1.19209289550781250e-07,1.0e+00), RES(8.8137358701954553738e-1, 1.5707962425011995974e0)}, {FN (arccosh), ARG(1.19209289550781250e-07,-1.0e+00), RES(8.8137358701954553738e-1, -1.5707962425011995974e0)}, {FN (arccosh), ARG(-1.19209289550781250e-07,1.0e+00), RES(8.8137358701954553738e-1, 1.5707964110885936410e0)}, {FN (arccosh), ARG(-1.19209289550781250e-07,-1.0e+00), RES(8.8137358701954553738e-1, -1.5707964110885936410e0)}, {FN (arccosh), ARG(1.19209289550781250e-07,2.0e+00), RES(1.4436354751788116136e0, 1.5707962734828816222e0)}, {FN (arccosh), ARG(1.19209289550781250e-07,-2.0e+00), RES(1.4436354751788116136e0, -1.5707962734828816222e0)}, {FN (arccosh), ARG(-1.19209289550781250e-07,2.0e+00), RES(1.4436354751788116136e0, 1.5707963801069116162e0)}, {FN (arccosh), ARG(-1.19209289550781250e-07,-2.0e+00), RES(1.4436354751788116136e0, -1.5707963801069116162e0)}, {FN (arccosh), ARG(1.19209289550781250e-07,8.3886080e+06), RES(1.6635532333438690979e1, 1.5707963267948824084e0)}, {FN (arccosh), ARG(1.19209289550781250e-07,-8.3886080e+06), RES(1.6635532333438690979e1, -1.5707963267948824084e0)}, {FN (arccosh), ARG(-1.19209289550781250e-07,8.3886080e+06), RES(1.6635532333438690979e1, 1.5707963267949108301e0)}, {FN (arccosh), ARG(-1.19209289550781250e-07,-8.3886080e+06), RES(1.6635532333438690979e1, -1.5707963267949108301e0)}, {FN (arccosh), ARG(5.0e-01,0.0e+00), RES(0, 1.0471975511965977462e0)}, {FN (arccosh), ARG(-5.0e-01,0.0e+00), RES(0, 2.0943951023931954923e0)}, {FN (arccosh), ARG(5.0e-01,1.19209289550781250e-07), RES(1.3765103082409432364e-7, 1.0471975511966032159e0)}, {FN (arccosh), ARG(5.0e-01,-1.19209289550781250e-07), RES(1.3765103082409432364e-7, -1.0471975511966032159e0)}, {FN (arccosh), ARG(-5.0e-01,1.19209289550781250e-07), RES(1.3765103082409432364e-7, 2.0943951023931900225e0)}, {FN (arccosh), ARG(-5.0e-01,-1.19209289550781250e-07), RES(1.3765103082409432364e-7, -2.0943951023931900225e0)}, {FN (arccosh), ARG(5.0e-01,5.0e-01), RES(5.3063753095251782602e-1, 1.1185178796437059372e0)}, {FN (arccosh), ARG(5.0e-01,-5.0e-01), RES(5.3063753095251782602e-1, -1.1185178796437059372e0)}, {FN (arccosh), ARG(-5.0e-01,5.0e-01), RES(5.3063753095251782602e-1, 2.0230747739460873013e0)}, {FN (arccosh), ARG(-5.0e-01,-5.0e-01), RES(5.3063753095251782602e-1, -2.0230747739460873013e0)}, {FN (arccosh), ARG(5.0e-01,1.0e+00), RES(9.2613303135018242455e-1, 1.2213572639376833256e0)}, {FN (arccosh), ARG(5.0e-01,-1.0e+00), RES(9.2613303135018242455e-1, -1.2213572639376833256e0)}, {FN (arccosh), ARG(-5.0e-01,1.0e+00), RES(9.2613303135018242455e-1, 1.9202353896521099129e0)}, {FN (arccosh), ARG(-5.0e-01,-1.0e+00), RES(9.2613303135018242455e-1, -1.9202353896521099129e0)}, {FN (arccosh), ARG(5.0e-01,2.0e+00), RES(1.4657153519472905218e0, 1.3497776911720127603e0)}, {FN (arccosh), ARG(5.0e-01,-2.0e+00), RES(1.4657153519472905218e0, -1.3497776911720127603e0)}, {FN (arccosh), ARG(-5.0e-01,2.0e+00), RES(1.4657153519472905218e0, 1.7918149624177804781e0)}, {FN (arccosh), ARG(-5.0e-01,-2.0e+00), RES(1.4657153519472905218e0, -1.7918149624177804781e0)}, {FN (arccosh), ARG(5.0e-01,8.3886080e+06), RES(1.6635532333438692755e1, 1.5707962671902518438e0)}, {FN (arccosh), ARG(5.0e-01,-8.3886080e+06), RES(1.6635532333438692755e1, -1.5707962671902518438e0)}, {FN (arccosh), ARG(-5.0e-01,8.3886080e+06), RES(1.6635532333438692755e1, 1.5707963863995413946e0)}, {FN (arccosh), ARG(-5.0e-01,-8.3886080e+06), RES(1.6635532333438692755e1, -1.5707963863995413946e0)}, {FN (arccosh), ARG(1.0e+00,0.0e+00), RES(0e0, 0.0)}, {FN (arccosh), ARG(-1.0e+00,0.0e+00), RES(0, 3.1415926535897932385e0)}, {FN (arccosh), ARG(1.0e+00,1.19209289550781250e-07), RES(3.4526698643116312881e-4, 3.4526697957132450399e-4)}, {FN (arccosh), ARG(1.0e+00,-1.19209289550781250e-07), RES(3.4526698643116312881e-4, -3.4526697957132450399e-4)}, {FN (arccosh), ARG(-1.0e+00,1.19209289550781250e-07), RES(3.4526698643116312881e-4, 3.1412473866102219140e0)}, {FN (arccosh), ARG(-1.0e+00,-1.19209289550781250e-07), RES(3.4526698643116312881e-4, -3.1412473866102219140e0)}, {FN (arccosh), ARG(1.0e+00,5.0e-01), RES(7.3285767597364526089e-1, 6.7488884558600638016e-1)}, {FN (arccosh), ARG(1.0e+00,-5.0e-01), RES(7.3285767597364526089e-1, -6.7488884558600638016e-1)}, {FN (arccosh), ARG(-1.0e+00,5.0e-01), RES(7.3285767597364526089e-1, 2.4667038080037868583e0)}, {FN (arccosh), ARG(-1.0e+00,-5.0e-01), RES(7.3285767597364526089e-1, -2.4667038080037868583e0)}, {FN (arccosh), ARG(1.0e+00,1.0e+00), RES(1.0612750619050356520e0, 9.0455689430238136413e-1)}, {FN (arccosh), ARG(1.0e+00,-1.0e+00), RES(1.0612750619050356520e0, -9.0455689430238136413e-1)}, {FN (arccosh), ARG(-1.0e+00,1.0e+00), RES(1.0612750619050356520e0, 2.2370357592874118743e0)}, {FN (arccosh), ARG(-1.0e+00,-1.0e+00), RES(1.0612750619050356520e0, -2.2370357592874118743e0)}, {FN (arccosh), ARG(1.0e+00,2.0e+00), RES(1.5285709194809981613e0, 1.1437177404024204938e0)}, {FN (arccosh), ARG(1.0e+00,-2.0e+00), RES(1.5285709194809981613e0, -1.1437177404024204938e0)}, {FN (arccosh), ARG(-1.0e+00,2.0e+00), RES(1.5285709194809981613e0, 1.9978749131873727447e0)}, {FN (arccosh), ARG(-1.0e+00,-2.0e+00), RES(1.5285709194809981613e0, -1.9978749131873727447e0)}, {FN (arccosh), ARG(1.0e+00,8.3886080e+06), RES(1.6635532333438698084e1, 1.5707962075856070685e0)}, {FN (arccosh), ARG(1.0e+00,-8.3886080e+06), RES(1.6635532333438698084e1, -1.5707962075856070685e0)}, {FN (arccosh), ARG(-1.0e+00,8.3886080e+06), RES(1.6635532333438698084e1, 1.570796446004186170e0)}, {FN (arccosh), ARG(-1.0e+00,-8.3886080e+06), RES(1.6635532333438698084e1, -1.570796446004186170e0)}, {FN (arccosh), ARG(2.0e+00,0.0e+00), RES(1.3169578969248167086e0, 0.0)}, {FN (arccosh), ARG(-2.0e+00,0.0e+00), RES(1.3169578969248167086e0, 3.1415926535897932385e0)}, {FN (arccosh), ARG(2.0e+00,1.19209289550781250e-07), RES(1.3169578969248194435e0, 6.8825515412047433504e-8)}, {FN (arccosh), ARG(2.0e+00,-1.19209289550781250e-07), RES(1.3169578969248194435e0, -6.8825515412047433504e-8)}, {FN (arccosh), ARG(-2.0e+00,1.19209289550781250e-07), RES(1.3169578969248194435e0, 3.1415925847642778264e0)}, {FN (arccosh), ARG(-2.0e+00,-1.19209289550781250e-07), RES(1.3169578969248194435e0, -3.1415925847642778264e0)}, {FN (arccosh), ARG(2.0e+00,5.0e-01), RES(1.3618009008578457882e0, 2.7775425655771396018e-1)}, {FN (arccosh), ARG(2.0e+00,-5.0e-01), RES(1.3618009008578457882e0, -2.7775425655771396018e-1)}, {FN (arccosh), ARG(-2.0e+00,5.0e-01), RES(1.3618009008578457882e0, 2.8638383970320792783e0)}, {FN (arccosh), ARG(-2.0e+00,-5.0e-01), RES(1.3618009008578457882e0, -2.8638383970320792783e0)}, {FN (arccosh), ARG(2.0e+00,1.0e+00), RES(1.4693517443681852733e0, 5.0735630321714456304e-1)}, {FN (arccosh), ARG(2.0e+00,-1.0e+00), RES(1.4693517443681852733e0, -5.0735630321714456304e-1)}, {FN (arccosh), ARG(-2.0e+00,1.0e+00), RES(1.4693517443681852733e0, 2.6342363503726486754e0)}, {FN (arccosh), ARG(-2.0e+00,-1.0e+00), RES(1.4693517443681852733e0, -2.6342363503726486754e0)}, {FN (arccosh), ARG(2.0e+00,2.0e+00), RES(1.7343245214879664480e0, 8.1654718209685057852e-1)}, {FN (arccosh), ARG(2.0e+00,-2.0e+00), RES(1.7343245214879664480e0, -8.1654718209685057852e-1)}, {FN (arccosh), ARG(-2.0e+00,2.0e+00), RES(1.7343245214879664480e0, 2.3250454714929426599e0)}, {FN (arccosh), ARG(-2.0e+00,-2.0e+00), RES(1.7343245214879664480e0, -2.3250454714929426599e0)}, {FN (arccosh), ARG(2.0e+00,8.3886080e+06), RES(1.663553233343871940e1, 1.5707960883763175177e0)}, {FN (arccosh), ARG(2.0e+00,-8.3886080e+06), RES(1.663553233343871940e1, -1.5707960883763175177e0)}, {FN (arccosh), ARG(-2.0e+00,8.3886080e+06), RES(1.663553233343871940e1, 1.5707965652134757208e0)}, {FN (arccosh), ARG(-2.0e+00,-8.3886080e+06), RES(1.663553233343871940e1, -1.5707965652134757208e0)}, {FN (arccosh), ARG(8.3886080e+06,0.0e+00), RES(1.6635532333438683873e1, 0.0)}, {FN (arccosh), ARG(-8.3886080e+06,0.0e+00), RES(1.6635532333438683873e1, 3.1415926535897932385e0)}, {FN (arccosh), ARG(8.3886080e+06,1.19209289550781250e-07), RES(1.6635532333438683873e1, 1.4210854715202104692e-14)}, {FN (arccosh), ARG(8.3886080e+06,-1.19209289550781250e-07), RES(1.6635532333438683873e1, -1.4210854715202104692e-14)}, {FN (arccosh), ARG(-8.3886080e+06,1.19209289550781250e-07), RES(1.6635532333438683873e1, 3.1415926535897790276e0)}, {FN (arccosh), ARG(-8.3886080e+06,-1.19209289550781250e-07), RES(1.6635532333438683873e1, -3.1415926535897790276e0)}, {FN (arccosh), ARG(8.3886080e+06,5.0e-01), RES(1.6635532333438685650e1, 5.9604644775390977930e-8)}, {FN (arccosh), ARG(8.3886080e+06,-5.0e-01), RES(1.6635532333438685650e1, -5.9604644775390977930e-8)}, {FN (arccosh), ARG(-8.3886080e+06,5.0e-01), RES(1.6635532333438685650e1, 3.1415925939851484631e0)}, {FN (arccosh), ARG(-8.3886080e+06,-5.0e-01), RES(1.6635532333438685650e1, -3.1415925939851484631e0)}, {FN (arccosh), ARG(8.3886080e+06,1.0e+00), RES(1.6635532333438690979e1, 1.1920928955078153234e-7)}, {FN (arccosh), ARG(8.3886080e+06,-1.0e+00), RES(1.6635532333438690979e1, -1.1920928955078153234e-7)}, {FN (arccosh), ARG(-8.3886080e+06,1.0e+00), RES(1.6635532333438690979e1, 3.1415925343805036877e0)}, {FN (arccosh), ARG(-8.3886080e+06,-1.0e+00), RES(1.6635532333438690979e1, -3.1415925343805036877e0)}, {FN (arccosh), ARG(8.3886080e+06,2.0e+00), RES(1.6635532333438712295e1, 2.3841857910155967656e-7)}, {FN (arccosh), ARG(8.3886080e+06,-2.0e+00), RES(1.6635532333438712295e1, -2.3841857910155967656e-7)}, {FN (arccosh), ARG(-8.3886080e+06,2.0e+00), RES(1.6635532333438712295e1, 3.1415924151712141369e0)}, {FN (arccosh), ARG(-8.3886080e+06,-2.0e+00), RES(1.6635532333438712295e1, -3.1415924151712141369e0)}, {FN (arccosh), ARG(8.3886080e+06,8.3886080e+06), RES(1.6982105923718660081e1, 7.8539816339745008597e-1)}, {FN (arccosh), ARG(8.3886080e+06,-8.3886080e+06), RES(1.6982105923718660081e1, -7.8539816339745008597e-1)}, {FN (arccosh), ARG(-8.3886080e+06,8.3886080e+06), RES(1.6982105923718660081e1, 2.3561944901923431525e0)}, {FN (arccosh), ARG(-8.3886080e+06,-8.3886080e+06), RES(1.6982105923718660081e1, -2.3561944901923431525e0)}, {FN (arctanh), ARG(0.0e+00,0.0e+00), RES(0e0, 0.0)}, {FN (arctanh), ARG(0.0e+00,1.19209289550781250e-07), RES(0, 1.1920928955078068531e-7)}, {FN (arctanh), ARG(0.0e+00,-1.19209289550781250e-07), RES(0, -1.1920928955078068531e-7)}, {FN (arctanh), ARG(0.0e+00,5.0e-01), RES(0, 4.6364760900080611621e-1)}, {FN (arctanh), ARG(0.0e+00,-5.0e-01), RES(0, -4.6364760900080611621e-1)}, {FN (arctanh), ARG(0.0e+00,1.0e+00), RES(0, 7.8539816339744830962e-1)}, {FN (arctanh), ARG(0.0e+00,-1.0e+00), RES(0, -7.8539816339744830962e-1)}, {FN (arctanh), ARG(0.0e+00,2.0e+00), RES(0, 1.1071487177940905030e0)}, {FN (arctanh), ARG(0.0e+00,-2.0e+00), RES(0, -1.1071487177940905030e0)}, {FN (arctanh), ARG(0.0e+00,8.3886080e+06), RES(0, 1.5707962075856070685e0)}, {FN (arctanh), ARG(0.0e+00,-8.3886080e+06), RES(0, -1.5707962075856070685e0)}, {FN (arctanh), ARG(1.19209289550781250e-07,0.0e+00), RES(1.1920928955078181469e-7, 0.0)}, {FN (arctanh), ARG(-1.19209289550781250e-07,0.0e+00), RES(-1.1920928955078181469e-7, 0.0)}, {FN (arctanh), ARG(1.19209289550781250e-07,1.19209289550781250e-07), RES(1.1920928955078012062e-7, 1.1920928955078237938e-7)}, {FN (arctanh), ARG(1.19209289550781250e-07,-1.19209289550781250e-07), RES(1.1920928955078012062e-7, -1.1920928955078237938e-7)}, {FN (arctanh), ARG(-1.19209289550781250e-07,1.19209289550781250e-07), RES(-1.1920928955078012062e-7, 1.1920928955078237938e-7)}, {FN (arctanh), ARG(-1.19209289550781250e-07,-1.19209289550781250e-07), RES(-1.1920928955078012062e-7, -1.1920928955078237938e-7)}, {FN (arctanh), ARG(1.19209289550781250e-07,5.0e-01), RES(9.5367431640625072280e-8, 4.6364760900081066369e-1)}, {FN (arctanh), ARG(1.19209289550781250e-07,-5.0e-01), RES(9.5367431640625072280e-8, -4.6364760900081066369e-1)}, {FN (arctanh), ARG(-1.19209289550781250e-07,5.0e-01), RES(-9.5367431640625072280e-8, 4.6364760900081066369e-1)}, {FN (arctanh), ARG(-1.19209289550781250e-07,-5.0e-01), RES(-9.5367431640625072280e-8, -4.6364760900081066369e-1)}, {FN (arctanh), ARG(1.19209289550781250e-07,1.0e+00), RES(5.9604644775390483828e-8, 7.8539816339745186233e-1)}, {FN (arctanh), ARG(1.19209289550781250e-07,-1.0e+00), RES(5.9604644775390483828e-8, -7.8539816339745186233e-1)}, {FN (arctanh), ARG(-1.19209289550781250e-07,1.0e+00), RES(-5.9604644775390483828e-8, 7.8539816339745186233e-1)}, {FN (arctanh), ARG(-1.19209289550781250e-07,-1.0e+00), RES(-5.9604644775390483828e-8, -7.8539816339745186233e-1)}, {FN (arctanh), ARG(1.19209289550781250e-07,2.0e+00), RES(2.3841857910156200307e-8, 1.1071487177940916399e0)}, {FN (arctanh), ARG(1.19209289550781250e-07,-2.0e+00), RES(2.3841857910156200307e-8, -1.1071487177940916399e0)}, {FN (arctanh), ARG(-1.19209289550781250e-07,2.0e+00), RES(-2.3841857910156200307e-8, 1.1071487177940916399e0)}, {FN (arctanh), ARG(-1.19209289550781250e-07,-2.0e+00), RES(-2.3841857910156200307e-8, -1.1071487177940916399e0)}, {FN (arctanh), ARG(1.19209289550781250e-07,8.3886080e+06), RES(1.6940658945085766040e-21, 1.5707962075856070685e0)}, {FN (arctanh), ARG(1.19209289550781250e-07,-8.3886080e+06), RES(1.6940658945085766040e-21, -1.5707962075856070685e0)}, {FN (arctanh), ARG(-1.19209289550781250e-07,8.3886080e+06), RES(-1.6940658945085766040e-21, 1.5707962075856070685e0)}, {FN (arctanh), ARG(-1.19209289550781250e-07,-8.3886080e+06), RES(-1.6940658945085766040e-21, -1.5707962075856070685e0)}, {FN (arctanh), ARG(5.0e-01,0.0e+00), RES(5.4930614433405484570e-1, 0.0)}, {FN (arctanh), ARG(-5.0e-01,0.0e+00), RES(-5.4930614433405484570e-1, 0.0)}, {FN (arctanh), ARG(5.0e-01,1.19209289550781250e-07), RES(5.4930614433404221383e-1, 1.5894571940103932425e-7)}, {FN (arctanh), ARG(5.0e-01,-1.19209289550781250e-07), RES(5.4930614433404221383e-1, -1.5894571940103932425e-7)}, {FN (arctanh), ARG(-5.0e-01,1.19209289550781250e-07), RES(-5.4930614433404221383e-1, 1.5894571940103932425e-7)}, {FN (arctanh), ARG(-5.0e-01,-1.19209289550781250e-07), RES(-5.4930614433404221383e-1, -1.5894571940103932425e-7)}, {FN (arctanh), ARG(5.0e-01,5.0e-01), RES(4.0235947810852509365e-1, 5.5357435889704525151e-1)}, {FN (arctanh), ARG(5.0e-01,-5.0e-01), RES(4.0235947810852509365e-1, -5.5357435889704525151e-1)}, {FN (arctanh), ARG(-5.0e-01,5.0e-01), RES(-4.0235947810852509365e-1, 5.5357435889704525151e-1)}, {FN (arctanh), ARG(-5.0e-01,-5.0e-01), RES(-4.0235947810852509365e-1, -5.5357435889704525151e-1)}, {FN (arctanh), ARG(5.0e-01,1.0e+00), RES(2.3887786125685909036e-1, 8.4757566067082902713e-1)}, {FN (arctanh), ARG(5.0e-01,-1.0e+00), RES(2.3887786125685909036e-1, -8.4757566067082902713e-1)}, {FN (arctanh), ARG(-5.0e-01,1.0e+00), RES(-2.3887786125685909036e-1, 8.4757566067082902713e-1)}, {FN (arctanh), ARG(-5.0e-01,-1.0e+00), RES(-2.3887786125685909036e-1, -8.4757566067082902713e-1)}, {FN (arctanh), ARG(5.0e-01,2.0e+00), RES(9.6415620202996167238e-2, 1.1265564408348223487e0)}, {FN (arctanh), ARG(5.0e-01,-2.0e+00), RES(9.6415620202996167238e-2, -1.1265564408348223487e0)}, {FN (arctanh), ARG(-5.0e-01,2.0e+00), RES(-9.6415620202996167238e-2, 1.1265564408348223487e0)}, {FN (arctanh), ARG(-5.0e-01,-2.0e+00), RES(-9.6415620202996167238e-2, -1.1265564408348223487e0)}, {FN (arctanh), ARG(5.0e-01,8.3886080e+06), RES(7.1054273576008756410e-15, 1.5707962075856070685e0)}, {FN (arctanh), ARG(5.0e-01,-8.3886080e+06), RES(7.1054273576008756410e-15, -1.5707962075856070685e0)}, {FN (arctanh), ARG(-5.0e-01,8.3886080e+06), RES(-7.1054273576008756410e-15, 1.5707962075856070685e0)}, {FN (arctanh), ARG(-5.0e-01,-8.3886080e+06), RES(-7.1054273576008756410e-15, -1.5707962075856070685e0)}, {FN (arctanh), ARG(1.0e+00,1.19209289550781250e-07), RES(8.3177661667193446012e0, 7.8539819319977069731e-1)}, {FN (arctanh), ARG(1.0e+00,-1.19209289550781250e-07), RES(8.3177661667193446012e0, -7.8539819319977069731e-1)}, {FN (arctanh), ARG(-1.0e+00,1.19209289550781250e-07), RES(-8.3177661667193446012e0, 7.8539819319977069731e-1)}, {FN (arctanh), ARG(-1.0e+00,-1.19209289550781250e-07), RES(-8.3177661667193446012e0, -7.8539819319977069731e-1)}, {FN (arctanh), ARG(1.0e+00,5.0e-01), RES(7.0830333601405402006e-1, 9.0788749496088038670e-1)}, {FN (arctanh), ARG(1.0e+00,-5.0e-01), RES(7.0830333601405402006e-1, -9.0788749496088038670e-1)}, {FN (arctanh), ARG(-1.0e+00,5.0e-01), RES(-7.0830333601405402006e-1, 9.0788749496088038670e-1)}, {FN (arctanh), ARG(-1.0e+00,-5.0e-01), RES(-7.0830333601405402006e-1, -9.0788749496088038670e-1)}, {FN (arctanh), ARG(1.0e+00,1.0e+00), RES(4.0235947810852509365e-1, 1.0172219678978513677e0)}, {FN (arctanh), ARG(1.0e+00,-1.0e+00), RES(4.0235947810852509365e-1, -1.0172219678978513677e0)}, {FN (arctanh), ARG(-1.0e+00,1.0e+00), RES(-4.0235947810852509365e-1, 1.0172219678978513677e0)}, {FN (arctanh), ARG(-1.0e+00,-1.0e+00), RES(-4.0235947810852509365e-1, -1.0172219678978513677e0)}, {FN (arctanh), ARG(1.0e+00,2.0e+00), RES(1.7328679513998632735e-1, 1.1780972450961724644e0)}, {FN (arctanh), ARG(1.0e+00,-2.0e+00), RES(1.7328679513998632735e-1, -1.1780972450961724644e0)}, {FN (arctanh), ARG(-1.0e+00,2.0e+00), RES(-1.7328679513998632735e-1, 1.1780972450961724644e0)}, {FN (arctanh), ARG(-1.0e+00,-2.0e+00), RES(-1.7328679513998632735e-1, -1.1780972450961724644e0)}, {FN (arctanh), ARG(1.0e+00,8.3886080e+06), RES(1.4210854715201599821e-14, 1.5707962075856070685e0)}, {FN (arctanh), ARG(1.0e+00,-8.3886080e+06), RES(1.4210854715201599821e-14, -1.5707962075856070685e0)}, {FN (arctanh), ARG(-1.0e+00,8.3886080e+06), RES(-1.4210854715201599821e-14, 1.5707962075856070685e0)}, {FN (arctanh), ARG(-1.0e+00,-8.3886080e+06), RES(-1.4210854715201599821e-14, -1.5707962075856070685e0)}, {FN (arctanh), ARG(2.0e+00,0.0e+00), RES(5.4930614433405484570e-1, -1.5707963267948966192e0)}, {FN (arctanh), ARG(-2.0e+00,0.0e+00), RES(-5.4930614433405484570e-1, 1.5707963267948966192e0)}, {FN (arctanh), ARG(2.0e+00,1.19209289550781250e-07), RES(5.4930614433405168773e-1, 1.5707962870584667690e0)}, {FN (arctanh), ARG(2.0e+00,-1.19209289550781250e-07), RES(5.4930614433405168773e-1, -1.5707962870584667690e0)}, {FN (arctanh), ARG(-2.0e+00,1.19209289550781250e-07), RES(-5.4930614433405168773e-1, 1.5707962870584667690e0)}, {FN (arctanh), ARG(-2.0e+00,-1.19209289550781250e-07), RES(-5.4930614433405168773e-1, -1.5707962870584667690e0)}, {FN (arctanh), ARG(2.0e+00,5.0e-01), RES(5.0037000005253101744e-1, 1.4215468610018069803e0)}, {FN (arctanh), ARG(2.0e+00,-5.0e-01), RES(5.0037000005253101744e-1, -1.4215468610018069803e0)}, {FN (arctanh), ARG(-2.0e+00,5.0e-01), RES(-5.0037000005253101744e-1, 1.4215468610018069803e0)}, {FN (arctanh), ARG(-2.0e+00,-5.0e-01), RES(-5.0037000005253101744e-1, -1.4215468610018069803e0)}, {FN (arctanh), ARG(2.0e+00,1.0e+00), RES(4.0235947810852509365e-1, 1.3389725222944935611e0)}, {FN (arctanh), ARG(2.0e+00,-1.0e+00), RES(4.0235947810852509365e-1, -1.3389725222944935611e0)}, {FN (arctanh), ARG(-2.0e+00,1.0e+00), RES(-4.0235947810852509365e-1, 1.3389725222944935611e0)}, {FN (arctanh), ARG(-2.0e+00,-1.0e+00), RES(-4.0235947810852509365e-1, -1.3389725222944935611e0)}, {FN (arctanh), ARG(2.0e+00,2.0e+00), RES(2.3887786125685909036e-1, 1.3112232696716351433e0)}, {FN (arctanh), ARG(2.0e+00,-2.0e+00), RES(2.3887786125685909036e-1, -1.3112232696716351433e0)}, {FN (arctanh), ARG(-2.0e+00,2.0e+00), RES(-2.3887786125685909036e-1, 1.3112232696716351433e0)}, {FN (arctanh), ARG(-2.0e+00,-2.0e+00), RES(-2.3887786125685909036e-1, -1.3112232696716351433e0)}, {FN (arctanh), ARG(2.0e+00,8.3886080e+06), RES(2.8421709430401987951e-14, 1.5707962075856070685e0)}, {FN (arctanh), ARG(2.0e+00,-8.3886080e+06), RES(2.8421709430401987951e-14, -1.5707962075856070685e0)}, {FN (arctanh), ARG(-2.0e+00,8.3886080e+06), RES(-2.8421709430401987951e-14, 1.5707962075856070685e0)}, {FN (arctanh), ARG(-2.0e+00,-8.3886080e+06), RES(-2.8421709430401987951e-14, -1.5707962075856070685e0)}, {FN (arctanh), ARG(8.3886080e+06,0.0e+00), RES(1.1920928955078181469e-7, -1.5707963267948966192e0)}, {FN (arctanh), ARG(-8.3886080e+06,0.0e+00), RES(-1.1920928955078181469e-7, 1.5707963267948966192e0)}, {FN (arctanh), ARG(8.3886080e+06,1.19209289550781250e-07), RES(1.1920928955078181469e-7, 1.5707963267948966192e0)}, {FN (arctanh), ARG(8.3886080e+06,-1.19209289550781250e-07), RES(1.1920928955078181469e-7, -1.5707963267948966192e0)}, {FN (arctanh), ARG(-8.3886080e+06,1.19209289550781250e-07), RES(-1.1920928955078181469e-7, 1.5707963267948966192e0)}, {FN (arctanh), ARG(-8.3886080e+06,-1.19209289550781250e-07), RES(-1.1920928955078181469e-7, -1.5707963267948966192e0)}, {FN (arctanh), ARG(8.3886080e+06,5.0e-01), RES(1.1920928955078139117e-7, 1.5707963267948895138e0)}, {FN (arctanh), ARG(8.3886080e+06,-5.0e-01), RES(1.1920928955078139117e-7, -1.5707963267948895138e0)}, {FN (arctanh), ARG(-8.3886080e+06,5.0e-01), RES(-1.1920928955078139117e-7, 1.5707963267948895138e0)}, {FN (arctanh), ARG(-8.3886080e+06,-5.0e-01), RES(-1.1920928955078139117e-7, -1.5707963267948895138e0)}, {FN (arctanh), ARG(8.3886080e+06,1.0e+00), RES(1.1920928955078012062e-7, 1.5707963267948824084e0)}, {FN (arctanh), ARG(8.3886080e+06,-1.0e+00), RES(1.1920928955078012062e-7, -1.5707963267948824084e0)}, {FN (arctanh), ARG(-8.3886080e+06,1.0e+00), RES(-1.1920928955078012062e-7, 1.5707963267948824084e0)}, {FN (arctanh), ARG(-8.3886080e+06,-1.0e+00), RES(-1.1920928955078012062e-7, -1.5707963267948824084e0)}, {FN (arctanh), ARG(8.3886080e+06,2.0e+00), RES(1.1920928955077503843e-7, 1.5707963267948681975e0)}, {FN (arctanh), ARG(8.3886080e+06,-2.0e+00), RES(1.1920928955077503843e-7, -1.5707963267948681975e0)}, {FN (arctanh), ARG(-8.3886080e+06,2.0e+00), RES(-1.1920928955077503843e-7, 1.5707963267948681975e0)}, {FN (arctanh), ARG(-8.3886080e+06,-2.0e+00), RES(-1.1920928955077503843e-7, -1.5707963267948681975e0)}, {FN (arctanh), ARG(8.3886080e+06,8.3886080e+06), RES(5.9604644775390483828e-8, 1.5707962671902518438e0)}, {FN (arctanh), ARG(8.3886080e+06,-8.3886080e+06), RES(5.9604644775390483828e-8, -1.5707962671902518438e0)}, {FN (arctanh), ARG(-8.3886080e+06,8.3886080e+06), RES(-5.9604644775390483828e-8, 1.5707962671902518438e0)}, {FN (arctanh), ARG(-8.3886080e+06,-8.3886080e+06), RES(-5.9604644775390483828e-8, -1.5707962671902518438e0)}, {FN (csc), ARG(-3.45266983001243932001e-04,0.0e+00), RES(-2.8963094332845964291e3, 0.0)}, {FN (csc), ARG(3.45266983001243932001e-04,0.0e+00), RES(2.8963094332845964291e3, 0.0)}, {FN (csc), ARG(-3.45266983001243932001e-04,1.19209289550781250e-07), RES(-2.8963090880176545869e3, -9.9999986092250876926e-1)}, {FN (csc), ARG(-3.45266983001243932001e-04,-1.19209289550781250e-07), RES(-2.8963090880176545869e3, 9.9999986092250876926e-1)}, {FN (csc), ARG(3.45266983001243932001e-04,1.19209289550781250e-07), RES(2.8963090880176545869e3, -9.9999986092250876926e-1)}, {FN (csc), ARG(3.45266983001243932001e-04,-1.19209289550781250e-07), RES(2.8963090880176545869e3, 9.9999986092250876926e-1)}, {FN (csc), ARG(-3.45266983001243932001e-04,5.0e-01), RES(-1.4337901642789801243e-3, -1.9190337944739187237e0)}, {FN (csc), ARG(-3.45266983001243932001e-04,-5.0e-01), RES(-1.4337901642789801243e-3, 1.9190337944739187237e0)}, {FN (csc), ARG(3.45266983001243932001e-04,5.0e-01), RES(1.4337901642789801243e-3, -1.9190337944739187237e0)}, {FN (csc), ARG(3.45266983001243932001e-04,-5.0e-01), RES(1.4337901642789801243e-3, 1.9190337944739187237e0)}, {FN (csc), ARG(-3.45266983001243932001e-04,1.0e+00), RES(-3.8576176225198860914e-4, -8.5091800407377002734e-1)}, {FN (csc), ARG(-3.45266983001243932001e-04,-1.0e+00), RES(-3.8576176225198860914e-4, 8.5091800407377002734e-1)}, {FN (csc), ARG(3.45266983001243932001e-04,1.0e+00), RES(3.8576176225198860914e-4, -8.5091800407377002734e-1)}, {FN (csc), ARG(3.45266983001243932001e-04,-1.0e+00), RES(3.8576176225198860914e-4, 8.5091800407377002734e-1)}, {FN (csc), ARG(-3.45266983001243932001e-04,2.0e+00), RES(-9.8749461907035665386e-5, -2.7572054583883740768e-1)}, {FN (csc), ARG(-3.45266983001243932001e-04,-2.0e+00), RES(-9.8749461907035665386e-5, 2.7572054583883740768e-1)}, {FN (csc), ARG(3.45266983001243932001e-04,2.0e+00), RES(9.8749461907035665386e-5, -2.7572054583883740768e-1)}, {FN (csc), ARG(3.45266983001243932001e-04,-2.0e+00), RES(9.8749461907035665386e-5, 2.7572054583883740768e-1)}, {FN (csc), ARG(1.57045105981189525579e+00,0.0e+00), RES(1.0000000596046477360e0, 0.0)}, {FN (csc), ARG(-1.57045105981189525579e+00,0.0e+00), RES(-1.0000000596046477360e0, 0.0)}, {FN (csc), ARG(1.57045105981189525579e+00,1.19209289550781250e-07), RES(1.0000000596046406306e0, -4.1159035837716456618e-11)}, {FN (csc), ARG(1.57045105981189525579e+00,-1.19209289550781250e-07), RES(1.0000000596046406306e0, 4.1159035837716456618e-11)}, {FN (csc), ARG(-1.57045105981189525579e+00,1.19209289550781250e-07), RES(-1.0000000596046406306e0, -4.1159035837716456618e-11)}, {FN (csc), ARG(-1.57045105981189525579e+00,-1.19209289550781250e-07), RES(-1.0000000596046406306e0, 4.1159035837716456618e-11)}, {FN (csc), ARG(1.57045105981189525579e+00,5.0e-01), RES(8.8681891425248302487e-1, -1.4149533035943115868e-4)}, {FN (csc), ARG(1.57045105981189525579e+00,-5.0e-01), RES(8.8681891425248302487e-1, 1.4149533035943115868e-4)}, {FN (csc), ARG(-1.57045105981189525579e+00,5.0e-01), RES(-8.8681891425248302487e-1, -1.4149533035943115868e-4)}, {FN (csc), ARG(-1.57045105981189525579e+00,-5.0e-01), RES(-8.8681891425248302487e-1, 1.4149533035943115868e-4)}, {FN (csc), ARG(1.57045105981189525579e+00,1.0e+00), RES(6.4805426748157480499e-1, -1.7040802567657401279e-4)}, {FN (csc), ARG(1.57045105981189525579e+00,-1.0e+00), RES(6.4805426748157480499e-1, 1.7040802567657401279e-4)}, {FN (csc), ARG(-1.57045105981189525579e+00,1.0e+00), RES(-6.4805426748157480499e-1, -1.7040802567657401279e-4)}, {FN (csc), ARG(-1.57045105981189525579e+00,-1.0e+00), RES(-6.4805426748157480499e-1, 1.7040802567657401279e-4)}, {FN (csc), ARG(1.57045105981189525579e+00,2.0e+00), RES(2.6580221522968095406e-1, -8.8471445300404633228e-5)}, {FN (csc), ARG(1.57045105981189525579e+00,-2.0e+00), RES(2.6580221522968095406e-1, 8.8471445300404633228e-5)}, {FN (csc), ARG(-1.57045105981189525579e+00,2.0e+00), RES(-2.6580221522968095406e-1, -8.8471445300404633228e-5)}, {FN (csc), ARG(-1.57045105981189525579e+00,-2.0e+00), RES(-2.6580221522968095406e-1, 8.8471445300404633228e-5)}, {FN (csc), ARG(1.57114159377789786021e+00,0.0e+00), RES(1.0000000596046477360e0, 0.0)}, {FN (csc), ARG(-1.57114159377789786021e+00,0.0e+00), RES(-1.0000000596046477360e0, 0.0)}, {FN (csc), ARG(1.57114159377789786021e+00,1.19209289550781250e-07), RES(1.0000000596046406306e0, 4.1159035837701857686e-11)}, {FN (csc), ARG(1.57114159377789786021e+00,-1.19209289550781250e-07), RES(1.0000000596046406306e0, -4.1159035837701857686e-11)}, {FN (csc), ARG(-1.57114159377789786021e+00,1.19209289550781250e-07), RES(-1.0000000596046406306e0, 4.1159035837701857686e-11)}, {FN (csc), ARG(-1.57114159377789786021e+00,-1.19209289550781250e-07), RES(-1.0000000596046406306e0, -4.1159035837701857686e-11)}, {FN (csc), ARG(1.57114159377789786021e+00,5.0e-01), RES(8.8681891425248302485e-1, 1.4149533035938097090e-4)}, {FN (csc), ARG(1.57114159377789786021e+00,-5.0e-01), RES(8.8681891425248302485e-1, -1.4149533035938097090e-4)}, {FN (csc), ARG(-1.57114159377789786021e+00,5.0e-01), RES(-8.8681891425248302485e-1, 1.4149533035938097090e-4)}, {FN (csc), ARG(-1.57114159377789786021e+00,-5.0e-01), RES(-8.8681891425248302485e-1, -1.4149533035938097090e-4)}, {FN (csc), ARG(1.57114159377789786021e+00,1.0e+00), RES(6.4805426748157480499e-1, 1.7040802567651356981e-4)}, {FN (csc), ARG(1.57114159377789786021e+00,-1.0e+00), RES(6.4805426748157480499e-1, -1.7040802567651356981e-4)}, {FN (csc), ARG(-1.57114159377789786021e+00,1.0e+00), RES(-6.4805426748157480499e-1, 1.7040802567651356981e-4)}, {FN (csc), ARG(-1.57114159377789786021e+00,-1.0e+00), RES(-6.4805426748157480499e-1, -1.7040802567651356981e-4)}, {FN (csc), ARG(1.57114159377789786021e+00,2.0e+00), RES(2.6580221522968095407e-1, 8.8471445300373252796e-5)}, {FN (csc), ARG(1.57114159377789786021e+00,-2.0e+00), RES(2.6580221522968095407e-1, -8.8471445300373252796e-5)}, {FN (csc), ARG(-1.57114159377789786021e+00,2.0e+00), RES(-2.6580221522968095407e-1, 8.8471445300373252796e-5)}, {FN (csc), ARG(-1.57114159377789786021e+00,-2.0e+00), RES(-2.6580221522968095407e-1, -8.8471445300373252796e-5)}, {FN (csc), ARG(3.14124738660679181379e+00,0.0e+00), RES(2.8963094332830802676e3, 0.0)}, {FN (csc), ARG(-3.14124738660679181379e+00,0.0e+00), RES(-2.8963094332830802676e3, 0.0)}, {FN (csc), ARG(3.14124738660679181379e+00,1.19209289550781250e-07), RES(2.8963090880161384259e3, 9.9999986092146180843e-1)}, {FN (csc), ARG(3.14124738660679181379e+00,-1.19209289550781250e-07), RES(2.8963090880161384259e3, -9.9999986092146180843e-1)}, {FN (csc), ARG(-3.14124738660679181379e+00,1.19209289550781250e-07), RES(-2.8963090880161384259e3, 9.9999986092146180843e-1)}, {FN (csc), ARG(-3.14124738660679181379e+00,-1.19209289550781250e-07), RES(-2.8963090880161384259e3, -9.9999986092146180843e-1)}, {FN (csc), ARG(3.14124738660679181379e+00,5.0e-01), RES(1.4337901642797306848e-3, 1.9190337944739187227e0)}, {FN (csc), ARG(3.14124738660679181379e+00,-5.0e-01), RES(1.4337901642797306848e-3, -1.9190337944739187227e0)}, {FN (csc), ARG(-3.14124738660679181379e+00,5.0e-01), RES(-1.4337901642797306848e-3, 1.9190337944739187227e0)}, {FN (csc), ARG(-3.14124738660679181379e+00,-5.0e-01), RES(-1.4337901642797306848e-3, -1.9190337944739187227e0)}, {FN (csc), ARG(3.14124738660679181379e+00,1.0e+00), RES(3.8576176225219054787e-4, 8.5091800407377002721e-1)}, {FN (csc), ARG(3.14124738660679181379e+00,-1.0e+00), RES(3.8576176225219054787e-4, -8.5091800407377002721e-1)}, {FN (csc), ARG(-3.14124738660679181379e+00,1.0e+00), RES(-3.8576176225219054787e-4, 8.5091800407377002721e-1)}, {FN (csc), ARG(-3.14124738660679181379e+00,-1.0e+00), RES(-3.8576176225219054787e-4, -8.5091800407377002721e-1)}, {FN (csc), ARG(3.14124738660679181379e+00,2.0e+00), RES(9.8749461907087358805e-5, 2.7572054583883740766e-1)}, {FN (csc), ARG(3.14124738660679181379e+00,-2.0e+00), RES(9.8749461907087358805e-5, -2.7572054583883740766e-1)}, {FN (csc), ARG(-3.14124738660679181379e+00,2.0e+00), RES(-9.8749461907087358805e-5, 2.7572054583883740766e-1)}, {FN (csc), ARG(-3.14124738660679181379e+00,-2.0e+00), RES(-9.8749461907087358805e-5, -2.7572054583883740766e-1)}, {FN (csc), ARG(3.14193792057279441821e+00,0.0e+00), RES(-2.8963094332851348839e3, 0.0)}, {FN (csc), ARG(-3.14193792057279441821e+00,0.0e+00), RES(2.8963094332851348839e3, 0.0)}, {FN (csc), ARG(3.14193792057279441821e+00,1.19209289550781250e-07), RES(-2.8963090880181930415e3, 9.9999986092288059049e-1)}, {FN (csc), ARG(3.14193792057279441821e+00,-1.19209289550781250e-07), RES(-2.8963090880181930415e3, -9.9999986092288059049e-1)}, {FN (csc), ARG(-3.14193792057279441821e+00,1.19209289550781250e-07), RES(2.8963090880181930415e3, 9.9999986092288059049e-1)}, {FN (csc), ARG(-3.14193792057279441821e+00,-1.19209289550781250e-07), RES(2.8963090880181930415e3, -9.9999986092288059049e-1)}, {FN (csc), ARG(3.14193792057279441821e+00,5.0e-01), RES(-1.4337901642787135676e-3, 1.9190337944739187241e0)}, {FN (csc), ARG(3.14193792057279441821e+00,-5.0e-01), RES(-1.4337901642787135676e-3, -1.9190337944739187241e0)}, {FN (csc), ARG(-3.14193792057279441821e+00,5.0e-01), RES(1.4337901642787135676e-3, 1.9190337944739187241e0)}, {FN (csc), ARG(-3.14193792057279441821e+00,-5.0e-01), RES(1.4337901642787135676e-3, -1.9190337944739187241e0)}, {FN (csc), ARG(3.14193792057279441821e+00,1.0e+00), RES(-3.8576176225191689193e-4, 8.5091800407377002738e-1)}, {FN (csc), ARG(3.14193792057279441821e+00,-1.0e+00), RES(-3.8576176225191689193e-4, -8.5091800407377002738e-1)}, {FN (csc), ARG(-3.14193792057279441821e+00,1.0e+00), RES(3.8576176225191689193e-4, 8.5091800407377002738e-1)}, {FN (csc), ARG(-3.14193792057279441821e+00,-1.0e+00), RES(3.8576176225191689193e-4, -8.5091800407377002738e-1)}, {FN (csc), ARG(3.14193792057279441821e+00,2.0e+00), RES(-9.8749461907017306810e-5, 2.7572054583883740769e-1)}, {FN (csc), ARG(3.14193792057279441821e+00,-2.0e+00), RES(-9.8749461907017306810e-5, -2.7572054583883740769e-1)}, {FN (csc), ARG(-3.14193792057279441821e+00,2.0e+00), RES(9.8749461907017306810e-5, 2.7572054583883740769e-1)}, {FN (csc), ARG(-3.14193792057279441821e+00,-2.0e+00), RES(9.8749461907017306810e-5, -2.7572054583883740769e-1)}, {FN (csc), ARG(4.71204371340168837179e+00,0.0e+00), RES(-1.0000000596046477361e0, 0.0)}, {FN (csc), ARG(-4.71204371340168837179e+00,0.0e+00), RES(1.0000000596046477361e0, 0.0)}, {FN (csc), ARG(4.71204371340168837179e+00,1.19209289550781250e-07), RES(-1.0000000596046406306e0, 4.1159035837731055550e-11)}, {FN (csc), ARG(4.71204371340168837179e+00,-1.19209289550781250e-07), RES(-1.0000000596046406306e0, -4.1159035837731055550e-11)}, {FN (csc), ARG(-4.71204371340168837179e+00,1.19209289550781250e-07), RES(1.0000000596046406306e0, 4.1159035837731055550e-11)}, {FN (csc), ARG(-4.71204371340168837179e+00,-1.19209289550781250e-07), RES(1.0000000596046406306e0, -4.1159035837731055550e-11)}, {FN (csc), ARG(4.71204371340168837179e+00,5.0e-01), RES(-8.8681891425248302489e-1, 1.4149533035948134646e-4)}, {FN (csc), ARG(4.71204371340168837179e+00,-5.0e-01), RES(-8.8681891425248302489e-1, -1.4149533035948134646e-4)}, {FN (csc), ARG(-4.71204371340168837179e+00,5.0e-01), RES(8.8681891425248302489e-1, 1.4149533035948134646e-4)}, {FN (csc), ARG(-4.71204371340168837179e+00,-5.0e-01), RES(8.8681891425248302489e-1, -1.4149533035948134646e-4)}, {FN (csc), ARG(4.71204371340168837179e+00,1.0e+00), RES(-6.4805426748157480498e-1, 1.7040802567663445577e-4)}, {FN (csc), ARG(4.71204371340168837179e+00,-1.0e+00), RES(-6.4805426748157480498e-1, -1.7040802567663445577e-4)}, {FN (csc), ARG(-4.71204371340168837179e+00,1.0e+00), RES(6.4805426748157480498e-1, 1.7040802567663445577e-4)}, {FN (csc), ARG(-4.71204371340168837179e+00,-1.0e+00), RES(6.4805426748157480498e-1, -1.7040802567663445577e-4)}, {FN (csc), ARG(4.71204371340168837179e+00,2.0e+00), RES(-2.6580221522968095405e-1, 8.8471445300436013659e-5)}, {FN (csc), ARG(4.71204371340168837179e+00,-2.0e+00), RES(-2.6580221522968095405e-1, -8.8471445300436013659e-5)}, {FN (csc), ARG(-4.71204371340168837179e+00,2.0e+00), RES(2.6580221522968095405e-1, 8.8471445300436013659e-5)}, {FN (csc), ARG(-4.71204371340168837179e+00,-2.0e+00), RES(2.6580221522968095405e-1, -8.8471445300436013659e-5)}, {FN (csc), ARG(4.71273424736769097620e+00,0.0e+00), RES(-1.0000000596046477359e0, 0.0)}, {FN (csc), ARG(-4.71273424736769097620e+00,0.0e+00), RES(1.0000000596046477359e0, 0.0)}, {FN (csc), ARG(4.71273424736769097620e+00,1.19209289550781250e-07), RES(-1.0000000596046406305e0, -4.1159035837687258754e-11)}, {FN (csc), ARG(4.71273424736769097620e+00,-1.19209289550781250e-07), RES(-1.0000000596046406305e0, 4.1159035837687258754e-11)}, {FN (csc), ARG(-4.71273424736769097620e+00,1.19209289550781250e-07), RES(1.0000000596046406305e0, -4.1159035837687258754e-11)}, {FN (csc), ARG(-4.71273424736769097620e+00,-1.19209289550781250e-07), RES(1.0000000596046406305e0, 4.1159035837687258754e-11)}, {FN (csc), ARG(4.71273424736769097620e+00,5.0e-01), RES(-8.8681891425248302483e-1, -1.4149533035933078312e-4)}, {FN (csc), ARG(4.71273424736769097620e+00,-5.0e-01), RES(-8.8681891425248302483e-1, 1.4149533035933078312e-4)}, {FN (csc), ARG(-4.71273424736769097620e+00,5.0e-01), RES(8.8681891425248302483e-1, -1.4149533035933078312e-4)}, {FN (csc), ARG(-4.71273424736769097620e+00,-5.0e-01), RES(8.8681891425248302483e-1, 1.4149533035933078312e-4)}, {FN (csc), ARG(4.71273424736769097620e+00,1.0e+00), RES(-6.480542674815748050e-1, -1.7040802567645312683e-4)}, {FN (csc), ARG(4.71273424736769097620e+00,-1.0e+00), RES(-6.480542674815748050e-1, 1.7040802567645312683e-4)}, {FN (csc), ARG(-4.71273424736769097620e+00,1.0e+00), RES(6.480542674815748050e-1, -1.7040802567645312683e-4)}, {FN (csc), ARG(-4.71273424736769097620e+00,-1.0e+00), RES(6.480542674815748050e-1, 1.7040802567645312683e-4)}, {FN (csc), ARG(4.71273424736769097620e+00,2.0e+00), RES(-2.6580221522968095408e-1, -8.8471445300341872364e-5)}, {FN (csc), ARG(4.71273424736769097620e+00,-2.0e+00), RES(-2.6580221522968095408e-1, 8.8471445300341872364e-5)}, {FN (csc), ARG(-4.71273424736769097620e+00,2.0e+00), RES(2.6580221522968095408e-1, -8.8471445300341872364e-5)}, {FN (csc), ARG(-4.71273424736769097620e+00,-2.0e+00), RES(2.6580221522968095408e-1, 8.8471445300341872364e-5)}, {FN (csc), ARG(6.28284004019658492979e+00,0.0e+00), RES(-2.8963094332820529594e3, 0.0)}, {FN (csc), ARG(-6.28284004019658492979e+00,0.0e+00), RES(2.8963094332820529594e3, 0.0)}, {FN (csc), ARG(6.28284004019658492979e+00,1.19209289550781250e-07), RES(-2.8963090880151111181e3, -9.9999986092075241740e-1)}, {FN (csc), ARG(6.28284004019658492979e+00,-1.19209289550781250e-07), RES(-2.8963090880151111181e3, 9.9999986092075241740e-1)}, {FN (csc), ARG(-6.28284004019658492979e+00,1.19209289550781250e-07), RES(2.8963090880151111181e3, -9.9999986092075241740e-1)}, {FN (csc), ARG(-6.28284004019658492979e+00,-1.19209289550781250e-07), RES(2.8963090880151111181e3, 9.9999986092075241740e-1)}, {FN (csc), ARG(6.28284004019658492979e+00,5.0e-01), RES(-1.4337901642802392434e-3, -1.9190337944739187220e0)}, {FN (csc), ARG(6.28284004019658492979e+00,-5.0e-01), RES(-1.4337901642802392434e-3, 1.9190337944739187220e0)}, {FN (csc), ARG(-6.28284004019658492979e+00,5.0e-01), RES(1.4337901642802392434e-3, -1.9190337944739187220e0)}, {FN (csc), ARG(-6.28284004019658492979e+00,-5.0e-01), RES(1.4337901642802392434e-3, 1.9190337944739187220e0)}, {FN (csc), ARG(6.28284004019658492979e+00,1.0e+00), RES(-3.8576176225232737584e-4, -8.5091800407377002712e-1)}, {FN (csc), ARG(6.28284004019658492979e+00,-1.0e+00), RES(-3.8576176225232737584e-4, 8.5091800407377002712e-1)}, {FN (csc), ARG(-6.28284004019658492979e+00,1.0e+00), RES(3.8576176225232737584e-4, -8.5091800407377002712e-1)}, {FN (csc), ARG(-6.28284004019658492979e+00,-1.0e+00), RES(3.8576176225232737584e-4, 8.5091800407377002712e-1)}, {FN (csc), ARG(6.28284004019658492979e+00,2.0e+00), RES(-9.8749461907122384803e-5, -2.7572054583883740765e-1)}, {FN (csc), ARG(6.28284004019658492979e+00,-2.0e+00), RES(-9.8749461907122384803e-5, 2.7572054583883740765e-1)}, {FN (csc), ARG(-6.28284004019658492979e+00,2.0e+00), RES(9.8749461907122384803e-5, -2.7572054583883740765e-1)}, {FN (csc), ARG(-6.28284004019658492979e+00,-2.0e+00), RES(9.8749461907122384803e-5, 2.7572054583883740765e-1)}, {FN (csc), ARG(6.28353057416258753420e+00,0.0e+00), RES(2.8963094332861621921e3, 0.0)}, {FN (csc), ARG(-6.28353057416258753420e+00,0.0e+00), RES(-2.8963094332861621921e3, 0.0)}, {FN (csc), ARG(6.28353057416258753420e+00,1.19209289550781250e-07), RES(2.8963090880192203493e3, -9.9999986092358998153e-1)}, {FN (csc), ARG(6.28353057416258753420e+00,-1.19209289550781250e-07), RES(2.8963090880192203493e3, 9.9999986092358998153e-1)}, {FN (csc), ARG(-6.28353057416258753420e+00,1.19209289550781250e-07), RES(-2.8963090880192203493e3, -9.9999986092358998153e-1)}, {FN (csc), ARG(-6.28353057416258753420e+00,-1.19209289550781250e-07), RES(-2.8963090880192203493e3, 9.9999986092358998153e-1)}, {FN (csc), ARG(6.28353057416258753420e+00,5.0e-01), RES(1.4337901642782050091e-3, -1.9190337944739187248e0)}, {FN (csc), ARG(6.28353057416258753420e+00,-5.0e-01), RES(1.4337901642782050091e-3, 1.9190337944739187248e0)}, {FN (csc), ARG(-6.28353057416258753420e+00,5.0e-01), RES(-1.4337901642782050091e-3, -1.9190337944739187248e0)}, {FN (csc), ARG(-6.28353057416258753420e+00,-5.0e-01), RES(-1.4337901642782050091e-3, 1.9190337944739187248e0)}, {FN (csc), ARG(6.28353057416258753420e+00,1.0e+00), RES(3.8576176225178006396e-4, -8.5091800407377002747e-1)}, {FN (csc), ARG(6.28353057416258753420e+00,-1.0e+00), RES(3.8576176225178006396e-4, 8.5091800407377002747e-1)}, {FN (csc), ARG(-6.28353057416258753420e+00,1.0e+00), RES(-3.8576176225178006396e-4, -8.5091800407377002747e-1)}, {FN (csc), ARG(-6.28353057416258753420e+00,-1.0e+00), RES(-3.8576176225178006396e-4, 8.5091800407377002747e-1)}, {FN (csc), ARG(6.28353057416258753420e+00,2.0e+00), RES(9.8749461906982280812e-5, -2.7572054583883740770e-1)}, {FN (csc), ARG(6.28353057416258753420e+00,-2.0e+00), RES(9.8749461906982280812e-5, 2.7572054583883740770e-1)}, {FN (csc), ARG(-6.28353057416258753420e+00,2.0e+00), RES(-9.8749461906982280812e-5, -2.7572054583883740770e-1)}, {FN (csc), ARG(-6.28353057416258753420e+00,-2.0e+00), RES(-9.8749461906982280812e-5, 2.7572054583883740770e-1)}, {FN (csc), ARG(9.42443269378637893396e+00,0.0e+00), RES(2.8963094332884762317e3, 0.0)}, {FN (csc), ARG(-9.42443269378637893396e+00,0.0e+00), RES(-2.8963094332884762317e3, 0.0)}, {FN (csc), ARG(9.42443269378637893396e+00,1.19209289550781250e-07), RES(2.8963090880215343881e3, 9.9999986092518790411e-1)}, {FN (csc), ARG(9.42443269378637893396e+00,-1.19209289550781250e-07), RES(2.8963090880215343881e3, -9.9999986092518790411e-1)}, {FN (csc), ARG(-9.42443269378637893396e+00,1.19209289550781250e-07), RES(-2.8963090880215343881e3, 9.9999986092518790411e-1)}, {FN (csc), ARG(-9.42443269378637893396e+00,-1.19209289550781250e-07), RES(-2.8963090880215343881e3, -9.9999986092518790411e-1)}, {FN (csc), ARG(9.42443269378637893396e+00,5.0e-01), RES(1.4337901642770594670e-3, 1.9190337944739187263e0)}, {FN (csc), ARG(9.42443269378637893396e+00,-5.0e-01), RES(1.4337901642770594670e-3, -1.9190337944739187263e0)}, {FN (csc), ARG(-9.42443269378637893396e+00,5.0e-01), RES(-1.4337901642770594670e-3, 1.9190337944739187263e0)}, {FN (csc), ARG(-9.42443269378637893396e+00,-5.0e-01), RES(-1.4337901642770594670e-3, -1.9190337944739187263e0)}, {FN (csc), ARG(9.42443269378637893396e+00,1.0e+00), RES(3.8576176225147185523e-4, 8.5091800407377002767e-1)}, {FN (csc), ARG(9.42443269378637893396e+00,-1.0e+00), RES(3.8576176225147185523e-4, -8.5091800407377002767e-1)}, {FN (csc), ARG(-9.42443269378637893396e+00,1.0e+00), RES(-3.8576176225147185523e-4, 8.5091800407377002767e-1)}, {FN (csc), ARG(-9.42443269378637893396e+00,-1.0e+00), RES(-3.8576176225147185523e-4, -8.5091800407377002767e-1)}, {FN (csc), ARG(9.42443269378637893396e+00,2.0e+00), RES(9.874946190690338380e-5, 2.7572054583883740773e-1)}, {FN (csc), ARG(9.42443269378637893396e+00,-2.0e+00), RES(9.874946190690338380e-5, -2.7572054583883740773e-1)}, {FN (csc), ARG(-9.42443269378637893396e+00,2.0e+00), RES(-9.874946190690338380e-5, 2.7572054583883740773e-1)}, {FN (csc), ARG(-9.42443269378637893396e+00,-2.0e+00), RES(-9.874946190690338380e-5, -2.7572054583883740773e-1)}, {FN (csc), ARG(9.42512322775237976202e+00,0.0e+00), RES(-2.8963094332946400807e3, 0.0)}, {FN (csc), ARG(-9.42512322775237976202e+00,0.0e+00), RES(2.8963094332946400807e3, 0.0)}, {FN (csc), ARG(9.42512322775237976202e+00,1.19209289550781250e-07), RES(-2.8963090880276982349e3, 9.9999986092944425030e-1)}, {FN (csc), ARG(9.42512322775237976202e+00,-1.19209289550781250e-07), RES(-2.8963090880276982349e3, -9.9999986092944425030e-1)}, {FN (csc), ARG(-9.42512322775237976202e+00,1.19209289550781250e-07), RES(2.8963090880276982349e3, 9.9999986092944425030e-1)}, {FN (csc), ARG(-9.42512322775237976202e+00,-1.19209289550781250e-07), RES(2.8963090880276982349e3, -9.9999986092944425030e-1)}, {FN (csc), ARG(9.42512322775237976202e+00,5.0e-01), RES(-1.4337901642740081154e-3, 1.9190337944739187304e0)}, {FN (csc), ARG(9.42512322775237976202e+00,-5.0e-01), RES(-1.4337901642740081154e-3, -1.9190337944739187304e0)}, {FN (csc), ARG(-9.42512322775237976202e+00,5.0e-01), RES(1.4337901642740081154e-3, 1.9190337944739187304e0)}, {FN (csc), ARG(-9.42512322775237976202e+00,-5.0e-01), RES(1.4337901642740081154e-3, -1.9190337944739187304e0)}, {FN (csc), ARG(9.42512322775237976202e+00,1.0e+00), RES(-3.8576176225065088741e-4, 8.5091800407377002820e-1)}, {FN (csc), ARG(9.42512322775237976202e+00,-1.0e+00), RES(-3.8576176225065088741e-4, -8.5091800407377002820e-1)}, {FN (csc), ARG(-9.42512322775237976202e+00,1.0e+00), RES(3.8576176225065088741e-4, 8.5091800407377002820e-1)}, {FN (csc), ARG(-9.42512322775237976202e+00,-1.0e+00), RES(3.8576176225065088741e-4, -8.5091800407377002820e-1)}, {FN (csc), ARG(9.42512322775237976202e+00,2.0e+00), RES(-9.8749461906693227814e-5, 2.7572054583883740781e-1)}, {FN (csc), ARG(9.42512322775237976202e+00,-2.0e+00), RES(-9.8749461906693227814e-5, -2.7572054583883740781e-1)}, {FN (csc), ARG(-9.42512322775237976202e+00,2.0e+00), RES(9.8749461906693227814e-5, 2.7572054583883740781e-1)}, {FN (csc), ARG(-9.42512322775237976202e+00,-2.0e+00), RES(9.8749461906693227814e-5, -2.7572054583883740781e-1)}, {FN (sec), ARG(-3.45266983001243932001e-04,0.0e+00), RES(1.0000000596046477360e0, 0.0)}, {FN (sec), ARG(3.45266983001243932001e-04,0.0e+00), RES(1.0000000596046477360e0, 0.0)}, {FN (sec), ARG(-3.45266983001243932001e-04,1.19209289550781250e-07), RES(1.0000000596046406306e0, -4.1159035837702210125e-11)}, {FN (sec), ARG(-3.45266983001243932001e-04,-1.19209289550781250e-07), RES(1.0000000596046406306e0, 4.1159035837702210125e-11)}, {FN (sec), ARG(3.45266983001243932001e-04,1.19209289550781250e-07), RES(1.0000000596046406306e0, 4.1159035837702210125e-11)}, {FN (sec), ARG(3.45266983001243932001e-04,-1.19209289550781250e-07), RES(1.0000000596046406306e0, -4.1159035837702210125e-11)}, {FN (sec), ARG(-3.45266983001243932001e-04,5.0e-01), RES(8.8681891425248302485e-1, -1.4149533035938218250e-4)}, {FN (sec), ARG(-3.45266983001243932001e-04,-5.0e-01), RES(8.8681891425248302485e-1, 1.4149533035938218250e-4)}, {FN (sec), ARG(3.45266983001243932001e-04,5.0e-01), RES(8.8681891425248302485e-1, 1.4149533035938218250e-4)}, {FN (sec), ARG(3.45266983001243932001e-04,-5.0e-01), RES(8.8681891425248302485e-1, -1.4149533035938218250e-4)}, {FN (sec), ARG(-3.45266983001243932001e-04,1.0e+00), RES(6.4805426748157480499e-1, -1.7040802567651502899e-4)}, {FN (sec), ARG(-3.45266983001243932001e-04,-1.0e+00), RES(6.4805426748157480499e-1, 1.7040802567651502899e-4)}, {FN (sec), ARG(3.45266983001243932001e-04,1.0e+00), RES(6.4805426748157480499e-1, 1.7040802567651502899e-4)}, {FN (sec), ARG(3.45266983001243932001e-04,-1.0e+00), RES(6.4805426748157480499e-1, -1.7040802567651502899e-4)}, {FN (sec), ARG(-3.45266983001243932001e-04,2.0e+00), RES(2.6580221522968095407e-1, -8.8471445300374010365e-5)}, {FN (sec), ARG(-3.45266983001243932001e-04,-2.0e+00), RES(2.6580221522968095407e-1, 8.8471445300374010365e-5)}, {FN (sec), ARG(3.45266983001243932001e-04,2.0e+00), RES(2.6580221522968095407e-1, 8.8471445300374010365e-5)}, {FN (sec), ARG(3.45266983001243932001e-04,-2.0e+00), RES(2.6580221522968095407e-1, -8.8471445300374010365e-5)}, {FN (sec), ARG(1.57045105981189525579e+00,0.0e+00), RES(2.8963094332835939217e3, 0.0)}, {FN (sec), ARG(-1.57045105981189525579e+00,0.0e+00), RES(2.8963094332835939217e3, 0.0)}, {FN (sec), ARG(1.57045105981189525579e+00,1.19209289550781250e-07), RES(2.8963090880166520798e3, 9.9999986092181650394e-1)}, {FN (sec), ARG(1.57045105981189525579e+00,-1.19209289550781250e-07), RES(2.8963090880166520798e3, -9.9999986092181650394e-1)}, {FN (sec), ARG(-1.57045105981189525579e+00,1.19209289550781250e-07), RES(2.8963090880166520798e3, -9.9999986092181650394e-1)}, {FN (sec), ARG(-1.57045105981189525579e+00,-1.19209289550781250e-07), RES(2.8963090880166520798e3, 9.9999986092181650394e-1)}, {FN (sec), ARG(1.57045105981189525579e+00,5.0e-01), RES(1.4337901642794764055e-3, 1.9190337944739187231e0)}, {FN (sec), ARG(1.57045105981189525579e+00,-5.0e-01), RES(1.4337901642794764055e-3, -1.9190337944739187231e0)}, {FN (sec), ARG(-1.57045105981189525579e+00,5.0e-01), RES(1.4337901642794764055e-3, -1.9190337944739187231e0)}, {FN (sec), ARG(-1.57045105981189525579e+00,-5.0e-01), RES(1.4337901642794764055e-3, 1.9190337944739187231e0)}, {FN (sec), ARG(1.57045105981189525579e+00,1.0e+00), RES(3.8576176225212213388e-4, 8.5091800407377002725e-1)}, {FN (sec), ARG(1.57045105981189525579e+00,-1.0e+00), RES(3.8576176225212213388e-4, -8.5091800407377002725e-1)}, {FN (sec), ARG(-1.57045105981189525579e+00,1.0e+00), RES(3.8576176225212213388e-4, -8.5091800407377002725e-1)}, {FN (sec), ARG(-1.57045105981189525579e+00,-1.0e+00), RES(3.8576176225212213388e-4, 8.5091800407377002725e-1)}, {FN (sec), ARG(1.57045105981189525579e+00,2.0e+00), RES(9.8749461907069845806e-5, 2.7572054583883740767e-1)}, {FN (sec), ARG(1.57045105981189525579e+00,-2.0e+00), RES(9.8749461907069845806e-5, -2.7572054583883740767e-1)}, {FN (sec), ARG(-1.57045105981189525579e+00,2.0e+00), RES(9.8749461907069845806e-5, -2.7572054583883740767e-1)}, {FN (sec), ARG(-1.57045105981189525579e+00,-2.0e+00), RES(9.8749461907069845806e-5, 2.7572054583883740767e-1)}, {FN (sec), ARG(1.57114159377789786021e+00,0.0e+00), RES(-2.8963094332846212298e3, 0.0)}, {FN (sec), ARG(-1.57114159377789786021e+00,0.0e+00), RES(-2.8963094332846212298e3, 0.0)}, {FN (sec), ARG(1.57114159377789786021e+00,1.19209289550781250e-07), RES(-2.8963090880176793876e3, 9.9999986092252589498e-1)}, {FN (sec), ARG(1.57114159377789786021e+00,-1.19209289550781250e-07), RES(-2.8963090880176793876e3, -9.9999986092252589498e-1)}, {FN (sec), ARG(-1.57114159377789786021e+00,1.19209289550781250e-07), RES(-2.8963090880176793876e3, -9.9999986092252589498e-1)}, {FN (sec), ARG(-1.57114159377789786021e+00,-1.19209289550781250e-07), RES(-2.8963090880176793876e3, 9.9999986092252589498e-1)}, {FN (sec), ARG(1.57114159377789786021e+00,5.0e-01), RES(-1.4337901642789678469e-3, 1.9190337944739187237e0)}, {FN (sec), ARG(1.57114159377789786021e+00,-5.0e-01), RES(-1.4337901642789678469e-3, -1.9190337944739187237e0)}, {FN (sec), ARG(-1.57114159377789786021e+00,5.0e-01), RES(-1.4337901642789678469e-3, -1.9190337944739187237e0)}, {FN (sec), ARG(-1.57114159377789786021e+00,-5.0e-01), RES(-1.4337901642789678469e-3, 1.9190337944739187237e0)}, {FN (sec), ARG(1.57114159377789786021e+00,1.0e+00), RES(-3.8576176225198530591e-4, 8.5091800407377002734e-1)}, {FN (sec), ARG(1.57114159377789786021e+00,-1.0e+00), RES(-3.8576176225198530591e-4, -8.5091800407377002734e-1)}, {FN (sec), ARG(-1.57114159377789786021e+00,1.0e+00), RES(-3.8576176225198530591e-4, -8.5091800407377002734e-1)}, {FN (sec), ARG(-1.57114159377789786021e+00,-1.0e+00), RES(-3.8576176225198530591e-4, 8.5091800407377002734e-1)}, {FN (sec), ARG(1.57114159377789786021e+00,2.0e+00), RES(-9.8749461907034819809e-5, 2.7572054583883740768e-1)}, {FN (sec), ARG(1.57114159377789786021e+00,-2.0e+00), RES(-9.8749461907034819809e-5, -2.7572054583883740768e-1)}, {FN (sec), ARG(-1.57114159377789786021e+00,2.0e+00), RES(-9.8749461907034819809e-5, -2.7572054583883740768e-1)}, {FN (sec), ARG(-1.57114159377789786021e+00,-2.0e+00), RES(-9.8749461907034819809e-5, 2.7572054583883740768e-1)}, {FN (sec), ARG(3.14124738660679181379e+00,0.0e+00), RES(-1.0000000596046477360e0, 0.0)}, {FN (sec), ARG(-3.14124738660679181379e+00,0.0e+00), RES(-1.0000000596046477360e0, 0.0)}, {FN (sec), ARG(3.14124738660679181379e+00,1.19209289550781250e-07), RES(-1.0000000596046406306e0, 4.1159035837723756084e-11)}, {FN (sec), ARG(3.14124738660679181379e+00,-1.19209289550781250e-07), RES(-1.0000000596046406306e0, -4.1159035837723756084e-11)}, {FN (sec), ARG(-3.14124738660679181379e+00,1.19209289550781250e-07), RES(-1.0000000596046406306e0, -4.1159035837723756084e-11)}, {FN (sec), ARG(-3.14124738660679181379e+00,-1.19209289550781250e-07), RES(-1.0000000596046406306e0, 4.1159035837723756084e-11)}, {FN (sec), ARG(3.14124738660679181379e+00,5.0e-01), RES(-8.8681891425248302488e-1, 1.4149533035945625257e-4)}, {FN (sec), ARG(3.14124738660679181379e+00,-5.0e-01), RES(-8.8681891425248302488e-1, -1.4149533035945625257e-4)}, {FN (sec), ARG(-3.14124738660679181379e+00,5.0e-01), RES(-8.8681891425248302488e-1, -1.4149533035945625257e-4)}, {FN (sec), ARG(-3.14124738660679181379e+00,-5.0e-01), RES(-8.8681891425248302488e-1, 1.4149533035945625257e-4)}, {FN (sec), ARG(3.14124738660679181379e+00,1.0e+00), RES(-6.4805426748157480499e-1, 1.7040802567660423428e-4)}, {FN (sec), ARG(3.14124738660679181379e+00,-1.0e+00), RES(-6.4805426748157480499e-1, -1.7040802567660423428e-4)}, {FN (sec), ARG(-3.14124738660679181379e+00,1.0e+00), RES(-6.4805426748157480499e-1, -1.7040802567660423428e-4)}, {FN (sec), ARG(-3.14124738660679181379e+00,-1.0e+00), RES(-6.4805426748157480499e-1, 1.7040802567660423428e-4)}, {FN (sec), ARG(3.14124738660679181379e+00,2.0e+00), RES(-2.6580221522968095405e-1, 8.8471445300420323443e-5)}, {FN (sec), ARG(3.14124738660679181379e+00,-2.0e+00), RES(-2.6580221522968095405e-1, -8.8471445300420323443e-5)}, {FN (sec), ARG(-3.14124738660679181379e+00,2.0e+00), RES(-2.6580221522968095405e-1, -8.8471445300420323443e-5)}, {FN (sec), ARG(-3.14124738660679181379e+00,-2.0e+00), RES(-2.6580221522968095405e-1, 8.8471445300420323443e-5)}, {FN (sec), ARG(3.14193792057279441821e+00,0.0e+00), RES(-1.0000000596046477360e0, 0.0)}, {FN (sec), ARG(-3.14193792057279441821e+00,0.0e+00), RES(-1.0000000596046477360e0, 0.0)}, {FN (sec), ARG(3.14193792057279441821e+00,1.19209289550781250e-07), RES(-1.0000000596046406305e0, -4.1159035837694558220e-11)}, {FN (sec), ARG(3.14193792057279441821e+00,-1.19209289550781250e-07), RES(-1.0000000596046406305e0, 4.1159035837694558220e-11)}, {FN (sec), ARG(-3.14193792057279441821e+00,1.19209289550781250e-07), RES(-1.0000000596046406305e0, 4.1159035837694558220e-11)}, {FN (sec), ARG(-3.14193792057279441821e+00,-1.19209289550781250e-07), RES(-1.0000000596046406305e0, -4.1159035837694558220e-11)}, {FN (sec), ARG(3.14193792057279441821e+00,5.0e-01), RES(-8.8681891425248302484e-1, -1.4149533035935587701e-4)}, {FN (sec), ARG(3.14193792057279441821e+00,-5.0e-01), RES(-8.8681891425248302484e-1, 1.4149533035935587701e-4)}, {FN (sec), ARG(-3.14193792057279441821e+00,5.0e-01), RES(-8.8681891425248302484e-1, 1.4149533035935587701e-4)}, {FN (sec), ARG(-3.14193792057279441821e+00,-5.0e-01), RES(-8.8681891425248302484e-1, -1.4149533035935587701e-4)}, {FN (sec), ARG(3.14193792057279441821e+00,1.0e+00), RES(-6.4805426748157480499e-1, -1.7040802567648334832e-4)}, {FN (sec), ARG(3.14193792057279441821e+00,-1.0e+00), RES(-6.4805426748157480499e-1, 1.7040802567648334832e-4)}, {FN (sec), ARG(-3.14193792057279441821e+00,1.0e+00), RES(-6.4805426748157480499e-1, 1.7040802567648334832e-4)}, {FN (sec), ARG(-3.14193792057279441821e+00,-1.0e+00), RES(-6.4805426748157480499e-1, -1.7040802567648334832e-4)}, {FN (sec), ARG(3.14193792057279441821e+00,2.0e+00), RES(-2.6580221522968095407e-1, -8.8471445300357562580e-5)}, {FN (sec), ARG(3.14193792057279441821e+00,-2.0e+00), RES(-2.6580221522968095407e-1, 8.8471445300357562580e-5)}, {FN (sec), ARG(-3.14193792057279441821e+00,2.0e+00), RES(-2.6580221522968095407e-1, 8.8471445300357562580e-5)}, {FN (sec), ARG(-3.14193792057279441821e+00,-2.0e+00), RES(-2.6580221522968095407e-1, -8.8471445300357562580e-5)}, {FN (sec), ARG(4.71204371340168837179e+00,0.0e+00), RES(-2.8963094332825666135e3, 0.0)}, {FN (sec), ARG(-4.71204371340168837179e+00,0.0e+00), RES(-2.8963094332825666135e3, 0.0)}, {FN (sec), ARG(4.71204371340168837179e+00,1.19209289550781250e-07), RES(-2.8963090880156247720e3, -9.9999986092110711291e-1)}, {FN (sec), ARG(4.71204371340168837179e+00,-1.19209289550781250e-07), RES(-2.8963090880156247720e3, 9.9999986092110711291e-1)}, {FN (sec), ARG(-4.71204371340168837179e+00,1.19209289550781250e-07), RES(-2.8963090880156247720e3, 9.9999986092110711291e-1)}, {FN (sec), ARG(-4.71204371340168837179e+00,-1.19209289550781250e-07), RES(-2.8963090880156247720e3, -9.9999986092110711291e-1)}, {FN (sec), ARG(4.71204371340168837179e+00,5.0e-01), RES(-1.4337901642799849641e-3, -1.9190337944739187224e0)}, {FN (sec), ARG(4.71204371340168837179e+00,-5.0e-01), RES(-1.4337901642799849641e-3, 1.9190337944739187224e0)}, {FN (sec), ARG(-4.71204371340168837179e+00,5.0e-01), RES(-1.4337901642799849641e-3, 1.9190337944739187224e0)}, {FN (sec), ARG(-4.71204371340168837179e+00,-5.0e-01), RES(-1.4337901642799849641e-3, -1.9190337944739187224e0)}, {FN (sec), ARG(4.71204371340168837179e+00,1.0e+00), RES(-3.8576176225225896185e-4, -8.5091800407377002716e-1)}, {FN (sec), ARG(4.71204371340168837179e+00,-1.0e+00), RES(-3.8576176225225896185e-4, 8.5091800407377002716e-1)}, {FN (sec), ARG(-4.71204371340168837179e+00,1.0e+00), RES(-3.8576176225225896185e-4, 8.5091800407377002716e-1)}, {FN (sec), ARG(-4.71204371340168837179e+00,-1.0e+00), RES(-3.8576176225225896185e-4, -8.5091800407377002716e-1)}, {FN (sec), ARG(4.71204371340168837179e+00,2.0e+00), RES(-9.8749461907104871804e-5, -2.7572054583883740766e-1)}, {FN (sec), ARG(4.71204371340168837179e+00,-2.0e+00), RES(-9.8749461907104871804e-5, 2.7572054583883740766e-1)}, {FN (sec), ARG(-4.71204371340168837179e+00,2.0e+00), RES(-9.8749461907104871804e-5, 2.7572054583883740766e-1)}, {FN (sec), ARG(-4.71204371340168837179e+00,-2.0e+00), RES(-9.8749461907104871804e-5, -2.7572054583883740766e-1)}, {FN (sec), ARG(4.71273424736769097620e+00,0.0e+00), RES(2.8963094332856485380e3, 0.0)}, {FN (sec), ARG(-4.71273424736769097620e+00,0.0e+00), RES(2.8963094332856485380e3, 0.0)}, {FN (sec), ARG(4.71273424736769097620e+00,1.19209289550781250e-07), RES(2.8963090880187066954e3, -9.9999986092323528601e-1)}, {FN (sec), ARG(4.71273424736769097620e+00,-1.19209289550781250e-07), RES(2.8963090880187066954e3, 9.9999986092323528601e-1)}, {FN (sec), ARG(-4.71273424736769097620e+00,1.19209289550781250e-07), RES(2.8963090880187066954e3, 9.9999986092323528601e-1)}, {FN (sec), ARG(-4.71273424736769097620e+00,-1.19209289550781250e-07), RES(2.8963090880187066954e3, -9.9999986092323528601e-1)}, {FN (sec), ARG(4.71273424736769097620e+00,5.0e-01), RES(1.4337901642784592884e-3, -1.9190337944739187244e0)}, {FN (sec), ARG(4.71273424736769097620e+00,-5.0e-01), RES(1.4337901642784592884e-3, 1.9190337944739187244e0)}, {FN (sec), ARG(-4.71273424736769097620e+00,5.0e-01), RES(1.4337901642784592884e-3, 1.9190337944739187244e0)}, {FN (sec), ARG(-4.71273424736769097620e+00,-5.0e-01), RES(1.4337901642784592884e-3, -1.9190337944739187244e0)}, {FN (sec), ARG(4.71273424736769097620e+00,1.0e+00), RES(3.8576176225184847794e-4, -8.5091800407377002743e-1)}, {FN (sec), ARG(4.71273424736769097620e+00,-1.0e+00), RES(3.8576176225184847794e-4, 8.5091800407377002743e-1)}, {FN (sec), ARG(-4.71273424736769097620e+00,1.0e+00), RES(3.8576176225184847794e-4, 8.5091800407377002743e-1)}, {FN (sec), ARG(-4.71273424736769097620e+00,-1.0e+00), RES(3.8576176225184847794e-4, -8.5091800407377002743e-1)}, {FN (sec), ARG(4.71273424736769097620e+00,2.0e+00), RES(9.8749461906999793811e-5, -2.7572054583883740770e-1)}, {FN (sec), ARG(4.71273424736769097620e+00,-2.0e+00), RES(9.8749461906999793811e-5, 2.7572054583883740770e-1)}, {FN (sec), ARG(-4.71273424736769097620e+00,2.0e+00), RES(9.8749461906999793811e-5, 2.7572054583883740770e-1)}, {FN (sec), ARG(-4.71273424736769097620e+00,-2.0e+00), RES(9.8749461906999793811e-5, -2.7572054583883740770e-1)}, {FN (sec), ARG(6.28284004019658492979e+00,0.0e+00), RES(1.0000000596046477361e0, 0.0)}, {FN (sec), ARG(-6.28284004019658492979e+00,0.0e+00), RES(1.0000000596046477361e0, 0.0)}, {FN (sec), ARG(6.28284004019658492979e+00,1.19209289550781250e-07), RES(1.0000000596046406307e0, -4.1159035837738355016e-11)}, {FN (sec), ARG(6.28284004019658492979e+00,-1.19209289550781250e-07), RES(1.0000000596046406307e0, 4.1159035837738355016e-11)}, {FN (sec), ARG(-6.28284004019658492979e+00,1.19209289550781250e-07), RES(1.0000000596046406307e0, 4.1159035837738355016e-11)}, {FN (sec), ARG(-6.28284004019658492979e+00,-1.19209289550781250e-07), RES(1.0000000596046406307e0, -4.1159035837738355016e-11)}, {FN (sec), ARG(6.28284004019658492979e+00,5.0e-01), RES(8.8681891425248302490e-1, -1.4149533035950644034e-4)}, {FN (sec), ARG(6.28284004019658492979e+00,-5.0e-01), RES(8.8681891425248302490e-1, 1.4149533035950644034e-4)}, {FN (sec), ARG(-6.28284004019658492979e+00,5.0e-01), RES(8.8681891425248302490e-1, 1.4149533035950644034e-4)}, {FN (sec), ARG(-6.28284004019658492979e+00,-5.0e-01), RES(8.8681891425248302490e-1, -1.4149533035950644034e-4)}, {FN (sec), ARG(6.28284004019658492979e+00,1.0e+00), RES(6.4805426748157480498e-1, -1.7040802567666467726e-4)}, {FN (sec), ARG(6.28284004019658492979e+00,-1.0e+00), RES(6.4805426748157480498e-1, 1.7040802567666467726e-4)}, {FN (sec), ARG(-6.28284004019658492979e+00,1.0e+00), RES(6.4805426748157480498e-1, 1.7040802567666467726e-4)}, {FN (sec), ARG(-6.28284004019658492979e+00,-1.0e+00), RES(6.4805426748157480498e-1, -1.7040802567666467726e-4)}, {FN (sec), ARG(6.28284004019658492979e+00,2.0e+00), RES(2.6580221522968095404e-1, -8.8471445300451703875e-5)}, {FN (sec), ARG(6.28284004019658492979e+00,-2.0e+00), RES(2.6580221522968095404e-1, 8.8471445300451703875e-5)}, {FN (sec), ARG(-6.28284004019658492979e+00,2.0e+00), RES(2.6580221522968095404e-1, 8.8471445300451703875e-5)}, {FN (sec), ARG(-6.28284004019658492979e+00,-2.0e+00), RES(2.6580221522968095404e-1, -8.8471445300451703875e-5)}, {FN (sec), ARG(6.28353057416258753420e+00,0.0e+00), RES(1.0000000596046477359e0, 0.0)}, {FN (sec), ARG(-6.28353057416258753420e+00,0.0e+00), RES(1.0000000596046477359e0, 0.0)}, {FN (sec), ARG(6.28353057416258753420e+00,1.19209289550781250e-07), RES(1.0000000596046406305e0, 4.1159035837679959288e-11)}, {FN (sec), ARG(6.28353057416258753420e+00,-1.19209289550781250e-07), RES(1.0000000596046406305e0, -4.1159035837679959288e-11)}, {FN (sec), ARG(-6.28353057416258753420e+00,1.19209289550781250e-07), RES(1.0000000596046406305e0, -4.1159035837679959288e-11)}, {FN (sec), ARG(-6.28353057416258753420e+00,-1.19209289550781250e-07), RES(1.0000000596046406305e0, 4.1159035837679959288e-11)}, {FN (sec), ARG(6.28353057416258753420e+00,5.0e-01), RES(8.8681891425248302482e-1, 1.4149533035930568923e-4)}, {FN (sec), ARG(6.28353057416258753420e+00,-5.0e-01), RES(8.8681891425248302482e-1, -1.4149533035930568923e-4)}, {FN (sec), ARG(-6.28353057416258753420e+00,5.0e-01), RES(8.8681891425248302482e-1, -1.4149533035930568923e-4)}, {FN (sec), ARG(-6.28353057416258753420e+00,-5.0e-01), RES(8.8681891425248302482e-1, 1.4149533035930568923e-4)}, {FN (sec), ARG(6.28353057416258753420e+00,1.0e+00), RES(6.480542674815748050e-1, 1.7040802567642290534e-4)}, {FN (sec), ARG(6.28353057416258753420e+00,-1.0e+00), RES(6.480542674815748050e-1, -1.7040802567642290534e-4)}, {FN (sec), ARG(-6.28353057416258753420e+00,1.0e+00), RES(6.480542674815748050e-1, -1.7040802567642290534e-4)}, {FN (sec), ARG(-6.28353057416258753420e+00,-1.0e+00), RES(6.480542674815748050e-1, 1.7040802567642290534e-4)}, {FN (sec), ARG(6.28353057416258753420e+00,2.0e+00), RES(2.6580221522968095408e-1, 8.8471445300326182148e-5)}, {FN (sec), ARG(6.28353057416258753420e+00,-2.0e+00), RES(2.6580221522968095408e-1, -8.8471445300326182148e-5)}, {FN (sec), ARG(-6.28353057416258753420e+00,2.0e+00), RES(2.6580221522968095408e-1, -8.8471445300326182148e-5)}, {FN (sec), ARG(-6.28353057416258753420e+00,-2.0e+00), RES(2.6580221522968095408e-1, 8.8471445300326182148e-5)}, {FN (sec), ARG(9.42443269378637893396e+00,0.0e+00), RES(-1.0000000596046477358e0, 0.0)}, {FN (sec), ARG(-9.42443269378637893396e+00,0.0e+00), RES(-1.0000000596046477358e0, 0.0)}, {FN (sec), ARG(9.42443269378637893396e+00,1.19209289550781250e-07), RES(-1.0000000596046406304e0, 4.1159035837647074798e-11)}, {FN (sec), ARG(9.42443269378637893396e+00,-1.19209289550781250e-07), RES(-1.0000000596046406304e0, -4.1159035837647074798e-11)}, {FN (sec), ARG(-9.42443269378637893396e+00,1.19209289550781250e-07), RES(-1.0000000596046406304e0, -4.1159035837647074798e-11)}, {FN (sec), ARG(-9.42443269378637893396e+00,-1.19209289550781250e-07), RES(-1.0000000596046406304e0, 4.1159035837647074798e-11)}, {FN (sec), ARG(9.42443269378637893396e+00,5.0e-01), RES(-8.8681891425248302477e-1, 1.4149533035919263990e-4)}, {FN (sec), ARG(9.42443269378637893396e+00,-5.0e-01), RES(-8.8681891425248302477e-1, -1.4149533035919263990e-4)}, {FN (sec), ARG(-9.42443269378637893396e+00,5.0e-01), RES(-8.8681891425248302477e-1, -1.4149533035919263990e-4)}, {FN (sec), ARG(-9.42443269378637893396e+00,-5.0e-01), RES(-8.8681891425248302477e-1, 1.4149533035919263990e-4)}, {FN (sec), ARG(9.42443269378637893396e+00,1.0e+00), RES(-6.4805426748157480501e-1, 1.7040802567628675588e-4)}, {FN (sec), ARG(9.42443269378637893396e+00,-1.0e+00), RES(-6.4805426748157480501e-1, -1.7040802567628675588e-4)}, {FN (sec), ARG(-9.42443269378637893396e+00,1.0e+00), RES(-6.4805426748157480501e-1, -1.7040802567628675588e-4)}, {FN (sec), ARG(-9.42443269378637893396e+00,-1.0e+00), RES(-6.4805426748157480501e-1, 1.7040802567628675588e-4)}, {FN (sec), ARG(9.42443269378637893396e+00,2.0e+00), RES(-2.6580221522968095410e-1, 8.8471445300255496873e-5)}, {FN (sec), ARG(9.42443269378637893396e+00,-2.0e+00), RES(-2.6580221522968095410e-1, -8.8471445300255496873e-5)}, {FN (sec), ARG(-9.42443269378637893396e+00,2.0e+00), RES(-2.6580221522968095410e-1, -8.8471445300255496873e-5)}, {FN (sec), ARG(-9.42443269378637893396e+00,-2.0e+00), RES(-2.6580221522968095410e-1, 8.8471445300255496873e-5)}, {FN (sec), ARG(9.42512322775237976202e+00,0.0e+00), RES(-1.0000000596046477356e0, 0.0)}, {FN (sec), ARG(-9.42512322775237976202e+00,0.0e+00), RES(-1.0000000596046477356e0, 0.0)}, {FN (sec), ARG(9.42512322775237976202e+00,1.19209289550781250e-07), RES(-1.0000000596046406301e0, -4.1159035837559481207e-11)}, {FN (sec), ARG(9.42512322775237976202e+00,-1.19209289550781250e-07), RES(-1.0000000596046406301e0, 4.1159035837559481207e-11)}, {FN (sec), ARG(-9.42512322775237976202e+00,1.19209289550781250e-07), RES(-1.0000000596046406301e0, 4.1159035837559481207e-11)}, {FN (sec), ARG(-9.42512322775237976202e+00,-1.19209289550781250e-07), RES(-1.0000000596046406301e0, -4.1159035837559481207e-11)}, {FN (sec), ARG(9.42512322775237976202e+00,5.0e-01), RES(-8.8681891425248302464e-1, -1.4149533035889151322e-4)}, {FN (sec), ARG(9.42512322775237976202e+00,-5.0e-01), RES(-8.8681891425248302464e-1, 1.4149533035889151322e-4)}, {FN (sec), ARG(-9.42512322775237976202e+00,5.0e-01), RES(-8.8681891425248302464e-1, 1.4149533035889151322e-4)}, {FN (sec), ARG(-9.42512322775237976202e+00,-5.0e-01), RES(-8.8681891425248302464e-1, -1.4149533035889151322e-4)}, {FN (sec), ARG(9.42512322775237976202e+00,1.0e+00), RES(-6.4805426748157480504e-1, -1.704080256759240980e-4)}, {FN (sec), ARG(9.42512322775237976202e+00,-1.0e+00), RES(-6.4805426748157480504e-1, 1.704080256759240980e-4)}, {FN (sec), ARG(-9.42512322775237976202e+00,1.0e+00), RES(-6.4805426748157480504e-1, 1.704080256759240980e-4)}, {FN (sec), ARG(-9.42512322775237976202e+00,-1.0e+00), RES(-6.4805426748157480504e-1, -1.704080256759240980e-4)}, {FN (sec), ARG(9.42512322775237976202e+00,2.0e+00), RES(-2.6580221522968095416e-1, -8.8471445300067214283e-5)}, {FN (sec), ARG(9.42512322775237976202e+00,-2.0e+00), RES(-2.6580221522968095416e-1, 8.8471445300067214283e-5)}, {FN (sec), ARG(-9.42512322775237976202e+00,2.0e+00), RES(-2.6580221522968095416e-1, 8.8471445300067214283e-5)}, {FN (sec), ARG(-9.42512322775237976202e+00,-2.0e+00), RES(-2.6580221522968095416e-1, -8.8471445300067214283e-5)}, {FN (cot), ARG(-3.45266983001243932001e-04,0.0e+00), RES(-2.8963092606511032136e3, 0.0)}, {FN (cot), ARG(3.45266983001243932001e-04,0.0e+00), RES(2.8963092606511032136e3, 0.0)}, {FN (cot), ARG(-3.45266983001243932001e-04,1.19209289550781250e-07), RES(-2.8963089153841613713e3, -9.9999992052715532101e-1)}, {FN (cot), ARG(-3.45266983001243932001e-04,-1.19209289550781250e-07), RES(-2.8963089153841613713e3, 9.9999992052715532101e-1)}, {FN (cot), ARG(3.45266983001243932001e-04,1.19209289550781250e-07), RES(2.8963089153841613713e3, -9.9999992052715532101e-1)}, {FN (cot), ARG(3.45266983001243932001e-04,-1.19209289550781250e-07), RES(2.8963089153841613713e3, 9.9999992052715532101e-1)}, {FN (cot), ARG(-3.45266983001243932001e-04,5.0e-01), RES(-1.2715121175451222247e-3, -2.1639524637389326002e0)}, {FN (cot), ARG(-3.45266983001243932001e-04,-5.0e-01), RES(-1.2715121175451222247e-3, 2.1639524637389326002e0)}, {FN (cot), ARG(3.45266983001243932001e-04,5.0e-01), RES(1.2715121175451222247e-3, -2.1639524637389326002e0)}, {FN (cot), ARG(3.45266983001243932001e-04,-5.0e-01), RES(1.2715121175451222247e-3, 2.1639524637389326002e0)}, {FN (cot), ARG(-3.45266983001243932001e-04,1.0e+00), RES(-2.4999454374267620687e-4, -1.3130351721648674824e0)}, {FN (cot), ARG(-3.45266983001243932001e-04,-1.0e+00), RES(-2.4999454374267620687e-4, 1.3130351721648674824e0)}, {FN (cot), ARG(3.45266983001243932001e-04,1.0e+00), RES(2.4999454374267620687e-4, -1.3130351721648674824e0)}, {FN (cot), ARG(3.45266983001243932001e-04,-1.0e+00), RES(2.4999454374267620687e-4, 1.3130351721648674824e0)}, {FN (cot), ARG(-3.45266983001243932001e-04,2.0e+00), RES(-2.6247825506563736365e-5, -1.0373147113268752620e0)}, {FN (cot), ARG(-3.45266983001243932001e-04,-2.0e+00), RES(-2.6247825506563736365e-5, 1.0373147113268752620e0)}, {FN (cot), ARG(3.45266983001243932001e-04,2.0e+00), RES(2.6247825506563736365e-5, -1.0373147113268752620e0)}, {FN (cot), ARG(3.45266983001243932001e-04,-2.0e+00), RES(2.6247825506563736365e-5, 1.0373147113268752620e0)}, {FN (cot), ARG(1.57045105981189525579e+00,0.0e+00), RES(3.4526699672104134407e-4, 0.0)}, {FN (cot), ARG(-1.57045105981189525579e+00,0.0e+00), RES(-3.4526699672104134407e-4, 0.0)}, {FN (cot), ARG(1.57045105981189525579e+00,1.19209289550781250e-07), RES(3.4526699672103643753e-4, -1.1920930376163652990e-7)}, {FN (cot), ARG(1.57045105981189525579e+00,-1.19209289550781250e-07), RES(3.4526699672103643753e-4, 1.1920930376163652990e-7)}, {FN (cot), ARG(-1.57045105981189525579e+00,1.19209289550781250e-07), RES(-3.4526699672103643753e-4, -1.1920930376163652990e-7)}, {FN (cot), ARG(-1.57045105981189525579e+00,-1.19209289550781250e-07), RES(-3.4526699672103643753e-4, 1.1920930376163652990e-7)}, {FN (cot), ARG(1.57045105981189525579e+00,5.0e-01), RES(2.7153443992665204631e-4, -4.6211720058436229982e-1)}, {FN (cot), ARG(1.57045105981189525579e+00,-5.0e-01), RES(2.7153443992665204631e-4, 4.6211720058436229982e-1)}, {FN (cot), ARG(-1.57045105981189525579e+00,5.0e-01), RES(-2.7153443992665204631e-4, -4.6211720058436229982e-1)}, {FN (cot), ARG(-1.57045105981189525579e+00,-5.0e-01), RES(-2.7153443992665204631e-4, 4.6211720058436229982e-1)}, {FN (cot), ARG(1.57045105981189525579e+00,1.0e+00), RES(1.4500326960279979918e-4, -7.6159419408485704839e-1)}, {FN (cot), ARG(1.57045105981189525579e+00,-1.0e+00), RES(1.4500326960279979918e-4, 7.6159419408485704839e-1)}, {FN (cot), ARG(-1.57045105981189525579e+00,1.0e+00), RES(-1.4500326960279979918e-4, -7.6159419408485704839e-1)}, {FN (cot), ARG(-1.57045105981189525579e+00,-1.0e+00), RES(-1.4500326960279979918e-4, 7.6159419408485704839e-1)}, {FN (cot), ARG(1.57045105981189525579e+00,2.0e+00), RES(2.4393395410443750226e-5, -9.6402758819508310557e-1)}, {FN (cot), ARG(1.57045105981189525579e+00,-2.0e+00), RES(2.4393395410443750226e-5, 9.6402758819508310557e-1)}, {FN (cot), ARG(-1.57045105981189525579e+00,2.0e+00), RES(-2.4393395410443750226e-5, -9.6402758819508310557e-1)}, {FN (cot), ARG(-1.57045105981189525579e+00,-2.0e+00), RES(-2.4393395410443750226e-5, 9.6402758819508310557e-1)}, {FN (cot), ARG(1.57114159377789786021e+00,0.0e+00), RES(-3.4526699672091887937e-4, 0.0)}, {FN (cot), ARG(-1.57114159377789786021e+00,0.0e+00), RES(3.4526699672091887937e-4, 0.0)}, {FN (cot), ARG(1.57114159377789786021e+00,1.19209289550781250e-07), RES(-3.4526699672091397283e-4, -1.1920930376163652989e-7)}, {FN (cot), ARG(1.57114159377789786021e+00,-1.19209289550781250e-07), RES(-3.4526699672091397283e-4, 1.1920930376163652989e-7)}, {FN (cot), ARG(-1.57114159377789786021e+00,1.19209289550781250e-07), RES(3.4526699672091397283e-4, -1.1920930376163652989e-7)}, {FN (cot), ARG(-1.57114159377789786021e+00,-1.19209289550781250e-07), RES(3.4526699672091397283e-4, 1.1920930376163652989e-7)}, {FN (cot), ARG(1.57114159377789786021e+00,5.0e-01), RES(-2.7153443992655573423e-4, -4.6211720058436229979e-1)}, {FN (cot), ARG(1.57114159377789786021e+00,-5.0e-01), RES(-2.7153443992655573423e-4, 4.6211720058436229979e-1)}, {FN (cot), ARG(-1.57114159377789786021e+00,5.0e-01), RES(2.7153443992655573423e-4, -4.6211720058436229979e-1)}, {FN (cot), ARG(-1.57114159377789786021e+00,-5.0e-01), RES(2.7153443992655573423e-4, 4.6211720058436229979e-1)}, {FN (cot), ARG(1.57114159377789786021e+00,1.0e+00), RES(-1.4500326960274836716e-4, -7.6159419408485704836e-1)}, {FN (cot), ARG(1.57114159377789786021e+00,-1.0e+00), RES(-1.4500326960274836716e-4, 7.6159419408485704836e-1)}, {FN (cot), ARG(-1.57114159377789786021e+00,1.0e+00), RES(1.4500326960274836716e-4, -7.6159419408485704836e-1)}, {FN (cot), ARG(-1.57114159377789786021e+00,-1.0e+00), RES(1.4500326960274836716e-4, 7.6159419408485704836e-1)}, {FN (cot), ARG(1.57114159377789786021e+00,2.0e+00), RES(-2.4393395410435097997e-5, -9.6402758819508310556e-1)}, {FN (cot), ARG(1.57114159377789786021e+00,-2.0e+00), RES(-2.4393395410435097997e-5, 9.6402758819508310556e-1)}, {FN (cot), ARG(-1.57114159377789786021e+00,2.0e+00), RES(2.4393395410435097997e-5, -9.6402758819508310556e-1)}, {FN (cot), ARG(-1.57114159377789786021e+00,-2.0e+00), RES(2.4393395410435097997e-5, 9.6402758819508310556e-1)}, {FN (cot), ARG(3.14124738660679181379e+00,0.0e+00), RES(-2.8963092606495870519e3, 0.0)}, {FN (cot), ARG(-3.14124738660679181379e+00,0.0e+00), RES(2.8963092606495870519e3, 0.0)}, {FN (cot), ARG(3.14124738660679181379e+00,1.19209289550781250e-07), RES(-2.8963089153826452102e3, -9.9999992052610836018e-1)}, {FN (cot), ARG(3.14124738660679181379e+00,-1.19209289550781250e-07), RES(-2.8963089153826452102e3, 9.9999992052610836018e-1)}, {FN (cot), ARG(-3.14124738660679181379e+00,1.19209289550781250e-07), RES(2.8963089153826452102e3, -9.9999992052610836018e-1)}, {FN (cot), ARG(-3.14124738660679181379e+00,-1.19209289550781250e-07), RES(2.8963089153826452102e3, 9.9999992052610836018e-1)}, {FN (cot), ARG(3.14124738660679181379e+00,5.0e-01), RES(-1.2715121175457878359e-3, -2.1639524637389325992e0)}, {FN (cot), ARG(3.14124738660679181379e+00,-5.0e-01), RES(-1.2715121175457878359e-3, 2.1639524637389325992e0)}, {FN (cot), ARG(-3.14124738660679181379e+00,5.0e-01), RES(1.2715121175457878359e-3, -2.1639524637389325992e0)}, {FN (cot), ARG(-3.14124738660679181379e+00,-5.0e-01), RES(1.2715121175457878359e-3, 2.1639524637389325992e0)}, {FN (cot), ARG(3.14124738660679181379e+00,1.0e+00), RES(-2.4999454374280707411e-4, -1.3130351721648674823e0)}, {FN (cot), ARG(3.14124738660679181379e+00,-1.0e+00), RES(-2.4999454374280707411e-4, 1.3130351721648674823e0)}, {FN (cot), ARG(-3.14124738660679181379e+00,1.0e+00), RES(2.4999454374280707411e-4, -1.3130351721648674823e0)}, {FN (cot), ARG(-3.14124738660679181379e+00,-1.0e+00), RES(2.4999454374280707411e-4, 1.3130351721648674823e0)}, {FN (cot), ARG(3.14124738660679181379e+00,2.0e+00), RES(-2.6247825506577476589e-5, -1.0373147113268752620e0)}, {FN (cot), ARG(3.14124738660679181379e+00,-2.0e+00), RES(-2.6247825506577476589e-5, 1.0373147113268752620e0)}, {FN (cot), ARG(-3.14124738660679181379e+00,2.0e+00), RES(2.6247825506577476589e-5, -1.0373147113268752620e0)}, {FN (cot), ARG(-3.14124738660679181379e+00,-2.0e+00), RES(2.6247825506577476589e-5, 1.0373147113268752620e0)}, {FN (cot), ARG(3.14193792057279441821e+00,0.0e+00), RES(2.8963092606516416684e3, 0.0)}, {FN (cot), ARG(-3.14193792057279441821e+00,0.0e+00), RES(-2.8963092606516416684e3, 0.0)}, {FN (cot), ARG(3.14193792057279441821e+00,1.19209289550781250e-07), RES(2.8963089153846998260e3, -9.9999992052752714224e-1)}, {FN (cot), ARG(3.14193792057279441821e+00,-1.19209289550781250e-07), RES(2.8963089153846998260e3, 9.9999992052752714224e-1)}, {FN (cot), ARG(-3.14193792057279441821e+00,1.19209289550781250e-07), RES(-2.8963089153846998260e3, -9.9999992052752714224e-1)}, {FN (cot), ARG(-3.14193792057279441821e+00,-1.19209289550781250e-07), RES(-2.8963089153846998260e3, 9.9999992052752714224e-1)}, {FN (cot), ARG(3.14193792057279441821e+00,5.0e-01), RES(1.2715121175448858373e-3, -2.1639524637389326006e0)}, {FN (cot), ARG(3.14193792057279441821e+00,-5.0e-01), RES(1.2715121175448858373e-3, 2.1639524637389326006e0)}, {FN (cot), ARG(-3.14193792057279441821e+00,5.0e-01), RES(-1.2715121175448858373e-3, -2.1639524637389326006e0)}, {FN (cot), ARG(-3.14193792057279441821e+00,-5.0e-01), RES(-1.2715121175448858373e-3, 2.1639524637389326006e0)}, {FN (cot), ARG(3.14193792057279441821e+00,1.0e+00), RES(2.4999454374262973024e-4, -1.3130351721648674824e0)}, {FN (cot), ARG(3.14193792057279441821e+00,-1.0e+00), RES(2.4999454374262973024e-4, 1.3130351721648674824e0)}, {FN (cot), ARG(-3.14193792057279441821e+00,1.0e+00), RES(-2.4999454374262973024e-4, -1.3130351721648674824e0)}, {FN (cot), ARG(-3.14193792057279441821e+00,-1.0e+00), RES(-2.4999454374262973024e-4, 1.3130351721648674824e0)}, {FN (cot), ARG(3.14193792057279441821e+00,2.0e+00), RES(2.6247825506558856616e-5, -1.0373147113268752620e0)}, {FN (cot), ARG(3.14193792057279441821e+00,-2.0e+00), RES(2.6247825506558856616e-5, 1.0373147113268752620e0)}, {FN (cot), ARG(-3.14193792057279441821e+00,2.0e+00), RES(-2.6247825506558856616e-5, -1.0373147113268752620e0)}, {FN (cot), ARG(-3.14193792057279441821e+00,-2.0e+00), RES(-2.6247825506558856616e-5, 1.0373147113268752620e0)}, {FN (cot), ARG(4.71204371340168837179e+00,0.0e+00), RES(3.4526699672116380876e-4, 0.0)}, {FN (cot), ARG(-4.71204371340168837179e+00,0.0e+00), RES(-3.4526699672116380876e-4, 0.0)}, {FN (cot), ARG(4.71204371340168837179e+00,1.19209289550781250e-07), RES(3.4526699672115890222e-4, -1.1920930376163652991e-7)}, {FN (cot), ARG(4.71204371340168837179e+00,-1.19209289550781250e-07), RES(3.4526699672115890222e-4, 1.1920930376163652991e-7)}, {FN (cot), ARG(-4.71204371340168837179e+00,1.19209289550781250e-07), RES(-3.4526699672115890222e-4, -1.1920930376163652991e-7)}, {FN (cot), ARG(-4.71204371340168837179e+00,-1.19209289550781250e-07), RES(-3.4526699672115890222e-4, 1.1920930376163652991e-7)}, {FN (cot), ARG(4.71204371340168837179e+00,5.0e-01), RES(2.7153443992674835838e-4, -4.6211720058436229985e-1)}, {FN (cot), ARG(4.71204371340168837179e+00,-5.0e-01), RES(2.7153443992674835838e-4, 4.6211720058436229985e-1)}, {FN (cot), ARG(-4.71204371340168837179e+00,5.0e-01), RES(-2.7153443992674835838e-4, -4.6211720058436229985e-1)}, {FN (cot), ARG(-4.71204371340168837179e+00,-5.0e-01), RES(-2.7153443992674835838e-4, 4.6211720058436229985e-1)}, {FN (cot), ARG(4.71204371340168837179e+00,1.0e+00), RES(1.4500326960285123120e-4, -7.6159419408485704842e-1)}, {FN (cot), ARG(4.71204371340168837179e+00,-1.0e+00), RES(1.4500326960285123120e-4, 7.6159419408485704842e-1)}, {FN (cot), ARG(-4.71204371340168837179e+00,1.0e+00), RES(-1.4500326960285123120e-4, -7.6159419408485704842e-1)}, {FN (cot), ARG(-4.71204371340168837179e+00,-1.0e+00), RES(-1.4500326960285123120e-4, 7.6159419408485704842e-1)}, {FN (cot), ARG(4.71204371340168837179e+00,2.0e+00), RES(2.4393395410452402454e-5, -9.6402758819508310557e-1)}, {FN (cot), ARG(4.71204371340168837179e+00,-2.0e+00), RES(2.4393395410452402454e-5, 9.6402758819508310557e-1)}, {FN (cot), ARG(-4.71204371340168837179e+00,2.0e+00), RES(-2.4393395410452402454e-5, -9.6402758819508310557e-1)}, {FN (cot), ARG(-4.71204371340168837179e+00,-2.0e+00), RES(-2.4393395410452402454e-5, 9.6402758819508310557e-1)}, {FN (cot), ARG(4.71273424736769097620e+00,0.0e+00), RES(-3.4526699672079641468e-4, 0.0)}, {FN (cot), ARG(-4.71273424736769097620e+00,0.0e+00), RES(3.4526699672079641468e-4, 0.0)}, {FN (cot), ARG(4.71273424736769097620e+00,1.19209289550781250e-07), RES(-3.4526699672079150814e-4, -1.1920930376163652988e-7)}, {FN (cot), ARG(4.71273424736769097620e+00,-1.19209289550781250e-07), RES(-3.4526699672079150814e-4, 1.1920930376163652988e-7)}, {FN (cot), ARG(-4.71273424736769097620e+00,1.19209289550781250e-07), RES(3.4526699672079150814e-4, -1.1920930376163652988e-7)}, {FN (cot), ARG(-4.71273424736769097620e+00,-1.19209289550781250e-07), RES(3.4526699672079150814e-4, 1.1920930376163652988e-7)}, {FN (cot), ARG(4.71273424736769097620e+00,5.0e-01), RES(-2.7153443992645942216e-4, -4.6211720058436229976e-1)}, {FN (cot), ARG(4.71273424736769097620e+00,-5.0e-01), RES(-2.7153443992645942216e-4, 4.6211720058436229976e-1)}, {FN (cot), ARG(-4.71273424736769097620e+00,5.0e-01), RES(2.7153443992645942216e-4, -4.6211720058436229976e-1)}, {FN (cot), ARG(-4.71273424736769097620e+00,-5.0e-01), RES(2.7153443992645942216e-4, 4.6211720058436229976e-1)}, {FN (cot), ARG(4.71273424736769097620e+00,1.0e+00), RES(-1.4500326960269693514e-4, -7.6159419408485704834e-1)}, {FN (cot), ARG(4.71273424736769097620e+00,-1.0e+00), RES(-1.4500326960269693514e-4, 7.6159419408485704834e-1)}, {FN (cot), ARG(-4.71273424736769097620e+00,1.0e+00), RES(1.4500326960269693514e-4, -7.6159419408485704834e-1)}, {FN (cot), ARG(-4.71273424736769097620e+00,-1.0e+00), RES(1.4500326960269693514e-4, 7.6159419408485704834e-1)}, {FN (cot), ARG(4.71273424736769097620e+00,2.0e+00), RES(-2.4393395410426445768e-5, -9.6402758819508310556e-1)}, {FN (cot), ARG(4.71273424736769097620e+00,-2.0e+00), RES(-2.4393395410426445768e-5, 9.6402758819508310556e-1)}, {FN (cot), ARG(-4.71273424736769097620e+00,2.0e+00), RES(2.4393395410426445768e-5, -9.6402758819508310556e-1)}, {FN (cot), ARG(-4.71273424736769097620e+00,-2.0e+00), RES(2.4393395410426445768e-5, 9.6402758819508310556e-1)}, {FN (cot), ARG(6.28284004019658492979e+00,0.0e+00), RES(-2.8963092606485597437e3, 0.0)}, {FN (cot), ARG(-6.28284004019658492979e+00,0.0e+00), RES(2.8963092606485597437e3, 0.0)}, {FN (cot), ARG(6.28284004019658492979e+00,1.19209289550781250e-07), RES(-2.8963089153816179024e3, -9.9999992052539896914e-1)}, {FN (cot), ARG(6.28284004019658492979e+00,-1.19209289550781250e-07), RES(-2.8963089153816179024e3, 9.9999992052539896914e-1)}, {FN (cot), ARG(-6.28284004019658492979e+00,1.19209289550781250e-07), RES(2.8963089153816179024e3, -9.9999992052539896914e-1)}, {FN (cot), ARG(-6.28284004019658492979e+00,-1.19209289550781250e-07), RES(2.8963089153816179024e3, 9.9999992052539896914e-1)}, {FN (cot), ARG(6.28284004019658492979e+00,5.0e-01), RES(-1.2715121175462388352e-3, -2.1639524637389325986e0)}, {FN (cot), ARG(6.28284004019658492979e+00,-5.0e-01), RES(-1.2715121175462388352e-3, 2.1639524637389325986e0)}, {FN (cot), ARG(-6.28284004019658492979e+00,5.0e-01), RES(1.2715121175462388352e-3, -2.1639524637389325986e0)}, {FN (cot), ARG(-6.28284004019658492979e+00,-5.0e-01), RES(1.2715121175462388352e-3, 2.1639524637389325986e0)}, {FN (cot), ARG(6.28284004019658492979e+00,1.0e+00), RES(-2.4999454374289574604e-4, -1.3130351721648674822e0)}, {FN (cot), ARG(6.28284004019658492979e+00,-1.0e+00), RES(-2.4999454374289574604e-4, 1.3130351721648674822e0)}, {FN (cot), ARG(-6.28284004019658492979e+00,1.0e+00), RES(2.4999454374289574604e-4, -1.3130351721648674822e0)}, {FN (cot), ARG(-6.28284004019658492979e+00,-1.0e+00), RES(2.4999454374289574604e-4, 1.3130351721648674822e0)}, {FN (cot), ARG(6.28284004019658492979e+00,2.0e+00), RES(-2.6247825506586786575e-5, -1.0373147113268752620e0)}, {FN (cot), ARG(6.28284004019658492979e+00,-2.0e+00), RES(-2.6247825506586786575e-5, 1.0373147113268752620e0)}, {FN (cot), ARG(-6.28284004019658492979e+00,2.0e+00), RES(2.6247825506586786575e-5, -1.0373147113268752620e0)}, {FN (cot), ARG(-6.28284004019658492979e+00,-2.0e+00), RES(2.6247825506586786575e-5, 1.0373147113268752620e0)}, {FN (cot), ARG(6.28353057416258753420e+00,0.0e+00), RES(2.8963092606526689766e3, 0.0)}, {FN (cot), ARG(-6.28353057416258753420e+00,0.0e+00), RES(-2.8963092606526689766e3, 0.0)}, {FN (cot), ARG(6.28353057416258753420e+00,1.19209289550781250e-07), RES(2.8963089153857271338e3, -9.9999992052823653327e-1)}, {FN (cot), ARG(6.28353057416258753420e+00,-1.19209289550781250e-07), RES(2.8963089153857271338e3, 9.9999992052823653327e-1)}, {FN (cot), ARG(-6.28353057416258753420e+00,1.19209289550781250e-07), RES(-2.8963089153857271338e3, -9.9999992052823653327e-1)}, {FN (cot), ARG(-6.28353057416258753420e+00,-1.19209289550781250e-07), RES(-2.8963089153857271338e3, 9.9999992052823653327e-1)}, {FN (cot), ARG(6.28353057416258753420e+00,5.0e-01), RES(1.2715121175444348380e-3, -2.1639524637389326012e0)}, {FN (cot), ARG(6.28353057416258753420e+00,-5.0e-01), RES(1.2715121175444348380e-3, 2.1639524637389326012e0)}, {FN (cot), ARG(-6.28353057416258753420e+00,5.0e-01), RES(-1.2715121175444348380e-3, -2.1639524637389326012e0)}, {FN (cot), ARG(-6.28353057416258753420e+00,-5.0e-01), RES(-1.2715121175444348380e-3, 2.1639524637389326012e0)}, {FN (cot), ARG(6.28353057416258753420e+00,1.0e+00), RES(2.4999454374254105830e-4, -1.3130351721648674825e0)}, {FN (cot), ARG(6.28353057416258753420e+00,-1.0e+00), RES(2.4999454374254105830e-4, 1.3130351721648674825e0)}, {FN (cot), ARG(-6.28353057416258753420e+00,1.0e+00), RES(-2.4999454374254105830e-4, -1.3130351721648674825e0)}, {FN (cot), ARG(-6.28353057416258753420e+00,-1.0e+00), RES(-2.4999454374254105830e-4, 1.3130351721648674825e0)}, {FN (cot), ARG(6.28353057416258753420e+00,2.0e+00), RES(2.6247825506549546629e-5, -1.0373147113268752620e0)}, {FN (cot), ARG(6.28353057416258753420e+00,-2.0e+00), RES(2.6247825506549546629e-5, 1.0373147113268752620e0)}, {FN (cot), ARG(-6.28353057416258753420e+00,2.0e+00), RES(-2.6247825506549546629e-5, -1.0373147113268752620e0)}, {FN (cot), ARG(-6.28353057416258753420e+00,-2.0e+00), RES(-2.6247825506549546629e-5, 1.0373147113268752620e0)}, {FN (cot), ARG(9.42443269378637893396e+00,0.0e+00), RES(-2.8963092606549830163e3, 0.0)}, {FN (cot), ARG(-9.42443269378637893396e+00,0.0e+00), RES(2.8963092606549830163e3, 0.0)}, {FN (cot), ARG(9.42443269378637893396e+00,1.19209289550781250e-07), RES(-2.8963089153880411727e3, -9.9999992052983445585e-1)}, {FN (cot), ARG(9.42443269378637893396e+00,-1.19209289550781250e-07), RES(-2.8963089153880411727e3, 9.9999992052983445585e-1)}, {FN (cot), ARG(-9.42443269378637893396e+00,1.19209289550781250e-07), RES(2.8963089153880411727e3, -9.9999992052983445585e-1)}, {FN (cot), ARG(-9.42443269378637893396e+00,-1.19209289550781250e-07), RES(2.8963089153880411727e3, 9.9999992052983445585e-1)}, {FN (cot), ARG(9.42443269378637893396e+00,5.0e-01), RES(-1.2715121175434189499e-3, -2.1639524637389326028e0)}, {FN (cot), ARG(9.42443269378637893396e+00,-5.0e-01), RES(-1.2715121175434189499e-3, 2.1639524637389326028e0)}, {FN (cot), ARG(-9.42443269378637893396e+00,5.0e-01), RES(1.2715121175434189499e-3, -2.1639524637389326028e0)}, {FN (cot), ARG(-9.42443269378637893396e+00,-5.0e-01), RES(1.2715121175434189499e-3, 2.1639524637389326028e0)}, {FN (cot), ARG(9.42443269378637893396e+00,1.0e+00), RES(-2.4999454374234132236e-4, -1.3130351721648674827e0)}, {FN (cot), ARG(9.42443269378637893396e+00,-1.0e+00), RES(-2.4999454374234132236e-4, 1.3130351721648674827e0)}, {FN (cot), ARG(-9.42443269378637893396e+00,1.0e+00), RES(2.4999454374234132236e-4, -1.3130351721648674827e0)}, {FN (cot), ARG(-9.42443269378637893396e+00,-1.0e+00), RES(2.4999454374234132236e-4, 1.3130351721648674827e0)}, {FN (cot), ARG(9.42443269378637893396e+00,2.0e+00), RES(-2.6247825506528575631e-5, -1.0373147113268752620e0)}, {FN (cot), ARG(9.42443269378637893396e+00,-2.0e+00), RES(-2.6247825506528575631e-5, 1.0373147113268752620e0)}, {FN (cot), ARG(-9.42443269378637893396e+00,2.0e+00), RES(2.6247825506528575631e-5, -1.0373147113268752620e0)}, {FN (cot), ARG(-9.42443269378637893396e+00,-2.0e+00), RES(2.6247825506528575631e-5, 1.0373147113268752620e0)}, {FN (cot), ARG(9.42512322775237976202e+00,0.0e+00), RES(2.8963092606611468657e3, 0.0)}, {FN (cot), ARG(-9.42512322775237976202e+00,0.0e+00), RES(-2.8963092606611468657e3, 0.0)}, {FN (cot), ARG(9.42512322775237976202e+00,1.19209289550781250e-07), RES(2.8963089153942050199e3, -9.9999992053409080205e-1)}, {FN (cot), ARG(9.42512322775237976202e+00,-1.19209289550781250e-07), RES(2.8963089153942050199e3, 9.9999992053409080205e-1)}, {FN (cot), ARG(-9.42512322775237976202e+00,1.19209289550781250e-07), RES(-2.8963089153942050199e3, -9.9999992053409080205e-1)}, {FN (cot), ARG(-9.42512322775237976202e+00,-1.19209289550781250e-07), RES(-2.8963089153942050199e3, 9.9999992053409080205e-1)}, {FN (cot), ARG(9.42512322775237976202e+00,5.0e-01), RES(1.2715121175407129542e-3, -2.1639524637389326068e0)}, {FN (cot), ARG(9.42512322775237976202e+00,-5.0e-01), RES(1.2715121175407129542e-3, 2.1639524637389326068e0)}, {FN (cot), ARG(-9.42512322775237976202e+00,5.0e-01), RES(-1.2715121175407129542e-3, -2.1639524637389326068e0)}, {FN (cot), ARG(-9.42512322775237976202e+00,-5.0e-01), RES(-1.2715121175407129542e-3, 2.1639524637389326068e0)}, {FN (cot), ARG(9.42512322775237976202e+00,1.0e+00), RES(2.4999454374180929074e-4, -1.3130351721648674832e0)}, {FN (cot), ARG(9.42512322775237976202e+00,-1.0e+00), RES(2.4999454374180929074e-4, 1.3130351721648674832e0)}, {FN (cot), ARG(-9.42512322775237976202e+00,1.0e+00), RES(-2.4999454374180929074e-4, -1.3130351721648674832e0)}, {FN (cot), ARG(-9.42512322775237976202e+00,-1.0e+00), RES(-2.4999454374180929074e-4, 1.3130351721648674832e0)}, {FN (cot), ARG(9.42512322775237976202e+00,2.0e+00), RES(2.6247825506472715712e-5, -1.0373147113268752621e0)}, {FN (cot), ARG(9.42512322775237976202e+00,-2.0e+00), RES(2.6247825506472715712e-5, 1.0373147113268752621e0)}, {FN (cot), ARG(-9.42512322775237976202e+00,2.0e+00), RES(-2.6247825506472715712e-5, -1.0373147113268752621e0)}, {FN (cot), ARG(-9.42512322775237976202e+00,-2.0e+00), RES(-2.6247825506472715712e-5, 1.0373147113268752621e0)}, {FN (arccsc), ARG(0.0e+00,1.19209289550781250e-07), RES(0, -1.6635532333438690979e1)}, {FN (arccsc), ARG(0.0e+00,-1.19209289550781250e-07), RES(0, 1.6635532333438690979e1)}, {FN (arccsc), ARG(0.0e+00,5.0e-01), RES(0, -1.4436354751788103425e0)}, {FN (arccsc), ARG(0.0e+00,-5.0e-01), RES(0, 1.4436354751788103425e0)}, {FN (arccsc), ARG(0.0e+00,1.0e+00), RES(0, -8.8137358701954302523e-1)}, {FN (arccsc), ARG(0.0e+00,-1.0e+00), RES(0, 8.8137358701954302523e-1)}, {FN (arccsc), ARG(0.0e+00,2.0e+00), RES(0, -4.8121182505960344750e-1)}, {FN (arccsc), ARG(0.0e+00,-2.0e+00), RES(0, 4.8121182505960344750e-1)}, {FN (arccsc), ARG(0.0e+00,8.3886080e+06), RES(0, -1.1920928955078096766e-7)}, {FN (arccsc), ARG(0.0e+00,-8.3886080e+06), RES(0, 1.1920928955078096766e-7)}, {FN (arccsc), ARG(1.19209289550781250e-07,0.0e+00), RES(1.5707963267948966192e0, -1.6635532333438683873e1)}, {FN (arccsc), ARG(-1.19209289550781250e-07,0.0e+00), RES(-1.5707963267948966192e0, 1.6635532333438683873e1)}, {FN (arccsc), ARG(1.19209289550781250e-07,1.19209289550781250e-07), RES(7.8539816339744120419e-1, -1.6288958743158714771e1)}, {FN (arccsc), ARG(1.19209289550781250e-07,-1.19209289550781250e-07), RES(7.8539816339744120419e-1, 1.6288958743158714771e1)}, {FN (arccsc), ARG(-1.19209289550781250e-07,1.19209289550781250e-07), RES(-7.8539816339744120419e-1, -1.6288958743158714771e1)}, {FN (arccsc), ARG(-1.19209289550781250e-07,-1.19209289550781250e-07), RES(-7.8539816339744120419e-1, 1.6288958743158714771e1)}, {FN (arccsc), ARG(1.19209289550781250e-07,5.0e-01), RES(2.1324805998799710740e-7, -1.4436354751787798371e0)}, {FN (arccsc), ARG(1.19209289550781250e-07,-5.0e-01), RES(2.1324805998799710740e-7, 1.4436354751787798371e0)}, {FN (arccsc), ARG(-1.19209289550781250e-07,5.0e-01), RES(-2.1324805998799710740e-7, -1.4436354751787798371e0)}, {FN (arccsc), ARG(-1.19209289550781250e-07,-5.0e-01), RES(-2.1324805998799710740e-7, 1.4436354751787798371e0)}, {FN (arccsc), ARG(1.19209289550781250e-07,1.0e+00), RES(8.4293697021787414719e-8, -8.8137358701953548879e-1)}, {FN (arccsc), ARG(1.19209289550781250e-07,-1.0e+00), RES(8.4293697021787414719e-8, 8.8137358701953548879e-1)}, {FN (arccsc), ARG(-1.19209289550781250e-07,1.0e+00), RES(-8.4293697021787414719e-8, -8.8137358701953548879e-1)}, {FN (arccsc), ARG(-1.19209289550781250e-07,-1.0e+00), RES(-8.4293697021787414719e-8, 8.8137358701953548879e-1)}, {FN (arccsc), ARG(1.19209289550781250e-07,2.0e+00), RES(2.6656007498500149811e-8, -4.8121182505960201756e-1)}, {FN (arccsc), ARG(1.19209289550781250e-07,-2.0e+00), RES(2.6656007498500149811e-8, 4.8121182505960201756e-1)}, {FN (arccsc), ARG(-1.19209289550781250e-07,2.0e+00), RES(-2.6656007498500149811e-8, -4.8121182505960201756e-1)}, {FN (arccsc), ARG(-1.19209289550781250e-07,-2.0e+00), RES(-2.6656007498500149811e-8, 4.8121182505960201756e-1)}, {FN (arccsc), ARG(1.19209289550781250e-07,8.3886080e+06), RES(1.6940658945085886411e-21, -1.1920928955078096766e-7)}, {FN (arccsc), ARG(1.19209289550781250e-07,-8.3886080e+06), RES(1.6940658945085886411e-21, 1.1920928955078096766e-7)}, {FN (arccsc), ARG(-1.19209289550781250e-07,8.3886080e+06), RES(-1.6940658945085886411e-21, -1.1920928955078096766e-7)}, {FN (arccsc), ARG(-1.19209289550781250e-07,-8.3886080e+06), RES(-1.6940658945085886411e-21, 1.1920928955078096766e-7)}, {FN (arccsc), ARG(5.0e-01,0.0e+00), RES(1.5707963267948966192e0, -1.3169578969248167086e0)}, {FN (arccsc), ARG(-5.0e-01,0.0e+00), RES(-1.5707963267948966192e0, 1.3169578969248167086e0)}, {FN (arccsc), ARG(5.0e-01,1.19209289550781250e-07), RES(1.5707960514928349710e0, -1.3169578969247948296e0)}, {FN (arccsc), ARG(5.0e-01,-1.19209289550781250e-07), RES(1.5707960514928349710e0, 1.3169578969247948296e0)}, {FN (arccsc), ARG(-5.0e-01,1.19209289550781250e-07), RES(-1.5707960514928349710e0, -1.3169578969247948296e0)}, {FN (arccsc), ARG(-5.0e-01,-1.19209289550781250e-07), RES(-1.5707960514928349710e0, 1.3169578969247948296e0)}, {FN (arccsc), ARG(5.0e-01,5.0e-01), RES(6.6623943249251525510e-1, -1.0612750619050356520e0)}, {FN (arccsc), ARG(5.0e-01,-5.0e-01), RES(6.6623943249251525510e-1, 1.0612750619050356520e0)}, {FN (arccsc), ARG(-5.0e-01,5.0e-01), RES(-6.6623943249251525510e-1, -1.0612750619050356520e0)}, {FN (arccsc), ARG(-5.0e-01,-5.0e-01), RES(-6.6623943249251525510e-1, 1.0612750619050356520e0)}, {FN (arccsc), ARG(5.0e-01,1.0e+00), RES(3.1122579724476109533e-1, -7.6388434595371104541e-1)}, {FN (arccsc), ARG(5.0e-01,-1.0e+00), RES(3.1122579724476109533e-1, 7.6388434595371104541e-1)}, {FN (arccsc), ARG(-5.0e-01,1.0e+00), RES(-3.1122579724476109533e-1, -7.6388434595371104541e-1)}, {FN (arccsc), ARG(-5.0e-01,-1.0e+00), RES(-3.1122579724476109533e-1, 7.6388434595371104541e-1)}, {FN (arccsc), ARG(5.0e-01,2.0e+00), RES(1.0654050295275703990e-1, -4.5717847686917515748e-1)}, {FN (arccsc), ARG(5.0e-01,-2.0e+00), RES(1.0654050295275703990e-1, 4.5717847686917515748e-1)}, {FN (arccsc), ARG(-5.0e-01,2.0e+00), RES(-1.0654050295275703990e-1, -4.5717847686917515748e-1)}, {FN (arccsc), ARG(-5.0e-01,-2.0e+00), RES(-1.0654050295275703990e-1, 4.5717847686917515748e-1)}, {FN (arccsc), ARG(5.0e-01,8.3886080e+06), RES(7.1054273576009261281e-15, -1.1920928955078054414e-7)}, {FN (arccsc), ARG(5.0e-01,-8.3886080e+06), RES(7.1054273576009261281e-15, 1.1920928955078054414e-7)}, {FN (arccsc), ARG(-5.0e-01,8.3886080e+06), RES(-7.1054273576009261281e-15, -1.1920928955078054414e-7)}, {FN (arccsc), ARG(-5.0e-01,-8.3886080e+06), RES(-7.1054273576009261281e-15, 1.1920928955078054414e-7)}, {FN (arccsc), ARG(1.0e+00,0.0e+00), RES(1.5707963267948966192e0, 0.0)}, {FN (arccsc), ARG(-1.0e+00,0.0e+00), RES(-1.5707963267948966192e0, 0.0)}, {FN (arccsc), ARG(1.0e+00,1.19209289550781250e-07), RES(1.5704510597947457801e0, -3.4526696585164602772e-4)}, {FN (arccsc), ARG(1.0e+00,-1.19209289550781250e-07), RES(1.5704510597947457801e0, 3.4526696585164602772e-4)}, {FN (arccsc), ARG(-1.0e+00,1.19209289550781250e-07), RES(-1.5704510597947457801e0, -3.4526696585164602772e-4)}, {FN (arccsc), ARG(-1.0e+00,-1.19209289550781250e-07), RES(-1.5704510597947457801e0, 3.4526696585164602772e-4)}, {FN (arccsc), ARG(1.0e+00,5.0e-01), RES(7.7308635671950473342e-1, -5.3321829058411214108e-1)}, {FN (arccsc), ARG(1.0e+00,-5.0e-01), RES(7.7308635671950473342e-1, 5.3321829058411214108e-1)}, {FN (arccsc), ARG(-1.0e+00,5.0e-01), RES(-7.7308635671950473342e-1, -5.3321829058411214108e-1)}, {FN (arccsc), ARG(-1.0e+00,-5.0e-01), RES(-7.7308635671950473342e-1, 5.3321829058411214108e-1)}, {FN (arccsc), ARG(1.0e+00,1.0e+00), RES(4.5227844715119068206e-1, -5.3063753095251782602e-1)}, {FN (arccsc), ARG(1.0e+00,-1.0e+00), RES(4.5227844715119068206e-1, 5.3063753095251782602e-1)}, {FN (arccsc), ARG(-1.0e+00,1.0e+00), RES(-4.5227844715119068206e-1, -5.3063753095251782602e-1)}, {FN (arccsc), ARG(-1.0e+00,-1.0e+00), RES(-4.5227844715119068206e-1, 5.3063753095251782602e-1)}, {FN (arccsc), ARG(1.0e+00,2.0e+00), RES(1.8631805410781552582e-1, -3.9656823011232897892e-1)}, {FN (arccsc), ARG(1.0e+00,-2.0e+00), RES(1.8631805410781552582e-1, 3.9656823011232897892e-1)}, {FN (arccsc), ARG(-1.0e+00,2.0e+00), RES(-1.8631805410781552582e-1, -3.9656823011232897892e-1)}, {FN (arccsc), ARG(-1.0e+00,-2.0e+00), RES(-1.8631805410781552582e-1, 3.9656823011232897892e-1)}, {FN (arccsc), ARG(1.0e+00,8.3886080e+06), RES(1.4210854715201700795e-14, -1.1920928955077927359e-7)}, {FN (arccsc), ARG(1.0e+00,-8.3886080e+06), RES(1.4210854715201700795e-14, 1.1920928955077927359e-7)}, {FN (arccsc), ARG(-1.0e+00,8.3886080e+06), RES(-1.4210854715201700795e-14, -1.1920928955077927359e-7)}, {FN (arccsc), ARG(-1.0e+00,-8.3886080e+06), RES(-1.4210854715201700795e-14, 1.1920928955077927359e-7)}, {FN (arccsc), ARG(2.0e+00,0.0e+00), RES(5.2359877559829887308e-1, 0.0)}, {FN (arccsc), ARG(-2.0e+00,0.0e+00), RES(-5.2359877559829887308e-1, 0.0)}, {FN (arccsc), ARG(2.0e+00,1.19209289550781250e-07), RES(5.2359877559829648006e-1, -3.4412757706023621662e-8)}, {FN (arccsc), ARG(2.0e+00,-1.19209289550781250e-07), RES(5.2359877559829648006e-1, 3.4412757706023621662e-8)}, {FN (arccsc), ARG(-2.0e+00,1.19209289550781250e-07), RES(-5.2359877559829648006e-1, -3.4412757706023621662e-8)}, {FN (arccsc), ARG(-2.0e+00,-1.19209289550781250e-07), RES(-5.2359877559829648006e-1, 3.4412757706023621662e-8)}, {FN (arccsc), ARG(2.0e+00,5.0e-01), RES(4.8530734047334251250e-1, -1.3261586085051183885e-1)}, {FN (arccsc), ARG(2.0e+00,-5.0e-01), RES(4.8530734047334251250e-1, 1.3261586085051183885e-1)}, {FN (arccsc), ARG(-2.0e+00,5.0e-01), RES(-4.8530734047334251250e-1, -1.3261586085051183885e-1)}, {FN (arccsc), ARG(-2.0e+00,-5.0e-01), RES(-4.8530734047334251250e-1, 1.3261586085051183885e-1)}, {FN (arccsc), ARG(2.0e+00,1.0e+00), RES(4.0158639166780606828e-1, -2.1561241855582964497e-1)}, {FN (arccsc), ARG(2.0e+00,-1.0e+00), RES(4.0158639166780606828e-1, 2.1561241855582964497e-1)}, {FN (arccsc), ARG(-2.0e+00,1.0e+00), RES(-4.0158639166780606828e-1, -2.1561241855582964497e-1)}, {FN (arccsc), ARG(-2.0e+00,-1.0e+00), RES(-4.0158639166780606828e-1, 2.1561241855582964497e-1)}, {FN (arccsc), ARG(2.0e+00,2.0e+00), RES(2.4452216513554014646e-1, -2.5489557334055081773e-1)}, {FN (arccsc), ARG(2.0e+00,-2.0e+00), RES(2.4452216513554014646e-1, 2.5489557334055081773e-1)}, {FN (arccsc), ARG(-2.0e+00,2.0e+00), RES(-2.4452216513554014646e-1, -2.5489557334055081773e-1)}, {FN (arccsc), ARG(-2.0e+00,-2.0e+00), RES(-2.4452216513554014646e-1, 2.5489557334055081773e-1)}, {FN (arccsc), ARG(2.0e+00,8.3886080e+06), RES(2.8421709430402189899e-14, -1.1920928955077419139e-7)}, {FN (arccsc), ARG(2.0e+00,-8.3886080e+06), RES(2.8421709430402189899e-14, 1.1920928955077419139e-7)}, {FN (arccsc), ARG(-2.0e+00,8.3886080e+06), RES(-2.8421709430402189899e-14, -1.1920928955077419139e-7)}, {FN (arccsc), ARG(-2.0e+00,-8.3886080e+06), RES(-2.8421709430402189899e-14, 1.1920928955077419139e-7)}, {FN (arccsc), ARG(8.3886080e+06,0.0e+00), RES(1.1920928955078153234e-7, 0.0)}, {FN (arccsc), ARG(-8.3886080e+06,0.0e+00), RES(-1.1920928955078153234e-7, 0.0)}, {FN (arccsc), ARG(8.3886080e+06,1.19209289550781250e-07), RES(1.1920928955078153234e-7, -1.6940658945086127152e-21)}, {FN (arccsc), ARG(8.3886080e+06,-1.19209289550781250e-07), RES(1.1920928955078153234e-7, 1.6940658945086127152e-21)}, {FN (arccsc), ARG(-8.3886080e+06,1.19209289550781250e-07), RES(-1.1920928955078153234e-7, -1.6940658945086127152e-21)}, {FN (arccsc), ARG(-8.3886080e+06,-1.19209289550781250e-07), RES(-1.1920928955078153234e-7, 1.6940658945086127152e-21)}, {FN (arccsc), ARG(8.3886080e+06,5.0e-01), RES(1.1920928955078110883e-7, -7.1054273576010271023e-15)}, {FN (arccsc), ARG(8.3886080e+06,-5.0e-01), RES(1.1920928955078110883e-7, 7.1054273576010271023e-15)}, {FN (arccsc), ARG(-8.3886080e+06,5.0e-01), RES(-1.1920928955078110883e-7, -7.1054273576010271023e-15)}, {FN (arccsc), ARG(-8.3886080e+06,-5.0e-01), RES(-1.1920928955078110883e-7, 7.1054273576010271023e-15)}, {FN (arccsc), ARG(8.3886080e+06,1.0e+00), RES(1.1920928955077983828e-7, -1.4210854715201902743e-14)}, {FN (arccsc), ARG(8.3886080e+06,-1.0e+00), RES(1.1920928955077983828e-7, 1.4210854715201902743e-14)}, {FN (arccsc), ARG(-8.3886080e+06,1.0e+00), RES(-1.1920928955077983828e-7, -1.4210854715201902743e-14)}, {FN (arccsc), ARG(-8.3886080e+06,-1.0e+00), RES(-1.1920928955077983828e-7, 1.4210854715201902743e-14)}, {FN (arccsc), ARG(8.3886080e+06,2.0e+00), RES(1.1920928955077475608e-7, -2.8421709430402593796e-14)}, {FN (arccsc), ARG(8.3886080e+06,-2.0e+00), RES(1.1920928955077475608e-7, 2.8421709430402593796e-14)}, {FN (arccsc), ARG(-8.3886080e+06,2.0e+00), RES(-1.1920928955077475608e-7, -2.8421709430402593796e-14)}, {FN (arccsc), ARG(-8.3886080e+06,-2.0e+00), RES(-1.1920928955077475608e-7, 2.8421709430402593796e-14)}, {FN (arccsc), ARG(8.3886080e+06,8.3886080e+06), RES(5.9604644775390554414e-8, -5.9604644775390695586e-8)}, {FN (arccsc), ARG(8.3886080e+06,-8.3886080e+06), RES(5.9604644775390554414e-8, 5.9604644775390695586e-8)}, {FN (arccsc), ARG(-8.3886080e+06,8.3886080e+06), RES(-5.9604644775390554414e-8, -5.9604644775390695586e-8)}, {FN (arccsc), ARG(-8.3886080e+06,-8.3886080e+06), RES(-5.9604644775390554414e-8, 5.9604644775390695586e-8)}, {FN (arcsec), ARG(0.0e+00,1.19209289550781250e-07), RES(1.5707963267948966192e0, 1.6635532333438690979e1)}, {FN (arcsec), ARG(0.0e+00,-1.19209289550781250e-07), RES(1.5707963267948966192e0, -1.6635532333438690979e1)}, {FN (arcsec), ARG(0.0e+00,5.0e-01), RES(1.5707963267948966192e0, 1.4436354751788103425e0)}, {FN (arcsec), ARG(0.0e+00,-5.0e-01), RES(1.5707963267948966192e0, -1.4436354751788103425e0)}, {FN (arcsec), ARG(0.0e+00,1.0e+00), RES(1.5707963267948966192e0, 8.8137358701954302523e-1)}, {FN (arcsec), ARG(0.0e+00,-1.0e+00), RES(1.5707963267948966192e0, -8.8137358701954302523e-1)}, {FN (arcsec), ARG(0.0e+00,2.0e+00), RES(1.5707963267948966192e0, 4.8121182505960344750e-1)}, {FN (arcsec), ARG(0.0e+00,-2.0e+00), RES(1.5707963267948966192e0, -4.8121182505960344750e-1)}, {FN (arcsec), ARG(0.0e+00,8.3886080e+06), RES(1.5707963267948966192e0, 1.1920928955078096766e-7)}, {FN (arcsec), ARG(0.0e+00,-8.3886080e+06), RES(1.5707963267948966192e0, -1.1920928955078096766e-7)}, {FN (arcsec), ARG(1.19209289550781250e-07,0.0e+00), RES(0, 1.6635532333438683873e1)}, {FN (arcsec), ARG(-1.19209289550781250e-07,0.0e+00), RES(3.1415926535897932385e0, -1.6635532333438683873e1)}, {FN (arcsec), ARG(1.19209289550781250e-07,1.19209289550781250e-07), RES(7.8539816339745541504e-1, 1.6288958743158714771e1)}, {FN (arcsec), ARG(1.19209289550781250e-07,-1.19209289550781250e-07), RES(7.8539816339745541504e-1, -1.6288958743158714771e1)}, {FN (arcsec), ARG(-1.19209289550781250e-07,1.19209289550781250e-07), RES(2.3561944901923378234e0, 1.6288958743158714771e1)}, {FN (arcsec), ARG(-1.19209289550781250e-07,-1.19209289550781250e-07), RES(2.3561944901923378234e0, -1.6288958743158714771e1)}, {FN (arcsec), ARG(1.19209289550781250e-07,5.0e-01), RES(1.5707961135468366312e0, 1.4436354751787798371e0)}, {FN (arcsec), ARG(1.19209289550781250e-07,-5.0e-01), RES(1.5707961135468366312e0, -1.4436354751787798371e0)}, {FN (arcsec), ARG(-1.19209289550781250e-07,5.0e-01), RES(1.5707965400429566072e0, 1.4436354751787798371e0)}, {FN (arcsec), ARG(-1.19209289550781250e-07,-5.0e-01), RES(1.5707965400429566072e0, -1.4436354751787798371e0)}, {FN (arcsec), ARG(1.19209289550781250e-07,1.0e+00), RES(1.5707962425011995974e0, 8.8137358701953548879e-1)}, {FN (arcsec), ARG(1.19209289550781250e-07,-1.0e+00), RES(1.5707962425011995974e0, -8.8137358701953548879e-1)}, {FN (arcsec), ARG(-1.19209289550781250e-07,1.0e+00), RES(1.5707964110885936410e0, 8.8137358701953548879e-1)}, {FN (arcsec), ARG(-1.19209289550781250e-07,-1.0e+00), RES(1.5707964110885936410e0, -8.8137358701953548879e-1)}, {FN (arcsec), ARG(1.19209289550781250e-07,2.0e+00), RES(1.5707963001388891207e0, 4.8121182505960201756e-1)}, {FN (arcsec), ARG(1.19209289550781250e-07,-2.0e+00), RES(1.5707963001388891207e0, -4.8121182505960201756e-1)}, {FN (arcsec), ARG(-1.19209289550781250e-07,2.0e+00), RES(1.5707963534509041177e0, 4.8121182505960201756e-1)}, {FN (arcsec), ARG(-1.19209289550781250e-07,-2.0e+00), RES(1.5707963534509041177e0, -4.8121182505960201756e-1)}, {FN (arcsec), ARG(1.19209289550781250e-07,8.3886080e+06), RES(1.5707963267948966192e0, 1.1920928955078096766e-7)}, {FN (arcsec), ARG(1.19209289550781250e-07,-8.3886080e+06), RES(1.5707963267948966192e0, -1.1920928955078096766e-7)}, {FN (arcsec), ARG(-1.19209289550781250e-07,8.3886080e+06), RES(1.5707963267948966192e0, 1.1920928955078096766e-7)}, {FN (arcsec), ARG(-1.19209289550781250e-07,-8.3886080e+06), RES(1.5707963267948966192e0, -1.1920928955078096766e-7)}, {FN (arcsec), ARG(5.0e-01,0.0e+00), RES(0, 1.3169578969248167086e0)}, {FN (arcsec), ARG(-5.0e-01,0.0e+00), RES(3.1415926535897932385e0, -1.3169578969248167086e0)}, {FN (arcsec), ARG(5.0e-01,1.19209289550781250e-07), RES(2.7530206164818516969e-7, 1.3169578969247948296e0)}, {FN (arcsec), ARG(5.0e-01,-1.19209289550781250e-07), RES(2.7530206164818516969e-7, -1.3169578969247948296e0)}, {FN (arcsec), ARG(-5.0e-01,1.19209289550781250e-07), RES(3.1415923782877315903e0, 1.3169578969247948296e0)}, {FN (arcsec), ARG(-5.0e-01,-1.19209289550781250e-07), RES(3.1415923782877315903e0, -1.3169578969247948296e0)}, {FN (arcsec), ARG(5.0e-01,5.0e-01), RES(9.0455689430238136413e-1, 1.0612750619050356520e0)}, {FN (arcsec), ARG(5.0e-01,-5.0e-01), RES(9.0455689430238136413e-1, -1.0612750619050356520e0)}, {FN (arcsec), ARG(-5.0e-01,5.0e-01), RES(2.2370357592874118743e0, 1.0612750619050356520e0)}, {FN (arcsec), ARG(-5.0e-01,-5.0e-01), RES(2.2370357592874118743e0, -1.0612750619050356520e0)}, {FN (arcsec), ARG(5.0e-01,1.0e+00), RES(1.2595705295501355239e0, 7.6388434595371104541e-1)}, {FN (arcsec), ARG(5.0e-01,-1.0e+00), RES(1.2595705295501355239e0, -7.6388434595371104541e-1)}, {FN (arcsec), ARG(-5.0e-01,1.0e+00), RES(1.8820221240396577146e0, 7.6388434595371104541e-1)}, {FN (arcsec), ARG(-5.0e-01,-1.0e+00), RES(1.8820221240396577146e0, -7.6388434595371104541e-1)}, {FN (arcsec), ARG(5.0e-01,2.0e+00), RES(1.4642558238421395793e0, 4.5717847686917515748e-1)}, {FN (arcsec), ARG(5.0e-01,-2.0e+00), RES(1.4642558238421395793e0, -4.5717847686917515748e-1)}, {FN (arcsec), ARG(-5.0e-01,2.0e+00), RES(1.6773368297476536591e0, 4.5717847686917515748e-1)}, {FN (arcsec), ARG(-5.0e-01,-2.0e+00), RES(1.6773368297476536591e0, -4.5717847686917515748e-1)}, {FN (arcsec), ARG(5.0e-01,8.3886080e+06), RES(1.5707963267948895138e0, 1.1920928955078054414e-7)}, {FN (arcsec), ARG(5.0e-01,-8.3886080e+06), RES(1.5707963267948895138e0, -1.1920928955078054414e-7)}, {FN (arcsec), ARG(-5.0e-01,8.3886080e+06), RES(1.5707963267949037247e0, 1.1920928955078054414e-7)}, {FN (arcsec), ARG(-5.0e-01,-8.3886080e+06), RES(1.5707963267949037247e0, -1.1920928955078054414e-7)}, {FN (arcsec), ARG(1.0e+00,0.0e+00), RES(0e0, 0.0)}, {FN (arcsec), ARG(-1.0e+00,0.0e+00), RES(3.1415926535897932385e0, 0.0)}, {FN (arcsec), ARG(1.0e+00,1.19209289550781250e-07), RES(3.4526700015083915182e-4, 3.4526696585164602772e-4)}, {FN (arcsec), ARG(1.0e+00,-1.19209289550781250e-07), RES(3.4526700015083915182e-4, -3.4526696585164602772e-4)}, {FN (arcsec), ARG(-1.0e+00,1.19209289550781250e-07), RES(3.1412473865896423993e0, 3.4526696585164602772e-4)}, {FN (arcsec), ARG(-1.0e+00,-1.19209289550781250e-07), RES(3.1412473865896423993e0, -3.4526696585164602772e-4)}, {FN (arcsec), ARG(1.0e+00,5.0e-01), RES(7.9770997007539188581e-1, 5.3321829058411214108e-1)}, {FN (arcsec), ARG(1.0e+00,-5.0e-01), RES(7.9770997007539188581e-1, -5.3321829058411214108e-1)}, {FN (arcsec), ARG(-1.0e+00,5.0e-01), RES(2.3438826835144013527e0, 5.3321829058411214108e-1)}, {FN (arcsec), ARG(-1.0e+00,-5.0e-01), RES(2.3438826835144013527e0, -5.3321829058411214108e-1)}, {FN (arcsec), ARG(1.0e+00,1.0e+00), RES(1.1185178796437059372e0, 5.3063753095251782602e-1)}, {FN (arcsec), ARG(1.0e+00,-1.0e+00), RES(1.1185178796437059372e0, -5.3063753095251782602e-1)}, {FN (arcsec), ARG(-1.0e+00,1.0e+00), RES(2.0230747739460873013e0, 5.3063753095251782602e-1)}, {FN (arcsec), ARG(-1.0e+00,-1.0e+00), RES(2.0230747739460873013e0, -5.3063753095251782602e-1)}, {FN (arcsec), ARG(1.0e+00,2.0e+00), RES(1.3844782726870810934e0, 3.9656823011232897892e-1)}, {FN (arcsec), ARG(1.0e+00,-2.0e+00), RES(1.3844782726870810934e0, -3.9656823011232897892e-1)}, {FN (arcsec), ARG(-1.0e+00,2.0e+00), RES(1.7571143809027121451e0, 3.9656823011232897892e-1)}, {FN (arcsec), ARG(-1.0e+00,-2.0e+00), RES(1.7571143809027121451e0, -3.9656823011232897892e-1)}, {FN (arcsec), ARG(1.0e+00,8.3886080e+06), RES(1.5707963267948824084e0, 1.1920928955077927359e-7)}, {FN (arcsec), ARG(1.0e+00,-8.3886080e+06), RES(1.5707963267948824084e0, -1.1920928955077927359e-7)}, {FN (arcsec), ARG(-1.0e+00,8.3886080e+06), RES(1.5707963267949108301e0, 1.1920928955077927359e-7)}, {FN (arcsec), ARG(-1.0e+00,-8.3886080e+06), RES(1.5707963267949108301e0, -1.1920928955077927359e-7)}, {FN (arcsec), ARG(2.0e+00,0.0e+00), RES(1.0471975511965977462e0, 0.0)}, {FN (arcsec), ARG(-2.0e+00,0.0e+00), RES(2.0943951023931954923e0, 0.0)}, {FN (arcsec), ARG(2.0e+00,1.19209289550781250e-07), RES(1.0471975511966001392e0, 3.4412757706023621662e-8)}, {FN (arcsec), ARG(2.0e+00,-1.19209289550781250e-07), RES(1.0471975511966001392e0, -3.4412757706023621662e-8)}, {FN (arcsec), ARG(-2.0e+00,1.19209289550781250e-07), RES(2.0943951023931930993e0, 3.4412757706023621662e-8)}, {FN (arcsec), ARG(-2.0e+00,-1.19209289550781250e-07), RES(2.0943951023931930993e0, -3.4412757706023621662e-8)}, {FN (arcsec), ARG(2.0e+00,5.0e-01), RES(1.0854889863215541067e0, 1.3261586085051183885e-1)}, {FN (arcsec), ARG(2.0e+00,-5.0e-01), RES(1.0854889863215541067e0, -1.3261586085051183885e-1)}, {FN (arcsec), ARG(-2.0e+00,5.0e-01), RES(2.0561036672682391317e0, 1.3261586085051183885e-1)}, {FN (arcsec), ARG(-2.0e+00,-5.0e-01), RES(2.0561036672682391317e0, -1.3261586085051183885e-1)}, {FN (arcsec), ARG(2.0e+00,1.0e+00), RES(1.1692099351270905509e0, 2.1561241855582964497e-1)}, {FN (arcsec), ARG(2.0e+00,-1.0e+00), RES(1.1692099351270905509e0, -2.1561241855582964497e-1)}, {FN (arcsec), ARG(-2.0e+00,1.0e+00), RES(1.9723827184627026875e0, 2.1561241855582964497e-1)}, {FN (arcsec), ARG(-2.0e+00,-1.0e+00), RES(1.9723827184627026875e0, -2.1561241855582964497e-1)}, {FN (arcsec), ARG(2.0e+00,2.0e+00), RES(1.3262741616593564728e0, 2.5489557334055081773e-1)}, {FN (arcsec), ARG(2.0e+00,-2.0e+00), RES(1.3262741616593564728e0, -2.5489557334055081773e-1)}, {FN (arcsec), ARG(-2.0e+00,2.0e+00), RES(1.8153184919304367657e0, 2.5489557334055081773e-1)}, {FN (arcsec), ARG(-2.0e+00,-2.0e+00), RES(1.8153184919304367657e0, -2.5489557334055081773e-1)}, {FN (arcsec), ARG(2.0e+00,8.3886080e+06), RES(1.5707963267948681975e0, 1.1920928955077419139e-7)}, {FN (arcsec), ARG(2.0e+00,-8.3886080e+06), RES(1.5707963267948681975e0, -1.1920928955077419139e-7)}, {FN (arcsec), ARG(-2.0e+00,8.3886080e+06), RES(1.5707963267949250409e0, 1.1920928955077419139e-7)}, {FN (arcsec), ARG(-2.0e+00,-8.3886080e+06), RES(1.5707963267949250409e0, -1.1920928955077419139e-7)}, {FN (arcsec), ARG(8.3886080e+06,0.0e+00), RES(1.5707962075856070684e0, 0.0)}, {FN (arcsec), ARG(-8.3886080e+06,0.0e+00), RES(1.570796446004186170e0, 0.0)}, {FN (arcsec), ARG(8.3886080e+06,1.19209289550781250e-07), RES(1.5707962075856070684e0, 1.6940658945086127152e-21)}, {FN (arcsec), ARG(8.3886080e+06,-1.19209289550781250e-07), RES(1.5707962075856070684e0, -1.6940658945086127152e-21)}, {FN (arcsec), ARG(-8.3886080e+06,1.19209289550781250e-07), RES(1.570796446004186170e0, 1.6940658945086127152e-21)}, {FN (arcsec), ARG(-8.3886080e+06,-1.19209289550781250e-07), RES(1.570796446004186170e0, -1.6940658945086127152e-21)}, {FN (arcsec), ARG(8.3886080e+06,5.0e-01), RES(1.5707962075856070685e0, 7.1054273576010271023e-15)}, {FN (arcsec), ARG(8.3886080e+06,-5.0e-01), RES(1.5707962075856070685e0, -7.1054273576010271023e-15)}, {FN (arcsec), ARG(-8.3886080e+06,5.0e-01), RES(1.570796446004186170e0, 7.1054273576010271023e-15)}, {FN (arcsec), ARG(-8.3886080e+06,-5.0e-01), RES(1.570796446004186170e0, -7.1054273576010271023e-15)}, {FN (arcsec), ARG(8.3886080e+06,1.0e+00), RES(1.5707962075856070685e0, 1.4210854715201902743e-14)}, {FN (arcsec), ARG(8.3886080e+06,-1.0e+00), RES(1.5707962075856070685e0, -1.4210854715201902743e-14)}, {FN (arcsec), ARG(-8.3886080e+06,1.0e+00), RES(1.570796446004186170e0, 1.4210854715201902743e-14)}, {FN (arcsec), ARG(-8.3886080e+06,-1.0e+00), RES(1.570796446004186170e0, -1.4210854715201902743e-14)}, {FN (arcsec), ARG(8.3886080e+06,2.0e+00), RES(1.5707962075856070685e0, 2.8421709430402593796e-14)}, {FN (arcsec), ARG(8.3886080e+06,-2.0e+00), RES(1.5707962075856070685e0, -2.8421709430402593796e-14)}, {FN (arcsec), ARG(-8.3886080e+06,2.0e+00), RES(1.570796446004186170e0, 2.8421709430402593796e-14)}, {FN (arcsec), ARG(-8.3886080e+06,-2.0e+00), RES(1.570796446004186170e0, -2.8421709430402593796e-14)}, {FN (arcsec), ARG(8.3886080e+06,8.3886080e+06), RES(1.5707962671902518438e0, 5.9604644775390695586e-8)}, {FN (arcsec), ARG(8.3886080e+06,-8.3886080e+06), RES(1.5707962671902518438e0, -5.9604644775390695586e-8)}, {FN (arcsec), ARG(-8.3886080e+06,8.3886080e+06), RES(1.5707963863995413946e0, 5.9604644775390695586e-8)}, {FN (arcsec), ARG(-8.3886080e+06,-8.3886080e+06), RES(1.5707963863995413946e0, -5.9604644775390695586e-8)}, {FN (arccot), ARG(0.0e+00,1.19209289550781250e-07), RES(-1.5707963267948966192e0, -1.1920928955078181469e-7)}, {FN (arccot), ARG(0.0e+00,-1.19209289550781250e-07), RES(1.5707963267948966192e0, 1.1920928955078181469e-7)}, {FN (arccot), ARG(0.0e+00,5.0e-01), RES(-1.5707963267948966192e0, -5.4930614433405484570e-1)}, {FN (arccot), ARG(0.0e+00,-5.0e-01), RES(1.5707963267948966192e0, 5.4930614433405484570e-1)}, {FN (arccot), ARG(0.0e+00,2.0e+00), RES(0, -5.4930614433405484570e-1)}, {FN (arccot), ARG(0.0e+00,-2.0e+00), RES(0, 5.4930614433405484570e-1)}, {FN (arccot), ARG(0.0e+00,8.3886080e+06), RES(0, -1.1920928955078181469e-7)}, {FN (arccot), ARG(0.0e+00,-8.3886080e+06), RES(0, 1.1920928955078181469e-7)}, {FN (arccot), ARG(1.19209289550781250e-07,0.0e+00), RES(1.5707962075856070685e0, 0.0)}, {FN (arccot), ARG(-1.19209289550781250e-07,0.0e+00), RES(-1.5707962075856070685e0, 0.0)}, {FN (arccot), ARG(1.19209289550781250e-07,1.19209289550781250e-07), RES(1.5707962075856070684e0, -1.1920928955078012062e-7)}, {FN (arccot), ARG(1.19209289550781250e-07,-1.19209289550781250e-07), RES(1.5707962075856070684e0, 1.1920928955078012062e-7)}, {FN (arccot), ARG(-1.19209289550781250e-07,1.19209289550781250e-07), RES(-1.5707962075856070684e0, -1.1920928955078012062e-7)}, {FN (arccot), ARG(-1.19209289550781250e-07,-1.19209289550781250e-07), RES(-1.5707962075856070684e0, 1.1920928955078012062e-7)}, {FN (arccot), ARG(1.19209289550781250e-07,5.0e-01), RES(1.5707961678491772182e0, -5.4930614433404221383e-1)}, {FN (arccot), ARG(1.19209289550781250e-07,-5.0e-01), RES(1.5707961678491772182e0, 5.4930614433404221383e-1)}, {FN (arccot), ARG(-1.19209289550781250e-07,5.0e-01), RES(-1.5707961678491772182e0, -5.4930614433404221383e-1)}, {FN (arccot), ARG(-1.19209289550781250e-07,-5.0e-01), RES(-1.5707961678491772182e0, 5.4930614433404221383e-1)}, {FN (arccot), ARG(1.19209289550781250e-07,1.0e+00), RES(7.8539813359512592192e-1, -8.3177661667193446012e0)}, {FN (arccot), ARG(1.19209289550781250e-07,-1.0e+00), RES(7.8539813359512592192e-1, 8.3177661667193446012e0)}, {FN (arccot), ARG(-1.19209289550781250e-07,1.0e+00), RES(-7.8539813359512592192e-1, -8.3177661667193446012e0)}, {FN (arccot), ARG(-1.19209289550781250e-07,-1.0e+00), RES(-7.8539813359512592192e-1, 8.3177661667193446012e0)}, {FN (arccot), ARG(1.19209289550781250e-07,2.0e+00), RES(3.9736429850260144780e-8, -5.4930614433405168773e-1)}, {FN (arccot), ARG(1.19209289550781250e-07,-2.0e+00), RES(3.9736429850260144780e-8, 5.4930614433405168773e-1)}, {FN (arccot), ARG(-1.19209289550781250e-07,2.0e+00), RES(-3.9736429850260144780e-8, -5.4930614433405168773e-1)}, {FN (arccot), ARG(-1.19209289550781250e-07,-2.0e+00), RES(-3.9736429850260144780e-8, 5.4930614433405168773e-1)}, {FN (arccot), ARG(1.19209289550781250e-07,8.3886080e+06), RES(1.6940658945086247523e-21, -1.1920928955078181469e-7)}, {FN (arccot), ARG(1.19209289550781250e-07,-8.3886080e+06), RES(1.6940658945086247523e-21, 1.1920928955078181469e-7)}, {FN (arccot), ARG(-1.19209289550781250e-07,8.3886080e+06), RES(-1.6940658945086247523e-21, -1.1920928955078181469e-7)}, {FN (arccot), ARG(-1.19209289550781250e-07,-8.3886080e+06), RES(-1.6940658945086247523e-21, 1.1920928955078181469e-7)}, {FN (arccot), ARG(5.0e-01,0.0e+00), RES(1.1071487177940905030e0, 0.0)}, {FN (arccot), ARG(-5.0e-01,0.0e+00), RES(-1.1071487177940905030e0, 0.0)}, {FN (arccot), ARG(5.0e-01,1.19209289550781250e-07), RES(1.1071487177940859555e0, -9.5367431640625072280e-8)}, {FN (arccot), ARG(5.0e-01,-1.19209289550781250e-07), RES(1.1071487177940859555e0, 9.5367431640625072280e-8)}, {FN (arccot), ARG(-5.0e-01,1.19209289550781250e-07), RES(-1.1071487177940859555e0, -9.5367431640625072280e-8)}, {FN (arccot), ARG(-5.0e-01,-1.19209289550781250e-07), RES(-1.1071487177940859555e0, 9.5367431640625072280e-8)}, {FN (arccot), ARG(5.0e-01,5.0e-01), RES(1.0172219678978513677e0, -4.0235947810852509365e-1)}, {FN (arccot), ARG(5.0e-01,-5.0e-01), RES(1.0172219678978513677e0, 4.0235947810852509365e-1)}, {FN (arccot), ARG(-5.0e-01,5.0e-01), RES(-1.0172219678978513677e0, -4.0235947810852509365e-1)}, {FN (arccot), ARG(-5.0e-01,-5.0e-01), RES(-1.0172219678978513677e0, 4.0235947810852509365e-1)}, {FN (arccot), ARG(5.0e-01,1.0e+00), RES(6.6290883183401623253e-1, -7.0830333601405402006e-1)}, {FN (arccot), ARG(5.0e-01,-1.0e+00), RES(6.6290883183401623253e-1, 7.0830333601405402006e-1)}, {FN (arccot), ARG(-5.0e-01,1.0e+00), RES(-6.6290883183401623253e-1, -7.0830333601405402006e-1)}, {FN (arccot), ARG(-5.0e-01,-1.0e+00), RES(-6.6290883183401623253e-1, 7.0830333601405402006e-1)}, {FN (arccot), ARG(5.0e-01,2.0e+00), RES(1.4924946579308963897e-1, -5.0037000005253101744e-1)}, {FN (arccot), ARG(5.0e-01,-2.0e+00), RES(1.4924946579308963897e-1, 5.0037000005253101744e-1)}, {FN (arccot), ARG(-5.0e-01,2.0e+00), RES(-1.4924946579308963897e-1, -5.0037000005253101744e-1)}, {FN (arccot), ARG(-5.0e-01,-2.0e+00), RES(-1.4924946579308963897e-1, 5.0037000005253101744e-1)}, {FN (arccot), ARG(5.0e-01,8.3886080e+06), RES(7.1054273576010775894e-15, -1.1920928955078139117e-7)}, {FN (arccot), ARG(5.0e-01,-8.3886080e+06), RES(7.1054273576010775894e-15, 1.1920928955078139117e-7)}, {FN (arccot), ARG(-5.0e-01,8.3886080e+06), RES(-7.1054273576010775894e-15, -1.1920928955078139117e-7)}, {FN (arccot), ARG(-5.0e-01,-8.3886080e+06), RES(-7.1054273576010775894e-15, 1.1920928955078139117e-7)}, {FN (arccot), ARG(1.0e+00,0.0e+00), RES(7.8539816339744830962e-1, 0.0)}, {FN (arccot), ARG(-1.0e+00,0.0e+00), RES(-7.8539816339744830962e-1, 0.0)}, {FN (arccot), ARG(1.0e+00,1.19209289550781250e-07), RES(7.8539816339744475690e-1, -5.9604644775390483828e-8)}, {FN (arccot), ARG(1.0e+00,-1.19209289550781250e-07), RES(7.8539816339744475690e-1, 5.9604644775390483828e-8)}, {FN (arccot), ARG(-1.0e+00,1.19209289550781250e-07), RES(-7.8539816339744475690e-1, -5.9604644775390483828e-8)}, {FN (arccot), ARG(-1.0e+00,-1.19209289550781250e-07), RES(-7.8539816339744475690e-1, 5.9604644775390483828e-8)}, {FN (arccot), ARG(1.0e+00,5.0e-01), RES(7.2322066612406759210e-1, -2.3887786125685909036e-1)}, {FN (arccot), ARG(1.0e+00,-5.0e-01), RES(7.2322066612406759210e-1, 2.3887786125685909036e-1)}, {FN (arccot), ARG(-1.0e+00,5.0e-01), RES(-7.2322066612406759210e-1, -2.3887786125685909036e-1)}, {FN (arccot), ARG(-1.0e+00,-5.0e-01), RES(-7.2322066612406759210e-1, 2.3887786125685909036e-1)}, {FN (arccot), ARG(1.0e+00,1.0e+00), RES(5.5357435889704525151e-1, -4.0235947810852509365e-1)}, {FN (arccot), ARG(1.0e+00,-1.0e+00), RES(5.5357435889704525151e-1, 4.0235947810852509365e-1)}, {FN (arccot), ARG(-1.0e+00,1.0e+00), RES(-5.5357435889704525151e-1, -4.0235947810852509365e-1)}, {FN (arccot), ARG(-1.0e+00,-1.0e+00), RES(-5.5357435889704525151e-1, 4.0235947810852509365e-1)}, {FN (arccot), ARG(1.0e+00,2.0e+00), RES(2.3182380450040305811e-1, -4.0235947810852509365e-1)}, {FN (arccot), ARG(1.0e+00,-2.0e+00), RES(2.3182380450040305811e-1, 4.0235947810852509365e-1)}, {FN (arccot), ARG(-1.0e+00,2.0e+00), RES(-2.3182380450040305811e-1, -4.0235947810852509365e-1)}, {FN (arccot), ARG(-1.0e+00,-2.0e+00), RES(-2.3182380450040305811e-1, 4.0235947810852509365e-1)}, {FN (arccot), ARG(1.0e+00,8.3886080e+06), RES(1.4210854715202003717e-14, -1.1920928955078012062e-7)}, {FN (arccot), ARG(1.0e+00,-8.3886080e+06), RES(1.4210854715202003717e-14, 1.1920928955078012062e-7)}, {FN (arccot), ARG(-1.0e+00,8.3886080e+06), RES(-1.4210854715202003717e-14, -1.1920928955078012062e-7)}, {FN (arccot), ARG(-1.0e+00,-8.3886080e+06), RES(-1.4210854715202003717e-14, 1.1920928955078012062e-7)}, {FN (arccot), ARG(2.0e+00,0.0e+00), RES(4.6364760900080611621e-1, 0.0)}, {FN (arccot), ARG(-2.0e+00,0.0e+00), RES(-4.6364760900080611621e-1, 0.0)}, {FN (arccot), ARG(2.0e+00,1.19209289550781250e-07), RES(4.6364760900080497935e-1, -2.3841857910156200307e-8)}, {FN (arccot), ARG(2.0e+00,-1.19209289550781250e-07), RES(4.6364760900080497935e-1, 2.3841857910156200307e-8)}, {FN (arccot), ARG(-2.0e+00,1.19209289550781250e-07), RES(-4.6364760900080497935e-1, -2.3841857910156200307e-8)}, {FN (arccot), ARG(-2.0e+00,-1.19209289550781250e-07), RES(-4.6364760900080497935e-1, 2.3841857910156200307e-8)}, {FN (arccot), ARG(2.0e+00,5.0e-01), RES(4.4423988596007427049e-1, -9.6415620202996167238e-2)}, {FN (arccot), ARG(2.0e+00,-5.0e-01), RES(4.4423988596007427049e-1, 9.6415620202996167238e-2)}, {FN (arccot), ARG(-2.0e+00,5.0e-01), RES(-4.4423988596007427049e-1, -9.6415620202996167238e-2)}, {FN (arccot), ARG(-2.0e+00,-5.0e-01), RES(-4.4423988596007427049e-1, 9.6415620202996167238e-2)}, {FN (arccot), ARG(2.0e+00,1.0e+00), RES(3.9269908169872415481e-1, -1.7328679513998632735e-1)}, {FN (arccot), ARG(2.0e+00,-1.0e+00), RES(3.9269908169872415481e-1, 1.7328679513998632735e-1)}, {FN (arccot), ARG(-2.0e+00,1.0e+00), RES(-3.9269908169872415481e-1, -1.7328679513998632735e-1)}, {FN (arccot), ARG(-2.0e+00,-1.0e+00), RES(-3.9269908169872415481e-1, 1.7328679513998632735e-1)}, {FN (arccot), ARG(2.0e+00,2.0e+00), RES(2.5957305712326147589e-1, -2.3887786125685909036e-1)}, {FN (arccot), ARG(2.0e+00,-2.0e+00), RES(2.5957305712326147589e-1, 2.3887786125685909036e-1)}, {FN (arccot), ARG(-2.0e+00,2.0e+00), RES(-2.5957305712326147589e-1, -2.3887786125685909036e-1)}, {FN (arccot), ARG(-2.0e+00,-2.0e+00), RES(-2.5957305712326147589e-1, 2.3887786125685909036e-1)}, {FN (arccot), ARG(2.0e+00,8.3886080e+06), RES(2.8421709430402795744e-14, -1.1920928955077503843e-7)}, {FN (arccot), ARG(2.0e+00,-8.3886080e+06), RES(2.8421709430402795744e-14, 1.1920928955077503843e-7)}, {FN (arccot), ARG(-2.0e+00,8.3886080e+06), RES(-2.8421709430402795744e-14, -1.1920928955077503843e-7)}, {FN (arccot), ARG(-2.0e+00,-8.3886080e+06), RES(-2.8421709430402795744e-14, 1.1920928955077503843e-7)}, {FN (arccot), ARG(8.3886080e+06,0.0e+00), RES(1.1920928955078068531e-7, 0.0)}, {FN (arccot), ARG(-8.3886080e+06,0.0e+00), RES(-1.1920928955078068531e-7, 0.0)}, {FN (arccot), ARG(8.3886080e+06,1.19209289550781250e-07), RES(1.1920928955078068531e-7, -1.6940658945085766040e-21)}, {FN (arccot), ARG(8.3886080e+06,-1.19209289550781250e-07), RES(1.1920928955078068531e-7, 1.6940658945085766040e-21)}, {FN (arccot), ARG(-8.3886080e+06,1.19209289550781250e-07), RES(-1.1920928955078068531e-7, -1.6940658945085766040e-21)}, {FN (arccot), ARG(-8.3886080e+06,-1.19209289550781250e-07), RES(-1.1920928955078068531e-7, 1.6940658945085766040e-21)}, {FN (arccot), ARG(8.3886080e+06,5.0e-01), RES(1.1920928955078026179e-7, -7.1054273576008756410e-15)}, {FN (arccot), ARG(8.3886080e+06,-5.0e-01), RES(1.1920928955078026179e-7, 7.1054273576008756410e-15)}, {FN (arccot), ARG(-8.3886080e+06,5.0e-01), RES(-1.1920928955078026179e-7, -7.1054273576008756410e-15)}, {FN (arccot), ARG(-8.3886080e+06,-5.0e-01), RES(-1.1920928955078026179e-7, 7.1054273576008756410e-15)}, {FN (arccot), ARG(8.3886080e+06,1.0e+00), RES(1.1920928955077899125e-7, -1.4210854715201599821e-14)}, {FN (arccot), ARG(8.3886080e+06,-1.0e+00), RES(1.1920928955077899125e-7, 1.4210854715201599821e-14)}, {FN (arccot), ARG(-8.3886080e+06,1.0e+00), RES(-1.1920928955077899125e-7, -1.4210854715201599821e-14)}, {FN (arccot), ARG(-8.3886080e+06,-1.0e+00), RES(-1.1920928955077899125e-7, 1.4210854715201599821e-14)}, {FN (arccot), ARG(8.3886080e+06,2.0e+00), RES(1.1920928955077390905e-7, -2.8421709430401987951e-14)}, {FN (arccot), ARG(8.3886080e+06,-2.0e+00), RES(1.1920928955077390905e-7, 2.8421709430401987951e-14)}, {FN (arccot), ARG(-8.3886080e+06,2.0e+00), RES(-1.1920928955077390905e-7, -2.8421709430401987951e-14)}, {FN (arccot), ARG(-8.3886080e+06,-2.0e+00), RES(-1.1920928955077390905e-7, 2.8421709430401987951e-14)}, {FN (arccot), ARG(8.3886080e+06,8.3886080e+06), RES(5.9604644775390766172e-8, -5.9604644775390483828e-8)}, {FN (arccot), ARG(8.3886080e+06,-8.3886080e+06), RES(5.9604644775390766172e-8, 5.9604644775390483828e-8)}, {FN (arccot), ARG(-8.3886080e+06,8.3886080e+06), RES(-5.9604644775390766172e-8, -5.9604644775390483828e-8)}, {FN (arccot), ARG(-8.3886080e+06,-8.3886080e+06), RES(-5.9604644775390766172e-8, 5.9604644775390483828e-8)}, {FN (csch), ARG(0.0e+00,-3.45266983001243932001e-04), RES(0, 2.8963094332845964291e3)}, {FN (csch), ARG(0.0e+00,3.45266983001243932001e-04), RES(0, -2.8963094332845964291e3)}, {FN (csch), ARG(0.0e+00,1.57045105981189525579e+00), RES(0, -1.0000000596046477360e0)}, {FN (csch), ARG(0.0e+00,-1.57045105981189525579e+00), RES(0, 1.0000000596046477360e0)}, {FN (csch), ARG(0.0e+00,1.57114159377789786021e+00), RES(0, -1.0000000596046477360e0)}, {FN (csch), ARG(0.0e+00,-1.57114159377789786021e+00), RES(0, 1.0000000596046477360e0)}, {FN (csch), ARG(0.0e+00,3.14124738660679181379e+00), RES(0, -2.8963094332830802676e3)}, {FN (csch), ARG(0.0e+00,-3.14124738660679181379e+00), RES(0, 2.8963094332830802676e3)}, {FN (csch), ARG(0.0e+00,3.14193792057279441821e+00), RES(0, 2.8963094332851348839e3)}, {FN (csch), ARG(0.0e+00,-3.14193792057279441821e+00), RES(0, -2.8963094332851348839e3)}, {FN (csch), ARG(0.0e+00,4.71204371340168837179e+00), RES(0, 1.0000000596046477361e0)}, {FN (csch), ARG(0.0e+00,-4.71204371340168837179e+00), RES(0, -1.0000000596046477361e0)}, {FN (csch), ARG(0.0e+00,4.71273424736769097620e+00), RES(0, 1.0000000596046477359e0)}, {FN (csch), ARG(0.0e+00,-4.71273424736769097620e+00), RES(0, -1.0000000596046477359e0)}, {FN (csch), ARG(0.0e+00,6.28284004019658492979e+00), RES(0, 2.8963094332820529594e3)}, {FN (csch), ARG(0.0e+00,-6.28284004019658492979e+00), RES(0, -2.8963094332820529594e3)}, {FN (csch), ARG(0.0e+00,6.28353057416258753420e+00), RES(0, -2.8963094332861621921e3)}, {FN (csch), ARG(0.0e+00,-6.28353057416258753420e+00), RES(0, 2.8963094332861621921e3)}, {FN (csch), ARG(0.0e+00,9.42443269378637893396e+00), RES(0, -2.8963094332884762317e3)}, {FN (csch), ARG(0.0e+00,-9.42443269378637893396e+00), RES(0, 2.8963094332884762317e3)}, {FN (csch), ARG(0.0e+00,9.42512322775237976202e+00), RES(0, 2.8963094332946400807e3)}, {FN (csch), ARG(0.0e+00,-9.42512322775237976202e+00), RES(0, -2.8963094332946400807e3)}, {FN (csch), ARG(1.19209289550781250e-07,-3.45266983001243932001e-04), RES(9.9999986092250876926e-1, 2.8963090880176545869e3)}, {FN (csch), ARG(1.19209289550781250e-07,3.45266983001243932001e-04), RES(9.9999986092250876926e-1, -2.8963090880176545869e3)}, {FN (csch), ARG(-1.19209289550781250e-07,-3.45266983001243932001e-04), RES(-9.9999986092250876926e-1, 2.8963090880176545869e3)}, {FN (csch), ARG(-1.19209289550781250e-07,3.45266983001243932001e-04), RES(-9.9999986092250876926e-1, -2.8963090880176545869e3)}, {FN (csch), ARG(1.19209289550781250e-07,1.57045105981189525579e+00), RES(4.1159035837716456618e-11, -1.0000000596046406306e0)}, {FN (csch), ARG(1.19209289550781250e-07,-1.57045105981189525579e+00), RES(4.1159035837716456618e-11, 1.0000000596046406306e0)}, {FN (csch), ARG(-1.19209289550781250e-07,1.57045105981189525579e+00), RES(-4.1159035837716456618e-11, -1.0000000596046406306e0)}, {FN (csch), ARG(-1.19209289550781250e-07,-1.57045105981189525579e+00), RES(-4.1159035837716456618e-11, 1.0000000596046406306e0)}, {FN (csch), ARG(1.19209289550781250e-07,1.57114159377789786021e+00), RES(-4.1159035837701857686e-11, -1.0000000596046406306e0)}, {FN (csch), ARG(1.19209289550781250e-07,-1.57114159377789786021e+00), RES(-4.1159035837701857686e-11, 1.0000000596046406306e0)}, {FN (csch), ARG(-1.19209289550781250e-07,1.57114159377789786021e+00), RES(4.1159035837701857686e-11, -1.0000000596046406306e0)}, {FN (csch), ARG(-1.19209289550781250e-07,-1.57114159377789786021e+00), RES(4.1159035837701857686e-11, 1.0000000596046406306e0)}, {FN (csch), ARG(1.19209289550781250e-07,3.14124738660679181379e+00), RES(-9.9999986092146180843e-1, -2.8963090880161384259e3)}, {FN (csch), ARG(1.19209289550781250e-07,-3.14124738660679181379e+00), RES(-9.9999986092146180843e-1, 2.8963090880161384259e3)}, {FN (csch), ARG(-1.19209289550781250e-07,3.14124738660679181379e+00), RES(9.9999986092146180843e-1, -2.8963090880161384259e3)}, {FN (csch), ARG(-1.19209289550781250e-07,-3.14124738660679181379e+00), RES(9.9999986092146180843e-1, 2.8963090880161384259e3)}, {FN (csch), ARG(1.19209289550781250e-07,3.14193792057279441821e+00), RES(-9.9999986092288059049e-1, 2.8963090880181930415e3)}, {FN (csch), ARG(1.19209289550781250e-07,-3.14193792057279441821e+00), RES(-9.9999986092288059049e-1, -2.8963090880181930415e3)}, {FN (csch), ARG(-1.19209289550781250e-07,3.14193792057279441821e+00), RES(9.9999986092288059049e-1, 2.8963090880181930415e3)}, {FN (csch), ARG(-1.19209289550781250e-07,-3.14193792057279441821e+00), RES(9.9999986092288059049e-1, -2.8963090880181930415e3)}, {FN (csch), ARG(1.19209289550781250e-07,4.71204371340168837179e+00), RES(-4.1159035837731055550e-11, 1.0000000596046406306e0)}, {FN (csch), ARG(1.19209289550781250e-07,-4.71204371340168837179e+00), RES(-4.1159035837731055550e-11, -1.0000000596046406306e0)}, {FN (csch), ARG(-1.19209289550781250e-07,4.71204371340168837179e+00), RES(4.1159035837731055550e-11, 1.0000000596046406306e0)}, {FN (csch), ARG(-1.19209289550781250e-07,-4.71204371340168837179e+00), RES(4.1159035837731055550e-11, -1.0000000596046406306e0)}, {FN (csch), ARG(1.19209289550781250e-07,4.71273424736769097620e+00), RES(4.1159035837687258754e-11, 1.0000000596046406305e0)}, {FN (csch), ARG(1.19209289550781250e-07,-4.71273424736769097620e+00), RES(4.1159035837687258754e-11, -1.0000000596046406305e0)}, {FN (csch), ARG(-1.19209289550781250e-07,4.71273424736769097620e+00), RES(-4.1159035837687258754e-11, 1.0000000596046406305e0)}, {FN (csch), ARG(-1.19209289550781250e-07,-4.71273424736769097620e+00), RES(-4.1159035837687258754e-11, -1.0000000596046406305e0)}, {FN (csch), ARG(1.19209289550781250e-07,6.28284004019658492979e+00), RES(9.9999986092075241740e-1, 2.8963090880151111181e3)}, {FN (csch), ARG(1.19209289550781250e-07,-6.28284004019658492979e+00), RES(9.9999986092075241740e-1, -2.8963090880151111181e3)}, {FN (csch), ARG(-1.19209289550781250e-07,6.28284004019658492979e+00), RES(-9.9999986092075241740e-1, 2.8963090880151111181e3)}, {FN (csch), ARG(-1.19209289550781250e-07,-6.28284004019658492979e+00), RES(-9.9999986092075241740e-1, -2.8963090880151111181e3)}, {FN (csch), ARG(1.19209289550781250e-07,6.28353057416258753420e+00), RES(9.9999986092358998153e-1, -2.8963090880192203493e3)}, {FN (csch), ARG(1.19209289550781250e-07,-6.28353057416258753420e+00), RES(9.9999986092358998153e-1, 2.8963090880192203493e3)}, {FN (csch), ARG(-1.19209289550781250e-07,6.28353057416258753420e+00), RES(-9.9999986092358998153e-1, -2.8963090880192203493e3)}, {FN (csch), ARG(-1.19209289550781250e-07,-6.28353057416258753420e+00), RES(-9.9999986092358998153e-1, 2.8963090880192203493e3)}, {FN (csch), ARG(1.19209289550781250e-07,9.42443269378637893396e+00), RES(-9.9999986092518790411e-1, -2.8963090880215343881e3)}, {FN (csch), ARG(1.19209289550781250e-07,-9.42443269378637893396e+00), RES(-9.9999986092518790411e-1, 2.8963090880215343881e3)}, {FN (csch), ARG(-1.19209289550781250e-07,9.42443269378637893396e+00), RES(9.9999986092518790411e-1, -2.8963090880215343881e3)}, {FN (csch), ARG(-1.19209289550781250e-07,-9.42443269378637893396e+00), RES(9.9999986092518790411e-1, 2.8963090880215343881e3)}, {FN (csch), ARG(1.19209289550781250e-07,9.42512322775237976202e+00), RES(-9.9999986092944425030e-1, 2.8963090880276982349e3)}, {FN (csch), ARG(1.19209289550781250e-07,-9.42512322775237976202e+00), RES(-9.9999986092944425030e-1, -2.8963090880276982349e3)}, {FN (csch), ARG(-1.19209289550781250e-07,9.42512322775237976202e+00), RES(9.9999986092944425030e-1, 2.8963090880276982349e3)}, {FN (csch), ARG(-1.19209289550781250e-07,-9.42512322775237976202e+00), RES(9.9999986092944425030e-1, -2.8963090880276982349e3)}, {FN (csch), ARG(5.0e-01,-3.45266983001243932001e-04), RES(1.9190337944739187237e0, 1.4337901642789801243e-3)}, {FN (csch), ARG(5.0e-01,3.45266983001243932001e-04), RES(1.9190337944739187237e0, -1.4337901642789801243e-3)}, {FN (csch), ARG(-5.0e-01,-3.45266983001243932001e-04), RES(-1.9190337944739187237e0, 1.4337901642789801243e-3)}, {FN (csch), ARG(-5.0e-01,3.45266983001243932001e-04), RES(-1.9190337944739187237e0, -1.4337901642789801243e-3)}, {FN (csch), ARG(5.0e-01,1.57045105981189525579e+00), RES(1.4149533035943115868e-4, -8.8681891425248302487e-1)}, {FN (csch), ARG(5.0e-01,-1.57045105981189525579e+00), RES(1.4149533035943115868e-4, 8.8681891425248302487e-1)}, {FN (csch), ARG(-5.0e-01,1.57045105981189525579e+00), RES(-1.4149533035943115868e-4, -8.8681891425248302487e-1)}, {FN (csch), ARG(-5.0e-01,-1.57045105981189525579e+00), RES(-1.4149533035943115868e-4, 8.8681891425248302487e-1)}, {FN (csch), ARG(5.0e-01,1.57114159377789786021e+00), RES(-1.4149533035938097090e-4, -8.8681891425248302485e-1)}, {FN (csch), ARG(5.0e-01,-1.57114159377789786021e+00), RES(-1.4149533035938097090e-4, 8.8681891425248302485e-1)}, {FN (csch), ARG(-5.0e-01,1.57114159377789786021e+00), RES(1.4149533035938097090e-4, -8.8681891425248302485e-1)}, {FN (csch), ARG(-5.0e-01,-1.57114159377789786021e+00), RES(1.4149533035938097090e-4, 8.8681891425248302485e-1)}, {FN (csch), ARG(5.0e-01,3.14124738660679181379e+00), RES(-1.9190337944739187227e0, -1.4337901642797306848e-3)}, {FN (csch), ARG(5.0e-01,-3.14124738660679181379e+00), RES(-1.9190337944739187227e0, 1.4337901642797306848e-3)}, {FN (csch), ARG(-5.0e-01,3.14124738660679181379e+00), RES(1.9190337944739187227e0, -1.4337901642797306848e-3)}, {FN (csch), ARG(-5.0e-01,-3.14124738660679181379e+00), RES(1.9190337944739187227e0, 1.4337901642797306848e-3)}, {FN (csch), ARG(5.0e-01,3.14193792057279441821e+00), RES(-1.9190337944739187241e0, 1.4337901642787135676e-3)}, {FN (csch), ARG(5.0e-01,-3.14193792057279441821e+00), RES(-1.9190337944739187241e0, -1.4337901642787135676e-3)}, {FN (csch), ARG(-5.0e-01,3.14193792057279441821e+00), RES(1.9190337944739187241e0, 1.4337901642787135676e-3)}, {FN (csch), ARG(-5.0e-01,-3.14193792057279441821e+00), RES(1.9190337944739187241e0, -1.4337901642787135676e-3)}, {FN (csch), ARG(5.0e-01,4.71204371340168837179e+00), RES(-1.4149533035948134646e-4, 8.8681891425248302489e-1)}, {FN (csch), ARG(5.0e-01,-4.71204371340168837179e+00), RES(-1.4149533035948134646e-4, -8.8681891425248302489e-1)}, {FN (csch), ARG(-5.0e-01,4.71204371340168837179e+00), RES(1.4149533035948134646e-4, 8.8681891425248302489e-1)}, {FN (csch), ARG(-5.0e-01,-4.71204371340168837179e+00), RES(1.4149533035948134646e-4, -8.8681891425248302489e-1)}, {FN (csch), ARG(5.0e-01,4.71273424736769097620e+00), RES(1.4149533035933078312e-4, 8.8681891425248302483e-1)}, {FN (csch), ARG(5.0e-01,-4.71273424736769097620e+00), RES(1.4149533035933078312e-4, -8.8681891425248302483e-1)}, {FN (csch), ARG(-5.0e-01,4.71273424736769097620e+00), RES(-1.4149533035933078312e-4, 8.8681891425248302483e-1)}, {FN (csch), ARG(-5.0e-01,-4.71273424736769097620e+00), RES(-1.4149533035933078312e-4, -8.8681891425248302483e-1)}, {FN (csch), ARG(5.0e-01,6.28284004019658492979e+00), RES(1.9190337944739187220e0, 1.4337901642802392434e-3)}, {FN (csch), ARG(5.0e-01,-6.28284004019658492979e+00), RES(1.9190337944739187220e0, -1.4337901642802392434e-3)}, {FN (csch), ARG(-5.0e-01,6.28284004019658492979e+00), RES(-1.9190337944739187220e0, 1.4337901642802392434e-3)}, {FN (csch), ARG(-5.0e-01,-6.28284004019658492979e+00), RES(-1.9190337944739187220e0, -1.4337901642802392434e-3)}, {FN (csch), ARG(5.0e-01,6.28353057416258753420e+00), RES(1.9190337944739187248e0, -1.4337901642782050091e-3)}, {FN (csch), ARG(5.0e-01,-6.28353057416258753420e+00), RES(1.9190337944739187248e0, 1.4337901642782050091e-3)}, {FN (csch), ARG(-5.0e-01,6.28353057416258753420e+00), RES(-1.9190337944739187248e0, -1.4337901642782050091e-3)}, {FN (csch), ARG(-5.0e-01,-6.28353057416258753420e+00), RES(-1.9190337944739187248e0, 1.4337901642782050091e-3)}, {FN (csch), ARG(5.0e-01,9.42443269378637893396e+00), RES(-1.9190337944739187263e0, -1.4337901642770594670e-3)}, {FN (csch), ARG(5.0e-01,-9.42443269378637893396e+00), RES(-1.9190337944739187263e0, 1.4337901642770594670e-3)}, {FN (csch), ARG(-5.0e-01,9.42443269378637893396e+00), RES(1.9190337944739187263e0, -1.4337901642770594670e-3)}, {FN (csch), ARG(-5.0e-01,-9.42443269378637893396e+00), RES(1.9190337944739187263e0, 1.4337901642770594670e-3)}, {FN (csch), ARG(5.0e-01,9.42512322775237976202e+00), RES(-1.9190337944739187304e0, 1.4337901642740081154e-3)}, {FN (csch), ARG(5.0e-01,-9.42512322775237976202e+00), RES(-1.9190337944739187304e0, -1.4337901642740081154e-3)}, {FN (csch), ARG(-5.0e-01,9.42512322775237976202e+00), RES(1.9190337944739187304e0, 1.4337901642740081154e-3)}, {FN (csch), ARG(-5.0e-01,-9.42512322775237976202e+00), RES(1.9190337944739187304e0, -1.4337901642740081154e-3)}, {FN (csch), ARG(1.0e+00,-3.45266983001243932001e-04), RES(8.5091800407377002734e-1, 3.8576176225198860914e-4)}, {FN (csch), ARG(1.0e+00,3.45266983001243932001e-04), RES(8.5091800407377002734e-1, -3.8576176225198860914e-4)}, {FN (csch), ARG(-1.0e+00,-3.45266983001243932001e-04), RES(-8.5091800407377002734e-1, 3.8576176225198860914e-4)}, {FN (csch), ARG(-1.0e+00,3.45266983001243932001e-04), RES(-8.5091800407377002734e-1, -3.8576176225198860914e-4)}, {FN (csch), ARG(1.0e+00,1.57045105981189525579e+00), RES(1.7040802567657401279e-4, -6.4805426748157480499e-1)}, {FN (csch), ARG(1.0e+00,-1.57045105981189525579e+00), RES(1.7040802567657401279e-4, 6.4805426748157480499e-1)}, {FN (csch), ARG(-1.0e+00,1.57045105981189525579e+00), RES(-1.7040802567657401279e-4, -6.4805426748157480499e-1)}, {FN (csch), ARG(-1.0e+00,-1.57045105981189525579e+00), RES(-1.7040802567657401279e-4, 6.4805426748157480499e-1)}, {FN (csch), ARG(1.0e+00,1.57114159377789786021e+00), RES(-1.7040802567651356981e-4, -6.4805426748157480499e-1)}, {FN (csch), ARG(1.0e+00,-1.57114159377789786021e+00), RES(-1.7040802567651356981e-4, 6.4805426748157480499e-1)}, {FN (csch), ARG(-1.0e+00,1.57114159377789786021e+00), RES(1.7040802567651356981e-4, -6.4805426748157480499e-1)}, {FN (csch), ARG(-1.0e+00,-1.57114159377789786021e+00), RES(1.7040802567651356981e-4, 6.4805426748157480499e-1)}, {FN (csch), ARG(1.0e+00,3.14124738660679181379e+00), RES(-8.5091800407377002721e-1, -3.8576176225219054787e-4)}, {FN (csch), ARG(1.0e+00,-3.14124738660679181379e+00), RES(-8.5091800407377002721e-1, 3.8576176225219054787e-4)}, {FN (csch), ARG(-1.0e+00,3.14124738660679181379e+00), RES(8.5091800407377002721e-1, -3.8576176225219054787e-4)}, {FN (csch), ARG(-1.0e+00,-3.14124738660679181379e+00), RES(8.5091800407377002721e-1, 3.8576176225219054787e-4)}, {FN (csch), ARG(1.0e+00,3.14193792057279441821e+00), RES(-8.5091800407377002738e-1, 3.8576176225191689193e-4)}, {FN (csch), ARG(1.0e+00,-3.14193792057279441821e+00), RES(-8.5091800407377002738e-1, -3.8576176225191689193e-4)}, {FN (csch), ARG(-1.0e+00,3.14193792057279441821e+00), RES(8.5091800407377002738e-1, 3.8576176225191689193e-4)}, {FN (csch), ARG(-1.0e+00,-3.14193792057279441821e+00), RES(8.5091800407377002738e-1, -3.8576176225191689193e-4)}, {FN (csch), ARG(1.0e+00,4.71204371340168837179e+00), RES(-1.7040802567663445577e-4, 6.4805426748157480498e-1)}, {FN (csch), ARG(1.0e+00,-4.71204371340168837179e+00), RES(-1.7040802567663445577e-4, -6.4805426748157480498e-1)}, {FN (csch), ARG(-1.0e+00,4.71204371340168837179e+00), RES(1.7040802567663445577e-4, 6.4805426748157480498e-1)}, {FN (csch), ARG(-1.0e+00,-4.71204371340168837179e+00), RES(1.7040802567663445577e-4, -6.4805426748157480498e-1)}, {FN (csch), ARG(1.0e+00,4.71273424736769097620e+00), RES(1.7040802567645312683e-4, 6.480542674815748050e-1)}, {FN (csch), ARG(1.0e+00,-4.71273424736769097620e+00), RES(1.7040802567645312683e-4, -6.480542674815748050e-1)}, {FN (csch), ARG(-1.0e+00,4.71273424736769097620e+00), RES(-1.7040802567645312683e-4, 6.480542674815748050e-1)}, {FN (csch), ARG(-1.0e+00,-4.71273424736769097620e+00), RES(-1.7040802567645312683e-4, -6.480542674815748050e-1)}, {FN (csch), ARG(1.0e+00,6.28284004019658492979e+00), RES(8.5091800407377002712e-1, 3.8576176225232737584e-4)}, {FN (csch), ARG(1.0e+00,-6.28284004019658492979e+00), RES(8.5091800407377002712e-1, -3.8576176225232737584e-4)}, {FN (csch), ARG(-1.0e+00,6.28284004019658492979e+00), RES(-8.5091800407377002712e-1, 3.8576176225232737584e-4)}, {FN (csch), ARG(-1.0e+00,-6.28284004019658492979e+00), RES(-8.5091800407377002712e-1, -3.8576176225232737584e-4)}, {FN (csch), ARG(1.0e+00,6.28353057416258753420e+00), RES(8.5091800407377002747e-1, -3.8576176225178006396e-4)}, {FN (csch), ARG(1.0e+00,-6.28353057416258753420e+00), RES(8.5091800407377002747e-1, 3.8576176225178006396e-4)}, {FN (csch), ARG(-1.0e+00,6.28353057416258753420e+00), RES(-8.5091800407377002747e-1, -3.8576176225178006396e-4)}, {FN (csch), ARG(-1.0e+00,-6.28353057416258753420e+00), RES(-8.5091800407377002747e-1, 3.8576176225178006396e-4)}, {FN (csch), ARG(1.0e+00,9.42443269378637893396e+00), RES(-8.5091800407377002767e-1, -3.8576176225147185523e-4)}, {FN (csch), ARG(1.0e+00,-9.42443269378637893396e+00), RES(-8.5091800407377002767e-1, 3.8576176225147185523e-4)}, {FN (csch), ARG(-1.0e+00,9.42443269378637893396e+00), RES(8.5091800407377002767e-1, -3.8576176225147185523e-4)}, {FN (csch), ARG(-1.0e+00,-9.42443269378637893396e+00), RES(8.5091800407377002767e-1, 3.8576176225147185523e-4)}, {FN (csch), ARG(1.0e+00,9.42512322775237976202e+00), RES(-8.5091800407377002820e-1, 3.8576176225065088741e-4)}, {FN (csch), ARG(1.0e+00,-9.42512322775237976202e+00), RES(-8.5091800407377002820e-1, -3.8576176225065088741e-4)}, {FN (csch), ARG(-1.0e+00,9.42512322775237976202e+00), RES(8.5091800407377002820e-1, 3.8576176225065088741e-4)}, {FN (csch), ARG(-1.0e+00,-9.42512322775237976202e+00), RES(8.5091800407377002820e-1, -3.8576176225065088741e-4)}, {FN (csch), ARG(2.0e+00,-3.45266983001243932001e-04), RES(2.7572054583883740768e-1, 9.8749461907035665386e-5)}, {FN (csch), ARG(2.0e+00,3.45266983001243932001e-04), RES(2.7572054583883740768e-1, -9.8749461907035665386e-5)}, {FN (csch), ARG(-2.0e+00,-3.45266983001243932001e-04), RES(-2.7572054583883740768e-1, 9.8749461907035665386e-5)}, {FN (csch), ARG(-2.0e+00,3.45266983001243932001e-04), RES(-2.7572054583883740768e-1, -9.8749461907035665386e-5)}, {FN (csch), ARG(2.0e+00,1.57045105981189525579e+00), RES(8.8471445300404633228e-5, -2.6580221522968095406e-1)}, {FN (csch), ARG(2.0e+00,-1.57045105981189525579e+00), RES(8.8471445300404633228e-5, 2.6580221522968095406e-1)}, {FN (csch), ARG(-2.0e+00,1.57045105981189525579e+00), RES(-8.8471445300404633228e-5, -2.6580221522968095406e-1)}, {FN (csch), ARG(-2.0e+00,-1.57045105981189525579e+00), RES(-8.8471445300404633228e-5, 2.6580221522968095406e-1)}, {FN (csch), ARG(2.0e+00,1.57114159377789786021e+00), RES(-8.8471445300373252796e-5, -2.6580221522968095407e-1)}, {FN (csch), ARG(2.0e+00,-1.57114159377789786021e+00), RES(-8.8471445300373252796e-5, 2.6580221522968095407e-1)}, {FN (csch), ARG(-2.0e+00,1.57114159377789786021e+00), RES(8.8471445300373252796e-5, -2.6580221522968095407e-1)}, {FN (csch), ARG(-2.0e+00,-1.57114159377789786021e+00), RES(8.8471445300373252796e-5, 2.6580221522968095407e-1)}, {FN (csch), ARG(2.0e+00,3.14124738660679181379e+00), RES(-2.7572054583883740766e-1, -9.8749461907087358805e-5)}, {FN (csch), ARG(2.0e+00,-3.14124738660679181379e+00), RES(-2.7572054583883740766e-1, 9.8749461907087358805e-5)}, {FN (csch), ARG(-2.0e+00,3.14124738660679181379e+00), RES(2.7572054583883740766e-1, -9.8749461907087358805e-5)}, {FN (csch), ARG(-2.0e+00,-3.14124738660679181379e+00), RES(2.7572054583883740766e-1, 9.8749461907087358805e-5)}, {FN (csch), ARG(2.0e+00,3.14193792057279441821e+00), RES(-2.7572054583883740769e-1, 9.8749461907017306810e-5)}, {FN (csch), ARG(2.0e+00,-3.14193792057279441821e+00), RES(-2.7572054583883740769e-1, -9.8749461907017306810e-5)}, {FN (csch), ARG(-2.0e+00,3.14193792057279441821e+00), RES(2.7572054583883740769e-1, 9.8749461907017306810e-5)}, {FN (csch), ARG(-2.0e+00,-3.14193792057279441821e+00), RES(2.7572054583883740769e-1, -9.8749461907017306810e-5)}, {FN (csch), ARG(2.0e+00,4.71204371340168837179e+00), RES(-8.8471445300436013659e-5, 2.6580221522968095405e-1)}, {FN (csch), ARG(2.0e+00,-4.71204371340168837179e+00), RES(-8.8471445300436013659e-5, -2.6580221522968095405e-1)}, {FN (csch), ARG(-2.0e+00,4.71204371340168837179e+00), RES(8.8471445300436013659e-5, 2.6580221522968095405e-1)}, {FN (csch), ARG(-2.0e+00,-4.71204371340168837179e+00), RES(8.8471445300436013659e-5, -2.6580221522968095405e-1)}, {FN (csch), ARG(2.0e+00,4.71273424736769097620e+00), RES(8.8471445300341872364e-5, 2.6580221522968095408e-1)}, {FN (csch), ARG(2.0e+00,-4.71273424736769097620e+00), RES(8.8471445300341872364e-5, -2.6580221522968095408e-1)}, {FN (csch), ARG(-2.0e+00,4.71273424736769097620e+00), RES(-8.8471445300341872364e-5, 2.6580221522968095408e-1)}, {FN (csch), ARG(-2.0e+00,-4.71273424736769097620e+00), RES(-8.8471445300341872364e-5, -2.6580221522968095408e-1)}, {FN (csch), ARG(2.0e+00,6.28284004019658492979e+00), RES(2.7572054583883740765e-1, 9.8749461907122384803e-5)}, {FN (csch), ARG(2.0e+00,-6.28284004019658492979e+00), RES(2.7572054583883740765e-1, -9.8749461907122384803e-5)}, {FN (csch), ARG(-2.0e+00,6.28284004019658492979e+00), RES(-2.7572054583883740765e-1, 9.8749461907122384803e-5)}, {FN (csch), ARG(-2.0e+00,-6.28284004019658492979e+00), RES(-2.7572054583883740765e-1, -9.8749461907122384803e-5)}, {FN (csch), ARG(2.0e+00,6.28353057416258753420e+00), RES(2.7572054583883740770e-1, -9.8749461906982280812e-5)}, {FN (csch), ARG(2.0e+00,-6.28353057416258753420e+00), RES(2.7572054583883740770e-1, 9.8749461906982280812e-5)}, {FN (csch), ARG(-2.0e+00,6.28353057416258753420e+00), RES(-2.7572054583883740770e-1, -9.8749461906982280812e-5)}, {FN (csch), ARG(-2.0e+00,-6.28353057416258753420e+00), RES(-2.7572054583883740770e-1, 9.8749461906982280812e-5)}, {FN (csch), ARG(2.0e+00,9.42443269378637893396e+00), RES(-2.7572054583883740773e-1, -9.874946190690338380e-5)}, {FN (csch), ARG(2.0e+00,-9.42443269378637893396e+00), RES(-2.7572054583883740773e-1, 9.874946190690338380e-5)}, {FN (csch), ARG(-2.0e+00,9.42443269378637893396e+00), RES(2.7572054583883740773e-1, -9.874946190690338380e-5)}, {FN (csch), ARG(-2.0e+00,-9.42443269378637893396e+00), RES(2.7572054583883740773e-1, 9.874946190690338380e-5)}, {FN (csch), ARG(2.0e+00,9.42512322775237976202e+00), RES(-2.7572054583883740781e-1, 9.8749461906693227814e-5)}, {FN (csch), ARG(2.0e+00,-9.42512322775237976202e+00), RES(-2.7572054583883740781e-1, -9.8749461906693227814e-5)}, {FN (csch), ARG(-2.0e+00,9.42512322775237976202e+00), RES(2.7572054583883740781e-1, 9.8749461906693227814e-5)}, {FN (csch), ARG(-2.0e+00,-9.42512322775237976202e+00), RES(2.7572054583883740781e-1, -9.8749461906693227814e-5)}, {FN (sech), ARG(0.0e+00,-3.45266983001243932001e-04), RES(1.0000000596046477360e0, 0.0)}, {FN (sech), ARG(0.0e+00,3.45266983001243932001e-04), RES(1.0000000596046477360e0, 0.0)}, {FN (sech), ARG(0.0e+00,1.57045105981189525579e+00), RES(2.8963094332835939217e3, 0.0)}, {FN (sech), ARG(0.0e+00,-1.57045105981189525579e+00), RES(2.8963094332835939217e3, 0.0)}, {FN (sech), ARG(0.0e+00,1.57114159377789786021e+00), RES(-2.8963094332846212298e3, 0.0)}, {FN (sech), ARG(0.0e+00,-1.57114159377789786021e+00), RES(-2.8963094332846212298e3, 0.0)}, {FN (sech), ARG(0.0e+00,3.14124738660679181379e+00), RES(-1.0000000596046477360e0, 0.0)}, {FN (sech), ARG(0.0e+00,-3.14124738660679181379e+00), RES(-1.0000000596046477360e0, 0.0)}, {FN (sech), ARG(0.0e+00,3.14193792057279441821e+00), RES(-1.0000000596046477360e0, 0.0)}, {FN (sech), ARG(0.0e+00,-3.14193792057279441821e+00), RES(-1.0000000596046477360e0, 0.0)}, {FN (sech), ARG(0.0e+00,4.71204371340168837179e+00), RES(-2.8963094332825666135e3, 0.0)}, {FN (sech), ARG(0.0e+00,-4.71204371340168837179e+00), RES(-2.8963094332825666135e3, 0.0)}, {FN (sech), ARG(0.0e+00,4.71273424736769097620e+00), RES(2.8963094332856485380e3, 0.0)}, {FN (sech), ARG(0.0e+00,-4.71273424736769097620e+00), RES(2.8963094332856485380e3, 0.0)}, {FN (sech), ARG(0.0e+00,6.28284004019658492979e+00), RES(1.0000000596046477361e0, 0.0)}, {FN (sech), ARG(0.0e+00,-6.28284004019658492979e+00), RES(1.0000000596046477361e0, 0.0)}, {FN (sech), ARG(0.0e+00,6.28353057416258753420e+00), RES(1.0000000596046477359e0, 0.0)}, {FN (sech), ARG(0.0e+00,-6.28353057416258753420e+00), RES(1.0000000596046477359e0, 0.0)}, {FN (sech), ARG(0.0e+00,9.42443269378637893396e+00), RES(-1.0000000596046477358e0, 0.0)}, {FN (sech), ARG(0.0e+00,-9.42443269378637893396e+00), RES(-1.0000000596046477358e0, 0.0)}, {FN (sech), ARG(0.0e+00,9.42512322775237976202e+00), RES(-1.0000000596046477356e0, 0.0)}, {FN (sech), ARG(0.0e+00,-9.42512322775237976202e+00), RES(-1.0000000596046477356e0, 0.0)}, {FN (sech), ARG(1.19209289550781250e-07,-3.45266983001243932001e-04), RES(1.0000000596046406306e0, 4.1159035837702210125e-11)}, {FN (sech), ARG(1.19209289550781250e-07,3.45266983001243932001e-04), RES(1.0000000596046406306e0, -4.1159035837702210125e-11)}, {FN (sech), ARG(-1.19209289550781250e-07,-3.45266983001243932001e-04), RES(1.0000000596046406306e0, -4.1159035837702210125e-11)}, {FN (sech), ARG(-1.19209289550781250e-07,3.45266983001243932001e-04), RES(1.0000000596046406306e0, 4.1159035837702210125e-11)}, {FN (sech), ARG(1.19209289550781250e-07,1.57045105981189525579e+00), RES(2.8963090880166520798e3, -9.9999986092181650394e-1)}, {FN (sech), ARG(1.19209289550781250e-07,-1.57045105981189525579e+00), RES(2.8963090880166520798e3, 9.9999986092181650394e-1)}, {FN (sech), ARG(-1.19209289550781250e-07,1.57045105981189525579e+00), RES(2.8963090880166520798e3, 9.9999986092181650394e-1)}, {FN (sech), ARG(-1.19209289550781250e-07,-1.57045105981189525579e+00), RES(2.8963090880166520798e3, -9.9999986092181650394e-1)}, {FN (sech), ARG(1.19209289550781250e-07,1.57114159377789786021e+00), RES(-2.8963090880176793876e3, -9.9999986092252589498e-1)}, {FN (sech), ARG(1.19209289550781250e-07,-1.57114159377789786021e+00), RES(-2.8963090880176793876e3, 9.9999986092252589498e-1)}, {FN (sech), ARG(-1.19209289550781250e-07,1.57114159377789786021e+00), RES(-2.8963090880176793876e3, 9.9999986092252589498e-1)}, {FN (sech), ARG(-1.19209289550781250e-07,-1.57114159377789786021e+00), RES(-2.8963090880176793876e3, -9.9999986092252589498e-1)}, {FN (sech), ARG(1.19209289550781250e-07,3.14124738660679181379e+00), RES(-1.0000000596046406306e0, -4.1159035837723756084e-11)}, {FN (sech), ARG(1.19209289550781250e-07,-3.14124738660679181379e+00), RES(-1.0000000596046406306e0, 4.1159035837723756084e-11)}, {FN (sech), ARG(-1.19209289550781250e-07,3.14124738660679181379e+00), RES(-1.0000000596046406306e0, 4.1159035837723756084e-11)}, {FN (sech), ARG(-1.19209289550781250e-07,-3.14124738660679181379e+00), RES(-1.0000000596046406306e0, -4.1159035837723756084e-11)}, {FN (sech), ARG(1.19209289550781250e-07,3.14193792057279441821e+00), RES(-1.0000000596046406305e0, 4.1159035837694558220e-11)}, {FN (sech), ARG(1.19209289550781250e-07,-3.14193792057279441821e+00), RES(-1.0000000596046406305e0, -4.1159035837694558220e-11)}, {FN (sech), ARG(-1.19209289550781250e-07,3.14193792057279441821e+00), RES(-1.0000000596046406305e0, -4.1159035837694558220e-11)}, {FN (sech), ARG(-1.19209289550781250e-07,-3.14193792057279441821e+00), RES(-1.0000000596046406305e0, 4.1159035837694558220e-11)}, {FN (sech), ARG(1.19209289550781250e-07,4.71204371340168837179e+00), RES(-2.8963090880156247720e3, 9.9999986092110711291e-1)}, {FN (sech), ARG(1.19209289550781250e-07,-4.71204371340168837179e+00), RES(-2.8963090880156247720e3, -9.9999986092110711291e-1)}, {FN (sech), ARG(-1.19209289550781250e-07,4.71204371340168837179e+00), RES(-2.8963090880156247720e3, -9.9999986092110711291e-1)}, {FN (sech), ARG(-1.19209289550781250e-07,-4.71204371340168837179e+00), RES(-2.8963090880156247720e3, 9.9999986092110711291e-1)}, {FN (sech), ARG(1.19209289550781250e-07,4.71273424736769097620e+00), RES(2.8963090880187066954e3, 9.9999986092323528601e-1)}, {FN (sech), ARG(1.19209289550781250e-07,-4.71273424736769097620e+00), RES(2.8963090880187066954e3, -9.9999986092323528601e-1)}, {FN (sech), ARG(-1.19209289550781250e-07,4.71273424736769097620e+00), RES(2.8963090880187066954e3, -9.9999986092323528601e-1)}, {FN (sech), ARG(-1.19209289550781250e-07,-4.71273424736769097620e+00), RES(2.8963090880187066954e3, 9.9999986092323528601e-1)}, {FN (sech), ARG(1.19209289550781250e-07,6.28284004019658492979e+00), RES(1.0000000596046406307e0, 4.1159035837738355016e-11)}, {FN (sech), ARG(1.19209289550781250e-07,-6.28284004019658492979e+00), RES(1.0000000596046406307e0, -4.1159035837738355016e-11)}, {FN (sech), ARG(-1.19209289550781250e-07,6.28284004019658492979e+00), RES(1.0000000596046406307e0, -4.1159035837738355016e-11)}, {FN (sech), ARG(-1.19209289550781250e-07,-6.28284004019658492979e+00), RES(1.0000000596046406307e0, 4.1159035837738355016e-11)}, {FN (sech), ARG(1.19209289550781250e-07,6.28353057416258753420e+00), RES(1.0000000596046406305e0, -4.1159035837679959288e-11)}, {FN (sech), ARG(1.19209289550781250e-07,-6.28353057416258753420e+00), RES(1.0000000596046406305e0, 4.1159035837679959288e-11)}, {FN (sech), ARG(-1.19209289550781250e-07,6.28353057416258753420e+00), RES(1.0000000596046406305e0, 4.1159035837679959288e-11)}, {FN (sech), ARG(-1.19209289550781250e-07,-6.28353057416258753420e+00), RES(1.0000000596046406305e0, -4.1159035837679959288e-11)}, {FN (sech), ARG(1.19209289550781250e-07,9.42443269378637893396e+00), RES(-1.0000000596046406304e0, -4.1159035837647074798e-11)}, {FN (sech), ARG(1.19209289550781250e-07,-9.42443269378637893396e+00), RES(-1.0000000596046406304e0, 4.1159035837647074798e-11)}, {FN (sech), ARG(-1.19209289550781250e-07,9.42443269378637893396e+00), RES(-1.0000000596046406304e0, 4.1159035837647074798e-11)}, {FN (sech), ARG(-1.19209289550781250e-07,-9.42443269378637893396e+00), RES(-1.0000000596046406304e0, -4.1159035837647074798e-11)}, {FN (sech), ARG(1.19209289550781250e-07,9.42512322775237976202e+00), RES(-1.0000000596046406301e0, 4.1159035837559481207e-11)}, {FN (sech), ARG(1.19209289550781250e-07,-9.42512322775237976202e+00), RES(-1.0000000596046406301e0, -4.1159035837559481207e-11)}, {FN (sech), ARG(-1.19209289550781250e-07,9.42512322775237976202e+00), RES(-1.0000000596046406301e0, -4.1159035837559481207e-11)}, {FN (sech), ARG(-1.19209289550781250e-07,-9.42512322775237976202e+00), RES(-1.0000000596046406301e0, 4.1159035837559481207e-11)}, {FN (sech), ARG(5.0e-01,-3.45266983001243932001e-04), RES(8.8681891425248302485e-1, 1.4149533035938218250e-4)}, {FN (sech), ARG(5.0e-01,3.45266983001243932001e-04), RES(8.8681891425248302485e-1, -1.4149533035938218250e-4)}, {FN (sech), ARG(-5.0e-01,-3.45266983001243932001e-04), RES(8.8681891425248302485e-1, -1.4149533035938218250e-4)}, {FN (sech), ARG(-5.0e-01,3.45266983001243932001e-04), RES(8.8681891425248302485e-1, 1.4149533035938218250e-4)}, {FN (sech), ARG(5.0e-01,1.57045105981189525579e+00), RES(1.4337901642794764055e-3, -1.9190337944739187231e0)}, {FN (sech), ARG(5.0e-01,-1.57045105981189525579e+00), RES(1.4337901642794764055e-3, 1.9190337944739187231e0)}, {FN (sech), ARG(-5.0e-01,1.57045105981189525579e+00), RES(1.4337901642794764055e-3, 1.9190337944739187231e0)}, {FN (sech), ARG(-5.0e-01,-1.57045105981189525579e+00), RES(1.4337901642794764055e-3, -1.9190337944739187231e0)}, {FN (sech), ARG(5.0e-01,1.57114159377789786021e+00), RES(-1.4337901642789678469e-3, -1.9190337944739187237e0)}, {FN (sech), ARG(5.0e-01,-1.57114159377789786021e+00), RES(-1.4337901642789678469e-3, 1.9190337944739187237e0)}, {FN (sech), ARG(-5.0e-01,1.57114159377789786021e+00), RES(-1.4337901642789678469e-3, 1.9190337944739187237e0)}, {FN (sech), ARG(-5.0e-01,-1.57114159377789786021e+00), RES(-1.4337901642789678469e-3, -1.9190337944739187237e0)}, {FN (sech), ARG(5.0e-01,3.14124738660679181379e+00), RES(-8.8681891425248302488e-1, -1.4149533035945625257e-4)}, {FN (sech), ARG(5.0e-01,-3.14124738660679181379e+00), RES(-8.8681891425248302488e-1, 1.4149533035945625257e-4)}, {FN (sech), ARG(-5.0e-01,3.14124738660679181379e+00), RES(-8.8681891425248302488e-1, 1.4149533035945625257e-4)}, {FN (sech), ARG(-5.0e-01,-3.14124738660679181379e+00), RES(-8.8681891425248302488e-1, -1.4149533035945625257e-4)}, {FN (sech), ARG(5.0e-01,3.14193792057279441821e+00), RES(-8.8681891425248302484e-1, 1.4149533035935587701e-4)}, {FN (sech), ARG(5.0e-01,-3.14193792057279441821e+00), RES(-8.8681891425248302484e-1, -1.4149533035935587701e-4)}, {FN (sech), ARG(-5.0e-01,3.14193792057279441821e+00), RES(-8.8681891425248302484e-1, -1.4149533035935587701e-4)}, {FN (sech), ARG(-5.0e-01,-3.14193792057279441821e+00), RES(-8.8681891425248302484e-1, 1.4149533035935587701e-4)}, {FN (sech), ARG(5.0e-01,4.71204371340168837179e+00), RES(-1.4337901642799849641e-3, 1.9190337944739187224e0)}, {FN (sech), ARG(5.0e-01,-4.71204371340168837179e+00), RES(-1.4337901642799849641e-3, -1.9190337944739187224e0)}, {FN (sech), ARG(-5.0e-01,4.71204371340168837179e+00), RES(-1.4337901642799849641e-3, -1.9190337944739187224e0)}, {FN (sech), ARG(-5.0e-01,-4.71204371340168837179e+00), RES(-1.4337901642799849641e-3, 1.9190337944739187224e0)}, {FN (sech), ARG(5.0e-01,4.71273424736769097620e+00), RES(1.4337901642784592884e-3, 1.9190337944739187244e0)}, {FN (sech), ARG(5.0e-01,-4.71273424736769097620e+00), RES(1.4337901642784592884e-3, -1.9190337944739187244e0)}, {FN (sech), ARG(-5.0e-01,4.71273424736769097620e+00), RES(1.4337901642784592884e-3, -1.9190337944739187244e0)}, {FN (sech), ARG(-5.0e-01,-4.71273424736769097620e+00), RES(1.4337901642784592884e-3, 1.9190337944739187244e0)}, {FN (sech), ARG(5.0e-01,6.28284004019658492979e+00), RES(8.8681891425248302490e-1, 1.4149533035950644034e-4)}, {FN (sech), ARG(5.0e-01,-6.28284004019658492979e+00), RES(8.8681891425248302490e-1, -1.4149533035950644034e-4)}, {FN (sech), ARG(-5.0e-01,6.28284004019658492979e+00), RES(8.8681891425248302490e-1, -1.4149533035950644034e-4)}, {FN (sech), ARG(-5.0e-01,-6.28284004019658492979e+00), RES(8.8681891425248302490e-1, 1.4149533035950644034e-4)}, {FN (sech), ARG(5.0e-01,6.28353057416258753420e+00), RES(8.8681891425248302482e-1, -1.4149533035930568923e-4)}, {FN (sech), ARG(5.0e-01,-6.28353057416258753420e+00), RES(8.8681891425248302482e-1, 1.4149533035930568923e-4)}, {FN (sech), ARG(-5.0e-01,6.28353057416258753420e+00), RES(8.8681891425248302482e-1, 1.4149533035930568923e-4)}, {FN (sech), ARG(-5.0e-01,-6.28353057416258753420e+00), RES(8.8681891425248302482e-1, -1.4149533035930568923e-4)}, {FN (sech), ARG(5.0e-01,9.42443269378637893396e+00), RES(-8.8681891425248302477e-1, -1.4149533035919263990e-4)}, {FN (sech), ARG(5.0e-01,-9.42443269378637893396e+00), RES(-8.8681891425248302477e-1, 1.4149533035919263990e-4)}, {FN (sech), ARG(-5.0e-01,9.42443269378637893396e+00), RES(-8.8681891425248302477e-1, 1.4149533035919263990e-4)}, {FN (sech), ARG(-5.0e-01,-9.42443269378637893396e+00), RES(-8.8681891425248302477e-1, -1.4149533035919263990e-4)}, {FN (sech), ARG(5.0e-01,9.42512322775237976202e+00), RES(-8.8681891425248302464e-1, 1.4149533035889151322e-4)}, {FN (sech), ARG(5.0e-01,-9.42512322775237976202e+00), RES(-8.8681891425248302464e-1, -1.4149533035889151322e-4)}, {FN (sech), ARG(-5.0e-01,9.42512322775237976202e+00), RES(-8.8681891425248302464e-1, -1.4149533035889151322e-4)}, {FN (sech), ARG(-5.0e-01,-9.42512322775237976202e+00), RES(-8.8681891425248302464e-1, 1.4149533035889151322e-4)}, {FN (sech), ARG(1.0e+00,-3.45266983001243932001e-04), RES(6.4805426748157480499e-1, 1.7040802567651502899e-4)}, {FN (sech), ARG(1.0e+00,3.45266983001243932001e-04), RES(6.4805426748157480499e-1, -1.7040802567651502899e-4)}, {FN (sech), ARG(-1.0e+00,-3.45266983001243932001e-04), RES(6.4805426748157480499e-1, -1.7040802567651502899e-4)}, {FN (sech), ARG(-1.0e+00,3.45266983001243932001e-04), RES(6.4805426748157480499e-1, 1.7040802567651502899e-4)}, {FN (sech), ARG(1.0e+00,1.57045105981189525579e+00), RES(3.8576176225212213388e-4, -8.5091800407377002725e-1)}, {FN (sech), ARG(1.0e+00,-1.57045105981189525579e+00), RES(3.8576176225212213388e-4, 8.5091800407377002725e-1)}, {FN (sech), ARG(-1.0e+00,1.57045105981189525579e+00), RES(3.8576176225212213388e-4, 8.5091800407377002725e-1)}, {FN (sech), ARG(-1.0e+00,-1.57045105981189525579e+00), RES(3.8576176225212213388e-4, -8.5091800407377002725e-1)}, {FN (sech), ARG(1.0e+00,1.57114159377789786021e+00), RES(-3.8576176225198530591e-4, -8.5091800407377002734e-1)}, {FN (sech), ARG(1.0e+00,-1.57114159377789786021e+00), RES(-3.8576176225198530591e-4, 8.5091800407377002734e-1)}, {FN (sech), ARG(-1.0e+00,1.57114159377789786021e+00), RES(-3.8576176225198530591e-4, 8.5091800407377002734e-1)}, {FN (sech), ARG(-1.0e+00,-1.57114159377789786021e+00), RES(-3.8576176225198530591e-4, -8.5091800407377002734e-1)}, {FN (sech), ARG(1.0e+00,3.14124738660679181379e+00), RES(-6.4805426748157480499e-1, -1.7040802567660423428e-4)}, {FN (sech), ARG(1.0e+00,-3.14124738660679181379e+00), RES(-6.4805426748157480499e-1, 1.7040802567660423428e-4)}, {FN (sech), ARG(-1.0e+00,3.14124738660679181379e+00), RES(-6.4805426748157480499e-1, 1.7040802567660423428e-4)}, {FN (sech), ARG(-1.0e+00,-3.14124738660679181379e+00), RES(-6.4805426748157480499e-1, -1.7040802567660423428e-4)}, {FN (sech), ARG(1.0e+00,3.14193792057279441821e+00), RES(-6.4805426748157480499e-1, 1.7040802567648334832e-4)}, {FN (sech), ARG(1.0e+00,-3.14193792057279441821e+00), RES(-6.4805426748157480499e-1, -1.7040802567648334832e-4)}, {FN (sech), ARG(-1.0e+00,3.14193792057279441821e+00), RES(-6.4805426748157480499e-1, -1.7040802567648334832e-4)}, {FN (sech), ARG(-1.0e+00,-3.14193792057279441821e+00), RES(-6.4805426748157480499e-1, 1.7040802567648334832e-4)}, {FN (sech), ARG(1.0e+00,4.71204371340168837179e+00), RES(-3.8576176225225896185e-4, 8.5091800407377002716e-1)}, {FN (sech), ARG(1.0e+00,-4.71204371340168837179e+00), RES(-3.8576176225225896185e-4, -8.5091800407377002716e-1)}, {FN (sech), ARG(-1.0e+00,4.71204371340168837179e+00), RES(-3.8576176225225896185e-4, -8.5091800407377002716e-1)}, {FN (sech), ARG(-1.0e+00,-4.71204371340168837179e+00), RES(-3.8576176225225896185e-4, 8.5091800407377002716e-1)}, {FN (sech), ARG(1.0e+00,4.71273424736769097620e+00), RES(3.8576176225184847794e-4, 8.5091800407377002743e-1)}, {FN (sech), ARG(1.0e+00,-4.71273424736769097620e+00), RES(3.8576176225184847794e-4, -8.5091800407377002743e-1)}, {FN (sech), ARG(-1.0e+00,4.71273424736769097620e+00), RES(3.8576176225184847794e-4, -8.5091800407377002743e-1)}, {FN (sech), ARG(-1.0e+00,-4.71273424736769097620e+00), RES(3.8576176225184847794e-4, 8.5091800407377002743e-1)}, {FN (sech), ARG(1.0e+00,6.28284004019658492979e+00), RES(6.4805426748157480498e-1, 1.7040802567666467726e-4)}, {FN (sech), ARG(1.0e+00,-6.28284004019658492979e+00), RES(6.4805426748157480498e-1, -1.7040802567666467726e-4)}, {FN (sech), ARG(-1.0e+00,6.28284004019658492979e+00), RES(6.4805426748157480498e-1, -1.7040802567666467726e-4)}, {FN (sech), ARG(-1.0e+00,-6.28284004019658492979e+00), RES(6.4805426748157480498e-1, 1.7040802567666467726e-4)}, {FN (sech), ARG(1.0e+00,6.28353057416258753420e+00), RES(6.480542674815748050e-1, -1.7040802567642290534e-4)}, {FN (sech), ARG(1.0e+00,-6.28353057416258753420e+00), RES(6.480542674815748050e-1, 1.7040802567642290534e-4)}, {FN (sech), ARG(-1.0e+00,6.28353057416258753420e+00), RES(6.480542674815748050e-1, 1.7040802567642290534e-4)}, {FN (sech), ARG(-1.0e+00,-6.28353057416258753420e+00), RES(6.480542674815748050e-1, -1.7040802567642290534e-4)}, {FN (sech), ARG(1.0e+00,9.42443269378637893396e+00), RES(-6.4805426748157480501e-1, -1.7040802567628675588e-4)}, {FN (sech), ARG(1.0e+00,-9.42443269378637893396e+00), RES(-6.4805426748157480501e-1, 1.7040802567628675588e-4)}, {FN (sech), ARG(-1.0e+00,9.42443269378637893396e+00), RES(-6.4805426748157480501e-1, 1.7040802567628675588e-4)}, {FN (sech), ARG(-1.0e+00,-9.42443269378637893396e+00), RES(-6.4805426748157480501e-1, -1.7040802567628675588e-4)}, {FN (sech), ARG(1.0e+00,9.42512322775237976202e+00), RES(-6.4805426748157480504e-1, 1.704080256759240980e-4)}, {FN (sech), ARG(1.0e+00,-9.42512322775237976202e+00), RES(-6.4805426748157480504e-1, -1.704080256759240980e-4)}, {FN (sech), ARG(-1.0e+00,9.42512322775237976202e+00), RES(-6.4805426748157480504e-1, -1.704080256759240980e-4)}, {FN (sech), ARG(-1.0e+00,-9.42512322775237976202e+00), RES(-6.4805426748157480504e-1, 1.704080256759240980e-4)}, {FN (sech), ARG(2.0e+00,-3.45266983001243932001e-04), RES(2.6580221522968095407e-1, 8.8471445300374010365e-5)}, {FN (sech), ARG(2.0e+00,3.45266983001243932001e-04), RES(2.6580221522968095407e-1, -8.8471445300374010365e-5)}, {FN (sech), ARG(-2.0e+00,-3.45266983001243932001e-04), RES(2.6580221522968095407e-1, -8.8471445300374010365e-5)}, {FN (sech), ARG(-2.0e+00,3.45266983001243932001e-04), RES(2.6580221522968095407e-1, 8.8471445300374010365e-5)}, {FN (sech), ARG(2.0e+00,1.57045105981189525579e+00), RES(9.8749461907069845806e-5, -2.7572054583883740767e-1)}, {FN (sech), ARG(2.0e+00,-1.57045105981189525579e+00), RES(9.8749461907069845806e-5, 2.7572054583883740767e-1)}, {FN (sech), ARG(-2.0e+00,1.57045105981189525579e+00), RES(9.8749461907069845806e-5, 2.7572054583883740767e-1)}, {FN (sech), ARG(-2.0e+00,-1.57045105981189525579e+00), RES(9.8749461907069845806e-5, -2.7572054583883740767e-1)}, {FN (sech), ARG(2.0e+00,1.57114159377789786021e+00), RES(-9.8749461907034819809e-5, -2.7572054583883740768e-1)}, {FN (sech), ARG(2.0e+00,-1.57114159377789786021e+00), RES(-9.8749461907034819809e-5, 2.7572054583883740768e-1)}, {FN (sech), ARG(-2.0e+00,1.57114159377789786021e+00), RES(-9.8749461907034819809e-5, 2.7572054583883740768e-1)}, {FN (sech), ARG(-2.0e+00,-1.57114159377789786021e+00), RES(-9.8749461907034819809e-5, -2.7572054583883740768e-1)}, {FN (sech), ARG(2.0e+00,3.14124738660679181379e+00), RES(-2.6580221522968095405e-1, -8.8471445300420323443e-5)}, {FN (sech), ARG(2.0e+00,-3.14124738660679181379e+00), RES(-2.6580221522968095405e-1, 8.8471445300420323443e-5)}, {FN (sech), ARG(-2.0e+00,3.14124738660679181379e+00), RES(-2.6580221522968095405e-1, 8.8471445300420323443e-5)}, {FN (sech), ARG(-2.0e+00,-3.14124738660679181379e+00), RES(-2.6580221522968095405e-1, -8.8471445300420323443e-5)}, {FN (sech), ARG(2.0e+00,3.14193792057279441821e+00), RES(-2.6580221522968095407e-1, 8.8471445300357562580e-5)}, {FN (sech), ARG(2.0e+00,-3.14193792057279441821e+00), RES(-2.6580221522968095407e-1, -8.8471445300357562580e-5)}, {FN (sech), ARG(-2.0e+00,3.14193792057279441821e+00), RES(-2.6580221522968095407e-1, -8.8471445300357562580e-5)}, {FN (sech), ARG(-2.0e+00,-3.14193792057279441821e+00), RES(-2.6580221522968095407e-1, 8.8471445300357562580e-5)}, {FN (sech), ARG(2.0e+00,4.71204371340168837179e+00), RES(-9.8749461907104871804e-5, 2.7572054583883740766e-1)}, {FN (sech), ARG(2.0e+00,-4.71204371340168837179e+00), RES(-9.8749461907104871804e-5, -2.7572054583883740766e-1)}, {FN (sech), ARG(-2.0e+00,4.71204371340168837179e+00), RES(-9.8749461907104871804e-5, -2.7572054583883740766e-1)}, {FN (sech), ARG(-2.0e+00,-4.71204371340168837179e+00), RES(-9.8749461907104871804e-5, 2.7572054583883740766e-1)}, {FN (sech), ARG(2.0e+00,4.71273424736769097620e+00), RES(9.8749461906999793811e-5, 2.7572054583883740770e-1)}, {FN (sech), ARG(2.0e+00,-4.71273424736769097620e+00), RES(9.8749461906999793811e-5, -2.7572054583883740770e-1)}, {FN (sech), ARG(-2.0e+00,4.71273424736769097620e+00), RES(9.8749461906999793811e-5, -2.7572054583883740770e-1)}, {FN (sech), ARG(-2.0e+00,-4.71273424736769097620e+00), RES(9.8749461906999793811e-5, 2.7572054583883740770e-1)}, {FN (sech), ARG(2.0e+00,6.28284004019658492979e+00), RES(2.6580221522968095404e-1, 8.8471445300451703875e-5)}, {FN (sech), ARG(2.0e+00,-6.28284004019658492979e+00), RES(2.6580221522968095404e-1, -8.8471445300451703875e-5)}, {FN (sech), ARG(-2.0e+00,6.28284004019658492979e+00), RES(2.6580221522968095404e-1, -8.8471445300451703875e-5)}, {FN (sech), ARG(-2.0e+00,-6.28284004019658492979e+00), RES(2.6580221522968095404e-1, 8.8471445300451703875e-5)}, {FN (sech), ARG(2.0e+00,6.28353057416258753420e+00), RES(2.6580221522968095408e-1, -8.8471445300326182148e-5)}, {FN (sech), ARG(2.0e+00,-6.28353057416258753420e+00), RES(2.6580221522968095408e-1, 8.8471445300326182148e-5)}, {FN (sech), ARG(-2.0e+00,6.28353057416258753420e+00), RES(2.6580221522968095408e-1, 8.8471445300326182148e-5)}, {FN (sech), ARG(-2.0e+00,-6.28353057416258753420e+00), RES(2.6580221522968095408e-1, -8.8471445300326182148e-5)}, {FN (sech), ARG(2.0e+00,9.42443269378637893396e+00), RES(-2.6580221522968095410e-1, -8.8471445300255496873e-5)}, {FN (sech), ARG(2.0e+00,-9.42443269378637893396e+00), RES(-2.6580221522968095410e-1, 8.8471445300255496873e-5)}, {FN (sech), ARG(-2.0e+00,9.42443269378637893396e+00), RES(-2.6580221522968095410e-1, 8.8471445300255496873e-5)}, {FN (sech), ARG(-2.0e+00,-9.42443269378637893396e+00), RES(-2.6580221522968095410e-1, -8.8471445300255496873e-5)}, {FN (sech), ARG(2.0e+00,9.42512322775237976202e+00), RES(-2.6580221522968095416e-1, 8.8471445300067214283e-5)}, {FN (sech), ARG(2.0e+00,-9.42512322775237976202e+00), RES(-2.6580221522968095416e-1, -8.8471445300067214283e-5)}, {FN (sech), ARG(-2.0e+00,9.42512322775237976202e+00), RES(-2.6580221522968095416e-1, -8.8471445300067214283e-5)}, {FN (sech), ARG(-2.0e+00,-9.42512322775237976202e+00), RES(-2.6580221522968095416e-1, 8.8471445300067214283e-5)}, {FN (coth), ARG(0.0e+00,-3.45266983001243932001e-04), RES(0, 2.8963092606511032136e3)}, {FN (coth), ARG(0.0e+00,3.45266983001243932001e-04), RES(0, -2.8963092606511032136e3)}, {FN (coth), ARG(0.0e+00,1.57045105981189525579e+00), RES(0, -3.4526699672104134407e-4)}, {FN (coth), ARG(0.0e+00,-1.57045105981189525579e+00), RES(0, 3.4526699672104134407e-4)}, {FN (coth), ARG(0.0e+00,1.57114159377789786021e+00), RES(0, 3.4526699672091887937e-4)}, {FN (coth), ARG(0.0e+00,-1.57114159377789786021e+00), RES(0, -3.4526699672091887937e-4)}, {FN (coth), ARG(0.0e+00,3.14124738660679181379e+00), RES(0, 2.8963092606495870519e3)}, {FN (coth), ARG(0.0e+00,-3.14124738660679181379e+00), RES(0, -2.8963092606495870519e3)}, {FN (coth), ARG(0.0e+00,3.14193792057279441821e+00), RES(0, -2.8963092606516416684e3)}, {FN (coth), ARG(0.0e+00,-3.14193792057279441821e+00), RES(0, 2.8963092606516416684e3)}, {FN (coth), ARG(0.0e+00,4.71204371340168837179e+00), RES(0, -3.4526699672116380876e-4)}, {FN (coth), ARG(0.0e+00,-4.71204371340168837179e+00), RES(0, 3.4526699672116380876e-4)}, {FN (coth), ARG(0.0e+00,4.71273424736769097620e+00), RES(0, 3.4526699672079641468e-4)}, {FN (coth), ARG(0.0e+00,-4.71273424736769097620e+00), RES(0, -3.4526699672079641468e-4)}, {FN (coth), ARG(0.0e+00,6.28284004019658492979e+00), RES(0, 2.8963092606485597437e3)}, {FN (coth), ARG(0.0e+00,-6.28284004019658492979e+00), RES(0, -2.8963092606485597437e3)}, {FN (coth), ARG(0.0e+00,6.28353057416258753420e+00), RES(0, -2.8963092606526689766e3)}, {FN (coth), ARG(0.0e+00,-6.28353057416258753420e+00), RES(0, 2.8963092606526689766e3)}, {FN (coth), ARG(0.0e+00,9.42443269378637893396e+00), RES(0, 2.8963092606549830163e3)}, {FN (coth), ARG(0.0e+00,-9.42443269378637893396e+00), RES(0, -2.8963092606549830163e3)}, {FN (coth), ARG(0.0e+00,9.42512322775237976202e+00), RES(0, -2.8963092606611468657e3)}, {FN (coth), ARG(0.0e+00,-9.42512322775237976202e+00), RES(0, 2.8963092606611468657e3)}, {FN (coth), ARG(1.19209289550781250e-07,-3.45266983001243932001e-04), RES(9.9999992052715532101e-1, 2.8963089153841613713e3)}, {FN (coth), ARG(1.19209289550781250e-07,3.45266983001243932001e-04), RES(9.9999992052715532101e-1, -2.8963089153841613713e3)}, {FN (coth), ARG(-1.19209289550781250e-07,-3.45266983001243932001e-04), RES(-9.9999992052715532101e-1, 2.8963089153841613713e3)}, {FN (coth), ARG(-1.19209289550781250e-07,3.45266983001243932001e-04), RES(-9.9999992052715532101e-1, -2.8963089153841613713e3)}, {FN (coth), ARG(1.19209289550781250e-07,1.57045105981189525579e+00), RES(1.1920930376163652990e-7, -3.4526699672103643753e-4)}, {FN (coth), ARG(1.19209289550781250e-07,-1.57045105981189525579e+00), RES(1.1920930376163652990e-7, 3.4526699672103643753e-4)}, {FN (coth), ARG(-1.19209289550781250e-07,1.57045105981189525579e+00), RES(-1.1920930376163652990e-7, -3.4526699672103643753e-4)}, {FN (coth), ARG(-1.19209289550781250e-07,-1.57045105981189525579e+00), RES(-1.1920930376163652990e-7, 3.4526699672103643753e-4)}, {FN (coth), ARG(1.19209289550781250e-07,1.57114159377789786021e+00), RES(1.1920930376163652989e-7, 3.4526699672091397283e-4)}, {FN (coth), ARG(1.19209289550781250e-07,-1.57114159377789786021e+00), RES(1.1920930376163652989e-7, -3.4526699672091397283e-4)}, {FN (coth), ARG(-1.19209289550781250e-07,1.57114159377789786021e+00), RES(-1.1920930376163652989e-7, 3.4526699672091397283e-4)}, {FN (coth), ARG(-1.19209289550781250e-07,-1.57114159377789786021e+00), RES(-1.1920930376163652989e-7, -3.4526699672091397283e-4)}, {FN (coth), ARG(1.19209289550781250e-07,3.14124738660679181379e+00), RES(9.9999992052610836018e-1, 2.8963089153826452102e3)}, {FN (coth), ARG(1.19209289550781250e-07,-3.14124738660679181379e+00), RES(9.9999992052610836018e-1, -2.8963089153826452102e3)}, {FN (coth), ARG(-1.19209289550781250e-07,3.14124738660679181379e+00), RES(-9.9999992052610836018e-1, 2.8963089153826452102e3)}, {FN (coth), ARG(-1.19209289550781250e-07,-3.14124738660679181379e+00), RES(-9.9999992052610836018e-1, -2.8963089153826452102e3)}, {FN (coth), ARG(1.19209289550781250e-07,3.14193792057279441821e+00), RES(9.9999992052752714224e-1, -2.8963089153846998260e3)}, {FN (coth), ARG(1.19209289550781250e-07,-3.14193792057279441821e+00), RES(9.9999992052752714224e-1, 2.8963089153846998260e3)}, {FN (coth), ARG(-1.19209289550781250e-07,3.14193792057279441821e+00), RES(-9.9999992052752714224e-1, -2.8963089153846998260e3)}, {FN (coth), ARG(-1.19209289550781250e-07,-3.14193792057279441821e+00), RES(-9.9999992052752714224e-1, 2.8963089153846998260e3)}, {FN (coth), ARG(1.19209289550781250e-07,4.71204371340168837179e+00), RES(1.1920930376163652991e-7, -3.4526699672115890222e-4)}, {FN (coth), ARG(1.19209289550781250e-07,-4.71204371340168837179e+00), RES(1.1920930376163652991e-7, 3.4526699672115890222e-4)}, {FN (coth), ARG(-1.19209289550781250e-07,4.71204371340168837179e+00), RES(-1.1920930376163652991e-7, -3.4526699672115890222e-4)}, {FN (coth), ARG(-1.19209289550781250e-07,-4.71204371340168837179e+00), RES(-1.1920930376163652991e-7, 3.4526699672115890222e-4)}, {FN (coth), ARG(1.19209289550781250e-07,4.71273424736769097620e+00), RES(1.1920930376163652988e-7, 3.4526699672079150814e-4)}, {FN (coth), ARG(1.19209289550781250e-07,-4.71273424736769097620e+00), RES(1.1920930376163652988e-7, -3.4526699672079150814e-4)}, {FN (coth), ARG(-1.19209289550781250e-07,4.71273424736769097620e+00), RES(-1.1920930376163652988e-7, 3.4526699672079150814e-4)}, {FN (coth), ARG(-1.19209289550781250e-07,-4.71273424736769097620e+00), RES(-1.1920930376163652988e-7, -3.4526699672079150814e-4)}, {FN (coth), ARG(1.19209289550781250e-07,6.28284004019658492979e+00), RES(9.9999992052539896914e-1, 2.8963089153816179024e3)}, {FN (coth), ARG(1.19209289550781250e-07,-6.28284004019658492979e+00), RES(9.9999992052539896914e-1, -2.8963089153816179024e3)}, {FN (coth), ARG(-1.19209289550781250e-07,6.28284004019658492979e+00), RES(-9.9999992052539896914e-1, 2.8963089153816179024e3)}, {FN (coth), ARG(-1.19209289550781250e-07,-6.28284004019658492979e+00), RES(-9.9999992052539896914e-1, -2.8963089153816179024e3)}, {FN (coth), ARG(1.19209289550781250e-07,6.28353057416258753420e+00), RES(9.9999992052823653327e-1, -2.8963089153857271338e3)}, {FN (coth), ARG(1.19209289550781250e-07,-6.28353057416258753420e+00), RES(9.9999992052823653327e-1, 2.8963089153857271338e3)}, {FN (coth), ARG(-1.19209289550781250e-07,6.28353057416258753420e+00), RES(-9.9999992052823653327e-1, -2.8963089153857271338e3)}, {FN (coth), ARG(-1.19209289550781250e-07,-6.28353057416258753420e+00), RES(-9.9999992052823653327e-1, 2.8963089153857271338e3)}, {FN (coth), ARG(1.19209289550781250e-07,9.42443269378637893396e+00), RES(9.9999992052983445585e-1, 2.8963089153880411727e3)}, {FN (coth), ARG(1.19209289550781250e-07,-9.42443269378637893396e+00), RES(9.9999992052983445585e-1, -2.8963089153880411727e3)}, {FN (coth), ARG(-1.19209289550781250e-07,9.42443269378637893396e+00), RES(-9.9999992052983445585e-1, 2.8963089153880411727e3)}, {FN (coth), ARG(-1.19209289550781250e-07,-9.42443269378637893396e+00), RES(-9.9999992052983445585e-1, -2.8963089153880411727e3)}, {FN (coth), ARG(1.19209289550781250e-07,9.42512322775237976202e+00), RES(9.9999992053409080205e-1, -2.8963089153942050199e3)}, {FN (coth), ARG(1.19209289550781250e-07,-9.42512322775237976202e+00), RES(9.9999992053409080205e-1, 2.8963089153942050199e3)}, {FN (coth), ARG(-1.19209289550781250e-07,9.42512322775237976202e+00), RES(-9.9999992053409080205e-1, -2.8963089153942050199e3)}, {FN (coth), ARG(-1.19209289550781250e-07,-9.42512322775237976202e+00), RES(-9.9999992053409080205e-1, 2.8963089153942050199e3)}, {FN (coth), ARG(5.0e-01,-3.45266983001243932001e-04), RES(2.1639524637389326002e0, 1.2715121175451222247e-3)}, {FN (coth), ARG(5.0e-01,3.45266983001243932001e-04), RES(2.1639524637389326002e0, -1.2715121175451222247e-3)}, {FN (coth), ARG(-5.0e-01,-3.45266983001243932001e-04), RES(-2.1639524637389326002e0, 1.2715121175451222247e-3)}, {FN (coth), ARG(-5.0e-01,3.45266983001243932001e-04), RES(-2.1639524637389326002e0, -1.2715121175451222247e-3)}, {FN (coth), ARG(5.0e-01,1.57045105981189525579e+00), RES(4.6211720058436229982e-1, -2.7153443992665204631e-4)}, {FN (coth), ARG(5.0e-01,-1.57045105981189525579e+00), RES(4.6211720058436229982e-1, 2.7153443992665204631e-4)}, {FN (coth), ARG(-5.0e-01,1.57045105981189525579e+00), RES(-4.6211720058436229982e-1, -2.7153443992665204631e-4)}, {FN (coth), ARG(-5.0e-01,-1.57045105981189525579e+00), RES(-4.6211720058436229982e-1, 2.7153443992665204631e-4)}, {FN (coth), ARG(5.0e-01,1.57114159377789786021e+00), RES(4.6211720058436229979e-1, 2.7153443992655573423e-4)}, {FN (coth), ARG(5.0e-01,-1.57114159377789786021e+00), RES(4.6211720058436229979e-1, -2.7153443992655573423e-4)}, {FN (coth), ARG(-5.0e-01,1.57114159377789786021e+00), RES(-4.6211720058436229979e-1, 2.7153443992655573423e-4)}, {FN (coth), ARG(-5.0e-01,-1.57114159377789786021e+00), RES(-4.6211720058436229979e-1, -2.7153443992655573423e-4)}, {FN (coth), ARG(5.0e-01,3.14124738660679181379e+00), RES(2.1639524637389325992e0, 1.2715121175457878359e-3)}, {FN (coth), ARG(5.0e-01,-3.14124738660679181379e+00), RES(2.1639524637389325992e0, -1.2715121175457878359e-3)}, {FN (coth), ARG(-5.0e-01,3.14124738660679181379e+00), RES(-2.1639524637389325992e0, 1.2715121175457878359e-3)}, {FN (coth), ARG(-5.0e-01,-3.14124738660679181379e+00), RES(-2.1639524637389325992e0, -1.2715121175457878359e-3)}, {FN (coth), ARG(5.0e-01,3.14193792057279441821e+00), RES(2.1639524637389326006e0, -1.2715121175448858373e-3)}, {FN (coth), ARG(5.0e-01,-3.14193792057279441821e+00), RES(2.1639524637389326006e0, 1.2715121175448858373e-3)}, {FN (coth), ARG(-5.0e-01,3.14193792057279441821e+00), RES(-2.1639524637389326006e0, -1.2715121175448858373e-3)}, {FN (coth), ARG(-5.0e-01,-3.14193792057279441821e+00), RES(-2.1639524637389326006e0, 1.2715121175448858373e-3)}, {FN (coth), ARG(5.0e-01,4.71204371340168837179e+00), RES(4.6211720058436229985e-1, -2.7153443992674835838e-4)}, {FN (coth), ARG(5.0e-01,-4.71204371340168837179e+00), RES(4.6211720058436229985e-1, 2.7153443992674835838e-4)}, {FN (coth), ARG(-5.0e-01,4.71204371340168837179e+00), RES(-4.6211720058436229985e-1, -2.7153443992674835838e-4)}, {FN (coth), ARG(-5.0e-01,-4.71204371340168837179e+00), RES(-4.6211720058436229985e-1, 2.7153443992674835838e-4)}, {FN (coth), ARG(5.0e-01,4.71273424736769097620e+00), RES(4.6211720058436229976e-1, 2.7153443992645942216e-4)}, {FN (coth), ARG(5.0e-01,-4.71273424736769097620e+00), RES(4.6211720058436229976e-1, -2.7153443992645942216e-4)}, {FN (coth), ARG(-5.0e-01,4.71273424736769097620e+00), RES(-4.6211720058436229976e-1, 2.7153443992645942216e-4)}, {FN (coth), ARG(-5.0e-01,-4.71273424736769097620e+00), RES(-4.6211720058436229976e-1, -2.7153443992645942216e-4)}, {FN (coth), ARG(5.0e-01,6.28284004019658492979e+00), RES(2.1639524637389325986e0, 1.2715121175462388352e-3)}, {FN (coth), ARG(5.0e-01,-6.28284004019658492979e+00), RES(2.1639524637389325986e0, -1.2715121175462388352e-3)}, {FN (coth), ARG(-5.0e-01,6.28284004019658492979e+00), RES(-2.1639524637389325986e0, 1.2715121175462388352e-3)}, {FN (coth), ARG(-5.0e-01,-6.28284004019658492979e+00), RES(-2.1639524637389325986e0, -1.2715121175462388352e-3)}, {FN (coth), ARG(5.0e-01,6.28353057416258753420e+00), RES(2.1639524637389326012e0, -1.2715121175444348380e-3)}, {FN (coth), ARG(5.0e-01,-6.28353057416258753420e+00), RES(2.1639524637389326012e0, 1.2715121175444348380e-3)}, {FN (coth), ARG(-5.0e-01,6.28353057416258753420e+00), RES(-2.1639524637389326012e0, -1.2715121175444348380e-3)}, {FN (coth), ARG(-5.0e-01,-6.28353057416258753420e+00), RES(-2.1639524637389326012e0, 1.2715121175444348380e-3)}, {FN (coth), ARG(5.0e-01,9.42443269378637893396e+00), RES(2.1639524637389326028e0, 1.2715121175434189499e-3)}, {FN (coth), ARG(5.0e-01,-9.42443269378637893396e+00), RES(2.1639524637389326028e0, -1.2715121175434189499e-3)}, {FN (coth), ARG(-5.0e-01,9.42443269378637893396e+00), RES(-2.1639524637389326028e0, 1.2715121175434189499e-3)}, {FN (coth), ARG(-5.0e-01,-9.42443269378637893396e+00), RES(-2.1639524637389326028e0, -1.2715121175434189499e-3)}, {FN (coth), ARG(5.0e-01,9.42512322775237976202e+00), RES(2.1639524637389326068e0, -1.2715121175407129542e-3)}, {FN (coth), ARG(5.0e-01,-9.42512322775237976202e+00), RES(2.1639524637389326068e0, 1.2715121175407129542e-3)}, {FN (coth), ARG(-5.0e-01,9.42512322775237976202e+00), RES(-2.1639524637389326068e0, -1.2715121175407129542e-3)}, {FN (coth), ARG(-5.0e-01,-9.42512322775237976202e+00), RES(-2.1639524637389326068e0, 1.2715121175407129542e-3)}, {FN (coth), ARG(1.0e+00,-3.45266983001243932001e-04), RES(1.3130351721648674824e0, 2.4999454374267620687e-4)}, {FN (coth), ARG(1.0e+00,3.45266983001243932001e-04), RES(1.3130351721648674824e0, -2.4999454374267620687e-4)}, {FN (coth), ARG(-1.0e+00,-3.45266983001243932001e-04), RES(-1.3130351721648674824e0, 2.4999454374267620687e-4)}, {FN (coth), ARG(-1.0e+00,3.45266983001243932001e-04), RES(-1.3130351721648674824e0, -2.4999454374267620687e-4)}, {FN (coth), ARG(1.0e+00,1.57045105981189525579e+00), RES(7.6159419408485704839e-1, -1.4500326960279979918e-4)}, {FN (coth), ARG(1.0e+00,-1.57045105981189525579e+00), RES(7.6159419408485704839e-1, 1.4500326960279979918e-4)}, {FN (coth), ARG(-1.0e+00,1.57045105981189525579e+00), RES(-7.6159419408485704839e-1, -1.4500326960279979918e-4)}, {FN (coth), ARG(-1.0e+00,-1.57045105981189525579e+00), RES(-7.6159419408485704839e-1, 1.4500326960279979918e-4)}, {FN (coth), ARG(1.0e+00,1.57114159377789786021e+00), RES(7.6159419408485704836e-1, 1.4500326960274836716e-4)}, {FN (coth), ARG(1.0e+00,-1.57114159377789786021e+00), RES(7.6159419408485704836e-1, -1.4500326960274836716e-4)}, {FN (coth), ARG(-1.0e+00,1.57114159377789786021e+00), RES(-7.6159419408485704836e-1, 1.4500326960274836716e-4)}, {FN (coth), ARG(-1.0e+00,-1.57114159377789786021e+00), RES(-7.6159419408485704836e-1, -1.4500326960274836716e-4)}, {FN (coth), ARG(1.0e+00,3.14124738660679181379e+00), RES(1.3130351721648674823e0, 2.4999454374280707411e-4)}, {FN (coth), ARG(1.0e+00,-3.14124738660679181379e+00), RES(1.3130351721648674823e0, -2.4999454374280707411e-4)}, {FN (coth), ARG(-1.0e+00,3.14124738660679181379e+00), RES(-1.3130351721648674823e0, 2.4999454374280707411e-4)}, {FN (coth), ARG(-1.0e+00,-3.14124738660679181379e+00), RES(-1.3130351721648674823e0, -2.4999454374280707411e-4)}, {FN (coth), ARG(1.0e+00,3.14193792057279441821e+00), RES(1.3130351721648674824e0, -2.4999454374262973024e-4)}, {FN (coth), ARG(1.0e+00,-3.14193792057279441821e+00), RES(1.3130351721648674824e0, 2.4999454374262973024e-4)}, {FN (coth), ARG(-1.0e+00,3.14193792057279441821e+00), RES(-1.3130351721648674824e0, -2.4999454374262973024e-4)}, {FN (coth), ARG(-1.0e+00,-3.14193792057279441821e+00), RES(-1.3130351721648674824e0, 2.4999454374262973024e-4)}, {FN (coth), ARG(1.0e+00,4.71204371340168837179e+00), RES(7.6159419408485704842e-1, -1.4500326960285123120e-4)}, {FN (coth), ARG(1.0e+00,-4.71204371340168837179e+00), RES(7.6159419408485704842e-1, 1.4500326960285123120e-4)}, {FN (coth), ARG(-1.0e+00,4.71204371340168837179e+00), RES(-7.6159419408485704842e-1, -1.4500326960285123120e-4)}, {FN (coth), ARG(-1.0e+00,-4.71204371340168837179e+00), RES(-7.6159419408485704842e-1, 1.4500326960285123120e-4)}, {FN (coth), ARG(1.0e+00,4.71273424736769097620e+00), RES(7.6159419408485704834e-1, 1.4500326960269693514e-4)}, {FN (coth), ARG(1.0e+00,-4.71273424736769097620e+00), RES(7.6159419408485704834e-1, -1.4500326960269693514e-4)}, {FN (coth), ARG(-1.0e+00,4.71273424736769097620e+00), RES(-7.6159419408485704834e-1, 1.4500326960269693514e-4)}, {FN (coth), ARG(-1.0e+00,-4.71273424736769097620e+00), RES(-7.6159419408485704834e-1, -1.4500326960269693514e-4)}, {FN (coth), ARG(1.0e+00,6.28284004019658492979e+00), RES(1.3130351721648674822e0, 2.4999454374289574604e-4)}, {FN (coth), ARG(1.0e+00,-6.28284004019658492979e+00), RES(1.3130351721648674822e0, -2.4999454374289574604e-4)}, {FN (coth), ARG(-1.0e+00,6.28284004019658492979e+00), RES(-1.3130351721648674822e0, 2.4999454374289574604e-4)}, {FN (coth), ARG(-1.0e+00,-6.28284004019658492979e+00), RES(-1.3130351721648674822e0, -2.4999454374289574604e-4)}, {FN (coth), ARG(1.0e+00,6.28353057416258753420e+00), RES(1.3130351721648674825e0, -2.4999454374254105830e-4)}, {FN (coth), ARG(1.0e+00,-6.28353057416258753420e+00), RES(1.3130351721648674825e0, 2.4999454374254105830e-4)}, {FN (coth), ARG(-1.0e+00,6.28353057416258753420e+00), RES(-1.3130351721648674825e0, -2.4999454374254105830e-4)}, {FN (coth), ARG(-1.0e+00,-6.28353057416258753420e+00), RES(-1.3130351721648674825e0, 2.4999454374254105830e-4)}, {FN (coth), ARG(1.0e+00,9.42443269378637893396e+00), RES(1.3130351721648674827e0, 2.4999454374234132236e-4)}, {FN (coth), ARG(1.0e+00,-9.42443269378637893396e+00), RES(1.3130351721648674827e0, -2.4999454374234132236e-4)}, {FN (coth), ARG(-1.0e+00,9.42443269378637893396e+00), RES(-1.3130351721648674827e0, 2.4999454374234132236e-4)}, {FN (coth), ARG(-1.0e+00,-9.42443269378637893396e+00), RES(-1.3130351721648674827e0, -2.4999454374234132236e-4)}, {FN (coth), ARG(1.0e+00,9.42512322775237976202e+00), RES(1.3130351721648674832e0, -2.4999454374180929074e-4)}, {FN (coth), ARG(1.0e+00,-9.42512322775237976202e+00), RES(1.3130351721648674832e0, 2.4999454374180929074e-4)}, {FN (coth), ARG(-1.0e+00,9.42512322775237976202e+00), RES(-1.3130351721648674832e0, -2.4999454374180929074e-4)}, {FN (coth), ARG(-1.0e+00,-9.42512322775237976202e+00), RES(-1.3130351721648674832e0, 2.4999454374180929074e-4)}, {FN (coth), ARG(2.0e+00,-3.45266983001243932001e-04), RES(1.0373147113268752620e0, 2.6247825506563736365e-5)}, {FN (coth), ARG(2.0e+00,3.45266983001243932001e-04), RES(1.0373147113268752620e0, -2.6247825506563736365e-5)}, {FN (coth), ARG(-2.0e+00,-3.45266983001243932001e-04), RES(-1.0373147113268752620e0, 2.6247825506563736365e-5)}, {FN (coth), ARG(-2.0e+00,3.45266983001243932001e-04), RES(-1.0373147113268752620e0, -2.6247825506563736365e-5)}, {FN (coth), ARG(2.0e+00,1.57045105981189525579e+00), RES(9.6402758819508310557e-1, -2.4393395410443750226e-5)}, {FN (coth), ARG(2.0e+00,-1.57045105981189525579e+00), RES(9.6402758819508310557e-1, 2.4393395410443750226e-5)}, {FN (coth), ARG(-2.0e+00,1.57045105981189525579e+00), RES(-9.6402758819508310557e-1, -2.4393395410443750226e-5)}, {FN (coth), ARG(-2.0e+00,-1.57045105981189525579e+00), RES(-9.6402758819508310557e-1, 2.4393395410443750226e-5)}, {FN (coth), ARG(2.0e+00,1.57114159377789786021e+00), RES(9.6402758819508310556e-1, 2.4393395410435097997e-5)}, {FN (coth), ARG(2.0e+00,-1.57114159377789786021e+00), RES(9.6402758819508310556e-1, -2.4393395410435097997e-5)}, {FN (coth), ARG(-2.0e+00,1.57114159377789786021e+00), RES(-9.6402758819508310556e-1, 2.4393395410435097997e-5)}, {FN (coth), ARG(-2.0e+00,-1.57114159377789786021e+00), RES(-9.6402758819508310556e-1, -2.4393395410435097997e-5)}, {FN (coth), ARG(2.0e+00,3.14124738660679181379e+00), RES(1.0373147113268752620e0, 2.6247825506577476589e-5)}, {FN (coth), ARG(2.0e+00,-3.14124738660679181379e+00), RES(1.0373147113268752620e0, -2.6247825506577476589e-5)}, {FN (coth), ARG(-2.0e+00,3.14124738660679181379e+00), RES(-1.0373147113268752620e0, 2.6247825506577476589e-5)}, {FN (coth), ARG(-2.0e+00,-3.14124738660679181379e+00), RES(-1.0373147113268752620e0, -2.6247825506577476589e-5)}, {FN (coth), ARG(2.0e+00,3.14193792057279441821e+00), RES(1.0373147113268752620e0, -2.6247825506558856616e-5)}, {FN (coth), ARG(2.0e+00,-3.14193792057279441821e+00), RES(1.0373147113268752620e0, 2.6247825506558856616e-5)}, {FN (coth), ARG(-2.0e+00,3.14193792057279441821e+00), RES(-1.0373147113268752620e0, -2.6247825506558856616e-5)}, {FN (coth), ARG(-2.0e+00,-3.14193792057279441821e+00), RES(-1.0373147113268752620e0, 2.6247825506558856616e-5)}, {FN (coth), ARG(2.0e+00,4.71204371340168837179e+00), RES(9.6402758819508310557e-1, -2.4393395410452402454e-5)}, {FN (coth), ARG(2.0e+00,-4.71204371340168837179e+00), RES(9.6402758819508310557e-1, 2.4393395410452402454e-5)}, {FN (coth), ARG(-2.0e+00,4.71204371340168837179e+00), RES(-9.6402758819508310557e-1, -2.4393395410452402454e-5)}, {FN (coth), ARG(-2.0e+00,-4.71204371340168837179e+00), RES(-9.6402758819508310557e-1, 2.4393395410452402454e-5)}, {FN (coth), ARG(2.0e+00,4.71273424736769097620e+00), RES(9.6402758819508310556e-1, 2.4393395410426445768e-5)}, {FN (coth), ARG(2.0e+00,-4.71273424736769097620e+00), RES(9.6402758819508310556e-1, -2.4393395410426445768e-5)}, {FN (coth), ARG(-2.0e+00,4.71273424736769097620e+00), RES(-9.6402758819508310556e-1, 2.4393395410426445768e-5)}, {FN (coth), ARG(-2.0e+00,-4.71273424736769097620e+00), RES(-9.6402758819508310556e-1, -2.4393395410426445768e-5)}, {FN (coth), ARG(2.0e+00,6.28284004019658492979e+00), RES(1.0373147113268752620e0, 2.6247825506586786575e-5)}, {FN (coth), ARG(2.0e+00,-6.28284004019658492979e+00), RES(1.0373147113268752620e0, -2.6247825506586786575e-5)}, {FN (coth), ARG(-2.0e+00,6.28284004019658492979e+00), RES(-1.0373147113268752620e0, 2.6247825506586786575e-5)}, {FN (coth), ARG(-2.0e+00,-6.28284004019658492979e+00), RES(-1.0373147113268752620e0, -2.6247825506586786575e-5)}, {FN (coth), ARG(2.0e+00,6.28353057416258753420e+00), RES(1.0373147113268752620e0, -2.6247825506549546629e-5)}, {FN (coth), ARG(2.0e+00,-6.28353057416258753420e+00), RES(1.0373147113268752620e0, 2.6247825506549546629e-5)}, {FN (coth), ARG(-2.0e+00,6.28353057416258753420e+00), RES(-1.0373147113268752620e0, -2.6247825506549546629e-5)}, {FN (coth), ARG(-2.0e+00,-6.28353057416258753420e+00), RES(-1.0373147113268752620e0, 2.6247825506549546629e-5)}, {FN (coth), ARG(2.0e+00,9.42443269378637893396e+00), RES(1.0373147113268752620e0, 2.6247825506528575631e-5)}, {FN (coth), ARG(2.0e+00,-9.42443269378637893396e+00), RES(1.0373147113268752620e0, -2.6247825506528575631e-5)}, {FN (coth), ARG(-2.0e+00,9.42443269378637893396e+00), RES(-1.0373147113268752620e0, 2.6247825506528575631e-5)}, {FN (coth), ARG(-2.0e+00,-9.42443269378637893396e+00), RES(-1.0373147113268752620e0, -2.6247825506528575631e-5)}, {FN (coth), ARG(2.0e+00,9.42512322775237976202e+00), RES(1.0373147113268752621e0, -2.6247825506472715712e-5)}, {FN (coth), ARG(2.0e+00,-9.42512322775237976202e+00), RES(1.0373147113268752621e0, 2.6247825506472715712e-5)}, {FN (coth), ARG(-2.0e+00,9.42512322775237976202e+00), RES(-1.0373147113268752621e0, -2.6247825506472715712e-5)}, {FN (coth), ARG(-2.0e+00,-9.42512322775237976202e+00), RES(-1.0373147113268752621e0, 2.6247825506472715712e-5)}, {FN (arccsch), ARG(0.0e+00,1.19209289550781250e-07), RES(-1.6635532333438683873e1, -1.5707963267948966192e0)}, {FN (arccsch), ARG(0.0e+00,-1.19209289550781250e-07), RES(1.6635532333438683873e1, 1.5707963267948966192e0)}, {FN (arccsch), ARG(0.0e+00,5.0e-01), RES(-1.3169578969248167086e0, -1.5707963267948966192e0)}, {FN (arccsch), ARG(0.0e+00,-5.0e-01), RES(1.3169578969248167086e0, 1.5707963267948966192e0)}, {FN (arccsch), ARG(0.0e+00,1.0e+00), RES(0, -1.5707963267948966192e0)}, {FN (arccsch), ARG(0.0e+00,-1.0e+00), RES(0, 1.5707963267948966192e0)}, {FN (arccsch), ARG(0.0e+00,2.0e+00), RES(0, -5.2359877559829887308e-1)}, {FN (arccsch), ARG(0.0e+00,-2.0e+00), RES(0, 5.2359877559829887308e-1)}, {FN (arccsch), ARG(0.0e+00,8.3886080e+06), RES(0, -1.1920928955078153234e-7)}, {FN (arccsch), ARG(0.0e+00,-8.3886080e+06), RES(0, 1.1920928955078153234e-7)}, {FN (arccsch), ARG(1.19209289550781250e-07,0.0e+00), RES(1.6635532333438690979e1, 0.0)}, {FN (arccsch), ARG(-1.19209289550781250e-07,0.0e+00), RES(-1.6635532333438690979e1, 0.0)}, {FN (arccsch), ARG(1.19209289550781250e-07,1.19209289550781250e-07), RES(1.6288958743158714771e1, -7.8539816339744120419e-1)}, {FN (arccsch), ARG(1.19209289550781250e-07,-1.19209289550781250e-07), RES(1.6288958743158714771e1, 7.8539816339744120419e-1)}, {FN (arccsch), ARG(-1.19209289550781250e-07,1.19209289550781250e-07), RES(-1.6288958743158714771e1, -7.8539816339744120419e-1)}, {FN (arccsch), ARG(-1.19209289550781250e-07,-1.19209289550781250e-07), RES(-1.6288958743158714771e1, 7.8539816339744120419e-1)}, {FN (arccsch), ARG(1.19209289550781250e-07,5.0e-01), RES(1.3169578969247948296e0, -1.5707960514928349710e0)}, {FN (arccsch), ARG(1.19209289550781250e-07,-5.0e-01), RES(1.3169578969247948296e0, 1.5707960514928349710e0)}, {FN (arccsch), ARG(-1.19209289550781250e-07,5.0e-01), RES(-1.3169578969247948296e0, -1.5707960514928349710e0)}, {FN (arccsch), ARG(-1.19209289550781250e-07,-5.0e-01), RES(-1.3169578969247948296e0, 1.5707960514928349710e0)}, {FN (arccsch), ARG(1.19209289550781250e-07,1.0e+00), RES(3.4526696585164602772e-4, -1.5704510597947457801e0)}, {FN (arccsch), ARG(1.19209289550781250e-07,-1.0e+00), RES(3.4526696585164602772e-4, 1.5704510597947457801e0)}, {FN (arccsch), ARG(-1.19209289550781250e-07,1.0e+00), RES(-3.4526696585164602772e-4, -1.5704510597947457801e0)}, {FN (arccsch), ARG(-1.19209289550781250e-07,-1.0e+00), RES(-3.4526696585164602772e-4, 1.5704510597947457801e0)}, {FN (arccsch), ARG(1.19209289550781250e-07,2.0e+00), RES(3.4412757706023621662e-8, -5.2359877559829648006e-1)}, {FN (arccsch), ARG(1.19209289550781250e-07,-2.0e+00), RES(3.4412757706023621662e-8, 5.2359877559829648006e-1)}, {FN (arccsch), ARG(-1.19209289550781250e-07,2.0e+00), RES(-3.4412757706023621662e-8, -5.2359877559829648006e-1)}, {FN (arccsch), ARG(-1.19209289550781250e-07,-2.0e+00), RES(-3.4412757706023621662e-8, 5.2359877559829648006e-1)}, {FN (arccsch), ARG(1.19209289550781250e-07,8.3886080e+06), RES(1.6940658945086127152e-21, -1.1920928955078153234e-7)}, {FN (arccsch), ARG(1.19209289550781250e-07,-8.3886080e+06), RES(1.6940658945086127152e-21, 1.1920928955078153234e-7)}, {FN (arccsch), ARG(-1.19209289550781250e-07,8.3886080e+06), RES(-1.6940658945086127152e-21, -1.1920928955078153234e-7)}, {FN (arccsch), ARG(-1.19209289550781250e-07,-8.3886080e+06), RES(-1.6940658945086127152e-21, 1.1920928955078153234e-7)}, {FN (arccsch), ARG(5.0e-01,0.0e+00), RES(1.4436354751788103425e0, 0.0)}, {FN (arccsch), ARG(-5.0e-01,0.0e+00), RES(-1.4436354751788103425e0, 0.0)}, {FN (arccsch), ARG(5.0e-01,1.19209289550781250e-07), RES(1.4436354751787798371e0, -2.1324805998799710740e-7)}, {FN (arccsch), ARG(5.0e-01,-1.19209289550781250e-07), RES(1.4436354751787798371e0, 2.1324805998799710740e-7)}, {FN (arccsch), ARG(-5.0e-01,1.19209289550781250e-07), RES(-1.4436354751787798371e0, -2.1324805998799710740e-7)}, {FN (arccsch), ARG(-5.0e-01,-1.19209289550781250e-07), RES(-1.4436354751787798371e0, 2.1324805998799710740e-7)}, {FN (arccsch), ARG(5.0e-01,5.0e-01), RES(1.0612750619050356520e0, -6.6623943249251525510e-1)}, {FN (arccsch), ARG(5.0e-01,-5.0e-01), RES(1.0612750619050356520e0, 6.6623943249251525510e-1)}, {FN (arccsch), ARG(-5.0e-01,5.0e-01), RES(-1.0612750619050356520e0, -6.6623943249251525510e-1)}, {FN (arccsch), ARG(-5.0e-01,-5.0e-01), RES(-1.0612750619050356520e0, 6.6623943249251525510e-1)}, {FN (arccsch), ARG(5.0e-01,1.0e+00), RES(5.3321829058411214108e-1, -7.7308635671950473342e-1)}, {FN (arccsch), ARG(5.0e-01,-1.0e+00), RES(5.3321829058411214108e-1, 7.7308635671950473342e-1)}, {FN (arccsch), ARG(-5.0e-01,1.0e+00), RES(-5.3321829058411214108e-1, -7.7308635671950473342e-1)}, {FN (arccsch), ARG(-5.0e-01,-1.0e+00), RES(-5.3321829058411214108e-1, 7.7308635671950473342e-1)}, {FN (arccsch), ARG(5.0e-01,2.0e+00), RES(1.3261586085051183885e-1, -4.8530734047334251250e-1)}, {FN (arccsch), ARG(5.0e-01,-2.0e+00), RES(1.3261586085051183885e-1, 4.8530734047334251250e-1)}, {FN (arccsch), ARG(-5.0e-01,2.0e+00), RES(-1.3261586085051183885e-1, -4.8530734047334251250e-1)}, {FN (arccsch), ARG(-5.0e-01,-2.0e+00), RES(-1.3261586085051183885e-1, 4.8530734047334251250e-1)}, {FN (arccsch), ARG(5.0e-01,8.3886080e+06), RES(7.1054273576010271023e-15, -1.1920928955078110883e-7)}, {FN (arccsch), ARG(5.0e-01,-8.3886080e+06), RES(7.1054273576010271023e-15, 1.1920928955078110883e-7)}, {FN (arccsch), ARG(-5.0e-01,8.3886080e+06), RES(-7.1054273576010271023e-15, -1.1920928955078110883e-7)}, {FN (arccsch), ARG(-5.0e-01,-8.3886080e+06), RES(-7.1054273576010271023e-15, 1.1920928955078110883e-7)}, {FN (arccsch), ARG(1.0e+00,0.0e+00), RES(8.8137358701954302523e-1, 0.0)}, {FN (arccsch), ARG(-1.0e+00,0.0e+00), RES(-8.8137358701954302523e-1, 0.0)}, {FN (arccsch), ARG(1.0e+00,1.19209289550781250e-07), RES(8.8137358701953548879e-1, -8.4293697021787414719e-8)}, {FN (arccsch), ARG(1.0e+00,-1.19209289550781250e-07), RES(8.8137358701953548879e-1, 8.4293697021787414719e-8)}, {FN (arccsch), ARG(-1.0e+00,1.19209289550781250e-07), RES(-8.8137358701953548879e-1, -8.4293697021787414719e-8)}, {FN (arccsch), ARG(-1.0e+00,-1.19209289550781250e-07), RES(-8.8137358701953548879e-1, 8.4293697021787414719e-8)}, {FN (arccsch), ARG(1.0e+00,5.0e-01), RES(7.6388434595371104541e-1, -3.1122579724476109533e-1)}, {FN (arccsch), ARG(1.0e+00,-5.0e-01), RES(7.6388434595371104541e-1, 3.1122579724476109533e-1)}, {FN (arccsch), ARG(-1.0e+00,5.0e-01), RES(-7.6388434595371104541e-1, -3.1122579724476109533e-1)}, {FN (arccsch), ARG(-1.0e+00,-5.0e-01), RES(-7.6388434595371104541e-1, 3.1122579724476109533e-1)}, {FN (arccsch), ARG(1.0e+00,1.0e+00), RES(5.3063753095251782602e-1, -4.5227844715119068206e-1)}, {FN (arccsch), ARG(1.0e+00,-1.0e+00), RES(5.3063753095251782602e-1, 4.5227844715119068206e-1)}, {FN (arccsch), ARG(-1.0e+00,1.0e+00), RES(-5.3063753095251782602e-1, -4.5227844715119068206e-1)}, {FN (arccsch), ARG(-1.0e+00,-1.0e+00), RES(-5.3063753095251782602e-1, 4.5227844715119068206e-1)}, {FN (arccsch), ARG(1.0e+00,2.0e+00), RES(2.1561241855582964497e-1, -4.0158639166780606828e-1)}, {FN (arccsch), ARG(1.0e+00,-2.0e+00), RES(2.1561241855582964497e-1, 4.0158639166780606828e-1)}, {FN (arccsch), ARG(-1.0e+00,2.0e+00), RES(-2.1561241855582964497e-1, -4.0158639166780606828e-1)}, {FN (arccsch), ARG(-1.0e+00,-2.0e+00), RES(-2.1561241855582964497e-1, 4.0158639166780606828e-1)}, {FN (arccsch), ARG(1.0e+00,8.3886080e+06), RES(1.4210854715201902743e-14, -1.1920928955077983828e-7)}, {FN (arccsch), ARG(1.0e+00,-8.3886080e+06), RES(1.4210854715201902743e-14, 1.1920928955077983828e-7)}, {FN (arccsch), ARG(-1.0e+00,8.3886080e+06), RES(-1.4210854715201902743e-14, -1.1920928955077983828e-7)}, {FN (arccsch), ARG(-1.0e+00,-8.3886080e+06), RES(-1.4210854715201902743e-14, 1.1920928955077983828e-7)}, {FN (arccsch), ARG(2.0e+00,0.0e+00), RES(4.8121182505960344750e-1, 0.0)}, {FN (arccsch), ARG(-2.0e+00,0.0e+00), RES(-4.8121182505960344750e-1, 0.0)}, {FN (arccsch), ARG(2.0e+00,1.19209289550781250e-07), RES(4.8121182505960201756e-1, -2.6656007498500149811e-8)}, {FN (arccsch), ARG(2.0e+00,-1.19209289550781250e-07), RES(4.8121182505960201756e-1, 2.6656007498500149811e-8)}, {FN (arccsch), ARG(-2.0e+00,1.19209289550781250e-07), RES(-4.8121182505960201756e-1, -2.6656007498500149811e-8)}, {FN (arccsch), ARG(-2.0e+00,-1.19209289550781250e-07), RES(-4.8121182505960201756e-1, 2.6656007498500149811e-8)}, {FN (arccsch), ARG(2.0e+00,5.0e-01), RES(4.5717847686917515748e-1, -1.0654050295275703990e-1)}, {FN (arccsch), ARG(2.0e+00,-5.0e-01), RES(4.5717847686917515748e-1, 1.0654050295275703990e-1)}, {FN (arccsch), ARG(-2.0e+00,5.0e-01), RES(-4.5717847686917515748e-1, -1.0654050295275703990e-1)}, {FN (arccsch), ARG(-2.0e+00,-5.0e-01), RES(-4.5717847686917515748e-1, 1.0654050295275703990e-1)}, {FN (arccsch), ARG(2.0e+00,1.0e+00), RES(3.9656823011232897892e-1, -1.8631805410781552582e-1)}, {FN (arccsch), ARG(2.0e+00,-1.0e+00), RES(3.9656823011232897892e-1, 1.8631805410781552582e-1)}, {FN (arccsch), ARG(-2.0e+00,1.0e+00), RES(-3.9656823011232897892e-1, -1.8631805410781552582e-1)}, {FN (arccsch), ARG(-2.0e+00,-1.0e+00), RES(-3.9656823011232897892e-1, 1.8631805410781552582e-1)}, {FN (arccsch), ARG(2.0e+00,2.0e+00), RES(2.5489557334055081773e-1, -2.4452216513554014646e-1)}, {FN (arccsch), ARG(2.0e+00,-2.0e+00), RES(2.5489557334055081773e-1, 2.4452216513554014646e-1)}, {FN (arccsch), ARG(-2.0e+00,2.0e+00), RES(-2.5489557334055081773e-1, -2.4452216513554014646e-1)}, {FN (arccsch), ARG(-2.0e+00,-2.0e+00), RES(-2.5489557334055081773e-1, 2.4452216513554014646e-1)}, {FN (arccsch), ARG(2.0e+00,8.3886080e+06), RES(2.8421709430402593796e-14, -1.1920928955077475608e-7)}, {FN (arccsch), ARG(2.0e+00,-8.3886080e+06), RES(2.8421709430402593796e-14, 1.1920928955077475608e-7)}, {FN (arccsch), ARG(-2.0e+00,8.3886080e+06), RES(-2.8421709430402593796e-14, -1.1920928955077475608e-7)}, {FN (arccsch), ARG(-2.0e+00,-8.3886080e+06), RES(-2.8421709430402593796e-14, 1.1920928955077475608e-7)}, {FN (arccsch), ARG(8.3886080e+06,0.0e+00), RES(1.1920928955078096766e-7, 0.0)}, {FN (arccsch), ARG(-8.3886080e+06,0.0e+00), RES(-1.1920928955078096766e-7, 0.0)}, {FN (arccsch), ARG(8.3886080e+06,1.19209289550781250e-07), RES(1.1920928955078096766e-7, -1.6940658945085886411e-21)}, {FN (arccsch), ARG(8.3886080e+06,-1.19209289550781250e-07), RES(1.1920928955078096766e-7, 1.6940658945085886411e-21)}, {FN (arccsch), ARG(-8.3886080e+06,1.19209289550781250e-07), RES(-1.1920928955078096766e-7, -1.6940658945085886411e-21)}, {FN (arccsch), ARG(-8.3886080e+06,-1.19209289550781250e-07), RES(-1.1920928955078096766e-7, 1.6940658945085886411e-21)}, {FN (arccsch), ARG(8.3886080e+06,5.0e-01), RES(1.1920928955078054414e-7, -7.1054273576009261281e-15)}, {FN (arccsch), ARG(8.3886080e+06,-5.0e-01), RES(1.1920928955078054414e-7, 7.1054273576009261281e-15)}, {FN (arccsch), ARG(-8.3886080e+06,5.0e-01), RES(-1.1920928955078054414e-7, -7.1054273576009261281e-15)}, {FN (arccsch), ARG(-8.3886080e+06,-5.0e-01), RES(-1.1920928955078054414e-7, 7.1054273576009261281e-15)}, {FN (arccsch), ARG(8.3886080e+06,1.0e+00), RES(1.1920928955077927359e-7, -1.4210854715201700795e-14)}, {FN (arccsch), ARG(8.3886080e+06,-1.0e+00), RES(1.1920928955077927359e-7, 1.4210854715201700795e-14)}, {FN (arccsch), ARG(-8.3886080e+06,1.0e+00), RES(-1.1920928955077927359e-7, -1.4210854715201700795e-14)}, {FN (arccsch), ARG(-8.3886080e+06,-1.0e+00), RES(-1.1920928955077927359e-7, 1.4210854715201700795e-14)}, {FN (arccsch), ARG(8.3886080e+06,2.0e+00), RES(1.1920928955077419139e-7, -2.8421709430402189899e-14)}, {FN (arccsch), ARG(8.3886080e+06,-2.0e+00), RES(1.1920928955077419139e-7, 2.8421709430402189899e-14)}, {FN (arccsch), ARG(-8.3886080e+06,2.0e+00), RES(-1.1920928955077419139e-7, -2.8421709430402189899e-14)}, {FN (arccsch), ARG(-8.3886080e+06,-2.0e+00), RES(-1.1920928955077419139e-7, 2.8421709430402189899e-14)}, {FN (arccsch), ARG(8.3886080e+06,8.3886080e+06), RES(5.9604644775390695586e-8, -5.9604644775390554414e-8)}, {FN (arccsch), ARG(8.3886080e+06,-8.3886080e+06), RES(5.9604644775390695586e-8, 5.9604644775390554414e-8)}, {FN (arccsch), ARG(-8.3886080e+06,8.3886080e+06), RES(-5.9604644775390695586e-8, -5.9604644775390554414e-8)}, {FN (arccsch), ARG(-8.3886080e+06,-8.3886080e+06), RES(-5.9604644775390695586e-8, 5.9604644775390554414e-8)}, {FN (arcsech), ARG(0.0e+00,1.19209289550781250e-07), RES(1.6635532333438690979e1, -1.5707963267948966192e0)}, {FN (arcsech), ARG(0.0e+00,-1.19209289550781250e-07), RES(1.6635532333438690979e1, 1.5707963267948966192e0)}, {FN (arcsech), ARG(0.0e+00,5.0e-01), RES(1.4436354751788103425e0, -1.5707963267948966192e0)}, {FN (arcsech), ARG(0.0e+00,-5.0e-01), RES(1.4436354751788103425e0, 1.5707963267948966192e0)}, {FN (arcsech), ARG(0.0e+00,1.0e+00), RES(8.8137358701954302523e-1, -1.5707963267948966192e0)}, {FN (arcsech), ARG(0.0e+00,-1.0e+00), RES(8.8137358701954302523e-1, 1.5707963267948966192e0)}, {FN (arcsech), ARG(0.0e+00,2.0e+00), RES(4.8121182505960344750e-1, -1.5707963267948966192e0)}, {FN (arcsech), ARG(0.0e+00,-2.0e+00), RES(4.8121182505960344750e-1, 1.5707963267948966192e0)}, {FN (arcsech), ARG(0.0e+00,8.3886080e+06), RES(1.1920928955078096766e-7, -1.5707963267948966192e0)}, {FN (arcsech), ARG(0.0e+00,-8.3886080e+06), RES(1.1920928955078096766e-7, 1.5707963267948966192e0)}, {FN (arcsech), ARG(1.19209289550781250e-07,0.0e+00), RES(1.6635532333438683873e1, 0.0)}, {FN (arcsech), ARG(-1.19209289550781250e-07,0.0e+00), RES(1.6635532333438683873e1, 3.1415926535897932385e0)}, {FN (arcsech), ARG(1.19209289550781250e-07,1.19209289550781250e-07), RES(1.6288958743158714771e1, -7.8539816339745541504e-1)}, {FN (arcsech), ARG(1.19209289550781250e-07,-1.19209289550781250e-07), RES(1.6288958743158714771e1, 7.8539816339745541504e-1)}, {FN (arcsech), ARG(-1.19209289550781250e-07,1.19209289550781250e-07), RES(1.6288958743158714771e1, -2.3561944901923378234e0)}, {FN (arcsech), ARG(-1.19209289550781250e-07,-1.19209289550781250e-07), RES(1.6288958743158714771e1, 2.3561944901923378234e0)}, {FN (arcsech), ARG(1.19209289550781250e-07,5.0e-01), RES(1.4436354751787798371e0, -1.5707961135468366312e0)}, {FN (arcsech), ARG(1.19209289550781250e-07,-5.0e-01), RES(1.4436354751787798371e0, 1.5707961135468366312e0)}, {FN (arcsech), ARG(-1.19209289550781250e-07,5.0e-01), RES(1.4436354751787798371e0, -1.5707965400429566072e0)}, {FN (arcsech), ARG(-1.19209289550781250e-07,-5.0e-01), RES(1.4436354751787798371e0, 1.5707965400429566072e0)}, {FN (arcsech), ARG(1.19209289550781250e-07,1.0e+00), RES(8.8137358701953548879e-1, -1.5707962425011995974e0)}, {FN (arcsech), ARG(1.19209289550781250e-07,-1.0e+00), RES(8.8137358701953548879e-1, 1.5707962425011995974e0)}, {FN (arcsech), ARG(-1.19209289550781250e-07,1.0e+00), RES(8.8137358701953548879e-1, -1.5707964110885936410e0)}, {FN (arcsech), ARG(-1.19209289550781250e-07,-1.0e+00), RES(8.8137358701953548879e-1, 1.5707964110885936410e0)}, {FN (arcsech), ARG(1.19209289550781250e-07,2.0e+00), RES(4.8121182505960201756e-1, -1.5707963001388891207e0)}, {FN (arcsech), ARG(1.19209289550781250e-07,-2.0e+00), RES(4.8121182505960201756e-1, 1.5707963001388891207e0)}, {FN (arcsech), ARG(-1.19209289550781250e-07,2.0e+00), RES(4.8121182505960201756e-1, -1.5707963534509041177e0)}, {FN (arcsech), ARG(-1.19209289550781250e-07,-2.0e+00), RES(4.8121182505960201756e-1, 1.5707963534509041177e0)}, {FN (arcsech), ARG(1.19209289550781250e-07,8.3886080e+06), RES(1.1920928955078096766e-7, -1.5707963267948966192e0)}, {FN (arcsech), ARG(1.19209289550781250e-07,-8.3886080e+06), RES(1.1920928955078096766e-7, 1.5707963267948966192e0)}, {FN (arcsech), ARG(-1.19209289550781250e-07,8.3886080e+06), RES(1.1920928955078096766e-7, -1.5707963267948966192e0)}, {FN (arcsech), ARG(-1.19209289550781250e-07,-8.3886080e+06), RES(1.1920928955078096766e-7, 1.5707963267948966192e0)}, {FN (arcsech), ARG(5.0e-01,0.0e+00), RES(1.3169578969248167086e0, 0.0)}, {FN (arcsech), ARG(-5.0e-01,0.0e+00), RES(1.3169578969248167086e0, 3.1415926535897932385e0)}, {FN (arcsech), ARG(5.0e-01,1.19209289550781250e-07), RES(1.3169578969247948296e0, -2.7530206164818516969e-7)}, {FN (arcsech), ARG(5.0e-01,-1.19209289550781250e-07), RES(1.3169578969247948296e0, 2.7530206164818516969e-7)}, {FN (arcsech), ARG(-5.0e-01,1.19209289550781250e-07), RES(1.3169578969247948296e0, -3.1415923782877315903e0)}, {FN (arcsech), ARG(-5.0e-01,-1.19209289550781250e-07), RES(1.3169578969247948296e0, 3.1415923782877315903e0)}, {FN (arcsech), ARG(5.0e-01,5.0e-01), RES(1.0612750619050356520e0, -9.0455689430238136413e-1)}, {FN (arcsech), ARG(5.0e-01,-5.0e-01), RES(1.0612750619050356520e0, 9.0455689430238136413e-1)}, {FN (arcsech), ARG(-5.0e-01,5.0e-01), RES(1.0612750619050356520e0, -2.2370357592874118743e0)}, {FN (arcsech), ARG(-5.0e-01,-5.0e-01), RES(1.0612750619050356520e0, 2.2370357592874118743e0)}, {FN (arcsech), ARG(5.0e-01,1.0e+00), RES(7.6388434595371104541e-1, -1.2595705295501355239e0)}, {FN (arcsech), ARG(5.0e-01,-1.0e+00), RES(7.6388434595371104541e-1, 1.2595705295501355239e0)}, {FN (arcsech), ARG(-5.0e-01,1.0e+00), RES(7.6388434595371104541e-1, -1.8820221240396577146e0)}, {FN (arcsech), ARG(-5.0e-01,-1.0e+00), RES(7.6388434595371104541e-1, 1.8820221240396577146e0)}, {FN (arcsech), ARG(5.0e-01,2.0e+00), RES(4.5717847686917515748e-1, -1.4642558238421395793e0)}, {FN (arcsech), ARG(5.0e-01,-2.0e+00), RES(4.5717847686917515748e-1, 1.4642558238421395793e0)}, {FN (arcsech), ARG(-5.0e-01,2.0e+00), RES(4.5717847686917515748e-1, -1.6773368297476536591e0)}, {FN (arcsech), ARG(-5.0e-01,-2.0e+00), RES(4.5717847686917515748e-1, 1.6773368297476536591e0)}, {FN (arcsech), ARG(5.0e-01,8.3886080e+06), RES(1.1920928955078054414e-7, -1.5707963267948895138e0)}, {FN (arcsech), ARG(5.0e-01,-8.3886080e+06), RES(1.1920928955078054414e-7, 1.5707963267948895138e0)}, {FN (arcsech), ARG(-5.0e-01,8.3886080e+06), RES(1.1920928955078054414e-7, -1.5707963267949037247e0)}, {FN (arcsech), ARG(-5.0e-01,-8.3886080e+06), RES(1.1920928955078054414e-7, 1.5707963267949037247e0)}, {FN (arcsech), ARG(1.0e+00,0.0e+00), RES(0e0, 0.0)}, {FN (arcsech), ARG(-1.0e+00,0.0e+00), RES(0, 3.1415926535897932385e0)}, {FN (arcsech), ARG(1.0e+00,1.19209289550781250e-07), RES(3.4526696585164602772e-4, -3.4526700015083915182e-4)}, {FN (arcsech), ARG(1.0e+00,-1.19209289550781250e-07), RES(3.4526696585164602772e-4, 3.4526700015083915182e-4)}, {FN (arcsech), ARG(-1.0e+00,1.19209289550781250e-07), RES(3.4526696585164602772e-4, -3.1412473865896423993e0)}, {FN (arcsech), ARG(-1.0e+00,-1.19209289550781250e-07), RES(3.4526696585164602772e-4, 3.1412473865896423993e0)}, {FN (arcsech), ARG(1.0e+00,5.0e-01), RES(5.3321829058411214108e-1, -7.9770997007539188581e-1)}, {FN (arcsech), ARG(1.0e+00,-5.0e-01), RES(5.3321829058411214108e-1, 7.9770997007539188581e-1)}, {FN (arcsech), ARG(-1.0e+00,5.0e-01), RES(5.3321829058411214108e-1, -2.3438826835144013527e0)}, {FN (arcsech), ARG(-1.0e+00,-5.0e-01), RES(5.3321829058411214108e-1, 2.3438826835144013527e0)}, {FN (arcsech), ARG(1.0e+00,1.0e+00), RES(5.3063753095251782602e-1, -1.1185178796437059372e0)}, {FN (arcsech), ARG(1.0e+00,-1.0e+00), RES(5.3063753095251782602e-1, 1.1185178796437059372e0)}, {FN (arcsech), ARG(-1.0e+00,1.0e+00), RES(5.3063753095251782602e-1, -2.0230747739460873013e0)}, {FN (arcsech), ARG(-1.0e+00,-1.0e+00), RES(5.3063753095251782602e-1, 2.0230747739460873013e0)}, {FN (arcsech), ARG(1.0e+00,2.0e+00), RES(3.9656823011232897892e-1, -1.3844782726870810934e0)}, {FN (arcsech), ARG(1.0e+00,-2.0e+00), RES(3.9656823011232897892e-1, 1.3844782726870810934e0)}, {FN (arcsech), ARG(-1.0e+00,2.0e+00), RES(3.9656823011232897892e-1, -1.7571143809027121451e0)}, {FN (arcsech), ARG(-1.0e+00,-2.0e+00), RES(3.9656823011232897892e-1, 1.7571143809027121451e0)}, {FN (arcsech), ARG(1.0e+00,8.3886080e+06), RES(1.1920928955077927359e-7, -1.5707963267948824084e0)}, {FN (arcsech), ARG(1.0e+00,-8.3886080e+06), RES(1.1920928955077927359e-7, 1.5707963267948824084e0)}, {FN (arcsech), ARG(-1.0e+00,8.3886080e+06), RES(1.1920928955077927359e-7, -1.5707963267949108301e0)}, {FN (arcsech), ARG(-1.0e+00,-8.3886080e+06), RES(1.1920928955077927359e-7, 1.5707963267949108301e0)}, {FN (arcsech), ARG(2.0e+00,0.0e+00), RES(0, 1.0471975511965977462e0)}, {FN (arcsech), ARG(-2.0e+00,0.0e+00), RES(0, 2.0943951023931954923e0)}, {FN (arcsech), ARG(2.0e+00,1.19209289550781250e-07), RES(3.4412757706023621662e-8, -1.0471975511966001392e0)}, {FN (arcsech), ARG(2.0e+00,-1.19209289550781250e-07), RES(3.4412757706023621662e-8, 1.0471975511966001392e0)}, {FN (arcsech), ARG(-2.0e+00,1.19209289550781250e-07), RES(3.4412757706023621662e-8, -2.0943951023931930993e0)}, {FN (arcsech), ARG(-2.0e+00,-1.19209289550781250e-07), RES(3.4412757706023621662e-8, 2.0943951023931930993e0)}, {FN (arcsech), ARG(2.0e+00,5.0e-01), RES(1.3261586085051183885e-1, -1.0854889863215541067e0)}, {FN (arcsech), ARG(2.0e+00,-5.0e-01), RES(1.3261586085051183885e-1, 1.0854889863215541067e0)}, {FN (arcsech), ARG(-2.0e+00,5.0e-01), RES(1.3261586085051183885e-1, -2.0561036672682391317e0)}, {FN (arcsech), ARG(-2.0e+00,-5.0e-01), RES(1.3261586085051183885e-1, 2.0561036672682391317e0)}, {FN (arcsech), ARG(2.0e+00,1.0e+00), RES(2.1561241855582964497e-1, -1.1692099351270905509e0)}, {FN (arcsech), ARG(2.0e+00,-1.0e+00), RES(2.1561241855582964497e-1, 1.1692099351270905509e0)}, {FN (arcsech), ARG(-2.0e+00,1.0e+00), RES(2.1561241855582964497e-1, -1.9723827184627026875e0)}, {FN (arcsech), ARG(-2.0e+00,-1.0e+00), RES(2.1561241855582964497e-1, 1.9723827184627026875e0)}, {FN (arcsech), ARG(2.0e+00,2.0e+00), RES(2.5489557334055081773e-1, -1.3262741616593564728e0)}, {FN (arcsech), ARG(2.0e+00,-2.0e+00), RES(2.5489557334055081773e-1, 1.3262741616593564728e0)}, {FN (arcsech), ARG(-2.0e+00,2.0e+00), RES(2.5489557334055081773e-1, -1.8153184919304367657e0)}, {FN (arcsech), ARG(-2.0e+00,-2.0e+00), RES(2.5489557334055081773e-1, 1.8153184919304367657e0)}, {FN (arcsech), ARG(2.0e+00,8.3886080e+06), RES(1.1920928955077419139e-7, -1.5707963267948681975e0)}, {FN (arcsech), ARG(2.0e+00,-8.3886080e+06), RES(1.1920928955077419139e-7, 1.5707963267948681975e0)}, {FN (arcsech), ARG(-2.0e+00,8.3886080e+06), RES(1.1920928955077419139e-7, -1.5707963267949250409e0)}, {FN (arcsech), ARG(-2.0e+00,-8.3886080e+06), RES(1.1920928955077419139e-7, 1.5707963267949250409e0)}, {FN (arcsech), ARG(8.3886080e+06,0.0e+00), RES(0, 1.5707962075856070684e0)}, {FN (arcsech), ARG(-8.3886080e+06,0.0e+00), RES(0, 1.570796446004186170e0)}, {FN (arcsech), ARG(8.3886080e+06,1.19209289550781250e-07), RES(1.6940658945086127152e-21, -1.5707962075856070684e0)}, {FN (arcsech), ARG(8.3886080e+06,-1.19209289550781250e-07), RES(1.6940658945086127152e-21, 1.5707962075856070684e0)}, {FN (arcsech), ARG(-8.3886080e+06,1.19209289550781250e-07), RES(1.6940658945086127152e-21, -1.570796446004186170e0)}, {FN (arcsech), ARG(-8.3886080e+06,-1.19209289550781250e-07), RES(1.6940658945086127152e-21, 1.570796446004186170e0)}, {FN (arcsech), ARG(8.3886080e+06,5.0e-01), RES(7.1054273576010271023e-15, -1.5707962075856070685e0)}, {FN (arcsech), ARG(8.3886080e+06,-5.0e-01), RES(7.1054273576010271023e-15, 1.5707962075856070685e0)}, {FN (arcsech), ARG(-8.3886080e+06,5.0e-01), RES(7.1054273576010271023e-15, -1.570796446004186170e0)}, {FN (arcsech), ARG(-8.3886080e+06,-5.0e-01), RES(7.1054273576010271023e-15, 1.570796446004186170e0)}, {FN (arcsech), ARG(8.3886080e+06,1.0e+00), RES(1.4210854715201902743e-14, -1.5707962075856070685e0)}, {FN (arcsech), ARG(8.3886080e+06,-1.0e+00), RES(1.4210854715201902743e-14, 1.5707962075856070685e0)}, {FN (arcsech), ARG(-8.3886080e+06,1.0e+00), RES(1.4210854715201902743e-14, -1.570796446004186170e0)}, {FN (arcsech), ARG(-8.3886080e+06,-1.0e+00), RES(1.4210854715201902743e-14, 1.570796446004186170e0)}, {FN (arcsech), ARG(8.3886080e+06,2.0e+00), RES(2.8421709430402593796e-14, -1.5707962075856070685e0)}, {FN (arcsech), ARG(8.3886080e+06,-2.0e+00), RES(2.8421709430402593796e-14, 1.5707962075856070685e0)}, {FN (arcsech), ARG(-8.3886080e+06,2.0e+00), RES(2.8421709430402593796e-14, -1.570796446004186170e0)}, {FN (arcsech), ARG(-8.3886080e+06,-2.0e+00), RES(2.8421709430402593796e-14, 1.570796446004186170e0)}, {FN (arcsech), ARG(8.3886080e+06,8.3886080e+06), RES(5.9604644775390695586e-8, -1.5707962671902518438e0)}, {FN (arcsech), ARG(8.3886080e+06,-8.3886080e+06), RES(5.9604644775390695586e-8, 1.5707962671902518438e0)}, {FN (arcsech), ARG(-8.3886080e+06,8.3886080e+06), RES(5.9604644775390695586e-8, -1.5707963863995413946e0)}, {FN (arcsech), ARG(-8.3886080e+06,-8.3886080e+06), RES(5.9604644775390695586e-8, 1.5707963863995413946e0)}, {FN (arccoth), ARG(0.0e+00,1.19209289550781250e-07), RES(0, -1.5707962075856070685e0)}, {FN (arccoth), ARG(0.0e+00,-1.19209289550781250e-07), RES(0, 1.5707962075856070685e0)}, {FN (arccoth), ARG(0.0e+00,5.0e-01), RES(0, -1.1071487177940905030e0)}, {FN (arccoth), ARG(0.0e+00,-5.0e-01), RES(0, 1.1071487177940905030e0)}, {FN (arccoth), ARG(0.0e+00,1.0e+00), RES(0, -7.8539816339744830962e-1)}, {FN (arccoth), ARG(0.0e+00,-1.0e+00), RES(0, 7.8539816339744830962e-1)}, {FN (arccoth), ARG(0.0e+00,2.0e+00), RES(0, -4.6364760900080611621e-1)}, {FN (arccoth), ARG(0.0e+00,-2.0e+00), RES(0, 4.6364760900080611621e-1)}, {FN (arccoth), ARG(0.0e+00,8.3886080e+06), RES(0, -1.1920928955078068531e-7)}, {FN (arccoth), ARG(0.0e+00,-8.3886080e+06), RES(0, 1.1920928955078068531e-7)}, {FN (arccoth), ARG(1.19209289550781250e-07,0.0e+00), RES(1.1920928955078181469e-7, -1.5707963267948966192e0)}, {FN (arccoth), ARG(-1.19209289550781250e-07,0.0e+00), RES(-1.1920928955078181469e-7, 1.5707963267948966192e0)}, {FN (arccoth), ARG(1.19209289550781250e-07,1.19209289550781250e-07), RES(1.1920928955078012062e-7, -1.5707962075856070684e0)}, {FN (arccoth), ARG(1.19209289550781250e-07,-1.19209289550781250e-07), RES(1.1920928955078012062e-7, 1.5707962075856070684e0)}, {FN (arccoth), ARG(-1.19209289550781250e-07,1.19209289550781250e-07), RES(-1.1920928955078012062e-7, -1.5707962075856070684e0)}, {FN (arccoth), ARG(-1.19209289550781250e-07,-1.19209289550781250e-07), RES(-1.1920928955078012062e-7, 1.5707962075856070684e0)}, {FN (arccoth), ARG(1.19209289550781250e-07,5.0e-01), RES(9.5367431640625072280e-8, -1.1071487177940859555e0)}, {FN (arccoth), ARG(1.19209289550781250e-07,-5.0e-01), RES(9.5367431640625072280e-8, 1.1071487177940859555e0)}, {FN (arccoth), ARG(-1.19209289550781250e-07,5.0e-01), RES(-9.5367431640625072280e-8, -1.1071487177940859555e0)}, {FN (arccoth), ARG(-1.19209289550781250e-07,-5.0e-01), RES(-9.5367431640625072280e-8, 1.1071487177940859555e0)}, {FN (arccoth), ARG(1.19209289550781250e-07,1.0e+00), RES(5.9604644775390483828e-8, -7.8539816339744475690e-1)}, {FN (arccoth), ARG(1.19209289550781250e-07,-1.0e+00), RES(5.9604644775390483828e-8, 7.8539816339744475690e-1)}, {FN (arccoth), ARG(-1.19209289550781250e-07,1.0e+00), RES(-5.9604644775390483828e-8, -7.8539816339744475690e-1)}, {FN (arccoth), ARG(-1.19209289550781250e-07,-1.0e+00), RES(-5.9604644775390483828e-8, 7.8539816339744475690e-1)}, {FN (arccoth), ARG(1.19209289550781250e-07,2.0e+00), RES(2.3841857910156200307e-8, -4.6364760900080497935e-1)}, {FN (arccoth), ARG(1.19209289550781250e-07,-2.0e+00), RES(2.3841857910156200307e-8, 4.6364760900080497935e-1)}, {FN (arccoth), ARG(-1.19209289550781250e-07,2.0e+00), RES(-2.3841857910156200307e-8, -4.6364760900080497935e-1)}, {FN (arccoth), ARG(-1.19209289550781250e-07,-2.0e+00), RES(-2.3841857910156200307e-8, 4.6364760900080497935e-1)}, {FN (arccoth), ARG(1.19209289550781250e-07,8.3886080e+06), RES(1.6940658945085766040e-21, -1.1920928955078068531e-7)}, {FN (arccoth), ARG(1.19209289550781250e-07,-8.3886080e+06), RES(1.6940658945085766040e-21, 1.1920928955078068531e-7)}, {FN (arccoth), ARG(-1.19209289550781250e-07,8.3886080e+06), RES(-1.6940658945085766040e-21, -1.1920928955078068531e-7)}, {FN (arccoth), ARG(-1.19209289550781250e-07,-8.3886080e+06), RES(-1.6940658945085766040e-21, 1.1920928955078068531e-7)}, {FN (arccoth), ARG(5.0e-01,0.0e+00), RES(5.4930614433405484570e-1, -1.5707963267948966192e0)}, {FN (arccoth), ARG(-5.0e-01,0.0e+00), RES(-5.4930614433405484570e-1, 1.5707963267948966192e0)}, {FN (arccoth), ARG(5.0e-01,1.19209289550781250e-07), RES(5.4930614433404221383e-1, -1.5707961678491772182e0)}, {FN (arccoth), ARG(5.0e-01,-1.19209289550781250e-07), RES(5.4930614433404221383e-1, 1.5707961678491772182e0)}, {FN (arccoth), ARG(-5.0e-01,1.19209289550781250e-07), RES(-5.4930614433404221383e-1, -1.5707961678491772182e0)}, {FN (arccoth), ARG(-5.0e-01,-1.19209289550781250e-07), RES(-5.4930614433404221383e-1, 1.5707961678491772182e0)}, {FN (arccoth), ARG(5.0e-01,5.0e-01), RES(4.0235947810852509365e-1, -1.0172219678978513677e0)}, {FN (arccoth), ARG(5.0e-01,-5.0e-01), RES(4.0235947810852509365e-1, 1.0172219678978513677e0)}, {FN (arccoth), ARG(-5.0e-01,5.0e-01), RES(-4.0235947810852509365e-1, -1.0172219678978513677e0)}, {FN (arccoth), ARG(-5.0e-01,-5.0e-01), RES(-4.0235947810852509365e-1, 1.0172219678978513677e0)}, {FN (arccoth), ARG(5.0e-01,1.0e+00), RES(2.3887786125685909036e-1, -7.2322066612406759210e-1)}, {FN (arccoth), ARG(5.0e-01,-1.0e+00), RES(2.3887786125685909036e-1, 7.2322066612406759210e-1)}, {FN (arccoth), ARG(-5.0e-01,1.0e+00), RES(-2.3887786125685909036e-1, -7.2322066612406759210e-1)}, {FN (arccoth), ARG(-5.0e-01,-1.0e+00), RES(-2.3887786125685909036e-1, 7.2322066612406759210e-1)}, {FN (arccoth), ARG(5.0e-01,2.0e+00), RES(9.6415620202996167238e-2, -4.4423988596007427049e-1)}, {FN (arccoth), ARG(5.0e-01,-2.0e+00), RES(9.6415620202996167238e-2, 4.4423988596007427049e-1)}, {FN (arccoth), ARG(-5.0e-01,2.0e+00), RES(-9.6415620202996167238e-2, -4.4423988596007427049e-1)}, {FN (arccoth), ARG(-5.0e-01,-2.0e+00), RES(-9.6415620202996167238e-2, 4.4423988596007427049e-1)}, {FN (arccoth), ARG(5.0e-01,8.3886080e+06), RES(7.1054273576008756410e-15, -1.1920928955078026179e-7)}, {FN (arccoth), ARG(5.0e-01,-8.3886080e+06), RES(7.1054273576008756410e-15, 1.1920928955078026179e-7)}, {FN (arccoth), ARG(-5.0e-01,8.3886080e+06), RES(-7.1054273576008756410e-15, -1.1920928955078026179e-7)}, {FN (arccoth), ARG(-5.0e-01,-8.3886080e+06), RES(-7.1054273576008756410e-15, 1.1920928955078026179e-7)}, {FN (arccoth), ARG(1.0e+00,1.19209289550781250e-07), RES(8.3177661667193446012e0, -7.8539813359512592192e-1)}, {FN (arccoth), ARG(1.0e+00,-1.19209289550781250e-07), RES(8.3177661667193446012e0, 7.8539813359512592192e-1)}, {FN (arccoth), ARG(-1.0e+00,1.19209289550781250e-07), RES(-8.3177661667193446012e0, -7.8539813359512592192e-1)}, {FN (arccoth), ARG(-1.0e+00,-1.19209289550781250e-07), RES(-8.3177661667193446012e0, 7.8539813359512592192e-1)}, {FN (arccoth), ARG(1.0e+00,5.0e-01), RES(7.0830333601405402006e-1, -6.6290883183401623253e-1)}, {FN (arccoth), ARG(1.0e+00,-5.0e-01), RES(7.0830333601405402006e-1, 6.6290883183401623253e-1)}, {FN (arccoth), ARG(-1.0e+00,5.0e-01), RES(-7.0830333601405402006e-1, -6.6290883183401623253e-1)}, {FN (arccoth), ARG(-1.0e+00,-5.0e-01), RES(-7.0830333601405402006e-1, 6.6290883183401623253e-1)}, {FN (arccoth), ARG(1.0e+00,1.0e+00), RES(4.0235947810852509365e-1, -5.5357435889704525151e-1)}, {FN (arccoth), ARG(1.0e+00,-1.0e+00), RES(4.0235947810852509365e-1, 5.5357435889704525151e-1)}, {FN (arccoth), ARG(-1.0e+00,1.0e+00), RES(-4.0235947810852509365e-1, -5.5357435889704525151e-1)}, {FN (arccoth), ARG(-1.0e+00,-1.0e+00), RES(-4.0235947810852509365e-1, 5.5357435889704525151e-1)}, {FN (arccoth), ARG(1.0e+00,2.0e+00), RES(1.7328679513998632735e-1, -3.9269908169872415481e-1)}, {FN (arccoth), ARG(1.0e+00,-2.0e+00), RES(1.7328679513998632735e-1, 3.9269908169872415481e-1)}, {FN (arccoth), ARG(-1.0e+00,2.0e+00), RES(-1.7328679513998632735e-1, -3.9269908169872415481e-1)}, {FN (arccoth), ARG(-1.0e+00,-2.0e+00), RES(-1.7328679513998632735e-1, 3.9269908169872415481e-1)}, {FN (arccoth), ARG(1.0e+00,8.3886080e+06), RES(1.4210854715201599821e-14, -1.1920928955077899125e-7)}, {FN (arccoth), ARG(1.0e+00,-8.3886080e+06), RES(1.4210854715201599821e-14, 1.1920928955077899125e-7)}, {FN (arccoth), ARG(-1.0e+00,8.3886080e+06), RES(-1.4210854715201599821e-14, -1.1920928955077899125e-7)}, {FN (arccoth), ARG(-1.0e+00,-8.3886080e+06), RES(-1.4210854715201599821e-14, 1.1920928955077899125e-7)}, {FN (arccoth), ARG(2.0e+00,0.0e+00), RES(5.4930614433405484570e-1, 0.0)}, {FN (arccoth), ARG(-2.0e+00,0.0e+00), RES(-5.4930614433405484570e-1, 0.0)}, {FN (arccoth), ARG(2.0e+00,1.19209289550781250e-07), RES(5.4930614433405168773e-1, -3.9736429850260144780e-8)}, {FN (arccoth), ARG(2.0e+00,-1.19209289550781250e-07), RES(5.4930614433405168773e-1, 3.9736429850260144780e-8)}, {FN (arccoth), ARG(-2.0e+00,1.19209289550781250e-07), RES(-5.4930614433405168773e-1, -3.9736429850260144780e-8)}, {FN (arccoth), ARG(-2.0e+00,-1.19209289550781250e-07), RES(-5.4930614433405168773e-1, 3.9736429850260144780e-8)}, {FN (arccoth), ARG(2.0e+00,5.0e-01), RES(5.0037000005253101744e-1, -1.4924946579308963897e-1)}, {FN (arccoth), ARG(2.0e+00,-5.0e-01), RES(5.0037000005253101744e-1, 1.4924946579308963897e-1)}, {FN (arccoth), ARG(-2.0e+00,5.0e-01), RES(-5.0037000005253101744e-1, -1.4924946579308963897e-1)}, {FN (arccoth), ARG(-2.0e+00,-5.0e-01), RES(-5.0037000005253101744e-1, 1.4924946579308963897e-1)}, {FN (arccoth), ARG(2.0e+00,1.0e+00), RES(4.0235947810852509365e-1, -2.3182380450040305811e-1)}, {FN (arccoth), ARG(2.0e+00,-1.0e+00), RES(4.0235947810852509365e-1, 2.3182380450040305811e-1)}, {FN (arccoth), ARG(-2.0e+00,1.0e+00), RES(-4.0235947810852509365e-1, -2.3182380450040305811e-1)}, {FN (arccoth), ARG(-2.0e+00,-1.0e+00), RES(-4.0235947810852509365e-1, 2.3182380450040305811e-1)}, {FN (arccoth), ARG(2.0e+00,2.0e+00), RES(2.3887786125685909036e-1, -2.5957305712326147589e-1)}, {FN (arccoth), ARG(2.0e+00,-2.0e+00), RES(2.3887786125685909036e-1, 2.5957305712326147589e-1)}, {FN (arccoth), ARG(-2.0e+00,2.0e+00), RES(-2.3887786125685909036e-1, -2.5957305712326147589e-1)}, {FN (arccoth), ARG(-2.0e+00,-2.0e+00), RES(-2.3887786125685909036e-1, 2.5957305712326147589e-1)}, {FN (arccoth), ARG(2.0e+00,8.3886080e+06), RES(2.8421709430401987951e-14, -1.1920928955077390905e-7)}, {FN (arccoth), ARG(2.0e+00,-8.3886080e+06), RES(2.8421709430401987951e-14, 1.1920928955077390905e-7)}, {FN (arccoth), ARG(-2.0e+00,8.3886080e+06), RES(-2.8421709430401987951e-14, -1.1920928955077390905e-7)}, {FN (arccoth), ARG(-2.0e+00,-8.3886080e+06), RES(-2.8421709430401987951e-14, 1.1920928955077390905e-7)}, {FN (arccoth), ARG(8.3886080e+06,0.0e+00), RES(1.1920928955078181469e-7, 0.0)}, {FN (arccoth), ARG(-8.3886080e+06,0.0e+00), RES(-1.1920928955078181469e-7, 0.0)}, {FN (arccoth), ARG(8.3886080e+06,1.19209289550781250e-07), RES(1.1920928955078181469e-7, -1.6940658945086247523e-21)}, {FN (arccoth), ARG(8.3886080e+06,-1.19209289550781250e-07), RES(1.1920928955078181469e-7, 1.6940658945086247523e-21)}, {FN (arccoth), ARG(-8.3886080e+06,1.19209289550781250e-07), RES(-1.1920928955078181469e-7, -1.6940658945086247523e-21)}, {FN (arccoth), ARG(-8.3886080e+06,-1.19209289550781250e-07), RES(-1.1920928955078181469e-7, 1.6940658945086247523e-21)}, {FN (arccoth), ARG(8.3886080e+06,5.0e-01), RES(1.1920928955078139117e-7, -7.1054273576010775894e-15)}, {FN (arccoth), ARG(8.3886080e+06,-5.0e-01), RES(1.1920928955078139117e-7, 7.1054273576010775894e-15)}, {FN (arccoth), ARG(-8.3886080e+06,5.0e-01), RES(-1.1920928955078139117e-7, -7.1054273576010775894e-15)}, {FN (arccoth), ARG(-8.3886080e+06,-5.0e-01), RES(-1.1920928955078139117e-7, 7.1054273576010775894e-15)}, {FN (arccoth), ARG(8.3886080e+06,1.0e+00), RES(1.1920928955078012062e-7, -1.4210854715202003717e-14)}, {FN (arccoth), ARG(8.3886080e+06,-1.0e+00), RES(1.1920928955078012062e-7, 1.4210854715202003717e-14)}, {FN (arccoth), ARG(-8.3886080e+06,1.0e+00), RES(-1.1920928955078012062e-7, -1.4210854715202003717e-14)}, {FN (arccoth), ARG(-8.3886080e+06,-1.0e+00), RES(-1.1920928955078012062e-7, 1.4210854715202003717e-14)}, {FN (arccoth), ARG(8.3886080e+06,2.0e+00), RES(1.1920928955077503843e-7, -2.8421709430402795744e-14)}, {FN (arccoth), ARG(8.3886080e+06,-2.0e+00), RES(1.1920928955077503843e-7, 2.8421709430402795744e-14)}, {FN (arccoth), ARG(-8.3886080e+06,2.0e+00), RES(-1.1920928955077503843e-7, -2.8421709430402795744e-14)}, {FN (arccoth), ARG(-8.3886080e+06,-2.0e+00), RES(-1.1920928955077503843e-7, 2.8421709430402795744e-14)}, {FN (arccoth), ARG(8.3886080e+06,8.3886080e+06), RES(5.9604644775390483828e-8, -5.9604644775390766172e-8)}, {FN (arccoth), ARG(8.3886080e+06,-8.3886080e+06), RES(5.9604644775390483828e-8, 5.9604644775390766172e-8)}, {FN (arccoth), ARG(-8.3886080e+06,8.3886080e+06), RES(-5.9604644775390483828e-8, -5.9604644775390766172e-8)}, {FN (arccoth), ARG(-8.3886080e+06,-8.3886080e+06), RES(-5.9604644775390483828e-8, 5.9604644775390766172e-8)}, praat-6.0.04/external/gsl/gsl_complex__results1.h000066400000000000000000001317611261542461700220260ustar00rootroot00000000000000 {FN (arg), ARG(0.0e+00,0.0e+00), RES(0e0, 0.0)}, {FN (arg), ARG(0.0e+00,1.19209289550781250e-07), RES(1.5707963267948966192e0, 0.0)}, {FN (arg), ARG(0.0e+00,-1.19209289550781250e-07), RES(-1.5707963267948966192e0, 0.0)}, {FN (arg), ARG(0.0e+00,5.0e-01), RES(1.5707963267948966192e0, 0.0)}, {FN (arg), ARG(0.0e+00,-5.0e-01), RES(-1.5707963267948966192e0, 0.0)}, {FN (arg), ARG(0.0e+00,1.0e+00), RES(1.5707963267948966192e0, 0.0)}, {FN (arg), ARG(0.0e+00,-1.0e+00), RES(-1.5707963267948966192e0, 0.0)}, {FN (arg), ARG(0.0e+00,2.0e+00), RES(1.5707963267948966192e0, 0.0)}, {FN (arg), ARG(0.0e+00,-2.0e+00), RES(-1.5707963267948966192e0, 0.0)}, {FN (arg), ARG(0.0e+00,8.3886080e+06), RES(1.5707963267948966192e0, 0.0)}, {FN (arg), ARG(0.0e+00,-8.3886080e+06), RES(-1.5707963267948966192e0, 0.0)}, {FN (arg), ARG(1.19209289550781250e-07,0.0e+00), RES(0e0, 0.0)}, {FN (arg), ARG(-1.19209289550781250e-07,0.0e+00), RES(3.1415926535897932385e0, 0.0)}, {FN (arg), ARG(1.19209289550781250e-07,1.19209289550781250e-07), RES(7.8539816339744830962e-1, 0.0)}, {FN (arg), ARG(1.19209289550781250e-07,-1.19209289550781250e-07), RES(-7.8539816339744830962e-1, 0.0)}, {FN (arg), ARG(-1.19209289550781250e-07,1.19209289550781250e-07), RES(2.3561944901923449288e0, 0.0)}, {FN (arg), ARG(-1.19209289550781250e-07,-1.19209289550781250e-07), RES(-2.3561944901923449288e0, 0.0)}, {FN (arg), ARG(1.19209289550781250e-07,5.0e-01), RES(1.5707960883763175177e0, 0.0)}, {FN (arg), ARG(1.19209289550781250e-07,-5.0e-01), RES(-1.5707960883763175177e0, 0.0)}, {FN (arg), ARG(-1.19209289550781250e-07,5.0e-01), RES(1.5707965652134757208e0, 0.0)}, {FN (arg), ARG(-1.19209289550781250e-07,-5.0e-01), RES(-1.5707965652134757208e0, 0.0)}, {FN (arg), ARG(1.19209289550781250e-07,1.0e+00), RES(1.5707962075856070685e0, 0.0)}, {FN (arg), ARG(1.19209289550781250e-07,-1.0e+00), RES(-1.5707962075856070685e0, 0.0)}, {FN (arg), ARG(-1.19209289550781250e-07,1.0e+00), RES(1.570796446004186170e0, 0.0)}, {FN (arg), ARG(-1.19209289550781250e-07,-1.0e+00), RES(-1.570796446004186170e0, 0.0)}, {FN (arg), ARG(1.19209289550781250e-07,2.0e+00), RES(1.5707962671902518438e0, 0.0)}, {FN (arg), ARG(1.19209289550781250e-07,-2.0e+00), RES(-1.5707962671902518438e0, 0.0)}, {FN (arg), ARG(-1.19209289550781250e-07,2.0e+00), RES(1.5707963863995413946e0, 0.0)}, {FN (arg), ARG(-1.19209289550781250e-07,-2.0e+00), RES(-1.5707963863995413946e0, 0.0)}, {FN (arg), ARG(1.19209289550781250e-07,8.3886080e+06), RES(1.5707963267948824084e0, 0.0)}, {FN (arg), ARG(1.19209289550781250e-07,-8.3886080e+06), RES(-1.5707963267948824084e0, 0.0)}, {FN (arg), ARG(-1.19209289550781250e-07,8.3886080e+06), RES(1.5707963267949108301e0, 0.0)}, {FN (arg), ARG(-1.19209289550781250e-07,-8.3886080e+06), RES(-1.5707963267949108301e0, 0.0)}, {FN (arg), ARG(5.0e-01,0.0e+00), RES(0e0, 0.0)}, {FN (arg), ARG(-5.0e-01,0.0e+00), RES(3.1415926535897932385e0, 0.0)}, {FN (arg), ARG(5.0e-01,1.19209289550781250e-07), RES(2.3841857910155798249e-7, 0.0)}, {FN (arg), ARG(5.0e-01,-1.19209289550781250e-07), RES(-2.3841857910155798249e-7, 0.0)}, {FN (arg), ARG(-5.0e-01,1.19209289550781250e-07), RES(3.1415924151712141369e0, 0.0)}, {FN (arg), ARG(-5.0e-01,-1.19209289550781250e-07), RES(-3.1415924151712141369e0, 0.0)}, {FN (arg), ARG(5.0e-01,5.0e-01), RES(7.8539816339744830962e-1, 0.0)}, {FN (arg), ARG(5.0e-01,-5.0e-01), RES(-7.8539816339744830962e-1, 0.0)}, {FN (arg), ARG(-5.0e-01,5.0e-01), RES(2.3561944901923449288e0, 0.0)}, {FN (arg), ARG(-5.0e-01,-5.0e-01), RES(-2.3561944901923449288e0, 0.0)}, {FN (arg), ARG(5.0e-01,1.0e+00), RES(1.1071487177940905030e0, 0.0)}, {FN (arg), ARG(5.0e-01,-1.0e+00), RES(-1.1071487177940905030e0, 0.0)}, {FN (arg), ARG(-5.0e-01,1.0e+00), RES(2.0344439357957027354e0, 0.0)}, {FN (arg), ARG(-5.0e-01,-1.0e+00), RES(-2.0344439357957027354e0, 0.0)}, {FN (arg), ARG(5.0e-01,2.0e+00), RES(1.3258176636680324651e0, 0.0)}, {FN (arg), ARG(5.0e-01,-2.0e+00), RES(-1.3258176636680324651e0, 0.0)}, {FN (arg), ARG(-5.0e-01,2.0e+00), RES(1.8157749899217607734e0, 0.0)}, {FN (arg), ARG(-5.0e-01,-2.0e+00), RES(-1.8157749899217607734e0, 0.0)}, {FN (arg), ARG(5.0e-01,8.3886080e+06), RES(1.5707962671902518438e0, 0.0)}, {FN (arg), ARG(5.0e-01,-8.3886080e+06), RES(-1.5707962671902518438e0, 0.0)}, {FN (arg), ARG(-5.0e-01,8.3886080e+06), RES(1.5707963863995413946e0, 0.0)}, {FN (arg), ARG(-5.0e-01,-8.3886080e+06), RES(-1.5707963863995413946e0, 0.0)}, {FN (arg), ARG(1.0e+00,0.0e+00), RES(0e0, 0.0)}, {FN (arg), ARG(-1.0e+00,0.0e+00), RES(3.1415926535897932385e0, 0.0)}, {FN (arg), ARG(1.0e+00,1.19209289550781250e-07), RES(1.1920928955078068531e-7, 0.0)}, {FN (arg), ARG(1.0e+00,-1.19209289550781250e-07), RES(-1.1920928955078068531e-7, 0.0)}, {FN (arg), ARG(-1.0e+00,1.19209289550781250e-07), RES(3.1415925343805036877e0, 0.0)}, {FN (arg), ARG(-1.0e+00,-1.19209289550781250e-07), RES(-3.1415925343805036877e0, 0.0)}, {FN (arg), ARG(1.0e+00,5.0e-01), RES(4.6364760900080611621e-1, 0.0)}, {FN (arg), ARG(1.0e+00,-5.0e-01), RES(-4.6364760900080611621e-1, 0.0)}, {FN (arg), ARG(-1.0e+00,5.0e-01), RES(2.6779450445889871222e0, 0.0)}, {FN (arg), ARG(-1.0e+00,-5.0e-01), RES(-2.6779450445889871222e0, 0.0)}, {FN (arg), ARG(1.0e+00,1.0e+00), RES(7.8539816339744830962e-1, 0.0)}, {FN (arg), ARG(1.0e+00,-1.0e+00), RES(-7.8539816339744830962e-1, 0.0)}, {FN (arg), ARG(-1.0e+00,1.0e+00), RES(2.3561944901923449288e0, 0.0)}, {FN (arg), ARG(-1.0e+00,-1.0e+00), RES(-2.3561944901923449288e0, 0.0)}, {FN (arg), ARG(1.0e+00,2.0e+00), RES(1.1071487177940905030e0, 0.0)}, {FN (arg), ARG(1.0e+00,-2.0e+00), RES(-1.1071487177940905030e0, 0.0)}, {FN (arg), ARG(-1.0e+00,2.0e+00), RES(2.0344439357957027354e0, 0.0)}, {FN (arg), ARG(-1.0e+00,-2.0e+00), RES(-2.0344439357957027354e0, 0.0)}, {FN (arg), ARG(1.0e+00,8.3886080e+06), RES(1.5707962075856070685e0, 0.0)}, {FN (arg), ARG(1.0e+00,-8.3886080e+06), RES(-1.5707962075856070685e0, 0.0)}, {FN (arg), ARG(-1.0e+00,8.3886080e+06), RES(1.570796446004186170e0, 0.0)}, {FN (arg), ARG(-1.0e+00,-8.3886080e+06), RES(-1.570796446004186170e0, 0.0)}, {FN (arg), ARG(2.0e+00,0.0e+00), RES(0e0, 0.0)}, {FN (arg), ARG(-2.0e+00,0.0e+00), RES(3.1415926535897932385e0, 0.0)}, {FN (arg), ARG(2.0e+00,1.19209289550781250e-07), RES(5.9604644775390554414e-8, 0.0)}, {FN (arg), ARG(2.0e+00,-1.19209289550781250e-07), RES(-5.9604644775390554414e-8, 0.0)}, {FN (arg), ARG(-2.0e+00,1.19209289550781250e-07), RES(3.1415925939851484631e0, 0.0)}, {FN (arg), ARG(-2.0e+00,-1.19209289550781250e-07), RES(-3.1415925939851484631e0, 0.0)}, {FN (arg), ARG(2.0e+00,5.0e-01), RES(2.4497866312686415417e-1, 0.0)}, {FN (arg), ARG(2.0e+00,-5.0e-01), RES(-2.4497866312686415417e-1, 0.0)}, {FN (arg), ARG(-2.0e+00,5.0e-01), RES(2.8966139904629290843e0, 0.0)}, {FN (arg), ARG(-2.0e+00,-5.0e-01), RES(-2.8966139904629290843e0, 0.0)}, {FN (arg), ARG(2.0e+00,1.0e+00), RES(4.6364760900080611621e-1, 0.0)}, {FN (arg), ARG(2.0e+00,-1.0e+00), RES(-4.6364760900080611621e-1, 0.0)}, {FN (arg), ARG(-2.0e+00,1.0e+00), RES(2.6779450445889871222e0, 0.0)}, {FN (arg), ARG(-2.0e+00,-1.0e+00), RES(-2.6779450445889871222e0, 0.0)}, {FN (arg), ARG(2.0e+00,2.0e+00), RES(7.8539816339744830962e-1, 0.0)}, {FN (arg), ARG(2.0e+00,-2.0e+00), RES(-7.8539816339744830962e-1, 0.0)}, {FN (arg), ARG(-2.0e+00,2.0e+00), RES(2.3561944901923449288e0, 0.0)}, {FN (arg), ARG(-2.0e+00,-2.0e+00), RES(-2.3561944901923449288e0, 0.0)}, {FN (arg), ARG(2.0e+00,8.3886080e+06), RES(1.5707960883763175177e0, 0.0)}, {FN (arg), ARG(2.0e+00,-8.3886080e+06), RES(-1.5707960883763175177e0, 0.0)}, {FN (arg), ARG(-2.0e+00,8.3886080e+06), RES(1.5707965652134757208e0, 0.0)}, {FN (arg), ARG(-2.0e+00,-8.3886080e+06), RES(-1.5707965652134757208e0, 0.0)}, {FN (arg), ARG(8.3886080e+06,0.0e+00), RES(0e0, 0.0)}, {FN (arg), ARG(-8.3886080e+06,0.0e+00), RES(3.1415926535897932385e0, 0.0)}, {FN (arg), ARG(8.3886080e+06,1.19209289550781250e-07), RES(1.4210854715202003717e-14, 0.0)}, {FN (arg), ARG(8.3886080e+06,-1.19209289550781250e-07), RES(-1.4210854715202003717e-14, 0.0)}, {FN (arg), ARG(-8.3886080e+06,1.19209289550781250e-07), RES(3.1415926535897790276e0, 0.0)}, {FN (arg), ARG(-8.3886080e+06,-1.19209289550781250e-07), RES(-3.1415926535897790276e0, 0.0)}, {FN (arg), ARG(8.3886080e+06,5.0e-01), RES(5.9604644775390554414e-8, 0.0)}, {FN (arg), ARG(8.3886080e+06,-5.0e-01), RES(-5.9604644775390554414e-8, 0.0)}, {FN (arg), ARG(-8.3886080e+06,5.0e-01), RES(3.1415925939851484631e0, 0.0)}, {FN (arg), ARG(-8.3886080e+06,-5.0e-01), RES(-3.1415925939851484631e0, 0.0)}, {FN (arg), ARG(8.3886080e+06,1.0e+00), RES(1.1920928955078068531e-7, 0.0)}, {FN (arg), ARG(8.3886080e+06,-1.0e+00), RES(-1.1920928955078068531e-7, 0.0)}, {FN (arg), ARG(-8.3886080e+06,1.0e+00), RES(3.1415925343805036877e0, 0.0)}, {FN (arg), ARG(-8.3886080e+06,-1.0e+00), RES(-3.1415925343805036877e0, 0.0)}, {FN (arg), ARG(8.3886080e+06,2.0e+00), RES(2.3841857910155798249e-7, 0.0)}, {FN (arg), ARG(8.3886080e+06,-2.0e+00), RES(-2.3841857910155798249e-7, 0.0)}, {FN (arg), ARG(-8.3886080e+06,2.0e+00), RES(3.1415924151712141369e0, 0.0)}, {FN (arg), ARG(-8.3886080e+06,-2.0e+00), RES(-3.1415924151712141369e0, 0.0)}, {FN (arg), ARG(8.3886080e+06,8.3886080e+06), RES(7.8539816339744830962e-1, 0.0)}, {FN (arg), ARG(8.3886080e+06,-8.3886080e+06), RES(-7.8539816339744830962e-1, 0.0)}, {FN (arg), ARG(-8.3886080e+06,8.3886080e+06), RES(2.3561944901923449288e0, 0.0)}, {FN (arg), ARG(-8.3886080e+06,-8.3886080e+06), RES(-2.3561944901923449288e0, 0.0)}, {FN (abs), ARG(0.0e+00,0.0e+00), RES(0e0, 0.0)}, {FN (abs), ARG(0.0e+00,1.19209289550781250e-07), RES(1.1920928955078125e-7, 0.0)}, {FN (abs), ARG(0.0e+00,-1.19209289550781250e-07), RES(1.1920928955078125e-7, 0.0)}, {FN (abs), ARG(0.0e+00,5.0e-01), RES(5e-1, 0.0)}, {FN (abs), ARG(0.0e+00,-5.0e-01), RES(5e-1, 0.0)}, {FN (abs), ARG(0.0e+00,1.0e+00), RES(1e0, 0.0)}, {FN (abs), ARG(0.0e+00,-1.0e+00), RES(1e0, 0.0)}, {FN (abs), ARG(0.0e+00,2.0e+00), RES(2e0, 0.0)}, {FN (abs), ARG(0.0e+00,-2.0e+00), RES(2e0, 0.0)}, {FN (abs), ARG(0.0e+00,8.3886080e+06), RES(8.388608e6, 0.0)}, {FN (abs), ARG(0.0e+00,-8.3886080e+06), RES(8.388608e6, 0.0)}, {FN (abs), ARG(1.19209289550781250e-07,0.0e+00), RES(1.1920928955078125e-7, 0.0)}, {FN (abs), ARG(-1.19209289550781250e-07,0.0e+00), RES(1.1920928955078125e-7, 0.0)}, {FN (abs), ARG(1.19209289550781250e-07,1.19209289550781250e-07), RES(1.6858739404357612715e-7, 0.0)}, {FN (abs), ARG(1.19209289550781250e-07,-1.19209289550781250e-07), RES(1.6858739404357612715e-7, 0.0)}, {FN (abs), ARG(-1.19209289550781250e-07,1.19209289550781250e-07), RES(1.6858739404357612715e-7, 0.0)}, {FN (abs), ARG(-1.19209289550781250e-07,-1.19209289550781250e-07), RES(1.6858739404357612715e-7, 0.0)}, {FN (abs), ARG(1.19209289550781250e-07,5.0e-01), RES(5.0000000000001421085e-1, 0.0)}, {FN (abs), ARG(1.19209289550781250e-07,-5.0e-01), RES(5.0000000000001421085e-1, 0.0)}, {FN (abs), ARG(-1.19209289550781250e-07,5.0e-01), RES(5.0000000000001421085e-1, 0.0)}, {FN (abs), ARG(-1.19209289550781250e-07,-5.0e-01), RES(5.0000000000001421085e-1, 0.0)}, {FN (abs), ARG(1.19209289550781250e-07,1.0e+00), RES(1.0000000000000071054e0, 0.0)}, {FN (abs), ARG(1.19209289550781250e-07,-1.0e+00), RES(1.0000000000000071054e0, 0.0)}, {FN (abs), ARG(-1.19209289550781250e-07,1.0e+00), RES(1.0000000000000071054e0, 0.0)}, {FN (abs), ARG(-1.19209289550781250e-07,-1.0e+00), RES(1.0000000000000071054e0, 0.0)}, {FN (abs), ARG(1.19209289550781250e-07,2.0e+00), RES(2.0000000000000035527e0, 0.0)}, {FN (abs), ARG(1.19209289550781250e-07,-2.0e+00), RES(2.0000000000000035527e0, 0.0)}, {FN (abs), ARG(-1.19209289550781250e-07,2.0e+00), RES(2.0000000000000035527e0, 0.0)}, {FN (abs), ARG(-1.19209289550781250e-07,-2.0e+00), RES(2.0000000000000035527e0, 0.0)}, {FN (abs), ARG(1.19209289550781250e-07,8.3886080e+06), RES(8.3886080e6, 0.0)}, {FN (abs), ARG(1.19209289550781250e-07,-8.3886080e+06), RES(8.3886080e6, 0.0)}, {FN (abs), ARG(-1.19209289550781250e-07,8.3886080e+06), RES(8.3886080e6, 0.0)}, {FN (abs), ARG(-1.19209289550781250e-07,-8.3886080e+06), RES(8.3886080e6, 0.0)}, {FN (abs), ARG(5.0e-01,0.0e+00), RES(5e-1, 0.0)}, {FN (abs), ARG(-5.0e-01,0.0e+00), RES(5e-1, 0.0)}, {FN (abs), ARG(5.0e-01,1.19209289550781250e-07), RES(5.0000000000001421085e-1, 0.0)}, {FN (abs), ARG(5.0e-01,-1.19209289550781250e-07), RES(5.0000000000001421085e-1, 0.0)}, {FN (abs), ARG(-5.0e-01,1.19209289550781250e-07), RES(5.0000000000001421085e-1, 0.0)}, {FN (abs), ARG(-5.0e-01,-1.19209289550781250e-07), RES(5.0000000000001421085e-1, 0.0)}, {FN (abs), ARG(5.0e-01,5.0e-01), RES(7.0710678118654752440e-1, 0.0)}, {FN (abs), ARG(5.0e-01,-5.0e-01), RES(7.0710678118654752440e-1, 0.0)}, {FN (abs), ARG(-5.0e-01,5.0e-01), RES(7.0710678118654752440e-1, 0.0)}, {FN (abs), ARG(-5.0e-01,-5.0e-01), RES(7.0710678118654752440e-1, 0.0)}, {FN (abs), ARG(5.0e-01,1.0e+00), RES(1.1180339887498948482e0, 0.0)}, {FN (abs), ARG(5.0e-01,-1.0e+00), RES(1.1180339887498948482e0, 0.0)}, {FN (abs), ARG(-5.0e-01,1.0e+00), RES(1.1180339887498948482e0, 0.0)}, {FN (abs), ARG(-5.0e-01,-1.0e+00), RES(1.1180339887498948482e0, 0.0)}, {FN (abs), ARG(5.0e-01,2.0e+00), RES(2.0615528128088302749e0, 0.0)}, {FN (abs), ARG(5.0e-01,-2.0e+00), RES(2.0615528128088302749e0, 0.0)}, {FN (abs), ARG(-5.0e-01,2.0e+00), RES(2.0615528128088302749e0, 0.0)}, {FN (abs), ARG(-5.0e-01,-2.0e+00), RES(2.0615528128088302749e0, 0.0)}, {FN (abs), ARG(5.0e-01,8.3886080e+06), RES(8.3886080000000149012e6, 0.0)}, {FN (abs), ARG(5.0e-01,-8.3886080e+06), RES(8.3886080000000149012e6, 0.0)}, {FN (abs), ARG(-5.0e-01,8.3886080e+06), RES(8.3886080000000149012e6, 0.0)}, {FN (abs), ARG(-5.0e-01,-8.3886080e+06), RES(8.3886080000000149012e6, 0.0)}, {FN (abs), ARG(1.0e+00,0.0e+00), RES(1e0, 0.0)}, {FN (abs), ARG(-1.0e+00,0.0e+00), RES(1e0, 0.0)}, {FN (abs), ARG(1.0e+00,1.19209289550781250e-07), RES(1.0000000000000071054e0, 0.0)}, {FN (abs), ARG(1.0e+00,-1.19209289550781250e-07), RES(1.0000000000000071054e0, 0.0)}, {FN (abs), ARG(-1.0e+00,1.19209289550781250e-07), RES(1.0000000000000071054e0, 0.0)}, {FN (abs), ARG(-1.0e+00,-1.19209289550781250e-07), RES(1.0000000000000071054e0, 0.0)}, {FN (abs), ARG(1.0e+00,5.0e-01), RES(1.1180339887498948482e0, 0.0)}, {FN (abs), ARG(1.0e+00,-5.0e-01), RES(1.1180339887498948482e0, 0.0)}, {FN (abs), ARG(-1.0e+00,5.0e-01), RES(1.1180339887498948482e0, 0.0)}, {FN (abs), ARG(-1.0e+00,-5.0e-01), RES(1.1180339887498948482e0, 0.0)}, {FN (abs), ARG(1.0e+00,1.0e+00), RES(1.4142135623730950488e0, 0.0)}, {FN (abs), ARG(1.0e+00,-1.0e+00), RES(1.4142135623730950488e0, 0.0)}, {FN (abs), ARG(-1.0e+00,1.0e+00), RES(1.4142135623730950488e0, 0.0)}, {FN (abs), ARG(-1.0e+00,-1.0e+00), RES(1.4142135623730950488e0, 0.0)}, {FN (abs), ARG(1.0e+00,2.0e+00), RES(2.2360679774997896964e0, 0.0)}, {FN (abs), ARG(1.0e+00,-2.0e+00), RES(2.2360679774997896964e0, 0.0)}, {FN (abs), ARG(-1.0e+00,2.0e+00), RES(2.2360679774997896964e0, 0.0)}, {FN (abs), ARG(-1.0e+00,-2.0e+00), RES(2.2360679774997896964e0, 0.0)}, {FN (abs), ARG(1.0e+00,8.3886080e+06), RES(8.3886080000000596046e6, 0.0)}, {FN (abs), ARG(1.0e+00,-8.3886080e+06), RES(8.3886080000000596046e6, 0.0)}, {FN (abs), ARG(-1.0e+00,8.3886080e+06), RES(8.3886080000000596046e6, 0.0)}, {FN (abs), ARG(-1.0e+00,-8.3886080e+06), RES(8.3886080000000596046e6, 0.0)}, {FN (abs), ARG(2.0e+00,0.0e+00), RES(2e0, 0.0)}, {FN (abs), ARG(-2.0e+00,0.0e+00), RES(2e0, 0.0)}, {FN (abs), ARG(2.0e+00,1.19209289550781250e-07), RES(2.0000000000000035527e0, 0.0)}, {FN (abs), ARG(2.0e+00,-1.19209289550781250e-07), RES(2.0000000000000035527e0, 0.0)}, {FN (abs), ARG(-2.0e+00,1.19209289550781250e-07), RES(2.0000000000000035527e0, 0.0)}, {FN (abs), ARG(-2.0e+00,-1.19209289550781250e-07), RES(2.0000000000000035527e0, 0.0)}, {FN (abs), ARG(2.0e+00,5.0e-01), RES(2.0615528128088302749e0, 0.0)}, {FN (abs), ARG(2.0e+00,-5.0e-01), RES(2.0615528128088302749e0, 0.0)}, {FN (abs), ARG(-2.0e+00,5.0e-01), RES(2.0615528128088302749e0, 0.0)}, {FN (abs), ARG(-2.0e+00,-5.0e-01), RES(2.0615528128088302749e0, 0.0)}, {FN (abs), ARG(2.0e+00,1.0e+00), RES(2.2360679774997896964e0, 0.0)}, {FN (abs), ARG(2.0e+00,-1.0e+00), RES(2.2360679774997896964e0, 0.0)}, {FN (abs), ARG(-2.0e+00,1.0e+00), RES(2.2360679774997896964e0, 0.0)}, {FN (abs), ARG(-2.0e+00,-1.0e+00), RES(2.2360679774997896964e0, 0.0)}, {FN (abs), ARG(2.0e+00,2.0e+00), RES(2.8284271247461900976e0, 0.0)}, {FN (abs), ARG(2.0e+00,-2.0e+00), RES(2.8284271247461900976e0, 0.0)}, {FN (abs), ARG(-2.0e+00,2.0e+00), RES(2.8284271247461900976e0, 0.0)}, {FN (abs), ARG(-2.0e+00,-2.0e+00), RES(2.8284271247461900976e0, 0.0)}, {FN (abs), ARG(2.0e+00,8.3886080e+06), RES(8.3886080000002384186e6, 0.0)}, {FN (abs), ARG(2.0e+00,-8.3886080e+06), RES(8.3886080000002384186e6, 0.0)}, {FN (abs), ARG(-2.0e+00,8.3886080e+06), RES(8.3886080000002384186e6, 0.0)}, {FN (abs), ARG(-2.0e+00,-8.3886080e+06), RES(8.3886080000002384186e6, 0.0)}, {FN (abs), ARG(8.3886080e+06,0.0e+00), RES(8.388608e6, 0.0)}, {FN (abs), ARG(-8.3886080e+06,0.0e+00), RES(8.388608e6, 0.0)}, {FN (abs), ARG(8.3886080e+06,1.19209289550781250e-07), RES(8.3886080e6, 0.0)}, {FN (abs), ARG(8.3886080e+06,-1.19209289550781250e-07), RES(8.3886080e6, 0.0)}, {FN (abs), ARG(-8.3886080e+06,1.19209289550781250e-07), RES(8.3886080e6, 0.0)}, {FN (abs), ARG(-8.3886080e+06,-1.19209289550781250e-07), RES(8.3886080e6, 0.0)}, {FN (abs), ARG(8.3886080e+06,5.0e-01), RES(8.3886080000000149012e6, 0.0)}, {FN (abs), ARG(8.3886080e+06,-5.0e-01), RES(8.3886080000000149012e6, 0.0)}, {FN (abs), ARG(-8.3886080e+06,5.0e-01), RES(8.3886080000000149012e6, 0.0)}, {FN (abs), ARG(-8.3886080e+06,-5.0e-01), RES(8.3886080000000149012e6, 0.0)}, {FN (abs), ARG(8.3886080e+06,1.0e+00), RES(8.3886080000000596046e6, 0.0)}, {FN (abs), ARG(8.3886080e+06,-1.0e+00), RES(8.3886080000000596046e6, 0.0)}, {FN (abs), ARG(-8.3886080e+06,1.0e+00), RES(8.3886080000000596046e6, 0.0)}, {FN (abs), ARG(-8.3886080e+06,-1.0e+00), RES(8.3886080000000596046e6, 0.0)}, {FN (abs), ARG(8.3886080e+06,2.0e+00), RES(8.3886080000002384186e6, 0.0)}, {FN (abs), ARG(8.3886080e+06,-2.0e+00), RES(8.3886080000002384186e6, 0.0)}, {FN (abs), ARG(-8.3886080e+06,2.0e+00), RES(8.3886080000002384186e6, 0.0)}, {FN (abs), ARG(-8.3886080e+06,-2.0e+00), RES(8.3886080000002384186e6, 0.0)}, {FN (abs), ARG(8.3886080e+06,8.3886080e+06), RES(1.1863283203031444111e7, 0.0)}, {FN (abs), ARG(8.3886080e+06,-8.3886080e+06), RES(1.1863283203031444111e7, 0.0)}, {FN (abs), ARG(-8.3886080e+06,8.3886080e+06), RES(1.1863283203031444111e7, 0.0)}, {FN (abs), ARG(-8.3886080e+06,-8.3886080e+06), RES(1.1863283203031444111e7, 0.0)}, {FN (abs2), ARG(0.0e+00,0.0e+00), RES(0e0, 0.0)}, {FN (abs2), ARG(0.0e+00,1.19209289550781250e-07), RES(1.4210854715202003717e-14, 0.0)}, {FN (abs2), ARG(0.0e+00,-1.19209289550781250e-07), RES(1.4210854715202003717e-14, 0.0)}, {FN (abs2), ARG(0.0e+00,5.0e-01), RES(2.5e-1, 0.0)}, {FN (abs2), ARG(0.0e+00,-5.0e-01), RES(2.5e-1, 0.0)}, {FN (abs2), ARG(0.0e+00,1.0e+00), RES(1e0, 0.0)}, {FN (abs2), ARG(0.0e+00,-1.0e+00), RES(1e0, 0.0)}, {FN (abs2), ARG(0.0e+00,2.0e+00), RES(4e0, 0.0)}, {FN (abs2), ARG(0.0e+00,-2.0e+00), RES(4e0, 0.0)}, {FN (abs2), ARG(0.0e+00,8.3886080e+06), RES(7.0368744177664e13, 0.0)}, {FN (abs2), ARG(0.0e+00,-8.3886080e+06), RES(7.0368744177664e13, 0.0)}, {FN (abs2), ARG(1.19209289550781250e-07,0.0e+00), RES(1.4210854715202003717e-14, 0.0)}, {FN (abs2), ARG(-1.19209289550781250e-07,0.0e+00), RES(1.4210854715202003717e-14, 0.0)}, {FN (abs2), ARG(1.19209289550781250e-07,1.19209289550781250e-07), RES(2.8421709430404007435e-14, 0.0)}, {FN (abs2), ARG(1.19209289550781250e-07,-1.19209289550781250e-07), RES(2.8421709430404007435e-14, 0.0)}, {FN (abs2), ARG(-1.19209289550781250e-07,1.19209289550781250e-07), RES(2.8421709430404007435e-14, 0.0)}, {FN (abs2), ARG(-1.19209289550781250e-07,-1.19209289550781250e-07), RES(2.8421709430404007435e-14, 0.0)}, {FN (abs2), ARG(1.19209289550781250e-07,5.0e-01), RES(2.5000000000001421085e-1, 0.0)}, {FN (abs2), ARG(1.19209289550781250e-07,-5.0e-01), RES(2.5000000000001421085e-1, 0.0)}, {FN (abs2), ARG(-1.19209289550781250e-07,5.0e-01), RES(2.5000000000001421085e-1, 0.0)}, {FN (abs2), ARG(-1.19209289550781250e-07,-5.0e-01), RES(2.5000000000001421085e-1, 0.0)}, {FN (abs2), ARG(1.19209289550781250e-07,1.0e+00), RES(1.0000000000000142109e0, 0.0)}, {FN (abs2), ARG(1.19209289550781250e-07,-1.0e+00), RES(1.0000000000000142109e0, 0.0)}, {FN (abs2), ARG(-1.19209289550781250e-07,1.0e+00), RES(1.0000000000000142109e0, 0.0)}, {FN (abs2), ARG(-1.19209289550781250e-07,-1.0e+00), RES(1.0000000000000142109e0, 0.0)}, {FN (abs2), ARG(1.19209289550781250e-07,2.0e+00), RES(4.0000000000000142109e0, 0.0)}, {FN (abs2), ARG(1.19209289550781250e-07,-2.0e+00), RES(4.0000000000000142109e0, 0.0)}, {FN (abs2), ARG(-1.19209289550781250e-07,2.0e+00), RES(4.0000000000000142109e0, 0.0)}, {FN (abs2), ARG(-1.19209289550781250e-07,-2.0e+00), RES(4.0000000000000142109e0, 0.0)}, {FN (abs2), ARG(1.19209289550781250e-07,8.3886080e+06), RES(7.03687441776640e13, 0.0)}, {FN (abs2), ARG(1.19209289550781250e-07,-8.3886080e+06), RES(7.03687441776640e13, 0.0)}, {FN (abs2), ARG(-1.19209289550781250e-07,8.3886080e+06), RES(7.03687441776640e13, 0.0)}, {FN (abs2), ARG(-1.19209289550781250e-07,-8.3886080e+06), RES(7.03687441776640e13, 0.0)}, {FN (abs2), ARG(5.0e-01,0.0e+00), RES(2.5e-1, 0.0)}, {FN (abs2), ARG(-5.0e-01,0.0e+00), RES(2.5e-1, 0.0)}, {FN (abs2), ARG(5.0e-01,1.19209289550781250e-07), RES(2.5000000000001421085e-1, 0.0)}, {FN (abs2), ARG(5.0e-01,-1.19209289550781250e-07), RES(2.5000000000001421085e-1, 0.0)}, {FN (abs2), ARG(-5.0e-01,1.19209289550781250e-07), RES(2.5000000000001421085e-1, 0.0)}, {FN (abs2), ARG(-5.0e-01,-1.19209289550781250e-07), RES(2.5000000000001421085e-1, 0.0)}, {FN (abs2), ARG(5.0e-01,5.0e-01), RES(5e-1, 0.0)}, {FN (abs2), ARG(5.0e-01,-5.0e-01), RES(5e-1, 0.0)}, {FN (abs2), ARG(-5.0e-01,5.0e-01), RES(5e-1, 0.0)}, {FN (abs2), ARG(-5.0e-01,-5.0e-01), RES(5e-1, 0.0)}, {FN (abs2), ARG(5.0e-01,1.0e+00), RES(1.25e0, 0.0)}, {FN (abs2), ARG(5.0e-01,-1.0e+00), RES(1.25e0, 0.0)}, {FN (abs2), ARG(-5.0e-01,1.0e+00), RES(1.25e0, 0.0)}, {FN (abs2), ARG(-5.0e-01,-1.0e+00), RES(1.25e0, 0.0)}, {FN (abs2), ARG(5.0e-01,2.0e+00), RES(4.25e0, 0.0)}, {FN (abs2), ARG(5.0e-01,-2.0e+00), RES(4.25e0, 0.0)}, {FN (abs2), ARG(-5.0e-01,2.0e+00), RES(4.25e0, 0.0)}, {FN (abs2), ARG(-5.0e-01,-2.0e+00), RES(4.25e0, 0.0)}, {FN (abs2), ARG(5.0e-01,8.3886080e+06), RES(7.036874417766425e13, 0.0)}, {FN (abs2), ARG(5.0e-01,-8.3886080e+06), RES(7.036874417766425e13, 0.0)}, {FN (abs2), ARG(-5.0e-01,8.3886080e+06), RES(7.036874417766425e13, 0.0)}, {FN (abs2), ARG(-5.0e-01,-8.3886080e+06), RES(7.036874417766425e13, 0.0)}, {FN (abs2), ARG(1.0e+00,0.0e+00), RES(1e0, 0.0)}, {FN (abs2), ARG(-1.0e+00,0.0e+00), RES(1e0, 0.0)}, {FN (abs2), ARG(1.0e+00,1.19209289550781250e-07), RES(1.0000000000000142109e0, 0.0)}, {FN (abs2), ARG(1.0e+00,-1.19209289550781250e-07), RES(1.0000000000000142109e0, 0.0)}, {FN (abs2), ARG(-1.0e+00,1.19209289550781250e-07), RES(1.0000000000000142109e0, 0.0)}, {FN (abs2), ARG(-1.0e+00,-1.19209289550781250e-07), RES(1.0000000000000142109e0, 0.0)}, {FN (abs2), ARG(1.0e+00,5.0e-01), RES(1.25e0, 0.0)}, {FN (abs2), ARG(1.0e+00,-5.0e-01), RES(1.25e0, 0.0)}, {FN (abs2), ARG(-1.0e+00,5.0e-01), RES(1.25e0, 0.0)}, {FN (abs2), ARG(-1.0e+00,-5.0e-01), RES(1.25e0, 0.0)}, {FN (abs2), ARG(1.0e+00,1.0e+00), RES(2e0, 0.0)}, {FN (abs2), ARG(1.0e+00,-1.0e+00), RES(2e0, 0.0)}, {FN (abs2), ARG(-1.0e+00,1.0e+00), RES(2e0, 0.0)}, {FN (abs2), ARG(-1.0e+00,-1.0e+00), RES(2e0, 0.0)}, {FN (abs2), ARG(1.0e+00,2.0e+00), RES(5e0, 0.0)}, {FN (abs2), ARG(1.0e+00,-2.0e+00), RES(5e0, 0.0)}, {FN (abs2), ARG(-1.0e+00,2.0e+00), RES(5e0, 0.0)}, {FN (abs2), ARG(-1.0e+00,-2.0e+00), RES(5e0, 0.0)}, {FN (abs2), ARG(1.0e+00,8.3886080e+06), RES(7.0368744177665e13, 0.0)}, {FN (abs2), ARG(1.0e+00,-8.3886080e+06), RES(7.0368744177665e13, 0.0)}, {FN (abs2), ARG(-1.0e+00,8.3886080e+06), RES(7.0368744177665e13, 0.0)}, {FN (abs2), ARG(-1.0e+00,-8.3886080e+06), RES(7.0368744177665e13, 0.0)}, {FN (abs2), ARG(2.0e+00,0.0e+00), RES(4e0, 0.0)}, {FN (abs2), ARG(-2.0e+00,0.0e+00), RES(4e0, 0.0)}, {FN (abs2), ARG(2.0e+00,1.19209289550781250e-07), RES(4.0000000000000142109e0, 0.0)}, {FN (abs2), ARG(2.0e+00,-1.19209289550781250e-07), RES(4.0000000000000142109e0, 0.0)}, {FN (abs2), ARG(-2.0e+00,1.19209289550781250e-07), RES(4.0000000000000142109e0, 0.0)}, {FN (abs2), ARG(-2.0e+00,-1.19209289550781250e-07), RES(4.0000000000000142109e0, 0.0)}, {FN (abs2), ARG(2.0e+00,5.0e-01), RES(4.25e0, 0.0)}, {FN (abs2), ARG(2.0e+00,-5.0e-01), RES(4.25e0, 0.0)}, {FN (abs2), ARG(-2.0e+00,5.0e-01), RES(4.25e0, 0.0)}, {FN (abs2), ARG(-2.0e+00,-5.0e-01), RES(4.25e0, 0.0)}, {FN (abs2), ARG(2.0e+00,1.0e+00), RES(5e0, 0.0)}, {FN (abs2), ARG(2.0e+00,-1.0e+00), RES(5e0, 0.0)}, {FN (abs2), ARG(-2.0e+00,1.0e+00), RES(5e0, 0.0)}, {FN (abs2), ARG(-2.0e+00,-1.0e+00), RES(5e0, 0.0)}, {FN (abs2), ARG(2.0e+00,2.0e+00), RES(8e0, 0.0)}, {FN (abs2), ARG(2.0e+00,-2.0e+00), RES(8e0, 0.0)}, {FN (abs2), ARG(-2.0e+00,2.0e+00), RES(8e0, 0.0)}, {FN (abs2), ARG(-2.0e+00,-2.0e+00), RES(8e0, 0.0)}, {FN (abs2), ARG(2.0e+00,8.3886080e+06), RES(7.0368744177668e13, 0.0)}, {FN (abs2), ARG(2.0e+00,-8.3886080e+06), RES(7.0368744177668e13, 0.0)}, {FN (abs2), ARG(-2.0e+00,8.3886080e+06), RES(7.0368744177668e13, 0.0)}, {FN (abs2), ARG(-2.0e+00,-8.3886080e+06), RES(7.0368744177668e13, 0.0)}, {FN (abs2), ARG(8.3886080e+06,0.0e+00), RES(7.0368744177664e13, 0.0)}, {FN (abs2), ARG(-8.3886080e+06,0.0e+00), RES(7.0368744177664e13, 0.0)}, {FN (abs2), ARG(8.3886080e+06,1.19209289550781250e-07), RES(7.03687441776640e13, 0.0)}, {FN (abs2), ARG(8.3886080e+06,-1.19209289550781250e-07), RES(7.03687441776640e13, 0.0)}, {FN (abs2), ARG(-8.3886080e+06,1.19209289550781250e-07), RES(7.03687441776640e13, 0.0)}, {FN (abs2), ARG(-8.3886080e+06,-1.19209289550781250e-07), RES(7.03687441776640e13, 0.0)}, {FN (abs2), ARG(8.3886080e+06,5.0e-01), RES(7.036874417766425e13, 0.0)}, {FN (abs2), ARG(8.3886080e+06,-5.0e-01), RES(7.036874417766425e13, 0.0)}, {FN (abs2), ARG(-8.3886080e+06,5.0e-01), RES(7.036874417766425e13, 0.0)}, {FN (abs2), ARG(-8.3886080e+06,-5.0e-01), RES(7.036874417766425e13, 0.0)}, {FN (abs2), ARG(8.3886080e+06,1.0e+00), RES(7.0368744177665e13, 0.0)}, {FN (abs2), ARG(8.3886080e+06,-1.0e+00), RES(7.0368744177665e13, 0.0)}, {FN (abs2), ARG(-8.3886080e+06,1.0e+00), RES(7.0368744177665e13, 0.0)}, {FN (abs2), ARG(-8.3886080e+06,-1.0e+00), RES(7.0368744177665e13, 0.0)}, {FN (abs2), ARG(8.3886080e+06,2.0e+00), RES(7.0368744177668e13, 0.0)}, {FN (abs2), ARG(8.3886080e+06,-2.0e+00), RES(7.0368744177668e13, 0.0)}, {FN (abs2), ARG(-8.3886080e+06,2.0e+00), RES(7.0368744177668e13, 0.0)}, {FN (abs2), ARG(-8.3886080e+06,-2.0e+00), RES(7.0368744177668e13, 0.0)}, {FN (abs2), ARG(8.3886080e+06,8.3886080e+06), RES(1.40737488355328e14, 0.0)}, {FN (abs2), ARG(8.3886080e+06,-8.3886080e+06), RES(1.40737488355328e14, 0.0)}, {FN (abs2), ARG(-8.3886080e+06,8.3886080e+06), RES(1.40737488355328e14, 0.0)}, {FN (abs2), ARG(-8.3886080e+06,-8.3886080e+06), RES(1.40737488355328e14, 0.0)}, {FN (logabs), ARG(1.19209289550781250e-07,0.0e+00), RES(-1.5942385152878742117e1, 0.0)}, {FN (logabs), ARG(-1.19209289550781250e-07,0.0e+00), RES(-1.5942385152878742117e1, 0.0)}, {FN (logabs), ARG(1.19209289550781250e-07,1.19209289550781250e-07), RES(-1.5595811562598769462e1, 0.0)}, {FN (logabs), ARG(1.19209289550781250e-07,-1.19209289550781250e-07), RES(-1.5595811562598769462e1, 0.0)}, {FN (logabs), ARG(-1.19209289550781250e-07,1.19209289550781250e-07), RES(-1.5595811562598769462e1, 0.0)}, {FN (logabs), ARG(-1.19209289550781250e-07,-1.19209289550781250e-07), RES(-1.5595811562598769462e1, 0.0)}, {FN (logabs), ARG(1.19209289550781250e-07,5.0e-01), RES(-6.9314718055991688771e-1, 0.0)}, {FN (logabs), ARG(1.19209289550781250e-07,-5.0e-01), RES(-6.9314718055991688771e-1, 0.0)}, {FN (logabs), ARG(-1.19209289550781250e-07,5.0e-01), RES(-6.9314718055991688771e-1, 0.0)}, {FN (logabs), ARG(-1.19209289550781250e-07,-5.0e-01), RES(-6.9314718055991688771e-1, 0.0)}, {FN (logabs), ARG(1.19209289550781250e-07,1.0e+00), RES(7.1054273576009513716e-15, 0.0)}, {FN (logabs), ARG(1.19209289550781250e-07,-1.0e+00), RES(7.1054273576009513716e-15, 0.0)}, {FN (logabs), ARG(-1.19209289550781250e-07,1.0e+00), RES(7.1054273576009513716e-15, 0.0)}, {FN (logabs), ARG(-1.19209289550781250e-07,-1.0e+00), RES(7.1054273576009513716e-15, 0.0)}, {FN (logabs), ARG(1.19209289550781250e-07,2.0e+00), RES(6.9314718055994708577e-1, 0.0)}, {FN (logabs), ARG(1.19209289550781250e-07,-2.0e+00), RES(6.9314718055994708577e-1, 0.0)}, {FN (logabs), ARG(-1.19209289550781250e-07,2.0e+00), RES(6.9314718055994708577e-1, 0.0)}, {FN (logabs), ARG(-1.19209289550781250e-07,-2.0e+00), RES(6.9314718055994708577e-1, 0.0)}, {FN (logabs), ARG(1.19209289550781250e-07,8.3886080e+06), RES(1.5942385152878742117e1, 0.0)}, {FN (logabs), ARG(1.19209289550781250e-07,-8.3886080e+06), RES(1.5942385152878742117e1, 0.0)}, {FN (logabs), ARG(-1.19209289550781250e-07,8.3886080e+06), RES(1.5942385152878742117e1, 0.0)}, {FN (logabs), ARG(-1.19209289550781250e-07,-8.3886080e+06), RES(1.5942385152878742117e1, 0.0)}, {FN (logabs), ARG(5.0e-01,0.0e+00), RES(-6.9314718055994530942e-1, 0.0)}, {FN (logabs), ARG(-5.0e-01,0.0e+00), RES(-6.9314718055994530942e-1, 0.0)}, {FN (logabs), ARG(5.0e-01,1.19209289550781250e-07), RES(-6.9314718055991688771e-1, 0.0)}, {FN (logabs), ARG(5.0e-01,-1.19209289550781250e-07), RES(-6.9314718055991688771e-1, 0.0)}, {FN (logabs), ARG(-5.0e-01,1.19209289550781250e-07), RES(-6.9314718055991688771e-1, 0.0)}, {FN (logabs), ARG(-5.0e-01,-1.19209289550781250e-07), RES(-6.9314718055991688771e-1, 0.0)}, {FN (logabs), ARG(5.0e-01,5.0e-01), RES(-3.4657359027997265471e-1, 0.0)}, {FN (logabs), ARG(5.0e-01,-5.0e-01), RES(-3.4657359027997265471e-1, 0.0)}, {FN (logabs), ARG(-5.0e-01,5.0e-01), RES(-3.4657359027997265471e-1, 0.0)}, {FN (logabs), ARG(-5.0e-01,-5.0e-01), RES(-3.4657359027997265471e-1, 0.0)}, {FN (logabs), ARG(5.0e-01,1.0e+00), RES(1.1157177565710487788e-1, 0.0)}, {FN (logabs), ARG(5.0e-01,-1.0e+00), RES(1.1157177565710487788e-1, 0.0)}, {FN (logabs), ARG(-5.0e-01,1.0e+00), RES(1.1157177565710487788e-1, 0.0)}, {FN (logabs), ARG(-5.0e-01,-1.0e+00), RES(1.1157177565710487788e-1, 0.0)}, {FN (logabs), ARG(5.0e-01,2.0e+00), RES(7.2345949146816273071e-1, 0.0)}, {FN (logabs), ARG(5.0e-01,-2.0e+00), RES(7.2345949146816273071e-1, 0.0)}, {FN (logabs), ARG(-5.0e-01,2.0e+00), RES(7.2345949146816273071e-1, 0.0)}, {FN (logabs), ARG(-5.0e-01,-2.0e+00), RES(7.2345949146816273071e-1, 0.0)}, {FN (logabs), ARG(5.0e-01,8.3886080e+06), RES(1.5942385152878743893e1, 0.0)}, {FN (logabs), ARG(5.0e-01,-8.3886080e+06), RES(1.5942385152878743893e1, 0.0)}, {FN (logabs), ARG(-5.0e-01,8.3886080e+06), RES(1.5942385152878743893e1, 0.0)}, {FN (logabs), ARG(-5.0e-01,-8.3886080e+06), RES(1.5942385152878743893e1, 0.0)}, {FN (logabs), ARG(1.0e+00,0.0e+00), RES(0e0, 0.0)}, {FN (logabs), ARG(-1.0e+00,0.0e+00), RES(0e0, 0.0)}, {FN (logabs), ARG(1.0e+00,1.19209289550781250e-07), RES(7.1054273576009513716e-15, 0.0)}, {FN (logabs), ARG(1.0e+00,-1.19209289550781250e-07), RES(7.1054273576009513716e-15, 0.0)}, {FN (logabs), ARG(-1.0e+00,1.19209289550781250e-07), RES(7.1054273576009513716e-15, 0.0)}, {FN (logabs), ARG(-1.0e+00,-1.19209289550781250e-07), RES(7.1054273576009513716e-15, 0.0)}, {FN (logabs), ARG(1.0e+00,5.0e-01), RES(1.1157177565710487788e-1, 0.0)}, {FN (logabs), ARG(1.0e+00,-5.0e-01), RES(1.1157177565710487788e-1, 0.0)}, {FN (logabs), ARG(-1.0e+00,5.0e-01), RES(1.1157177565710487788e-1, 0.0)}, {FN (logabs), ARG(-1.0e+00,-5.0e-01), RES(1.1157177565710487788e-1, 0.0)}, {FN (logabs), ARG(1.0e+00,1.0e+00), RES(3.4657359027997265471e-1, 0.0)}, {FN (logabs), ARG(1.0e+00,-1.0e+00), RES(3.4657359027997265471e-1, 0.0)}, {FN (logabs), ARG(-1.0e+00,1.0e+00), RES(3.4657359027997265471e-1, 0.0)}, {FN (logabs), ARG(-1.0e+00,-1.0e+00), RES(3.4657359027997265471e-1, 0.0)}, {FN (logabs), ARG(1.0e+00,2.0e+00), RES(8.0471895621705018730e-1, 0.0)}, {FN (logabs), ARG(1.0e+00,-2.0e+00), RES(8.0471895621705018730e-1, 0.0)}, {FN (logabs), ARG(-1.0e+00,2.0e+00), RES(8.0471895621705018730e-1, 0.0)}, {FN (logabs), ARG(-1.0e+00,-2.0e+00), RES(8.0471895621705018730e-1, 0.0)}, {FN (logabs), ARG(1.0e+00,8.3886080e+06), RES(1.5942385152878749222e1, 0.0)}, {FN (logabs), ARG(1.0e+00,-8.3886080e+06), RES(1.5942385152878749222e1, 0.0)}, {FN (logabs), ARG(-1.0e+00,8.3886080e+06), RES(1.5942385152878749222e1, 0.0)}, {FN (logabs), ARG(-1.0e+00,-8.3886080e+06), RES(1.5942385152878749222e1, 0.0)}, {FN (logabs), ARG(2.0e+00,0.0e+00), RES(6.9314718055994530942e-1, 0.0)}, {FN (logabs), ARG(-2.0e+00,0.0e+00), RES(6.9314718055994530942e-1, 0.0)}, {FN (logabs), ARG(2.0e+00,1.19209289550781250e-07), RES(6.9314718055994708577e-1, 0.0)}, {FN (logabs), ARG(2.0e+00,-1.19209289550781250e-07), RES(6.9314718055994708577e-1, 0.0)}, {FN (logabs), ARG(-2.0e+00,1.19209289550781250e-07), RES(6.9314718055994708577e-1, 0.0)}, {FN (logabs), ARG(-2.0e+00,-1.19209289550781250e-07), RES(6.9314718055994708577e-1, 0.0)}, {FN (logabs), ARG(2.0e+00,5.0e-01), RES(7.2345949146816273071e-1, 0.0)}, {FN (logabs), ARG(2.0e+00,-5.0e-01), RES(7.2345949146816273071e-1, 0.0)}, {FN (logabs), ARG(-2.0e+00,5.0e-01), RES(7.2345949146816273071e-1, 0.0)}, {FN (logabs), ARG(-2.0e+00,-5.0e-01), RES(7.2345949146816273071e-1, 0.0)}, {FN (logabs), ARG(2.0e+00,1.0e+00), RES(8.0471895621705018730e-1, 0.0)}, {FN (logabs), ARG(2.0e+00,-1.0e+00), RES(8.0471895621705018730e-1, 0.0)}, {FN (logabs), ARG(-2.0e+00,1.0e+00), RES(8.0471895621705018730e-1, 0.0)}, {FN (logabs), ARG(-2.0e+00,-1.0e+00), RES(8.0471895621705018730e-1, 0.0)}, {FN (logabs), ARG(2.0e+00,2.0e+00), RES(1.0397207708399179641e0, 0.0)}, {FN (logabs), ARG(2.0e+00,-2.0e+00), RES(1.0397207708399179641e0, 0.0)}, {FN (logabs), ARG(-2.0e+00,2.0e+00), RES(1.0397207708399179641e0, 0.0)}, {FN (logabs), ARG(-2.0e+00,-2.0e+00), RES(1.0397207708399179641e0, 0.0)}, {FN (logabs), ARG(2.0e+00,8.3886080e+06), RES(1.5942385152878770538e1, 0.0)}, {FN (logabs), ARG(2.0e+00,-8.3886080e+06), RES(1.5942385152878770538e1, 0.0)}, {FN (logabs), ARG(-2.0e+00,8.3886080e+06), RES(1.5942385152878770538e1, 0.0)}, {FN (logabs), ARG(-2.0e+00,-8.3886080e+06), RES(1.5942385152878770538e1, 0.0)}, {FN (logabs), ARG(8.3886080e+06,0.0e+00), RES(1.5942385152878742117e1, 0.0)}, {FN (logabs), ARG(-8.3886080e+06,0.0e+00), RES(1.5942385152878742117e1, 0.0)}, {FN (logabs), ARG(8.3886080e+06,1.19209289550781250e-07), RES(1.5942385152878742117e1, 0.0)}, {FN (logabs), ARG(8.3886080e+06,-1.19209289550781250e-07), RES(1.5942385152878742117e1, 0.0)}, {FN (logabs), ARG(-8.3886080e+06,1.19209289550781250e-07), RES(1.5942385152878742117e1, 0.0)}, {FN (logabs), ARG(-8.3886080e+06,-1.19209289550781250e-07), RES(1.5942385152878742117e1, 0.0)}, {FN (logabs), ARG(8.3886080e+06,5.0e-01), RES(1.5942385152878743893e1, 0.0)}, {FN (logabs), ARG(8.3886080e+06,-5.0e-01), RES(1.5942385152878743893e1, 0.0)}, {FN (logabs), ARG(-8.3886080e+06,5.0e-01), RES(1.5942385152878743893e1, 0.0)}, {FN (logabs), ARG(-8.3886080e+06,-5.0e-01), RES(1.5942385152878743893e1, 0.0)}, {FN (logabs), ARG(8.3886080e+06,1.0e+00), RES(1.5942385152878749222e1, 0.0)}, {FN (logabs), ARG(8.3886080e+06,-1.0e+00), RES(1.5942385152878749222e1, 0.0)}, {FN (logabs), ARG(-8.3886080e+06,1.0e+00), RES(1.5942385152878749222e1, 0.0)}, {FN (logabs), ARG(-8.3886080e+06,-1.0e+00), RES(1.5942385152878749222e1, 0.0)}, {FN (logabs), ARG(8.3886080e+06,2.0e+00), RES(1.5942385152878770538e1, 0.0)}, {FN (logabs), ARG(8.3886080e+06,-2.0e+00), RES(1.5942385152878770538e1, 0.0)}, {FN (logabs), ARG(-8.3886080e+06,2.0e+00), RES(1.5942385152878770538e1, 0.0)}, {FN (logabs), ARG(-8.3886080e+06,-2.0e+00), RES(1.5942385152878770538e1, 0.0)}, {FN (logabs), ARG(8.3886080e+06,8.3886080e+06), RES(1.6288958743158714771e1, 0.0)}, {FN (logabs), ARG(8.3886080e+06,-8.3886080e+06), RES(1.6288958743158714771e1, 0.0)}, {FN (logabs), ARG(-8.3886080e+06,8.3886080e+06), RES(1.6288958743158714771e1, 0.0)}, {FN (logabs), ARG(-8.3886080e+06,-8.3886080e+06), RES(1.6288958743158714771e1, 0.0)}, {FN (logabs), ARG(0.0e+00,1.19209289550781250e-07), RES(-1.5942385152878742117e1, 0.0)}, {FN (logabs), ARG(0.0e+00,-1.19209289550781250e-07), RES(-1.5942385152878742117e1, 0.0)}, {FN (logabs), ARG(0.0e+00,5.0e-01), RES(-6.9314718055994530942e-1, 0.0)}, {FN (logabs), ARG(0.0e+00,-5.0e-01), RES(-6.9314718055994530942e-1, 0.0)}, {FN (logabs), ARG(0.0e+00,1.0e+00), RES(0e0, 0.0)}, {FN (logabs), ARG(0.0e+00,-1.0e+00), RES(0e0, 0.0)}, {FN (logabs), ARG(0.0e+00,2.0e+00), RES(6.9314718055994530942e-1, 0.0)}, {FN (logabs), ARG(0.0e+00,-2.0e+00), RES(6.9314718055994530942e-1, 0.0)}, {FN (logabs), ARG(0.0e+00,8.3886080e+06), RES(1.5942385152878742117e1, 0.0)}, {FN (logabs), ARG(0.0e+00,-8.3886080e+06), RES(1.5942385152878742117e1, 0.0)}, {FN (logabs), ARG(1.19209289550781250e-07,1.19209289550781250e-07), RES(-1.5595811562598769462e1, 0.0)}, {FN (logabs), ARG(1.19209289550781250e-07,-1.19209289550781250e-07), RES(-1.5595811562598769462e1, 0.0)}, {FN (logabs), ARG(-1.19209289550781250e-07,1.19209289550781250e-07), RES(-1.5595811562598769462e1, 0.0)}, {FN (logabs), ARG(-1.19209289550781250e-07,-1.19209289550781250e-07), RES(-1.5595811562598769462e1, 0.0)}, {FN (logabs), ARG(1.19209289550781250e-07,5.0e-01), RES(-6.9314718055991688771e-1, 0.0)}, {FN (logabs), ARG(1.19209289550781250e-07,-5.0e-01), RES(-6.9314718055991688771e-1, 0.0)}, {FN (logabs), ARG(-1.19209289550781250e-07,5.0e-01), RES(-6.9314718055991688771e-1, 0.0)}, {FN (logabs), ARG(-1.19209289550781250e-07,-5.0e-01), RES(-6.9314718055991688771e-1, 0.0)}, {FN (logabs), ARG(1.19209289550781250e-07,1.0e+00), RES(7.1054273576009513716e-15, 0.0)}, {FN (logabs), ARG(1.19209289550781250e-07,-1.0e+00), RES(7.1054273576009513716e-15, 0.0)}, {FN (logabs), ARG(-1.19209289550781250e-07,1.0e+00), RES(7.1054273576009513716e-15, 0.0)}, {FN (logabs), ARG(-1.19209289550781250e-07,-1.0e+00), RES(7.1054273576009513716e-15, 0.0)}, {FN (logabs), ARG(1.19209289550781250e-07,2.0e+00), RES(6.9314718055994708577e-1, 0.0)}, {FN (logabs), ARG(1.19209289550781250e-07,-2.0e+00), RES(6.9314718055994708577e-1, 0.0)}, {FN (logabs), ARG(-1.19209289550781250e-07,2.0e+00), RES(6.9314718055994708577e-1, 0.0)}, {FN (logabs), ARG(-1.19209289550781250e-07,-2.0e+00), RES(6.9314718055994708577e-1, 0.0)}, {FN (logabs), ARG(1.19209289550781250e-07,8.3886080e+06), RES(1.5942385152878742117e1, 0.0)}, {FN (logabs), ARG(1.19209289550781250e-07,-8.3886080e+06), RES(1.5942385152878742117e1, 0.0)}, {FN (logabs), ARG(-1.19209289550781250e-07,8.3886080e+06), RES(1.5942385152878742117e1, 0.0)}, {FN (logabs), ARG(-1.19209289550781250e-07,-8.3886080e+06), RES(1.5942385152878742117e1, 0.0)}, {FN (logabs), ARG(5.0e-01,1.19209289550781250e-07), RES(-6.9314718055991688771e-1, 0.0)}, {FN (logabs), ARG(5.0e-01,-1.19209289550781250e-07), RES(-6.9314718055991688771e-1, 0.0)}, {FN (logabs), ARG(-5.0e-01,1.19209289550781250e-07), RES(-6.9314718055991688771e-1, 0.0)}, {FN (logabs), ARG(-5.0e-01,-1.19209289550781250e-07), RES(-6.9314718055991688771e-1, 0.0)}, {FN (logabs), ARG(5.0e-01,5.0e-01), RES(-3.4657359027997265471e-1, 0.0)}, {FN (logabs), ARG(5.0e-01,-5.0e-01), RES(-3.4657359027997265471e-1, 0.0)}, {FN (logabs), ARG(-5.0e-01,5.0e-01), RES(-3.4657359027997265471e-1, 0.0)}, {FN (logabs), ARG(-5.0e-01,-5.0e-01), RES(-3.4657359027997265471e-1, 0.0)}, {FN (logabs), ARG(5.0e-01,1.0e+00), RES(1.1157177565710487788e-1, 0.0)}, {FN (logabs), ARG(5.0e-01,-1.0e+00), RES(1.1157177565710487788e-1, 0.0)}, {FN (logabs), ARG(-5.0e-01,1.0e+00), RES(1.1157177565710487788e-1, 0.0)}, {FN (logabs), ARG(-5.0e-01,-1.0e+00), RES(1.1157177565710487788e-1, 0.0)}, {FN (logabs), ARG(5.0e-01,2.0e+00), RES(7.2345949146816273071e-1, 0.0)}, {FN (logabs), ARG(5.0e-01,-2.0e+00), RES(7.2345949146816273071e-1, 0.0)}, {FN (logabs), ARG(-5.0e-01,2.0e+00), RES(7.2345949146816273071e-1, 0.0)}, {FN (logabs), ARG(-5.0e-01,-2.0e+00), RES(7.2345949146816273071e-1, 0.0)}, {FN (logabs), ARG(5.0e-01,8.3886080e+06), RES(1.5942385152878743893e1, 0.0)}, {FN (logabs), ARG(5.0e-01,-8.3886080e+06), RES(1.5942385152878743893e1, 0.0)}, {FN (logabs), ARG(-5.0e-01,8.3886080e+06), RES(1.5942385152878743893e1, 0.0)}, {FN (logabs), ARG(-5.0e-01,-8.3886080e+06), RES(1.5942385152878743893e1, 0.0)}, {FN (logabs), ARG(1.0e+00,1.19209289550781250e-07), RES(7.1054273576009513716e-15, 0.0)}, {FN (logabs), ARG(1.0e+00,-1.19209289550781250e-07), RES(7.1054273576009513716e-15, 0.0)}, {FN (logabs), ARG(-1.0e+00,1.19209289550781250e-07), RES(7.1054273576009513716e-15, 0.0)}, {FN (logabs), ARG(-1.0e+00,-1.19209289550781250e-07), RES(7.1054273576009513716e-15, 0.0)}, {FN (logabs), ARG(1.0e+00,5.0e-01), RES(1.1157177565710487788e-1, 0.0)}, {FN (logabs), ARG(1.0e+00,-5.0e-01), RES(1.1157177565710487788e-1, 0.0)}, {FN (logabs), ARG(-1.0e+00,5.0e-01), RES(1.1157177565710487788e-1, 0.0)}, {FN (logabs), ARG(-1.0e+00,-5.0e-01), RES(1.1157177565710487788e-1, 0.0)}, {FN (logabs), ARG(1.0e+00,1.0e+00), RES(3.4657359027997265471e-1, 0.0)}, {FN (logabs), ARG(1.0e+00,-1.0e+00), RES(3.4657359027997265471e-1, 0.0)}, {FN (logabs), ARG(-1.0e+00,1.0e+00), RES(3.4657359027997265471e-1, 0.0)}, {FN (logabs), ARG(-1.0e+00,-1.0e+00), RES(3.4657359027997265471e-1, 0.0)}, {FN (logabs), ARG(1.0e+00,2.0e+00), RES(8.0471895621705018730e-1, 0.0)}, {FN (logabs), ARG(1.0e+00,-2.0e+00), RES(8.0471895621705018730e-1, 0.0)}, {FN (logabs), ARG(-1.0e+00,2.0e+00), RES(8.0471895621705018730e-1, 0.0)}, {FN (logabs), ARG(-1.0e+00,-2.0e+00), RES(8.0471895621705018730e-1, 0.0)}, {FN (logabs), ARG(1.0e+00,8.3886080e+06), RES(1.5942385152878749222e1, 0.0)}, {FN (logabs), ARG(1.0e+00,-8.3886080e+06), RES(1.5942385152878749222e1, 0.0)}, {FN (logabs), ARG(-1.0e+00,8.3886080e+06), RES(1.5942385152878749222e1, 0.0)}, {FN (logabs), ARG(-1.0e+00,-8.3886080e+06), RES(1.5942385152878749222e1, 0.0)}, {FN (logabs), ARG(2.0e+00,1.19209289550781250e-07), RES(6.9314718055994708577e-1, 0.0)}, {FN (logabs), ARG(2.0e+00,-1.19209289550781250e-07), RES(6.9314718055994708577e-1, 0.0)}, {FN (logabs), ARG(-2.0e+00,1.19209289550781250e-07), RES(6.9314718055994708577e-1, 0.0)}, {FN (logabs), ARG(-2.0e+00,-1.19209289550781250e-07), RES(6.9314718055994708577e-1, 0.0)}, {FN (logabs), ARG(2.0e+00,5.0e-01), RES(7.2345949146816273071e-1, 0.0)}, {FN (logabs), ARG(2.0e+00,-5.0e-01), RES(7.2345949146816273071e-1, 0.0)}, {FN (logabs), ARG(-2.0e+00,5.0e-01), RES(7.2345949146816273071e-1, 0.0)}, {FN (logabs), ARG(-2.0e+00,-5.0e-01), RES(7.2345949146816273071e-1, 0.0)}, {FN (logabs), ARG(2.0e+00,1.0e+00), RES(8.0471895621705018730e-1, 0.0)}, {FN (logabs), ARG(2.0e+00,-1.0e+00), RES(8.0471895621705018730e-1, 0.0)}, {FN (logabs), ARG(-2.0e+00,1.0e+00), RES(8.0471895621705018730e-1, 0.0)}, {FN (logabs), ARG(-2.0e+00,-1.0e+00), RES(8.0471895621705018730e-1, 0.0)}, {FN (logabs), ARG(2.0e+00,2.0e+00), RES(1.0397207708399179641e0, 0.0)}, {FN (logabs), ARG(2.0e+00,-2.0e+00), RES(1.0397207708399179641e0, 0.0)}, {FN (logabs), ARG(-2.0e+00,2.0e+00), RES(1.0397207708399179641e0, 0.0)}, {FN (logabs), ARG(-2.0e+00,-2.0e+00), RES(1.0397207708399179641e0, 0.0)}, {FN (logabs), ARG(2.0e+00,8.3886080e+06), RES(1.5942385152878770538e1, 0.0)}, {FN (logabs), ARG(2.0e+00,-8.3886080e+06), RES(1.5942385152878770538e1, 0.0)}, {FN (logabs), ARG(-2.0e+00,8.3886080e+06), RES(1.5942385152878770538e1, 0.0)}, {FN (logabs), ARG(-2.0e+00,-8.3886080e+06), RES(1.5942385152878770538e1, 0.0)}, {FN (logabs), ARG(8.3886080e+06,1.19209289550781250e-07), RES(1.5942385152878742117e1, 0.0)}, {FN (logabs), ARG(8.3886080e+06,-1.19209289550781250e-07), RES(1.5942385152878742117e1, 0.0)}, {FN (logabs), ARG(-8.3886080e+06,1.19209289550781250e-07), RES(1.5942385152878742117e1, 0.0)}, {FN (logabs), ARG(-8.3886080e+06,-1.19209289550781250e-07), RES(1.5942385152878742117e1, 0.0)}, {FN (logabs), ARG(8.3886080e+06,5.0e-01), RES(1.5942385152878743893e1, 0.0)}, {FN (logabs), ARG(8.3886080e+06,-5.0e-01), RES(1.5942385152878743893e1, 0.0)}, {FN (logabs), ARG(-8.3886080e+06,5.0e-01), RES(1.5942385152878743893e1, 0.0)}, {FN (logabs), ARG(-8.3886080e+06,-5.0e-01), RES(1.5942385152878743893e1, 0.0)}, {FN (logabs), ARG(8.3886080e+06,1.0e+00), RES(1.5942385152878749222e1, 0.0)}, {FN (logabs), ARG(8.3886080e+06,-1.0e+00), RES(1.5942385152878749222e1, 0.0)}, {FN (logabs), ARG(-8.3886080e+06,1.0e+00), RES(1.5942385152878749222e1, 0.0)}, {FN (logabs), ARG(-8.3886080e+06,-1.0e+00), RES(1.5942385152878749222e1, 0.0)}, {FN (logabs), ARG(8.3886080e+06,2.0e+00), RES(1.5942385152878770538e1, 0.0)}, {FN (logabs), ARG(8.3886080e+06,-2.0e+00), RES(1.5942385152878770538e1, 0.0)}, {FN (logabs), ARG(-8.3886080e+06,2.0e+00), RES(1.5942385152878770538e1, 0.0)}, {FN (logabs), ARG(-8.3886080e+06,-2.0e+00), RES(1.5942385152878770538e1, 0.0)}, {FN (logabs), ARG(8.3886080e+06,8.3886080e+06), RES(1.6288958743158714771e1, 0.0)}, {FN (logabs), ARG(8.3886080e+06,-8.3886080e+06), RES(1.6288958743158714771e1, 0.0)}, {FN (logabs), ARG(-8.3886080e+06,8.3886080e+06), RES(1.6288958743158714771e1, 0.0)}, {FN (logabs), ARG(-8.3886080e+06,-8.3886080e+06), RES(1.6288958743158714771e1, 0.0)}, praat-6.0.04/external/gsl/gsl_complex__results2.h000066400000000000000000000104411261542461700220160ustar00rootroot00000000000000 {FN (pow), ARG(1.0e+00,0.0e+00), ARG(0.0e+00,0.0e+00), RES(1e0, 0.0)}, {FN (pow), ARG(1.0e+00,0.0e+00), ARG(1.0e+00,0.0e+00), RES(1e0, 0.0)}, {FN (pow), ARG(1.0e+00,0.0e+00), ARG(0.0e+00,1.0e+00), RES(1e0, 0.0)}, {FN (pow), ARG(1.0e+00,0.0e+00), ARG(-1.0e+00,0.0e+00), RES(1e0, 0.0)}, {FN (pow), ARG(1.0e+00,0.0e+00), ARG(0.0e+00,-1.0e+00), RES(1e0, 0.0)}, {FN (pow), ARG(1.0e+00,0.0e+00), ARG(5.0e-01,1.00000000000000005551e-01), RES(1e0, 0.0)}, {FN (pow), ARG(1.0e+00,0.0e+00), ARG(5.0e-01,-1.00000000000000005551e-01), RES(1e0, 0.0)}, {FN (pow), ARG(0.0e+00,1.0e+00), ARG(0.0e+00,0.0e+00), RES(1e0, 0.0)}, {FN (pow), ARG(0.0e+00,1.0e+00), ARG(1.0e+00,0.0e+00), RES(0, 1)}, {FN (pow), ARG(0.0e+00,1.0e+00), ARG(0.0e+00,1.0e+00), RES(2.0787957635076190855e-1, 0.0)}, {FN (pow), ARG(0.0e+00,1.0e+00), ARG(-1.0e+00,0.0e+00), RES(0, -1)}, {FN (pow), ARG(0.0e+00,1.0e+00), ARG(0.0e+00,-1.0e+00), RES(4.8104773809653516555e0, 0.0)}, {FN (pow), ARG(0.0e+00,1.0e+00), ARG(5.0e-01,1.00000000000000005551e-01), RES(6.0431891044739184057e-1, 6.0431891044739184057e-1)}, {FN (pow), ARG(0.0e+00,1.0e+00), ARG(5.0e-01,-1.00000000000000005551e-01), RES(8.2737771622906514822e-1, 8.2737771622906514822e-1)}, {FN (pow), ARG(-1.0e+00,0.0e+00), ARG(0.0e+00,0.0e+00), RES(1e0, 0.0)}, {FN (pow), ARG(-1.0e+00,0.0e+00), ARG(1.0e+00,0.0e+00), RES(-1e0, 0.0)}, {FN (pow), ARG(-1.0e+00,0.0e+00), ARG(0.0e+00,1.0e+00), RES(4.3213918263772249774e-2, 0.0)}, {FN (pow), ARG(-1.0e+00,0.0e+00), ARG(-1.0e+00,0.0e+00), RES(-1e0, 0.0)}, {FN (pow), ARG(-1.0e+00,0.0e+00), ARG(0.0e+00,-1.0e+00), RES(2.3140692632779269006e1, 0.0)}, {FN (pow), ARG(-1.0e+00,0.0e+00), ARG(5.0e-01,1.00000000000000005551e-01), RES(0, 7.3040269104864559813e-1)}, {FN (pow), ARG(-1.0e+00,0.0e+00), ARG(5.0e-01,-1.00000000000000005551e-01), RES(0, 1.3691077706248469087e0)}, {FN (pow), ARG(0.0e+00,-1.0e+00), ARG(0.0e+00,0.0e+00), RES(1e0, 0.0)}, {FN (pow), ARG(0.0e+00,-1.0e+00), ARG(1.0e+00,0.0e+00), RES(0, -1)}, {FN (pow), ARG(0.0e+00,-1.0e+00), ARG(0.0e+00,1.0e+00), RES(4.8104773809653516555e0, 0.0)}, {FN (pow), ARG(0.0e+00,-1.0e+00), ARG(-1.0e+00,0.0e+00), RES(0, 1)}, {FN (pow), ARG(0.0e+00,-1.0e+00), ARG(0.0e+00,-1.0e+00), RES(2.0787957635076190855e-1, 0.0)}, {FN (pow), ARG(0.0e+00,-1.0e+00), ARG(5.0e-01,1.00000000000000005551e-01), RES(8.2737771622906514822e-1, -8.2737771622906514822e-1)}, {FN (pow), ARG(0.0e+00,-1.0e+00), ARG(5.0e-01,-1.00000000000000005551e-01), RES(6.0431891044739184057e-1, -6.0431891044739184057e-1)}, {FN (pow), ARG(5.0e-01,1.00000000000000005551e-01), ARG(0.0e+00,0.0e+00), RES(1e0, 0.0)}, {FN (pow), ARG(5.0e-01,1.00000000000000005551e-01), ARG(1.0e+00,0.0e+00), RES(5e-1, 1.0000000000000000555e-1)}, {FN (pow), ARG(5.0e-01,1.00000000000000005551e-01), ARG(0.0e+00,1.0e+00), RES(6.4160554864378080418e-1, -5.1201864456768275590e-1)}, {FN (pow), ARG(5.0e-01,1.00000000000000005551e-01), ARG(-1.0e+00,0.0e+00), RES(1.9230769230769230687e0, -3.8461538461538463509e-1)}, {FN (pow), ARG(5.0e-01,1.00000000000000005551e-01), ARG(0.0e+00,-1.0e+00), RES(9.5219021866126714108e-1, 7.5987364224031834571e-1)}, {FN (pow), ARG(5.0e-01,1.00000000000000005551e-01), ARG(5.0e-01,1.00000000000000005551e-01), RES(6.9977300530987816719e-1, 2.1940939105372143160e-2)}, {FN (pow), ARG(5.0e-01,1.00000000000000005551e-01), ARG(5.0e-01,-1.00000000000000005551e-01), RES(7.1829191470060938876e-1, 1.2038189555821612762e-1)}, {FN (pow), ARG(5.0e-01,-1.00000000000000005551e-01), ARG(0.0e+00,0.0e+00), RES(1e0, 0.0)}, {FN (pow), ARG(5.0e-01,-1.00000000000000005551e-01), ARG(1.0e+00,0.0e+00), RES(5e-1, -1.0000000000000000555e-1)}, {FN (pow), ARG(5.0e-01,-1.00000000000000005551e-01), ARG(0.0e+00,1.0e+00), RES(9.5219021866126714108e-1, -7.5987364224031834571e-1)}, {FN (pow), ARG(5.0e-01,-1.00000000000000005551e-01), ARG(-1.0e+00,0.0e+00), RES(1.9230769230769230687e0, 3.8461538461538463509e-1)}, {FN (pow), ARG(5.0e-01,-1.00000000000000005551e-01), ARG(0.0e+00,-1.0e+00), RES(6.4160554864378080418e-1, 5.1201864456768275590e-1)}, {FN (pow), ARG(5.0e-01,-1.00000000000000005551e-01), ARG(5.0e-01,1.00000000000000005551e-01), RES(7.1829191470060938876e-1, -1.2038189555821612762e-1)}, {FN (pow), ARG(5.0e-01,-1.00000000000000005551e-01), ARG(5.0e-01,-1.00000000000000005551e-01), RES(6.9977300530987816719e-1, -2.1940939105372143160e-2)}, praat-6.0.04/external/gsl/gsl_complex__results_real.h000066400000000000000000000206041261542461700227410ustar00rootroot00000000000000 {FN (sqrt_real), -1.0e+01, RES(0, 3.1622776601683793320e0)}, {FN (sqrt_real), -2.0e+00, RES(0, 1.4142135623730950488e0)}, {FN (sqrt_real), -1.0e+00, RES(0, 1)}, {FN (sqrt_real), -7.50e-01, RES(0, 8.6602540378443864676e-1)}, {FN (sqrt_real), -5.0e-01, RES(0, 7.0710678118654752440e-1)}, {FN (sqrt_real), -1.250e-01, RES(0, 3.5355339059327376220e-1)}, {FN (sqrt_real), -3.45266983001243932001e-04, RES(0, 1.8581361171917517303e-2)}, {FN (sqrt_real), -1.19209289550781250e-07, RES(0, 3.4526698300124390840e-4)}, {FN (sqrt_real), 0.0e+00, RES(0e0, 0.0)}, {FN (sqrt_real), 1.19209289550781250e-07, RES(3.4526698300124390840e-4, 0.0)}, {FN (sqrt_real), 3.45266983001243932001e-04, RES(1.8581361171917517303e-2, 0.0)}, {FN (sqrt_real), 1.250e-01, RES(3.5355339059327376220e-1, 0.0)}, {FN (sqrt_real), 5.0e-01, RES(7.0710678118654752440e-1, 0.0)}, {FN (sqrt_real), 7.50e-01, RES(8.6602540378443864676e-1, 0.0)}, {FN (sqrt_real), 1.0e+00, RES(1e0, 0.0)}, {FN (sqrt_real), 2.0e+00, RES(1.4142135623730950488e0, 0.0)}, {FN (sqrt_real), 1.0e+01, RES(3.1622776601683793320e0, 0.0)}, {FN (arcsin_real), -1.0e+01, RES(-1.5707963267948966192e0, 2.9932228461263808979e0)}, {FN (arcsin_real), -2.0e+00, RES(-1.5707963267948966192e0, 1.3169578969248167086e0)}, {FN (arcsin_real), -1.0e+00, RES(-1.5707963267948966192e0, 0.0)}, {FN (arcsin_real), -7.50e-01, RES(-8.4806207898148100805e-1, 0.0)}, {FN (arcsin_real), -5.0e-01, RES(-5.2359877559829887308e-1, 0.0)}, {FN (arcsin_real), -1.250e-01, RES(-1.2532783116806539687e-1, 0.0)}, {FN (arcsin_real), -3.45266983001243932001e-04, RES(-3.4526698986108292481e-4, 0.0)}, {FN (arcsin_real), -1.19209289550781250e-07, RES(-1.1920928955078153234e-7, 0.0)}, {FN (arcsin_real), 0.0e+00, RES(0e0, 0.0)}, {FN (arcsin_real), 1.19209289550781250e-07, RES(1.1920928955078153234e-7, 0.0)}, {FN (arcsin_real), 3.45266983001243932001e-04, RES(3.4526698986108292481e-4, 0.0)}, {FN (arcsin_real), 1.250e-01, RES(1.2532783116806539687e-1, 0.0)}, {FN (arcsin_real), 5.0e-01, RES(5.2359877559829887308e-1, 0.0)}, {FN (arcsin_real), 7.50e-01, RES(8.4806207898148100805e-1, 0.0)}, {FN (arcsin_real), 1.0e+00, RES(1.5707963267948966192e0, 0.0)}, {FN (arcsin_real), 2.0e+00, RES(1.5707963267948966192e0, -1.3169578969248167086e0)}, {FN (arcsin_real), 1.0e+01, RES(1.5707963267948966192e0, -2.9932228461263808979e0)}, {FN (arccos_real), -1.0e+01, RES(3.1415926535897932385e0, -2.9932228461263808979e0)}, {FN (arccos_real), -2.0e+00, RES(3.1415926535897932385e0, -1.3169578969248167086e0)}, {FN (arccos_real), -1.0e+00, RES(3.1415926535897932385e0, 0.0)}, {FN (arccos_real), -7.50e-01, RES(2.4188584057763776273e0, 0.0)}, {FN (arccos_real), -5.0e-01, RES(2.0943951023931954923e0, 0.0)}, {FN (arccos_real), -1.250e-01, RES(1.6961241579629620161e0, 0.0)}, {FN (arccos_real), -3.45266983001243932001e-04, RES(1.5711415937847577022e0, 0.0)}, {FN (arccos_real), -1.19209289550781250e-07, RES(1.570796446004186170e0, 0.0)}, {FN (arccos_real), 0.0e+00, RES(1.5707963267948966192e0, 0.0)}, {FN (arccos_real), 1.19209289550781250e-07, RES(1.5707962075856070684e0, 0.0)}, {FN (arccos_real), 3.45266983001243932001e-04, RES(1.5704510598050355363e0, 0.0)}, {FN (arccos_real), 1.250e-01, RES(1.4454684956268312224e0, 0.0)}, {FN (arccos_real), 5.0e-01, RES(1.0471975511965977462e0, 0.0)}, {FN (arccos_real), 7.50e-01, RES(7.2273424781341561118e-1, 0.0)}, {FN (arccos_real), 1.0e+00, RES(0e0, 0.0)}, {FN (arccos_real), 2.0e+00, RES(0, 1.3169578969248167086e0)}, {FN (arccos_real), 1.0e+01, RES(0, 2.9932228461263808979e0)}, {FN (arccosh_real), -1.0e+01, RES(2.9932228461263808979e0, 3.1415926535897932385e0)}, {FN (arccosh_real), -2.0e+00, RES(1.3169578969248167086e0, 3.1415926535897932385e0)}, {FN (arccosh_real), -1.0e+00, RES(0, 3.1415926535897932385e0)}, {FN (arccosh_real), -7.50e-01, RES(0, 2.4188584057763776273e0)}, {FN (arccosh_real), -5.0e-01, RES(0, 2.0943951023931954923e0)}, {FN (arccosh_real), -1.250e-01, RES(0, 1.6961241579629620161e0)}, {FN (arccosh_real), -3.45266983001243932001e-04, RES(0, 1.5711415937847577022e0)}, {FN (arccosh_real), -1.19209289550781250e-07, RES(0, 1.570796446004186170e0)}, {FN (arccosh_real), 0.0e+00, RES(0, 1.5707963267948966192e0)}, {FN (arccosh_real), 1.19209289550781250e-07, RES(0, 1.5707962075856070684e0)}, {FN (arccosh_real), 3.45266983001243932001e-04, RES(0, 1.5704510598050355363e0)}, {FN (arccosh_real), 1.250e-01, RES(0, 1.4454684956268312224e0)}, {FN (arccosh_real), 5.0e-01, RES(0, 1.0471975511965977462e0)}, {FN (arccosh_real), 7.50e-01, RES(0, 7.2273424781341561118e-1)}, {FN (arccosh_real), 1.0e+00, RES(0e0, 0.0)}, {FN (arccosh_real), 2.0e+00, RES(1.3169578969248167086e0, 0.0)}, {FN (arccosh_real), 1.0e+01, RES(2.9932228461263808979e0, 0.0)}, {FN (arctanh_real), -1.0e+01, RES(-1.0033534773107558064e-1, 1.5707963267948966192e0)}, {FN (arctanh_real), -2.0e+00, RES(-5.4930614433405484570e-1, 1.5707963267948966192e0)}, {FN (arctanh_real), -7.50e-01, RES(-9.7295507452765665255e-1, 0.0)}, {FN (arctanh_real), -5.0e-01, RES(-5.4930614433405484570e-1, 0.0)}, {FN (arctanh_real), -1.250e-01, RES(-1.2565721414045303884e-1, 0.0)}, {FN (arctanh_real), -3.45266983001243932001e-04, RES(-3.4526699672092216295e-4, 0.0)}, {FN (arctanh_real), -1.19209289550781250e-07, RES(-1.1920928955078181469e-7, 0.0)}, {FN (arctanh_real), 0.0e+00, RES(0e0, 0.0)}, {FN (arctanh_real), 1.19209289550781250e-07, RES(1.1920928955078181469e-7, 0.0)}, {FN (arctanh_real), 3.45266983001243932001e-04, RES(3.4526699672092216295e-4, 0.0)}, {FN (arctanh_real), 1.250e-01, RES(1.2565721414045303884e-1, 0.0)}, {FN (arctanh_real), 5.0e-01, RES(5.4930614433405484570e-1, 0.0)}, {FN (arctanh_real), 7.50e-01, RES(9.7295507452765665255e-1, 0.0)}, {FN (arctanh_real), 2.0e+00, RES(5.4930614433405484570e-1, -1.5707963267948966192e0)}, {FN (arctanh_real), 1.0e+01, RES(1.0033534773107558064e-1, -1.5707963267948966192e0)}, {FN (arccsc_real), -1.0e+01, RES(-1.0016742116155979635e-1, 0.0)}, {FN (arccsc_real), -2.0e+00, RES(-5.2359877559829887308e-1, 0.0)}, {FN (arccsc_real), -1.0e+00, RES(-1.5707963267948966192e0, 0.0)}, {FN (arccsc_real), -7.50e-01, RES(-1.5707963267948966192e0, 7.9536546122390563053e-1)}, {FN (arccsc_real), -5.0e-01, RES(-1.5707963267948966192e0, 1.3169578969248167086e0)}, {FN (arccsc_real), -1.250e-01, RES(-1.5707963267948966192e0, 2.7686593833135738327e0)}, {FN (arccsc_real), -3.45266983001243932001e-04, RES(-1.5707963267948966192e0, 8.6643397271969925794e0)}, {FN (arccsc_real), -1.19209289550781250e-07, RES(-1.5707963267948966192e0, 1.6635532333438683873e1)}, {FN (arccsc_real), 1.19209289550781250e-07, RES(1.5707963267948966192e0, -1.6635532333438683873e1)}, {FN (arccsc_real), 3.45266983001243932001e-04, RES(1.5707963267948966192e0, -8.6643397271969925794e0)}, {FN (arccsc_real), 1.250e-01, RES(1.5707963267948966192e0, -2.7686593833135738327e0)}, {FN (arccsc_real), 5.0e-01, RES(1.5707963267948966192e0, -1.3169578969248167086e0)}, {FN (arccsc_real), 7.50e-01, RES(1.5707963267948966192e0, -7.9536546122390563053e-1)}, {FN (arccsc_real), 1.0e+00, RES(1.5707963267948966192e0, 0.0)}, {FN (arccsc_real), 2.0e+00, RES(5.2359877559829887308e-1, 0.0)}, {FN (arccsc_real), 1.0e+01, RES(1.0016742116155979635e-1, 0.0)}, {FN (arcsec_real), -1.0e+01, RES(1.6709637479564564156e0, 0.0)}, {FN (arcsec_real), -2.0e+00, RES(2.0943951023931954923e0, 0.0)}, {FN (arcsec_real), -1.0e+00, RES(3.1415926535897932385e0, 0.0)}, {FN (arcsec_real), -7.50e-01, RES(3.1415926535897932385e0, -7.9536546122390563053e-1)}, {FN (arcsec_real), -5.0e-01, RES(3.1415926535897932385e0, -1.3169578969248167086e0)}, {FN (arcsec_real), -1.250e-01, RES(3.1415926535897932385e0, -2.7686593833135738327e0)}, {FN (arcsec_real), -3.45266983001243932001e-04, RES(3.1415926535897932385e0, -8.6643397271969925794e0)}, {FN (arcsec_real), -1.19209289550781250e-07, RES(3.1415926535897932385e0, -1.6635532333438683873e1)}, {FN (arcsec_real), 1.19209289550781250e-07, RES(0, 1.6635532333438683873e1)}, {FN (arcsec_real), 3.45266983001243932001e-04, RES(0, 8.6643397271969925794e0)}, {FN (arcsec_real), 1.250e-01, RES(0, 2.7686593833135738327e0)}, {FN (arcsec_real), 5.0e-01, RES(0, 1.3169578969248167086e0)}, {FN (arcsec_real), 7.50e-01, RES(0, 7.9536546122390563053e-1)}, {FN (arcsec_real), 1.0e+00, RES(0e0, 0.0)}, {FN (arcsec_real), 2.0e+00, RES(1.0471975511965977462e0, 0.0)}, {FN (arcsec_real), 1.0e+01, RES(1.4706289056333368229e0, 0.0)}, praat-6.0.04/external/gsl/gsl_complex_math.h000066400000000000000000000135661261542461700210400ustar00rootroot00000000000000/* complex/gsl_complex_math.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004, 2007 Jorma Olavi Thtinen, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_COMPLEX_MATH_H__ #define __GSL_COMPLEX_MATH_H__ #include "gsl_complex.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS /* empty */ #define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Complex numbers */ gsl_complex gsl_complex_rect (double x, double y); /* r= real+i*imag */ gsl_complex gsl_complex_polar (double r, double theta); /* r= r e^(i theta) */ #ifdef HAVE_INLINE extern inline gsl_complex gsl_complex_rect (double x, double y) { /* return z = x + i y */ gsl_complex z; GSL_SET_COMPLEX (&z, x, y); return z; } #endif #define GSL_COMPLEX_ONE (gsl_complex_rect(1.0,0.0)) #define GSL_COMPLEX_ZERO (gsl_complex_rect(0.0,0.0)) #define GSL_COMPLEX_NEGONE (gsl_complex_rect(-1.0,0.0)) /* Properties of complex numbers */ double gsl_complex_arg (gsl_complex z); /* return arg(z), -pi< arg(z) <=+pi */ double gsl_complex_abs (gsl_complex z); /* return |z| */ double gsl_complex_abs2 (gsl_complex z); /* return |z|^2 */ double gsl_complex_logabs (gsl_complex z); /* return log|z| */ /* Complex arithmetic operators */ gsl_complex gsl_complex_add (gsl_complex a, gsl_complex b); /* r=a+b */ gsl_complex gsl_complex_sub (gsl_complex a, gsl_complex b); /* r=a-b */ gsl_complex gsl_complex_mul (gsl_complex a, gsl_complex b); /* r=a*b */ gsl_complex gsl_complex_div (gsl_complex a, gsl_complex b); /* r=a/b */ gsl_complex gsl_complex_add_real (gsl_complex a, double x); /* r=a+x */ gsl_complex gsl_complex_sub_real (gsl_complex a, double x); /* r=a-x */ gsl_complex gsl_complex_mul_real (gsl_complex a, double x); /* r=a*x */ gsl_complex gsl_complex_div_real (gsl_complex a, double x); /* r=a/x */ gsl_complex gsl_complex_add_imag (gsl_complex a, double y); /* r=a+iy */ gsl_complex gsl_complex_sub_imag (gsl_complex a, double y); /* r=a-iy */ gsl_complex gsl_complex_mul_imag (gsl_complex a, double y); /* r=a*iy */ gsl_complex gsl_complex_div_imag (gsl_complex a, double y); /* r=a/iy */ gsl_complex gsl_complex_conjugate (gsl_complex z); /* r=conj(z) */ gsl_complex gsl_complex_inverse (gsl_complex a); /* r=1/a */ gsl_complex gsl_complex_negative (gsl_complex a); /* r=-a */ /* Elementary Complex Functions */ gsl_complex gsl_complex_sqrt (gsl_complex z); /* r=sqrt(z) */ gsl_complex gsl_complex_sqrt_real (double x); /* r=sqrt(x) (x<0 ok) */ gsl_complex gsl_complex_pow (gsl_complex a, gsl_complex b); /* r=a^b */ gsl_complex gsl_complex_pow_real (gsl_complex a, double b); /* r=a^b */ gsl_complex gsl_complex_exp (gsl_complex a); /* r=exp(a) */ gsl_complex gsl_complex_log (gsl_complex a); /* r=log(a) (base e) */ gsl_complex gsl_complex_log10 (gsl_complex a); /* r=log10(a) (base 10) */ gsl_complex gsl_complex_log_b (gsl_complex a, gsl_complex b); /* r=log_b(a) (base=b) */ /* Complex Trigonometric Functions */ gsl_complex gsl_complex_sin (gsl_complex a); /* r=sin(a) */ gsl_complex gsl_complex_cos (gsl_complex a); /* r=cos(a) */ gsl_complex gsl_complex_sec (gsl_complex a); /* r=sec(a) */ gsl_complex gsl_complex_csc (gsl_complex a); /* r=csc(a) */ gsl_complex gsl_complex_tan (gsl_complex a); /* r=tan(a) */ gsl_complex gsl_complex_cot (gsl_complex a); /* r=cot(a) */ /* Inverse Complex Trigonometric Functions */ gsl_complex gsl_complex_arcsin (gsl_complex a); /* r=arcsin(a) */ gsl_complex gsl_complex_arcsin_real (double a); /* r=arcsin(a) */ gsl_complex gsl_complex_arccos (gsl_complex a); /* r=arccos(a) */ gsl_complex gsl_complex_arccos_real (double a); /* r=arccos(a) */ gsl_complex gsl_complex_arcsec (gsl_complex a); /* r=arcsec(a) */ gsl_complex gsl_complex_arcsec_real (double a); /* r=arcsec(a) */ gsl_complex gsl_complex_arccsc (gsl_complex a); /* r=arccsc(a) */ gsl_complex gsl_complex_arccsc_real (double a); /* r=arccsc(a) */ gsl_complex gsl_complex_arctan (gsl_complex a); /* r=arctan(a) */ gsl_complex gsl_complex_arccot (gsl_complex a); /* r=arccot(a) */ /* Complex Hyperbolic Functions */ gsl_complex gsl_complex_sinh (gsl_complex a); /* r=sinh(a) */ gsl_complex gsl_complex_cosh (gsl_complex a); /* r=coshh(a) */ gsl_complex gsl_complex_sech (gsl_complex a); /* r=sech(a) */ gsl_complex gsl_complex_csch (gsl_complex a); /* r=csch(a) */ gsl_complex gsl_complex_tanh (gsl_complex a); /* r=tanh(a) */ gsl_complex gsl_complex_coth (gsl_complex a); /* r=coth(a) */ /* Inverse Complex Hyperbolic Functions */ gsl_complex gsl_complex_arcsinh (gsl_complex a); /* r=arcsinh(a) */ gsl_complex gsl_complex_arccosh (gsl_complex a); /* r=arccosh(a) */ gsl_complex gsl_complex_arccosh_real (double a); /* r=arccosh(a) */ gsl_complex gsl_complex_arcsech (gsl_complex a); /* r=arcsech(a) */ gsl_complex gsl_complex_arccsch (gsl_complex a); /* r=arccsch(a) */ gsl_complex gsl_complex_arctanh (gsl_complex a); /* r=arctanh(a) */ gsl_complex gsl_complex_arctanh_real (double a); /* r=arctanh(a) */ gsl_complex gsl_complex_arccoth (gsl_complex a); /* r=arccoth(a) */ __END_DECLS #endif /* __GSL_COMPLEX_MATH_H__ */ praat-6.0.04/external/gsl/gsl_const.h000066400000000000000000000020141261542461700174700ustar00rootroot00000000000000/* const/gsl_const.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_CONST__ #define __GSL_CONST__ #include "gsl_const_num.h" #include "gsl_const_cgs.h" #include "gsl_const_mks.h" #include "gsl_const_cgsm.h" #include "gsl_const_mksa.h" #endif /* __GSL_CONST__ */ praat-6.0.04/external/gsl/gsl_const_cgs.h000066400000000000000000000150311261542461700203270ustar00rootroot00000000000000/* const/gsl_const_cgs.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, * 2006 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_CONST_CGS__ #define __GSL_CONST_CGS__ #define GSL_CONST_CGS_SPEED_OF_LIGHT (2.99792458e10) /* cm / s */ #define GSL_CONST_CGS_GRAVITATIONAL_CONSTANT (6.673e-8) /* cm^3 / g s^2 */ #define GSL_CONST_CGS_PLANCKS_CONSTANT_H (6.62606876e-27) /* g cm^2 / s */ #define GSL_CONST_CGS_PLANCKS_CONSTANT_HBAR (1.05457159642e-27) /* g cm^2 / s */ #define GSL_CONST_CGS_ASTRONOMICAL_UNIT (1.49597870691e13) /* cm */ #define GSL_CONST_CGS_LIGHT_YEAR (9.46053620707e17) /* cm */ #define GSL_CONST_CGS_PARSEC (3.08567758135e18) /* cm */ #define GSL_CONST_CGS_GRAV_ACCEL (9.80665e2) /* cm / s^2 */ #define GSL_CONST_CGS_ELECTRON_VOLT (1.602176462e-12) /* g cm^2 / s^2 */ #define GSL_CONST_CGS_MASS_ELECTRON (9.10938188e-28) /* g */ #define GSL_CONST_CGS_MASS_MUON (1.88353109e-25) /* g */ #define GSL_CONST_CGS_MASS_PROTON (1.67262158e-24) /* g */ #define GSL_CONST_CGS_MASS_NEUTRON (1.67492716e-24) /* g */ #define GSL_CONST_CGS_RYDBERG (2.17987190389e-11) /* g cm^2 / s^2 */ #define GSL_CONST_CGS_BOLTZMANN (1.3806503e-16) /* g cm^2 / K s^2 */ #define GSL_CONST_CGS_BOHR_MAGNETON (9.27400899e-20) /* A cm^2 */ #define GSL_CONST_CGS_NUCLEAR_MAGNETON (5.05078317e-23) /* A cm^2 */ #define GSL_CONST_CGS_ELECTRON_MAGNETIC_MOMENT (9.28476362e-20) /* A cm^2 */ #define GSL_CONST_CGS_PROTON_MAGNETIC_MOMENT (1.410606633e-22) /* A cm^2 */ #define GSL_CONST_CGS_MOLAR_GAS (8.314472e7) /* g cm^2 / K mol s^2 */ #define GSL_CONST_CGS_STANDARD_GAS_VOLUME (2.2710981e4) /* cm^3 / mol */ #define GSL_CONST_CGS_MINUTE (6e1) /* s */ #define GSL_CONST_CGS_HOUR (3.6e3) /* s */ #define GSL_CONST_CGS_DAY (8.64e4) /* s */ #define GSL_CONST_CGS_WEEK (6.048e5) /* s */ #define GSL_CONST_CGS_INCH (2.54e0) /* cm */ #define GSL_CONST_CGS_FOOT (3.048e1) /* cm */ #define GSL_CONST_CGS_YARD (9.144e1) /* cm */ #define GSL_CONST_CGS_MILE (1.609344e5) /* cm */ #define GSL_CONST_CGS_NAUTICAL_MILE (1.852e5) /* cm */ #define GSL_CONST_CGS_FATHOM (1.8288e2) /* cm */ #define GSL_CONST_CGS_MIL (2.54e-3) /* cm */ #define GSL_CONST_CGS_POINT (3.52777777778e-2) /* cm */ #define GSL_CONST_CGS_TEXPOINT (3.51459803515e-2) /* cm */ #define GSL_CONST_CGS_MICRON (1e-4) /* cm */ #define GSL_CONST_CGS_ANGSTROM (1e-8) /* cm */ #define GSL_CONST_CGS_HECTARE (1e8) /* cm^2 */ #define GSL_CONST_CGS_ACRE (4.04685642241e7) /* cm^2 */ #define GSL_CONST_CGS_BARN (1e-24) /* cm^2 */ #define GSL_CONST_CGS_LITER (1e3) /* cm^3 */ #define GSL_CONST_CGS_US_GALLON (3.78541178402e3) /* cm^3 */ #define GSL_CONST_CGS_QUART (9.46352946004e2) /* cm^3 */ #define GSL_CONST_CGS_PINT (4.73176473002e2) /* cm^3 */ #define GSL_CONST_CGS_CUP (2.36588236501e2) /* cm^3 */ #define GSL_CONST_CGS_FLUID_OUNCE (2.95735295626e1) /* cm^3 */ #define GSL_CONST_CGS_TABLESPOON (1.47867647813e1) /* cm^3 */ #define GSL_CONST_CGS_TEASPOON (4.92892159375e0) /* cm^3 */ #define GSL_CONST_CGS_CANADIAN_GALLON (4.54609e3) /* cm^3 */ #define GSL_CONST_CGS_UK_GALLON (4.546092e3) /* cm^3 */ #define GSL_CONST_CGS_MILES_PER_HOUR (4.4704e1) /* cm / s */ #define GSL_CONST_CGS_KILOMETERS_PER_HOUR (2.77777777778e1) /* cm / s */ #define GSL_CONST_CGS_KNOT (5.14444444444e1) /* cm / s */ #define GSL_CONST_CGS_POUND_MASS (4.5359237e2) /* g */ #define GSL_CONST_CGS_OUNCE_MASS (2.8349523125e1) /* g */ #define GSL_CONST_CGS_TON (9.0718474e5) /* g */ #define GSL_CONST_CGS_METRIC_TON (1e6) /* g */ #define GSL_CONST_CGS_UK_TON (1.0160469088e6) /* g */ #define GSL_CONST_CGS_TROY_OUNCE (3.1103475e1) /* g */ #define GSL_CONST_CGS_CARAT (2e-1) /* g */ #define GSL_CONST_CGS_UNIFIED_ATOMIC_MASS (1.66053873e-24) /* g */ #define GSL_CONST_CGS_GRAM_FORCE (9.80665e2) /* cm g / s^2 */ #define GSL_CONST_CGS_POUND_FORCE (4.44822161526e5) /* cm g / s^2 */ #define GSL_CONST_CGS_KILOPOUND_FORCE (4.44822161526e8) /* cm g / s^2 */ #define GSL_CONST_CGS_POUNDAL (1.38255e4) /* cm g / s^2 */ #define GSL_CONST_CGS_CALORIE (4.1868e7) /* g cm^2 / s^2 */ #define GSL_CONST_CGS_BTU (1.05505585262e10) /* g cm^2 / s^2 */ #define GSL_CONST_CGS_THERM (1.05506e15) /* g cm^2 / s^2 */ #define GSL_CONST_CGS_HORSEPOWER (7.457e9) /* g cm^2 / s^3 */ #define GSL_CONST_CGS_BAR (1e6) /* g / cm s^2 */ #define GSL_CONST_CGS_STD_ATMOSPHERE (1.01325e6) /* g / cm s^2 */ #define GSL_CONST_CGS_TORR (1.33322368421e3) /* g / cm s^2 */ #define GSL_CONST_CGS_METER_OF_MERCURY (1.33322368421e6) /* g / cm s^2 */ #define GSL_CONST_CGS_INCH_OF_MERCURY (3.38638815789e4) /* g / cm s^2 */ #define GSL_CONST_CGS_INCH_OF_WATER (2.490889e3) /* g / cm s^2 */ #define GSL_CONST_CGS_PSI (6.89475729317e4) /* g / cm s^2 */ #define GSL_CONST_CGS_POISE (1e0) /* g / cm s */ #define GSL_CONST_CGS_STOKES (1e0) /* cm^2 / s */ #define GSL_CONST_CGS_FARADAY (9.6485341472e4) /* A s / mol */ #define GSL_CONST_CGS_ELECTRON_CHARGE (1.602176462e-19) /* A s */ #define GSL_CONST_CGS_GAUSS (1e-1) /* g / A s^2 */ #define GSL_CONST_CGS_STILB (1e0) /* cd / cm^2 */ #define GSL_CONST_CGS_LUMEN (1e0) /* cd sr */ #define GSL_CONST_CGS_LUX (1e-4) /* cd sr / cm^2 */ #define GSL_CONST_CGS_PHOT (1e0) /* cd sr / cm^2 */ #define GSL_CONST_CGS_FOOTCANDLE (1.076e-3) /* cd sr / cm^2 */ #define GSL_CONST_CGS_LAMBERT (1e0) /* cd sr / cm^2 */ #define GSL_CONST_CGS_FOOTLAMBERT (1.07639104e-3) /* cd sr / cm^2 */ #define GSL_CONST_CGS_CURIE (3.7e10) /* 1 / s */ #define GSL_CONST_CGS_ROENTGEN (2.58e-7) /* A s / g */ #define GSL_CONST_CGS_RAD (1e2) /* cm^2 / s^2 */ #define GSL_CONST_CGS_SOLAR_MASS (1.98892e33) /* g */ #define GSL_CONST_CGS_BOHR_RADIUS (5.291772083e-9) /* cm */ #define GSL_CONST_CGS_NEWTON (1e5) /* cm g / s^2 */ #define GSL_CONST_CGS_DYNE (1e0) /* cm g / s^2 */ #define GSL_CONST_CGS_JOULE (1e7) /* g cm^2 / s^2 */ #define GSL_CONST_CGS_ERG (1e0) /* g cm^2 / s^2 */ #define GSL_CONST_CGS_STEFAN_BOLTZMANN_CONSTANT (5.67039934436e-5) /* g / K^4 s^3 */ #define GSL_CONST_CGS_THOMSON_CROSS_SECTION (6.65245853542e-25) /* cm^2 */ #endif /* __GSL_CONST_CGS__ */ praat-6.0.04/external/gsl/gsl_const_cgsm.h000066400000000000000000000152361261542461700205130ustar00rootroot00000000000000/* const/gsl_const_cgsm.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, * 2006 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_CONST_CGSM__ #define __GSL_CONST_CGSM__ #define GSL_CONST_CGSM_SPEED_OF_LIGHT (2.99792458e10) /* cm / s */ #define GSL_CONST_CGSM_GRAVITATIONAL_CONSTANT (6.673e-8) /* cm^3 / g s^2 */ #define GSL_CONST_CGSM_PLANCKS_CONSTANT_H (6.62606876e-27) /* g cm^2 / s */ #define GSL_CONST_CGSM_PLANCKS_CONSTANT_HBAR (1.05457159642e-27) /* g cm^2 / s */ #define GSL_CONST_CGSM_ASTRONOMICAL_UNIT (1.49597870691e13) /* cm */ #define GSL_CONST_CGSM_LIGHT_YEAR (9.46053620707e17) /* cm */ #define GSL_CONST_CGSM_PARSEC (3.08567758135e18) /* cm */ #define GSL_CONST_CGSM_GRAV_ACCEL (9.80665e2) /* cm / s^2 */ #define GSL_CONST_CGSM_ELECTRON_VOLT (1.602176462e-12) /* g cm^2 / s^2 */ #define GSL_CONST_CGSM_MASS_ELECTRON (9.10938188e-28) /* g */ #define GSL_CONST_CGSM_MASS_MUON (1.88353109e-25) /* g */ #define GSL_CONST_CGSM_MASS_PROTON (1.67262158e-24) /* g */ #define GSL_CONST_CGSM_MASS_NEUTRON (1.67492716e-24) /* g */ #define GSL_CONST_CGSM_RYDBERG (2.17987190389e-11) /* g cm^2 / s^2 */ #define GSL_CONST_CGSM_BOLTZMANN (1.3806503e-16) /* g cm^2 / K s^2 */ #define GSL_CONST_CGSM_BOHR_MAGNETON (9.27400899e-21) /* abamp cm^2 */ #define GSL_CONST_CGSM_NUCLEAR_MAGNETON (5.05078317e-24) /* abamp cm^2 */ #define GSL_CONST_CGSM_ELECTRON_MAGNETIC_MOMENT (9.28476362e-21) /* abamp cm^2 */ #define GSL_CONST_CGSM_PROTON_MAGNETIC_MOMENT (1.410606633e-23) /* abamp cm^2 */ #define GSL_CONST_CGSM_MOLAR_GAS (8.314472e7) /* g cm^2 / K mol s^2 */ #define GSL_CONST_CGSM_STANDARD_GAS_VOLUME (2.2710981e4) /* cm^3 / mol */ #define GSL_CONST_CGSM_MINUTE (6e1) /* s */ #define GSL_CONST_CGSM_HOUR (3.6e3) /* s */ #define GSL_CONST_CGSM_DAY (8.64e4) /* s */ #define GSL_CONST_CGSM_WEEK (6.048e5) /* s */ #define GSL_CONST_CGSM_INCH (2.54e0) /* cm */ #define GSL_CONST_CGSM_FOOT (3.048e1) /* cm */ #define GSL_CONST_CGSM_YARD (9.144e1) /* cm */ #define GSL_CONST_CGSM_MILE (1.609344e5) /* cm */ #define GSL_CONST_CGSM_NAUTICAL_MILE (1.852e5) /* cm */ #define GSL_CONST_CGSM_FATHOM (1.8288e2) /* cm */ #define GSL_CONST_CGSM_MIL (2.54e-3) /* cm */ #define GSL_CONST_CGSM_POINT (3.52777777778e-2) /* cm */ #define GSL_CONST_CGSM_TEXPOINT (3.51459803515e-2) /* cm */ #define GSL_CONST_CGSM_MICRON (1e-4) /* cm */ #define GSL_CONST_CGSM_ANGSTROM (1e-8) /* cm */ #define GSL_CONST_CGSM_HECTARE (1e8) /* cm^2 */ #define GSL_CONST_CGSM_ACRE (4.04685642241e7) /* cm^2 */ #define GSL_CONST_CGSM_BARN (1e-24) /* cm^2 */ #define GSL_CONST_CGSM_LITER (1e3) /* cm^3 */ #define GSL_CONST_CGSM_US_GALLON (3.78541178402e3) /* cm^3 */ #define GSL_CONST_CGSM_QUART (9.46352946004e2) /* cm^3 */ #define GSL_CONST_CGSM_PINT (4.73176473002e2) /* cm^3 */ #define GSL_CONST_CGSM_CUP (2.36588236501e2) /* cm^3 */ #define GSL_CONST_CGSM_FLUID_OUNCE (2.95735295626e1) /* cm^3 */ #define GSL_CONST_CGSM_TABLESPOON (1.47867647813e1) /* cm^3 */ #define GSL_CONST_CGSM_TEASPOON (4.92892159375e0) /* cm^3 */ #define GSL_CONST_CGSM_CANADIAN_GALLON (4.54609e3) /* cm^3 */ #define GSL_CONST_CGSM_UK_GALLON (4.546092e3) /* cm^3 */ #define GSL_CONST_CGSM_MILES_PER_HOUR (4.4704e1) /* cm / s */ #define GSL_CONST_CGSM_KILOMETERS_PER_HOUR (2.77777777778e1) /* cm / s */ #define GSL_CONST_CGSM_KNOT (5.14444444444e1) /* cm / s */ #define GSL_CONST_CGSM_POUND_MASS (4.5359237e2) /* g */ #define GSL_CONST_CGSM_OUNCE_MASS (2.8349523125e1) /* g */ #define GSL_CONST_CGSM_TON (9.0718474e5) /* g */ #define GSL_CONST_CGSM_METRIC_TON (1e6) /* g */ #define GSL_CONST_CGSM_UK_TON (1.0160469088e6) /* g */ #define GSL_CONST_CGSM_TROY_OUNCE (3.1103475e1) /* g */ #define GSL_CONST_CGSM_CARAT (2e-1) /* g */ #define GSL_CONST_CGSM_UNIFIED_ATOMIC_MASS (1.66053873e-24) /* g */ #define GSL_CONST_CGSM_GRAM_FORCE (9.80665e2) /* cm g / s^2 */ #define GSL_CONST_CGSM_POUND_FORCE (4.44822161526e5) /* cm g / s^2 */ #define GSL_CONST_CGSM_KILOPOUND_FORCE (4.44822161526e8) /* cm g / s^2 */ #define GSL_CONST_CGSM_POUNDAL (1.38255e4) /* cm g / s^2 */ #define GSL_CONST_CGSM_CALORIE (4.1868e7) /* g cm^2 / s^2 */ #define GSL_CONST_CGSM_BTU (1.05505585262e10) /* g cm^2 / s^2 */ #define GSL_CONST_CGSM_THERM (1.05506e15) /* g cm^2 / s^2 */ #define GSL_CONST_CGSM_HORSEPOWER (7.457e9) /* g cm^2 / s^3 */ #define GSL_CONST_CGSM_BAR (1e6) /* g / cm s^2 */ #define GSL_CONST_CGSM_STD_ATMOSPHERE (1.01325e6) /* g / cm s^2 */ #define GSL_CONST_CGSM_TORR (1.33322368421e3) /* g / cm s^2 */ #define GSL_CONST_CGSM_METER_OF_MERCURY (1.33322368421e6) /* g / cm s^2 */ #define GSL_CONST_CGSM_INCH_OF_MERCURY (3.38638815789e4) /* g / cm s^2 */ #define GSL_CONST_CGSM_INCH_OF_WATER (2.490889e3) /* g / cm s^2 */ #define GSL_CONST_CGSM_PSI (6.89475729317e4) /* g / cm s^2 */ #define GSL_CONST_CGSM_POISE (1e0) /* g / cm s */ #define GSL_CONST_CGSM_STOKES (1e0) /* cm^2 / s */ #define GSL_CONST_CGSM_FARADAY (9.6485341472e3) /* abamp s / mol */ #define GSL_CONST_CGSM_ELECTRON_CHARGE (1.602176462e-20) /* abamp s */ #define GSL_CONST_CGSM_GAUSS (1e0) /* g / abamp s^2 */ #define GSL_CONST_CGSM_STILB (1e0) /* cd / cm^2 */ #define GSL_CONST_CGSM_LUMEN (1e0) /* cd sr */ #define GSL_CONST_CGSM_LUX (1e-4) /* cd sr / cm^2 */ #define GSL_CONST_CGSM_PHOT (1e0) /* cd sr / cm^2 */ #define GSL_CONST_CGSM_FOOTCANDLE (1.076e-3) /* cd sr / cm^2 */ #define GSL_CONST_CGSM_LAMBERT (1e0) /* cd sr / cm^2 */ #define GSL_CONST_CGSM_FOOTLAMBERT (1.07639104e-3) /* cd sr / cm^2 */ #define GSL_CONST_CGSM_CURIE (3.7e10) /* 1 / s */ #define GSL_CONST_CGSM_ROENTGEN (2.58e-8) /* abamp s / g */ #define GSL_CONST_CGSM_RAD (1e2) /* cm^2 / s^2 */ #define GSL_CONST_CGSM_SOLAR_MASS (1.98892e33) /* g */ #define GSL_CONST_CGSM_BOHR_RADIUS (5.291772083e-9) /* cm */ #define GSL_CONST_CGSM_NEWTON (1e5) /* cm g / s^2 */ #define GSL_CONST_CGSM_DYNE (1e0) /* cm g / s^2 */ #define GSL_CONST_CGSM_JOULE (1e7) /* g cm^2 / s^2 */ #define GSL_CONST_CGSM_ERG (1e0) /* g cm^2 / s^2 */ #define GSL_CONST_CGSM_STEFAN_BOLTZMANN_CONSTANT (5.67039934436e-5) /* g / K^4 s^3 */ #define GSL_CONST_CGSM_THOMSON_CROSS_SECTION (6.65245853542e-25) /* cm^2 */ #endif /* __GSL_CONST_CGSM__ */ praat-6.0.04/external/gsl/gsl_const_mks.h000066400000000000000000000153751261542461700203600ustar00rootroot00000000000000/* const/gsl_const_mks.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, * 2006 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_CONST_MKS__ #define __GSL_CONST_MKS__ #define GSL_CONST_MKS_SPEED_OF_LIGHT (2.99792458e8) /* m / s */ #define GSL_CONST_MKS_GRAVITATIONAL_CONSTANT (6.673e-11) /* m^3 / kg s^2 */ #define GSL_CONST_MKS_PLANCKS_CONSTANT_H (6.62606876e-34) /* kg m^2 / s */ #define GSL_CONST_MKS_PLANCKS_CONSTANT_HBAR (1.05457159642e-34) /* kg m^2 / s */ #define GSL_CONST_MKS_ASTRONOMICAL_UNIT (1.49597870691e11) /* m */ #define GSL_CONST_MKS_LIGHT_YEAR (9.46053620707e15) /* m */ #define GSL_CONST_MKS_PARSEC (3.08567758135e16) /* m */ #define GSL_CONST_MKS_GRAV_ACCEL (9.80665e0) /* m / s^2 */ #define GSL_CONST_MKS_ELECTRON_VOLT (1.602176462e-19) /* kg m^2 / s^2 */ #define GSL_CONST_MKS_MASS_ELECTRON (9.10938188e-31) /* kg */ #define GSL_CONST_MKS_MASS_MUON (1.88353109e-28) /* kg */ #define GSL_CONST_MKS_MASS_PROTON (1.67262158e-27) /* kg */ #define GSL_CONST_MKS_MASS_NEUTRON (1.67492716e-27) /* kg */ #define GSL_CONST_MKS_RYDBERG (2.17987190389e-18) /* kg m^2 / s^2 */ #define GSL_CONST_MKS_BOLTZMANN (1.3806503e-23) /* kg m^2 / K s^2 */ #define GSL_CONST_MKS_BOHR_MAGNETON (9.27400899e-24) /* A m^2 */ #define GSL_CONST_MKS_NUCLEAR_MAGNETON (5.05078317e-27) /* A m^2 */ #define GSL_CONST_MKS_ELECTRON_MAGNETIC_MOMENT (9.28476362e-24) /* A m^2 */ #define GSL_CONST_MKS_PROTON_MAGNETIC_MOMENT (1.410606633e-26) /* A m^2 */ #define GSL_CONST_MKS_MOLAR_GAS (8.314472e0) /* kg m^2 / K mol s^2 */ #define GSL_CONST_MKS_STANDARD_GAS_VOLUME (2.2710981e-2) /* m^3 / mol */ #define GSL_CONST_MKS_MINUTE (6e1) /* s */ #define GSL_CONST_MKS_HOUR (3.6e3) /* s */ #define GSL_CONST_MKS_DAY (8.64e4) /* s */ #define GSL_CONST_MKS_WEEK (6.048e5) /* s */ #define GSL_CONST_MKS_INCH (2.54e-2) /* m */ #define GSL_CONST_MKS_FOOT (3.048e-1) /* m */ #define GSL_CONST_MKS_YARD (9.144e-1) /* m */ #define GSL_CONST_MKS_MILE (1.609344e3) /* m */ #define GSL_CONST_MKS_NAUTICAL_MILE (1.852e3) /* m */ #define GSL_CONST_MKS_FATHOM (1.8288e0) /* m */ #define GSL_CONST_MKS_MIL (2.54e-5) /* m */ #define GSL_CONST_MKS_POINT (3.52777777778e-4) /* m */ #define GSL_CONST_MKS_TEXPOINT (3.51459803515e-4) /* m */ #define GSL_CONST_MKS_MICRON (1e-6) /* m */ #define GSL_CONST_MKS_ANGSTROM (1e-10) /* m */ #define GSL_CONST_MKS_HECTARE (1e4) /* m^2 */ #define GSL_CONST_MKS_ACRE (4.04685642241e3) /* m^2 */ #define GSL_CONST_MKS_BARN (1e-28) /* m^2 */ #define GSL_CONST_MKS_LITER (1e-3) /* m^3 */ #define GSL_CONST_MKS_US_GALLON (3.78541178402e-3) /* m^3 */ #define GSL_CONST_MKS_QUART (9.46352946004e-4) /* m^3 */ #define GSL_CONST_MKS_PINT (4.73176473002e-4) /* m^3 */ #define GSL_CONST_MKS_CUP (2.36588236501e-4) /* m^3 */ #define GSL_CONST_MKS_FLUID_OUNCE (2.95735295626e-5) /* m^3 */ #define GSL_CONST_MKS_TABLESPOON (1.47867647813e-5) /* m^3 */ #define GSL_CONST_MKS_TEASPOON (4.92892159375e-6) /* m^3 */ #define GSL_CONST_MKS_CANADIAN_GALLON (4.54609e-3) /* m^3 */ #define GSL_CONST_MKS_UK_GALLON (4.546092e-3) /* m^3 */ #define GSL_CONST_MKS_MILES_PER_HOUR (4.4704e-1) /* m / s */ #define GSL_CONST_MKS_KILOMETERS_PER_HOUR (2.77777777778e-1) /* m / s */ #define GSL_CONST_MKS_KNOT (5.14444444444e-1) /* m / s */ #define GSL_CONST_MKS_POUND_MASS (4.5359237e-1) /* kg */ #define GSL_CONST_MKS_OUNCE_MASS (2.8349523125e-2) /* kg */ #define GSL_CONST_MKS_TON (9.0718474e2) /* kg */ #define GSL_CONST_MKS_METRIC_TON (1e3) /* kg */ #define GSL_CONST_MKS_UK_TON (1.0160469088e3) /* kg */ #define GSL_CONST_MKS_TROY_OUNCE (3.1103475e-2) /* kg */ #define GSL_CONST_MKS_CARAT (2e-4) /* kg */ #define GSL_CONST_MKS_UNIFIED_ATOMIC_MASS (1.66053873e-27) /* kg */ #define GSL_CONST_MKS_GRAM_FORCE (9.80665e-3) /* kg m / s^2 */ #define GSL_CONST_MKS_POUND_FORCE (4.44822161526e0) /* kg m / s^2 */ #define GSL_CONST_MKS_KILOPOUND_FORCE (4.44822161526e3) /* kg m / s^2 */ #define GSL_CONST_MKS_POUNDAL (1.38255e-1) /* kg m / s^2 */ #define GSL_CONST_MKS_CALORIE (4.1868e0) /* kg m^2 / s^2 */ #define GSL_CONST_MKS_BTU (1.05505585262e3) /* kg m^2 / s^2 */ #define GSL_CONST_MKS_THERM (1.05506e8) /* kg m^2 / s^2 */ #define GSL_CONST_MKS_HORSEPOWER (7.457e2) /* kg m^2 / s^3 */ #define GSL_CONST_MKS_BAR (1e5) /* kg / m s^2 */ #define GSL_CONST_MKS_STD_ATMOSPHERE (1.01325e5) /* kg / m s^2 */ #define GSL_CONST_MKS_TORR (1.33322368421e2) /* kg / m s^2 */ #define GSL_CONST_MKS_METER_OF_MERCURY (1.33322368421e5) /* kg / m s^2 */ #define GSL_CONST_MKS_INCH_OF_MERCURY (3.38638815789e3) /* kg / m s^2 */ #define GSL_CONST_MKS_INCH_OF_WATER (2.490889e2) /* kg / m s^2 */ #define GSL_CONST_MKS_PSI (6.89475729317e3) /* kg / m s^2 */ #define GSL_CONST_MKS_POISE (1e-1) /* kg m^-1 s^-1 */ #define GSL_CONST_MKS_STOKES (1e-4) /* m^2 / s */ #define GSL_CONST_MKS_FARADAY (9.6485341472e4) /* A s / mol */ #define GSL_CONST_MKS_ELECTRON_CHARGE (1.602176462e-19) /* A s */ #define GSL_CONST_MKS_GAUSS (1e-4) /* kg / A s^2 */ #define GSL_CONST_MKS_STILB (1e4) /* cd / m^2 */ #define GSL_CONST_MKS_LUMEN (1e0) /* cd sr */ #define GSL_CONST_MKS_LUX (1e0) /* cd sr / m^2 */ #define GSL_CONST_MKS_PHOT (1e4) /* cd sr / m^2 */ #define GSL_CONST_MKS_FOOTCANDLE (1.076e1) /* cd sr / m^2 */ #define GSL_CONST_MKS_LAMBERT (1e4) /* cd sr / m^2 */ #define GSL_CONST_MKS_FOOTLAMBERT (1.07639104e1) /* cd sr / m^2 */ #define GSL_CONST_MKS_CURIE (3.7e10) /* 1 / s */ #define GSL_CONST_MKS_ROENTGEN (2.58e-4) /* A s / kg */ #define GSL_CONST_MKS_RAD (1e-2) /* m^2 / s^2 */ #define GSL_CONST_MKS_SOLAR_MASS (1.98892e30) /* kg */ #define GSL_CONST_MKS_BOHR_RADIUS (5.291772083e-11) /* m */ #define GSL_CONST_MKS_NEWTON (1e0) /* kg m / s^2 */ #define GSL_CONST_MKS_DYNE (1e-5) /* kg m / s^2 */ #define GSL_CONST_MKS_JOULE (1e0) /* kg m^2 / s^2 */ #define GSL_CONST_MKS_ERG (1e-7) /* kg m^2 / s^2 */ #define GSL_CONST_MKS_STEFAN_BOLTZMANN_CONSTANT (5.67039934436e-8) /* kg / K^4 s^3 */ #define GSL_CONST_MKS_THOMSON_CROSS_SECTION (6.65245853542e-29) /* m^2 */ #define GSL_CONST_MKS_VACUUM_PERMITTIVITY (8.854187817e-12) /* A^2 s^4 / kg m^3 */ #define GSL_CONST_MKS_VACUUM_PERMEABILITY (1.25663706144e-6) /* kg m / A^2 s^2 */ #define GSL_CONST_MKS_DEBYE (3.33564095198e-30) /* A s^2 / m^2 */ #endif /* __GSL_CONST_MKS__ */ praat-6.0.04/external/gsl/gsl_const_mksa.h000066400000000000000000000155461261542461700205210ustar00rootroot00000000000000/* const/gsl_const_mksa.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, * 2006 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_CONST_MKSA__ #define __GSL_CONST_MKSA__ #define GSL_CONST_MKSA_SPEED_OF_LIGHT (2.99792458e8) /* m / s */ #define GSL_CONST_MKSA_GRAVITATIONAL_CONSTANT (6.673e-11) /* m^3 / kg s^2 */ #define GSL_CONST_MKSA_PLANCKS_CONSTANT_H (6.62606876e-34) /* kg m^2 / s */ #define GSL_CONST_MKSA_PLANCKS_CONSTANT_HBAR (1.05457159642e-34) /* kg m^2 / s */ #define GSL_CONST_MKSA_ASTRONOMICAL_UNIT (1.49597870691e11) /* m */ #define GSL_CONST_MKSA_LIGHT_YEAR (9.46053620707e15) /* m */ #define GSL_CONST_MKSA_PARSEC (3.08567758135e16) /* m */ #define GSL_CONST_MKSA_GRAV_ACCEL (9.80665e0) /* m / s^2 */ #define GSL_CONST_MKSA_ELECTRON_VOLT (1.602176462e-19) /* kg m^2 / s^2 */ #define GSL_CONST_MKSA_MASS_ELECTRON (9.10938188e-31) /* kg */ #define GSL_CONST_MKSA_MASS_MUON (1.88353109e-28) /* kg */ #define GSL_CONST_MKSA_MASS_PROTON (1.67262158e-27) /* kg */ #define GSL_CONST_MKSA_MASS_NEUTRON (1.67492716e-27) /* kg */ #define GSL_CONST_MKSA_RYDBERG (2.17987190389e-18) /* kg m^2 / s^2 */ #define GSL_CONST_MKSA_BOLTZMANN (1.3806503e-23) /* kg m^2 / K s^2 */ #define GSL_CONST_MKSA_BOHR_MAGNETON (9.27400899e-24) /* A m^2 */ #define GSL_CONST_MKSA_NUCLEAR_MAGNETON (5.05078317e-27) /* A m^2 */ #define GSL_CONST_MKSA_ELECTRON_MAGNETIC_MOMENT (9.28476362e-24) /* A m^2 */ #define GSL_CONST_MKSA_PROTON_MAGNETIC_MOMENT (1.410606633e-26) /* A m^2 */ #define GSL_CONST_MKSA_MOLAR_GAS (8.314472e0) /* kg m^2 / K mol s^2 */ #define GSL_CONST_MKSA_STANDARD_GAS_VOLUME (2.2710981e-2) /* m^3 / mol */ #define GSL_CONST_MKSA_MINUTE (6e1) /* s */ #define GSL_CONST_MKSA_HOUR (3.6e3) /* s */ #define GSL_CONST_MKSA_DAY (8.64e4) /* s */ #define GSL_CONST_MKSA_WEEK (6.048e5) /* s */ #define GSL_CONST_MKSA_INCH (2.54e-2) /* m */ #define GSL_CONST_MKSA_FOOT (3.048e-1) /* m */ #define GSL_CONST_MKSA_YARD (9.144e-1) /* m */ #define GSL_CONST_MKSA_MILE (1.609344e3) /* m */ #define GSL_CONST_MKSA_NAUTICAL_MILE (1.852e3) /* m */ #define GSL_CONST_MKSA_FATHOM (1.8288e0) /* m */ #define GSL_CONST_MKSA_MIL (2.54e-5) /* m */ #define GSL_CONST_MKSA_POINT (3.52777777778e-4) /* m */ #define GSL_CONST_MKSA_TEXPOINT (3.51459803515e-4) /* m */ #define GSL_CONST_MKSA_MICRON (1e-6) /* m */ #define GSL_CONST_MKSA_ANGSTROM (1e-10) /* m */ #define GSL_CONST_MKSA_HECTARE (1e4) /* m^2 */ #define GSL_CONST_MKSA_ACRE (4.04685642241e3) /* m^2 */ #define GSL_CONST_MKSA_BARN (1e-28) /* m^2 */ #define GSL_CONST_MKSA_LITER (1e-3) /* m^3 */ #define GSL_CONST_MKSA_US_GALLON (3.78541178402e-3) /* m^3 */ #define GSL_CONST_MKSA_QUART (9.46352946004e-4) /* m^3 */ #define GSL_CONST_MKSA_PINT (4.73176473002e-4) /* m^3 */ #define GSL_CONST_MKSA_CUP (2.36588236501e-4) /* m^3 */ #define GSL_CONST_MKSA_FLUID_OUNCE (2.95735295626e-5) /* m^3 */ #define GSL_CONST_MKSA_TABLESPOON (1.47867647813e-5) /* m^3 */ #define GSL_CONST_MKSA_TEASPOON (4.92892159375e-6) /* m^3 */ #define GSL_CONST_MKSA_CANADIAN_GALLON (4.54609e-3) /* m^3 */ #define GSL_CONST_MKSA_UK_GALLON (4.546092e-3) /* m^3 */ #define GSL_CONST_MKSA_MILES_PER_HOUR (4.4704e-1) /* m / s */ #define GSL_CONST_MKSA_KILOMETERS_PER_HOUR (2.77777777778e-1) /* m / s */ #define GSL_CONST_MKSA_KNOT (5.14444444444e-1) /* m / s */ #define GSL_CONST_MKSA_POUND_MASS (4.5359237e-1) /* kg */ #define GSL_CONST_MKSA_OUNCE_MASS (2.8349523125e-2) /* kg */ #define GSL_CONST_MKSA_TON (9.0718474e2) /* kg */ #define GSL_CONST_MKSA_METRIC_TON (1e3) /* kg */ #define GSL_CONST_MKSA_UK_TON (1.0160469088e3) /* kg */ #define GSL_CONST_MKSA_TROY_OUNCE (3.1103475e-2) /* kg */ #define GSL_CONST_MKSA_CARAT (2e-4) /* kg */ #define GSL_CONST_MKSA_UNIFIED_ATOMIC_MASS (1.66053873e-27) /* kg */ #define GSL_CONST_MKSA_GRAM_FORCE (9.80665e-3) /* kg m / s^2 */ #define GSL_CONST_MKSA_POUND_FORCE (4.44822161526e0) /* kg m / s^2 */ #define GSL_CONST_MKSA_KILOPOUND_FORCE (4.44822161526e3) /* kg m / s^2 */ #define GSL_CONST_MKSA_POUNDAL (1.38255e-1) /* kg m / s^2 */ #define GSL_CONST_MKSA_CALORIE (4.1868e0) /* kg m^2 / s^2 */ #define GSL_CONST_MKSA_BTU (1.05505585262e3) /* kg m^2 / s^2 */ #define GSL_CONST_MKSA_THERM (1.05506e8) /* kg m^2 / s^2 */ #define GSL_CONST_MKSA_HORSEPOWER (7.457e2) /* kg m^2 / s^3 */ #define GSL_CONST_MKSA_BAR (1e5) /* kg / m s^2 */ #define GSL_CONST_MKSA_STD_ATMOSPHERE (1.01325e5) /* kg / m s^2 */ #define GSL_CONST_MKSA_TORR (1.33322368421e2) /* kg / m s^2 */ #define GSL_CONST_MKSA_METER_OF_MERCURY (1.33322368421e5) /* kg / m s^2 */ #define GSL_CONST_MKSA_INCH_OF_MERCURY (3.38638815789e3) /* kg / m s^2 */ #define GSL_CONST_MKSA_INCH_OF_WATER (2.490889e2) /* kg / m s^2 */ #define GSL_CONST_MKSA_PSI (6.89475729317e3) /* kg / m s^2 */ #define GSL_CONST_MKSA_POISE (1e-1) /* kg m^-1 s^-1 */ #define GSL_CONST_MKSA_STOKES (1e-4) /* m^2 / s */ #define GSL_CONST_MKSA_FARADAY (9.6485341472e4) /* A s / mol */ #define GSL_CONST_MKSA_ELECTRON_CHARGE (1.602176462e-19) /* A s */ #define GSL_CONST_MKSA_GAUSS (1e-4) /* kg / A s^2 */ #define GSL_CONST_MKSA_STILB (1e4) /* cd / m^2 */ #define GSL_CONST_MKSA_LUMEN (1e0) /* cd sr */ #define GSL_CONST_MKSA_LUX (1e0) /* cd sr / m^2 */ #define GSL_CONST_MKSA_PHOT (1e4) /* cd sr / m^2 */ #define GSL_CONST_MKSA_FOOTCANDLE (1.076e1) /* cd sr / m^2 */ #define GSL_CONST_MKSA_LAMBERT (1e4) /* cd sr / m^2 */ #define GSL_CONST_MKSA_FOOTLAMBERT (1.07639104e1) /* cd sr / m^2 */ #define GSL_CONST_MKSA_CURIE (3.7e10) /* 1 / s */ #define GSL_CONST_MKSA_ROENTGEN (2.58e-4) /* A s / kg */ #define GSL_CONST_MKSA_RAD (1e-2) /* m^2 / s^2 */ #define GSL_CONST_MKSA_SOLAR_MASS (1.98892e30) /* kg */ #define GSL_CONST_MKSA_BOHR_RADIUS (5.291772083e-11) /* m */ #define GSL_CONST_MKSA_NEWTON (1e0) /* kg m / s^2 */ #define GSL_CONST_MKSA_DYNE (1e-5) /* kg m / s^2 */ #define GSL_CONST_MKSA_JOULE (1e0) /* kg m^2 / s^2 */ #define GSL_CONST_MKSA_ERG (1e-7) /* kg m^2 / s^2 */ #define GSL_CONST_MKSA_STEFAN_BOLTZMANN_CONSTANT (5.67039934436e-8) /* kg / K^4 s^3 */ #define GSL_CONST_MKSA_THOMSON_CROSS_SECTION (6.65245853542e-29) /* m^2 */ #define GSL_CONST_MKSA_VACUUM_PERMITTIVITY (8.854187817e-12) /* A^2 s^4 / kg m^3 */ #define GSL_CONST_MKSA_VACUUM_PERMEABILITY (1.25663706144e-6) /* kg m / A^2 s^2 */ #define GSL_CONST_MKSA_DEBYE (3.33564095198e-30) /* A s^2 / m^2 */ #endif /* __GSL_CONST_MKSA__ */ praat-6.0.04/external/gsl/gsl_const_num.h000066400000000000000000000033171261542461700203560ustar00rootroot00000000000000/* const/gsl_const_num.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, * 2006 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_CONST_NUM__ #define __GSL_CONST_NUM__ #define GSL_CONST_NUM_FINE_STRUCTURE (7.297352533e-3) /* 1 */ #define GSL_CONST_NUM_AVOGADRO (6.02214199e23) /* 1 / mol */ #define GSL_CONST_NUM_YOTTA (1e24) /* 1 */ #define GSL_CONST_NUM_ZETTA (1e21) /* 1 */ #define GSL_CONST_NUM_EXA (1e18) /* 1 */ #define GSL_CONST_NUM_PETA (1e15) /* 1 */ #define GSL_CONST_NUM_TERA (1e12) /* 1 */ #define GSL_CONST_NUM_GIGA (1e9) /* 1 */ #define GSL_CONST_NUM_MEGA (1e6) /* 1 */ #define GSL_CONST_NUM_KILO (1e3) /* 1 */ #define GSL_CONST_NUM_MILLI (1e-3) /* 1 */ #define GSL_CONST_NUM_MICRO (1e-6) /* 1 */ #define GSL_CONST_NUM_NANO (1e-9) /* 1 */ #define GSL_CONST_NUM_PICO (1e-12) /* 1 */ #define GSL_CONST_NUM_FEMTO (1e-15) /* 1 */ #define GSL_CONST_NUM_ATTO (1e-18) /* 1 */ #define GSL_CONST_NUM_ZEPTO (1e-21) /* 1 */ #define GSL_CONST_NUM_YOCTO (1e-24) /* 1 */ #endif /* __GSL_CONST_NUM__ */ praat-6.0.04/external/gsl/gsl_deriv.h000066400000000000000000000030301261542461700174520ustar00rootroot00000000000000/* deriv/gsl_deriv.h * * Copyright (C) 2000 David Morrison * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_DERIV_H__ #define __GSL_DERIV_H__ #include "gsl_math.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_deriv_central (const gsl_function *f, double x, double h, double *result, double *abserr); int gsl_deriv_backward (const gsl_function *f, double x, double h, double *result, double *abserr); int gsl_deriv_forward (const gsl_function *f, double x, double h, double *result, double *abserr); __END_DECLS #endif /* __GSL_DERIV_H__ */ praat-6.0.04/external/gsl/gsl_deriv__deriv.c000066400000000000000000000134211261542461700210020ustar00rootroot00000000000000/* deriv/deriv.c * * Copyright (C) 2004, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_deriv.h" static void central_deriv (const gsl_function * f, double x, double h, double *result, double *abserr_round, double *abserr_trunc) { /* Compute the derivative using the 5-point rule (x-h, x-h/2, x, x+h/2, x+h). Note that the central point is not used. Compute the error using the difference between the 5-point and the 3-point rule (x-h,x,x+h). Again the central point is not used. */ double fm1 = GSL_FN_EVAL (f, x - h); double fp1 = GSL_FN_EVAL (f, x + h); double fmh = GSL_FN_EVAL (f, x - h / 2); double fph = GSL_FN_EVAL (f, x + h / 2); double r3 = 0.5 * (fp1 - fm1); double r5 = (4.0 / 3.0) * (fph - fmh) - (1.0 / 3.0) * r3; double e3 = (fabs (fp1) + fabs (fm1)) * GSL_DBL_EPSILON; double e5 = 2.0 * (fabs (fph) + fabs (fmh)) * GSL_DBL_EPSILON + e3; /* The next term is due to finite precision in x+h = O (eps * x) */ double dy = GSL_MAX (fabs (r3 / h), fabs (r5 / h)) *(fabs (x) / h) * GSL_DBL_EPSILON; /* The truncation error in the r5 approximation itself is O(h^4). However, for safety, we estimate the error from r5-r3, which is O(h^2). By scaling h we will minimise this estimated error, not the actual truncation error in r5. */ *result = r5 / h; *abserr_trunc = fabs ((r5 - r3) / h); /* Estimated truncation error O(h^2) */ *abserr_round = fabs (e5 / h) + dy; /* Rounding error (cancellations) */ } int gsl_deriv_central (const gsl_function * f, double x, double h, double *result, double *abserr) { double r_0, round, trunc, error; central_deriv (f, x, h, &r_0, &round, &trunc); error = round + trunc; if (round < trunc && (round > 0 && trunc > 0)) { double r_opt, round_opt, trunc_opt, error_opt; /* Compute an optimised stepsize to minimize the total error, using the scaling of the truncation error (O(h^2)) and rounding error (O(1/h)). */ double h_opt = h * pow (round / (2.0 * trunc), 1.0 / 3.0); central_deriv (f, x, h_opt, &r_opt, &round_opt, &trunc_opt); error_opt = round_opt + trunc_opt; /* Check that the new error is smaller, and that the new derivative is consistent with the error bounds of the original estimate. */ if (error_opt < error && fabs (r_opt - r_0) < 4.0 * error) { r_0 = r_opt; error = error_opt; } } *result = r_0; *abserr = error; return GSL_SUCCESS; } static void forward_deriv (const gsl_function * f, double x, double h, double *result, double *abserr_round, double *abserr_trunc) { /* Compute the derivative using the 4-point rule (x+h/4, x+h/2, x+3h/4, x+h). Compute the error using the difference between the 4-point and the 2-point rule (x+h/2,x+h). */ double f1 = GSL_FN_EVAL (f, x + h / 4.0); double f2 = GSL_FN_EVAL (f, x + h / 2.0); double f3 = GSL_FN_EVAL (f, x + (3.0 / 4.0) * h); double f4 = GSL_FN_EVAL (f, x + h); double r2 = 2.0*(f4 - f2); double r4 = (22.0 / 3.0) * (f4 - f3) - (62.0 / 3.0) * (f3 - f2) + (52.0 / 3.0) * (f2 - f1); /* Estimate the rounding error for r4 */ double e4 = 2 * 20.67 * (fabs (f4) + fabs (f3) + fabs (f2) + fabs (f1)) * GSL_DBL_EPSILON; /* The next term is due to finite precision in x+h = O (eps * x) */ double dy = GSL_MAX (fabs (r2 / h), fabs (r4 / h)) * fabs (x / h) * GSL_DBL_EPSILON; /* The truncation error in the r4 approximation itself is O(h^3). However, for safety, we estimate the error from r4-r2, which is O(h). By scaling h we will minimise this estimated error, not the actual truncation error in r4. */ *result = r4 / h; *abserr_trunc = fabs ((r4 - r2) / h); /* Estimated truncation error O(h) */ *abserr_round = fabs (e4 / h) + dy; } int gsl_deriv_forward (const gsl_function * f, double x, double h, double *result, double *abserr) { double r_0, round, trunc, error; forward_deriv (f, x, h, &r_0, &round, &trunc); error = round + trunc; if (round < trunc && (round > 0 && trunc > 0)) { double r_opt, round_opt, trunc_opt, error_opt; /* Compute an optimised stepsize to minimize the total error, using the scaling of the estimated truncation error (O(h)) and rounding error (O(1/h)). */ double h_opt = h * pow (round / (trunc), 1.0 / 2.0); forward_deriv (f, x, h_opt, &r_opt, &round_opt, &trunc_opt); error_opt = round_opt + trunc_opt; /* Check that the new error is smaller, and that the new derivative is consistent with the error bounds of the original estimate. */ if (error_opt < error && fabs (r_opt - r_0) < 4.0 * error) { r_0 = r_opt; error = error_opt; } } *result = r_0; *abserr = error; return GSL_SUCCESS; } int gsl_deriv_backward (const gsl_function * f, double x, double h, double *result, double *abserr) { return gsl_deriv_forward (f, x, -h, result, abserr); } praat-6.0.04/external/gsl/gsl_dft_complex.h000066400000000000000000000034121261542461700206510ustar00rootroot00000000000000/* fft/gsl_dft_complex.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_DFT_COMPLEX_H__ #define __GSL_DFT_COMPLEX_H__ #include #include "gsl_math.h" #include "gsl_complex.h" #include "gsl_fft.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_dft_complex_forward (const double data[], const size_t stride, const size_t n, double result[]); int gsl_dft_complex_backward (const double data[], const size_t stride, const size_t n, double result[]); int gsl_dft_complex_inverse (const double data[], const size_t stride, const size_t n, double result[]); int gsl_dft_complex_transform (const double data[], const size_t stride, const size_t n, double result[], const gsl_fft_direction sign); __END_DECLS #endif /* __GSL_DFT_COMPLEX_H__ */ praat-6.0.04/external/gsl/gsl_dft_complex_float.h000066400000000000000000000034621261542461700220430ustar00rootroot00000000000000/* fft/gsl_dft_complex_float.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_DFT_COMPLEX_FLOAT_H__ #define __GSL_DFT_COMPLEX_FLOAT_H__ #include #include "gsl_math.h" #include "gsl_complex.h" #include "gsl_fft.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_dft_complex_float_forward (const float data[], const size_t stride, const size_t n, float result[]); int gsl_dft_complex_float_backward (const float data[], const size_t stride, const size_t n, float result[]); int gsl_dft_complex_float_inverse (const float data[], const size_t stride, const size_t n, float result[]); int gsl_dft_complex_float_transform (const float data[], const size_t stride, const size_t n, float result[], const gsl_fft_direction sign); __END_DECLS #endif /* __GSL_DFT_COMPLEX_FLOAT_H__ */ praat-6.0.04/external/gsl/gsl_dht.h000066400000000000000000000051051261542461700171250ustar00rootroot00000000000000/* dht/gsl_dht.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_DHT_H__ #define __GSL_DHT_H__ #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS struct gsl_dht_struct { size_t size; /* size of the sample arrays to be transformed */ double nu; /* Bessel function order */ double xmax; /* the upper limit to the x-sampling domain */ double kmax; /* the upper limit to the k-sampling domain */ double * j; /* array of computed J_nu zeros, j_{nu,s} = j[s] */ double * Jjj; /* transform numerator, J_nu(j_i j_m / j_N) */ double * J2; /* transform denominator, J_{nu+1}^2(j_m) */ }; typedef struct gsl_dht_struct gsl_dht; /* Create a new transform object for a given size * sampling array on the domain [0, xmax]. */ gsl_dht * gsl_dht_alloc(size_t size); gsl_dht * gsl_dht_new(size_t size, double nu, double xmax); /* Recalculate a transform object for given values of nu, xmax. * You cannot change the size of the object since the internal * allocation is reused. */ int gsl_dht_init(gsl_dht * t, double nu, double xmax); /* The n'th computed x sample point for a given transform. * 0 <= n <= size-1 */ double gsl_dht_x_sample(const gsl_dht * t, int n); /* The n'th computed k sample point for a given transform. * 0 <= n <= size-1 */ double gsl_dht_k_sample(const gsl_dht * t, int n); /* Free a transform object. */ void gsl_dht_free(gsl_dht * t); /* Perform a transform on a sampled array. * f_in[0] ... f_in[size-1] and similarly for f_out[] */ int gsl_dht_apply(const gsl_dht * t, double * f_in, double * f_out); __END_DECLS #endif /* __GSL_DHT_H__ */ praat-6.0.04/external/gsl/gsl_dht__dht.c000066400000000000000000000112551261542461700201210ustar00rootroot00000000000000/* dht/dht.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_math.h" #include "gsl_sf_bessel.h" #include "gsl_dht.h" gsl_dht * gsl_dht_alloc (size_t size) { gsl_dht * t; if(size == 0) { GSL_ERROR_VAL("size == 0", GSL_EDOM, 0); } t = (gsl_dht *)malloc(sizeof(gsl_dht)); if(t == 0) { GSL_ERROR_VAL("out of memory", GSL_ENOMEM, 0); } t->size = size; t->xmax = -1.0; /* Make it clear that this needs to be calculated. */ t->nu = -1.0; t->j = (double *)malloc((size+2)*sizeof(double)); if(t->j == 0) { free(t); GSL_ERROR_VAL("could not allocate memory for j", GSL_ENOMEM, 0); } t->Jjj = (double *)malloc(size*(size+1)/2 * sizeof(double)); if(t->Jjj == 0) { free(t->j); free(t); GSL_ERROR_VAL("could not allocate memory for Jjj", GSL_ENOMEM, 0); } t->J2 = (double *)malloc((size+1)*sizeof(double)); if(t->J2 == 0) { free(t->Jjj); free(t->j); free(t); GSL_ERROR_VAL("could not allocate memory for J2", GSL_ENOMEM, 0); } return t; } /* Handle internal calculation of Bessel zeros. */ static int dht_bessel_zeros(gsl_dht * t) { unsigned int s; gsl_sf_result z; int stat_z = 0; t->j[0] = 0.0; for(s=1; s < t->size + 2; s++) { stat_z += gsl_sf_bessel_zero_Jnu_e(t->nu, s, &z); t->j[s] = z.val; } if(stat_z != 0) { GSL_ERROR("could not compute bessel zeroes", GSL_EFAILED); } else { return GSL_SUCCESS; } } gsl_dht * gsl_dht_new (size_t size, double nu, double xmax) { int status; gsl_dht * dht = gsl_dht_alloc (size); if (dht == 0) return 0; status = gsl_dht_init(dht, nu, xmax); if (status) return 0; return dht; } int gsl_dht_init(gsl_dht * t, double nu, double xmax) { if(xmax <= 0.0) { GSL_ERROR ("xmax is not positive", GSL_EDOM); } else if(nu < 0.0) { GSL_ERROR ("nu is negative", GSL_EDOM); } else { size_t n, m; int stat_bz = GSL_SUCCESS; int stat_J = 0; double jN; if(nu != t->nu) { /* Recalculate Bessel zeros if necessary. */ t->nu = nu; stat_bz = dht_bessel_zeros(t); } jN = t->j[t->size+1]; t->xmax = xmax; t->kmax = jN / xmax; t->J2[0] = 0.0; for(m=1; msize+1; m++) { gsl_sf_result J; stat_J += gsl_sf_bessel_Jnu_e(nu + 1.0, t->j[m], &J); t->J2[m] = J.val * J.val; } /* J_nu(j[n] j[m] / j[N]) = Jjj[n(n-1)/2 + m - 1], 1 <= n,m <= size */ for(n=1; nsize+1; n++) { for(m=1; m<=n; m++) { double arg = t->j[n] * t->j[m] / jN; gsl_sf_result J; stat_J += gsl_sf_bessel_Jnu_e(nu, arg, &J); t->Jjj[n*(n-1)/2 + m - 1] = J.val; } } if(stat_J != 0) { GSL_ERROR("error computing bessel function", GSL_EFAILED); } else { return stat_bz; } } } double gsl_dht_x_sample(const gsl_dht * t, int n) { return t->j[n+1]/t->j[t->size+1] * t->xmax; } double gsl_dht_k_sample(const gsl_dht * t, int n) { return t->j[n+1] / t->xmax; } void gsl_dht_free(gsl_dht * t) { free(t->J2); free(t->Jjj); free(t->j); free(t); } int gsl_dht_apply(const gsl_dht * t, double * f_in, double * f_out) { const double jN = t->j[t->size + 1]; const double r = t->xmax / jN; size_t m; size_t i; for(m=0; msize; m++) { double sum = 0.0; double Y; for(i=0; isize; i++) { /* Need to find max and min so that we * address the symmetric Jjj matrix properly. * FIXME: we can presumably optimize this * by just running over the elements of Jjj * in a deterministic manner. */ size_t m_local; size_t n_local; if(i < m) { m_local = i; n_local = m; } else { m_local = m; n_local = i; } Y = t->Jjj[n_local*(n_local+1)/2 + m_local] / t->J2[i+1]; sum += Y * f_in[i]; } f_out[m] = sum * 2.0 * r*r; } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_diff.h000066400000000000000000000027541261542461700172650ustar00rootroot00000000000000/* diff/gsl_diff.h * * Copyright (C) 2000 David Morrison * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_DIFF_H__ #define __GSL_DIFF_H__ #include "gsl_math.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_diff_central (const gsl_function *f, double x, double *result, double *abserr); int gsl_diff_backward (const gsl_function *f, double x, double *result, double *abserr); int gsl_diff_forward (const gsl_function *f, double x, double *result, double *abserr); __END_DECLS #endif /* __GSL_DIFF_H__ */ praat-6.0.04/external/gsl/gsl_diff__diff.c000066400000000000000000000112331261542461700203770ustar00rootroot00000000000000/* diff/diff.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 David Morrison * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_diff.h" int gsl_diff_backward (const gsl_function * f, double x, double *result, double *abserr) { /* Construct a divided difference table with a fairly large step size to get a very rough estimate of f''. Use this to estimate the step size which will minimize the error in calculating f'. */ int i, k; double h = GSL_SQRT_DBL_EPSILON; double a[3], d[3], a2; /* Algorithm based on description on pg. 204 of Conte and de Boor (CdB) - coefficients of Newton form of polynomial of degree 2. */ for (i = 0; i < 3; i++) { a[i] = x + (i - 2.0) * h; d[i] = GSL_FN_EVAL (f, a[i]); } for (k = 1; k < 4; k++) { for (i = 0; i < 3 - k; i++) { d[i] = (d[i + 1] - d[i]) / (a[i + k] - a[i]); } } /* Adapt procedure described on pg. 282 of CdB to find best value of step size. */ a2 = fabs (d[0] + d[1] + d[2]); if (a2 < 100.0 * GSL_SQRT_DBL_EPSILON) { a2 = 100.0 * GSL_SQRT_DBL_EPSILON; } h = sqrt (GSL_SQRT_DBL_EPSILON / (2.0 * a2)); if (h > 100.0 * GSL_SQRT_DBL_EPSILON) { h = 100.0 * GSL_SQRT_DBL_EPSILON; } *result = (GSL_FN_EVAL (f, x) - GSL_FN_EVAL (f, x - h)) / h; *abserr = fabs (10.0 * a2 * h); return GSL_SUCCESS; } int gsl_diff_forward (const gsl_function * f, double x, double *result, double *abserr) { /* Construct a divided difference table with a fairly large step size to get a very rough estimate of f''. Use this to estimate the step size which will minimize the error in calculating f'. */ int i, k; double h = GSL_SQRT_DBL_EPSILON; double a[3], d[3], a2; /* Algorithm based on description on pg. 204 of Conte and de Boor (CdB) - coefficients of Newton form of polynomial of degree 2. */ for (i = 0; i < 3; i++) { a[i] = x + i * h; d[i] = GSL_FN_EVAL (f, a[i]); } for (k = 1; k < 4; k++) { for (i = 0; i < 3 - k; i++) { d[i] = (d[i + 1] - d[i]) / (a[i + k] - a[i]); } } /* Adapt procedure described on pg. 282 of CdB to find best value of step size. */ a2 = fabs (d[0] + d[1] + d[2]); if (a2 < 100.0 * GSL_SQRT_DBL_EPSILON) { a2 = 100.0 * GSL_SQRT_DBL_EPSILON; } h = sqrt (GSL_SQRT_DBL_EPSILON / (2.0 * a2)); if (h > 100.0 * GSL_SQRT_DBL_EPSILON) { h = 100.0 * GSL_SQRT_DBL_EPSILON; } *result = (GSL_FN_EVAL (f, x + h) - GSL_FN_EVAL (f, x)) / h; *abserr = fabs (10.0 * a2 * h); return GSL_SUCCESS; } int gsl_diff_central (const gsl_function * f, double x, double *result, double *abserr) { /* Construct a divided difference table with a fairly large step size to get a very rough estimate of f'''. Use this to estimate the step size which will minimize the error in calculating f'. */ int i, k; double h = GSL_SQRT_DBL_EPSILON; double a[4], d[4], a3; /* Algorithm based on description on pg. 204 of Conte and de Boor (CdB) - coefficients of Newton form of polynomial of degree 3. */ for (i = 0; i < 4; i++) { a[i] = x + (i - 2.0) * h; d[i] = GSL_FN_EVAL (f, a[i]); } for (k = 1; k < 5; k++) { for (i = 0; i < 4 - k; i++) { d[i] = (d[i + 1] - d[i]) / (a[i + k] - a[i]); } } /* Adapt procedure described on pg. 282 of CdB to find best value of step size. */ a3 = fabs (d[0] + d[1] + d[2] + d[3]); if (a3 < 100.0 * GSL_SQRT_DBL_EPSILON) { a3 = 100.0 * GSL_SQRT_DBL_EPSILON; } h = pow (GSL_SQRT_DBL_EPSILON / (2.0 * a3), 1.0 / 3.0); if (h > 100.0 * GSL_SQRT_DBL_EPSILON) { h = 100.0 * GSL_SQRT_DBL_EPSILON; } *result = (GSL_FN_EVAL (f, x + h) - GSL_FN_EVAL (f, x - h)) / (2.0 * h); *abserr = fabs (100.0 * a3 * h * h); return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_eigen.h000066400000000000000000000315351261542461700174430ustar00rootroot00000000000000/* eigen/gsl_eigen.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2006, 2007 Gerard Jungman, Brian Gough, Patrick Alken * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_EIGEN_H__ #define __GSL_EIGEN_H__ #include "gsl_vector.h" #include "gsl_matrix.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size; double * d; double * sd; } gsl_eigen_symm_workspace; gsl_eigen_symm_workspace * gsl_eigen_symm_alloc (const size_t n); void gsl_eigen_symm_free (gsl_eigen_symm_workspace * w); int gsl_eigen_symm (gsl_matrix * A, gsl_vector * eval, gsl_eigen_symm_workspace * w); typedef struct { size_t size; double * d; double * sd; double * gc; double * gs; } gsl_eigen_symmv_workspace; gsl_eigen_symmv_workspace * gsl_eigen_symmv_alloc (const size_t n); void gsl_eigen_symmv_free (gsl_eigen_symmv_workspace * w); int gsl_eigen_symmv (gsl_matrix * A, gsl_vector * eval, gsl_matrix * evec, gsl_eigen_symmv_workspace * w); typedef struct { size_t size; double * d; double * sd; double * tau; } gsl_eigen_herm_workspace; gsl_eigen_herm_workspace * gsl_eigen_herm_alloc (const size_t n); void gsl_eigen_herm_free (gsl_eigen_herm_workspace * w); int gsl_eigen_herm (gsl_matrix_complex * A, gsl_vector * eval, gsl_eigen_herm_workspace * w); typedef struct { size_t size; double * d; double * sd; double * tau; double * gc; double * gs; } gsl_eigen_hermv_workspace; gsl_eigen_hermv_workspace * gsl_eigen_hermv_alloc (const size_t n); void gsl_eigen_hermv_free (gsl_eigen_hermv_workspace * w); int gsl_eigen_hermv (gsl_matrix_complex * A, gsl_vector * eval, gsl_matrix_complex * evec, gsl_eigen_hermv_workspace * w); typedef struct { size_t size; /* matrix size */ size_t max_iterations; /* max iterations since last eigenvalue found */ size_t n_iter; /* number of iterations since last eigenvalue found */ size_t n_evals; /* number of eigenvalues found so far */ int compute_t; /* compute Schur form T = Z^t A Z */ gsl_matrix *H; /* pointer to Hessenberg matrix */ gsl_matrix *Z; /* pointer to Schur vector matrix */ } gsl_eigen_francis_workspace; gsl_eigen_francis_workspace * gsl_eigen_francis_alloc (void); void gsl_eigen_francis_free (gsl_eigen_francis_workspace * w); void gsl_eigen_francis_T (const int compute_t, gsl_eigen_francis_workspace * w); int gsl_eigen_francis (gsl_matrix * H, gsl_vector_complex * eval, gsl_eigen_francis_workspace * w); int gsl_eigen_francis_Z (gsl_matrix * H, gsl_vector_complex * eval, gsl_matrix * Z, gsl_eigen_francis_workspace * w); typedef struct { size_t size; /* size of matrices */ gsl_vector *diag; /* diagonal matrix elements from balancing */ gsl_vector *tau; /* Householder coefficients */ gsl_matrix *Z; /* pointer to Z matrix */ int do_balance; /* perform balancing transformation? */ size_t n_evals; /* number of eigenvalues found */ gsl_eigen_francis_workspace *francis_workspace_p; } gsl_eigen_nonsymm_workspace; gsl_eigen_nonsymm_workspace * gsl_eigen_nonsymm_alloc (const size_t n); void gsl_eigen_nonsymm_free (gsl_eigen_nonsymm_workspace * w); void gsl_eigen_nonsymm_params (const int compute_t, const int balance, gsl_eigen_nonsymm_workspace *w); int gsl_eigen_nonsymm (gsl_matrix * A, gsl_vector_complex * eval, gsl_eigen_nonsymm_workspace * w); int gsl_eigen_nonsymm_Z (gsl_matrix * A, gsl_vector_complex * eval, gsl_matrix * Z, gsl_eigen_nonsymm_workspace * w); typedef struct { size_t size; /* size of matrices */ gsl_vector *work; /* scratch workspace */ gsl_vector *work2; /* scratch workspace */ gsl_vector *work3; /* scratch workspace */ gsl_matrix *Z; /* pointer to Schur vectors */ gsl_eigen_nonsymm_workspace *nonsymm_workspace_p; } gsl_eigen_nonsymmv_workspace; gsl_eigen_nonsymmv_workspace * gsl_eigen_nonsymmv_alloc (const size_t n); void gsl_eigen_nonsymmv_free (gsl_eigen_nonsymmv_workspace * w); int gsl_eigen_nonsymmv (gsl_matrix * A, gsl_vector_complex * eval, gsl_matrix_complex * evec, gsl_eigen_nonsymmv_workspace * w); int gsl_eigen_nonsymmv_Z (gsl_matrix * A, gsl_vector_complex * eval, gsl_matrix_complex * evec, gsl_matrix * Z, gsl_eigen_nonsymmv_workspace * w); typedef struct { size_t size; /* size of matrices */ gsl_eigen_symm_workspace *symm_workspace_p; } gsl_eigen_gensymm_workspace; gsl_eigen_gensymm_workspace * gsl_eigen_gensymm_alloc (const size_t n); void gsl_eigen_gensymm_free (gsl_eigen_gensymm_workspace * w); int gsl_eigen_gensymm (gsl_matrix * A, gsl_matrix * B, gsl_vector * eval, gsl_eigen_gensymm_workspace * w); int gsl_eigen_gensymm_standardize (gsl_matrix * A, const gsl_matrix * B); typedef struct { size_t size; /* size of matrices */ gsl_eigen_symmv_workspace *symmv_workspace_p; } gsl_eigen_gensymmv_workspace; gsl_eigen_gensymmv_workspace * gsl_eigen_gensymmv_alloc (const size_t n); void gsl_eigen_gensymmv_free (gsl_eigen_gensymmv_workspace * w); int gsl_eigen_gensymmv (gsl_matrix * A, gsl_matrix * B, gsl_vector * eval, gsl_matrix * evec, gsl_eigen_gensymmv_workspace * w); typedef struct { size_t size; /* size of matrices */ gsl_eigen_herm_workspace *herm_workspace_p; } gsl_eigen_genherm_workspace; gsl_eigen_genherm_workspace * gsl_eigen_genherm_alloc (const size_t n); void gsl_eigen_genherm_free (gsl_eigen_genherm_workspace * w); int gsl_eigen_genherm (gsl_matrix_complex * A, gsl_matrix_complex * B, gsl_vector * eval, gsl_eigen_genherm_workspace * w); int gsl_eigen_genherm_standardize (gsl_matrix_complex * A, const gsl_matrix_complex * B); typedef struct { size_t size; /* size of matrices */ gsl_eigen_hermv_workspace *hermv_workspace_p; } gsl_eigen_genhermv_workspace; gsl_eigen_genhermv_workspace * gsl_eigen_genhermv_alloc (const size_t n); void gsl_eigen_genhermv_free (gsl_eigen_genhermv_workspace * w); int gsl_eigen_genhermv (gsl_matrix_complex * A, gsl_matrix_complex * B, gsl_vector * eval, gsl_matrix_complex * evec, gsl_eigen_genhermv_workspace * w); typedef struct { size_t size; /* size of matrices */ gsl_vector *work; /* scratch workspace */ size_t n_evals; /* number of eigenvalues found */ size_t max_iterations; /* maximum QZ iterations allowed */ size_t n_iter; /* number of iterations since last eigenvalue found */ double eshift; /* exceptional shift counter */ int needtop; /* need to compute top index? */ double atol; /* tolerance for splitting A matrix */ double btol; /* tolerance for splitting B matrix */ double ascale; /* scaling factor for shifts */ double bscale; /* scaling factor for shifts */ gsl_matrix *H; /* pointer to hessenberg matrix */ gsl_matrix *R; /* pointer to upper triangular matrix */ int compute_s; /* compute generalized Schur form S */ int compute_t; /* compute generalized Schur form T */ gsl_matrix *Q; /* pointer to left Schur vectors */ gsl_matrix *Z; /* pointer to right Schur vectors */ } gsl_eigen_gen_workspace; gsl_eigen_gen_workspace * gsl_eigen_gen_alloc (const size_t n); void gsl_eigen_gen_free (gsl_eigen_gen_workspace * w); void gsl_eigen_gen_params (const int compute_s, const int compute_t, const int balance, gsl_eigen_gen_workspace * w); int gsl_eigen_gen (gsl_matrix * A, gsl_matrix * B, gsl_vector_complex * alpha, gsl_vector * beta, gsl_eigen_gen_workspace * w); int gsl_eigen_gen_QZ (gsl_matrix * A, gsl_matrix * B, gsl_vector_complex * alpha, gsl_vector * beta, gsl_matrix * Q, gsl_matrix * Z, gsl_eigen_gen_workspace * w); typedef struct { size_t size; /* size of matrices */ gsl_vector *work1; /* 1-norm of columns of A */ gsl_vector *work2; /* 1-norm of columns of B */ gsl_vector *work3; /* real part of eigenvector */ gsl_vector *work4; /* imag part of eigenvector */ gsl_vector *work5; /* real part of back-transformed eigenvector */ gsl_vector *work6; /* imag part of back-transformed eigenvector */ gsl_matrix *Q; /* pointer to left Schur vectors */ gsl_matrix *Z; /* pointer to right Schur vectors */ gsl_eigen_gen_workspace *gen_workspace_p; } gsl_eigen_genv_workspace; gsl_eigen_genv_workspace * gsl_eigen_genv_alloc (const size_t n); void gsl_eigen_genv_free (gsl_eigen_genv_workspace * w); int gsl_eigen_genv (gsl_matrix * A, gsl_matrix * B, gsl_vector_complex * alpha, gsl_vector * beta, gsl_matrix_complex * evec, gsl_eigen_genv_workspace * w); int gsl_eigen_genv_QZ (gsl_matrix * A, gsl_matrix * B, gsl_vector_complex * alpha, gsl_vector * beta, gsl_matrix_complex * evec, gsl_matrix * Q, gsl_matrix * Z, gsl_eigen_genv_workspace * w); typedef enum { GSL_EIGEN_SORT_VAL_ASC, GSL_EIGEN_SORT_VAL_DESC, GSL_EIGEN_SORT_ABS_ASC, GSL_EIGEN_SORT_ABS_DESC } gsl_eigen_sort_t; /* Sort eigensystem results based on eigenvalues. * Sorts in order of increasing value or increasing * absolute value. * * exceptions: GSL_EBADLEN */ int gsl_eigen_symmv_sort(gsl_vector * eval, gsl_matrix * evec, gsl_eigen_sort_t sort_type); int gsl_eigen_hermv_sort(gsl_vector * eval, gsl_matrix_complex * evec, gsl_eigen_sort_t sort_type); int gsl_eigen_nonsymmv_sort(gsl_vector_complex * eval, gsl_matrix_complex * evec, gsl_eigen_sort_t sort_type); int gsl_eigen_gensymmv_sort (gsl_vector * eval, gsl_matrix * evec, gsl_eigen_sort_t sort_type); int gsl_eigen_genhermv_sort (gsl_vector * eval, gsl_matrix_complex * evec, gsl_eigen_sort_t sort_type); int gsl_eigen_genv_sort (gsl_vector_complex * alpha, gsl_vector * beta, gsl_matrix_complex * evec, gsl_eigen_sort_t sort_type); /* Prototypes for the schur module */ int gsl_schur_gen_eigvals(const gsl_matrix *A, const gsl_matrix *B, double *wr1, double *wr2, double *wi, double *scale1, double *scale2); int gsl_schur_solve_equation(double ca, const gsl_matrix *A, double z, double d1, double d2, const gsl_vector *b, gsl_vector *x, double *s, double *xnorm, double smin); int gsl_schur_solve_equation_z(double ca, const gsl_matrix *A, gsl_complex *z, double d1, double d2, const gsl_vector_complex *b, gsl_vector_complex *x, double *s, double *xnorm, double smin); /* The following functions are obsolete: */ /* Eigensolve by Jacobi Method * * The data in the matrix input is destroyed. * * exceptions: */ int gsl_eigen_jacobi(gsl_matrix * matrix, gsl_vector * eval, gsl_matrix * evec, unsigned int max_rot, unsigned int * nrot); /* Invert by Jacobi Method * * exceptions: */ int gsl_eigen_invert_jacobi(const gsl_matrix * matrix, gsl_matrix * ainv, unsigned int max_rot); __END_DECLS #endif /* __GSL_EIGEN_H__ */ praat-6.0.04/external/gsl/gsl_eigen__francis.c000066400000000000000000000714711261542461700213050ustar00rootroot00000000000000/* eigen/francis.c * * Copyright (C) 2006, 2007 Patrick Alken * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_eigen.h" #include "gsl_linalg.h" #include "gsl_math.h" #include "gsl_blas.h" #include "gsl_vector.h" #include "gsl_vector_complex.h" #include "gsl_matrix.h" #include "gsl_cblas.h" #include "gsl_complex.h" #include "gsl_complex_math.h" /* * This module computes the eigenvalues of a real upper hessenberg * matrix, using the classical double shift Francis QR algorithm. * It will also optionally compute the full Schur form and matrix of * Schur vectors. * * See Golub & Van Loan, "Matrix Computations" (3rd ed), * algorithm 7.5.2 */ /* exceptional shift coefficients - these values are from LAPACK DLAHQR */ #define GSL_FRANCIS_COEFF1 (0.75) #define GSL_FRANCIS_COEFF2 (-0.4375) static inline void francis_schur_decomp(gsl_matrix * H, gsl_vector_complex * eval, gsl_eigen_francis_workspace * w); static inline size_t francis_search_subdiag_small_elements(gsl_matrix * A); static inline int francis_qrstep(gsl_matrix * H, gsl_eigen_francis_workspace * w); static inline void francis_schur_standardize(gsl_matrix *A, gsl_complex *eval1, gsl_complex *eval2, gsl_eigen_francis_workspace *w); static inline size_t francis_get_submatrix(gsl_matrix *A, gsl_matrix *B); static void francis_standard_form(gsl_matrix *A, double *cs, double *sn); /* gsl_eigen_francis_alloc() Allocate a workspace for solving the nonsymmetric eigenvalue problem. The size of this workspace is O(1) Inputs: none Return: pointer to workspace */ gsl_eigen_francis_workspace * gsl_eigen_francis_alloc(void) { gsl_eigen_francis_workspace *w; w = (gsl_eigen_francis_workspace *) calloc (1, sizeof (gsl_eigen_francis_workspace)); if (w == 0) { GSL_ERROR_NULL ("failed to allocate space for workspace", GSL_ENOMEM); } /* these are filled in later */ w->size = 0; w->max_iterations = 0; w->n_iter = 0; w->n_evals = 0; w->compute_t = 0; w->Z = NULL; w->H = NULL; return (w); } /* gsl_eigen_francis_alloc() */ /* gsl_eigen_francis_free() Free francis workspace w */ void gsl_eigen_francis_free (gsl_eigen_francis_workspace *w) { free(w); } /* gsl_eigen_francis_free() */ /* gsl_eigen_francis_T() Called when we want to compute the Schur form T, or no longer compute the Schur form T Inputs: compute_t - 1 to compute T, 0 to not compute T w - francis workspace */ void gsl_eigen_francis_T (const int compute_t, gsl_eigen_francis_workspace *w) { w->compute_t = compute_t; } /* gsl_eigen_francis() Solve the nonsymmetric eigenvalue problem H x = \lambda x for the eigenvalues \lambda using algorithm 7.5.2 of Golub & Van Loan, "Matrix Computations" (3rd ed) Inputs: H - upper hessenberg matrix eval - where to store eigenvalues w - workspace Return: success or error - if error code is returned, then the QR procedure did not converge in the allowed number of iterations. In the event of non- convergence, the number of eigenvalues found will still be stored in the beginning of eval, Notes: On output, the diagonal of H contains 1-by-1 or 2-by-2 blocks containing the eigenvalues. If T is desired, H will contain the full Schur form on output. */ int gsl_eigen_francis (gsl_matrix * H, gsl_vector_complex * eval, gsl_eigen_francis_workspace * w) { /* check matrix and vector sizes */ if (H->size1 != H->size2) { GSL_ERROR ("matrix must be square to compute eigenvalues", GSL_ENOTSQR); } else if (eval->size != H->size1) { GSL_ERROR ("eigenvalue vector must match matrix size", GSL_EBADLEN); } else { const size_t N = H->size1; int j; /* * Set internal parameters which depend on matrix size. * The Francis solver can be called with any size matrix * since the workspace does not depend on N. * Furthermore, multishift solvers which call the Francis * solver may need to call it with different sized matrices */ w->size = N; w->max_iterations = 30 * N; /* * save a pointer to original matrix since francis_schur_decomp * is recursive */ w->H = H; w->n_iter = 0; w->n_evals = 0; /* * zero out the first two subdiagonals (below the main subdiagonal) * needed as scratch space by the QR sweep routine */ for (j = 0; j < (int) N - 3; ++j) { gsl_matrix_set(H, (size_t) j + 2, (size_t) j, 0.0); gsl_matrix_set(H, (size_t) j + 3, (size_t) j, 0.0); } if (N > 2) gsl_matrix_set(H, N - 1, N - 3, 0.0); /* * compute Schur decomposition of H and store eigenvalues * into eval */ francis_schur_decomp(H, eval, w); if (w->n_evals != N) return GSL_EMAXITER; return GSL_SUCCESS; } } /* gsl_eigen_francis() */ /* gsl_eigen_francis_Z() Solve the nonsymmetric eigenvalue problem for a Hessenberg matrix H x = \lambda x for the eigenvalues \lambda using the Francis double-shift method. Here we compute the real Schur form T = Q^t H Q with the diagonal blocks of T giving us the eigenvalues. Q is the matrix of Schur vectors. Originally, H was obtained from a general nonsymmetric matrix A via a transformation H = U^t A U so that T = (UQ)^t A (UQ) = Z^t A Z Z is the matrix of Schur vectors computed by this algorithm Inputs: H - upper hessenberg matrix eval - where to store eigenvalues Z - where to store Schur vectors w - workspace Notes: 1) If T is computed, it is stored in H on output. Otherwise, the diagonal of H will contain 1-by-1 and 2-by-2 blocks containing the eigenvalues. 2) The matrix Z must be initialized to the Hessenberg similarity matrix U. Or if you want the eigenvalues of H, initialize Z to the identity matrix. */ int gsl_eigen_francis_Z (gsl_matrix * H, gsl_vector_complex * eval, gsl_matrix * Z, gsl_eigen_francis_workspace * w) { int s; /* set internal Z pointer so we know to accumulate transformations */ w->Z = Z; s = gsl_eigen_francis(H, eval, w); w->Z = NULL; return s; } /* gsl_eigen_francis_Z() */ /******************************************** * INTERNAL ROUTINES * ********************************************/ /* francis_schur_decomp() Compute the Schur decomposition of the matrix H Inputs: H - hessenberg matrix eval - where to store eigenvalues w - workspace Return: none */ static inline void francis_schur_decomp(gsl_matrix * H, gsl_vector_complex * eval, gsl_eigen_francis_workspace * w) { gsl_matrix_view m; /* active matrix we are working on */ size_t N; /* size of matrix */ size_t q; /* index of small subdiagonal element */ gsl_complex lambda1, /* eigenvalues */ lambda2; N = H->size1; m = gsl_matrix_submatrix(H, 0, 0, N, N); while ((N > 2) && ((w->n_iter)++ < w->max_iterations)) { q = francis_search_subdiag_small_elements(&m.matrix); if (q == 0) { /* * no small subdiagonal element found - perform a QR * sweep on the active reduced hessenberg matrix */ francis_qrstep(&m.matrix, w); continue; } /* * a small subdiagonal element was found - one or two eigenvalues * have converged or the matrix has split into two smaller matrices */ if (q == (N - 1)) { /* * the last subdiagonal element of the matrix is 0 - * m_{NN} is a real eigenvalue */ GSL_SET_COMPLEX(&lambda1, gsl_matrix_get(&m.matrix, q, q), 0.0); gsl_vector_complex_set(eval, w->n_evals, lambda1); w->n_evals += 1; w->n_iter = 0; --N; m = gsl_matrix_submatrix(&m.matrix, 0, 0, N, N); } else if (q == (N - 2)) { gsl_matrix_view v; /* * The bottom right 2-by-2 block of m is an eigenvalue * system */ v = gsl_matrix_submatrix(&m.matrix, q, q, 2, 2); francis_schur_standardize(&v.matrix, &lambda1, &lambda2, w); gsl_vector_complex_set(eval, w->n_evals, lambda1); gsl_vector_complex_set(eval, w->n_evals + 1, lambda2); w->n_evals += 2; w->n_iter = 0; N -= 2; m = gsl_matrix_submatrix(&m.matrix, 0, 0, N, N); } else if (q == 1) { /* the first matrix element is an eigenvalue */ GSL_SET_COMPLEX(&lambda1, gsl_matrix_get(&m.matrix, 0, 0), 0.0); gsl_vector_complex_set(eval, w->n_evals, lambda1); w->n_evals += 1; w->n_iter = 0; --N; m = gsl_matrix_submatrix(&m.matrix, 1, 1, N, N); } else if (q == 2) { gsl_matrix_view v; /* the upper left 2-by-2 block is an eigenvalue system */ v = gsl_matrix_submatrix(&m.matrix, 0, 0, 2, 2); francis_schur_standardize(&v.matrix, &lambda1, &lambda2, w); gsl_vector_complex_set(eval, w->n_evals, lambda1); gsl_vector_complex_set(eval, w->n_evals + 1, lambda2); w->n_evals += 2; w->n_iter = 0; N -= 2; m = gsl_matrix_submatrix(&m.matrix, 2, 2, N, N); } else { gsl_matrix_view v; /* * There is a zero element on the subdiagonal somewhere * in the middle of the matrix - we can now operate * separately on the two submatrices split by this * element. q is the row index of the zero element. */ /* operate on lower right (N - q)-by-(N - q) block first */ v = gsl_matrix_submatrix(&m.matrix, q, q, N - q, N - q); francis_schur_decomp(&v.matrix, eval, w); /* operate on upper left q-by-q block */ v = gsl_matrix_submatrix(&m.matrix, 0, 0, q, q); francis_schur_decomp(&v.matrix, eval, w); N = 0; } } /* handle special cases of N = 1 or 2 */ if (N == 1) { GSL_SET_COMPLEX(&lambda1, gsl_matrix_get(&m.matrix, 0, 0), 0.0); gsl_vector_complex_set(eval, w->n_evals, lambda1); w->n_evals += 1; w->n_iter = 0; } else if (N == 2) { francis_schur_standardize(&m.matrix, &lambda1, &lambda2, w); gsl_vector_complex_set(eval, w->n_evals, lambda1); gsl_vector_complex_set(eval, w->n_evals + 1, lambda2); w->n_evals += 2; w->n_iter = 0; } } /* francis_schur_decomp() */ /* francis_qrstep() Perform a Francis QR step. See Golub & Van Loan, "Matrix Computations" (3rd ed), algorithm 7.5.1 Inputs: H - upper Hessenberg matrix w - workspace Notes: The matrix H must be "reduced", ie: have no tiny subdiagonal elements. When computing the first householder reflection, we divide by H_{21} so it is necessary that this element is not zero. When a subdiagonal element becomes negligible, the calling function should call this routine with the submatrices split by that element, so that we don't divide by zeros. */ static inline int francis_qrstep(gsl_matrix * H, gsl_eigen_francis_workspace * w) { const size_t N = H->size1; size_t i; /* looping */ gsl_matrix_view m; double tau_i; /* householder coefficient */ double dat[3]; /* householder vector */ double scale; /* scale factor to avoid overflow */ gsl_vector_view v2, v3; size_t q, r; size_t top = 0; /* location of H in original matrix */ double s, disc; double h_nn, /* H(n,n) */ h_nm1nm1, /* H(n-1,n-1) */ h_cross, /* H(n,n-1) * H(n-1,n) */ h_tmp1, h_tmp2; v2 = gsl_vector_view_array(dat, 2); v3 = gsl_vector_view_array(dat, 3); if ((w->n_iter % 10) == 0) { /* * exceptional shifts: we have gone 10 iterations * without finding a new eigenvalue, try a new choice of shifts. * See LAPACK routine DLAHQR */ s = fabs(gsl_matrix_get(H, N - 1, N - 2)) + fabs(gsl_matrix_get(H, N - 2, N - 3)); h_nn = gsl_matrix_get(H, N - 1, N - 1) + GSL_FRANCIS_COEFF1 * s; h_nm1nm1 = h_nn; h_cross = GSL_FRANCIS_COEFF2 * s * s; } else { /* * normal shifts - compute Rayleigh quotient and use * Wilkinson shift if possible */ h_nn = gsl_matrix_get(H, N - 1, N - 1); h_nm1nm1 = gsl_matrix_get(H, N - 2, N - 2); h_cross = gsl_matrix_get(H, N - 1, N - 2) * gsl_matrix_get(H, N - 2, N - 1); disc = 0.5 * (h_nm1nm1 - h_nn); disc = disc * disc + h_cross; if (disc > 0.0) { double ave; /* real roots - use Wilkinson's shift twice */ disc = sqrt(disc); ave = 0.5 * (h_nm1nm1 + h_nn); if (fabs(h_nm1nm1) - fabs(h_nn) > 0.0) { h_nm1nm1 = h_nm1nm1 * h_nn - h_cross; h_nn = h_nm1nm1 / (disc * GSL_SIGN(ave) + ave); } else { h_nn = disc * GSL_SIGN(ave) + ave; } h_nm1nm1 = h_nn; h_cross = 0.0; } } h_tmp1 = h_nm1nm1 - gsl_matrix_get(H, 0, 0); h_tmp2 = h_nn - gsl_matrix_get(H, 0, 0); /* * These formulas are equivalent to those in Golub & Van Loan * for the normal shift case - the terms have been rearranged * to reduce possible roundoff error when subdiagonal elements * are small */ dat[0] = (h_tmp1*h_tmp2 - h_cross) / gsl_matrix_get(H, 1, 0) + gsl_matrix_get(H, 0, 1); dat[1] = gsl_matrix_get(H, 1, 1) - gsl_matrix_get(H, 0, 0) - h_tmp1 - h_tmp2; dat[2] = gsl_matrix_get(H, 2, 1); scale = fabs(dat[0]) + fabs(dat[1]) + fabs(dat[2]); if (scale != 0.0) { /* scale to prevent overflow or underflow */ dat[0] /= scale; dat[1] /= scale; dat[2] /= scale; } if (w->Z || w->compute_t) { /* * get absolute indices of this (sub)matrix relative to the * original Hessenberg matrix */ top = francis_get_submatrix(w->H, H); } for (i = 0; i < N - 2; ++i) { tau_i = gsl_linalg_householder_transform(&v3.vector); if (tau_i != 0.0) { /* q = max(1, i - 1) */ q = (1 > ((int)i - 1)) ? 0 : (i - 1); /* r = min(i + 3, N - 1) */ r = ((i + 3) < (N - 1)) ? (i + 3) : (N - 1); if (w->compute_t) { /* * We are computing the Schur form T, so we * need to transform the whole matrix H * * H -> P_k^t H P_k * * where P_k is the current Householder matrix */ /* apply left householder matrix (I - tau_i v v') to H */ m = gsl_matrix_submatrix(w->H, top + i, top + q, 3, w->size - top - q); gsl_linalg_householder_hm(tau_i, &v3.vector, &m.matrix); /* apply right householder matrix (I - tau_i v v') to H */ m = gsl_matrix_submatrix(w->H, 0, top + i, top + r + 1, 3); gsl_linalg_householder_mh(tau_i, &v3.vector, &m.matrix); } else { /* * We are not computing the Schur form T, so we * only need to transform the active block */ /* apply left householder matrix (I - tau_i v v') to H */ m = gsl_matrix_submatrix(H, i, q, 3, N - q); gsl_linalg_householder_hm(tau_i, &v3.vector, &m.matrix); /* apply right householder matrix (I - tau_i v v') to H */ m = gsl_matrix_submatrix(H, 0, i, r + 1, 3); gsl_linalg_householder_mh(tau_i, &v3.vector, &m.matrix); } if (w->Z) { /* accumulate the similarity transformation into Z */ m = gsl_matrix_submatrix(w->Z, 0, top + i, w->size, 3); gsl_linalg_householder_mh(tau_i, &v3.vector, &m.matrix); } } /* if (tau_i != 0.0) */ dat[0] = gsl_matrix_get(H, i + 1, i); dat[1] = gsl_matrix_get(H, i + 2, i); if (i < (N - 3)) { dat[2] = gsl_matrix_get(H, i + 3, i); } scale = fabs(dat[0]) + fabs(dat[1]) + fabs(dat[2]); if (scale != 0.0) { /* scale to prevent overflow or underflow */ dat[0] /= scale; dat[1] /= scale; dat[2] /= scale; } } /* for (i = 0; i < N - 2; ++i) */ scale = fabs(dat[0]) + fabs(dat[1]); if (scale != 0.0) { /* scale to prevent overflow or underflow */ dat[0] /= scale; dat[1] /= scale; } tau_i = gsl_linalg_householder_transform(&v2.vector); if (w->compute_t) { m = gsl_matrix_submatrix(w->H, top + N - 2, top + N - 3, 2, w->size - top - N + 3); gsl_linalg_householder_hm(tau_i, &v2.vector, &m.matrix); m = gsl_matrix_submatrix(w->H, 0, top + N - 2, top + N, 2); gsl_linalg_householder_mh(tau_i, &v2.vector, &m.matrix); } else { m = gsl_matrix_submatrix(H, N - 2, N - 3, 2, 3); gsl_linalg_householder_hm(tau_i, &v2.vector, &m.matrix); m = gsl_matrix_submatrix(H, 0, N - 2, N, 2); gsl_linalg_householder_mh(tau_i, &v2.vector, &m.matrix); } if (w->Z) { /* accumulate transformation into Z */ m = gsl_matrix_submatrix(w->Z, 0, top + N - 2, w->size, 2); gsl_linalg_householder_mh(tau_i, &v2.vector, &m.matrix); } return GSL_SUCCESS; } /* francis_qrstep() */ /* francis_search_subdiag_small_elements() Search for a small subdiagonal element starting from the bottom of a matrix A. A small element is one that satisfies: |A_{i,i-1}| <= eps * (|A_{i,i}| + |A_{i-1,i-1}|) Inputs: A - matrix (must be at least 3-by-3) Return: row index of small subdiagonal element or 0 if not found Notes: the first small element that is found (starting from bottom) is set to zero */ static inline size_t francis_search_subdiag_small_elements(gsl_matrix * A) { const size_t N = A->size1; size_t i; double dpel = gsl_matrix_get(A, N - 2, N - 2); for (i = N - 1; i > 0; --i) { double sel = gsl_matrix_get(A, i, i - 1); double del = gsl_matrix_get(A, i, i); if ((sel == 0.0) || (fabs(sel) < GSL_DBL_EPSILON * (fabs(del) + fabs(dpel)))) { gsl_matrix_set(A, i, i - 1, 0.0); return (i); } dpel = del; } return (0); } /* francis_search_subdiag_small_elements() */ /* francis_schur_standardize() Convert a 2-by-2 diagonal block in the Schur form to standard form and update the rest of T and Z matrices if required. Inputs: A - 2-by-2 matrix eval1 - where to store eigenvalue 1 eval2 - where to store eigenvalue 2 w - francis workspace */ static inline void francis_schur_standardize(gsl_matrix *A, gsl_complex *eval1, gsl_complex *eval2, gsl_eigen_francis_workspace *w) { const size_t N = w->size; double cs, sn; size_t top; /* * figure out where the submatrix A resides in the * original matrix H */ top = francis_get_submatrix(w->H, A); /* convert 2-by-2 block to standard form */ francis_standard_form(A, &cs, &sn); /* set eigenvalues */ GSL_SET_REAL(eval1, gsl_matrix_get(A, 0, 0)); GSL_SET_REAL(eval2, gsl_matrix_get(A, 1, 1)); if (gsl_matrix_get(A, 1, 0) == 0.0) { GSL_SET_IMAG(eval1, 0.0); GSL_SET_IMAG(eval2, 0.0); } else { double tmp = sqrt(fabs(gsl_matrix_get(A, 0, 1)) * fabs(gsl_matrix_get(A, 1, 0))); GSL_SET_IMAG(eval1, tmp); GSL_SET_IMAG(eval2, -tmp); } if (w->compute_t) { gsl_vector_view xv, yv; /* * The above call to francis_standard_form transformed a 2-by-2 block * of T into upper triangular form via the transformation * * U = [ CS -SN ] * [ SN CS ] * * The original matrix T was * * T = [ T_{11} | T_{12} | T_{13} ] * [ 0* | A | T_{23} ] * [ 0 | 0* | T_{33} ] * * where 0* indicates all zeros except for possibly * one subdiagonal element next to A. * * After francis_standard_form, T looks like this: * * T = [ T_{11} | T_{12} | T_{13} ] * [ 0* | U^t A U | T_{23} ] * [ 0 | 0* | T_{33} ] * * since only the 2-by-2 block of A was changed. However, * in order to be able to back transform T at the end, * we need to apply the U transformation to the rest * of the matrix T since there is no way to apply a * similarity transformation to T and change only the * middle 2-by-2 block. In other words, let * * M = [ I 0 0 ] * [ 0 U 0 ] * [ 0 0 I ] * * and compute * * M^t T M = [ T_{11} | T_{12} U | T_{13} ] * [ U^t 0* | U^t A U | U^t T_{23} ] * [ 0 | 0* U | T_{33} ] * * So basically we need to apply the transformation U * to the i x 2 matrix T_{12} and the 2 x (n - i + 2) * matrix T_{23}, where i is the index of the top of A * in T. * * The BLAS routine drot() is suited for this. */ if (top < (N - 2)) { /* transform the 2 rows of T_{23} */ xv = gsl_matrix_subrow(w->H, top, top + 2, N - top - 2); yv = gsl_matrix_subrow(w->H, top + 1, top + 2, N - top - 2); gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); } if (top > 0) { /* transform the 2 columns of T_{12} */ xv = gsl_matrix_subcolumn(w->H, top, 0, top); yv = gsl_matrix_subcolumn(w->H, top + 1, 0, top); gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); } } /* if (w->compute_t) */ if (w->Z) { gsl_vector_view xv, yv; /* * Accumulate the transformation in Z. Here, Z -> Z * M * * So: * * Z -> [ Z_{11} | Z_{12} U | Z_{13} ] * [ Z_{21} | Z_{22} U | Z_{23} ] * [ Z_{31} | Z_{32} U | Z_{33} ] * * So we just need to apply drot() to the 2 columns * starting at index 'top' */ xv = gsl_matrix_column(w->Z, top); yv = gsl_matrix_column(w->Z, top + 1); gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); } /* if (w->Z) */ } /* francis_schur_standardize() */ /* francis_get_submatrix() B is a submatrix of A. The goal of this function is to compute the indices in A of where the matrix B resides */ static inline size_t francis_get_submatrix(gsl_matrix *A, gsl_matrix *B) { size_t diff; double ratio; size_t top; diff = (size_t) (B->data - A->data); ratio = (double)diff / ((double) (A->tda + 1)); top = (size_t) floor(ratio); return top; } /* francis_get_submatrix() */ /* francis_standard_form() Compute the Schur factorization of a real 2-by-2 matrix in standard form: [ A B ] = [ CS -SN ] [ T11 T12 ] [ CS SN ] [ C D ] [ SN CS ] [ T21 T22 ] [-SN CS ] where either: 1) T21 = 0 so that T11 and T22 are real eigenvalues of the matrix, or 2) T11 = T22 and T21*T12 < 0, so that T11 +/- sqrt(|T21*T12|) are complex conjugate eigenvalues Inputs: A - 2-by-2 matrix cs - where to store cosine parameter of rotation matrix sn - where to store sine parameter of rotation matrix Notes: 1) based on LAPACK routine DLANV2 2) On output, A is modified to contain the matrix in standard form */ static void francis_standard_form(gsl_matrix *A, double *cs, double *sn) { double a, b, c, d; /* input matrix values */ double tmp; double p, z; double bcmax, bcmis, scale; double tau, sigma; double cs1, sn1; double aa, bb, cc, dd; double sab, sac; a = gsl_matrix_get(A, 0, 0); b = gsl_matrix_get(A, 0, 1); c = gsl_matrix_get(A, 1, 0); d = gsl_matrix_get(A, 1, 1); if (c == 0.0) { /* * matrix is already upper triangular - set rotation matrix * to the identity */ *cs = 1.0; *sn = 0.0; } else if (b == 0.0) { /* swap rows and columns to make it upper triangular */ *cs = 0.0; *sn = 1.0; tmp = d; d = a; a = tmp; b = -c; c = 0.0; } else if (((a - d) == 0.0) && (GSL_SIGN(b) != GSL_SIGN(c))) { /* the matrix has complex eigenvalues with a == d */ *cs = 1.0; *sn = 0.0; } else { tmp = a - d; p = 0.5 * tmp; bcmax = GSL_MAX(fabs(b), fabs(c)); bcmis = GSL_MIN(fabs(b), fabs(c)) * GSL_SIGN(b) * GSL_SIGN(c); scale = GSL_MAX(fabs(p), bcmax); z = (p / scale) * p + (bcmax / scale) * bcmis; if (z >= 4.0 * GSL_DBL_EPSILON) { /* real eigenvalues, compute a and d */ z = p + GSL_SIGN(p) * fabs(sqrt(scale) * sqrt(z)); a = d + z; d -= (bcmax / z) * bcmis; /* compute b and the rotation matrix */ tau = gsl_hypot(c, z); *cs = z / tau; *sn = c / tau; b -= c; c = 0.0; } else { /* * complex eigenvalues, or real (almost) equal eigenvalues - * make diagonal elements equal */ sigma = b + c; tau = gsl_hypot(sigma, tmp); *cs = sqrt(0.5 * (1.0 + fabs(sigma) / tau)); *sn = -(p / (tau * (*cs))) * GSL_SIGN(sigma); /* * Compute [ AA BB ] = [ A B ] [ CS -SN ] * [ CC DD ] [ C D ] [ SN CS ] */ aa = a * (*cs) + b * (*sn); bb = -a * (*sn) + b * (*cs); cc = c * (*cs) + d * (*sn); dd = -c * (*sn) + d * (*cs); /* * Compute [ A B ] = [ CS SN ] [ AA BB ] * [ C D ] [-SN CS ] [ CC DD ] */ a = aa * (*cs) + cc * (*sn); b = bb * (*cs) + dd * (*sn); c = -aa * (*sn) + cc * (*cs); d = -bb * (*sn) + dd * (*cs); tmp = 0.5 * (a + d); a = d = tmp; if (c != 0.0) { if (b != 0.0) { if (GSL_SIGN(b) == GSL_SIGN(c)) { /* * real eigenvalues: reduce to upper triangular * form */ sab = sqrt(fabs(b)); sac = sqrt(fabs(c)); p = GSL_SIGN(c) * fabs(sab * sac); tau = 1.0 / sqrt(fabs(b + c)); a = tmp + p; d = tmp - p; b -= c; c = 0.0; cs1 = sab * tau; sn1 = sac * tau; tmp = (*cs) * cs1 - (*sn) * sn1; *sn = (*cs) * sn1 + (*sn) * cs1; *cs = tmp; } } else { b = -c; c = 0.0; tmp = *cs; *cs = -(*sn); *sn = tmp; } } } } /* set new matrix elements */ gsl_matrix_set(A, 0, 0, a); gsl_matrix_set(A, 0, 1, b); gsl_matrix_set(A, 1, 0, c); gsl_matrix_set(A, 1, 1, d); } /* francis_standard_form() */ praat-6.0.04/external/gsl/gsl_eigen__gen.c000066400000000000000000001662111261542461700204260ustar00rootroot00000000000000/* eigen/gen.c * * Copyright (C) 2006, 2007 Patrick Alken * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "gsl__config.h" #include "gsl_eigen.h" #include "gsl_linalg.h" #include "gsl_math.h" #include "gsl_blas.h" #include "gsl_vector.h" #include "gsl_vector_complex.h" #include "gsl_matrix.h" /* * This module computes the eigenvalues of a real generalized * eigensystem A x = \lambda B x. Left and right Schur vectors * are optionally computed as well. * * Based on the algorithm from Moler and Stewart * [1] C. Moler, G. Stewart, "An Algorithm for Generalized Matrix * Eigenvalue Problems", SIAM J. Numer. Anal., Vol 10, No 2, 1973. * * This algorithm is also described in the book * [2] Golub & Van Loan, "Matrix Computations" (3rd ed), algorithm 7.7.3 * * This file contains routines based on original code from LAPACK * which is distributed under the modified BSD license. */ #define GEN_ESHIFT_COEFF (1.736) static void gen_schur_decomp(gsl_matrix *H, gsl_matrix *R, gsl_vector_complex *alpha, gsl_vector *beta, gsl_eigen_gen_workspace *w); static inline int gen_qzstep(gsl_matrix *H, gsl_matrix *R, gsl_eigen_gen_workspace *w); static inline void gen_qzstep_d(gsl_matrix *H, gsl_matrix *R, gsl_eigen_gen_workspace *w); static void gen_tri_split_top(gsl_matrix *H, gsl_matrix *R, gsl_eigen_gen_workspace *w); static inline void gen_tri_chase_zero(gsl_matrix *H, gsl_matrix *R, size_t q, gsl_eigen_gen_workspace *w); static inline void gen_tri_zero_H(gsl_matrix *H, gsl_matrix *R, gsl_eigen_gen_workspace *w); static inline size_t gen_search_small_elements(gsl_matrix *H, gsl_matrix *R, int *flag, gsl_eigen_gen_workspace *w); static int gen_schur_standardize1(gsl_matrix *A, gsl_matrix *B, double *alphar, double *beta, gsl_eigen_gen_workspace *w); static int gen_schur_standardize2(gsl_matrix *A, gsl_matrix *B, gsl_complex *alpha1, gsl_complex *alpha2, double *beta1, double *beta2, gsl_eigen_gen_workspace *w); static int gen_compute_eigenvals(gsl_matrix *A, gsl_matrix *B, gsl_complex *alpha1, gsl_complex *alpha2, double *beta1, double *beta2); static void gen_store_eigval1(const gsl_matrix *H, const double a, const double b, gsl_vector_complex *alpha, gsl_vector *beta, gsl_eigen_gen_workspace *w); static void gen_store_eigval2(const gsl_matrix *H, const gsl_complex *alpha1, const double beta1, const gsl_complex *alpha2, const double beta2, gsl_vector_complex *alpha, gsl_vector *beta, gsl_eigen_gen_workspace *w); static inline size_t gen_get_submatrix(const gsl_matrix *A, const gsl_matrix *B); /*FIX**/ inline static double normF (gsl_matrix * A); inline static void create_givens (const double a, const double b, double *c, double *s); /* gsl_eigen_gen_alloc() Allocate a workspace for solving the generalized eigenvalue problem. The size of this workspace is O(n) Inputs: n - size of matrices Return: pointer to workspace */ gsl_eigen_gen_workspace * gsl_eigen_gen_alloc(const size_t n) { gsl_eigen_gen_workspace *w; if (n == 0) { GSL_ERROR_NULL ("matrix dimension must be positive integer", GSL_EINVAL); } w = calloc (1, sizeof (gsl_eigen_gen_workspace)); if (w == 0) { GSL_ERROR_NULL ("failed to allocate space for workspace", GSL_ENOMEM); } w->size = n; w->max_iterations = 30 * n; w->n_evals = 0; w->n_iter = 0; w->needtop = 0; w->atol = 0.0; w->btol = 0.0; w->ascale = 0.0; w->bscale = 0.0; w->eshift = 0.0; w->H = NULL; w->R = NULL; w->compute_s = 0; w->compute_t = 0; w->Q = NULL; w->Z = NULL; w->work = gsl_vector_alloc(n); if (w->work == 0) { gsl_eigen_gen_free(w); GSL_ERROR_NULL ("failed to allocate space for additional workspace", GSL_ENOMEM); } return (w); } /* gsl_eigen_gen_alloc() */ /* gsl_eigen_gen_free() Free workspace w */ void gsl_eigen_gen_free (gsl_eigen_gen_workspace * w) { if (w->work) gsl_vector_free(w->work); free(w); } /* gsl_eigen_gen_free() */ /* gsl_eigen_gen_params() Set parameters which define how we solve the eigenvalue problem Inputs: compute_s - 1 if we want to compute S, 0 if not compute_t - 1 if we want to compute T, 0 if not balance - 1 if we want to balance matrices, 0 if not w - gen workspace Return: none */ void gsl_eigen_gen_params (const int compute_s, const int compute_t, const int balance, gsl_eigen_gen_workspace *w) { w->compute_s = compute_s; w->compute_t = compute_t; } /* gsl_eigen_gen_params() */ /* gsl_eigen_gen() Solve the generalized eigenvalue problem A x = \lambda B x for the eigenvalues \lambda. Inputs: A - general real matrix B - general real matrix alpha - where to store eigenvalue numerators beta - where to store eigenvalue denominators w - workspace Return: success or error */ int gsl_eigen_gen (gsl_matrix * A, gsl_matrix * B, gsl_vector_complex * alpha, gsl_vector * beta, gsl_eigen_gen_workspace * w) { const size_t N = A->size1; /* check matrix and vector sizes */ if (N != A->size2) { GSL_ERROR ("matrix must be square to compute eigenvalues", GSL_ENOTSQR); } else if ((N != B->size1) || (N != B->size2)) { GSL_ERROR ("B matrix dimensions must match A", GSL_EBADLEN); } else if (alpha->size != N || beta->size != N) { GSL_ERROR ("eigenvalue vector must match matrix size", GSL_EBADLEN); } else if (w->size != N) { GSL_ERROR ("matrix size does not match workspace", GSL_EBADLEN); } else { double anorm, bnorm; /* compute the Hessenberg-Triangular reduction of (A, B) */ gsl_linalg_hesstri_decomp(A, B, w->Q, w->Z, w->work); /* save pointers to original matrices */ w->H = A; w->R = B; w->n_evals = 0; w->n_iter = 0; w->eshift = 0.0; /* determine if we need to compute top indices in QZ step */ w->needtop = w->Q != 0 || w->Z != 0 || w->compute_t || w->compute_s; /* compute matrix norms */ anorm = normF(A); bnorm = normF(B); /* compute tolerances and scaling factors */ w->atol = GSL_MAX(GSL_DBL_MIN, GSL_DBL_EPSILON * anorm); w->btol = GSL_MAX(GSL_DBL_MIN, GSL_DBL_EPSILON * bnorm); w->ascale = 1.0 / GSL_MAX(GSL_DBL_MIN, anorm); w->bscale = 1.0 / GSL_MAX(GSL_DBL_MIN, bnorm); /* compute the generalized Schur decomposition and eigenvalues */ gen_schur_decomp(A, B, alpha, beta, w); if (w->n_evals != N) return GSL_EMAXITER; return GSL_SUCCESS; } } /* gsl_eigen_gen() */ /* gsl_eigen_gen_QZ() Solve the generalized eigenvalue problem A x = \lambda B x for the eigenvalues \lambda. Optionally compute left and/or right Schur vectors Q and Z which satisfy: A = Q S Z^t B = Q T Z^t where (S, T) is the generalized Schur form of (A, B) Inputs: A - general real matrix B - general real matrix alpha - where to store eigenvalue numerators beta - where to store eigenvalue denominators Q - if non-null, where to store left Schur vectors Z - if non-null, where to store right Schur vectors w - workspace Return: success or error */ int gsl_eigen_gen_QZ (gsl_matrix * A, gsl_matrix * B, gsl_vector_complex * alpha, gsl_vector * beta, gsl_matrix * Q, gsl_matrix * Z, gsl_eigen_gen_workspace * w) { if (Q && (A->size1 != Q->size1 || A->size1 != Q->size2)) { GSL_ERROR("Q matrix has wrong dimensions", GSL_EBADLEN); } else if (Z && (A->size1 != Z->size1 || A->size1 != Z->size2)) { GSL_ERROR("Z matrix has wrong dimensions", GSL_EBADLEN); } else { int s; w->Q = Q; w->Z = Z; s = gsl_eigen_gen(A, B, alpha, beta, w); w->Q = NULL; w->Z = NULL; return s; } } /* gsl_eigen_gen_QZ() */ /******************************************** * INTERNAL ROUTINES * ********************************************/ /* gen_schur_decomp() Compute the generalized Schur decomposition of the matrix pencil (H, R) which is in Hessenberg-Triangular form Inputs: H - upper hessenberg matrix R - upper triangular matrix alpha - (output) where to store eigenvalue numerators beta - (output) where to store eigenvalue denominators w - workspace Return: none Notes: 1) w->n_evals is updated to keep track of how many eigenvalues are found */ static void gen_schur_decomp(gsl_matrix *H, gsl_matrix *R, gsl_vector_complex *alpha, gsl_vector *beta, gsl_eigen_gen_workspace *w) { size_t N; gsl_matrix_view h, r; gsl_matrix_view vh, vr; size_t q; /* index of small subdiagonal element */ gsl_complex z1, z2; /* complex values */ double a, b; int s; int flag; N = H->size1; h = gsl_matrix_submatrix(H, 0, 0, N, N); r = gsl_matrix_submatrix(R, 0, 0, N, N); while ((N > 1) && (w->n_iter)++ < w->max_iterations) { q = gen_search_small_elements(&h.matrix, &r.matrix, &flag, w); if (flag == 0) { /* no small elements found - do a QZ sweep */ s = gen_qzstep(&h.matrix, &r.matrix, w); if (s == GSL_CONTINUE) { /* * (h, r) is a 2-by-2 block with complex eigenvalues - * standardize and read off eigenvalues */ s = gen_schur_standardize2(&h.matrix, &r.matrix, &z1, &z2, &a, &b, w); if (s != GSL_SUCCESS) { /* * if we get here, then the standardization process * perturbed the eigenvalues onto the real line - * continue QZ iteration to break them into 1-by-1 * blocks */ continue; } gen_store_eigval2(&h.matrix, &z1, a, &z2, b, alpha, beta, w); N = 0; } /* if (s) */ continue; } /* if (flag == 0) */ else if (flag == 2) { if (q == 0) { /* * the leading element of R is zero, split off a block * at the top */ gen_tri_split_top(&h.matrix, &r.matrix, w); } else { /* * we found a small element on the diagonal of R - chase the * zero to the bottom of the active block and then zero * H(n, n - 1) to split off a 1-by-1 block */ if (q != N - 1) gen_tri_chase_zero(&h.matrix, &r.matrix, q, w); /* now zero H(n, n - 1) */ gen_tri_zero_H(&h.matrix, &r.matrix, w); } /* continue so the next iteration detects the zero in H */ continue; } /* * a small subdiagonal element of H was found - one or two * eigenvalues have converged or the matrix has split into * two smaller matrices */ if (q == (N - 1)) { /* * the last subdiagonal element of the hessenberg matrix is 0 - * H_{NN} / R_{NN} is a real eigenvalue - standardize so * R_{NN} > 0 */ vh = gsl_matrix_submatrix(&h.matrix, q, q, 1, 1); vr = gsl_matrix_submatrix(&r.matrix, q, q, 1, 1); gen_schur_standardize1(&vh.matrix, &vr.matrix, &a, &b, w); gen_store_eigval1(&vh.matrix, a, b, alpha, beta, w); --N; h = gsl_matrix_submatrix(&h.matrix, 0, 0, N, N); r = gsl_matrix_submatrix(&r.matrix, 0, 0, N, N); } else if (q == (N - 2)) { /* bottom right 2-by-2 block may have converged */ vh = gsl_matrix_submatrix(&h.matrix, q, q, 2, 2); vr = gsl_matrix_submatrix(&r.matrix, q, q, 2, 2); s = gen_schur_standardize2(&vh.matrix, &vr.matrix, &z1, &z2, &a, &b, w); if (s != GSL_SUCCESS) { /* * this 2-by-2 block contains real eigenvalues that * have not yet separated into 1-by-1 blocks - * recursively call gen_schur_decomp() to finish off * this block */ gen_schur_decomp(&vh.matrix, &vr.matrix, alpha, beta, w); } else { /* we got 2 complex eigenvalues */ gen_store_eigval2(&vh.matrix, &z1, a, &z2, b, alpha, beta, w); } N -= 2; h = gsl_matrix_submatrix(&h.matrix, 0, 0, N, N); r = gsl_matrix_submatrix(&r.matrix, 0, 0, N, N); } else if (q == 1) { /* H_{11} / R_{11} is an eigenvalue */ vh = gsl_matrix_submatrix(&h.matrix, 0, 0, 1, 1); vr = gsl_matrix_submatrix(&r.matrix, 0, 0, 1, 1); gen_schur_standardize1(&vh.matrix, &vr.matrix, &a, &b, w); gen_store_eigval1(&vh.matrix, a, b, alpha, beta, w); --N; h = gsl_matrix_submatrix(&h.matrix, 1, 1, N, N); r = gsl_matrix_submatrix(&r.matrix, 1, 1, N, N); } else if (q == 2) { /* upper left 2-by-2 block may have converged */ vh = gsl_matrix_submatrix(&h.matrix, 0, 0, 2, 2); vr = gsl_matrix_submatrix(&r.matrix, 0, 0, 2, 2); s = gen_schur_standardize2(&vh.matrix, &vr.matrix, &z1, &z2, &a, &b, w); if (s != GSL_SUCCESS) { /* * this 2-by-2 block contains real eigenvalues that * have not yet separated into 1-by-1 blocks - * recursively call gen_schur_decomp() to finish off * this block */ gen_schur_decomp(&vh.matrix, &vr.matrix, alpha, beta, w); } else { /* we got 2 complex eigenvalues */ gen_store_eigval2(&vh.matrix, &z1, a, &z2, b, alpha, beta, w); } N -= 2; h = gsl_matrix_submatrix(&h.matrix, 2, 2, N, N); r = gsl_matrix_submatrix(&r.matrix, 2, 2, N, N); } else { /* * There is a zero element on the subdiagonal somewhere * in the middle of the matrix - we can now operate * separately on the two submatrices split by this * element. q is the row index of the zero element. */ /* operate on lower right (N - q)-by-(N - q) block first */ vh = gsl_matrix_submatrix(&h.matrix, q, q, N - q, N - q); vr = gsl_matrix_submatrix(&r.matrix, q, q, N - q, N - q); gen_schur_decomp(&vh.matrix, &vr.matrix, alpha, beta, w); /* operate on upper left q-by-q block */ vh = gsl_matrix_submatrix(&h.matrix, 0, 0, q, q); vr = gsl_matrix_submatrix(&r.matrix, 0, 0, q, q); gen_schur_decomp(&vh.matrix, &vr.matrix, alpha, beta, w); N = 0; } } /* while ((N > 1) && (w->n_iter)++ < w->max_iterations) */ /* handle special case of N = 1 */ if (N == 1) { gen_schur_standardize1(&h.matrix, &r.matrix, &a, &b, w); gen_store_eigval1(&h.matrix, a, b, alpha, beta, w); } } /* gen_schur_decomp() */ /* gen_qzstep() This routine determines what type of QZ step to perform on the generalized matrix pair (H, R). If the pair is 3-by-3 or bigger, we look at the bottom right 2-by-2 block. If this block has complex eigenvalues, we perform a Francis double shift QZ sweep. If it has real eigenvalues, we perform an implicit single shift QZ sweep. If the pair is 2-by-2 with real eigenvalues, we perform a single shift sweep. If it has complex eigenvalues, we return GSL_CONTINUE to notify the calling function that a 2-by-2 block with complex eigenvalues has converged, so that it may then call gen_schur_standardize2(). In the real eigenvalue case, we want to continue doing QZ sweeps to break it up into two 1-by-1 blocks. See LAPACK routine DHGEQZ and [1] for more information. Inputs: H - upper Hessenberg matrix (at least 2-by-2) R - upper triangular matrix (at least 2-by-2) w - workspace Return: GSL_SUCCESS on normal completion GSL_CONTINUE if we detect a 2-by-2 block with complex eigenvalues */ static inline int gen_qzstep(gsl_matrix *H, gsl_matrix *R, gsl_eigen_gen_workspace *w) { const size_t N = H->size1; gsl_matrix_view vh, vr; /* views of bottom right 2-by-2 block */ double wr1, wr2, wi; double scale1, scale2, scale; double cs, sn; /* givens rotation */ double temp, /* temporary variables */ temp2; size_t j; /* looping */ gsl_vector_view xv, yv; /* temporary views */ size_t top; size_t rows; if (w->n_iter % 10 == 0) { /* * Exceptional shift - we have gone 10 iterations without finding * a new eigenvalue, do a single shift sweep with an * exceptional shift */ if ((GSL_DBL_MIN * w->max_iterations) * fabs(gsl_matrix_get(H, N - 2, N - 1)) < fabs(gsl_matrix_get(R, N - 2, N - 2))) { w->eshift += gsl_matrix_get(H, N - 2, N - 1) / gsl_matrix_get(R, N - 2, N - 2); } else w->eshift += 1.0 / (GSL_DBL_MIN * w->max_iterations); if ((w->eshift < GSL_DBL_EPSILON) && (GSL_DBL_MIN * w->max_iterations) * fabs(gsl_matrix_get(H, N - 1, N - 2)) < fabs(gsl_matrix_get(R, N - 2, N - 2))) { w->eshift = GEN_ESHIFT_COEFF * (w->ascale * gsl_matrix_get(H, N - 1, N - 2)) / (w->bscale * gsl_matrix_get(R, N - 2, N - 2)); } scale1 = 1.0; wr1 = w->eshift; } else { /* * Compute generalized eigenvalues of bottom right 2-by-2 block * to be used as shifts - wr1 is the Wilkinson shift */ vh = gsl_matrix_submatrix(H, N - 2, N - 2, 2, 2); vr = gsl_matrix_submatrix(R, N - 2, N - 2, 2, 2); gsl_schur_gen_eigvals(&vh.matrix, &vr.matrix, &wr1, &wr2, &wi, &scale1, &scale2); if (wi != 0.0) { /* complex eigenvalues */ if (N == 2) { /* * its a 2-by-2 block with complex eigenvalues - notify * the calling function to deflate */ return (GSL_CONTINUE); } else { /* do a francis double shift sweep */ gen_qzstep_d(H, R, w); } return GSL_SUCCESS; } } /* real eigenvalues - perform single shift QZ step */ temp = GSL_MIN(w->ascale, 1.0) * (0.5 / GSL_DBL_MIN); if (scale1 > temp) scale = temp / scale1; else scale = 1.0; temp = GSL_MIN(w->bscale, 1.0) * (0.5 / GSL_DBL_MIN); if (fabs(wr1) > temp) scale = GSL_MIN(scale, temp / fabs(wr1)); scale1 *= scale; wr1 *= scale; if (w->needtop) { /* get absolute index of this matrix relative to original matrix */ top = gen_get_submatrix(w->H, H); } temp = scale1*gsl_matrix_get(H, 0, 0) - wr1*gsl_matrix_get(R, 0, 0); temp2 = scale1*gsl_matrix_get(H, 1, 0); create_givens(temp, temp2, &cs, &sn); sn = -sn; for (j = 0; j < N - 1; ++j) { if (j > 0) { temp = gsl_matrix_get(H, j, j - 1); temp2 = gsl_matrix_get(H, j + 1, j - 1); create_givens(temp, temp2, &cs, &sn); sn = -sn; /* apply to column (j - 1) */ temp = cs * gsl_matrix_get(H, j, j - 1) + sn * gsl_matrix_get(H, j + 1, j - 1); gsl_matrix_set(H, j, j - 1, temp); gsl_matrix_set(H, j + 1, j - 1, 0.0); } /* apply G to H(j:j+1,:) and T(j:j+1,:) */ if (w->compute_s) { xv = gsl_matrix_subrow(w->H, top + j, top + j, w->size - top - j); yv = gsl_matrix_subrow(w->H, top + j + 1, top + j, w->size - top - j); } else { xv = gsl_matrix_subrow(H, j, j, N - j); yv = gsl_matrix_subrow(H, j + 1, j, N - j); } gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); if (w->compute_t) { xv = gsl_matrix_subrow(w->R, top + j, top + j, w->size - top - j); yv = gsl_matrix_subrow(w->R, top + j + 1, top + j, w->size - top - j); } else { xv = gsl_matrix_subrow(R, j, j, N - j); yv = gsl_matrix_subrow(R, j + 1, j, N - j); } gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); if (w->Q) { /* accumulate Q: Q -> QG */ xv = gsl_matrix_column(w->Q, top + j); yv = gsl_matrix_column(w->Q, top + j + 1); gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); } temp = gsl_matrix_get(R, j + 1, j + 1); temp2 = gsl_matrix_get(R, j + 1, j); create_givens(temp, temp2, &cs, &sn); rows = GSL_MIN(j + 3, N); if (w->compute_s) { xv = gsl_matrix_subcolumn(w->H, top + j, 0, top + rows); yv = gsl_matrix_subcolumn(w->H, top + j + 1, 0, top + rows); } else { xv = gsl_matrix_subcolumn(H, j, 0, rows); yv = gsl_matrix_subcolumn(H, j + 1, 0, rows); } gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); rows = GSL_MIN(j + 2, N); if (w->compute_t) { xv = gsl_matrix_subcolumn(w->R, top + j, 0, top + rows); yv = gsl_matrix_subcolumn(w->R, top + j + 1, 0, top + rows); } else { xv = gsl_matrix_subcolumn(R, j, 0, rows); yv = gsl_matrix_subcolumn(R, j + 1, 0, rows); } gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); if (w->Z) { /* accumulate Z: Z -> ZG */ xv = gsl_matrix_column(w->Z, top + j); yv = gsl_matrix_column(w->Z, top + j + 1); gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); } } /* for (j = 0; j < N - 1; ++j) */ return GSL_SUCCESS; } /* gen_qzstep() */ /* gen_qzstep_d() Perform an implicit double shift QZ step. See Golub & Van Loan, "Matrix Computations" (3rd ed), algorithm 7.7.2 Inputs: H - upper Hessenberg matrix (at least 3-by-3) R - upper triangular matrix (at least 3-by-3) w - workspace */ static inline void gen_qzstep_d(gsl_matrix *H, gsl_matrix *R, gsl_eigen_gen_workspace *w) { const size_t N = H->size1; size_t j; /* looping */ double dat[3]; /* householder vector */ double tau; /* householder coefficient */ gsl_vector_view v2, v3; /* views into 'dat' */ gsl_matrix_view m; /* temporary view */ double tmp; size_t q, r; size_t top; /* location of H in original matrix */ double scale; double AB11, /* various matrix element ratios */ AB22, ABNN, ABMM, AMNBNN, ANMBMM, A21B11, A12B22, A32B22, B12B22, BMNBNN; v2 = gsl_vector_view_array(dat, 2); v3 = gsl_vector_view_array(dat, 3); if (w->needtop) { /* get absolute index of this matrix relative to original matrix */ top = gen_get_submatrix(w->H, H); } /* * Similar to the QR method, we take the shifts to be the two * zeros of the problem * * det[H(n-1:n,n-1:n) - s*R(n-1:n,n-1:n)] = 0 * * The initial householder vector elements are then given by * Eq. 4.1 of [1], which are designed to reduce errors when * off diagonal elements are small. */ ABMM = (w->ascale * gsl_matrix_get(H, N - 2, N - 2)) / (w->bscale * gsl_matrix_get(R, N - 2, N - 2)); ABNN = (w->ascale * gsl_matrix_get(H, N - 1, N - 1)) / (w->bscale * gsl_matrix_get(R, N - 1, N - 1)); AB11 = (w->ascale * gsl_matrix_get(H, 0, 0)) / (w->bscale * gsl_matrix_get(R, 0, 0)); AB22 = (w->ascale * gsl_matrix_get(H, 1, 1)) / (w->bscale * gsl_matrix_get(R, 1, 1)); AMNBNN = (w->ascale * gsl_matrix_get(H, N - 2, N - 1)) / (w->bscale * gsl_matrix_get(R, N - 1, N - 1)); ANMBMM = (w->ascale * gsl_matrix_get(H, N - 1, N - 2)) / (w->bscale * gsl_matrix_get(R, N - 2, N - 2)); BMNBNN = gsl_matrix_get(R, N - 2, N - 1) / gsl_matrix_get(R, N - 1, N - 1); A21B11 = (w->ascale * gsl_matrix_get(H, 1, 0)) / (w->bscale * gsl_matrix_get(R, 0, 0)); A12B22 = (w->ascale * gsl_matrix_get(H, 0, 1)) / (w->bscale * gsl_matrix_get(R, 1, 1)); A32B22 = (w->ascale * gsl_matrix_get(H, 2, 1)) / (w->bscale * gsl_matrix_get(R, 1, 1)); B12B22 = gsl_matrix_get(R, 0, 1) / gsl_matrix_get(R, 1, 1); /* * These are the Eqs (4.1) of [1], just multiplied by the factor * (A_{21} / B_{11}) */ dat[0] = (ABMM - AB11) * (ABNN - AB11) - (AMNBNN * ANMBMM) + (ANMBMM * BMNBNN * AB11) + (A12B22 - (AB11 * B12B22)) * A21B11; dat[1] = ((AB22 - AB11) - (A21B11 * B12B22) - (ABMM - AB11) - (ABNN - AB11) + (ANMBMM * BMNBNN)) * A21B11; dat[2] = A32B22 * A21B11; scale = fabs(dat[0]) + fabs(dat[1]) + fabs(dat[2]); if (scale != 0.0) { dat[0] /= scale; dat[1] /= scale; dat[2] /= scale; } for (j = 0; j < N - 2; ++j) { r = GSL_MIN(j + 4, N); /* * Find householder Q so that * * Q [x y z]^t = [ * 0 0 ]^t */ tau = gsl_linalg_householder_transform(&v3.vector); if (tau != 0.0) { /* * q is the initial column to start applying the householder * transformation. The GSL_MAX() simply ensures we don't * try to apply it to column (-1), since we are zeroing out * column (j - 1) except for the first iteration which * introduces the bulge. */ q = (size_t) GSL_MAX(0, (int)j - 1); /* H -> QH, R -> QR */ if (w->compute_s) { /* * We are computing the Schur form S, so we need to * transform the whole matrix H */ m = gsl_matrix_submatrix(w->H, top + j, top + q, 3, w->size - top - q); gsl_linalg_householder_hm(tau, &v3.vector, &m.matrix); } else { /* just transform the active block */ m = gsl_matrix_submatrix(H, j, q, 3, N - q); gsl_linalg_householder_hm(tau, &v3.vector, &m.matrix); } if (w->compute_t) { /* * We are computing the Schur form T, so we need to * transform the whole matrix R */ m = gsl_matrix_submatrix(w->R, top + j, top + j, 3, w->size - top - j); gsl_linalg_householder_hm(tau, &v3.vector, &m.matrix); } else { /* just transform the active block */ m = gsl_matrix_submatrix(R, j, j, 3, N - j); gsl_linalg_householder_hm(tau, &v3.vector, &m.matrix); } if (w->Q) { /* accumulate the transformation into Q */ m = gsl_matrix_submatrix(w->Q, 0, top + j, w->size, 3); gsl_linalg_householder_mh(tau, &v3.vector, &m.matrix); } } /* if (tau != 0.0) */ /* * Find householder Z so that * * [ r_{j+2,j} r_{j+2, j+1}, r_{j+2, j+2} ] Z = [ 0 0 * ] * * This isn't exactly what gsl_linalg_householder_transform * does, so we need to rotate the input vector so it preserves * the last element, and then rotate it back afterwards. * * So instead of transforming [x y z], we transform [z x y], * and the resulting HH vector [1 v2 v3] -> [v2 v3 1] but * then needs to be scaled to have the first element = 1, so * it becomes [1 v3/v2 1/v2] (tau must also be scaled accordingly). */ dat[0] = gsl_matrix_get(R, j + 2, j + 2); dat[1] = gsl_matrix_get(R, j + 2, j); dat[2] = gsl_matrix_get(R, j + 2, j + 1); scale = fabs(dat[0]) + fabs(dat[1]) + fabs(dat[2]); if (scale != 0.0) { dat[0] /= scale; dat[1] /= scale; dat[2] /= scale; } tau = gsl_linalg_householder_transform(&v3.vector); if (tau != 0.0) { /* rotate back */ tmp = gsl_vector_get(&v3.vector, 1); gsl_vector_set(&v3.vector, 1, gsl_vector_get(&v3.vector, 2)/tmp); gsl_vector_set(&v3.vector, 2, 1.0 / tmp); tau *= tmp * tmp; /* H -> HZ, R -> RZ */ if (w->compute_s) { m = gsl_matrix_submatrix(w->H, 0, top + j, top + r, 3); gsl_linalg_householder_mh(tau, &v3.vector, &m.matrix); } else { m = gsl_matrix_submatrix(H, 0, j, r, 3); gsl_linalg_householder_mh(tau, &v3.vector, &m.matrix); } if (w->compute_t) { m = gsl_matrix_submatrix(w->R, 0, top + j, top + j + 3, 3); gsl_linalg_householder_mh(tau, &v3.vector, &m.matrix); } else { m = gsl_matrix_submatrix(R, 0, j, j + 3, 3); gsl_linalg_householder_mh(tau, &v3.vector, &m.matrix); } if (w->Z) { /* accumulate transformation into Z */ m = gsl_matrix_submatrix(w->Z, 0, top + j, w->size, 3); gsl_linalg_householder_mh(tau, &v3.vector, &m.matrix); } } /* if (tau != 0.0) */ /* * Find householder Z so that * * [ r_{j+1,j} r_{j+1, j+1} ] Z = [ 0 * ] */ dat[0] = gsl_matrix_get(R, j + 1, j + 1); dat[1] = gsl_matrix_get(R, j + 1, j); scale = fabs(dat[0]) + fabs(dat[1]); if (scale != 0.0) { dat[0] /= scale; dat[1] /= scale; } tau = gsl_linalg_householder_transform(&v2.vector); if (tau != 0.0) { /* rotate back */ tmp = gsl_vector_get(&v2.vector, 1); gsl_vector_set(&v2.vector, 1, 1.0 / tmp); tau *= tmp * tmp; /* H -> HZ, R -> RZ */ if (w->compute_s) { m = gsl_matrix_submatrix(w->H, 0, top + j, top + r, 2); gsl_linalg_householder_mh(tau, &v2.vector, &m.matrix); } else { m = gsl_matrix_submatrix(H, 0, j, r, 2); gsl_linalg_householder_mh(tau, &v2.vector, &m.matrix); } if (w->compute_t) { m = gsl_matrix_submatrix(w->R, 0, top + j, top + j + 3, 2); gsl_linalg_householder_mh(tau, &v2.vector, &m.matrix); } else { m = gsl_matrix_submatrix(R, 0, j, j + 3, 2); gsl_linalg_householder_mh(tau, &v2.vector, &m.matrix); } if (w->Z) { /* accumulate transformation into Z */ m = gsl_matrix_submatrix(w->Z, 0, top + j, w->size, 2); gsl_linalg_householder_mh(tau, &v2.vector, &m.matrix); } } /* if (tau != 0.0) */ dat[0] = gsl_matrix_get(H, j + 1, j); dat[1] = gsl_matrix_get(H, j + 2, j); if (j < N - 3) dat[2] = gsl_matrix_get(H, j + 3, j); scale = fabs(dat[0]) + fabs(dat[1]) + fabs(dat[2]); if (scale != 0.0) { dat[0] /= scale; dat[1] /= scale; dat[2] /= scale; } } /* for (j = 0; j < N - 2; ++j) */ /* * Find Householder Q so that * * Q [ x y ]^t = [ * 0 ]^t */ scale = fabs(dat[0]) + fabs(dat[1]); if (scale != 0.0) { dat[0] /= scale; dat[1] /= scale; } tau = gsl_linalg_householder_transform(&v2.vector); if (w->compute_s) { m = gsl_matrix_submatrix(w->H, top + N - 2, top + N - 3, 2, w->size - top - N + 3); gsl_linalg_householder_hm(tau, &v2.vector, &m.matrix); } else { m = gsl_matrix_submatrix(H, N - 2, N - 3, 2, 3); gsl_linalg_householder_hm(tau, &v2.vector, &m.matrix); } if (w->compute_t) { m = gsl_matrix_submatrix(w->R, top + N - 2, top + N - 2, 2, w->size - top - N + 2); gsl_linalg_householder_hm(tau, &v2.vector, &m.matrix); } else { m = gsl_matrix_submatrix(R, N - 2, N - 2, 2, 2); gsl_linalg_householder_hm(tau, &v2.vector, &m.matrix); } if (w->Q) { /* accumulate the transformation into Q */ m = gsl_matrix_submatrix(w->Q, 0, top + N - 2, w->size, 2); gsl_linalg_householder_mh(tau, &v2.vector, &m.matrix); } /* * Find Householder Z so that * * [ b_{n,n-1} b_{nn} ] Z = [ 0 * ] */ dat[0] = gsl_matrix_get(R, N - 1, N - 1); dat[1] = gsl_matrix_get(R, N - 1, N - 2); scale = fabs(dat[0]) + fabs(dat[1]); if (scale != 0.0) { dat[0] /= scale; dat[1] /= scale; } tau = gsl_linalg_householder_transform(&v2.vector); /* rotate back */ tmp = gsl_vector_get(&v2.vector, 1); gsl_vector_set(&v2.vector, 1, 1.0 / tmp); tau *= tmp * tmp; if (w->compute_s) { m = gsl_matrix_submatrix(w->H, 0, top + N - 2, top + N, 2); gsl_linalg_householder_mh(tau, &v2.vector, &m.matrix); } else { m = gsl_matrix_submatrix(H, 0, N - 2, N, 2); gsl_linalg_householder_mh(tau, &v2.vector, &m.matrix); } if (w->compute_t) { m = gsl_matrix_submatrix(w->R, 0, top + N - 2, top + N, 2); gsl_linalg_householder_mh(tau, &v2.vector, &m.matrix); } else { m = gsl_matrix_submatrix(R, 0, N - 2, N, 2); gsl_linalg_householder_mh(tau, &v2.vector, &m.matrix); } if (w->Z) { /* accumulate the transformation into Z */ m = gsl_matrix_submatrix(w->Z, 0, top + N - 2, w->size, 2); gsl_linalg_householder_mh(tau, &v2.vector, &m.matrix); } } /* gen_qzstep_d() */ /* gen_tri_split_top() This routine is called when the leading element on the diagonal of R has become negligible. Split off a 1-by-1 block at the top. Inputs: H - upper hessenberg matrix R - upper triangular matrix w - workspace */ static void gen_tri_split_top(gsl_matrix *H, gsl_matrix *R, gsl_eigen_gen_workspace *w) { const size_t N = H->size1; size_t j, top; double cs, sn; gsl_vector_view xv, yv; if (w->needtop) top = gen_get_submatrix(w->H, H); j = 0; create_givens(gsl_matrix_get(H, j, j), gsl_matrix_get(H, j + 1, j), &cs, &sn); sn = -sn; if (w->compute_s) { xv = gsl_matrix_subrow(w->H, top + j, top, w->size - top); yv = gsl_matrix_subrow(w->H, top + j + 1, top, w->size - top); } else { xv = gsl_matrix_row(H, j); yv = gsl_matrix_row(H, j + 1); } gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); gsl_matrix_set(H, j + 1, j, 0.0); if (w->compute_t) { xv = gsl_matrix_subrow(w->R, top + j, top + 1, w->size - top - 1); yv = gsl_matrix_subrow(w->R, top + j + 1, top + 1, w->size - top - 1); } else { xv = gsl_matrix_subrow(R, j, 1, N - 1); yv = gsl_matrix_subrow(R, j + 1, 1, N - 1); } gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); if (w->Q) { xv = gsl_matrix_column(w->Q, top + j); yv = gsl_matrix_column(w->Q, top + j + 1); gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); } } /* gen_tri_split_top() */ /* gen_tri_chase_zero() This routine is called when an element on the diagonal of R has become negligible. Chase the zero to the bottom of the active block so we can split off a 1-by-1 block. Inputs: H - upper hessenberg matrix R - upper triangular matrix q - index such that R(q,q) = 0 (q must be > 0) w - workspace */ static inline void gen_tri_chase_zero(gsl_matrix *H, gsl_matrix *R, size_t q, gsl_eigen_gen_workspace *w) { const size_t N = H->size1; size_t j, top; double cs, sn; gsl_vector_view xv, yv; if (w->needtop) top = gen_get_submatrix(w->H, H); for (j = q; j < N - 1; ++j) { create_givens(gsl_matrix_get(R, j, j + 1), gsl_matrix_get(R, j + 1, j + 1), &cs, &sn); sn = -sn; if (w->compute_t) { xv = gsl_matrix_subrow(w->R, top + j, top + j + 1, w->size - top - j - 1); yv = gsl_matrix_subrow(w->R, top + j + 1, top + j + 1, w->size - top - j - 1); } else { xv = gsl_matrix_subrow(R, j, j + 1, N - j - 1); yv = gsl_matrix_subrow(R, j + 1, j + 1, N - j - 1); } gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); gsl_matrix_set(R, j + 1, j + 1, 0.0); if (w->compute_s) { xv = gsl_matrix_subrow(w->H, top + j, top + j - 1, w->size - top - j + 1); yv = gsl_matrix_subrow(w->H, top + j + 1, top + j - 1, w->size - top - j + 1); } else { xv = gsl_matrix_subrow(H, j, j - 1, N - j + 1); yv = gsl_matrix_subrow(H, j + 1, j - 1, N - j + 1); } gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); if (w->Q) { /* accumulate Q */ xv = gsl_matrix_column(w->Q, top + j); yv = gsl_matrix_column(w->Q, top + j + 1); gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); } create_givens(gsl_matrix_get(H, j + 1, j), gsl_matrix_get(H, j + 1, j - 1), &cs, &sn); sn = -sn; if (w->compute_s) { xv = gsl_matrix_subcolumn(w->H, top + j, 0, top + j + 2); yv = gsl_matrix_subcolumn(w->H, top + j - 1, 0, top + j + 2); } else { xv = gsl_matrix_subcolumn(H, j, 0, j + 2); yv = gsl_matrix_subcolumn(H, j - 1, 0, j + 2); } gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); gsl_matrix_set(H, j + 1, j - 1, 0.0); if (w->compute_t) { xv = gsl_matrix_subcolumn(w->R, top + j, 0, top + j + 1); yv = gsl_matrix_subcolumn(w->R, top + j - 1, 0, top + j + 1); } else { xv = gsl_matrix_subcolumn(R, j, 0, j + 1); yv = gsl_matrix_subcolumn(R, j - 1, 0, j + 1); } gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); if (w->Z) { /* accumulate Z */ xv = gsl_matrix_column(w->Z, top + j); yv = gsl_matrix_column(w->Z, top + j - 1); gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); } } } /* gen_tri_chase_zero() */ /* gen_tri_zero_H() Companion function to get_tri_chase_zero(). After the zero on the diagonal of R has been chased to the bottom, we zero the element H(n, n - 1) in order to split off a 1-by-1 block. */ static inline void gen_tri_zero_H(gsl_matrix *H, gsl_matrix *R, gsl_eigen_gen_workspace *w) { const size_t N = H->size1; size_t top; double cs, sn; gsl_vector_view xv, yv; if (w->needtop) top = gen_get_submatrix(w->H, H); create_givens(gsl_matrix_get(H, N - 1, N - 1), gsl_matrix_get(H, N - 1, N - 2), &cs, &sn); sn = -sn; if (w->compute_s) { xv = gsl_matrix_subcolumn(w->H, top + N - 1, 0, top + N); yv = gsl_matrix_subcolumn(w->H, top + N - 2, 0, top + N); } else { xv = gsl_matrix_column(H, N - 1); yv = gsl_matrix_column(H, N - 2); } gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); gsl_matrix_set(H, N - 1, N - 2, 0.0); if (w->compute_t) { xv = gsl_matrix_subcolumn(w->R, top + N - 1, 0, top + N - 1); yv = gsl_matrix_subcolumn(w->R, top + N - 2, 0, top + N - 1); } else { xv = gsl_matrix_subcolumn(R, N - 1, 0, N - 1); yv = gsl_matrix_subcolumn(R, N - 2, 0, N - 1); } gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); if (w->Z) { /* accumulate Z */ xv = gsl_matrix_column(w->Z, top + N - 1); yv = gsl_matrix_column(w->Z, top + N - 2); gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); } } /* gen_tri_zero_H() */ /* gen_search_small_elements() This routine searches for small elements in the matrix pencil (H, R) to determine if any eigenvalues have converged. Tests: 1. Test if the Hessenberg matrix has a small subdiagonal element: H(i, i - 1) < tolerance 2. Test if the Triangular matrix has a small diagonal element: R(i, i) < tolerance Possible outcomes: (A) Neither test passed: in this case 'flag' is set to 0 and the function returns 0 (B) Test 1 passes and 2 does not: in this case 'flag' is set to 1 and we return the row index i such that H(i, i - 1) < tol (C) Test 2 passes and 1 does not: in this case 'flag' is set to 2 and we return the index i such that R(i, i) < tol (D) Tests 1 and 2 both pass: in this case 'flag' is set to 3 and we return the index i such that H(i, i - 1) < tol and R(i, i) < tol Inputs: H - upper Hessenberg matrix R - upper Triangular matrix flag - (output) flag set on output (see above) w - workspace Return: see above */ static inline size_t gen_search_small_elements(gsl_matrix *H, gsl_matrix *R, int *flag, gsl_eigen_gen_workspace *w) { const size_t N = H->size1; int k; size_t i; int pass1 = 0; int pass2 = 0; for (k = (int) N - 1; k >= 0; --k) { i = (size_t) k; if (i != 0 && fabs(gsl_matrix_get(H, i, i - 1)) <= w->atol) { gsl_matrix_set(H, i, i - 1, 0.0); pass1 = 1; } if (fabs(gsl_matrix_get(R, i, i)) < w->btol) { gsl_matrix_set(R, i, i, 0.0); pass2 = 1; } if (pass1 && !pass2) /* case B */ { *flag = 1; return (i); } else if (!pass1 && pass2) /* case C */ { *flag = 2; return (i); } else if (pass1 && pass2) /* case D */ { *flag = 3; return (i); } } /* neither test passed: case A */ *flag = 0; return (0); } /* gen_search_subdiag_small_elements() */ /* gen_schur_standardize1() This function is called when a 1-by-1 block has converged - convert the block to standard form and update the Schur forms and vectors if required. Standard form here means that the diagonal element of B is positive. Inputs: A - 1-by-1 matrix in Schur form S B - 1-by-1 matrix in Schur form T alphar - where to store real part of eigenvalue numerator beta - where to store eigenvalue denominator w - workspace Return: success */ static int gen_schur_standardize1(gsl_matrix *A, gsl_matrix *B, double *alphar, double *beta, gsl_eigen_gen_workspace *w) { size_t i; size_t top; /* * it is a 1-by-1 block - the only requirement is that * B_{00} is > 0, so if it isn't apply a -I transformation */ if (gsl_matrix_get(B, 0, 0) < 0.0) { if (w->needtop) top = gen_get_submatrix(w->H, A); if (w->compute_t) { for (i = 0; i <= top; ++i) gsl_matrix_set(w->R, i, top, -gsl_matrix_get(w->R, i, top)); } else gsl_matrix_set(B, 0, 0, -gsl_matrix_get(B, 0, 0)); if (w->compute_s) { for (i = 0; i <= top; ++i) gsl_matrix_set(w->H, i, top, -gsl_matrix_get(w->H, i, top)); } else gsl_matrix_set(A, 0, 0, -gsl_matrix_get(A, 0, 0)); if (w->Z) { for (i = 0; i < w->size; ++i) gsl_matrix_set(w->Z, i, top, -gsl_matrix_get(w->Z, i, top)); } } *alphar = gsl_matrix_get(A, 0, 0); *beta = gsl_matrix_get(B, 0, 0); return GSL_SUCCESS; } /* gen_schur_standardize1() */ /* gen_schur_standardize2() This function is called when a 2-by-2 generalized block has converged. Convert the block to standard form, which means B is rotated so that B = [ B11 0 ] with B11, B22 non-negative [ 0 B22 ] If the resulting block (A, B) has complex eigenvalues, they are computed. Otherwise, the function will return GSL_CONTINUE to notify caller that we need to do more single shift sweeps to convert the 2-by-2 block into two 1-by-1 blocks. Inputs: A - 2-by-2 submatrix of schur form S B - 2-by-2 submatrix of schur form T alpha1 - (output) where to store eigenvalue 1 numerator alpha2 - (output) where to store eigenvalue 2 numerator beta1 - (output) where to store eigenvalue 1 denominator beta2 - (output) where to store eigenvalue 2 denominator w - workspace Return: GSL_SUCCESS if block has complex eigenvalues (they are computed) GSL_CONTINUE if block has real eigenvalues (they are not computed) */ static int gen_schur_standardize2(gsl_matrix *A, gsl_matrix *B, gsl_complex *alpha1, gsl_complex *alpha2, double *beta1, double *beta2, gsl_eigen_gen_workspace *w) { double datB[4], datV[4], datS[2], work[2]; gsl_matrix_view uv = gsl_matrix_view_array(datB, 2, 2); gsl_matrix_view vv = gsl_matrix_view_array(datV, 2, 2); gsl_vector_view sv = gsl_vector_view_array(datS, 2); gsl_vector_view wv = gsl_vector_view_array(work, 2); double B11, B22; size_t top; double det; double cr, sr, cl, sl; gsl_vector_view xv, yv; int s; if (w->needtop) top = gen_get_submatrix(w->H, A); /* * Rotate B so that * * B = [ B11 0 ] * [ 0 B22 ] * * with B11 non-negative */ gsl_matrix_memcpy(&uv.matrix, B); gsl_linalg_SV_decomp(&uv.matrix, &vv.matrix, &sv.vector, &wv.vector); /* * Right now, B = U S V^t, where S = diag(s) * * The SVD routine may have computed reflection matrices U and V, * but it would be much nicer to have rotations since we won't have * to use BLAS mat-mat multiplications to update our matrices, * and can instead use drot. So convert them to rotations if * necessary */ det = gsl_matrix_get(&vv.matrix, 0, 0) * gsl_matrix_get(&vv.matrix, 1, 1) - gsl_matrix_get(&vv.matrix, 0, 1) * gsl_matrix_get(&vv.matrix, 1, 0); if (det < 0.0) { /* V is a reflection, convert it to a rotation by inserting * F = [1 0; 0 -1] so that: * * B = U S [1 0] [1 0] V^t * [0 -1] [0 -1] * * so S -> S F and V -> V F where F is the reflection matrix * We just need to invert S22 since the first column of V * will remain unchanged and we can just read off the CS and SN * parameters. */ datS[1] = -datS[1]; } cr = gsl_matrix_get(&vv.matrix, 0, 0); sr = gsl_matrix_get(&vv.matrix, 1, 0); /* same for U */ det = gsl_matrix_get(&uv.matrix, 0, 0) * gsl_matrix_get(&uv.matrix, 1, 1) - gsl_matrix_get(&uv.matrix, 0, 1) * gsl_matrix_get(&uv.matrix, 1, 0); if (det < 0.0) datS[1] = -datS[1]; cl = gsl_matrix_get(&uv.matrix, 0, 0); sl = gsl_matrix_get(&uv.matrix, 1, 0); B11 = gsl_vector_get(&sv.vector, 0); B22 = gsl_vector_get(&sv.vector, 1); /* make sure B11 is positive */ if (B11 < 0.0) { B11 = -B11; B22 = -B22; cr = -cr; sr = -sr; } /* * At this point, * * [ S11 0 ] = [ CSL SNL ] B [ CSR -SNR ] * [ 0 S22 ] [-SNL CSL ] [ SNR CSR ] * * apply rotations to H and rest of R */ if (w->compute_s) { xv = gsl_matrix_subrow(w->H, top, top, w->size - top); yv = gsl_matrix_subrow(w->H, top + 1, top, w->size - top); gsl_blas_drot(&xv.vector, &yv.vector, cl, sl); xv = gsl_matrix_subcolumn(w->H, top, 0, top + 2); yv = gsl_matrix_subcolumn(w->H, top + 1, 0, top + 2); gsl_blas_drot(&xv.vector, &yv.vector, cr, sr); } else { xv = gsl_matrix_row(A, 0); yv = gsl_matrix_row(A, 1); gsl_blas_drot(&xv.vector, &yv.vector, cl, sl); xv = gsl_matrix_column(A, 0); yv = gsl_matrix_column(A, 1); gsl_blas_drot(&xv.vector, &yv.vector, cr, sr); } if (w->compute_t) { if (top != (w->size - 2)) { xv = gsl_matrix_subrow(w->R, top, top + 2, w->size - top - 2); yv = gsl_matrix_subrow(w->R, top + 1, top + 2, w->size - top - 2); gsl_blas_drot(&xv.vector, &yv.vector, cl, sl); } if (top != 0) { xv = gsl_matrix_subcolumn(w->R, top, 0, top); yv = gsl_matrix_subcolumn(w->R, top + 1, 0, top); gsl_blas_drot(&xv.vector, &yv.vector, cr, sr); } } if (w->Q) { xv = gsl_matrix_column(w->Q, top); yv = gsl_matrix_column(w->Q, top + 1); gsl_blas_drot(&xv.vector, &yv.vector, cl, sl); } if (w->Z) { xv = gsl_matrix_column(w->Z, top); yv = gsl_matrix_column(w->Z, top + 1); gsl_blas_drot(&xv.vector, &yv.vector, cr, sr); } gsl_matrix_set(B, 0, 0, B11); gsl_matrix_set(B, 0, 1, 0.0); gsl_matrix_set(B, 1, 0, 0.0); gsl_matrix_set(B, 1, 1, B22); /* if B22 is < 0, make it positive by negating its column */ if (B22 < 0.0) { size_t i; if (w->compute_s) { for (i = 0; i < top + 2; ++i) gsl_matrix_set(w->H, i, top + 1, -gsl_matrix_get(w->H, i, top + 1)); } else { gsl_matrix_set(A, 0, 1, -gsl_matrix_get(A, 0, 1)); gsl_matrix_set(A, 1, 1, -gsl_matrix_get(A, 1, 1)); } if (w->compute_t) { for (i = 0; i < top + 2; ++i) gsl_matrix_set(w->R, i, top + 1, -gsl_matrix_get(w->R, i, top + 1)); } else { gsl_matrix_set(B, 0, 1, -gsl_matrix_get(B, 0, 1)); gsl_matrix_set(B, 1, 1, -gsl_matrix_get(B, 1, 1)); } if (w->Z) { xv = gsl_matrix_column(w->Z, top + 1); gsl_vector_scale(&xv.vector, -1.0); } } /* our block is now in standard form - compute eigenvalues */ s = gen_compute_eigenvals(A, B, alpha1, alpha2, beta1, beta2); return s; } /* gen_schur_standardize2() */ /* gen_compute_eigenvals() Compute the complex eigenvalues of a 2-by-2 block Return: GSL_CONTINUE if block contains real eigenvalues (they are not computed) GSL_SUCCESS on normal completion */ static int gen_compute_eigenvals(gsl_matrix *A, gsl_matrix *B, gsl_complex *alpha1, gsl_complex *alpha2, double *beta1, double *beta2) { double wr1, wr2, wi, scale1, scale2; double s1inv; double A11, A12, A21, A22; double B11, B22; double c11r, c11i, c12, c21, c22r, c22i; double cz, cq; double szr, szi, sqr, sqi; double a1r, a1i, a2r, a2i, b1r, b1i, b1a, b2r, b2i, b2a; double alphar, alphai; double t1, an, bn, tempr, tempi, wabs; /* * This function is called from gen_schur_standardize2() and * its possible the standardization has perturbed the eigenvalues * onto the real line - so check for this before computing them */ gsl_schur_gen_eigvals(A, B, &wr1, &wr2, &wi, &scale1, &scale2); if (wi == 0.0) return GSL_CONTINUE; /* real eigenvalues - continue QZ iteration */ /* complex eigenvalues - compute alpha and beta */ s1inv = 1.0 / scale1; A11 = gsl_matrix_get(A, 0, 0); A12 = gsl_matrix_get(A, 0, 1); A21 = gsl_matrix_get(A, 1, 0); A22 = gsl_matrix_get(A, 1, 1); B11 = gsl_matrix_get(B, 0, 0); B22 = gsl_matrix_get(B, 1, 1); c11r = scale1 * A11 - wr1 * B11; c11i = -wi * B11; c12 = scale1 * A12; c21 = scale1 * A21; c22r = scale1 * A22 - wr1 * B22; c22i = -wi * B22; if (fabs(c11r) + fabs(c11i) + fabs(c12) > fabs(c21) + fabs(c22r) + fabs(c22i)) { t1 = gsl_hypot3(c12, c11r, c11i); if (t1 != 0.0) { cz = c12 / t1; szr = -c11r / t1; szi = -c11i / t1; } else { cz = 0.0; szr = 1.0; szi = 0.0; } } else { cz = hypot(c22r, c22i); if (cz <= GSL_DBL_MIN) { cz = 0.0; szr = 1.0; szi = 0.0; } else { tempr = c22r / cz; tempi = c22i / cz; t1 = hypot(cz, c21); cz /= t1; szr = -c21*tempr / t1; szi = c21*tempi / t1; } } an = fabs(A11) + fabs(A12) + fabs(A21) + fabs(A22); bn = fabs(B11) + fabs(B22); wabs = fabs(wr1) + fabs(wi); if (scale1*an > wabs*bn) { cq = cz * B11; if (cq <= GSL_DBL_MIN) { cq = 0.0; sqr = 1.0; sqi = 0.0; } else { sqr = szr * B22; sqi = -szi * B22; } } else { a1r = cz * A11 + szr * A12; a1i = szi * A12; a2r = cz * A21 + szr * A22; a2i = szi * A22; cq = hypot(a1r, a1i); if (cq <= GSL_DBL_MIN) { cq = 0.0; sqr = 1.0; sqi = 0.0; } else { tempr = a1r / cq; tempi = a1i / cq; sqr = tempr * a2r + tempi * a2i; sqi = tempi * a2r - tempr * a2i; } } t1 = gsl_hypot3(cq, sqr, sqi); cq /= t1; sqr /= t1; sqi /= t1; tempr = sqr*szr - sqi*szi; tempi = sqr*szi + sqi*szr; b1r = cq*cz*B11 + tempr*B22; b1i = tempi*B22; b1a = hypot(b1r, b1i); b2r = cq*cz*B22 + tempr*B11; b2i = -tempi*B11; b2a = hypot(b2r, b2i); *beta1 = b1a; *beta2 = b2a; alphar = (wr1 * b1a) * s1inv; alphai = (wi * b1a) * s1inv; GSL_SET_COMPLEX(alpha1, alphar, alphai); alphar = (wr1 * b2a) * s1inv; alphai = -(wi * b2a) * s1inv; GSL_SET_COMPLEX(alpha2, alphar, alphai); return GSL_SUCCESS; } /* gen_compute_eigenvals() */ /* gen_store_eigval1() Store eigenvalue of a 1-by-1 block into the alpha and beta output vectors. This routine ensures that eigenvalues are stored in the same order as they appear in the Schur form and updates various internal workspace quantities. */ static void gen_store_eigval1(const gsl_matrix *H, const double a, const double b, gsl_vector_complex *alpha, gsl_vector *beta, gsl_eigen_gen_workspace *w) { size_t top = gen_get_submatrix(w->H, H); gsl_complex z; GSL_SET_COMPLEX(&z, a, 0.0); gsl_vector_complex_set(alpha, top, z); gsl_vector_set(beta, top, b); w->n_evals += 1; w->n_iter = 0; w->eshift = 0.0; } /* gen_store_eigval1() */ /* gen_store_eigval2() Store eigenvalues of a 2-by-2 block into the alpha and beta output vectors. This routine ensures that eigenvalues are stored in the same order as they appear in the Schur form and updates various internal workspace quantities. */ static void gen_store_eigval2(const gsl_matrix *H, const gsl_complex *alpha1, const double beta1, const gsl_complex *alpha2, const double beta2, gsl_vector_complex *alpha, gsl_vector *beta, gsl_eigen_gen_workspace *w) { size_t top = gen_get_submatrix(w->H, H); gsl_vector_complex_set(alpha, top, *alpha1); gsl_vector_set(beta, top, beta1); gsl_vector_complex_set(alpha, top + 1, *alpha2); gsl_vector_set(beta, top + 1, beta2); w->n_evals += 2; w->n_iter = 0; w->eshift = 0.0; } /* gen_store_eigval2() */ /* gen_get_submatrix() B is a submatrix of A. The goal of this function is to compute the indices in A of where the matrix B resides */ static inline size_t gen_get_submatrix(const gsl_matrix *A, const gsl_matrix *B) { size_t diff; double ratio; size_t top; diff = (size_t) (B->data - A->data); /* B is on the diagonal of A, so measure distance in units of tda+1 */ ratio = (double)diff / ((double) (A->tda + 1)); top = (size_t) floor(ratio); return top; } /* gen_get_submatrix() */ /* Frobenius norm */ inline static double normF (gsl_matrix * A) { size_t i, j, M = A->size1, N = A->size2; double sum = 0.0, scale = 0.0, ssq = 1.0; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { double Aij = gsl_matrix_get (A, i, j); if (Aij != 0.0) { double ax = fabs (Aij); if (scale < ax) { ssq = 1.0 + ssq * (scale / ax) * (scale / ax); scale = ax; } else { ssq += (ax / scale) * (ax / scale); } } } } sum = scale * sqrt (ssq); return sum; } /* Generate a Givens rotation (cos,sin) which takes v=(x,y) to (|v|,0) From Golub and Van Loan, "Matrix Computations", Section 5.1.8 */ inline static void create_givens (const double a, const double b, double *c, double *s) { if (b == 0) { *c = 1; *s = 0; } else if (fabs (b) > fabs (a)) { double t = -a / b; double s1 = 1.0 / sqrt (1 + t * t); *s = s1; *c = s1 * t; } else { double t = -b / a; double c1 = 1.0 / sqrt (1 + t * t); *c = c1; *s = c1 * t; } } praat-6.0.04/external/gsl/gsl_eigen__genherm.c000066400000000000000000000133341261542461700212770ustar00rootroot00000000000000/* eigen/genherm.c * * Copyright (C) 2007 Patrick Alken * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "gsl__config.h" #include "gsl_eigen.h" #include "gsl_linalg.h" #include "gsl_math.h" #include "gsl_blas.h" #include "gsl_vector.h" #include "gsl_matrix.h" #include "gsl_complex.h" #include "gsl_complex_math.h" /* * This module computes the eigenvalues of a complex generalized * hermitian-definite eigensystem A x = \lambda B x, where A and * B are hermitian, and B is positive-definite. */ /* gsl_eigen_genherm_alloc() Allocate a workspace for solving the generalized hermitian-definite eigenvalue problem. The size of this workspace is O(3n). Inputs: n - size of matrices Return: pointer to workspace */ gsl_eigen_genherm_workspace * gsl_eigen_genherm_alloc(const size_t n) { gsl_eigen_genherm_workspace *w; if (n == 0) { GSL_ERROR_NULL ("matrix dimension must be positive integer", GSL_EINVAL); } w = calloc (1, sizeof (gsl_eigen_genherm_workspace)); if (w == 0) { GSL_ERROR_NULL ("failed to allocate space for workspace", GSL_ENOMEM); } w->size = n; w->herm_workspace_p = gsl_eigen_herm_alloc(n); if (!w->herm_workspace_p) { gsl_eigen_genherm_free(w); GSL_ERROR_NULL("failed to allocate space for herm workspace", GSL_ENOMEM); } return (w); } /* gsl_eigen_genherm_alloc() */ /* gsl_eigen_genherm_free() Free workspace w */ void gsl_eigen_genherm_free (gsl_eigen_genherm_workspace * w) { if (w->herm_workspace_p) gsl_eigen_herm_free(w->herm_workspace_p); free(w); } /* gsl_eigen_genherm_free() */ /* gsl_eigen_genherm() Solve the generalized hermitian-definite eigenvalue problem A x = \lambda B x for the eigenvalues \lambda. Inputs: A - complex hermitian matrix B - complex hermitian and positive definite matrix eval - where to store eigenvalues w - workspace Return: success or error */ int gsl_eigen_genherm (gsl_matrix_complex * A, gsl_matrix_complex * B, gsl_vector * eval, gsl_eigen_genherm_workspace * w) { const size_t N = A->size1; /* check matrix and vector sizes */ if (N != A->size2) { GSL_ERROR ("matrix must be square to compute eigenvalues", GSL_ENOTSQR); } else if ((N != B->size1) || (N != B->size2)) { GSL_ERROR ("B matrix dimensions must match A", GSL_EBADLEN); } else if (eval->size != N) { GSL_ERROR ("eigenvalue vector must match matrix size", GSL_EBADLEN); } else if (w->size != N) { GSL_ERROR ("matrix size does not match workspace", GSL_EBADLEN); } else { int s; /* compute Cholesky factorization of B */ s = gsl_linalg_complex_cholesky_decomp(B); if (s != GSL_SUCCESS) return s; /* B is not positive definite */ /* transform to standard hermitian eigenvalue problem */ gsl_eigen_genherm_standardize(A, B); s = gsl_eigen_herm(A, eval, w->herm_workspace_p); return s; } } /* gsl_eigen_genherm() */ /* gsl_eigen_genherm_standardize() Reduce the generalized hermitian-definite eigenproblem to the standard hermitian eigenproblem by computing C = L^{-1} A L^{-H} where L L^H is the Cholesky decomposition of B Inputs: A - (input/output) complex hermitian matrix B - complex hermitian, positive definite matrix in Cholesky form Return: success Notes: A is overwritten by L^{-1} A L^{-H} */ int gsl_eigen_genherm_standardize(gsl_matrix_complex *A, const gsl_matrix_complex *B) { const size_t N = A->size1; size_t i; double a, b; gsl_complex y, z; GSL_SET_IMAG(&z, 0.0); for (i = 0; i < N; ++i) { /* update lower triangle of A(i:n, i:n) */ y = gsl_matrix_complex_get(A, i, i); a = GSL_REAL(y); y = gsl_matrix_complex_get(B, i, i); b = GSL_REAL(y); a /= b * b; GSL_SET_REAL(&z, a); gsl_matrix_complex_set(A, i, i, z); if (i < N - 1) { gsl_vector_complex_view ai = gsl_matrix_complex_subcolumn(A, i, i + 1, N - i - 1); gsl_matrix_complex_view ma = gsl_matrix_complex_submatrix(A, i + 1, i + 1, N - i - 1, N - i - 1); gsl_vector_complex_const_view bi = gsl_matrix_complex_const_subcolumn(B, i, i + 1, N - i - 1); gsl_matrix_complex_const_view mb = gsl_matrix_complex_const_submatrix(B, i + 1, i + 1, N - i - 1, N - i - 1); gsl_blas_zdscal(1.0 / b, &ai.vector); GSL_SET_REAL(&z, -0.5 * a); gsl_blas_zaxpy(z, &bi.vector, &ai.vector); gsl_blas_zher2(CblasLower, GSL_COMPLEX_NEGONE, &ai.vector, &bi.vector, &ma.matrix); gsl_blas_zaxpy(z, &bi.vector, &ai.vector); gsl_blas_ztrsv(CblasLower, CblasNoTrans, CblasNonUnit, &mb.matrix, &ai.vector); } } return GSL_SUCCESS; } /* gsl_eigen_genherm_standardize() */ praat-6.0.04/external/gsl/gsl_eigen__genhermv.c000066400000000000000000000124031261542461700214610ustar00rootroot00000000000000/* eigen/genhermv.c * * Copyright (C) 2007 Patrick Alken * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "gsl__config.h" #include "gsl_eigen.h" #include "gsl_linalg.h" #include "gsl_math.h" #include "gsl_blas.h" #include "gsl_vector.h" #include "gsl_matrix.h" #include "gsl_complex.h" #include "gsl_complex_math.h" /* * This module computes the eigenvalues and eigenvectors of a complex * generalized hermitian-definite eigensystem A x = \lambda B x, where * A and B are hermitian, and B is positive-definite. */ static void genhermv_normalize_eigenvectors(gsl_matrix_complex *evec); /* gsl_eigen_genhermv_alloc() Allocate a workspace for solving the generalized hermitian-definite eigenvalue problem. The size of this workspace is O(5n). Inputs: n - size of matrices Return: pointer to workspace */ gsl_eigen_genhermv_workspace * gsl_eigen_genhermv_alloc(const size_t n) { gsl_eigen_genhermv_workspace *w; if (n == 0) { GSL_ERROR_NULL ("matrix dimension must be positive integer", GSL_EINVAL); } w = calloc (1, sizeof (gsl_eigen_genhermv_workspace)); if (w == 0) { GSL_ERROR_NULL ("failed to allocate space for workspace", GSL_ENOMEM); } w->size = n; w->hermv_workspace_p = gsl_eigen_hermv_alloc(n); if (!w->hermv_workspace_p) { gsl_eigen_genhermv_free(w); GSL_ERROR_NULL("failed to allocate space for hermv workspace", GSL_ENOMEM); } return (w); } /* gsl_eigen_genhermv_alloc() */ /* gsl_eigen_genhermv_free() Free workspace w */ void gsl_eigen_genhermv_free (gsl_eigen_genhermv_workspace * w) { if (w->hermv_workspace_p) gsl_eigen_hermv_free(w->hermv_workspace_p); free(w); } /* gsl_eigen_genhermv_free() */ /* gsl_eigen_genhermv() Solve the generalized hermitian-definite eigenvalue problem A x = \lambda B x for the eigenvalues \lambda and eigenvectors x. Inputs: A - complex hermitian matrix B - complex hermitian and positive definite matrix eval - where to store eigenvalues evec - where to store eigenvectors w - workspace Return: success or error */ int gsl_eigen_genhermv (gsl_matrix_complex * A, gsl_matrix_complex * B, gsl_vector * eval, gsl_matrix_complex * evec, gsl_eigen_genhermv_workspace * w) { const size_t N = A->size1; /* check matrix and vector sizes */ if (N != A->size2) { GSL_ERROR ("matrix must be square to compute eigenvalues", GSL_ENOTSQR); } else if ((N != B->size1) || (N != B->size2)) { GSL_ERROR ("B matrix dimensions must match A", GSL_EBADLEN); } else if (eval->size != N) { GSL_ERROR ("eigenvalue vector must match matrix size", GSL_EBADLEN); } else if (evec->size1 != evec->size2) { GSL_ERROR ("eigenvector matrix must be square", GSL_ENOTSQR); } else if (evec->size1 != N) { GSL_ERROR ("eigenvector matrix has wrong size", GSL_EBADLEN); } else if (w->size != N) { GSL_ERROR ("matrix size does not match workspace", GSL_EBADLEN); } else { int s; /* compute Cholesky factorization of B */ s = gsl_linalg_complex_cholesky_decomp(B); if (s != GSL_SUCCESS) return s; /* B is not positive definite */ /* transform to standard hermitian eigenvalue problem */ gsl_eigen_genherm_standardize(A, B); /* compute eigenvalues and eigenvectors */ s = gsl_eigen_hermv(A, eval, evec, w->hermv_workspace_p); if (s != GSL_SUCCESS) return s; /* backtransform eigenvectors: evec -> L^{-H} evec */ gsl_blas_ztrsm(CblasLeft, CblasLower, CblasConjTrans, CblasNonUnit, GSL_COMPLEX_ONE, B, evec); /* the blas call destroyed the normalization - renormalize */ genhermv_normalize_eigenvectors(evec); return GSL_SUCCESS; } } /* gsl_eigen_genhermv() */ /******************************************** * INTERNAL ROUTINES * ********************************************/ /* genhermv_normalize_eigenvectors() Normalize eigenvectors so that their Euclidean norm is 1 Inputs: evec - eigenvectors */ static void genhermv_normalize_eigenvectors(gsl_matrix_complex *evec) { const size_t N = evec->size1; size_t i; /* looping */ for (i = 0; i < N; ++i) { gsl_vector_complex_view vi = gsl_matrix_complex_column(evec, i); double scale = 1.0 / gsl_blas_dznrm2(&vi.vector); gsl_blas_zdscal(scale, &vi.vector); } } /* genhermv_normalize_eigenvectors() */ praat-6.0.04/external/gsl/gsl_eigen__gensymm.c000066400000000000000000000123671261542461700213360ustar00rootroot00000000000000/* eigen/gensymm.c * * Copyright (C) 2007 Patrick Alken * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "gsl__config.h" #include "gsl_eigen.h" #include "gsl_linalg.h" #include "gsl_math.h" #include "gsl_blas.h" #include "gsl_vector.h" #include "gsl_matrix.h" /* * This module computes the eigenvalues of a real generalized * symmetric-definite eigensystem A x = \lambda B x, where A and * B are symmetric, and B is positive-definite. */ /* gsl_eigen_gensymm_alloc() Allocate a workspace for solving the generalized symmetric-definite eigenvalue problem. The size of this workspace is O(2n). Inputs: n - size of matrices Return: pointer to workspace */ gsl_eigen_gensymm_workspace * gsl_eigen_gensymm_alloc(const size_t n) { gsl_eigen_gensymm_workspace *w; if (n == 0) { GSL_ERROR_NULL ("matrix dimension must be positive integer", GSL_EINVAL); } w = calloc (1, sizeof (gsl_eigen_gensymm_workspace)); if (w == 0) { GSL_ERROR_NULL ("failed to allocate space for workspace", GSL_ENOMEM); } w->size = n; w->symm_workspace_p = gsl_eigen_symm_alloc(n); if (!w->symm_workspace_p) { gsl_eigen_gensymm_free(w); GSL_ERROR_NULL("failed to allocate space for symm workspace", GSL_ENOMEM); } return (w); } /* gsl_eigen_gensymm_alloc() */ /* gsl_eigen_gensymm_free() Free workspace w */ void gsl_eigen_gensymm_free (gsl_eigen_gensymm_workspace * w) { if (w->symm_workspace_p) gsl_eigen_symm_free(w->symm_workspace_p); free(w); } /* gsl_eigen_gensymm_free() */ /* gsl_eigen_gensymm() Solve the generalized symmetric-definite eigenvalue problem A x = \lambda B x for the eigenvalues \lambda. Inputs: A - real symmetric matrix B - real symmetric and positive definite matrix eval - where to store eigenvalues w - workspace Return: success or error */ int gsl_eigen_gensymm (gsl_matrix * A, gsl_matrix * B, gsl_vector * eval, gsl_eigen_gensymm_workspace * w) { const size_t N = A->size1; /* check matrix and vector sizes */ if (N != A->size2) { GSL_ERROR ("matrix must be square to compute eigenvalues", GSL_ENOTSQR); } else if ((N != B->size1) || (N != B->size2)) { GSL_ERROR ("B matrix dimensions must match A", GSL_EBADLEN); } else if (eval->size != N) { GSL_ERROR ("eigenvalue vector must match matrix size", GSL_EBADLEN); } else if (w->size != N) { GSL_ERROR ("matrix size does not match workspace", GSL_EBADLEN); } else { int s; /* compute Cholesky factorization of B */ s = gsl_linalg_cholesky_decomp(B); if (s != GSL_SUCCESS) return s; /* B is not positive definite */ /* transform to standard symmetric eigenvalue problem */ gsl_eigen_gensymm_standardize(A, B); s = gsl_eigen_symm(A, eval, w->symm_workspace_p); return s; } } /* gsl_eigen_gensymm() */ /* gsl_eigen_gensymm_standardize() Reduce the generalized symmetric-definite eigenproblem to the standard symmetric eigenproblem by computing C = L^{-1} A L^{-t} where L L^t is the Cholesky decomposition of B Inputs: A - (input/output) real symmetric matrix B - real symmetric, positive definite matrix in Cholesky form Return: success Notes: A is overwritten by L^{-1} A L^{-t} */ int gsl_eigen_gensymm_standardize(gsl_matrix *A, const gsl_matrix *B) { const size_t N = A->size1; size_t i; double a, b, c; for (i = 0; i < N; ++i) { /* update lower triangle of A(i:n, i:n) */ a = gsl_matrix_get(A, i, i); b = gsl_matrix_get(B, i, i); a /= b * b; gsl_matrix_set(A, i, i, a); if (i < N - 1) { gsl_vector_view ai = gsl_matrix_subcolumn(A, i, i + 1, N - i - 1); gsl_matrix_view ma = gsl_matrix_submatrix(A, i + 1, i + 1, N - i - 1, N - i - 1); gsl_vector_const_view bi = gsl_matrix_const_subcolumn(B, i, i + 1, N - i - 1); gsl_matrix_const_view mb = gsl_matrix_const_submatrix(B, i + 1, i + 1, N - i - 1, N - i - 1); gsl_blas_dscal(1.0 / b, &ai.vector); c = -0.5 * a; gsl_blas_daxpy(c, &bi.vector, &ai.vector); gsl_blas_dsyr2(CblasLower, -1.0, &ai.vector, &bi.vector, &ma.matrix); gsl_blas_daxpy(c, &bi.vector, &ai.vector); gsl_blas_dtrsv(CblasLower, CblasNoTrans, CblasNonUnit, &mb.matrix, &ai.vector); } } return GSL_SUCCESS; } /* gsl_eigen_gensymm_standardize() */ praat-6.0.04/external/gsl/gsl_eigen__gensymmv.c000066400000000000000000000121351261542461700215150ustar00rootroot00000000000000/* eigen/gensymmv.c * * Copyright (C) 2007 Patrick Alken * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "gsl__config.h" #include "gsl_eigen.h" #include "gsl_linalg.h" #include "gsl_math.h" #include "gsl_blas.h" #include "gsl_vector.h" #include "gsl_matrix.h" /* * This module computes the eigenvalues and eigenvectors of a real * generalized symmetric-definite eigensystem A x = \lambda B x, where * A and B are symmetric, and B is positive-definite. */ static void gensymmv_normalize_eigenvectors(gsl_matrix *evec); /* gsl_eigen_gensymmv_alloc() Allocate a workspace for solving the generalized symmetric-definite eigenvalue problem. The size of this workspace is O(4n). Inputs: n - size of matrices Return: pointer to workspace */ gsl_eigen_gensymmv_workspace * gsl_eigen_gensymmv_alloc(const size_t n) { gsl_eigen_gensymmv_workspace *w; if (n == 0) { GSL_ERROR_NULL ("matrix dimension must be positive integer", GSL_EINVAL); } w = calloc (1, sizeof (gsl_eigen_gensymmv_workspace)); if (w == 0) { GSL_ERROR_NULL ("failed to allocate space for workspace", GSL_ENOMEM); } w->size = n; w->symmv_workspace_p = gsl_eigen_symmv_alloc(n); if (!w->symmv_workspace_p) { gsl_eigen_gensymmv_free(w); GSL_ERROR_NULL("failed to allocate space for symmv workspace", GSL_ENOMEM); } return (w); } /* gsl_eigen_gensymmv_alloc() */ /* gsl_eigen_gensymmv_free() Free workspace w */ void gsl_eigen_gensymmv_free (gsl_eigen_gensymmv_workspace * w) { if (w->symmv_workspace_p) gsl_eigen_symmv_free(w->symmv_workspace_p); free(w); } /* gsl_eigen_gensymmv_free() */ /* gsl_eigen_gensymmv() Solve the generalized symmetric-definite eigenvalue problem A x = \lambda B x for the eigenvalues \lambda and eigenvectors x. Inputs: A - real symmetric matrix B - real symmetric and positive definite matrix eval - where to store eigenvalues evec - where to store eigenvectors w - workspace Return: success or error */ int gsl_eigen_gensymmv (gsl_matrix * A, gsl_matrix * B, gsl_vector * eval, gsl_matrix * evec, gsl_eigen_gensymmv_workspace * w) { const size_t N = A->size1; /* check matrix and vector sizes */ if (N != A->size2) { GSL_ERROR ("matrix must be square to compute eigenvalues", GSL_ENOTSQR); } else if ((N != B->size1) || (N != B->size2)) { GSL_ERROR ("B matrix dimensions must match A", GSL_EBADLEN); } else if (eval->size != N) { GSL_ERROR ("eigenvalue vector must match matrix size", GSL_EBADLEN); } else if (evec->size1 != evec->size2) { GSL_ERROR ("eigenvector matrix must be square", GSL_ENOTSQR); } else if (evec->size1 != N) { GSL_ERROR ("eigenvector matrix has wrong size", GSL_EBADLEN); } else if (w->size != N) { GSL_ERROR ("matrix size does not match workspace", GSL_EBADLEN); } else { int s; /* compute Cholesky factorization of B */ s = gsl_linalg_cholesky_decomp(B); if (s != GSL_SUCCESS) return s; /* B is not positive definite */ /* transform to standard symmetric eigenvalue problem */ gsl_eigen_gensymm_standardize(A, B); /* compute eigenvalues and eigenvectors */ s = gsl_eigen_symmv(A, eval, evec, w->symmv_workspace_p); if (s != GSL_SUCCESS) return s; /* backtransform eigenvectors: evec -> L^{-T} evec */ gsl_blas_dtrsm(CblasLeft, CblasLower, CblasTrans, CblasNonUnit, 1.0, B, evec); /* the blas call destroyed the normalization - renormalize */ gensymmv_normalize_eigenvectors(evec); return GSL_SUCCESS; } } /* gsl_eigen_gensymmv() */ /******************************************** * INTERNAL ROUTINES * ********************************************/ /* gensymmv_normalize_eigenvectors() Normalize eigenvectors so that their Euclidean norm is 1 Inputs: evec - eigenvectors */ static void gensymmv_normalize_eigenvectors(gsl_matrix *evec) { const size_t N = evec->size1; size_t i; /* looping */ for (i = 0; i < N; ++i) { gsl_vector_view vi = gsl_matrix_column(evec, i); double scale = 1.0 / gsl_blas_dnrm2(&vi.vector); gsl_blas_dscal(scale, &vi.vector); } } /* gensymmv_normalize_eigenvectors() */ praat-6.0.04/external/gsl/gsl_eigen__genv.c000066400000000000000000000700201261542461700206040ustar00rootroot00000000000000/* eigen/genv.c * * Copyright (C) 2007 Patrick Alken * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "gsl__config.h" #include "gsl_eigen.h" #include "gsl_linalg.h" #include "gsl_math.h" #include "gsl_blas.h" #include "gsl_vector.h" #include "gsl_vector_complex.h" #include "gsl_matrix.h" #include "gsl_errno.h" /* * This module computes the eigenvalues and eigenvectors of a * real generalized eigensystem A x = \lambda B x. Left and right * Schur vectors are optionally computed as well. * * This file contains routines based on original code from LAPACK * which is distributed under the modified BSD license. */ static int genv_get_right_eigenvectors(const gsl_matrix *S, const gsl_matrix *T, gsl_matrix *Z, gsl_matrix_complex *evec, gsl_eigen_genv_workspace *w); static void genv_normalize_eigenvectors(gsl_vector_complex *alpha, gsl_matrix_complex *evec); /* gsl_eigen_genv_alloc() Allocate a workspace for solving the generalized eigenvalue problem. The size of this workspace is O(7n). Inputs: n - size of matrices Return: pointer to workspace */ gsl_eigen_genv_workspace * gsl_eigen_genv_alloc(const size_t n) { gsl_eigen_genv_workspace *w; if (n == 0) { GSL_ERROR_NULL ("matrix dimension must be positive integer", GSL_EINVAL); } w = calloc (1, sizeof (gsl_eigen_genv_workspace)); if (w == 0) { GSL_ERROR_NULL ("failed to allocate space for workspace", GSL_ENOMEM); } w->size = n; w->Q = NULL; w->Z = NULL; w->gen_workspace_p = gsl_eigen_gen_alloc(n); if (w->gen_workspace_p == 0) { gsl_eigen_genv_free(w); GSL_ERROR_NULL ("failed to allocate space for gen workspace", GSL_ENOMEM); } /* compute the full Schur forms */ gsl_eigen_gen_params(1, 1, 1, w->gen_workspace_p); w->work1 = gsl_vector_alloc(n); w->work2 = gsl_vector_alloc(n); w->work3 = gsl_vector_alloc(n); w->work4 = gsl_vector_alloc(n); w->work5 = gsl_vector_alloc(n); w->work6 = gsl_vector_alloc(n); if (w->work1 == 0 || w->work2 == 0 || w->work3 == 0 || w->work4 == 0 || w->work5 == 0 || w->work6 == 0) { gsl_eigen_genv_free(w); GSL_ERROR_NULL ("failed to allocate space for additional workspace", GSL_ENOMEM); } return (w); } /* gsl_eigen_genv_alloc() */ /* gsl_eigen_genv_free() Free workspace w */ void gsl_eigen_genv_free(gsl_eigen_genv_workspace *w) { if (w->gen_workspace_p) gsl_eigen_gen_free(w->gen_workspace_p); if (w->work1) gsl_vector_free(w->work1); if (w->work2) gsl_vector_free(w->work2); if (w->work3) gsl_vector_free(w->work3); if (w->work4) gsl_vector_free(w->work4); if (w->work5) gsl_vector_free(w->work5); if (w->work6) gsl_vector_free(w->work6); free(w); } /* gsl_eigen_genv_free() */ /* gsl_eigen_genv() Solve the generalized eigenvalue problem A x = \lambda B x for the eigenvalues \lambda and right eigenvectors x. Inputs: A - general real matrix B - general real matrix alpha - (output) where to store eigenvalue numerators beta - (output) where to store eigenvalue denominators evec - (output) where to store eigenvectors w - workspace Return: success or error */ int gsl_eigen_genv (gsl_matrix * A, gsl_matrix * B, gsl_vector_complex * alpha, gsl_vector * beta, gsl_matrix_complex *evec, gsl_eigen_genv_workspace * w) { const size_t N = A->size1; /* check matrix and vector sizes */ if (N != A->size2) { GSL_ERROR ("matrix must be square to compute eigenvalues", GSL_ENOTSQR); } else if ((N != B->size1) || (N != B->size2)) { GSL_ERROR ("B matrix dimensions must match A", GSL_EBADLEN); } else if (alpha->size != N || beta->size != N) { GSL_ERROR ("eigenvalue vector must match matrix size", GSL_EBADLEN); } else if (w->size != N) { GSL_ERROR ("matrix size does not match workspace", GSL_EBADLEN); } else if (evec->size1 != N) { GSL_ERROR ("eigenvector matrix has wrong size", GSL_EBADLEN); } else { int s; gsl_matrix Z; /* * We need a place to store the right Schur vectors, so we will * treat evec as a real matrix and store them in the left * half - the factor of 2 in the tda corresponds to the * complex multiplicity */ Z.size1 = N; Z.size2 = N; Z.tda = 2 * N; Z.data = evec->data; Z.block = 0; Z.owner = 0; s = gsl_eigen_gen_QZ(A, B, alpha, beta, w->Q, &Z, w->gen_workspace_p); if (w->Z) { /* save right Schur vectors */ gsl_matrix_memcpy(w->Z, &Z); } /* only compute eigenvectors if we found all eigenvalues */ if (s == GSL_SUCCESS) { /* compute eigenvectors */ s = genv_get_right_eigenvectors(A, B, &Z, evec, w); if (s == GSL_SUCCESS) genv_normalize_eigenvectors(alpha, evec); } return s; } } /* gsl_eigen_genv() */ /* gsl_eigen_genv_QZ() Solve the generalized eigenvalue problem A x = \lambda B x for the eigenvalues \lambda and right eigenvectors x. Optionally compute left and/or right Schur vectors Q and Z which satisfy: A = Q S Z^t B = Q T Z^t where (S, T) is the generalized Schur form of (A, B) Inputs: A - general real matrix B - general real matrix alpha - (output) where to store eigenvalue numerators beta - (output) where to store eigenvalue denominators evec - (output) where to store eigenvectors Q - (output) if non-null, where to store left Schur vectors Z - (output) if non-null, where to store right Schur vectors w - workspace Return: success or error */ int gsl_eigen_genv_QZ (gsl_matrix * A, gsl_matrix * B, gsl_vector_complex * alpha, gsl_vector * beta, gsl_matrix_complex * evec, gsl_matrix * Q, gsl_matrix * Z, gsl_eigen_genv_workspace * w) { if (Q && (A->size1 != Q->size1 || A->size1 != Q->size2)) { GSL_ERROR("Q matrix has wrong dimensions", GSL_EBADLEN); } else if (Z && (A->size1 != Z->size1 || A->size1 != Z->size2)) { GSL_ERROR("Z matrix has wrong dimensions", GSL_EBADLEN); } else { int s; w->Q = Q; w->Z = Z; s = gsl_eigen_genv(A, B, alpha, beta, evec, w); w->Q = NULL; w->Z = NULL; return s; } } /* gsl_eigen_genv_QZ() */ /******************************************** * INTERNAL ROUTINES * ********************************************/ /* genv_get_right_eigenvectors() Compute right eigenvectors of the Schur form (S, T) and then backtransform them using the right Schur vectors to get right eigenvectors of the original system. Inputs: S - upper quasi-triangular Schur form of A T - upper triangular Schur form of B Z - right Schur vectors evec - (output) where to store eigenvectors w - workspace Return: success or error Notes: 1) based on LAPACK routine DTGEVC 2) eigenvectors are stored in the order that their eigenvalues appear in the Schur form */ static int genv_get_right_eigenvectors(const gsl_matrix *S, const gsl_matrix *T, gsl_matrix *Z, gsl_matrix_complex *evec, gsl_eigen_genv_workspace *w) { const size_t N = w->size; const double small = GSL_DBL_MIN * N / GSL_DBL_EPSILON; const double big = 1.0 / small; const double bignum = 1.0 / (GSL_DBL_MIN * N); size_t i, j, k, end; int is; double anorm, bnorm; double temp, temp2, temp2r, temp2i; double ascale, bscale; double salfar, sbeta; double acoef, bcoefr, bcoefi, acoefa, bcoefa; double creala, cimaga, crealb, cimagb, cre2a, cim2a, cre2b, cim2b; double dmin, xmax; double scale; size_t nw, na; int lsa, lsb; int complex_pair; gsl_complex z_zero, z_one; double bdiag[2] = { 0.0, 0.0 }; double sum[4]; int il2by2; size_t jr, jc, ja; double xscale; gsl_vector_complex_view ecol; gsl_vector_view re, im, re2, im2; GSL_SET_COMPLEX(&z_zero, 0.0, 0.0); GSL_SET_COMPLEX(&z_one, 1.0, 0.0); /* * Compute the 1-norm of each column of (S, T) excluding elements * belonging to the diagonal blocks to check for possible overflow * in the triangular solver */ anorm = fabs(gsl_matrix_get(S, 0, 0)); if (N > 1) anorm += fabs(gsl_matrix_get(S, 1, 0)); bnorm = fabs(gsl_matrix_get(T, 0, 0)); gsl_vector_set(w->work1, 0, 0.0); gsl_vector_set(w->work2, 0, 0.0); for (j = 1; j < N; ++j) { temp = temp2 = 0.0; if (gsl_matrix_get(S, j, j - 1) == 0.0) end = j; else end = j - 1; for (i = 0; i < end; ++i) { temp += fabs(gsl_matrix_get(S, i, j)); temp2 += fabs(gsl_matrix_get(T, i, j)); } gsl_vector_set(w->work1, j, temp); gsl_vector_set(w->work2, j, temp2); for (i = end; i < GSL_MIN(j + 2, N); ++i) { temp += fabs(gsl_matrix_get(S, i, j)); temp2 += fabs(gsl_matrix_get(T, i, j)); } anorm = GSL_MAX(anorm, temp); bnorm = GSL_MAX(bnorm, temp2); } ascale = 1.0 / GSL_MAX(anorm, GSL_DBL_MIN); bscale = 1.0 / GSL_MAX(bnorm, GSL_DBL_MIN); complex_pair = 0; for (k = 0; k < N; ++k) { size_t je = N - 1 - k; if (complex_pair) { complex_pair = 0; continue; } nw = 1; if (je > 0) { if (gsl_matrix_get(S, je, je - 1) != 0.0) { complex_pair = 1; nw = 2; } } if (!complex_pair) { if (fabs(gsl_matrix_get(S, je, je)) <= GSL_DBL_MIN && fabs(gsl_matrix_get(T, je, je)) <= GSL_DBL_MIN) { /* singular matrix pencil - unit eigenvector */ for (i = 0; i < N; ++i) gsl_matrix_complex_set(evec, i, je, z_zero); gsl_matrix_complex_set(evec, je, je, z_one); continue; } /* clear vector */ for (i = 0; i < N; ++i) gsl_vector_set(w->work3, i, 0.0); } else { /* clear vectors */ for (i = 0; i < N; ++i) { gsl_vector_set(w->work3, i, 0.0); gsl_vector_set(w->work4, i, 0.0); } } if (!complex_pair) { /* real eigenvalue */ temp = 1.0 / GSL_MAX(GSL_DBL_MIN, GSL_MAX(fabs(gsl_matrix_get(S, je, je)) * ascale, fabs(gsl_matrix_get(T, je, je)) * bscale)); salfar = (temp * gsl_matrix_get(S, je, je)) * ascale; sbeta = (temp * gsl_matrix_get(T, je, je)) * bscale; acoef = sbeta * ascale; bcoefr = salfar * bscale; bcoefi = 0.0; /* scale to avoid underflow */ scale = 1.0; lsa = fabs(sbeta) >= GSL_DBL_MIN && fabs(acoef) < small; lsb = fabs(salfar) >= GSL_DBL_MIN && fabs(bcoefr) < small; if (lsa) scale = (small / fabs(sbeta)) * GSL_MIN(anorm, big); if (lsb) scale = GSL_MAX(scale, (small / fabs(salfar)) * GSL_MIN(bnorm, big)); if (lsa || lsb) { scale = GSL_MIN(scale, 1.0 / (GSL_DBL_MIN * GSL_MAX(1.0, GSL_MAX(fabs(acoef), fabs(bcoefr))))); if (lsa) acoef = ascale * (scale * sbeta); else acoef *= scale; if (lsb) bcoefr = bscale * (scale * salfar); else bcoefr *= scale; } acoefa = fabs(acoef); bcoefa = fabs(bcoefr); /* first component is 1 */ gsl_vector_set(w->work3, je, 1.0); xmax = 1.0; /* compute contribution from column je of A and B to sum */ for (i = 0; i < je; ++i) { gsl_vector_set(w->work3, i, bcoefr*gsl_matrix_get(T, i, je) - acoef * gsl_matrix_get(S, i, je)); } } else { gsl_matrix_const_view vs = gsl_matrix_const_submatrix(S, je - 1, je - 1, 2, 2); gsl_matrix_const_view vt = gsl_matrix_const_submatrix(T, je - 1, je - 1, 2, 2); /* complex eigenvalue */ gsl_schur_gen_eigvals(&vs.matrix, &vt.matrix, &bcoefr, &temp2, &bcoefi, &acoef, &temp); if (bcoefi == 0.0) { GSL_ERROR("gsl_schur_gen_eigvals failed on complex block", GSL_FAILURE); } /* scale to avoid over/underflow */ acoefa = fabs(acoef); bcoefa = fabs(bcoefr) + fabs(bcoefi); scale = 1.0; if (acoefa*GSL_DBL_EPSILON < GSL_DBL_MIN && acoefa >= GSL_DBL_MIN) scale = (GSL_DBL_MIN / GSL_DBL_EPSILON) / acoefa; if (bcoefa*GSL_DBL_EPSILON < GSL_DBL_MIN && bcoefa >= GSL_DBL_MIN) scale = GSL_MAX(scale, (GSL_DBL_MIN/GSL_DBL_EPSILON) / bcoefa); if (GSL_DBL_MIN*acoefa > ascale) scale = ascale / (GSL_DBL_MIN * acoefa); if (GSL_DBL_MIN*bcoefa > bscale) scale = GSL_MIN(scale, bscale / (GSL_DBL_MIN*bcoefa)); if (scale != 1.0) { acoef *= scale; acoefa = fabs(acoef); bcoefr *= scale; bcoefi *= scale; bcoefa = fabs(bcoefr) + fabs(bcoefi); } /* compute first two components of eigenvector */ temp = acoef * gsl_matrix_get(S, je, je - 1); temp2r = acoef * gsl_matrix_get(S, je, je) - bcoefr * gsl_matrix_get(T, je, je); temp2i = -bcoefi * gsl_matrix_get(T, je, je); if (fabs(temp) >= fabs(temp2r) + fabs(temp2i)) { gsl_vector_set(w->work3, je, 1.0); gsl_vector_set(w->work4, je, 0.0); gsl_vector_set(w->work3, je - 1, -temp2r / temp); gsl_vector_set(w->work4, je - 1, -temp2i / temp); } else { gsl_vector_set(w->work3, je - 1, 1.0); gsl_vector_set(w->work4, je - 1, 0.0); temp = acoef * gsl_matrix_get(S, je - 1, je); gsl_vector_set(w->work3, je, (bcoefr*gsl_matrix_get(T, je - 1, je - 1) - acoef*gsl_matrix_get(S, je - 1, je - 1)) / temp); gsl_vector_set(w->work4, je, bcoefi*gsl_matrix_get(T, je - 1, je - 1) / temp); } xmax = GSL_MAX(fabs(gsl_vector_get(w->work3, je)) + fabs(gsl_vector_get(w->work4, je)), fabs(gsl_vector_get(w->work3, je - 1)) + fabs(gsl_vector_get(w->work4, je - 1))); /* compute contribution from column je and je - 1 */ creala = acoef * gsl_vector_get(w->work3, je - 1); cimaga = acoef * gsl_vector_get(w->work4, je - 1); crealb = bcoefr * gsl_vector_get(w->work3, je - 1) - bcoefi * gsl_vector_get(w->work4, je - 1); cimagb = bcoefi * gsl_vector_get(w->work3, je - 1) + bcoefr * gsl_vector_get(w->work4, je - 1); cre2a = acoef * gsl_vector_get(w->work3, je); cim2a = acoef * gsl_vector_get(w->work4, je); cre2b = bcoefr * gsl_vector_get(w->work3, je) - bcoefi * gsl_vector_get(w->work4, je); cim2b = bcoefi * gsl_vector_get(w->work3, je) + bcoefr * gsl_vector_get(w->work4, je); for (i = 0; i < je - 1; ++i) { gsl_vector_set(w->work3, i, -creala * gsl_matrix_get(S, i, je - 1) + crealb * gsl_matrix_get(T, i, je - 1) - cre2a * gsl_matrix_get(S, i, je) + cre2b * gsl_matrix_get(T, i, je)); gsl_vector_set(w->work4, i, -cimaga * gsl_matrix_get(S, i, je - 1) + cimagb * gsl_matrix_get(T, i, je - 1) - cim2a * gsl_matrix_get(S, i, je) + cim2b * gsl_matrix_get(T, i, je)); } } dmin = GSL_MAX(GSL_DBL_MIN, GSL_MAX(GSL_DBL_EPSILON*acoefa*anorm, GSL_DBL_EPSILON*bcoefa*bnorm)); /* triangular solve of (a A - b B) x = 0 */ il2by2 = 0; for (is = (int) je - (int) nw; is >= 0; --is) { j = (size_t) is; if (!il2by2 && j > 0) { if (gsl_matrix_get(S, j, j - 1) != 0.0) { il2by2 = 1; continue; } } bdiag[0] = gsl_matrix_get(T, j, j); if (il2by2) { na = 2; bdiag[1] = gsl_matrix_get(T, j + 1, j + 1); } else na = 1; if (nw == 1) { gsl_matrix_const_view sv = gsl_matrix_const_submatrix(S, j, j, na, na); gsl_vector_view xv, bv; bv = gsl_vector_subvector(w->work3, j, na); /* * the loop below expects the solution in the first column * of sum, so set stride to 2 */ xv = gsl_vector_view_array_with_stride(sum, 2, na); gsl_schur_solve_equation(acoef, &sv.matrix, bcoefr, bdiag[0], bdiag[1], &bv.vector, &xv.vector, &scale, &temp, dmin); } else { double bdat[4]; gsl_matrix_const_view sv = gsl_matrix_const_submatrix(S, j, j, na, na); gsl_vector_complex_view xv = gsl_vector_complex_view_array(sum, na); gsl_vector_complex_view bv = gsl_vector_complex_view_array(bdat, na); gsl_complex z; bdat[0] = gsl_vector_get(w->work3, j); bdat[1] = gsl_vector_get(w->work4, j); if (na == 2) { bdat[2] = gsl_vector_get(w->work3, j + 1); bdat[3] = gsl_vector_get(w->work4, j + 1); } GSL_SET_COMPLEX(&z, bcoefr, bcoefi); gsl_schur_solve_equation_z(acoef, &sv.matrix, &z, bdiag[0], bdiag[1], &bv.vector, &xv.vector, &scale, &temp, dmin); } if (scale < 1.0) { for (jr = 0; jr <= je; ++jr) { gsl_vector_set(w->work3, jr, scale * gsl_vector_get(w->work3, jr)); if (nw == 2) { gsl_vector_set(w->work4, jr, scale * gsl_vector_get(w->work4, jr)); } } } xmax = GSL_MAX(scale * xmax, temp); for (jr = 0; jr < na; ++jr) { gsl_vector_set(w->work3, j + jr, sum[jr*na]); if (nw == 2) gsl_vector_set(w->work4, j + jr, sum[jr*na + 1]); } if (j > 0) { xscale = 1.0 / GSL_MAX(1.0, xmax); temp = acoefa * gsl_vector_get(w->work1, j) + bcoefa * gsl_vector_get(w->work2, j); if (il2by2) { temp = GSL_MAX(temp, acoefa * gsl_vector_get(w->work1, j + 1) + bcoefa * gsl_vector_get(w->work2, j + 1)); } temp = GSL_MAX(temp, GSL_MAX(acoefa, bcoefa)); if (temp > bignum * xscale) { for (jr = 0; jr <= je; ++jr) { gsl_vector_set(w->work3, jr, xscale * gsl_vector_get(w->work3, jr)); if (nw == 2) { gsl_vector_set(w->work4, jr, xscale * gsl_vector_get(w->work4, jr)); } } xmax *= xscale; } for (ja = 0; ja < na; ++ja) { if (complex_pair) { creala = acoef * gsl_vector_get(w->work3, j + ja); cimaga = acoef * gsl_vector_get(w->work4, j + ja); crealb = bcoefr * gsl_vector_get(w->work3, j + ja) - bcoefi * gsl_vector_get(w->work4, j + ja); cimagb = bcoefi * gsl_vector_get(w->work3, j + ja) + bcoefr * gsl_vector_get(w->work4, j + ja); for (jr = 0; jr <= j - 1; ++jr) { gsl_vector_set(w->work3, jr, gsl_vector_get(w->work3, jr) - creala * gsl_matrix_get(S, jr, j + ja) + crealb * gsl_matrix_get(T, jr, j + ja)); gsl_vector_set(w->work4, jr, gsl_vector_get(w->work4, jr) - cimaga * gsl_matrix_get(S, jr, j + ja) + cimagb * gsl_matrix_get(T, jr, j + ja)); } } else { creala = acoef * gsl_vector_get(w->work3, j + ja); crealb = bcoefr * gsl_vector_get(w->work3, j + ja); for (jr = 0; jr <= j - 1; ++jr) { gsl_vector_set(w->work3, jr, gsl_vector_get(w->work3, jr) - creala * gsl_matrix_get(S, jr, j + ja) + crealb * gsl_matrix_get(T, jr, j + ja)); } } /* if (!complex_pair) */ } /* for (ja = 0; ja < na; ++ja) */ } /* if (j > 0) */ il2by2 = 0; } /* for (i = 0; i < je - nw; ++i) */ for (jr = 0; jr < N; ++jr) { gsl_vector_set(w->work5, jr, gsl_vector_get(w->work3, 0) * gsl_matrix_get(Z, jr, 0)); if (nw == 2) { gsl_vector_set(w->work6, jr, gsl_vector_get(w->work4, 0) * gsl_matrix_get(Z, jr, 0)); } } for (jc = 1; jc <= je; ++jc) { for (jr = 0; jr < N; ++jr) { gsl_vector_set(w->work5, jr, gsl_vector_get(w->work5, jr) + gsl_vector_get(w->work3, jc) * gsl_matrix_get(Z, jr, jc)); if (nw == 2) { gsl_vector_set(w->work6, jr, gsl_vector_get(w->work6, jr) + gsl_vector_get(w->work4, jc) * gsl_matrix_get(Z, jr, jc)); } } } /* store the eigenvector */ if (complex_pair) { ecol = gsl_matrix_complex_column(evec, je - 1); re = gsl_vector_complex_real(&ecol.vector); im = gsl_vector_complex_imag(&ecol.vector); ecol = gsl_matrix_complex_column(evec, je); re2 = gsl_vector_complex_real(&ecol.vector); im2 = gsl_vector_complex_imag(&ecol.vector); } else { ecol = gsl_matrix_complex_column(evec, je); re = gsl_vector_complex_real(&ecol.vector); im = gsl_vector_complex_imag(&ecol.vector); } for (jr = 0; jr < N; ++jr) { gsl_vector_set(&re.vector, jr, gsl_vector_get(w->work5, jr)); if (complex_pair) { gsl_vector_set(&im.vector, jr, gsl_vector_get(w->work6, jr)); gsl_vector_set(&re2.vector, jr, gsl_vector_get(w->work5, jr)); gsl_vector_set(&im2.vector, jr, -gsl_vector_get(w->work6, jr)); } else { gsl_vector_set(&im.vector, jr, 0.0); } } /* scale eigenvector */ xmax = 0.0; if (complex_pair) { for (j = 0; j < N; ++j) { xmax = GSL_MAX(xmax, fabs(gsl_vector_get(&re.vector, j)) + fabs(gsl_vector_get(&im.vector, j))); } } else { for (j = 0; j < N; ++j) { xmax = GSL_MAX(xmax, fabs(gsl_vector_get(&re.vector, j))); } } if (xmax > GSL_DBL_MIN) { xscale = 1.0 / xmax; for (j = 0; j < N; ++j) { gsl_vector_set(&re.vector, j, gsl_vector_get(&re.vector, j) * xscale); if (complex_pair) { gsl_vector_set(&im.vector, j, gsl_vector_get(&im.vector, j) * xscale); gsl_vector_set(&re2.vector, j, gsl_vector_get(&re2.vector, j) * xscale); gsl_vector_set(&im2.vector, j, gsl_vector_get(&im2.vector, j) * xscale); } } } } /* for (k = 0; k < N; ++k) */ return GSL_SUCCESS; } /* genv_get_right_eigenvectors() */ /* genv_normalize_eigenvectors() Normalize eigenvectors so that their Euclidean norm is 1 Inputs: alpha - eigenvalue numerators evec - eigenvectors */ static void genv_normalize_eigenvectors(gsl_vector_complex *alpha, gsl_matrix_complex *evec) { const size_t N = evec->size1; size_t i; /* looping */ gsl_complex ai; gsl_vector_complex_view vi; gsl_vector_view re, im; double scale; /* scaling factor */ for (i = 0; i < N; ++i) { ai = gsl_vector_complex_get(alpha, i); vi = gsl_matrix_complex_column(evec, i); re = gsl_vector_complex_real(&vi.vector); if (GSL_IMAG(ai) == 0.0) { scale = 1.0 / gsl_blas_dnrm2(&re.vector); gsl_blas_dscal(scale, &re.vector); } else if (GSL_IMAG(ai) > 0.0) { im = gsl_vector_complex_imag(&vi.vector); scale = 1.0 / gsl_hypot(gsl_blas_dnrm2(&re.vector), gsl_blas_dnrm2(&im.vector)); gsl_blas_zdscal(scale, &vi.vector); vi = gsl_matrix_complex_column(evec, i + 1); gsl_blas_zdscal(scale, &vi.vector); } } } /* genv_normalize_eigenvectors() */ praat-6.0.04/external/gsl/gsl_eigen__herm.c000066400000000000000000000112061261542461700206010ustar00rootroot00000000000000/* eigen/herm.c * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_vector.h" #include "gsl_matrix.h" #include "gsl_linalg.h" #include "gsl_eigen.h" /* Compute eigenvalues of complex hermitian matrix using reduction to real symmetric tridiagonal form, followed by QR iteration with implicit shifts. See Golub & Van Loan, "Matrix Computations" (3rd ed), Section 8.3 */ #include "gsl_eigen__qrstep.c" gsl_eigen_herm_workspace * gsl_eigen_herm_alloc (const size_t n) { gsl_eigen_herm_workspace * w ; if (n == 0) { GSL_ERROR_NULL ("matrix dimension must be positive integer", GSL_EINVAL); } w = (gsl_eigen_herm_workspace *) malloc (sizeof(gsl_eigen_herm_workspace)); if (w == 0) { GSL_ERROR_NULL ("failed to allocate space for workspace", GSL_ENOMEM); } w->d = (double *) malloc (n * sizeof (double)); if (w->d == 0) { GSL_ERROR_NULL ("failed to allocate space for diagonal", GSL_ENOMEM); } w->sd = (double *) malloc (n * sizeof (double)); if (w->sd == 0) { GSL_ERROR_NULL ("failed to allocate space for subdiagonal", GSL_ENOMEM); } w->tau = (double *) malloc (2 * n * sizeof (double)); if (w->tau == 0) { GSL_ERROR_NULL ("failed to allocate space for tau", GSL_ENOMEM); } w->size = n; return w; } void gsl_eigen_herm_free (gsl_eigen_herm_workspace * w) { free (w->tau); free (w->sd); free (w->d); free(w); } int gsl_eigen_herm (gsl_matrix_complex * A, gsl_vector * eval, gsl_eigen_herm_workspace * w) { if (A->size1 != A->size2) { GSL_ERROR ("matrix must be square to compute eigenvalues", GSL_ENOTSQR); } else if (eval->size != A->size1) { GSL_ERROR ("eigenvalue vector must match matrix size", GSL_EBADLEN); } else { const size_t N = A->size1; double *const d = w->d; double *const sd = w->sd; size_t a, b; /* handle special case */ if (N == 1) { gsl_complex A00 = gsl_matrix_complex_get (A, 0, 0); gsl_vector_set (eval, 0, GSL_REAL(A00)); return GSL_SUCCESS; } { gsl_vector_view d_vec = gsl_vector_view_array (d, N); gsl_vector_view sd_vec = gsl_vector_view_array (sd, N - 1); gsl_vector_complex_view tau_vec = gsl_vector_complex_view_array (w->tau, N-1); gsl_linalg_hermtd_decomp (A, &tau_vec.vector); gsl_linalg_hermtd_unpack_T (A, &d_vec.vector, &sd_vec.vector); } /* Make an initial pass through the tridiagonal decomposition to remove off-diagonal elements which are effectively zero */ chop_small_elements (N, d, sd); /* Progressively reduce the matrix until it is diagonal */ b = N - 1; while (b > 0) { if (sd[b - 1] == 0.0 || isnan(sd[b - 1])) { b--; continue; } /* Find the largest unreduced block (a,b) starting from b and working backwards */ a = b - 1; while (a > 0) { if (sd[a - 1] == 0.0) { break; } a--; } { const size_t n_block = b - a + 1; double *d_block = d + a; double *sd_block = sd + a; /* apply QR reduction with implicit deflation to the unreduced block */ qrstep (n_block, d_block, sd_block, NULL, NULL); /* remove any small off-diagonal elements */ chop_small_elements (n_block, d_block, sd_block); } } { gsl_vector_view d_vec = gsl_vector_view_array (d, N); gsl_vector_memcpy (eval, &d_vec.vector); } return GSL_SUCCESS; } } praat-6.0.04/external/gsl/gsl_eigen__hermv.c000066400000000000000000000156541261542461700210020ustar00rootroot00000000000000/* eigen/hermv.c * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_vector.h" #include "gsl_matrix.h" #include "gsl_complex_math.h" #include "gsl_linalg.h" #include "gsl_eigen.h" /* Compute eigenvalues/eigenvectors of complex hermitian matrix using reduction to real symmetric tridiagonal form, followed by QR iteration with implicit shifts. See Golub & Van Loan, "Matrix Computations" (3rd ed), Section 8.3 */ #include "gsl_eigen__qrstep.c" gsl_eigen_hermv_workspace * gsl_eigen_hermv_alloc (const size_t n) { gsl_eigen_hermv_workspace * w ; if (n == 0) { GSL_ERROR_NULL ("matrix dimension must be positive integer", GSL_EINVAL); } w = (gsl_eigen_hermv_workspace *) malloc (sizeof(gsl_eigen_hermv_workspace)); if (w == 0) { GSL_ERROR_NULL ("failed to allocate space for workspace", GSL_ENOMEM); } w->d = (double *) malloc (n * sizeof (double)); if (w->d == 0) { free (w); GSL_ERROR_NULL ("failed to allocate space for diagonal", GSL_ENOMEM); } w->sd = (double *) malloc (n * sizeof (double)); if (w->sd == 0) { free (w->d); free (w); GSL_ERROR_NULL ("failed to allocate space for subdiagonal", GSL_ENOMEM); } w->tau = (double *) malloc (2 * n * sizeof (double)); if (w->tau == 0) { free (w->sd); free (w->d); free (w); GSL_ERROR_NULL ("failed to allocate space for tau", GSL_ENOMEM); } w->gc = (double *) malloc (n * sizeof (double)); if (w->gc == 0) { free (w->tau); free (w->sd); free (w->d); free (w); GSL_ERROR_NULL ("failed to allocate space for cosines", GSL_ENOMEM); } w->gs = (double *) malloc (n * sizeof (double)); if (w->gs == 0) { free (w->gc); free (w->tau); free (w->sd); free (w->d); free (w); GSL_ERROR_NULL ("failed to allocate space for sines", GSL_ENOMEM); } w->size = n; return w; } void gsl_eigen_hermv_free (gsl_eigen_hermv_workspace * w) { free (w->gs); free (w->gc); free (w->tau); free (w->sd); free (w->d); free (w); } int gsl_eigen_hermv (gsl_matrix_complex * A, gsl_vector * eval, gsl_matrix_complex * evec, gsl_eigen_hermv_workspace * w) { if (A->size1 != A->size2) { GSL_ERROR ("matrix must be square to compute eigenvalues", GSL_ENOTSQR); } else if (eval->size != A->size1) { GSL_ERROR ("eigenvalue vector must match matrix size", GSL_EBADLEN); } else if (evec->size1 != A->size1 || evec->size2 != A->size1) { GSL_ERROR ("eigenvector matrix must match matrix size", GSL_EBADLEN); } else { const size_t N = A->size1; double *const d = w->d; double *const sd = w->sd; size_t a, b; /* handle special case */ if (N == 1) { gsl_complex A00 = gsl_matrix_complex_get (A, 0, 0); gsl_vector_set (eval, 0, GSL_REAL(A00)); gsl_matrix_complex_set (evec, 0, 0, GSL_COMPLEX_ONE); return GSL_SUCCESS; } /* Transform the matrix into a symmetric tridiagonal form */ { gsl_vector_view d_vec = gsl_vector_view_array (d, N); gsl_vector_view sd_vec = gsl_vector_view_array (sd, N - 1); gsl_vector_complex_view tau_vec = gsl_vector_complex_view_array (w->tau, N-1); gsl_linalg_hermtd_decomp (A, &tau_vec.vector); gsl_linalg_hermtd_unpack (A, &tau_vec.vector, evec, &d_vec.vector, &sd_vec.vector); } /* Make an initial pass through the tridiagonal decomposition to remove off-diagonal elements which are effectively zero */ chop_small_elements (N, d, sd); /* Progressively reduce the matrix until it is diagonal */ b = N - 1; while (b > 0) { if (sd[b - 1] == 0.0 || isnan(sd[b - 1])) { b--; continue; } /* Find the largest unreduced block (a,b) starting from b and working backwards */ a = b - 1; while (a > 0) { if (sd[a - 1] == 0.0) { break; } a--; } { size_t i; const size_t n_block = b - a + 1; double *d_block = d + a; double *sd_block = sd + a; double * const gc = w->gc; double * const gs = w->gs; /* apply QR reduction with implicit deflation to the unreduced block */ qrstep (n_block, d_block, sd_block, gc, gs); /* Apply Givens rotation Gij(c,s) to matrix Q, Q <- Q G */ for (i = 0; i < n_block - 1; i++) { const double c = gc[i], s = gs[i]; size_t k; for (k = 0; k < N; k++) { gsl_complex qki = gsl_matrix_complex_get (evec, k, a + i); gsl_complex qkj = gsl_matrix_complex_get (evec, k, a + i + 1); /* qki <= qki * c - qkj * s */ /* qkj <= qki * s + qkj * c */ gsl_complex x1 = gsl_complex_mul_real(qki, c); gsl_complex y1 = gsl_complex_mul_real(qkj, -s); gsl_complex x2 = gsl_complex_mul_real(qki, s); gsl_complex y2 = gsl_complex_mul_real(qkj, c); gsl_complex qqki = gsl_complex_add(x1, y1); gsl_complex qqkj = gsl_complex_add(x2, y2); gsl_matrix_complex_set (evec, k, a + i, qqki); gsl_matrix_complex_set (evec, k, a + i + 1, qqkj); } } /* remove any small off-diagonal elements */ chop_small_elements (n_block, d_block, sd_block); } } { gsl_vector_view d_vec = gsl_vector_view_array (d, N); gsl_vector_memcpy (eval, &d_vec.vector); } return GSL_SUCCESS; } } praat-6.0.04/external/gsl/gsl_eigen__jacobi.c000066400000000000000000000136311261542461700211010ustar00rootroot00000000000000/* eigen/jacobi.c * * Copyright (C) 2004, 2007 Brian Gough, Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_vector.h" #include "gsl_matrix.h" #include "gsl_eigen.h" /* Algorithm 8.4.3 - Cyclic Jacobi. Golub & Van Loan, Matrix Computations */ static inline double symschur2 (gsl_matrix * A, size_t p, size_t q, double *c, double *s) { double Apq = gsl_matrix_get (A, p, q); if (Apq != 0.0) { double App = gsl_matrix_get (A, p, p); double Aqq = gsl_matrix_get (A, q, q); double tau = (Aqq - App) / (2.0 * Apq); double t, c1; if (tau >= 0.0) { t = 1.0 / (tau + hypot (1.0, tau)); } else { t = -1.0 / (-tau + hypot (1.0, tau)); } c1 = 1.0 / hypot (1.0, t); *c = c1; *s = t * c1; } else { *c = 1.0; *s = 0.0; } /* reduction in off(A) is 2*(A_pq)^2 */ return fabs (Apq); } inline static void apply_jacobi_L (gsl_matrix * A, size_t p, size_t q, double c, double s) { size_t j; const size_t N = A->size2; /* Apply rotation to matrix A, A' = J^T A */ for (j = 0; j < N; j++) { double Apj = gsl_matrix_get (A, p, j); double Aqj = gsl_matrix_get (A, q, j); gsl_matrix_set (A, p, j, Apj * c - Aqj * s); gsl_matrix_set (A, q, j, Apj * s + Aqj * c); } } inline static void apply_jacobi_R (gsl_matrix * A, size_t p, size_t q, double c, double s) { size_t i; const size_t M = A->size1; /* Apply rotation to matrix A, A' = A J */ for (i = 0; i < M; i++) { double Aip = gsl_matrix_get (A, i, p); double Aiq = gsl_matrix_get (A, i, q); gsl_matrix_set (A, i, p, Aip * c - Aiq * s); gsl_matrix_set (A, i, q, Aip * s + Aiq * c); } } inline static double norm (gsl_matrix * A) { size_t i, j, M = A->size1, N = A->size2; double sum = 0.0, scale = 0.0, ssq = 1.0; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { double Aij = gsl_matrix_get (A, i, j); if (Aij != 0.0) { double ax = fabs (Aij); if (scale < ax) { ssq = 1.0 + ssq * (scale / ax) * (scale / ax); scale = ax; } else { ssq += (ax / scale) * (ax / scale); } } } } sum = scale * sqrt (ssq); return sum; } int gsl_eigen_jacobi (gsl_matrix * a, gsl_vector * eval, gsl_matrix * evec, unsigned int max_rot, unsigned int *nrot) { size_t i, p, q; const size_t M = a->size1, N = a->size2; double red, redsum = 0.0; if (M != N) { GSL_ERROR ("eigenproblem requires square matrix", GSL_ENOTSQR); } else if (M != evec->size1 || M != evec->size2) { GSL_ERROR ("eigenvector matrix must match input matrix", GSL_EBADLEN); } else if (M != eval->size) { GSL_ERROR ("eigenvalue vector must match input matrix", GSL_EBADLEN); } gsl_vector_set_zero (eval); gsl_matrix_set_identity (evec); for (i = 0; i < max_rot; i++) { double nrm = norm (a); if (nrm == 0.0) break; for (p = 0; p < N; p++) { for (q = p + 1; q < N; q++) { double c, s; red = symschur2 (a, p, q, &c, &s); redsum += red; /* Compute A <- J^T A J */ apply_jacobi_L (a, p, q, c, s); apply_jacobi_R (a, p, q, c, s); /* Compute V <- V J */ apply_jacobi_R (evec, p, q, c, s); } } } *nrot = i; for (p = 0; p < N; p++) { double ep = gsl_matrix_get (a, p, p); gsl_vector_set (eval, p, ep); } if (i == max_rot) { return GSL_EMAXITER; } return GSL_SUCCESS; } int gsl_eigen_invert_jacobi (const gsl_matrix * a, gsl_matrix * ainv, unsigned int max_rot) { if (a->size1 != a->size2 || ainv->size1 != ainv->size2) { GSL_ERROR("jacobi method requires square matrix", GSL_ENOTSQR); } else if (a->size1 != ainv->size2) { GSL_ERROR ("inverse matrix must match input matrix", GSL_EBADLEN); } { const size_t n = a->size2; size_t i,j,k; unsigned int nrot = 0; int status; gsl_vector * eval = gsl_vector_alloc(n); gsl_matrix * evec = gsl_matrix_alloc(n, n); gsl_matrix * tmp = gsl_matrix_alloc(n, n); gsl_matrix_memcpy (tmp, a); status = gsl_eigen_jacobi(tmp, eval, evec, max_rot, &nrot); for(i=0; i #include #include "gsl_eigen.h" #include "gsl_linalg.h" #include "gsl_math.h" #include "gsl_blas.h" #include "gsl_vector.h" #include "gsl_vector_complex.h" #include "gsl_matrix.h" /* * This module computes the eigenvalues of a real nonsymmetric * matrix, using the double shift Francis method. * * See the references in francis.c. * * This module gets the matrix ready by balancing it and * reducing it to Hessenberg form before passing it to the * francis module. */ /* gsl_eigen_nonsymm_alloc() Allocate a workspace for solving the nonsymmetric eigenvalue problem. The size of this workspace is O(2n) Inputs: n - size of matrix Return: pointer to workspace */ gsl_eigen_nonsymm_workspace * gsl_eigen_nonsymm_alloc(const size_t n) { gsl_eigen_nonsymm_workspace *w; if (n == 0) { GSL_ERROR_NULL ("matrix dimension must be positive integer", GSL_EINVAL); } w = (gsl_eigen_nonsymm_workspace *) calloc (1, sizeof (gsl_eigen_nonsymm_workspace)); if (w == 0) { GSL_ERROR_NULL ("failed to allocate space for workspace", GSL_ENOMEM); } w->size = n; w->Z = NULL; w->do_balance = 0; w->diag = gsl_vector_alloc(n); if (w->diag == 0) { gsl_eigen_nonsymm_free(w); GSL_ERROR_NULL ("failed to allocate space for balancing vector", GSL_ENOMEM); } w->tau = gsl_vector_alloc(n); if (w->tau == 0) { gsl_eigen_nonsymm_free(w); GSL_ERROR_NULL ("failed to allocate space for hessenberg coefficients", GSL_ENOMEM); } w->francis_workspace_p = gsl_eigen_francis_alloc(); if (w->francis_workspace_p == 0) { gsl_eigen_nonsymm_free(w); GSL_ERROR_NULL ("failed to allocate space for francis workspace", GSL_ENOMEM); } return (w); } /* gsl_eigen_nonsymm_alloc() */ /* gsl_eigen_nonsymm_free() Free workspace w */ void gsl_eigen_nonsymm_free (gsl_eigen_nonsymm_workspace * w) { if (w->tau) gsl_vector_free(w->tau); if (w->diag) gsl_vector_free(w->diag); if (w->francis_workspace_p) gsl_eigen_francis_free(w->francis_workspace_p); free(w); } /* gsl_eigen_nonsymm_free() */ /* gsl_eigen_nonsymm_params() Set some parameters which define how we solve the eigenvalue problem. Inputs: compute_t - 1 if we want to compute T, 0 if not balance - 1 if we want to balance the matrix, 0 if not w - nonsymm workspace */ void gsl_eigen_nonsymm_params (const int compute_t, const int balance, gsl_eigen_nonsymm_workspace *w) { gsl_eigen_francis_T(compute_t, w->francis_workspace_p); w->do_balance = balance; } /* gsl_eigen_nonsymm_params() */ /* gsl_eigen_nonsymm() Solve the nonsymmetric eigenvalue problem A x = \lambda x for the eigenvalues \lambda using the Francis method. Here we compute the real Schur form T = Z^t A Z with the diagonal blocks of T giving us the eigenvalues. Z is a matrix of Schur vectors which is not computed by this algorithm. See gsl_eigen_nonsymm_Z(). Inputs: A - general real matrix eval - where to store eigenvalues w - workspace Return: success or error Notes: If T is computed, it is stored in A on output. Otherwise the diagonal of A contains the 1-by-1 and 2-by-2 eigenvalue blocks. */ int gsl_eigen_nonsymm (gsl_matrix * A, gsl_vector_complex * eval, gsl_eigen_nonsymm_workspace * w) { const size_t N = A->size1; /* check matrix and vector sizes */ if (N != A->size2) { GSL_ERROR ("matrix must be square to compute eigenvalues", GSL_ENOTSQR); } else if (eval->size != N) { GSL_ERROR ("eigenvalue vector must match matrix size", GSL_EBADLEN); } else { int s; if (w->do_balance) { /* balance the matrix */ gsl_linalg_balance_matrix(A, w->diag); } /* compute the Hessenberg reduction of A */ gsl_linalg_hessenberg_decomp(A, w->tau); if (w->Z) { /* * initialize the matrix Z to U, which is the matrix used * to construct the Hessenberg reduction. */ /* compute U and store it in Z */ gsl_linalg_hessenberg_unpack(A, w->tau, w->Z); /* find the eigenvalues and Schur vectors */ s = gsl_eigen_francis_Z(A, eval, w->Z, w->francis_workspace_p); if (w->do_balance) { /* * The Schur vectors in Z are the vectors for the balanced * matrix. We now must undo the balancing to get the * vectors for the original matrix A. */ gsl_linalg_balance_accum(w->Z, w->diag); } } else { /* find the eigenvalues only */ s = gsl_eigen_francis(A, eval, w->francis_workspace_p); } w->n_evals = w->francis_workspace_p->n_evals; return s; } } /* gsl_eigen_nonsymm() */ /* gsl_eigen_nonsymm_Z() Solve the nonsymmetric eigenvalue problem A x = \lambda x for the eigenvalues \lambda. Here we compute the real Schur form T = Z^t A Z with the diagonal blocks of T giving us the eigenvalues. Z is the matrix of Schur vectors. Inputs: A - general real matrix eval - where to store eigenvalues Z - where to store Schur vectors w - workspace Return: success or error Notes: If T is computed, it is stored in A on output. Otherwise the diagonal of A contains the 1-by-1 and 2-by-2 eigenvalue blocks. */ int gsl_eigen_nonsymm_Z (gsl_matrix * A, gsl_vector_complex * eval, gsl_matrix * Z, gsl_eigen_nonsymm_workspace * w) { /* check matrix and vector sizes */ if (A->size1 != A->size2) { GSL_ERROR ("matrix must be square to compute eigenvalues", GSL_ENOTSQR); } else if (eval->size != A->size1) { GSL_ERROR ("eigenvalue vector must match matrix size", GSL_EBADLEN); } else if ((Z->size1 != Z->size2) || (Z->size1 != A->size1)) { GSL_ERROR ("Z matrix has wrong dimensions", GSL_EBADLEN); } else { int s; w->Z = Z; s = gsl_eigen_nonsymm(A, eval, w); w->Z = NULL; return s; } } /* gsl_eigen_nonsymm_Z() */ praat-6.0.04/external/gsl/gsl_eigen__nonsymmv.c000066400000000000000000000752141261542461700215450ustar00rootroot00000000000000/* eigen/nonsymmv.c * * Copyright (C) 2006 Patrick Alken * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_complex.h" #include "gsl_complex_math.h" #include "gsl_eigen.h" #include "gsl_linalg.h" #include "gsl_math.h" #include "gsl_blas.h" #include "gsl_cblas.h" #include "gsl_vector.h" #include "gsl_vector_complex.h" #include "gsl_matrix.h" /* * This module computes the eigenvalues and eigenvectors of a real * nonsymmetric matrix. * * This file contains routines based on original code from LAPACK * which is distributed under the modified BSD license. The LAPACK * routines used are DTREVC and DLALN2. */ #define GSL_NONSYMMV_SMLNUM (2.0 * GSL_DBL_MIN) #define GSL_NONSYMMV_BIGNUM ((1.0 - GSL_DBL_EPSILON) / GSL_NONSYMMV_SMLNUM) static void nonsymmv_get_right_eigenvectors(gsl_matrix *T, gsl_matrix *Z, gsl_vector_complex *eval, gsl_matrix_complex *evec, gsl_eigen_nonsymmv_workspace *w); static void nonsymmv_normalize_eigenvectors(gsl_vector_complex *eval, gsl_matrix_complex *evec); /* gsl_eigen_nonsymmv_alloc() Allocate a workspace for solving the nonsymmetric eigenvalue problem. The size of this workspace is O(5n). Inputs: n - size of matrices Return: pointer to workspace */ gsl_eigen_nonsymmv_workspace * gsl_eigen_nonsymmv_alloc(const size_t n) { gsl_eigen_nonsymmv_workspace *w; if (n == 0) { GSL_ERROR_NULL ("matrix dimension must be positive integer", GSL_EINVAL); } w = (gsl_eigen_nonsymmv_workspace *) calloc (1, sizeof (gsl_eigen_nonsymmv_workspace)); if (w == 0) { GSL_ERROR_NULL ("failed to allocate space for workspace", GSL_ENOMEM); } w->size = n; w->Z = NULL; w->nonsymm_workspace_p = gsl_eigen_nonsymm_alloc(n); if (w->nonsymm_workspace_p == 0) { gsl_eigen_nonsymmv_free(w); GSL_ERROR_NULL ("failed to allocate space for nonsymm workspace", GSL_ENOMEM); } /* * set parameters to compute the full Schur form T and balance * the matrices */ gsl_eigen_nonsymm_params(1, 1, w->nonsymm_workspace_p); w->work = gsl_vector_alloc(n); w->work2 = gsl_vector_alloc(n); w->work3 = gsl_vector_alloc(n); if (w->work == 0 || w->work2 == 0 || w->work3 == 0) { gsl_eigen_nonsymmv_free(w); GSL_ERROR_NULL ("failed to allocate space for nonsymmv additional workspace", GSL_ENOMEM); } return (w); } /* gsl_eigen_nonsymmv_alloc() */ /* gsl_eigen_nonsymmv_free() Free workspace w */ void gsl_eigen_nonsymmv_free (gsl_eigen_nonsymmv_workspace * w) { if (w->nonsymm_workspace_p) gsl_eigen_nonsymm_free(w->nonsymm_workspace_p); if (w->work) gsl_vector_free(w->work); if (w->work2) gsl_vector_free(w->work2); if (w->work3) gsl_vector_free(w->work3); free(w); } /* gsl_eigen_nonsymmv_free() */ /* gsl_eigen_nonsymmv() Solve the nonsymmetric eigensystem problem A x = \lambda x for the eigenvalues \lambda and right eigenvectors x Inputs: A - general real matrix eval - where to store eigenvalues evec - where to store eigenvectors w - workspace Return: success or error */ int gsl_eigen_nonsymmv (gsl_matrix * A, gsl_vector_complex * eval, gsl_matrix_complex * evec, gsl_eigen_nonsymmv_workspace * w) { const size_t N = A->size1; /* check matrix and vector sizes */ if (N != A->size2) { GSL_ERROR ("matrix must be square to compute eigenvalues", GSL_ENOTSQR); } else if (eval->size != N) { GSL_ERROR ("eigenvalue vector must match matrix size", GSL_EBADLEN); } else if (evec->size1 != evec->size2) { GSL_ERROR ("eigenvector matrix must be square", GSL_ENOTSQR); } else if (evec->size1 != N) { GSL_ERROR ("eigenvector matrix has wrong size", GSL_EBADLEN); } else { int s; gsl_matrix Z; /* * We need a place to store the Schur vectors, so we will * treat evec as a real matrix and store them in the left * half - the factor of 2 in the tda corresponds to the * complex multiplicity */ Z.size1 = N; Z.size2 = N; Z.tda = 2 * N; Z.data = evec->data; Z.block = 0; Z.owner = 0; /* compute eigenvalues, Schur form, and Schur vectors */ s = gsl_eigen_nonsymm_Z(A, eval, &Z, w->nonsymm_workspace_p); if (w->Z) { /* * save the Schur vectors in user supplied matrix, since * they will be destroyed when computing eigenvectors */ gsl_matrix_memcpy(w->Z, &Z); } /* only compute eigenvectors if we found all eigenvalues */ if (s == GSL_SUCCESS) { /* compute eigenvectors */ nonsymmv_get_right_eigenvectors(A, &Z, eval, evec, w); /* normalize so that Euclidean norm is 1 */ nonsymmv_normalize_eigenvectors(eval, evec); } return s; } } /* gsl_eigen_nonsymmv() */ /* gsl_eigen_nonsymmv_Z() Compute eigenvalues and eigenvectors of a real nonsymmetric matrix and also save the Schur vectors. See comments in gsl_eigen_nonsymm_Z for more information. Inputs: A - real nonsymmetric matrix eval - where to store eigenvalues evec - where to store eigenvectors Z - where to store Schur vectors w - nonsymmv workspace Return: success or error */ int gsl_eigen_nonsymmv_Z (gsl_matrix * A, gsl_vector_complex * eval, gsl_matrix_complex * evec, gsl_matrix * Z, gsl_eigen_nonsymmv_workspace * w) { /* check matrix and vector sizes */ if (A->size1 != A->size2) { GSL_ERROR ("matrix must be square to compute eigenvalues/eigenvectors", GSL_ENOTSQR); } else if (eval->size != A->size1) { GSL_ERROR ("eigenvalue vector must match matrix size", GSL_EBADLEN); } else if (evec->size1 != evec->size2) { GSL_ERROR ("eigenvector matrix must be square", GSL_ENOTSQR); } else if (evec->size1 != A->size1) { GSL_ERROR ("eigenvector matrix has wrong size", GSL_EBADLEN); } else if ((Z->size1 != Z->size2) || (Z->size1 != A->size1)) { GSL_ERROR ("Z matrix has wrong dimensions", GSL_EBADLEN); } else { int s; w->Z = Z; s = gsl_eigen_nonsymmv(A, eval, evec, w); w->Z = NULL; return s; } } /* gsl_eigen_nonsymmv_Z() */ /******************************************** * INTERNAL ROUTINES * ********************************************/ /* nonsymmv_get_right_eigenvectors() Compute the right eigenvectors of the Schur form T and then backtransform them using the Schur vectors to get right eigenvectors of the original matrix. Inputs: T - Schur form Z - Schur vectors eval - where to store eigenvalues (to ensure that the correct eigenvalue is stored in the same position as the eigenvectors) evec - where to store eigenvectors w - nonsymmv workspace Return: none Notes: 1) based on LAPACK routine DTREVC - the algorithm used is backsubstitution on the upper quasi triangular system T followed by backtransformation by Z to get vectors of the original matrix. 2) The Schur vectors in Z are destroyed and replaced with eigenvectors stored with the same storage scheme as DTREVC. The eigenvectors are also stored in 'evec' 3) The matrix T is unchanged on output 4) Each eigenvector is normalized so that the element of largest magnitude has magnitude 1; here the magnitude of a complex number (x,y) is taken to be |x| + |y| */ static void nonsymmv_get_right_eigenvectors(gsl_matrix *T, gsl_matrix *Z, gsl_vector_complex *eval, gsl_matrix_complex *evec, gsl_eigen_nonsymmv_workspace *w) { const size_t N = T->size1; const double smlnum = GSL_DBL_MIN * N / GSL_DBL_EPSILON; const double bignum = (1.0 - GSL_DBL_EPSILON) / smlnum; int i; /* looping */ size_t iu, /* looping */ ju, ii; gsl_complex lambda; /* current eigenvalue */ double lambda_re, /* Re(lambda) */ lambda_im; /* Im(lambda) */ gsl_matrix_view Tv, /* temporary views */ Zv; gsl_vector_view y, /* temporary views */ y2, ev, ev2; double dat[4], /* scratch arrays */ dat_X[4]; double scale; /* scale factor */ double xnorm; /* |X| */ gsl_vector_complex_view ecol, /* column of evec */ ecol2; int complex_pair; /* complex eigenvalue pair? */ double smin; /* * Compute 1-norm of each column of upper triangular part of T * to control overflow in triangular solver */ gsl_vector_set(w->work3, 0, 0.0); for (ju = 1; ju < N; ++ju) { gsl_vector_set(w->work3, ju, 0.0); for (iu = 0; iu < ju; ++iu) { gsl_vector_set(w->work3, ju, gsl_vector_get(w->work3, ju) + fabs(gsl_matrix_get(T, iu, ju))); } } for (i = (int) N - 1; i >= 0; --i) { iu = (size_t) i; /* get current eigenvalue and store it in lambda */ lambda_re = gsl_matrix_get(T, iu, iu); if (iu != 0 && gsl_matrix_get(T, iu, iu - 1) != 0.0) { lambda_im = sqrt(fabs(gsl_matrix_get(T, iu, iu - 1))) * sqrt(fabs(gsl_matrix_get(T, iu - 1, iu))); } else { lambda_im = 0.0; } GSL_SET_COMPLEX(&lambda, lambda_re, lambda_im); smin = GSL_MAX(GSL_DBL_EPSILON * (fabs(lambda_re) + fabs(lambda_im)), smlnum); smin = GSL_MAX(smin, GSL_NONSYMMV_SMLNUM); if (lambda_im == 0.0) { int k, l; gsl_vector_view bv, xv; /* real eigenvector */ /* * The ordering of eigenvalues in 'eval' is arbitrary and * does not necessarily follow the Schur form T, so store * lambda in the right slot in eval to ensure it corresponds * to the eigenvector we are about to compute */ gsl_vector_complex_set(eval, iu, lambda); /* * We need to solve the system: * * (T(1:iu-1, 1:iu-1) - lambda*I)*X = -T(1:iu-1,iu) */ /* construct right hand side */ for (k = 0; k < i; ++k) { gsl_vector_set(w->work, (size_t) k, -gsl_matrix_get(T, (size_t) k, iu)); } gsl_vector_set(w->work, iu, 1.0); for (l = i - 1; l >= 0; --l) { size_t lu = (size_t) l; if (lu == 0) complex_pair = 0; else complex_pair = gsl_matrix_get(T, lu, lu - 1) != 0.0; if (!complex_pair) { double x; /* * 1-by-1 diagonal block - solve the system: * * (T_{ll} - lambda)*x = -T_{l(iu)} */ Tv = gsl_matrix_submatrix(T, lu, lu, 1, 1); bv = gsl_vector_view_array(dat, 1); gsl_vector_set(&bv.vector, 0, gsl_vector_get(w->work, lu)); xv = gsl_vector_view_array(dat_X, 1); gsl_schur_solve_equation(1.0, &Tv.matrix, lambda_re, 1.0, 1.0, &bv.vector, &xv.vector, &scale, &xnorm, smin); /* scale x to avoid overflow */ x = gsl_vector_get(&xv.vector, 0); if (xnorm > 1.0) { if (gsl_vector_get(w->work3, lu) > bignum / xnorm) { x /= xnorm; scale /= xnorm; } } if (scale != 1.0) { gsl_vector_view wv; wv = gsl_vector_subvector(w->work, 0, iu + 1); gsl_blas_dscal(scale, &wv.vector); } gsl_vector_set(w->work, lu, x); if (lu > 0) { gsl_vector_view v1, v2; /* update right hand side */ v1 = gsl_matrix_subcolumn(T, lu, 0, lu); v2 = gsl_vector_subvector(w->work, 0, lu); gsl_blas_daxpy(-x, &v1.vector, &v2.vector); } /* if (l > 0) */ } /* if (!complex_pair) */ else { double x11, x21; /* * 2-by-2 diagonal block */ Tv = gsl_matrix_submatrix(T, lu - 1, lu - 1, 2, 2); bv = gsl_vector_view_array(dat, 2); gsl_vector_set(&bv.vector, 0, gsl_vector_get(w->work, lu - 1)); gsl_vector_set(&bv.vector, 1, gsl_vector_get(w->work, lu)); xv = gsl_vector_view_array(dat_X, 2); gsl_schur_solve_equation(1.0, &Tv.matrix, lambda_re, 1.0, 1.0, &bv.vector, &xv.vector, &scale, &xnorm, smin); /* scale X(1,1) and X(2,1) to avoid overflow */ x11 = gsl_vector_get(&xv.vector, 0); x21 = gsl_vector_get(&xv.vector, 1); if (xnorm > 1.0) { double beta; beta = GSL_MAX(gsl_vector_get(w->work3, lu - 1), gsl_vector_get(w->work3, lu)); if (beta > bignum / xnorm) { x11 /= xnorm; x21 /= xnorm; scale /= xnorm; } } /* scale if necessary */ if (scale != 1.0) { gsl_vector_view wv; wv = gsl_vector_subvector(w->work, 0, iu + 1); gsl_blas_dscal(scale, &wv.vector); } gsl_vector_set(w->work, lu - 1, x11); gsl_vector_set(w->work, lu, x21); /* update right hand side */ if (lu > 1) { gsl_vector_view v1, v2; v1 = gsl_matrix_subcolumn(T, lu - 1, 0, lu - 1); v2 = gsl_vector_subvector(w->work, 0, lu - 1); gsl_blas_daxpy(-x11, &v1.vector, &v2.vector); v1 = gsl_matrix_subcolumn(T, lu, 0, lu - 1); gsl_blas_daxpy(-x21, &v1.vector, &v2.vector); } --l; } /* if (complex_pair) */ } /* for (l = i - 1; l >= 0; --l) */ /* * At this point, w->work is an eigenvector of the * Schur form T. To get an eigenvector of the original * matrix, we multiply on the left by Z, the matrix of * Schur vectors */ ecol = gsl_matrix_complex_column(evec, iu); y = gsl_matrix_column(Z, iu); if (iu > 0) { gsl_vector_view x; Zv = gsl_matrix_submatrix(Z, 0, 0, N, iu); x = gsl_vector_subvector(w->work, 0, iu); /* compute Z * w->work and store it in Z(:,iu) */ gsl_blas_dgemv(CblasNoTrans, 1.0, &Zv.matrix, &x.vector, gsl_vector_get(w->work, iu), &y.vector); } /* if (iu > 0) */ /* store eigenvector into evec */ ev = gsl_vector_complex_real(&ecol.vector); ev2 = gsl_vector_complex_imag(&ecol.vector); scale = 0.0; for (ii = 0; ii < N; ++ii) { double a = gsl_vector_get(&y.vector, ii); /* store real part of eigenvector */ gsl_vector_set(&ev.vector, ii, a); /* set imaginary part to 0 */ gsl_vector_set(&ev2.vector, ii, 0.0); if (fabs(a) > scale) scale = fabs(a); } if (scale != 0.0) scale = 1.0 / scale; /* scale by magnitude of largest element */ gsl_blas_dscal(scale, &ev.vector); } /* if (GSL_IMAG(lambda) == 0.0) */ else { gsl_vector_complex_view bv, xv; size_t k; int l; gsl_complex lambda2; /* complex eigenvector */ /* * Store the complex conjugate eigenvalues in the right * slots in eval */ GSL_SET_REAL(&lambda2, GSL_REAL(lambda)); GSL_SET_IMAG(&lambda2, -GSL_IMAG(lambda)); gsl_vector_complex_set(eval, iu - 1, lambda); gsl_vector_complex_set(eval, iu, lambda2); /* * First solve: * * [ T(i:i+1,i:i+1) - lambda*I ] * X = 0 */ if (fabs(gsl_matrix_get(T, iu - 1, iu)) >= fabs(gsl_matrix_get(T, iu, iu - 1))) { gsl_vector_set(w->work, iu - 1, 1.0); gsl_vector_set(w->work2, iu, lambda_im / gsl_matrix_get(T, iu - 1, iu)); } else { gsl_vector_set(w->work, iu - 1, -lambda_im / gsl_matrix_get(T, iu, iu - 1)); gsl_vector_set(w->work2, iu, 1.0); } gsl_vector_set(w->work, iu, 0.0); gsl_vector_set(w->work2, iu - 1, 0.0); /* construct right hand side */ for (k = 0; k < iu - 1; ++k) { gsl_vector_set(w->work, k, -gsl_vector_get(w->work, iu - 1) * gsl_matrix_get(T, k, iu - 1)); gsl_vector_set(w->work2, k, -gsl_vector_get(w->work2, iu) * gsl_matrix_get(T, k, iu)); } /* * We must solve the upper quasi-triangular system: * * [ T(1:i-2,1:i-2) - lambda*I ] * X = s*(work + i*work2) */ for (l = i - 2; l >= 0; --l) { size_t lu = (size_t) l; if (lu == 0) complex_pair = 0; else complex_pair = gsl_matrix_get(T, lu, lu - 1) != 0.0; if (!complex_pair) { gsl_complex bval; gsl_complex x; /* * 1-by-1 diagonal block - solve the system: * * (T_{ll} - lambda)*x = work + i*work2 */ Tv = gsl_matrix_submatrix(T, lu, lu, 1, 1); bv = gsl_vector_complex_view_array(dat, 1); xv = gsl_vector_complex_view_array(dat_X, 1); GSL_SET_COMPLEX(&bval, gsl_vector_get(w->work, lu), gsl_vector_get(w->work2, lu)); gsl_vector_complex_set(&bv.vector, 0, bval); gsl_schur_solve_equation_z(1.0, &Tv.matrix, &lambda, 1.0, 1.0, &bv.vector, &xv.vector, &scale, &xnorm, smin); if (xnorm > 1.0) { if (gsl_vector_get(w->work3, lu) > bignum / xnorm) { gsl_blas_zdscal(1.0/xnorm, &xv.vector); scale /= xnorm; } } /* scale if necessary */ if (scale != 1.0) { gsl_vector_view wv; wv = gsl_vector_subvector(w->work, 0, iu + 1); gsl_blas_dscal(scale, &wv.vector); wv = gsl_vector_subvector(w->work2, 0, iu + 1); gsl_blas_dscal(scale, &wv.vector); } x = gsl_vector_complex_get(&xv.vector, 0); gsl_vector_set(w->work, lu, GSL_REAL(x)); gsl_vector_set(w->work2, lu, GSL_IMAG(x)); /* update the right hand side */ if (lu > 0) { gsl_vector_view v1, v2; v1 = gsl_matrix_subcolumn(T, lu, 0, lu); v2 = gsl_vector_subvector(w->work, 0, lu); gsl_blas_daxpy(-GSL_REAL(x), &v1.vector, &v2.vector); v2 = gsl_vector_subvector(w->work2, 0, lu); gsl_blas_daxpy(-GSL_IMAG(x), &v1.vector, &v2.vector); } /* if (lu > 0) */ } /* if (!complex_pair) */ else { gsl_complex b1, b2, x1, x2; /* * 2-by-2 diagonal block - solve the system */ Tv = gsl_matrix_submatrix(T, lu - 1, lu - 1, 2, 2); bv = gsl_vector_complex_view_array(dat, 2); xv = gsl_vector_complex_view_array(dat_X, 2); GSL_SET_COMPLEX(&b1, gsl_vector_get(w->work, lu - 1), gsl_vector_get(w->work2, lu - 1)); GSL_SET_COMPLEX(&b2, gsl_vector_get(w->work, lu), gsl_vector_get(w->work2, lu)); gsl_vector_complex_set(&bv.vector, 0, b1); gsl_vector_complex_set(&bv.vector, 1, b2); gsl_schur_solve_equation_z(1.0, &Tv.matrix, &lambda, 1.0, 1.0, &bv.vector, &xv.vector, &scale, &xnorm, smin); x1 = gsl_vector_complex_get(&xv.vector, 0); x2 = gsl_vector_complex_get(&xv.vector, 1); if (xnorm > 1.0) { double beta; beta = GSL_MAX(gsl_vector_get(w->work3, lu - 1), gsl_vector_get(w->work3, lu)); if (beta > bignum / xnorm) { gsl_blas_zdscal(1.0/xnorm, &xv.vector); scale /= xnorm; } } /* scale if necessary */ if (scale != 1.0) { gsl_vector_view wv; wv = gsl_vector_subvector(w->work, 0, iu + 1); gsl_blas_dscal(scale, &wv.vector); wv = gsl_vector_subvector(w->work2, 0, iu + 1); gsl_blas_dscal(scale, &wv.vector); } gsl_vector_set(w->work, lu - 1, GSL_REAL(x1)); gsl_vector_set(w->work, lu, GSL_REAL(x2)); gsl_vector_set(w->work2, lu - 1, GSL_IMAG(x1)); gsl_vector_set(w->work2, lu, GSL_IMAG(x2)); /* update right hand side */ if (lu > 1) { gsl_vector_view v1, v2, v3, v4; v1 = gsl_matrix_subcolumn(T, lu - 1, 0, lu - 1); v4 = gsl_matrix_subcolumn(T, lu, 0, lu - 1); v2 = gsl_vector_subvector(w->work, 0, lu - 1); v3 = gsl_vector_subvector(w->work2, 0, lu - 1); gsl_blas_daxpy(-GSL_REAL(x1), &v1.vector, &v2.vector); gsl_blas_daxpy(-GSL_REAL(x2), &v4.vector, &v2.vector); gsl_blas_daxpy(-GSL_IMAG(x1), &v1.vector, &v3.vector); gsl_blas_daxpy(-GSL_IMAG(x2), &v4.vector, &v3.vector); } /* if (lu > 1) */ --l; } /* if (complex_pair) */ } /* for (l = i - 2; l >= 0; --l) */ /* * At this point, work + i*work2 is an eigenvector * of T - backtransform to get an eigenvector of the * original matrix */ y = gsl_matrix_column(Z, iu - 1); y2 = gsl_matrix_column(Z, iu); if (iu > 1) { gsl_vector_view x; /* compute real part of eigenvectors */ Zv = gsl_matrix_submatrix(Z, 0, 0, N, iu - 1); x = gsl_vector_subvector(w->work, 0, iu - 1); gsl_blas_dgemv(CblasNoTrans, 1.0, &Zv.matrix, &x.vector, gsl_vector_get(w->work, iu - 1), &y.vector); /* now compute the imaginary part */ x = gsl_vector_subvector(w->work2, 0, iu - 1); gsl_blas_dgemv(CblasNoTrans, 1.0, &Zv.matrix, &x.vector, gsl_vector_get(w->work2, iu), &y2.vector); } else { gsl_blas_dscal(gsl_vector_get(w->work, iu - 1), &y.vector); gsl_blas_dscal(gsl_vector_get(w->work2, iu), &y2.vector); } /* * Now store the eigenvectors into evec - the real parts * are Z(:,iu - 1) and the imaginary parts are * +/- Z(:,iu) */ /* get views of the two eigenvector slots */ ecol = gsl_matrix_complex_column(evec, iu - 1); ecol2 = gsl_matrix_complex_column(evec, iu); /* * save imaginary part first as it may get overwritten * when copying the real part due to our storage scheme * in Z/evec */ ev = gsl_vector_complex_imag(&ecol.vector); ev2 = gsl_vector_complex_imag(&ecol2.vector); scale = 0.0; for (ii = 0; ii < N; ++ii) { double a = gsl_vector_get(&y2.vector, ii); scale = GSL_MAX(scale, fabs(a) + fabs(gsl_vector_get(&y.vector, ii))); gsl_vector_set(&ev.vector, ii, a); gsl_vector_set(&ev2.vector, ii, -a); } /* now save the real part */ ev = gsl_vector_complex_real(&ecol.vector); ev2 = gsl_vector_complex_real(&ecol2.vector); for (ii = 0; ii < N; ++ii) { double a = gsl_vector_get(&y.vector, ii); gsl_vector_set(&ev.vector, ii, a); gsl_vector_set(&ev2.vector, ii, a); } if (scale != 0.0) scale = 1.0 / scale; /* scale by largest element magnitude */ gsl_blas_zdscal(scale, &ecol.vector); gsl_blas_zdscal(scale, &ecol2.vector); /* * decrement i since we took care of two eigenvalues at * the same time */ --i; } /* if (GSL_IMAG(lambda) != 0.0) */ } /* for (i = (int) N - 1; i >= 0; --i) */ } /* nonsymmv_get_right_eigenvectors() */ /* nonsymmv_normalize_eigenvectors() Normalize eigenvectors so that their Euclidean norm is 1 Inputs: eval - eigenvalues evec - eigenvectors */ static void nonsymmv_normalize_eigenvectors(gsl_vector_complex *eval, gsl_matrix_complex *evec) { const size_t N = evec->size1; size_t i; /* looping */ gsl_complex ei; gsl_vector_complex_view vi; gsl_vector_view re, im; double scale; /* scaling factor */ for (i = 0; i < N; ++i) { ei = gsl_vector_complex_get(eval, i); vi = gsl_matrix_complex_column(evec, i); re = gsl_vector_complex_real(&vi.vector); if (GSL_IMAG(ei) == 0.0) { scale = 1.0 / gsl_blas_dnrm2(&re.vector); gsl_blas_dscal(scale, &re.vector); } else if (GSL_IMAG(ei) > 0.0) { im = gsl_vector_complex_imag(&vi.vector); scale = 1.0 / gsl_hypot(gsl_blas_dnrm2(&re.vector), gsl_blas_dnrm2(&im.vector)); gsl_blas_zdscal(scale, &vi.vector); vi = gsl_matrix_complex_column(evec, i + 1); gsl_blas_zdscal(scale, &vi.vector); } } } /* nonsymmv_normalize_eigenvectors() */ praat-6.0.04/external/gsl/gsl_eigen__qrstep.c000066400000000000000000000077071261542461700211770ustar00rootroot00000000000000/* eigen/qrstep.c * * Copyright (C) 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* remove off-diagonal elements which are neglegible compared with the neighboring diagonal elements */ static void chop_small_elements (const size_t N, const double d[], double sd[]) { double d_i = d[0]; size_t i; for (i = 0; i < N - 1; i++) { double sd_i = sd[i]; double d_ip1 = d[i + 1]; if (fabs (sd_i) < GSL_DBL_EPSILON * (fabs (d_i) + fabs (d_ip1))) { sd[i] = 0.0; } d_i = d_ip1; } } /* Generate a Givens rotation (cos,sin) which takes v=(x,y) to (|v|,0) From Golub and Van Loan, "Matrix Computations", Section 5.1.8 */ inline static void create_givens (const double a, const double b, double *c, double *s) { if (b == 0) { *c = 1; *s = 0; } else if (fabs (b) > fabs (a)) { double t = -a / b; double s1 = 1.0 / sqrt (1 + t * t); *s = s1; *c = s1 * t; } else { double t = -b / a; double c1 = 1.0 / sqrt (1 + t * t); *c = c1; *s = c1 * t; } } inline static double trailing_eigenvalue (const size_t n, const double d[], const double sd[]) { double ta = d[n - 2]; double tb = d[n - 1]; double tab = sd[n - 2]; double dt = (ta - tb) / 2.0; double mu; if (dt > 0) { mu = tb - tab * (tab / (dt + hypot (dt, tab))); } else if (dt == 0) { mu = tb - fabs(tab); } else { mu = tb + tab * (tab / ((-dt) + hypot (dt, tab))); } return mu; } static void qrstep (const size_t n, double d[], double sd[], double gc[], double gs[]) { double x, z; double ak, bk, zk, ap, bp, aq, bq; size_t k; double mu = trailing_eigenvalue (n, d, sd); x = d[0] - mu; z = sd[0]; ak = 0; bk = 0; zk = 0; ap = d[0]; bp = sd[0]; aq = d[1]; if (n == 2) { double c, s; create_givens (x, z, &c, &s); if (gc != NULL) gc[0] = c; if (gs != NULL) gs[0] = s; { double ap1 = c * (c * ap - s * bp) + s * (s * aq - c * bp); double bp1 = c * (s * ap + c * bp) - s * (s * bp + c * aq); double aq1 = s * (s * ap + c * bp) + c * (s * bp + c * aq); ak = ap1; bk = bp1; ap = aq1; } d[0] = ak; sd[0] = bk; d[1] = ap; return; } bq = sd[1]; for (k = 0; k < n - 1; k++) { double c, s; create_givens (x, z, &c, &s); /* store Givens rotation */ if (gc != NULL) gc[k] = c; if (gs != NULL) gs[k] = s; /* compute G' T G */ { double bk1 = c * bk - s * zk; double ap1 = c * (c * ap - s * bp) + s * (s * aq - c * bp); double bp1 = c * (s * ap + c * bp) - s * (s * bp + c * aq); double zp1 = -s * bq; double aq1 = s * (s * ap + c * bp) + c * (s * bp + c * aq); double bq1 = c * bq; ak = ap1; bk = bp1; zk = zp1; ap = aq1; bp = bq1; if (k < n - 2) aq = d[k + 2]; if (k < n - 3) bq = sd[k + 2]; d[k] = ak; if (k > 0) sd[k - 1] = bk1; if (k < n - 2) sd[k + 1] = bp; x = bk; z = zk; } } /* k = n - 1 */ d[k] = ap; sd[k - 1] = bk; } praat-6.0.04/external/gsl/gsl_eigen__schur.c000066400000000000000000000527511261542461700210040ustar00rootroot00000000000000/* eigen/schur.c * * Copyright (C) 2006, 2007 Patrick Alken * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_eigen.h" #include "gsl_math.h" #include "gsl_matrix.h" #include "gsl_vector.h" #include "gsl_vector_complex.h" #include "gsl_blas.h" #include "gsl_complex.h" #include "gsl_complex_math.h" /* * This module contains some routines related to manipulating the * Schur form of a matrix which are needed by the eigenvalue solvers * * This file contains routines based on original code from LAPACK * which is distributed under the modified BSD license. */ #define GSL_SCHUR_SMLNUM (2.0 * GSL_DBL_MIN) #define GSL_SCHUR_BIGNUM ((1.0 - GSL_DBL_EPSILON) / GSL_SCHUR_SMLNUM) /* gsl_schur_gen_eigvals() Compute the eigenvalues of a 2-by-2 generalized block. Inputs: A - 2-by-2 matrix B - 2-by-2 upper triangular matrix wr1 - (output) see notes wr2 - (output) see notes wi - (output) see notes scale1 - (output) see notes scale2 - (output) see notes Return: success Notes: 1) If the block contains real eigenvalues, then wi is set to 0, and wr1, wr2, scale1, and scale2 are set such that: eval1 = wr1 * scale1 eval2 = wr2 * scale2 If the block contains complex eigenvalues, then wr1, wr2, scale1, scale2, and wi are set such that: wr1 = wr2 = scale1 * Re(eval) wi = scale1 * Im(eval) wi is always non-negative 2) This routine is based on LAPACK DLAG2 */ int gsl_schur_gen_eigvals(const gsl_matrix *A, const gsl_matrix *B, double *wr1, double *wr2, double *wi, double *scale1, double *scale2) { const double safemin = GSL_DBL_MIN * 1.0e2; const double safemax = 1.0 / safemin; const double rtmin = sqrt(safemin); const double rtmax = 1.0 / rtmin; double anorm, bnorm; double ascale, bscale, bsize; double s1, s2; double A11, A12, A21, A22; double B11, B12, B22; double binv11, binv22; double bmin; double as11, as12, as22, abi22; double pp, qq, shift, ss, discr, r; /* scale A */ anorm = GSL_MAX(GSL_MAX(fabs(gsl_matrix_get(A, 0, 0)) + fabs(gsl_matrix_get(A, 1, 0)), fabs(gsl_matrix_get(A, 0, 1)) + fabs(gsl_matrix_get(A, 1, 1))), safemin); ascale = 1.0 / anorm; A11 = ascale * gsl_matrix_get(A, 0, 0); A12 = ascale * gsl_matrix_get(A, 0, 1); A21 = ascale * gsl_matrix_get(A, 1, 0); A22 = ascale * gsl_matrix_get(A, 1, 1); /* perturb B if necessary to ensure non-singularity */ B11 = gsl_matrix_get(B, 0, 0); B12 = gsl_matrix_get(B, 0, 1); B22 = gsl_matrix_get(B, 1, 1); bmin = rtmin * GSL_MAX(fabs(B11), GSL_MAX(fabs(B12), GSL_MAX(fabs(B22), rtmin))); if (fabs(B11) < bmin) B11 = GSL_SIGN(B11) * bmin; if (fabs(B22) < bmin) B22 = GSL_SIGN(B22) * bmin; /* scale B */ bnorm = GSL_MAX(fabs(B11), GSL_MAX(fabs(B12) + fabs(B22), safemin)); bsize = GSL_MAX(fabs(B11), fabs(B22)); bscale = 1.0 / bsize; B11 *= bscale; B12 *= bscale; B22 *= bscale; /* compute larger eigenvalue */ binv11 = 1.0 / B11; binv22 = 1.0 / B22; s1 = A11 * binv11; s2 = A22 * binv22; if (fabs(s1) <= fabs(s2)) { as12 = A12 - s1 * B12; as22 = A22 - s1 * B22; ss = A21 * (binv11 * binv22); abi22 = as22 * binv22 - ss * B12; pp = 0.5 * abi22; shift = s1; } else { as12 = A12 - s2 * B12; as11 = A11 - s2 * B11; ss = A21 * (binv11 * binv22); abi22 = -ss * B12; pp = 0.5 * (as11 * binv11 + abi22); shift = s2; } qq = ss * as12; if (fabs(pp * rtmin) >= 1.0) { discr = (rtmin * pp) * (rtmin * pp) + qq * safemin; r = sqrt(fabs(discr)) * rtmax; } else if (pp * pp + fabs(qq) <= safemin) { discr = (rtmax * pp) * (rtmax * pp) + qq * safemax; r = sqrt(fabs(discr)) * rtmin; } else { discr = pp * pp + qq; r = sqrt(fabs(discr)); } if (discr >= 0.0 || r == 0.0) { double sum = pp + GSL_SIGN(pp) * r; double diff = pp - GSL_SIGN(pp) * r; double wbig = shift + sum; double wsmall = shift + diff; /* compute smaller eigenvalue */ if (0.5 * fabs(wbig) > GSL_MAX(fabs(wsmall), safemin)) { double wdet = (A11*A22 - A12*A21) * (binv11 * binv22); wsmall = wdet / wbig; } /* choose (real) eigenvalue closest to 2,2 element of AB^{-1} for wr1 */ if (pp > abi22) { *wr1 = GSL_MIN(wbig, wsmall); *wr2 = GSL_MAX(wbig, wsmall); } else { *wr1 = GSL_MAX(wbig, wsmall); *wr2 = GSL_MIN(wbig, wsmall); } *wi = 0.0; } else { /* complex eigenvalues */ *wr1 = shift + pp; *wr2 = *wr1; *wi = r; } /* compute scaling */ { const double fuzzy1 = 1.0 + 1.0e-5; double c1, c2, c3, c4, c5; double wabs, wsize, wscale; c1 = bsize * (safemin * GSL_MAX(1.0, ascale)); c2 = safemin * GSL_MAX(1.0, bnorm); c3 = bsize * safemin; if (ascale <= 1.0 && bsize <= 1.0) c4 = GSL_MIN(1.0, (ascale / safemin) * bsize); else c4 = 1.0; if (ascale <= 1.0 || bsize <= 1.0) c5 = GSL_MIN(1.0, ascale * bsize); else c5 = 1.0; /* scale first eigenvalue */ wabs = fabs(*wr1) + fabs(*wi); wsize = GSL_MAX(safemin, GSL_MAX(c1, GSL_MAX(fuzzy1 * (wabs*c2 + c3), GSL_MIN(c4, 0.5 * GSL_MAX(wabs, c5))))); if (wsize != 1.0) { wscale = 1.0 / wsize; if (wsize > 1.0) { *scale1 = (GSL_MAX(ascale, bsize) * wscale) * GSL_MIN(ascale, bsize); } else { *scale1 = (GSL_MIN(ascale, bsize) * wscale) * GSL_MAX(ascale, bsize); } *wr1 *= wscale; if (*wi != 0.0) { *wi *= wscale; *wr2 = *wr1; *scale2 = *scale1; } } else { *scale1 = ascale * bsize; *scale2 = *scale1; } /* scale second eigenvalue if real */ if (*wi == 0.0) { wsize = GSL_MAX(safemin, GSL_MAX(c1, GSL_MAX(fuzzy1 * (fabs(*wr2) * c2 + c3), GSL_MIN(c4, 0.5 * GSL_MAX(fabs(*wr2), c5))))); if (wsize != 1.0) { wscale = 1.0 / wsize; if (wsize > 1.0) { *scale2 = (GSL_MAX(ascale, bsize) * wscale) * GSL_MIN(ascale, bsize); } else { *scale2 = (GSL_MIN(ascale, bsize) * wscale) * GSL_MAX(ascale, bsize); } *wr2 *= wscale; } else { *scale2 = ascale * bsize; } } } return GSL_SUCCESS; } /* gsl_schur_gen_eigvals() */ /* gsl_schur_solve_equation() Solve the equation which comes up in the back substitution when computing eigenvectors corresponding to real eigenvalues. The equation that is solved is: (ca*A - z*D)*x = s*b where A is n-by-n with n = 1 or 2 D is a n-by-n diagonal matrix b and x are n-by-1 real vectors s is a scaling factor set by this function to prevent overflow in x Inputs: ca - coefficient multiplying A A - square matrix (n-by-n) z - real scalar (eigenvalue) d1 - (1,1) element in diagonal matrix D d2 - (2,2) element in diagonal matrix D b - right hand side vector x - (output) where to store solution s - (output) scale factor xnorm - (output) infinity norm of X smin - lower bound on singular values of A - if ca*A - z*D is less than this value, we'll use smin*I instead. This value should be a safe distance above underflow. Return: success Notes: 1) A and b are not changed on output 2) Based on lapack routine DLALN2 */ int gsl_schur_solve_equation(double ca, const gsl_matrix *A, double z, double d1, double d2, const gsl_vector *b, gsl_vector *x, double *s, double *xnorm, double smin) { size_t N = A->size1; double bnorm; double scale = 1.0; if (N == 1) { double c, /* denominator */ cnorm; /* |c| */ /* we have a 1-by-1 (real) scalar system to solve */ c = ca * gsl_matrix_get(A, 0, 0) - z * d1; cnorm = fabs(c); if (cnorm < smin) { /* set c = smin*I */ c = smin; cnorm = smin; } /* check scaling for x = b / c */ bnorm = fabs(gsl_vector_get(b, 0)); if (cnorm < 1.0 && bnorm > 1.0) { if (bnorm > GSL_SCHUR_BIGNUM*cnorm) scale = 1.0 / bnorm; } /* compute x */ gsl_vector_set(x, 0, gsl_vector_get(b, 0) * scale / c); *xnorm = fabs(gsl_vector_get(x, 0)); } /* if (N == 1) */ else { double cr[2][2]; double *crv; double cmax; size_t icmax, j; double bval1, bval2; double ur11, ur12, ur22, ur11r; double cr21, cr22; double lr21; double b1, b2, bbnd; double x1, x2; double temp; size_t ipivot[4][4] = { { 0, 1, 2, 3 }, { 1, 0, 3, 2 }, { 2, 3, 0, 1 }, { 3, 2, 1, 0 } }; int rswap[4] = { 0, 1, 0, 1 }; int zswap[4] = { 0, 0, 1, 1 }; /* * we have a 2-by-2 real system to solve: * * ( ca * [ A11 A12 ] - z * [ D1 0 ] ) [ x1 ] = [ b1 ] * ( [ A21 A22 ] [ 0 D2 ] ) [ x2 ] [ b2 ] * * (z real) */ crv = (double *) cr; /* * compute the real part of C = ca*A - z*D - use column ordering * here since porting from lapack */ cr[0][0] = ca * gsl_matrix_get(A, 0, 0) - z * d1; cr[1][1] = ca * gsl_matrix_get(A, 1, 1) - z * d2; cr[0][1] = ca * gsl_matrix_get(A, 1, 0); cr[1][0] = ca * gsl_matrix_get(A, 0, 1); /* find the largest element in C */ cmax = 0.0; icmax = 0; for (j = 0; j < 4; ++j) { if (fabs(crv[j]) > cmax) { cmax = fabs(crv[j]); icmax = j; } } bval1 = gsl_vector_get(b, 0); bval2 = gsl_vector_get(b, 1); /* if norm(C) < smin, use smin*I */ if (cmax < smin) { bnorm = GSL_MAX(fabs(bval1), fabs(bval2)); if (smin < 1.0 && bnorm > 1.0) { if (bnorm > GSL_SCHUR_BIGNUM*smin) scale = 1.0 / bnorm; } temp = scale / smin; gsl_vector_set(x, 0, temp * bval1); gsl_vector_set(x, 1, temp * bval2); *xnorm = temp * bnorm; *s = scale; return GSL_SUCCESS; } /* gaussian elimination with complete pivoting */ ur11 = crv[icmax]; cr21 = crv[ipivot[1][icmax]]; ur12 = crv[ipivot[2][icmax]]; cr22 = crv[ipivot[3][icmax]]; ur11r = 1.0 / ur11; lr21 = ur11r * cr21; ur22 = cr22 - ur12 * lr21; /* if smaller pivot < smin, use smin */ if (fabs(ur22) < smin) ur22 = smin; if (rswap[icmax]) { b1 = bval2; b2 = bval1; } else { b1 = bval1; b2 = bval2; } b2 -= lr21 * b1; bbnd = GSL_MAX(fabs(b1 * (ur22 * ur11r)), fabs(b2)); if (bbnd > 1.0 && fabs(ur22) < 1.0) { if (bbnd >= GSL_SCHUR_BIGNUM * fabs(ur22)) scale = 1.0 / bbnd; } x2 = (b2 * scale) / ur22; x1 = (scale * b1) * ur11r - x2 * (ur11r * ur12); if (zswap[icmax]) { gsl_vector_set(x, 0, x2); gsl_vector_set(x, 1, x1); } else { gsl_vector_set(x, 0, x1); gsl_vector_set(x, 1, x2); } *xnorm = GSL_MAX(fabs(x1), fabs(x2)); /* further scaling if norm(A) norm(X) > overflow */ if (*xnorm > 1.0 && cmax > 1.0) { if (*xnorm > GSL_SCHUR_BIGNUM / cmax) { temp = cmax / GSL_SCHUR_BIGNUM; gsl_blas_dscal(temp, x); *xnorm *= temp; scale *= temp; } } } /* if (N == 2) */ *s = scale; return GSL_SUCCESS; } /* gsl_schur_solve_equation() */ /* gsl_schur_solve_equation_z() Solve the equation which comes up in the back substitution when computing eigenvectors corresponding to complex eigenvalues. The equation that is solved is: (ca*A - z*D)*x = s*b where A is n-by-n with n = 1 or 2 D is a n-by-n diagonal matrix b and x are n-by-1 complex vectors s is a scaling factor set by this function to prevent overflow in x Inputs: ca - coefficient multiplying A A - square matrix (n-by-n) z - complex scalar (eigenvalue) d1 - (1,1) element in diagonal matrix D d2 - (2,2) element in diagonal matrix D b - right hand side vector x - (output) where to store solution s - (output) scale factor xnorm - (output) infinity norm of X smin - lower bound on singular values of A - if ca*A - z*D is less than this value, we'll use smin*I instead. This value should be a safe distance above underflow. Notes: 1) A and b are not changed on output 2) Based on lapack routine DLALN2 */ int gsl_schur_solve_equation_z(double ca, const gsl_matrix *A, gsl_complex *z, double d1, double d2, const gsl_vector_complex *b, gsl_vector_complex *x, double *s, double *xnorm, double smin) { size_t N = A->size1; double scale = 1.0; double bnorm; if (N == 1) { double cr, /* denominator */ ci, cnorm; /* |c| */ gsl_complex bval, c, xval, tmp; /* we have a 1-by-1 (complex) scalar system to solve */ /* c = ca*a - z*d1 */ cr = ca * gsl_matrix_get(A, 0, 0) - GSL_REAL(*z) * d1; ci = -GSL_IMAG(*z) * d1; cnorm = fabs(cr) + fabs(ci); if (cnorm < smin) { /* set c = smin*I */ cr = smin; ci = 0.0; cnorm = smin; } /* check scaling for x = b / c */ bval = gsl_vector_complex_get(b, 0); bnorm = fabs(GSL_REAL(bval)) + fabs(GSL_IMAG(bval)); if (cnorm < 1.0 && bnorm > 1.0) { if (bnorm > GSL_SCHUR_BIGNUM*cnorm) scale = 1.0 / bnorm; } /* compute x */ GSL_SET_COMPLEX(&tmp, scale*GSL_REAL(bval), scale*GSL_IMAG(bval)); GSL_SET_COMPLEX(&c, cr, ci); xval = gsl_complex_div(tmp, c); gsl_vector_complex_set(x, 0, xval); *xnorm = fabs(GSL_REAL(xval)) + fabs(GSL_IMAG(xval)); } /* if (N == 1) */ else { double cr[2][2], ci[2][2]; double *civ, *crv; double cmax; gsl_complex bval1, bval2; gsl_complex xval1, xval2; double xr1, xi1; size_t icmax; size_t j; double temp; double ur11, ur12, ur22, ui11, ui12, ui22, ur11r, ui11r; double ur12s, ui12s; double u22abs; double lr21, li21; double cr21, cr22, ci21, ci22; double br1, bi1, br2, bi2, bbnd; gsl_complex b1, b2; size_t ipivot[4][4] = { { 0, 1, 2, 3 }, { 1, 0, 3, 2 }, { 2, 3, 0, 1 }, { 3, 2, 1, 0 } }; int rswap[4] = { 0, 1, 0, 1 }; int zswap[4] = { 0, 0, 1, 1 }; /* * complex 2-by-2 system: * * ( ca * [ A11 A12 ] - z * [ D1 0 ] ) [ X1 ] = [ B1 ] * ( [ A21 A22 ] [ 0 D2] ) [ X2 ] [ B2 ] * * (z complex) * * where the X and B values are complex. */ civ = (double *) ci; crv = (double *) cr; /* * compute the real part of C = ca*A - z*D - use column ordering * here since porting from lapack */ cr[0][0] = ca*gsl_matrix_get(A, 0, 0) - GSL_REAL(*z)*d1; cr[1][1] = ca*gsl_matrix_get(A, 1, 1) - GSL_REAL(*z)*d2; cr[0][1] = ca*gsl_matrix_get(A, 1, 0); cr[1][0] = ca*gsl_matrix_get(A, 0, 1); /* compute the imaginary part */ ci[0][0] = -GSL_IMAG(*z) * d1; ci[0][1] = 0.0; ci[1][0] = 0.0; ci[1][1] = -GSL_IMAG(*z) * d2; cmax = 0.0; icmax = 0; for (j = 0; j < 4; ++j) { if (fabs(crv[j]) + fabs(civ[j]) > cmax) { cmax = fabs(crv[j]) + fabs(civ[j]); icmax = j; } } bval1 = gsl_vector_complex_get(b, 0); bval2 = gsl_vector_complex_get(b, 1); /* if norm(C) < smin, use smin*I */ if (cmax < smin) { bnorm = GSL_MAX(fabs(GSL_REAL(bval1)) + fabs(GSL_IMAG(bval1)), fabs(GSL_REAL(bval2)) + fabs(GSL_IMAG(bval2))); if (smin < 1.0 && bnorm > 1.0) { if (bnorm > GSL_SCHUR_BIGNUM*smin) scale = 1.0 / bnorm; } temp = scale / smin; xval1 = gsl_complex_mul_real(bval1, temp); xval2 = gsl_complex_mul_real(bval2, temp); gsl_vector_complex_set(x, 0, xval1); gsl_vector_complex_set(x, 1, xval2); *xnorm = temp * bnorm; *s = scale; return GSL_SUCCESS; } /* gaussian elimination with complete pivoting */ ur11 = crv[icmax]; ui11 = civ[icmax]; cr21 = crv[ipivot[1][icmax]]; ci21 = civ[ipivot[1][icmax]]; ur12 = crv[ipivot[2][icmax]]; ui12 = civ[ipivot[2][icmax]]; cr22 = crv[ipivot[3][icmax]]; ci22 = civ[ipivot[3][icmax]]; if (icmax == 0 || icmax == 3) { /* off diagonals of pivoted C are real */ if (fabs(ur11) > fabs(ui11)) { temp = ui11 / ur11; ur11r = 1.0 / (ur11 * (1.0 + temp*temp)); ui11r = -temp * ur11r; } else { temp = ur11 / ui11; ui11r = -1.0 / (ui11 * (1.0 + temp*temp)); ur11r = -temp*ui11r; } lr21 = cr21 * ur11r; li21 = cr21 * ui11r; ur12s = ur12 * ur11r; ui12s = ur12 * ui11r; ur22 = cr22 - ur12 * lr21; ui22 = ci22 - ur12 * li21; } else { /* diagonals of pivoted C are real */ ur11r = 1.0 / ur11; ui11r = 0.0; lr21 = cr21 * ur11r; li21 = ci21 * ur11r; ur12s = ur12 * ur11r; ui12s = ui12 * ur11r; ur22 = cr22 - ur12 * lr21 + ui12 * li21; ui22 = -ur12 * li21 - ui12 * lr21; } u22abs = fabs(ur22) + fabs(ui22); /* if smaller pivot < smin, use smin */ if (u22abs < smin) { ur22 = smin; ui22 = 0.0; } if (rswap[icmax]) { br2 = GSL_REAL(bval1); bi2 = GSL_IMAG(bval1); br1 = GSL_REAL(bval2); bi1 = GSL_IMAG(bval2); } else { br1 = GSL_REAL(bval1); bi1 = GSL_IMAG(bval1); br2 = GSL_REAL(bval2); bi2 = GSL_IMAG(bval2); } br2 += li21*bi1 - lr21*br1; bi2 -= li21*br1 + lr21*bi1; bbnd = GSL_MAX((fabs(br1) + fabs(bi1)) * (u22abs * (fabs(ur11r) + fabs(ui11r))), fabs(br2) + fabs(bi2)); if (bbnd > 1.0 && u22abs < 1.0) { if (bbnd >= GSL_SCHUR_BIGNUM*u22abs) { scale = 1.0 / bbnd; br1 *= scale; bi1 *= scale; br2 *= scale; bi2 *= scale; } } GSL_SET_COMPLEX(&b1, br2, bi2); GSL_SET_COMPLEX(&b2, ur22, ui22); xval2 = gsl_complex_div(b1, b2); xr1 = ur11r*br1 - ui11r*bi1 - ur12s*GSL_REAL(xval2) + ui12s*GSL_IMAG(xval2); xi1 = ui11r*br1 + ur11r*bi1 - ui12s*GSL_REAL(xval2) - ur12s*GSL_IMAG(xval2); GSL_SET_COMPLEX(&xval1, xr1, xi1); if (zswap[icmax]) { gsl_vector_complex_set(x, 0, xval2); gsl_vector_complex_set(x, 1, xval1); } else { gsl_vector_complex_set(x, 0, xval1); gsl_vector_complex_set(x, 1, xval2); } *xnorm = GSL_MAX(fabs(GSL_REAL(xval1)) + fabs(GSL_IMAG(xval1)), fabs(GSL_REAL(xval2)) + fabs(GSL_IMAG(xval2))); /* further scaling if norm(A) norm(X) > overflow */ if (*xnorm > 1.0 && cmax > 1.0) { if (*xnorm > GSL_SCHUR_BIGNUM / cmax) { temp = cmax / GSL_SCHUR_BIGNUM; gsl_blas_zdscal(temp, x); *xnorm *= temp; scale *= temp; } } } /* if (N == 2) */ *s = scale; return GSL_SUCCESS; } /* gsl_schur_solve_equation_z() */ praat-6.0.04/external/gsl/gsl_eigen__sort.c000066400000000000000000000226311261542461700206410ustar00rootroot00000000000000/* eigen/sort.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2006, 2007 Gerard Jungman, Patrick Alken * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman, Modified: B. Gough. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_eigen.h" #include "gsl_complex.h" #include "gsl_complex_math.h" /* The eigen_sort below is not very good, but it is simple and * self-contained. We can always implement an improved sort later. */ int gsl_eigen_symmv_sort (gsl_vector * eval, gsl_matrix * evec, gsl_eigen_sort_t sort_type) { if (evec->size1 != evec->size2) { GSL_ERROR ("eigenvector matrix must be square", GSL_ENOTSQR); } else if (eval->size != evec->size1) { GSL_ERROR ("eigenvalues must match eigenvector matrix", GSL_EBADLEN); } else { const size_t N = eval->size; size_t i; for (i = 0; i < N - 1; i++) { size_t j; size_t k = i; double ek = gsl_vector_get (eval, i); /* search for something to swap */ for (j = i + 1; j < N; j++) { int test; const double ej = gsl_vector_get (eval, j); switch (sort_type) { case GSL_EIGEN_SORT_VAL_ASC: test = (ej < ek); break; case GSL_EIGEN_SORT_VAL_DESC: test = (ej > ek); break; case GSL_EIGEN_SORT_ABS_ASC: test = (fabs (ej) < fabs (ek)); break; case GSL_EIGEN_SORT_ABS_DESC: test = (fabs (ej) > fabs (ek)); break; default: GSL_ERROR ("unrecognized sort type", GSL_EINVAL); } if (test) { k = j; ek = ej; } } if (k != i) { /* swap eigenvalues */ gsl_vector_swap_elements (eval, i, k); /* swap eigenvectors */ gsl_matrix_swap_columns (evec, i, k); } } return GSL_SUCCESS; } } int gsl_eigen_hermv_sort (gsl_vector * eval, gsl_matrix_complex * evec, gsl_eigen_sort_t sort_type) { if (evec->size1 != evec->size2) { GSL_ERROR ("eigenvector matrix must be square", GSL_ENOTSQR); } else if (eval->size != evec->size1) { GSL_ERROR ("eigenvalues must match eigenvector matrix", GSL_EBADLEN); } else { const size_t N = eval->size; size_t i; for (i = 0; i < N - 1; i++) { size_t j; size_t k = i; double ek = gsl_vector_get (eval, i); /* search for something to swap */ for (j = i + 1; j < N; j++) { int test; const double ej = gsl_vector_get (eval, j); switch (sort_type) { case GSL_EIGEN_SORT_VAL_ASC: test = (ej < ek); break; case GSL_EIGEN_SORT_VAL_DESC: test = (ej > ek); break; case GSL_EIGEN_SORT_ABS_ASC: test = (fabs (ej) < fabs (ek)); break; case GSL_EIGEN_SORT_ABS_DESC: test = (fabs (ej) > fabs (ek)); break; default: GSL_ERROR ("unrecognized sort type", GSL_EINVAL); } if (test) { k = j; ek = ej; } } if (k != i) { /* swap eigenvalues */ gsl_vector_swap_elements (eval, i, k); /* swap eigenvectors */ gsl_matrix_complex_swap_columns (evec, i, k); } } return GSL_SUCCESS; } } int gsl_eigen_nonsymmv_sort (gsl_vector_complex * eval, gsl_matrix_complex * evec, gsl_eigen_sort_t sort_type) { if (evec && (evec->size1 != evec->size2)) { GSL_ERROR ("eigenvector matrix must be square", GSL_ENOTSQR); } else if (evec && (eval->size != evec->size1)) { GSL_ERROR ("eigenvalues must match eigenvector matrix", GSL_EBADLEN); } else { const size_t N = eval->size; size_t i; for (i = 0; i < N - 1; i++) { size_t j; size_t k = i; gsl_complex ek = gsl_vector_complex_get (eval, i); /* search for something to swap */ for (j = i + 1; j < N; j++) { int test; const gsl_complex ej = gsl_vector_complex_get (eval, j); switch (sort_type) { case GSL_EIGEN_SORT_ABS_ASC: test = (gsl_complex_abs (ej) < gsl_complex_abs (ek)); break; case GSL_EIGEN_SORT_ABS_DESC: test = (gsl_complex_abs (ej) > gsl_complex_abs (ek)); break; case GSL_EIGEN_SORT_VAL_ASC: case GSL_EIGEN_SORT_VAL_DESC: default: GSL_ERROR ("invalid sort type", GSL_EINVAL); } if (test) { k = j; ek = ej; } } if (k != i) { /* swap eigenvalues */ gsl_vector_complex_swap_elements (eval, i, k); /* swap eigenvectors */ if (evec) gsl_matrix_complex_swap_columns (evec, i, k); } } return GSL_SUCCESS; } } int gsl_eigen_gensymmv_sort (gsl_vector * eval, gsl_matrix * evec, gsl_eigen_sort_t sort_type) { int s; s = gsl_eigen_symmv_sort(eval, evec, sort_type); return s; } int gsl_eigen_genhermv_sort (gsl_vector * eval, gsl_matrix_complex * evec, gsl_eigen_sort_t sort_type) { int s; s = gsl_eigen_hermv_sort(eval, evec, sort_type); return s; } int gsl_eigen_genv_sort (gsl_vector_complex * alpha, gsl_vector * beta, gsl_matrix_complex * evec, gsl_eigen_sort_t sort_type) { if (evec->size1 != evec->size2) { GSL_ERROR ("eigenvector matrix must be square", GSL_ENOTSQR); } else if (alpha->size != evec->size1 || beta->size != evec->size1) { GSL_ERROR ("eigenvalues must match eigenvector matrix", GSL_EBADLEN); } else { const size_t N = alpha->size; size_t i; for (i = 0; i < N - 1; i++) { size_t j; size_t k = i; gsl_complex ak = gsl_vector_complex_get (alpha, i); double bk = gsl_vector_get(beta, i); gsl_complex ek; if (bk < GSL_DBL_EPSILON) { GSL_SET_COMPLEX(&ek, GSL_SIGN(GSL_REAL(ak)) ? GSL_POSINF : GSL_NEGINF, GSL_SIGN(GSL_IMAG(ak)) ? GSL_POSINF : GSL_NEGINF); } else ek = gsl_complex_div_real(ak, bk); /* search for something to swap */ for (j = i + 1; j < N; j++) { int test; const gsl_complex aj = gsl_vector_complex_get (alpha, j); double bj = gsl_vector_get(beta, j); gsl_complex ej; if (bj < GSL_DBL_EPSILON) { GSL_SET_COMPLEX(&ej, GSL_SIGN(GSL_REAL(aj)) ? GSL_POSINF : GSL_NEGINF, GSL_SIGN(GSL_IMAG(aj)) ? GSL_POSINF : GSL_NEGINF); } else ej = gsl_complex_div_real(aj, bj); switch (sort_type) { case GSL_EIGEN_SORT_ABS_ASC: test = (gsl_complex_abs (ej) < gsl_complex_abs (ek)); break; case GSL_EIGEN_SORT_ABS_DESC: test = (gsl_complex_abs (ej) > gsl_complex_abs (ek)); break; case GSL_EIGEN_SORT_VAL_ASC: case GSL_EIGEN_SORT_VAL_DESC: default: GSL_ERROR ("invalid sort type", GSL_EINVAL); } if (test) { k = j; ek = ej; } } if (k != i) { /* swap eigenvalues */ gsl_vector_complex_swap_elements (alpha, i, k); gsl_vector_swap_elements (beta, i, k); /* swap eigenvectors */ gsl_matrix_complex_swap_columns (evec, i, k); } } return GSL_SUCCESS; } } praat-6.0.04/external/gsl/gsl_eigen__symm.c000066400000000000000000000111421261542461700206320ustar00rootroot00000000000000/* eigen/symm.c * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_vector.h" #include "gsl_matrix.h" #include "gsl_linalg.h" #include "gsl_eigen.h" /* Compute eigenvalues/eigenvectors of real symmetric matrix using reduction to tridiagonal form, followed by QR iteration with implicit shifts. See Golub & Van Loan, "Matrix Computations" (3rd ed), Section 8.3 */ #include "gsl_eigen__qrstep.c" gsl_eigen_symm_workspace * gsl_eigen_symm_alloc (const size_t n) { gsl_eigen_symm_workspace *w; if (n == 0) { GSL_ERROR_NULL ("matrix dimension must be positive integer", GSL_EINVAL); } w = ((gsl_eigen_symm_workspace *) malloc (sizeof (gsl_eigen_symm_workspace))); if (w == 0) { GSL_ERROR_NULL ("failed to allocate space for workspace", GSL_ENOMEM); } w->d = (double *) malloc (n * sizeof (double)); if (w->d == 0) { GSL_ERROR_NULL ("failed to allocate space for diagonal", GSL_ENOMEM); } w->sd = (double *) malloc (n * sizeof (double)); if (w->sd == 0) { GSL_ERROR_NULL ("failed to allocate space for subdiagonal", GSL_ENOMEM); } w->size = n; return w; } void gsl_eigen_symm_free (gsl_eigen_symm_workspace * w) { free (w->sd); free (w->d); free (w); } int gsl_eigen_symm (gsl_matrix * A, gsl_vector * eval, gsl_eigen_symm_workspace * w) { if (A->size1 != A->size2) { GSL_ERROR ("matrix must be square to compute eigenvalues", GSL_ENOTSQR); } else if (eval->size != A->size1) { GSL_ERROR ("eigenvalue vector must match matrix size", GSL_EBADLEN); } else { const size_t N = A->size1; double *const d = w->d; double *const sd = w->sd; size_t a, b; /* handle special case */ if (N == 1) { double A00 = gsl_matrix_get (A, 0, 0); gsl_vector_set (eval, 0, A00); return GSL_SUCCESS; } /* use sd as the temporary workspace for the decomposition, since we can discard the tau result immediately if we are not computing eigenvectors */ { gsl_vector_view d_vec = gsl_vector_view_array (d, N); gsl_vector_view sd_vec = gsl_vector_view_array (sd, N - 1); gsl_vector_view tau = gsl_vector_view_array (sd, N - 1); gsl_linalg_symmtd_decomp (A, &tau.vector); gsl_linalg_symmtd_unpack_T (A, &d_vec.vector, &sd_vec.vector); } /* Make an initial pass through the tridiagonal decomposition to remove off-diagonal elements which are effectively zero */ chop_small_elements (N, d, sd); /* Progressively reduce the matrix until it is diagonal */ b = N - 1; while (b > 0) { if (sd[b - 1] == 0.0 || isnan(sd[b - 1])) { b--; continue; } /* Find the largest unreduced block (a,b) starting from b and working backwards */ a = b - 1; while (a > 0) { if (sd[a - 1] == 0.0) { break; } a--; } { const size_t n_block = b - a + 1; double *d_block = d + a; double *sd_block = sd + a; /* apply QR reduction with implicit deflation to the unreduced block */ qrstep (n_block, d_block, sd_block, NULL, NULL); /* remove any small off-diagonal elements */ chop_small_elements (n_block, d_block, sd_block); } } { gsl_vector_view d_vec = gsl_vector_view_array (d, N); gsl_vector_memcpy (eval, &d_vec.vector); } return GSL_SUCCESS; } } praat-6.0.04/external/gsl/gsl_eigen__symmv.c000066400000000000000000000134171261542461700210270ustar00rootroot00000000000000/* eigen/symmv.c * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_vector.h" #include "gsl_matrix.h" #include "gsl_linalg.h" #include "gsl_eigen.h" /* Compute eigenvalues/eigenvectors of real symmetric matrix using reduction to tridiagonal form, followed by QR iteration with implicit shifts. See Golub & Van Loan, "Matrix Computations" (3rd ed), Section 8.3 */ #include "gsl_eigen__qrstep.c" gsl_eigen_symmv_workspace * gsl_eigen_symmv_alloc (const size_t n) { gsl_eigen_symmv_workspace * w ; if (n == 0) { GSL_ERROR_NULL ("matrix dimension must be positive integer", GSL_EINVAL); } w= ((gsl_eigen_symmv_workspace *) malloc (sizeof(gsl_eigen_symmv_workspace))); if (w == 0) { GSL_ERROR_NULL ("failed to allocate space for workspace", GSL_ENOMEM); } w->d = (double *) malloc (n * sizeof (double)); if (w->d == 0) { GSL_ERROR_NULL ("failed to allocate space for diagonal", GSL_ENOMEM); } w->sd = (double *) malloc (n * sizeof (double)); if (w->sd == 0) { GSL_ERROR_NULL ("failed to allocate space for subdiagonal", GSL_ENOMEM); } w->gc = (double *) malloc (n * sizeof (double)); if (w->gc == 0) { GSL_ERROR_NULL ("failed to allocate space for cosines", GSL_ENOMEM); } w->gs = (double *) malloc (n * sizeof (double)); if (w->gs == 0) { GSL_ERROR_NULL ("failed to allocate space for sines", GSL_ENOMEM); } w->size = n; return w; } void gsl_eigen_symmv_free (gsl_eigen_symmv_workspace * w) { free(w->gs); free(w->gc); free(w->sd); free(w->d); free(w); } int gsl_eigen_symmv (gsl_matrix * A, gsl_vector * eval, gsl_matrix * evec, gsl_eigen_symmv_workspace * w) { if (A->size1 != A->size2) { GSL_ERROR ("matrix must be square to compute eigenvalues", GSL_ENOTSQR); } else if (eval->size != A->size1) { GSL_ERROR ("eigenvalue vector must match matrix size", GSL_EBADLEN); } else if (evec->size1 != A->size1 || evec->size2 != A->size1) { GSL_ERROR ("eigenvector matrix must match matrix size", GSL_EBADLEN); } else { double *const d = w->d; double *const sd = w->sd; const size_t N = A->size1; size_t a, b; /* handle special case */ if (N == 1) { double A00 = gsl_matrix_get (A, 0, 0); gsl_vector_set (eval, 0, A00); gsl_matrix_set (evec, 0, 0, 1.0); return GSL_SUCCESS; } /* use sd as the temporary workspace for the decomposition when computing eigenvectors */ { gsl_vector_view d_vec = gsl_vector_view_array (d, N); gsl_vector_view sd_vec = gsl_vector_view_array (sd, N - 1); gsl_vector_view tau = gsl_vector_view_array (sd, N - 1); gsl_linalg_symmtd_decomp (A, &tau.vector); gsl_linalg_symmtd_unpack (A, &tau.vector, evec, &d_vec.vector, &sd_vec.vector); } /* Make an initial pass through the tridiagonal decomposition to remove off-diagonal elements which are effectively zero */ chop_small_elements (N, d, sd); /* Progressively reduce the matrix until it is diagonal */ b = N - 1; while (b > 0) { if (sd[b - 1] == 0.0 || isnan(sd[b - 1])) { b--; continue; } /* Find the largest unreduced block (a,b) starting from b and working backwards */ a = b - 1; while (a > 0) { if (sd[a - 1] == 0.0) { break; } a--; } { size_t i; const size_t n_block = b - a + 1; double *d_block = d + a; double *sd_block = sd + a; double * const gc = w->gc; double * const gs = w->gs; /* apply QR reduction with implicit deflation to the unreduced block */ qrstep (n_block, d_block, sd_block, gc, gs); /* Apply Givens rotation Gij(c,s) to matrix Q, Q <- Q G */ for (i = 0; i < n_block - 1; i++) { const double c = gc[i], s = gs[i]; size_t k; for (k = 0; k < N; k++) { double qki = gsl_matrix_get (evec, k, a + i); double qkj = gsl_matrix_get (evec, k, a + i + 1); gsl_matrix_set (evec, k, a + i, qki * c - qkj * s); gsl_matrix_set (evec, k, a + i + 1, qki * s + qkj * c); } } /* remove any small off-diagonal elements */ chop_small_elements (N, d, sd); } } { gsl_vector_view d_vec = gsl_vector_view_array (d, N); gsl_vector_memcpy (eval, &d_vec.vector); } return GSL_SUCCESS; } } praat-6.0.04/external/gsl/gsl_err__error.c000066400000000000000000000040031261542461700204750ustar00rootroot00000000000000/* err/error.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include #include "gsl_errno.h" #include "gsl_message.h" gsl_error_handler_t * gsl_error_handler = NULL; static void no_error_handler (const char *reason, const char *file, int line, int gsl_errno); void gsl_error (const char * reason, const char * file, int line, int gsl_errno) { if (gsl_error_handler) { (*gsl_error_handler) (reason, file, line, gsl_errno); return ; } gsl_stream_printf ("ERROR", file, line, reason); fflush (stdout); fprintf (stderr, "Default GSL error handler invoked.\n"); fflush (stderr); abort (); } gsl_error_handler_t * gsl_set_error_handler (gsl_error_handler_t * new_handler) { gsl_error_handler_t * previous_handler = gsl_error_handler; gsl_error_handler = new_handler; return previous_handler; } gsl_error_handler_t * gsl_set_error_handler_off (void) { gsl_error_handler_t * previous_handler = gsl_error_handler; gsl_error_handler = no_error_handler; return previous_handler; } static void no_error_handler (const char *reason, const char *file, int line, int gsl_errno) { /* do nothing */ reason = 0; file = 0; line = 0; gsl_errno = 0; return; } praat-6.0.04/external/gsl/gsl_err__message.c000066400000000000000000000023041261542461700207720ustar00rootroot00000000000000/* err/message.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include #include "gsl_errno.h" #include "gsl_message.h" unsigned int gsl_message_mask = GSL_MESSAGE_MASK; void gsl_message (const char * reason, const char * file, int line, unsigned int mask) { if (mask & gsl_message_mask) { gsl_stream_printf ("MESSAGE", file, line, reason); } } praat-6.0.04/external/gsl/gsl_err__stream.c000066400000000000000000000034541261542461700206500ustar00rootroot00000000000000/* err/stream.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include #include "gsl_errno.h" #include "gsl_message.h" FILE * gsl_stream = NULL ; gsl_stream_handler_t * gsl_stream_handler = NULL; void gsl_stream_printf (const char *label, const char *file, int line, const char *reason) { if (gsl_stream == NULL) { gsl_stream = stderr; } if (gsl_stream_handler) { (*gsl_stream_handler) (label, file, line, reason); return; } fprintf (gsl_stream, "gsl: %s:%d: %s: %s\n", file, line, label, reason); } gsl_stream_handler_t * gsl_set_stream_handler (gsl_stream_handler_t * new_handler) { gsl_stream_handler_t * previous_handler = gsl_stream_handler; gsl_stream_handler = new_handler; return previous_handler; } FILE * gsl_set_stream (FILE * new_stream) { FILE * previous_stream; if (gsl_stream == NULL) { gsl_stream = stderr; } previous_stream = gsl_stream; gsl_stream = new_stream; return previous_stream; } praat-6.0.04/external/gsl/gsl_err__strerror.c000066400000000000000000000065131261542461700212360ustar00rootroot00000000000000/* err/strerror.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_errno.h" const char * gsl_strerror (const int gsl_errno) { switch (gsl_errno) { case GSL_SUCCESS: return "success" ; case GSL_FAILURE: return "failure" ; case GSL_CONTINUE: return "the iteration has not converged yet"; case GSL_EDOM: return "input domain error" ; case GSL_ERANGE: return "output range error" ; case GSL_EFAULT: return "invalid pointer" ; case GSL_EINVAL: return "invalid argument supplied by user" ; case GSL_EFAILED: return "generic failure" ; case GSL_EFACTOR: return "factorization failed" ; case GSL_ESANITY: return "sanity check failed - shouldn't happen" ; case GSL_ENOMEM: return "malloc failed" ; case GSL_EBADFUNC: return "problem with user-supplied function"; case GSL_ERUNAWAY: return "iterative process is out of control"; case GSL_EMAXITER: return "exceeded max number of iterations" ; case GSL_EZERODIV: return "tried to divide by zero" ; case GSL_EBADTOL: return "specified tolerance is invalid or theoretically unattainable" ; case GSL_ETOL: return "failed to reach the specified tolerance" ; case GSL_EUNDRFLW: return "underflow" ; case GSL_EOVRFLW: return "overflow" ; case GSL_ELOSS: return "loss of accuracy" ; case GSL_EROUND: return "roundoff error" ; case GSL_EBADLEN: return "matrix/vector sizes are not conformant" ; case GSL_ENOTSQR: return "matrix not square" ; case GSL_ESING: return "singularity or extremely bad function behavior detected" ; case GSL_EDIVERGE: return "integral or series is divergent" ; case GSL_EUNSUP: return "the required feature is not supported by this hardware platform"; case GSL_EUNIMPL: return "the requested feature is not (yet) implemented"; case GSL_ECACHE: return "cache limit exceeded"; case GSL_ETABLE: return "table limit exceeded"; case GSL_ENOPROG: return "iteration is not making progress towards solution"; case GSL_ENOPROGJ: return "jacobian evaluations are not improving the solution"; case GSL_ETOLF: return "cannot reach the specified tolerance in F"; case GSL_ETOLX: return "cannot reach the specified tolerance in X"; case GSL_ETOLG: return "cannot reach the specified tolerance in gradient"; case GSL_EOF: return "end of file"; default: return "unknown error code" ; } } praat-6.0.04/external/gsl/gsl_errno.h000066400000000000000000000135111261542461700174730ustar00rootroot00000000000000/* err/gsl_errno.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_ERRNO_H__ #define __GSL_ERRNO_H__ #include #include #include "gsl_types.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS enum { GSL_SUCCESS = 0, GSL_FAILURE = -1, GSL_CONTINUE = -2, /* iteration has not converged */ GSL_EDOM = 1, /* input domain error, e.g sqrt(-1) */ GSL_ERANGE = 2, /* output range error, e.g. exp(1e100) */ GSL_EFAULT = 3, /* invalid pointer */ GSL_EINVAL = 4, /* invalid argument supplied by user */ GSL_EFAILED = 5, /* generic failure */ GSL_EFACTOR = 6, /* factorization failed */ GSL_ESANITY = 7, /* sanity check failed - shouldn't happen */ GSL_ENOMEM = 8, /* malloc failed */ GSL_EBADFUNC = 9, /* problem with user-supplied function */ GSL_ERUNAWAY = 10, /* iterative process is out of control */ GSL_EMAXITER = 11, /* exceeded max number of iterations */ GSL_EZERODIV = 12, /* tried to divide by zero */ GSL_EBADTOL = 13, /* user specified an invalid tolerance */ GSL_ETOL = 14, /* failed to reach the specified tolerance */ GSL_EUNDRFLW = 15, /* underflow */ GSL_EOVRFLW = 16, /* overflow */ GSL_ELOSS = 17, /* loss of accuracy */ GSL_EROUND = 18, /* failed because of roundoff error */ GSL_EBADLEN = 19, /* matrix, vector lengths are not conformant */ GSL_ENOTSQR = 20, /* matrix not square */ GSL_ESING = 21, /* apparent singularity detected */ GSL_EDIVERGE = 22, /* integral or series is divergent */ GSL_EUNSUP = 23, /* requested feature is not supported by the hardware */ GSL_EUNIMPL = 24, /* requested feature not (yet) implemented */ GSL_ECACHE = 25, /* cache limit exceeded */ GSL_ETABLE = 26, /* table limit exceeded */ GSL_ENOPROG = 27, /* iteration is not making progress towards solution */ GSL_ENOPROGJ = 28, /* jacobian evaluations are not improving the solution */ GSL_ETOLF = 29, /* cannot reach the specified tolerance in F */ GSL_ETOLX = 30, /* cannot reach the specified tolerance in X */ GSL_ETOLG = 31, /* cannot reach the specified tolerance in gradient */ GSL_EOF = 32 /* end of file */ } ; void gsl_error (const char * reason, const char * file, int line, int gsl_errno); void gsl_stream_printf (const char *label, const char *file, int line, const char *reason); const char * gsl_strerror (const int gsl_errno); typedef void gsl_error_handler_t (const char * reason, const char * file, int line, int gsl_errno); typedef void gsl_stream_handler_t (const char * label, const char * file, int line, const char * reason); gsl_error_handler_t * gsl_set_error_handler (gsl_error_handler_t * new_handler); gsl_error_handler_t * gsl_set_error_handler_off (void); gsl_stream_handler_t * gsl_set_stream_handler (gsl_stream_handler_t * new_handler); FILE * gsl_set_stream (FILE * new_stream); /* GSL_ERROR: call the error handler, and return the error code */ #define GSL_ERROR(reason, gsl_errno) \ do { \ gsl_error (reason, __FILE__, __LINE__, gsl_errno) ; \ return gsl_errno ; \ } while (0) /* GSL_ERROR_VAL: call the error handler, and return the given value */ #define GSL_ERROR_VAL(reason, gsl_errno, value) \ do { \ gsl_error (reason, __FILE__, __LINE__, gsl_errno) ; \ return value ; \ } while (0) /* GSL_ERROR_VOID: call the error handler, and then return (for void functions which still need to generate an error) */ #define GSL_ERROR_VOID(reason, gsl_errno) \ do { \ gsl_error (reason, __FILE__, __LINE__, gsl_errno) ; \ return ; \ } while (0) /* GSL_ERROR_NULL suitable for out-of-memory conditions */ #define GSL_ERROR_NULL(reason, gsl_errno) GSL_ERROR_VAL(reason, gsl_errno, 0) /* Sometimes you have several status results returned from * function calls and you want to combine them in some sensible * way. You cannot produce a "total" status condition, but you can * pick one from a set of conditions based on an implied hierarchy. * * In other words: * you have: status_a, status_b, ... * you want: status = (status_a if it is bad, or status_b if it is bad,...) * * In this example you consider status_a to be more important and * it is checked first, followed by the others in the order specified. * * Here are some dumb macros to do this. */ #define GSL_ERROR_SELECT_2(a,b) ((a) != GSL_SUCCESS ? (a) : ((b) != GSL_SUCCESS ? (b) : GSL_SUCCESS)) #define GSL_ERROR_SELECT_3(a,b,c) ((a) != GSL_SUCCESS ? (a) : GSL_ERROR_SELECT_2(b,c)) #define GSL_ERROR_SELECT_4(a,b,c,d) ((a) != GSL_SUCCESS ? (a) : GSL_ERROR_SELECT_3(b,c,d)) #define GSL_ERROR_SELECT_5(a,b,c,d,e) ((a) != GSL_SUCCESS ? (a) : GSL_ERROR_SELECT_4(b,c,d,e)) #define GSL_STATUS_UPDATE(sp, s) do { if ((s) != GSL_SUCCESS) *(sp) = (s);} while(0) __END_DECLS #endif /* __GSL_ERRNO_H__ */ praat-6.0.04/external/gsl/gsl_fft.h000066400000000000000000000030411261542461700171220ustar00rootroot00000000000000/* fft/gsl_fft.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_FFT_H__ #define __GSL_FFT_H__ #include "gsl_complex.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS #ifndef GSL_DISABLE_DEPRECATED typedef enum { forward = -1, backward = +1, gsl_fft_forward = -1, gsl_fft_backward = +1 } gsl_fft_direction; #else typedef enum { gsl_fft_forward = -1, gsl_fft_backward = +1 } gsl_fft_direction; #endif /* this gives the sign in the formula h(f) = \sum x(t) exp(+/- 2 pi i f t) where - is the forward transform direction and + the inverse direction */ __END_DECLS #endif /* __GSL_FFT_H__ */ praat-6.0.04/external/gsl/gsl_fft__bitreverse.c000066400000000000000000000047601261542461700215170ustar00rootroot00000000000000/* fft/bitreverse.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_fft.h" #include "gsl_fft__complex_internal.h" #include "gsl_fft__bitreverse.h" static int FUNCTION(fft_complex,bitreverse_order) (BASE data[], const size_t stride, const size_t n, size_t logn) { /* This is the Goldrader bit-reversal algorithm */ size_t i; size_t j = 0; logn = 0 ; /* not needed for this algorithm */ for (i = 0; i < n - 1; i++) { size_t k = n / 2 ; if (i < j) { const BASE tmp_real = REAL(data,stride,i); const BASE tmp_imag = IMAG(data,stride,i); REAL(data,stride,i) = REAL(data,stride,j); IMAG(data,stride,i) = IMAG(data,stride,j); REAL(data,stride,j) = tmp_real; IMAG(data,stride,j) = tmp_imag; } while (k <= j) { j = j - k ; k = k / 2 ; } j += k ; } return 0; } static int FUNCTION(fft_real,bitreverse_order) (BASE data[], const size_t stride, const size_t n, size_t logn) { /* This is the Goldrader bit-reversal algorithm */ size_t i; size_t j = 0; logn = 0 ; /* not needed for this algorithm */ for (i = 0; i < n - 1; i++) { size_t k = n / 2 ; if (i < j) { const BASE tmp = VECTOR(data,stride,i); VECTOR(data,stride,i) = VECTOR(data,stride,j); VECTOR(data,stride,j) = tmp; } while (k <= j) { j = j - k ; k = k / 2 ; } j += k ; } return 0; } praat-6.0.04/external/gsl/gsl_fft__bitreverse.h000066400000000000000000000025071261542461700215210ustar00rootroot00000000000000/* fft/bitreverse.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static int FUNCTION(fft_complex,bitreverse_order) (BASE data[], const size_t stride, const size_t n, size_t logn) ; static int FUNCTION(fft_real,bitreverse_order) (BASE data[], const size_t stride, const size_t n, size_t logn) ; praat-6.0.04/external/gsl/gsl_fft__c_init.c000066400000000000000000000112071261542461700206040ustar00rootroot00000000000000/* fft/c_init.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ TYPE(gsl_fft_complex_wavetable) * FUNCTION(gsl_fft_complex_wavetable,alloc) (size_t n) { int status ; size_t i; size_t n_factors; size_t t, product, product_1, q; double d_theta; TYPE(gsl_fft_complex_wavetable) * wavetable ; if (n == 0) { GSL_ERROR_VAL ("length n must be positive integer", GSL_EDOM, 0); } wavetable = (TYPE(gsl_fft_complex_wavetable) *) malloc(sizeof(TYPE(gsl_fft_complex_wavetable))); if (wavetable == NULL) { GSL_ERROR_VAL ("failed to allocate struct", GSL_ENOMEM, 0); } wavetable->trig = (TYPE(gsl_complex) *) malloc (n * sizeof (TYPE(gsl_complex))); if (wavetable->trig == NULL) { free(wavetable) ; /* error in constructor, prevent memory leak */ GSL_ERROR_VAL ("failed to allocate trigonometric lookup table", GSL_ENOMEM, 0); } wavetable->n = n ; status = fft_complex_factorize (n, &n_factors, wavetable->factor); if (status) { /* exception in constructor, avoid memory leak */ free (wavetable->trig); free (wavetable); GSL_ERROR_VAL ("factorization failed", GSL_EFACTOR, 0); }; wavetable->nf = n_factors; d_theta = -2.0 * M_PI / ((double) n); t = 0; product = 1; for (i = 0; i < n_factors; i++) { size_t j; const size_t factor = wavetable->factor[i]; wavetable->twiddle[i] = wavetable->trig + t; product_1 = product; /* product_1 = p_(i-1) */ product *= factor; q = n / product; for (j = 1; j < factor; j++) { size_t k; size_t m = 0; for (k = 1; k <= q; k++) { double theta; m = m + j * product_1; m = m % n; theta = d_theta * m; /* d_theta*j*k*p_(i-1) */ GSL_REAL(wavetable->trig[t]) = cos (theta); GSL_IMAG(wavetable->trig[t]) = sin (theta); t++; } } } if (t > n) { /* exception in constructor, avoid memory leak */ free (wavetable->trig); free (wavetable); GSL_ERROR_VAL ("overflowed trigonometric lookup table", GSL_ESANITY, 0); } return wavetable; } TYPE(gsl_fft_complex_workspace) * FUNCTION(gsl_fft_complex_workspace,alloc) (size_t n) { TYPE(gsl_fft_complex_workspace) * workspace ; if (n == 0) { GSL_ERROR_VAL ("length n must be positive integer", GSL_EDOM, 0); } workspace = (TYPE(gsl_fft_complex_workspace) *) malloc(sizeof(TYPE(gsl_fft_complex_workspace))); if (workspace == NULL) { GSL_ERROR_VAL ("failed to allocate struct", GSL_ENOMEM, 0); } workspace->n = n ; workspace->scratch = (BASE *) malloc (2 * n * sizeof (BASE)); if (workspace->scratch == NULL) { free(workspace) ; /* error in constructor, prevent memory leak */ GSL_ERROR_VAL ("failed to allocate scratch space", GSL_ENOMEM, 0); } return workspace; } void FUNCTION(gsl_fft_complex_wavetable,free) (TYPE(gsl_fft_complex_wavetable) * wavetable) { /* release trigonometric lookup tables */ free (wavetable->trig); wavetable->trig = NULL; free (wavetable) ; } void FUNCTION(gsl_fft_complex_workspace,free) (TYPE(gsl_fft_complex_workspace) * workspace) { /* release scratch space */ free (workspace->scratch); workspace->scratch = NULL; free (workspace) ; } int FUNCTION(gsl_fft_complex,memcpy) (TYPE(gsl_fft_complex_wavetable) * dest, TYPE(gsl_fft_complex_wavetable) * src) { int i, n, nf ; if (dest->n != src->n) { GSL_ERROR ("length of src and dest do not match", GSL_EINVAL); } n = dest->n ; nf = dest->nf ; memcpy(dest->trig, src->trig, n * sizeof (double)) ; for (i = 0 ; i < nf ; i++) { dest->twiddle[i] = dest->trig + (src->twiddle[i] - src->trig) ; } return 0 ; } praat-6.0.04/external/gsl/gsl_fft__c_main.c000066400000000000000000000157421261542461700205750ustar00rootroot00000000000000/* fft/c_main.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl_fft__c_pass.h" int FUNCTION(gsl_fft_complex,forward) (TYPE(gsl_complex_packed_array) data, const size_t stride, const size_t n, const TYPE(gsl_fft_complex_wavetable) * wavetable, TYPE(gsl_fft_complex_workspace) * work) { gsl_fft_direction sign = gsl_fft_forward; int status = FUNCTION(gsl_fft_complex,transform) (data, stride, n, wavetable, work, sign); return status; } int FUNCTION(gsl_fft_complex,backward) (TYPE(gsl_complex_packed_array) data, const size_t stride, const size_t n, const TYPE(gsl_fft_complex_wavetable) * wavetable, TYPE(gsl_fft_complex_workspace) * work) { gsl_fft_direction sign = gsl_fft_backward; int status = FUNCTION(gsl_fft_complex,transform) (data, stride, n, wavetable, work, sign); return status; } int FUNCTION(gsl_fft_complex,inverse) (TYPE(gsl_complex_packed_array) data, const size_t stride, const size_t n, const TYPE(gsl_fft_complex_wavetable) * wavetable, TYPE(gsl_fft_complex_workspace) * work) { gsl_fft_direction sign = gsl_fft_backward; int status = FUNCTION(gsl_fft_complex,transform) (data, stride, n, wavetable, work, sign); if (status) { return status; } /* normalize inverse fft with 1/n */ { const ATOMIC norm = ONE / (ATOMIC)n; size_t i; for (i = 0; i < n; i++) { REAL(data,stride,i) *= norm; IMAG(data,stride,i) *= norm; } } return status; } int FUNCTION(gsl_fft_complex,transform) (TYPE(gsl_complex_packed_array) data, const size_t stride, const size_t n, const TYPE(gsl_fft_complex_wavetable) * wavetable, TYPE(gsl_fft_complex_workspace) * work, const gsl_fft_direction sign) { const size_t nf = wavetable->nf; size_t i; size_t q, product = 1; TYPE(gsl_complex) *twiddle1, *twiddle2, *twiddle3, *twiddle4, *twiddle5, *twiddle6; size_t state = 0; BASE * const scratch = work->scratch; BASE * in = data; size_t istride = stride; BASE * out = scratch; size_t ostride = 1; if (n == 0) { GSL_ERROR ("length n must be positive integer", GSL_EDOM); } if (n == 1) { /* FFT of 1 data point is the identity */ return 0; } if (n != wavetable->n) { GSL_ERROR ("wavetable does not match length of data", GSL_EINVAL); } if (n != work->n) { GSL_ERROR ("workspace does not match length of data", GSL_EINVAL); } for (i = 0; i < nf; i++) { const size_t factor = wavetable->factor[i]; product *= factor; q = n / product; if (state == 0) { in = data; istride = stride; out = scratch; ostride = 1; state = 1; } else { in = scratch; istride = 1; out = data; ostride = stride; state = 0; } if (factor == 2) { twiddle1 = wavetable->twiddle[i]; FUNCTION(fft_complex,pass_2) (in, istride, out, ostride, sign, product, n, twiddle1); } else if (factor == 3) { twiddle1 = wavetable->twiddle[i]; twiddle2 = twiddle1 + q; FUNCTION(fft_complex,pass_3) (in, istride, out, ostride, sign, product, n, twiddle1, twiddle2); } else if (factor == 4) { twiddle1 = wavetable->twiddle[i]; twiddle2 = twiddle1 + q; twiddle3 = twiddle2 + q; FUNCTION(fft_complex,pass_4) (in, istride, out, ostride, sign, product, n, twiddle1, twiddle2, twiddle3); } else if (factor == 5) { twiddle1 = wavetable->twiddle[i]; twiddle2 = twiddle1 + q; twiddle3 = twiddle2 + q; twiddle4 = twiddle3 + q; FUNCTION(fft_complex,pass_5) (in, istride, out, ostride, sign, product, n, twiddle1, twiddle2, twiddle3, twiddle4); } else if (factor == 6) { twiddle1 = wavetable->twiddle[i]; twiddle2 = twiddle1 + q; twiddle3 = twiddle2 + q; twiddle4 = twiddle3 + q; twiddle5 = twiddle4 + q; FUNCTION(fft_complex,pass_6) (in, istride, out, ostride, sign, product, n, twiddle1, twiddle2, twiddle3, twiddle4, twiddle5); } else if (factor == 7) { twiddle1 = wavetable->twiddle[i]; twiddle2 = twiddle1 + q; twiddle3 = twiddle2 + q; twiddle4 = twiddle3 + q; twiddle5 = twiddle4 + q; twiddle6 = twiddle5 + q; FUNCTION(fft_complex,pass_7) (in, istride, out, ostride, sign, product, n, twiddle1, twiddle2, twiddle3, twiddle4, twiddle5, twiddle6); } else { twiddle1 = wavetable->twiddle[i]; FUNCTION(fft_complex,pass_n) (in, istride, out, ostride, sign, factor, product, n, twiddle1); } } if (state == 1) /* copy results back from scratch to data */ { for (i = 0; i < n; i++) { REAL(data,stride,i) = REAL(scratch,1,i) ; IMAG(data,stride,i) = IMAG(scratch,1,i) ; } } return 0; } praat-6.0.04/external/gsl/gsl_fft__c_pass.h000066400000000000000000000113711261542461700206160ustar00rootroot00000000000000/* fft/c_pass.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static int FUNCTION(fft_complex,pass_2) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const gsl_fft_direction sign, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle[]); static int FUNCTION(fft_complex,pass_3) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const gsl_fft_direction sign, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle1[], const TYPE(gsl_complex) twiddle2[]); static int FUNCTION(fft_complex,pass_4) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const gsl_fft_direction sign, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle1[], const TYPE(gsl_complex) twiddle2[], const TYPE(gsl_complex) twiddle3[]); static int FUNCTION(fft_complex,pass_5) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const gsl_fft_direction sign, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle1[], const TYPE(gsl_complex) twiddle2[], const TYPE(gsl_complex) twiddle3[], const TYPE(gsl_complex) twiddle4[]); static int FUNCTION(fft_complex,pass_6) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const gsl_fft_direction sign, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle1[], const TYPE(gsl_complex) twiddle2[], const TYPE(gsl_complex) twiddle3[], const TYPE(gsl_complex) twiddle4[], const TYPE(gsl_complex) twiddle5[]); static int FUNCTION(fft_complex,pass_7) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const gsl_fft_direction sign, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle1[], const TYPE(gsl_complex) twiddle2[], const TYPE(gsl_complex) twiddle3[], const TYPE(gsl_complex) twiddle4[], const TYPE(gsl_complex) twiddle5[], const TYPE(gsl_complex) twiddle6[]); static int FUNCTION(fft_complex,pass_n) (BASE in[], const size_t istride, BASE out[], const size_t ostride, const gsl_fft_direction sign, const size_t factor, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle[]); praat-6.0.04/external/gsl/gsl_fft__c_pass_2.c000066400000000000000000000057761261542461700210460ustar00rootroot00000000000000/* fft/c_pass_2.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static int FUNCTION(fft_complex,pass_2) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const gsl_fft_direction sign, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle[]) { size_t i = 0, j = 0; size_t k, k1; const size_t factor = 2; const size_t m = n / factor; const size_t q = n / product; const size_t product_1 = product / factor; const size_t jump = (factor - 1) * product_1; for (k = 0; k < q; k++) { ATOMIC w_real, w_imag; if (k == 0) { w_real = 1.0; w_imag = 0.0; } else { if (sign == gsl_fft_forward) { /* forward tranform */ w_real = GSL_REAL(twiddle[k - 1]); w_imag = GSL_IMAG(twiddle[k - 1]); } else { /* backward tranform: w -> conjugate(w) */ w_real = GSL_REAL(twiddle[k - 1]); w_imag = -GSL_IMAG(twiddle[k - 1]); } } for (k1 = 0; k1 < product_1; k1++) { const ATOMIC z0_real = REAL(in,istride,i); const ATOMIC z0_imag = IMAG(in,istride,i); const ATOMIC z1_real = REAL(in,istride,i+m); const ATOMIC z1_imag = IMAG(in,istride,i+m); /* compute x = W(2) z */ /* x0 = z0 + z1 */ const ATOMIC x0_real = z0_real + z1_real; const ATOMIC x0_imag = z0_imag + z1_imag; /* x1 = z0 - z1 */ const ATOMIC x1_real = z0_real - z1_real; const ATOMIC x1_imag = z0_imag - z1_imag; /* apply twiddle factors */ /* out0 = 1 * x0 */ REAL(out,ostride,j) = x0_real; IMAG(out,ostride,j) = x0_imag; /* out1 = w * x1 */ REAL(out,ostride,j+product_1) = w_real * x1_real - w_imag * x1_imag; IMAG(out,ostride,j+product_1) = w_real * x1_imag + w_imag * x1_real; i++; j++; } j += jump; } return 0; } praat-6.0.04/external/gsl/gsl_fft__c_pass_3.c000066400000000000000000000105071261542461700210330ustar00rootroot00000000000000/* fft/c_pass_3.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static int FUNCTION(fft_complex,pass_3) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const gsl_fft_direction sign, const size_t product, const size_t n, const TYPE(gsl_complex) * twiddle1, const TYPE(gsl_complex) * twiddle2) { size_t i = 0, j = 0; size_t k, k1; const size_t factor = 3; const size_t m = n / factor; const size_t q = n / product; const size_t product_1 = product / factor; const size_t jump = (factor - 1) * product_1; const ATOMIC tau = sqrt (3.0) / 2.0; for (k = 0; k < q; k++) { ATOMIC w1_real, w1_imag, w2_real, w2_imag; if (k == 0) { w1_real = 1.0; w1_imag = 0.0; w2_real = 1.0; w2_imag = 0.0; } else { if (sign == gsl_fft_forward) { /* forward tranform */ w1_real = GSL_REAL(twiddle1[k - 1]); w1_imag = GSL_IMAG(twiddle1[k - 1]); w2_real = GSL_REAL(twiddle2[k - 1]); w2_imag = GSL_IMAG(twiddle2[k - 1]); } else { /* backward tranform: w -> conjugate(w) */ w1_real = GSL_REAL(twiddle1[k - 1]); w1_imag = -GSL_IMAG(twiddle1[k - 1]); w2_real = GSL_REAL(twiddle2[k - 1]); w2_imag = -GSL_IMAG(twiddle2[k - 1]); } } for (k1 = 0; k1 < product_1; k1++) { const ATOMIC z0_real = REAL(in,istride,i); const ATOMIC z0_imag = IMAG(in,istride,i); const ATOMIC z1_real = REAL(in,istride,i+m); const ATOMIC z1_imag = IMAG(in,istride,i+m); const ATOMIC z2_real = REAL(in,istride,i+2*m); const ATOMIC z2_imag = IMAG(in,istride,i+2*m); /* compute x = W(3) z */ /* t1 = z1 + z2 */ const ATOMIC t1_real = z1_real + z2_real; const ATOMIC t1_imag = z1_imag + z2_imag; /* t2 = z0 - t1/2 */ const ATOMIC t2_real = z0_real - t1_real / 2.0; const ATOMIC t2_imag = z0_imag - t1_imag / 2.0; /* t3 = (+/-) sin(pi/3)*(z1 - z2) */ const ATOMIC t3_real = ((int) sign) * tau * (z1_real - z2_real); const ATOMIC t3_imag = ((int) sign) * tau * (z1_imag - z2_imag); /* x0 = z0 + t1 */ const ATOMIC x0_real = z0_real + t1_real; const ATOMIC x0_imag = z0_imag + t1_imag; /* x1 = t2 + i t3 */ const ATOMIC x1_real = t2_real - t3_imag; const ATOMIC x1_imag = t2_imag + t3_real; /* x2 = t2 - i t3 */ const ATOMIC x2_real = t2_real + t3_imag; const ATOMIC x2_imag = t2_imag - t3_real; /* apply twiddle factors */ /* to0 = 1 * x0 */ REAL(out,ostride,j) = x0_real; IMAG(out,ostride,j) = x0_imag; /* to1 = w1 * x1 */ REAL(out,ostride,j+product_1) = w1_real * x1_real - w1_imag * x1_imag; IMAG(out,ostride,j+product_1) = w1_real * x1_imag + w1_imag * x1_real; /* to2 = w2 * x2 */ REAL(out,ostride,j+2*product_1) = w2_real * x2_real - w2_imag * x2_imag; IMAG(out,ostride,j+2*product_1) = w2_real * x2_imag + w2_imag * x2_real; i++; j++; } j += jump; } return 0; } praat-6.0.04/external/gsl/gsl_fft__c_pass_4.c000066400000000000000000000122151261542461700210320ustar00rootroot00000000000000/* fft/c_pass_4.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static int FUNCTION(fft_complex,pass_4) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const gsl_fft_direction sign, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle1[], const TYPE(gsl_complex) twiddle2[], const TYPE(gsl_complex) twiddle3[]) { size_t i = 0, j = 0; size_t k, k1; const size_t factor = 4; const size_t m = n / factor; const size_t q = n / product; const size_t p_1 = product / factor; const size_t jump = (factor - 1) * p_1; for (k = 0; k < q; k++) { ATOMIC w1_real, w1_imag, w2_real, w2_imag, w3_real, w3_imag; if (k == 0) { w1_real = 1.0; w1_imag = 0.0; w2_real = 1.0; w2_imag = 0.0; w3_real = 1.0; w3_imag = 0.0; } else { if (sign == gsl_fft_forward) { /* forward tranform */ w1_real = GSL_REAL(twiddle1[k - 1]); w1_imag = GSL_IMAG(twiddle1[k - 1]); w2_real = GSL_REAL(twiddle2[k - 1]); w2_imag = GSL_IMAG(twiddle2[k - 1]); w3_real = GSL_REAL(twiddle3[k - 1]); w3_imag = GSL_IMAG(twiddle3[k - 1]); } else { /* backward tranform: w -> conjugate(w) */ w1_real = GSL_REAL(twiddle1[k - 1]); w1_imag = -GSL_IMAG(twiddle1[k - 1]); w2_real = GSL_REAL(twiddle2[k - 1]); w2_imag = -GSL_IMAG(twiddle2[k - 1]); w3_real = GSL_REAL(twiddle3[k - 1]); w3_imag = -GSL_IMAG(twiddle3[k - 1]); } } for (k1 = 0; k1 < p_1; k1++) { const ATOMIC z0_real = REAL(in,istride,i); const ATOMIC z0_imag = IMAG(in,istride,i); const ATOMIC z1_real = REAL(in,istride,i+m); const ATOMIC z1_imag = IMAG(in,istride,i+m); const ATOMIC z2_real = REAL(in,istride,i+2*m); const ATOMIC z2_imag = IMAG(in,istride,i+2*m); const ATOMIC z3_real = REAL(in,istride,i+3*m); const ATOMIC z3_imag = IMAG(in,istride,i+3*m); /* compute x = W(4) z */ /* t1 = z0 + z2 */ const ATOMIC t1_real = z0_real + z2_real; const ATOMIC t1_imag = z0_imag + z2_imag; /* t2 = z1 + z3 */ const ATOMIC t2_real = z1_real + z3_real; const ATOMIC t2_imag = z1_imag + z3_imag; /* t3 = z0 - z2 */ const ATOMIC t3_real = z0_real - z2_real; const ATOMIC t3_imag = z0_imag - z2_imag; /* t4 = (+/-) (z1 - z3) */ const ATOMIC t4_real = ((int) sign) * (z1_real - z3_real); const ATOMIC t4_imag = ((int) sign) * (z1_imag - z3_imag); /* x0 = t1 + t2 */ const ATOMIC x0_real = t1_real + t2_real; const ATOMIC x0_imag = t1_imag + t2_imag; /* x1 = t3 + i t4 */ const ATOMIC x1_real = t3_real - t4_imag; const ATOMIC x1_imag = t3_imag + t4_real; /* x2 = t1 - t2 */ const ATOMIC x2_real = t1_real - t2_real; const ATOMIC x2_imag = t1_imag - t2_imag; /* x3 = t3 - i t4 */ const ATOMIC x3_real = t3_real + t4_imag; const ATOMIC x3_imag = t3_imag - t4_real; /* apply twiddle factors */ /* to0 = 1 * x0 */ REAL(out,ostride,j) = x0_real; IMAG(out,ostride,j) = x0_imag; /* to1 = w1 * x1 */ REAL(out, ostride, j + p_1) = w1_real * x1_real - w1_imag * x1_imag; IMAG(out, ostride, j + p_1) = w1_real * x1_imag + w1_imag * x1_real; /* to2 = w2 * x2 */ REAL(out, ostride, j + 2 * p_1) = w2_real * x2_real - w2_imag * x2_imag; IMAG(out, ostride, j + 2 * p_1) = w2_real * x2_imag + w2_imag * x2_real; /* to3 = w3 * x3 */ REAL(out, ostride, j + 3 * p_1) = w3_real * x3_real - w3_imag * x3_imag; IMAG(out, ostride, j + 3 * p_1) = w3_real * x3_imag + w3_imag * x3_real; i++; j++; } j += jump; } return 0; } praat-6.0.04/external/gsl/gsl_fft__c_pass_5.c000066400000000000000000000170351261542461700210400ustar00rootroot00000000000000/* fft/c_pass_5.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static int FUNCTION(fft_complex,pass_5) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const gsl_fft_direction sign, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle1[], const TYPE(gsl_complex) twiddle2[], const TYPE(gsl_complex) twiddle3[], const TYPE(gsl_complex) twiddle4[]) { size_t i = 0, j = 0; size_t k, k1; const size_t factor = 5; const size_t m = n / factor; const size_t q = n / product; const size_t p_1 = product / factor; const size_t jump = (factor - 1) * p_1; const ATOMIC sin_2pi_by_5 = sin (2.0 * M_PI / 5.0); const ATOMIC sin_2pi_by_10 = sin (2.0 * M_PI / 10.0); for (k = 0; k < q; k++) { ATOMIC w1_real, w1_imag, w2_real, w2_imag, w3_real, w3_imag, w4_real, w4_imag; if (k == 0) { w1_real = 1.0; w1_imag = 0.0; w2_real = 1.0; w2_imag = 0.0; w3_real = 1.0; w3_imag = 0.0; w4_real = 1.0; w4_imag = 0.0; } else { if (sign == gsl_fft_forward) { /* forward tranform */ w1_real = GSL_REAL(twiddle1[k - 1]); w1_imag = GSL_IMAG(twiddle1[k - 1]); w2_real = GSL_REAL(twiddle2[k - 1]); w2_imag = GSL_IMAG(twiddle2[k - 1]); w3_real = GSL_REAL(twiddle3[k - 1]); w3_imag = GSL_IMAG(twiddle3[k - 1]); w4_real = GSL_REAL(twiddle4[k - 1]); w4_imag = GSL_IMAG(twiddle4[k - 1]); } else { /* backward tranform: w -> conjugate(w) */ w1_real = GSL_REAL(twiddle1[k - 1]); w1_imag = -GSL_IMAG(twiddle1[k - 1]); w2_real = GSL_REAL(twiddle2[k - 1]); w2_imag = -GSL_IMAG(twiddle2[k - 1]); w3_real = GSL_REAL(twiddle3[k - 1]); w3_imag = -GSL_IMAG(twiddle3[k - 1]); w4_real = GSL_REAL(twiddle4[k - 1]); w4_imag = -GSL_IMAG(twiddle4[k - 1]); } } for (k1 = 0; k1 < p_1; k1++) { ATOMIC x0_real, x0_imag, x1_real, x1_imag, x2_real, x2_imag, x3_real, x3_imag, x4_real, x4_imag; const ATOMIC z0_real = REAL(in,istride,i); const ATOMIC z0_imag = IMAG(in,istride,i); const ATOMIC z1_real = REAL(in,istride,i + m); const ATOMIC z1_imag = IMAG(in,istride,i + m); const ATOMIC z2_real = REAL(in,istride,i + 2*m); const ATOMIC z2_imag = IMAG(in,istride,i + 2*m); const ATOMIC z3_real = REAL(in,istride,i + 3*m); const ATOMIC z3_imag = IMAG(in,istride,i + 3*m); const ATOMIC z4_real = REAL(in,istride,i + 4*m); const ATOMIC z4_imag = IMAG(in,istride,i + 4*m); /* compute x = W(5) z */ /* t1 = z1 + z4 */ const ATOMIC t1_real = z1_real + z4_real; const ATOMIC t1_imag = z1_imag + z4_imag; /* t2 = z2 + z3 */ const ATOMIC t2_real = z2_real + z3_real; const ATOMIC t2_imag = z2_imag + z3_imag; /* t3 = z1 - z4 */ const ATOMIC t3_real = z1_real - z4_real; const ATOMIC t3_imag = z1_imag - z4_imag; /* t4 = z2 - z3 */ const ATOMIC t4_real = z2_real - z3_real; const ATOMIC t4_imag = z2_imag - z3_imag; /* t5 = t1 + t2 */ const ATOMIC t5_real = t1_real + t2_real; const ATOMIC t5_imag = t1_imag + t2_imag; /* t6 = (sqrt(5)/4)(t1 - t2) */ const ATOMIC t6_real = (sqrt (5.0) / 4.0) * (t1_real - t2_real); const ATOMIC t6_imag = (sqrt (5.0) / 4.0) * (t1_imag - t2_imag); /* t7 = z0 - ((t5)/4) */ const ATOMIC t7_real = z0_real - t5_real / 4.0; const ATOMIC t7_imag = z0_imag - t5_imag / 4.0; /* t8 = t7 + t6 */ const ATOMIC t8_real = t7_real + t6_real; const ATOMIC t8_imag = t7_imag + t6_imag; /* t9 = t7 - t6 */ const ATOMIC t9_real = t7_real - t6_real; const ATOMIC t9_imag = t7_imag - t6_imag; /* t10 = sin(2 pi/5) t3 + sin(2 pi/10) t4 */ const ATOMIC t10_real = ((int) sign) * (sin_2pi_by_5 * t3_real + sin_2pi_by_10 * t4_real); const ATOMIC t10_imag = ((int) sign) * (sin_2pi_by_5 * t3_imag + sin_2pi_by_10 * t4_imag); /* t11 = sin(2 pi/10) t3 - sin(2 pi/5) t4 */ const ATOMIC t11_real = ((int) sign) * (sin_2pi_by_10 * t3_real - sin_2pi_by_5 * t4_real); const ATOMIC t11_imag = ((int) sign) * (sin_2pi_by_10 * t3_imag - sin_2pi_by_5 * t4_imag); /* x0 = z0 + t5 */ x0_real = z0_real + t5_real; x0_imag = z0_imag + t5_imag; /* x1 = t8 + i t10 */ x1_real = t8_real - t10_imag; x1_imag = t8_imag + t10_real; /* x2 = t9 + i t11 */ x2_real = t9_real - t11_imag; x2_imag = t9_imag + t11_real; /* x3 = t9 - i t11 */ x3_real = t9_real + t11_imag; x3_imag = t9_imag - t11_real; /* x4 = t8 - i t10 */ x4_real = t8_real + t10_imag; x4_imag = t8_imag - t10_real; /* apply twiddle factors */ /* to0 = 1 * x0 */ REAL(out,ostride,j) = x0_real; IMAG(out,ostride,j) = x0_imag; /* to1 = w1 * x1 */ REAL(out,ostride,j + p_1) = w1_real * x1_real - w1_imag * x1_imag; IMAG(out,ostride,j + p_1) = w1_real * x1_imag + w1_imag * x1_real; /* to2 = w2 * x2 */ REAL(out,ostride,j + 2*p_1) = w2_real * x2_real - w2_imag * x2_imag; IMAG(out,ostride,j+2*p_1) = w2_real * x2_imag + w2_imag * x2_real; /* to3 = w3 * x3 */ REAL(out,ostride,j+3*p_1) = w3_real * x3_real - w3_imag * x3_imag; IMAG(out,ostride,j+3*p_1) = w3_real * x3_imag + w3_imag * x3_real; /* to4 = w4 * x4 */ REAL(out,ostride,j+4*p_1) = w4_real * x4_real - w4_imag * x4_imag; IMAG(out,ostride,j+4*p_1) = w4_real * x4_imag + w4_imag * x4_real; i++; j++; } j += jump; } return 0; } praat-6.0.04/external/gsl/gsl_fft__c_pass_6.c000066400000000000000000000202311261542461700210310ustar00rootroot00000000000000/* fft/c_pass_6.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static int FUNCTION(fft_complex,pass_6) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const gsl_fft_direction sign, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle1[], const TYPE(gsl_complex) twiddle2[], const TYPE(gsl_complex) twiddle3[], const TYPE(gsl_complex) twiddle4[], const TYPE(gsl_complex) twiddle5[]) { size_t i = 0, j = 0; size_t k, k1; const size_t factor = 6; const size_t m = n / factor; const size_t q = n / product; const size_t p_1 = product / factor; const size_t jump = (factor - 1) * p_1; const ATOMIC tau = sqrt (3.0) / 2.0; for (k = 0; k < q; k++) { ATOMIC w1_real, w1_imag, w2_real, w2_imag, w3_real, w3_imag, w4_real, w4_imag, w5_real, w5_imag; if (k == 0) { w1_real = 1.0; w1_imag = 0.0; w2_real = 1.0; w2_imag = 0.0; w3_real = 1.0; w3_imag = 0.0; w4_real = 1.0; w4_imag = 0.0; w5_real = 1.0; w5_imag = 0.0; } else { if (sign == gsl_fft_forward) { /* forward tranform */ w1_real = GSL_REAL(twiddle1[k - 1]); w1_imag = GSL_IMAG(twiddle1[k - 1]); w2_real = GSL_REAL(twiddle2[k - 1]); w2_imag = GSL_IMAG(twiddle2[k - 1]); w3_real = GSL_REAL(twiddle3[k - 1]); w3_imag = GSL_IMAG(twiddle3[k - 1]); w4_real = GSL_REAL(twiddle4[k - 1]); w4_imag = GSL_IMAG(twiddle4[k - 1]); w5_real = GSL_REAL(twiddle5[k - 1]); w5_imag = GSL_IMAG(twiddle5[k - 1]); } else { /* backward tranform: w -> conjugate(w) */ w1_real = GSL_REAL(twiddle1[k - 1]); w1_imag = -GSL_IMAG(twiddle1[k - 1]); w2_real = GSL_REAL(twiddle2[k - 1]); w2_imag = -GSL_IMAG(twiddle2[k - 1]); w3_real = GSL_REAL(twiddle3[k - 1]); w3_imag = -GSL_IMAG(twiddle3[k - 1]); w4_real = GSL_REAL(twiddle4[k - 1]); w4_imag = -GSL_IMAG(twiddle4[k - 1]); w5_real = GSL_REAL(twiddle5[k - 1]); w5_imag = -GSL_IMAG(twiddle5[k - 1]); } } for (k1 = 0; k1 < p_1; k1++) { const ATOMIC z0_real = REAL(in,istride,i); const ATOMIC z0_imag = IMAG(in,istride,i); const ATOMIC z1_real = REAL(in,istride,i+m); const ATOMIC z1_imag = IMAG(in,istride,i+m); const ATOMIC z2_real = REAL(in,istride,i+2*m); const ATOMIC z2_imag = IMAG(in,istride,i+2*m); const ATOMIC z3_real = REAL(in,istride,i+3*m); const ATOMIC z3_imag = IMAG(in,istride,i+3*m); const ATOMIC z4_real = REAL(in,istride,i+4*m); const ATOMIC z4_imag = IMAG(in,istride,i+4*m); const ATOMIC z5_real = REAL(in,istride,i+5*m); const ATOMIC z5_imag = IMAG(in,istride,i+5*m); /* compute x = W(6) z */ /* W(6) is a combination of sums and differences of W(3) acting on the even and odd elements of z */ /* ta1 = z2 + z4 */ const ATOMIC ta1_real = z2_real + z4_real; const ATOMIC ta1_imag = z2_imag + z4_imag; /* ta2 = z0 - ta1/2 */ const ATOMIC ta2_real = z0_real - ta1_real / 2; const ATOMIC ta2_imag = z0_imag - ta1_imag / 2; /* ta3 = (+/-) sin(pi/3)*(z2 - z4) */ const ATOMIC ta3_real = ((int) sign) * tau * (z2_real - z4_real); const ATOMIC ta3_imag = ((int) sign) * tau * (z2_imag - z4_imag); /* a0 = z0 + ta1 */ const ATOMIC a0_real = z0_real + ta1_real; const ATOMIC a0_imag = z0_imag + ta1_imag; /* a1 = ta2 + i ta3 */ const ATOMIC a1_real = ta2_real - ta3_imag; const ATOMIC a1_imag = ta2_imag + ta3_real; /* a2 = ta2 - i ta3 */ const ATOMIC a2_real = ta2_real + ta3_imag; const ATOMIC a2_imag = ta2_imag - ta3_real; /* tb1 = z5 + z1 */ const ATOMIC tb1_real = z5_real + z1_real; const ATOMIC tb1_imag = z5_imag + z1_imag; /* tb2 = z3 - tb1/2 */ const ATOMIC tb2_real = z3_real - tb1_real / 2; const ATOMIC tb2_imag = z3_imag - tb1_imag / 2; /* tb3 = (+/-) sin(pi/3)*(z5 - z1) */ const ATOMIC tb3_real = ((int) sign) * tau * (z5_real - z1_real); const ATOMIC tb3_imag = ((int) sign) * tau * (z5_imag - z1_imag); /* b0 = z3 + tb1 */ const ATOMIC b0_real = z3_real + tb1_real; const ATOMIC b0_imag = z3_imag + tb1_imag; /* b1 = tb2 + i tb3 */ const ATOMIC b1_real = tb2_real - tb3_imag; const ATOMIC b1_imag = tb2_imag + tb3_real; /* b2 = tb2 - i tb3 */ const ATOMIC b2_real = tb2_real + tb3_imag; const ATOMIC b2_imag = tb2_imag - tb3_real; /* x0 = a0 + b0 */ const ATOMIC x0_real = a0_real + b0_real; const ATOMIC x0_imag = a0_imag + b0_imag; /* x4 = a1 + b1 */ const ATOMIC x4_real = a1_real + b1_real; const ATOMIC x4_imag = a1_imag + b1_imag; /* x2 = a2 + b2 */ const ATOMIC x2_real = a2_real + b2_real; const ATOMIC x2_imag = a2_imag + b2_imag; /* x3 = a0 - b0 */ const ATOMIC x3_real = a0_real - b0_real; const ATOMIC x3_imag = a0_imag - b0_imag; /* x1 = a1 - b1 */ const ATOMIC x1_real = a1_real - b1_real; const ATOMIC x1_imag = a1_imag - b1_imag; /* x5 = a2 - b2 */ const ATOMIC x5_real = a2_real - b2_real; const ATOMIC x5_imag = a2_imag - b2_imag; /* apply twiddle factors */ /* to0 = 1 * x0 */ REAL(out,ostride,j) = x0_real; IMAG(out,ostride,j) = x0_imag; /* to1 = w1 * x1 */ REAL(out,ostride,j+p_1) = w1_real * x1_real - w1_imag * x1_imag; IMAG(out,ostride,j+p_1) = w1_real * x1_imag + w1_imag * x1_real; /* to2 = w2 * x2 */ REAL(out,ostride,j+2*p_1) = w2_real * x2_real - w2_imag * x2_imag; IMAG(out,ostride,j+2*p_1) = w2_real * x2_imag + w2_imag * x2_real; /* to3 = w3 * x3 */ REAL(out,ostride,j+3*p_1) = w3_real * x3_real - w3_imag * x3_imag; IMAG(out,ostride,j+3*p_1) = w3_real * x3_imag + w3_imag * x3_real; /* to4 = w4 * x4 */ REAL(out,ostride,j+4*p_1) = w4_real * x4_real - w4_imag * x4_imag; IMAG(out,ostride,j+4*p_1) = w4_real * x4_imag + w4_imag * x4_real; /* to5 = w5 * x5 */ REAL(out,ostride,j+5*p_1) = w5_real * x5_real - w5_imag * x5_imag; IMAG(out,ostride,j+5*p_1) = w5_real * x5_imag + w5_imag * x5_real; i++; j++; } j += jump; } return 0; } praat-6.0.04/external/gsl/gsl_fft__c_pass_7.c000066400000000000000000000307531261542461700210440ustar00rootroot00000000000000/* fft/c_pass_7.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static int FUNCTION(fft_complex,pass_7) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const gsl_fft_direction sign, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle1[], const TYPE(gsl_complex) twiddle2[], const TYPE(gsl_complex) twiddle3[], const TYPE(gsl_complex) twiddle4[], const TYPE(gsl_complex) twiddle5[], const TYPE(gsl_complex) twiddle6[]) { size_t i = 0, j = 0; size_t k, k1; const size_t factor = 7; const size_t m = n / factor; const size_t q = n / product; const size_t p_1 = product / factor; const size_t jump = (factor - 1) * p_1; const ATOMIC c1 = cos(1.0 * 2.0 * M_PI / 7.0) ; const ATOMIC c2 = cos(2.0 * 2.0 * M_PI / 7.0) ; const ATOMIC c3 = cos(3.0 * 2.0 * M_PI / 7.0) ; const ATOMIC s1 = sin(1.0 * 2.0 * M_PI / 7.0) ; const ATOMIC s2 = sin(2.0 * 2.0 * M_PI / 7.0) ; const ATOMIC s3 = sin(3.0 * 2.0 * M_PI / 7.0) ; for (k = 0; k < q; k++) { ATOMIC w1_real, w1_imag, w2_real, w2_imag, w3_real, w3_imag, w4_real, w4_imag, w5_real, w5_imag, w6_real, w6_imag; if (k == 0) { w1_real = 1.0; w1_imag = 0.0; w2_real = 1.0; w2_imag = 0.0; w3_real = 1.0; w3_imag = 0.0; w4_real = 1.0; w4_imag = 0.0; w5_real = 1.0; w5_imag = 0.0; w6_real = 1.0; w6_imag = 0.0; } else { if (sign == gsl_fft_forward) { /* forward tranform */ w1_real = GSL_REAL(twiddle1[k - 1]); w1_imag = GSL_IMAG(twiddle1[k - 1]); w2_real = GSL_REAL(twiddle2[k - 1]); w2_imag = GSL_IMAG(twiddle2[k - 1]); w3_real = GSL_REAL(twiddle3[k - 1]); w3_imag = GSL_IMAG(twiddle3[k - 1]); w4_real = GSL_REAL(twiddle4[k - 1]); w4_imag = GSL_IMAG(twiddle4[k - 1]); w5_real = GSL_REAL(twiddle5[k - 1]); w5_imag = GSL_IMAG(twiddle5[k - 1]); w6_real = GSL_REAL(twiddle6[k - 1]); w6_imag = GSL_IMAG(twiddle6[k - 1]); } else { /* backward tranform: w -> conjugate(w) */ w1_real = GSL_REAL(twiddle1[k - 1]); w1_imag = -GSL_IMAG(twiddle1[k - 1]); w2_real = GSL_REAL(twiddle2[k - 1]); w2_imag = -GSL_IMAG(twiddle2[k - 1]); w3_real = GSL_REAL(twiddle3[k - 1]); w3_imag = -GSL_IMAG(twiddle3[k - 1]); w4_real = GSL_REAL(twiddle4[k - 1]); w4_imag = -GSL_IMAG(twiddle4[k - 1]); w5_real = GSL_REAL(twiddle5[k - 1]); w5_imag = -GSL_IMAG(twiddle5[k - 1]); w6_real = GSL_REAL(twiddle6[k - 1]); w6_imag = -GSL_IMAG(twiddle6[k - 1]); } } for (k1 = 0; k1 < p_1; k1++) { const ATOMIC z0_real = REAL(in,istride,i); const ATOMIC z0_imag = IMAG(in,istride,i); const ATOMIC z1_real = REAL(in,istride,i+m); const ATOMIC z1_imag = IMAG(in,istride,i+m); const ATOMIC z2_real = REAL(in,istride,i+2*m); const ATOMIC z2_imag = IMAG(in,istride,i+2*m); const ATOMIC z3_real = REAL(in,istride,i+3*m); const ATOMIC z3_imag = IMAG(in,istride,i+3*m); const ATOMIC z4_real = REAL(in,istride,i+4*m); const ATOMIC z4_imag = IMAG(in,istride,i+4*m); const ATOMIC z5_real = REAL(in,istride,i+5*m); const ATOMIC z5_imag = IMAG(in,istride,i+5*m); const ATOMIC z6_real = REAL(in,istride,i+6*m); const ATOMIC z6_imag = IMAG(in,istride,i+6*m); /* compute x = W(7) z */ /* t0 = z1 + z6 */ const ATOMIC t0_real = z1_real + z6_real ; const ATOMIC t0_imag = z1_imag + z6_imag ; /* t1 = z1 - z6 */ const ATOMIC t1_real = z1_real - z6_real ; const ATOMIC t1_imag = z1_imag - z6_imag ; /* t2 = z2 + z5 */ const ATOMIC t2_real = z2_real + z5_real ; const ATOMIC t2_imag = z2_imag + z5_imag ; /* t3 = z2 - z5 */ const ATOMIC t3_real = z2_real - z5_real ; const ATOMIC t3_imag = z2_imag - z5_imag ; /* t4 = z4 + z3 */ const ATOMIC t4_real = z4_real + z3_real ; const ATOMIC t4_imag = z4_imag + z3_imag ; /* t5 = z4 - z3 */ const ATOMIC t5_real = z4_real - z3_real ; const ATOMIC t5_imag = z4_imag - z3_imag ; /* t6 = t2 + t0 */ const ATOMIC t6_real = t2_real + t0_real ; const ATOMIC t6_imag = t2_imag + t0_imag ; /* t7 = t5 + t3 */ const ATOMIC t7_real = t5_real + t3_real ; const ATOMIC t7_imag = t5_imag + t3_imag ; /* b0 = z0 + t6 + t4 */ const ATOMIC b0_real = z0_real + t6_real + t4_real ; const ATOMIC b0_imag = z0_imag + t6_imag + t4_imag ; /* b1 = ((cos(2pi/7) + cos(4pi/7) + cos(6pi/7))/3-1) (t6 + t4) */ const ATOMIC b1_real = (((c1 + c2 + c3)/3.0 - 1.0) * (t6_real + t4_real)); const ATOMIC b1_imag = (((c1 + c2 + c3)/3.0 - 1.0) * (t6_imag + t4_imag)); /* b2 = ((2*cos(2pi/7) - cos(4pi/7) - cos(6pi/7))/3) (t0 - t4) */ const ATOMIC b2_real = (((2.0 * c1 - c2 - c3)/3.0) * (t0_real - t4_real)); const ATOMIC b2_imag = (((2.0 * c1 - c2 - c3)/3.0) * (t0_imag - t4_imag)); /* b3 = ((cos(2pi/7) - 2*cos(4pi/7) + cos(6pi/7))/3) (t4 - t2) */ const ATOMIC b3_real = (((c1 - 2.0*c2 + c3)/3.0) * (t4_real - t2_real)); const ATOMIC b3_imag = (((c1 - 2.0*c2 + c3)/3.0) * (t4_imag - t2_imag)); /* b4 = ((cos(2pi/7) + cos(4pi/7) - 2*cos(6pi/7))/3) (t2 - t0) */ const ATOMIC b4_real = (((c1 + c2 - 2.0 * c3)/3.0) * (t2_real - t0_real)); const ATOMIC b4_imag = (((c1 + c2 - 2.0 * c3)/3.0) * (t2_imag - t0_imag)); /* b5 = sign * ((sin(2pi/7) + sin(4pi/7) - sin(6pi/7))/3) (t7 + t1) */ const ATOMIC b5_real = (-(int)sign) * ((s1 + s2 - s3)/3.0) * (t7_real + t1_real) ; const ATOMIC b5_imag = (-(int)sign) * ((s1 + s2 - s3)/3.0) * (t7_imag + t1_imag) ; /* b6 = sign * ((2sin(2pi/7) - sin(4pi/7) + sin(6pi/7))/3) (t1 - t5) */ const ATOMIC b6_real = (-(int)sign) * ((2.0 * s1 - s2 + s3)/3.0) * (t1_real - t5_real) ; const ATOMIC b6_imag = (-(int)sign) * ((2.0 * s1 - s2 + s3)/3.0) * (t1_imag - t5_imag) ; /* b7 = sign * ((sin(2pi/7) - 2sin(4pi/7) - sin(6pi/7))/3) (t5 - t3) */ const ATOMIC b7_real = (-(int)sign) * ((s1 - 2.0 * s2 - s3)/3.0) * (t5_real - t3_real) ; const ATOMIC b7_imag = (-(int)sign) * ((s1 - 2.0 * s2 - s3)/3.0) * (t5_imag - t3_imag) ; /* b8 = sign * ((sin(2pi/7) + sin(4pi/7) + 2sin(6pi/7))/3) (t3 - t1) */ const ATOMIC b8_real = (-(int)sign) * ((s1 + s2 + 2.0 * s3)/3.0) * (t3_real - t1_real) ; const ATOMIC b8_imag = (-(int)sign) * ((s1 + s2 + 2.0 * s3)/3.0) * (t3_imag - t1_imag) ; /* T0 = b0 + b1 */ const ATOMIC T0_real = b0_real + b1_real ; const ATOMIC T0_imag = b0_imag + b1_imag ; /* T1 = b2 + b3 */ const ATOMIC T1_real = b2_real + b3_real ; const ATOMIC T1_imag = b2_imag + b3_imag ; /* T2 = b4 - b3 */ const ATOMIC T2_real = b4_real - b3_real ; const ATOMIC T2_imag = b4_imag - b3_imag ; /* T3 = -b2 - b4 */ const ATOMIC T3_real = -b2_real - b4_real ; const ATOMIC T3_imag = -b2_imag - b4_imag ; /* T4 = b6 + b7 */ const ATOMIC T4_real = b6_real + b7_real ; const ATOMIC T4_imag = b6_imag + b7_imag ; /* T5 = b8 - b7 */ const ATOMIC T5_real = b8_real - b7_real ; const ATOMIC T5_imag = b8_imag - b7_imag ; /* T6 = -b8 - b6 */ const ATOMIC T6_real = -b8_real - b6_real ; const ATOMIC T6_imag = -b8_imag - b6_imag ; /* T7 = T0 + T1 */ const ATOMIC T7_real = T0_real + T1_real ; const ATOMIC T7_imag = T0_imag + T1_imag ; /* T8 = T0 + T2 */ const ATOMIC T8_real = T0_real + T2_real ; const ATOMIC T8_imag = T0_imag + T2_imag ; /* T9 = T0 + T3 */ const ATOMIC T9_real = T0_real + T3_real ; const ATOMIC T9_imag = T0_imag + T3_imag ; /* T10 = T4 + b5 */ const ATOMIC T10_real = T4_real + b5_real ; const ATOMIC T10_imag = T4_imag + b5_imag ; /* T11 = T5 + b5 */ const ATOMIC T11_real = T5_real + b5_real ; const ATOMIC T11_imag = T5_imag + b5_imag ; /* T12 = T6 + b5 */ const ATOMIC T12_real = T6_real + b5_real ; const ATOMIC T12_imag = T6_imag + b5_imag ; /* x0 = b0 */ const ATOMIC x0_real = b0_real ; const ATOMIC x0_imag = b0_imag ; /* x1 = T7 - i T10 */ const ATOMIC x1_real = T7_real + T10_imag ; const ATOMIC x1_imag = T7_imag - T10_real ; /* x2 = T9 - i T12 */ const ATOMIC x2_real = T9_real + T12_imag ; const ATOMIC x2_imag = T9_imag - T12_real ; /* x3 = T8 + i T11 */ const ATOMIC x3_real = T8_real - T11_imag ; const ATOMIC x3_imag = T8_imag + T11_real ; /* x4 = T8 - i T11 */ const ATOMIC x4_real = T8_real + T11_imag ; const ATOMIC x4_imag = T8_imag - T11_real ; /* x5 = T9 + i T12 */ const ATOMIC x5_real = T9_real - T12_imag ; const ATOMIC x5_imag = T9_imag + T12_real ; /* x6 = T7 + i T10 */ const ATOMIC x6_real = T7_real - T10_imag ; const ATOMIC x6_imag = T7_imag + T10_real ; /* apply twiddle factors */ /* to0 = 1 * x0 */ REAL(out,ostride,j) = x0_real; IMAG(out,ostride,j) = x0_imag; /* to1 = w1 * x1 */ REAL(out,ostride,j+p_1) = w1_real * x1_real - w1_imag * x1_imag; IMAG(out,ostride,j+p_1) = w1_real * x1_imag + w1_imag * x1_real; /* to2 = w2 * x2 */ REAL(out,ostride,j+2*p_1) = w2_real * x2_real - w2_imag * x2_imag; IMAG(out,ostride,j+2*p_1) = w2_real * x2_imag + w2_imag * x2_real; /* to3 = w3 * x3 */ REAL(out,ostride,j+3*p_1) = w3_real * x3_real - w3_imag * x3_imag; IMAG(out,ostride,j+3*p_1) = w3_real * x3_imag + w3_imag * x3_real; /* to4 = w4 * x4 */ REAL(out,ostride,j+4*p_1) = w4_real * x4_real - w4_imag * x4_imag; IMAG(out,ostride,j+4*p_1) = w4_real * x4_imag + w4_imag * x4_real; /* to5 = w5 * x5 */ REAL(out,ostride,j+5*p_1) = w5_real * x5_real - w5_imag * x5_imag; IMAG(out,ostride,j+5*p_1) = w5_real * x5_imag + w5_imag * x5_real; /* to6 = w6 * x6 */ REAL(out,ostride,j+6*p_1) = w6_real * x6_real - w6_imag * x6_imag; IMAG(out,ostride,j+6*p_1) = w6_real * x6_imag + w6_imag * x6_real; i++; j++; } j += jump; } return 0; } praat-6.0.04/external/gsl/gsl_fft__c_pass_n.c000066400000000000000000000137401261542461700211300ustar00rootroot00000000000000/* fft/c_pass_n.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static int FUNCTION(fft_complex,pass_n) (BASE in[], const size_t istride, BASE out[], const size_t ostride, const gsl_fft_direction sign, const size_t factor, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle[]) { size_t i = 0, j = 0; size_t k, k1; const size_t m = n / factor; const size_t q = n / product; const size_t p_1 = product / factor; const size_t jump = (factor - 1) * p_1; size_t e, e1; for (i = 0; i < m; i++) { REAL(out,ostride,i) = REAL(in,istride,i); IMAG(out,ostride,i) = IMAG(in,istride,i); } for (e = 1; e < (factor - 1) / 2 + 1; e++) { for (i = 0; i < m; i++) { const size_t idx = i + e * m; const size_t idxc = i + (factor - e) * m; REAL(out,ostride,idx) = REAL(in,istride,idx) + REAL(in,istride,idxc); IMAG(out,ostride,idx) = IMAG(in,istride,idx) + IMAG(in,istride,idxc); REAL(out,ostride,idxc) = REAL(in,istride,idx) - REAL(in,istride,idxc); IMAG(out,ostride,idxc) = IMAG(in,istride,idx) - IMAG(in,istride,idxc); } } /* e = 0 */ for (i=0 ; i exp(i theta) w */ { const ATOMIC tmp_real = w_real - s * w_imag - s2 * w_real; const ATOMIC tmp_imag = w_imag + s * w_real - s2 * w_imag; w_real = tmp_real; w_imag = tmp_imag; } for (b = 0; b < n; b += 2 * dual) { const size_t i = b + a; const size_t j = b + a + dual; const ATOMIC z1_real = REAL(data,stride,j) ; const ATOMIC z1_imag = IMAG(data,stride,j) ; const ATOMIC wd_real = w_real * z1_real - w_imag * z1_imag; const ATOMIC wd_imag = w_real * z1_imag + w_imag * z1_real; REAL(data,stride,j) = REAL(data,stride,i) - wd_real; IMAG(data,stride,j) = IMAG(data,stride,i) - wd_imag; REAL(data,stride,i) += wd_real; IMAG(data,stride,i) += wd_imag; } } dual *= 2; } return 0; } int FUNCTION(gsl_fft_complex,radix2_dif_forward) (TYPE(gsl_complex_packed_array) data, const size_t stride, const size_t n) { gsl_fft_direction sign = gsl_fft_forward; int status = FUNCTION(gsl_fft_complex,radix2_dif_transform) (data, stride, n, sign); return status; } int FUNCTION(gsl_fft_complex,radix2_dif_backward) (TYPE(gsl_complex_packed_array) data, const size_t stride, const size_t n) { gsl_fft_direction sign = gsl_fft_backward; int status = FUNCTION(gsl_fft_complex,radix2_dif_transform) (data, stride, n, sign); return status; } int FUNCTION(gsl_fft_complex,radix2_dif_inverse) (TYPE(gsl_complex_packed_array) data, const size_t stride, const size_t n) { gsl_fft_direction sign = gsl_fft_backward; int status = FUNCTION(gsl_fft_complex,radix2_dif_transform) (data, stride, n, sign); if (status) { return status; } /* normalize inverse fft with 1/n */ { const ATOMIC norm = 1.0 / n; size_t i; for (i = 0; i < n; i++) { REAL(data,stride,i) *= norm; IMAG(data,stride,i) *= norm; } } return status; } int FUNCTION(gsl_fft_complex,radix2_dif_transform) (TYPE(gsl_complex_packed_array) data, const size_t stride, const size_t n, const gsl_fft_direction sign) { int result ; size_t dual; size_t bit; size_t logn = 0; int status; if (n == 1) /* identity operation */ { return 0 ; } /* make sure that n is a power of 2 */ result = fft_binary_logn(n) ; if (result == -1) { GSL_ERROR ("n is not a power of 2", GSL_EINVAL); } else { logn = result ; } /* apply fft recursion */ dual = n / 2; for (bit = 0; bit < logn; bit++) { ATOMIC w_real = 1.0; ATOMIC w_imag = 0.0; const double theta = 2.0 * ((int) sign) * M_PI / ((double) (2 * dual)); const ATOMIC s = sin (theta); const ATOMIC t = sin (theta / 2.0); const ATOMIC s2 = 2.0 * t * t; size_t a, b; for (b = 0; b < dual; b++) { for (a = 0; a < n; a+= 2 * dual) { const size_t i = b + a; const size_t j = b + a + dual; const ATOMIC t1_real = REAL(data,stride,i) + REAL(data,stride,j); const ATOMIC t1_imag = IMAG(data,stride,i) + IMAG(data,stride,j); const ATOMIC t2_real = REAL(data,stride,i) - REAL(data,stride,j); const ATOMIC t2_imag = IMAG(data,stride,i) - IMAG(data,stride,j); REAL(data,stride,i) = t1_real; IMAG(data,stride,i) = t1_imag; REAL(data,stride,j) = w_real*t2_real - w_imag * t2_imag; IMAG(data,stride,j) = w_real*t2_imag + w_imag * t2_real; } /* trignometric recurrence for w-> exp(i theta) w */ { const ATOMIC tmp_real = w_real - s * w_imag - s2 * w_real; const ATOMIC tmp_imag = w_imag + s * w_real - s2 * w_imag; w_real = tmp_real; w_imag = tmp_imag; } } dual /= 2; } /* bit reverse the ordering of output data for decimation in frequency algorithm */ status = FUNCTION(fft_complex,bitreverse_order)(data, stride, n, logn) ; return 0; } praat-6.0.04/external/gsl/gsl_fft__compare.h000066400000000000000000000025121261542461700207710ustar00rootroot00000000000000/* fft/compare.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ int FUNCTION(compare_complex,results) (const char *name_a, const BASE a[], const char *name_b, const BASE b[], size_t stride, size_t n, const double allowed_ticks); int FUNCTION(compare_real,results) (const char *name_a, const BASE a[], const char *name_b, const BASE b[], size_t stride, size_t n, const double allowed_ticks); praat-6.0.04/external/gsl/gsl_fft__compare_source.c000066400000000000000000000062741261542461700223550ustar00rootroot00000000000000/* fft/compare_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl_fft__compare.h" int FUNCTION(compare_complex,results) (const char *name_a, const BASE a[], const char *name_b, const BASE b[], size_t stride, size_t n, const double allowed_ticks) { size_t i; double ticks, max_ticks = 0; double dr, di; const char *flag; for (i = 0; i < n; i++) { dr = b[2*stride*i] - a[2*stride*i]; di = b[2*stride*i+1] - a[2*stride*i+1]; ticks = (fabs (dr) + fabs (di)) / BASE_EPSILON; if (ticks > max_ticks) { max_ticks = ticks; } } if (max_ticks < allowed_ticks) { return 0; } printf ("\n%s vs %s : max_ticks = %f\n", name_a, name_b, max_ticks); for (i = 0; i < n; i++) { dr = b[2*stride*i] - a[2*stride*i]; di = b[2*stride*i+1] - a[2*stride*i+1]; ticks = (fabs (dr) + fabs (di)) / BASE_EPSILON; if (ticks > 1000) { flag = "***"; } else { flag = ""; } printf ("%15s: %d %.16f %.16f %s\n", name_a, (int)i, a[2*stride*i], a[2*stride*i+1], flag); printf ("%15s: %d %.16f %.16f %e %s\n", name_b, (int)i, b[2*stride*i], b[2*stride*i+1], ticks, flag); } return -1; } int FUNCTION(compare_real,results) (const char *name_a, const BASE a[], const char *name_b, const BASE b[], size_t stride, size_t n, const double allowed_ticks) { size_t i; double ticks, max_ticks = 0; double dr; const char *flag; for (i = 0; i < n; i++) { dr = b[stride*i] - a[stride*i]; ticks = fabs (dr) / BASE_EPSILON; if (ticks > max_ticks) { max_ticks = ticks; } } if (max_ticks < allowed_ticks) { return 0; } printf ("\n%s vs %s : max_ticks = %f\n", name_a, name_b, max_ticks); for (i = 0; i < n; i++) { dr = b[stride*i] - a[stride*i]; ticks = fabs (dr) / BASE_EPSILON; if (ticks > 1000) { flag = "***"; } else { flag = ""; } printf ("%15s: %d %.16f %s\n", name_a, (int)i, a[stride*i], flag); printf ("%15s: %d %.16f %e %s\n", name_b, (int)i, b[stride*i], ticks, flag); } return -1; } praat-6.0.04/external/gsl/gsl_fft__complex_internal.h000066400000000000000000000005561261542461700227140ustar00rootroot00000000000000/* Handling of packed complex types... not meant for client consumption. */ #ifndef COMPLEX_INTERNAL_H_ #define COMPLEX_INTERNAL_H_ #define VECTOR(a,stride,i) ((a)[(stride)*(i)]) #define REAL(a,stride,i) ((a)[2*(stride)*(i)]) #define IMAG(a,stride,i) ((a)[2*(stride)*(i)+1]) #define REAL0(a) ((a)[0]) #define IMAG0(a) ((a)[1]) #endif /* !COMPLEX_INTERNAL_H_ */ praat-6.0.04/external/gsl/gsl_fft__dft.c000066400000000000000000000007521261542461700201170ustar00rootroot00000000000000#include "gsl__config.h" #include #include #include #include "gsl_errno.h" #include "gsl_complex.h" #include "gsl_dft_complex.h" #include "gsl_dft_complex_float.h" #include "gsl_fft__complex_internal.h" #define BASE_DOUBLE #include "templates_on.h" #include "gsl_fft__dft_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_fft__dft_source.c" #include "templates_off.h" #undef BASE_FLOAT praat-6.0.04/external/gsl/gsl_fft__dft_source.c000066400000000000000000000061641261542461700215020ustar00rootroot00000000000000/* fft/dft_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ int FUNCTION(gsl_dft_complex,forward) (const BASE data[], const size_t stride, const size_t n, BASE result[]) { gsl_fft_direction sign = gsl_fft_forward; int status = FUNCTION(gsl_dft_complex,transform) (data, stride, n, result, sign); return status; } int FUNCTION(gsl_dft_complex,backward) (const BASE data[], const size_t stride, const size_t n, BASE result[]) { gsl_fft_direction sign = gsl_fft_backward; int status = FUNCTION(gsl_dft_complex,transform) (data, stride, n, result, sign); return status; } int FUNCTION(gsl_dft_complex,inverse) (const BASE data[], const size_t stride, const size_t n, BASE result[]) { gsl_fft_direction sign = gsl_fft_backward; int status = FUNCTION(gsl_dft_complex,transform) (data, stride, n, result, sign); /* normalize inverse fft with 1/n */ { const ATOMIC norm = ONE / (ATOMIC)n; size_t i; for (i = 0; i < n; i++) { REAL(result,stride,i) *= norm; IMAG(result,stride,i) *= norm; } } return status; } int FUNCTION(gsl_dft_complex,transform) (const BASE data[], const size_t stride, const size_t n, BASE result[], const gsl_fft_direction sign) { size_t i, j, exponent; const double d_theta = 2.0 * ((int) sign) * M_PI / (double) n; /* FIXME: check that input length == output length and give error */ for (i = 0; i < n; i++) { ATOMIC sum_real = 0; ATOMIC sum_imag = 0; exponent = 0; for (j = 0; j < n; j++) { double theta = d_theta * (double) exponent; /* sum = exp(i theta) * data[j] */ ATOMIC w_real = (ATOMIC) cos (theta); ATOMIC w_imag = (ATOMIC) sin (theta); ATOMIC data_real = REAL(data,stride,j); ATOMIC data_imag = IMAG(data,stride,j); sum_real += w_real * data_real - w_imag * data_imag; sum_imag += w_real * data_imag + w_imag * data_real; exponent = (exponent + i) % n; } REAL(result,stride,i) = sum_real; IMAG(result,stride,i) = sum_imag; } return 0; } praat-6.0.04/external/gsl/gsl_fft__factorize.c000066400000000000000000000072251261542461700213320ustar00rootroot00000000000000/* fft/factorize.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_fft_complex.h" #include "gsl_fft__factorize.h" static int fft_complex_factorize (const size_t n, size_t *nf, size_t factors[]) { const size_t complex_subtransforms[] = {7, 6, 5, 4, 3, 2, 0}; /* other factors can be added here if their transform modules are implemented. The end of the list is marked by 0. */ int status = fft_factorize (n, complex_subtransforms, nf, factors); return status; } static int fft_halfcomplex_factorize (const size_t n, size_t *nf, size_t factors[]) { const size_t halfcomplex_subtransforms[] = {5, 4, 3, 2, 0}; int status = fft_factorize (n, halfcomplex_subtransforms, nf, factors); return status; } static int fft_real_factorize (const size_t n, size_t *nf, size_t factors[]) { const size_t real_subtransforms[] = {5, 4, 3, 2, 0}; int status = fft_factorize (n, real_subtransforms, nf, factors); return status; } static int fft_factorize (const size_t n, const size_t implemented_subtransforms[], size_t *n_factors, size_t factors[]) { size_t nf = 0; size_t ntest = n; size_t factor; size_t i = 0; if (n == 0) { GSL_ERROR ("length n must be positive integer", GSL_EDOM); } if (n == 1) { factors[0] = 1; *n_factors = 1; return 0; } /* deal with the implemented factors first */ while (implemented_subtransforms[i] && ntest != 1) { factor = implemented_subtransforms[i]; while ((ntest % factor) == 0) { ntest = ntest / factor; factors[nf] = factor; nf++; } i++; } /* deal with any other even prime factors (there is only one) */ factor = 2; while ((ntest % factor) == 0 && (ntest != 1)) { ntest = ntest / factor; factors[nf] = factor; nf++; } /* deal with any other odd prime factors */ factor = 3; while (ntest != 1) { while ((ntest % factor) != 0) { factor += 2; } ntest = ntest / factor; factors[nf] = factor; nf++; } /* check that the factorization is correct */ { size_t product = 1; for (i = 0; i < nf; i++) { product *= factors[i]; } if (product != n) { GSL_ERROR ("factorization failed", GSL_ESANITY); } } *n_factors = nf; return 0; } static int fft_binary_logn (const size_t n) { size_t ntest ; size_t binary_logn = 0 ; size_t k = 1; while (k < n) { k *= 2; binary_logn++; } ntest = (1 << binary_logn) ; if (n != ntest ) { return -1 ; /* n is not a power of 2 */ } return binary_logn; } praat-6.0.04/external/gsl/gsl_fft__factorize.h000066400000000000000000000023211261542461700213270ustar00rootroot00000000000000/* fft/factorize.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static int fft_complex_factorize (const size_t n, size_t *nf, size_t factors[]); static int fft_halfcomplex_factorize (const size_t n, size_t *nf, size_t factors[]); static int fft_real_factorize (const size_t n, size_t *nf, size_t factors[]); static int fft_factorize (const size_t n, const size_t implemented_subtransforms[], size_t *n_factors, size_t factors[]); static int fft_binary_logn (const size_t n) ; praat-6.0.04/external/gsl/gsl_fft__fft.c000066400000000000000000000056401261542461700201220ustar00rootroot00000000000000#include "gsl__config.h" #include #include #include #include #include "gsl_errno.h" #include "gsl_complex.h" #include "gsl_fft_complex.h" #include "gsl_fft_complex_float.h" #define BASE_DOUBLE #include "templates_on.h" #include "gsl_fft__bitreverse.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_fft__bitreverse.c" #include "templates_off.h" #undef BASE_FLOAT #include "gsl_fft__factorize.c" #define BASE_DOUBLE #include "templates_on.h" #include "gsl_fft__c_init.c" #include "gsl_fft__c_main.c" #include "gsl_fft__c_pass_2.c" #include "gsl_fft__c_pass_3.c" #include "gsl_fft__c_pass_4.c" #include "gsl_fft__c_pass_5.c" #include "gsl_fft__c_pass_6.c" #include "gsl_fft__c_pass_7.c" #include "gsl_fft__c_pass_n.c" #include "gsl_fft__c_radix2.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_fft__c_init.c" #include "gsl_fft__c_main.c" #include "gsl_fft__c_pass_2.c" #include "gsl_fft__c_pass_3.c" #include "gsl_fft__c_pass_4.c" #include "gsl_fft__c_pass_5.c" #include "gsl_fft__c_pass_6.c" #include "gsl_fft__c_pass_7.c" #include "gsl_fft__c_pass_n.c" #include "gsl_fft__c_radix2.c" #include "templates_off.h" #undef BASE_FLOAT #include "gsl_fft_halfcomplex.h" #include "gsl_fft_halfcomplex_float.h" #define BASE_DOUBLE #include "templates_on.h" #include "gsl_fft__hc_init.c" #include "gsl_fft__hc_main.c" #include "gsl_fft__hc_pass_2.c" #include "gsl_fft__hc_pass_3.c" #include "gsl_fft__hc_pass_4.c" #include "gsl_fft__hc_pass_5.c" #include "gsl_fft__hc_pass_n.c" #include "gsl_fft__hc_radix2.c" #include "gsl_fft__hc_unpack.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_fft__hc_init.c" #include "gsl_fft__hc_main.c" #include "gsl_fft__hc_pass_2.c" #include "gsl_fft__hc_pass_3.c" #include "gsl_fft__hc_pass_4.c" #include "gsl_fft__hc_pass_5.c" #include "gsl_fft__hc_pass_n.c" #include "gsl_fft__hc_radix2.c" #include "gsl_fft__hc_unpack.c" #include "templates_off.h" #undef BASE_FLOAT #include "gsl_fft_real.h" #include "gsl_fft_real_float.h" #define BASE_DOUBLE #include "templates_on.h" #include "gsl_fft__real_init.c" #include "gsl_fft__real_main.c" #include "gsl_fft__real_pass_2.c" #include "gsl_fft__real_pass_3.c" #include "gsl_fft__real_pass_4.c" #include "gsl_fft__real_pass_5.c" #include "gsl_fft__real_pass_n.c" #include "gsl_fft__real_radix2.c" #include "gsl_fft__real_unpack.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_fft__real_init.c" #include "gsl_fft__real_main.c" #include "gsl_fft__real_pass_2.c" #include "gsl_fft__real_pass_3.c" #include "gsl_fft__real_pass_4.c" #include "gsl_fft__real_pass_5.c" #include "gsl_fft__real_pass_n.c" #include "gsl_fft__real_radix2.c" #include "gsl_fft__real_unpack.c" #include "templates_off.h" #undef BASE_FLOAT praat-6.0.04/external/gsl/gsl_fft__hc_init.c000066400000000000000000000063431261542461700207610ustar00rootroot00000000000000/* fft/hc_init.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ TYPE(gsl_fft_halfcomplex_wavetable) * FUNCTION(gsl_fft_halfcomplex_wavetable,alloc) (size_t n) { int status; size_t i; size_t n_factors; size_t t, product, product_1, q; double d_theta; TYPE(gsl_fft_halfcomplex_wavetable) * wavetable ; if (n == 0) { GSL_ERROR_VAL ("length n must be positive integer", GSL_EDOM, 0); } wavetable = (TYPE(gsl_fft_halfcomplex_wavetable) *) malloc(sizeof(TYPE(gsl_fft_halfcomplex_wavetable))); if (wavetable == NULL) { GSL_ERROR_VAL ("failed to allocate struct", GSL_ENOMEM, 0); } wavetable->trig = (TYPE(gsl_complex) *) malloc (n * sizeof (TYPE(gsl_complex))); if (wavetable->trig == NULL) { /* error in constructor, prevent memory leak */ free(wavetable) ; GSL_ERROR_VAL ("failed to allocate trigonometric lookup table", GSL_ENOMEM, 0); } wavetable->n = n ; status = fft_halfcomplex_factorize (n, &n_factors, wavetable->factor); if (status) { /* error in constructor, prevent memory leak */ free(wavetable->trig) ; free(wavetable) ; GSL_ERROR_VAL ("factorization failed", GSL_EFACTOR, 0); } wavetable->nf = n_factors; d_theta = 2.0 * M_PI / ((double) n); t = 0; product = 1; for (i = 0; i < n_factors; i++) { size_t j; const size_t factor = wavetable->factor[i]; wavetable->twiddle[i] = wavetable->trig + t; product_1 = product; /* product_1 = p_(i-1) */ product *= factor; q = n / product; for (j = 1; j < factor; j++) { size_t k; size_t m = 0; for (k = 1; k < (q + 1) / 2; k++) { double theta; m = m + j * product_1; m = m % n; theta = d_theta * m; /* d_theta*j*k*product_1 */ GSL_REAL(wavetable->trig[t]) = cos (theta); GSL_IMAG(wavetable->trig[t]) = sin (theta); t++; } } } if (t > (n / 2)) { /* error in constructor, prevent memory leak */ free(wavetable->trig) ; free(wavetable) ; GSL_ERROR_VAL ("overflowed trigonometric lookup table", GSL_ESANITY, 0); } return wavetable; } void FUNCTION(gsl_fft_halfcomplex_wavetable,free) (TYPE(gsl_fft_halfcomplex_wavetable) * wavetable) { /* release trigonometric lookup tables */ free (wavetable->trig); wavetable->trig = NULL; free (wavetable); } praat-6.0.04/external/gsl/gsl_fft__hc_main.c000066400000000000000000000122221261542461700207330ustar00rootroot00000000000000/* fft/hc_main.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_errno.h" #include "gsl_complex.h" #include "gsl_fft_halfcomplex.h" #include "gsl_fft__hc_pass.h" int FUNCTION(gsl_fft_halfcomplex,backward) (BASE data[], const size_t stride, const size_t n, const TYPE(gsl_fft_halfcomplex_wavetable) * wavetable, TYPE(gsl_fft_real_workspace) * work) { int status = FUNCTION(gsl_fft_halfcomplex,transform) (data, stride, n, wavetable, work) ; return status ; } int FUNCTION(gsl_fft_halfcomplex,inverse) (BASE data[], const size_t stride, const size_t n, const TYPE(gsl_fft_halfcomplex_wavetable) * wavetable, TYPE(gsl_fft_real_workspace) * work) { int status = FUNCTION(gsl_fft_halfcomplex,transform) (data, stride, n, wavetable, work); if (status) { return status; } /* normalize inverse fft with 1/n */ { const double norm = 1.0 / n; size_t i; for (i = 0; i < n; i++) { data[stride*i] *= norm; } } return status; } int FUNCTION(gsl_fft_halfcomplex,transform) (BASE data[], const size_t stride, const size_t n, const TYPE(gsl_fft_halfcomplex_wavetable) * wavetable, TYPE(gsl_fft_real_workspace) * work) { BASE * const scratch = work->scratch; BASE * in; BASE * out; size_t istride, ostride ; size_t factor, product, q; size_t i; size_t nf; int state; int product_1; int tskip; TYPE(gsl_complex) *twiddle1, *twiddle2, *twiddle3, *twiddle4; if (n == 0) { GSL_ERROR ("length n must be positive integer", GSL_EDOM); } if (n == 1) { /* FFT of one data point is the identity */ return 0; } if (n != wavetable->n) { GSL_ERROR ("wavetable does not match length of data", GSL_EINVAL); } if (n != work->n) { GSL_ERROR ("workspace does not match length of data", GSL_EINVAL); } nf = wavetable->nf; product = 1; state = 0; for (i = 0; i < nf; i++) { factor = wavetable->factor[i]; product_1 = product; product *= factor; q = n / product; tskip = (q + 1) / 2 - 1; if (state == 0) { in = data; istride = stride; out = scratch; ostride = 1; state = 1; } else { in = scratch; istride = 1; out = data; ostride = stride; state = 0; } if (factor == 2) { twiddle1 = wavetable->twiddle[i]; FUNCTION(fft_halfcomplex,pass_2) (in, istride, out, ostride, product, n, twiddle1); } else if (factor == 3) { twiddle1 = wavetable->twiddle[i]; twiddle2 = twiddle1 + tskip; FUNCTION(fft_halfcomplex,pass_3) (in, istride, out, ostride, product, n, twiddle1, twiddle2); } else if (factor == 4) { twiddle1 = wavetable->twiddle[i]; twiddle2 = twiddle1 + tskip; twiddle3 = twiddle2 + tskip; FUNCTION(fft_halfcomplex,pass_4) (in, istride, out, ostride, product, n, twiddle1, twiddle2, twiddle3); } else if (factor == 5) { twiddle1 = wavetable->twiddle[i]; twiddle2 = twiddle1 + tskip; twiddle3 = twiddle2 + tskip; twiddle4 = twiddle3 + tskip; FUNCTION(fft_halfcomplex,pass_5) (in, istride, out, ostride, product, n, twiddle1, twiddle2, twiddle3, twiddle4); } else { twiddle1 = wavetable->twiddle[i]; FUNCTION(fft_halfcomplex,pass_n) (in, istride, out, ostride, factor, product, n, twiddle1); } } if (state == 1) /* copy results back from scratch to data */ { for (i = 0; i < n; i++) { data[stride*i] = scratch[i] ; } } return 0; } praat-6.0.04/external/gsl/gsl_fft__hc_pass.h000066400000000000000000000063761261542461700207770ustar00rootroot00000000000000/* fft/hc_pass.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl_fft__complex_internal.h" static void FUNCTION(fft_halfcomplex,pass_2) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle[]); static void FUNCTION(fft_halfcomplex,pass_3) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle1[], const TYPE(gsl_complex) twiddle2[]); static void FUNCTION(fft_halfcomplex,pass_4) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle1[], const TYPE(gsl_complex) twiddle2[], const TYPE(gsl_complex) twiddle3[]); static void FUNCTION(fft_halfcomplex,pass_5) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle1[], const TYPE(gsl_complex) twiddle2[], const TYPE(gsl_complex) twiddle3[], const TYPE(gsl_complex) twiddle4[]); static void FUNCTION(fft_halfcomplex,pass_n) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const size_t factor, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle[]); praat-6.0.04/external/gsl/gsl_fft__hc_pass_2.c000066400000000000000000000063711261542461700212060ustar00rootroot00000000000000/* fft/hc_pass_2.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static void FUNCTION(fft_halfcomplex,pass_2) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle[]) { size_t i, j, k, k1, jump; size_t factor, q, m, product_1; i = 0; j = 0; factor = 2; m = n / factor; q = n / product; product_1 = product / factor; jump = (factor - 1) * q; for (k1 = 0; k1 < product_1; k1++) { const ATOMIC r0 = VECTOR(in,istride,2 * k1 * q); const ATOMIC r1 = VECTOR(in,istride,2 * k1 * q + 2 * q - 1); const ATOMIC s0 = r0 + r1; const ATOMIC s1 = r0 - r1; VECTOR(out,ostride,q * k1) = s0; VECTOR(out,ostride,q * k1 + m) = s1; } if (q == 1) return; for (k = 1; k < (q + 1) / 2; k++) { const ATOMIC w_real = GSL_REAL(twiddle[k - 1]); const ATOMIC w_imag = GSL_IMAG(twiddle[k - 1]); for (k1 = 0; k1 < product_1; k1++) { const size_t from0 = 2 * k1 * q + 2 * k - 1; const size_t from1 = 2 * k1 * q - 2 * k + 2 * q - 1; const ATOMIC z0_real = VECTOR(in,istride,from0); const ATOMIC z0_imag = VECTOR(in,istride,from0 + 1); const ATOMIC z1_real = VECTOR(in,istride,from1); const ATOMIC z1_imag = VECTOR(in,istride,from1 + 1); /* compute x = W(2) z */ /* x0 = z0 + z1 */ const ATOMIC x0_real = z0_real + z1_real; const ATOMIC x0_imag = z0_imag - z1_imag; /* x1 = z0 - z1 */ const ATOMIC x1_real = z0_real - z1_real; const ATOMIC x1_imag = z0_imag + z1_imag; const size_t to0 = k1 * q + 2 * k - 1; const size_t to1 = to0 + m; VECTOR(out,ostride,to0) = x0_real; VECTOR(out,ostride,to0 + 1) = x0_imag; VECTOR(out,ostride,to1) = w_real * x1_real - w_imag * x1_imag; VECTOR(out,ostride,to1 + 1) = w_imag * x1_real + w_real * x1_imag; } } if (q % 2 == 1) return; for (k1 = 0; k1 < product_1; k1++) { const size_t from0 = 2 * k1 * q + q - 1; const size_t to0 = k1 * q + q - 1; const size_t to1 = to0 + m; VECTOR(out,ostride,to0) = 2 * VECTOR(in,istride,from0); VECTOR(out,ostride,to1) = -2 * VECTOR(in,istride,from0 + 1); } return; } praat-6.0.04/external/gsl/gsl_fft__hc_pass_3.c000066400000000000000000000123571261542461700212100ustar00rootroot00000000000000/* fft/hc_pass_3.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static void FUNCTION(fft_halfcomplex,pass_3) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle1[], const TYPE(gsl_complex) twiddle2[]) { size_t i, j, k, k1, jump; size_t factor, q, m, product_1; ATOMIC tau = sqrt (3.0) / 2.0; i = 0; j = 0; factor = 3; m = n / factor; q = n / product; product_1 = product / factor; jump = (factor - 1) * q; for (k1 = 0; k1 < product_1; k1++) { const size_t from0 = 3 * k1 * q; const size_t from1 = from0 + 2 * q - 1; const ATOMIC z0_real = VECTOR(in,istride,from0); const ATOMIC z1_real = VECTOR(in,istride,from1); const ATOMIC z1_imag = VECTOR(in,istride,from1 + 1); const ATOMIC t1_real = 2 * z1_real; const ATOMIC t2_real = z0_real - z1_real; const ATOMIC t3_imag = 2 * tau * z1_imag; const size_t to0 = q * k1; const size_t to1 = to0 + m; const size_t to2 = to1 + m; VECTOR(out,ostride,to0) = z0_real + t1_real; VECTOR(out,ostride,to1) = t2_real - t3_imag; VECTOR(out,ostride,to2) = t2_real + t3_imag; } if (q == 1) return; for (k = 1; k < (q + 1) / 2; k++) { const ATOMIC w1_real = GSL_REAL(twiddle1[k - 1]); const ATOMIC w1_imag = GSL_IMAG(twiddle1[k - 1]); const ATOMIC w2_real = GSL_REAL(twiddle2[k - 1]); const ATOMIC w2_imag = GSL_IMAG(twiddle2[k - 1]); for (k1 = 0; k1 < product_1; k1++) { const size_t from0 = 3 * k1 * q + 2 * k - 1; const size_t from1 = from0 + 2 * q; const size_t from2 = 3 * k1 * q - 2 * k + 2 * q - 1; const ATOMIC z0_real = VECTOR(in,istride,from0); const ATOMIC z0_imag = VECTOR(in,istride,from0 + 1); const ATOMIC z1_real = VECTOR(in,istride,from1); const ATOMIC z1_imag = VECTOR(in,istride,from1 + 1); const ATOMIC z2_real = VECTOR(in,istride,from2); const ATOMIC z2_imag = -VECTOR(in,istride,from2 + 1); /* compute x = W(3) z */ /* t1 = z1 + z2 */ const ATOMIC t1_real = z1_real + z2_real; const ATOMIC t1_imag = z1_imag + z2_imag; /* t2 = z0 - t1/2 */ const ATOMIC t2_real = z0_real - t1_real / 2.0; const ATOMIC t2_imag = z0_imag - t1_imag / 2.0; /* t3 = sin(pi/3)*(z1 - z2) */ const ATOMIC t3_real = tau * (z1_real - z2_real); const ATOMIC t3_imag = tau * (z1_imag - z2_imag); /* x0 = z0 + t1 */ const ATOMIC x0_real = z0_real + t1_real; const ATOMIC x0_imag = z0_imag + t1_imag; /* x1 = t2 + i t3 */ const ATOMIC x1_real = t2_real - t3_imag; const ATOMIC x1_imag = t2_imag + t3_real; /* x2 = t2 - i t3 */ const ATOMIC x2_real = t2_real + t3_imag; const ATOMIC x2_imag = t2_imag - t3_real; const size_t to0 = k1 * q + 2 * k - 1; const size_t to1 = to0 + m; const size_t to2 = to1 + m; VECTOR(out,ostride,to0) = x0_real; VECTOR(out,ostride,to0 + 1) = x0_imag; VECTOR(out,ostride,to1) = w1_real * x1_real - w1_imag * x1_imag; VECTOR(out,ostride,to1 + 1) = w1_imag * x1_real + w1_real * x1_imag; VECTOR(out,ostride,to2) = w2_real * x2_real - w2_imag * x2_imag; VECTOR(out,ostride,to2 + 1) = w2_imag * x2_real + w2_real * x2_imag; } } if (q % 2 == 1) return; for (k1 = 0; k1 < product_1; k1++) { const size_t from0 = 3 * k1 * q + q - 1; const size_t from1 = from0 + 2 * q; const ATOMIC z0_real = VECTOR(in,istride,from0); const ATOMIC z0_imag = VECTOR(in,istride,from0 + 1); const ATOMIC z1_real = VECTOR(in,istride,from1); const ATOMIC t1_real = z0_real - z1_real; const ATOMIC t2_real = 2 * tau * z0_imag; const ATOMIC x0_real = 2 * z0_real + z1_real; const ATOMIC x1_real = t1_real - t2_real; const ATOMIC x2_real = -t1_real - t2_real; const size_t to0 = k1 * q + q - 1; const size_t to1 = to0 + m; const size_t to2 = to1 + m; VECTOR(out,ostride,to0) = x0_real; VECTOR(out,ostride,to1) = x1_real; VECTOR(out,ostride,to2) = x2_real; } return; } praat-6.0.04/external/gsl/gsl_fft__hc_pass_4.c000066400000000000000000000146621261542461700212120ustar00rootroot00000000000000/* fft/hc_pass_4.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static void FUNCTION(fft_halfcomplex,pass_4) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle1[], const TYPE(gsl_complex) twiddle2[], const TYPE(gsl_complex) twiddle3[]) { size_t i, j, k, k1, jump; size_t factor, q, m, product_1; i = 0; j = 0; factor = 4; m = n / factor; q = n / product; product_1 = product / factor; jump = (factor - 1) * q; for (k1 = 0; k1 < product_1; k1++) { const size_t from0 = 4 * k1 * q; const size_t from1 = from0 + 2 * q - 1; const size_t from2 = from1 + 2 * q; const ATOMIC z0_real = VECTOR(in,istride,from0); const ATOMIC z1_real = VECTOR(in,istride,from1); const ATOMIC z1_imag = VECTOR(in,istride,from1 + 1); const ATOMIC z2_real = VECTOR(in,istride,from2); const ATOMIC t1_real = z0_real + z2_real; const ATOMIC t2_real = 2 * z1_real; const ATOMIC t3_real = z0_real - z2_real; const ATOMIC t4_imag = 2 * z1_imag; const size_t to0 = q * k1; const size_t to1 = to0 + m; const size_t to2 = to1 + m; const size_t to3 = to2 + m; VECTOR(out,ostride,to0) = t1_real + t2_real; VECTOR(out,ostride,to1) = t3_real - t4_imag; VECTOR(out,ostride,to2) = t1_real - t2_real; VECTOR(out,ostride,to3) = t3_real + t4_imag; } if (q == 1) return; for (k = 1; k < (q + 1) / 2; k++) { const ATOMIC w1_real = GSL_REAL(twiddle1[k - 1]); const ATOMIC w1_imag = GSL_IMAG(twiddle1[k - 1]); const ATOMIC w2_real = GSL_REAL(twiddle2[k - 1]); const ATOMIC w2_imag = GSL_IMAG(twiddle2[k - 1]); const ATOMIC w3_real = GSL_REAL(twiddle3[k - 1]); const ATOMIC w3_imag = GSL_IMAG(twiddle3[k - 1]); for (k1 = 0; k1 < product_1; k1++) { const size_t from0 = 4 * k1 * q + 2 * k - 1; const size_t from1 = from0 + 2 * q; const size_t from2 = 4 * k1 * q - 2 * k + 2 * q - 1; const size_t from3 = from2 + 2 * q; const ATOMIC z0_real = VECTOR(in,istride,from0); const ATOMIC z0_imag = VECTOR(in,istride,from0 + 1); const ATOMIC z1_real = VECTOR(in,istride,from1); const ATOMIC z1_imag = VECTOR(in,istride,from1 + 1); const ATOMIC z2_real = VECTOR(in,istride,from3); const ATOMIC z2_imag = -VECTOR(in,istride,from3 + 1); const ATOMIC z3_real = VECTOR(in,istride,from2); const ATOMIC z3_imag = -VECTOR(in,istride,from2 + 1); /* compute x = W(4) z */ /* t1 = z0 + z2 */ const ATOMIC t1_real = z0_real + z2_real; const ATOMIC t1_imag = z0_imag + z2_imag; /* t2 = z1 + z3 */ const ATOMIC t2_real = z1_real + z3_real; const ATOMIC t2_imag = z1_imag + z3_imag; /* t3 = z0 - z2 */ const ATOMIC t3_real = z0_real - z2_real; const ATOMIC t3_imag = z0_imag - z2_imag; /* t4 = (z1 - z3) */ const ATOMIC t4_real = (z1_real - z3_real); const ATOMIC t4_imag = (z1_imag - z3_imag); /* x0 = t1 + t2 */ const ATOMIC x0_real = t1_real + t2_real; const ATOMIC x0_imag = t1_imag + t2_imag; /* x1 = t3 + i t4 */ const ATOMIC x1_real = t3_real - t4_imag; const ATOMIC x1_imag = t3_imag + t4_real; /* x2 = t1 - t2 */ const ATOMIC x2_real = t1_real - t2_real; const ATOMIC x2_imag = t1_imag - t2_imag; /* x3 = t3 - i t4 */ const ATOMIC x3_real = t3_real + t4_imag; const ATOMIC x3_imag = t3_imag - t4_real; const size_t to0 = k1 * q + 2 * k - 1; const size_t to1 = to0 + m; const size_t to2 = to1 + m; const size_t to3 = to2 + m; VECTOR(out,ostride,to0) = x0_real; VECTOR(out,ostride,to0 + 1) = x0_imag; VECTOR(out,ostride,to1) = w1_real * x1_real - w1_imag * x1_imag; VECTOR(out,ostride,to1 + 1) = w1_imag * x1_real + w1_real * x1_imag; VECTOR(out,ostride,to2) = w2_real * x2_real - w2_imag * x2_imag; VECTOR(out,ostride,to2 + 1) = w2_imag * x2_real + w2_real * x2_imag; /* to3 = w3 * x3 */ VECTOR(out,ostride,to3) = w3_real * x3_real - w3_imag * x3_imag; VECTOR(out,ostride,to3 + 1) = w3_real * x3_imag + w3_imag * x3_real; } } if (q % 2 == 1) return; for (k1 = 0; k1 < product_1; k1++) { const size_t from0 = 4 * k1 * q + q - 1; const size_t from1 = from0 + 2 * q; const ATOMIC z0_real = VECTOR(in,istride,from0); const ATOMIC z0_imag = VECTOR(in,istride,from0 + 1); const ATOMIC z1_real = VECTOR(in,istride,from1); const ATOMIC z1_imag = VECTOR(in,istride,from1 + 1); const ATOMIC t1_real = sqrt (2.0) * (z0_imag + z1_imag); const ATOMIC t2_real = sqrt (2.0) * (z0_real - z1_real); const ATOMIC x0_real = 2 * (z0_real + z1_real); const ATOMIC x1_real = t2_real - t1_real; const ATOMIC x2_real = 2 * (z1_imag - z0_imag); const ATOMIC x3_real = -(t2_real + t1_real); const size_t to0 = k1 * q + q - 1; const size_t to1 = to0 + m; const size_t to2 = to1 + m; const size_t to3 = to2 + m; VECTOR(out,ostride,to0) = x0_real; VECTOR(out,ostride,to1) = x1_real; VECTOR(out,ostride,to2) = x2_real; VECTOR(out,ostride,to3) = x3_real; } return; } praat-6.0.04/external/gsl/gsl_fft__hc_pass_5.c000066400000000000000000000227551261542461700212150ustar00rootroot00000000000000/* fft/hc_pass_5.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static void FUNCTION(fft_halfcomplex,pass_5) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle1[], const TYPE(gsl_complex) twiddle2[], const TYPE(gsl_complex) twiddle3[], const TYPE(gsl_complex) twiddle4[]) { size_t i, j, k, k1, jump; size_t factor, q, m, product_1; const ATOMIC sina = sin (2.0 * M_PI / 5.0); const ATOMIC sinb = sin (2.0 * M_PI / 10.0); i = 0; j = 0; factor = 5; m = n / factor; q = n / product; product_1 = product / factor; jump = (factor - 1) * q; for (k1 = 0; k1 < product_1; k1++) { const size_t from0 = 5 * k1 * q; const size_t from1 = from0 + 2 * q - 1; const size_t from2 = from1 + 2 * q; const ATOMIC z0_real = VECTOR(in,istride,from0); const ATOMIC z1_real = VECTOR(in,istride,from1); const ATOMIC z1_imag = VECTOR(in,istride,from1 + 1); const ATOMIC z2_real = VECTOR(in,istride,from2); const ATOMIC z2_imag = VECTOR(in,istride,from2 + 1); const ATOMIC t1_real = 2 * (z1_real + z2_real); const ATOMIC t2_real = 2 * (sqrt (5.0) / 4.0) * (z1_real - z2_real); const ATOMIC t3_real = z0_real - t1_real / 4.0; const ATOMIC t4_real = t2_real + t3_real; const ATOMIC t5_real = -t2_real + t3_real; const ATOMIC t6_imag = 2 * (sina * z1_imag + sinb * z2_imag); const ATOMIC t7_imag = 2 * (sinb * z1_imag - sina * z2_imag); const ATOMIC x0_real = z0_real + t1_real; const ATOMIC x1_real = t4_real - t6_imag; const ATOMIC x2_real = t5_real - t7_imag; const ATOMIC x3_real = t5_real + t7_imag; const ATOMIC x4_real = t4_real + t6_imag; const size_t to0 = q * k1; const size_t to1 = to0 + m; const size_t to2 = to1 + m; const size_t to3 = to2 + m; const size_t to4 = to3 + m; VECTOR(out,ostride,to0) = x0_real; VECTOR(out,ostride,to1) = x1_real; VECTOR(out,ostride,to2) = x2_real; VECTOR(out,ostride,to3) = x3_real; VECTOR(out,ostride,to4) = x4_real; } if (q == 1) return; for (k = 1; k < (q + 1) / 2; k++) { const ATOMIC w1_real = GSL_REAL(twiddle1[k - 1]); const ATOMIC w1_imag = GSL_IMAG(twiddle1[k - 1]); const ATOMIC w2_real = GSL_REAL(twiddle2[k - 1]); const ATOMIC w2_imag = GSL_IMAG(twiddle2[k - 1]); const ATOMIC w3_real = GSL_REAL(twiddle3[k - 1]); const ATOMIC w3_imag = GSL_IMAG(twiddle3[k - 1]); const ATOMIC w4_real = GSL_REAL(twiddle4[k - 1]); const ATOMIC w4_imag = GSL_IMAG(twiddle4[k - 1]); for (k1 = 0; k1 < product_1; k1++) { const size_t from0 = 5 * k1 * q + 2 * k - 1; const size_t from1 = from0 + 2 * q; const size_t from2 = from1 + 2 * q; const size_t from3 = 5 * k1 * q - 2 * k + 2 * q - 1; const size_t from4 = from3 + 2 * q; const ATOMIC z0_real = VECTOR(in,istride,from0); const ATOMIC z0_imag = VECTOR(in,istride,from0 + 1); const ATOMIC z1_real = VECTOR(in,istride,from1); const ATOMIC z1_imag = VECTOR(in,istride,from1 + 1); const ATOMIC z2_real = VECTOR(in,istride,from2); const ATOMIC z2_imag = VECTOR(in,istride,from2 + 1); const ATOMIC z3_real = VECTOR(in,istride,from4); const ATOMIC z3_imag = -VECTOR(in,istride,from4 + 1); const ATOMIC z4_real = VECTOR(in,istride,from3); const ATOMIC z4_imag = -VECTOR(in,istride,from3 + 1); /* compute x = W(5) z */ /* t1 = z1 + z4 */ const ATOMIC t1_real = z1_real + z4_real; const ATOMIC t1_imag = z1_imag + z4_imag; /* t2 = z2 + z3 */ const ATOMIC t2_real = z2_real + z3_real; const ATOMIC t2_imag = z2_imag + z3_imag; /* t3 = z1 - z4 */ const ATOMIC t3_real = z1_real - z4_real; const ATOMIC t3_imag = z1_imag - z4_imag; /* t4 = z2 - z3 */ const ATOMIC t4_real = z2_real - z3_real; const ATOMIC t4_imag = z2_imag - z3_imag; /* t5 = t1 + t2 */ const ATOMIC t5_real = t1_real + t2_real; const ATOMIC t5_imag = t1_imag + t2_imag; /* t6 = (sqrt(5)/4)(t1 - t2) */ const ATOMIC t6_real = (sqrt (5.0) / 4.0) * (t1_real - t2_real); const ATOMIC t6_imag = (sqrt (5.0) / 4.0) * (t1_imag - t2_imag); /* t7 = z0 - ((t5)/4) */ const ATOMIC t7_real = z0_real - t5_real / 4.0; const ATOMIC t7_imag = z0_imag - t5_imag / 4.0; /* t8 = t7 + t6 */ const ATOMIC t8_real = t7_real + t6_real; const ATOMIC t8_imag = t7_imag + t6_imag; /* t9 = t7 - t6 */ const ATOMIC t9_real = t7_real - t6_real; const ATOMIC t9_imag = t7_imag - t6_imag; /* t10 = sin(2 pi/5) t3 + sin(2 pi/10) t4 */ const ATOMIC t10_real = sina * t3_real + sinb * t4_real; const ATOMIC t10_imag = sina * t3_imag + sinb * t4_imag; /* t11 = sin(2 pi/10) t3 - sin(2 pi/5) t4 */ const ATOMIC t11_real = sinb * t3_real - sina * t4_real; const ATOMIC t11_imag = sinb * t3_imag - sina * t4_imag; /* x0 = z0 + t5 */ const ATOMIC x0_real = z0_real + t5_real; const ATOMIC x0_imag = z0_imag + t5_imag; /* x1 = t8 + i t10 */ const ATOMIC x1_real = t8_real - t10_imag; const ATOMIC x1_imag = t8_imag + t10_real; /* x2 = t9 + i t11 */ const ATOMIC x2_real = t9_real - t11_imag; const ATOMIC x2_imag = t9_imag + t11_real; /* x3 = t9 - i t11 */ const ATOMIC x3_real = t9_real + t11_imag; const ATOMIC x3_imag = t9_imag - t11_real; /* x4 = t8 - i t10 */ const ATOMIC x4_real = t8_real + t10_imag; const ATOMIC x4_imag = t8_imag - t10_real; const size_t to0 = k1 * q + 2 * k - 1; const size_t to1 = to0 + m; const size_t to2 = to1 + m; const size_t to3 = to2 + m; const size_t to4 = to3 + m; /* apply twiddle factors */ /* to0 = 1 * x0 */ VECTOR(out,ostride,to0) = x0_real; VECTOR(out,ostride,to0 + 1) = x0_imag; /* to1 = w1 * x1 */ VECTOR(out,ostride,to1) = w1_real * x1_real - w1_imag * x1_imag; VECTOR(out,ostride,to1 + 1) = w1_real * x1_imag + w1_imag * x1_real; /* to2 = w2 * x2 */ VECTOR(out,ostride,to2) = w2_real * x2_real - w2_imag * x2_imag; VECTOR(out,ostride,to2 + 1) = w2_real * x2_imag + w2_imag * x2_real; /* to3 = w3 * x3 */ VECTOR(out,ostride,to3) = w3_real * x3_real - w3_imag * x3_imag; VECTOR(out,ostride,to3 + 1) = w3_real * x3_imag + w3_imag * x3_real; /* to4 = w4 * x4 */ VECTOR(out,ostride,to4) = w4_real * x4_real - w4_imag * x4_imag; VECTOR(out,ostride,to4 + 1) = w4_real * x4_imag + w4_imag * x4_real; } } if (q % 2 == 1) return; for (k1 = 0; k1 < product_1; k1++) { const size_t from0 = 5 * k1 * q + q - 1; const size_t from1 = from0 + 2 * q; const size_t from2 = from1 + 2 * q; const ATOMIC z0_real = 2 * VECTOR(in,istride,from0); const ATOMIC z0_imag = 2 * VECTOR(in,istride,from0 + 1); const ATOMIC z1_real = 2 * VECTOR(in,istride,from1); const ATOMIC z1_imag = 2 * VECTOR(in,istride,from1 + 1); const ATOMIC z2_real = VECTOR(in,istride,from2); const ATOMIC t1_real = z0_real + z1_real; const ATOMIC t2_real = (t1_real / 4.0) - z2_real; const ATOMIC t3_real = (sqrt (5.0) / 4.0) * (z0_real - z1_real); const ATOMIC t4_real = sinb * z0_imag + sina * z1_imag; const ATOMIC t5_real = sina * z0_imag - sinb * z1_imag; const ATOMIC t6_real = t3_real + t2_real; const ATOMIC t7_real = t3_real - t2_real; const ATOMIC x0_real = t1_real + z2_real; const ATOMIC x1_real = t6_real - t4_real; const ATOMIC x2_real = t7_real - t5_real; const ATOMIC x3_real = -t7_real - t5_real; const ATOMIC x4_real = -t6_real - t4_real; const size_t to0 = k1 * q + q - 1; const size_t to1 = to0 + m; const size_t to2 = to1 + m; const size_t to3 = to2 + m; const size_t to4 = to3 + m; VECTOR(out,ostride,to0) = x0_real; VECTOR(out,ostride,to1) = x1_real; VECTOR(out,ostride,to2) = x2_real; VECTOR(out,ostride,to3) = x3_real; VECTOR(out,ostride,to4) = x4_real; } return; } praat-6.0.04/external/gsl/gsl_fft__hc_pass_n.c000066400000000000000000000200651261542461700212760ustar00rootroot00000000000000/* fft/hc_pass_n.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static void FUNCTION(fft_halfcomplex,pass_n) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const size_t factor, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle[]) { size_t k, k1; const size_t m = n / factor; const size_t q = n / product; const size_t product_1 = product / factor; size_t e1, e2; const double d_theta = 2.0 * M_PI / ((double) factor); const ATOMIC cos_d_theta = cos (d_theta); const ATOMIC sin_d_theta = sin (d_theta); for (k1 = 0; k1 < product_1; k1++) { /* compute z = W(factor) x, for x halfcomplex */ ATOMIC dw_real = 1.0, dw_imag = 0.0; for (e1 = 0; e1 < factor; e1++) { ATOMIC sum_real = 0.0; ATOMIC w_real = 1.0, w_imag = 0.0; if (e1 > 0) { ATOMIC tmp_real = dw_real * cos_d_theta - dw_imag * sin_d_theta; ATOMIC tmp_imag = dw_real * sin_d_theta + dw_imag * cos_d_theta; dw_real = tmp_real; dw_imag = tmp_imag; } for (e2 = 0; e2 <= factor - e2; e2++) { ATOMIC z_real, z_imag; if (e2 > 0) { ATOMIC tmp_real = dw_real * w_real - dw_imag * w_imag; ATOMIC tmp_imag = dw_real * w_imag + dw_imag * w_real; w_real = tmp_real; w_imag = tmp_imag; } if (e2 == 0) { size_t from_idx = factor * k1 * q; z_real = VECTOR(in,istride,from_idx); z_imag = 0.0; sum_real += w_real * z_real - w_imag * z_imag; } else if (e2 == factor - e2) { size_t from_idx = factor * q * k1 + 2 * e2 * q - 1; z_real = VECTOR(in,istride,from_idx); z_imag = 0.0; sum_real += w_real * z_real; } else { size_t from_idx = factor * q * k1 + 2 * e2 * q - 1; z_real = VECTOR(in,istride,from_idx); z_imag = VECTOR(in,istride,from_idx + 1); sum_real += 2 * (w_real * z_real - w_imag * z_imag); } } { const size_t to_idx = q * k1 + e1 * m; VECTOR(out,ostride,to_idx) = sum_real; } } } if (q == 1) return; for (k = 1; k < (q + 1) / 2; k++) { for (k1 = 0; k1 < product_1; k1++) { ATOMIC dw_real = 1.0, dw_imag = 0.0; for (e1 = 0; e1 < factor; e1++) { ATOMIC z_real, z_imag; ATOMIC sum_real = 0.0; ATOMIC sum_imag = 0.0; ATOMIC w_real = 1.0, w_imag = 0.0; if (e1 > 0) { ATOMIC t_real = dw_real * cos_d_theta - dw_imag * sin_d_theta; ATOMIC t_imag = dw_real * sin_d_theta + dw_imag * cos_d_theta; dw_real = t_real; dw_imag = t_imag; } for (e2 = 0; e2 < factor; e2++) { if (e2 > 0) { ATOMIC tmp_real = dw_real * w_real - dw_imag * w_imag; ATOMIC tmp_imag = dw_real * w_imag + dw_imag * w_real; w_real = tmp_real; w_imag = tmp_imag; } if (e2 < factor - e2) { const size_t from0 = factor * k1 * q + 2 * k + 2 * e2 * q - 1; z_real = VECTOR(in,istride,from0); z_imag = VECTOR(in,istride,from0 + 1); } else { const size_t from0 = factor * k1 * q - 2 * k + 2 * (factor - e2) * q - 1; z_real = VECTOR(in,istride,from0); z_imag = -VECTOR(in,istride,from0 + 1); } sum_real += w_real * z_real - w_imag * z_imag; sum_imag += w_real * z_imag + w_imag * z_real; } if (k == 0 || e1 == 0) { w_real = 1.0; w_imag = 0.0; } else { size_t tskip = (q + 1) / 2 - 1; w_real = GSL_REAL(twiddle[k - 1 + tskip * (e1 - 1)]); w_imag = GSL_IMAG(twiddle[k - 1 + tskip * (e1 - 1)]); } { const size_t to0 = k1 * q + 2 * k + e1 * m - 1; VECTOR(out,ostride,to0) = w_real * sum_real - w_imag * sum_imag; VECTOR(out,ostride,to0 + 1) = w_real * sum_imag + w_imag * sum_real; } } } } if (q % 2 == 1) return; { double tw_arg = M_PI / ((double) factor); ATOMIC cos_tw_arg = cos (tw_arg); ATOMIC sin_tw_arg = sin (tw_arg); for (k1 = 0; k1 < product_1; k1++) { ATOMIC dw_real = 1.0, dw_imag = 0.0; ATOMIC tw_real = 1.0, tw_imag = 0.0; for (e1 = 0; e1 < factor; e1++) { ATOMIC w_real, w_imag, z_real, z_imag; ATOMIC sum_real = 0.0; if (e1 > 0) { ATOMIC tmp_real = tw_real * cos_tw_arg - tw_imag * sin_tw_arg; ATOMIC tmp_imag = tw_real * sin_tw_arg + tw_imag * cos_tw_arg; tw_real = tmp_real; tw_imag = tmp_imag; } w_real = tw_real; w_imag = tw_imag; if (e1 > 0) { ATOMIC t_real = dw_real * cos_d_theta - dw_imag * sin_d_theta; ATOMIC t_imag = dw_real * sin_d_theta + dw_imag * cos_d_theta; dw_real = t_real; dw_imag = t_imag; } for (e2 = 0; e2 <= factor - e2 - 1; e2++) { if (e2 > 0) { ATOMIC tmp_real = dw_real * w_real - dw_imag * w_imag; ATOMIC tmp_imag = dw_real * w_imag + dw_imag * w_real; w_real = tmp_real; w_imag = tmp_imag; } if (e2 == factor - e2 - 1) { const size_t from0 = factor * k1 * q + q + 2 * e2 * q - 1; z_real = VECTOR(in,istride,from0); z_imag = 0.0; sum_real += w_real * z_real - w_imag * z_imag; } else { const size_t from0 = factor * k1 * q + q + 2 * e2 * q - 1; z_real = VECTOR(in,istride,from0); z_imag = VECTOR(in,istride,from0 + 1); sum_real += 2 * (w_real * z_real - w_imag * z_imag); } } { const size_t to0 = k1 * q + q + e1 * m - 1; VECTOR(out,ostride,to0) = sum_real; } } } } return; } praat-6.0.04/external/gsl/gsl_fft__hc_radix2.c000066400000000000000000000113351261542461700212040ustar00rootroot00000000000000/* fft/hc_radix2.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ int FUNCTION(gsl_fft_halfcomplex,radix2_backward) (BASE data[], const size_t stride, const size_t n) { int status = FUNCTION(gsl_fft_halfcomplex,radix2_transform) (data, stride, n) ; return status ; } int FUNCTION(gsl_fft_halfcomplex,radix2_inverse) (BASE data[], const size_t stride, const size_t n) { int status = FUNCTION(gsl_fft_halfcomplex,radix2_transform) (data, stride, n); if (status) { return status; } /* normalize inverse fft with 1/n */ { const ATOMIC norm = 1.0 / n; size_t i; for (i = 0; i < n; i++) { data[stride*i] *= norm; } } return status; } int FUNCTION(gsl_fft_halfcomplex,radix2_transform) (BASE data[], const size_t stride, const size_t n) { int result ; size_t p, p_1, q; size_t i; size_t logn = 0; int status; if (n == 1) /* identity operation */ { return 0 ; } /* make sure that n is a power of 2 */ result = fft_binary_logn(n) ; if (result == -1) { GSL_ERROR ("n is not a power of 2", GSL_EINVAL); } else { logn = result ; } /* apply fft recursion */ p = n; q = 1 ; p_1 = n/2 ; for (i = 1; i <= logn; i++) { size_t a, b; /* a = 0 */ for (b = 0; b < q; b++) { const ATOMIC z0 = VECTOR(data,stride,b*p); const ATOMIC z1 = VECTOR(data,stride,b*p + p_1); const ATOMIC t0_real = z0 + z1 ; const ATOMIC t1_real = z0 - z1 ; VECTOR(data,stride,b*p) = t0_real; VECTOR(data,stride,b*p + p_1) = t1_real ; } /* a = 1 ... p_{i-1}/2 - 1 */ { ATOMIC w_real = 1.0; ATOMIC w_imag = 0.0; const ATOMIC theta = 2.0 * M_PI / p; const ATOMIC s = sin (theta); const ATOMIC t = sin (theta / 2.0); const ATOMIC s2 = 2.0 * t * t; for (a = 1; a < (p_1)/2; a++) { /* trignometric recurrence for w-> exp(i theta) w */ { const ATOMIC tmp_real = w_real - s * w_imag - s2 * w_real; const ATOMIC tmp_imag = w_imag + s * w_real - s2 * w_imag; w_real = tmp_real; w_imag = tmp_imag; } for (b = 0; b < q; b++) { ATOMIC z0_real = VECTOR(data,stride,b*p + a) ; ATOMIC z0_imag = VECTOR(data,stride,b*p + p - a) ; ATOMIC z1_real = VECTOR(data,stride,b*p + p_1 - a) ; ATOMIC z1_imag = -VECTOR(data,stride,b*p + p_1 + a) ; /* t0 = z0 + z1 */ ATOMIC t0_real = z0_real + z1_real; ATOMIC t0_imag = z0_imag + z1_imag; /* t1 = (z0 - z1) */ ATOMIC t1_real = z0_real - z1_real; ATOMIC t1_imag = z0_imag - z1_imag; VECTOR(data,stride,b*p + a) = t0_real ; VECTOR(data,stride,b*p + p_1 - a) = t0_imag ; VECTOR(data,stride,b*p + p_1 + a) = (w_real * t1_real - w_imag * t1_imag) ; VECTOR(data,stride,b*p + p - a) = (w_real * t1_imag + w_imag * t1_real) ; } } } if (p_1 > 1) { for (b = 0; b < q; b++) { VECTOR(data,stride,b*p + p_1/2) *= 2 ; VECTOR(data,stride,b*p + p_1 + p_1/2) *= -2 ; } } p_1 = p_1 / 2 ; p = p / 2 ; q = q * 2 ; } /* bit reverse the ordering of output data for decimation in frequency algorithm */ status = FUNCTION(fft_real,bitreverse_order)(data, stride, n, logn) ; return 0; } praat-6.0.04/external/gsl/gsl_fft__hc_unpack.c000066400000000000000000000054761261542461700213050ustar00rootroot00000000000000/* fft/hc_unpack.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ int FUNCTION(gsl_fft_halfcomplex,unpack) (const BASE halfcomplex_coefficient[], BASE complex_coefficient[], const size_t stride, const size_t n) { size_t i; if (n == 0) { GSL_ERROR ("length n must be positive integer", GSL_EDOM); } REAL(complex_coefficient,stride,0) = halfcomplex_coefficient[0]; IMAG(complex_coefficient,stride,0) = 0.0; for (i = 1; i < n - i; i++) { const ATOMIC hc_real = halfcomplex_coefficient[(2 * i - 1) * stride]; const ATOMIC hc_imag = halfcomplex_coefficient[2 * i * stride]; REAL(complex_coefficient,stride,i) = hc_real; IMAG(complex_coefficient,stride,i) = hc_imag; REAL(complex_coefficient,stride,n - i) = hc_real; IMAG(complex_coefficient,stride,n - i) = -hc_imag; } if (i == n - i) { REAL(complex_coefficient,stride,i) = halfcomplex_coefficient[(n - 1) * stride]; IMAG(complex_coefficient,stride,i) = 0.0; } return 0; } int FUNCTION(gsl_fft_halfcomplex,radix2_unpack) (const BASE halfcomplex_coefficient[], BASE complex_coefficient[], const size_t stride, const size_t n) { size_t i; if (n == 0) { GSL_ERROR ("length n must be positive integer", GSL_EDOM); } REAL(complex_coefficient,stride,0) = halfcomplex_coefficient[0]; IMAG(complex_coefficient,stride,0) = 0.0; for (i = 1; i < n - i; i++) { const ATOMIC hc_real = halfcomplex_coefficient[i * stride]; const ATOMIC hc_imag = halfcomplex_coefficient[(n - i) * stride]; REAL(complex_coefficient,stride,i) = hc_real; IMAG(complex_coefficient,stride,i) = hc_imag; REAL(complex_coefficient,stride,n - i) = hc_real; IMAG(complex_coefficient,stride,n - i) = -hc_imag; } if (i == n - i) { REAL(complex_coefficient,stride,i) = halfcomplex_coefficient[i * stride]; IMAG(complex_coefficient,stride,i) = 0.0; } return 0; } praat-6.0.04/external/gsl/gsl_fft__real_init.c000066400000000000000000000103741261542461700213110ustar00rootroot00000000000000/* fft/real_init.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ TYPE(gsl_fft_real_wavetable) * FUNCTION(gsl_fft_real_wavetable,alloc) (size_t n) { int status; size_t i; size_t n_factors; size_t t, product, product_1, q; double d_theta; TYPE(gsl_fft_real_wavetable) * wavetable; if (n == 0) { GSL_ERROR_VAL ("length n must be positive integer", GSL_EDOM, 0); } wavetable = (TYPE(gsl_fft_real_wavetable) *) malloc(sizeof(TYPE(gsl_fft_real_wavetable))); if (wavetable == NULL) { GSL_ERROR_VAL ("failed to allocate struct", GSL_ENOMEM, 0); } if (n == 1) { wavetable->trig = 0; } else { wavetable->trig = (TYPE(gsl_complex) *) malloc ((n / 2) * sizeof (TYPE(gsl_complex))); if (wavetable->trig == NULL) { /* error in constructor, prevent memory leak */ free(wavetable) ; GSL_ERROR_VAL ("failed to allocate trigonometric lookup table", GSL_ENOMEM, 0); } } wavetable->n = n; status = fft_real_factorize (n, &n_factors, wavetable->factor); if (status) { /* error in constructor, prevent memory leak */ free(wavetable->trig); free(wavetable) ; GSL_ERROR_VAL ("factorization failed", GSL_EFACTOR, 0); } wavetable->nf = n_factors; d_theta = 2.0 * M_PI / ((double) n); t = 0; product = 1; for (i = 0; i < wavetable->nf; i++) { size_t j; const size_t factor = wavetable->factor[i]; wavetable->twiddle[i] = wavetable->trig + t; product_1 = product; /* product_1 = p_(i-1) */ product *= factor; q = n / product; for (j = 1; j < factor; j++) { size_t k; size_t m = 0; for (k = 1; k < (product_1 + 1) / 2; k++) { double theta; m = m + j * q; m = m % n; theta = d_theta * m; /* d_theta*j*k*q */ GSL_REAL(wavetable->trig[t]) = cos (theta); GSL_IMAG(wavetable->trig[t]) = sin (theta); t++; } } } if (t > (n / 2)) { /* error in constructor, prevent memory leak */ free(wavetable->trig); free(wavetable) ; GSL_ERROR_VAL ("overflowed trigonometric lookup table", GSL_ESANITY, 0); } return wavetable; } TYPE(gsl_fft_real_workspace) * FUNCTION(gsl_fft_real_workspace,alloc) (size_t n) { TYPE(gsl_fft_real_workspace) * workspace; if (n == 0) { GSL_ERROR_VAL ("length n must be positive integer", GSL_EDOM, 0); } workspace = (TYPE(gsl_fft_real_workspace) *) malloc(sizeof(TYPE(gsl_fft_real_workspace))); if (workspace == NULL) { GSL_ERROR_VAL ("failed to allocate struct", GSL_ENOMEM, 0); } workspace->n = n; workspace->scratch = (BASE *) malloc (n * sizeof (BASE)); if (workspace->scratch == NULL) { /* error in constructor, prevent memory leak */ free(workspace) ; GSL_ERROR_VAL ("failed to allocate scratch space", GSL_ENOMEM, 0); } return workspace; } void FUNCTION(gsl_fft_real_wavetable,free) (TYPE(gsl_fft_real_wavetable) * wavetable) { /* release trigonometric lookup tables */ free (wavetable->trig); wavetable->trig = NULL; free (wavetable) ; } void FUNCTION(gsl_fft_real_workspace,free) (TYPE(gsl_fft_real_workspace) * workspace) { /* release scratch space */ free (workspace->scratch); workspace->scratch = NULL; free (workspace) ; } praat-6.0.04/external/gsl/gsl_fft__real_main.c000066400000000000000000000076541261542461700213010ustar00rootroot00000000000000/* fft/real_main.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_errno.h" #include "gsl_complex.h" #include "gsl_fft_real.h" #include "gsl_fft__real_pass.h" int FUNCTION(gsl_fft_real,transform) (BASE data[], const size_t stride, const size_t n, const TYPE(gsl_fft_real_wavetable) * wavetable, TYPE(gsl_fft_real_workspace) * work) { const size_t nf = wavetable->nf; size_t i; size_t q, product = 1; size_t tskip; size_t product_1; BASE *const scratch = work->scratch; TYPE(gsl_complex) *twiddle1, *twiddle2, *twiddle3, *twiddle4; size_t state = 0; BASE *in = data; size_t istride = stride ; BASE *out = scratch; size_t ostride = 1 ; if (n == 0) { GSL_ERROR ("length n must be positive integer", GSL_EDOM); } if (n == 1) { /* FFT of one data point is the identity */ return 0; } if (n != wavetable->n) { GSL_ERROR ("wavetable does not match length of data", GSL_EINVAL); } if (n != work->n) { GSL_ERROR ("workspace does not match length of data", GSL_EINVAL); } for (i = 0; i < nf; i++) { const size_t factor = wavetable->factor[i]; product_1 = product; product *= factor; q = n / product; tskip = (product_1 + 1) / 2 - 1; if (state == 0) { in = data; istride = stride; out = scratch; ostride = 1; state = 1; } else { in = scratch; istride = 1; out = data; ostride = stride; state = 0; } if (factor == 2) { twiddle1 = wavetable->twiddle[i]; FUNCTION(fft_real,pass_2) (in, istride, out, ostride, product, n, twiddle1); } else if (factor == 3) { twiddle1 = wavetable->twiddle[i]; twiddle2 = twiddle1 + tskip; FUNCTION(fft_real,pass_3) (in, istride, out, ostride, product, n, twiddle1, twiddle2); } else if (factor == 4) { twiddle1 = wavetable->twiddle[i]; twiddle2 = twiddle1 + tskip; twiddle3 = twiddle2 + tskip; FUNCTION(fft_real,pass_4) (in, istride, out, ostride, product, n, twiddle1, twiddle2, twiddle3); } else if (factor == 5) { twiddle1 = wavetable->twiddle[i]; twiddle2 = twiddle1 + tskip; twiddle3 = twiddle2 + tskip; twiddle4 = twiddle3 + tskip; FUNCTION(fft_real,pass_5) (in, istride, out, ostride, product, n, twiddle1, twiddle2, twiddle3, twiddle4); } else { twiddle1 = wavetable->twiddle[i]; FUNCTION(fft_real,pass_n) (in, istride, out, ostride, factor, product, n, twiddle1); } } if (state == 1) /* copy results back from scratch to data */ { for (i = 0; i < n; i++) { data[stride*i] = scratch[i] ; } } return 0; } praat-6.0.04/external/gsl/gsl_fft__real_pass.h000066400000000000000000000065531261542461700213250ustar00rootroot00000000000000/* fft/real_pass.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static void FUNCTION(fft_real,pass_2) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle[]); static void FUNCTION(fft_real,pass_3) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle1[], const TYPE(gsl_complex) twiddle2[]); static void FUNCTION(fft_real,pass_4) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle1[], const TYPE(gsl_complex) twiddle2[], const TYPE(gsl_complex) twiddle3[]); static void FUNCTION(fft_real,pass_5) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle1[], const TYPE(gsl_complex) twiddle2[], const TYPE(gsl_complex) twiddle3[], const TYPE(gsl_complex) twiddle4[]); static void FUNCTION(fft_real,pass_n) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const size_t factor, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle[]); praat-6.0.04/external/gsl/gsl_fft__real_pass_2.c000066400000000000000000000072061261542461700215350ustar00rootroot00000000000000/* fft/real_pass_2.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static void FUNCTION(fft_real,pass_2) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle[]) { size_t k, k1; const size_t factor = 2; const size_t m = n / factor; const size_t q = n / product; const size_t product_1 = product / factor; for (k1 = 0; k1 < q; k1++) { const size_t from0 = k1 * product_1; const size_t from1 = from0 + m; const ATOMIC r0 = VECTOR(in,istride,from0); const ATOMIC r1 = VECTOR(in,istride,from1); const ATOMIC s0 = r0 + r1; const ATOMIC s1 = r0 - r1; const size_t to0 = product * k1; const size_t to1 = to0 + product - 1; VECTOR(out,ostride,to0) = s0; VECTOR(out,ostride,to1) = s1; } if (product_1 == 1) return; for (k = 1; k < (product_1 + 1) / 2; k++) { /* forward real transform: w -> conjugate(w) */ const ATOMIC w_real = GSL_REAL(twiddle[k - 1]); const ATOMIC w_imag = -GSL_IMAG(twiddle[k - 1]); for (k1 = 0; k1 < q; k1++) { const size_t from0 = k1 * product_1 + 2 * k - 1; const size_t from1 = from0 + m; const ATOMIC f0_real = VECTOR(in,istride,from0); const ATOMIC f0_imag = VECTOR(in,istride,from0 + 1); const ATOMIC f1_real = VECTOR(in,istride,from1); const ATOMIC f1_imag = VECTOR(in,istride,from1 + 1); const ATOMIC z0_real = f0_real; const ATOMIC z0_imag = f0_imag; const ATOMIC z1_real = w_real * f1_real - w_imag * f1_imag; const ATOMIC z1_imag = w_real * f1_imag + w_imag * f1_real; /* compute x = W(2) z */ /* x0 = z0 + z1 */ const ATOMIC x0_real = z0_real + z1_real; const ATOMIC x0_imag = z0_imag + z1_imag; /* x1 = z0 - z1 */ const ATOMIC x1_real = z0_real - z1_real; const ATOMIC x1_imag = z0_imag - z1_imag; const size_t to0 = k1 * product + 2 * k - 1; const size_t to1 = k1 * product + product - 2 * k - 1; VECTOR(out,ostride,to0) = x0_real; VECTOR(out,ostride,to0 + 1) = x0_imag; /* stored in conjugate location */ VECTOR(out,ostride,to1) = x1_real; VECTOR(out,ostride,to1 + 1) = -x1_imag; } } if (product_1 % 2 == 1) return; for (k1 = 0; k1 < q; k1++) { const size_t from0 = k1 * product_1 + product_1 - 1; const size_t from1 = from0 + m; const size_t to0 = k1 * product + product_1 - 1; VECTOR(out,ostride,to0) = VECTOR(in,istride,from0); VECTOR(out,ostride,to0 + 1) = -VECTOR(in,istride,from1); } return; } praat-6.0.04/external/gsl/gsl_fft__real_pass_3.c000066400000000000000000000133231261542461700215330ustar00rootroot00000000000000/* fft/real_pass_3.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static void FUNCTION(fft_real,pass_3) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle1[], const TYPE(gsl_complex) twiddle2[]) { size_t k, k1; const size_t factor = 3; const size_t m = n / factor; const size_t q = n / product; const size_t product_1 = product / factor; const ATOMIC tau = sqrt (3.0) / 2.0; for (k1 = 0; k1 < q; k1++) { const size_t from0 = k1 * product_1; const size_t from1 = from0 + m; const size_t from2 = from1 + m; const ATOMIC z0_real = VECTOR(in,istride,from0); const ATOMIC z1_real = VECTOR(in,istride,from1); const ATOMIC z2_real = VECTOR(in,istride,from2); const ATOMIC t1 = z1_real + z2_real; const ATOMIC x0_real = z0_real + t1; const ATOMIC x1_real = z0_real - t1 / 2.0; const ATOMIC x1_imag = -tau * (z1_real - z2_real); const size_t to0 = product * k1; const size_t to1 = to0 + 2 * product_1 - 1; VECTOR(out,ostride,to0) = x0_real; VECTOR(out,ostride,to1) = x1_real; VECTOR(out,ostride,to1 + 1) = x1_imag; } if (product_1 == 1) return; for (k = 1; k < (product_1 + 1) / 2; k++) { const ATOMIC w1_real = GSL_REAL(twiddle1[k - 1]); const ATOMIC w1_imag = -GSL_IMAG(twiddle1[k - 1]); const ATOMIC w2_real = GSL_REAL(twiddle2[k - 1]); const ATOMIC w2_imag = -GSL_IMAG(twiddle2[k - 1]); for (k1 = 0; k1 < q; k1++) { const size_t from0 = k1 * product_1 + 2 * k - 1; const size_t from1 = from0 + m; const size_t from2 = from1 + m; const ATOMIC f0_real = VECTOR(in,istride,from0); const ATOMIC f0_imag = VECTOR(in,istride,from0 + 1); const ATOMIC f1_real = VECTOR(in,istride,from1); const ATOMIC f1_imag = VECTOR(in,istride,from1 + 1); const ATOMIC f2_real = VECTOR(in,istride,from2); const ATOMIC f2_imag = VECTOR(in,istride,from2 + 1); const ATOMIC z0_real = f0_real; const ATOMIC z0_imag = f0_imag; const ATOMIC z1_real = w1_real * f1_real - w1_imag * f1_imag; const ATOMIC z1_imag = w1_real * f1_imag + w1_imag * f1_real; const ATOMIC z2_real = w2_real * f2_real - w2_imag * f2_imag; const ATOMIC z2_imag = w2_real * f2_imag + w2_imag * f2_real; /* compute x = W(3) z */ /* t1 = z1 + z2 */ const ATOMIC t1_real = z1_real + z2_real; const ATOMIC t1_imag = z1_imag + z2_imag; /* t2 = z0 - t1/2 */ const ATOMIC t2_real = z0_real - t1_real / 2; const ATOMIC t2_imag = z0_imag - t1_imag / 2; /* t3 = (+/-) sin(pi/3)*(z1 - z2) */ const ATOMIC t3_real = -tau * (z1_real - z2_real); const ATOMIC t3_imag = -tau * (z1_imag - z2_imag); /* x0 = z0 + t1 */ const ATOMIC x0_real = z0_real + t1_real; const ATOMIC x0_imag = z0_imag + t1_imag; /* x1 = t2 + i t3 */ const ATOMIC x1_real = t2_real - t3_imag; const ATOMIC x1_imag = t2_imag + t3_real; /* x2 = t2 - i t3 */ const ATOMIC x2_real = t2_real + t3_imag; const ATOMIC x2_imag = t2_imag - t3_real; /* apply twiddle factors */ const size_t to0 = k1 * product + 2 * k - 1; const size_t to1 = to0 + 2 * product_1; const size_t to2 = 2 * product_1 - 2 * k + k1 * product - 1; /* to0 = 1 * x0 */ VECTOR(out,ostride,to0) = x0_real; VECTOR(out,ostride,to0 + 1) = x0_imag; /* to1 = 1 * x1 */ VECTOR(out,ostride,to1) = x1_real; VECTOR(out,ostride,to1 + 1) = x1_imag; /* to2 = 1 * x2 */ VECTOR(out,ostride,to2) = x2_real; VECTOR(out,ostride,to2 + 1) = -x2_imag; } } if (product_1 % 2 == 1) return; for (k1 = 0; k1 < q; k1++) { const size_t from0 = k1 * product_1 + product_1 - 1; const size_t from1 = from0 + m; const size_t from2 = from1 + m; const ATOMIC z0_real = VECTOR(in,istride,from0); const ATOMIC z1_real = VECTOR(in,istride,from1); const ATOMIC z2_real = VECTOR(in,istride,from2); const ATOMIC t1 = z1_real - z2_real; const ATOMIC x0_real = z0_real + t1 / 2.0; const ATOMIC x0_imag = -tau * (z1_real + z2_real); const ATOMIC x1_real = z0_real - t1; const size_t to0 = k1 * product + product_1 - 1; const size_t to1 = to0 + 2 * product_1; VECTOR(out,ostride,to0) = x0_real; VECTOR(out,ostride,to0 + 1) = x0_imag; VECTOR(out,ostride,to1) = x1_real; } return; } praat-6.0.04/external/gsl/gsl_fft__real_pass_4.c000066400000000000000000000160451261542461700215400ustar00rootroot00000000000000/* fft/real_pass_4.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static void FUNCTION(fft_real,pass_4) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle1[], const TYPE(gsl_complex) twiddle2[], const TYPE(gsl_complex) twiddle3[]) { size_t k, k1; const size_t factor = 4; const size_t m = n / factor; const size_t q = n / product; const size_t product_1 = product / factor; for (k1 = 0; k1 < q; k1++) { const size_t from0 = k1 * product_1; const size_t from1 = from0 + m; const size_t from2 = from1 + m; const size_t from3 = from2 + m; const ATOMIC z0_real = VECTOR(in,istride,from0); const ATOMIC z1_real = VECTOR(in,istride,from1); const ATOMIC z2_real = VECTOR(in,istride,from2); const ATOMIC z3_real = VECTOR(in,istride,from3); /* compute x = W(4) z */ /* t1 = z0 + z2 */ const ATOMIC t1_real = z0_real + z2_real; /* t2 = z1 + z3 */ const ATOMIC t2_real = z1_real + z3_real; /* t3 = z0 - z2 */ const ATOMIC t3_real = z0_real - z2_real; /* t4 = - (z1 - z3) */ const ATOMIC t4_real = -(z1_real - z3_real); /* x0 = t1 + t2 */ const ATOMIC x0_real = t1_real + t2_real; /* x1 = t3 + i t4 */ const ATOMIC x1_real = t3_real; const ATOMIC x1_imag = t4_real; /* x2 = t1 - t2 */ const ATOMIC x2_real = t1_real - t2_real; const size_t to0 = product * k1; const size_t to1 = to0 + 2 * product_1 - 1; const size_t to2 = to1 + 2 * product_1; VECTOR(out,ostride,to0) = x0_real; VECTOR(out,ostride,to1) = x1_real; VECTOR(out,ostride,to1 + 1) = x1_imag; VECTOR(out,ostride,to2) = x2_real; } if (product_1 == 1) return; for (k = 1; k < (product_1 + 1) / 2; k++) { ATOMIC w1_real, w1_imag, w2_real, w2_imag, w3_real, w3_imag; w1_real = GSL_REAL(twiddle1[k - 1]); w1_imag = -GSL_IMAG(twiddle1[k - 1]); w2_real = GSL_REAL(twiddle2[k - 1]); w2_imag = -GSL_IMAG(twiddle2[k - 1]); w3_real = GSL_REAL(twiddle3[k - 1]); w3_imag = -GSL_IMAG(twiddle3[k - 1]); for (k1 = 0; k1 < q; k1++) { const size_t from0 = k1 * product_1 + 2 * k - 1; const size_t from1 = from0 + m; const size_t from2 = from1 + m; const size_t from3 = from2 + m; const ATOMIC f0_real = VECTOR(in,istride,from0); const ATOMIC f0_imag = VECTOR(in,istride,from0 + 1); const ATOMIC f1_real = VECTOR(in,istride,from1); const ATOMIC f1_imag = VECTOR(in,istride,from1 + 1); const ATOMIC f2_real = VECTOR(in,istride,from2); const ATOMIC f2_imag = VECTOR(in,istride,from2 + 1); const ATOMIC f3_real = VECTOR(in,istride,from3); const ATOMIC f3_imag = VECTOR(in,istride,from3 + 1); const ATOMIC z0_real = f0_real; const ATOMIC z0_imag = f0_imag; const ATOMIC z1_real = w1_real * f1_real - w1_imag * f1_imag; const ATOMIC z1_imag = w1_real * f1_imag + w1_imag * f1_real; const ATOMIC z2_real = w2_real * f2_real - w2_imag * f2_imag; const ATOMIC z2_imag = w2_real * f2_imag + w2_imag * f2_real; const ATOMIC z3_real = w3_real * f3_real - w3_imag * f3_imag; const ATOMIC z3_imag = w3_real * f3_imag + w3_imag * f3_real; /* compute x = W(4) z */ /* t1 = z0 + z2 */ const ATOMIC t1_real = z0_real + z2_real; const ATOMIC t1_imag = z0_imag + z2_imag; /* t2 = z1 + z3 */ const ATOMIC t2_real = z1_real + z3_real; const ATOMIC t2_imag = z1_imag + z3_imag; /* t3 = z0 - z2 */ const ATOMIC t3_real = z0_real - z2_real; const ATOMIC t3_imag = z0_imag - z2_imag; /* t4 = - (z1 - z3) */ const ATOMIC t4_real = -(z1_real - z3_real); const ATOMIC t4_imag = -(z1_imag - z3_imag); /* x0 = t1 + t2 */ const ATOMIC x0_real = t1_real + t2_real; const ATOMIC x0_imag = t1_imag + t2_imag; /* x1 = t3 + i t4 */ const ATOMIC x1_real = t3_real - t4_imag; const ATOMIC x1_imag = t3_imag + t4_real; /* x2 = t1 - t2 */ const ATOMIC x2_real = t1_real - t2_real; const ATOMIC x2_imag = t1_imag - t2_imag; /* x3 = t3 - i t4 */ const ATOMIC x3_real = t3_real + t4_imag; const ATOMIC x3_imag = t3_imag - t4_real; const size_t to0 = k1 * product + 2 * k - 1; const size_t to1 = to0 + 2 * product_1; const size_t to2 = 2 * product_1 - 2 * k + k1 * product - 1; const size_t to3 = to2 + 2 * product_1; VECTOR(out,ostride,to0) = x0_real; VECTOR(out,ostride,to0 + 1) = x0_imag; VECTOR(out,ostride,to1) = x1_real; VECTOR(out,ostride,to1 + 1) = x1_imag; VECTOR(out,ostride,to3) = x2_real; VECTOR(out,ostride,to3 + 1) = -x2_imag; VECTOR(out,ostride,to2) = x3_real; VECTOR(out,ostride,to2 + 1) = -x3_imag; } } if (product_1 % 2 == 1) return; for (k1 = 0; k1 < q; k1++) { const size_t from0 = k1 * product_1 + product_1 - 1; const size_t from1 = from0 + m; const size_t from2 = from1 + m; const size_t from3 = from2 + m; const ATOMIC x0 = VECTOR(in,istride,from0); const ATOMIC x1 = VECTOR(in,istride,from1); const ATOMIC x2 = VECTOR(in,istride,from2); const ATOMIC x3 = VECTOR(in,istride,from3); const ATOMIC t1 = (1.0 / sqrt (2.0)) * (x1 - x3); const ATOMIC t2 = (1.0 / sqrt (2.0)) * (x1 + x3); const size_t to0 = k1 * product + 2 * k - 1; const size_t to1 = to0 + 2 * product_1; VECTOR(out,ostride,to0) = x0 + t1; VECTOR(out,ostride,to0 + 1) = -x2 - t2; VECTOR(out,ostride,to1) = x0 - t1; VECTOR(out,ostride,to1 + 1) = x2 - t2; } return; } praat-6.0.04/external/gsl/gsl_fft__real_pass_5.c000066400000000000000000000243721261542461700215430ustar00rootroot00000000000000/* fft/real_pass_5.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static void FUNCTION(fft_real,pass_5) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle1[], const TYPE(gsl_complex) twiddle2[], const TYPE(gsl_complex) twiddle3[], const TYPE(gsl_complex) twiddle4[]) { size_t k, k1; const size_t factor = 5; const size_t m = n / factor; const size_t q = n / product; const size_t product_1 = product / factor; const ATOMIC sina = sin (2.0 * M_PI / 5.0); const ATOMIC sinb = sin (2.0 * M_PI / 10.0); for (k1 = 0; k1 < q; k1++) { const size_t from0 = k1 * product_1; const size_t from1 = from0 + m; const size_t from2 = from1 + m; const size_t from3 = from2 + m; const size_t from4 = from3 + m; const ATOMIC z0_real = VECTOR(in,istride,from0); const ATOMIC z1_real = VECTOR(in,istride,from1); const ATOMIC z2_real = VECTOR(in,istride,from2); const ATOMIC z3_real = VECTOR(in,istride,from3); const ATOMIC z4_real = VECTOR(in,istride,from4); /* t1 = z1 + z4 */ const ATOMIC t1_real = z1_real + z4_real; /* t2 = z2 + z3 */ const ATOMIC t2_real = z2_real + z3_real; /* t3 = z1 - z4 */ const ATOMIC t3_real = z1_real - z4_real; /* t4 = z2 - z3 */ const ATOMIC t4_real = z2_real - z3_real; /* t5 = t1 + t2 */ const ATOMIC t5_real = t1_real + t2_real; /* t6 = (sqrt(5)/4)(t1 - t2) */ const ATOMIC t6_real = (sqrt (5.0) / 4.0) * (t1_real - t2_real); /* t7 = z0 - ((t5)/4) */ const ATOMIC t7_real = z0_real - t5_real / 4.0; /* t8 = t7 + t6 */ const ATOMIC t8_real = t7_real + t6_real; /* t9 = t7 - t6 */ const ATOMIC t9_real = t7_real - t6_real; /* t10 = -(sin(2 pi/5) t3 + sin(2 pi/10) t4 ) */ const ATOMIC t10_real = -sina * t3_real - sinb * t4_real; /* t11 = -(sin(2 pi/10) t3 - sin(2 pi/5) t4) */ const ATOMIC t11_real = -sinb * t3_real + sina * t4_real; /* x0 = z0 + t5 */ const ATOMIC x0_real = z0_real + t5_real; /* x1 = t8 + i t10 */ const ATOMIC x1_real = t8_real; const ATOMIC x1_imag = t10_real; /* x2 = t9 + i t11 */ const ATOMIC x2_real = t9_real; const ATOMIC x2_imag = t11_real; const size_t to0 = product * k1; const size_t to1 = to0 + 2 * product_1 - 1; const size_t to2 = to1 + 2 * product_1; VECTOR(out,ostride,to0) = x0_real; VECTOR(out,ostride,to1) = x1_real; VECTOR(out,ostride,to1 + 1) = x1_imag; VECTOR(out,ostride,to2) = x2_real; VECTOR(out,ostride,to2 + 1) = x2_imag; } if (product_1 == 1) return; for (k = 1; k < (product_1 + 1) / 2; k++) { const ATOMIC w1_real = GSL_REAL(twiddle1[k - 1]); const ATOMIC w1_imag = -GSL_IMAG(twiddle1[k - 1]); const ATOMIC w2_real = GSL_REAL(twiddle2[k - 1]); const ATOMIC w2_imag = -GSL_IMAG(twiddle2[k - 1]); const ATOMIC w3_real = GSL_REAL(twiddle3[k - 1]); const ATOMIC w3_imag = -GSL_IMAG(twiddle3[k - 1]); const ATOMIC w4_real = GSL_REAL(twiddle4[k - 1]); const ATOMIC w4_imag = -GSL_IMAG(twiddle4[k - 1]); for (k1 = 0; k1 < q; k1++) { const size_t from0 = k1 * product_1 + 2 * k - 1; const size_t from1 = from0 + m; const size_t from2 = from1 + m; const size_t from3 = from2 + m; const size_t from4 = from3 + m; const ATOMIC f0_real = VECTOR(in,istride,from0); const ATOMIC f0_imag = VECTOR(in,istride,from0 + 1); const ATOMIC f1_real = VECTOR(in,istride,from1); const ATOMIC f1_imag = VECTOR(in,istride,from1 + 1); const ATOMIC f2_real = VECTOR(in,istride,from2); const ATOMIC f2_imag = VECTOR(in,istride,from2 + 1); const ATOMIC f3_real = VECTOR(in,istride,from3); const ATOMIC f3_imag = VECTOR(in,istride,from3 + 1); const ATOMIC f4_real = VECTOR(in,istride,from4); const ATOMIC f4_imag = VECTOR(in,istride,from4 + 1); const ATOMIC z0_real = f0_real; const ATOMIC z0_imag = f0_imag; const ATOMIC z1_real = w1_real * f1_real - w1_imag * f1_imag; const ATOMIC z1_imag = w1_real * f1_imag + w1_imag * f1_real; const ATOMIC z2_real = w2_real * f2_real - w2_imag * f2_imag; const ATOMIC z2_imag = w2_real * f2_imag + w2_imag * f2_real; const ATOMIC z3_real = w3_real * f3_real - w3_imag * f3_imag; const ATOMIC z3_imag = w3_real * f3_imag + w3_imag * f3_real; const ATOMIC z4_real = w4_real * f4_real - w4_imag * f4_imag; const ATOMIC z4_imag = w4_real * f4_imag + w4_imag * f4_real; /* compute x = W(5) z */ /* t1 = z1 + z4 */ const ATOMIC t1_real = z1_real + z4_real; const ATOMIC t1_imag = z1_imag + z4_imag; /* t2 = z2 + z3 */ const ATOMIC t2_real = z2_real + z3_real; const ATOMIC t2_imag = z2_imag + z3_imag; /* t3 = z1 - z4 */ const ATOMIC t3_real = z1_real - z4_real; const ATOMIC t3_imag = z1_imag - z4_imag; /* t4 = z2 - z3 */ const ATOMIC t4_real = z2_real - z3_real; const ATOMIC t4_imag = z2_imag - z3_imag; /* t5 = t1 + t2 */ const ATOMIC t5_real = t1_real + t2_real; const ATOMIC t5_imag = t1_imag + t2_imag; /* t6 = (sqrt(5)/4)(t1 - t2) */ const ATOMIC t6_real = (sqrt (5.0) / 4.0) * (t1_real - t2_real); const ATOMIC t6_imag = (sqrt (5.0) / 4.0) * (t1_imag - t2_imag); /* t7 = z0 - ((t5)/4) */ const ATOMIC t7_real = z0_real - t5_real / 4.0; const ATOMIC t7_imag = z0_imag - t5_imag / 4.0; /* t8 = t7 + t6 */ const ATOMIC t8_real = t7_real + t6_real; const ATOMIC t8_imag = t7_imag + t6_imag; /* t9 = t7 - t6 */ const ATOMIC t9_real = t7_real - t6_real; const ATOMIC t9_imag = t7_imag - t6_imag; /* t10 = - (sin(2 pi/5) t3 + sin(2 pi/10) t4) */ const ATOMIC t10_real = -sina * t3_real - sinb * t4_real; const ATOMIC t10_imag = -sina * t3_imag - sinb * t4_imag; /* t11 = -(sin(2 pi/10) t3 - sin(2 pi/5) t4) */ const ATOMIC t11_real = -sinb * t3_real + sina * t4_real; const ATOMIC t11_imag = -sinb * t3_imag + sina * t4_imag; /* x0 = z0 + t5 */ const ATOMIC x0_real = z0_real + t5_real; const ATOMIC x0_imag = z0_imag + t5_imag; /* x1 = t8 + i t10 */ const ATOMIC x1_real = t8_real - t10_imag; const ATOMIC x1_imag = t8_imag + t10_real; /* x2 = t9 + i t11 */ const ATOMIC x2_real = t9_real - t11_imag; const ATOMIC x2_imag = t9_imag + t11_real; /* x3 = t9 - i t11 */ const ATOMIC x3_real = t9_real + t11_imag; const ATOMIC x3_imag = t9_imag - t11_real; /* x4 = t8 - i t10 */ const ATOMIC x4_real = t8_real + t10_imag; const ATOMIC x4_imag = t8_imag - t10_real; const size_t to0 = k1 * product + 2 * k - 1; const size_t to1 = to0 + 2 * product_1; const size_t to2 = to1 + 2 * product_1; const size_t to3 = 2 * product_1 - 2 * k + k1 * product - 1; const size_t to4 = to3 + 2 * product_1; VECTOR(out,ostride,to0) = x0_real; VECTOR(out,ostride,to0 + 1) = x0_imag; VECTOR(out,ostride,to1) = x1_real; VECTOR(out,ostride,to1 + 1) = x1_imag; VECTOR(out,ostride,to2) = x2_real; VECTOR(out,ostride,to2 + 1) = x2_imag; VECTOR(out,ostride,to3) = x4_real; VECTOR(out,ostride,to3 + 1) = -x4_imag; VECTOR(out,ostride,to4) = x3_real; VECTOR(out,ostride,to4 + 1) = -x3_imag; } } if (product_1 % 2 == 1) return; for (k1 = 0; k1 < q; k1++) { const size_t from0 = k1 * product_1 + product_1 - 1; const size_t from1 = from0 + m; const size_t from2 = from1 + m; const size_t from3 = from2 + m; const size_t from4 = from3 + m; const ATOMIC z0_real = VECTOR(in,istride,from0); const ATOMIC z1_real = VECTOR(in,istride,from1); const ATOMIC z2_real = VECTOR(in,istride,from2); const ATOMIC z3_real = VECTOR(in,istride,from3); const ATOMIC z4_real = VECTOR(in,istride,from4); const ATOMIC t1 = z1_real - z4_real; const ATOMIC t2 = z1_real + z4_real; const ATOMIC t3 = z2_real - z3_real; const ATOMIC t4 = z2_real + z3_real; const ATOMIC t5 = t1 - t3; const ATOMIC t6 = z0_real + t5 / 4.0; const ATOMIC t7 = (sqrt (5.0) / 4.0) * (t1 + t3); const size_t to0 = k1 * product + product_1 - 1; const size_t to1 = to0 + 2 * product_1; const size_t to2 = to1 + 2 * product_1; VECTOR(out,ostride,to0) = t6 + t7; VECTOR(out,ostride,to0 + 1) = -sinb * t2 - sina * t4; VECTOR(out,ostride,to1) = t6 - t7; VECTOR(out,ostride,to1 + 1) = -sina * t2 + sinb * t4; VECTOR(out,ostride,to2) = z0_real - t5; } return; } praat-6.0.04/external/gsl/gsl_fft__real_pass_n.c000066400000000000000000000205221261542461700216250ustar00rootroot00000000000000/* fft/real_pass_n.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static void FUNCTION(fft_real,pass_n) (const BASE in[], const size_t istride, BASE out[], const size_t ostride, const size_t factor, const size_t product, const size_t n, const TYPE(gsl_complex) twiddle[]) { size_t k, k1; const size_t m = n / factor; const size_t q = n / product; const size_t product_1 = product / factor; size_t e1, e2; const double d_theta = 2.0 * M_PI / ((double) factor); const ATOMIC cos_d_theta = cos (d_theta); const ATOMIC sin_d_theta = sin (d_theta); for (k1 = 0; k1 < q; k1++) { /* compute x = W(factor) z, for z real */ ATOMIC dw_real = 1.0, dw_imag = 0.0; for (e1 = 0; e1 <= factor - e1; e1++) { ATOMIC sum_real = 0.0; ATOMIC sum_imag = 0.0; ATOMIC w_real = 1.0, w_imag = 0.0; if (e1 > 0) { ATOMIC tmp_real = dw_real * cos_d_theta + dw_imag * sin_d_theta; ATOMIC tmp_imag = -dw_real * sin_d_theta + dw_imag * cos_d_theta; dw_real = tmp_real; dw_imag = tmp_imag; } for (e2 = 0; e2 < factor; e2++) { ATOMIC z_real = VECTOR(in,istride,k1 * product_1 + e2 * m); if (e2 > 0) { ATOMIC tmp_real = dw_real * w_real - dw_imag * w_imag; ATOMIC tmp_imag = dw_real * w_imag + dw_imag * w_real; w_real = tmp_real; w_imag = tmp_imag; } sum_real += w_real * z_real; sum_imag += w_imag * z_real; } if (e1 == 0) { const size_t to0 = product * k1; VECTOR(out,ostride,to0) = sum_real; } else if (e1 < factor - e1) { const size_t to0 = k1 * product + 2 * e1 * product_1 - 1; VECTOR(out,ostride,to0) = sum_real; VECTOR(out,ostride,to0 + 1) = sum_imag; } else if (e1 == factor - e1) { const size_t to0 = k1 * product + 2 * e1 * product_1 - 1; VECTOR(out,ostride,to0) = sum_real; } } } if (product_1 == 1) return; for (k = 1; k < (product_1 + 1) / 2; k++) { for (k1 = 0; k1 < q; k1++) { ATOMIC dw_real = 1.0, dw_imag = 0.0; for (e1 = 0; e1 < factor; e1++) { ATOMIC sum_real = 0.0, sum_imag = 0.0; ATOMIC w_real = 1.0, w_imag = 0.0; if (e1 > 0) { const ATOMIC tmp_real = dw_real * cos_d_theta + dw_imag * sin_d_theta; const ATOMIC tmp_imag = -dw_real * sin_d_theta + dw_imag * cos_d_theta; dw_real = tmp_real; dw_imag = tmp_imag; } for (e2 = 0; e2 < factor; e2++) { int tskip = (product_1 + 1) / 2 - 1; const size_t from0 = k1 * product_1 + 2 * k + e2 * m - 1; ATOMIC tw_real, tw_imag; ATOMIC z_real, z_imag; if (e2 == 0) { tw_real = 1.0; tw_imag = 0.0; } else { const size_t t_index = (k - 1) + (e2 - 1) * tskip; tw_real = GSL_REAL(twiddle[t_index]); tw_imag = -GSL_IMAG(twiddle[t_index]); } { const ATOMIC f0_real = VECTOR(in,istride,from0); const ATOMIC f0_imag = VECTOR(in,istride,from0 + 1); z_real = tw_real * f0_real - tw_imag * f0_imag; z_imag = tw_real * f0_imag + tw_imag * f0_real; } if (e2 > 0) { const ATOMIC tmp_real = dw_real * w_real - dw_imag * w_imag; const ATOMIC tmp_imag = dw_real * w_imag + dw_imag * w_real; w_real = tmp_real; w_imag = tmp_imag; } sum_real += w_real * z_real - w_imag * z_imag; sum_imag += w_real * z_imag + w_imag * z_real; } if (e1 < factor - e1) { const size_t to0 = k1 * product - 1 + 2 * e1 * product_1 + 2 * k; VECTOR(out,ostride,to0) = sum_real; VECTOR(out,ostride,to0 + 1) = sum_imag; } else { const size_t to0 = k1 * product - 1 + 2 * (factor - e1) * product_1 - 2 * k; VECTOR(out,ostride,to0) = sum_real; VECTOR(out,ostride,to0 + 1) = -sum_imag; } } } } if (product_1 % 2 == 1) return; { double tw_arg = M_PI / ((double) factor); ATOMIC cos_tw_arg = cos (tw_arg); ATOMIC sin_tw_arg = -sin (tw_arg); for (k1 = 0; k1 < q; k1++) { ATOMIC dw_real = 1.0, dw_imag = 0.0; for (e1 = 0; e1 < factor; e1++) { ATOMIC z_real, z_imag; ATOMIC sum_real = 0.0; ATOMIC sum_imag = 0.0; ATOMIC w_real = 1.0, w_imag = 0.0; ATOMIC tw_real = 1.0, tw_imag = 0.0; if (e1 > 0) { ATOMIC t_real = dw_real * cos_d_theta + dw_imag * sin_d_theta; ATOMIC t_imag = -dw_real * sin_d_theta + dw_imag * cos_d_theta; dw_real = t_real; dw_imag = t_imag; } for (e2 = 0; e2 < factor; e2++) { if (e2 > 0) { ATOMIC tmp_real = tw_real * cos_tw_arg - tw_imag * sin_tw_arg; ATOMIC tmp_imag = tw_real * sin_tw_arg + tw_imag * cos_tw_arg; tw_real = tmp_real; tw_imag = tmp_imag; } if (e2 > 0) { ATOMIC tmp_real = dw_real * w_real - dw_imag * w_imag; ATOMIC tmp_imag = dw_real * w_imag + dw_imag * w_real; w_real = tmp_real; w_imag = tmp_imag; } { const size_t from0 = k1 * product_1 + 2 * k + e2 * m - 1; const ATOMIC f0_real = VECTOR(in,istride,from0); z_real = tw_real * f0_real; z_imag = tw_imag * f0_real; } sum_real += w_real * z_real - w_imag * z_imag; sum_imag += w_real * z_imag + w_imag * z_real; } if (e1 + 1 < factor - e1) { const size_t to0 = k1 * product - 1 + 2 * e1 * product_1 + 2 * k; VECTOR(out,ostride,to0) = sum_real; VECTOR(out,ostride,to0 + 1) = sum_imag; } else if (e1 + 1 == factor - e1) { const size_t to0 = k1 * product - 1 + 2 * e1 * product_1 + 2 * k; VECTOR(out,ostride,to0) = sum_real; } else { const size_t to0 = k1 * product - 1 + 2 * (factor - e1) * product_1 - 2 * k; VECTOR(out,ostride,to0) = sum_real; VECTOR(out,ostride,to0 + 1) = -sum_imag; } } } } return; } praat-6.0.04/external/gsl/gsl_fft__real_radix2.c000066400000000000000000000075371261542461700215460ustar00rootroot00000000000000/* fft/real_radix2.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ int FUNCTION(gsl_fft_real,radix2_transform) (BASE data[], const size_t stride, const size_t n) { int result ; size_t p, p_1, q; size_t i; size_t logn = 0; int status; if (n == 1) /* identity operation */ { return 0 ; } /* make sure that n is a power of 2 */ result = fft_binary_logn(n) ; if (result == -1) { GSL_ERROR ("n is not a power of 2", GSL_EINVAL); } else { logn = result ; } /* bit reverse the ordering of input data for decimation in time algorithm */ status = FUNCTION(fft_real,bitreverse_order)(data, stride, n, logn) ; /* apply fft recursion */ p = 1; q = n ; for (i = 1; i <= logn; i++) { size_t a, b; p_1 = p ; p = 2 * p ; q = q / 2 ; /* a = 0 */ for (b = 0; b < q; b++) { ATOMIC t0_real = VECTOR(data,stride,b*p) + VECTOR(data,stride,b*p + p_1) ; ATOMIC t1_real = VECTOR(data,stride,b*p) - VECTOR(data,stride,b*p + p_1) ; VECTOR(data,stride,b*p) = t0_real ; VECTOR(data,stride,b*p + p_1) = t1_real ; } /* a = 1 ... p_{i-1}/2 - 1 */ { ATOMIC w_real = 1.0; ATOMIC w_imag = 0.0; const double theta = - 2.0 * M_PI / p; const ATOMIC s = sin (theta); const ATOMIC t = sin (theta / 2.0); const ATOMIC s2 = 2.0 * t * t; for (a = 1; a < (p_1)/2; a++) { /* trignometric recurrence for w-> exp(i theta) w */ { const ATOMIC tmp_real = w_real - s * w_imag - s2 * w_real; const ATOMIC tmp_imag = w_imag + s * w_real - s2 * w_imag; w_real = tmp_real; w_imag = tmp_imag; } for (b = 0; b < q; b++) { ATOMIC z0_real = VECTOR(data,stride,b*p + a) ; ATOMIC z0_imag = VECTOR(data,stride,b*p + p_1 - a) ; ATOMIC z1_real = VECTOR(data,stride,b*p + p_1 + a) ; ATOMIC z1_imag = VECTOR(data,stride,b*p + p - a) ; /* t0 = z0 + w * z1 */ ATOMIC t0_real = z0_real + w_real * z1_real - w_imag * z1_imag; ATOMIC t0_imag = z0_imag + w_real * z1_imag + w_imag * z1_real; /* t1 = z0 - w * z1 */ ATOMIC t1_real = z0_real - w_real * z1_real + w_imag * z1_imag; ATOMIC t1_imag = z0_imag - w_real * z1_imag - w_imag * z1_real; VECTOR(data,stride,b*p + a) = t0_real ; VECTOR(data,stride,b*p + p - a) = t0_imag ; VECTOR(data,stride,b*p + p_1 - a) = t1_real ; VECTOR(data,stride,b*p + p_1 + a) = -t1_imag ; } } } if (p_1 > 1) { for (b = 0; b < q; b++) { /* a = p_{i-1}/2 */ VECTOR(data,stride,b*p + p - p_1/2) *= -1 ; } } } return 0; } praat-6.0.04/external/gsl/gsl_fft__real_unpack.c000066400000000000000000000024651261542461700216310ustar00rootroot00000000000000/* fft/real_unpack.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl_fft__complex_internal.h" int FUNCTION(gsl_fft_real,unpack) (const BASE real_coefficient[], BASE complex_coefficient[], const size_t stride, const size_t n) { size_t i; if (n == 0) { GSL_ERROR ("length n must be positive integer", GSL_EDOM); } for (i = 0; i < n; i++) { REAL(complex_coefficient,stride,i) = real_coefficient[i * stride]; IMAG(complex_coefficient,stride,i) = 0.0; } return 0; } praat-6.0.04/external/gsl/gsl_fft__signals.c000066400000000000000000000010201261542461700207670ustar00rootroot00000000000000#include "gsl__config.h" #include #include #include "gsl_math.h" #include "gsl_complex.h" #include "gsl_errno.h" #include "gsl_dft_complex.h" #include "gsl_dft_complex_float.h" #include "gsl_fft__complex_internal.h" #include "gsl_fft__urand.c" #define BASE_DOUBLE #include "templates_on.h" #include "gsl_fft__signals_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_fft__signals_source.c" #include "templates_off.h" #undef BASE_FLOAT praat-6.0.04/external/gsl/gsl_fft__signals.h000066400000000000000000000056501261542461700210110ustar00rootroot00000000000000/* fft/signals.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ int FUNCTION(fft_signal,complex_pulse) (const size_t k, const size_t n, const size_t stride, const BASE z_real, const BASE z_imag, BASE data[], BASE fft[]); int FUNCTION(fft_signal,complex_constant) (const size_t n, const size_t stride, const BASE z_real, const BASE z_imag, BASE data[], BASE fft[]); int FUNCTION(fft_signal,complex_exp) (const int k, const size_t n, const size_t stride, const BASE z_real, const BASE z_imag, BASE data[], BASE fft[]); int FUNCTION(fft_signal,complex_exppair) (const int k1, const int k2, const size_t n, const size_t stride, const BASE z1_real, const BASE z1_imag, const BASE z2_real, const BASE z2_imag, BASE data[], BASE fft[]); int FUNCTION(fft_signal,complex_noise) (const size_t n, const size_t stride, BASE data[], BASE fft[]); int FUNCTION(fft_signal,real_noise) (const size_t n, const size_t stride, BASE data[], BASE fft[]); praat-6.0.04/external/gsl/gsl_fft__signals_source.c000066400000000000000000000161501261542461700223610ustar00rootroot00000000000000/* fft/signals_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl_fft__signals.h" int FUNCTION(fft_signal,complex_pulse) (const size_t k, const size_t n, const size_t stride, const BASE z_real, const BASE z_imag, BASE data[], BASE fft[]) { size_t j; if (n == 0) { GSL_ERROR ("length n must be positive integer", GSL_EDOM); } /* gsl_complex pulse at position k, data[j] = z * delta_{jk} */ for (j = 0; j < n; j++) { REAL(data,stride,j) = 0.0; IMAG(data,stride,j) = 0.0; } REAL(data,stride,k % n) = z_real; IMAG(data,stride,k % n) = z_imag; /* fourier transform, fft[j] = z * exp(-2 pi i j k / n) */ for (j = 0; j < n; j++) { const double arg = -2 * M_PI * ((double) ((j * k) % n)) / ((double) n); const BASE w_real = (BASE)cos (arg); const BASE w_imag = (BASE)sin (arg); REAL(fft,stride,j) = w_real * z_real - w_imag * z_imag; IMAG(fft,stride,j) = w_real * z_imag + w_imag * z_real; } return 0; } int FUNCTION(fft_signal,complex_constant) (const size_t n, const size_t stride, const BASE z_real, const BASE z_imag, BASE data[], BASE fft[]) { size_t j; if (n == 0) { GSL_ERROR ("length n must be positive integer", GSL_EDOM); } /* constant, data[j] = z */ for (j = 0; j < n; j++) { REAL(data,stride,j) = z_real; IMAG(data,stride,j) = z_imag; } /* fourier transform, fft[j] = n z delta_{j0} */ for (j = 0; j < n; j++) { REAL(fft,stride,j) = 0.0; IMAG(fft,stride,j) = 0.0; } REAL(fft,stride,0) = ((BASE) n) * z_real; IMAG(fft,stride,0) = ((BASE) n) * z_imag; return 0; } int FUNCTION(fft_signal,complex_exp) (const int k, const size_t n, const size_t stride, const BASE z_real, const BASE z_imag, BASE data[], BASE fft[]) { size_t j; if (n == 0) { GSL_ERROR ("length n must be positive integer", GSL_EDOM); } /* exponential, data[j] = z * exp(2 pi i j k) */ for (j = 0; j < n; j++) { const double arg = 2 * M_PI * ((double) ((j * k) % n)) / ((double) n); const BASE w_real = (BASE)cos (arg); const BASE w_imag = (BASE)sin (arg); REAL(data,stride,j) = w_real * z_real - w_imag * z_imag; IMAG(data,stride,j) = w_real * z_imag + w_imag * z_real; } /* fourier transform, fft[j] = z * delta{(j - k),0} */ for (j = 0; j < n; j++) { REAL(fft,stride,j) = 0.0; IMAG(fft,stride,j) = 0.0; } { int freq; if (k <= 0) { freq = (n-k) % n ; } else { freq = (k % n); }; REAL(fft,stride,freq) = ((BASE) n) * z_real; IMAG(fft,stride,freq) = ((BASE) n) * z_imag; } return 0; } int FUNCTION(fft_signal,complex_exppair) (const int k1, const int k2, const size_t n, const size_t stride, const BASE z1_real, const BASE z1_imag, const BASE z2_real, const BASE z2_imag, BASE data[], BASE fft[]) { size_t j; if (n == 0) { GSL_ERROR ("length n must be positive integer", GSL_EDOM); } /* exponential, data[j] = z1 * exp(2 pi i j k1) + z2 * exp(2 pi i j k2) */ for (j = 0; j < n; j++) { const double arg1 = 2 * M_PI * ((double) ((j * k1) % n)) / ((double) n); const BASE w1_real = (BASE)cos (arg1); const BASE w1_imag = (BASE)sin (arg1); const double arg2 = 2 * M_PI * ((double) ((j * k2) % n)) / ((double) n); const BASE w2_real = (BASE)cos (arg2); const BASE w2_imag = (BASE)sin (arg2); REAL(data,stride,j) = w1_real * z1_real - w1_imag * z1_imag; IMAG(data,stride,j) = w1_real * z1_imag + w1_imag * z1_real; REAL(data,stride,j) += w2_real * z2_real - w2_imag * z2_imag; IMAG(data,stride,j) += w2_real * z2_imag + w2_imag * z2_real; } /* fourier transform, fft[j] = z1 * delta{(j - k1),0} + z2 * delta{(j - k2,0)} */ for (j = 0; j < n; j++) { REAL(fft,stride,j) = 0.0; IMAG(fft,stride,j) = 0.0; } { int freq1, freq2; if (k1 <= 0) { freq1 = (n - k1) % n; } else { freq1 = (k1 % n); }; if (k2 <= 0) { freq2 = (n - k2) % n; } else { freq2 = (k2 % n); }; REAL(fft,stride,freq1) += ((BASE) n) * z1_real; IMAG(fft,stride,freq1) += ((BASE) n) * z1_imag; REAL(fft,stride,freq2) += ((BASE) n) * z2_real; IMAG(fft,stride,freq2) += ((BASE) n) * z2_imag; } return 0; } int FUNCTION(fft_signal,complex_noise) (const size_t n, const size_t stride, BASE data[], BASE fft[]) { size_t i; int status; if (n == 0) { GSL_ERROR ("length n must be positive integer", GSL_EDOM); } for (i = 0; i < n; i++) { REAL(data,stride,i) = (BASE)urand(); IMAG(data,stride,i) = (BASE)urand(); } /* compute the dft */ status = FUNCTION(gsl_dft_complex,forward) (data, stride, n, fft); return status; } int FUNCTION(fft_signal,real_noise) (const size_t n, const size_t stride, BASE data[], BASE fft[]) { size_t i; int status; if (n == 0) { GSL_ERROR ("length n must be positive integer", GSL_EDOM); } for (i = 0; i < n; i++) { REAL(data,stride,i) = (BASE)urand(); IMAG(data,stride,i) = 0.0; } /* compute the dft */ status = FUNCTION(gsl_dft_complex,forward) (data, stride, n, fft); return status; } praat-6.0.04/external/gsl/gsl_fft__urand.c000066400000000000000000000017121261542461700204500ustar00rootroot00000000000000/* fft/urand.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ double urand (void); double urand (void) { static unsigned long int x = 1; x = (1103515245 * x + 12345) & 0x7fffffffUL ; return x / 2147483648.0 ; } praat-6.0.04/external/gsl/gsl_fft_complex.h000066400000000000000000000113221261542461700206520ustar00rootroot00000000000000/* fft/gsl_fft_complex.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_FFT_COMPLEX_H__ #define __GSL_FFT_COMPLEX_H__ #include #include "gsl_math.h" #include "gsl_complex.h" #include "gsl_fft.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Power of 2 routines */ int gsl_fft_complex_radix2_forward (gsl_complex_packed_array data, const size_t stride, const size_t n); int gsl_fft_complex_radix2_backward (gsl_complex_packed_array data, const size_t stride, const size_t n); int gsl_fft_complex_radix2_inverse (gsl_complex_packed_array data, const size_t stride, const size_t n); int gsl_fft_complex_radix2_transform (gsl_complex_packed_array data, const size_t stride, const size_t n, const gsl_fft_direction sign); int gsl_fft_complex_radix2_dif_forward (gsl_complex_packed_array data, const size_t stride, const size_t n); int gsl_fft_complex_radix2_dif_backward (gsl_complex_packed_array data, const size_t stride, const size_t n); int gsl_fft_complex_radix2_dif_inverse (gsl_complex_packed_array data, const size_t stride, const size_t n); int gsl_fft_complex_radix2_dif_transform (gsl_complex_packed_array data, const size_t stride, const size_t n, const gsl_fft_direction sign); /* Mixed Radix general-N routines */ typedef struct { size_t n; size_t nf; size_t factor[64]; gsl_complex *twiddle[64]; gsl_complex *trig; } gsl_fft_complex_wavetable; typedef struct { size_t n; double *scratch; } gsl_fft_complex_workspace; gsl_fft_complex_wavetable *gsl_fft_complex_wavetable_alloc (size_t n); void gsl_fft_complex_wavetable_free (gsl_fft_complex_wavetable * wavetable); gsl_fft_complex_workspace *gsl_fft_complex_workspace_alloc (size_t n); void gsl_fft_complex_workspace_free (gsl_fft_complex_workspace * workspace); int gsl_fft_complex_memcpy (gsl_fft_complex_wavetable * dest, gsl_fft_complex_wavetable * src); int gsl_fft_complex_forward (gsl_complex_packed_array data, const size_t stride, const size_t n, const gsl_fft_complex_wavetable * wavetable, gsl_fft_complex_workspace * work); int gsl_fft_complex_backward (gsl_complex_packed_array data, const size_t stride, const size_t n, const gsl_fft_complex_wavetable * wavetable, gsl_fft_complex_workspace * work); int gsl_fft_complex_inverse (gsl_complex_packed_array data, const size_t stride, const size_t n, const gsl_fft_complex_wavetable * wavetable, gsl_fft_complex_workspace * work); int gsl_fft_complex_transform (gsl_complex_packed_array data, const size_t stride, const size_t n, const gsl_fft_complex_wavetable * wavetable, gsl_fft_complex_workspace * work, const gsl_fft_direction sign); __END_DECLS #endif /* __GSL_FFT_COMPLEX_H__ */ praat-6.0.04/external/gsl/gsl_fft_complex_float.h000066400000000000000000000123311261542461700220400ustar00rootroot00000000000000/* fft/gsl_fft_complex_float.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_FFT_COMPLEX_FLOAT_H__ #define __GSL_FFT_COMPLEX_FLOAT_H__ #include #include "gsl_math.h" #include "gsl_complex.h" #include "gsl_fft.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Power of 2 routines */ int gsl_fft_complex_float_radix2_forward (gsl_complex_packed_array_float data, const size_t stride, const size_t n); int gsl_fft_complex_float_radix2_backward (gsl_complex_packed_array_float data, const size_t stride, const size_t n); int gsl_fft_complex_float_radix2_inverse (gsl_complex_packed_array_float data, const size_t stride, const size_t n); int gsl_fft_complex_float_radix2_transform (gsl_complex_packed_array_float data, const size_t stride, const size_t n, const gsl_fft_direction sign); int gsl_fft_complex_float_radix2_dif_forward (gsl_complex_packed_array_float data, const size_t stride, const size_t n); int gsl_fft_complex_float_radix2_dif_backward (gsl_complex_packed_array_float data, const size_t stride, const size_t n); int gsl_fft_complex_float_radix2_dif_inverse (gsl_complex_packed_array_float data, const size_t stride, const size_t n); int gsl_fft_complex_float_radix2_dif_transform (gsl_complex_packed_array_float data, const size_t stride, const size_t n, const gsl_fft_direction sign); /* Mixed Radix general-N routines */ typedef struct { size_t n; size_t nf; size_t factor[64]; gsl_complex_float *twiddle[64]; gsl_complex_float *trig; } gsl_fft_complex_wavetable_float; typedef struct { size_t n; float *scratch; } gsl_fft_complex_workspace_float; gsl_fft_complex_wavetable_float *gsl_fft_complex_wavetable_float_alloc (size_t n); void gsl_fft_complex_wavetable_float_free (gsl_fft_complex_wavetable_float * wavetable); gsl_fft_complex_workspace_float *gsl_fft_complex_workspace_float_alloc (size_t n); void gsl_fft_complex_workspace_float_free (gsl_fft_complex_workspace_float * workspace); int gsl_fft_complex_float_memcpy (gsl_fft_complex_wavetable_float * dest, gsl_fft_complex_wavetable_float * src); int gsl_fft_complex_float_forward (gsl_complex_packed_array_float data, const size_t stride, const size_t n, const gsl_fft_complex_wavetable_float * wavetable, gsl_fft_complex_workspace_float * work); int gsl_fft_complex_float_backward (gsl_complex_packed_array_float data, const size_t stride, const size_t n, const gsl_fft_complex_wavetable_float * wavetable, gsl_fft_complex_workspace_float * work); int gsl_fft_complex_float_inverse (gsl_complex_packed_array_float data, const size_t stride, const size_t n, const gsl_fft_complex_wavetable_float * wavetable, gsl_fft_complex_workspace_float * work); int gsl_fft_complex_float_transform (gsl_complex_packed_array_float data, const size_t stride, const size_t n, const gsl_fft_complex_wavetable_float * wavetable, gsl_fft_complex_workspace_float * work, const gsl_fft_direction sign); __END_DECLS #endif /* __GSL_FFT_COMPLEX_FLOAT_H__ */ praat-6.0.04/external/gsl/gsl_fft_halfcomplex.h000066400000000000000000000057041261542461700215140ustar00rootroot00000000000000/* fft/gsl_fft_halfcomplex.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_FFT_HALFCOMPLEX_H__ #define __GSL_FFT_HALFCOMPLEX_H__ #include #include "gsl_math.h" #include "gsl_complex.h" #include "gsl_fft.h" #include "gsl_fft_real.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_fft_halfcomplex_radix2_backward (double data[], const size_t stride, const size_t n); int gsl_fft_halfcomplex_radix2_inverse (double data[], const size_t stride, const size_t n); int gsl_fft_halfcomplex_radix2_transform (double data[], const size_t stride, const size_t n); typedef struct { size_t n; size_t nf; size_t factor[64]; gsl_complex *twiddle[64]; gsl_complex *trig; } gsl_fft_halfcomplex_wavetable; gsl_fft_halfcomplex_wavetable * gsl_fft_halfcomplex_wavetable_alloc (size_t n); void gsl_fft_halfcomplex_wavetable_free (gsl_fft_halfcomplex_wavetable * wavetable); int gsl_fft_halfcomplex_backward (double data[], const size_t stride, const size_t n, const gsl_fft_halfcomplex_wavetable * wavetable, gsl_fft_real_workspace * work); int gsl_fft_halfcomplex_inverse (double data[], const size_t stride, const size_t n, const gsl_fft_halfcomplex_wavetable * wavetable, gsl_fft_real_workspace * work); int gsl_fft_halfcomplex_transform (double data[], const size_t stride, const size_t n, const gsl_fft_halfcomplex_wavetable * wavetable, gsl_fft_real_workspace * work); int gsl_fft_halfcomplex_unpack (const double halfcomplex_coefficient[], double complex_coefficient[], const size_t stride, const size_t n); int gsl_fft_halfcomplex_radix2_unpack (const double halfcomplex_coefficient[], double complex_coefficient[], const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_FFT_HALFCOMPLEX_H__ */ praat-6.0.04/external/gsl/gsl_fft_halfcomplex_float.h000066400000000000000000000062221261542461700226750ustar00rootroot00000000000000/* fft/gsl_fft_halfcomplex_float.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_FFT_HALFCOMPLEX_FLOAT_H__ #define __GSL_FFT_HALFCOMPLEX_FLOAT_H__ #include #include "gsl_math.h" #include "gsl_complex.h" #include "gsl_fft.h" #include "gsl_fft_real_float.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_fft_halfcomplex_float_radix2_backward (float data[], const size_t stride, const size_t n); int gsl_fft_halfcomplex_float_radix2_inverse (float data[], const size_t stride, const size_t n); int gsl_fft_halfcomplex_float_radix2_transform (float data[], const size_t stride, const size_t n); typedef struct { size_t n; size_t nf; size_t factor[64]; gsl_complex_float *twiddle[64]; gsl_complex_float *trig; } gsl_fft_halfcomplex_wavetable_float; gsl_fft_halfcomplex_wavetable_float * gsl_fft_halfcomplex_wavetable_float_alloc (size_t n); void gsl_fft_halfcomplex_wavetable_float_free (gsl_fft_halfcomplex_wavetable_float * wavetable); int gsl_fft_halfcomplex_float_backward (float data[], const size_t stride, const size_t n, const gsl_fft_halfcomplex_wavetable_float * wavetable, gsl_fft_real_workspace_float * work); int gsl_fft_halfcomplex_float_inverse (float data[], const size_t stride, const size_t n, const gsl_fft_halfcomplex_wavetable_float * wavetable, gsl_fft_real_workspace_float * work); int gsl_fft_halfcomplex_float_transform (float data[], const size_t stride, const size_t n, const gsl_fft_halfcomplex_wavetable_float * wavetable, gsl_fft_real_workspace_float * work); int gsl_fft_halfcomplex_float_unpack (const float halfcomplex_coefficient[], float complex_coefficient[], const size_t stride, const size_t n); int gsl_fft_halfcomplex_float_radix2_unpack (const float halfcomplex_coefficient[], float complex_coefficient[], const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_FFT_HALFCOMPLEX_FLOAT_H__ */ praat-6.0.04/external/gsl/gsl_fft_real.h000066400000000000000000000042541261542461700201340ustar00rootroot00000000000000/* fft/gsl_fft_real.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_FFT_REAL_H__ #define __GSL_FFT_REAL_H__ #include #include "gsl_math.h" #include "gsl_complex.h" #include "gsl_fft.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_fft_real_radix2_transform (double data[], const size_t stride, const size_t n) ; typedef struct { size_t n; size_t nf; size_t factor[64]; gsl_complex *twiddle[64]; gsl_complex *trig; } gsl_fft_real_wavetable; typedef struct { size_t n; double *scratch; } gsl_fft_real_workspace; gsl_fft_real_wavetable * gsl_fft_real_wavetable_alloc (size_t n); void gsl_fft_real_wavetable_free (gsl_fft_real_wavetable * wavetable); gsl_fft_real_workspace * gsl_fft_real_workspace_alloc (size_t n); void gsl_fft_real_workspace_free (gsl_fft_real_workspace * workspace); int gsl_fft_real_transform (double data[], const size_t stride, const size_t n, const gsl_fft_real_wavetable * wavetable, gsl_fft_real_workspace * work); int gsl_fft_real_unpack (const double real_coefficient[], double complex_coefficient[], const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_FFT_REAL_H__ */ praat-6.0.04/external/gsl/gsl_fft_real_float.h000066400000000000000000000045021261542461700213150ustar00rootroot00000000000000/* fft/gsl_fft_real_float.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_FFT_REAL_FLOAT_H__ #define __GSL_FFT_REAL_FLOAT_H__ #include #include "gsl_math.h" #include "gsl_complex.h" #include "gsl_fft.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_fft_real_float_radix2_transform (float data[], const size_t stride, const size_t n) ; typedef struct { size_t n; size_t nf; size_t factor[64]; gsl_complex_float *twiddle[64]; gsl_complex_float *trig; } gsl_fft_real_wavetable_float; typedef struct { size_t n; float *scratch; } gsl_fft_real_workspace_float; gsl_fft_real_wavetable_float * gsl_fft_real_wavetable_float_alloc (size_t n); void gsl_fft_real_wavetable_float_free (gsl_fft_real_wavetable_float * wavetable); gsl_fft_real_workspace_float * gsl_fft_real_workspace_float_alloc (size_t n); void gsl_fft_real_workspace_float_free (gsl_fft_real_workspace_float * workspace); int gsl_fft_real_float_transform (float data[], const size_t stride, const size_t n, const gsl_fft_real_wavetable_float * wavetable, gsl_fft_real_workspace_float * work); int gsl_fft_real_float_unpack (const float real_float_coefficient[], float complex_coefficient[], const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_FFT_REAL_FLOAT_H__ */ praat-6.0.04/external/gsl/gsl_fit.h000066400000000000000000000053101261542461700171260ustar00rootroot00000000000000/* fit/gsl_fit.h * * Copyright (C) 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_FIT_H__ #define __GSL_FIT_H__ #include #include "gsl_math.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_fit_linear (const double * x, const size_t xstride, const double * y, const size_t ystride, const size_t n, double * c0, double * c1, double * cov00, double * cov01, double * cov11, double * sumsq); int gsl_fit_wlinear (const double * x, const size_t xstride, const double * w, const size_t wstride, const double * y, const size_t ystride, const size_t n, double * c0, double * c1, double * cov00, double * cov01, double * cov11, double * chisq); int gsl_fit_linear_est (const double x, const double c0, const double c1, const double cov00, const double cov01, const double cov11, double *y, double *y_err); int gsl_fit_mul (const double * x, const size_t xstride, const double * y, const size_t ystride, const size_t n, double * c1, double * cov11, double * sumsq); int gsl_fit_wmul (const double * x, const size_t xstride, const double * w, const size_t wstride, const double * y, const size_t ystride, const size_t n, double * c1, double * cov11, double * sumsq); int gsl_fit_mul_est (const double x, const double c1, const double cov11, double *y, double *y_err); __END_DECLS #endif /* __GSL_FIT_H__ */ praat-6.0.04/external/gsl/gsl_fit__linear.c000066400000000000000000000203361261542461700206170ustar00rootroot00000000000000/* fit/linear.c * * Copyright (C) 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_fit.h" /* Fit the data (x_i, y_i) to the linear relationship Y = c0 + c1 x returning, c0, c1 -- coefficients cov00, cov01, cov11 -- variance-covariance matrix of c0 and c1, sumsq -- sum of squares of residuals This fit can be used in the case where the errors for the data are uknown, but assumed equal for all points. The resulting variance-covariance matrix estimates the error in the coefficients from the observed variance of the points around the best fit line. */ int gsl_fit_linear (const double *x, const size_t xstride, const double *y, const size_t ystride, const size_t n, double *c0, double *c1, double *cov_00, double *cov_01, double *cov_11, double *sumsq) { double m_x = 0, m_y = 0, m_dx2 = 0, m_dxdy = 0; size_t i; for (i = 0; i < n; i++) { m_x += (x[i * xstride] - m_x) / (i + 1.0); m_y += (y[i * ystride] - m_y) / (i + 1.0); } for (i = 0; i < n; i++) { const double dx = x[i * xstride] - m_x; const double dy = y[i * ystride] - m_y; m_dx2 += (dx * dx - m_dx2) / (i + 1.0); m_dxdy += (dx * dy - m_dxdy) / (i + 1.0); } /* In terms of y = a + b x */ { double s2 = 0, d2 = 0; double b = m_dxdy / m_dx2; double a = m_y - m_x * b; *c0 = a; *c1 = b; /* Compute chi^2 = \sum (y_i - (a + b * x_i))^2 */ for (i = 0; i < n; i++) { const double dx = x[i * xstride] - m_x; const double dy = y[i * ystride] - m_y; const double d = dy - b * dx; d2 += d * d; } s2 = d2 / (n - 2.0); /* chisq per degree of freedom */ *cov_00 = s2 * (1.0 / n) * (1 + m_x * m_x / m_dx2); *cov_11 = s2 * 1.0 / (n * m_dx2); *cov_01 = s2 * (-m_x) / (n * m_dx2); *sumsq = d2; } return GSL_SUCCESS; } /* Fit the weighted data (x_i, w_i, y_i) to the linear relationship Y = c0 + c1 x returning, c0, c1 -- coefficients s0, s1 -- the standard deviations of c0 and c1, r -- the correlation coefficient between c0 and c1, chisq -- weighted sum of squares of residuals */ int gsl_fit_wlinear (const double *x, const size_t xstride, const double *w, const size_t wstride, const double *y, const size_t ystride, const size_t n, double *c0, double *c1, double *cov_00, double *cov_01, double *cov_11, double *chisq) { /* compute the weighted means and weighted deviations from the means */ /* wm denotes a "weighted mean", wm(f) = (sum_i w_i f_i) / (sum_i w_i) */ double W = 0, wm_x = 0, wm_y = 0, wm_dx2 = 0, wm_dxdy = 0; size_t i; for (i = 0; i < n; i++) { const double wi = w[i * wstride]; if (wi > 0) { W += wi; wm_x += (x[i * xstride] - wm_x) * (wi / W); wm_y += (y[i * ystride] - wm_y) * (wi / W); } } W = 0; /* reset the total weight */ for (i = 0; i < n; i++) { const double wi = w[i * wstride]; if (wi > 0) { const double dx = x[i * xstride] - wm_x; const double dy = y[i * ystride] - wm_y; W += wi; wm_dx2 += (dx * dx - wm_dx2) * (wi / W); wm_dxdy += (dx * dy - wm_dxdy) * (wi / W); } } /* In terms of y = a + b x */ { double d2 = 0; double b = wm_dxdy / wm_dx2; double a = wm_y - wm_x * b; *c0 = a; *c1 = b; *cov_00 = (1 / W) * (1 + wm_x * wm_x / wm_dx2); *cov_11 = 1 / (W * wm_dx2); *cov_01 = -wm_x / (W * wm_dx2); /* Compute chi^2 = \sum w_i (y_i - (a + b * x_i))^2 */ for (i = 0; i < n; i++) { const double wi = w[i * wstride]; if (wi > 0) { const double dx = x[i * xstride] - wm_x; const double dy = y[i * ystride] - wm_y; const double d = dy - b * dx; d2 += wi * d * d; } } *chisq = d2; } return GSL_SUCCESS; } int gsl_fit_linear_est (const double x, const double c0, const double c1, const double cov00, const double cov01, const double cov11, double *y, double *y_err) { *y = c0 + c1 * x; *y_err = sqrt (cov00 + x * (2 * cov01 + cov11 * x)); return GSL_SUCCESS; } int gsl_fit_mul (const double *x, const size_t xstride, const double *y, const size_t ystride, const size_t n, double *c1, double *cov_11, double *sumsq) { double m_x = 0, m_y = 0, m_dx2 = 0, m_dxdy = 0; size_t i; for (i = 0; i < n; i++) { m_x += (x[i * xstride] - m_x) / (i + 1.0); m_y += (y[i * ystride] - m_y) / (i + 1.0); } for (i = 0; i < n; i++) { const double dx = x[i * xstride] - m_x; const double dy = y[i * ystride] - m_y; m_dx2 += (dx * dx - m_dx2) / (i + 1.0); m_dxdy += (dx * dy - m_dxdy) / (i + 1.0); } /* In terms of y = b x */ { double s2 = 0, d2 = 0; double b = (m_x * m_y + m_dxdy) / (m_x * m_x + m_dx2); *c1 = b; /* Compute chi^2 = \sum (y_i - b * x_i)^2 */ for (i = 0; i < n; i++) { const double dx = x[i * xstride] - m_x; const double dy = y[i * ystride] - m_y; const double d = (m_y - b * m_x) + dy - b * dx; d2 += d * d; } s2 = d2 / (n - 1.0); /* chisq per degree of freedom */ *cov_11 = s2 * 1.0 / (n * (m_x * m_x + m_dx2)); *sumsq = d2; } return GSL_SUCCESS; } int gsl_fit_wmul (const double *x, const size_t xstride, const double *w, const size_t wstride, const double *y, const size_t ystride, const size_t n, double *c1, double *cov_11, double *chisq) { /* compute the weighted means and weighted deviations from the means */ /* wm denotes a "weighted mean", wm(f) = (sum_i w_i f_i) / (sum_i w_i) */ double W = 0, wm_x = 0, wm_y = 0, wm_dx2 = 0, wm_dxdy = 0; size_t i; for (i = 0; i < n; i++) { const double wi = w[i * wstride]; if (wi > 0) { W += wi; wm_x += (x[i * xstride] - wm_x) * (wi / W); wm_y += (y[i * ystride] - wm_y) * (wi / W); } } W = 0; /* reset the total weight */ for (i = 0; i < n; i++) { const double wi = w[i * wstride]; if (wi > 0) { const double dx = x[i * xstride] - wm_x; const double dy = y[i * ystride] - wm_y; W += wi; wm_dx2 += (dx * dx - wm_dx2) * (wi / W); wm_dxdy += (dx * dy - wm_dxdy) * (wi / W); } } /* In terms of y = b x */ { double d2 = 0; double b = (wm_x * wm_y + wm_dxdy) / (wm_x * wm_x + wm_dx2); *c1 = b; *cov_11 = 1 / (W * (wm_x * wm_x + wm_dx2)); /* Compute chi^2 = \sum w_i (y_i - b * x_i)^2 */ for (i = 0; i < n; i++) { const double wi = w[i * wstride]; if (wi > 0) { const double dx = x[i * xstride] - wm_x; const double dy = y[i * ystride] - wm_y; const double d = (wm_y - b * wm_x) + (dy - b * dx); d2 += wi * d * d; } } *chisq = d2; } return GSL_SUCCESS; } int gsl_fit_mul_est (const double x, const double c1, const double cov11, double *y, double *y_err) { *y = c1 * x; *y_err = sqrt (cov11) * fabs (x); return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_heapsort.h000066400000000000000000000026521261542461700201770ustar00rootroot00000000000000/* sort/gsl_heapsort.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_HEAPSORT_H__ #define __GSL_HEAPSORT_H__ #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef int (*gsl_comparison_fn_t) (const void *, const void *); void gsl_heapsort (void * array, size_t count, size_t size, gsl_comparison_fn_t compare); int gsl_heapsort_index (size_t * p, const void * array, size_t count, size_t size, gsl_comparison_fn_t compare); __END_DECLS #endif /* __GSL_HEAPSORT_H__ */ praat-6.0.04/external/gsl/gsl_histogram.h000066400000000000000000000100541261542461700203420ustar00rootroot00000000000000/* histogram/gsl_histogram.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_HISTOGRAM_H__ #define __GSL_HISTOGRAM_H__ #include #include #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t n ; double * range ; double * bin ; } gsl_histogram ; typedef struct { size_t n ; double * range ; double * sum ; } gsl_histogram_pdf ; gsl_histogram * gsl_histogram_alloc (size_t n); gsl_histogram * gsl_histogram_calloc (size_t n); gsl_histogram * gsl_histogram_calloc_uniform (const size_t n, const double xmin, const double xmax); void gsl_histogram_free (gsl_histogram * h); int gsl_histogram_increment (gsl_histogram * h, double x); int gsl_histogram_accumulate (gsl_histogram * h, double x, double weight); int gsl_histogram_find (const gsl_histogram * h, const double x, size_t * i); double gsl_histogram_get (const gsl_histogram * h, size_t i); int gsl_histogram_get_range (const gsl_histogram * h, size_t i, double * lower, double * upper); double gsl_histogram_max (const gsl_histogram * h); double gsl_histogram_min (const gsl_histogram * h); size_t gsl_histogram_bins (const gsl_histogram * h); void gsl_histogram_reset (gsl_histogram * h); gsl_histogram * gsl_histogram_calloc_range(size_t n, double * range); int gsl_histogram_set_ranges (gsl_histogram * h, const double range[], size_t size); int gsl_histogram_set_ranges_uniform (gsl_histogram * h, double xmin, double xmax); int gsl_histogram_memcpy(gsl_histogram * dest, const gsl_histogram * source); gsl_histogram * gsl_histogram_clone(const gsl_histogram * source); double gsl_histogram_max_val (const gsl_histogram * h); size_t gsl_histogram_max_bin (const gsl_histogram * h); double gsl_histogram_min_val (const gsl_histogram * h); size_t gsl_histogram_min_bin (const gsl_histogram * h); int gsl_histogram_equal_bins_p(const gsl_histogram *h1, const gsl_histogram *h2); int gsl_histogram_add(gsl_histogram *h1, const gsl_histogram *h2); int gsl_histogram_sub(gsl_histogram *h1, const gsl_histogram *h2); int gsl_histogram_mul(gsl_histogram *h1, const gsl_histogram *h2); int gsl_histogram_div(gsl_histogram *h1, const gsl_histogram *h2); int gsl_histogram_scale(gsl_histogram *h, double scale); int gsl_histogram_shift (gsl_histogram * h, double shift); double gsl_histogram_sigma (const gsl_histogram * h); double gsl_histogram_mean (const gsl_histogram * h); double gsl_histogram_sum (const gsl_histogram * h); int gsl_histogram_fwrite (FILE * stream, const gsl_histogram * h) ; int gsl_histogram_fread (FILE * stream, gsl_histogram * h); int gsl_histogram_fprintf (FILE * stream, const gsl_histogram * h, const char * range_format, const char * bin_format); int gsl_histogram_fscanf (FILE * stream, gsl_histogram * h); gsl_histogram_pdf * gsl_histogram_pdf_alloc (const size_t n); int gsl_histogram_pdf_init (gsl_histogram_pdf * p, const gsl_histogram * h); void gsl_histogram_pdf_free (gsl_histogram_pdf * p); double gsl_histogram_pdf_sample (const gsl_histogram_pdf * p, double r); __END_DECLS #endif /* __GSL_HISTOGRAM_H__ */ praat-6.0.04/external/gsl/gsl_histogram2d.h000066400000000000000000000130121261542461700205650ustar00rootroot00000000000000/* histogram/gsl_histogram2d.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_HISTOGRAM2D_H__ #define __GSL_HISTOGRAM2D_H__ #include #include #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t nx, ny ; double * xrange ; double * yrange ; double * bin ; } gsl_histogram2d ; typedef struct { size_t nx, ny ; double * xrange ; double * yrange ; double * sum ; } gsl_histogram2d_pdf ; gsl_histogram2d * gsl_histogram2d_alloc (const size_t nx, const size_t ny); gsl_histogram2d * gsl_histogram2d_calloc (const size_t nx, const size_t ny); gsl_histogram2d * gsl_histogram2d_calloc_uniform (const size_t nx, const size_t ny, const double xmin, const double xmax, const double ymin, const double ymax); void gsl_histogram2d_free (gsl_histogram2d * h); int gsl_histogram2d_increment (gsl_histogram2d * h, double x, double y); int gsl_histogram2d_accumulate (gsl_histogram2d * h, double x, double y, double weight); int gsl_histogram2d_find (const gsl_histogram2d * h, const double x, const double y, size_t * i, size_t * j); double gsl_histogram2d_get (const gsl_histogram2d * h, const size_t i, const size_t j); int gsl_histogram2d_get_xrange (const gsl_histogram2d * h, const size_t i, double * xlower, double * xupper); int gsl_histogram2d_get_yrange (const gsl_histogram2d * h, const size_t j, double * ylower, double * yupper); double gsl_histogram2d_xmax (const gsl_histogram2d * h); double gsl_histogram2d_xmin (const gsl_histogram2d * h); size_t gsl_histogram2d_nx (const gsl_histogram2d * h); double gsl_histogram2d_ymax (const gsl_histogram2d * h); double gsl_histogram2d_ymin (const gsl_histogram2d * h); size_t gsl_histogram2d_ny (const gsl_histogram2d * h); void gsl_histogram2d_reset (gsl_histogram2d * h); gsl_histogram2d * gsl_histogram2d_calloc_range(size_t nx, size_t ny, double *xrange, double *yrange); int gsl_histogram2d_set_ranges_uniform (gsl_histogram2d * h, double xmin, double xmax, double ymin, double ymax); int gsl_histogram2d_set_ranges (gsl_histogram2d * h, const double xrange[], size_t xsize, const double yrange[], size_t ysize); int gsl_histogram2d_memcpy(gsl_histogram2d *dest, const gsl_histogram2d *source); gsl_histogram2d * gsl_histogram2d_clone(const gsl_histogram2d * source); double gsl_histogram2d_max_val(const gsl_histogram2d *h); void gsl_histogram2d_max_bin (const gsl_histogram2d *h, size_t *i, size_t *j); double gsl_histogram2d_min_val(const gsl_histogram2d *h); void gsl_histogram2d_min_bin (const gsl_histogram2d *h, size_t *i, size_t *j); double gsl_histogram2d_xmean (const gsl_histogram2d * h); double gsl_histogram2d_ymean (const gsl_histogram2d * h); double gsl_histogram2d_xsigma (const gsl_histogram2d * h); double gsl_histogram2d_ysigma (const gsl_histogram2d * h); double gsl_histogram2d_cov (const gsl_histogram2d * h); double gsl_histogram2d_sum (const gsl_histogram2d *h); int gsl_histogram2d_equal_bins_p(const gsl_histogram2d *h1, const gsl_histogram2d *h2) ; int gsl_histogram2d_add(gsl_histogram2d *h1, const gsl_histogram2d *h2); int gsl_histogram2d_sub(gsl_histogram2d *h1, const gsl_histogram2d *h2); int gsl_histogram2d_mul(gsl_histogram2d *h1, const gsl_histogram2d *h2); int gsl_histogram2d_div(gsl_histogram2d *h1, const gsl_histogram2d *h2); int gsl_histogram2d_scale(gsl_histogram2d *h, double scale); int gsl_histogram2d_shift(gsl_histogram2d *h, double shift); int gsl_histogram2d_fwrite (FILE * stream, const gsl_histogram2d * h) ; int gsl_histogram2d_fread (FILE * stream, gsl_histogram2d * h); int gsl_histogram2d_fprintf (FILE * stream, const gsl_histogram2d * h, const char * range_format, const char * bin_format); int gsl_histogram2d_fscanf (FILE * stream, gsl_histogram2d * h); gsl_histogram2d_pdf * gsl_histogram2d_pdf_alloc (const size_t nx, const size_t ny); int gsl_histogram2d_pdf_init (gsl_histogram2d_pdf * p, const gsl_histogram2d * h); void gsl_histogram2d_pdf_free (gsl_histogram2d_pdf * p); int gsl_histogram2d_pdf_sample (const gsl_histogram2d_pdf * p, double r1, double r2, double * x, double * y); __END_DECLS #endif /* __GSL_HISTOGRAM2D_H__ */ praat-6.0.04/external/gsl/gsl_histogram__add.c000066400000000000000000000026641261542461700213140ustar00rootroot00000000000000/* histogram/add.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_histogram.h" #include "gsl_histogram__find.c" int gsl_histogram_increment (gsl_histogram * h, double x) { int status = gsl_histogram_accumulate (h, x, 1.0); return status; } int gsl_histogram_accumulate (gsl_histogram * h, double x, double weight) { const size_t n = h->n; size_t index = 0; int status = find (h->n, h->range, x, &index); if (status) { return GSL_EDOM; } if (index >= n) { GSL_ERROR ("index lies outside valid range of 0 .. n - 1", GSL_ESANITY); } h->bin[index] += weight; return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_histogram__add2d.c000066400000000000000000000033401261542461700215320ustar00rootroot00000000000000/* histogram/add2d.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_histogram.h" #include "gsl_histogram2d.h" #include "gsl_histogram__find2d.c" int gsl_histogram2d_increment (gsl_histogram2d * h, double x, double y) { int status = gsl_histogram2d_accumulate (h, x, y, 1.0); return status; } int gsl_histogram2d_accumulate (gsl_histogram2d * h, double x, double y, double weight) { const size_t nx = h->nx; const size_t ny = h->ny; size_t i = 0, j = 0; int status = find2d (h->nx, h->xrange, h->ny, h->yrange, x, y, &i, &j); if (status) { return GSL_EDOM; } if (i >= nx) { GSL_ERROR ("index lies outside valid range of 0 .. nx - 1", GSL_ESANITY); } if (j >= ny) { GSL_ERROR ("index lies outside valid range of 0 .. ny - 1", GSL_ESANITY); } h->bin[i * ny + j] += weight; return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_histogram__calloc_range.c000066400000000000000000000053271261542461700231740ustar00rootroot00000000000000/* gsl_histogram_calloc_range.c * Copyright (C) 2000 Simone Piccardi * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /*************************************************************** * * File gsl_histogram_calloc_range.c: * Routine to create a variable binning histogram providing * an input range vector. Need GSL library and header. * Do range check and allocate the histogram data. * * Author: S. Piccardi * Jan. 2000 * ***************************************************************/ #include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_histogram.h" gsl_histogram * gsl_histogram_calloc_range (size_t n, double *range) { size_t i; gsl_histogram *h; /* check arguments */ if (n == 0) { GSL_ERROR_VAL ("histogram length n must be positive integer", GSL_EDOM, 0); } /* check ranges */ for (i = 0; i < n; i++) { if (range[i] >= range[i + 1]) { GSL_ERROR_VAL ("histogram bin extremes must be " "in increasing order", GSL_EDOM, 0); } } /* Allocate histogram */ h = (gsl_histogram *) malloc (sizeof (gsl_histogram)); if (h == 0) { GSL_ERROR_VAL ("failed to allocate space for histogram struct", GSL_ENOMEM, 0); } h->range = (double *) malloc ((n + 1) * sizeof (double)); if (h->range == 0) { /* exception in constructor, avoid memory leak */ free (h); GSL_ERROR_VAL ("failed to allocate space for histogram ranges", GSL_ENOMEM, 0); } h->bin = (double *) malloc (n * sizeof (double)); if (h->bin == 0) { /* exception in constructor, avoid memory leak */ free (h->range); free (h); GSL_ERROR_VAL ("failed to allocate space for histogram bins", GSL_ENOMEM, 0); } /* initialize ranges */ for (i = 0; i <= n; i++) { h->range[i] = range[i]; } /* clear contents */ for (i = 0; i < n; i++) { h->bin[i] = 0; } h->n = n; return h; } praat-6.0.04/external/gsl/gsl_histogram__calloc_range2d.c000066400000000000000000000073341261542461700234220ustar00rootroot00000000000000/* gsl_histogram2d_calloc_range.c * Copyright (C) 2000 Simone Piccardi * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /*************************************************************** * * File gsl_histogram2d_calloc_range.c: * Routine to create a variable binning 2D histogram providing * the input range vectors. Need GSL library and header. * Do range check and allocate the histogram data. * * Author: S. Piccardi * Jan. 2000 * ***************************************************************/ #include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_histogram2d.h" /* * Routine that create a 2D histogram using the given * values for X and Y ranges */ gsl_histogram2d * gsl_histogram2d_calloc_range (size_t nx, size_t ny, double *xrange, double *yrange) { size_t i, j; gsl_histogram2d *h; /* check arguments */ if (nx == 0) { GSL_ERROR_VAL ("histogram length nx must be positive integer", GSL_EDOM, 0); } if (ny == 0) { GSL_ERROR_VAL ("histogram length ny must be positive integer", GSL_EDOM, 0); } /* init ranges */ for (i = 0; i < nx; i++) { if (xrange[i] >= xrange[i + 1]) { GSL_ERROR_VAL ("histogram xrange not in increasing order", GSL_EDOM, 0); } } for (j = 0; j < ny; j++) { if (yrange[j] >= yrange[j + 1]) { GSL_ERROR_VAL ("histogram yrange not in increasing order" ,GSL_EDOM, 0); } } /* Allocate histogram */ h = (gsl_histogram2d *) malloc (sizeof (gsl_histogram2d)); if (h == 0) { GSL_ERROR_VAL ("failed to allocate space for histogram struct", GSL_ENOMEM, 0); } h->xrange = (double *) malloc ((nx + 1) * sizeof (double)); if (h->xrange == 0) { /* exception in constructor, avoid memory leak */ free (h); GSL_ERROR_VAL ("failed to allocate space for histogram xrange", GSL_ENOMEM, 0); } h->yrange = (double *) malloc ((ny + 1) * sizeof (double)); if (h->yrange == 0) { /* exception in constructor, avoid memory leak */ free (h); GSL_ERROR_VAL ("failed to allocate space for histogram yrange", GSL_ENOMEM, 0); } h->bin = (double *) malloc (nx * ny * sizeof (double)); if (h->bin == 0) { /* exception in constructor, avoid memory leak */ free (h->xrange); free (h->yrange); free (h); GSL_ERROR_VAL ("failed to allocate space for histogram bins", GSL_ENOMEM, 0); } /* init histogram */ /* init ranges */ for (i = 0; i <= nx; i++) { h->xrange[i] = xrange[i]; } for (j = 0; j <= ny; j++) { h->yrange[j] = yrange[j]; } /* clear contents */ for (i = 0; i < nx; i++) { for (j = 0; j < ny; j++) { h->bin[i * ny + j] = 0; } } h->nx = nx; h->ny = ny; return h; } praat-6.0.04/external/gsl/gsl_histogram__copy.c000066400000000000000000000041411261542461700215260ustar00rootroot00000000000000/* gsl_histogram_copy.c * Copyright (C) 2000 Simone Piccardi * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /*************************************************************** * * File gsl_histogram_copy.c: * Routine to copy an histogram. * Need GSL library and headers. * * Author: S. Piccardi * Jan. 2000 * ***************************************************************/ #include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_histogram.h" /* * gsl_histogram_copy: * copy the contents of an histogram into another */ int gsl_histogram_memcpy (gsl_histogram * dest, const gsl_histogram * src) { size_t n = src->n; size_t i; if (dest->n != src->n) { GSL_ERROR ("histograms have different sizes, cannot copy", GSL_EINVAL); } for (i = 0; i <= n; i++) { dest->range[i] = src->range[i]; } for (i = 0; i < n; i++) { dest->bin[i] = src->bin[i]; } return GSL_SUCCESS; } /* * gsl_histogram_duplicate: * duplicate an histogram creating * an identical new one */ gsl_histogram * gsl_histogram_clone (const gsl_histogram * src) { size_t n = src->n; size_t i; gsl_histogram *h; h = gsl_histogram_calloc_range (n, src->range); if (h == 0) { GSL_ERROR_VAL ("failed to allocate space for histogram struct", GSL_ENOMEM, 0); } for (i = 0; i < n; i++) { h->bin[i] = src->bin[i]; } return h; } praat-6.0.04/external/gsl/gsl_histogram__copy2d.c000066400000000000000000000044721261542461700217630ustar00rootroot00000000000000/* gsl_histogram2d_copy.c * Copyright (C) 2000 Simone Piccardi * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /*************************************************************** * * File gsl_histogram2d_copy.c: * Routine to copy a 2D histogram. * Need GSL library and header. * * Author: S. Piccardi * Jan. 2000 * ***************************************************************/ #include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_histogram2d.h" /* * gsl_histogram2d_copy: * copy the contents of an histogram into another */ int gsl_histogram2d_memcpy (gsl_histogram2d * dest, const gsl_histogram2d * src) { size_t nx = src->nx; size_t ny = src->ny; size_t i; if (dest->nx != src->nx || dest->ny != src->ny) { GSL_ERROR ("histograms have different sizes, cannot copy", GSL_EINVAL); } for (i = 0; i <= nx; i++) { dest->xrange[i] = src->xrange[i]; } for (i = 0; i <= ny; i++) { dest->yrange[i] = src->yrange[i]; } for (i = 0; i < nx * ny; i++) { dest->bin[i] = src->bin[i]; } return GSL_SUCCESS; } /* * gsl_histogram2d_duplicate: * duplicate an histogram creating * an identical new one */ gsl_histogram2d * gsl_histogram2d_clone (const gsl_histogram2d * src) { size_t nx = src->nx; size_t ny = src->ny; size_t i; gsl_histogram2d *h; h = gsl_histogram2d_calloc_range (nx, ny, src->xrange, src->yrange); if (h == 0) { GSL_ERROR_VAL ("failed to allocate space for histogram struct", GSL_ENOMEM, 0); } for (i = 0; i < nx * ny; i++) { h->bin[i] = src->bin[i]; } return h; } praat-6.0.04/external/gsl/gsl_histogram__file.c000066400000000000000000000056451261542461700215050ustar00rootroot00000000000000/* histogram/file.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_block.h" #include "gsl_histogram.h" int gsl_histogram_fread (FILE * stream, gsl_histogram * h) { int status = gsl_block_raw_fread (stream, h->range, h->n + 1, 1); if (status) return status; status = gsl_block_raw_fread (stream, h->bin, h->n, 1); return status; } int gsl_histogram_fwrite (FILE * stream, const gsl_histogram * h) { int status = gsl_block_raw_fwrite (stream, h->range, h->n + 1, 1); if (status) return status; status = gsl_block_raw_fwrite (stream, h->bin, h->n, 1); return status; } int gsl_histogram_fprintf (FILE * stream, const gsl_histogram * h, const char *range_format, const char *bin_format) { size_t i; const size_t n = h->n; for (i = 0; i < n; i++) { int status = fprintf (stream, range_format, h->range[i]); if (status < 0) { GSL_ERROR ("fprintf failed", GSL_EFAILED); } status = putc (' ', stream); if (status == EOF) { GSL_ERROR ("putc failed", GSL_EFAILED); } status = fprintf (stream, range_format, h->range[i + 1]); if (status < 0) { GSL_ERROR ("fprintf failed", GSL_EFAILED); } status = putc (' ', stream); if (status == EOF) { GSL_ERROR ("putc failed", GSL_EFAILED); } status = fprintf (stream, bin_format, h->bin[i]); if (status < 0) { GSL_ERROR ("fprintf failed", GSL_EFAILED); } status = putc ('\n', stream); if (status == EOF) { GSL_ERROR ("putc failed", GSL_EFAILED); } } return GSL_SUCCESS; } int gsl_histogram_fscanf (FILE * stream, gsl_histogram * h) { size_t i; const size_t n = h->n; double upper; for (i = 0; i < n; i++) { int status = fscanf (stream, "%lg %lg %lg", h->range + i, &upper, h->bin + i); if (status != 3) { GSL_ERROR ("fscanf failed", GSL_EFAILED); } } h->range[n] = upper; return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_histogram__file2d.c000066400000000000000000000106351261542461700217260ustar00rootroot00000000000000/* histogram/file2d.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_block.h" #include "gsl_histogram2d.h" int gsl_histogram2d_fread (FILE * stream, gsl_histogram2d * h) { int status = gsl_block_raw_fread (stream, h->xrange, h->nx + 1, 1); if (status) return status; status = gsl_block_raw_fread (stream, h->yrange, h->ny + 1, 1); if (status) return status; status = gsl_block_raw_fread (stream, h->bin, h->nx * h->ny, 1); return status; } int gsl_histogram2d_fwrite (FILE * stream, const gsl_histogram2d * h) { int status = gsl_block_raw_fwrite (stream, h->xrange, h->nx + 1, 1); if (status) return status; status = gsl_block_raw_fwrite (stream, h->yrange, h->ny + 1, 1); if (status) return status; status = gsl_block_raw_fwrite (stream, h->bin, h->nx * h->ny, 1); return status; } int gsl_histogram2d_fprintf (FILE * stream, const gsl_histogram2d * h, const char *range_format, const char *bin_format) { size_t i, j; const size_t nx = h->nx; const size_t ny = h->ny; int status; for (i = 0; i < nx; i++) { for (j = 0; j < ny; j++) { status = fprintf (stream, range_format, h->xrange[i]); if (status < 0) { GSL_ERROR ("fprintf failed", GSL_EFAILED); } status = putc (' ', stream); if (status == EOF) { GSL_ERROR ("putc failed", GSL_EFAILED); } status = fprintf (stream, range_format, h->xrange[i + 1]); if (status < 0) { GSL_ERROR ("fprintf failed", GSL_EFAILED); } status = putc (' ', stream); if (status == EOF) { GSL_ERROR ("putc failed", GSL_EFAILED); } status = fprintf (stream, range_format, h->yrange[j]); if (status < 0) { GSL_ERROR ("fprintf failed", GSL_EFAILED); } status = putc (' ', stream); if (status == EOF) { GSL_ERROR ("putc failed", GSL_EFAILED); } status = fprintf (stream, range_format, h->yrange[j + 1]); if (status < 0) { GSL_ERROR ("fprintf failed", GSL_EFAILED); } status = putc (' ', stream); if (status == EOF) { GSL_ERROR ("putc failed", GSL_EFAILED); } status = fprintf (stream, bin_format, h->bin[i * ny + j]); if (status < 0) { GSL_ERROR ("fprintf failed", GSL_EFAILED); } status = putc ('\n', stream); if (status == EOF) { GSL_ERROR ("putc failed", GSL_EFAILED); } } status = putc ('\n', stream); if (status == EOF) { GSL_ERROR ("putc failed", GSL_EFAILED); } } return GSL_SUCCESS; } int gsl_histogram2d_fscanf (FILE * stream, gsl_histogram2d * h) { size_t i, j; const size_t nx = h->nx; const size_t ny = h->ny; double xupper, yupper; for (i = 0; i < nx; i++) { for (j = 0; j < ny; j++) { int status = fscanf (stream, "%lg %lg %lg %lg %lg", h->xrange + i, &xupper, h->yrange + j, &yupper, h->bin + i * ny + j); if (status != 5) { GSL_ERROR ("fscanf failed", GSL_EFAILED); } } h->yrange[ny] = yupper; } h->xrange[nx] = xupper; return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_histogram__find.c000066400000000000000000000036161261542461700215020ustar00rootroot00000000000000/* histogram/find.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* determines whether to optimize for linear ranges */ #define LINEAR_OPT 1 static int find (const size_t n, const double range[], const double x, size_t * i); static int find (const size_t n, const double range[], const double x, size_t * i) { size_t i_linear, lower, upper, mid; if (x < range[0]) { return -1; } if (x >= range[n]) { return +1; } /* optimize for linear case */ #ifdef LINEAR_OPT { double u = (x - range[0]) / (range[n] - range[0]); i_linear = (size_t) (u * n); } if (x >= range[i_linear] && x < range[i_linear + 1]) { *i = i_linear; return 0; } #endif /* perform binary search */ upper = n ; lower = 0 ; while (upper - lower > 1) { mid = (upper + lower) / 2 ; if (x >= range[mid]) { lower = mid ; } else { upper = mid ; } } *i = lower ; /* sanity check the result */ if (x < range[lower] || x >= range[lower + 1]) { GSL_ERROR ("x not found in range", GSL_ESANITY); } return 0; } praat-6.0.04/external/gsl/gsl_histogram__find2d.c000066400000000000000000000025741261542461700217320ustar00rootroot00000000000000/* histogram/find2d.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl_histogram__find.c" static int find2d (const size_t nx, const double xrange[], const size_t ny, const double yrange[], const double x, const double y, size_t * i, size_t * j); static int find2d (const size_t nx, const double xrange[], const size_t ny, const double yrange[], const double x, const double y, size_t * i, size_t * j) { int status = find (nx, xrange, x, i); if (status) { return status; } status = find (ny, yrange, y, j); if (status) { return status; } return 0; } praat-6.0.04/external/gsl/gsl_histogram__get.c000066400000000000000000000033301261542461700213320ustar00rootroot00000000000000/* histogram/get.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_histogram.h" #include "gsl_histogram__find.c" double gsl_histogram_get (const gsl_histogram * h, size_t i) { const size_t n = h->n; if (i >= n) { GSL_ERROR_VAL ("index lies outside valid range of 0 .. n - 1", GSL_EDOM, 0); } return h->bin[i]; } int gsl_histogram_get_range (const gsl_histogram * h, size_t i, double *lower, double *upper) { const size_t n = h->n; if (i >= n) { GSL_ERROR ("index lies outside valid range of 0 .. n - 1", GSL_EDOM); } *lower = h->range[i]; *upper = h->range[i + 1]; return GSL_SUCCESS; } int gsl_histogram_find (const gsl_histogram * h, const double x, size_t * i) { int status = find (h->n, h->range, x, i); if (status) { GSL_ERROR ("x not found in range of h", GSL_EDOM); } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_histogram__get2d.c000066400000000000000000000047371261542461700215740ustar00rootroot00000000000000/* histogram/get2d.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_histogram2d.h" #include "gsl_histogram__find.c" double gsl_histogram2d_get (const gsl_histogram2d * h, const size_t i, const size_t j) { const size_t nx = h->nx; const size_t ny = h->ny; if (i >= nx) { GSL_ERROR_VAL ("index i lies outside valid range of 0 .. nx - 1", GSL_EDOM, 0); } if (j >= ny) { GSL_ERROR_VAL ("index j lies outside valid range of 0 .. ny - 1", GSL_EDOM, 0); } return h->bin[i * ny + j]; } int gsl_histogram2d_get_xrange (const gsl_histogram2d * h, const size_t i, double *xlower, double *xupper) { const size_t nx = h->nx; if (i >= nx) { GSL_ERROR ("index i lies outside valid range of 0 .. nx - 1", GSL_EDOM); } *xlower = h->xrange[i]; *xupper = h->xrange[i + 1]; return GSL_SUCCESS; } int gsl_histogram2d_get_yrange (const gsl_histogram2d * h, const size_t j, double *ylower, double *yupper) { const size_t ny = h->ny; if (j >= ny) { GSL_ERROR ("index j lies outside valid range of 0 .. ny - 1", GSL_EDOM); } *ylower = h->yrange[j]; *yupper = h->yrange[j + 1]; return GSL_SUCCESS; } int gsl_histogram2d_find (const gsl_histogram2d * h, const double x, const double y, size_t * i, size_t * j) { int status = find (h->nx, h->xrange, x, i); if (status) { GSL_ERROR ("x not found in range of h", GSL_EDOM); } status = find (h->ny, h->yrange, y, j); if (status) { GSL_ERROR ("y not found in range of h", GSL_EDOM); } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_histogram__init.c000066400000000000000000000074761261542461700215350ustar00rootroot00000000000000/* histogram/init.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_histogram.h" gsl_histogram * gsl_histogram_alloc (size_t n) { gsl_histogram *h; if (n == 0) { GSL_ERROR_VAL ("histogram length n must be positive integer", GSL_EDOM, 0); } h = (gsl_histogram *) malloc (sizeof (gsl_histogram)); if (h == 0) { GSL_ERROR_VAL ("failed to allocate space for histogram struct", GSL_ENOMEM, 0); } h->range = (double *) malloc ((n + 1) * sizeof (double)); if (h->range == 0) { free (h); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for histogram ranges", GSL_ENOMEM, 0); } h->bin = (double *) malloc (n * sizeof (double)); if (h->bin == 0) { free (h->range); free (h); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for histogram bins", GSL_ENOMEM, 0); } h->n = n; return h; } static void make_uniform (double range[], size_t n, double xmin, double xmax) { size_t i; for (i = 0; i <= n; i++) { double f1 = ((double) (n-i) / (double) n); double f2 = ((double) i / (double) n); range[i] = f1 * xmin + f2 * xmax; } } gsl_histogram * gsl_histogram_calloc_uniform (const size_t n, const double xmin, const double xmax) { gsl_histogram *h; if (xmin >= xmax) { GSL_ERROR_VAL ("xmin must be less than xmax", GSL_EINVAL, 0); } h = gsl_histogram_calloc (n); if (h == 0) { return h; } make_uniform (h->range, n, xmin, xmax); return h; } gsl_histogram * gsl_histogram_calloc (size_t n) { gsl_histogram * h = gsl_histogram_alloc (n); if (h == 0) { return h; } { size_t i; for (i = 0; i < n + 1; i++) { h->range[i] = i; } for (i = 0; i < n; i++) { h->bin[i] = 0; } } h->n = n; return h; } void gsl_histogram_free (gsl_histogram * h) { free (h->range); free (h->bin); free (h); } /* These initialization functions suggested by Achim Gaedke */ int gsl_histogram_set_ranges_uniform (gsl_histogram * h, double xmin, double xmax) { size_t i; const size_t n = h->n; if (xmin >= xmax) { GSL_ERROR ("xmin must be less than xmax", GSL_EINVAL); } /* initialize ranges */ make_uniform (h->range, n, xmin, xmax); /* clear contents */ for (i = 0; i < n; i++) { h->bin[i] = 0; } return GSL_SUCCESS; } int gsl_histogram_set_ranges (gsl_histogram * h, const double range[], size_t size) { size_t i; const size_t n = h->n; if (size != (n+1)) { GSL_ERROR ("size of range must match size of histogram", GSL_EINVAL); } /* initialize ranges */ for (i = 0; i <= n; i++) { h->range[i] = range[i]; } /* clear contents */ for (i = 0; i < n; i++) { h->bin[i] = 0; } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_histogram__init2d.c000066400000000000000000000151771261542461700217600ustar00rootroot00000000000000/* histogram/init2d.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_errno.h" #include "gsl_histogram2d.h" gsl_histogram2d * gsl_histogram2d_alloc (const size_t nx, const size_t ny) { gsl_histogram2d *h; if (nx == 0) { GSL_ERROR_VAL ("histogram2d length nx must be positive integer", GSL_EDOM, 0); } if (ny == 0) { GSL_ERROR_VAL ("histogram2d length ny must be positive integer", GSL_EDOM, 0); } h = (gsl_histogram2d *) malloc (sizeof (gsl_histogram2d)); if (h == 0) { GSL_ERROR_VAL ("failed to allocate space for histogram2d struct", GSL_ENOMEM, 0); } h->xrange = (double *) malloc ((nx + 1) * sizeof (double)); if (h->xrange == 0) { free (h); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for histogram2d x ranges", GSL_ENOMEM, 0); } h->yrange = (double *) malloc ((ny + 1) * sizeof (double)); if (h->yrange == 0) { free (h->xrange); free (h); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for histogram2d y ranges", GSL_ENOMEM, 0); } h->bin = (double *) malloc (nx * ny * sizeof (double)); if (h->bin == 0) { free (h->xrange); free (h->yrange); free (h); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for histogram bins", GSL_ENOMEM, 0); } h->nx = nx; h->ny = ny; return h; } static void make_uniform (double range[], size_t n, double xmin, double xmax) { size_t i; for (i = 0; i <= n; i++) { double f1 = ((double) (n-i) / (double) n); double f2 = ((double) i / (double) n); range[i] = f1 * xmin + f2 * xmax; } } gsl_histogram2d * gsl_histogram2d_calloc_uniform (const size_t nx, const size_t ny, const double xmin, const double xmax, const double ymin, const double ymax) { gsl_histogram2d *h; if (xmin >= xmax) { GSL_ERROR_VAL ("xmin must be less than xmax", GSL_EINVAL, 0); } if (ymin >= ymax) { GSL_ERROR_VAL ("ymin must be less than ymax", GSL_EINVAL, 0); } h = gsl_histogram2d_calloc (nx, ny); if (h == 0) { return h; } make_uniform (h->xrange, nx, xmin, xmax); make_uniform (h->yrange, ny, ymin, ymax); return h; } gsl_histogram2d * gsl_histogram2d_calloc (const size_t nx, const size_t ny) { gsl_histogram2d *h; if (nx == 0) { GSL_ERROR_VAL ("histogram2d length nx must be positive integer", GSL_EDOM, 0); } if (ny == 0) { GSL_ERROR_VAL ("histogram2d length ny must be positive integer", GSL_EDOM, 0); } h = (gsl_histogram2d *) malloc (sizeof (gsl_histogram2d)); if (h == 0) { GSL_ERROR_VAL ("failed to allocate space for histogram2d struct", GSL_ENOMEM, 0); } h->xrange = (double *) malloc ((nx + 1) * sizeof (double)); if (h->xrange == 0) { free (h); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for histogram2d x ranges", GSL_ENOMEM, 0); } h->yrange = (double *) malloc ((ny + 1) * sizeof (double)); if (h->yrange == 0) { free (h->xrange); free (h); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for histogram2d y ranges", GSL_ENOMEM, 0); } h->bin = (double *) malloc (nx * ny * sizeof (double)); if (h->bin == 0) { free (h->xrange); free (h->yrange); free (h); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for histogram bins", GSL_ENOMEM, 0); } { size_t i; for (i = 0; i < nx + 1; i++) { h->xrange[i] = i; } for (i = 0; i < ny + 1; i++) { h->yrange[i] = i; } for (i = 0; i < nx * ny; i++) { h->bin[i] = 0; } } h->nx = nx; h->ny = ny; return h; } void gsl_histogram2d_free (gsl_histogram2d * h) { free (h->xrange); free (h->yrange); free (h->bin); free (h); } int gsl_histogram2d_set_ranges_uniform (gsl_histogram2d * h, double xmin, double xmax, double ymin, double ymax) { size_t i; const size_t nx = h->nx, ny = h->ny; if (xmin >= xmax) { GSL_ERROR_VAL ("xmin must be less than xmax", GSL_EINVAL, 0); } if (ymin >= ymax) { GSL_ERROR_VAL ("ymin must be less than ymax", GSL_EINVAL, 0); } /* initialize ranges */ make_uniform (h->xrange, nx, xmin, xmax); make_uniform (h->yrange, ny, ymin, ymax); /* clear contents */ for (i = 0; i < nx * ny; i++) { h->bin[i] = 0; } return GSL_SUCCESS; } int gsl_histogram2d_set_ranges (gsl_histogram2d * h, const double xrange[], size_t xsize, const double yrange[], size_t ysize) { size_t i; const size_t nx = h->nx, ny = h->ny; if (xsize != (nx + 1)) { GSL_ERROR_VAL ("size of xrange must match size of histogram", GSL_EINVAL, 0); } if (ysize != (ny + 1)) { GSL_ERROR_VAL ("size of yrange must match size of histogram", GSL_EINVAL, 0); } /* initialize ranges */ for (i = 0; i <= nx; i++) { h->xrange[i] = xrange[i]; } for (i = 0; i <= ny; i++) { h->yrange[i] = yrange[i]; } /* clear contents */ for (i = 0; i < nx * ny; i++) { h->bin[i] = 0; } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_histogram__maxval.c000066400000000000000000000045721261542461700220540ustar00rootroot00000000000000/* gsl_histogram_maxval.c * Copyright (C) 2000 Simone Piccardi * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /*************************************************************** * * File gsl_histogram_maxval.c: * Routine to find maximum and minumum content of a hisogram. * Need GSL library and header. * Contains the routines: * gsl_histogram_max_val find max content values * gsl_histogram_min_val find min content values * gsl_histogram_bin_max find coordinates of max contents bin * gsl_histogram_bin_min find coordinates of min contents bin * * Author: S. Piccardi * Jan. 2000 * ***************************************************************/ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_histogram.h" double gsl_histogram_max_val (const gsl_histogram * h) { const size_t n = h->n; size_t i; double max = h->bin[0]; for (i = 0; i < n; i++) { if (h->bin[i] > max) { max = h->bin[i]; } } return max; } size_t gsl_histogram_max_bin (const gsl_histogram * h) { size_t i; size_t imax = 0; double max = h->bin[0]; for (i = 0; i < h->n; i++) { if (h->bin[i] > max) { max = h->bin[i]; imax = i; } } return imax; } double gsl_histogram_min_val (const gsl_histogram * h) { size_t i; double min = h->bin[0]; for (i = 0; i < h->n; i++) { if (h->bin[i] < min) { min = h->bin[i]; } } return min; } size_t gsl_histogram_min_bin (const gsl_histogram * h) { size_t i; size_t imin = 0; double min = h->bin[0]; for (i = 0; i < h->n; i++) { if (h->bin[i] < min) { min = h->bin[i]; imin = i; } } return imin; } praat-6.0.04/external/gsl/gsl_histogram__maxval2d.c000066400000000000000000000063751261542461700223050ustar00rootroot00000000000000/* gsl_histogram2d_maxval.c * Copyright (C) 2000 Simone Piccardi * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /*************************************************************** * * File gsl_histogram2d_maxval.c: * Routine to find maximum and minumum content of a 2D hisogram. * Need GSL library and header. * Contains the routines: * gsl_histogram2d_max_val find max content values * gsl_histogram2d_min_val find min content values * gsl_histogram2d_bin_max find coordinates of max contents bin * gsl_histogram2d_bin_min find coordinates of min contents bin * * Author: S. Piccardi * Jan. 2000 * ***************************************************************/ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_histogram2d.h" /* * Return the maximum contents value of a 2D histogram */ double gsl_histogram2d_max_val (const gsl_histogram2d * h) { const size_t nx = h->nx; const size_t ny = h->ny; size_t i; double max = h->bin[0 * ny + 0]; for (i = 0; i < nx * ny; i++) { if (h->bin[i] > max) { max = h->bin[i]; } } return max; } /* * Find the bin index for maximum value of a 2D histogram */ void gsl_histogram2d_max_bin (const gsl_histogram2d * h, size_t * imax_out, size_t * jmax_out) { const size_t nx = h->nx; const size_t ny = h->ny; size_t imax = 0, jmax = 0, i, j; double max = h->bin[0 * ny + 0]; for (i = 0; i < nx; i++) { for (j = 0; j < ny; j++) { double x = h->bin[i * ny + j]; if (x > max) { max = x; imax = i; jmax = j; } } } *imax_out = imax; *jmax_out = jmax; } /* * Return the minimum contents value of a 2D histogram */ double gsl_histogram2d_min_val (const gsl_histogram2d * h) { const size_t nx = h->nx; const size_t ny = h->ny; size_t i; double min = h->bin[0 * ny + 0]; for (i = 0; i < nx * ny; i++) { if (h->bin[i] < min) { min = h->bin[i]; } } return min; } /* * Find the bin index for minimum value of a 2D histogram */ void gsl_histogram2d_min_bin (const gsl_histogram2d * h, size_t * imin_out, size_t * jmin_out) { const size_t nx = h->nx; const size_t ny = h->ny; size_t imin = 0, jmin = 0, i, j; double min = h->bin[0 * ny + 0]; for (i = 0; i < nx; i++) { for (j = 0; j < ny; j++) { double x = h->bin[i * ny + j]; if (x < min) { min = x; imin = i; jmin = j; } } } *imin_out = imin; *jmin_out = jmin; } praat-6.0.04/external/gsl/gsl_histogram__oper.c000066400000000000000000000075011261542461700215240ustar00rootroot00000000000000/* gsl_histogram_oper.c * Copyright (C) 2000 Simone Piccardi * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /*************************************************************** * * File gsl_histogram_oper.c: * Routine to make operation on histograms. * Need GSL library and header. * Contains the routines: * gsl_histogram_same_binning check if two histograms have the same binning * gsl_histogram_add add two histograms * gsl_histogram_sub subctract two histograms * gsl_histogram_mult multiply two histograms * gsl_histogram_div divide two histograms * gsl_histogram_scale scale histogram contents * * Author: S. Piccardi * Jan. 2000 * ***************************************************************/ #include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_histogram.h" /* * gsl_histogram_same_binning: * control if two histograms have the * same binning */ int gsl_histogram_equal_bins_p (const gsl_histogram * h1, const gsl_histogram * h2) { if (h1->n != h2->n) { return 0; } { size_t i; /* init ranges */ for (i = 0; i <= h1->n; i++) { if (h1->range[i] != h2->range[i]) { return 0; } } } return 1; } /* * gsl_histogram_add: * add two histograms */ int gsl_histogram_add (gsl_histogram * h1, const gsl_histogram * h2) { size_t i; if (!gsl_histogram_equal_bins_p (h1, h2)) { GSL_ERROR ("histograms have different binning", GSL_EINVAL); } for (i = 0; i < h1->n; i++) { h1->bin[i] += h2->bin[i]; } return GSL_SUCCESS; } /* * gsl_histogram_sub: * subtract two histograms */ int gsl_histogram_sub (gsl_histogram * h1, const gsl_histogram * h2) { size_t i; if (!gsl_histogram_equal_bins_p (h1, h2)) { GSL_ERROR ("histograms have different binning", GSL_EINVAL); } for (i = 0; i < h1->n; i++) { h1->bin[i] -= h2->bin[i]; } return GSL_SUCCESS; } /* * gsl_histogram_mult: * multiply two histograms */ int gsl_histogram_mul (gsl_histogram * h1, const gsl_histogram * h2) { size_t i; if (!gsl_histogram_equal_bins_p (h1, h2)) { GSL_ERROR ("histograms have different binning", GSL_EINVAL); } for (i = 0; i < h1->n; i++) { h1->bin[i] *= h2->bin[i]; } return GSL_SUCCESS; } /* * gsl_histogram_div: * divide two histograms */ int gsl_histogram_div (gsl_histogram * h1, const gsl_histogram * h2) { size_t i; if (!gsl_histogram_equal_bins_p (h1, h2)) { GSL_ERROR ("histograms have different binning", GSL_EINVAL); } for (i = 0; i < h1->n; i++) { h1->bin[i] /= h2->bin[i]; } return GSL_SUCCESS; } /* * gsl_histogram_scale: * scale a histogram by a numeric factor */ int gsl_histogram_scale (gsl_histogram * h, double scale) { size_t i; for (i = 0; i < h->n; i++) { h->bin[i] *= scale; } return GSL_SUCCESS; } /* * gsl_histogram_shift: * shift a histogram by a numeric offset */ int gsl_histogram_shift (gsl_histogram * h, double shift) { size_t i; for (i = 0; i < h->n; i++) { h->bin[i] += shift; } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_histogram__oper2d.c000066400000000000000000000102521261542461700217470ustar00rootroot00000000000000/* gsl_histogram2d_oper.c * Copyright (C) 2000 Simone Piccardi * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /*************************************************************** * * File gsl_histogram2d_oper.c: * Routine to make operation on 2D histograms. * Need GSL library and header. * Contains the routines: * gsl_histogram2d_same_binning check if two histograms have the same binning * gsl_histogram2d_add add two histogram * gsl_histogram2d_sub subctract two histogram * gsl_histogram2d_mult multiply two histogram * gsl_histogram2d_div divide two histogram * gsl_histogram2d_scale scale histogram contents * * Author: S. Piccardi * Jan. 2000 * ***************************************************************/ #include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_histogram2d.h" /* * gsl_histogram2d_same_binning: * control if two histogram have the * same binning */ int gsl_histogram2d_equal_bins_p (const gsl_histogram2d * h1, const gsl_histogram2d * h2) { if ((h1->nx != h2->nx) || (h1->ny != h2->ny)) { return 0; } { size_t i; /* init ranges */ for (i = 0; i <= (h1->nx); i++) { if (h1->xrange[i] != h2->xrange[i]) { return 0; } } for (i = 0; i <= (h1->ny); i++) { if (h1->yrange[i] != h2->yrange[i]) { return 0; } } } return 1; } /* * gsl_histogram2d_add: * add two histogram */ int gsl_histogram2d_add (gsl_histogram2d * h1, const gsl_histogram2d * h2) { size_t i; if (!gsl_histogram2d_equal_bins_p (h1, h2)) { GSL_ERROR ("histograms have different binning", GSL_EINVAL); } for (i = 0; i < (h1->nx) * (h1->ny); i++) { h1->bin[i] += h2->bin[i]; } return GSL_SUCCESS; } /* * gsl_histogram2d_sub: * subtract two histogram */ int gsl_histogram2d_sub (gsl_histogram2d * h1, const gsl_histogram2d * h2) { size_t i; if (!gsl_histogram2d_equal_bins_p (h1, h2)) { GSL_ERROR ("histograms have different binning", GSL_EINVAL); } for (i = 0; i < (h1->nx) * (h1->ny); i++) { h1->bin[i] -= h2->bin[i]; } return GSL_SUCCESS; } /* * gsl_histogram2d_mult: * multiply two histogram */ int gsl_histogram2d_mul (gsl_histogram2d * h1, const gsl_histogram2d * h2) { size_t i; if (!gsl_histogram2d_equal_bins_p (h1, h2)) { GSL_ERROR ("histograms have different binning", GSL_EINVAL); } for (i = 0; i < (h1->nx) * (h1->ny); i++) { h1->bin[i] *= h2->bin[i]; } return GSL_SUCCESS; } /* * gsl_histogram2d_div: * divide two histogram */ int gsl_histogram2d_div (gsl_histogram2d * h1, const gsl_histogram2d * h2) { size_t i; if (!gsl_histogram2d_equal_bins_p (h1, h2)) { GSL_ERROR ("histograms have different binning", GSL_EINVAL); } for (i = 0; i < (h1->nx) * (h1->ny); i++) { h1->bin[i] /= h2->bin[i]; } return GSL_SUCCESS; } /* * gsl_histogram2d_scale: * scale a histogram by a numeric factor */ int gsl_histogram2d_scale (gsl_histogram2d * h, double scale) { size_t i; for (i = 0; i < (h->nx) * (h->ny); i++) { h->bin[i] *= scale; } return GSL_SUCCESS; } /* * gsl_histogram2d_shift: * shift a histogram by a numeric offset */ int gsl_histogram2d_shift (gsl_histogram2d * h, double shift) { size_t i; for (i = 0; i < (h->nx) * (h->ny); i++) { h->bin[i] += shift; } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_histogram__params.c000066400000000000000000000021711261542461700220400ustar00rootroot00000000000000/* histogram/params.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_histogram.h" double gsl_histogram_max (const gsl_histogram * h) { const int n = h->n; return h->range[n]; } double gsl_histogram_min (const gsl_histogram * h) { return h->range[0]; } size_t gsl_histogram_bins (const gsl_histogram * h) { return h->n; } praat-6.0.04/external/gsl/gsl_histogram__params2d.c000066400000000000000000000026321261542461700222700ustar00rootroot00000000000000/* histogram/params2d.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_histogram2d.h" double gsl_histogram2d_xmax (const gsl_histogram2d * h) { const int nx = h->nx; return h->xrange[nx]; } double gsl_histogram2d_xmin (const gsl_histogram2d * h) { return h->xrange[0]; } double gsl_histogram2d_ymax (const gsl_histogram2d * h) { const int ny = h->ny; return h->yrange[ny]; } double gsl_histogram2d_ymin (const gsl_histogram2d * h) { return h->yrange[0]; } size_t gsl_histogram2d_nx (const gsl_histogram2d * h) { return h->nx; } size_t gsl_histogram2d_ny (const gsl_histogram2d * h) { return h->ny; } praat-6.0.04/external/gsl/gsl_histogram__pdf.c000066400000000000000000000066731261542461700213410ustar00rootroot00000000000000/* histogram/pdf.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_histogram.h" #include "gsl_histogram__find.c" double gsl_histogram_pdf_sample (const gsl_histogram_pdf * p, double r) { size_t i; int status; /* Wrap the exclusive top of the bin down to the inclusive bottom of the bin. Since this is a single point it should not affect the distribution. */ if (r == 1.0) { r = 0.0; } status = find (p->n, p->sum, r, &i); if (status) { GSL_ERROR_VAL ("cannot find r in cumulative pdf", GSL_EDOM, 0); } else { double delta = (r - p->sum[i]) / (p->sum[i + 1] - p->sum[i]); double x = p->range[i] + delta * (p->range[i + 1] - p->range[i]); return x; } } gsl_histogram_pdf * gsl_histogram_pdf_alloc (const size_t n) { gsl_histogram_pdf *p; if (n == 0) { GSL_ERROR_VAL ("histogram pdf length n must be positive integer", GSL_EDOM, 0); } p = (gsl_histogram_pdf *) malloc (sizeof (gsl_histogram_pdf)); if (p == 0) { GSL_ERROR_VAL ("failed to allocate space for histogram pdf struct", GSL_ENOMEM, 0); } p->range = (double *) malloc ((n + 1) * sizeof (double)); if (p->range == 0) { free (p); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for histogram pdf ranges", GSL_ENOMEM, 0); } p->sum = (double *) malloc ((n + 1) * sizeof (double)); if (p->sum == 0) { free (p->range); free (p); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for histogram pdf sums", GSL_ENOMEM, 0); } p->n = n; return p; } int gsl_histogram_pdf_init (gsl_histogram_pdf * p, const gsl_histogram * h) { size_t i; size_t n = p->n; if (n != h->n) { GSL_ERROR ("histogram length must match pdf length", GSL_EINVAL); } for (i = 0; i < n; i++) { if (h->bin[i] < 0) { GSL_ERROR ("histogram bins must be non-negative to compute" "a probability distribution", GSL_EDOM); } } for (i = 0; i < n + 1; i++) { p->range[i] = h->range[i]; } { double mean = 0, sum = 0; for (i = 0; i < n; i++) { mean += (h->bin[i] - mean) / ((double) (i + 1)); } p->sum[0] = 0; for (i = 0; i < n; i++) { sum += (h->bin[i] / mean) / n; p->sum[i + 1] = sum; } } return GSL_SUCCESS; } void gsl_histogram_pdf_free (gsl_histogram_pdf * p) { free (p->range); free (p->sum); free (p); } praat-6.0.04/external/gsl/gsl_histogram__pdf2d.c000066400000000000000000000105241261542461700215550ustar00rootroot00000000000000/* histogram/pdf2d.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_histogram.h" #include "gsl_histogram2d.h" #include "gsl_histogram__find.c" int gsl_histogram2d_pdf_sample (const gsl_histogram2d_pdf * p, double r1, double r2, double *x, double *y) { size_t k; int status; /* Wrap the exclusive top of the bin down to the inclusive bottom of the bin. Since this is a single point it should not affect the distribution. */ if (r2 == 1.0) { r2 = 0.0; } if (r1 == 1.0) { r1 = 0.0; } status = find (p->nx * p->ny, p->sum, r1, &k); if (status) { GSL_ERROR ("cannot find r1 in cumulative pdf", GSL_EDOM); } else { size_t i = k / p->ny; size_t j = k - (i * p->ny); double delta = (r1 - p->sum[k]) / (p->sum[k + 1] - p->sum[k]); *x = p->xrange[i] + delta * (p->xrange[i + 1] - p->xrange[i]); *y = p->yrange[j] + r2 * (p->yrange[j + 1] - p->yrange[j]); return GSL_SUCCESS; } } gsl_histogram2d_pdf * gsl_histogram2d_pdf_alloc (const size_t nx, const size_t ny) { const size_t n = nx * ny; gsl_histogram2d_pdf *p; if (n == 0) { GSL_ERROR_VAL ("histogram2d pdf length n must be positive integer", GSL_EDOM, 0); } p = (gsl_histogram2d_pdf *) malloc (sizeof (gsl_histogram2d_pdf)); if (p == 0) { GSL_ERROR_VAL ("failed to allocate space for histogram2d pdf struct", GSL_ENOMEM, 0); } p->xrange = (double *) malloc ((nx + 1) * sizeof (double)); if (p->xrange == 0) { free (p); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for histogram2d pdf xranges", GSL_ENOMEM, 0); } p->yrange = (double *) malloc ((ny + 1) * sizeof (double)); if (p->yrange == 0) { free (p->xrange); free (p); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for histogram2d pdf yranges", GSL_ENOMEM, 0); } p->sum = (double *) malloc ((n + 1) * sizeof (double)); if (p->sum == 0) { free (p->yrange); free (p->xrange); free (p); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for histogram2d pdf sums", GSL_ENOMEM, 0); } p->nx = nx; p->ny = ny; return p; } int gsl_histogram2d_pdf_init (gsl_histogram2d_pdf * p, const gsl_histogram2d * h) { size_t i; const size_t nx = p->nx; const size_t ny = p->ny; const size_t n = nx * ny; if (nx != h->nx || ny != h->ny) { GSL_ERROR ("histogram2d size must match pdf size", GSL_EDOM); } for (i = 0; i < n; i++) { if (h->bin[i] < 0) { GSL_ERROR ("histogram bins must be non-negative to compute" "a probability distribution", GSL_EDOM); } } for (i = 0; i < nx + 1; i++) { p->xrange[i] = h->xrange[i]; } for (i = 0; i < ny + 1; i++) { p->yrange[i] = h->yrange[i]; } { double mean = 0, sum = 0; for (i = 0; i < n; i++) { mean += (h->bin[i] - mean) / ((double) (i + 1)); } p->sum[0] = 0; for (i = 0; i < n; i++) { sum += (h->bin[i] / mean) / n; p->sum[i + 1] = sum; } } return GSL_SUCCESS; } void gsl_histogram2d_pdf_free (gsl_histogram2d_pdf * p) { free (p->xrange); free (p->yrange); free (p->sum); free (p); } praat-6.0.04/external/gsl/gsl_histogram__reset.c000066400000000000000000000020201261542461700216700ustar00rootroot00000000000000/* histogram/reset.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_histogram.h" void gsl_histogram_reset (gsl_histogram * h) { size_t i; const size_t n = h->n; for (i = 0; i < n; i++) { h->bin[i] = 0; } } praat-6.0.04/external/gsl/gsl_histogram__reset2d.c000066400000000000000000000020731261542461700221260ustar00rootroot00000000000000/* histogram/reset2d.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_histogram2d.h" void gsl_histogram2d_reset (gsl_histogram2d * h) { size_t i; const size_t nx = h->nx; const size_t ny = h->ny; for (i = 0; i < nx * ny; i++) { h->bin[i] = 0; } } praat-6.0.04/external/gsl/gsl_histogram__stat.c000066400000000000000000000061411261542461700215310ustar00rootroot00000000000000/* gsl_histogram_stat.c * Copyright (C) 2000 Simone Piccardi * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /*************************************************************** * * File gsl_histogram_stat.c: * Routines for statisticalcomputations on histograms. * Need GSL library and header. * Contains the routines: * gsl_histogram_mean compute histogram mean * gsl_histogram_sigma compute histogram sigma * * Author: S. Piccardi * Jan. 2000 * ***************************************************************/ #include "gsl__config.h" #include #include #include "gsl_errno.h" #include "gsl_histogram.h" /* FIXME: We skip negative values in the histogram h->bin[i] < 0, since those correspond to negative weights (BJG) */ double gsl_histogram_mean (const gsl_histogram * h) { const size_t n = h->n; size_t i; /* Compute the bin-weighted arithmetic mean M of a histogram using the recurrence relation M(n) = M(n-1) + (x[n] - M(n-1)) (w(n)/(W(n-1) + w(n))) W(n) = W(n-1) + w(n) */ long double wmean = 0; long double W = 0; for (i = 0; i < n; i++) { double xi = (h->range[i + 1] + h->range[i]) / 2; double wi = h->bin[i]; if (wi > 0) { W += wi; wmean += (xi - wmean) * (wi / W); } } return wmean; } double gsl_histogram_sigma (const gsl_histogram * h) { const size_t n = h->n; size_t i; long double wvariance = 0 ; long double wmean = 0; long double W = 0; /* FIXME: should use a single pass formula here, as given in N.J.Higham 'Accuracy and Stability of Numerical Methods', p.12 */ /* Compute the mean */ for (i = 0; i < n; i++) { double xi = (h->range[i + 1] + h->range[i]) / 2; double wi = h->bin[i]; if (wi > 0) { W += wi; wmean += (xi - wmean) * (wi / W); } } /* Compute the variance */ W = 0.0; for (i = 0; i < n; i++) { double xi = ((h->range[i + 1]) + (h->range[i])) / 2; double wi = h->bin[i]; if (wi > 0) { const long double delta = (xi - wmean); W += wi ; wvariance += (delta * delta - wvariance) * (wi / W); } } { double sigma = sqrt (wvariance) ; return sigma; } } /* sum up all bins of histogram */ double gsl_histogram_sum(const gsl_histogram * h) { double sum=0; size_t i=0; size_t n; n=h->n; while(i < n) sum += h->bin[i++]; return sum; } praat-6.0.04/external/gsl/gsl_histogram__stat2d.c000066400000000000000000000132661261542461700217650ustar00rootroot00000000000000/* histogram/stat2d.c * Copyright (C) 2002 Achim Gaedke * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /*************************************************************** * * File histogram/stat2d.c: * Routine to return statistical values of the content of a 2D hisogram. * * Contains the routines: * gsl_histogram2d_sum sum up all bin values * gsl_histogram2d_xmean determine mean of x values * gsl_histogram2d_ymean determine mean of y values * * Author: Achim Gaedke Achim.Gaedke@zpr.uni-koeln.de * Jan. 2002 * ***************************************************************/ #include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_histogram2d.h" /* sum up all bins of histogram2d */ double gsl_histogram2d_sum (const gsl_histogram2d * h) { const size_t n = h->nx * h->ny; double sum = 0; size_t i = 0; while (i < n) sum += h->bin[i++]; return sum; } double gsl_histogram2d_xmean (const gsl_histogram2d * h) { const size_t nx = h->nx; const size_t ny = h->ny; size_t i; size_t j; /* Compute the bin-weighted arithmetic mean M of a histogram using the recurrence relation M(n) = M(n-1) + (x[n] - M(n-1)) (w(n)/(W(n-1) + w(n))) W(n) = W(n-1) + w(n) */ long double wmean = 0; long double W = 0; for (i = 0; i < nx; i++) { double xi = (h->xrange[i + 1] + h->xrange[i]) / 2.0; double wi = 0; for (j = 0; j < ny; j++) { double wij = h->bin[i * ny + j]; if (wij > 0) wi += wij; } if (wi > 0) { W += wi; wmean += (xi - wmean) * (wi / W); } } return wmean; } double gsl_histogram2d_ymean (const gsl_histogram2d * h) { const size_t nx = h->nx; const size_t ny = h->ny; size_t i; size_t j; /* Compute the bin-weighted arithmetic mean M of a histogram using the recurrence relation M(n) = M(n-1) + (x[n] - M(n-1)) (w(n)/(W(n-1) + w(n))) W(n) = W(n-1) + w(n) */ long double wmean = 0; long double W = 0; for (j = 0; j < ny; j++) { double yj = (h->yrange[j + 1] + h->yrange[j]) / 2.0; double wj = 0; for (i = 0; i < nx; i++) { double wij = h->bin[i * ny + j]; if (wij > 0) wj += wij; } if (wj > 0) { W += wj; wmean += (yj - wmean) * (wj / W); } } return wmean; } double gsl_histogram2d_xsigma (const gsl_histogram2d * h) { const double xmean = gsl_histogram2d_xmean (h); const size_t nx = h->nx; const size_t ny = h->ny; size_t i; size_t j; /* Compute the bin-weighted arithmetic mean M of a histogram using the recurrence relation M(n) = M(n-1) + (x[n] - M(n-1)) (w(n)/(W(n-1) + w(n))) W(n) = W(n-1) + w(n) */ long double wvariance = 0; long double W = 0; for (i = 0; i < nx; i++) { double xi = (h->xrange[i + 1] + h->xrange[i]) / 2 - xmean; double wi = 0; for (j = 0; j < ny; j++) { double wij = h->bin[i * ny + j]; if (wij > 0) wi += wij; } if (wi > 0) { W += wi; wvariance += ((xi * xi) - wvariance) * (wi / W); } } { double xsigma = sqrt (wvariance); return xsigma; } } double gsl_histogram2d_ysigma (const gsl_histogram2d * h) { const double ymean = gsl_histogram2d_ymean (h); const size_t nx = h->nx; const size_t ny = h->ny; size_t i; size_t j; /* Compute the bin-weighted arithmetic mean M of a histogram using the recurrence relation M(n) = M(n-1) + (x[n] - M(n-1)) (w(n)/(W(n-1) + w(n))) W(n) = W(n-1) + w(n) */ long double wvariance = 0; long double W = 0; for (j = 0; j < ny; j++) { double yj = (h->yrange[j + 1] + h->yrange[j]) / 2.0 - ymean; double wj = 0; for (i = 0; i < nx; i++) { double wij = h->bin[i * ny + j]; if (wij > 0) wj += wij; } if (wj > 0) { W += wj; wvariance += ((yj * yj) - wvariance) * (wj / W); } } { double ysigma = sqrt (wvariance); return ysigma; } } double gsl_histogram2d_cov (const gsl_histogram2d * h) { const double xmean = gsl_histogram2d_xmean (h); const double ymean = gsl_histogram2d_ymean (h); const size_t nx = h->nx; const size_t ny = h->ny; size_t i; size_t j; /* Compute the bin-weighted arithmetic mean M of a histogram using the recurrence relation M(n) = M(n-1) + (x[n] - M(n-1)) (w(n)/(W(n-1) + w(n))) W(n) = W(n-1) + w(n) */ long double wcovariance = 0; long double W = 0; for (j = 0; j < ny; j++) { for (i = 0; i < nx; i++) { double xi = (h->xrange[i + 1] + h->xrange[i]) / 2.0 - xmean; double yj = (h->yrange[j + 1] + h->yrange[j]) / 2.0 - ymean; double wij = h->bin[i * ny + j]; if (wij > 0) { W += wij; wcovariance += ((xi * yj) - wcovariance) * (wij / W); } } } return wcovariance; } praat-6.0.04/external/gsl/gsl_histogram__urand.c000066400000000000000000000017361261542461700216740ustar00rootroot00000000000000/* histogram/urand.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static double urand (void); static double urand (void) { static unsigned long int x = 1; x = (1103515245 * x + 12345) & 0x7fffffffUL ; return x / 2147483648.0 ; } praat-6.0.04/external/gsl/gsl_ieee-utils__endian.c000066400000000000000000000021671261542461700220700ustar00rootroot00000000000000/* ieee-utils/endian.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_ieee_utils.h" static int little_endian_p (void) ; static int little_endian_p (void) { /* Are we little or big endian? From Harbison & Steele. */ union { long l; char c[sizeof (long)]; } u; u.l = 1; return (u.c[sizeof (long) - 1] == 1); } praat-6.0.04/external/gsl/gsl_ieee-utils__env.c000066400000000000000000000057221261542461700214220ustar00rootroot00000000000000/* ieee-utils/env.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_ieee_utils.h" #include "gsl_errno.h" void gsl_ieee_env_setup (void) { const char * p = getenv("GSL_IEEE_MODE") ; int precision = 0, rounding = 0, exception_mask = 0 ; int comma = 0 ; if (p == 0) /* GSL_IEEE_MODE environment variable is not set */ return ; if (*p == '\0') /* GSL_IEEE_MODE environment variable is empty */ return ; gsl_ieee_read_mode_string (p, &precision, &rounding, &exception_mask) ; gsl_ieee_set_mode (precision, rounding, exception_mask) ; fprintf(stderr, "GSL_IEEE_MODE=\"") ; /* Print string with a preceeding comma if the list has already begun */ #define PRINTC(x) do {if(comma) fprintf(stderr,","); fprintf(stderr,x); comma++ ;} while(0) switch (precision) { case GSL_IEEE_SINGLE_PRECISION: PRINTC("single-precision") ; break ; case GSL_IEEE_DOUBLE_PRECISION: PRINTC("double-precision") ; break ; case GSL_IEEE_EXTENDED_PRECISION: PRINTC("extended-precision") ; break ; } switch (rounding) { case GSL_IEEE_ROUND_TO_NEAREST: PRINTC("round-to-nearest") ; break ; case GSL_IEEE_ROUND_DOWN: PRINTC("round-down") ; break ; case GSL_IEEE_ROUND_UP: PRINTC("round-up") ; break ; case GSL_IEEE_ROUND_TO_ZERO: PRINTC("round-to-zero") ; break ; } if ((exception_mask & GSL_IEEE_MASK_ALL) == GSL_IEEE_MASK_ALL) { PRINTC("mask-all") ; } else if ((exception_mask & GSL_IEEE_MASK_ALL) == 0) { PRINTC("trap-common") ; } else { if (exception_mask & GSL_IEEE_MASK_INVALID) PRINTC("mask-invalid") ; if (exception_mask & GSL_IEEE_MASK_DENORMALIZED) PRINTC("mask-denormalized") ; if (exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO) PRINTC("mask-division-by-zero") ; if (exception_mask & GSL_IEEE_MASK_OVERFLOW) PRINTC("mask-overflow") ; if (exception_mask & GSL_IEEE_MASK_UNDERFLOW) PRINTC("mask-underflow") ; } if (exception_mask & GSL_IEEE_TRAP_INEXACT) PRINTC("trap-inexact") ; fprintf(stderr,"\"\n") ; } praat-6.0.04/external/gsl/gsl_ieee-utils__fp-aix.c000066400000000000000000000062431261542461700220150ustar00rootroot00000000000000/* ieee-utils/fp-aix.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Tim Mooney * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include "gsl_ieee_utils.h" #include "gsl_errno.h" int gsl_ieee_set_mode (int precision, int rounding, int exception_mask) { fptrap_t mode = 0 ; fprnd_t rnd = 0 ; switch (precision) { /* I'm not positive about AIX only supporting default precision rounding, * but this is the best assumption until it's proven otherwise. */ case GSL_IEEE_SINGLE_PRECISION: GSL_ERROR ("AIX only supports default precision rounding", GSL_EUNSUP) ; break ; case GSL_IEEE_DOUBLE_PRECISION: GSL_ERROR ("AIX only supports default precision rounding", GSL_EUNSUP) ; break ; case GSL_IEEE_EXTENDED_PRECISION: GSL_ERROR ("AIX only supports default precision rounding", GSL_EUNSUP) ; break ; } switch (rounding) { case GSL_IEEE_ROUND_TO_NEAREST: rnd = FP_RND_RN ; fp_swap_rnd (rnd) ; break ; case GSL_IEEE_ROUND_DOWN: rnd = FP_RND_RM ; fp_swap_rnd (rnd) ; break ; case GSL_IEEE_ROUND_UP: rnd = FP_RND_RP ; fp_swap_rnd (rnd) ; break ; case GSL_IEEE_ROUND_TO_ZERO: rnd = FP_RND_RZ ; fp_swap_rnd (rnd) ; break ; default: rnd = FP_RND_RN ; fp_swap_rnd (rnd) ; } /* Turn on all the exceptions apart from 'inexact' */ mode = TRP_INVALID | TRP_DIV_BY_ZERO | TRP_OVERFLOW | TRP_UNDERFLOW ; if (exception_mask & GSL_IEEE_MASK_INVALID) mode &= ~ TRP_INVALID ; if (exception_mask & GSL_IEEE_MASK_DENORMALIZED) { /* do nothing */ } else { GSL_ERROR ("AIX does not support the denormalized operand exception. " "Use 'mask-denormalized' to work around this.", GSL_EUNSUP) ; } if (exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO) mode &= ~ TRP_DIV_BY_ZERO ; if (exception_mask & GSL_IEEE_MASK_OVERFLOW) mode &= ~ TRP_OVERFLOW ; if (exception_mask & GSL_IEEE_MASK_UNDERFLOW) mode &= ~ TRP_UNDERFLOW ; if (exception_mask & GSL_IEEE_TRAP_INEXACT) { mode |= TRP_INEXACT ; } else { mode &= ~ TRP_INEXACT ; } /* AIX appears to require two steps -- first enable floating point traps * in general... */ fp_trap(FP_TRAP_SYNC); /* next, enable the traps we're interested in */ fp_enable(mode); return GSL_SUCCESS ; } praat-6.0.04/external/gsl/gsl_ieee-utils__fp-darwin.c000066400000000000000000000055421261542461700225210ustar00rootroot00000000000000/* ieee-utils/fp-darwin.c * * Copyright (C) 2001 Rodney Sparapani * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "gsl_ieee_utils.h" #include "gsl_errno.h" int gsl_ieee_set_mode (int precision, int rounding, int exception_mask) { ppc_fp_scr_t fp_scr = get_fp_scr() ; switch (precision) { case GSL_IEEE_SINGLE_PRECISION: GSL_ERROR ("powerpc only supports default precision rounding", GSL_EUNSUP); break ; case GSL_IEEE_DOUBLE_PRECISION: GSL_ERROR ("powerpc only supports default precision rounding", GSL_EUNSUP); break ; case GSL_IEEE_EXTENDED_PRECISION: GSL_ERROR ("powerpc only supports default precision rounding", GSL_EUNSUP); break ; } switch (rounding) { case GSL_IEEE_ROUND_TO_NEAREST: fp_scr.rn = RN_NEAREST ; break ; case GSL_IEEE_ROUND_DOWN: fp_scr.rn = RN_TOWARD_MINUS ; break ; case GSL_IEEE_ROUND_UP: fp_scr.rn = RN_TOWARD_PLUS ; break ; case GSL_IEEE_ROUND_TO_ZERO: fp_scr.rn = RN_TOWARD_ZERO ; break ; default: fp_scr.rn = RN_NEAREST ; } if (exception_mask & GSL_IEEE_MASK_INVALID) fp_scr.ve = 0 ; //ve bit: invalid op exception enable if (exception_mask & GSL_IEEE_MASK_DENORMALIZED) { /* do nothing */ } else { GSL_ERROR ("powerpc does not support the denormalized operand exception. " "Use 'mask-denormalized' to work around this.", GSL_EUNSUP) ; } if (exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO) fp_scr.ze = 0 ; //ze bit: zero divide exception enable if (exception_mask & GSL_IEEE_MASK_OVERFLOW) fp_scr.oe = 0 ; //oe bit: overflow exception enable if (exception_mask & GSL_IEEE_MASK_UNDERFLOW) fp_scr.ue = 0 ; //ue bit: underflow exception enable if (exception_mask & GSL_IEEE_TRAP_INEXACT) { fp_scr.xe = 1 ; //xe bit: inexact exception enable } else { fp_scr.xe = 01 ; } set_fp_scr(fp_scr); return GSL_SUCCESS ; } praat-6.0.04/external/gsl/gsl_ieee-utils__fp-darwin86.c000066400000000000000000000123721261542461700226760ustar00rootroot00000000000000/* ieee-utils/fp-darwin86.c * * Copyright (C) 2006 Erik Schnetter * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_ieee_utils.h" #include "gsl_errno.h" /* Here is the dirty part. Set up your 387 through the control word * (cw) register. * * 15-13 12 11-10 9-8 7-6 5 4 3 2 1 0 * | reserved | IC | RC | PC | reserved | PM | UM | OM | ZM | DM | IM * * IM: Invalid operation mask * DM: Denormalized operand mask * ZM: Zero-divide mask * OM: Overflow mask * UM: Underflow mask * PM: Precision (inexact result) mask * * Mask bit is 1 means no interrupt. * * PC: Precision control * 11 - round to extended precision * 10 - round to double precision * 00 - round to single precision * * RC: Rounding control * 00 - rounding to nearest * 01 - rounding down (toward - infinity) * 10 - rounding up (toward + infinity) * 11 - rounding toward zero * * IC: Infinity control * That is for 8087 and 80287 only. * * The hardware default is 0x037f which we use. */ /* masking of interrupts */ #define _FPU_MASK_IM 0x01 #define _FPU_MASK_DM 0x02 #define _FPU_MASK_ZM 0x04 #define _FPU_MASK_OM 0x08 #define _FPU_MASK_UM 0x10 #define _FPU_MASK_PM 0x20 /* precision control */ #define _FPU_EXTENDED 0x300 /* libm requires double extended precision. */ #define _FPU_DOUBLE 0x200 #define _FPU_SINGLE 0x0 /* rounding control */ #define _FPU_RC_NEAREST 0x0 /* RECOMMENDED */ #define _FPU_RC_DOWN 0x400 #define _FPU_RC_UP 0x800 #define _FPU_RC_ZERO 0xC00 #define _FPU_RESERVED 0xF0C0 /* Reserved bits in cw */ /* The fdlibm code requires strict IEEE double precision arithmetic, and no interrupts for exceptions, rounding to nearest. */ #define _FPU_DEFAULT 0x037f /* IEEE: same as above. */ #define _FPU_IEEE 0x037f /* Type of the control word. */ typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__HI__))); /* Macros for accessing the hardware control word. Note that the use of these macros is no sufficient anymore with recent hardware. Some floating point operations are executed in the SSE/SSE2 engines which have their own control and status register. */ #define _FPU_GETCW(cw) __asm__ __volatile__ ("fnstcw %0" : "=m" (*&cw)) #define _FPU_SETCW(cw) __asm__ __volatile__ ("fldcw %0" : : "m" (*&cw)) /* Default control word set at startup. */ extern fpu_control_t __fpu_control; #define _FPU_GETMXCSR(cw_sse) asm volatile ("stmxcsr %0" : "=m" (cw_sse)) #define _FPU_SETMXCSR(cw_sse) asm volatile ("ldmxcsr %0" : : "m" (cw_sse)) int gsl_ieee_set_mode (int precision, int rounding, int exception_mask) { fpu_control_t mode, mode_sse; _FPU_GETCW (mode) ; mode &= _FPU_RESERVED ; switch (precision) { case GSL_IEEE_SINGLE_PRECISION: mode |= _FPU_SINGLE ; break ; case GSL_IEEE_DOUBLE_PRECISION: mode |= _FPU_DOUBLE ; break ; case GSL_IEEE_EXTENDED_PRECISION: mode |= _FPU_EXTENDED ; break ; default: mode |= _FPU_EXTENDED ; } switch (rounding) { case GSL_IEEE_ROUND_TO_NEAREST: mode |= _FPU_RC_NEAREST ; break ; case GSL_IEEE_ROUND_DOWN: mode |= _FPU_RC_DOWN ; break ; case GSL_IEEE_ROUND_UP: mode |= _FPU_RC_UP ; break ; case GSL_IEEE_ROUND_TO_ZERO: mode |= _FPU_RC_ZERO ; break ; default: mode |= _FPU_RC_NEAREST ; } if (exception_mask & GSL_IEEE_MASK_INVALID) mode |= _FPU_MASK_IM ; if (exception_mask & GSL_IEEE_MASK_DENORMALIZED) mode |= _FPU_MASK_DM ; if (exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO) mode |= _FPU_MASK_ZM ; if (exception_mask & GSL_IEEE_MASK_OVERFLOW) mode |= _FPU_MASK_OM ; if (exception_mask & GSL_IEEE_MASK_UNDERFLOW) mode |= _FPU_MASK_UM ; if (exception_mask & GSL_IEEE_TRAP_INEXACT) { mode &= ~ _FPU_MASK_PM ; } else { mode |= _FPU_MASK_PM ; } _FPU_SETCW (mode) ; _FPU_GETMXCSR (mode_sse) ; mode_sse &= 0xFFFF0000 ; if (exception_mask & GSL_IEEE_MASK_INVALID) mode_sse |= _FPU_MASK_IM << 7 ; if (exception_mask & GSL_IEEE_MASK_DENORMALIZED) mode_sse |= _FPU_MASK_DM << 7 ; if (exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO) mode_sse |= _FPU_MASK_ZM << 7 ; if (exception_mask & GSL_IEEE_MASK_OVERFLOW) mode_sse |= _FPU_MASK_OM << 7 ; if (exception_mask & GSL_IEEE_MASK_UNDERFLOW) mode_sse |= _FPU_MASK_UM << 7 ; if (exception_mask & GSL_IEEE_TRAP_INEXACT) { mode_sse &= ~ _FPU_MASK_PM << 7 ; } else { mode_sse |= _FPU_MASK_PM << 7 ; } _FPU_SETMXCSR (mode_sse) ; return GSL_SUCCESS ; } praat-6.0.04/external/gsl/gsl_ieee-utils__fp-freebsd.c000066400000000000000000000046501261542461700226460ustar00rootroot00000000000000/* ieee-utils/fp-freebsd.c * * Copyright (C) 2000 Vladimir Kushnir * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "gsl_ieee_utils.h" #include "gsl_errno.h" int gsl_ieee_set_mode (int precision, int rounding, int exception_mask) { fp_prec_t prec = 0 ; fp_except_t mode = 0 ; fp_rnd_t rnd = 0 ; switch (precision) { case GSL_IEEE_SINGLE_PRECISION: prec = FP_PS; fpsetprec(prec); break ; case GSL_IEEE_DOUBLE_PRECISION: prec = FP_PD; fpsetprec(prec); break ; case GSL_IEEE_EXTENDED_PRECISION: prec = FP_PE; fpsetprec(prec); break ; } switch (rounding) { case GSL_IEEE_ROUND_TO_NEAREST: rnd = FP_RN ; fpsetround (rnd) ; break ; case GSL_IEEE_ROUND_DOWN: rnd = FP_RM ; fpsetround (rnd) ; break ; case GSL_IEEE_ROUND_UP: rnd = FP_RP ; fpsetround (rnd) ; break ; case GSL_IEEE_ROUND_TO_ZERO: rnd = FP_RZ ; fpsetround (rnd) ; break ; default: rnd = FP_RN ; fpsetround (rnd) ; } /* Turn on all the exceptions apart from 'inexact' */ mode = FP_X_INV | FP_X_DNML | FP_X_DZ | FP_X_OFL | FP_X_UFL ; if (exception_mask & GSL_IEEE_MASK_INVALID) mode &= ~ FP_X_INV ; if (exception_mask & GSL_IEEE_MASK_DENORMALIZED) mode &= ~ FP_X_DNML ; if (exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO) mode &= ~ FP_X_DZ ; if (exception_mask & GSL_IEEE_MASK_OVERFLOW) mode &= ~ FP_X_OFL ; if (exception_mask & GSL_IEEE_MASK_UNDERFLOW) mode &= ~ FP_X_UFL ; if (exception_mask & GSL_IEEE_TRAP_INEXACT) { mode |= FP_X_IMP ; } else { mode &= ~ FP_X_IMP ; } fpsetmask (mode) ; return GSL_SUCCESS ; } praat-6.0.04/external/gsl/gsl_ieee-utils__fp-gnuc99.c000066400000000000000000000104501261542461700223450ustar00rootroot00000000000000/* ieee-utils/fp-gnuc99.c * * Copyright (C) 2003, 2004, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define _GNU_SOURCE 1 #include #include #include #include "gsl_ieee_utils.h" #include "gsl_errno.h" int gsl_ieee_set_mode (int precision, int rounding, int exception_mask) { int mode; switch (precision) { case GSL_IEEE_SINGLE_PRECISION: GSL_ERROR ("single precision rounding is not supported by ", GSL_EUNSUP) ; break ; case GSL_IEEE_DOUBLE_PRECISION: GSL_ERROR ("double precision rounding is not supported by ", GSL_EUNSUP) ; break ; case GSL_IEEE_EXTENDED_PRECISION: GSL_ERROR ("extended precision rounding is not supported by ", GSL_EUNSUP) ; break ; } switch (rounding) { case GSL_IEEE_ROUND_TO_NEAREST: #ifdef FE_TONEAREST fesetround (FE_TONEAREST) ; #else GSL_ERROR ("round-to-nearest is not supported by ", GSL_EUNSUP) ; #endif break ; case GSL_IEEE_ROUND_DOWN: #ifdef FE_DOWNWARD fesetround (FE_DOWNWARD) ; #else GSL_ERROR ("round-down is not supported by ", GSL_EUNSUP) ; #endif break ; case GSL_IEEE_ROUND_UP: #ifdef FE_UPWARD fesetround (FE_UPWARD) ; #else GSL_ERROR ("round-up is not supported by ", GSL_EUNSUP) ; #endif break ; case GSL_IEEE_ROUND_TO_ZERO: #ifdef FE_TOWARDZERO fesetround (FE_TOWARDZERO) ; #else GSL_ERROR ("round-toward-zero is not supported by ", GSL_EUNSUP) ; #endif break ; default: #ifdef FE_TONEAREST fesetround (FE_TONEAREST) ; #else GSL_ERROR ("default round-to-nearest mode is not supported by ", GSL_EUNSUP) ; #endif } /* Turn on all the exceptions apart from 'inexact' */ mode = 0; #ifdef FE_INVALID mode |= FE_INVALID; #endif #ifdef FE_DIVBYZERO mode |= FE_DIVBYZERO; #endif #ifdef FE_OVERFLOW mode |= FE_OVERFLOW ; #endif #ifdef FE_UNDERFLOW mode |= FE_UNDERFLOW ; #endif if (exception_mask & GSL_IEEE_MASK_INVALID) { #ifdef FE_INVALID mode &= ~ FE_INVALID ; #else GSL_ERROR ("invalid operation exception not supported by ", GSL_EUNSUP); #endif } if (exception_mask & GSL_IEEE_MASK_DENORMALIZED) { /* do nothing */ } else { GSL_ERROR ("denormalized operand exception not supported by . " "Use 'mask-denormalized' to work around this.", GSL_EUNSUP) ; } if (exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO) { #ifdef FE_DIVBYZERO mode &= ~ FE_DIVBYZERO ; #else GSL_ERROR ("division by zero exception not supported by ", GSL_EUNSUP); #endif } if (exception_mask & GSL_IEEE_MASK_OVERFLOW) { #ifdef FE_OVERFLOW mode &= ~ FE_OVERFLOW ; #else GSL_ERROR ("overflow exception not supported by ", GSL_EUNSUP); #endif } if (exception_mask & GSL_IEEE_MASK_UNDERFLOW) { #ifdef FE_UNDERFLOW mode &= ~ FE_UNDERFLOW ; #else GSL_ERROR ("underflow exception not supported by ", GSL_EUNSUP); #endif } if (exception_mask & GSL_IEEE_TRAP_INEXACT) { #ifdef FE_INEXACT mode |= FE_INEXACT ; #else GSL_ERROR ("inexact exception not supported by ", GSL_EUNSUP); #endif } else { #ifdef FE_INEXACT mode &= ~ FE_INEXACT ; #else /* do nothing */ #endif } #if HAVE_DECL_FEENABLEEXCEPT feenableexcept (mode) ; #elif HAVE_DECL_FESETTRAPENABLE fesettrapenable (mode); #else GSL_ERROR ("unknown exception trap method", GSL_EUNSUP) #endif return GSL_SUCCESS ; } praat-6.0.04/external/gsl/gsl_ieee-utils__fp-gnum68k.c000066400000000000000000000052631261542461700225340ustar00rootroot00000000000000/* ieee-utils/fp-gnum68k.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "gsl_errno.h" #include "gsl_ieee_utils.h" int gsl_ieee_set_mode (int precision, int rounding, int exception_mask) { unsigned short mode = 0 ; switch (precision) { case GSL_IEEE_SINGLE_PRECISION: mode |= _FPU_SINGLE ; break ; case GSL_IEEE_DOUBLE_PRECISION: mode |= _FPU_DOUBLE ; break ; case GSL_IEEE_EXTENDED_PRECISION: mode |= _FPU_EXTENDED ; break ; default: mode |= _FPU_EXTENDED ; } switch (rounding) { case GSL_IEEE_ROUND_TO_NEAREST: mode |= _FPU_RC_NEAREST ; break ; case GSL_IEEE_ROUND_DOWN: mode |= _FPU_RC_DOWN ; break ; case GSL_IEEE_ROUND_UP: mode |= _FPU_RC_UP ; break ; case GSL_IEEE_ROUND_TO_ZERO: mode |= _FPU_RC_ZERO ; break ; default: mode |= _FPU_RC_NEAREST ; } /* FIXME: I don't have documentation for the M68K so I'm not sure about the mapping of the exceptions below. Maybe someone who does know could correct this. */ if (exception_mask & GSL_IEEE_MASK_INVALID) mode |= _FPU_MASK_OPERR ; if (exception_mask & GSL_IEEE_MASK_DENORMALIZED) { /* do nothing */ } else { GSL_ERROR ("the denormalized operand exception has not been implemented for m68k yet. Use 'mask-denormalized' to work around this.", GSL_EUNSUP) ; /*mode |= _FPU_MASK_DM ; ???? */ } if (exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO) mode |= _FPU_MASK_DZ ; if (exception_mask & GSL_IEEE_MASK_OVERFLOW) mode |= _FPU_MASK_OVFL ; if (exception_mask & GSL_IEEE_MASK_UNDERFLOW) mode |= _FPU_MASK_UNFL ; if (exception_mask & GSL_IEEE_TRAP_INEXACT) { mode &= ~ (_FPU_MASK_INEX1 | _FPU_MASK_INEX2) ; } else { mode |= (_FPU_MASK_INEX1 | _FPU_MASK_INEX2) ; } _FPU_SETCW(mode) ; return GSL_SUCCESS ; } praat-6.0.04/external/gsl/gsl_ieee-utils__fp-gnuppc.c000066400000000000000000000053261261542461700225310ustar00rootroot00000000000000/* ieee-utils/fp-gnuppc.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough, John Fisher * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "gsl_errno.h" #include "gsl_ieee_utils.h" /* * Identical to fp-gnux86.c, except with references to * _FPU_SINGLE, _FPU_DOUBLE, _FPU_EXTENDED, _FPU_MASK_DM * and _FPU_MASK_PM converted to errors. */ int gsl_ieee_set_mode (int precision, int rounding, int exception_mask) { unsigned short mode = 0 ; switch (precision) { case GSL_IEEE_SINGLE_PRECISION: GSL_ERROR ("powerpc only supports default precision rounding", GSL_EUNSUP); break ; case GSL_IEEE_DOUBLE_PRECISION: GSL_ERROR ("powerpc only supports default precision rounding", GSL_EUNSUP); break ; case GSL_IEEE_EXTENDED_PRECISION: GSL_ERROR ("powerpc only supports default precision rounding", GSL_EUNSUP); break ; } switch (rounding) { case GSL_IEEE_ROUND_TO_NEAREST: mode |= _FPU_RC_NEAREST ; break ; case GSL_IEEE_ROUND_DOWN: mode |= _FPU_RC_DOWN ; break ; case GSL_IEEE_ROUND_UP: mode |= _FPU_RC_UP ; break ; case GSL_IEEE_ROUND_TO_ZERO: mode |= _FPU_RC_ZERO ; break ; default: mode |= _FPU_RC_NEAREST ; } if (exception_mask & GSL_IEEE_MASK_INVALID) mode |= _FPU_MASK_IM ; if (exception_mask & GSL_IEEE_MASK_DENORMALIZED) { /* do nothing */ } else { GSL_ERROR ("powerpc does not support the denormalized operand exception. " "Use 'mask-denormalized' to work around this.", GSL_EUNSUP) ; } if (exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO) mode |= _FPU_MASK_ZM ; if (exception_mask & GSL_IEEE_MASK_OVERFLOW) mode |= _FPU_MASK_OM ; if (exception_mask & GSL_IEEE_MASK_UNDERFLOW) mode |= _FPU_MASK_UM ; if (exception_mask & GSL_IEEE_TRAP_INEXACT) { GSL_ERROR ("powerpc does not support traps for inexact operations", GSL_EUNSUP) ; } _FPU_SETCW(mode) ; return GSL_SUCCESS ; } praat-6.0.04/external/gsl/gsl_ieee-utils__fp-gnusparc.c000066400000000000000000000046521261542461700230600ustar00rootroot00000000000000/* ieee-utils/fp-gnusparc.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "gsl_errno.h" #include "gsl_ieee_utils.h" int gsl_ieee_set_mode (int precision, int rounding, int exception_mask) { unsigned short mode = 0 ; switch (precision) { case GSL_IEEE_SINGLE_PRECISION: mode |= _FPU_SINGLE ; break ; case GSL_IEEE_DOUBLE_PRECISION: mode |= _FPU_DOUBLE ; break ; case GSL_IEEE_EXTENDED_PRECISION: mode |= _FPU_EXTENDED ; break ; default: mode |= _FPU_EXTENDED ; } switch (rounding) { case GSL_IEEE_ROUND_TO_NEAREST: mode |= _FPU_RC_NEAREST ; break ; case GSL_IEEE_ROUND_DOWN: mode |= _FPU_RC_DOWN ; break ; case GSL_IEEE_ROUND_UP: mode |= _FPU_RC_UP ; break ; case GSL_IEEE_ROUND_TO_ZERO: mode |= _FPU_RC_ZERO ; break ; default: mode |= _FPU_RC_NEAREST ; } if (exception_mask & GSL_IEEE_MASK_INVALID) mode |= _FPU_MASK_IM ; if (exception_mask & GSL_IEEE_MASK_DENORMALIZED) { /* do nothing */ } else { GSL_ERROR ("sparc does not support the denormalized operand exception. " "Use 'mask-denormalized' to work around this.", GSL_EUNSUP) ; } if (exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO) mode |= _FPU_MASK_ZM ; if (exception_mask & GSL_IEEE_MASK_OVERFLOW) mode |= _FPU_MASK_OM ; if (exception_mask & GSL_IEEE_MASK_UNDERFLOW) mode |= _FPU_MASK_UM ; if (exception_mask & GSL_IEEE_TRAP_INEXACT) { mode &= ~ _FPU_MASK_PM ; } else { mode |= _FPU_MASK_PM ; } _FPU_SETCW(mode) ; return GSL_SUCCESS ; } praat-6.0.04/external/gsl/gsl_ieee-utils__fp-gnux86.c000066400000000000000000000054461261542461700223770ustar00rootroot00000000000000/* ieee-utils/fp-gnux86.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "gsl_errno.h" #include "gsl_ieee_utils.h" /* Handle libc5, where _FPU_SETCW is not available, suggested by OKUJI Yoshinori and Evgeny Stambulchik */ #ifndef _FPU_SETCW #include #define _FPU_SETCW(cw) __setfpucw(cw) #endif int gsl_ieee_set_mode (int precision, int rounding, int exception_mask) { unsigned short mode = 0 ; switch (precision) { case GSL_IEEE_SINGLE_PRECISION: mode |= _FPU_SINGLE ; break ; case GSL_IEEE_DOUBLE_PRECISION: mode |= _FPU_DOUBLE ; break ; case GSL_IEEE_EXTENDED_PRECISION: mode |= _FPU_EXTENDED ; break ; default: mode |= _FPU_EXTENDED ; } switch (rounding) { case GSL_IEEE_ROUND_TO_NEAREST: mode |= _FPU_RC_NEAREST ; break ; case GSL_IEEE_ROUND_DOWN: mode |= _FPU_RC_DOWN ; break ; case GSL_IEEE_ROUND_UP: mode |= _FPU_RC_UP ; break ; case GSL_IEEE_ROUND_TO_ZERO: mode |= _FPU_RC_ZERO ; break ; default: mode |= _FPU_RC_NEAREST ; } if (exception_mask & GSL_IEEE_MASK_INVALID) mode |= _FPU_MASK_IM ; if (exception_mask & GSL_IEEE_MASK_DENORMALIZED) mode |= _FPU_MASK_DM ; if (exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO) mode |= _FPU_MASK_ZM ; if (exception_mask & GSL_IEEE_MASK_OVERFLOW) mode |= _FPU_MASK_OM ; if (exception_mask & GSL_IEEE_MASK_UNDERFLOW) mode |= _FPU_MASK_UM ; if (exception_mask & GSL_IEEE_TRAP_INEXACT) { mode &= ~ _FPU_MASK_PM ; } else { mode |= _FPU_MASK_PM ; } _FPU_SETCW(mode) ; #if HAVE_FPU_X86_SSE #define _FPU_SETMXCSR(cw_sse) asm volatile ("ldmxcsr %0" : : "m" (*&cw_sse)) { unsigned int mode_sse = 0; mode_sse |= (mode & 0x3f)<<7; /* exception masks */ mode_sse |= (mode & 0xc00)<<3; /* rounding control */ _FPU_SETMXCSR(mode_sse); } #endif return GSL_SUCCESS ; } praat-6.0.04/external/gsl/gsl_ieee-utils__fp-hpux.c000066400000000000000000000054471261542461700222250ustar00rootroot00000000000000/* ieee-utils/fp-hpux.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "gsl_ieee_utils.h" #include "gsl_errno.h" int gsl_ieee_set_mode (int precision, int rounding, int exception_mask) { fp_except mode = 0 ; fp_rnd rnd = 0 ; switch (precision) { case GSL_IEEE_SINGLE_PRECISION: GSL_ERROR ("HPUX PA-RISC only supports default precision rounding", GSL_EUNSUP) ; break ; case GSL_IEEE_DOUBLE_PRECISION: GSL_ERROR ("HPUX PA-RISC only supports default precision rounding", GSL_EUNSUP) ; break ; case GSL_IEEE_EXTENDED_PRECISION: GSL_ERROR ("HPUX PA-RISC only supports default precision rounding", GSL_EUNSUP) ; break ; } switch (rounding) { case GSL_IEEE_ROUND_TO_NEAREST: rnd = FP_RN ; fpsetround (rnd) ; break ; case GSL_IEEE_ROUND_DOWN: rnd = FP_RM ; fpsetround (rnd) ; break ; case GSL_IEEE_ROUND_UP: rnd = FP_RP ; fpsetround (rnd) ; break ; case GSL_IEEE_ROUND_TO_ZERO: rnd = FP_RZ ; fpsetround (rnd) ; break ; default: rnd = FP_RN ; fpsetround (rnd) ; } /* Turn on all the exceptions apart from 'inexact' */ mode = FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_UFL ; if (exception_mask & GSL_IEEE_MASK_INVALID) mode &= ~ FP_X_INV ; if (exception_mask & GSL_IEEE_MASK_DENORMALIZED) { /* do nothing */ } else { GSL_ERROR ("HP-UX does not support the denormalized operand exception. " "Use 'mask-denormalized' to work around this.", GSL_EUNSUP) ; } if (exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO) mode &= ~ FP_X_DZ ; if (exception_mask & GSL_IEEE_MASK_OVERFLOW) mode &= ~ FP_X_OFL ; if (exception_mask & GSL_IEEE_MASK_UNDERFLOW) mode &= ~ FP_X_UFL ; if (exception_mask & GSL_IEEE_TRAP_INEXACT) { mode |= FP_X_IMP ; } else { mode &= ~ FP_X_IMP ; } fpsetmask (mode) ; return GSL_SUCCESS ; } praat-6.0.04/external/gsl/gsl_ieee-utils__fp-hpux11.c000066400000000000000000000053551261542461700223650ustar00rootroot00000000000000/* ieee-utils/fp-hpux11.c * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include "gsl_ieee_utils.h" #include "gsl_errno.h" int gsl_ieee_set_mode (int precision, int rounding, int exception_mask) { int mode; switch (precision) { case GSL_IEEE_SINGLE_PRECISION: GSL_ERROR ("HPUX PA-RISC only supports default precision rounding", GSL_EUNSUP) ; break ; case GSL_IEEE_DOUBLE_PRECISION: GSL_ERROR ("HPUX PA-RISC only supports default precision rounding", GSL_EUNSUP) ; break ; case GSL_IEEE_EXTENDED_PRECISION: GSL_ERROR ("HPUX PA-RISC only supports default precision rounding", GSL_EUNSUP) ; break ; } switch (rounding) { case GSL_IEEE_ROUND_TO_NEAREST: fesetround (FE_TONEAREST) ; break ; case GSL_IEEE_ROUND_DOWN: fesetround (FE_DOWNWARD) ; break ; case GSL_IEEE_ROUND_UP: fesetround (FE_UPWARD) ; break ; case GSL_IEEE_ROUND_TO_ZERO: fesetround (FE_TOWARDZERO) ; break ; default: fesetround (FE_TONEAREST) ; } /* Turn on all the exceptions apart from 'inexact' */ mode = FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW ; if (exception_mask & GSL_IEEE_MASK_INVALID) mode &= ~ FE_INVALID ; if (exception_mask & GSL_IEEE_MASK_DENORMALIZED) { /* do nothing */ } else { GSL_ERROR ("HP-UX does not support the denormalized operand exception. " "Use 'mask-denormalized' to work around this.", GSL_EUNSUP) ; } if (exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO) mode &= ~ FE_DIVBYZERO ; if (exception_mask & GSL_IEEE_MASK_OVERFLOW) mode &= ~ FE_OVERFLOW ; if (exception_mask & GSL_IEEE_MASK_UNDERFLOW) mode &= ~ FE_UNDERFLOW ; if (exception_mask & GSL_IEEE_TRAP_INEXACT) { mode |= FE_INEXACT ; } else { mode &= ~ FE_INEXACT ; } fesettrapenable (mode) ; return GSL_SUCCESS ; } praat-6.0.04/external/gsl/gsl_ieee-utils__fp-irix.c000066400000000000000000000054101261542461700222020ustar00rootroot00000000000000/* ieee-utils/fp-irix.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Tim Mooney * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "gsl_ieee_utils.h" #include "gsl_errno.h" int gsl_ieee_set_mode (int precision, int rounding, int exception_mask) { fp_except mode = 0 ; fp_rnd rnd = 0 ; switch (precision) { case GSL_IEEE_SINGLE_PRECISION: GSL_ERROR ("IRIX only supports default precision rounding", GSL_EUNSUP) ; break ; case GSL_IEEE_DOUBLE_PRECISION: GSL_ERROR ("IRIX only supports default precision rounding", GSL_EUNSUP) ; break ; case GSL_IEEE_EXTENDED_PRECISION: GSL_ERROR ("IRIX only supports default precision rounding", GSL_EUNSUP) ; break ; } switch (rounding) { case GSL_IEEE_ROUND_TO_NEAREST: rnd = FP_RN ; fpsetround (rnd) ; break ; case GSL_IEEE_ROUND_DOWN: rnd = FP_RM ; fpsetround (rnd) ; break ; case GSL_IEEE_ROUND_UP: rnd = FP_RP ; fpsetround (rnd) ; break ; case GSL_IEEE_ROUND_TO_ZERO: rnd = FP_RZ ; fpsetround (rnd) ; break ; default: rnd = FP_RN ; fpsetround (rnd) ; } /* Turn on all the exceptions apart from 'inexact' */ mode = FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_UFL ; if (exception_mask & GSL_IEEE_MASK_INVALID) mode &= ~ FP_X_INV ; if (exception_mask & GSL_IEEE_MASK_DENORMALIZED) { /* do nothing */ } else { GSL_ERROR ("IRIX does not support the denormalized operand exception. " "Use 'mask-denormalized' to work around this.", GSL_EUNSUP) ; } if (exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO) mode &= ~ FP_X_DZ ; if (exception_mask & GSL_IEEE_MASK_OVERFLOW) mode &= ~ FP_X_OFL ; if (exception_mask & GSL_IEEE_MASK_UNDERFLOW) mode &= ~ FP_X_UFL ; if (exception_mask & GSL_IEEE_TRAP_INEXACT) { mode |= FP_X_IMP ; } else { mode &= ~ FP_X_IMP ; } fpsetmask (mode) ; return GSL_SUCCESS ; } praat-6.0.04/external/gsl/gsl_ieee-utils__fp-netbsd.c000066400000000000000000000056001261542461700225070ustar00rootroot00000000000000/* fp-netbsd.c * * Copyright (C) 2001 Jason Beegan * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "gsl_ieee_utils.h" #include "gsl_errno.h" int gsl_ieee_set_mode (int precision, int rounding, int exception_mask) { fp_except mode = 0; fp_rnd rnd = 0; switch (precision) { case GSL_IEEE_SINGLE_PRECISION: GSL_ERROR ("NetBSD only supports default precision rounding", GSL_EUNSUP); break; case GSL_IEEE_DOUBLE_PRECISION: GSL_ERROR ("NetBSD only supports default precision rounding", GSL_EUNSUP); break; case GSL_IEEE_EXTENDED_PRECISION: GSL_ERROR ("NetBSD only supports default precision rounding", GSL_EUNSUP); break; } switch (rounding) { case GSL_IEEE_ROUND_TO_NEAREST: rnd = FP_RN; fpsetround (rnd); break; case GSL_IEEE_ROUND_DOWN: rnd = FP_RM; fpsetround (rnd); break; case GSL_IEEE_ROUND_UP: rnd = FP_RP; fpsetround (rnd); break; case GSL_IEEE_ROUND_TO_ZERO: rnd = FP_RZ; fpsetround (rnd); break; default: rnd = FP_RN; fpsetround (rnd); } /* Turn on all available exceptions apart from 'inexact'. Denormalized operand exception not available on all platforms. */ mode = FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_UFL; #ifdef FP_X_DNML mode = mode | FP_X_DNML; #endif if (exception_mask & GSL_IEEE_MASK_INVALID) mode &= ~ FP_X_INV; if (exception_mask & GSL_IEEE_MASK_DENORMALIZED) { #ifdef FP_X_DNML mode &= ~ FP_X_DNML; #endif } else { #ifndef FP_X_DNML GSL_ERROR ("NetBSD does not support the denormalized operand exception on this platform. " "Use 'mask-denormalized' to work around this.", GSL_EUNSUP); #endif } if (exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO) mode &= ~ FP_X_DZ; if (exception_mask & GSL_IEEE_MASK_OVERFLOW) mode &= ~ FP_X_OFL; if (exception_mask & GSL_IEEE_MASK_UNDERFLOW) mode &= ~ FP_X_UFL; if (exception_mask & GSL_IEEE_TRAP_INEXACT) { mode |= FP_X_IMP; } else { mode &= ~ FP_X_IMP; } fpsetmask (mode); return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_ieee-utils__fp-openbsd.c000066400000000000000000000057411261542461700226700ustar00rootroot00000000000000/* fp-openbsd.c * * Copyright (C) 2001 Jason Beegan * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "gsl_ieee_utils.h" #include "gsl_errno.h" /* This is a copy of fp-netbsd.c, modified for openbsd by Toby White --- Brian Gough */ int gsl_ieee_set_mode (int precision, int rounding, int exception_mask) { fp_except mode = 0; fp_rnd rnd = 0; switch (precision) { case GSL_IEEE_SINGLE_PRECISION: GSL_ERROR ("OpenBSD only supports default precision rounding", GSL_EUNSUP); break; case GSL_IEEE_DOUBLE_PRECISION: GSL_ERROR ("OpenBSD only supports default precision rounding", GSL_EUNSUP); break; case GSL_IEEE_EXTENDED_PRECISION: GSL_ERROR ("OpenBSD only supports default precision rounding", GSL_EUNSUP); break; } switch (rounding) { case GSL_IEEE_ROUND_TO_NEAREST: rnd = FP_RN; fpsetround (rnd); break; case GSL_IEEE_ROUND_DOWN: rnd = FP_RM; fpsetround (rnd); break; case GSL_IEEE_ROUND_UP: rnd = FP_RP; fpsetround (rnd); break; case GSL_IEEE_ROUND_TO_ZERO: rnd = FP_RZ; fpsetround (rnd); break; default: rnd = FP_RN; fpsetround (rnd); } /* Turn on all available exceptions apart from 'inexact'. Denormalized operand exception not available on all platforms. */ mode = FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_UFL; #ifdef FP_X_DNML mode = mode | FP_X_DNML; #endif if (exception_mask & GSL_IEEE_MASK_INVALID) mode &= ~ FP_X_INV; if (exception_mask & GSL_IEEE_MASK_DENORMALIZED) { #ifdef FP_X_DNML mode &= ~ FP_X_DNML; #endif } else { #ifndef FP_X_DNML GSL_ERROR ("OpenBSD does not support the denormalized operand exception on this platform. " "Use 'mask-denormalized' to work around this.", GSL_EUNSUP); #endif } if (exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO) mode &= ~ FP_X_DZ; if (exception_mask & GSL_IEEE_MASK_OVERFLOW) mode &= ~ FP_X_OFL; if (exception_mask & GSL_IEEE_MASK_UNDERFLOW) mode &= ~ FP_X_UFL; if (exception_mask & GSL_IEEE_TRAP_INEXACT) { mode |= FP_X_IMP; } else { mode &= ~ FP_X_IMP; } fpsetmask (mode); return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_ieee-utils__fp-os2emx.c000066400000000000000000000045171261542461700224530ustar00rootroot00000000000000/* ieee-utils/fp-os2.c * * Copyright (C) 2001 Henry Sobotka * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "gsl_ieee_utils.h" #include "gsl_errno.h" int gsl_ieee_set_mode (int precision, int rounding, int exception_mask) { unsigned mode = 0; switch (precision) { case GSL_IEEE_SINGLE_PRECISION: _control87(PC_24, MCW_PC); break ; case GSL_IEEE_DOUBLE_PRECISION: _control87(PC_53, MCW_PC); break ; case GSL_IEEE_EXTENDED_PRECISION: _control87(PC_64, MCW_PC); break ; } switch (rounding) { case GSL_IEEE_ROUND_TO_NEAREST: _control87(RC_NEAR, MCW_RC); break ; case GSL_IEEE_ROUND_DOWN: _control87(RC_DOWN, MCW_RC); break ; case GSL_IEEE_ROUND_UP: _control87(RC_UP, MCW_RC); break ; case GSL_IEEE_ROUND_TO_ZERO: _control87(RC_CHOP, MCW_RC); break ; default: _control87(RC_NEAR, MCW_RC); } /* Turn on all the exceptions apart from 'inexact' */ mode = EM_INVALID | EM_DENORMAL | EM_ZERODIVIDE | EM_OVERFLOW | EM_UNDERFLOW; if (exception_mask & GSL_IEEE_MASK_INVALID) mode &= ~ EM_INVALID; if (exception_mask & GSL_IEEE_MASK_DENORMALIZED) mode &= ~ EM_DENORMAL; if (exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO) mode &= ~ EM_ZERODIVIDE; if (exception_mask & GSL_IEEE_MASK_OVERFLOW) mode &= ~ EM_OVERFLOW; if (exception_mask & GSL_IEEE_MASK_UNDERFLOW) mode &= ~ EM_UNDERFLOW; if (exception_mask & GSL_IEEE_TRAP_INEXACT) { mode |= EM_INEXACT; } else { mode &= ~ EM_INEXACT; } _control87(mode, MCW_EM); return GSL_SUCCESS ; } praat-6.0.04/external/gsl/gsl_ieee-utils__fp-solaris.c000066400000000000000000000054361261542461700227130ustar00rootroot00000000000000/* ieee-utils/fp-solaris.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "gsl_ieee_utils.h" #include "gsl_errno.h" int gsl_ieee_set_mode (int precision, int rounding, int exception_mask) { fp_except mode = 0 ; fp_rnd rnd = 0 ; switch (precision) { case GSL_IEEE_SINGLE_PRECISION: GSL_ERROR ("solaris only supports default precision rounding", GSL_EUNSUP) ; break ; case GSL_IEEE_DOUBLE_PRECISION: GSL_ERROR ("solaris only supports default precision rounding", GSL_EUNSUP) ; break ; case GSL_IEEE_EXTENDED_PRECISION: GSL_ERROR ("solaris only supports default precision rounding", GSL_EUNSUP) ; break ; } switch (rounding) { case GSL_IEEE_ROUND_TO_NEAREST: rnd = FP_RN ; fpsetround (rnd) ; break ; case GSL_IEEE_ROUND_DOWN: rnd = FP_RM ; fpsetround (rnd) ; break ; case GSL_IEEE_ROUND_UP: rnd = FP_RP ; fpsetround (rnd) ; break ; case GSL_IEEE_ROUND_TO_ZERO: rnd = FP_RZ ; fpsetround (rnd) ; break ; default: rnd = FP_RN ; fpsetround (rnd) ; } /* Turn on all the exceptions apart from 'inexact' */ mode = FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_UFL ; if (exception_mask & GSL_IEEE_MASK_INVALID) mode &= ~ FP_X_INV ; if (exception_mask & GSL_IEEE_MASK_DENORMALIZED) { /* do nothing */ } else { GSL_ERROR ("solaris does not support the denormalized operand exception. " "Use 'mask-denormalized' to work around this.", GSL_EUNSUP) ; } if (exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO) mode &= ~ FP_X_DZ ; if (exception_mask & GSL_IEEE_MASK_OVERFLOW) mode &= ~ FP_X_OFL ; if (exception_mask & GSL_IEEE_MASK_UNDERFLOW) mode &= ~ FP_X_UFL ; if (exception_mask & GSL_IEEE_TRAP_INEXACT) { mode |= FP_X_IMP ; } else { mode &= ~ FP_X_IMP ; } fpsetmask (mode) ; return GSL_SUCCESS ; } praat-6.0.04/external/gsl/gsl_ieee-utils__fp-sunos4.c000066400000000000000000000063121261542461700224640ustar00rootroot00000000000000/* ieee-utils/fp-sunos4.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include "gsl_ieee_utils.h" #include "gsl_errno.h" int gsl_ieee_set_mode (int precision, int rounding, int exception_mask) { char * out ; switch (precision) { case GSL_IEEE_SINGLE_PRECISION: ieee_flags ("set", "precision", "single", out) ; break ; case GSL_IEEE_DOUBLE_PRECISION: ieee_flags ("set", "precision", "double", out) ; break ; case GSL_IEEE_EXTENDED_PRECISION: ieee_flags ("set", "precision", "extended", out) ; break ; default: ieee_flags ("set", "precision", "extended", out) ; } switch (rounding) { case GSL_IEEE_ROUND_TO_NEAREST: ieee_flags ("set", "direction", "nearest", out) ; break ; case GSL_IEEE_ROUND_DOWN: ieee_flags ("set", "direction", "negative", out) ; break ; case GSL_IEEE_ROUND_UP: ieee_flags ("set", "direction", "positive", out) ; break ; case GSL_IEEE_ROUND_TO_ZERO: ieee_flags ("set", "direction", "tozero", out) ; break ; default: ieee_flags ("set", "direction", "nearest", out) ; } if (exception_mask & GSL_IEEE_MASK_INVALID) { ieee_handler ("set", "invalid", SIGFPE_IGNORE) ; } else { ieee_handler ("set", "invalid", SIGFPE_ABORT) ; } if (exception_mask & GSL_IEEE_MASK_DENORMALIZED) { ieee_handler ("set", "denormalized", SIGFPE_IGNORE) ; } else { GSL_ERROR ("sunos4 does not support the denormalized operand exception. " "Use 'mask-denormalized' to work around this.", GSL_EUNSUP) ; } if (exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO) { ieee_handler ("set", "division", SIGFPE_IGNORE) ; } else { ieee_handler ("set", "division", SIGFPE_ABORT) ; } if (exception_mask & GSL_IEEE_MASK_OVERFLOW) { ieee_handler ("set", "overflow", SIGFPE_IGNORE) ; } else { ieee_handler ("set", "overflow", SIGFPE_ABORT) ; } if (exception_mask & GSL_IEEE_MASK_UNDERFLOW) { ieee_handler ("set", "underflow", SIGFPE_IGNORE) ; } else { ieee_handler ("set", "underflow", SIGFPE_ABORT) ; } if (exception_mask & GSL_IEEE_TRAP_INEXACT) { ieee_handler ("set", "inexact", SIGFPE_ABORT) ; } else { ieee_handler ("set", "inexact", SIGFPE_IGNORE) ; } return GSL_SUCCESS ; } praat-6.0.04/external/gsl/gsl_ieee-utils__fp-tru64.c000066400000000000000000000131651261542461700222210ustar00rootroot00000000000000/* ieee-utils/fp-tru64.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Tim Mooney * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Under Compaq's Unix with the silly name, read the man pages for read_rnd, * write_rnd, and ieee(3) for more information on the functions used here. * * Note that enabling control of dynamic rounding mode (via write_rnd) requires * that you pass a special flag to your C compiler. For Compaq's C compiler * the flag is `-fprm d', for gcc it's `-mfp-rounding-mode=d'. * * Enabling the trap control (via ieee_set_fp_control) also requires a * flag be passed to the C compiler. The flag for Compaq's C compiler * is `-ieee' and for gcc it's `-mieee'. * We have not implemented the `inexact' case, since it is rarely used * and requires the library being built with an additional compiler * flag that can degrade performance for everything else. If you need * to add support for `inexact' the relevant flag for Compaq's * compiler is `-ieee_with_inexact', and the flag for gcc is * `-mieee-with-inexact'. * * Problem have been reported with the "fixed" float.h installed with * gcc-2.95 lacking some of the definitions in the system float.h (the * symptoms are errors like: `FP_RND_RN' undeclared). To work around * this we can include the system float.h before the gcc version, e.g. * * #include "/usr/include/float.h" * #include */ #include #ifndef FP_RND_RN # undef _FLOAT_H_ # include /usr/include/float.h # undef _FLOAT_H_ # include #endif #include #include #include "gsl_ieee_utils.h" #include "gsl_errno.h" int gsl_ieee_set_mode (int precision, int rounding, int exception_mask) { unsigned long int mode = 0 ; unsigned int rnd = 0 ; /* I'm actually not completely sure that the alpha only supports default * precisions rounding, but I couldn't find any information regarding this, so * it seems safe to assume this for now until it's proven otherwise. */ switch (precision) { case GSL_IEEE_SINGLE_PRECISION: GSL_ERROR ("Tru64 Unix on the alpha only supports default precision rounding", GSL_EUNSUP) ; break ; case GSL_IEEE_DOUBLE_PRECISION: GSL_ERROR ("Tru64 Unix on the alpha only supports default precision rounding", GSL_EUNSUP) ; break ; case GSL_IEEE_EXTENDED_PRECISION: GSL_ERROR ("Tru64 Unix on the alpha only supports default precision rounding", GSL_EUNSUP) ; break ; } switch (rounding) { case GSL_IEEE_ROUND_TO_NEAREST: rnd = FP_RND_RN ; write_rnd (rnd) ; break ; case GSL_IEEE_ROUND_DOWN: rnd = FP_RND_RM ; write_rnd (rnd) ; break ; case GSL_IEEE_ROUND_UP: rnd = FP_RND_RP ; write_rnd (rnd) ; break ; case GSL_IEEE_ROUND_TO_ZERO: rnd = FP_RND_RZ ; write_rnd (rnd) ; break ; default: rnd = FP_RND_RN ; write_rnd (rnd) ; } /* Turn on all the exceptions apart from 'inexact' */ /* from the ieee(3) man page: * IEEE_TRAP_ENABLE_INV -> Invalid operation * IEEE_TRAP_ENABLE_DZE -> Divide by 0 * IEEE_TRAP_ENABLE_OVF -> Overflow * IEEE_TRAP_ENABLE_UNF -> Underflow * IEEE_TRAP_ENABLE_INE -> Inexact (requires special option to C compiler) * IEEE_TRAP_ENABLE_DNO -> denormal operand * Note: IEEE_TRAP_ENABLE_DNO is not supported on OSF 3.x or Digital Unix * 4.0 - 4.0d(?). * IEEE_TRAP_ENABLE_MASK -> mask of all the trap enables * IEEE_MAP_DMZ -> map denormal inputs to zero * IEEE_MAP_UMZ -> map underflow results to zero */ mode = IEEE_TRAP_ENABLE_INV | IEEE_TRAP_ENABLE_DZE | IEEE_TRAP_ENABLE_OVF | IEEE_TRAP_ENABLE_UNF ; if (exception_mask & GSL_IEEE_MASK_INVALID) mode &= ~ IEEE_TRAP_ENABLE_INV ; if (exception_mask & GSL_IEEE_MASK_DENORMALIZED) { #ifdef IEEE_TRAP_ENABLE_DNO mode &= ~ IEEE_TRAP_ENABLE_DNO ; #else GSL_ERROR ("Sorry, this version of Digital Unix does not support denormalized operands", GSL_EUNSUP) ; #endif } if (exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO) mode &= ~ IEEE_TRAP_ENABLE_DZE ; if (exception_mask & GSL_IEEE_MASK_OVERFLOW) mode &= ~ IEEE_TRAP_ENABLE_OVF ; if (exception_mask & GSL_IEEE_MASK_UNDERFLOW) mode &= ~ IEEE_TRAP_ENABLE_UNF ; if (exception_mask & GSL_IEEE_TRAP_INEXACT) { /* To implement this would require a special flag to the C compiler which can cause degraded performance */ GSL_ERROR ("Sorry, GSL does not implement trap-inexact for Tru64 Unix on the alpha - see fp-tru64.c for details", GSL_EUNSUP) ; /* In case you need to add it, the appropriate line would be * * mode |= IEEE_TRAP_ENABLE_INE ; * */ } else { mode &= ~ IEEE_TRAP_ENABLE_INE ; } ieee_set_fp_control (mode) ; return GSL_SUCCESS ; } praat-6.0.04/external/gsl/gsl_ieee-utils__fp-unknown.c000066400000000000000000000021261261542461700227270ustar00rootroot00000000000000/* ieee-utils/fp-unknown.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_ieee_utils.h" #include "gsl_errno.h" int gsl_ieee_set_mode (int precision, int rounding, int exception_mask) { GSL_ERROR ( "the IEEE interface for this platform is unsupported or could not be " "determined at configure time\n", GSL_EUNSUP) ; } praat-6.0.04/external/gsl/gsl_ieee-utils__fp.c000066400000000000000000000031001261542461700212230ustar00rootroot00000000000000#include "gsl__config.h" #if HAVE_GNUSPARC_IEEE_INTERFACE #include "gsl_ieee-utils__fp-gnusparc.c" #elif HAVE_GNUM68K_IEEE_INTERFACE #include "gsl_ieee-utils__fp-gnum68k.c" #elif HAVE_GNUPPC_IEEE_INTERFACE #include "gsl_ieee-utils__fp-gnuppc.c" #elif HAVE_GNUX86_IEEE_INTERFACE #include "gsl_ieee-utils__fp-gnux86.c" #elif HAVE_HPUX11_IEEE_INTERFACE #include "gsl_ieee-utils__fp-hpux11.c" #elif HAVE_HPUX_IEEE_INTERFACE #include "gsl_ieee-utils__fp-hpux.c" #elif HAVE_SUNOS4_IEEE_INTERFACE #include "gsl_ieee-utils__fp-sunos4.c" #elif HAVE_SOLARIS_IEEE_INTERFACE #include "gsl_ieee-utils__fp-solaris.c" #elif HAVE_IRIX_IEEE_INTERFACE #include "gsl_ieee-utils__fp-irix.c" #elif HAVE_AIX_IEEE_INTERFACE #include "gsl_ieee-utils__fp-aix.c" #elif HAVE_TRU64_IEEE_INTERFACE #include "gsl_ieee-utils__fp-tru64.c" #elif HAVE_FREEBSD_IEEE_INTERFACE #include "gsl_ieee-utils__fp-freebsd.c" #elif HAVE_OS2EMX_IEEE_INTERFACE #include "gsl_ieee-utils__fp-os2emx.c" #elif HAVE_NETBSD_IEEE_INTERFACE #include "gsl_ieee-utils__fp-netbsd.c" #elif HAVE_OPENBSD_IEEE_INTERFACE #include "gsl_ieee-utils__fp-openbsd.c" /* Try to handle universal binaries */ #elif HAVE_DARWIN_IEEE_INTERFACE # if defined(__i386__) # include "gsl_ieee-utils__fp-darwin86.c" #else # include "gsl_ieee-utils__fp-darwin.c" # endif #elif HAVE_DARWIN86_IEEE_INTERFACE # if defined(__ppc__) # include "gsl_ieee-utils__fp-darwin.c" # else # include "gsl_ieee-utils__fp-darwin86.c" #endif #elif HAVE_DECL_FEENABLEEXCEPT || HAVE_DECL_FESETTRAPENABLE #include "gsl_ieee-utils__fp-gnuc99.c" #else #include "gsl_ieee-utils__fp-unknown.c" #endif praat-6.0.04/external/gsl/gsl_ieee-utils__make_rep.c000066400000000000000000000107101261542461700224060ustar00rootroot00000000000000/* ieee-utils/make_rep.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_ieee_utils.h" #include "gsl_ieee-utils__endian.c" #include "gsl_ieee-utils__standardize.c" static void sprint_nybble(int i, char *s) ; static void sprint_byte(int i, char *s) ; static int determine_ieee_type (int non_zero, int exponent, int max_exponent); /* For the IEEE float format the bits are found from the following masks, sign = 0x80000000 exponent = 0x7f800000 mantisssa = 0x007fffff For the IEEE double format the masks are, sign = 0x8000000000000000 exponent = 0x7ff0000000000000 mantissa = 0x000fffffffffffff */ void gsl_ieee_float_to_rep (const float * x, gsl_ieee_float_rep * r) { int e, non_zero; union { float f; struct { unsigned char byte[4] ; } ieee ; } u; u.f = *x ; if (little_endian_p()) make_float_bigendian(&(u.f)) ; /* note that r->sign is signed, u.ieee.byte is unsigned */ if (u.ieee.byte[3]>>7) { r->sign = 1 ; } else { r->sign = 0 ; } e = (u.ieee.byte[3] & 0x7f) << 1 | (u.ieee.byte[2] & 0x80)>>7 ; r->exponent = e - 127 ; sprint_byte((u.ieee.byte[2] & 0x7f) << 1,r->mantissa) ; sprint_byte(u.ieee.byte[1],r->mantissa + 7) ; sprint_byte(u.ieee.byte[0],r->mantissa + 15) ; r->mantissa[23] = '\0' ; non_zero = u.ieee.byte[0] || u.ieee.byte[1] || (u.ieee.byte[2] & 0x7f); r->type = determine_ieee_type (non_zero, e, 255) ; } void gsl_ieee_double_to_rep (const double * x, gsl_ieee_double_rep * r) { int e, non_zero; union { double d; struct { unsigned char byte[8]; } ieee ; } u; u.d= *x ; if (little_endian_p()) make_double_bigendian(&(u.d)) ; /* note that r->sign is signed, u.ieee.byte is unsigned */ if (u.ieee.byte[7]>>7) { r->sign = 1 ; } else { r->sign = 0 ; } e =(u.ieee.byte[7] & 0x7f)<<4 ^ (u.ieee.byte[6] & 0xf0)>>4 ; r->exponent = e - 1023 ; sprint_nybble(u.ieee.byte[6],r->mantissa) ; sprint_byte(u.ieee.byte[5],r->mantissa + 4) ; sprint_byte(u.ieee.byte[4],r->mantissa + 12) ; sprint_byte(u.ieee.byte[3],r->mantissa + 20) ; sprint_byte(u.ieee.byte[2],r->mantissa + 28) ; sprint_byte(u.ieee.byte[1],r->mantissa + 36) ; sprint_byte(u.ieee.byte[0],r->mantissa + 44) ; r->mantissa[52] = '\0' ; non_zero = (u.ieee.byte[0] || u.ieee.byte[1] || u.ieee.byte[2] || u.ieee.byte[3] || u.ieee.byte[4] || u.ieee.byte[5] || (u.ieee.byte[6] & 0x0f)) ; r->type = determine_ieee_type (non_zero, e, 2047) ; } /* A table of character representations of nybbles */ static char nybble[16][5]={ /* include space for the \0 */ "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" } ; static void sprint_nybble(int i, char *s) { char *c ; c=nybble[i & 0x0f ]; *s=c[0] ; *(s+1)=c[1] ; *(s+2)=c[2] ; *(s+3)=c[3] ; } static void sprint_byte(int i, char *s) { char *c ; c=nybble[(i & 0xf0)>>4]; *s=c[0] ; *(s+1)=c[1] ; *(s+2)=c[2] ; *(s+3)=c[3] ; c=nybble[i & 0x0f]; *(s+4)=c[0] ; *(s+5)=c[1] ; *(s+6)=c[2] ; *(s+7)=c[3] ; } static int determine_ieee_type (int non_zero, int exponent, int max_exponent) { if (exponent == max_exponent) { if (non_zero) { return GSL_IEEE_TYPE_NAN ; } else { return GSL_IEEE_TYPE_INF ; } } else if (exponent == 0) { if (non_zero) { return GSL_IEEE_TYPE_DENORMAL ; } else { return GSL_IEEE_TYPE_ZERO ; } } else { return GSL_IEEE_TYPE_NORMAL ; } } praat-6.0.04/external/gsl/gsl_ieee-utils__print.c000066400000000000000000000052351261542461700217650ustar00rootroot00000000000000/* ieee-utils/print.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_ieee_utils.h" /* A table of sign characters, 0=positive, 1=negative. We print a space instead of a unary + sign for compatibility with bc */ static char signs[2]={' ','-'} ; void gsl_ieee_fprintf_float (FILE * stream, const float * x) { gsl_ieee_float_rep r ; gsl_ieee_float_to_rep(x, &r) ; switch (r.type) { case GSL_IEEE_TYPE_NAN: fprintf(stream, "NaN") ; break ; case GSL_IEEE_TYPE_INF: fprintf(stream, "%cInf", signs[r.sign]) ; break ; case GSL_IEEE_TYPE_NORMAL: fprintf(stream, "%c1.%s*2^%d", signs[r.sign], r.mantissa, r.exponent) ; break ; case GSL_IEEE_TYPE_DENORMAL: fprintf(stream, "%c0.%s*2^%d", signs[r.sign], r.mantissa, r.exponent + 1) ; break ; case GSL_IEEE_TYPE_ZERO: fprintf(stream, "%c0", signs[r.sign]) ; break ; default: fprintf(stream, "[non-standard IEEE float]") ; } } void gsl_ieee_printf_float (const float * x) { gsl_ieee_fprintf_float (stdout,x); } void gsl_ieee_fprintf_double (FILE * stream, const double * x) { gsl_ieee_double_rep r ; gsl_ieee_double_to_rep (x, &r) ; switch (r.type) { case GSL_IEEE_TYPE_NAN: fprintf(stream, "NaN") ; break ; case GSL_IEEE_TYPE_INF: fprintf(stream, "%cInf", signs[r.sign]) ; break ; case GSL_IEEE_TYPE_NORMAL: fprintf(stream, "%c1.%s*2^%d", signs[r.sign], r.mantissa, r.exponent) ; break ; case GSL_IEEE_TYPE_DENORMAL: fprintf(stream, "%c0.%s*2^%d", signs[r.sign], r.mantissa, r.exponent + 1) ; break ; case GSL_IEEE_TYPE_ZERO: fprintf(stream, "%c0", signs[r.sign]) ; break ; default: fprintf(stream, "[non-standard IEEE double]") ; } } void gsl_ieee_printf_double (const double * x) { gsl_ieee_fprintf_double (stdout,x); } praat-6.0.04/external/gsl/gsl_ieee-utils__read.c000066400000000000000000000116361261542461700215460ustar00rootroot00000000000000/* ieee-utils/read.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_errno.h" #include "gsl_ieee_utils.h" static int lookup_string (const char * p, int * precision, int * rounding, int * exception_mask) ; int gsl_ieee_read_mode_string (const char * description, int * precision, int * rounding, int * exception_mask) { char * start ; char * end; char * p; int precision_count = 0 ; int rounding_count = 0 ; int exception_count = 0 ; start = (char *) malloc(strlen(description) + 1) ; if (start == 0) { GSL_ERROR ("no memory to parse mode string", GSL_ENOMEM) ; } strcpy (start, description) ; p = start ; *precision = 0 ; *rounding = 0 ; *exception_mask = 0 ; do { int status ; int new_precision, new_rounding, new_exception ; end = strchr (p,',') ; if (end) { *end = '\0' ; do { end++ ; /* skip over trailing whitespace */ } while (*end == ' ' || *end == ',') ; } new_precision = 0 ; new_rounding = 0 ; new_exception = 0 ; status = lookup_string (p, &new_precision, &new_rounding, &new_exception) ; if (status) GSL_ERROR ("unrecognized GSL_IEEE_MODE string.\nValid settings are:\n\n" " single-precision double-precision extended-precision\n" " round-to-nearest round-down round-up round-to-zero\n" " mask-invalid mask-denormalized mask-division-by-zero\n" " mask-overflow mask-underflow mask-all\n" " trap-common trap-inexact\n" "\n" "separated by commas. " "(e.g. GSL_IEEE_MODE=\"round-down,mask-underflow\")", GSL_EINVAL) ; if (new_precision) { *precision = new_precision ; precision_count ++ ; if (precision_count > 1) GSL_ERROR ("attempted to set IEEE precision twice", GSL_EINVAL) ; } if (new_rounding) { *rounding = new_rounding ; rounding_count ++ ; if (rounding_count > 1) GSL_ERROR ("attempted to set IEEE rounding mode twice", GSL_EINVAL) ; } if (new_exception) { *exception_mask |= new_exception ; exception_count ++ ; } p = end ; } while (end && *p != '\0') ; free(start) ; return GSL_SUCCESS ; } static int lookup_string (const char * p, int * precision, int * rounding, int * exception_mask) { if (strcmp(p,"single-precision") == 0) { *precision = GSL_IEEE_SINGLE_PRECISION ; } else if (strcmp(p,"double-precision") == 0) { *precision = GSL_IEEE_DOUBLE_PRECISION ; } else if (strcmp(p,"extended-precision") == 0) { *precision = GSL_IEEE_EXTENDED_PRECISION ; } else if (strcmp(p,"round-to-nearest") == 0) { *rounding = GSL_IEEE_ROUND_TO_NEAREST ; } else if (strcmp(p,"round-down") == 0) { *rounding = GSL_IEEE_ROUND_DOWN ; } else if (strcmp(p,"round-up") == 0) { *rounding = GSL_IEEE_ROUND_UP ; } else if (strcmp(p,"round-to-zero") == 0) { *rounding = GSL_IEEE_ROUND_TO_ZERO ; } else if (strcmp(p,"mask-all") == 0) { *exception_mask = GSL_IEEE_MASK_ALL ; } else if (strcmp(p,"mask-invalid") == 0) { *exception_mask = GSL_IEEE_MASK_INVALID ; } else if (strcmp(p,"mask-denormalized") == 0) { *exception_mask = GSL_IEEE_MASK_DENORMALIZED ; } else if (strcmp(p,"mask-division-by-zero") == 0) { *exception_mask = GSL_IEEE_MASK_DIVISION_BY_ZERO ; } else if (strcmp(p,"mask-overflow") == 0) { *exception_mask = GSL_IEEE_MASK_OVERFLOW ; } else if (strcmp(p,"mask-underflow") == 0) { *exception_mask = GSL_IEEE_MASK_UNDERFLOW ; } else if (strcmp(p,"trap-inexact") == 0) { *exception_mask = GSL_IEEE_TRAP_INEXACT ; } else if (strcmp(p,"trap-common") == 0) { return 0 ; } else { return 1 ; } return 0 ; } praat-6.0.04/external/gsl/gsl_ieee-utils__standardize.c000066400000000000000000000025761261542461700231460ustar00rootroot00000000000000/* ieee-utils/standardize.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static void make_float_bigendian (float * x); static void make_double_bigendian (double * x); static void make_float_bigendian (float * x) { union { float f; unsigned char b[4]; } u,v; u.f = *x ; v.b[0]=u.b[3] ; v.b[1]=u.b[2] ; v.b[2]=u.b[1] ; v.b[3]=u.b[0] ; *x=v.f ; } static void make_double_bigendian (double * x) { union { double d; unsigned char b[8]; } u,v; u.d = *x ; v.b[0]=u.b[7] ; v.b[1]=u.b[6] ; v.b[2]=u.b[5] ; v.b[3]=u.b[4] ; v.b[4]=u.b[3] ; v.b[5]=u.b[2] ; v.b[6]=u.b[1] ; v.b[7]=u.b[0] ; *x=v.d ; } praat-6.0.04/external/gsl/gsl_ieee_utils.h000066400000000000000000000052331261542461700204770ustar00rootroot00000000000000/* ieee-utils/gsl_ieee_utils.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_IEEE_UTILS_H__ #define __GSL_IEEE_UTILS_H__ #include #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS enum { GSL_IEEE_TYPE_NAN = 1, GSL_IEEE_TYPE_INF = 2, GSL_IEEE_TYPE_NORMAL = 3, GSL_IEEE_TYPE_DENORMAL = 4, GSL_IEEE_TYPE_ZERO = 5 } ; typedef struct { int sign ; char mantissa[24] ; /* Actual bits are 0..22, element 23 is \0 */ int exponent ; int type ; } gsl_ieee_float_rep ; typedef struct { int sign ; char mantissa[53] ; /* Actual bits are 0..51, element 52 is \0 */ int exponent ; int type ; } gsl_ieee_double_rep ; void gsl_ieee_printf_float (const float * x) ; void gsl_ieee_printf_double (const double * x) ; void gsl_ieee_fprintf_float (FILE * stream, const float * x) ; void gsl_ieee_fprintf_double (FILE * stream, const double * x) ; void gsl_ieee_float_to_rep (const float * x, gsl_ieee_float_rep * r) ; void gsl_ieee_double_to_rep (const double * x, gsl_ieee_double_rep * r) ; enum { GSL_IEEE_SINGLE_PRECISION = 1, GSL_IEEE_DOUBLE_PRECISION = 2, GSL_IEEE_EXTENDED_PRECISION = 3 } ; enum { GSL_IEEE_ROUND_TO_NEAREST = 1, GSL_IEEE_ROUND_DOWN = 2, GSL_IEEE_ROUND_UP = 3, GSL_IEEE_ROUND_TO_ZERO = 4 } ; enum { GSL_IEEE_MASK_INVALID = 1, GSL_IEEE_MASK_DENORMALIZED = 2, GSL_IEEE_MASK_DIVISION_BY_ZERO = 4, GSL_IEEE_MASK_OVERFLOW = 8, GSL_IEEE_MASK_UNDERFLOW = 16, GSL_IEEE_MASK_ALL = 31, GSL_IEEE_TRAP_INEXACT = 32 } ; void gsl_ieee_env_setup (void) ; int gsl_ieee_read_mode_string (const char * description, int * precision, int * rounding, int * exception_mask) ; int gsl_ieee_set_mode (int precision, int rounding, int exception_mask) ; __END_DECLS #endif /* __GSL_IEEE_UTILS_H__ */ praat-6.0.04/external/gsl/gsl_integration.h000066400000000000000000000214651261542461700207000ustar00rootroot00000000000000/* integration/gsl_integration.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_INTEGRATION_H__ #define __GSL_INTEGRATION_H__ #include #include "gsl_math.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Workspace for adaptive integrators */ typedef struct { size_t limit; size_t size; size_t nrmax; size_t i; size_t maximum_level; double *alist; double *blist; double *rlist; double *elist; size_t *order; size_t *level; } gsl_integration_workspace; gsl_integration_workspace * gsl_integration_workspace_alloc (const size_t n); void gsl_integration_workspace_free (gsl_integration_workspace * w); /* Workspace for QAWS integrator */ typedef struct { double alpha; double beta; int mu; int nu; double ri[25]; double rj[25]; double rg[25]; double rh[25]; } gsl_integration_qaws_table; gsl_integration_qaws_table * gsl_integration_qaws_table_alloc (double alpha, double beta, int mu, int nu); int gsl_integration_qaws_table_set (gsl_integration_qaws_table * t, double alpha, double beta, int mu, int nu); void gsl_integration_qaws_table_free (gsl_integration_qaws_table * t); /* Workspace for QAWO integrator */ enum gsl_integration_qawo_enum { GSL_INTEG_COSINE, GSL_INTEG_SINE }; typedef struct { size_t n; double omega; double L; double par; enum gsl_integration_qawo_enum sine; double *chebmo; } gsl_integration_qawo_table; gsl_integration_qawo_table * gsl_integration_qawo_table_alloc (double omega, double L, enum gsl_integration_qawo_enum sine, size_t n); int gsl_integration_qawo_table_set (gsl_integration_qawo_table * t, double omega, double L, enum gsl_integration_qawo_enum sine); int gsl_integration_qawo_table_set_length (gsl_integration_qawo_table * t, double L); void gsl_integration_qawo_table_free (gsl_integration_qawo_table * t); /* Definition of an integration rule */ typedef void gsl_integration_rule (const gsl_function * f, double a, double b, double *result, double *abserr, double *defabs, double *resabs); void gsl_integration_qk15 (const gsl_function * f, double a, double b, double *result, double *abserr, double *resabs, double *resasc); void gsl_integration_qk21 (const gsl_function * f, double a, double b, double *result, double *abserr, double *resabs, double *resasc); void gsl_integration_qk31 (const gsl_function * f, double a, double b, double *result, double *abserr, double *resabs, double *resasc); void gsl_integration_qk41 (const gsl_function * f, double a, double b, double *result, double *abserr, double *resabs, double *resasc); void gsl_integration_qk51 (const gsl_function * f, double a, double b, double *result, double *abserr, double *resabs, double *resasc); void gsl_integration_qk61 (const gsl_function * f, double a, double b, double *result, double *abserr, double *resabs, double *resasc); void gsl_integration_qcheb (gsl_function * f, double a, double b, double *cheb12, double *cheb24); /* The low-level integration rules in QUADPACK are identified by small integers (1-6). We'll use symbolic constants to refer to them. */ enum { GSL_INTEG_GAUSS15 = 1, /* 15 point Gauss-Kronrod rule */ GSL_INTEG_GAUSS21 = 2, /* 21 point Gauss-Kronrod rule */ GSL_INTEG_GAUSS31 = 3, /* 31 point Gauss-Kronrod rule */ GSL_INTEG_GAUSS41 = 4, /* 41 point Gauss-Kronrod rule */ GSL_INTEG_GAUSS51 = 5, /* 51 point Gauss-Kronrod rule */ GSL_INTEG_GAUSS61 = 6 /* 61 point Gauss-Kronrod rule */ }; void gsl_integration_qk (const int n, const double xgk[], const double wg[], const double wgk[], double fv1[], double fv2[], const gsl_function *f, double a, double b, double * result, double * abserr, double * resabs, double * resasc); int gsl_integration_qng (const gsl_function * f, double a, double b, double epsabs, double epsrel, double *result, double *abserr, size_t * neval); int gsl_integration_qag (const gsl_function * f, double a, double b, double epsabs, double epsrel, size_t limit, int key, gsl_integration_workspace * workspace, double *result, double *abserr); int gsl_integration_qagi (gsl_function * f, double epsabs, double epsrel, size_t limit, gsl_integration_workspace * workspace, double *result, double *abserr); int gsl_integration_qagiu (gsl_function * f, double a, double epsabs, double epsrel, size_t limit, gsl_integration_workspace * workspace, double *result, double *abserr); int gsl_integration_qagil (gsl_function * f, double b, double epsabs, double epsrel, size_t limit, gsl_integration_workspace * workspace, double *result, double *abserr); int gsl_integration_qags (const gsl_function * f, double a, double b, double epsabs, double epsrel, size_t limit, gsl_integration_workspace * workspace, double *result, double *abserr); int gsl_integration_qagp (const gsl_function * f, double *pts, size_t npts, double epsabs, double epsrel, size_t limit, gsl_integration_workspace * workspace, double *result, double *abserr); int gsl_integration_qawc (gsl_function *f, const double a, const double b, const double c, const double epsabs, const double epsrel, const size_t limit, gsl_integration_workspace * workspace, double * result, double * abserr); int gsl_integration_qaws (gsl_function * f, const double a, const double b, gsl_integration_qaws_table * t, const double epsabs, const double epsrel, const size_t limit, gsl_integration_workspace * workspace, double *result, double *abserr); int gsl_integration_qawo (gsl_function * f, const double a, const double epsabs, const double epsrel, const size_t limit, gsl_integration_workspace * workspace, gsl_integration_qawo_table * wf, double *result, double *abserr); int gsl_integration_qawf (gsl_function * f, const double a, const double epsabs, const size_t limit, gsl_integration_workspace * workspace, gsl_integration_workspace * cycle_workspace, gsl_integration_qawo_table * wf, double *result, double *abserr); __END_DECLS #endif /* __GSL_INTEGRATION_H__ */ praat-6.0.04/external/gsl/gsl_integration__append.c000066400000000000000000000023351261542461700223540ustar00rootroot00000000000000/* integration/append.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static inline void append_interval (gsl_integration_workspace * workspace, double a1, double b1, double area1, double error1) { const size_t i_new = workspace->size ; workspace->alist[i_new] = a1; workspace->blist[i_new] = b1; workspace->rlist[i_new] = area1; workspace->elist[i_new] = error1; workspace->order[i_new] = i_new; workspace->level[i_new] = 0; workspace->size++; } praat-6.0.04/external/gsl/gsl_integration__err.c000066400000000000000000000031451261542461700216750ustar00rootroot00000000000000/* integration/err.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_math.h" #include "gsl_integration.h" static double rescale_error (double err, const double result_abs, const double result_asc) ; static double rescale_error (double err, const double result_abs, const double result_asc) { err = fabs(err) ; if (result_asc != 0 && err != 0) { double scale = pow((200 * err / result_asc), 1.5) ; if (scale < 1) { err = result_asc * scale ; } else { err = result_asc ; } } if (result_abs > GSL_DBL_MIN / (50 * GSL_DBL_EPSILON)) { double min_err = 50 * GSL_DBL_EPSILON * result_abs ; if (min_err > err) { err = min_err ; } } return err ; } praat-6.0.04/external/gsl/gsl_integration__initialise.c000066400000000000000000000024031261542461700232330ustar00rootroot00000000000000/* integration/initialise.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static inline void initialise (gsl_integration_workspace * workspace, double a, double b); static inline void initialise (gsl_integration_workspace * workspace, double a, double b) { workspace->size = 0; workspace->nrmax = 0; workspace->i = 0; workspace->alist[0] = a; workspace->blist[0] = b; workspace->rlist[0] = 0.0; workspace->elist[0] = 0.0; workspace->order[0] = 0; workspace->level[0] = 0; workspace->maximum_level = 0; } praat-6.0.04/external/gsl/gsl_integration__positivity.c000066400000000000000000000005421261542461700233260ustar00rootroot00000000000000/* Compare the integral of f(x) with the integral of |f(x)| to determine if f(x) covers both positive and negative values */ static inline int test_positivity (double result, double resabs); static inline int test_positivity (double result, double resabs) { int status = (fabs (result) >= (1 - 50 * GSL_DBL_EPSILON) * resabs); return status; } praat-6.0.04/external/gsl/gsl_integration__ptsort.c000066400000000000000000000030621261542461700224360ustar00rootroot00000000000000/* integration/ptsort.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static void sort_results (gsl_integration_workspace * workspace); static void sort_results (gsl_integration_workspace * workspace) { size_t i; double * elist = workspace->elist ; size_t * order = workspace->order ; size_t nint = workspace->size; for (i = 0; i < nint; i++) { size_t i1 = order[i]; double e1 = elist[i1]; size_t i_max = i1; size_t j; for (j = i + 1; j < nint; j++) { size_t i2 = order[j]; double e2 = elist[i2]; if (e2 >= e1) { i_max = i2; e1 = e2; } } if (i_max != i1) { order[i] = order[i_max]; order[i_max] = i1; } } workspace->i = order[0] ; } praat-6.0.04/external/gsl/gsl_integration__qag.c000066400000000000000000000155141261542461700216600ustar00rootroot00000000000000/* integration/qag.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_integration.h" #include "gsl_integration__initialise.c" #include "gsl_integration__set_initial.c" #include "gsl_integration__qpsrt.c" #include "gsl_integration__util.c" static int qag (const gsl_function *f, const double a, const double b, const double epsabs, const double epsrel, const size_t limit, gsl_integration_workspace * workspace, double * result, double * abserr, gsl_integration_rule * q) ; int gsl_integration_qag (const gsl_function *f, double a, double b, double epsabs, double epsrel, size_t limit, int key, gsl_integration_workspace * workspace, double * result, double * abserr) { int status ; gsl_integration_rule * integration_rule = gsl_integration_qk15 ; if (key < GSL_INTEG_GAUSS15) { key = GSL_INTEG_GAUSS15 ; } else if (key > GSL_INTEG_GAUSS61) { key = GSL_INTEG_GAUSS61 ; } switch (key) { case GSL_INTEG_GAUSS15: integration_rule = gsl_integration_qk15 ; break ; case GSL_INTEG_GAUSS21: integration_rule = gsl_integration_qk21 ; break ; case GSL_INTEG_GAUSS31: integration_rule = gsl_integration_qk31 ; break ; case GSL_INTEG_GAUSS41: integration_rule = gsl_integration_qk41 ; break ; case GSL_INTEG_GAUSS51: integration_rule = gsl_integration_qk51 ; break ; case GSL_INTEG_GAUSS61: integration_rule = gsl_integration_qk61 ; break ; default: GSL_ERROR("value of key does specify a known integration rule", GSL_EINVAL) ; } status = qag (f, a, b, epsabs, epsrel, limit, workspace, result, abserr, integration_rule) ; return status ; } static int qag (const gsl_function * f, const double a, const double b, const double epsabs, const double epsrel, const size_t limit, gsl_integration_workspace * workspace, double *result, double *abserr, gsl_integration_rule * q) { double area, errsum; double result0, abserr0, resabs0, resasc0; double tolerance; size_t iteration = 0; int roundoff_type1 = 0, roundoff_type2 = 0, error_type = 0; double round_off; /* Initialize results */ initialise (workspace, a, b); *result = 0; *abserr = 0; if (limit > workspace->limit) { GSL_ERROR ("iteration limit exceeds available workspace", GSL_EINVAL) ; } if (epsabs <= 0 && (epsrel < 50 * GSL_DBL_EPSILON || epsrel < 0.5e-28)) { GSL_ERROR ("tolerance cannot be acheived with given epsabs and epsrel", GSL_EBADTOL); } /* perform the first integration */ q (f, a, b, &result0, &abserr0, &resabs0, &resasc0); set_initial_result (workspace, result0, abserr0); /* Test on accuracy */ tolerance = GSL_MAX_DBL (epsabs, epsrel * fabs (result0)); /* need IEEE rounding here to match original quadpack behavior */ round_off = GSL_COERCE_DBL (50 * GSL_DBL_EPSILON * resabs0); if (abserr0 <= round_off && abserr0 > tolerance) { *result = result0; *abserr = abserr0; GSL_ERROR ("cannot reach tolerance because of roundoff error " "on first attempt", GSL_EROUND); } else if ((abserr0 <= tolerance && abserr0 != resasc0) || abserr0 == 0.0) { *result = result0; *abserr = abserr0; return GSL_SUCCESS; } else if (limit == 1) { *result = result0; *abserr = abserr0; GSL_ERROR ("a maximum of one iteration was insufficient", GSL_EMAXITER); } area = result0; errsum = abserr0; iteration = 1; do { double a1, b1, a2, b2; double a_i, b_i, r_i, e_i; double area1 = 0, area2 = 0, area12 = 0; double error1 = 0, error2 = 0, error12 = 0; double resasc1, resasc2; double resabs1, resabs2; /* Bisect the subinterval with the largest error estimate */ retrieve (workspace, &a_i, &b_i, &r_i, &e_i); a1 = a_i; b1 = 0.5 * (a_i + b_i); a2 = b1; b2 = b_i; q (f, a1, b1, &area1, &error1, &resabs1, &resasc1); q (f, a2, b2, &area2, &error2, &resabs2, &resasc2); area12 = area1 + area2; error12 = error1 + error2; errsum += (error12 - e_i); area += area12 - r_i; if (resasc1 != error1 && resasc2 != error2) { double delta = r_i - area12; if (fabs (delta) <= 1.0e-5 * fabs (area12) && error12 >= 0.99 * e_i) { roundoff_type1++; } if (iteration >= 10 && error12 > e_i) { roundoff_type2++; } } tolerance = GSL_MAX_DBL (epsabs, epsrel * fabs (area)); if (errsum > tolerance) { if (roundoff_type1 >= 6 || roundoff_type2 >= 20) { error_type = 2; /* round off error */ } /* set error flag in the case of bad integrand behaviour at a point of the integration range */ if (subinterval_too_small (a1, a2, b2)) { error_type = 3; } } update (workspace, a1, b1, area1, error1, a2, b2, area2, error2); retrieve (workspace, &a_i, &b_i, &r_i, &e_i); iteration++; } while (iteration < limit && !error_type && errsum > tolerance); *result = sum_results (workspace); *abserr = errsum; if (errsum <= tolerance) { return GSL_SUCCESS; } else if (error_type == 2) { GSL_ERROR ("roundoff error prevents tolerance from being achieved", GSL_EROUND); } else if (error_type == 3) { GSL_ERROR ("bad integrand behavior found in the integration interval", GSL_ESING); } else if (iteration == limit) { GSL_ERROR ("maximum number of subdivisions reached", GSL_EMAXITER); } else { GSL_ERROR ("could not integrate function", GSL_EFAILED); } } praat-6.0.04/external/gsl/gsl_integration__qagp.c000066400000000000000000000273141261542461700220410ustar00rootroot00000000000000/* integration/qagp.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_integration.h" static int qagp (const gsl_function *f, const double *pts, const size_t npts, const double epsabs, const double epsrel, const size_t limit, gsl_integration_workspace * workspace, double *result, double *abserr, gsl_integration_rule * q); #include "gsl_integration__initialise.c" #include "gsl_integration__qpsrt.c" #include "gsl_integration__util.c" #include "gsl_integration__append.c" #include "gsl_integration__reset.c" #include "gsl_integration__qelg.c" #include "gsl_integration__qpsrt2.c" #include "gsl_integration__ptsort.c" #include "gsl_integration__positivity.c" int gsl_integration_qagp (const gsl_function *f, double * pts, size_t npts, double epsabs, double epsrel, size_t limit, gsl_integration_workspace * workspace, double * result, double * abserr) { int status = qagp (f, pts, npts, epsabs, epsrel, limit, workspace, result, abserr, &gsl_integration_qk21) ; return status ; } static int qagp (const gsl_function * f, const double *pts, const size_t npts, const double epsabs, const double epsrel, const size_t limit, gsl_integration_workspace * workspace, double *result, double *abserr, gsl_integration_rule * q) { double area, errsum; double res_ext, err_ext; double result0, abserr0, resabs0; double tolerance; double ertest = 0; double error_over_large_intervals = 0; double reseps = 0, abseps = 0, correc = 0; size_t ktmin = 0; int roundoff_type1 = 0, roundoff_type2 = 0, roundoff_type3 = 0; int error_type = 0, error_type2 = 0; size_t iteration = 0; int positive_integrand = 0; int extrapolate = 0; int disallow_extrapolation = 0; struct extrapolation_table table; const size_t nint = npts - 1; /* number of intervals */ size_t *ndin = workspace->level; /* temporarily alias ndin to level */ size_t i; /* Initialize results */ *result = 0; *abserr = 0; /* Test on validity of parameters */ if (limit > workspace->limit) { GSL_ERROR ("iteration limit exceeds available workspace", GSL_EINVAL) ; } if (npts > workspace->limit) { GSL_ERROR ("npts exceeds size of workspace", GSL_EINVAL); } if (epsabs <= 0 && (epsrel < 50 * GSL_DBL_EPSILON || epsrel < 0.5e-28)) { GSL_ERROR ("tolerance cannot be acheived with given epsabs and epsrel", GSL_EBADTOL); } /* Check that the integration range and break points are an ascending sequence */ for (i = 0; i < nint; i++) { if (pts[i + 1] < pts[i]) { GSL_ERROR ("points are not in an ascending sequence", GSL_EINVAL); } } /* Perform the first integration */ result0 = 0; abserr0 = 0; resabs0 = 0; initialise (workspace, 0.0, 0.0) ; for (i = 0; i < nint; i++) { double area1, error1, resabs1, resasc1; const double a1 = pts[i]; const double b1 = pts[i + 1]; q (f, a1, b1, &area1, &error1, &resabs1, &resasc1); result0 = result0 + area1; abserr0 = abserr0 + error1; resabs0 = resabs0 + resabs1; append_interval (workspace, a1, b1, area1, error1); if (error1 == resasc1 && error1 != 0.0) { ndin[i] = 1; } else { ndin[i] = 0; } } /* Compute the initial error estimate */ errsum = 0.0; for (i = 0; i < nint; i++) { if (ndin[i]) { workspace->elist[i] = abserr0; } errsum = errsum + workspace->elist[i]; } for (i = 0; i < nint; i++) { workspace->level[i] = 0; } /* Sort results into order of decreasing error via the indirection array order[] */ sort_results (workspace); /* Test on accuracy */ tolerance = GSL_MAX_DBL (epsabs, epsrel * fabs (result0)); if (abserr0 <= 100 * GSL_DBL_EPSILON * resabs0 && abserr0 > tolerance) { *result = result0; *abserr = abserr0; GSL_ERROR ("cannot reach tolerance because of roundoff error" "on first attempt", GSL_EROUND); } else if (abserr0 <= tolerance) { *result = result0; *abserr = abserr0; return GSL_SUCCESS; } else if (limit == 1) { *result = result0; *abserr = abserr0; GSL_ERROR ("a maximum of one iteration was insufficient", GSL_EMAXITER); } /* Initialization */ initialise_table (&table); append_table (&table, result0); area = result0; res_ext = result0; err_ext = GSL_DBL_MAX; error_over_large_intervals = errsum; ertest = tolerance; positive_integrand = test_positivity (result0, resabs0); iteration = nint - 1; do { size_t current_level; double a1, b1, a2, b2; double a_i, b_i, r_i, e_i; double area1 = 0, area2 = 0, area12 = 0; double error1 = 0, error2 = 0, error12 = 0; double resasc1, resasc2; double resabs1, resabs2; double last_e_i; /* Bisect the subinterval with the largest error estimate */ retrieve (workspace, &a_i, &b_i, &r_i, &e_i); current_level = workspace->level[workspace->i] + 1; a1 = a_i; b1 = 0.5 * (a_i + b_i); a2 = b1; b2 = b_i; iteration++; q (f, a1, b1, &area1, &error1, &resabs1, &resasc1); q (f, a2, b2, &area2, &error2, &resabs2, &resasc2); area12 = area1 + area2; error12 = error1 + error2; last_e_i = e_i; /* Improve previous approximations to the integral and test for accuracy. We write these expressions in the same way as the original QUADPACK code so that the rounding errors are the same, which makes testing easier. */ errsum = errsum + error12 - e_i; area = area + area12 - r_i; tolerance = GSL_MAX_DBL (epsabs, epsrel * fabs (area)); if (resasc1 != error1 && resasc2 != error2) { double delta = r_i - area12; if (fabs (delta) <= 1.0e-5 * fabs (area12) && error12 >= 0.99 * e_i) { if (!extrapolate) { roundoff_type1++; } else { roundoff_type2++; } } if (i > 10 && error12 > e_i) { roundoff_type3++; } } /* Test for roundoff and eventually set error flag */ if (roundoff_type1 + roundoff_type2 >= 10 || roundoff_type3 >= 20) { error_type = 2; /* round off error */ } if (roundoff_type2 >= 5) { error_type2 = 1; } /* set error flag in the case of bad integrand behaviour at a point of the integration range */ if (subinterval_too_small (a1, a2, b2)) { error_type = 4; } /* append the newly-created intervals to the list */ update (workspace, a1, b1, area1, error1, a2, b2, area2, error2); if (errsum <= tolerance) { goto compute_result; } if (error_type) { break; } if (iteration >= limit - 1) { error_type = 1; break; } if (disallow_extrapolation) { continue; } error_over_large_intervals += -last_e_i; if (current_level < workspace->maximum_level) { error_over_large_intervals += error12; } if (!extrapolate) { /* test whether the interval to be bisected next is the smallest interval. */ if (large_interval (workspace)) continue; extrapolate = 1; workspace->nrmax = 1; } /* The smallest interval has the largest error. Before bisecting decrease the sum of the errors over the larger intervals (error_over_large_intervals) and perform extrapolation. */ if (!error_type2 && error_over_large_intervals > ertest) { if (increase_nrmax (workspace)) continue; } /* Perform extrapolation */ append_table (&table, area); if (table.n < 3) { goto skip_extrapolation; } qelg (&table, &reseps, &abseps); ktmin++; if (ktmin > 5 && err_ext < 0.001 * errsum) { error_type = 5; } if (abseps < err_ext) { ktmin = 0; err_ext = abseps; res_ext = reseps; correc = error_over_large_intervals; ertest = GSL_MAX_DBL (epsabs, epsrel * fabs (reseps)); if (err_ext <= ertest) break; } /* Prepare bisection of the smallest interval. */ if (table.n == 1) { disallow_extrapolation = 1; } if (error_type == 5) { break; } skip_extrapolation: reset_nrmax (workspace); extrapolate = 0; error_over_large_intervals = errsum; } while (iteration < limit); *result = res_ext; *abserr = err_ext; if (err_ext == GSL_DBL_MAX) goto compute_result; if (error_type || error_type2) { if (error_type2) { err_ext += correc; } if (error_type == 0) error_type = 3; if (result != 0 && area != 0) { if (err_ext / fabs (res_ext) > errsum / fabs (area)) goto compute_result; } else if (err_ext > errsum) { goto compute_result; } else if (area == 0.0) { goto return_error; } } /* Test on divergence. */ { double max_area = GSL_MAX_DBL (fabs (res_ext), fabs (area)); if (!positive_integrand && max_area < 0.01 * resabs0) goto return_error; } { double ratio = res_ext / area; if (ratio < 0.01 || ratio > 100 || errsum > fabs (area)) error_type = 6; } goto return_error; compute_result: *result = sum_results (workspace); *abserr = errsum; return_error: if (error_type > 2) error_type--; if (error_type == 0) { return GSL_SUCCESS; } else if (error_type == 1) { GSL_ERROR ("number of iterations was insufficient", GSL_EMAXITER); } else if (error_type == 2) { GSL_ERROR ("cannot reach tolerance because of roundoff error", GSL_EROUND); } else if (error_type == 3) { GSL_ERROR ("bad integrand behavior found in the integration interval", GSL_ESING); } else if (error_type == 4) { GSL_ERROR ("roundoff error detected in the extrapolation table", GSL_EROUND); } else if (error_type == 5) { GSL_ERROR ("integral is divergent, or slowly convergent", GSL_EDIVERGE); } else { GSL_ERROR ("could not integrate function", GSL_EFAILED); } } praat-6.0.04/external/gsl/gsl_integration__qags.c000066400000000000000000000327451261542461700220500ustar00rootroot00000000000000/* integration/qags.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_integration.h" #include "gsl_integration__initialise.c" #include "gsl_integration__set_initial.c" #include "gsl_integration__qpsrt.c" #include "gsl_integration__util.c" #include "gsl_integration__reset.c" #include "gsl_integration__qpsrt2.c" #include "gsl_integration__qelg.c" #include "gsl_integration__positivity.c" static int qags (const gsl_function * f, const double a, const double b, const double epsabs, const double epsrel, const size_t limit, gsl_integration_workspace * workspace, double *result, double *abserr, gsl_integration_rule * q); int gsl_integration_qags (const gsl_function *f, double a, double b, double epsabs, double epsrel, size_t limit, gsl_integration_workspace * workspace, double * result, double * abserr) { int status = qags (f, a, b, epsabs, epsrel, limit, workspace, result, abserr, &gsl_integration_qk21) ; return status ; } /* QAGI: evaluate an integral over an infinite range using the transformation integrate(f(x),-Inf,Inf) = integrate((f((1-t)/t) + f(-(1-t)/t))/t^2,0,1) */ static double i_transform (double t, void *params); int gsl_integration_qagi (gsl_function * f, double epsabs, double epsrel, size_t limit, gsl_integration_workspace * workspace, double *result, double *abserr) { int status; gsl_function f_transform; f_transform.function = &i_transform; f_transform.params = f; status = qags (&f_transform, 0.0, 1.0, epsabs, epsrel, limit, workspace, result, abserr, &gsl_integration_qk15); return status; } static double i_transform (double t, void *params) { gsl_function *f = (gsl_function *) params; double x = (1 - t) / t; double y = GSL_FN_EVAL (f, x) + GSL_FN_EVAL (f, -x); return (y / t) / t; } /* QAGIL: Evaluate an integral over an infinite range using the transformation, integrate(f(x),-Inf,b) = integrate(f(b-(1-t)/t)/t^2,0,1) */ struct il_params { double b ; gsl_function * f ; } ; static double il_transform (double t, void *params); int gsl_integration_qagil (gsl_function * f, double b, double epsabs, double epsrel, size_t limit, gsl_integration_workspace * workspace, double *result, double *abserr) { int status; gsl_function f_transform; struct il_params transform_params ; transform_params.b = b ; transform_params.f = f ; f_transform.function = &il_transform; f_transform.params = &transform_params; status = qags (&f_transform, 0.0, 1.0, epsabs, epsrel, limit, workspace, result, abserr, &gsl_integration_qk15); return status; } static double il_transform (double t, void *params) { struct il_params *p = (struct il_params *) params; double b = p->b; gsl_function * f = p->f; double x = b - (1 - t) / t; double y = GSL_FN_EVAL (f, x); return (y / t) / t; } /* QAGIU: Evaluate an integral over an infinite range using the transformation integrate(f(x),a,Inf) = integrate(f(a+(1-t)/t)/t^2,0,1) */ struct iu_params { double a ; gsl_function * f ; } ; static double iu_transform (double t, void *params); int gsl_integration_qagiu (gsl_function * f, double a, double epsabs, double epsrel, size_t limit, gsl_integration_workspace * workspace, double *result, double *abserr) { int status; gsl_function f_transform; struct iu_params transform_params ; transform_params.a = a ; transform_params.f = f ; f_transform.function = &iu_transform; f_transform.params = &transform_params; status = qags (&f_transform, 0.0, 1.0, epsabs, epsrel, limit, workspace, result, abserr, &gsl_integration_qk15); return status; } static double iu_transform (double t, void *params) { struct iu_params *p = (struct iu_params *) params; double a = p->a; gsl_function * f = p->f; double x = a + (1 - t) / t; double y = GSL_FN_EVAL (f, x); return (y / t) / t; } /* Main integration function */ static int qags (const gsl_function * f, const double a, const double b, const double epsabs, const double epsrel, const size_t limit, gsl_integration_workspace * workspace, double *result, double *abserr, gsl_integration_rule * q) { double area, errsum; double res_ext, err_ext; double result0, abserr0, resabs0, resasc0; double tolerance; double ertest = 0; double error_over_large_intervals = 0; double reseps = 0, abseps = 0, correc = 0; size_t ktmin = 0; int roundoff_type1 = 0, roundoff_type2 = 0, roundoff_type3 = 0; int error_type = 0, error_type2 = 0; size_t iteration = 0; int positive_integrand = 0; int extrapolate = 0; int disallow_extrapolation = 0; struct extrapolation_table table; /* Initialize results */ initialise (workspace, a, b); *result = 0; *abserr = 0; if (limit > workspace->limit) { GSL_ERROR ("iteration limit exceeds available workspace", GSL_EINVAL) ; } /* Test on accuracy */ if (epsabs <= 0 && (epsrel < 50 * GSL_DBL_EPSILON || epsrel < 0.5e-28)) { GSL_ERROR ("tolerance cannot be acheived with given epsabs and epsrel", GSL_EBADTOL); } /* Perform the first integration */ q (f, a, b, &result0, &abserr0, &resabs0, &resasc0); set_initial_result (workspace, result0, abserr0); tolerance = GSL_MAX_DBL (epsabs, epsrel * fabs (result0)); if (abserr0 <= 100 * GSL_DBL_EPSILON * resabs0 && abserr0 > tolerance) { *result = result0; *abserr = abserr0; GSL_ERROR ("cannot reach tolerance because of roundoff error" "on first attempt", GSL_EROUND); } else if ((abserr0 <= tolerance && abserr0 != resasc0) || abserr0 == 0.0) { *result = result0; *abserr = abserr0; return GSL_SUCCESS; } else if (limit == 1) { *result = result0; *abserr = abserr0; GSL_ERROR ("a maximum of one iteration was insufficient", GSL_EMAXITER); } /* Initialization */ initialise_table (&table); append_table (&table, result0); area = result0; errsum = abserr0; res_ext = result0; err_ext = GSL_DBL_MAX; positive_integrand = test_positivity (result0, resabs0); iteration = 1; do { size_t current_level; double a1, b1, a2, b2; double a_i, b_i, r_i, e_i; double area1 = 0, area2 = 0, area12 = 0; double error1 = 0, error2 = 0, error12 = 0; double resasc1, resasc2; double resabs1, resabs2; double last_e_i; /* Bisect the subinterval with the largest error estimate */ retrieve (workspace, &a_i, &b_i, &r_i, &e_i); current_level = workspace->level[workspace->i] + 1; a1 = a_i; b1 = 0.5 * (a_i + b_i); a2 = b1; b2 = b_i; iteration++; q (f, a1, b1, &area1, &error1, &resabs1, &resasc1); q (f, a2, b2, &area2, &error2, &resabs2, &resasc2); area12 = area1 + area2; error12 = error1 + error2; last_e_i = e_i; /* Improve previous approximations to the integral and test for accuracy. We write these expressions in the same way as the original QUADPACK code so that the rounding errors are the same, which makes testing easier. */ errsum = errsum + error12 - e_i; area = area + area12 - r_i; tolerance = GSL_MAX_DBL (epsabs, epsrel * fabs (area)); if (resasc1 != error1 && resasc2 != error2) { double delta = r_i - area12; if (fabs (delta) <= 1.0e-5 * fabs (area12) && error12 >= 0.99 * e_i) { if (!extrapolate) { roundoff_type1++; } else { roundoff_type2++; } } if (iteration > 10 && error12 > e_i) { roundoff_type3++; } } /* Test for roundoff and eventually set error flag */ if (roundoff_type1 + roundoff_type2 >= 10 || roundoff_type3 >= 20) { error_type = 2; /* round off error */ } if (roundoff_type2 >= 5) { error_type2 = 1; } /* set error flag in the case of bad integrand behaviour at a point of the integration range */ if (subinterval_too_small (a1, a2, b2)) { error_type = 4; } /* append the newly-created intervals to the list */ update (workspace, a1, b1, area1, error1, a2, b2, area2, error2); if (errsum <= tolerance) { goto compute_result; } if (error_type) { break; } if (iteration >= limit - 1) { error_type = 1; break; } if (iteration == 2) /* set up variables on first iteration */ { error_over_large_intervals = errsum; ertest = tolerance; append_table (&table, area); continue; } if (disallow_extrapolation) { continue; } error_over_large_intervals += -last_e_i; if (current_level < workspace->maximum_level) { error_over_large_intervals += error12; } if (!extrapolate) { /* test whether the interval to be bisected next is the smallest interval. */ if (large_interval (workspace)) continue; extrapolate = 1; workspace->nrmax = 1; } if (!error_type2 && error_over_large_intervals > ertest) { if (increase_nrmax (workspace)) continue; } /* Perform extrapolation */ append_table (&table, area); qelg (&table, &reseps, &abseps); ktmin++; if (ktmin > 5 && err_ext < 0.001 * errsum) { error_type = 5; } if (abseps < err_ext) { ktmin = 0; err_ext = abseps; res_ext = reseps; correc = error_over_large_intervals; ertest = GSL_MAX_DBL (epsabs, epsrel * fabs (reseps)); if (err_ext <= ertest) break; } /* Prepare bisection of the smallest interval. */ if (table.n == 1) { disallow_extrapolation = 1; } if (error_type == 5) { break; } /* work on interval with largest error */ reset_nrmax (workspace); extrapolate = 0; error_over_large_intervals = errsum; } while (iteration < limit); *result = res_ext; *abserr = err_ext; if (err_ext == GSL_DBL_MAX) goto compute_result; if (error_type || error_type2) { if (error_type2) { err_ext += correc; } if (error_type == 0) error_type = 3; if (res_ext != 0.0 && area != 0.0) { if (err_ext / fabs (res_ext) > errsum / fabs (area)) goto compute_result; } else if (err_ext > errsum) { goto compute_result; } else if (area == 0.0) { goto return_error; } } /* Test on divergence. */ { double max_area = GSL_MAX_DBL (fabs (res_ext), fabs (area)); if (!positive_integrand && max_area < 0.01 * resabs0) goto return_error; } { double ratio = res_ext / area; if (ratio < 0.01 || ratio > 100.0 || errsum > fabs (area)) error_type = 6; } goto return_error; compute_result: *result = sum_results (workspace); *abserr = errsum; return_error: if (error_type > 2) error_type--; if (error_type == 0) { return GSL_SUCCESS; } else if (error_type == 1) { GSL_ERROR ("number of iterations was insufficient", GSL_EMAXITER); } else if (error_type == 2) { GSL_ERROR ("cannot reach tolerance because of roundoff error", GSL_EROUND); } else if (error_type == 3) { GSL_ERROR ("bad integrand behavior found in the integration interval", GSL_ESING); } else if (error_type == 4) { GSL_ERROR ("roundoff error detected in the extrapolation table", GSL_EROUND); } else if (error_type == 5) { GSL_ERROR ("integral is divergent, or slowly convergent", GSL_EDIVERGE); } else { GSL_ERROR ("could not integrate function", GSL_EFAILED); } } praat-6.0.04/external/gsl/gsl_integration__qawc.c000066400000000000000000000130471261542461700220420ustar00rootroot00000000000000/* integration/qawc.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_integration.h" #include "gsl_integration__initialise.c" #include "gsl_integration__set_initial.c" #include "gsl_integration__qpsrt.c" #include "gsl_integration__util.c" #include "gsl_integration__qc25c.c" int gsl_integration_qawc (gsl_function * f, const double a, const double b, const double c, const double epsabs, const double epsrel, const size_t limit, gsl_integration_workspace * workspace, double *result, double *abserr) { double area, errsum; double result0, abserr0; double tolerance; size_t iteration = 0; int roundoff_type1 = 0, roundoff_type2 = 0, error_type = 0; int err_reliable; int sign = 1; double lower, higher; /* Initialize results */ *result = 0; *abserr = 0; if (limit > workspace->limit) { GSL_ERROR ("iteration limit exceeds available workspace", GSL_EINVAL) ; } if (b < a) { lower = b ; higher = a ; sign = -1 ; } else { lower = a; higher = b; } initialise (workspace, lower, higher); if (epsabs <= 0 && (epsrel < 50 * GSL_DBL_EPSILON || epsrel < 0.5e-28)) { GSL_ERROR ("tolerance cannot be acheived with given epsabs and epsrel", GSL_EBADTOL); } if (c == a || c == b) { GSL_ERROR ("cannot integrate with singularity on endpoint", GSL_EINVAL); } /* perform the first integration */ qc25c (f, lower, higher, c, &result0, &abserr0, &err_reliable); set_initial_result (workspace, result0, abserr0); /* Test on accuracy, use 0.01 relative error as an extra safety margin on the first iteration (ignored for subsequent iterations) */ tolerance = GSL_MAX_DBL (epsabs, epsrel * fabs (result0)); if (abserr0 < tolerance && abserr0 < 0.01 * fabs(result0)) { *result = sign * result0; *abserr = abserr0; return GSL_SUCCESS; } else if (limit == 1) { *result = sign * result0; *abserr = abserr0; GSL_ERROR ("a maximum of one iteration was insufficient", GSL_EMAXITER); } area = result0; errsum = abserr0; iteration = 1; do { double a1, b1, a2, b2; double a_i, b_i, r_i, e_i; double area1 = 0, area2 = 0, area12 = 0; double error1 = 0, error2 = 0, error12 = 0; int err_reliable1, err_reliable2; /* Bisect the subinterval with the largest error estimate */ retrieve (workspace, &a_i, &b_i, &r_i, &e_i); a1 = a_i; b1 = 0.5 * (a_i + b_i); a2 = b1; b2 = b_i; if (c > a1 && c <= b1) { b1 = 0.5 * (c + b2) ; a2 = b1; } else if (c > b1 && c < b2) { b1 = 0.5 * (a1 + c) ; a2 = b1; } qc25c (f, a1, b1, c, &area1, &error1, &err_reliable1); qc25c (f, a2, b2, c, &area2, &error2, &err_reliable2); area12 = area1 + area2; error12 = error1 + error2; errsum += (error12 - e_i); area += area12 - r_i; if (err_reliable1 && err_reliable2) { double delta = r_i - area12; if (fabs (delta) <= 1.0e-5 * fabs (area12) && error12 >= 0.99 * e_i) { roundoff_type1++; } if (iteration >= 10 && error12 > e_i) { roundoff_type2++; } } tolerance = GSL_MAX_DBL (epsabs, epsrel * fabs (area)); if (errsum > tolerance) { if (roundoff_type1 >= 6 || roundoff_type2 >= 20) { error_type = 2; /* round off error */ } /* set error flag in the case of bad integrand behaviour at a point of the integration range */ if (subinterval_too_small (a1, a2, b2)) { error_type = 3; } } update (workspace, a1, b1, area1, error1, a2, b2, area2, error2); retrieve (workspace, &a_i, &b_i, &r_i, &e_i); iteration++; } while (iteration < limit && !error_type && errsum > tolerance); *result = sign * sum_results (workspace); *abserr = errsum; if (errsum <= tolerance) { return GSL_SUCCESS; } else if (error_type == 2) { GSL_ERROR ("roundoff error prevents tolerance from being achieved", GSL_EROUND); } else if (error_type == 3) { GSL_ERROR ("bad integrand behavior found in the integration interval", GSL_ESING); } else if (iteration == limit) { GSL_ERROR ("maximum number of subdivisions reached", GSL_EMAXITER); } else { GSL_ERROR ("could not integrate function", GSL_EFAILED); } } praat-6.0.04/external/gsl/gsl_integration__qawf.c000066400000000000000000000143051261542461700220430ustar00rootroot00000000000000/* integration/qawf.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_integration.h" #include "gsl_integration__initialise.c" #include "gsl_integration__append.c" #include "gsl_integration__qelg.c" int gsl_integration_qawf (gsl_function * f, const double a, const double epsabs, const size_t limit, gsl_integration_workspace * workspace, gsl_integration_workspace * cycle_workspace, gsl_integration_qawo_table * wf, double *result, double *abserr) { double area, errsum; double res_ext, err_ext; double correc, total_error = 0.0, truncation_error; size_t ktmin = 0; size_t iteration = 0; struct extrapolation_table table; double cycle; double omega = wf->omega; const double p = 0.9; double factor = 1; double initial_eps, eps; int error_type = 0; /* Initialize results */ initialise (workspace, a, a); *result = 0; *abserr = 0; if (limit > workspace->limit) { GSL_ERROR ("iteration limit exceeds available workspace", GSL_EINVAL) ; } /* Test on accuracy */ if (epsabs <= 0) { GSL_ERROR ("absolute tolerance epsabs must be positive", GSL_EBADTOL) ; } if (omega == 0.0) { if (wf->sine == GSL_INTEG_SINE) { /* The function sin(w x) f(x) is always zero for w = 0 */ *result = 0; *abserr = 0; return GSL_SUCCESS; } else { /* The function cos(w x) f(x) is always f(x) for w = 0 */ int status = gsl_integration_qagiu (f, a, epsabs, 0.0, cycle_workspace->limit, cycle_workspace, result, abserr); return status; } } if (epsabs > GSL_DBL_MIN / (1 - p)) { eps = epsabs * (1 - p); } else { eps = epsabs; } initial_eps = eps; area = 0; errsum = 0; res_ext = 0; err_ext = GSL_DBL_MAX; correc = 0; cycle = (2 * floor (fabs (omega)) + 1) * M_PI / fabs (omega); gsl_integration_qawo_table_set_length (wf, cycle); initialise_table (&table); for (iteration = 0; iteration < limit; iteration++) { double area1, error1, reseps, erreps; double a1 = a + iteration * cycle; double b1 = a1 + cycle; double epsabs1 = eps * factor; int status = gsl_integration_qawo (f, a1, epsabs1, 0.0, limit, cycle_workspace, wf, &area1, &error1); append_interval (workspace, a1, b1, area1, error1); factor *= p; area = area + area1; errsum = errsum + error1; /* estimate the truncation error as 50 times the final term */ truncation_error = 50 * fabs (area1); total_error = errsum + truncation_error; if (total_error < epsabs && iteration > 4) { goto compute_result; } if (error1 > correc) { correc = error1; } if (status) { eps = GSL_MAX_DBL (initial_eps, correc * (1.0 - p)); } if (status && total_error < 10 * correc && iteration > 3) { goto compute_result; } append_table (&table, area); if (table.n < 2) { continue; } qelg (&table, &reseps, &erreps); ktmin++; if (ktmin >= 15 && err_ext < 0.001 * total_error) { error_type = 4; } if (erreps < err_ext) { ktmin = 0; err_ext = erreps; res_ext = reseps; if (err_ext + 10 * correc <= epsabs) break; if (err_ext <= epsabs && 10 * correc >= epsabs) break; } } if (iteration == limit) error_type = 1; if (err_ext == GSL_DBL_MAX) goto compute_result; err_ext = err_ext + 10 * correc; *result = res_ext; *abserr = err_ext; if (error_type == 0) { return GSL_SUCCESS ; } if (res_ext != 0.0 && area != 0.0) { if (err_ext / fabs (res_ext) > errsum / fabs (area)) goto compute_result; } else if (err_ext > errsum) { goto compute_result; } else if (area == 0.0) { goto return_error; } if (error_type == 4) { err_ext = err_ext + truncation_error; } goto return_error; compute_result: *result = area; *abserr = total_error; return_error: if (error_type > 2) error_type--; if (error_type == 0) { return GSL_SUCCESS; } else if (error_type == 1) { GSL_ERROR ("number of iterations was insufficient", GSL_EMAXITER); } else if (error_type == 2) { GSL_ERROR ("cannot reach tolerance because of roundoff error", GSL_EROUND); } else if (error_type == 3) { GSL_ERROR ("bad integrand behavior found in the integration interval", GSL_ESING); } else if (error_type == 4) { GSL_ERROR ("roundoff error detected in the extrapolation table", GSL_EROUND); } else if (error_type == 5) { GSL_ERROR ("integral is divergent, or slowly convergent", GSL_EDIVERGE); } else { GSL_ERROR ("could not integrate function", GSL_EFAILED); } } praat-6.0.04/external/gsl/gsl_integration__qawo.c000066400000000000000000000253301261542461700220540ustar00rootroot00000000000000/* integration/qawo.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_integration.h" #include "gsl_integration__initialise.c" #include "gsl_integration__set_initial.c" #include "gsl_integration__reset.c" #include "gsl_integration__qpsrt.c" #include "gsl_integration__util.c" #include "gsl_integration__qpsrt2.c" #include "gsl_integration__qelg.c" #include "gsl_integration__positivity.c" #include "gsl_integration__qc25f.c" int gsl_integration_qawo (gsl_function * f, const double a, const double epsabs, const double epsrel, const size_t limit, gsl_integration_workspace * workspace, gsl_integration_qawo_table * wf, double *result, double *abserr) { double area, errsum; double res_ext, err_ext; double result0, abserr0, resabs0, resasc0; double tolerance; double ertest = 0; double error_over_large_intervals = 0; double reseps = 0, abseps = 0, correc = 0; size_t ktmin = 0; int roundoff_type1 = 0, roundoff_type2 = 0, roundoff_type3 = 0; int error_type = 0, error_type2 = 0; size_t iteration = 0; int positive_integrand = 0; int extrapolate = 0; int extall = 0; int disallow_extrapolation = 0; struct extrapolation_table table; double b = a + wf->L ; double abs_omega = fabs (wf->omega) ; /* Initialize results */ initialise (workspace, a, b); *result = 0; *abserr = 0; if (limit > workspace->limit) { GSL_ERROR ("iteration limit exceeds available workspace", GSL_EINVAL) ; } /* Test on accuracy */ if (epsabs <= 0 && (epsrel < 50 * GSL_DBL_EPSILON || epsrel < 0.5e-28)) { GSL_ERROR ("tolerance cannot be acheived with given epsabs and epsrel", GSL_EBADTOL); } /* Perform the first integration */ qc25f (f, a, b, wf, 0, &result0, &abserr0, &resabs0, &resasc0); set_initial_result (workspace, result0, abserr0); tolerance = GSL_MAX_DBL (epsabs, epsrel * fabs (result0)); if (abserr0 <= 100 * GSL_DBL_EPSILON * resabs0 && abserr0 > tolerance) { *result = result0; *abserr = abserr0; GSL_ERROR ("cannot reach tolerance because of roundoff error" "on first attempt", GSL_EROUND); } else if ((abserr0 <= tolerance && abserr0 != resasc0) || abserr0 == 0.0) { *result = result0; *abserr = abserr0; return GSL_SUCCESS; } else if (limit == 1) { *result = result0; *abserr = abserr0; GSL_ERROR ("a maximum of one iteration was insufficient", GSL_EMAXITER); } /* Initialization */ initialise_table (&table); if (0.5 * abs_omega * fabs(b - a) <= 2) { append_table (&table, result0); extall = 1; } area = result0; errsum = abserr0; res_ext = result0; err_ext = GSL_DBL_MAX; positive_integrand = test_positivity (result0, resabs0); iteration = 1; do { size_t current_level; double a1, b1, a2, b2; double a_i, b_i, r_i, e_i; double area1 = 0, area2 = 0, area12 = 0; double error1 = 0, error2 = 0, error12 = 0; double resasc1, resasc2; double resabs1, resabs2; double last_e_i; /* Bisect the subinterval with the largest error estimate */ retrieve (workspace, &a_i, &b_i, &r_i, &e_i); current_level = workspace->level[workspace->i] + 1; if (current_level >= wf->n) { error_type = -1 ; /* exceeded limit of table */ break ; } a1 = a_i; b1 = 0.5 * (a_i + b_i); a2 = b1; b2 = b_i; iteration++; qc25f (f, a1, b1, wf, current_level, &area1, &error1, &resabs1, &resasc1); qc25f (f, a2, b2, wf, current_level, &area2, &error2, &resabs2, &resasc2); area12 = area1 + area2; error12 = error1 + error2; last_e_i = e_i; /* Improve previous approximations to the integral and test for accuracy. We write these expressions in the same way as the original QUADPACK code so that the rounding errors are the same, which makes testing easier. */ errsum = errsum + error12 - e_i; area = area + area12 - r_i; tolerance = GSL_MAX_DBL (epsabs, epsrel * fabs (area)); if (resasc1 != error1 && resasc2 != error2) { double delta = r_i - area12; if (fabs (delta) <= 1.0e-5 * fabs (area12) && error12 >= 0.99 * e_i) { if (!extrapolate) { roundoff_type1++; } else { roundoff_type2++; } } if (iteration > 10 && error12 > e_i) { roundoff_type3++; } } /* Test for roundoff and eventually set error flag */ if (roundoff_type1 + roundoff_type2 >= 10 || roundoff_type3 >= 20) { error_type = 2; /* round off error */ } if (roundoff_type2 >= 5) { error_type2 = 1; } /* set error flag in the case of bad integrand behaviour at a point of the integration range */ if (subinterval_too_small (a1, a2, b2)) { error_type = 4; } /* append the newly-created intervals to the list */ update (workspace, a1, b1, area1, error1, a2, b2, area2, error2); if (errsum <= tolerance) { goto compute_result; } if (error_type) { break; } if (iteration >= limit - 1) { error_type = 1; break; } /* set up variables on first iteration */ if (iteration == 2 && extall) { error_over_large_intervals = errsum; ertest = tolerance; append_table (&table, area); continue; } if (disallow_extrapolation) { continue; } if (extall) { error_over_large_intervals += -last_e_i; if (current_level < workspace->maximum_level) { error_over_large_intervals += error12; } if (extrapolate) goto label70; } if (large_interval(workspace)) { continue; } if (extall) { extrapolate = 1; workspace->nrmax = 1; } else { /* test whether the interval to be bisected next is the smallest interval. */ size_t i = workspace->i; double width = workspace->blist[i] - workspace->alist[i]; if (0.25 * fabs(width) * abs_omega > 2) continue; extall = 1; error_over_large_intervals = errsum; ertest = tolerance; continue; } label70: if (!error_type2 && error_over_large_intervals > ertest) { if (increase_nrmax (workspace)) continue; } /* Perform extrapolation */ append_table (&table, area); if (table.n < 3) { reset_nrmax(workspace); extrapolate = 0; error_over_large_intervals = errsum; continue; } qelg (&table, &reseps, &abseps); ktmin++; if (ktmin > 5 && err_ext < 0.001 * errsum) { error_type = 5; } if (abseps < err_ext) { ktmin = 0; err_ext = abseps; res_ext = reseps; correc = error_over_large_intervals; ertest = GSL_MAX_DBL (epsabs, epsrel * fabs (reseps)); if (err_ext <= ertest) break; } /* Prepare bisection of the smallest interval. */ if (table.n == 1) { disallow_extrapolation = 1; } if (error_type == 5) { break; } /* work on interval with largest error */ reset_nrmax (workspace); extrapolate = 0; error_over_large_intervals = errsum; } while (iteration < limit); *result = res_ext; *abserr = err_ext; if (err_ext == GSL_DBL_MAX) goto compute_result; if (error_type || error_type2) { if (error_type2) { err_ext += correc; } if (error_type == 0) error_type = 3; if (result != 0 && area != 0) { if (err_ext / fabs (res_ext) > errsum / fabs (area)) goto compute_result; } else if (err_ext > errsum) { goto compute_result; } else if (area == 0.0) { goto return_error; } } /* Test on divergence. */ { double max_area = GSL_MAX_DBL (fabs (res_ext), fabs (area)); if (!positive_integrand && max_area < 0.01 * resabs0) goto return_error; } { double ratio = res_ext / area; if (ratio < 0.01 || ratio > 100 || errsum > fabs (area)) error_type = 6; } goto return_error; compute_result: *result = sum_results (workspace); *abserr = errsum; return_error: if (error_type > 2) error_type--; if (error_type == 0) { return GSL_SUCCESS; } else if (error_type == 1) { GSL_ERROR ("number of iterations was insufficient", GSL_EMAXITER); } else if (error_type == 2) { GSL_ERROR ("cannot reach tolerance because of roundoff error", GSL_EROUND); } else if (error_type == 3) { GSL_ERROR ("bad integrand behavior found in the integration interval", GSL_ESING); } else if (error_type == 4) { GSL_ERROR ("roundoff error detected in extrapolation table", GSL_EROUND); } else if (error_type == 5) { GSL_ERROR ("integral is divergent, or slowly convergent", GSL_EDIVERGE); } else if (error_type == -1) { GSL_ERROR ("exceeded limit of trigonometric table", GSL_ETABLE); } else { GSL_ERROR ("could not integrate function", GSL_EFAILED); } } praat-6.0.04/external/gsl/gsl_integration__qaws.c000066400000000000000000000133551261542461700220640ustar00rootroot00000000000000/* integration/qaws.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_integration.h" #include "gsl_integration__initialise.c" #include "gsl_integration__append.c" #include "gsl_integration__qpsrt.c" #include "gsl_integration__util.c" #include "gsl_integration__qc25s.c" int gsl_integration_qaws (gsl_function * f, const double a, const double b, gsl_integration_qaws_table * t, const double epsabs, const double epsrel, const size_t limit, gsl_integration_workspace * workspace, double *result, double *abserr) { double area, errsum; double result0, abserr0; double tolerance; size_t iteration = 0; int roundoff_type1 = 0, roundoff_type2 = 0, error_type = 0; /* Initialize results */ initialise (workspace, a, b); *result = 0; *abserr = 0; if (limit > workspace->limit) { GSL_ERROR ("iteration limit exceeds available workspace", GSL_EINVAL) ; } if (b <= a) { GSL_ERROR ("limits must form an ascending sequence, a < b", GSL_EINVAL) ; } if (epsabs <= 0 && (epsrel < 50 * GSL_DBL_EPSILON || epsrel < 0.5e-28)) { GSL_ERROR ("tolerance cannot be acheived with given epsabs and epsrel", GSL_EBADTOL); } /* perform the first integration */ { double area1, area2; double error1, error2; int err_reliable1, err_reliable2; double a1 = a; double b1 = 0.5 * (a + b); double a2 = b1; double b2 = b; qc25s (f, a, b, a1, b1, t, &area1, &error1, &err_reliable1); qc25s (f, a, b, a2, b2, t, &area2, &error2, &err_reliable2); if (error1 > error2) { append_interval (workspace, a1, b1, area1, error1); append_interval (workspace, a2, b2, area2, error2); } else { append_interval (workspace, a2, b2, area2, error2); append_interval (workspace, a1, b1, area1, error1); } result0 = area1 + area2; abserr0 = error1 + error2; } /* Test on accuracy */ tolerance = GSL_MAX_DBL (epsabs, epsrel * fabs (result0)); /* Test on accuracy, use 0.01 relative error as an extra safety margin on the first iteration (ignored for subsequent iterations) */ if (abserr0 < tolerance && abserr0 < 0.01 * fabs(result0)) { *result = result0; *abserr = abserr0; return GSL_SUCCESS; } else if (limit == 1) { *result = result0; *abserr = abserr0; GSL_ERROR ("a maximum of one iteration was insufficient", GSL_EMAXITER); } area = result0; errsum = abserr0; iteration = 2; do { double a1, b1, a2, b2; double a_i, b_i, r_i, e_i; double area1 = 0, area2 = 0, area12 = 0; double error1 = 0, error2 = 0, error12 = 0; int err_reliable1, err_reliable2; /* Bisect the subinterval with the largest error estimate */ retrieve (workspace, &a_i, &b_i, &r_i, &e_i); a1 = a_i; b1 = 0.5 * (a_i + b_i); a2 = b1; b2 = b_i; qc25s (f, a, b, a1, b1, t, &area1, &error1, &err_reliable1); qc25s (f, a, b, a2, b2, t, &area2, &error2, &err_reliable2); area12 = area1 + area2; error12 = error1 + error2; errsum += (error12 - e_i); area += area12 - r_i; if (err_reliable1 && err_reliable2) { double delta = r_i - area12; if (fabs (delta) <= 1.0e-5 * fabs (area12) && error12 >= 0.99 * e_i) { roundoff_type1++; } if (iteration >= 10 && error12 > e_i) { roundoff_type2++; } } tolerance = GSL_MAX_DBL (epsabs, epsrel * fabs (area)); if (errsum > tolerance) { if (roundoff_type1 >= 6 || roundoff_type2 >= 20) { error_type = 2; /* round off error */ } /* set error flag in the case of bad integrand behaviour at a point of the integration range */ if (subinterval_too_small (a1, a2, b2)) { error_type = 3; } } update (workspace, a1, b1, area1, error1, a2, b2, area2, error2); retrieve (workspace, &a_i, &b_i, &r_i, &e_i); iteration++; } while (iteration < limit && !error_type && errsum > tolerance); *result = sum_results (workspace); *abserr = errsum; if (errsum <= tolerance) { return GSL_SUCCESS; } else if (error_type == 2) { GSL_ERROR ("roundoff error prevents tolerance from being achieved", GSL_EROUND); } else if (error_type == 3) { GSL_ERROR ("bad integrand behavior found in the integration interval", GSL_ESING); } else if (iteration == limit) { GSL_ERROR ("maximum number of subdivisions reached", GSL_EMAXITER); } else { GSL_ERROR ("could not integrate function", GSL_EFAILED); } } praat-6.0.04/external/gsl/gsl_integration__qc25c.c000066400000000000000000000060601261542461700220210ustar00rootroot00000000000000/* integration/qc25c.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ struct fn_cauchy_params { gsl_function *function; double singularity; }; static double fn_cauchy (double t, void *params); static void compute_moments (double cc, double *moment); static void qc25c (gsl_function * f, double a, double b, double c, double *result, double *abserr, int *err_reliable); static void qc25c (gsl_function * f, double a, double b, double c, double *result, double *abserr, int *err_reliable) { double cc = (2 * c - b - a) / (b - a); if (fabs (cc) > 1.1) { double resabs, resasc; gsl_function weighted_function; struct fn_cauchy_params fn_params; fn_params.function = f; fn_params.singularity = c; weighted_function.function = &fn_cauchy; weighted_function.params = &fn_params; gsl_integration_qk15 (&weighted_function, a, b, result, abserr, &resabs, &resasc); if (*abserr == resasc) { *err_reliable = 0; } else { *err_reliable = 1; } return; } else { double cheb12[13], cheb24[25], moment[25]; double res12 = 0, res24 = 0; size_t i; gsl_integration_qcheb (f, a, b, cheb12, cheb24); compute_moments (cc, moment); for (i = 0; i < 13; i++) { res12 += cheb12[i] * moment[i]; } for (i = 0; i < 25; i++) { res24 += cheb24[i] * moment[i]; } *result = res24; *abserr = fabs(res24 - res12) ; *err_reliable = 0; return; } } static double fn_cauchy (double x, void *params) { struct fn_cauchy_params *p = (struct fn_cauchy_params *) params; gsl_function *f = p->function; double c = p->singularity; return GSL_FN_EVAL (f, x) / (x - c); } static void compute_moments (double cc, double *moment) { size_t k; double a0 = log (fabs ((1.0 - cc) / (1.0 + cc))); double a1 = 2 + a0 * cc; moment[0] = a0; moment[1] = a1; for (k = 2; k < 25; k++) { double a2; if ((k % 2) == 0) { a2 = 2.0 * cc * a1 - a0; } else { const double km1 = k - 1.0; a2 = 2.0 * cc * a1 - a0 - 4.0 / (km1 * km1 - 1.0); } moment[k] = a2; a0 = a1; a1 = a2; } } praat-6.0.04/external/gsl/gsl_integration__qc25f.c000066400000000000000000000103511261542461700220220ustar00rootroot00000000000000/* integration/qc25f.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ struct fn_fourier_params { gsl_function *function; double omega; }; static double fn_sin (double t, void *params); static double fn_cos (double t, void *params); static void qc25f (gsl_function * f, double a, double b, gsl_integration_qawo_table * wf, size_t level, double *result, double *abserr, double *resabs, double *resasc); static void qc25f (gsl_function * f, double a, double b, gsl_integration_qawo_table * wf, size_t level, double *result, double *abserr, double *resabs, double *resasc) { const double center = 0.5 * (a + b); const double half_length = 0.5 * (b - a); const double omega = wf->omega ; const double par = omega * half_length; if (fabs (par) < 2) { gsl_function weighted_function; struct fn_fourier_params fn_params; fn_params.function = f; fn_params.omega = omega; if (wf->sine == GSL_INTEG_SINE) { weighted_function.function = &fn_sin; } else { weighted_function.function = &fn_cos; } weighted_function.params = &fn_params; gsl_integration_qk15 (&weighted_function, a, b, result, abserr, resabs, resasc); return; } else { double *moment; double cheb12[13], cheb24[25]; double result_abs, res12_cos, res12_sin, res24_cos, res24_sin; double est_cos, est_sin; double c, s; size_t i; gsl_integration_qcheb (f, a, b, cheb12, cheb24); if (level >= wf->n) { /* table overflow should not happen, check before calling */ GSL_ERROR_VOID("table overflow in internal function", GSL_ESANITY); } /* obtain moments from the table */ moment = wf->chebmo + 25 * level; res12_cos = cheb12[12] * moment[12]; res12_sin = 0 ; for (i = 0; i < 6; i++) { size_t k = 10 - 2 * i; res12_cos += cheb12[k] * moment[k]; res12_sin += cheb12[k + 1] * moment[k + 1]; } res24_cos = cheb24[24] * moment[24]; res24_sin = 0 ; result_abs = fabs(cheb24[24]) ; for (i = 0; i < 12; i++) { size_t k = 22 - 2 * i; res24_cos += cheb24[k] * moment[k]; res24_sin += cheb24[k + 1] * moment[k + 1]; result_abs += fabs(cheb24[k]) + fabs(cheb24[k+1]); } est_cos = fabs(res24_cos - res12_cos); est_sin = fabs(res24_sin - res12_sin); c = half_length * cos(center * omega); s = half_length * sin(center * omega); if (wf->sine == GSL_INTEG_SINE) { *result = c * res24_sin + s * res24_cos; *abserr = fabs(c * est_sin) + fabs(s * est_cos); } else { *result = c * res24_cos - s * res24_sin; *abserr = fabs(c * est_cos) + fabs(s * est_sin); } *resabs = result_abs * half_length; *resasc = GSL_DBL_MAX; return; } } static double fn_sin (double x, void *params) { struct fn_fourier_params *p = (struct fn_fourier_params *) params; gsl_function *f = p->function; double w = p->omega; double wx = w * x; double sinwx = sin(wx) ; return GSL_FN_EVAL (f, x) * sinwx; } static double fn_cos (double x, void *params) { struct fn_fourier_params *p = (struct fn_fourier_params *) params; gsl_function *f = p->function; double w = p->omega; double wx = w * x; double coswx = cos(wx) ; return GSL_FN_EVAL (f, x) * coswx ; } praat-6.0.04/external/gsl/gsl_integration__qc25s.c000066400000000000000000000133271261542461700220450ustar00rootroot00000000000000/* integration/qc25s.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ struct fn_qaws_params { gsl_function *function; double a; double b; gsl_integration_qaws_table *table; }; static double fn_qaws (double t, void *params); static double fn_qaws_L (double x, void *params); static double fn_qaws_R (double x, void *params); static void compute_result (const double * r, const double * cheb12, const double * cheb24, double * result12, double * result24); static void qc25s (gsl_function * f, double a, double b, double a1, double b1, gsl_integration_qaws_table * t, double *result, double *abserr, int *err_reliable); static void qc25s (gsl_function * f, double a, double b, double a1, double b1, gsl_integration_qaws_table * t, double *result, double *abserr, int *err_reliable) { gsl_function weighted_function; struct fn_qaws_params fn_params; fn_params.function = f; fn_params.a = a; fn_params.b = b; fn_params.table = t; weighted_function.params = &fn_params; if (a1 == a && (t->alpha != 0.0 || t->mu != 0)) { double cheb12[13], cheb24[25]; double factor = pow(0.5 * (b1 - a1), t->alpha + 1.0); weighted_function.function = &fn_qaws_R; gsl_integration_qcheb (&weighted_function, a1, b1, cheb12, cheb24); if (t->mu == 0) { double res12 = 0, res24 = 0; double u = factor; compute_result (t->ri, cheb12, cheb24, &res12, &res24); *result = u * res24; *abserr = fabs(u * (res24 - res12)); } else { double res12a = 0, res24a = 0; double res12b = 0, res24b = 0; double u = factor * log(b1 - a1); double v = factor; compute_result (t->ri, cheb12, cheb24, &res12a, &res24a); compute_result (t->rg, cheb12, cheb24, &res12b, &res24b); *result = u * res24a + v * res24b; *abserr = fabs(u * (res24a - res12a)) + fabs(v * (res24b - res12b)); } *err_reliable = 0; return; } else if (b1 == b && (t->beta != 0.0 || t->nu != 0)) { double cheb12[13], cheb24[25]; double factor = pow(0.5 * (b1 - a1), t->beta + 1.0); weighted_function.function = &fn_qaws_L; gsl_integration_qcheb (&weighted_function, a1, b1, cheb12, cheb24); if (t->nu == 0) { double res12 = 0, res24 = 0; double u = factor; compute_result (t->rj, cheb12, cheb24, &res12, &res24); *result = u * res24; *abserr = fabs(u * (res24 - res12)); } else { double res12a = 0, res24a = 0; double res12b = 0, res24b = 0; double u = factor * log(b1 - a1); double v = factor; compute_result (t->rj, cheb12, cheb24, &res12a, &res24a); compute_result (t->rh, cheb12, cheb24, &res12b, &res24b); *result = u * res24a + v * res24b; *abserr = fabs(u * (res24a - res12a)) + fabs(v * (res24b - res12b)); } *err_reliable = 0; return; } else { double resabs, resasc; weighted_function.function = &fn_qaws; gsl_integration_qk15 (&weighted_function, a1, b1, result, abserr, &resabs, &resasc); if (*abserr == resasc) { *err_reliable = 0; } else { *err_reliable = 1; } return; } } static double fn_qaws (double x, void *params) { struct fn_qaws_params *p = (struct fn_qaws_params *) params; gsl_function *f = p->function; gsl_integration_qaws_table *t = p->table; double factor = 1.0; if (t->alpha != 0.0) factor *= pow(x - p->a, t->alpha); if (t->beta != 0.0) factor *= pow(p->b - x, t->beta); if (t->mu == 1) factor *= log(x - p->a); if (t->nu == 1) factor *= log(p->b - x); return factor * GSL_FN_EVAL (f, x); } static double fn_qaws_L (double x, void *params) { struct fn_qaws_params *p = (struct fn_qaws_params *) params; gsl_function *f = p->function; gsl_integration_qaws_table *t = p->table; double factor = 1.0; if (t->alpha != 0.0) factor *= pow(x - p->a, t->alpha); if (t->mu == 1) factor *= log(x - p->a); return factor * GSL_FN_EVAL (f, x); } static double fn_qaws_R (double x, void *params) { struct fn_qaws_params *p = (struct fn_qaws_params *) params; gsl_function *f = p->function; gsl_integration_qaws_table *t = p->table; double factor = 1.0; if (t->beta != 0.0) factor *= pow(p->b - x, t->beta); if (t->nu == 1) factor *= log(p->b - x); return factor * GSL_FN_EVAL (f, x); } static void compute_result (const double * r, const double * cheb12, const double * cheb24, double * result12, double * result24) { size_t i; double res12 = 0; double res24 = 0; for (i = 0; i < 13; i++) { res12 += r[i] * cheb12[i]; } for (i = 0; i < 25; i++) { res24 += r[i] * cheb24[i]; } *result12 = res12; *result24 = res24; } praat-6.0.04/external/gsl/gsl_integration__qcheb.c000066400000000000000000000134101261542461700221630ustar00rootroot00000000000000/* integration/qcheb.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_integration.h" /* This function computes the 12-th order and 24-th order Chebyshev approximations to f(x) on [a,b] */ void gsl_integration_qcheb (gsl_function * f, double a, double b, double *cheb12, double *cheb24) { size_t i; double fval[25], v[12]; /* These are the values of cos(pi*k/24) for k=1..11 needed for the Chebyshev expansion of f(x) */ const double x[11] = { 0.9914448613738104, 0.9659258262890683, 0.9238795325112868, 0.8660254037844386, 0.7933533402912352, 0.7071067811865475, 0.6087614290087206, 0.5000000000000000, 0.3826834323650898, 0.2588190451025208, 0.1305261922200516 }; const double center = 0.5 * (b + a); const double half_length = 0.5 * (b - a); fval[0] = 0.5 * GSL_FN_EVAL (f, b); fval[12] = GSL_FN_EVAL (f, center); fval[24] = 0.5 * GSL_FN_EVAL (f, a); for (i = 1; i < 12; i++) { const size_t j = 24 - i; const double u = half_length * x[i-1]; fval[i] = GSL_FN_EVAL(f, center + u); fval[j] = GSL_FN_EVAL(f, center - u); } for (i = 0; i < 12; i++) { const size_t j = 24 - i; v[i] = fval[i] - fval[j]; fval[i] = fval[i] + fval[j]; } { const double alam1 = v[0] - v[8]; const double alam2 = x[5] * (v[2] - v[6] - v[10]); cheb12[3] = alam1 + alam2; cheb12[9] = alam1 - alam2; } { const double alam1 = v[1] - v[7] - v[9]; const double alam2 = v[3] - v[5] - v[11]; { const double alam = x[2] * alam1 + x[8] * alam2; cheb24[3] = cheb12[3] + alam; cheb24[21] = cheb12[3] - alam; } { const double alam = x[8] * alam1 - x[2] * alam2; cheb24[9] = cheb12[9] + alam; cheb24[15] = cheb12[9] - alam; } } { const double part1 = x[3] * v[4]; const double part2 = x[7] * v[8]; const double part3 = x[5] * v[6]; { const double alam1 = v[0] + part1 + part2; const double alam2 = x[1] * v[2] + part3 + x[9] * v[10]; cheb12[1] = alam1 + alam2; cheb12[11] = alam1 - alam2; } { const double alam1 = v[0] - part1 + part2; const double alam2 = x[9] * v[2] - part3 + x[1] * v[10]; cheb12[5] = alam1 + alam2; cheb12[7] = alam1 - alam2; } } { const double alam = (x[0] * v[1] + x[2] * v[3] + x[4] * v[5] + x[6] * v[7] + x[8] * v[9] + x[10] * v[11]); cheb24[1] = cheb12[1] + alam; cheb24[23] = cheb12[1] - alam; } { const double alam = (x[10] * v[1] - x[8] * v[3] + x[6] * v[5] - x[4] * v[7] + x[2] * v[9] - x[0] * v[11]); cheb24[11] = cheb12[11] + alam; cheb24[13] = cheb12[11] - alam; } { const double alam = (x[4] * v[1] - x[8] * v[3] - x[0] * v[5] - x[10] * v[7] + x[2] * v[9] + x[6] * v[11]); cheb24[5] = cheb12[5] + alam; cheb24[19] = cheb12[5] - alam; } { const double alam = (x[6] * v[1] - x[2] * v[3] - x[10] * v[5] + x[0] * v[7] - x[8] * v[9] - x[4] * v[11]); cheb24[7] = cheb12[7] + alam; cheb24[17] = cheb12[7] - alam; } for (i = 0; i < 6; i++) { const size_t j = 12 - i; v[i] = fval[i] - fval[j]; fval[i] = fval[i] + fval[j]; } { const double alam1 = v[0] + x[7] * v[4]; const double alam2 = x[3] * v[2]; cheb12[2] = alam1 + alam2; cheb12[10] = alam1 - alam2; } cheb12[6] = v[0] - v[4]; { const double alam = x[1] * v[1] + x[5] * v[3] + x[9] * v[5]; cheb24[2] = cheb12[2] + alam; cheb24[22] = cheb12[2] - alam; } { const double alam = x[5] * (v[1] - v[3] - v[5]); cheb24[6] = cheb12[6] + alam; cheb24[18] = cheb12[6] - alam; } { const double alam = x[9] * v[1] - x[5] * v[3] + x[1] * v[5]; cheb24[10] = cheb12[10] + alam; cheb24[14] = cheb12[10] - alam; } for (i = 0; i < 3; i++) { const size_t j = 6 - i; v[i] = fval[i] - fval[j]; fval[i] = fval[i] + fval[j]; } cheb12[4] = v[0] + x[7] * v[2]; cheb12[8] = fval[0] - x[7] * fval[2]; { const double alam = x[3] * v[1]; cheb24[4] = cheb12[4] + alam; cheb24[20] = cheb12[4] - alam; } { const double alam = x[7] * fval[1] - fval[3]; cheb24[8] = cheb12[8] + alam; cheb24[16] = cheb12[8] - alam; } cheb12[0] = fval[0] + fval[2]; { const double alam = fval[1] + fval[3]; cheb24[0] = cheb12[0] + alam; cheb24[24] = cheb12[0] - alam; } cheb12[12] = v[0] - v[2]; cheb24[12] = cheb12[12]; for (i = 1; i < 12; i++) { cheb12[i] *= 1.0 / 6.0; } cheb12[0] *= 1.0 / 12.0; cheb12[12] *= 1.0 / 12.0; for (i = 1; i < 24; i++) { cheb24[i] *= 1.0 / 12.0; } cheb24[0] *= 1.0 / 24.0; cheb24[24] *= 1.0 / 24.0; } praat-6.0.04/external/gsl/gsl_integration__qelg.c000066400000000000000000000131161261542461700220340ustar00rootroot00000000000000/* integration/qelg.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ struct extrapolation_table { size_t n; double rlist2[52]; size_t nres; double res3la[3]; }; static void initialise_table (struct extrapolation_table *table); static void append_table (struct extrapolation_table *table, double y); static void initialise_table (struct extrapolation_table *table) { table->n = 0; table->nres = 0; } #ifdef JUNK static void initialise_table (struct extrapolation_table *table, double y) { table->n = 0; table->rlist2[0] = y; table->nres = 0; } #endif static void append_table (struct extrapolation_table *table, double y) { size_t n; n = table->n; table->rlist2[n] = y; table->n++; } /* static inline void qelg (size_t * n, double epstab[], double * result, double * abserr, double res3la[], size_t * nres); */ static inline void qelg (struct extrapolation_table *table, double *result, double *abserr); static inline void qelg (struct extrapolation_table *table, double *result, double *abserr) { double *epstab = table->rlist2; double *res3la = table->res3la; const size_t n = table->n - 1; const double current = epstab[n]; double absolute = GSL_DBL_MAX; double relative = 5 * GSL_DBL_EPSILON * fabs (current); const size_t newelm = n / 2; const size_t n_orig = n; size_t n_final = n; size_t i; const size_t nres_orig = table->nres; *result = current; *abserr = GSL_DBL_MAX; if (n < 2) { *result = current; *abserr = GSL_MAX_DBL (absolute, relative); return; } epstab[n + 2] = epstab[n]; epstab[n] = GSL_DBL_MAX; for (i = 0; i < newelm; i++) { double res = epstab[n - 2 * i + 2]; double e0 = epstab[n - 2 * i - 2]; double e1 = epstab[n - 2 * i - 1]; double e2 = res; double e1abs = fabs (e1); double delta2 = e2 - e1; double err2 = fabs (delta2); double tol2 = GSL_MAX_DBL (fabs (e2), e1abs) * GSL_DBL_EPSILON; double delta3 = e1 - e0; double err3 = fabs (delta3); double tol3 = GSL_MAX_DBL (e1abs, fabs (e0)) * GSL_DBL_EPSILON; double e3, delta1, err1, tol1, ss; if (err2 <= tol2 && err3 <= tol3) { /* If e0, e1 and e2 are equal to within machine accuracy, convergence is assumed. */ *result = res; absolute = err2 + err3; relative = 5 * GSL_DBL_EPSILON * fabs (res); *abserr = GSL_MAX_DBL (absolute, relative); return; } e3 = epstab[n - 2 * i]; epstab[n - 2 * i] = e1; delta1 = e1 - e3; err1 = fabs (delta1); tol1 = GSL_MAX_DBL (e1abs, fabs (e3)) * GSL_DBL_EPSILON; /* If two elements are very close to each other, omit a part of the table by adjusting the value of n */ if (err1 <= tol1 || err2 <= tol2 || err3 <= tol3) { n_final = 2 * i; break; } ss = (1 / delta1 + 1 / delta2) - 1 / delta3; /* Test to detect irregular behaviour in the table, and eventually omit a part of the table by adjusting the value of n. */ if (fabs (ss * e1) <= 0.0001) { n_final = 2 * i; break; } /* Compute a new element and eventually adjust the value of result. */ res = e1 + 1 / ss; epstab[n - 2 * i] = res; { const double error = err2 + fabs (res - e2) + err3; if (error <= *abserr) { *abserr = error; *result = res; } } } /* Shift the table */ { const size_t limexp = 50 - 1; if (n_final == limexp) { n_final = 2 * (limexp / 2); } } if (n_orig % 2 == 1) { for (i = 0; i <= newelm; i++) { epstab[1 + i * 2] = epstab[i * 2 + 3]; } } else { for (i = 0; i <= newelm; i++) { epstab[i * 2] = epstab[i * 2 + 2]; } } if (n_orig != n_final) { for (i = 0; i <= n_final; i++) { epstab[i] = epstab[n_orig - n_final + i]; } } table->n = n_final + 1; if (nres_orig < 3) { res3la[nres_orig] = *result; *abserr = GSL_DBL_MAX; } else { /* Compute error estimate */ *abserr = (fabs (*result - res3la[2]) + fabs (*result - res3la[1]) + fabs (*result - res3la[0])); res3la[0] = res3la[1]; res3la[1] = res3la[2]; res3la[2] = *result; } /* In QUADPACK the variable table->nres is incremented at the top of qelg, so it increases on every call. This leads to the array res3la being accessed when its elements are still undefined, so I have moved the update to this point so that its value more useful. */ table->nres = nres_orig + 1; *abserr = GSL_MAX_DBL (*abserr, 5 * GSL_DBL_EPSILON * fabs (*result)); return; } praat-6.0.04/external/gsl/gsl_integration__qk.c000066400000000000000000000062301261542461700215160ustar00rootroot00000000000000/* integration/qk.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_integration.h" #include "gsl_integration__err.c" void gsl_integration_qk (const int n, const double xgk[], const double wg[], const double wgk[], double fv1[], double fv2[], const gsl_function * f, double a, double b, double *result, double *abserr, double *resabs, double *resasc) { const double center = 0.5 * (a + b); const double half_length = 0.5 * (b - a); const double abs_half_length = fabs (half_length); const double f_center = GSL_FN_EVAL (f, center); double result_gauss = 0; double result_kronrod = f_center * wgk[n - 1]; double result_abs = fabs (result_kronrod); double result_asc = 0; double mean = 0, err = 0; int j; if (n % 2 == 0) { result_gauss = f_center * wg[n / 2 - 1]; } for (j = 0; j < (n - 1) / 2; j++) { const int jtw = j * 2 + 1; /* j=1,2,3 jtw=2,4,6 */ const double abscissa = half_length * xgk[jtw]; const double fval1 = GSL_FN_EVAL (f, center - abscissa); const double fval2 = GSL_FN_EVAL (f, center + abscissa); const double fsum = fval1 + fval2; fv1[jtw] = fval1; fv2[jtw] = fval2; result_gauss += wg[j] * fsum; result_kronrod += wgk[jtw] * fsum; result_abs += wgk[jtw] * (fabs (fval1) + fabs (fval2)); } for (j = 0; j < n / 2; j++) { int jtwm1 = j * 2; const double abscissa = half_length * xgk[jtwm1]; const double fval1 = GSL_FN_EVAL (f, center - abscissa); const double fval2 = GSL_FN_EVAL (f, center + abscissa); fv1[jtwm1] = fval1; fv2[jtwm1] = fval2; result_kronrod += wgk[jtwm1] * (fval1 + fval2); result_abs += wgk[jtwm1] * (fabs (fval1) + fabs (fval2)); }; mean = result_kronrod * 0.5; result_asc = wgk[n - 1] * fabs (f_center - mean); for (j = 0; j < n - 1; j++) { result_asc += wgk[j] * (fabs (fv1[j] - mean) + fabs (fv2[j] - mean)); } /* scale by the width of the integration region */ err = (result_kronrod - result_gauss) * half_length; result_kronrod *= half_length; result_abs *= abs_half_length; result_asc *= abs_half_length; *result = result_kronrod; *resabs = result_abs; *resasc = result_asc; *abserr = rescale_error (err, result_abs, result_asc); } praat-6.0.04/external/gsl/gsl_integration__qk15.c000066400000000000000000000046511261542461700216710ustar00rootroot00000000000000/* integration/qk15.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_integration.h" /* Gauss quadrature weights and kronrod quadrature abscissae and weights as evaluated with 80 decimal digit arithmetic by L. W. Fullerton, Bell Labs, Nov. 1981. */ static const double xgk[8] = /* abscissae of the 15-point kronrod rule */ { 0.991455371120812639206854697526329, 0.949107912342758524526189684047851, 0.864864423359769072789712788640926, 0.741531185599394439863864773280788, 0.586087235467691130294144838258730, 0.405845151377397166906606412076961, 0.207784955007898467600689403773245, 0.000000000000000000000000000000000 }; /* xgk[1], xgk[3], ... abscissae of the 7-point gauss rule. xgk[0], xgk[2], ... abscissae to optimally extend the 7-point gauss rule */ static const double wg[4] = /* weights of the 7-point gauss rule */ { 0.129484966168869693270611432679082, 0.279705391489276667901467771423780, 0.381830050505118944950369775488975, 0.417959183673469387755102040816327 }; static const double wgk[8] = /* weights of the 15-point kronrod rule */ { 0.022935322010529224963732008058970, 0.063092092629978553290700663189204, 0.104790010322250183839876322541518, 0.140653259715525918745189590510238, 0.169004726639267902826583426598550, 0.190350578064785409913256402421014, 0.204432940075298892414161999234649, 0.209482141084727828012999174891714 }; void gsl_integration_qk15 (const gsl_function * f, double a, double b, double *result, double *abserr, double *resabs, double *resasc) { double fv1[8], fv2[8]; gsl_integration_qk (8, xgk, wg, wgk, fv1, fv2, f, a, b, result, abserr, resabs, resasc); } praat-6.0.04/external/gsl/gsl_integration__qk21.c000066400000000000000000000053401261542461700216620ustar00rootroot00000000000000/* integration/qk21.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_integration.h" /* Gauss quadrature weights and kronrod quadrature abscissae and weights as evaluated with 80 decimal digit arithmetic by L. W. Fullerton, Bell Labs, Nov. 1981. */ static const double xgk[11] = /* abscissae of the 21-point kronrod rule */ { 0.995657163025808080735527280689003, 0.973906528517171720077964012084452, 0.930157491355708226001207180059508, 0.865063366688984510732096688423493, 0.780817726586416897063717578345042, 0.679409568299024406234327365114874, 0.562757134668604683339000099272694, 0.433395394129247190799265943165784, 0.294392862701460198131126603103866, 0.148874338981631210884826001129720, 0.000000000000000000000000000000000 }; /* xgk[1], xgk[3], ... abscissae of the 10-point gauss rule. xgk[0], xgk[2], ... abscissae to optimally extend the 10-point gauss rule */ static const double wg[5] = /* weights of the 10-point gauss rule */ { 0.066671344308688137593568809893332, 0.149451349150580593145776339657697, 0.219086362515982043995534934228163, 0.269266719309996355091226921569469, 0.295524224714752870173892994651338 }; static const double wgk[11] = /* weights of the 21-point kronrod rule */ { 0.011694638867371874278064396062192, 0.032558162307964727478818972459390, 0.054755896574351996031381300244580, 0.075039674810919952767043140916190, 0.093125454583697605535065465083366, 0.109387158802297641899210590325805, 0.123491976262065851077958109831074, 0.134709217311473325928054001771707, 0.142775938577060080797094273138717, 0.147739104901338491374841515972068, 0.149445554002916905664936468389821 }; void gsl_integration_qk21 (const gsl_function * f, double a, double b, double *result, double *abserr, double *resabs, double *resasc) { double fv1[11], fv2[11]; gsl_integration_qk (11, xgk, wg, wgk, fv1, fv2, f, a, b, result, abserr, resabs, resasc); } praat-6.0.04/external/gsl/gsl_integration__qk31.c000066400000000000000000000062721261542461700216700ustar00rootroot00000000000000/* integration/qk31.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_integration.h" /* Gauss quadrature weights and kronrod quadrature abscissae and weights as evaluated with 80 decimal digit arithmetic by L. W. Fullerton, Bell Labs, Nov. 1981. */ static const double xgk[16] = /* abscissae of the 31-point kronrod rule */ { 0.998002298693397060285172840152271, 0.987992518020485428489565718586613, 0.967739075679139134257347978784337, 0.937273392400705904307758947710209, 0.897264532344081900882509656454496, 0.848206583410427216200648320774217, 0.790418501442465932967649294817947, 0.724417731360170047416186054613938, 0.650996741297416970533735895313275, 0.570972172608538847537226737253911, 0.485081863640239680693655740232351, 0.394151347077563369897207370981045, 0.299180007153168812166780024266389, 0.201194093997434522300628303394596, 0.101142066918717499027074231447392, 0.000000000000000000000000000000000 }; /* xgk[1], xgk[3], ... abscissae of the 15-point gauss rule. xgk[0], xgk[2], ... abscissae to optimally extend the 15-point gauss rule */ static const double wg[8] = /* weights of the 15-point gauss rule */ { 0.030753241996117268354628393577204, 0.070366047488108124709267416450667, 0.107159220467171935011869546685869, 0.139570677926154314447804794511028, 0.166269205816993933553200860481209, 0.186161000015562211026800561866423, 0.198431485327111576456118326443839, 0.202578241925561272880620199967519 }; static const double wgk[16] = /* weights of the 31-point kronrod rule */ { 0.005377479872923348987792051430128, 0.015007947329316122538374763075807, 0.025460847326715320186874001019653, 0.035346360791375846222037948478360, 0.044589751324764876608227299373280, 0.053481524690928087265343147239430, 0.062009567800670640285139230960803, 0.069854121318728258709520077099147, 0.076849680757720378894432777482659, 0.083080502823133021038289247286104, 0.088564443056211770647275443693774, 0.093126598170825321225486872747346, 0.096642726983623678505179907627589, 0.099173598721791959332393173484603, 0.100769845523875595044946662617570, 0.101330007014791549017374792767493 }; void gsl_integration_qk31 (const gsl_function * f, double a, double b, double *result, double *abserr, double *resabs, double *resasc) { double fv1[16], fv2[16]; gsl_integration_qk (16, xgk, wg, wgk, fv1, fv2, f, a, b, result, abserr, resabs, resasc); } praat-6.0.04/external/gsl/gsl_integration__qk41.c000066400000000000000000000072571261542461700216750ustar00rootroot00000000000000/* integration/qk41.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_integration.h" /* Gauss quadrature weights and kronrod quadrature abscissae and weights as evaluated with 80 decimal digit arithmetic by L. W. Fullerton, Bell Labs, Nov. 1981. */ static const double xgk[21] = /* abscissae of the 41-point kronrod rule */ { 0.998859031588277663838315576545863, 0.993128599185094924786122388471320, 0.981507877450250259193342994720217, 0.963971927277913791267666131197277, 0.940822633831754753519982722212443, 0.912234428251325905867752441203298, 0.878276811252281976077442995113078, 0.839116971822218823394529061701521, 0.795041428837551198350638833272788, 0.746331906460150792614305070355642, 0.693237656334751384805490711845932, 0.636053680726515025452836696226286, 0.575140446819710315342946036586425, 0.510867001950827098004364050955251, 0.443593175238725103199992213492640, 0.373706088715419560672548177024927, 0.301627868114913004320555356858592, 0.227785851141645078080496195368575, 0.152605465240922675505220241022678, 0.076526521133497333754640409398838, 0.000000000000000000000000000000000 }; /* xgk[1], xgk[3], ... abscissae of the 20-point gauss rule. xgk[0], xgk[2], ... abscissae to optimally extend the 20-point gauss rule */ static const double wg[11] = /* weights of the 20-point gauss rule */ { 0.017614007139152118311861962351853, 0.040601429800386941331039952274932, 0.062672048334109063569506535187042, 0.083276741576704748724758143222046, 0.101930119817240435036750135480350, 0.118194531961518417312377377711382, 0.131688638449176626898494499748163, 0.142096109318382051329298325067165, 0.149172986472603746787828737001969, 0.152753387130725850698084331955098 }; static const double wgk[21] = /* weights of the 41-point kronrod rule */ { 0.003073583718520531501218293246031, 0.008600269855642942198661787950102, 0.014626169256971252983787960308868, 0.020388373461266523598010231432755, 0.025882133604951158834505067096153, 0.031287306777032798958543119323801, 0.036600169758200798030557240707211, 0.041668873327973686263788305936895, 0.046434821867497674720231880926108, 0.050944573923728691932707670050345, 0.055195105348285994744832372419777, 0.059111400880639572374967220648594, 0.062653237554781168025870122174255, 0.065834597133618422111563556969398, 0.068648672928521619345623411885368, 0.071054423553444068305790361723210, 0.073030690332786667495189417658913, 0.074582875400499188986581418362488, 0.075704497684556674659542775376617, 0.076377867672080736705502835038061, 0.076600711917999656445049901530102 }; void gsl_integration_qk41 (const gsl_function * f, double a, double b, double *result, double *abserr, double *resabs, double *resasc) { double fv1[21], fv2[21]; gsl_integration_qk (21, xgk, wg, wgk, fv1, fv2, f, a, b, result, abserr, resabs, resasc); } praat-6.0.04/external/gsl/gsl_integration__qk51.c000066400000000000000000000103461261542461700216670ustar00rootroot00000000000000/* integration/qk51.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_integration.h" /* Gauss quadrature weights and kronrod quadrature abscissae and weights as evaluated with 80 decimal digit arithmetic by L. W. Fullerton, Bell Labs, Nov. 1981. */ static const double xgk[26] = /* abscissae of the 51-point kronrod rule */ { 0.999262104992609834193457486540341, 0.995556969790498097908784946893902, 0.988035794534077247637331014577406, 0.976663921459517511498315386479594, 0.961614986425842512418130033660167, 0.942974571228974339414011169658471, 0.920747115281701561746346084546331, 0.894991997878275368851042006782805, 0.865847065293275595448996969588340, 0.833442628760834001421021108693570, 0.797873797998500059410410904994307, 0.759259263037357630577282865204361, 0.717766406813084388186654079773298, 0.673566368473468364485120633247622, 0.626810099010317412788122681624518, 0.577662930241222967723689841612654, 0.526325284334719182599623778158010, 0.473002731445714960522182115009192, 0.417885382193037748851814394594572, 0.361172305809387837735821730127641, 0.303089538931107830167478909980339, 0.243866883720988432045190362797452, 0.183718939421048892015969888759528, 0.122864692610710396387359818808037, 0.061544483005685078886546392366797, 0.000000000000000000000000000000000 }; /* xgk[1], xgk[3], ... abscissae of the 25-point gauss rule. xgk[0], xgk[2], ... abscissae to optimally extend the 25-point gauss rule */ static const double wg[13] = /* weights of the 25-point gauss rule */ { 0.011393798501026287947902964113235, 0.026354986615032137261901815295299, 0.040939156701306312655623487711646, 0.054904695975835191925936891540473, 0.068038333812356917207187185656708, 0.080140700335001018013234959669111, 0.091028261982963649811497220702892, 0.100535949067050644202206890392686, 0.108519624474263653116093957050117, 0.114858259145711648339325545869556, 0.119455763535784772228178126512901, 0.122242442990310041688959518945852, 0.123176053726715451203902873079050 }; static const double wgk[26] = /* weights of the 51-point kronrod rule */ { 0.001987383892330315926507851882843, 0.005561932135356713758040236901066, 0.009473973386174151607207710523655, 0.013236229195571674813656405846976, 0.016847817709128298231516667536336, 0.020435371145882835456568292235939, 0.024009945606953216220092489164881, 0.027475317587851737802948455517811, 0.030792300167387488891109020215229, 0.034002130274329337836748795229551, 0.037116271483415543560330625367620, 0.040083825504032382074839284467076, 0.042872845020170049476895792439495, 0.045502913049921788909870584752660, 0.047982537138836713906392255756915, 0.050277679080715671963325259433440, 0.052362885806407475864366712137873, 0.054251129888545490144543370459876, 0.055950811220412317308240686382747, 0.057437116361567832853582693939506, 0.058689680022394207961974175856788, 0.059720340324174059979099291932562, 0.060539455376045862945360267517565, 0.061128509717053048305859030416293, 0.061471189871425316661544131965264, 0.061580818067832935078759824240066 }; /* wgk[25] was calculated from the values of wgk[0..24] */ void gsl_integration_qk51 (const gsl_function * f, double a, double b, double *result, double *abserr, double *resabs, double *resasc) { double fv1[26], fv2[26]; gsl_integration_qk (26, xgk, wg, wgk, fv1, fv2, f, a, b, result, abserr, resabs, resasc); } praat-6.0.04/external/gsl/gsl_integration__qk61.c000066400000000000000000000111751261542461700216710ustar00rootroot00000000000000/* integration/qk61.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_integration.h" /* Gauss quadrature weights and kronrod quadrature abscissae and weights as evaluated with 80 decimal digit arithmetic by L. W. Fullerton, Bell Labs, Nov. 1981. */ static const double xgk[31] = /* abscissae of the 61-point kronrod rule */ { 0.999484410050490637571325895705811, 0.996893484074649540271630050918695, 0.991630996870404594858628366109486, 0.983668123279747209970032581605663, 0.973116322501126268374693868423707, 0.960021864968307512216871025581798, 0.944374444748559979415831324037439, 0.926200047429274325879324277080474, 0.905573307699907798546522558925958, 0.882560535792052681543116462530226, 0.857205233546061098958658510658944, 0.829565762382768397442898119732502, 0.799727835821839083013668942322683, 0.767777432104826194917977340974503, 0.733790062453226804726171131369528, 0.697850494793315796932292388026640, 0.660061064126626961370053668149271, 0.620526182989242861140477556431189, 0.579345235826361691756024932172540, 0.536624148142019899264169793311073, 0.492480467861778574993693061207709, 0.447033769538089176780609900322854, 0.400401254830394392535476211542661, 0.352704725530878113471037207089374, 0.304073202273625077372677107199257, 0.254636926167889846439805129817805, 0.204525116682309891438957671002025, 0.153869913608583546963794672743256, 0.102806937966737030147096751318001, 0.051471842555317695833025213166723, 0.000000000000000000000000000000000 }; /* xgk[1], xgk[3], ... abscissae of the 30-point gauss rule. xgk[0], xgk[2], ... abscissae to optimally extend the 30-point gauss rule */ static const double wg[15] = /* weights of the 30-point gauss rule */ { 0.007968192496166605615465883474674, 0.018466468311090959142302131912047, 0.028784707883323369349719179611292, 0.038799192569627049596801936446348, 0.048402672830594052902938140422808, 0.057493156217619066481721689402056, 0.065974229882180495128128515115962, 0.073755974737705206268243850022191, 0.080755895229420215354694938460530, 0.086899787201082979802387530715126, 0.092122522237786128717632707087619, 0.096368737174644259639468626351810, 0.099593420586795267062780282103569, 0.101762389748405504596428952168554, 0.102852652893558840341285636705415 }; static const double wgk[31] = /* weights of the 61-point kronrod rule */ { 0.001389013698677007624551591226760, 0.003890461127099884051267201844516, 0.006630703915931292173319826369750, 0.009273279659517763428441146892024, 0.011823015253496341742232898853251, 0.014369729507045804812451432443580, 0.016920889189053272627572289420322, 0.019414141193942381173408951050128, 0.021828035821609192297167485738339, 0.024191162078080601365686370725232, 0.026509954882333101610601709335075, 0.028754048765041292843978785354334, 0.030907257562387762472884252943092, 0.032981447057483726031814191016854, 0.034979338028060024137499670731468, 0.036882364651821229223911065617136, 0.038678945624727592950348651532281, 0.040374538951535959111995279752468, 0.041969810215164246147147541285970, 0.043452539701356069316831728117073, 0.044814800133162663192355551616723, 0.046059238271006988116271735559374, 0.047185546569299153945261478181099, 0.048185861757087129140779492298305, 0.049055434555029778887528165367238, 0.049795683427074206357811569379942, 0.050405921402782346840893085653585, 0.050881795898749606492297473049805, 0.051221547849258772170656282604944, 0.051426128537459025933862879215781, 0.051494729429451567558340433647099 }; void gsl_integration_qk61 (const gsl_function * f, double a, double b, double *result, double *abserr, double *resabs, double *resasc) { double fv1[31], fv2[31]; gsl_integration_qk (31, xgk, wg, wgk, fv1, fv2, f, a, b, result, abserr, resabs, resasc); } praat-6.0.04/external/gsl/gsl_integration__qmomo.c000066400000000000000000000103741261542461700222370ustar00rootroot00000000000000/* integration/qmomo.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_integration.h" #include "gsl_errno.h" static void initialise (double * ri, double * rj, double * rg, double * rh, double alpha, double beta); gsl_integration_qaws_table * gsl_integration_qaws_table_alloc (double alpha, double beta, int mu, int nu) { gsl_integration_qaws_table * t; if (alpha < -1.0) { GSL_ERROR_VAL ("alpha must be greater than -1.0", GSL_EINVAL, 0); } if (beta < -1.0) { GSL_ERROR_VAL ("beta must be greater than -1.0", GSL_EINVAL, 0); } if (mu != 0 && mu != 1) { GSL_ERROR_VAL ("mu must be 0 or 1", GSL_EINVAL, 0); } if (nu != 0 && nu != 1) { GSL_ERROR_VAL ("nu must be 0 or 1", GSL_EINVAL, 0); } t = (gsl_integration_qaws_table *) malloc(sizeof(gsl_integration_qaws_table)); if (t == 0) { GSL_ERROR_VAL ("failed to allocate space for qaws_table struct", GSL_ENOMEM, 0); } t->alpha = alpha; t->beta = beta; t->mu = mu; t->nu = nu; initialise (t->ri, t->rj, t->rg, t->rh, alpha, beta); return t; } int gsl_integration_qaws_table_set (gsl_integration_qaws_table * t, double alpha, double beta, int mu, int nu) { if (alpha < -1.0) { GSL_ERROR ("alpha must be greater than -1.0", GSL_EINVAL); } if (beta < -1.0) { GSL_ERROR ("beta must be greater than -1.0", GSL_EINVAL); } if (mu != 0 && mu != 1) { GSL_ERROR ("mu must be 0 or 1", GSL_EINVAL); } if (nu != 0 && nu != 1) { GSL_ERROR ("nu must be 0 or 1", GSL_EINVAL); } t->alpha = alpha; t->beta = beta; t->mu = mu; t->nu = nu; initialise (t->ri, t->rj, t->rg, t->rh, alpha, beta); return GSL_SUCCESS; } void gsl_integration_qaws_table_free (gsl_integration_qaws_table * t) { free (t); } static void initialise (double * ri, double * rj, double * rg, double * rh, double alpha, double beta) { const double alpha_p1 = alpha + 1.0; const double beta_p1 = beta + 1.0; const double alpha_p2 = alpha + 2.0; const double beta_p2 = beta + 2.0; const double r_alpha = pow (2.0, alpha_p1); const double r_beta = pow (2.0, beta_p1); size_t i; double an, anm1; ri[0] = r_alpha / alpha_p1; ri[1] = ri[0] * alpha / alpha_p2; an = 2.0; anm1 = 1.0; for (i = 2; i < 25; i++) { ri[i] = -(r_alpha + an * (an - alpha_p2) * ri[i - 1]) / (anm1 * (an + alpha_p1)); anm1 = an; an = an + 1.0; } rj[0] = r_beta / beta_p1; rj[1] = rj[0] * beta / beta_p2; an = 2.0; anm1 = 1.0; for (i = 2; i < 25; i++) { rj[i] = -(r_beta + an * (an - beta_p2) * rj[i - 1]) / (anm1 * (an + beta_p1)); anm1 = an; an = an + 1.0; } rg[0] = -ri[0] / alpha_p1; rg[1] = -rg[0] - 2.0 * r_alpha / (alpha_p2 * alpha_p2); an = 2.0; anm1 = 1.0; for (i = 2; i < 25; i++) { rg[i] = -(an * (an - alpha_p2) * rg[i - 1] - an * ri[i - 1] + anm1 * ri[i]) / (anm1 * (an + alpha_p1)); anm1 = an; an = an + 1.0; } rh[0] = -rj[0] / beta_p1; rh[1] = -rh[0] - 2.0 * r_beta / (beta_p2 * beta_p2); an = 2.0; anm1 = 1.0; for (i = 2; i < 25; i++) { rh[i] = -(an * (an - beta_p2) * rh[i - 1] - an * rj[i - 1] + anm1 * rj[i]) / (anm1 * (an + beta_p1)); anm1 = an; an = an + 1.0; } for (i = 1; i < 25; i += 2) { rj[i] *= -1; rh[i] *= -1; } } praat-6.0.04/external/gsl/gsl_integration__qmomof.c000066400000000000000000000214101261542461700223760ustar00rootroot00000000000000/* integration/qmomof.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_integration.h" #include "gsl_errno.h" static void compute_moments (double par, double * cheb); static int dgtsl (size_t n, double *c, double *d, double *e, double *b); gsl_integration_qawo_table * gsl_integration_qawo_table_alloc (double omega, double L, enum gsl_integration_qawo_enum sine, size_t n) { gsl_integration_qawo_table *t; double * chebmo; if (n == 0) { GSL_ERROR_VAL ("table length n must be positive integer", GSL_EDOM, 0); } t = (gsl_integration_qawo_table *) malloc (sizeof (gsl_integration_qawo_table)); if (t == 0) { GSL_ERROR_VAL ("failed to allocate space for qawo_table struct", GSL_ENOMEM, 0); } chebmo = (double *) malloc (25 * n * sizeof (double)); if (chebmo == 0) { free (t); GSL_ERROR_VAL ("failed to allocate space for chebmo block", GSL_ENOMEM, 0); } t->n = n; t->sine = sine; t->omega = omega; t->L = L; t->par = 0.5 * omega * L; t->chebmo = chebmo; /* precompute the moments */ { size_t i; double scale = 1.0; for (i = 0 ; i < t->n; i++) { compute_moments (t->par * scale, t->chebmo + 25*i); scale *= 0.5; } } return t; } int gsl_integration_qawo_table_set (gsl_integration_qawo_table * t, double omega, double L, enum gsl_integration_qawo_enum sine) { t->omega = omega; t->sine = sine; t->L = L; t->par = 0.5 * omega * L; /* recompute the moments */ { size_t i; double scale = 1.0; for (i = 0 ; i < t->n; i++) { compute_moments (t->par * scale, t->chebmo + 25*i); scale *= 0.5; } } return GSL_SUCCESS; } int gsl_integration_qawo_table_set_length (gsl_integration_qawo_table * t, double L) { /* return immediately if the length is the same as the old length */ if (L == t->L) return GSL_SUCCESS; /* otherwise reset the table and compute the new parameters */ t->L = L; t->par = 0.5 * t->omega * L; /* recompute the moments */ { size_t i; double scale = 1.0; for (i = 0 ; i < t->n; i++) { compute_moments (t->par * scale, t->chebmo + 25*i); scale *= 0.5; } } return GSL_SUCCESS; } void gsl_integration_qawo_table_free (gsl_integration_qawo_table * t) { free (t->chebmo); free (t); } static void compute_moments (double par, double *chebmo) { double v[28], d[25], d1[25], d2[25]; const size_t noeq = 25; const double par2 = par * par; const double par4 = par2 * par2; const double par22 = par2 + 2.0; const double sinpar = sin (par); const double cospar = cos (par); size_t i; /* compute the chebyschev moments with respect to cosine */ double ac = 8 * cospar; double as = 24 * par * sinpar; v[0] = 2 * sinpar / par; v[1] = (8 * cospar + (2 * par2 - 8) * sinpar / par) / par2; v[2] = (32 * (par2 - 12) * cospar + (2 * ((par2 - 80) * par2 + 192) * sinpar) / par) / par4; if (fabs (par) <= 24) { /* compute the moments as the solution of a boundary value problem using the asyptotic expansion as an endpoint */ double an2, ass, asap; double an = 6; size_t k; for (k = 0; k < noeq - 1; k++) { an2 = an * an; d[k] = -2 * (an2 - 4) * (par22 - 2 * an2); d2[k] = (an - 1) * (an - 2) * par2; d1[k + 1] = (an + 3) * (an + 4) * par2; v[k + 3] = as - (an2 - 4) * ac; an = an + 2.0; } an2 = an * an; d[noeq - 1] = -2 * (an2 - 4) * (par22 - 2 * an2); v[noeq + 2] = as - (an2 - 4) * ac; v[3] = v[3] - 56 * par2 * v[2]; ass = par * sinpar; asap = (((((210 * par2 - 1) * cospar - (105 * par2 - 63) * ass) / an2 - (1 - 15 * par2) * cospar + 15 * ass) / an2 - cospar + 3 * ass) / an2 - cospar) / an2; v[noeq + 2] = v[noeq + 2] - 2 * asap * par2 * (an - 1) * (an - 2); dgtsl (noeq, d1, d, d2, v + 3); } else { /* compute the moments by forward recursion */ size_t k; double an = 4; for (k = 3; k < 13; k++) { double an2 = an * an; v[k] = ((an2 - 4) * (2 * (par22 - 2 * an2) * v[k - 1] - ac) + as - par2 * (an + 1) * (an + 2) * v[k - 2]) / (par2 * (an - 1) * (an - 2)); an = an + 2.0; } } for (i = 0; i < 13; i++) { chebmo[2 * i] = v[i]; } /* compute the chebyschev moments with respect to sine */ v[0] = 2 * (sinpar - par * cospar) / par2; v[1] = (18 - 48 / par2) * sinpar / par2 + (-2 + 48 / par2) * cospar / par; ac = -24 * par * cospar; as = -8 * sinpar; if (fabs (par) <= 24) { /* compute the moments as the solution of a boundary value problem using the asyptotic expansion as an endpoint */ size_t k; double an2, ass, asap; double an = 5; for (k = 0; k < noeq - 1; k++) { an2 = an * an; d[k] = -2 * (an2 - 4) * (par22 - 2 * an2); d2[k] = (an - 1) * (an - 2) * par2; d1[k + 1] = (an + 3) * (an + 4) * par2; v[k + 2] = ac + (an2 - 4) * as; an = an + 2.0; } an2 = an * an; d[noeq - 1] = -2 * (an2 - 4) * (par22 - 2 * an2); v[noeq + 1] = ac + (an2 - 4) * as; v[2] = v[2] - 42 * par2 * v[1]; ass = par * cospar; asap = (((((105 * par2 - 63) * ass - (210 * par2 - 1) * sinpar) / an2 + (15 * par2 - 1) * sinpar - 15 * ass) / an2 - sinpar - 3 * ass) / an2 - sinpar) / an2; v[noeq + 1] = v[noeq + 1] - 2 * asap * par2 * (an - 1) * (an - 2); dgtsl (noeq, d1, d, d2, v + 2); } else { /* compute the moments by forward recursion */ size_t k; double an = 3; for (k = 2; k < 12; k++) { double an2 = an * an; v[k] = ((an2 - 4) * (2 * (par22 - 2 * an2) * v[k - 1] + as) + ac - par2 * (an + 1) * (an + 2) * v[k - 2]) / (par2 * (an - 1) * (an - 2)); an = an + 2.0; } } for (i = 0; i < 12; i++) { chebmo[2 * i + 1] = v[i]; } } static int dgtsl (size_t n, double *c, double *d, double *e, double *b) { /* solves a tridiagonal matrix A x = b c[1 .. n - 1] subdiagonal of the matrix A d[0 .. n - 1] diagonal of the matrix A e[0 .. n - 2] superdiagonal of the matrix A b[0 .. n - 1] right hand side, replaced by the solution vector x */ size_t k; c[0] = d[0]; if (n == 0) { return GSL_SUCCESS; } if (n == 1) { b[0] = b[0] / d[0] ; return GSL_SUCCESS; } d[0] = e[0]; e[0] = 0; e[n - 1] = 0; for (k = 0; k < n - 1; k++) { size_t k1 = k + 1; if (fabs (c[k1]) >= fabs (c[k])) { { double t = c[k1]; c[k1] = c[k]; c[k] = t; }; { double t = d[k1]; d[k1] = d[k]; d[k] = t; }; { double t = e[k1]; e[k1] = e[k]; e[k] = t; }; { double t = b[k1]; b[k1] = b[k]; b[k] = t; }; } if (c[k] == 0) { return GSL_FAILURE ; } { double t = -c[k1] / c[k]; c[k1] = d[k1] + t * d[k]; d[k1] = e[k1] + t * e[k]; e[k1] = 0; b[k1] = b[k1] + t * b[k]; } } if (c[n - 1] == 0) { return GSL_FAILURE; } b[n - 1] = b[n - 1] / c[n - 1]; b[n - 2] = (b[n - 2] - d[n - 2] * b[n - 1]) / c[n - 2]; for (k = n ; k > 2; k--) { size_t kb = k - 3; b[kb] = (b[kb] - d[kb] * b[kb + 1] - e[kb] * b[kb + 2]) / c[kb]; } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_integration__qng.c000066400000000000000000000124201261542461700216660ustar00rootroot00000000000000/* integration/qng.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_integration.h" #include "gsl_integration__err.c" #include "gsl_integration__qng.h" int gsl_integration_qng (const gsl_function *f, double a, double b, double epsabs, double epsrel, double * result, double * abserr, size_t * neval) { double fv1[5], fv2[5], fv3[5], fv4[5]; double savfun[21]; /* array of function values which have been computed */ double res10, res21, res43, res87; /* 10, 21, 43 and 87 point results */ double result_kronrod, err ; double resabs; /* approximation to the integral of abs(f) */ double resasc; /* approximation to the integral of abs(f-i/(b-a)) */ const double half_length = 0.5 * (b - a); const double abs_half_length = fabs (half_length); const double center = 0.5 * (b + a); const double f_center = GSL_FN_EVAL(f, center); int k ; if (epsabs <= 0 && (epsrel < 50 * GSL_DBL_EPSILON || epsrel < 0.5e-28)) { * result = 0; * abserr = 0; * neval = 0; GSL_ERROR ("tolerance cannot be acheived with given epsabs and epsrel", GSL_EBADTOL); }; /* Compute the integral using the 10- and 21-point formula. */ res10 = 0; res21 = w21b[5] * f_center; resabs = w21b[5] * fabs (f_center); for (k = 0; k < 5; k++) { const double abscissa = half_length * x1[k]; const double fval1 = GSL_FN_EVAL(f, center + abscissa); const double fval2 = GSL_FN_EVAL(f, center - abscissa); const double fval = fval1 + fval2; res10 += w10[k] * fval; res21 += w21a[k] * fval; resabs += w21a[k] * (fabs (fval1) + fabs (fval2)); savfun[k] = fval; fv1[k] = fval1; fv2[k] = fval2; } for (k = 0; k < 5; k++) { const double abscissa = half_length * x2[k]; const double fval1 = GSL_FN_EVAL(f, center + abscissa); const double fval2 = GSL_FN_EVAL(f, center - abscissa); const double fval = fval1 + fval2; res21 += w21b[k] * fval; resabs += w21b[k] * (fabs (fval1) + fabs (fval2)); savfun[k + 5] = fval; fv3[k] = fval1; fv4[k] = fval2; } resabs *= abs_half_length ; { const double mean = 0.5 * res21; resasc = w21b[5] * fabs (f_center - mean); for (k = 0; k < 5; k++) { resasc += (w21a[k] * (fabs (fv1[k] - mean) + fabs (fv2[k] - mean)) + w21b[k] * (fabs (fv3[k] - mean) + fabs (fv4[k] - mean))); } resasc *= abs_half_length ; } result_kronrod = res21 * half_length; err = rescale_error ((res21 - res10) * half_length, resabs, resasc) ; /* test for convergence. */ if (err < epsabs || err < epsrel * fabs (result_kronrod)) { * result = result_kronrod ; * abserr = err ; * neval = 21; return GSL_SUCCESS; } /* compute the integral using the 43-point formula. */ res43 = w43b[11] * f_center; for (k = 0; k < 10; k++) { res43 += savfun[k] * w43a[k]; } for (k = 0; k < 11; k++) { const double abscissa = half_length * x3[k]; const double fval = (GSL_FN_EVAL(f, center + abscissa) + GSL_FN_EVAL(f, center - abscissa)); res43 += fval * w43b[k]; savfun[k + 10] = fval; } /* test for convergence */ result_kronrod = res43 * half_length; err = rescale_error ((res43 - res21) * half_length, resabs, resasc); if (err < epsabs || err < epsrel * fabs (result_kronrod)) { * result = result_kronrod ; * abserr = err ; * neval = 43; return GSL_SUCCESS; } /* compute the integral using the 87-point formula. */ res87 = w87b[22] * f_center; for (k = 0; k < 21; k++) { res87 += savfun[k] * w87a[k]; } for (k = 0; k < 22; k++) { const double abscissa = half_length * x4[k]; res87 += w87b[k] * (GSL_FN_EVAL(f, center + abscissa) + GSL_FN_EVAL(f, center - abscissa)); } /* test for convergence */ result_kronrod = res87 * half_length ; err = rescale_error ((res87 - res43) * half_length, resabs, resasc); if (err < epsabs || err < epsrel * fabs (result_kronrod)) { * result = result_kronrod ; * abserr = err ; * neval = 87; return GSL_SUCCESS; } /* failed to converge */ * result = result_kronrod ; * abserr = err ; * neval = 87; GSL_ERROR("failed to reach tolerance with highest-order rule", GSL_ETOL) ; } praat-6.0.04/external/gsl/gsl_integration__qng.h000066400000000000000000000154351261542461700217040ustar00rootroot00000000000000/* integration/qng.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Gauss-Kronrod-Patterson quadrature coefficients for use in quadpack routine qng. These coefficients were calculated with 101 decimal digit arithmetic by L. W. Fullerton, Bell Labs, Nov 1981. */ /* x1, abscissae common to the 10-, 21-, 43- and 87-point rule */ static const double x1[5] = { 0.973906528517171720077964012084452, 0.865063366688984510732096688423493, 0.679409568299024406234327365114874, 0.433395394129247190799265943165784, 0.148874338981631210884826001129720 } ; /* w10, weights of the 10-point formula */ static const double w10[5] = { 0.066671344308688137593568809893332, 0.149451349150580593145776339657697, 0.219086362515982043995534934228163, 0.269266719309996355091226921569469, 0.295524224714752870173892994651338 } ; /* x2, abscissae common to the 21-, 43- and 87-point rule */ static const double x2[5] = { 0.995657163025808080735527280689003, 0.930157491355708226001207180059508, 0.780817726586416897063717578345042, 0.562757134668604683339000099272694, 0.294392862701460198131126603103866 } ; /* w21a, weights of the 21-point formula for abscissae x1 */ static const double w21a[5] = { 0.032558162307964727478818972459390, 0.075039674810919952767043140916190, 0.109387158802297641899210590325805, 0.134709217311473325928054001771707, 0.147739104901338491374841515972068 } ; /* w21b, weights of the 21-point formula for abscissae x2 */ static const double w21b[6] = { 0.011694638867371874278064396062192, 0.054755896574351996031381300244580, 0.093125454583697605535065465083366, 0.123491976262065851077958109831074, 0.142775938577060080797094273138717, 0.149445554002916905664936468389821 } ; /* x3, abscissae common to the 43- and 87-point rule */ static const double x3[11] = { 0.999333360901932081394099323919911, 0.987433402908088869795961478381209, 0.954807934814266299257919200290473, 0.900148695748328293625099494069092, 0.825198314983114150847066732588520, 0.732148388989304982612354848755461, 0.622847970537725238641159120344323, 0.499479574071056499952214885499755, 0.364901661346580768043989548502644, 0.222254919776601296498260928066212, 0.074650617461383322043914435796506 } ; /* w43a, weights of the 43-point formula for abscissae x1, x3 */ static const double w43a[10] = { 0.016296734289666564924281974617663, 0.037522876120869501461613795898115, 0.054694902058255442147212685465005, 0.067355414609478086075553166302174, 0.073870199632393953432140695251367, 0.005768556059769796184184327908655, 0.027371890593248842081276069289151, 0.046560826910428830743339154433824, 0.061744995201442564496240336030883, 0.071387267268693397768559114425516 } ; /* w43b, weights of the 43-point formula for abscissae x3 */ static const double w43b[12] = { 0.001844477640212414100389106552965, 0.010798689585891651740465406741293, 0.021895363867795428102523123075149, 0.032597463975345689443882222526137, 0.042163137935191811847627924327955, 0.050741939600184577780189020092084, 0.058379395542619248375475369330206, 0.064746404951445885544689259517511, 0.069566197912356484528633315038405, 0.072824441471833208150939535192842, 0.074507751014175118273571813842889, 0.074722147517403005594425168280423 } ; /* x4, abscissae of the 87-point rule */ static const double x4[22] = { 0.999902977262729234490529830591582, 0.997989895986678745427496322365960, 0.992175497860687222808523352251425, 0.981358163572712773571916941623894, 0.965057623858384619128284110607926, 0.943167613133670596816416634507426, 0.915806414685507209591826430720050, 0.883221657771316501372117548744163, 0.845710748462415666605902011504855, 0.803557658035230982788739474980964, 0.757005730685495558328942793432020, 0.706273209787321819824094274740840, 0.651589466501177922534422205016736, 0.593223374057961088875273770349144, 0.531493605970831932285268948562671, 0.466763623042022844871966781659270, 0.399424847859218804732101665817923, 0.329874877106188288265053371824597, 0.258503559202161551802280975429025, 0.185695396568346652015917141167606, 0.111842213179907468172398359241362, 0.037352123394619870814998165437704 } ; /* w87a, weights of the 87-point formula for abscissae x1, x2, x3 */ static const double w87a[21] = { 0.008148377384149172900002878448190, 0.018761438201562822243935059003794, 0.027347451050052286161582829741283, 0.033677707311637930046581056957588, 0.036935099820427907614589586742499, 0.002884872430211530501334156248695, 0.013685946022712701888950035273128, 0.023280413502888311123409291030404, 0.030872497611713358675466394126442, 0.035693633639418770719351355457044, 0.000915283345202241360843392549948, 0.005399280219300471367738743391053, 0.010947679601118931134327826856808, 0.016298731696787335262665703223280, 0.021081568889203835112433060188190, 0.025370969769253827243467999831710, 0.029189697756475752501446154084920, 0.032373202467202789685788194889595, 0.034783098950365142750781997949596, 0.036412220731351787562801163687577, 0.037253875503047708539592001191226 } ; /* w87b, weights of the 87-point formula for abscissae x4 */ static const double w87b[23] = { 0.000274145563762072350016527092881, 0.001807124155057942948341311753254, 0.004096869282759164864458070683480, 0.006758290051847378699816577897424, 0.009549957672201646536053581325377, 0.012329447652244853694626639963780, 0.015010447346388952376697286041943, 0.017548967986243191099665352925900, 0.019938037786440888202278192730714, 0.022194935961012286796332102959499, 0.024339147126000805470360647041454, 0.026374505414839207241503786552615, 0.028286910788771200659968002987960, 0.030052581128092695322521110347341, 0.031646751371439929404586051078883, 0.033050413419978503290785944862689, 0.034255099704226061787082821046821, 0.035262412660156681033782717998428, 0.036076989622888701185500318003895, 0.036698604498456094498018047441094, 0.037120549269832576114119958413599, 0.037334228751935040321235449094698, 0.037361073762679023410321241766599 } ; praat-6.0.04/external/gsl/gsl_integration__qpsrt.c000066400000000000000000000054561261542461700222650ustar00rootroot00000000000000/* integration/qpsrt.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static inline void qpsrt (gsl_integration_workspace * workspace); static inline void qpsrt (gsl_integration_workspace * workspace) { const size_t last = workspace->size - 1; const size_t limit = workspace->limit; double * elist = workspace->elist; size_t * order = workspace->order; double errmax ; double errmin ; int i, k, top; size_t i_nrmax = workspace->nrmax; size_t i_maxerr = order[i_nrmax] ; /* Check whether the list contains more than two error estimates */ if (last < 2) { order[0] = 0 ; order[1] = 1 ; workspace->i = i_maxerr ; return ; } errmax = elist[i_maxerr] ; /* This part of the routine is only executed if, due to a difficult integrand, subdivision increased the error estimate. In the normal case the insert procedure should start after the nrmax-th largest error estimate. */ while (i_nrmax > 0 && errmax > elist[order[i_nrmax - 1]]) { order[i_nrmax] = order[i_nrmax - 1] ; i_nrmax-- ; } /* Compute the number of elements in the list to be maintained in descending order. This number depends on the number of subdivisions still allowed. */ if(last < (limit/2 + 2)) { top = last ; } else { top = limit - last + 1; } /* Insert errmax by traversing the list top-down, starting comparison from the element elist(order(i_nrmax+1)). */ i = i_nrmax + 1 ; /* The order of the tests in the following line is important to prevent a segmentation fault */ while (i < top && errmax < elist[order[i]]) { order[i-1] = order[i] ; i++ ; } order[i-1] = i_maxerr ; /* Insert errmin by traversing the list bottom-up */ errmin = elist[last] ; k = top - 1 ; while (k > i - 2 && errmin >= elist[order[k]]) { order[k+1] = order[k] ; k-- ; } order[k+1] = last ; /* Set i_max and e_max */ i_maxerr = order[i_nrmax] ; workspace->i = i_maxerr ; workspace->nrmax = i_nrmax ; } praat-6.0.04/external/gsl/gsl_integration__qpsrt2.c000066400000000000000000000037121261542461700223400ustar00rootroot00000000000000/* integration/qpsrt2.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* The smallest interval has the largest error. Before bisecting decrease the sum of the errors over the larger intervals (error_over_large_intervals) and perform extrapolation. */ static int increase_nrmax (gsl_integration_workspace * workspace); static int increase_nrmax (gsl_integration_workspace * workspace) { int k; int id = workspace->nrmax; int jupbnd; const size_t * level = workspace->level; const size_t * order = workspace->order; size_t limit = workspace->limit ; size_t last = workspace->size - 1 ; if (last > (1 + limit / 2)) { jupbnd = limit + 1 - last; } else { jupbnd = last; } for (k = id; k <= jupbnd; k++) { size_t i_max = order[workspace->nrmax]; workspace->i = i_max ; if (level[i_max] < workspace->maximum_level) { return 1; } workspace->nrmax++; } return 0; } static int large_interval (gsl_integration_workspace * workspace) { size_t i = workspace->i ; const size_t * level = workspace->level; if (level[i] < workspace->maximum_level) { return 1 ; } else { return 0 ; } } praat-6.0.04/external/gsl/gsl_integration__reset.c000066400000000000000000000003231261542461700222220ustar00rootroot00000000000000static inline void reset_nrmax (gsl_integration_workspace * workspace); static inline void reset_nrmax (gsl_integration_workspace * workspace) { workspace->nrmax = 0; workspace->i = workspace->order[0] ; } praat-6.0.04/external/gsl/gsl_integration__set_initial.c000066400000000000000000000005461261542461700234130ustar00rootroot00000000000000static inline void set_initial_result (gsl_integration_workspace * workspace, double result, double error); static inline void set_initial_result (gsl_integration_workspace * workspace, double result, double error) { workspace->size = 1; workspace->rlist[0] = result; workspace->elist[0] = error; } praat-6.0.04/external/gsl/gsl_integration__util.c000066400000000000000000000071401261542461700220610ustar00rootroot00000000000000/* integration/util.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static inline void update (gsl_integration_workspace * workspace, double a1, double b1, double area1, double error1, double a2, double b2, double area2, double error2); static inline void retrieve (const gsl_integration_workspace * workspace, double * a, double * b, double * r, double * e); static inline void update (gsl_integration_workspace * workspace, double a1, double b1, double area1, double error1, double a2, double b2, double area2, double error2) { double * alist = workspace->alist ; double * blist = workspace->blist ; double * rlist = workspace->rlist ; double * elist = workspace->elist ; size_t * level = workspace->level ; const size_t i_max = workspace->i ; const size_t i_new = workspace->size ; const size_t new_level = workspace->level[i_max] + 1; /* append the newly-created intervals to the list */ if (error2 > error1) { alist[i_max] = a2; /* blist[maxerr] is already == b2 */ rlist[i_max] = area2; elist[i_max] = error2; level[i_max] = new_level; alist[i_new] = a1; blist[i_new] = b1; rlist[i_new] = area1; elist[i_new] = error1; level[i_new] = new_level; } else { blist[i_max] = b1; /* alist[maxerr] is already == a1 */ rlist[i_max] = area1; elist[i_max] = error1; level[i_max] = new_level; alist[i_new] = a2; blist[i_new] = b2; rlist[i_new] = area2; elist[i_new] = error2; level[i_new] = new_level; } workspace->size++; if (new_level > workspace->maximum_level) { workspace->maximum_level = new_level; } qpsrt (workspace) ; } static inline void retrieve (const gsl_integration_workspace * workspace, double * a, double * b, double * r, double * e) { const size_t i = workspace->i; double * alist = workspace->alist; double * blist = workspace->blist; double * rlist = workspace->rlist; double * elist = workspace->elist; *a = alist[i] ; *b = blist[i] ; *r = rlist[i] ; *e = elist[i] ; } static inline double sum_results (const gsl_integration_workspace * workspace); static inline double sum_results (const gsl_integration_workspace * workspace) { const double * const rlist = workspace->rlist ; const size_t n = workspace->size; size_t k; double result_sum = 0; for (k = 0; k < n; k++) { result_sum += rlist[k]; } return result_sum; } static inline int subinterval_too_small (double a1, double a2, double b2); static inline int subinterval_too_small (double a1, double a2, double b2) { const double e = GSL_DBL_EPSILON; const double u = GSL_DBL_MIN; double tmp = (1 + 100 * e) * (fabs (a2) + 1000 * u); int status = fabs (a1) <= tmp && fabs (b2) <= tmp; return status; } praat-6.0.04/external/gsl/gsl_integration__workspace.c000066400000000000000000000074051261542461700231060ustar00rootroot00000000000000/* integration/workspace.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_integration.h" #include "gsl_errno.h" gsl_integration_workspace * gsl_integration_workspace_alloc (const size_t n) { gsl_integration_workspace * w ; if (n == 0) { GSL_ERROR_VAL ("workspace length n must be positive integer", GSL_EDOM, 0); } w = (gsl_integration_workspace *) malloc (sizeof (gsl_integration_workspace)); if (w == 0) { GSL_ERROR_VAL ("failed to allocate space for workspace struct", GSL_ENOMEM, 0); } w->alist = (double *) malloc (n * sizeof (double)); if (w->alist == 0) { free (w); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for alist ranges", GSL_ENOMEM, 0); } w->blist = (double *) malloc (n * sizeof (double)); if (w->blist == 0) { free (w->alist); free (w); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for blist ranges", GSL_ENOMEM, 0); } w->rlist = (double *) malloc (n * sizeof (double)); if (w->rlist == 0) { free (w->blist); free (w->alist); free (w); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for rlist ranges", GSL_ENOMEM, 0); } w->elist = (double *) malloc (n * sizeof (double)); if (w->elist == 0) { free (w->rlist); free (w->blist); free (w->alist); free (w); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for elist ranges", GSL_ENOMEM, 0); } w->order = (size_t *) malloc (n * sizeof (size_t)); if (w->order == 0) { free (w->elist); free (w->rlist); free (w->blist); free (w->alist); free (w); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for order ranges", GSL_ENOMEM, 0); } w->level = (size_t *) malloc (n * sizeof (size_t)); if (w->level == 0) { free (w->order); free (w->elist); free (w->rlist); free (w->blist); free (w->alist); free (w); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for order ranges", GSL_ENOMEM, 0); } w->size = 0 ; w->limit = n ; w->maximum_level = 0 ; return w ; } void gsl_integration_workspace_free (gsl_integration_workspace * w) { free (w->level) ; free (w->order) ; free (w->elist) ; free (w->rlist) ; free (w->blist) ; free (w->alist) ; free (w) ; } /* size_t gsl_integration_workspace_limit (gsl_integration_workspace * w) { return w->limit ; } size_t gsl_integration_workspace_size (gsl_integration_workspace * w) { return w->size ; } */ praat-6.0.04/external/gsl/gsl_interp.h000066400000000000000000000134131261542461700176500ustar00rootroot00000000000000/* interpolation/gsl_interp.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_INTERP_H__ #define __GSL_INTERP_H__ #include #include "gsl_types.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* evaluation accelerator */ typedef struct { size_t cache; /* cache of index */ size_t miss_count; /* keep statistics */ size_t hit_count; } gsl_interp_accel; /* interpolation object type */ typedef struct { const char * name; unsigned int min_size; void * (*alloc) (size_t size); int (*init) (void *, const double xa[], const double ya[], size_t size); int (*eval) (const void *, const double xa[], const double ya[], size_t size, double x, gsl_interp_accel *, double * y); int (*eval_deriv) (const void *, const double xa[], const double ya[], size_t size, double x, gsl_interp_accel *, double * y_p); int (*eval_deriv2) (const void *, const double xa[], const double ya[], size_t size, double x, gsl_interp_accel *, double * y_pp); int (*eval_integ) (const void *, const double xa[], const double ya[], size_t size, gsl_interp_accel *, double a, double b, double * result); void (*free) (void *); } gsl_interp_type; /* general interpolation object */ typedef struct { const gsl_interp_type * type; double xmin; double xmax; size_t size; void * state; } gsl_interp; /* available types */ GSL_VAR const gsl_interp_type * gsl_interp_linear; GSL_VAR const gsl_interp_type * gsl_interp_polynomial; GSL_VAR const gsl_interp_type * gsl_interp_cspline; GSL_VAR const gsl_interp_type * gsl_interp_cspline_periodic; GSL_VAR const gsl_interp_type * gsl_interp_akima; GSL_VAR const gsl_interp_type * gsl_interp_akima_periodic; gsl_interp_accel * gsl_interp_accel_alloc(void); size_t gsl_interp_accel_find(gsl_interp_accel * a, const double x_array[], size_t size, double x); int gsl_interp_accel_reset (gsl_interp_accel * a); void gsl_interp_accel_free(gsl_interp_accel * a); gsl_interp * gsl_interp_alloc(const gsl_interp_type * T, size_t n); int gsl_interp_init(gsl_interp * obj, const double xa[], const double ya[], size_t size); const char * gsl_interp_name(const gsl_interp * interp); unsigned int gsl_interp_min_size(const gsl_interp * interp); int gsl_interp_eval_e(const gsl_interp * obj, const double xa[], const double ya[], double x, gsl_interp_accel * a, double * y); double gsl_interp_eval(const gsl_interp * obj, const double xa[], const double ya[], double x, gsl_interp_accel * a); int gsl_interp_eval_deriv_e(const gsl_interp * obj, const double xa[], const double ya[], double x, gsl_interp_accel * a, double * d); double gsl_interp_eval_deriv(const gsl_interp * obj, const double xa[], const double ya[], double x, gsl_interp_accel * a); int gsl_interp_eval_deriv2_e(const gsl_interp * obj, const double xa[], const double ya[], double x, gsl_interp_accel * a, double * d2); double gsl_interp_eval_deriv2(const gsl_interp * obj, const double xa[], const double ya[], double x, gsl_interp_accel * a); int gsl_interp_eval_integ_e(const gsl_interp * obj, const double xa[], const double ya[], double a, double b, gsl_interp_accel * acc, double * result); double gsl_interp_eval_integ(const gsl_interp * obj, const double xa[], const double ya[], double a, double b, gsl_interp_accel * acc); void gsl_interp_free(gsl_interp * interp); size_t gsl_interp_bsearch(const double x_array[], double x, size_t index_lo, size_t index_hi); #ifdef HAVE_INLINE extern inline size_t gsl_interp_bsearch(const double x_array[], double x, size_t index_lo, size_t index_hi); extern inline size_t gsl_interp_bsearch(const double x_array[], double x, size_t index_lo, size_t index_hi) { size_t ilo = index_lo; size_t ihi = index_hi; while(ihi > ilo + 1) { size_t i = (ihi + ilo)/2; if(x_array[i] > x) ihi = i; else ilo = i; } return ilo; } #endif #ifdef HAVE_INLINE extern inline size_t gsl_interp_accel_find(gsl_interp_accel * a, const double xa[], size_t len, double x) { size_t x_index = a->cache; if(x < xa[x_index]) { a->miss_count++; a->cache = gsl_interp_bsearch(xa, x, 0, x_index); } else if(x > xa[x_index + 1]) { a->miss_count++; a->cache = gsl_interp_bsearch(xa, x, x_index, len-1); } else { a->hit_count++; } return a->cache; } #endif /* HAVE_INLINE */ __END_DECLS #endif /* __GSL_INTERP_H__ */ praat-6.0.04/external/gsl/gsl_linalg.h000066400000000000000000000504071261542461700176210ustar00rootroot00000000000000/* linalg/gsl_linalg.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2006, 2007 Gerard Jungman, Brian Gough, Patrick Alken * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_LINALG_H__ #define __GSL_LINALG_H__ #include "gsl_mode.h" #include "gsl_permutation.h" #include "gsl_vector.h" #include "gsl_matrix.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS /* empty */ #define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef enum { GSL_LINALG_MOD_NONE = 0, GSL_LINALG_MOD_TRANSPOSE = 1, GSL_LINALG_MOD_CONJUGATE = 2 } gsl_linalg_matrix_mod_t; /* Note: You can now use the gsl_blas_dgemm function instead of matmult */ /* Simple implementation of matrix multiply. * Calculates C = A.B * * exceptions: GSL_EBADLEN */ int gsl_linalg_matmult (const gsl_matrix * A, const gsl_matrix * B, gsl_matrix * C); /* Simple implementation of matrix multiply. * Allows transposition of either matrix, so it * can compute A.B or Trans(A).B or A.Trans(B) or Trans(A).Trans(B) * * exceptions: GSL_EBADLEN */ int gsl_linalg_matmult_mod (const gsl_matrix * A, gsl_linalg_matrix_mod_t modA, const gsl_matrix * B, gsl_linalg_matrix_mod_t modB, gsl_matrix * C); /* Calculate the matrix exponential by the scaling and * squaring method described in Moler + Van Loan, * SIAM Rev 20, 801 (1978). The mode argument allows * choosing an optimal strategy, from the table * given in the paper, for a given precision. * * exceptions: GSL_ENOTSQR, GSL_EBADLEN */ int gsl_linalg_exponential_ss( const gsl_matrix * A, gsl_matrix * eA, gsl_mode_t mode ); /* Householder Transformations */ double gsl_linalg_householder_transform (gsl_vector * v); gsl_complex gsl_linalg_complex_householder_transform (gsl_vector_complex * v); int gsl_linalg_householder_hm (double tau, const gsl_vector * v, gsl_matrix * A); int gsl_linalg_householder_mh (double tau, const gsl_vector * v, gsl_matrix * A); int gsl_linalg_householder_hv (double tau, const gsl_vector * v, gsl_vector * w); int gsl_linalg_householder_hm1 (double tau, gsl_matrix * A); int gsl_linalg_complex_householder_hm (gsl_complex tau, const gsl_vector_complex * v, gsl_matrix_complex * A); int gsl_linalg_complex_householder_mh (gsl_complex tau, const gsl_vector_complex * v, gsl_matrix_complex * A); int gsl_linalg_complex_householder_hv (gsl_complex tau, const gsl_vector_complex * v, gsl_vector_complex * w); /* Hessenberg reduction */ int gsl_linalg_hessenberg_decomp(gsl_matrix *A, gsl_vector *tau); int gsl_linalg_hessenberg_unpack(gsl_matrix * H, gsl_vector * tau, gsl_matrix * U); int gsl_linalg_hessenberg_unpack_accum(gsl_matrix * H, gsl_vector * tau, gsl_matrix * U); int gsl_linalg_hessenberg_set_zero(gsl_matrix * H); int gsl_linalg_hessenberg_submatrix(gsl_matrix *M, gsl_matrix *A, size_t top, gsl_vector *tau); /* Hessenberg-Triangular reduction */ int gsl_linalg_hesstri_decomp(gsl_matrix * A, gsl_matrix * B, gsl_matrix * U, gsl_matrix * V, gsl_vector * work); /* Singular Value Decomposition * exceptions: */ int gsl_linalg_SV_decomp (gsl_matrix * A, gsl_matrix * V, gsl_vector * S, gsl_vector * work); int gsl_linalg_SV_decomp_mod (gsl_matrix * A, gsl_matrix * X, gsl_matrix * V, gsl_vector * S, gsl_vector * work); int gsl_linalg_SV_decomp_jacobi (gsl_matrix * A, gsl_matrix * Q, gsl_vector * S); int gsl_linalg_SV_solve (const gsl_matrix * U, const gsl_matrix * Q, const gsl_vector * S, const gsl_vector * b, gsl_vector * x); /* LU Decomposition, Gaussian elimination with partial pivoting */ int gsl_linalg_LU_decomp (gsl_matrix * A, gsl_permutation * p, int *signum); int gsl_linalg_LU_solve (const gsl_matrix * LU, const gsl_permutation * p, const gsl_vector * b, gsl_vector * x); int gsl_linalg_LU_svx (const gsl_matrix * LU, const gsl_permutation * p, gsl_vector * x); int gsl_linalg_LU_refine (const gsl_matrix * A, const gsl_matrix * LU, const gsl_permutation * p, const gsl_vector * b, gsl_vector * x, gsl_vector * residual); int gsl_linalg_LU_invert (const gsl_matrix * LU, const gsl_permutation * p, gsl_matrix * inverse); double gsl_linalg_LU_det (gsl_matrix * LU, int signum); double gsl_linalg_LU_lndet (gsl_matrix * LU); int gsl_linalg_LU_sgndet (gsl_matrix * lu, int signum); /* Complex LU Decomposition */ int gsl_linalg_complex_LU_decomp (gsl_matrix_complex * A, gsl_permutation * p, int *signum); int gsl_linalg_complex_LU_solve (const gsl_matrix_complex * LU, const gsl_permutation * p, const gsl_vector_complex * b, gsl_vector_complex * x); int gsl_linalg_complex_LU_svx (const gsl_matrix_complex * LU, const gsl_permutation * p, gsl_vector_complex * x); int gsl_linalg_complex_LU_refine (const gsl_matrix_complex * A, const gsl_matrix_complex * LU, const gsl_permutation * p, const gsl_vector_complex * b, gsl_vector_complex * x, gsl_vector_complex * residual); int gsl_linalg_complex_LU_invert (const gsl_matrix_complex * LU, const gsl_permutation * p, gsl_matrix_complex * inverse); gsl_complex gsl_linalg_complex_LU_det (gsl_matrix_complex * LU, int signum); double gsl_linalg_complex_LU_lndet (gsl_matrix_complex * LU); gsl_complex gsl_linalg_complex_LU_sgndet (gsl_matrix_complex * LU, int signum); /* QR decomposition */ int gsl_linalg_QR_decomp (gsl_matrix * A, gsl_vector * tau); int gsl_linalg_QR_solve (const gsl_matrix * QR, const gsl_vector * tau, const gsl_vector * b, gsl_vector * x); int gsl_linalg_QR_svx (const gsl_matrix * QR, const gsl_vector * tau, gsl_vector * x); int gsl_linalg_QR_lssolve (const gsl_matrix * QR, const gsl_vector * tau, const gsl_vector * b, gsl_vector * x, gsl_vector * residual); int gsl_linalg_QR_QRsolve (gsl_matrix * Q, gsl_matrix * R, const gsl_vector * b, gsl_vector * x); int gsl_linalg_QR_Rsolve (const gsl_matrix * QR, const gsl_vector * b, gsl_vector * x); int gsl_linalg_QR_Rsvx (const gsl_matrix * QR, gsl_vector * x); int gsl_linalg_QR_update (gsl_matrix * Q, gsl_matrix * R, gsl_vector * w, const gsl_vector * v); int gsl_linalg_QR_QTvec (const gsl_matrix * QR, const gsl_vector * tau, gsl_vector * v); int gsl_linalg_QR_Qvec (const gsl_matrix * QR, const gsl_vector * tau, gsl_vector * v); int gsl_linalg_QR_QTmat (const gsl_matrix * QR, const gsl_vector * tau, gsl_matrix * A); int gsl_linalg_QR_unpack (const gsl_matrix * QR, const gsl_vector * tau, gsl_matrix * Q, gsl_matrix * R); int gsl_linalg_R_solve (const gsl_matrix * R, const gsl_vector * b, gsl_vector * x); int gsl_linalg_R_svx (const gsl_matrix * R, gsl_vector * x); /* Q R P^T decomposition */ int gsl_linalg_QRPT_decomp (gsl_matrix * A, gsl_vector * tau, gsl_permutation * p, int *signum, gsl_vector * norm); int gsl_linalg_QRPT_decomp2 (const gsl_matrix * A, gsl_matrix * q, gsl_matrix * r, gsl_vector * tau, gsl_permutation * p, int *signum, gsl_vector * norm); int gsl_linalg_QRPT_solve (const gsl_matrix * QR, const gsl_vector * tau, const gsl_permutation * p, const gsl_vector * b, gsl_vector * x); int gsl_linalg_QRPT_svx (const gsl_matrix * QR, const gsl_vector * tau, const gsl_permutation * p, gsl_vector * x); int gsl_linalg_QRPT_QRsolve (const gsl_matrix * Q, const gsl_matrix * R, const gsl_permutation * p, const gsl_vector * b, gsl_vector * x); int gsl_linalg_QRPT_Rsolve (const gsl_matrix * QR, const gsl_permutation * p, const gsl_vector * b, gsl_vector * x); int gsl_linalg_QRPT_Rsvx (const gsl_matrix * QR, const gsl_permutation * p, gsl_vector * x); int gsl_linalg_QRPT_update (gsl_matrix * Q, gsl_matrix * R, const gsl_permutation * p, gsl_vector * u, const gsl_vector * v); /* LQ decomposition */ int gsl_linalg_LQ_decomp (gsl_matrix * A, gsl_vector * tau); int gsl_linalg_LQ_solve_T (const gsl_matrix * LQ, const gsl_vector * tau, const gsl_vector * b, gsl_vector * x); int gsl_linalg_LQ_svx_T (const gsl_matrix * LQ, const gsl_vector * tau, gsl_vector * x); int gsl_linalg_LQ_lssolve_T (const gsl_matrix * LQ, const gsl_vector * tau, const gsl_vector * b, gsl_vector * x, gsl_vector * residual); int gsl_linalg_LQ_Lsolve_T (const gsl_matrix * LQ, const gsl_vector * b, gsl_vector * x); int gsl_linalg_LQ_Lsvx_T (const gsl_matrix * LQ, gsl_vector * x); int gsl_linalg_L_solve_T (const gsl_matrix * L, const gsl_vector * b, gsl_vector * x); int gsl_linalg_LQ_vecQ (const gsl_matrix * LQ, const gsl_vector * tau, gsl_vector * v); int gsl_linalg_LQ_vecQT (const gsl_matrix * LQ, const gsl_vector * tau, gsl_vector * v); int gsl_linalg_LQ_unpack (const gsl_matrix * LQ, const gsl_vector * tau, gsl_matrix * Q, gsl_matrix * L); int gsl_linalg_LQ_update (gsl_matrix * Q, gsl_matrix * R, const gsl_vector * v, gsl_vector * w); int gsl_linalg_LQ_LQsolve (gsl_matrix * Q, gsl_matrix * L, const gsl_vector * b, gsl_vector * x); /* P^T L Q decomposition */ int gsl_linalg_PTLQ_decomp (gsl_matrix * A, gsl_vector * tau, gsl_permutation * p, int *signum, gsl_vector * norm); int gsl_linalg_PTLQ_decomp2 (const gsl_matrix * A, gsl_matrix * q, gsl_matrix * r, gsl_vector * tau, gsl_permutation * p, int *signum, gsl_vector * norm); int gsl_linalg_PTLQ_solve_T (const gsl_matrix * QR, const gsl_vector * tau, const gsl_permutation * p, const gsl_vector * b, gsl_vector * x); int gsl_linalg_PTLQ_svx_T (const gsl_matrix * LQ, const gsl_vector * tau, const gsl_permutation * p, gsl_vector * x); int gsl_linalg_PTLQ_LQsolve_T (const gsl_matrix * Q, const gsl_matrix * L, const gsl_permutation * p, const gsl_vector * b, gsl_vector * x); int gsl_linalg_PTLQ_Lsolve_T (const gsl_matrix * LQ, const gsl_permutation * p, const gsl_vector * b, gsl_vector * x); int gsl_linalg_PTLQ_Lsvx_T (const gsl_matrix * LQ, const gsl_permutation * p, gsl_vector * x); int gsl_linalg_PTLQ_update (gsl_matrix * Q, gsl_matrix * L, const gsl_permutation * p, const gsl_vector * v, gsl_vector * w); /* Cholesky Decomposition */ int gsl_linalg_cholesky_decomp (gsl_matrix * A); int gsl_linalg_cholesky_solve (const gsl_matrix * cholesky, const gsl_vector * b, gsl_vector * x); int gsl_linalg_cholesky_svx (const gsl_matrix * cholesky, gsl_vector * x); /* Cholesky decomposition with unit-diagonal triangular parts. * A = L D L^T, where diag(L) = (1,1,...,1). * Upon exit, A contains L and L^T as for Cholesky, and * the diagonal of A is (1,1,...,1). The vector Dis set * to the diagonal elements of the diagonal matrix D. */ int gsl_linalg_cholesky_decomp_unit(gsl_matrix * A, gsl_vector * D); /* Complex Cholesky Decomposition */ int gsl_linalg_complex_cholesky_decomp (gsl_matrix_complex * A); int gsl_linalg_complex_cholesky_solve (const gsl_matrix_complex * cholesky, const gsl_vector_complex * b, gsl_vector_complex * x); int gsl_linalg_complex_cholesky_svx (const gsl_matrix_complex * cholesky, gsl_vector_complex * x); /* Symmetric to symmetric tridiagonal decomposition */ int gsl_linalg_symmtd_decomp (gsl_matrix * A, gsl_vector * tau); int gsl_linalg_symmtd_unpack (const gsl_matrix * A, const gsl_vector * tau, gsl_matrix * Q, gsl_vector * diag, gsl_vector * subdiag); int gsl_linalg_symmtd_unpack_T (const gsl_matrix * A, gsl_vector * diag, gsl_vector * subdiag); /* Hermitian to symmetric tridiagonal decomposition */ int gsl_linalg_hermtd_decomp (gsl_matrix_complex * A, gsl_vector_complex * tau); int gsl_linalg_hermtd_unpack (const gsl_matrix_complex * A, const gsl_vector_complex * tau, gsl_matrix_complex * Q, gsl_vector * diag, gsl_vector * sudiag); int gsl_linalg_hermtd_unpack_T (const gsl_matrix_complex * A, gsl_vector * diag, gsl_vector * subdiag); /* Linear Solve Using Householder Transformations * exceptions: */ int gsl_linalg_HH_solve (gsl_matrix * A, const gsl_vector * b, gsl_vector * x); int gsl_linalg_HH_svx (gsl_matrix * A, gsl_vector * x); /* Linear solve for a symmetric tridiagonal system. * The input vectors represent the NxN matrix as follows: * * diag[0] offdiag[0] 0 ... * offdiag[0] diag[1] offdiag[1] ... * 0 offdiag[1] diag[2] ... * 0 0 offdiag[2] ... * ... ... ... ... */ int gsl_linalg_solve_symm_tridiag (const gsl_vector * diag, const gsl_vector * offdiag, const gsl_vector * b, gsl_vector * x); /* Linear solve for a nonsymmetric tridiagonal system. * The input vectors represent the NxN matrix as follows: * * diag[0] abovediag[0] 0 ... * belowdiag[0] diag[1] abovediag[1] ... * 0 belowdiag[1] diag[2] ... * 0 0 belowdiag[2] ... * ... ... ... ... */ int gsl_linalg_solve_tridiag (const gsl_vector * diag, const gsl_vector * abovediag, const gsl_vector * belowdiag, const gsl_vector * b, gsl_vector * x); /* Linear solve for a symmetric cyclic tridiagonal system. * The input vectors represent the NxN matrix as follows: * * diag[0] offdiag[0] 0 ..... offdiag[N-1] * offdiag[0] diag[1] offdiag[1] ..... * 0 offdiag[1] diag[2] ..... * 0 0 offdiag[2] ..... * ... ... * offdiag[N-1] ... */ int gsl_linalg_solve_symm_cyc_tridiag (const gsl_vector * diag, const gsl_vector * offdiag, const gsl_vector * b, gsl_vector * x); /* Linear solve for a nonsymmetric cyclic tridiagonal system. * The input vectors represent the NxN matrix as follows: * * diag[0] abovediag[0] 0 ..... belowdiag[N-1] * belowdiag[0] diag[1] abovediag[1] ..... * 0 belowdiag[1] diag[2] * 0 0 belowdiag[2] ..... * ... ... * abovediag[N-1] ... */ int gsl_linalg_solve_cyc_tridiag (const gsl_vector * diag, const gsl_vector * abovediag, const gsl_vector * belowdiag, const gsl_vector * b, gsl_vector * x); /* Bidiagonal decomposition */ int gsl_linalg_bidiag_decomp (gsl_matrix * A, gsl_vector * tau_U, gsl_vector * tau_V); int gsl_linalg_bidiag_unpack (const gsl_matrix * A, const gsl_vector * tau_U, gsl_matrix * U, const gsl_vector * tau_V, gsl_matrix * V, gsl_vector * diag, gsl_vector * superdiag); int gsl_linalg_bidiag_unpack2 (gsl_matrix * A, gsl_vector * tau_U, gsl_vector * tau_V, gsl_matrix * V); int gsl_linalg_bidiag_unpack_B (const gsl_matrix * A, gsl_vector * diag, gsl_vector * superdiag); /* Balancing */ int gsl_linalg_balance_matrix (gsl_matrix * A, gsl_vector * D); int gsl_linalg_balance_accum (gsl_matrix * A, gsl_vector * D); int gsl_linalg_balance_columns (gsl_matrix * A, gsl_vector * D); __END_DECLS #endif /* __GSL_LINALG_H__ */ praat-6.0.04/external/gsl/gsl_linalg__apply_givens.c000066400000000000000000000074331261542461700225340ustar00rootroot00000000000000/* linalg/apply_givens.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2007 Gerard Jungman, Brian Gough * Copyright (C) 2004 Joerg Wensch, modifications for LQ. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ inline static void apply_givens_qr (size_t M, size_t N, gsl_matrix * Q, gsl_matrix * R, size_t i, size_t j, double c, double s) { size_t k; /* Apply rotation to matrix Q, Q' = Q G */ #if USE_BLAS { gsl_matrix_view Q0M = gsl_matrix_submatrix(Q,0,0,M,j+1); gsl_vector_view Qi = gsl_matrix_column(&Q0M.matrix,i); gsl_vector_view Qj = gsl_matrix_column(&Q0M.matrix,j); gsl_blas_drot(&Qi.vector, &Qj.vector, c, -s); } #else for (k = 0; k < M; k++) { double qki = gsl_matrix_get (Q, k, i); double qkj = gsl_matrix_get (Q, k, j); gsl_matrix_set (Q, k, i, qki * c - qkj * s); gsl_matrix_set (Q, k, j, qki * s + qkj * c); } #endif /* Apply rotation to matrix R, R' = G^T R (note: upper triangular so zero for column < row) */ #if USE_BLAS { k = GSL_MIN(i,j); gsl_matrix_view R0 = gsl_matrix_submatrix(R, 0, k, j+1, N-k); gsl_vector_view Ri = gsl_matrix_row(&R0.matrix,i); gsl_vector_view Rj = gsl_matrix_row(&R0.matrix,j); gsl_blas_drot(&Ri.vector, &Rj.vector, c, -s); } #else for (k = GSL_MIN (i, j); k < N; k++) { double rik = gsl_matrix_get (R, i, k); double rjk = gsl_matrix_get (R, j, k); gsl_matrix_set (R, i, k, c * rik - s * rjk); gsl_matrix_set (R, j, k, s * rik + c * rjk); } #endif } inline static void apply_givens_lq (size_t M, size_t N, gsl_matrix * Q, gsl_matrix * L, size_t i, size_t j, double c, double s) { size_t k; /* Apply rotation to matrix Q, Q' = G Q */ #if USE_BLAS { gsl_matrix_view Q0M = gsl_matrix_submatrix(Q,0,0,j+1,M); gsl_vector_view Qi = gsl_matrix_row(&Q0M.matrix,i); gsl_vector_view Qj = gsl_matrix_row(&Q0M.matrix,j); gsl_blas_drot(&Qi.vector, &Qj.vector, c, -s); } #else for (k = 0; k < M; k++) { double qik = gsl_matrix_get (Q, i, k); double qjk = gsl_matrix_get (Q, j, k); gsl_matrix_set (Q, i, k, qik * c - qjk * s); gsl_matrix_set (Q, j, k, qik * s + qjk * c); } #endif /* Apply rotation to matrix L, L' = L G^T (note: lower triangular so zero for column > row) */ #if USE_BLAS { k = GSL_MIN(i,j); gsl_matrix_view L0 = gsl_matrix_submatrix(L, k, 0, N-k, j+1); gsl_vector_view Li = gsl_matrix_column(&L0.matrix,i); gsl_vector_view Lj = gsl_matrix_column(&L0.matrix,j); gsl_blas_drot(&Li.vector, &Lj.vector, c, -s); } #else for (k = GSL_MIN (i, j); k < N; k++) { double lki = gsl_matrix_get (L, k, i); double lkj = gsl_matrix_get (L, k, j); gsl_matrix_set (L, k, i, c * lki - s * lkj); gsl_matrix_set (L, k, j, s * lki + c * lkj); } #endif } inline static void apply_givens_vec (gsl_vector * v, size_t i, size_t j, double c, double s) { /* Apply rotation to vector v' = G^T v */ double vi = gsl_vector_get (v, i); double vj = gsl_vector_get (v, j); gsl_vector_set (v, i, c * vi - s * vj); gsl_vector_set (v, j, s * vi + c * vj); } praat-6.0.04/external/gsl/gsl_linalg__balance.c000066400000000000000000000037071261542461700214210ustar00rootroot00000000000000/* linalg/balance.c * * Copyright (C) 2001, 2004, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Balance a general matrix by scaling the columns * * B = A D * * where D is a diagonal matrix */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_vector.h" #include "gsl_matrix.h" #include "gsl_blas.h" #include "gsl_linalg.h" int gsl_linalg_balance_columns (gsl_matrix * A, gsl_vector * D) { const size_t N = A->size2; size_t j; if (D->size != A->size2) { GSL_ERROR("length of D must match second dimension of A", GSL_EINVAL); } gsl_vector_set_all (D, 1.0); for (j = 0; j < N; j++) { gsl_vector_view A_j = gsl_matrix_column (A, j); double s = gsl_blas_dasum(&A_j.vector); double f = 1.0; if (s == 0.0 || !gsl_finite(s)) { gsl_vector_set (D, j, f); continue; } /* FIXME: we could use frexp() here */ while (s > 1.0) { s /= 2.0; f *= 2.0; } while (s < 0.5) { s *= 2.0; f /= 2.0; } gsl_vector_set (D, j, f); if (f != 1.0) { gsl_blas_dscal(1.0/f, &A_j.vector); } } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_linalg__balancemat.c000066400000000000000000000115531261542461700221210ustar00rootroot00000000000000/* linalg/balance.c * * Copyright (C) 2006 Patrick Alken * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Balance a general matrix by scaling the rows and columns, so the * new row and column norms are the same order of magnitude. * * B = D^-1 A D * * where D is a diagonal matrix * * This is necessary for the unsymmetric eigenvalue problem since the * calculation can become numerically unstable for unbalanced * matrices. * * See Golub & Van Loan, "Matrix Computations" (3rd ed), Section 7.5.7 * and Wilkinson & Reinsch, "Handbook for Automatic Computation", II/11 p320. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_vector.h" #include "gsl_matrix.h" #include "gsl_blas.h" #include "gsl_linalg.h" #define FLOAT_RADIX 2.0 #define FLOAT_RADIX_SQ (FLOAT_RADIX * FLOAT_RADIX) int gsl_linalg_balance_matrix(gsl_matrix * A, gsl_vector * D) { const size_t N = A->size1; if (N != D->size) { GSL_ERROR ("vector must match matrix size", GSL_EBADLEN); } else { double row_norm, col_norm; int not_converged; gsl_vector_view v; /* initialize D to the identity matrix */ gsl_vector_set_all(D, 1.0); not_converged = 1; while (not_converged) { size_t i, j; double g, f, s; not_converged = 0; for (i = 0; i < N; ++i) { row_norm = 0.0; col_norm = 0.0; for (j = 0; j < N; ++j) { if (j != i) { col_norm += fabs(gsl_matrix_get(A, j, i)); row_norm += fabs(gsl_matrix_get(A, i, j)); } } if ((col_norm == 0.0) || (row_norm == 0.0)) { continue; } g = row_norm / FLOAT_RADIX; f = 1.0; s = col_norm + row_norm; /* * find the integer power of the machine radix which * comes closest to balancing the matrix */ while (col_norm < g) { f *= FLOAT_RADIX; col_norm *= FLOAT_RADIX_SQ; } g = row_norm * FLOAT_RADIX; while (col_norm > g) { f /= FLOAT_RADIX; col_norm /= FLOAT_RADIX_SQ; } if ((row_norm + col_norm) < 0.95 * s * f) { not_converged = 1; g = 1.0 / f; /* * apply similarity transformation D, where * D_{ij} = f_i * delta_{ij} */ /* multiply by D^{-1} on the left */ v = gsl_matrix_row(A, i); gsl_blas_dscal(g, &v.vector); /* multiply by D on the right */ v = gsl_matrix_column(A, i); gsl_blas_dscal(f, &v.vector); /* keep track of transformation */ gsl_vector_set(D, i, gsl_vector_get(D, i) * f); } } } return GSL_SUCCESS; } } /* gsl_linalg_balance_matrix() */ /* gsl_linalg_balance_accum() Accumulate a balancing transformation into a matrix. This is used during the computation of Schur vectors since the Schur vectors computed are the vectors for the balanced matrix. We must at some point accumulate the balancing transformation into the Schur vector matrix to get the vectors for the original matrix. A -> D A where D is the diagonal matrix Inputs: A - matrix to transform D - vector containing diagonal elements of D */ int gsl_linalg_balance_accum(gsl_matrix *A, gsl_vector *D) { const size_t N = A->size1; if (N != D->size) { GSL_ERROR ("vector must match matrix size", GSL_EBADLEN); } else { size_t i; double s; gsl_vector_view r; for (i = 0; i < N; ++i) { s = gsl_vector_get(D, i); r = gsl_matrix_row(A, i); gsl_blas_dscal(s, &r.vector); } return GSL_SUCCESS; } } /* gsl_linalg_balance_accum() */ praat-6.0.04/external/gsl/gsl_linalg__bidiag.c000066400000000000000000000236171261542461700212550ustar00rootroot00000000000000/* linalg/bidiag.c * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Factorise a matrix A into * * A = U B V^T * * where U and V are orthogonal and B is upper bidiagonal. * * On exit, B is stored in the diagonal and first superdiagonal of A. * * U is stored as a packed set of Householder transformations in the * lower triangular part of the input matrix below the diagonal. * * V is stored as a packed set of Householder transformations in the * upper triangular part of the input matrix above the first * superdiagonal. * * The full matrix for U can be obtained as the product * * U = U_1 U_2 .. U_N * * where * * U_i = (I - tau_i * u_i * u_i') * * and where u_i is a Householder vector * * u_i = [0, .. , 0, 1, A(i+1,i), A(i+3,i), .. , A(M,i)] * * The full matrix for V can be obtained as the product * * V = V_1 V_2 .. V_(N-2) * * where * * V_i = (I - tau_i * v_i * v_i') * * and where v_i is a Householder vector * * v_i = [0, .. , 0, 1, A(i,i+2), A(i,i+3), .. , A(i,N)] * * See Golub & Van Loan, "Matrix Computations" (3rd ed), Algorithm 5.4.2 * * Note: this description uses 1-based indices. The code below uses * 0-based indices */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_vector.h" #include "gsl_matrix.h" #include "gsl_blas.h" #include "gsl_linalg.h" int gsl_linalg_bidiag_decomp (gsl_matrix * A, gsl_vector * tau_U, gsl_vector * tau_V) { if (A->size1 < A->size2) { GSL_ERROR ("bidiagonal decomposition requires M>=N", GSL_EBADLEN); } else if (tau_U->size != A->size2) { GSL_ERROR ("size of tau_U must be N", GSL_EBADLEN); } else if (tau_V->size + 1 != A->size2) { GSL_ERROR ("size of tau_V must be (N - 1)", GSL_EBADLEN); } else { const size_t M = A->size1; const size_t N = A->size2; size_t i; for (i = 0 ; i < N; i++) { /* Apply Householder transformation to current column */ { gsl_vector_view c = gsl_matrix_column (A, i); gsl_vector_view v = gsl_vector_subvector (&c.vector, i, M - i); double tau_i = gsl_linalg_householder_transform (&v.vector); /* Apply the transformation to the remaining columns */ if (i + 1 < N) { gsl_matrix_view m = gsl_matrix_submatrix (A, i, i + 1, M - i, N - (i + 1)); gsl_linalg_householder_hm (tau_i, &v.vector, &m.matrix); } gsl_vector_set (tau_U, i, tau_i); } /* Apply Householder transformation to current row */ if (i + 1 < N) { gsl_vector_view r = gsl_matrix_row (A, i); gsl_vector_view v = gsl_vector_subvector (&r.vector, i + 1, N - (i + 1)); double tau_i = gsl_linalg_householder_transform (&v.vector); /* Apply the transformation to the remaining rows */ if (i + 1 < M) { gsl_matrix_view m = gsl_matrix_submatrix (A, i+1, i+1, M - (i+1), N - (i+1)); gsl_linalg_householder_mh (tau_i, &v.vector, &m.matrix); } gsl_vector_set (tau_V, i, tau_i); } } } return GSL_SUCCESS; } /* Form the orthogonal matrices U, V, diagonal d and superdiagonal sd from the packed bidiagonal matrix A */ int gsl_linalg_bidiag_unpack (const gsl_matrix * A, const gsl_vector * tau_U, gsl_matrix * U, const gsl_vector * tau_V, gsl_matrix * V, gsl_vector * diag, gsl_vector * superdiag) { const size_t M = A->size1; const size_t N = A->size2; const size_t K = GSL_MIN(M, N); if (M < N) { GSL_ERROR ("matrix A must have M >= N", GSL_EBADLEN); } else if (tau_U->size != K) { GSL_ERROR ("size of tau must be MIN(M,N)", GSL_EBADLEN); } else if (tau_V->size + 1 != K) { GSL_ERROR ("size of tau must be MIN(M,N) - 1", GSL_EBADLEN); } else if (U->size1 != M || U->size2 != N) { GSL_ERROR ("size of U must be M x N", GSL_EBADLEN); } else if (V->size1 != N || V->size2 != N) { GSL_ERROR ("size of V must be N x N", GSL_EBADLEN); } else if (diag->size != K) { GSL_ERROR ("size of diagonal must match size of A", GSL_EBADLEN); } else if (superdiag->size + 1 != K) { GSL_ERROR ("size of subdiagonal must be (diagonal size - 1)", GSL_EBADLEN); } else { size_t i, j; /* Copy diagonal into diag */ for (i = 0; i < N; i++) { double Aii = gsl_matrix_get (A, i, i); gsl_vector_set (diag, i, Aii); } /* Copy superdiagonal into superdiag */ for (i = 0; i < N - 1; i++) { double Aij = gsl_matrix_get (A, i, i+1); gsl_vector_set (superdiag, i, Aij); } /* Initialize V to the identity */ gsl_matrix_set_identity (V); for (i = N - 1; i > 0 && i--;) { /* Householder row transformation to accumulate V */ gsl_vector_const_view r = gsl_matrix_const_row (A, i); gsl_vector_const_view h = gsl_vector_const_subvector (&r.vector, i + 1, N - (i+1)); double ti = gsl_vector_get (tau_V, i); gsl_matrix_view m = gsl_matrix_submatrix (V, i + 1, i + 1, N-(i+1), N-(i+1)); gsl_linalg_householder_hm (ti, &h.vector, &m.matrix); } /* Initialize U to the identity */ gsl_matrix_set_identity (U); for (j = N; j > 0 && j--;) { /* Householder column transformation to accumulate U */ gsl_vector_const_view c = gsl_matrix_const_column (A, j); gsl_vector_const_view h = gsl_vector_const_subvector (&c.vector, j, M - j); double tj = gsl_vector_get (tau_U, j); gsl_matrix_view m = gsl_matrix_submatrix (U, j, j, M-j, N-j); gsl_linalg_householder_hm (tj, &h.vector, &m.matrix); } return GSL_SUCCESS; } } int gsl_linalg_bidiag_unpack2 (gsl_matrix * A, gsl_vector * tau_U, gsl_vector * tau_V, gsl_matrix * V) { const size_t M = A->size1; const size_t N = A->size2; const size_t K = GSL_MIN(M, N); if (M < N) { GSL_ERROR ("matrix A must have M >= N", GSL_EBADLEN); } else if (tau_U->size != K) { GSL_ERROR ("size of tau must be MIN(M,N)", GSL_EBADLEN); } else if (tau_V->size + 1 != K) { GSL_ERROR ("size of tau must be MIN(M,N) - 1", GSL_EBADLEN); } else if (V->size1 != N || V->size2 != N) { GSL_ERROR ("size of V must be N x N", GSL_EBADLEN); } else { size_t i, j; /* Initialize V to the identity */ gsl_matrix_set_identity (V); for (i = N - 1; i > 0 && i--;) { /* Householder row transformation to accumulate V */ gsl_vector_const_view r = gsl_matrix_const_row (A, i); gsl_vector_const_view h = gsl_vector_const_subvector (&r.vector, i + 1, N - (i+1)); double ti = gsl_vector_get (tau_V, i); gsl_matrix_view m = gsl_matrix_submatrix (V, i + 1, i + 1, N-(i+1), N-(i+1)); gsl_linalg_householder_hm (ti, &h.vector, &m.matrix); } /* Copy superdiagonal into tau_v */ for (i = 0; i < N - 1; i++) { double Aij = gsl_matrix_get (A, i, i+1); gsl_vector_set (tau_V, i, Aij); } /* Allow U to be unpacked into the same memory as A, copy diagonal into tau_U */ for (j = N; j > 0 && j--;) { /* Householder column transformation to accumulate U */ double tj = gsl_vector_get (tau_U, j); double Ajj = gsl_matrix_get (A, j, j); gsl_matrix_view m = gsl_matrix_submatrix (A, j, j, M-j, N-j); gsl_vector_set (tau_U, j, Ajj); gsl_linalg_householder_hm1 (tj, &m.matrix); } return GSL_SUCCESS; } } int gsl_linalg_bidiag_unpack_B (const gsl_matrix * A, gsl_vector * diag, gsl_vector * superdiag) { const size_t M = A->size1; const size_t N = A->size2; const size_t K = GSL_MIN(M, N); if (diag->size != K) { GSL_ERROR ("size of diagonal must match size of A", GSL_EBADLEN); } else if (superdiag->size + 1 != K) { GSL_ERROR ("size of subdiagonal must be (matrix size - 1)", GSL_EBADLEN); } else { size_t i; /* Copy diagonal into diag */ for (i = 0; i < K; i++) { double Aii = gsl_matrix_get (A, i, i); gsl_vector_set (diag, i, Aii); } /* Copy superdiagonal into superdiag */ for (i = 0; i < K - 1; i++) { double Aij = gsl_matrix_get (A, i, i+1); gsl_vector_set (superdiag, i, Aij); } return GSL_SUCCESS; } } praat-6.0.04/external/gsl/gsl_linalg__cholesky.c000066400000000000000000000151621261542461700216530ustar00rootroot00000000000000/* Cholesky Decomposition * * Copyright (C) 2000 Thomas Walter * * 03 May 2000: Modified for GSL by Brian Gough * 29 Jul 2005: Additions by Gerard Jungman * Copyright (C) 2000,2001, 2002, 2003, 2005, 2007 Brian Gough, Gerard Jungman * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 3, or (at your option) any * later version. * * This source is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ /* * Cholesky decomposition of a symmetrix positive definite matrix. * This is useful to solve the matrix arising in * periodic cubic splines * approximating splines * * This algorithm does: * A = L * L' * with * L := lower left triangle matrix * L' := the transposed form of L. * */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_vector.h" #include "gsl_matrix.h" #include "gsl_blas.h" #include "gsl_linalg.h" static inline double quiet_sqrt (double x) /* avoids runtime error, for checking matrix for positive definiteness */ { return (x >= 0) ? sqrt(x) : GSL_NAN; } int gsl_linalg_cholesky_decomp (gsl_matrix * A) { const size_t M = A->size1; const size_t N = A->size2; if (M != N) { GSL_ERROR("cholesky decomposition requires square matrix", GSL_ENOTSQR); } else { size_t i,j,k; int status = 0; /* Do the first 2 rows explicitly. It is simple, and faster. And * one can return if the matrix has only 1 or 2 rows. */ double A_00 = gsl_matrix_get (A, 0, 0); double L_00 = quiet_sqrt(A_00); if (A_00 <= 0) { status = GSL_EDOM ; } gsl_matrix_set (A, 0, 0, L_00); if (M > 1) { double A_10 = gsl_matrix_get (A, 1, 0); double A_11 = gsl_matrix_get (A, 1, 1); double L_10 = A_10 / L_00; double diag = A_11 - L_10 * L_10; double L_11 = quiet_sqrt(diag); if (diag <= 0) { status = GSL_EDOM; } gsl_matrix_set (A, 1, 0, L_10); gsl_matrix_set (A, 1, 1, L_11); } for (k = 2; k < M; k++) { double A_kk = gsl_matrix_get (A, k, k); for (i = 0; i < k; i++) { double sum = 0; double A_ki = gsl_matrix_get (A, k, i); double A_ii = gsl_matrix_get (A, i, i); gsl_vector_view ci = gsl_matrix_row (A, i); gsl_vector_view ck = gsl_matrix_row (A, k); if (i > 0) { gsl_vector_view di = gsl_vector_subvector(&ci.vector, 0, i); gsl_vector_view dk = gsl_vector_subvector(&ck.vector, 0, i); gsl_blas_ddot (&di.vector, &dk.vector, &sum); } A_ki = (A_ki - sum) / A_ii; gsl_matrix_set (A, k, i, A_ki); } { gsl_vector_view ck = gsl_matrix_row (A, k); gsl_vector_view dk = gsl_vector_subvector (&ck.vector, 0, k); double sum = gsl_blas_dnrm2 (&dk.vector); double diag = A_kk - sum * sum; double L_kk = quiet_sqrt(diag); if (diag <= 0) { status = GSL_EDOM; } gsl_matrix_set (A, k, k, L_kk); } } /* Now copy the transposed lower triangle to the upper triangle, * the diagonal is common. */ for (i = 1; i < M; i++) { for (j = 0; j < i; j++) { double A_ij = gsl_matrix_get (A, i, j); gsl_matrix_set (A, j, i, A_ij); } } if (status == GSL_EDOM) { GSL_ERROR ("matrix must be positive definite", GSL_EDOM); } return GSL_SUCCESS; } } int gsl_linalg_cholesky_solve (const gsl_matrix * LLT, const gsl_vector * b, gsl_vector * x) { if (LLT->size1 != LLT->size2) { GSL_ERROR ("cholesky matrix must be square", GSL_ENOTSQR); } else if (LLT->size1 != b->size) { GSL_ERROR ("matrix size must match b size", GSL_EBADLEN); } else if (LLT->size2 != x->size) { GSL_ERROR ("matrix size must match solution size", GSL_EBADLEN); } else { /* Copy x <- b */ gsl_vector_memcpy (x, b); /* Solve for c using forward-substitution, L c = b */ gsl_blas_dtrsv (CblasLower, CblasNoTrans, CblasNonUnit, LLT, x); /* Perform back-substitution, U x = c */ gsl_blas_dtrsv (CblasUpper, CblasNoTrans, CblasNonUnit, LLT, x); return GSL_SUCCESS; } } int gsl_linalg_cholesky_svx (const gsl_matrix * LLT, gsl_vector * x) { if (LLT->size1 != LLT->size2) { GSL_ERROR ("cholesky matrix must be square", GSL_ENOTSQR); } else if (LLT->size2 != x->size) { GSL_ERROR ("matrix size must match solution size", GSL_EBADLEN); } else { /* Solve for c using forward-substitution, L c = b */ gsl_blas_dtrsv (CblasLower, CblasNoTrans, CblasNonUnit, LLT, x); /* Perform back-substitution, U x = c */ gsl_blas_dtrsv (CblasUpper, CblasNoTrans, CblasNonUnit, LLT, x); return GSL_SUCCESS; } } int gsl_linalg_cholesky_decomp_unit(gsl_matrix * A, gsl_vector * D) { const size_t N = A->size1; size_t i, j; /* initial Cholesky */ int stat_chol = gsl_linalg_cholesky_decomp(A); if(stat_chol == GSL_SUCCESS) { /* calculate D from diagonal part of initial Cholesky */ for(i = 0; i < N; ++i) { const double C_ii = gsl_matrix_get(A, i, i); gsl_vector_set(D, i, C_ii*C_ii); } /* multiply initial Cholesky by 1/sqrt(D) on the right */ for(i = 0; i < N; ++i) { for(j = 0; j < N; ++j) { gsl_matrix_set(A, i, j, gsl_matrix_get(A, i, j) / sqrt(gsl_vector_get(D, j))); } } /* Because the initial Cholesky contained both L and transpose(L), the result of the multiplication is not symmetric anymore; but the lower triangle _is_ correct. Therefore we reflect it to the upper triangle and declare victory. */ for(i = 0; i < N; ++i) for(j = i + 1; j < N; ++j) gsl_matrix_set(A, i, j, gsl_matrix_get(A, j, i)); } return stat_chol; } praat-6.0.04/external/gsl/gsl_linalg__choleskyc.c000066400000000000000000000131531261542461700220140ustar00rootroot00000000000000/* linalg/choleskyc.c * * Copyright (C) 2007 Patrick Alken * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_matrix.h" #include "gsl_vector.h" #include "gsl_linalg.h" #include "gsl_math.h" #include "gsl_complex.h" #include "gsl_complex_math.h" #include "gsl_blas.h" #include "gsl_errno.h" /* * This module contains routines related to the Cholesky decomposition * of a complex Hermitian positive definite matrix. */ static void cholesky_complex_conj_vector(gsl_vector_complex *v); /* gsl_linalg_complex_cholesky_decomp() Perform the Cholesky decomposition on a Hermitian positive definite matrix. See Golub & Van Loan, "Matrix Computations" (3rd ed), algorithm 4.2.2. Inputs: A - (input/output) complex postive definite matrix Return: success or error The lower triangle of A is overwritten with the Cholesky decomposition */ int gsl_linalg_complex_cholesky_decomp(gsl_matrix_complex *A) { const size_t N = A->size1; if (N != A->size2) { GSL_ERROR("cholesky decomposition requires square matrix", GSL_ENOTSQR); } else { size_t j; gsl_complex z; double ajj; for (j = 0; j < N; ++j) { z = gsl_matrix_complex_get(A, j, j); ajj = GSL_REAL(z); if (j > 0) { gsl_vector_complex_const_view aj = gsl_matrix_complex_const_subrow(A, j, 0, j); gsl_blas_zdotc(&aj.vector, &aj.vector, &z); ajj -= GSL_REAL(z); } if (ajj <= 0.0) { GSL_ERROR("matrix is not positive definite", GSL_EDOM); } ajj = sqrt(ajj); GSL_SET_COMPLEX(&z, ajj, 0.0); gsl_matrix_complex_set(A, j, j, z); if (j < N - 1) { gsl_vector_complex_view av = gsl_matrix_complex_subcolumn(A, j, j + 1, N - j - 1); if (j > 0) { gsl_vector_complex_view aj = gsl_matrix_complex_subrow(A, j, 0, j); gsl_matrix_complex_view am = gsl_matrix_complex_submatrix(A, j + 1, 0, N - j - 1, j); cholesky_complex_conj_vector(&aj.vector); gsl_blas_zgemv(CblasNoTrans, GSL_COMPLEX_NEGONE, &am.matrix, &aj.vector, GSL_COMPLEX_ONE, &av.vector); cholesky_complex_conj_vector(&aj.vector); } gsl_blas_zdscal(1.0 / ajj, &av.vector); } } return GSL_SUCCESS; } } /* gsl_linalg_complex_cholesky_decomp() */ /* gsl_linalg_complex_cholesky_solve() Solve A x = b where A is in cholesky form */ int gsl_linalg_complex_cholesky_solve (const gsl_matrix_complex * cholesky, const gsl_vector_complex * b, gsl_vector_complex * x) { if (cholesky->size1 != cholesky->size2) { GSL_ERROR ("cholesky matrix must be square", GSL_ENOTSQR); } else if (cholesky->size1 != b->size) { GSL_ERROR ("matrix size must match b size", GSL_EBADLEN); } else if (cholesky->size2 != x->size) { GSL_ERROR ("matrix size must match solution size", GSL_EBADLEN); } else { gsl_vector_complex_memcpy (x, b); /* solve for y using forward-substitution, L y = b */ gsl_blas_ztrsv (CblasLower, CblasNoTrans, CblasNonUnit, cholesky, x); /* perform back-substitution, L^H x = y */ gsl_blas_ztrsv (CblasLower, CblasConjTrans, CblasNonUnit, cholesky, x); return GSL_SUCCESS; } } /* gsl_linalg_complex_cholesky_solve() */ /* gsl_linalg_complex_cholesky_svx() Solve A x = b in place where A is in cholesky form */ int gsl_linalg_complex_cholesky_svx (const gsl_matrix_complex * cholesky, gsl_vector_complex * x) { if (cholesky->size1 != cholesky->size2) { GSL_ERROR ("cholesky matrix must be square", GSL_ENOTSQR); } else if (cholesky->size2 != x->size) { GSL_ERROR ("matrix size must match solution size", GSL_EBADLEN); } else { /* solve for y using forward-substitution, L y = b */ gsl_blas_ztrsv (CblasLower, CblasNoTrans, CblasNonUnit, cholesky, x); /* perform back-substitution, L^H x = y */ gsl_blas_ztrsv (CblasLower, CblasConjTrans, CblasNonUnit, cholesky, x); return GSL_SUCCESS; } } /* gsl_linalg_complex_cholesky_svx() */ /******************************************** * INTERNAL ROUTINES * ********************************************/ static void cholesky_complex_conj_vector(gsl_vector_complex *v) { size_t i; for (i = 0; i < v->size; ++i) { gsl_complex z = gsl_vector_complex_get(v, i); gsl_vector_complex_set(v, i, gsl_complex_conjugate(z)); } } /* cholesky_complex_conj_vector() */ praat-6.0.04/external/gsl/gsl_linalg__exponential.c000066400000000000000000000116251261542461700223600ustar00rootroot00000000000000/* linalg/exponential.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ /* Calculate the matrix exponential, following * Moler + Van Loan, SIAM Rev. 20, 801 (1978). */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_mode.h" #include "gsl_errno.h" #include "gsl_blas.h" #include "gsl_linalg.h" /* store one of the suggested choices for the * Taylor series / square method from Moler + VanLoan */ struct moler_vanloan_optimal_suggestion { int k; int j; }; typedef struct moler_vanloan_optimal_suggestion mvl_suggestion_t; /* table from Moler and Van Loan * mvl_tab[gsl_mode_t][matrix_norm_group] */ static mvl_suggestion_t mvl_tab[3][6] = { /* double precision */ { { 5, 1 }, { 5, 4 }, { 7, 5 }, { 9, 7 }, { 10, 10 }, { 8, 14 } }, /* single precision */ { { 2, 1 }, { 4, 0 }, { 7, 1 }, { 6, 5 }, { 5, 9 }, { 7, 11 } }, /* approx precision */ { { 1, 0 }, { 3, 0 }, { 5, 1 }, { 4, 5 }, { 4, 8 }, { 2, 11 } } }; inline static double sup_norm(const gsl_matrix * A) { double min, max; gsl_matrix_minmax(A, &min, &max); return GSL_MAX_DBL(fabs(min), fabs(max)); } static mvl_suggestion_t obtain_suggestion(const gsl_matrix * A, gsl_mode_t mode) { const unsigned int mode_prec = GSL_MODE_PREC(mode); const double norm_A = sup_norm(A); if(norm_A < 0.01) return mvl_tab[mode_prec][0]; else if(norm_A < 0.1) return mvl_tab[mode_prec][1]; else if(norm_A < 1.0) return mvl_tab[mode_prec][2]; else if(norm_A < 10.0) return mvl_tab[mode_prec][3]; else if(norm_A < 100.0) return mvl_tab[mode_prec][4]; else if(norm_A < 1000.0) return mvl_tab[mode_prec][5]; else { /* outside the table we simply increase the number * of squarings, bringing the reduced matrix into * the range of the table; this is obviously suboptimal, * but that is the price paid for not having those extra * table entries */ const double extra = log(1.01*norm_A/1000.0) / M_LN2; const int extra_i = (unsigned int) ceil(extra); mvl_suggestion_t s = mvl_tab[mode][5]; s.j += extra_i; return s; } } /* use series representation to calculate matrix exponential; * this is used for small matrices; we use the sup_norm * to measure the size of the terms in the expansion */ static void matrix_exp_series( const gsl_matrix * B, gsl_matrix * eB, int number_of_terms ) { int count; gsl_matrix * temp = gsl_matrix_calloc(B->size1, B->size2); /* init the Horner polynomial evaluation, * eB = 1 + B/number_of_terms; we use * eB to collect the partial results */ gsl_matrix_memcpy(eB, B); gsl_matrix_scale(eB, 1.0/number_of_terms); gsl_matrix_add_diagonal(eB, 1.0); for(count = number_of_terms-1; count >= 1; --count) { /* mult_temp = 1 + B eB / count */ gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, B, eB, 0.0, temp); gsl_matrix_scale(temp, 1.0/count); gsl_matrix_add_diagonal(temp, 1.0); /* transfer partial result out of temp */ gsl_matrix_memcpy(eB, temp); } /* now eB holds the full result; we're done */ gsl_matrix_free(temp); } int gsl_linalg_exponential_ss( const gsl_matrix * A, gsl_matrix * eA, gsl_mode_t mode ) { if(A->size1 != A->size2) { GSL_ERROR("cannot exponentiate a non-square matrix", GSL_ENOTSQR); } else if(A->size1 != eA->size1 || A->size2 != eA->size2) { GSL_ERROR("exponential of matrix must have same dimension as matrix", GSL_EBADLEN); } else { int i; const mvl_suggestion_t sugg = obtain_suggestion(A, mode); const double divisor = exp(M_LN2 * sugg.j); gsl_matrix * reduced_A = gsl_matrix_alloc(A->size1, A->size2); /* decrease A by the calculated divisor */ gsl_matrix_memcpy(reduced_A, A); gsl_matrix_scale(reduced_A, 1.0/divisor); /* calculate exp of reduced matrix; store in eA as temp */ matrix_exp_series(reduced_A, eA, sugg.k); /* square repeatedly; use reduced_A for scratch */ for(i = 0; i < sugg.j; ++i) { gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, eA, eA, 0.0, reduced_A); gsl_matrix_memcpy(eA, reduced_A); } gsl_matrix_free(reduced_A); return GSL_SUCCESS; } } praat-6.0.04/external/gsl/gsl_linalg__givens.c000066400000000000000000000025511261542461700213230ustar00rootroot00000000000000/* linalg/givens.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Generate a Givens rotation (cos,sin) which takes v=(x,y) to (|v|,0) From Golub and Van Loan, "Matrix Computations", Section 5.1.8 */ inline static void create_givens (const double a, const double b, double *c, double *s) { if (b == 0) { *c = 1; *s = 0; } else if (fabs (b) > fabs (a)) { double t = -a / b; double s1 = 1.0 / sqrt (1 + t * t); *s = s1; *c = s1 * t; } else { double t = -b / a; double c1 = 1.0 / sqrt (1 + t * t); *c = c1; *s = c1 * t; } } praat-6.0.04/external/gsl/gsl_linalg__hermtd.c000066400000000000000000000162121261542461700213120ustar00rootroot00000000000000/* linalg/hermtd.c * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Factorise a hermitian matrix A into * * A = U T U' * * where U is unitary and T is real symmetric tridiagonal. Only the * diagonal and lower triangular part of A is referenced and modified. * * On exit, T is stored in the diagonal and first subdiagonal of * A. Since T is symmetric the upper diagonal is not stored. * * U is stored as a packed set of Householder transformations in the * lower triangular part of the input matrix below the first subdiagonal. * * The full matrix for Q can be obtained as the product * * Q = Q_N ... Q_2 Q_1 * * where * * Q_i = (I - tau_i * v_i * v_i') * * and where v_i is a Householder vector * * v_i = [0, ..., 0, 1, A(i+2,i), A(i+3,i), ... , A(N,i)] * * This storage scheme is the same as in LAPACK. See LAPACK's * chetd2.f for details. * * See Golub & Van Loan, "Matrix Computations" (3rd ed), Section 8.3 */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_vector.h" #include "gsl_matrix.h" #include "gsl_blas.h" #include "gsl_complex_math.h" #include "gsl_linalg.h" int gsl_linalg_hermtd_decomp (gsl_matrix_complex * A, gsl_vector_complex * tau) { if (A->size1 != A->size2) { GSL_ERROR ("hermitian tridiagonal decomposition requires square matrix", GSL_ENOTSQR); } else if (tau->size + 1 != A->size1) { GSL_ERROR ("size of tau must be (matrix size - 1)", GSL_EBADLEN); } else { const size_t N = A->size1; size_t i; const gsl_complex zero = gsl_complex_rect (0.0, 0.0); const gsl_complex one = gsl_complex_rect (1.0, 0.0); const gsl_complex neg_one = gsl_complex_rect (-1.0, 0.0); for (i = 0 ; i < N - 1; i++) { gsl_vector_complex_view c = gsl_matrix_complex_column (A, i); gsl_vector_complex_view v = gsl_vector_complex_subvector (&c.vector, i + 1, N - (i + 1)); gsl_complex tau_i = gsl_linalg_complex_householder_transform (&v.vector); /* Apply the transformation H^T A H to the remaining columns */ if ((i + 1) < (N - 1) && !(GSL_REAL(tau_i) == 0.0 && GSL_IMAG(tau_i) == 0.0)) { gsl_matrix_complex_view m = gsl_matrix_complex_submatrix (A, i + 1, i + 1, N - (i+1), N - (i+1)); gsl_complex ei = gsl_vector_complex_get(&v.vector, 0); gsl_vector_complex_view x = gsl_vector_complex_subvector (tau, i, N-(i+1)); gsl_vector_complex_set (&v.vector, 0, one); /* x = tau * A * v */ gsl_blas_zhemv (CblasLower, tau_i, &m.matrix, &v.vector, zero, &x.vector); /* w = x - (1/2) tau * (x' * v) * v */ { gsl_complex xv, txv, alpha; gsl_blas_zdotc(&x.vector, &v.vector, &xv); txv = gsl_complex_mul(tau_i, xv); alpha = gsl_complex_mul_real(txv, -0.5); gsl_blas_zaxpy(alpha, &v.vector, &x.vector); } /* apply the transformation A = A - v w' - w v' */ gsl_blas_zher2(CblasLower, neg_one, &v.vector, &x.vector, &m.matrix); gsl_vector_complex_set (&v.vector, 0, ei); } gsl_vector_complex_set (tau, i, tau_i); } return GSL_SUCCESS; } } /* Form the orthogonal matrix Q from the packed QR matrix */ int gsl_linalg_hermtd_unpack (const gsl_matrix_complex * A, const gsl_vector_complex * tau, gsl_matrix_complex * Q, gsl_vector * diag, gsl_vector * sdiag) { if (A->size1 != A->size2) { GSL_ERROR ("matrix A must be sqaure", GSL_ENOTSQR); } else if (tau->size + 1 != A->size1) { GSL_ERROR ("size of tau must be (matrix size - 1)", GSL_EBADLEN); } else if (Q->size1 != A->size1 || Q->size2 != A->size1) { GSL_ERROR ("size of Q must match size of A", GSL_EBADLEN); } else if (diag->size != A->size1) { GSL_ERROR ("size of diagonal must match size of A", GSL_EBADLEN); } else if (sdiag->size + 1 != A->size1) { GSL_ERROR ("size of subdiagonal must be (matrix size - 1)", GSL_EBADLEN); } else { const size_t N = A->size1; size_t i; /* Initialize Q to the identity */ gsl_matrix_complex_set_identity (Q); for (i = N - 1; i > 0 && i--;) { gsl_complex ti = gsl_vector_complex_get (tau, i); gsl_vector_complex_const_view c = gsl_matrix_complex_const_column (A, i); gsl_vector_complex_const_view h = gsl_vector_complex_const_subvector (&c.vector, i + 1, N - (i+1)); gsl_matrix_complex_view m = gsl_matrix_complex_submatrix (Q, i + 1, i + 1, N-(i+1), N-(i+1)); gsl_linalg_complex_householder_hm (ti, &h.vector, &m.matrix); } /* Copy diagonal into diag */ for (i = 0; i < N; i++) { gsl_complex Aii = gsl_matrix_complex_get (A, i, i); gsl_vector_set (diag, i, GSL_REAL(Aii)); } /* Copy subdiagonal into sdiag */ for (i = 0; i < N - 1; i++) { gsl_complex Aji = gsl_matrix_complex_get (A, i+1, i); gsl_vector_set (sdiag, i, GSL_REAL(Aji)); } return GSL_SUCCESS; } } int gsl_linalg_hermtd_unpack_T (const gsl_matrix_complex * A, gsl_vector * diag, gsl_vector * sdiag) { if (A->size1 != A->size2) { GSL_ERROR ("matrix A must be sqaure", GSL_ENOTSQR); } else if (diag->size != A->size1) { GSL_ERROR ("size of diagonal must match size of A", GSL_EBADLEN); } else if (sdiag->size + 1 != A->size1) { GSL_ERROR ("size of subdiagonal must be (matrix size - 1)", GSL_EBADLEN); } else { const size_t N = A->size1; size_t i; /* Copy diagonal into diag */ for (i = 0; i < N; i++) { gsl_complex Aii = gsl_matrix_complex_get (A, i, i); gsl_vector_set (diag, i, GSL_REAL(Aii)); } /* Copy subdiagonal into sd */ for (i = 0; i < N - 1; i++) { gsl_complex Aji = gsl_matrix_complex_get (A, i+1, i); gsl_vector_set (sdiag, i, GSL_REAL(Aji)); } return GSL_SUCCESS; } } praat-6.0.04/external/gsl/gsl_linalg__hessenberg.c000066400000000000000000000310011261542461700221450ustar00rootroot00000000000000/* linalg/hessenberg.c * * Copyright (C) 2006 Patrick Alken * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_linalg.h" #include "gsl_matrix.h" #include "gsl_vector.h" /* gsl_linalg_hessenberg_decomp() Compute the Householder reduction to Hessenberg form of a square N-by-N matrix A. H = U^t A U See Golub & Van Loan, "Matrix Computations" (3rd ed), algorithm 7.4.2 Inputs: A - matrix to reduce tau - where to store scalar factors in Householder matrices; this vector must be of length N, where N is the order of A Return: GSL_SUCCESS unless error occurs Notes: on output, the upper triangular portion of A (including the diagaonal and subdiagonal) contains the Hessenberg matrix. The lower triangular portion (below the subdiagonal) contains the Householder vectors which can be used to construct the similarity transform matrix U. The matrix U is U = U(1) U(2) ... U(n - 2) where U(i) = I - tau(i) * v(i) * v(i)^t and the vector v(i) is stored in column i of the matrix A underneath the subdiagonal. So the first element of v(i) is stored in row i + 2, column i, the second element at row i + 3, column i, and so on. Also note that for the purposes of computing U(i), v(1:i) = 0, v(i + 1) = 1, and v(i+2:n) is what is stored in column i of A beneath the subdiagonal. */ int gsl_linalg_hessenberg_decomp(gsl_matrix *A, gsl_vector *tau) { const size_t N = A->size1; if (N != A->size2) { GSL_ERROR ("Hessenberg reduction requires square matrix", GSL_ENOTSQR); } else if (N != tau->size) { GSL_ERROR ("tau vector must match matrix size", GSL_EBADLEN); } else if (N < 3) { /* nothing to do */ return GSL_SUCCESS; } else { size_t i; /* looping */ gsl_vector_view c, /* matrix column */ hv; /* householder vector */ gsl_matrix_view m; double tau_i; /* beta in algorithm 7.4.2 */ for (i = 0; i < N - 2; ++i) { /* * make a copy of A(i + 1:n, i) and store it in the section * of 'tau' that we haven't stored coefficients in yet */ c = gsl_matrix_subcolumn(A, i, i + 1, N - i - 1); hv = gsl_vector_subvector(tau, i + 1, N - (i + 1)); gsl_vector_memcpy(&hv.vector, &c.vector); /* compute householder transformation of A(i+1:n,i) */ tau_i = gsl_linalg_householder_transform(&hv.vector); /* apply left householder matrix (I - tau_i v v') to A */ m = gsl_matrix_submatrix(A, i + 1, i, N - (i + 1), N - i); gsl_linalg_householder_hm(tau_i, &hv.vector, &m.matrix); /* apply right householder matrix (I - tau_i v v') to A */ m = gsl_matrix_submatrix(A, 0, i + 1, N, N - (i + 1)); gsl_linalg_householder_mh(tau_i, &hv.vector, &m.matrix); /* save Householder coefficient */ gsl_vector_set(tau, i, tau_i); /* * store Householder vector below the subdiagonal in column * i of the matrix. hv(1) does not need to be stored since * it is always 1. */ c = gsl_vector_subvector(&c.vector, 1, c.vector.size - 1); hv = gsl_vector_subvector(&hv.vector, 1, hv.vector.size - 1); gsl_vector_memcpy(&c.vector, &hv.vector); } return GSL_SUCCESS; } } /* gsl_linalg_hessenberg_decomp() */ /* gsl_linalg_hessenberg_unpack() Construct the matrix U which transforms a matrix A into its upper Hessenberg form: H = U^t A U by unpacking the information stored in H from gsl_linalg_hessenberg(). U is a product of Householder matrices: U = U(1) U(2) ... U(n - 2) where U(i) = I - tau(i) * v(i) * v(i)^t The v(i) are stored in the lower triangular part of H by gsl_linalg_hessenberg(). The tau(i) are stored in the vector tau. Inputs: H - Hessenberg matrix computed from gsl_linalg_hessenberg() tau - tau vector computed from gsl_linalg_hessenberg() U - (output) where to store similarity matrix Return: success or error */ int gsl_linalg_hessenberg_unpack(gsl_matrix * H, gsl_vector * tau, gsl_matrix * U) { int s; gsl_matrix_set_identity(U); s = gsl_linalg_hessenberg_unpack_accum(H, tau, U); return s; } /* gsl_linalg_hessenberg_unpack() */ /* gsl_linalg_hessenberg_unpack_accum() This routine is the same as gsl_linalg_hessenberg_unpack(), except instead of storing the similarity matrix in U, it accumulates it, so that U -> U * [ U(1) U(2) ... U(n - 2) ] instead of: U -> U(1) U(2) ... U(n - 2) Inputs: H - Hessenberg matrix computed from gsl_linalg_hessenberg() tau - tau vector computed from gsl_linalg_hessenberg() V - (input/output) where to accumulate similarity matrix Return: success or error Notes: 1) On input, V needs to be initialized. The Householder matrices are accumulated into V, so on output, V_out = V_in * U(1) * U(2) * ... * U(n - 2) so if you just want the product of the Householder matrices, initialize V to the identity matrix before calling this function. 2) V does not have to be square, but must have the same number of columns as the order of H */ int gsl_linalg_hessenberg_unpack_accum(gsl_matrix * H, gsl_vector * tau, gsl_matrix * V) { const size_t N = H->size1; if (N != H->size2) { GSL_ERROR ("Hessenberg reduction requires square matrix", GSL_ENOTSQR); } else if (N != tau->size) { GSL_ERROR ("tau vector must match matrix size", GSL_EBADLEN); } else if (N != V->size2) { GSL_ERROR ("V matrix has wrong dimension", GSL_EBADLEN); } else { size_t j; /* looping */ double tau_j; /* householder coefficient */ gsl_vector_view c, /* matrix column */ hv; /* householder vector */ gsl_matrix_view m; if (N < 3) { /* nothing to do */ return GSL_SUCCESS; } for (j = 0; j < (N - 2); ++j) { c = gsl_matrix_column(H, j); tau_j = gsl_vector_get(tau, j); /* * get a view to the householder vector in column j, but * make sure hv(2) starts at the element below the * subdiagonal, since hv(1) was never stored and is always * 1 */ hv = gsl_vector_subvector(&c.vector, j + 1, N - (j + 1)); /* * Only operate on part of the matrix since the first * j + 1 entries of the real householder vector are 0 * * V -> V * U(j) * * Note here that V->size1 is not necessarily equal to N */ m = gsl_matrix_submatrix(V, 0, j + 1, V->size1, N - (j + 1)); /* apply right Householder matrix to V */ gsl_linalg_householder_mh(tau_j, &hv.vector, &m.matrix); } return GSL_SUCCESS; } } /* gsl_linalg_hessenberg_unpack_accum() */ /* gsl_linalg_hessenberg_set_zero() Zero out the lower triangular portion of the Hessenberg matrix H. This is useful when Householder vectors may be stored in the lower part of H, but eigenvalue solvers need some scratch space with zeros. */ int gsl_linalg_hessenberg_set_zero(gsl_matrix * H) { const size_t N = H->size1; size_t i, j; if (N < 3) return GSL_SUCCESS; for (j = 0; j < N - 2; ++j) { for (i = j + 2; i < N; ++i) { gsl_matrix_set(H, i, j, 0.0); } } return GSL_SUCCESS; } /* gsl_linalg_hessenberg_set_zero() */ /* gsl_linalg_hessenberg_submatrix() This routine does the same thing as gsl_linalg_hessenberg(), except that it operates on a submatrix of a larger matrix, but updates the larger matrix with the Householder transformations. For example, suppose M = [ M_{11} | M_{12} | M_{13} ] [ 0 | A | M_{23} ] [ 0 | 0 | M_{33} ] where M_{11} and M_{33} are already in Hessenberg form, and we just want to reduce A to Hessenberg form. Applying the transformations to A alone will cause the larger matrix M to lose its similarity information. So this routine updates M_{12} and M_{23} as A gets reduced. Inputs: M - total matrix A - (sub)matrix to reduce top - row index of top of A in M tau - where to store scalar factors in Householder matrices; this vector must be of length N, where N is the order of A Return: GSL_SUCCESS unless error occurs Notes: on output, the upper triangular portion of A (including the diagaonal and subdiagonal) contains the Hessenberg matrix. The lower triangular portion (below the subdiagonal) contains the Householder vectors which can be used to construct the similarity transform matrix U. The matrix U is U = U(1) U(2) ... U(n - 2) where U(i) = I - tau(i) * v(i) * v(i)^t and the vector v(i) is stored in column i of the matrix A underneath the subdiagonal. So the first element of v(i) is stored in row i + 2, column i, the second element at row i + 3, column i, and so on. Also note that for the purposes of computing U(i), v(1:i) = 0, v(i + 1) = 1, and v(i+2:n) is what is stored in column i of A beneath the subdiagonal. */ int gsl_linalg_hessenberg_submatrix(gsl_matrix *M, gsl_matrix *A, size_t top, gsl_vector *tau) { const size_t N = A->size1; const size_t N_M = M->size1; if (N != A->size2) { GSL_ERROR ("Hessenberg reduction requires square matrix", GSL_ENOTSQR); } else if (N != tau->size) { GSL_ERROR ("tau vector must match matrix size", GSL_EBADLEN); } else if (N < 3) { /* nothing to do */ return GSL_SUCCESS; } else { size_t i; /* looping */ gsl_vector_view c, /* matrix column */ hv; /* householder vector */ gsl_matrix_view m; double tau_i; /* beta in algorithm 7.4.2 */ for (i = 0; i < N - 2; ++i) { /* * make a copy of A(i + 1:n, i) and store it in the section * of 'tau' that we haven't stored coefficients in yet */ c = gsl_matrix_subcolumn(A, i, i + 1, N - i - 1); hv = gsl_vector_subvector(tau, i + 1, N - (i + 1)); gsl_vector_memcpy(&hv.vector, &c.vector); /* compute householder transformation of A(i+1:n,i) */ tau_i = gsl_linalg_householder_transform(&hv.vector); /* * apply left householder matrix (I - tau_i v v') to * [ A | M_{23} ] */ m = gsl_matrix_submatrix(M, top + i + 1, top + i, N - (i + 1), N_M - top - i); gsl_linalg_householder_hm(tau_i, &hv.vector, &m.matrix); /* * apply right householder matrix (I - tau_i v v') to * * [ M_{12} ] * [ A ] */ m = gsl_matrix_submatrix(M, 0, top + i + 1, top + N, N - (i + 1)); gsl_linalg_householder_mh(tau_i, &hv.vector, &m.matrix); /* save Householder coefficient */ gsl_vector_set(tau, i, tau_i); /* * store Householder vector below the subdiagonal in column * i of the matrix. hv(1) does not need to be stored since * it is always 1. */ c = gsl_vector_subvector(&c.vector, 1, c.vector.size - 1); hv = gsl_vector_subvector(&hv.vector, 1, hv.vector.size - 1); gsl_vector_memcpy(&c.vector, &hv.vector); } return GSL_SUCCESS; } } /* gsl_linalg_hessenberg_submatrix() */ praat-6.0.04/external/gsl/gsl_linalg__hesstri.c000066400000000000000000000126331261542461700215130ustar00rootroot00000000000000/* linalg/hesstri.c * * Copyright (C) 2006, 2007 Patrick Alken * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "gsl__config.h" #include "gsl_linalg.h" #include "gsl_matrix.h" #include "gsl_vector.h" #include "gsl_blas.h" #include "gsl_linalg__givens.c" /* * This module contains routines related to the Hessenberg-Triangular * reduction of two general real matrices * * See Golub & Van Loan, "Matrix Computations", 3rd ed, sec 7.7.4 */ /* gsl_linalg_hesstri_decomp() Perform a reduction to generalized upper Hessenberg form. Given A and B, this function overwrites A with an upper Hessenberg matrix H = U^T A V and B with an upper triangular matrix R = U^T B V with U and V orthogonal. See Golub & Van Loan, "Matrix Computations" (3rd ed) algorithm 7.7.1 Inputs: A - real square matrix B - real square matrix U - (output) if non-null, U is stored here on output V - (output) if non-null, V is stored here on output work - workspace (length n) Return: success or error */ int gsl_linalg_hesstri_decomp(gsl_matrix * A, gsl_matrix * B, gsl_matrix * U, gsl_matrix * V, gsl_vector * work) { const size_t N = A->size1; if ((N != A->size2) || (N != B->size1) || (N != B->size2)) { GSL_ERROR ("Hessenberg-triangular reduction requires square matrices", GSL_ENOTSQR); } else if (N != work->size) { GSL_ERROR ("length of workspace must match matrix dimension", GSL_EBADLEN); } else { double cs, sn; /* rotation parameters */ size_t i, j; /* looping */ gsl_vector_view xv, yv; /* temporary views */ /* B -> Q^T B = R (upper triangular) */ gsl_linalg_QR_decomp(B, work); /* A -> Q^T A */ gsl_linalg_QR_QTmat(B, work, A); /* initialize U and V if desired */ if (U) { gsl_linalg_QR_unpack(B, work, U, B); } else { /* zero out lower triangle of B */ for (j = 0; j < N - 1; ++j) { for (i = j + 1; i < N; ++i) gsl_matrix_set(B, i, j, 0.0); } } if (V) gsl_matrix_set_identity(V); if (N < 3) return GSL_SUCCESS; /* nothing more to do */ /* reduce A and B */ for (j = 0; j < N - 2; ++j) { for (i = N - 1; i >= (j + 2); --i) { /* step 1: rotate rows i - 1, i to kill A(i,j) */ /* * compute G = [ CS SN ] so that G^t [ A(i-1,j) ] = [ * ] * [-SN CS ] [ A(i, j) ] [ 0 ] */ create_givens(gsl_matrix_get(A, i - 1, j), gsl_matrix_get(A, i, j), &cs, &sn); /* invert so drot() works correctly (G -> G^t) */ sn = -sn; /* compute G^t A(i-1:i, j:n) */ xv = gsl_matrix_subrow(A, i - 1, j, N - j); yv = gsl_matrix_subrow(A, i, j, N - j); gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); /* compute G^t B(i-1:i, i-1:n) */ xv = gsl_matrix_subrow(B, i - 1, i - 1, N - i + 1); yv = gsl_matrix_subrow(B, i, i - 1, N - i + 1); gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); if (U) { /* accumulate U: U -> U G */ xv = gsl_matrix_column(U, i - 1); yv = gsl_matrix_column(U, i); gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); } /* step 2: rotate columns i, i - 1 to kill B(i, i - 1) */ create_givens(-gsl_matrix_get(B, i, i), gsl_matrix_get(B, i, i - 1), &cs, &sn); /* invert so drot() works correctly (G -> G^t) */ sn = -sn; /* compute B(1:i, i-1:i) G */ xv = gsl_matrix_subcolumn(B, i - 1, 0, i + 1); yv = gsl_matrix_subcolumn(B, i, 0, i + 1); gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); /* apply to A(1:n, i-1:i) */ xv = gsl_matrix_column(A, i - 1); yv = gsl_matrix_column(A, i); gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); if (V) { /* accumulate V: V -> V G */ xv = gsl_matrix_column(V, i - 1); yv = gsl_matrix_column(V, i); gsl_blas_drot(&xv.vector, &yv.vector, cs, sn); } } } return GSL_SUCCESS; } } /* gsl_linalg_hesstri_decomp() */ praat-6.0.04/external/gsl/gsl_linalg__hh.c000066400000000000000000000110461261542461700204260ustar00rootroot00000000000000/* linalg/hh.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_vector.h" #include "gsl_matrix.h" #include "gsl_linalg.h" #define REAL double /* [Engeln-Mullges + Uhlig, Alg. 4.42] */ int gsl_linalg_HH_solve (gsl_matrix * A, const gsl_vector * b, gsl_vector * x) { if (A->size1 > A->size2) { /* System is underdetermined. */ GSL_ERROR ("System is underdetermined", GSL_EINVAL); } else if (A->size2 != x->size) { GSL_ERROR ("matrix and vector sizes must be equal", GSL_EBADLEN); } else { int status ; gsl_vector_memcpy (x, b); status = gsl_linalg_HH_svx (A, x); return status ; } } int gsl_linalg_HH_svx (gsl_matrix * A, gsl_vector * x) { if (A->size1 > A->size2) { /* System is underdetermined. */ GSL_ERROR ("System is underdetermined", GSL_EINVAL); } else if (A->size2 != x->size) { GSL_ERROR ("matrix and vector sizes must be equal", GSL_EBADLEN); } else { const size_t N = A->size1; const size_t M = A->size2; size_t i, j, k; REAL *d = (REAL *) malloc (N * sizeof (REAL)); if (d == 0) { GSL_ERROR ("could not allocate memory for workspace", GSL_ENOMEM); } /* Perform Householder transformation. */ for (i = 0; i < N; i++) { const REAL aii = gsl_matrix_get (A, i, i); REAL alpha; REAL f; REAL ak; REAL max_norm = 0.0; REAL r = 0.0; for (k = i; k < M; k++) { REAL aki = gsl_matrix_get (A, k, i); r += aki * aki; } if (r == 0.0) { /* Rank of matrix is less than size1. */ free (d); GSL_ERROR ("matrix is rank deficient", GSL_ESING); } alpha = sqrt (r) * GSL_SIGN (aii); ak = 1.0 / (r + alpha * aii); gsl_matrix_set (A, i, i, aii + alpha); d[i] = -alpha; for (k = i + 1; k < N; k++) { REAL norm = 0.0; f = 0.0; for (j = i; j < M; j++) { REAL ajk = gsl_matrix_get (A, j, k); REAL aji = gsl_matrix_get (A, j, i); norm += ajk * ajk; f += ajk * aji; } max_norm = GSL_MAX (max_norm, norm); f *= ak; for (j = i; j < M; j++) { REAL ajk = gsl_matrix_get (A, j, k); REAL aji = gsl_matrix_get (A, j, i); gsl_matrix_set (A, j, k, ajk - f * aji); } } if (fabs (alpha) < 2.0 * GSL_DBL_EPSILON * sqrt (max_norm)) { /* Apparent singularity. */ free (d); GSL_ERROR("apparent singularity detected", GSL_ESING); } /* Perform update of RHS. */ f = 0.0; for (j = i; j < M; j++) { f += gsl_vector_get (x, j) * gsl_matrix_get (A, j, i); } f *= ak; for (j = i; j < M; j++) { REAL xj = gsl_vector_get (x, j); REAL aji = gsl_matrix_get (A, j, i); gsl_vector_set (x, j, xj - f * aji); } } /* Perform back-substitution. */ for (i = N; i > 0 && i--;) { REAL xi = gsl_vector_get (x, i); REAL sum = 0.0; for (k = i + 1; k < N; k++) { sum += gsl_matrix_get (A, i, k) * gsl_vector_get (x, k); } gsl_vector_set (x, i, (xi - sum) / d[i]); } free (d); return GSL_SUCCESS; } } praat-6.0.04/external/gsl/gsl_linalg__householder.c000066400000000000000000000173661261542461700223630ustar00rootroot00000000000000/* linalg/householder.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_vector.h" #include "gsl_matrix.h" #include "gsl_blas.h" #include "gsl_linalg.h" double gsl_linalg_householder_transform (gsl_vector * v) { /* replace v[0:n-1] with a householder vector (v[0:n-1]) and coefficient tau that annihilate v[1:n-1] */ const size_t n = v->size ; if (n == 1) { return 0.0; /* tau = 0 */ } else { double alpha, beta, tau ; gsl_vector_view x = gsl_vector_subvector (v, 1, n - 1) ; double xnorm = gsl_blas_dnrm2 (&x.vector); if (xnorm == 0) { return 0.0; /* tau = 0 */ } alpha = gsl_vector_get (v, 0) ; beta = - (alpha >= 0.0 ? +1.0 : -1.0) * hypot(alpha, xnorm) ; tau = (beta - alpha) / beta ; gsl_blas_dscal (1.0 / (alpha - beta), &x.vector); gsl_vector_set (v, 0, beta) ; return tau; } } int gsl_linalg_householder_hm (double tau, const gsl_vector * v, gsl_matrix * A) { /* applies a householder transformation v,tau to matrix m */ if (tau == 0.0) { return GSL_SUCCESS; } #ifdef USE_BLAS { gsl_vector_const_view v1 = gsl_vector_const_subvector (v, 1, v->size - 1); gsl_matrix_view A1 = gsl_matrix_submatrix (A, 1, 0, A->size1 - 1, A->size2); size_t j; for (j = 0; j < A->size2; j++) { double wj = 0.0; gsl_vector_view A1j = gsl_matrix_column(&A1.matrix, j); gsl_blas_ddot (&A1j.vector, &v1.vector, &wj); wj += gsl_matrix_get(A,0,j); { double A0j = gsl_matrix_get (A, 0, j); gsl_matrix_set (A, 0, j, A0j - tau * wj); } gsl_blas_daxpy (-tau * wj, &v1.vector, &A1j.vector); } } #else { size_t i, j; for (j = 0; j < A->size2; j++) { /* Compute wj = Akj vk */ double wj = gsl_matrix_get(A,0,j); for (i = 1; i < A->size1; i++) /* note, computed for v(0) = 1 above */ { wj += gsl_matrix_get(A,i,j) * gsl_vector_get(v,i); } /* Aij = Aij - tau vi wj */ /* i = 0 */ { double A0j = gsl_matrix_get (A, 0, j); gsl_matrix_set (A, 0, j, A0j - tau * wj); } /* i = 1 .. M-1 */ for (i = 1; i < A->size1; i++) { double Aij = gsl_matrix_get (A, i, j); double vi = gsl_vector_get (v, i); gsl_matrix_set (A, i, j, Aij - tau * vi * wj); } } } #endif return GSL_SUCCESS; } int gsl_linalg_householder_mh (double tau, const gsl_vector * v, gsl_matrix * A) { /* applies a householder transformation v,tau to matrix m from the right hand side in order to zero out rows */ if (tau == 0) return GSL_SUCCESS; /* A = A - tau w v' */ #ifdef USE_BLAS { gsl_vector_const_view v1 = gsl_vector_const_subvector (v, 1, v->size - 1); gsl_matrix_view A1 = gsl_matrix_submatrix (A, 0, 1, A->size1, A->size2-1); size_t i; for (i = 0; i < A->size1; i++) { double wi = 0.0; gsl_vector_view A1i = gsl_matrix_row(&A1.matrix, i); gsl_blas_ddot (&A1i.vector, &v1.vector, &wi); wi += gsl_matrix_get(A,i,0); { double Ai0 = gsl_matrix_get (A, i, 0); gsl_matrix_set (A, i, 0, Ai0 - tau * wi); } gsl_blas_daxpy(-tau * wi, &v1.vector, &A1i.vector); } } #else { size_t i, j; for (i = 0; i < A->size1; i++) { double wi = gsl_matrix_get(A,i,0); for (j = 1; j < A->size2; j++) /* note, computed for v(0) = 1 above */ { wi += gsl_matrix_get(A,i,j) * gsl_vector_get(v,j); } /* j = 0 */ { double Ai0 = gsl_matrix_get (A, i, 0); gsl_matrix_set (A, i, 0, Ai0 - tau * wi); } /* j = 1 .. N-1 */ for (j = 1; j < A->size2; j++) { double vj = gsl_vector_get (v, j); double Aij = gsl_matrix_get (A, i, j); gsl_matrix_set (A, i, j, Aij - tau * wi * vj); } } } #endif return GSL_SUCCESS; } int gsl_linalg_householder_hv (double tau, const gsl_vector * v, gsl_vector * w) { /* applies a householder transformation v to vector w */ const size_t N = v->size; if (tau == 0) return GSL_SUCCESS ; { /* compute d = v'w */ double d0 = gsl_vector_get(w,0); double d1, d; gsl_vector_const_view v1 = gsl_vector_const_subvector(v, 1, N-1); gsl_vector_view w1 = gsl_vector_subvector(w, 1, N-1); gsl_blas_ddot (&v1.vector, &w1.vector, &d1); d = d0 + d1; /* compute w = w - tau (v) (v'w) */ { double w0 = gsl_vector_get (w,0); gsl_vector_set (w, 0, w0 - tau * d); } gsl_blas_daxpy (-tau * d, &v1.vector, &w1.vector); } return GSL_SUCCESS; } int gsl_linalg_householder_hm1 (double tau, gsl_matrix * A) { /* applies a householder transformation v,tau to a matrix being build up from the identity matrix, using the first column of A as a householder vector */ if (tau == 0) { size_t i,j; gsl_matrix_set (A, 0, 0, 1.0); for (j = 1; j < A->size2; j++) { gsl_matrix_set (A, 0, j, 0.0); } for (i = 1; i < A->size1; i++) { gsl_matrix_set (A, i, 0, 0.0); } return GSL_SUCCESS; } /* w = A' v */ #ifdef USE_BLAS { gsl_matrix_view A1 = gsl_matrix_submatrix (A, 1, 0, A->size1 - 1, A->size2); gsl_vector_view v1 = gsl_matrix_column (&A1.matrix, 0); size_t j; for (j = 1; j < A->size2; j++) { double wj = 0.0; /* A0j * v0 */ gsl_vector_view A1j = gsl_matrix_column(&A1.matrix, j); gsl_blas_ddot (&A1j.vector, &v1.vector, &wj); /* A = A - tau v w' */ gsl_matrix_set (A, 0, j, - tau * wj); gsl_blas_daxpy(-tau*wj, &v1.vector, &A1j.vector); } gsl_blas_dscal(-tau, &v1.vector); gsl_matrix_set (A, 0, 0, 1.0 - tau); } #else { size_t i, j; for (j = 1; j < A->size2; j++) { double wj = 0.0; /* A0j * v0 */ for (i = 1; i < A->size1; i++) { double vi = gsl_matrix_get(A, i, 0); wj += gsl_matrix_get(A,i,j) * vi; } /* A = A - tau v w' */ gsl_matrix_set (A, 0, j, - tau * wj); for (i = 1; i < A->size1; i++) { double vi = gsl_matrix_get (A, i, 0); double Aij = gsl_matrix_get (A, i, j); gsl_matrix_set (A, i, j, Aij - tau * vi * wj); } } for (i = 1; i < A->size1; i++) { double vi = gsl_matrix_get(A, i, 0); gsl_matrix_set(A, i, 0, -tau * vi); } gsl_matrix_set (A, 0, 0, 1.0 - tau); } #endif return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_linalg__householdercomplex.c000066400000000000000000000164461261542461700237510ustar00rootroot00000000000000/* linalg/householdercomplex.c * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Computes a householder transformation matrix H such that * * H' v = -/+ |v| e_1 * * where e_1 is the first unit vector. On exit the matrix H can be * computed from the return values (tau, v) * * H = I - tau * w * w' * * where w = (1, v(2), ..., v(N)). The nonzero element of the result * vector -/+|v| e_1 is stored in v(1). * * Note that the matrix H' in the householder transformation is the * hermitian conjugate of H. To compute H'v, pass the conjugate of * tau as the first argument to gsl_linalg_householder_hm() rather * than tau itself. See the LAPACK function CLARFG for details of this * convention. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_vector.h" #include "gsl_matrix.h" #include "gsl_blas.h" #include "gsl_complex_math.h" #include "gsl_linalg.h" gsl_complex gsl_linalg_complex_householder_transform (gsl_vector_complex * v) { /* replace v[0:n-1] with a householder vector (v[0:n-1]) and coefficient tau that annihilate v[1:n-1] */ const size_t n = v->size ; if (n == 1) { gsl_complex alpha = gsl_vector_complex_get (v, 0) ; double absa = gsl_complex_abs (alpha); double beta_r = - (GSL_REAL(alpha) >= 0 ? +1 : -1) * absa ; gsl_complex tau; if (beta_r == 0.0) { GSL_REAL(tau) = 0.0; GSL_IMAG(tau) = 0.0; } else { GSL_REAL(tau) = (beta_r - GSL_REAL(alpha)) / beta_r ; GSL_IMAG(tau) = - GSL_IMAG(alpha) / beta_r ; { gsl_complex beta = gsl_complex_rect (beta_r, 0.0); gsl_vector_complex_set (v, 0, beta) ; } } return tau; } else { gsl_complex tau ; double beta_r; gsl_vector_complex_view x = gsl_vector_complex_subvector (v, 1, n - 1) ; gsl_complex alpha = gsl_vector_complex_get (v, 0) ; double absa = gsl_complex_abs (alpha); double xnorm = gsl_blas_dznrm2 (&x.vector); if (xnorm == 0 && GSL_IMAG(alpha) == 0) { gsl_complex zero = gsl_complex_rect(0.0, 0.0); return zero; /* tau = 0 */ } beta_r = - (GSL_REAL(alpha) >= 0 ? +1 : -1) * hypot(absa, xnorm) ; GSL_REAL(tau) = (beta_r - GSL_REAL(alpha)) / beta_r ; GSL_IMAG(tau) = - GSL_IMAG(alpha) / beta_r ; { gsl_complex amb = gsl_complex_sub_real(alpha, beta_r); gsl_complex s = gsl_complex_inverse(amb); gsl_blas_zscal (s, &x.vector); } { gsl_complex beta = gsl_complex_rect (beta_r, 0.0); gsl_vector_complex_set (v, 0, beta) ; } return tau; } } int gsl_linalg_complex_householder_hm (gsl_complex tau, const gsl_vector_complex * v, gsl_matrix_complex * A) { /* applies a householder transformation v,tau to matrix m */ size_t i, j; if (GSL_REAL(tau) == 0.0 && GSL_IMAG(tau) == 0.0) { return GSL_SUCCESS; } /* w = (v' A)^T */ for (j = 0; j < A->size2; j++) { gsl_complex tauwj; gsl_complex wj = gsl_matrix_complex_get(A,0,j); for (i = 1; i < A->size1; i++) /* note, computed for v(0) = 1 above */ { gsl_complex Aij = gsl_matrix_complex_get(A,i,j); gsl_complex vi = gsl_vector_complex_get(v,i); gsl_complex Av = gsl_complex_mul (Aij, gsl_complex_conjugate(vi)); wj = gsl_complex_add (wj, Av); } tauwj = gsl_complex_mul (tau, wj); /* A = A - v w^T */ { gsl_complex A0j = gsl_matrix_complex_get (A, 0, j); gsl_complex Atw = gsl_complex_sub (A0j, tauwj); /* store A0j - tau * wj */ gsl_matrix_complex_set (A, 0, j, Atw); } for (i = 1; i < A->size1; i++) { gsl_complex vi = gsl_vector_complex_get (v, i); gsl_complex tauvw = gsl_complex_mul(vi, tauwj); gsl_complex Aij = gsl_matrix_complex_get (A, i, j); gsl_complex Atwv = gsl_complex_sub (Aij, tauvw); /* store Aij - tau * vi * wj */ gsl_matrix_complex_set (A, i, j, Atwv); } } return GSL_SUCCESS; } int gsl_linalg_complex_householder_mh (gsl_complex tau, const gsl_vector_complex * v, gsl_matrix_complex * A) { /* applies a householder transformation v,tau to matrix m on the right */ size_t i, j; if (GSL_REAL(tau) == 0.0 && GSL_IMAG(tau) == 0.0) { return GSL_SUCCESS; } /* A -> A - A*tau*v*v^h */ for (i = 0; i < A->size1; i++) { gsl_complex tauwi; gsl_complex Ai0 = gsl_matrix_complex_get (A, i, 0); gsl_complex wi = Ai0; /* compute w = A v */ for (j = 1; j < A->size2; j++) /* note, computed for v(0) = 1 above */ { gsl_complex Aij = gsl_matrix_complex_get(A, i, j); gsl_complex vj = gsl_vector_complex_get(v, j); gsl_complex Av = gsl_complex_mul (Aij, vj); wi = gsl_complex_add (wi, Av); } tauwi = gsl_complex_mul (tau, wi); /* A = A - w v^H */ { gsl_complex Atw = gsl_complex_sub (Ai0, tauwi); /* store Ai0 - tau * wi */ gsl_matrix_complex_set (A, i, 0, Atw); } for (j = 1; j < A->size2; j++) { gsl_complex vj = gsl_vector_complex_get (v, j); gsl_complex tauwv = gsl_complex_mul(gsl_complex_conjugate(vj), tauwi); gsl_complex Aij = gsl_matrix_complex_get (A, i, j); gsl_complex Atwv = gsl_complex_sub (Aij, tauwv); /* store Aij - tau * wi * conj(vj) */ gsl_matrix_complex_set (A, i, j, Atwv); } } return GSL_SUCCESS; } int gsl_linalg_complex_householder_hv (gsl_complex tau, const gsl_vector_complex * v, gsl_vector_complex * w) { const size_t N = v->size; if (GSL_REAL(tau) == 0.0 && GSL_IMAG(tau) == 0.0) return GSL_SUCCESS; { /* compute z = v'w */ gsl_complex z0 = gsl_vector_complex_get(w,0); gsl_complex z1, z; gsl_complex tz, ntz; gsl_vector_complex_const_view v1 = gsl_vector_complex_const_subvector(v, 1, N-1); gsl_vector_complex_view w1 = gsl_vector_complex_subvector(w, 1, N-1); gsl_blas_zdotc(&v1.vector, &w1.vector, &z1); z = gsl_complex_add (z0, z1); tz = gsl_complex_mul(tau, z); ntz = gsl_complex_negative (tz); /* compute w = w - tau * (v'w) * v */ { gsl_complex w0 = gsl_vector_complex_get(w, 0); gsl_complex w0ntz = gsl_complex_add (w0, ntz); gsl_vector_complex_set (w, 0, w0ntz); } gsl_blas_zaxpy(ntz, &v1.vector, &w1.vector); } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_linalg__lq.c000066400000000000000000000344311261542461700204460ustar00rootroot00000000000000/* linalg/lq.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * Copyright (C) 2004 Joerg Wensch, modifications for LQ. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_math.h" #include "gsl_vector.h" #include "gsl_matrix.h" #include "gsl_blas.h" #include "gsl_linalg.h" #define REAL double #include "gsl_linalg__givens.c" #include "gsl_linalg__apply_givens.c" /* Note: The standard in numerical linear algebra is to solve A x = b * resp. ||A x - b||_2 -> min by QR-decompositions where x, b are * column vectors. * * When the matrix A has a large number of rows it is much more * efficient to work with the transposed matrix A^T and to solve the * system x^T A = b^T resp. ||x^T A - b^T||_2 -> min. This is caused * by the row-oriented format in which GSL stores matrices. Therefore * the QR-decomposition of A has to be replaced by a LQ decomposition * of A^T * * The purpose of this package is to provide the algorithms to compute * the LQ-decomposition and to solve the linear equations resp. least * squares problems. The dimensions N, M of the matrix are switched * because here A will probably be a transposed matrix. We write x^T, * b^T,... for vectors the comments to emphasize that they are row * vectors. * * It may even be useful to transpose your matrix explicitly (assumed * that there are no memory restrictions) because this takes O(M x N) * computing time where the decompostion takes O(M x N^2) computing * time. */ /* Factorise a general N x M matrix A into * * A = L Q * * where Q is orthogonal (M x M) and L is lower triangular (N x M). * * Q is stored as a packed set of Householder transformations in the * strict upper triangular part of the input matrix. * * R is stored in the diagonal and lower triangle of the input matrix. * * The full matrix for Q can be obtained as the product * * Q = Q_k .. Q_2 Q_1 * * where k = MIN(M,N) and * * Q_i = (I - tau_i * v_i * v_i') * * and where v_i is a Householder vector * * v_i = [1, m(i+1,i), m(i+2,i), ... , m(M,i)] * * This storage scheme is the same as in LAPACK. */ int gsl_linalg_LQ_decomp (gsl_matrix * A, gsl_vector * tau) { const size_t N = A->size1; const size_t M = A->size2; if (tau->size != GSL_MIN (M, N)) { GSL_ERROR ("size of tau must be MIN(M,N)", GSL_EBADLEN); } else { size_t i; for (i = 0; i < GSL_MIN (M, N); i++) { /* Compute the Householder transformation to reduce the j-th column of the matrix to a multiple of the j-th unit vector */ gsl_vector_view c_full = gsl_matrix_row (A, i); gsl_vector_view c = gsl_vector_subvector (&(c_full.vector), i, M-i); double tau_i = gsl_linalg_householder_transform (&(c.vector)); gsl_vector_set (tau, i, tau_i); /* Apply the transformation to the remaining columns and update the norms */ if (i + 1 < N) { gsl_matrix_view m = gsl_matrix_submatrix (A, i + 1, i, N - (i + 1), M - i ); gsl_linalg_householder_mh (tau_i, &(c.vector), &(m.matrix)); } } return GSL_SUCCESS; } } /* Solves the system x^T A = b^T using the LQ factorisation, * x^T L = b^T Q^T * * to obtain x. Based on SLATEC code. */ int gsl_linalg_LQ_solve_T (const gsl_matrix * LQ, const gsl_vector * tau, const gsl_vector * b, gsl_vector * x) { if (LQ->size1 != LQ->size2) { GSL_ERROR ("LQ matrix must be square", GSL_ENOTSQR); } else if (LQ->size2 != b->size) { GSL_ERROR ("matrix size must match b size", GSL_EBADLEN); } else if (LQ->size1 != x->size) { GSL_ERROR ("matrix size must match solution size", GSL_EBADLEN); } else { /* Copy x <- b */ gsl_vector_memcpy (x, b); /* Solve for x */ gsl_linalg_LQ_svx_T (LQ, tau, x); return GSL_SUCCESS; } } /* Solves the system x^T A = b^T in place using the LQ factorisation, * * x^T L = b^T Q^T * * to obtain x. Based on SLATEC code. */ int gsl_linalg_LQ_svx_T (const gsl_matrix * LQ, const gsl_vector * tau, gsl_vector * x) { if (LQ->size1 != LQ->size2) { GSL_ERROR ("LQ matrix must be square", GSL_ENOTSQR); } else if (LQ->size1 != x->size) { GSL_ERROR ("matrix size must match x/rhs size", GSL_EBADLEN); } else { /* compute rhs = Q^T b */ gsl_linalg_LQ_vecQT (LQ, tau, x); /* Solve R x = rhs, storing x in-place */ gsl_blas_dtrsv (CblasLower, CblasTrans, CblasNonUnit, LQ, x); return GSL_SUCCESS; } } /* Find the least squares solution to the overdetermined system * * x^T A = b^T * * for M >= N using the LQ factorization A = L Q. */ int gsl_linalg_LQ_lssolve_T (const gsl_matrix * LQ, const gsl_vector * tau, const gsl_vector * b, gsl_vector * x, gsl_vector * residual) { const size_t N = LQ->size1; const size_t M = LQ->size2; if (M < N) { GSL_ERROR ("LQ matrix must have M>=N", GSL_EBADLEN); } else if (M != b->size) { GSL_ERROR ("matrix size must match b size", GSL_EBADLEN); } else if (N != x->size) { GSL_ERROR ("matrix size must match solution size", GSL_EBADLEN); } else if (M != residual->size) { GSL_ERROR ("matrix size must match residual size", GSL_EBADLEN); } else { gsl_matrix_const_view L = gsl_matrix_const_submatrix (LQ, 0, 0, N, N); gsl_vector_view c = gsl_vector_subvector(residual, 0, N); gsl_vector_memcpy(residual, b); /* compute rhs = b^T Q^T */ gsl_linalg_LQ_vecQT (LQ, tau, residual); /* Solve x^T L = rhs */ gsl_vector_memcpy(x, &(c.vector)); gsl_blas_dtrsv (CblasLower, CblasTrans, CblasNonUnit, &(L.matrix), x); /* Compute residual = b^T - x^T A = (b^T Q^T - x^T L) Q */ gsl_vector_set_zero(&(c.vector)); gsl_linalg_LQ_vecQ(LQ, tau, residual); return GSL_SUCCESS; } } int gsl_linalg_LQ_Lsolve_T (const gsl_matrix * LQ, const gsl_vector * b, gsl_vector * x) { if (LQ->size1 != LQ->size2) { GSL_ERROR ("LQ matrix must be square", GSL_ENOTSQR); } else if (LQ->size1 != b->size) { GSL_ERROR ("matrix size must match b size", GSL_EBADLEN); } else if (LQ->size1 != x->size) { GSL_ERROR ("matrix size must match x size", GSL_EBADLEN); } else { /* Copy x <- b */ gsl_vector_memcpy (x, b); /* Solve R x = b, storing x in-place */ gsl_blas_dtrsv (CblasLower, CblasTrans, CblasNonUnit, LQ, x); return GSL_SUCCESS; } } int gsl_linalg_LQ_Lsvx_T (const gsl_matrix * LQ, gsl_vector * x) { if (LQ->size1 != LQ->size2) { GSL_ERROR ("LQ matrix must be square", GSL_ENOTSQR); } else if (LQ->size2 != x->size) { GSL_ERROR ("matrix size must match rhs size", GSL_EBADLEN); } else { /* Solve x^T L = b^T, storing x in-place */ gsl_blas_dtrsv (CblasLower, CblasTrans, CblasNonUnit, LQ, x); return GSL_SUCCESS; } } int gsl_linalg_L_solve_T (const gsl_matrix * L, const gsl_vector * b, gsl_vector * x) { if (L->size1 != L->size2) { GSL_ERROR ("R matrix must be square", GSL_ENOTSQR); } else if (L->size2 != b->size) { GSL_ERROR ("matrix size must match b size", GSL_EBADLEN); } else if (L->size1 != x->size) { GSL_ERROR ("matrix size must match solution size", GSL_EBADLEN); } else { /* Copy x <- b */ gsl_vector_memcpy (x, b); /* Solve R x = b, storing x inplace in b */ gsl_blas_dtrsv (CblasLower, CblasTrans, CblasNonUnit, L, x); return GSL_SUCCESS; } } int gsl_linalg_LQ_vecQT (const gsl_matrix * LQ, const gsl_vector * tau, gsl_vector * v) { const size_t N = LQ->size1; const size_t M = LQ->size2; if (tau->size != GSL_MIN (M, N)) { GSL_ERROR ("size of tau must be MIN(M,N)", GSL_EBADLEN); } else if (v->size != M) { GSL_ERROR ("vector size must be M", GSL_EBADLEN); } else { size_t i; /* compute v Q^T */ for (i = 0; i < GSL_MIN (M, N); i++) { gsl_vector_const_view c = gsl_matrix_const_row (LQ, i); gsl_vector_const_view h = gsl_vector_const_subvector (&(c.vector), i, M - i); gsl_vector_view w = gsl_vector_subvector (v, i, M - i); double ti = gsl_vector_get (tau, i); gsl_linalg_householder_hv (ti, &(h.vector), &(w.vector)); } return GSL_SUCCESS; } } int gsl_linalg_LQ_vecQ (const gsl_matrix * LQ, const gsl_vector * tau, gsl_vector * v) { const size_t N = LQ->size1; const size_t M = LQ->size2; if (tau->size != GSL_MIN (M, N)) { GSL_ERROR ("size of tau must be MIN(M,N)", GSL_EBADLEN); } else if (v->size != M) { GSL_ERROR ("vector size must be M", GSL_EBADLEN); } else { size_t i; /* compute v Q^T */ for (i = GSL_MIN (M, N); i > 0 && i--;) { gsl_vector_const_view c = gsl_matrix_const_row (LQ, i); gsl_vector_const_view h = gsl_vector_const_subvector (&(c.vector), i, M - i); gsl_vector_view w = gsl_vector_subvector (v, i, M - i); double ti = gsl_vector_get (tau, i); gsl_linalg_householder_hv (ti, &(h.vector), &(w.vector)); } return GSL_SUCCESS; } } /* Form the orthogonal matrix Q from the packed LQ matrix */ int gsl_linalg_LQ_unpack (const gsl_matrix * LQ, const gsl_vector * tau, gsl_matrix * Q, gsl_matrix * L) { const size_t N = LQ->size1; const size_t M = LQ->size2; if (Q->size1 != M || Q->size2 != M) { GSL_ERROR ("Q matrix must be M x M", GSL_ENOTSQR); } else if (L->size1 != N || L->size2 != M) { GSL_ERROR ("R matrix must be N x M", GSL_ENOTSQR); } else if (tau->size != GSL_MIN (M, N)) { GSL_ERROR ("size of tau must be MIN(M,N)", GSL_EBADLEN); } else { size_t i, j, l_border; /* Initialize Q to the identity */ gsl_matrix_set_identity (Q); for (i = GSL_MIN (M, N); i > 0 && i--;) { gsl_vector_const_view c = gsl_matrix_const_row (LQ, i); gsl_vector_const_view h = gsl_vector_const_subvector (&c.vector, i, M - i); gsl_matrix_view m = gsl_matrix_submatrix (Q, i, i, M - i, M - i); double ti = gsl_vector_get (tau, i); gsl_linalg_householder_mh (ti, &h.vector, &m.matrix); } /* Form the lower triangular matrix L from a packed LQ matrix */ for (i = 0; i < N; i++) { l_border=GSL_MIN(i,M-1); for (j = 0; j <= l_border ; j++) gsl_matrix_set (L, i, j, gsl_matrix_get (LQ, i, j)); for (j = l_border+1; j < M; j++) gsl_matrix_set (L, i, j, 0.0); } return GSL_SUCCESS; } } /* Update a LQ factorisation for A= L Q , A' = A + v u^T, * L' Q' = LQ + v u^T * = (L + v u^T Q^T) Q * = (L + v w^T) Q * * where w = Q u. * * Algorithm from Golub and Van Loan, "Matrix Computations", Section * 12.5 (Updating Matrix Factorizations, Rank-One Changes) */ int gsl_linalg_LQ_update (gsl_matrix * Q, gsl_matrix * L, const gsl_vector * v, gsl_vector * w) { const size_t N = L->size1; const size_t M = L->size2; if (Q->size1 != M || Q->size2 != M) { GSL_ERROR ("Q matrix must be N x N if L is M x N", GSL_ENOTSQR); } else if (w->size != M) { GSL_ERROR ("w must be length N if L is M x N", GSL_EBADLEN); } else if (v->size != N) { GSL_ERROR ("v must be length M if L is M x N", GSL_EBADLEN); } else { size_t j, k; double w0; /* Apply Given's rotations to reduce w to (|w|, 0, 0, ... , 0) J_1^T .... J_(n-1)^T w = +/- |w| e_1 simultaneously applied to L, H = J_1^T ... J^T_(n-1) L so that H is upper Hessenberg. (12.5.2) */ for (k = M - 1; k > 0; k--) { double c, s; double wk = gsl_vector_get (w, k); double wkm1 = gsl_vector_get (w, k - 1); create_givens (wkm1, wk, &c, &s); apply_givens_vec (w, k - 1, k, c, s); apply_givens_lq (M, N, Q, L, k - 1, k, c, s); } w0 = gsl_vector_get (w, 0); /* Add in v w^T (Equation 12.5.3) */ for (j = 0; j < N; j++) { double lj0 = gsl_matrix_get (L, j, 0); double vj = gsl_vector_get (v, j); gsl_matrix_set (L, j, 0, lj0 + w0 * vj); } /* Apply Givens transformations L' = G_(n-1)^T ... G_1^T H Equation 12.5.4 */ for (k = 1; k < GSL_MIN(M,N+1); k++) { double c, s; double diag = gsl_matrix_get (L, k - 1, k - 1); double offdiag = gsl_matrix_get (L, k - 1 , k); create_givens (diag, offdiag, &c, &s); apply_givens_lq (M, N, Q, L, k - 1, k, c, s); gsl_matrix_set (L, k - 1, k, 0.0); /* exact zero of G^T */ } return GSL_SUCCESS; } } int gsl_linalg_LQ_LQsolve (gsl_matrix * Q, gsl_matrix * L, const gsl_vector * b, gsl_vector * x) { const size_t N = L->size1; const size_t M = L->size2; if (M != N) { return GSL_ENOTSQR; } else if (Q->size1 != M || b->size != M || x->size != M) { return GSL_EBADLEN; } else { /* compute sol = b^T Q^T */ gsl_blas_dgemv (CblasNoTrans, 1.0, Q, b, 0.0, x); /* Solve x^T L = sol, storing x in-place */ gsl_blas_dtrsv (CblasLower, CblasTrans, CblasNonUnit, L, x); return GSL_SUCCESS; } } praat-6.0.04/external/gsl/gsl_linalg__lu.c000066400000000000000000000163621261542461700204550ustar00rootroot00000000000000/* linalg/lu.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include #include #include "gsl_math.h" #include "gsl_vector.h" #include "gsl_matrix.h" #include "gsl_permute_vector.h" #include "gsl_blas.h" #include "gsl_linalg.h" #define REAL double /* Factorise a general N x N matrix A into, * * P A = L U * * where P is a permutation matrix, L is unit lower triangular and U * is upper triangular. * * L is stored in the strict lower triangular part of the input * matrix. The diagonal elements of L are unity and are not stored. * * U is stored in the diagonal and upper triangular part of the * input matrix. * * P is stored in the permutation p. Column j of P is column k of the * identity matrix, where k = permutation->data[j] * * signum gives the sign of the permutation, (-1)^n, where n is the * number of interchanges in the permutation. * * See Golub & Van Loan, Matrix Computations, Algorithm 3.4.1 (Gauss * Elimination with Partial Pivoting). */ int gsl_linalg_LU_decomp (gsl_matrix * A, gsl_permutation * p, int *signum) { if (A->size1 != A->size2) { GSL_ERROR ("LU decomposition requires square matrix", GSL_ENOTSQR); } else if (p->size != A->size1) { GSL_ERROR ("permutation length must match matrix size", GSL_EBADLEN); } else { const size_t N = A->size1; size_t i, j, k; *signum = 1; gsl_permutation_init (p); for (j = 0; j < N - 1; j++) { /* Find maximum in the j-th column */ REAL ajj, max = fabs (gsl_matrix_get (A, j, j)); size_t i_pivot = j; for (i = j + 1; i < N; i++) { REAL aij = fabs (gsl_matrix_get (A, i, j)); if (aij > max) { max = aij; i_pivot = i; } } if (i_pivot != j) { gsl_matrix_swap_rows (A, j, i_pivot); gsl_permutation_swap (p, j, i_pivot); *signum = -(*signum); } ajj = gsl_matrix_get (A, j, j); if (ajj != 0.0) { for (i = j + 1; i < N; i++) { REAL aij = gsl_matrix_get (A, i, j) / ajj; gsl_matrix_set (A, i, j, aij); for (k = j + 1; k < N; k++) { REAL aik = gsl_matrix_get (A, i, k); REAL ajk = gsl_matrix_get (A, j, k); gsl_matrix_set (A, i, k, aik - aij * ajk); } } } } return GSL_SUCCESS; } } int gsl_linalg_LU_solve (const gsl_matrix * LU, const gsl_permutation * p, const gsl_vector * b, gsl_vector * x) { if (LU->size1 != LU->size2) { GSL_ERROR ("LU matrix must be square", GSL_ENOTSQR); } else if (LU->size1 != p->size) { GSL_ERROR ("permutation length must match matrix size", GSL_EBADLEN); } else if (LU->size1 != b->size) { GSL_ERROR ("matrix size must match b size", GSL_EBADLEN); } else if (LU->size2 != x->size) { GSL_ERROR ("matrix size must match solution size", GSL_EBADLEN); } else { /* Copy x <- b */ gsl_vector_memcpy (x, b); /* Solve for x */ gsl_linalg_LU_svx (LU, p, x); return GSL_SUCCESS; } } int gsl_linalg_LU_svx (const gsl_matrix * LU, const gsl_permutation * p, gsl_vector * x) { if (LU->size1 != LU->size2) { GSL_ERROR ("LU matrix must be square", GSL_ENOTSQR); } else if (LU->size1 != p->size) { GSL_ERROR ("permutation length must match matrix size", GSL_EBADLEN); } else if (LU->size1 != x->size) { GSL_ERROR ("matrix size must match solution/rhs size", GSL_EBADLEN); } else { /* Apply permutation to RHS */ gsl_permute_vector (p, x); /* Solve for c using forward-substitution, L c = P b */ gsl_blas_dtrsv (CblasLower, CblasNoTrans, CblasUnit, LU, x); /* Perform back-substitution, U x = c */ gsl_blas_dtrsv (CblasUpper, CblasNoTrans, CblasNonUnit, LU, x); return GSL_SUCCESS; } } int gsl_linalg_LU_refine (const gsl_matrix * A, const gsl_matrix * LU, const gsl_permutation * p, const gsl_vector * b, gsl_vector * x, gsl_vector * residual) { if (A->size1 != A->size2) { GSL_ERROR ("matrix a must be square", GSL_ENOTSQR); } if (LU->size1 != LU->size2) { GSL_ERROR ("LU matrix must be square", GSL_ENOTSQR); } else if (A->size1 != LU->size2) { GSL_ERROR ("LU matrix must be decomposition of a", GSL_ENOTSQR); } else if (LU->size1 != p->size) { GSL_ERROR ("permutation length must match matrix size", GSL_EBADLEN); } else if (LU->size1 != b->size) { GSL_ERROR ("matrix size must match b size", GSL_EBADLEN); } else if (LU->size1 != x->size) { GSL_ERROR ("matrix size must match solution size", GSL_EBADLEN); } else { /* Compute residual, residual = (A * x - b) */ gsl_vector_memcpy (residual, b); gsl_blas_dgemv (CblasNoTrans, 1.0, A, x, -1.0, residual); /* Find correction, delta = - (A^-1) * residual, and apply it */ gsl_linalg_LU_svx (LU, p, residual); gsl_blas_daxpy (-1.0, residual, x); return GSL_SUCCESS; } } int gsl_linalg_LU_invert (const gsl_matrix * LU, const gsl_permutation * p, gsl_matrix * inverse) { size_t i, n = LU->size1; int status = GSL_SUCCESS; gsl_matrix_set_identity (inverse); for (i = 0; i < n; i++) { gsl_vector_view c = gsl_matrix_column (inverse, i); int status_i = gsl_linalg_LU_svx (LU, p, &(c.vector)); if (status_i) status = status_i; } return status; } double gsl_linalg_LU_det (gsl_matrix * LU, int signum) { size_t i, n = LU->size1; double det = (double) signum; for (i = 0; i < n; i++) { det *= gsl_matrix_get (LU, i, i); } return det; } double gsl_linalg_LU_lndet (gsl_matrix * LU) { size_t i, n = LU->size1; double lndet = 0.0; for (i = 0; i < n; i++) { lndet += log (fabs (gsl_matrix_get (LU, i, i))); } return lndet; } int gsl_linalg_LU_sgndet (gsl_matrix * LU, int signum) { size_t i, n = LU->size1; int s = signum; for (i = 0; i < n; i++) { double u = gsl_matrix_get (LU, i, i); if (u < 0) { s *= -1; } else if (u == 0) { s = 0; break; } } return s; } praat-6.0.04/external/gsl/gsl_linalg__luc.c000066400000000000000000000207661261542461700206230ustar00rootroot00000000000000/* linalg/luc.c * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_math.h" #include "gsl_vector.h" #include "gsl_matrix.h" #include "gsl_complex.h" #include "gsl_complex_math.h" #include "gsl_permute_vector.h" #include "gsl_blas.h" #include "gsl_complex_math.h" #include "gsl_linalg.h" /* Factorise a general N x N complex matrix A into, * * P A = L U * * where P is a permutation matrix, L is unit lower triangular and U * is upper triangular. * * L is stored in the strict lower triangular part of the input * matrix. The diagonal elements of L are unity and are not stored. * * U is stored in the diagonal and upper triangular part of the * input matrix. * * P is stored in the permutation p. Column j of P is column k of the * identity matrix, where k = permutation->data[j] * * signum gives the sign of the permutation, (-1)^n, where n is the * number of interchanges in the permutation. * * See Golub & Van Loan, Matrix Computations, Algorithm 3.4.1 (Gauss * Elimination with Partial Pivoting). */ int gsl_linalg_complex_LU_decomp (gsl_matrix_complex * A, gsl_permutation * p, int *signum) { if (A->size1 != A->size2) { GSL_ERROR ("LU decomposition requires square matrix", GSL_ENOTSQR); } else if (p->size != A->size1) { GSL_ERROR ("permutation length must match matrix size", GSL_EBADLEN); } else { const size_t N = A->size1; size_t i, j, k; *signum = 1; gsl_permutation_init (p); for (j = 0; j < N - 1; j++) { /* Find maximum in the j-th column */ gsl_complex ajj = gsl_matrix_complex_get (A, j, j); double max = gsl_complex_abs (ajj); size_t i_pivot = j; for (i = j + 1; i < N; i++) { gsl_complex aij = gsl_matrix_complex_get (A, i, j); double ai = gsl_complex_abs (aij); if (ai > max) { max = ai; i_pivot = i; } } if (i_pivot != j) { gsl_matrix_complex_swap_rows (A, j, i_pivot); gsl_permutation_swap (p, j, i_pivot); *signum = -(*signum); } ajj = gsl_matrix_complex_get (A, j, j); if (!(GSL_REAL(ajj) == 0.0 && GSL_IMAG(ajj) == 0.0)) { for (i = j + 1; i < N; i++) { gsl_complex aij_orig = gsl_matrix_complex_get (A, i, j); gsl_complex aij = gsl_complex_div (aij_orig, ajj); gsl_matrix_complex_set (A, i, j, aij); for (k = j + 1; k < N; k++) { gsl_complex aik = gsl_matrix_complex_get (A, i, k); gsl_complex ajk = gsl_matrix_complex_get (A, j, k); /* aik = aik - aij * ajk */ gsl_complex aijajk = gsl_complex_mul (aij, ajk); gsl_complex aik_new = gsl_complex_sub (aik, aijajk); gsl_matrix_complex_set (A, i, k, aik_new); } } } } return GSL_SUCCESS; } } int gsl_linalg_complex_LU_solve (const gsl_matrix_complex * LU, const gsl_permutation * p, const gsl_vector_complex * b, gsl_vector_complex * x) { if (LU->size1 != LU->size2) { GSL_ERROR ("LU matrix must be square", GSL_ENOTSQR); } else if (LU->size1 != p->size) { GSL_ERROR ("permutation length must match matrix size", GSL_EBADLEN); } else if (LU->size1 != b->size) { GSL_ERROR ("matrix size must match b size", GSL_EBADLEN); } else if (LU->size2 != x->size) { GSL_ERROR ("matrix size must match solution size", GSL_EBADLEN); } else { /* Copy x <- b */ gsl_vector_complex_memcpy (x, b); /* Solve for x */ gsl_linalg_complex_LU_svx (LU, p, x); return GSL_SUCCESS; } } int gsl_linalg_complex_LU_svx (const gsl_matrix_complex * LU, const gsl_permutation * p, gsl_vector_complex * x) { if (LU->size1 != LU->size2) { GSL_ERROR ("LU matrix must be square", GSL_ENOTSQR); } else if (LU->size1 != p->size) { GSL_ERROR ("permutation length must match matrix size", GSL_EBADLEN); } else if (LU->size1 != x->size) { GSL_ERROR ("matrix size must match solution/rhs size", GSL_EBADLEN); } else { /* Apply permutation to RHS */ gsl_permute_vector_complex (p, x); /* Solve for c using forward-substitution, L c = P b */ gsl_blas_ztrsv (CblasLower, CblasNoTrans, CblasUnit, LU, x); /* Perform back-substitution, U x = c */ gsl_blas_ztrsv (CblasUpper, CblasNoTrans, CblasNonUnit, LU, x); return GSL_SUCCESS; } } int gsl_linalg_complex_LU_refine (const gsl_matrix_complex * A, const gsl_matrix_complex * LU, const gsl_permutation * p, const gsl_vector_complex * b, gsl_vector_complex * x, gsl_vector_complex * residual) { if (A->size1 != A->size2) { GSL_ERROR ("matrix a must be square", GSL_ENOTSQR); } if (LU->size1 != LU->size2) { GSL_ERROR ("LU matrix must be square", GSL_ENOTSQR); } else if (A->size1 != LU->size2) { GSL_ERROR ("LU matrix must be decomposition of a", GSL_ENOTSQR); } else if (LU->size1 != p->size) { GSL_ERROR ("permutation length must match matrix size", GSL_EBADLEN); } else if (LU->size1 != b->size) { GSL_ERROR ("matrix size must match b size", GSL_EBADLEN); } else if (LU->size1 != x->size) { GSL_ERROR ("matrix size must match solution size", GSL_EBADLEN); } else { /* Compute residual, residual = (A * x - b) */ gsl_vector_complex_memcpy (residual, b); { gsl_complex one = GSL_COMPLEX_ONE; gsl_complex negone = GSL_COMPLEX_NEGONE; gsl_blas_zgemv (CblasNoTrans, one, A, x, negone, residual); } /* Find correction, delta = - (A^-1) * residual, and apply it */ gsl_linalg_complex_LU_svx (LU, p, residual); { gsl_complex negone= GSL_COMPLEX_NEGONE; gsl_blas_zaxpy (negone, residual, x); } return GSL_SUCCESS; } } int gsl_linalg_complex_LU_invert (const gsl_matrix_complex * LU, const gsl_permutation * p, gsl_matrix_complex * inverse) { size_t i, n = LU->size1; int status = GSL_SUCCESS; gsl_matrix_complex_set_identity (inverse); for (i = 0; i < n; i++) { gsl_vector_complex_view c = gsl_matrix_complex_column (inverse, i); int status_i = gsl_linalg_complex_LU_svx (LU, p, &(c.vector)); if (status_i) status = status_i; } return status; } gsl_complex gsl_linalg_complex_LU_det (gsl_matrix_complex * LU, int signum) { size_t i, n = LU->size1; gsl_complex det = gsl_complex_rect((double) signum, 0.0); for (i = 0; i < n; i++) { gsl_complex zi = gsl_matrix_complex_get (LU, i, i); det = gsl_complex_mul (det, zi); } return det; } double gsl_linalg_complex_LU_lndet (gsl_matrix_complex * LU) { size_t i, n = LU->size1; double lndet = 0.0; for (i = 0; i < n; i++) { gsl_complex z = gsl_matrix_complex_get (LU, i, i); lndet += log (gsl_complex_abs (z)); } return lndet; } gsl_complex gsl_linalg_complex_LU_sgndet (gsl_matrix_complex * LU, int signum) { size_t i, n = LU->size1; gsl_complex phase = gsl_complex_rect((double) signum, 0.0); for (i = 0; i < n; i++) { gsl_complex z = gsl_matrix_complex_get (LU, i, i); double r = gsl_complex_abs(z); if (r == 0) { phase = gsl_complex_rect(0.0, 0.0); break; } else { z = gsl_complex_div_real(z, r); phase = gsl_complex_mul(phase, z); } } return phase; } praat-6.0.04/external/gsl/gsl_linalg__multiply.c000066400000000000000000000100011261542461700216740ustar00rootroot00000000000000/* linalg/multiply.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_linalg.h" #define SWAP_SIZE_T(a, b) do { size_t swap_tmp = a; a = b; b = swap_tmp; } while(0) int gsl_linalg_matmult (const gsl_matrix * A, const gsl_matrix * B, gsl_matrix * C) { if (A->size2 != B->size1 || A->size1 != C->size1 || B->size2 != C->size2) { GSL_ERROR ("matrix sizes are not conformant", GSL_EBADLEN); } else { double a, b; double temp; size_t i, j, k; for (i = 0; i < C->size1; i++) { for (j = 0; j < C->size2; j++) { a = gsl_matrix_get (A, i, 0); b = gsl_matrix_get (B, 0, j); temp = a * b; for (k = 1; k < A->size2; k++) { a = gsl_matrix_get (A, i, k); b = gsl_matrix_get (B, k, j); temp += a * b; } gsl_matrix_set (C, i, j, temp); } } return GSL_SUCCESS; } } int gsl_linalg_matmult_mod (const gsl_matrix * A, gsl_linalg_matrix_mod_t modA, const gsl_matrix * B, gsl_linalg_matrix_mod_t modB, gsl_matrix * C) { if (modA == GSL_LINALG_MOD_NONE && modB == GSL_LINALG_MOD_NONE) { return gsl_linalg_matmult (A, B, C); } else { size_t dim1_A = A->size1; size_t dim2_A = A->size2; size_t dim1_B = B->size1; size_t dim2_B = B->size2; size_t dim1_C = C->size1; size_t dim2_C = C->size2; if (modA & GSL_LINALG_MOD_TRANSPOSE) SWAP_SIZE_T (dim1_A, dim2_A); if (modB & GSL_LINALG_MOD_TRANSPOSE) SWAP_SIZE_T (dim1_B, dim2_B); if (dim2_A != dim1_B || dim1_A != dim1_C || dim2_B != dim2_C) { GSL_ERROR ("matrix sizes are not conformant", GSL_EBADLEN); } else { double a, b; double temp; size_t i, j, k; size_t a1, a2, b1, b2; for (i = 0; i < dim1_C; i++) { for (j = 0; j < dim2_C; j++) { a1 = i; a2 = 0; b1 = 0; b2 = j; if (modA & GSL_LINALG_MOD_TRANSPOSE) SWAP_SIZE_T (a1, a2); if (modB & GSL_LINALG_MOD_TRANSPOSE) SWAP_SIZE_T (b1, b2); a = gsl_matrix_get (A, a1, a2); b = gsl_matrix_get (B, b1, b2); temp = a * b; for (k = 1; k < dim2_A; k++) { a1 = i; a2 = k; b1 = k; b2 = j; if (modA & GSL_LINALG_MOD_TRANSPOSE) SWAP_SIZE_T (a1, a2); if (modB & GSL_LINALG_MOD_TRANSPOSE) SWAP_SIZE_T (b1, b2); a = gsl_matrix_get (A, a1, a2); b = gsl_matrix_get (B, b1, b2); temp += a * b; } gsl_matrix_set (C, i, j, temp); } } return GSL_SUCCESS; } } } praat-6.0.04/external/gsl/gsl_linalg__ptlq.c000066400000000000000000000321141261542461700210060ustar00rootroot00000000000000/* linalg/ptlq.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * Copyright (C) 2004 Joerg Wensch, modifications for LQ. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_blas.h" #include "gsl_math.h" #include "gsl_vector.h" #include "gsl_matrix.h" #include "gsl_permute_vector.h" #include "gsl_linalg.h" #include "gsl_linalg__givens.c" #include "gsl_linalg__apply_givens.c" /* The purpose of this package is to speed up QR-decomposition for large matrices. Because QR-decomposition is column oriented, but GSL uses a row-oriented matrix format, there can considerable speedup obtained by computing the LQ-decomposition of the transposed matrix instead. This package provides LQ-decomposition and related algorithms. */ /* Factorise a general N x M matrix A into * * P A = L Q * * where Q is orthogonal (M x M) and L is lower triangular (N x M). * When A is rank deficient, r = rank(A) < n, then the permutation is * used to ensure that the lower n - r columns of L are zero and the first * l rows of Q form an orthonormal basis for the rows of A. * * Q is stored as a packed set of Householder transformations in the * strict upper triangular part of the input matrix. * * L is stored in the diagonal and lower triangle of the input matrix. * * P: column j of P is column k of the identity matrix, where k = * permutation->data[j] * * The full matrix for Q can be obtained as the product * * Q = Q_k .. Q_2 Q_1 * * where k = MIN(M,N) and * * Q_i = (I - tau_i * v_i * v_i') * * and where v_i is a Householder vector * * v_i = [1, m(i,i+1), m(i,i+2), ... , m(i,M)] * * This storage scheme is the same as in LAPACK. See LAPACK's * dgeqpf.f for details. * */ int gsl_linalg_PTLQ_decomp (gsl_matrix * A, gsl_vector * tau, gsl_permutation * p, int *signum, gsl_vector * norm) { const size_t N = A->size1; const size_t M = A->size2; if (tau->size != GSL_MIN (M, N)) { GSL_ERROR ("size of tau must be MIN(M,N)", GSL_EBADLEN); } else if (p->size != N) { GSL_ERROR ("permutation size must be N", GSL_EBADLEN); } else if (norm->size != N) { GSL_ERROR ("norm size must be N", GSL_EBADLEN); } else { size_t i; *signum = 1; gsl_permutation_init (p); /* set to identity */ /* Compute column norms and store in workspace */ for (i = 0; i < N; i++) { gsl_vector_view c = gsl_matrix_row (A, i); double x = gsl_blas_dnrm2 (&c.vector); gsl_vector_set (norm, i, x); } for (i = 0; i < GSL_MIN (M, N); i++) { /* Bring the column of largest norm into the pivot position */ double max_norm = gsl_vector_get(norm, i); size_t j, kmax = i; for (j = i + 1; j < N; j++) { double x = gsl_vector_get (norm, j); if (x > max_norm) { max_norm = x; kmax = j; } } if (kmax != i) { gsl_matrix_swap_rows (A, i, kmax); gsl_permutation_swap (p, i, kmax); gsl_vector_swap_elements(norm,i,kmax); (*signum) = -(*signum); } /* Compute the Householder transformation to reduce the j-th column of the matrix to a multiple of the j-th unit vector */ { gsl_vector_view c_full = gsl_matrix_row (A, i); gsl_vector_view c = gsl_vector_subvector (&c_full.vector, i, M - i); double tau_i = gsl_linalg_householder_transform (&c.vector); gsl_vector_set (tau, i, tau_i); /* Apply the transformation to the remaining columns */ if (i + 1 < N) { gsl_matrix_view m = gsl_matrix_submatrix (A, i +1, i, N - (i+1), M - i); gsl_linalg_householder_mh (tau_i, &c.vector, &m.matrix); } } /* Update the norms of the remaining columns too */ if (i + 1 < M) { for (j = i + 1; j < N; j++) { double x = gsl_vector_get (norm, j); if (x > 0.0) { double y = 0; double temp= gsl_matrix_get (A, j, i) / x; if (fabs (temp) >= 1) y = 0.0; else y = x * sqrt (1 - temp * temp); /* recompute norm to prevent loss of accuracy */ if (fabs (y / x) < sqrt (20.0) * GSL_SQRT_DBL_EPSILON) { gsl_vector_view c_full = gsl_matrix_row (A, j); gsl_vector_view c = gsl_vector_subvector(&c_full.vector, i+1, M - (i+1)); y = gsl_blas_dnrm2 (&c.vector); } gsl_vector_set (norm, j, y); } } } } return GSL_SUCCESS; } } int gsl_linalg_PTLQ_decomp2 (const gsl_matrix * A, gsl_matrix * q, gsl_matrix * r, gsl_vector * tau, gsl_permutation * p, int *signum, gsl_vector * norm) { const size_t N = A->size1; const size_t M = A->size2; if (q->size1 != M || q->size2 !=M) { GSL_ERROR ("q must be M x M", GSL_EBADLEN); } else if (r->size1 != N || r->size2 !=M) { GSL_ERROR ("r must be N x M", GSL_EBADLEN); } else if (tau->size != GSL_MIN (M, N)) { GSL_ERROR ("size of tau must be MIN(M,N)", GSL_EBADLEN); } else if (p->size != N) { GSL_ERROR ("permutation size must be N", GSL_EBADLEN); } else if (norm->size != N) { GSL_ERROR ("norm size must be N", GSL_EBADLEN); } gsl_matrix_memcpy (r, A); gsl_linalg_PTLQ_decomp (r, tau, p, signum, norm); /* FIXME: aliased arguments depends on behavior of unpack routine! */ gsl_linalg_LQ_unpack (r, tau, q, r); return GSL_SUCCESS; } /* Solves the system x^T A = b^T using the P^T L Q factorisation, z^T L = b^T Q^T x = P z; to obtain x. Based on SLATEC code. */ int gsl_linalg_PTLQ_solve_T (const gsl_matrix * QR, const gsl_vector * tau, const gsl_permutation * p, const gsl_vector * b, gsl_vector * x) { if (QR->size1 != QR->size2) { GSL_ERROR ("QR matrix must be square", GSL_ENOTSQR); } else if (QR->size2 != p->size) { GSL_ERROR ("matrix size must match permutation size", GSL_EBADLEN); } else if (QR->size2 != b->size) { GSL_ERROR ("matrix size must match b size", GSL_EBADLEN); } else if (QR->size1 != x->size) { GSL_ERROR ("matrix size must match solution size", GSL_EBADLEN); } else { gsl_vector_memcpy (x, b); gsl_linalg_PTLQ_svx_T (QR, tau, p, x); return GSL_SUCCESS; } } int gsl_linalg_PTLQ_svx_T (const gsl_matrix * LQ, const gsl_vector * tau, const gsl_permutation * p, gsl_vector * x) { if (LQ->size1 != LQ->size2) { GSL_ERROR ("LQ matrix must be square", GSL_ENOTSQR); } else if (LQ->size2 != p->size) { GSL_ERROR ("matrix size must match permutation size", GSL_EBADLEN); } else if (LQ->size1 != x->size) { GSL_ERROR ("matrix size must match solution size", GSL_EBADLEN); } else { /* compute sol = b^T Q^T */ gsl_linalg_LQ_vecQT (LQ, tau, x); /* Solve L^T x = sol, storing x inplace in sol */ gsl_blas_dtrsv (CblasLower, CblasTrans, CblasNonUnit, LQ, x); gsl_permute_vector_inverse (p, x); return GSL_SUCCESS; } } int gsl_linalg_PTLQ_LQsolve_T (const gsl_matrix * Q, const gsl_matrix * L, const gsl_permutation * p, const gsl_vector * b, gsl_vector * x) { if (Q->size1 != Q->size2 || L->size1 != L->size2) { return GSL_ENOTSQR; } else if (Q->size1 != p->size || Q->size1 != L->size1 || Q->size1 != b->size) { return GSL_EBADLEN; } else { /* compute b' = Q b */ gsl_blas_dgemv (CblasNoTrans, 1.0, Q, b, 0.0, x); /* Solve L^T x = b', storing x inplace */ gsl_blas_dtrsv (CblasLower, CblasTrans, CblasNonUnit, L, x); /* Apply permutation to solution in place */ gsl_permute_vector_inverse (p, x); return GSL_SUCCESS; } } int gsl_linalg_PTLQ_Lsolve_T (const gsl_matrix * LQ, const gsl_permutation * p, const gsl_vector * b, gsl_vector * x) { if (LQ->size1 != LQ->size2) { GSL_ERROR ("LQ matrix must be square", GSL_ENOTSQR); } else if (LQ->size1 != b->size) { GSL_ERROR ("matrix size must match b size", GSL_EBADLEN); } else if (LQ->size2 != x->size) { GSL_ERROR ("matrix size must match x size", GSL_EBADLEN); } else if (p->size != x->size) { GSL_ERROR ("permutation size must match x size", GSL_EBADLEN); } else { /* Copy x <- b */ gsl_vector_memcpy (x, b); /* Solve L^T x = b, storing x inplace */ gsl_blas_dtrsv (CblasLower, CblasTrans, CblasNonUnit, LQ, x); gsl_permute_vector_inverse (p, x); return GSL_SUCCESS; } } int gsl_linalg_PTLQ_Lsvx_T (const gsl_matrix * LQ, const gsl_permutation * p, gsl_vector * x) { if (LQ->size1 != LQ->size2) { GSL_ERROR ("LQ matrix must be square", GSL_ENOTSQR); } else if (LQ->size2 != x->size) { GSL_ERROR ("matrix size must match x size", GSL_EBADLEN); } else if (p->size != x->size) { GSL_ERROR ("permutation size must match x size", GSL_EBADLEN); } else { /* Solve L^T x = b, storing x inplace */ gsl_blas_dtrsv (CblasLower, CblasTrans, CblasNonUnit, LQ, x); gsl_permute_vector_inverse (p, x); return GSL_SUCCESS; } } /* Update a P^T L Q factorisation for P A= L Q , A' = A + v u^T, PA' = PA + Pv u^T * P^T L' Q' = P^T LQ + v u^T * = P^T (L + (P v) u^T Q^T) Q * = P^T (L + (P v) w^T) Q * * where w = Q^T u. * * Algorithm from Golub and Van Loan, "Matrix Computations", Section * 12.5 (Updating Matrix Factorizations, Rank-One Changes) */ int gsl_linalg_PTLQ_update (gsl_matrix * Q, gsl_matrix * L, const gsl_permutation * p, const gsl_vector * v, gsl_vector * w) { if (Q->size1 != Q->size2 || L->size1 != L->size2) { return GSL_ENOTSQR; } else if (L->size1 != Q->size2 || v->size != Q->size2 || w->size != Q->size2) { return GSL_EBADLEN; } else { size_t j, k; const size_t N = Q->size1; const size_t M = Q->size2; double w0; /* Apply Given's rotations to reduce w to (|w|, 0, 0, ... , 0) J_1^T .... J_(n-1)^T w = +/- |w| e_1 simultaneously applied to L, H = J_1^T ... J^T_(n-1) L so that H is upper Hessenberg. (12.5.2) */ for (k = M - 1; k > 0; k--) { double c, s; double wk = gsl_vector_get (w, k); double wkm1 = gsl_vector_get (w, k - 1); create_givens (wkm1, wk, &c, &s); apply_givens_vec (w, k - 1, k, c, s); apply_givens_lq (M, N, Q, L, k - 1, k, c, s); } w0 = gsl_vector_get (w, 0); /* Add in v w^T (Equation 12.5.3) */ for (j = 0; j < N; j++) { double lj0 = gsl_matrix_get (L, j, 0); size_t p_j = gsl_permutation_get (p, j); double vj = gsl_vector_get (v, p_j); gsl_matrix_set (L, j, 0, lj0 + w0 * vj); } /* Apply Givens transformations L' = G_(n-1)^T ... G_1^T H Equation 12.5.4 */ for (k = 1; k < N; k++) { double c, s; double diag = gsl_matrix_get (L, k - 1, k - 1); double offdiag = gsl_matrix_get (L, k - 1, k ); create_givens (diag, offdiag, &c, &s); apply_givens_lq (M, N, Q, L, k - 1, k, c, s); } return GSL_SUCCESS; } } praat-6.0.04/external/gsl/gsl_linalg__qr.c000066400000000000000000000346771261542461700204700ustar00rootroot00000000000000/* linalg/qr.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include #include #include "gsl_math.h" #include "gsl_vector.h" #include "gsl_matrix.h" #include "gsl_blas.h" #include "gsl_linalg.h" #define REAL double #include "gsl_linalg__givens.c" #include "gsl_linalg__apply_givens.c" /* Factorise a general M x N matrix A into * * A = Q R * * where Q is orthogonal (M x M) and R is upper triangular (M x N). * * Q is stored as a packed set of Householder transformations in the * strict lower triangular part of the input matrix. * * R is stored in the diagonal and upper triangle of the input matrix. * * The full matrix for Q can be obtained as the product * * Q = Q_k .. Q_2 Q_1 * * where k = MIN(M,N) and * * Q_i = (I - tau_i * v_i * v_i') * * and where v_i is a Householder vector * * v_i = [1, m(i+1,i), m(i+2,i), ... , m(M,i)] * * This storage scheme is the same as in LAPACK. */ int gsl_linalg_QR_decomp (gsl_matrix * A, gsl_vector * tau) { const size_t M = A->size1; const size_t N = A->size2; if (tau->size != GSL_MIN (M, N)) { GSL_ERROR ("size of tau must be MIN(M,N)", GSL_EBADLEN); } else { size_t i; for (i = 0; i < GSL_MIN (M, N); i++) { /* Compute the Householder transformation to reduce the j-th column of the matrix to a multiple of the j-th unit vector */ gsl_vector_view c_full = gsl_matrix_column (A, i); gsl_vector_view c = gsl_vector_subvector (&(c_full.vector), i, M-i); double tau_i = gsl_linalg_householder_transform (&(c.vector)); gsl_vector_set (tau, i, tau_i); /* Apply the transformation to the remaining columns and update the norms */ if (i + 1 < N) { gsl_matrix_view m = gsl_matrix_submatrix (A, i, i + 1, M - i, N - (i + 1)); gsl_linalg_householder_hm (tau_i, &(c.vector), &(m.matrix)); } } return GSL_SUCCESS; } } /* Solves the system A x = b using the QR factorisation, * R x = Q^T b * * to obtain x. Based on SLATEC code. */ int gsl_linalg_QR_solve (const gsl_matrix * QR, const gsl_vector * tau, const gsl_vector * b, gsl_vector * x) { if (QR->size1 != QR->size2) { GSL_ERROR ("QR matrix must be square", GSL_ENOTSQR); } else if (QR->size1 != b->size) { GSL_ERROR ("matrix size must match b size", GSL_EBADLEN); } else if (QR->size2 != x->size) { GSL_ERROR ("matrix size must match solution size", GSL_EBADLEN); } else { /* Copy x <- b */ gsl_vector_memcpy (x, b); /* Solve for x */ gsl_linalg_QR_svx (QR, tau, x); return GSL_SUCCESS; } } /* Solves the system A x = b in place using the QR factorisation, * R x = Q^T b * * to obtain x. Based on SLATEC code. */ int gsl_linalg_QR_svx (const gsl_matrix * QR, const gsl_vector * tau, gsl_vector * x) { if (QR->size1 != QR->size2) { GSL_ERROR ("QR matrix must be square", GSL_ENOTSQR); } else if (QR->size1 != x->size) { GSL_ERROR ("matrix size must match x/rhs size", GSL_EBADLEN); } else { /* compute rhs = Q^T b */ gsl_linalg_QR_QTvec (QR, tau, x); /* Solve R x = rhs, storing x in-place */ gsl_blas_dtrsv (CblasUpper, CblasNoTrans, CblasNonUnit, QR, x); return GSL_SUCCESS; } } /* Find the least squares solution to the overdetermined system * * A x = b * * for M >= N using the QR factorization A = Q R. */ int gsl_linalg_QR_lssolve (const gsl_matrix * QR, const gsl_vector * tau, const gsl_vector * b, gsl_vector * x, gsl_vector * residual) { const size_t M = QR->size1; const size_t N = QR->size2; if (M < N) { GSL_ERROR ("QR matrix must have M>=N", GSL_EBADLEN); } else if (M != b->size) { GSL_ERROR ("matrix size must match b size", GSL_EBADLEN); } else if (N != x->size) { GSL_ERROR ("matrix size must match solution size", GSL_EBADLEN); } else if (M != residual->size) { GSL_ERROR ("matrix size must match residual size", GSL_EBADLEN); } else { gsl_matrix_const_view R = gsl_matrix_const_submatrix (QR, 0, 0, N, N); gsl_vector_view c = gsl_vector_subvector(residual, 0, N); gsl_vector_memcpy(residual, b); /* compute rhs = Q^T b */ gsl_linalg_QR_QTvec (QR, tau, residual); /* Solve R x = rhs */ gsl_vector_memcpy(x, &(c.vector)); gsl_blas_dtrsv (CblasUpper, CblasNoTrans, CblasNonUnit, &(R.matrix), x); /* Compute residual = b - A x = Q (Q^T b - R x) */ gsl_vector_set_zero(&(c.vector)); gsl_linalg_QR_Qvec(QR, tau, residual); return GSL_SUCCESS; } } int gsl_linalg_QR_Rsolve (const gsl_matrix * QR, const gsl_vector * b, gsl_vector * x) { if (QR->size1 != QR->size2) { GSL_ERROR ("QR matrix must be square", GSL_ENOTSQR); } else if (QR->size1 != b->size) { GSL_ERROR ("matrix size must match b size", GSL_EBADLEN); } else if (QR->size2 != x->size) { GSL_ERROR ("matrix size must match x size", GSL_EBADLEN); } else { /* Copy x <- b */ gsl_vector_memcpy (x, b); /* Solve R x = b, storing x in-place */ gsl_blas_dtrsv (CblasUpper, CblasNoTrans, CblasNonUnit, QR, x); return GSL_SUCCESS; } } int gsl_linalg_QR_Rsvx (const gsl_matrix * QR, gsl_vector * x) { if (QR->size1 != QR->size2) { GSL_ERROR ("QR matrix must be square", GSL_ENOTSQR); } else if (QR->size1 != x->size) { GSL_ERROR ("matrix size must match rhs size", GSL_EBADLEN); } else { /* Solve R x = b, storing x in-place */ gsl_blas_dtrsv (CblasUpper, CblasNoTrans, CblasNonUnit, QR, x); return GSL_SUCCESS; } } int gsl_linalg_R_solve (const gsl_matrix * R, const gsl_vector * b, gsl_vector * x) { if (R->size1 != R->size2) { GSL_ERROR ("R matrix must be square", GSL_ENOTSQR); } else if (R->size1 != b->size) { GSL_ERROR ("matrix size must match b size", GSL_EBADLEN); } else if (R->size2 != x->size) { GSL_ERROR ("matrix size must match solution size", GSL_EBADLEN); } else { /* Copy x <- b */ gsl_vector_memcpy (x, b); /* Solve R x = b, storing x inplace in b */ gsl_blas_dtrsv (CblasUpper, CblasNoTrans, CblasNonUnit, R, x); return GSL_SUCCESS; } } int gsl_linalg_R_svx (const gsl_matrix * R, gsl_vector * x) { if (R->size1 != R->size2) { GSL_ERROR ("R matrix must be square", GSL_ENOTSQR); } else if (R->size2 != x->size) { GSL_ERROR ("matrix size must match solution size", GSL_EBADLEN); } else { /* Solve R x = b, storing x inplace in b */ gsl_blas_dtrsv (CblasUpper, CblasNoTrans, CblasNonUnit, R, x); return GSL_SUCCESS; } } /* Form the product Q^T v from a QR factorized matrix */ int gsl_linalg_QR_QTvec (const gsl_matrix * QR, const gsl_vector * tau, gsl_vector * v) { const size_t M = QR->size1; const size_t N = QR->size2; if (tau->size != GSL_MIN (M, N)) { GSL_ERROR ("size of tau must be MIN(M,N)", GSL_EBADLEN); } else if (v->size != M) { GSL_ERROR ("vector size must be N", GSL_EBADLEN); } else { size_t i; /* compute Q^T v */ for (i = 0; i < GSL_MIN (M, N); i++) { gsl_vector_const_view c = gsl_matrix_const_column (QR, i); gsl_vector_const_view h = gsl_vector_const_subvector (&(c.vector), i, M - i); gsl_vector_view w = gsl_vector_subvector (v, i, M - i); double ti = gsl_vector_get (tau, i); gsl_linalg_householder_hv (ti, &(h.vector), &(w.vector)); } return GSL_SUCCESS; } } int gsl_linalg_QR_Qvec (const gsl_matrix * QR, const gsl_vector * tau, gsl_vector * v) { const size_t M = QR->size1; const size_t N = QR->size2; if (tau->size != GSL_MIN (M, N)) { GSL_ERROR ("size of tau must be MIN(M,N)", GSL_EBADLEN); } else if (v->size != M) { GSL_ERROR ("vector size must be N", GSL_EBADLEN); } else { size_t i; /* compute Q^T v */ for (i = GSL_MIN (M, N); i > 0 && i--;) { gsl_vector_const_view c = gsl_matrix_const_column (QR, i); gsl_vector_const_view h = gsl_vector_const_subvector (&(c.vector), i, M - i); gsl_vector_view w = gsl_vector_subvector (v, i, M - i); double ti = gsl_vector_get (tau, i); gsl_linalg_householder_hv (ti, &h.vector, &w.vector); } return GSL_SUCCESS; } } /* Form the product Q^T A from a QR factorized matrix */ int gsl_linalg_QR_QTmat (const gsl_matrix * QR, const gsl_vector * tau, gsl_matrix * A) { const size_t M = QR->size1; const size_t N = QR->size2; if (tau->size != GSL_MIN (M, N)) { GSL_ERROR ("size of tau must be MIN(M,N)", GSL_EBADLEN); } else if (A->size1 != M) { GSL_ERROR ("matrix must have M rows", GSL_EBADLEN); } else { size_t i; /* compute Q^T A */ for (i = 0; i < GSL_MIN (M, N); i++) { gsl_vector_const_view c = gsl_matrix_const_column (QR, i); gsl_vector_const_view h = gsl_vector_const_subvector (&(c.vector), i, M - i); gsl_matrix_view m = gsl_matrix_submatrix(A, i, 0, M - i, A->size2); double ti = gsl_vector_get (tau, i); gsl_linalg_householder_hm (ti, &(h.vector), &(m.matrix)); } return GSL_SUCCESS; } } /* Form the orthogonal matrix Q from the packed QR matrix */ int gsl_linalg_QR_unpack (const gsl_matrix * QR, const gsl_vector * tau, gsl_matrix * Q, gsl_matrix * R) { const size_t M = QR->size1; const size_t N = QR->size2; if (Q->size1 != M || Q->size2 != M) { GSL_ERROR ("Q matrix must be M x M", GSL_ENOTSQR); } else if (R->size1 != M || R->size2 != N) { GSL_ERROR ("R matrix must be M x N", GSL_ENOTSQR); } else if (tau->size != GSL_MIN (M, N)) { GSL_ERROR ("size of tau must be MIN(M,N)", GSL_EBADLEN); } else { size_t i, j; /* Initialize Q to the identity */ gsl_matrix_set_identity (Q); for (i = GSL_MIN (M, N); i > 0 && i--;) { gsl_vector_const_view c = gsl_matrix_const_column (QR, i); gsl_vector_const_view h = gsl_vector_const_subvector (&c.vector, i, M - i); gsl_matrix_view m = gsl_matrix_submatrix (Q, i, i, M - i, M - i); double ti = gsl_vector_get (tau, i); gsl_linalg_householder_hm (ti, &h.vector, &m.matrix); } /* Form the right triangular matrix R from a packed QR matrix */ for (i = 0; i < M; i++) { for (j = 0; j < i && j < N; j++) gsl_matrix_set (R, i, j, 0.0); for (j = i; j < N; j++) gsl_matrix_set (R, i, j, gsl_matrix_get (QR, i, j)); } return GSL_SUCCESS; } } /* Update a QR factorisation for A= Q R , A' = A + u v^T, * Q' R' = QR + u v^T * = Q (R + Q^T u v^T) * = Q (R + w v^T) * * where w = Q^T u. * * Algorithm from Golub and Van Loan, "Matrix Computations", Section * 12.5 (Updating Matrix Factorizations, Rank-One Changes) */ int gsl_linalg_QR_update (gsl_matrix * Q, gsl_matrix * R, gsl_vector * w, const gsl_vector * v) { const size_t M = R->size1; const size_t N = R->size2; if (Q->size1 != M || Q->size2 != M) { GSL_ERROR ("Q matrix must be M x M if R is M x N", GSL_ENOTSQR); } else if (w->size != M) { GSL_ERROR ("w must be length M if R is M x N", GSL_EBADLEN); } else if (v->size != N) { GSL_ERROR ("v must be length N if R is M x N", GSL_EBADLEN); } else { size_t j, k; double w0; /* Apply Given's rotations to reduce w to (|w|, 0, 0, ... , 0) J_1^T .... J_(n-1)^T w = +/- |w| e_1 simultaneously applied to R, H = J_1^T ... J^T_(n-1) R so that H is upper Hessenberg. (12.5.2) */ for (k = M - 1; k > 0; k--) { double c, s; double wk = gsl_vector_get (w, k); double wkm1 = gsl_vector_get (w, k - 1); create_givens (wkm1, wk, &c, &s); apply_givens_vec (w, k - 1, k, c, s); apply_givens_qr (M, N, Q, R, k - 1, k, c, s); } w0 = gsl_vector_get (w, 0); /* Add in w v^T (Equation 12.5.3) */ for (j = 0; j < N; j++) { double r0j = gsl_matrix_get (R, 0, j); double vj = gsl_vector_get (v, j); gsl_matrix_set (R, 0, j, r0j + w0 * vj); } /* Apply Givens transformations R' = G_(n-1)^T ... G_1^T H Equation 12.5.4 */ for (k = 1; k < GSL_MIN(M,N+1); k++) { double c, s; double diag = gsl_matrix_get (R, k - 1, k - 1); double offdiag = gsl_matrix_get (R, k, k - 1); create_givens (diag, offdiag, &c, &s); apply_givens_qr (M, N, Q, R, k - 1, k, c, s); gsl_matrix_set (R, k, k - 1, 0.0); /* exact zero of G^T */ } return GSL_SUCCESS; } } int gsl_linalg_QR_QRsolve (gsl_matrix * Q, gsl_matrix * R, const gsl_vector * b, gsl_vector * x) { const size_t M = R->size1; const size_t N = R->size2; if (M != N) { return GSL_ENOTSQR; } else if (Q->size1 != M || b->size != M || x->size != M) { return GSL_EBADLEN; } else { /* compute sol = Q^T b */ gsl_blas_dgemv (CblasTrans, 1.0, Q, b, 0.0, x); /* Solve R x = sol, storing x in-place */ gsl_blas_dtrsv (CblasUpper, CblasNoTrans, CblasNonUnit, R, x); return GSL_SUCCESS; } } praat-6.0.04/external/gsl/gsl_linalg__qrpt.c000066400000000000000000000310661261542461700210210ustar00rootroot00000000000000/* linalg/qrpt.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_math.h" #include "gsl_vector.h" #include "gsl_matrix.h" #include "gsl_permute_vector.h" #include "gsl_blas.h" #include "gsl_linalg.h" #define REAL double #include "gsl_linalg__givens.c" #include "gsl_linalg__apply_givens.c" /* Factorise a general M x N matrix A into * * A P = Q R * * where Q is orthogonal (M x M) and R is upper triangular (M x N). * When A is rank deficient, r = rank(A) < n, then the permutation is * used to ensure that the lower n - r rows of R are zero and the first * r columns of Q form an orthonormal basis for A. * * Q is stored as a packed set of Householder transformations in the * strict lower triangular part of the input matrix. * * R is stored in the diagonal and upper triangle of the input matrix. * * P: column j of P is column k of the identity matrix, where k = * permutation->data[j] * * The full matrix for Q can be obtained as the product * * Q = Q_k .. Q_2 Q_1 * * where k = MIN(M,N) and * * Q_i = (I - tau_i * v_i * v_i') * * and where v_i is a Householder vector * * v_i = [1, m(i+1,i), m(i+2,i), ... , m(M,i)] * * This storage scheme is the same as in LAPACK. See LAPACK's * dgeqpf.f for details. * */ int gsl_linalg_QRPT_decomp (gsl_matrix * A, gsl_vector * tau, gsl_permutation * p, int *signum, gsl_vector * norm) { const size_t M = A->size1; const size_t N = A->size2; if (tau->size != GSL_MIN (M, N)) { GSL_ERROR ("size of tau must be MIN(M,N)", GSL_EBADLEN); } else if (p->size != N) { GSL_ERROR ("permutation size must be N", GSL_EBADLEN); } else if (norm->size != N) { GSL_ERROR ("norm size must be N", GSL_EBADLEN); } else { size_t i; *signum = 1; gsl_permutation_init (p); /* set to identity */ /* Compute column norms and store in workspace */ for (i = 0; i < N; i++) { gsl_vector_view c = gsl_matrix_column (A, i); double x = gsl_blas_dnrm2 (&c.vector); gsl_vector_set (norm, i, x); } for (i = 0; i < GSL_MIN (M, N); i++) { /* Bring the column of largest norm into the pivot position */ double max_norm = gsl_vector_get(norm, i); size_t j, kmax = i; for (j = i + 1; j < N; j++) { double x = gsl_vector_get (norm, j); if (x > max_norm) { max_norm = x; kmax = j; } } if (kmax != i) { gsl_matrix_swap_columns (A, i, kmax); gsl_permutation_swap (p, i, kmax); gsl_vector_swap_elements(norm,i,kmax); (*signum) = -(*signum); } /* Compute the Householder transformation to reduce the j-th column of the matrix to a multiple of the j-th unit vector */ { gsl_vector_view c_full = gsl_matrix_column (A, i); gsl_vector_view c = gsl_vector_subvector (&c_full.vector, i, M - i); double tau_i = gsl_linalg_householder_transform (&c.vector); gsl_vector_set (tau, i, tau_i); /* Apply the transformation to the remaining columns */ if (i + 1 < N) { gsl_matrix_view m = gsl_matrix_submatrix (A, i, i + 1, M - i, N - (i+1)); gsl_linalg_householder_hm (tau_i, &c.vector, &m.matrix); } } /* Update the norms of the remaining columns too */ if (i + 1 < M) { for (j = i + 1; j < N; j++) { double x = gsl_vector_get (norm, j); if (x > 0.0) { double y = 0; double temp= gsl_matrix_get (A, i, j) / x; if (fabs (temp) >= 1) y = 0.0; else y = x * sqrt (1 - temp * temp); /* recompute norm to prevent loss of accuracy */ if (fabs (y / x) < sqrt (20.0) * GSL_SQRT_DBL_EPSILON) { gsl_vector_view c_full = gsl_matrix_column (A, j); gsl_vector_view c = gsl_vector_subvector(&c_full.vector, i+1, M - (i+1)); y = gsl_blas_dnrm2 (&c.vector); } gsl_vector_set (norm, j, y); } } } } return GSL_SUCCESS; } } int gsl_linalg_QRPT_decomp2 (const gsl_matrix * A, gsl_matrix * q, gsl_matrix * r, gsl_vector * tau, gsl_permutation * p, int *signum, gsl_vector * norm) { const size_t M = A->size1; const size_t N = A->size2; if (q->size1 != M || q->size2 !=M) { GSL_ERROR ("q must be M x M", GSL_EBADLEN); } else if (r->size1 != M || r->size2 !=N) { GSL_ERROR ("r must be M x N", GSL_EBADLEN); } else if (tau->size != GSL_MIN (M, N)) { GSL_ERROR ("size of tau must be MIN(M,N)", GSL_EBADLEN); } else if (p->size != N) { GSL_ERROR ("permutation size must be N", GSL_EBADLEN); } else if (norm->size != N) { GSL_ERROR ("norm size must be N", GSL_EBADLEN); } gsl_matrix_memcpy (r, A); gsl_linalg_QRPT_decomp (r, tau, p, signum, norm); /* FIXME: aliased arguments depends on behavior of unpack routine! */ gsl_linalg_QR_unpack (r, tau, q, r); return GSL_SUCCESS; } /* Solves the system A x = b using the Q R P^T factorisation, R z = Q^T b x = P z; to obtain x. Based on SLATEC code. */ int gsl_linalg_QRPT_solve (const gsl_matrix * QR, const gsl_vector * tau, const gsl_permutation * p, const gsl_vector * b, gsl_vector * x) { if (QR->size1 != QR->size2) { GSL_ERROR ("QR matrix must be square", GSL_ENOTSQR); } else if (QR->size1 != p->size) { GSL_ERROR ("matrix size must match permutation size", GSL_EBADLEN); } else if (QR->size1 != b->size) { GSL_ERROR ("matrix size must match b size", GSL_EBADLEN); } else if (QR->size2 != x->size) { GSL_ERROR ("matrix size must match solution size", GSL_EBADLEN); } else { gsl_vector_memcpy (x, b); gsl_linalg_QRPT_svx (QR, tau, p, x); return GSL_SUCCESS; } } int gsl_linalg_QRPT_svx (const gsl_matrix * QR, const gsl_vector * tau, const gsl_permutation * p, gsl_vector * x) { if (QR->size1 != QR->size2) { GSL_ERROR ("QR matrix must be square", GSL_ENOTSQR); } else if (QR->size1 != p->size) { GSL_ERROR ("matrix size must match permutation size", GSL_EBADLEN); } else if (QR->size2 != x->size) { GSL_ERROR ("matrix size must match solution size", GSL_EBADLEN); } else { /* compute sol = Q^T b */ gsl_linalg_QR_QTvec (QR, tau, x); /* Solve R x = sol, storing x inplace in sol */ gsl_blas_dtrsv (CblasUpper, CblasNoTrans, CblasNonUnit, QR, x); gsl_permute_vector_inverse (p, x); return GSL_SUCCESS; } } int gsl_linalg_QRPT_QRsolve (const gsl_matrix * Q, const gsl_matrix * R, const gsl_permutation * p, const gsl_vector * b, gsl_vector * x) { if (Q->size1 != Q->size2 || R->size1 != R->size2) { return GSL_ENOTSQR; } else if (Q->size1 != p->size || Q->size1 != R->size1 || Q->size1 != b->size) { return GSL_EBADLEN; } else { /* compute b' = Q^T b */ gsl_blas_dgemv (CblasTrans, 1.0, Q, b, 0.0, x); /* Solve R x = b', storing x inplace */ gsl_blas_dtrsv (CblasUpper, CblasNoTrans, CblasNonUnit, R, x); /* Apply permutation to solution in place */ gsl_permute_vector_inverse (p, x); return GSL_SUCCESS; } } int gsl_linalg_QRPT_Rsolve (const gsl_matrix * QR, const gsl_permutation * p, const gsl_vector * b, gsl_vector * x) { if (QR->size1 != QR->size2) { GSL_ERROR ("QR matrix must be square", GSL_ENOTSQR); } else if (QR->size1 != b->size) { GSL_ERROR ("matrix size must match b size", GSL_EBADLEN); } else if (QR->size2 != x->size) { GSL_ERROR ("matrix size must match x size", GSL_EBADLEN); } else if (p->size != x->size) { GSL_ERROR ("permutation size must match x size", GSL_EBADLEN); } else { /* Copy x <- b */ gsl_vector_memcpy (x, b); /* Solve R x = b, storing x inplace */ gsl_blas_dtrsv (CblasUpper, CblasNoTrans, CblasNonUnit, QR, x); gsl_permute_vector_inverse (p, x); return GSL_SUCCESS; } } int gsl_linalg_QRPT_Rsvx (const gsl_matrix * QR, const gsl_permutation * p, gsl_vector * x) { if (QR->size1 != QR->size2) { GSL_ERROR ("QR matrix must be square", GSL_ENOTSQR); } else if (QR->size2 != x->size) { GSL_ERROR ("matrix size must match x size", GSL_EBADLEN); } else if (p->size != x->size) { GSL_ERROR ("permutation size must match x size", GSL_EBADLEN); } else { /* Solve R x = b, storing x inplace */ gsl_blas_dtrsv (CblasUpper, CblasNoTrans, CblasNonUnit, QR, x); gsl_permute_vector_inverse (p, x); return GSL_SUCCESS; } } /* Update a Q R P^T factorisation for A P= Q R , A' = A + u v^T, Q' R' P^-1 = QR P^-1 + u v^T = Q (R + Q^T u v^T P ) P^-1 = Q (R + w v^T P) P^-1 where w = Q^T u. Algorithm from Golub and Van Loan, "Matrix Computations", Section 12.5 (Updating Matrix Factorizations, Rank-One Changes) */ int gsl_linalg_QRPT_update (gsl_matrix * Q, gsl_matrix * R, const gsl_permutation * p, gsl_vector * w, const gsl_vector * v) { if (Q->size1 != Q->size2 || R->size1 != R->size2) { return GSL_ENOTSQR; } else if (R->size1 != Q->size2 || v->size != Q->size2 || w->size != Q->size2) { return GSL_EBADLEN; } else { size_t j, k; const size_t M = Q->size1; const size_t N = Q->size2; double w0; /* Apply Given's rotations to reduce w to (|w|, 0, 0, ... , 0) J_1^T .... J_(n-1)^T w = +/- |w| e_1 simultaneously applied to R, H = J_1^T ... J^T_(n-1) R so that H is upper Hessenberg. (12.5.2) */ for (k = N - 1; k > 0; k--) { double c, s; double wk = gsl_vector_get (w, k); double wkm1 = gsl_vector_get (w, k - 1); create_givens (wkm1, wk, &c, &s); apply_givens_vec (w, k - 1, k, c, s); apply_givens_qr (M, N, Q, R, k - 1, k, c, s); } w0 = gsl_vector_get (w, 0); /* Add in w v^T (Equation 12.5.3) */ for (j = 0; j < N; j++) { double r0j = gsl_matrix_get (R, 0, j); size_t p_j = gsl_permutation_get (p, j); double vj = gsl_vector_get (v, p_j); gsl_matrix_set (R, 0, j, r0j + w0 * vj); } /* Apply Givens transformations R' = G_(n-1)^T ... G_1^T H Equation 12.5.4 */ for (k = 1; k < N; k++) { double c, s; double diag = gsl_matrix_get (R, k - 1, k - 1); double offdiag = gsl_matrix_get (R, k, k - 1); create_givens (diag, offdiag, &c, &s); apply_givens_qr (M, N, Q, R, k - 1, k, c, s); } return GSL_SUCCESS; } } praat-6.0.04/external/gsl/gsl_linalg__svd.c000066400000000000000000000420261261542461700206250ustar00rootroot00000000000000/* linalg/svd.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_math.h" #include "gsl_vector.h" #include "gsl_matrix.h" #include "gsl_blas.h" #include "gsl_linalg.h" #include "gsl_linalg__givens.c" #include "gsl_linalg__svdstep.c" /* Factorise a general M x N matrix A into, * * A = U D V^T * * where U is a column-orthogonal M x N matrix (U^T U = I), * D is a diagonal N x N matrix, * and V is an N x N orthogonal matrix (V^T V = V V^T = I) * * U is stored in the original matrix A, which has the same size * * V is stored as a separate matrix (not V^T). You must take the * transpose to form the product above. * * The diagonal matrix D is stored in the vector S, D_ii = S_i */ int gsl_linalg_SV_decomp (gsl_matrix * A, gsl_matrix * V, gsl_vector * S, gsl_vector * work) { size_t a, b, i, j, iter; const size_t M = A->size1; const size_t N = A->size2; const size_t K = GSL_MIN (M, N); if (M < N) { GSL_ERROR ("svd of MxN matrix, Msize1 != N) { GSL_ERROR ("square matrix V must match second dimension of matrix A", GSL_EBADLEN); } else if (V->size1 != V->size2) { GSL_ERROR ("matrix V must be square", GSL_ENOTSQR); } else if (S->size != N) { GSL_ERROR ("length of vector S must match second dimension of matrix A", GSL_EBADLEN); } else if (work->size != N) { GSL_ERROR ("length of workspace must match second dimension of matrix A", GSL_EBADLEN); } /* Handle the case of N = 1 (SVD of a column vector) */ if (N == 1) { gsl_vector_view column = gsl_matrix_column (A, 0); double norm = gsl_blas_dnrm2 (&column.vector); gsl_vector_set (S, 0, norm); gsl_matrix_set (V, 0, 0, 1.0); if (norm != 0.0) { gsl_blas_dscal (1.0/norm, &column.vector); } return GSL_SUCCESS; } { gsl_vector_view f = gsl_vector_subvector (work, 0, K - 1); /* bidiagonalize matrix A, unpack A into U S V */ gsl_linalg_bidiag_decomp (A, S, &f.vector); gsl_linalg_bidiag_unpack2 (A, S, &f.vector, V); /* apply reduction steps to B=(S,Sd) */ chop_small_elements (S, &f.vector); /* Progressively reduce the matrix until it is diagonal */ b = N - 1; iter = 0; while (b > 0) { double fbm1 = gsl_vector_get (&f.vector, b - 1); if (fbm1 == 0.0 || gsl_isnan (fbm1)) { b--; continue; } /* Find the largest unreduced block (a,b) starting from b and working backwards */ a = b - 1; while (a > 0) { double fam1 = gsl_vector_get (&f.vector, a - 1); if (fam1 == 0.0 || gsl_isnan (fam1)) { break; } a--; } iter++; if (iter > 100 * N) { GSL_ERROR("SVD decomposition failed to converge", GSL_EMAXITER); } { const size_t n_block = b - a + 1; gsl_vector_view S_block = gsl_vector_subvector (S, a, n_block); gsl_vector_view f_block = gsl_vector_subvector (&f.vector, a, n_block - 1); gsl_matrix_view U_block = gsl_matrix_submatrix (A, 0, a, A->size1, n_block); gsl_matrix_view V_block = gsl_matrix_submatrix (V, 0, a, V->size1, n_block); qrstep (&S_block.vector, &f_block.vector, &U_block.matrix, &V_block.matrix); /* remove any small off-diagonal elements */ chop_small_elements (&S_block.vector, &f_block.vector); } } } /* Make singular values positive by reflections if necessary */ for (j = 0; j < K; j++) { double Sj = gsl_vector_get (S, j); if (Sj < 0.0) { for (i = 0; i < N; i++) { double Vij = gsl_matrix_get (V, i, j); gsl_matrix_set (V, i, j, -Vij); } gsl_vector_set (S, j, -Sj); } } /* Sort singular values into decreasing order */ for (i = 0; i < K; i++) { double S_max = gsl_vector_get (S, i); size_t i_max = i; for (j = i + 1; j < K; j++) { double Sj = gsl_vector_get (S, j); if (Sj > S_max) { S_max = Sj; i_max = j; } } if (i_max != i) { /* swap eigenvalues */ gsl_vector_swap_elements (S, i, i_max); /* swap eigenvectors */ gsl_matrix_swap_columns (A, i, i_max); gsl_matrix_swap_columns (V, i, i_max); } } return GSL_SUCCESS; } /* Modified algorithm which is better for M>>N */ int gsl_linalg_SV_decomp_mod (gsl_matrix * A, gsl_matrix * X, gsl_matrix * V, gsl_vector * S, gsl_vector * work) { size_t i, j; const size_t M = A->size1; const size_t N = A->size2; if (M < N) { GSL_ERROR ("svd of MxN matrix, Msize1 != N) { GSL_ERROR ("square matrix V must match second dimension of matrix A", GSL_EBADLEN); } else if (V->size1 != V->size2) { GSL_ERROR ("matrix V must be square", GSL_ENOTSQR); } else if (X->size1 != N) { GSL_ERROR ("square matrix X must match second dimension of matrix A", GSL_EBADLEN); } else if (X->size1 != X->size2) { GSL_ERROR ("matrix X must be square", GSL_ENOTSQR); } else if (S->size != N) { GSL_ERROR ("length of vector S must match second dimension of matrix A", GSL_EBADLEN); } else if (work->size != N) { GSL_ERROR ("length of workspace must match second dimension of matrix A", GSL_EBADLEN); } if (N == 1) { gsl_vector_view column = gsl_matrix_column (A, 0); double norm = gsl_blas_dnrm2 (&column.vector); gsl_vector_set (S, 0, norm); gsl_matrix_set (V, 0, 0, 1.0); if (norm != 0.0) { gsl_blas_dscal (1.0/norm, &column.vector); } return GSL_SUCCESS; } /* Convert A into an upper triangular matrix R */ for (i = 0; i < N; i++) { gsl_vector_view c = gsl_matrix_column (A, i); gsl_vector_view v = gsl_vector_subvector (&c.vector, i, M - i); double tau_i = gsl_linalg_householder_transform (&v.vector); /* Apply the transformation to the remaining columns */ if (i + 1 < N) { gsl_matrix_view m = gsl_matrix_submatrix (A, i, i + 1, M - i, N - (i + 1)); gsl_linalg_householder_hm (tau_i, &v.vector, &m.matrix); } gsl_vector_set (S, i, tau_i); } /* Copy the upper triangular part of A into X */ for (i = 0; i < N; i++) { for (j = 0; j < i; j++) { gsl_matrix_set (X, i, j, 0.0); } { double Aii = gsl_matrix_get (A, i, i); gsl_matrix_set (X, i, i, Aii); } for (j = i + 1; j < N; j++) { double Aij = gsl_matrix_get (A, i, j); gsl_matrix_set (X, i, j, Aij); } } /* Convert A into an orthogonal matrix L */ for (j = N; j > 0 && j--;) { /* Householder column transformation to accumulate L */ double tj = gsl_vector_get (S, j); gsl_matrix_view m = gsl_matrix_submatrix (A, j, j, M - j, N - j); gsl_linalg_householder_hm1 (tj, &m.matrix); } /* unpack R into X V S */ gsl_linalg_SV_decomp (X, V, S, work); /* Multiply L by X, to obtain U = L X, stored in U */ { gsl_vector_view sum = gsl_vector_subvector (work, 0, N); for (i = 0; i < M; i++) { gsl_vector_view L_i = gsl_matrix_row (A, i); gsl_vector_set_zero (&sum.vector); for (j = 0; j < N; j++) { double Lij = gsl_vector_get (&L_i.vector, j); gsl_vector_view X_j = gsl_matrix_row (X, j); gsl_blas_daxpy (Lij, &X_j.vector, &sum.vector); } gsl_vector_memcpy (&L_i.vector, &sum.vector); } } return GSL_SUCCESS; } /* Solves the system A x = b using the SVD factorization * * A = U S V^T * * to obtain x. For M x N systems it finds the solution in the least * squares sense. */ int gsl_linalg_SV_solve (const gsl_matrix * U, const gsl_matrix * V, const gsl_vector * S, const gsl_vector * b, gsl_vector * x) { if (U->size1 != b->size) { GSL_ERROR ("first dimension of matrix U must size of vector b", GSL_EBADLEN); } else if (U->size2 != S->size) { GSL_ERROR ("length of vector S must match second dimension of matrix U", GSL_EBADLEN); } else if (V->size1 != V->size2) { GSL_ERROR ("matrix V must be square", GSL_ENOTSQR); } else if (S->size != V->size1) { GSL_ERROR ("length of vector S must match size of matrix V", GSL_EBADLEN); } else if (V->size2 != x->size) { GSL_ERROR ("size of matrix V must match size of vector x", GSL_EBADLEN); } else { const size_t N = U->size2; size_t i; gsl_vector *w = gsl_vector_calloc (N); gsl_blas_dgemv (CblasTrans, 1.0, U, b, 0.0, w); for (i = 0; i < N; i++) { double wi = gsl_vector_get (w, i); double alpha = gsl_vector_get (S, i); if (alpha != 0) alpha = 1.0 / alpha; gsl_vector_set (w, i, alpha * wi); } gsl_blas_dgemv (CblasNoTrans, 1.0, V, w, 0.0, x); gsl_vector_free (w); return GSL_SUCCESS; } } /* This is a the jacobi version */ /* Author: G. Jungman */ /* * Algorithm due to J.C. Nash, Compact Numerical Methods for * Computers (New York: Wiley and Sons, 1979), chapter 3. * See also Algorithm 4.1 in * James Demmel, Kresimir Veselic, "Jacobi's Method is more * accurate than QR", Lapack Working Note 15 (LAWN15), October 1989. * Available from netlib. * * Based on code by Arthur Kosowsky, Rutgers University * kosowsky@physics.rutgers.edu * * Another relevant paper is, P.P.M. De Rijk, "A One-Sided Jacobi * Algorithm for computing the singular value decomposition on a * vector computer", SIAM Journal of Scientific and Statistical * Computing, Vol 10, No 2, pp 359-371, March 1989. * */ int gsl_linalg_SV_decomp_jacobi (gsl_matrix * A, gsl_matrix * Q, gsl_vector * S) { if (A->size1 < A->size2) { /* FIXME: only implemented M>=N case so far */ GSL_ERROR ("svd of MxN matrix, Msize1 != A->size2) { GSL_ERROR ("square matrix Q must match second dimension of matrix A", GSL_EBADLEN); } else if (Q->size1 != Q->size2) { GSL_ERROR ("matrix Q must be square", GSL_ENOTSQR); } else if (S->size != A->size2) { GSL_ERROR ("length of vector S must match second dimension of matrix A", GSL_EBADLEN); } else { const size_t M = A->size1; const size_t N = A->size2; size_t i, j, k; /* Initialize the rotation counter and the sweep counter. */ int count = 1; int sweep = 0; int sweepmax = 5*N; double tolerance = 10 * M * GSL_DBL_EPSILON; /* Always do at least 12 sweeps. */ sweepmax = GSL_MAX (sweepmax, 12); /* Set Q to the identity matrix. */ gsl_matrix_set_identity (Q); /* Store the column error estimates in S, for use during the orthogonalization */ for (j = 0; j < N; j++) { gsl_vector_view cj = gsl_matrix_column (A, j); double sj = gsl_blas_dnrm2 (&cj.vector); gsl_vector_set(S, j, GSL_DBL_EPSILON * sj); } /* Orthogonalize A by plane rotations. */ while (count > 0 && sweep <= sweepmax) { /* Initialize rotation counter. */ count = N * (N - 1) / 2; for (j = 0; j < N - 1; j++) { for (k = j + 1; k < N; k++) { double a = 0.0; double b = 0.0; double p = 0.0; double q = 0.0; double cosine, sine; double v; double abserr_a, abserr_b; int sorted, orthog, noisya, noisyb; gsl_vector_view cj = gsl_matrix_column (A, j); gsl_vector_view ck = gsl_matrix_column (A, k); gsl_blas_ddot (&cj.vector, &ck.vector, &p); p *= 2.0 ; /* equation 9a: p = 2 x.y */ a = gsl_blas_dnrm2 (&cj.vector); b = gsl_blas_dnrm2 (&ck.vector); q = a * a - b * b; v = hypot(p, q); /* test for columns j,k orthogonal, or dominant errors */ abserr_a = gsl_vector_get(S,j); abserr_b = gsl_vector_get(S,k); sorted = (gsl_coerce_double(a) >= gsl_coerce_double(b)); orthog = (fabs (p) <= tolerance * gsl_coerce_double(a * b)); noisya = (a < abserr_a); noisyb = (b < abserr_b); if (sorted && (orthog || noisya || noisyb)) { count--; continue; } /* calculate rotation angles */ if (v == 0 || !sorted) { cosine = 0.0; sine = 1.0; } else { cosine = sqrt((v + q) / (2.0 * v)); sine = p / (2.0 * v * cosine); } /* apply rotation to A */ for (i = 0; i < M; i++) { const double Aik = gsl_matrix_get (A, i, k); const double Aij = gsl_matrix_get (A, i, j); gsl_matrix_set (A, i, j, Aij * cosine + Aik * sine); gsl_matrix_set (A, i, k, -Aij * sine + Aik * cosine); } gsl_vector_set(S, j, fabs(cosine) * abserr_a + fabs(sine) * abserr_b); gsl_vector_set(S, k, fabs(sine) * abserr_a + fabs(cosine) * abserr_b); /* apply rotation to Q */ for (i = 0; i < N; i++) { const double Qij = gsl_matrix_get (Q, i, j); const double Qik = gsl_matrix_get (Q, i, k); gsl_matrix_set (Q, i, j, Qij * cosine + Qik * sine); gsl_matrix_set (Q, i, k, -Qij * sine + Qik * cosine); } } } /* Sweep completed. */ sweep++; } /* * Orthogonalization complete. Compute singular values. */ { double prev_norm = -1.0; for (j = 0; j < N; j++) { gsl_vector_view column = gsl_matrix_column (A, j); double norm = gsl_blas_dnrm2 (&column.vector); /* Determine if singular value is zero, according to the criteria used in the main loop above (i.e. comparison with norm of previous column). */ if (norm == 0.0 || prev_norm == 0.0 || (j > 0 && norm <= tolerance * prev_norm)) { gsl_vector_set (S, j, 0.0); /* singular */ gsl_vector_set_zero (&column.vector); /* annihilate column */ prev_norm = 0.0; } else { gsl_vector_set (S, j, norm); /* non-singular */ gsl_vector_scale (&column.vector, 1.0 / norm); /* normalize column */ prev_norm = norm; } } } if (count > 0) { /* reached sweep limit */ GSL_ERROR ("Jacobi iterations did not reach desired tolerance", GSL_ETOL); } return GSL_SUCCESS; } } praat-6.0.04/external/gsl/gsl_linalg__svdstep.c000066400000000000000000000300661261542461700215220ustar00rootroot00000000000000/* linalg/svdstep.c * * Copyright (C) 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static void chop_small_elements (gsl_vector * d, gsl_vector * f) { const size_t N = d->size; double d_i = gsl_vector_get (d, 0); size_t i; for (i = 0; i < N - 1; i++) { double f_i = gsl_vector_get (f, i); double d_ip1 = gsl_vector_get (d, i + 1); if (fabs (f_i) < GSL_DBL_EPSILON * (fabs (d_i) + fabs (d_ip1))) { gsl_vector_set (f, i, 0.0); } d_i = d_ip1; } } static double trailing_eigenvalue (const gsl_vector * d, const gsl_vector * f) { const size_t n = d->size; double da = gsl_vector_get (d, n - 2); double db = gsl_vector_get (d, n - 1); double fa = (n > 2) ? gsl_vector_get (f, n - 3) : 0.0; double fb = gsl_vector_get (f, n - 2); double ta = da * da + fa * fa; double tb = db * db + fb * fb; double tab = da * fb; double dt = (ta - tb) / 2.0; double mu; if (dt >= 0) { mu = tb - (tab * tab) / (dt + hypot (dt, tab)); } else { mu = tb + (tab * tab) / ((-dt) + hypot (dt, tab)); } return mu; } static void create_schur (double d0, double f0, double d1, double * c, double * s) { double apq = 2.0 * d0 * f0; if (d0 == 0 || f0 == 0) { *c = 1.0; *s = 0.0; return; } /* Check if we need to rescale to avoid underflow/overflow */ if (fabs(d0) < GSL_SQRT_DBL_MIN || fabs(d0) > GSL_SQRT_DBL_MAX || fabs(f0) < GSL_SQRT_DBL_MIN || fabs(f0) > GSL_SQRT_DBL_MAX || fabs(d1) < GSL_SQRT_DBL_MIN || fabs(d1) > GSL_SQRT_DBL_MAX) { double scale; int d0_exp, f0_exp; frexp(d0, &d0_exp); frexp(f0, &f0_exp); /* Bring |d0*f0| into the range GSL_DBL_MIN to GSL_DBL_MAX */ scale = ldexp(1.0, -(d0_exp + f0_exp)/4); d0 *= scale; f0 *= scale; d1 *= scale; apq = 2.0 * d0 * f0; } if (apq != 0.0) { double t; double tau = (f0*f0 + (d1 + d0)*(d1 - d0)) / apq; if (tau >= 0.0) { t = 1.0/(tau + hypot(1.0, tau)); } else { t = -1.0/(-tau + hypot(1.0, tau)); } *c = 1.0 / hypot(1.0, t); *s = t * (*c); } else { *c = 1.0; *s = 0.0; } } static void svd2 (gsl_vector * d, gsl_vector * f, gsl_matrix * U, gsl_matrix * V) { size_t i; double c, s, a11, a12, a21, a22; const size_t M = U->size1; const size_t N = V->size1; double d0 = gsl_vector_get (d, 0); double f0 = gsl_vector_get (f, 0); double d1 = gsl_vector_get (d, 1); if (d0 == 0.0) { /* Eliminate off-diagonal element in [0,f0;0,d1] to make [d,0;0,0] */ create_givens (f0, d1, &c, &s); /* compute B <= G^T B X, where X = [0,1;1,0] */ gsl_vector_set (d, 0, c * f0 - s * d1); gsl_vector_set (f, 0, s * f0 + c * d1); gsl_vector_set (d, 1, 0.0); /* Compute U <= U G */ for (i = 0; i < M; i++) { double Uip = gsl_matrix_get (U, i, 0); double Uiq = gsl_matrix_get (U, i, 1); gsl_matrix_set (U, i, 0, c * Uip - s * Uiq); gsl_matrix_set (U, i, 1, s * Uip + c * Uiq); } /* Compute V <= V X */ gsl_matrix_swap_columns (V, 0, 1); return; } else if (d1 == 0.0) { /* Eliminate off-diagonal element in [d0,f0;0,0] */ create_givens (d0, f0, &c, &s); /* compute B <= B G */ gsl_vector_set (d, 0, d0 * c - f0 * s); gsl_vector_set (f, 0, 0.0); /* Compute V <= V G */ for (i = 0; i < N; i++) { double Vip = gsl_matrix_get (V, i, 0); double Viq = gsl_matrix_get (V, i, 1); gsl_matrix_set (V, i, 0, c * Vip - s * Viq); gsl_matrix_set (V, i, 1, s * Vip + c * Viq); } return; } else { /* Make columns orthogonal, A = [d0, f0; 0, d1] * G */ create_schur (d0, f0, d1, &c, &s); /* compute B <= B G */ a11 = c * d0 - s * f0; a21 = - s * d1; a12 = s * d0 + c * f0; a22 = c * d1; /* Compute V <= V G */ for (i = 0; i < N; i++) { double Vip = gsl_matrix_get (V, i, 0); double Viq = gsl_matrix_get (V, i, 1); gsl_matrix_set (V, i, 0, c * Vip - s * Viq); gsl_matrix_set (V, i, 1, s * Vip + c * Viq); } /* Eliminate off-diagonal elements, bring column with largest norm to first column */ if (hypot(a11, a21) < hypot(a12,a22)) { double t1, t2; /* B <= B X */ t1 = a11; a11 = a12; a12 = t1; t2 = a21; a21 = a22; a22 = t2; /* V <= V X */ gsl_matrix_swap_columns(V, 0, 1); } create_givens (a11, a21, &c, &s); /* compute B <= G^T B */ gsl_vector_set (d, 0, c * a11 - s * a21); gsl_vector_set (f, 0, c * a12 - s * a22); gsl_vector_set (d, 1, s * a12 + c * a22); /* Compute U <= U G */ for (i = 0; i < M; i++) { double Uip = gsl_matrix_get (U, i, 0); double Uiq = gsl_matrix_get (U, i, 1); gsl_matrix_set (U, i, 0, c * Uip - s * Uiq); gsl_matrix_set (U, i, 1, s * Uip + c * Uiq); } return; } } static void chase_out_intermediate_zero (gsl_vector * d, gsl_vector * f, gsl_matrix * U, size_t k0) { #if !USE_BLAS const size_t M = U->size1; #endif const size_t n = d->size; double c, s; double x, y; size_t k; x = gsl_vector_get (f, k0); y = gsl_vector_get (d, k0+1); for (k = k0; k < n - 1; k++) { create_givens (y, -x, &c, &s); /* Compute U <= U G */ #ifdef USE_BLAS { gsl_vector_view Uk0 = gsl_matrix_column(U,k0); gsl_vector_view Ukp1 = gsl_matrix_column(U,k+1); gsl_blas_drot(&Uk0.vector, &Ukp1.vector, c, -s); } #else { size_t i; for (i = 0; i < M; i++) { double Uip = gsl_matrix_get (U, i, k0); double Uiq = gsl_matrix_get (U, i, k + 1); gsl_matrix_set (U, i, k0, c * Uip - s * Uiq); gsl_matrix_set (U, i, k + 1, s * Uip + c * Uiq); } } #endif /* compute B <= G^T B */ gsl_vector_set (d, k + 1, s * x + c * y); if (k == k0) gsl_vector_set (f, k, c * x - s * y ); if (k < n - 2) { double z = gsl_vector_get (f, k + 1); gsl_vector_set (f, k + 1, c * z); x = -s * z ; y = gsl_vector_get (d, k + 2); } } } static void chase_out_trailing_zero (gsl_vector * d, gsl_vector * f, gsl_matrix * V) { #if !USE_BLAS const size_t N = V->size1; #endif const size_t n = d->size; double c, s; double x, y; size_t k; x = gsl_vector_get (d, n - 2); y = gsl_vector_get (f, n - 2); for (k = n - 1; k > 0 && k--;) { create_givens (x, y, &c, &s); /* Compute V <= V G where G = [c, s ; -s, c] */ #ifdef USE_BLAS { gsl_vector_view Vp = gsl_matrix_column(V,k); gsl_vector_view Vq = gsl_matrix_column(V,n-1); gsl_blas_drot(&Vp.vector, &Vq.vector, c, -s); } #else { size_t i; for (i = 0; i < N; i++) { double Vip = gsl_matrix_get (V, i, k); double Viq = gsl_matrix_get (V, i, n - 1); gsl_matrix_set (V, i, k, c * Vip - s * Viq); gsl_matrix_set (V, i, n - 1, s * Vip + c * Viq); } } #endif /* compute B <= B G */ gsl_vector_set (d, k, c * x - s * y); if (k == n - 2) gsl_vector_set (f, k, s * x + c * y ); if (k > 0) { double z = gsl_vector_get (f, k - 1); gsl_vector_set (f, k - 1, c * z); x = gsl_vector_get (d, k - 1); y = s * z ; } } } static void qrstep (gsl_vector * d, gsl_vector * f, gsl_matrix * U, gsl_matrix * V) { #if !USE_BLAS const size_t M = U->size1; const size_t N = V->size1; #endif const size_t n = d->size; double y, z; double ak, bk, zk, ap, bp, aq, bq; size_t i, k; if (n == 1) return; /* shouldn't happen */ /* Compute 2x2 svd directly */ if (n == 2) { svd2 (d, f, U, V); return; } /* Chase out any zeroes on the diagonal */ for (i = 0; i < n - 1; i++) { double d_i = gsl_vector_get (d, i); if (d_i == 0.0) { chase_out_intermediate_zero (d, f, U, i); return; } } /* Chase out any zero at the end of the diagonal */ { double d_nm1 = gsl_vector_get (d, n - 1); if (d_nm1 == 0.0) { chase_out_trailing_zero (d, f, V); return; } } /* Apply QR reduction steps to the diagonal and offdiagonal */ { double d0 = gsl_vector_get (d, 0); double f0 = gsl_vector_get (f, 0); double d1 = gsl_vector_get (d, 1); double f1 = gsl_vector_get (f, 1); { double mu = trailing_eigenvalue (d, f); y = d0 * d0 - mu; z = d0 * f0; } /* Set up the recurrence for Givens rotations on a bidiagonal matrix */ ak = 0; bk = 0; ap = d0; bp = f0; aq = d1; bq = f1; } for (k = 0; k < n - 1; k++) { double c, s; create_givens (y, z, &c, &s); /* Compute V <= V G */ #ifdef USE_BLAS { gsl_vector_view Vk = gsl_matrix_column(V,k); gsl_vector_view Vkp1 = gsl_matrix_column(V,k+1); gsl_blas_drot(&Vk.vector, &Vkp1.vector, c, -s); } #else for (i = 0; i < N; i++) { double Vip = gsl_matrix_get (V, i, k); double Viq = gsl_matrix_get (V, i, k + 1); gsl_matrix_set (V, i, k, c * Vip - s * Viq); gsl_matrix_set (V, i, k + 1, s * Vip + c * Viq); } #endif /* compute B <= B G */ { double bk1 = c * bk - s * z; double ap1 = c * ap - s * bp; double bp1 = s * ap + c * bp; double zp1 = -s * aq; double aq1 = c * aq; if (k > 0) { gsl_vector_set (f, k - 1, bk1); } ak = ap1; bk = bp1; zk = zp1; ap = aq1; if (k < n - 2) { bp = gsl_vector_get (f, k + 1); } else { bp = 0.0; } y = ak; z = zk; } create_givens (y, z, &c, &s); /* Compute U <= U G */ #ifdef USE_BLAS { gsl_vector_view Uk = gsl_matrix_column(U,k); gsl_vector_view Ukp1 = gsl_matrix_column(U,k+1); gsl_blas_drot(&Uk.vector, &Ukp1.vector, c, -s); } #else for (i = 0; i < M; i++) { double Uip = gsl_matrix_get (U, i, k); double Uiq = gsl_matrix_get (U, i, k + 1); gsl_matrix_set (U, i, k, c * Uip - s * Uiq); gsl_matrix_set (U, i, k + 1, s * Uip + c * Uiq); } #endif /* compute B <= G^T B */ { double ak1 = c * ak - s * zk; double bk1 = c * bk - s * ap; double zk1 = -s * bp; double ap1 = s * bk + c * ap; double bp1 = c * bp; gsl_vector_set (d, k, ak1); ak = ak1; bk = bk1; zk = zk1; ap = ap1; bp = bp1; if (k < n - 2) { aq = gsl_vector_get (d, k + 2); } else { aq = 0.0; } y = bk; z = zk; } } gsl_vector_set (f, n - 2, bk); gsl_vector_set (d, n - 1, ap); } praat-6.0.04/external/gsl/gsl_linalg__symmtd.c000066400000000000000000000150151261542461700213440ustar00rootroot00000000000000/* linalg/sytd.c * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Factorise a symmetric matrix A into * * A = Q T Q' * * where Q is orthogonal and T is symmetric tridiagonal. Only the * diagonal and lower triangular part of A is referenced and modified. * * On exit, T is stored in the diagonal and first subdiagonal of * A. Since T is symmetric the upper diagonal is not stored. * * Q is stored as a packed set of Householder transformations in the * lower triangular part of the input matrix below the first subdiagonal. * * The full matrix for Q can be obtained as the product * * Q = Q_1 Q_2 ... Q_(N-2) * * where * * Q_i = (I - tau_i * v_i * v_i') * * and where v_i is a Householder vector * * v_i = [0, ... , 0, 1, A(i+1,i), A(i+2,i), ... , A(N,i)] * * This storage scheme is the same as in LAPACK. See LAPACK's * ssytd2.f for details. * * See Golub & Van Loan, "Matrix Computations" (3rd ed), Section 8.3 * * Note: this description uses 1-based indices. The code below uses * 0-based indices */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_vector.h" #include "gsl_matrix.h" #include "gsl_blas.h" #include "gsl_linalg.h" int gsl_linalg_symmtd_decomp (gsl_matrix * A, gsl_vector * tau) { if (A->size1 != A->size2) { GSL_ERROR ("symmetric tridiagonal decomposition requires square matrix", GSL_ENOTSQR); } else if (tau->size + 1 != A->size1) { GSL_ERROR ("size of tau must be (matrix size - 1)", GSL_EBADLEN); } else { const size_t N = A->size1; size_t i; for (i = 0 ; i < N - 2; i++) { gsl_vector_view c = gsl_matrix_column (A, i); gsl_vector_view v = gsl_vector_subvector (&c.vector, i + 1, N - (i + 1)); double tau_i = gsl_linalg_householder_transform (&v.vector); /* Apply the transformation H^T A H to the remaining columns */ if (tau_i != 0.0) { gsl_matrix_view m = gsl_matrix_submatrix (A, i + 1, i + 1, N - (i+1), N - (i+1)); double ei = gsl_vector_get(&v.vector, 0); gsl_vector_view x = gsl_vector_subvector (tau, i, N-(i+1)); gsl_vector_set (&v.vector, 0, 1.0); /* x = tau * A * v */ gsl_blas_dsymv (CblasLower, tau_i, &m.matrix, &v.vector, 0.0, &x.vector); /* w = x - (1/2) tau * (x' * v) * v */ { double xv, alpha; gsl_blas_ddot(&x.vector, &v.vector, &xv); alpha = - (tau_i / 2.0) * xv; gsl_blas_daxpy(alpha, &v.vector, &x.vector); } /* apply the transformation A = A - v w' - w v' */ gsl_blas_dsyr2(CblasLower, -1.0, &v.vector, &x.vector, &m.matrix); gsl_vector_set (&v.vector, 0, ei); } gsl_vector_set (tau, i, tau_i); } return GSL_SUCCESS; } } /* Form the orthogonal matrix Q from the packed QR matrix */ int gsl_linalg_symmtd_unpack (const gsl_matrix * A, const gsl_vector * tau, gsl_matrix * Q, gsl_vector * diag, gsl_vector * sdiag) { if (A->size1 != A->size2) { GSL_ERROR ("matrix A must be square", GSL_ENOTSQR); } else if (tau->size + 1 != A->size1) { GSL_ERROR ("size of tau must be (matrix size - 1)", GSL_EBADLEN); } else if (Q->size1 != A->size1 || Q->size2 != A->size1) { GSL_ERROR ("size of Q must match size of A", GSL_EBADLEN); } else if (diag->size != A->size1) { GSL_ERROR ("size of diagonal must match size of A", GSL_EBADLEN); } else if (sdiag->size + 1 != A->size1) { GSL_ERROR ("size of subdiagonal must be (matrix size - 1)", GSL_EBADLEN); } else { const size_t N = A->size1; size_t i; /* Initialize Q to the identity */ gsl_matrix_set_identity (Q); for (i = N - 2; i > 0 && i--;) { gsl_vector_const_view c = gsl_matrix_const_column (A, i); gsl_vector_const_view h = gsl_vector_const_subvector (&c.vector, i + 1, N - (i+1)); double ti = gsl_vector_get (tau, i); gsl_matrix_view m = gsl_matrix_submatrix (Q, i + 1, i + 1, N-(i+1), N-(i+1)); gsl_linalg_householder_hm (ti, &h.vector, &m.matrix); } /* Copy diagonal into diag */ for (i = 0; i < N; i++) { double Aii = gsl_matrix_get (A, i, i); gsl_vector_set (diag, i, Aii); } /* Copy subdiagonal into sd */ for (i = 0; i < N - 1; i++) { double Aji = gsl_matrix_get (A, i+1, i); gsl_vector_set (sdiag, i, Aji); } return GSL_SUCCESS; } } int gsl_linalg_symmtd_unpack_T (const gsl_matrix * A, gsl_vector * diag, gsl_vector * sdiag) { if (A->size1 != A->size2) { GSL_ERROR ("matrix A must be square", GSL_ENOTSQR); } else if (diag->size != A->size1) { GSL_ERROR ("size of diagonal must match size of A", GSL_EBADLEN); } else if (sdiag->size + 1 != A->size1) { GSL_ERROR ("size of subdiagonal must be (matrix size - 1)", GSL_EBADLEN); } else { const size_t N = A->size1; size_t i; /* Copy diagonal into diag */ for (i = 0; i < N; i++) { double Aii = gsl_matrix_get (A, i, i); gsl_vector_set (diag, i, Aii); } /* Copy subdiagonal into sdiag */ for (i = 0; i < N - 1; i++) { double Aij = gsl_matrix_get (A, i+1, i); gsl_vector_set (sdiag, i, Aij); } return GSL_SUCCESS; } } praat-6.0.04/external/gsl/gsl_linalg__tridiag.c000066400000000000000000000367071261542461700214650ustar00rootroot00000000000000/* linalg/tridiag.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2004, 2007 Gerard Jungman, Brian Gough, David Necas * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include #include #include "gsl_errno.h" #include "gsl_linalg__tridiag.h" #include "gsl_linalg.h" /* for description of method see [Engeln-Mullges + Uhlig, p. 92] * * diag[0] offdiag[0] 0 ..... * offdiag[0] diag[1] offdiag[1] ..... * 0 offdiag[1] diag[2] * 0 0 offdiag[2] ..... */ static int solve_tridiag( const double diag[], size_t d_stride, const double offdiag[], size_t o_stride, const double b[], size_t b_stride, double x[], size_t x_stride, size_t N) { int status = GSL_SUCCESS; double *gamma = (double *) malloc (N * sizeof (double)); double *alpha = (double *) malloc (N * sizeof (double)); double *c = (double *) malloc (N * sizeof (double)); double *z = (double *) malloc (N * sizeof (double)); if (gamma == 0 || alpha == 0 || c == 0 || z == 0) { GSL_ERROR("failed to allocate working space", GSL_ENOMEM); } else { size_t i, j; /* Cholesky decomposition A = L.D.L^t lower_diag(L) = gamma diag(D) = alpha */ alpha[0] = diag[0]; gamma[0] = offdiag[0] / alpha[0]; if (alpha[0] == 0) { status = GSL_EZERODIV; } for (i = 1; i < N - 1; i++) { alpha[i] = diag[d_stride * i] - offdiag[o_stride*(i - 1)] * gamma[i - 1]; gamma[i] = offdiag[o_stride * i] / alpha[i]; if (alpha[i] == 0) { status = GSL_EZERODIV; } } if (N > 1) { alpha[N - 1] = diag[d_stride * (N - 1)] - offdiag[o_stride*(N - 2)] * gamma[N - 2]; } /* update RHS */ z[0] = b[0]; for (i = 1; i < N; i++) { z[i] = b[b_stride * i] - gamma[i - 1] * z[i - 1]; } for (i = 0; i < N; i++) { c[i] = z[i] / alpha[i]; } /* backsubstitution */ x[x_stride * (N - 1)] = c[N - 1]; if (N >= 2) { for (i = N - 2, j = 0; j <= N - 2; j++, i--) { x[x_stride * i] = c[i] - gamma[i] * x[x_stride * (i + 1)]; } } } if (z != 0) free (z); if (c != 0) free (c); if (alpha != 0) free (alpha); if (gamma != 0) free (gamma); if (status == GSL_EZERODIV) { GSL_ERROR ("matrix must be positive definite", status); } return status; } /* plain gauss elimination, only not bothering with the zeroes * * diag[0] abovediag[0] 0 ..... * belowdiag[0] diag[1] abovediag[1] ..... * 0 belowdiag[1] diag[2] * 0 0 belowdiag[2] ..... */ static int solve_tridiag_nonsym( const double diag[], size_t d_stride, const double abovediag[], size_t a_stride, const double belowdiag[], size_t b_stride, const double rhs[], size_t r_stride, double x[], size_t x_stride, size_t N) { int status = GSL_SUCCESS; double *alpha = (double *) malloc (N * sizeof (double)); double *z = (double *) malloc (N * sizeof (double)); if (alpha == 0 || z == 0) { GSL_ERROR("failed to allocate working space", GSL_ENOMEM); } else { size_t i, j; /* Bidiagonalization (eliminating belowdiag) & rhs update diag' = alpha rhs' = z */ alpha[0] = diag[0]; z[0] = rhs[0]; if (alpha[0] == 0) { status = GSL_EZERODIV; } for (i = 1; i < N; i++) { const double t = belowdiag[b_stride*(i - 1)]/alpha[i-1]; alpha[i] = diag[d_stride*i] - t*abovediag[a_stride*(i - 1)]; z[i] = rhs[r_stride*i] - t*z[i-1]; if (alpha[i] == 0) { status = GSL_EZERODIV; } } /* backsubstitution */ x[x_stride * (N - 1)] = z[N - 1]/alpha[N - 1]; if (N >= 2) { for (i = N - 2, j = 0; j <= N - 2; j++, i--) { x[x_stride * i] = (z[i] - abovediag[a_stride*i] * x[x_stride * (i + 1)])/alpha[i]; } } } if (z != 0) free (z); if (alpha != 0) free (alpha); if (status == GSL_EZERODIV) { GSL_ERROR ("matrix must be positive definite", status); } return status; } /* for description of method see [Engeln-Mullges + Uhlig, p. 96] * * diag[0] offdiag[0] 0 ..... offdiag[N-1] * offdiag[0] diag[1] offdiag[1] ..... * 0 offdiag[1] diag[2] * 0 0 offdiag[2] ..... * ... ... * offdiag[N-1] ... * */ static int solve_cyc_tridiag( const double diag[], size_t d_stride, const double offdiag[], size_t o_stride, const double b[], size_t b_stride, double x[], size_t x_stride, size_t N) { int status = GSL_SUCCESS; double * delta = (double *) malloc (N * sizeof (double)); double * gamma = (double *) malloc (N * sizeof (double)); double * alpha = (double *) malloc (N * sizeof (double)); double * c = (double *) malloc (N * sizeof (double)); double * z = (double *) malloc (N * sizeof (double)); if (delta == 0 || gamma == 0 || alpha == 0 || c == 0 || z == 0) { GSL_ERROR("failed to allocate working space", GSL_ENOMEM); } else { size_t i, j; double sum = 0.0; /* factor */ if (N == 1) { x[0] = b[0] / diag[0]; return GSL_SUCCESS; } alpha[0] = diag[0]; gamma[0] = offdiag[0] / alpha[0]; delta[0] = offdiag[o_stride * (N-1)] / alpha[0]; if (alpha[0] == 0) { status = GSL_EZERODIV; } for (i = 1; i < N - 2; i++) { alpha[i] = diag[d_stride * i] - offdiag[o_stride * (i-1)] * gamma[i - 1]; gamma[i] = offdiag[o_stride * i] / alpha[i]; delta[i] = -delta[i - 1] * offdiag[o_stride * (i-1)] / alpha[i]; if (alpha[i] == 0) { status = GSL_EZERODIV; } } for (i = 0; i < N - 2; i++) { sum += alpha[i] * delta[i] * delta[i]; } alpha[N - 2] = diag[d_stride * (N - 2)] - offdiag[o_stride * (N - 3)] * gamma[N - 3]; gamma[N - 2] = (offdiag[o_stride * (N - 2)] - offdiag[o_stride * (N - 3)] * delta[N - 3]) / alpha[N - 2]; alpha[N - 1] = diag[d_stride * (N - 1)] - sum - alpha[(N - 2)] * gamma[N - 2] * gamma[N - 2]; /* update */ z[0] = b[0]; for (i = 1; i < N - 1; i++) { z[i] = b[b_stride * i] - z[i - 1] * gamma[i - 1]; } sum = 0.0; for (i = 0; i < N - 2; i++) { sum += delta[i] * z[i]; } z[N - 1] = b[b_stride * (N - 1)] - sum - gamma[N - 2] * z[N - 2]; for (i = 0; i < N; i++) { c[i] = z[i] / alpha[i]; } /* backsubstitution */ x[x_stride * (N - 1)] = c[N - 1]; x[x_stride * (N - 2)] = c[N - 2] - gamma[N - 2] * x[x_stride * (N - 1)]; if (N >= 3) { for (i = N - 3, j = 0; j <= N - 3; j++, i--) { x[x_stride * i] = c[i] - gamma[i] * x[x_stride * (i + 1)] - delta[i] * x[x_stride * (N - 1)]; } } } if (z != 0) free (z); if (c != 0) free (c); if (alpha != 0) free (alpha); if (gamma != 0) free (gamma); if (delta != 0) free (delta); if (status == GSL_EZERODIV) { GSL_ERROR ("matrix must be positive definite", status); } return status; } /* solve following system w/o the corner elements and then use * Sherman-Morrison formula to compensate for them * * diag[0] abovediag[0] 0 ..... belowdiag[N-1] * belowdiag[0] diag[1] abovediag[1] ..... * 0 belowdiag[1] diag[2] * 0 0 belowdiag[2] ..... * ... ... * abovediag[N-1] ... */ static int solve_cyc_tridiag_nonsym( const double diag[], size_t d_stride, const double abovediag[], size_t a_stride, const double belowdiag[], size_t b_stride, const double rhs[], size_t r_stride, double x[], size_t x_stride, size_t N) { int status = GSL_SUCCESS; double *alpha = (double *) malloc (N * sizeof (double)); double *zb = (double *) malloc (N * sizeof (double)); double *zu = (double *) malloc (N * sizeof (double)); double *w = (double *) malloc (N * sizeof (double)); if (alpha == 0 || zb == 0 || zu == 0 || w == 0) { GSL_ERROR("failed to allocate working space", GSL_ENOMEM); } else { double beta; /* Bidiagonalization (eliminating belowdiag) & rhs update diag' = alpha rhs' = zb rhs' for Aq=u is zu */ zb[0] = rhs[0]; if (diag[0] != 0) beta = -diag[0]; else beta = 1; { const double q = 1 - abovediag[0]*belowdiag[0]/(diag[0]*diag[d_stride]); if (fabs(q/beta) > 0.5 && fabs(q/beta) < 2) { beta *= (fabs(q/beta) < 1) ? 0.5 : 2; } } zu[0] = beta; alpha[0] = diag[0] - beta; if (alpha[0] == 0) { status = GSL_EZERODIV; } { size_t i; for (i = 1; i+1 < N; i++) { const double t = belowdiag[b_stride*(i - 1)]/alpha[i-1]; alpha[i] = diag[d_stride*i] - t*abovediag[a_stride*(i - 1)]; zb[i] = rhs[r_stride*i] - t*zb[i-1]; zu[i] = -t*zu[i-1]; /* FIXME!!! */ if (alpha[i] == 0) { status = GSL_EZERODIV; } } } { const size_t i = N-1; const double t = belowdiag[b_stride*(i - 1)]/alpha[i-1]; alpha[i] = diag[d_stride*i] - abovediag[a_stride*i]*belowdiag[b_stride*i]/beta - t*abovediag[a_stride*(i - 1)]; zb[i] = rhs[r_stride*i] - t*zb[i-1]; zu[i] = abovediag[a_stride*i] - t*zu[i-1]; /* FIXME!!! */ if (alpha[i] == 0) { status = GSL_EZERODIV; } } /* backsubstitution */ { size_t i, j; w[N-1] = zu[N-1]/alpha[N-1]; x[N-1] = zb[N-1]/alpha[N-1]; for (i = N - 2, j = 0; j <= N - 2; j++, i--) { w[i] = (zu[i] - abovediag[a_stride*i] * w[i+1])/alpha[i]; x[i*x_stride] = (zb[i] - abovediag[a_stride*i] * x[x_stride*(i + 1)])/alpha[i]; } } /* Sherman-Morrison */ { const double vw = w[0] + belowdiag[b_stride*(N - 1)]/beta * w[N-1]; const double vx = x[0] + belowdiag[b_stride*(N - 1)]/beta * x[x_stride*(N - 1)]; /* FIXME!!! */ if (vw + 1 == 0) { status = GSL_EZERODIV; } { size_t i; for (i = 0; i < N; i++) x[i] -= vx/(1 + vw)*w[i]; } } } if (zb != 0) free (zb); if (zu != 0) free (zu); if (w != 0) free (w); if (alpha != 0) free (alpha); if (status == GSL_EZERODIV) { GSL_ERROR ("matrix must be positive definite", status); } return status; } int gsl_linalg_solve_symm_tridiag( const gsl_vector * diag, const gsl_vector * offdiag, const gsl_vector * rhs, gsl_vector * solution) { if(diag->size != rhs->size) { GSL_ERROR ("size of diag must match rhs", GSL_EBADLEN); } else if (offdiag->size != rhs->size-1) { GSL_ERROR ("size of offdiag must match rhs-1", GSL_EBADLEN); } else if (solution->size != rhs->size) { GSL_ERROR ("size of solution must match rhs", GSL_EBADLEN); } else { return solve_tridiag(diag->data, diag->stride, offdiag->data, offdiag->stride, rhs->data, rhs->stride, solution->data, solution->stride, diag->size); } } int gsl_linalg_solve_tridiag( const gsl_vector * diag, const gsl_vector * abovediag, const gsl_vector * belowdiag, const gsl_vector * rhs, gsl_vector * solution) { if(diag->size != rhs->size) { GSL_ERROR ("size of diag must match rhs", GSL_EBADLEN); } else if (abovediag->size != rhs->size-1) { GSL_ERROR ("size of abovediag must match rhs-1", GSL_EBADLEN); } else if (belowdiag->size != rhs->size-1) { GSL_ERROR ("size of belowdiag must match rhs-1", GSL_EBADLEN); } else if (solution->size != rhs->size) { GSL_ERROR ("size of solution must match rhs", GSL_EBADLEN); } else { return solve_tridiag_nonsym(diag->data, diag->stride, abovediag->data, abovediag->stride, belowdiag->data, belowdiag->stride, rhs->data, rhs->stride, solution->data, solution->stride, diag->size); } } int gsl_linalg_solve_symm_cyc_tridiag( const gsl_vector * diag, const gsl_vector * offdiag, const gsl_vector * rhs, gsl_vector * solution) { if(diag->size != rhs->size) { GSL_ERROR ("size of diag must match rhs", GSL_EBADLEN); } else if (offdiag->size != rhs->size) { GSL_ERROR ("size of offdiag must match rhs", GSL_EBADLEN); } else if (solution->size != rhs->size) { GSL_ERROR ("size of solution must match rhs", GSL_EBADLEN); } else if (diag->size < 3) { GSL_ERROR ("size of cyclic system must be 3 or more", GSL_EBADLEN); } else { return solve_cyc_tridiag(diag->data, diag->stride, offdiag->data, offdiag->stride, rhs->data, rhs->stride, solution->data, solution->stride, diag->size); } } int gsl_linalg_solve_cyc_tridiag( const gsl_vector * diag, const gsl_vector * abovediag, const gsl_vector * belowdiag, const gsl_vector * rhs, gsl_vector * solution) { if(diag->size != rhs->size) { GSL_ERROR ("size of diag must match rhs", GSL_EBADLEN); } else if (abovediag->size != rhs->size) { GSL_ERROR ("size of abovediag must match rhs", GSL_EBADLEN); } else if (belowdiag->size != rhs->size) { GSL_ERROR ("size of belowdiag must match rhs", GSL_EBADLEN); } else if (solution->size != rhs->size) { GSL_ERROR ("size of solution must match rhs", GSL_EBADLEN); } else if (diag->size < 3) { GSL_ERROR ("size of cyclic system must be 3 or more", GSL_EBADLEN); } else { return solve_cyc_tridiag_nonsym(diag->data, diag->stride, abovediag->data, abovediag->stride, belowdiag->data, belowdiag->stride, rhs->data, rhs->stride, solution->data, solution->stride, diag->size); } } praat-6.0.04/external/gsl/gsl_linalg__tridiag.h000066400000000000000000000036371261542461700214660ustar00rootroot00000000000000/* linalg/tridiag.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002 Gerard Jungman, * Brian Gough, David Necas * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ /* Low level tridiagonal solvers. * Used internally in other areas of GSL. */ #ifndef __GSL_TRIDIAG_H__ #define __GSL_TRIDIAG_H__ #include static int solve_tridiag_nonsym( const double diag[], size_t d_stride, const double abovediag[], size_t a_stride, const double belowdiag[], size_t b_stride, const double rhs[], size_t r_stride, double x[], size_t x_stride, size_t N ); static int solve_tridiag( const double diag[], size_t d_stride, const double offdiag[], size_t o_stride, const double b[], size_t b_stride, double x[], size_t x_stride, size_t N); static int solve_cyc_tridiag( const double diag[], size_t d_stride, const double offdiag[], size_t o_stride, const double b[], size_t b_stride, double x[], size_t x_stride, size_t N ); static int solve_cyc_tridiag_nonsym( const double diag[], size_t d_stride, const double abovediag[], size_t a_stride, const double belowdiag[], size_t b_stride, const double rhs[], size_t r_stride, double x[], size_t x_stride, size_t N); #endif /* __GSL_TRIDIAG_H__ */ praat-6.0.04/external/gsl/gsl_machine.h000066400000000000000000000073351261542461700177610ustar00rootroot00000000000000/* Author: B. Gough and G. Jungman */ #ifndef __GSL_MACHINE_H__ #define __GSL_MACHINE_H__ #include #include /* magic constants; mostly for the benefit of the implementation */ /* -*-MACHINE CONSTANTS-*- * * PLATFORM: Whiz-O-Matic 9000 * FP_PLATFORM: IEEE-Virtual * HOSTNAME: nnn.lanl.gov * DATE: Fri Nov 20 17:53:26 MST 1998 */ #define GSL_DBL_EPSILON 2.2204460492503131e-16 #define GSL_SQRT_DBL_EPSILON 1.4901161193847656e-08 #define GSL_ROOT3_DBL_EPSILON 6.0554544523933429e-06 #define GSL_ROOT4_DBL_EPSILON 1.2207031250000000e-04 #define GSL_ROOT5_DBL_EPSILON 7.4009597974140505e-04 #define GSL_ROOT6_DBL_EPSILON 2.4607833005759251e-03 #define GSL_LOG_DBL_EPSILON (-3.6043653389117154e+01) #define GSL_DBL_MIN 2.2250738585072014e-308 #define GSL_SQRT_DBL_MIN 1.4916681462400413e-154 #define GSL_ROOT3_DBL_MIN 2.8126442852362996e-103 #define GSL_ROOT4_DBL_MIN 1.2213386697554620e-77 #define GSL_ROOT5_DBL_MIN 2.9476022969691763e-62 #define GSL_ROOT6_DBL_MIN 5.3034368905798218e-52 #define GSL_LOG_DBL_MIN (-7.0839641853226408e+02) #define GSL_DBL_MAX 1.7976931348623157e+308 #define GSL_SQRT_DBL_MAX 1.3407807929942596e+154 #define GSL_ROOT3_DBL_MAX 5.6438030941222897e+102 #define GSL_ROOT4_DBL_MAX 1.1579208923731620e+77 #define GSL_ROOT5_DBL_MAX 4.4765466227572707e+61 #define GSL_ROOT6_DBL_MAX 2.3756689782295612e+51 #define GSL_LOG_DBL_MAX 7.0978271289338397e+02 #define GSL_FLT_EPSILON 1.1920928955078125e-07 #define GSL_SQRT_FLT_EPSILON 3.4526698300124393e-04 #define GSL_ROOT3_FLT_EPSILON 4.9215666011518501e-03 #define GSL_ROOT4_FLT_EPSILON 1.8581361171917516e-02 #define GSL_ROOT5_FLT_EPSILON 4.1234622211652937e-02 #define GSL_ROOT6_FLT_EPSILON 7.0153878019335827e-02 #define GSL_LOG_FLT_EPSILON (-1.5942385152878742e+01) #define GSL_FLT_MIN 1.1754943508222875e-38 #define GSL_SQRT_FLT_MIN 1.0842021724855044e-19 #define GSL_ROOT3_FLT_MIN 2.2737367544323241e-13 #define GSL_ROOT4_FLT_MIN 3.2927225399135965e-10 #define GSL_ROOT5_FLT_MIN 2.5944428542140822e-08 #define GSL_ROOT6_FLT_MIN 4.7683715820312542e-07 #define GSL_LOG_FLT_MIN (-8.7336544750553102e+01) #define GSL_FLT_MAX 3.4028234663852886e+38 #define GSL_SQRT_FLT_MAX 1.8446743523953730e+19 #define GSL_ROOT3_FLT_MAX 6.9814635196223242e+12 #define GSL_ROOT4_FLT_MAX 4.2949672319999986e+09 #define GSL_ROOT5_FLT_MAX 5.0859007855960041e+07 #define GSL_ROOT6_FLT_MAX 2.6422459233807749e+06 #define GSL_LOG_FLT_MAX 8.8722839052068352e+01 #define GSL_SFLT_EPSILON 4.8828125000000000e-04 #define GSL_SQRT_SFLT_EPSILON 2.2097086912079612e-02 #define GSL_ROOT3_SFLT_EPSILON 7.8745065618429588e-02 #define GSL_ROOT4_SFLT_EPSILON 1.4865088937534013e-01 #define GSL_ROOT5_SFLT_EPSILON 2.1763764082403100e-01 #define GSL_ROOT6_SFLT_EPSILON 2.8061551207734325e-01 #define GSL_LOG_SFLT_EPSILON (-7.6246189861593985e+00) /* !MACHINE CONSTANTS! */ /* a little internal backwards compatibility */ #define GSL_MACH_EPS GSL_DBL_EPSILON /* Here are the constants related to or derived from * machine constants. These are not to be confused with * the constants that define various precision levels * for the precision/error system. * * This information is determined at configure time * and is platform dependent. Edit at your own risk. * * PLATFORM: WHIZ-O-MATIC * CONFIG-DATE: Thu Nov 19 19:27:18 MST 1998 * CONFIG-HOST: nnn.lanl.gov */ /* machine precision constants */ /* #define GSL_MACH_EPS 1.0e-15 */ #define GSL_SQRT_MACH_EPS 3.2e-08 #define GSL_ROOT3_MACH_EPS 1.0e-05 #define GSL_ROOT4_MACH_EPS 0.000178 #define GSL_ROOT5_MACH_EPS 0.00100 #define GSL_ROOT6_MACH_EPS 0.00316 #define GSL_LOG_MACH_EPS (-34.54) #endif /* __GSL_MACHINE_H__ */ praat-6.0.04/external/gsl/gsl_math.h000066400000000000000000000132501261542461700172770ustar00rootroot00000000000000/* gsl_math.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_MATH_H__ #define __GSL_MATH_H__ #include #include "gsl_sys.h" #include "gsl_machine.h" #include "gsl_precision.h" #include "gsl_nan.h" #include "gsl_pow_int.h" #ifndef M_E #define M_E 2.71828182845904523536028747135 /* e */ #endif #ifndef M_LOG2E #define M_LOG2E 1.44269504088896340735992468100 /* log_2 (e) */ #endif #ifndef M_LOG10E #define M_LOG10E 0.43429448190325182765112891892 /* log_10 (e) */ #endif #ifndef M_SQRT2 #define M_SQRT2 1.41421356237309504880168872421 /* sqrt(2) */ #endif #ifndef M_SQRT1_2 #define M_SQRT1_2 0.70710678118654752440084436210 /* sqrt(1/2) */ #endif #ifndef M_SQRT3 #define M_SQRT3 1.73205080756887729352744634151 /* sqrt(3) */ #endif #ifndef M_PI #define M_PI 3.14159265358979323846264338328 /* pi */ #endif #ifndef M_PI_2 #define M_PI_2 1.57079632679489661923132169164 /* pi/2 */ #endif #ifndef M_PI_4 #define M_PI_4 0.78539816339744830961566084582 /* pi/4 */ #endif #ifndef M_SQRTPI #define M_SQRTPI 1.77245385090551602729816748334 /* sqrt(pi) */ #endif #ifndef M_2_SQRTPI #define M_2_SQRTPI 1.12837916709551257389615890312 /* 2/sqrt(pi) */ #endif #ifndef M_1_PI #define M_1_PI 0.31830988618379067153776752675 /* 1/pi */ #endif #ifndef M_2_PI #define M_2_PI 0.63661977236758134307553505349 /* 2/pi */ #endif #ifndef M_LN10 #define M_LN10 2.30258509299404568401799145468 /* ln(10) */ #endif #ifndef M_LN2 #define M_LN2 0.69314718055994530941723212146 /* ln(2) */ #endif #ifndef M_LNPI #define M_LNPI 1.14472988584940017414342735135 /* ln(pi) */ #endif #ifndef M_EULER #define M_EULER 0.57721566490153286060651209008 /* Euler constant */ #endif #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* other needlessly compulsive abstractions */ #define GSL_IS_ODD(n) ((n) & 1) #define GSL_IS_EVEN(n) (!(GSL_IS_ODD(n))) #define GSL_SIGN(x) ((x) >= 0.0 ? 1 : -1) /* Return nonzero if x is a real number, i.e. non NaN or infinite. */ #define GSL_IS_REAL(x) (gsl_finite(x)) /* Define MAX and MIN macros/functions if they don't exist. */ /* plain old macros for general use */ #define GSL_MAX(a,b) ((a) > (b) ? (a) : (b)) #define GSL_MIN(a,b) ((a) < (b) ? (a) : (b)) /* function versions of the above, in case they are needed */ double gsl_max (double a, double b); double gsl_min (double a, double b); /* inline-friendly strongly typed versions */ #ifdef HAVE_INLINE extern inline int GSL_MAX_INT (int a, int b); extern inline int GSL_MIN_INT (int a, int b); extern inline double GSL_MAX_DBL (double a, double b); extern inline double GSL_MIN_DBL (double a, double b); extern inline long double GSL_MAX_LDBL (long double a, long double b); extern inline long double GSL_MIN_LDBL (long double a, long double b); extern inline int GSL_MAX_INT (int a, int b) { return GSL_MAX (a, b); } extern inline int GSL_MIN_INT (int a, int b) { return GSL_MIN (a, b); } extern inline double GSL_MAX_DBL (double a, double b) { return GSL_MAX (a, b); } extern inline double GSL_MIN_DBL (double a, double b) { return GSL_MIN (a, b); } extern inline long double GSL_MAX_LDBL (long double a, long double b) { return GSL_MAX (a, b); } extern inline long double GSL_MIN_LDBL (long double a, long double b) { return GSL_MIN (a, b); } #else #define GSL_MAX_INT(a,b) GSL_MAX(a,b) #define GSL_MIN_INT(a,b) GSL_MIN(a,b) #define GSL_MAX_DBL(a,b) GSL_MAX(a,b) #define GSL_MIN_DBL(a,b) GSL_MIN(a,b) #define GSL_MAX_LDBL(a,b) GSL_MAX(a,b) #define GSL_MIN_LDBL(a,b) GSL_MIN(a,b) #endif /* HAVE_INLINE */ /* Definition of an arbitrary function with parameters */ struct gsl_function_struct { double (* function) (double x, void * params); void * params; }; typedef struct gsl_function_struct gsl_function ; #define GSL_FN_EVAL(F,x) (*((F)->function))(x,(F)->params) /* Definition of an arbitrary function returning two values, r1, r2 */ struct gsl_function_fdf_struct { double (* f) (double x, void * params); double (* df) (double x, void * params); void (* fdf) (double x, void * params, double * f, double * df); void * params; }; typedef struct gsl_function_fdf_struct gsl_function_fdf ; #define GSL_FN_FDF_EVAL_F(FDF,x) (*((FDF)->f))(x,(FDF)->params) #define GSL_FN_FDF_EVAL_DF(FDF,x) (*((FDF)->df))(x,(FDF)->params) #define GSL_FN_FDF_EVAL_F_DF(FDF,x,y,dy) (*((FDF)->fdf))(x,(FDF)->params,(y),(dy)) /* Definition of an arbitrary vector-valued function with parameters */ struct gsl_function_vec_struct { int (* function) (double x, double y[], void * params); void * params; }; typedef struct gsl_function_vec_struct gsl_function_vec ; #define GSL_FN_VEC_EVAL(F,x,y) (*((F)->function))(x,y,(F)->params) __END_DECLS #endif /* __GSL_MATH_H__ */ praat-6.0.04/external/gsl/gsl_matrix.h000066400000000000000000000010361261542461700176510ustar00rootroot00000000000000#ifndef __GSL_MATRIX_H__ #define __GSL_MATRIX_H__ #include "gsl_matrix_complex_long_double.h" #include "gsl_matrix_complex_double.h" #include "gsl_matrix_complex_float.h" #include "gsl_matrix_long_double.h" #include "gsl_matrix_double.h" #include "gsl_matrix_float.h" #include "gsl_matrix_ulong.h" #include "gsl_matrix_long.h" #include "gsl_matrix_uint.h" #include "gsl_matrix_int.h" #include "gsl_matrix_ushort.h" #include "gsl_matrix_short.h" #include "gsl_matrix_uchar.h" #include "gsl_matrix_char.h" #endif /* __GSL_MATRIX_H__ */ praat-6.0.04/external/gsl/gsl_matrix__copy.c000066400000000000000000000036261261542461700210440ustar00rootroot00000000000000#include "gsl__config.h" #include "gsl_matrix.h" #include "gsl_errno.h" #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_matrix__copy_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_matrix__copy_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_matrix__copy_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_matrix__copy_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_matrix__copy_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_matrix__copy_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_matrix__copy_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_matrix__copy_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_matrix__copy_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_matrix__copy_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_matrix__copy_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_matrix__copy_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_matrix__copy_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_matrix__copy_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_matrix__copy_source.c000066400000000000000000000047361261542461700224270ustar00rootroot00000000000000/* matrix/copy_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ int FUNCTION (gsl_matrix, memcpy) (TYPE (gsl_matrix) * dest, const TYPE (gsl_matrix) * src) { const size_t src_size1 = src->size1; const size_t src_size2 = src->size2; const size_t dest_size1 = dest->size1; const size_t dest_size2 = dest->size2; if (src_size1 != dest_size1 || src_size2 != dest_size2) { GSL_ERROR ("matrix sizes are different", GSL_EBADLEN); } { const size_t src_tda = src->tda ; const size_t dest_tda = dest->tda ; size_t i, j; for (i = 0; i < src_size1 ; i++) { for (j = 0; j < MULTIPLICITY * src_size2; j++) { dest->data[MULTIPLICITY * dest_tda * i + j] = src->data[MULTIPLICITY * src_tda * i + j]; } } } return GSL_SUCCESS; } int FUNCTION (gsl_matrix, swap) (TYPE (gsl_matrix) * dest, TYPE (gsl_matrix) * src) { const size_t src_size1 = src->size1; const size_t src_size2 = src->size2; const size_t dest_size1 = dest->size1; const size_t dest_size2 = dest->size2; if (src_size1 != dest_size1 || src_size2 != dest_size2) { GSL_ERROR ("matrix sizes are different", GSL_EBADLEN); } { const size_t src_tda = src->tda ; const size_t dest_tda = dest->tda ; size_t i, j; for (i = 0; i < src_size1 ; i++) { for (j = 0; j < MULTIPLICITY * src_size2; j++) { ATOMIC tmp = src->data[MULTIPLICITY * src_tda * i + j]; src->data[MULTIPLICITY * src_tda * i + j] = dest->data[MULTIPLICITY * dest_tda * i + j]; dest->data[MULTIPLICITY * dest_tda * i + j] = tmp ; } } } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_matrix__file.c000066400000000000000000000036561261542461700210140ustar00rootroot00000000000000#include "gsl__config.h" #include "gsl_errno.h" #include "gsl_matrix.h" #include "gsl_vector.h" #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_matrix__file_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_matrix__file_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_matrix__file_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_matrix__file_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_matrix__file_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_matrix__file_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_matrix__file_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_matrix__file_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_matrix__file_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_matrix__file_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_matrix__file_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_matrix__file_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_matrix__file_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_matrix__file_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_matrix__file_source.c000066400000000000000000000104321261542461700223620ustar00rootroot00000000000000/* matrix/file_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ int FUNCTION (gsl_matrix, fread) (FILE * stream, TYPE (gsl_matrix) * m) { int status = 0; const size_t size1 = m->size1; const size_t size2 = m->size2; const size_t tda = m->tda; if (tda == size2) /* the rows are contiguous */ { status = FUNCTION (gsl_block, raw_fread) (stream, m->data, size1 * size2, 1); } else { size_t i; for (i = 0 ; i < size1 ; i++) /* read each row separately */ { status = FUNCTION (gsl_block, raw_fread) (stream, m->data + i * tda, size2, 1); if (status) break; } } return status; } int FUNCTION (gsl_matrix, fwrite) (FILE * stream, const TYPE (gsl_matrix) * m) { int status = 0; const size_t size1 = m->size1; const size_t size2 = m->size2; const size_t tda = m->tda; if (tda == size2) /* the rows are contiguous */ { status = FUNCTION (gsl_block, raw_fwrite) (stream, m->data, size1 * size2, 1); } else { size_t i; for (i = 0 ; i < size1 ; i++) /* write each row separately */ { status = FUNCTION (gsl_block, raw_fwrite) (stream, m->data + i * tda, size2, 1); if (status) break; } } return status; } #if !(USES_LONGDOUBLE && !HAVE_PRINTF_LONGDOUBLE) int FUNCTION (gsl_matrix, fprintf) (FILE * stream, const TYPE (gsl_matrix) * m, const char *format) { int status = 0; const size_t size1 = m->size1; const size_t size2 = m->size2; const size_t tda = m->tda; if (tda == size2) /* the rows are contiguous */ { status = FUNCTION (gsl_block, raw_fprintf) (stream, m->data, size1 * size2, 1, format); } else { size_t i; for (i = 0 ; i < size1 ; i++) /* print each row separately */ { status = FUNCTION (gsl_block, raw_fprintf) (stream, m->data + i * tda, size2, 1, format); if (status) break; } } return status; } int FUNCTION (gsl_matrix, fscanf) (FILE * stream, TYPE (gsl_matrix) * m) { int status = 0; const size_t size1 = m->size1; const size_t size2 = m->size2; const size_t tda = m->tda; if (tda == size2) /* the rows are contiguous */ { status = FUNCTION (gsl_block, raw_fscanf) (stream, m->data, size1 * size2, 1); } else { size_t i; for (i = 0 ; i < size1 ; i++) /* scan each row separately */ { status = FUNCTION (gsl_block, raw_fscanf) (stream, m->data + i * tda, size2, 1); if (status) break; } } return status; } #endif praat-6.0.04/external/gsl/gsl_matrix__getset.c000066400000000000000000000037121261542461700213610ustar00rootroot00000000000000#include "gsl__config.h" #include "gsl_errno.h" #include "gsl_matrix.h" #include "gsl_vector.h" #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_matrix__getset_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_matrix__getset_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_matrix__getset_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_matrix__getset_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_matrix__getset_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_matrix__getset_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_matrix__getset_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_matrix__getset_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_matrix__getset_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_matrix__getset_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_matrix__getset_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_matrix__getset_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_matrix__getset_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_matrix__getset_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_matrix__getset_source.c000066400000000000000000000116761261542461700227510ustar00rootroot00000000000000/**********************************************************************/ /* The functions below are obsolete */ /**********************************************************************/ int FUNCTION (gsl_matrix, get_row) (TYPE (gsl_vector) * v, const TYPE (gsl_matrix) * m, const size_t i) { const size_t M = m->size1; const size_t N = m->size2; const size_t tda = m->tda; if (i >= M) { GSL_ERROR ("row index is out of range", GSL_EINVAL); } if (v->size != N) { GSL_ERROR ("matrix row size and vector length are not equal", GSL_EBADLEN); } { ATOMIC *v_data = v->data; const ATOMIC *row_data = m->data + MULTIPLICITY * i * tda; const size_t stride = v->stride ; size_t j; for (j = 0; j < N; j++) { unsigned int k; for (k = 0; k < MULTIPLICITY; k++) { v_data[MULTIPLICITY * stride * j + k] = row_data[MULTIPLICITY * j + k]; } } } return GSL_SUCCESS; } int FUNCTION (gsl_matrix, get_col) (TYPE (gsl_vector) * v, const TYPE (gsl_matrix) * m, const size_t j) { const size_t M = m->size1; const size_t N = m->size2; const size_t tda = m->tda; if (j >= N) { GSL_ERROR ("column index is out of range", GSL_EINVAL); } if (v->size != M) { GSL_ERROR ("matrix column size and vector length are not equal", GSL_EBADLEN); } { ATOMIC *v_data = v->data; const ATOMIC *column_data = m->data + MULTIPLICITY * j; const size_t stride = v->stride ; size_t i; for (i = 0; i < M; i++) { unsigned int k; for (k = 0; k < MULTIPLICITY; k++) { v_data[stride * MULTIPLICITY * i + k] = column_data[MULTIPLICITY * i * tda + k]; } } } return GSL_SUCCESS; } int FUNCTION (gsl_matrix, set_row) (TYPE (gsl_matrix) * m, const size_t i, const TYPE (gsl_vector) * v) { const size_t M = m->size1; const size_t N = m->size2; const size_t tda = m->tda; if (i >= M) { GSL_ERROR ("row index is out of range", GSL_EINVAL); } if (v->size != N) { GSL_ERROR ("matrix row size and vector length are not equal", GSL_EBADLEN); } { const ATOMIC *v_data = v->data; ATOMIC *row_data = m->data + MULTIPLICITY * i * tda; const size_t stride = v->stride ; size_t j; for (j = 0; j < N; j++) { unsigned int k; for (k = 0; k < MULTIPLICITY; k++) { row_data[MULTIPLICITY*j + k] = v_data[MULTIPLICITY * stride * j + k]; } } } return GSL_SUCCESS; } int FUNCTION (gsl_matrix, set_col) (TYPE (gsl_matrix) * m, const size_t j, const TYPE (gsl_vector) * v) { const size_t M = m->size1; const size_t N = m->size2; const size_t tda = m->tda; if (j >= N) { GSL_ERROR ("column index is out of range", GSL_EINVAL); } if (v->size != M) { GSL_ERROR ("matrix column size and vector length are not equal", GSL_EBADLEN); } { const ATOMIC *v_data = v->data; ATOMIC *column_data = m->data + MULTIPLICITY * j; const size_t stride = v->stride ; size_t i; for (i = 0; i < M; i++) { unsigned int k; for (k = 0; k < MULTIPLICITY; k++) { column_data[MULTIPLICITY * i * tda + k] = v_data[MULTIPLICITY * stride * i + k]; } } } return GSL_SUCCESS; } TYPE (gsl_vector) * FUNCTION (gsl_vector, alloc_row_from_matrix) (TYPE(gsl_matrix) * m, const size_t i) { TYPE (gsl_vector) * v; const size_t M = m->size1; if (i >= M) { GSL_ERROR_VAL ("row index is out of range", GSL_EINVAL, 0); } v = (TYPE (gsl_vector) *) malloc (sizeof (TYPE (gsl_vector))); if (v == 0) { GSL_ERROR_VAL ("failed to allocate space for vector struct", GSL_ENOMEM, 0); } v->data = m->data + MULTIPLICITY * i * m->tda ; v->size = m->size2; v->stride = 1; v->block = 0; return v; } TYPE (gsl_vector) * FUNCTION (gsl_vector, alloc_col_from_matrix) (TYPE(gsl_matrix) * m, const size_t j) { TYPE (gsl_vector) * v; const size_t N = m->size2; if (j >= N) { GSL_ERROR_VAL ("column index is out of range", GSL_EINVAL, 0); } v = (TYPE (gsl_vector) *) malloc (sizeof (TYPE (gsl_vector))); if (v == 0) { GSL_ERROR_VAL ("failed to allocate space for vector struct", GSL_ENOMEM, 0); } v->data = m->data + MULTIPLICITY * j ; v->size = m->size1; v->stride = m->tda; v->block = 0; return v; } praat-6.0.04/external/gsl/gsl_matrix__init.c000066400000000000000000000036261261542461700210350ustar00rootroot00000000000000#include "gsl__config.h" #include "gsl_errno.h" #include "gsl_matrix.h" #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_matrix__init_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_matrix__init_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_matrix__init_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_matrix__init_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_matrix__init_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_matrix__init_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_matrix__init_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_matrix__init_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_matrix__init_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_matrix__init_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_matrix__init_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_matrix__init_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_matrix__init_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_matrix__init_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_matrix__init_source.c000066400000000000000000000136401261542461700224120ustar00rootroot00000000000000/* matrix/init_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ TYPE (gsl_matrix) * FUNCTION (gsl_matrix, alloc) (const size_t n1, const size_t n2) { TYPE (gsl_block) * block; TYPE (gsl_matrix) * m; if (n1 == 0) { GSL_ERROR_VAL ("matrix dimension n1 must be positive integer", GSL_EINVAL, 0); } else if (n2 == 0) { GSL_ERROR_VAL ("matrix dimension n2 must be positive integer", GSL_EINVAL, 0); } m = (TYPE (gsl_matrix) *) malloc (sizeof (TYPE (gsl_matrix))); if (m == 0) { GSL_ERROR_VAL ("failed to allocate space for matrix struct", GSL_ENOMEM, 0); } /* FIXME: n1*n2 could overflow for large dimensions */ block = FUNCTION(gsl_block, alloc) (n1 * n2) ; if (block == 0) { GSL_ERROR_VAL ("failed to allocate space for block", GSL_ENOMEM, 0); } m->data = block->data; m->size1 = n1; m->size2 = n2; m->tda = n2; m->block = block; m->owner = 1; return m; } TYPE (gsl_matrix) * FUNCTION (gsl_matrix, calloc) (const size_t n1, const size_t n2) { size_t i; TYPE (gsl_matrix) * m = FUNCTION (gsl_matrix, alloc) (n1, n2); if (m == 0) return 0; /* initialize matrix to zero */ for (i = 0; i < MULTIPLICITY * n1 * n2; i++) { m->data[i] = 0; } return m; } TYPE (gsl_matrix) * FUNCTION (gsl_matrix, alloc_from_block) (TYPE(gsl_block) * block, const size_t offset, const size_t n1, const size_t n2, const size_t d2) { TYPE (gsl_matrix) * m; if (n1 == 0) { GSL_ERROR_VAL ("matrix dimension n1 must be positive integer", GSL_EINVAL, 0); } else if (n2 == 0) { GSL_ERROR_VAL ("matrix dimension n2 must be positive integer", GSL_EINVAL, 0); } else if (d2 < n2) { GSL_ERROR_VAL ("matrix dimension d2 must be greater than n2", GSL_EINVAL, 0); } else if (block->size < offset + n1 * d2) { GSL_ERROR_VAL ("matrix size exceeds available block size", GSL_EINVAL, 0); } m = (TYPE (gsl_matrix) *) malloc (sizeof (TYPE (gsl_matrix))); if (m == 0) { GSL_ERROR_VAL ("failed to allocate space for matrix struct", GSL_ENOMEM, 0); } m->data = block->data + MULTIPLICITY * offset; m->size1 = n1; m->size2 = n2; m->tda = d2; m->block = block; m->owner = 0; return m; } TYPE (gsl_matrix) * FUNCTION (gsl_matrix, alloc_from_matrix) (TYPE(gsl_matrix) * mm, const size_t k1, const size_t k2, const size_t n1, const size_t n2) { TYPE (gsl_matrix) * m; if (n1 == 0) { GSL_ERROR_VAL ("matrix dimension n1 must be positive integer", GSL_EINVAL, 0); } else if (n2 == 0) { GSL_ERROR_VAL ("matrix dimension n2 must be positive integer", GSL_EINVAL, 0); } else if (k1 + n1 > mm->size1) { GSL_ERROR_VAL ("submatrix dimension 1 exceeds size of original", GSL_EINVAL, 0); } else if (k2 + n2 > mm->size2) { GSL_ERROR_VAL ("submatrix dimension 2 exceeds size of original", GSL_EINVAL, 0); } m = (TYPE (gsl_matrix) *) malloc (sizeof (TYPE (gsl_matrix))); if (m == 0) { GSL_ERROR_VAL ("failed to allocate space for matrix struct", GSL_ENOMEM, 0); } m->data = mm->data + k1 * mm->tda + k2 ; m->size1 = n1; m->size2 = n2; m->tda = mm->tda; m->block = mm->block; m->owner = 0; return m; } void FUNCTION (gsl_matrix, free) (TYPE (gsl_matrix) * m) { if (m->owner) { FUNCTION(gsl_block, free) (m->block); } free (m); } void FUNCTION (gsl_matrix, set_identity) (TYPE (gsl_matrix) * m) { size_t i, j; ATOMIC * const data = m->data; const size_t p = m->size1 ; const size_t q = m->size2 ; const size_t tda = m->tda ; const BASE zero = ZERO; const BASE one = ONE; for (i = 0; i < p; i++) { for (j = 0; j < q; j++) { *(BASE *) (data + MULTIPLICITY * (i * tda + j)) = ((i == j) ? one : zero); } } } void FUNCTION (gsl_matrix, set_zero) (TYPE (gsl_matrix) * m) { size_t i, j; ATOMIC * const data = m->data; const size_t p = m->size1 ; const size_t q = m->size2 ; const size_t tda = m->tda ; const BASE zero = ZERO; for (i = 0; i < p; i++) { for (j = 0; j < q; j++) { *(BASE *) (data + MULTIPLICITY * (i * tda + j)) = zero; } } } void FUNCTION (gsl_matrix, set_all) (TYPE (gsl_matrix) * m, BASE x) { size_t i, j; ATOMIC * const data = m->data; const size_t p = m->size1 ; const size_t q = m->size2 ; const size_t tda = m->tda ; for (i = 0; i < p; i++) { for (j = 0; j < q; j++) { *(BASE *) (data + MULTIPLICITY * (i * tda + j)) = x; } } } praat-6.0.04/external/gsl/gsl_matrix__matrix.c000066400000000000000000000036621261542461700213760ustar00rootroot00000000000000#include "gsl__config.h" #include "gsl_errno.h" #include "gsl_matrix.h" #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_matrix__matrix_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_matrix__matrix_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_matrix__matrix_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_matrix__matrix_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_matrix__matrix_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_matrix__matrix_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_matrix__matrix_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_matrix__matrix_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_matrix__matrix_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_matrix__matrix_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_matrix__matrix_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_matrix__matrix_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_matrix__matrix_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_matrix__matrix_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_matrix__matrix_source.c000066400000000000000000000061421261542461700227520ustar00rootroot00000000000000/* matrix/matrix_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef HIDE_INLINE_STATIC BASE FUNCTION (gsl_matrix, get) (const TYPE (gsl_matrix) * m, const size_t i, const size_t j) { BASE zero = ZERO; if (gsl_check_range) { if (i >= m->size1) /* size_t is unsigned, can't be negative */ { GSL_ERROR_VAL ("first index out of range", GSL_EINVAL, zero); } else if (j >= m->size2) /* size_t is unsigned, can't be negative */ { GSL_ERROR_VAL ("second index out of range", GSL_EINVAL, zero); } } return *(BASE *) (m->data + MULTIPLICITY * (i * m->tda + j)); } void FUNCTION (gsl_matrix, set) (TYPE (gsl_matrix) * m, const size_t i, const size_t j, const BASE x) { if (gsl_check_range) { if (i >= m->size1) /* size_t is unsigned, can't be negative */ { GSL_ERROR_VOID ("first index out of range", GSL_EINVAL); } else if (j >= m->size2) /* size_t is unsigned, can't be negative */ { GSL_ERROR_VOID ("second index out of range", GSL_EINVAL); } } *(BASE *) (m->data + MULTIPLICITY * (i * m->tda + j)) = x; } BASE * FUNCTION (gsl_matrix, ptr) (TYPE (gsl_matrix) * m, const size_t i, const size_t j) { if (gsl_check_range) { if (i >= m->size1) /* size_t is unsigned, can't be negative */ { GSL_ERROR_NULL ("first index out of range", GSL_EINVAL); } else if (j >= m->size2) /* size_t is unsigned, can't be negative */ { GSL_ERROR_NULL ("second index out of range", GSL_EINVAL); } } return (BASE *) (m->data + MULTIPLICITY * (i * m->tda + j)); } const BASE * FUNCTION (gsl_matrix, const_ptr) (const TYPE (gsl_matrix) * m, const size_t i, const size_t j) { if (gsl_check_range) { if (i >= m->size1) /* size_t is unsigned, can't be negative */ { GSL_ERROR_NULL ("first index out of range", GSL_EINVAL); } else if (j >= m->size2) /* size_t is unsigned, can't be negative */ { GSL_ERROR_NULL ("second index out of range", GSL_EINVAL); } } return (const BASE *) (m->data + MULTIPLICITY * (i * m->tda + j)); } #endif praat-6.0.04/external/gsl/gsl_matrix__minmax.c000066400000000000000000000030041261542461700213510ustar00rootroot00000000000000#include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_matrix.h" #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_matrix__minmax_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_matrix__minmax_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_matrix__minmax_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_matrix__minmax_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_matrix__minmax_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_matrix__minmax_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_matrix__minmax_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_matrix__minmax_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_matrix__minmax_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_matrix__minmax_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_matrix__minmax_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_matrix__minmax_source.c000066400000000000000000000125651261542461700227450ustar00rootroot00000000000000/* matrix/minmax_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ BASE FUNCTION (gsl_matrix, max) (const TYPE (gsl_matrix) * m) { /* finds the largest element of a matrix */ const size_t M = m->size1; const size_t N = m->size2; const size_t tda = m->tda; BASE max = m->data[0 * tda + 0]; size_t i, j; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { BASE x = m->data[i * tda + j]; if (x > max) max = x; #ifdef FP if (isnan (x)) return x; #endif } } return max; } BASE FUNCTION (gsl_matrix, min) (const TYPE (gsl_matrix) * m) { /* finds the smallest element of a matrix */ const size_t M = m->size1; const size_t N = m->size2; const size_t tda = m->tda; BASE min = m->data[0 * tda + 0]; size_t i, j; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { BASE x = m->data[i * tda + j]; if (x < min) min = x; #ifdef FP if (isnan (x)) return x; #endif } } return min; } void FUNCTION (gsl_matrix, minmax) (const TYPE (gsl_matrix) * m, BASE * min_out, BASE * max_out) { /* finds the smallest and largest elements of a matrix */ const size_t M = m->size1; const size_t N = m->size2; const size_t tda = m->tda; BASE max = m->data[0 * tda + 0]; BASE min = m->data[0 * tda + 0]; size_t i, j; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { BASE x = m->data[i * tda + j]; if (x < min) { min = x; } if (x > max) { max = x; } #ifdef FP if (isnan (x)) { *min_out = x; *max_out = x; return; } #endif } } *min_out = min; *max_out = max; } void FUNCTION (gsl_matrix, max_index) (const TYPE (gsl_matrix) * m, size_t * imax_out, size_t *jmax_out) { /* finds the largest element of a matrix */ const size_t M = m->size1; const size_t N = m->size2; const size_t tda = m->tda; BASE max = m->data[0 * tda + 0]; size_t imax = 0, jmax = 0; size_t i, j; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { BASE x = m->data[i * tda + j]; if (x > max) { max = x; imax = i; jmax = j; } #ifdef FP if (isnan (x)) { *imax_out = i; *jmax_out = j; return; } #endif } } *imax_out = imax; *jmax_out = jmax; } void FUNCTION (gsl_matrix, min_index) (const TYPE (gsl_matrix) * m, size_t * imin_out, size_t *jmin_out) { /* finds the largest element of a matrix */ const size_t M = m->size1; const size_t N = m->size2; const size_t tda = m->tda; BASE min = m->data[0 * tda + 0]; size_t imin = 0, jmin = 0; size_t i, j; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { BASE x = m->data[i * tda + j]; if (x < min) { min = x; imin = i; jmin = j; } #ifdef FP if (isnan (x)) { *imin_out = i; *jmin_out = j; return; } #endif } } *imin_out = imin; *jmin_out = jmin; } void FUNCTION (gsl_matrix, minmax_index) (const TYPE (gsl_matrix) * m, size_t * imin_out, size_t * jmin_out, size_t * imax_out, size_t * jmax_out) { /* finds the smallest and largest elements of a matrix */ const size_t M = m->size1; const size_t N = m->size2; const size_t tda = m->tda; size_t imin = 0, jmin = 0, imax = 0, jmax = 0; BASE max = m->data[0 * tda + 0]; BASE min = m->data[0 * tda + 0]; size_t i, j; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { BASE x = m->data[i * tda + j]; if (x < min) { min = x; imin = i; jmin = j; } if (x > max) { max = x; imax = i; jmax = j; } #ifdef FP if (isnan (x)) { *imin_out = i; *jmin_out = j; *imax_out = i; *jmax_out = j; return; } #endif } } *imin_out = imin; *jmin_out = jmin; *imax_out = imax; *jmax_out = jmax; } praat-6.0.04/external/gsl/gsl_matrix__oper.c000066400000000000000000000037251261542461700210370ustar00rootroot00000000000000#include "gsl__config.h" #include #include #include "gsl_math.h" #include "gsl_matrix.h" #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_matrix__oper_complex_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_matrix__oper_complex_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_matrix__oper_complex_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_matrix__oper_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_matrix__oper_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_matrix__oper_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_matrix__oper_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_matrix__oper_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_matrix__oper_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_matrix__oper_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_matrix__oper_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_matrix__oper_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_matrix__oper_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_matrix__oper_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_matrix__oper_complex_source.c000066400000000000000000000131521261542461700241410ustar00rootroot00000000000000/* matrix/oper_complex_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ int FUNCTION (gsl_matrix, add) (TYPE (gsl_matrix) * a, const TYPE (gsl_matrix) * b) { const size_t M = a->size1; const size_t N = a->size2; if (b->size1 != M || b->size2 != N) { GSL_ERROR ("matrices must have same dimensions", GSL_EBADLEN); } else { const size_t tda_a = a->tda; const size_t tda_b = b->tda; size_t i, j; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { const size_t aij = 2 * (i * tda_a + j); const size_t bij = 2 * (i * tda_b + j); a->data[aij] += b->data[bij]; a->data[aij + 1] += b->data[bij + 1]; } } return GSL_SUCCESS; } } int FUNCTION (gsl_matrix, sub) (TYPE (gsl_matrix) * a, const TYPE (gsl_matrix) * b) { const size_t M = a->size1; const size_t N = a->size2; if (b->size1 != M || b->size2 != N) { GSL_ERROR ("matrices must have same dimensions", GSL_EBADLEN); } else { const size_t tda_a = a->tda; const size_t tda_b = b->tda; size_t i, j; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { const size_t aij = 2 * (i * tda_a + j); const size_t bij = 2 * (i * tda_b + j); a->data[aij] -= b->data[bij]; a->data[aij + 1] -= b->data[bij + 1]; } } return GSL_SUCCESS; } } int FUNCTION (gsl_matrix, mul_elements) (TYPE (gsl_matrix) * a, const TYPE (gsl_matrix) * b) { const size_t M = a->size1; const size_t N = a->size2; if (b->size1 != M || b->size2 != N) { GSL_ERROR ("matrices must have same dimensions", GSL_EBADLEN); } else { const size_t tda_a = a->tda; const size_t tda_b = b->tda; size_t i, j; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { const size_t aij = 2 * (i * tda_a + j); const size_t bij = 2 * (i * tda_b + j); ATOMIC ar = a->data[aij]; ATOMIC ai = a->data[aij + 1]; ATOMIC br = b->data[bij]; ATOMIC bi = b->data[bij + 1]; a->data[aij] = ar * br - ai * bi; a->data[aij + 1] = ar * bi + ai * br; } } return GSL_SUCCESS; } } int FUNCTION (gsl_matrix, div_elements) (TYPE (gsl_matrix) * a, const TYPE (gsl_matrix) * b) { const size_t M = a->size1; const size_t N = a->size2; if (b->size1 != M || b->size2 != N) { GSL_ERROR ("matrices must have same dimensions", GSL_EBADLEN); } else { const size_t tda_a = a->tda; const size_t tda_b = b->tda; size_t i, j; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { const size_t aij = 2 * (i * tda_a + j); const size_t bij = 2 * (i * tda_b + j); ATOMIC ar = a->data[aij]; ATOMIC ai = a->data[aij + 1]; ATOMIC br = b->data[bij]; ATOMIC bi = b->data[bij + 1]; ATOMIC s = 1.0 / hypot(br, bi); ATOMIC sbr = s * br; ATOMIC sbi = s * bi; a->data[aij] = (ar * sbr + ai * sbi) * s; a->data[aij + 1] = (ai * sbr - ar * sbi) * s; } } return GSL_SUCCESS; } } int FUNCTION (gsl_matrix, scale) (TYPE (gsl_matrix) * a, const BASE x) { const size_t M = a->size1; const size_t N = a->size2; const size_t tda = a->tda; size_t i, j; ATOMIC xr = GSL_REAL(x); ATOMIC xi = GSL_IMAG(x); for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { const size_t aij = 2 * (i * tda + j); ATOMIC ar = a->data[aij]; ATOMIC ai = a->data[aij + 1]; a->data[aij] = ar * xr - ai * xi; a->data[aij + 1] = ar * xi + ai * xr; } } return GSL_SUCCESS; } int FUNCTION (gsl_matrix, add_constant) (TYPE (gsl_matrix) * a, const BASE x) { const size_t M = a->size1; const size_t N = a->size2; const size_t tda = a->tda; size_t i, j; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { a->data[2 * (i * tda + j)] += GSL_REAL (x); a->data[2 * (i * tda + j) + 1] += GSL_IMAG (x); } } return GSL_SUCCESS; } int FUNCTION (gsl_matrix, add_diagonal) (TYPE (gsl_matrix) * a, const BASE x) { const size_t M = a->size1; const size_t N = a->size2; const size_t tda = a->tda; const size_t loop_lim = (M < N ? M : N); size_t i; for (i = 0; i < loop_lim; i++) { a->data[2 * (i * tda + i)] += GSL_REAL (x); a->data[2 * (i * tda + i) + 1] += GSL_IMAG (x); } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_matrix__oper_source.c000066400000000000000000000101171261542461700224100ustar00rootroot00000000000000/* matrix/oper_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ int FUNCTION(gsl_matrix, add) (TYPE(gsl_matrix) * a, const TYPE(gsl_matrix) * b) { const size_t M = a->size1; const size_t N = a->size2; if (b->size1 != M || b->size2 != N) { GSL_ERROR ("matrices must have same dimensions", GSL_EBADLEN); } else { const size_t tda_a = a->tda; const size_t tda_b = b->tda; size_t i, j; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { a->data[i * tda_a + j] += b->data[i * tda_b + j]; } } return GSL_SUCCESS; } } int FUNCTION(gsl_matrix, sub) (TYPE(gsl_matrix) * a, const TYPE(gsl_matrix) * b) { const size_t M = a->size1; const size_t N = a->size2; if (b->size1 != M || b->size2 != N) { GSL_ERROR ("matrices must have same dimensions", GSL_EBADLEN); } else { const size_t tda_a = a->tda; const size_t tda_b = b->tda; size_t i, j; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { a->data[i * tda_a + j] -= b->data[i * tda_b + j]; } } return GSL_SUCCESS; } } int FUNCTION(gsl_matrix, mul_elements) (TYPE(gsl_matrix) * a, const TYPE(gsl_matrix) * b) { const size_t M = a->size1; const size_t N = a->size2; if (b->size1 != M || b->size2 != N) { GSL_ERROR ("matrices must have same dimensions", GSL_EBADLEN); } else { const size_t tda_a = a->tda; const size_t tda_b = b->tda; size_t i, j; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { a->data[i * tda_a + j] *= b->data[i * tda_b + j]; } } return GSL_SUCCESS; } } int FUNCTION(gsl_matrix, div_elements) (TYPE(gsl_matrix) * a, const TYPE(gsl_matrix) * b) { const size_t M = a->size1; const size_t N = a->size2; if (b->size1 != M || b->size2 != N) { GSL_ERROR ("matrices must have same dimensions", GSL_EBADLEN); } else { const size_t tda_a = a->tda; const size_t tda_b = b->tda; size_t i, j; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { a->data[i * tda_a + j] /= b->data[i * tda_b + j]; } } return GSL_SUCCESS; } } int FUNCTION(gsl_matrix, scale) (TYPE(gsl_matrix) * a, const double x) { const size_t M = a->size1; const size_t N = a->size2; const size_t tda = a->tda; size_t i, j; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { a->data[i * tda + j] *= x; } } return GSL_SUCCESS; } int FUNCTION(gsl_matrix, add_constant) (TYPE(gsl_matrix) * a, const double x) { const size_t M = a->size1; const size_t N = a->size2; const size_t tda = a->tda; size_t i, j; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { a->data[i * tda + j] += x; } } return GSL_SUCCESS; } int FUNCTION(gsl_matrix, add_diagonal) (TYPE(gsl_matrix) * a, const double x) { const size_t M = a->size1; const size_t N = a->size2; const size_t tda = a->tda; const size_t loop_lim = ( M < N ? M : N ); size_t i; for (i = 0; i < loop_lim; i++) { a->data[i * tda + i] += x; } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_matrix__prop.c000066400000000000000000000036261261542461700210520ustar00rootroot00000000000000#include "gsl__config.h" #include "gsl_matrix.h" #include "gsl_errno.h" #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_matrix__prop_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_matrix__prop_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_matrix__prop_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_matrix__prop_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_matrix__prop_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_matrix__prop_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_matrix__prop_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_matrix__prop_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_matrix__prop_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_matrix__prop_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_matrix__prop_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_matrix__prop_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_matrix__prop_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_matrix__prop_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_matrix__prop_source.c000066400000000000000000000054721261542461700224330ustar00rootroot00000000000000/* matrix/prop_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ int FUNCTION (gsl_matrix, isnull) (const TYPE (gsl_matrix) * m) { const size_t size1 = m->size1; const size_t size2 = m->size2; const size_t tda = m->tda ; size_t i, j, k; for (i = 0; i < size1 ; i++) { for (j = 0; j < size2; j++) { for (k = 0; k < MULTIPLICITY; k++) { if (m->data[(i * tda + j) * MULTIPLICITY + k] != 0.0) { return 0; } } } } return 1; } int FUNCTION (gsl_matrix, ispos) (const TYPE (gsl_matrix) * m) { const size_t size1 = m->size1; const size_t size2 = m->size2; const size_t tda = m->tda ; size_t i, j, k; for (i = 0; i < size1 ; i++) { for (j = 0; j < size2; j++) { for (k = 0; k < MULTIPLICITY; k++) { if (m->data[(i * tda + j) * MULTIPLICITY + k] <= 0.0) { return 0; } } } } return 1; } int FUNCTION (gsl_matrix, isneg) (const TYPE (gsl_matrix) * m) { const size_t size1 = m->size1; const size_t size2 = m->size2; const size_t tda = m->tda ; size_t i, j, k; for (i = 0; i < size1 ; i++) { for (j = 0; j < size2; j++) { for (k = 0; k < MULTIPLICITY; k++) { if (m->data[(i * tda + j) * MULTIPLICITY + k] >= 0.0) { return 0; } } } } return 1; } int FUNCTION (gsl_matrix, isnonneg) (const TYPE (gsl_matrix) * m) { const size_t size1 = m->size1; const size_t size2 = m->size2; const size_t tda = m->tda ; size_t i, j, k; for (i = 0; i < size1 ; i++) { for (j = 0; j < size2; j++) { for (k = 0; k < MULTIPLICITY; k++) { if (m->data[(i * tda + j) * MULTIPLICITY + k] < 0.0) { return 0; } } } } return 1; } praat-6.0.04/external/gsl/gsl_matrix__rowcol.c000066400000000000000000000076301261542461700213760ustar00rootroot00000000000000#include "gsl__config.h" #include "gsl_math.h" #include "gsl_matrix.h" #include "gsl_vector.h" #include "gsl_errno.h" #include "gsl_matrix__view.h" #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_CHAR #define USE_QUALIFIER #define QUALIFIER const #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_matrix__rowcol_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_matrix__rowcol_source.c000066400000000000000000000115741261542461700227600ustar00rootroot00000000000000/* matrix/rowcol_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ QUALIFIED_VIEW(_gsl_vector,view) FUNCTION (gsl_matrix, row) (QUALIFIED_TYPE(gsl_matrix) * m, const size_t i) { QUALIFIED_VIEW(_gsl_vector,view) view = NULL_VECTOR_VIEW; if (i >= m->size1) { GSL_ERROR_VAL ("row index is out of range", GSL_EINVAL, view); } { TYPE(gsl_vector) v = NULL_VECTOR; v.data = m->data + i * MULTIPLICITY * m->tda; v.size = m->size2; v.stride = 1; v.block = m->block; v.owner = 0; view.vector = v; return view; } } QUALIFIED_VIEW(_gsl_vector,view) FUNCTION (gsl_matrix, column) (QUALIFIED_TYPE(gsl_matrix) * m, const size_t j) { QUALIFIED_VIEW(_gsl_vector,view) view = NULL_VECTOR_VIEW; if (j >= m->size2) { GSL_ERROR_VAL ("column index is out of range", GSL_EINVAL, view); } { TYPE(gsl_vector) v = NULL_VECTOR; v.data = m->data + j * MULTIPLICITY; v.size = m->size1; v.stride = m->tda; v.block = m->block; v.owner = 0; view.vector = v; return view; } } QUALIFIED_VIEW(_gsl_vector,view) FUNCTION (gsl_matrix, diagonal) (QUALIFIED_TYPE(gsl_matrix) * m) { QUALIFIED_VIEW(_gsl_vector,view) view = NULL_VECTOR_VIEW; TYPE(gsl_vector) v = NULL_VECTOR; v.data = m->data; v.size = GSL_MIN(m->size1,m->size2); v.stride = m->tda + 1; v.block = m->block; v.owner = 0; view.vector = v; return view; } QUALIFIED_VIEW(_gsl_vector,view) FUNCTION (gsl_matrix, subdiagonal) (QUALIFIED_TYPE(gsl_matrix) * m, const size_t k) { QUALIFIED_VIEW(_gsl_vector,view) view = NULL_VECTOR_VIEW; if (k >= m->size1) { GSL_ERROR_VAL ("subdiagonal index is out of range", GSL_EINVAL, view); } { TYPE(gsl_vector) v = NULL_VECTOR; v.data = m->data + k * MULTIPLICITY * m->tda; v.size = GSL_MIN(m->size1 - k, m->size2); v.stride = m->tda + 1; v.block = m->block; v.owner = 0; view.vector = v; return view; } } QUALIFIED_VIEW(_gsl_vector,view) FUNCTION (gsl_matrix, superdiagonal) (QUALIFIED_TYPE(gsl_matrix) * m, const size_t k) { QUALIFIED_VIEW(_gsl_vector,view) view = NULL_VECTOR_VIEW; if (k >= m->size2) { GSL_ERROR_VAL ("column index is out of range", GSL_EINVAL, view); } { TYPE(gsl_vector) v = NULL_VECTOR; v.data = m->data + k * MULTIPLICITY; v.size = GSL_MIN(m->size1, m->size2 - k); v.stride = m->tda + 1; v.block = m->block; v.owner = 0; view.vector = v; return view; } } QUALIFIED_VIEW(_gsl_vector,view) FUNCTION (gsl_matrix, subrow) (QUALIFIED_TYPE(gsl_matrix) * m, const size_t i, const size_t offset, const size_t n) { QUALIFIED_VIEW(_gsl_vector,view) view = NULL_VECTOR_VIEW; if (i >= m->size1) { GSL_ERROR_VAL ("row index is out of range", GSL_EINVAL, view); } else if (n == 0) { GSL_ERROR_VAL ("vector length n must be positive integer", GSL_EINVAL, view); } else if (offset + n > m->size1) { GSL_ERROR_VAL ("dimension n overflows matrix", GSL_EINVAL, view); } { TYPE(gsl_vector) v = NULL_VECTOR; v.data = m->data + MULTIPLICITY * (i * m->tda + offset); v.size = n; v.stride = 1; v.block = m->block; v.owner = 0; view.vector = v; return view; } } QUALIFIED_VIEW(_gsl_vector,view) FUNCTION (gsl_matrix, subcolumn) (QUALIFIED_TYPE(gsl_matrix) * m, const size_t j, const size_t offset, const size_t n) { QUALIFIED_VIEW(_gsl_vector,view) view = NULL_VECTOR_VIEW; if (j >= m->size2) { GSL_ERROR_VAL ("column index is out of range", GSL_EINVAL, view); } else if (n == 0) { GSL_ERROR_VAL ("vector length n must be positive integer", GSL_EINVAL, view); } else if (offset + n > m->size2) { GSL_ERROR_VAL ("dimension n overflows matrix", GSL_EINVAL, view); } { TYPE(gsl_vector) v = NULL_VECTOR; v.data = m->data + MULTIPLICITY * (offset * m->tda + j); v.size = n; v.stride = m->tda; v.block = m->block; v.owner = 0; view.vector = v; return view; } } praat-6.0.04/external/gsl/gsl_matrix__submatrix.c000066400000000000000000000077541261542461700221160ustar00rootroot00000000000000#include "gsl__config.h" #include "gsl_math.h" #include "gsl_matrix.h" #include "gsl_vector.h" #include "gsl_errno.h" #include "gsl_matrix__view.h" #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_CHAR #define USE_QUALIFIER #define QUALIFIER const #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_matrix__submatrix_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_matrix__submatrix_source.c000066400000000000000000000040241261542461700234610ustar00rootroot00000000000000/* matrix/submatrix_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ QUALIFIED_VIEW(_gsl_matrix,view) FUNCTION (gsl_matrix, submatrix) (QUALIFIED_TYPE(gsl_matrix) * m, const size_t i, const size_t j, const size_t n1, const size_t n2) { QUALIFIED_VIEW(_gsl_matrix,view) view = NULL_MATRIX_VIEW; if (i >= m->size1) { GSL_ERROR_VAL ("row index is out of range", GSL_EINVAL, view); } else if (j >= m->size2) { GSL_ERROR_VAL ("column index is out of range", GSL_EINVAL, view); } else if (n1 == 0) { GSL_ERROR_VAL ("first dimension must be non-zero", GSL_EINVAL, view); } else if (n2 == 0) { GSL_ERROR_VAL ("second dimension must be non-zero", GSL_EINVAL, view); } else if (i + n1 > m->size1) { GSL_ERROR_VAL ("first dimension overflows matrix", GSL_EINVAL, view); } else if (j + n2 > m->size2) { GSL_ERROR_VAL ("second dimension overflows matrix", GSL_EINVAL, view); } { TYPE(gsl_matrix) s = NULL_MATRIX; s.data = m->data + MULTIPLICITY * (i * m->tda + j); s.size1 = n1; s.size2 = n2; s.tda = m->tda; s.block = m->block; s.owner = 0; view.matrix = s; return view; } } praat-6.0.04/external/gsl/gsl_matrix__swap.c000066400000000000000000000036561261542461700210470ustar00rootroot00000000000000#include "gsl__config.h" #include "gsl_matrix.h" #include "gsl_vector.h" #include "gsl_errno.h" #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_matrix__swap_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_matrix__swap_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_matrix__swap_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_matrix__swap_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_matrix__swap_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_matrix__swap_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_matrix__swap_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_matrix__swap_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_matrix__swap_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_matrix__swap_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_matrix__swap_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_matrix__swap_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_matrix__swap_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_matrix__swap_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_matrix__swap_source.c000066400000000000000000000117661261542461700224300ustar00rootroot00000000000000/* matrix/swap_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ int FUNCTION (gsl_matrix, swap_rows) (TYPE (gsl_matrix) * m, const size_t i, const size_t j) { const size_t size1 = m->size1; const size_t size2 = m->size2; if (i >= size1) { GSL_ERROR ("first row index is out of range", GSL_EINVAL); } if (j >= size1) { GSL_ERROR ("second row index is out of range", GSL_EINVAL); } if (i != j) { ATOMIC *row1 = m->data + MULTIPLICITY * i * m->tda; ATOMIC *row2 = m->data + MULTIPLICITY * j * m->tda; size_t k; for (k = 0; k < MULTIPLICITY * size2; k++) { ATOMIC tmp = row1[k] ; row1[k] = row2[k] ; row2[k] = tmp ; } } return GSL_SUCCESS; } int FUNCTION (gsl_matrix, swap_columns) (TYPE (gsl_matrix) * m, const size_t i, const size_t j) { const size_t size1 = m->size1; const size_t size2 = m->size2; if (i >= size2) { GSL_ERROR ("first column index is out of range", GSL_EINVAL); } if (j >= size2) { GSL_ERROR ("second column index is out of range", GSL_EINVAL); } if (i != j) { ATOMIC *col1 = m->data + MULTIPLICITY * i; ATOMIC *col2 = m->data + MULTIPLICITY * j; size_t p; for (p = 0; p < size1; p++) { size_t k; size_t n = p * MULTIPLICITY * m->tda; for (k = 0; k < MULTIPLICITY; k++) { ATOMIC tmp = col1[n+k] ; col1[n+k] = col2[n+k] ; col2[n+k] = tmp ; } } } return GSL_SUCCESS; } int FUNCTION (gsl_matrix, swap_rowcol) (TYPE (gsl_matrix) * m, const size_t i, const size_t j) { const size_t size1 = m->size1; const size_t size2 = m->size2; if (size1 != size2) { GSL_ERROR ("matrix must be square to swap row and column", GSL_ENOTSQR); } if (i >= size1) { GSL_ERROR ("row index is out of range", GSL_EINVAL); } if (j >= size2) { GSL_ERROR ("column index is out of range", GSL_EINVAL); } { ATOMIC *row = m->data + MULTIPLICITY * i * m->tda; ATOMIC *col = m->data + MULTIPLICITY * j; size_t p; for (p = 0; p < size1; p++) { size_t k; size_t r = p * MULTIPLICITY; size_t c = p * MULTIPLICITY * m->tda; for (k = 0; k < MULTIPLICITY; k++) { ATOMIC tmp = col[c+k] ; col[c+k] = row[r+k] ; row[r+k] = tmp ; } } } return GSL_SUCCESS; } int FUNCTION (gsl_matrix, transpose) (TYPE (gsl_matrix) * m) { const size_t size1 = m->size1; const size_t size2 = m->size2; size_t i, j, k; if (size1 != size2) { GSL_ERROR ("matrix must be square to take transpose", GSL_ENOTSQR); } for (i = 0; i < size1; i++) { for (j = i + 1 ; j < size2 ; j++) { for (k = 0; k < MULTIPLICITY; k++) { size_t e1 = (i * m->tda + j) * MULTIPLICITY + k ; size_t e2 = (j * m->tda + i) * MULTIPLICITY + k ; { ATOMIC tmp = m->data[e1] ; m->data[e1] = m->data[e2] ; m->data[e2] = tmp ; } } } } return GSL_SUCCESS; } int FUNCTION (gsl_matrix, transpose_memcpy) (TYPE (gsl_matrix) * dest, const TYPE (gsl_matrix) * src) { const size_t src_size1 = src->size1; const size_t src_size2 = src->size2; const size_t dest_size1 = dest->size1; const size_t dest_size2 = dest->size2; size_t i, j, k; if (dest_size2 != src_size1 || dest_size1 != src_size2) { GSL_ERROR ("dimensions of dest matrix must be transpose of src matrix", GSL_EBADLEN); } for (i = 0; i < dest_size1; i++) { for (j = 0 ; j < dest_size2; j++) { for (k = 0; k < MULTIPLICITY; k++) { size_t e1 = (i * dest->tda + j) * MULTIPLICITY + k ; size_t e2 = (j * src->tda + i) * MULTIPLICITY + k ; dest->data[e1] = src->data[e2] ; } } } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_matrix__view.c000066400000000000000000000074621261542461700210460ustar00rootroot00000000000000#include "gsl__config.h" #include "gsl_errno.h" #include "gsl_matrix.h" #include "gsl_matrix__view.h" #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_CHAR #define USE_QUALIFIER #define QUALIFIER const #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_matrix__view_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_matrix__view.h000066400000000000000000000002451261542461700210430ustar00rootroot00000000000000#define NULL_VECTOR {0, 0, 0, 0, 0} #define NULL_VECTOR_VIEW {{0, 0, 0, 0, 0}} #define NULL_MATRIX {0, 0, 0, 0, 0, 0} #define NULL_MATRIX_VIEW {{0, 0, 0, 0, 0, 0}} praat-6.0.04/external/gsl/gsl_matrix__view_source.c000066400000000000000000000157031261542461700224230ustar00rootroot00000000000000/* matrix/view_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ QUALIFIED_VIEW (_gsl_matrix,view) FUNCTION (gsl_matrix, view_array) (QUALIFIER ATOMIC * array, const size_t n1, const size_t n2) { QUALIFIED_VIEW (_gsl_matrix,view) view = NULL_MATRIX_VIEW; if (n1 == 0) { GSL_ERROR_VAL ("matrix dimension n1 must be positive integer", GSL_EINVAL, view); } else if (n2 == 0) { GSL_ERROR_VAL ("matrix dimension n2 must be positive integer", GSL_EINVAL, view); } { TYPE(gsl_matrix) m = NULL_MATRIX; m.data = (ATOMIC *)array; m.size1 = n1; m.size2 = n2; m.tda = n2; m.block = 0; m.owner = 0; view.matrix = m; return view; } } QUALIFIED_VIEW (_gsl_matrix,view) FUNCTION(gsl_matrix, view_array_with_tda) (QUALIFIER ATOMIC * base, const size_t n1, const size_t n2, const size_t tda) { QUALIFIED_VIEW (_gsl_matrix,view) view = NULL_MATRIX_VIEW; if (n1 == 0) { GSL_ERROR_VAL ("matrix dimension n1 must be positive integer", GSL_EINVAL, view); } else if (n2 == 0) { GSL_ERROR_VAL ("matrix dimension n2 must be positive integer", GSL_EINVAL, view); } else if (n2 > tda) { GSL_ERROR_VAL ("matrix dimension n2 must not exceed tda", GSL_EINVAL, view); } { TYPE(gsl_matrix) m = NULL_MATRIX; m.data = (ATOMIC *)base; m.size1 = n1; m.size2 = n2; m.tda = tda; m.block = 0; m.owner = 0; view.matrix = m; return view; } } QUALIFIED_VIEW (_gsl_matrix,view) FUNCTION(gsl_matrix, view_vector) (QUALIFIED_TYPE(gsl_vector) * v, const size_t n1, const size_t n2) { QUALIFIED_VIEW (_gsl_matrix,view) view = NULL_MATRIX_VIEW; if (n1 == 0) { GSL_ERROR_VAL ("matrix dimension n1 must be positive integer", GSL_EINVAL, view); } else if (n2 == 0) { GSL_ERROR_VAL ("matrix dimension n2 must be positive integer", GSL_EINVAL, view); } else if (v->stride != 1) { GSL_ERROR_VAL ("vector must have unit stride", GSL_EINVAL, view); } else if (n1 * n2 > v->size) { GSL_ERROR_VAL ("matrix size exceeds size of original", GSL_EINVAL, view); } { TYPE(gsl_matrix) m = NULL_MATRIX; m.data = v->data; m.size1 = n1; m.size2 = n2; m.tda = n2; m.block = v->block; m.owner = 0; view.matrix = m; return view; } } QUALIFIED_VIEW (_gsl_matrix,view) FUNCTION(gsl_matrix, view_vector_with_tda) (QUALIFIED_TYPE(gsl_vector) * v, const size_t n1, const size_t n2, const size_t tda) { QUALIFIED_VIEW (_gsl_matrix,view) view = NULL_MATRIX_VIEW; if (n1 == 0) { GSL_ERROR_VAL ("matrix dimension n1 must be positive integer", GSL_EINVAL, view); } else if (n2 == 0) { GSL_ERROR_VAL ("matrix dimension n2 must be positive integer", GSL_EINVAL, view); } else if (v->stride != 1) { GSL_ERROR_VAL ("vector must have unit stride", GSL_EINVAL, view); } else if (n2 > tda) { GSL_ERROR_VAL ("matrix dimension n2 must not exceed tda", GSL_EINVAL, view); } else if (n1 * tda > v->size) { GSL_ERROR_VAL ("matrix size exceeds size of original", GSL_EINVAL, view); } { TYPE(gsl_matrix) m = NULL_MATRIX; m.data = v->data; m.size1 = n1; m.size2 = n2; m.tda = tda; m.block = v->block; m.owner = 0; view.matrix = m; return view; } } #ifdef JUNK int FUNCTION (gsl_matrix, view_from_matrix) (TYPE(gsl_matrix) * m, TYPE(gsl_matrix) * mm, const size_t k1, const size_t k2, const size_t n1, const size_t n2) { if (n1 == 0) { GSL_ERROR_VAL ("matrix dimension n1 must be positive integer", GSL_EINVAL, 0); } else if (n2 == 0) { GSL_ERROR_VAL ("matrix dimension n2 must be positive integer", GSL_EINVAL, 0); } else if (k1 + n1 > mm->size1) { GSL_ERROR_VAL ("submatrix dimension 1 exceeds size of original", GSL_EINVAL, 0); } else if (k2 + n2 > mm->size2) { GSL_ERROR_VAL ("submatrix dimension 2 exceeds size of original", GSL_EINVAL, 0); } m->data = mm->data + k1 * mm->tda + k2 ; m->size1 = n1; m->size2 = n2; m->tda = mm->tda; m->block = mm->block; m->owner = 0; return GSL_SUCCESS; } int FUNCTION (gsl_vector, view_row_from_matrix) (TYPE(gsl_vector) * v, TYPE(gsl_matrix) * m, const size_t i) { const size_t column_length = m->size1; if (i >= column_length) { GSL_ERROR ("row index is out of range", GSL_EINVAL); } if (v->block != 0) { GSL_ERROR ("vector already has memory allocated to it", GSL_ENOMEM); } v->data = m->data + MULTIPLICITY * i * m->tda ; v->size = m->size2; v->stride = 1; return GSL_SUCCESS; } int FUNCTION (gsl_vector, view_col_from_matrix) (TYPE(gsl_vector) * v, TYPE(gsl_matrix) * m, const size_t j) { const size_t row_length = m->size2; if (j >= row_length) { GSL_ERROR_VAL ("column index is out of range", GSL_EINVAL, 0); } if (v->block != 0) { GSL_ERROR ("vector already has memory allocated to it", GSL_ENOMEM); } v->data = m->data + MULTIPLICITY * j ; v->size = m->size1; v->stride = m->tda; return GSL_SUCCESS; } #endif /* JUNK */ praat-6.0.04/external/gsl/gsl_matrix_char.h000066400000000000000000000264361261542461700206610ustar00rootroot00000000000000/* matrix/gsl_matrix_char.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_MATRIX_CHAR_H__ #define __GSL_MATRIX_CHAR_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_check_range.h" #include "gsl_vector_char.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size1; size_t size2; size_t tda; char * data; gsl_block_char * block; int owner; } gsl_matrix_char; typedef struct { gsl_matrix_char matrix; } _gsl_matrix_char_view; typedef _gsl_matrix_char_view gsl_matrix_char_view; typedef struct { gsl_matrix_char matrix; } _gsl_matrix_char_const_view; typedef const _gsl_matrix_char_const_view gsl_matrix_char_const_view; /* Allocation */ gsl_matrix_char * gsl_matrix_char_alloc (const size_t n1, const size_t n2); gsl_matrix_char * gsl_matrix_char_calloc (const size_t n1, const size_t n2); gsl_matrix_char * gsl_matrix_char_alloc_from_block (gsl_block_char * b, const size_t offset, const size_t n1, const size_t n2, const size_t d2); gsl_matrix_char * gsl_matrix_char_alloc_from_matrix (gsl_matrix_char * m, const size_t k1, const size_t k2, const size_t n1, const size_t n2); gsl_vector_char * gsl_vector_char_alloc_row_from_matrix (gsl_matrix_char * m, const size_t i); gsl_vector_char * gsl_vector_char_alloc_col_from_matrix (gsl_matrix_char * m, const size_t j); void gsl_matrix_char_free (gsl_matrix_char * m); /* Views */ _gsl_matrix_char_view gsl_matrix_char_submatrix (gsl_matrix_char * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_char_view gsl_matrix_char_row (gsl_matrix_char * m, const size_t i); _gsl_vector_char_view gsl_matrix_char_column (gsl_matrix_char * m, const size_t j); _gsl_vector_char_view gsl_matrix_char_diagonal (gsl_matrix_char * m); _gsl_vector_char_view gsl_matrix_char_subdiagonal (gsl_matrix_char * m, const size_t k); _gsl_vector_char_view gsl_matrix_char_superdiagonal (gsl_matrix_char * m, const size_t k); _gsl_vector_char_view gsl_matrix_char_subrow (gsl_matrix_char * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_char_view gsl_matrix_char_subcolumn (gsl_matrix_char * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_char_view gsl_matrix_char_view_array (char * base, const size_t n1, const size_t n2); _gsl_matrix_char_view gsl_matrix_char_view_array_with_tda (char * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_char_view gsl_matrix_char_view_vector (gsl_vector_char * v, const size_t n1, const size_t n2); _gsl_matrix_char_view gsl_matrix_char_view_vector_with_tda (gsl_vector_char * v, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_char_const_view gsl_matrix_char_const_submatrix (const gsl_matrix_char * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_char_const_view gsl_matrix_char_const_row (const gsl_matrix_char * m, const size_t i); _gsl_vector_char_const_view gsl_matrix_char_const_column (const gsl_matrix_char * m, const size_t j); _gsl_vector_char_const_view gsl_matrix_char_const_diagonal (const gsl_matrix_char * m); _gsl_vector_char_const_view gsl_matrix_char_const_subdiagonal (const gsl_matrix_char * m, const size_t k); _gsl_vector_char_const_view gsl_matrix_char_const_superdiagonal (const gsl_matrix_char * m, const size_t k); _gsl_vector_char_const_view gsl_matrix_char_const_subrow (const gsl_matrix_char * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_char_const_view gsl_matrix_char_const_subcolumn (const gsl_matrix_char * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_char_const_view gsl_matrix_char_const_view_array (const char * base, const size_t n1, const size_t n2); _gsl_matrix_char_const_view gsl_matrix_char_const_view_array_with_tda (const char * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_char_const_view gsl_matrix_char_const_view_vector (const gsl_vector_char * v, const size_t n1, const size_t n2); _gsl_matrix_char_const_view gsl_matrix_char_const_view_vector_with_tda (const gsl_vector_char * v, const size_t n1, const size_t n2, const size_t tda); /* Operations */ char gsl_matrix_char_get(const gsl_matrix_char * m, const size_t i, const size_t j); void gsl_matrix_char_set(gsl_matrix_char * m, const size_t i, const size_t j, const char x); char * gsl_matrix_char_ptr(gsl_matrix_char * m, const size_t i, const size_t j); const char * gsl_matrix_char_const_ptr(const gsl_matrix_char * m, const size_t i, const size_t j); void gsl_matrix_char_set_zero (gsl_matrix_char * m); void gsl_matrix_char_set_identity (gsl_matrix_char * m); void gsl_matrix_char_set_all (gsl_matrix_char * m, char x); int gsl_matrix_char_fread (FILE * stream, gsl_matrix_char * m) ; int gsl_matrix_char_fwrite (FILE * stream, const gsl_matrix_char * m) ; int gsl_matrix_char_fscanf (FILE * stream, gsl_matrix_char * m); int gsl_matrix_char_fprintf (FILE * stream, const gsl_matrix_char * m, const char * format); int gsl_matrix_char_memcpy(gsl_matrix_char * dest, const gsl_matrix_char * src); int gsl_matrix_char_swap(gsl_matrix_char * m1, gsl_matrix_char * m2); int gsl_matrix_char_swap_rows(gsl_matrix_char * m, const size_t i, const size_t j); int gsl_matrix_char_swap_columns(gsl_matrix_char * m, const size_t i, const size_t j); int gsl_matrix_char_swap_rowcol(gsl_matrix_char * m, const size_t i, const size_t j); int gsl_matrix_char_transpose (gsl_matrix_char * m); int gsl_matrix_char_transpose_memcpy (gsl_matrix_char * dest, const gsl_matrix_char * src); char gsl_matrix_char_max (const gsl_matrix_char * m); char gsl_matrix_char_min (const gsl_matrix_char * m); void gsl_matrix_char_minmax (const gsl_matrix_char * m, char * min_out, char * max_out); void gsl_matrix_char_max_index (const gsl_matrix_char * m, size_t * imax, size_t *jmax); void gsl_matrix_char_min_index (const gsl_matrix_char * m, size_t * imin, size_t *jmin); void gsl_matrix_char_minmax_index (const gsl_matrix_char * m, size_t * imin, size_t * jmin, size_t * imax, size_t * jmax); int gsl_matrix_char_isnull (const gsl_matrix_char * m); int gsl_matrix_char_ispos (const gsl_matrix_char * m); int gsl_matrix_char_isneg (const gsl_matrix_char * m); int gsl_matrix_char_isnonneg (const gsl_matrix_char * m); int gsl_matrix_char_add (gsl_matrix_char * a, const gsl_matrix_char * b); int gsl_matrix_char_sub (gsl_matrix_char * a, const gsl_matrix_char * b); int gsl_matrix_char_mul_elements (gsl_matrix_char * a, const gsl_matrix_char * b); int gsl_matrix_char_div_elements (gsl_matrix_char * a, const gsl_matrix_char * b); int gsl_matrix_char_scale (gsl_matrix_char * a, const double x); int gsl_matrix_char_add_constant (gsl_matrix_char * a, const double x); int gsl_matrix_char_add_diagonal (gsl_matrix_char * a, const double x); /***********************************************************************/ /* The functions below are obsolete */ /***********************************************************************/ int gsl_matrix_char_get_row(gsl_vector_char * v, const gsl_matrix_char * m, const size_t i); int gsl_matrix_char_get_col(gsl_vector_char * v, const gsl_matrix_char * m, const size_t j); int gsl_matrix_char_set_row(gsl_matrix_char * m, const size_t i, const gsl_vector_char * v); int gsl_matrix_char_set_col(gsl_matrix_char * m, const size_t j, const gsl_vector_char * v); /* inline functions if you are using GCC */ #ifdef HAVE_INLINE extern inline char gsl_matrix_char_get(const gsl_matrix_char * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_VAL("first index out of range", GSL_EINVAL, 0) ; } else if (j >= m->size2) { GSL_ERROR_VAL("second index out of range", GSL_EINVAL, 0) ; } #endif return m->data[i * m->tda + j] ; } extern inline void gsl_matrix_char_set(gsl_matrix_char * m, const size_t i, const size_t j, const char x) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; } #endif m->data[i * m->tda + j] = x ; } extern inline char * gsl_matrix_char_ptr(gsl_matrix_char * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (char *) (m->data + (i * m->tda + j)) ; } extern inline const char * gsl_matrix_char_const_ptr(const gsl_matrix_char * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (const char *) (m->data + (i * m->tda + j)) ; } #endif __END_DECLS #endif /* __GSL_MATRIX_CHAR_H__ */ praat-6.0.04/external/gsl/gsl_matrix_complex_double.h000066400000000000000000000273631261542461700227450ustar00rootroot00000000000000/* matrix/gsl_matrix_complex_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_MATRIX_COMPLEX_DOUBLE_H__ #define __GSL_MATRIX_COMPLEX_DOUBLE_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_complex.h" #include "gsl_check_range.h" #include "gsl_vector_complex_double.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size1; size_t size2; size_t tda; double * data; gsl_block_complex * block; int owner; } gsl_matrix_complex ; typedef struct { gsl_matrix_complex matrix; } _gsl_matrix_complex_view; typedef _gsl_matrix_complex_view gsl_matrix_complex_view; typedef struct { gsl_matrix_complex matrix; } _gsl_matrix_complex_const_view; typedef const _gsl_matrix_complex_const_view gsl_matrix_complex_const_view; /* Allocation */ gsl_matrix_complex * gsl_matrix_complex_alloc (const size_t n1, const size_t n2); gsl_matrix_complex * gsl_matrix_complex_calloc (const size_t n1, const size_t n2); gsl_matrix_complex * gsl_matrix_complex_alloc_from_block (gsl_block_complex * b, const size_t offset, const size_t n1, const size_t n2, const size_t d2); gsl_matrix_complex * gsl_matrix_complex_alloc_from_matrix (gsl_matrix_complex * b, const size_t k1, const size_t k2, const size_t n1, const size_t n2); gsl_vector_complex * gsl_vector_complex_alloc_row_from_matrix (gsl_matrix_complex * m, const size_t i); gsl_vector_complex * gsl_vector_complex_alloc_col_from_matrix (gsl_matrix_complex * m, const size_t j); void gsl_matrix_complex_free (gsl_matrix_complex * m); /* Views */ _gsl_matrix_complex_view gsl_matrix_complex_submatrix (gsl_matrix_complex * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_complex_view gsl_matrix_complex_row (gsl_matrix_complex * m, const size_t i); _gsl_vector_complex_view gsl_matrix_complex_column (gsl_matrix_complex * m, const size_t j); _gsl_vector_complex_view gsl_matrix_complex_diagonal (gsl_matrix_complex * m); _gsl_vector_complex_view gsl_matrix_complex_subdiagonal (gsl_matrix_complex * m, const size_t k); _gsl_vector_complex_view gsl_matrix_complex_superdiagonal (gsl_matrix_complex * m, const size_t k); _gsl_vector_complex_view gsl_matrix_complex_subrow (gsl_matrix_complex * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_complex_view gsl_matrix_complex_subcolumn (gsl_matrix_complex * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_complex_view gsl_matrix_complex_view_array (double * base, const size_t n1, const size_t n2); _gsl_matrix_complex_view gsl_matrix_complex_view_array_with_tda (double * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_complex_view gsl_matrix_complex_view_vector (gsl_vector_complex * v, const size_t n1, const size_t n2); _gsl_matrix_complex_view gsl_matrix_complex_view_vector_with_tda (gsl_vector_complex * v, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_complex_const_view gsl_matrix_complex_const_submatrix (const gsl_matrix_complex * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_complex_const_view gsl_matrix_complex_const_row (const gsl_matrix_complex * m, const size_t i); _gsl_vector_complex_const_view gsl_matrix_complex_const_column (const gsl_matrix_complex * m, const size_t j); _gsl_vector_complex_const_view gsl_matrix_complex_const_diagonal (const gsl_matrix_complex * m); _gsl_vector_complex_const_view gsl_matrix_complex_const_subdiagonal (const gsl_matrix_complex * m, const size_t k); _gsl_vector_complex_const_view gsl_matrix_complex_const_superdiagonal (const gsl_matrix_complex * m, const size_t k); _gsl_vector_complex_const_view gsl_matrix_complex_const_subrow (const gsl_matrix_complex * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_complex_const_view gsl_matrix_complex_const_subcolumn (const gsl_matrix_complex * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_complex_const_view gsl_matrix_complex_const_view_array (const double * base, const size_t n1, const size_t n2); _gsl_matrix_complex_const_view gsl_matrix_complex_const_view_array_with_tda (const double * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_complex_const_view gsl_matrix_complex_const_view_vector (const gsl_vector_complex * v, const size_t n1, const size_t n2); _gsl_matrix_complex_const_view gsl_matrix_complex_const_view_vector_with_tda (const gsl_vector_complex * v, const size_t n1, const size_t n2, const size_t tda); /* Operations */ gsl_complex gsl_matrix_complex_get(const gsl_matrix_complex * m, const size_t i, const size_t j); void gsl_matrix_complex_set(gsl_matrix_complex * m, const size_t i, const size_t j, const gsl_complex x); gsl_complex * gsl_matrix_complex_ptr(gsl_matrix_complex * m, const size_t i, const size_t j); const gsl_complex * gsl_matrix_complex_const_ptr(const gsl_matrix_complex * m, const size_t i, const size_t j); void gsl_matrix_complex_set_zero (gsl_matrix_complex * m); void gsl_matrix_complex_set_identity (gsl_matrix_complex * m); void gsl_matrix_complex_set_all (gsl_matrix_complex * m, gsl_complex x); int gsl_matrix_complex_fread (FILE * stream, gsl_matrix_complex * m) ; int gsl_matrix_complex_fwrite (FILE * stream, const gsl_matrix_complex * m) ; int gsl_matrix_complex_fscanf (FILE * stream, gsl_matrix_complex * m); int gsl_matrix_complex_fprintf (FILE * stream, const gsl_matrix_complex * m, const char * format); int gsl_matrix_complex_memcpy(gsl_matrix_complex * dest, const gsl_matrix_complex * src); int gsl_matrix_complex_swap(gsl_matrix_complex * m1, gsl_matrix_complex * m2); int gsl_matrix_complex_swap_rows(gsl_matrix_complex * m, const size_t i, const size_t j); int gsl_matrix_complex_swap_columns(gsl_matrix_complex * m, const size_t i, const size_t j); int gsl_matrix_complex_swap_rowcol(gsl_matrix_complex * m, const size_t i, const size_t j); int gsl_matrix_complex_transpose (gsl_matrix_complex * m); int gsl_matrix_complex_transpose_memcpy (gsl_matrix_complex * dest, const gsl_matrix_complex * src); int gsl_matrix_complex_isnull (const gsl_matrix_complex * m); int gsl_matrix_complex_ispos (const gsl_matrix_complex * m); int gsl_matrix_complex_isneg (const gsl_matrix_complex * m); int gsl_matrix_complex_isnonneg (const gsl_matrix_complex * m); int gsl_matrix_complex_add (gsl_matrix_complex * a, const gsl_matrix_complex * b); int gsl_matrix_complex_sub (gsl_matrix_complex * a, const gsl_matrix_complex * b); int gsl_matrix_complex_mul_elements (gsl_matrix_complex * a, const gsl_matrix_complex * b); int gsl_matrix_complex_div_elements (gsl_matrix_complex * a, const gsl_matrix_complex * b); int gsl_matrix_complex_scale (gsl_matrix_complex * a, const gsl_complex x); int gsl_matrix_complex_add_constant (gsl_matrix_complex * a, const gsl_complex x); int gsl_matrix_complex_add_diagonal (gsl_matrix_complex * a, const gsl_complex x); /***********************************************************************/ /* The functions below are obsolete */ /***********************************************************************/ int gsl_matrix_complex_get_row(gsl_vector_complex * v, const gsl_matrix_complex * m, const size_t i); int gsl_matrix_complex_get_col(gsl_vector_complex * v, const gsl_matrix_complex * m, const size_t j); int gsl_matrix_complex_set_row(gsl_matrix_complex * m, const size_t i, const gsl_vector_complex * v); int gsl_matrix_complex_set_col(gsl_matrix_complex * m, const size_t j, const gsl_vector_complex * v); #ifdef HAVE_INLINE extern inline gsl_complex gsl_matrix_complex_get(const gsl_matrix_complex * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK gsl_complex zero = {{0,0}}; if (i >= m->size1) { GSL_ERROR_VAL("first index out of range", GSL_EINVAL, zero) ; } else if (j >= m->size2) { GSL_ERROR_VAL("second index out of range", GSL_EINVAL, zero) ; } #endif return *(gsl_complex *)(m->data + 2*(i * m->tda + j)) ; } extern inline void gsl_matrix_complex_set(gsl_matrix_complex * m, const size_t i, const size_t j, const gsl_complex x) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; } #endif *(gsl_complex *)(m->data + 2*(i * m->tda + j)) = x ; } extern inline gsl_complex * gsl_matrix_complex_ptr(gsl_matrix_complex * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (gsl_complex *)(m->data + 2*(i * m->tda + j)) ; } extern inline const gsl_complex * gsl_matrix_complex_const_ptr(const gsl_matrix_complex * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (const gsl_complex *)(m->data + 2*(i * m->tda + j)) ; } #endif /* HAVE_INLINE */ __END_DECLS #endif /* __GSL_MATRIX_COMPLEX_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_matrix_complex_float.h000066400000000000000000000316151261542461700225730ustar00rootroot00000000000000/* matrix/gsl_matrix_complex_float.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_MATRIX_COMPLEX_FLOAT_H__ #define __GSL_MATRIX_COMPLEX_FLOAT_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_complex.h" #include "gsl_check_range.h" #include "gsl_vector_complex_float.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size1; size_t size2; size_t tda; float * data; gsl_block_complex_float * block; int owner; } gsl_matrix_complex_float ; typedef struct { gsl_matrix_complex_float matrix; } _gsl_matrix_complex_float_view; typedef _gsl_matrix_complex_float_view gsl_matrix_complex_float_view; typedef struct { gsl_matrix_complex_float matrix; } _gsl_matrix_complex_float_const_view; typedef const _gsl_matrix_complex_float_const_view gsl_matrix_complex_float_const_view; /* Allocation */ gsl_matrix_complex_float * gsl_matrix_complex_float_alloc (const size_t n1, const size_t n2); gsl_matrix_complex_float * gsl_matrix_complex_float_calloc (const size_t n1, const size_t n2); gsl_matrix_complex_float * gsl_matrix_complex_float_alloc_from_block (gsl_block_complex_float * b, const size_t offset, const size_t n1, const size_t n2, const size_t d2); gsl_matrix_complex_float * gsl_matrix_complex_float_alloc_from_matrix (gsl_matrix_complex_float * b, const size_t k1, const size_t k2, const size_t n1, const size_t n2); gsl_vector_complex_float * gsl_vector_complex_float_alloc_row_from_matrix (gsl_matrix_complex_float * m, const size_t i); gsl_vector_complex_float * gsl_vector_complex_float_alloc_col_from_matrix (gsl_matrix_complex_float * m, const size_t j); void gsl_matrix_complex_float_free (gsl_matrix_complex_float * m); /* Views */ _gsl_matrix_complex_float_view gsl_matrix_complex_float_submatrix (gsl_matrix_complex_float * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_complex_float_view gsl_matrix_complex_float_row (gsl_matrix_complex_float * m, const size_t i); _gsl_vector_complex_float_view gsl_matrix_complex_float_column (gsl_matrix_complex_float * m, const size_t j); _gsl_vector_complex_float_view gsl_matrix_complex_float_diagonal (gsl_matrix_complex_float * m); _gsl_vector_complex_float_view gsl_matrix_complex_float_subdiagonal (gsl_matrix_complex_float * m, const size_t k); _gsl_vector_complex_float_view gsl_matrix_complex_float_superdiagonal (gsl_matrix_complex_float * m, const size_t k); _gsl_vector_complex_float_view gsl_matrix_complex_float_subrow (gsl_matrix_complex_float * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_complex_float_view gsl_matrix_complex_float_subcolumn (gsl_matrix_complex_float * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_complex_float_view gsl_matrix_complex_float_view_array (float * base, const size_t n1, const size_t n2); _gsl_matrix_complex_float_view gsl_matrix_complex_float_view_array_with_tda (float * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_complex_float_view gsl_matrix_complex_float_view_vector (gsl_vector_complex_float * v, const size_t n1, const size_t n2); _gsl_matrix_complex_float_view gsl_matrix_complex_float_view_vector_with_tda (gsl_vector_complex_float * v, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_complex_float_const_view gsl_matrix_complex_float_const_submatrix (const gsl_matrix_complex_float * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_complex_float_const_view gsl_matrix_complex_float_const_row (const gsl_matrix_complex_float * m, const size_t i); _gsl_vector_complex_float_const_view gsl_matrix_complex_float_const_column (const gsl_matrix_complex_float * m, const size_t j); _gsl_vector_complex_float_const_view gsl_matrix_complex_float_const_diagonal (const gsl_matrix_complex_float * m); _gsl_vector_complex_float_const_view gsl_matrix_complex_float_const_subdiagonal (const gsl_matrix_complex_float * m, const size_t k); _gsl_vector_complex_float_const_view gsl_matrix_complex_float_const_superdiagonal (const gsl_matrix_complex_float * m, const size_t k); _gsl_vector_complex_float_const_view gsl_matrix_complex_float_const_subrow (const gsl_matrix_complex_float * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_complex_float_const_view gsl_matrix_complex_float_const_subcolumn (const gsl_matrix_complex_float * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_complex_float_const_view gsl_matrix_complex_float_const_view_array (const float * base, const size_t n1, const size_t n2); _gsl_matrix_complex_float_const_view gsl_matrix_complex_float_const_view_array_with_tda (const float * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_complex_float_const_view gsl_matrix_complex_float_const_view_vector (const gsl_vector_complex_float * v, const size_t n1, const size_t n2); _gsl_matrix_complex_float_const_view gsl_matrix_complex_float_const_view_vector_with_tda (const gsl_vector_complex_float * v, const size_t n1, const size_t n2, const size_t tda); /* Operations */ gsl_complex_float gsl_matrix_complex_float_get(const gsl_matrix_complex_float * m, const size_t i, const size_t j); void gsl_matrix_complex_float_set(gsl_matrix_complex_float * m, const size_t i, const size_t j, const gsl_complex_float x); gsl_complex_float * gsl_matrix_complex_float_ptr(gsl_matrix_complex_float * m, const size_t i, const size_t j); const gsl_complex_float * gsl_matrix_complex_float_const_ptr(const gsl_matrix_complex_float * m, const size_t i, const size_t j); void gsl_matrix_complex_float_set_zero (gsl_matrix_complex_float * m); void gsl_matrix_complex_float_set_identity (gsl_matrix_complex_float * m); void gsl_matrix_complex_float_set_all (gsl_matrix_complex_float * m, gsl_complex_float x); int gsl_matrix_complex_float_fread (FILE * stream, gsl_matrix_complex_float * m) ; int gsl_matrix_complex_float_fwrite (FILE * stream, const gsl_matrix_complex_float * m) ; int gsl_matrix_complex_float_fscanf (FILE * stream, gsl_matrix_complex_float * m); int gsl_matrix_complex_float_fprintf (FILE * stream, const gsl_matrix_complex_float * m, const char * format); int gsl_matrix_complex_float_memcpy(gsl_matrix_complex_float * dest, const gsl_matrix_complex_float * src); int gsl_matrix_complex_float_swap(gsl_matrix_complex_float * m1, gsl_matrix_complex_float * m2); int gsl_matrix_complex_float_swap_rows(gsl_matrix_complex_float * m, const size_t i, const size_t j); int gsl_matrix_complex_float_swap_columns(gsl_matrix_complex_float * m, const size_t i, const size_t j); int gsl_matrix_complex_float_swap_rowcol(gsl_matrix_complex_float * m, const size_t i, const size_t j); int gsl_matrix_complex_float_transpose (gsl_matrix_complex_float * m); int gsl_matrix_complex_float_transpose_memcpy (gsl_matrix_complex_float * dest, const gsl_matrix_complex_float * src); int gsl_matrix_complex_float_isnull (const gsl_matrix_complex_float * m); int gsl_matrix_complex_float_ispos (const gsl_matrix_complex_float * m); int gsl_matrix_complex_float_isneg (const gsl_matrix_complex_float * m); int gsl_matrix_complex_float_isnonneg (const gsl_matrix_complex_float * m); int gsl_matrix_complex_float_add (gsl_matrix_complex_float * a, const gsl_matrix_complex_float * b); int gsl_matrix_complex_float_sub (gsl_matrix_complex_float * a, const gsl_matrix_complex_float * b); int gsl_matrix_complex_float_mul_elements (gsl_matrix_complex_float * a, const gsl_matrix_complex_float * b); int gsl_matrix_complex_float_div_elements (gsl_matrix_complex_float * a, const gsl_matrix_complex_float * b); int gsl_matrix_complex_float_scale (gsl_matrix_complex_float * a, const gsl_complex_float x); int gsl_matrix_complex_float_add_constant (gsl_matrix_complex_float * a, const gsl_complex_float x); int gsl_matrix_complex_float_add_diagonal (gsl_matrix_complex_float * a, const gsl_complex_float x); /***********************************************************************/ /* The functions below are obsolete */ /***********************************************************************/ int gsl_matrix_complex_float_get_row(gsl_vector_complex_float * v, const gsl_matrix_complex_float * m, const size_t i); int gsl_matrix_complex_float_get_col(gsl_vector_complex_float * v, const gsl_matrix_complex_float * m, const size_t j); int gsl_matrix_complex_float_set_row(gsl_matrix_complex_float * m, const size_t i, const gsl_vector_complex_float * v); int gsl_matrix_complex_float_set_col(gsl_matrix_complex_float * m, const size_t j, const gsl_vector_complex_float * v); #ifdef HAVE_INLINE extern inline gsl_complex_float gsl_matrix_complex_float_get(const gsl_matrix_complex_float * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK gsl_complex_float zero = {{0,0}}; if (i >= m->size1) { GSL_ERROR_VAL("first index out of range", GSL_EINVAL, zero) ; } else if (j >= m->size2) { GSL_ERROR_VAL("second index out of range", GSL_EINVAL, zero) ; } #endif return *(gsl_complex_float *)(m->data + 2*(i * m->tda + j)) ; } extern inline void gsl_matrix_complex_float_set(gsl_matrix_complex_float * m, const size_t i, const size_t j, const gsl_complex_float x) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; } #endif *(gsl_complex_float *)(m->data + 2*(i * m->tda + j)) = x ; } extern inline gsl_complex_float * gsl_matrix_complex_float_ptr(gsl_matrix_complex_float * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (gsl_complex_float *)(m->data + 2*(i * m->tda + j)) ; } extern inline const gsl_complex_float * gsl_matrix_complex_float_const_ptr(const gsl_matrix_complex_float * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (const gsl_complex_float *)(m->data + 2*(i * m->tda + j)) ; } #endif /* HAVE_INLINE */ __END_DECLS #endif /* __GSL_MATRIX_COMPLEX_FLOAT_H__ */ praat-6.0.04/external/gsl/gsl_matrix_complex_long_double.h000066400000000000000000000341551261542461700237610ustar00rootroot00000000000000/* matrix/gsl_matrix_complex_long_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_MATRIX_COMPLEX_LONG_DOUBLE_H__ #define __GSL_MATRIX_COMPLEX_LONG_DOUBLE_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_complex.h" #include "gsl_check_range.h" #include "gsl_vector_complex_long_double.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size1; size_t size2; size_t tda; long double * data; gsl_block_complex_long_double * block; int owner; } gsl_matrix_complex_long_double ; typedef struct { gsl_matrix_complex_long_double matrix; } _gsl_matrix_complex_long_double_view; typedef _gsl_matrix_complex_long_double_view gsl_matrix_complex_long_double_view; typedef struct { gsl_matrix_complex_long_double matrix; } _gsl_matrix_complex_long_double_const_view; typedef const _gsl_matrix_complex_long_double_const_view gsl_matrix_complex_long_double_const_view; /* Allocation */ gsl_matrix_complex_long_double * gsl_matrix_complex_long_double_alloc (const size_t n1, const size_t n2); gsl_matrix_complex_long_double * gsl_matrix_complex_long_double_calloc (const size_t n1, const size_t n2); gsl_matrix_complex_long_double * gsl_matrix_complex_long_double_alloc_from_block (gsl_block_complex_long_double * b, const size_t offset, const size_t n1, const size_t n2, const size_t d2); gsl_matrix_complex_long_double * gsl_matrix_complex_long_double_alloc_from_matrix (gsl_matrix_complex_long_double * b, const size_t k1, const size_t k2, const size_t n1, const size_t n2); gsl_vector_complex_long_double * gsl_vector_complex_long_double_alloc_row_from_matrix (gsl_matrix_complex_long_double * m, const size_t i); gsl_vector_complex_long_double * gsl_vector_complex_long_double_alloc_col_from_matrix (gsl_matrix_complex_long_double * m, const size_t j); void gsl_matrix_complex_long_double_free (gsl_matrix_complex_long_double * m); /* Views */ _gsl_matrix_complex_long_double_view gsl_matrix_complex_long_double_submatrix (gsl_matrix_complex_long_double * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_complex_long_double_view gsl_matrix_complex_long_double_row (gsl_matrix_complex_long_double * m, const size_t i); _gsl_vector_complex_long_double_view gsl_matrix_complex_long_double_column (gsl_matrix_complex_long_double * m, const size_t j); _gsl_vector_complex_long_double_view gsl_matrix_complex_long_double_diagonal (gsl_matrix_complex_long_double * m); _gsl_vector_complex_long_double_view gsl_matrix_complex_long_double_subdiagonal (gsl_matrix_complex_long_double * m, const size_t k); _gsl_vector_complex_long_double_view gsl_matrix_complex_long_double_superdiagonal (gsl_matrix_complex_long_double * m, const size_t k); _gsl_vector_complex_long_double_view gsl_matrix_complex_long_double_subrow (gsl_matrix_complex_long_double * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_complex_long_double_view gsl_matrix_complex_long_double_subcolumn (gsl_matrix_complex_long_double * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_complex_long_double_view gsl_matrix_complex_long_double_view_array (long double * base, const size_t n1, const size_t n2); _gsl_matrix_complex_long_double_view gsl_matrix_complex_long_double_view_array_with_tda (long double * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_complex_long_double_view gsl_matrix_complex_long_double_view_vector (gsl_vector_complex_long_double * v, const size_t n1, const size_t n2); _gsl_matrix_complex_long_double_view gsl_matrix_complex_long_double_view_vector_with_tda (gsl_vector_complex_long_double * v, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_complex_long_double_const_view gsl_matrix_complex_long_double_const_submatrix (const gsl_matrix_complex_long_double * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_complex_long_double_const_view gsl_matrix_complex_long_double_const_row (const gsl_matrix_complex_long_double * m, const size_t i); _gsl_vector_complex_long_double_const_view gsl_matrix_complex_long_double_const_column (const gsl_matrix_complex_long_double * m, const size_t j); _gsl_vector_complex_long_double_const_view gsl_matrix_complex_long_double_const_diagonal (const gsl_matrix_complex_long_double * m); _gsl_vector_complex_long_double_const_view gsl_matrix_complex_long_double_const_subdiagonal (const gsl_matrix_complex_long_double * m, const size_t k); _gsl_vector_complex_long_double_const_view gsl_matrix_complex_long_double_const_superdiagonal (const gsl_matrix_complex_long_double * m, const size_t k); _gsl_vector_complex_long_double_const_view gsl_matrix_complex_long_double_const_subrow (const gsl_matrix_complex_long_double * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_complex_long_double_const_view gsl_matrix_complex_long_double_const_subcolumn (const gsl_matrix_complex_long_double * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_complex_long_double_const_view gsl_matrix_complex_long_double_const_view_array (const long double * base, const size_t n1, const size_t n2); _gsl_matrix_complex_long_double_const_view gsl_matrix_complex_long_double_const_view_array_with_tda (const long double * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_complex_long_double_const_view gsl_matrix_complex_long_double_const_view_vector (const gsl_vector_complex_long_double * v, const size_t n1, const size_t n2); _gsl_matrix_complex_long_double_const_view gsl_matrix_complex_long_double_const_view_vector_with_tda (const gsl_vector_complex_long_double * v, const size_t n1, const size_t n2, const size_t tda); /* Operations */ gsl_complex_long_double gsl_matrix_complex_long_double_get(const gsl_matrix_complex_long_double * m, const size_t i, const size_t j); void gsl_matrix_complex_long_double_set(gsl_matrix_complex_long_double * m, const size_t i, const size_t j, const gsl_complex_long_double x); gsl_complex_long_double * gsl_matrix_complex_long_double_ptr(gsl_matrix_complex_long_double * m, const size_t i, const size_t j); const gsl_complex_long_double * gsl_matrix_complex_long_double_const_ptr(const gsl_matrix_complex_long_double * m, const size_t i, const size_t j); void gsl_matrix_complex_long_double_set_zero (gsl_matrix_complex_long_double * m); void gsl_matrix_complex_long_double_set_identity (gsl_matrix_complex_long_double * m); void gsl_matrix_complex_long_double_set_all (gsl_matrix_complex_long_double * m, gsl_complex_long_double x); int gsl_matrix_complex_long_double_fread (FILE * stream, gsl_matrix_complex_long_double * m) ; int gsl_matrix_complex_long_double_fwrite (FILE * stream, const gsl_matrix_complex_long_double * m) ; int gsl_matrix_complex_long_double_fscanf (FILE * stream, gsl_matrix_complex_long_double * m); int gsl_matrix_complex_long_double_fprintf (FILE * stream, const gsl_matrix_complex_long_double * m, const char * format); int gsl_matrix_complex_long_double_memcpy(gsl_matrix_complex_long_double * dest, const gsl_matrix_complex_long_double * src); int gsl_matrix_complex_long_double_swap(gsl_matrix_complex_long_double * m1, gsl_matrix_complex_long_double * m2); int gsl_matrix_complex_long_double_swap_rows(gsl_matrix_complex_long_double * m, const size_t i, const size_t j); int gsl_matrix_complex_long_double_swap_columns(gsl_matrix_complex_long_double * m, const size_t i, const size_t j); int gsl_matrix_complex_long_double_swap_rowcol(gsl_matrix_complex_long_double * m, const size_t i, const size_t j); int gsl_matrix_complex_long_double_transpose (gsl_matrix_complex_long_double * m); int gsl_matrix_complex_long_double_transpose_memcpy (gsl_matrix_complex_long_double * dest, const gsl_matrix_complex_long_double * src); int gsl_matrix_complex_long_double_isnull (const gsl_matrix_complex_long_double * m); int gsl_matrix_complex_long_double_ispos (const gsl_matrix_complex_long_double * m); int gsl_matrix_complex_long_double_isneg (const gsl_matrix_complex_long_double * m); int gsl_matrix_complex_long_double_isnonneg (const gsl_matrix_complex_long_double * m); int gsl_matrix_complex_long_double_add (gsl_matrix_complex_long_double * a, const gsl_matrix_complex_long_double * b); int gsl_matrix_complex_long_double_sub (gsl_matrix_complex_long_double * a, const gsl_matrix_complex_long_double * b); int gsl_matrix_complex_long_double_mul_elements (gsl_matrix_complex_long_double * a, const gsl_matrix_complex_long_double * b); int gsl_matrix_complex_long_double_div_elements (gsl_matrix_complex_long_double * a, const gsl_matrix_complex_long_double * b); int gsl_matrix_complex_long_double_scale (gsl_matrix_complex_long_double * a, const gsl_complex_long_double x); int gsl_matrix_complex_long_double_add_constant (gsl_matrix_complex_long_double * a, const gsl_complex_long_double x); int gsl_matrix_complex_long_double_add_diagonal (gsl_matrix_complex_long_double * a, const gsl_complex_long_double x); /***********************************************************************/ /* The functions below are obsolete */ /***********************************************************************/ int gsl_matrix_complex_long_double_get_row(gsl_vector_complex_long_double * v, const gsl_matrix_complex_long_double * m, const size_t i); int gsl_matrix_complex_long_double_get_col(gsl_vector_complex_long_double * v, const gsl_matrix_complex_long_double * m, const size_t j); int gsl_matrix_complex_long_double_set_row(gsl_matrix_complex_long_double * m, const size_t i, const gsl_vector_complex_long_double * v); int gsl_matrix_complex_long_double_set_col(gsl_matrix_complex_long_double * m, const size_t j, const gsl_vector_complex_long_double * v); #ifdef HAVE_INLINE extern inline gsl_complex_long_double gsl_matrix_complex_long_double_get(const gsl_matrix_complex_long_double * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK gsl_complex_long_double zero = {{0,0}}; if (i >= m->size1) { GSL_ERROR_VAL("first index out of range", GSL_EINVAL, zero) ; } else if (j >= m->size2) { GSL_ERROR_VAL("second index out of range", GSL_EINVAL, zero) ; } #endif return *(gsl_complex_long_double *)(m->data + 2*(i * m->tda + j)) ; } extern inline void gsl_matrix_complex_long_double_set(gsl_matrix_complex_long_double * m, const size_t i, const size_t j, const gsl_complex_long_double x) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; } #endif *(gsl_complex_long_double *)(m->data + 2*(i * m->tda + j)) = x ; } extern inline gsl_complex_long_double * gsl_matrix_complex_long_double_ptr(gsl_matrix_complex_long_double * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (gsl_complex_long_double *)(m->data + 2*(i * m->tda + j)) ; } extern inline const gsl_complex_long_double * gsl_matrix_complex_long_double_const_ptr(const gsl_matrix_complex_long_double * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (const gsl_complex_long_double *)(m->data + 2*(i * m->tda + j)) ; } #endif /* HAVE_INLINE */ __END_DECLS #endif /* __GSL_MATRIX_COMPLEX_LONG_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_matrix_double.h000066400000000000000000000246131261542461700212110ustar00rootroot00000000000000/* matrix/gsl_matrix_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_MATRIX_DOUBLE_H__ #define __GSL_MATRIX_DOUBLE_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_check_range.h" #include "gsl_vector_double.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size1; size_t size2; size_t tda; double * data; gsl_block * block; int owner; } gsl_matrix; typedef struct { gsl_matrix matrix; } _gsl_matrix_view; typedef _gsl_matrix_view gsl_matrix_view; typedef struct { gsl_matrix matrix; } _gsl_matrix_const_view; typedef const _gsl_matrix_const_view gsl_matrix_const_view; /* Allocation */ gsl_matrix * gsl_matrix_alloc (const size_t n1, const size_t n2); gsl_matrix * gsl_matrix_calloc (const size_t n1, const size_t n2); gsl_matrix * gsl_matrix_alloc_from_block (gsl_block * b, const size_t offset, const size_t n1, const size_t n2, const size_t d2); gsl_matrix * gsl_matrix_alloc_from_matrix (gsl_matrix * m, const size_t k1, const size_t k2, const size_t n1, const size_t n2); gsl_vector * gsl_vector_alloc_row_from_matrix (gsl_matrix * m, const size_t i); gsl_vector * gsl_vector_alloc_col_from_matrix (gsl_matrix * m, const size_t j); void gsl_matrix_free (gsl_matrix * m); /* Views */ _gsl_matrix_view gsl_matrix_submatrix (gsl_matrix * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_view gsl_matrix_row (gsl_matrix * m, const size_t i); _gsl_vector_view gsl_matrix_column (gsl_matrix * m, const size_t j); _gsl_vector_view gsl_matrix_diagonal (gsl_matrix * m); _gsl_vector_view gsl_matrix_subdiagonal (gsl_matrix * m, const size_t k); _gsl_vector_view gsl_matrix_superdiagonal (gsl_matrix * m, const size_t k); _gsl_vector_view gsl_matrix_subrow (gsl_matrix * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_view gsl_matrix_subcolumn (gsl_matrix * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_view gsl_matrix_view_array (double * base, const size_t n1, const size_t n2); _gsl_matrix_view gsl_matrix_view_array_with_tda (double * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_view gsl_matrix_view_vector (gsl_vector * v, const size_t n1, const size_t n2); _gsl_matrix_view gsl_matrix_view_vector_with_tda (gsl_vector * v, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_const_view gsl_matrix_const_submatrix (const gsl_matrix * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_const_view gsl_matrix_const_row (const gsl_matrix * m, const size_t i); _gsl_vector_const_view gsl_matrix_const_column (const gsl_matrix * m, const size_t j); _gsl_vector_const_view gsl_matrix_const_diagonal (const gsl_matrix * m); _gsl_vector_const_view gsl_matrix_const_subdiagonal (const gsl_matrix * m, const size_t k); _gsl_vector_const_view gsl_matrix_const_superdiagonal (const gsl_matrix * m, const size_t k); _gsl_vector_const_view gsl_matrix_const_subrow (const gsl_matrix * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_const_view gsl_matrix_const_subcolumn (const gsl_matrix * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_const_view gsl_matrix_const_view_array (const double * base, const size_t n1, const size_t n2); _gsl_matrix_const_view gsl_matrix_const_view_array_with_tda (const double * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_const_view gsl_matrix_const_view_vector (const gsl_vector * v, const size_t n1, const size_t n2); _gsl_matrix_const_view gsl_matrix_const_view_vector_with_tda (const gsl_vector * v, const size_t n1, const size_t n2, const size_t tda); /* Operations */ double gsl_matrix_get(const gsl_matrix * m, const size_t i, const size_t j); void gsl_matrix_set(gsl_matrix * m, const size_t i, const size_t j, const double x); double * gsl_matrix_ptr(gsl_matrix * m, const size_t i, const size_t j); const double * gsl_matrix_const_ptr(const gsl_matrix * m, const size_t i, const size_t j); void gsl_matrix_set_zero (gsl_matrix * m); void gsl_matrix_set_identity (gsl_matrix * m); void gsl_matrix_set_all (gsl_matrix * m, double x); int gsl_matrix_fread (FILE * stream, gsl_matrix * m) ; int gsl_matrix_fwrite (FILE * stream, const gsl_matrix * m) ; int gsl_matrix_fscanf (FILE * stream, gsl_matrix * m); int gsl_matrix_fprintf (FILE * stream, const gsl_matrix * m, const char * format); int gsl_matrix_memcpy(gsl_matrix * dest, const gsl_matrix * src); int gsl_matrix_swap(gsl_matrix * m1, gsl_matrix * m2); int gsl_matrix_swap_rows(gsl_matrix * m, const size_t i, const size_t j); int gsl_matrix_swap_columns(gsl_matrix * m, const size_t i, const size_t j); int gsl_matrix_swap_rowcol(gsl_matrix * m, const size_t i, const size_t j); int gsl_matrix_transpose (gsl_matrix * m); int gsl_matrix_transpose_memcpy (gsl_matrix * dest, const gsl_matrix * src); double gsl_matrix_max (const gsl_matrix * m); double gsl_matrix_min (const gsl_matrix * m); void gsl_matrix_minmax (const gsl_matrix * m, double * min_out, double * max_out); void gsl_matrix_max_index (const gsl_matrix * m, size_t * imax, size_t *jmax); void gsl_matrix_min_index (const gsl_matrix * m, size_t * imin, size_t *jmin); void gsl_matrix_minmax_index (const gsl_matrix * m, size_t * imin, size_t * jmin, size_t * imax, size_t * jmax); int gsl_matrix_isnull (const gsl_matrix * m); int gsl_matrix_ispos (const gsl_matrix * m); int gsl_matrix_isneg (const gsl_matrix * m); int gsl_matrix_isnonneg (const gsl_matrix * m); int gsl_matrix_add (gsl_matrix * a, const gsl_matrix * b); int gsl_matrix_sub (gsl_matrix * a, const gsl_matrix * b); int gsl_matrix_mul_elements (gsl_matrix * a, const gsl_matrix * b); int gsl_matrix_div_elements (gsl_matrix * a, const gsl_matrix * b); int gsl_matrix_scale (gsl_matrix * a, const double x); int gsl_matrix_add_constant (gsl_matrix * a, const double x); int gsl_matrix_add_diagonal (gsl_matrix * a, const double x); /***********************************************************************/ /* The functions below are obsolete */ /***********************************************************************/ int gsl_matrix_get_row(gsl_vector * v, const gsl_matrix * m, const size_t i); int gsl_matrix_get_col(gsl_vector * v, const gsl_matrix * m, const size_t j); int gsl_matrix_set_row(gsl_matrix * m, const size_t i, const gsl_vector * v); int gsl_matrix_set_col(gsl_matrix * m, const size_t j, const gsl_vector * v); /* inline functions if you are using GCC */ #ifdef HAVE_INLINE extern inline double gsl_matrix_get(const gsl_matrix * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_VAL("first index out of range", GSL_EINVAL, 0) ; } else if (j >= m->size2) { GSL_ERROR_VAL("second index out of range", GSL_EINVAL, 0) ; } #endif return m->data[i * m->tda + j] ; } extern inline void gsl_matrix_set(gsl_matrix * m, const size_t i, const size_t j, const double x) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; } #endif m->data[i * m->tda + j] = x ; } extern inline double * gsl_matrix_ptr(gsl_matrix * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (double *) (m->data + (i * m->tda + j)) ; } extern inline const double * gsl_matrix_const_ptr(const gsl_matrix * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (const double *) (m->data + (i * m->tda + j)) ; } #endif __END_DECLS #endif /* __GSL_MATRIX_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_matrix_float.h000066400000000000000000000267701261542461700210520ustar00rootroot00000000000000/* matrix/gsl_matrix_float.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_MATRIX_FLOAT_H__ #define __GSL_MATRIX_FLOAT_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_check_range.h" #include "gsl_vector_float.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size1; size_t size2; size_t tda; float * data; gsl_block_float * block; int owner; } gsl_matrix_float; typedef struct { gsl_matrix_float matrix; } _gsl_matrix_float_view; typedef _gsl_matrix_float_view gsl_matrix_float_view; typedef struct { gsl_matrix_float matrix; } _gsl_matrix_float_const_view; typedef const _gsl_matrix_float_const_view gsl_matrix_float_const_view; /* Allocation */ gsl_matrix_float * gsl_matrix_float_alloc (const size_t n1, const size_t n2); gsl_matrix_float * gsl_matrix_float_calloc (const size_t n1, const size_t n2); gsl_matrix_float * gsl_matrix_float_alloc_from_block (gsl_block_float * b, const size_t offset, const size_t n1, const size_t n2, const size_t d2); gsl_matrix_float * gsl_matrix_float_alloc_from_matrix (gsl_matrix_float * m, const size_t k1, const size_t k2, const size_t n1, const size_t n2); gsl_vector_float * gsl_vector_float_alloc_row_from_matrix (gsl_matrix_float * m, const size_t i); gsl_vector_float * gsl_vector_float_alloc_col_from_matrix (gsl_matrix_float * m, const size_t j); void gsl_matrix_float_free (gsl_matrix_float * m); /* Views */ _gsl_matrix_float_view gsl_matrix_float_submatrix (gsl_matrix_float * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_float_view gsl_matrix_float_row (gsl_matrix_float * m, const size_t i); _gsl_vector_float_view gsl_matrix_float_column (gsl_matrix_float * m, const size_t j); _gsl_vector_float_view gsl_matrix_float_diagonal (gsl_matrix_float * m); _gsl_vector_float_view gsl_matrix_float_subdiagonal (gsl_matrix_float * m, const size_t k); _gsl_vector_float_view gsl_matrix_float_superdiagonal (gsl_matrix_float * m, const size_t k); _gsl_vector_float_view gsl_matrix_float_subrow (gsl_matrix_float * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_float_view gsl_matrix_float_subcolumn (gsl_matrix_float * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_float_view gsl_matrix_float_view_array (float * base, const size_t n1, const size_t n2); _gsl_matrix_float_view gsl_matrix_float_view_array_with_tda (float * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_float_view gsl_matrix_float_view_vector (gsl_vector_float * v, const size_t n1, const size_t n2); _gsl_matrix_float_view gsl_matrix_float_view_vector_with_tda (gsl_vector_float * v, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_float_const_view gsl_matrix_float_const_submatrix (const gsl_matrix_float * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_float_const_view gsl_matrix_float_const_row (const gsl_matrix_float * m, const size_t i); _gsl_vector_float_const_view gsl_matrix_float_const_column (const gsl_matrix_float * m, const size_t j); _gsl_vector_float_const_view gsl_matrix_float_const_diagonal (const gsl_matrix_float * m); _gsl_vector_float_const_view gsl_matrix_float_const_subdiagonal (const gsl_matrix_float * m, const size_t k); _gsl_vector_float_const_view gsl_matrix_float_const_superdiagonal (const gsl_matrix_float * m, const size_t k); _gsl_vector_float_const_view gsl_matrix_float_const_subrow (const gsl_matrix_float * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_float_const_view gsl_matrix_float_const_subcolumn (const gsl_matrix_float * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_float_const_view gsl_matrix_float_const_view_array (const float * base, const size_t n1, const size_t n2); _gsl_matrix_float_const_view gsl_matrix_float_const_view_array_with_tda (const float * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_float_const_view gsl_matrix_float_const_view_vector (const gsl_vector_float * v, const size_t n1, const size_t n2); _gsl_matrix_float_const_view gsl_matrix_float_const_view_vector_with_tda (const gsl_vector_float * v, const size_t n1, const size_t n2, const size_t tda); /* Operations */ float gsl_matrix_float_get(const gsl_matrix_float * m, const size_t i, const size_t j); void gsl_matrix_float_set(gsl_matrix_float * m, const size_t i, const size_t j, const float x); float * gsl_matrix_float_ptr(gsl_matrix_float * m, const size_t i, const size_t j); const float * gsl_matrix_float_const_ptr(const gsl_matrix_float * m, const size_t i, const size_t j); void gsl_matrix_float_set_zero (gsl_matrix_float * m); void gsl_matrix_float_set_identity (gsl_matrix_float * m); void gsl_matrix_float_set_all (gsl_matrix_float * m, float x); int gsl_matrix_float_fread (FILE * stream, gsl_matrix_float * m) ; int gsl_matrix_float_fwrite (FILE * stream, const gsl_matrix_float * m) ; int gsl_matrix_float_fscanf (FILE * stream, gsl_matrix_float * m); int gsl_matrix_float_fprintf (FILE * stream, const gsl_matrix_float * m, const char * format); int gsl_matrix_float_memcpy(gsl_matrix_float * dest, const gsl_matrix_float * src); int gsl_matrix_float_swap(gsl_matrix_float * m1, gsl_matrix_float * m2); int gsl_matrix_float_swap_rows(gsl_matrix_float * m, const size_t i, const size_t j); int gsl_matrix_float_swap_columns(gsl_matrix_float * m, const size_t i, const size_t j); int gsl_matrix_float_swap_rowcol(gsl_matrix_float * m, const size_t i, const size_t j); int gsl_matrix_float_transpose (gsl_matrix_float * m); int gsl_matrix_float_transpose_memcpy (gsl_matrix_float * dest, const gsl_matrix_float * src); float gsl_matrix_float_max (const gsl_matrix_float * m); float gsl_matrix_float_min (const gsl_matrix_float * m); void gsl_matrix_float_minmax (const gsl_matrix_float * m, float * min_out, float * max_out); void gsl_matrix_float_max_index (const gsl_matrix_float * m, size_t * imax, size_t *jmax); void gsl_matrix_float_min_index (const gsl_matrix_float * m, size_t * imin, size_t *jmin); void gsl_matrix_float_minmax_index (const gsl_matrix_float * m, size_t * imin, size_t * jmin, size_t * imax, size_t * jmax); int gsl_matrix_float_isnull (const gsl_matrix_float * m); int gsl_matrix_float_ispos (const gsl_matrix_float * m); int gsl_matrix_float_isneg (const gsl_matrix_float * m); int gsl_matrix_float_isnonneg (const gsl_matrix_float * m); int gsl_matrix_float_add (gsl_matrix_float * a, const gsl_matrix_float * b); int gsl_matrix_float_sub (gsl_matrix_float * a, const gsl_matrix_float * b); int gsl_matrix_float_mul_elements (gsl_matrix_float * a, const gsl_matrix_float * b); int gsl_matrix_float_div_elements (gsl_matrix_float * a, const gsl_matrix_float * b); int gsl_matrix_float_scale (gsl_matrix_float * a, const double x); int gsl_matrix_float_add_constant (gsl_matrix_float * a, const double x); int gsl_matrix_float_add_diagonal (gsl_matrix_float * a, const double x); /***********************************************************************/ /* The functions below are obsolete */ /***********************************************************************/ int gsl_matrix_float_get_row(gsl_vector_float * v, const gsl_matrix_float * m, const size_t i); int gsl_matrix_float_get_col(gsl_vector_float * v, const gsl_matrix_float * m, const size_t j); int gsl_matrix_float_set_row(gsl_matrix_float * m, const size_t i, const gsl_vector_float * v); int gsl_matrix_float_set_col(gsl_matrix_float * m, const size_t j, const gsl_vector_float * v); /* inline functions if you are using GCC */ #ifdef HAVE_INLINE extern inline float gsl_matrix_float_get(const gsl_matrix_float * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_VAL("first index out of range", GSL_EINVAL, 0) ; } else if (j >= m->size2) { GSL_ERROR_VAL("second index out of range", GSL_EINVAL, 0) ; } #endif return m->data[i * m->tda + j] ; } extern inline void gsl_matrix_float_set(gsl_matrix_float * m, const size_t i, const size_t j, const float x) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; } #endif m->data[i * m->tda + j] = x ; } extern inline float * gsl_matrix_float_ptr(gsl_matrix_float * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (float *) (m->data + (i * m->tda + j)) ; } extern inline const float * gsl_matrix_float_const_ptr(const gsl_matrix_float * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (const float *) (m->data + (i * m->tda + j)) ; } #endif __END_DECLS #endif /* __GSL_MATRIX_FLOAT_H__ */ praat-6.0.04/external/gsl/gsl_matrix_int.h000066400000000000000000000261041261542461700205260ustar00rootroot00000000000000/* matrix/gsl_matrix_int.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_MATRIX_INT_H__ #define __GSL_MATRIX_INT_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_check_range.h" #include "gsl_vector_int.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size1; size_t size2; size_t tda; int * data; gsl_block_int * block; int owner; } gsl_matrix_int; typedef struct { gsl_matrix_int matrix; } _gsl_matrix_int_view; typedef _gsl_matrix_int_view gsl_matrix_int_view; typedef struct { gsl_matrix_int matrix; } _gsl_matrix_int_const_view; typedef const _gsl_matrix_int_const_view gsl_matrix_int_const_view; /* Allocation */ gsl_matrix_int * gsl_matrix_int_alloc (const size_t n1, const size_t n2); gsl_matrix_int * gsl_matrix_int_calloc (const size_t n1, const size_t n2); gsl_matrix_int * gsl_matrix_int_alloc_from_block (gsl_block_int * b, const size_t offset, const size_t n1, const size_t n2, const size_t d2); gsl_matrix_int * gsl_matrix_int_alloc_from_matrix (gsl_matrix_int * m, const size_t k1, const size_t k2, const size_t n1, const size_t n2); gsl_vector_int * gsl_vector_int_alloc_row_from_matrix (gsl_matrix_int * m, const size_t i); gsl_vector_int * gsl_vector_int_alloc_col_from_matrix (gsl_matrix_int * m, const size_t j); void gsl_matrix_int_free (gsl_matrix_int * m); /* Views */ _gsl_matrix_int_view gsl_matrix_int_submatrix (gsl_matrix_int * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_int_view gsl_matrix_int_row (gsl_matrix_int * m, const size_t i); _gsl_vector_int_view gsl_matrix_int_column (gsl_matrix_int * m, const size_t j); _gsl_vector_int_view gsl_matrix_int_diagonal (gsl_matrix_int * m); _gsl_vector_int_view gsl_matrix_int_subdiagonal (gsl_matrix_int * m, const size_t k); _gsl_vector_int_view gsl_matrix_int_superdiagonal (gsl_matrix_int * m, const size_t k); _gsl_vector_int_view gsl_matrix_int_subrow (gsl_matrix_int * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_int_view gsl_matrix_int_subcolumn (gsl_matrix_int * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_int_view gsl_matrix_int_view_array (int * base, const size_t n1, const size_t n2); _gsl_matrix_int_view gsl_matrix_int_view_array_with_tda (int * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_int_view gsl_matrix_int_view_vector (gsl_vector_int * v, const size_t n1, const size_t n2); _gsl_matrix_int_view gsl_matrix_int_view_vector_with_tda (gsl_vector_int * v, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_int_const_view gsl_matrix_int_const_submatrix (const gsl_matrix_int * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_int_const_view gsl_matrix_int_const_row (const gsl_matrix_int * m, const size_t i); _gsl_vector_int_const_view gsl_matrix_int_const_column (const gsl_matrix_int * m, const size_t j); _gsl_vector_int_const_view gsl_matrix_int_const_diagonal (const gsl_matrix_int * m); _gsl_vector_int_const_view gsl_matrix_int_const_subdiagonal (const gsl_matrix_int * m, const size_t k); _gsl_vector_int_const_view gsl_matrix_int_const_superdiagonal (const gsl_matrix_int * m, const size_t k); _gsl_vector_int_const_view gsl_matrix_int_const_subrow (const gsl_matrix_int * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_int_const_view gsl_matrix_int_const_subcolumn (const gsl_matrix_int * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_int_const_view gsl_matrix_int_const_view_array (const int * base, const size_t n1, const size_t n2); _gsl_matrix_int_const_view gsl_matrix_int_const_view_array_with_tda (const int * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_int_const_view gsl_matrix_int_const_view_vector (const gsl_vector_int * v, const size_t n1, const size_t n2); _gsl_matrix_int_const_view gsl_matrix_int_const_view_vector_with_tda (const gsl_vector_int * v, const size_t n1, const size_t n2, const size_t tda); /* Operations */ int gsl_matrix_int_get(const gsl_matrix_int * m, const size_t i, const size_t j); void gsl_matrix_int_set(gsl_matrix_int * m, const size_t i, const size_t j, const int x); int * gsl_matrix_int_ptr(gsl_matrix_int * m, const size_t i, const size_t j); const int * gsl_matrix_int_const_ptr(const gsl_matrix_int * m, const size_t i, const size_t j); void gsl_matrix_int_set_zero (gsl_matrix_int * m); void gsl_matrix_int_set_identity (gsl_matrix_int * m); void gsl_matrix_int_set_all (gsl_matrix_int * m, int x); int gsl_matrix_int_fread (FILE * stream, gsl_matrix_int * m) ; int gsl_matrix_int_fwrite (FILE * stream, const gsl_matrix_int * m) ; int gsl_matrix_int_fscanf (FILE * stream, gsl_matrix_int * m); int gsl_matrix_int_fprintf (FILE * stream, const gsl_matrix_int * m, const char * format); int gsl_matrix_int_memcpy(gsl_matrix_int * dest, const gsl_matrix_int * src); int gsl_matrix_int_swap(gsl_matrix_int * m1, gsl_matrix_int * m2); int gsl_matrix_int_swap_rows(gsl_matrix_int * m, const size_t i, const size_t j); int gsl_matrix_int_swap_columns(gsl_matrix_int * m, const size_t i, const size_t j); int gsl_matrix_int_swap_rowcol(gsl_matrix_int * m, const size_t i, const size_t j); int gsl_matrix_int_transpose (gsl_matrix_int * m); int gsl_matrix_int_transpose_memcpy (gsl_matrix_int * dest, const gsl_matrix_int * src); int gsl_matrix_int_max (const gsl_matrix_int * m); int gsl_matrix_int_min (const gsl_matrix_int * m); void gsl_matrix_int_minmax (const gsl_matrix_int * m, int * min_out, int * max_out); void gsl_matrix_int_max_index (const gsl_matrix_int * m, size_t * imax, size_t *jmax); void gsl_matrix_int_min_index (const gsl_matrix_int * m, size_t * imin, size_t *jmin); void gsl_matrix_int_minmax_index (const gsl_matrix_int * m, size_t * imin, size_t * jmin, size_t * imax, size_t * jmax); int gsl_matrix_int_isnull (const gsl_matrix_int * m); int gsl_matrix_int_ispos (const gsl_matrix_int * m); int gsl_matrix_int_isneg (const gsl_matrix_int * m); int gsl_matrix_int_isnonneg (const gsl_matrix_int * m); int gsl_matrix_int_add (gsl_matrix_int * a, const gsl_matrix_int * b); int gsl_matrix_int_sub (gsl_matrix_int * a, const gsl_matrix_int * b); int gsl_matrix_int_mul_elements (gsl_matrix_int * a, const gsl_matrix_int * b); int gsl_matrix_int_div_elements (gsl_matrix_int * a, const gsl_matrix_int * b); int gsl_matrix_int_scale (gsl_matrix_int * a, const double x); int gsl_matrix_int_add_constant (gsl_matrix_int * a, const double x); int gsl_matrix_int_add_diagonal (gsl_matrix_int * a, const double x); /***********************************************************************/ /* The functions below are obsolete */ /***********************************************************************/ int gsl_matrix_int_get_row(gsl_vector_int * v, const gsl_matrix_int * m, const size_t i); int gsl_matrix_int_get_col(gsl_vector_int * v, const gsl_matrix_int * m, const size_t j); int gsl_matrix_int_set_row(gsl_matrix_int * m, const size_t i, const gsl_vector_int * v); int gsl_matrix_int_set_col(gsl_matrix_int * m, const size_t j, const gsl_vector_int * v); /* inline functions if you are using GCC */ #ifdef HAVE_INLINE extern inline int gsl_matrix_int_get(const gsl_matrix_int * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_VAL("first index out of range", GSL_EINVAL, 0) ; } else if (j >= m->size2) { GSL_ERROR_VAL("second index out of range", GSL_EINVAL, 0) ; } #endif return m->data[i * m->tda + j] ; } extern inline void gsl_matrix_int_set(gsl_matrix_int * m, const size_t i, const size_t j, const int x) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; } #endif m->data[i * m->tda + j] = x ; } extern inline int * gsl_matrix_int_ptr(gsl_matrix_int * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (int *) (m->data + (i * m->tda + j)) ; } extern inline const int * gsl_matrix_int_const_ptr(const gsl_matrix_int * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (const int *) (m->data + (i * m->tda + j)) ; } #endif __END_DECLS #endif /* __GSL_MATRIX_INT_H__ */ praat-6.0.04/external/gsl/gsl_matrix_long.h000066400000000000000000000264361261542461700207030ustar00rootroot00000000000000/* matrix/gsl_matrix_long.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_MATRIX_LONG_H__ #define __GSL_MATRIX_LONG_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_check_range.h" #include "gsl_vector_long.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size1; size_t size2; size_t tda; long * data; gsl_block_long * block; int owner; } gsl_matrix_long; typedef struct { gsl_matrix_long matrix; } _gsl_matrix_long_view; typedef _gsl_matrix_long_view gsl_matrix_long_view; typedef struct { gsl_matrix_long matrix; } _gsl_matrix_long_const_view; typedef const _gsl_matrix_long_const_view gsl_matrix_long_const_view; /* Allocation */ gsl_matrix_long * gsl_matrix_long_alloc (const size_t n1, const size_t n2); gsl_matrix_long * gsl_matrix_long_calloc (const size_t n1, const size_t n2); gsl_matrix_long * gsl_matrix_long_alloc_from_block (gsl_block_long * b, const size_t offset, const size_t n1, const size_t n2, const size_t d2); gsl_matrix_long * gsl_matrix_long_alloc_from_matrix (gsl_matrix_long * m, const size_t k1, const size_t k2, const size_t n1, const size_t n2); gsl_vector_long * gsl_vector_long_alloc_row_from_matrix (gsl_matrix_long * m, const size_t i); gsl_vector_long * gsl_vector_long_alloc_col_from_matrix (gsl_matrix_long * m, const size_t j); void gsl_matrix_long_free (gsl_matrix_long * m); /* Views */ _gsl_matrix_long_view gsl_matrix_long_submatrix (gsl_matrix_long * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_long_view gsl_matrix_long_row (gsl_matrix_long * m, const size_t i); _gsl_vector_long_view gsl_matrix_long_column (gsl_matrix_long * m, const size_t j); _gsl_vector_long_view gsl_matrix_long_diagonal (gsl_matrix_long * m); _gsl_vector_long_view gsl_matrix_long_subdiagonal (gsl_matrix_long * m, const size_t k); _gsl_vector_long_view gsl_matrix_long_superdiagonal (gsl_matrix_long * m, const size_t k); _gsl_vector_long_view gsl_matrix_long_subrow (gsl_matrix_long * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_long_view gsl_matrix_long_subcolumn (gsl_matrix_long * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_long_view gsl_matrix_long_view_array (long * base, const size_t n1, const size_t n2); _gsl_matrix_long_view gsl_matrix_long_view_array_with_tda (long * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_long_view gsl_matrix_long_view_vector (gsl_vector_long * v, const size_t n1, const size_t n2); _gsl_matrix_long_view gsl_matrix_long_view_vector_with_tda (gsl_vector_long * v, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_long_const_view gsl_matrix_long_const_submatrix (const gsl_matrix_long * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_long_const_view gsl_matrix_long_const_row (const gsl_matrix_long * m, const size_t i); _gsl_vector_long_const_view gsl_matrix_long_const_column (const gsl_matrix_long * m, const size_t j); _gsl_vector_long_const_view gsl_matrix_long_const_diagonal (const gsl_matrix_long * m); _gsl_vector_long_const_view gsl_matrix_long_const_subdiagonal (const gsl_matrix_long * m, const size_t k); _gsl_vector_long_const_view gsl_matrix_long_const_superdiagonal (const gsl_matrix_long * m, const size_t k); _gsl_vector_long_const_view gsl_matrix_long_const_subrow (const gsl_matrix_long * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_long_const_view gsl_matrix_long_const_subcolumn (const gsl_matrix_long * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_long_const_view gsl_matrix_long_const_view_array (const long * base, const size_t n1, const size_t n2); _gsl_matrix_long_const_view gsl_matrix_long_const_view_array_with_tda (const long * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_long_const_view gsl_matrix_long_const_view_vector (const gsl_vector_long * v, const size_t n1, const size_t n2); _gsl_matrix_long_const_view gsl_matrix_long_const_view_vector_with_tda (const gsl_vector_long * v, const size_t n1, const size_t n2, const size_t tda); /* Operations */ long gsl_matrix_long_get(const gsl_matrix_long * m, const size_t i, const size_t j); void gsl_matrix_long_set(gsl_matrix_long * m, const size_t i, const size_t j, const long x); long * gsl_matrix_long_ptr(gsl_matrix_long * m, const size_t i, const size_t j); const long * gsl_matrix_long_const_ptr(const gsl_matrix_long * m, const size_t i, const size_t j); void gsl_matrix_long_set_zero (gsl_matrix_long * m); void gsl_matrix_long_set_identity (gsl_matrix_long * m); void gsl_matrix_long_set_all (gsl_matrix_long * m, long x); int gsl_matrix_long_fread (FILE * stream, gsl_matrix_long * m) ; int gsl_matrix_long_fwrite (FILE * stream, const gsl_matrix_long * m) ; int gsl_matrix_long_fscanf (FILE * stream, gsl_matrix_long * m); int gsl_matrix_long_fprintf (FILE * stream, const gsl_matrix_long * m, const char * format); int gsl_matrix_long_memcpy(gsl_matrix_long * dest, const gsl_matrix_long * src); int gsl_matrix_long_swap(gsl_matrix_long * m1, gsl_matrix_long * m2); int gsl_matrix_long_swap_rows(gsl_matrix_long * m, const size_t i, const size_t j); int gsl_matrix_long_swap_columns(gsl_matrix_long * m, const size_t i, const size_t j); int gsl_matrix_long_swap_rowcol(gsl_matrix_long * m, const size_t i, const size_t j); int gsl_matrix_long_transpose (gsl_matrix_long * m); int gsl_matrix_long_transpose_memcpy (gsl_matrix_long * dest, const gsl_matrix_long * src); long gsl_matrix_long_max (const gsl_matrix_long * m); long gsl_matrix_long_min (const gsl_matrix_long * m); void gsl_matrix_long_minmax (const gsl_matrix_long * m, long * min_out, long * max_out); void gsl_matrix_long_max_index (const gsl_matrix_long * m, size_t * imax, size_t *jmax); void gsl_matrix_long_min_index (const gsl_matrix_long * m, size_t * imin, size_t *jmin); void gsl_matrix_long_minmax_index (const gsl_matrix_long * m, size_t * imin, size_t * jmin, size_t * imax, size_t * jmax); int gsl_matrix_long_isnull (const gsl_matrix_long * m); int gsl_matrix_long_ispos (const gsl_matrix_long * m); int gsl_matrix_long_isneg (const gsl_matrix_long * m); int gsl_matrix_long_isnonneg (const gsl_matrix_long * m); int gsl_matrix_long_add (gsl_matrix_long * a, const gsl_matrix_long * b); int gsl_matrix_long_sub (gsl_matrix_long * a, const gsl_matrix_long * b); int gsl_matrix_long_mul_elements (gsl_matrix_long * a, const gsl_matrix_long * b); int gsl_matrix_long_div_elements (gsl_matrix_long * a, const gsl_matrix_long * b); int gsl_matrix_long_scale (gsl_matrix_long * a, const double x); int gsl_matrix_long_add_constant (gsl_matrix_long * a, const double x); int gsl_matrix_long_add_diagonal (gsl_matrix_long * a, const double x); /***********************************************************************/ /* The functions below are obsolete */ /***********************************************************************/ int gsl_matrix_long_get_row(gsl_vector_long * v, const gsl_matrix_long * m, const size_t i); int gsl_matrix_long_get_col(gsl_vector_long * v, const gsl_matrix_long * m, const size_t j); int gsl_matrix_long_set_row(gsl_matrix_long * m, const size_t i, const gsl_vector_long * v); int gsl_matrix_long_set_col(gsl_matrix_long * m, const size_t j, const gsl_vector_long * v); /* inline functions if you are using GCC */ #ifdef HAVE_INLINE extern inline long gsl_matrix_long_get(const gsl_matrix_long * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_VAL("first index out of range", GSL_EINVAL, 0) ; } else if (j >= m->size2) { GSL_ERROR_VAL("second index out of range", GSL_EINVAL, 0) ; } #endif return m->data[i * m->tda + j] ; } extern inline void gsl_matrix_long_set(gsl_matrix_long * m, const size_t i, const size_t j, const long x) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; } #endif m->data[i * m->tda + j] = x ; } extern inline long * gsl_matrix_long_ptr(gsl_matrix_long * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (long *) (m->data + (i * m->tda + j)) ; } extern inline const long * gsl_matrix_long_const_ptr(const gsl_matrix_long * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (const long *) (m->data + (i * m->tda + j)) ; } #endif __END_DECLS #endif /* __GSL_MATRIX_LONG_H__ */ praat-6.0.04/external/gsl/gsl_matrix_long_double.h000066400000000000000000000314241261542461700222260ustar00rootroot00000000000000/* matrix/gsl_matrix_long_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_MATRIX_LONG_DOUBLE_H__ #define __GSL_MATRIX_LONG_DOUBLE_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_check_range.h" #include "gsl_vector_long_double.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size1; size_t size2; size_t tda; long double * data; gsl_block_long_double * block; int owner; } gsl_matrix_long_double; typedef struct { gsl_matrix_long_double matrix; } _gsl_matrix_long_double_view; typedef _gsl_matrix_long_double_view gsl_matrix_long_double_view; typedef struct { gsl_matrix_long_double matrix; } _gsl_matrix_long_double_const_view; typedef const _gsl_matrix_long_double_const_view gsl_matrix_long_double_const_view; /* Allocation */ gsl_matrix_long_double * gsl_matrix_long_double_alloc (const size_t n1, const size_t n2); gsl_matrix_long_double * gsl_matrix_long_double_calloc (const size_t n1, const size_t n2); gsl_matrix_long_double * gsl_matrix_long_double_alloc_from_block (gsl_block_long_double * b, const size_t offset, const size_t n1, const size_t n2, const size_t d2); gsl_matrix_long_double * gsl_matrix_long_double_alloc_from_matrix (gsl_matrix_long_double * m, const size_t k1, const size_t k2, const size_t n1, const size_t n2); gsl_vector_long_double * gsl_vector_long_double_alloc_row_from_matrix (gsl_matrix_long_double * m, const size_t i); gsl_vector_long_double * gsl_vector_long_double_alloc_col_from_matrix (gsl_matrix_long_double * m, const size_t j); void gsl_matrix_long_double_free (gsl_matrix_long_double * m); /* Views */ _gsl_matrix_long_double_view gsl_matrix_long_double_submatrix (gsl_matrix_long_double * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_long_double_view gsl_matrix_long_double_row (gsl_matrix_long_double * m, const size_t i); _gsl_vector_long_double_view gsl_matrix_long_double_column (gsl_matrix_long_double * m, const size_t j); _gsl_vector_long_double_view gsl_matrix_long_double_diagonal (gsl_matrix_long_double * m); _gsl_vector_long_double_view gsl_matrix_long_double_subdiagonal (gsl_matrix_long_double * m, const size_t k); _gsl_vector_long_double_view gsl_matrix_long_double_superdiagonal (gsl_matrix_long_double * m, const size_t k); _gsl_vector_long_double_view gsl_matrix_long_double_subrow (gsl_matrix_long_double * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_long_double_view gsl_matrix_long_double_subcolumn (gsl_matrix_long_double * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_long_double_view gsl_matrix_long_double_view_array (long double * base, const size_t n1, const size_t n2); _gsl_matrix_long_double_view gsl_matrix_long_double_view_array_with_tda (long double * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_long_double_view gsl_matrix_long_double_view_vector (gsl_vector_long_double * v, const size_t n1, const size_t n2); _gsl_matrix_long_double_view gsl_matrix_long_double_view_vector_with_tda (gsl_vector_long_double * v, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_long_double_const_view gsl_matrix_long_double_const_submatrix (const gsl_matrix_long_double * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_long_double_const_view gsl_matrix_long_double_const_row (const gsl_matrix_long_double * m, const size_t i); _gsl_vector_long_double_const_view gsl_matrix_long_double_const_column (const gsl_matrix_long_double * m, const size_t j); _gsl_vector_long_double_const_view gsl_matrix_long_double_const_diagonal (const gsl_matrix_long_double * m); _gsl_vector_long_double_const_view gsl_matrix_long_double_const_subdiagonal (const gsl_matrix_long_double * m, const size_t k); _gsl_vector_long_double_const_view gsl_matrix_long_double_const_superdiagonal (const gsl_matrix_long_double * m, const size_t k); _gsl_vector_long_double_const_view gsl_matrix_long_double_const_subrow (const gsl_matrix_long_double * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_long_double_const_view gsl_matrix_long_double_const_subcolumn (const gsl_matrix_long_double * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_long_double_const_view gsl_matrix_long_double_const_view_array (const long double * base, const size_t n1, const size_t n2); _gsl_matrix_long_double_const_view gsl_matrix_long_double_const_view_array_with_tda (const long double * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_long_double_const_view gsl_matrix_long_double_const_view_vector (const gsl_vector_long_double * v, const size_t n1, const size_t n2); _gsl_matrix_long_double_const_view gsl_matrix_long_double_const_view_vector_with_tda (const gsl_vector_long_double * v, const size_t n1, const size_t n2, const size_t tda); /* Operations */ long double gsl_matrix_long_double_get(const gsl_matrix_long_double * m, const size_t i, const size_t j); void gsl_matrix_long_double_set(gsl_matrix_long_double * m, const size_t i, const size_t j, const long double x); long double * gsl_matrix_long_double_ptr(gsl_matrix_long_double * m, const size_t i, const size_t j); const long double * gsl_matrix_long_double_const_ptr(const gsl_matrix_long_double * m, const size_t i, const size_t j); void gsl_matrix_long_double_set_zero (gsl_matrix_long_double * m); void gsl_matrix_long_double_set_identity (gsl_matrix_long_double * m); void gsl_matrix_long_double_set_all (gsl_matrix_long_double * m, long double x); int gsl_matrix_long_double_fread (FILE * stream, gsl_matrix_long_double * m) ; int gsl_matrix_long_double_fwrite (FILE * stream, const gsl_matrix_long_double * m) ; int gsl_matrix_long_double_fscanf (FILE * stream, gsl_matrix_long_double * m); int gsl_matrix_long_double_fprintf (FILE * stream, const gsl_matrix_long_double * m, const char * format); int gsl_matrix_long_double_memcpy(gsl_matrix_long_double * dest, const gsl_matrix_long_double * src); int gsl_matrix_long_double_swap(gsl_matrix_long_double * m1, gsl_matrix_long_double * m2); int gsl_matrix_long_double_swap_rows(gsl_matrix_long_double * m, const size_t i, const size_t j); int gsl_matrix_long_double_swap_columns(gsl_matrix_long_double * m, const size_t i, const size_t j); int gsl_matrix_long_double_swap_rowcol(gsl_matrix_long_double * m, const size_t i, const size_t j); int gsl_matrix_long_double_transpose (gsl_matrix_long_double * m); int gsl_matrix_long_double_transpose_memcpy (gsl_matrix_long_double * dest, const gsl_matrix_long_double * src); long double gsl_matrix_long_double_max (const gsl_matrix_long_double * m); long double gsl_matrix_long_double_min (const gsl_matrix_long_double * m); void gsl_matrix_long_double_minmax (const gsl_matrix_long_double * m, long double * min_out, long double * max_out); void gsl_matrix_long_double_max_index (const gsl_matrix_long_double * m, size_t * imax, size_t *jmax); void gsl_matrix_long_double_min_index (const gsl_matrix_long_double * m, size_t * imin, size_t *jmin); void gsl_matrix_long_double_minmax_index (const gsl_matrix_long_double * m, size_t * imin, size_t * jmin, size_t * imax, size_t * jmax); int gsl_matrix_long_double_isnull (const gsl_matrix_long_double * m); int gsl_matrix_long_double_ispos (const gsl_matrix_long_double * m); int gsl_matrix_long_double_isneg (const gsl_matrix_long_double * m); int gsl_matrix_long_double_isnonneg (const gsl_matrix_long_double * m); int gsl_matrix_long_double_add (gsl_matrix_long_double * a, const gsl_matrix_long_double * b); int gsl_matrix_long_double_sub (gsl_matrix_long_double * a, const gsl_matrix_long_double * b); int gsl_matrix_long_double_mul_elements (gsl_matrix_long_double * a, const gsl_matrix_long_double * b); int gsl_matrix_long_double_div_elements (gsl_matrix_long_double * a, const gsl_matrix_long_double * b); int gsl_matrix_long_double_scale (gsl_matrix_long_double * a, const double x); int gsl_matrix_long_double_add_constant (gsl_matrix_long_double * a, const double x); int gsl_matrix_long_double_add_diagonal (gsl_matrix_long_double * a, const double x); /***********************************************************************/ /* The functions below are obsolete */ /***********************************************************************/ int gsl_matrix_long_double_get_row(gsl_vector_long_double * v, const gsl_matrix_long_double * m, const size_t i); int gsl_matrix_long_double_get_col(gsl_vector_long_double * v, const gsl_matrix_long_double * m, const size_t j); int gsl_matrix_long_double_set_row(gsl_matrix_long_double * m, const size_t i, const gsl_vector_long_double * v); int gsl_matrix_long_double_set_col(gsl_matrix_long_double * m, const size_t j, const gsl_vector_long_double * v); /* inline functions if you are using GCC */ #ifdef HAVE_INLINE extern inline long double gsl_matrix_long_double_get(const gsl_matrix_long_double * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_VAL("first index out of range", GSL_EINVAL, 0) ; } else if (j >= m->size2) { GSL_ERROR_VAL("second index out of range", GSL_EINVAL, 0) ; } #endif return m->data[i * m->tda + j] ; } extern inline void gsl_matrix_long_double_set(gsl_matrix_long_double * m, const size_t i, const size_t j, const long double x) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; } #endif m->data[i * m->tda + j] = x ; } extern inline long double * gsl_matrix_long_double_ptr(gsl_matrix_long_double * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (long double *) (m->data + (i * m->tda + j)) ; } extern inline const long double * gsl_matrix_long_double_const_ptr(const gsl_matrix_long_double * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (const long double *) (m->data + (i * m->tda + j)) ; } #endif __END_DECLS #endif /* __GSL_MATRIX_LONG_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_matrix_short.h000066400000000000000000000267701261542461700211040ustar00rootroot00000000000000/* matrix/gsl_matrix_short.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_MATRIX_SHORT_H__ #define __GSL_MATRIX_SHORT_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_check_range.h" #include "gsl_vector_short.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size1; size_t size2; size_t tda; short * data; gsl_block_short * block; int owner; } gsl_matrix_short; typedef struct { gsl_matrix_short matrix; } _gsl_matrix_short_view; typedef _gsl_matrix_short_view gsl_matrix_short_view; typedef struct { gsl_matrix_short matrix; } _gsl_matrix_short_const_view; typedef const _gsl_matrix_short_const_view gsl_matrix_short_const_view; /* Allocation */ gsl_matrix_short * gsl_matrix_short_alloc (const size_t n1, const size_t n2); gsl_matrix_short * gsl_matrix_short_calloc (const size_t n1, const size_t n2); gsl_matrix_short * gsl_matrix_short_alloc_from_block (gsl_block_short * b, const size_t offset, const size_t n1, const size_t n2, const size_t d2); gsl_matrix_short * gsl_matrix_short_alloc_from_matrix (gsl_matrix_short * m, const size_t k1, const size_t k2, const size_t n1, const size_t n2); gsl_vector_short * gsl_vector_short_alloc_row_from_matrix (gsl_matrix_short * m, const size_t i); gsl_vector_short * gsl_vector_short_alloc_col_from_matrix (gsl_matrix_short * m, const size_t j); void gsl_matrix_short_free (gsl_matrix_short * m); /* Views */ _gsl_matrix_short_view gsl_matrix_short_submatrix (gsl_matrix_short * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_short_view gsl_matrix_short_row (gsl_matrix_short * m, const size_t i); _gsl_vector_short_view gsl_matrix_short_column (gsl_matrix_short * m, const size_t j); _gsl_vector_short_view gsl_matrix_short_diagonal (gsl_matrix_short * m); _gsl_vector_short_view gsl_matrix_short_subdiagonal (gsl_matrix_short * m, const size_t k); _gsl_vector_short_view gsl_matrix_short_superdiagonal (gsl_matrix_short * m, const size_t k); _gsl_vector_short_view gsl_matrix_short_subrow (gsl_matrix_short * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_short_view gsl_matrix_short_subcolumn (gsl_matrix_short * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_short_view gsl_matrix_short_view_array (short * base, const size_t n1, const size_t n2); _gsl_matrix_short_view gsl_matrix_short_view_array_with_tda (short * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_short_view gsl_matrix_short_view_vector (gsl_vector_short * v, const size_t n1, const size_t n2); _gsl_matrix_short_view gsl_matrix_short_view_vector_with_tda (gsl_vector_short * v, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_short_const_view gsl_matrix_short_const_submatrix (const gsl_matrix_short * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_short_const_view gsl_matrix_short_const_row (const gsl_matrix_short * m, const size_t i); _gsl_vector_short_const_view gsl_matrix_short_const_column (const gsl_matrix_short * m, const size_t j); _gsl_vector_short_const_view gsl_matrix_short_const_diagonal (const gsl_matrix_short * m); _gsl_vector_short_const_view gsl_matrix_short_const_subdiagonal (const gsl_matrix_short * m, const size_t k); _gsl_vector_short_const_view gsl_matrix_short_const_superdiagonal (const gsl_matrix_short * m, const size_t k); _gsl_vector_short_const_view gsl_matrix_short_const_subrow (const gsl_matrix_short * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_short_const_view gsl_matrix_short_const_subcolumn (const gsl_matrix_short * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_short_const_view gsl_matrix_short_const_view_array (const short * base, const size_t n1, const size_t n2); _gsl_matrix_short_const_view gsl_matrix_short_const_view_array_with_tda (const short * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_short_const_view gsl_matrix_short_const_view_vector (const gsl_vector_short * v, const size_t n1, const size_t n2); _gsl_matrix_short_const_view gsl_matrix_short_const_view_vector_with_tda (const gsl_vector_short * v, const size_t n1, const size_t n2, const size_t tda); /* Operations */ short gsl_matrix_short_get(const gsl_matrix_short * m, const size_t i, const size_t j); void gsl_matrix_short_set(gsl_matrix_short * m, const size_t i, const size_t j, const short x); short * gsl_matrix_short_ptr(gsl_matrix_short * m, const size_t i, const size_t j); const short * gsl_matrix_short_const_ptr(const gsl_matrix_short * m, const size_t i, const size_t j); void gsl_matrix_short_set_zero (gsl_matrix_short * m); void gsl_matrix_short_set_identity (gsl_matrix_short * m); void gsl_matrix_short_set_all (gsl_matrix_short * m, short x); int gsl_matrix_short_fread (FILE * stream, gsl_matrix_short * m) ; int gsl_matrix_short_fwrite (FILE * stream, const gsl_matrix_short * m) ; int gsl_matrix_short_fscanf (FILE * stream, gsl_matrix_short * m); int gsl_matrix_short_fprintf (FILE * stream, const gsl_matrix_short * m, const char * format); int gsl_matrix_short_memcpy(gsl_matrix_short * dest, const gsl_matrix_short * src); int gsl_matrix_short_swap(gsl_matrix_short * m1, gsl_matrix_short * m2); int gsl_matrix_short_swap_rows(gsl_matrix_short * m, const size_t i, const size_t j); int gsl_matrix_short_swap_columns(gsl_matrix_short * m, const size_t i, const size_t j); int gsl_matrix_short_swap_rowcol(gsl_matrix_short * m, const size_t i, const size_t j); int gsl_matrix_short_transpose (gsl_matrix_short * m); int gsl_matrix_short_transpose_memcpy (gsl_matrix_short * dest, const gsl_matrix_short * src); short gsl_matrix_short_max (const gsl_matrix_short * m); short gsl_matrix_short_min (const gsl_matrix_short * m); void gsl_matrix_short_minmax (const gsl_matrix_short * m, short * min_out, short * max_out); void gsl_matrix_short_max_index (const gsl_matrix_short * m, size_t * imax, size_t *jmax); void gsl_matrix_short_min_index (const gsl_matrix_short * m, size_t * imin, size_t *jmin); void gsl_matrix_short_minmax_index (const gsl_matrix_short * m, size_t * imin, size_t * jmin, size_t * imax, size_t * jmax); int gsl_matrix_short_isnull (const gsl_matrix_short * m); int gsl_matrix_short_ispos (const gsl_matrix_short * m); int gsl_matrix_short_isneg (const gsl_matrix_short * m); int gsl_matrix_short_isnonneg (const gsl_matrix_short * m); int gsl_matrix_short_add (gsl_matrix_short * a, const gsl_matrix_short * b); int gsl_matrix_short_sub (gsl_matrix_short * a, const gsl_matrix_short * b); int gsl_matrix_short_mul_elements (gsl_matrix_short * a, const gsl_matrix_short * b); int gsl_matrix_short_div_elements (gsl_matrix_short * a, const gsl_matrix_short * b); int gsl_matrix_short_scale (gsl_matrix_short * a, const double x); int gsl_matrix_short_add_constant (gsl_matrix_short * a, const double x); int gsl_matrix_short_add_diagonal (gsl_matrix_short * a, const double x); /***********************************************************************/ /* The functions below are obsolete */ /***********************************************************************/ int gsl_matrix_short_get_row(gsl_vector_short * v, const gsl_matrix_short * m, const size_t i); int gsl_matrix_short_get_col(gsl_vector_short * v, const gsl_matrix_short * m, const size_t j); int gsl_matrix_short_set_row(gsl_matrix_short * m, const size_t i, const gsl_vector_short * v); int gsl_matrix_short_set_col(gsl_matrix_short * m, const size_t j, const gsl_vector_short * v); /* inline functions if you are using GCC */ #ifdef HAVE_INLINE extern inline short gsl_matrix_short_get(const gsl_matrix_short * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_VAL("first index out of range", GSL_EINVAL, 0) ; } else if (j >= m->size2) { GSL_ERROR_VAL("second index out of range", GSL_EINVAL, 0) ; } #endif return m->data[i * m->tda + j] ; } extern inline void gsl_matrix_short_set(gsl_matrix_short * m, const size_t i, const size_t j, const short x) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; } #endif m->data[i * m->tda + j] = x ; } extern inline short * gsl_matrix_short_ptr(gsl_matrix_short * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (short *) (m->data + (i * m->tda + j)) ; } extern inline const short * gsl_matrix_short_const_ptr(const gsl_matrix_short * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (const short *) (m->data + (i * m->tda + j)) ; } #endif __END_DECLS #endif /* __GSL_MATRIX_SHORT_H__ */ praat-6.0.04/external/gsl/gsl_matrix_uchar.h000066400000000000000000000272301261542461700210370ustar00rootroot00000000000000/* matrix/gsl_matrix_uchar.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_MATRIX_UCHAR_H__ #define __GSL_MATRIX_UCHAR_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_check_range.h" #include "gsl_vector_uchar.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size1; size_t size2; size_t tda; unsigned char * data; gsl_block_uchar * block; int owner; } gsl_matrix_uchar; typedef struct { gsl_matrix_uchar matrix; } _gsl_matrix_uchar_view; typedef _gsl_matrix_uchar_view gsl_matrix_uchar_view; typedef struct { gsl_matrix_uchar matrix; } _gsl_matrix_uchar_const_view; typedef const _gsl_matrix_uchar_const_view gsl_matrix_uchar_const_view; /* Allocation */ gsl_matrix_uchar * gsl_matrix_uchar_alloc (const size_t n1, const size_t n2); gsl_matrix_uchar * gsl_matrix_uchar_calloc (const size_t n1, const size_t n2); gsl_matrix_uchar * gsl_matrix_uchar_alloc_from_block (gsl_block_uchar * b, const size_t offset, const size_t n1, const size_t n2, const size_t d2); gsl_matrix_uchar * gsl_matrix_uchar_alloc_from_matrix (gsl_matrix_uchar * m, const size_t k1, const size_t k2, const size_t n1, const size_t n2); gsl_vector_uchar * gsl_vector_uchar_alloc_row_from_matrix (gsl_matrix_uchar * m, const size_t i); gsl_vector_uchar * gsl_vector_uchar_alloc_col_from_matrix (gsl_matrix_uchar * m, const size_t j); void gsl_matrix_uchar_free (gsl_matrix_uchar * m); /* Views */ _gsl_matrix_uchar_view gsl_matrix_uchar_submatrix (gsl_matrix_uchar * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_uchar_view gsl_matrix_uchar_row (gsl_matrix_uchar * m, const size_t i); _gsl_vector_uchar_view gsl_matrix_uchar_column (gsl_matrix_uchar * m, const size_t j); _gsl_vector_uchar_view gsl_matrix_uchar_diagonal (gsl_matrix_uchar * m); _gsl_vector_uchar_view gsl_matrix_uchar_subdiagonal (gsl_matrix_uchar * m, const size_t k); _gsl_vector_uchar_view gsl_matrix_uchar_superdiagonal (gsl_matrix_uchar * m, const size_t k); _gsl_vector_uchar_view gsl_matrix_uchar_subrow (gsl_matrix_uchar * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_uchar_view gsl_matrix_uchar_subcolumn (gsl_matrix_uchar * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_uchar_view gsl_matrix_uchar_view_array (unsigned char * base, const size_t n1, const size_t n2); _gsl_matrix_uchar_view gsl_matrix_uchar_view_array_with_tda (unsigned char * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_uchar_view gsl_matrix_uchar_view_vector (gsl_vector_uchar * v, const size_t n1, const size_t n2); _gsl_matrix_uchar_view gsl_matrix_uchar_view_vector_with_tda (gsl_vector_uchar * v, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_uchar_const_view gsl_matrix_uchar_const_submatrix (const gsl_matrix_uchar * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_uchar_const_view gsl_matrix_uchar_const_row (const gsl_matrix_uchar * m, const size_t i); _gsl_vector_uchar_const_view gsl_matrix_uchar_const_column (const gsl_matrix_uchar * m, const size_t j); _gsl_vector_uchar_const_view gsl_matrix_uchar_const_diagonal (const gsl_matrix_uchar * m); _gsl_vector_uchar_const_view gsl_matrix_uchar_const_subdiagonal (const gsl_matrix_uchar * m, const size_t k); _gsl_vector_uchar_const_view gsl_matrix_uchar_const_superdiagonal (const gsl_matrix_uchar * m, const size_t k); _gsl_vector_uchar_const_view gsl_matrix_uchar_const_subrow (const gsl_matrix_uchar * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_uchar_const_view gsl_matrix_uchar_const_subcolumn (const gsl_matrix_uchar * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_uchar_const_view gsl_matrix_uchar_const_view_array (const unsigned char * base, const size_t n1, const size_t n2); _gsl_matrix_uchar_const_view gsl_matrix_uchar_const_view_array_with_tda (const unsigned char * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_uchar_const_view gsl_matrix_uchar_const_view_vector (const gsl_vector_uchar * v, const size_t n1, const size_t n2); _gsl_matrix_uchar_const_view gsl_matrix_uchar_const_view_vector_with_tda (const gsl_vector_uchar * v, const size_t n1, const size_t n2, const size_t tda); /* Operations */ unsigned char gsl_matrix_uchar_get(const gsl_matrix_uchar * m, const size_t i, const size_t j); void gsl_matrix_uchar_set(gsl_matrix_uchar * m, const size_t i, const size_t j, const unsigned char x); unsigned char * gsl_matrix_uchar_ptr(gsl_matrix_uchar * m, const size_t i, const size_t j); const unsigned char * gsl_matrix_uchar_const_ptr(const gsl_matrix_uchar * m, const size_t i, const size_t j); void gsl_matrix_uchar_set_zero (gsl_matrix_uchar * m); void gsl_matrix_uchar_set_identity (gsl_matrix_uchar * m); void gsl_matrix_uchar_set_all (gsl_matrix_uchar * m, unsigned char x); int gsl_matrix_uchar_fread (FILE * stream, gsl_matrix_uchar * m) ; int gsl_matrix_uchar_fwrite (FILE * stream, const gsl_matrix_uchar * m) ; int gsl_matrix_uchar_fscanf (FILE * stream, gsl_matrix_uchar * m); int gsl_matrix_uchar_fprintf (FILE * stream, const gsl_matrix_uchar * m, const char * format); int gsl_matrix_uchar_memcpy(gsl_matrix_uchar * dest, const gsl_matrix_uchar * src); int gsl_matrix_uchar_swap(gsl_matrix_uchar * m1, gsl_matrix_uchar * m2); int gsl_matrix_uchar_swap_rows(gsl_matrix_uchar * m, const size_t i, const size_t j); int gsl_matrix_uchar_swap_columns(gsl_matrix_uchar * m, const size_t i, const size_t j); int gsl_matrix_uchar_swap_rowcol(gsl_matrix_uchar * m, const size_t i, const size_t j); int gsl_matrix_uchar_transpose (gsl_matrix_uchar * m); int gsl_matrix_uchar_transpose_memcpy (gsl_matrix_uchar * dest, const gsl_matrix_uchar * src); unsigned char gsl_matrix_uchar_max (const gsl_matrix_uchar * m); unsigned char gsl_matrix_uchar_min (const gsl_matrix_uchar * m); void gsl_matrix_uchar_minmax (const gsl_matrix_uchar * m, unsigned char * min_out, unsigned char * max_out); void gsl_matrix_uchar_max_index (const gsl_matrix_uchar * m, size_t * imax, size_t *jmax); void gsl_matrix_uchar_min_index (const gsl_matrix_uchar * m, size_t * imin, size_t *jmin); void gsl_matrix_uchar_minmax_index (const gsl_matrix_uchar * m, size_t * imin, size_t * jmin, size_t * imax, size_t * jmax); int gsl_matrix_uchar_isnull (const gsl_matrix_uchar * m); int gsl_matrix_uchar_ispos (const gsl_matrix_uchar * m); int gsl_matrix_uchar_isneg (const gsl_matrix_uchar * m); int gsl_matrix_uchar_isnonneg (const gsl_matrix_uchar * m); int gsl_matrix_uchar_add (gsl_matrix_uchar * a, const gsl_matrix_uchar * b); int gsl_matrix_uchar_sub (gsl_matrix_uchar * a, const gsl_matrix_uchar * b); int gsl_matrix_uchar_mul_elements (gsl_matrix_uchar * a, const gsl_matrix_uchar * b); int gsl_matrix_uchar_div_elements (gsl_matrix_uchar * a, const gsl_matrix_uchar * b); int gsl_matrix_uchar_scale (gsl_matrix_uchar * a, const double x); int gsl_matrix_uchar_add_constant (gsl_matrix_uchar * a, const double x); int gsl_matrix_uchar_add_diagonal (gsl_matrix_uchar * a, const double x); /***********************************************************************/ /* The functions below are obsolete */ /***********************************************************************/ int gsl_matrix_uchar_get_row(gsl_vector_uchar * v, const gsl_matrix_uchar * m, const size_t i); int gsl_matrix_uchar_get_col(gsl_vector_uchar * v, const gsl_matrix_uchar * m, const size_t j); int gsl_matrix_uchar_set_row(gsl_matrix_uchar * m, const size_t i, const gsl_vector_uchar * v); int gsl_matrix_uchar_set_col(gsl_matrix_uchar * m, const size_t j, const gsl_vector_uchar * v); /* inline functions if you are using GCC */ #ifdef HAVE_INLINE extern inline unsigned char gsl_matrix_uchar_get(const gsl_matrix_uchar * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_VAL("first index out of range", GSL_EINVAL, 0) ; } else if (j >= m->size2) { GSL_ERROR_VAL("second index out of range", GSL_EINVAL, 0) ; } #endif return m->data[i * m->tda + j] ; } extern inline void gsl_matrix_uchar_set(gsl_matrix_uchar * m, const size_t i, const size_t j, const unsigned char x) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; } #endif m->data[i * m->tda + j] = x ; } extern inline unsigned char * gsl_matrix_uchar_ptr(gsl_matrix_uchar * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (unsigned char *) (m->data + (i * m->tda + j)) ; } extern inline const unsigned char * gsl_matrix_uchar_const_ptr(const gsl_matrix_uchar * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (const unsigned char *) (m->data + (i * m->tda + j)) ; } #endif __END_DECLS #endif /* __GSL_MATRIX_UCHAR_H__ */ praat-6.0.04/external/gsl/gsl_matrix_uint.h000066400000000000000000000266761261542461700207310ustar00rootroot00000000000000/* matrix/gsl_matrix_uint.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_MATRIX_UINT_H__ #define __GSL_MATRIX_UINT_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_check_range.h" #include "gsl_vector_uint.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size1; size_t size2; size_t tda; unsigned int * data; gsl_block_uint * block; int owner; } gsl_matrix_uint; typedef struct { gsl_matrix_uint matrix; } _gsl_matrix_uint_view; typedef _gsl_matrix_uint_view gsl_matrix_uint_view; typedef struct { gsl_matrix_uint matrix; } _gsl_matrix_uint_const_view; typedef const _gsl_matrix_uint_const_view gsl_matrix_uint_const_view; /* Allocation */ gsl_matrix_uint * gsl_matrix_uint_alloc (const size_t n1, const size_t n2); gsl_matrix_uint * gsl_matrix_uint_calloc (const size_t n1, const size_t n2); gsl_matrix_uint * gsl_matrix_uint_alloc_from_block (gsl_block_uint * b, const size_t offset, const size_t n1, const size_t n2, const size_t d2); gsl_matrix_uint * gsl_matrix_uint_alloc_from_matrix (gsl_matrix_uint * m, const size_t k1, const size_t k2, const size_t n1, const size_t n2); gsl_vector_uint * gsl_vector_uint_alloc_row_from_matrix (gsl_matrix_uint * m, const size_t i); gsl_vector_uint * gsl_vector_uint_alloc_col_from_matrix (gsl_matrix_uint * m, const size_t j); void gsl_matrix_uint_free (gsl_matrix_uint * m); /* Views */ _gsl_matrix_uint_view gsl_matrix_uint_submatrix (gsl_matrix_uint * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_uint_view gsl_matrix_uint_row (gsl_matrix_uint * m, const size_t i); _gsl_vector_uint_view gsl_matrix_uint_column (gsl_matrix_uint * m, const size_t j); _gsl_vector_uint_view gsl_matrix_uint_diagonal (gsl_matrix_uint * m); _gsl_vector_uint_view gsl_matrix_uint_subdiagonal (gsl_matrix_uint * m, const size_t k); _gsl_vector_uint_view gsl_matrix_uint_superdiagonal (gsl_matrix_uint * m, const size_t k); _gsl_vector_uint_view gsl_matrix_uint_subrow (gsl_matrix_uint * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_uint_view gsl_matrix_uint_subcolumn (gsl_matrix_uint * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_uint_view gsl_matrix_uint_view_array (unsigned int * base, const size_t n1, const size_t n2); _gsl_matrix_uint_view gsl_matrix_uint_view_array_with_tda (unsigned int * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_uint_view gsl_matrix_uint_view_vector (gsl_vector_uint * v, const size_t n1, const size_t n2); _gsl_matrix_uint_view gsl_matrix_uint_view_vector_with_tda (gsl_vector_uint * v, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_uint_const_view gsl_matrix_uint_const_submatrix (const gsl_matrix_uint * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_uint_const_view gsl_matrix_uint_const_row (const gsl_matrix_uint * m, const size_t i); _gsl_vector_uint_const_view gsl_matrix_uint_const_column (const gsl_matrix_uint * m, const size_t j); _gsl_vector_uint_const_view gsl_matrix_uint_const_diagonal (const gsl_matrix_uint * m); _gsl_vector_uint_const_view gsl_matrix_uint_const_subdiagonal (const gsl_matrix_uint * m, const size_t k); _gsl_vector_uint_const_view gsl_matrix_uint_const_superdiagonal (const gsl_matrix_uint * m, const size_t k); _gsl_vector_uint_const_view gsl_matrix_uint_const_subrow (const gsl_matrix_uint * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_uint_const_view gsl_matrix_uint_const_subcolumn (const gsl_matrix_uint * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_uint_const_view gsl_matrix_uint_const_view_array (const unsigned int * base, const size_t n1, const size_t n2); _gsl_matrix_uint_const_view gsl_matrix_uint_const_view_array_with_tda (const unsigned int * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_uint_const_view gsl_matrix_uint_const_view_vector (const gsl_vector_uint * v, const size_t n1, const size_t n2); _gsl_matrix_uint_const_view gsl_matrix_uint_const_view_vector_with_tda (const gsl_vector_uint * v, const size_t n1, const size_t n2, const size_t tda); /* Operations */ unsigned int gsl_matrix_uint_get(const gsl_matrix_uint * m, const size_t i, const size_t j); void gsl_matrix_uint_set(gsl_matrix_uint * m, const size_t i, const size_t j, const unsigned int x); unsigned int * gsl_matrix_uint_ptr(gsl_matrix_uint * m, const size_t i, const size_t j); const unsigned int * gsl_matrix_uint_const_ptr(const gsl_matrix_uint * m, const size_t i, const size_t j); void gsl_matrix_uint_set_zero (gsl_matrix_uint * m); void gsl_matrix_uint_set_identity (gsl_matrix_uint * m); void gsl_matrix_uint_set_all (gsl_matrix_uint * m, unsigned int x); int gsl_matrix_uint_fread (FILE * stream, gsl_matrix_uint * m) ; int gsl_matrix_uint_fwrite (FILE * stream, const gsl_matrix_uint * m) ; int gsl_matrix_uint_fscanf (FILE * stream, gsl_matrix_uint * m); int gsl_matrix_uint_fprintf (FILE * stream, const gsl_matrix_uint * m, const char * format); int gsl_matrix_uint_memcpy(gsl_matrix_uint * dest, const gsl_matrix_uint * src); int gsl_matrix_uint_swap(gsl_matrix_uint * m1, gsl_matrix_uint * m2); int gsl_matrix_uint_swap_rows(gsl_matrix_uint * m, const size_t i, const size_t j); int gsl_matrix_uint_swap_columns(gsl_matrix_uint * m, const size_t i, const size_t j); int gsl_matrix_uint_swap_rowcol(gsl_matrix_uint * m, const size_t i, const size_t j); int gsl_matrix_uint_transpose (gsl_matrix_uint * m); int gsl_matrix_uint_transpose_memcpy (gsl_matrix_uint * dest, const gsl_matrix_uint * src); unsigned int gsl_matrix_uint_max (const gsl_matrix_uint * m); unsigned int gsl_matrix_uint_min (const gsl_matrix_uint * m); void gsl_matrix_uint_minmax (const gsl_matrix_uint * m, unsigned int * min_out, unsigned int * max_out); void gsl_matrix_uint_max_index (const gsl_matrix_uint * m, size_t * imax, size_t *jmax); void gsl_matrix_uint_min_index (const gsl_matrix_uint * m, size_t * imin, size_t *jmin); void gsl_matrix_uint_minmax_index (const gsl_matrix_uint * m, size_t * imin, size_t * jmin, size_t * imax, size_t * jmax); int gsl_matrix_uint_isnull (const gsl_matrix_uint * m); int gsl_matrix_uint_ispos (const gsl_matrix_uint * m); int gsl_matrix_uint_isneg (const gsl_matrix_uint * m); int gsl_matrix_uint_isnonneg (const gsl_matrix_uint * m); int gsl_matrix_uint_add (gsl_matrix_uint * a, const gsl_matrix_uint * b); int gsl_matrix_uint_sub (gsl_matrix_uint * a, const gsl_matrix_uint * b); int gsl_matrix_uint_mul_elements (gsl_matrix_uint * a, const gsl_matrix_uint * b); int gsl_matrix_uint_div_elements (gsl_matrix_uint * a, const gsl_matrix_uint * b); int gsl_matrix_uint_scale (gsl_matrix_uint * a, const double x); int gsl_matrix_uint_add_constant (gsl_matrix_uint * a, const double x); int gsl_matrix_uint_add_diagonal (gsl_matrix_uint * a, const double x); /***********************************************************************/ /* The functions below are obsolete */ /***********************************************************************/ int gsl_matrix_uint_get_row(gsl_vector_uint * v, const gsl_matrix_uint * m, const size_t i); int gsl_matrix_uint_get_col(gsl_vector_uint * v, const gsl_matrix_uint * m, const size_t j); int gsl_matrix_uint_set_row(gsl_matrix_uint * m, const size_t i, const gsl_vector_uint * v); int gsl_matrix_uint_set_col(gsl_matrix_uint * m, const size_t j, const gsl_vector_uint * v); /* inline functions if you are using GCC */ #ifdef HAVE_INLINE extern inline unsigned int gsl_matrix_uint_get(const gsl_matrix_uint * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_VAL("first index out of range", GSL_EINVAL, 0) ; } else if (j >= m->size2) { GSL_ERROR_VAL("second index out of range", GSL_EINVAL, 0) ; } #endif return m->data[i * m->tda + j] ; } extern inline void gsl_matrix_uint_set(gsl_matrix_uint * m, const size_t i, const size_t j, const unsigned int x) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; } #endif m->data[i * m->tda + j] = x ; } extern inline unsigned int * gsl_matrix_uint_ptr(gsl_matrix_uint * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (unsigned int *) (m->data + (i * m->tda + j)) ; } extern inline const unsigned int * gsl_matrix_uint_const_ptr(const gsl_matrix_uint * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (const unsigned int *) (m->data + (i * m->tda + j)) ; } #endif __END_DECLS #endif /* __GSL_MATRIX_UINT_H__ */ praat-6.0.04/external/gsl/gsl_matrix_ulong.h000066400000000000000000000272301261542461700210610ustar00rootroot00000000000000/* matrix/gsl_matrix_ulong.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_MATRIX_ULONG_H__ #define __GSL_MATRIX_ULONG_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_check_range.h" #include "gsl_vector_ulong.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size1; size_t size2; size_t tda; unsigned long * data; gsl_block_ulong * block; int owner; } gsl_matrix_ulong; typedef struct { gsl_matrix_ulong matrix; } _gsl_matrix_ulong_view; typedef _gsl_matrix_ulong_view gsl_matrix_ulong_view; typedef struct { gsl_matrix_ulong matrix; } _gsl_matrix_ulong_const_view; typedef const _gsl_matrix_ulong_const_view gsl_matrix_ulong_const_view; /* Allocation */ gsl_matrix_ulong * gsl_matrix_ulong_alloc (const size_t n1, const size_t n2); gsl_matrix_ulong * gsl_matrix_ulong_calloc (const size_t n1, const size_t n2); gsl_matrix_ulong * gsl_matrix_ulong_alloc_from_block (gsl_block_ulong * b, const size_t offset, const size_t n1, const size_t n2, const size_t d2); gsl_matrix_ulong * gsl_matrix_ulong_alloc_from_matrix (gsl_matrix_ulong * m, const size_t k1, const size_t k2, const size_t n1, const size_t n2); gsl_vector_ulong * gsl_vector_ulong_alloc_row_from_matrix (gsl_matrix_ulong * m, const size_t i); gsl_vector_ulong * gsl_vector_ulong_alloc_col_from_matrix (gsl_matrix_ulong * m, const size_t j); void gsl_matrix_ulong_free (gsl_matrix_ulong * m); /* Views */ _gsl_matrix_ulong_view gsl_matrix_ulong_submatrix (gsl_matrix_ulong * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_ulong_view gsl_matrix_ulong_row (gsl_matrix_ulong * m, const size_t i); _gsl_vector_ulong_view gsl_matrix_ulong_column (gsl_matrix_ulong * m, const size_t j); _gsl_vector_ulong_view gsl_matrix_ulong_diagonal (gsl_matrix_ulong * m); _gsl_vector_ulong_view gsl_matrix_ulong_subdiagonal (gsl_matrix_ulong * m, const size_t k); _gsl_vector_ulong_view gsl_matrix_ulong_superdiagonal (gsl_matrix_ulong * m, const size_t k); _gsl_vector_ulong_view gsl_matrix_ulong_subrow (gsl_matrix_ulong * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_ulong_view gsl_matrix_ulong_subcolumn (gsl_matrix_ulong * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_ulong_view gsl_matrix_ulong_view_array (unsigned long * base, const size_t n1, const size_t n2); _gsl_matrix_ulong_view gsl_matrix_ulong_view_array_with_tda (unsigned long * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_ulong_view gsl_matrix_ulong_view_vector (gsl_vector_ulong * v, const size_t n1, const size_t n2); _gsl_matrix_ulong_view gsl_matrix_ulong_view_vector_with_tda (gsl_vector_ulong * v, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_ulong_const_view gsl_matrix_ulong_const_submatrix (const gsl_matrix_ulong * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_ulong_const_view gsl_matrix_ulong_const_row (const gsl_matrix_ulong * m, const size_t i); _gsl_vector_ulong_const_view gsl_matrix_ulong_const_column (const gsl_matrix_ulong * m, const size_t j); _gsl_vector_ulong_const_view gsl_matrix_ulong_const_diagonal (const gsl_matrix_ulong * m); _gsl_vector_ulong_const_view gsl_matrix_ulong_const_subdiagonal (const gsl_matrix_ulong * m, const size_t k); _gsl_vector_ulong_const_view gsl_matrix_ulong_const_superdiagonal (const gsl_matrix_ulong * m, const size_t k); _gsl_vector_ulong_const_view gsl_matrix_ulong_const_subrow (const gsl_matrix_ulong * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_ulong_const_view gsl_matrix_ulong_const_subcolumn (const gsl_matrix_ulong * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_ulong_const_view gsl_matrix_ulong_const_view_array (const unsigned long * base, const size_t n1, const size_t n2); _gsl_matrix_ulong_const_view gsl_matrix_ulong_const_view_array_with_tda (const unsigned long * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_ulong_const_view gsl_matrix_ulong_const_view_vector (const gsl_vector_ulong * v, const size_t n1, const size_t n2); _gsl_matrix_ulong_const_view gsl_matrix_ulong_const_view_vector_with_tda (const gsl_vector_ulong * v, const size_t n1, const size_t n2, const size_t tda); /* Operations */ unsigned long gsl_matrix_ulong_get(const gsl_matrix_ulong * m, const size_t i, const size_t j); void gsl_matrix_ulong_set(gsl_matrix_ulong * m, const size_t i, const size_t j, const unsigned long x); unsigned long * gsl_matrix_ulong_ptr(gsl_matrix_ulong * m, const size_t i, const size_t j); const unsigned long * gsl_matrix_ulong_const_ptr(const gsl_matrix_ulong * m, const size_t i, const size_t j); void gsl_matrix_ulong_set_zero (gsl_matrix_ulong * m); void gsl_matrix_ulong_set_identity (gsl_matrix_ulong * m); void gsl_matrix_ulong_set_all (gsl_matrix_ulong * m, unsigned long x); int gsl_matrix_ulong_fread (FILE * stream, gsl_matrix_ulong * m) ; int gsl_matrix_ulong_fwrite (FILE * stream, const gsl_matrix_ulong * m) ; int gsl_matrix_ulong_fscanf (FILE * stream, gsl_matrix_ulong * m); int gsl_matrix_ulong_fprintf (FILE * stream, const gsl_matrix_ulong * m, const char * format); int gsl_matrix_ulong_memcpy(gsl_matrix_ulong * dest, const gsl_matrix_ulong * src); int gsl_matrix_ulong_swap(gsl_matrix_ulong * m1, gsl_matrix_ulong * m2); int gsl_matrix_ulong_swap_rows(gsl_matrix_ulong * m, const size_t i, const size_t j); int gsl_matrix_ulong_swap_columns(gsl_matrix_ulong * m, const size_t i, const size_t j); int gsl_matrix_ulong_swap_rowcol(gsl_matrix_ulong * m, const size_t i, const size_t j); int gsl_matrix_ulong_transpose (gsl_matrix_ulong * m); int gsl_matrix_ulong_transpose_memcpy (gsl_matrix_ulong * dest, const gsl_matrix_ulong * src); unsigned long gsl_matrix_ulong_max (const gsl_matrix_ulong * m); unsigned long gsl_matrix_ulong_min (const gsl_matrix_ulong * m); void gsl_matrix_ulong_minmax (const gsl_matrix_ulong * m, unsigned long * min_out, unsigned long * max_out); void gsl_matrix_ulong_max_index (const gsl_matrix_ulong * m, size_t * imax, size_t *jmax); void gsl_matrix_ulong_min_index (const gsl_matrix_ulong * m, size_t * imin, size_t *jmin); void gsl_matrix_ulong_minmax_index (const gsl_matrix_ulong * m, size_t * imin, size_t * jmin, size_t * imax, size_t * jmax); int gsl_matrix_ulong_isnull (const gsl_matrix_ulong * m); int gsl_matrix_ulong_ispos (const gsl_matrix_ulong * m); int gsl_matrix_ulong_isneg (const gsl_matrix_ulong * m); int gsl_matrix_ulong_isnonneg (const gsl_matrix_ulong * m); int gsl_matrix_ulong_add (gsl_matrix_ulong * a, const gsl_matrix_ulong * b); int gsl_matrix_ulong_sub (gsl_matrix_ulong * a, const gsl_matrix_ulong * b); int gsl_matrix_ulong_mul_elements (gsl_matrix_ulong * a, const gsl_matrix_ulong * b); int gsl_matrix_ulong_div_elements (gsl_matrix_ulong * a, const gsl_matrix_ulong * b); int gsl_matrix_ulong_scale (gsl_matrix_ulong * a, const double x); int gsl_matrix_ulong_add_constant (gsl_matrix_ulong * a, const double x); int gsl_matrix_ulong_add_diagonal (gsl_matrix_ulong * a, const double x); /***********************************************************************/ /* The functions below are obsolete */ /***********************************************************************/ int gsl_matrix_ulong_get_row(gsl_vector_ulong * v, const gsl_matrix_ulong * m, const size_t i); int gsl_matrix_ulong_get_col(gsl_vector_ulong * v, const gsl_matrix_ulong * m, const size_t j); int gsl_matrix_ulong_set_row(gsl_matrix_ulong * m, const size_t i, const gsl_vector_ulong * v); int gsl_matrix_ulong_set_col(gsl_matrix_ulong * m, const size_t j, const gsl_vector_ulong * v); /* inline functions if you are using GCC */ #ifdef HAVE_INLINE extern inline unsigned long gsl_matrix_ulong_get(const gsl_matrix_ulong * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_VAL("first index out of range", GSL_EINVAL, 0) ; } else if (j >= m->size2) { GSL_ERROR_VAL("second index out of range", GSL_EINVAL, 0) ; } #endif return m->data[i * m->tda + j] ; } extern inline void gsl_matrix_ulong_set(gsl_matrix_ulong * m, const size_t i, const size_t j, const unsigned long x) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; } #endif m->data[i * m->tda + j] = x ; } extern inline unsigned long * gsl_matrix_ulong_ptr(gsl_matrix_ulong * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (unsigned long *) (m->data + (i * m->tda + j)) ; } extern inline const unsigned long * gsl_matrix_ulong_const_ptr(const gsl_matrix_ulong * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (const unsigned long *) (m->data + (i * m->tda + j)) ; } #endif __END_DECLS #endif /* __GSL_MATRIX_ULONG_H__ */ praat-6.0.04/external/gsl/gsl_matrix_ushort.h000066400000000000000000000275621261542461700212710ustar00rootroot00000000000000/* matrix/gsl_matrix_ushort.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_MATRIX_USHORT_H__ #define __GSL_MATRIX_USHORT_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_check_range.h" #include "gsl_vector_ushort.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size1; size_t size2; size_t tda; unsigned short * data; gsl_block_ushort * block; int owner; } gsl_matrix_ushort; typedef struct { gsl_matrix_ushort matrix; } _gsl_matrix_ushort_view; typedef _gsl_matrix_ushort_view gsl_matrix_ushort_view; typedef struct { gsl_matrix_ushort matrix; } _gsl_matrix_ushort_const_view; typedef const _gsl_matrix_ushort_const_view gsl_matrix_ushort_const_view; /* Allocation */ gsl_matrix_ushort * gsl_matrix_ushort_alloc (const size_t n1, const size_t n2); gsl_matrix_ushort * gsl_matrix_ushort_calloc (const size_t n1, const size_t n2); gsl_matrix_ushort * gsl_matrix_ushort_alloc_from_block (gsl_block_ushort * b, const size_t offset, const size_t n1, const size_t n2, const size_t d2); gsl_matrix_ushort * gsl_matrix_ushort_alloc_from_matrix (gsl_matrix_ushort * m, const size_t k1, const size_t k2, const size_t n1, const size_t n2); gsl_vector_ushort * gsl_vector_ushort_alloc_row_from_matrix (gsl_matrix_ushort * m, const size_t i); gsl_vector_ushort * gsl_vector_ushort_alloc_col_from_matrix (gsl_matrix_ushort * m, const size_t j); void gsl_matrix_ushort_free (gsl_matrix_ushort * m); /* Views */ _gsl_matrix_ushort_view gsl_matrix_ushort_submatrix (gsl_matrix_ushort * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_ushort_view gsl_matrix_ushort_row (gsl_matrix_ushort * m, const size_t i); _gsl_vector_ushort_view gsl_matrix_ushort_column (gsl_matrix_ushort * m, const size_t j); _gsl_vector_ushort_view gsl_matrix_ushort_diagonal (gsl_matrix_ushort * m); _gsl_vector_ushort_view gsl_matrix_ushort_subdiagonal (gsl_matrix_ushort * m, const size_t k); _gsl_vector_ushort_view gsl_matrix_ushort_superdiagonal (gsl_matrix_ushort * m, const size_t k); _gsl_vector_ushort_view gsl_matrix_ushort_subrow (gsl_matrix_ushort * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_ushort_view gsl_matrix_ushort_subcolumn (gsl_matrix_ushort * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_ushort_view gsl_matrix_ushort_view_array (unsigned short * base, const size_t n1, const size_t n2); _gsl_matrix_ushort_view gsl_matrix_ushort_view_array_with_tda (unsigned short * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_ushort_view gsl_matrix_ushort_view_vector (gsl_vector_ushort * v, const size_t n1, const size_t n2); _gsl_matrix_ushort_view gsl_matrix_ushort_view_vector_with_tda (gsl_vector_ushort * v, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_ushort_const_view gsl_matrix_ushort_const_submatrix (const gsl_matrix_ushort * m, const size_t i, const size_t j, const size_t n1, const size_t n2); _gsl_vector_ushort_const_view gsl_matrix_ushort_const_row (const gsl_matrix_ushort * m, const size_t i); _gsl_vector_ushort_const_view gsl_matrix_ushort_const_column (const gsl_matrix_ushort * m, const size_t j); _gsl_vector_ushort_const_view gsl_matrix_ushort_const_diagonal (const gsl_matrix_ushort * m); _gsl_vector_ushort_const_view gsl_matrix_ushort_const_subdiagonal (const gsl_matrix_ushort * m, const size_t k); _gsl_vector_ushort_const_view gsl_matrix_ushort_const_superdiagonal (const gsl_matrix_ushort * m, const size_t k); _gsl_vector_ushort_const_view gsl_matrix_ushort_const_subrow (const gsl_matrix_ushort * m, const size_t i, const size_t offset, const size_t n); _gsl_vector_ushort_const_view gsl_matrix_ushort_const_subcolumn (const gsl_matrix_ushort * m, const size_t j, const size_t offset, const size_t n); _gsl_matrix_ushort_const_view gsl_matrix_ushort_const_view_array (const unsigned short * base, const size_t n1, const size_t n2); _gsl_matrix_ushort_const_view gsl_matrix_ushort_const_view_array_with_tda (const unsigned short * base, const size_t n1, const size_t n2, const size_t tda); _gsl_matrix_ushort_const_view gsl_matrix_ushort_const_view_vector (const gsl_vector_ushort * v, const size_t n1, const size_t n2); _gsl_matrix_ushort_const_view gsl_matrix_ushort_const_view_vector_with_tda (const gsl_vector_ushort * v, const size_t n1, const size_t n2, const size_t tda); /* Operations */ unsigned short gsl_matrix_ushort_get(const gsl_matrix_ushort * m, const size_t i, const size_t j); void gsl_matrix_ushort_set(gsl_matrix_ushort * m, const size_t i, const size_t j, const unsigned short x); unsigned short * gsl_matrix_ushort_ptr(gsl_matrix_ushort * m, const size_t i, const size_t j); const unsigned short * gsl_matrix_ushort_const_ptr(const gsl_matrix_ushort * m, const size_t i, const size_t j); void gsl_matrix_ushort_set_zero (gsl_matrix_ushort * m); void gsl_matrix_ushort_set_identity (gsl_matrix_ushort * m); void gsl_matrix_ushort_set_all (gsl_matrix_ushort * m, unsigned short x); int gsl_matrix_ushort_fread (FILE * stream, gsl_matrix_ushort * m) ; int gsl_matrix_ushort_fwrite (FILE * stream, const gsl_matrix_ushort * m) ; int gsl_matrix_ushort_fscanf (FILE * stream, gsl_matrix_ushort * m); int gsl_matrix_ushort_fprintf (FILE * stream, const gsl_matrix_ushort * m, const char * format); int gsl_matrix_ushort_memcpy(gsl_matrix_ushort * dest, const gsl_matrix_ushort * src); int gsl_matrix_ushort_swap(gsl_matrix_ushort * m1, gsl_matrix_ushort * m2); int gsl_matrix_ushort_swap_rows(gsl_matrix_ushort * m, const size_t i, const size_t j); int gsl_matrix_ushort_swap_columns(gsl_matrix_ushort * m, const size_t i, const size_t j); int gsl_matrix_ushort_swap_rowcol(gsl_matrix_ushort * m, const size_t i, const size_t j); int gsl_matrix_ushort_transpose (gsl_matrix_ushort * m); int gsl_matrix_ushort_transpose_memcpy (gsl_matrix_ushort * dest, const gsl_matrix_ushort * src); unsigned short gsl_matrix_ushort_max (const gsl_matrix_ushort * m); unsigned short gsl_matrix_ushort_min (const gsl_matrix_ushort * m); void gsl_matrix_ushort_minmax (const gsl_matrix_ushort * m, unsigned short * min_out, unsigned short * max_out); void gsl_matrix_ushort_max_index (const gsl_matrix_ushort * m, size_t * imax, size_t *jmax); void gsl_matrix_ushort_min_index (const gsl_matrix_ushort * m, size_t * imin, size_t *jmin); void gsl_matrix_ushort_minmax_index (const gsl_matrix_ushort * m, size_t * imin, size_t * jmin, size_t * imax, size_t * jmax); int gsl_matrix_ushort_isnull (const gsl_matrix_ushort * m); int gsl_matrix_ushort_ispos (const gsl_matrix_ushort * m); int gsl_matrix_ushort_isneg (const gsl_matrix_ushort * m); int gsl_matrix_ushort_isnonneg (const gsl_matrix_ushort * m); int gsl_matrix_ushort_add (gsl_matrix_ushort * a, const gsl_matrix_ushort * b); int gsl_matrix_ushort_sub (gsl_matrix_ushort * a, const gsl_matrix_ushort * b); int gsl_matrix_ushort_mul_elements (gsl_matrix_ushort * a, const gsl_matrix_ushort * b); int gsl_matrix_ushort_div_elements (gsl_matrix_ushort * a, const gsl_matrix_ushort * b); int gsl_matrix_ushort_scale (gsl_matrix_ushort * a, const double x); int gsl_matrix_ushort_add_constant (gsl_matrix_ushort * a, const double x); int gsl_matrix_ushort_add_diagonal (gsl_matrix_ushort * a, const double x); /***********************************************************************/ /* The functions below are obsolete */ /***********************************************************************/ int gsl_matrix_ushort_get_row(gsl_vector_ushort * v, const gsl_matrix_ushort * m, const size_t i); int gsl_matrix_ushort_get_col(gsl_vector_ushort * v, const gsl_matrix_ushort * m, const size_t j); int gsl_matrix_ushort_set_row(gsl_matrix_ushort * m, const size_t i, const gsl_vector_ushort * v); int gsl_matrix_ushort_set_col(gsl_matrix_ushort * m, const size_t j, const gsl_vector_ushort * v); /* inline functions if you are using GCC */ #ifdef HAVE_INLINE extern inline unsigned short gsl_matrix_ushort_get(const gsl_matrix_ushort * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_VAL("first index out of range", GSL_EINVAL, 0) ; } else if (j >= m->size2) { GSL_ERROR_VAL("second index out of range", GSL_EINVAL, 0) ; } #endif return m->data[i * m->tda + j] ; } extern inline void gsl_matrix_ushort_set(gsl_matrix_ushort * m, const size_t i, const size_t j, const unsigned short x) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; } #endif m->data[i * m->tda + j] = x ; } extern inline unsigned short * gsl_matrix_ushort_ptr(gsl_matrix_ushort * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (unsigned short *) (m->data + (i * m->tda + j)) ; } extern inline const unsigned short * gsl_matrix_ushort_const_ptr(const gsl_matrix_ushort * m, const size_t i, const size_t j) { #if GSL_RANGE_CHECK if (i >= m->size1) { GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; } else if (j >= m->size2) { GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; } #endif return (const unsigned short *) (m->data + (i * m->tda + j)) ; } #endif __END_DECLS #endif /* __GSL_MATRIX_USHORT_H__ */ praat-6.0.04/external/gsl/gsl_message.h000066400000000000000000000045601261542461700177760ustar00rootroot00000000000000/* err/gsl_message.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_MESSAGE_H__ #define __GSL_MESSAGE_H__ #include "gsl_types.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Provide a general messaging service for client use. Messages can * be selectively turned off at compile time by defining an * appropriate message mask. Client code which uses the GSL_MESSAGE() * macro must provide a mask which is or'ed with the GSL_MESSAGE_MASK. * * The messaging service can be completely turned off * by defining GSL_MESSAGING_OFF. */ void gsl_message(const char * message, const char * file, int line, unsigned int mask); #ifndef GSL_MESSAGE_MASK #define GSL_MESSAGE_MASK 0xffffffffu /* default all messages allowed */ #endif GSL_VAR unsigned int gsl_message_mask ; /* Provide some symolic masks for client ease of use. */ enum { GSL_MESSAGE_MASK_A = 1, GSL_MESSAGE_MASK_B = 2, GSL_MESSAGE_MASK_C = 4, GSL_MESSAGE_MASK_D = 8, GSL_MESSAGE_MASK_E = 16, GSL_MESSAGE_MASK_F = 32, GSL_MESSAGE_MASK_G = 64, GSL_MESSAGE_MASK_H = 128 } ; #ifdef GSL_MESSAGING_OFF /* throw away messages */ #define GSL_MESSAGE(message, mask) do { } while(0) #else /* output all messages */ #define GSL_MESSAGE(message, mask) \ do { \ if (mask & GSL_MESSAGE_MASK) \ gsl_message (message, __FILE__, __LINE__, mask) ; \ } while (0) #endif __END_DECLS #endif /* __GSL_MESSAGE_H__ */ praat-6.0.04/external/gsl/gsl_min.h000066400000000000000000000075601261542461700171400ustar00rootroot00000000000000/* min/gsl_min.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_MIN_H__ #define __GSL_MIN_H__ #include #include "gsl_types.h" #include "gsl_math.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { const char *name; size_t size; int (*set) (void *state, gsl_function * f, double x_minimum, double f_minimum, double x_lower, double f_lower, double x_upper, double f_upper); int (*iterate) (void *state, gsl_function * f, double * x_minimum, double * f_minimum, double * x_lower, double * f_lower, double * x_upper, double * f_upper); } gsl_min_fminimizer_type; typedef struct { const gsl_min_fminimizer_type * type; gsl_function * function ; double x_minimum ; double x_lower ; double x_upper ; double f_minimum, f_lower, f_upper; void *state; } gsl_min_fminimizer; gsl_min_fminimizer * gsl_min_fminimizer_alloc (const gsl_min_fminimizer_type * T) ; void gsl_min_fminimizer_free (gsl_min_fminimizer * s); int gsl_min_fminimizer_set (gsl_min_fminimizer * s, gsl_function * f, double x_minimum, double x_lower, double x_upper); int gsl_min_fminimizer_set_with_values (gsl_min_fminimizer * s, gsl_function * f, double x_minimum, double f_minimum, double x_lower, double f_lower, double x_upper, double f_upper); int gsl_min_fminimizer_iterate (gsl_min_fminimizer * s); const char * gsl_min_fminimizer_name (const gsl_min_fminimizer * s); double gsl_min_fminimizer_x_minimum (const gsl_min_fminimizer * s); double gsl_min_fminimizer_x_lower (const gsl_min_fminimizer * s); double gsl_min_fminimizer_x_upper (const gsl_min_fminimizer * s); double gsl_min_fminimizer_f_minimum (const gsl_min_fminimizer * s); double gsl_min_fminimizer_f_lower (const gsl_min_fminimizer * s); double gsl_min_fminimizer_f_upper (const gsl_min_fminimizer * s); /* Deprecated, use x_minimum instead */ double gsl_min_fminimizer_minimum (const gsl_min_fminimizer * s); int gsl_min_test_interval (double x_lower, double x_upper, double epsabs, double epsrel); GSL_VAR const gsl_min_fminimizer_type * gsl_min_fminimizer_goldensection; GSL_VAR const gsl_min_fminimizer_type * gsl_min_fminimizer_brent; typedef int (*gsl_min_bracketing_function)(gsl_function *f, double *x_minimum,double * f_minimum, double *x_lower, double * f_lower, double *x_upper, double * f_upper, size_t eval_max); int gsl_min_find_bracket(gsl_function *f,double *x_minimum,double * f_minimum, double *x_lower, double * f_lower, double *x_upper, double * f_upper, size_t eval_max); __END_DECLS #endif /* __GSL_MIN_H__ */ praat-6.0.04/external/gsl/gsl_min__bracketing.c000066400000000000000000000077471261542461700214720ustar00rootroot00000000000000/* min/bracketing.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Fabrice Rossi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* bracketing.c -- find an initial bracketing interval for a function to minimize */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_min.h" #include "gsl_machine.h" #include "gsl_min__min.h" int gsl_min_find_bracket(gsl_function *f,double *x_minimum,double * f_minimum, double * x_lower, double * f_lower, double * x_upper, double * f_upper, size_t eval_max) { /* The three following variables must be declared volatile to avoid storage in extended precision registers available on some architecture. The code relies on the ability to compare double values. As the values will be store in regular memory, the extended precision will then be lost and values that are different in extended precision might have equal representation in double precision. This behavior might break the algorithm. */ volatile double f_left = *f_lower; volatile double f_right = *f_upper; volatile double f_center; double x_left = *x_lower; double x_right= *x_upper; double x_center; const double golden = 0.3819660; /* golden = (3 - sqrt(5))/2 */ size_t nb_eval = 0; if (f_right >= f_left) { x_center = (x_right - x_left) * golden + x_left; nb_eval++; SAFE_FUNC_CALL (f, x_center, &f_center); } else { x_center = x_right ; f_center = f_right ; x_right = (x_center - x_left) / golden + x_left; nb_eval++; SAFE_FUNC_CALL (f, x_right, &f_right); } do { if (f_center < f_left ) { if (f_center < f_right) { *x_lower = x_left; *x_upper = x_right; *x_minimum = x_center; *f_lower = f_left; *f_upper = f_right; *f_minimum = f_center; /* gsl_ieee_printf_double (&f_left); printf(" "); gsl_ieee_printf_double (&f_center); printf("\n");*/ return GSL_SUCCESS; } else if (f_center > f_right) { x_left = x_center; f_left = f_center; x_center = x_right; f_center = f_right; x_right = (x_center - x_left) / golden + x_left; nb_eval++; SAFE_FUNC_CALL (f, x_right, &f_right); } else /* f_center == f_right */ { x_right = x_center; f_right = f_center; x_center = (x_right - x_left) * golden + x_left; nb_eval++; SAFE_FUNC_CALL (f, x_center, &f_center); } } else /* f_center >= f_left */ { x_right = x_center; f_right = f_center; x_center = (x_right - x_left) * golden + x_left; nb_eval++; SAFE_FUNC_CALL (f, x_center, &f_center); } } while (nb_eval < eval_max && (x_right - x_left) > GSL_SQRT_DBL_EPSILON * ( (x_right + x_left) * 0.5 ) + GSL_SQRT_DBL_EPSILON); *x_lower = x_left; *x_upper = x_right; *x_minimum = x_center; *f_lower = f_left; *f_upper = f_right; *f_minimum = f_center; return GSL_FAILURE; } praat-6.0.04/external/gsl/gsl_min__brent.c000066400000000000000000000117201261542461700204550ustar00rootroot00000000000000/* min/brent.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* brent.c -- brent minimum finding algorithm */ #include "gsl__config.h" #include #include #include #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_min.h" #include "gsl_min__min.h" typedef struct { double d, e, v, w; double f_v, f_w; } brent_state_t; static int brent_init (void *vstate, gsl_function * f, double x_minimum, double f_minimum, double x_lower, double f_lower, double x_upper, double f_upper); static int brent_iterate (void *vstate, gsl_function * f, double *x_minimum, double * f_minimum, double * x_lower, double * f_lower, double * x_upper, double * f_upper); static int brent_init (void *vstate, gsl_function * f, double x_minimum, double f_minimum, double x_lower, double f_lower, double x_upper, double f_upper) { brent_state_t *state = (brent_state_t *) vstate; const double golden = 0.3819660; /* golden = (3 - sqrt(5))/2 */ double v = x_lower + golden * (x_upper - x_lower); double w = v; double f_vw; x_minimum = 0 ; /* avoid warnings about unused varibles */ f_minimum = 0 ; f_lower = 0 ; f_upper = 0 ; state->v = v; state->w = w; state->d = 0; state->e = 0; SAFE_FUNC_CALL (f, v, &f_vw); state->f_v = f_vw; state->f_w = f_vw; return GSL_SUCCESS; } static int brent_iterate (void *vstate, gsl_function * f, double *x_minimum, double * f_minimum, double * x_lower, double * f_lower, double * x_upper, double * f_upper) { brent_state_t *state = (brent_state_t *) vstate; const double x_left = *x_lower; const double x_right = *x_upper; const double z = *x_minimum; double d = state->e; double e = state->d; double u, f_u; const double v = state->v; const double w = state->w; const double f_v = state->f_v; const double f_w = state->f_w; const double f_z = *f_minimum; const double golden = 0.3819660; /* golden = (3 - sqrt(5))/2 */ const double w_lower = (z - x_left); const double w_upper = (x_right - z); const double tolerance = GSL_SQRT_DBL_EPSILON * fabs (z); double p = 0, q = 0, r = 0; const double midpoint = 0.5 * (x_left + x_right); if (fabs (e) > tolerance) { /* fit parabola */ r = (z - w) * (f_z - f_v); q = (z - v) * (f_z - f_w); p = (z - v) * q - (z - w) * r; q = 2 * (q - r); if (q > 0) { p = -p; } else { q = -q; } r = e; e = d; } if (fabs (p) < fabs (0.5 * q * r) && p < q * w_lower && p < q * w_upper) { double t2 = 2 * tolerance ; d = p / q; u = z + d; if ((u - x_left) < t2 || (x_right - u) < t2) { d = (z < midpoint) ? tolerance : -tolerance ; } } else { e = (z < midpoint) ? x_right - z : -(z - x_left) ; d = golden * e; } if (fabs (d) >= tolerance) { u = z + d; } else { u = z + ((d > 0) ? tolerance : -tolerance) ; } state->e = e; state->d = d; SAFE_FUNC_CALL(f, u, &f_u); if (f_u <= f_z) { if (u < z) { *x_upper = z; *f_upper = f_z; } else { *x_lower = z; *f_lower = f_z; } state->v = w; state->f_v = f_w; state->w = z; state->f_w = f_z; *x_minimum = u; *f_minimum = f_u; return GSL_SUCCESS; } else { if (u < z) { *x_lower = u; *f_lower = f_u; return GSL_SUCCESS; } else { *x_upper = u; *f_upper = f_u; return GSL_SUCCESS; } if (f_u <= f_w || w == z) { state->v = w; state->f_v = f_w; state->w = u; state->f_w = f_u; return GSL_SUCCESS; } else if (f_u <= f_v || v == z || v == w) { state->v = u; state->f_v = f_u; return GSL_SUCCESS; } } return GSL_FAILURE; } static const gsl_min_fminimizer_type brent_type = {"brent", /* name */ sizeof (brent_state_t), &brent_init, &brent_iterate}; const gsl_min_fminimizer_type *gsl_min_fminimizer_brent = &brent_type; praat-6.0.04/external/gsl/gsl_min__convergence.c000066400000000000000000000033151261542461700216420ustar00rootroot00000000000000/* min/convergence.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_min.h" int gsl_min_test_interval (double x_lower, double x_upper, double epsabs, double epsrel) { const double lower = x_lower; const double upper = x_upper; const double abs_lower = fabs(lower) ; const double abs_upper = fabs(upper) ; double min_abs, tolerance; if (epsrel < 0.0) GSL_ERROR ("relative tolerance is negative", GSL_EBADTOL); if (epsabs < 0.0) GSL_ERROR ("absolute tolerance is negative", GSL_EBADTOL); if (lower > upper) GSL_ERROR ("lower bound larger than upper_bound", GSL_EINVAL); if ((lower > 0 && upper > 0) || (lower < 0 && upper < 0)) { min_abs = GSL_MIN_DBL(abs_lower, abs_upper) ; } else { min_abs = 0; } tolerance = epsabs + epsrel * min_abs ; if (fabs(upper - lower) < tolerance) return GSL_SUCCESS; return GSL_CONTINUE ; } praat-6.0.04/external/gsl/gsl_min__fsolver.c000066400000000000000000000116301261542461700210230ustar00rootroot00000000000000/* min/fsolver.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_errno.h" #include "gsl_min.h" #include "gsl_min__min.h" static int compute_f_values (gsl_function * f, double x_minimum, double * f_minimum, double x_lower, double * f_lower, double x_upper, double * f_upper); static int compute_f_values (gsl_function * f, double x_minimum, double * f_minimum, double x_lower, double * f_lower, double x_upper, double * f_upper) { SAFE_FUNC_CALL(f, x_lower, f_lower); SAFE_FUNC_CALL(f, x_upper, f_upper); SAFE_FUNC_CALL(f, x_minimum, f_minimum); return GSL_SUCCESS; } int gsl_min_fminimizer_set (gsl_min_fminimizer * s, gsl_function * f, double x_minimum, double x_lower, double x_upper) { int status ; double f_minimum, f_lower, f_upper; status = compute_f_values (f, x_minimum, &f_minimum, x_lower, &f_lower, x_upper, &f_upper); if (status != GSL_SUCCESS) { return status ; } status = gsl_min_fminimizer_set_with_values (s, f, x_minimum, f_minimum, x_lower, f_lower, x_upper, f_upper); return status; } gsl_min_fminimizer * gsl_min_fminimizer_alloc (const gsl_min_fminimizer_type * T) { gsl_min_fminimizer * s = (gsl_min_fminimizer *) malloc (sizeof (gsl_min_fminimizer)); if (s == 0) { GSL_ERROR_VAL ("failed to allocate space for minimizer struct", GSL_ENOMEM, 0); }; s->state = malloc (T->size); if (s->state == 0) { free (s); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for minimizer state", GSL_ENOMEM, 0); }; s->type = T ; s->function = NULL; return s; } int gsl_min_fminimizer_set_with_values (gsl_min_fminimizer * s, gsl_function * f, double x_minimum, double f_minimum, double x_lower, double f_lower, double x_upper, double f_upper) { s->function = f; s->x_minimum = x_minimum; s->x_lower = x_lower; s->x_upper = x_upper; if (x_lower > x_upper) { GSL_ERROR ("invalid interval (lower > upper)", GSL_EINVAL); } if (x_minimum >= x_upper || x_minimum <= x_lower) { GSL_ERROR ("x_minimum must lie inside interval (lower < x < upper)", GSL_EINVAL); } s->f_lower = f_lower; s->f_upper = f_upper; s->f_minimum = f_minimum; if (f_minimum >= f_lower || f_minimum >= f_upper) { GSL_ERROR ("endpoints do not enclose a minimum", GSL_EINVAL); } return (s->type->set) (s->state, s->function, x_minimum, f_minimum, x_lower, f_lower, x_upper, f_upper); } int gsl_min_fminimizer_iterate (gsl_min_fminimizer * s) { return (s->type->iterate) (s->state, s->function, &(s->x_minimum), &(s->f_minimum), &(s->x_lower), &(s->f_lower), &(s->x_upper), &(s->f_upper)); } void gsl_min_fminimizer_free (gsl_min_fminimizer * s) { free (s->state); free (s); } const char * gsl_min_fminimizer_name (const gsl_min_fminimizer * s) { return s->type->name; } /* Deprecated, use x_minimum instead */ double gsl_min_fminimizer_minimum (const gsl_min_fminimizer * s) { return s->x_minimum; } double gsl_min_fminimizer_x_minimum (const gsl_min_fminimizer * s) { return s->x_minimum; } double gsl_min_fminimizer_x_lower (const gsl_min_fminimizer * s) { return s->x_lower; } double gsl_min_fminimizer_x_upper (const gsl_min_fminimizer * s) { return s->x_upper; } double gsl_min_fminimizer_f_minimum (const gsl_min_fminimizer * s) { return s->f_minimum; } double gsl_min_fminimizer_f_lower (const gsl_min_fminimizer * s) { return s->f_lower; } double gsl_min_fminimizer_f_upper (const gsl_min_fminimizer * s) { return s->f_upper; } praat-6.0.04/external/gsl/gsl_min__golden.c000066400000000000000000000065571261542461700206270ustar00rootroot00000000000000/* min/golden.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* goldensection.c -- goldensection minimum finding algorithm */ #include "gsl__config.h" #include #include #include #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_min.h" #include "gsl_min__min.h" typedef struct { double dummy; } goldensection_state_t; static int goldensection_init (void * vstate, gsl_function * f, double x_minimum, double f_minimum, double x_lower, double f_lower, double x_upper, double f_upper); static int goldensection_iterate (void * vstate, gsl_function * f, double * x_minimum, double * f_minimum, double * x_lower, double * f_lower, double * x_upper, double * f_upper); static int goldensection_init (void * vstate, gsl_function * f, double x_minimum, double f_minimum, double x_lower, double f_lower, double x_upper, double f_upper) { goldensection_state_t * state = (goldensection_state_t *) vstate; /* no initialization required, prevent warnings about unused variables */ state = 0; f = 0; x_minimum = 0; f_minimum = 0; x_lower = 0; f_lower = 0; x_upper = 0; f_upper = 0; return GSL_SUCCESS; } static int goldensection_iterate (void * vstate, gsl_function * f, double * x_minimum, double * f_minimum, double * x_lower, double * f_lower, double * x_upper, double * f_upper) { goldensection_state_t * state = (goldensection_state_t *) vstate; const double x_center = *x_minimum ; const double x_left = *x_lower ; const double x_right = *x_upper ; const double f_min = *f_minimum; const double golden = 0.3819660; /* golden = (3 - sqrt(5))/2 */ const double w_lower = (x_center - x_left); const double w_upper = (x_right - x_center); double x_new, f_new; state = 0 ; /* avoid warning about unused parameters */ x_new = x_center + golden * ((w_upper > w_lower) ? w_upper : -w_lower) ; SAFE_FUNC_CALL (f, x_new, &f_new); if (f_new < f_min) { *x_minimum = x_new ; *f_minimum = f_new ; return GSL_SUCCESS; } else if (x_new < x_center && f_new > f_min) { *x_lower = x_new ; *f_lower = f_new ; return GSL_SUCCESS; } else if (x_new > x_center && f_new > f_min) { *x_upper = x_new ; *f_upper = f_new ; return GSL_SUCCESS; } else { return GSL_FAILURE; } } static const gsl_min_fminimizer_type goldensection_type = {"goldensection", /* name */ sizeof (goldensection_state_t), &goldensection_init, &goldensection_iterate}; const gsl_min_fminimizer_type * gsl_min_fminimizer_goldensection = &goldensection_type; praat-6.0.04/external/gsl/gsl_min__min.h000066400000000000000000000017431261542461700201370ustar00rootroot00000000000000/* min/min.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define SAFE_FUNC_CALL(f, x, yp) \ do { \ *yp = GSL_FN_EVAL(f,x); \ if (!gsl_finite(*yp)) \ GSL_ERROR("computed function value is infinite or NaN", GSL_EBADFUNC); \ } while (0) praat-6.0.04/external/gsl/gsl_mode.h000066400000000000000000000045171261542461700173000ustar00rootroot00000000000000/* gsl_mode.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: B. Gough and G. Jungman */ #ifndef __GSL_MODE_H__ #define __GSL_MODE_H__ #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Some functions can take a mode argument. This * is a rough method to do things like control * the precision of the algorithm. This mainly * occurs in special functions, but we figured * it was ok to have a general facility. * * The mode type is 32-bit field. Most of * the fields are currently unused. Users * '|' various predefined constants to get * a desired mode. */ typedef unsigned int gsl_mode_t; /* Here are the predefined constants. * Note that the precision constants * are special because they are used * to index arrays, so do not change * them. The precision information is * in the low order 3 bits of gsl_mode_t * (the third bit is currently unused). */ /* Note that "0" is double precision, * so that you get that by default if * you forget a flag. */ #define GSL_PREC_DOUBLE 0 #define GSL_PREC_SINGLE 1 #define GSL_PREC_APPROX 2 #ifdef HAVE_INLINE extern inline unsigned int GSL_MODE_PREC(gsl_mode_t mt); extern inline unsigned int GSL_MODE_PREC(gsl_mode_t mt) { return (mt & (unsigned int)7); } #else /* HAVE_INLINE */ #define GSL_MODE_PREC(mt) ((mt) & (unsigned int)7) #endif /* HAVE_INLINE */ /* Here are some predefined generic modes. */ #define GSL_MODE_DEFAULT 0 __END_DECLS #endif /* __GSL_MODE_H__ */ praat-6.0.04/external/gsl/gsl_monte.h000066400000000000000000000031011261542461700174620ustar00rootroot00000000000000/* monte/gsl_monte.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Michael Booth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Some things common to all the Monte-Carlo implementations */ /* Author: MJB */ #ifndef __GSL_MONTE_H__ #define __GSL_MONTE_H__ #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Hide the function type in a typedef so that we can use it in all our integration functions, and make it easy to change things. */ struct gsl_monte_function_struct { double (*f)(double * x_array, size_t dim, void * params); size_t dim; void * params; }; typedef struct gsl_monte_function_struct gsl_monte_function; #define GSL_MONTE_FN_EVAL(F,x) (*((F)->f))(x,(F)->dim,(F)->params) __END_DECLS #endif /* __GSL_MONTE_H__ */ praat-6.0.04/external/gsl/gsl_monte__miser.c000066400000000000000000000403721261542461700210260ustar00rootroot00000000000000/* monte/miser.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Michael Booth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* MISER. Based on the algorithm described in the following article, W.H. Press, G.R. Farrar, "Recursive Stratified Sampling for Multidimensional Monte Carlo Integration", Computers in Physics, v4 (1990), pp190-195. */ /* Author: MJB */ /* Modified by Brian Gough 12/2000 */ #include "gsl__config.h" #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_rng.h" #include "gsl_monte.h" #include "gsl_monte_miser.h" static int estimate_corrmc (gsl_monte_function * f, const double xl[], const double xu[], size_t dim, size_t calls, gsl_rng * r, gsl_monte_miser_state * state, double *result, double *abserr, const double xmid[], double sigma_l[], double sigma_r[]); int gsl_monte_miser_integrate (gsl_monte_function * f, const double xl[], const double xu[], size_t dim, size_t calls, gsl_rng * r, gsl_monte_miser_state * state, double *result, double *abserr) { size_t n, estimate_calls, calls_l, calls_r; const size_t min_calls = state->min_calls; size_t i; size_t i_bisect; int found_best; double res_est = 0, err_est = 0; double res_r = 0, err_r = 0, res_l = 0, err_l = 0; double xbi_l, xbi_m, xbi_r, s; double vol; double weight_l, weight_r; double *x = state->x; double *xmid = state->xmid; double *sigma_l = state->sigma_l, *sigma_r = state->sigma_r; if (dim != state->dim) { GSL_ERROR ("number of dimensions must match allocated size", GSL_EINVAL); } for (i = 0; i < dim; i++) { if (xu[i] <= xl[i]) { GSL_ERROR ("xu must be greater than xl", GSL_EINVAL); } if (xu[i] - xl[i] > GSL_DBL_MAX) { GSL_ERROR ("Range of integration is too large, please rescale", GSL_EINVAL); } } if (state->alpha < 0) { GSL_ERROR ("alpha must be non-negative", GSL_EINVAL); } /* Compute volume */ vol = 1; for (i = 0; i < dim; i++) { vol *= xu[i] - xl[i]; } if (calls < state->min_calls_per_bisection) { double m = 0.0, q = 0.0; if (calls < 2) { GSL_ERROR ("insufficient calls for subvolume", GSL_EFAILED); } for (n = 0; n < calls; n++) { /* Choose a random point in the integration region */ for (i = 0; i < dim; i++) { x[i] = xl[i] + gsl_rng_uniform_pos (r) * (xu[i] - xl[i]); } { double fval = GSL_MONTE_FN_EVAL (f, x); /* recurrence for mean and variance */ double d = fval - m; m += d / (n + 1.0); q += d * d * (n / (n + 1.0)); } } *result = vol * m; *abserr = vol * sqrt (q / (calls * (calls - 1.0))); return GSL_SUCCESS; } estimate_calls = GSL_MAX (min_calls, calls * (state->estimate_frac)); if (estimate_calls < 4 * dim) { GSL_ERROR ("insufficient calls to sample all halfspaces", GSL_ESANITY); } /* Flip coins to bisect the integration region with some fuzz */ for (i = 0; i < dim; i++) { s = (gsl_rng_uniform (r) - 0.5) >= 0.0 ? state->dither : -state->dither; state->xmid[i] = (0.5 + s) * xl[i] + (0.5 - s) * xu[i]; } /* The idea is to chose the direction to bisect based on which will give the smallest total variance. We could (and may do so later) use MC to compute these variances. But the NR guys simply estimate the variances by finding the min and max function values for each half-region for each bisection. */ estimate_corrmc (f, xl, xu, dim, estimate_calls, r, state, &res_est, &err_est, xmid, sigma_l, sigma_r); /* We have now used up some calls for the estimation */ calls -= estimate_calls; /* Now find direction with the smallest total "variance" */ { double best_var = GSL_DBL_MAX; double beta = 2.0 / (1.0 + state->alpha); found_best = 0; i_bisect = 0; weight_l = weight_r = 1.0; for (i = 0; i < dim; i++) { if (sigma_l[i] >= 0 && sigma_r[i] >= 0) { /* estimates are okay */ double var = pow (sigma_l[i], beta) + pow (sigma_r[i], beta); if (var <= best_var) { found_best = 1; best_var = var; i_bisect = i; weight_l = pow (sigma_l[i], beta); weight_r = pow (sigma_r[i], beta); } } else { if (sigma_l[i] < 0) { GSL_ERROR ("no points in left-half space!", GSL_ESANITY); } if (sigma_r[i] < 0) { GSL_ERROR ("no points in right-half space!", GSL_ESANITY); } } } } if (!found_best) { /* All estimates were the same, so chose a direction at random */ i_bisect = gsl_rng_uniform_int (r, dim); } xbi_l = xl[i_bisect]; xbi_m = xmid[i_bisect]; xbi_r = xu[i_bisect]; /* Get the actual fractional sizes of the two "halves", and distribute the remaining calls among them */ { double fraction_l = fabs ((xbi_m - xbi_l) / (xbi_r - xbi_l)); double fraction_r = 1 - fraction_l; double a = fraction_l * weight_l; double b = fraction_r * weight_r; calls_l = min_calls + (calls - 2 * min_calls) * a / (a + b); calls_r = min_calls + (calls - 2 * min_calls) * b / (a + b); } /* Compute the integral for the left hand side of the bisection */ /* Due to the recursive nature of the algorithm we must allocate some new memory for each recursive call */ { int status; double *xu_tmp = (double *) malloc (dim * sizeof (double)); if (xu_tmp == 0) { GSL_ERROR_VAL ("out of memory for left workspace", GSL_ENOMEM, 0); } for (i = 0; i < dim; i++) { xu_tmp[i] = xu[i]; } xu_tmp[i_bisect] = xbi_m; status = gsl_monte_miser_integrate (f, xl, xu_tmp, dim, calls_l, r, state, &res_l, &err_l); free (xu_tmp); if (status != GSL_SUCCESS) { return status; } } /* Compute the integral for the right hand side of the bisection */ { int status; double *xl_tmp = (double *) malloc (dim * sizeof (double)); if (xl_tmp == 0) { GSL_ERROR_VAL ("out of memory for right workspace", GSL_ENOMEM, 0); } for (i = 0; i < dim; i++) { xl_tmp[i] = xl[i]; } xl_tmp[i_bisect] = xbi_m; status = gsl_monte_miser_integrate (f, xl_tmp, xu, dim, calls_r, r, state, &res_r, &err_r); free (xl_tmp); if (status != GSL_SUCCESS) { return status; } } *result = res_l + res_r; *abserr = sqrt (err_l * err_l + err_r * err_r); return GSL_SUCCESS; } gsl_monte_miser_state * gsl_monte_miser_alloc (size_t dim) { gsl_monte_miser_state *s = (gsl_monte_miser_state *) malloc (sizeof (gsl_monte_miser_state)); if (s == 0) { GSL_ERROR_VAL ("failed to allocate space for miser state struct", GSL_ENOMEM, 0); } s->x = (double *) malloc (dim * sizeof (double)); if (s->x == 0) { free (s); GSL_ERROR_VAL ("failed to allocate space for x", GSL_ENOMEM, 0); } s->xmid = (double *) malloc (dim * sizeof (double)); if (s->xmid == 0) { free (s->x); free (s); GSL_ERROR_VAL ("failed to allocate space for xmid", GSL_ENOMEM, 0); } s->sigma_l = (double *) malloc (dim * sizeof (double)); if (s->sigma_l == 0) { free (s->xmid); free (s->x); free (s); GSL_ERROR_VAL ("failed to allocate space for sigma_l", GSL_ENOMEM, 0); } s->sigma_r = (double *) malloc (dim * sizeof (double)); if (s->sigma_r == 0) { free (s->sigma_l); free (s->xmid); free (s->x); free (s); GSL_ERROR_VAL ("failed to allocate space for sigma_r", GSL_ENOMEM, 0); } s->fmax_l = (double *) malloc (dim * sizeof (double)); if (s->fmax_l == 0) { free (s->sigma_r); free (s->sigma_l); free (s->xmid); free (s->x); free (s); GSL_ERROR_VAL ("failed to allocate space for fmax_l", GSL_ENOMEM, 0); } s->fmax_r = (double *) malloc (dim * sizeof (double)); if (s->fmax_r == 0) { free (s->fmax_l); free (s->sigma_r); free (s->sigma_l); free (s->xmid); free (s->x); free (s); GSL_ERROR_VAL ("failed to allocate space for fmax_r", GSL_ENOMEM, 0); } s->fmin_l = (double *) malloc (dim * sizeof (double)); if (s->fmin_l == 0) { free (s->fmax_r); free (s->fmax_l); free (s->sigma_r); free (s->sigma_l); free (s->xmid); free (s->x); free (s); GSL_ERROR_VAL ("failed to allocate space for fmin_l", GSL_ENOMEM, 0); } s->fmin_r = (double *) malloc (dim * sizeof (double)); if (s->fmin_r == 0) { free (s->fmin_l); free (s->fmax_r); free (s->fmax_l); free (s->sigma_r); free (s->sigma_l); free (s->xmid); free (s->x); free (s); GSL_ERROR_VAL ("failed to allocate space for fmin_r", GSL_ENOMEM, 0); } s->fsum_l = (double *) malloc (dim * sizeof (double)); if (s->fsum_l == 0) { free (s->fmin_r); free (s->fmin_l); free (s->fmax_r); free (s->fmax_l); free (s->sigma_r); free (s->sigma_l); free (s->xmid); free (s->x); free (s); GSL_ERROR_VAL ("failed to allocate space for fsum_l", GSL_ENOMEM, 0); } s->fsum_r = (double *) malloc (dim * sizeof (double)); if (s->fsum_r == 0) { free (s->fsum_l); free (s->fmin_r); free (s->fmin_l); free (s->fmax_r); free (s->fmax_l); free (s->sigma_r); free (s->sigma_l); free (s->xmid); free (s->x); free (s); GSL_ERROR_VAL ("failed to allocate space for fsum_r", GSL_ENOMEM, 0); } s->fsum2_l = (double *) malloc (dim * sizeof (double)); if (s->fsum2_l == 0) { free (s->fsum_r); free (s->fsum_l); free (s->fmin_r); free (s->fmin_l); free (s->fmax_r); free (s->fmax_l); free (s->sigma_r); free (s->sigma_l); free (s->xmid); free (s->x); free (s); GSL_ERROR_VAL ("failed to allocate space for fsum2_l", GSL_ENOMEM, 0); } s->fsum2_r = (double *) malloc (dim * sizeof (double)); if (s->fsum2_r == 0) { free (s->fsum2_l); free (s->fsum_r); free (s->fsum_l); free (s->fmin_r); free (s->fmin_l); free (s->fmax_r); free (s->fmax_l); free (s->sigma_r); free (s->sigma_l); free (s->xmid); free (s->x); free (s); GSL_ERROR_VAL ("failed to allocate space for fsum2_r", GSL_ENOMEM, 0); } s->hits_r = (size_t *) malloc (dim * sizeof (size_t)); if (s->hits_r == 0) { free (s->fsum2_r); free (s->fsum2_l); free (s->fsum_r); free (s->fsum_l); free (s->fmin_r); free (s->fmin_l); free (s->fmax_r); free (s->fmax_l); free (s->sigma_r); free (s->sigma_l); free (s->xmid); free (s->x); free (s); GSL_ERROR_VAL ("failed to allocate space for fsum2_r", GSL_ENOMEM, 0); } s->hits_l = (size_t *) malloc (dim * sizeof (size_t)); if (s->hits_l == 0) { free (s->hits_r); free (s->fsum2_r); free (s->fsum2_l); free (s->fsum_r); free (s->fsum_l); free (s->fmin_r); free (s->fmin_l); free (s->fmax_r); free (s->fmax_l); free (s->sigma_r); free (s->sigma_l); free (s->xmid); free (s->x); free (s); GSL_ERROR_VAL ("failed to allocate space for fsum2_r", GSL_ENOMEM, 0); } s->dim = dim; gsl_monte_miser_init (s); return s; } int gsl_monte_miser_init (gsl_monte_miser_state * s) { /* We use 8 points in each halfspace to estimate the variance. There are 2*dim halfspaces. A variance estimate requires a minimum of 2 points. */ s->min_calls = 16 * s->dim; s->min_calls_per_bisection = 32 * s->min_calls; s->estimate_frac = 0.1; s->alpha = 2.0; s->dither = 0.0; return GSL_SUCCESS; } void gsl_monte_miser_free (gsl_monte_miser_state * s) { free (s->hits_r); free (s->hits_l); free (s->fsum2_r); free (s->fsum2_l); free (s->fsum_r); free (s->fsum_l); free (s->fmin_r); free (s->fmin_l); free (s->fmax_r); free (s->fmax_l); free (s->sigma_r); free (s->sigma_l); free (s->xmid); free (s->x); free (s); } static int estimate_corrmc (gsl_monte_function * f, const double xl[], const double xu[], size_t dim, size_t calls, gsl_rng * r, gsl_monte_miser_state * state, double *result, double *abserr, const double xmid[], double sigma_l[], double sigma_r[]) { size_t i, n; double *x = state->x; double *fsum_l = state->fsum_l; double *fsum_r = state->fsum_r; double *fsum2_l = state->fsum2_l; double *fsum2_r = state->fsum2_r; size_t *hits_l = state->hits_l; size_t *hits_r = state->hits_r; double m = 0.0, q = 0.0; double vol = 1.0; for (i = 0; i < dim; i++) { vol *= xu[i] - xl[i]; hits_l[i] = hits_r[i] = 0; fsum_l[i] = fsum_r[i] = 0.0; fsum2_l[i] = fsum2_r[i] = 0.0; sigma_l[i] = sigma_r[i] = -1; } for (n = 0; n < calls; n++) { double fval; unsigned int j = (n/2) % dim; unsigned int side = (n % 2); for (i = 0; i < dim; i++) { double z = gsl_rng_uniform_pos (r) ; if (i != j) { x[i] = xl[i] + z * (xu[i] - xl[i]); } else { if (side == 0) { x[i] = xmid[i] + z * (xu[i] - xmid[i]); } else { x[i] = xl[i] + z * (xmid[i] - xl[i]); } } } fval = GSL_MONTE_FN_EVAL (f, x); /* recurrence for mean and variance */ { double d = fval - m; m += d / (n + 1.0); q += d * d * (n / (n + 1.0)); } /* compute the variances on each side of the bisection */ for (i = 0; i < dim; i++) { if (x[i] <= xmid[i]) { fsum_l[i] += fval; fsum2_l[i] += fval * fval; hits_l[i]++; } else { fsum_r[i] += fval; fsum2_r[i] += fval * fval; hits_r[i]++; } } } for (i = 0; i < dim; i++) { double fraction_l = (xmid[i] - xl[i]) / (xu[i] - xl[i]); if (hits_l[i] > 0) { fsum_l[i] /= hits_l[i]; sigma_l[i] = sqrt (fsum2_l[i] - fsum_l[i] * fsum_l[i] / hits_l[i]); sigma_l[i] *= fraction_l * vol / hits_l[i]; } if (hits_r[i] > 0) { fsum_r[i] /= hits_r[i]; sigma_r[i] = sqrt (fsum2_r[i] - fsum_r[i] * fsum_r[i] / hits_r[i]); sigma_r[i] *= (1 - fraction_l) * vol / hits_r[i]; } } *result = vol * m; if (calls < 2) { *abserr = GSL_POSINF; } else { *abserr = vol * sqrt (q / (calls * (calls - 1.0))); } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_monte__plain.c000066400000000000000000000065161261542461700210140ustar00rootroot00000000000000/* monte/plain.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Michael Booth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Plain Monte-Carlo. */ /* Author: MJB */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_rng.h" #include "gsl_monte_plain.h" int gsl_monte_plain_integrate (const gsl_monte_function * f, const double xl[], const double xu[], const size_t dim, const size_t calls, gsl_rng * r, gsl_monte_plain_state * state, double *result, double *abserr) { double vol, m = 0, q = 0; double *x = state->x; size_t n, i; if (dim != state->dim) { GSL_ERROR ("number of dimensions must match allocated size", GSL_EINVAL); } for (i = 0; i < dim; i++) { if (xu[i] <= xl[i]) { GSL_ERROR ("xu must be greater than xl", GSL_EINVAL); } if (xu[i] - xl[i] > GSL_DBL_MAX) { GSL_ERROR ("Range of integration is too large, please rescale", GSL_EINVAL); } } /* Compute the volume of the region */ vol = 1; for (i = 0; i < dim; i++) { vol *= xu[i] - xl[i]; } for (n = 0; n < calls; n++) { /* Choose a random point in the integration region */ for (i = 0; i < dim; i++) { x[i] = xl[i] + gsl_rng_uniform_pos (r) * (xu[i] - xl[i]); } { double fval = GSL_MONTE_FN_EVAL (f, x); /* recurrence for mean and variance */ double d = fval - m; m += d / (n + 1.0); q += d * d * (n / (n + 1.0)); } } *result = vol * m; if (calls < 2) { *abserr = GSL_POSINF; } else { *abserr = vol * sqrt (q / (calls * (calls - 1.0))); } return GSL_SUCCESS; } gsl_monte_plain_state * gsl_monte_plain_alloc (size_t dim) { gsl_monte_plain_state *s = (gsl_monte_plain_state *) malloc (sizeof (gsl_monte_plain_state)); if (s == 0) { GSL_ERROR_VAL ("failed to allocate space for state struct", GSL_ENOMEM, 0); } s->x = (double *) malloc (dim * sizeof (double)); if (s->x == 0) { free (s); GSL_ERROR_VAL ("failed to allocate space for working vector", GSL_ENOMEM, 0); } s->dim = dim; return s; } /* Set some default values and whatever */ int gsl_monte_plain_init (gsl_monte_plain_state * s) { size_t i; for (i = 0; i < s->dim; i++) { s->x[i] = 0.0; } return GSL_SUCCESS; } void gsl_monte_plain_free (gsl_monte_plain_state * s) { free (s->x); free (s); } praat-6.0.04/external/gsl/gsl_monte__vegas.c000066400000000000000000000516011261542461700210110ustar00rootroot00000000000000/* monte/vegas.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Michael Booth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: MJB */ /* Modified by: Brian Gough, 12/2000 */ /* This is an implementation of the adaptive Monte-Carlo algorithm of G. P. Lepage, originally described in J. Comp. Phys. 27, 192(1978). The current version of the algorithm was described in the Cornell preprint CLNS-80/447 of March, 1980. This code follows most closely the c version by D.R.Yennie, coded in 1984. The input coordinates are x[j], with upper and lower limits xu[j] and xl[j]. The integration length in the j-th direction is delx[j]. Each coordinate x[j] is rescaled to a variable y[j] in the range 0 to 1. The range is divided into bins with boundaries xi[i][j], where i=0 corresponds to y=0 and i=bins to y=1. The grid is refined (ie, bins are adjusted) using d[i][j] which is some variation on the squared sum. A third parameter used in defining the real coordinate using random numbers is called z. It ranges from 0 to bins. Its integer part gives the lower index of the bin into which a call is to be placed, and the remainder gives the location inside the bin. When stratified sampling is used the bins are grouped into boxes, and the algorithm allocates an equal number of function calls to each box. The variable alpha controls how "stiff" the rebinning algorithm is. alpha = 0 means never change the grid. Alpha is typically set between 1 and 2. */ /* configuration headers */ #include "gsl__config.h" /* standard headers */ #include #include /* gsl headers */ #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_rng.h" #include "gsl_monte_vegas.h" /* lib-specific headers */ #define BINS_MAX 50 /* even integer, will be divided by two */ /* A separable grid with coordinates and values */ #define COORD(s,i,j) ((s)->xi[(i)*(s)->dim + (j)]) #define NEW_COORD(s,i) ((s)->xin[(i)]) #define VALUE(s,i,j) ((s)->d[(i)*(s)->dim + (j)]) /* predeclare functions */ typedef int coord; static void init_grid (gsl_monte_vegas_state * s, double xl[], double xu[], size_t dim); static void reset_grid_values (gsl_monte_vegas_state * s); static void init_box_coord (gsl_monte_vegas_state * s, coord box[]); static int change_box_coord (gsl_monte_vegas_state * s, coord box[]); static void accumulate_distribution (gsl_monte_vegas_state * s, coord bin[], double y); static void random_point (double x[], coord bin[], double *bin_vol, const coord box[], const double xl[], const double xu[], gsl_monte_vegas_state * s, gsl_rng * r); static void resize_grid (gsl_monte_vegas_state * s, unsigned int bins); static void refine_grid (gsl_monte_vegas_state * s); static void print_lim (gsl_monte_vegas_state * state, double xl[], double xu[], unsigned long dim); static void print_head (gsl_monte_vegas_state * state, unsigned long num_dim, unsigned long calls, unsigned int it_num, unsigned int bins, unsigned int boxes); static void print_res (gsl_monte_vegas_state * state, unsigned int itr, double res, double err, double cum_res, double cum_err, double chi_sq); static void print_dist (gsl_monte_vegas_state * state, unsigned long dim); static void print_grid (gsl_monte_vegas_state * state, unsigned long dim); int gsl_monte_vegas_integrate (gsl_monte_function * f, double xl[], double xu[], size_t dim, size_t calls, gsl_rng * r, gsl_monte_vegas_state * state, double *result, double *abserr) { double cum_int, cum_sig; size_t i, k, it; if (dim != state->dim) { GSL_ERROR ("number of dimensions must match allocated size", GSL_EINVAL); } for (i = 0; i < dim; i++) { if (xu[i] <= xl[i]) { GSL_ERROR ("xu must be greater than xl", GSL_EINVAL); } if (xu[i] - xl[i] > GSL_DBL_MAX) { GSL_ERROR ("Range of integration is too large, please rescale", GSL_EINVAL); } } if (state->stage == 0) { init_grid (state, xl, xu, dim); if (state->verbose >= 0) { print_lim (state, xl, xu, dim); } } if (state->stage <= 1) { state->wtd_int_sum = 0; state->sum_wgts = 0; state->chi_sum = 0; state->it_num = 1; state->samples = 0; } if (state->stage <= 2) { unsigned int bins = state->bins_max; unsigned int boxes = 1; if (state->mode != GSL_VEGAS_MODE_IMPORTANCE_ONLY) { /* shooting for 2 calls/box */ boxes = floor (pow (calls / 2.0, 1.0 / dim)); state->mode = GSL_VEGAS_MODE_IMPORTANCE; if (2 * boxes >= state->bins_max) { /* if bins/box < 2 */ int box_per_bin = GSL_MAX (boxes / state->bins_max, 1); bins = GSL_MIN(boxes / box_per_bin, state->bins_max); boxes = box_per_bin * bins; state->mode = GSL_VEGAS_MODE_STRATIFIED; } } { double tot_boxes = pow ((double) boxes, (double) dim); state->calls_per_box = GSL_MAX (calls / tot_boxes, 2); calls = state->calls_per_box * tot_boxes; } /* total volume of x-space/(avg num of calls/bin) */ state->jac = state->vol * pow ((double) bins, (double) dim) / calls; state->boxes = boxes; /* If the number of bins changes from the previous invocation, bins are expanded or contracted accordingly, while preserving bin density */ if (bins != state->bins) { resize_grid (state, bins); if (state->verbose > 1) { print_grid (state, dim); } } if (state->verbose >= 0) { print_head (state, dim, calls, state->it_num, state->bins, state->boxes); } } state->it_start = state->it_num; cum_int = 0.0; cum_sig = 0.0; state->chisq = 0.0; for (it = 0; it < state->iterations; it++) { double intgrl = 0.0, intgrl_sq = 0.0; double sig = 0.0; double wgt; size_t calls_per_box = state->calls_per_box; double jacbin = state->jac; double *x = state->x; coord *bin = state->bin; state->it_num = state->it_start + it; reset_grid_values (state); init_box_coord (state, state->box); do { double m = 0, q = 0; double f_sq_sum = 0.0; for (k = 0; k < calls_per_box; k++) { double fval, bin_vol; random_point (x, bin, &bin_vol, state->box, xl, xu, state, r); fval = jacbin * bin_vol * GSL_MONTE_FN_EVAL (f, x); /* recurrence for mean and variance */ { double d = fval - m; m += d / (k + 1.0); q += d * d * (k / (k + 1.0)); } if (state->mode != GSL_VEGAS_MODE_STRATIFIED) { double f_sq = fval * fval; accumulate_distribution (state, bin, f_sq); } } intgrl += m * calls_per_box; f_sq_sum = q * calls_per_box ; sig += f_sq_sum ; if (state->mode == GSL_VEGAS_MODE_STRATIFIED) { accumulate_distribution (state, bin, f_sq_sum); } } while (change_box_coord (state, state->box)); /* Compute final results for this iteration */ sig = sig / (calls_per_box - 1.0) ; if (sig > 0) { wgt = 1.0 / sig; } else if (state->sum_wgts > 0) { wgt = state->sum_wgts / state->samples; } else { wgt = 0.0; } intgrl_sq = intgrl * intgrl; state->result = intgrl; state->sigma = sqrt(sig); if (wgt > 0.0) { state->samples++ ; state->sum_wgts += wgt; state->wtd_int_sum += intgrl * wgt; state->chi_sum += intgrl_sq * wgt; cum_int = state->wtd_int_sum / state->sum_wgts; cum_sig = sqrt (1 / state->sum_wgts); if (state->samples > 1) { state->chisq = (state->chi_sum - state->wtd_int_sum * cum_int) / (state->samples - 1.0); } } else { cum_int += (intgrl - cum_int) / (it + 1.0); cum_sig = 0.0; } if (state->verbose >= 0) { print_res (state, state->it_num, intgrl, sqrt (sig), cum_int, cum_sig, state->chisq); if (it + 1 == state->iterations && state->verbose > 0) { print_grid (state, dim); } } if (state->verbose > 1) { print_dist (state, dim); } refine_grid (state); if (state->verbose > 1) { print_grid (state, dim); } } /* By setting stage to 1 further calls will generate independent estimates based on the same grid, although it may be rebinned. */ state->stage = 1; *result = cum_int; *abserr = cum_sig; return GSL_SUCCESS; } gsl_monte_vegas_state * gsl_monte_vegas_alloc (size_t dim) { gsl_monte_vegas_state *s = (gsl_monte_vegas_state *) malloc (sizeof (gsl_monte_vegas_state)); if (s == 0) { GSL_ERROR_VAL ("failed to allocate space for vegas state struct", GSL_ENOMEM, 0); } s->delx = (double *) malloc (dim * sizeof (double)); if (s->delx == 0) { free (s); GSL_ERROR_VAL ("failed to allocate space for delx", GSL_ENOMEM, 0); } s->d = (double *) malloc (BINS_MAX * dim * sizeof (double)); if (s->d == 0) { free (s->delx); free (s); GSL_ERROR_VAL ("failed to allocate space for d", GSL_ENOMEM, 0); } s->xi = (double *) malloc ((BINS_MAX + 1) * dim * sizeof (double)); if (s->xi == 0) { free (s->d); free (s->delx); free (s); GSL_ERROR_VAL ("failed to allocate space for xi", GSL_ENOMEM, 0); } s->xin = (double *) malloc ((BINS_MAX + 1) * sizeof (double)); if (s->xin == 0) { free (s->xi); free (s->d); free (s->delx); free (s); GSL_ERROR_VAL ("failed to allocate space for xin", GSL_ENOMEM, 0); } s->weight = (double *) malloc (BINS_MAX * sizeof (double)); if (s->weight == 0) { free (s->xin); free (s->xi); free (s->d); free (s->delx); free (s); GSL_ERROR_VAL ("failed to allocate space for xin", GSL_ENOMEM, 0); } s->box = (coord *) malloc (dim * sizeof (coord)); if (s->box == 0) { free (s->weight); free (s->xin); free (s->xi); free (s->d); free (s->delx); free (s); GSL_ERROR_VAL ("failed to allocate space for box", GSL_ENOMEM, 0); } s->bin = (coord *) malloc (dim * sizeof (coord)); if (s->bin == 0) { free (s->box); free (s->weight); free (s->xin); free (s->xi); free (s->d); free (s->delx); free (s); GSL_ERROR_VAL ("failed to allocate space for bin", GSL_ENOMEM, 0); } s->x = (double *) malloc (dim * sizeof (double)); if (s->x == 0) { free (s->bin); free (s->box); free (s->weight); free (s->xin); free (s->xi); free (s->d); free (s->delx); free (s); GSL_ERROR_VAL ("failed to allocate space for x", GSL_ENOMEM, 0); } s->dim = dim; s->bins_max = BINS_MAX; gsl_monte_vegas_init (s); return s; } /* Set some default values and whatever */ int gsl_monte_vegas_init (gsl_monte_vegas_state * state) { state->stage = 0; state->alpha = 1.5; state->verbose = -1; state->iterations = 5; state->mode = GSL_VEGAS_MODE_IMPORTANCE; state->chisq = 0; state->bins = state->bins_max; state->ostream = stdout; return GSL_SUCCESS; } void gsl_monte_vegas_free (gsl_monte_vegas_state * s) { free (s->x); free (s->delx); free (s->d); free (s->xi); free (s->xin); free (s->weight); free (s->box); free (s->bin); free (s); } static void init_box_coord (gsl_monte_vegas_state * s, coord box[]) { size_t i; size_t dim = s->dim; for (i = 0; i < dim; i++) { box[i] = 0; } } /* change_box_coord steps through the box coord like {0,0}, {0, 1}, {0, 2}, {0, 3}, {1, 0}, {1, 1}, {1, 2}, ... */ static int change_box_coord (gsl_monte_vegas_state * s, coord box[]) { int j = s->dim - 1; int ng = s->boxes; while (j >= 0) { box[j] = (box[j] + 1) % ng; if (box[j] != 0) { return 1; } j--; } return 0; } static void init_grid (gsl_monte_vegas_state * s, double xl[], double xu[], size_t dim) { size_t j; double vol = 1.0; s->bins = 1; for (j = 0; j < dim; j++) { double dx = xu[j] - xl[j]; s->delx[j] = dx; vol *= dx; COORD (s, 0, j) = 0.0; COORD (s, 1, j) = 1.0; } s->vol = vol; } static void reset_grid_values (gsl_monte_vegas_state * s) { size_t i, j; size_t dim = s->dim; size_t bins = s->bins; for (i = 0; i < bins; i++) { for (j = 0; j < dim; j++) { VALUE (s, i, j) = 0.0; } } } static void accumulate_distribution (gsl_monte_vegas_state * s, coord bin[], double y) { size_t j; size_t dim = s->dim; for (j = 0; j < dim; j++) { int i = bin[j]; VALUE (s, i, j) += y; } } static void random_point (double x[], coord bin[], double *bin_vol, const coord box[], const double xl[], const double xu[], gsl_monte_vegas_state * s, gsl_rng * r) { /* Use the random number generator r to return a random position x in a given box. The value of bin gives the bin location of the random position (there may be several bins within a given box) */ double vol = 1.0; size_t j; size_t dim = s->dim; size_t bins = s->bins; size_t boxes = s->boxes; DISCARD_POINTER(xu); /* prevent warning about unused parameter */ for (j = 0; j < dim; ++j) { /* box[j] + ran gives the position in the box units, while z is the position in bin units. */ double z = ((box[j] + gsl_rng_uniform_pos (r)) / boxes) * bins; int k = z; double y, bin_width; bin[j] = k; if (k == 0) { bin_width = COORD (s, 1, j); y = z * bin_width; } else { bin_width = COORD (s, k + 1, j) - COORD (s, k, j); y = COORD (s, k, j) + (z - k) * bin_width; } x[j] = xl[j] + y * s->delx[j]; vol *= bin_width; } *bin_vol = vol; } static void resize_grid (gsl_monte_vegas_state * s, unsigned int bins) { size_t j, k; size_t dim = s->dim; /* weight is ratio of bin sizes */ double pts_per_bin = (double) s->bins / (double) bins; for (j = 0; j < dim; j++) { double xold; double xnew = 0; double dw = 0; int i = 1; for (k = 1; k <= s->bins; k++) { dw += 1.0; xold = xnew; xnew = COORD (s, k, j); for (; dw > pts_per_bin; i++) { dw -= pts_per_bin; NEW_COORD (s, i) = xnew - (xnew - xold) * dw; } } for (k = 1 ; k < bins; k++) { COORD(s, k, j) = NEW_COORD(s, k); } COORD (s, bins, j) = 1; } s->bins = bins; } static void refine_grid (gsl_monte_vegas_state * s) { size_t i, j, k; size_t dim = s->dim; size_t bins = s->bins; for (j = 0; j < dim; j++) { double grid_tot_j, tot_weight; double * weight = s->weight; double oldg = VALUE (s, 0, j); double newg = VALUE (s, 1, j); VALUE (s, 0, j) = (oldg + newg) / 2; grid_tot_j = VALUE (s, 0, j); /* This implements gs[i][j] = (gs[i-1][j]+gs[i][j]+gs[i+1][j])/3 */ for (i = 1; i < bins - 1; i++) { double rc = oldg + newg; oldg = newg; newg = VALUE (s, i + 1, j); VALUE (s, i, j) = (rc + newg) / 3; grid_tot_j += VALUE (s, i, j); } VALUE (s, bins - 1, j) = (newg + oldg) / 2; grid_tot_j += VALUE (s, bins - 1, j); tot_weight = 0; for (i = 0; i < bins; i++) { weight[i] = 0; if (VALUE (s, i, j) > 0) { oldg = grid_tot_j / VALUE (s, i, j); /* damped change */ weight[i] = pow (((oldg - 1) / oldg / log (oldg)), s->alpha); } tot_weight += weight[i]; #ifdef DEBUG printf("weight[%d] = %g\n", i, weight[i]); #endif } { double pts_per_bin = tot_weight / bins; double xold; double xnew = 0; double dw = 0; i = 1; for (k = 0; k < bins; k++) { dw += weight[k]; xold = xnew; xnew = COORD (s, k + 1, j); for (; dw > pts_per_bin; i++) { dw -= pts_per_bin; NEW_COORD (s, i) = xnew - (xnew - xold) * dw / weight[k]; } } for (k = 1 ; k < bins ; k++) { COORD(s, k, j) = NEW_COORD(s, k); } COORD (s, bins, j) = 1; } } } static void print_lim (gsl_monte_vegas_state * state, double xl[], double xu[], unsigned long dim) { unsigned long j; fprintf (state->ostream, "The limits of integration are:\n"); for (j = 0; j < dim; ++j) fprintf (state->ostream, "\nxl[%lu]=%f xu[%lu]=%f", j, xl[j], j, xu[j]); fprintf (state->ostream, "\n"); fflush (state->ostream); } static void print_head (gsl_monte_vegas_state * state, unsigned long num_dim, unsigned long calls, unsigned int it_num, unsigned int bins, unsigned int boxes) { fprintf (state->ostream, "\nnum_dim=%lu, calls=%lu, it_num=%d, max_it_num=%d ", num_dim, calls, it_num, state->iterations); fprintf (state->ostream, "verb=%d, alph=%.2f,\nmode=%d, bins=%d, boxes=%d\n", state->verbose, state->alpha, state->mode, bins, boxes); fprintf (state->ostream, "\n single.......iteration "); fprintf (state->ostream, "accumulated......results \n"); fprintf (state->ostream, "iteration integral sigma integral "); fprintf (state->ostream, " sigma chi-sq/it\n\n"); fflush (state->ostream); } static void print_res (gsl_monte_vegas_state * state, unsigned int itr, double res, double err, double cum_res, double cum_err, double chi_sq) { fprintf (state->ostream, "%4d %6.4e %10.2e %6.4e %8.2e %10.2e\n", itr, res, err, cum_res, cum_err, chi_sq); fflush (state->ostream); } static void print_dist (gsl_monte_vegas_state * state, unsigned long dim) { unsigned long i, j; int p = state->verbose; if (p < 1) return; for (j = 0; j < dim; ++j) { fprintf (state->ostream, "\n axis %lu \n", j); fprintf (state->ostream, " x g\n"); for (i = 0; i < state->bins; i++) { fprintf (state->ostream, "weight [%11.2e , %11.2e] = ", COORD (state, i, j), COORD(state,i+1,j)); fprintf (state->ostream, " %11.2e\n", VALUE (state, i, j)); } fprintf (state->ostream, "\n"); } fprintf (state->ostream, "\n"); fflush (state->ostream); } static void print_grid (gsl_monte_vegas_state * state, unsigned long dim) { unsigned long i, j; int p = state->verbose; if (p < 1) return; for (j = 0; j < dim; ++j) { fprintf (state->ostream, "\n axis %lu \n", j); fprintf (state->ostream, " x \n"); for (i = 0; i <= state->bins; i++) { fprintf (state->ostream, "%11.2e", COORD (state, i, j)); if (i % 5 == 4) fprintf (state->ostream, "\n"); } fprintf (state->ostream, "\n"); } fprintf (state->ostream, "\n"); fflush (state->ostream); } praat-6.0.04/external/gsl/gsl_monte_miser.h000066400000000000000000000043021261542461700206650ustar00rootroot00000000000000/* monte/gsl_monte_miser.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Michael Booth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: MJB */ #ifndef __GSL_MONTE_MISER_H__ #define __GSL_MONTE_MISER_H__ #include "gsl_rng.h" #include "gsl_monte.h" #include "gsl_monte_plain.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t min_calls; size_t min_calls_per_bisection; double dither; double estimate_frac; double alpha; size_t dim; int estimate_style; int depth; int verbose; double * x; double * xmid; double * sigma_l; double * sigma_r; double * fmax_l; double * fmax_r; double * fmin_l; double * fmin_r; double * fsum_l; double * fsum_r; double * fsum2_l; double * fsum2_r; size_t * hits_l; size_t * hits_r; } gsl_monte_miser_state; int gsl_monte_miser_integrate(gsl_monte_function * f, const double xl[], const double xh[], size_t dim, size_t calls, gsl_rng *r, gsl_monte_miser_state* state, double *result, double *abserr); gsl_monte_miser_state* gsl_monte_miser_alloc(size_t dim); int gsl_monte_miser_init(gsl_monte_miser_state* state); void gsl_monte_miser_free(gsl_monte_miser_state* state); __END_DECLS #endif /* __GSL_MONTE_MISER_H__ */ praat-6.0.04/external/gsl/gsl_monte_plain.h000066400000000000000000000035241261542461700206560ustar00rootroot00000000000000/* monte/gsl_monte_plain.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Michael Booth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Plain Monte-Carlo. */ /* Author: MJB */ #ifndef __GSL_MONTE_PLAIN_H__ #define __GSL_MONTE_PLAIN_H__ #include #include "gsl_monte.h" #include "gsl_rng.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t dim; double *x; } gsl_monte_plain_state; int gsl_monte_plain_integrate (const gsl_monte_function * f, const double xl[], const double xu[], const size_t dim, const size_t calls, gsl_rng * r, gsl_monte_plain_state * state, double *result, double *abserr); gsl_monte_plain_state* gsl_monte_plain_alloc(size_t dim); int gsl_monte_plain_init(gsl_monte_plain_state* state); void gsl_monte_plain_free (gsl_monte_plain_state* state); __END_DECLS #endif /* __GSL_MONTE_PLAIN_H__ */ praat-6.0.04/external/gsl/gsl_monte_vegas.h000066400000000000000000000051261261542461700206600ustar00rootroot00000000000000/* monte/gsl_monte_vegas.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Michael Booth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* header for the gsl "vegas" routines. Mike Booth, May 1998 */ #ifndef __GSL_MONTE_VEGAS_H__ #define __GSL_MONTE_VEGAS_H__ #include "gsl_rng.h" #include "gsl_monte.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS enum {GSL_VEGAS_MODE_IMPORTANCE = 1, GSL_VEGAS_MODE_IMPORTANCE_ONLY = 0, GSL_VEGAS_MODE_STRATIFIED = -1}; typedef struct { /* grid */ size_t dim; size_t bins_max; unsigned int bins; unsigned int boxes; /* these are both counted along the axes */ double * xi; double * xin; double * delx; double * weight; double vol; double * x; int * bin; int * box; /* distribution */ double * d; /* control variables */ double alpha; int mode; int verbose; unsigned int iterations; int stage; /* scratch variables preserved between calls to vegas1/2/3 */ double jac; double wtd_int_sum; double sum_wgts; double chi_sum; double chisq; double result; double sigma; unsigned int it_start; unsigned int it_num; unsigned int samples; unsigned int calls_per_box; FILE * ostream; } gsl_monte_vegas_state; int gsl_monte_vegas_integrate(gsl_monte_function * f, double xl[], double xu[], size_t dim, size_t calls, gsl_rng * r, gsl_monte_vegas_state *state, double* result, double* abserr); gsl_monte_vegas_state* gsl_monte_vegas_alloc(size_t dim); int gsl_monte_vegas_init(gsl_monte_vegas_state* state); void gsl_monte_vegas_free (gsl_monte_vegas_state* state); __END_DECLS #endif /* __GSL_MONTE_VEGAS_H__ */ praat-6.0.04/external/gsl/gsl_multifit.h000066400000000000000000000061301261542461700202020ustar00rootroot00000000000000/* multifit/gsl_multifit.h * * Copyright (C) 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_MULTIFIT_H__ #define __GSL_MULTIFIT_H__ #include #include "gsl_math.h" #include "gsl_vector.h" #include "gsl_matrix.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t n; /* number of observations */ size_t p; /* number of parameters */ gsl_matrix * A; gsl_matrix * Q; gsl_matrix * QSI; gsl_vector * S; gsl_vector * t; gsl_vector * xt; gsl_vector * D; } gsl_multifit_linear_workspace; gsl_multifit_linear_workspace * gsl_multifit_linear_alloc (size_t n, size_t p); void gsl_multifit_linear_free (gsl_multifit_linear_workspace * work); int gsl_multifit_linear (const gsl_matrix * X, const gsl_vector * y, gsl_vector * c, gsl_matrix * cov, double * chisq, gsl_multifit_linear_workspace * work); int gsl_multifit_linear_svd (const gsl_matrix * X, const gsl_vector * y, double tol, size_t * rank, gsl_vector * c, gsl_matrix * cov, double *chisq, gsl_multifit_linear_workspace * work); int gsl_multifit_wlinear (const gsl_matrix * X, const gsl_vector * w, const gsl_vector * y, gsl_vector * c, gsl_matrix * cov, double * chisq, gsl_multifit_linear_workspace * work); int gsl_multifit_wlinear_svd (const gsl_matrix * X, const gsl_vector * w, const gsl_vector * y, double tol, size_t * rank, gsl_vector * c, gsl_matrix * cov, double *chisq, gsl_multifit_linear_workspace * work); int gsl_multifit_linear_est (const gsl_vector * x, const gsl_vector * c, const gsl_matrix * cov, double *y, double *y_err); __END_DECLS #endif /* __GSL_MULTIFIT_H__ */ praat-6.0.04/external/gsl/gsl_multifit__convergence.c000066400000000000000000000037601261542461700227200ustar00rootroot00000000000000/* multifit/convergence.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_multifit_nlin.h" int gsl_multifit_test_delta (const gsl_vector * dx, const gsl_vector * x, double epsabs, double epsrel) { size_t i; int ok = 1; const size_t n = x->size ; if (epsrel < 0.0) { GSL_ERROR ("relative tolerance is negative", GSL_EBADTOL); } for (i = 0 ; i < n ; i++) { double xi = gsl_vector_get(x,i); double dxi = gsl_vector_get(dx,i); double tolerance = epsabs + epsrel * fabs(xi) ; if (fabs(dxi) < tolerance) { ok = 1; } else { ok = 0; break; } } if (ok) return GSL_SUCCESS ; return GSL_CONTINUE; } int gsl_multifit_test_gradient (const gsl_vector * g, double epsabs) { size_t i; double residual = 0; const size_t n = g->size; if (epsabs < 0.0) { GSL_ERROR ("absolute tolerance is negative", GSL_EBADTOL); } for (i = 0 ; i < n ; i++) { double gi = gsl_vector_get(g, i); residual += fabs(gi); } if (residual < epsabs) { return GSL_SUCCESS; } return GSL_CONTINUE ; } praat-6.0.04/external/gsl/gsl_multifit__covar.c000066400000000000000000000107071261542461700215330ustar00rootroot00000000000000/* multifit/covar.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_linalg.h" #include "gsl_multifit_nlin.h" /* Compute the covariance matrix cov = inv (J^T J) by QRP^T decomposition of J */ int gsl_multifit_covar (const gsl_matrix * J, double epsrel, gsl_matrix * covar) { double tolr; size_t i, j, k; size_t kmax = 0; gsl_matrix * r; gsl_vector * tau; gsl_vector * norm; gsl_permutation * perm; size_t m = J->size1, n = J->size2 ; if (m < n) { GSL_ERROR ("Jacobian be rectangular M x N with M >= N", GSL_EBADLEN); } if (covar->size1 != covar->size2 || covar->size1 != n) { GSL_ERROR ("covariance matrix must be square and match second dimension of jacobian", GSL_EBADLEN); } r = gsl_matrix_alloc (m, n); tau = gsl_vector_alloc (n); perm = gsl_permutation_alloc (n) ; norm = gsl_vector_alloc (n) ; { int signum = 0; gsl_matrix_memcpy (r, J); gsl_linalg_QRPT_decomp (r, tau, perm, &signum, norm); } /* Form the inverse of R in the full upper triangle of R */ tolr = epsrel * fabs(gsl_matrix_get(r, 0, 0)); for (k = 0 ; k < n ; k++) { double rkk = gsl_matrix_get(r, k, k); if (fabs(rkk) <= tolr) { break; } gsl_matrix_set(r, k, k, 1.0/rkk); for (j = 0; j < k ; j++) { double t = gsl_matrix_get(r, j, k) / rkk; gsl_matrix_set (r, j, k, 0.0); for (i = 0; i <= j; i++) { double rik = gsl_matrix_get (r, i, k); double rij = gsl_matrix_get (r, i, j); gsl_matrix_set (r, i, k, rik - t * rij); } } kmax = k; } /* Form the full upper triangle of the inverse of R^T R in the full upper triangle of R */ for (k = 0; k <= kmax ; k++) { for (j = 0; j < k; j++) { double rjk = gsl_matrix_get (r, j, k); for (i = 0; i <= j ; i++) { double rij = gsl_matrix_get (r, i, j); double rik = gsl_matrix_get (r, i, k); gsl_matrix_set (r, i, j, rij + rjk * rik); } } { double t = gsl_matrix_get (r, k, k); for (i = 0; i <= k; i++) { double rik = gsl_matrix_get (r, i, k); gsl_matrix_set (r, i, k, t * rik); }; } } /* Form the full lower triangle of the covariance matrix in the strict lower triangle of R and in w */ for (j = 0 ; j < n ; j++) { size_t pj = gsl_permutation_get (perm, j); for (i = 0; i <= j; i++) { size_t pi = gsl_permutation_get (perm, i); double rij; if (j > kmax) { gsl_matrix_set (r, i, j, 0.0); rij = 0.0 ; } else { rij = gsl_matrix_get (r, i, j); } if (pi > pj) { gsl_matrix_set (r, pi, pj, rij); } else if (pi < pj) { gsl_matrix_set (r, pj, pi, rij); } } { double rjj = gsl_matrix_get (r, j, j); gsl_matrix_set (covar, pj, pj, rjj); } } /* symmetrize the covariance matrix */ for (j = 0 ; j < n ; j++) { for (i = 0; i < j ; i++) { double rji = gsl_matrix_get (r, j, i); gsl_matrix_set (covar, j, i, rji); gsl_matrix_set (covar, i, j, rji); } } gsl_matrix_free (r); gsl_permutation_free (perm); gsl_vector_free (tau); gsl_vector_free (norm); return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_multifit__fdfsolver.c000066400000000000000000000100501261542461700224020ustar00rootroot00000000000000/* multifit/fdfsolver.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_errno.h" #include "gsl_multifit_nlin.h" gsl_multifit_fdfsolver * gsl_multifit_fdfsolver_alloc (const gsl_multifit_fdfsolver_type * T, size_t n, size_t p) { int status; gsl_multifit_fdfsolver * s; if (n < p) { GSL_ERROR_VAL ("insufficient data points, n < p", GSL_EINVAL, 0); } s = (gsl_multifit_fdfsolver *) malloc (sizeof (gsl_multifit_fdfsolver)); if (s == 0) { GSL_ERROR_VAL ("failed to allocate space for multifit solver struct", GSL_ENOMEM, 0); } s->x = gsl_vector_calloc (p); if (s->x == 0) { free (s); GSL_ERROR_VAL ("failed to allocate space for x", GSL_ENOMEM, 0); } s->f = gsl_vector_calloc (n); if (s->f == 0) { gsl_vector_free (s->x); free (s); GSL_ERROR_VAL ("failed to allocate space for f", GSL_ENOMEM, 0); } s->J = gsl_matrix_calloc (n,p); if (s->J == 0) { gsl_vector_free (s->x); gsl_vector_free (s->f); free (s); GSL_ERROR_VAL ("failed to allocate space for g", GSL_ENOMEM, 0); } s->dx = gsl_vector_calloc (p); if (s->dx == 0) { gsl_matrix_free (s->J); gsl_vector_free (s->x); gsl_vector_free (s->f); free (s); GSL_ERROR_VAL ("failed to allocate space for dx", GSL_ENOMEM, 0); } s->state = malloc (T->size); if (s->state == 0) { gsl_vector_free (s->dx); gsl_vector_free (s->x); gsl_vector_free (s->f); gsl_matrix_free (s->J); free (s); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for multifit solver state", GSL_ENOMEM, 0); } s->type = T ; status = (s->type->alloc)(s->state, n, p); if (status != GSL_SUCCESS) { free (s->state); gsl_vector_free (s->dx); gsl_vector_free (s->x); gsl_vector_free (s->f); gsl_matrix_free (s->J); free (s); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to set solver", status, 0); } s->fdf = NULL; return s; } int gsl_multifit_fdfsolver_set (gsl_multifit_fdfsolver * s, gsl_multifit_function_fdf * f, const gsl_vector * x) { if (s->f->size != f->n) { GSL_ERROR ("function size does not match solver", GSL_EBADLEN); } if (s->x->size != x->size) { GSL_ERROR ("vector length does not match solver", GSL_EBADLEN); } s->fdf = f; gsl_vector_memcpy(s->x,x); return (s->type->set) (s->state, s->fdf, s->x, s->f, s->J, s->dx); } int gsl_multifit_fdfsolver_iterate (gsl_multifit_fdfsolver * s) { return (s->type->iterate) (s->state, s->fdf, s->x, s->f, s->J, s->dx); } void gsl_multifit_fdfsolver_free (gsl_multifit_fdfsolver * s) { (s->type->free) (s->state); free (s->state); gsl_vector_free (s->dx); gsl_vector_free (s->x); gsl_vector_free (s->f); gsl_matrix_free (s->J); free (s); } const char * gsl_multifit_fdfsolver_name (const gsl_multifit_fdfsolver * s) { return s->type->name; } gsl_vector * gsl_multifit_fdfsolver_position (const gsl_multifit_fdfsolver * s) { return s->x; } praat-6.0.04/external/gsl/gsl_multifit__fsolver.c000066400000000000000000000073411261542461700221010ustar00rootroot00000000000000/* multifit/fsolver.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_errno.h" #include "gsl_multifit_nlin.h" gsl_multifit_fsolver * gsl_multifit_fsolver_alloc (const gsl_multifit_fsolver_type * T, size_t n, size_t p) { int status; gsl_multifit_fsolver * s; if (n < p) { GSL_ERROR_VAL ("insufficient data points, n < p", GSL_EINVAL, 0); } s = (gsl_multifit_fsolver *) malloc (sizeof (gsl_multifit_fsolver)); if (s == 0) { GSL_ERROR_VAL ("failed to allocate space for multifit solver struct", GSL_ENOMEM, 0); } s->x = gsl_vector_calloc (p); if (s->x == 0) { free (s); GSL_ERROR_VAL ("failed to allocate space for x", GSL_ENOMEM, 0); } s->f = gsl_vector_calloc (n); if (s->f == 0) { gsl_vector_free (s->x); free (s); GSL_ERROR_VAL ("failed to allocate space for f", GSL_ENOMEM, 0); } s->dx = gsl_vector_calloc (p); if (s->dx == 0) { gsl_vector_free (s->x); gsl_vector_free (s->f); free (s); GSL_ERROR_VAL ("failed to allocate space for dx", GSL_ENOMEM, 0); } s->state = malloc (T->size); if (s->state == 0) { gsl_vector_free (s->dx); gsl_vector_free (s->x); gsl_vector_free (s->f); free (s); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for multifit solver state", GSL_ENOMEM, 0); } s->type = T ; status = (s->type->alloc)(s->state, n, p); if (status != GSL_SUCCESS) { (s->type->free)(s->state); free (s->state); gsl_vector_free (s->dx); gsl_vector_free (s->x); gsl_vector_free (s->f); free (s); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to set solver", status, 0); } s->function = NULL; return s; } int gsl_multifit_fsolver_set (gsl_multifit_fsolver * s, gsl_multifit_function * f, const gsl_vector * x) { if (s->f->size != f->n) { GSL_ERROR ("function size does not match solver", GSL_EBADLEN); } if (s->x->size != x->size) { GSL_ERROR ("vector length does not match solver", GSL_EBADLEN); } s->function = f; gsl_vector_memcpy(s->x,x); return (s->type->set) (s->state, s->function, s->x, s->f, s->dx); } int gsl_multifit_fsolver_iterate (gsl_multifit_fsolver * s) { return (s->type->iterate) (s->state, s->function, s->x, s->f, s->dx); } void gsl_multifit_fsolver_free (gsl_multifit_fsolver * s) { (s->type->free) (s->state); free (s->state); gsl_vector_free (s->dx); gsl_vector_free (s->x); gsl_vector_free (s->f); free (s); } const char * gsl_multifit_fsolver_name (const gsl_multifit_fsolver * s) { return s->type->name; } gsl_vector * gsl_multifit_fsolver_position (const gsl_multifit_fsolver * s) { return s->x; } praat-6.0.04/external/gsl/gsl_multifit__gradient.c000066400000000000000000000021621261542461700222120ustar00rootroot00000000000000/* multifit/covar.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_multifit_nlin.h" #include "gsl_blas.h" int gsl_multifit_gradient (const gsl_matrix * J, const gsl_vector * f, gsl_vector * g) { int status = gsl_blas_dgemv (CblasTrans, 1.0, J, f, 0.0, g); return status; } praat-6.0.04/external/gsl/gsl_multifit__lmder.c000066400000000000000000000226771261542461700215350ustar00rootroot00000000000000/* multfit/lmder.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_multifit_nlin.h" #include "gsl_blas.h" #include "gsl_linalg.h" #include "gsl_permutation.h" typedef struct { size_t iter; double xnorm; double fnorm; double delta; double par; gsl_matrix *r; gsl_vector *tau; gsl_vector *diag; gsl_vector *qtf; gsl_vector *newton; gsl_vector *gradient; gsl_vector *x_trial; gsl_vector *f_trial; gsl_vector *df; gsl_vector *sdiag; gsl_vector *rptdx; gsl_vector *w; gsl_vector *work1; gsl_permutation * perm; } lmder_state_t; static int lmder_alloc (void *vstate, size_t n, size_t p); static int lmder_set (void *vstate, gsl_multifit_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx); static int lmsder_set (void *vstate, gsl_multifit_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx); static int set (void *vstate, gsl_multifit_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx, int scale); static int lmder_iterate (void *vstate, gsl_multifit_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx); static void lmder_free (void *vstate); static int iterate (void *vstate, gsl_multifit_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx, int scale); #include "gsl_multifit__lmutil.c" #include "gsl_multifit__lmpar.c" #include "gsl_multifit__lmset.c" #include "gsl_multifit__lmiterate.c" static int lmder_alloc (void *vstate, size_t n, size_t p) { lmder_state_t *state = (lmder_state_t *) vstate; gsl_matrix *r; gsl_vector *tau, *diag, *qtf, *newton, *gradient, *x_trial, *f_trial, *df, *sdiag, *rptdx, *w, *work1; gsl_permutation *perm; r = gsl_matrix_calloc (n, p); if (r == 0) { GSL_ERROR ("failed to allocate space for r", GSL_ENOMEM); } state->r = r; tau = gsl_vector_calloc (GSL_MIN(n, p)); if (tau == 0) { gsl_matrix_free (r); GSL_ERROR ("failed to allocate space for tau", GSL_ENOMEM); } state->tau = tau; diag = gsl_vector_calloc (p); if (diag == 0) { gsl_matrix_free (r); gsl_vector_free (tau); GSL_ERROR ("failed to allocate space for diag", GSL_ENOMEM); } state->diag = diag; qtf = gsl_vector_calloc (n); if (qtf == 0) { gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); GSL_ERROR ("failed to allocate space for qtf", GSL_ENOMEM); } state->qtf = qtf; newton = gsl_vector_calloc (p); if (newton == 0) { gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); GSL_ERROR ("failed to allocate space for newton", GSL_ENOMEM); } state->newton = newton; gradient = gsl_vector_calloc (p); if (gradient == 0) { gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); gsl_vector_free (newton); GSL_ERROR ("failed to allocate space for gradient", GSL_ENOMEM); } state->gradient = gradient; x_trial = gsl_vector_calloc (p); if (x_trial == 0) { gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); gsl_vector_free (newton); gsl_vector_free (gradient); GSL_ERROR ("failed to allocate space for x_trial", GSL_ENOMEM); } state->x_trial = x_trial; f_trial = gsl_vector_calloc (n); if (f_trial == 0) { gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); gsl_vector_free (newton); gsl_vector_free (gradient); gsl_vector_free (x_trial); GSL_ERROR ("failed to allocate space for f_trial", GSL_ENOMEM); } state->f_trial = f_trial; df = gsl_vector_calloc (n); if (df == 0) { gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); gsl_vector_free (newton); gsl_vector_free (gradient); gsl_vector_free (x_trial); gsl_vector_free (f_trial); GSL_ERROR ("failed to allocate space for df", GSL_ENOMEM); } state->df = df; sdiag = gsl_vector_calloc (p); if (sdiag == 0) { gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); gsl_vector_free (newton); gsl_vector_free (gradient); gsl_vector_free (x_trial); gsl_vector_free (f_trial); gsl_vector_free (df); GSL_ERROR ("failed to allocate space for sdiag", GSL_ENOMEM); } state->sdiag = sdiag; rptdx = gsl_vector_calloc (n); if (rptdx == 0) { gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); gsl_vector_free (newton); gsl_vector_free (gradient); gsl_vector_free (x_trial); gsl_vector_free (f_trial); gsl_vector_free (df); gsl_vector_free (sdiag); GSL_ERROR ("failed to allocate space for rptdx", GSL_ENOMEM); } state->rptdx = rptdx; w = gsl_vector_calloc (n); if (w == 0) { gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); gsl_vector_free (newton); gsl_vector_free (gradient); gsl_vector_free (x_trial); gsl_vector_free (f_trial); gsl_vector_free (df); gsl_vector_free (sdiag); gsl_vector_free (rptdx); GSL_ERROR ("failed to allocate space for w", GSL_ENOMEM); } state->w = w; work1 = gsl_vector_calloc (p); if (work1 == 0) { gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); gsl_vector_free (newton); gsl_vector_free (gradient); gsl_vector_free (x_trial); gsl_vector_free (f_trial); gsl_vector_free (df); gsl_vector_free (sdiag); gsl_vector_free (rptdx); gsl_vector_free (w); GSL_ERROR ("failed to allocate space for work1", GSL_ENOMEM); } state->work1 = work1; perm = gsl_permutation_calloc (p); if (perm == 0) { gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); gsl_vector_free (newton); gsl_vector_free (gradient); gsl_vector_free (x_trial); gsl_vector_free (f_trial); gsl_vector_free (df); gsl_vector_free (sdiag); gsl_vector_free (rptdx); gsl_vector_free (w); gsl_vector_free (work1); GSL_ERROR ("failed to allocate space for perm", GSL_ENOMEM); } state->perm = perm; return GSL_SUCCESS; } static int lmder_set (void *vstate, gsl_multifit_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx) { int status = set (vstate, fdf, x, f, J, dx, 0); return status ; } static int lmsder_set (void *vstate, gsl_multifit_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx) { int status = set (vstate, fdf, x, f, J, dx, 1); return status ; } static int lmder_iterate (void *vstate, gsl_multifit_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx) { int status = iterate (vstate, fdf, x, f, J, dx, 0); return status; } static int lmsder_iterate (void *vstate, gsl_multifit_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx) { int status = iterate (vstate, fdf, x, f, J, dx, 1); return status; } static void lmder_free (void *vstate) { lmder_state_t *state = (lmder_state_t *) vstate; gsl_permutation_free (state->perm); gsl_vector_free (state->work1); gsl_vector_free (state->w); gsl_vector_free (state->rptdx); gsl_vector_free (state->sdiag); gsl_vector_free (state->df); gsl_vector_free (state->f_trial); gsl_vector_free (state->x_trial); gsl_vector_free (state->gradient); gsl_vector_free (state->newton); gsl_vector_free (state->qtf); gsl_vector_free (state->diag); gsl_vector_free (state->tau); gsl_matrix_free (state->r); } static const gsl_multifit_fdfsolver_type lmder_type = { "lmder", /* name */ sizeof (lmder_state_t), &lmder_alloc, &lmder_set, &lmder_iterate, &lmder_free }; static const gsl_multifit_fdfsolver_type lmsder_type = { "lmsder", /* name */ sizeof (lmder_state_t), &lmder_alloc, &lmsder_set, &lmsder_iterate, &lmder_free }; const gsl_multifit_fdfsolver_type *gsl_multifit_fdfsolver_lmder = &lmder_type; const gsl_multifit_fdfsolver_type *gsl_multifit_fdfsolver_lmsder = &lmsder_type; praat-6.0.04/external/gsl/gsl_multifit__lmiterate.c000066400000000000000000000121611261542461700224030ustar00rootroot00000000000000static int iterate (void *vstate, gsl_multifit_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx, int scale) { lmder_state_t *state = (lmder_state_t *) vstate; gsl_matrix *r = state->r; gsl_vector *tau = state->tau; gsl_vector *diag = state->diag; gsl_vector *qtf = state->qtf; gsl_vector *x_trial = state->x_trial; gsl_vector *f_trial = state->f_trial; gsl_vector *rptdx = state->rptdx; gsl_vector *newton = state->newton; gsl_vector *gradient = state->gradient; gsl_vector *sdiag = state->sdiag; gsl_vector *w = state->w; gsl_vector *work1 = state->work1; gsl_permutation *perm = state->perm; double prered, actred; double pnorm, fnorm1, fnorm1p, gnorm; double ratio; double dirder; int iter = 0; double p1 = 0.1, p25 = 0.25, p5 = 0.5, p75 = 0.75, p0001 = 0.0001; if (state->fnorm == 0.0) { return GSL_SUCCESS; } /* Compute qtf = Q^T f */ gsl_vector_memcpy (qtf, f); gsl_linalg_QR_QTvec (r, tau, qtf); /* Compute norm of scaled gradient */ compute_gradient_direction (r, perm, qtf, diag, gradient); { size_t iamax = gsl_blas_idamax (gradient); gnorm = fabs(gsl_vector_get (gradient, iamax) / state->fnorm); } /* Determine the Levenberg-Marquardt parameter */ lm_iteration: iter++ ; { int status = lmpar (r, perm, qtf, diag, state->delta, &(state->par), newton, gradient, sdiag, dx, w); if (status) return status; } /* Take a trial step */ gsl_vector_scale (dx, -1.0); /* reverse the step to go downhill */ compute_trial_step (x, dx, state->x_trial); pnorm = scaled_enorm (diag, dx); if (state->iter == 1) { if (pnorm < state->delta) { #ifdef DEBUG printf("set delta = pnorm = %g\n" , pnorm); #endif state->delta = pnorm; } } /* Evaluate function at x + p */ /* return immediately if evaluation raised error */ { int status = GSL_MULTIFIT_FN_EVAL_F (fdf, x_trial, f_trial); if (status) return status; } fnorm1 = enorm (f_trial); /* Compute the scaled actual reduction */ actred = compute_actual_reduction (state->fnorm, fnorm1); #ifdef DEBUG printf("lmiterate: fnorm = %g fnorm1 = %g actred = %g\n", state->fnorm, fnorm1, actred); printf("r = "); gsl_matrix_fprintf(stdout, r, "%g"); printf("perm = "); gsl_permutation_fprintf(stdout, perm, "%d"); printf("dx = "); gsl_vector_fprintf(stdout, dx, "%g"); #endif /* Compute rptdx = R P^T dx, noting that |J dx| = |R P^T dx| */ compute_rptdx (r, perm, dx, rptdx); #ifdef DEBUG printf("rptdx = "); gsl_vector_fprintf(stdout, rptdx, "%g"); #endif fnorm1p = enorm (rptdx); /* Compute the scaled predicted reduction = |J dx|^2 + 2 par |D dx|^2 */ { double t1 = fnorm1p / state->fnorm; double t2 = (sqrt(state->par) * pnorm) / state->fnorm; prered = t1 * t1 + t2 * t2 / p5; dirder = -(t1 * t1 + t2 * t2); } /* compute the ratio of the actual to predicted reduction */ if (prered > 0) { ratio = actred / prered; } else { ratio = 0; } #ifdef DEBUG printf("lmiterate: prered = %g dirder = %g ratio = %g\n", prered, dirder,ratio); #endif /* update the step bound */ if (ratio > p25) { #ifdef DEBUG printf("ratio > p25\n"); #endif if (state->par == 0 || ratio >= p75) { state->delta = pnorm / p5; state->par *= p5; #ifdef DEBUG printf("updated step bounds: delta = %g, par = %g\n", state->delta, state->par); #endif } } else { double temp = (actred >= 0) ? p5 : p5*dirder / (dirder + p5 * actred); #ifdef DEBUG printf("ratio < p25\n"); #endif if (p1 * fnorm1 >= state->fnorm || temp < p1 ) { temp = p1; } state->delta = temp * GSL_MIN_DBL (state->delta, pnorm/p1); state->par /= temp; #ifdef DEBUG printf("updated step bounds: delta = %g, par = %g\n", state->delta, state->par); #endif } /* test for successful iteration, termination and stringent tolerances */ if (ratio >= p0001) { gsl_vector_memcpy (x, x_trial); gsl_vector_memcpy (f, f_trial); /* return immediately if evaluation raised error */ { int status = GSL_MULTIFIT_FN_EVAL_DF (fdf, x_trial, J); if (status) return status; } /* wa2_j = diag_j * x_j */ state->xnorm = scaled_enorm(diag, x); state->fnorm = fnorm1; state->iter++; /* Rescale if necessary */ if (scale) { update_diag (J, diag); } { int signum; gsl_matrix_memcpy (r, J); gsl_linalg_QRPT_decomp (r, tau, perm, &signum, work1); } return GSL_SUCCESS; } else if (fabs(actred) <= GSL_DBL_EPSILON && prered <= GSL_DBL_EPSILON && p5 * ratio <= 1.0) { return GSL_ETOLF ; } else if (state->delta <= GSL_DBL_EPSILON * state->xnorm) { return GSL_ETOLX; } else if (gnorm <= GSL_DBL_EPSILON) { return GSL_ETOLG; } else if (iter < 10) { /* Repeat inner loop if unsuccessful */ goto lm_iteration; } return GSL_CONTINUE; } praat-6.0.04/external/gsl/gsl_multifit__lmpar.c000066400000000000000000000251761261542461700215420ustar00rootroot00000000000000/* multifit/lmpar.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl_permute_vector_double.h" #include "gsl_multifit__qrsolv.c" static size_t count_nsing (const gsl_matrix * r) { /* Count the number of nonsingular entries. Returns the index of the first entry which is singular. */ size_t n = r->size2; size_t i; for (i = 0; i < n; i++) { double rii = gsl_matrix_get (r, i, i); if (rii == 0) { break; } } return i; } static void compute_newton_direction (const gsl_matrix * r, const gsl_permutation * perm, const gsl_vector * qtf, gsl_vector * x) { /* Compute and store in x the Gauss-Newton direction. If the Jacobian is rank-deficient then obtain a least squares solution. */ const size_t n = r->size2; size_t i, j, nsing; for (i = 0 ; i < n ; i++) { double qtfi = gsl_vector_get (qtf, i); gsl_vector_set (x, i, qtfi); } nsing = count_nsing (r); #ifdef DEBUG printf("nsing = %d\n", nsing); printf("r = "); gsl_matrix_fprintf(stdout, r, "%g"); printf("\n"); printf("qtf = "); gsl_vector_fprintf(stdout, x, "%g"); printf("\n"); #endif for (i = nsing; i < n; i++) { gsl_vector_set (x, i, 0.0); } if (nsing > 0) { for (j = nsing; j > 0 && j--;) { double rjj = gsl_matrix_get (r, j, j); double temp = gsl_vector_get (x, j) / rjj; gsl_vector_set (x, j, temp); for (i = 0; i < j; i++) { double rij = gsl_matrix_get (r, i, j); double xi = gsl_vector_get (x, i); gsl_vector_set (x, i, xi - rij * temp); } } } gsl_permute_vector_inverse (perm, x); } static void compute_newton_correction (const gsl_matrix * r, const gsl_vector * sdiag, const gsl_permutation * p, gsl_vector * x, double dxnorm, const gsl_vector * diag, gsl_vector * w) { size_t n = r->size2; size_t i, j; for (i = 0; i < n; i++) { size_t pi = gsl_permutation_get (p, i); double dpi = gsl_vector_get (diag, pi); double xpi = gsl_vector_get (x, pi); gsl_vector_set (w, i, dpi * (dpi * xpi) / dxnorm); } for (j = 0; j < n; j++) { double sj = gsl_vector_get (sdiag, j); double wj = gsl_vector_get (w, j); double tj = wj / sj; gsl_vector_set (w, j, tj); for (i = j + 1; i < n; i++) { double rij = gsl_matrix_get (r, i, j); double wi = gsl_vector_get (w, i); gsl_vector_set (w, i, wi - rij * tj); } } } static void compute_newton_bound (const gsl_matrix * r, const gsl_vector * x, double dxnorm, const gsl_permutation * perm, const gsl_vector * diag, gsl_vector * w) { /* If the jacobian is not rank-deficient then the Newton step provides a lower bound for the zero of the function. Otherwise set this bound to zero. */ size_t n = r->size2; size_t i, j; size_t nsing = count_nsing (r); if (nsing < n) { gsl_vector_set_zero (w); return; } for (i = 0; i < n; i++) { size_t pi = gsl_permutation_get (perm, i); double dpi = gsl_vector_get (diag, pi); double xpi = gsl_vector_get (x, pi); gsl_vector_set (w, i, dpi * (dpi * xpi / dxnorm)); } for (j = 0; j < n; j++) { double sum = 0; for (i = 0; i < j; i++) { sum += gsl_matrix_get (r, i, j) * gsl_vector_get (w, i); } { double rjj = gsl_matrix_get (r, j, j); double wj = gsl_vector_get (w, j); gsl_vector_set (w, j, (wj - sum) / rjj); } } } static void compute_gradient_direction (const gsl_matrix * r, const gsl_permutation * p, const gsl_vector * qtf, const gsl_vector * diag, gsl_vector * g) { const size_t n = r->size2; size_t i, j; for (j = 0; j < n; j++) { double sum = 0; for (i = 0; i <= j; i++) { sum += gsl_matrix_get (r, i, j) * gsl_vector_get (qtf, i); } { size_t pj = gsl_permutation_get (p, j); double dpj = gsl_vector_get (diag, pj); gsl_vector_set (g, j, sum / dpj); } } } static int lmpar (gsl_matrix * r, const gsl_permutation * perm, const gsl_vector * qtf, const gsl_vector * diag, double delta, double * par_inout, gsl_vector * newton, gsl_vector * gradient, gsl_vector * sdiag, gsl_vector * x, gsl_vector * w) { double dxnorm, gnorm, fp, fp_old, par_lower, par_upper, par_c; double par = *par_inout; size_t iter = 0; #ifdef DEBUG printf("ENTERING lmpar\n"); #endif compute_newton_direction (r, perm, qtf, newton); #ifdef DEBUG printf ("newton = "); gsl_vector_fprintf (stdout, newton, "%g"); printf ("\n"); printf ("diag = "); gsl_vector_fprintf (stdout, diag, "%g"); printf ("\n"); #endif /* Evaluate the function at the origin and test for acceptance of the Gauss-Newton direction. */ dxnorm = scaled_enorm (diag, newton); fp = dxnorm - delta; #ifdef DEBUG printf ("dxnorm = %g, delta = %g, fp = %g\n", dxnorm, delta, fp); #endif if (fp <= 0.1 * delta) { gsl_vector_memcpy (x, newton); #ifdef DEBUG printf ("took newton (fp = %g, delta = %g)\n", fp, delta); #endif *par_inout = 0; return GSL_SUCCESS; } #ifdef DEBUG printf ("r = "); gsl_matrix_fprintf (stdout, r, "%g"); printf ("\n"); printf ("newton = "); gsl_vector_fprintf (stdout, newton, "%g"); printf ("\n"); printf ("dxnorm = %g\n", dxnorm); #endif compute_newton_bound (r, newton, dxnorm, perm, diag, w); #ifdef DEBUG printf("perm = "); gsl_permutation_fprintf(stdout, perm, "%d"); printf ("diag = "); gsl_vector_fprintf (stdout, diag, "%g"); printf ("\n"); printf ("w = "); gsl_vector_fprintf (stdout, w, "%g"); printf ("\n"); #endif { double wnorm = enorm (w); double phider = wnorm * wnorm; /* w == zero if r rank-deficient, then set lower bound to zero form MINPACK, lmder.f Hans E. Plesser 2002-02-25 (hans.plesser@itf.nlh.no) */ if ( wnorm > 0 ) par_lower = fp / (delta * phider); else par_lower = 0.0; } #ifdef DEBUG printf("par = %g\n", par ); printf("par_lower = %g\n", par_lower); #endif compute_gradient_direction (r, perm, qtf, diag, gradient); gnorm = enorm (gradient); #ifdef DEBUG printf("gradient = "); gsl_vector_fprintf(stdout, gradient, "%g"); printf("\n"); printf("gnorm = %g\n", gnorm); #endif par_upper = gnorm / delta; if (par_upper == 0) { par_upper = GSL_DBL_MIN / GSL_MIN_DBL(delta, 0.1); } #ifdef DEBUG printf("par_upper = %g\n", par_upper); #endif if (par > par_upper) { #ifdef DEBUG printf("set par to par_upper\n"); #endif par = par_upper; } else if (par < par_lower) { #ifdef DEBUG printf("set par to par_lower\n"); #endif par = par_lower; } if (par == 0) { par = gnorm / dxnorm; #ifdef DEBUG printf("set par to gnorm/dxnorm = %g\n", par); #endif } /* Beginning of iteration */ iteration: iter++; #ifdef DEBUG printf("lmpar iteration = %d\n", iter); #endif #ifdef BRIANSFIX /* Seems like this is described in the paper but not in the MINPACK code */ if (par < par_lower || par > par_upper) { par = GSL_MAX_DBL (0.001 * par_upper, sqrt(par_lower * par_upper)); } #endif /* Evaluate the function at the current value of par */ if (par == 0) { par = GSL_MAX_DBL (0.001 * par_upper, GSL_DBL_MIN); #ifdef DEBUG printf("par = 0, set par to = %g\n", par); #endif } /* Compute the least squares solution of [ R P x - Q^T f, sqrt(par) D x] for A = Q R P^T */ #ifdef DEBUG printf ("calling qrsolv with par = %g\n", par); #endif { double sqrt_par = sqrt(par); qrsolv (r, perm, sqrt_par, diag, qtf, x, sdiag, w); } dxnorm = scaled_enorm (diag, x); fp_old = fp; fp = dxnorm - delta; #ifdef DEBUG printf ("After qrsolv dxnorm = %g, delta = %g, fp = %g\n", dxnorm, delta, fp); printf ("sdiag = ") ; gsl_vector_fprintf(stdout, sdiag, "%g"); printf("\n"); printf ("x = ") ; gsl_vector_fprintf(stdout, x, "%g"); printf("\n"); printf ("r = ") ; gsl_matrix_fprintf(stdout, r, "%g"); printf("\nXXX\n"); #endif /* If the function is small enough, accept the current value of par */ if (fabs (fp) <= 0.1 * delta) goto line220; if (par_lower == 0 && fp <= fp_old && fp_old < 0) goto line220; /* Check for maximum number of iterations */ if (iter == 10) goto line220; /* Compute the Newton correction */ compute_newton_correction (r, sdiag, perm, x, dxnorm, diag, w); #ifdef DEBUG printf ("newton_correction = "); gsl_vector_fprintf(stdout, w, "%g"); printf("\n"); #endif { double wnorm = enorm (w); par_c = fp / (delta * wnorm * wnorm); } #ifdef DEBUG printf("fp = %g\n", fp); printf("par_lower = %g\n", par_lower); printf("par_upper = %g\n", par_upper); printf("par_c = %g\n", par_c); #endif /* Depending on the sign of the function, update par_lower or par_upper */ if (fp > 0) { if (par > par_lower) { par_lower = par; #ifdef DEBUG printf("fp > 0: set par_lower = par = %g\n", par); #endif } } else if (fp < 0) { if (par < par_upper) { #ifdef DEBUG printf("fp < 0: set par_upper = par = %g\n", par); #endif par_upper = par; } } /* Compute an improved estimate for par */ #ifdef DEBUG printf("improved estimate par = MAX(%g, %g) \n", par_lower, par+par_c); #endif par = GSL_MAX_DBL (par_lower, par + par_c); #ifdef DEBUG printf("improved estimate par = %g \n", par); #endif goto iteration; line220: #ifdef DEBUG printf("LEAVING lmpar, par = %g\n", par); #endif *par_inout = par; return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_multifit__lmset.c000066400000000000000000000024731261542461700215460ustar00rootroot00000000000000static int set (void *vstate, gsl_multifit_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx, int scale) { lmder_state_t *state = (lmder_state_t *) vstate; gsl_matrix *r = state->r; gsl_vector *tau = state->tau; gsl_vector *diag = state->diag; gsl_vector *work1 = state->work1; gsl_permutation *perm = state->perm; int signum; GSL_MULTIFIT_FN_EVAL_F_DF (fdf, x, f, J); state->par = 0; state->iter = 1; state->fnorm = enorm (f); gsl_vector_set_all (dx, 0.0); /* store column norms in diag */ if (scale) { compute_diag (J, diag); } else { gsl_vector_set_all (diag, 1.0); } /* set delta to 100 |D x| or to 100 if |D x| is zero */ state->xnorm = scaled_enorm (diag, x); state->delta = compute_delta (diag, x); /* Factorize J into QR decomposition */ gsl_matrix_memcpy (r, J); gsl_linalg_QRPT_decomp (r, tau, perm, &signum, work1); gsl_vector_set_zero (state->rptdx); gsl_vector_set_zero (state->w); /* Zero the trial vector, as in the alloc function */ gsl_vector_set_zero (state->f_trial); #ifdef DEBUG printf("r = "); gsl_matrix_fprintf(stdout, r, "%g"); printf("perm = "); gsl_permutation_fprintf(stdout, perm, "%d"); printf("tau = "); gsl_vector_fprintf(stdout, tau, "%g"); #endif return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_multifit__lmutil.c000066400000000000000000000053031261542461700217230ustar00rootroot00000000000000static void compute_diag (const gsl_matrix * J, gsl_vector * diag); static void update_diag (const gsl_matrix * J, gsl_vector * diag); static double compute_delta (gsl_vector * diag, gsl_vector * x); static double scaled_enorm (const gsl_vector * d, const gsl_vector * f); static double enorm (const gsl_vector * f); static double enorm (const gsl_vector * f) { return gsl_blas_dnrm2 (f); } static double scaled_enorm (const gsl_vector * d, const gsl_vector * f) { double e2 = 0; size_t i, n = f->size; for (i = 0; i < n; i++) { double fi = gsl_vector_get (f, i); double di = gsl_vector_get (d, i); double u = di * fi; e2 += u * u; } return sqrt (e2); } static double compute_delta (gsl_vector * diag, gsl_vector * x) { double Dx = scaled_enorm (diag, x); double factor = 100; /* generally recommended value from MINPACK */ return (Dx > 0) ? factor * Dx : factor; } static double compute_actual_reduction (double fnorm, double fnorm1) { double actred; if (0.1 * fnorm1 < fnorm) { double u = fnorm1 / fnorm; actred = 1 - u * u; } else { actred = -1; } return actred; } static void compute_diag (const gsl_matrix * J, gsl_vector * diag) { size_t i, j, n = J->size1, p = J->size2; for (j = 0; j < p; j++) { double sum = 0; for (i = 0; i < n; i++) { double Jij = gsl_matrix_get (J, i, j); sum += Jij * Jij; } if (sum == 0) sum = 1.0; gsl_vector_set (diag, j, sqrt (sum)); } } static void update_diag (const gsl_matrix * J, gsl_vector * diag) { size_t i, j, n = diag->size; for (j = 0; j < n; j++) { double cnorm, diagj, sum = 0; for (i = 0; i < n; i++) { double Jij = gsl_matrix_get (J, i, j); sum += Jij * Jij; } if (sum == 0) sum = 1.0; cnorm = sqrt (sum); diagj = gsl_vector_get (diag, j); if (cnorm > diagj) gsl_vector_set (diag, j, cnorm); } } static void compute_rptdx (const gsl_matrix * r, const gsl_permutation * p, const gsl_vector * dx, gsl_vector * rptdx) { size_t i, j, N = dx->size; for (i = 0; i < N; i++) { double sum = 0; for (j = i; j < N; j++) { size_t pj = gsl_permutation_get (p, j); sum += gsl_matrix_get (r, i, j) * gsl_vector_get (dx, pj); } gsl_vector_set (rptdx, i, sum); } } static void compute_trial_step (gsl_vector * x, gsl_vector * dx, gsl_vector * x_trial) { size_t i, N = x->size; for (i = 0; i < N; i++) { double pi = gsl_vector_get (dx, i); double xi = gsl_vector_get (x, i); gsl_vector_set (x_trial, i, xi + pi); } } praat-6.0.04/external/gsl/gsl_multifit__multilinear.c000066400000000000000000000257771261542461700227630ustar00rootroot00000000000000/* multifit/multilinear.c * * Copyright (C) 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_multifit.h" #include "gsl_blas.h" #include "gsl_linalg.h" /* Fit * * y = X c * * where X is an M x N matrix of M observations for N variables. * */ int gsl_multifit_linear (const gsl_matrix * X, const gsl_vector * y, gsl_vector * c, gsl_matrix * cov, double *chisq, gsl_multifit_linear_workspace * work) { size_t rank; int status = gsl_multifit_linear_svd (X, y, GSL_DBL_EPSILON, &rank, c, cov, chisq, work); return status; } /* Handle the general case of the SVD with tolerance and rank */ int gsl_multifit_linear_svd (const gsl_matrix * X, const gsl_vector * y, double tol, size_t * rank, gsl_vector * c, gsl_matrix * cov, double *chisq, gsl_multifit_linear_workspace * work) { if (X->size1 != y->size) { GSL_ERROR ("number of observations in y does not match rows of matrix X", GSL_EBADLEN); } else if (X->size2 != c->size) { GSL_ERROR ("number of parameters c does not match columns of matrix X", GSL_EBADLEN); } else if (cov->size1 != cov->size2) { GSL_ERROR ("covariance matrix is not square", GSL_ENOTSQR); } else if (c->size != cov->size1) { GSL_ERROR ("number of parameters does not match size of covariance matrix", GSL_EBADLEN); } else if (X->size1 != work->n || X->size2 != work->p) { GSL_ERROR ("size of workspace does not match size of observation matrix", GSL_EBADLEN); } else if (tol <= 0) { GSL_ERROR ("tolerance must be positive", GSL_EINVAL); } else { const size_t n = X->size1; const size_t p = X->size2; size_t i, j, p_eff; gsl_matrix *A = work->A; gsl_matrix *Q = work->Q; gsl_matrix *QSI = work->QSI; gsl_vector *S = work->S; gsl_vector *xt = work->xt; gsl_vector *D = work->D; /* Copy X to workspace, A <= X */ gsl_matrix_memcpy (A, X); /* Balance the columns of the matrix A */ gsl_linalg_balance_columns (A, D); /* Decompose A into U S Q^T */ gsl_linalg_SV_decomp_mod (A, QSI, Q, S, xt); /* Solve y = A c for c */ gsl_blas_dgemv (CblasTrans, 1.0, A, y, 0.0, xt); /* Scale the matrix Q, Q' = Q S^-1 */ gsl_matrix_memcpy (QSI, Q); { double alpha0 = gsl_vector_get (S, 0); p_eff = 0; for (j = 0; j < p; j++) { gsl_vector_view column = gsl_matrix_column (QSI, j); double alpha = gsl_vector_get (S, j); if (alpha <= tol * alpha0) { alpha = 0.0; } else { alpha = 1.0 / alpha; p_eff++; } gsl_vector_scale (&column.vector, alpha); } *rank = p_eff; } gsl_vector_set_zero (c); gsl_blas_dgemv (CblasNoTrans, 1.0, QSI, xt, 0.0, c); /* Unscale the balancing factors */ gsl_vector_div (c, D); /* Compute chisq, from residual r = y - X c */ { double s2 = 0, r2 = 0; for (i = 0; i < n; i++) { double yi = gsl_vector_get (y, i); gsl_vector_const_view row = gsl_matrix_const_row (X, i); double y_est, ri; gsl_blas_ddot (&row.vector, c, &y_est); ri = yi - y_est; r2 += ri * ri; } s2 = r2 / (n - p_eff); /* p_eff == rank */ *chisq = r2; /* Form variance-covariance matrix cov = s2 * (Q S^-1) (Q S^-1)^T */ for (i = 0; i < p; i++) { gsl_vector_view row_i = gsl_matrix_row (QSI, i); double d_i = gsl_vector_get (D, i); for (j = i; j < p; j++) { gsl_vector_view row_j = gsl_matrix_row (QSI, j); double d_j = gsl_vector_get (D, j); double s; gsl_blas_ddot (&row_i.vector, &row_j.vector, &s); gsl_matrix_set (cov, i, j, s * s2 / (d_i * d_j)); gsl_matrix_set (cov, j, i, s * s2 / (d_i * d_j)); } } } return GSL_SUCCESS; } } int gsl_multifit_wlinear (const gsl_matrix * X, const gsl_vector * w, const gsl_vector * y, gsl_vector * c, gsl_matrix * cov, double *chisq, gsl_multifit_linear_workspace * work) { size_t rank; int status = gsl_multifit_wlinear_svd (X, w, y, GSL_DBL_EPSILON, &rank, c, cov, chisq, work); return status; } int gsl_multifit_wlinear_svd (const gsl_matrix * X, const gsl_vector * w, const gsl_vector * y, double tol, size_t * rank, gsl_vector * c, gsl_matrix * cov, double *chisq, gsl_multifit_linear_workspace * work) { if (X->size1 != y->size) { GSL_ERROR ("number of observations in y does not match rows of matrix X", GSL_EBADLEN); } else if (X->size2 != c->size) { GSL_ERROR ("number of parameters c does not match columns of matrix X", GSL_EBADLEN); } else if (w->size != y->size) { GSL_ERROR ("number of weights does not match number of observations", GSL_EBADLEN); } else if (cov->size1 != cov->size2) { GSL_ERROR ("covariance matrix is not square", GSL_ENOTSQR); } else if (c->size != cov->size1) { GSL_ERROR ("number of parameters does not match size of covariance matrix", GSL_EBADLEN); } else if (X->size1 != work->n || X->size2 != work->p) { GSL_ERROR ("size of workspace does not match size of observation matrix", GSL_EBADLEN); } else { const size_t n = X->size1; const size_t p = X->size2; size_t i, j, p_eff; gsl_matrix *A = work->A; gsl_matrix *Q = work->Q; gsl_matrix *QSI = work->QSI; gsl_vector *S = work->S; gsl_vector *t = work->t; gsl_vector *xt = work->xt; gsl_vector *D = work->D; /* Scale X, A = sqrt(w) X */ gsl_matrix_memcpy (A, X); for (i = 0; i < n; i++) { double wi = gsl_vector_get (w, i); if (wi < 0) wi = 0; { gsl_vector_view row = gsl_matrix_row (A, i); gsl_vector_scale (&row.vector, sqrt (wi)); } } /* Balance the columns of the matrix A */ gsl_linalg_balance_columns (A, D); /* Decompose A into U S Q^T */ gsl_linalg_SV_decomp_mod (A, QSI, Q, S, xt); /* Solve sqrt(w) y = A c for c, by first computing t = sqrt(w) y */ for (i = 0; i < n; i++) { double wi = gsl_vector_get (w, i); double yi = gsl_vector_get (y, i); if (wi < 0) wi = 0; gsl_vector_set (t, i, sqrt (wi) * yi); } gsl_blas_dgemv (CblasTrans, 1.0, A, t, 0.0, xt); /* Scale the matrix Q, Q' = Q S^-1 */ gsl_matrix_memcpy (QSI, Q); { double alpha0 = gsl_vector_get (S, 0); p_eff = 0; for (j = 0; j < p; j++) { gsl_vector_view column = gsl_matrix_column (QSI, j); double alpha = gsl_vector_get (S, j); if (alpha <= tol * alpha0) { alpha = 0.0; } else { alpha = 1.0 / alpha; p_eff++; } gsl_vector_scale (&column.vector, alpha); } *rank = p_eff; } gsl_vector_set_zero (c); /* Solution */ gsl_blas_dgemv (CblasNoTrans, 1.0, QSI, xt, 0.0, c); /* Unscale the balancing factors */ gsl_vector_div (c, D); /* Form covariance matrix cov = (Q S^-1) (Q S^-1)^T */ for (i = 0; i < p; i++) { gsl_vector_view row_i = gsl_matrix_row (QSI, i); double d_i = gsl_vector_get (D, i); for (j = i; j < p; j++) { gsl_vector_view row_j = gsl_matrix_row (QSI, j); double d_j = gsl_vector_get (D, j); double s; gsl_blas_ddot (&row_i.vector, &row_j.vector, &s); gsl_matrix_set (cov, i, j, s / (d_i * d_j)); gsl_matrix_set (cov, j, i, s / (d_i * d_j)); } } /* Compute chisq, from residual r = y - X c */ { double r2 = 0; for (i = 0; i < n; i++) { double yi = gsl_vector_get (y, i); double wi = gsl_vector_get (w, i); gsl_vector_const_view row = gsl_matrix_const_row (X, i); double y_est, ri; gsl_blas_ddot (&row.vector, c, &y_est); ri = yi - y_est; r2 += wi * ri * ri; } *chisq = r2; } return GSL_SUCCESS; } } int gsl_multifit_linear_est (const gsl_vector * x, const gsl_vector * c, const gsl_matrix * cov, double *y, double *y_err) { if (x->size != c->size) { GSL_ERROR ("number of parameters c does not match number of observations x", GSL_EBADLEN); } else if (cov->size1 != cov->size2) { GSL_ERROR ("covariance matrix is not square", GSL_ENOTSQR); } else if (c->size != cov->size1) { GSL_ERROR ("number of parameters c does not match size of covariance matrix cov", GSL_EBADLEN); } else { size_t i, j; double var = 0; gsl_blas_ddot(x, c, y); /* y = x.c */ /* var = x' cov x */ for (i = 0; i < x->size; i++) { const double xi = gsl_vector_get (x, i); var += xi * xi * gsl_matrix_get (cov, i, i); for (j = 0; j < i; j++) { const double xj = gsl_vector_get (x, j); var += 2 * xi * xj * gsl_matrix_get (cov, i, j); } } *y_err = sqrt (var); return GSL_SUCCESS; } } praat-6.0.04/external/gsl/gsl_multifit__qrsolv.c000066400000000000000000000132471261542461700217510ustar00rootroot00000000000000/* This function computes the solution to the least squares system phi = [ A x = b , lambda D x = 0 ]^2 where A is an M by N matrix, D is an N by N diagonal matrix, lambda is a scalar parameter and b is a vector of length M. The function requires the factorization of A into A = Q R P^T, where Q is an orthogonal matrix, R is an upper triangular matrix with diagonal elements of non-increasing magnitude and P is a permuation matrix. The system above is then equivalent to [ R z = Q^T b, P^T (lambda D) P z = 0 ] where x = P z. If this system does not have full rank then a least squares solution is obtained. On output the function also provides an upper triangular matrix S such that P^T (A^T A + lambda^2 D^T D) P = S^T S Parameters, r: On input, contains the full upper triangle of R. On output the strict lower triangle contains the transpose of the strict upper triangle of S, and the diagonal of S is stored in sdiag. The full upper triangle of R is not modified. p: the encoded form of the permutation matrix P. column j of P is column p[j] of the identity matrix. lambda, diag: contains the scalar lambda and the diagonal elements of the matrix D qtb: contains the product Q^T b x: on output contains the least squares solution of the system wa: is a workspace of length N */ static int qrsolv (gsl_matrix * r, const gsl_permutation * p, const double lambda, const gsl_vector * diag, const gsl_vector * qtb, gsl_vector * x, gsl_vector * sdiag, gsl_vector * wa) { size_t n = r->size2; size_t i, j, k, nsing; /* Copy r and qtb to preserve input and initialise s. In particular, save the diagonal elements of r in x */ for (j = 0; j < n; j++) { double rjj = gsl_matrix_get (r, j, j); double qtbj = gsl_vector_get (qtb, j); for (i = j + 1; i < n; i++) { double rji = gsl_matrix_get (r, j, i); gsl_matrix_set (r, i, j, rji); } gsl_vector_set (x, j, rjj); gsl_vector_set (wa, j, qtbj); } /* Eliminate the diagonal matrix d using a Givens rotation */ for (j = 0; j < n; j++) { double qtbpj; size_t pj = gsl_permutation_get (p, j); double diagpj = lambda * gsl_vector_get (diag, pj); if (diagpj == 0) { continue; } gsl_vector_set (sdiag, j, diagpj); for (k = j + 1; k < n; k++) { gsl_vector_set (sdiag, k, 0.0); } /* The transformations to eliminate the row of d modify only a single element of qtb beyond the first n, which is initially zero */ qtbpj = 0; for (k = j; k < n; k++) { /* Determine a Givens rotation which eliminates the appropriate element in the current row of d */ double sine, cosine; double wak = gsl_vector_get (wa, k); double rkk = gsl_matrix_get (r, k, k); double sdiagk = gsl_vector_get (sdiag, k); if (sdiagk == 0) { continue; } if (fabs (rkk) < fabs (sdiagk)) { double cotangent = rkk / sdiagk; sine = 0.5 / sqrt (0.25 + 0.25 * cotangent * cotangent); cosine = sine * cotangent; } else { double tangent = sdiagk / rkk; cosine = 0.5 / sqrt (0.25 + 0.25 * tangent * tangent); sine = cosine * tangent; } /* Compute the modified diagonal element of r and the modified element of [qtb,0] */ { double new_rkk = cosine * rkk + sine * sdiagk; double new_wak = cosine * wak + sine * qtbpj; qtbpj = -sine * wak + cosine * qtbpj; gsl_matrix_set(r, k, k, new_rkk); gsl_vector_set(wa, k, new_wak); } /* Accumulate the transformation in the row of s */ for (i = k + 1; i < n; i++) { double rik = gsl_matrix_get (r, i, k); double sdiagi = gsl_vector_get (sdiag, i); double new_rik = cosine * rik + sine * sdiagi; double new_sdiagi = -sine * rik + cosine * sdiagi; gsl_matrix_set(r, i, k, new_rik); gsl_vector_set(sdiag, i, new_sdiagi); } } /* Store the corresponding diagonal element of s and restore the corresponding diagonal element of r */ { double rjj = gsl_matrix_get (r, j, j); double xj = gsl_vector_get(x, j); gsl_vector_set (sdiag, j, rjj); gsl_matrix_set (r, j, j, xj); } } /* Solve the triangular system for z. If the system is singular then obtain a least squares solution */ nsing = n; for (j = 0; j < n; j++) { double sdiagj = gsl_vector_get (sdiag, j); if (sdiagj == 0) { nsing = j; break; } } for (j = nsing; j < n; j++) { gsl_vector_set (wa, j, 0.0); } for (k = 0; k < nsing; k++) { double sum = 0; j = (nsing - 1) - k; for (i = j + 1; i < nsing; i++) { sum += gsl_matrix_get(r, i, j) * gsl_vector_get(wa, i); } { double waj = gsl_vector_get (wa, j); double sdiagj = gsl_vector_get (sdiag, j); gsl_vector_set (wa, j, (waj - sum) / sdiagj); } } /* Permute the components of z back to the components of x */ for (j = 0; j < n; j++) { size_t pj = gsl_permutation_get (p, j); double waj = gsl_vector_get (wa, j); gsl_vector_set (x, pj, waj); } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_multifit__work.c000066400000000000000000000064301261542461700214010ustar00rootroot00000000000000/* multifit/work.c * * Copyright (C) 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_multifit.h" gsl_multifit_linear_workspace * gsl_multifit_linear_alloc (size_t n, size_t p) { gsl_multifit_linear_workspace *w; w = (gsl_multifit_linear_workspace *) malloc (sizeof (gsl_multifit_linear_workspace)); if (w == 0) { GSL_ERROR_VAL ("failed to allocate space for multifit_linear struct", GSL_ENOMEM, 0); } w->n = n; /* number of observations */ w->p = p; /* number of parameters */ w->A = gsl_matrix_alloc (n, p); if (w->A == 0) { free (w); GSL_ERROR_VAL ("failed to allocate space for A", GSL_ENOMEM, 0); } w->Q = gsl_matrix_alloc (p, p); if (w->Q == 0) { gsl_matrix_free (w->A); free (w); GSL_ERROR_VAL ("failed to allocate space for Q", GSL_ENOMEM, 0); } w->QSI = gsl_matrix_alloc (p, p); if (w->QSI == 0) { gsl_matrix_free (w->Q); gsl_matrix_free (w->A); free (w); GSL_ERROR_VAL ("failed to allocate space for QSI", GSL_ENOMEM, 0); } w->S = gsl_vector_alloc (p); if (w->S == 0) { gsl_matrix_free (w->QSI); gsl_matrix_free (w->Q); gsl_matrix_free (w->A); free (w); GSL_ERROR_VAL ("failed to allocate space for S", GSL_ENOMEM, 0); } w->t = gsl_vector_alloc (n); if (w->t == 0) { gsl_vector_free (w->S); gsl_matrix_free (w->QSI); gsl_matrix_free (w->Q); gsl_matrix_free (w->A); free (w); GSL_ERROR_VAL ("failed to allocate space for t", GSL_ENOMEM, 0); } w->xt = gsl_vector_calloc (p); if (w->xt == 0) { gsl_vector_free (w->t); gsl_vector_free (w->S); gsl_matrix_free (w->QSI); gsl_matrix_free (w->Q); gsl_matrix_free (w->A); free (w); GSL_ERROR_VAL ("failed to allocate space for xt", GSL_ENOMEM, 0); } w->D = gsl_vector_calloc (p); if (w->D == 0) { gsl_vector_free (w->D); gsl_vector_free (w->t); gsl_vector_free (w->S); gsl_matrix_free (w->QSI); gsl_matrix_free (w->Q); gsl_matrix_free (w->A); free (w); GSL_ERROR_VAL ("failed to allocate space for xt", GSL_ENOMEM, 0); } return w; } void gsl_multifit_linear_free (gsl_multifit_linear_workspace * work) { gsl_matrix_free (work->A); gsl_matrix_free (work->Q); gsl_matrix_free (work->QSI); gsl_vector_free (work->S); gsl_vector_free (work->t); gsl_vector_free (work->xt); gsl_vector_free (work->D); free (work); } praat-6.0.04/external/gsl/gsl_multifit_nlin.h000066400000000000000000000127701261542461700212310ustar00rootroot00000000000000/* multifit_nlin/gsl_multifit_nlin.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_MULTIFIT_NLIN_H__ #define __GSL_MULTIFIT_NLIN_H__ #include #include "gsl_types.h" #include "gsl_math.h" #include "gsl_vector.h" #include "gsl_matrix.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_multifit_gradient (const gsl_matrix * J, const gsl_vector * f, gsl_vector * g); int gsl_multifit_covar (const gsl_matrix * J, double epsrel, gsl_matrix * covar); /* Definition of vector-valued functions with parameters based on gsl_vector */ struct gsl_multifit_function_struct { int (* f) (const gsl_vector * x, void * params, gsl_vector * f); size_t n; /* number of functions */ size_t p; /* number of independent variables */ void * params; }; typedef struct gsl_multifit_function_struct gsl_multifit_function ; #define GSL_MULTIFIT_FN_EVAL(F,x,y) (*((F)->f))(x,(F)->params,(y)) typedef struct { const char *name; size_t size; int (*alloc) (void *state, size_t n, size_t p); int (*set) (void *state, gsl_multifit_function * function, gsl_vector * x, gsl_vector * f, gsl_vector * dx); int (*iterate) (void *state, gsl_multifit_function * function, gsl_vector * x, gsl_vector * f, gsl_vector * dx); void (*free) (void *state); } gsl_multifit_fsolver_type; typedef struct { const gsl_multifit_fsolver_type * type; gsl_multifit_function * function ; gsl_vector * x ; gsl_vector * f ; gsl_vector * dx ; void *state; } gsl_multifit_fsolver; gsl_multifit_fsolver * gsl_multifit_fsolver_alloc (const gsl_multifit_fsolver_type * T, size_t n, size_t p); void gsl_multifit_fsolver_free (gsl_multifit_fsolver * s); int gsl_multifit_fsolver_set (gsl_multifit_fsolver * s, gsl_multifit_function * f, const gsl_vector * x); int gsl_multifit_fsolver_iterate (gsl_multifit_fsolver * s); const char * gsl_multifit_fsolver_name (const gsl_multifit_fsolver * s); gsl_vector * gsl_multifit_fsolver_position (const gsl_multifit_fsolver * s); /* Definition of vector-valued functions and gradient with parameters based on gsl_vector */ struct gsl_multifit_function_fdf_struct { int (* f) (const gsl_vector * x, void * params, gsl_vector * f); int (* df) (const gsl_vector * x, void * params, gsl_matrix * df); int (* fdf) (const gsl_vector * x, void * params, gsl_vector * f, gsl_matrix *df); size_t n; /* number of functions */ size_t p; /* number of independent variables */ void * params; }; typedef struct gsl_multifit_function_fdf_struct gsl_multifit_function_fdf ; #define GSL_MULTIFIT_FN_EVAL_F(F,x,y) ((*((F)->f))(x,(F)->params,(y))) #define GSL_MULTIFIT_FN_EVAL_DF(F,x,dy) ((*((F)->df))(x,(F)->params,(dy))) #define GSL_MULTIFIT_FN_EVAL_F_DF(F,x,y,dy) ((*((F)->fdf))(x,(F)->params,(y),(dy))) typedef struct { const char *name; size_t size; int (*alloc) (void *state, size_t n, size_t p); int (*set) (void *state, gsl_multifit_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx); int (*iterate) (void *state, gsl_multifit_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx); void (*free) (void *state); } gsl_multifit_fdfsolver_type; typedef struct { const gsl_multifit_fdfsolver_type * type; gsl_multifit_function_fdf * fdf ; gsl_vector * x; gsl_vector * f; gsl_matrix * J; gsl_vector * dx; void *state; } gsl_multifit_fdfsolver; gsl_multifit_fdfsolver * gsl_multifit_fdfsolver_alloc (const gsl_multifit_fdfsolver_type * T, size_t n, size_t p); int gsl_multifit_fdfsolver_set (gsl_multifit_fdfsolver * s, gsl_multifit_function_fdf * fdf, const gsl_vector * x); int gsl_multifit_fdfsolver_iterate (gsl_multifit_fdfsolver * s); void gsl_multifit_fdfsolver_free (gsl_multifit_fdfsolver * s); const char * gsl_multifit_fdfsolver_name (const gsl_multifit_fdfsolver * s); gsl_vector * gsl_multifit_fdfsolver_position (const gsl_multifit_fdfsolver * s); int gsl_multifit_test_delta (const gsl_vector * dx, const gsl_vector * x, double epsabs, double epsrel); int gsl_multifit_test_gradient (const gsl_vector * g, double epsabs); /* extern const gsl_multifit_fsolver_type * gsl_multifit_fsolver_gradient; */ GSL_VAR const gsl_multifit_fdfsolver_type * gsl_multifit_fdfsolver_lmder; GSL_VAR const gsl_multifit_fdfsolver_type * gsl_multifit_fdfsolver_lmsder; __END_DECLS #endif /* __GSL_MULTIFIT_NLIN_H__ */ praat-6.0.04/external/gsl/gsl_multimin.h000066400000000000000000000146731261542461700202160ustar00rootroot00000000000000/* multimin/gsl_multimin.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Fabrice Rossi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Modified by Tuomo Keskitalo to include fminimizer and Nelder Mead related lines */ #ifndef __GSL_MULTIMIN_H__ #define __GSL_MULTIMIN_H__ #include #include "gsl_types.h" #include "gsl_math.h" #include "gsl_vector.h" #include "gsl_matrix.h" #include "gsl_min.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Definition of an arbitrary real-valued function with gsl_vector input and */ /* parameters */ struct gsl_multimin_function_struct { double (* f) (const gsl_vector * x, void * params); size_t n; void * params; }; typedef struct gsl_multimin_function_struct gsl_multimin_function; #define GSL_MULTIMIN_FN_EVAL(F,x) (*((F)->f))(x,(F)->params) /* Definition of an arbitrary differentiable real-valued function */ /* with gsl_vector input and parameters */ struct gsl_multimin_function_fdf_struct { double (* f) (const gsl_vector * x, void * params); void (* df) (const gsl_vector * x, void * params,gsl_vector * df); void (* fdf) (const gsl_vector * x, void * params,double *f,gsl_vector * df); size_t n; void * params; }; typedef struct gsl_multimin_function_fdf_struct gsl_multimin_function_fdf; #define GSL_MULTIMIN_FN_EVAL_F(F,x) (*((F)->f))(x,(F)->params) #define GSL_MULTIMIN_FN_EVAL_DF(F,x,g) (*((F)->df))(x,(F)->params,(g)) #define GSL_MULTIMIN_FN_EVAL_F_DF(F,x,y,g) (*((F)->fdf))(x,(F)->params,(y),(g)) int gsl_multimin_diff (const gsl_multimin_function * f, const gsl_vector * x, gsl_vector * g); /* minimization of non-differentiable functions */ typedef struct { const char *name; size_t size; int (*alloc) (void *state, size_t n); int (*set) (void *state, gsl_multimin_function * f, const gsl_vector * x, double * size, const gsl_vector * step_size); int (*iterate) (void *state, gsl_multimin_function * f, gsl_vector * x, double * size, double * fval); void (*free) (void *state); } gsl_multimin_fminimizer_type; typedef struct { /* multi dimensional part */ const gsl_multimin_fminimizer_type *type; gsl_multimin_function *f; double fval; gsl_vector * x; double size; void *state; } gsl_multimin_fminimizer; gsl_multimin_fminimizer * gsl_multimin_fminimizer_alloc(const gsl_multimin_fminimizer_type *T, size_t n); int gsl_multimin_fminimizer_set (gsl_multimin_fminimizer * s, gsl_multimin_function * f, const gsl_vector * x, const gsl_vector * step_size); void gsl_multimin_fminimizer_free(gsl_multimin_fminimizer *s); const char * gsl_multimin_fminimizer_name (const gsl_multimin_fminimizer * s); int gsl_multimin_fminimizer_iterate(gsl_multimin_fminimizer *s); gsl_vector * gsl_multimin_fminimizer_x (const gsl_multimin_fminimizer * s); double gsl_multimin_fminimizer_minimum (const gsl_multimin_fminimizer * s); double gsl_multimin_fminimizer_size (const gsl_multimin_fminimizer * s); /* Convergence test functions */ int gsl_multimin_test_gradient(const gsl_vector * g,double epsabs); int gsl_multimin_test_size(const double size ,double epsabs); /* minimisation of differentiable functions */ typedef struct { const char *name; size_t size; int (*alloc) (void *state, size_t n); int (*set) (void *state, gsl_multimin_function_fdf * fdf, const gsl_vector * x, double * f, gsl_vector * gradient, double step_size, double tol); int (*iterate) (void *state,gsl_multimin_function_fdf * fdf, gsl_vector * x, double * f, gsl_vector * gradient, gsl_vector * dx); int (*restart) (void *state); void (*free) (void *state); } gsl_multimin_fdfminimizer_type; typedef struct { /* multi dimensional part */ const gsl_multimin_fdfminimizer_type *type; gsl_multimin_function_fdf *fdf; double f; gsl_vector * x; gsl_vector * gradient; gsl_vector * dx; void *state; } gsl_multimin_fdfminimizer; gsl_multimin_fdfminimizer * gsl_multimin_fdfminimizer_alloc(const gsl_multimin_fdfminimizer_type *T, size_t n); int gsl_multimin_fdfminimizer_set (gsl_multimin_fdfminimizer * s, gsl_multimin_function_fdf *fdf, const gsl_vector * x, double step_size, double tol); void gsl_multimin_fdfminimizer_free(gsl_multimin_fdfminimizer *s); const char * gsl_multimin_fdfminimizer_name (const gsl_multimin_fdfminimizer * s); int gsl_multimin_fdfminimizer_iterate(gsl_multimin_fdfminimizer *s); int gsl_multimin_fdfminimizer_restart(gsl_multimin_fdfminimizer *s); gsl_vector * gsl_multimin_fdfminimizer_x (gsl_multimin_fdfminimizer * s); gsl_vector * gsl_multimin_fdfminimizer_dx (gsl_multimin_fdfminimizer * s); gsl_vector * gsl_multimin_fdfminimizer_gradient (gsl_multimin_fdfminimizer * s); double gsl_multimin_fdfminimizer_minimum (gsl_multimin_fdfminimizer * s); GSL_VAR const gsl_multimin_fdfminimizer_type *gsl_multimin_fdfminimizer_steepest_descent; GSL_VAR const gsl_multimin_fdfminimizer_type *gsl_multimin_fdfminimizer_conjugate_pr; GSL_VAR const gsl_multimin_fdfminimizer_type *gsl_multimin_fdfminimizer_conjugate_fr; GSL_VAR const gsl_multimin_fdfminimizer_type *gsl_multimin_fdfminimizer_vector_bfgs; GSL_VAR const gsl_multimin_fdfminimizer_type *gsl_multimin_fdfminimizer_vector_bfgs2; GSL_VAR const gsl_multimin_fminimizer_type *gsl_multimin_fminimizer_nmsimplex; __END_DECLS #endif /* __GSL_MULTIMIN_H__ */ praat-6.0.04/external/gsl/gsl_multimin__conjugate_fr.c000066400000000000000000000147531261542461700230750ustar00rootroot00000000000000/* multimin/conjugate_fr.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Fabrice Rossi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* conjugate_fr.c -- Conjugate gradient Fletcher-Reeve algorithm */ /* Modified by Brian Gough to use single iteration structure */ #include "gsl__config.h" #include "gsl_multimin.h" #include "gsl_blas.h" #include "gsl_multimin__directional_minimize.c" typedef struct { int iter; double step; double max_step; double tol; gsl_vector *x1; gsl_vector *dx1; gsl_vector *x2; double pnorm; gsl_vector *p; double g0norm; gsl_vector *g0; } conjugate_fr_state_t; static int conjugate_fr_alloc (void *vstate, size_t n) { conjugate_fr_state_t *state = (conjugate_fr_state_t *) vstate; state->x1 = gsl_vector_calloc (n); if (state->x1 == 0) { GSL_ERROR ("failed to allocate space for x1", GSL_ENOMEM); } state->dx1 = gsl_vector_calloc (n); if (state->dx1 == 0) { gsl_vector_free (state->x1); GSL_ERROR ("failed to allocate space for dx1", GSL_ENOMEM); } state->x2 = gsl_vector_calloc (n); if (state->x2 == 0) { gsl_vector_free (state->dx1); gsl_vector_free (state->x1); GSL_ERROR ("failed to allocate space for x2", GSL_ENOMEM); } state->p = gsl_vector_calloc (n); if (state->p == 0) { gsl_vector_free (state->x2); gsl_vector_free (state->dx1); gsl_vector_free (state->x1); GSL_ERROR ("failed to allocate space for p", GSL_ENOMEM); } state->g0 = gsl_vector_calloc (n); if (state->g0 == 0) { gsl_vector_free (state->p); gsl_vector_free (state->x2); gsl_vector_free (state->dx1); gsl_vector_free (state->x1); GSL_ERROR ("failed to allocate space for g0", GSL_ENOMEM); } return GSL_SUCCESS; } static int conjugate_fr_set (void *vstate, gsl_multimin_function_fdf * fdf, const gsl_vector * x, double *f, gsl_vector * gradient, double step_size, double tol) { conjugate_fr_state_t *state = (conjugate_fr_state_t *) vstate; state->iter = 0; state->step = step_size; state->max_step = step_size; state->tol = tol; GSL_MULTIMIN_FN_EVAL_F_DF (fdf, x, f, gradient); /* Use the gradient as the initial direction */ gsl_vector_memcpy (state->p, gradient); gsl_vector_memcpy (state->g0, gradient); { double gnorm = gsl_blas_dnrm2 (gradient); state->pnorm = gnorm; state->g0norm = gnorm; } return GSL_SUCCESS; } static void conjugate_fr_free (void *vstate) { conjugate_fr_state_t *state = (conjugate_fr_state_t *) vstate; gsl_vector_free (state->g0); gsl_vector_free (state->p); gsl_vector_free (state->x2); gsl_vector_free (state->dx1); gsl_vector_free (state->x1); } static int conjugate_fr_restart (void *vstate) { conjugate_fr_state_t *state = (conjugate_fr_state_t *) vstate; state->iter = 0; return GSL_SUCCESS; } static int conjugate_fr_iterate (void *vstate, gsl_multimin_function_fdf * fdf, gsl_vector * x, double *f, gsl_vector * gradient, gsl_vector * dx) { conjugate_fr_state_t *state = (conjugate_fr_state_t *) vstate; gsl_vector *x1 = state->x1; gsl_vector *dx1 = state->dx1; gsl_vector *x2 = state->x2; gsl_vector *p = state->p; gsl_vector *g0 = state->g0; double pnorm = state->pnorm; double g0norm = state->g0norm; double fa = *f, fb, fc; double dir; double stepa = 0.0, stepb, stepc = state->step, tol = state->tol; double g1norm; double pg; if (pnorm == 0.0 || g0norm == 0.0) { gsl_vector_set_zero (dx); return GSL_ENOPROG; } /* Determine which direction is downhill, +p or -p */ gsl_blas_ddot (p, gradient, &pg); dir = (pg >= 0.0) ? +1.0 : -1.0; /* Compute new trial point at x_c= x - step * p, where p is the current direction */ take_step (x, p, stepc, dir / pnorm, x1, dx); /* Evaluate function and gradient at new point xc */ fc = GSL_MULTIMIN_FN_EVAL_F (fdf, x1); if (fc < fa) { /* Success, reduced the function value */ state->step = stepc * 2.0; *f = fc; gsl_vector_memcpy (x, x1); GSL_MULTIMIN_FN_EVAL_DF (fdf, x1, gradient); return GSL_SUCCESS; } #ifdef DEBUG printf ("got stepc = %g fc = %g\n", stepc, fc); #endif /* Do a line minimisation in the region (xa,fa) (xc,fc) to find an intermediate (xb,fb) satisifying fa > fb < fc. Choose an initial xb based on parabolic interpolation */ intermediate_point (fdf, x, p, dir / pnorm, pg, stepa, stepc, fa, fc, x1, dx1, gradient, &stepb, &fb); if (stepb == 0.0) { return GSL_ENOPROG; } minimize (fdf, x, p, dir / pnorm, stepa, stepb, stepc, fa, fb, fc, tol, x1, dx1, x2, dx, gradient, &(state->step), f, &g1norm); gsl_vector_memcpy (x, x2); /* Choose a new conjugate direction for the next step */ state->iter = (state->iter + 1) % x->size; if (state->iter == 0) { gsl_vector_memcpy (p, gradient); state->pnorm = g1norm; } else { /* p' = g1 - beta * p */ double beta = -pow (g1norm / g0norm, 2.0); gsl_blas_dscal (-beta, p); gsl_blas_daxpy (1.0, gradient, p); state->pnorm = gsl_blas_dnrm2 (p); } state->g0norm = g1norm; gsl_vector_memcpy (g0, gradient); #ifdef DEBUG printf ("updated conjugate directions\n"); printf ("p: "); gsl_vector_fprintf (stdout, p, "%g"); printf ("g: "); gsl_vector_fprintf (stdout, gradient, "%g"); #endif return GSL_SUCCESS; } static const gsl_multimin_fdfminimizer_type conjugate_fr_type = { "conjugate_fr", /* name */ sizeof (conjugate_fr_state_t), &conjugate_fr_alloc, &conjugate_fr_set, &conjugate_fr_iterate, &conjugate_fr_restart, &conjugate_fr_free }; const gsl_multimin_fdfminimizer_type * gsl_multimin_fdfminimizer_conjugate_fr = &conjugate_fr_type; praat-6.0.04/external/gsl/gsl_multimin__conjugate_pr.c000066400000000000000000000152431261542461700231020ustar00rootroot00000000000000/* multimin/conjugate_pr.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Fabrice Rossi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* conjugate_pr.c -- Conjugate gradient Polak-Ribiere algorithm */ /* Modified by Brian Gough to use single iteration structure */ #include "gsl__config.h" #include "gsl_multimin.h" #include "gsl_blas.h" #include "gsl_multimin__directional_minimize.c" typedef struct { int iter; double step; double max_step; double tol; gsl_vector *x1; gsl_vector *dx1; gsl_vector *x2; double pnorm; gsl_vector *p; double g0norm; gsl_vector *g0; } conjugate_pr_state_t; static int conjugate_pr_alloc (void *vstate, size_t n) { conjugate_pr_state_t *state = (conjugate_pr_state_t *) vstate; state->x1 = gsl_vector_calloc (n); if (state->x1 == 0) { GSL_ERROR ("failed to allocate space for x1", GSL_ENOMEM); } state->dx1 = gsl_vector_calloc (n); if (state->dx1 == 0) { gsl_vector_free (state->x1); GSL_ERROR ("failed to allocate space for dx1", GSL_ENOMEM); } state->x2 = gsl_vector_calloc (n); if (state->x2 == 0) { gsl_vector_free (state->dx1); gsl_vector_free (state->x1); GSL_ERROR ("failed to allocate space for x2", GSL_ENOMEM); } state->p = gsl_vector_calloc (n); if (state->p == 0) { gsl_vector_free (state->x2); gsl_vector_free (state->dx1); gsl_vector_free (state->x1); GSL_ERROR ("failed to allocate space for p", GSL_ENOMEM); } state->g0 = gsl_vector_calloc (n); if (state->g0 == 0) { gsl_vector_free (state->p); gsl_vector_free (state->x2); gsl_vector_free (state->dx1); gsl_vector_free (state->x1); GSL_ERROR ("failed to allocate space for g0", GSL_ENOMEM); } return GSL_SUCCESS; } static int conjugate_pr_set (void *vstate, gsl_multimin_function_fdf * fdf, const gsl_vector * x, double *f, gsl_vector * gradient, double step_size, double tol) { conjugate_pr_state_t *state = (conjugate_pr_state_t *) vstate; state->iter = 0; state->step = step_size; state->max_step = step_size; state->tol = tol; GSL_MULTIMIN_FN_EVAL_F_DF (fdf, x, f, gradient); /* Use the gradient as the initial direction */ gsl_vector_memcpy (state->p, gradient); gsl_vector_memcpy (state->g0, gradient); { double gnorm = gsl_blas_dnrm2 (gradient); state->pnorm = gnorm; state->g0norm = gnorm; } return GSL_SUCCESS; } static void conjugate_pr_free (void *vstate) { conjugate_pr_state_t *state = (conjugate_pr_state_t *) vstate; gsl_vector_free (state->g0); gsl_vector_free (state->p); gsl_vector_free (state->x2); gsl_vector_free (state->dx1); gsl_vector_free (state->x1); } static int conjugate_pr_restart (void *vstate) { conjugate_pr_state_t *state = (conjugate_pr_state_t *) vstate; state->iter = 0; return GSL_SUCCESS; } static int conjugate_pr_iterate (void *vstate, gsl_multimin_function_fdf * fdf, gsl_vector * x, double *f, gsl_vector * gradient, gsl_vector * dx) { conjugate_pr_state_t *state = (conjugate_pr_state_t *) vstate; gsl_vector *x1 = state->x1; gsl_vector *dx1 = state->dx1; gsl_vector *x2 = state->x2; gsl_vector *p = state->p; gsl_vector *g0 = state->g0; double pnorm = state->pnorm; double g0norm = state->g0norm; double fa = *f, fb, fc; double dir; double stepa = 0.0, stepb, stepc = state->step, tol = state->tol; double g1norm; double pg; if (pnorm == 0.0 || g0norm == 0.0) { gsl_vector_set_zero (dx); return GSL_ENOPROG; } /* Determine which direction is downhill, +p or -p */ gsl_blas_ddot (p, gradient, &pg); dir = (pg >= 0.0) ? +1.0 : -1.0; /* Compute new trial point at x_c= x - step * p, where p is the current direction */ take_step (x, p, stepc, dir / pnorm, x1, dx); /* Evaluate function and gradient at new point xc */ fc = GSL_MULTIMIN_FN_EVAL_F (fdf, x1); if (fc < fa) { /* Success, reduced the function value */ state->step = stepc * 2.0; *f = fc; gsl_vector_memcpy (x, x1); GSL_MULTIMIN_FN_EVAL_DF (fdf, x1, gradient); return GSL_SUCCESS; } #ifdef DEBUG printf ("got stepc = %g fc = %g\n", stepc, fc); #endif /* Do a line minimisation in the region (xa,fa) (xc,fc) to find an intermediate (xb,fb) satisifying fa > fb < fc. Choose an initial xb based on parabolic interpolation */ intermediate_point (fdf, x, p, dir / pnorm, pg, stepa, stepc, fa, fc, x1, dx1, gradient, &stepb, &fb); if (stepb == 0.0) { return GSL_ENOPROG; } minimize (fdf, x, p, dir / pnorm, stepa, stepb, stepc, fa, fb, fc, tol, x1, dx1, x2, dx, gradient, &(state->step), f, &g1norm); gsl_vector_memcpy (x, x2); /* Choose a new conjugate direction for the next step */ state->iter = (state->iter + 1) % x->size; if (state->iter == 0) { gsl_vector_memcpy (p, gradient); state->pnorm = g1norm; } else { /* p' = g1 - beta * p */ double g0g1, beta; gsl_blas_daxpy (-1.0, gradient, g0); /* g0' = g0 - g1 */ gsl_blas_ddot(g0, gradient, &g0g1); /* g1g0 = (g0-g1).g1 */ beta = g0g1 / (g0norm*g0norm); /* beta = -((g1 - g0).g1)/(g0.g0) */ gsl_blas_dscal (-beta, p); gsl_blas_daxpy (1.0, gradient, p); state->pnorm = gsl_blas_dnrm2 (p); } state->g0norm = g1norm; gsl_vector_memcpy (g0, gradient); #ifdef DEBUG printf ("updated conjugate directions\n"); printf ("p: "); gsl_vector_fprintf (stdout, p, "%g"); printf ("g: "); gsl_vector_fprintf (stdout, gradient, "%g"); #endif return GSL_SUCCESS; } static const gsl_multimin_fdfminimizer_type conjugate_pr_type = { "conjugate_pr", /* name */ sizeof (conjugate_pr_state_t), &conjugate_pr_alloc, &conjugate_pr_set, &conjugate_pr_iterate, &conjugate_pr_restart, &conjugate_pr_free }; const gsl_multimin_fdfminimizer_type * gsl_multimin_fdfminimizer_conjugate_pr = &conjugate_pr_type; praat-6.0.04/external/gsl/gsl_multimin__convergence.c000066400000000000000000000026431261542461700227200ustar00rootroot00000000000000/* multimin/convergence.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Fabrice Rossi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_multimin.h" #include "gsl_blas.h" int gsl_multimin_test_gradient (const gsl_vector *g, double epsabs) { double norm; if (epsabs < 0.0) { GSL_ERROR ("absolute tolerance is negative", GSL_EBADTOL); } norm = gsl_blas_dnrm2(g); if (norm < epsabs) { return GSL_SUCCESS; } return GSL_CONTINUE; } int gsl_multimin_test_size (const double size, double epsabs) { if (epsabs < 0.0) { GSL_ERROR ("absolute tolerance is negative", GSL_EBADTOL); } if (size < epsabs) { return GSL_SUCCESS; } return GSL_CONTINUE; } praat-6.0.04/external/gsl/gsl_multimin__diff.c000066400000000000000000000030571261542461700213320ustar00rootroot00000000000000/* multimin/diff.c * * Copyright (C) 2000 David Morrison * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_multimin.h" int gsl_multimin_diff (const gsl_multimin_function * f, const gsl_vector * x, gsl_vector * g) { size_t i, n = f->n; double h = GSL_SQRT_DBL_EPSILON; gsl_vector * x1 = gsl_vector_alloc (n); /* FIXME: pass as argument */ gsl_vector_memcpy (x1, x); for (i = 0; i < n; i++) { double fl, fh; double xi = gsl_vector_get (x, i); double dx = fabs(xi) * h; if (dx == 0.0) dx = h; gsl_vector_set (x1, i, xi + dx); fh = GSL_MULTIMIN_FN_EVAL(f, x1); gsl_vector_set (x1, i, xi - dx); fl = GSL_MULTIMIN_FN_EVAL(f, x1); gsl_vector_set (x1, i, xi); gsl_vector_set (g, i, (fh - fl) / (2.0 * dx)); } gsl_vector_free (x1); return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_multimin__directional_minimize.c000066400000000000000000000126001261542461700246120ustar00rootroot00000000000000/* multimin/directional_minimize.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Fabrice Rossi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static void take_step (const gsl_vector * x, const gsl_vector * p, double step, double lambda, gsl_vector * x1, gsl_vector * dx) { gsl_vector_set_zero (dx); gsl_blas_daxpy (-step * lambda, p, dx); gsl_vector_memcpy (x1, x); gsl_blas_daxpy (1.0, dx, x1); } static void intermediate_point (gsl_multimin_function_fdf * fdf, const gsl_vector * x, const gsl_vector * p, double lambda, double pg, double stepa, double stepc, double fa, double fc, gsl_vector * x1, gsl_vector * dx, gsl_vector * gradient, double * step, double * f) { double stepb, fb; trial: { double u = fabs (pg * lambda * stepc); stepb = 0.5 * stepc * u / ((fc - fa) + u); } take_step (x, p, stepb, lambda, x1, dx); fb = GSL_MULTIMIN_FN_EVAL_F (fdf, x1); #ifdef DEBUG printf ("trying stepb = %g fb = %.18e\n", stepb, fb); #endif if (fb >= fa && stepb > 0.0) { /* downhill step failed, reduce step-size and try again */ fc = fb; stepc = stepb; goto trial; } #ifdef DEBUG printf ("ok!\n"); #endif *step = stepb; *f = fb; GSL_MULTIMIN_FN_EVAL_DF(fdf, x1, gradient); } static void minimize (gsl_multimin_function_fdf * fdf, const gsl_vector * x, const gsl_vector * p, double lambda, double stepa, double stepb, double stepc, double fa, double fb, double fc, double tol, gsl_vector * x1, gsl_vector * dx1, gsl_vector * x2, gsl_vector * dx2, gsl_vector * gradient, double * step, double * f, double * gnorm) { /* Starting at (x0, f0) move along the direction p to find a minimum f(x0 - lambda * p), returning the new point x1 = x0-lambda*p, f1=f(x1) and g1 = grad(f) at x1. */ double u = stepb; double v = stepa; double w = stepc; double fu = fb; double fv = fa; double fw = fc; double old2 = fabs(w - v); double old1 = fabs(v - u); double stepm, fm, pg, gnorm1; int iter = 0; gsl_vector_memcpy (x2, x1); gsl_vector_memcpy (dx2, dx1); *f = fb; *step = stepb; *gnorm = gsl_blas_dnrm2 (gradient); mid_trial: iter++; if (iter > 10) { return; /* MAX ITERATIONS */ } { double dw = w - u; double dv = v - u; double du = 0.0; double e1 = ((fv - fu) * dw * dw + (fu - fw) * dv * dv); double e2 = 2.0 * ((fv - fu) * dw + (fu - fw) * dv); if (e2 != 0.0) { du = e1 / e2; } if (du > 0.0 && du < (stepc - stepb) && fabs(du) < 0.5 * old2) { stepm = u + du; } else if (du < 0.0 && du > (stepa - stepb) && fabs(du) < 0.5 * old2) { stepm = u + du; } else if ((stepc - stepb) > (stepb - stepa)) { stepm = 0.38 * (stepc - stepb) + stepb; } else { stepm = stepb - 0.38 * (stepb - stepa); } } take_step (x, p, stepm, lambda, x1, dx1); fm = GSL_MULTIMIN_FN_EVAL_F (fdf, x1); #ifdef DEBUG printf ("trying stepm = %g fm = %.18e\n", stepm, fm); #endif if (fm > fb) { if (fm < fv) { w = v; v = stepm; fw = fv; fv = fm; } else if (fm < fw) { w = stepm; fw = fm; } if (stepm < stepb) { stepa = stepm; fa = fm; } else { stepc = stepm; fc = fm; } goto mid_trial; } else if (fm <= fb) { old2 = old1; old1 = fabs(u - stepm); w = v; v = u; u = stepm; fw = fv; fv = fu; fu = fm; gsl_vector_memcpy (x2, x1); gsl_vector_memcpy (dx2, dx1); GSL_MULTIMIN_FN_EVAL_DF (fdf, x1, gradient); gsl_blas_ddot (p, gradient, &pg); gnorm1 = gsl_blas_dnrm2 (gradient); #ifdef DEBUG printf ("p: "); gsl_vector_fprintf(stdout, p, "%g"); printf ("g: "); gsl_vector_fprintf(stdout, gradient, "%g"); printf ("gnorm: %.18e\n", gnorm1); printf ("pg: %.18e\n", pg); printf ("orth: %g\n", fabs (pg * lambda/ gnorm1)); #endif *f = fm; *step = stepm; *gnorm = gnorm1; if (fabs (pg * lambda / gnorm1) < tol) { #ifdef DEBUG printf("ok!\n"); #endif return; /* SUCCESS */ } if (stepm < stepb) { stepc = stepb; fc = fb; stepb = stepm; fb = fm; } else { stepa = stepb; fa = fb; stepb = stepm; fb = fm; } goto mid_trial; } } praat-6.0.04/external/gsl/gsl_multimin__fdfminimizer.c000066400000000000000000000100611261542461700230760ustar00rootroot00000000000000/* multimin/fdfminimizer.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Fabrice Rossi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_multimin.h" gsl_multimin_fdfminimizer * gsl_multimin_fdfminimizer_alloc (const gsl_multimin_fdfminimizer_type * T, size_t n) { int status; gsl_multimin_fdfminimizer *s = (gsl_multimin_fdfminimizer *) malloc (sizeof (gsl_multimin_fdfminimizer)); if (s == 0) { GSL_ERROR_VAL ("failed to allocate space for minimizer struct", GSL_ENOMEM, 0); } s->type = T; s->x = gsl_vector_calloc (n); if (s->x == 0) { free (s); GSL_ERROR_VAL ("failed to allocate space for x", GSL_ENOMEM, 0); } s->gradient = gsl_vector_calloc (n); if (s->gradient == 0) { gsl_vector_free (s->x); free (s); GSL_ERROR_VAL ("failed to allocate space for gradient", GSL_ENOMEM, 0); } s->dx = gsl_vector_calloc (n); if (s->dx == 0) { gsl_vector_free (s->x); gsl_vector_free (s->gradient); free (s); GSL_ERROR_VAL ("failed to allocate space for dx", GSL_ENOMEM, 0); } s->state = malloc (T->size); if (s->state == 0) { gsl_vector_free (s->x); gsl_vector_free (s->gradient); gsl_vector_free (s->dx); free (s); GSL_ERROR_VAL ("failed to allocate space for minimizer state", GSL_ENOMEM, 0); } status = (T->alloc) (s->state, n); if (status != GSL_SUCCESS) { free (s->state); gsl_vector_free (s->x); gsl_vector_free (s->gradient); gsl_vector_free (s->dx); free (s); GSL_ERROR_VAL ("failed to initialize minimizer state", GSL_ENOMEM, 0); } return s; } int gsl_multimin_fdfminimizer_set (gsl_multimin_fdfminimizer * s, gsl_multimin_function_fdf * fdf, const gsl_vector * x, double step_size, double tol) { if (s->x->size != fdf->n) { GSL_ERROR ("function incompatible with solver size", GSL_EBADLEN); } if (x->size != fdf->n) { GSL_ERROR ("vector length not compatible with function", GSL_EBADLEN); } s->fdf = fdf; gsl_vector_memcpy (s->x,x); gsl_vector_set_zero (s->dx); return (s->type->set) (s->state, s->fdf, s->x, &(s->f), s->gradient, step_size, tol); } void gsl_multimin_fdfminimizer_free (gsl_multimin_fdfminimizer * s) { (s->type->free) (s->state); free (s->state); gsl_vector_free (s->dx); gsl_vector_free (s->gradient); gsl_vector_free (s->x); free (s); } int gsl_multimin_fdfminimizer_iterate (gsl_multimin_fdfminimizer * s) { return (s->type->iterate) (s->state, s->fdf, s->x, &(s->f), s->gradient, s->dx); } int gsl_multimin_fdfminimizer_restart (gsl_multimin_fdfminimizer * s) { return (s->type->restart) (s->state); } const char * gsl_multimin_fdfminimizer_name (const gsl_multimin_fdfminimizer * s) { return s->type->name; } gsl_vector * gsl_multimin_fdfminimizer_x (gsl_multimin_fdfminimizer * s) { return s->x; } gsl_vector * gsl_multimin_fdfminimizer_dx (gsl_multimin_fdfminimizer * s) { return s->dx; } gsl_vector * gsl_multimin_fdfminimizer_gradient (gsl_multimin_fdfminimizer * s) { return s->gradient; } double gsl_multimin_fdfminimizer_minimum (gsl_multimin_fdfminimizer * s) { return s->f; } praat-6.0.04/external/gsl/gsl_multimin__fminimizer.c000066400000000000000000000062211261542461700225670ustar00rootroot00000000000000/* multimin/fminimizer.c * * Copyright (C) 2002 Tuomo Keskitalo, Ivo Alxneit * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_multimin.h" gsl_multimin_fminimizer * gsl_multimin_fminimizer_alloc (const gsl_multimin_fminimizer_type * T, size_t n) { int status; gsl_multimin_fminimizer *s = (gsl_multimin_fminimizer *) malloc (sizeof (gsl_multimin_fminimizer)); if (s == 0) { GSL_ERROR_VAL ("failed to allocate space for minimizer struct", GSL_ENOMEM, 0); } s->type = T; s->x = gsl_vector_calloc (n); if (s->x == 0) { free (s); GSL_ERROR_VAL ("failed to allocate space for x", GSL_ENOMEM, 0); } s->state = malloc (T->size); if (s->state == 0) { gsl_vector_free (s->x); free (s); GSL_ERROR_VAL ("failed to allocate space for minimizer state", GSL_ENOMEM, 0); } status = (T->alloc) (s->state, n); if (status != GSL_SUCCESS) { free (s->state); gsl_vector_free (s->x); free (s); GSL_ERROR_VAL ("failed to initialize minimizer state", GSL_ENOMEM, 0); } return s; } int gsl_multimin_fminimizer_set (gsl_multimin_fminimizer * s, gsl_multimin_function * f, const gsl_vector * x, const gsl_vector * step_size) { if (s->x->size != f->n) { GSL_ERROR ("function incompatible with solver size", GSL_EBADLEN); } if (x->size != f->n || step_size->size != f->n) { GSL_ERROR ("vector length not compatible with function", GSL_EBADLEN); } s->f = f; gsl_vector_memcpy (s->x,x); return (s->type->set) (s->state, s->f, s->x, &(s->size), step_size); } void gsl_multimin_fminimizer_free (gsl_multimin_fminimizer * s) { (s->type->free) (s->state); free (s->state); gsl_vector_free (s->x); free (s); } int gsl_multimin_fminimizer_iterate (gsl_multimin_fminimizer * s) { return (s->type->iterate) (s->state, s->f, s->x, &(s->size), &(s->fval)); } const char * gsl_multimin_fminimizer_name (const gsl_multimin_fminimizer * s) { return s->type->name; } gsl_vector * gsl_multimin_fminimizer_x (const gsl_multimin_fminimizer * s) { return s->x; } double gsl_multimin_fminimizer_minimum (const gsl_multimin_fminimizer * s) { return s->fval; } double gsl_multimin_fminimizer_size (const gsl_multimin_fminimizer * s) { return s->size; } praat-6.0.04/external/gsl/gsl_multimin__linear_minimize.c000066400000000000000000000141341261542461700235730ustar00rootroot00000000000000#include "gsl_math.h" #include "gsl_errno.h" #include "gsl_poly.h" /* Find a minimum in x=[0,1] of the interpolating quadratic through * (0,f0) (1,f1) with derivative fp0 at x=0. The interpolating * polynomial is q(x) = f0 + fp0 * z + (f1-f0-fp0) * z^2 */ static double interp_quad (double f0, double fp0, double f1, double zl, double zh) { double fl = f0 + zl*(fp0 + zl*(f1 - f0 -fp0)); double fh = f0 + zh*(fp0 + zh*(f1 - f0 -fp0)); double c = 2 * (f1 - f0 - fp0); /* curvature */ double zmin = zl, fmin = fl; if (fh < fmin) { zmin = zh; fmin = fh; } if (c > 0) /* positive curvature required for a minimum */ { double z = -fp0 / c; /* location of minimum */ if (z > zl && z < zh) { double f = f0 + z*(fp0 + z*(f1 - f0 -fp0)); if (f < fmin) { zmin = z; fmin = f; }; } } return zmin; } /* Find a minimum in x=[0,1] of the interpolating cubic through * (0,f0) (1,f1) with derivatives fp0 at x=0 and fp1 at x=1. * * The interpolating polynomial is: * * c(x) = f0 + fp0 * z + eta * z^2 + xi * z^3 * * where eta=3*(f1-f0)-2*fp0-fp1, xi=fp0+fp1-2*(f1-f0). */ static double cubic (double c0, double c1, double c2, double c3, double z) { return c0 + z * (c1 + z * (c2 + z * c3)); } static void check_extremum (double c0, double c1, double c2, double c3, double z, double *zmin, double *fmin) { /* could make an early return by testing curvature >0 for minimum */ double y = cubic (c0, c1, c2, c3, z); if (y < *fmin) { *zmin = z; /* accepted new point*/ *fmin = y; } } static double interp_cubic (double f0, double fp0, double f1, double fp1, double zl, double zh) { double eta = 3 * (f1 - f0) - 2 * fp0 - fp1; double xi = fp0 + fp1 - 2 * (f1 - f0); double c0 = f0, c1 = fp0, c2 = eta, c3 = xi; double zmin, fmin; double z0, z1; zmin = zl; fmin = cubic(c0, c1, c2, c3, zl); check_extremum (c0, c1, c2, c3, zh, &zmin, &fmin); { int n = gsl_poly_solve_quadratic (3 * c3, 2 * c2, c1, &z0, &z1); if (n == 2) /* found 2 roots */ { if (z0 > zl && z0 < zh) check_extremum (c0, c1, c2, c3, z0, &zmin, &fmin); if (z1 > zl && z1 < zh) check_extremum (c0, c1, c2, c3, z1, &zmin, &fmin); } else if (n == 1) /* found 1 root */ { if (z0 > zl && z0 < zh) check_extremum (c0, c1, c2, c3, z0, &zmin, &fmin); } } return zmin; } static double interpolate (double a, double fa, double fpa, double b, double fb, double fpb, double xmin, double xmax, int order) { /* Map [a,b] to [0,1] */ double z, alpha, zmin, zmax; zmin = (xmin - a) / (b - a); zmax = (xmax - a) / (b - a); if (zmin > zmax) { double tmp = zmin; zmin = zmax; zmax = tmp; }; if (order > 2 && GSL_IS_REAL(fpb)) { z = interp_cubic (fa, fpa * (b - a), fb, fpb * (b - a), zmin, zmax); } else { z = interp_quad (fa, fpa * (b - a), fb, zmin, zmax); } alpha = a + z * (b - a); return alpha; } /* recommended values from Fletcher are rho = 0.01, sigma = 0.1, tau1 = 9, tau2 = 0.05, tau3 = 0.5 */ static int minimize (gsl_function_fdf * fn, double rho, double sigma, double tau1, double tau2, double tau3, int order, double alpha1, double *alpha_new) { double f0, fp0, falpha, falpha_prev, fpalpha, fpalpha_prev, delta, alpha_next; double alpha = alpha1, alpha_prev = 0.0; double a, b, fa, fb, fpa, fpb; const size_t bracket_iters = 100, section_iters = 100; size_t i = 0; GSL_FN_FDF_EVAL_F_DF (fn, 0.0, &f0, &fp0); falpha_prev = f0; fpalpha_prev = fp0; /* Avoid uninitialized variables morning */ a = 0.0; b = alpha; fa = f0; fb = 0.0; fpa = fp0; fpb = 0.0; /* Begin bracketing */ while (i++ < bracket_iters) { falpha = GSL_FN_FDF_EVAL_F (fn, alpha); /* Fletcher's rho test */ if (falpha > f0 + alpha * rho * fp0 || falpha >= falpha_prev) { a = alpha_prev; fa = falpha_prev; fpa = fpalpha_prev; b = alpha; fb = falpha; fpb = GSL_NAN; break; /* goto sectioning */ } fpalpha = GSL_FN_FDF_EVAL_DF (fn, alpha); /* Fletcher's sigma test */ if (fabs (fpalpha) <= -sigma * fp0) { *alpha_new = alpha; return GSL_SUCCESS; } if (fpalpha >= 0) { a = alpha; fa = falpha; fpa = fpalpha; b = alpha_prev; fb = falpha_prev; fpb = fpalpha_prev; break; /* goto sectioning */ } delta = alpha - alpha_prev; { double lower = alpha + delta; double upper = alpha + tau1 * delta; alpha_next = interpolate (alpha_prev, falpha_prev, fpalpha_prev, alpha, falpha, fpalpha, lower, upper, order); } alpha_prev = alpha; falpha_prev = falpha; fpalpha_prev = fpalpha; alpha = alpha_next; } /* Sectioning of bracket [a,b] */ while (i++ < section_iters) { delta = b - a; { double lower = a + tau2 * delta; double upper = b - tau3 * delta; alpha = interpolate (a, fa, fpa, b, fb, fpb, lower, upper, order); } falpha = GSL_FN_FDF_EVAL_F (fn, alpha); if ((a-alpha)*fpa <= GSL_DBL_EPSILON) { /* roundoff prevents progress */ return GSL_ENOPROG; }; if (falpha > f0 + rho * alpha * fp0 || falpha >= fa) { /* a_next = a; */ b = alpha; fb = falpha; fpb = GSL_NAN; } else { fpalpha = GSL_FN_FDF_EVAL_DF (fn, alpha); if (fabs(fpalpha) <= -sigma * fp0) { *alpha_new = alpha; return GSL_SUCCESS; /* terminate */ } if ( ((b-a) >= 0 && fpalpha >= 0) || ((b-a) <=0 && fpalpha <= 0)) { b = a; fb = fa; fpb = fpa; a = alpha; fa = falpha; fpa = fpalpha; } else { a = alpha; fa = falpha; fpa = fpalpha; } } } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_multimin__linear_wrapper.c000066400000000000000000000077341261542461700234420ustar00rootroot00000000000000typedef struct { gsl_function_fdf fdf_linear; gsl_multimin_function_fdf *fdf; /* fixed values */ const gsl_vector *x; const gsl_vector *g; const gsl_vector *p; /* cached values, for x(alpha) = x + alpha * p */ double f_alpha; double df_alpha; gsl_vector *x_alpha; gsl_vector *g_alpha; /* cache "keys" */ double f_cache_key; double df_cache_key; double x_cache_key; double g_cache_key; } wrapper_t; static void moveto (double alpha, wrapper_t * w) { if (alpha == w->x_cache_key) /* using previously cached position */ { return; } /* set x_alpha = x + alpha * p */ gsl_vector_memcpy (w->x_alpha, w->x); gsl_blas_daxpy (alpha, w->p, w->x_alpha); w->x_cache_key = alpha; } static double slope (wrapper_t * w) /* compute gradient . direction */ { double df; gsl_blas_ddot (w->g_alpha, w->p, &df); return df; } static double wrap_f (double alpha, void *params) { wrapper_t *w = (wrapper_t *) params; if (alpha == w->f_cache_key) /* using previously cached f(alpha) */ { return w->f_alpha; } moveto (alpha, w); w->f_alpha = GSL_MULTIMIN_FN_EVAL_F (w->fdf, w->x_alpha); w->f_cache_key = alpha; return w->f_alpha; } static double wrap_df (double alpha, void *params) { wrapper_t *w = (wrapper_t *) params; if (alpha == w->df_cache_key) /* using previously cached df(alpha) */ { return w->df_alpha; } moveto (alpha, w); if (alpha != w->g_cache_key) { GSL_MULTIMIN_FN_EVAL_DF (w->fdf, w->x_alpha, w->g_alpha); w->g_cache_key = alpha; } w->df_alpha = slope (w); w->df_cache_key = alpha; return w->df_alpha; } static void wrap_fdf (double alpha, void *params, double *f, double *df) { wrapper_t *w = (wrapper_t *) params; /* Check for previously cached values */ if (alpha == w->f_cache_key && alpha == w->df_cache_key) { *f = w->f_alpha; *df = w->df_alpha; return; } if (alpha == w->f_cache_key || alpha == w->df_cache_key) { *f = wrap_f (alpha, params); *df = wrap_df (alpha, params); return; } moveto (alpha, w); GSL_MULTIMIN_FN_EVAL_F_DF (w->fdf, w->x_alpha, &w->f_alpha, w->g_alpha); w->f_cache_key = alpha; w->g_cache_key = alpha; w->df_alpha = slope (w); w->df_cache_key = alpha; *f = w->f_alpha; *df = w->df_alpha; } static void prepare_wrapper (wrapper_t * w, gsl_multimin_function_fdf * fdf, const gsl_vector * x, double f, const gsl_vector *g, const gsl_vector * p, gsl_vector * x_alpha, gsl_vector *g_alpha) { w->fdf_linear.f = &wrap_f; w->fdf_linear.df = &wrap_df; w->fdf_linear.fdf = &wrap_fdf; w->fdf_linear.params = (void *)w; /* pointer to "self" */ w->fdf = fdf; w->x = x; w->g = g; w->p = p; w->x_alpha = x_alpha; w->g_alpha = g_alpha; gsl_vector_memcpy(w->x_alpha, w->x); w->x_cache_key = 0.0; w->f_alpha = f; w->f_cache_key = 0.0; gsl_vector_memcpy(w->g_alpha, w->g); w->g_cache_key = 0.0; w->df_alpha = slope(w); w->df_cache_key = 0.0; } static void update_position (wrapper_t * w, double alpha, gsl_vector *x, double *f, gsl_vector *g) { /* ensure that everything is fully cached */ { double f_alpha, df_alpha; wrap_fdf (alpha, w, &f_alpha, &df_alpha); } ; *f = w->f_alpha; gsl_vector_memcpy(x, w->x_alpha); gsl_vector_memcpy(g, w->g_alpha); } static void change_direction (wrapper_t * w) { /* Convert the cache values from the end of the current minimisation to those needed for the start of the next minimisation, alpha=0 */ /* The new x_alpha for alpha=0 is the current position */ gsl_vector_memcpy (w->x_alpha, w->x); w->x_cache_key = 0.0; /* The function value does not change */ w->f_cache_key = 0.0; /* The new g_alpha for alpha=0 is the current gradient at the endpoint */ gsl_vector_memcpy (w->g_alpha, w->g); w->g_cache_key = 0.0; /* Calculate the slope along the new direction vector, p */ w->df_alpha = slope (w); w->df_cache_key = 0.0; } praat-6.0.04/external/gsl/gsl_multimin__simplex.c000066400000000000000000000260001261542461700220740ustar00rootroot00000000000000/* multimin/simplex.c * * Copyright (C) 2007 Brian Gough * Copyright (C) 2002 Tuomo Keskitalo, Ivo Alxneit * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* - Originally written by Tuomo Keskitalo - Corrections to nmsimplex_iterate and other functions by Ivo Alxneit - Additional help by Brian Gough */ /* The Simplex method of Nelder and Mead, also known as the polytope search alogorithm. Ref: Nelder, J.A., Mead, R., Computer Journal 7 (1965) pp. 308-313. This implementation uses n+1 corner points in the simplex. */ #include "gsl__config.h" #include #include "gsl_blas.h" #include "gsl_multimin.h" typedef struct { gsl_matrix *x1; /* simplex corner points */ gsl_vector *y1; /* function value at corner points */ gsl_vector *ws1; /* workspace 1 for algorithm */ gsl_vector *ws2; /* workspace 2 for algorithm */ } nmsimplex_state_t; static double nmsimplex_move_corner (const double coeff, const nmsimplex_state_t * state, size_t corner, gsl_vector * xc, const gsl_multimin_function * f) { /* moves a simplex corner scaled by coeff (negative value represents mirroring by the middle point of the "other" corner points) and gives new corner in xc and function value at xc as a return value */ gsl_matrix *x1 = state->x1; size_t i, j; double newval, mp; for (j = 0; j < x1->size2; j++) { mp = 0.0; for (i = 0; i < x1->size1; i++) { if (i != corner) { mp += (gsl_matrix_get (x1, i, j)); } } mp /= (double) (x1->size1 - 1); newval = mp - coeff * (mp - gsl_matrix_get (x1, corner, j)); gsl_vector_set (xc, j, newval); } newval = GSL_MULTIMIN_FN_EVAL (f, xc); return newval; } static int nmsimplex_contract_by_best (nmsimplex_state_t * state, size_t best, gsl_vector * xc, gsl_multimin_function * f) { /* Function contracts the simplex in respect to best valued corner. That is, all corners besides the best corner are moved. */ /* the xc vector is simply work space here */ gsl_matrix *x1 = state->x1; gsl_vector *y1 = state->y1; size_t i, j; double newval; int status = GSL_SUCCESS; for (i = 0; i < x1->size1; i++) { if (i != best) { for (j = 0; j < x1->size2; j++) { newval = 0.5 * (gsl_matrix_get (x1, i, j) + gsl_matrix_get (x1, best, j)); gsl_matrix_set (x1, i, j, newval); } /* evaluate function in the new point */ gsl_matrix_get_row (xc, x1, i); newval = GSL_MULTIMIN_FN_EVAL (f, xc); gsl_vector_set (y1, i, newval); /* notify caller that we found at least one bad function value. we finish the contraction (and do not abort) to allow the user to handle the situation */ if(!gsl_finite(newval)) { status = GSL_EBADFUNC; } } } return status; } static int nmsimplex_calc_center (const nmsimplex_state_t * state, gsl_vector * mp) { /* calculates the center of the simplex to mp */ gsl_matrix *x1 = state->x1; size_t i, j; double val; for (j = 0; j < x1->size2; j++) { val = 0.0; for (i = 0; i < x1->size1; i++) { val += gsl_matrix_get (x1, i, j); } val /= x1->size1; gsl_vector_set (mp, j, val); } return GSL_SUCCESS; } static double nmsimplex_size (nmsimplex_state_t * state) { /* calculates simplex size as average sum of length of vectors from simplex center to corner points: ( sum ( || y - y_middlepoint || ) ) / n */ gsl_vector *s = state->ws1; gsl_vector *mp = state->ws2; gsl_matrix *x1 = state->x1; size_t i; double ss = 0.0; /* Calculate middle point */ nmsimplex_calc_center (state, mp); for (i = 0; i < x1->size1; i++) { gsl_matrix_get_row (s, x1, i); gsl_blas_daxpy (-1.0, mp, s); ss += gsl_blas_dnrm2 (s); } return ss / (double) (x1->size1); } static int nmsimplex_alloc (void *vstate, size_t n) { nmsimplex_state_t *state = (nmsimplex_state_t *) vstate; if (n == 0) { GSL_ERROR("invalid number of parameters specified", GSL_EINVAL); } state->x1 = gsl_matrix_alloc (n + 1, n); if (state->x1 == NULL) { GSL_ERROR ("failed to allocate space for x1", GSL_ENOMEM); } state->y1 = gsl_vector_alloc (n + 1); if (state->y1 == NULL) { gsl_matrix_free(state->x1); GSL_ERROR ("failed to allocate space for y", GSL_ENOMEM); } state->ws1 = gsl_vector_alloc (n); if (state->ws1 == NULL) { gsl_matrix_free(state->x1); gsl_vector_free(state->y1); GSL_ERROR ("failed to allocate space for ws1", GSL_ENOMEM); } state->ws2 = gsl_vector_alloc (n); if (state->ws2 == NULL) { gsl_matrix_free(state->x1); gsl_vector_free(state->y1); gsl_vector_free(state->ws1); GSL_ERROR ("failed to allocate space for ws2", GSL_ENOMEM); } return GSL_SUCCESS; } static int nmsimplex_set (void *vstate, gsl_multimin_function * f, const gsl_vector * x, double *size, const gsl_vector * step_size) { int status; size_t i; double val; nmsimplex_state_t *state = (nmsimplex_state_t *) vstate; gsl_vector *xtemp = state->ws1; if (xtemp->size != x->size) { GSL_ERROR("incompatible size of x", GSL_EINVAL); } if (xtemp->size != step_size->size) { GSL_ERROR("incompatible size of step_size", GSL_EINVAL); } /* first point is the original x0 */ val = GSL_MULTIMIN_FN_EVAL (f, x); if (!gsl_finite(val)) { GSL_ERROR("non-finite function value encountered", GSL_EBADFUNC); } gsl_matrix_set_row (state->x1, 0, x); gsl_vector_set (state->y1, 0, val); /* following points are initialized to x0 + step_size */ for (i = 0; i < x->size; i++) { status = gsl_vector_memcpy (xtemp, x); if (status != 0) { GSL_ERROR ("vector memcopy failed", GSL_EFAILED); } val = gsl_vector_get (xtemp, i) + gsl_vector_get (step_size, i); gsl_vector_set (xtemp, i, val); val = GSL_MULTIMIN_FN_EVAL (f, xtemp); if (!gsl_finite(val)) { GSL_ERROR("non-finite function value encountered", GSL_EBADFUNC); } gsl_matrix_set_row (state->x1, i + 1, xtemp); gsl_vector_set (state->y1, i + 1, val); } /* Initialize simplex size */ *size = nmsimplex_size (state); return GSL_SUCCESS; } static void nmsimplex_free (void *vstate) { nmsimplex_state_t *state = (nmsimplex_state_t *) vstate; gsl_matrix_free (state->x1); gsl_vector_free (state->y1); gsl_vector_free (state->ws1); gsl_vector_free (state->ws2); } static int nmsimplex_iterate (void *vstate, gsl_multimin_function * f, gsl_vector * x, double *size, double *fval) { /* Simplex iteration tries to minimize function f value */ /* Includes corrections from Ivo Alxneit */ nmsimplex_state_t *state = (nmsimplex_state_t *) vstate; /* xc and xc2 vectors store tried corner point coordinates */ gsl_vector *xc = state->ws1; gsl_vector *xc2 = state->ws2; gsl_vector *y1 = state->y1; gsl_matrix *x1 = state->x1; size_t n = y1->size; size_t i; size_t hi = 0, s_hi = 0, lo = 0; double dhi, ds_hi, dlo; int status; double val, val2; if (xc->size != x->size) { GSL_ERROR("incompatible size of x", GSL_EINVAL); } /* get index of highest, second highest and lowest point */ dhi = ds_hi = dlo = gsl_vector_get (y1, 0); for (i = 1; i < n; i++) { val = (gsl_vector_get (y1, i)); if (val < dlo) { dlo = val; lo = i; } else if (val > dhi) { ds_hi = dhi; s_hi = hi; dhi = val; hi = i; } else if (val > ds_hi) { ds_hi = val; s_hi = i; } } /* reflect the highest value */ val = nmsimplex_move_corner (-1.0, state, hi, xc, f); if (gsl_finite(val) && val < gsl_vector_get (y1, lo)) { /* reflected point becomes lowest point, try expansion */ val2 = nmsimplex_move_corner (-2.0, state, hi, xc2, f); if (gsl_finite(val2) && val2 < gsl_vector_get (y1, lo)) { gsl_matrix_set_row (x1, hi, xc2); gsl_vector_set (y1, hi, val2); } else { gsl_matrix_set_row (x1, hi, xc); gsl_vector_set (y1, hi, val); } } /* reflection does not improve things enough or we got a non-finite (illegal) function value */ else if (!gsl_finite(val) || val > gsl_vector_get (y1, s_hi)) { if (gsl_finite(val) && val <= gsl_vector_get (y1, hi)) { /* if trial point is better than highest point, replace highest point */ gsl_matrix_set_row (x1, hi, xc); gsl_vector_set (y1, hi, val); } /* try one dimensional contraction */ val2 = nmsimplex_move_corner (0.5, state, hi, xc2, f); if (gsl_finite(val2) && val2 <= gsl_vector_get (y1, hi)) { gsl_matrix_set_row (state->x1, hi, xc2); gsl_vector_set (y1, hi, val2); } else { /* contract the whole simplex in respect to the best point */ status = nmsimplex_contract_by_best (state, lo, xc, f); if (status != GSL_SUCCESS) { GSL_ERROR ("nmsimplex_contract_by_best failed", GSL_EFAILED); } } } else { /* trial point is better than second highest point. Replace highest point by it */ gsl_matrix_set_row (x1, hi, xc); gsl_vector_set (y1, hi, val); } /* return lowest point of simplex as x */ lo = gsl_vector_min_index (y1); gsl_matrix_get_row (x, x1, lo); *fval = gsl_vector_get (y1, lo); /* Update simplex size */ *size = nmsimplex_size (state); return GSL_SUCCESS; } static const gsl_multimin_fminimizer_type nmsimplex_type = { "nmsimplex", /* name */ sizeof (nmsimplex_state_t), &nmsimplex_alloc, &nmsimplex_set, &nmsimplex_iterate, &nmsimplex_free }; const gsl_multimin_fminimizer_type * gsl_multimin_fminimizer_nmsimplex = &nmsimplex_type; praat-6.0.04/external/gsl/gsl_multimin__steepest_descent.c000066400000000000000000000100361261542461700237560ustar00rootroot00000000000000/* multimin/steepest_descent.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Fabrice Rossi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* steepest_descent.c -- the steepest descent algorithm */ /* Modified by Brian Gough to use single iteration structure */ #include "gsl__config.h" #include "gsl_multimin.h" #include "gsl_blas_types.h" #include "gsl_blas.h" typedef struct { double step; double max_step; double tol; gsl_vector *x1; gsl_vector *g1; } steepest_descent_state_t; static int steepest_descent_alloc (void *vstate, size_t n) { steepest_descent_state_t *state = (steepest_descent_state_t *) vstate; state->x1 = gsl_vector_alloc (n); if (state->x1 == NULL) { GSL_ERROR ("failed to allocate space for x1", GSL_ENOMEM); } state->g1 = gsl_vector_alloc (n); if (state->g1 == NULL) { gsl_vector_free (state->x1); GSL_ERROR ("failed to allocate space for g1", GSL_ENOMEM); } return GSL_SUCCESS; } static int steepest_descent_set (void *vstate, gsl_multimin_function_fdf * fdf, const gsl_vector * x, double *f, gsl_vector * gradient, double step_size, double tol) { steepest_descent_state_t *state = (steepest_descent_state_t *) vstate; GSL_MULTIMIN_FN_EVAL_F_DF (fdf, x, f, gradient); state->step = step_size; state->max_step = step_size; state->tol = tol; return GSL_SUCCESS; } static void steepest_descent_free (void *vstate) { steepest_descent_state_t *state = (steepest_descent_state_t *) vstate; gsl_vector_free (state->x1); gsl_vector_free (state->g1); } static int steepest_descent_restart (void *vstate) { steepest_descent_state_t *state = (steepest_descent_state_t *) vstate; state->step = state->max_step; return GSL_SUCCESS; } static int steepest_descent_iterate (void *vstate, gsl_multimin_function_fdf * fdf, gsl_vector * x, double *f, gsl_vector * gradient, gsl_vector * dx) { steepest_descent_state_t *state = (steepest_descent_state_t *) vstate; gsl_vector *x1 = state->x1; gsl_vector *g1 = state->g1; double f0 = *f; double f1; double step = state->step, tol = state->tol; int failed = 0; /* compute new trial point at x1= x - step * dir, where dir is the normalized gradient */ double gnorm = gsl_blas_dnrm2 (gradient); if (gnorm == 0.0) { gsl_vector_set_zero (dx); return GSL_ENOPROG; } trial: gsl_vector_set_zero (dx); gsl_blas_daxpy (-step / gnorm, gradient, dx); gsl_vector_memcpy (x1, x); gsl_blas_daxpy (1.0, dx, x1); /* evaluate function and gradient at new point x1 */ GSL_MULTIMIN_FN_EVAL_F_DF (fdf, x1, &f1, g1); if (f1 > f0) { /* downhill step failed, reduce step-size and try again */ failed = 1; step *= tol; goto trial; } if (failed) step *= tol; else step *= 2.0; state->step = step; gsl_vector_memcpy (x, x1); gsl_vector_memcpy (gradient, g1); *f = f1; return GSL_SUCCESS; } static const gsl_multimin_fdfminimizer_type steepest_descent_type = { "steepest_descent", /* name */ sizeof (steepest_descent_state_t), &steepest_descent_alloc, &steepest_descent_set, &steepest_descent_iterate, &steepest_descent_restart, &steepest_descent_free }; const gsl_multimin_fdfminimizer_type * gsl_multimin_fdfminimizer_steepest_descent = &steepest_descent_type; praat-6.0.04/external/gsl/gsl_multimin__vector_bfgs.c000066400000000000000000000207541261542461700227300ustar00rootroot00000000000000/* multimin/vector_bfgs.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Fabrice Rossi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* vector_bfgs.c -- Limited memory Broyden-Fletcher-Goldfarb-Shanno method */ /* Modified by Brian Gough to use single iteration structure */ #include "gsl__config.h" #include "gsl_multimin.h" #include "gsl_blas.h" #include "gsl_multimin__directional_minimize.c" typedef struct { int iter; double step; double max_step; double tol; gsl_vector *x1; gsl_vector *dx1; gsl_vector *x2; double g0norm; double pnorm; gsl_vector *p; gsl_vector *x0; gsl_vector *g0; gsl_vector *dx0; gsl_vector *dg0; } vector_bfgs_state_t; static int vector_bfgs_alloc (void *vstate, size_t n) { vector_bfgs_state_t *state = (vector_bfgs_state_t *) vstate; state->x1 = gsl_vector_calloc (n); if (state->x1 == 0) { GSL_ERROR ("failed to allocate space for x1", GSL_ENOMEM); } state->dx1 = gsl_vector_calloc (n); if (state->dx1 == 0) { gsl_vector_free (state->x1); GSL_ERROR ("failed to allocate space for dx1", GSL_ENOMEM); } state->x2 = gsl_vector_calloc (n); if (state->x2 == 0) { gsl_vector_free (state->dx1); gsl_vector_free (state->x1); GSL_ERROR ("failed to allocate space for x2", GSL_ENOMEM); } state->p = gsl_vector_calloc (n); if (state->p == 0) { gsl_vector_free (state->x2); gsl_vector_free (state->dx1); gsl_vector_free (state->x1); GSL_ERROR ("failed to allocate space for p", GSL_ENOMEM); } state->x0 = gsl_vector_calloc (n); if (state->x0 == 0) { gsl_vector_free (state->p); gsl_vector_free (state->x2); gsl_vector_free (state->dx1); gsl_vector_free (state->x1); GSL_ERROR ("failed to allocate space for g0", GSL_ENOMEM); } state->g0 = gsl_vector_calloc (n); if (state->g0 == 0) { gsl_vector_free (state->x0); gsl_vector_free (state->p); gsl_vector_free (state->x2); gsl_vector_free (state->dx1); gsl_vector_free (state->x1); GSL_ERROR ("failed to allocate space for g0", GSL_ENOMEM); } state->dx0 = gsl_vector_calloc (n); if (state->dx0 == 0) { gsl_vector_free (state->g0); gsl_vector_free (state->x0); gsl_vector_free (state->p); gsl_vector_free (state->x2); gsl_vector_free (state->dx1); gsl_vector_free (state->x1); GSL_ERROR ("failed to allocate space for g0", GSL_ENOMEM); } state->dg0 = gsl_vector_calloc (n); if (state->dg0 == 0) { gsl_vector_free (state->dx0); gsl_vector_free (state->g0); gsl_vector_free (state->x0); gsl_vector_free (state->p); gsl_vector_free (state->x2); gsl_vector_free (state->dx1); gsl_vector_free (state->x1); GSL_ERROR ("failed to allocate space for g0", GSL_ENOMEM); } return GSL_SUCCESS; } static int vector_bfgs_set (void *vstate, gsl_multimin_function_fdf * fdf, const gsl_vector * x, double *f, gsl_vector * gradient, double step_size, double tol) { vector_bfgs_state_t *state = (vector_bfgs_state_t *) vstate; state->iter = 0; state->step = step_size; state->max_step = step_size; state->tol = tol; GSL_MULTIMIN_FN_EVAL_F_DF (fdf, x, f, gradient); /* Use the gradient as the initial direction */ gsl_vector_memcpy (state->x0, x); gsl_vector_memcpy (state->p, gradient); gsl_vector_memcpy (state->g0, gradient); { double gnorm = gsl_blas_dnrm2 (gradient); state->pnorm = gnorm; state->g0norm = gnorm; } return GSL_SUCCESS; } static void vector_bfgs_free (void *vstate) { vector_bfgs_state_t *state = (vector_bfgs_state_t *) vstate; gsl_vector_free (state->dg0); gsl_vector_free (state->dx0); gsl_vector_free (state->g0); gsl_vector_free (state->x0); gsl_vector_free (state->p); gsl_vector_free (state->x2); gsl_vector_free (state->dx1); gsl_vector_free (state->x1); } static int vector_bfgs_restart (void *vstate) { vector_bfgs_state_t *state = (vector_bfgs_state_t *) vstate; state->iter = 0; return GSL_SUCCESS; } static int vector_bfgs_iterate (void *vstate, gsl_multimin_function_fdf * fdf, gsl_vector * x, double *f, gsl_vector * gradient, gsl_vector * dx) { vector_bfgs_state_t *state = (vector_bfgs_state_t *) vstate; gsl_vector *x1 = state->x1; gsl_vector *dx1 = state->dx1; gsl_vector *x2 = state->x2; gsl_vector *p = state->p; gsl_vector *g0 = state->g0; gsl_vector *x0 = state->x0; double pnorm = state->pnorm; double g0norm = state->g0norm; double fa = *f, fb, fc; double dir; double stepa = 0.0, stepb, stepc = state->step, tol = state->tol; double g1norm; double pg; if (pnorm == 0.0 || g0norm == 0.0) { gsl_vector_set_zero (dx); return GSL_ENOPROG; } /* Determine which direction is downhill, +p or -p */ gsl_blas_ddot (p, gradient, &pg); dir = (pg >= 0.0) ? +1.0 : -1.0; /* Compute new trial point at x_c= x - step * p, where p is the current direction */ take_step (x, p, stepc, dir / pnorm, x1, dx); /* Evaluate function and gradient at new point xc */ fc = GSL_MULTIMIN_FN_EVAL_F (fdf, x1); if (fc < fa) { /* Success, reduced the function value */ state->step = stepc * 2.0; *f = fc; gsl_vector_memcpy (x, x1); GSL_MULTIMIN_FN_EVAL_DF (fdf, x1, gradient); return GSL_SUCCESS; } #ifdef DEBUG printf ("got stepc = %g fc = %g\n", stepc, fc); #endif /* Do a line minimisation in the region (xa,fa) (xc,fc) to find an intermediate (xb,fb) satisifying fa > fb < fc. Choose an initial xb based on parabolic interpolation */ intermediate_point (fdf, x, p, dir / pnorm, pg, stepa, stepc, fa, fc, x1, dx1, gradient, &stepb, &fb); if (stepb == 0.0) { return GSL_ENOPROG; } minimize (fdf, x, p, dir / pnorm, stepa, stepb, stepc, fa, fb, fc, tol, x1, dx1, x2, dx, gradient, &(state->step), f, &g1norm); gsl_vector_memcpy (x, x2); /* Choose a new direction for the next step */ state->iter = (state->iter + 1) % x->size; if (state->iter == 0) { gsl_vector_memcpy (p, gradient); state->pnorm = g1norm; } else { /* This is the BFGS update: */ /* p' = g1 - A dx - B dg */ /* A = - (1+ dg.dg/dx.dg) B + dg.g/dx.dg */ /* B = dx.g/dx.dg */ gsl_vector *dx0 = state->dx0; gsl_vector *dg0 = state->dg0; double dxg, dgg, dxdg, dgnorm, A, B; /* dx0 = x - x0 */ gsl_vector_memcpy (dx0, x); gsl_blas_daxpy (-1.0, x0, dx0); /* dg0 = g - g0 */ gsl_vector_memcpy (dg0, gradient); gsl_blas_daxpy (-1.0, g0, dg0); gsl_blas_ddot (dx0, gradient, &dxg); gsl_blas_ddot (dg0, gradient, &dgg); gsl_blas_ddot (dx0, dg0, &dxdg); dgnorm = gsl_blas_dnrm2 (dg0); if (dxdg != 0) { B = dxg / dxdg; A = -(1.0 + dgnorm * dgnorm / dxdg) * B + dgg / dxdg; } else { B = 0; A = 0; } gsl_vector_memcpy (p, gradient); gsl_blas_daxpy (-A, dx0, p); gsl_blas_daxpy (-B, dg0, p); state->pnorm = gsl_blas_dnrm2 (p); } gsl_vector_memcpy (g0, gradient); gsl_vector_memcpy (x0, x); state->g0norm = gsl_blas_dnrm2 (g0); #ifdef DEBUG printf ("updated directions\n"); printf ("p: "); gsl_vector_fprintf (stdout, p, "%g"); printf ("g: "); gsl_vector_fprintf (stdout, gradient, "%g"); #endif return GSL_SUCCESS; } static const gsl_multimin_fdfminimizer_type vector_bfgs_type = { "vector_bfgs", /* name */ sizeof (vector_bfgs_state_t), &vector_bfgs_alloc, &vector_bfgs_set, &vector_bfgs_iterate, &vector_bfgs_restart, &vector_bfgs_free }; const gsl_multimin_fdfminimizer_type * gsl_multimin_fdfminimizer_vector_bfgs = &vector_bfgs_type; praat-6.0.04/external/gsl/gsl_multimin__vector_bfgs2.c000066400000000000000000000203041261542461700230010ustar00rootroot00000000000000/* multimin/vector_bfgs2.c * * Copyright (C) 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ /* vector_bfgs2.c -- Fletcher's implementation of the BFGS method, from R.Fletcher, "Practical Method's of Optimization", Second Edition, ISBN 0471915475. Algorithms 2.6.2 and 2.6.4. */ /* Thanks to Alan Irwin irwin@beluga.phys.uvic.ca. for suggesting this algorithm and providing sample fortran benchmarks */ #include "gsl__config.h" #include "gsl_multimin.h" #include "gsl_blas.h" #include "gsl_multimin__linear_minimize.c" #include "gsl_multimin__linear_wrapper.c" typedef struct { int iter; double step; double g0norm; double pnorm; double delta_f; double fp0; /* f'(0) for f(x-alpha*p) */ gsl_vector *x0; gsl_vector *g0; gsl_vector *p; /* work space */ gsl_vector *dx0; gsl_vector *dg0; gsl_vector *x_alpha; gsl_vector *g_alpha; /* wrapper function */ wrapper_t wrap; /* minimization parameters */ double rho; double sigma; double tau1; double tau2; double tau3; int order; } vector_bfgs2_state_t; static int vector_bfgs2_alloc (void *vstate, size_t n) { vector_bfgs2_state_t *state = (vector_bfgs2_state_t *) vstate; state->p = gsl_vector_calloc (n); if (state->p == 0) { GSL_ERROR ("failed to allocate space for p", GSL_ENOMEM); } state->x0 = gsl_vector_calloc (n); if (state->x0 == 0) { gsl_vector_free (state->p); GSL_ERROR ("failed to allocate space for g0", GSL_ENOMEM); } state->g0 = gsl_vector_calloc (n); if (state->g0 == 0) { gsl_vector_free (state->x0); gsl_vector_free (state->p); GSL_ERROR ("failed to allocate space for g0", GSL_ENOMEM); } state->dx0 = gsl_vector_calloc (n); if (state->dx0 == 0) { gsl_vector_free (state->g0); gsl_vector_free (state->x0); gsl_vector_free (state->p); GSL_ERROR ("failed to allocate space for g0", GSL_ENOMEM); } state->dg0 = gsl_vector_calloc (n); if (state->dg0 == 0) { gsl_vector_free (state->dx0); gsl_vector_free (state->g0); gsl_vector_free (state->x0); gsl_vector_free (state->p); GSL_ERROR ("failed to allocate space for g0", GSL_ENOMEM); } state->x_alpha = gsl_vector_calloc (n); if (state->x_alpha == 0) { gsl_vector_free (state->dg0); gsl_vector_free (state->dx0); gsl_vector_free (state->g0); gsl_vector_free (state->x0); gsl_vector_free (state->p); GSL_ERROR ("failed to allocate space for g0", GSL_ENOMEM); } state->g_alpha = gsl_vector_calloc (n); if (state->g_alpha == 0) { gsl_vector_free (state->x_alpha); gsl_vector_free (state->dg0); gsl_vector_free (state->dx0); gsl_vector_free (state->g0); gsl_vector_free (state->x0); gsl_vector_free (state->p); GSL_ERROR ("failed to allocate space for g0", GSL_ENOMEM); } return GSL_SUCCESS; } static int vector_bfgs2_set (void *vstate, gsl_multimin_function_fdf * fdf, const gsl_vector * x, double *f, gsl_vector * gradient, double step_size, double tol) { vector_bfgs2_state_t *state = (vector_bfgs2_state_t *) vstate; state->iter = 0; state->step = step_size; state->delta_f = 0; GSL_MULTIMIN_FN_EVAL_F_DF (fdf, x, f, gradient); /* Use the gradient as the initial direction */ gsl_vector_memcpy (state->x0, x); gsl_vector_memcpy (state->g0, gradient); state->g0norm = gsl_blas_dnrm2 (state->g0); gsl_vector_memcpy (state->p, gradient); gsl_blas_dscal (-1 / state->g0norm, state->p); state->pnorm = gsl_blas_dnrm2 (state->p); /* should be 1 */ state->fp0 = -state->g0norm; /* Prepare the wrapper */ prepare_wrapper (&state->wrap, fdf, state->x0, *f, state->g0, state->p, state->x_alpha, state->g_alpha); /* Prepare 1d minimisation parameters */ state->rho = 0.01; state->sigma = tol; state->tau1 = 9; state->tau2 = 0.05; state->tau3 = 0.5; state->order = 3; /* use cubic interpolation where possible */ return GSL_SUCCESS; } static void vector_bfgs2_free (void *vstate) { vector_bfgs2_state_t *state = (vector_bfgs2_state_t *) vstate; gsl_vector_free (state->x_alpha); gsl_vector_free (state->g_alpha); gsl_vector_free (state->dg0); gsl_vector_free (state->dx0); gsl_vector_free (state->g0); gsl_vector_free (state->x0); gsl_vector_free (state->p); } static int vector_bfgs2_restart (void *vstate) { vector_bfgs2_state_t *state = (vector_bfgs2_state_t *) vstate; state->iter = 0; return GSL_SUCCESS; } static int vector_bfgs2_iterate (void *vstate, gsl_multimin_function_fdf * fdf, gsl_vector * x, double *f, gsl_vector * gradient, gsl_vector * dx) { vector_bfgs2_state_t *state = (vector_bfgs2_state_t *) vstate; double alpha = 0.0, alpha1; gsl_vector *x0 = state->x0; gsl_vector *g0 = state->g0; gsl_vector *p = state->p; double g0norm = state->g0norm; double pnorm = state->pnorm; double delta_f = state->delta_f; double pg, dir; int status; double f0 = *f; if (pnorm == 0.0 || g0norm == 0.0 || state->fp0 == 0) { gsl_vector_set_zero (dx); return GSL_ENOPROG; } if (delta_f < 0) { double del = GSL_MAX_DBL (-delta_f, 10 * GSL_DBL_EPSILON * fabs(f0)); alpha1 = GSL_MIN_DBL (1.0, 2.0 * del / (-state->fp0)); } else { alpha1 = fabs(state->step); } /* line minimisation, with cubic interpolation (order = 3) */ status = minimize (&state->wrap.fdf_linear, state->rho, state->sigma, state->tau1, state->tau2, state->tau3, state->order, alpha1, &alpha); if (status != GSL_SUCCESS) { return status; } update_position (&(state->wrap), alpha, x, f, gradient); state->delta_f = *f - f0; /* Choose a new direction for the next step */ { /* This is the BFGS update: */ /* p' = g1 - A dx - B dg */ /* A = - (1+ dg.dg/dx.dg) B + dg.g/dx.dg */ /* B = dx.g/dx.dg */ gsl_vector *dx0 = state->dx0; gsl_vector *dg0 = state->dg0; double dxg, dgg, dxdg, dgnorm, A, B; /* dx0 = x - x0 */ gsl_vector_memcpy (dx0, x); gsl_blas_daxpy (-1.0, x0, dx0); gsl_vector_memcpy (dx, dx0); /* keep a copy */ /* dg0 = g - g0 */ gsl_vector_memcpy (dg0, gradient); gsl_blas_daxpy (-1.0, g0, dg0); gsl_blas_ddot (dx0, gradient, &dxg); gsl_blas_ddot (dg0, gradient, &dgg); gsl_blas_ddot (dx0, dg0, &dxdg); dgnorm = gsl_blas_dnrm2 (dg0); if (dxdg != 0) { B = dxg / dxdg; A = -(1.0 + dgnorm * dgnorm / dxdg) * B + dgg / dxdg; } else { B = 0; A = 0; } gsl_vector_memcpy (p, gradient); gsl_blas_daxpy (-A, dx0, p); gsl_blas_daxpy (-B, dg0, p); } gsl_vector_memcpy (g0, gradient); gsl_vector_memcpy (x0, x); state->g0norm = gsl_blas_dnrm2 (g0); state->pnorm = gsl_blas_dnrm2 (p); /* update direction and fp0 */ gsl_blas_ddot (p, gradient, &pg); dir = (pg >= 0.0) ? -1.0 : +1.0; gsl_blas_dscal (dir / state->pnorm, p); state->pnorm = gsl_blas_dnrm2 (p); gsl_blas_ddot (p, g0, &state->fp0); change_direction (&state->wrap); return GSL_SUCCESS; } static const gsl_multimin_fdfminimizer_type vector_bfgs2_type = { "vector_bfgs2", /* name */ sizeof (vector_bfgs2_state_t), &vector_bfgs2_alloc, &vector_bfgs2_set, &vector_bfgs2_iterate, &vector_bfgs2_restart, &vector_bfgs2_free }; const gsl_multimin_fdfminimizer_type * gsl_multimin_fdfminimizer_vector_bfgs2 = &vector_bfgs2_type; praat-6.0.04/external/gsl/gsl_multiroots.h000066400000000000000000000137701261542461700205760ustar00rootroot00000000000000/* multiroots/gsl_multiroots.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_MULTIROOTS_H__ #define __GSL_MULTIROOTS_H__ #include #include "gsl_types.h" #include "gsl_math.h" #include "gsl_vector.h" #include "gsl_matrix.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Definition of vector-valued functions with parameters based on gsl_vector */ struct gsl_multiroot_function_struct { int (* f) (const gsl_vector * x, void * params, gsl_vector * f); size_t n; void * params; }; typedef struct gsl_multiroot_function_struct gsl_multiroot_function ; #define GSL_MULTIROOT_FN_EVAL(F,x,y) (*((F)->f))(x,(F)->params,(y)) int gsl_multiroot_fdjacobian (gsl_multiroot_function * F, const gsl_vector * x, const gsl_vector * f, double epsrel, gsl_matrix * jacobian); typedef struct { const char *name; size_t size; int (*alloc) (void *state, size_t n); int (*set) (void *state, gsl_multiroot_function * function, gsl_vector * x, gsl_vector * f, gsl_vector * dx); int (*iterate) (void *state, gsl_multiroot_function * function, gsl_vector * x, gsl_vector * f, gsl_vector * dx); void (*free) (void *state); } gsl_multiroot_fsolver_type; typedef struct { const gsl_multiroot_fsolver_type * type; gsl_multiroot_function * function ; gsl_vector * x ; gsl_vector * f ; gsl_vector * dx ; void *state; } gsl_multiroot_fsolver; gsl_multiroot_fsolver * gsl_multiroot_fsolver_alloc (const gsl_multiroot_fsolver_type * T, size_t n); void gsl_multiroot_fsolver_free (gsl_multiroot_fsolver * s); int gsl_multiroot_fsolver_set (gsl_multiroot_fsolver * s, gsl_multiroot_function * f, const gsl_vector * x); int gsl_multiroot_fsolver_iterate (gsl_multiroot_fsolver * s); const char * gsl_multiroot_fsolver_name (const gsl_multiroot_fsolver * s); gsl_vector * gsl_multiroot_fsolver_root (const gsl_multiroot_fsolver * s); gsl_vector * gsl_multiroot_fsolver_dx (const gsl_multiroot_fsolver * s); gsl_vector * gsl_multiroot_fsolver_f (const gsl_multiroot_fsolver * s); /* Definition of vector-valued functions and gradient with parameters based on gsl_vector */ struct gsl_multiroot_function_fdf_struct { int (* f) (const gsl_vector * x, void * params, gsl_vector * f); int (* df) (const gsl_vector * x, void * params, gsl_matrix * df); int (* fdf) (const gsl_vector * x, void * params, gsl_vector * f, gsl_matrix *df); size_t n; void * params; }; typedef struct gsl_multiroot_function_fdf_struct gsl_multiroot_function_fdf ; #define GSL_MULTIROOT_FN_EVAL_F(F,x,y) ((*((F)->f))(x,(F)->params,(y))) #define GSL_MULTIROOT_FN_EVAL_DF(F,x,dy) ((*((F)->df))(x,(F)->params,(dy))) #define GSL_MULTIROOT_FN_EVAL_F_DF(F,x,y,dy) ((*((F)->fdf))(x,(F)->params,(y),(dy))) typedef struct { const char *name; size_t size; int (*alloc) (void *state, size_t n); int (*set) (void *state, gsl_multiroot_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx); int (*iterate) (void *state, gsl_multiroot_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx); void (*free) (void *state); } gsl_multiroot_fdfsolver_type; typedef struct { const gsl_multiroot_fdfsolver_type * type; gsl_multiroot_function_fdf * fdf ; gsl_vector * x; gsl_vector * f; gsl_matrix * J; gsl_vector * dx; void *state; } gsl_multiroot_fdfsolver; gsl_multiroot_fdfsolver * gsl_multiroot_fdfsolver_alloc (const gsl_multiroot_fdfsolver_type * T, size_t n); int gsl_multiroot_fdfsolver_set (gsl_multiroot_fdfsolver * s, gsl_multiroot_function_fdf * fdf, const gsl_vector * x); int gsl_multiroot_fdfsolver_iterate (gsl_multiroot_fdfsolver * s); void gsl_multiroot_fdfsolver_free (gsl_multiroot_fdfsolver * s); const char * gsl_multiroot_fdfsolver_name (const gsl_multiroot_fdfsolver * s); gsl_vector * gsl_multiroot_fdfsolver_root (const gsl_multiroot_fdfsolver * s); gsl_vector * gsl_multiroot_fdfsolver_dx (const gsl_multiroot_fdfsolver * s); gsl_vector * gsl_multiroot_fdfsolver_f (const gsl_multiroot_fdfsolver * s); int gsl_multiroot_test_delta (const gsl_vector * dx, const gsl_vector * x, double epsabs, double epsrel); int gsl_multiroot_test_residual (const gsl_vector * f, double epsabs); GSL_VAR const gsl_multiroot_fsolver_type * gsl_multiroot_fsolver_dnewton; GSL_VAR const gsl_multiroot_fsolver_type * gsl_multiroot_fsolver_broyden; GSL_VAR const gsl_multiroot_fsolver_type * gsl_multiroot_fsolver_hybrid; GSL_VAR const gsl_multiroot_fsolver_type * gsl_multiroot_fsolver_hybrids; GSL_VAR const gsl_multiroot_fdfsolver_type * gsl_multiroot_fdfsolver_newton; GSL_VAR const gsl_multiroot_fdfsolver_type * gsl_multiroot_fdfsolver_gnewton; GSL_VAR const gsl_multiroot_fdfsolver_type * gsl_multiroot_fdfsolver_hybridj; GSL_VAR const gsl_multiroot_fdfsolver_type * gsl_multiroot_fdfsolver_hybridsj; __END_DECLS #endif /* __GSL_MULTIROOTS_H__ */ praat-6.0.04/external/gsl/gsl_multiroots__broyden.c000066400000000000000000000233221261542461700224440ustar00rootroot00000000000000/* multiroots/broyden.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_multiroots.h" #include "gsl_linalg.h" #include "gsl_multiroots__enorm.c" /* Broyden's method. It is not an efficient or modern algorithm but gives an example of a rank-1 update. C.G. Broyden, "A Class of Methods for Solving Nonlinear Simultaneous Equations", Mathematics of Computation, vol 19 (1965), p 577-593 */ typedef struct { gsl_matrix *H; gsl_matrix *lu; gsl_permutation *permutation; gsl_vector *v; gsl_vector *w; gsl_vector *y; gsl_vector *p; gsl_vector *fnew; gsl_vector *x_trial; double phi; } broyden_state_t; static int broyden_alloc (void *vstate, size_t n); static int broyden_set (void *vstate, gsl_multiroot_function * function, gsl_vector * x, gsl_vector * f, gsl_vector * dx); static int broyden_iterate (void *vstate, gsl_multiroot_function * function, gsl_vector * x, gsl_vector * f, gsl_vector * dx); static void broyden_free (void *vstate); static int broyden_alloc (void *vstate, size_t n) { broyden_state_t *state = (broyden_state_t *) vstate; gsl_vector *v, *w, *y, *fnew, *x_trial, *p; gsl_permutation *perm; gsl_matrix *m, *H; m = gsl_matrix_calloc (n, n); if (m == 0) { GSL_ERROR ("failed to allocate space for lu", GSL_ENOMEM); } state->lu = m; perm = gsl_permutation_calloc (n); if (perm == 0) { gsl_matrix_free (m); GSL_ERROR ("failed to allocate space for permutation", GSL_ENOMEM); } state->permutation = perm; H = gsl_matrix_calloc (n, n); if (H == 0) { gsl_permutation_free (perm); gsl_matrix_free (m); GSL_ERROR ("failed to allocate space for d", GSL_ENOMEM); } state->H = H; v = gsl_vector_calloc (n); if (v == 0) { gsl_matrix_free (H); gsl_permutation_free (perm); gsl_matrix_free (m); GSL_ERROR ("failed to allocate space for v", GSL_ENOMEM); } state->v = v; w = gsl_vector_calloc (n); if (w == 0) { gsl_vector_free (v); gsl_matrix_free (H); gsl_permutation_free (perm); gsl_matrix_free (m); GSL_ERROR ("failed to allocate space for w", GSL_ENOMEM); } state->w = w; y = gsl_vector_calloc (n); if (y == 0) { gsl_vector_free (w); gsl_vector_free (v); gsl_matrix_free (H); gsl_permutation_free (perm); gsl_matrix_free (m); GSL_ERROR ("failed to allocate space for y", GSL_ENOMEM); } state->y = y; fnew = gsl_vector_calloc (n); if (fnew == 0) { gsl_vector_free (y); gsl_vector_free (w); gsl_vector_free (v); gsl_matrix_free (H); gsl_permutation_free (perm); gsl_matrix_free (m); GSL_ERROR ("failed to allocate space for fnew", GSL_ENOMEM); } state->fnew = fnew; x_trial = gsl_vector_calloc (n); if (x_trial == 0) { gsl_vector_free (fnew); gsl_vector_free (y); gsl_vector_free (w); gsl_vector_free (v); gsl_matrix_free (H); gsl_permutation_free (perm); gsl_matrix_free (m); GSL_ERROR ("failed to allocate space for x_trial", GSL_ENOMEM); } state->x_trial = x_trial; p = gsl_vector_calloc (n); if (p == 0) { gsl_vector_free (x_trial); gsl_vector_free (fnew); gsl_vector_free (y); gsl_vector_free (w); gsl_vector_free (v); gsl_matrix_free (H); gsl_permutation_free (perm); gsl_matrix_free (m); GSL_ERROR ("failed to allocate space for p", GSL_ENOMEM); } state->p = p; return GSL_SUCCESS; } static int broyden_set (void *vstate, gsl_multiroot_function * function, gsl_vector * x, gsl_vector * f, gsl_vector * dx) { broyden_state_t *state = (broyden_state_t *) vstate; size_t i, j, n = function->n; int signum = 0; GSL_MULTIROOT_FN_EVAL (function, x, f); gsl_multiroot_fdjacobian (function, x, f, GSL_SQRT_DBL_EPSILON, state->lu); gsl_linalg_LU_decomp (state->lu, state->permutation, &signum); gsl_linalg_LU_invert (state->lu, state->permutation, state->H); for (i = 0; i < n; i++) for (j = 0; j < n; j++) gsl_matrix_set(state->H,i,j,-gsl_matrix_get(state->H,i,j)); for (i = 0; i < n; i++) { gsl_vector_set (dx, i, 0.0); } state->phi = enorm (f); return GSL_SUCCESS; } static int broyden_iterate (void *vstate, gsl_multiroot_function * function, gsl_vector * x, gsl_vector * f, gsl_vector * dx) { broyden_state_t *state = (broyden_state_t *) vstate; double phi0, phi1, t, lambda; gsl_matrix *H = state->H; gsl_vector *p = state->p; gsl_vector *y = state->y; gsl_vector *v = state->v; gsl_vector *w = state->w; gsl_vector *fnew = state->fnew; gsl_vector *x_trial = state->x_trial; gsl_matrix *lu = state->lu; gsl_permutation *perm = state->permutation; size_t i, j, iter; size_t n = function->n; /* p = H f */ for (i = 0; i < n; i++) { double sum = 0; for (j = 0; j < n; j++) { sum += gsl_matrix_get (H, i, j) * gsl_vector_get (f, j); } gsl_vector_set (p, i, sum); } t = 1; iter = 0; phi0 = state->phi; new_step: for (i = 0; i < n; i++) { double pi = gsl_vector_get (p, i); double xi = gsl_vector_get (x, i); gsl_vector_set (x_trial, i, xi + t * pi); } { int status = GSL_MULTIROOT_FN_EVAL (function, x_trial, fnew); if (status != GSL_SUCCESS) { return GSL_EBADFUNC; } } phi1 = enorm (fnew); iter++ ; if (phi1 > phi0 && iter < 10 && t > 0.1) { /* full step goes uphill, take a reduced step instead */ double theta = phi1 / phi0; t *= (sqrt (1.0 + 6.0 * theta) - 1.0) / (3.0 * theta); goto new_step; } if (phi1 > phi0) { /* need to recompute Jacobian */ int signum = 0; gsl_multiroot_fdjacobian (function, x, f, GSL_SQRT_DBL_EPSILON, lu); for (i = 0; i < n; i++) for (j = 0; j < n; j++) gsl_matrix_set(lu,i,j,-gsl_matrix_get(lu,i,j)); gsl_linalg_LU_decomp (lu, perm, &signum); gsl_linalg_LU_invert (lu, perm, H); gsl_linalg_LU_solve (lu, perm, f, p); t = 1; for (i = 0; i < n; i++) { double pi = gsl_vector_get (p, i); double xi = gsl_vector_get (x, i); gsl_vector_set (x_trial, i, xi + t * pi); } { int status = GSL_MULTIROOT_FN_EVAL (function, x_trial, fnew); if (status != GSL_SUCCESS) { return GSL_EBADFUNC; } } phi1 = enorm (fnew); } /* y = f' - f */ for (i = 0; i < n; i++) { double yi = gsl_vector_get (fnew, i) - gsl_vector_get (f, i); gsl_vector_set (y, i, yi); } /* v = H y */ for (i = 0; i < n; i++) { double sum = 0; for (j = 0; j < n; j++) { sum += gsl_matrix_get (H, i, j) * gsl_vector_get (y, j); } gsl_vector_set (v, i, sum); } /* lambda = p . v */ lambda = 0; for (i = 0; i < n; i++) { lambda += gsl_vector_get (p, i) * gsl_vector_get (v, i); } if (lambda == 0) { GSL_ERROR ("approximation to Jacobian has collapsed", GSL_EZERODIV) ; } /* v' = v + t * p */ for (i = 0; i < n; i++) { double vi = gsl_vector_get (v, i) + t * gsl_vector_get (p, i); gsl_vector_set (v, i, vi); } /* w^T = p^T H */ for (i = 0; i < n; i++) { double sum = 0; for (j = 0; j < n; j++) { sum += gsl_matrix_get (H, j, i) * gsl_vector_get (p, j); } gsl_vector_set (w, i, sum); } /* Hij -> Hij - (vi wj / lambda) */ for (i = 0; i < n; i++) { double vi = gsl_vector_get (v, i); for (j = 0; j < n; j++) { double wj = gsl_vector_get (w, j); double Hij = gsl_matrix_get (H, i, j) - vi * wj / lambda; gsl_matrix_set (H, i, j, Hij); } } /* copy fnew into f */ gsl_vector_memcpy (f, fnew); /* copy x_trial into x */ gsl_vector_memcpy (x, x_trial); for (i = 0; i < n; i++) { double pi = gsl_vector_get (p, i); gsl_vector_set (dx, i, t * pi); } state->phi = phi1; return GSL_SUCCESS; } static void broyden_free (void *vstate) { broyden_state_t *state = (broyden_state_t *) vstate; gsl_matrix_free (state->H); gsl_matrix_free (state->lu); gsl_permutation_free (state->permutation); gsl_vector_free (state->v); gsl_vector_free (state->w); gsl_vector_free (state->y); gsl_vector_free (state->p); gsl_vector_free (state->fnew); gsl_vector_free (state->x_trial); } static const gsl_multiroot_fsolver_type broyden_type = {"broyden", /* name */ sizeof (broyden_state_t), &broyden_alloc, &broyden_set, &broyden_iterate, &broyden_free}; const gsl_multiroot_fsolver_type *gsl_multiroot_fsolver_broyden = &broyden_type; praat-6.0.04/external/gsl/gsl_multiroots__convergence.c000066400000000000000000000037561261542461700233110ustar00rootroot00000000000000/* multiroots/convergence.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_multiroots.h" int gsl_multiroot_test_delta (const gsl_vector * dx, const gsl_vector * x, double epsabs, double epsrel) { size_t i; int ok = 1; const size_t n = x->size ; if (epsrel < 0.0) { GSL_ERROR ("relative tolerance is negative", GSL_EBADTOL); } for (i = 0 ; i < n ; i++) { double xi = gsl_vector_get(x,i); double dxi = gsl_vector_get(dx,i); double tolerance = epsabs + epsrel * fabs(xi) ; if (fabs(dxi) < tolerance) { ok = 1; } else { ok = 0; break; } } if (ok) return GSL_SUCCESS ; return GSL_CONTINUE; } int gsl_multiroot_test_residual (const gsl_vector * f, double epsabs) { size_t i; double residual = 0; const size_t n = f->size; if (epsabs < 0.0) { GSL_ERROR ("absolute tolerance is negative", GSL_EBADTOL); } for (i = 0 ; i < n ; i++) { double fi = gsl_vector_get(f, i); residual += fabs(fi); } if (residual < epsabs) { return GSL_SUCCESS; } return GSL_CONTINUE ; } praat-6.0.04/external/gsl/gsl_multiroots__dnewton.c000066400000000000000000000104631261542461700224620ustar00rootroot00000000000000/* multiroots/dnewton.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_multiroots.h" #include "gsl_linalg.h" /* Newton method using a finite difference approximation to the jacobian. The derivatives are estimated using a step size of h_i = sqrt(DBL_EPSILON) * x_i */ typedef struct { gsl_matrix * J; gsl_matrix * lu; gsl_permutation * permutation; } dnewton_state_t; static int dnewton_alloc (void * vstate, size_t n); static int dnewton_set (void * vstate, gsl_multiroot_function * function, gsl_vector * x, gsl_vector * f, gsl_vector * dx); static int dnewton_iterate (void * vstate, gsl_multiroot_function * function, gsl_vector * x, gsl_vector * f, gsl_vector * dx); static void dnewton_free (void * vstate); static int dnewton_alloc (void * vstate, size_t n) { dnewton_state_t * state = (dnewton_state_t *) vstate; gsl_permutation * p; gsl_matrix * m, * J; m = gsl_matrix_calloc (n,n); if (m == 0) { GSL_ERROR ("failed to allocate space for lu", GSL_ENOMEM); } state->lu = m ; p = gsl_permutation_calloc (n); if (p == 0) { gsl_matrix_free(m); GSL_ERROR ("failed to allocate space for permutation", GSL_ENOMEM); } state->permutation = p ; J = gsl_matrix_calloc (n,n); if (J == 0) { gsl_permutation_free(p); gsl_matrix_free(m); GSL_ERROR ("failed to allocate space for d", GSL_ENOMEM); } state->J = J; return GSL_SUCCESS; } static int dnewton_set (void * vstate, gsl_multiroot_function * function, gsl_vector * x, gsl_vector * f, gsl_vector * dx) { dnewton_state_t * state = (dnewton_state_t *) vstate; size_t i, n = function->n ; int status; status = GSL_MULTIROOT_FN_EVAL (function, x, f); if (status) return status; status = gsl_multiroot_fdjacobian (function, x, f, GSL_SQRT_DBL_EPSILON, state->J); if (status) return status; for (i = 0; i < n; i++) { gsl_vector_set (dx, i, 0.0); } return GSL_SUCCESS; } static int dnewton_iterate (void * vstate, gsl_multiroot_function * function, gsl_vector * x, gsl_vector * f, gsl_vector * dx) { dnewton_state_t * state = (dnewton_state_t *) vstate; int signum ; size_t i; size_t n = function->n ; gsl_matrix_memcpy (state->lu, state->J); { int status = gsl_linalg_LU_decomp (state->lu, state->permutation, &signum); if (status) return status; } { int status = gsl_linalg_LU_solve (state->lu, state->permutation, f, dx); if (status) return status; } for (i = 0; i < n; i++) { double e = gsl_vector_get (dx, i); double y = gsl_vector_get (x, i); gsl_vector_set (dx, i, -e); gsl_vector_set (x, i, y - e); } { int status = GSL_MULTIROOT_FN_EVAL (function, x, f); if (status != GSL_SUCCESS) { return GSL_EBADFUNC; } } gsl_multiroot_fdjacobian (function, x, f, GSL_SQRT_DBL_EPSILON, state->J); return GSL_SUCCESS; } static void dnewton_free (void * vstate) { dnewton_state_t * state = (dnewton_state_t *) vstate; gsl_matrix_free(state->J); gsl_matrix_free(state->lu); gsl_permutation_free(state->permutation); } static const gsl_multiroot_fsolver_type dnewton_type = {"dnewton", /* name */ sizeof (dnewton_state_t), &dnewton_alloc, &dnewton_set, &dnewton_iterate, &dnewton_free}; const gsl_multiroot_fsolver_type * gsl_multiroot_fsolver_dnewton = &dnewton_type; praat-6.0.04/external/gsl/gsl_multiroots__dogleg.c000066400000000000000000000225721261542461700222510ustar00rootroot00000000000000/* multiroots/dogleg.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl_multiroots__enorm.c" static void compute_diag (const gsl_matrix * J, gsl_vector * diag); static void update_diag (const gsl_matrix * J, gsl_vector * diag); static double compute_delta (gsl_vector * diag, gsl_vector * x); static void compute_df (const gsl_vector * f_trial, const gsl_vector * f, gsl_vector * df); static void compute_wv (const gsl_vector * qtdf, const gsl_vector *rdx, const gsl_vector *dx, const gsl_vector *diag, double pnorm, gsl_vector * w, gsl_vector * v); static double scaled_enorm (const gsl_vector * d, const gsl_vector * f); static double scaled_enorm (const gsl_vector * d, const gsl_vector * f) { double e2 = 0 ; size_t i, n = f->size ; for (i = 0; i < n ; i++) { double fi= gsl_vector_get(f, i); double di= gsl_vector_get(d, i); double u = di * fi; e2 += u * u ; } return sqrt(e2); } static double enorm_sum (const gsl_vector * a, const gsl_vector * b); static double enorm_sum (const gsl_vector * a, const gsl_vector * b) { double e2 = 0 ; size_t i, n = a->size ; for (i = 0; i < n ; i++) { double ai= gsl_vector_get(a, i); double bi= gsl_vector_get(b, i); double u = ai + bi; e2 += u * u ; } return sqrt(e2); } static void compute_wv (const gsl_vector * qtdf, const gsl_vector *rdx, const gsl_vector *dx, const gsl_vector *diag, double pnorm, gsl_vector * w, gsl_vector * v) { size_t i, n = qtdf->size; for (i = 0; i < n; i++) { double qtdfi = gsl_vector_get (qtdf, i); double rdxi = gsl_vector_get (rdx, i); double dxi = gsl_vector_get (dx, i); double diagi = gsl_vector_get (diag, i); gsl_vector_set (w, i, (qtdfi - rdxi) / pnorm); gsl_vector_set (v, i, diagi * diagi * dxi / pnorm); } } static void compute_df (const gsl_vector * f_trial, const gsl_vector * f, gsl_vector * df) { size_t i, n = f->size; for (i = 0; i < n; i++) { double dfi = gsl_vector_get (f_trial, i) - gsl_vector_get (f, i); gsl_vector_set (df, i, dfi); } } static void compute_diag (const gsl_matrix * J, gsl_vector * diag) { size_t i, j, n = diag->size; for (j = 0; j < n; j++) { double sum = 0; for (i = 0; i < n; i++) { double Jij = gsl_matrix_get (J, i, j); sum += Jij * Jij; } if (sum == 0) sum = 1.0; gsl_vector_set (diag, j, sqrt (sum)); } } static void update_diag (const gsl_matrix * J, gsl_vector * diag) { size_t i, j, n = diag->size; for (j = 0; j < n; j++) { double cnorm, diagj, sum = 0; for (i = 0; i < n; i++) { double Jij = gsl_matrix_get (J, i, j); sum += Jij * Jij; } if (sum == 0) sum = 1.0; cnorm = sqrt (sum); diagj = gsl_vector_get (diag, j); if (cnorm > diagj) gsl_vector_set (diag, j, cnorm); } } static double compute_delta (gsl_vector * diag, gsl_vector * x) { double Dx = scaled_enorm (diag, x); double factor = 100; return (Dx > 0) ? factor * Dx : factor; } static double compute_actual_reduction (double fnorm, double fnorm1) { double actred; if (fnorm1 < fnorm) { double u = fnorm1 / fnorm; actred = 1 - u * u; } else { actred = -1; } return actred; } static double compute_predicted_reduction (double fnorm, double fnorm1) { double prered; if (fnorm1 < fnorm) { double u = fnorm1 / fnorm; prered = 1 - u * u; } else { prered = 0; } return prered; } static void compute_qtf (const gsl_matrix * q, const gsl_vector * f, gsl_vector * qtf) { size_t i, j, N = f->size ; for (j = 0; j < N; j++) { double sum = 0; for (i = 0; i < N; i++) sum += gsl_matrix_get (q, i, j) * gsl_vector_get (f, i); gsl_vector_set (qtf, j, sum); } } static void compute_rdx (const gsl_matrix * r, const gsl_vector * dx, gsl_vector * rdx) { size_t i, j, N = dx->size ; for (i = 0; i < N; i++) { double sum = 0; for (j = i; j < N; j++) { sum += gsl_matrix_get (r, i, j) * gsl_vector_get (dx, j); } gsl_vector_set (rdx, i, sum); } } static void compute_trial_step (gsl_vector *x, gsl_vector * dx, gsl_vector * x_trial) { size_t i, N = x->size; for (i = 0; i < N; i++) { double pi = gsl_vector_get (dx, i); double xi = gsl_vector_get (x, i); gsl_vector_set (x_trial, i, xi + pi); } } static int newton_direction (const gsl_matrix * r, const gsl_vector * qtf, gsl_vector * p) { const size_t N = r->size2; size_t i; int status; status = gsl_linalg_R_solve (r, qtf, p); #ifdef DEBUG printf("rsolve status = %d\n", status); #endif for (i = 0; i < N; i++) { double pi = gsl_vector_get (p, i); gsl_vector_set (p, i, -pi); } return status; } static void gradient_direction (const gsl_matrix * r, const gsl_vector * qtf, const gsl_vector * diag, gsl_vector * g) { const size_t M = r->size1; const size_t N = r->size2; size_t i, j; for (j = 0; j < M; j++) { double sum = 0; double dj; for (i = 0; i < N; i++) { sum += gsl_matrix_get (r, i, j) * gsl_vector_get (qtf, i); } dj = gsl_vector_get (diag, j); gsl_vector_set (g, j, -sum / dj); } } static void minimum_step (double gnorm, const gsl_vector * diag, gsl_vector * g) { const size_t N = g->size; size_t i; for (i = 0; i < N; i++) { double gi = gsl_vector_get (g, i); double di = gsl_vector_get (diag, i); gsl_vector_set (g, i, (gi / gnorm) / di); } } static void compute_Rg (const gsl_matrix * r, const gsl_vector * gradient, gsl_vector * Rg) { const size_t N = r->size2; size_t i, j; for (i = 0; i < N; i++) { double sum = 0; for (j = i; j < N; j++) { double gj = gsl_vector_get (gradient, j); double rij = gsl_matrix_get (r, i, j); sum += rij * gj; } gsl_vector_set (Rg, i, sum); } } static void scaled_addition (double alpha, gsl_vector * newton, double beta, gsl_vector * gradient, gsl_vector * p) { const size_t N = p->size; size_t i; for (i = 0; i < N; i++) { double ni = gsl_vector_get (newton, i); double gi = gsl_vector_get (gradient, i); gsl_vector_set (p, i, alpha * ni + beta * gi); } } static int dogleg (const gsl_matrix * r, const gsl_vector * qtf, const gsl_vector * diag, double delta, gsl_vector * newton, gsl_vector * gradient, gsl_vector * p) { double qnorm, gnorm, sgnorm, bnorm, temp; newton_direction (r, qtf, newton); #ifdef DEBUG printf("newton = "); gsl_vector_fprintf(stdout, newton, "%g"); printf("\n"); #endif qnorm = scaled_enorm (diag, newton); if (qnorm <= delta) { gsl_vector_memcpy (p, newton); #ifdef DEBUG printf("took newton (qnorm = %g <= delta = %g)\n", qnorm, delta); #endif return GSL_SUCCESS; } gradient_direction (r, qtf, diag, gradient); #ifdef DEBUG printf("grad = "); gsl_vector_fprintf(stdout, gradient, "%g"); printf("\n"); #endif gnorm = enorm (gradient); if (gnorm == 0) { double alpha = delta / qnorm; double beta = 0; scaled_addition (alpha, newton, beta, gradient, p); #ifdef DEBUG printf("took scaled newton because gnorm = 0\n"); #endif return GSL_SUCCESS; } minimum_step (gnorm, diag, gradient); compute_Rg (r, gradient, p); /* Use p as temporary space to compute Rg */ #ifdef DEBUG printf("mingrad = "); gsl_vector_fprintf(stdout, gradient, "%g"); printf("\n"); printf("Rg = "); gsl_vector_fprintf(stdout, p, "%g"); printf("\n"); #endif temp = enorm (p); sgnorm = (gnorm / temp) / temp; if (sgnorm > delta) { double alpha = 0; double beta = delta; scaled_addition (alpha, newton, beta, gradient, p); #ifdef DEBUG printf("took gradient\n"); #endif return GSL_SUCCESS; } bnorm = enorm (qtf); { double bg = bnorm / gnorm; double bq = bnorm / qnorm; double dq = delta / qnorm; double dq2 = dq * dq; double sd = sgnorm / delta; double sd2 = sd * sd; double t1 = bg * bq * sd; double u = t1 - dq; double t2 = t1 - dq * sd2 + sqrt (u * u + (1-dq2) * (1 - sd2)); double alpha = dq * (1 - sd2) / t2; double beta = (1 - alpha) * sgnorm; #ifdef DEBUG printf("bnorm = %g\n", bnorm); printf("gnorm = %g\n", gnorm); printf("qnorm = %g\n", qnorm); printf("delta = %g\n", delta); printf("alpha = %g beta = %g\n", alpha, beta); printf("took scaled combination of newton and gradient\n"); #endif scaled_addition (alpha, newton, beta, gradient, p); } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_multiroots__enorm.c000066400000000000000000000020531261542461700221200ustar00rootroot00000000000000/* multiroots/enorm.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static double enorm (const gsl_vector * f); static double enorm (const gsl_vector * f) { double e2 = 0 ; size_t i, n = f->size ; for (i = 0; i < n ; i++) { double fi= gsl_vector_get(f, i); e2 += fi * fi ; } return sqrt(e2); } praat-6.0.04/external/gsl/gsl_multiroots__fdfsolver.c000066400000000000000000000102411261542461700227700ustar00rootroot00000000000000/* multiroots/fdfsolver.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_errno.h" #include "gsl_multiroots.h" gsl_multiroot_fdfsolver * gsl_multiroot_fdfsolver_alloc (const gsl_multiroot_fdfsolver_type * T, size_t n) { int status; gsl_multiroot_fdfsolver * s; s = (gsl_multiroot_fdfsolver *) malloc (sizeof (gsl_multiroot_fdfsolver)); if (s == 0) { GSL_ERROR_VAL ("failed to allocate space for multiroot solver struct", GSL_ENOMEM, 0); } s->x = gsl_vector_calloc (n); if (s->x == 0) { free (s); GSL_ERROR_VAL ("failed to allocate space for x", GSL_ENOMEM, 0); } s->f = gsl_vector_calloc (n); if (s->f == 0) { gsl_vector_free (s->x); free (s); GSL_ERROR_VAL ("failed to allocate space for f", GSL_ENOMEM, 0); } s->J = gsl_matrix_calloc (n,n); if (s->J == 0) { gsl_vector_free (s->x); gsl_vector_free (s->f); free (s); GSL_ERROR_VAL ("failed to allocate space for g", GSL_ENOMEM, 0); } s->dx = gsl_vector_calloc (n); if (s->dx == 0) { gsl_matrix_free (s->J); gsl_vector_free (s->x); gsl_vector_free (s->f); free (s); GSL_ERROR_VAL ("failed to allocate space for dx", GSL_ENOMEM, 0); } s->state = malloc (T->size); if (s->state == 0) { gsl_vector_free (s->dx); gsl_vector_free (s->x); gsl_vector_free (s->f); gsl_matrix_free (s->J); free (s); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for multiroot solver state", GSL_ENOMEM, 0); } s->type = T ; status = (s->type->alloc)(s->state, n); if (status != GSL_SUCCESS) { free (s->state); gsl_vector_free (s->dx); gsl_vector_free (s->x); gsl_vector_free (s->f); gsl_matrix_free (s->J); free (s); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to set solver", status, 0); } s->fdf = NULL; return s; } int gsl_multiroot_fdfsolver_set (gsl_multiroot_fdfsolver * s, gsl_multiroot_function_fdf * f, const gsl_vector * x) { if (s->x->size != f->n) { GSL_ERROR ("function incompatible with solver size", GSL_EBADLEN); } if (x->size != f->n) { GSL_ERROR ("vector length not compatible with function", GSL_EBADLEN); } s->fdf = f; gsl_vector_memcpy(s->x,x); return (s->type->set) (s->state, s->fdf, s->x, s->f, s->J, s->dx); } int gsl_multiroot_fdfsolver_iterate (gsl_multiroot_fdfsolver * s) { return (s->type->iterate) (s->state, s->fdf, s->x, s->f, s->J, s->dx); } void gsl_multiroot_fdfsolver_free (gsl_multiroot_fdfsolver * s) { (s->type->free) (s->state); free (s->state); gsl_vector_free (s->dx); gsl_vector_free (s->x); gsl_vector_free (s->f); gsl_matrix_free (s->J); free (s); } const char * gsl_multiroot_fdfsolver_name (const gsl_multiroot_fdfsolver * s) { return s->type->name; } gsl_vector * gsl_multiroot_fdfsolver_root (const gsl_multiroot_fdfsolver * s) { return s->x; } gsl_vector * gsl_multiroot_fdfsolver_dx (const gsl_multiroot_fdfsolver * s) { return s->dx; } gsl_vector * gsl_multiroot_fdfsolver_f (const gsl_multiroot_fdfsolver * s) { return s->f; } praat-6.0.04/external/gsl/gsl_multiroots__fdjac.c000066400000000000000000000056131261542461700220540ustar00rootroot00000000000000/* multiroots/fdjac.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_multiroots.h" int gsl_multiroot_fdjacobian (gsl_multiroot_function * F, const gsl_vector * x, const gsl_vector * f, double epsrel, gsl_matrix * jacobian) { const size_t n = x->size; const size_t m = f->size; const size_t n1 = jacobian->size1; const size_t n2 = jacobian->size2; int status = 0; if (m != n1 || n != n2) { GSL_ERROR ("function and jacobian are not conformant", GSL_EBADLEN); } { size_t i,j; gsl_vector *x1, *f1; x1 = gsl_vector_alloc (n); if (x1 == 0) { GSL_ERROR ("failed to allocate space for x1 workspace", GSL_ENOMEM); } f1 = gsl_vector_alloc (m); if (f1 == 0) { gsl_vector_free (x1); GSL_ERROR ("failed to allocate space for f1 workspace", GSL_ENOMEM); } gsl_vector_memcpy (x1, x); /* copy x into x1 */ for (j = 0; j < n; j++) { double xj = gsl_vector_get (x, j); double dx = epsrel * fabs (xj); if (dx == 0) { dx = epsrel; } gsl_vector_set (x1, j, xj + dx); { int f_stat = GSL_MULTIROOT_FN_EVAL (F, x1, f1); if (f_stat != GSL_SUCCESS) { status = GSL_EBADFUNC; break; /* n.b. avoid memory leak for x1,f1 */ } } gsl_vector_set (x1, j, xj); for (i = 0; i < m; i++) { double g1 = gsl_vector_get (f1, i); double g0 = gsl_vector_get (f, i); gsl_matrix_set (jacobian, i, j, (g1 - g0) / dx); } { gsl_vector_view col = gsl_matrix_column (jacobian, j); int null_col = gsl_vector_isnull (&col.vector); /* if column is null, return an error - this may be due to dx being too small. Try increasing epsrel */ if (null_col) { status = GSL_ESING; } } } gsl_vector_free (x1); gsl_vector_free (f1); } if (status) return status; else return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_multiroots__fsolver.c000066400000000000000000000075101261542461700224630ustar00rootroot00000000000000/* multiroots/fsolver.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_errno.h" #include "gsl_multiroots.h" gsl_multiroot_fsolver * gsl_multiroot_fsolver_alloc (const gsl_multiroot_fsolver_type * T, size_t n) { int status; gsl_multiroot_fsolver * s; s = (gsl_multiroot_fsolver *) malloc (sizeof (gsl_multiroot_fsolver)); if (s == 0) { GSL_ERROR_VAL ("failed to allocate space for multiroot solver struct", GSL_ENOMEM, 0); } s->x = gsl_vector_calloc (n); if (s->x == 0) { free (s); GSL_ERROR_VAL ("failed to allocate space for x", GSL_ENOMEM, 0); } s->f = gsl_vector_calloc (n); if (s->f == 0) { gsl_vector_free (s->x); free (s); GSL_ERROR_VAL ("failed to allocate space for f", GSL_ENOMEM, 0); } s->dx = gsl_vector_calloc (n); if (s->dx == 0) { gsl_vector_free (s->x); gsl_vector_free (s->f); free (s); GSL_ERROR_VAL ("failed to allocate space for dx", GSL_ENOMEM, 0); } s->state = malloc (T->size); if (s->state == 0) { gsl_vector_free (s->dx); gsl_vector_free (s->x); gsl_vector_free (s->f); free (s); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for multiroot solver state", GSL_ENOMEM, 0); } s->type = T ; status = (s->type->alloc)(s->state, n); if (status != GSL_SUCCESS) { (s->type->free)(s->state); free (s->state); gsl_vector_free (s->dx); gsl_vector_free (s->x); gsl_vector_free (s->f); free (s); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to set solver", status, 0); } s->function = NULL; return s; } int gsl_multiroot_fsolver_set (gsl_multiroot_fsolver * s, gsl_multiroot_function * f, const gsl_vector * x) { if (s->x->size != f->n) { GSL_ERROR ("function incompatible with solver size", GSL_EBADLEN); } if (x->size != f->n) { GSL_ERROR ("vector length not compatible with function", GSL_EBADLEN); } s->function = f; gsl_vector_memcpy(s->x,x); return (s->type->set) (s->state, s->function, s->x, s->f, s->dx); } int gsl_multiroot_fsolver_iterate (gsl_multiroot_fsolver * s) { return (s->type->iterate) (s->state, s->function, s->x, s->f, s->dx); } void gsl_multiroot_fsolver_free (gsl_multiroot_fsolver * s) { (s->type->free) (s->state); free (s->state); gsl_vector_free (s->dx); gsl_vector_free (s->x); gsl_vector_free (s->f); free (s); } const char * gsl_multiroot_fsolver_name (const gsl_multiroot_fsolver * s) { return s->type->name; } gsl_vector * gsl_multiroot_fsolver_root (const gsl_multiroot_fsolver * s) { return s->x; } gsl_vector * gsl_multiroot_fsolver_dx (const gsl_multiroot_fsolver * s) { return s->dx; } gsl_vector * gsl_multiroot_fsolver_f (const gsl_multiroot_fsolver * s) { return s->f; } praat-6.0.04/external/gsl/gsl_multiroots__gnewton.c000066400000000000000000000117721261542461700224710ustar00rootroot00000000000000/* multiroots/gnewton.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_multiroots.h" #include "gsl_linalg.h" #include "gsl_multiroots__enorm.c" /* Simple globally convergent Newton method (rejects uphill steps) */ typedef struct { double phi; gsl_vector * x_trial; gsl_vector * d; gsl_matrix * lu; gsl_permutation * permutation; } gnewton_state_t; static int gnewton_alloc (void * vstate, size_t n); static int gnewton_set (void * vstate, gsl_multiroot_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx); static int gnewton_iterate (void * vstate, gsl_multiroot_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx); static void gnewton_free (void * vstate); static int gnewton_alloc (void * vstate, size_t n) { gnewton_state_t * state = (gnewton_state_t *) vstate; gsl_vector * d, * x_trial ; gsl_permutation * p; gsl_matrix * m; m = gsl_matrix_calloc (n,n); if (m == 0) { GSL_ERROR ("failed to allocate space for lu", GSL_ENOMEM); } state->lu = m ; p = gsl_permutation_calloc (n); if (p == 0) { gsl_matrix_free(m); GSL_ERROR ("failed to allocate space for permutation", GSL_ENOMEM); } state->permutation = p ; d = gsl_vector_calloc (n); if (d == 0) { gsl_permutation_free(p); gsl_matrix_free(m); GSL_ERROR ("failed to allocate space for d", GSL_ENOMEM); } state->d = d; x_trial = gsl_vector_calloc (n); if (x_trial == 0) { gsl_vector_free(d); gsl_permutation_free(p); gsl_matrix_free(m); GSL_ERROR ("failed to allocate space for x_trial", GSL_ENOMEM); } state->x_trial = x_trial; return GSL_SUCCESS; } static int gnewton_set (void * vstate, gsl_multiroot_function_fdf * FDF, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx) { gnewton_state_t * state = (gnewton_state_t *) vstate; size_t i, n = FDF->n ; GSL_MULTIROOT_FN_EVAL_F_DF (FDF, x, f, J); for (i = 0; i < n; i++) { gsl_vector_set (dx, i, 0.0); } state->phi = enorm(f); return GSL_SUCCESS; } static int gnewton_iterate (void * vstate, gsl_multiroot_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx) { gnewton_state_t * state = (gnewton_state_t *) vstate; int signum ; double t, phi0, phi1; size_t i; size_t n = fdf->n ; gsl_matrix_memcpy (state->lu, J); gsl_linalg_LU_decomp (state->lu, state->permutation, &signum); gsl_linalg_LU_solve (state->lu, state->permutation, f, state->d); t = 1; phi0 = state->phi; new_step: for (i = 0; i < n; i++) { double di = gsl_vector_get (state->d, i); double xi = gsl_vector_get (x, i); gsl_vector_set (state->x_trial, i, xi - t*di); } { int status = GSL_MULTIROOT_FN_EVAL_F (fdf, state->x_trial, f); if (status != GSL_SUCCESS) { return GSL_EBADFUNC; } } phi1 = enorm (f); if (phi1 > phi0 && t > GSL_DBL_EPSILON) { /* full step goes uphill, take a reduced step instead */ double theta = phi1 / phi0; double u = (sqrt(1.0 + 6.0 * theta) - 1.0) / (3.0 * theta); t *= u ; goto new_step; } /* copy x_trial into x */ gsl_vector_memcpy (x, state->x_trial); for (i = 0; i < n; i++) { double di = gsl_vector_get (state->d, i); gsl_vector_set (dx, i, -t*di); } { int status = GSL_MULTIROOT_FN_EVAL_DF (fdf, x, J); if (status != GSL_SUCCESS) { return GSL_EBADFUNC; } } state->phi = phi1; return GSL_SUCCESS; } static void gnewton_free (void * vstate) { gnewton_state_t * state = (gnewton_state_t *) vstate; gsl_vector_free(state->d); gsl_vector_free(state->x_trial); gsl_matrix_free(state->lu); gsl_permutation_free(state->permutation); } static const gsl_multiroot_fdfsolver_type gnewton_type = {"gnewton", /* name */ sizeof (gnewton_state_t), &gnewton_alloc, &gnewton_set, &gnewton_iterate, &gnewton_free}; const gsl_multiroot_fdfsolver_type * gsl_multiroot_fdfsolver_gnewton = &gnewton_type; praat-6.0.04/external/gsl/gsl_multiroots__hybrid.c000066400000000000000000000347271261542461700222760ustar00rootroot00000000000000/* multiroots/hybrid.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_multiroots.h" #include "gsl_linalg.h" #include "gsl_multiroots__dogleg.c" typedef struct { size_t iter; size_t ncfail; size_t ncsuc; size_t nslow1; size_t nslow2; double fnorm; double delta; gsl_matrix *J; gsl_matrix *q; gsl_matrix *r; gsl_vector *tau; gsl_vector *diag; gsl_vector *qtf; gsl_vector *newton; gsl_vector *gradient; gsl_vector *x_trial; gsl_vector *f_trial; gsl_vector *df; gsl_vector *qtdf; gsl_vector *rdx; gsl_vector *w; gsl_vector *v; } hybrid_state_t; static int hybrid_alloc (void *vstate, size_t n); static int hybrid_set (void *vstate, gsl_multiroot_function * func, gsl_vector * x, gsl_vector * f, gsl_vector * dx); static int hybrids_set (void *vstate, gsl_multiroot_function * func, gsl_vector * x, gsl_vector * f, gsl_vector * dx); static int set (void *vstate, gsl_multiroot_function * func, gsl_vector * x, gsl_vector * f, gsl_vector * dx, int scale); static int hybrid_iterate (void *vstate, gsl_multiroot_function * func, gsl_vector * x, gsl_vector * f, gsl_vector * dx); static void hybrid_free (void *vstate); static int iterate (void *vstate, gsl_multiroot_function * func, gsl_vector * x, gsl_vector * f, gsl_vector * dx, int scale); static int hybrid_alloc (void *vstate, size_t n) { hybrid_state_t *state = (hybrid_state_t *) vstate; gsl_matrix *J, *q, *r; gsl_vector *tau, *diag, *qtf, *newton, *gradient, *x_trial, *f_trial, *df, *qtdf, *rdx, *w, *v; J = gsl_matrix_calloc (n, n); if (J == 0) { GSL_ERROR ("failed to allocate space for J", GSL_ENOMEM); } state->J = J; q = gsl_matrix_calloc (n, n); if (q == 0) { gsl_matrix_free (J); GSL_ERROR ("failed to allocate space for q", GSL_ENOMEM); } state->q = q; r = gsl_matrix_calloc (n, n); if (r == 0) { gsl_matrix_free (J); gsl_matrix_free (q); GSL_ERROR ("failed to allocate space for r", GSL_ENOMEM); } state->r = r; tau = gsl_vector_calloc (n); if (tau == 0) { gsl_matrix_free (J); gsl_matrix_free (q); gsl_matrix_free (r); GSL_ERROR ("failed to allocate space for tau", GSL_ENOMEM); } state->tau = tau; diag = gsl_vector_calloc (n); if (diag == 0) { gsl_matrix_free (J); gsl_matrix_free (q); gsl_matrix_free (r); gsl_vector_free (tau); GSL_ERROR ("failed to allocate space for diag", GSL_ENOMEM); } state->diag = diag; qtf = gsl_vector_calloc (n); if (qtf == 0) { gsl_matrix_free (J); gsl_matrix_free (q); gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); GSL_ERROR ("failed to allocate space for qtf", GSL_ENOMEM); } state->qtf = qtf; newton = gsl_vector_calloc (n); if (newton == 0) { gsl_matrix_free (J); gsl_matrix_free (q); gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); GSL_ERROR ("failed to allocate space for newton", GSL_ENOMEM); } state->newton = newton; gradient = gsl_vector_calloc (n); if (gradient == 0) { gsl_matrix_free (J); gsl_matrix_free (q); gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); gsl_vector_free (newton); GSL_ERROR ("failed to allocate space for gradient", GSL_ENOMEM); } state->gradient = gradient; x_trial = gsl_vector_calloc (n); if (x_trial == 0) { gsl_matrix_free (J); gsl_matrix_free (q); gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); gsl_vector_free (newton); gsl_vector_free (gradient); GSL_ERROR ("failed to allocate space for x_trial", GSL_ENOMEM); } state->x_trial = x_trial; f_trial = gsl_vector_calloc (n); if (f_trial == 0) { gsl_matrix_free (J); gsl_matrix_free (q); gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); gsl_vector_free (newton); gsl_vector_free (gradient); gsl_vector_free (x_trial); GSL_ERROR ("failed to allocate space for f_trial", GSL_ENOMEM); } state->f_trial = f_trial; df = gsl_vector_calloc (n); if (df == 0) { gsl_matrix_free (J); gsl_matrix_free (q); gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); gsl_vector_free (newton); gsl_vector_free (gradient); gsl_vector_free (x_trial); gsl_vector_free (f_trial); GSL_ERROR ("failed to allocate space for df", GSL_ENOMEM); } state->df = df; qtdf = gsl_vector_calloc (n); if (qtdf == 0) { gsl_matrix_free (J); gsl_matrix_free (q); gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); gsl_vector_free (newton); gsl_vector_free (gradient); gsl_vector_free (x_trial); gsl_vector_free (f_trial); gsl_vector_free (df); GSL_ERROR ("failed to allocate space for qtdf", GSL_ENOMEM); } state->qtdf = qtdf; rdx = gsl_vector_calloc (n); if (rdx == 0) { gsl_matrix_free (J); gsl_matrix_free (q); gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); gsl_vector_free (newton); gsl_vector_free (gradient); gsl_vector_free (x_trial); gsl_vector_free (f_trial); gsl_vector_free (df); gsl_vector_free (qtdf); GSL_ERROR ("failed to allocate space for rdx", GSL_ENOMEM); } state->rdx = rdx; w = gsl_vector_calloc (n); if (w == 0) { gsl_matrix_free (J); gsl_matrix_free (q); gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); gsl_vector_free (newton); gsl_vector_free (gradient); gsl_vector_free (x_trial); gsl_vector_free (f_trial); gsl_vector_free (df); gsl_vector_free (qtdf); gsl_vector_free (rdx); GSL_ERROR ("failed to allocate space for w", GSL_ENOMEM); } state->w = w; v = gsl_vector_calloc (n); if (v == 0) { gsl_matrix_free (J); gsl_matrix_free (q); gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); gsl_vector_free (newton); gsl_vector_free (gradient); gsl_vector_free (x_trial); gsl_vector_free (f_trial); gsl_vector_free (df); gsl_vector_free (qtdf); gsl_vector_free (rdx); gsl_vector_free (w); GSL_ERROR ("failed to allocate space for v", GSL_ENOMEM); } state->v = v; return GSL_SUCCESS; } static int hybrid_set (void *vstate, gsl_multiroot_function * func, gsl_vector * x, gsl_vector * f, gsl_vector * dx) { int status = set (vstate, func, x, f, dx, 0); return status; } static int hybrids_set (void *vstate, gsl_multiroot_function * func, gsl_vector * x, gsl_vector * f, gsl_vector * dx) { int status = set (vstate, func, x, f, dx, 1); return status; } static int set (void *vstate, gsl_multiroot_function * func, gsl_vector * x, gsl_vector * f, gsl_vector * dx, int scale) { hybrid_state_t *state = (hybrid_state_t *) vstate; gsl_matrix *J = state->J; gsl_matrix *q = state->q; gsl_matrix *r = state->r; gsl_vector *tau = state->tau; gsl_vector *diag = state->diag; int status; status = GSL_MULTIROOT_FN_EVAL (func, x, f); if (status) { return status; } status = gsl_multiroot_fdjacobian (func, x, f, GSL_SQRT_DBL_EPSILON, J); if (status) { return status; } state->iter = 1; state->fnorm = enorm (f); state->ncfail = 0; state->ncsuc = 0; state->nslow1 = 0; state->nslow2 = 0; gsl_vector_set_all (dx, 0.0); /* Store column norms in diag */ if (scale) compute_diag (J, diag); else gsl_vector_set_all (diag, 1.0); /* Set delta to factor |D x| or to factor if |D x| is zero */ state->delta = compute_delta (diag, x); /* Factorize J into QR decomposition */ status = gsl_linalg_QR_decomp (J, tau); if (status) { return status; } status = gsl_linalg_QR_unpack (J, tau, q, r); return status; } static int hybrid_iterate (void *vstate, gsl_multiroot_function * func, gsl_vector * x, gsl_vector * f, gsl_vector * dx) { int status = iterate (vstate, func, x, f, dx, 0); return status; } static int hybrids_iterate (void *vstate, gsl_multiroot_function * func, gsl_vector * x, gsl_vector * f, gsl_vector * dx) { int status = iterate (vstate, func, x, f, dx, 1); return status; } static int iterate (void *vstate, gsl_multiroot_function * func, gsl_vector * x, gsl_vector * f, gsl_vector * dx, int scale) { hybrid_state_t *state = (hybrid_state_t *) vstate; const double fnorm = state->fnorm; gsl_matrix *J = state->J; gsl_matrix *q = state->q; gsl_matrix *r = state->r; gsl_vector *tau = state->tau; gsl_vector *diag = state->diag; gsl_vector *qtf = state->qtf; gsl_vector *x_trial = state->x_trial; gsl_vector *f_trial = state->f_trial; gsl_vector *df = state->df; gsl_vector *qtdf = state->qtdf; gsl_vector *rdx = state->rdx; gsl_vector *w = state->w; gsl_vector *v = state->v; double prered, actred; double pnorm, fnorm1, fnorm1p; double ratio; double p1 = 0.1, p5 = 0.5, p001 = 0.001, p0001 = 0.0001; /* Compute qtf = Q^T f */ compute_qtf (q, f, qtf); /* Compute dogleg step */ dogleg (r, qtf, diag, state->delta, state->newton, state->gradient, dx); /* Take a trial step */ compute_trial_step (x, dx, state->x_trial); pnorm = scaled_enorm (diag, dx); if (state->iter == 1) { if (pnorm < state->delta) { state->delta = pnorm; } } /* Evaluate function at x + p */ { int status = GSL_MULTIROOT_FN_EVAL (func, x_trial, f_trial); if (status != GSL_SUCCESS) { return GSL_EBADFUNC; } } /* Set df = f_trial - f */ compute_df (f_trial, f, df); /* Compute the scaled actual reduction */ fnorm1 = enorm (f_trial); actred = compute_actual_reduction (fnorm, fnorm1); /* Compute rdx = R dx */ compute_rdx (r, dx, rdx); /* Compute the scaled predicted reduction phi1p = |Q^T f + R dx| */ fnorm1p = enorm_sum (qtf, rdx); prered = compute_predicted_reduction (fnorm, fnorm1p); /* Compute the ratio of the actual to predicted reduction */ if (prered > 0) { ratio = actred / prered; } else { ratio = 0; } /* Update the step bound */ if (ratio < p1) { state->ncsuc = 0; state->ncfail++; state->delta *= p5; } else { state->ncfail = 0; state->ncsuc++; if (ratio >= p5 || state->ncsuc > 1) state->delta = GSL_MAX (state->delta, pnorm / p5); if (fabs (ratio - 1) <= p1) state->delta = pnorm / p5; } /* Test for successful iteration */ if (ratio >= p0001) { gsl_vector_memcpy (x, x_trial); gsl_vector_memcpy (f, f_trial); state->fnorm = fnorm1; state->iter++; } /* Determine the progress of the iteration */ state->nslow1++; if (actred >= p001) state->nslow1 = 0; if (actred >= p1) state->nslow2 = 0; if (state->ncfail == 2) { gsl_multiroot_fdjacobian (func, x, f, GSL_SQRT_DBL_EPSILON, J); state->nslow2++; if (state->iter == 1) { if (scale) compute_diag (J, diag); state->delta = compute_delta (diag, x); } else { if (scale) update_diag (J, diag); } /* Factorize J into QR decomposition */ gsl_linalg_QR_decomp (J, tau); gsl_linalg_QR_unpack (J, tau, q, r); return GSL_SUCCESS; } /* Compute qtdf = Q^T df, w = (Q^T df - R dx)/|dx|, v = D^2 dx/|dx| */ compute_qtf (q, df, qtdf); compute_wv (qtdf, rdx, dx, diag, pnorm, w, v); /* Rank-1 update of the jacobian Q'R' = Q(R + w v^T) */ gsl_linalg_QR_update (q, r, w, v); /* No progress as measured by jacobian evaluations */ if (state->nslow2 == 5) { return GSL_ENOPROGJ; } /* No progress as measured by function evaluations */ if (state->nslow1 == 10) { return GSL_ENOPROG; } return GSL_SUCCESS; } static void hybrid_free (void *vstate) { hybrid_state_t *state = (hybrid_state_t *) vstate; gsl_vector_free (state->v); gsl_vector_free (state->w); gsl_vector_free (state->rdx); gsl_vector_free (state->qtdf); gsl_vector_free (state->df); gsl_vector_free (state->f_trial); gsl_vector_free (state->x_trial); gsl_vector_free (state->gradient); gsl_vector_free (state->newton); gsl_vector_free (state->qtf); gsl_vector_free (state->diag); gsl_vector_free (state->tau); gsl_matrix_free (state->r); gsl_matrix_free (state->q); gsl_matrix_free (state->J); } static const gsl_multiroot_fsolver_type hybrid_type = { "hybrid", /* name */ sizeof (hybrid_state_t), &hybrid_alloc, &hybrid_set, &hybrid_iterate, &hybrid_free }; static const gsl_multiroot_fsolver_type hybrids_type = { "hybrids", /* name */ sizeof (hybrid_state_t), &hybrid_alloc, &hybrids_set, &hybrids_iterate, &hybrid_free }; const gsl_multiroot_fsolver_type *gsl_multiroot_fsolver_hybrid = &hybrid_type; const gsl_multiroot_fsolver_type *gsl_multiroot_fsolver_hybrids = &hybrids_type; praat-6.0.04/external/gsl/gsl_multiroots__hybridj.c000066400000000000000000000335021261542461700224360ustar00rootroot00000000000000/* multiroots/hybridj.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_multiroots.h" #include "gsl_linalg.h" #include "gsl_multiroots__dogleg.c" typedef struct { size_t iter; size_t ncfail; size_t ncsuc; size_t nslow1; size_t nslow2; double fnorm; double delta; gsl_matrix *q; gsl_matrix *r; gsl_vector *tau; gsl_vector *diag; gsl_vector *qtf; gsl_vector *newton; gsl_vector *gradient; gsl_vector *x_trial; gsl_vector *f_trial; gsl_vector *df; gsl_vector *qtdf; gsl_vector *rdx; gsl_vector *w; gsl_vector *v; } hybridj_state_t; static int hybridj_alloc (void *vstate, size_t n); static int hybridj_set (void *vstate, gsl_multiroot_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx); static int hybridsj_set (void *vstate, gsl_multiroot_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx); static int set (void *vstate, gsl_multiroot_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx, int scale); static int hybridj_iterate (void *vstate, gsl_multiroot_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx); static void hybridj_free (void *vstate); static int iterate (void *vstate, gsl_multiroot_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx, int scale); static int hybridj_alloc (void *vstate, size_t n) { hybridj_state_t *state = (hybridj_state_t *) vstate; gsl_matrix *q, *r; gsl_vector *tau, *diag, *qtf, *newton, *gradient, *x_trial, *f_trial, *df, *qtdf, *rdx, *w, *v; q = gsl_matrix_calloc (n, n); if (q == 0) { GSL_ERROR ("failed to allocate space for q", GSL_ENOMEM); } state->q = q; r = gsl_matrix_calloc (n, n); if (r == 0) { gsl_matrix_free (q); GSL_ERROR ("failed to allocate space for r", GSL_ENOMEM); } state->r = r; tau = gsl_vector_calloc (n); if (tau == 0) { gsl_matrix_free (q); gsl_matrix_free (r); GSL_ERROR ("failed to allocate space for tau", GSL_ENOMEM); } state->tau = tau; diag = gsl_vector_calloc (n); if (diag == 0) { gsl_matrix_free (q); gsl_matrix_free (r); gsl_vector_free (tau); GSL_ERROR ("failed to allocate space for diag", GSL_ENOMEM); } state->diag = diag; qtf = gsl_vector_calloc (n); if (qtf == 0) { gsl_matrix_free (q); gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); GSL_ERROR ("failed to allocate space for qtf", GSL_ENOMEM); } state->qtf = qtf; newton = gsl_vector_calloc (n); if (newton == 0) { gsl_matrix_free (q); gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); GSL_ERROR ("failed to allocate space for newton", GSL_ENOMEM); } state->newton = newton; gradient = gsl_vector_calloc (n); if (gradient == 0) { gsl_matrix_free (q); gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); gsl_vector_free (newton); GSL_ERROR ("failed to allocate space for gradient", GSL_ENOMEM); } state->gradient = gradient; x_trial = gsl_vector_calloc (n); if (x_trial == 0) { gsl_matrix_free (q); gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); gsl_vector_free (newton); gsl_vector_free (gradient); GSL_ERROR ("failed to allocate space for x_trial", GSL_ENOMEM); } state->x_trial = x_trial; f_trial = gsl_vector_calloc (n); if (f_trial == 0) { gsl_matrix_free (q); gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); gsl_vector_free (newton); gsl_vector_free (gradient); gsl_vector_free (x_trial); GSL_ERROR ("failed to allocate space for f_trial", GSL_ENOMEM); } state->f_trial = f_trial; df = gsl_vector_calloc (n); if (df == 0) { gsl_matrix_free (q); gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); gsl_vector_free (newton); gsl_vector_free (gradient); gsl_vector_free (x_trial); gsl_vector_free (f_trial); GSL_ERROR ("failed to allocate space for df", GSL_ENOMEM); } state->df = df; qtdf = gsl_vector_calloc (n); if (qtdf == 0) { gsl_matrix_free (q); gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); gsl_vector_free (newton); gsl_vector_free (gradient); gsl_vector_free (x_trial); gsl_vector_free (f_trial); gsl_vector_free (df); GSL_ERROR ("failed to allocate space for qtdf", GSL_ENOMEM); } state->qtdf = qtdf; rdx = gsl_vector_calloc (n); if (rdx == 0) { gsl_matrix_free (q); gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); gsl_vector_free (newton); gsl_vector_free (gradient); gsl_vector_free (x_trial); gsl_vector_free (f_trial); gsl_vector_free (df); gsl_vector_free (qtdf); GSL_ERROR ("failed to allocate space for rdx", GSL_ENOMEM); } state->rdx = rdx; w = gsl_vector_calloc (n); if (w == 0) { gsl_matrix_free (q); gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); gsl_vector_free (newton); gsl_vector_free (gradient); gsl_vector_free (x_trial); gsl_vector_free (f_trial); gsl_vector_free (df); gsl_vector_free (qtdf); gsl_vector_free (rdx); GSL_ERROR ("failed to allocate space for w", GSL_ENOMEM); } state->w = w; v = gsl_vector_calloc (n); if (v == 0) { gsl_matrix_free (q); gsl_matrix_free (r); gsl_vector_free (tau); gsl_vector_free (diag); gsl_vector_free (qtf); gsl_vector_free (newton); gsl_vector_free (gradient); gsl_vector_free (x_trial); gsl_vector_free (f_trial); gsl_vector_free (df); gsl_vector_free (qtdf); gsl_vector_free (rdx); gsl_vector_free (w); GSL_ERROR ("failed to allocate space for v", GSL_ENOMEM); } state->v = v; return GSL_SUCCESS; } static int hybridj_set (void *vstate, gsl_multiroot_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx) { int status = set (vstate, fdf, x, f, J, dx, 0); return status ; } static int hybridsj_set (void *vstate, gsl_multiroot_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx) { int status = set (vstate, fdf, x, f, J, dx, 1); return status ; } static int set (void *vstate, gsl_multiroot_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx, int scale) { hybridj_state_t *state = (hybridj_state_t *) vstate; gsl_matrix *q = state->q; gsl_matrix *r = state->r; gsl_vector *tau = state->tau; gsl_vector *diag = state->diag; GSL_MULTIROOT_FN_EVAL_F_DF (fdf, x, f, J); state->iter = 1; state->fnorm = enorm (f); state->ncfail = 0; state->ncsuc = 0; state->nslow1 = 0; state->nslow2 = 0; gsl_vector_set_all (dx, 0.0); /* Store column norms in diag */ if (scale) compute_diag (J, diag); else gsl_vector_set_all (diag, 1.0); /* Set delta to factor |D x| or to factor if |D x| is zero */ state->delta = compute_delta (diag, x); /* Factorize J into QR decomposition */ gsl_linalg_QR_decomp (J, tau); gsl_linalg_QR_unpack (J, tau, q, r); return GSL_SUCCESS; } static int hybridj_iterate (void *vstate, gsl_multiroot_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx) { int status = iterate (vstate, fdf, x, f, J, dx, 0); return status; } static int hybridsj_iterate (void *vstate, gsl_multiroot_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx) { int status = iterate (vstate, fdf, x, f, J, dx, 1); return status; } static int iterate (void *vstate, gsl_multiroot_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx, int scale) { hybridj_state_t *state = (hybridj_state_t *) vstate; const double fnorm = state->fnorm; gsl_matrix *q = state->q; gsl_matrix *r = state->r; gsl_vector *tau = state->tau; gsl_vector *diag = state->diag; gsl_vector *qtf = state->qtf; gsl_vector *x_trial = state->x_trial; gsl_vector *f_trial = state->f_trial; gsl_vector *df = state->df; gsl_vector *qtdf = state->qtdf; gsl_vector *rdx = state->rdx; gsl_vector *w = state->w; gsl_vector *v = state->v; double prered, actred; double pnorm, fnorm1, fnorm1p; double ratio; double p1 = 0.1, p5 = 0.5, p001 = 0.001, p0001 = 0.0001; /* Compute qtf = Q^T f */ compute_qtf (q, f, qtf); /* Compute dogleg step */ dogleg (r, qtf, diag, state->delta, state->newton, state->gradient, dx); /* Take a trial step */ compute_trial_step (x, dx, state->x_trial); pnorm = scaled_enorm (diag, dx); if (state->iter == 1) { if (pnorm < state->delta) { state->delta = pnorm; } } /* Evaluate function at x + p */ { int status = GSL_MULTIROOT_FN_EVAL_F (fdf, x_trial, f_trial); if (status != GSL_SUCCESS) { return GSL_EBADFUNC; } } /* Set df = f_trial - f */ compute_df (f_trial, f, df); /* Compute the scaled actual reduction */ fnorm1 = enorm (f_trial); actred = compute_actual_reduction (fnorm, fnorm1); /* Compute rdx = R dx */ compute_rdx (r, dx, rdx); /* Compute the scaled predicted reduction phi1p = |Q^T f + R dx| */ fnorm1p = enorm_sum (qtf, rdx); prered = compute_predicted_reduction (fnorm, fnorm1p); /* Compute the ratio of the actual to predicted reduction */ if (prered > 0) { ratio = actred / prered; } else { ratio = 0; } /* Update the step bound */ if (ratio < p1) { state->ncsuc = 0; state->ncfail++; state->delta *= p5; } else { state->ncfail = 0; state->ncsuc++; if (ratio >= p5 || state->ncsuc > 1) state->delta = GSL_MAX (state->delta, pnorm / p5); if (fabs (ratio - 1) <= p1) state->delta = pnorm / p5; } /* Test for successful iteration */ if (ratio >= p0001) { gsl_vector_memcpy (x, x_trial); gsl_vector_memcpy (f, f_trial); state->fnorm = fnorm1; state->iter++; } /* Determine the progress of the iteration */ state->nslow1++; if (actred >= p001) state->nslow1 = 0; if (actred >= p1) state->nslow2 = 0; if (state->ncfail == 2) { { int status = GSL_MULTIROOT_FN_EVAL_DF (fdf, x, J); if (status != GSL_SUCCESS) { return GSL_EBADFUNC; } } state->nslow2++; if (state->iter == 1) { if (scale) compute_diag (J, diag); state->delta = compute_delta (diag, x); } else { if (scale) update_diag (J, diag); } /* Factorize J into QR decomposition */ gsl_linalg_QR_decomp (J, tau); gsl_linalg_QR_unpack (J, tau, q, r); return GSL_SUCCESS; } /* Compute qtdf = Q^T df, w = (Q^T df - R dx)/|dx|, v = D^2 dx/|dx| */ compute_qtf (q, df, qtdf); compute_wv (qtdf, rdx, dx, diag, pnorm, w, v); /* Rank-1 update of the jacobian Q'R' = Q(R + w v^T) */ gsl_linalg_QR_update (q, r, w, v); /* No progress as measured by jacobian evaluations */ if (state->nslow2 == 5) { return GSL_ENOPROGJ; } /* No progress as measured by function evaluations */ if (state->nslow1 == 10) { return GSL_ENOPROG; } return GSL_SUCCESS; } static void hybridj_free (void *vstate) { hybridj_state_t *state = (hybridj_state_t *) vstate; gsl_vector_free (state->v); gsl_vector_free (state->w); gsl_vector_free (state->rdx); gsl_vector_free (state->qtdf); gsl_vector_free (state->df); gsl_vector_free (state->f_trial); gsl_vector_free (state->x_trial); gsl_vector_free (state->gradient); gsl_vector_free (state->newton); gsl_vector_free (state->qtf); gsl_vector_free (state->diag); gsl_vector_free (state->tau); gsl_matrix_free (state->r); gsl_matrix_free (state->q); } static const gsl_multiroot_fdfsolver_type hybridj_type = { "hybridj", /* name */ sizeof (hybridj_state_t), &hybridj_alloc, &hybridj_set, &hybridj_iterate, &hybridj_free }; static const gsl_multiroot_fdfsolver_type hybridsj_type = { "hybridsj", /* name */ sizeof (hybridj_state_t), &hybridj_alloc, &hybridsj_set, &hybridsj_iterate, &hybridj_free }; const gsl_multiroot_fdfsolver_type *gsl_multiroot_fdfsolver_hybridj = &hybridj_type; const gsl_multiroot_fdfsolver_type *gsl_multiroot_fdfsolver_hybridsj = &hybridsj_type; praat-6.0.04/external/gsl/gsl_multiroots__newton.c000066400000000000000000000071571261542461700223240ustar00rootroot00000000000000/* multiroots/newton.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_multiroots.h" #include "gsl_linalg.h" typedef struct { gsl_matrix * lu; gsl_permutation * permutation; } newton_state_t; static int newton_alloc (void * vstate, size_t n); static int newton_set (void * vstate, gsl_multiroot_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx); static int newton_iterate (void * vstate, gsl_multiroot_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx); static void newton_free (void * vstate); static int newton_alloc (void * vstate, size_t n) { newton_state_t * state = (newton_state_t *) vstate; gsl_permutation * p; gsl_matrix * m; m = gsl_matrix_calloc (n,n); if (m == 0) { GSL_ERROR ("failed to allocate space for lu", GSL_ENOMEM); } state->lu = m ; p = gsl_permutation_calloc (n); if (p == 0) { gsl_matrix_free(m); GSL_ERROR ("failed to allocate space for permutation", GSL_ENOMEM); } state->permutation = p ; return GSL_SUCCESS; } static int newton_set (void * vstate, gsl_multiroot_function_fdf * FDF, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx) { newton_state_t * state = (newton_state_t *) vstate; size_t i, n = FDF->n ; state = 0 ; /* avoid warnings about unused parameters */ GSL_MULTIROOT_FN_EVAL_F_DF (FDF, x, f, J); for (i = 0; i < n; i++) { gsl_vector_set (dx, i, 0.0); } return GSL_SUCCESS; } static int newton_iterate (void * vstate, gsl_multiroot_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx) { newton_state_t * state = (newton_state_t *) vstate; int signum; size_t i; size_t n = fdf->n ; gsl_matrix_memcpy (state->lu, J); gsl_linalg_LU_decomp (state->lu, state->permutation, &signum); gsl_linalg_LU_solve (state->lu, state->permutation, f, dx); for (i = 0; i < n; i++) { double e = gsl_vector_get (dx, i); double y = gsl_vector_get (x, i); gsl_vector_set (dx, i, -e); gsl_vector_set (x, i, y - e); } { int status = GSL_MULTIROOT_FN_EVAL_F_DF (fdf, x, f, J); if (status != GSL_SUCCESS) { return GSL_EBADFUNC; } } return GSL_SUCCESS; } static void newton_free (void * vstate) { newton_state_t * state = (newton_state_t *) vstate; gsl_matrix_free(state->lu); gsl_permutation_free(state->permutation); } static const gsl_multiroot_fdfsolver_type newton_type = {"newton", /* name */ sizeof (newton_state_t), &newton_alloc, &newton_set, &newton_iterate, &newton_free}; const gsl_multiroot_fdfsolver_type * gsl_multiroot_fdfsolver_newton = &newton_type; praat-6.0.04/external/gsl/gsl_nan.h000066400000000000000000000024631261542461700171260ustar00rootroot00000000000000/* gsl_nan.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_NAN_H__ #define __GSL_NAN_H__ #ifdef INFINITY # define GSL_POSINF INFINITY # define GSL_NEGINF (-INFINITY) #elif defined(HUGE_VAL) # define GSL_POSINF HUGE_VAL # define GSL_NEGINF (-HUGE_VAL) #else # define GSL_POSINF (gsl_posinf()) # define GSL_NEGINF (gsl_neginf()) #endif #ifdef NAN # define GSL_NAN NAN #elif defined(INFINITY) # define GSL_NAN (INFINITY/INFINITY) #else # define GSL_NAN (gsl_nan()) #endif #define GSL_POSZERO (+0) #define GSL_NEGZERO (-0) #endif /* __GSL_NAN_H__ */ praat-6.0.04/external/gsl/gsl_ntuple.h000066400000000000000000000041351261542461700176570ustar00rootroot00000000000000/* histogram/ntuple.h * * Copyright (C) 2000 Simone Piccardi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ /* Jan/2001 Modified by Brian Gough. Minor changes for GSL */ #ifndef __GSL_NTUPLE_H__ #define __GSL_NTUPLE_H__ #include #include #include "gsl_errno.h" #include "gsl_histogram.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { FILE * file; void * ntuple_data; size_t size; } gsl_ntuple; typedef struct { int (* function) (void * ntuple_data, void * params); void * params; } gsl_ntuple_select_fn; typedef struct { double (* function) (void * ntuple_data, void * params); void * params; } gsl_ntuple_value_fn; gsl_ntuple * gsl_ntuple_open (char * filename, void * ntuple_data, size_t size); gsl_ntuple * gsl_ntuple_create (char * filename, void * ntuple_data, size_t size); int gsl_ntuple_write (gsl_ntuple * ntuple); int gsl_ntuple_read (gsl_ntuple * ntuple); int gsl_ntuple_bookdata (gsl_ntuple * ntuple); /* synonym for write */ int gsl_ntuple_project (gsl_histogram * h, gsl_ntuple * ntuple, gsl_ntuple_value_fn *value_func, gsl_ntuple_select_fn *select_func); int gsl_ntuple_close (gsl_ntuple * ntuple); __END_DECLS #endif /* __GSL_NTUPLE_H__ */ praat-6.0.04/external/gsl/gsl_ntuple__ntuple.c000066400000000000000000000104661261542461700214040ustar00rootroot00000000000000/* histogram/ntuple.c * * Copyright (C) 2000 Simone Piccardi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Jan/2001 Modified by Brian Gough. Minor changes for GSL */ #include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_ntuple.h" /* * gsl_ntuple_open: * Initialize an ntuple structure and create the related file */ gsl_ntuple * gsl_ntuple_create (char *filename, void *ntuple_data, size_t size) { gsl_ntuple *ntuple = (gsl_ntuple *)malloc (sizeof (gsl_ntuple)); if (ntuple == 0) { GSL_ERROR_VAL ("failed to allocate space for ntuple struct", GSL_ENOMEM, 0); } ntuple->ntuple_data = ntuple_data; ntuple->size = size; ntuple->file = fopen (filename, "wb"); if (ntuple->file == 0) { free (ntuple); GSL_ERROR_VAL ("unable to create ntuple file", GSL_EFAILED, 0); } return ntuple; } /* * gsl_ntuple_open: * Initialize an ntuple structure and open the related file */ gsl_ntuple * gsl_ntuple_open (char *filename, void *ntuple_data, size_t size) { gsl_ntuple *ntuple = (gsl_ntuple *)malloc (sizeof (gsl_ntuple)); if (ntuple == 0) { GSL_ERROR_VAL ("failed to allocate space for ntuple struct", GSL_ENOMEM, 0); } ntuple->ntuple_data = ntuple_data; ntuple->size = size; ntuple->file = fopen (filename, "rb"); if (ntuple->file == 0) { free (ntuple); GSL_ERROR_VAL ("unable to open ntuple file for reading", GSL_EFAILED, 0); } return ntuple; } /* * gsl_ntuple_write: * write to file a data row, must be used in a loop! */ int gsl_ntuple_write (gsl_ntuple * ntuple) { size_t nwrite; nwrite = fwrite (ntuple->ntuple_data, ntuple->size, 1, ntuple->file); if (nwrite != 1) { GSL_ERROR ("failed to write ntuple entry to file", GSL_EFAILED); } return GSL_SUCCESS; } /* the following function is a synonym for gsl_ntuple_write */ int gsl_ntuple_bookdata (gsl_ntuple * ntuple) { return gsl_ntuple_write (ntuple); } /* * gsl_ntuple_read: * read form file a data row, must be used in a loop! */ int gsl_ntuple_read (gsl_ntuple * ntuple) { size_t nread; nread = fread (ntuple->ntuple_data, ntuple->size, 1, ntuple->file); if (nread == 0 && feof(ntuple->file)) { return GSL_EOF; } if (nread != 1) { GSL_ERROR ("failed to read ntuple entry from file", GSL_EFAILED); } return GSL_SUCCESS; } /* * gsl_ntuple_project: * fill an histogram with an ntuple file contents, use * SelVal and SelFunc user defined functions to get * the value to book and the selection funtion */ #define EVAL(f,x) ((*((f)->function))(x,(f)->params)) int gsl_ntuple_project (gsl_histogram * h, gsl_ntuple * ntuple, gsl_ntuple_value_fn * value_func, gsl_ntuple_select_fn * select_func) { size_t nread; do { nread = fread (ntuple->ntuple_data, ntuple->size, 1, ntuple->file); if (nread == 0 && feof(ntuple->file)) { break ; } if (nread != 1) { GSL_ERROR ("failed to read ntuple for projection", GSL_EFAILED); } if (EVAL(select_func, ntuple->ntuple_data)) { gsl_histogram_increment (h, EVAL(value_func, ntuple->ntuple_data)); } } while (1); return GSL_SUCCESS; } /* * gsl_ntuple_close: * close the ntuple file and free the memory */ int gsl_ntuple_close (gsl_ntuple * ntuple) { int status = fclose (ntuple->file); if (status) { GSL_ERROR ("failed to close ntuple file", GSL_EFAILED); } free (ntuple); return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_ode-initval__bsimp.c000066400000000000000000000327601261542461700221140ustar00rootroot00000000000000/* ode-initval/bsimp.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Bulirsch-Stoer Implicit */ /* Author: G. Jungman */ /* Bader-Deuflhard implicit extrapolative stepper. * [Numer. Math., 41, 373 (1983)] */ #include "gsl__config.h" #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_linalg.h" #include "gsl_odeiv.h" #include "gsl_ode-initval__odeiv_util.h" #define SEQUENCE_COUNT 8 #define SEQUENCE_MAX 7 /* Bader-Deuflhard extrapolation sequence */ static const int bd_sequence[SEQUENCE_COUNT] = { 2, 6, 10, 14, 22, 34, 50, 70 }; typedef struct { gsl_matrix *d; /* workspace for extrapolation */ gsl_matrix *a_mat; /* workspace for linear system matrix */ gsl_permutation *p_vec; /* workspace for LU permutation */ double x[SEQUENCE_MAX]; /* workspace for extrapolation */ /* state info */ size_t k_current; size_t k_choice; double h_next; double eps; /* workspace for extrapolation step */ double *yp; double *y_save; double *yerr_save; double *y_extrap_save; double *y_extrap_sequence; double *extrap_work; double *dfdt; double *y_temp; double *delta_temp; double *weight; gsl_matrix *dfdy; /* workspace for the basic stepper */ double *rhs_temp; double *delta; /* order of last step */ size_t order; } bsimp_state_t; /* Compute weighting factor */ static void compute_weights (const double y[], double w[], size_t dim) { size_t i; for (i = 0; i < dim; i++) { double u = fabs(y[i]); w[i] = (u > 0.0) ? u : 1.0; } } /* Calculate a choice for the "order" of the method, using the * Deuflhard criteria. */ static size_t bsimp_deuf_kchoice (double eps, size_t dimension) { const double safety_f = 0.25; const double small_eps = safety_f * eps; double a_work[SEQUENCE_COUNT]; double alpha[SEQUENCE_MAX][SEQUENCE_MAX]; int i, k; a_work[0] = bd_sequence[0] + 1.0; for (k = 0; k < SEQUENCE_MAX; k++) { a_work[k + 1] = a_work[k] + bd_sequence[k + 1]; } for (i = 0; i < SEQUENCE_MAX; i++) { alpha[i][i] = 1.0; for (k = 0; k < i; k++) { const double tmp1 = a_work[k + 1] - a_work[i + 1]; const double tmp2 = (a_work[i + 1] - a_work[0] + 1.0) * (2 * k + 1); alpha[k][i] = pow (small_eps, tmp1 / tmp2); } } a_work[0] += dimension; for (k = 0; k < SEQUENCE_MAX; k++) { a_work[k + 1] = a_work[k] + bd_sequence[k + 1]; } for (k = 0; k < SEQUENCE_MAX - 1; k++) { if (a_work[k + 2] > a_work[k + 1] * alpha[k][k + 1]) break; } return k; } static void poly_extrap (gsl_matrix * d, const double x[], const unsigned int i_step, const double x_i, const double y_i[], double y_0[], double y_0_err[], double work[], const size_t dim) { size_t j, k; DBL_MEMCPY (y_0_err, y_i, dim); DBL_MEMCPY (y_0, y_i, dim); if (i_step == 0) { for (j = 0; j < dim; j++) { gsl_matrix_set (d, 0, j, y_i[j]); } } else { DBL_MEMCPY (work, y_i, dim); for (k = 0; k < i_step; k++) { double delta = 1.0 / (x[i_step - k - 1] - x_i); const double f1 = delta * x_i; const double f2 = delta * x[i_step - k - 1]; for (j = 0; j < dim; j++) { const double q_kj = gsl_matrix_get (d, k, j); gsl_matrix_set (d, k, j, y_0_err[j]); delta = work[j] - q_kj; y_0_err[j] = f1 * delta; work[j] = f2 * delta; y_0[j] += y_0_err[j]; } } for (j = 0; j < dim; j++) { gsl_matrix_set (d, i_step, j, y_0_err[j]); } } } /* Basic implicit Bulirsch-Stoer step. Divide the step h_total into * n_step smaller steps and do the Bader-Deuflhard semi-implicit * iteration. */ static int bsimp_step_local (void *vstate, size_t dim, const double t0, const double h_total, const unsigned int n_step, const double y[], const double yp[], const double dfdt[], const gsl_matrix * dfdy, double y_out[], const gsl_odeiv_system * sys) { bsimp_state_t *state = (bsimp_state_t *) vstate; gsl_matrix *const a_mat = state->a_mat; gsl_permutation *const p_vec = state->p_vec; double *const delta = state->delta; double *const y_temp = state->y_temp; double *const delta_temp = state->delta_temp; double *const rhs_temp = state->rhs_temp; double *const w = state->weight; gsl_vector_view y_temp_vec = gsl_vector_view_array (y_temp, dim); gsl_vector_view delta_temp_vec = gsl_vector_view_array (delta_temp, dim); gsl_vector_view rhs_temp_vec = gsl_vector_view_array (rhs_temp, dim); const double h = h_total / n_step; double t = t0 + h; double sum; /* This is the factor sigma referred to in equation 3.4 of the paper. A relative change in y exceeding sigma indicates a runaway behavior. According to the authors suitable values for sigma are >>1. I have chosen a value of 100*dim. BJG */ const double max_sum = 100.0 * dim; int signum, status; size_t i, j; size_t n_inter; /* Calculate the matrix for the linear system. */ for (i = 0; i < dim; i++) { for (j = 0; j < dim; j++) { gsl_matrix_set (a_mat, i, j, -h * gsl_matrix_get (dfdy, i, j)); } gsl_matrix_set (a_mat, i, i, gsl_matrix_get (a_mat, i, i) + 1.0); } /* LU decomposition for the linear system. */ gsl_linalg_LU_decomp (a_mat, p_vec, &signum); /* Compute weighting factors */ compute_weights (y, w, dim); /* Initial step. */ for (i = 0; i < dim; i++) { y_temp[i] = h * (yp[i] + h * dfdt[i]); } gsl_linalg_LU_solve (a_mat, p_vec, &y_temp_vec.vector, &delta_temp_vec.vector); sum = 0.0; for (i = 0; i < dim; i++) { const double di = delta_temp[i]; delta[i] = di; y_temp[i] = y[i] + di; sum += fabs(di) / w[i]; } if (sum > max_sum) { return GSL_EFAILED ; } /* Intermediate steps. */ status = GSL_ODEIV_FN_EVAL (sys, t, y_temp, y_out); if (status) { return status; } for (n_inter = 1; n_inter < n_step; n_inter++) { for (i = 0; i < dim; i++) { rhs_temp[i] = h * y_out[i] - delta[i]; } gsl_linalg_LU_solve (a_mat, p_vec, &rhs_temp_vec.vector, &delta_temp_vec.vector); sum = 0.0; for (i = 0; i < dim; i++) { delta[i] += 2.0 * delta_temp[i]; y_temp[i] += delta[i]; sum += fabs(delta[i]) / w[i]; } if (sum > max_sum) { return GSL_EFAILED ; } t += h; status = GSL_ODEIV_FN_EVAL (sys, t, y_temp, y_out); if (status) { return status; } } /* Final step. */ for (i = 0; i < dim; i++) { rhs_temp[i] = h * y_out[i] - delta[i]; } gsl_linalg_LU_solve (a_mat, p_vec, &rhs_temp_vec.vector, &delta_temp_vec.vector); sum = 0.0; for (i = 0; i < dim; i++) { y_out[i] = y_temp[i] + delta_temp[i]; sum += fabs(delta_temp[i]) / w[i]; } if (sum > max_sum) { return GSL_EFAILED ; } return GSL_SUCCESS; } static void * bsimp_alloc (size_t dim) { bsimp_state_t *state = (bsimp_state_t *) malloc (sizeof (bsimp_state_t)); state->d = gsl_matrix_alloc (SEQUENCE_MAX, dim); state->a_mat = gsl_matrix_alloc (dim, dim); state->p_vec = gsl_permutation_alloc (dim); state->yp = (double *) malloc (dim * sizeof (double)); state->y_save = (double *) malloc (dim * sizeof (double)); state->yerr_save = (double *) malloc (dim * sizeof (double)); state->y_extrap_save = (double *) malloc (dim * sizeof (double)); state->y_extrap_sequence = (double *) malloc (dim * sizeof (double)); state->extrap_work = (double *) malloc (dim * sizeof (double)); state->dfdt = (double *) malloc (dim * sizeof (double)); state->y_temp = (double *) malloc (dim * sizeof (double)); state->delta_temp = (double *) malloc (dim * sizeof(double)); state->weight = (double *) malloc (dim * sizeof(double)); state->dfdy = gsl_matrix_alloc (dim, dim); state->rhs_temp = (double *) malloc (dim * sizeof(double)); state->delta = (double *) malloc (dim * sizeof (double)); { size_t k_choice = bsimp_deuf_kchoice (GSL_SQRT_DBL_EPSILON, dim); /*FIXME: choice of epsilon? */ state->k_choice = k_choice; state->k_current = k_choice; state->order = 2 * k_choice; } state->h_next = -GSL_SQRT_DBL_MAX; return state; } /* Perform the basic semi-implicit extrapolation * step, of size h, at a Deuflhard determined order. */ static int bsimp_apply (void *vstate, size_t dim, double t, double h, double y[], double yerr[], const double dydt_in[], double dydt_out[], const gsl_odeiv_system * sys) { bsimp_state_t *state = (bsimp_state_t *) vstate; double *const x = state->x; double *const yp = state->yp; double *const y_save = state->y_save; double *const yerr_save = state->yerr_save; double *const y_extrap_sequence = state->y_extrap_sequence; double *const y_extrap_save = state->y_extrap_save; double *const extrap_work = state->extrap_work; double *const dfdt = state->dfdt; gsl_matrix *d = state->d; gsl_matrix *dfdy = state->dfdy; const double t_local = t; size_t i, k; if (h + t_local == t_local) { return GSL_EUNDRFLW; /* FIXME: error condition */ } DBL_MEMCPY (y_extrap_save, y, dim); /* Save inputs */ DBL_MEMCPY (y_save, y, dim); DBL_MEMCPY (yerr_save, yerr, dim); /* Evaluate the derivative. */ if (dydt_in != NULL) { DBL_MEMCPY (yp, dydt_in, dim); } else { int s = GSL_ODEIV_FN_EVAL (sys, t_local, y, yp); if (s != GSL_SUCCESS) { return s; } } /* Evaluate the Jacobian for the system. */ { int s = GSL_ODEIV_JA_EVAL (sys, t_local, y, dfdy->data, dfdt); if (s != GSL_SUCCESS) { return s; } } /* Make a series of refined extrapolations, * up to the specified maximum order, which * was calculated based on the Deuflhard * criterion upon state initialization. */ for (k = 0; k <= state->k_current; k++) { const unsigned int N = bd_sequence[k]; const double r = (h / N); const double x_k = r * r; int status = bsimp_step_local (state, dim, t_local, h, N, y_extrap_save, yp, dfdt, dfdy, y_extrap_sequence, sys); if (status == GSL_EFAILED) { /* If the local step fails, set the error to infinity in order to force a reduction in the step size */ for (i = 0; i < dim; i++) { yerr[i] = GSL_POSINF; } break; } else if (status != GSL_SUCCESS) { return status; } x[k] = x_k; poly_extrap (d, x, k, x_k, y_extrap_sequence, y, yerr, extrap_work, dim); } /* Evaluate dydt_out[]. */ if (dydt_out != NULL) { int s = GSL_ODEIV_FN_EVAL (sys, t + h, y, dydt_out); if (s != GSL_SUCCESS) { DBL_MEMCPY (y, y_save, dim); DBL_MEMCPY (yerr, yerr_save, dim); return s; } } return GSL_SUCCESS; } static unsigned int bsimp_order (void *vstate) { bsimp_state_t *state = (bsimp_state_t *) vstate; return state->order; } static int bsimp_reset (void *vstate, size_t dim) { bsimp_state_t *state = (bsimp_state_t *) vstate; state->h_next = 0; DBL_ZERO_MEMSET (state->yp, dim); return GSL_SUCCESS; } static void bsimp_free (void * vstate) { bsimp_state_t *state = (bsimp_state_t *) vstate; free (state->delta); free (state->rhs_temp); gsl_matrix_free (state->dfdy); free (state->weight); free (state->delta_temp); free (state->y_temp); free (state->dfdt); free (state->extrap_work); free (state->y_extrap_sequence); free (state->y_extrap_save); free (state->y_save); free (state->yerr_save); free (state->yp); gsl_permutation_free (state->p_vec); gsl_matrix_free (state->a_mat); gsl_matrix_free (state->d); free (state); } static const gsl_odeiv_step_type bsimp_type = { "bsimp", /* name */ 1, /* can use dydt_in */ 1, /* gives exact dydt_out */ &bsimp_alloc, &bsimp_apply, &bsimp_reset, &bsimp_order, &bsimp_free }; const gsl_odeiv_step_type *gsl_odeiv_step_bsimp = &bsimp_type; praat-6.0.04/external/gsl/gsl_ode-initval__control.c000066400000000000000000000042611261542461700224550ustar00rootroot00000000000000/* ode-initval/control.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_odeiv.h" gsl_odeiv_control * gsl_odeiv_control_alloc(const gsl_odeiv_control_type * T) { gsl_odeiv_control * c = (gsl_odeiv_control *) malloc(sizeof(gsl_odeiv_control)); if(c == 0) { GSL_ERROR_NULL ("failed to allocate space for control struct", GSL_ENOMEM); }; c->type = T; c->state = c->type->alloc(); if (c->state == 0) { free (c); /* exception in constructor, avoid memory leak */ GSL_ERROR_NULL ("failed to allocate space for control state", GSL_ENOMEM); }; return c; } int gsl_odeiv_control_init(gsl_odeiv_control * c, double eps_abs, double eps_rel, double a_y, double a_dydt) { return c->type->init (c->state, eps_abs, eps_rel, a_y, a_dydt); } void gsl_odeiv_control_free(gsl_odeiv_control * c) { c->type->free(c->state); free(c); } const char * gsl_odeiv_control_name(const gsl_odeiv_control * c) { return c->type->name; } int gsl_odeiv_control_hadjust (gsl_odeiv_control * c, gsl_odeiv_step * s, const double y[], const double yerr[], const double dydt[], double * h) { return c->type->hadjust(c->state, s->dimension, s->type->order(s->state), y, yerr, dydt, h); } praat-6.0.04/external/gsl/gsl_ode-initval__cscal.c000066400000000000000000000111501261542461700220550ustar00rootroot00000000000000/* ode-initval/cscal.c * * Copyright (C) 2002, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include #include "gsl_errno.h" #include "gsl_math.h" #include "gsl_odeiv.h" typedef struct { double eps_abs; double eps_rel; double a_y; double a_dydt; double * scale_abs; } sc_control_state_t; static void * sc_control_alloc (void) { sc_control_state_t * s = (sc_control_state_t *) malloc (sizeof(sc_control_state_t)); if (s == 0) { GSL_ERROR_NULL ("failed to allocate space for sc_control_state", GSL_ENOMEM); } return s; } static int sc_control_init (void * vstate, double eps_abs, double eps_rel, double a_y, double a_dydt) { sc_control_state_t * s = (sc_control_state_t *) vstate; if (eps_abs < 0) { GSL_ERROR ("eps_abs is negative", GSL_EINVAL); } else if (eps_rel < 0) { GSL_ERROR ("eps_rel is negative", GSL_EINVAL); } else if (a_y < 0) { GSL_ERROR ("a_y is negative", GSL_EINVAL); } else if (a_dydt < 0) { GSL_ERROR ("a_dydt is negative", GSL_EINVAL); } s->eps_rel = eps_rel; s->eps_abs = eps_abs; s->a_y = a_y; s->a_dydt = a_dydt; return GSL_SUCCESS; } static int sc_control_hadjust(void * vstate, size_t dim, unsigned int ord, const double y[], const double yerr[], const double yp[], double * h) { sc_control_state_t *state = (sc_control_state_t *) vstate; const double eps_abs = state->eps_abs; const double eps_rel = state->eps_rel; const double a_y = state->a_y; const double a_dydt = state->a_dydt; const double * scale_abs = state->scale_abs; const double S = 0.9; const double h_old = *h; double rmax = DBL_MIN; size_t i; for(i=0; i 1.1) { /* decrease step, no more than factor of 5, but a fraction S more than scaling suggests (for better accuracy) */ double r = S / pow(rmax, 1.0/ord); if (r < 0.2) r = 0.2; *h = r * h_old; return GSL_ODEIV_HADJ_DEC; } else if(rmax < 0.5) { /* increase step, no more than factor of 5 */ double r = S / pow(rmax, 1.0/(ord+1.0)); if (r > 5.0) r = 5.0; if (r < 1.0) /* don't allow any decrease caused by S<1 */ r = 1.0; *h = r * h_old; return GSL_ODEIV_HADJ_INC; } else { /* no change */ return GSL_ODEIV_HADJ_NIL; } } static void sc_control_free (void * vstate) { sc_control_state_t *state = (sc_control_state_t *) vstate; free (state->scale_abs); free (state); } static const gsl_odeiv_control_type sc_control_type = {"scaled", /* name */ &sc_control_alloc, &sc_control_init, &sc_control_hadjust, &sc_control_free}; const gsl_odeiv_control_type *gsl_odeiv_control_scaled = &sc_control_type; gsl_odeiv_control * gsl_odeiv_control_scaled_new(double eps_abs, double eps_rel, double a_y, double a_dydt, const double scale_abs[], size_t dim) { gsl_odeiv_control * c = gsl_odeiv_control_alloc (gsl_odeiv_control_scaled); int status = gsl_odeiv_control_init (c, eps_abs, eps_rel, a_y, a_dydt); if (status != GSL_SUCCESS) { gsl_odeiv_control_free (c); GSL_ERROR_NULL ("error trying to initialize control", status); } { sc_control_state_t * s = (sc_control_state_t *) c->state; s->scale_abs = (double *)malloc(dim * sizeof(double)); if (s->scale_abs == 0) { free (s); GSL_ERROR_NULL ("failed to allocate space for scale_abs", GSL_ENOMEM); } memcpy(s->scale_abs, scale_abs, dim * sizeof(double)); } return c; } praat-6.0.04/external/gsl/gsl_ode-initval__cstd.c000066400000000000000000000105601261542461700217310ustar00rootroot00000000000000/* ode-initval/cstd.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_errno.h" #include "gsl_math.h" #include "gsl_odeiv.h" typedef struct { double eps_abs; double eps_rel; double a_y; double a_dydt; } std_control_state_t; static void * std_control_alloc (void) { std_control_state_t * s = (std_control_state_t *) malloc (sizeof(std_control_state_t)); if (s == 0) { GSL_ERROR_NULL ("failed to allocate space for std_control_state", GSL_ENOMEM); } return s; } static int std_control_init (void * vstate, double eps_abs, double eps_rel, double a_y, double a_dydt) { std_control_state_t * s = (std_control_state_t *) vstate; if (eps_abs < 0) { GSL_ERROR ("eps_abs is negative", GSL_EINVAL); } else if (eps_rel < 0) { GSL_ERROR ("eps_rel is negative", GSL_EINVAL); } else if (a_y < 0) { GSL_ERROR ("a_y is negative", GSL_EINVAL); } else if (a_dydt < 0) { GSL_ERROR ("a_dydt is negative", GSL_EINVAL); } s->eps_rel = eps_rel; s->eps_abs = eps_abs; s->a_y = a_y; s->a_dydt = a_dydt; return GSL_SUCCESS; } static int std_control_hadjust(void * vstate, size_t dim, unsigned int ord, const double y[], const double yerr[], const double yp[], double * h) { std_control_state_t *state = (std_control_state_t *) vstate; const double eps_abs = state->eps_abs; const double eps_rel = state->eps_rel; const double a_y = state->a_y; const double a_dydt = state->a_dydt; const double S = 0.9; const double h_old = *h; double rmax = DBL_MIN; size_t i; for(i=0; i 1.1) { /* decrease step, no more than factor of 5, but a fraction S more than scaling suggests (for better accuracy) */ double r = S / pow(rmax, 1.0/ord); if (r < 0.2) r = 0.2; *h = r * h_old; return GSL_ODEIV_HADJ_DEC; } else if(rmax < 0.5) { /* increase step, no more than factor of 5 */ double r = S / pow(rmax, 1.0/(ord+1.0)); if (r > 5.0) r = 5.0; if (r < 1.0) /* don't allow any decrease caused by S<1 */ r = 1.0; *h = r * h_old; return GSL_ODEIV_HADJ_INC; } else { /* no change */ return GSL_ODEIV_HADJ_NIL; } } static void std_control_free (void * vstate) { std_control_state_t *state = (std_control_state_t *) vstate; free (state); } static const gsl_odeiv_control_type std_control_type = {"standard", /* name */ &std_control_alloc, &std_control_init, &std_control_hadjust, &std_control_free}; const gsl_odeiv_control_type *gsl_odeiv_control_standard = &std_control_type; gsl_odeiv_control * gsl_odeiv_control_standard_new(double eps_abs, double eps_rel, double a_y, double a_dydt) { gsl_odeiv_control * c = gsl_odeiv_control_alloc (gsl_odeiv_control_standard); int status = gsl_odeiv_control_init (c, eps_abs, eps_rel, a_y, a_dydt); if (status != GSL_SUCCESS) { gsl_odeiv_control_free (c); GSL_ERROR_NULL ("error trying to initialize control", status); } return c; } gsl_odeiv_control * gsl_odeiv_control_y_new(double eps_abs, double eps_rel) { return gsl_odeiv_control_standard_new(eps_abs, eps_rel, 1.0, 0.0); } gsl_odeiv_control * gsl_odeiv_control_yp_new(double eps_abs, double eps_rel) { return gsl_odeiv_control_standard_new(eps_abs, eps_rel, 0.0, 1.0); } praat-6.0.04/external/gsl/gsl_ode-initval__evolve.c000066400000000000000000000116161261542461700222770ustar00rootroot00000000000000/* ode-initval/evolve.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_odeiv.h" #include "gsl_ode-initval__odeiv_util.h" gsl_odeiv_evolve * gsl_odeiv_evolve_alloc (size_t dim) { gsl_odeiv_evolve *e = (gsl_odeiv_evolve *) malloc (sizeof (gsl_odeiv_evolve)); if (e == 0) { GSL_ERROR_NULL ("failed to allocate space for evolve struct", GSL_ENOMEM); } e->y0 = (double *) malloc (dim * sizeof (double)); if (e->y0 == 0) { free (e); GSL_ERROR_NULL ("failed to allocate space for y0", GSL_ENOMEM); } e->yerr = (double *) malloc (dim * sizeof (double)); if (e->yerr == 0) { free (e->y0); free (e); GSL_ERROR_NULL ("failed to allocate space for yerr", GSL_ENOMEM); } e->dydt_in = (double *) malloc (dim * sizeof (double)); if (e->dydt_in == 0) { free (e->yerr); free (e->y0); free (e); GSL_ERROR_NULL ("failed to allocate space for dydt_in", GSL_ENOMEM); } e->dydt_out = (double *) malloc (dim * sizeof (double)); if (e->dydt_out == 0) { free (e->dydt_in); free (e->yerr); free (e->y0); free (e); GSL_ERROR_NULL ("failed to allocate space for dydt_out", GSL_ENOMEM); } e->dimension = dim; e->count = 0; e->failed_steps = 0; e->last_step = 0.0; return e; } int gsl_odeiv_evolve_reset (gsl_odeiv_evolve * e) { e->count = 0; e->failed_steps = 0; e->last_step = 0.0; return GSL_SUCCESS; } void gsl_odeiv_evolve_free (gsl_odeiv_evolve * e) { free (e->dydt_out); free (e->dydt_in); free (e->yerr); free (e->y0); free (e); } /* Evolution framework method. * * Uses an adaptive step control object */ int gsl_odeiv_evolve_apply (gsl_odeiv_evolve * e, gsl_odeiv_control * con, gsl_odeiv_step * step, const gsl_odeiv_system * dydt, double *t, double t1, double *h, double y[]) { const double t0 = *t; double h0 = *h; int step_status; int final_step = 0; double dt = t1 - t0; /* remaining time, possibly less than h */ if (e->dimension != step->dimension) { GSL_ERROR ("step dimension must match evolution size", GSL_EINVAL); } if ((dt < 0.0 && h0 > 0.0) || (dt > 0.0 && h0 < 0.0)) { GSL_ERROR ("step direction must match interval direction", GSL_EINVAL); } /* No need to copy if we cannot control the step size. */ if (con != NULL) { DBL_MEMCPY (e->y0, y, e->dimension); } /* Calculate initial dydt once if the method can benefit. */ if (step->type->can_use_dydt_in) { int status = GSL_ODEIV_FN_EVAL (dydt, t0, y, e->dydt_in); if (status) { return status; } } try_step: if ((dt >= 0.0 && h0 > dt) || (dt < 0.0 && h0 < dt)) { h0 = dt; final_step = 1; } else { final_step = 0; } if (step->type->can_use_dydt_in) { step_status = gsl_odeiv_step_apply (step, t0, h0, y, e->yerr, e->dydt_in, e->dydt_out, dydt); } else { step_status = gsl_odeiv_step_apply (step, t0, h0, y, e->yerr, NULL, e->dydt_out, dydt); } /* Check for stepper internal failure */ if (step_status != GSL_SUCCESS) { *h = h0; /* notify user of step-size which caused the failure */ return step_status; } e->count++; e->last_step = h0; if (final_step) { *t = t1; } else { *t = t0 + h0; } if (con != NULL) { /* Check error and attempt to adjust the step. */ const int hadjust_status = gsl_odeiv_control_hadjust (con, step, y, e->yerr, e->dydt_out, &h0); if (hadjust_status == GSL_ODEIV_HADJ_DEC) { /* Step was decreased. Undo and go back to try again. */ DBL_MEMCPY (y, e->y0, dydt->dimension); e->failed_steps++; goto try_step; } } *h = h0; /* suggest step size for next time-step */ return step_status; } praat-6.0.04/external/gsl/gsl_ode-initval__gear1.c000066400000000000000000000140531261542461700217740ustar00rootroot00000000000000/* ode-initval/gear1.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Gear 1. This is the implicit Euler a.k.a backward Euler method. */ /* Author: G. Jungman */ /* Error estimation by step doubling, see eg. Ascher, U.M., Petzold, L.R., Computer methods for ordinary differential and differential-algebraic equations, SIAM, Philadelphia, 1998. The method is also described in eg. this reference. */ #include "gsl__config.h" #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_odeiv.h" #include "gsl_ode-initval__odeiv_util.h" typedef struct { double *k; double *y0; double *y0_orig; double *y_onestep; } gear1_state_t; static void * gear1_alloc (size_t dim) { gear1_state_t *state = (gear1_state_t *) malloc (sizeof (gear1_state_t)); if (state == 0) { GSL_ERROR_NULL ("failed to allocate space for gear1_state", GSL_ENOMEM); } state->k = (double *) malloc (dim * sizeof (double)); if (state->k == 0) { free (state); GSL_ERROR_NULL ("failed to allocate space for k", GSL_ENOMEM); } state->y0 = (double *) malloc (dim * sizeof (double)); if (state->y0 == 0) { free (state->k); free (state); GSL_ERROR_NULL ("failed to allocate space for y0", GSL_ENOMEM); } state->y0_orig = (double *) malloc (dim * sizeof (double)); if (state->y0_orig == 0) { free (state->y0); free (state->k); free (state); GSL_ERROR_NULL ("failed to allocate space for y0_orig", GSL_ENOMEM); } state->y_onestep = (double *) malloc (dim * sizeof (double)); if (state->y_onestep == 0) { free (state->y0_orig); free (state->y0); free (state->k); free (state); GSL_ERROR_NULL ("failed to allocate space for y_onestep", GSL_ENOMEM); } return state; } static int gear1_step (double *y, gear1_state_t *state, const double h, const double t, const size_t dim, const gsl_odeiv_system *sys) { /* Makes an implicit Euler advance with step size h. y0 is the initial values of variables y. The implicit matrix equations to solve are: k = y0 + h * f(t + h, k) y = y0 + h * f(t + h, k) */ const int iter_steps = 3; int nu; size_t i; double *y0 = state->y0; double *k = state->k; /* Iterative solution of k = y0 + h * f(t + h, k) Note: This method does not check for convergence of the iterative solution! */ for (nu = 0; nu < iter_steps; nu++) { int s = GSL_ODEIV_FN_EVAL(sys, t + h, y, k); if (s != GSL_SUCCESS) { return s; } for (i=0; iy0; double *y0_orig = state->y0_orig; double *y_onestep = state->y_onestep; /* initialization */ DBL_MEMCPY(y0, y, dim); /* Save initial values for possible failures */ DBL_MEMCPY (y0_orig, y, dim); /* First traverse h with one step (save to y_onestep) */ DBL_MEMCPY (y_onestep, y, dim); { int s = gear1_step (y_onestep, state, h, t, dim, sys); if (s != GSL_SUCCESS) { return s; } } /* Then with two steps with half step length (save to y) */ { int s = gear1_step (y, state, h / 2.0, t, dim, sys); if (s != GSL_SUCCESS) { /* Restore original y vector */ DBL_MEMCPY (y, y0_orig, dim); return s; } } DBL_MEMCPY (y0, y, dim); { int s = gear1_step (y, state, h / 2.0, t + h / 2.0, dim, sys); if (s != GSL_SUCCESS) { /* Restore original y vector */ DBL_MEMCPY (y, y0_orig, dim); return s; } } /* Cleanup update */ if (dydt_out != NULL) { int s = GSL_ODEIV_FN_EVAL (sys, t + h, y, dydt_out); if (s != GSL_SUCCESS) { /* Restore original y vector */ DBL_MEMCPY (y, y0_orig, dim); return s; } } /* Error estimation */ for (i = 0; i < dim; i++) { yerr[i] = 4.0 * (y[i] - y_onestep[i]); } return GSL_SUCCESS; } static int gear1_reset (void *vstate, size_t dim) { gear1_state_t *state = (gear1_state_t *) vstate; DBL_ZERO_MEMSET (state->y_onestep, dim); DBL_ZERO_MEMSET (state->y0_orig, dim); DBL_ZERO_MEMSET (state->y0, dim); DBL_ZERO_MEMSET (state->k, dim); return GSL_SUCCESS; } static unsigned int gear1_order (void *vstate) { gear1_state_t *state = (gear1_state_t *) vstate; state = 0; /* prevent warnings about unused parameters */ return 1; } static void gear1_free (void *vstate) { gear1_state_t *state = (gear1_state_t *) vstate; free (state->y_onestep); free (state->y0_orig); free (state->y0); free (state->k); free (state); } static const gsl_odeiv_step_type gear1_type = { "gear1", /* name */ 0, /* can use dydt_in? */ 1, /* gives exact dydt_out? */ &gear1_alloc, &gear1_apply, &gear1_reset, &gear1_order, &gear1_free }; const gsl_odeiv_step_type *gsl_odeiv_step_gear1 = &gear1_type; praat-6.0.04/external/gsl/gsl_ode-initval__gear2.c000066400000000000000000000205031261542461700217720ustar00rootroot00000000000000/* ode-initval/gear2.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Gear 2 */ /* Author: G. Jungman */ #include "gsl__config.h" #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_ode-initval__odeiv_util.h" #include "gsl_odeiv.h" /* gear2 state object */ typedef struct { int primed; /* flag indicating that yim1 is ready */ double t_primed; /* system was primed for this value of t */ double last_h; /* last step size */ gsl_odeiv_step *primer; /* stepper to use for priming */ double *yim1; /* y_{i-1} */ double *k; /* work space */ double *y0; /* work space */ double *y0_orig; double *y_onestep; int stutter; } gear2_state_t; static void * gear2_alloc (size_t dim) { gear2_state_t *state = (gear2_state_t *) malloc (sizeof (gear2_state_t)); if (state == 0) { GSL_ERROR_NULL ("failed to allocate space for gear2_state", GSL_ENOMEM); } state->yim1 = (double *) malloc (dim * sizeof (double)); if (state->yim1 == 0) { free (state); GSL_ERROR_NULL ("failed to allocate space for yim1", GSL_ENOMEM); } state->k = (double *) malloc (dim * sizeof (double)); if (state->k == 0) { free (state->yim1); free (state); GSL_ERROR_NULL ("failed to allocate space for k", GSL_ENOMEM); } state->y0 = (double *) malloc (dim * sizeof (double)); if (state->y0 == 0) { free (state->k); free (state->yim1); free (state); GSL_ERROR_NULL ("failed to allocate space for y0", GSL_ENOMEM); } state->y0_orig = (double *) malloc (dim * sizeof (double)); if (state->y0_orig == 0) { free (state->y0); free (state->k); free (state->yim1); free (state); GSL_ERROR_NULL ("failed to allocate space for y0_orig", GSL_ENOMEM); } state->y_onestep = (double *) malloc (dim * sizeof (double)); if (state->y_onestep == 0) { free (state->y0_orig); free (state->y0); free (state->k); free (state->yim1); free (state); GSL_ERROR_NULL ("failed to allocate space for y0_orig", GSL_ENOMEM); } state->primed = 0; state->primer = gsl_odeiv_step_alloc (gsl_odeiv_step_rk4imp, dim); if (state->primer == 0) { free (state->y_onestep); free (state->y0_orig); free (state->y0); free (state->k); free (state->yim1); free (state); GSL_ERROR_NULL ("failed to allocate space for primer", GSL_ENOMEM); } state->last_h = 0.0; return state; } static int gear2_step (double *y, gear2_state_t * state, const double h, const double t, const size_t dim, const gsl_odeiv_system * sys) { /* Makes a Gear2 advance with step size h. y0 is the initial values of variables y. The implicit matrix equations to solve are: k = y0 + h * f(t + h, k) y = y0 + h * f(t + h, k) */ const int iter_steps = 3; int nu; size_t i; double *y0 = state->y0; double *yim1 = state->yim1; double *k = state->k; /* Iterative solution of k = y0 + h * f(t + h, k) Note: This method does not check for convergence of the iterative solution! */ for (nu = 0; nu < iter_steps; nu++) { int s = GSL_ODEIV_FN_EVAL (sys, t + h, y, k); if (s != GSL_SUCCESS) { return s; } for (i = 0; i < dim; i++) { y[i] = ((4.0 * y0[i] - yim1[i]) + 2.0 * h * k[i]) / 3.0; } } return GSL_SUCCESS; } static int gear2_apply (void *vstate, size_t dim, double t, double h, double y[], double yerr[], const double dydt_in[], double dydt_out[], const gsl_odeiv_system * sys) { gear2_state_t *state = (gear2_state_t *) vstate; state->stutter = 0; if (state->primed == 0 || t == state->t_primed || h != state->last_h) { /* Execute a single-step method to prime the process. Note that * we do this if the step size changes, so frequent step size * changes will cause the method to stutter. * * Note that we reuse this method if the time has not changed, * which can occur when the adaptive driver is attempting to find * an appropriate step-size on its first iteration */ int status; DBL_MEMCPY (state->yim1, y, dim); status = gsl_odeiv_step_apply (state->primer, t, h, y, yerr, dydt_in, dydt_out, sys); /* Make note of step size and indicate readiness for a Gear step. */ state->primed = 1; state->t_primed = t; state->last_h = h; state->stutter = 1; return status; } else { /* We have a previous y value in the buffer, and the step * sizes match, so we go ahead with the Gear step. */ double *const k = state->k; double *const y0 = state->y0; double *const y0_orig = state->y0_orig; double *const yim1 = state->yim1; double *y_onestep = state->y_onestep; int s; size_t i; DBL_MEMCPY (y0, y, dim); /* iterative solution */ if (dydt_out != NULL) { DBL_MEMCPY (k, dydt_out, dim); } /* First traverse h with one step (save to y_onestep) */ DBL_MEMCPY (y_onestep, y, dim); s = gear2_step (y_onestep, state, h, t, dim, sys); if (s != GSL_SUCCESS) { return s; } /* Then with two steps with half step length (save to y) */ s = gear2_step (y, state, h / 2.0, t, dim, sys); if (s != GSL_SUCCESS) { /* Restore original y vector */ DBL_MEMCPY (y, y0_orig, dim); return s; } DBL_MEMCPY (y0, y, dim); s = gear2_step (y, state, h / 2.0, t + h / 2.0, dim, sys); if (s != GSL_SUCCESS) { /* Restore original y vector */ DBL_MEMCPY (y, y0_orig, dim); return s; } /* Cleanup update */ if (dydt_out != NULL) { s = GSL_ODEIV_FN_EVAL (sys, t + h, y, dydt_out); if (s != GSL_SUCCESS) { /* Restore original y vector */ DBL_MEMCPY (y, y0_orig, dim); return s; } } /* Estimate error and update the state buffer. */ for (i = 0; i < dim; i++) { yerr[i] = 4.0 * (y[i] - y_onestep[i]); yim1[i] = y0[i]; } /* Make note of step size. */ state->last_h = h; return 0; } } static int gear2_reset (void *vstate, size_t dim) { gear2_state_t *state = (gear2_state_t *) vstate; DBL_ZERO_MEMSET (state->yim1, dim); DBL_ZERO_MEMSET (state->k, dim); DBL_ZERO_MEMSET (state->y0, dim); state->primed = 0; state->last_h = 0.0; return GSL_SUCCESS; } static unsigned int gear2_order (void *vstate) { gear2_state_t *state = (gear2_state_t *) vstate; state = 0; /* prevent warnings about unused parameters */ return 3; } static void gear2_free (void *vstate) { gear2_state_t *state = (gear2_state_t *) vstate; free (state->yim1); free (state->k); free (state->y0); free (state->y0_orig); free (state->y_onestep); gsl_odeiv_step_free (state->primer); free (state); } static const gsl_odeiv_step_type gear2_type = { "gear2", /* name */ 1, /* can use dydt_in */ 0, /* gives exact dydt_out */ &gear2_alloc, &gear2_apply, &gear2_reset, &gear2_order, &gear2_free }; const gsl_odeiv_step_type *gsl_odeiv_step_gear2 = &gear2_type; praat-6.0.04/external/gsl/gsl_ode-initval__odeiv_util.h000066400000000000000000000002131261542461700231360ustar00rootroot00000000000000#define DBL_MEMCPY(dest,src,n) memcpy((dest),(src),(n)*sizeof(double)) #define DBL_ZERO_MEMSET(dest,n) memset((dest),0,(n)*sizeof(double)) praat-6.0.04/external/gsl/gsl_ode-initval__rk2.c000066400000000000000000000122001261542461700214630ustar00rootroot00000000000000/* ode-initval/rk2.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Runge-Kutta 2(3), Euler-Cauchy */ /* Author: G. Jungman */ /* Reference: Abramowitz & Stegun, section 25.5. Runge-Kutta 2nd (25.5.7) and 3rd (25.5.8) order methods */ #include "gsl__config.h" #include #include #include "gsl_errno.h" #include "gsl_odeiv.h" #include "gsl_ode-initval__odeiv_util.h" typedef struct { double *k1; double *k2; double *k3; double *ytmp; } rk2_state_t; static void * rk2_alloc (size_t dim) { rk2_state_t *state = (rk2_state_t *) malloc (sizeof (rk2_state_t)); if (state == 0) { GSL_ERROR_NULL ("failed to allocate space for rk2_state", GSL_ENOMEM); } state->k1 = (double *) malloc (dim * sizeof (double)); if (state->k1 == 0) { free (state); GSL_ERROR_NULL ("failed to allocate space for k1", GSL_ENOMEM); } state->k2 = (double *) malloc (dim * sizeof (double)); if (state->k2 == 0) { free (state->k1); free (state); GSL_ERROR_NULL ("failed to allocate space for k2", GSL_ENOMEM); } state->k3 = (double *) malloc (dim * sizeof (double)); if (state->k3 == 0) { free (state->k2); free (state->k1); free (state); GSL_ERROR_NULL ("failed to allocate space for k2", GSL_ENOMEM); } state->ytmp = (double *) malloc (dim * sizeof (double)); if (state->ytmp == 0) { free (state->k3); free (state->k2); free (state->k1); free (state); GSL_ERROR_NULL ("failed to allocate space for k2", GSL_ENOMEM); } return state; } static int rk2_apply (void *vstate, size_t dim, double t, double h, double y[], double yerr[], const double dydt_in[], double dydt_out[], const gsl_odeiv_system * sys) { rk2_state_t *state = (rk2_state_t *) vstate; size_t i; double *const k1 = state->k1; double *const k2 = state->k2; double *const k3 = state->k3; double *const ytmp = state->ytmp; /* k1 step */ /* k1 = f(t,y) */ if (dydt_in != NULL) { DBL_MEMCPY (k1, dydt_in, dim); } else { int s = GSL_ODEIV_FN_EVAL (sys, t, y, k1); if (s != GSL_SUCCESS) { return s; } } /* k2 step */ /* k2 = f(t + 0.5*h, y + 0.5*k1) */ for (i = 0; i < dim; i++) { ytmp[i] = y[i] + 0.5 * h * k1[i]; } { int s = GSL_ODEIV_FN_EVAL (sys, t + 0.5 * h, ytmp, k2); if (s != GSL_SUCCESS) { return s; } } /* k3 step */ /* for 3rd order estimates, is used for error estimation k3 = f(t + h, y - k1 + 2*k2) */ for (i = 0; i < dim; i++) { ytmp[i] = y[i] + h * (-k1[i] + 2.0 * k2[i]); } { int s = GSL_ODEIV_FN_EVAL (sys, t + h, ytmp, k3); if (s != GSL_SUCCESS) { return s; } } /* final sum */ for (i = 0; i < dim; i++) { /* Save original values if derivative evaluation below fails */ ytmp[i] = y[i]; { const double ksum3 = (k1[i] + 4.0 * k2[i] + k3[i]) / 6.0; y[i] += h * ksum3; } } /* Derivatives at output */ if (dydt_out != NULL) { int s = GSL_ODEIV_FN_EVAL (sys, t + h, y, dydt_out); if (s != GSL_SUCCESS) { /* Restore original values */ DBL_MEMCPY (y, ytmp, dim); return s; } } /* Error estimation */ for (i = 0; i < dim; i++) { const double ksum3 = (k1[i] + 4.0 * k2[i] + k3[i]) / 6.0; yerr[i] = h * (k2[i] - ksum3); } return GSL_SUCCESS; } static int rk2_reset (void *vstate, size_t dim) { rk2_state_t *state = (rk2_state_t *) vstate; DBL_ZERO_MEMSET (state->k1, dim); DBL_ZERO_MEMSET (state->k2, dim); DBL_ZERO_MEMSET (state->k3, dim); DBL_ZERO_MEMSET (state->ytmp, dim); return GSL_SUCCESS; } static unsigned int rk2_order (void *vstate) { rk2_state_t *state = (rk2_state_t *) vstate; state = 0; /* prevent warnings about unused parameters */ return 2; } static void rk2_free (void *vstate) { rk2_state_t *state = (rk2_state_t *) vstate; free (state->k1); free (state->k2); free (state->k3); free (state->ytmp); free (state); } static const gsl_odeiv_step_type rk2_type = { "rk2", /* name */ 1, /* can use dydt_in */ 1, /* gives exact dydt_out */ &rk2_alloc, &rk2_apply, &rk2_reset, &rk2_order, &rk2_free }; const gsl_odeiv_step_type *gsl_odeiv_step_rk2 = &rk2_type; praat-6.0.04/external/gsl/gsl_ode-initval__rk2imp.c000066400000000000000000000162021261542461700221770ustar00rootroot00000000000000/* ode-initval/rk2imp.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Runge-Kutta 2, Gaussian implicit. Also known as the implicit midpoint rule. */ /* Author: G. Jungman */ /* Error estimation by step doubling, see eg. Ascher, U.M., Petzold, L.R., Computer methods for ordinary differential and differential-algebraic equations, SIAM, Philadelphia, 1998. The method is also described in eg. this reference. */ #include "gsl__config.h" #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_odeiv.h" #include "gsl_ode-initval__odeiv_util.h" typedef struct { double *Y1; double *y0; double *ytmp; double *y_onestep; double *y0_orig; } rk2imp_state_t; static void * rk2imp_alloc (size_t dim) { rk2imp_state_t *state = (rk2imp_state_t *) malloc (sizeof (rk2imp_state_t)); if (state == 0) { GSL_ERROR_NULL ("failed to allocate space for rk2imp_state", GSL_ENOMEM); } state->Y1 = (double *) malloc (dim * sizeof (double)); if (state->Y1 == 0) { free (state); GSL_ERROR_NULL ("failed to allocate space for Y1", GSL_ENOMEM); } state->ytmp = (double *) malloc (dim * sizeof (double)); if (state->ytmp == 0) { free (state->Y1); free (state); GSL_ERROR_NULL ("failed to allocate space for ytmp", GSL_ENOMEM); } state->y0 = (double *) malloc (dim * sizeof (double)); if (state->y0 == 0) { free (state->Y1); free (state->ytmp); free (state); GSL_ERROR_NULL ("failed to allocate space for y0", GSL_ENOMEM); } state->y_onestep = (double *) malloc (dim * sizeof (double)); if (state->y_onestep == 0) { free (state->Y1); free (state->ytmp); free (state->y0); free (state); GSL_ERROR_NULL ("failed to allocate space for y_onestep", GSL_ENOMEM); } state->y0_orig = (double *) malloc (dim * sizeof (double)); if (state->y0_orig == 0) { free (state->y_onestep); free (state->Y1); free (state->ytmp); free (state->y0); free (state); GSL_ERROR_NULL ("failed to allocate space for y0_orig", GSL_ENOMEM); } return state; } static int rk2imp_step (double *y, rk2imp_state_t *state, const double h, const double t, const size_t dim, const gsl_odeiv_system *sys) { /* Makes a Runge-Kutta 2nd order implicit advance with step size h. y0 is initial values of variables y. The implicit matrix equations to solve are: Y1 = y0 + h/2 * f(t + h/2, Y1) y = y0 + h * f(t + h/2, Y1) */ const double *y0 = state->y0; double *Y1 = state->Y1; double *ytmp = state->ytmp; int max_iter=3; int nu; size_t i; /* iterative solution of Y1 = y0 + h/2 * f(t + h/2, Y1) Y1 should include initial values at call. Note: This method does not check for convergence of the iterative solution! */ for (nu = 0; nu < max_iter; nu++) { for (i = 0; i < dim; i++) { ytmp[i] = y0[i] + 0.5 * h * Y1[i]; } { int s = GSL_ODEIV_FN_EVAL (sys, t + 0.5 * h, ytmp, Y1); if (s != GSL_SUCCESS) { return s; } } } /* assignment */ for (i = 0; i < dim; i++) { y[i] = y0[i] + h * Y1[i]; } return GSL_SUCCESS; } static int rk2imp_apply (void *vstate, size_t dim, double t, double h, double y[], double yerr[], const double dydt_in[], double dydt_out[], const gsl_odeiv_system * sys) { rk2imp_state_t *state = (rk2imp_state_t *) vstate; size_t i; double *Y1 = state->Y1; double *y0 = state->y0; double *y_onestep = state->y_onestep; double *y0_orig = state->y0_orig; /* Error estimation is done by step doubling procedure */ /* initialization step */ DBL_MEMCPY (y0, y, dim); /* Save initial values for possible failures */ DBL_MEMCPY (y0_orig, y, dim); if (dydt_in != NULL) { DBL_MEMCPY (Y1, dydt_in, dim); } else { int s = GSL_ODEIV_FN_EVAL (sys, t, y, Y1); if (s != GSL_SUCCESS) { return s; } } /* First traverse h with one step (save to y_onestep) */ DBL_MEMCPY (y_onestep, y, dim); { int s = rk2imp_step (y_onestep, state, h, t, dim, sys); if (s != GSL_SUCCESS) { return s; } } /* Then with two steps with half step length (save to y) */ { int s = rk2imp_step (y, state, h / 2.0, t, dim, sys); if (s != GSL_SUCCESS) { /* Restore original y vector */ DBL_MEMCPY (y, y0_orig, dim); return s; } } DBL_MEMCPY (y0, y, dim); { int s = GSL_ODEIV_FN_EVAL (sys, t + h / 2.0, y, Y1); if (s != GSL_SUCCESS) { /* Restore original y vector */ DBL_MEMCPY (y, y0_orig, dim); return s; } } { int s = rk2imp_step (y, state, h / 2.0, t + h / 2.0, dim, sys); if (s != GSL_SUCCESS) { /* Restore original y vector */ DBL_MEMCPY (y, y0_orig, dim); return s; } } /* Derivatives at output */ if (dydt_out != NULL) { int s = GSL_ODEIV_FN_EVAL (sys, t + h, y, dydt_out); if (s != GSL_SUCCESS) { /* Restore original y vector */ DBL_MEMCPY (y, y0_orig, dim); return s; } } /* Error estimation */ for (i = 0; i < dim; i++) { yerr[i] = 4.0 * (y[i] - y_onestep[i]) / 3.0; } return GSL_SUCCESS; } static int rk2imp_reset (void *vstate, size_t dim) { rk2imp_state_t *state = (rk2imp_state_t *) vstate; DBL_ZERO_MEMSET (state->Y1, dim); DBL_ZERO_MEMSET (state->ytmp, dim); DBL_ZERO_MEMSET (state->y0, dim); DBL_ZERO_MEMSET (state->y_onestep, dim); DBL_ZERO_MEMSET (state->y0_orig, dim); return GSL_SUCCESS; } static unsigned int rk2imp_order (void *vstate) { rk2imp_state_t *state = (rk2imp_state_t *) vstate; state = 0; /* prevent warnings about unused parameters */ return 2; } static void rk2imp_free (void *vstate) { rk2imp_state_t *state = (rk2imp_state_t *) vstate; free (state->Y1); free (state->ytmp); free (state->y0); free (state->y_onestep); free (state->y0_orig); free (state); } static const gsl_odeiv_step_type rk2imp_type = { "rk2imp", /* name */ 1, /* can use dydt_in */ 1, /* gives exact dydt_out */ &rk2imp_alloc, &rk2imp_apply, &rk2imp_reset, &rk2imp_order, &rk2imp_free }; const gsl_odeiv_step_type *gsl_odeiv_step_rk2imp = &rk2imp_type; praat-6.0.04/external/gsl/gsl_ode-initval__rk2simp.c000066400000000000000000000216221261542461700223640ustar00rootroot00000000000000/* ode-initval/rk2simp.c * * Copyright (C) 2004 Tuomo Keskitalo * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Runge-Kutta 2, Gaussian implicit. Also known as implicit midpoint rule. Non-linear equations solved by linearization, LU-decomposition and matrix inversion. For reference, see eg. Ascher, U.M., Petzold, L.R., Computer methods for ordinary differential and differential-algebraic equations, SIAM, Philadelphia, 1998. */ #include "gsl__config.h" #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_odeiv.h" #include "gsl_linalg.h" #include "gsl_ode-initval__odeiv_util.h" typedef struct { double *Y1; double *y0; double *y0_orig; double *ytmp; double *dfdy; /* Jacobian */ double *dfdt; /* time derivatives, not used */ double *y_onestep; gsl_permutation *p; } rk2simp_state_t; static void * rk2simp_alloc (size_t dim) { rk2simp_state_t *state = (rk2simp_state_t *) malloc (sizeof (rk2simp_state_t)); if (state == 0) { GSL_ERROR_NULL ("failed to allocate space for rk2simp_state", GSL_ENOMEM); } state->Y1 = (double *) malloc (dim * sizeof (double)); if (state->Y1 == 0) { free (state); GSL_ERROR_NULL ("failed to allocate space for Y1", GSL_ENOMEM); } state->y0 = (double *) malloc (dim * sizeof (double)); if (state->y0 == 0) { free (state->Y1); free (state); GSL_ERROR_NULL ("failed to allocate space for y0", GSL_ENOMEM); } state->y0_orig = (double *) malloc (dim * sizeof (double)); if (state->y0_orig == 0) { free (state->Y1); free (state->y0); free (state); GSL_ERROR_NULL ("failed to allocate space for y0_orig", GSL_ENOMEM); } state->ytmp = (double *) malloc (dim * sizeof (double)); if (state->ytmp == 0) { free (state->Y1); free (state->y0); free (state->y0_orig); free (state); GSL_ERROR_NULL ("failed to allocate space for ytmp", GSL_ENOMEM); } state->dfdy = (double *) malloc (dim * dim * sizeof (double)); if (state->dfdy == 0) { free (state->Y1); free (state->y0); free (state->y0_orig); free (state->ytmp); free (state); GSL_ERROR_NULL ("failed to allocate space for dfdy", GSL_ENOMEM); } state->dfdt = (double *) malloc (dim * sizeof (double)); if (state->dfdt == 0) { free (state->Y1); free (state->y0); free (state->y0_orig); free (state->ytmp); free (state->dfdy); free (state); GSL_ERROR_NULL ("failed to allocate space for dfdt", GSL_ENOMEM); } state->y_onestep = (double *) malloc (dim * sizeof (double)); if (state->y_onestep == 0) { free (state->Y1); free (state->y0); free (state->y0_orig); free (state->ytmp); free (state->dfdy); free (state->dfdt); free (state); GSL_ERROR_NULL ("failed to allocate space for y_onestep", GSL_ENOMEM); } state->p = gsl_permutation_alloc (dim); if (state->p == 0) { free (state->Y1); free (state->y0); free (state->y0_orig); free (state->ytmp); free (state->dfdy); free (state->dfdt); free (state); GSL_ERROR_NULL ("failed to allocate space for p", GSL_ENOMEM); } return state; } static int rk2simp_step (double *y, rk2simp_state_t * state, const double h, const double t, const size_t dim, const gsl_odeiv_system * sys) { /* Makes a Runge-Kutta 2nd order semi-implicit advance with step size h. y0 is initial values of variables y. The linearized semi-implicit equations to calculate are: Y1 = y0 + h/2 * (1 - h/2 * df/dy)^(-1) * f(t + h/2, y0) y = y0 + h * f(t + h/2, Y1) */ const double *y0 = state->y0; double *Y1 = state->Y1; double *ytmp = state->ytmp; size_t i; int s, ps; gsl_matrix_view J = gsl_matrix_view_array (state->dfdy, dim, dim); /* First solve Y1. Calculate the inverse matrix (1 - h/2 * df/dy)^-1 */ /* Create matrix to J */ s = GSL_ODEIV_JA_EVAL (sys, t, y0, state->dfdy, state->dfdt); if (s != GSL_SUCCESS) { return s; } gsl_matrix_scale (&J.matrix, -h / 2.0); gsl_matrix_add_diagonal(&J.matrix, 1.0); /* Invert it by LU-decomposition to invmat */ s += gsl_linalg_LU_decomp (&J.matrix, state->p, &ps); if (s != GSL_SUCCESS) { return GSL_EFAILED; } /* Evaluate f(t + h/2, y0) */ s = GSL_ODEIV_FN_EVAL (sys, t + 0.5 * h, y0, ytmp); if (s != GSL_SUCCESS) { return s; } /* Calculate Y1 = y0 + h/2 * ((1-h/2 * df/dy)^-1) ytmp */ { gsl_vector_const_view y0_view = gsl_vector_const_view_array(y0, dim); gsl_vector_view ytmp_view = gsl_vector_view_array(ytmp, dim); gsl_vector_view Y1_view = gsl_vector_view_array(Y1, dim); s = gsl_linalg_LU_solve (&J.matrix, state->p, &ytmp_view.vector, &Y1_view.vector); gsl_vector_scale (&Y1_view.vector, 0.5 * h); gsl_vector_add (&Y1_view.vector, &y0_view.vector); } /* And finally evaluation of f(t + h/2, Y1) and calculation of y */ s = GSL_ODEIV_FN_EVAL (sys, t + 0.5 * h, Y1, ytmp); if (s != GSL_SUCCESS) { return s; } for (i = 0; i < dim; i++) { y[i] = y0[i] + h * ytmp[i]; } return s; } static int rk2simp_apply (void *vstate, size_t dim, double t, double h, double y[], double yerr[], const double dydt_in[], double dydt_out[], const gsl_odeiv_system * sys) { rk2simp_state_t *state = (rk2simp_state_t *) vstate; size_t i; double *y0 = state->y0; double *y0_orig = state->y0_orig; double *y_onestep = state->y_onestep; /* Error estimation is done by step doubling procedure */ DBL_MEMCPY (y0, y, dim); /* Save initial values in case of failure */ DBL_MEMCPY (y0_orig, y, dim); /* First traverse h with one step (save to y_onestep) */ DBL_MEMCPY (y_onestep, y, dim); { int s = rk2simp_step (y_onestep, state, h, t, dim, sys); if (s != GSL_SUCCESS) { return s; } } /* Then with two steps with half step length (save to y) */ { int s = rk2simp_step (y, state, h / 2.0, t, dim, sys); if (s != GSL_SUCCESS) { /* Restore original y vector */ DBL_MEMCPY (y, y0_orig, dim); return s; } } DBL_MEMCPY (y0, y, dim); { int s = rk2simp_step (y, state, h / 2.0, t + h / 2.0, dim, sys); if (s != GSL_SUCCESS) { /* Restore original y vector */ DBL_MEMCPY (y, y0_orig, dim); return s; } } /* Derivatives at output */ if (dydt_out != NULL) { int s = GSL_ODEIV_FN_EVAL (sys, t + h, y, dydt_out); if (s != GSL_SUCCESS) { /* Restore original y vector */ DBL_MEMCPY (y, y0_orig, dim); return s; } } /* Error estimation */ for (i = 0; i < dim; i++) { yerr[i] = 4.0 * (y[i] - y_onestep[i]) / 3.0; } return GSL_SUCCESS; } static int rk2simp_reset (void *vstate, size_t dim) { rk2simp_state_t *state = (rk2simp_state_t *) vstate; DBL_ZERO_MEMSET (state->Y1, dim); DBL_ZERO_MEMSET (state->y0, dim); DBL_ZERO_MEMSET (state->y0_orig, dim); DBL_ZERO_MEMSET (state->ytmp, dim); DBL_ZERO_MEMSET (state->dfdt, dim * dim); DBL_ZERO_MEMSET (state->dfdt, dim); DBL_ZERO_MEMSET (state->y_onestep, dim); return GSL_SUCCESS; } static unsigned int rk2simp_order (void *vstate) { rk2simp_state_t *state = (rk2simp_state_t *) vstate; state = 0; /* prevent warnings about unused parameters */ return 2; } static void rk2simp_free (void *vstate) { rk2simp_state_t *state = (rk2simp_state_t *) vstate; free (state->Y1); free (state->y0); free (state->y0_orig); free (state->ytmp); free (state->dfdy); free (state->dfdt); free (state->y_onestep); gsl_permutation_free (state->p); free (state); } static const gsl_odeiv_step_type rk2simp_type = { "rk2simp", /* name */ 0, /* can use dydt_in? */ 1, /* gives exact dydt_out? */ &rk2simp_alloc, &rk2simp_apply, &rk2simp_reset, &rk2simp_order, &rk2simp_free }; const gsl_odeiv_step_type *gsl_odeiv_step_rk2simp = &rk2simp_type; praat-6.0.04/external/gsl/gsl_ode-initval__rk4.c000066400000000000000000000166131261542461700215010ustar00rootroot00000000000000/* ode-initval/rk4.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Runge-Kutta 4th order, Classical */ /* Author: G. Jungman */ /* Reference: Abramowitz & Stegun, section 25.5. equation 25.5.10 Error estimation by step doubling, see eg. Ascher, U.M., Petzold, L.R., Computer methods for ordinary differential and differential-algebraic equations, SIAM, Philadelphia, 1998. */ #include "gsl__config.h" #include #include #include "gsl_errno.h" #include "gsl_odeiv.h" #include "gsl_ode-initval__odeiv_util.h" typedef struct { double *k; double *k1; double *y0; double *ytmp; double *y_onestep; } rk4_state_t; static void * rk4_alloc (size_t dim) { rk4_state_t *state = (rk4_state_t *) malloc (sizeof (rk4_state_t)); if (state == 0) { GSL_ERROR_NULL ("failed to allocate space for rk4_state", GSL_ENOMEM); } state->k = (double *) malloc (dim * sizeof (double)); if (state->k == 0) { free (state); GSL_ERROR_NULL ("failed to allocate space for k", GSL_ENOMEM); } state->k1 = (double *) malloc (dim * sizeof (double)); if (state->k1 == 0) { free (state); free (state->k); GSL_ERROR_NULL ("failed to allocate space for k1", GSL_ENOMEM); } state->y0 = (double *) malloc (dim * sizeof (double)); if (state->y0 == 0) { free (state->k); free (state->k1); free (state); GSL_ERROR_NULL ("failed to allocate space for y0", GSL_ENOMEM); } state->ytmp = (double *) malloc (dim * sizeof (double)); if (state->ytmp == 0) { free (state->y0); free (state->k); free (state->k1); free (state); GSL_ERROR_NULL ("failed to allocate space for ytmp", GSL_ENOMEM); } state->y_onestep = (double *) malloc (dim * sizeof (double)); if (state->y_onestep == 0) { free (state->ytmp); free (state->y0); free (state->k); free (state->k1); free (state); GSL_ERROR_NULL ("failed to allocate space for ytmp", GSL_ENOMEM); } return state; } static int rk4_step (double *y, const rk4_state_t *state, const double h, const double t, const size_t dim, const gsl_odeiv_system *sys) { /* Makes a Runge-Kutta 4th order advance with step size h. */ /* initial values of variables y. */ const double *y0 = state->y0; /* work space */ double *ytmp = state->ytmp; /* Runge-Kutta coefficients. Contains values of coefficient k1 in the beginning */ double *k = state->k; size_t i; /* k1 step */ for (i = 0; i < dim; i++) { y[i] += h / 6.0 * k[i]; ytmp[i] = y0[i] + 0.5 * h * k[i]; } /* k2 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + 0.5 * h, ytmp, k); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) { y[i] += h / 3.0 * k[i]; ytmp[i] = y0[i] + 0.5 * h * k[i]; } /* k3 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + 0.5 * h, ytmp, k); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) { y[i] += h / 3.0 * k[i]; ytmp[i] = y0[i] + h * k[i]; } /* k4 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + h, ytmp, k); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) { y[i] += h / 6.0 * k[i]; } return GSL_SUCCESS; } static int rk4_apply (void *vstate, size_t dim, double t, double h, double y[], double yerr[], const double dydt_in[], double dydt_out[], const gsl_odeiv_system * sys) { rk4_state_t *state = (rk4_state_t *) vstate; size_t i; double *const k = state->k; double *const k1 = state->k1; double *const y0 = state->y0; double *const y_onestep = state->y_onestep; DBL_MEMCPY (y0, y, dim); if (dydt_in != NULL) { DBL_MEMCPY (k, dydt_in, dim); } else { int s = GSL_ODEIV_FN_EVAL (sys, t, y0, k); if (s != GSL_SUCCESS) { return s; } } /* Error estimation is done by step doubling procedure */ /* Save first point derivatives*/ DBL_MEMCPY (k1, k, dim); /* First traverse h with one step (save to y_onestep) */ DBL_MEMCPY (y_onestep, y, dim); { int s = rk4_step (y_onestep, state, h, t, dim, sys); if (s != GSL_SUCCESS) { return s; } } /* Then with two steps with half step length (save to y) */ DBL_MEMCPY (k, k1, dim); { int s = rk4_step (y, state, h/2.0, t, dim, sys); if (s != GSL_SUCCESS) { /* Restore original values */ DBL_MEMCPY (y, y0, dim); return s; } } /* Update before second step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + h/2.0, y, k); if (s != GSL_SUCCESS) { /* Restore original values */ DBL_MEMCPY (y, y0, dim); return s; } } /* Save original y0 to k1 for possible failures */ DBL_MEMCPY (k1, y0, dim); /* Update y0 for second step */ DBL_MEMCPY (y0, y, dim); { int s = rk4_step (y, state, h/2.0, t + h/2.0, dim, sys); if (s != GSL_SUCCESS) { /* Restore original values */ DBL_MEMCPY (y, k1, dim); return s; } } /* Derivatives at output */ if (dydt_out != NULL) { int s = GSL_ODEIV_FN_EVAL (sys, t + h, y, dydt_out); if (s != GSL_SUCCESS) { /* Restore original values */ DBL_MEMCPY (y, k1, dim); return s; } } /* Error estimation yerr = C * 0.5 * | y(onestep) - y(twosteps) | / (2^order - 1) constant C is approximately 8.0 to ensure 90% of samples lie within the error (assuming a gaussian distribution with prior p(sigma)=1/sigma.) */ for (i = 0; i < dim; i++) { yerr[i] = 4.0 * (y[i] - y_onestep[i]) / 15.0; } return GSL_SUCCESS; } static int rk4_reset (void *vstate, size_t dim) { rk4_state_t *state = (rk4_state_t *) vstate; DBL_ZERO_MEMSET (state->k, dim); DBL_ZERO_MEMSET (state->k1, dim); DBL_ZERO_MEMSET (state->y0, dim); DBL_ZERO_MEMSET (state->ytmp, dim); DBL_ZERO_MEMSET (state->y_onestep, dim); return GSL_SUCCESS; } static unsigned int rk4_order (void *vstate) { rk4_state_t *state = (rk4_state_t *) vstate; state = 0; /* prevent warnings about unused parameters */ return 4; } static void rk4_free (void *vstate) { rk4_state_t *state = (rk4_state_t *) vstate; free (state->k); free (state->k1); free (state->y0); free (state->ytmp); free (state->y_onestep); free (state); } static const gsl_odeiv_step_type rk4_type = { "rk4", /* name */ 1, /* can use dydt_in */ 1, /* gives exact dydt_out */ &rk4_alloc, &rk4_apply, &rk4_reset, &rk4_order, &rk4_free }; const gsl_odeiv_step_type *gsl_odeiv_step_rk4 = &rk4_type; praat-6.0.04/external/gsl/gsl_ode-initval__rk4imp.c000066400000000000000000000215061261542461700222040ustar00rootroot00000000000000/* ode-initval/rk4imp.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Runge-Kutta 4, Gaussian implicit */ /* Author: G. Jungman */ /* Error estimation by step doubling, see eg. Ascher, U.M., Petzold, L.R., Computer methods for ordinary differential and differential-algebraic equations, SIAM, Philadelphia, 1998. Method coefficients can also be found in it. */ #include "gsl__config.h" #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_odeiv.h" #include "gsl_ode-initval__odeiv_util.h" typedef struct { double *k1nu; double *k2nu; double *ytmp1; double *ytmp2; double *y0; double *y0_orig; double *y_onestep; } rk4imp_state_t; static void * rk4imp_alloc (size_t dim) { rk4imp_state_t *state = (rk4imp_state_t *) malloc (sizeof (rk4imp_state_t)); if (state == 0) { GSL_ERROR_NULL ("failed to allocate space for rk4imp_state", GSL_ENOMEM); } state->k1nu = (double *) malloc (dim * sizeof (double)); if (state->k1nu == 0) { free (state); GSL_ERROR_NULL ("failed to allocate space for k1nu", GSL_ENOMEM); } state->k2nu = (double *) malloc (dim * sizeof (double)); if (state->k2nu == 0) { free (state->k1nu); free (state); GSL_ERROR_NULL ("failed to allocate space for k2nu", GSL_ENOMEM); } state->ytmp1 = (double *) malloc (dim * sizeof (double)); if (state->ytmp1 == 0) { free (state->k2nu); free (state->k1nu); free (state); GSL_ERROR_NULL ("failed to allocate space for ytmp1", GSL_ENOMEM); } state->ytmp2 = (double *) malloc (dim * sizeof (double)); if (state->ytmp2 == 0) { free (state->ytmp1); free (state->k2nu); free (state->k1nu); free (state); GSL_ERROR_NULL ("failed to allocate space for ytmp2", GSL_ENOMEM); } state->y0 = (double *) malloc (dim * sizeof (double)); if (state->y0 == 0) { free (state->ytmp2); free (state->ytmp1); free (state->k2nu); free (state->k1nu); free (state); GSL_ERROR_NULL ("failed to allocate space for y0", GSL_ENOMEM); } state->y0_orig = (double *) malloc (dim * sizeof (double)); if (state->y0_orig == 0) { free (state->y0); free (state->ytmp2); free (state->ytmp1); free (state->k2nu); free (state->k1nu); free (state); GSL_ERROR_NULL ("failed to allocate space for y0_orig", GSL_ENOMEM); } state->y_onestep = (double *) malloc (dim * sizeof (double)); if (state->y_onestep == 0) { free (state->y0_orig); free (state->y0); free (state->ytmp2); free (state->ytmp1); free (state->k2nu); free (state->k1nu); free (state); GSL_ERROR_NULL ("failed to allocate space for y_onestep", GSL_ENOMEM); } return state; } static int rk4imp_step (double *y, rk4imp_state_t *state, const double h, const double t, const size_t dim, const gsl_odeiv_system *sys) { /* Makes a Runge-Kutta 4th order implicit advance with step size h. y0 is initial values of variables y. The implicit matrix equations to solve are: Y1 = y0 + h * a11 * f(t + h * c1, Y1) + h * a12 * f(t + h * c2, Y2) Y2 = y0 + h * a21 * f(t + h * c1, Y1) + h * a22 * f(t + h * c2, Y2) y = y0 + h * b1 * f(t + h * c1, Y1) + h * b2 * f(t + h * c2, Y2) with constant coefficients a, b and c. For this method they are: b=[0.5 0.5] c=[(3-sqrt(3))/6 (3+sqrt(3))/6] a11=1/4, a12=(3-2*sqrt(3))/12, a21=(3+2*sqrt(3))/12 and a22=1/4 */ const double ir3 = 1.0 / M_SQRT3; const int iter_steps = 3; int nu; size_t i; double *const k1nu = state->k1nu; double *const k2nu = state->k2nu; double *const ytmp1 = state->ytmp1; double *const ytmp2 = state->ytmp2; /* iterative solution of Y1 and Y2. Note: This method does not check for convergence of the iterative solution! */ for (nu = 0; nu < iter_steps; nu++) { for (i = 0; i < dim; i++) { ytmp1[i] = y[i] + h * (0.25 * k1nu[i] + 0.5 * (0.5 - ir3) * k2nu[i]); ytmp2[i] = y[i] + h * (0.25 * k2nu[i] + 0.5 * (0.5 + ir3) * k1nu[i]); } { int s = GSL_ODEIV_FN_EVAL (sys, t + 0.5 * h * (1.0 - ir3), ytmp1, k1nu); if (s != GSL_SUCCESS) { return s; } } { int s = GSL_ODEIV_FN_EVAL (sys, t + 0.5 * h * (1.0 + ir3), ytmp2, k2nu); if (s != GSL_SUCCESS) { return s; } } } /* assignment */ for (i = 0; i < dim; i++) { const double d_i = 0.5 * (k1nu[i] + k2nu[i]); y[i] += h * d_i; } return GSL_SUCCESS; } static int rk4imp_apply (void *vstate, size_t dim, double t, double h, double y[], double yerr[], const double dydt_in[], double dydt_out[], const gsl_odeiv_system * sys) { rk4imp_state_t *state = (rk4imp_state_t *) vstate; size_t i; double *y0 = state->y0; double *y0_orig = state->y0_orig; double *y_onestep = state->y_onestep; double *k1nu = state->k1nu; double *k2nu = state->k2nu; /* Initialization step */ DBL_MEMCPY (y0, y, dim); /* Save initial values in case of failure */ DBL_MEMCPY (y0_orig, y, dim); if (dydt_in != 0) { DBL_MEMCPY (k1nu, dydt_in, dim); } else { int s = GSL_ODEIV_FN_EVAL (sys, t, y, k1nu); if (s != GSL_SUCCESS) { return s; } } DBL_MEMCPY (k2nu, k1nu, dim); /* First traverse h with one step (save to y_onestep) */ DBL_MEMCPY (y_onestep, y, dim); { int s = rk4imp_step (y_onestep, state, h, t, dim, sys); if (s != GSL_SUCCESS) { return s; } } /* Then with two steps with half step length (save to y) */ { int s = rk4imp_step (y, state, h/2.0, t, dim, sys); if (s != GSL_SUCCESS) { /* Restore original y vector */ DBL_MEMCPY (y, y0_orig, dim); return s; } } DBL_MEMCPY (y0, y, dim); { int s = GSL_ODEIV_FN_EVAL (sys, t + h/2.0, y, k1nu); if (s != GSL_SUCCESS) { /* Restore original y vector */ DBL_MEMCPY (y, y0_orig, dim); return s; } } DBL_MEMCPY (k2nu, k1nu, dim); { int s = rk4imp_step (y, state, h/2.0, t + h/2.0, dim, sys); if (s != GSL_SUCCESS) { /* Restore original y vector */ DBL_MEMCPY (y, y0_orig, dim); return s; } } /* Derivatives at output */ if (dydt_out != NULL) { int s = GSL_ODEIV_FN_EVAL (sys, t + h, y, dydt_out); if (s != GSL_SUCCESS) { /* Restore original y vector */ DBL_MEMCPY (y, y0_orig, dim); return s; } } /* Error estimation */ /* Denominator in step doubling error equation * yerr = 0.5 * | y(onestep) - y(twosteps) | / (2^order - 1) */ for (i = 0; i < dim; i++) { yerr[i] = 8.0 * 0.5 * (y[i] - y_onestep[i]) / 15.0; } return GSL_SUCCESS; } static int rk4imp_reset (void *vstate, size_t dim) { rk4imp_state_t *state = (rk4imp_state_t *) vstate; DBL_ZERO_MEMSET (state->y_onestep, dim); DBL_ZERO_MEMSET (state->y0_orig, dim); DBL_ZERO_MEMSET (state->y0, dim); DBL_ZERO_MEMSET (state->k1nu, dim); DBL_ZERO_MEMSET (state->k2nu, dim); DBL_ZERO_MEMSET (state->ytmp1, dim); DBL_ZERO_MEMSET (state->ytmp2, dim); return GSL_SUCCESS; } static unsigned int rk4imp_order (void *vstate) { rk4imp_state_t *state = (rk4imp_state_t *) vstate; state = 0; /* prevent warnings about unused parameters */ return 4; } static void rk4imp_free (void *vstate) { rk4imp_state_t *state = (rk4imp_state_t *) vstate; free (state->y_onestep); free (state->y0_orig); free (state->y0); free (state->k1nu); free (state->k2nu); free (state->ytmp1); free (state->ytmp2); free (state); } static const gsl_odeiv_step_type rk4imp_type = { "rk4imp", /* name */ 1, /* can use dydt_in? */ 1, /* gives exact dydt_out? */ &rk4imp_alloc, &rk4imp_apply, &rk4imp_reset, &rk4imp_order, &rk4imp_free }; const gsl_odeiv_step_type *gsl_odeiv_step_rk4imp = &rk4imp_type; praat-6.0.04/external/gsl/gsl_ode-initval__rk8pd.c000066400000000000000000000274401261542461700220310ustar00rootroot00000000000000/* ode-initval/rk8pd.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Runge-Kutta 8(9), Prince-Dormand * * High Order Embedded Runge-Kutta Formulae * P.J. Prince and J.R. Dormand * J. Comp. Appl. Math.,7, pp. 67-75, 1981 */ /* Author: G. Jungman */ #include "gsl__config.h" #include #include #include "gsl_errno.h" #include "gsl_odeiv.h" #include "gsl_ode-initval__odeiv_util.h" /* Prince-Dormand constants */ static const double Abar[] = { 14005451.0 / 335480064.0, 0.0, 0.0, 0.0, 0.0, -59238493.0 / 1068277825.0, 181606767.0 / 758867731.0, 561292985.0 / 797845732.0, -1041891430.0 / 1371343529.0, 760417239.0 / 1151165299.0, 118820643.0 / 751138087.0, -528747749.0 / 2220607170.0, 1.0 / 4.0 }; static const double A[] = { 13451932.0 / 455176623.0, 0.0, 0.0, 0.0, 0.0, -808719846.0 / 976000145.0, 1757004468.0 / 5645159321.0, 656045339.0 / 265891186.0, -3867574721.0 / 1518517206.0, 465885868.0 / 322736535.0, 53011238.0 / 667516719.0, 2.0 / 45.0 }; static const double ah[] = { 1.0 / 18.0, 1.0 / 12.0, 1.0 / 8.0, 5.0 / 16.0, 3.0 / 8.0, 59.0 / 400.0, 93.0 / 200.0, 5490023248.0 / 9719169821.0, 13.0 / 20.0, 1201146811.0 / 1299019798.0 }; static const double b21 = 1.0 / 18.0; static const double b3[] = { 1.0 / 48.0, 1.0 / 16.0 }; static const double b4[] = { 1.0 / 32.0, 0.0, 3.0 / 32.0 }; static const double b5[] = { 5.0 / 16.0, 0.0, -75.0 / 64.0, 75.0 / 64.0 }; static const double b6[] = { 3.0 / 80.0, 0.0, 0.0, 3.0 / 16.0, 3.0 / 20.0 }; static const double b7[] = { 29443841.0 / 614563906.0, 0.0, 0.0, 77736538.0 / 692538347.0, -28693883.0 / 1125000000.0, 23124283.0 / 1800000000.0 }; static const double b8[] = { 16016141.0 / 946692911.0, 0.0, 0.0, 61564180.0 / 158732637.0, 22789713.0 / 633445777.0, 545815736.0 / 2771057229.0, -180193667.0 / 1043307555.0 }; static const double b9[] = { 39632708.0 / 573591083.0, 0.0, 0.0, -433636366.0 / 683701615.0, -421739975.0 / 2616292301.0, 100302831.0 / 723423059.0, 790204164.0 / 839813087.0, 800635310.0 / 3783071287.0 }; static const double b10[] = { 246121993.0 / 1340847787.0, 0.0, 0.0, -37695042795.0 / 15268766246.0, -309121744.0 / 1061227803.0, -12992083.0 / 490766935.0, 6005943493.0 / 2108947869.0, 393006217.0 / 1396673457.0, 123872331.0 / 1001029789.0 }; static const double b11[] = { -1028468189.0 / 846180014.0, 0.0, 0.0, 8478235783.0 / 508512852.0, 1311729495.0 / 1432422823.0, -10304129995.0 / 1701304382.0, -48777925059.0 / 3047939560.0, 15336726248.0 / 1032824649.0, -45442868181.0 / 3398467696.0, 3065993473.0 / 597172653.0 }; static const double b12[] = { 185892177.0 / 718116043.0, 0.0, 0.0, -3185094517.0 / 667107341.0, -477755414.0 / 1098053517.0, -703635378.0 / 230739211.0, 5731566787.0 / 1027545527.0, 5232866602.0 / 850066563.0, -4093664535.0 / 808688257.0, 3962137247.0 / 1805957418.0, 65686358.0 / 487910083.0 }; static const double b13[] = { 403863854.0 / 491063109.0, 0.0, 0.0, -5068492393.0 / 434740067.0, -411421997.0 / 543043805.0, 652783627.0 / 914296604.0, 11173962825.0 / 925320556.0, -13158990841.0 / 6184727034.0, 3936647629.0 / 1978049680.0, -160528059.0 / 685178525.0, 248638103.0 / 1413531060.0, 0.0 }; typedef struct { double *k[13]; double *ytmp; double *y0; } rk8pd_state_t; static void * rk8pd_alloc (size_t dim) { rk8pd_state_t *state = (rk8pd_state_t *) malloc (sizeof (rk8pd_state_t)); int i, j; if (state == 0) { GSL_ERROR_NULL ("failed to allocate space for rk8pd_state", GSL_ENOMEM); } state->ytmp = (double *) malloc (dim * sizeof (double)); if (state->ytmp == 0) { free (state); GSL_ERROR_NULL ("failed to allocate space for ytmp", GSL_ENOMEM); } state->y0 = (double *) malloc (dim * sizeof (double)); if (state->y0 == 0) { free (state->ytmp); free (state); GSL_ERROR_NULL ("failed to allocate space for y0", GSL_ENOMEM); } for (i = 0; i < 13; i++) { state->k[i] = (double *) malloc (dim * sizeof (double)); if (state->k[i] == 0) { for (j = 0; j < i; j++) { free (state->k[j]); } free (state->y0); free (state->ytmp); free (state); GSL_ERROR_NULL ("failed to allocate space for k's", GSL_ENOMEM); } } return state; } static int rk8pd_apply (void *vstate, size_t dim, double t, double h, double y[], double yerr[], const double dydt_in[], double dydt_out[], const gsl_odeiv_system * sys) { rk8pd_state_t *state = (rk8pd_state_t *) vstate; size_t i; double *const ytmp = state->ytmp; double *const y0 = state->y0; /* Note that k1 is stored in state->k[0] due to zero-based indexing */ double *const k1 = state->k[0]; double *const k2 = state->k[1]; double *const k3 = state->k[2]; double *const k4 = state->k[3]; double *const k5 = state->k[4]; double *const k6 = state->k[5]; double *const k7 = state->k[6]; double *const k8 = state->k[7]; double *const k9 = state->k[8]; double *const k10 = state->k[9]; double *const k11 = state->k[10]; double *const k12 = state->k[11]; double *const k13 = state->k[12]; DBL_MEMCPY (y0, y, dim); /* k1 step */ if (dydt_in != NULL) { DBL_MEMCPY (k1, dydt_in, dim); } else { int s = GSL_ODEIV_FN_EVAL (sys, t, y, k1); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) ytmp[i] = y[i] + b21 * h * k1[i]; /* k2 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[0] * h, ytmp, k2); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b3[0] * k1[i] + b3[1] * k2[i]); /* k3 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[1] * h, ytmp, k3); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b4[0] * k1[i] + b4[2] * k3[i]); /* k4 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[2] * h, ytmp, k4); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b5[0] * k1[i] + b5[2] * k3[i] + b5[3] * k4[i]); /* k5 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[3] * h, ytmp, k5); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b6[0] * k1[i] + b6[3] * k4[i] + b6[4] * k5[i]); /* k6 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[4] * h, ytmp, k6); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b7[0] * k1[i] + b7[3] * k4[i] + b7[4] * k5[i] + b7[5] * k6[i]); /* k7 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[5] * h, ytmp, k7); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b8[0] * k1[i] + b8[3] * k4[i] + b8[4] * k5[i] + b8[5] * k6[i] + b8[6] * k7[i]); /* k8 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[6] * h, ytmp, k8); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b9[0] * k1[i] + b9[3] * k4[i] + b9[4] * k5[i] + b9[5] * k6[i] + b9[6] * k7[i] + b9[7] * k8[i]); /* k9 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[7] * h, ytmp, k9); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b10[0] * k1[i] + b10[3] * k4[i] + b10[4] * k5[i] + b10[5] * k6[i] + b10[6] * k7[i] + b10[7] * k8[i] + b10[8] * k9[i]); /* k10 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[8] * h, ytmp, k10); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b11[0] * k1[i] + b11[3] * k4[i] + b11[4] * k5[i] + b11[5] * k6[i] + b11[6] * k7[i] + b11[7] * k8[i] + b11[8] * k9[i] + b11[9] * k10[i]); /* k11 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[9] * h, ytmp, k11); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b12[0] * k1[i] + b12[3] * k4[i] + b12[4] * k5[i] + b12[5] * k6[i] + b12[6] * k7[i] + b12[7] * k8[i] + b12[8] * k9[i] + b12[9] * k10[i] + b12[10] * k11[i]); /* k12 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + h, ytmp, k12); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b13[0] * k1[i] + b13[3] * k4[i] + b13[4] * k5[i] + b13[5] * k6[i] + b13[6] * k7[i] + b13[7] * k8[i] + b13[8] * k9[i] + b13[9] * k10[i] + b13[10] * k11[i] + b13[11] * k12[i]); /* k13 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + h, ytmp, k13); if (s != GSL_SUCCESS) { return s; } } /* final sum */ for (i = 0; i < dim; i++) { const double ksum8 = Abar[0] * k1[i] + Abar[5] * k6[i] + Abar[6] * k7[i] + Abar[7] * k8[i] + Abar[8] * k9[i] + Abar[9] * k10[i] + Abar[10] * k11[i] + Abar[11] * k12[i] + Abar[12] * k13[i]; y[i] += h * ksum8; } /* Evaluate dydt_out[]. */ if (dydt_out != NULL) { int s = GSL_ODEIV_FN_EVAL (sys, t + h, y, dydt_out); if (s != GSL_SUCCESS) { /* Restore initial values */ DBL_MEMCPY (y, y0, dim); return s; } } /* error estimate */ for (i = 0; i < dim; i++) { const double ksum8 = Abar[0] * k1[i] + Abar[5] * k6[i] + Abar[6] * k7[i] + Abar[7] * k8[i] + Abar[8] * k9[i] + Abar[9] * k10[i] + Abar[10] * k11[i] + Abar[11] * k12[i] + Abar[12] * k13[i]; const double ksum7 = A[0] * k1[i] + A[5] * k6[i] + A[6] * k7[i] + A[7] * k8[i] + A[8] * k9[i] + A[9] * k10[i] + A[10] * k11[i] + A[11] * k12[i]; yerr[i] = h * (ksum7 - ksum8); } return GSL_SUCCESS; } static int rk8pd_reset (void *vstate, size_t dim) { rk8pd_state_t *state = (rk8pd_state_t *) vstate; int i; for (i = 0; i < 13; i++) { DBL_ZERO_MEMSET (state->k[i], dim); } DBL_ZERO_MEMSET (state->y0, dim); DBL_ZERO_MEMSET (state->ytmp, dim); return GSL_SUCCESS; } static unsigned int rk8pd_order (void *vstate) { rk8pd_state_t *state = (rk8pd_state_t *) vstate; state = 0; /* prevent warnings about unused parameters */ return 8; } static void rk8pd_free (void *vstate) { rk8pd_state_t *state = (rk8pd_state_t *) vstate; int i; for (i = 0; i < 13; i++) { free (state->k[i]); } free (state->y0); free (state->ytmp); free (state); } static const gsl_odeiv_step_type rk8pd_type = { "rk8pd", /* name */ 1, /* can use dydt_in */ 1, /* gives exact dydt_out */ &rk8pd_alloc, &rk8pd_apply, &rk8pd_reset, &rk8pd_order, &rk8pd_free }; const gsl_odeiv_step_type *gsl_odeiv_step_rk8pd = &rk8pd_type; praat-6.0.04/external/gsl/gsl_ode-initval__rkck.c000066400000000000000000000205001261542461700217210ustar00rootroot00000000000000/* ode-initval/rkck.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Runge-Kutta 4(5), Cash-Karp */ /* Reference: Cash, J.R., Karp, A.H., ACM Transactions of Mathematical Software, vol. 16 (1990) 201-222. */ /* Author: G. Jungman */ #include "gsl__config.h" #include #include #include "gsl_errno.h" #include "gsl_odeiv.h" #include "gsl_ode-initval__odeiv_util.h" /* Cash-Karp constants */ static const double ah[] = { 1.0 / 5.0, 0.3, 3.0 / 5.0, 1.0, 7.0 / 8.0 }; static const double b21 = 1.0 / 5.0; static const double b3[] = { 3.0 / 40.0, 9.0 / 40.0 }; static const double b4[] = { 0.3, -0.9, 1.2 }; static const double b5[] = { -11.0 / 54.0, 2.5, -70.0 / 27.0, 35.0 / 27.0 }; static const double b6[] = { 1631.0 / 55296.0, 175.0 / 512.0, 575.0 / 13824.0, 44275.0 / 110592.0, 253.0 / 4096.0 }; static const double c1 = 37.0 / 378.0; static const double c3 = 250.0 / 621.0; static const double c4 = 125.0 / 594.0; static const double c6 = 512.0 / 1771.0; /* These are the differences of fifth and fourth order coefficients for error estimation */ static const double ec[] = { 0.0, 37.0 / 378.0 - 2825.0 / 27648.0, 0.0, 250.0 / 621.0 - 18575.0 / 48384.0, 125.0 / 594.0 - 13525.0 / 55296.0, -277.0 / 14336.0, 512.0 / 1771.0 - 0.25 }; typedef struct { double *k1; double *k2; double *k3; double *k4; double *k5; double *k6; double *y0; double *ytmp; } rkck_state_t; static void * rkck_alloc (size_t dim) { rkck_state_t *state = (rkck_state_t *) malloc (sizeof (rkck_state_t)); if (state == 0) { GSL_ERROR_NULL ("failed to allocate space for rkck_state", GSL_ENOMEM); } state->k1 = (double *) malloc (dim * sizeof (double)); if (state->k1 == 0) { free (state); GSL_ERROR_NULL ("failed to allocate space for k1", GSL_ENOMEM); } state->k2 = (double *) malloc (dim * sizeof (double)); if (state->k2 == 0) { free (state->k1); free (state); GSL_ERROR_NULL ("failed to allocate space for k2", GSL_ENOMEM); } state->k3 = (double *) malloc (dim * sizeof (double)); if (state->k3 == 0) { free (state->k2); free (state->k1); free (state); GSL_ERROR_NULL ("failed to allocate space for k3", GSL_ENOMEM); } state->k4 = (double *) malloc (dim * sizeof (double)); if (state->k4 == 0) { free (state->k3); free (state->k2); free (state->k1); free (state); GSL_ERROR_NULL ("failed to allocate space for k4", GSL_ENOMEM); } state->k5 = (double *) malloc (dim * sizeof (double)); if (state->k5 == 0) { free (state->k4); free (state->k3); free (state->k2); free (state->k1); free (state); GSL_ERROR_NULL ("failed to allocate space for k5", GSL_ENOMEM); } state->k6 = (double *) malloc (dim * sizeof (double)); if (state->k6 == 0) { free (state->k5); free (state->k4); free (state->k3); free (state->k2); free (state->k1); free (state); GSL_ERROR_NULL ("failed to allocate space for k6", GSL_ENOMEM); } state->y0 = (double *) malloc (dim * sizeof (double)); if (state->y0 == 0) { free (state->k6); free (state->k5); free (state->k4); free (state->k3); free (state->k2); free (state->k1); free (state); GSL_ERROR_NULL ("failed to allocate space for y0", GSL_ENOMEM); } state->ytmp = (double *) malloc (dim * sizeof (double)); if (state->ytmp == 0) { free (state->y0); free (state->k6); free (state->k5); free (state->k4); free (state->k3); free (state->k2); free (state->k1); free (state); GSL_ERROR_NULL ("failed to allocate space for ytmp", GSL_ENOMEM); } return state; } static int rkck_apply (void *vstate, size_t dim, double t, double h, double y[], double yerr[], const double dydt_in[], double dydt_out[], const gsl_odeiv_system * sys) { rkck_state_t *state = (rkck_state_t *) vstate; size_t i; double *const k1 = state->k1; double *const k2 = state->k2; double *const k3 = state->k3; double *const k4 = state->k4; double *const k5 = state->k5; double *const k6 = state->k6; double *const ytmp = state->ytmp; double *const y0 = state->y0; DBL_MEMCPY (y0, y, dim); /* k1 step */ if (dydt_in != NULL) { DBL_MEMCPY (k1, dydt_in, dim); } else { int s = GSL_ODEIV_FN_EVAL (sys, t, y, k1); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) ytmp[i] = y[i] + b21 * h * k1[i]; /* k2 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[0] * h, ytmp, k2); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b3[0] * k1[i] + b3[1] * k2[i]); /* k3 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[1] * h, ytmp, k3); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b4[0] * k1[i] + b4[1] * k2[i] + b4[2] * k3[i]); /* k4 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[2] * h, ytmp, k4); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b5[0] * k1[i] + b5[1] * k2[i] + b5[2] * k3[i] + b5[3] * k4[i]); /* k5 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[3] * h, ytmp, k5); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b6[0] * k1[i] + b6[1] * k2[i] + b6[2] * k3[i] + b6[3] * k4[i] + b6[4] * k5[i]); /* k6 step and final sum */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[4] * h, ytmp, k6); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) { const double d_i = c1 * k1[i] + c3 * k3[i] + c4 * k4[i] + c6 * k6[i]; y[i] += h * d_i; } /* Evaluate dydt_out[]. */ if (dydt_out != NULL) { int s = GSL_ODEIV_FN_EVAL (sys, t + h, y, dydt_out); if (s != GSL_SUCCESS) { /* Restore initial values */ DBL_MEMCPY (y, y0, dim); return s; } } /* difference between 4th and 5th order */ for (i = 0; i < dim; i++) { yerr[i] = h * (ec[1] * k1[i] + ec[3] * k3[i] + ec[4] * k4[i] + ec[5] * k5[i] + ec[6] * k6[i]); } return GSL_SUCCESS; } static int rkck_reset (void *vstate, size_t dim) { rkck_state_t *state = (rkck_state_t *) vstate; DBL_ZERO_MEMSET (state->k1, dim); DBL_ZERO_MEMSET (state->k2, dim); DBL_ZERO_MEMSET (state->k3, dim); DBL_ZERO_MEMSET (state->k4, dim); DBL_ZERO_MEMSET (state->k5, dim); DBL_ZERO_MEMSET (state->k6, dim); DBL_ZERO_MEMSET (state->ytmp, dim); DBL_ZERO_MEMSET (state->y0, dim); return GSL_SUCCESS; } static unsigned int rkck_order (void *vstate) { rkck_state_t *state = (rkck_state_t *) vstate; state = 0; /* prevent warnings about unused parameters */ return 5; /* FIXME: should this be 4? */ } static void rkck_free (void *vstate) { rkck_state_t *state = (rkck_state_t *) vstate; free (state->ytmp); free (state->y0); free (state->k6); free (state->k5); free (state->k4); free (state->k3); free (state->k2); free (state->k1); free (state); } static const gsl_odeiv_step_type rkck_type = { "rkck", /* name */ 1, /* can use dydt_in */ 1, /* gives exact dydt_out */ &rkck_alloc, &rkck_apply, &rkck_reset, &rkck_order, &rkck_free }; const gsl_odeiv_step_type *gsl_odeiv_step_rkck = &rkck_type; praat-6.0.04/external/gsl/gsl_ode-initval__rkf45.c000066400000000000000000000205761261542461700217370ustar00rootroot00000000000000/* ode-initval/rkf45.c * * Copyright (C) 2001, 2004, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Runge-Kutta-Fehlberg 4(5)*/ /* Reference eg. Hairer, E., Norsett S.P., Wanner, G. Solving ordinary differential equations I, Nonstiff Problems, 2nd revised edition, Springer, 2000. */ #include "gsl__config.h" #include #include #include "gsl_errno.h" #include "gsl_odeiv.h" #include "gsl_ode-initval__odeiv_util.h" /* Runge-Kutta-Fehlberg coefficients. Zero elements left out */ static const double ah[] = { 1.0/4.0, 3.0/8.0, 12.0/13.0, 1.0, 1.0/2.0 }; static const double b3[] = { 3.0/32.0, 9.0/32.0 }; static const double b4[] = { 1932.0/2197.0, -7200.0/2197.0, 7296.0/2197.0}; static const double b5[] = { 8341.0/4104.0, -32832.0/4104.0, 29440.0/4104.0, -845.0/4104.0}; static const double b6[] = { -6080.0/20520.0, 41040.0/20520.0, -28352.0/20520.0, 9295.0/20520.0, -5643.0/20520.0}; static const double c1 = 902880.0/7618050.0; static const double c3 = 3953664.0/7618050.0; static const double c4 = 3855735.0/7618050.0; static const double c5 = -1371249.0/7618050.0; static const double c6 = 277020.0/7618050.0; /* These are the differences of fifth and fourth order coefficients for error estimation */ static const double ec[] = { 0.0, 1.0 / 360.0, 0.0, -128.0 / 4275.0, -2197.0 / 75240.0, 1.0 / 50.0, 2.0 / 55.0 }; typedef struct { double *k1; double *k2; double *k3; double *k4; double *k5; double *k6; double *y0; double *ytmp; } rkf45_state_t; static void * rkf45_alloc (size_t dim) { rkf45_state_t *state = (rkf45_state_t *) malloc (sizeof (rkf45_state_t)); if (state == 0) { GSL_ERROR_NULL ("failed to allocate space for rkf45_state", GSL_ENOMEM); } state->k1 = (double *) malloc (dim * sizeof (double)); if (state->k1 == 0) { free (state); GSL_ERROR_NULL ("failed to allocate space for k1", GSL_ENOMEM); } state->k2 = (double *) malloc (dim * sizeof (double)); if (state->k2 == 0) { free (state->k1); free (state); GSL_ERROR_NULL ("failed to allocate space for k2", GSL_ENOMEM); } state->k3 = (double *) malloc (dim * sizeof (double)); if (state->k3 == 0) { free (state->k2); free (state->k1); free (state); GSL_ERROR_NULL ("failed to allocate space for k3", GSL_ENOMEM); } state->k4 = (double *) malloc (dim * sizeof (double)); if (state->k4 == 0) { free (state->k3); free (state->k2); free (state->k1); free (state); GSL_ERROR_NULL ("failed to allocate space for k4", GSL_ENOMEM); } state->k5 = (double *) malloc (dim * sizeof (double)); if (state->k5 == 0) { free (state->k4); free (state->k3); free (state->k2); free (state->k1); free (state); GSL_ERROR_NULL ("failed to allocate space for k5", GSL_ENOMEM); } state->k6 = (double *) malloc (dim * sizeof (double)); if (state->k6 == 0) { free (state->k5); free (state->k4); free (state->k3); free (state->k2); free (state->k1); free (state); GSL_ERROR_NULL ("failed to allocate space for k6", GSL_ENOMEM); } state->y0 = (double *) malloc (dim * sizeof (double)); if (state->y0 == 0) { free (state->k6); free (state->k5); free (state->k4); free (state->k3); free (state->k2); free (state->k1); free (state); GSL_ERROR_NULL ("failed to allocate space for y0", GSL_ENOMEM); } state->ytmp = (double *) malloc (dim * sizeof (double)); if (state->ytmp == 0) { free (state->y0); free (state->k6); free (state->k5); free (state->k4); free (state->k3); free (state->k2); free (state->k1); free (state); GSL_ERROR_NULL ("failed to allocate space for ytmp", GSL_ENOMEM); } return state; } static int rkf45_apply (void *vstate, size_t dim, double t, double h, double y[], double yerr[], const double dydt_in[], double dydt_out[], const gsl_odeiv_system * sys) { rkf45_state_t *state = (rkf45_state_t *) vstate; size_t i; double *const k1 = state->k1; double *const k2 = state->k2; double *const k3 = state->k3; double *const k4 = state->k4; double *const k5 = state->k5; double *const k6 = state->k6; double *const ytmp = state->ytmp; double *const y0 = state->y0; DBL_MEMCPY (y0, y, dim); /* k1 step */ if (dydt_in != NULL) { DBL_MEMCPY (k1, dydt_in, dim); } else { int s = GSL_ODEIV_FN_EVAL (sys, t, y, k1); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) ytmp[i] = y[i] + ah[0] * h * k1[i]; /* k2 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[0] * h, ytmp, k2); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b3[0] * k1[i] + b3[1] * k2[i]); /* k3 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[1] * h, ytmp, k3); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b4[0] * k1[i] + b4[1] * k2[i] + b4[2] * k3[i]); /* k4 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[2] * h, ytmp, k4); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b5[0] * k1[i] + b5[1] * k2[i] + b5[2] * k3[i] + b5[3] * k4[i]); /* k5 step */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[3] * h, ytmp, k5); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) ytmp[i] = y[i] + h * (b6[0] * k1[i] + b6[1] * k2[i] + b6[2] * k3[i] + b6[3] * k4[i] + b6[4] * k5[i]); /* k6 step and final sum */ { int s = GSL_ODEIV_FN_EVAL (sys, t + ah[4] * h, ytmp, k6); if (s != GSL_SUCCESS) { return s; } } for (i = 0; i < dim; i++) { const double d_i = c1 * k1[i] + c3 * k3[i] + c4 * k4[i] + c5 * k5[i] + c6 * k6[i]; y[i] += h * d_i; } /* Derivatives at output */ if (dydt_out != NULL) { int s = GSL_ODEIV_FN_EVAL (sys, t + h, y, dydt_out); if (s != GSL_SUCCESS) { /* Restore initial values */ DBL_MEMCPY (y, y0, dim); return s; } } /* difference between 4th and 5th order */ for (i = 0; i < dim; i++) { yerr[i] = h * (ec[1] * k1[i] + ec[3] * k3[i] + ec[4] * k4[i] + ec[5] * k5[i] + ec[6] * k6[i]); } return GSL_SUCCESS; } static int rkf45_reset (void *vstate, size_t dim) { rkf45_state_t *state = (rkf45_state_t *) vstate; DBL_ZERO_MEMSET (state->k1, dim); DBL_ZERO_MEMSET (state->k2, dim); DBL_ZERO_MEMSET (state->k3, dim); DBL_ZERO_MEMSET (state->k4, dim); DBL_ZERO_MEMSET (state->k5, dim); DBL_ZERO_MEMSET (state->k6, dim); DBL_ZERO_MEMSET (state->ytmp, dim); DBL_ZERO_MEMSET (state->y0, dim); return GSL_SUCCESS; } static unsigned int rkf45_order (void *vstate) { rkf45_state_t *state = (rkf45_state_t *) vstate; state = 0; /* prevent warnings about unused parameters */ return 5; } static void rkf45_free (void *vstate) { rkf45_state_t *state = (rkf45_state_t *) vstate; free (state->ytmp); free (state->y0); free (state->k6); free (state->k5); free (state->k4); free (state->k3); free (state->k2); free (state->k1); free (state); } static const gsl_odeiv_step_type rkf45_type = { "rkf45", /* name */ 1, /* can use dydt_in */ 0, /* gives exact dydt_out */ &rkf45_alloc, &rkf45_apply, &rkf45_reset, &rkf45_order, &rkf45_free }; const gsl_odeiv_step_type *gsl_odeiv_step_rkf45 = &rkf45_type; praat-6.0.04/external/gsl/gsl_ode-initval__step.c000066400000000000000000000041241261542461700217460ustar00rootroot00000000000000/* ode-initval/odeiv.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_odeiv.h" gsl_odeiv_step * gsl_odeiv_step_alloc(const gsl_odeiv_step_type * T, size_t dim) { gsl_odeiv_step *s = (gsl_odeiv_step *) malloc (sizeof (gsl_odeiv_step)); if (s == 0) { GSL_ERROR_NULL ("failed to allocate space for ode struct", GSL_ENOMEM); }; s->type = T; s->dimension = dim; s->state = s->type->alloc(dim); if (s->state == 0) { free (s); /* exception in constructor, avoid memory leak */ GSL_ERROR_NULL ("failed to allocate space for ode state", GSL_ENOMEM); }; return s; } const char * gsl_odeiv_step_name(const gsl_odeiv_step * s) { return s->type->name; } unsigned int gsl_odeiv_step_order(const gsl_odeiv_step * s) { return s->type->order(s->state); } int gsl_odeiv_step_apply( gsl_odeiv_step * s, double t, double h, double y[], double yerr[], const double dydt_in[], double dydt_out[], const gsl_odeiv_system * dydt) { return s->type->apply(s->state, s->dimension, t, h, y, yerr, dydt_in, dydt_out, dydt); } int gsl_odeiv_step_reset(gsl_odeiv_step * s) { return s->type->reset(s->state, s->dimension); } void gsl_odeiv_step_free(gsl_odeiv_step * s) { s->type->free(s->state); free(s); } praat-6.0.04/external/gsl/gsl_odeiv.h000066400000000000000000000171021261542461700174540ustar00rootroot00000000000000/* ode-initval/gsl_odeiv.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_ODEIV_H__ #define __GSL_ODEIV_H__ #include #include #include "gsl_types.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Description of a system of ODEs. * * y' = f(t,y) = dydt(t, y) * * The system is specified by giving the right-hand-side * of the equation and possibly a jacobian function. * * Some methods require the jacobian function, which calculates * the matrix dfdy and the vector dfdt. The matrix dfdy conforms * to the GSL standard, being a continuous range of floating point * values, in row-order. * * As with GSL function objects, user-supplied parameter * data is also present. */ typedef struct { int (* function) (double t, const double y[], double dydt[], void * params); int (* jacobian) (double t, const double y[], double * dfdy, double dfdt[], void * params); size_t dimension; void * params; } gsl_odeiv_system; #define GSL_ODEIV_FN_EVAL(S,t,y,f) (*((S)->function))(t,y,f,(S)->params) #define GSL_ODEIV_JA_EVAL(S,t,y,dfdy,dfdt) (*((S)->jacobian))(t,y,dfdy,dfdt,(S)->params) /* General stepper object. * * Opaque object for stepping an ODE system from t to t+h. * In general the object has some state which facilitates * iterating the stepping operation. */ typedef struct { const char * name; int can_use_dydt_in; int gives_exact_dydt_out; void * (*alloc) (size_t dim); int (*apply) (void * state, size_t dim, double t, double h, double y[], double yerr[], const double dydt_in[], double dydt_out[], const gsl_odeiv_system * dydt); int (*reset) (void * state, size_t dim); unsigned int (*order) (void * state); void (*free) (void * state); } gsl_odeiv_step_type; typedef struct { const gsl_odeiv_step_type * type; size_t dimension; void * state; } gsl_odeiv_step; /* Available stepper types. * * rk2 : embedded 2nd(3rd) Runge-Kutta * rk4 : 4th order (classical) Runge-Kutta * rkck : embedded 4th(5th) Runge-Kutta, Cash-Karp * rk8pd : embedded 8th(9th) Runge-Kutta, Prince-Dormand * rk2imp : implicit 2nd order Runge-Kutta at Gaussian points * rk4imp : implicit 4th order Runge-Kutta at Gaussian points * gear1 : M=1 implicit Gear method * gear2 : M=2 implicit Gear method */ GSL_VAR const gsl_odeiv_step_type *gsl_odeiv_step_rk2; GSL_VAR const gsl_odeiv_step_type *gsl_odeiv_step_rk4; GSL_VAR const gsl_odeiv_step_type *gsl_odeiv_step_rkf45; GSL_VAR const gsl_odeiv_step_type *gsl_odeiv_step_rkck; GSL_VAR const gsl_odeiv_step_type *gsl_odeiv_step_rk8pd; GSL_VAR const gsl_odeiv_step_type *gsl_odeiv_step_rk2imp; GSL_VAR const gsl_odeiv_step_type *gsl_odeiv_step_rk2simp; GSL_VAR const gsl_odeiv_step_type *gsl_odeiv_step_rk4imp; GSL_VAR const gsl_odeiv_step_type *gsl_odeiv_step_bsimp; GSL_VAR const gsl_odeiv_step_type *gsl_odeiv_step_gear1; GSL_VAR const gsl_odeiv_step_type *gsl_odeiv_step_gear2; /* Constructor for specialized stepper objects. */ gsl_odeiv_step * gsl_odeiv_step_alloc(const gsl_odeiv_step_type * T, size_t dim); int gsl_odeiv_step_reset(gsl_odeiv_step * s); void gsl_odeiv_step_free(gsl_odeiv_step * s); /* General stepper object methods. */ const char * gsl_odeiv_step_name(const gsl_odeiv_step *); unsigned int gsl_odeiv_step_order(const gsl_odeiv_step * s); int gsl_odeiv_step_apply(gsl_odeiv_step *, double t, double h, double y[], double yerr[], const double dydt_in[], double dydt_out[], const gsl_odeiv_system * dydt); /* General step size control object. * * The hadjust() method controls the adjustment of * step size given the result of a step and the error. * Valid hadjust() methods must return one of the codes below. * * The general data can be used by specializations * to store state and control their heuristics. */ typedef struct { const char * name; void * (*alloc) (void); int (*init) (void * state, double eps_abs, double eps_rel, double a_y, double a_dydt); int (*hadjust) (void * state, size_t dim, unsigned int ord, const double y[], const double yerr[], const double yp[], double * h); void (*free) (void * state); } gsl_odeiv_control_type; typedef struct { const gsl_odeiv_control_type * type; void * state; } gsl_odeiv_control; /* Possible return values for an hadjust() evolution method. */ #define GSL_ODEIV_HADJ_INC 1 /* step was increased */ #define GSL_ODEIV_HADJ_NIL 0 /* step unchanged */ #define GSL_ODEIV_HADJ_DEC (-1) /* step decreased */ gsl_odeiv_control * gsl_odeiv_control_alloc(const gsl_odeiv_control_type * T); int gsl_odeiv_control_init(gsl_odeiv_control * c, double eps_abs, double eps_rel, double a_y, double a_dydt); void gsl_odeiv_control_free(gsl_odeiv_control * c); int gsl_odeiv_control_hadjust (gsl_odeiv_control * c, gsl_odeiv_step * s, const double y[], const double yerr[], const double dydt[], double * h); const char * gsl_odeiv_control_name(const gsl_odeiv_control * c); /* Available control object constructors. * * The standard control object is a four parameter heuristic * defined as follows: * D0 = eps_abs + eps_rel * (a_y |y| + a_dydt h |y'|) * D1 = |yerr| * q = consistency order of method (q=4 for 4(5) embedded RK) * S = safety factor (0.9 say) * * / (D0/D1)^(1/(q+1)) D0 >= D1 * h_NEW = S h_OLD * | * \ (D0/D1)^(1/q) D0 < D1 * * This encompasses all the standard error scaling methods. * * The y method is the standard method with a_y=1, a_dydt=0. * The yp method is the standard method with a_y=0, a_dydt=1. */ gsl_odeiv_control * gsl_odeiv_control_standard_new(double eps_abs, double eps_rel, double a_y, double a_dydt); gsl_odeiv_control * gsl_odeiv_control_y_new(double eps_abs, double eps_rel); gsl_odeiv_control * gsl_odeiv_control_yp_new(double eps_abs, double eps_rel); /* This controller computes errors using different absolute errors for * each component * * D0 = eps_abs * scale_abs[i] + eps_rel * (a_y |y| + a_dydt h |y'|) */ gsl_odeiv_control * gsl_odeiv_control_scaled_new(double eps_abs, double eps_rel, double a_y, double a_dydt, const double scale_abs[], size_t dim); /* General evolution object. */ typedef struct { size_t dimension; double * y0; double * yerr; double * dydt_in; double * dydt_out; double last_step; unsigned long int count; unsigned long int failed_steps; } gsl_odeiv_evolve; /* Evolution object methods. */ gsl_odeiv_evolve * gsl_odeiv_evolve_alloc(size_t dim); int gsl_odeiv_evolve_apply(gsl_odeiv_evolve *, gsl_odeiv_control * con, gsl_odeiv_step * step, const gsl_odeiv_system * dydt, double * t, double t1, double * h, double y[]); int gsl_odeiv_evolve_reset(gsl_odeiv_evolve *); void gsl_odeiv_evolve_free(gsl_odeiv_evolve *); __END_DECLS #endif /* __GSL_ODEIV_H__ */ praat-6.0.04/external/gsl/gsl_permutation.h000066400000000000000000000063121261542461700207160ustar00rootroot00000000000000/* permutation/gsl_permutation.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTATION_H__ #define __GSL_PERMUTATION_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_check_range.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS struct gsl_permutation_struct { size_t size; size_t *data; }; typedef struct gsl_permutation_struct gsl_permutation; gsl_permutation *gsl_permutation_alloc (const size_t n); gsl_permutation *gsl_permutation_calloc (const size_t n); void gsl_permutation_init (gsl_permutation * p); void gsl_permutation_free (gsl_permutation * p); int gsl_permutation_memcpy (gsl_permutation * dest, const gsl_permutation * src); int gsl_permutation_fread (FILE * stream, gsl_permutation * p); int gsl_permutation_fwrite (FILE * stream, const gsl_permutation * p); int gsl_permutation_fscanf (FILE * stream, gsl_permutation * p); int gsl_permutation_fprintf (FILE * stream, const gsl_permutation * p, const char *format); size_t gsl_permutation_size (const gsl_permutation * p); size_t * gsl_permutation_data (const gsl_permutation * p); size_t gsl_permutation_get (const gsl_permutation * p, const size_t i); int gsl_permutation_swap (gsl_permutation * p, const size_t i, const size_t j); int gsl_permutation_valid (gsl_permutation * p); void gsl_permutation_reverse (gsl_permutation * p); int gsl_permutation_inverse (gsl_permutation * inv, const gsl_permutation * p); int gsl_permutation_next (gsl_permutation * p); int gsl_permutation_prev (gsl_permutation * p); int gsl_permutation_mul (gsl_permutation * p, const gsl_permutation * pa, const gsl_permutation * pb); int gsl_permutation_linear_to_canonical (gsl_permutation * q, const gsl_permutation * p); int gsl_permutation_canonical_to_linear (gsl_permutation * p, const gsl_permutation * q); size_t gsl_permutation_inversions (const gsl_permutation * p); size_t gsl_permutation_linear_cycles (const gsl_permutation * p); size_t gsl_permutation_canonical_cycles (const gsl_permutation * q); #ifdef HAVE_INLINE extern inline size_t gsl_permutation_get (const gsl_permutation * p, const size_t i) { #if GSL_RANGE_CHECK if (i >= p->size) { GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); } #endif return p->data[i]; } #endif /* HAVE_INLINE */ __END_DECLS #endif /* __GSL_PERMUTATION_H__ */ praat-6.0.04/external/gsl/gsl_permutation__canonical.c000066400000000000000000000070251261542461700230610ustar00rootroot00000000000000/* permutation/permutation.c * * Copyright (C) 2001, 2002 Nicolas Darnis * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Modified for GSL by Brian Gough. * Use in-place algorithms, no need for workspace * Use conventions for canonical form given in Knuth (opposite of Sedgewick) */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_permutation.h" int gsl_permutation_linear_to_canonical (gsl_permutation * q, const gsl_permutation * p) { const size_t n = p->size; size_t i, k, s; size_t t = n; const size_t *const pp = p->data; size_t *const qq = q->data; if (q->size != p->size) { GSL_ERROR ("size of q does not match size of p", GSL_EINVAL); } for (i = 0; i < n; i++) { k = pp[i]; s = 1; while (k > i) { k = pp[k]; s++; } if (k < i) continue; /* Now have k == i, i.e the least in its cycle, and s == cycle length */ t -= s; qq[t] = i; k = pp[i]; s = 1; while (k > i) { qq[t + s] = k; k = pp[k]; s++; } if (t == 0) break; } return GSL_SUCCESS; } int gsl_permutation_canonical_to_linear (gsl_permutation * p, const gsl_permutation * q) { size_t i, k, kk, first; const size_t n = p->size; size_t *const pp = p->data; const size_t *const qq = q->data; if (q->size != p->size) { GSL_ERROR ("size of q does not match size of p", GSL_EINVAL); } for (i = 0; i < n; i++) { pp[i] = i; } k = qq[0]; first = pp[k]; for (i = 1; i < n; i++) { kk = qq[i]; if (kk > first) { pp[k] = pp[kk]; k = kk; } else { pp[k] = first; k = kk; first = pp[kk]; } } pp[k] = first; return GSL_SUCCESS; } size_t gsl_permutation_inversions (const gsl_permutation * p) { size_t count = 0; size_t i, j; const size_t size = p->size; for (i = 0; i < size - 1; i++) { for (j = i + 1; j < size; j++) { if (p->data[i] > p->data[j]) { count++; } } } return count; } size_t gsl_permutation_linear_cycles (const gsl_permutation * p) { size_t i, k; size_t count = 0; const size_t size = p->size; for (i = 0; i < size; i++) { k = p->data[i]; while (k > i) { k = p->data[k]; } if (k < i) continue; count++; } return count; } size_t gsl_permutation_canonical_cycles (const gsl_permutation * p) { size_t i; size_t count = 1; size_t min = p->data[0]; for (i = 0; i < p->size; i++) { if (p->data[i] < min) { min = p->data[i]; count++; } } return count; } praat-6.0.04/external/gsl/gsl_permutation__file.c000066400000000000000000000046261261542461700220550ustar00rootroot00000000000000/* permutation/file.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_permutation.h" #define IN_FORMAT "%lu" int gsl_permutation_fread (FILE * stream, gsl_permutation * p) { size_t n = p->size ; size_t * data = p->data ; size_t items = fread (data, sizeof (size_t), n, stream); if (items != n) { GSL_ERROR ("fread failed", GSL_EFAILED); } return GSL_SUCCESS; } int gsl_permutation_fwrite (FILE * stream, const gsl_permutation * p) { size_t n = p->size ; size_t * data = p->data ; size_t items = fwrite (data, sizeof (size_t), n, stream); if (items != n) { GSL_ERROR ("fwrite failed", GSL_EFAILED); } return GSL_SUCCESS; } int gsl_permutation_fprintf (FILE * stream, const gsl_permutation * p, const char *format) { size_t n = p->size ; size_t * data = p->data ; size_t i; for (i = 0; i < n; i++) { int status = fprintf (stream, format, data[i]); if (status < 0) { GSL_ERROR ("fprintf failed", GSL_EFAILED); } } return GSL_SUCCESS; } int gsl_permutation_fscanf (FILE * stream, gsl_permutation * p) { size_t n = p->size ; size_t * data = p->data ; size_t i; for (i = 0; i < n; i++) { unsigned long j ; /* FIXME: what if size_t != unsigned long ??? want read in size_t but have to read in unsigned long to avoid error from compiler */ int status = fscanf (stream, IN_FORMAT, &j); if (status != 1) { GSL_ERROR ("fscanf failed", GSL_EFAILED); } data[i] = j; } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_permutation__init.c000066400000000000000000000042231261542461700220720ustar00rootroot00000000000000/* permutation/init.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_permutation.h" gsl_permutation * gsl_permutation_alloc (const size_t n) { gsl_permutation * p; if (n == 0) { GSL_ERROR_VAL ("permutation length n must be positive integer", GSL_EDOM, 0); } p = (gsl_permutation *) malloc (sizeof (gsl_permutation)); if (p == 0) { GSL_ERROR_VAL ("failed to allocate space for permutation struct", GSL_ENOMEM, 0); } p->data = (size_t *) malloc (n * sizeof (size_t)); if (p->data == 0) { free (p); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for permutation data", GSL_ENOMEM, 0); } p->size = n; return p; } gsl_permutation * gsl_permutation_calloc (const size_t n) { size_t i; gsl_permutation * p = gsl_permutation_alloc (n); if (p == 0) return 0; /* initialize permutation to identity */ for (i = 0; i < n; i++) { p->data[i] = i; } return p; } void gsl_permutation_init (gsl_permutation * p) { const size_t n = p->size ; size_t i; /* initialize permutation to identity */ for (i = 0; i < n; i++) { p->data[i] = i; } } void gsl_permutation_free (gsl_permutation * p) { free (p->data); free (p); } praat-6.0.04/external/gsl/gsl_permutation__permutation.c000066400000000000000000000127051261542461700235020ustar00rootroot00000000000000/* permutation/permutation.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_permutation.h" size_t gsl_permutation_size (const gsl_permutation * p) { return p->size ; } size_t * gsl_permutation_data (const gsl_permutation * p) { return p->data ; } #ifndef HIDE_INLINE_STATIC size_t gsl_permutation_get (const gsl_permutation * p, const size_t i) { if (gsl_check_range) { if (i >= p->size) /* size_t is unsigned, can't be negative */ { GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); } } return p->data[i]; } #endif int gsl_permutation_swap (gsl_permutation * p, const size_t i, const size_t j) { const size_t size = p->size ; if (i >= size) { GSL_ERROR("first index is out of range", GSL_EINVAL); } if (j >= size) { GSL_ERROR("second index is out of range", GSL_EINVAL); } if (i != j) { size_t tmp = p->data[i]; p->data[i] = p->data[j]; p->data[j] = tmp; } return GSL_SUCCESS; } int gsl_permutation_valid (gsl_permutation * p) { const size_t size = p->size ; size_t i, j ; for (i = 0; i < size; i++) { if (p->data[i] >= size) { GSL_ERROR("permutation index outside range", GSL_FAILURE) ; } for (j = 0; j < i; j++) { if (p->data[i] == p->data[j]) { GSL_ERROR("duplicate permutation index", GSL_FAILURE) ; } } } return GSL_SUCCESS; } void gsl_permutation_reverse (gsl_permutation * p) { const size_t size = p->size ; size_t i ; for (i = 0; i < (size / 2); i++) { size_t j = size - i - 1; size_t tmp = p->data[i] ; p->data[i] = p->data[j] ; p->data[j] = tmp ; } } int gsl_permutation_inverse (gsl_permutation * inv, const gsl_permutation * p) { const size_t size = p->size ; size_t i ; if (inv->size != size) { GSL_ERROR("permutation lengths are not equal", GSL_EBADLEN); } for (i = 0; i < size; i++) { inv->data[p->data[i]] = i ; } return GSL_SUCCESS ; } int gsl_permutation_next (gsl_permutation * p) { /* Replaces p with the next permutation (in the standard lexicographical * ordering). Returns GSL_FAILURE if there is no next permutation. */ const size_t size = p->size; size_t i, j, k; if (size < 2) { return GSL_FAILURE; } i = size - 2; while ((p->data[i] > p->data[i+1]) && (i != 0)) { i--; } if ((i == 0) && (p->data[0] > p->data[1])) { return GSL_FAILURE; } k = i + 1; for (j = i + 2; j < size; j++ ) { if ((p->data[j] > p->data[i]) && (p->data[j] < p->data[k])) { k = j; } } /* swap i and k */ { size_t tmp = p->data[i]; p->data[i] = p->data[k]; p->data[k] = tmp; } for (j = i + 1; j <= ((size + i) / 2); j++) { size_t tmp = p->data[j]; p->data[j] = p->data[size + i - j]; p->data[size + i - j] = tmp; } return GSL_SUCCESS; } int gsl_permutation_prev (gsl_permutation * p) { const size_t size = p->size; size_t i, j, k; if (size < 2) { return GSL_FAILURE; } i = size - 2; while ((p->data[i] < p->data[i+1]) && (i != 0)) { i--; } if ((i == 0) && (p->data[0] < p->data[1])) { return GSL_FAILURE; } k = i + 1; for (j = i + 2; j < size; j++ ) { if ((p->data[j] < p->data[i]) && (p->data[j] > p->data[k])) { k = j; } } /* swap i and k */ { size_t tmp = p->data[i]; p->data[i] = p->data[k]; p->data[k] = tmp; } for (j = i + 1; j <= ((size + i) / 2); j++) { size_t tmp = p->data[j]; p->data[j] = p->data[size + i - j]; p->data[size + i - j] = tmp; } return GSL_SUCCESS; } int gsl_permutation_mul (gsl_permutation * p, const gsl_permutation * pa, const gsl_permutation * pb) { size_t i; const size_t size = p->size; if (pa->size != size) { GSL_ERROR("size of result does not match size of pa", GSL_EINVAL); } if (pb->size != size) { GSL_ERROR("size of result does not match size of pb", GSL_EINVAL); } for (i = 0; i < size; i++) { p->data[i] = pb->data[pa->data[i]]; } return GSL_SUCCESS; } int gsl_permutation_memcpy (gsl_permutation * dest, const gsl_permutation * src) { const size_t src_size = src->size; const size_t dest_size = dest->size; if (src_size != dest_size) { GSL_ERROR ("permutation lengths are not equal", GSL_EBADLEN); } { size_t j; for (j = 0; j < src_size; j++) { dest->data[j] = src->data[j]; } } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_permutation__permute.c000066400000000000000000000040771261542461700226170ustar00rootroot00000000000000#include "gsl__config.h" #include "gsl_errno.h" #include "gsl_vector.h" #include "gsl_permute.h" #include "gsl_permute_vector.h" #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_permutation__permute_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_permutation__permute_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_permutation__permute_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_permutation__permute_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_permutation__permute_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_permutation__permute_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_permutation__permute_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_permutation__permute_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_permutation__permute_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_permutation__permute_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_permutation__permute_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_permutation__permute_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_permutation__permute_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_permutation__permute_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_permutation__permute_source.c000066400000000000000000000075631261542461700242020ustar00rootroot00000000000000/* permutation/permute_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* In-place Permutations permute: OUT[i] = IN[perm[i]] i = 0 .. N-1 invpermute: OUT[perm[i]] = IN[i] i = 0 .. N-1 PERM is an index map, i.e. a vector which contains a permutation of the integers 0 .. N-1. From Knuth "Sorting and Searching", Volume 3 (3rd ed), Section 5.2 Exercise 10 (answers), p 617 FIXME: these have not been fully tested. */ int TYPE (gsl_permute) (const size_t * p, ATOMIC * data, const size_t stride, const size_t n) { size_t i, k, pk; for (i = 0; i < n; i++) { k = p[i]; while (k > i) k = p[k]; if (k < i) continue ; /* Now have k == i, i.e the least in its cycle */ pk = p[k]; if (pk == i) continue ; /* shuffle the elements of the cycle */ { unsigned int a; ATOMIC t[MULTIPLICITY]; for (a = 0; a < MULTIPLICITY; a++) t[a] = data[i*stride*MULTIPLICITY + a]; while (pk != i) { for (a = 0; a < MULTIPLICITY; a++) { ATOMIC r1 = data[pk*stride*MULTIPLICITY + a]; data[k*stride*MULTIPLICITY + a] = r1; } k = pk; pk = p[k]; }; for (a = 0; a < MULTIPLICITY; a++) data[k*stride*MULTIPLICITY + a] = t[a]; } } return GSL_SUCCESS; } int FUNCTION (gsl_permute,inverse) (const size_t * p, ATOMIC * data, const size_t stride, const size_t n) { size_t i, k, pk; for (i = 0; i < n; i++) { k = p[i]; while (k > i) k = p[k]; if (k < i) continue ; /* Now have k == i, i.e the least in its cycle */ pk = p[k]; if (pk == i) continue ; /* shuffle the elements of the cycle in the inverse direction */ { unsigned int a; ATOMIC t[MULTIPLICITY]; for (a = 0; a < MULTIPLICITY; a++) t[a] = data[k*stride*MULTIPLICITY+a]; while (pk != i) { for (a = 0; a < MULTIPLICITY; a++) { ATOMIC r1 = data[pk*stride*MULTIPLICITY + a]; data[pk*stride*MULTIPLICITY + a] = t[a]; t[a] = r1; } k = pk; pk = p[k]; }; for (a = 0; a < MULTIPLICITY; a++) data[pk*stride*MULTIPLICITY+a] = t[a]; } } return GSL_SUCCESS; } int TYPE (gsl_permute_vector) (const gsl_permutation * p, TYPE (gsl_vector) * v) { if (v->size != p->size) { GSL_ERROR ("vector and permutation must be the same length", GSL_EBADLEN); } TYPE (gsl_permute) (p->data, v->data, v->stride, v->size) ; return GSL_SUCCESS; } int FUNCTION (gsl_permute_vector,inverse) (const gsl_permutation * p, TYPE (gsl_vector) * v) { if (v->size != p->size) { GSL_ERROR ("vector and permutation must be the same length", GSL_EBADLEN); } FUNCTION (gsl_permute,inverse) (p->data, v->data, v->stride, v->size) ; return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_permute.h000066400000000000000000000010561261542461700200300ustar00rootroot00000000000000#ifndef __GSL_PERMUTE_H__ #define __GSL_PERMUTE_H__ #include "gsl_permute_complex_long_double.h" #include "gsl_permute_complex_double.h" #include "gsl_permute_complex_float.h" #include "gsl_permute_long_double.h" #include "gsl_permute_double.h" #include "gsl_permute_float.h" #include "gsl_permute_ulong.h" #include "gsl_permute_long.h" #include "gsl_permute_uint.h" #include "gsl_permute_int.h" #include "gsl_permute_ushort.h" #include "gsl_permute_short.h" #include "gsl_permute_uchar.h" #include "gsl_permute_char.h" #endif /* __GSL_PERMUTE_H__ */ praat-6.0.04/external/gsl/gsl_permute_char.h000066400000000000000000000026161261542461700210300ustar00rootroot00000000000000/* permutation/gsl_permute_char.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_CHAR_H__ #define __GSL_PERMUTE_CHAR_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_char (const size_t * p, char * data, const size_t stride, const size_t n); int gsl_permute_char_inverse (const size_t * p, char * data, const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_PERMUTE_CHAR_H__ */ praat-6.0.04/external/gsl/gsl_permute_complex_double.h000066400000000000000000000027311261542461700231120ustar00rootroot00000000000000/* permutation/gsl_permute_complex_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_COMPLEX_DOUBLE_H__ #define __GSL_PERMUTE_COMPLEX_DOUBLE_H__ #include #include "gsl_errno.h" #include "gsl_complex.h" #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_complex (const size_t * p, double * data, const size_t stride, const size_t n); int gsl_permute_complex_inverse (const size_t * p, double * data, const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_PERMUTE_COMPLEX_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_permute_complex_float.h000066400000000000000000000027371261542461700227530ustar00rootroot00000000000000/* permutation/gsl_permute_complex_float.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_COMPLEX_FLOAT_H__ #define __GSL_PERMUTE_COMPLEX_FLOAT_H__ #include #include "gsl_errno.h" #include "gsl_complex.h" #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_complex_float (const size_t * p, float * data, const size_t stride, const size_t n); int gsl_permute_complex_float_inverse (const size_t * p, float * data, const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_PERMUTE_COMPLEX_FLOAT_H__ */ praat-6.0.04/external/gsl/gsl_permute_complex_long_double.h000066400000000000000000000030171261542461700241270ustar00rootroot00000000000000/* permutation/gsl_permute_complex_long_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_COMPLEX_LONG_DOUBLE_H__ #define __GSL_PERMUTE_COMPLEX_LONG_DOUBLE_H__ #include #include "gsl_errno.h" #include "gsl_complex.h" #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_complex_long_double (const size_t * p, long double * data, const size_t stride, const size_t n); int gsl_permute_complex_long_double_inverse (const size_t * p, long double * data, const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_PERMUTE_COMPLEX_LONG_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_permute_double.h000066400000000000000000000026201261542461700213600ustar00rootroot00000000000000/* permutation/gsl_permute_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_DOUBLE_H__ #define __GSL_PERMUTE_DOUBLE_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute (const size_t * p, double * data, const size_t stride, const size_t n); int gsl_permute_inverse (const size_t * p, double * data, const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_PERMUTE_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_permute_float.h000066400000000000000000000026261261542461700212210ustar00rootroot00000000000000/* permutation/gsl_permute_float.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_FLOAT_H__ #define __GSL_PERMUTE_FLOAT_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_float (const size_t * p, float * data, const size_t stride, const size_t n); int gsl_permute_float_inverse (const size_t * p, float * data, const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_PERMUTE_FLOAT_H__ */ praat-6.0.04/external/gsl/gsl_permute_int.h000066400000000000000000000026061261542461700207040ustar00rootroot00000000000000/* permutation/gsl_permute_int.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_INT_H__ #define __GSL_PERMUTE_INT_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_int (const size_t * p, int * data, const size_t stride, const size_t n); int gsl_permute_int_inverse (const size_t * p, int * data, const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_PERMUTE_INT_H__ */ praat-6.0.04/external/gsl/gsl_permute_long.h000066400000000000000000000026161261542461700210520ustar00rootroot00000000000000/* permutation/gsl_permute_long.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_LONG_H__ #define __GSL_PERMUTE_LONG_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_long (const size_t * p, long * data, const size_t stride, const size_t n); int gsl_permute_long_inverse (const size_t * p, long * data, const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_PERMUTE_LONG_H__ */ praat-6.0.04/external/gsl/gsl_permute_long_double.h000066400000000000000000000027061261542461700224040ustar00rootroot00000000000000/* permutation/gsl_permute_long_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_LONG_DOUBLE_H__ #define __GSL_PERMUTE_LONG_DOUBLE_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_long_double (const size_t * p, long double * data, const size_t stride, const size_t n); int gsl_permute_long_double_inverse (const size_t * p, long double * data, const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_PERMUTE_LONG_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_permute_short.h000066400000000000000000000026261261542461700212530ustar00rootroot00000000000000/* permutation/gsl_permute_short.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_SHORT_H__ #define __GSL_PERMUTE_SHORT_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_short (const size_t * p, short * data, const size_t stride, const size_t n); int gsl_permute_short_inverse (const size_t * p, short * data, const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_PERMUTE_SHORT_H__ */ praat-6.0.04/external/gsl/gsl_permute_uchar.h000066400000000000000000000026461261542461700212200ustar00rootroot00000000000000/* permutation/gsl_permute_uchar.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_UCHAR_H__ #define __GSL_PERMUTE_UCHAR_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_uchar (const size_t * p, unsigned char * data, const size_t stride, const size_t n); int gsl_permute_uchar_inverse (const size_t * p, unsigned char * data, const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_PERMUTE_UCHAR_H__ */ praat-6.0.04/external/gsl/gsl_permute_uint.h000066400000000000000000000026361261542461700210740ustar00rootroot00000000000000/* permutation/gsl_permute_uint.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_UINT_H__ #define __GSL_PERMUTE_UINT_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_uint (const size_t * p, unsigned int * data, const size_t stride, const size_t n); int gsl_permute_uint_inverse (const size_t * p, unsigned int * data, const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_PERMUTE_UINT_H__ */ praat-6.0.04/external/gsl/gsl_permute_ulong.h000066400000000000000000000026461261542461700212420ustar00rootroot00000000000000/* permutation/gsl_permute_ulong.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_ULONG_H__ #define __GSL_PERMUTE_ULONG_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_ulong (const size_t * p, unsigned long * data, const size_t stride, const size_t n); int gsl_permute_ulong_inverse (const size_t * p, unsigned long * data, const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_PERMUTE_ULONG_H__ */ praat-6.0.04/external/gsl/gsl_permute_ushort.h000066400000000000000000000026561261542461700214430ustar00rootroot00000000000000/* permutation/gsl_permute_ushort.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_USHORT_H__ #define __GSL_PERMUTE_USHORT_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_ushort (const size_t * p, unsigned short * data, const size_t stride, const size_t n); int gsl_permute_ushort_inverse (const size_t * p, unsigned short * data, const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_PERMUTE_USHORT_H__ */ praat-6.0.04/external/gsl/gsl_permute_vector.h000066400000000000000000000012451261542461700214120ustar00rootroot00000000000000#ifndef __GSL_PERMUTE_VECTOR_H__ #define __GSL_PERMUTE_VECTOR_H__ #include "gsl_permute_vector_complex_long_double.h" #include "gsl_permute_vector_complex_double.h" #include "gsl_permute_vector_complex_float.h" #include "gsl_permute_vector_long_double.h" #include "gsl_permute_vector_double.h" #include "gsl_permute_vector_float.h" #include "gsl_permute_vector_ulong.h" #include "gsl_permute_vector_long.h" #include "gsl_permute_vector_uint.h" #include "gsl_permute_vector_int.h" #include "gsl_permute_vector_ushort.h" #include "gsl_permute_vector_short.h" #include "gsl_permute_vector_uchar.h" #include "gsl_permute_vector_char.h" #endif /* __GSL_PERMUTE_VECTOR_H__ */ praat-6.0.04/external/gsl/gsl_permute_vector_char.h000066400000000000000000000026551261542461700224150ustar00rootroot00000000000000/* permutation/gsl_permute_vector_char.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_VECTOR_CHAR_H__ #define __GSL_PERMUTE_VECTOR_CHAR_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_vector_char.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_vector_char (const gsl_permutation * p, gsl_vector_char * v); int gsl_permute_vector_char_inverse (const gsl_permutation * p, gsl_vector_char * v); __END_DECLS #endif /* __GSL_PERMUTE_VECTOR_CHAR_H__ */ praat-6.0.04/external/gsl/gsl_permute_vector_complex_double.h000066400000000000000000000027531261542461700245000ustar00rootroot00000000000000/* permutation/gsl_permute_vector_complex_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_VECTOR_COMPLEX_DOUBLE_H__ #define __GSL_PERMUTE_VECTOR_COMPLEX_DOUBLE_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_vector_complex_double.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_vector_complex (const gsl_permutation * p, gsl_vector_complex * v); int gsl_permute_vector_complex_inverse (const gsl_permutation * p, gsl_vector_complex * v); __END_DECLS #endif /* __GSL_PERMUTE_VECTOR_COMPLEX_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_permute_vector_complex_float.h000066400000000000000000000027761261542461700243400ustar00rootroot00000000000000/* permutation/gsl_permute_vector_complex_float.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_VECTOR_COMPLEX_FLOAT_H__ #define __GSL_PERMUTE_VECTOR_COMPLEX_FLOAT_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_vector_complex_float.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_vector_complex_float (const gsl_permutation * p, gsl_vector_complex_float * v); int gsl_permute_vector_complex_float_inverse (const gsl_permutation * p, gsl_vector_complex_float * v); __END_DECLS #endif /* __GSL_PERMUTE_VECTOR_COMPLEX_FLOAT_H__ */ praat-6.0.04/external/gsl/gsl_permute_vector_complex_long_double.h000066400000000000000000000030641261542461700255130ustar00rootroot00000000000000/* permutation/gsl_permute_vector_complex_long_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_VECTOR_COMPLEX_LONG_DOUBLE_H__ #define __GSL_PERMUTE_VECTOR_COMPLEX_LONG_DOUBLE_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_vector_complex_long_double.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_vector_complex_long_double (const gsl_permutation * p, gsl_vector_complex_long_double * v); int gsl_permute_vector_complex_long_double_inverse (const gsl_permutation * p, gsl_vector_complex_long_double * v); __END_DECLS #endif /* __GSL_PERMUTE_VECTOR_COMPLEX_LONG_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_permute_vector_double.h000066400000000000000000000026431261542461700227470ustar00rootroot00000000000000/* permutation/gsl_permute_vector_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_VECTOR_DOUBLE_H__ #define __GSL_PERMUTE_VECTOR_DOUBLE_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_vector_double.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_vector (const gsl_permutation * p, gsl_vector * v); int gsl_permute_vector_inverse (const gsl_permutation * p, gsl_vector * v); __END_DECLS #endif /* __GSL_PERMUTE_VECTOR_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_permute_vector_float.h000066400000000000000000000026661261542461700226070ustar00rootroot00000000000000/* permutation/gsl_permute_vector_float.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_VECTOR_FLOAT_H__ #define __GSL_PERMUTE_VECTOR_FLOAT_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_vector_float.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_vector_float (const gsl_permutation * p, gsl_vector_float * v); int gsl_permute_vector_float_inverse (const gsl_permutation * p, gsl_vector_float * v); __END_DECLS #endif /* __GSL_PERMUTE_VECTOR_FLOAT_H__ */ praat-6.0.04/external/gsl/gsl_permute_vector_int.h000066400000000000000000000026441261542461700222700ustar00rootroot00000000000000/* permutation/gsl_permute_vector_int.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_VECTOR_INT_H__ #define __GSL_PERMUTE_VECTOR_INT_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_vector_int.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_vector_int (const gsl_permutation * p, gsl_vector_int * v); int gsl_permute_vector_int_inverse (const gsl_permutation * p, gsl_vector_int * v); __END_DECLS #endif /* __GSL_PERMUTE_VECTOR_INT_H__ */ praat-6.0.04/external/gsl/gsl_permute_vector_long.h000066400000000000000000000026551261542461700224370ustar00rootroot00000000000000/* permutation/gsl_permute_vector_long.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_VECTOR_LONG_H__ #define __GSL_PERMUTE_VECTOR_LONG_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_vector_long.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_vector_long (const gsl_permutation * p, gsl_vector_long * v); int gsl_permute_vector_long_inverse (const gsl_permutation * p, gsl_vector_long * v); __END_DECLS #endif /* __GSL_PERMUTE_VECTOR_LONG_H__ */ praat-6.0.04/external/gsl/gsl_permute_vector_long_double.h000066400000000000000000000027541261542461700237710ustar00rootroot00000000000000/* permutation/gsl_permute_vector_long_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_VECTOR_LONG_DOUBLE_H__ #define __GSL_PERMUTE_VECTOR_LONG_DOUBLE_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_vector_long_double.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_vector_long_double (const gsl_permutation * p, gsl_vector_long_double * v); int gsl_permute_vector_long_double_inverse (const gsl_permutation * p, gsl_vector_long_double * v); __END_DECLS #endif /* __GSL_PERMUTE_VECTOR_LONG_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_permute_vector_short.h000066400000000000000000000026661261542461700226410ustar00rootroot00000000000000/* permutation/gsl_permute_vector_short.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_VECTOR_SHORT_H__ #define __GSL_PERMUTE_VECTOR_SHORT_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_vector_short.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_vector_short (const gsl_permutation * p, gsl_vector_short * v); int gsl_permute_vector_short_inverse (const gsl_permutation * p, gsl_vector_short * v); __END_DECLS #endif /* __GSL_PERMUTE_VECTOR_SHORT_H__ */ praat-6.0.04/external/gsl/gsl_permute_vector_uchar.h000066400000000000000000000026661261542461700226040ustar00rootroot00000000000000/* permutation/gsl_permute_vector_uchar.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_VECTOR_UCHAR_H__ #define __GSL_PERMUTE_VECTOR_UCHAR_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_vector_uchar.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_vector_uchar (const gsl_permutation * p, gsl_vector_uchar * v); int gsl_permute_vector_uchar_inverse (const gsl_permutation * p, gsl_vector_uchar * v); __END_DECLS #endif /* __GSL_PERMUTE_VECTOR_UCHAR_H__ */ praat-6.0.04/external/gsl/gsl_permute_vector_uint.h000066400000000000000000000026551261542461700224570ustar00rootroot00000000000000/* permutation/gsl_permute_vector_uint.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_VECTOR_UINT_H__ #define __GSL_PERMUTE_VECTOR_UINT_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_vector_uint.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_vector_uint (const gsl_permutation * p, gsl_vector_uint * v); int gsl_permute_vector_uint_inverse (const gsl_permutation * p, gsl_vector_uint * v); __END_DECLS #endif /* __GSL_PERMUTE_VECTOR_UINT_H__ */ praat-6.0.04/external/gsl/gsl_permute_vector_ulong.h000066400000000000000000000026661261542461700226260ustar00rootroot00000000000000/* permutation/gsl_permute_vector_ulong.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_VECTOR_ULONG_H__ #define __GSL_PERMUTE_VECTOR_ULONG_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_vector_ulong.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_vector_ulong (const gsl_permutation * p, gsl_vector_ulong * v); int gsl_permute_vector_ulong_inverse (const gsl_permutation * p, gsl_vector_ulong * v); __END_DECLS #endif /* __GSL_PERMUTE_VECTOR_ULONG_H__ */ praat-6.0.04/external/gsl/gsl_permute_vector_ushort.h000066400000000000000000000026771261542461700230300ustar00rootroot00000000000000/* permutation/gsl_permute_vector_ushort.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_PERMUTE_VECTOR_USHORT_H__ #define __GSL_PERMUTE_VECTOR_USHORT_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_vector_ushort.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_permute_vector_ushort (const gsl_permutation * p, gsl_vector_ushort * v); int gsl_permute_vector_ushort_inverse (const gsl_permutation * p, gsl_vector_ushort * v); __END_DECLS #endif /* __GSL_PERMUTE_VECTOR_USHORT_H__ */ praat-6.0.04/external/gsl/gsl_poly.h000066400000000000000000000070421261542461700173330ustar00rootroot00000000000000/* poly/gsl_poly.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_POLY_H__ #define __GSL_POLY_H__ #include #include "gsl_complex.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Evaluate polynomial * * c[0] + c[1] x + c[2] x^2 + ... + c[len-1] x^(len-1) * * exceptions: none */ double gsl_poly_eval(const double c[], const int len, const double x); #ifdef HAVE_INLINE extern inline double gsl_poly_eval(const double c[], const int len, const double x) { int i; double ans = c[len-1]; for(i=len-1; i>0; i--) ans = c[i-1] + x * ans; return ans; } #endif /* HAVE_INLINE */ /* Work with divided-difference polynomials, Abramowitz & Stegun 25.2.26 */ int gsl_poly_dd_init (double dd[], const double x[], const double y[], size_t size); double gsl_poly_dd_eval (const double dd[], const double xa[], const size_t size, const double x); #ifdef HAVE_INLINE extern inline double gsl_poly_dd_eval(const double dd[], const double xa[], const size_t size, const double x) { size_t i; double y = dd[size - 1]; for (i = size - 1; i--;) y = dd[i] + (x - xa[i]) * y; return y; } #endif /* HAVE_INLINE */ int gsl_poly_dd_taylor (double c[], double xp, const double dd[], const double x[], size_t size, double w[]); /* Solve for real or complex roots of the standard quadratic equation, * returning the number of real roots. * * Roots are returned ordered. */ int gsl_poly_solve_quadratic (double a, double b, double c, double * x0, double * x1); int gsl_poly_complex_solve_quadratic (double a, double b, double c, gsl_complex * z0, gsl_complex * z1); /* Solve for real roots of the cubic equation * x^3 + a x^2 + b x + c = 0, returning the * number of real roots. * * Roots are returned ordered. */ int gsl_poly_solve_cubic (double a, double b, double c, double * x0, double * x1, double * x2); int gsl_poly_complex_solve_cubic (double a, double b, double c, gsl_complex * z0, gsl_complex * z1, gsl_complex * z2); /* Solve for the complex roots of a general real polynomial */ typedef struct { size_t nc ; double * matrix ; } gsl_poly_complex_workspace ; gsl_poly_complex_workspace * gsl_poly_complex_workspace_alloc (size_t n); void gsl_poly_complex_workspace_free (gsl_poly_complex_workspace * w); int gsl_poly_complex_solve (const double * a, size_t n, gsl_poly_complex_workspace * w, gsl_complex_packed_ptr z); __END_DECLS #endif /* __GSL_POLY_H__ */ praat-6.0.04/external/gsl/gsl_poly__balance.c000066400000000000000000000061511261542461700211320ustar00rootroot00000000000000/* poly/balance.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static void balance_companion_matrix (double *m, size_t n); #define RADIX 2 #define RADIX2 (RADIX*RADIX) static void balance_companion_matrix (double *m, size_t nc) { int not_converged = 1; double row_norm = 0; double col_norm = 0; while (not_converged) { size_t i, j; double g, f, s; not_converged = 0; for (i = 0; i < nc; i++) { /* column norm, excluding the diagonal */ if (i != nc - 1) { col_norm = fabs (MAT (m, i + 1, i, nc)); } else { col_norm = 0; for (j = 0; j < nc - 1; j++) { col_norm += fabs (MAT (m, j, nc - 1, nc)); } } /* row norm, excluding the diagonal */ if (i == 0) { row_norm = fabs (MAT (m, 0, nc - 1, nc)); } else if (i == nc - 1) { row_norm = fabs (MAT (m, i, i - 1, nc)); } else { row_norm = (fabs (MAT (m, i, i - 1, nc)) + fabs (MAT (m, i, nc - 1, nc))); } if (col_norm == 0 || row_norm == 0) { continue; } g = row_norm / RADIX; f = 1; s = col_norm + row_norm; while (col_norm < g) { f *= RADIX; col_norm *= RADIX2; } g = row_norm * RADIX; while (col_norm > g) { f /= RADIX; col_norm /= RADIX2; } if ((row_norm + col_norm) < 0.95 * s * f) { not_converged = 1; g = 1 / f; if (i == 0) { MAT (m, 0, nc - 1, nc) *= g; } else { MAT (m, i, i - 1, nc) *= g; MAT (m, i, nc - 1, nc) *= g; } if (i == nc - 1) { for (j = 0; j < nc; j++) { MAT (m, j, i, nc) *= f; } } else { MAT (m, i + 1, i, nc) *= f; } } } } } praat-6.0.04/external/gsl/gsl_poly__companion.c000066400000000000000000000022641261542461700215310ustar00rootroot00000000000000/* poly/companion.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static void set_companion_matrix (const double *a, size_t n, double *m); static void set_companion_matrix (const double *a, size_t nc, double *m) { size_t i, j; for (i = 0; i < nc; i++) for (j = 0; j < nc; j++) MAT (m, i, j, nc) = 0.0; for (i = 1; i < nc; i++) MAT (m, i, i - 1, nc) = 1.0; for (i = 0; i < nc; i++) MAT (m, i, nc - 1, nc) = -a[i] / a[nc]; } praat-6.0.04/external/gsl/gsl_poly__dd.c000066400000000000000000000044041261542461700201330ustar00rootroot00000000000000/* interpolation/interp_poly.c * * Copyright (C) 2001 DAN, HO-JIN * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Modified for standalone use in polynomial directory, B.Gough 2001 */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_poly.h" int gsl_poly_dd_init (double dd[], const double xa[], const double ya[], size_t size) { size_t i, j; /* Newton's divided differences */ dd[0] = ya[0]; for (j = size - 1; j >= 1; j--) { dd[j] = (ya[j] - ya[j - 1]) / (xa[j] - xa[j - 1]); } for (i = 2; i < size; i++) { for (j = size - 1; j >= i; j--) { dd[j] = (dd[j] - dd[j - 1]) / (xa[j] - xa[j - i]); } } return GSL_SUCCESS; } #ifndef HIDE_INLINE_STATIC double gsl_poly_dd_eval (const double dd[], const double xa[], const size_t size, const double x) { size_t i; double y = dd[size - 1]; for (i = size - 1; i--;) { y = dd[i] + (x - xa[i]) * y; } return y; } #endif int gsl_poly_dd_taylor (double c[], double xp, const double dd[], const double xa[], size_t size, double w[]) { size_t i, j; for (i = 0; i < size; i++) { c[i] = 0.0; w[i] = 0.0; } w[size - 1] = 1.0; c[0] = dd[0]; for (i = size - 1; i > 0 && i--;) { w[i] = -w[i + 1] * (xa[size - 2 - i] - xp); for (j = i + 1; j < size - 1; j++) { w[j] = w[j] - w[j + 1] * (xa[size - 2 - i] - xp); } for (j = i; j < size; j++) { c[j - i] += w[j] * dd[size - i - 1]; } } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_poly__eval.c000066400000000000000000000022561261542461700204760ustar00rootroot00000000000000/* poly/eval.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_poly.h" /*-*-*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*-*/ /* checked OK [GJ] Tue May 5 12:19:56 MDT 1998 */ #ifndef HIDE_INLINE_STATIC double gsl_poly_eval(const double c[], const int len, const double x) { int i; double ans = c[len-1]; for(i=len-1; i>0; i--) ans = c[i-1] + x * ans; return ans; } #endif praat-6.0.04/external/gsl/gsl_poly__qr.c000066400000000000000000000125341261542461700201710ustar00rootroot00000000000000/* poly/qr.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static int qr_companion (double *h, size_t nc, gsl_complex_packed_ptr z); static int qr_companion (double *h, size_t nc, gsl_complex_packed_ptr zroot) { double t = 0.0; size_t iterations, e, i, j, k, m; double w, x, y, s, z; double p = 0, q = 0, r = 0; /* FIXME: if p,q,r, are not set to zero then the compiler complains that they ``might be used uninitialized in this function''. Looking at the code this does seem possible, so this should be checked. */ int notlast; size_t n = nc; next_root: if (n == 0) return GSL_SUCCESS ; iterations = 0; next_iteration: for (e = n; e >= 2; e--) { double a1 = fabs (FMAT (h, e, e - 1, nc)); double a2 = fabs (FMAT (h, e - 1, e - 1, nc)); double a3 = fabs (FMAT (h, e, e, nc)); if (a1 <= GSL_DBL_EPSILON * (a2 + a3)) break; } x = FMAT (h, n, n, nc); if (e == n) { GSL_SET_COMPLEX_PACKED (zroot, n-1, x + t, 0); /* one real root */ n--; goto next_root; /*continue;*/ } y = FMAT (h, n - 1, n - 1, nc); w = FMAT (h, n - 1, n, nc) * FMAT (h, n, n - 1, nc); if (e == n - 1) { p = (y - x) / 2; q = p * p + w; y = sqrt (fabs (q)); x += t; if (q > 0) /* two real roots */ { if (p < 0) y = -y; y += p; GSL_SET_COMPLEX_PACKED (zroot, n-1, x - w / y, 0); GSL_SET_COMPLEX_PACKED (zroot, n-2, x + y, 0); } else { GSL_SET_COMPLEX_PACKED (zroot, n-1, x + p, -y); GSL_SET_COMPLEX_PACKED (zroot, n-2, x + p, y); } n -= 2; goto next_root; /*continue;*/ } /* No more roots found yet, do another iteration */ if (iterations == 60) /* increased from 30 to 60 */ { /* too many iterations - give up! */ return GSL_FAILURE ; } if (iterations % 10 == 0 && iterations > 0) { /* use an exceptional shift */ t += x; for (i = 1; i <= n; i++) { FMAT (h, i, i, nc) -= x; } s = fabs (FMAT (h, n, n - 1, nc)) + fabs (FMAT (h, n - 1, n - 2, nc)); y = 0.75 * s; x = y; w = -0.4375 * s * s; } iterations++; for (m = n - 2; m >= e; m--) { double a1, a2, a3; z = FMAT (h, m, m, nc); r = x - z; s = y - z; p = FMAT (h, m, m + 1, nc) + (r * s - w) / FMAT (h, m + 1, m, nc); q = FMAT (h, m + 1, m + 1, nc) - z - r - s; r = FMAT (h, m + 2, m + 1, nc); s = fabs (p) + fabs (q) + fabs (r); p /= s; q /= s; r /= s; if (m == e) break; a1 = fabs (FMAT (h, m, m - 1, nc)); a2 = fabs (FMAT (h, m - 1, m - 1, nc)); a3 = fabs (FMAT (h, m + 1, m + 1, nc)); if (a1 * (fabs (q) + fabs (r)) <= GSL_DBL_EPSILON * fabs (p) * (a2 + a3)) break; } for (i = m + 2; i <= n; i++) { FMAT (h, i, i - 2, nc) = 0; } for (i = m + 3; i <= n; i++) { FMAT (h, i, i - 3, nc) = 0; } /* double QR step */ for (k = m; k <= n - 1; k++) { notlast = (k != n - 1); if (k != m) { p = FMAT (h, k, k - 1, nc); q = FMAT (h, k + 1, k - 1, nc); r = notlast ? FMAT (h, k + 2, k - 1, nc) : 0.0; x = fabs (p) + fabs (q) + fabs (r); if (x == 0) continue; /* FIXME????? */ p /= x; q /= x; r /= x; } s = sqrt (p * p + q * q + r * r); if (p < 0) s = -s; if (k != m) { FMAT (h, k, k - 1, nc) = -s * x; } else if (e != m) { FMAT (h, k, k - 1, nc) *= -1; } p += s; x = p / s; y = q / s; z = r / s; q /= p; r /= p; /* do row modifications */ for (j = k; j <= n; j++) { p = FMAT (h, k, j, nc) + q * FMAT (h, k + 1, j, nc); if (notlast) { p += r * FMAT (h, k + 2, j, nc); FMAT (h, k + 2, j, nc) -= p * z; } FMAT (h, k + 1, j, nc) -= p * y; FMAT (h, k, j, nc) -= p * x; } j = (k + 3 < n) ? (k + 3) : n; /* do column modifications */ for (i = e; i <= j; i++) { p = x * FMAT (h, i, k, nc) + y * FMAT (h, i, k + 1, nc); if (notlast) { p += z * FMAT (h, i, k + 2, nc); FMAT (h, i, k + 2, nc) -= p * r; } FMAT (h, i, k + 1, nc) -= p * q; FMAT (h, i, k, nc) -= p; } } goto next_iteration; } praat-6.0.04/external/gsl/gsl_poly__solve_cubic.c000066400000000000000000000056751261542461700220540ustar00rootroot00000000000000/* poly/solve_cubic.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* solve_cubic.c - finds the real roots of x^3 + a x^2 + b x + c = 0 */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_poly.h" #define SWAP(a,b) do { double tmp = b ; b = a ; a = tmp ; } while(0) int gsl_poly_solve_cubic (double a, double b, double c, double *x0, double *x1, double *x2) { double q = (a * a - 3 * b); double r = (2 * a * a * a - 9 * a * b + 27 * c); double Q = q / 9; double R = r / 54; double Q3 = Q * Q * Q; double R2 = R * R; double CR2 = 729 * r * r; double CQ3 = 2916 * q * q * q; if (R == 0 && Q == 0) { *x0 = - a / 3 ; *x1 = - a / 3 ; *x2 = - a / 3 ; return 3 ; } else if (CR2 == CQ3) { /* this test is actually R2 == Q3, written in a form suitable for exact computation with integers */ /* Due to finite precision some double roots may be missed, and considered to be a pair of complex roots z = x +/- epsilon i close to the real axis. */ double sqrtQ = sqrt (Q); if (R > 0) { *x0 = -2 * sqrtQ - a / 3; *x1 = sqrtQ - a / 3; *x2 = sqrtQ - a / 3; } else { *x0 = - sqrtQ - a / 3; *x1 = - sqrtQ - a / 3; *x2 = 2 * sqrtQ - a / 3; } return 3 ; } else if (CR2 < CQ3) /* equivalent to R2 < Q3 */ { double sqrtQ = sqrt (Q); double sqrtQ3 = sqrtQ * sqrtQ * sqrtQ; double theta = acos (R / sqrtQ3); double norm = -2 * sqrtQ; *x0 = norm * cos (theta / 3) - a / 3; *x1 = norm * cos ((theta + 2.0 * M_PI) / 3) - a / 3; *x2 = norm * cos ((theta - 2.0 * M_PI) / 3) - a / 3; /* Sort *x0, *x1, *x2 into increasing order */ if (*x0 > *x1) SWAP(*x0, *x1) ; if (*x1 > *x2) { SWAP(*x1, *x2) ; if (*x0 > *x1) SWAP(*x0, *x1) ; } return 3; } else { double sgnR = (R >= 0 ? 1 : -1); double A = -sgnR * pow (fabs (R) + sqrt (R2 - Q3), 1.0/3.0); double B = Q / A ; *x0 = A + B - a / 3; return 1; } } praat-6.0.04/external/gsl/gsl_poly__solve_quadratic.c000066400000000000000000000037301261542461700227320ustar00rootroot00000000000000/* poly/solve_quadratic.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* solve_quadratic.c - finds the real roots of a x^2 + b x + c = 0 */ #include "gsl__config.h" #include #include "gsl_poly.h" int gsl_poly_solve_quadratic (double a, double b, double c, double *x0, double *x1) { double disc = b * b - 4 * a * c; if (a == 0) /* Handle linear case */ { if (b == 0) { return 0; } else { *x0 = -c / b; return 1; }; } if (disc > 0) { if (b == 0) { double r = fabs (0.5 * sqrt (disc) / a); *x0 = -r; *x1 = r; } else { double sgnb = (b > 0 ? 1 : -1); double temp = -0.5 * (b + sgnb * sqrt (disc)); double r1 = temp / a ; double r2 = c / temp ; if (r1 < r2) { *x0 = r1 ; *x1 = r2 ; } else { *x0 = r2 ; *x1 = r1 ; } } return 2; } else if (disc == 0) { *x0 = -0.5 * b / a ; *x1 = -0.5 * b / a ; return 2 ; } else { return 0; } } praat-6.0.04/external/gsl/gsl_poly__zsolve.c000066400000000000000000000041451261542461700210700ustar00rootroot00000000000000/* poly/zsolve.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* zsolve.c - finds the complex roots of = 0 */ #include "gsl__config.h" #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_complex.h" #include "gsl_poly.h" /* C-style matrix elements */ #define MAT(m,i,j,n) ((m)[(i)*(n) + (j)]) /* Fortran-style matrix elements */ #define FMAT(m,i,j,n) ((m)[((i)-1)*(n) + ((j)-1)]) #include "gsl_poly__companion.c" #include "gsl_poly__balance.c" #include "gsl_poly__qr.c" int gsl_poly_complex_solve (const double *a, size_t n, gsl_poly_complex_workspace * w, gsl_complex_packed_ptr z) { int status; double *m; if (n == 0) { GSL_ERROR ("number of terms must be a positive integer", GSL_EINVAL); } if (n == 1) { GSL_ERROR ("cannot solve for only one term", GSL_EINVAL); } if (a[n - 1] == 0) { GSL_ERROR ("leading term of polynomial must be non-zero", GSL_EINVAL) ; } if (w->nc != n - 1) { GSL_ERROR ("size of workspace does not match polynomial", GSL_EINVAL); } m = w->matrix; set_companion_matrix (a, n - 1, m); balance_companion_matrix (m, n - 1); status = qr_companion (m, n - 1, z); if (status) { GSL_ERROR("root solving qr method failed to converge", GSL_EFAILED); } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_poly__zsolve_cubic.c000066400000000000000000000102111261542461700222240ustar00rootroot00000000000000/* poly/zsolve_cubic.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* zsolve_cubic.c - finds the complex roots of x^3 + a x^2 + b x + c = 0 */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_complex.h" #include "gsl_poly.h" #define SWAP(a,b) do { double tmp = b ; b = a ; a = tmp ; } while(0) int gsl_poly_complex_solve_cubic (double a, double b, double c, gsl_complex *z0, gsl_complex *z1, gsl_complex *z2) { double q = (a * a - 3 * b); double r = (2 * a * a * a - 9 * a * b + 27 * c); double Q = q / 9; double R = r / 54; double Q3 = Q * Q * Q; double R2 = R * R; double CR2 = 729 * r * r; double CQ3 = 2916 * q * q * q; if (R == 0 && Q == 0) { GSL_REAL (*z0) = -a / 3; GSL_IMAG (*z0) = 0; GSL_REAL (*z1) = -a / 3; GSL_IMAG (*z1) = 0; GSL_REAL (*z2) = -a / 3; GSL_IMAG (*z2) = 0; return 3; } else if (CR2 == CQ3) { /* this test is actually R2 == Q3, written in a form suitable for exact computation with integers */ /* Due to finite precision some double roots may be missed, and will be considered to be a pair of complex roots z = x +/- epsilon i close to the real axis. */ double sqrtQ = sqrt (Q); if (R > 0) { GSL_REAL (*z0) = -2 * sqrtQ - a / 3; GSL_IMAG (*z0) = 0; GSL_REAL (*z1) = sqrtQ - a / 3; GSL_IMAG (*z1) = 0; GSL_REAL (*z2) = sqrtQ - a / 3; GSL_IMAG (*z2) = 0; } else { GSL_REAL (*z0) = -sqrtQ - a / 3; GSL_IMAG (*z0) = 0; GSL_REAL (*z1) = -sqrtQ - a / 3; GSL_IMAG (*z1) = 0; GSL_REAL (*z2) = 2 * sqrtQ - a / 3; GSL_IMAG (*z2) = 0; } return 3; } else if (CR2 < CQ3) /* equivalent to R2 < Q3 */ { double sqrtQ = sqrt (Q); double sqrtQ3 = sqrtQ * sqrtQ * sqrtQ; double theta = acos (R / sqrtQ3); double norm = -2 * sqrtQ; double r0 = norm * cos (theta / 3) - a / 3; double r1 = norm * cos ((theta + 2.0 * M_PI) / 3) - a / 3; double r2 = norm * cos ((theta - 2.0 * M_PI) / 3) - a / 3; /* Sort r0, r1, r2 into increasing order */ if (r0 > r1) SWAP (r0, r1); if (r1 > r2) { SWAP (r1, r2); if (r0 > r1) SWAP (r0, r1); } GSL_REAL (*z0) = r0; GSL_IMAG (*z0) = 0; GSL_REAL (*z1) = r1; GSL_IMAG (*z1) = 0; GSL_REAL (*z2) = r2; GSL_IMAG (*z2) = 0; return 3; } else { double sgnR = (R >= 0 ? 1 : -1); double A = -sgnR * pow (fabs (R) + sqrt (R2 - Q3), 1.0 / 3.0); double B = Q / A; if (A + B < 0) { GSL_REAL (*z0) = A + B - a / 3; GSL_IMAG (*z0) = 0; GSL_REAL (*z1) = -0.5 * (A + B) - a / 3; GSL_IMAG (*z1) = -(sqrt (3.0) / 2.0) * fabs(A - B); GSL_REAL (*z2) = -0.5 * (A + B) - a / 3; GSL_IMAG (*z2) = (sqrt (3.0) / 2.0) * fabs(A - B); } else { GSL_REAL (*z0) = -0.5 * (A + B) - a / 3; GSL_IMAG (*z0) = -(sqrt (3.0) / 2.0) * fabs(A - B); GSL_REAL (*z1) = -0.5 * (A + B) - a / 3; GSL_IMAG (*z1) = (sqrt (3.0) / 2.0) * fabs(A - B); GSL_REAL (*z2) = A + B - a / 3; GSL_IMAG (*z2) = 0; } return 3; } } praat-6.0.04/external/gsl/gsl_poly__zsolve_init.c000066400000000000000000000034261261542461700221140ustar00rootroot00000000000000/* poly/zsolve_init.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_complex.h" #include "gsl_poly.h" #include "gsl_errno.h" gsl_poly_complex_workspace * gsl_poly_complex_workspace_alloc (size_t n) { size_t nc ; gsl_poly_complex_workspace * w ; if (n == 0) { GSL_ERROR_VAL ("matrix size n must be positive integer", GSL_EDOM, 0); } w = (gsl_poly_complex_workspace *) malloc (sizeof(gsl_poly_complex_workspace)); if (w == 0) { GSL_ERROR_VAL ("failed to allocate space for struct", GSL_ENOMEM, 0); } nc = n - 1; w->nc = nc; w->matrix = (double *) malloc (nc * nc * sizeof(double)); if (w->matrix == 0) { free (w) ; /* error in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for workspace matrix", GSL_ENOMEM, 0); } return w ; } void gsl_poly_complex_workspace_free (gsl_poly_complex_workspace * w) { free(w->matrix) ; free(w); } praat-6.0.04/external/gsl/gsl_poly__zsolve_quadratic.c000066400000000000000000000050541261542461700231250ustar00rootroot00000000000000/* poly/zsolve_quadratic.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* complex_solve_quadratic.c - finds complex roots of a x^2 + b x + c = 0 */ #include "gsl__config.h" #include #include "gsl_complex.h" #include "gsl_poly.h" int gsl_poly_complex_solve_quadratic (double a, double b, double c, gsl_complex *z0, gsl_complex *z1) { double disc = b * b - 4 * a * c; if (a == 0) /* Handle linear case */ { if (b == 0) { return 0; } else { GSL_REAL(*z0) = -c / b; GSL_IMAG(*z0) = 0; return 1; }; } if (disc > 0) { if (b == 0) { double s = fabs (0.5 * sqrt (disc) / a); GSL_REAL (*z0) = -s; GSL_IMAG (*z0) = 0; GSL_REAL (*z1) = s; GSL_IMAG (*z1) = 0; } else { double sgnb = (b > 0 ? 1 : -1); double temp = -0.5 * (b + sgnb * sqrt (disc)); double r1 = temp / a; double r2 = c / temp; if (r1 < r2) { GSL_REAL (*z0) = r1; GSL_IMAG (*z0) = 0; GSL_REAL (*z1) = r2; GSL_IMAG (*z1) = 0; } else { GSL_REAL (*z0) = r2; GSL_IMAG (*z0) = 0; GSL_REAL (*z1) = r1; GSL_IMAG (*z1) = 0; } } return 2; } else if (disc == 0) { GSL_REAL (*z0) = -0.5 * b / a; GSL_IMAG (*z0) = 0; GSL_REAL (*z1) = -0.5 * b / a; GSL_IMAG (*z1) = 0; return 2; } else { double s = fabs (0.5 * sqrt (-disc) / a); GSL_REAL (*z0) = -0.5 * b / a; GSL_IMAG (*z0) = -s; GSL_REAL (*z1) = -0.5 * b / a; GSL_IMAG (*z1) = s; return 2; } } praat-6.0.04/external/gsl/gsl_pow_int.h000066400000000000000000000047601261542461700200330ustar00rootroot00000000000000/* gsl_pow_int.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_POW_INT_H__ #define __GSL_POW_INT_H__ #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS #ifdef HAVE_INLINE extern inline double gsl_pow_2(const double x); extern inline double gsl_pow_3(const double x); extern inline double gsl_pow_4(const double x); extern inline double gsl_pow_5(const double x); extern inline double gsl_pow_6(const double x); extern inline double gsl_pow_7(const double x); extern inline double gsl_pow_8(const double x); extern inline double gsl_pow_9(const double x); extern inline double gsl_pow_2(const double x) { return x*x; } extern inline double gsl_pow_3(const double x) { return x*x*x; } extern inline double gsl_pow_4(const double x) { double x2 = x*x; return x2*x2; } extern inline double gsl_pow_5(const double x) { double x2 = x*x; return x2*x2*x; } extern inline double gsl_pow_6(const double x) { double x2 = x*x; return x2*x2*x2; } extern inline double gsl_pow_7(const double x) { double x3 = x*x*x; return x3*x3*x; } extern inline double gsl_pow_8(const double x) { double x2 = x*x; double x4 = x2*x2; return x4*x4; } extern inline double gsl_pow_9(const double x) { double x3 = x*x*x; return x3*x3*x3; } #else double gsl_pow_2(const double x); double gsl_pow_3(const double x); double gsl_pow_4(const double x); double gsl_pow_5(const double x); double gsl_pow_6(const double x); double gsl_pow_7(const double x); double gsl_pow_8(const double x); double gsl_pow_9(const double x); #endif double gsl_pow_int(double x, int n); __END_DECLS #endif /* __GSL_POW_INT_H__ */ praat-6.0.04/external/gsl/gsl_precision.h000066400000000000000000000033601261542461700203420ustar00rootroot00000000000000/* gsl_precision.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: B. Gough and G. Jungman */ #ifndef __GSL_PRECISION_H__ #define __GSL_PRECISION_H__ #include "gsl_types.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* A type for the precision indicator. * This is mainly for pedagogy. */ typedef unsigned int gsl_prec_t; /* The number of precision types. * Remember that precision-mode * can index an array. */ #define _GSL_PREC_T_NUM 3 /* Arrays containing derived * precision constants for the * different precision levels. */ GSL_VAR const double gsl_prec_eps[]; GSL_VAR const double gsl_prec_sqrt_eps[]; GSL_VAR const double gsl_prec_root3_eps[]; GSL_VAR const double gsl_prec_root4_eps[]; GSL_VAR const double gsl_prec_root5_eps[]; GSL_VAR const double gsl_prec_root6_eps[]; __END_DECLS #endif /* __GSL_PRECISION_H__ */ praat-6.0.04/external/gsl/gsl_qrng.h000066400000000000000000000043031261542461700173140ustar00rootroot00000000000000/* Author: G. Jungman */ #ifndef __GSL_QRNG_H__ #define __GSL_QRNG_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Once again, more inane C-style OOP... kill me now. */ /* Structure describing a type of generator. */ typedef struct { const char * name; unsigned int max_dimension; size_t (*state_size) (unsigned int dimension); int (*init_state) (void * state, unsigned int dimension); int (*get) (void * state, unsigned int dimension, double x[]); } gsl_qrng_type; /* Structure describing a generator instance of a * specified type, with generator-specific state info * and dimension-specific info. */ typedef struct { const gsl_qrng_type * type; unsigned int dimension; size_t state_size; void * state; } gsl_qrng; /* Supported generator types. */ GSL_VAR const gsl_qrng_type * gsl_qrng_niederreiter_2; GSL_VAR const gsl_qrng_type * gsl_qrng_sobol; /* Allocate and initialize a generator * of the specified type, in the given * space dimension. */ gsl_qrng * gsl_qrng_alloc (const gsl_qrng_type * T, unsigned int dimension); /* Copy a generator. */ int gsl_qrng_memcpy (gsl_qrng * dest, const gsl_qrng * src); /* Clone a generator. */ gsl_qrng * gsl_qrng_clone (const gsl_qrng * q); /* Free a generator. */ void gsl_qrng_free (gsl_qrng * q); /* Intialize a generator. */ void gsl_qrng_init (gsl_qrng * q); /* Get the standardized name of the generator. */ const char * gsl_qrng_name (const gsl_qrng * q); /* ISN'T THIS CONFUSING FOR PEOPLE? WHAT IF SOMEBODY TRIES TO COPY WITH THIS ??? */ size_t gsl_qrng_size (const gsl_qrng * q); void * gsl_qrng_state (const gsl_qrng * q); /* Retrieve next vector in sequence. */ int gsl_qrng_get (const gsl_qrng * q, double x[]); #ifdef HAVE_INLINE extern inline int gsl_qrng_get (const gsl_qrng * q, double x[]); extern inline int gsl_qrng_get (const gsl_qrng * q, double x[]) { return (q->type->get) (q->state, q->dimension, x); } #endif /* HAVE_INLINE */ __END_DECLS #endif /* !__GSL_QRNG_H__ */ praat-6.0.04/external/gsl/gsl_qrng__niederreiter-2.c000066400000000000000000000216151261542461700223530ustar00rootroot00000000000000/* Author: G. Jungman */ /* Implement Niederreiter base 2 generator. * See: * Bratley, Fox, Niederreiter, ACM Trans. Model. Comp. Sim. 2, 195 (1992) */ #include "gsl__config.h" #include "gsl_qrng.h" #define NIED2_CHARACTERISTIC 2 #define NIED2_BASE 2 #define NIED2_MAX_DIMENSION 12 #define NIED2_MAX_PRIM_DEGREE 5 #define NIED2_MAX_DEGREE 50 #define NIED2_BIT_COUNT 30 #define NIED2_NBITS (NIED2_BIT_COUNT+1) #define MAXV (NIED2_NBITS + NIED2_MAX_DEGREE) /* Z_2 field operations */ #define NIED2_ADD(x,y) (((x)+(y))%2) #define NIED2_MUL(x,y) (((x)*(y))%2) #define NIED2_SUB(x,y) NIED2_ADD((x),(y)) static size_t nied2_state_size(unsigned int dimension); static int nied2_init(void * state, unsigned int dimension); static int nied2_get(void * state, unsigned int dimension, double * v); static const gsl_qrng_type nied2_type = { "niederreiter-base-2", NIED2_MAX_DIMENSION, nied2_state_size, nied2_init, nied2_get }; const gsl_qrng_type * gsl_qrng_niederreiter_2 = &nied2_type; /* primitive polynomials in binary encoding */ static const int primitive_poly[NIED2_MAX_DIMENSION+1][NIED2_MAX_PRIM_DEGREE+1] = { { 1, 0, 0, 0, 0, 0 }, /* 1 */ { 0, 1, 0, 0, 0, 0 }, /* x */ { 1, 1, 0, 0, 0, 0 }, /* 1 + x */ { 1, 1, 1, 0, 0, 0 }, /* 1 + x + x^2 */ { 1, 1, 0, 1, 0, 0 }, /* 1 + x + x^3 */ { 1, 0, 1, 1, 0, 0 }, /* 1 + x^2 + x^3 */ { 1, 1, 0, 0, 1, 0 }, /* 1 + x + x^4 */ { 1, 0, 0, 1, 1, 0 }, /* 1 + x^3 + x^4 */ { 1, 1, 1, 1, 1, 0 }, /* 1 + x + x^2 + x^3 + x^4 */ { 1, 0, 1, 0, 0, 1 }, /* 1 + x^2 + x^5 */ { 1, 0, 0, 1, 0, 1 }, /* 1 + x^3 + x^5 */ { 1, 1, 1, 1, 0, 1 }, /* 1 + x + x^2 + x^3 + x^5 */ { 1, 1, 1, 0, 1, 1 } /* 1 + x + x^2 + x^4 + x^5 */ }; /* degrees of primitive polynomials */ static const int poly_degree[NIED2_MAX_DIMENSION+1] = { 0, 1, 1, 2, 3, 3, 4, 4, 4, 5, 5, 5, 5 }; typedef struct { unsigned int sequence_count; int cj[NIED2_NBITS][NIED2_MAX_DIMENSION]; int nextq[NIED2_MAX_DIMENSION]; } nied2_state_t; static size_t nied2_state_size(unsigned int dimension) { return sizeof(nied2_state_t); } /* Multiply polynomials over Z_2. * Notice use of a temporary vector, * side-stepping aliasing issues when * one of inputs is the same as the output * [especially important in the original fortran version, I guess]. */ static void poly_multiply( const int pa[], int pa_degree, const int pb[], int pb_degree, int pc[], int * pc_degree ) { int j, k; int pt[NIED2_MAX_DEGREE+1]; int pt_degree = pa_degree + pb_degree; for(k=0; k<=pt_degree; k++) { int term = 0; for(j=0; j<=k; j++) { const int conv_term = NIED2_MUL(pa[k-j], pb[j]); term = NIED2_ADD(term, conv_term); } pt[k] = term; } for(k=0; k<=pt_degree; k++) { pc[k] = pt[k]; } for(k=pt_degree+1; k<=NIED2_MAX_DEGREE; k++) { pc[k] = 0; } *pc_degree = pt_degree; } /* Calculate the values of the constants V(J,R) as * described in BFN section 3.3. * * px = appropriate irreducible polynomial for current dimension * pb = polynomial defined in section 2.3 of BFN. * pb is modified */ static void calculate_v( const int px[], int px_degree, int pb[], int * pb_degree, int v[], int maxv ) { const int nonzero_element = 1; /* nonzero element of Z_2 */ const int arbitrary_element = 1; /* arbitray element of Z_2 */ /* The polynomial ph is px**(J-1), which is the value of B on arrival. * In section 3.3, the values of Hi are defined with a minus sign: * don't forget this if you use them later ! */ int ph[NIED2_MAX_DEGREE+1]; /* int ph_degree = *pb_degree; */ int bigm = *pb_degree; /* m from section 3.3 */ int m; /* m from section 2.3 */ int r, k, kj; for(k=0; k<=NIED2_MAX_DEGREE; k++) { ph[k] = pb[k]; } /* Now multiply B by PX so B becomes PX**J. * In section 2.3, the values of Bi are defined with a minus sign : * don't forget this if you use them later ! */ poly_multiply(px, px_degree, pb, *pb_degree, pb, pb_degree); m = *pb_degree; /* Now choose a value of Kj as defined in section 3.3. * We must have 0 <= Kj < E*J = M. * The limit condition on Kj does not seem very relevant * in this program. */ /* Quoting from BFN: "Our program currently sets each K_q * equal to eq. This has the effect of setting all unrestricted * values of v to 1." * Actually, it sets them to the arbitrary chosen value. * Whatever. */ kj = bigm; /* Now choose values of V in accordance with * the conditions in section 3.3. */ for(r=0; r= bigm) { for(r=kj+1; rcj[r][i_dim] = term; } } } static int nied2_init(void * state, unsigned int dimension) { nied2_state_t * n_state = (nied2_state_t *) state; unsigned int i_dim; if(dimension < 1 || dimension > NIED2_MAX_DIMENSION) return GSL_EINVAL; calculate_cj(n_state, dimension); for(i_dim=0; i_dimnextq[i_dim] = 0; n_state->sequence_count = 0; return GSL_SUCCESS; } static int nied2_get(void * state, unsigned int dimension, double * v) { static const double recip = 1.0/(double)(1U << NIED2_NBITS); /* 2^(-nbits) */ nied2_state_t * n_state = (nied2_state_t *) state; int r; int c; unsigned int i_dim; /* Load the result from the saved state. */ for(i_dim=0; i_dimnextq[i_dim] * recip; } /* Find the position of the least-significant zero in sequence_count. * This is the bit that changes in the Gray-code representation as * the count is advanced. */ r = 0; c = n_state->sequence_count; while(1) { if((c % 2) == 1) { ++r; c /= 2; } else break; } if(r >= NIED2_NBITS) return GSL_EFAILED; /* FIXME: better error code here */ /* Calculate the next state. */ for(i_dim=0; i_dimnextq[i_dim] ^= n_state->cj[r][i_dim]; } n_state->sequence_count++; return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_qrng__qrng.c000066400000000000000000000042311261542461700204750ustar00rootroot00000000000000/* Author: G. Jungman */ #include "gsl__config.h" #include #include #include "gsl_errno.h" #include "gsl_qrng.h" gsl_qrng * gsl_qrng_alloc (const gsl_qrng_type * T, unsigned int dimension) { gsl_qrng * q = (gsl_qrng *) malloc (sizeof (gsl_qrng)); if (q == 0) { GSL_ERROR_VAL ("allocation failed for qrng struct", GSL_ENOMEM, 0); }; q->dimension = dimension; q->state_size = T->state_size(dimension); q->state = malloc (q->state_size); if (q->state == 0) { free (q); GSL_ERROR_VAL ("allocation failed for qrng state", GSL_ENOMEM, 0); }; q->type = T; T->init_state(q->state, q->dimension); return q; } void gsl_qrng_init (gsl_qrng * q) { (q->type->init_state) (q->state, q->dimension); } int gsl_qrng_memcpy (gsl_qrng * dest, const gsl_qrng * src) { if (dest->type != src->type) { GSL_ERROR ("generators must be of the same type", GSL_EINVAL); } dest->dimension = src->dimension; dest->state_size = src->state_size; memcpy (dest->state, src->state, src->state_size); return GSL_SUCCESS; } gsl_qrng * gsl_qrng_clone (const gsl_qrng * q) { gsl_qrng * r = (gsl_qrng *) malloc (sizeof (gsl_qrng)); if (r == 0) { GSL_ERROR_VAL ("failed to allocate space for rng struct", GSL_ENOMEM, 0); }; r->dimension = q->dimension; r->state_size = q->state_size; r->state = malloc (r->state_size); if (r->state == 0) { free (r); GSL_ERROR_VAL ("failed to allocate space for rng state", GSL_ENOMEM, 0); }; r->type = q->type; memcpy (r->state, q->state, q->state_size); return r; } #ifndef HIDE_INLINE_STATIC int gsl_qrng_get (const gsl_qrng * q, double x[]) { return (q->type->get) (q->state, q->dimension, x); } #endif const char * gsl_qrng_name (const gsl_qrng * q) { return q->type->name; } size_t gsl_qrng_size (const gsl_qrng * q) { return q->state_size; } void * gsl_qrng_state (const gsl_qrng * q) { return q->state; } void gsl_qrng_free (gsl_qrng * q) { if(q != 0) { if(q->state != 0) free (q->state); free (q); } } praat-6.0.04/external/gsl/gsl_qrng__sobol.c000066400000000000000000000144231261542461700206500ustar00rootroot00000000000000/* Author: G. Jungman */ /* Implementation for Sobol generator. * See * [Bratley+Fox, TOMS 14, 88 (1988)] * [Antonov+Saleev, USSR Comput. Maths. Math. Phys. 19, 252 (1980)] */ #include "gsl__config.h" #include "gsl_qrng.h" /* maximum allowed space dimension */ #define SOBOL_MAX_DIMENSION 40 /* bit count; assumes sizeof(int) >= 32-bit */ #define SOBOL_BIT_COUNT 30 /* prototypes for generator type functions */ static size_t sobol_state_size(unsigned int dimension); static int sobol_init(void * state, unsigned int dimension); static int sobol_get(void * state, unsigned int dimension, double * v); /* global Sobol generator type object */ static const gsl_qrng_type sobol_type = { "sobol", SOBOL_MAX_DIMENSION, sobol_state_size, sobol_init, sobol_get }; const gsl_qrng_type * gsl_qrng_sobol = &sobol_type; /* primitive polynomials in binary encoding */ static const int primitive_polynomials[SOBOL_MAX_DIMENSION] = { 1, 3, 7, 11, 13, 19, 25, 37, 59, 47, 61, 55, 41, 67, 97, 91, 109, 103, 115, 131, 193, 137, 145, 143, 241, 157, 185, 167, 229, 171, 213, 191, 253, 203, 211, 239, 247, 285, 369, 299 }; /* degrees of the primitive polynomials */ static const int degree_table[SOBOL_MAX_DIMENSION] = { 0, 1, 2, 3, 3, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8 }; /* initial values for direction tables, following * Bratley+Fox, taken from [Sobol+Levitan, preprint 1976] */ static const int v_init[8][SOBOL_MAX_DIMENSION] = { { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 0, 0, 1, 3, 1, 3, 1, 3, 3, 1, 3, 1, 3, 1, 3, 1, 1, 3, 1, 3, 1, 3, 1, 3, 3, 1, 3, 1, 3, 1, 3, 1, 1, 3, 1, 3, 1, 3, 1, 3 }, { 0, 0, 0, 7, 5, 1, 3, 3, 7, 5, 5, 7, 7, 1, 3, 3, 7, 5, 1, 1, 5, 3, 3, 1, 7, 5, 1, 3, 3, 7, 5, 1, 1, 5, 7, 7, 5, 1, 3, 3 }, { 0, 0, 0, 0, 0, 1, 7, 9, 13, 11, 1, 3, 7, 9, 5, 13, 13, 11, 3, 15, 5, 3, 15, 7, 9, 13, 9, 1, 11, 7, 5, 15, 1, 15, 11, 5, 3, 1, 7, 9 }, { 0, 0, 0, 0, 0, 0, 0, 9, 3, 27, 15, 29, 21, 23, 19, 11, 25, 7, 13, 17, 1, 25, 29, 3, 31, 11, 5, 23, 27, 19, 21, 5, 1, 17, 13, 7, 15, 9, 31, 9 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 33, 7, 5, 11, 39, 63, 27, 17, 15, 23, 29, 3, 21, 13, 31, 25, 9, 49, 33, 19, 29, 11, 19, 27, 15, 25 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 33, 115, 41, 79, 17, 29, 119, 75, 73, 105, 7, 59, 65, 21, 3, 113, 61, 89, 45, 107 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 23, 39 } }; /* Sobol generator state. * sequence_count = number of calls with this generator * last_numerator_vec = last generated numerator vector * last_denominator_inv = 1/denominator for last numerator vector * v_direction = direction number table */ typedef struct { unsigned int sequence_count; double last_denominator_inv; int last_numerator_vec[SOBOL_MAX_DIMENSION]; int v_direction[SOBOL_BIT_COUNT][SOBOL_MAX_DIMENSION]; } sobol_state_t; /* NOTE: I fixed the size for the preliminary implementation. This could/should be relaxed, as an optimization. */ static size_t sobol_state_size(unsigned int dimension) { return sizeof(sobol_state_t); } static int sobol_init(void * state, unsigned int dimension) { sobol_state_t * s_state = (sobol_state_t *) state; unsigned int i_dim; int j, k; int ell; if(dimension < 1 || dimension > SOBOL_MAX_DIMENSION) { return GSL_EINVAL; } /* Initialize direction table in dimension 0. */ for(k=0; kv_direction[k][0] = 1; /* Initialize in remaining dimensions. */ for(i_dim=1; i_dim= 0; k--) { includ[k] = ((p_i % 2) == 1); p_i /= 2; } /* Leading elements for dimension i come from v_init[][]. */ for(j=0; jv_direction[j][i_dim] = v_init[j][i_dim]; /* Calculate remaining elements for this dimension, * as explained in Bratley+Fox, section 2. */ for(j=degree_i; jv_direction[j-degree_i][i_dim]; ell = 1; for(k=0; kv_direction[j-k-1][i_dim]); } s_state->v_direction[j][i_dim] = newv; } } /* Multiply columns of v by appropriate power of 2. */ ell = 1; for(j=SOBOL_BIT_COUNT-1-1; j>=0; j--) { ell *= 2; for(i_dim=0; i_dimv_direction[j][i_dim] *= ell; } } /* 1/(common denominator of the elements in v_direction) */ s_state->last_denominator_inv = 1.0 /(2.0 * ell); /* final setup */ s_state->sequence_count = 0; for(i_dim=0; i_dimlast_numerator_vec[i_dim] = 0; return GSL_SUCCESS; } static int sobol_get(void * state, unsigned int dimension, double * v) { sobol_state_t * s_state = (sobol_state_t *) state; unsigned int i_dimension; /* Find the position of the least-significant zero in count. */ int ell = 0; int c = s_state->sequence_count; while(1) { ++ell; if((c % 2) == 1) c /= 2; else break; } /* Check for exhaustion. */ if(ell > SOBOL_BIT_COUNT) return GSL_EFAILED; /* FIXME: good return code here */ for(i_dimension=0; i_dimensionv_direction[ell-1][i_dimension]; const int old_numerator_i = s_state->last_numerator_vec[i_dimension]; const int new_numerator_i = old_numerator_i ^ direction_i; s_state->last_numerator_vec[i_dimension] = new_numerator_i; v[i_dimension] = new_numerator_i * s_state->last_denominator_inv; } s_state->sequence_count++; return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_randist.h000066400000000000000000000206331261542461700200150ustar00rootroot00000000000000/* randist/gsl_randist.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_RANDIST_H__ #define __GSL_RANDIST_H__ #include "gsl_rng.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS unsigned int gsl_ran_bernoulli (const gsl_rng * r, double p); double gsl_ran_bernoulli_pdf (const unsigned int k, double p); double gsl_ran_beta (const gsl_rng * r, const double a, const double b); double gsl_ran_beta_pdf (const double x, const double a, const double b); unsigned int gsl_ran_binomial (const gsl_rng * r, double p, unsigned int n); unsigned int gsl_ran_binomial_knuth (const gsl_rng * r, double p, unsigned int n); unsigned int gsl_ran_binomial_tpe (const gsl_rng * r, double p, unsigned int n); double gsl_ran_binomial_pdf (const unsigned int k, const double p, const unsigned int n); double gsl_ran_exponential (const gsl_rng * r, const double mu); double gsl_ran_exponential_pdf (const double x, const double mu); double gsl_ran_exppow (const gsl_rng * r, const double a, const double b); double gsl_ran_exppow_pdf (const double x, const double a, const double b); double gsl_ran_cauchy (const gsl_rng * r, const double a); double gsl_ran_cauchy_pdf (const double x, const double a); double gsl_ran_chisq (const gsl_rng * r, const double nu); double gsl_ran_chisq_pdf (const double x, const double nu); void gsl_ran_dirichlet (const gsl_rng * r, const size_t K, const double alpha[], double theta[]); double gsl_ran_dirichlet_pdf (const size_t K, const double alpha[], const double theta[]); double gsl_ran_dirichlet_lnpdf (const size_t K, const double alpha[], const double theta[]); double gsl_ran_erlang (const gsl_rng * r, const double a, const double n); double gsl_ran_erlang_pdf (const double x, const double a, const double n); double gsl_ran_fdist (const gsl_rng * r, const double nu1, const double nu2); double gsl_ran_fdist_pdf (const double x, const double nu1, const double nu2); double gsl_ran_flat (const gsl_rng * r, const double a, const double b); double gsl_ran_flat_pdf (double x, const double a, const double b); double gsl_ran_gamma (const gsl_rng * r, const double a, const double b); double gsl_ran_gamma_int (const gsl_rng * r, const unsigned int a); double gsl_ran_gamma_pdf (const double x, const double a, const double b); double gsl_ran_gamma_mt (const gsl_rng * r, const double a, const double b); double gsl_ran_gamma_knuth (const gsl_rng * r, const double a, const double b); double gsl_ran_gaussian (const gsl_rng * r, const double sigma); double gsl_ran_gaussian_ratio_method (const gsl_rng * r, const double sigma); double gsl_ran_gaussian_ziggurat (const gsl_rng * r, const double sigma); double gsl_ran_gaussian_pdf (const double x, const double sigma); double gsl_ran_ugaussian (const gsl_rng * r); double gsl_ran_ugaussian_ratio_method (const gsl_rng * r); double gsl_ran_ugaussian_pdf (const double x); double gsl_ran_gaussian_tail (const gsl_rng * r, const double a, const double sigma); double gsl_ran_gaussian_tail_pdf (const double x, const double a, const double sigma); double gsl_ran_ugaussian_tail (const gsl_rng * r, const double a); double gsl_ran_ugaussian_tail_pdf (const double x, const double a); void gsl_ran_bivariate_gaussian (const gsl_rng * r, double sigma_x, double sigma_y, double rho, double *x, double *y); double gsl_ran_bivariate_gaussian_pdf (const double x, const double y, const double sigma_x, const double sigma_y, const double rho); double gsl_ran_landau (const gsl_rng * r); double gsl_ran_landau_pdf (const double x); unsigned int gsl_ran_geometric (const gsl_rng * r, const double p); double gsl_ran_geometric_pdf (const unsigned int k, const double p); unsigned int gsl_ran_hypergeometric (const gsl_rng * r, unsigned int n1, unsigned int n2, unsigned int t); double gsl_ran_hypergeometric_pdf (const unsigned int k, const unsigned int n1, const unsigned int n2, unsigned int t); double gsl_ran_gumbel1 (const gsl_rng * r, const double a, const double b); double gsl_ran_gumbel1_pdf (const double x, const double a, const double b); double gsl_ran_gumbel2 (const gsl_rng * r, const double a, const double b); double gsl_ran_gumbel2_pdf (const double x, const double a, const double b); double gsl_ran_logistic (const gsl_rng * r, const double a); double gsl_ran_logistic_pdf (const double x, const double a); double gsl_ran_lognormal (const gsl_rng * r, const double zeta, const double sigma); double gsl_ran_lognormal_pdf (const double x, const double zeta, const double sigma); unsigned int gsl_ran_logarithmic (const gsl_rng * r, const double p); double gsl_ran_logarithmic_pdf (const unsigned int k, const double p); void gsl_ran_multinomial (const gsl_rng * r, const size_t K, const unsigned int N, const double p[], unsigned int n[] ); double gsl_ran_multinomial_pdf (const size_t K, const double p[], const unsigned int n[] ); double gsl_ran_multinomial_lnpdf (const size_t K, const double p[], const unsigned int n[] ); unsigned int gsl_ran_negative_binomial (const gsl_rng * r, double p, double n); double gsl_ran_negative_binomial_pdf (const unsigned int k, const double p, double n); unsigned int gsl_ran_pascal (const gsl_rng * r, double p, unsigned int n); double gsl_ran_pascal_pdf (const unsigned int k, const double p, unsigned int n); double gsl_ran_pareto (const gsl_rng * r, double a, const double b); double gsl_ran_pareto_pdf (const double x, const double a, const double b); unsigned int gsl_ran_poisson (const gsl_rng * r, double mu); void gsl_ran_poisson_array (const gsl_rng * r, size_t n, unsigned int array[], double mu); double gsl_ran_poisson_pdf (const unsigned int k, const double mu); double gsl_ran_rayleigh (const gsl_rng * r, const double sigma); double gsl_ran_rayleigh_pdf (const double x, const double sigma); double gsl_ran_rayleigh_tail (const gsl_rng * r, const double a, const double sigma); double gsl_ran_rayleigh_tail_pdf (const double x, const double a, const double sigma); double gsl_ran_tdist (const gsl_rng * r, const double nu); double gsl_ran_tdist_pdf (const double x, const double nu); double gsl_ran_laplace (const gsl_rng * r, const double a); double gsl_ran_laplace_pdf (const double x, const double a); double gsl_ran_levy (const gsl_rng * r, const double c, const double alpha); double gsl_ran_levy_skew (const gsl_rng * r, const double c, const double alpha, const double beta); double gsl_ran_weibull (const gsl_rng * r, const double a, const double b); double gsl_ran_weibull_pdf (const double x, const double a, const double b); void gsl_ran_dir_2d (const gsl_rng * r, double * x, double * y); void gsl_ran_dir_2d_trig_method (const gsl_rng * r, double * x, double * y); void gsl_ran_dir_3d (const gsl_rng * r, double * x, double * y, double * z); void gsl_ran_dir_nd (const gsl_rng * r, size_t n, double * x); void gsl_ran_shuffle (const gsl_rng * r, void * base, size_t nmembm, size_t size); int gsl_ran_choose (const gsl_rng * r, void * dest, size_t k, void * src, size_t n, size_t size) ; void gsl_ran_sample (const gsl_rng * r, void * dest, size_t k, void * src, size_t n, size_t size) ; typedef struct { /* struct for Walker algorithm */ size_t K; size_t *A; double *F; } gsl_ran_discrete_t; gsl_ran_discrete_t * gsl_ran_discrete_preproc (size_t K, const double *P); void gsl_ran_discrete_free(gsl_ran_discrete_t *g); size_t gsl_ran_discrete (const gsl_rng *r, const gsl_ran_discrete_t *g); double gsl_ran_discrete_pdf (size_t k, const gsl_ran_discrete_t *g); __END_DECLS #endif /* __GSL_RANDIST_H__ */ praat-6.0.04/external/gsl/gsl_randist__bernoulli.c000066400000000000000000000025511261542461700222210ustar00rootroot00000000000000/* randist/bernoulli.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" #include "gsl_randist.h" /* The bernoulli distribution has the form, prob(0) = 1-p, prob(1) = p */ unsigned int gsl_ran_bernoulli (const gsl_rng * r, double p) { double u = gsl_rng_uniform (r) ; if (u < p) { return 1 ; } else { return 0 ; } } double gsl_ran_bernoulli_pdf (const unsigned int k, double p) { if (k == 0) { return 1 - p ; } else if (k == 1) { return p ; } else { return 0 ; } } praat-6.0.04/external/gsl/gsl_randist__beta.c000066400000000000000000000035101261542461700211350ustar00rootroot00000000000000/* randist/beta.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_rng.h" #include "gsl_randist.h" #include "gsl_sf_gamma.h" /* The beta distribution has the form p(x) dx = (Gamma(a + b)/(Gamma(a) Gamma(b))) x^(a-1) (1-x)^(b-1) dx The method used here is the one described in Knuth */ double gsl_ran_beta (const gsl_rng * r, const double a, const double b) { double x1 = gsl_ran_gamma (r, a, 1.0); double x2 = gsl_ran_gamma (r, b, 1.0); return x1 / (x1 + x2); } double gsl_ran_beta_pdf (const double x, const double a, const double b) { if (x < 0 || x > 1) { return 0 ; } else { double p; double gab = gsl_sf_lngamma (a + b); double ga = gsl_sf_lngamma (a); double gb = gsl_sf_lngamma (b); if (x == 0.0 || x == 1.0) { p = exp (gab - ga - gb) * pow (x, a - 1) * pow (1 - x, b - 1); } else { p = exp (gab - ga - gb + log(x) * (a - 1) + log1p(-x) * (b - 1)); } return p; } } praat-6.0.04/external/gsl/gsl_randist__bigauss.c000066400000000000000000000041701261542461700216620ustar00rootroot00000000000000/* randist/bigauss.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_rng.h" #include "gsl_randist.h" /* The Bivariate Gaussian probability distribution is p(x,y) dxdy = (1/(2 pi sigma_x sigma_y sqrt(c))) exp(-((x/sigma_x)^2 + (y/sigma_y)^2 - 2 r (x/sigma_x)(y/sigma_y))/2c) dxdy where c = 1-r^2 */ void gsl_ran_bivariate_gaussian (const gsl_rng * r, double sigma_x, double sigma_y, double rho, double *x, double *y) { double u, v, r2, scale; do { /* choose x,y in uniform square (-1,-1) to (+1,+1) */ u = -1 + 2 * gsl_rng_uniform (r); v = -1 + 2 * gsl_rng_uniform (r); /* see if it is in the unit circle */ r2 = u * u + v * v; } while (r2 > 1.0 || r2 == 0); scale = sqrt (-2.0 * log (r2) / r2); *x = sigma_x * u * scale; *y = sigma_y * (rho * u + sqrt(1 - rho*rho) * v) * scale; } double gsl_ran_bivariate_gaussian_pdf (const double x, const double y, const double sigma_x, const double sigma_y, const double rho) { double u = x / sigma_x ; double v = y / sigma_y ; double c = 1 - rho*rho ; double p = (1 / (2 * M_PI * sigma_x * sigma_y * sqrt(c))) * exp (-(u * u - 2 * rho * u * v + v * v) / (2 * c)); return p; } praat-6.0.04/external/gsl/gsl_randist__binomial.c000066400000000000000000000043761261542461700220270ustar00rootroot00000000000000/* randist/binomial.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_sys.h" #include "gsl_rng.h" #include "gsl_randist.h" #include "gsl_sf_gamma.h" /* The binomial distribution has the form, prob(k) = n!/(k!(n-k)!) * p^k (1-p)^(n-k) for k = 0, 1, ..., n This is the algorithm from Knuth */ /* Default binomial generator is now in binomial_tpe.c */ unsigned int gsl_ran_binomial_knuth (const gsl_rng * r, double p, unsigned int n) { unsigned int i, a, b, k = 0; while (n > 10) /* This parameter is tunable */ { double X; a = 1 + (n / 2); b = 1 + n - a; X = gsl_ran_beta (r, (double) a, (double) b); if (X >= p) { n = a - 1; p /= X; } else { k += a; n = b - 1; p = (p - X) / (1 - X); } } for (i = 0; i < n; i++) { double u = gsl_rng_uniform (r); if (u < p) k++; } return k; } double gsl_ran_binomial_pdf (const unsigned int k, const double p, const unsigned int n) { if (k > n) { return 0; } else { double P; if (p == 0) { P = (k == 0) ? 1 : 0; } else if (p == 1) { P = (k == n) ? 1 : 0; } else { double ln_Cnk = gsl_sf_lnchoose (n, k); P = ln_Cnk + k * log (p) + (n - k) * log1p (-p); P = exp (P); } return P; } } praat-6.0.04/external/gsl/gsl_randist__binomial_tpe.c000066400000000000000000000311661261542461700226740ustar00rootroot00000000000000/* randist/binomial_tpe.c * * Copyright (C) 1996, 2003, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" #include "gsl_randist.h" #include "gsl_pow_int.h" #include "gsl_sf_gamma.h" /* The binomial distribution has the form, f(x) = n!/(x!(n-x)!) * p^x (1-p)^(n-x) for integer 0 <= x <= n = 0 otherwise This implementation follows the public domain ranlib function "ignbin", the bulk of which is the BTPE (Binomial Triangle Parallelogram Exponential) algorithm introduced in Kachitvichyanukul and Schmeiser[1]. It has been translated to use modern C coding standards. If n is small and/or p is near 0 or near 1 (specifically, if n*min(p,1-p) < SMALL_MEAN), then a different algorithm, called BINV, is used which has an average runtime that scales linearly with n*min(p,1-p). But for larger problems, the BTPE algorithm takes the form of two functions b(x) and t(x) -- "bottom" and "top" -- for which b(x) < f(x)/f(M) < t(x), with M = floor(n*p+p). b(x) defines a triangular region, and t(x) includes a parallelogram and two tails. Details (including a nice drawing) are in the paper. [1] Kachitvichyanukul, V. and Schmeiser, B. W. Binomial Random Variate Generation. Communications of the ACM, 31, 2 (February, 1988) 216. Note, Bruce Schmeiser (personal communication) points out that if you want very fast binomial deviates, and you are happy with approximate results, and/or n and n*p are both large, then you can just use gaussian estimates: mean=n*p, variance=n*p*(1-p). This implementation by James Theiler, April 2003, after obtaining permission -- and some good advice -- from Drs. Kachitvichyanukul and Schmeiser to use their code as a starting point, and then doing a little bit of tweaking. Additional polishing for GSL coding standards by Brian Gough. */ #define SMALL_MEAN 14 /* If n*p < SMALL_MEAN then use BINV algorithm. The ranlib implementation used cutoff=30; but on my computer 14 works better */ #define BINV_CUTOFF 110 /* In BINV, do not permit ix too large */ #define FAR_FROM_MEAN 20 /* If ix-n*p is larger than this, then use the "squeeze" algorithm. Ranlib used 20, and this seems to be the best choice on my machine as well */ #define LNFACT(x) gsl_sf_lnfact(x) inline static double Stirling (double y1) { double y2 = y1 * y1; double s = (13860.0 - (462.0 - (132.0 - (99.0 - 140.0 / y2) / y2) / y2) / y2) / y1 / 166320.0; return s; } unsigned int gsl_ran_binomial_tpe (const gsl_rng * rng, double p, unsigned int n) { return gsl_ran_binomial (rng, p, n); } unsigned int gsl_ran_binomial (const gsl_rng * rng, double p, unsigned int n) { int ix; /* return value */ int flipped = 0; double q, s, np; if (n == 0) return 0; if (p > 0.5) { p = 1.0 - p; /* work with small p */ flipped = 1; } q = 1 - p; s = p / q; np = n * p; /* Inverse cdf logic for small mean (BINV in K+S) */ if (np < SMALL_MEAN) { double f0 = gsl_pow_int (q, n); /* f(x), starting with x=0 */ while (1) { /* This while(1) loop will almost certainly only loop once; but * if u=1 to within a few epsilons of machine precision, then it * is possible for roundoff to prevent the main loop over ix to * achieve its proper value. following the ranlib implementation, * we introduce a check for that situation, and when it occurs, * we just try again. */ double f = f0; double u = gsl_rng_uniform (rng); for (ix = 0; ix <= BINV_CUTOFF; ++ix) { if (u < f) goto Finish; u -= f; /* Use recursion f(x+1) = f(x)*[(n-x)/(x+1)]*[p/(1-p)] */ f *= s * (n - ix) / (ix + 1); } /* It should be the case that the 'goto Finish' was encountered * before this point was ever reached. But if we have reached * this point, then roundoff has prevented u from decreasing * all the way to zero. This can happen only if the initial u * was very nearly equal to 1, which is a rare situation. In * that rare situation, we just try again. * * Note, following the ranlib implementation, we loop ix only to * a hardcoded value of SMALL_MEAN_LARGE_N=110; we could have * looped to n, and 99.99...% of the time it won't matter. This * choice, I think is a little more robust against the rare * roundoff error. If n>LARGE_N, then it is technically * possible for ix>LARGE_N, but it is astronomically rare, and * if ix is that large, it is more likely due to roundoff than * probability, so better to nip it at LARGE_N than to take a * chance that roundoff will somehow conspire to produce an even * larger (and more improbable) ix. If n= SMALL_MEAN, we invoke the BTPE algorithm */ int k; double ffm = np + p; /* ffm = n*p+p */ int m = (int) ffm; /* m = int floor[n*p+p] */ double fm = m; /* fm = double m; */ double xm = fm + 0.5; /* xm = half integer mean (tip of triangle) */ double npq = np * q; /* npq = n*p*q */ /* Compute cumulative area of tri, para, exp tails */ /* p1: radius of triangle region; since height=1, also: area of region */ /* p2: p1 + area of parallelogram region */ /* p3: p2 + area of left tail */ /* p4: p3 + area of right tail */ /* pi/p4: probability of i'th area (i=1,2,3,4) */ /* Note: magic numbers 2.195, 4.6, 0.134, 20.5, 15.3 */ /* These magic numbers are not adjustable...at least not easily! */ double p1 = floor (2.195 * sqrt (npq) - 4.6 * q) + 0.5; /* xl, xr: left and right edges of triangle */ double xl = xm - p1; double xr = xm + p1; /* Parameter of exponential tails */ /* Left tail: t(x) = c*exp(-lambda_l*[xl - (x+0.5)]) */ /* Right tail: t(x) = c*exp(-lambda_r*[(x+0.5) - xr]) */ double c = 0.134 + 20.5 / (15.3 + fm); double p2 = p1 * (1.0 + c + c); double al = (ffm - xl) / (ffm - xl * p); double lambda_l = al * (1.0 + 0.5 * al); double ar = (xr - ffm) / (xr * q); double lambda_r = ar * (1.0 + 0.5 * ar); double p3 = p2 + c / lambda_l; double p4 = p3 + c / lambda_r; double var, accept; double u, v; /* random variates */ TryAgain: /* generate random variates, u specifies which region: Tri, Par, Tail */ u = gsl_rng_uniform (rng) * p4; v = gsl_rng_uniform (rng); if (u <= p1) { /* Triangular region */ ix = (int) (xm - p1 * v + u); goto Finish; } else if (u <= p2) { /* Parallelogram region */ double x = xl + (u - p1) / c; v = v * c + 1.0 - fabs (x - xm) / p1; if (v > 1.0 || v <= 0.0) goto TryAgain; ix = (int) x; } else if (u <= p3) { /* Left tail */ ix = (int) (xl + log (v) / lambda_l); if (ix < 0) goto TryAgain; v *= ((u - p2) * lambda_l); } else { /* Right tail */ ix = (int) (xr - log (v) / lambda_r); if (ix > (double) n) goto TryAgain; v *= ((u - p3) * lambda_r); } /* At this point, the goal is to test whether v <= f(x)/f(m) * * v <= f(x)/f(m) = (m!(n-m)! / (x!(n-x)!)) * (p/q)^{x-m} * */ /* Here is a direct test using logarithms. It is a little * slower than the various "squeezing" computations below, but * if things are working, it should give exactly the same answer * (given the same random number seed). */ #ifdef DIRECT var = log (v); accept = LNFACT (m) + LNFACT (n - m) - LNFACT (ix) - LNFACT (n - ix) + (ix - m) * log (p / q); #else /* SQUEEZE METHOD */ /* More efficient determination of whether v < f(x)/f(M) */ k = abs (ix - m); if (k <= FAR_FROM_MEAN) { /* * If ix near m (ie, |ix-m| ix) { int i; for (i = ix + 1; i <= m; i++) { f /= (g / i - s); } } accept = f; } else { /* If ix is far from the mean m: k=ABS(ix-m) large */ var = log (v); if (k < npq / 2 - 1) { /* "Squeeze" using upper and lower bounds on * log(f(x)) The squeeze condition was derived * under the condition k < npq/2-1 */ double amaxp = k / npq * ((k * (k / 3.0 + 0.625) + (1.0 / 6.0)) / npq + 0.5); double ynorm = -(k * k / (2.0 * npq)); if (var < ynorm - amaxp) goto Finish; if (var > ynorm + amaxp) goto TryAgain; } /* Now, again: do the test log(v) vs. log f(x)/f(M) */ #if USE_EXACT /* This is equivalent to the above, but is a little (~20%) slower */ /* There are five log's vs three above, maybe that's it? */ accept = LNFACT (m) + LNFACT (n - m) - LNFACT (ix) - LNFACT (n - ix) + (ix - m) * log (p / q); #else /* USE STIRLING */ /* The "#define Stirling" above corresponds to the first five * terms in asymptoic formula for * log Gamma (y) - (y-0.5)log(y) + y - 0.5 log(2*pi); * See Abramowitz and Stegun, eq 6.1.40 */ /* Note below: two Stirling's are added, and two are * subtracted. In both K+S, and in the ranlib * implementation, all four are added. I (jt) believe that * is a mistake -- this has been confirmed by personal * correspondence w/ Dr. Kachitvichyanukul. Note, however, * the corrections are so small, that I couldn't find an * example where it made a difference that could be * observed, let alone tested. In fact, define'ing Stirling * to be zero gave identical results!! In practice, alv is * O(1), ranging 0 to -10 or so, while the Stirling * correction is typically O(10^{-5}) ...setting the * correction to zero gives about a 2% performance boost; * might as well keep it just to be pendantic. */ { double x1 = ix + 1.0; double w1 = n - ix + 1.0; double f1 = fm + 1.0; double z1 = n + 1.0 - fm; accept = xm * log (f1 / x1) + (n - m + 0.5) * log (z1 / w1) + (ix - m) * log (w1 * p / (x1 * q)) + Stirling (f1) + Stirling (z1) - Stirling (x1) - Stirling (w1); } #endif #endif } if (var <= accept) { goto Finish; } else { goto TryAgain; } } Finish: return (flipped) ? (n - ix) : (unsigned int)ix; } praat-6.0.04/external/gsl/gsl_randist__cauchy.c000066400000000000000000000026071261542461700215040ustar00rootroot00000000000000/* randist/cauchy.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_rng.h" #include "gsl_randist.h" /* The Cauchy probability distribution is p(x) dx = (1/(pi a)) (1 + (x/a)^2)^(-1) dx It is also known as the Lorentzian probability distribution */ double gsl_ran_cauchy (const gsl_rng * r, const double a) { double u; do { u = gsl_rng_uniform (r); } while (u == 0.5); return a * tan (M_PI * u); } double gsl_ran_cauchy_pdf (const double x, const double a) { double u = x / a; double p = (1 / (M_PI * a)) / (1 + u * u); return p; } praat-6.0.04/external/gsl/gsl_randist__chisq.c000066400000000000000000000027151261542461700213370ustar00rootroot00000000000000/* randist/chisq.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_sf_gamma.h" #include "gsl_rng.h" #include "gsl_randist.h" /* The chisq distribution has the form p(x) dx = (1/(2*Gamma(nu/2))) (x/2)^(nu/2 - 1) exp(-x/2) dx for x = 0 ... +infty */ double gsl_ran_chisq (const gsl_rng * r, const double nu) { double chisq = 2 * gsl_ran_gamma (r, nu / 2, 1.0); return chisq; } double gsl_ran_chisq_pdf (const double x, const double nu) { if (x <= 0) { return 0 ; } else { double p; double lngamma = gsl_sf_lngamma (nu / 2); p = exp ((nu / 2 - 1) * log (x/2) - x/2 - lngamma) / 2; return p; } } praat-6.0.04/external/gsl/gsl_randist__dirichlet.c000066400000000000000000000077421261542461700222040ustar00rootroot00000000000000/* randist/dirichlet.c * * Copyright (C) 2007 Brian Gough * Copyright (C) 2002 Gavin E. Crooks * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_rng.h" #include "gsl_randist.h" #include "gsl_sf_gamma.h" /* The Dirichlet probability distribution of order K-1 is p(\theta_1,...,\theta_K) d\theta_1 ... d\theta_K = (1/Z) \prod_i=1,K \theta_i^{alpha_i - 1} \delta(1 -\sum_i=1,K \theta_i) The normalization factor Z can be expressed in terms of gamma functions: Z = {\prod_i=1,K \Gamma(\alpha_i)} / {\Gamma( \sum_i=1,K \alpha_i)} The K constants, \alpha_1,...,\alpha_K, must be positive. The K parameters, \theta_1,...,\theta_K are nonnegative and sum to 1. The random variates are generated by sampling K values from gamma distributions with parameters a=\alpha_i, b=1, and renormalizing. See A.M. Law, W.D. Kelton, Simulation Modeling and Analysis (1991). Gavin E. Crooks (2002) */ static void ran_dirichlet_small (const gsl_rng * r, const size_t K, const double alpha[], double theta[]); void gsl_ran_dirichlet (const gsl_rng * r, const size_t K, const double alpha[], double theta[]) { size_t i; double norm = 0.0; for (i = 0; i < K; i++) { theta[i] = gsl_ran_gamma (r, alpha[i], 1.0); } for (i = 0; i < K; i++) { norm += theta[i]; } if (norm < GSL_SQRT_DBL_MIN) /* Handle underflow */ { ran_dirichlet_small (r, K, alpha, theta); return; } for (i = 0; i < K; i++) { theta[i] /= norm; } } /* When the values of alpha[] are small, scale the variates to avoid underflow so that the result is not 0/0. Note that the Dirichlet distribution is defined by a ratio of gamma functions so we can take out an arbitrary factor to keep the values in the range of double precision. */ static void ran_dirichlet_small (const gsl_rng * r, const size_t K, const double alpha[], double theta[]) { size_t i; double norm = 0.0, umax = 0; for (i = 0; i < K; i++) { double u = log(gsl_rng_uniform_pos (r)) / alpha[i]; theta[i] = u; if (u > umax || i == 0) { umax = u; } } for (i = 0; i < K; i++) { theta[i] = exp(theta[i] - umax); } for (i = 0; i < K; i++) { theta[i] = theta[i] * gsl_ran_gamma (r, alpha[i] + 1.0, 1.0); } for (i = 0; i < K; i++) { norm += theta[i]; } for (i = 0; i < K; i++) { theta[i] /= norm; } } double gsl_ran_dirichlet_pdf (const size_t K, const double alpha[], const double theta[]) { return exp (gsl_ran_dirichlet_lnpdf (K, alpha, theta)); } double gsl_ran_dirichlet_lnpdf (const size_t K, const double alpha[], const double theta[]) { /*We calculate the log of the pdf to minimize the possibility of overflow */ size_t i; double log_p = 0.0; double sum_alpha = 0.0; for (i = 0; i < K; i++) { log_p += (alpha[i] - 1.0) * log (theta[i]); } for (i = 0; i < K; i++) { sum_alpha += alpha[i]; } log_p += gsl_sf_lngamma (sum_alpha); for (i = 0; i < K; i++) { log_p -= gsl_sf_lngamma (alpha[i]); } return log_p; } praat-6.0.04/external/gsl/gsl_randist__discrete.c000066400000000000000000000314601261542461700220310ustar00rootroot00000000000000/* randist/discrete.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Random Discrete Events Given K discrete events with different probabilities P[k] produce a value k consistent with its probability. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * Based on: Alastair J Walker, An efficient method for generating * discrete random variables with general distributions, ACM Trans * Math Soft 3, 253-256 (1977). See also: D. E. Knuth, The Art of * Computer Programming, Volume 2 (Seminumerical algorithms), 3rd * edition, Addison-Wesley (1997), p120. * Walker's algorithm does some preprocessing, and provides two * arrays: floating point F[k] and integer A[k]. A value k is chosen * from 0..K-1 with equal likelihood, and then a uniform random number * u is compared to F[k]. If it is less than F[k], then k is * returned. Otherwise, A[k] is returned. * Walker's original paper describes an O(K^2) algorithm for setting * up the F and A arrays. I found this disturbing since I wanted to * use very large values of K. I'm sure I'm not the first to realize * this, but in fact the preprocessing can be done in O(K) steps. * A figure of merit for the preprocessing is the average value for * the F[k]'s (that is, SUM_k F[k]/K); this corresponds to the * probability that k is returned, instead of A[k], thereby saving a * redirection. Walker's O(K^2) preprocessing will generally improve * that figure of merit, compared to my cheaper O(K) method; from some * experiments with a perl script, I get values of around 0.6 for my * method and just under 0.75 for Walker's. Knuth has pointed out * that finding _the_ optimum lookup tables, which maximize the * average F[k], is a combinatorially difficult problem. But any * valid preprocessing will still provide O(1) time for the call to * gsl_ran_discrete(). I find that if I artificially set F[k]=1 -- * ie, better than optimum! -- I get a speedup of maybe 20%, so that's * the maximum I could expect from the most expensive preprocessing. * Folding in the difference of 0.6 vs 0.75, I'd estimate that the * speedup would be less than 10%. * I've not implemented it here, but one compromise is to sort the * probabilities once, and then work from the two ends inward. This * requires O(K log K), still lots cheaper than O(K^2), and from my * experiments with the perl script, the figure of merit is within * about 0.01 for K up to 1000, and no sign of diverging (in fact, * they seemed to be converging, but it's hard to say with just a * handful of runs). * The O(K) algorithm goes through all the p_k's and decides if they * are "smalls" or "bigs" according to whether they are less than or * greater than the mean value 1/K. The indices to the smalls and the * bigs are put in separate stacks, and then we work through the * stacks together. For each small, we pair it up with the next big * in the stack (Walker always wanted to pair up the smallest small * with the biggest big). The small "borrows" from the big just * enough to bring the small up to mean. This reduces the size of the * big, so the (smaller) big is compared again to the mean, and if it * is smaller, it gets "popped" from the big stack and "pushed" to the * small stack. Otherwise, it stays put. Since every time we pop a * small, we are able to deal with it right then and there, and we * never have to pop more than K smalls, then the algorithm is O(K). * This implementation sets up two separate stacks, and allocates K * elements between them. Since neither stack ever grows, we do an * extra O(K) pass through the data to determine how many smalls and * bigs there are to begin with and allocate appropriately. In all * there are 2*K*sizeof(double) transient bytes of memory that are * used than returned, and K*(sizeof(int)+sizeof(double)) bytes used * in the lookup table. * Walker spoke of using two random numbers (an integer 0..K-1, and a * floating point u in [0,1]), but Knuth points out that one can just * use the integer and fractional parts of K*u where u is in [0,1]. * In fact, Knuth further notes that taking F'[k]=(k+F[k])/K, one can * directly compare u to F'[k] without having to explicitly set * u=K*u-int(K*u). * Usage: * Starting with an array of probabilities P, initialize and do * preprocessing with a call to: * gsl_rng *r; * gsl_ran_discrete_t *f; * f = gsl_ran_discrete_preproc(K,P); * Then, whenever a random index 0..K-1 is desired, use * k = gsl_ran_discrete(r,f); * Note that several different randevent struct's can be * simultaneously active. * Aside: A very clever alternative approach is described in * Abramowitz and Stegun, p 950, citing: Marsaglia, Random variables * and computers, Proc Third Prague Conference in Probability Theory, * 1962. A more accesible reference is: G. Marsaglia, Generating * discrete random numbers in a computer, Comm ACM 6, 37-38 (1963). * If anybody is interested, I (jt) have also coded up this version as * part of another software package. However, I've done some * comparisons, and the Walker method is both faster and more stingy * with memory. So, in the end I decided not to include it with the * GSL package. * Written 26 Jan 1999, James Theiler, jt@lanl.gov * Adapted to GSL, 30 Jan 1999, jt */ #include "gsl__config.h" #include #include #include #include "gsl_errno.h" #include "gsl_rng.h" #include "gsl_randist.h" #define DEBUG 0 #define KNUTH_CONVENTION 1 /* Saves a few steps of arithmetic * in the call to gsl_ran_discrete() */ /*** Begin Stack (this code is used just in this file) ***/ /* Stack code converted to use unsigned indices (i.e. s->i == 0 now means an empty stack, instead of -1), for consistency and to give a bigger allowable range. BJG */ typedef struct { size_t N; /* max number of elts on stack */ size_t *v; /* array of values on the stack */ size_t i; /* index of top of stack */ } gsl_stack_t; static gsl_stack_t * new_stack(size_t N) { gsl_stack_t *s; s = (gsl_stack_t *)malloc(sizeof(gsl_stack_t)); s->N = N; s->i = 0; /* indicates stack is empty */ s->v = (size_t *)malloc(sizeof(size_t)*N); return s; } static void push_stack(gsl_stack_t *s, size_t v) { if ((s->i) >= (s->N)) { fprintf(stderr,"Cannot push stack!\n"); abort(); /* FIXME: fatal!! */ } (s->v)[s->i] = v; s->i += 1; } static size_t pop_stack(gsl_stack_t *s) { if ((s->i) == 0) { fprintf(stderr,"Cannot pop stack!\n"); abort(); /* FIXME: fatal!! */ } s->i -= 1; return ((s->v)[s->i]); } static inline size_t size_stack(const gsl_stack_t *s) { return s->i; } static void free_stack(gsl_stack_t *s) { free((char *)(s->v)); free((char *)s); } /*** End Stack ***/ /*** Begin Walker's Algorithm ***/ gsl_ran_discrete_t * gsl_ran_discrete_preproc(size_t Kevents, const double *ProbArray) { size_t k,b,s; gsl_ran_discrete_t *g; size_t nBigs, nSmalls; gsl_stack_t *Bigs; gsl_stack_t *Smalls; double *E; double pTotal = 0.0, mean, d; if (Kevents < 1) { /* Could probably treat Kevents=1 as a special case */ GSL_ERROR_VAL ("number of events must be a positive integer", GSL_EINVAL, 0); } /* Make sure elements of ProbArray[] are positive. * Won't enforce that sum is unity; instead will just normalize */ for (k=0; kK = Kevents; g->F = (double *)malloc(sizeof(double)*Kevents); g->A = (size_t *)malloc(sizeof(size_t)*Kevents); E = (double *)malloc(sizeof(double)*Kevents); if (E==NULL) { GSL_ERROR_VAL ("Cannot allocate memory for randevent", GSL_ENOMEM, 0); } for (k=0; k 0) { s = pop_stack(Smalls); if (size_stack(Bigs) == 0) { (g->A)[s]=s; (g->F)[s]=1.0; continue; } b = pop_stack(Bigs); (g->A)[s]=b; (g->F)[s]=Kevents*E[s]; #if DEBUG fprintf(stderr,"s=%2d, A=%2d, F=%.4f\n",s,(g->A)[s],(g->F)[s]); #endif d = mean - E[s]; E[s] += d; /* now E[s] == mean */ E[b] -= d; if (E[b] < mean) { push_stack(Smalls,b); /* no longer big, join ranks of the small */ } else if (E[b] > mean) { push_stack(Bigs,b); /* still big, put it back where you found it */ } else { /* E[b]==mean implies it is finished too */ (g->A)[b]=b; (g->F)[b]=1.0; } } while (size_stack(Bigs) > 0) { b = pop_stack(Bigs); (g->A)[b]=b; (g->F)[b]=1.0; } /* Stacks have been emptied, and A and F have been filled */ if ( size_stack(Smalls) != 0) { GSL_ERROR_VAL ("Smalls stack has not been emptied", GSL_ESANITY, 0 ); } #if 0 /* if 1, then artificially set all F[k]'s to unity. This will * give wrong answers, but you'll get them faster. But, not * that much faster (I get maybe 20%); that's an upper bound * on what the optimal preprocessing would give. */ for (k=0; kF)[k] = 1.0; } #endif #if KNUTH_CONVENTION /* For convenience, set F'[k]=(k+F[k])/K */ /* This saves some arithmetic in gsl_ran_discrete(); I find that * it doesn't actually make much difference. */ for (k=0; kF)[k] += k; (g->F)[k] /= Kevents; } #endif free_stack(Bigs); free_stack(Smalls); free((char *)E); return g; } size_t gsl_ran_discrete(const gsl_rng *r, const gsl_ran_discrete_t *g) { size_t c=0; double u,f; u = gsl_rng_uniform(r); #if KNUTH_CONVENTION c = (u*(g->K)); #else u *= g->K; c = u; u -= c; #endif f = (g->F)[c]; /* fprintf(stderr,"c,f,u: %d %.4f %f\n",c,f,u); */ if (f == 1.0) return c; if (u < f) { return c; } else { return (g->A)[c]; } } void gsl_ran_discrete_free(gsl_ran_discrete_t *g) { free((char *)(g->A)); free((char *)(g->F)); free((char *)g); } double gsl_ran_discrete_pdf(size_t k, const gsl_ran_discrete_t *g) { size_t i,K; double f,p=0; K= g->K; if (k>K) return 0; for (i=0; iF)[i]; #if KNUTH_CONVENTION f = K*f-i; #endif if (i==k) { p += f; } else if (k == (g->A)[i]) { p += 1.0 - f; } } return p/K; } praat-6.0.04/external/gsl/gsl_randist__erlang.c000066400000000000000000000027401261542461700214760ustar00rootroot00000000000000/* randist/erlang.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_sf_gamma.h" #include "gsl_rng.h" #include "gsl_randist.h" /* The sum of N samples from an exponential distribution gives an Erlang distribution p(x) dx = x^(n-1) exp (-x/a) / ((n-1)!a^n) dx for x = 0 ... +infty */ double gsl_ran_erlang (const gsl_rng * r, const double a, const double n) { return gsl_ran_gamma (r, n, a); } double gsl_ran_erlang_pdf (const double x, const double a, const double n) { if (x <= 0) { return 0 ; } else { double p; double lngamma = gsl_sf_lngamma (n); p = exp ((n - 1) * log (x/a) - x/a - lngamma) / a; return p; } } praat-6.0.04/external/gsl/gsl_randist__exponential.c000066400000000000000000000025061261542461700225540ustar00rootroot00000000000000/* randist/exponential.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" #include "gsl_randist.h" /* The exponential distribution has the form p(x) dx = exp(-x/mu) dx/mu for x = 0 ... +infty */ double gsl_ran_exponential (const gsl_rng * r, const double mu) { double u = gsl_rng_uniform_pos (r); return -mu * log (u); } double gsl_ran_exponential_pdf (const double x, const double mu) { if (x < 0) { return 0 ; } else { double p = exp (-x/mu)/mu; return p; } } praat-6.0.04/external/gsl/gsl_randist__exppow.c000066400000000000000000000063571261542461700215600ustar00rootroot00000000000000/* randist/exppow.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2006, 2007 James Theiler, Brian Gough * Copyright (C) 2006 Giulio Bottazzi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_sf_gamma.h" #include "gsl_rng.h" #include "gsl_randist.h" /* The exponential power probability distribution is p(x) dx = (1/(2 a Gamma(1+1/b))) * exp(-|x/a|^b) dx for -infty < x < infty. For b = 1 it reduces to the Laplace distribution. The exponential power distribution is related to the gamma distribution by E = a * pow(G(1/b),1/b), where E is an exponential power variate and G is a gamma variate. We use this relation for b < 1. For b >=1 we use rejection methods based on the laplace and gaussian distributions which should be faster. For b>4 we revert to the gamma method. See P. R. Tadikamalla, "Random Sampling from the Exponential Power Distribution", Journal of the American Statistical Association, September 1980, Volume 75, Number 371, pages 683-686. */ double gsl_ran_exppow (const gsl_rng * r, const double a, const double b) { if (b < 1 || b > 4) { double u = gsl_rng_uniform (r); double v = gsl_ran_gamma (r, 1 / b, 1.0); double z = a * pow (v, 1 / b); if (u > 0.5) { return z; } else { return -z; } } else if (b == 1) { /* Laplace distribution */ return gsl_ran_laplace (r, a); } else if (b < 2) { /* Use laplace distribution for rejection method, from Tadikamalla */ double x, h, u; double B = pow (1 / b, 1 / b); do { x = gsl_ran_laplace (r, B); u = gsl_rng_uniform_pos (r); h = -pow (fabs (x), b) + fabs (x) / B - 1 + (1 / b); } while (log (u) > h); return a * x; } else if (b == 2) { /* Gaussian distribution */ return gsl_ran_gaussian (r, a / sqrt (2.0)); } else { /* Use gaussian for rejection method, from Tadikamalla */ double x, h, u; double B = pow (1 / b, 1 / b); do { x = gsl_ran_gaussian (r, B); u = gsl_rng_uniform_pos (r); h = -pow (fabs (x), b) + (x * x) / (2 * B * B) + (1 / b) - 0.5; } while (log (u) > h); return a * x; } } double gsl_ran_exppow_pdf (const double x, const double a, const double b) { double p; double lngamma = gsl_sf_lngamma (1 + 1 / b); p = (1 / (2 * a)) * exp (-pow (fabs (x / a), b) - lngamma); return p; } praat-6.0.04/external/gsl/gsl_randist__fdist.c000066400000000000000000000036161261542461700213420ustar00rootroot00000000000000/* randist/fdist.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_sf_gamma.h" #include "gsl_rng.h" #include "gsl_randist.h" /* The F distribution has the form p(x) dx = (nu1^(nu1/2) nu2^(nu2/2) Gamma((nu1 + nu2)/2) / Gamma(nu1/2) Gamma(nu2/2)) * x^(nu1/2 - 1) (nu2 + nu1 * x)^(-nu1/2 -nu2/2) dx The method used here is the one described in Knuth */ double gsl_ran_fdist (const gsl_rng * r, const double nu1, const double nu2) { double Y1 = gsl_ran_gamma (r, nu1 / 2, 2.0); double Y2 = gsl_ran_gamma (r, nu2 / 2, 2.0); double f = (Y1 * nu2) / (Y2 * nu1); return f; } double gsl_ran_fdist_pdf (const double x, const double nu1, const double nu2) { if (x < 0) { return 0 ; } else { double p; double lglg = (nu1 / 2) * log (nu1) + (nu2 / 2) * log (nu2) ; double lg12 = gsl_sf_lngamma ((nu1 + nu2) / 2); double lg1 = gsl_sf_lngamma (nu1 / 2); double lg2 = gsl_sf_lngamma (nu2 / 2); p = exp (lglg + lg12 - lg1 - lg2) * pow (x, nu1 / 2 - 1) * pow (nu2 + nu1 * x, -nu1 / 2 - nu2 / 2); return p; } } praat-6.0.04/external/gsl/gsl_randist__flat.c000066400000000000000000000026051261542461700211540ustar00rootroot00000000000000/* randist/flat.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" #include "gsl_randist.h" /* This is the uniform distribution in the range [a, b) p(x) dx = 1/(b-a) dx if a <= x < b ..... = 0 otherwise */ double gsl_ran_flat (const gsl_rng * r, const double a, const double b) { double u = gsl_rng_uniform (r); /* A uniform distribution over [a,b] */ return a * (1 - u) + b * u; } double gsl_ran_flat_pdf (double x, const double a, const double b) { if (x < b && x >= a) { return 1 / (b - a); } else { return 0; } } praat-6.0.04/external/gsl/gsl_randist__gamma.c000066400000000000000000000117711261542461700213140ustar00rootroot00000000000000/* randist/gamma.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_sf_gamma.h" #include "gsl_rng.h" #include "gsl_randist.h" static double gamma_large (const gsl_rng * r, const double a); static double gamma_frac (const gsl_rng * r, const double a); /* The Gamma distribution of order a>0 is defined by: p(x) dx = {1 / \Gamma(a) b^a } x^{a-1} e^{-x/b} dx for x>0. If X and Y are independent gamma-distributed random variables of order a1 and a2 with the same scale parameter b, then X+Y has gamma distribution of order a1+a2. The algorithms below are from Knuth, vol 2, 2nd ed, p. 129. */ double gsl_ran_gamma_knuth (const gsl_rng * r, const double a, const double b) { /* assume a > 0 */ unsigned int na = floor (a); if (a == na) { return b * gsl_ran_gamma_int (r, na); } else if (na == 0) { return b * gamma_frac (r, a); } else { return b * (gsl_ran_gamma_int (r, na) + gamma_frac (r, a - na)) ; } } double gsl_ran_gamma_int (const gsl_rng * r, const unsigned int a) { if (a < 12) { unsigned int i; double prod = 1; for (i = 0; i < a; i++) { prod *= gsl_rng_uniform_pos (r); } /* Note: for 12 iterations we are safe against underflow, since the smallest positive random number is O(2^-32). This means the smallest possible product is 2^(-12*32) = 10^-116 which is within the range of double precision. */ return -log (prod); } else { return gamma_large (r, (double) a); } } static double gamma_large (const gsl_rng * r, const double a) { /* Works only if a > 1, and is most efficient if a is large This algorithm, reported in Knuth, is attributed to Ahrens. A faster one, we are told, can be found in: J. H. Ahrens and U. Dieter, Computing 12 (1974) 223-246. */ double sqa, x, y, v; sqa = sqrt (2 * a - 1); do { do { y = tan (M_PI * gsl_rng_uniform (r)); x = sqa * y + a - 1; } while (x <= 0); v = gsl_rng_uniform (r); } while (v > (1 + y * y) * exp ((a - 1) * log (x / (a - 1)) - sqa * y)); return x; } static double gamma_frac (const gsl_rng * r, const double a) { /* This is exercise 16 from Knuth; see page 135, and the solution is on page 551. */ double p, q, x, u, v; p = M_E / (a + M_E); do { u = gsl_rng_uniform (r); v = gsl_rng_uniform_pos (r); if (u < p) { x = exp ((1 / a) * log (v)); q = exp (-x); } else { x = 1 - log (v); q = exp ((a - 1) * log (x)); } } while (gsl_rng_uniform (r) >= q); return x; } double gsl_ran_gamma_pdf (const double x, const double a, const double b) { if (x < 0) { return 0 ; } else if (x == 0) { if (a == 1) return 1/b ; else return 0 ; } else if (a == 1) { return exp(-x/b)/b ; } else { double p; double lngamma = gsl_sf_lngamma (a); p = exp ((a - 1) * log (x/b) - x/b - lngamma)/b; return p; } } /* New version based on Marsaglia and Tsang, "A Simple Method for * generating gamma variables", ACM Transactions on Mathematical * Software, Vol 26, No 3 (2000), p363-372. * * Implemented by J.D.Lamb@btinternet.com, minor modifications for GSL * by Brian Gough */ double gsl_ran_gamma_mt (const gsl_rng * r, const double a, const double b) { return gsl_ran_gamma (r, a, b); } double gsl_ran_gamma (const gsl_rng * r, const double a, const double b) { /* assume a > 0 */ if (a < 1) { double u = gsl_rng_uniform_pos (r); return gsl_ran_gamma (r, 1.0 + a, b) * pow (u, 1.0 / a); } { double x, v, u; double d = a - 1.0 / 3.0; double c = (1.0 / 3.0) / sqrt (d); while (1) { do { x = gsl_ran_gaussian_ziggurat (r, 1.0); v = 1.0 + c * x; } while (v <= 0); v = v * v * v; u = gsl_rng_uniform_pos (r); if (u < 1 - 0.0331 * x * x * x * x) break; if (log (u) < 0.5 * x * x + d * (1 - v + log (v))) break; } return b * d * v; } } praat-6.0.04/external/gsl/gsl_randist__gauss.c000066400000000000000000000106301261542461700213450ustar00rootroot00000000000000/* randist/gauss.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2006, 2007 James Theiler, Brian Gough * Copyright (C) 2006 Charles Karney * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_rng.h" #include "gsl_randist.h" /* Of the two methods provided below, I think the Polar method is more * efficient, but only when you are actually producing two random * deviates. We don't produce two, because then we'd have to save one * in a static variable for the next call, and that would screws up * re-entrant or threaded code, so we only produce one. This makes * the Ratio method suddenly more appealing. * * [Added by Charles Karney] We use Leva's implementation of the Ratio * method which avoids calling log() nearly all the time and makes the * Ratio method faster than the Polar method (when it produces just one * result per call). Timing per call (gcc -O2 on 866MHz Pentium, * average over 10^8 calls) * * Polar method: 660 ns * Ratio method: 368 ns * */ /* Polar (Box-Mueller) method; See Knuth v2, 3rd ed, p122 */ double gsl_ran_gaussian (const gsl_rng * r, const double sigma) { double x, y, r2; do { /* choose x,y in uniform square (-1,-1) to (+1,+1) */ x = -1 + 2 * gsl_rng_uniform_pos (r); y = -1 + 2 * gsl_rng_uniform_pos (r); /* see if it is in the unit circle */ r2 = x * x + y * y; } while (r2 > 1.0 || r2 == 0); /* Box-Muller transform */ return sigma * y * sqrt (-2.0 * log (r2) / r2); } /* Ratio method (Kinderman-Monahan); see Knuth v2, 3rd ed, p130. * K+M, ACM Trans Math Software 3 (1977) 257-260. * * [Added by Charles Karney] This is an implementation of Leva's * modifications to the original K+M method; see: * J. L. Leva, ACM Trans Math Software 18 (1992) 449-453 and 454-455. */ double gsl_ran_gaussian_ratio_method (const gsl_rng * r, const double sigma) { double u, v, x, y, Q; const double s = 0.449871; /* Constants from Leva */ const double t = -0.386595; const double a = 0.19600; const double b = 0.25472; const double r1 = 0.27597; const double r2 = 0.27846; do /* This loop is executed 1.369 times on average */ { /* Generate a point P = (u, v) uniform in a rectangle enclosing the K+M region v^2 <= - 4 u^2 log(u). */ /* u in (0, 1] to avoid singularity at u = 0 */ u = 1 - gsl_rng_uniform (r); /* v is in the asymmetric interval [-0.5, 0.5). However v = -0.5 is rejected in the last part of the while clause. The resulting normal deviate is strictly symmetric about 0 (provided that v is symmetric once v = -0.5 is excluded). */ v = gsl_rng_uniform (r) - 0.5; /* Constant 1.7156 > sqrt(8/e) (for accuracy); but not by too much (for efficiency). */ v *= 1.7156; /* Compute Leva's quadratic form Q */ x = u - s; y = fabs (v) - t; Q = x * x + y * (a * y - b * x); /* Accept P if Q < r1 (Leva) */ /* Reject P if Q > r2 (Leva) */ /* Accept if v^2 <= -4 u^2 log(u) (K+M) */ /* This final test is executed 0.012 times on average. */ } while (Q >= r1 && (Q > r2 || v * v > -4 * u * u * log (u))); return sigma * (v / u); /* Return slope */ } double gsl_ran_gaussian_pdf (const double x, const double sigma) { double u = x / fabs (sigma); double p = (1 / (sqrt (2 * M_PI) * fabs (sigma))) * exp (-u * u / 2); return p; } double gsl_ran_ugaussian (const gsl_rng * r) { return gsl_ran_gaussian (r, 1.0); } double gsl_ran_ugaussian_ratio_method (const gsl_rng * r) { return gsl_ran_gaussian_ratio_method (r, 1.0); } double gsl_ran_ugaussian_pdf (const double x) { return gsl_ran_gaussian_pdf (x, 1.0); } praat-6.0.04/external/gsl/gsl_randist__gausstail.c000066400000000000000000000051301261542461700222160ustar00rootroot00000000000000/* randist/gausstail.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_rng.h" #include "gsl_randist.h" #include "gsl_sf_erf.h" double gsl_ran_gaussian_tail (const gsl_rng * r, const double a, const double sigma) { /* Returns a gaussian random variable larger than a * This implementation does one-sided upper-tailed deviates. */ double s = a / sigma; if (s < 1) { /* For small s, use a direct rejection method. The limit s < 1 can be adjusted to optimise the overall efficiency */ double x; do { x = gsl_ran_gaussian (r, 1.0); } while (x < s); return x * sigma; } else { /* Use the "supertail" deviates from the last two steps * of Marsaglia's rectangle-wedge-tail method, as described * in Knuth, v2, 3rd ed, pp 123-128. (See also exercise 11, p139, * and the solution, p586.) */ double u, v, x; do { u = gsl_rng_uniform (r); do { v = gsl_rng_uniform (r); } while (v == 0.0); x = sqrt (s * s - 2 * log (v)); } while (x * u > s); return x * sigma; } } double gsl_ran_gaussian_tail_pdf (const double x, const double a, const double sigma) { if (x < a) { return 0; } else { double N, p; double u = x / sigma ; double f = gsl_sf_erfc (a / (sqrt (2.0) * sigma)); N = 0.5 * f; p = (1 / (N * sqrt (2 * M_PI) * sigma)) * exp (-u * u / 2); return p; } } double gsl_ran_ugaussian_tail (const gsl_rng * r, const double a) { return gsl_ran_gaussian_tail (r, a, 1.0) ; } double gsl_ran_ugaussian_tail_pdf (const double x, const double a) { return gsl_ran_gaussian_tail_pdf (x, a, 1.0) ; } praat-6.0.04/external/gsl/gsl_randist__gausszig.c000066400000000000000000000216351261542461700220660ustar00rootroot00000000000000/* gauss.c - gaussian random numbers, using the Ziggurat method * * Copyright (C) 2005 Jochen Voss. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * This routine is based on the following article, with a couple of * modifications which simplify the implementation. * * George Marsaglia, Wai Wan Tsang * The Ziggurat Method for Generating Random Variables * Journal of Statistical Software, vol. 5 (2000), no. 8 * http://www.jstatsoft.org/v05/i08/ * * The modifications are: * * 1) use 128 steps instead of 256 to decrease the amount of static * data necessary. * * 2) use an acceptance sampling from an exponential wedge * exp(-R*(x-R/2)) for the tail of the base strip to simplify the * implementation. The area of exponential wedge is used in * calculating 'v' and the coefficients in ziggurat table, so the * coefficients differ slightly from those in the Marsaglia and Tsang * paper. * * See also Leong et al, "A Comment on the Implementation of the * Ziggurat Method", Journal of Statistical Software, vol 5 (2005), no 7. * */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_rng.h" #include "gsl_randist.h" /* position of right-most step */ #define PARAM_R 3.44428647676 /* tabulated values for the heigt of the Ziggurat levels */ static const double ytab[128] = { 1, 0.963598623011, 0.936280813353, 0.913041104253, 0.892278506696, 0.873239356919, 0.855496407634, 0.838778928349, 0.822902083699, 0.807732738234, 0.793171045519, 0.779139726505, 0.765577436082, 0.752434456248, 0.739669787677, 0.727249120285, 0.715143377413, 0.703327646455, 0.691780377035, 0.68048276891, 0.669418297233, 0.65857233912, 0.647931876189, 0.637485254896, 0.62722199145, 0.617132611532, 0.607208517467, 0.597441877296, 0.587825531465, 0.578352913803, 0.569017984198, 0.559815170911, 0.550739320877, 0.541785656682, 0.532949739145, 0.524227434628, 0.515614886373, 0.507108489253, 0.498704867478, 0.490400854812, 0.482193476986, 0.47407993601, 0.466057596125, 0.458123971214, 0.450276713467, 0.442513603171, 0.434832539473, 0.427231532022, 0.419708693379, 0.41226223212, 0.404890446548, 0.397591718955, 0.390364510382, 0.383207355816, 0.376118859788, 0.369097692334, 0.362142585282, 0.355252328834, 0.348425768415, 0.341661801776, 0.334959376311, 0.328317486588, 0.321735172063, 0.31521151497, 0.308745638367, 0.302336704338, 0.29598391232, 0.289686497571, 0.283443729739, 0.27725491156, 0.271119377649, 0.265036493387, 0.259005653912, 0.253026283183, 0.247097833139, 0.241219782932, 0.235391638239, 0.229612930649, 0.223883217122, 0.218202079518, 0.212569124201, 0.206983981709, 0.201446306496, 0.195955776745, 0.190512094256, 0.185114984406, 0.179764196185, 0.174459502324, 0.169200699492, 0.1639876086, 0.158820075195, 0.153697969964, 0.148621189348, 0.143589656295, 0.138603321143, 0.133662162669, 0.128766189309, 0.123915440582, 0.119109988745, 0.114349940703, 0.10963544023, 0.104966670533, 0.100343857232, 0.0957672718266, 0.0912372357329, 0.0867541250127, 0.082318375932, 0.0779304915295, 0.0735910494266, 0.0693007111742, 0.065060233529, 0.0608704821745, 0.056732448584, 0.05264727098, 0.0486162607163, 0.0446409359769, 0.0407230655415, 0.0368647267386, 0.0330683839378, 0.0293369977411, 0.0256741818288, 0.0220844372634, 0.0185735200577, 0.0151490552854, 0.0118216532614, 0.00860719483079, 0.00553245272614, 0.00265435214565 }; /* tabulated values for 2^24 times x[i]/x[i+1], * used to accept for U*x[i+1]<=x[i] without any floating point operations */ static const unsigned long ktab[128] = { 0, 12590644, 14272653, 14988939, 15384584, 15635009, 15807561, 15933577, 16029594, 16105155, 16166147, 16216399, 16258508, 16294295, 16325078, 16351831, 16375291, 16396026, 16414479, 16431002, 16445880, 16459343, 16471578, 16482744, 16492970, 16502368, 16511031, 16519039, 16526459, 16533352, 16539769, 16545755, 16551348, 16556584, 16561493, 16566101, 16570433, 16574511, 16578353, 16581977, 16585398, 16588629, 16591685, 16594575, 16597311, 16599901, 16602354, 16604679, 16606881, 16608968, 16610945, 16612818, 16614592, 16616272, 16617861, 16619363, 16620782, 16622121, 16623383, 16624570, 16625685, 16626730, 16627708, 16628619, 16629465, 16630248, 16630969, 16631628, 16632228, 16632768, 16633248, 16633671, 16634034, 16634340, 16634586, 16634774, 16634903, 16634972, 16634980, 16634926, 16634810, 16634628, 16634381, 16634066, 16633680, 16633222, 16632688, 16632075, 16631380, 16630598, 16629726, 16628757, 16627686, 16626507, 16625212, 16623794, 16622243, 16620548, 16618698, 16616679, 16614476, 16612071, 16609444, 16606571, 16603425, 16599973, 16596178, 16591995, 16587369, 16582237, 16576520, 16570120, 16562917, 16554758, 16545450, 16534739, 16522287, 16507638, 16490152, 16468907, 16442518, 16408804, 16364095, 16301683, 16207738, 16047994, 15704248, 15472926 }; /* tabulated values of 2^{-24}*x[i] */ static const double wtab[128] = { 1.62318314817e-08, 2.16291505214e-08, 2.54246305087e-08, 2.84579525938e-08, 3.10340022482e-08, 3.33011726243e-08, 3.53439060345e-08, 3.72152672658e-08, 3.8950989572e-08, 4.05763964764e-08, 4.21101548915e-08, 4.35664624904e-08, 4.49563968336e-08, 4.62887864029e-08, 4.75707945735e-08, 4.88083237257e-08, 5.00063025384e-08, 5.11688950428e-08, 5.22996558616e-08, 5.34016475624e-08, 5.44775307871e-08, 5.55296344581e-08, 5.65600111659e-08, 5.75704813695e-08, 5.85626690412e-08, 5.95380306862e-08, 6.04978791776e-08, 6.14434034901e-08, 6.23756851626e-08, 6.32957121259e-08, 6.42043903937e-08, 6.51025540077e-08, 6.59909735447e-08, 6.68703634341e-08, 6.77413882848e-08, 6.8604668381e-08, 6.94607844804e-08, 7.03102820203e-08, 7.11536748229e-08, 7.1991448372e-08, 7.2824062723e-08, 7.36519550992e-08, 7.44755422158e-08, 7.52952223703e-08, 7.61113773308e-08, 7.69243740467e-08, 7.77345662086e-08, 7.85422956743e-08, 7.93478937793e-08, 8.01516825471e-08, 8.09539758128e-08, 8.17550802699e-08, 8.25552964535e-08, 8.33549196661e-08, 8.41542408569e-08, 8.49535474601e-08, 8.57531242006e-08, 8.65532538723e-08, 8.73542180955e-08, 8.8156298059e-08, 8.89597752521e-08, 8.97649321908e-08, 9.05720531451e-08, 9.138142487e-08, 9.21933373471e-08, 9.30080845407e-08, 9.38259651738e-08, 9.46472835298e-08, 9.54723502847e-08, 9.63014833769e-08, 9.71350089201e-08, 9.79732621669e-08, 9.88165885297e-08, 9.96653446693e-08, 1.00519899658e-07, 1.0138063623e-07, 1.02247952126e-07, 1.03122261554e-07, 1.04003996769e-07, 1.04893609795e-07, 1.05791574313e-07, 1.06698387725e-07, 1.07614573423e-07, 1.08540683296e-07, 1.09477300508e-07, 1.1042504257e-07, 1.11384564771e-07, 1.12356564007e-07, 1.13341783071e-07, 1.14341015475e-07, 1.15355110887e-07, 1.16384981291e-07, 1.17431607977e-07, 1.18496049514e-07, 1.19579450872e-07, 1.20683053909e-07, 1.21808209468e-07, 1.2295639141e-07, 1.24129212952e-07, 1.25328445797e-07, 1.26556042658e-07, 1.27814163916e-07, 1.29105209375e-07, 1.30431856341e-07, 1.31797105598e-07, 1.3320433736e-07, 1.34657379914e-07, 1.36160594606e-07, 1.37718982103e-07, 1.39338316679e-07, 1.41025317971e-07, 1.42787873535e-07, 1.44635331499e-07, 1.4657889173e-07, 1.48632138436e-07, 1.50811780719e-07, 1.53138707402e-07, 1.55639532047e-07, 1.58348931426e-07, 1.61313325908e-07, 1.64596952856e-07, 1.68292495203e-07, 1.72541128694e-07, 1.77574279496e-07, 1.83813550477e-07, 1.92166040885e-07, 2.05295471952e-07, 2.22600839893e-07 }; double gsl_ran_gaussian_ziggurat (const gsl_rng * r, const double sigma) { unsigned long int i, j; int sign; double x, y; while (1) { i = gsl_rng_uniform_int (r, 256); /* choose the step */ j = gsl_rng_uniform_int (r, 16777216); /* sample from 2^24 */ sign = (i & 0x80) ? +1 : -1; i &= 0x7f; x = j * wtab[i]; if (j < ktab[i]) break; if (i < 127) { double y0, y1, U1; y0 = ytab[i]; y1 = ytab[i + 1]; U1 = gsl_rng_uniform (r); y = y1 + (y0 - y1) * U1; } else { double U1, U2; U1 = 1.0 - gsl_rng_uniform (r); U2 = gsl_rng_uniform (r); x = PARAM_R - log (U1) / PARAM_R; y = exp (-PARAM_R * (x - 0.5 * PARAM_R)) * U2; } if (y < exp (-0.5 * x * x)) break; } return sign * sigma * x; } praat-6.0.04/external/gsl/gsl_randist__geometric.c000066400000000000000000000031251261542461700222020ustar00rootroot00000000000000/* randist/geometric.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" #include "gsl_randist.h" /* Geometric distribution (bernoulli trial with probability p) prob(k) = p (1 - p)^(k-1) for n = 1, 2, 3, ... It gives the distribution of "waiting times" for an event that occurs with probability p. */ unsigned int gsl_ran_geometric (const gsl_rng * r, const double p) { double u = gsl_rng_uniform_pos (r); unsigned int k; if (p == 1) { k = 1; } else { k = log (u) / log (1 - p) + 1; } return k; } double gsl_ran_geometric_pdf (const unsigned int k, const double p) { if (k == 0) { return 0 ; } else if (k == 1) { return p ; } else { double P = p * pow (1 - p, k - 1.0); return P; } } praat-6.0.04/external/gsl/gsl_randist__gumbel.c000066400000000000000000000034551261542461700215050ustar00rootroot00000000000000/* randist/gumbel.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" #include "gsl_randist.h" /* The Type I Gumbel distribution has the form, p(x) dx = a b exp(-(b exp(-ax) + ax)) dx and the Type II Gumbel distribution has the form, p(x) dx = b a x^-(a+1) exp(-b x^-a)) dx */ double gsl_ran_gumbel1 (const gsl_rng * r, const double a, const double b) { double x = gsl_rng_uniform_pos (r); double z = (log(b) - log(-log(x))) / a; return z; } double gsl_ran_gumbel1_pdf (const double x, const double a, const double b) { double p = a * b * exp (-(b * exp(-a * x) + a * x)); return p; } double gsl_ran_gumbel2 (const gsl_rng * r, const double a, const double b) { double x = gsl_rng_uniform_pos (r); double z = pow(-b / log(x), 1/a); return z; } double gsl_ran_gumbel2_pdf (const double x, const double a, const double b) { if (x <= 0) { return 0 ; } else { double p = b * a * pow(x,-(a+1)) * exp (-b * pow(x, -a)); return p; } } praat-6.0.04/external/gsl/gsl_randist__hyperg.c000066400000000000000000000054161261542461700215270ustar00rootroot00000000000000/* randist/hyperg.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" #include "gsl_randist.h" #include "gsl_sf_gamma.h" /* The hypergeometric distribution has the form, prob(k) = choose(n1,t) choose(n2, t-k) / choose(n1+n2,t) where choose(a,b) = a!/(b!(a-b)!) n1 + n2 is the total population (tagged plus untagged) n1 is the tagged population t is the number of samples taken (without replacement) k is the number of tagged samples found */ unsigned int gsl_ran_hypergeometric (const gsl_rng * r, unsigned int n1, unsigned int n2, unsigned int t) { const unsigned int n = n1 + n2; unsigned int i = 0; unsigned int a = n1; unsigned int b = n1 + n2; unsigned int k = 0; if (t > n) { t = n ; } if (t < n / 2) { for (i = 0 ; i < t ; i++) { double u = gsl_rng_uniform(r) ; if (b * u < a) { k++ ; if (k == n1) return k ; a-- ; } b-- ; } return k; } else { for (i = 0 ; i < n - t ; i++) { double u = gsl_rng_uniform(r) ; if (b * u < a) { k++ ; if (k == n1) return n1 - k ; a-- ; } b-- ; } return n1 - k; } } double gsl_ran_hypergeometric_pdf (const unsigned int k, const unsigned int n1, const unsigned int n2, unsigned int t) { if (t > n1 + n2) { t = n1 + n2 ; } if (k > n1 || k > t) { return 0 ; } else if (t > n2 && k + n2 < t ) { return 0 ; } else { double p; double c1 = gsl_sf_lnchoose(n1,k); double c2 = gsl_sf_lnchoose(n2,t-k); double c3 = gsl_sf_lnchoose(n1+n2,t); p = exp(c1 + c2 - c3) ; return p; } } praat-6.0.04/external/gsl/gsl_randist__landau.c000066400000000000000000000511151261542461700214720ustar00rootroot00000000000000/* randist/landau.c * * Copyright (C) 2001, 2004 David Morrison * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Adapted from the CERN library routines DENLAN, RANLAN, and DISLAN * as described in http://consult.cern.ch/shortwrups/g110/top.html. * Original author: K.S. K\"olbig. * * The distribution is given by the complex path integral, * * p(x) = (1/(2 pi i)) \int_{c-i\inf}^{c+i\inf} ds exp(s log(s) + x s) * * which can be converted into a real integral over [0,+\inf] * * p(x) = (1/pi) \int_0^\inf dt \exp(-t log(t) - x t) sin(pi t) * */ #include "gsl__config.h" #include #include "gsl_rng.h" #include "gsl_randist.h" double gsl_ran_landau_pdf(const double x) { static double P1[5] = { 0.4259894875E0, -0.1249762550E0, 0.3984243700E-1, -0.6298287635E-2, 0.1511162253E-2 }; static double P2[5] = { 0.1788541609E0, 0.1173957403E0, 0.1488850518E-1, -0.1394989411E-2, 0.1283617211E-3 }; static double P3[5] = { 0.1788544503E0, 0.9359161662E-1, 0.6325387654E-2, 0.6611667319E-4, -0.2031049101E-5 }; static double P4[5] = { 0.9874054407E0, 0.1186723273E3, 0.8492794360E3, -0.7437792444E3, 0.4270262186E3 }; static double P5[5] = { 0.1003675074E1, 0.1675702434E3, 0.4789711289E4, 0.2121786767E5, -0.2232494910E5 }; static double P6[5] = { 0.1000827619E1, 0.6649143136E3, 0.6297292665E5, 0.4755546998E6, -0.5743609109E7 }; static double Q1[5] = { 1.0, -0.3388260629E0, 0.9594393323E-1, -0.1608042283E-1, 0.3778942063E-2 }; static double Q2[5] = { 1.0, 0.7428795082E0, 0.3153932961E0, 0.6694219548E-1, 0.8790609714E-2 }; static double Q3[5] = { 1.0, 0.6097809921E0, 0.2560616665E0, 0.4746722384E-1, 0.6957301675E-2 }; static double Q4[5] = { 1.0, 0.1068615961E3, 0.3376496214E3, 0.2016712389E4, 0.1597063511E4 }; static double Q5[5] = { 1.0, 0.1569424537E3, 0.3745310488E4, 0.9834698876E4, 0.6692428357E5 }; static double Q6[5] = { 1.0, 0.6514101098E3, 0.5697473333E5, 0.1659174725E6, -0.2815759939E7 }; static double A1[3] = { 0.4166666667E-1, -0.1996527778E-1, 0.2709538966E-1 }; static double A2[2] = { -0.1845568670E1, -0.4284640743E1 }; double U, V, DENLAN; V = x; if (V < -5.5) { U = exp(V + 1.0); DENLAN = 0.3989422803 * (exp( -1 / U) / sqrt(U)) * (1 + (A1[0] + (A1[1] + A1[2] * U) * U) * U); } else if (V < -1) { U = exp( -V - 1); DENLAN = exp( -U) * sqrt(U) * (P1[0] + (P1[1] + (P1[2] + (P1[3] + P1[4] * V) * V) * V) * V) / (Q1[0] + (Q1[1] + (Q1[2] + (Q1[3] + Q1[4] * V) * V) * V) * V); } else if (V < 1) { DENLAN = (P2[0] + (P2[1] + (P2[2] + (P2[3] + P2[4] * V) * V) * V) * V) / (Q2[0] + (Q2[1] + (Q2[2] + (Q2[3] + Q2[4] * V) * V) * V) * V); } else if (V < 5) { DENLAN = (P3[0] + (P3[1] + (P3[2] + (P3[3] + P3[4] * V) * V) * V) * V) / (Q3[0] + (Q3[1] + (Q3[2] + (Q3[3] + Q3[4] * V) * V) * V) * V); } else if (V < 12) { U = 1 / V; DENLAN = U * U * (P4[0] + (P4[1] + (P4[2] + (P4[3] + P4[4] * U) * U) * U) * U) / (Q4[0] + (Q4[1] + (Q4[2] + (Q4[3] + Q4[4] * U) * U) * U) * U); } else if (V < 50) { U = 1 / V; DENLAN = U * U * (P5[0] + (P5[1] + (P5[2] + (P5[3] + P5[4] * U) * U) * U) * U) / (Q5[0] + (Q5[1] + (Q5[2] + (Q5[3] + Q5[4] * U) * U) * U) * U); } else if (V < 300) { U = 1 / V; DENLAN = U * U * (P6[0] + (P6[1] + (P6[2] + (P6[3] + P6[4] * U) * U) * U) * U) / (Q6[0] + (Q6[1] + (Q6[2] + (Q6[3] + Q6[4] * U) * U) * U) * U); } else { U = 1 / (V - V * log(V) / (V + 1)); DENLAN = U * U * (1 + (A2[0] + A2[1] * U) * U); } return DENLAN; } #if 0 /* Not needed yet */ /* This function is a translation from the original Fortran of the * CERN library routine DISLAN, the integral from -inf to x of the * Landau p.d.f. */ static double gsl_ran_landau_dislan(const double x) { static double P1[5] = { 0.2514091491E0, -0.6250580444E-1, 0.1458381230E-1, -0.2108817737E-2, 0.7411247290E-3 }; static double P2[4] = { 0.2868328584E0, 0.3564363231E0, 0.1523518695E0, 0.2251304883E-1 }; static double P3[4] = { 0.2868329066E0, 0.3003828436E0, 0.9950951941E-1, 0.8733827185E-2 }; static double P4[4] = { 0.1000351630E1, 0.4503592498E1, 0.1085883880E2, 0.7536052269E1 }; static double P5[4] = { 0.1000006517E1, 0.4909414111E2, 0.8505544753E2, 0.1532153455E3 }; static double P6[4] = { 0.1000000983E1, 0.1329868456E3, 0.9162149244E3, -0.9605054274E3 }; static double Q1[5] = { 1.0, -0.5571175625E-2, 0.6225310236E-1, -0.3137378427E-2, 0.1931496439E-2 }; static double Q2[4] = { 1.0, 0.6191136137E0, 0.1720721448E0, 0.2278594771E-1 }; static double Q3[4] = { 1.0, 0.4237190502E0, 0.1095631512E0, 0.8693851567E-2 }; static double Q4[4] = { 1.0, 0.5539969678E1, 0.1933581111E2, 0.2721321508E2 }; static double Q5[4] = { 1.0, 0.5009928881E2, 0.1399819104E3, 0.4200002909E3 }; static double Q6[4] = { 1.0, 0.1339887843E3, 0.1055990413E4, 0.5532224619E3 }; static double A1[3] = { -0.4583333333E0, 0.6675347222E0, -0.1641741416E1 }; static double A2[3] = { 1.0, -0.4227843351E0, -0.2043403138E1 }; double U, V, DISLAN; V = x; if (V < -5.5) { U = exp(V + 1); DISLAN = 0.3989422803 * exp( -1 / U) * sqrt(U) * (1 + (A1[0] + (A1[1] + A1[2] * U) * U) * U); } else if (V < -1) { U = exp( -V - 1); DISLAN = (exp( -U) / sqrt(U)) * (P1[0] + (P1[1] + (P1[2] + (P1[3] + P1[4] * V) * V) * V) * V) / (Q1[0] + (Q1[1] + (Q1[2] + (Q1[3] + Q1[4] * V) * V) * V) * V); } else if (V < 1) { DISLAN = (P2[0] + (P2[1] + (P2[2] + P2[3] * V) * V) * V) / (Q2[0] + (Q2[1] + (Q2[2] + Q2[3] * V) * V) * V); } else if (V < 4) { DISLAN = (P3[0] + (P3[1] + (P3[2] + P3[3] * V) * V) * V) / (Q3[0] + (Q3[1] + (Q3[2] + Q3[3] * V) * V) * V); } else if (V < 12) { U = 1 / V; DISLAN = (P4[0] + (P4[1] + (P4[2] + P4[3] * U) * U) * U) / (Q4[0] + (Q4[1] + (Q4[2] + Q4[3] * U) * U) * U); } else if (V < 50) { U = 1 / V; DISLAN = (P5[0] + (P5[1] + (P5[2] + P5[3] * U) * U) * U) / (Q5[0] + (Q5[1] + (Q5[2] + Q5[3] * U) * U) * U); } else if (V < 300) { U = 1 / V; DISLAN = (P6[0] + (P6[1] + (P6[2] + P6[3] * U) * U) * U) / (Q6[0] + (Q6[1] + (Q6[2] + Q6[3] * U) * U) * U); } else { U = 1 / (V - V * log(V) / (V + 1)); DISLAN = 1 - (A2[0] + (A2[1] + A2[2] * U) * U) * U; } return DISLAN; } #endif double gsl_ran_landau(const gsl_rng * r) { static double F[983] = { 0.0000000, /* Add empty element [0] to account for difference between C and Fortran convention for lower bound. */ 00.000000, 00.000000, 00.000000, 00.000000, 00.000000, -2.244733, -2.204365, -2.168163, -2.135219, -2.104898, -2.076740, -2.050397, -2.025605, -2.002150, -1.979866, -1.958612, -1.938275, -1.918760, -1.899984, -1.881879, -1.864385, -1.847451, -1.831030, -1.815083, -1.799574, -1.784473, -1.769751, -1.755383, -1.741346, -1.727620, -1.714187, -1.701029, -1.688130, -1.675477, -1.663057, -1.650858, -1.638868, -1.627078, -1.615477, -1.604058, -1.592811, -1.581729, -1.570806, -1.560034, -1.549407, -1.538919, -1.528565, -1.518339, -1.508237, -1.498254, -1.488386, -1.478628, -1.468976, -1.459428, -1.449979, -1.440626, -1.431365, -1.422195, -1.413111, -1.404112, -1.395194, -1.386356, -1.377594, -1.368906, -1.360291, -1.351746, -1.343269, -1.334859, -1.326512, -1.318229, -1.310006, -1.301843, -1.293737, -1.285688, -1.277693, -1.269752, -1.261863, -1.254024, -1.246235, -1.238494, -1.230800, -1.223153, -1.215550, -1.207990, -1.200474, -1.192999, -1.185566, -1.178172, -1.170817, -1.163500, -1.156220, -1.148977, -1.141770, -1.134598, -1.127459, -1.120354, -1.113282, -1.106242, -1.099233, -1.092255, -1.085306, -1.078388, -1.071498, -1.064636, -1.057802, -1.050996, -1.044215, -1.037461, -1.030733, -1.024029, -1.017350, -1.010695, -1.004064, -0.997456, -0.990871, -0.984308, -0.977767, -0.971247, -0.964749, -0.958271, -0.951813, -0.945375, -0.938957, -0.932558, -0.926178, -0.919816, -0.913472, -0.907146, -0.900838, -0.894547, -0.888272, -0.882014, -0.875773, -0.869547, -0.863337, -0.857142, -0.850963, -0.844798, -0.838648, -0.832512, -0.826390, -0.820282, -0.814187, -0.808106, -0.802038, -0.795982, -0.789940, -0.783909, -0.777891, -0.771884, -0.765889, -0.759906, -0.753934, -0.747973, -0.742023, -0.736084, -0.730155, -0.724237, -0.718328, -0.712429, -0.706541, -0.700661, -0.694791, -0.688931, -0.683079, -0.677236, -0.671402, -0.665576, -0.659759, -0.653950, -0.648149, -0.642356, -0.636570, -0.630793, -0.625022, -0.619259, -0.613503, -0.607754, -0.602012, -0.596276, -0.590548, -0.584825, -0.579109, -0.573399, -0.567695, -0.561997, -0.556305, -0.550618, -0.544937, -0.539262, -0.533592, -0.527926, -0.522266, -0.516611, -0.510961, -0.505315, -0.499674, -0.494037, -0.488405, -0.482777, -0.477153, -0.471533, -0.465917, -0.460305, -0.454697, -0.449092, -0.443491, -0.437893, -0.432299, -0.426707, -0.421119, -0.415534, -0.409951, -0.404372, -0.398795, -0.393221, -0.387649, -0.382080, -0.376513, -0.370949, -0.365387, -0.359826, -0.354268, -0.348712, -0.343157, -0.337604, -0.332053, -0.326503, -0.320955, -0.315408, -0.309863, -0.304318, -0.298775, -0.293233, -0.287692, -0.282152, -0.276613, -0.271074, -0.265536, -0.259999, -0.254462, -0.248926, -0.243389, -0.237854, -0.232318, -0.226783, -0.221247, -0.215712, -0.210176, -0.204641, -0.199105, -0.193568, -0.188032, -0.182495, -0.176957, -0.171419, -0.165880, -0.160341, -0.154800, -0.149259, -0.143717, -0.138173, -0.132629, -0.127083, -0.121537, -0.115989, -0.110439, -0.104889, -0.099336, -0.093782, -0.088227, -0.082670, -0.077111, -0.071550, -0.065987, -0.060423, -0.054856, -0.049288, -0.043717, -0.038144, -0.032569, -0.026991, -0.021411, -0.015828, -0.010243, -0.004656, 00.000934, 00.006527, 00.012123, 00.017722, 00.023323, 00.028928, 00.034535, 00.040146, 00.045759, 00.051376, 00.056997, 00.062620, 00.068247, 00.073877, 00.079511, 00.085149, 00.090790, 00.096435, 00.102083, 00.107736, 00.113392, 00.119052, 00.124716, 00.130385, 00.136057, 00.141734, 00.147414, 00.153100, 00.158789, 00.164483, 00.170181, 00.175884, 00.181592, 00.187304, 00.193021, 00.198743, 00.204469, 00.210201, 00.215937, 00.221678, 00.227425, 00.233177, 00.238933, 00.244696, 00.250463, 00.256236, 00.262014, 00.267798, 00.273587, 00.279382, 00.285183, 00.290989, 00.296801, 00.302619, 00.308443, 00.314273, 00.320109, 00.325951, 00.331799, 00.337654, 00.343515, 00.349382, 00.355255, 00.361135, 00.367022, 00.372915, 00.378815, 00.384721, 00.390634, 00.396554, 00.402481, 00.408415, 00.414356, 00.420304, 00.426260, 00.432222, 00.438192, 00.444169, 00.450153, 00.456145, 00.462144, 00.468151, 00.474166, 00.480188, 00.486218, 00.492256, 00.498302, 00.504356, 00.510418, 00.516488, 00.522566, 00.528653, 00.534747, 00.540850, 00.546962, 00.553082, 00.559210, 00.565347, 00.571493, 00.577648, 00.583811, 00.589983, 00.596164, 00.602355, 00.608554, 00.614762, 00.620980, 00.627207, 00.633444, 00.639689, 00.645945, 00.652210, 00.658484, 00.664768, 00.671062, 00.677366, 00.683680, 00.690004, 00.696338, 00.702682, 00.709036, 00.715400, 00.721775, 00.728160, 00.734556, 00.740963, 00.747379, 00.753807, 00.760246, 00.766695, 00.773155, 00.779627, 00.786109, 00.792603, 00.799107, 00.805624, 00.812151, 00.818690, 00.825241, 00.831803, 00.838377, 00.844962, 00.851560, 00.858170, 00.864791, 00.871425, 00.878071, 00.884729, 00.891399, 00.898082, 00.904778, 00.911486, 00.918206, 00.924940, 00.931686, 00.938446, 00.945218, 00.952003, 00.958802, 00.965614, 00.972439, 00.979278, 00.986130, 00.992996, 00.999875, 01.006769, 01.013676, 01.020597, 01.027533, 01.034482, 01.041446, 01.048424, 01.055417, 01.062424, 01.069446, 01.076482, 01.083534, 01.090600, 01.097681, 01.104778, 01.111889, 01.119016, 01.126159, 01.133316, 01.140490, 01.147679, 01.154884, 01.162105, 01.169342, 01.176595, 01.183864, 01.191149, 01.198451, 01.205770, 01.213105, 01.220457, 01.227826, 01.235211, 01.242614, 01.250034, 01.257471, 01.264926, 01.272398, 01.279888, 01.287395, 01.294921, 01.302464, 01.310026, 01.317605, 01.325203, 01.332819, 01.340454, 01.348108, 01.355780, 01.363472, 01.371182, 01.378912, 01.386660, 01.394429, 01.402216, 01.410024, 01.417851, 01.425698, 01.433565, 01.441453, 01.449360, 01.457288, 01.465237, 01.473206, 01.481196, 01.489208, 01.497240, 01.505293, 01.513368, 01.521465, 01.529583, 01.537723, 01.545885, 01.554068, 01.562275, 01.570503, 01.578754, 01.587028, 01.595325, 01.603644, 01.611987, 01.620353, 01.628743, 01.637156, 01.645593, 01.654053, 01.662538, 01.671047, 01.679581, 01.688139, 01.696721, 01.705329, 01.713961, 01.722619, 01.731303, 01.740011, 01.748746, 01.757506, 01.766293, 01.775106, 01.783945, 01.792810, 01.801703, 01.810623, 01.819569, 01.828543, 01.837545, 01.846574, 01.855631, 01.864717, 01.873830, 01.882972, 01.892143, 01.901343, 01.910572, 01.919830, 01.929117, 01.938434, 01.947781, 01.957158, 01.966566, 01.976004, 01.985473, 01.994972, 02.004503, 02.014065, 02.023659, 02.033285, 02.042943, 02.052633, 02.062355, 02.072110, 02.081899, 02.091720, 02.101575, 02.111464, 02.121386, 02.131343, 02.141334, 02.151360, 02.161421, 02.171517, 02.181648, 02.191815, 02.202018, 02.212257, 02.222533, 02.232845, 02.243195, 02.253582, 02.264006, 02.274468, 02.284968, 02.295507, 02.306084, 02.316701, 02.327356, 02.338051, 02.348786, 02.359562, 02.370377, 02.381234, 02.392131, 02.403070, 02.414051, 02.425073, 02.436138, 02.447246, 02.458397, 02.469591, 02.480828, 02.492110, 02.503436, 02.514807, 02.526222, 02.537684, 02.549190, 02.560743, 02.572343, 02.583989, 02.595682, 02.607423, 02.619212, 02.631050, 02.642936, 02.654871, 02.666855, 02.678890, 02.690975, 02.703110, 02.715297, 02.727535, 02.739825, 02.752168, 02.764563, 02.777012, 02.789514, 02.802070, 02.814681, 02.827347, 02.840069, 02.852846, 02.865680, 02.878570, 02.891518, 02.904524, 02.917588, 02.930712, 02.943894, 02.957136, 02.970439, 02.983802, 02.997227, 03.010714, 03.024263, 03.037875, 03.051551, 03.065290, 03.079095, 03.092965, 03.106900, 03.120902, 03.134971, 03.149107, 03.163312, 03.177585, 03.191928, 03.206340, 03.220824, 03.235378, 03.250005, 03.264704, 03.279477, 03.294323, 03.309244, 03.324240, 03.339312, 03.354461, 03.369687, 03.384992, 03.400375, 03.415838, 03.431381, 03.447005, 03.462711, 03.478500, 03.494372, 03.510328, 03.526370, 03.542497, 03.558711, 03.575012, 03.591402, 03.607881, 03.624450, 03.641111, 03.657863, 03.674708, 03.691646, 03.708680, 03.725809, 03.743034, 03.760357, 03.777779, 03.795300, 03.812921, 03.830645, 03.848470, 03.866400, 03.884434, 03.902574, 03.920821, 03.939176, 03.957640, 03.976215, 03.994901, 04.013699, 04.032612, 04.051639, 04.070783, 04.090045, 04.109425, 04.128925, 04.148547, 04.168292, 04.188160, 04.208154, 04.228275, 04.248524, 04.268903, 04.289413, 04.310056, 04.330832, 04.351745, 04.372794, 04.393982, 04.415310, 04.436781, 04.458395, 04.480154, 04.502060, 04.524114, 04.546319, 04.568676, 04.591187, 04.613854, 04.636678, 04.659662, 04.682807, 04.706116, 04.729590, 04.753231, 04.777041, 04.801024, 04.825179, 04.849511, 04.874020, 04.898710, 04.923582, 04.948639, 04.973883, 04.999316, 05.024942, 05.050761, 05.076778, 05.102993, 05.129411, 05.156034, 05.182864, 05.209903, 05.237156, 05.264625, 05.292312, 05.320220, 05.348354, 05.376714, 05.405306, 05.434131, 05.463193, 05.492496, 05.522042, 05.551836, 05.581880, 05.612178, 05.642734, 05.673552, 05.704634, 05.735986, 05.767610, 05.799512, 05.831694, 05.864161, 05.896918, 05.929968, 05.963316, 05.996967, 06.030925, 06.065194, 06.099780, 06.134687, 06.169921, 06.205486, 06.241387, 06.277630, 06.314220, 06.351163, 06.388465, 06.426130, 06.464166, 06.502578, 06.541371, 06.580553, 06.620130, 06.660109, 06.700495, 06.741297, 06.782520, 06.824173, 06.866262, 06.908795, 06.951780, 06.995225, 07.039137, 07.083525, 07.128398, 07.173764, 07.219632, 07.266011, 07.312910, 07.360339, 07.408308, 07.456827, 07.505905, 07.555554, 07.605785, 07.656608, 07.708035, 07.760077, 07.812747, 07.866057, 07.920019, 07.974647, 08.029953, 08.085952, 08.142657, 08.200083, 08.258245, 08.317158, 08.376837, 08.437300, 08.498562, 08.560641, 08.623554, 08.687319, 08.751955, 08.817481, 08.883916, 08.951282, 09.019600, 09.088889, 09.159174, 09.230477, 09.302822, 09.376233, 09.450735, 09.526355, 09.603118, 09.681054, 09.760191, 09.840558, 09.922186, 10.005107, 10.089353, 10.174959, 10.261958, 10.350389, 10.440287, 10.531693, 10.624646, 10.719188, 10.815362, 10.913214, 11.012789, 11.114137, 11.217307, 11.322352, 11.429325, 11.538283, 11.649285, 11.762390, 11.877664, 11.995170, 12.114979, 12.237161, 12.361791, 12.488946, 12.618708, 12.751161, 12.886394, 13.024498, 13.165570, 13.309711, 13.457026, 13.607625, 13.761625, 13.919145, 14.080314, 14.245263, 14.414134, 14.587072, 14.764233, 14.945778, 15.131877, 15.322712, 15.518470, 15.719353, 15.925570, 16.137345, 16.354912, 16.578520, 16.808433, 17.044929, 17.288305, 17.538873, 17.796967, 18.062943, 18.337176, 18.620068, 18.912049, 19.213574, 19.525133, 19.847249, 20.180480, 20.525429, 20.882738, 21.253102, 21.637266, 22.036036, 22.450278, 22.880933, 23.329017, 23.795634, 24.281981, 24.789364, 25.319207, 25.873062, 26.452634, 27.059789, 27.696581, 28.365274, 29.068370, 29.808638, 30.589157, 31.413354, 32.285060, 33.208568, 34.188705, 35.230920, 36.341388, 37.527131, 38.796172, 40.157721, 41.622399, 43.202525, 44.912465, 46.769077, 48.792279, 51.005773, 53.437996, 56.123356, 59.103894 }; double X, U, V, RANLAN; int I; X = gsl_rng_uniform_pos(r); U = 1000.0 * X; I = U; U = U - I; if (I >= 70 && I <= 800) { RANLAN = F[I] + U * (F[I + 1] - F[I]); } else if (I >= 7 && I <= 980) { RANLAN = F[I] + U * (F[I + 1] - F[I] - 0.25 * (1 - U) * (F[I + 2] - F[I + 1] - F[I] + F[I - 1])); } else if (I < 7) { V = log(X); U = 1 / V; RANLAN = ((0.99858950 + (3.45213058E1 + 1.70854528E1 * U) * U) / (1 + (3.41760202E1 + 4.01244582 * U) * U)) * ( -log( -0.91893853 - V) - 1); } else { U = 1 - X; V = U * U; if (X <= 0.999) { RANLAN = (1.00060006 + 2.63991156E2 * U + 4.37320068E3 * V) / ((1 + 2.57368075E2 * U + 3.41448018E3 * V) * U); } else { RANLAN = (1.00001538 + 6.07514119E3 * U + 7.34266409E5 * V) / ((1 + 6.06511919E3 * U + 6.94021044E5 * V) * U); } } return RANLAN; } praat-6.0.04/external/gsl/gsl_randist__laplace.c000066400000000000000000000027041261542461700216270ustar00rootroot00000000000000/* randist/laplace.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" #include "gsl_randist.h" /* The two-sided exponential probability distribution is p(x) dx = (1/(2 a)) * exp(-|x/a|) dx for -infty < x < infty. It is also known as the Laplace distribution. */ double gsl_ran_laplace (const gsl_rng * r, const double a) { double u; do { u = 2 * gsl_rng_uniform (r) - 1.0; } while (u == 0.0); if (u < 0) { return a * log (-u); } else { return -a * log (u); } } double gsl_ran_laplace_pdf (const double x, const double a) { double p = (1/(2*a)) * exp (-fabs (x)/a); return p; } praat-6.0.04/external/gsl/gsl_randist__levy.c000066400000000000000000000072301261542461700212040ustar00rootroot00000000000000/* randist/levy.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_rng.h" #include "gsl_randist.h" /* The stable Levy probability distributions have the form p(x) dx = (1/(2 pi)) \int dt exp(- it x - |c t|^alpha) with 0 < alpha <= 2. For alpha = 1, we get the Cauchy distribution For alpha = 2, we get the Gaussian distribution with sigma = sqrt(2) c. Fromn Chapter 5 of Bratley, Fox and Schrage "A Guide to Simulation". The original reference given there is, J.M. Chambers, C.L. Mallows and B. W. Stuck. "A method for simulating stable random variates". Journal of the American Statistical Association, JASA 71 340-344 (1976). */ double gsl_ran_levy (const gsl_rng * r, const double c, const double alpha) { double u, v, t, s; u = M_PI * (gsl_rng_uniform_pos (r) - 0.5); if (alpha == 1) /* cauchy case */ { t = tan (u); return c * t; } do { v = gsl_ran_exponential (r, 1.0); } while (v == 0); if (alpha == 2) /* gaussian case */ { t = 2 * sin (u) * sqrt(v); return c * t; } /* general case */ t = sin (alpha * u) / pow (cos (u), 1 / alpha); s = pow (cos ((1 - alpha) * u) / v, (1 - alpha) / alpha); return c * t * s; } /* The following routine for the skew-symmetric case was provided by Keith Briggs. The stable Levy probability distributions have the form 2*pi* p(x) dx = \int dt exp(mu*i*t-|sigma*t|^alpha*(1-i*beta*sign(t)*tan(pi*alpha/2))) for alpha!=1 = \int dt exp(mu*i*t-|sigma*t|^alpha*(1+i*beta*sign(t)*2/pi*log(|t|))) for alpha==1 with 00. For beta=0, sigma=c, mu=0, we get gsl_ran_levy above. For alpha = 1, beta=0, we get the Lorentz distribution For alpha = 2, beta=0, we get the Gaussian distribution See A. Weron and R. Weron: Computer simulation of Lvy alpha-stable variables and processes, preprint Technical University of Wroclaw. http://www.im.pwr.wroc.pl/~hugo/Publications.html */ double gsl_ran_levy_skew (const gsl_rng * r, const double c, const double alpha, const double beta) { double V, W, X; if (beta == 0) /* symmetric case */ { return gsl_ran_levy (r, c, alpha); } V = M_PI * (gsl_rng_uniform_pos (r) - 0.5); do { W = gsl_ran_exponential (r, 1.0); } while (W == 0); if (alpha == 1) { X = ((M_PI_2 + beta * V) * tan (V) - beta * log (M_PI_2 * W * cos (V) / (M_PI_2 + beta * V))) / M_PI_2; return c * (X + beta * log (c) / M_PI_2); } else { double t = beta * tan (M_PI_2 * alpha); double B = atan (t) / alpha; double S = pow (1 + t * t, 1/(2 * alpha)); X = S * sin (alpha * (V + B)) / pow (cos (V), 1 / alpha) * pow (cos (V - alpha * (V + B)) / W, (1 - alpha) / alpha); return c * X; } } praat-6.0.04/external/gsl/gsl_randist__logarithmic.c000066400000000000000000000035141261542461700225300ustar00rootroot00000000000000/* randist/logarithmic.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" #include "gsl_randist.h" /* Logarithmic distribution prob(n) = p^n / (n log(1/(1-p)) for n = 1, 2, 3, ... We use Kemp's second accelerated generator, from Luc Devroye's book on "Non-Uniform Random Variate Generation", Springer */ unsigned int gsl_ran_logarithmic (const gsl_rng * r, const double p) { double c = log (1-p) ; double v = gsl_rng_uniform_pos (r); if (v >= p) { return 1 ; } else { double u = gsl_rng_uniform_pos (r); double q = 1 - exp (c * u); if (v <= q*q) { double x = 1 + log(v)/log(q) ; return x ; } else if (v <= q) { return 2; } else { return 1 ; } } } double gsl_ran_logarithmic_pdf (const unsigned int k, const double p) { if (k == 0) { return 0 ; } else { double P = pow(p, (double)k) / (double) k / log(1/(1-p)) ; return P; } } praat-6.0.04/external/gsl/gsl_randist__logistic.c000066400000000000000000000025711261542461700220450ustar00rootroot00000000000000/* randist/logistic.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" #include "gsl_randist.h" /* The logistic distribution has the form, p(x) dx = (1/a) exp(-x/a) / (1 + exp(-x/a))^2 dx for -infty < x < infty */ double gsl_ran_logistic (const gsl_rng * r, const double a) { double x, z; do { x = gsl_rng_uniform_pos (r); } while (x == 1); z = log (x / (1 - x)); return a * z; } double gsl_ran_logistic_pdf (const double x, const double a) { double u = exp (-fabs(x)/a); double p = u / (fabs(a) * (1 + u) * (1 + u)); return p; } praat-6.0.04/external/gsl/gsl_randist__lognormal.c000066400000000000000000000036041261542461700222200ustar00rootroot00000000000000/* randist/lognormal.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_rng.h" #include "gsl_randist.h" /* The lognormal distribution has the form p(x) dx = 1/(x * sqrt(2 pi sigma^2)) exp(-(ln(x) - zeta)^2/2 sigma^2) dx for x > 0. Lognormal random numbers are the exponentials of gaussian random numbers */ double gsl_ran_lognormal (const gsl_rng * r, const double zeta, const double sigma) { double u, v, r2, normal, z; do { /* choose x,y in uniform square (-1,-1) to (+1,+1) */ u = -1 + 2 * gsl_rng_uniform (r); v = -1 + 2 * gsl_rng_uniform (r); /* see if it is in the unit circle */ r2 = u * u + v * v; } while (r2 > 1.0 || r2 == 0); normal = u * sqrt (-2.0 * log (r2) / r2); z = exp (sigma * normal + zeta); return z; } double gsl_ran_lognormal_pdf (const double x, const double zeta, const double sigma) { if (x <= 0) { return 0 ; } else { double u = (log (x) - zeta)/sigma; double p = 1 / (x * fabs(sigma) * sqrt (2 * M_PI)) * exp (-(u * u) /2); return p; } } praat-6.0.04/external/gsl/gsl_randist__multinomial.c000066400000000000000000000056461261542461700225700ustar00rootroot00000000000000/* randist/multinomial.c * * Copyright (C) 2002 Gavin E. Crooks * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" #include "gsl_randist.h" #include "gsl_sf_gamma.h" /* The multinomial distribution has the form N! n_1 n_2 n_K prob(n_1, n_2, ... n_K) = -------------------- p_1 p_2 ... p_K (n_1! n_2! ... n_K!) where n_1, n_2, ... n_K are nonnegative integers, sum_{k=1,K} n_k = N, and p = (p_1, p_2, ..., p_K) is a probability distribution. Random variates are generated using the conditional binomial method. This scales well with N and does not require a setup step. Ref: C.S. David, The computer generation of multinomial random variates, Comp. Stat. Data Anal. 16 (1993) 205-217 */ void gsl_ran_multinomial (const gsl_rng * r, const size_t K, const unsigned int N, const double p[], unsigned int n[]) { size_t k; double norm = 0.0; double sum_p = 0.0; unsigned int sum_n = 0; /* p[k] may contain non-negative weights that do not sum to 1.0. * Even a probability distribution will not exactly sum to 1.0 * due to rounding errors. */ for (k = 0; k < K; k++) { norm += p[k]; } for (k = 0; k < K; k++) { if (p[k] > 0.0) { n[k] = gsl_ran_binomial (r, p[k] / (norm - sum_p), N - sum_n); } else { n[k] = 0; } sum_p += p[k]; sum_n += n[k]; } } double gsl_ran_multinomial_pdf (const size_t K, const double p[], const unsigned int n[]) { return exp (gsl_ran_multinomial_lnpdf (K, p, n)); } double gsl_ran_multinomial_lnpdf (const size_t K, const double p[], const unsigned int n[]) { size_t k; unsigned int N = 0; double log_pdf = 0.0; double norm = 0.0; for (k = 0; k < K; k++) { N += n[k]; } for (k = 0; k < K; k++) { norm += p[k]; } log_pdf = gsl_sf_lnfact (N); for (k = 0; k < K; k++) { log_pdf -= gsl_sf_lnfact (n[k]); } for (k = 0; k < K; k++) { log_pdf += log (p[k] / norm) * n[k]; } return log_pdf; } praat-6.0.04/external/gsl/gsl_randist__nbinomial.c000066400000000000000000000032241261542461700221740ustar00rootroot00000000000000/* randist/nbinomial.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" #include "gsl_randist.h" #include "gsl_sf_gamma.h" /* The negative binomial distribution has the form, prob(k) = Gamma(n + k)/(Gamma(n) Gamma(k + 1)) p^n (1-p)^k for k = 0, 1, ... . Note that n does not have to be an integer. This is the Leger's algorithm (given in the answers in Knuth) */ unsigned int gsl_ran_negative_binomial (const gsl_rng * r, double p, double n) { double X = gsl_ran_gamma (r, n, 1.0) ; unsigned int k = gsl_ran_poisson (r, X*(1-p)/p) ; return k ; } double gsl_ran_negative_binomial_pdf (const unsigned int k, const double p, double n) { double P; double f = gsl_sf_lngamma (k + n) ; double a = gsl_sf_lngamma (n) ; double b = gsl_sf_lngamma (k + 1.0) ; P = exp(f-a-b) * pow (p, n) * pow (1 - p, (double)k); return P; } praat-6.0.04/external/gsl/gsl_randist__pareto.c000066400000000000000000000025441261542461700215220ustar00rootroot00000000000000/* randist/pareto.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" #include "gsl_randist.h" /* The Pareto distribution has the form, p(x) dx = (a/b) / (x/b)^(a+1) dx for x >= b */ double gsl_ran_pareto (const gsl_rng * r, double a, const double b) { double x = gsl_rng_uniform_pos (r); double z = pow (x, -1 / a); return b * z; } double gsl_ran_pareto_pdf (const double x, const double a, const double b) { if (x >= b) { double p = (a/b) / pow (x/b, a + 1); return p; } else { return 0; } } praat-6.0.04/external/gsl/gsl_randist__pascal.c000066400000000000000000000032221261542461700214650ustar00rootroot00000000000000/* randist/pascal.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" #include "gsl_randist.h" /* The Pascal distribution is a negative binomial with valued integer n prob(k) = (n - 1 + k)!/(n!(k - 1)!) * p^n (1-p)^k for k = 0, 1, ..., n */ unsigned int gsl_ran_pascal (const gsl_rng * r, double p, unsigned int n) { /* This is a separate interface for the pascal distribution so that it can be optimized differently from the negative binomial in future. e.g. if n < 10 it might be faster to generate the Pascal distributions as the sum of geometric variates directly. */ unsigned int k = gsl_ran_negative_binomial (r, p, (double) n); return k; } double gsl_ran_pascal_pdf (const unsigned int k, const double p, unsigned int n) { double P = gsl_ran_negative_binomial_pdf (k, p, (double) n); return P; } praat-6.0.04/external/gsl/gsl_randist__poisson.c000066400000000000000000000040321261542461700217140ustar00rootroot00000000000000/* randist/poisson.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_sf_gamma.h" #include "gsl_rng.h" #include "gsl_randist.h" /* The poisson distribution has the form p(n) = (mu^n / n!) exp(-mu) for n = 0, 1, 2, ... . The method used here is the one from Knuth. */ unsigned int gsl_ran_poisson (const gsl_rng * r, double mu) { double emu; double prod = 1.0; unsigned int k = 0; while (mu > 10) { unsigned int m = mu * (7.0 / 8.0); double X = gsl_ran_gamma_int (r, m); if (X >= mu) { return k + gsl_ran_binomial (r, mu / X, m - 1); } else { k += m; mu -= X; } } /* This following method works well when mu is small */ emu = exp (-mu); do { prod *= gsl_rng_uniform (r); k++; } while (prod > emu); return k - 1; } void gsl_ran_poisson_array (const gsl_rng * r, size_t n, unsigned int array[], double mu) { size_t i; for (i = 0; i < n; i++) { array[i] = gsl_ran_poisson (r, mu); } return; } double gsl_ran_poisson_pdf (const unsigned int k, const double mu) { double p; double lf = gsl_sf_lnfact (k); p = exp (log (mu) * k - lf - mu); return p; } praat-6.0.04/external/gsl/gsl_randist__rayleigh.c000066400000000000000000000037731261542461700220410ustar00rootroot00000000000000/* randist/rayleigh.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" #include "gsl_randist.h" /* The Rayleigh distribution has the form p(x) dx = (x / sigma^2) exp(-x^2/(2 sigma^2)) dx for x = 0 ... +infty */ double gsl_ran_rayleigh (const gsl_rng * r, const double sigma) { double u = gsl_rng_uniform_pos (r); return sigma * sqrt(-2.0 * log (u)); } double gsl_ran_rayleigh_pdf (const double x, const double sigma) { if (x < 0) { return 0 ; } else { double u = x / sigma ; double p = (u / sigma) * exp(-u * u / 2.0) ; return p; } } /* The Rayleigh tail distribution has the form p(x) dx = (x / sigma^2) exp((a^2 - x^2)/(2 sigma^2)) dx for x = a ... +infty */ double gsl_ran_rayleigh_tail (const gsl_rng * r, const double a, const double sigma) { double u = gsl_rng_uniform_pos (r); return sqrt(a * a - 2.0 * sigma * sigma * log (u)); } double gsl_ran_rayleigh_tail_pdf (const double x, const double a, const double sigma) { if (x < a) { return 0 ; } else { double u = x / sigma ; double v = a / sigma ; double p = (u / sigma) * exp((v + u) * (v - u) / 2.0) ; return p; } } praat-6.0.04/external/gsl/gsl_randist__shuffle.c000066400000000000000000000067201261542461700216640ustar00rootroot00000000000000/* randist/shuffle.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_rng.h" #include "gsl_randist.h" /* Inline swap and copy functions for moving objects around */ static inline void swap (void * base, size_t size, size_t i, size_t j) { register char * a = size * i + (char *) base ; register char * b = size * j + (char *) base ; register size_t s = size ; if (i == j) return ; do { char tmp = *a; *a++ = *b; *b++ = tmp; } while (--s > 0); } static inline void copy (void * dest, size_t i, void * src, size_t j, size_t size) { register char * a = size * i + (char *) dest ; register char * b = size * j + (char *) src ; register size_t s = size ; do { *a++ = *b++; } while (--s > 0); } /* Randomly permute (shuffle) N indices Supply an array x[N] with nmemb members, each of size size and on return it will be shuffled into a random order. The algorithm is from Knuth, SemiNumerical Algorithms, v2, p139, who cites Moses and Oakford, and Durstenfeld */ void gsl_ran_shuffle (const gsl_rng * r, void * base, size_t n, size_t size) { size_t i ; for (i = n - 1; i > 0; i--) { size_t j = gsl_rng_uniform_int(r, i+1); /* originally (i + 1) * gsl_rng_uniform (r) */ swap (base, size, i, j) ; } } int gsl_ran_choose (const gsl_rng * r, void * dest, size_t k, void * src, size_t n, size_t size) { size_t i, j = 0; /* Choose k out of n items, return an array x[] of the k items. These items will prevserve the relative order of the original input -- you can use shuffle() to randomize the output if you wish */ if (k > n) { GSL_ERROR ("k is greater than n, cannot sample more than n items", GSL_EINVAL) ; } for (i = 0; i < n && j < k; i++) { if ((n - i) * gsl_rng_uniform (r) < k - j) { copy (dest, j, src, i, size) ; j++ ; } } return GSL_SUCCESS; } void gsl_ran_sample (const gsl_rng * r, void * dest, size_t k, void * src, size_t n, size_t size) { size_t i, j = 0; /* Choose k out of n items, with replacement */ for (i = 0; i < k; i++) { j = gsl_rng_uniform_int (r, n); /* originally n * gsl_rng_uniform (r) */ copy (dest, i, src, j, size) ; } } praat-6.0.04/external/gsl/gsl_randist__sphere.c000066400000000000000000000066341261542461700215220ustar00rootroot00000000000000/* randist/sphere.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" #include "gsl_randist.h" void gsl_ran_dir_2d (const gsl_rng * r, double *x, double *y) { /* This method avoids trig, but it does take an average of 8/pi = * 2.55 calls to the RNG, instead of one for the direct * trigonometric method. */ double u, v, s; do { u = -1 + 2 * gsl_rng_uniform (r); v = -1 + 2 * gsl_rng_uniform (r); s = u * u + v * v; } while (s > 1.0 || s == 0.0); /* This is the Von Neumann trick. See Knuth, v2, 3rd ed, p140 * (exercise 23). Note, no sin, cos, or sqrt ! */ *x = (u * u - v * v) / s; *y = 2 * u * v / s; /* Here is the more straightforward approach, * s = sqrt (s); *x = u / s; *y = v / s; * It has fewer total operations, but one of them is a sqrt */ } void gsl_ran_dir_2d_trig_method (const gsl_rng * r, double *x, double *y) { /* This is the obvious solution... */ /* It ain't clever, but since sin/cos are often hardware accelerated, * it can be faster -- it is on my home Pentium -- than von Neumann's * solution, or slower -- as it is on my Sun Sparc 20 at work */ double t = 6.2831853071795864 * gsl_rng_uniform (r); /* 2*PI */ *x = cos (t); *y = sin (t); } void gsl_ran_dir_3d (const gsl_rng * r, double *x, double *y, double *z) { double s, a; /* This is a variant of the algorithm for computing a random point * on the unit sphere; the algorithm is suggested in Knuth, v2, * 3rd ed, p136; and attributed to Robert E Knop, CACM, 13 (1970), * 326. */ /* Begin with the polar method for getting x,y inside a unit circle */ do { *x = -1 + 2 * gsl_rng_uniform (r); *y = -1 + 2 * gsl_rng_uniform (r); s = (*x) * (*x) + (*y) * (*y); } while (s > 1.0); *z = -1 + 2 * s; /* z uniformly distributed from -1 to 1 */ a = 2 * sqrt (1 - s); /* factor to adjust x,y so that x^2+y^2 * is equal to 1-z^2 */ *x *= a; *y *= a; } void gsl_ran_dir_nd (const gsl_rng * r, size_t n, double *x) { double d; size_t i; /* See Knuth, v2, 3rd ed, p135-136. The method is attributed to * G. W. Brown, in Modern Mathematics for the Engineer (1956). * The idea is that gaussians G(x) have the property that * G(x)G(y)G(z)G(...) is radially symmetric, a function only * r = sqrt(x^2+y^2+...) */ d = 0; do { for (i = 0; i < n; ++i) { x[i] = gsl_ran_gaussian (r, 1.0); d += x[i] * x[i]; } } while (d == 0); d = sqrt (d); for (i = 0; i < n; ++i) { x[i] /= d; } } praat-6.0.04/external/gsl/gsl_randist__tdist.c000066400000000000000000000041651261542461700213600ustar00rootroot00000000000000/* randist/tdist.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_sf_gamma.h" #include "gsl_rng.h" #include "gsl_randist.h" /* The t-distribution has the form p(x) dx = (Gamma((nu + 1)/2)/(sqrt(pi nu) Gamma(nu/2)) * (1 + (x^2)/nu)^-((nu + 1)/2) dx The method used here is the one described in Knuth */ double gsl_ran_tdist (const gsl_rng * r, const double nu) { if (nu <= 2) { double Y1 = gsl_ran_ugaussian (r); double Y2 = gsl_ran_chisq (r, nu); double t = Y1 / sqrt (Y2 / nu); return t; } else { double Y1, Y2, Z, t; do { Y1 = gsl_ran_ugaussian (r); Y2 = gsl_ran_exponential (r, 1 / (nu/2 - 1)); Z = Y1 * Y1 / (nu - 2); } while (1 - Z < 0 || exp (-Y2 - Z) > (1 - Z)); /* Note that there is a typo in Knuth's formula, the line below is taken from the original paper of Marsaglia, Mathematics of Computation, 34 (1980), p 234-256 */ t = Y1 / sqrt ((1 - 2 / nu) * (1 - Z)); return t; } } double gsl_ran_tdist_pdf (const double x, const double nu) { double p; double lg1 = gsl_sf_lngamma (nu / 2); double lg2 = gsl_sf_lngamma ((nu + 1) / 2); p = ((exp (lg2 - lg1) / sqrt (M_PI * nu)) * pow ((1 + x * x / nu), -(nu + 1) / 2)); return p; } praat-6.0.04/external/gsl/gsl_randist__weibull.c000066400000000000000000000030471261542461700216720ustar00rootroot00000000000000/* randist/weibull.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" #include "gsl_randist.h" /* The Weibull distribution has the form, p(x) dx = (b/a) (x/a)^(b-1) exp(-(x/a)^b) dx */ double gsl_ran_weibull (const gsl_rng * r, const double a, const double b) { double x = gsl_rng_uniform_pos (r); double z = pow (-log (x), 1 / b); return a * z; } double gsl_ran_weibull_pdf (const double x, const double a, const double b) { if (x < 0) { return 0 ; } else if (x == 0) { if (b == 1) return 1/a ; else return 0 ; } else if (b == 1) { return exp(-x/a)/a ; } else { double p = (b/a) * exp (-pow (x/a, b) + (b - 1) * log (x/a)); return p; } } praat-6.0.04/external/gsl/gsl_rng.h000066400000000000000000000153041261542461700171360ustar00rootroot00000000000000/* rng/gsl_rng.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_RNG_H__ #define __GSL_RNG_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { const char *name; unsigned long int max; unsigned long int min; size_t size; void (*set) (void *state, unsigned long int seed); unsigned long int (*get) (void *state); double (*get_double) (void *state); } gsl_rng_type; typedef struct { const gsl_rng_type * type; void *state; } gsl_rng; /* These structs also need to appear in default.c so you can select them via the environment variable GSL_RNG_TYPE */ GSL_VAR const gsl_rng_type *gsl_rng_borosh13; GSL_VAR const gsl_rng_type *gsl_rng_coveyou; GSL_VAR const gsl_rng_type *gsl_rng_cmrg; GSL_VAR const gsl_rng_type *gsl_rng_fishman18; GSL_VAR const gsl_rng_type *gsl_rng_fishman20; GSL_VAR const gsl_rng_type *gsl_rng_fishman2x; GSL_VAR const gsl_rng_type *gsl_rng_gfsr4; GSL_VAR const gsl_rng_type *gsl_rng_knuthran; GSL_VAR const gsl_rng_type *gsl_rng_knuthran2; GSL_VAR const gsl_rng_type *gsl_rng_knuthran2002; GSL_VAR const gsl_rng_type *gsl_rng_lecuyer21; GSL_VAR const gsl_rng_type *gsl_rng_minstd; GSL_VAR const gsl_rng_type *gsl_rng_mrg; GSL_VAR const gsl_rng_type *gsl_rng_mt19937; GSL_VAR const gsl_rng_type *gsl_rng_mt19937_1999; GSL_VAR const gsl_rng_type *gsl_rng_mt19937_1998; GSL_VAR const gsl_rng_type *gsl_rng_r250; GSL_VAR const gsl_rng_type *gsl_rng_ran0; GSL_VAR const gsl_rng_type *gsl_rng_ran1; GSL_VAR const gsl_rng_type *gsl_rng_ran2; GSL_VAR const gsl_rng_type *gsl_rng_ran3; GSL_VAR const gsl_rng_type *gsl_rng_rand; GSL_VAR const gsl_rng_type *gsl_rng_rand48; GSL_VAR const gsl_rng_type *gsl_rng_random128_bsd; GSL_VAR const gsl_rng_type *gsl_rng_random128_glibc2; GSL_VAR const gsl_rng_type *gsl_rng_random128_libc5; GSL_VAR const gsl_rng_type *gsl_rng_random256_bsd; GSL_VAR const gsl_rng_type *gsl_rng_random256_glibc2; GSL_VAR const gsl_rng_type *gsl_rng_random256_libc5; GSL_VAR const gsl_rng_type *gsl_rng_random32_bsd; GSL_VAR const gsl_rng_type *gsl_rng_random32_glibc2; GSL_VAR const gsl_rng_type *gsl_rng_random32_libc5; GSL_VAR const gsl_rng_type *gsl_rng_random64_bsd; GSL_VAR const gsl_rng_type *gsl_rng_random64_glibc2; GSL_VAR const gsl_rng_type *gsl_rng_random64_libc5; GSL_VAR const gsl_rng_type *gsl_rng_random8_bsd; GSL_VAR const gsl_rng_type *gsl_rng_random8_glibc2; GSL_VAR const gsl_rng_type *gsl_rng_random8_libc5; GSL_VAR const gsl_rng_type *gsl_rng_random_bsd; GSL_VAR const gsl_rng_type *gsl_rng_random_glibc2; GSL_VAR const gsl_rng_type *gsl_rng_random_libc5; GSL_VAR const gsl_rng_type *gsl_rng_randu; GSL_VAR const gsl_rng_type *gsl_rng_ranf; GSL_VAR const gsl_rng_type *gsl_rng_ranlux; GSL_VAR const gsl_rng_type *gsl_rng_ranlux389; GSL_VAR const gsl_rng_type *gsl_rng_ranlxd1; GSL_VAR const gsl_rng_type *gsl_rng_ranlxd2; GSL_VAR const gsl_rng_type *gsl_rng_ranlxs0; GSL_VAR const gsl_rng_type *gsl_rng_ranlxs1; GSL_VAR const gsl_rng_type *gsl_rng_ranlxs2; GSL_VAR const gsl_rng_type *gsl_rng_ranmar; GSL_VAR const gsl_rng_type *gsl_rng_slatec; GSL_VAR const gsl_rng_type *gsl_rng_taus; GSL_VAR const gsl_rng_type *gsl_rng_taus2; GSL_VAR const gsl_rng_type *gsl_rng_taus113; GSL_VAR const gsl_rng_type *gsl_rng_transputer; GSL_VAR const gsl_rng_type *gsl_rng_tt800; GSL_VAR const gsl_rng_type *gsl_rng_uni; GSL_VAR const gsl_rng_type *gsl_rng_uni32; GSL_VAR const gsl_rng_type *gsl_rng_vax; GSL_VAR const gsl_rng_type *gsl_rng_waterman14; GSL_VAR const gsl_rng_type *gsl_rng_zuf; const gsl_rng_type ** gsl_rng_types_setup(void); GSL_VAR const gsl_rng_type *gsl_rng_default; GSL_VAR unsigned long int gsl_rng_default_seed; gsl_rng *gsl_rng_alloc (const gsl_rng_type * T); int gsl_rng_memcpy (gsl_rng * dest, const gsl_rng * src); gsl_rng *gsl_rng_clone (const gsl_rng * r); void gsl_rng_free (gsl_rng * r); void gsl_rng_set (const gsl_rng * r, unsigned long int seed); unsigned long int gsl_rng_max (const gsl_rng * r); unsigned long int gsl_rng_min (const gsl_rng * r); const char *gsl_rng_name (const gsl_rng * r); int gsl_rng_fread (FILE * stream, gsl_rng * r); int gsl_rng_fwrite (FILE * stream, const gsl_rng * r); size_t gsl_rng_size (const gsl_rng * r); void * gsl_rng_state (const gsl_rng * r); void gsl_rng_print_state (const gsl_rng * r); const gsl_rng_type * gsl_rng_env_setup (void); unsigned long int gsl_rng_get (const gsl_rng * r); double gsl_rng_uniform (const gsl_rng * r); double gsl_rng_uniform_pos (const gsl_rng * r); unsigned long int gsl_rng_uniform_int (const gsl_rng * r, unsigned long int n); #ifdef HAVE_INLINE extern inline unsigned long int gsl_rng_get (const gsl_rng * r); extern inline unsigned long int gsl_rng_get (const gsl_rng * r) { return (r->type->get) (r->state); } extern inline double gsl_rng_uniform (const gsl_rng * r); extern inline double gsl_rng_uniform (const gsl_rng * r) { return (r->type->get_double) (r->state); } extern inline double gsl_rng_uniform_pos (const gsl_rng * r); extern inline double gsl_rng_uniform_pos (const gsl_rng * r) { double x ; do { x = (r->type->get_double) (r->state) ; } while (x == 0) ; return x ; } extern inline unsigned long int gsl_rng_uniform_int (const gsl_rng * r, unsigned long int n); extern inline unsigned long int gsl_rng_uniform_int (const gsl_rng * r, unsigned long int n) { unsigned long int offset = r->type->min; unsigned long int range = r->type->max - offset; unsigned long int scale; unsigned long int k; if (n > range || n == 0) { GSL_ERROR_VAL ("invalid n, either 0 or exceeds maximum value of generator", GSL_EINVAL, 0) ; } scale = range / n; do { k = (((r->type->get) (r->state)) - offset) / scale; } while (k >= n); return k; } #endif /* HAVE_INLINE */ __END_DECLS #endif /* __GSL_RNG_H__ */ praat-6.0.04/external/gsl/gsl_rng__borosh13.c000066400000000000000000000042321261542461700210060ustar00rootroot00000000000000/* rng/borosh13.c * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This generator is taken from * * Donald E. Knuth * The Art of Computer Programming * Volume 2 * Third Edition * Addison-Wesley * Page 106-108 * * It is called "Borosh - Niederreiter" * * This implementation copyright (C) 2001 Carlo Perassi and * (C) 2003 Heiko Bauke. */ #include "gsl__config.h" #include #include "gsl_rng.h" #define AA 1812433253UL #define MM 0xffffffffUL /* 2 ^ 32 - 1 */ static inline unsigned long int ran_get (void *vstate); static double ran_get_double (void *vstate); static void ran_set (void *state, unsigned long int s); typedef struct { unsigned long int x; } ran_state_t; static inline unsigned long int ran_get (void *vstate) { ran_state_t *state = (ran_state_t *) vstate; state->x = (AA * state->x) & MM; return state->x; } static double ran_get_double (void *vstate) { ran_state_t *state = (ran_state_t *) vstate; return ran_get (state) / 4294967296.0; } static void ran_set (void *vstate, unsigned long int s) { ran_state_t *state = (ran_state_t *) vstate; if (s == 0) s = 1; /* default seed is 1 */ state->x = s & MM; return; } static const gsl_rng_type ran_type = { "borosh13", /* name */ MM, /* RAND_MAX */ 1, /* RAND_MIN */ sizeof (ran_state_t), &ran_set, &ran_get, &ran_get_double }; const gsl_rng_type *gsl_rng_borosh13 = &ran_type; praat-6.0.04/external/gsl/gsl_rng__cmrg.c000066400000000000000000000123111261542461700202730ustar00rootroot00000000000000/* rng/cmrg.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" /* This is a combined multiple recursive generator. The sequence is, z_n = (x_n - y_n) mod m1 where the two underlying generators x and y are, x_n = (a_{1} x_{n-1} + a_{2} x_{n-2} + a_{3} x_{n-3}) mod m1 y_n = (b_{1} y_{n-1} + b_{2} y_{n-2} + b_{3} y_{n-3}) mod m2 with coefficients a11 ... a23, a_{1} = 0, a_{2} = 63308, a_{3} = -183326 b_{1} = 86098, b_{2} = 0, b_{3} = -539608 and moduli m1, m2, m1 = 2^31 - 1 = 2147483647 m2 = 2^31 - 2000169 = 2145483479 We initialize the generator with x_1 = s_1 MOD m1, x_2 = s_2 MOD m1, x_3 = s_3 MOD m1 y_1 = s_4 MOD m2, y_2 = s_5 MOD m2, y_3 = s_6 MOD m2 where s_n = (69069 * s_{n-1}) mod 2^32 and s_0 = s is the user-supplied seed. NOTE: According to the paper the initial values for x_n must lie in the range 0 <= x_n <= (m1 - 1) and the initial values for y_n must lie in the range 0 <= y_n <= (m2 - 1), with at least one non-zero value -- our seeding procedure satisfies these constraints. We then use 7 iterations of the generator to "warm up" the internal state. The theoretical value of z_{10008} is 719452880. The subscript 10008 means (1) seed the generator with s=1, (2) do the seven warm-up iterations that are part of the seeding process, (3) then do 10000 actual iterations. The period of this generator is about 2^205. From: P. L'Ecuyer, "Combined Multiple Recursive Random Number Generators," Operations Research, 44, 5 (1996), 816--822. This is available on the net from L'Ecuyer's home page, http://www.iro.umontreal.ca/~lecuyer/myftp/papers/combmrg.ps ftp://ftp.iro.umontreal.ca/pub/simulation/lecuyer/papers/combmrg.ps */ static inline unsigned long int cmrg_get (void *vstate); static double cmrg_get_double (void *vstate); static void cmrg_set (void *state, unsigned long int s); static const long int m1 = 2147483647, m2 = 2145483479; static const long int a2 = 63308, qa2 = 33921, ra2 = 12979; static const long int a3 = -183326, qa3 = 11714, ra3 = 2883; static const long int b1 = 86098, qb1 = 24919, rb1 = 7417; static const long int b3 = -539608, qb3 = 3976, rb3 = 2071; typedef struct { long int x1, x2, x3; /* first component */ long int y1, y2, y3; /* second component */ } cmrg_state_t; static inline unsigned long int cmrg_get (void *vstate) { cmrg_state_t *state = (cmrg_state_t *) vstate; /* Component 1 */ { long int h3 = state->x3 / qa3; long int p3 = -a3 * (state->x3 - h3 * qa3) - h3 * ra3; long int h2 = state->x2 / qa2; long int p2 = a2 * (state->x2 - h2 * qa2) - h2 * ra2; if (p3 < 0) p3 += m1; if (p2 < 0) p2 += m1; state->x3 = state->x2; state->x2 = state->x1; state->x1 = p2 - p3; if (state->x1 < 0) state->x1 += m1; } /* Component 2 */ { long int h3 = state->y3 / qb3; long int p3 = -b3 * (state->y3 - h3 * qb3) - h3 * rb3; long int h1 = state->y1 / qb1; long int p1 = b1 * (state->y1 - h1 * qb1) - h1 * rb1; if (p3 < 0) p3 += m2; if (p1 < 0) p1 += m2; state->y3 = state->y2; state->y2 = state->y1; state->y1 = p1 - p3; if (state->y1 < 0) state->y1 += m2; } if (state->x1 < state->y1) return (state->x1 - state->y1 + m1); else return (state->x1 - state->y1); } static double cmrg_get_double (void *vstate) { return cmrg_get (vstate) / 2147483647.0 ; } static void cmrg_set (void *vstate, unsigned long int s) { /* An entirely adhoc way of seeding! This does **not** come from L'Ecuyer et al */ cmrg_state_t *state = (cmrg_state_t *) vstate; if (s == 0) s = 1; /* default seed is 1 */ #define LCG(n) ((69069 * n) & 0xffffffffUL) s = LCG (s); state->x1 = s % m1; s = LCG (s); state->x2 = s % m1; s = LCG (s); state->x3 = s % m1; s = LCG (s); state->y1 = s % m2; s = LCG (s); state->y2 = s % m2; s = LCG (s); state->y3 = s % m2; /* "warm it up" */ cmrg_get (state); cmrg_get (state); cmrg_get (state); cmrg_get (state); cmrg_get (state); cmrg_get (state); cmrg_get (state); } static const gsl_rng_type cmrg_type = {"cmrg", /* name */ 2147483646, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (cmrg_state_t), &cmrg_set, &cmrg_get, &cmrg_get_double}; const gsl_rng_type *gsl_rng_cmrg = &cmrg_type; praat-6.0.04/external/gsl/gsl_rng__coveyou.c000066400000000000000000000043131261542461700210370ustar00rootroot00000000000000/* rng/coveyou.c * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This generator is taken from * * Donald E. Knuth * The Art of Computer Programming * Volume 2 * Third Edition * Addison-Wesley * Section 3.2.2 * * This implementation copyright (C) 2001 Carlo Perassi * and (C) 2003 Heiko Bauke. * Carlo Perassi reorganized the code to use the rng framework of GSL. */ #include "gsl__config.h" #include #include "gsl_rng.h" #define MM 0xffffffffUL /* 2 ^ 32 - 1 */ static inline unsigned long int ran_get (void *vstate); static double ran_get_double (void *vstate); static void ran_set (void *state, unsigned long int s); typedef struct { unsigned long int x; } ran_state_t; static inline unsigned long int ran_get (void *vstate) { ran_state_t *state = (ran_state_t *) vstate; state->x = (state->x * (state->x + 1)) & MM; return state->x; } static double ran_get_double (void *vstate) { ran_state_t *state = (ran_state_t *) vstate; return ran_get (state) / 4294967296.0; } static void ran_set (void *vstate, unsigned long int s) { ran_state_t *state = (ran_state_t *) vstate; unsigned long int diff = ((s % 4UL) - 2UL) % MM; if (diff) state->x = (s - diff) & MM; else state->x = s & MM; return; } static const gsl_rng_type ran_type = { "coveyou", /* name */ MM-1, /* RAND_MAX */ 2, /* RAND_MIN */ sizeof (ran_state_t), &ran_set, &ran_get, &ran_get_double }; const gsl_rng_type *gsl_rng_coveyou = &ran_type; praat-6.0.04/external/gsl/gsl_rng__default.c000066400000000000000000000045751261542461700210040ustar00rootroot00000000000000/* rng/default.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include #include "gsl_rng.h" #include "gsl_errno.h" /* The initial defaults are defined in the file mt.c, so we can get access to the static parts of the default generator. */ const gsl_rng_type * gsl_rng_env_setup (void) { unsigned long int seed = 0; const char *p = getenv ("GSL_RNG_TYPE"); if (p) { const gsl_rng_type **t, **t0 = gsl_rng_types_setup (); gsl_rng_default = 0; /* check GSL_RNG_TYPE against the names of all the generators */ for (t = t0; *t != 0; t++) { if (strcmp (p, (*t)->name) == 0) { gsl_rng_default = *t; break; } } if (gsl_rng_default == 0) { int i = 0; fprintf (stderr, "GSL_RNG_TYPE=%s not recognized\n", p); fprintf (stderr, "Valid generator types are:\n"); for (t = t0; *t != 0; t++) { fprintf (stderr, " %18s", (*t)->name); if ((++i) % 4 == 0) { fputc ('\n', stderr); } } fputc ('\n', stderr); GSL_ERROR_VAL ("unknown generator", GSL_EINVAL, 0); } fprintf (stderr, "GSL_RNG_TYPE=%s\n", gsl_rng_default->name); } else { gsl_rng_default = gsl_rng_mt19937; } p = getenv ("GSL_RNG_SEED"); if (p) { seed = strtoul (p, 0, 0); fprintf (stderr, "GSL_RNG_SEED=%lu\n", seed); }; gsl_rng_default_seed = seed; return gsl_rng_default; } praat-6.0.04/external/gsl/gsl_rng__file.c000066400000000000000000000025721261542461700202720ustar00rootroot00000000000000/* rng/file.c * * Copyright (C) 2003 Olaf Lenz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_rng.h" int gsl_rng_fread (FILE * stream, gsl_rng * r) { size_t n = r->type->size ; char * state = r->state; size_t items = fread (state, 1, n, stream); if (items != n) { GSL_ERROR ("fread failed", GSL_EFAILED); } return GSL_SUCCESS; } int gsl_rng_fwrite (FILE * stream, const gsl_rng * r) { size_t n = r->type->size ; char * state = r->state; size_t items = fwrite (state, 1, n, stream); if (items != n) { GSL_ERROR ("fwrite failed", GSL_EFAILED); } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_rng__fishman18.c000066400000000000000000000044471261542461700211540ustar00rootroot00000000000000/* rng/fishman18.c * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This generator is taken from * * Donald E. Knuth * The Art of Computer Programming * Volume 2 * Third Edition * Addison-Wesley * Page 106-108 * * It is called "Fishman - Moore III". * * This implementation copyright (C) 2001 Carlo Perassi * and (C) 2003 Heiko Bauke. */ #include "gsl__config.h" #include #include "gsl_rng.h" #include "gsl_rng__schrage.c" #define AA 62089911UL #define MM 0x7fffffffUL /* 2 ^ 31 - 1 */ #define CEIL_SQRT_MM 46341UL /* ceil(sqrt(2 ^ 31 - 1)) */ static inline unsigned long int ran_get (void *vstate); static double ran_get_double (void *vstate); static void ran_set (void *state, unsigned long int s); typedef struct { unsigned long int x; } ran_state_t; static inline unsigned long int ran_get (void *vstate) { ran_state_t *state = (ran_state_t *) vstate; state->x = schrage_mult (AA, state->x, MM, CEIL_SQRT_MM); return state->x; } static double ran_get_double (void *vstate) { ran_state_t *state = (ran_state_t *) vstate; return ran_get (state) / 2147483647.0; } static void ran_set (void *vstate, unsigned long int s) { ran_state_t *state = (ran_state_t *) vstate; if ((s % MM) == 0) s = 1; /* default seed is 1 */ state->x = s % MM; return; } static const gsl_rng_type ran_type = { "fishman18", /* name */ MM - 1, /* RAND_MAX */ 1, /* RAND_MIN */ sizeof (ran_state_t), &ran_set, &ran_get, &ran_get_double }; const gsl_rng_type *gsl_rng_fishman18 = &ran_type; praat-6.0.04/external/gsl/gsl_rng__fishman20.c000066400000000000000000000044631261542461700211430ustar00rootroot00000000000000/* rng/fishman20.c * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This generator is taken from * * Donald E. Knuth * The Art of Computer Programming * Volume 2 * Third Edition * Addison-Wesley * Page 108 * * It is called "Fishman" * * This implementation copyright (C) 2001 Carlo Perassi * and (C) 2003 Heiko Bauke. */ #include "gsl__config.h" #include #include "gsl_rng.h" static inline unsigned long int ran_get (void *vstate); static double ran_get_double (void *vstate); static void ran_set (void *state, unsigned long int s); static const long int m = 2147483647, a = 48271, q = 44488, r = 3399; typedef struct { unsigned long int x; } ran_state_t; static inline unsigned long int ran_get (void *vstate) { ran_state_t *state = (ran_state_t *) vstate; const unsigned long int x = state->x; const long int h = x / q; const long int t = a * (x - h * q) - h * r; if (t < 0) { state->x = t + m; } else { state->x = t; } return state->x; } static double ran_get_double (void *vstate) { ran_state_t *state = (ran_state_t *) vstate; return ran_get (state) / 2147483647.0; } static void ran_set (void *vstate, unsigned long int s) { ran_state_t *state = (ran_state_t *) vstate; if ((s%m) == 0) s = 1; /* default seed is 1 */ state->x = s & m; return; } static const gsl_rng_type ran_type = { "fishman20", /* name */ 2147483646, /* RAND_MAX */ 1, /* RAND_MIN */ sizeof (ran_state_t), &ran_set, &ran_get, &ran_get_double }; const gsl_rng_type *gsl_rng_fishman20 = &ran_type; praat-6.0.04/external/gsl/gsl_rng__fishman2x.c000066400000000000000000000055161261542461700212530ustar00rootroot00000000000000/* rng/fishman2x.c * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This generator is taken from * * Donald E. Knuth * The Art of Computer Programming * Volume 2 * Third Edition * Addison-Wesley * Page 108 * * It is called "Fishman - L'Ecuyer" * * This implementation copyright (C) 2001 Carlo Perassi * and (C) 2003 Heiko Bauke. */ #include "gsl__config.h" #include #include "gsl_rng.h" /* Fishman */ #define AAA_F 48271UL #define MMM_F 0x7fffffffUL /* 2 ^ 31 - 1 */ #define QQQ_F 44488UL #define RRR_F 3399UL /* L'Ecuyer */ #define AAA_L 40692UL #define MMM_L 0x7fffff07UL /* 2 ^ 31 - 249 */ #define QQQ_L 52774UL #define RRR_L 3791UL static inline unsigned long int ran_get (void *vstate); static double ran_get_double (void *vstate); static void ran_set (void *state, unsigned long int s); typedef struct { unsigned long int x; unsigned long int y; unsigned long int z; } ran_state_t; static inline unsigned long int ran_get (void *vstate) { ran_state_t *state = (ran_state_t *) vstate; long int y, r; r = RRR_F * (state->x / QQQ_F); y = AAA_F * (state->x % QQQ_F) - r; if (y < 0) y += MMM_F; state->x = y; r = RRR_L * (state->y / QQQ_L); y = AAA_L * (state->y % QQQ_L) - r; if (y < 0) y += MMM_L; state->y = y; state->z = (state->x > state->y) ? (state->x - state->y) : MMM_F + state->x - state->y; return state->z; } static double ran_get_double (void *vstate) { ran_state_t *state = (ran_state_t *) vstate; return ran_get (state) / 2147483647.0; } static void ran_set (void *vstate, unsigned long int s) { ran_state_t *state = (ran_state_t *) vstate; if ((s % MMM_F) == 0 || (s % MMM_L) == 0) s = 1; /* default seed is 1 */ state->x = s % MMM_F; state->y = s % MMM_L; state->z = (state->x > state->y) ? (state->x - state->y) : MMM_F + state->x - state->y; return; } static const gsl_rng_type ran_type = { "fishman2x", /* name */ MMM_F - 1, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (ran_state_t), &ran_set, &ran_get, &ran_get_double }; const gsl_rng_type *gsl_rng_fishman2x = &ran_type; praat-6.0.04/external/gsl/gsl_rng__gfsr4.c000066400000000000000000000126121261542461700203740ustar00rootroot00000000000000/* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA From Robert M. Ziff, "Four-tap shift-register-sequence random-number generators," Computers in Physics 12(4), Jul/Aug 1998, pp 385-392. A generalized feedback shift-register (GFSR) is basically an xor-sum of particular past lagged values. A four-tap register looks like: ra[nd] = ra[nd-A] ^ ra[nd-B] ^ ra[nd-C] ^ ra[nd-D] Ziff notes that "it is now widely known" that two-tap registers have serious flaws, the most obvious one being the three-point correlation that comes from the defn of the generator. Nice mathematical properties can be derived for GFSR's, and numerics bears out the claim that 4-tap GFSR's with appropriately chosen offsets are as random as can be measured, using the author's test. This implementation uses the values suggested the the author's example on p392, but altered to fit the GSL framework. The "state" is 2^14 longs, or 64Kbytes; 2^14 is the smallest power of two that is larger than D, the largest offset. We really only need a state with the last D values, but by going to a power of two, we can do a masking operation instead of a modulo, and this is presumably faster, though I haven't actually tried it. The article actually suggested a short/fast hack: #define RandomInteger (++nd, ra[nd&M]=ra[(nd-A)&M]\ ^ra[(nd-B)&M]^ra[(nd-C)&M]^ra[(nd-D)&M]) so that (as long as you've defined nd,ra[M+1]), then you ca do things like: 'if (RandomInteger < p) {...}'. Note that n&M varies from 0 to M, *including* M, so that the array has to be of size M+1. Since M+1 is a power of two, n&M is a potentially quicker implementation of the equivalent n%(M+1). This implementation copyright (C) 1998 James Theiler, based on the example mt.c in the GSL, as implemented by Brian Gough. */ #include "gsl__config.h" #include #include "gsl_rng.h" static inline unsigned long int gfsr4_get (void *vstate); static double gfsr4_get_double (void *vstate); static void gfsr4_set (void *state, unsigned long int s); /* Magic numbers */ #define A 471 #define B 1586 #define C 6988 #define D 9689 #define M 16383 /* = 2^14-1 */ /* #define M 0x0003fff */ typedef struct { int nd; unsigned long ra[M+1]; } gfsr4_state_t; static inline unsigned long gfsr4_get (void *vstate) { gfsr4_state_t *state = (gfsr4_state_t *) vstate; state->nd = ((state->nd)+1)&M; return state->ra[(state->nd)] = state->ra[((state->nd)+(M+1-A))&M]^ state->ra[((state->nd)+(M+1-B))&M]^ state->ra[((state->nd)+(M+1-C))&M]^ state->ra[((state->nd)+(M+1-D))&M]; } static double gfsr4_get_double (void * vstate) { return gfsr4_get (vstate) / 4294967296.0 ; } static void gfsr4_set (void *vstate, unsigned long int s) { gfsr4_state_t *state = (gfsr4_state_t *) vstate; int i, j; /* Masks for turning on the diagonal bit and turning off the leftmost bits */ unsigned long int msb = 0x80000000UL; unsigned long int mask = 0xffffffffUL; if (s == 0) s = 4357; /* the default seed is 4357 */ /* We use the congruence s_{n+1} = (69069*s_n) mod 2^32 to initialize the state. This works because ANSI-C unsigned long integer arithmetic is automatically modulo 2^32 (or a higher power of two), so we can safely ignore overflow. */ #define LCG(n) ((69069 * n) & 0xffffffffUL) /* Brian Gough suggests this to avoid low-order bit correlations */ for (i = 0; i <= M; i++) { unsigned long t = 0 ; unsigned long bit = msb ; for (j = 0; j < 32; j++) { s = LCG(s) ; if (s & msb) t |= bit ; bit >>= 1 ; } state->ra[i] = t ; } /* Perform the "orthogonalization" of the matrix */ /* Based on the orthogonalization used in r250, as suggested initially * by Kirkpatrick and Stoll, and pointed out to me by Brian Gough */ /* BJG: note that this orthogonalisation doesn't have any effect here because the the initial 6695 elements do not participate in the calculation. For practical purposes this orthogonalisation is somewhat irrelevant, because the probability of the original sequence being degenerate should be exponentially small. */ for (i=0; i<32; ++i) { int k=7+i*3; state->ra[k] &= mask; /* Turn off bits left of the diagonal */ state->ra[k] |= msb; /* Turn on the diagonal bit */ mask >>= 1; msb >>= 1; } state->nd = i; } static const gsl_rng_type gfsr4_type = {"gfsr4", /* name */ 0xffffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (gfsr4_state_t), &gfsr4_set, &gfsr4_get, &gfsr4_get_double}; const gsl_rng_type *gsl_rng_gfsr4 = &gfsr4_type; praat-6.0.04/external/gsl/gsl_rng__knuthran.c000066400000000000000000000113501261542461700211770ustar00rootroot00000000000000/* rng/knuthran.c * * Copyright (C) 2001, 2007 Brian Gough, Carlo Perassi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This generator is taken from * * Donald E. Knuth * The Art of Computer Programming * Volume 2 * Third Edition * Addison-Wesley * Section 3.6 * * The comments are taken from the book * Our comments are signed */ #include "gsl__config.h" #include #include "gsl_rng.h" #define BUFLEN 2009 /* [Brian]: length of the buffer aa[] */ #define KK 100 /* the long lag */ #define LL 37 /* the short lag */ #define MM (1L << 30) /* the modulus */ #define TT 70 /* guaranteed separation between streams */ #define evenize(x) ((x) & (MM - 2)) /* make x even */ #define is_odd(x) ((x) & 1) /* the units bit of x */ #define mod_diff(x, y) (((x) - (y)) & (MM - 1)) /* (x - y) mod MM */ static inline void ran_array (unsigned long int aa[], unsigned int n, unsigned long int ran_x[]); static inline unsigned long int ran_get (void *vstate); static double ran_get_double (void *vstate); static void ran_set (void *state, unsigned long int s); typedef struct { unsigned int i; unsigned long int aa[BUFLEN]; /* [Carlo]: I can't pass n to ran_array like Knuth does */ unsigned long int ran_x[KK]; /* the generator state */ } ran_state_t; static inline void ran_array (unsigned long int aa[], unsigned int n, unsigned long int ran_x[]) { unsigned int i; unsigned int j; for (j = 0; j < KK; j++) aa[j] = ran_x[j]; for (; j < n; j++) aa[j] = mod_diff (aa[j - KK], aa[j - LL]); for (i = 0; i < LL; i++, j++) ran_x[i] = mod_diff (aa[j - KK], aa[j - LL]); for (; i < KK; i++, j++) ran_x[i] = mod_diff (aa[j - KK], ran_x[i - LL]); } static inline unsigned long int ran_get (void *vstate) { ran_state_t *state = (ran_state_t *) vstate; unsigned int i = state->i; if (i == 0) { /* fill buffer with new random numbers */ ran_array (state->aa, BUFLEN, state->ran_x); } state->i = (i + 1) % BUFLEN; return state->aa[i]; } static double ran_get_double (void *vstate) { ran_state_t *state = (ran_state_t *) vstate; return ran_get (state) / 1073741824.0; /* [Carlo]: RAND_MAX + 1 */ } static void ran_set (void *vstate, unsigned long int s) { ran_state_t *state = (ran_state_t *) vstate; long x[KK + KK - 1]; /* the preparation buffer */ register int j; register int t; register long ss = evenize (s + 2); for (j = 0; j < KK; j++) { x[j] = ss; /* bootstrap the buffer */ ss <<= 1; if (ss >= MM) /* cyclic shift 29 bits */ ss -= MM - 2; } for (; j < KK + KK - 1; j++) x[j] = 0; x[1]++; /* make x[1] (and only x[1]) odd */ ss = s & (MM - 1); t = TT - 1; while (t) { for (j = KK - 1; j > 0; j--) /* square */ x[j + j] = x[j]; for (j = KK + KK - 2; j > KK - LL; j -= 2) x[KK + KK - 1 - j] = evenize (x[j]); for (j = KK + KK - 2; j >= KK; j--) if (is_odd (x[j])) { x[j - (KK - LL)] = mod_diff (x[j - (KK - LL)], x[j]); x[j - KK] = mod_diff (x[j - KK], x[j]); } if (is_odd (ss)) { /* multiply by "z" */ for (j = KK; j > 0; j--) x[j] = x[j - 1]; x[0] = x[KK]; /* shift the buffer cyclically */ if (is_odd (x[KK])) x[LL] = mod_diff (x[LL], x[KK]); } if (ss) ss >>= 1; else t--; } state->i = 0; for (j = 0; j < LL; j++) state->ran_x[j + KK - LL] = x[j]; for (; j < KK; j++) state->ran_x[j - LL] = x[j]; return; } static const gsl_rng_type ran_type = { "knuthran", /* name */ 0x3fffffffUL, /* RAND_MAX *//* [Carlo]: (2 ^ 30) - 1 */ 0, /* RAND_MIN */ sizeof (ran_state_t), &ran_set, &ran_get, &ran_get_double }; const gsl_rng_type *gsl_rng_knuthran = &ran_type; praat-6.0.04/external/gsl/gsl_rng__knuthran2.c000066400000000000000000000050041261542461700212600ustar00rootroot00000000000000/* rng/knuthran2.c * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This generator is taken from * * Donald E. Knuth * The Art of Computer Programming * Volume 2 * Third Edition * Addison-Wesley * Page 108 * * This implementation copyright (C) 2001 Carlo Perassi * and (C) 2003 Heiko Bauke. */ #include "gsl__config.h" #include #include "gsl_rng.h" #include "gsl_rng__schrage.c" #define AA1 271828183UL #define AA2 1833324378UL /* = -314159269 mod (2 ^ 31 -1) */ #define MM 0x7fffffffUL /* 2 ^ 31 - 1 */ #define CEIL_SQRT_MM 46341UL /* sqrt(2 ^ 31 - 1) */ static inline unsigned long int ran_get (void *vstate); static double ran_get_double (void *vstate); static void ran_set (void *state, unsigned long int s); typedef struct { unsigned long int x0; unsigned long int x1; } ran_state_t; static inline unsigned long int ran_get (void *vstate) { ran_state_t *state = (ran_state_t *) vstate; const unsigned long int xtmp = state->x1; state->x1 = schrage_mult (AA1, state->x1, MM, CEIL_SQRT_MM) + schrage_mult (AA2, state->x0, MM, CEIL_SQRT_MM); if (state->x1 >= MM) state->x1 -= MM; state->x0 = xtmp; return state->x1; } static double ran_get_double (void *vstate) { ran_state_t *state = (ran_state_t *) vstate; return ran_get (state) / 2147483647.0; } static void ran_set (void *vstate, unsigned long int s) { ran_state_t *state = (ran_state_t *) vstate; if ((s % MM) == 0) s = 1; /* default seed is 1 */ state->x0 = s % MM; state->x1 = s % MM; return; } static const gsl_rng_type ran_type = { "knuthran2", /* name */ MM - 1L, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (ran_state_t), &ran_set, &ran_get, &ran_get_double }; const gsl_rng_type *gsl_rng_knuthran2 = &ran_type; praat-6.0.04/external/gsl/gsl_rng__knuthran2002.c000066400000000000000000000114311261542461700215030ustar00rootroot00000000000000/* rng/knuthran2002.c * * Copyright (C) 2007 Brian Gough * Copyright (C) 2001, 2007 Brian Gough, Carlo Perassi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This generator is taken from * * Donald E. Knuth, The Art of Computer Programming, Volume 2, Section 3.6 * Third Edition, Addison-Wesley, * * The modifications introduced in the 9th printing (2002) are * included here; there's no backwards compatibility with the * original. [ see http://www-cs-faculty.stanford.edu/~knuth/taocp.html ] * */ #include "gsl__config.h" #include #include "gsl_rng.h" #define BUFLEN 1009 /* length of the buffer aa[] */ #define KK 100 /* the long lag */ #define LL 37 /* the short lag */ #define MM (1L << 30) /* the modulus */ #define TT 70 /* guaranteed separation between streams */ #define is_odd(x) ((x) & 1) /* the units bit of x */ #define mod_diff(x, y) (((x) - (y)) & (MM - 1)) /* (x - y) mod MM */ static inline void ran_array (long int aa[], unsigned int n, long int ran_x[]); static inline unsigned long int ran_get (void *vstate); static double ran_get_double (void *vstate); static void ran_set (void *state, unsigned long int s); typedef struct { unsigned int i; long int aa[BUFLEN]; long int ran_x[KK]; /* the generator state */ } ran_state_t; static inline void ran_array (long int aa[], unsigned int n, long int ran_x[]) { unsigned int i; unsigned int j; for (j = 0; j < KK; j++) aa[j] = ran_x[j]; for (; j < n; j++) aa[j] = mod_diff (aa[j - KK], aa[j - LL]); for (i = 0; i < LL; i++, j++) ran_x[i] = mod_diff (aa[j - KK], aa[j - LL]); for (; i < KK; i++, j++) ran_x[i] = mod_diff (aa[j - KK], ran_x[i - LL]); } static inline unsigned long int ran_get (void *vstate) { ran_state_t *state = (ran_state_t *) vstate; unsigned int i = state->i; unsigned long int v; if (i == 0) { /* fill buffer with new random numbers */ ran_array (state->aa, BUFLEN, state->ran_x); } v = state->aa[i]; state->i = (i + 1) % KK; return v; } static double ran_get_double (void *vstate) { ran_state_t *state = (ran_state_t *) vstate; return ran_get (state) / 1073741824.0; /* RAND_MAX + 1 */ } static void ran_set (void *vstate, unsigned long int s) { ran_state_t *state = (ran_state_t *) vstate; long x[KK + KK - 1]; /* the preparation buffer */ register int j; register int t; register long ss; if (s == 0 ) s = 314159; /* default seed used by Knuth */ ss = (s + 2)&(MM-2); for (j = 0; j < KK; j++) { x[j] = ss; /* bootstrap the buffer */ ss <<= 1; if (ss >= MM) /* cyclic shift 29 bits */ ss -= MM - 2; } x[1]++; /* make x[1] (and only x[1]) odd */ ss = s & (MM - 1); t = TT - 1; while (t) { for (j = KK - 1; j > 0; j--) /* square */ { x[j + j] = x[j]; x[j + j - 1] = 0; } for (j = KK + KK - 2; j >= KK; j--) { x[j - (KK - LL)] = mod_diff (x[j - (KK - LL)], x[j]); x[j - KK] = mod_diff (x[j - KK], x[j]); } if (is_odd (ss)) { /* multiply by "z" */ for (j = KK; j > 0; j--) { x[j] = x[j - 1]; } x[0] = x[KK]; /* shift the buffer cyclically */ x[LL] = mod_diff (x[LL], x[KK]); } if (ss) ss >>= 1; else t--; } for (j = 0; j < LL; j++) state->ran_x[j + KK - LL] = x[j]; for (; j < KK; j++) state->ran_x[j - LL] = x[j]; for (j = 0; j< 10; j++) ran_array(x, KK+KK-1, state->ran_x); /* warm things up */ state->i = 0; return; } static const gsl_rng_type ran_type = { "knuthran2002", /* name */ 0x3fffffffUL, /* RAND_MAX = (2 ^ 30) - 1 */ 0, /* RAND_MIN */ sizeof (ran_state_t), &ran_set, &ran_get, &ran_get_double }; const gsl_rng_type *gsl_rng_knuthran2002 = &ran_type; praat-6.0.04/external/gsl/gsl_rng__lecuyer21.c000066400000000000000000000043441261542461700211650ustar00rootroot00000000000000/* rng/lecuyer21.c * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This generator is taken from * * Donald E. Knuth * The Art of Computer Programming * Volume 2 * Third Edition * Addison-Wesley * Page 108 * * This implementation copyright (C) 2001 Brian Gough, Carlo Perassi * and (C) 2003 Heiko Bauke. */ #include "gsl__config.h" #include #include "gsl_rng.h" #define AAA 40692 #define MMM 2147483399UL #define QQQ 52774 #define RRR 3791 static inline unsigned long int ran_get (void *vstate); static double ran_get_double (void *vstate); static void ran_set (void *state, unsigned long int s); typedef struct { unsigned long int x; } ran_state_t; static inline unsigned long int ran_get (void *vstate) { ran_state_t *state = (ran_state_t *) vstate; long int y = state->x; long int r = RRR * (y / QQQ); y = AAA * (y % QQQ) - r; if (y < 0) y += MMM; state->x = y; return state->x; } static double ran_get_double (void *vstate) { ran_state_t *state = (ran_state_t *) vstate; return ran_get (state) / 2147483399.0; } static void ran_set (void *vstate, unsigned long int s) { ran_state_t *state = (ran_state_t *) vstate; if ((s%MMM) == 0) s = 1; /* default seed is 1 */ state->x = s % MMM; return; } static const gsl_rng_type ran_type = { "lecuyer21", /* name */ MMM-1, /* RAND_MAX */ 1, /* RAND_MIN */ sizeof (ran_state_t), &ran_set, &ran_get, &ran_get_double }; const gsl_rng_type *gsl_rng_lecuyer21 = &ran_type; praat-6.0.04/external/gsl/gsl_rng__minstd.c000066400000000000000000000054701261542461700206510ustar00rootroot00000000000000/* rng/minstd.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" /* MINSTD is Park and Miller's minimal standard generator (i.e. it's not particularly good). The sequence is x_{n+1} = (a x_n) mod m with a = 16807 and m = 2^31 - 1 = 2147483647. The seed specifies the initial value, x_1. The theoretical value of x_{10001} is 1043618065, starting with a seed of x_1 = 1. The period of this generator is 2^31. It is used as the RNUN subroutine in the IMSL Library and the RAND function in MATLAB. The generator is sometimes known by the acronym "GGL" (I'm not sure what that stands for). From: Park and Miller, "Random Number Generators: Good ones are hard to find" Communications of the ACM, October 1988, Volume 31, No 10, pages 1192-1201. */ static inline unsigned long int minstd_get (void *vstate); static double minstd_get_double (void *vstate); static void minstd_set (void *state, unsigned long int s); static const long int m = 2147483647, a = 16807, q = 127773, r = 2836; typedef struct { unsigned long int x; } minstd_state_t; static inline unsigned long int minstd_get (void *vstate) { minstd_state_t *state = (minstd_state_t *) vstate; const unsigned long int x = state->x; const long int h = x / q; const long int t = a * (x - h * q) - h * r; if (t < 0) { state->x = t + m; } else { state->x = t; } return state->x; } static double minstd_get_double (void *vstate) { return minstd_get (vstate) / 2147483647.0; } static void minstd_set (void *vstate, unsigned long int s) { minstd_state_t *state = (minstd_state_t *) vstate; if (s == 0) s = 1; /* default seed is 1 */ state->x = s; return; } static const gsl_rng_type minstd_type = {"minstd", /* name */ 2147483646, /* RAND_MAX */ 1, /* RAND_MIN */ sizeof (minstd_state_t), &minstd_set, &minstd_get, &minstd_get_double}; const gsl_rng_type *gsl_rng_minstd = &minstd_type; praat-6.0.04/external/gsl/gsl_rng__mrg.c000066400000000000000000000076011261542461700201360ustar00rootroot00000000000000/* rng/mrg.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" /* This is a fifth-order multiple recursive generator. The sequence is, x_n = (a_1 x_{n-1} + a_5 x_{n-5}) mod m with a_1 = 107374182, a_2 = a_3 = a_4 = 0, a_5 = 104480 and m = 2^31-1. We initialize the generator with x_n = s_n MOD m for n = 1..5, where s_n = (69069 * s_{n-1}) mod 2^32, and s_0 = s is the user-supplied seed. NOTE: According to the paper the seeds must lie in the range [0, 2^31 - 2] with at least one non-zero value -- our seeding procedure satisfies these constraints. We then use 6 iterations of the generator to "warm up" the internal state. With this initialization procedure the theoretical value of z_{10006} is 2064828650 for s = 1. The subscript 10006 means (1) seed the generator with s = 1, (2) do the 6 warm-up iterations that are part of the seeding process, (3) then do 10000 actual iterations. The period of this generator is about 2^155. From: P. L'Ecuyer, F. Blouin, and R. Coutre, "A search for good multiple recursive random number generators", ACM Transactions on Modeling and Computer Simulation 3, 87-98 (1993). */ static inline unsigned long int mrg_get (void *vstate); static double mrg_get_double (void *vstate); static void mrg_set (void *state, unsigned long int s); static const long int m = 2147483647; static const long int a1 = 107374182, q1 = 20, r1 = 7; static const long int a5 = 104480, q5 = 20554, r5 = 1727; typedef struct { long int x1, x2, x3, x4, x5; } mrg_state_t; static inline unsigned long int mrg_get (void *vstate) { mrg_state_t *state = (mrg_state_t *) vstate; long int p1, h1, p5, h5; h5 = state->x5 / q5; p5 = a5 * (state->x5 - h5 * q5) - h5 * r5; if (p5 > 0) p5 -= m; h1 = state->x1 / q1; p1 = a1 * (state->x1 - h1 * q1) - h1 * r1; if (p1 < 0) p1 += m; state->x5 = state->x4; state->x4 = state->x3; state->x3 = state->x2; state->x2 = state->x1; state->x1 = p1 + p5; if (state->x1 < 0) state->x1 += m; return state->x1; } static double mrg_get_double (void *vstate) { return mrg_get (vstate) / 2147483647.0 ; } static void mrg_set (void *vstate, unsigned long int s) { /* An entirely adhoc way of seeding! This does **not** come from L'Ecuyer et al */ mrg_state_t *state = (mrg_state_t *) vstate; if (s == 0) s = 1; /* default seed is 1 */ #define LCG(n) ((69069 * n) & 0xffffffffUL) s = LCG (s); state->x1 = s % m; s = LCG (s); state->x2 = s % m; s = LCG (s); state->x3 = s % m; s = LCG (s); state->x4 = s % m; s = LCG (s); state->x5 = s % m; /* "warm it up" with at least 5 calls to go through all the x values */ mrg_get (state); mrg_get (state); mrg_get (state); mrg_get (state); mrg_get (state); mrg_get (state); return; } static const gsl_rng_type mrg_type = {"mrg", /* name */ 2147483646, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (mrg_state_t), &mrg_set, &mrg_get, &mrg_get_double}; const gsl_rng_type *gsl_rng_mrg = &mrg_type; praat-6.0.04/external/gsl/gsl_rng__mt.c000066400000000000000000000146371261542461700200000ustar00rootroot00000000000000/* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Original implementation was copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. Coded by Takuji Nishimura, considering the suggestions by Topher Cooper and Marc Rieffel in July-Aug. 1997, "A C-program for MT19937: Integer version (1998/4/6)" This implementation copyright (C) 1998 Brian Gough. I reorganized the code to use the module framework of GSL. The license on this implementation was changed from LGPL to GPL, following paragraph 3 of the LGPL, version 2. Update: The seeding procedure has been updated to match the 10/99 release of MT19937. Update: The seeding procedure has been updated again to match the 2002 release of MT19937 The original code included the comment: "When you use this, send an email to: matumoto@math.keio.ac.jp with an appropriate reference to your work". Makoto Matsumoto has a web page with more information about the generator, http://www.math.keio.ac.jp/~matumoto/emt.html. The paper below has details of the algorithm. From: Makoto Matsumoto and Takuji Nishimura, "Mersenne Twister: A 623-dimensionally equidistributerd uniform pseudorandom number generator". ACM Transactions on Modeling and Computer Simulation, Vol. 8, No. 1 (Jan. 1998), Pages 3-30 You can obtain the paper directly from Makoto Matsumoto's web page. The period of this generator is 2^{19937} - 1. */ #include "gsl__config.h" #include #include "gsl_rng.h" static inline unsigned long int mt_get (void *vstate); static double mt_get_double (void *vstate); static void mt_set (void *state, unsigned long int s); #define N 624 /* Period parameters */ #define M 397 /* most significant w-r bits */ static const unsigned long UPPER_MASK = 0x80000000UL; /* least significant r bits */ static const unsigned long LOWER_MASK = 0x7fffffffUL; typedef struct { unsigned long mt[N]; int mti; } mt_state_t; static inline unsigned long mt_get (void *vstate) { mt_state_t *state = (mt_state_t *) vstate; unsigned long k ; unsigned long int *const mt = state->mt; #define MAGIC(y) (((y)&0x1) ? 0x9908b0dfUL : 0) if (state->mti >= N) { /* generate N words at one time */ int kk; for (kk = 0; kk < N - M; kk++) { unsigned long y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK); mt[kk] = mt[kk + M] ^ (y >> 1) ^ MAGIC(y); } for (; kk < N - 1; kk++) { unsigned long y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK); mt[kk] = mt[kk + (M - N)] ^ (y >> 1) ^ MAGIC(y); } { unsigned long y = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK); mt[N - 1] = mt[M - 1] ^ (y >> 1) ^ MAGIC(y); } state->mti = 0; } /* Tempering */ k = mt[state->mti]; k ^= (k >> 11); k ^= (k << 7) & 0x9d2c5680UL; k ^= (k << 15) & 0xefc60000UL; k ^= (k >> 18); state->mti++; return k; } static double mt_get_double (void * vstate) { return mt_get (vstate) / 4294967296.0 ; } static void mt_set (void *vstate, unsigned long int s) { mt_state_t *state = (mt_state_t *) vstate; int i; if (s == 0) s = 4357; /* the default seed is 4357 */ state->mt[0]= s & 0xffffffffUL; for (i = 1; i < N; i++) { /* See Knuth's "Art of Computer Programming" Vol. 2, 3rd Ed. p.106 for multiplier. */ state->mt[i] = (1812433253UL * (state->mt[i-1] ^ (state->mt[i-1] >> 30)) + i); state->mt[i] &= 0xffffffffUL; } state->mti = i; } static void mt_1999_set (void *vstate, unsigned long int s) { mt_state_t *state = (mt_state_t *) vstate; int i; if (s == 0) s = 4357; /* the default seed is 4357 */ /* This is the October 1999 version of the seeding procedure. It was updated by the original developers to avoid the periodicity in the simple congruence originally used. Note that an ANSI-C unsigned long integer arithmetic is automatically modulo 2^32 (or a higher power of two), so we can safely ignore overflow. */ #define LCG(x) ((69069 * x) + 1) &0xffffffffUL for (i = 0; i < N; i++) { state->mt[i] = s & 0xffff0000UL; s = LCG(s); state->mt[i] |= (s &0xffff0000UL) >> 16; s = LCG(s); } state->mti = i; } /* This is the original version of the seeding procedure, no longer used but available for compatibility with the original MT19937. */ static void mt_1998_set (void *vstate, unsigned long int s) { mt_state_t *state = (mt_state_t *) vstate; int i; if (s == 0) s = 4357; /* the default seed is 4357 */ state->mt[0] = s & 0xffffffffUL; #define LCG1998(n) ((69069 * n) & 0xffffffffUL) for (i = 1; i < N; i++) state->mt[i] = LCG1998 (state->mt[i - 1]); state->mti = i; } static const gsl_rng_type mt_type = {"mt19937", /* name */ 0xffffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (mt_state_t), &mt_set, &mt_get, &mt_get_double}; static const gsl_rng_type mt_1999_type = {"mt19937_1999", /* name */ 0xffffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (mt_state_t), &mt_1999_set, &mt_get, &mt_get_double}; static const gsl_rng_type mt_1998_type = {"mt19937_1998", /* name */ 0xffffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (mt_state_t), &mt_1998_set, &mt_get, &mt_get_double}; const gsl_rng_type *gsl_rng_mt19937 = &mt_type; const gsl_rng_type *gsl_rng_mt19937_1999 = &mt_1999_type; const gsl_rng_type *gsl_rng_mt19937_1998 = &mt_1998_type; /* MT19937 is the default generator, so define that here too */ const gsl_rng_type *gsl_rng_default = &mt_type; unsigned long int gsl_rng_default_seed = 0; praat-6.0.04/external/gsl/gsl_rng__r250.c000066400000000000000000000113251261542461700200370ustar00rootroot00000000000000/* rng/r250.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" /* This is a shift-register random number generator. The sequence is x_n = x_{n-103} ^ x_{n-250} ("^" means XOR) defined on 32-bit words. BJG: Note that this implementation actually uses the sequence, x_n = x_{n-147} ^ x_{n-250} which generates the outputs in time-reversed order but is otherwise completely equivalent. The first 250 elements x_1 .. x_250 are first initialized as x_n = s_n, where s_n = (69069*s_{n-1}) mod 2^32 and s_0=s is the user-supplied seed. To ensure that the sequence does not lie on a subspace we force 32 of the entries to be linearly independent. We take the 32 elements x[3], x[10], x[17], x[24], ..., 213 and apply the following operations, x[3] &= 11111111111111111111111111111111 x[3] |= 10000000000000000000000000000000 x[10] &= 01111111111111111111111111111111 x[10] |= 01000000000000000000000000000000 x[17] &= 00111111111111111111111111111111 x[17] |= 00100000000000000000000000000000 .... ... x[206] &= 00000000000000000000000000000111 x[206] |= 00000000000000000000000000000100 x[213] &= 00000000000000000000000000000011 x[213] |= 00000000000000000000000000000010 x[220] &= 00000000000000000000000000000001 x[220] |= 00000000000000000000000000000001 i.e. if we consider the bits of the 32 elements as forming a 32x32 array then we are setting the diagonal bits of the array to one and masking the lower triangle below the diagonal to zero. With this initialization procedure the theoretical value of x_{10001} is 1100653588 for s = 1 (Actually I got this by running the original code). The subscript 10001 means (1) seed the generator with s = 1 and then do 10000 actual iterations. The period of this generator is about 2^250. The algorithm works for any number of bits. It is implemented here for 32 bits. From: S. Kirkpatrick and E. Stoll, "A very fast shift-register sequence random number generator", Journal of Computational Physics, 40, 517-526 (1981). */ static inline unsigned long int r250_get (void *vstate); static double r250_get_double (void *vstate); static void r250_set (void *state, unsigned long int s); typedef struct { int i; unsigned long x[250]; } r250_state_t; static inline unsigned long int r250_get (void *vstate) { r250_state_t *state = (r250_state_t *) vstate; unsigned long int k; int j; int i = state->i; if (i >= 147) { j = i - 147; } else { j = i + 103; } k = state->x[i] ^ state->x[j]; state->x[i] = k; if (i >= 249) { state->i = 0; } else { state->i = i + 1; } return k; } static double r250_get_double (void *vstate) { return r250_get (vstate) / 4294967296.0 ; } static void r250_set (void *vstate, unsigned long int s) { r250_state_t *state = (r250_state_t *) vstate; int i; if (s == 0) s = 1; /* default seed is 1 */ state->i = 0; #define LCG(n) ((69069 * n) & 0xffffffffUL) for (i = 0; i < 250; i++) /* Fill the buffer */ { s = LCG (s); state->x[i] = s; } { /* Masks for turning on the diagonal bit and turning off the leftmost bits */ unsigned long int msb = 0x80000000UL; unsigned long int mask = 0xffffffffUL; for (i = 0; i < 32; i++) { int k = 7 * i + 3; /* Select a word to operate on */ state->x[k] &= mask; /* Turn off bits left of the diagonal */ state->x[k] |= msb; /* Turn on the diagonal bit */ mask >>= 1; msb >>= 1; } } return; } static const gsl_rng_type r250_type = {"r250", /* name */ 0xffffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (r250_state_t), &r250_set, &r250_get, &r250_get_double}; const gsl_rng_type *gsl_rng_r250 = &r250_type; praat-6.0.04/external/gsl/gsl_rng__ran0.c000066400000000000000000000050451261542461700202110ustar00rootroot00000000000000/* rng/ran0.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_rng.h" /* This is an implementation of the algorithm used in Numerical Recipe's ran0 generator. It is the same as MINSTD with an XOR mask of 123459876 on the seed. The period of this generator is 2^31. Note, if you choose a seed of 123459876 it would give a degenerate series 0,0,0,0, ... I've made that into an error. */ static inline unsigned long int ran0_get (void *vstate); static double ran0_get_double (void *vstate); static void ran0_set (void *state, unsigned long int s); static const long int m = 2147483647, a = 16807, q = 127773, r = 2836; static const unsigned long int mask = 123459876; typedef struct { unsigned long int x; } ran0_state_t; static inline unsigned long int ran0_get (void *vstate) { ran0_state_t *state = (ran0_state_t *) vstate; const unsigned long int x = state->x; const long int h = x / q; const long int t = a * (x - h * q) - h * r; if (t < 0) { state->x = t + m; } else { state->x = t; } return state->x; } static double ran0_get_double (void *vstate) { return ran0_get (vstate) / 2147483647.0 ; } static void ran0_set (void *vstate, unsigned long int s) { ran0_state_t *state = (ran0_state_t *) vstate; if (s == mask) { GSL_ERROR_VOID ("ran0 should not use seed == mask", GSL_EINVAL); } state->x = s ^ mask; return; } static const gsl_rng_type ran0_type = {"ran0", /* name */ 2147483646, /* RAND_MAX */ 1, /* RAND_MIN */ sizeof (ran0_state_t), &ran0_set, &ran0_get, &ran0_get_double}; const gsl_rng_type *gsl_rng_ran0 = &ran0_type; praat-6.0.04/external/gsl/gsl_rng__ran1.c000066400000000000000000000057031261542461700202130ustar00rootroot00000000000000/* rng/ran1.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" /* This is an implementation of the algorithm used in Numerical Recipe's ran1 generator. It is MINSTD with a 32-element shuffle-box. */ static inline unsigned long int ran1_get (void *vstate); static double ran1_get_double (void *vstate); static void ran1_set (void *state, unsigned long int s); static const long int m = 2147483647, a = 16807, q = 127773, r = 2836; #define N_SHUFFLE 32 #define N_DIV (1 + 2147483646/N_SHUFFLE) typedef struct { unsigned long int x; unsigned long int n; unsigned long int shuffle[N_SHUFFLE]; } ran1_state_t; static inline unsigned long int ran1_get (void *vstate) { ran1_state_t *state = (ran1_state_t *) vstate; const unsigned long int x = state->x; const long int h = x / q; const long int t = a * (x - h * q) - h * r; if (t < 0) { state->x = t + m; } else { state->x = t; } { unsigned long int j = state->n / N_DIV; state->n = state->shuffle[j]; state->shuffle[j] = state->x; } return state->n; } static double ran1_get_double (void *vstate) { float x_max = 1 - 1.2e-7f ; /* Numerical Recipes version of 1-FLT_EPS */ float x = ran1_get (vstate) / 2147483647.0f ; if (x > x_max) return x_max ; return x ; } static void ran1_set (void *vstate, unsigned long int s) { ran1_state_t *state = (ran1_state_t *) vstate; int i; if (s == 0) s = 1; /* default seed is 1 */ for (i = 0; i < 8; i++) { long int h = s / q; long int t = a * (s - h * q) - h * r; if (t < 0) t += m; s = t; } for (i = N_SHUFFLE - 1; i >= 0; i--) { long int h = s / q; long int t = a * (s - h * q) - h * r; if (t < 0) t += m; s = t; state->shuffle[i] = s; } state->x = s; state->n = s; return; } static const gsl_rng_type ran1_type = {"ran1", /* name */ 2147483646, /* RAND_MAX */ 1, /* RAND_MIN */ sizeof (ran1_state_t), &ran1_set, &ran1_get, &ran1_get_double}; const gsl_rng_type *gsl_rng_ran1 = &ran1_type; praat-6.0.04/external/gsl/gsl_rng__ran2.c000066400000000000000000000067651261542461700202250ustar00rootroot00000000000000/* rng/ran2.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" /* This is an implementation of the algorithm used in Numerical Recipe's ran2 generator. It is a L'Ecuyer combined recursive generator with a 32-element shuffle-box. As far as I can tell, in general the effects of adding a shuffle box cannot be proven theoretically, so the period of this generator is unknown. The period of the underlying combined generator is O(2^60). */ static inline unsigned long int ran2_get (void *vstate); static double ran2_get_double (void *vstate); static void ran2_set (void *state, unsigned long int s); static const long int m1 = 2147483563, a1 = 40014, q1 = 53668, r1 = 12211; static const long int m2 = 2147483399, a2 = 40692, q2 = 52774, r2 = 3791; #define N_SHUFFLE 32 #define N_DIV (1 + 2147483562/N_SHUFFLE) typedef struct { unsigned long int x; unsigned long int y; unsigned long int n; unsigned long int shuffle[N_SHUFFLE]; } ran2_state_t; static inline unsigned long int ran2_get (void *vstate) { ran2_state_t *state = (ran2_state_t *) vstate; const unsigned long int x = state->x; const unsigned long int y = state->y; long int h1 = x / q1; long int t1 = a1 * (x - h1 * q1) - h1 * r1; long int h2 = y / q2; long int t2 = a2 * (y - h2 * q2) - h2 * r2; if (t1 < 0) t1 += m1; if (t2 < 0) t2 += m2; state->x = t1; state->y = t2; { unsigned long int j = state->n / N_DIV; long int delta = state->shuffle[j] - t2; if (delta < 1) delta += m1 - 1; state->n = delta; state->shuffle[j] = t1; } return state->n; } static double ran2_get_double (void *vstate) { float x_max = 1 - 1.2e-7f ; /* Numerical Recipes version of 1-FLT_EPS */ float x = ran2_get (vstate) / 2147483563.0f ; if (x > x_max) return x_max ; return x ; } static void ran2_set (void *vstate, unsigned long int s) { ran2_state_t *state = (ran2_state_t *) vstate; int i; if (s == 0) s = 1; /* default seed is 1 */ state->y = s; for (i = 0; i < 8; i++) { long int h = s / q1; long int t = a1 * (s - h * q1) - h * r1; if (t < 0) t += m1; s = t; } for (i = N_SHUFFLE - 1; i >= 0; i--) { long int h = s / q1; long int t = a1 * (s - h * q1) - h * r1; if (t < 0) t += m1; s = t; state->shuffle[i] = s; } state->x = s; state->n = s; return; } static const gsl_rng_type ran2_type = {"ran2", /* name */ 2147483562, /* RAND_MAX */ 1, /* RAND_MIN */ sizeof (ran2_state_t), &ran2_set, &ran2_get, &ran2_get_double}; const gsl_rng_type *gsl_rng_ran2 = &ran2_type; praat-6.0.04/external/gsl/gsl_rng__ran3.c000066400000000000000000000057121261542461700202150ustar00rootroot00000000000000/* rng/ran3.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" /* This is an implementation of the algorithm used in Knuths's subtractive generator, with the Numerical Recipe's ran3 paramters. It is a subtractive lagged fibonnaci generator. */ static inline unsigned long int ran3_get (void *vstate); static double ran3_get_double (void *vstate); static void ran3_set (void *state, unsigned long int s); #define M_BIG 1000000000 #define M_SEED 161803398 typedef struct { unsigned int x; unsigned int y; unsigned long int buffer[56]; } ran3_state_t; static inline unsigned long int ran3_get (void *vstate) { ran3_state_t *state = (ran3_state_t *) vstate; long int j; state->x++; if (state->x == 56) state->x = 1; state->y++; if (state->y == 56) state->y = 1; j = state->buffer[state->x] - state->buffer[state->y]; if (j < 0) j += M_BIG; state->buffer[state->x] = j; return j; } static double ran3_get_double (void *vstate) { return ran3_get (vstate) / (double) M_BIG ; } static void ran3_set (void *vstate, unsigned long int s) { ran3_state_t *state = (ran3_state_t *) vstate; int i, i1; long int j, k; if (s == 0) s = 1; /* default seed is 1 */ j = (M_SEED - s) % M_BIG; /* the zeroth element is never used, but we initialize it for consistency between states */ state->buffer[0] = 0; state->buffer[55] = j; k = 1; for (i = 1; i < 55; i++) { int n = (21 * i) % 55; state->buffer[n] = k; k = j - k; if (k < 0) k += M_BIG; j = state->buffer[n]; } for (i1 = 0; i1 < 4; i1++) { for (i = 1; i < 56; i++) { long int t = state->buffer[i] - state->buffer[1 + (i + 30) % 55]; if (t < 0) t += M_BIG; state->buffer[i] = t; } } state->x = 0; state->y = 31; return; } static const gsl_rng_type ran3_type = {"ran3", /* name */ M_BIG, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (ran3_state_t), &ran3_set, &ran3_get, &ran3_get_double}; const gsl_rng_type *gsl_rng_ran3 = &ran3_type; praat-6.0.04/external/gsl/gsl_rng__rand.c000066400000000000000000000043671261542461700203030ustar00rootroot00000000000000/* rng/rand.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" /* This is the old BSD rand() generator. The sequence is x_{n+1} = (a x_n + c) mod m with a = 1103515245, c = 12345 and m = 2^31 = 2147483648. The seed specifies the initial value, x_1. The theoretical value of x_{10001} is 1910041713. The period of this generator is 2^31. The rand() generator is not very good -- the low bits of successive numbers are correlated. */ static inline unsigned long int rand_get (void *vstate); static double rand_get_double (void *vstate); static void rand_set (void *state, unsigned long int s); typedef struct { unsigned long int x; } rand_state_t; static inline unsigned long int rand_get (void *vstate) { rand_state_t *state = (rand_state_t *) vstate; /* The following line relies on unsigned 32-bit arithmetic */ state->x = (1103515245 * state->x + 12345) & 0x7fffffffUL; return state->x; } static double rand_get_double (void *vstate) { return rand_get (vstate) / 2147483648.0 ; } static void rand_set (void *vstate, unsigned long int s) { rand_state_t *state = (rand_state_t *) vstate; state->x = s; return; } static const gsl_rng_type rand_type = {"rand", /* name */ 0x7fffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (rand_state_t), &rand_set, &rand_get, &rand_get_double}; const gsl_rng_type *gsl_rng_rand = &rand_type; praat-6.0.04/external/gsl/gsl_rng__rand48.c000066400000000000000000000074241261542461700204540ustar00rootroot00000000000000/* rng/rand48.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_sys.h" #include "gsl_rng.h" /* This is the Unix rand48() generator. The generator returns the upper 32 bits from each term of the sequence, x_{n+1} = (a x_n + c) mod m using 48-bit unsigned arithmetic, with a = 0x5DEECE66D , c = 0xB and m = 2^48. The seed specifies the upper 32 bits of the initial value, x_1, with the lower 16 bits set to 0x330E. The theoretical value of x_{10001} is 244131582646046. The period of this generator is ? FIXME (probably around 2^48). */ static inline void rand48_advance (void *vstate); static unsigned long int rand48_get (void *vstate); static double rand48_get_double (void *vstate); static void rand48_set (void *state, unsigned long int s); static const unsigned short int a0 = 0xE66D ; static const unsigned short int a1 = 0xDEEC ; static const unsigned short int a2 = 0x0005 ; static const unsigned short int c0 = 0x000B ; typedef struct { unsigned short int x0, x1, x2; } rand48_state_t; static inline void rand48_advance (void *vstate) { rand48_state_t *state = (rand48_state_t *) vstate; /* work with unsigned long ints throughout to get correct integer promotions of any unsigned short ints */ const unsigned long int x0 = (unsigned long int) state->x0 ; const unsigned long int x1 = (unsigned long int) state->x1 ; const unsigned long int x2 = (unsigned long int) state->x2 ; unsigned long int a ; a = a0 * x0 + c0 ; state->x0 = (a & 0xFFFF) ; a >>= 16 ; /* although the next line may overflow we only need the top 16 bits in the following stage, so it does not matter */ a += a0 * x1 + a1 * x0 ; state->x1 = (a & 0xFFFF) ; a >>= 16 ; a += a0 * x2 + a1 * x1 + a2 * x0 ; state->x2 = (a & 0xFFFF) ; } static unsigned long int rand48_get (void *vstate) { unsigned long int x1, x2; rand48_state_t *state = (rand48_state_t *) vstate; rand48_advance (state) ; x2 = (unsigned long int) state->x2; x1 = (unsigned long int) state->x1; return (x2 << 16) + x1; } static double rand48_get_double (void * vstate) { rand48_state_t *state = (rand48_state_t *) vstate; rand48_advance (state) ; return (ldexp((double) state->x2, -16) + ldexp((double) state->x1, -32) + ldexp((double) state->x0, -48)) ; } static void rand48_set (void *vstate, unsigned long int s) { rand48_state_t *state = (rand48_state_t *) vstate; if (s == 0) /* default seed */ { state->x0 = 0x330E ; state->x1 = 0xABCD ; state->x2 = 0x1234 ; } else { state->x0 = 0x330E ; state->x1 = s & 0xFFFF ; state->x2 = (s >> 16) & 0xFFFF ; } return; } static const gsl_rng_type rand48_type = {"rand48", /* name */ 0xffffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (rand48_state_t), &rand48_set, &rand48_get, &rand48_get_double }; const gsl_rng_type *gsl_rng_rand48 = &rand48_type; praat-6.0.04/external/gsl/gsl_rng__random.c000066400000000000000000000400341261542461700206260ustar00rootroot00000000000000/* rng/random.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" /* This file provides support for random() generators. There are three versions in widespread use today, - The original BSD version, e.g. on SunOS 4.1 and FreeBSD. - The Linux libc5 version, which is differs from the BSD version in its seeding procedure, possibly due to the introduction of a typo in the multiplier. - The GNU glibc2 version, which has a new (and better) seeding procedure. They all produce different numbers, due to the different seeding algorithms, but the algorithm for the generator is the same in each case. */ static inline long int random_get (int * i, int * j, int n, long int * x); static inline unsigned long int random8_get (void *vstate); static inline unsigned long int random32_get (void *vstate); static inline unsigned long int random64_get (void *vstate); static inline unsigned long int random128_get (void *vstate); static inline unsigned long int random256_get (void *vstate); static double random8_get_double (void *vstate); static double random32_get_double (void *vstate); static double random64_get_double (void *vstate); static double random128_get_double (void *vstate); static double random256_get_double (void *vstate); static void random8_glibc2_set (void *state, unsigned long int s); static void random32_glibc2_set (void *state, unsigned long int s); static void random64_glibc2_set (void *state, unsigned long int s); static void random128_glibc2_set (void *state, unsigned long int s); static void random256_glibc2_set (void *state, unsigned long int s); static void random8_libc5_set (void *state, unsigned long int s); static void random32_libc5_set (void *state, unsigned long int s); static void random64_libc5_set (void *state, unsigned long int s); static void random128_libc5_set (void *state, unsigned long int s); static void random256_libc5_set (void *state, unsigned long int s); static void random8_bsd_set (void *state, unsigned long int s); static void random32_bsd_set (void *state, unsigned long int s); static void random64_bsd_set (void *state, unsigned long int s); static void random128_bsd_set (void *state, unsigned long int s); static void random256_bsd_set (void *state, unsigned long int s); static void bsd_initialize (long int * x, int n, unsigned long int s); static void libc5_initialize (long int * x, int n, unsigned long int s); static void glibc2_initialize (long int * x, int n, unsigned long int s); typedef struct { long int x; } random8_state_t; typedef struct { int i, j; long int x[7]; } random32_state_t; typedef struct { int i, j; long int x[15]; } random64_state_t; typedef struct { int i, j; long int x[31]; } random128_state_t; typedef struct { int i, j; long int x[63]; } random256_state_t; static inline unsigned long int random8_get (void *vstate) { random8_state_t *state = (random8_state_t *) vstate; state->x = (1103515245 * state->x + 12345) & 0x7fffffffUL; return state->x; } static inline long int random_get (int * i, int * j, int n, long int * x) { long int k ; x[*i] += x[*j] ; k = (x[*i] >> 1) & 0x7FFFFFFF ; (*i)++ ; if (*i == n) *i = 0 ; (*j)++ ; if (*j == n) *j = 0 ; return k ; } static inline unsigned long int random32_get (void *vstate) { random32_state_t *state = (random32_state_t *) vstate; unsigned long int k = random_get (&state->i, &state->j, 7, state->x) ; return k ; } static inline unsigned long int random64_get (void *vstate) { random64_state_t *state = (random64_state_t *) vstate; long int k = random_get (&state->i, &state->j, 15, state->x) ; return k ; } static inline unsigned long int random128_get (void *vstate) { random128_state_t *state = (random128_state_t *) vstate; unsigned long int k = random_get (&state->i, &state->j, 31, state->x) ; return k ; } static inline unsigned long int random256_get (void *vstate) { random256_state_t *state = (random256_state_t *) vstate; long int k = random_get (&state->i, &state->j, 63, state->x) ; return k ; } static double random8_get_double (void *vstate) { return random8_get (vstate) / 2147483648.0 ; } static double random32_get_double (void *vstate) { return random32_get (vstate) / 2147483648.0 ; } static double random64_get_double (void *vstate) { return random64_get (vstate) / 2147483648.0 ; } static double random128_get_double (void *vstate) { return random128_get (vstate) / 2147483648.0 ; } static double random256_get_double (void *vstate) { return random256_get (vstate) / 2147483648.0 ; } static void random8_bsd_set (void *vstate, unsigned long int s) { random8_state_t *state = (random8_state_t *) vstate; if (s == 0) s = 1; state->x = s; } static void random32_bsd_set (void *vstate, unsigned long int s) { random32_state_t *state = (random32_state_t *) vstate; int i; bsd_initialize (state->x, 7, s) ; state->i = 3; state->j = 0; for (i = 0 ; i < 10 * 7 ; i++) random32_get (state) ; } static void random64_bsd_set (void *vstate, unsigned long int s) { random64_state_t *state = (random64_state_t *) vstate; int i; bsd_initialize (state->x, 15, s) ; state->i = 1; state->j = 0; for (i = 0 ; i < 10 * 15 ; i++) random64_get (state) ; } static void random128_bsd_set (void *vstate, unsigned long int s) { random128_state_t *state = (random128_state_t *) vstate; int i; bsd_initialize (state->x, 31, s) ; state->i = 3; state->j = 0; for (i = 0 ; i < 10 * 31 ; i++) random128_get (state) ; } static void random256_bsd_set (void *vstate, unsigned long int s) { random256_state_t *state = (random256_state_t *) vstate; int i; bsd_initialize (state->x, 63, s) ; state->i = 1; state->j = 0; for (i = 0 ; i < 10 * 63 ; i++) random256_get (state) ; } static void bsd_initialize (long int * x, int n, unsigned long int s) { int i; if (s == 0) s = 1 ; x[0] = s; for (i = 1 ; i < n ; i++) x[i] = 1103515245 * x[i-1] + 12345 ; } static void libc5_initialize (long int * x, int n, unsigned long int s) { int i; if (s == 0) s = 1 ; x[0] = s; for (i = 1 ; i < n ; i++) x[i] = 1103515145 * x[i-1] + 12345 ; } static void glibc2_initialize (long int * x, int n, unsigned long int s) { int i; if (s == 0) s = 1 ; x[0] = s; for (i = 1 ; i < n ; i++) { const long int h = s / 127773; const long int t = 16807 * (s - h * 127773) - h * 2836; if (t < 0) { s = t + 2147483647 ; } else { s = t ; } x[i] = s ; } } static void random8_glibc2_set (void *vstate, unsigned long int s) { random8_state_t *state = (random8_state_t *) vstate; if (s == 0) s = 1; state->x = s; } static void random32_glibc2_set (void *vstate, unsigned long int s) { random32_state_t *state = (random32_state_t *) vstate; int i; glibc2_initialize (state->x, 7, s) ; state->i = 3; state->j = 0; for (i = 0 ; i < 10 * 7 ; i++) random32_get (state) ; } static void random64_glibc2_set (void *vstate, unsigned long int s) { random64_state_t *state = (random64_state_t *) vstate; int i; glibc2_initialize (state->x, 15, s) ; state->i = 1; state->j = 0; for (i = 0 ; i < 10 * 15 ; i++) random64_get (state) ; } static void random128_glibc2_set (void *vstate, unsigned long int s) { random128_state_t *state = (random128_state_t *) vstate; int i; glibc2_initialize (state->x, 31, s) ; state->i = 3; state->j = 0; for (i = 0 ; i < 10 * 31 ; i++) random128_get (state) ; } static void random256_glibc2_set (void *vstate, unsigned long int s) { random256_state_t *state = (random256_state_t *) vstate; int i; glibc2_initialize (state->x, 63, s) ; state->i = 1; state->j = 0; for (i = 0 ; i < 10 * 63 ; i++) random256_get (state) ; } static void random8_libc5_set (void *vstate, unsigned long int s) { random8_state_t *state = (random8_state_t *) vstate; if (s == 0) s = 1; state->x = s; } static void random32_libc5_set (void *vstate, unsigned long int s) { random32_state_t *state = (random32_state_t *) vstate; int i; libc5_initialize (state->x, 7, s) ; state->i = 3; state->j = 0; for (i = 0 ; i < 10 * 7 ; i++) random32_get (state) ; } static void random64_libc5_set (void *vstate, unsigned long int s) { random64_state_t *state = (random64_state_t *) vstate; int i; libc5_initialize (state->x, 15, s) ; state->i = 1; state->j = 0; for (i = 0 ; i < 10 * 15 ; i++) random64_get (state) ; } static void random128_libc5_set (void *vstate, unsigned long int s) { random128_state_t *state = (random128_state_t *) vstate; int i; libc5_initialize (state->x, 31, s) ; state->i = 3; state->j = 0; for (i = 0 ; i < 10 * 31 ; i++) random128_get (state) ; } static void random256_libc5_set (void *vstate, unsigned long int s) { random256_state_t *state = (random256_state_t *) vstate; int i; libc5_initialize (state->x, 63, s) ; state->i = 1; state->j = 0; for (i = 0 ; i < 10 * 63 ; i++) random256_get (state) ; } static const gsl_rng_type random_glibc2_type = {"random-glibc2", /* name */ 0x7fffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (random128_state_t), &random128_glibc2_set, &random128_get, &random128_get_double}; static const gsl_rng_type random8_glibc2_type = {"random8-glibc2", /* name */ 0x7fffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (random8_state_t), &random8_glibc2_set, &random8_get, &random8_get_double}; static const gsl_rng_type random32_glibc2_type = {"random32-glibc2", /* name */ 0x7fffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (random32_state_t), &random32_glibc2_set, &random32_get, &random32_get_double}; static const gsl_rng_type random64_glibc2_type = {"random64-glibc2", /* name */ 0x7fffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (random64_state_t), &random64_glibc2_set, &random64_get, &random64_get_double}; static const gsl_rng_type random128_glibc2_type = {"random128-glibc2", /* name */ 0x7fffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (random128_state_t), &random128_glibc2_set, &random128_get, &random128_get_double}; static const gsl_rng_type random256_glibc2_type = {"random256-glibc2", /* name */ 0x7fffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (random256_state_t), &random256_glibc2_set, &random256_get, &random256_get_double}; static const gsl_rng_type random_libc5_type = {"random-libc5", /* name */ 0x7fffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (random128_state_t), &random128_libc5_set, &random128_get, &random128_get_double}; static const gsl_rng_type random8_libc5_type = {"random8-libc5", /* name */ 0x7fffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (random8_state_t), &random8_libc5_set, &random8_get, &random8_get_double}; static const gsl_rng_type random32_libc5_type = {"random32-libc5", /* name */ 0x7fffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (random32_state_t), &random32_libc5_set, &random32_get, &random32_get_double}; static const gsl_rng_type random64_libc5_type = {"random64-libc5", /* name */ 0x7fffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (random64_state_t), &random64_libc5_set, &random64_get, &random64_get_double}; static const gsl_rng_type random128_libc5_type = {"random128-libc5", /* name */ 0x7fffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (random128_state_t), &random128_libc5_set, &random128_get, &random128_get_double}; static const gsl_rng_type random256_libc5_type = {"random256-libc5", /* name */ 0x7fffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (random256_state_t), &random256_libc5_set, &random256_get, &random256_get_double}; static const gsl_rng_type random_bsd_type = {"random-bsd", /* name */ 0x7fffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (random128_state_t), &random128_bsd_set, &random128_get, &random128_get_double}; static const gsl_rng_type random8_bsd_type = {"random8-bsd", /* name */ 0x7fffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (random8_state_t), &random8_bsd_set, &random8_get, &random8_get_double}; static const gsl_rng_type random32_bsd_type = {"random32-bsd", /* name */ 0x7fffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (random32_state_t), &random32_bsd_set, &random32_get, &random32_get_double}; static const gsl_rng_type random64_bsd_type = {"random64-bsd", /* name */ 0x7fffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (random64_state_t), &random64_bsd_set, &random64_get, &random64_get_double}; static const gsl_rng_type random128_bsd_type = {"random128-bsd", /* name */ 0x7fffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (random128_state_t), &random128_bsd_set, &random128_get, &random128_get_double}; static const gsl_rng_type random256_bsd_type = {"random256-bsd", /* name */ 0x7fffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (random256_state_t), &random256_bsd_set, &random256_get, &random256_get_double}; const gsl_rng_type *gsl_rng_random_libc5 = &random_libc5_type; const gsl_rng_type *gsl_rng_random8_libc5 = &random8_libc5_type; const gsl_rng_type *gsl_rng_random32_libc5 = &random32_libc5_type; const gsl_rng_type *gsl_rng_random64_libc5 = &random64_libc5_type; const gsl_rng_type *gsl_rng_random128_libc5 = &random128_libc5_type; const gsl_rng_type *gsl_rng_random256_libc5 = &random256_libc5_type; const gsl_rng_type *gsl_rng_random_glibc2 = &random_glibc2_type; const gsl_rng_type *gsl_rng_random8_glibc2 = &random8_glibc2_type; const gsl_rng_type *gsl_rng_random32_glibc2 = &random32_glibc2_type; const gsl_rng_type *gsl_rng_random64_glibc2 = &random64_glibc2_type; const gsl_rng_type *gsl_rng_random128_glibc2 = &random128_glibc2_type; const gsl_rng_type *gsl_rng_random256_glibc2 = &random256_glibc2_type; const gsl_rng_type *gsl_rng_random_bsd = &random_bsd_type; const gsl_rng_type *gsl_rng_random8_bsd = &random8_bsd_type; const gsl_rng_type *gsl_rng_random32_bsd = &random32_bsd_type; const gsl_rng_type *gsl_rng_random64_bsd = &random64_bsd_type; const gsl_rng_type *gsl_rng_random128_bsd = &random128_bsd_type; const gsl_rng_type *gsl_rng_random256_bsd = &random256_bsd_type; praat-6.0.04/external/gsl/gsl_rng__randu.c000066400000000000000000000050231261542461700204560ustar00rootroot00000000000000/* rng/randu.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" /* This is a reincarnation of the infamously bad RANDU generator. The sequence is, x_{n+1} = (a x_n) mod m with a = 65539 and m = 2^31 = 2147483648. The seed specifies the initial value, x_1. The theoretical value of x_{10001} is 1623524161. The period of this generator is 2^29. Note: Knuth describes this generator as "really horrible". From: Park and Miller, "Random Number Generators: Good ones are hard to find" Communications of the ACM, October 1988, Volume 31, No 10, pages 1192-1201. */ static inline unsigned long int randu_get (void *vstate); static double randu_get_double (void *vstate); static void randu_set (void *state, unsigned long int s); static const long int a = 65539; /* static const unsigned long int m = 2147483648UL; */ typedef struct { unsigned long int x; } randu_state_t; static inline unsigned long int randu_get (void *vstate) { randu_state_t *state = (randu_state_t *) vstate; /* The following line relies on unsigned 32-bit arithmetic */ state->x = (a * state->x) & 0x7fffffffUL; return state->x; } static double randu_get_double (void *vstate) { return randu_get (vstate) / 2147483648.0 ; } static void randu_set (void *vstate, unsigned long int s) { randu_state_t *state = (randu_state_t *) vstate; if (s == 0) s = 1; /* default seed is 1 */ state->x = s; return; } static const gsl_rng_type randu_type = {"randu", /* name */ 0x7fffffffUL, /* RAND_MAX */ 1, /* RAND_MIN */ sizeof (randu_state_t), &randu_set, &randu_get, &randu_get_double}; const gsl_rng_type *gsl_rng_randu = &randu_type; praat-6.0.04/external/gsl/gsl_rng__ranf.c000066400000000000000000000102011261542461700202650ustar00rootroot00000000000000/* rng/ranf.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_rng.h" /* This is the CRAY RANF generator. The generator returns the upper 32 bits from each term of the sequence, x_{n+1} = (a x_n) mod m using 48-bit unsigned arithmetic, with a = 0x2875A2E7B175 and m = 2^48. The seed specifies the lower 32 bits of the initial value, x_1, with the lowest bit set (to prevent the seed taking an even value), and the upper 16 bits set to 0. There is a subtlety in the implementation of the seed. The initial state is put one step back by multiplying by the modular inverse of a mod m. This is done for compatibility with the original CRAY implementation. Note, you can only seed the generator with integers up to 2^32, while the CRAY uses wide integers which can cover all 2^48 states of the generator. The theoretical value of x_{10001} is 141091827447341. The period of this generator is 2^{46}. */ static inline void ranf_advance (void *vstate); static unsigned long int ranf_get (void *vstate); static double ranf_get_double (void *vstate); static void ranf_set (void *state, unsigned long int s); static const unsigned short int a0 = 0xB175 ; static const unsigned short int a1 = 0xA2E7 ; static const unsigned short int a2 = 0x2875 ; typedef struct { unsigned short int x0, x1, x2; } ranf_state_t; static inline void ranf_advance (void *vstate) { ranf_state_t *state = (ranf_state_t *) vstate; const unsigned long int x0 = (unsigned long int) state->x0 ; const unsigned long int x1 = (unsigned long int) state->x1 ; const unsigned long int x2 = (unsigned long int) state->x2 ; unsigned long int r ; r = a0 * x0 ; state->x0 = (r & 0xFFFF) ; r >>= 16 ; r += a0 * x1 + a1 * x0 ; state->x1 = (r & 0xFFFF) ; r >>= 16 ; r += a0 * x2 + a1 * x1 + a2 * x0 ; state->x2 = (r & 0xFFFF) ; } static unsigned long int ranf_get (void *vstate) { unsigned long int x1, x2; ranf_state_t *state = (ranf_state_t *) vstate; ranf_advance (state) ; x1 = (unsigned long int) state->x1; x2 = (unsigned long int) state->x2; return (x2 << 16) + x1; } static double ranf_get_double (void * vstate) { ranf_state_t *state = (ranf_state_t *) vstate; ranf_advance (state) ; return (ldexp((double) state->x2, -16) + ldexp((double) state->x1, -32) + ldexp((double) state->x0, -48)) ; } static void ranf_set (void *vstate, unsigned long int s) { ranf_state_t *state = (ranf_state_t *) vstate; unsigned short int x0, x1, x2 ; unsigned long int r ; unsigned long int b0 = 0xD6DD ; unsigned long int b1 = 0xB894 ; unsigned long int b2 = 0x5CEE ; if (s == 0) /* default seed */ { x0 = 0x9CD1 ; x1 = 0x53FC ; x2 = 0x9482 ; } else { x0 = (s | 1) & 0xFFFF ; x1 = s >> 16 & 0xFFFF ; x2 = 0 ; } r = b0 * x0 ; state->x0 = (r & 0xFFFF) ; r >>= 16 ; r += b0 * x1 + b1 * x0 ; state->x1 = (r & 0xFFFF) ; r >>= 16 ; r += b0 * x2 + b1 * x1 + b2 * x0 ; state->x2 = (r & 0xFFFF) ; return; } static const gsl_rng_type ranf_type = {"ranf", /* name */ 0xffffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (ranf_state_t), &ranf_set, &ranf_get, &ranf_get_double }; const gsl_rng_type *gsl_rng_ranf = &ranf_type; praat-6.0.04/external/gsl/gsl_rng__ranlux.c000066400000000000000000000124251261542461700206620ustar00rootroot00000000000000/* rng/ranlux.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" /* This is a lagged fibonacci generator with skipping developed by Luescher. The sequence is a series of 24-bit integers, x_n, x_n = d_n + b_n where d_n = x_{n-10} - x_{n-24} - c_{n-1}, b_n = 0 if d_n >= 0 and b_n = 2^24 if d_n < 0, c_n = 0 if d_n >= 0 and c_n = 1 if d_n < 0, where after 24 samples a group of p integers are "skipped", to reduce correlations. By default p = 199, but can be increased to 365. The period of the generator is around 10^171. From: M. Luescher, "A portable high-quality random number generator for lattice field theory calculations", Computer Physics Communications, 79 (1994) 100-110. Available on the net as hep-lat/9309020 at http://xxx.lanl.gov/ See also, F. James, "RANLUX: A Fortran implementation of the high-quality pseudo-random number generator of Luscher", Computer Physics Communications, 79 (1994) 111-114 Kenneth G. Hamilton, F. James, "Acceleration of RANLUX", Computer Physics Communications, 101 (1997) 241-248 Kenneth G. Hamilton, "Assembler RANLUX for PCs", Computer Physics Communications, 101 (1997) 249-253 */ static inline unsigned long int ranlux_get (void *vstate); static double ranlux_get_double (void *vstate); static void ranlux_set_lux (void *state, unsigned long int s, unsigned int luxury); static void ranlux_set (void *state, unsigned long int s); static void ranlux389_set (void *state, unsigned long int s); static const unsigned long int mask_lo = 0x00ffffffUL; /* 2^24 - 1 */ static const unsigned long int mask_hi = ~0x00ffffffUL; static const unsigned long int two24 = 16777216; /* 2^24 */ typedef struct { unsigned int i; unsigned int j; unsigned int n; unsigned int skip; unsigned int carry; unsigned long int u[24]; } ranlux_state_t; static inline unsigned long int increment_state (ranlux_state_t * state); static inline unsigned long int increment_state (ranlux_state_t * state) { unsigned int i = state->i; unsigned int j = state->j; long int delta = state->u[j] - state->u[i] - state->carry; if (delta & mask_hi) { state->carry = 1; delta &= mask_lo; } else { state->carry = 0; } state->u[i] = delta; if (i == 0) { i = 23; } else { i--; } state->i = i; if (j == 0) { j = 23; } else { j--; } state->j = j; return delta; } static inline unsigned long int ranlux_get (void *vstate) { ranlux_state_t *state = (ranlux_state_t *) vstate; const unsigned int skip = state->skip; unsigned long int r = increment_state (state); state->n++; if (state->n == 24) { unsigned int i; state->n = 0; for (i = 0; i < skip; i++) increment_state (state); } return r; } static double ranlux_get_double (void *vstate) { return ranlux_get (vstate) / 16777216.0; } static void ranlux_set_lux (void *vstate, unsigned long int s, unsigned int luxury) { ranlux_state_t *state = (ranlux_state_t *) vstate; int i; long int seed; if (s == 0) s = 314159265; /* default seed is 314159265 */ seed = s; /* This is the initialization algorithm of F. James, widely in use for RANLUX. */ for (i = 0; i < 24; i++) { unsigned long int k = seed / 53668; seed = 40014 * (seed - k * 53668) - k * 12211; if (seed < 0) { seed += 2147483563; } state->u[i] = seed % two24; } state->i = 23; state->j = 9; state->n = 0; state->skip = luxury - 24; if (state->u[23] & mask_hi) { state->carry = 1; } else { state->carry = 0; } } static void ranlux_set (void *vstate, unsigned long int s) { ranlux_set_lux (vstate, s, 223); } static void ranlux389_set (void *vstate, unsigned long int s) { ranlux_set_lux (vstate, s, 389); } static const gsl_rng_type ranlux_type = {"ranlux", /* name */ 0x00ffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (ranlux_state_t), &ranlux_set, &ranlux_get, &ranlux_get_double}; static const gsl_rng_type ranlux389_type = {"ranlux389", /* name */ 0x00ffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (ranlux_state_t), &ranlux389_set, &ranlux_get, &ranlux_get_double}; const gsl_rng_type *gsl_rng_ranlux = &ranlux_type; const gsl_rng_type *gsl_rng_ranlux389 = &ranlux389_type; praat-6.0.04/external/gsl/gsl_rng__ranlxd.c000066400000000000000000000132151261542461700206370ustar00rootroot00000000000000/* rng/ranlxd.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" /* This is an implementation of Martin Luescher's second generation double-precision (48-bit) version of the RANLUX generator. Thanks to Martin Luescher for providing information on this generator. */ static inline unsigned long int ranlxd_get (void *vstate); static double ranlxd_get_double (void *vstate); static void ranlxd_set_lux (void *state, unsigned long int s, unsigned int luxury); static void ranlxd1_set (void *state, unsigned long int s); static void ranlxd2_set (void *state, unsigned long int s); static const int next[12] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0}; static const double one_bit = 1.0 / 281474976710656.0; /* 1/2^48 */ #define RANLUX_STEP(x1,x2,i1,i2,i3) \ x1=xdbl[i1] - xdbl[i2]; \ if (x2 < 0) \ { \ x1-=one_bit; \ x2+=1; \ } \ xdbl[i3]=x2 typedef struct { double xdbl[12]; double carry; unsigned int ir; unsigned int jr; unsigned int ir_old; unsigned int pr; } ranlxd_state_t; static inline void increment_state (ranlxd_state_t * state); static inline void increment_state (ranlxd_state_t * state) { int k, kmax; double y1, y2, y3; double *xdbl = state->xdbl; double carry = state->carry; unsigned int ir = state->ir; unsigned int jr = state->jr; for (k = 0; ir > 0; ++k) { y1 = xdbl[jr] - xdbl[ir]; y2 = y1 - carry; if (y2 < 0) { carry = one_bit; y2 += 1; } else { carry = 0; } xdbl[ir] = y2; ir = next[ir]; jr = next[jr]; } kmax = state->pr - 12; for (; k <= kmax; k += 12) { y1 = xdbl[7] - xdbl[0]; y1 -= carry; RANLUX_STEP (y2, y1, 8, 1, 0); RANLUX_STEP (y3, y2, 9, 2, 1); RANLUX_STEP (y1, y3, 10, 3, 2); RANLUX_STEP (y2, y1, 11, 4, 3); RANLUX_STEP (y3, y2, 0, 5, 4); RANLUX_STEP (y1, y3, 1, 6, 5); RANLUX_STEP (y2, y1, 2, 7, 6); RANLUX_STEP (y3, y2, 3, 8, 7); RANLUX_STEP (y1, y3, 4, 9, 8); RANLUX_STEP (y2, y1, 5, 10, 9); RANLUX_STEP (y3, y2, 6, 11, 10); if (y3 < 0) { carry = one_bit; y3 += 1; } else { carry = 0; } xdbl[11] = y3; } kmax = state->pr; for (; k < kmax; ++k) { y1 = xdbl[jr] - xdbl[ir]; y2 = y1 - carry; if (y2 < 0) { carry = one_bit; y2 += 1; } else { carry = 0; } xdbl[ir] = y2; ir = next[ir]; jr = next[jr]; } state->ir = ir; state->ir_old = ir; state->jr = jr; state->carry = carry; } static inline unsigned long int ranlxd_get (void *vstate) { return ranlxd_get_double (vstate) * 4294967296.0; /* 2^32 */ } static double ranlxd_get_double (void *vstate) { ranlxd_state_t *state = (ranlxd_state_t *) vstate; int ir = state->ir; state->ir = next[ir]; if (state->ir == state->ir_old) increment_state (state); return state->xdbl[state->ir]; } static void ranlxd_set_lux (void *vstate, unsigned long int s, unsigned int luxury) { ranlxd_state_t *state = (ranlxd_state_t *) vstate; int ibit, jbit, i, k, l, xbit[31]; double x, y; long int seed; if (s == 0) s = 1; /* default seed is 1 */ seed = s; i = seed & 0xFFFFFFFFUL; for (k = 0; k < 31; ++k) { xbit[k] = i % 2; i /= 2; } ibit = 0; jbit = 18; for (k = 0; k < 12; ++k) { x = 0; for (l = 1; l <= 48; ++l) { y = (double) ((xbit[ibit] + 1) % 2); x += x + y; xbit[ibit] = (xbit[ibit] + xbit[jbit]) % 2; ibit = (ibit + 1) % 31; jbit = (jbit + 1) % 31; } state->xdbl[k] = one_bit * x; } state->carry = 0; state->ir = 11; state->jr = 7; state->ir_old = 0; state->pr = luxury; } static void ranlxd1_set (void *vstate, unsigned long int s) { ranlxd_set_lux (vstate, s, 202); } static void ranlxd2_set (void *vstate, unsigned long int s) { ranlxd_set_lux (vstate, s, 397); } static const gsl_rng_type ranlxd1_type = {"ranlxd1", /* name */ 0xffffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (ranlxd_state_t), &ranlxd1_set, &ranlxd_get, &ranlxd_get_double}; static const gsl_rng_type ranlxd2_type = {"ranlxd2", /* name */ 0xffffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (ranlxd_state_t), &ranlxd2_set, &ranlxd_get, &ranlxd_get_double}; const gsl_rng_type *gsl_rng_ranlxd1 = &ranlxd1_type; const gsl_rng_type *gsl_rng_ranlxd2 = &ranlxd2_type; praat-6.0.04/external/gsl/gsl_rng__ranlxs.c000066400000000000000000000157121261542461700206620ustar00rootroot00000000000000/* rng/ranlxs.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" /* This is an implementation of M. Luescher's second generation version of the RANLUX generator. Thanks to Martin Luescher for providing information on this generator. */ static unsigned long int ranlxs_get (void *vstate); static inline double ranlxs_get_double (void *vstate); static void ranlxs_set_lux (void *state, unsigned long int s, unsigned int luxury); static void ranlxs0_set (void *state, unsigned long int s); static void ranlxs1_set (void *state, unsigned long int s); static void ranlxs2_set (void *state, unsigned long int s); static const int next[12] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0}; static const int snext[24] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0}; static const double sbase = 16777216.0; /* 2^24 */ static const double sone_bit = 1.0 / 16777216.0; /* 1/2^24 */ static const double one_bit = 1.0 / 281474976710656.0; /* 1/2^48 */ static const double shift = 268435456.0; /* 2^28 */ #define RANLUX_STEP(x1,x2,i1,i2,i3) \ x1=xdbl[i1] - xdbl[i2]; \ if (x2 < 0) \ { \ x1-=one_bit; \ x2+=1; \ } \ xdbl[i3]=x2 typedef struct { double xdbl[12], ydbl[12]; /* doubles first so they are 8-byte aligned */ double carry; float xflt[24]; unsigned int ir; unsigned int jr; unsigned int is; unsigned int is_old; unsigned int pr; } ranlxs_state_t; static void increment_state (ranlxs_state_t * state); static void increment_state (ranlxs_state_t * state) { int k, kmax, m; double x, y1, y2, y3; float *xflt = state->xflt; double *xdbl = state->xdbl; double *ydbl = state->ydbl; double carry = state->carry; unsigned int ir = state->ir; unsigned int jr = state->jr; for (k = 0; ir > 0; ++k) { y1 = xdbl[jr] - xdbl[ir]; y2 = y1 - carry; if (y2 < 0) { carry = one_bit; y2 += 1; } else { carry = 0; } xdbl[ir] = y2; ir = next[ir]; jr = next[jr]; } kmax = state->pr - 12; for (; k <= kmax; k += 12) { y1 = xdbl[7] - xdbl[0]; y1 -= carry; RANLUX_STEP (y2, y1, 8, 1, 0); RANLUX_STEP (y3, y2, 9, 2, 1); RANLUX_STEP (y1, y3, 10, 3, 2); RANLUX_STEP (y2, y1, 11, 4, 3); RANLUX_STEP (y3, y2, 0, 5, 4); RANLUX_STEP (y1, y3, 1, 6, 5); RANLUX_STEP (y2, y1, 2, 7, 6); RANLUX_STEP (y3, y2, 3, 8, 7); RANLUX_STEP (y1, y3, 4, 9, 8); RANLUX_STEP (y2, y1, 5, 10, 9); RANLUX_STEP (y3, y2, 6, 11, 10); if (y3 < 0) { carry = one_bit; y3 += 1; } else { carry = 0; } xdbl[11] = y3; } kmax = state->pr; for (; k < kmax; ++k) { y1 = xdbl[jr] - xdbl[ir]; y2 = y1 - carry; if (y2 < 0) { carry = one_bit; y2 += 1; } else { carry = 0; } xdbl[ir] = y2; ydbl[ir] = y2 + shift; ir = next[ir]; jr = next[jr]; } ydbl[ir] = xdbl[ir] + shift; for (k = next[ir]; k > 0;) { ydbl[k] = xdbl[k] + shift; k = next[k]; } for (k = 0, m = 0; k < 12; ++k) { x = xdbl[k]; y2 = ydbl[k] - shift; if (y2 > x) y2 -= sone_bit; y1 = (x - y2) * sbase; xflt[m++] = (float) y1; xflt[m++] = (float) y2; } state->ir = ir; state->is = 2 * ir; state->is_old = 2 * ir; state->jr = jr; state->carry = carry; } static inline double ranlxs_get_double (void *vstate) { ranlxs_state_t *state = (ranlxs_state_t *) vstate; const unsigned int is = snext[state->is]; state->is = is; if (is == state->is_old) increment_state (state); return state->xflt[state->is]; } static unsigned long int ranlxs_get (void *vstate) { return ranlxs_get_double (vstate) * 16777216.0; /* 2^24 */ } static void ranlxs_set_lux (void *vstate, unsigned long int s, unsigned int luxury) { ranlxs_state_t *state = (ranlxs_state_t *) vstate; int ibit, jbit, i, k, m, xbit[31]; double x, y; long int seed; if (s == 0) s = 1; /* default seed is 1 */ seed = s; i = seed & 0xFFFFFFFFUL; for (k = 0; k < 31; ++k) { xbit[k] = i % 2; i /= 2; } ibit = 0; jbit = 18; for (k = 0; k < 12; ++k) { x = 0; for (m = 1; m <= 48; ++m) { y = (double) xbit[ibit]; x += x + y; xbit[ibit] = (xbit[ibit] + xbit[jbit]) % 2; ibit = (ibit + 1) % 31; jbit = (jbit + 1) % 31; } state->xdbl[k] = one_bit * x; } state->carry = 0; state->ir = 0; state->jr = 7; state->is = 23; state->is_old = 0; state->pr = luxury; } static void ranlxs0_set (void *vstate, unsigned long int s) { ranlxs_set_lux (vstate, s, 109); } void ranlxs1_set (void *vstate, unsigned long int s) { ranlxs_set_lux (vstate, s, 202); } static void ranlxs2_set (void *vstate, unsigned long int s) { ranlxs_set_lux (vstate, s, 397); } static const gsl_rng_type ranlxs0_type = {"ranlxs0", /* name */ 0x00ffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (ranlxs_state_t), &ranlxs0_set, &ranlxs_get, &ranlxs_get_double}; static const gsl_rng_type ranlxs1_type = {"ranlxs1", /* name */ 0x00ffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (ranlxs_state_t), &ranlxs1_set, &ranlxs_get, &ranlxs_get_double}; static const gsl_rng_type ranlxs2_type = {"ranlxs2", /* name */ 0x00ffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (ranlxs_state_t), &ranlxs2_set, &ranlxs_get, &ranlxs_get_double}; const gsl_rng_type *gsl_rng_ranlxs0 = &ranlxs0_type; const gsl_rng_type *gsl_rng_ranlxs1 = &ranlxs1_type; const gsl_rng_type *gsl_rng_ranlxs2 = &ranlxs2_type; praat-6.0.04/external/gsl/gsl_rng__ranmar.c000066400000000000000000000075711261542461700206370ustar00rootroot00000000000000/* rng/ranmar.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" /* This is the RANMAR lagged fibonacci generator of Marsaglia, Zaman and Tsang. The sequence is a series of 24-bit integers, x_n, x_n = (y_n - c_n + 2^24) mod 2^24 where, y_n = (y_{n-97) - y_{n-33} + 2^24) mod 2^24 c_n = (c_{n-1} - 7654321 + 2^24 - 3) mod (2^24 - 3) The period of this generator is 2^144. The generator provides about 900 million different subsequences each of length O(10^30). Thus each seed up to 900,000,000 gives an independent sequence. Although it was good in its day this generator now has known statistical defects and has been superseded by RANLUX. From: F. James, "A Review of Pseudorandom number generators", Computer Physics Communications 60, 329 (1990). G. Marsaglia, A. Zaman and W.W. Tsang, Stat. Prob. Lett. 9, 35 (1990) */ static inline unsigned long int ranmar_get (void *vstate); static double ranmar_get_double (void *vstate); static void ranmar_set (void *state, unsigned long int s); static const unsigned long int two24 = 16777216; /* 2^24 */ typedef struct { unsigned int i; unsigned int j; long int carry; unsigned long int u[97]; } ranmar_state_t; static inline unsigned long int ranmar_get (void *vstate) { ranmar_state_t *state = (ranmar_state_t *) vstate; unsigned int i = state->i; unsigned int j = state->j; long int carry = state->carry; long int delta = state->u[i] - state->u[j]; if (delta < 0) delta += two24 ; state->u[i] = delta; if (i == 0) { i = 96; } else { i--; } state->i = i; if (j == 0) { j = 96; } else { j--; } state->j = j; carry += - 7654321 ; if (carry < 0) carry += two24 - 3; state->carry = carry ; delta += - carry ; if (delta < 0) delta += two24 ; return delta; } static double ranmar_get_double (void *vstate) { return ranmar_get (vstate) / 16777216.0 ; } static void ranmar_set (void *vstate, unsigned long int s) { ranmar_state_t *state = (ranmar_state_t *) vstate; unsigned long int ij = s / 30082 ; unsigned long int kl = s % 30082 ; int i = (ij / 177) % 177 + 2 ; int j = (ij % 177) + 2 ; int k = (kl / 169) % 178 + 1 ; int l = (kl % 169) ; int a, b; for (a = 0; a < 97; a++) { unsigned long int sum = 0 ; unsigned long int t = two24 ; for (b = 0; b < 24; b++) { unsigned long int m = (((i * j) % 179) * k) % 179 ; i = j ; j = k ; k = m ; l = (53 * l + 1) % 169 ; t >>= 1 ; if ((l * m) % 64 >= 32) sum += t ; } state->u[a] = sum ; } state->i = 96; state->j = 32; state->carry = 362436 ; } static const gsl_rng_type ranmar_type = {"ranmar", /* name */ 0x00ffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (ranmar_state_t), &ranmar_set, &ranmar_get, &ranmar_get_double}; const gsl_rng_type *gsl_rng_ranmar = &ranmar_type; praat-6.0.04/external/gsl/gsl_rng__rng.c000066400000000000000000000104351261542461700201360ustar00rootroot00000000000000/* rng/rng.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include #include "gsl_errno.h" #include "gsl_rng.h" gsl_rng * gsl_rng_alloc (const gsl_rng_type * T) { gsl_rng *r = (gsl_rng *) malloc (sizeof (gsl_rng)); if (r == 0) { GSL_ERROR_VAL ("failed to allocate space for rng struct", GSL_ENOMEM, 0); }; r->state = malloc (T->size); if (r->state == 0) { free (r); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for rng state", GSL_ENOMEM, 0); }; r->type = T; gsl_rng_set (r, gsl_rng_default_seed); /* seed the generator */ return r; } int gsl_rng_memcpy (gsl_rng * dest, const gsl_rng * src) { if (dest->type != src->type) { GSL_ERROR ("generators must be of the same type", GSL_EINVAL); } memcpy (dest->state, src->state, src->type->size); return GSL_SUCCESS; } gsl_rng * gsl_rng_clone (const gsl_rng * q) { gsl_rng *r = (gsl_rng *) malloc (sizeof (gsl_rng)); if (r == 0) { GSL_ERROR_VAL ("failed to allocate space for rng struct", GSL_ENOMEM, 0); }; r->state = malloc (q->type->size); if (r->state == 0) { free (r); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for rng state", GSL_ENOMEM, 0); }; r->type = q->type; memcpy (r->state, q->state, q->type->size); return r; } void gsl_rng_set (const gsl_rng * r, unsigned long int seed) { (r->type->set) (r->state, seed); } #ifndef HIDE_INLINE_STATIC unsigned long int gsl_rng_get (const gsl_rng * r) { return (r->type->get) (r->state); } double gsl_rng_uniform (const gsl_rng * r) { return (r->type->get_double) (r->state); } double gsl_rng_uniform_pos (const gsl_rng * r) { double x ; do { x = (r->type->get_double) (r->state) ; } while (x == 0) ; return x ; } /* Note: to avoid integer overflow in (range+1) we work with scale = range/n = (max-min)/n rather than scale=(max-min+1)/n, this reduces efficiency slightly but avoids having to check for the out of range value. Note that range is typically O(2^32) so the addition of 1 is negligible in most usage. */ unsigned long int gsl_rng_uniform_int (const gsl_rng * r, unsigned long int n) { unsigned long int offset = r->type->min; unsigned long int range = r->type->max - offset; unsigned long int scale; unsigned long int k; if (n > range || n == 0) { GSL_ERROR_VAL ("invalid n, either 0 or exceeds maximum value of generator", GSL_EINVAL, 0) ; } scale = range / n; do { k = (((r->type->get) (r->state)) - offset) / scale; } while (k >= n); return k; } #endif unsigned long int gsl_rng_max (const gsl_rng * r) { return r->type->max; } unsigned long int gsl_rng_min (const gsl_rng * r) { return r->type->min; } const char * gsl_rng_name (const gsl_rng * r) { return r->type->name; } size_t gsl_rng_size (const gsl_rng * r) { return r->type->size; } void * gsl_rng_state (const gsl_rng * r) { return r->state; } void gsl_rng_print_state (const gsl_rng * r) { size_t i; unsigned char *p = (unsigned char *) (r->state); const size_t n = r->type->size; for (i = 0; i < n; i++) { /* FIXME: we're assuming that a char is 8 bits */ printf ("%.2x", *(p + i)); } } void gsl_rng_free (gsl_rng * r) { free (r->state); free (r); } praat-6.0.04/external/gsl/gsl_rng__schrage.c000066400000000000000000000035221261542461700207630ustar00rootroot00000000000000/* rng/schrage.c * Copyright (C) 2003 Carlo Perassi and Heiko Bauke. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static inline unsigned long int schrage (unsigned long int a, unsigned long int b, unsigned long int m) { /* This is a modified version of Schrage's method. It ensures that no * overflow or underflow occurs even if a=ceil(sqrt(m)). Usual * Schrage's method works only until a=floor(sqrt(m)). */ unsigned long int q, t; if (a == 0UL) return 0UL; q = m / a; t = 2 * m - (m % a) * (b / q); if (t >= m) t -= m; t += a * (b % q); return (t >= m) ? (t - m) : t; } static inline unsigned long int schrage_mult (unsigned long int a, unsigned long int b, unsigned long int m, unsigned long int sqrtm) { /* To multiply a and b use Schrage's method 3 times. * represent a in base ceil(sqrt(m)) a = a1*ceil(sqrt(m)) + a0 * a*b = (a1*ceil(sqrt(m)) + a0)*b = a1*ceil(sqrt(m))*b + a0*b */ unsigned long int t0 = schrage (sqrtm, b, m); unsigned long int t1 = schrage (a / sqrtm, t0, m); unsigned long int t2 = schrage (a % sqrtm, b, m); unsigned long int t = t1 + t2; return (t >= m) ? (t - m) : t; } praat-6.0.04/external/gsl/gsl_rng__slatec.c000066400000000000000000000166201261542461700206250ustar00rootroot00000000000000/* rng/slatec.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** * ====================================================================== * NIST Guide to Available Math Software. * Source for module RAND from package CMLIB. * Retrieved from TIBER on Fri Oct 11 11:43:42 1996. * ====================================================================== FUNCTION RAND(R) C***BEGIN PROLOGUE RAND C***DATE WRITTEN 770401 (YYMMDD) C***REVISION DATE 820801 (YYMMDD) C***CATEGORY NO. L6A21 C***KEYWORDS RANDOM NUMBER,SPECIAL FUNCTION,UNIFORM C***AUTHOR FULLERTON, W., (LANL) C***PURPOSE Generates a uniformly distributed random number. C***DESCRIPTION C C This pseudo-random number generator is portable among a wide C variety of computers. RAND(R) undoubtedly is not as good as many C readily available installation dependent versions, and so this C routine is not recommended for widespread usage. Its redeeming C feature is that the exact same random numbers (to within final round- C off error) can be generated from machine to machine. Thus, programs C that make use of random numbers can be easily transported to and C checked in a new environment. C The random numbers are generated by the linear congruential C method described, e.g., by Knuth in Seminumerical Methods (p.9), C Addison-Wesley, 1969. Given the I-th number of a pseudo-random C sequence, the I+1 -st number is generated from C X(I+1) = (A*X(I) + C) MOD M, C where here M = 2**22 = 4194304, C = 1731 and several suitable values C of the multiplier A are discussed below. Both the multiplier A and C random number X are represented in double precision as two 11-bit C words. The constants are chosen so that the period is the maximum C possible, 4194304. C In order that the same numbers be generated from machine to C machine, it is necessary that 23-bit integers be reducible modulo C 2**11 exactly, that 23-bit integers be added exactly, and that 11-bit C integers be multiplied exactly. Furthermore, if the restart option C is used (where R is between 0 and 1), then the product R*2**22 = C R*4194304 must be correct to the nearest integer. C The first four random numbers should be .0004127026, C .6750836372, .1614754200, and .9086198807. The tenth random number C is .5527787209, and the hundredth is .3600893021 . The thousandth C number should be .2176990509 . C In order to generate several effectively independent sequences C with the same generator, it is necessary to know the random number C for several widely spaced calls. The I-th random number times 2**22, C where I=K*P/8 and P is the period of the sequence (P = 2**22), is C still of the form L*P/8. In particular we find the I-th random C number multiplied by 2**22 is given by C I = 0 1*P/8 2*P/8 3*P/8 4*P/8 5*P/8 6*P/8 7*P/8 8*P/8 C RAND= 0 5*P/8 2*P/8 7*P/8 4*P/8 1*P/8 6*P/8 3*P/8 0 C Thus the 4*P/8 = 2097152 random number is 2097152/2**22. C Several multipliers have been subjected to the spectral test C (see Knuth, p. 82). Four suitable multipliers roughly in order of C goodness according to the spectral test are C 3146757 = 1536*2048 + 1029 = 2**21 + 2**20 + 2**10 + 5 C 2098181 = 1024*2048 + 1029 = 2**21 + 2**10 + 5 C 3146245 = 1536*2048 + 517 = 2**21 + 2**20 + 2**9 + 5 C 2776669 = 1355*2048 + 1629 = 5**9 + 7**7 + 1 C C In the table below LOG10(NU(I)) gives roughly the number of C random decimal digits in the random numbers considered I at a time. C C is the primary measure of goodness. In both cases bigger is better. C C LOG10 NU(I) C(I) C A I=2 I=3 I=4 I=5 I=2 I=3 I=4 I=5 C C 3146757 3.3 2.0 1.6 1.3 3.1 1.3 4.6 2.6 C 2098181 3.3 2.0 1.6 1.2 3.2 1.3 4.6 1.7 C 3146245 3.3 2.2 1.5 1.1 3.2 4.2 1.1 0.4 C 2776669 3.3 2.1 1.6 1.3 2.5 2.0 1.9 2.6 C Best C Possible 3.3 2.3 1.7 1.4 3.6 5.9 9.7 14.9 C C Input Argument -- C R If R=0., the next random number of the sequence is generated. C If R .LT. 0., the last generated number will be returned for C possible use in a restart procedure. C If R .GT. 0., the sequence of random numbers will start with C the seed R mod 1. This seed is also returned as the value of C RAND provided the arithmetic is done exactly. C C Output Value -- C RAND a pseudo-random number between 0. and 1. C***REFERENCES (NONE) C***ROUTINES CALLED (NONE) C***END PROLOGUE RAND DATA IA1, IA0, IA1MA0 /1536, 1029, 507/ DATA IC /1731/ DATA IX1, IX0 /0, 0/ C***FIRST EXECUTABLE STATEMENT RAND IF (R.LT.0.) GO TO 10 IF (R.GT.0.) GO TO 20 C C A*X = 2**22*IA1*IX1 + 2**11*(IA1*IX1 + (IA1-IA0)*(IX0-IX1) C + IA0*IX0) + IA0*IX0 C IY0 = IA0*IX0 IY1 = IA1*IX1 + IA1MA0*(IX0-IX1) + IY0 IY0 = IY0 + IC IX0 = MOD (IY0, 2048) IY1 = IY1 + (IY0-IX0)/2048 IX1 = MOD (IY1, 2048) C 10 RAND = IX1*2048 + IX0 RAND = RAND / 4194304. RETURN C 20 IX1 = AMOD(R,1.)*4194304. + 0.5 IX0 = MOD (IX1, 2048) IX1 = (IX1-IX0)/2048 GO TO 10 C END **/ #include "gsl__config.h" #include #include "gsl_rng.h" static inline unsigned long int slatec_get (void *vstate); static double slatec_get_double (void *vstate); static void slatec_set (void *state, unsigned long int s); typedef struct { long int x0, x1; } slatec_state_t; static const long P = 4194304; static const long a1 = 1536; static const long a0 = 1029; static const long a1ma0 = 507; static const long c = 1731; static inline unsigned long int slatec_get (void *vstate) { long y0, y1; slatec_state_t *state = (slatec_state_t *) vstate; y0 = a0 * state->x0; y1 = a1 * state->x1 + a1ma0 * (state->x0 - state->x1) + y0; y0 = y0 + c; state->x0 = y0 % 2048; y1 = y1 + (y0 - state->x0) / 2048; state->x1 = y1 % 2048; return state->x1 * 2048 + state->x0; } static double slatec_get_double (void *vstate) { return slatec_get (vstate) / 4194304.0 ; } static void slatec_set (void *vstate, unsigned long int s) { slatec_state_t *state = (slatec_state_t *) vstate; /* Only eight seeds are permitted. This is pretty limiting, but at least we are guaranteed that the eight sequences are different */ s = s % 8; s *= P / 8; state->x0 = s % 2048; state->x1 = (s - state->x0) / 2048; } static const gsl_rng_type slatec_type = {"slatec", /* name */ 4194303, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (slatec_state_t), &slatec_set, &slatec_get, &slatec_get_double}; const gsl_rng_type *gsl_rng_slatec = &slatec_type; praat-6.0.04/external/gsl/gsl_rng__taus.c000066400000000000000000000126651261542461700203330ustar00rootroot00000000000000/* rng/taus.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" /* This is a maximally equidistributed combined Tausworthe generator. The sequence is, x_n = (s1_n ^ s2_n ^ s3_n) s1_{n+1} = (((s1_n & 4294967294) <<12) ^ (((s1_n <<13) ^ s1_n) >>19)) s2_{n+1} = (((s2_n & 4294967288) << 4) ^ (((s2_n << 2) ^ s2_n) >>25)) s3_{n+1} = (((s3_n & 4294967280) <<17) ^ (((s3_n << 3) ^ s3_n) >>11)) computed modulo 2^32. In the three formulas above '^' means exclusive-or (C-notation), not exponentiation. Note that the algorithm relies on the properties of 32-bit unsigned integers (it is formally defined on bit-vectors of length 32). I have added a bitmask to make it work on 64 bit machines. We initialize the generator with s1_1 .. s3_1 = s_n MOD m, where s_n = (69069 * s_{n-1}) mod 2^32, and s_0 = s is the user-supplied seed. The theoretical value of x_{10007} is 2733957125. The subscript 10007 means (1) seed the generator with s=1 (2) do six warm-up iterations, (3) then do 10000 actual iterations. The period of this generator is about 2^88. From: P. L'Ecuyer, "Maximally Equidistributed Combined Tausworthe Generators", Mathematics of Computation, 65, 213 (1996), 203--213. This is available on the net from L'Ecuyer's home page, http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps ftp://ftp.iro.umontreal.ca/pub/simulation/lecuyer/papers/tausme.ps Update: April 2002 There is an erratum in the paper "Tables of Maximally Equidistributed Combined LFSR Generators", Mathematics of Computation, 68, 225 (1999), 261--269: http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme2.ps ... the k_j most significant bits of z_j must be non- zero, for each j. (Note: this restriction also applies to the computer code given in [4], but was mistakenly not mentioned in that paper.) This affects the seeding procedure by imposing the requirement s1 > 1, s2 > 7, s3 > 15. The generator taus2 has been added to satisfy this requirement. The original taus generator is unchanged. Update: November 2002 There was a bug in the correction to the seeding procedure for s2. It affected the following seeds 254679140 1264751179 1519430319 2274823218 2529502358 3284895257 3539574397 (s2 < 8). */ static inline unsigned long int taus_get (void *vstate); static double taus_get_double (void *vstate); static void taus_set (void *state, unsigned long int s); typedef struct { unsigned long int s1, s2, s3; } taus_state_t; static inline unsigned long taus_get (void *vstate) { taus_state_t *state = (taus_state_t *) vstate; #define MASK 0xffffffffUL #define TAUSWORTHE(s,a,b,c,d) (((s &c) <>b) state->s1 = TAUSWORTHE (state->s1, 13, 19, 4294967294UL, 12); state->s2 = TAUSWORTHE (state->s2, 2, 25, 4294967288UL, 4); state->s3 = TAUSWORTHE (state->s3, 3, 11, 4294967280UL, 17); return (state->s1 ^ state->s2 ^ state->s3); } static double taus_get_double (void *vstate) { return taus_get (vstate) / 4294967296.0 ; } static void taus_set (void *vstate, unsigned long int s) { taus_state_t *state = (taus_state_t *) vstate; if (s == 0) s = 1; /* default seed is 1 */ #define LCG(n) ((69069 * n) & 0xffffffffUL) state->s1 = LCG (s); state->s2 = LCG (state->s1); state->s3 = LCG (state->s2); /* "warm it up" */ taus_get (state); taus_get (state); taus_get (state); taus_get (state); taus_get (state); taus_get (state); return; } static void taus2_set (void *vstate, unsigned long int s) { taus_state_t *state = (taus_state_t *) vstate; if (s == 0) s = 1; /* default seed is 1 */ #define LCG(n) ((69069 * n) & 0xffffffffUL) state->s1 = LCG (s); if (state->s1 < 2) state->s1 += 2UL; state->s2 = LCG (state->s1); if (state->s2 < 8) state->s2 += 8UL; state->s3 = LCG (state->s2); if (state->s3 < 16) state->s3 += 16UL; /* "warm it up" */ taus_get (state); taus_get (state); taus_get (state); taus_get (state); taus_get (state); taus_get (state); return; } static const gsl_rng_type taus_type = {"taus", /* name */ 0xffffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (taus_state_t), &taus_set, &taus_get, &taus_get_double}; const gsl_rng_type *gsl_rng_taus = &taus_type; static const gsl_rng_type taus2_type = {"taus2", /* name */ 0xffffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (taus_state_t), &taus2_set, &taus_get, &taus_get_double}; const gsl_rng_type *gsl_rng_taus2 = &taus2_type; praat-6.0.04/external/gsl/gsl_rng__taus113.c000066400000000000000000000125701261542461700205530ustar00rootroot00000000000000/* rng/taus113.c * Copyright (C) 2002 Atakan Gurkan * Based on the file taus.c which has the notice * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* This is a maximally equidistributed combined, collision free Tausworthe generator, with a period ~2^{113}. The sequence is, x_n = (z1_n ^ z2_n ^ z3_n ^ z4_n) b = (((z1_n << 6) ^ z1_n) >> 13) z1_{n+1} = (((z1_n & 4294967294) << 18) ^ b) b = (((z2_n << 2) ^ z2_n) >> 27) z2_{n+1} = (((z2_n & 4294967288) << 2) ^ b) b = (((z3_n << 13) ^ z3_n) >> 21) z3_{n+1} = (((z3_n & 4294967280) << 7) ^ b) b = (((z4_n << 3) ^ z4_n) >> 12) z4_{n+1} = (((z4_n & 4294967168) << 13) ^ b) computed modulo 2^32. In the formulas above '^' means exclusive-or (C-notation), not exponentiation. The algorithm is for 32-bit integers, hence a bitmask is used to clear all but least significant 32 bits, after left shifts, to make the code work on architectures where integers are 64-bit. The generator is initialized with zi = (69069 * z{i+1}) MOD 2^32 where z0 is the seed provided During initialization a check is done to make sure that the initial seeds have a required number of their most significant bits set. After this, the state is passed through the RNG 10 times to ensure the state satisfies a recurrence relation. References: P. L'Ecuyer, "Tables of Maximally-Equidistributed Combined LFSR Generators", Mathematics of Computation, 68, 225 (1999), 261--269. http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme2.ps P. L'Ecuyer, "Maximally Equidistributed Combined Tausworthe Generators", Mathematics of Computation, 65, 213 (1996), 203--213. http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps the online version of the latter contains corrections to the print version. */ #include "gsl__config.h" #include #include "gsl_rng.h" #define LCG(n) ((69069UL * n) & 0xffffffffUL) #define MASK 0xffffffffUL static inline unsigned long int taus113_get (void *vstate); static double taus113_get_double (void *vstate); static void taus113_set (void *state, unsigned long int s); typedef struct { unsigned long int z1, z2, z3, z4; } taus113_state_t; static inline unsigned long taus113_get (void *vstate) { taus113_state_t *state = (taus113_state_t *) vstate; unsigned long b1, b2, b3, b4; b1 = ((((state->z1 << 6UL) & MASK) ^ state->z1) >> 13UL); state->z1 = ((((state->z1 & 4294967294UL) << 18UL) & MASK) ^ b1); b2 = ((((state->z2 << 2UL) & MASK) ^ state->z2) >> 27UL); state->z2 = ((((state->z2 & 4294967288UL) << 2UL) & MASK) ^ b2); b3 = ((((state->z3 << 13UL) & MASK) ^ state->z3) >> 21UL); state->z3 = ((((state->z3 & 4294967280UL) << 7UL) & MASK) ^ b3); b4 = ((((state->z4 << 3UL) & MASK) ^ state->z4) >> 12UL); state->z4 = ((((state->z4 & 4294967168UL) << 13UL) & MASK) ^ b4); return (state->z1 ^ state->z2 ^ state->z3 ^ state->z4); } static double taus113_get_double (void *vstate) { return taus113_get (vstate) / 4294967296.0; } static void taus113_set (void *vstate, unsigned long int s) { taus113_state_t *state = (taus113_state_t *) vstate; if (!s) s = 1UL; /* default seed is 1 */ state->z1 = LCG (s); if (state->z1 < 2UL) state->z1 += 2UL; state->z2 = LCG (state->z1); if (state->z2 < 8UL) state->z2 += 8UL; state->z3 = LCG (state->z2); if (state->z3 < 16UL) state->z3 += 16UL; state->z4 = LCG (state->z3); if (state->z4 < 128UL) state->z4 += 128UL; /* Calling RNG ten times to satify recurrence condition */ taus113_get (state); taus113_get (state); taus113_get (state); taus113_get (state); taus113_get (state); taus113_get (state); taus113_get (state); taus113_get (state); taus113_get (state); taus113_get (state); return; } static const gsl_rng_type taus113_type = { "taus113", /* name */ 0xffffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (taus113_state_t), &taus113_set, &taus113_get, &taus113_get_double }; const gsl_rng_type *gsl_rng_taus113 = &taus113_type; /* Rules for analytic calculations using GNU Emacs Calc: (used to find the values for the test program) [ LCG(n) := n * 69069 mod (2^32) ] [ b1(x) := rsh(xor(lsh(x, 6), x), 13), q1(x) := xor(lsh(and(x, 4294967294), 18), b1(x)), b2(x) := rsh(xor(lsh(x, 2), x), 27), q2(x) := xor(lsh(and(x, 4294967288), 2), b2(x)), b3(x) := rsh(xor(lsh(x, 13), x), 21), q3(x) := xor(lsh(and(x, 4294967280), 7), b3(x)), b4(x) := rsh(xor(lsh(x, 3), x), 12), q4(x) := xor(lsh(and(x, 4294967168), 13), b4(x)) ] [ S([z1,z2,z3,z4]) := [q1(z1), q2(z2), q3(z3), q4(z4)] ] */ praat-6.0.04/external/gsl/gsl_rng__transputer.c000066400000000000000000000043551261542461700215630ustar00rootroot00000000000000/* rng/transputer.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" /* This is the INMOS Transputer Development System generator. The sequence is, x_{n+1} = (a x_n) mod m with a = 1664525 and m = 2^32. The seed specifies the initial value, x_1. The theoretical value of x_{10001} is 1244127297. The period of this generator is 2^30. */ static inline unsigned long int transputer_get (void *vstate); static double transputer_get_double (void *vstate); static void transputer_set (void *state, unsigned long int s); typedef struct { unsigned long int x; } transputer_state_t; static unsigned long int transputer_get (void *vstate) { transputer_state_t *state = (transputer_state_t *) vstate; state->x = (1664525 * state->x) & 0xffffffffUL; return state->x; } static double transputer_get_double (void *vstate) { return transputer_get (vstate) / 4294967296.0 ; } static void transputer_set (void *vstate, unsigned long int s) { transputer_state_t *state = (transputer_state_t *) vstate; if (s == 0) s = 1 ; /* default seed is 1. */ state->x = s; return; } static const gsl_rng_type transputer_type = {"transputer", /* name */ 0xffffffffUL, /* RAND_MAX */ 1, /* RAND_MIN */ sizeof (transputer_state_t), &transputer_set, &transputer_get, &transputer_get_double}; const gsl_rng_type *gsl_rng_transputer = &transputer_type; praat-6.0.04/external/gsl/gsl_rng__tt.c000066400000000000000000000074161261542461700200040ustar00rootroot00000000000000/* rng/tt.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" /* This is the TT800 twisted GSFR generator for 32 bit integers. It has been superceded by MT19937 (mt.c). The period is 2^800. This implementation is based on tt800.c, July 8th 1996 version by M. Matsumoto, email: matumoto@math.keio.ac.jp From: Makoto Matsumoto and Yoshiharu Kurita, "Twisted GFSR Generators II", ACM Transactions on Modelling and Computer Simulation, Vol. 4, No. 3, 1994, pages 254-266. */ static inline unsigned long int tt_get (void *vstate); static double tt_get_double (void *vstate); static void tt_set (void *state, unsigned long int s); #define N 25 #define M 7 typedef struct { int n; unsigned long int x[N]; } tt_state_t; static inline unsigned long int tt_get (void *vstate) { tt_state_t *state = (tt_state_t *) vstate; /* this is the magic vector, a */ const unsigned long mag01[2] = {0x00000000, 0x8ebfd028UL}; unsigned long int y; unsigned long int *const x = state->x; int n = state->n; if (n >= N) { int i; for (i = 0; i < N - M; i++) { x[i] = x[i + M] ^ (x[i] >> 1) ^ mag01[x[i] % 2]; } for (; i < N; i++) { x[i] = x[i + (M - N)] ^ (x[i] >> 1) ^ mag01[x[i] % 2]; }; n = 0; } y = x[n]; y ^= (y << 7) & 0x2b5b2500UL; /* s and b, magic vectors */ y ^= (y << 15) & 0xdb8b0000UL; /* t and c, magic vectors */ y &= 0xffffffffUL; /* you may delete this line if word size = 32 */ /* The following line was added by Makoto Matsumoto in the 1996 version to improve lower bit's correlation. Delete this line to use the code published in 1994. */ y ^= (y >> 16); /* added to the 1994 version */ state->n = n + 1; return y; } static double tt_get_double (void * vstate) { return tt_get (vstate) / 4294967296.0 ; } static void tt_set (void *vstate, unsigned long int s) { tt_state_t *state = (tt_state_t *) vstate; const tt_state_t init_state = {0, {0x95f24dabUL, 0x0b685215UL, 0xe76ccae7UL, 0xaf3ec239UL, 0x715fad23UL, 0x24a590adUL, 0x69e4b5efUL, 0xbf456141UL, 0x96bc1b7bUL, 0xa7bdf825UL, 0xc1de75b7UL, 0x8858a9c9UL, 0x2da87693UL, 0xb657f9ddUL, 0xffdc8a9fUL, 0x8121da71UL, 0x8b823ecbUL, 0x885d05f5UL, 0x4e20cd47UL, 0x5a9ad5d9UL, 0x512c0c03UL, 0xea857ccdUL, 0x4cc1d30fUL, 0x8891a8a1UL, 0xa6b7aadbUL}}; if (s == 0) /* default seed is given explicitly in the original code */ { *state = init_state; } else { int i; state->n = 0; state->x[0] = s & 0xffffffffUL; for (i = 1; i < N; i++) state->x[i] = (69069 * state->x[i - 1]) & 0xffffffffUL; } return; } static const gsl_rng_type tt_type = {"tt800", /* name */ 0xffffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (tt_state_t), &tt_set, &tt_get, &tt_get_double}; const gsl_rng_type *gsl_rng_tt800 = &tt_type; praat-6.0.04/external/gsl/gsl_rng__types.c000066400000000000000000000052051261542461700205130ustar00rootroot00000000000000/* rng/types.c * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" #define N 100 const gsl_rng_type * gsl_rng_generator_types[N]; #define ADD(t) {if (i==N) abort(); gsl_rng_generator_types[i] = (t); i++; }; const gsl_rng_type ** gsl_rng_types_setup (void) { int i = 0; ADD(gsl_rng_borosh13); ADD(gsl_rng_cmrg); ADD(gsl_rng_coveyou); ADD(gsl_rng_fishman18); ADD(gsl_rng_fishman20); ADD(gsl_rng_fishman2x); ADD(gsl_rng_gfsr4); ADD(gsl_rng_knuthran); ADD(gsl_rng_knuthran2); ADD(gsl_rng_knuthran2002); ADD(gsl_rng_lecuyer21); ADD(gsl_rng_minstd); ADD(gsl_rng_mrg); ADD(gsl_rng_mt19937); ADD(gsl_rng_mt19937_1999); ADD(gsl_rng_mt19937_1998); ADD(gsl_rng_r250); ADD(gsl_rng_ran0); ADD(gsl_rng_ran1); ADD(gsl_rng_ran2); ADD(gsl_rng_ran3); ADD(gsl_rng_rand); ADD(gsl_rng_rand48); ADD(gsl_rng_random128_bsd); ADD(gsl_rng_random128_glibc2); ADD(gsl_rng_random128_libc5); ADD(gsl_rng_random256_bsd); ADD(gsl_rng_random256_glibc2); ADD(gsl_rng_random256_libc5); ADD(gsl_rng_random32_bsd); ADD(gsl_rng_random32_glibc2); ADD(gsl_rng_random32_libc5); ADD(gsl_rng_random64_bsd); ADD(gsl_rng_random64_glibc2); ADD(gsl_rng_random64_libc5); ADD(gsl_rng_random8_bsd); ADD(gsl_rng_random8_glibc2); ADD(gsl_rng_random8_libc5); ADD(gsl_rng_random_bsd); ADD(gsl_rng_random_glibc2); ADD(gsl_rng_random_libc5); ADD(gsl_rng_randu); ADD(gsl_rng_ranf); ADD(gsl_rng_ranlux); ADD(gsl_rng_ranlux389); ADD(gsl_rng_ranlxd1); ADD(gsl_rng_ranlxd2); ADD(gsl_rng_ranlxs0); ADD(gsl_rng_ranlxs1); ADD(gsl_rng_ranlxs2); ADD(gsl_rng_ranmar); ADD(gsl_rng_slatec); ADD(gsl_rng_taus); ADD(gsl_rng_taus2); ADD(gsl_rng_taus113); ADD(gsl_rng_transputer); ADD(gsl_rng_tt800); ADD(gsl_rng_uni); ADD(gsl_rng_uni32); ADD(gsl_rng_vax); ADD(gsl_rng_waterman14); ADD(gsl_rng_zuf); ADD(0); return gsl_rng_generator_types; } praat-6.0.04/external/gsl/gsl_rng__uni.c000066400000000000000000000136731261542461700201520ustar00rootroot00000000000000/* rng/uni.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** This is a lagged Fibonacci generator which supposedly excellent statistical properties (I do not concur) I got it from the net and translated into C. * ====================================================================== * NIST Guide to Available Math Software. * Fullsource for module UNI from package CMLIB. * Retrieved from CAMSUN on Tue Oct 8 14:04:10 1996. * ====================================================================== C***BEGIN PROLOGUE UNI C***DATE WRITTEN 810915 C***REVISION DATE 830805 C***CATEGORY NO. L6A21 C***KEYWORDS RANDOM NUMBERS, UNIFORM RANDOM NUMBERS C***AUTHOR BLUE, JAMES, SCIENTIFIC COMPUTING DIVISION, NBS C KAHANER, DAVID, SCIENTIFIC COMPUTING DIVISION, NBS C MARSAGLIA, GEORGE, COMPUTER SCIENCE DEPT., WASH STATE UNIV C C***PURPOSE THIS ROUTINE GENERATES QUASI UNIFORM RANDOM NUMBERS ON [0,1 C AND CAN BE USED ON ANY COMPUTER WITH WHICH ALLOWS INTEGERS C AT LEAST AS LARGE AS 32767. C***DESCRIPTION C C THIS ROUTINE GENERATES QUASI UNIFORM RANDOM NUMBERS ON THE INTER C [0,1). IT CAN BE USED WITH ANY COMPUTER WHICH ALLOWS C INTEGERS AT LEAST AS LARGE AS 32767. C C C USE C FIRST TIME.... C Z = UNI(JD) C HERE JD IS ANY N O N - Z E R O INTEGER. C THIS CAUSES INITIALIZATION OF THE PROGRAM C AND THE FIRST RANDOM NUMBER TO BE RETURNED AS Z. C SUBSEQUENT TIMES... C Z = UNI(0) C CAUSES THE NEXT RANDOM NUMBER TO BE RETURNED AS Z. C C C.................................................................. C NOTE: USERS WHO WISH TO TRANSPORT THIS PROGRAM FROM ONE COMPUTER C TO ANOTHER SHOULD READ THE FOLLOWING INFORMATION..... C C MACHINE DEPENDENCIES... C MDIG = A LOWER BOUND ON THE NUMBER OF BINARY DIGITS AVAILABLE C FOR REPRESENTING INTEGERS, INCLUDING THE SIGN BIT. C THIS VALUE MUST BE AT LEAST 16, BUT MAY BE INCREASED C IN LINE WITH REMARK A BELOW. C C REMARKS... C A. THIS PROGRAM CAN BE USED IN TWO WAYS: C (1) TO OBTAIN REPEATABLE RESULTS ON DIFFERENT COMPUTERS, C SET 'MDIG' TO THE SMALLEST OF ITS VALUES ON EACH, OR, C (2) TO ALLOW THE LONGEST SEQUENCE OF RANDOM NUMBERS TO BE C GENERATED WITHOUT CYCLING (REPEATING) SET 'MDIG' TO THE C LARGEST POSSIBLE VALUE. C B. THE SEQUENCE OF NUMBERS GENERATED DEPENDS ON THE INITIAL C INPUT 'JD' AS WELL AS THE VALUE OF 'MDIG'. C IF MDIG=16 ONE SHOULD FIND THAT Editors Note: set the seed using 152 in order to get uni(305) -jt C THE FIRST EVALUATION C Z=UNI(305) GIVES Z=.027832881... C THE SECOND EVALUATION C Z=UNI(0) GIVES Z=.56102176... C THE THIRD EVALUATION C Z=UNI(0) GIVES Z=.41456343... C THE THOUSANDTH EVALUATION C Z=UNI(0) GIVES Z=.19797357... C C***REFERENCES MARSAGLIA G., "COMMENTS ON THE PERFECT UNIFORM RANDOM C NUMBER GENERATOR", UNPUBLISHED NOTES, WASH S. U. C***ROUTINES CALLED I1MACH,XERROR C***END PROLOGUE UNI **/ #include "gsl__config.h" #include #include "gsl_rng.h" static inline unsigned long int uni_get (void *vstate); static double uni_get_double (void *vstate); static void uni_set (void *state, unsigned long int s); static const unsigned int MDIG = 16; /* Machine digits in int */ static const unsigned int m1 = 32767; /* 2^(MDIG-1) - 1 */ static const unsigned int m2 = 256; /* 2^(MDIG/2) */ typedef struct { int i, j; unsigned long m[17]; } uni_state_t; static inline unsigned long uni_get (void *vstate) { uni_state_t *state = (uni_state_t *) vstate; const int i = state->i; const int j = state->j; /* important k not be unsigned */ long k = state->m[i] - state->m[j]; if (k < 0) k += m1; state->m[j] = k; if (i == 0) { state->i = 16; } else { (state->i)--; } if (j == 0) { state->j = 16; } else { (state->j)--; } return k; } static double uni_get_double (void *vstate) { return uni_get (vstate) / 32767.0 ; } static void uni_set (void *vstate, unsigned long int s) { unsigned int i, seed, k0, k1, j0, j1; uni_state_t *state = (uni_state_t *) vstate; /* For this routine, the seeding is very elaborate! */ /* A flaw in this approach is that seeds 1,2 give exactly the same random number sequence! */ s = 2 * s + 1; /* enforce seed be odd */ seed = (s < m1 ? s : m1); /* seed should be less than m1 */ k0 = 9069 % m2; k1 = 9069 / m2; j0 = seed % m2; j1 = seed / m2; for (i = 0; i < 17; ++i) { seed = j0 * k0; j1 = (seed / m2 + j0 * k1 + j1 * k0) % (m2 / 2); j0 = seed % m2; state->m[i] = j0 + m2 * j1; } state->i = 4; state->j = 16; return; } static const gsl_rng_type uni_type = {"uni", /* name */ 32766, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (uni_state_t), &uni_set, &uni_get, &uni_get_double}; const gsl_rng_type *gsl_rng_uni = &uni_type; praat-6.0.04/external/gsl/gsl_rng__uni32.c000066400000000000000000000140641261542461700203120ustar00rootroot00000000000000/* rng/uni32.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** This is a lagged Fibonacci generator which supposedly excellent statistical properties (I do not concur) I got it from the net and translated into C. * ====================================================================== * NIST Guide to Available Math Software. * Fullsource for module UNI from package CMLIB. * Retrieved from CAMSUN on Tue Oct 8 14:04:10 1996. * ====================================================================== C***BEGIN PROLOGUE UNI C***DATE WRITTEN 810915 C***REVISION DATE 830805 C***CATEGORY NO. L6A21 C***KEYWORDS RANDOM NUMBERS, UNIFORM RANDOM NUMBERS C***AUTHOR BLUE, JAMES, SCIENTIFIC COMPUTING DIVISION, NBS C KAHANER, DAVID, SCIENTIFIC COMPUTING DIVISION, NBS C MARSAGLIA, GEORGE, COMPUTER SCIENCE DEPT., WASH STATE UNIV C C***PURPOSE THIS ROUTINE GENERATES QUASI UNIFORM RANDOM NUMBERS ON [0,1 C AND CAN BE USED ON ANY COMPUTER WITH WHICH ALLOWS INTEGERS C AT LEAST AS LARGE AS 32767. C***DESCRIPTION C C THIS ROUTINE GENERATES QUASI UNIFORM RANDOM NUMBERS ON THE INTER C [0,1). IT CAN BE USED WITH ANY COMPUTER WHICH ALLOWS C INTEGERS AT LEAST AS LARGE AS 32767. C C C USE C FIRST TIME.... C Z = UNI(JD) C HERE JD IS ANY N O N - Z E R O INTEGER. C THIS CAUSES INITIALIZATION OF THE PROGRAM C AND THE FIRST RANDOM NUMBER TO BE RETURNED AS Z. C SUBSEQUENT TIMES... C Z = UNI(0) C CAUSES THE NEXT RANDOM NUMBER TO BE RETURNED AS Z. C C C.................................................................. C NOTE: USERS WHO WISH TO TRANSPORT THIS PROGRAM FROM ONE COMPUTER C TO ANOTHER SHOULD READ THE FOLLOWING INFORMATION..... C C MACHINE DEPENDENCIES... C MDIG = A LOWER BOUND ON THE NUMBER OF BINARY DIGITS AVAILABLE C FOR REPRESENTING INTEGERS, INCLUDING THE SIGN BIT. C THIS VALUE MUST BE AT LEAST 16, BUT MAY BE INCREASED C IN LINE WITH REMARK A BELOW. C C REMARKS... C A. THIS PROGRAM CAN BE USED IN TWO WAYS: C (1) TO OBTAIN REPEATABLE RESULTS ON DIFFERENT COMPUTERS, C SET 'MDIG' TO THE SMALLEST OF ITS VALUES ON EACH, OR, C (2) TO ALLOW THE LONGEST SEQUENCE OF RANDOM NUMBERS TO BE C GENERATED WITHOUT CYCLING (REPEATING) SET 'MDIG' TO THE C LARGEST POSSIBLE VALUE. C B. THE SEQUENCE OF NUMBERS GENERATED DEPENDS ON THE INITIAL C INPUT 'JD' AS WELL AS THE VALUE OF 'MDIG'. C IF MDIG=16 ONE SHOULD FIND THAT Editors Note: set the seed using 152 in order to get uni(305) -jt C THE FIRST EVALUATION C Z=UNI(305) GIVES Z=.027832881... C THE SECOND EVALUATION C Z=UNI(0) GIVES Z=.56102176... C THE THIRD EVALUATION C Z=UNI(0) GIVES Z=.41456343... C THE THOUSANDTH EVALUATION C Z=UNI(0) GIVES Z=.19797357... C C***REFERENCES MARSAGLIA G., "COMMENTS ON THE PERFECT UNIFORM RANDOM C NUMBER GENERATOR", UNPUBLISHED NOTES, WASH S. U. C***ROUTINES CALLED I1MACH,XERROR C***END PROLOGUE UNI **/ #include "gsl__config.h" #include #include "gsl_rng.h" static inline unsigned long int uni32_get (void *vstate); static double uni32_get_double (void *vstate); static void uni32_set (void *state, unsigned long int s); static const unsigned long int MDIG = 32; /* Machine digits in int */ static const unsigned long int m1 = 2147483647; /* 2^(MDIG-1) - 1 */ static const unsigned long int m2 = 65536; /* 2^(MDIG/2) */ typedef struct { int i, j; unsigned long m[17]; } uni32_state_t; static inline unsigned long uni32_get (void *vstate) { uni32_state_t *state = (uni32_state_t *) vstate; const long int i = state->i; const long int j = state->j; /* important k not be unsigned */ long int k = state->m[i] - state->m[j]; if (k < 0) k += m1; state->m[j] = k; if (i == 0) { state->i = 16; } else { (state->i)--; } if (j == 0) { state->j = 16; } else { (state->j)--; } return k; } static double uni32_get_double (void *vstate) { return uni32_get (vstate) / 2147483647.0 ; } static void uni32_set (void *vstate, unsigned long int s) { long int seed, k0, k1, j0, j1; int i; uni32_state_t *state = (uni32_state_t *) vstate; /* For this routine, the seeding is very elaborate! */ /* A flaw in this approach is that seeds 1,2 give exactly the same random number sequence! */ /*s = 2*s+1; *//* enforce seed be odd */ seed = (s < m1 ? s : m1); /* seed should be less than m1 */ seed -= (seed % 2 == 0 ? 1 : 0); k0 = 9069 % m2; k1 = 9069 / m2; j0 = seed % m2; j1 = seed / m2; for (i = 0; i < 17; i++) { seed = j0 * k0; j1 = (seed / m2 + j0 * k1 + j1 * k0) % (m2 / 2); j0 = seed % m2; state->m[i] = j0 + m2 * j1; } state->i = 4; state->j = 16; return; } static const gsl_rng_type uni32_type = {"uni32", /* name */ 2147483646, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (uni32_state_t), &uni32_set, &uni32_get, &uni32_get_double}; const gsl_rng_type *gsl_rng_uni32 = &uni32_type; praat-6.0.04/external/gsl/gsl_rng__vax.c000066400000000000000000000042131261542461700201430ustar00rootroot00000000000000/* rng/vax.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" /* This is the old vax generator MTH$RANDOM. The sequence is, x_{n+1} = (a x_n + c) mod m with a = 69069, c = 1 and m = 2^32. The seed specifies the initial value, x_1. The theoretical value of x_{10001} is 3051034865. The period of this generator is 2^32. */ static inline unsigned long int vax_get (void *vstate); static double vax_get_double (void *vstate); static void vax_set (void *state, unsigned long int s); typedef struct { unsigned long int x; } vax_state_t; static inline unsigned long int vax_get (void *vstate) { vax_state_t *state = (vax_state_t *) vstate; state->x = (69069 * state->x + 1) & 0xffffffffUL; return state->x; } static double vax_get_double (void *vstate) { return vax_get (vstate) / 4294967296.0 ; } static void vax_set (void *vstate, unsigned long int s) { vax_state_t *state = (vax_state_t *) vstate; /* default seed is 0. The constant term c stops the series from collapsing to 0,0,0,0,0,... */ state->x = s; return; } static const gsl_rng_type vax_type = {"vax", /* name */ 0xffffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (vax_state_t), &vax_set, &vax_get, &vax_get_double}; const gsl_rng_type *gsl_rng_vax = &vax_type; praat-6.0.04/external/gsl/gsl_rng__waterman14.c000066400000000000000000000042221261542461700213300ustar00rootroot00000000000000/* rng/waterman14.c * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This generator is taken from * * Donald E. Knuth * The Art of Computer Programming * Volume 2 * Third Edition * Addison-Wesley * Page 106-108 * * It is called "Waterman". * * This implementation copyright (C) 2001 Carlo Perassi * and (C) 2003 Heiko Bauke. */ #include "gsl__config.h" #include #include "gsl_rng.h" #define AA 1566083941UL #define MM 0xffffffffUL /* 2 ^ 32 - 1 */ static inline unsigned long int ran_get (void *vstate); static double ran_get_double (void *vstate); static void ran_set (void *state, unsigned long int s); typedef struct { unsigned long int x; } ran_state_t; static inline unsigned long int ran_get (void *vstate) { ran_state_t *state = (ran_state_t *) vstate; state->x = (AA * state->x) & MM; return state->x; } static double ran_get_double (void *vstate) { ran_state_t *state = (ran_state_t *) vstate; return ran_get (state) / 4294967296.0; } static void ran_set (void *vstate, unsigned long int s) { ran_state_t *state = (ran_state_t *) vstate; if (s == 0) s = 1; /* default seed is 1 */ state->x = s & MM; return; } static const gsl_rng_type ran_type = { "waterman14", /* name */ MM, /* RAND_MAX */ 1, /* RAND_MIN */ sizeof (ran_state_t), &ran_set, &ran_get, &ran_get_double }; const gsl_rng_type *gsl_rng_waterman14 = &ran_type; praat-6.0.04/external/gsl/gsl_rng__zuf.c000066400000000000000000000067121261542461700201570ustar00rootroot00000000000000/* rng/zuf.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_rng.h" /* It is crucial that m == n-273 mod 607 at all times; For speed of execution, however, this is never enforced. Instead is is set in the initializer: note 607-273=334 Note also that the state.u[607] is not initialized */ static inline unsigned long int zuf_get (void *vstate); static double zuf_get_double (void *vstate); static void zuf_set (void *state, unsigned long int s); static const unsigned long int zuf_randmax = 16777216; /* 2^24 */ typedef struct { int n; unsigned long int u[607]; } zuf_state_t; /* The zufall package was implemented with float's, which is to say 24 bits of precision. Since I'm using long's instead, my RANDMAX reflects this. */ static inline unsigned long int zuf_get (void *vstate) { zuf_state_t *state = (zuf_state_t *) vstate; const int n = state->n; const int m = (n - 273 + 607) % 607; unsigned long int t = state->u[n] + state->u[m]; while (t > zuf_randmax) t -= zuf_randmax; state->u[n] = t; if (n == 606) { state->n = 0; } else { state->n = n + 1; } return t; } static double zuf_get_double (void *vstate) { return zuf_get (vstate) / 16777216.0 ; } static void zuf_set (void *vstate, unsigned long int s) { /* A very elaborate seeding procedure is provided with the zufall package; this is virtually a copy of that procedure */ /* Initialized data */ long int kl = 9373; long int ij = 1802; /* Local variables */ long int i, j, k, l, m; double x, y; long int ii, jj; zuf_state_t *state = (zuf_state_t *) vstate; state->n = 0; /* generates initial seed buffer by linear congruential */ /* method. Taken from Marsaglia, FSU report FSU-SCRI-87-50 */ /* variable seed should be 0 < seed <31328 */ if (s == 0) s = 1802; /* default seed is 1802 */ ij = s; i = ij / 177 % 177 + 2; j = ij % 177 + 2; k = kl / 169 % 178 + 1; l = kl % 169; for (ii = 0; ii < 607; ++ii) { x = 0.0; y = 0.5; /* 24 bits?? */ for (jj = 1; jj <= 24; ++jj) { m = i * j % 179 * k % 179; i = j; j = k; k = m; l = (l * 53 + 1) % 169; if (l * m % 64 >= 32) { x += y; } y *= 0.5; } state->u[ii] = (unsigned long int) (x * zuf_randmax); } } static const gsl_rng_type zuf_type = {"zuf", /* name */ 0x00ffffffUL, /* RAND_MAX */ 0, /* RAND_MIN */ sizeof (zuf_state_t), &zuf_set, &zuf_get, &zuf_get_double}; const gsl_rng_type *gsl_rng_zuf = &zuf_type; praat-6.0.04/external/gsl/gsl_roots.h000066400000000000000000000072101261542461700175130ustar00rootroot00000000000000/* roots/gsl_roots.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Reid Priedhorsky, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_ROOTS_H__ #define __GSL_ROOTS_H__ #include #include "gsl_types.h" #include "gsl_math.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { const char *name; size_t size; int (*set) (void *state, gsl_function * f, double * root, double x_lower, double x_upper); int (*iterate) (void *state, gsl_function * f, double * root, double * x_lower, double * x_upper); } gsl_root_fsolver_type; typedef struct { const gsl_root_fsolver_type * type; gsl_function * function ; double root ; double x_lower; double x_upper; void *state; } gsl_root_fsolver; typedef struct { const char *name; size_t size; int (*set) (void *state, gsl_function_fdf * f, double * root); int (*iterate) (void *state, gsl_function_fdf * f, double * root); } gsl_root_fdfsolver_type; typedef struct { const gsl_root_fdfsolver_type * type; gsl_function_fdf * fdf ; double root ; void *state; } gsl_root_fdfsolver; gsl_root_fsolver * gsl_root_fsolver_alloc (const gsl_root_fsolver_type * T); void gsl_root_fsolver_free (gsl_root_fsolver * s); int gsl_root_fsolver_set (gsl_root_fsolver * s, gsl_function * f, double x_lower, double x_upper); int gsl_root_fsolver_iterate (gsl_root_fsolver * s); const char * gsl_root_fsolver_name (const gsl_root_fsolver * s); double gsl_root_fsolver_root (const gsl_root_fsolver * s); double gsl_root_fsolver_x_lower (const gsl_root_fsolver * s); double gsl_root_fsolver_x_upper (const gsl_root_fsolver * s); gsl_root_fdfsolver * gsl_root_fdfsolver_alloc (const gsl_root_fdfsolver_type * T); int gsl_root_fdfsolver_set (gsl_root_fdfsolver * s, gsl_function_fdf * fdf, double root); int gsl_root_fdfsolver_iterate (gsl_root_fdfsolver * s); void gsl_root_fdfsolver_free (gsl_root_fdfsolver * s); const char * gsl_root_fdfsolver_name (const gsl_root_fdfsolver * s); double gsl_root_fdfsolver_root (const gsl_root_fdfsolver * s); int gsl_root_test_interval (double x_lower, double x_upper, double epsabs, double epsrel); int gsl_root_test_residual (double f, double epsabs); int gsl_root_test_delta (double x1, double x0, double epsabs, double epsrel); GSL_VAR const gsl_root_fsolver_type * gsl_root_fsolver_bisection; GSL_VAR const gsl_root_fsolver_type * gsl_root_fsolver_brent; GSL_VAR const gsl_root_fsolver_type * gsl_root_fsolver_falsepos; GSL_VAR const gsl_root_fdfsolver_type * gsl_root_fdfsolver_newton; GSL_VAR const gsl_root_fdfsolver_type * gsl_root_fdfsolver_secant; GSL_VAR const gsl_root_fdfsolver_type * gsl_root_fdfsolver_steffenson; __END_DECLS #endif /* __GSL_ROOTS_H__ */ praat-6.0.04/external/gsl/gsl_roots__bisection.c000066400000000000000000000066051261542461700217130ustar00rootroot00000000000000/* roots/bisection.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Reid Priedhorsky, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* bisection.c -- bisection root finding algorithm */ #include "gsl__config.h" #include #include #include #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_roots.h" #include "gsl_roots__roots.h" typedef struct { double f_lower, f_upper; } bisection_state_t; static int bisection_init (void * vstate, gsl_function * f, double * root, double x_lower, double x_upper); static int bisection_iterate (void * vstate, gsl_function * f, double * root, double * x_lower, double * x_upper); static int bisection_init (void * vstate, gsl_function * f, double * root, double x_lower, double x_upper) { bisection_state_t * state = (bisection_state_t *) vstate; double f_lower, f_upper ; *root = 0.5 * (x_lower + x_upper) ; SAFE_FUNC_CALL (f, x_lower, &f_lower); SAFE_FUNC_CALL (f, x_upper, &f_upper); state->f_lower = f_lower; state->f_upper = f_upper; if ((f_lower < 0.0 && f_upper < 0.0) || (f_lower > 0.0 && f_upper > 0.0)) { GSL_ERROR ("endpoints do not straddle y=0", GSL_EINVAL); } return GSL_SUCCESS; } static int bisection_iterate (void * vstate, gsl_function * f, double * root, double * x_lower, double * x_upper) { bisection_state_t * state = (bisection_state_t *) vstate; double x_bisect, f_bisect; const double x_left = *x_lower ; const double x_right = *x_upper ; const double f_lower = state->f_lower; const double f_upper = state->f_upper; if (f_lower == 0.0) { *root = x_left ; *x_upper = x_left; return GSL_SUCCESS; } if (f_upper == 0.0) { *root = x_right ; *x_lower = x_right; return GSL_SUCCESS; } x_bisect = (x_left + x_right) / 2.0; SAFE_FUNC_CALL (f, x_bisect, &f_bisect); if (f_bisect == 0.0) { *root = x_bisect; *x_lower = x_bisect; *x_upper = x_bisect; return GSL_SUCCESS; } /* Discard the half of the interval which doesn't contain the root. */ if ((f_lower > 0.0 && f_bisect < 0.0) || (f_lower < 0.0 && f_bisect > 0.0)) { *root = 0.5 * (x_left + x_bisect) ; *x_upper = x_bisect; state->f_upper = f_bisect; } else { *root = 0.5 * (x_bisect + x_right) ; *x_lower = x_bisect; state->f_lower = f_bisect; } return GSL_SUCCESS; } static const gsl_root_fsolver_type bisection_type = {"bisection", /* name */ sizeof (bisection_state_t), &bisection_init, &bisection_iterate}; const gsl_root_fsolver_type * gsl_root_fsolver_bisection = &bisection_type; praat-6.0.04/external/gsl/gsl_roots__brent.c000066400000000000000000000114711261542461700210430ustar00rootroot00000000000000/* roots/brent.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Reid Priedhorsky, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* brent.c -- brent root finding algorithm */ #include "gsl__config.h" #include #include #include #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_roots.h" #include "gsl_roots__roots.h" typedef struct { double a, b, c, d, e; double fa, fb, fc; } brent_state_t; static int brent_init (void * vstate, gsl_function * f, double * root, double x_lower, double x_upper); static int brent_iterate (void * vstate, gsl_function * f, double * root, double * x_lower, double * x_upper); static int brent_init (void * vstate, gsl_function * f, double * root, double x_lower, double x_upper) { brent_state_t * state = (brent_state_t *) vstate; double f_lower, f_upper ; *root = 0.5 * (x_lower + x_upper) ; SAFE_FUNC_CALL (f, x_lower, &f_lower); SAFE_FUNC_CALL (f, x_upper, &f_upper); state->a = x_lower; state->fa = f_lower; state->b = x_upper; state->fb = f_upper; state->c = x_upper; state->fc = f_upper; state->d = x_upper - x_lower ; state->e = x_upper - x_lower ; if ((f_lower < 0.0 && f_upper < 0.0) || (f_lower > 0.0 && f_upper > 0.0)) { GSL_ERROR ("endpoints do not straddle y=0", GSL_EINVAL); } return GSL_SUCCESS; } static int brent_iterate (void * vstate, gsl_function * f, double * root, double * x_lower, double * x_upper) { brent_state_t * state = (brent_state_t *) vstate; double tol, m; int ac_equal = 0; double a = state->a, b = state->b, c = state->c; double fa = state->fa, fb = state->fb, fc = state->fc; double d = state->d, e = state->e; if ((fb < 0 && fc < 0) || (fb > 0 && fc > 0)) { ac_equal = 1; c = a; fc = fa; d = b - a; e = b - a; } if (fabs (fc) < fabs (fb)) { ac_equal = 1; a = b; b = c; c = a; fa = fb; fb = fc; fc = fa; } tol = 0.5 * GSL_DBL_EPSILON * fabs (b); m = 0.5 * (c - b); if (fb == 0) { *root = b; *x_lower = b; *x_upper = b; return GSL_SUCCESS; } if (fabs (m) <= tol) { *root = b; if (b < c) { *x_lower = b; *x_upper = c; } else { *x_lower = c; *x_upper = b; } return GSL_SUCCESS; } if (fabs (e) < tol || fabs (fa) <= fabs (fb)) { d = m; /* use bisection */ e = m; } else { double p, q, r; /* use inverse cubic interpolation */ double s = fb / fa; if (ac_equal) { p = 2 * m * s; q = 1 - s; } else { q = fa / fc; r = fb / fc; p = s * (2 * m * q * (q - r) - (b - a) * (r - 1)); q = (q - 1) * (r - 1) * (s - 1); } if (p > 0) { q = -q; } else { p = -p; } if (2 * p < GSL_MIN (3 * m * q - fabs (tol * q), fabs (e * q))) { e = d; d = p / q; } else { /* interpolation failed, fall back to bisection */ d = m; e = m; } } a = b; fa = fb; if (fabs (d) > tol) { b += d; } else { b += (m > 0 ? +tol : -tol); } SAFE_FUNC_CALL (f, b, &fb); state->a = a ; state->b = b ; state->c = c ; state->d = d ; state->e = e ; state->fa = fa ; state->fb = fb ; state->fc = fc ; /* Update the best estimate of the root and bounds on each iteration */ *root = b; if ((fb < 0 && fc < 0) || (fb > 0 && fc > 0)) { c = a; } if (b < c) { *x_lower = b; *x_upper = c; } else { *x_lower = c; *x_upper = b; } return GSL_SUCCESS ; } static const gsl_root_fsolver_type brent_type = {"brent", /* name */ sizeof (brent_state_t), &brent_init, &brent_iterate}; const gsl_root_fsolver_type * gsl_root_fsolver_brent = &brent_type; praat-6.0.04/external/gsl/gsl_roots__convergence.c000066400000000000000000000044611261542461700222300ustar00rootroot00000000000000/* roots/convergence.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Reid Priedhorsky, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_roots.h" int gsl_root_test_interval (double x_lower, double x_upper, double epsabs, double epsrel) { const double abs_lower = fabs(x_lower) ; const double abs_upper = fabs(x_upper) ; double min_abs, tolerance; if (epsrel < 0.0) GSL_ERROR ("relative tolerance is negative", GSL_EBADTOL); if (epsabs < 0.0) GSL_ERROR ("absolute tolerance is negative", GSL_EBADTOL); if (x_lower > x_upper) GSL_ERROR ("lower bound larger than upper bound", GSL_EINVAL); if ((x_lower > 0.0 && x_upper > 0.0) || (x_lower < 0.0 && x_upper < 0.0)) { min_abs = GSL_MIN_DBL(abs_lower, abs_upper) ; } else { min_abs = 0; } tolerance = epsabs + epsrel * min_abs ; if (fabs(x_upper - x_lower) < tolerance) return GSL_SUCCESS; return GSL_CONTINUE ; } int gsl_root_test_delta (double x1, double x0, double epsabs, double epsrel) { const double tolerance = epsabs + epsrel * fabs(x1) ; if (epsrel < 0.0) GSL_ERROR ("relative tolerance is negative", GSL_EBADTOL); if (epsabs < 0.0) GSL_ERROR ("absolute tolerance is negative", GSL_EBADTOL); if (fabs(x1 - x0) < tolerance || x1 == x0) return GSL_SUCCESS; return GSL_CONTINUE ; } int gsl_root_test_residual (double f, double epsabs) { if (epsabs < 0.0) GSL_ERROR ("absolute tolerance is negative", GSL_EBADTOL); if (fabs(f) < epsabs) return GSL_SUCCESS; return GSL_CONTINUE ; } praat-6.0.04/external/gsl/gsl_roots__falsepos.c000066400000000000000000000110651261542461700215440ustar00rootroot00000000000000/* roots/falsepos.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Reid Priedhorsky, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* falsepos.c -- falsepos root finding algorithm The false position algorithm uses bracketing by linear interpolation. If a linear interpolation step would decrease the size of the bracket by less than a bisection step would then the algorithm takes a bisection step instead. The last linear interpolation estimate of the root is used. If a bisection step causes it to fall outside the brackets then it is replaced by the bisection estimate (x_upper + x_lower)/2. */ #include "gsl__config.h" #include #include #include #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_roots.h" #include "gsl_roots__roots.h" typedef struct { double f_lower, f_upper; } falsepos_state_t; static int falsepos_init (void * vstate, gsl_function * f, double * root, double x_lower, double x_upper); static int falsepos_iterate (void * vstate, gsl_function * f, double * root, double * x_lower, double * x_upper); static int falsepos_init (void * vstate, gsl_function * f, double * root, double x_lower, double x_upper) { falsepos_state_t * state = (falsepos_state_t *) vstate; double f_lower, f_upper ; *root = 0.5 * (x_lower + x_upper); SAFE_FUNC_CALL (f, x_lower, &f_lower); SAFE_FUNC_CALL (f, x_upper, &f_upper); state->f_lower = f_lower; state->f_upper = f_upper; if ((f_lower < 0.0 && f_upper < 0.0) || (f_lower > 0.0 && f_upper > 0.0)) { GSL_ERROR ("endpoints do not straddle y=0", GSL_EINVAL); } return GSL_SUCCESS; } static int falsepos_iterate (void * vstate, gsl_function * f, double * root, double * x_lower, double * x_upper) { falsepos_state_t * state = (falsepos_state_t *) vstate; double x_linear, f_linear; double x_bisect, f_bisect; double x_left = *x_lower ; double x_right = *x_upper ; double f_lower = state->f_lower; double f_upper = state->f_upper; double w ; if (f_lower == 0.0) { *root = x_left ; *x_upper = x_left; return GSL_SUCCESS; } if (f_upper == 0.0) { *root = x_right ; *x_lower = x_right; return GSL_SUCCESS; } /* Draw a line between f(*lower_bound) and f(*upper_bound) and note where it crosses the X axis; that's where we will split the interval. */ x_linear = x_right - (f_upper * (x_left - x_right) / (f_lower - f_upper)); SAFE_FUNC_CALL (f, x_linear, &f_linear); if (f_linear == 0.0) { *root = x_linear; *x_lower = x_linear; *x_upper = x_linear; return GSL_SUCCESS; } /* Discard the half of the interval which doesn't contain the root. */ if ((f_lower > 0.0 && f_linear < 0.0) || (f_lower < 0.0 && f_linear > 0.0)) { *root = x_linear ; *x_upper = x_linear; state->f_upper = f_linear; w = x_linear - x_left ; } else { *root = x_linear ; *x_lower = x_linear; state->f_lower = f_linear; w = x_right - x_linear; } if (w < 0.5 * (x_right - x_left)) { return GSL_SUCCESS ; } x_bisect = 0.5 * (x_left + x_right); SAFE_FUNC_CALL (f, x_bisect, &f_bisect); if ((f_lower > 0.0 && f_bisect < 0.0) || (f_lower < 0.0 && f_bisect > 0.0)) { *x_upper = x_bisect; state->f_upper = f_bisect; if (*root > x_bisect) *root = 0.5 * (x_left + x_bisect) ; } else { *x_lower = x_bisect; state->f_lower = f_bisect; if (*root < x_bisect) *root = 0.5 * (x_bisect + x_right) ; } return GSL_SUCCESS; } static const gsl_root_fsolver_type falsepos_type = {"falsepos", /* name */ sizeof (falsepos_state_t), &falsepos_init, &falsepos_iterate}; const gsl_root_fsolver_type * gsl_root_fsolver_falsepos = &falsepos_type; praat-6.0.04/external/gsl/gsl_roots__fdfsolver.c000066400000000000000000000041331261542461700217200ustar00rootroot00000000000000/* roots/fdfsolver.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Reid Priedhorsky, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_errno.h" #include "gsl_roots.h" gsl_root_fdfsolver * gsl_root_fdfsolver_alloc (const gsl_root_fdfsolver_type * T) { gsl_root_fdfsolver * s = (gsl_root_fdfsolver *) malloc (sizeof (gsl_root_fdfsolver)); if (s == 0) { GSL_ERROR_VAL ("failed to allocate space for root solver struct", GSL_ENOMEM, 0); }; s->state = malloc (T->size); if (s->state == 0) { free (s); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for root solver state", GSL_ENOMEM, 0); }; s->type = T ; s->fdf = NULL; return s; } int gsl_root_fdfsolver_set (gsl_root_fdfsolver * s, gsl_function_fdf * f, double root) { s->fdf = f; s->root = root; return (s->type->set) (s->state, s->fdf, &(s->root)); } int gsl_root_fdfsolver_iterate (gsl_root_fdfsolver * s) { return (s->type->iterate) (s->state, s->fdf, &(s->root)); } void gsl_root_fdfsolver_free (gsl_root_fdfsolver * s) { free (s->state); free (s); } const char * gsl_root_fdfsolver_name (const gsl_root_fdfsolver * s) { return s->type->name; } double gsl_root_fdfsolver_root (const gsl_root_fdfsolver * s) { return s->root; } praat-6.0.04/external/gsl/gsl_roots__fsolver.c000066400000000000000000000050721261542461700214110ustar00rootroot00000000000000/* roots/fsolver.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Reid Priedhorsky, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include "gsl_errno.h" #include "gsl_roots.h" gsl_root_fsolver * gsl_root_fsolver_alloc (const gsl_root_fsolver_type * T) { gsl_root_fsolver * s = (gsl_root_fsolver *) malloc (sizeof (gsl_root_fsolver)); if (s == 0) { GSL_ERROR_VAL ("failed to allocate space for root solver struct", GSL_ENOMEM, 0); }; s->state = malloc (T->size); if (s->state == 0) { free (s); /* exception in constructor, avoid memory leak */ GSL_ERROR_VAL ("failed to allocate space for root solver state", GSL_ENOMEM, 0); }; s->type = T ; s->function = NULL ; return s; } int gsl_root_fsolver_set (gsl_root_fsolver * s, gsl_function * f, double x_lower, double x_upper) { if (x_lower > x_upper) { GSL_ERROR ("invalid interval (lower > upper)", GSL_EINVAL); } s->function = f; s->root = 0.5 * (x_lower + x_upper); /* initial estimate */ s->x_lower = x_lower; s->x_upper = x_upper; return (s->type->set) (s->state, s->function, &(s->root), x_lower, x_upper); } int gsl_root_fsolver_iterate (gsl_root_fsolver * s) { return (s->type->iterate) (s->state, s->function, &(s->root), &(s->x_lower), &(s->x_upper)); } void gsl_root_fsolver_free (gsl_root_fsolver * s) { free (s->state); free (s); } const char * gsl_root_fsolver_name (const gsl_root_fsolver * s) { return s->type->name; } double gsl_root_fsolver_root (const gsl_root_fsolver * s) { return s->root; } double gsl_root_fsolver_x_lower (const gsl_root_fsolver * s) { return s->x_lower; } double gsl_root_fsolver_x_upper (const gsl_root_fsolver * s) { return s->x_upper; } praat-6.0.04/external/gsl/gsl_roots__newton.c000066400000000000000000000050601261542461700212400ustar00rootroot00000000000000/* roots/newton.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Reid Priedhorsky, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* newton.c -- newton root finding algorithm This is the classical Newton-Raphson iteration. x[i+1] = x[i] - f(x[i])/f'(x[i]) */ #include "gsl__config.h" #include #include #include #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_roots.h" #include "gsl_roots__roots.h" typedef struct { double f, df; } newton_state_t; static int newton_init (void * vstate, gsl_function_fdf * fdf, double * root); static int newton_iterate (void * vstate, gsl_function_fdf * fdf, double * root); static int newton_init (void * vstate, gsl_function_fdf * fdf, double * root) { newton_state_t * state = (newton_state_t *) vstate; const double x = *root ; state->f = GSL_FN_FDF_EVAL_F (fdf, x); state->df = GSL_FN_FDF_EVAL_DF (fdf, x) ; return GSL_SUCCESS; } static int newton_iterate (void * vstate, gsl_function_fdf * fdf, double * root) { newton_state_t * state = (newton_state_t *) vstate; double root_new, f_new, df_new; if (state->df == 0.0) { GSL_ERROR("derivative is zero", GSL_EZERODIV); } root_new = *root - (state->f / state->df); *root = root_new ; GSL_FN_FDF_EVAL_F_DF(fdf, root_new, &f_new, &df_new); state->f = f_new ; state->df = df_new ; if (!gsl_finite(f_new)) { GSL_ERROR ("function value is not finite", GSL_EBADFUNC); } if (!gsl_finite (df_new)) { GSL_ERROR ("derivative value is not finite", GSL_EBADFUNC); } return GSL_SUCCESS; } static const gsl_root_fdfsolver_type newton_type = {"newton", /* name */ sizeof (newton_state_t), &newton_init, &newton_iterate}; const gsl_root_fdfsolver_type * gsl_root_fdfsolver_newton = &newton_type; praat-6.0.04/external/gsl/gsl_roots__roots.h000066400000000000000000000024031261542461700210770ustar00rootroot00000000000000/* roots/roots.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Reid Priedhorsky, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* roots.h -- declarations for internal root finding and RF support stuff. */ #ifndef __ROOTS_H__ #define __ROOTS_H__ /* Call the pointed-to function with argument x, put its result in y, and return an error if the function value is Inf/Nan. */ #define SAFE_FUNC_CALL(f, x, yp) \ do { \ *yp = GSL_FN_EVAL(f,x); \ if (!gsl_finite(*yp)) \ GSL_ERROR("function value is not finite", GSL_EBADFUNC); \ } while (0) #endif /* __ROOTS_H__ */ praat-6.0.04/external/gsl/gsl_roots__secant.c000066400000000000000000000055471261542461700212150ustar00rootroot00000000000000/* roots/secant.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Reid Priedhorsky, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* secant.c -- secant root finding algorithm The secant algorithm is a variant of the Newton algorithm with the derivative term replaced by a numerical estimate from the last two function evaluations. x[i+1] = x[i] - f(x[i]) / f'_est where f'_est = (f(x[i]) - f(x[i-1])) / (x[i] - x[i-1]) The exact derivative is used for the initial value of f'_est. */ #include "gsl__config.h" #include #include #include #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_roots.h" #include "gsl_roots__roots.h" typedef struct { double f; double df; } secant_state_t; static int secant_init (void * vstate, gsl_function_fdf * fdf, double * root); static int secant_iterate (void * vstate, gsl_function_fdf * fdf, double * root); static int secant_init (void * vstate, gsl_function_fdf * fdf, double * root) { secant_state_t * state = (secant_state_t *) vstate; const double x = *root; GSL_FN_FDF_EVAL_F_DF (fdf, x, &(state->f), &(state->df)); return GSL_SUCCESS; } static int secant_iterate (void * vstate, gsl_function_fdf * fdf, double * root) { secant_state_t * state = (secant_state_t *) vstate; const double x = *root ; const double f = state->f; const double df = state->df; double x_new, f_new, df_new; if (state->df == 0.0) { GSL_ERROR("derivative is zero", GSL_EZERODIV); } x_new = x - (f / df); f_new = GSL_FN_FDF_EVAL_F(fdf, x_new) ; df_new = (f_new - f) / (x_new - x) ; *root = x_new ; state->f = f_new ; state->df = df_new ; if (!gsl_finite (f_new)) { GSL_ERROR ("function value is not finite", GSL_EBADFUNC); } if (!gsl_finite (df_new)) { GSL_ERROR ("derivative value is not finite", GSL_EBADFUNC); } return GSL_SUCCESS; } static const gsl_root_fdfsolver_type secant_type = {"secant", /* name */ sizeof (secant_state_t), &secant_init, &secant_iterate}; const gsl_root_fdfsolver_type * gsl_root_fdfsolver_secant = &secant_type; praat-6.0.04/external/gsl/gsl_roots__steffenson.c000066400000000000000000000067341261542461700221110ustar00rootroot00000000000000/* roots/steffenson.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Reid Priedhorsky, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* steffenson.c -- steffenson root finding algorithm This is Newton's method with an Aitken "delta-squared" acceleration of the iterates. This can improve the convergence on multiple roots where the ordinary Newton algorithm is slow. x[i+1] = x[i] - f(x[i]) / f'(x[i]) x_accelerated[i] = x[i] - (x[i+1] - x[i])**2 / (x[i+2] - 2*x[i+1] + x[i]) We can only use the accelerated estimate after three iterations, and use the unaccelerated value until then. */ #include "gsl__config.h" #include #include #include #include #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_roots.h" #include "gsl_roots__roots.h" typedef struct { double f, df; double x; double x_1; double x_2; int count; } steffenson_state_t; static int steffenson_init (void * vstate, gsl_function_fdf * fdf, double * root); static int steffenson_iterate (void * vstate, gsl_function_fdf * fdf, double * root); static int steffenson_init (void * vstate, gsl_function_fdf * fdf, double * root) { steffenson_state_t * state = (steffenson_state_t *) vstate; const double x = *root ; state->f = GSL_FN_FDF_EVAL_F (fdf, x); state->df = GSL_FN_FDF_EVAL_DF (fdf, x) ; state->x = x; state->x_1 = 0.0; state->x_2 = 0.0; state->count = 1; return GSL_SUCCESS; } static int steffenson_iterate (void * vstate, gsl_function_fdf * fdf, double * root) { steffenson_state_t * state = (steffenson_state_t *) vstate; double x_new, f_new, df_new; double x_1 = state->x_1 ; double x = state->x ; if (state->df == 0.0) { GSL_ERROR("derivative is zero", GSL_EZERODIV); } x_new = x - (state->f / state->df); GSL_FN_FDF_EVAL_F_DF(fdf, x_new, &f_new, &df_new); state->x_2 = x_1 ; state->x_1 = x ; state->x = x_new; state->f = f_new ; state->df = df_new ; if (!gsl_finite (f_new)) { GSL_ERROR ("function value is not finite", GSL_EBADFUNC); } if (state->count < 3) { *root = x_new ; state->count++ ; } else { double u = (x - x_1) ; double v = (x_new - 2 * x + x_1); if (v == 0) *root = x_new; /* avoid division by zero */ else *root = x_1 - u * u / v ; /* accelerated value */ } if (!gsl_finite (df_new)) { GSL_ERROR ("derivative value is not finite", GSL_EBADFUNC); } return GSL_SUCCESS; } static const gsl_root_fdfsolver_type steffenson_type = {"steffenson", /* name */ sizeof (steffenson_state_t), &steffenson_init, &steffenson_iterate}; const gsl_root_fdfsolver_type * gsl_root_fdfsolver_steffenson = &steffenson_type; praat-6.0.04/external/gsl/gsl_sf.h000066400000000000000000000016301261542461700167550ustar00rootroot00000000000000/* Author: G. Jungman */ #ifndef __GSL_SF_H__ #define __GSL_SF_H__ #include "gsl_sf_result.h" #include "gsl_sf_airy.h" #include "gsl_sf_bessel.h" #include "gsl_sf_clausen.h" #include "gsl_sf_coupling.h" #include "gsl_sf_coulomb.h" #include "gsl_sf_dawson.h" #include "gsl_sf_debye.h" #include "gsl_sf_dilog.h" #include "gsl_sf_elementary.h" #include "gsl_sf_ellint.h" #include "gsl_sf_elljac.h" #include "gsl_sf_erf.h" #include "gsl_sf_exp.h" #include "gsl_sf_expint.h" #include "gsl_sf_fermi_dirac.h" #include "gsl_sf_gamma.h" #include "gsl_sf_gegenbauer.h" #include "gsl_sf_hyperg.h" #include "gsl_sf_laguerre.h" #include "gsl_sf_lambert.h" #include "gsl_sf_legendre.h" #include "gsl_sf_log.h" #include "gsl_sf_mathieu.h" #include "gsl_sf_pow_int.h" #include "gsl_sf_psi.h" #include "gsl_sf_synchrotron.h" #include "gsl_sf_transport.h" #include "gsl_sf_trig.h" #include "gsl_sf_zeta.h" #endif /* __GSL_SF_H__ */ praat-6.0.04/external/gsl/gsl_sf_airy.h000066400000000000000000000071651261542461700200120ustar00rootroot00000000000000/* specfunc/gsl_sf_airy.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_AIRY_H__ #define __GSL_SF_AIRY_H__ #include "gsl_mode.h" #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Airy function Ai(x) * * exceptions: GSL_EUNDRFLW */ int gsl_sf_airy_Ai_e(const double x, const gsl_mode_t mode, gsl_sf_result * result); double gsl_sf_airy_Ai(const double x, gsl_mode_t mode); /* Airy function Bi(x) * * exceptions: GSL_EOVRFLW */ int gsl_sf_airy_Bi_e(const double x, gsl_mode_t mode, gsl_sf_result * result); double gsl_sf_airy_Bi(const double x, gsl_mode_t mode); /* scaled Ai(x): * Ai(x) x < 0 * exp(+2/3 x^{3/2}) Ai(x) x > 0 * * exceptions: none */ int gsl_sf_airy_Ai_scaled_e(const double x, gsl_mode_t mode, gsl_sf_result * result); double gsl_sf_airy_Ai_scaled(const double x, gsl_mode_t mode); /* scaled Bi(x): * Bi(x) x < 0 * exp(-2/3 x^{3/2}) Bi(x) x > 0 * * exceptions: none */ int gsl_sf_airy_Bi_scaled_e(const double x, gsl_mode_t mode, gsl_sf_result * result); double gsl_sf_airy_Bi_scaled(const double x, gsl_mode_t mode); /* derivative Ai'(x) * * exceptions: GSL_EUNDRFLW */ int gsl_sf_airy_Ai_deriv_e(const double x, gsl_mode_t mode, gsl_sf_result * result); double gsl_sf_airy_Ai_deriv(const double x, gsl_mode_t mode); /* derivative Bi'(x) * * exceptions: GSL_EOVRFLW */ int gsl_sf_airy_Bi_deriv_e(const double x, gsl_mode_t mode, gsl_sf_result * result); double gsl_sf_airy_Bi_deriv(const double x, gsl_mode_t mode); /* scaled derivative Ai'(x): * Ai'(x) x < 0 * exp(+2/3 x^{3/2}) Ai'(x) x > 0 * * exceptions: none */ int gsl_sf_airy_Ai_deriv_scaled_e(const double x, gsl_mode_t mode, gsl_sf_result * result); double gsl_sf_airy_Ai_deriv_scaled(const double x, gsl_mode_t mode); /* scaled derivative: * Bi'(x) x < 0 * exp(-2/3 x^{3/2}) Bi'(x) x > 0 * * exceptions: none */ int gsl_sf_airy_Bi_deriv_scaled_e(const double x, gsl_mode_t mode, gsl_sf_result * result); double gsl_sf_airy_Bi_deriv_scaled(const double x, gsl_mode_t mode); /* Zeros of Ai(x) */ int gsl_sf_airy_zero_Ai_e(unsigned int s, gsl_sf_result * result); double gsl_sf_airy_zero_Ai(unsigned int s); /* Zeros of Bi(x) */ int gsl_sf_airy_zero_Bi_e(unsigned int s, gsl_sf_result * result); double gsl_sf_airy_zero_Bi(unsigned int s); /* Zeros of Ai'(x) */ int gsl_sf_airy_zero_Ai_deriv_e(unsigned int s, gsl_sf_result * result); double gsl_sf_airy_zero_Ai_deriv(unsigned int s); /* Zeros of Bi'(x) */ int gsl_sf_airy_zero_Bi_deriv_e(unsigned int s, gsl_sf_result * result); double gsl_sf_airy_zero_Bi_deriv(unsigned int s); __END_DECLS #endif /* __GSL_SF_AIRY_H__ */ praat-6.0.04/external/gsl/gsl_sf_bessel.h000066400000000000000000000333501261542461700203160ustar00rootroot00000000000000/* specfunc/gsl_sf_bessel.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_BESSEL_H__ #define __GSL_SF_BESSEL_H__ #include #include "gsl_mode.h" #include "gsl_precision.h" #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Regular Bessel Function J_0(x) * * exceptions: none */ int gsl_sf_bessel_J0_e(const double x, gsl_sf_result * result); double gsl_sf_bessel_J0(const double x); /* Regular Bessel Function J_1(x) * * exceptions: GSL_EUNDRFLW */ int gsl_sf_bessel_J1_e(const double x, gsl_sf_result * result); double gsl_sf_bessel_J1(const double x); /* Regular Bessel Function J_n(x) * * exceptions: GSL_EUNDRFLW */ int gsl_sf_bessel_Jn_e(int n, double x, gsl_sf_result * result); double gsl_sf_bessel_Jn(const int n, const double x); /* Regular Bessel Function J_n(x), nmin <= n <= nmax * * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_bessel_Jn_array(int nmin, int nmax, double x, double * result_array); /* Irregular Bessel function Y_0(x) * * x > 0.0 * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_bessel_Y0_e(const double x, gsl_sf_result * result); double gsl_sf_bessel_Y0(const double x); /* Irregular Bessel function Y_1(x) * * x > 0.0 * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_bessel_Y1_e(const double x, gsl_sf_result * result); double gsl_sf_bessel_Y1(const double x); /* Irregular Bessel function Y_n(x) * * x > 0.0 * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_bessel_Yn_e(int n,const double x, gsl_sf_result * result); double gsl_sf_bessel_Yn(const int n,const double x); /* Irregular Bessel function Y_n(x), nmin <= n <= nmax * * x > 0.0 * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_bessel_Yn_array(const int nmin, const int nmax, const double x, double * result_array); /* Regular modified Bessel function I_0(x) * * exceptions: GSL_EOVRFLW */ int gsl_sf_bessel_I0_e(const double x, gsl_sf_result * result); double gsl_sf_bessel_I0(const double x); /* Regular modified Bessel function I_1(x) * * exceptions: GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_bessel_I1_e(const double x, gsl_sf_result * result); double gsl_sf_bessel_I1(const double x); /* Regular modified Bessel function I_n(x) * * exceptions: GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_bessel_In_e(const int n, const double x, gsl_sf_result * result); double gsl_sf_bessel_In(const int n, const double x); /* Regular modified Bessel function I_n(x) for n=nmin,...,nmax * * nmin >=0, nmax >= nmin * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_bessel_In_array(const int nmin, const int nmax, const double x, double * result_array); /* Scaled regular modified Bessel function * exp(-|x|) I_0(x) * * exceptions: none */ int gsl_sf_bessel_I0_scaled_e(const double x, gsl_sf_result * result); double gsl_sf_bessel_I0_scaled(const double x); /* Scaled regular modified Bessel function * exp(-|x|) I_1(x) * * exceptions: GSL_EUNDRFLW */ int gsl_sf_bessel_I1_scaled_e(const double x, gsl_sf_result * result); double gsl_sf_bessel_I1_scaled(const double x); /* Scaled regular modified Bessel function * exp(-|x|) I_n(x) * * exceptions: GSL_EUNDRFLW */ int gsl_sf_bessel_In_scaled_e(int n, const double x, gsl_sf_result * result); double gsl_sf_bessel_In_scaled(const int n, const double x); /* Scaled regular modified Bessel function * exp(-|x|) I_n(x) for n=nmin,...,nmax * * nmin >=0, nmax >= nmin * exceptions: GSL_EUNDRFLW */ int gsl_sf_bessel_In_scaled_array(const int nmin, const int nmax, const double x, double * result_array); /* Irregular modified Bessel function K_0(x) * * x > 0.0 * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_bessel_K0_e(const double x, gsl_sf_result * result); double gsl_sf_bessel_K0(const double x); /* Irregular modified Bessel function K_1(x) * * x > 0.0 * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_bessel_K1_e(const double x, gsl_sf_result * result); double gsl_sf_bessel_K1(const double x); /* Irregular modified Bessel function K_n(x) * * x > 0.0 * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_bessel_Kn_e(const int n, const double x, gsl_sf_result * result); double gsl_sf_bessel_Kn(const int n, const double x); /* Irregular modified Bessel function K_n(x) for n=nmin,...,nmax * * x > 0.0, nmin >=0, nmax >= nmin * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_bessel_Kn_array(const int nmin, const int nmax, const double x, double * result_array); /* Scaled irregular modified Bessel function * exp(x) K_0(x) * * x > 0.0 * exceptions: GSL_EDOM */ int gsl_sf_bessel_K0_scaled_e(const double x, gsl_sf_result * result); double gsl_sf_bessel_K0_scaled(const double x); /* Scaled irregular modified Bessel function * exp(x) K_1(x) * * x > 0.0 * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_bessel_K1_scaled_e(const double x, gsl_sf_result * result); double gsl_sf_bessel_K1_scaled(const double x); /* Scaled irregular modified Bessel function * exp(x) K_n(x) * * x > 0.0 * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_bessel_Kn_scaled_e(int n, const double x, gsl_sf_result * result); double gsl_sf_bessel_Kn_scaled(const int n, const double x); /* Scaled irregular modified Bessel function exp(x) K_n(x) for n=nmin,...,nmax * * x > 0.0, nmin >=0, nmax >= nmin * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_bessel_Kn_scaled_array(const int nmin, const int nmax, const double x, double * result_array); /* Regular spherical Bessel function j_0(x) = sin(x)/x * * exceptions: none */ int gsl_sf_bessel_j0_e(const double x, gsl_sf_result * result); double gsl_sf_bessel_j0(const double x); /* Regular spherical Bessel function j_1(x) = (sin(x)/x - cos(x))/x * * exceptions: GSL_EUNDRFLW */ int gsl_sf_bessel_j1_e(const double x, gsl_sf_result * result); double gsl_sf_bessel_j1(const double x); /* Regular spherical Bessel function j_2(x) = ((3/x^2 - 1)sin(x) - 3cos(x)/x)/x * * exceptions: GSL_EUNDRFLW */ int gsl_sf_bessel_j2_e(const double x, gsl_sf_result * result); double gsl_sf_bessel_j2(const double x); /* Regular spherical Bessel function j_l(x) * * l >= 0, x >= 0.0 * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_bessel_jl_e(const int l, const double x, gsl_sf_result * result); double gsl_sf_bessel_jl(const int l, const double x); /* Regular spherical Bessel function j_l(x) for l=0,1,...,lmax * * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_bessel_jl_array(const int lmax, const double x, double * result_array); /* Regular spherical Bessel function j_l(x) for l=0,1,...,lmax * Uses Steed's method. * * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_bessel_jl_steed_array(const int lmax, const double x, double * jl_x_array); /* Irregular spherical Bessel function y_0(x) * * exceptions: none */ int gsl_sf_bessel_y0_e(const double x, gsl_sf_result * result); double gsl_sf_bessel_y0(const double x); /* Irregular spherical Bessel function y_1(x) * * exceptions: GSL_EUNDRFLW */ int gsl_sf_bessel_y1_e(const double x, gsl_sf_result * result); double gsl_sf_bessel_y1(const double x); /* Irregular spherical Bessel function y_2(x) * * exceptions: GSL_EUNDRFLW */ int gsl_sf_bessel_y2_e(const double x, gsl_sf_result * result); double gsl_sf_bessel_y2(const double x); /* Irregular spherical Bessel function y_l(x) * * exceptions: GSL_EUNDRFLW */ int gsl_sf_bessel_yl_e(int l, const double x, gsl_sf_result * result); double gsl_sf_bessel_yl(const int l, const double x); /* Irregular spherical Bessel function y_l(x) for l=0,1,...,lmax * * exceptions: GSL_EUNDRFLW */ int gsl_sf_bessel_yl_array(const int lmax, const double x, double * result_array); /* Regular scaled modified spherical Bessel function * * Exp[-|x|] i_0(x) * * exceptions: none */ int gsl_sf_bessel_i0_scaled_e(const double x, gsl_sf_result * result); double gsl_sf_bessel_i0_scaled(const double x); /* Regular scaled modified spherical Bessel function * * Exp[-|x|] i_1(x) * * exceptions: GSL_EUNDRFLW */ int gsl_sf_bessel_i1_scaled_e(const double x, gsl_sf_result * result); double gsl_sf_bessel_i1_scaled(const double x); /* Regular scaled modified spherical Bessel function * * Exp[-|x|] i_2(x) * * exceptions: GSL_EUNDRFLW */ int gsl_sf_bessel_i2_scaled_e(const double x, gsl_sf_result * result); double gsl_sf_bessel_i2_scaled(const double x); /* Regular scaled modified spherical Bessel functions * * Exp[-|x|] i_l(x) * * i_l(x) = Sqrt[Pi/(2x)] BesselI[l+1/2,x] * * l >= 0 * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_bessel_il_scaled_e(const int l, double x, gsl_sf_result * result); double gsl_sf_bessel_il_scaled(const int l, const double x); /* Regular scaled modified spherical Bessel functions * * Exp[-|x|] i_l(x) * for l=0,1,...,lmax * * exceptions: GSL_EUNDRFLW */ int gsl_sf_bessel_il_scaled_array(const int lmax, const double x, double * result_array); /* Irregular scaled modified spherical Bessel function * Exp[x] k_0(x) * * x > 0.0 * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_bessel_k0_scaled_e(const double x, gsl_sf_result * result); double gsl_sf_bessel_k0_scaled(const double x); /* Irregular modified spherical Bessel function * Exp[x] k_1(x) * * x > 0.0 * exceptions: GSL_EDOM, GSL_EUNDRFLW, GSL_EOVRFLW */ int gsl_sf_bessel_k1_scaled_e(const double x, gsl_sf_result * result); double gsl_sf_bessel_k1_scaled(const double x); /* Irregular modified spherical Bessel function * Exp[x] k_2(x) * * x > 0.0 * exceptions: GSL_EDOM, GSL_EUNDRFLW, GSL_EOVRFLW */ int gsl_sf_bessel_k2_scaled_e(const double x, gsl_sf_result * result); double gsl_sf_bessel_k2_scaled(const double x); /* Irregular modified spherical Bessel function * Exp[x] k_l[x] * * k_l(x) = Sqrt[Pi/(2x)] BesselK[l+1/2,x] * * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_bessel_kl_scaled_e(int l, const double x, gsl_sf_result * result); double gsl_sf_bessel_kl_scaled(const int l, const double x); /* Irregular scaled modified spherical Bessel function * Exp[x] k_l(x) * * for l=0,1,...,lmax * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_bessel_kl_scaled_array(const int lmax, const double x, double * result_array); /* Regular cylindrical Bessel function J_nu(x) * * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_bessel_Jnu_e(const double nu, const double x, gsl_sf_result * result); double gsl_sf_bessel_Jnu(const double nu, const double x); /* Irregular cylindrical Bessel function Y_nu(x) * * exceptions: */ int gsl_sf_bessel_Ynu_e(double nu, double x, gsl_sf_result * result); double gsl_sf_bessel_Ynu(const double nu, const double x); /* Regular cylindrical Bessel function J_nu(x) * evaluated at a series of x values. The array * contains the x values. They are assumed to be * strictly ordered and positive. The array is * over-written with the values of J_nu(x_i). * * exceptions: GSL_EDOM, GSL_EINVAL */ int gsl_sf_bessel_sequence_Jnu_e(double nu, gsl_mode_t mode, size_t size, double * v); /* Scaled modified cylindrical Bessel functions * * Exp[-|x|] BesselI[nu, x] * x >= 0, nu >= 0 * * exceptions: GSL_EDOM */ int gsl_sf_bessel_Inu_scaled_e(double nu, double x, gsl_sf_result * result); double gsl_sf_bessel_Inu_scaled(double nu, double x); /* Modified cylindrical Bessel functions * * BesselI[nu, x] * x >= 0, nu >= 0 * * exceptions: GSL_EDOM, GSL_EOVRFLW */ int gsl_sf_bessel_Inu_e(double nu, double x, gsl_sf_result * result); double gsl_sf_bessel_Inu(double nu, double x); /* Scaled modified cylindrical Bessel functions * * Exp[+|x|] BesselK[nu, x] * x > 0, nu >= 0 * * exceptions: GSL_EDOM */ int gsl_sf_bessel_Knu_scaled_e(const double nu, const double x, gsl_sf_result * result); double gsl_sf_bessel_Knu_scaled(const double nu, const double x); /* Modified cylindrical Bessel functions * * BesselK[nu, x] * x > 0, nu >= 0 * * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_bessel_Knu_e(const double nu, const double x, gsl_sf_result * result); double gsl_sf_bessel_Knu(const double nu, const double x); /* Logarithm of modified cylindrical Bessel functions. * * Log[BesselK[nu, x]] * x > 0, nu >= 0 * * exceptions: GSL_EDOM */ int gsl_sf_bessel_lnKnu_e(const double nu, const double x, gsl_sf_result * result); double gsl_sf_bessel_lnKnu(const double nu, const double x); /* s'th positive zero of the Bessel function J_0(x). * * exceptions: */ int gsl_sf_bessel_zero_J0_e(unsigned int s, gsl_sf_result * result); double gsl_sf_bessel_zero_J0(unsigned int s); /* s'th positive zero of the Bessel function J_1(x). * * exceptions: */ int gsl_sf_bessel_zero_J1_e(unsigned int s, gsl_sf_result * result); double gsl_sf_bessel_zero_J1(unsigned int s); /* s'th positive zero of the Bessel function J_nu(x). * * exceptions: */ int gsl_sf_bessel_zero_Jnu_e(double nu, unsigned int s, gsl_sf_result * result); double gsl_sf_bessel_zero_Jnu(double nu, unsigned int s); __END_DECLS #endif /* __GSL_SF_BESSEL_H__ */ praat-6.0.04/external/gsl/gsl_sf_clausen.h000066400000000000000000000026671261542461700205020ustar00rootroot00000000000000/* specfunc/gsl_sf_clausen.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_CLAUSEN_H__ #define __GSL_SF_CLAUSEN_H__ #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Calculate the Clausen integral: * Cl_2(x) := Integrate[-Log[2 Sin[t/2]], {t,0,x}] * * Relation to dilogarithm: * Cl_2(theta) = Im[ Li_2(e^(i theta)) ] */ int gsl_sf_clausen_e(double x, gsl_sf_result * result); double gsl_sf_clausen(const double x); __END_DECLS #endif /* __GSL_SF_CLAUSEN_H__ */ praat-6.0.04/external/gsl/gsl_sf_coulomb.h000066400000000000000000000104521261542461700204770ustar00rootroot00000000000000/* specfunc/gsl_sf_coulomb.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_COULOMB_H__ #define __GSL_SF_COULOMB_H__ #include "gsl_mode.h" #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Normalized hydrogenic bound states, radial dependence. */ /* R_1 := 2Z sqrt(Z) exp(-Z r) */ int gsl_sf_hydrogenicR_1_e(const double Z, const double r, gsl_sf_result * result); double gsl_sf_hydrogenicR_1(const double Z, const double r); /* R_n := norm exp(-Z r/n) (2Z/n)^l Laguerre[n-l-1, 2l+1, 2Z/n r] * * normalization such that psi(n,l,r) = R_n Y_{lm} */ int gsl_sf_hydrogenicR_e(const int n, const int l, const double Z, const double r, gsl_sf_result * result); double gsl_sf_hydrogenicR(const int n, const int l, const double Z, const double r); /* Coulomb wave functions F_{lam_F}(eta,x), G_{lam_G}(eta,x) * and their derivatives; lam_G := lam_F - k_lam_G * * lam_F, lam_G > -0.5 * x > 0.0 * * Conventions of Abramowitz+Stegun. * * Because there can be a large dynamic range of values, * overflows are handled gracefully. If an overflow occurs, * GSL_EOVRFLW is signalled and exponent(s) are returned * through exp_F, exp_G. These are such that * * F_L(eta,x) = fc[k_L] * exp(exp_F) * G_L(eta,x) = gc[k_L] * exp(exp_G) * F_L'(eta,x) = fcp[k_L] * exp(exp_F) * G_L'(eta,x) = gcp[k_L] * exp(exp_G) */ int gsl_sf_coulomb_wave_FG_e(const double eta, const double x, const double lam_F, const int k_lam_G, gsl_sf_result * F, gsl_sf_result * Fp, gsl_sf_result * G, gsl_sf_result * Gp, double * exp_F, double * exp_G); /* F_L(eta,x) as array */ int gsl_sf_coulomb_wave_F_array( double lam_min, int kmax, double eta, double x, double * fc_array, double * F_exponent ); /* F_L(eta,x), G_L(eta,x) as arrays */ int gsl_sf_coulomb_wave_FG_array(double lam_min, int kmax, double eta, double x, double * fc_array, double * gc_array, double * F_exponent, double * G_exponent ); /* F_L(eta,x), G_L(eta,x), F'_L(eta,x), G'_L(eta,x) as arrays */ int gsl_sf_coulomb_wave_FGp_array(double lam_min, int kmax, double eta, double x, double * fc_array, double * fcp_array, double * gc_array, double * gcp_array, double * F_exponent, double * G_exponent ); /* Coulomb wave function divided by the argument, * F(eta, x)/x. This is the function which reduces to * spherical Bessel functions in the limit eta->0. */ int gsl_sf_coulomb_wave_sphF_array(double lam_min, int kmax, double eta, double x, double * fc_array, double * F_exponent ); /* Coulomb wave function normalization constant. * [Abramowitz+Stegun 14.1.8, 14.1.9] */ int gsl_sf_coulomb_CL_e(double L, double eta, gsl_sf_result * result); int gsl_sf_coulomb_CL_array(double Lmin, int kmax, double eta, double * cl); __END_DECLS #endif /* __GSL_SF_COULOMB_H__ */ praat-6.0.04/external/gsl/gsl_sf_coupling.h000066400000000000000000000101011261542461700206460ustar00rootroot00000000000000/* specfunc/gsl_sf_coupling.h * * Copyright (C) 1996,1997,1998,1999,2000,2001,2002 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_COUPLING_H__ #define __GSL_SF_COUPLING_H__ #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* 3j Symbols: / ja jb jc \ * \ ma mb mc / * * exceptions: GSL_EDOM, GSL_EOVRFLW */ int gsl_sf_coupling_3j_e(int two_ja, int two_jb, int two_jc, int two_ma, int two_mb, int two_mc, gsl_sf_result * result ); double gsl_sf_coupling_3j(int two_ja, int two_jb, int two_jc, int two_ma, int two_mb, int two_mc ); /* 6j Symbols: / ja jb jc \ * \ jd je jf / * * exceptions: GSL_EDOM, GSL_EOVRFLW */ int gsl_sf_coupling_6j_e(int two_ja, int two_jb, int two_jc, int two_jd, int two_je, int two_jf, gsl_sf_result * result ); double gsl_sf_coupling_6j(int two_ja, int two_jb, int two_jc, int two_jd, int two_je, int two_jf ); /* Racah W coefficients: * * W(a b c d; e f) = (-1)^{a+b+c+d} / a b e \ * \ d c f / * * exceptions: GSL_EDOM, GSL_EOVRFLW */ int gsl_sf_coupling_RacahW_e(int two_ja, int two_jb, int two_jc, int two_jd, int two_je, int two_jf, gsl_sf_result * result ); double gsl_sf_coupling_RacahW(int two_ja, int two_jb, int two_jc, int two_jd, int two_je, int two_jf ); /* 9j Symbols: / ja jb jc \ * | jd je jf | * \ jg jh ji / * * exceptions: GSL_EDOM, GSL_EOVRFLW */ int gsl_sf_coupling_9j_e(int two_ja, int two_jb, int two_jc, int two_jd, int two_je, int two_jf, int two_jg, int two_jh, int two_ji, gsl_sf_result * result ); double gsl_sf_coupling_9j(int two_ja, int two_jb, int two_jc, int two_jd, int two_je, int two_jf, int two_jg, int two_jh, int two_ji ); /* INCORRECT version of 6j Symbols: * This function actually calculates * / ja jb je \ * \ jd jc jf / * It represents the original implementation, * which had the above permutation of the * arguments. This was wrong and confusing, * and I had to fix it. Sorry for the trouble. * [GJ] Tue Nov 26 12:53:39 MST 2002 * * exceptions: GSL_EDOM, GSL_EOVRFLW */ #ifndef GSL_DISABLE_DEPRECATED int gsl_sf_coupling_6j_INCORRECT_e(int two_ja, int two_jb, int two_jc, int two_jd, int two_je, int two_jf, gsl_sf_result * result ); double gsl_sf_coupling_6j_INCORRECT(int two_ja, int two_jb, int two_jc, int two_jd, int two_je, int two_jf ); #endif /* !GSL_DISABLE_DEPRECATED */ __END_DECLS #endif /* __GSL_SF_COUPLING_H__ */ praat-6.0.04/external/gsl/gsl_sf_dawson.h000066400000000000000000000025661261542461700203410ustar00rootroot00000000000000/* specfunc/gsl_sf_dawson.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_DAWSON_H__ #define __GSL_SF_DAWSON_H__ #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Dawson's integral: * * Exp[-x^2] Integral[ Exp[t^2], {t,0,x}] * * exceptions: GSL_EUNDRFLW; */ int gsl_sf_dawson_e(double x, gsl_sf_result * result); double gsl_sf_dawson(double x); __END_DECLS #endif /* __GSL_SF_DAWSON_H__ */ praat-6.0.04/external/gsl/gsl_sf_debye.h000066400000000000000000000043731261542461700201340ustar00rootroot00000000000000/* specfunc/gsl_sf_debye.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ /* augmented by D_5(x) and D_6(x) by Richard J. Mathar, 2005-11-08 */ #ifndef __GSL_SF_DEBYE_H__ #define __GSL_SF_DEBYE_H__ #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* D_n(x) := n/x^n Integrate[t^n/(e^t - 1), {t,0,x}] */ /* D_1(x) * * exceptions: GSL_EDOM */ int gsl_sf_debye_1_e(const double x, gsl_sf_result * result); double gsl_sf_debye_1(const double x); /* D_2(x) * * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_debye_2_e(const double x, gsl_sf_result * result); double gsl_sf_debye_2(const double x); /* D_3(x) * * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_debye_3_e(const double x, gsl_sf_result * result); double gsl_sf_debye_3(const double x); /* D_4(x) * * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_debye_4_e(const double x, gsl_sf_result * result); double gsl_sf_debye_4(const double x); /* D_5(x) * * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_debye_5_e(const double x, gsl_sf_result * result); double gsl_sf_debye_5(const double x); /* D_6(x) * * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_debye_6_e(const double x, gsl_sf_result * result); double gsl_sf_debye_6(const double x); __END_DECLS #endif /* __GSL_SF_DEBYE_H__ */ praat-6.0.04/external/gsl/gsl_sf_dilog.h000066400000000000000000000101071261542461700201320ustar00rootroot00000000000000/* specfunc/gsl_sf_dilog.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_DILOG_H__ #define __GSL_SF_DILOG_H__ #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Real part of DiLogarithm(x), for real argument. * In Lewin's notation, this is Li_2(x). * * Li_2(x) = - Re[ Integrate[ Log[1-s] / s, {s, 0, x}] ] * * The function in the complex plane has a branch point * at z = 1; we place the cut in the conventional way, * on [1, +infty). This means that the value for real x > 1 * is a matter of definition; however, this choice does not * affect the real part and so is not relevant to the * interpretation of this implemented function. */ int gsl_sf_dilog_e(const double x, gsl_sf_result * result); double gsl_sf_dilog(const double x); /* DiLogarithm(z), for complex argument z = x + i y. * Computes the principal branch. * * Recall that the branch cut is on the real axis with x > 1. * The imaginary part of the computed value on the cut is given * by -Pi*log(x), which is the limiting value taken approaching * from y < 0. This is a conventional choice, though there is no * true standardized choice. * * Note that there is no canonical way to lift the defining * contour to the full Riemann surface because of the appearance * of a "hidden branch point" at z = 0 on non-principal sheets. * Experts will know the simple algebraic prescription for * obtaining the sheet they want; non-experts will not want * to know anything about it. This is why GSL chooses to compute * only on the principal branch. */ int gsl_sf_complex_dilog_xy_e( const double x, const double y, gsl_sf_result * result_re, gsl_sf_result * result_im ); /* DiLogarithm(z), for complex argument z = r Exp[i theta]. * Computes the principal branch, thereby assuming an * implicit reduction of theta to the range (-2 pi, 2 pi). * * If theta is identically zero, the imaginary part is computed * as if approaching from y > 0. For other values of theta no * special consideration is given, since it is assumed that * no other machine representations of multiples of pi will * produce y = 0 precisely. This assumption depends on some * subtle properties of the machine arithmetic, such as * correct rounding and monotonicity of the underlying * implementation of sin() and cos(). * * This function is ok, but the interface is confusing since * it makes it appear that the branch structure is resolved. * Furthermore the handling of values close to the branch * cut is subtle. Perhap this interface should be deprecated. */ int gsl_sf_complex_dilog_e( const double r, const double theta, gsl_sf_result * result_re, gsl_sf_result * result_im ); /* Spence integral; spence(s) := Li_2(1-s) * * This function has a branch point at 0; we place the * cut on (-infty,0). Because of our choice for the value * of Li_2(z) on the cut, spence(s) is continuous as * s approaches the cut from above. In other words, * we define spence(x) = spence(x + i 0+). */ int gsl_sf_complex_spence_xy_e( const double x, const double y, gsl_sf_result * real_sp, gsl_sf_result * imag_sp ); __END_DECLS #endif /* __GSL_SF_DILOG_H__ */ praat-6.0.04/external/gsl/gsl_sf_elementary.h000066400000000000000000000031651261542461700212070ustar00rootroot00000000000000/* specfunc/gsl_sf_elementary.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ /* Miscellaneous elementary functions and operations. */ #ifndef __GSL_SF_ELEMENTARY_H__ #define __GSL_SF_ELEMENTARY_H__ #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Multiplication. * * exceptions: GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_multiply_e(const double x, const double y, gsl_sf_result * result); double gsl_sf_multiply(const double x, const double y); /* Multiplication of quantities with associated errors. */ int gsl_sf_multiply_err_e(const double x, const double dx, const double y, const double dy, gsl_sf_result * result); __END_DECLS #endif /* __GSL_SF_ELEMENTARY_H__ */ praat-6.0.04/external/gsl/gsl_sf_ellint.h000066400000000000000000000101131261542461700203200ustar00rootroot00000000000000/* specfunc/gsl_sf_ellint.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_ELLINT_H__ #define __GSL_SF_ELLINT_H__ #include "gsl_mode.h" #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Legendre form of complete elliptic integrals * * K(k) = Integral[1/Sqrt[1 - k^2 Sin[t]^2], {t, 0, Pi/2}] * E(k) = Integral[ Sqrt[1 - k^2 Sin[t]^2], {t, 0, Pi/2}] * * exceptions: GSL_EDOM */ int gsl_sf_ellint_Kcomp_e(double k, gsl_mode_t mode, gsl_sf_result * result); double gsl_sf_ellint_Kcomp(double k, gsl_mode_t mode); int gsl_sf_ellint_Ecomp_e(double k, gsl_mode_t mode, gsl_sf_result * result); double gsl_sf_ellint_Ecomp(double k, gsl_mode_t mode); int gsl_sf_ellint_Pcomp_e(double k, double n, gsl_mode_t mode, gsl_sf_result * result); double gsl_sf_ellint_Pcomp(double k, double n, gsl_mode_t mode); int gsl_sf_ellint_Dcomp_e(double k, gsl_mode_t mode, gsl_sf_result * result); double gsl_sf_ellint_Dcomp(double k, gsl_mode_t mode); /* Legendre form of incomplete elliptic integrals * * F(phi,k) = Integral[1/Sqrt[1 - k^2 Sin[t]^2], {t, 0, phi}] * E(phi,k) = Integral[ Sqrt[1 - k^2 Sin[t]^2], {t, 0, phi}] * P(phi,k,n) = Integral[(1 + n Sin[t]^2)^(-1)/Sqrt[1 - k^2 Sin[t]^2], {t, 0, phi}] * D(phi,k,n) = R_D(1-Sin[phi]^2, 1-k^2 Sin[phi]^2, 1.0) * * F: [Carlson, Numerische Mathematik 33 (1979) 1, (4.1)] * E: [Carlson, ", (4.2)] * P: [Carlson, ", (4.3)] * D: [Carlson, ", (4.4)] * * exceptions: GSL_EDOM */ int gsl_sf_ellint_F_e(double phi, double k, gsl_mode_t mode, gsl_sf_result * result); double gsl_sf_ellint_F(double phi, double k, gsl_mode_t mode); int gsl_sf_ellint_E_e(double phi, double k, gsl_mode_t mode, gsl_sf_result * result); double gsl_sf_ellint_E(double phi, double k, gsl_mode_t mode); int gsl_sf_ellint_P_e(double phi, double k, double n, gsl_mode_t mode, gsl_sf_result * result); double gsl_sf_ellint_P(double phi, double k, double n, gsl_mode_t mode); int gsl_sf_ellint_D_e(double phi, double k, double n, gsl_mode_t mode, gsl_sf_result * result); double gsl_sf_ellint_D(double phi, double k, double n, gsl_mode_t mode); /* Carlson's symmetric basis of functions * * RC(x,y) = 1/2 Integral[(t+x)^(-1/2) (t+y)^(-1)], {t,0,Inf}] * RD(x,y,z) = 3/2 Integral[(t+x)^(-1/2) (t+y)^(-1/2) (t+z)^(-3/2), {t,0,Inf}] * RF(x,y,z) = 1/2 Integral[(t+x)^(-1/2) (t+y)^(-1/2) (t+z)^(-1/2), {t,0,Inf}] * RJ(x,y,z,p) = 3/2 Integral[(t+x)^(-1/2) (t+y)^(-1/2) (t+z)^(-1/2) (t+p)^(-1), {t,0,Inf}] * * exceptions: GSL_EDOM */ int gsl_sf_ellint_RC_e(double x, double y, gsl_mode_t mode, gsl_sf_result * result); double gsl_sf_ellint_RC(double x, double y, gsl_mode_t mode); int gsl_sf_ellint_RD_e(double x, double y, double z, gsl_mode_t mode, gsl_sf_result * result); double gsl_sf_ellint_RD(double x, double y, double z, gsl_mode_t mode); int gsl_sf_ellint_RF_e(double x, double y, double z, gsl_mode_t mode, gsl_sf_result * result); double gsl_sf_ellint_RF(double x, double y, double z, gsl_mode_t mode); int gsl_sf_ellint_RJ_e(double x, double y, double z, double p, gsl_mode_t mode, gsl_sf_result * result); double gsl_sf_ellint_RJ(double x, double y, double z, double p, gsl_mode_t mode); __END_DECLS #endif /* __GSL_SF_ELLINT_H__ */ praat-6.0.04/external/gsl/gsl_sf_elljac.h000066400000000000000000000025241261542461700202720ustar00rootroot00000000000000/* specfunc/gsl_sf_elljac.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_ELLJAC_H__ #define __GSL_SF_ELLJAC_H__ #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Jacobian elliptic functions sn, dn, cn, * by descending Landen transformations * * exceptions: GSL_EDOM */ int gsl_sf_elljac_e(double u, double m, double * sn, double * cn, double * dn); __END_DECLS #endif /* __GSL_SF_ELLJAC_H__ */ praat-6.0.04/external/gsl/gsl_sf_erf.h000066400000000000000000000043631261542461700176170ustar00rootroot00000000000000/* specfunc/gsl_sf_erf.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_ERF_H__ #define __GSL_SF_ERF_H__ #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Complementary Error Function * erfc(x) := 2/Sqrt[Pi] Integrate[Exp[-t^2], {t,x,Infinity}] * * exceptions: none */ int gsl_sf_erfc_e(double x, gsl_sf_result * result); double gsl_sf_erfc(double x); /* Log Complementary Error Function * * exceptions: none */ int gsl_sf_log_erfc_e(double x, gsl_sf_result * result); double gsl_sf_log_erfc(double x); /* Error Function * erf(x) := 2/Sqrt[Pi] Integrate[Exp[-t^2], {t,0,x}] * * exceptions: none */ int gsl_sf_erf_e(double x, gsl_sf_result * result); double gsl_sf_erf(double x); /* Probability functions: * Z(x) : Abramowitz+Stegun 26.2.1 * Q(x) : Abramowitz+Stegun 26.2.3 * * exceptions: none */ int gsl_sf_erf_Z_e(double x, gsl_sf_result * result); int gsl_sf_erf_Q_e(double x, gsl_sf_result * result); double gsl_sf_erf_Z(double x); double gsl_sf_erf_Q(double x); /* Hazard function, also known as the inverse Mill's ratio. * * H(x) := Z(x)/Q(x) * = Sqrt[2/Pi] Exp[-x^2 / 2] / Erfc[x/Sqrt[2]] * * exceptions: GSL_EUNDRFLW */ int gsl_sf_hazard_e(double x, gsl_sf_result * result); double gsl_sf_hazard(double x); __END_DECLS #endif /* __GSL_SF_ERF_H__ */ praat-6.0.04/external/gsl/gsl_sf_exp.h000066400000000000000000000072541261542461700176410ustar00rootroot00000000000000/* specfunc/gsl_sf_exp.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_EXP_H__ #define __GSL_SF_EXP_H__ #include "gsl_sf_result.h" #include "gsl_precision.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Provide an exp() function with GSL semantics, * i.e. with proper error checking, etc. * * exceptions: GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_exp_e(const double x, gsl_sf_result * result); double gsl_sf_exp(const double x); /* Exp(x) * * exceptions: GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_exp_e10_e(const double x, gsl_sf_result_e10 * result); /* Exponentiate and multiply by a given factor: y * Exp(x) * * exceptions: GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_exp_mult_e(const double x, const double y, gsl_sf_result * result); double gsl_sf_exp_mult(const double x, const double y); /* Exponentiate and multiply by a given factor: y * Exp(x) * * exceptions: GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_exp_mult_e10_e(const double x, const double y, gsl_sf_result_e10 * result); /* exp(x)-1 * * exceptions: GSL_EOVRFLW */ int gsl_sf_expm1_e(const double x, gsl_sf_result * result); double gsl_sf_expm1(const double x); /* (exp(x)-1)/x = 1 + x/2 + x^2/(2*3) + x^3/(2*3*4) + ... * * exceptions: GSL_EOVRFLW */ int gsl_sf_exprel_e(const double x, gsl_sf_result * result); double gsl_sf_exprel(const double x); /* 2(exp(x)-1-x)/x^2 = 1 + x/3 + x^2/(3*4) + x^3/(3*4*5) + ... * * exceptions: GSL_EOVRFLW */ int gsl_sf_exprel_2_e(double x, gsl_sf_result * result); double gsl_sf_exprel_2(const double x); /* Similarly for the N-th generalization of * the above. The so-called N-relative exponential * * exprel_N(x) = N!/x^N (exp(x) - Sum[x^k/k!, {k,0,N-1}]) * = 1 + x/(N+1) + x^2/((N+1)(N+2)) + ... * = 1F1(1,1+N,x) */ int gsl_sf_exprel_n_e(const int n, const double x, gsl_sf_result * result); double gsl_sf_exprel_n(const int n, const double x); /* Exponentiate a quantity with an associated error. */ int gsl_sf_exp_err_e(const double x, const double dx, gsl_sf_result * result); /* Exponentiate a quantity with an associated error. */ int gsl_sf_exp_err_e10_e(const double x, const double dx, gsl_sf_result_e10 * result); /* Exponentiate and multiply by a given factor: y * Exp(x), * for quantities with associated errors. * * exceptions: GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_exp_mult_err_e(const double x, const double dx, const double y, const double dy, gsl_sf_result * result); /* Exponentiate and multiply by a given factor: y * Exp(x), * for quantities with associated errors. * * exceptions: GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_exp_mult_err_e10_e(const double x, const double dx, const double y, const double dy, gsl_sf_result_e10 * result); __END_DECLS #endif /* __GSL_SF_EXP_H__ */ praat-6.0.04/external/gsl/gsl_sf_expint.h000066400000000000000000000104511261542461700203450ustar00rootroot00000000000000/* specfunc/gsl_sf_expint.h * * Copyright (C) 2007 Brian Gough * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_EXPINT_H__ #define __GSL_SF_EXPINT_H__ #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* E_1(x) := Re[ Integrate[ Exp[-xt]/t, {t,1,Infinity}] ] * * x != 0.0 * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_expint_E1_e(const double x, gsl_sf_result * result); double gsl_sf_expint_E1(const double x); /* E_2(x) := Re[ Integrate[ Exp[-xt]/t^2, {t,1,Infinity}] ] * * x != 0.0 * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_expint_E2_e(const double x, gsl_sf_result * result); double gsl_sf_expint_E2(const double x); /* E_n(x) := Re[ Integrate[ Exp[-xt]/t^n, {t,1,Infinity}] ] * * x != 0.0 * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_expint_En_e(const int n, const double x, gsl_sf_result * result); double gsl_sf_expint_En(const int n, const double x); /* E_1_scaled(x) := exp(x) E_1(x) * * x != 0.0 * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_expint_E1_scaled_e(const double x, gsl_sf_result * result); double gsl_sf_expint_E1_scaled(const double x); /* E_2_scaled(x) := exp(x) E_2(x) * * x != 0.0 * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_expint_E2_scaled_e(const double x, gsl_sf_result * result); double gsl_sf_expint_E2_scaled(const double x); /* E_n_scaled(x) := exp(x) E_n(x) * * x != 0.0 * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_expint_En_scaled_e(const int n, const double x, gsl_sf_result * result); double gsl_sf_expint_En_scaled(const int n, const double x); /* Ei(x) := - PV Integrate[ Exp[-t]/t, {t,-x,Infinity}] * := PV Integrate[ Exp[t]/t, {t,-Infinity,x}] * * x != 0.0 * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_expint_Ei_e(const double x, gsl_sf_result * result); double gsl_sf_expint_Ei(const double x); /* Ei_scaled(x) := exp(-x) Ei(x) * * x != 0.0 * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_expint_Ei_scaled_e(const double x, gsl_sf_result * result); double gsl_sf_expint_Ei_scaled(const double x); /* Shi(x) := Integrate[ Sinh[t]/t, {t,0,x}] * * exceptions: GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_Shi_e(const double x, gsl_sf_result * result); double gsl_sf_Shi(const double x); /* Chi(x) := Re[ M_EULER + log(x) + Integrate[(Cosh[t]-1)/t, {t,0,x}] ] * * x != 0.0 * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_Chi_e(const double x, gsl_sf_result * result); double gsl_sf_Chi(const double x); /* Ei_3(x) := Integral[ Exp[-t^3], {t,0,x}] * * x >= 0.0 * exceptions: GSL_EDOM */ int gsl_sf_expint_3_e(const double x, gsl_sf_result * result); double gsl_sf_expint_3(double x); /* Si(x) := Integrate[ Sin[t]/t, {t,0,x}] * * exceptions: none */ int gsl_sf_Si_e(const double x, gsl_sf_result * result); double gsl_sf_Si(const double x); /* Ci(x) := -Integrate[ Cos[t]/t, {t,x,Infinity}] * * x > 0.0 * exceptions: GSL_EDOM */ int gsl_sf_Ci_e(const double x, gsl_sf_result * result); double gsl_sf_Ci(const double x); /* AtanInt(x) := Integral[ Arctan[t]/t, {t,0,x}] * * * exceptions: */ int gsl_sf_atanint_e(const double x, gsl_sf_result * result); double gsl_sf_atanint(const double x); __END_DECLS #endif /* __GSL_SF_EXPINT_H__ */ praat-6.0.04/external/gsl/gsl_sf_fermi_dirac.h000066400000000000000000000065211261542461700213050ustar00rootroot00000000000000/* specfunc/gsl_sf_fermi_dirac.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_FERMI_DIRAC_H__ #define __GSL_SF_FERMI_DIRAC_H__ #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Complete Fermi-Dirac Integrals: * * F_j(x) := 1/Gamma[j+1] Integral[ t^j /(Exp[t-x] + 1), {t,0,Infinity}] * * * Incomplete Fermi-Dirac Integrals: * * F_j(x,b) := 1/Gamma[j+1] Integral[ t^j /(Exp[t-x] + 1), {t,b,Infinity}] */ /* Complete integral F_{-1}(x) = e^x / (1 + e^x) * * exceptions: GSL_EUNDRFLW */ int gsl_sf_fermi_dirac_m1_e(const double x, gsl_sf_result * result); double gsl_sf_fermi_dirac_m1(const double x); /* Complete integral F_0(x) = ln(1 + e^x) * * exceptions: GSL_EUNDRFLW */ int gsl_sf_fermi_dirac_0_e(const double x, gsl_sf_result * result); double gsl_sf_fermi_dirac_0(const double x); /* Complete integral F_1(x) * * exceptions: GSL_EUNDRFLW, GSL_EOVRFLW */ int gsl_sf_fermi_dirac_1_e(const double x, gsl_sf_result * result); double gsl_sf_fermi_dirac_1(const double x); /* Complete integral F_2(x) * * exceptions: GSL_EUNDRFLW, GSL_EOVRFLW */ int gsl_sf_fermi_dirac_2_e(const double x, gsl_sf_result * result); double gsl_sf_fermi_dirac_2(const double x); /* Complete integral F_j(x) * for integer j * * exceptions: GSL_EUNDRFLW, GSL_EOVRFLW */ int gsl_sf_fermi_dirac_int_e(const int j, const double x, gsl_sf_result * result); double gsl_sf_fermi_dirac_int(const int j, const double x); /* Complete integral F_{-1/2}(x) * * exceptions: GSL_EUNDRFLW, GSL_EOVRFLW */ int gsl_sf_fermi_dirac_mhalf_e(const double x, gsl_sf_result * result); double gsl_sf_fermi_dirac_mhalf(const double x); /* Complete integral F_{1/2}(x) * * exceptions: GSL_EUNDRFLW, GSL_EOVRFLW */ int gsl_sf_fermi_dirac_half_e(const double x, gsl_sf_result * result); double gsl_sf_fermi_dirac_half(const double x); /* Complete integral F_{3/2}(x) * * exceptions: GSL_EUNDRFLW, GSL_EOVRFLW */ int gsl_sf_fermi_dirac_3half_e(const double x, gsl_sf_result * result); double gsl_sf_fermi_dirac_3half(const double x); /* Incomplete integral F_0(x,b) = ln(1 + e^(b-x)) - (b-x) * * exceptions: GSL_EUNDRFLW, GSL_EDOM */ int gsl_sf_fermi_dirac_inc_0_e(const double x, const double b, gsl_sf_result * result); double gsl_sf_fermi_dirac_inc_0(const double x, const double b); __END_DECLS #endif /* __GSL_SF_FERMI_DIRAC_H__ */ praat-6.0.04/external/gsl/gsl_sf_gamma.h000066400000000000000000000171001261542461700201160ustar00rootroot00000000000000/* specfunc/gsl_sf_gamma.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_GAMMA_H__ #define __GSL_SF_GAMMA_H__ #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Log[Gamma(x)], x not a negative integer * Uses real Lanczos method. * Returns the real part of Log[Gamma[x]] when x < 0, * i.e. Log[|Gamma[x]|]. * * exceptions: GSL_EDOM, GSL_EROUND */ int gsl_sf_lngamma_e(double x, gsl_sf_result * result); double gsl_sf_lngamma(const double x); /* Log[Gamma(x)], x not a negative integer * Uses real Lanczos method. Determines * the sign of Gamma[x] as well as Log[|Gamma[x]|] for x < 0. * So Gamma[x] = sgn * Exp[result_lg]. * * exceptions: GSL_EDOM, GSL_EROUND */ int gsl_sf_lngamma_sgn_e(double x, gsl_sf_result * result_lg, double *sgn); /* Gamma(x), x not a negative integer * Uses real Lanczos method. * * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EROUND */ int gsl_sf_gamma_e(const double x, gsl_sf_result * result); double gsl_sf_gamma(const double x); /* Regulated Gamma Function, x > 0 * Gamma^*(x) = Gamma(x)/(Sqrt[2Pi] x^(x-1/2) exp(-x)) * = (1 + 1/(12x) + ...), x->Inf * A useful suggestion of Temme. * * exceptions: GSL_EDOM */ int gsl_sf_gammastar_e(const double x, gsl_sf_result * result); double gsl_sf_gammastar(const double x); /* 1/Gamma(x) * Uses real Lanczos method. * * exceptions: GSL_EUNDRFLW, GSL_EROUND */ int gsl_sf_gammainv_e(const double x, gsl_sf_result * result); double gsl_sf_gammainv(const double x); /* Log[Gamma(z)] for z complex, z not a negative integer * Uses complex Lanczos method. Note that the phase part (arg) * is not well-determined when |z| is very large, due * to inevitable roundoff in restricting to (-Pi,Pi]. * This will raise the GSL_ELOSS exception when it occurs. * The absolute value part (lnr), however, never suffers. * * Calculates: * lnr = log|Gamma(z)| * arg = arg(Gamma(z)) in (-Pi, Pi] * * exceptions: GSL_EDOM, GSL_ELOSS */ int gsl_sf_lngamma_complex_e(double zr, double zi, gsl_sf_result * lnr, gsl_sf_result * arg); /* x^n / n! * * x >= 0.0, n >= 0 * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_taylorcoeff_e(const int n, const double x, gsl_sf_result * result); double gsl_sf_taylorcoeff(const int n, const double x); /* n! * * exceptions: GSL_EDOM, GSL_OVRFLW */ int gsl_sf_fact_e(const unsigned int n, gsl_sf_result * result); double gsl_sf_fact(const unsigned int n); /* n!! = n(n-2)(n-4) ... * * exceptions: GSL_EDOM, GSL_OVRFLW */ int gsl_sf_doublefact_e(const unsigned int n, gsl_sf_result * result); double gsl_sf_doublefact(const unsigned int n); /* log(n!) * Faster than ln(Gamma(n+1)) for n < 170; defers for larger n. * * exceptions: none */ int gsl_sf_lnfact_e(const unsigned int n, gsl_sf_result * result); double gsl_sf_lnfact(const unsigned int n); /* log(n!!) * * exceptions: none */ int gsl_sf_lndoublefact_e(const unsigned int n, gsl_sf_result * result); double gsl_sf_lndoublefact(const unsigned int n); /* log(n choose m) * * exceptions: GSL_EDOM */ int gsl_sf_lnchoose_e(unsigned int n, unsigned int m, gsl_sf_result * result); double gsl_sf_lnchoose(unsigned int n, unsigned int m); /* n choose m * * exceptions: GSL_EDOM, GSL_EOVRFLW */ int gsl_sf_choose_e(unsigned int n, unsigned int m, gsl_sf_result * result); double gsl_sf_choose(unsigned int n, unsigned int m); /* Logarithm of Pochhammer (Apell) symbol * log( (a)_x ) * where (a)_x := Gamma[a + x]/Gamma[a] * * a > 0, a+x > 0 * * exceptions: GSL_EDOM */ int gsl_sf_lnpoch_e(const double a, const double x, gsl_sf_result * result); double gsl_sf_lnpoch(const double a, const double x); /* Logarithm of Pochhammer (Apell) symbol, with sign information. * result = log( |(a)_x| ) * sgn = sgn( (a)_x ) * where (a)_x := Gamma[a + x]/Gamma[a] * * a != neg integer, a+x != neg integer * * exceptions: GSL_EDOM */ int gsl_sf_lnpoch_sgn_e(const double a, const double x, gsl_sf_result * result, double * sgn); /* Pochhammer (Apell) symbol * (a)_x := Gamma[a + x]/Gamma[x] * * a != neg integer, a+x != neg integer * * exceptions: GSL_EDOM, GSL_EOVRFLW */ int gsl_sf_poch_e(const double a, const double x, gsl_sf_result * result); double gsl_sf_poch(const double a, const double x); /* Relative Pochhammer (Apell) symbol * ((a,x) - 1)/x * where (a,x) = (a)_x := Gamma[a + x]/Gamma[a] * * exceptions: GSL_EDOM */ int gsl_sf_pochrel_e(const double a, const double x, gsl_sf_result * result); double gsl_sf_pochrel(const double a, const double x); /* Normalized Incomplete Gamma Function * * Q(a,x) = 1/Gamma(a) Integral[ t^(a-1) e^(-t), {t,x,Infinity} ] * * a >= 0, x >= 0 * Q(a,0) := 1 * Q(0,x) := 0, x != 0 * * exceptions: GSL_EDOM */ int gsl_sf_gamma_inc_Q_e(const double a, const double x, gsl_sf_result * result); double gsl_sf_gamma_inc_Q(const double a, const double x); /* Complementary Normalized Incomplete Gamma Function * * P(a,x) = 1/Gamma(a) Integral[ t^(a-1) e^(-t), {t,0,x} ] * * a > 0, x >= 0 * * exceptions: GSL_EDOM */ int gsl_sf_gamma_inc_P_e(const double a, const double x, gsl_sf_result * result); double gsl_sf_gamma_inc_P(const double a, const double x); /* Non-normalized Incomplete Gamma Function * * Gamma(a,x) := Integral[ t^(a-1) e^(-t), {t,x,Infinity} ] * * x >= 0.0 * Gamma(a, 0) := Gamma(a) * * exceptions: GSL_EDOM */ int gsl_sf_gamma_inc_e(const double a, const double x, gsl_sf_result * result); double gsl_sf_gamma_inc(const double a, const double x); /* Logarithm of Beta Function * Log[B(a,b)] * * a > 0, b > 0 * exceptions: GSL_EDOM */ int gsl_sf_lnbeta_e(const double a, const double b, gsl_sf_result * result); double gsl_sf_lnbeta(const double a, const double b); int gsl_sf_lnbeta_sgn_e(const double x, const double y, gsl_sf_result * result, double * sgn); /* Beta Function * B(a,b) * * a > 0, b > 0 * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_beta_e(const double a, const double b, gsl_sf_result * result); double gsl_sf_beta(const double a, const double b); /* Normalized Incomplete Beta Function * B_x(a,b)/B(a,b) * * a > 0, b > 0, 0 <= x <= 1 * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_beta_inc_e(const double a, const double b, const double x, gsl_sf_result * result); double gsl_sf_beta_inc(const double a, const double b, const double x); /* The maximum x such that gamma(x) is not * considered an overflow. */ #define GSL_SF_GAMMA_XMAX 171.0 /* The maximum n such that gsl_sf_fact(n) does not give an overflow. */ #define GSL_SF_FACT_NMAX 170 /* The maximum n such that gsl_sf_doublefact(n) does not give an overflow. */ #define GSL_SF_DOUBLEFACT_NMAX 297 __END_DECLS #endif /* __GSL_SF_GAMMA_H__ */ praat-6.0.04/external/gsl/gsl_sf_gegenbauer.h000066400000000000000000000041461261542461700211460ustar00rootroot00000000000000/* specfunc/gsl_sf_gegenbauer.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_GEGENBAUER_H__ #define __GSL_SF_GEGENBAUER_H__ #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Evaluate Gegenbauer polynomials * using explicit representations. * * exceptions: none */ int gsl_sf_gegenpoly_1_e(double lambda, double x, gsl_sf_result * result); int gsl_sf_gegenpoly_2_e(double lambda, double x, gsl_sf_result * result); int gsl_sf_gegenpoly_3_e(double lambda, double x, gsl_sf_result * result); double gsl_sf_gegenpoly_1(double lambda, double x); double gsl_sf_gegenpoly_2(double lambda, double x); double gsl_sf_gegenpoly_3(double lambda, double x); /* Evaluate Gegenbauer polynomials. * * lambda > -1/2, n >= 0 * exceptions: GSL_EDOM */ int gsl_sf_gegenpoly_n_e(int n, double lambda, double x, gsl_sf_result * result); double gsl_sf_gegenpoly_n(int n, double lambda, double x); /* Calculate array of Gegenbauer polynomials * for n = (0, 1, 2, ... nmax) * * lambda > -1/2, nmax >= 0 * exceptions: GSL_EDOM */ int gsl_sf_gegenpoly_array(int nmax, double lambda, double x, double * result_array); __END_DECLS #endif /* __GSL_SF_GEGENBAUER_H__ */ praat-6.0.04/external/gsl/gsl_sf_hyperg.h000066400000000000000000000106411261542461700203350ustar00rootroot00000000000000/* specfunc/gsl_sf_hyperg.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_HYPERG_H__ #define __GSL_SF_HYPERG_H__ #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Hypergeometric function related to Bessel functions * 0F1[c,x] = * Gamma[c] x^(1/2(1-c)) I_{c-1}(2 Sqrt[x]) * Gamma[c] (-x)^(1/2(1-c)) J_{c-1}(2 Sqrt[-x]) * * exceptions: GSL_EOVRFLW, GSL_EUNDRFLW */ int gsl_sf_hyperg_0F1_e(double c, double x, gsl_sf_result * result); double gsl_sf_hyperg_0F1(const double c, const double x); /* Confluent hypergeometric function for integer parameters. * 1F1[m,n,x] = M(m,n,x) * * exceptions: */ int gsl_sf_hyperg_1F1_int_e(const int m, const int n, const double x, gsl_sf_result * result); double gsl_sf_hyperg_1F1_int(const int m, const int n, double x); /* Confluent hypergeometric function. * 1F1[a,b,x] = M(a,b,x) * * exceptions: */ int gsl_sf_hyperg_1F1_e(const double a, const double b, const double x, gsl_sf_result * result); double gsl_sf_hyperg_1F1(double a, double b, double x); /* Confluent hypergeometric function for integer parameters. * U(m,n,x) * * exceptions: */ int gsl_sf_hyperg_U_int_e(const int m, const int n, const double x, gsl_sf_result * result); double gsl_sf_hyperg_U_int(const int m, const int n, const double x); /* Confluent hypergeometric function for integer parameters. * U(m,n,x) * * exceptions: */ int gsl_sf_hyperg_U_int_e10_e(const int m, const int n, const double x, gsl_sf_result_e10 * result); /* Confluent hypergeometric function. * U(a,b,x) * * exceptions: */ int gsl_sf_hyperg_U_e(const double a, const double b, const double x, gsl_sf_result * result); double gsl_sf_hyperg_U(const double a, const double b, const double x); /* Confluent hypergeometric function. * U(a,b,x) * * exceptions: */ int gsl_sf_hyperg_U_e10_e(const double a, const double b, const double x, gsl_sf_result_e10 * result); /* Gauss hypergeometric function 2F1[a,b,c,x] * |x| < 1 * * exceptions: */ int gsl_sf_hyperg_2F1_e(double a, double b, const double c, const double x, gsl_sf_result * result); double gsl_sf_hyperg_2F1(double a, double b, double c, double x); /* Gauss hypergeometric function * 2F1[aR + I aI, aR - I aI, c, x] * |x| < 1 * * exceptions: */ int gsl_sf_hyperg_2F1_conj_e(const double aR, const double aI, const double c, const double x, gsl_sf_result * result); double gsl_sf_hyperg_2F1_conj(double aR, double aI, double c, double x); /* Renormalized Gauss hypergeometric function * 2F1[a,b,c,x] / Gamma[c] * |x| < 1 * * exceptions: */ int gsl_sf_hyperg_2F1_renorm_e(const double a, const double b, const double c, const double x, gsl_sf_result * result); double gsl_sf_hyperg_2F1_renorm(double a, double b, double c, double x); /* Renormalized Gauss hypergeometric function * 2F1[aR + I aI, aR - I aI, c, x] / Gamma[c] * |x| < 1 * * exceptions: */ int gsl_sf_hyperg_2F1_conj_renorm_e(const double aR, const double aI, const double c, const double x, gsl_sf_result * result); double gsl_sf_hyperg_2F1_conj_renorm(double aR, double aI, double c, double x); /* Mysterious hypergeometric function. The series representation * is a divergent hypergeometric series. However, for x < 0 we * have 2F0(a,b,x) = (-1/x)^a U(a,1+a-b,-1/x) * * exceptions: GSL_EDOM */ int gsl_sf_hyperg_2F0_e(const double a, const double b, const double x, gsl_sf_result * result); double gsl_sf_hyperg_2F0(const double a, const double b, const double x); __END_DECLS #endif /* __GSL_SF_HYPERG_H__ */ praat-6.0.04/external/gsl/gsl_sf_laguerre.h000066400000000000000000000037141261542461700206500ustar00rootroot00000000000000/* specfunc/gsl_sf_laguerre.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_LAGUERRE_H__ #define __GSL_SF_LAGUERRE_H__ #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* L^a_n(x) = (a+1)_n / n! 1F1(-n,a+1,x) */ /* Evaluate generalized Laguerre polynomials * using explicit representations. * * exceptions: none */ int gsl_sf_laguerre_1_e(const double a, const double x, gsl_sf_result * result); int gsl_sf_laguerre_2_e(const double a, const double x, gsl_sf_result * result); int gsl_sf_laguerre_3_e(const double a, const double x, gsl_sf_result * result); double gsl_sf_laguerre_1(double a, double x); double gsl_sf_laguerre_2(double a, double x); double gsl_sf_laguerre_3(double a, double x); /* Evaluate generalized Laguerre polynomials. * * a > -1.0 * n >= 0 * exceptions: GSL_EDOM */ int gsl_sf_laguerre_n_e(const int n, const double a, const double x, gsl_sf_result * result); double gsl_sf_laguerre_n(int n, double a, double x); __END_DECLS #endif /* __GSL_SF_LAGUERRE_H__ */ praat-6.0.04/external/gsl/gsl_sf_lambert.h000066400000000000000000000034211261542461700204630ustar00rootroot00000000000000/* specfunc/gsl_sf_lambert.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_LAMBERT_H__ #define __GSL_SF_LAMBERT_H__ #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Lambert's Function W_0(x) * * W_0(x) is the principal branch of the * implicit function defined by W e^W = x. * * -1/E < x < \infty * * exceptions: GSL_EMAXITER; */ int gsl_sf_lambert_W0_e(double x, gsl_sf_result * result); double gsl_sf_lambert_W0(double x); /* Lambert's Function W_{-1}(x) * * W_{-1}(x) is the second real branch of the * implicit function defined by W e^W = x. * It agrees with W_0(x) when x >= 0. * * -1/E < x < \infty * * exceptions: GSL_MAXITER; */ int gsl_sf_lambert_Wm1_e(double x, gsl_sf_result * result); double gsl_sf_lambert_Wm1(double x); __END_DECLS #endif /* __GSL_SF_LAMBERT_H__ */ praat-6.0.04/external/gsl/gsl_sf_legendre.h000066400000000000000000000210151261542461700206210ustar00rootroot00000000000000/* specfunc/gsl_sf_legendre.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_LEGENDRE_H__ #define __GSL_SF_LEGENDRE_H__ #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* P_l(x) l >= 0; |x| <= 1 * * exceptions: GSL_EDOM */ int gsl_sf_legendre_Pl_e(const int l, const double x, gsl_sf_result * result); double gsl_sf_legendre_Pl(const int l, const double x); /* P_l(x) for l=0,...,lmax; |x| <= 1 * * exceptions: GSL_EDOM */ int gsl_sf_legendre_Pl_array( const int lmax, const double x, double * result_array ); /* P_l(x) and P_l'(x) for l=0,...,lmax; |x| <= 1 * * exceptions: GSL_EDOM */ int gsl_sf_legendre_Pl_deriv_array( const int lmax, const double x, double * result_array, double * result_deriv_array ); /* P_l(x), l=1,2,3 * * exceptions: none */ int gsl_sf_legendre_P1_e(double x, gsl_sf_result * result); int gsl_sf_legendre_P2_e(double x, gsl_sf_result * result); int gsl_sf_legendre_P3_e(double x, gsl_sf_result * result); double gsl_sf_legendre_P1(const double x); double gsl_sf_legendre_P2(const double x); double gsl_sf_legendre_P3(const double x); /* Q_0(x), x > -1, x != 1 * * exceptions: GSL_EDOM */ int gsl_sf_legendre_Q0_e(const double x, gsl_sf_result * result); double gsl_sf_legendre_Q0(const double x); /* Q_1(x), x > -1, x != 1 * * exceptions: GSL_EDOM */ int gsl_sf_legendre_Q1_e(const double x, gsl_sf_result * result); double gsl_sf_legendre_Q1(const double x); /* Q_l(x), x > -1, x != 1, l >= 0 * * exceptions: GSL_EDOM */ int gsl_sf_legendre_Ql_e(const int l, const double x, gsl_sf_result * result); double gsl_sf_legendre_Ql(const int l, const double x); /* P_l^m(x) m >= 0; l >= m; |x| <= 1.0 * * Note that this function grows combinatorially with l. * Therefore we can easily generate an overflow for l larger * than about 150. * * There is no trouble for small m, but when m and l are both large, * then there will be trouble. Rather than allow overflows, these * functions refuse to calculate when they can sense that l and m are * too big. * * If you really want to calculate a spherical harmonic, then DO NOT * use this. Instead use legendre_sphPlm() below, which uses a similar * recursion, but with the normalized functions. * * exceptions: GSL_EDOM, GSL_EOVRFLW */ int gsl_sf_legendre_Plm_e(const int l, const int m, const double x, gsl_sf_result * result); double gsl_sf_legendre_Plm(const int l, const int m, const double x); /* P_l^m(x) m >= 0; l >= m; |x| <= 1.0 * l=|m|,...,lmax * * exceptions: GSL_EDOM, GSL_EOVRFLW */ int gsl_sf_legendre_Plm_array( const int lmax, const int m, const double x, double * result_array ); /* P_l^m(x) and d(P_l^m(x))/dx; m >= 0; lmax >= m; |x| <= 1.0 * l=|m|,...,lmax * * exceptions: GSL_EDOM, GSL_EOVRFLW */ int gsl_sf_legendre_Plm_deriv_array( const int lmax, const int m, const double x, double * result_array, double * result_deriv_array ); /* P_l^m(x), normalized properly for use in spherical harmonics * m >= 0; l >= m; |x| <= 1.0 * * There is no overflow problem, as there is for the * standard normalization of P_l^m(x). * * Specifically, it returns: * * sqrt((2l+1)/(4pi)) sqrt((l-m)!/(l+m)!) P_l^m(x) * * exceptions: GSL_EDOM */ int gsl_sf_legendre_sphPlm_e(const int l, int m, const double x, gsl_sf_result * result); double gsl_sf_legendre_sphPlm(const int l, const int m, const double x); /* sphPlm(l,m,x) values * m >= 0; l >= m; |x| <= 1.0 * l=|m|,...,lmax * * exceptions: GSL_EDOM */ int gsl_sf_legendre_sphPlm_array( const int lmax, int m, const double x, double * result_array ); /* sphPlm(l,m,x) and d(sphPlm(l,m,x))/dx values * m >= 0; l >= m; |x| <= 1.0 * l=|m|,...,lmax * * exceptions: GSL_EDOM */ int gsl_sf_legendre_sphPlm_deriv_array( const int lmax, const int m, const double x, double * result_array, double * result_deriv_array ); /* size of result_array[] needed for the array versions of Plm * (lmax - m + 1) */ int gsl_sf_legendre_array_size(const int lmax, const int m); /* Irregular Spherical Conical Function * P^{1/2}_{-1/2 + I lambda}(x) * * x > -1.0 * exceptions: GSL_EDOM */ int gsl_sf_conicalP_half_e(const double lambda, const double x, gsl_sf_result * result); double gsl_sf_conicalP_half(const double lambda, const double x); /* Regular Spherical Conical Function * P^{-1/2}_{-1/2 + I lambda}(x) * * x > -1.0 * exceptions: GSL_EDOM */ int gsl_sf_conicalP_mhalf_e(const double lambda, const double x, gsl_sf_result * result); double gsl_sf_conicalP_mhalf(const double lambda, const double x); /* Conical Function * P^{0}_{-1/2 + I lambda}(x) * * x > -1.0 * exceptions: GSL_EDOM */ int gsl_sf_conicalP_0_e(const double lambda, const double x, gsl_sf_result * result); double gsl_sf_conicalP_0(const double lambda, const double x); /* Conical Function * P^{1}_{-1/2 + I lambda}(x) * * x > -1.0 * exceptions: GSL_EDOM */ int gsl_sf_conicalP_1_e(const double lambda, const double x, gsl_sf_result * result); double gsl_sf_conicalP_1(const double lambda, const double x); /* Regular Spherical Conical Function * P^{-1/2-l}_{-1/2 + I lambda}(x) * * x > -1.0, l >= -1 * exceptions: GSL_EDOM */ int gsl_sf_conicalP_sph_reg_e(const int l, const double lambda, const double x, gsl_sf_result * result); double gsl_sf_conicalP_sph_reg(const int l, const double lambda, const double x); /* Regular Cylindrical Conical Function * P^{-m}_{-1/2 + I lambda}(x) * * x > -1.0, m >= -1 * exceptions: GSL_EDOM */ int gsl_sf_conicalP_cyl_reg_e(const int m, const double lambda, const double x, gsl_sf_result * result); double gsl_sf_conicalP_cyl_reg(const int m, const double lambda, const double x); /* The following spherical functions are specializations * of Legendre functions which give the regular eigenfunctions * of the Laplacian on a 3-dimensional hyperbolic space. * Of particular interest is the flat limit, which is * Flat-Lim := {lambda->Inf, eta->0, lambda*eta fixed}. */ /* Zeroth radial eigenfunction of the Laplacian on the * 3-dimensional hyperbolic space. * * legendre_H3d_0(lambda,eta) := sin(lambda*eta)/(lambda*sinh(eta)) * * Normalization: * Flat-Lim legendre_H3d_0(lambda,eta) = j_0(lambda*eta) * * eta >= 0.0 * exceptions: GSL_EDOM */ int gsl_sf_legendre_H3d_0_e(const double lambda, const double eta, gsl_sf_result * result); double gsl_sf_legendre_H3d_0(const double lambda, const double eta); /* First radial eigenfunction of the Laplacian on the * 3-dimensional hyperbolic space. * * legendre_H3d_1(lambda,eta) := * 1/sqrt(lambda^2 + 1) sin(lam eta)/(lam sinh(eta)) * (coth(eta) - lambda cot(lambda*eta)) * * Normalization: * Flat-Lim legendre_H3d_1(lambda,eta) = j_1(lambda*eta) * * eta >= 0.0 * exceptions: GSL_EDOM */ int gsl_sf_legendre_H3d_1_e(const double lambda, const double eta, gsl_sf_result * result); double gsl_sf_legendre_H3d_1(const double lambda, const double eta); /* l'th radial eigenfunction of the Laplacian on the * 3-dimensional hyperbolic space. * * Normalization: * Flat-Lim legendre_H3d_l(l,lambda,eta) = j_l(lambda*eta) * * eta >= 0.0, l >= 0 * exceptions: GSL_EDOM */ int gsl_sf_legendre_H3d_e(const int l, const double lambda, const double eta, gsl_sf_result * result); double gsl_sf_legendre_H3d(const int l, const double lambda, const double eta); /* Array of H3d(ell), 0 <= ell <= lmax */ int gsl_sf_legendre_H3d_array(const int lmax, const double lambda, const double eta, double * result_array); #ifdef HAVE_INLINE extern inline int gsl_sf_legendre_array_size(const int lmax, const int m) { return lmax-m+1; } #endif /* HAVE_INLINE */ __END_DECLS #endif /* __GSL_SF_LEGENDRE_H__ */ praat-6.0.04/external/gsl/gsl_sf_log.h000066400000000000000000000040121261542461700176130ustar00rootroot00000000000000/* specfunc/gsl_sf_log.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_LOG_H__ #define __GSL_SF_LOG_H__ #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Provide a logarithm function with GSL semantics. * * exceptions: GSL_EDOM */ int gsl_sf_log_e(const double x, gsl_sf_result * result); double gsl_sf_log(const double x); /* Log(|x|) * * exceptions: GSL_EDOM */ int gsl_sf_log_abs_e(const double x, gsl_sf_result * result); double gsl_sf_log_abs(const double x); /* Complex Logarithm * exp(lnr + I theta) = zr + I zi * Returns argument in [-pi,pi]. * * exceptions: GSL_EDOM */ int gsl_sf_complex_log_e(const double zr, const double zi, gsl_sf_result * lnr, gsl_sf_result * theta); /* Log(1 + x) * * exceptions: GSL_EDOM */ int gsl_sf_log_1plusx_e(const double x, gsl_sf_result * result); double gsl_sf_log_1plusx(const double x); /* Log(1 + x) - x * * exceptions: GSL_EDOM */ int gsl_sf_log_1plusx_mx_e(const double x, gsl_sf_result * result); double gsl_sf_log_1plusx_mx(const double x); __END_DECLS #endif /* __GSL_SF_LOG_H__ */ praat-6.0.04/external/gsl/gsl_sf_mathieu.h000066400000000000000000000075411261542461700205000ustar00rootroot00000000000000/* specfunc/gsl_sf_mathieu.h * * Copyright (C) 2002 Lowell Johnson * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Author: L. Johnson */ #ifndef __GSL_SF_MATHIEU_H__ #define __GSL_SF_MATHIEU_H__ #include "gsl_sf_result.h" #include "gsl_eigen.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS #define GSL_SF_MATHIEU_COEFF 100 typedef struct { size_t size; size_t even_order; size_t odd_order; int extra_values; double qa; /* allow for caching of results: not implemented yet */ double qb; /* allow for caching of results: not implemented yet */ double *aa; double *bb; double *dd; double *ee; double *tt; double *e2; double *zz; gsl_vector *eval; gsl_matrix *evec; gsl_eigen_symmv_workspace *wmat; } gsl_sf_mathieu_workspace; /* Compute an array of characteristic (eigen) values from the recurrence matrices for the Mathieu equations. */ int gsl_sf_mathieu_a_array(int order_min, int order_max, double qq, gsl_sf_mathieu_workspace *work, double result_array[]); int gsl_sf_mathieu_b_array(int order_min, int order_max, double qq, gsl_sf_mathieu_workspace *work, double result_array[]); /* Compute the characteristic value for a Mathieu function of order n and type ntype. */ int gsl_sf_mathieu_a(int order, double qq, gsl_sf_result *result); int gsl_sf_mathieu_b(int order, double qq, gsl_sf_result *result); /* Compute the Fourier coefficients for a Mathieu function. */ int gsl_sf_mathieu_a_coeff(int order, double qq, double aa, double coeff[]); int gsl_sf_mathieu_b_coeff(int order, double qq, double aa, double coeff[]); /* Allocate computational storage space for eigenvalue solution. */ gsl_sf_mathieu_workspace *gsl_sf_mathieu_alloc(const size_t nn, const double qq); void gsl_sf_mathieu_free(gsl_sf_mathieu_workspace *workspace); /* Compute an angular Mathieu function. */ int gsl_sf_mathieu_ce(int order, double qq, double zz, gsl_sf_result *result); int gsl_sf_mathieu_se(int order, double qq, double zz, gsl_sf_result *result); int gsl_sf_mathieu_ce_array(int nmin, int nmax, double qq, double zz, gsl_sf_mathieu_workspace *work, double result_array[]); int gsl_sf_mathieu_se_array(int nmin, int nmax, double qq, double zz, gsl_sf_mathieu_workspace *work, double result_array[]); /* Compute a radial Mathieu function. */ int gsl_sf_mathieu_Mc(int kind, int order, double qq, double zz, gsl_sf_result *result); int gsl_sf_mathieu_Ms(int kind, int order, double qq, double zz, gsl_sf_result *result); int gsl_sf_mathieu_Mc_array(int kind, int nmin, int nmax, double qq, double zz, gsl_sf_mathieu_workspace *work, double result_array[]); int gsl_sf_mathieu_Ms_array(int kind, int nmin, int nmax, double qq, double zz, gsl_sf_mathieu_workspace *work, double result_array[]); __END_DECLS #endif /* !__GSL_SF_MATHIEU_H__ */ praat-6.0.04/external/gsl/gsl_sf_pow_int.h000066400000000000000000000025521261542461700205200ustar00rootroot00000000000000/* specfunc/gsl_sf_pow_int.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_POW_INT_H__ #define __GSL_SF_POW_INT_H__ #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Calculate x^n. * Does not check for overflow/underflow. */ int gsl_sf_pow_int_e(double x, int n, gsl_sf_result * result); double gsl_sf_pow_int(const double x, const int n); __END_DECLS #endif /* __GSL_SF_POW_INT_H__ */ praat-6.0.04/external/gsl/gsl_sf_psi.h000066400000000000000000000051671261542461700176410ustar00rootroot00000000000000/* specfunc/gsl_sf_psi.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_PSI_H__ #define __GSL_SF_PSI_H__ #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Poly-Gamma Functions * * psi(m,x) := (d/dx)^m psi(0,x) = (d/dx)^{m+1} log(gamma(x)) */ /* Di-Gamma Function psi(n) = psi(0,n) * * n > 0 * exceptions: GSL_EDOM */ int gsl_sf_psi_int_e(const int n, gsl_sf_result * result); double gsl_sf_psi_int(const int n); /* Di-Gamma Function psi(x) = psi(0, x) * * x != 0.0, -1.0, -2.0, ... * exceptions: GSL_EDOM, GSL_ELOSS */ int gsl_sf_psi_e(const double x, gsl_sf_result * result); double gsl_sf_psi(const double x); /* Di-Gamma Function Re[psi(1 + I y)] * * exceptions: none */ int gsl_sf_psi_1piy_e(const double y, gsl_sf_result * result); double gsl_sf_psi_1piy(const double y); /* Di-Gamma Function psi(z) for general complex argument z = x + iy * * exceptions: GSL_EDOM */ int gsl_sf_complex_psi_e( const double x, const double y, gsl_sf_result * result_re, gsl_sf_result * result_im ); /* Tri-Gamma Function psi^(1)(n) * * n > 0 * exceptions: GSL_EDOM */ int gsl_sf_psi_1_int_e(const int n, gsl_sf_result * result); double gsl_sf_psi_1_int(const int n); /* Tri-Gamma Function psi^(1)(x) * * x != 0.0, -1.0, -2.0, ... * exceptions: GSL_EDOM, GSL_ELOSS */ int gsl_sf_psi_1_e(const double x, gsl_sf_result * result); double gsl_sf_psi_1(const double x); /* Poly-Gamma Function psi^(n)(x) * * n >= 0, x > 0.0 * exceptions: GSL_EDOM */ int gsl_sf_psi_n_e(const int n, const double x, gsl_sf_result * result); double gsl_sf_psi_n(const int n, const double x); __END_DECLS #endif /* __GSL_SF_PSI_H__ */ praat-6.0.04/external/gsl/gsl_sf_result.h000066400000000000000000000030511261542461700203520ustar00rootroot00000000000000/* specfunc/gsl_sf_result.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_RESULT_H__ #define __GSL_SF_RESULT_H__ #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS struct gsl_sf_result_struct { double val; double err; }; typedef struct gsl_sf_result_struct gsl_sf_result; #define GSL_SF_RESULT_SET(r,v,e) do { (r)->val=(v); (r)->err=(e); } while(0) struct gsl_sf_result_e10_struct { double val; double err; int e10; }; typedef struct gsl_sf_result_e10_struct gsl_sf_result_e10; int gsl_sf_result_smash_e(const gsl_sf_result_e10 * re, gsl_sf_result * r); __END_DECLS #endif /* __GSL_SF_RESULT_H__ */ praat-6.0.04/external/gsl/gsl_sf_synchrotron.h000066400000000000000000000032671261542461700214350ustar00rootroot00000000000000/* specfunc/gsl_sf_synchrotron.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_SYNCHROTRON_H__ #define __GSL_SF_SYNCHROTRON_H__ #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* First synchrotron function: * synchrotron_1(x) = x Integral[ K_{5/3}(t), {t, x, Infinity}] * * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_synchrotron_1_e(const double x, gsl_sf_result * result); double gsl_sf_synchrotron_1(const double x); /* Second synchroton function: * synchrotron_2(x) = x * K_{2/3}(x) * * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_synchrotron_2_e(const double x, gsl_sf_result * result); double gsl_sf_synchrotron_2(const double x); __END_DECLS #endif /* __GSL_SF_SYNCHROTRON_H__ */ praat-6.0.04/external/gsl/gsl_sf_transport.h000066400000000000000000000036661261542461700211040ustar00rootroot00000000000000/* specfunc/gsl_sf_transport.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_TRANSPORT_H__ #define __GSL_SF_TRANSPORT_H__ #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Transport function: * J(n,x) := Integral[ t^n e^t /(e^t - 1)^2, {t,0,x}] */ /* J(2,x) * * exceptions: GSL_EDOM */ int gsl_sf_transport_2_e(const double x, gsl_sf_result * result); double gsl_sf_transport_2(const double x); /* J(3,x) * * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_transport_3_e(const double x, gsl_sf_result * result); double gsl_sf_transport_3(const double x); /* J(4,x) * * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_transport_4_e(const double x, gsl_sf_result * result); double gsl_sf_transport_4(const double x); /* J(5,x) * * exceptions: GSL_EDOM, GSL_EUNDRFLW */ int gsl_sf_transport_5_e(const double x, gsl_sf_result * result); double gsl_sf_transport_5(const double x); __END_DECLS #endif /* __GSL_SF_TRANSPORT_H__ */ praat-6.0.04/external/gsl/gsl_sf_trig.h000066400000000000000000000075611261542461700200130ustar00rootroot00000000000000/* specfunc/gsl_sf_trig.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_TRIG_H__ #define __GSL_SF_TRIG_H__ #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Sin(x) with GSL semantics. This is actually important * because we want to control the error estimate, and trying * to guess the error for the standard library implementation * every time it is used would be a little goofy. */ int gsl_sf_sin_e(double x, gsl_sf_result * result); double gsl_sf_sin(const double x); /* Cos(x) with GSL semantics. */ int gsl_sf_cos_e(double x, gsl_sf_result * result); double gsl_sf_cos(const double x); /* Hypot(x,y) with GSL semantics. */ int gsl_sf_hypot_e(const double x, const double y, gsl_sf_result * result); double gsl_sf_hypot(const double x, const double y); /* Sin(z) for complex z * * exceptions: GSL_EOVRFLW */ int gsl_sf_complex_sin_e(const double zr, const double zi, gsl_sf_result * szr, gsl_sf_result * szi); /* Cos(z) for complex z * * exceptions: GSL_EOVRFLW */ int gsl_sf_complex_cos_e(const double zr, const double zi, gsl_sf_result * czr, gsl_sf_result * czi); /* Log(Sin(z)) for complex z * * exceptions: GSL_EDOM, GSL_ELOSS */ int gsl_sf_complex_logsin_e(const double zr, const double zi, gsl_sf_result * lszr, gsl_sf_result * lszi); /* Sinc(x) = sin(pi x) / (pi x) * * exceptions: none */ int gsl_sf_sinc_e(double x, gsl_sf_result * result); double gsl_sf_sinc(const double x); /* Log(Sinh(x)), x > 0 * * exceptions: GSL_EDOM */ int gsl_sf_lnsinh_e(const double x, gsl_sf_result * result); double gsl_sf_lnsinh(const double x); /* Log(Cosh(x)) * * exceptions: none */ int gsl_sf_lncosh_e(const double x, gsl_sf_result * result); double gsl_sf_lncosh(const double x); /* Convert polar to rectlinear coordinates. * * exceptions: GSL_ELOSS */ int gsl_sf_polar_to_rect(const double r, const double theta, gsl_sf_result * x, gsl_sf_result * y); /* Convert rectilinear to polar coordinates. * return argument in range [-pi, pi] * * exceptions: GSL_EDOM */ int gsl_sf_rect_to_polar(const double x, const double y, gsl_sf_result * r, gsl_sf_result * theta); /* Sin(x) for quantity with an associated error. */ int gsl_sf_sin_err_e(const double x, const double dx, gsl_sf_result * result); /* Cos(x) for quantity with an associated error. */ int gsl_sf_cos_err_e(const double x, const double dx, gsl_sf_result * result); /* Force an angle to lie in the range (-pi,pi]. * * exceptions: GSL_ELOSS */ int gsl_sf_angle_restrict_symm_e(double * theta); double gsl_sf_angle_restrict_symm(const double theta); /* Force an angle to lie in the range [0, 2pi) * * exceptions: GSL_ELOSS */ int gsl_sf_angle_restrict_pos_e(double * theta); double gsl_sf_angle_restrict_pos(const double theta); int gsl_sf_angle_restrict_symm_err_e(const double theta, gsl_sf_result * result); int gsl_sf_angle_restrict_pos_err_e(const double theta, gsl_sf_result * result); __END_DECLS #endif /* __GSL_SF_TRIG_H__ */ praat-6.0.04/external/gsl/gsl_sf_zeta.h000066400000000000000000000055121261542461700200030ustar00rootroot00000000000000/* specfunc/gsl_sf_zeta.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SF_ZETA_H__ #define __GSL_SF_ZETA_H__ #include "gsl_sf_result.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Riemann Zeta Function * zeta(n) = Sum[ k^(-n), {k,1,Infinity} ] * * n=integer, n != 1 * exceptions: GSL_EDOM, GSL_EOVRFLW */ int gsl_sf_zeta_int_e(const int n, gsl_sf_result * result); double gsl_sf_zeta_int(const int n); /* Riemann Zeta Function * zeta(x) = Sum[ k^(-s), {k,1,Infinity} ], s != 1.0 * * s != 1.0 * exceptions: GSL_EDOM, GSL_EOVRFLW */ int gsl_sf_zeta_e(const double s, gsl_sf_result * result); double gsl_sf_zeta(const double s); /* Riemann Zeta Function minus 1 * useful for evaluating the fractional part * of Riemann zeta for large argument * * s != 1.0 * exceptions: GSL_EDOM, GSL_EOVRFLW */ int gsl_sf_zetam1_e(const double s, gsl_sf_result * result); double gsl_sf_zetam1(const double s); /* Riemann Zeta Function minus 1 for integer arg * useful for evaluating the fractional part * of Riemann zeta for large argument * * s != 1.0 * exceptions: GSL_EDOM, GSL_EOVRFLW */ int gsl_sf_zetam1_int_e(const int s, gsl_sf_result * result); double gsl_sf_zetam1_int(const int s); /* Hurwitz Zeta Function * zeta(s,q) = Sum[ (k+q)^(-s), {k,0,Infinity} ] * * s > 1.0, q > 0.0 * exceptions: GSL_EDOM, GSL_EUNDRFLW, GSL_EOVRFLW */ int gsl_sf_hzeta_e(const double s, const double q, gsl_sf_result * result); double gsl_sf_hzeta(const double s, const double q); /* Eta Function * eta(n) = (1-2^(1-n)) zeta(n) * * exceptions: GSL_EUNDRFLW, GSL_EOVRFLW */ int gsl_sf_eta_int_e(int n, gsl_sf_result * result); double gsl_sf_eta_int(const int n); /* Eta Function * eta(s) = (1-2^(1-s)) zeta(s) * * exceptions: GSL_EUNDRFLW, GSL_EOVRFLW */ int gsl_sf_eta_e(const double s, gsl_sf_result * result); double gsl_sf_eta(const double s); __END_DECLS #endif /* __GSL_SF_ZETA_H__ */ praat-6.0.04/external/gsl/gsl_siman.h000066400000000000000000000057061261542461700174640ustar00rootroot00000000000000/* siman/gsl_siman.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Mark Galassi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_SIMAN_H__ #define __GSL_SIMAN_H__ #include #include "gsl_rng.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* types for the function pointers passed to gsl_siman_solve */ typedef double (*gsl_siman_Efunc_t) (void *xp); typedef void (*gsl_siman_step_t) (const gsl_rng *r, void *xp, double step_size); typedef double (*gsl_siman_metric_t) (void *xp, void *yp); typedef void (*gsl_siman_print_t) (void *xp); typedef void (*gsl_siman_copy_t) (void *source, void *dest); typedef void * (*gsl_siman_copy_construct_t) (void *xp); typedef void (*gsl_siman_destroy_t) (void *xp); /* this structure contains all the information needed to structure the search, beyond the energy function, the step function and the initial guess. */ typedef struct { int n_tries; /* how many points to try for each step */ int iters_fixed_T; /* how many iterations at each temperature? */ double step_size; /* max step size in the random walk */ /* the following parameters are for the Boltzmann distribution */ double k, t_initial, mu_t, t_min; } gsl_siman_params_t; /* prototype for the workhorse function */ void gsl_siman_solve(const gsl_rng * r, void *x0_p, gsl_siman_Efunc_t Ef, gsl_siman_step_t take_step, gsl_siman_metric_t distance, gsl_siman_print_t print_position, gsl_siman_copy_t copyfunc, gsl_siman_copy_construct_t copy_constructor, gsl_siman_destroy_t destructor, size_t element_size, gsl_siman_params_t params); void gsl_siman_solve_many (const gsl_rng * r, void *x0_p, gsl_siman_Efunc_t Ef, gsl_siman_step_t take_step, gsl_siman_metric_t distance, gsl_siman_print_t print_position, size_t element_size, gsl_siman_params_t params); __END_DECLS #endif /* __GSL_SIMAN_H__ */ praat-6.0.04/external/gsl/gsl_siman__siman.c000066400000000000000000000177201261542461700210040ustar00rootroot00000000000000/* siman/siman.c * * Copyright (C) 2007 Brian Gough * Copyright (C) 1996, 1997, 1998, 1999, 2000 Mark Galassi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include #include #include #include "gsl_machine.h" #include "gsl_rng.h" #include "gsl_siman.h" static inline double boltzmann(double E, double new_E, double T, gsl_siman_params_t *params) { double x = -(new_E - E) / (params->k * T); /* avoid underflow errors for large uphill steps */ return (x < GSL_LOG_DBL_MIN) ? 0.0 : exp(x); } static inline void copy_state(void *src, void *dst, size_t size, gsl_siman_copy_t copyfunc) { if (copyfunc) { copyfunc(src, dst); } else { memcpy(dst, src, size); } } /* implementation of a basic simulated annealing algorithm */ void gsl_siman_solve (const gsl_rng * r, void *x0_p, gsl_siman_Efunc_t Ef, gsl_siman_step_t take_step, gsl_siman_metric_t distance, gsl_siman_print_t print_position, gsl_siman_copy_t copyfunc, gsl_siman_copy_construct_t copy_constructor, gsl_siman_destroy_t destructor, size_t element_size, gsl_siman_params_t params) { void *x, *new_x, *best_x; double E, new_E, best_E; int i; double T, T_factor; int n_evals = 1, n_iter = 0, n_accepts, n_rejects, n_eless; /* this function requires that either the dynamic functions (copy, copy_constructor and destrcutor) are passed, or that an element size is given */ assert((copyfunc != NULL && copy_constructor != NULL && destructor != NULL) || (element_size != 0)); distance = 0 ; /* This parameter is not currently used */ E = Ef(x0_p); if (copyfunc) { x = copy_constructor(x0_p); new_x = copy_constructor(x0_p); best_x = copy_constructor(x0_p); } else { x = (void *) malloc (element_size); memcpy (x, x0_p, element_size); new_x = (void *) malloc (element_size); best_x = (void *) malloc (element_size); memcpy (best_x, x0_p, element_size); } best_E = E; T = params.t_initial; T_factor = 1.0 / params.mu_t; if (print_position) { printf ("#-iter #-evals temperature position energy\n"); } while (1) { n_accepts = 0; n_rejects = 0; n_eless = 0; for (i = 0; i < params.iters_fixed_T; ++i) { copy_state(x, new_x, element_size, copyfunc); take_step (r, new_x, params.step_size); new_E = Ef (new_x); if(new_E <= best_E){ if (copyfunc) { copyfunc(new_x,best_x); } else { memcpy (best_x, new_x, element_size); } best_E=new_E; } ++n_evals; /* keep track of Ef() evaluations */ /* now take the crucial step: see if the new point is accepted or not, as determined by the boltzmann probability */ if (new_E < E) { if (new_E < best_E) { copy_state(new_x, best_x, element_size, copyfunc); best_E = new_E; } /* yay! take a step */ copy_state(new_x, x, element_size, copyfunc); E = new_E; ++n_eless; } else if (gsl_rng_uniform(r) < boltzmann(E, new_E, T, ¶ms)) { /* yay! take a step */ copy_state(new_x, x, element_size, copyfunc); E = new_E; ++n_accepts; } else { ++n_rejects; } } if (print_position) { /* see if we need to print stuff as we go */ /* printf("%5d %12g %5d %3d %3d %3d", n_iter, T, n_evals, */ /* 100*n_eless/n_steps, 100*n_accepts/n_steps, */ /* 100*n_rejects/n_steps); */ printf ("%5d %7d %12g", n_iter, n_evals, T); print_position (x); printf (" %12g %12g\n", E, best_E); } /* apply the cooling schedule to the temperature */ /* FIXME: I should also introduce a cooling schedule for the iters */ T *= T_factor; ++n_iter; if (T < params.t_min) { break; } } /* at the end, copy the result onto the initial point, so we pass it back to the caller */ copy_state(best_x, x0_p, element_size, copyfunc); if (copyfunc) { destructor(x); destructor(new_x); destructor(best_x); } else { free (x); free (new_x); free (best_x); } } /* implementation of a simulated annealing algorithm with many tries */ void gsl_siman_solve_many (const gsl_rng * r, void *x0_p, gsl_siman_Efunc_t Ef, gsl_siman_step_t take_step, gsl_siman_metric_t distance, gsl_siman_print_t print_position, size_t element_size, gsl_siman_params_t params) { /* the new set of trial points, and their energies and probabilities */ void *x, *new_x; double *energies, *probs, *sum_probs; double Ex; /* energy of the chosen point */ double T, T_factor; /* the temperature and a step multiplier */ int i; double u; /* throw the die to choose a new "x" */ int n_iter; if (print_position) { printf ("#-iter temperature position"); printf (" delta_pos energy\n"); } x = (void *) malloc (params.n_tries * element_size); new_x = (void *) malloc (params.n_tries * element_size); energies = (double *) malloc (params.n_tries * sizeof (double)); probs = (double *) malloc (params.n_tries * sizeof (double)); sum_probs = (double *) malloc (params.n_tries * sizeof (double)); T = params.t_initial; T_factor = 1.0 / params.mu_t; memcpy (x, x0_p, element_size); n_iter = 0; while (1) { Ex = Ef (x); for (i = 0; i < params.n_tries - 1; ++i) { /* only go to N_TRIES-2 */ /* center the new_x[] around x, then pass it to take_step() */ sum_probs[i] = 0; memcpy ((char *)new_x + i * element_size, x, element_size); take_step (r, (char *)new_x + i * element_size, params.step_size); energies[i] = Ef ((char *)new_x + i * element_size); probs[i] = boltzmann(Ex, energies[i], T, ¶ms); } /* now add in the old value of "x", so it is a contendor */ memcpy ((char *)new_x + (params.n_tries - 1) * element_size, x, element_size); energies[params.n_tries - 1] = Ex; probs[params.n_tries - 1] = boltzmann(Ex, energies[i], T, ¶ms); /* now throw biased die to see which new_x[i] we choose */ sum_probs[0] = probs[0]; for (i = 1; i < params.n_tries; ++i) { sum_probs[i] = sum_probs[i - 1] + probs[i]; } u = gsl_rng_uniform (r) * sum_probs[params.n_tries - 1]; for (i = 0; i < params.n_tries; ++i) { if (u < sum_probs[i]) { memcpy (x, (char *) new_x + i * element_size, element_size); break; } } if (print_position) { printf ("%5d\t%12g\t", n_iter, T); print_position (x); printf ("\t%12g\t%12g\n", distance (x, x0_p), Ex); } T *= T_factor; ++n_iter; if (T < params.t_min) { break; } } /* now return the value via x0_p */ memcpy (x0_p, x, element_size); /* printf("the result is: %g (E=%g)\n", x, Ex); */ free (x); free (new_x); free (energies); free (probs); free (sum_probs); } praat-6.0.04/external/gsl/gsl_siman__siman_tsp.c000066400000000000000000000224101261542461700216620ustar00rootroot00000000000000/* siman/siman_tsp.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Mark Galassi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include #include #include "gsl_math.h" #include "gsl_rng.h" #include "gsl_siman.h" #include "gsl_ieee_utils.h" /* set up parameters for this simulated annealing run */ #define N_TRIES 200 /* how many points do we try before stepping */ #define ITERS_FIXED_T 2000 /* how many iterations for each T? */ #define STEP_SIZE 1.0 /* max step size in random walk */ #define K 1.0 /* Boltzmann constant */ #define T_INITIAL 5000.0 /* initial temperature */ #define MU_T 1.002 /* damping factor for temperature */ #define T_MIN 5.0e-1 gsl_siman_params_t params = {N_TRIES, ITERS_FIXED_T, STEP_SIZE, K, T_INITIAL, MU_T, T_MIN}; struct s_tsp_city { const char * name; double lat, longitude; /* coordinates */ }; typedef struct s_tsp_city Stsp_city; void prepare_distance_matrix(void); void exhaustive_search(void); void print_distance_matrix(void); double city_distance(Stsp_city c1, Stsp_city c2); double Etsp(void *xp); double Mtsp(void *xp, void *yp); void Stsp(const gsl_rng * r, void *xp, double step_size); void Ptsp(void *xp); /* in this table, latitude and longitude are obtained from the US Census Bureau, at http://www.census.gov/cgi-bin/gazetteer */ Stsp_city cities[] = {{"Santa Fe", 35.68, 105.95}, {"Phoenix", 33.54, 112.07}, {"Albuquerque", 35.12, 106.62}, {"Clovis", 34.41, 103.20}, {"Durango", 37.29, 107.87}, {"Dallas", 32.79, 96.77}, {"Tesuque", 35.77, 105.92}, {"Grants", 35.15, 107.84}, {"Los Alamos", 35.89, 106.28}, {"Las Cruces", 32.34, 106.76}, {"Cortez", 37.35, 108.58}, {"Gallup", 35.52, 108.74}}; #define N_CITIES (sizeof(cities)/sizeof(Stsp_city)) double distance_matrix[N_CITIES][N_CITIES]; /* distance between two cities */ double city_distance(Stsp_city c1, Stsp_city c2) { const double earth_radius = 6375.000; /* 6000KM approximately */ /* sin and cos of lat and long; must convert to radians */ double sla1 = sin(c1.lat*M_PI/180), cla1 = cos(c1.lat*M_PI/180), slo1 = sin(c1.longitude*M_PI/180), clo1 = cos(c1.longitude*M_PI/180); double sla2 = sin(c2.lat*M_PI/180), cla2 = cos(c2.lat*M_PI/180), slo2 = sin(c2.longitude*M_PI/180), clo2 = cos(c2.longitude*M_PI/180); double x1 = cla1*clo1; double x2 = cla2*clo2; double y1 = cla1*slo1; double y2 = cla2*slo2; double z1 = sla1; double z2 = sla2; double dot_product = x1*x2 + y1*y2 + z1*z2; double angle = acos(dot_product); /* distance is the angle (in radians) times the earth radius */ return angle*earth_radius; } /* energy for the travelling salesman problem */ double Etsp(void *xp) { /* an array of N_CITIES integers describing the order */ int *route = (int *) xp; double E = 0; unsigned int i; for (i = 0; i < N_CITIES; ++i) { /* use the distance_matrix to optimize this calculation; it had better be allocated!! */ E += distance_matrix[route[i]][route[(i + 1) % N_CITIES]]; } return E; } double Mtsp(void *xp, void *yp) { int *route1 = (int *) xp, *route2 = (int *) yp; double distance = 0; unsigned int i; for (i = 0; i < N_CITIES; ++i) { distance += ((route1[i] == route2[i]) ? 0 : 1); } return distance; } /* take a step through the TSP space */ void Stsp(const gsl_rng * r, void *xp, double step_size) { int x1, x2, dummy; int *route = (int *) xp; step_size = 0 ; /* prevent warnings about unused parameter */ /* pick the two cities to swap in the matrix; we leave the first city fixed */ x1 = (gsl_rng_get (r) % (N_CITIES-1)) + 1; do { x2 = (gsl_rng_get (r) % (N_CITIES-1)) + 1; } while (x2 == x1); dummy = route[x1]; route[x1] = route[x2]; route[x2] = dummy; } void Ptsp(void *xp) { unsigned int i; int *route = (int *) xp; printf(" ["); for (i = 0; i < N_CITIES; ++i) { printf(" %d ", route[i]); } printf("] "); } int main(void) { int x_initial[N_CITIES]; unsigned int i; const gsl_rng * r = gsl_rng_alloc (gsl_rng_env_setup()) ; gsl_ieee_env_setup (); prepare_distance_matrix(); /* set up a trivial initial route */ printf("# initial order of cities:\n"); for (i = 0; i < N_CITIES; ++i) { printf("# \"%s\"\n", cities[i].name); x_initial[i] = i; } printf("# distance matrix is:\n"); print_distance_matrix(); printf("# initial coordinates of cities (longitude and latitude)\n"); /* this can be plotted with */ /* ./siman_tsp > hhh ; grep city_coord hhh | awk '{print $2 " " $3}' | xyplot -ps -d "xy" > c.eps */ for (i = 0; i < N_CITIES+1; ++i) { printf("###initial_city_coord: %g %g \"%s\"\n", -cities[x_initial[i % N_CITIES]].longitude, cities[x_initial[i % N_CITIES]].lat, cities[x_initial[i % N_CITIES]].name); } /* exhaustive_search(); */ gsl_siman_solve(r, x_initial, Etsp, Stsp, Mtsp, Ptsp, NULL, NULL, NULL, N_CITIES*sizeof(int), params); printf("# final order of cities:\n"); for (i = 0; i < N_CITIES; ++i) { printf("# \"%s\"\n", cities[x_initial[i]].name); } printf("# final coordinates of cities (longitude and latitude)\n"); /* this can be plotted with */ /* ./siman_tsp > hhh ; grep city_coord hhh | awk '{print $2 " " $3}' | xyplot -ps -d "xy" > c.eps */ for (i = 0; i < N_CITIES+1; ++i) { printf("###final_city_coord: %g %g %s\n", -cities[x_initial[i % N_CITIES]].longitude, cities[x_initial[i % N_CITIES]].lat, cities[x_initial[i % N_CITIES]].name); } printf("# "); fflush(stdout); #if 0 system("date"); #endif /* 0 */ fflush(stdout); return 0; } void prepare_distance_matrix() { unsigned int i, j; double dist; for (i = 0; i < N_CITIES; ++i) { for (j = 0; j < N_CITIES; ++j) { if (i == j) { dist = 0; } else { dist = city_distance(cities[i], cities[j]); } distance_matrix[i][j] = dist; } } } void print_distance_matrix() { unsigned int i, j; for (i = 0; i < N_CITIES; ++i) { printf("# "); for (j = 0; j < N_CITIES; ++j) { printf("%15.8f ", distance_matrix[i][j]); } printf("\n"); } } /* [only works for 12] search the entire space for solutions */ static double best_E = 1.0e100, second_E = 1.0e100, third_E = 1.0e100; static int best_route[N_CITIES]; static int second_route[N_CITIES]; static int third_route[N_CITIES]; static void do_all_perms(int *route, int n); void exhaustive_search() { static int initial_route[N_CITIES] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; printf("\n# "); fflush(stdout); #if 0 system("date"); #endif fflush(stdout); do_all_perms(initial_route, 1); printf("\n# "); fflush(stdout); #if 0 system("date"); #endif /* 0 */ fflush(stdout); printf("# exhaustive best route: "); Ptsp(best_route); printf("\n# its energy is: %g\n", best_E); printf("# exhaustive second_best route: "); Ptsp(second_route); printf("\n# its energy is: %g\n", second_E); printf("# exhaustive third_best route: "); Ptsp(third_route); printf("\n# its energy is: %g\n", third_E); } /* James Theiler's recursive algorithm for generating all routes */ static void do_all_perms(int *route, int n) { if (n == (N_CITIES-1)) { /* do it! calculate the energy/cost for that route */ double E; E = Etsp(route); /* TSP energy function */ /* now save the best 3 energies and routes */ if (E < best_E) { third_E = second_E; memcpy(third_route, second_route, N_CITIES*sizeof(*route)); second_E = best_E; memcpy(second_route, best_route, N_CITIES*sizeof(*route)); best_E = E; memcpy(best_route, route, N_CITIES*sizeof(*route)); } else if (E < second_E) { third_E = second_E; memcpy(third_route, second_route, N_CITIES*sizeof(*route)); second_E = E; memcpy(second_route, route, N_CITIES*sizeof(*route)); } else if (E < third_E) { third_E = E; memcpy(route, third_route, N_CITIES*sizeof(*route)); } } else { int new_route[N_CITIES]; unsigned int j; int swap_tmp; memcpy(new_route, route, N_CITIES*sizeof(*route)); for (j = n; j < N_CITIES; ++j) { swap_tmp = new_route[j]; new_route[j] = new_route[n]; new_route[n] = swap_tmp; do_all_perms(new_route, n+1); } } } praat-6.0.04/external/gsl/gsl_sort.h000066400000000000000000000006071261542461700173370ustar00rootroot00000000000000#ifndef __GSL_SORT_H__ #define __GSL_SORT_H__ #include "gsl_sort_long_double.h" #include "gsl_sort_double.h" #include "gsl_sort_float.h" #include "gsl_sort_ulong.h" #include "gsl_sort_long.h" #include "gsl_sort_uint.h" #include "gsl_sort_int.h" #include "gsl_sort_ushort.h" #include "gsl_sort_short.h" #include "gsl_sort_uchar.h" #include "gsl_sort_char.h" #endif /* __GSL_SORT_H__ */ praat-6.0.04/external/gsl/gsl_sort__sort.c000066400000000000000000000052401261542461700205360ustar00rootroot00000000000000/* * Implement Heap sort -- direct and indirect sorting * Based on descriptions in Sedgewick "Algorithms in C" * * Copyright (C) 1999 Thomas Walter * * 18 February 2000: Modified for GSL by Brian Gough * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 3, or (at your option) any * later version. * * This source is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ #include "gsl__config.h" #include #include "gsl_heapsort.h" static inline void swap (void *base, size_t size, size_t i, size_t j); static inline void downheap (void *data, const size_t size, const size_t N, size_t k, gsl_comparison_fn_t compare); /* Inline swap function for moving objects around */ static inline void swap (void *base, size_t size, size_t i, size_t j) { register char *a = size * i + (char *) base; register char *b = size * j + (char *) base; register size_t s = size; if (i == j) return; do { char tmp = *a; *a++ = *b; *b++ = tmp; } while (--s > 0); } #define CMP(data,size,j,k) (compare((char *)(data) + (size) * (j), (char *)(data) + (size) * (k))) static inline void downheap (void *data, const size_t size, const size_t N, size_t k, gsl_comparison_fn_t compare) { while (k <= N / 2) { size_t j = 2 * k; if (j < N && CMP (data, size, j, j + 1) < 0) { j++; } if (CMP (data, size, k, j) < 0) { swap (data, size, j, k); } else { break; } k = j; } } void gsl_heapsort (void *data, size_t count, size_t size, gsl_comparison_fn_t compare) { /* Sort the array in ascending order. This is a true inplace algorithm with N log N operations. Worst case (an already sorted array) is something like 20% slower */ size_t N; size_t k; if (count == 0) { return; /* No data to sort */ } /* We have n_data elements, last element is at 'n_data-1', first at '0' Set N to the last element number. */ N = count - 1; k = N / 2; k++; /* Compensate the first use of 'k--' */ do { k--; downheap (data, size, N, k, compare); } while (k > 0); while (N > 0) { /* first swap the elements */ swap (data, size, 0, N); /* then process the heap */ N--; downheap (data, size, N, 0, compare); } } praat-6.0.04/external/gsl/gsl_sort__sortind.c000066400000000000000000000047261261542461700212410ustar00rootroot00000000000000/* * Implement Heap sort -- direct and indirect sorting * Based on descriptions in Sedgewick "Algorithms in C" * Copyright (C) 1999 Thomas Walter * * 18 February 2000: Modified for GSL by Brian Gough * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 3, or (at your option) any * later version. * * This source is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ #include "gsl__config.h" #include #include "gsl_heapsort.h" static inline void downheap (size_t * p, const void *data, const size_t size, const size_t N, size_t k, gsl_comparison_fn_t compare); #define CMP(data,size,j,k) (compare((const char *)(data) + (size) * (j), (const char *)(data) + (size) * (k))) static inline void downheap (size_t * p, const void *data, const size_t size, const size_t N, size_t k, gsl_comparison_fn_t compare) { const size_t pki = p[k]; while (k <= N / 2) { size_t j = 2 * k; if (j < N && CMP (data, size, p[j], p[j + 1]) < 0) { j++; } if (CMP (data, size, pki, p[j]) >= 0) { break; } p[k] = p[j]; k = j; } p[k] = pki; } int gsl_heapsort_index (size_t * p, const void *data, size_t count, size_t size, gsl_comparison_fn_t compare) { /* Sort the array in ascending order. This is a true inplace algorithm with N log N operations. Worst case (an already sorted array) is something like 20% slower */ size_t i, k, N; if (count == 0) { return GSL_SUCCESS; /* No data to sort */ } for (i = 0; i < count; i++) { p[i] = i ; /* set permutation to identity */ } /* We have n_data elements, last element is at 'n_data-1', first at '0' Set N to the last element number. */ N = count - 1; k = N / 2; k++; /* Compensate the first use of 'k--' */ do { k--; downheap (p, data, size, N, k, compare); } while (k > 0); while (N > 0) { /* first swap the elements */ size_t tmp = p[0]; p[0] = p[N]; p[N] = tmp; /* then process the heap */ N--; downheap (p, data, size, N, 0, compare); } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_sort__sortvec.c000066400000000000000000000043151261542461700212360ustar00rootroot00000000000000/* * Implement Heap sort -- direct and indirect sorting * Based on descriptions in Sedgewick "Algorithms in C" * * Copyright (C) 1999 Thomas Walter * * 18 February 2000: Modified for GSL by Brian Gough * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 3, or (at your option) any * later version. * * This source is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_vector.h" #include "gsl_sort.h" #include "gsl_sort_vector.h" #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_sort__sortvec_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_sort__sortvec_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_sort__sortvec_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_sort__sortvec_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_sort__sortvec_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_sort__sortvec_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_sort__sortvec_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_sort__sortvec_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_sort__sortvec_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_sort__sortvec_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_sort__sortvec_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_sort__sortvec_source.c000066400000000000000000000041571261542461700226220ustar00rootroot00000000000000/* * Implement Heap sort -- direct and indirect sorting * Based on descriptions in Sedgewick "Algorithms in C" * * Copyright (C) 1999 Thomas Walter * * 18 February 2000: Modified for GSL by Brian Gough * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 3, or (at your option) any * later version. * * This source is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ static inline void FUNCTION (my, downheap) (BASE * data, const size_t stride, const size_t N, size_t k); static inline void FUNCTION (my, downheap) (BASE * data, const size_t stride, const size_t N, size_t k) { BASE v = data[k * stride]; while (k <= N / 2) { size_t j = 2 * k; if (j < N && data[j * stride] < data[(j + 1) * stride]) { j++; } if (!(v < data[j * stride])) /* avoid infinite loop if nan */ { break; } data[k * stride] = data[j * stride]; k = j; } data[k * stride] = v; } void TYPE (gsl_sort) (BASE * data, const size_t stride, const size_t n) { size_t N; size_t k; if (n == 0) { return; /* No data to sort */ } /* We have n_data elements, last element is at 'n_data-1', first at '0' Set N to the last element number. */ N = n - 1; k = N / 2; k++; /* Compensate the first use of 'k--' */ do { k--; FUNCTION (my, downheap) (data, stride, N, k); } while (k > 0); while (N > 0) { /* first swap the elements */ BASE tmp = data[0 * stride]; data[0 * stride] = data[N * stride]; data[N * stride] = tmp; /* then process the heap */ N--; FUNCTION (my, downheap) (data, stride, N, 0); } } void TYPE (gsl_sort_vector) (TYPE (gsl_vector) * v) { TYPE (gsl_sort) (v->data, v->stride, v->size) ; } praat-6.0.04/external/gsl/gsl_sort__sortvecind.c000066400000000000000000000043561261542461700217360ustar00rootroot00000000000000/* * Implement Heap sort -- direct and indirect sorting * Based on descriptions in Sedgewick "Algorithms in C" * * Copyright (C) 1999 Thomas Walter * * 18 February 2000: Modified for GSL by Brian Gough * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 3, or (at your option) any * later version. * * This source is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_vector.h" #include "gsl_sort.h" #include "gsl_sort_vector.h" #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_sort__sortvecind_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_sort__sortvecind_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_sort__sortvecind_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_sort__sortvecind_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_sort__sortvecind_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_sort__sortvecind_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_sort__sortvecind_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_sort__sortvecind_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_sort__sortvecind_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_sort__sortvecind_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_sort__sortvecind_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_sort__sortvecind_source.c000066400000000000000000000046771261542461700233240ustar00rootroot00000000000000/* * Implement Heap sort -- direct and indirect sorting * Based on descriptions in Sedgewick "Algorithms in C" * * Copyright (C) 1999 Thomas Walter * * 18 February 2000: Modified for GSL by Brian Gough * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 3, or (at your option) any * later version. * * This source is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ static inline void FUNCTION (index, downheap) (size_t * p, const BASE * data, const size_t stride, const size_t N, size_t k); static inline void FUNCTION (index, downheap) (size_t * p, const BASE * data, const size_t stride, const size_t N, size_t k) { const size_t pki = p[k]; while (k <= N / 2) { size_t j = 2 * k; if (j < N && data[p[j] * stride] < data[p[j + 1] * stride]) { j++; } if (!(data[pki * stride] < data[p[j] * stride])) /* avoid infinite loop if nan */ { break; } p[k] = p[j]; k = j; } p[k] = pki; } void FUNCTION (gsl_sort, index) (size_t * p, const BASE * data, const size_t stride, const size_t n) { size_t N; size_t i, k; if (n == 0) { return; /* No data to sort */ } /* set permutation to identity */ for (i = 0 ; i < n ; i++) { p[i] = i ; } /* We have n_data elements, last element is at 'n_data-1', first at '0' Set N to the last element number. */ N = n - 1; k = N / 2; k++; /* Compensate the first use of 'k--' */ do { k--; FUNCTION (index, downheap) (p, data, stride, N, k); } while (k > 0); while (N > 0) { /* first swap the elements */ size_t tmp = p[0]; p[0] = p[N]; p[N] = tmp; /* then process the heap */ N--; FUNCTION (index, downheap) (p, data, stride, N, 0); } } int FUNCTION (gsl_sort_vector, index) (gsl_permutation * permutation, const TYPE (gsl_vector) * v) { if (permutation->size != v->size) { GSL_ERROR ("permutation and vector lengths are not equal", GSL_EBADLEN); } FUNCTION (gsl_sort, index) (permutation->data, v->data, v->stride, v->size) ; return GSL_SUCCESS ; } praat-6.0.04/external/gsl/gsl_sort__subset.c000066400000000000000000000040571261542461700210610ustar00rootroot00000000000000/* sort/subset.c * * Copyright (C) 2001, 2007 Brian Gough * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 3, or (at your option) any * later version. * * This source is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_vector.h" #include "gsl_sort.h" #include "gsl_sort_vector.h" #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_sort__subset_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_sort__subset_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_sort__subset_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_sort__subset_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_sort__subset_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_sort__subset_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_sort__subset_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_sort__subset_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_sort__subset_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_sort__subset_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_sort__subset_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_sort__subset_source.c000066400000000000000000000056301261542461700224370ustar00rootroot00000000000000/* sort/subset_source.c * * Copyright (C) 1999,2000,2001 Thomas Walter, Brian Gough * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 3, or (at your option) any * later version. * * This source is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ /* find the k-th smallest elements of the vector data, in ascending order */ int FUNCTION (gsl_sort, smallest) (BASE * dest, const size_t k, const BASE * src, const size_t stride, const size_t n) { size_t i, j; BASE xbound; if (k > n) { GSL_ERROR ("subset length k exceeds vector length n", GSL_EINVAL); } if (k == 0 || n == 0) { return GSL_SUCCESS; } /* take the first element */ j = 1; xbound = src[0 * stride]; dest[0] = xbound; /* examine the remaining elements */ for (i = 1; i < n; i++) { size_t i1; BASE xi = src[i * stride]; if (j < k) { j++; } else if (xi >= xbound) { continue; } for (i1 = j - 1; i1 > 0 ; i1--) { if (xi > dest[i1 - 1]) break; dest[i1] = dest[i1 - 1]; } dest[i1] = xi; xbound = dest[j-1]; } return GSL_SUCCESS; } int FUNCTION (gsl_sort_vector,smallest) (BASE * dest, const size_t k, const TYPE (gsl_vector) * v) { return FUNCTION (gsl_sort, smallest) (dest, k, v->data, v->stride, v->size); } int FUNCTION (gsl_sort, largest) (BASE * dest, const size_t k, const BASE * src, const size_t stride, const size_t n) { size_t i, j; BASE xbound; if (k > n) { GSL_ERROR ("subset length k exceeds vector length n", GSL_EINVAL); } if (k == 0 || n == 0) { return GSL_SUCCESS; } /* take the first element */ j = 1; xbound = src[0 * stride]; dest[0] = xbound; /* examine the remaining elements */ for (i = 1; i < n; i++) { size_t i1; BASE xi = src[i * stride]; if (j < k) { j++; } else if (xi <= xbound) { continue; } for (i1 = j - 1; i1 > 0 ; i1--) { if (xi < dest[i1 - 1]) break; dest[i1] = dest[i1 - 1]; } dest[i1] = xi; xbound = dest[j-1]; } return GSL_SUCCESS; } int FUNCTION (gsl_sort_vector,largest) (BASE * dest, const size_t k, const TYPE (gsl_vector) * v) { return FUNCTION (gsl_sort, largest) (dest, k, v->data, v->stride, v->size); } praat-6.0.04/external/gsl/gsl_sort__subsetind.c000066400000000000000000000041231261542461700215460ustar00rootroot00000000000000/* sort/subsetind.c * * Copyright (C) 2001, 2007 Brian Gough * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 3, or (at your option) any * later version. * * This source is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_vector.h" #include "gsl_sort.h" #include "gsl_sort_vector.h" #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_sort__subsetind_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_sort__subsetind_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_sort__subsetind_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_sort__subsetind_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_sort__subsetind_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_sort__subsetind_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_sort__subsetind_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_sort__subsetind_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_sort__subsetind_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_sort__subsetind_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_sort__subsetind_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_sort__subsetind_source.c000066400000000000000000000057411261542461700231350ustar00rootroot00000000000000/* sort/subsetind_source.c * * Copyright (C) 1999,2000,2001 Thomas Walter, Brian Gough * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 3, or (at your option) any * later version. * * This source is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ /* find the k-th smallest elements of the vector data, in ascending order */ int FUNCTION (gsl_sort, smallest_index) (size_t * p, const size_t k, const BASE * src, const size_t stride, const size_t n) { size_t i, j; BASE xbound; if (k > n) { GSL_ERROR ("subset length k exceeds vector length n", GSL_EINVAL); } if (k == 0 || n == 0) { return GSL_SUCCESS; } /* take the first element */ j = 1; xbound = src[0 * stride]; p[0] = 0; /* examine the remaining elements */ for (i = 1; i < n; i++) { size_t i1; BASE xi = src[i * stride]; if (j < k) { j++; } else if (xi >= xbound) { continue; } for (i1 = j - 1; i1 > 0 ; i1--) { if (xi > src[p[i1 - 1] * stride]) break; p[i1] = p[i1 - 1]; } p[i1] = i; xbound = src[p[j-1] * stride]; } return GSL_SUCCESS; } int FUNCTION (gsl_sort_vector,smallest_index) (size_t * p, const size_t k, const TYPE (gsl_vector) * v) { return FUNCTION (gsl_sort, smallest_index) (p, k, v->data, v->stride, v->size); } int FUNCTION (gsl_sort, largest_index) (size_t * p, const size_t k, const BASE * src, const size_t stride, const size_t n) { size_t i, j; BASE xbound; if (k > n) { GSL_ERROR ("subset length k exceeds vector length n", GSL_EINVAL); } if (k == 0 || n == 0) { return GSL_SUCCESS; } /* take the first element */ j = 1; xbound = src[0 * stride]; p[0] = 0; /* examine the remaining elements */ for (i = 1; i < n; i++) { size_t i1; BASE xi = src[i * stride]; if (j < k) { j++; } else if (xi <= xbound) { continue; } for (i1 = j - 1; i1 > 0 ; i1--) { if (xi < src[stride * p[i1 - 1]]) break; p[i1] = p[i1 - 1]; } p[i1] = i; xbound = src[stride * p[j-1]]; } return GSL_SUCCESS; } int FUNCTION (gsl_sort_vector,largest_index) (size_t * p, const size_t k, const TYPE (gsl_vector) * v) { return FUNCTION (gsl_sort, largest_index) (p, k, v->data, v->stride, v->size); } praat-6.0.04/external/gsl/gsl_sort_char.h000066400000000000000000000035001261542461700203270ustar00rootroot00000000000000/* sort/gsl_sort_char.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_SORT_CHAR_H__ #define __GSL_SORT_CHAR_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS void gsl_sort_char (char * data, const size_t stride, const size_t n); void gsl_sort_char_index (size_t * p, const char * data, const size_t stride, const size_t n); int gsl_sort_char_smallest (char * dest, const size_t k, const char * src, const size_t stride, const size_t n); int gsl_sort_char_smallest_index (size_t * p, const size_t k, const char * src, const size_t stride, const size_t n); int gsl_sort_char_largest (char * dest, const size_t k, const char * src, const size_t stride, const size_t n); int gsl_sort_char_largest_index (size_t * p, const size_t k, const char * src, const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_SORT_CHAR_H__ */ praat-6.0.04/external/gsl/gsl_sort_double.h000066400000000000000000000034721261542461700206740ustar00rootroot00000000000000/* sort/gsl_sort_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_SORT_DOUBLE_H__ #define __GSL_SORT_DOUBLE_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS void gsl_sort (double * data, const size_t stride, const size_t n); void gsl_sort_index (size_t * p, const double * data, const size_t stride, const size_t n); int gsl_sort_smallest (double * dest, const size_t k, const double * src, const size_t stride, const size_t n); int gsl_sort_smallest_index (size_t * p, const size_t k, const double * src, const size_t stride, const size_t n); int gsl_sort_largest (double * dest, const size_t k, const double * src, const size_t stride, const size_t n); int gsl_sort_largest_index (size_t * p, const size_t k, const double * src, const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_SORT_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_sort_float.h000066400000000000000000000035221261542461700205230ustar00rootroot00000000000000/* sort/gsl_sort_float.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_SORT_FLOAT_H__ #define __GSL_SORT_FLOAT_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS void gsl_sort_float (float * data, const size_t stride, const size_t n); void gsl_sort_float_index (size_t * p, const float * data, const size_t stride, const size_t n); int gsl_sort_float_smallest (float * dest, const size_t k, const float * src, const size_t stride, const size_t n); int gsl_sort_float_smallest_index (size_t * p, const size_t k, const float * src, const size_t stride, const size_t n); int gsl_sort_float_largest (float * dest, const size_t k, const float * src, const size_t stride, const size_t n); int gsl_sort_float_largest_index (size_t * p, const size_t k, const float * src, const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_SORT_FLOAT_H__ */ praat-6.0.04/external/gsl/gsl_sort_int.h000066400000000000000000000034561261542461700202160ustar00rootroot00000000000000/* sort/gsl_sort_int.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_SORT_INT_H__ #define __GSL_SORT_INT_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS void gsl_sort_int (int * data, const size_t stride, const size_t n); void gsl_sort_int_index (size_t * p, const int * data, const size_t stride, const size_t n); int gsl_sort_int_smallest (int * dest, const size_t k, const int * src, const size_t stride, const size_t n); int gsl_sort_int_smallest_index (size_t * p, const size_t k, const int * src, const size_t stride, const size_t n); int gsl_sort_int_largest (int * dest, const size_t k, const int * src, const size_t stride, const size_t n); int gsl_sort_int_largest_index (size_t * p, const size_t k, const int * src, const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_SORT_INT_H__ */ praat-6.0.04/external/gsl/gsl_sort_long.h000066400000000000000000000035001261542461700203510ustar00rootroot00000000000000/* sort/gsl_sort_long.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_SORT_LONG_H__ #define __GSL_SORT_LONG_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS void gsl_sort_long (long * data, const size_t stride, const size_t n); void gsl_sort_long_index (size_t * p, const long * data, const size_t stride, const size_t n); int gsl_sort_long_smallest (long * dest, const size_t k, const long * src, const size_t stride, const size_t n); int gsl_sort_long_smallest_index (size_t * p, const size_t k, const long * src, const size_t stride, const size_t n); int gsl_sort_long_largest (long * dest, const size_t k, const long * src, const size_t stride, const size_t n); int gsl_sort_long_largest_index (size_t * p, const size_t k, const long * src, const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_SORT_LONG_H__ */ praat-6.0.04/external/gsl/gsl_sort_long_double.h000066400000000000000000000036761261542461700217210ustar00rootroot00000000000000/* sort/gsl_sort_long_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_SORT_LONG_DOUBLE_H__ #define __GSL_SORT_LONG_DOUBLE_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS void gsl_sort_long_double (long double * data, const size_t stride, const size_t n); void gsl_sort_long_double_index (size_t * p, const long double * data, const size_t stride, const size_t n); int gsl_sort_long_double_smallest (long double * dest, const size_t k, const long double * src, const size_t stride, const size_t n); int gsl_sort_long_double_smallest_index (size_t * p, const size_t k, const long double * src, const size_t stride, const size_t n); int gsl_sort_long_double_largest (long double * dest, const size_t k, const long double * src, const size_t stride, const size_t n); int gsl_sort_long_double_largest_index (size_t * p, const size_t k, const long double * src, const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_SORT_LONG_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_sort_short.h000066400000000000000000000035221261542461700205550ustar00rootroot00000000000000/* sort/gsl_sort_short.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_SORT_SHORT_H__ #define __GSL_SORT_SHORT_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS void gsl_sort_short (short * data, const size_t stride, const size_t n); void gsl_sort_short_index (size_t * p, const short * data, const size_t stride, const size_t n); int gsl_sort_short_smallest (short * dest, const size_t k, const short * src, const size_t stride, const size_t n); int gsl_sort_short_smallest_index (size_t * p, const size_t k, const short * src, const size_t stride, const size_t n); int gsl_sort_short_largest (short * dest, const size_t k, const short * src, const size_t stride, const size_t n); int gsl_sort_short_largest_index (size_t * p, const size_t k, const short * src, const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_SORT_SHORT_H__ */ praat-6.0.04/external/gsl/gsl_sort_uchar.h000066400000000000000000000036221261542461700205210ustar00rootroot00000000000000/* sort/gsl_sort_uchar.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_SORT_UCHAR_H__ #define __GSL_SORT_UCHAR_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS void gsl_sort_uchar (unsigned char * data, const size_t stride, const size_t n); void gsl_sort_uchar_index (size_t * p, const unsigned char * data, const size_t stride, const size_t n); int gsl_sort_uchar_smallest (unsigned char * dest, const size_t k, const unsigned char * src, const size_t stride, const size_t n); int gsl_sort_uchar_smallest_index (size_t * p, const size_t k, const unsigned char * src, const size_t stride, const size_t n); int gsl_sort_uchar_largest (unsigned char * dest, const size_t k, const unsigned char * src, const size_t stride, const size_t n); int gsl_sort_uchar_largest_index (size_t * p, const size_t k, const unsigned char * src, const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_SORT_UCHAR_H__ */ praat-6.0.04/external/gsl/gsl_sort_uint.h000066400000000000000000000036001261542461700203720ustar00rootroot00000000000000/* sort/gsl_sort_uint.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_SORT_UINT_H__ #define __GSL_SORT_UINT_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS void gsl_sort_uint (unsigned int * data, const size_t stride, const size_t n); void gsl_sort_uint_index (size_t * p, const unsigned int * data, const size_t stride, const size_t n); int gsl_sort_uint_smallest (unsigned int * dest, const size_t k, const unsigned int * src, const size_t stride, const size_t n); int gsl_sort_uint_smallest_index (size_t * p, const size_t k, const unsigned int * src, const size_t stride, const size_t n); int gsl_sort_uint_largest (unsigned int * dest, const size_t k, const unsigned int * src, const size_t stride, const size_t n); int gsl_sort_uint_largest_index (size_t * p, const size_t k, const unsigned int * src, const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_SORT_UINT_H__ */ praat-6.0.04/external/gsl/gsl_sort_ulong.h000066400000000000000000000036221261542461700205430ustar00rootroot00000000000000/* sort/gsl_sort_ulong.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_SORT_ULONG_H__ #define __GSL_SORT_ULONG_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS void gsl_sort_ulong (unsigned long * data, const size_t stride, const size_t n); void gsl_sort_ulong_index (size_t * p, const unsigned long * data, const size_t stride, const size_t n); int gsl_sort_ulong_smallest (unsigned long * dest, const size_t k, const unsigned long * src, const size_t stride, const size_t n); int gsl_sort_ulong_smallest_index (size_t * p, const size_t k, const unsigned long * src, const size_t stride, const size_t n); int gsl_sort_ulong_largest (unsigned long * dest, const size_t k, const unsigned long * src, const size_t stride, const size_t n); int gsl_sort_ulong_largest_index (size_t * p, const size_t k, const unsigned long * src, const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_SORT_ULONG_H__ */ praat-6.0.04/external/gsl/gsl_sort_ushort.h000066400000000000000000000036441261542461700207470ustar00rootroot00000000000000/* sort/gsl_sort_ushort.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_SORT_USHORT_H__ #define __GSL_SORT_USHORT_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS void gsl_sort_ushort (unsigned short * data, const size_t stride, const size_t n); void gsl_sort_ushort_index (size_t * p, const unsigned short * data, const size_t stride, const size_t n); int gsl_sort_ushort_smallest (unsigned short * dest, const size_t k, const unsigned short * src, const size_t stride, const size_t n); int gsl_sort_ushort_smallest_index (size_t * p, const size_t k, const unsigned short * src, const size_t stride, const size_t n); int gsl_sort_ushort_largest (unsigned short * dest, const size_t k, const unsigned short * src, const size_t stride, const size_t n); int gsl_sort_ushort_largest_index (size_t * p, const size_t k, const unsigned short * src, const size_t stride, const size_t n); __END_DECLS #endif /* __GSL_SORT_USHORT_H__ */ praat-6.0.04/external/gsl/gsl_sort_vector.h000066400000000000000000000007511261542461700207210ustar00rootroot00000000000000#ifndef __GSL_SORT_VECTOR_H__ #define __GSL_SORT_VECTOR_H__ #include "gsl_sort_vector_long_double.h" #include "gsl_sort_vector_double.h" #include "gsl_sort_vector_float.h" #include "gsl_sort_vector_ulong.h" #include "gsl_sort_vector_long.h" #include "gsl_sort_vector_uint.h" #include "gsl_sort_vector_int.h" #include "gsl_sort_vector_ushort.h" #include "gsl_sort_vector_short.h" #include "gsl_sort_vector_uchar.h" #include "gsl_sort_vector_char.h" #endif /* __GSL_SORT_VECTOR_H__ */ praat-6.0.04/external/gsl/gsl_sort_vector_char.h000066400000000000000000000034011261542461700217110ustar00rootroot00000000000000/* sort/gsl_sort_vector_char.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_SORT_VECTOR_CHAR_H__ #define __GSL_SORT_VECTOR_CHAR_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_vector_char.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS void gsl_sort_vector_char (gsl_vector_char * v); int gsl_sort_vector_char_index (gsl_permutation * p, const gsl_vector_char * v); int gsl_sort_vector_char_smallest (char * dest, const size_t k, const gsl_vector_char * v); int gsl_sort_vector_char_largest (char * dest, const size_t k, const gsl_vector_char * v); int gsl_sort_vector_char_smallest_index (size_t * p, const size_t k, const gsl_vector_char * v); int gsl_sort_vector_char_largest_index (size_t * p, const size_t k, const gsl_vector_char * v); __END_DECLS #endif /* __GSL_SORT_VECTOR_CHAR_H__ */ praat-6.0.04/external/gsl/gsl_sort_vector_double.h000066400000000000000000000033231261542461700222510ustar00rootroot00000000000000/* sort/gsl_sort_vector_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_SORT_VECTOR_DOUBLE_H__ #define __GSL_SORT_VECTOR_DOUBLE_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_vector_double.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS void gsl_sort_vector (gsl_vector * v); int gsl_sort_vector_index (gsl_permutation * p, const gsl_vector * v); int gsl_sort_vector_smallest (double * dest, const size_t k, const gsl_vector * v); int gsl_sort_vector_largest (double * dest, const size_t k, const gsl_vector * v); int gsl_sort_vector_smallest_index (size_t * p, const size_t k, const gsl_vector * v); int gsl_sort_vector_largest_index (size_t * p, const size_t k, const gsl_vector * v); __END_DECLS #endif /* __GSL_SORT_VECTOR_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_sort_vector_float.h000066400000000000000000000034241261542461700221060ustar00rootroot00000000000000/* sort/gsl_sort_vector_float.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_SORT_VECTOR_FLOAT_H__ #define __GSL_SORT_VECTOR_FLOAT_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_vector_float.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS void gsl_sort_vector_float (gsl_vector_float * v); int gsl_sort_vector_float_index (gsl_permutation * p, const gsl_vector_float * v); int gsl_sort_vector_float_smallest (float * dest, const size_t k, const gsl_vector_float * v); int gsl_sort_vector_float_largest (float * dest, const size_t k, const gsl_vector_float * v); int gsl_sort_vector_float_smallest_index (size_t * p, const size_t k, const gsl_vector_float * v); int gsl_sort_vector_float_largest_index (size_t * p, const size_t k, const gsl_vector_float * v); __END_DECLS #endif /* __GSL_SORT_VECTOR_FLOAT_H__ */ praat-6.0.04/external/gsl/gsl_sort_vector_int.h000066400000000000000000000033561261542461700215770ustar00rootroot00000000000000/* sort/gsl_sort_vector_int.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_SORT_VECTOR_INT_H__ #define __GSL_SORT_VECTOR_INT_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_vector_int.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS void gsl_sort_vector_int (gsl_vector_int * v); int gsl_sort_vector_int_index (gsl_permutation * p, const gsl_vector_int * v); int gsl_sort_vector_int_smallest (int * dest, const size_t k, const gsl_vector_int * v); int gsl_sort_vector_int_largest (int * dest, const size_t k, const gsl_vector_int * v); int gsl_sort_vector_int_smallest_index (size_t * p, const size_t k, const gsl_vector_int * v); int gsl_sort_vector_int_largest_index (size_t * p, const size_t k, const gsl_vector_int * v); __END_DECLS #endif /* __GSL_SORT_VECTOR_INT_H__ */ praat-6.0.04/external/gsl/gsl_sort_vector_long.h000066400000000000000000000034011261542461700217330ustar00rootroot00000000000000/* sort/gsl_sort_vector_long.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_SORT_VECTOR_LONG_H__ #define __GSL_SORT_VECTOR_LONG_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_vector_long.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS void gsl_sort_vector_long (gsl_vector_long * v); int gsl_sort_vector_long_index (gsl_permutation * p, const gsl_vector_long * v); int gsl_sort_vector_long_smallest (long * dest, const size_t k, const gsl_vector_long * v); int gsl_sort_vector_long_largest (long * dest, const size_t k, const gsl_vector_long * v); int gsl_sort_vector_long_smallest_index (size_t * p, const size_t k, const gsl_vector_long * v); int gsl_sort_vector_long_largest_index (size_t * p, const size_t k, const gsl_vector_long * v); __END_DECLS #endif /* __GSL_SORT_VECTOR_LONG_H__ */ praat-6.0.04/external/gsl/gsl_sort_vector_long_double.h000066400000000000000000000036061261542461700232740ustar00rootroot00000000000000/* sort/gsl_sort_vector_long_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_SORT_VECTOR_LONG_DOUBLE_H__ #define __GSL_SORT_VECTOR_LONG_DOUBLE_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_vector_long_double.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS void gsl_sort_vector_long_double (gsl_vector_long_double * v); int gsl_sort_vector_long_double_index (gsl_permutation * p, const gsl_vector_long_double * v); int gsl_sort_vector_long_double_smallest (long double * dest, const size_t k, const gsl_vector_long_double * v); int gsl_sort_vector_long_double_largest (long double * dest, const size_t k, const gsl_vector_long_double * v); int gsl_sort_vector_long_double_smallest_index (size_t * p, const size_t k, const gsl_vector_long_double * v); int gsl_sort_vector_long_double_largest_index (size_t * p, const size_t k, const gsl_vector_long_double * v); __END_DECLS #endif /* __GSL_SORT_VECTOR_LONG_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_sort_vector_short.h000066400000000000000000000034241261542461700221400ustar00rootroot00000000000000/* sort/gsl_sort_vector_short.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_SORT_VECTOR_SHORT_H__ #define __GSL_SORT_VECTOR_SHORT_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_vector_short.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS void gsl_sort_vector_short (gsl_vector_short * v); int gsl_sort_vector_short_index (gsl_permutation * p, const gsl_vector_short * v); int gsl_sort_vector_short_smallest (short * dest, const size_t k, const gsl_vector_short * v); int gsl_sort_vector_short_largest (short * dest, const size_t k, const gsl_vector_short * v); int gsl_sort_vector_short_smallest_index (size_t * p, const size_t k, const gsl_vector_short * v); int gsl_sort_vector_short_largest_index (size_t * p, const size_t k, const gsl_vector_short * v); __END_DECLS #endif /* __GSL_SORT_VECTOR_SHORT_H__ */ praat-6.0.04/external/gsl/gsl_sort_vector_uchar.h000066400000000000000000000034441261542461700221050ustar00rootroot00000000000000/* sort/gsl_sort_vector_uchar.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_SORT_VECTOR_UCHAR_H__ #define __GSL_SORT_VECTOR_UCHAR_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_vector_uchar.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS void gsl_sort_vector_uchar (gsl_vector_uchar * v); int gsl_sort_vector_uchar_index (gsl_permutation * p, const gsl_vector_uchar * v); int gsl_sort_vector_uchar_smallest (unsigned char * dest, const size_t k, const gsl_vector_uchar * v); int gsl_sort_vector_uchar_largest (unsigned char * dest, const size_t k, const gsl_vector_uchar * v); int gsl_sort_vector_uchar_smallest_index (size_t * p, const size_t k, const gsl_vector_uchar * v); int gsl_sort_vector_uchar_largest_index (size_t * p, const size_t k, const gsl_vector_uchar * v); __END_DECLS #endif /* __GSL_SORT_VECTOR_UCHAR_H__ */ praat-6.0.04/external/gsl/gsl_sort_vector_uint.h000066400000000000000000000034211261542461700217550ustar00rootroot00000000000000/* sort/gsl_sort_vector_uint.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_SORT_VECTOR_UINT_H__ #define __GSL_SORT_VECTOR_UINT_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_vector_uint.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS void gsl_sort_vector_uint (gsl_vector_uint * v); int gsl_sort_vector_uint_index (gsl_permutation * p, const gsl_vector_uint * v); int gsl_sort_vector_uint_smallest (unsigned int * dest, const size_t k, const gsl_vector_uint * v); int gsl_sort_vector_uint_largest (unsigned int * dest, const size_t k, const gsl_vector_uint * v); int gsl_sort_vector_uint_smallest_index (size_t * p, const size_t k, const gsl_vector_uint * v); int gsl_sort_vector_uint_largest_index (size_t * p, const size_t k, const gsl_vector_uint * v); __END_DECLS #endif /* __GSL_SORT_VECTOR_UINT_H__ */ praat-6.0.04/external/gsl/gsl_sort_vector_ulong.h000066400000000000000000000034441261542461700221270ustar00rootroot00000000000000/* sort/gsl_sort_vector_ulong.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_SORT_VECTOR_ULONG_H__ #define __GSL_SORT_VECTOR_ULONG_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_vector_ulong.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS void gsl_sort_vector_ulong (gsl_vector_ulong * v); int gsl_sort_vector_ulong_index (gsl_permutation * p, const gsl_vector_ulong * v); int gsl_sort_vector_ulong_smallest (unsigned long * dest, const size_t k, const gsl_vector_ulong * v); int gsl_sort_vector_ulong_largest (unsigned long * dest, const size_t k, const gsl_vector_ulong * v); int gsl_sort_vector_ulong_smallest_index (size_t * p, const size_t k, const gsl_vector_ulong * v); int gsl_sort_vector_ulong_largest_index (size_t * p, const size_t k, const gsl_vector_ulong * v); __END_DECLS #endif /* __GSL_SORT_VECTOR_ULONG_H__ */ praat-6.0.04/external/gsl/gsl_sort_vector_ushort.h000066400000000000000000000034671261542461700223340ustar00rootroot00000000000000/* sort/gsl_sort_vector_ushort.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_SORT_VECTOR_USHORT_H__ #define __GSL_SORT_VECTOR_USHORT_H__ #include #include "gsl_errno.h" #include "gsl_permutation.h" #include "gsl_vector_ushort.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS void gsl_sort_vector_ushort (gsl_vector_ushort * v); int gsl_sort_vector_ushort_index (gsl_permutation * p, const gsl_vector_ushort * v); int gsl_sort_vector_ushort_smallest (unsigned short * dest, const size_t k, const gsl_vector_ushort * v); int gsl_sort_vector_ushort_largest (unsigned short * dest, const size_t k, const gsl_vector_ushort * v); int gsl_sort_vector_ushort_smallest_index (size_t * p, const size_t k, const gsl_vector_ushort * v); int gsl_sort_vector_ushort_largest_index (size_t * p, const size_t k, const gsl_vector_ushort * v); __END_DECLS #endif /* __GSL_SORT_VECTOR_USHORT_H__ */ praat-6.0.04/external/gsl/gsl_specfunc.h000066400000000000000000000002511261542461700201510ustar00rootroot00000000000000/* Author: G. Jungman */ /* Convenience header */ #ifndef __GSL_SPECFUNC_H__ #define __GSL_SPECFUNC_H__ #include "gsl_sf.h" #endif /* __GSL_SPECFUNC_H__ */ praat-6.0.04/external/gsl/gsl_specfunc__airy.c000066400000000000000000000560651261542461700213450ustar00rootroot00000000000000/* specfunc/airy.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_trig.h" #include "gsl_sf_airy.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__check.h" #include "gsl_specfunc__chebyshev.h" #include "gsl_specfunc__cheb_eval_mode.c" /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/ /* chebyshev expansions for Airy modulus and phase based on SLATEC r9aimp() Series for AM21 on the interval -1.25000D-01 to 0. with weighted error 2.89E-17 log weighted error 16.54 significant figures required 14.15 decimal places required 17.34 Series for ATH1 on the interval -1.25000D-01 to 0. with weighted error 2.53E-17 log weighted error 16.60 significant figures required 15.15 decimal places required 17.38 Series for AM22 on the interval -1.00000D+00 to -1.25000D-01 with weighted error 2.99E-17 log weighted error 16.52 significant figures required 14.57 decimal places required 17.28 Series for ATH2 on the interval -1.00000D+00 to -1.25000D-01 with weighted error 2.57E-17 log weighted error 16.59 significant figures required 15.07 decimal places required 17.34 */ static double am21_data[37] = { 0.0065809191761485, 0.0023675984685722, 0.0001324741670371, 0.0000157600904043, 0.0000027529702663, 0.0000006102679017, 0.0000001595088468, 0.0000000471033947, 0.0000000152933871, 0.0000000053590722, 0.0000000020000910, 0.0000000007872292, 0.0000000003243103, 0.0000000001390106, 0.0000000000617011, 0.0000000000282491, 0.0000000000132979, 0.0000000000064188, 0.0000000000031697, 0.0000000000015981, 0.0000000000008213, 0.0000000000004296, 0.0000000000002284, 0.0000000000001232, 0.0000000000000675, 0.0000000000000374, 0.0000000000000210, 0.0000000000000119, 0.0000000000000068, 0.0000000000000039, 0.0000000000000023, 0.0000000000000013, 0.0000000000000008, 0.0000000000000005, 0.0000000000000003, 0.0000000000000001, 0.0000000000000001 }; static cheb_series am21_cs = { am21_data, 36, -1, 1, 20 }; static double ath1_data[36] = { -0.07125837815669365, -0.00590471979831451, -0.00012114544069499, -0.00000988608542270, -0.00000138084097352, -0.00000026142640172, -0.00000006050432589, -0.00000001618436223, -0.00000000483464911, -0.00000000157655272, -0.00000000055231518, -0.00000000020545441, -0.00000000008043412, -0.00000000003291252, -0.00000000001399875, -0.00000000000616151, -0.00000000000279614, -0.00000000000130428, -0.00000000000062373, -0.00000000000030512, -0.00000000000015239, -0.00000000000007758, -0.00000000000004020, -0.00000000000002117, -0.00000000000001132, -0.00000000000000614, -0.00000000000000337, -0.00000000000000188, -0.00000000000000105, -0.00000000000000060, -0.00000000000000034, -0.00000000000000020, -0.00000000000000011, -0.00000000000000007, -0.00000000000000004, -0.00000000000000002 }; static cheb_series ath1_cs = { ath1_data, 35, -1, 1, 15 }; static double am22_data[33] = { -0.01562844480625341, 0.00778336445239681, 0.00086705777047718, 0.00015696627315611, 0.00003563962571432, 0.00000924598335425, 0.00000262110161850, 0.00000079188221651, 0.00000025104152792, 0.00000008265223206, 0.00000002805711662, 0.00000000976821090, 0.00000000347407923, 0.00000000125828132, 0.00000000046298826, 0.00000000017272825, 0.00000000006523192, 0.00000000002490471, 0.00000000000960156, 0.00000000000373448, 0.00000000000146417, 0.00000000000057826, 0.00000000000022991, 0.00000000000009197, 0.00000000000003700, 0.00000000000001496, 0.00000000000000608, 0.00000000000000248, 0.00000000000000101, 0.00000000000000041, 0.00000000000000017, 0.00000000000000007, 0.00000000000000002 }; static cheb_series am22_cs = { am22_data, 32, -1, 1, 15 }; static double ath2_data[32] = { 0.00440527345871877, -0.03042919452318455, -0.00138565328377179, -0.00018044439089549, -0.00003380847108327, -0.00000767818353522, -0.00000196783944371, -0.00000054837271158, -0.00000016254615505, -0.00000005053049981, -0.00000001631580701, -0.00000000543420411, -0.00000000185739855, -0.00000000064895120, -0.00000000023105948, -0.00000000008363282, -0.00000000003071196, -0.00000000001142367, -0.00000000000429811, -0.00000000000163389, -0.00000000000062693, -0.00000000000024260, -0.00000000000009461, -0.00000000000003716, -0.00000000000001469, -0.00000000000000584, -0.00000000000000233, -0.00000000000000093, -0.00000000000000037, -0.00000000000000015, -0.00000000000000006, -0.00000000000000002 }; static cheb_series ath2_cs = { ath2_data, 31, -1, 1, 16 }; /* Airy modulus and phase for x < -1 */ static int airy_mod_phase(const double x, gsl_mode_t mode, gsl_sf_result * mod, gsl_sf_result * phase) { gsl_sf_result result_m; gsl_sf_result result_p; double m, p; double sqx; if(x < -2.0) { double z = 16.0/(x*x*x) + 1.0; cheb_eval_mode_e(&am21_cs, z, mode, &result_m); cheb_eval_mode_e(&ath1_cs, z, mode, &result_p); } else if(x <= -1.0) { double z = (16.0/(x*x*x) + 9.0)/7.0; cheb_eval_mode_e(&am22_cs, z, mode, &result_m); cheb_eval_mode_e(&ath2_cs, z, mode, &result_p); } else { mod->val = 0.0; mod->err = 0.0; phase->val = 0.0; phase->err = 0.0; GSL_ERROR ("x is greater than 1.0", GSL_EDOM); } m = 0.3125 + result_m.val; p = -0.625 + result_p.val; sqx = sqrt(-x); mod->val = sqrt(m/sqx); mod->err = fabs(mod->val) * (GSL_DBL_EPSILON + fabs(result_m.err/result_m.val)); phase->val = M_PI_4 - x*sqx * p; phase->err = fabs(phase->val) * (GSL_DBL_EPSILON + fabs(result_p.err/result_p.val)); return GSL_SUCCESS; } /* Chebyshev series for Ai(x) with x in [-1,1] based on SLATEC ai(x) series for aif on the interval -1.00000d+00 to 1.00000d+00 with weighted error 1.09e-19 log weighted error 18.96 significant figures required 17.76 decimal places required 19.44 series for aig on the interval -1.00000d+00 to 1.00000d+00 with weighted error 1.51e-17 log weighted error 16.82 significant figures required 15.19 decimal places required 17.27 */ static double ai_data_f[9] = { -0.03797135849666999750, 0.05919188853726363857, 0.00098629280577279975, 0.00000684884381907656, 0.00000002594202596219, 0.00000000006176612774, 0.00000000000010092454, 0.00000000000000012014, 0.00000000000000000010 }; static cheb_series aif_cs = { ai_data_f, 8, -1, 1, 8 }; static double ai_data_g[8] = { 0.01815236558116127, 0.02157256316601076, 0.00025678356987483, 0.00000142652141197, 0.00000000457211492, 0.00000000000952517, 0.00000000000001392, 0.00000000000000001 }; static cheb_series aig_cs = { ai_data_g, 7, -1, 1, 7 }; /* Chebvyshev series for Bi(x) with x in [-1,1] based on SLATEC bi(x) series for bif on the interval -1.00000d+00 to 1.00000d+00 with weighted error 1.88e-19 log weighted error 18.72 significant figures required 17.74 decimal places required 19.20 series for big on the interval -1.00000d+00 to 1.00000d+00 with weighted error 2.61e-17 log weighted error 16.58 significant figures required 15.17 decimal places required 17.03 */ static double data_bif[9] = { -0.01673021647198664948, 0.10252335834249445610, 0.00170830925073815165, 0.00001186254546774468, 0.00000004493290701779, 0.00000000010698207143, 0.00000000000017480643, 0.00000000000000020810, 0.00000000000000000018 }; static cheb_series bif_cs = { data_bif, 8, -1, 1, 8 }; static double data_big[8] = { 0.02246622324857452, 0.03736477545301955, 0.00044476218957212, 0.00000247080756363, 0.00000000791913533, 0.00000000001649807, 0.00000000000002411, 0.00000000000000002 }; static cheb_series big_cs = { data_big, 7, -1, 1, 7 }; /* Chebyshev series for Bi(x) with x in [1,8] based on SLATEC bi(x) */ static double data_bif2[10] = { 0.0998457269381604100, 0.4786249778630055380, 0.0251552119604330118, 0.0005820693885232645, 0.0000074997659644377, 0.0000000613460287034, 0.0000000003462753885, 0.0000000000014288910, 0.0000000000000044962, 0.0000000000000000111 }; static cheb_series bif2_cs = { data_bif2, 9, -1, 1, 9 }; static double data_big2[10] = { 0.033305662145514340, 0.161309215123197068, 0.0063190073096134286, 0.0001187904568162517, 0.0000013045345886200, 0.0000000093741259955, 0.0000000000474580188, 0.0000000000001783107, 0.0000000000000005167, 0.0000000000000000011 }; static cheb_series big2_cs = { data_big2, 9, -1, 1, 9 }; /* chebyshev for Ai(x) asymptotic factor based on SLATEC aie() Series for AIP on the interval 0. to 1.00000D+00 with weighted error 5.10E-17 log weighted error 16.29 significant figures required 14.41 decimal places required 17.06 [GJ] Sun Apr 19 18:14:31 EDT 1998 There was something wrong with these coefficients. I was getting errors after 3 or 4 digits. So I recomputed this table. Now I get double precision agreement with Mathematica. But it does not seem possible that the small differences here would account for the original discrepancy. There must have been something wrong with my original usage... */ static double data_aip[36] = { -0.0187519297793867540198, -0.0091443848250055004725, 0.0009010457337825074652, -0.0001394184127221491507, 0.0000273815815785209370, -0.0000062750421119959424, 0.0000016064844184831521, -0.0000004476392158510354, 0.0000001334635874651668, -0.0000000420735334263215, 0.0000000139021990246364, -0.0000000047831848068048, 0.0000000017047897907465, -0.0000000006268389576018, 0.0000000002369824276612, -0.0000000000918641139267, 0.0000000000364278543037, -0.0000000000147475551725, 0.0000000000060851006556, -0.0000000000025552772234, 0.0000000000010906187250, -0.0000000000004725870319, 0.0000000000002076969064, -0.0000000000000924976214, 0.0000000000000417096723, -0.0000000000000190299093, 0.0000000000000087790676, -0.0000000000000040927557, 0.0000000000000019271068, -0.0000000000000009160199, 0.0000000000000004393567, -0.0000000000000002125503, 0.0000000000000001036735, -0.0000000000000000509642, 0.0000000000000000252377, -0.0000000000000000125793 /* -.0187519297793868 -.0091443848250055, .0009010457337825, -.0001394184127221, .0000273815815785, -.0000062750421119, .0000016064844184, -.0000004476392158, .0000001334635874, -.0000000420735334, .0000000139021990, -.0000000047831848, .0000000017047897, -.0000000006268389, .0000000002369824, -.0000000000918641, .0000000000364278, -.0000000000147475, .0000000000060851, -.0000000000025552, .0000000000010906, -.0000000000004725, .0000000000002076, -.0000000000000924, .0000000000000417, -.0000000000000190, .0000000000000087, -.0000000000000040, .0000000000000019, -.0000000000000009, .0000000000000004, -.0000000000000002, .0000000000000001, -.0000000000000000 */ }; static cheb_series aip_cs = { data_aip, 35, -1, 1, 17 }; /* chebyshev for Bi(x) asymptotic factor based on SLATEC bie() Series for BIP on the interval 1.25000D-01 to 3.53553D-01 with weighted error 1.91E-17 log weighted error 16.72 significant figures required 15.35 decimal places required 17.41 Series for BIP2 on the interval 0. to 1.25000D-01 with weighted error 1.05E-18 log weighted error 17.98 significant figures required 16.74 decimal places required 18.71 */ static double data_bip[24] = { -0.08322047477943447, 0.01146118927371174, 0.00042896440718911, -0.00014906639379950, -0.00001307659726787, 0.00000632759839610, -0.00000042226696982, -0.00000019147186298, 0.00000006453106284, -0.00000000784485467, -0.00000000096077216, 0.00000000070004713, -0.00000000017731789, 0.00000000002272089, 0.00000000000165404, -0.00000000000185171, 0.00000000000059576, -0.00000000000012194, 0.00000000000001334, 0.00000000000000172, -0.00000000000000145, 0.00000000000000049, -0.00000000000000011, 0.00000000000000001 }; static cheb_series bip_cs = { data_bip, 23, -1, 1, 14 }; static double data_bip2[29] = { -0.113596737585988679, 0.0041381473947881595, 0.0001353470622119332, 0.0000104273166530153, 0.0000013474954767849, 0.0000001696537405438, -0.0000000100965008656, -0.0000000167291194937, -0.0000000045815364485, 0.0000000003736681366, 0.0000000005766930320, 0.0000000000621812650, -0.0000000000632941202, -0.0000000000149150479, 0.0000000000078896213, 0.0000000000024960513, -0.0000000000012130075, -0.0000000000003740493, 0.0000000000002237727, 0.0000000000000474902, -0.0000000000000452616, -0.0000000000000030172, 0.0000000000000091058, -0.0000000000000009814, -0.0000000000000016429, 0.0000000000000005533, 0.0000000000000002175, -0.0000000000000001737, -0.0000000000000000010 }; static cheb_series bip2_cs = { data_bip2, 28, -1, 1, 10 }; /* assumes x >= 1.0 */ inline static int airy_aie(const double x, gsl_mode_t mode, gsl_sf_result * result) { double sqx = sqrt(x); double z = 2.0/(x*sqx) - 1.0; double y = sqrt(sqx); gsl_sf_result result_c; cheb_eval_mode_e(&aip_cs, z, mode, &result_c); result->val = (0.28125 + result_c.val)/y; result->err = result_c.err/y + GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } /* assumes x >= 2.0 */ static int airy_bie(const double x, gsl_mode_t mode, gsl_sf_result * result) { const double ATR = 8.7506905708484345; const double BTR = -2.0938363213560543; if(x < 4.0) { double sqx = sqrt(x); double z = ATR/(x*sqx) + BTR; double y = sqrt(sqx); gsl_sf_result result_c; cheb_eval_mode_e(&bip_cs, z, mode, &result_c); result->val = (0.625 + result_c.val)/y; result->err = result_c.err/y + GSL_DBL_EPSILON * fabs(result->val); } else { double sqx = sqrt(x); double z = 16.0/(x*sqx) - 1.0; double y = sqrt(sqx); gsl_sf_result result_c; cheb_eval_mode_e(&bip2_cs, z, mode, &result_c); result->val = (0.625 + result_c.val)/y; result->err = result_c.err/y + GSL_DBL_EPSILON * fabs(result->val); } return GSL_SUCCESS; } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_airy_Ai_e(const double x, const gsl_mode_t mode, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x < -1.0) { gsl_sf_result mod; gsl_sf_result theta; gsl_sf_result cos_result; int stat_mp = airy_mod_phase(x, mode, &mod, &theta); int stat_cos = gsl_sf_cos_err_e(theta.val, theta.err, &cos_result); result->val = mod.val * cos_result.val; result->err = fabs(mod.val * cos_result.err) + fabs(cos_result.val * mod.err); result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_mp, stat_cos); } else if(x <= 1.0) { const double z = x*x*x; gsl_sf_result result_c0; gsl_sf_result result_c1; cheb_eval_mode_e(&aif_cs, z, mode, &result_c0); cheb_eval_mode_e(&aig_cs, z, mode, &result_c1); result->val = 0.375 + (result_c0.val - x*(0.25 + result_c1.val)); result->err = result_c0.err + fabs(x*result_c1.err); result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { double x32 = x * sqrt(x); double s = exp(-2.0*x32/3.0); gsl_sf_result result_aie; int stat_aie = airy_aie(x, mode, &result_aie); result->val = result_aie.val * s; result->err = result_aie.err * s + result->val * x32 * GSL_DBL_EPSILON; result->err += GSL_DBL_EPSILON * fabs(result->val); CHECK_UNDERFLOW(result); return stat_aie; } } int gsl_sf_airy_Ai_scaled_e(const double x, gsl_mode_t mode, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x < -1.0) { gsl_sf_result mod; gsl_sf_result theta; gsl_sf_result cos_result; int stat_mp = airy_mod_phase(x, mode, &mod, &theta); int stat_cos = gsl_sf_cos_err_e(theta.val, theta.err, &cos_result); result->val = mod.val * cos_result.val; result->err = fabs(mod.val * cos_result.err) + fabs(cos_result.val * mod.err); result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_mp, stat_cos); } else if(x <= 1.0) { const double z = x*x*x; gsl_sf_result result_c0; gsl_sf_result result_c1; cheb_eval_mode_e(&aif_cs, z, mode, &result_c0); cheb_eval_mode_e(&aig_cs, z, mode, &result_c1); result->val = 0.375 + (result_c0.val - x*(0.25 + result_c1.val)); result->err = result_c0.err + fabs(x*result_c1.err); result->err += GSL_DBL_EPSILON * fabs(result->val); if(x > 0.0) { const double scale = exp(2.0/3.0 * sqrt(z)); result->val *= scale; result->err *= scale; } return GSL_SUCCESS; } else { return airy_aie(x, mode, result); } } int gsl_sf_airy_Bi_e(const double x, gsl_mode_t mode, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x < -1.0) { gsl_sf_result mod; gsl_sf_result theta; gsl_sf_result sin_result; int stat_mp = airy_mod_phase(x, mode, &mod, &theta); int stat_sin = gsl_sf_sin_err_e(theta.val, theta.err, &sin_result); result->val = mod.val * sin_result.val; result->err = fabs(mod.val * sin_result.err) + fabs(sin_result.val * mod.err); result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_mp, stat_sin); } else if(x < 1.0) { const double z = x*x*x; gsl_sf_result result_c0; gsl_sf_result result_c1; cheb_eval_mode_e(&bif_cs, z, mode, &result_c0); cheb_eval_mode_e(&big_cs, z, mode, &result_c1); result->val = 0.625 + result_c0.val + x*(0.4375 + result_c1.val); result->err = result_c0.err + fabs(x * result_c1.err); result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x <= 2.0) { const double z = (2.0*x*x*x - 9.0)/7.0; gsl_sf_result result_c0; gsl_sf_result result_c1; cheb_eval_mode_e(&bif2_cs, z, mode, &result_c0); cheb_eval_mode_e(&big2_cs, z, mode, &result_c1); result->val = 1.125 + result_c0.val + x*(0.625 + result_c1.val); result->err = result_c0.err + fabs(x * result_c1.err); result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { const double y = 2.0*x*sqrt(x)/3.0; const double s = exp(y); if(y > GSL_LOG_DBL_MAX - 1.0) { OVERFLOW_ERROR(result); } else { gsl_sf_result result_bie; int stat_bie = airy_bie(x, mode, &result_bie); result->val = result_bie.val * s; result->err = result_bie.err * s + fabs(1.5*y * (GSL_DBL_EPSILON * result->val)); result->err += GSL_DBL_EPSILON * fabs(result->val); return stat_bie; } } } int gsl_sf_airy_Bi_scaled_e(const double x, gsl_mode_t mode, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x < -1.0) { gsl_sf_result mod; gsl_sf_result theta; gsl_sf_result sin_result; int stat_mp = airy_mod_phase(x, mode, &mod, &theta); int stat_sin = gsl_sf_sin_err_e(theta.val, theta.err, &sin_result); result->val = mod.val * sin_result.val; result->err = fabs(mod.val * sin_result.err) + fabs(sin_result.val * mod.err); result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_mp, stat_sin); } else if(x < 1.0) { const double z = x*x*x; gsl_sf_result result_c0; gsl_sf_result result_c1; cheb_eval_mode_e(&bif_cs, z, mode, &result_c0); cheb_eval_mode_e(&big_cs, z, mode, &result_c1); result->val = 0.625 + result_c0.val + x*(0.4375 + result_c1.val); result->err = result_c0.err + fabs(x * result_c1.err); result->err += GSL_DBL_EPSILON * fabs(result->val); if(x > 0.0) { const double scale = exp(-2.0/3.0 * sqrt(z)); result->val *= scale; result->err *= scale; } return GSL_SUCCESS; } else if(x <= 2.0) { const double x3 = x*x*x; const double z = (2.0*x3 - 9.0)/7.0; const double s = exp(-2.0/3.0 * sqrt(x3)); gsl_sf_result result_c0; gsl_sf_result result_c1; cheb_eval_mode_e(&bif2_cs, z, mode, &result_c0); cheb_eval_mode_e(&big2_cs, z, mode, &result_c1); result->val = s * (1.125 + result_c0.val + x*(0.625 + result_c1.val)); result->err = s * (result_c0.err + fabs(x * result_c1.err)); result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { return airy_bie(x, mode, result); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_airy_Ai(const double x, gsl_mode_t mode) { EVAL_RESULT(gsl_sf_airy_Ai_e(x, mode, &result)); } double gsl_sf_airy_Ai_scaled(const double x, gsl_mode_t mode) { EVAL_RESULT(gsl_sf_airy_Ai_scaled_e(x, mode, &result)); } double gsl_sf_airy_Bi(const double x, gsl_mode_t mode) { EVAL_RESULT(gsl_sf_airy_Bi_e(x, mode, &result)); } double gsl_sf_airy_Bi_scaled(const double x, gsl_mode_t mode) { EVAL_RESULT(gsl_sf_airy_Bi_scaled_e(x, mode, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__airy_der.c000066400000000000000000000621121261542461700221650ustar00rootroot00000000000000/* specfunc/airy_der.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_exp.h" #include "gsl_sf_airy.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__chebyshev.h" #include "gsl_specfunc__cheb_eval_mode.c" /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/ /* based on SLATEC aide.f, bide.f, aid.f, bid.f, r9admp.f */ /* series for aif on the interval -1.00000e+00 to 1.00000e+00 with weighted error 5.22e-18 log weighted error 17.28 significant figures required 16.01 decimal places required 17.73 */ static double aif_data[8] = { 0.10527461226531408809, 0.01183613628152997844, 0.00012328104173225664, 0.00000062261225638140, 0.00000000185298887844, 0.00000000000363328873, 0.00000000000000504622, 0.00000000000000000522 }; static cheb_series aif_cs = { aif_data, 7, -1, 1, 7 }; /* series for aig on the interval -1.00000e+00 to 1.00000e+00 with weighted error 3.14e-19 log weighted error 18.50 significant figures required 17.44 decimal places required 18.98 */ static double aig_data[9] = { 0.021233878150918666852, 0.086315930335214406752, 0.001797594720383231358, 0.000014265499875550693, 0.000000059437995283683, 0.000000000152403366479, 0.000000000000264587660, 0.000000000000000331562, 0.000000000000000000314 }; static cheb_series aig_cs = { aig_data, 8, -1, 1, 8 }; /* series for aip2 on the interval 0.00000e+00 to 1.25000e-01 with weighted error 2.15e-17 log weighted error 16.67 significant figures required 14.27 decimal places required 17.26 */ static double aip2_data[15] = { 0.0065457691989713757, 0.0023833724120774592, -0.0000430700770220586, 0.0000015629125858629, -0.0000000815417186163, 0.0000000054103738057, -0.0000000004284130883, 0.0000000000389497963, -0.0000000000039623161, 0.0000000000004428184, -0.0000000000000536297, 0.0000000000000069650, -0.0000000000000009620, 0.0000000000000001403, -0.0000000000000000215 }; static cheb_series aip2_cs = { aip2_data, 14, -1, 1, 9 }; /* series for aip1 on the interval 1.25000e-01 to 1.00000e+00 with weighted error 2.60e-17 log weighted error 16.58 significant figures required 14.91 decimal places required 17.28 */ static double aip1_data[25] = { 0.0358865097808301538, 0.0114668575627764899, -0.0007592073583861400, 0.0000869517610893841, -0.0000128237294298592, 0.0000022062695681038, -0.0000004222295185921, 0.0000000874686415726, -0.0000000192773588418, 0.0000000044668460054, -0.0000000010790108052, 0.0000000002700029447, -0.0000000000696480108, 0.0000000000184489907, -0.0000000000050027817, 0.0000000000013852243, -0.0000000000003908218, 0.0000000000001121536, -0.0000000000000326862, 0.0000000000000096619, -0.0000000000000028935, 0.0000000000000008770, -0.0000000000000002688, 0.0000000000000000832, -0.0000000000000000260 }; static cheb_series aip1_cs = { aip1_data, 24, -1, 1, 14 }; /* series for bif on the interval -1.00000e+00 to 1.00000e+00 with weighted error 9.05e-18 log weighted error 17.04 significant figures required 15.83 decimal places required 17.49 */ static double bif_data[8] = { 0.1153536790828570243, 0.0205007894049192875, 0.0002135290278902876, 0.0000010783960614677, 0.0000000032094708833, 0.0000000000062930407, 0.0000000000000087403, 0.0000000000000000090 }; static cheb_series bif_cs = { bif_data, 7, -1, 1, 7 }; /* series for big on the interval -1.00000e+00 to 1.00000e+00 with weighted error 5.44e-19 log weighted error 18.26 significant figures required 17.46 decimal places required 18.74 */ static double big_data[9] = { -0.097196440416443537390, 0.149503576843167066571, 0.003113525387121326042, 0.000024708570579821297, 0.000000102949627731379, 0.000000000263970373987, 0.000000000000458279271, 0.000000000000000574283, 0.000000000000000000544 }; static cheb_series big_cs = { big_data, 8, -1, 1, 8 }; /* series for bif2 on the interval 1.00000e+00 to 8.00000e+00 with weighted error 3.82e-19 log weighted error 18.42 significant figures required 17.68 decimal places required 18.92 */ static double bif2_data[10] = { 0.323493987603522033521, 0.086297871535563559139, 0.002994025552655397426, 0.000051430528364661637, 0.000000525840250036811, 0.000000003561751373958, 0.000000000017146864007, 0.000000000000061663520, 0.000000000000000171911, 0.000000000000000000382 }; static cheb_series bif2_cs = { bif2_data, 9, -1, 1, 9 }; /* series for big2 on the interval 1.00000e+00 to 8.00000e+00 with weighted error 3.35e-17 log weighted error 16.48 significant figures required 16.52 decimal places required 16.98 */ static double big2_data[10] = { 1.6062999463621294578, 0.7449088819876088652, 0.0470138738610277380, 0.0012284422062548239, 0.0000173222412256624, 0.0000001521901652368, 0.0000000009113560249, 0.0000000000039547918, 0.0000000000000130017, 0.0000000000000000335 }; static cheb_series big2_cs = { big2_data, 9, -1, 1, 9 }; /* series for bip2 on the interval 0.00000e+00 to 1.25000e-01 with weighted error 2.07e-18 log weighted error 17.69 significant figures required 16.51 decimal places required 18.42 */ static double bip2_data[29] = { -0.13269705443526630495, -0.00568443626045977481, -0.00015643601119611610, -0.00001136737203679562, -0.00000143464350991284, -0.00000018098531185164, 0.00000000926177343611, 0.00000001710005490721, 0.00000000476698163504, -0.00000000035195022023, -0.00000000058890614316, -0.00000000006678499608, 0.00000000006395565102, 0.00000000001554529427, -0.00000000000792397000, -0.00000000000258326243, 0.00000000000121655048, 0.00000000000038707207, -0.00000000000022487045, -0.00000000000004953477, 0.00000000000004563782, 0.00000000000000332998, -0.00000000000000921750, 0.00000000000000094157, 0.00000000000000167154, -0.00000000000000055134, -0.00000000000000022369, 0.00000000000000017487, 0.00000000000000000207 }; static cheb_series bip2_cs = { bip2_data, 28, -1, 1, 14 }; /* series for bip1 on the interval 1.25000e-01 to 3.53553e-01 with weighted error 1.86e-17 log weighted error 16.73 significant figures required 15.67 decimal places required 17.42 */ static double bip1_data[24] = { -0.1729187351079553719, -0.0149358492984694364, -0.0005471104951678566, 0.0001537966292958408, 0.0000154353476192179, -0.0000065434113851906, 0.0000003728082407879, 0.0000002072078388189, -0.0000000658173336470, 0.0000000074926746354, 0.0000000011101336884, -0.0000000007265140553, 0.0000000001782723560, -0.0000000000217346352, -0.0000000000020302035, 0.0000000000019311827, -0.0000000000006044953, 0.0000000000001209450, -0.0000000000000125109, -0.0000000000000019917, 0.0000000000000015154, -0.0000000000000004977, 0.0000000000000001155, -0.0000000000000000186 }; static cheb_series bip1_cs = { bip1_data, 23, -1, 1, 13 }; /* series for an22 on the interval -1.00000e+00 to -1.25000e-01 with weighted error 3.30e-17 log weighted error 16.48 significant figures required 14.95 decimal places required 17.24 */ static double an22_data[33] = { 0.0537418629629794329, -0.0126661435859883193, -0.0011924334106593007, -0.0002032327627275655, -0.0000446468963075164, -0.0000113359036053123, -0.0000031641352378546, -0.0000009446708886149, -0.0000002966562236472, -0.0000000969118892024, -0.0000000326822538653, -0.0000000113144618964, -0.0000000040042691002, -0.0000000014440333684, -0.0000000005292853746, -0.0000000001967763374, -0.0000000000740800096, -0.0000000000282016314, -0.0000000000108440066, -0.0000000000042074801, -0.0000000000016459150, -0.0000000000006486827, -0.0000000000002574095, -0.0000000000001027889, -0.0000000000000412846, -0.0000000000000166711, -0.0000000000000067657, -0.0000000000000027585, -0.0000000000000011296, -0.0000000000000004645, -0.0000000000000001917, -0.0000000000000000794, -0.0000000000000000330 }; static cheb_series an22_cs = { an22_data, 32, -1, 1, 18 }; /* series for an21 on the interval -1.25000e-01 to -1.56250e-02 with weighted error 3.43e-17 log weighted error 16.47 significant figures required 14.48 decimal places required 17.16 */ static double an21_data[24] = { 0.0198313155263169394, -0.0029376249067087533, -0.0001136260695958196, -0.0000100554451087156, -0.0000013048787116563, -0.0000002123881993151, -0.0000000402270833384, -0.0000000084996745953, -0.0000000019514839426, -0.0000000004783865344, -0.0000000001236733992, -0.0000000000334137486, -0.0000000000093702824, -0.0000000000027130128, -0.0000000000008075954, -0.0000000000002463214, -0.0000000000000767656, -0.0000000000000243883, -0.0000000000000078831, -0.0000000000000025882, -0.0000000000000008619, -0.0000000000000002908, -0.0000000000000000993, -0.0000000000000000343 }; static cheb_series an21_cs = { an21_data, 23, -1, 1, 12 }; /* series for an20 on the interval -1.56250e-02 to 0.00000e+00 with weighted error 4.41e-17 log weighted error 16.36 significant figures required 14.16 decimal places required 16.96 */ static double an20_data[16] = { 0.0126732217145738027, -0.0005212847072615621, -0.0000052672111140370, -0.0000001628202185026, -0.0000000090991442687, -0.0000000007438647126, -0.0000000000795494752, -0.0000000000104050944, -0.0000000000015932426, -0.0000000000002770648, -0.0000000000000535343, -0.0000000000000113062, -0.0000000000000025772, -0.0000000000000006278, -0.0000000000000001621, -0.0000000000000000441 }; static cheb_series an20_cs = { an20_data, 15, -1, 1, 8 }; /* series for aph2 on the interval -1.00000e+00 to -1.25000e-01 with weighted error 2.94e-17 log weighted error 16.53 significant figures required 15.58 decimal places required 17.28 */ static double aph2_data[32] = { -0.2057088719781465107, 0.0422196961357771922, 0.0020482560511207275, 0.0002607800735165006, 0.0000474824268004729, 0.0000105102756431612, 0.0000026353534014668, 0.0000007208824863499, 0.0000002103236664473, 0.0000000644975634555, 0.0000000205802377264, 0.0000000067836273921, 0.0000000022974015284, 0.0000000007961306765, 0.0000000002813860610, 0.0000000001011749057, 0.0000000000369306738, 0.0000000000136615066, 0.0000000000051142751, 0.0000000000019351689, 0.0000000000007393607, 0.0000000000002849792, 0.0000000000001107281, 0.0000000000000433412, 0.0000000000000170801, 0.0000000000000067733, 0.0000000000000027017, 0.0000000000000010835, 0.0000000000000004367, 0.0000000000000001769, 0.0000000000000000719, 0.0000000000000000294 }; static cheb_series aph2_cs = { aph2_data, 31, -1, 1, 16 }; /* series for aph1 on the interval -1.25000e-01 to -1.56250e-02 with weighted error 6.38e-17 log weighted error 16.20 significant figures required 14.91 decimal places required 16.87 */ static double aph1_data[22] = { -0.1024172908077571694, 0.0071697275146591248, 0.0001209959363122329, 0.0000073361512841220, 0.0000007535382954272, 0.0000001041478171741, 0.0000000174358728519, 0.0000000033399795033, 0.0000000007073075174, 0.0000000001619187515, 0.0000000000394539982, 0.0000000000101192282, 0.0000000000027092778, 0.0000000000007523806, 0.0000000000002156369, 0.0000000000000635283, 0.0000000000000191757, 0.0000000000000059143, 0.0000000000000018597, 0.0000000000000005950, 0.0000000000000001934, 0.0000000000000000638 }; static cheb_series aph1_cs = { aph1_data, 21, -1, 1, 10 }; /* series for aph0 on the interval -1.56250e-02 to 0.00000e+00 with weighted error 2.29e-17 log weighted error 16.64 significant figures required 15.27 decimal places required 17.23 */ static double aph0_data[15] = { -0.0855849241130933257, 0.0011214378867065261, 0.0000042721029353664, 0.0000000817607381483, 0.0000000033907645000, 0.0000000002253264423, 0.0000000000206284209, 0.0000000000023858763, 0.0000000000003301618, 0.0000000000000527010, 0.0000000000000094555, 0.0000000000000018709, 0.0000000000000004024, 0.0000000000000000930, 0.0000000000000000229 }; static cheb_series aph0_cs = { aph0_data, 14, -1, 1, 7 }; static int airy_deriv_mod_phase(const double x, gsl_mode_t mode, gsl_sf_result * ampl, gsl_sf_result * phi) { const double pi34 = 2.356194490192344928847; gsl_sf_result result_a; gsl_sf_result result_p; double a, p; double sqx; double x32; if(x <= -4.0) { double z = 128.0/(x*x*x) + 1.0; cheb_eval_mode_e(&an20_cs, z, mode, &result_a); cheb_eval_mode_e(&aph0_cs, z, mode, &result_p); } else if(x <= -2.0) { double z = (128.0/(x*x*x) + 9.0) / 7.0; cheb_eval_mode_e(&an21_cs, z, mode, &result_a); cheb_eval_mode_e(&aph1_cs, z, mode, &result_p); } else if(x <= -1.0) { double z = (16.0/(x*x*x) + 9.0) / 7.0; cheb_eval_mode_e(&an22_cs, z, mode, &result_a); cheb_eval_mode_e(&aph2_cs, z, mode, &result_p); } else { ampl->val = 0.0; ampl->err = 0.0; phi->val = 0.0; phi->err = 0.0; GSL_ERROR ("x is greater than 1.0", GSL_EDOM); } a = 0.3125 + result_a.val; p = -0.625 + result_p.val; sqx = sqrt(-x); x32 = x*sqx; ampl->val = sqrt(a * sqx); ampl->err = fabs(ampl->val) * (GSL_DBL_EPSILON + fabs(result_a.err/result_a.val)); phi->val = pi34 - x * sqx * p; phi->err = fabs(phi->val) * (GSL_DBL_EPSILON + fabs(result_p.err/result_p.val)); return GSL_SUCCESS; } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_airy_Ai_deriv_scaled_e(const double x, gsl_mode_t mode, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x < -1.0) { gsl_sf_result a; gsl_sf_result p; int status_ap = airy_deriv_mod_phase(x, mode, &a, &p); double c = cos(p.val); result->val = a.val * c; result->err = fabs(result->val * p.err) + fabs(c * a.err); result->err += GSL_DBL_EPSILON * fabs(result->val); return status_ap; } else if(x <= 1.0) { const double x3 = x*x*x; const double x2 = x*x; gsl_sf_result result_c0; gsl_sf_result result_c1; cheb_eval_mode_e(&aif_cs, x3, mode, &result_c0); cheb_eval_mode_e(&aig_cs, x3, mode, &result_c1); result->val = (x2*(0.125 + result_c0.val) - result_c1.val) - 0.25; result->err = fabs(x2*result_c0.val) + result_c1.err; result->err += GSL_DBL_EPSILON * fabs(result->val); if(x > GSL_ROOT3_DBL_EPSILON*GSL_ROOT3_DBL_EPSILON) { /* scale only if x is positive */ double s = exp(2.0*x*sqrt(x)/3.0); result->val *= s; result->err *= s; } return GSL_SUCCESS; } else if(x <= 4.0) { const double sqrtx = sqrt(x); const double z = (16.0/(x*sqrtx) - 9.0)/7.0; const double s = sqrt(sqrtx); gsl_sf_result result_c0; cheb_eval_mode_e(&aip1_cs, z, mode, &result_c0); result->val = -(0.28125 + result_c0.val) * s; result->err = result_c0.err * s; result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { const double sqrtx = sqrt(x); const double z = 16.0/(x*sqrtx) - 1.0; const double s = sqrt(sqrtx); gsl_sf_result result_c0; cheb_eval_mode_e(&aip2_cs, z, mode, &result_c0); result->val = -(0.28125 + result_c0.val) * s; result->err = result_c0.err * s; result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_airy_Ai_deriv_e(const double x, gsl_mode_t mode, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x < -1.0) { gsl_sf_result a; gsl_sf_result p; int status_ap = airy_deriv_mod_phase(x, mode, &a, &p); double c = cos(p.val); result->val = a.val * c; result->err = fabs(result->val * p.err) + fabs(c * a.err); result->err += GSL_DBL_EPSILON * fabs(result->val); return status_ap; } else if(x < 1.0) { const double x3 = x*x*x; gsl_sf_result result_c1; gsl_sf_result result_c2; cheb_eval_mode_e(&aif_cs, x3, mode, &result_c1); cheb_eval_mode_e(&aig_cs, x3, mode, &result_c2); result->val = (x*x*(0.125 + result_c1.val) - result_c2.val) - 0.25; result->err = fabs(x*x*result_c1.err) + result_c2.err; result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x*x*x < 9.0/4.0 * GSL_LOG_DBL_MIN*GSL_LOG_DBL_MIN) { gsl_sf_result result_aps; const double arg = -2.0*x*sqrt(x)/3.0; const int stat_a = gsl_sf_airy_Ai_deriv_scaled_e(x, mode, &result_aps); const int stat_e = gsl_sf_exp_mult_err_e(arg, 1.5*fabs(arg*GSL_DBL_EPSILON), result_aps.val, result_aps.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_a); } else { UNDERFLOW_ERROR(result); } } int gsl_sf_airy_Bi_deriv_scaled_e(const double x, gsl_mode_t mode, gsl_sf_result * result) { const double atr = 8.7506905708484345; /* 16./(sqrt(8)-1) */ const double btr = -2.0938363213560543; /* -(sqrt(8)+1)/(sqrt(8)-1) */ /* CHECK_POINTER(result) */ if(x < -1.0) { gsl_sf_result a; gsl_sf_result p; int status_ap = airy_deriv_mod_phase(x, mode, &a, &p); double s = sin(p.val); result->val = a.val * s; result->err = fabs(result->val * p.err) + fabs(s * a.err); result->err += GSL_DBL_EPSILON * fabs(result->val); return status_ap; } else if(x < 1.0) { const double x3 = x*x*x; const double x2 = x*x; gsl_sf_result result_c1; gsl_sf_result result_c2; cheb_eval_mode_e(&bif_cs, x3, mode, &result_c1); cheb_eval_mode_e(&big_cs, x3, mode, &result_c2); result->val = x2 * (result_c1.val + 0.25) + result_c2.val + 0.5; result->err = x2 * result_c1.err + result_c2.err; result->err += GSL_DBL_EPSILON * fabs(result->val); if(x > GSL_ROOT3_DBL_EPSILON*GSL_ROOT3_DBL_EPSILON) { /* scale only if x is positive */ const double s = exp(-2.0*x*sqrt(x)/3.0); result->val *= s; result->err *= s; } return GSL_SUCCESS; } else if(x < 2.0) { const double z = (2.0*x*x*x - 9.0) / 7.0; const double s = exp(-2.0*x*sqrt(x)/3.0); gsl_sf_result result_c0; gsl_sf_result result_c1; cheb_eval_mode_e(&bif2_cs, z, mode, &result_c0); cheb_eval_mode_e(&big2_cs, z, mode, &result_c1); result->val = s * (x*x * (0.25 + result_c0.val) + 0.5 + result_c1.val); result->err = s * (x*x * result_c0.err + result_c1.err); result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < 4.0) { const double sqrtx = sqrt(x); const double z = atr/(x*sqrtx) + btr; const double s = sqrt(sqrtx); gsl_sf_result result_c0; cheb_eval_mode_e(&bip1_cs, z, mode, &result_c0); result->val = s * (0.625 + result_c0.val); result->err = s * result_c0.err; result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { const double sqrtx = sqrt(x); const double z = 16.0/(x*sqrtx) - 1.0; const double s = sqrt(sqrtx); gsl_sf_result result_c0; cheb_eval_mode_e(&bip2_cs, z, mode, &result_c0); result->val = s * (0.625 + result_c0.val); result->err = s * result_c0.err; result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_airy_Bi_deriv_e(const double x, gsl_mode_t mode, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x < -1.0) { gsl_sf_result a; gsl_sf_result p; int status_ap = airy_deriv_mod_phase(x, mode, &a, &p); double s = sin(p.val); result->val = a.val * s; result->err = fabs(result->val * p.err) + fabs(s * a.err); result->err += GSL_DBL_EPSILON * fabs(result->val); return status_ap; } else if(x < 1.0) { const double x3 = x*x*x; const double x2 = x*x; gsl_sf_result result_c1; gsl_sf_result result_c2; cheb_eval_mode_e(&bif_cs, x3, mode, &result_c1); cheb_eval_mode_e(&big_cs, x3, mode, &result_c2); result->val = x2 * (result_c1.val + 0.25) + result_c2.val + 0.5; result->err = x2 * result_c1.err + result_c2.err; result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < 2.0) { const double z = (2.0*x*x*x - 9.0) / 7.0; gsl_sf_result result_c1; gsl_sf_result result_c2; cheb_eval_mode_e(&bif2_cs, z, mode, &result_c1); cheb_eval_mode_e(&big2_cs, z, mode, &result_c2); result->val = x*x * (result_c1.val + 0.25) + result_c2.val + 0.5; result->err = x*x * result_c1.err + result_c2.err; result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < GSL_ROOT3_DBL_MAX*GSL_ROOT3_DBL_MAX) { gsl_sf_result result_bps; const double arg = 2.0*(x*sqrt(x)/3.0); int stat_b = gsl_sf_airy_Bi_deriv_scaled_e(x, mode, &result_bps); int stat_e = gsl_sf_exp_mult_err_e(arg, 1.5*fabs(arg*GSL_DBL_EPSILON), result_bps.val, result_bps.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_b); } else { OVERFLOW_ERROR(result); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_airy_Ai_deriv_scaled(const double x, gsl_mode_t mode) { EVAL_RESULT(gsl_sf_airy_Ai_deriv_scaled_e(x, mode, &result)); } double gsl_sf_airy_Ai_deriv(const double x, gsl_mode_t mode) { EVAL_RESULT(gsl_sf_airy_Ai_deriv_e(x, mode, &result)); } double gsl_sf_airy_Bi_deriv_scaled(const double x, gsl_mode_t mode) { EVAL_RESULT(gsl_sf_airy_Bi_deriv_scaled_e(x, mode, &result)); } double gsl_sf_airy_Bi_deriv(const double x, gsl_mode_t mode) { EVAL_RESULT(gsl_sf_airy_Bi_deriv_e(x, mode, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__airy_zero.c000066400000000000000000000325321261542461700223750ustar00rootroot00000000000000/* specfunc/airy_zero.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_airy.h" #include "gsl_specfunc__error.h" static const double zero_Ai[] = { 0, -2.338107410459767039, -4.087949444130970617, -5.520559828095551059, -6.786708090071758999, -7.944133587120853123, -9.022650853340980380, -10.04017434155808593, -11.00852430373326289, -11.93601556323626252, -12.82877675286575720, -13.69148903521071793, -14.52782995177533498, -15.34075513597799686, -16.13268515694577144, -16.90563399742994263, -17.661300105697057509, -18.401132599207115416, -19.126380474246952144, -19.838129891721499701, -20.537332907677566360, -21.224829943642096955, -21.901367595585130707, -22.567612917496502831, -23.224165001121681061, -23.871564455535918567, -24.510301236589677490, -25.140821166148963748, -25.763531400982756459, -26.378805052137232374, -26.986985111606367686, -27.588387809882444812, -28.183305502632644923, -28.772009165237435382, -29.354750558766287963, -29.931764119086555913, -30.503268611418505287, -31.069468585183755604, -31.63055565801265934, -32.18670965295205069, -32.73809960900026913, -33.28488468190140188, -33.82721494950865194, -34.36523213386365906, -34.89907025034531210, -35.42885619274788846, -35.95471026189862926, -36.47674664437480896, -36.99507384699450161, -37.50979509200501613, -38.02100867725525443, -38.52880830509424882, -39.03328338327251391, -39.53451930072301805, -40.03259768075417603, -40.52759661388971821, -41.01959087233248966, -41.50865210780525018, -41.99484903432643004, -42.47824759730839188, -42.95891113021656009, -43.43690049989685412, -43.91227424156370168, -44.38508868433939023, -44.85539806814583243, -45.32325465267043011, -45.78870881905730086, -46.25180916491254629, -46.71260259315651633, -47.17113439520631705, -47.62744832892739292, -48.08158669175325711, -48.53359038933679845, -48.98349900006458366, -49.43135083573678341, -49.87718299868941729, -50.32103143561221860, -50.76293098829428522, -51.20291544151056412, -51.64101756824489758, -52.07726917242964943, -52.51170112936766183, -52.94434342398931824, -53.37522518708567514, -53.80437472964785717, -54.23181957543308298, -54.65758649186871111, -55.08170151939748312, -55.50418999935962251, -55.92507660050055598, -56.34438534418670066, -56.76213962840595327, -57.17836225062417808, -57.59307542956407782, -58.00630082596830627, -58.41805956240450934, -58.82837224216613231, -59.23725896731927534, -59.64473935594259360, -60.05083255860419805, -60.45555727411669871 }; static const size_t size_zero_Ai = sizeof(zero_Ai)/sizeof(double); static const double zero_Bi[] = { 0, -1.173713222709127925, -3.271093302836352716, -4.830737841662015933, -6.169852128310251260, -7.376762079367763714, -8.491948846509388013, -9.538194379346238887, -10.52991350670535792, -11.47695355127877944, -12.38641713858273875, -13.26363952294180555, -14.11275680906865779, -14.93705741215416404, -15.739210351190482771, -16.521419550634379054, -17.285531624581242533, -18.033113287225001572, -18.765508284480081041, -19.483880132989234014, -20.189244785396202420, -20.882495994193175768, -21.564425284712977653, -22.235737881803385167, -22.897065554219793474, -23.548977079642448269, -24.191986850649000086, -24.826562012152892172, -25.453128427085131994, -26.072075698466804494, -26.683761425120990449, -27.288514830076298204, -27.886639871735962459, -28.478417925678661737, -29.064110107777650305, -29.643959295918396591, -30.218191897047274645, -30.787019397921766297, -31.350639731255585371, -31.90923848358456965, -32.46298996683685318, -33.01205817205683814, -33.55659762084006113, -34.09675412765602851, -34.63266548426775468, -35.16446207582101720, -35.69226743681080479, -36.21619875398748222, -36.73636732230120657, -37.25287895916828697, -37.76583438165180116, -38.27532955056003997, -38.78145598496327279, -39.28430105019802461, -39.78394822205711298, -40.28047732954369150, -40.77396477829068148, -41.26448375650675678, -41.75210442510106287, -42.23689409345656643, -42.71891738216253539, -43.19823637387693118, -43.67491075336673948, -44.14899793766617113, -44.62055319719727274, -45.08962976861312825, -45.55627896004907928, -46.02055024940102076, -46.48249137619078661, -46.94214842752602207, -47.39956591861496210, -47.85478686825452176, -48.30785286967246692, -48.75880415707066192, -49.20767966818603897, -49.65451710315861501, -50.09935297997125482, -50.54222268670364757, -50.98316053082286586, -51.42219978571468262, -51.85937273464332870, -52.29471071231240525, -52.72824414418606069, -53.16000258371716397, -53.59001474761792882, -54.01830854929815828, -54.44491113058688729, -54.86984889184461534, -55.29314752056546491, -55.71483201856140365, -56.13492672781406761, -56.55345535507366411, -56.97044099527886475, -57.38590615386647834, -57.79987276803497897, -58.21236222702161974, -58.62339539144885603, -59.03299261179210306, -59.44117374601743460, -59.84795817643466996, -60.25336482580837088 }; static const size_t size_zero_Bi = sizeof(zero_Bi)/sizeof(double); static const double zero_Aip[] = { 0, -1.018792971647471089, -3.248197582179836738, -4.820099211178735639, -6.163307355639486822, -7.372177255047770177, -8.488486734019722133, -9.535449052433547471, -10.52766039695740728, -11.47505663348024529, -12.384788371845747325, -13.262218961665210382, -14.111501970462995282, -14.935937196720517467, -15.738201373692538303, -16.520503825433793542, -17.284695050216437357, -18.032344622504393395, -18.764798437665954740, -19.483221656567231178, -20.188631509463373154, -20.881922755516737701, -21.563887723198974958, -22.235232285348913331, -22.896588738874619001, -23.548526295928801574, -24.191559709526353841, -24.826156425921155001, -25.452742561777649948, -26.071707935173912515, -26.683410328322449767, -27.288179121523985029, -27.886318408768461192, -28.478109683102278108, -29.063814162638199090, -29.643674814632015921, -30.217918124468574603, -30.786755648012502519, -31.350385379083034671, -31.90899295843046320, -32.46275274623847982, -33.01182877663428709, -33.55637560978942190, -34.09653909480913771, -34.63245705463586589, -35.16425990255340758, -35.69207119851046870, -36.21600815233519918, -36.73618207994680321, -37.25269881785414827, -37.76565910053887108, -38.27515890473087933, -38.78128976408036876, -39.28413905729859644, -39.78379027246823278, -40.28032324990371935, -40.77381440566486637, -41.26433693758643383, -41.75196101547722703, -42.23675395695976012, -42.71878039026198233, -43.19810240513270670, -43.67477969292950869, -44.14886967681966886, -44.62042763293925724, -45.08950680327102630, -45.55615850092696446, -46.02043220845493728, -46.48237566972975615, -46.94203497593635633, -47.39945464610575493, -47.85467770262241617, -48.30774574208398774, -48.75869900186057804, -49.20757642267037247, -49.65441570746105074, -50.09925337686182515, -50.54212482144867502, -50.98306435104524282, -51.42210524126365311, -51.85927977747301469, -52.29461929636838876, -52.72815422529939506, -53.15991411950524351, -53.58992769739169611, -54.01822287397517367, -54.44482679260982599, -54.86976585510479430, -55.29306575033103518, -55.71475148140987392, -56.13484739156885235, -56.55337718874437424, -56.97036396900508167, -57.38583023886477265, -57.79979793654895377, -58.21228845227477578, -58.62332264760009139, -59.03292087389367419, -59.44110298997521892, -59.84788837897058171, -60.25329596442479317 }; static const size_t size_zero_Aip = sizeof(zero_Aip)/sizeof(double); static const double zero_Bip[] = { 0, -2.294439682614123247, -4.073155089071828216, -5.512395729663599496, -6.781294445990305390, -7.940178689168578927, -9.019583358794239067, -10.037696334908545802, -11.006462667712289940, -11.934261645014844663, -12.827258309177217640, -13.690155826835049101, -14.526645763485711410, -15.339693082242404109, -16.131724782385900578, -16.904759411889649958, -17.660498743114976102, -18.400394367181703280, -19.125697156412638066, -19.837494718415910503, -20.536740241453273980, -21.224275044889266569, -21.900846445139208281, -22.567122080497200470, -23.223701521208962116, -23.871125771677973595, -24.509885117016242729, -25.140425655367878908, -25.763154776913454319, -26.378445791146615697, -26.986641859775034987, -27.588059359225600573, -28.182990771292975456, -28.771707180886056250, -29.354460444612957224, -29.931485082026055160, -30.502999931936645516, -31.069209608721234058, -31.63030578754333679, -32.18646834257807369, -32.73786635840274752, -33.28465903151424981, -33.82699647630635587, -34.36502044767239631, -34.89886499060196419, -35.42865702564380962, -35.95451687785511190, -36.47655875580547918, -36.99489118631672770, -37.50961740986809593, -38.02083574095788210 }; static const size_t size_zero_Bip = sizeof(zero_Bip)/sizeof(double); /* [Abramowitz+Stegun, 10.4.105] */ static double zero_f(double z) { const double pre = pow(z, 2.0/3.0); const double zi2 = 1.0/(z*z); const double zi4 = zi2 * zi2; const double t1 = 5.0/48.0 * zi2; const double t2 = -5.0/36.0 * zi4; const double t3 = 77125.0/82944.0 * zi4 * zi2; const double t4 = -108056875.0/6967296.0 * zi4 * zi4; return pre * (1.0 + t1 + t2 + t3 + t4); } static double zero_g(double z) { const double pre = pow(z, 2.0/3.0); const double zi2 = 1.0/(z*z); const double zi4 = zi2 * zi2; const double t1 = -7.0/48.0 * zi2; const double t2 = 35.0/288.0 * zi4; const double t3 = -181223.0/207360.0 * zi4 * zi2; const double t4 = 18683371.0/1244160.0 * zi4 * zi4; return pre * (1.0 + t1 + t2 + t3 + t4); } int gsl_sf_airy_zero_Ai_e(unsigned int s, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(s < 1) { DOMAIN_ERROR_MSG("s is less than 1", result); } else if(s < size_zero_Ai) { result->val = zero_Ai[s]; result->err = GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { const double z = 3.0*M_PI/8.0 * (4.0*s - 1.0); const double f = zero_f(z); result->val = -f; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_airy_zero_Bi_e(unsigned int s, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(s < 1) { DOMAIN_ERROR_MSG("s is less than 1", result); } else if(s < size_zero_Bi) { result->val = zero_Bi[s]; result->err = GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { const double z = 3.0*M_PI/8.0 * (4.0*s - 3.0); const double f = zero_f(z); result->val = -f; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_airy_zero_Ai_deriv_e(unsigned int s, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(s < 1) { DOMAIN_ERROR_MSG("s is less than 1", result); } else if(s < size_zero_Aip) { result->val = zero_Aip[s]; result->err = GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { const double z = 3.0*M_PI/8.0 * (4.0*s - 3.0); const double g = zero_g(z); result->val = -g; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_airy_zero_Bi_deriv_e(unsigned int s, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(s < 1) { DOMAIN_ERROR_MSG("s is less than 1", result); } else if(s < size_zero_Bip) { result->val = zero_Bip[s]; result->err = GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { const double z = 3.0*M_PI/8.0 * (4.0*s - 1.0); const double g = zero_g(z); result->val = -g; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_airy_zero_Ai(unsigned int s) { EVAL_RESULT(gsl_sf_airy_zero_Ai_e(s, &result)); } double gsl_sf_airy_zero_Bi(unsigned int s) { EVAL_RESULT(gsl_sf_airy_zero_Bi_e(s, &result)); } double gsl_sf_airy_zero_Ai_deriv(unsigned int s) { EVAL_RESULT(gsl_sf_airy_zero_Ai_deriv_e(s, &result)); } double gsl_sf_airy_zero_Bi_deriv(unsigned int s) { EVAL_RESULT(gsl_sf_airy_zero_Bi_deriv_e(s, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__atanint.c000066400000000000000000000057371261542461700220370ustar00rootroot00000000000000/* specfunc/atanint.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_mode.h" #include "gsl_sf_expint.h" #include "gsl_specfunc__chebyshev.h" #include "gsl_specfunc__cheb_eval.c" static double atanint_data[21] = { 1.91040361296235937512, -0.4176351437656746940e-01, 0.275392550786367434e-02, -0.25051809526248881e-03, 0.2666981285121171e-04, -0.311890514107001e-05, 0.38833853132249e-06, -0.5057274584964e-07, 0.681225282949e-08, -0.94212561654e-09, 0.13307878816e-09, -0.1912678075e-10, 0.278912620e-11, -0.41174820e-12, 0.6142987e-13, -0.924929e-14, 0.140387e-14, -0.21460e-15, 0.3301e-16, -0.511e-17, 0.79e-18, }; static cheb_series atanint_cs = { atanint_data, 20, -1, 1, 10 }; /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_atanint_e(const double x, gsl_sf_result * result) { const double ax = fabs(x); const double sgn = GSL_SIGN(x); /* CHECK_POINTER(result) */ if(ax == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(ax < 0.5*GSL_SQRT_DBL_EPSILON) { result->val = x; result->err = 0.0; return GSL_SUCCESS; } else if(ax <= 1.0) { const double t = 2.0 * (x*x - 0.5); gsl_sf_result result_c; cheb_eval_e(&atanint_cs, t, &result_c); result->val = x * result_c.val; result->err = x * result_c.err; result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(ax < 1.0/GSL_SQRT_DBL_EPSILON) { const double t = 2.0 * (1.0/(x*x) - 0.5); gsl_sf_result result_c; cheb_eval_e(&atanint_cs, t, &result_c); result->val = sgn * (0.5*M_PI*log(ax) + result_c.val/ax); result->err = result_c.err/ax + fabs(result->val*GSL_DBL_EPSILON); result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { result->val = sgn * 0.5*M_PI*log(ax); result->err = 2.0 * fabs(result->val * GSL_DBL_EPSILON); return GSL_SUCCESS; } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_atanint(const double x) { EVAL_RESULT(gsl_sf_atanint_e(x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__bessel.c000066400000000000000000000645311261542461700216530ustar00rootroot00000000000000/* specfunc/bessel.c * * Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ /* Miscellaneous support functions for Bessel function evaluations. */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_airy.h" #include "gsl_sf_elementary.h" #include "gsl_sf_exp.h" #include "gsl_sf_gamma.h" #include "gsl_sf_trig.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__bessel_amp_phase.h" #include "gsl_specfunc__bessel_temme.h" #include "gsl_specfunc__bessel.h" #define CubeRoot2_ 1.25992104989487316476721060728 /* Debye functions [Abramowitz+Stegun, 9.3.9-10] */ inline static double debye_u1(const double * tpow) { return (3.0*tpow[1] - 5.0*tpow[3])/24.0; } inline static double debye_u2(const double * tpow) { return (81.0*tpow[2] - 462.0*tpow[4] + 385.0*tpow[6])/1152.0; } inline static double debye_u3(const double * tpow) { return (30375.0*tpow[3] - 369603.0*tpow[5] + 765765.0*tpow[7] - 425425.0*tpow[9])/414720.0; } inline static double debye_u4(const double * tpow) { return (4465125.0*tpow[4] - 94121676.0*tpow[6] + 349922430.0*tpow[8] - 446185740.0*tpow[10] + 185910725.0*tpow[12])/39813120.0; } inline static double debye_u5(const double * tpow) { return (1519035525.0*tpow[5] - 49286948607.0*tpow[7] + 284499769554.0*tpow[9] - 614135872350.0*tpow[11] + 566098157625.0*tpow[13] - 188699385875.0*tpow[15])/6688604160.0; } #if 0 inline static double debye_u6(const double * tpow) { return (2757049477875.0*tpow[6] - 127577298354750.0*tpow[8] + 1050760774457901.0*tpow[10] - 3369032068261860.0*tpow[12] + 5104696716244125.0*tpow[14] - 3685299006138750.0*tpow[16] + 1023694168371875.0*tpow[18])/4815794995200.0; } #endif /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_bessel_IJ_taylor_e(const double nu, const double x, const int sign, const int kmax, const double threshold, gsl_sf_result * result ) { /* CHECK_POINTER(result) */ if(nu < 0.0 || x < 0.0) { DOMAIN_ERROR(result); } else if(x == 0.0) { if(nu == 0.0) { result->val = 1.0; result->err = 0.0; } else { result->val = 0.0; result->err = 0.0; } return GSL_SUCCESS; } else { gsl_sf_result prefactor; /* (x/2)^nu / Gamma(nu+1) */ gsl_sf_result sum; int stat_pre; int stat_sum; int stat_mul; if(nu == 0.0) { prefactor.val = 1.0; prefactor.err = 0.0; stat_pre = GSL_SUCCESS; } else if(nu < INT_MAX-1) { /* Separate the integer part and use * y^nu / Gamma(nu+1) = y^N /N! y^f / (N+1)_f, * to control the error. */ const int N = (int)floor(nu + 0.5); const double f = nu - N; gsl_sf_result poch_factor; gsl_sf_result tc_factor; const int stat_poch = gsl_sf_poch_e(N+1.0, f, &poch_factor); const int stat_tc = gsl_sf_taylorcoeff_e(N, 0.5*x, &tc_factor); const double p = pow(0.5*x,f); prefactor.val = tc_factor.val * p / poch_factor.val; prefactor.err = tc_factor.err * p / poch_factor.val; prefactor.err += fabs(prefactor.val) / poch_factor.val * poch_factor.err; prefactor.err += 2.0 * GSL_DBL_EPSILON * fabs(prefactor.val); stat_pre = GSL_ERROR_SELECT_2(stat_tc, stat_poch); } else { gsl_sf_result lg; const int stat_lg = gsl_sf_lngamma_e(nu+1.0, &lg); const double term1 = nu*log(0.5*x); const double term2 = lg.val; const double ln_pre = term1 - term2; const double ln_pre_err = GSL_DBL_EPSILON * (fabs(term1)+fabs(term2)) + lg.err; const int stat_ex = gsl_sf_exp_err_e(ln_pre, ln_pre_err, &prefactor); stat_pre = GSL_ERROR_SELECT_2(stat_ex, stat_lg); } /* Evaluate the sum. * [Abramowitz+Stegun, 9.1.10] * [Abramowitz+Stegun, 9.6.7] */ { const double y = sign * 0.25 * x*x; double sumk = 1.0; double term = 1.0; int k; for(k=1; k<=kmax; k++) { term *= y/((nu+k)*k); sumk += term; if(fabs(term/sumk) < threshold) break; } sum.val = sumk; sum.err = threshold * fabs(sumk); stat_sum = ( k >= kmax ? GSL_EMAXITER : GSL_SUCCESS ); } stat_mul = gsl_sf_multiply_err_e(prefactor.val, prefactor.err, sum.val, sum.err, result); return GSL_ERROR_SELECT_3(stat_mul, stat_pre, stat_sum); } } /* x >> nu*nu+1 * error ~ O( ((nu*nu+1)/x)^4 ) * * empirical error analysis: * choose GSL_ROOT4_MACH_EPS * x > (nu*nu + 1) * * This is not especially useful. When the argument gets * large enough for this to apply, the cos() and sin() * start loosing digits. However, this seems inevitable * for this particular method. * * Wed Jun 25 14:39:38 MDT 2003 [GJ] * This function was inconsistent since the Q term did not * go to relative order eps^2. That's why the error estimate * originally given was screwy (it didn't make sense that the * "empirical" error was coming out O(eps^3)). * With Q to proper order, the error is O(eps^4). */ int gsl_sf_bessel_Jnu_asympx_e(const double nu, const double x, gsl_sf_result * result) { double mu = 4.0*nu*nu; double mum1 = mu-1.0; double mum9 = mu-9.0; double mum25 = mu-25.0; double chi = x - (0.5*nu + 0.25)*M_PI; double P = 1.0 - mum1*mum9/(128.0*x*x); double Q = mum1/(8.0*x) * (1.0 - mum9*mum25/(384.0*x*x)); double pre = sqrt(2.0/(M_PI*x)); double c = cos(chi); double s = sin(chi); double r = mu/x; result->val = pre * (c*P - s*Q); result->err = pre * GSL_DBL_EPSILON * (1.0 + fabs(x)) * (fabs(c*P) + fabs(s*Q)); result->err += pre * fabs(0.1*r*r*r*r); return GSL_SUCCESS; } /* x >> nu*nu+1 */ int gsl_sf_bessel_Ynu_asympx_e(const double nu, const double x, gsl_sf_result * result) { double ampl; double theta; double alpha = x; double beta = -0.5*nu*M_PI; int stat_a = gsl_sf_bessel_asymp_Mnu_e(nu, x, &l); int stat_t = gsl_sf_bessel_asymp_thetanu_corr_e(nu, x, &theta); double sin_alpha = sin(alpha); double cos_alpha = cos(alpha); double sin_chi = sin(beta + theta); double cos_chi = cos(beta + theta); double sin_term = sin_alpha * cos_chi + sin_chi * cos_alpha; double sin_term_mag = fabs(sin_alpha * cos_chi) + fabs(sin_chi * cos_alpha); result->val = ampl * sin_term; result->err = fabs(ampl) * GSL_DBL_EPSILON * sin_term_mag; result->err += fabs(result->val) * 2.0 * GSL_DBL_EPSILON; if(fabs(alpha) > 1.0/GSL_DBL_EPSILON) { result->err *= 0.5 * fabs(alpha); } else if(fabs(alpha) > 1.0/GSL_SQRT_DBL_EPSILON) { result->err *= 256.0 * fabs(alpha) * GSL_SQRT_DBL_EPSILON; } return GSL_ERROR_SELECT_2(stat_t, stat_a); } /* x >> nu*nu+1 */ int gsl_sf_bessel_Inu_scaled_asympx_e(const double nu, const double x, gsl_sf_result * result) { double mu = 4.0*nu*nu; double mum1 = mu-1.0; double mum9 = mu-9.0; double pre = 1.0/sqrt(2.0*M_PI*x); double r = mu/x; result->val = pre * (1.0 - mum1/(8.0*x) + mum1*mum9/(128.0*x*x)); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val) + pre * fabs(0.1*r*r*r); return GSL_SUCCESS; } /* x >> nu*nu+1 */ int gsl_sf_bessel_Knu_scaled_asympx_e(const double nu, const double x, gsl_sf_result * result) { double mu = 4.0*nu*nu; double mum1 = mu-1.0; double mum9 = mu-9.0; double pre = sqrt(M_PI/(2.0*x)); double r = nu/x; result->val = pre * (1.0 + mum1/(8.0*x) + mum1*mum9/(128.0*x*x)); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val) + pre * fabs(0.1*r*r*r); return GSL_SUCCESS; } /* nu -> Inf; uniform in x > 0 [Abramowitz+Stegun, 9.7.7] * * error: * The error has the form u_N(t)/nu^N where 0 <= t <= 1. * It is not hard to show that |u_N(t)| is small for such t. * We have N=6 here, and |u_6(t)| < 0.025, so the error is clearly * bounded by 0.025/nu^6. This gives the asymptotic bound on nu * seen below as nu ~ 100. For general MACH_EPS it will be * nu > 0.5 / MACH_EPS^(1/6) * When t is small, the bound is even better because |u_N(t)| vanishes * as t->0. In fact u_N(t) ~ C t^N as t->0, with C ~= 0.1. * We write * err_N <= min(0.025, C(1/(1+(x/nu)^2))^3) / nu^6 * therefore * min(0.29/nu^2, 0.5/(nu^2+x^2)) < MACH_EPS^{1/3} * and this is the general form. * * empirical error analysis, assuming 14 digit requirement: * choose x > 50.000 nu ==> nu > 3 * choose x > 10.000 nu ==> nu > 15 * choose x > 2.000 nu ==> nu > 50 * choose x > 1.000 nu ==> nu > 75 * choose x > 0.500 nu ==> nu > 80 * choose x > 0.100 nu ==> nu > 83 * * This makes sense. For x << nu, the error will be of the form u_N(1)/nu^N, * since the polynomial term will be evaluated near t=1, so the bound * on nu will become constant for small x. Furthermore, increasing x with * nu fixed will decrease the error. */ int gsl_sf_bessel_Inu_scaled_asymp_unif_e(const double nu, const double x, gsl_sf_result * result) { int i; double z = x/nu; double root_term = hypot(1.0,z); double pre = 1.0/sqrt(2.0*M_PI*nu * root_term); double eta = root_term + log(z/(1.0+root_term)); double ex_arg = ( z < 1.0/GSL_ROOT3_DBL_EPSILON ? nu*(-z + eta) : -0.5*nu/z*(1.0 - 1.0/(12.0*z*z)) ); gsl_sf_result ex_result; int stat_ex = gsl_sf_exp_e(ex_arg, &ex_result); if(stat_ex == GSL_SUCCESS) { double t = 1.0/root_term; double sum; double tpow[16]; tpow[0] = 1.0; for(i=1; i<16; i++) tpow[i] = t * tpow[i-1]; sum = 1.0 + debye_u1(tpow)/nu + debye_u2(tpow)/(nu*nu) + debye_u3(tpow)/(nu*nu*nu) + debye_u4(tpow)/(nu*nu*nu*nu) + debye_u5(tpow)/(nu*nu*nu*nu*nu); result->val = pre * ex_result.val * sum; result->err = pre * ex_result.val / (nu*nu*nu*nu*nu*nu); result->err += pre * ex_result.err * fabs(sum); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { result->val = 0.0; result->err = 0.0; return stat_ex; } } /* nu -> Inf; uniform in x > 0 [Abramowitz+Stegun, 9.7.8] * * error: * identical to that above for Inu_scaled */ int gsl_sf_bessel_Knu_scaled_asymp_unif_e(const double nu, const double x, gsl_sf_result * result) { int i; double z = x/nu; double root_term = hypot(1.0,z); double pre = sqrt(M_PI/(2.0*nu*root_term)); double eta = root_term + log(z/(1.0+root_term)); double ex_arg = ( z < 1.0/GSL_ROOT3_DBL_EPSILON ? nu*(z - eta) : 0.5*nu/z*(1.0 + 1.0/(12.0*z*z)) ); gsl_sf_result ex_result; int stat_ex = gsl_sf_exp_e(ex_arg, &ex_result); if(stat_ex == GSL_SUCCESS) { double t = 1.0/root_term; double sum; double tpow[16]; tpow[0] = 1.0; for(i=1; i<16; i++) tpow[i] = t * tpow[i-1]; sum = 1.0 - debye_u1(tpow)/nu + debye_u2(tpow)/(nu*nu) - debye_u3(tpow)/(nu*nu*nu) + debye_u4(tpow)/(nu*nu*nu*nu) - debye_u5(tpow)/(nu*nu*nu*nu*nu); result->val = pre * ex_result.val * sum; result->err = pre * ex_result.err * fabs(sum); result->err += pre * ex_result.val / (nu*nu*nu*nu*nu*nu); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { result->val = 0.0; result->err = 0.0; return stat_ex; } } /* Evaluate J_mu(x),J_{mu+1}(x) and Y_mu(x),Y_{mu+1}(x) for |mu| < 1/2 */ int gsl_sf_bessel_JY_mu_restricted(const double mu, const double x, gsl_sf_result * Jmu, gsl_sf_result * Jmup1, gsl_sf_result * Ymu, gsl_sf_result * Ymup1) { /* CHECK_POINTER(Jmu) */ /* CHECK_POINTER(Jmup1) */ /* CHECK_POINTER(Ymu) */ /* CHECK_POINTER(Ymup1) */ if(x < 0.0 || fabs(mu) > 0.5) { Jmu->val = 0.0; Jmu->err = 0.0; Jmup1->val = 0.0; Jmup1->err = 0.0; Ymu->val = 0.0; Ymu->err = 0.0; Ymup1->val = 0.0; Ymup1->err = 0.0; GSL_ERROR ("error", GSL_EDOM); } else if(x == 0.0) { if(mu == 0.0) { Jmu->val = 1.0; Jmu->err = 0.0; } else { Jmu->val = 0.0; Jmu->err = 0.0; } Jmup1->val = 0.0; Jmup1->err = 0.0; Ymu->val = 0.0; Ymu->err = 0.0; Ymup1->val = 0.0; Ymup1->err = 0.0; GSL_ERROR ("error", GSL_EDOM); } else { int stat_Y; int stat_J; if(x < 2.0) { /* Use Taylor series for J and the Temme series for Y. * The Taylor series for J requires nu > 0, so we shift * up one and use the recursion relation to get Jmu, in * case mu < 0. */ gsl_sf_result Jmup2; int stat_J1 = gsl_sf_bessel_IJ_taylor_e(mu+1.0, x, -1, 100, GSL_DBL_EPSILON, Jmup1); int stat_J2 = gsl_sf_bessel_IJ_taylor_e(mu+2.0, x, -1, 100, GSL_DBL_EPSILON, &Jmup2); double c = 2.0*(mu+1.0)/x; Jmu->val = c * Jmup1->val - Jmup2.val; Jmu->err = c * Jmup1->err + Jmup2.err; Jmu->err += 2.0 * GSL_DBL_EPSILON * fabs(Jmu->val); stat_J = GSL_ERROR_SELECT_2(stat_J1, stat_J2); stat_Y = gsl_sf_bessel_Y_temme(mu, x, Ymu, Ymup1); return GSL_ERROR_SELECT_2(stat_J, stat_Y); } else if(x < 1000.0) { double P, Q; double J_ratio; double J_sgn; const int stat_CF1 = gsl_sf_bessel_J_CF1(mu, x, &J_ratio, &J_sgn); const int stat_CF2 = gsl_sf_bessel_JY_steed_CF2(mu, x, &P, &Q); double Jprime_J_ratio = mu/x - J_ratio; double gamma = (P - Jprime_J_ratio)/Q; Jmu->val = J_sgn * sqrt(2.0/(M_PI*x) / (Q + gamma*(P-Jprime_J_ratio))); Jmu->err = 4.0 * GSL_DBL_EPSILON * fabs(Jmu->val); Jmup1->val = J_ratio * Jmu->val; Jmup1->err = fabs(J_ratio) * Jmu->err; Ymu->val = gamma * Jmu->val; Ymu->err = fabs(gamma) * Jmu->err; Ymup1->val = Ymu->val * (mu/x - P - Q/gamma); Ymup1->err = Ymu->err * fabs(mu/x - P - Q/gamma) + 4.0*GSL_DBL_EPSILON*fabs(Ymup1->val); return GSL_ERROR_SELECT_2(stat_CF1, stat_CF2); } else { /* Use asymptotics for large argument. */ const int stat_J0 = gsl_sf_bessel_Jnu_asympx_e(mu, x, Jmu); const int stat_J1 = gsl_sf_bessel_Jnu_asympx_e(mu+1.0, x, Jmup1); const int stat_Y0 = gsl_sf_bessel_Ynu_asympx_e(mu, x, Ymu); const int stat_Y1 = gsl_sf_bessel_Ynu_asympx_e(mu+1.0, x, Ymup1); stat_J = GSL_ERROR_SELECT_2(stat_J0, stat_J1); stat_Y = GSL_ERROR_SELECT_2(stat_Y0, stat_Y1); return GSL_ERROR_SELECT_2(stat_J, stat_Y); } } } int gsl_sf_bessel_J_CF1(const double nu, const double x, double * ratio, double * sgn) { const double RECUR_BIG = GSL_SQRT_DBL_MAX; const int maxiter = 10000; int n = 1; double Anm2 = 1.0; double Bnm2 = 0.0; double Anm1 = 0.0; double Bnm1 = 1.0; double a1 = x/(2.0*(nu+1.0)); double An = Anm1 + a1*Anm2; double Bn = Bnm1 + a1*Bnm2; double an; double fn = An/Bn; double dn = a1; double s = 1.0; while(n < maxiter) { double old_fn; double del; n++; Anm2 = Anm1; Bnm2 = Bnm1; Anm1 = An; Bnm1 = Bn; an = -x*x/(4.0*(nu+n-1.0)*(nu+n)); An = Anm1 + an*Anm2; Bn = Bnm1 + an*Bnm2; if(fabs(An) > RECUR_BIG || fabs(Bn) > RECUR_BIG) { An /= RECUR_BIG; Bn /= RECUR_BIG; Anm1 /= RECUR_BIG; Bnm1 /= RECUR_BIG; Anm2 /= RECUR_BIG; Bnm2 /= RECUR_BIG; } old_fn = fn; fn = An/Bn; del = old_fn/fn; dn = 1.0 / (2.0*(nu+n)/x - dn); if(dn < 0.0) s = -s; if(fabs(del - 1.0) < 2.0*GSL_DBL_EPSILON) break; } *ratio = fn; *sgn = s; if(n >= maxiter) GSL_ERROR ("error", GSL_EMAXITER); else return GSL_SUCCESS; } /* Evaluate the continued fraction CF1 for J_{nu+1}/J_nu * using Gautschi (Euler) equivalent series. * This exhibits an annoying problem because the * a_k are not positive definite (in fact they are all negative). * There are cases when rho_k blows up. Example: nu=1,x=4. */ #if 0 int gsl_sf_bessel_J_CF1_ser(const double nu, const double x, double * ratio, double * sgn) { const int maxk = 20000; double tk = 1.0; double sum = 1.0; double rhok = 0.0; double dk = 0.0; double s = 1.0; int k; for(k=1; k 2 is a good cutoff. * Also requires |nu| < 1/2. */ int gsl_sf_bessel_K_scaled_steed_temme_CF2(const double nu, const double x, double * K_nu, double * K_nup1, double * Kp_nu) { const int maxiter = 10000; int i = 1; double bi = 2.0*(1.0 + x); double di = 1.0/bi; double delhi = di; double hi = di; double qi = 0.0; double qip1 = 1.0; double ai = -(0.25 - nu*nu); double a1 = ai; double ci = -ai; double Qi = -ai; double s = 1.0 + Qi*delhi; for(i=2; i<=maxiter; i++) { double dels; double tmp; ai -= 2.0*(i-1); ci = -ai*ci/i; tmp = (qi - bi*qip1)/ai; qi = qip1; qip1 = tmp; Qi += ci*qip1; bi += 2.0; di = 1.0/(bi + ai*di); delhi = (bi*di - 1.0) * delhi; hi += delhi; dels = Qi*delhi; s += dels; if(fabs(dels/s) < GSL_DBL_EPSILON) break; } hi *= -a1; *K_nu = sqrt(M_PI/(2.0*x)) / s; *K_nup1 = *K_nu * (nu + x + 0.5 - hi)/x; *Kp_nu = - *K_nup1 + nu/x * *K_nu; if(i == maxiter) GSL_ERROR ("error", GSL_EMAXITER); else return GSL_SUCCESS; } int gsl_sf_bessel_cos_pi4_e(double y, double eps, gsl_sf_result * result) { const double sy = sin(y); const double cy = cos(y); const double s = sy + cy; const double d = sy - cy; const double abs_sum = fabs(cy) + fabs(sy); double seps; double ceps; if(fabs(eps) < GSL_ROOT5_DBL_EPSILON) { const double e2 = eps*eps; seps = eps * (1.0 - e2/6.0 * (1.0 - e2/20.0)); ceps = 1.0 - e2/2.0 * (1.0 - e2/12.0); } else { seps = sin(eps); ceps = cos(eps); } result->val = (ceps * s - seps * d)/ M_SQRT2; result->err = 2.0 * GSL_DBL_EPSILON * (fabs(ceps) + fabs(seps)) * abs_sum / M_SQRT2; /* Try to account for error in evaluation of sin(y), cos(y). * This is a little sticky because we don't really know * how the library routines are doing their argument reduction. * However, we will make a reasonable guess. * FIXME ? */ if(y > 1.0/GSL_DBL_EPSILON) { result->err *= 0.5 * y; } else if(y > 1.0/GSL_SQRT_DBL_EPSILON) { result->err *= 256.0 * y * GSL_SQRT_DBL_EPSILON; } return GSL_SUCCESS; } int gsl_sf_bessel_sin_pi4_e(double y, double eps, gsl_sf_result * result) { const double sy = sin(y); const double cy = cos(y); const double s = sy + cy; const double d = sy - cy; const double abs_sum = fabs(cy) + fabs(sy); double seps; double ceps; if(fabs(eps) < GSL_ROOT5_DBL_EPSILON) { const double e2 = eps*eps; seps = eps * (1.0 - e2/6.0 * (1.0 - e2/20.0)); ceps = 1.0 - e2/2.0 * (1.0 - e2/12.0); } else { seps = sin(eps); ceps = cos(eps); } result->val = (ceps * d + seps * s)/ M_SQRT2; result->err = 2.0 * GSL_DBL_EPSILON * (fabs(ceps) + fabs(seps)) * abs_sum / M_SQRT2; /* Try to account for error in evaluation of sin(y), cos(y). * See above. * FIXME ? */ if(y > 1.0/GSL_DBL_EPSILON) { result->err *= 0.5 * y; } else if(y > 1.0/GSL_SQRT_DBL_EPSILON) { result->err *= 256.0 * y * GSL_SQRT_DBL_EPSILON; } return GSL_SUCCESS; } /************************************************************************ * * Asymptotic approximations 8.11.5, 8.12.5, and 8.42.7 from G.N.Watson, A Treatise on the Theory of Bessel Functions, 2nd Edition (Cambridge University Press, 1944). Higher terms in expansion for x near l given by Airey in Phil. Mag. 31, 520 (1916). This approximation is accurate to near 0.1% at the boundaries between the asymptotic regions; well away from the boundaries the accuracy is better than 10^{-5}. * * ************************************************************************/ #if 0 double besselJ_meissel(double nu, double x) { double beta = pow(nu, 0.325); double result; /* Fitted matching points. */ double llimit = 1.1 * beta; double ulimit = 1.3 * beta; double nu2 = nu * nu; if (nu < 5. && x < 1.) { /* Small argument and order. Use a Taylor expansion. */ int k; double xo2 = 0.5 * x; double gamfactor = pow(nu,nu) * exp(-nu) * sqrt(nu * 2. * M_PI) * (1. + 1./(12.*nu) + 1./(288.*nu*nu)); double prefactor = pow(xo2, nu) / gamfactor; double C[5]; C[0] = 1.; C[1] = -C[0] / (nu+1.); C[2] = -C[1] / (2.*(nu+2.)); C[3] = -C[2] / (3.*(nu+3.)); C[4] = -C[3] / (4.*(nu+4.)); result = 0.; for(k=0; k<5; k++) result += C[k] * pow(xo2, 2.*k); result *= prefactor; } else if(x < nu - llimit) { /* Small x region: x << l. */ double z = x / nu; double z2 = z*z; double rtomz2 = sqrt(1.-z2); double omz2_2 = (1.-z2)*(1.-z2); /* Calculate Meissel exponent. */ double term1 = 1./(24.*nu) * ((2.+3.*z2)/((1.-z2)*rtomz2) -2.); double term2 = - z2*(4. + z2)/(16.*nu2*(1.-z2)*omz2_2); double V_nu = term1 + term2; /* Calculate the harmless prefactor. */ double sterlingsum = 1. + 1./(12.*nu) + 1./(288*nu2); double harmless = 1. / (sqrt(rtomz2*2.*M_PI*nu) * sterlingsum); /* Calculate the logarithm of the nu dependent prefactor. */ double ln_nupre = rtomz2 + log(z) - log(1. + rtomz2); result = harmless * exp(nu*ln_nupre - V_nu); } else if(x < nu + ulimit) { /* Intermediate region 1: x near nu. */ double eps = 1.-nu/x; double eps_x = eps * x; double eps_x_2 = eps_x * eps_x; double xo6 = x/6.; double B[6]; static double gam[6] = {2.67894, 1.35412, 1., 0.89298, 0.902745, 1.}; static double sf[6] = {0.866025, 0.866025, 0., -0.866025, -0.866025, 0.}; /* Some terms are identically zero, because sf[] can be zero. * Some terms do not appear in the result. */ B[0] = 1.; B[1] = eps_x; /* B[2] = 0.5 * eps_x_2 - 1./20.; */ B[3] = eps_x * (eps_x_2/6. - 1./15.); B[4] = eps_x_2 * (eps_x_2 - 1.)/24. + 1./280.; /* B[5] = eps_x * (eps_x_2*(0.5*eps_x_2 - 1.)/60. + 43./8400.); */ result = B[0] * gam[0] * sf[0] / pow(xo6, 1./3.); result += B[1] * gam[1] * sf[1] / pow(xo6, 2./3.); result += B[3] * gam[3] * sf[3] / pow(xo6, 4./3.); result += B[4] * gam[4] * sf[4] / pow(xo6, 5./3.); result /= (3.*M_PI); } else { /* Region of very large argument. Use expansion * for x>>l, and we need not be very exacting. */ double secb = x/nu; double sec2b= secb*secb; double cotb = 1./sqrt(sec2b-1.); /* cotb=cot(beta) */ double beta = acos(nu/x); double trigarg = nu/cotb - nu*beta - 0.25 * M_PI; double cot3b = cotb * cotb * cotb; double cot6b = cot3b * cot3b; double sum1, sum2, expterm, prefactor, trigcos; sum1 = 2.0 + 3.0 * sec2b; trigarg -= sum1 * cot3b / (24.0 * nu); trigcos = cos(trigarg); sum2 = 4.0 + sec2b; expterm = sum2 * sec2b * cot6b / (16.0 * nu2); expterm = exp(-expterm); prefactor = sqrt(2. * cotb / (nu * M_PI)); result = prefactor * expterm * trigcos; } return result; } #endif praat-6.0.04/external/gsl/gsl_specfunc__bessel.h000066400000000000000000000060401261542461700216470ustar00rootroot00000000000000/* specfunc/bessel.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef _BESSEL_H_ #define _BESSEL_H_ #include "gsl_sf_result.h" /* Taylor expansion for J_nu(x) or I_nu(x) * sign = -1 ==> Jnu * sign = +1 ==> Inu */ int gsl_sf_bessel_IJ_taylor_e(const double nu, const double x, const int sign, const int kmax, const double threshold, gsl_sf_result * result ); int gsl_sf_bessel_Jnu_asympx_e(const double nu, const double x, gsl_sf_result * result); int gsl_sf_bessel_Ynu_asympx_e(const double nu, const double x, gsl_sf_result * result); int gsl_sf_bessel_Inu_scaled_asympx_e(const double nu, const double x, gsl_sf_result * result); int gsl_sf_bessel_Knu_scaled_asympx_e(const double nu, const double x, gsl_sf_result * result); int gsl_sf_bessel_Inu_scaled_asymp_unif_e(const double nu, const double x, gsl_sf_result * result); int gsl_sf_bessel_Knu_scaled_asymp_unif_e(const double nu, const double x, gsl_sf_result * result); /* ratio = J_{nu+1}(x) / J_nu(x) * sgn = sgn(J_nu(x)) */ int gsl_sf_bessel_J_CF1(const double nu, const double x, double * ratio, double * sgn); /* ratio = I_{nu+1}(x) / I_nu(x) */ int gsl_sf_bessel_I_CF1_ser(const double nu, const double x, double * ratio); /* Evaluate the Steed method continued fraction CF2 for * * (J' + i Y')/(J + i Y) := P + i Q */ int gsl_sf_bessel_JY_steed_CF2(const double nu, const double x, double * P, double * Q); int gsl_sf_bessel_JY_mu_restricted(const double mu, const double x, gsl_sf_result * Jmu, gsl_sf_result * Jmup1, gsl_sf_result * Ymu, gsl_sf_result * Ymup1); int gsl_sf_bessel_K_scaled_steed_temme_CF2(const double nu, const double x, double * K_nu, double * K_nup1, double * Kp_nu); /* These are of use in calculating the oscillating * Bessel functions. * cos(y - pi/4 + eps) * sin(y - pi/4 + eps) */ int gsl_sf_bessel_cos_pi4_e(double y, double eps, gsl_sf_result * result); int gsl_sf_bessel_sin_pi4_e(double y, double eps, gsl_sf_result * result); #endif /* !_BESSEL_H_ */ praat-6.0.04/external/gsl/gsl_specfunc__bessel_I0.c000066400000000000000000000142451261542461700222000ustar00rootroot00000000000000/* specfunc/bessel_I0.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_bessel.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__chebyshev.h" #include "gsl_specfunc__cheb_eval.c" /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/ /* based on SLATEC besi0 */ /* chebyshev expansions series for bi0 on the interval 0. to 9.00000d+00 with weighted error 2.46e-18 log weighted error 17.61 significant figures required 17.90 decimal places required 18.15 series for ai0 on the interval 1.25000d-01 to 3.33333d-01 with weighted error 7.87e-17 log weighted error 16.10 significant figures required 14.69 decimal places required 16.76 series for ai02 on the interval 0. to 1.25000d-01 with weighted error 3.79e-17 log weighted error 16.42 significant figures required 14.86 decimal places required 17.09 */ static double bi0_data[12] = { -.07660547252839144951, 1.92733795399380827000, .22826445869203013390, .01304891466707290428, .00043442709008164874, .00000942265768600193, .00000014340062895106, .00000000161384906966, .00000000001396650044, .00000000000009579451, .00000000000000053339, .00000000000000000245 }; static cheb_series bi0_cs = { bi0_data, 11, -1, 1, 11 }; static double ai0_data[21] = { .07575994494023796, .00759138081082334, .00041531313389237, .00001070076463439, -.00000790117997921, -.00000078261435014, .00000027838499429, .00000000825247260, -.00000001204463945, .00000000155964859, .00000000022925563, -.00000000011916228, .00000000001757854, .00000000000112822, -.00000000000114684, .00000000000027155, -.00000000000002415, -.00000000000000608, .00000000000000314, -.00000000000000071, .00000000000000007 }; static cheb_series ai0_cs = { ai0_data, 20, -1, 1, 13 }; static double ai02_data[22] = { .05449041101410882, .00336911647825569, .00006889758346918, .00000289137052082, .00000020489185893, .00000002266668991, .00000000339623203, .00000000049406022, .00000000001188914, -.00000000003149915, -.00000000001321580, -.00000000000179419, .00000000000071801, .00000000000038529, .00000000000001539, -.00000000000004151, -.00000000000000954, .00000000000000382, .00000000000000176, -.00000000000000034, -.00000000000000027, .00000000000000003 }; static cheb_series ai02_cs = { ai02_data, 21, -1, 1, 11 }; /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_bessel_I0_scaled_e(const double x, gsl_sf_result * result) { double y = fabs(x); /* CHECK_POINTER(result) */ if(y < 2.0 * GSL_SQRT_DBL_EPSILON) { result->val = 1.0 - y; result->err = 0.5*y*y; return GSL_SUCCESS; } else if(y <= 3.0) { const double ey = exp(-y); gsl_sf_result c; cheb_eval_e(&bi0_cs, y*y/4.5-1.0, &c); result->val = ey * (2.75 + c.val); result->err = GSL_DBL_EPSILON * fabs(result->val) + ey * c.err; return GSL_SUCCESS; } else if(y <= 8.0) { const double sy = sqrt(y); gsl_sf_result c; cheb_eval_e(&ai0_cs, (48.0/y-11.0)/5.0, &c); result->val = (0.375 + c.val) / sy; result->err = 2.0 * GSL_DBL_EPSILON * (0.375 + fabs(c.val)) / sy; result->err += c.err / sy; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { const double sy = sqrt(y); gsl_sf_result c; cheb_eval_e(&ai02_cs, 16.0/y-1.0, &c); result->val = (0.375 + c.val) / sy; result->err = 2.0 * GSL_DBL_EPSILON * (0.375 + fabs(c.val)) / sy; result->err += c.err / sy; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_bessel_I0_e(const double x, gsl_sf_result * result) { double y = fabs(x); /* CHECK_POINTER(result) */ if(y < 2.0 * GSL_SQRT_DBL_EPSILON) { result->val = 1.0; result->err = 0.5*y*y; return GSL_SUCCESS; } else if(y <= 3.0) { gsl_sf_result c; cheb_eval_e(&bi0_cs, y*y/4.5-1.0, &c); result->val = 2.75 + c.val; result->err = GSL_DBL_EPSILON * (2.75 + fabs(c.val)); result->err += c.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(y < GSL_LOG_DBL_MAX - 1.0) { const double ey = exp(y); gsl_sf_result b_scaled; gsl_sf_bessel_I0_scaled_e(x, &b_scaled); result->val = ey * b_scaled.val; result->err = ey * b_scaled.err + y*GSL_DBL_EPSILON*fabs(result->val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { OVERFLOW_ERROR(result); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_bessel_I0_scaled(const double x) { EVAL_RESULT(gsl_sf_bessel_I0_scaled_e(x, &result); ) } double gsl_sf_bessel_I0(const double x) { EVAL_RESULT(gsl_sf_bessel_I0_e(x, &result); ) } praat-6.0.04/external/gsl/gsl_specfunc__bessel_I1.c000066400000000000000000000153151261542461700222000ustar00rootroot00000000000000/* specfunc/bessel_I1.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_bessel.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__chebyshev.h" #include "gsl_specfunc__cheb_eval.c" #define ROOT_EIGHT (2.0*M_SQRT2) /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/ /* based on SLATEC besi1(), besi1e() */ /* chebyshev expansions series for bi1 on the interval 0. to 9.00000d+00 with weighted error 2.40e-17 log weighted error 16.62 significant figures required 16.23 decimal places required 17.14 series for ai1 on the interval 1.25000d-01 to 3.33333d-01 with weighted error 6.98e-17 log weighted error 16.16 significant figures required 14.53 decimal places required 16.82 series for ai12 on the interval 0. to 1.25000d-01 with weighted error 3.55e-17 log weighted error 16.45 significant figures required 14.69 decimal places required 17.12 */ static double bi1_data[11] = { -0.001971713261099859, 0.407348876675464810, 0.034838994299959456, 0.001545394556300123, 0.000041888521098377, 0.000000764902676483, 0.000000010042493924, 0.000000000099322077, 0.000000000000766380, 0.000000000000004741, 0.000000000000000024 }; static cheb_series bi1_cs = { bi1_data, 10, -1, 1, 10 }; static double ai1_data[21] = { -0.02846744181881479, -0.01922953231443221, -0.00061151858579437, -0.00002069971253350, 0.00000858561914581, 0.00000104949824671, -0.00000029183389184, -0.00000001559378146, 0.00000001318012367, -0.00000000144842341, -0.00000000029085122, 0.00000000012663889, -0.00000000001664947, -0.00000000000166665, 0.00000000000124260, -0.00000000000027315, 0.00000000000002023, 0.00000000000000730, -0.00000000000000333, 0.00000000000000071, -0.00000000000000006 }; static cheb_series ai1_cs = { ai1_data, 20, -1, 1, 11 }; static double ai12_data[22] = { 0.02857623501828014, -0.00976109749136147, -0.00011058893876263, -0.00000388256480887, -0.00000025122362377, -0.00000002631468847, -0.00000000383538039, -0.00000000055897433, -0.00000000001897495, 0.00000000003252602, 0.00000000001412580, 0.00000000000203564, -0.00000000000071985, -0.00000000000040836, -0.00000000000002101, 0.00000000000004273, 0.00000000000001041, -0.00000000000000382, -0.00000000000000186, 0.00000000000000033, 0.00000000000000028, -0.00000000000000003 }; static cheb_series ai12_cs = { ai12_data, 21, -1, 1, 9 }; /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_bessel_I1_scaled_e(const double x, gsl_sf_result * result) { const double xmin = 2.0 * GSL_DBL_MIN; const double x_small = ROOT_EIGHT * GSL_SQRT_DBL_EPSILON; const double y = fabs(x); /* CHECK_POINTER(result) */ if(y == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(y < xmin) { UNDERFLOW_ERROR(result); } else if(y < x_small) { result->val = 0.5*x; result->err = 0.0; return GSL_SUCCESS; } else if(y <= 3.0) { const double ey = exp(-y); gsl_sf_result c; cheb_eval_e(&bi1_cs, y*y/4.5-1.0, &c); result->val = x * ey * (0.875 + c.val); result->err = ey * c.err + y * GSL_DBL_EPSILON * fabs(result->val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(y <= 8.0) { const double sy = sqrt(y); gsl_sf_result c; double b; double s; cheb_eval_e(&ai1_cs, (48.0/y-11.0)/5.0, &c); b = (0.375 + c.val) / sy; s = (x > 0.0 ? 1.0 : -1.0); result->val = s * b; result->err = c.err / sy; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { const double sy = sqrt(y); gsl_sf_result c; double b; double s; cheb_eval_e(&ai12_cs, 16.0/y-1.0, &c); b = (0.375 + c.val) / sy; s = (x > 0.0 ? 1.0 : -1.0); result->val = s * b; result->err = c.err / sy; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_bessel_I1_e(const double x, gsl_sf_result * result) { const double xmin = 2.0 * GSL_DBL_MIN; const double x_small = ROOT_EIGHT * GSL_SQRT_DBL_EPSILON; const double y = fabs(x); /* CHECK_POINTER(result) */ if(y == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(y < xmin) { UNDERFLOW_ERROR(result); } else if(y < x_small) { result->val = 0.5*x; result->err = 0.0; return GSL_SUCCESS; } else if(y <= 3.0) { gsl_sf_result c; cheb_eval_e(&bi1_cs, y*y/4.5-1.0, &c); result->val = x * (0.875 + c.val); result->err = y * c.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(y < GSL_LOG_DBL_MAX) { const double ey = exp(y); gsl_sf_result I1_scaled; gsl_sf_bessel_I1_scaled_e(x, &I1_scaled); result->val = ey * I1_scaled.val; result->err = ey * I1_scaled.err + y * GSL_DBL_EPSILON * fabs(result->val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { OVERFLOW_ERROR(result); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_bessel_I1_scaled(const double x) { EVAL_RESULT(gsl_sf_bessel_I1_scaled_e(x, &result)); } double gsl_sf_bessel_I1(const double x) { EVAL_RESULT(gsl_sf_bessel_I1_e(x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__bessel_In.c000066400000000000000000000144731261542461700223010ustar00rootroot00000000000000/* specfunc/bessel_In.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_bessel.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__bessel.h" /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_bessel_In_scaled_e(int n, const double x, gsl_sf_result * result) { const double ax = fabs(x); n = abs(n); /* I(-n, z) = I(n, z) */ /* CHECK_POINTER(result) */ if(n == 0) { return gsl_sf_bessel_I0_scaled_e(x, result); } else if(n == 1) { return gsl_sf_bessel_I1_scaled_e(x, result); } else if(x == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(x*x < 10.0*(n+1.0)/M_E) { gsl_sf_result t; double ex = exp(-ax); int stat_In = gsl_sf_bessel_IJ_taylor_e((double)n, ax, 1, 50, GSL_DBL_EPSILON, &t); result->val = t.val * ex; result->err = t.err * ex; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); if(x < 0.0 && GSL_IS_ODD(n)) result->val = -result->val; return stat_In; } else if(n < 150 && ax < 1e7) { gsl_sf_result I0_scaled; int stat_I0 = gsl_sf_bessel_I0_scaled_e(ax, &I0_scaled); double rat; int stat_CF1 = gsl_sf_bessel_I_CF1_ser((double)n, ax, &rat); double Ikp1 = rat * GSL_SQRT_DBL_MIN; double Ik = GSL_SQRT_DBL_MIN; double Ikm1; int k; for(k=n; k >= 1; k--) { Ikm1 = Ikp1 + 2.0*k/ax * Ik; Ikp1 = Ik; Ik = Ikm1; } result->val = I0_scaled.val * (GSL_SQRT_DBL_MIN / Ik); result->err = I0_scaled.err * (GSL_SQRT_DBL_MIN / Ik); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); if(x < 0.0 && GSL_IS_ODD(n)) result->val = -result->val; return GSL_ERROR_SELECT_2(stat_I0, stat_CF1); } else if( GSL_MIN( 0.29/(n*n), 0.5/(n*n + x*x) ) < 0.5*GSL_ROOT3_DBL_EPSILON) { int stat_as = gsl_sf_bessel_Inu_scaled_asymp_unif_e((double)n, ax, result); if(x < 0.0 && GSL_IS_ODD(n)) result->val = -result->val; return stat_as; } else { const int nhi = 2 + (int) (1.2 / GSL_ROOT6_DBL_EPSILON); gsl_sf_result r_Ikp1; gsl_sf_result r_Ik; int stat_a1 = gsl_sf_bessel_Inu_scaled_asymp_unif_e(nhi+1.0, ax, &r_Ikp1); int stat_a2 = gsl_sf_bessel_Inu_scaled_asymp_unif_e((double)nhi, ax, &r_Ik); double Ikp1 = r_Ikp1.val; double Ik = r_Ik.val; double Ikm1; int k; for(k=nhi; k > n; k--) { Ikm1 = Ikp1 + 2.0*k/ax * Ik; Ikp1 = Ik; Ik = Ikm1; } result->val = Ik; result->err = Ik * (r_Ikp1.err/r_Ikp1.val + r_Ik.err/r_Ik.val); if(x < 0.0 && GSL_IS_ODD(n)) result->val = -result->val; return GSL_ERROR_SELECT_2(stat_a1, stat_a2); } } int gsl_sf_bessel_In_scaled_array(const int nmin, const int nmax, const double x, double * result_array) { /* CHECK_POINTER(result_array) */ if(nmax < nmin || nmin < 0) { int j; for(j=0; j<=nmax-nmin; j++) result_array[j] = 0.0; GSL_ERROR ("domain error", GSL_EDOM); } else if(x == 0.0) { int j; for(j=0; j<=nmax-nmin; j++) result_array[j] = 0.0; if(nmin == 0) result_array[0] = 1.0; return GSL_SUCCESS; } else if(nmax == 0) { gsl_sf_result I0_scaled; int stat = gsl_sf_bessel_I0_scaled_e(x, &I0_scaled); result_array[0] = I0_scaled.val; return stat; } else { const double ax = fabs(x); const double two_over_x = 2.0/ax; /* starting values */ gsl_sf_result r_Inp1; gsl_sf_result r_In; int stat_0 = gsl_sf_bessel_In_scaled_e(nmax+1, ax, &r_Inp1); int stat_1 = gsl_sf_bessel_In_scaled_e(nmax, ax, &r_In); double Inp1 = r_Inp1.val; double In = r_In.val; double Inm1; int n; for(n=nmax; n>=nmin; n--) { result_array[n-nmin] = In; Inm1 = Inp1 + n * two_over_x * In; Inp1 = In; In = Inm1; } /* deal with signs */ if(x < 0.0) { for(n=nmin; n<=nmax; n++) { if(GSL_IS_ODD(n)) result_array[n-nmin] = -result_array[n-nmin]; } } return GSL_ERROR_SELECT_2(stat_0, stat_1); } } int gsl_sf_bessel_In_e(const int n_in, const double x, gsl_sf_result * result) { const double ax = fabs(x); const int n = abs(n_in); /* I(-n, z) = I(n, z) */ gsl_sf_result In_scaled; const int stat_In_scaled = gsl_sf_bessel_In_scaled_e(n, ax, &In_scaled); /* In_scaled is always less than 1, * so this overflow check is conservative. */ if(ax > GSL_LOG_DBL_MAX - 1.0) { OVERFLOW_ERROR(result); } else { const double ex = exp(ax); result->val = ex * In_scaled.val; result->err = ex * In_scaled.err; result->err += ax * GSL_DBL_EPSILON * fabs(result->val); if(x < 0.0 && GSL_IS_ODD(n)) result->val = -result->val; return stat_In_scaled; } } int gsl_sf_bessel_In_array(const int nmin, const int nmax, const double x, double * result_array) { double ax = fabs(x); /* CHECK_POINTER(result_array) */ if(ax > GSL_LOG_DBL_MAX - 1.0) { int j; for(j=0; j<=nmax-nmin; j++) result_array[j] = 0.0; /* FIXME: should be Inf */ GSL_ERROR ("overflow", GSL_EOVRFLW); } else { int j; double eax = exp(ax); int status = gsl_sf_bessel_In_scaled_array(nmin, nmax, x, result_array); for(j=0; j<=nmax-nmin; j++) result_array[j] *= eax; return status; } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_bessel_In_scaled(const int n, const double x) { EVAL_RESULT(gsl_sf_bessel_In_scaled_e(n, x, &result)); } double gsl_sf_bessel_In(const int n, const double x) { EVAL_RESULT(gsl_sf_bessel_In_e(n, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__bessel_Inu.c000066400000000000000000000066011261542461700224600ustar00rootroot00000000000000/* specfunc/bessel_Inu.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_exp.h" #include "gsl_sf_gamma.h" #include "gsl_sf_bessel.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__bessel.h" #include "gsl_specfunc__bessel_temme.h" /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_bessel_Inu_scaled_e(double nu, double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x < 0.0 || nu < 0.0) { DOMAIN_ERROR(result); } else if(x*x < 10.0*(nu+1.0)) { gsl_sf_result b; double ex = exp(-x); int stat = gsl_sf_bessel_IJ_taylor_e(nu, x, 1, 100, GSL_DBL_EPSILON, &b); result->val = b.val * ex; result->err = b.err * ex; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat; } else if(0.5/(nu*nu + x*x) < GSL_ROOT3_DBL_EPSILON) { return gsl_sf_bessel_Inu_scaled_asymp_unif_e(nu, x, result); } else { int N = (int)(nu + 0.5); double mu = nu - N; /* -1/2 <= mu <= 1/2 */ double K_mu, K_mup1, Kp_mu; double K_nu, K_nup1, K_num1; double I_nu_ratio; int stat_Irat; int stat_Kmu; int n; /* obtain K_mu, K_mup1 */ if(x < 2.0) { stat_Kmu = gsl_sf_bessel_K_scaled_temme(mu, x, &K_mu, &K_mup1, &Kp_mu); } else { stat_Kmu = gsl_sf_bessel_K_scaled_steed_temme_CF2(mu, x, &K_mu, &K_mup1, &Kp_mu); } /* recurse forward to obtain K_num1, K_nu */ K_nu = K_mu; K_nup1 = K_mup1; for(n=0; nval = 1.0/(x * (K_nup1 + I_nu_ratio * K_nu)); result->err = GSL_DBL_EPSILON * (0.5*N + 2.0) * fabs(result->val); return GSL_ERROR_SELECT_2(stat_Kmu, stat_Irat); } } int gsl_sf_bessel_Inu_e(double nu, double x, gsl_sf_result * result) { gsl_sf_result b; int stat_I = gsl_sf_bessel_Inu_scaled_e(nu, x, &b); int stat_e = gsl_sf_exp_mult_err_e(x, fabs(x*GSL_DBL_EPSILON), b.val, b.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_I); } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_bessel_Inu_scaled(double nu, double x) { EVAL_RESULT(gsl_sf_bessel_Inu_scaled_e(nu, x, &result)); } double gsl_sf_bessel_Inu(double nu, double x) { EVAL_RESULT(gsl_sf_bessel_Inu_e(nu, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__bessel_J0.c000066400000000000000000000063471261542461700222050ustar00rootroot00000000000000/* specfunc/bessel_J0.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_mode.h" #include "gsl_specfunc__bessel.h" #include "gsl_specfunc__bessel_amp_phase.h" #include "gsl_sf_trig.h" #include "gsl_sf_bessel.h" #include "gsl_specfunc__cheb_eval.c" /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/ /* based on SLATEC besj0, 1977 version, w. fullerton */ /* chebyshev expansions for Bessel functions series for bj0 on the interval 0. to 1.60000d+01 with weighted error 7.47e-18 log weighted error 17.13 significant figures required 16.98 decimal places required 17.68 */ static double bj0_data[13] = { 0.100254161968939137, -0.665223007764405132, 0.248983703498281314, -0.0332527231700357697, 0.0023114179304694015, -0.0000991127741995080, 0.0000028916708643998, -0.0000000612108586630, 0.0000000009838650793, -0.0000000000124235515, 0.0000000000001265433, -0.0000000000000010619, 0.0000000000000000074, }; static cheb_series bj0_cs = { bj0_data, 12, -1, 1, 9 }; /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_bessel_J0_e(const double x, gsl_sf_result * result) { double y = fabs(x); /* CHECK_POINTER(result) */ if(y < 2.0*GSL_SQRT_DBL_EPSILON) { result->val = 1.0; result->err = y*y; return GSL_SUCCESS; } else if(y <= 4.0) { return cheb_eval_e(&bj0_cs, 0.125*y*y - 1.0, result); } else { const double z = 32.0/(y*y) - 1.0; gsl_sf_result ca; gsl_sf_result ct; gsl_sf_result cp; const int stat_ca = cheb_eval_e(&_gsl_sf_bessel_amp_phase_bm0_cs, z, &ca); const int stat_ct = cheb_eval_e(&_gsl_sf_bessel_amp_phase_bth0_cs, z, &ct); const int stat_cp = gsl_sf_bessel_cos_pi4_e(y, ct.val/y, &cp); const double sqrty = sqrt(y); const double ampl = (0.75 + ca.val) / sqrty; result->val = ampl * cp.val; result->err = fabs(cp.val) * ca.err/sqrty + fabs(ampl) * cp.err; result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_3(stat_ca, stat_ct, stat_cp); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_bessel_J0(const double x) { EVAL_RESULT(gsl_sf_bessel_J0_e(x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__bessel_J1.c000066400000000000000000000072321261542461700222000ustar00rootroot00000000000000/* specfunc/bessel_J1.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_trig.h" #include "gsl_sf_bessel.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__bessel.h" #include "gsl_specfunc__bessel_amp_phase.h" #include "gsl_specfunc__cheb_eval.c" #define ROOT_EIGHT (2.0*M_SQRT2) /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/ /* based on SLATEC besj1, 1983 version, w. fullerton */ /* chebyshev expansions series for bj1 on the interval 0. to 1.60000d+01 with weighted error 4.48e-17 log weighted error 16.35 significant figures required 15.77 decimal places required 16.89 */ static double bj1_data[12] = { -0.11726141513332787, -0.25361521830790640, 0.050127080984469569, -0.004631514809625081, 0.000247996229415914, -0.000008678948686278, 0.000000214293917143, -0.000000003936093079, 0.000000000055911823, -0.000000000000632761, 0.000000000000005840, -0.000000000000000044, }; static cheb_series bj1_cs = { bj1_data, 11, -1, 1, 8 }; /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_bessel_J1_e(const double x, gsl_sf_result * result) { double y = fabs(x); /* CHECK_POINTER(result) */ if(y == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(y < 2.0*GSL_DBL_MIN) { UNDERFLOW_ERROR(result); } else if(y < ROOT_EIGHT * GSL_SQRT_DBL_EPSILON) { result->val = 0.5*x; result->err = 0.0; return GSL_SUCCESS; } else if(y < 4.0) { gsl_sf_result c; cheb_eval_e(&bj1_cs, 0.125*y*y-1.0, &c); result->val = x * (0.25 + c.val); result->err = fabs(x * c.err); return GSL_SUCCESS; } else { /* Because the leading term in the phase is y, * which we assume is exactly known, the error * in the cos() evaluation is bounded. */ const double z = 32.0/(y*y) - 1.0; gsl_sf_result ca; gsl_sf_result ct; gsl_sf_result sp; const int stat_ca = cheb_eval_e(&_gsl_sf_bessel_amp_phase_bm1_cs, z, &ca); const int stat_ct = cheb_eval_e(&_gsl_sf_bessel_amp_phase_bth1_cs, z, &ct); const int stat_sp = gsl_sf_bessel_sin_pi4_e(y, ct.val/y, &sp); const double sqrty = sqrt(y); const double ampl = (0.75 + ca.val) / sqrty; result->val = (x < 0.0 ? -ampl : ampl) * sp.val; result->err = fabs(sp.val) * ca.err/sqrty + fabs(ampl) * sp.err; result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_3(stat_ca, stat_ct, stat_sp); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_bessel_J1(const double x) { EVAL_RESULT(gsl_sf_bessel_J1_e(x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__bessel_Jn.c000066400000000000000000000117671261542461700223050ustar00rootroot00000000000000/* specfunc/bessel_Jn.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_pow_int.h" #include "gsl_specfunc__bessel.h" #include "gsl_specfunc__bessel_amp_phase.h" #include "gsl_specfunc__bessel_olver.h" #include "gsl_sf_bessel.h" /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_bessel_Jn_e(int n, double x, gsl_sf_result * result) { int sign = 1; if(n < 0) { /* reduce to case n >= 0 */ n = -n; if(GSL_IS_ODD(n)) sign = -sign; } if(x < 0.0) { /* reduce to case x >= 0. */ x = -x; if(GSL_IS_ODD(n)) sign = -sign; } /* CHECK_POINTER(result) */ if(n == 0) { gsl_sf_result b0; int stat_J0 = gsl_sf_bessel_J0_e(x, &b0); result->val = sign * b0.val; result->err = b0.err; return stat_J0; } else if(n == 1) { gsl_sf_result b1; int stat_J1 = gsl_sf_bessel_J1_e(x, &b1); result->val = sign * b1.val; result->err = b1.err; return stat_J1; } else { if(x == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(x*x < 10.0*(n+1.0)*GSL_ROOT5_DBL_EPSILON) { gsl_sf_result b; int status = gsl_sf_bessel_IJ_taylor_e((double)n, x, -1, 50, GSL_DBL_EPSILON, &b); result->val = sign * b.val; result->err = b.err; result->err += GSL_DBL_EPSILON * fabs(result->val); return status; } else if(GSL_ROOT4_DBL_EPSILON * x > (n*n+1.0)) { int status = gsl_sf_bessel_Jnu_asympx_e((double)n, x, result); result->val *= sign; return status; } else if(n > 50) { int status = gsl_sf_bessel_Jnu_asymp_Olver_e((double)n, x, result); result->val *= sign; return status; } else if(x > 1000.0) { /* We need this to avoid feeding large x to CF1; note that * due to the above check, we know that n <= 50. */ int status = gsl_sf_bessel_Jnu_asympx_e((double)n, x, result); result->val *= sign; return status; } else { double ans; double err; double ratio; double sgn; int stat_b; int stat_CF1 = gsl_sf_bessel_J_CF1((double)n, x, &ratio, &sgn); /* backward recurrence */ double Jkp1 = GSL_SQRT_DBL_MIN * ratio; double Jk = GSL_SQRT_DBL_MIN; double Jkm1; int k; for(k=n; k>0; k--) { Jkm1 = 2.0*k/x * Jk - Jkp1; Jkp1 = Jk; Jk = Jkm1; } if(fabs(Jkp1) > fabs(Jk)) { gsl_sf_result b1; stat_b = gsl_sf_bessel_J1_e(x, &b1); ans = b1.val/Jkp1 * GSL_SQRT_DBL_MIN; err = b1.err/Jkp1 * GSL_SQRT_DBL_MIN; } else { gsl_sf_result b0; stat_b = gsl_sf_bessel_J0_e(x, &b0); ans = b0.val/Jk * GSL_SQRT_DBL_MIN; err = b0.err/Jk * GSL_SQRT_DBL_MIN; } result->val = sign * ans; result->err = fabs(err); return GSL_ERROR_SELECT_2(stat_CF1, stat_b); } } } int gsl_sf_bessel_Jn_array(int nmin, int nmax, double x, double * result_array) { /* CHECK_POINTER(result_array) */ if(nmin < 0 || nmax < nmin) { int n; for(n=nmax; n>=nmin; n--) { result_array[n-nmin] = 0.0; } GSL_ERROR ("domain error", GSL_EDOM); } else if(x == 0.0) { int n; for(n=nmax; n>=nmin; n--) { result_array[n-nmin] = 0.0; } if(nmin == 0) result_array[0] = 1.0; return GSL_SUCCESS; } else { gsl_sf_result r_Jnp1; gsl_sf_result r_Jn; int stat_np1 = gsl_sf_bessel_Jn_e(nmax+1, x, &r_Jnp1); int stat_n = gsl_sf_bessel_Jn_e(nmax, x, &r_Jn); int stat = GSL_ERROR_SELECT_2(stat_np1, stat_n); double Jnp1 = r_Jnp1.val; double Jn = r_Jn.val; double Jnm1; int n; if(stat == GSL_SUCCESS) { for(n=nmax; n>=nmin; n--) { result_array[n-nmin] = Jn; Jnm1 = -Jnp1 + 2.0*n/x * Jn; Jnp1 = Jn; Jn = Jnm1; } } else { for(n=nmax; n>=nmin; n--) { result_array[n-nmin] = 0.0; } } return stat; } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_bessel_Jn(const int n, const double x) { EVAL_RESULT(gsl_sf_bessel_Jn_e(n, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__bessel_Jnu.c000066400000000000000000000122311261542461700224550ustar00rootroot00000000000000/* specfunc/bessel_Jnu.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_bessel.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__bessel.h" #include "gsl_specfunc__bessel_olver.h" #include "gsl_specfunc__bessel_temme.h" /* Evaluate at large enough nu to apply asymptotic * results and apply backward recurrence. */ #if 0 static int bessel_J_recur_asymp(const double nu, const double x, gsl_sf_result * Jnu, gsl_sf_result * Jnup1) { const double nu_cut = 25.0; int n; int steps = ceil(nu_cut - nu) + 1; gsl_sf_result r_Jnp1; gsl_sf_result r_Jn; int stat_O1 = gsl_sf_bessel_Jnu_asymp_Olver_e(nu + steps + 1.0, x, &r_Jnp1); int stat_O2 = gsl_sf_bessel_Jnu_asymp_Olver_e(nu + steps, x, &r_Jn); double r_fe = fabs(r_Jnp1.err/r_Jnp1.val) + fabs(r_Jn.err/r_Jn.val); double Jnp1 = r_Jnp1.val; double Jn = r_Jn.val; double Jnm1; double Jnp1_save; for(n=steps; n>0; n--) { Jnm1 = 2.0*(nu+n)/x * Jn - Jnp1; Jnp1 = Jn; Jnp1_save = Jn; Jn = Jnm1; } Jnu->val = Jn; Jnu->err = (r_fe + GSL_DBL_EPSILON * (steps + 1.0)) * fabs(Jn); Jnup1->val = Jnp1_save; Jnup1->err = (r_fe + GSL_DBL_EPSILON * (steps + 1.0)) * fabs(Jnp1_save); return GSL_ERROR_SELECT_2(stat_O1, stat_O2); } #endif /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_bessel_Jnu_e(const double nu, const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x < 0.0 || nu < 0.0) { DOMAIN_ERROR(result); } else if(x == 0.0) { if(nu == 0.0) { result->val = 1.0; result->err = 0.0; } else { result->val = 0.0; result->err = 0.0; } return GSL_SUCCESS; } else if(x*x < 10.0*(nu+1.0)) { return gsl_sf_bessel_IJ_taylor_e(nu, x, -1, 100, GSL_DBL_EPSILON, result); } else if(nu > 50.0) { return gsl_sf_bessel_Jnu_asymp_Olver_e(nu, x, result); } else if(x > 1000.0) { /* We need this to avoid feeding large x to CF1; note that * due to the above check, we know that n <= 50. See similar * block in bessel_Jn.c. */ return gsl_sf_bessel_Jnu_asympx_e(nu, x, result); } else { /* -1/2 <= mu <= 1/2 */ int N = (int)(nu + 0.5); double mu = nu - N; /* Determine the J ratio at nu. */ double Jnup1_Jnu; double sgn_Jnu; const int stat_CF1 = gsl_sf_bessel_J_CF1(nu, x, &Jnup1_Jnu, &sgn_Jnu); if(x < 2.0) { /* Determine Y_mu, Y_mup1 directly and recurse forward to nu. * Then use the CF1 information to solve for J_nu and J_nup1. */ gsl_sf_result Y_mu, Y_mup1; const int stat_mu = gsl_sf_bessel_Y_temme(mu, x, &Y_mu, &Y_mup1); double Ynm1 = Y_mu.val; double Yn = Y_mup1.val; double Ynp1 = 0.0; int n; for(n=1; nval = 2.0/(M_PI*x) / (Jnup1_Jnu*Yn - Ynp1); result->err = GSL_DBL_EPSILON * (N + 2.0) * fabs(result->val); return GSL_ERROR_SELECT_2(stat_mu, stat_CF1); } else { /* Recurse backward from nu to mu, determining the J ratio * at mu. Use this together with a Steed method CF2 to * determine the actual J_mu, and thus obtain the normalization. */ double Jmu; double Jmup1_Jmu; double sgn_Jmu; double Jmuprime_Jmu; double P, Q; const int stat_CF2 = gsl_sf_bessel_JY_steed_CF2(mu, x, &P, &Q); double gamma; double Jnp1 = sgn_Jnu * GSL_SQRT_DBL_MIN * Jnup1_Jnu; double Jn = sgn_Jnu * GSL_SQRT_DBL_MIN; double Jnm1; int n; for(n=N; n>0; n--) { Jnm1 = 2.0*(mu+n)/x * Jn - Jnp1; Jnp1 = Jn; Jn = Jnm1; } Jmup1_Jmu = Jnp1/Jn; sgn_Jmu = GSL_SIGN(Jn); Jmuprime_Jmu = mu/x - Jmup1_Jmu; gamma = (P - Jmuprime_Jmu)/Q; Jmu = sgn_Jmu * sqrt(2.0/(M_PI*x) / (Q + gamma*(P-Jmuprime_Jmu))); result->val = Jmu * (sgn_Jnu * GSL_SQRT_DBL_MIN) / Jn; result->err = 2.0 * GSL_DBL_EPSILON * (N + 2.0) * fabs(result->val); return GSL_ERROR_SELECT_2(stat_CF2, stat_CF1); } } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_bessel_Jnu(const double nu, const double x) { EVAL_RESULT(gsl_sf_bessel_Jnu_e(nu, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__bessel_K0.c000066400000000000000000000135571261542461700222070ustar00rootroot00000000000000/* specfunc/bessel_K0.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_exp.h" #include "gsl_sf_bessel.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__chebyshev.h" #include "gsl_specfunc__cheb_eval.c" /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/ /* based on SLATEC bk0(), bk0e() */ /* chebyshev expansions series for bk0 on the interval 0. to 4.00000d+00 with weighted error 3.57e-19 log weighted error 18.45 significant figures required 17.99 decimal places required 18.97 series for ak0 on the interval 1.25000d-01 to 5.00000d-01 with weighted error 5.34e-17 log weighted error 16.27 significant figures required 14.92 decimal places required 16.89 series for ak02 on the interval 0. to 1.25000d-01 with weighted error 2.34e-17 log weighted error 16.63 significant figures required 14.67 decimal places required 17.20 */ static double bk0_data[11] = { -0.03532739323390276872, 0.3442898999246284869, 0.03597993651536150163, 0.00126461541144692592, 0.00002286212103119451, 0.00000025347910790261, 0.00000000190451637722, 0.00000000001034969525, 0.00000000000004259816, 0.00000000000000013744, 0.00000000000000000035 }; static cheb_series bk0_cs = { bk0_data, 10, -1, 1, 10 }; static double ak0_data[17] = { -0.07643947903327941, -0.02235652605699819, 0.00077341811546938, -0.00004281006688886, 0.00000308170017386, -0.00000026393672220, 0.00000002563713036, -0.00000000274270554, 0.00000000031694296, -0.00000000003902353, 0.00000000000506804, -0.00000000000068895, 0.00000000000009744, -0.00000000000001427, 0.00000000000000215, -0.00000000000000033, 0.00000000000000005 }; static cheb_series ak0_cs = { ak0_data, 16, -1, 1, 10 }; static double ak02_data[14] = { -0.01201869826307592, -0.00917485269102569, 0.00014445509317750, -0.00000401361417543, 0.00000015678318108, -0.00000000777011043, 0.00000000046111825, -0.00000000003158592, 0.00000000000243501, -0.00000000000020743, 0.00000000000001925, -0.00000000000000192, 0.00000000000000020, -0.00000000000000002 }; static cheb_series ak02_cs = { ak02_data, 13, -1, 1, 8 }; /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_bessel_K0_scaled_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= 0.0) { DOMAIN_ERROR(result); } else if(x <= 2.0) { const double lx = log(x); const double ex = exp(x); int stat_I0; gsl_sf_result I0; gsl_sf_result c; cheb_eval_e(&bk0_cs, 0.5*x*x-1.0, &c); stat_I0 = gsl_sf_bessel_I0_e(x, &I0); result->val = ex * ((-lx+M_LN2)*I0.val - 0.25 + c.val); result->err = ex * ((M_LN2+fabs(lx))*I0.err + c.err); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_I0; } else if(x <= 8.0) { const double sx = sqrt(x); gsl_sf_result c; cheb_eval_e(&ak0_cs, (16.0/x-5.0)/3.0, &c); result->val = (1.25 + c.val) / sx; result->err = c.err / sx; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { const double sx = sqrt(x); gsl_sf_result c; cheb_eval_e(&ak02_cs, 16.0/x-1.0, &c); result->val = (1.25 + c.val) / sx; result->err = (c.err + GSL_DBL_EPSILON) / sx; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_bessel_K0_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= 0.0) { DOMAIN_ERROR(result); } else if(x <= 2.0) { const double lx = log(x); int stat_I0; gsl_sf_result I0; gsl_sf_result c; cheb_eval_e(&bk0_cs, 0.5*x*x-1.0, &c); stat_I0 = gsl_sf_bessel_I0_e(x, &I0); result->val = (-lx+M_LN2)*I0.val - 0.25 + c.val; result->err = (fabs(lx) + M_LN2) * I0.err + c.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_I0; } else { gsl_sf_result K0_scaled; int stat_K0 = gsl_sf_bessel_K0_scaled_e(x, &K0_scaled); int stat_e = gsl_sf_exp_mult_err_e(-x, GSL_DBL_EPSILON*fabs(x), K0_scaled.val, K0_scaled.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_K0); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_bessel_K0_scaled(const double x) { EVAL_RESULT(gsl_sf_bessel_K0_scaled_e(x, &result)); } double gsl_sf_bessel_K0(const double x) { EVAL_RESULT(gsl_sf_bessel_K0_e(x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__bessel_K1.c000066400000000000000000000140261261542461700222000ustar00rootroot00000000000000/* specfunc/bessel_K1.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_exp.h" #include "gsl_sf_bessel.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__chebyshev.h" #include "gsl_specfunc__cheb_eval.c" /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/ /* based on SLATEC besk1(), besk1e() */ /* chebyshev expansions series for bk1 on the interval 0. to 4.00000d+00 with weighted error 7.02e-18 log weighted error 17.15 significant figures required 16.73 decimal places required 17.67 series for ak1 on the interval 1.25000d-01 to 5.00000d-01 with weighted error 6.06e-17 log weighted error 16.22 significant figures required 15.41 decimal places required 16.83 series for ak12 on the interval 0. to 1.25000d-01 with weighted error 2.58e-17 log weighted error 16.59 significant figures required 15.22 decimal places required 17.16 */ static double bk1_data[11] = { 0.0253002273389477705, -0.3531559607765448760, -0.1226111808226571480, -0.0069757238596398643, -0.0001730288957513052, -0.0000024334061415659, -0.0000000221338763073, -0.0000000001411488392, -0.0000000000006666901, -0.0000000000000024274, -0.0000000000000000070 }; static cheb_series bk1_cs = { bk1_data, 10, -1, 1, 8 }; static double ak1_data[17] = { 0.27443134069738830, 0.07571989953199368, -0.00144105155647540, 0.00006650116955125, -0.00000436998470952, 0.00000035402774997, -0.00000003311163779, 0.00000000344597758, -0.00000000038989323, 0.00000000004720819, -0.00000000000604783, 0.00000000000081284, -0.00000000000011386, 0.00000000000001654, -0.00000000000000248, 0.00000000000000038, -0.00000000000000006 }; static cheb_series ak1_cs = { ak1_data, 16, -1, 1, 9 }; static double ak12_data[14] = { 0.06379308343739001, 0.02832887813049721, -0.00024753706739052, 0.00000577197245160, -0.00000020689392195, 0.00000000973998344, -0.00000000055853361, 0.00000000003732996, -0.00000000000282505, 0.00000000000023720, -0.00000000000002176, 0.00000000000000215, -0.00000000000000022, 0.00000000000000002 }; static cheb_series ak12_cs = { ak12_data, 13, -1, 1, 7 }; /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_bessel_K1_scaled_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= 0.0) { DOMAIN_ERROR(result); } else if(x < 2.0*GSL_DBL_MIN) { OVERFLOW_ERROR(result); } else if(x <= 2.0) { const double lx = log(x); const double ex = exp(x); int stat_I1; gsl_sf_result I1; gsl_sf_result c; cheb_eval_e(&bk1_cs, 0.5*x*x-1.0, &c); stat_I1 = gsl_sf_bessel_I1_e(x, &I1); result->val = ex * ((lx-M_LN2)*I1.val + (0.75 + c.val)/x); result->err = ex * (c.err/x + fabs(lx)*I1.err); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_I1; } else if(x <= 8.0) { const double sx = sqrt(x); gsl_sf_result c; cheb_eval_e(&ak1_cs, (16.0/x-5.0)/3.0, &c); result->val = (1.25 + c.val) / sx; result->err = c.err / sx; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { const double sx = sqrt(x); gsl_sf_result c; cheb_eval_e(&ak12_cs, 16.0/x-1.0, &c); result->val = (1.25 + c.val) / sx; result->err = c.err / sx; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_bessel_K1_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= 0.0) { DOMAIN_ERROR(result); } else if(x < 2.0*GSL_DBL_MIN) { OVERFLOW_ERROR(result); } else if(x <= 2.0) { const double lx = log(x); int stat_I1; gsl_sf_result I1; gsl_sf_result c; cheb_eval_e(&bk1_cs, 0.5*x*x-1.0, &c); stat_I1 = gsl_sf_bessel_I1_e(x, &I1); result->val = (lx-M_LN2)*I1.val + (0.75 + c.val)/x; result->err = c.err/x + fabs(lx)*I1.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_I1; } else { gsl_sf_result K1_scaled; int stat_K1 = gsl_sf_bessel_K1_scaled_e(x, &K1_scaled); int stat_e = gsl_sf_exp_mult_err_e(-x, 0.0, K1_scaled.val, K1_scaled.err, result); result->err = fabs(result->val) * (GSL_DBL_EPSILON*fabs(x) + K1_scaled.err/K1_scaled.val); return GSL_ERROR_SELECT_2(stat_e, stat_K1); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_bessel_K1_scaled(const double x) { EVAL_RESULT(gsl_sf_bessel_K1_scaled_e(x, &result)); } double gsl_sf_bessel_K1(const double x) { EVAL_RESULT(gsl_sf_bessel_K1_e(x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__bessel_Kn.c000066400000000000000000000147311261542461700223000ustar00rootroot00000000000000/* specfunc/bessel_Kn.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_gamma.h" #include "gsl_sf_psi.h" #include "gsl_sf_bessel.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__bessel.h" /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/ /* [Abramowitz+Stegun, 9.6.11] * assumes n >= 1 */ static int bessel_Kn_scaled_small_x(const int n, const double x, gsl_sf_result * result) { int k; double y = 0.25 * x * x; double ln_x_2 = log(0.5*x); double ex = exp(x); gsl_sf_result ln_nm1_fact; double k_term; double term1, sum1, ln_pre1; double term2, sum2, pre2; gsl_sf_lnfact_e((unsigned int)(n-1), &ln_nm1_fact); ln_pre1 = -n*ln_x_2 + ln_nm1_fact.val; if(ln_pre1 > GSL_LOG_DBL_MAX - 3.0) GSL_ERROR ("error", GSL_EOVRFLW); sum1 = 1.0; k_term = 1.0; for(k=1; k<=n-1; k++) { k_term *= -y/(k * (n-k)); sum1 += k_term; } term1 = 0.5 * exp(ln_pre1) * sum1; pre2 = 0.5 * exp(n*ln_x_2); if(pre2 > 0.0) { const int KMAX = 20; gsl_sf_result psi_n; gsl_sf_result npk_fact; double yk = 1.0; double k_fact = 1.0; double psi_kp1 = -M_EULER; double psi_npkp1; gsl_sf_psi_int_e(n, &psi_n); gsl_sf_fact_e((unsigned int)n, &npk_fact); psi_npkp1 = psi_n.val + 1.0/n; sum2 = (psi_kp1 + psi_npkp1 - 2.0*ln_x_2)/npk_fact.val; for(k=1; kval = ex * (term1 + term2); result->err = ex * GSL_DBL_EPSILON * (fabs(ln_pre1)*fabs(term1) + fabs(term2)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_bessel_Kn_scaled_e(int n, const double x, gsl_sf_result * result) { n = abs(n); /* K(-n, z) = K(n, z) */ /* CHECK_POINTER(result) */ if(x <= 0.0) { DOMAIN_ERROR(result); } else if(n == 0) { return gsl_sf_bessel_K0_scaled_e(x, result); } else if(n == 1) { return gsl_sf_bessel_K1_scaled_e(x, result); } else if(x <= 5.0) { return bessel_Kn_scaled_small_x(n, x, result); } else if(GSL_ROOT3_DBL_EPSILON * x > 0.25 * (n*n + 1)) { return gsl_sf_bessel_Knu_scaled_asympx_e((double)n, x, result); } else if(GSL_MIN(0.29/(n*n), 0.5/(n*n + x*x)) < GSL_ROOT3_DBL_EPSILON) { return gsl_sf_bessel_Knu_scaled_asymp_unif_e((double)n, x, result); } else { /* Upward recurrence. [Gradshteyn + Ryzhik, 8.471.1] */ double two_over_x = 2.0/x; gsl_sf_result r_b_jm1; gsl_sf_result r_b_j; int stat_0 = gsl_sf_bessel_K0_scaled_e(x, &r_b_jm1); int stat_1 = gsl_sf_bessel_K1_scaled_e(x, &r_b_j); double b_jm1 = r_b_jm1.val; double b_j = r_b_j.val; double b_jp1; int j; for(j=1; jval = b_j; result->err = n * (fabs(b_j) * (fabs(r_b_jm1.err/r_b_jm1.val) + fabs(r_b_j.err/r_b_j.val))); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_0, stat_1); } } int gsl_sf_bessel_Kn_e(const int n, const double x, gsl_sf_result * result) { const int status = gsl_sf_bessel_Kn_scaled_e(n, x, result); const double ex = exp(-x); result->val *= ex; result->err *= ex; result->err += x * GSL_DBL_EPSILON * fabs(result->val); return status; } int gsl_sf_bessel_Kn_scaled_array(const int nmin, const int nmax, const double x, double * result_array) { /* CHECK_POINTER(result_array) */ if(nmin < 0 || nmax < nmin || x <= 0.0) { int j; for(j=0; j<=nmax-nmin; j++) result_array[j] = 0.0; GSL_ERROR ("domain error", GSL_EDOM); } else if(nmax == 0) { gsl_sf_result b; int stat = gsl_sf_bessel_K0_scaled_e(x, &b); result_array[0] = b.val; return stat; } else { double two_over_x = 2.0/x; gsl_sf_result r_Knm1; gsl_sf_result r_Kn; int stat_0 = gsl_sf_bessel_Kn_scaled_e(nmin, x, &r_Knm1); int stat_1 = gsl_sf_bessel_Kn_scaled_e(nmin+1, x, &r_Kn); int stat = GSL_ERROR_SELECT_2(stat_0, stat_1); double Knp1; double Kn = r_Kn.val; double Knm1 = r_Knm1.val; int n; for(n=nmin+1; n<=nmax+1; n++) { if(Knm1 < GSL_DBL_MAX) { result_array[n-1-nmin] = Knm1; Knp1 = Knm1 + n * two_over_x * Kn; Knm1 = Kn; Kn = Knp1; } else { /* Overflow. Set the rest of the elements to * zero and bug out. * FIXME: Note: this relies on the convention * that the test x < DBL_MIN fails for x not * a number. This may be only an IEEE convention, * so the portability is unclear. */ int j; for(j=n; j<=nmax+1; j++) result_array[j-1-nmin] = 0.0; GSL_ERROR ("overflow", GSL_EOVRFLW); } } return stat; } } int gsl_sf_bessel_Kn_array(const int nmin, const int nmax, const double x, double * result_array) { int status = gsl_sf_bessel_Kn_scaled_array(nmin, nmax, x, result_array); double ex = exp(-x); int i; for(i=0; i<=nmax-nmin; i++) result_array[i] *= ex; return status; } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_bessel_Kn_scaled(const int n, const double x) { EVAL_RESULT(gsl_sf_bessel_Kn_scaled_e(n, x, &result)); } double gsl_sf_bessel_Kn(const int n, const double x) { EVAL_RESULT(gsl_sf_bessel_Kn_e(n, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__bessel_Knu.c000066400000000000000000000111641261542461700224620ustar00rootroot00000000000000/* specfunc/bessel_Knu.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_exp.h" #include "gsl_sf_gamma.h" #include "gsl_sf_bessel.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__bessel.h" #include "gsl_specfunc__bessel_temme.h" /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_bessel_Knu_scaled_e(const double nu, const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= 0.0 || nu < 0.0) { DOMAIN_ERROR(result); } else { int N = (int)(nu + 0.5); double mu = nu - N; /* -1/2 <= mu <= 1/2 */ double K_mu, K_mup1, Kp_mu; double K_nu, K_nup1, K_num1; int n; if(x < 2.0) { gsl_sf_bessel_K_scaled_temme(mu, x, &K_mu, &K_mup1, &Kp_mu); } else { gsl_sf_bessel_K_scaled_steed_temme_CF2(mu, x, &K_mu, &K_mup1, &Kp_mu); } /* recurse forward to obtain K_num1, K_nu */ K_nu = K_mu; K_nup1 = K_mup1; for(n=0; nval = K_nu; result->err = 2.0 * GSL_DBL_EPSILON * (N + 4.0) * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_bessel_Knu_e(const double nu, const double x, gsl_sf_result * result) { gsl_sf_result b; int stat_K = gsl_sf_bessel_Knu_scaled_e(nu, x, &b); int stat_e = gsl_sf_exp_mult_err_e(-x, 0.0, b.val, b.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_K); } int gsl_sf_bessel_lnKnu_e(const double nu, const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= 0.0 || nu < 0.0) { DOMAIN_ERROR(result); } else if(nu == 0.0) { gsl_sf_result K_scaled; /* This cannot underflow, and * it will not throw GSL_EDOM * since that is already checked. */ gsl_sf_bessel_K0_scaled_e(x, &K_scaled); result->val = -x + log(fabs(K_scaled.val)); result->err = GSL_DBL_EPSILON * fabs(x) + fabs(K_scaled.err/K_scaled.val); result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < 2.0 && nu > 1.0) { /* Make use of the inequality * Knu(x) <= 1/2 (2/x)^nu Gamma(nu), * which follows from the integral representation * [Abramowitz+Stegun, 9.6.23 (2)]. With this * we decide whether or not there is an overflow * problem because x is small. */ double ln_bound; gsl_sf_result lg_nu; gsl_sf_lngamma_e(nu, &lg_nu); ln_bound = -M_LN2 - nu*log(0.5*x) + lg_nu.val; if(ln_bound > GSL_LOG_DBL_MAX - 20.0) { /* x must be very small or nu very large (or both). */ double xi = 0.25*x*x; double sum = 1.0 - xi/(nu-1.0); if(nu > 2.0) sum += (xi/(nu-1.0)) * (xi/(nu-2.0)); result->val = ln_bound + log(sum); result->err = lg_nu.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } /* can drop-through here */ } { /* We passed the above tests, so no problem. * Evaluate as usual. Note the possible drop-through * in the above code! */ gsl_sf_result K_scaled; gsl_sf_bessel_Knu_scaled_e(nu, x, &K_scaled); result->val = -x + log(fabs(K_scaled.val)); result->err = GSL_DBL_EPSILON * fabs(x) + fabs(K_scaled.err/K_scaled.val); result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_bessel_Knu_scaled(const double nu, const double x) { EVAL_RESULT(gsl_sf_bessel_Knu_scaled_e(nu, x, &result)); } double gsl_sf_bessel_Knu(const double nu, const double x) { EVAL_RESULT(gsl_sf_bessel_Knu_e(nu, x, &result)); } double gsl_sf_bessel_lnKnu(const double nu, const double x) { EVAL_RESULT(gsl_sf_bessel_lnKnu_e(nu, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__bessel_Y0.c000066400000000000000000000071351261542461700222200ustar00rootroot00000000000000/* specfunc/bessel_Y0.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_trig.h" #include "gsl_sf_bessel.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__bessel.h" #include "gsl_specfunc__bessel_amp_phase.h" #include "gsl_specfunc__cheb_eval.c" /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/ /* based on SLATEC besy0, 1980 version, w. fullerton */ /* chebyshev expansions series for by0 on the interval 0. to 1.60000d+01 with weighted error 1.20e-17 log weighted error 16.92 significant figures required 16.15 decimal places required 17.48 */ static double by0_data[13] = { -0.011277839392865573, -0.128345237560420350, -0.104378847997942490, 0.023662749183969695, -0.002090391647700486, 0.000103975453939057, -0.000003369747162423, 0.000000077293842676, -0.000000001324976772, 0.000000000017648232, -0.000000000000188105, 0.000000000000001641, -0.000000000000000011 }; static cheb_series by0_cs = { by0_data, 12, -1, 1, 8 }; /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_bessel_Y0_e(const double x, gsl_sf_result * result) { const double two_over_pi = 2.0/M_PI; const double xmax = 1.0/GSL_DBL_EPSILON; /* CHECK_POINTER(result) */ if (x <= 0.0) { DOMAIN_ERROR(result); } else if(x < 4.0) { gsl_sf_result J0; gsl_sf_result c; int stat_J0 = gsl_sf_bessel_J0_e(x, &J0); cheb_eval_e(&by0_cs, 0.125*x*x-1.0, &c); result->val = two_over_pi*(-M_LN2 + log(x))*J0.val + 0.375 + c.val; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val) + c.err; return stat_J0; } else if(x < xmax) { /* Leading behaviour of phase is x, which is exact, * so the error is bounded. */ const double z = 32.0/(x*x) - 1.0; gsl_sf_result c1; gsl_sf_result c2; gsl_sf_result sp; const int stat_c1 = cheb_eval_e(&_gsl_sf_bessel_amp_phase_bm0_cs, z, &c1); const int stat_c2 = cheb_eval_e(&_gsl_sf_bessel_amp_phase_bth0_cs, z, &c2); const int stat_sp = gsl_sf_bessel_sin_pi4_e(x, c2.val/x, &sp); const double sqrtx = sqrt(x); const double ampl = (0.75 + c1.val) / sqrtx; result->val = ampl * sp.val; result->err = fabs(sp.val) * c1.err/sqrtx + fabs(ampl) * sp.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_3(stat_sp, stat_c1, stat_c2); } else { UNDERFLOW_ERROR(result); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_bessel_Y0(const double x) { EVAL_RESULT(gsl_sf_bessel_Y0_e(x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__bessel_Y1.c000066400000000000000000000102141261542461700222110ustar00rootroot00000000000000/* specfunc/bessel_Y1.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_trig.h" #include "gsl_sf_bessel.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__bessel.h" #include "gsl_specfunc__bessel_amp_phase.h" #include "gsl_specfunc__cheb_eval.c" /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/ /* based on SLATEC besy1, 1977 version, w. fullerton */ /* chebyshev expansions series for by1 on the interval 0. to 1.60000d+01 with weighted error 1.87e-18 log weighted error 17.73 significant figures required 17.83 decimal places required 18.30 */ static double by1_data[14] = { 0.03208047100611908629, 1.262707897433500450, 0.00649996189992317500, -0.08936164528860504117, 0.01325088122175709545, -0.00089790591196483523, 0.00003647361487958306, -0.00000100137438166600, 0.00000001994539657390, -0.00000000030230656018, 0.00000000000360987815, -0.00000000000003487488, 0.00000000000000027838, -0.00000000000000000186 }; static cheb_series by1_cs = { by1_data, 13, -1, 1, 10 }; /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_bessel_Y1_e(const double x, gsl_sf_result * result) { const double two_over_pi = 2.0/M_PI; const double xmin = 1.571*GSL_DBL_MIN; /*exp ( amax1(alog(r1mach(1)), -alog(r1mach(2)))+.01) */ const double x_small = 2.0 * GSL_SQRT_DBL_EPSILON; const double xmax = 1.0/GSL_DBL_EPSILON; /* CHECK_POINTER(result) */ if(x <= 0.0) { DOMAIN_ERROR(result); } else if(x < xmin) { OVERFLOW_ERROR(result); } else if(x < x_small) { const double lnterm = log(0.5*x); gsl_sf_result J1; gsl_sf_result c; int status = gsl_sf_bessel_J1_e(x, &J1); cheb_eval_e(&by1_cs, -1.0, &c); result->val = two_over_pi * lnterm * J1.val + (0.5 + c.val)/x; result->err = fabs(lnterm) * (fabs(GSL_DBL_EPSILON * J1.val) + J1.err) + c.err/x; return status; } else if(x < 4.0) { const double lnterm = log(0.5*x); int status; gsl_sf_result J1; gsl_sf_result c; cheb_eval_e(&by1_cs, 0.125*x*x-1.0, &c); status = gsl_sf_bessel_J1_e(x, &J1); result->val = two_over_pi * lnterm * J1.val + (0.5 + c.val)/x; result->err = fabs(lnterm) * (fabs(GSL_DBL_EPSILON * J1.val) + J1.err) + c.err/x; return status; } else if(x < xmax) { const double z = 32.0/(x*x) - 1.0; gsl_sf_result ca; gsl_sf_result ct; gsl_sf_result cp; const int stat_ca = cheb_eval_e(&_gsl_sf_bessel_amp_phase_bm1_cs, z, &ca); const int stat_ct = cheb_eval_e(&_gsl_sf_bessel_amp_phase_bth1_cs, z, &ct); const int stat_cp = gsl_sf_bessel_cos_pi4_e(x, ct.val/x, &cp); const double sqrtx = sqrt(x); const double ampl = (0.75 + ca.val) / sqrtx; result->val = -ampl * cp.val; result->err = fabs(cp.val) * ca.err/sqrtx + fabs(ampl) * cp.err; result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_3(stat_ca, stat_ct, stat_cp); } else { UNDERFLOW_ERROR(result); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_bessel_Y1(const double x) { EVAL_RESULT(gsl_sf_bessel_Y1_e(x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__bessel_Yn.c000066400000000000000000000126631261542461700223200ustar00rootroot00000000000000/* specfunc/bessel_Yn.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_gamma.h" #include "gsl_sf_psi.h" #include "gsl_sf_bessel.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__bessel.h" #include "gsl_specfunc__bessel_amp_phase.h" #include "gsl_specfunc__bessel_olver.h" /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/ /* assumes n >= 1 */ static int bessel_Yn_small_x(const int n, const double x, gsl_sf_result * result) { int k; double y = 0.25 * x * x; double ln_x_2 = log(0.5*x); gsl_sf_result ln_nm1_fact; double k_term; double term1, sum1, ln_pre1; double term2, sum2, pre2; gsl_sf_lnfact_e((unsigned int)(n-1), &ln_nm1_fact); ln_pre1 = -n*ln_x_2 + ln_nm1_fact.val; if(ln_pre1 > GSL_LOG_DBL_MAX - 3.0) GSL_ERROR ("error", GSL_EOVRFLW); sum1 = 1.0; k_term = 1.0; for(k=1; k<=n-1; k++) { k_term *= y/(k * (n-k)); sum1 += k_term; } term1 = -exp(ln_pre1) * sum1 / M_PI; pre2 = -exp(n*ln_x_2) / M_PI; if(fabs(pre2) > 0.0) { const int KMAX = 20; gsl_sf_result psi_n; gsl_sf_result npk_fact; double yk = 1.0; double k_fact = 1.0; double psi_kp1 = -M_EULER; double psi_npkp1; gsl_sf_psi_int_e(n, &psi_n); gsl_sf_fact_e((unsigned int)n, &npk_fact); psi_npkp1 = psi_n.val + 1.0/n; sum2 = (psi_kp1 + psi_npkp1 - 2.0*ln_x_2)/npk_fact.val; for(k=1; kval = term1 + term2; result->err = GSL_DBL_EPSILON * (fabs(ln_pre1)*fabs(term1) + fabs(term2)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_bessel_Yn_e(int n, const double x, gsl_sf_result * result) { int sign = 1; if(n < 0) { /* reduce to case n >= 0 */ n = -n; if(GSL_IS_ODD(n)) sign = -1; } /* CHECK_POINTER(result) */ if(n == 0) { int status = gsl_sf_bessel_Y0_e(x, result); result->val *= sign; return status; } else if(n == 1) { int status = gsl_sf_bessel_Y1_e(x, result); result->val *= sign; return status; } else { if(x <= 0.0) { DOMAIN_ERROR(result); } if(x < 5.0) { int status = bessel_Yn_small_x(n, x, result); result->val *= sign; return status; } else if(GSL_ROOT3_DBL_EPSILON * x > (n*n + 1.0)) { int status = gsl_sf_bessel_Ynu_asympx_e((double)n, x, result); result->val *= sign; return status; } else if(n > 50) { int status = gsl_sf_bessel_Ynu_asymp_Olver_e((double)n, x, result); result->val *= sign; return status; } else { double two_over_x = 2.0/x; gsl_sf_result r_by; gsl_sf_result r_bym; int stat_1 = gsl_sf_bessel_Y1_e(x, &r_by); int stat_0 = gsl_sf_bessel_Y0_e(x, &r_bym); double bym = r_bym.val; double by = r_by.val; double byp; int j; for(j=1; jval = sign * by; result->err = fabs(result->val) * (fabs(r_by.err/r_by.val) + fabs(r_bym.err/r_bym.val)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_1, stat_0); } } } int gsl_sf_bessel_Yn_array(const int nmin, const int nmax, const double x, double * result_array) { /* CHECK_POINTER(result_array) */ if(nmin < 0 || nmax < nmin || x <= 0.0) { int j; for(j=0; j<=nmax-nmin; j++) result_array[j] = 0.0; GSL_ERROR ("error", GSL_EDOM); } else { gsl_sf_result r_Ynm1; gsl_sf_result r_Yn; int stat_nm1 = gsl_sf_bessel_Yn_e(nmin, x, &r_Ynm1); int stat_n = gsl_sf_bessel_Yn_e(nmin+1, x, &r_Yn); double Ynp1; double Yn = r_Yn.val; double Ynm1 = r_Ynm1.val; int n; int stat = GSL_ERROR_SELECT_2(stat_nm1, stat_n); if(stat == GSL_SUCCESS) { for(n=nmin+1; n<=nmax+1; n++) { result_array[n-nmin-1] = Ynm1; Ynp1 = -Ynm1 + 2.0*n/x * Yn; Ynm1 = Yn; Yn = Ynp1; } } else { for(n=nmin; n<=nmax; n++) { result_array[n-nmin] = 0.0; } } return stat; } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_bessel_Yn(const int n, const double x) { EVAL_RESULT(gsl_sf_bessel_Yn_e(n, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__bessel_Ynu.c000066400000000000000000000066041261542461700225030ustar00rootroot00000000000000/* specfunc/bessel_Ynu.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_bessel.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__bessel.h" #include "gsl_specfunc__bessel_olver.h" #include "gsl_specfunc__bessel_temme.h" /* Perform forward recurrence for Y_nu(x) and Y'_nu(x) * * Y_{nu+1} = nu/x Y_nu - Y'_nu * Y'_{nu+1} = -(nu+1)/x Y_{nu+1} + Y_nu */ #if 0 static int bessel_Y_recur(const double nu_min, const double x, const int kmax, const double Y_start, const double Yp_start, double * Y_end, double * Yp_end) { double x_inv = 1.0/x; double nu = nu_min; double Y_nu = Y_start; double Yp_nu = Yp_start; int k; for(k=1; k<=kmax; k++) { double nuox = nu*x_inv; double Y_nu_save = Y_nu; Y_nu = -Yp_nu + nuox * Y_nu; Yp_nu = Y_nu_save - (nuox+x_inv) * Y_nu; nu += 1.0; } *Y_end = Y_nu; *Yp_end = Yp_nu; return GSL_SUCCESS; } #endif /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_bessel_Ynu_e(double nu, double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= 0.0 || nu < 0.0) { DOMAIN_ERROR(result); } else if(nu > 50.0) { return gsl_sf_bessel_Ynu_asymp_Olver_e(nu, x, result); } else { /* -1/2 <= mu <= 1/2 */ int N = (int)(nu + 0.5); double mu = nu - N; gsl_sf_result Y_mu, Y_mup1; int stat_mu; double Ynm1; double Yn; double Ynp1; int n; if(x < 2.0) { /* Determine Ymu, Ymup1 directly. This is really * an optimization since this case could as well * be handled by a call to gsl_sf_bessel_JY_mu_restricted(), * as below. */ stat_mu = gsl_sf_bessel_Y_temme(mu, x, &Y_mu, &Y_mup1); } else { /* Determine Ymu, Ymup1 and Jmu, Jmup1. */ gsl_sf_result J_mu, J_mup1; stat_mu = gsl_sf_bessel_JY_mu_restricted(mu, x, &J_mu, &J_mup1, &Y_mu, &Y_mup1); } /* Forward recursion to get Ynu, Ynup1. */ Ynm1 = Y_mu.val; Yn = Y_mup1.val; for(n=1; n<=N; n++) { Ynp1 = 2.0*(mu+n)/x * Yn - Ynm1; Ynm1 = Yn; Yn = Ynp1; } result->val = Ynm1; /* Y_nu */ result->err = (N + 1.0) * fabs(Ynm1) * (fabs(Y_mu.err/Y_mu.val) + fabs(Y_mup1.err/Y_mup1.val)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(Ynm1); return stat_mu; } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_bessel_Ynu(const double nu, const double x) { EVAL_RESULT(gsl_sf_bessel_Ynu_e(nu, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__bessel_amp_phase.c000066400000000000000000000110621261542461700236570ustar00rootroot00000000000000/* specfunc/bessel_amp_phase.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_bessel.h" #include "gsl_specfunc__bessel_amp_phase.h" /* chebyshev expansions for amplitude and phase functions used in bessel evaluations These are the same for J0,Y0 and for J1,Y1, so they sit outside those functions. */ static double bm0_data[21] = { 0.09284961637381644, -0.00142987707403484, 0.00002830579271257, -0.00000143300611424, 0.00000012028628046, -0.00000001397113013, 0.00000000204076188, -0.00000000035399669, 0.00000000007024759, -0.00000000001554107, 0.00000000000376226, -0.00000000000098282, 0.00000000000027408, -0.00000000000008091, 0.00000000000002511, -0.00000000000000814, 0.00000000000000275, -0.00000000000000096, 0.00000000000000034, -0.00000000000000012, 0.00000000000000004 }; const cheb_series _gsl_sf_bessel_amp_phase_bm0_cs = { bm0_data, 20, -1, 1, 10 }; static double bth0_data[24] = { -0.24639163774300119, 0.001737098307508963, -0.000062183633402968, 0.000004368050165742, -0.000000456093019869, 0.000000062197400101, -0.000000010300442889, 0.000000001979526776, -0.000000000428198396, 0.000000000102035840, -0.000000000026363898, 0.000000000007297935, -0.000000000002144188, 0.000000000000663693, -0.000000000000215126, 0.000000000000072659, -0.000000000000025465, 0.000000000000009229, -0.000000000000003448, 0.000000000000001325, -0.000000000000000522, 0.000000000000000210, -0.000000000000000087, 0.000000000000000036 }; const cheb_series _gsl_sf_bessel_amp_phase_bth0_cs = { bth0_data, 23, -1, 1, 12 }; static double bm1_data[21] = { 0.1047362510931285, 0.00442443893702345, -0.00005661639504035, 0.00000231349417339, -0.00000017377182007, 0.00000001893209930, -0.00000000265416023, 0.00000000044740209, -0.00000000008691795, 0.00000000001891492, -0.00000000000451884, 0.00000000000116765, -0.00000000000032265, 0.00000000000009450, -0.00000000000002913, 0.00000000000000939, -0.00000000000000315, 0.00000000000000109, -0.00000000000000039, 0.00000000000000014, -0.00000000000000005, }; const cheb_series _gsl_sf_bessel_amp_phase_bm1_cs = { bm1_data, 20, -1, 1, 10 }; static double bth1_data[24] = { 0.74060141026313850, -0.004571755659637690, 0.000119818510964326, -0.000006964561891648, 0.000000655495621447, -0.000000084066228945, 0.000000013376886564, -0.000000002499565654, 0.000000000529495100, -0.000000000124135944, 0.000000000031656485, -0.000000000008668640, 0.000000000002523758, -0.000000000000775085, 0.000000000000249527, -0.000000000000083773, 0.000000000000029205, -0.000000000000010534, 0.000000000000003919, -0.000000000000001500, 0.000000000000000589, -0.000000000000000237, 0.000000000000000097, -0.000000000000000040, }; const cheb_series _gsl_sf_bessel_amp_phase_bth1_cs = { bth1_data, 23, -1, 1, 12 }; int gsl_sf_bessel_asymp_Mnu_e(const double nu, const double x, double * result) { const double r = 2.0*nu/x; const double r2 = r*r; const double x2 = x*x; const double term1 = (r2-1.0/x2)/8.0; const double term2 = (r2-1.0/x2)*(r2-9.0/x2)*3.0/128.0; const double Mnu2_c = 2.0/(M_PI) * (1.0 + term1 + term2); *result = sqrt(Mnu2_c)/sqrt(x); /* will never underflow this way */ return GSL_SUCCESS; } int gsl_sf_bessel_asymp_thetanu_corr_e(const double nu, const double x, double * result) { const double r = 2.0*nu/x; const double r2 = r*r; const double x2 = x*x; const double term1 = x*(r2 - 1.0/x2)/8.0; const double term2 = x*(r2 - 1.0/x2)*(r2 - 25.0/x2)/384.0; *result = (-0.25*M_PI + term1 + term2); return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_specfunc__bessel_amp_phase.h000066400000000000000000000030051261542461700236620ustar00rootroot00000000000000/* specfunc/bessel_amp_phase.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef _BESSEL_AMP_PHASE_H_ #define _BESSEL_AMP_PHASE_H_ #include "gsl_specfunc__chebyshev.h" extern const cheb_series _gsl_sf_bessel_amp_phase_bm0_cs; extern const cheb_series _gsl_sf_bessel_amp_phase_bth0_cs; extern const cheb_series _gsl_sf_bessel_amp_phase_bm1_cs; extern const cheb_series _gsl_sf_bessel_amp_phase_bth1_cs; /* large argument expansions [Abramowitz+Stegun, 9.2.28-29] * * thetanu_corr = thetanu - x + 1/2 nu Pi * * assumes x > 0 */ int gsl_sf_bessel_asymp_Mnu_e(const double nu, const double x, double * result); int gsl_sf_bessel_asymp_thetanu_corr_e(const double nu, const double x, double * result); /* w/o x term */ #endif /* !_BESSEL_AMP_PHASE_H_ */ praat-6.0.04/external/gsl/gsl_specfunc__bessel_i.c000066400000000000000000000215361261542461700221610ustar00rootroot00000000000000/* specfunc/bessel_i.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_pow_int.h" #include "gsl_sf_bessel.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__bessel.h" /* i_{l+1}/i_l */ static int bessel_il_CF1(const int l, const double x, const double threshold, double * ratio) { const int kmax = 2000; double tk = 1.0; double sum = 1.0; double rhok = 0.0; int k; for(k=1; k<=kmax; k++) { double ak = (x/(2.0*l+1.0+2.0*k)) * (x/(2.0*l+3.0+2.0*k)); rhok = -ak*(1.0 + rhok)/(1.0 + ak*(1.0 + rhok)); tk *= rhok; sum += tk; if(fabs(tk/sum) < threshold) break; } *ratio = x/(2.0*l+3.0) * sum; if(k == kmax) GSL_ERROR ("error", GSL_EMAXITER); else return GSL_SUCCESS; } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_bessel_i0_scaled_e(const double x, gsl_sf_result * result) { double ax = fabs(x); /* CHECK_POINTER(result) */ if(x == 0.0) { result->val = 1.0; result->err = 0.0; return GSL_SUCCESS; } else if(ax < 0.2) { const double eax = exp(-ax); const double y = ax*ax; const double c1 = 1.0/6.0; const double c2 = 1.0/120.0; const double c3 = 1.0/5040.0; const double c4 = 1.0/362880.0; const double c5 = 1.0/39916800.0; const double sum = 1.0 + y*(c1 + y*(c2 + y*(c3 + y*(c4 + y*c5)))); result->val = eax * sum; result->err = 2.0 * GSL_DBL_EPSILON * result->val; } else if(ax < -0.5*GSL_LOG_DBL_EPSILON) { result->val = (1.0 - exp(-2.0*ax))/(2.0*ax); result->err = 2.0 * GSL_DBL_EPSILON * result->val; } else { result->val = 1.0/(2.0*ax); result->err = 2.0 * GSL_DBL_EPSILON * result->val; } return GSL_SUCCESS; } int gsl_sf_bessel_i1_scaled_e(const double x, gsl_sf_result * result) { double ax = fabs(x); /* CHECK_POINTER(result) */ if(x == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(ax < 3.0*GSL_DBL_MIN) { UNDERFLOW_ERROR(result); } else if(ax < 0.25) { const double eax = exp(-ax); const double y = x*x; const double c1 = 1.0/10.0; const double c2 = 1.0/280.0; const double c3 = 1.0/15120.0; const double c4 = 1.0/1330560.0; const double c5 = 1.0/172972800.0; const double sum = 1.0 + y*(c1 + y*(c2 + y*(c3 + y*(c4 + y*c5)))); result->val = eax * x/3.0 * sum; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { double ex = exp(-2.0*ax); result->val = 0.5 * (ax*(1.0+ex) - (1.0-ex)) / (ax*ax); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); if(x < 0.0) result->val = -result->val; return GSL_SUCCESS; } } int gsl_sf_bessel_i2_scaled_e(const double x, gsl_sf_result * result) { double ax = fabs(x); /* CHECK_POINTER(result) */ if(x == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(ax < 4.0*GSL_SQRT_DBL_MIN) { UNDERFLOW_ERROR(result); } else if(ax < 0.25) { const double y = x*x; const double c1 = 1.0/14.0; const double c2 = 1.0/504.0; const double c3 = 1.0/33264.0; const double c4 = 1.0/3459456.0; const double c5 = 1.0/518918400.0; const double sum = 1.0 + y*(c1 + y*(c2 + y*(c3 + y*(c4 + y*c5)))); const double pre = exp(-ax) * x*x/15.0; result->val = pre * sum; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { double ex = exp(-2.0*ax); double x2 = x*x; result->val = 0.5 * ((3.0+x2)*(1.0-ex) - 3.0*ax*(1.0+ex))/(ax*ax*ax); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_bessel_il_scaled_e(const int l, double x, gsl_sf_result * result) { double sgn = 1.0; double ax = fabs(x); if(x < 0.0) { /* i_l(-x) = (-1)^l i_l(x) */ sgn = ( GSL_IS_ODD(l) ? -1.0 : 1.0 ); x = -x; } if(l < 0) { DOMAIN_ERROR(result); } else if(x == 0.0) { result->val = ( l == 0 ? 1.0 : 0.0 ); result->err = 0.0; return GSL_SUCCESS; } else if(l == 0) { gsl_sf_result il; int stat_il = gsl_sf_bessel_i0_scaled_e(x, &il); result->val = sgn * il.val; result->err = il.err; return stat_il; } else if(l == 1) { gsl_sf_result il; int stat_il = gsl_sf_bessel_i1_scaled_e(x, &il); result->val = sgn * il.val; result->err = il.err; return stat_il; } else if(l == 2) { gsl_sf_result il; int stat_il = gsl_sf_bessel_i2_scaled_e(x, &il); result->val = sgn * il.val; result->err = il.err; return stat_il; } else if(x*x < 10.0*(l+1.5)/M_E) { gsl_sf_result b; int stat = gsl_sf_bessel_IJ_taylor_e(l+0.5, x, 1, 50, GSL_DBL_EPSILON, &b); double pre = exp(-ax) * sqrt((0.5*M_PI)/x); result->val = sgn * pre * b.val; result->err = pre * b.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat; } else if(l < 150) { gsl_sf_result i0_scaled; int stat_i0 = gsl_sf_bessel_i0_scaled_e(ax, &i0_scaled); double rat; int stat_CF1 = bessel_il_CF1(l, ax, GSL_DBL_EPSILON, &rat); double iellp1 = rat * GSL_SQRT_DBL_MIN; double iell = GSL_SQRT_DBL_MIN; double iellm1; int ell; for(ell = l; ell >= 1; ell--) { iellm1 = iellp1 + (2*ell + 1)/x * iell; iellp1 = iell; iell = iellm1; } result->val = sgn * i0_scaled.val * (GSL_SQRT_DBL_MIN / iell); result->err = i0_scaled.err * (GSL_SQRT_DBL_MIN / iell); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_i0, stat_CF1); } else if(GSL_MIN(0.29/(l*l+1.0), 0.5/(l*l+1.0+x*x)) < 0.5*GSL_ROOT3_DBL_EPSILON) { int status = gsl_sf_bessel_Inu_scaled_asymp_unif_e(l + 0.5, x, result); double pre = sqrt((0.5*M_PI)/x); result->val *= sgn * pre; result->err *= pre; return status; } else { /* recurse down from safe values */ double rt_term = sqrt((0.5*M_PI)/x); const int LMAX = 2 + (int) (1.2 / GSL_ROOT6_DBL_EPSILON); gsl_sf_result r_iellp1; gsl_sf_result r_iell; int stat_a1 = gsl_sf_bessel_Inu_scaled_asymp_unif_e(LMAX + 1 + 0.5, x, &r_iellp1); int stat_a2 = gsl_sf_bessel_Inu_scaled_asymp_unif_e(LMAX + 0.5, x, &r_iell); double iellp1 = r_iellp1.val; double iell = r_iell.val; double iellm1 = 0.0; int ell; iellp1 *= rt_term; iell *= rt_term; for(ell = LMAX; ell >= l+1; ell--) { iellm1 = iellp1 + (2*ell + 1)/x * iell; iellp1 = iell; iell = iellm1; } result->val = sgn * iellm1; result->err = fabs(result->val)*(GSL_DBL_EPSILON + fabs(r_iellp1.err/r_iellp1.val) + fabs(r_iell.err/r_iell.val)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_a1, stat_a2); } } int gsl_sf_bessel_il_scaled_array(const int lmax, const double x, double * result_array) { if(x == 0.0) { int ell; result_array[0] = 1.0; for (ell = lmax; ell >= 1; ell--) { result_array[ell] = 0.0; }; return GSL_SUCCESS; } else { int ell; gsl_sf_result r_iellp1; gsl_sf_result r_iell; int stat_0 = gsl_sf_bessel_il_scaled_e(lmax+1, x, &r_iellp1); int stat_1 = gsl_sf_bessel_il_scaled_e(lmax, x, &r_iell); double iellp1 = r_iellp1.val; double iell = r_iell.val; double iellm1; result_array[lmax] = iell; for(ell = lmax; ell >= 1; ell--) { iellm1 = iellp1 + (2*ell + 1)/x * iell; iellp1 = iell; iell = iellm1; result_array[ell-1] = iellm1; } return GSL_ERROR_SELECT_2(stat_0, stat_1); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_bessel_i0_scaled(const double x) { EVAL_RESULT(gsl_sf_bessel_i0_scaled_e(x, &result)); } double gsl_sf_bessel_i1_scaled(const double x) { EVAL_RESULT(gsl_sf_bessel_i1_scaled_e(x, &result)); } double gsl_sf_bessel_i2_scaled(const double x) { EVAL_RESULT(gsl_sf_bessel_i2_scaled_e(x, &result)); } double gsl_sf_bessel_il_scaled(const int l, const double x) { EVAL_RESULT(gsl_sf_bessel_il_scaled_e(l, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__bessel_j.c000066400000000000000000000255211261542461700221600ustar00rootroot00000000000000/* specfunc/bessel_j.c * * Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_pow_int.h" #include "gsl_sf_trig.h" #include "gsl_sf_bessel.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__bessel.h" #include "gsl_specfunc__bessel_olver.h" /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_bessel_j0_e(const double x, gsl_sf_result * result) { double ax = fabs(x); /* CHECK_POINTER(result) */ if(ax < 0.5) { const double y = x*x; const double c1 = -1.0/6.0; const double c2 = 1.0/120.0; const double c3 = -1.0/5040.0; const double c4 = 1.0/362880.0; const double c5 = -1.0/39916800.0; const double c6 = 1.0/6227020800.0; result->val = 1.0 + y*(c1 + y*(c2 + y*(c3 + y*(c4 + y*(c5 + y*c6))))); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { gsl_sf_result sin_result; const int stat = gsl_sf_sin_e(x, &sin_result); result->val = sin_result.val/x; result->err = fabs(sin_result.err/x); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat; } } int gsl_sf_bessel_j1_e(const double x, gsl_sf_result * result) { double ax = fabs(x); /* CHECK_POINTER(result) */ if(x == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(ax < 3.1*GSL_DBL_MIN) { UNDERFLOW_ERROR(result); } else if(ax < 0.25) { const double y = x*x; const double c1 = -1.0/10.0; const double c2 = 1.0/280.0; const double c3 = -1.0/15120.0; const double c4 = 1.0/1330560.0; const double c5 = -1.0/172972800.0; const double sum = 1.0 + y*(c1 + y*(c2 + y*(c3 + y*(c4 + y*c5)))); result->val = x/3.0 * sum; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { gsl_sf_result cos_result; gsl_sf_result sin_result; const int stat_cos = gsl_sf_cos_e(x, &cos_result); const int stat_sin = gsl_sf_sin_e(x, &sin_result); const double cos_x = cos_result.val; const double sin_x = sin_result.val; result->val = (sin_x/x - cos_x)/x; result->err = (fabs(sin_result.err/x) + fabs(cos_result.err))/fabs(x); result->err += 2.0 * GSL_DBL_EPSILON * (fabs(sin_x/(x*x)) + fabs(cos_x/x)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_cos, stat_sin); } } int gsl_sf_bessel_j2_e(const double x, gsl_sf_result * result) { double ax = fabs(x); /* CHECK_POINTER(result) */ if(x == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(ax < 4.0*GSL_SQRT_DBL_MIN) { UNDERFLOW_ERROR(result); } else if(ax < 1.3) { const double y = x*x; const double c1 = -1.0/14.0; const double c2 = 1.0/504.0; const double c3 = -1.0/33264.0; const double c4 = 1.0/3459456.0; const double c5 = -1.0/518918400; const double c6 = 1.0/105859353600.0; const double c7 = -1.0/28158588057600.0; const double c8 = 1.0/9461285587353600.0; const double c9 = -1.0/3916972233164390400.0; const double sum = 1.0+y*(c1+y*(c2+y*(c3+y*(c4+y*(c5+y*(c6+y*(c7+y*(c8+y*c9)))))))); result->val = y/15.0 * sum; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { gsl_sf_result cos_result; gsl_sf_result sin_result; const int stat_cos = gsl_sf_cos_e(x, &cos_result); const int stat_sin = gsl_sf_sin_e(x, &sin_result); const double cos_x = cos_result.val; const double sin_x = sin_result.val; const double f = (3.0/(x*x) - 1.0); result->val = (f * sin_x - 3.0*cos_x/x)/x; result->err = fabs(f * sin_result.err/x) + fabs((3.0*cos_result.err/x)/x); result->err += 2.0 * GSL_DBL_EPSILON * (fabs(f*sin_x/x) + 3.0*fabs(cos_x/(x*x))); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_cos, stat_sin); } } int gsl_sf_bessel_jl_e(const int l, const double x, gsl_sf_result * result) { if(l < 0 || x < 0.0) { DOMAIN_ERROR(result); } else if(x == 0.0) { result->val = ( l > 0 ? 0.0 : 1.0 ); result->err = 0.0; return GSL_SUCCESS; } else if(l == 0) { return gsl_sf_bessel_j0_e(x, result); } else if(l == 1) { return gsl_sf_bessel_j1_e(x, result); } else if(l == 2) { return gsl_sf_bessel_j2_e(x, result); } else if(x*x < 10.0*(l+0.5)/M_E) { gsl_sf_result b; int status = gsl_sf_bessel_IJ_taylor_e(l+0.5, x, -1, 50, GSL_DBL_EPSILON, &b); double pre = sqrt((0.5*M_PI)/x); result->val = pre * b.val; result->err = pre * b.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return status; } else if(GSL_ROOT4_DBL_EPSILON * x > (l*l + l + 1.0)) { gsl_sf_result b; int status = gsl_sf_bessel_Jnu_asympx_e(l + 0.5, x, &b); double pre = sqrt((0.5*M_PI)/x); result->val = pre * b.val; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val) + pre * b.err; return status; } else if(l > 1.0/GSL_ROOT6_DBL_EPSILON) { gsl_sf_result b; int status = gsl_sf_bessel_Jnu_asymp_Olver_e(l + 0.5, x, &b); double pre = sqrt((0.5*M_PI)/x); result->val = pre * b.val; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val) + pre * b.err; return status; } else if(x > 1000.0 && x > 100.0*l*l) { /* We need this to avoid feeding large x to CF1; note that * due to the above check, we know that n <= 50. */ gsl_sf_result b; int status = gsl_sf_bessel_Jnu_asympx_e(l + 0.5, x, &b); double pre = sqrt((0.5*M_PI)/x); result->val = pre * b.val; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val) + pre * b.err; return status; } else { double sgn; double ratio; int stat_CF1 = gsl_sf_bessel_J_CF1(l+0.5, x, &ratio, &sgn); double jellp1 = GSL_SQRT_DBL_EPSILON * ratio; double jell = GSL_SQRT_DBL_EPSILON; double jellm1; int ell; for(ell = l; ell > 0; ell--) { jellm1 = -jellp1 + (2*ell + 1)/x * jell; jellp1 = jell; jell = jellm1; } if(fabs(jell) > fabs(jellp1)) { gsl_sf_result j0_result; int stat_j0 = gsl_sf_bessel_j0_e(x, &j0_result); double pre = GSL_SQRT_DBL_EPSILON / jell; result->val = j0_result.val * pre; result->err = j0_result.err * fabs(pre); result->err += 2.0 * GSL_DBL_EPSILON * (0.5*l + 1.0) * fabs(result->val); return GSL_ERROR_SELECT_2(stat_j0, stat_CF1); } else { gsl_sf_result j1_result; int stat_j1 = gsl_sf_bessel_j1_e(x, &j1_result); double pre = GSL_SQRT_DBL_EPSILON / jellp1; result->val = j1_result.val * pre; result->err = j1_result.err * fabs(pre); result->err += 2.0 * GSL_DBL_EPSILON * (0.5*l + 1.0) * fabs(result->val); return GSL_ERROR_SELECT_2(stat_j1, stat_CF1); } } } int gsl_sf_bessel_jl_array(const int lmax, const double x, double * result_array) { /* CHECK_POINTER(result_array) */ if(lmax < 0 || x < 0.0) { int j; for(j=0; j<=lmax; j++) result_array[j] = 0.0; GSL_ERROR ("error", GSL_EDOM); } else if(x == 0.0) { int j; for(j=1; j<=lmax; j++) result_array[j] = 0.0; result_array[0] = 1.0; return GSL_SUCCESS; } else { gsl_sf_result r_jellp1; gsl_sf_result r_jell; int stat_0 = gsl_sf_bessel_jl_e(lmax+1, x, &r_jellp1); int stat_1 = gsl_sf_bessel_jl_e(lmax, x, &r_jell); double jellp1 = r_jellp1.val; double jell = r_jell.val; double jellm1; int ell; result_array[lmax] = jell; for(ell = lmax; ell >= 1; ell--) { jellm1 = -jellp1 + (2*ell + 1)/x * jell; jellp1 = jell; jell = jellm1; result_array[ell-1] = jellm1; } return GSL_ERROR_SELECT_2(stat_0, stat_1); } } int gsl_sf_bessel_jl_steed_array(const int lmax, const double x, double * jl_x) { /* CHECK_POINTER(jl_x) */ if(lmax < 0 || x < 0.0) { int j; for(j=0; j<=lmax; j++) jl_x[j] = 0.0; GSL_ERROR ("error", GSL_EDOM); } else if(x == 0.0) { int j; for(j=1; j<=lmax; j++) jl_x[j] = 0.0; jl_x[0] = 1.0; return GSL_SUCCESS; } else if(x < 2.0*GSL_ROOT4_DBL_EPSILON) { /* first two terms of Taylor series */ double inv_fact = 1.0; /* 1/(1 3 5 ... (2l+1)) */ double x_l = 1.0; /* x^l */ int l; for(l=0; l<=lmax; l++) { jl_x[l] = x_l * inv_fact; jl_x[l] *= 1.0 - 0.5*x*x/(2.0*l+3.0); inv_fact /= 2.0*l+3.0; x_l *= x; } return GSL_SUCCESS; } else { /* Steed/Barnett algorithm [Comp. Phys. Comm. 21, 297 (1981)] */ double x_inv = 1.0/x; double W = 2.0*x_inv; double F = 1.0; double FP = (lmax+1.0) * x_inv; double B = 2.0*FP + x_inv; double end = B + 20000.0*W; double D = 1.0/B; double del = -D; FP += del; /* continued fraction */ do { B += W; D = 1.0/(B-D); del *= (B*D - 1.); FP += del; if(D < 0.0) F = -F; if(B > end) { GSL_ERROR ("error", GSL_EMAXITER); } } while(fabs(del) >= fabs(FP) * GSL_DBL_EPSILON); FP *= F; if(lmax > 0) { /* downward recursion */ double XP2 = FP; double PL = lmax * x_inv; int L = lmax; int LP; jl_x[lmax] = F; for(LP = 1; LP<=lmax; LP++) { jl_x[L-1] = PL * jl_x[L] + XP2; FP = PL*jl_x[L-1] - jl_x[L]; XP2 = FP; PL -= x_inv; --L; } F = jl_x[0]; } /* normalization */ W = x_inv / hypot(FP, F); jl_x[0] = W*F; if(lmax > 0) { int L; for(L=1; L<=lmax; L++) { jl_x[L] *= W; } } return GSL_SUCCESS; } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_bessel_j0(const double x) { EVAL_RESULT(gsl_sf_bessel_j0_e(x, &result)); } double gsl_sf_bessel_j1(const double x) { EVAL_RESULT(gsl_sf_bessel_j1_e(x, &result)); } double gsl_sf_bessel_j2(const double x) { EVAL_RESULT(gsl_sf_bessel_j2_e(x, &result)); } double gsl_sf_bessel_jl(const int l, const double x) { EVAL_RESULT(gsl_sf_bessel_jl_e(l, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__bessel_k.c000066400000000000000000000145241261542461700221620ustar00rootroot00000000000000/* specfunc/bessel_k.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_pow_int.h" #include "gsl_sf_gamma.h" #include "gsl_sf_bessel.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__check.h" #include "gsl_specfunc__bessel.h" /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/ /* [Abramowitz+Stegun, 10.2.4 + 10.2.6] * with lmax=15, precision ~ 15D for x < 3 * * assumes l >= 1 */ static int bessel_kl_scaled_small_x(int l, const double x, gsl_sf_result * result) { gsl_sf_result num_fact; double den = gsl_sf_pow_int(x, l+1); int stat_df = gsl_sf_doublefact_e((unsigned int) (2*l-1), &num_fact); if(stat_df != GSL_SUCCESS || den == 0.0) { OVERFLOW_ERROR(result); } else { const int lmax = 50; gsl_sf_result ipos_term; double ineg_term; double sgn = (GSL_IS_ODD(l) ? -1.0 : 1.0); double ex = exp(x); double t = 0.5*x*x; double sum = 1.0; double t_coeff = 1.0; double t_power = 1.0; double delta; int stat_il; int i; for(i=1; ival = -sgn * 0.5*M_PI * (ex*ipos_term.val - ineg_term); result->val *= ex; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_il; } } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_bessel_k0_scaled_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= 0.0) { DOMAIN_ERROR(result); } else { result->val = M_PI/(2.0*x); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); CHECK_UNDERFLOW(result); return GSL_SUCCESS; } } int gsl_sf_bessel_k1_scaled_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= 0.0) { DOMAIN_ERROR(result); } else if(x < (M_SQRTPI+1.0)/(M_SQRT2*GSL_SQRT_DBL_MAX)) { OVERFLOW_ERROR(result); } else { result->val = M_PI/(2.0*x) * (1.0 + 1.0/x); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); CHECK_UNDERFLOW(result); return GSL_SUCCESS; } } int gsl_sf_bessel_k2_scaled_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= 0.0) { DOMAIN_ERROR(result); } else if(x < 2.0/GSL_ROOT3_DBL_MAX) { OVERFLOW_ERROR(result); } else { result->val = M_PI/(2.0*x) * (1.0 + 3.0/x * (1.0 + 1.0/x)); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); CHECK_UNDERFLOW(result); return GSL_SUCCESS; } } int gsl_sf_bessel_kl_scaled_e(int l, const double x, gsl_sf_result * result) { if(l < 0 || x <= 0.0) { DOMAIN_ERROR(result); } else if(l == 0) { return gsl_sf_bessel_k0_scaled_e(x, result); } else if(l == 1) { return gsl_sf_bessel_k1_scaled_e(x, result); } else if(l == 2) { return gsl_sf_bessel_k2_scaled_e(x, result); } else if(x < 3.0) { return bessel_kl_scaled_small_x(l, x, result); } else if(GSL_ROOT3_DBL_EPSILON * x > (l*l + l + 1)) { int status = gsl_sf_bessel_Knu_scaled_asympx_e(l + 0.5, x, result); double pre = sqrt((0.5*M_PI)/x); result->val *= pre; result->err *= pre; return status; } else if(GSL_MIN(0.29/(l*l+1.0), 0.5/(l*l+1.0+x*x)) < GSL_ROOT3_DBL_EPSILON) { int status = gsl_sf_bessel_Knu_scaled_asymp_unif_e(l + 0.5, x, result); double pre = sqrt((0.5*M_PI)/x); result->val *= pre; result->err *= pre; return status; } else { /* recurse upward */ gsl_sf_result r_bk; gsl_sf_result r_bkm; int stat_1 = gsl_sf_bessel_k1_scaled_e(x, &r_bk); int stat_0 = gsl_sf_bessel_k0_scaled_e(x, &r_bkm); double bkp; double bk = r_bk.val; double bkm = r_bkm.val; int j; for(j=1; jval = bk; result->err = fabs(bk) * (fabs(r_bk.err/r_bk.val) + fabs(r_bkm.err/r_bkm.val)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_1, stat_0); } } int gsl_sf_bessel_kl_scaled_array(const int lmax, const double x, double * result_array) { if(lmax < 0 || x <= 0.0) { GSL_ERROR("domain error", GSL_EDOM); } else if (lmax == 0) { gsl_sf_result result; int stat = gsl_sf_bessel_k0_scaled_e(x, &result); result_array[0] = result.val; return stat; } else { int ell; double kellp1, kell, kellm1; gsl_sf_result r_kell; gsl_sf_result r_kellm1; gsl_sf_bessel_k1_scaled_e(x, &r_kell); gsl_sf_bessel_k0_scaled_e(x, &r_kellm1); kell = r_kell.val; kellm1 = r_kellm1.val; result_array[0] = kellm1; result_array[1] = kell; for(ell = 1; ell < lmax; ell++) { kellp1 = (2*ell+1)/x * kell + kellm1; result_array[ell+1] = kellp1; kellm1 = kell; kell = kellp1; } return GSL_SUCCESS; } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_bessel_k0_scaled(const double x) { EVAL_RESULT(gsl_sf_bessel_k0_scaled_e(x, &result)); } double gsl_sf_bessel_k1_scaled(const double x) { EVAL_RESULT(gsl_sf_bessel_k1_scaled_e(x, &result)); } double gsl_sf_bessel_k2_scaled(const double x) { EVAL_RESULT(gsl_sf_bessel_k2_scaled_e(x, &result)); } double gsl_sf_bessel_kl_scaled(const int l, const double x) { EVAL_RESULT(gsl_sf_bessel_kl_scaled_e(l, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__bessel_olver.c000066400000000000000000000762231261542461700230630ustar00rootroot00000000000000/* specfunc/bessel_olver.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_airy.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__bessel.h" #include "gsl_specfunc__bessel_olver.h" #include "gsl_specfunc__chebyshev.h" #include "gsl_specfunc__cheb_eval.c" /* fit for f(x) = zofmzeta((x+1)/2), 0 <= mzeta <= 1 */ static double zofmzeta_a_data[20] = { 2.9332563730829348990, 0.4896518224847036624, 0.0228637617355380860, -0.0001715731377284693, -0.0000105927538148751, 1.0595602530419e-6, -4.68016051691e-8, 5.8310020e-12, 1.766537581e-10, -1.45034640e-11, 4.357772e-13, 4.60971e-14, -2.57571e-14, 2.26468e-14, -2.22053e-14, 2.08593e-14, -1.84454e-14, 1.50150e-14, -1.06506e-14, 5.5375e-15 }; static cheb_series zofmzeta_a_cs = { zofmzeta_a_data, 19, -1,1, 8 }; /* fit for f(x) = zofmzeta((9x+11)/2), 1 <= mzeta <= 10 */ static double zofmzeta_b_data[30] = { 22.40725276466303489, 10.39808258825165581, 1.092050144486018425, -0.071111274777921604, 0.008990125336059704, -0.001201950338088875, 0.000106686807968315, 0.000017406491576830, -0.000014946669657805, 6.189984487752e-6, -2.049466715178e-6, 5.87189458020e-7, -1.46077514157e-7, 2.9803936132e-8, -3.817692108e-9, -4.66980416e-10, 5.83860334e-10, -2.78825299e-10, 1.01682688e-10, -3.1209928e-11, 8.111122e-12, -1.663986e-12, 1.81364e-13, 5.3414e-14, -4.7234e-14, 2.1689e-14, -7.815e-15, 2.371e-15, -6.04e-16, 1.20e-16 }; static cheb_series zofmzeta_b_cs = { zofmzeta_b_data, 29, -1,1, 15 }; /* fit for f(x) = zofmzeta(mz(x))/mz(x)^(3/2), * mz(x) = (2/(x+1))^(2/3) 10 * 10 <= mzeta <= Inf */ static double zofmzeta_c_data[11] = { 1.3824761227122911500, 0.0244856101686774245, -0.0000842866496282540, 1.4656076569771e-6, -3.14874099476e-8, 7.561134833e-10, -1.94531643e-11, 5.245878e-13, -1.46380e-14, 4.192e-16, -1.23e-17 }; static cheb_series zofmzeta_c_cs = { zofmzeta_c_data, 10, -1,1, 6 }; /* Invert [Abramowitz+Stegun, 9.3.39]. * Assumes minus_zeta >= 0. */ double gsl_sf_bessel_Olver_zofmzeta(double minus_zeta) { if(minus_zeta < 1.0) { const double x = 2.0*minus_zeta - 1.0; gsl_sf_result c; cheb_eval_e(&zofmzeta_a_cs, x, &c); return c.val; } else if(minus_zeta < 10.0) { const double x = (2.0*minus_zeta - 11.0)/9.0; gsl_sf_result c; cheb_eval_e(&zofmzeta_b_cs, x, &c); return c.val; } else { const double TEN_32 = 31.62277660168379332; /* 10^(3/2) */ const double p = pow(minus_zeta, 3.0/2.0); const double x = 2.0*TEN_32/p - 1.0; gsl_sf_result c; cheb_eval_e(&zofmzeta_c_cs, x, &c); return c.val * p; } } /* Chebyshev fit for f(x) = z(x)^6 A_3(z(x)), z(x) = 22/(10(x+1)) */ static double A3_gt1_data[31] = { -0.123783199829515294670493131190, 0.104636462534700704670877382304, -0.067500816575851826744877535903, 0.035563362418888483652711005520, -0.0160738524035979408472979609051, 0.0064497878252851092073278056238, -0.00235408261133449663958121821593, 0.00079545702851302155411892534965, -0.00025214920745855079895784825637, 0.00007574004596069392921153301833, -0.00002172917966339623434407978263, 5.9914810727868915476543145465e-06, -1.5958781571808992162953719817e-06, 4.1232986512903717525448312012e-07, -1.0369725993417659101913919101e-07, 2.5457982304266541145999235022e-08, -6.1161715053791743082427422443e-09, 1.4409346199138658887871461320e-09, -3.3350445956255561668232014995e-10, 7.5950686572918996453336138108e-11, -1.7042296334409430377389900278e-11, 3.7723525020626230919721640081e-12, -8.2460237635733980528416501227e-13, 1.7816961527997797696251868875e-13, -3.8084101506541792942694560802e-14, 8.0593669930916099079755351563e-15, -1.6896565961641739017452636964e-15, 3.5115651805888443184822853595e-16, -7.2384771938569255638904297651e-17, 1.4806598977677176106283840244e-17, -3.0069285750787303634897997963e-18 }; static cheb_series A3_gt1_cs = { A3_gt1_data, 30, -1,1, 17 }; /* chebyshev expansion for f(x) = z(x)^8 A_4(z(x)), z(x) = 12/(5(x+1)) */ static double A4_gt1_data[30] = { 1.15309329391198493586724229008, -1.01812701728669338904729927846, 0.71964022270555684403652781941, -0.42359963977172689685150061355, 0.215024488759339557817435404261, -0.096751915348145944032096342479, 0.039413982058824310099856035361, -0.014775225692561697963781115014, 0.005162114514159370516947823271, -0.00169783446445524322560925166335, 0.00052995667873006847211519193478, -0.00015802027574996477115667974856, 0.000045254366680989687988902825193, -0.000012503722965474638015488600967, 3.3457656998119148699124716204e-06, -8.6981575241150758412492331833e-07, 2.2030895484325645640823940625e-07, -5.4493369492600677068285936533e-08, 1.3190457281724829107139385556e-08, -3.1301560183377379158951191769e-09, 7.2937802527123344842593076131e-10, -1.6712080137945140407348940109e-10, 3.7700053248213600430503521194e-11, -8.3824538848817227637828899571e-12, 1.8388741910049766865274037194e-12, -3.9835919980753778560117573063e-13, 8.5288827136546615604290389711e-14, -1.8060227869114416998653266836e-14, 3.7849342199690728470461022877e-15, -7.8552867468122209577151823365e-16 }; static cheb_series A4_gt1_cs = { A4_gt1_data, 17, /* 29, */ -1, 1, 17 }; /* Chebyshev fit for f(x) = z(x)^3 B_2(z(x)), z(x) = 12/(5(x+1)) */ static double B2_gt1_data[40] = { 0.00118587147272683864479328868589, 0.00034820459990648274622193981840, -0.00030411304425639768103075864567, 0.00002812066284012343531484682886, 0.00004493525295901613184489898748, -0.00003037629997093072196779489677, 0.00001125979647123875721949743970, -2.4832533969517775991951008218e-06, -9.9003813640537799587086928278e-08, 4.9259859656183110299492296029e-07, -3.7644120964426705960749504975e-07, 2.2887828521334625189639122509e-07, -1.3202687370822203731489855050e-07, 7.7019669092537400811434860763e-08, -4.6589706973010511603890144294e-08, 2.9396476233013923711978522963e-08, -1.9293230611988282919101954538e-08, 1.3099107013728717842406906896e-08, -9.1509111940885962831104149355e-09, 6.5483472971925614347299375295e-09, -4.7831253582139967461241674569e-09, 3.5562625457426178152760148639e-09, -2.6853389444008414186916562103e-09, 2.0554738667134200145781857289e-09, -1.5923172019517426277886522758e-09, 1.2465923213464381457319481498e-09, -9.8494846881180588507969988989e-10, 7.8438674499372126663957464312e-10, -6.2877567918342950225937136855e-10, 5.0662318868755257959686944117e-10, -4.0962270881243451160378710952e-10, 3.3168684677374908553161911299e-10, -2.6829406619847450633596163305e-10, 2.1603988122184568375561077873e-10, -1.7232373309560278402012124481e-10, 1.3512709089611470626617830434e-10, -1.0285354732538663013167579792e-10, 7.4211345443901713467637018423e-11, -4.8124980266864320351456993068e-11, 2.3666534694476306077416831958e-11 }; static cheb_series B2_gt1_cs = { B2_gt1_data, 39, -1, 1, 30 }; /* Chebyshev fit for f(x) = z(x)^6 B_3(z(x)), z(x) = 12/(5(x+1)) */ static double B3_gt1_data[30] = { -0.0102445379362695740863663926486, 0.0036618484329295342954730801917, 0.0026154252498599303282569321117, -0.0036187389410353156728771706336, 0.0021878564157692275944613452462, -0.0008219952303590803584426516821, 0.0001281773889155631494321316520, 0.0001000944653368032985720548637, -0.0001288293344663774273453147788, 0.00010136264202696513867821487205, -0.00007000275849659556221916572733, 0.00004694886396757430431607955146, -0.00003190003869717837686356945696, 0.00002231453668447775219665947479, -0.00001611102197712439539300336438, 0.00001196634424990735214466633513, -9.0986920398931223804111374679e-06, 7.0492613694235423068926562567e-06, -5.5425216624642184684300615394e-06, 4.4071884714230296614449244106e-06, -3.5328595506791663127928952625e-06, 2.84594975572077091520522824686e-06, -2.29592697828824392391071619788e-06, 1.84714740375289956396370322228e-06, -1.47383331248116454652025598620e-06, 1.15687781098593231076084710267e-06, -8.8174688524627071175315084910e-07, 6.3705856964426840441434605593e-07, -4.1358791499961929237755474814e-07, 2.0354151158738819867477996807e-07 }; static cheb_series B3_gt1_cs = { B3_gt1_data, 29, -1, 1, 29 }; /* Chebyshev fit for f(x) = z(x) B_2(z(x)), z(x) = 2(x+1)/5 */ static double B2_lt1_data[40] = { 0.00073681565841337130021924199490, 0.00033803599647571227535304316937, -0.00008251723219239754024210552679, -0.00003390879948656432545900779710, 0.00001961398056848881816694014889, -2.35593745904151401624656805567e-06, -1.79055017080406086541563835433e-06, 1.33129571185610681090725934031e-06, -5.38879444715436544130673956170e-07, 1.49603056041381416881299945557e-07, -1.83377228267274327911131293091e-08, -1.33191430762944336526965187651e-08, 1.60642096463700438411396889489e-08, -1.28932576330421806740136816643e-08, 9.6169275086179165484403221944e-09, -7.1818502280703532276832887290e-09, 5.4744009217215145730697754561e-09, -4.2680446690508456935030086136e-09, 3.3941665009266174865683284781e-09, -2.7440714072221673882163135170e-09, 2.2488361522108255229193038962e-09, -1.8638240716608748862087923337e-09, 1.5592350940805373500866440401e-09, -1.3145743937732330609242633070e-09, 1.1153716777215047842790244968e-09, -9.5117576805266622854647303110e-10, 8.1428799553234876296804561100e-10, -6.9893770813548773664326279169e-10, 6.0073113636087448745018831981e-10, -5.1627434258513453901420776514e-10, 4.4290993195074905891788459756e-10, -3.7852978599966867611179315200e-10, 3.2143959338863177145307610452e-10, -2.7025926680620777594992221143e-10, 2.2384857772457918539228234321e-10, -1.8125071664276678046551271701e-10, 1.4164870008713668767293008546e-10, -1.0433101857132782485813325981e-10, 6.8663910168392483929411418190e-11, -3.4068313177952244040559740439e-11 }; static cheb_series B2_lt1_cs = { B2_lt1_data, 39, -1, 1, 39 }; /* Chebyshev fit for f(x) = B_3(2(x+1)/5) */ static double B3_lt1_data[40] = { -0.00137160820526992057354001614451, -0.00025474937951101049982680561302, 0.00024762975547895881652073467771, 0.00005229657281480196749313930265, -0.00007488354272621512385016593760, 0.00001416880012891046449980449746, 0.00001528986060172183690742576230, -0.00001668672297078590514293325326, 0.00001061765189536459018739585094, -5.8220577442406209989680801335e-06, 3.3322423743855900506302033234e-06, -2.23292405803003860894449897815e-06, 1.74816651036678291794777245325e-06, -1.49581306041395051804547535093e-06, 1.32759146107893129050610165582e-06, -1.19376077392564467408373553343e-06, 1.07878303863211630544654040875e-06, -9.7743335011819134006676476250e-07, 8.8729318903693324226127054792e-07, -8.0671146292125665050876015280e-07, 7.3432860378667354971042255937e-07, -6.6897926072697370325310483359e-07, 6.0966619703735610352576581485e-07, -5.5554095284507959561958605420e-07, 5.0588335673197236002812826526e-07, -4.6008146297767601862670079590e-07, 4.1761348515688145911438168306e-07, -3.7803230006989446874174476515e-07, 3.4095248501364300041684648230e-07, -3.0603959751354749520615015472e-07, 2.7300134179365690589640458993e-07, -2.4158028250762304756044254231e-07, 2.1154781038298751985689113868e-07, -1.8269911328756771201465223313e-07, 1.5484895085808513749026173074e-07, -1.2782806851555809369226440495e-07, 1.0148011725394892565174207341e-07, -7.5658969771439627809239950461e-08, 5.0226342286491286957075289622e-08, -2.5049645660259882970547555831e-08 }; static cheb_series B3_lt1_cs = { B3_lt1_data, 39, -1, 1, 39 }; /* Chebyshev fit for f(x) = A_3(9(x+1)/20) */ static double A3_lt1_data[40] = { -0.00017982561472134418587634980117, -0.00036558603837525275836608884064, -0.00002819398055929628850294406363, 0.00016704539863875736769812786067, -0.00007098969970347674307623044850, -8.4470843942344237748899879940e-06, 0.0000273413090343147765148014327150, -0.0000199073838489821681991178018081, 0.0000100004176278235088881096950105, -3.9739852013143676487867902026e-06, 1.2265357766449574306882693267e-06, -1.88755584306424047416914864854e-07, -1.37482206060161206336523452036e-07, 2.10326379301853336795686477738e-07, -2.05583778245412633433934301948e-07, 1.82377384812654863038691147988e-07, -1.58130247846381041027699152436e-07, 1.36966982725588978654041029615e-07, -1.19250280944620257443805710485e-07, 1.04477169029350256435316644493e-07, -9.2064832489437534542041040184e-08, 8.1523798290458784610230199344e-08, -7.2471794980050867512294061891e-08, 6.4614432955971132569968860233e-08, -5.7724095125560946811081322985e-08, 5.1623107567436835158110947901e-08, -4.6171250746798606260216486042e-08, 4.1256621998650164023254101585e-08, -3.6788925543159819135102047082e-08, 3.2694499457951844422299750661e-08, -2.89125899697964696586521743928e-08, 2.53925288725374047626589488217e-08, -2.20915707933726481321465184207e-08, 1.89732166352720474944407102940e-08, -1.60058977893259856012119939554e-08, 1.31619294542205876946742394494e-08, -1.04166651771938038563454275883e-08, 7.7478015858156185064152078434e-09, -5.1347942579352613057675111787e-09, 2.5583541594586723967261504321e-09 }; static cheb_series A3_lt1_cs = { A3_lt1_data, 39, -1, 1, 39 }; /* chebyshev fit for f(x) = A_4(2(x+1)/5) */ static double A4_lt1_data[30] = { 0.00009054703770051610946958226736, 0.00033066000498098017589672988293, 0.00019737453734363989127226073272, -0.00015490809725932037720034762889, -0.00004514948935538730085479280454, 0.00007976881782603940889444573924, -0.00003314566154544740986264993251, -1.88212148790135672249935711657e-06, 0.0000114788756505519986352882940648, -9.2263039911196207101468331210e-06, 5.1401128250377780476084336340e-06, -2.38418218951722002658891397905e-06, 1.00664292214481531598338960828e-06, -4.23224678096490060264249970540e-07, 2.00132031535793489976535190025e-07, -1.18689501178886741400633921047e-07, 8.7819524319114212999768013738e-08, -7.3964150324206644900787216386e-08, 6.5780431507637165113885884236e-08, -5.9651053193022652369837650411e-08, 5.4447762662767276209052293773e-08, -4.9802057381568863702541294988e-08, 4.5571368194694340198117635845e-08, -4.1682117173547642845382848197e-08, 3.8084701352766049815367147717e-08, -3.4740302885185237434662649907e-08, 3.1616557064701510611273692060e-08, -2.8685739487689556252374879267e-08, 2.5923752117132254429002796600e-08, -2.3309428552190587304662883477e-08 }; static cheb_series A4_lt1_cs = { A4_lt1_data, 29, -1, 1, 29 }; static double olver_B0(double z, double abs_zeta) { if(z < 0.98) { const double t = 1.0/sqrt(1.0-z*z); return -5.0/(48.0*abs_zeta*abs_zeta) + t*(-3.0 + 5.0*t*t)/(24.0*sqrt(abs_zeta)); } else if(z < 1.02) { const double a = 1.0-z; const double c0 = 0.0179988721413553309252458658183; const double c1 = 0.0111992982212877614645974276203; const double c2 = 0.0059404069786014304317781160605; const double c3 = 0.0028676724516390040844556450173; const double c4 = 0.0012339189052567271708525111185; const double c5 = 0.0004169250674535178764734660248; const double c6 = 0.0000330173385085949806952777365; const double c7 = -0.0001318076238578203009990106425; const double c8 = -0.0001906870370050847239813945647; return c0 + a*(c1 + a*(c2 + a*(c3 + a*(c4 + a*(c5 + a*(c6 + a*(c7 + a*c8))))))); } else { const double t = 1.0/(z*sqrt(1.0 - 1.0/(z*z))); return -5.0/(48.0*abs_zeta*abs_zeta) + t*(3.0 + 5.0*t*t)/(24.0*sqrt(abs_zeta)); } } static double olver_B1(double z, double abs_zeta) { if(z < 0.88) { const double t = 1.0/sqrt(1.0-z*z); const double t2 = t*t; const double rz = sqrt(abs_zeta); const double z32 = rz*rz*rz; const double z92 = z32*z32*z32; const double term1 = t*t*t * (30375.0 - 369603.0*t2 + 765765.0*t2*t2 - 425425.0*t2*t2*t2)/414720.0; const double term2 = 85085.0/(663552.0*z92); const double term3 = 385.0/110592.*t*(3.0-5.0*t2)/(abs_zeta*abs_zeta*abs_zeta); const double term4 = 5.0/55296.0*t2*(81.0 - 462.0*t2 + 385.0*t2*t2)/z32; return -(term1 + term2 + term3 + term4)/rz; } else if(z < 1.12) { const double a = 1.0-z; const double c0 = -0.00149282953213429172050073403334; const double c1 = -0.00175640941909277865678308358128; const double c2 = -0.00113346148874174912576929663517; const double c3 = -0.00034691090981382974689396961817; const double c4 = 0.00022752516104839243675693256916; const double c5 = 0.00051764145724244846447294636552; const double c6 = 0.00058906174858194233998714243010; const double c7 = 0.00053485514521888073087240392846; const double c8 = 0.00042891792986220150647633418796; const double c9 = 0.00031639765900613633260381972850; const double c10 = 0.00021908147678699592975840749194; return c0+a*(c1+a*(c2+a*(c3+a*(c4+a*(c5+a*(c6+a*(c7+a*(c8+a*(c9+a*c10))))))))); } else { const double t = 1.0/(z*sqrt(1.0 - 1.0/(z*z))); const double t2 = t*t; const double rz = sqrt(abs_zeta); const double z32 = rz*rz*rz; const double z92 = z32*z32*z32; const double term1 = -t2*t * (30375.0 + 369603.0*t2 + 765765.0*t2*t2 + 425425.0*t2*t2*t2)/414720.0; const double term2 = 85085.0/(663552.0*z92); const double term3 = -385.0/110592.0*t*(3.0+5.0*t2)/(abs_zeta*abs_zeta*abs_zeta); const double term4 = 5.0/55296.0*t2*(81.0 + 462.0*t2 + 385.0*t2*t2)/z32; return (term1 + term2 + term3 + term4)/rz; } } static double olver_B2(double z, double abs_zeta) { if(z < 0.8) { const double x = 5.0*z/2.0 - 1.0; gsl_sf_result c; cheb_eval_e(&B2_lt1_cs, x, &c); return c.val / z; } else if(z <= 1.2) { const double a = 1.0-z; const double c0 = 0.00055221307672129279005986982501; const double c1 = 0.00089586516310476929281129228969; const double c2 = 0.00067015003441569770883539158863; const double c3 = 0.00010166263361949045682945811828; const double c4 = -0.00044086345133806887291336488582; const double c5 = -0.00073963081508788743392883072523; const double c6 = -0.00076745494377839561259903887331; const double c7 = -0.00060829038106040362291568012663; const double c8 = -0.00037128707528893496121336168683; const double c9 = -0.00014116325105702609866850307176; return c0+a*(c1+a*(c2+a*(c3+a*(c4+a*(c5+a*(c6+a*(c7+a*(c8+a*c9)))))))); } else { const double zi = 1.0/z; const double x = 12.0/5.0 * zi - 1.0; gsl_sf_result c; cheb_eval_e(&B2_gt1_cs, x, &c); return c.val * zi*zi*zi; } } static double olver_B3(double z, double abs_zeta) { if(z < 0.8) { const double x = 5.0*z/2.0 - 1.0; gsl_sf_result c; cheb_eval_e(&B3_lt1_cs, x, &c); return c.val; } else if(z < 1.2) { const double a = 1.0-z; const double c0 = -0.00047461779655995980754441833105; const double c1 = -0.00095572913429464297452176811898; const double c2 = -0.00080369634512082892655558133973; const double c3 = -0.00000727921669154784138080600339; const double c4 = 0.00093162500331581345235746518994; const double c5 = 0.00149848796913751497227188612403; const double c6 = 0.00148406039675949727870390426462; return c0 + a*(c1 + a*(c2 + a*(c3 + a*(c4 + a*(c5 + a*c6))))); } else { const double x = 12.0/(5.0*z) - 1.0; const double zi2 = 1.0/(z*z); gsl_sf_result c; cheb_eval_e(&B3_gt1_cs, x, &c); return c.val * zi2*zi2*zi2; } } static double olver_A1(double z, double abs_zeta, double * err) { if(z < 0.98) { double t = 1.0/sqrt(1.0-z*z); double rz = sqrt(abs_zeta); double t2 = t*t; double term1 = t2*(81.0 - 462.0*t2 + 385.0*t2*t2)/1152.0; double term2 = -455.0/(4608.0*abs_zeta*abs_zeta*abs_zeta); double term3 = 7.0*t*(-3.0 + 5.0*t2)/(1152.0*rz*rz*rz); *err = 2.0 * GSL_DBL_EPSILON * (fabs(term1) + fabs(term2) + fabs(term3)); return term1 + term2 + term3; } else if(z < 1.02) { const double a = 1.0-z; const double c0 = -0.00444444444444444444444444444444; const double c1 = -0.00184415584415584415584415584416; const double c2 = 0.00056812076812076812076812076812; const double c3 = 0.00168137865661675185484709294233; const double c4 = 0.00186744042139000122193399504324; const double c5 = 0.00161330105833747826430066790326; const double c6 = 0.00123177312220625816558607537838; const double c7 = 0.00087334711007377573881689318421; const double c8 = 0.00059004942455353250141217015410; const double sum = c0+a*(c1+a*(c2+a*(c3+a*(c4+a*(c5+a*(c6+a*(c7+a*c8))))))); *err = 2.0 * GSL_DBL_EPSILON * fabs(sum); return sum; } else { const double t = 1.0/(z*sqrt(1.0 - 1.0/(z*z))); const double rz = sqrt(abs_zeta); const double t2 = t*t; const double term1 = -t2*(81.0 + 462.0*t2 + 385.0*t2*t2)/1152.0; const double term2 = 455.0/(4608.0*abs_zeta*abs_zeta*abs_zeta); const double term3 = -7.0*t*(3.0 + 5.0*t2)/(1152.0*rz*rz*rz); *err = 2.0 * GSL_DBL_EPSILON * (fabs(term1) + fabs(term2) + fabs(term3)); return term1 + term2 + term3; } } static double olver_A2(double z, double abs_zeta) { if(z < 0.88) { double t = 1.0/sqrt(1.0-z*z); double t2 = t*t; double t4 = t2*t2; double t6 = t4*t2; double t8 = t4*t4; double rz = sqrt(abs_zeta); double z3 = abs_zeta*abs_zeta*abs_zeta; double z32 = rz*rz*rz; double z92 = z3*z32; double term1 = t4*(4465125.0 - 94121676.0*t2 + 349922430.0*t4 - 446185740.0*t6 + 185910725.0*t8)/39813120.0; double term2 = -40415375.0/(127401984.0*z3*z3); double term3 = -95095.0/15925248.0*t*(3.0-5.0*t2)/z92; double term4 = -455.0/5308416.0 *t2*(81.0 - 462.0*t2 + 385.0*t4)/z3; double term5 = -7.0/19906560.0*t*t2*(30375.0 - 369603.0*t2 + 765765.0*t4 - 425425.0*t6)/z32; return term1 + term2 + term3 + term4 + term5; } else if(z < 1.12) { double a = 1.0-z; const double c0 = 0.000693735541354588973636592684210; const double c1 = 0.000464483490365843307019777608010; const double c2 = -0.000289036254605598132482570468291; const double c3 = -0.000874764943953712638574497548110; const double c4 = -0.001029716376139865629968584679350; const double c5 = -0.000836857329713810600584714031650; const double c6 = -0.000488910893527218954998270124540; const double c7 = -0.000144236747940817220502256810151; const double c8 = 0.000114363800986163478038576460325; const double c9 = 0.000266806881492777536223944807117; const double c10 = -0.011975517576151069627471048587000; return c0+a*(c1+a*(c2+a*(c3+a*(c4+a*(c5+a*(c6+a*(c7+a*(c8+a*(c9+a*c10))))))))); } else { const double t = 1.0/(z*sqrt(1.0 - 1.0/(z*z))); const double t2 = t*t; const double t4 = t2*t2; const double t6 = t4*t2; const double t8 = t4*t4; const double rz = sqrt(abs_zeta); const double z3 = abs_zeta*abs_zeta*abs_zeta; const double z32 = rz*rz*rz; const double z92 = z3*z32; const double term1 = t4*(4465125.0 + 94121676.0*t2 + 349922430.0*t4 + 446185740.0*t6 + 185910725.0*t8)/39813120.0; const double term2 = -40415375.0/(127401984.0*z3*z3); const double term3 = 95095.0/15925248.0*t*(3.0+5.0*t2)/z92; const double term4 = -455.0/5308416.0 *t2*(81.0 + 462.0*t2 + 385.0*t4)/z3; const double term5 = 7.0/19906560.0*t*t2*(30375.0 + 369603.0*t2 + 765765.0*t4 + 425425.0*t6)/z32; return term1 + term2 + term3 + term4 + term5; } } static double olver_A3(double z, double abs_zeta) { if(z < 0.9) { const double x = 20.0*z/9.0 - 1.0; gsl_sf_result c; cheb_eval_e(&A3_lt1_cs, x, &c); return c.val; } else if(z < 1.1) { double a = 1.0-z; const double c0 = -0.000354211971457743840771125759200; const double c1 = -0.000312322527890318832782774881353; const double c2 = 0.000277947465383133980329617631915; const double c3 = 0.000919803044747966977054155192400; const double c4 = 0.001147600388275977640983696906320; const double c5 = 0.000869239326123625742931772044544; const double c6 = 0.000287392257282507334785281718027; return c0 + a*(c1 + a*(c2 + a*(c3 + a*(c4 + a*(c5 + a*c6))))); } else { const double x = 11.0/(5.0*z) - 1.0; const double zi2 = 1.0/(z*z); gsl_sf_result c; cheb_eval_e(&A3_gt1_cs, x, &c); return c.val * zi2*zi2*zi2; } } static double olver_A4(double z, double abs_zeta) { if(z < 0.8) { const double x = 5.0*z/2.0 - 1.0; gsl_sf_result c; cheb_eval_e(&A4_lt1_cs, x, &c); return c.val; } else if(z < 1.2) { double a = 1.0-z; const double c0 = 0.00037819419920177291402661228437; const double c1 = 0.00040494390552363233477213857527; const double c2 = -0.00045764735528936113047289344569; const double c3 = -0.00165361044229650225813161341879; const double c4 = -0.00217527517983360049717137015539; const double c5 = -0.00152003287866490735107772795537; return c0 + a*(c1 + a*(c2 + a*(c3 + a*(c4 + a*c5)))); } else { const double x = 12.0/(5.0*z) - 1.0; const double zi2 = 1.0/(z*z); gsl_sf_result c; cheb_eval_e(&A4_gt1_cs, x, &c); return c.val * zi2*zi2*zi2*zi2; } } inline static double olver_Asum(double nu, double z, double abs_zeta, double * err) { double nu2 = nu*nu; double A1_err; double A1 = olver_A1(z, abs_zeta, &A1_err); double A2 = olver_A2(z, abs_zeta); double A3 = olver_A3(z, abs_zeta); double A4 = olver_A4(z, abs_zeta); *err = A1_err/nu2 + GSL_DBL_EPSILON; return 1.0 + A1/nu2 + A2/(nu2*nu2) + A3/(nu2*nu2*nu2) + A4/(nu2*nu2*nu2*nu2); } inline static double olver_Bsum(double nu, double z, double abs_zeta) { double nu2 = nu*nu; double B0 = olver_B0(z, abs_zeta); double B1 = olver_B1(z, abs_zeta); double B2 = olver_B2(z, abs_zeta); double B3 = olver_B3(z, abs_zeta); return B0 + B1/nu2 + B2/(nu2*nu2) + B3/(nu2*nu2*nu2*nu2); } /* uniform asymptotic, nu -> Inf, [Abramowitz+Stegun, 9.3.35] * * error: * nu = 2: uniformly good to > 6D * nu = 5: uniformly good to > 8D * nu = 10: uniformly good to > 10D * nu = 20: uniformly good to > 13D * */ int gsl_sf_bessel_Jnu_asymp_Olver_e(double nu, double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= 0.0 || nu <= 0.0) { DOMAIN_ERROR(result); } else { double zeta, abs_zeta; double arg; double pre; double asum, bsum, asum_err; gsl_sf_result ai; gsl_sf_result aip; double z = x/nu; double crnu = pow(nu, 1.0/3.0); double nu3 = nu*nu*nu; double nu11 = nu3*nu3*nu3*nu*nu; int stat_a, stat_ap; if(fabs(1.0-z) < 0.02) { const double a = 1.0-z; const double c0 = 1.25992104989487316476721060728; const double c1 = 0.37797631496846194943016318218; const double c2 = 0.230385563409348235843147082474; const double c3 = 0.165909603649648694839821892031; const double c4 = 0.12931387086451008907; const double c5 = 0.10568046188858133991; const double c6 = 0.08916997952268186978; const double c7 = 0.07700014900618802456; pre = c0 + a*(c1 + a*(c2 + a*(c3 + a*(c4 + a*(c5 + a*(c6 + a*c7)))))); zeta = a * pre; pre = sqrt(2.0*sqrt(pre/(1.0+z))); abs_zeta = fabs(zeta); } else if(z < 1.0) { double rt = sqrt(1.0 - z*z); abs_zeta = pow(1.5*(log((1.0+rt)/z) - rt), 2.0/3.0); zeta = abs_zeta; pre = sqrt(2.0*sqrt(abs_zeta/(rt*rt))); } else { /* z > 1 */ double rt = z * sqrt(1.0 - 1.0/(z*z)); abs_zeta = pow(1.5*(rt - acos(1.0/z)), 2.0/3.0); zeta = -abs_zeta; pre = sqrt(2.0*sqrt(abs_zeta/(rt*rt))); } asum = olver_Asum(nu, z, abs_zeta, &asum_err); bsum = olver_Bsum(nu, z, abs_zeta); arg = crnu*crnu * zeta; stat_a = gsl_sf_airy_Ai_e(arg, GSL_MODE_DEFAULT, &ai); stat_ap = gsl_sf_airy_Ai_deriv_e(arg, GSL_MODE_DEFAULT, &aip); result->val = pre * (ai.val*asum/crnu + aip.val*bsum/(nu*crnu*crnu)); result->err = pre * (ai.err * fabs(asum/crnu)); result->err += pre * fabs(ai.val) * asum_err / crnu; result->err += pre * fabs(ai.val * asum) / (crnu*nu11); result->err += 8.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_a, stat_ap); } } /* uniform asymptotic, nu -> Inf, [Abramowitz+Stegun, 9.3.36] * * error: * nu = 2: uniformly good to > 6D * nu = 5: uniformly good to > 8D * nu = 10: uniformly good to > 10D * nu = 20: uniformly good to > 13D */ int gsl_sf_bessel_Ynu_asymp_Olver_e(double nu, double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= 0.0 || nu <= 0.0) { DOMAIN_ERROR(result); } else { double zeta, abs_zeta; double arg; double pre; double asum, bsum, asum_err; gsl_sf_result bi; gsl_sf_result bip; double z = x/nu; double crnu = pow(nu, 1.0/3.0); double nu3 = nu*nu*nu; double nu11 = nu3*nu3*nu3*nu*nu; int stat_b, stat_d; if(fabs(1.0-z) < 0.02) { const double a = 1.0-z; const double c0 = 1.25992104989487316476721060728; const double c1 = 0.37797631496846194943016318218; const double c2 = 0.230385563409348235843147082474; const double c3 = 0.165909603649648694839821892031; const double c4 = 0.12931387086451008907; const double c5 = 0.10568046188858133991; const double c6 = 0.08916997952268186978; const double c7 = 0.07700014900618802456; pre = c0 + a*(c1 + a*(c2 + a*(c3 + a*(c4 + a*(c5 + a*(c6 + a*c7)))))); zeta = a * pre; pre = sqrt(2.0*sqrt(pre/(1.0+z))); abs_zeta = fabs(zeta); } else if(z < 1.0) { double rt = sqrt(1.0 - z*z); abs_zeta = pow(1.5*(log((1.0+rt)/z) - rt), 2.0/3.0); zeta = abs_zeta; pre = sqrt(2.0*sqrt(abs_zeta/(rt*rt))); } else { /* z > 1 */ double rt = z * sqrt(1.0 - 1.0/(z*z)); double ac = acos(1.0/z); abs_zeta = pow(1.5*(rt - ac), 2.0/3.0); zeta = -abs_zeta; pre = sqrt(2.0*sqrt(abs_zeta)/rt); } asum = olver_Asum(nu, z, abs_zeta, &asum_err); bsum = olver_Bsum(nu, z, abs_zeta); arg = crnu*crnu * zeta; stat_b = gsl_sf_airy_Bi_e(arg, GSL_MODE_DEFAULT, &bi); stat_d = gsl_sf_airy_Bi_deriv_e(arg, GSL_MODE_DEFAULT, &bip); result->val = -pre * (bi.val*asum/crnu + bip.val*bsum/(nu*crnu*crnu)); result->err = pre * (bi.err * fabs(asum/crnu)); result->err += pre * fabs(bi.val) * asum_err / crnu; result->err += pre * fabs(bi.val*asum) / (crnu*nu11); result->err += 8.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_b, stat_d); } } praat-6.0.04/external/gsl/gsl_specfunc__bessel_olver.h000066400000000000000000000022321261542461700230550ustar00rootroot00000000000000/* specfunc/bessel_olver.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef BESSEL_OLVER_H_ #define BESSEL_OLVER_H_ #include "gsl_sf_result.h" int gsl_sf_bessel_Jnu_asymp_Olver_e(double nu, double x, gsl_sf_result * result); int gsl_sf_bessel_Ynu_asymp_Olver_e(double nu, double x, gsl_sf_result * result); double gsl_sf_bessel_Olver_zofmzeta(double minus_zeta); #endif /* !BESSEL_OLVER_H_ */ praat-6.0.04/external/gsl/gsl_specfunc__bessel_sequence.c000066400000000000000000000102541261542461700235340ustar00rootroot00000000000000/* specfunc/bessel_sequence.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_bessel.h" #define DYDX_p(p,u,x) (-(p)/(x) + (((nu)*(nu))/((x)*(x))-1.0)*(u)) #define DYDX_u(p,u,x) (p) static int rk_step(double nu, double x, double dx, double * Jp, double * J) { double p_0 = *Jp; double u_0 = *J; double p_1 = dx * DYDX_p(p_0, u_0, x); double u_1 = dx * DYDX_u(p_0, u_0, x); double p_2 = dx * DYDX_p(p_0 + 0.5*p_1, u_0 + 0.5*u_1, x + 0.5*dx); double u_2 = dx * DYDX_u(p_0 + 0.5*p_1, u_0 + 0.5*u_1, x + 0.5*dx); double p_3 = dx * DYDX_p(p_0 + 0.5*p_2, u_0 + 0.5*u_2, x + 0.5*dx); double u_3 = dx * DYDX_u(p_0 + 0.5*p_2, u_0 + 0.5*u_2, x + 0.5*dx); double p_4 = dx * DYDX_p(p_0 + p_3, u_0 + u_3, x + dx); double u_4 = dx * DYDX_u(p_0 + p_3, u_0 + u_3, x + dx); *Jp = p_0 + p_1/6.0 + p_2/3.0 + p_3/3.0 + p_4/6.0; *J = u_0 + u_1/6.0 + u_2/3.0 + u_3/3.0 + u_4/6.0; return GSL_SUCCESS; } int gsl_sf_bessel_sequence_Jnu_e(double nu, gsl_mode_t mode, size_t size, double * v) { /* CHECK_POINTER(v) */ if(nu < 0.0) { GSL_ERROR ("domain error", GSL_EDOM); } else if(size == 0) { GSL_ERROR ("error", GSL_EINVAL); } else { const gsl_prec_t goal = GSL_MODE_PREC(mode); const double dx_array[] = { 0.001, 0.03, 0.1 }; /* double, single, approx */ const double dx_nominal = dx_array[goal]; const int cnu = (int) ceil(nu); const double nu13 = pow(nu,1.0/3.0); const double smalls[] = { 0.01, 0.02, 0.4, 0.7, 1.3, 2.0, 2.5, 3.2, 3.5, 4.5, 6.0 }; const double x_small = ( nu >= 10.0 ? nu - nu13 : smalls[cnu] ); gsl_sf_result J0, J1; double Jp, J; double x; size_t i = 0; /* Calculate the first point. */ x = v[0]; gsl_sf_bessel_Jnu_e(nu, x, &J0); v[0] = J0.val; ++i; /* Step over the idiot case where the * first point was actually zero. */ if(x == 0.0) { if(v[1] <= x) { /* Strict ordering failure. */ GSL_ERROR ("error", GSL_EFAILED); } x = v[1]; gsl_sf_bessel_Jnu_e(nu, x, &J0); v[1] = J0.val; ++i; } /* Calculate directly as long as the argument * is small. This is necessary because the * integration is not very good there. */ while(v[i] < x_small && i < size) { if(v[i] <= x) { /* Strict ordering failure. */ GSL_ERROR ("error", GSL_EFAILED); } x = v[i]; gsl_sf_bessel_Jnu_e(nu, x, &J0); v[i] = J0.val; ++i; } /* At this point we are ready to integrate. * The value of x is the last calculated * point, which has the value J0; v[i] is * the next point we need to calculate. We * calculate nu+1 at x as well to get * the derivative, then we go forward. */ gsl_sf_bessel_Jnu_e(nu+1.0, x, &J1); J = J0.val; Jp = -J1.val + nu/x * J0.val; while(i < size) { const double dv = v[i] - x; const int Nd = (int) ceil(dv/dx_nominal); const double dx = dv / Nd; double xj; int j; if(v[i] <= x) { /* Strict ordering failure. */ GSL_ERROR ("error", GSL_EFAILED); } /* Integrate over interval up to next sample point. */ for(j=0, xj=x; j 0. */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_mode.h" #include "gsl_specfunc__bessel_temme.h" #include "gsl_specfunc__chebyshev.h" #include "gsl_specfunc__cheb_eval.c" /* nu = (x+1)/4, -1val = -sum0; Ynu->err = (2.0 + 0.5*k) * GSL_DBL_EPSILON * fabs(Ynu->val); Ynup1->val = -sum1 * 2.0/x; Ynup1->err = (2.0 + 0.5*k) * GSL_DBL_EPSILON * fabs(Ynup1->val); stat_iter = ( k >= max_iter ? GSL_EMAXITER : GSL_SUCCESS ); return GSL_ERROR_SELECT_2(stat_iter, stat_g); } int gsl_sf_bessel_K_scaled_temme(const double nu, const double x, double * K_nu, double * K_nup1, double * Kp_nu) { const int max_iter = 15000; const double half_x = 0.5 * x; const double ln_half_x = log(half_x); const double half_x_nu = exp(nu*ln_half_x); const double pi_nu = M_PI * nu; const double sigma = -nu * ln_half_x; const double sinrat = (fabs(pi_nu) < GSL_DBL_EPSILON ? 1.0 : pi_nu/sin(pi_nu)); const double sinhrat = (fabs(sigma) < GSL_DBL_EPSILON ? 1.0 : sinh(sigma)/sigma); const double ex = exp(x); double sum0, sum1; double fk, pk, qk, hk, ck; int k = 0; int stat_iter; double g_1pnu, g_1mnu, g1, g2; int stat_g = gsl_sf_temme_gamma(nu, &g_1pnu, &g_1mnu, &g1, &g2); fk = sinrat * (cosh(sigma)*g1 - sinhrat*ln_half_x*g2); pk = 0.5/half_x_nu * g_1pnu; qk = 0.5*half_x_nu * g_1mnu; hk = pk; ck = 1.0; sum0 = fk; sum1 = hk; while(k < max_iter) { double del0; double del1; k++; fk = (k*fk + pk + qk)/(k*k-nu*nu); ck *= half_x*half_x/k; pk /= (k - nu); qk /= (k + nu); hk = -k*fk + pk; del0 = ck * fk; del1 = ck * hk; sum0 += del0; sum1 += del1; if(fabs(del0) < 0.5*fabs(sum0)*GSL_DBL_EPSILON) break; } *K_nu = sum0 * ex; *K_nup1 = sum1 * 2.0/x * ex; *Kp_nu = - *K_nup1 + nu/x * *K_nu; stat_iter = ( k == max_iter ? GSL_EMAXITER : GSL_SUCCESS ); return GSL_ERROR_SELECT_2(stat_iter, stat_g); } praat-6.0.04/external/gsl/gsl_specfunc__bessel_temme.h000066400000000000000000000023451261542461700230420ustar00rootroot00000000000000/* specfunc/bessel_temme.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef BESSEL_TEMME_H_ #define BESSEL_TEMME_H_ #include "gsl_sf_result.h" int gsl_sf_bessel_Y_temme(const double nu, const double x, gsl_sf_result * Y_nu, gsl_sf_result * Y_nup1); int gsl_sf_bessel_K_scaled_temme(const double nu, const double x, double * K_nu, double * K_nup1, double * Kp_nu); #endif /* !BESSEL_TEMME_H_ */ praat-6.0.04/external/gsl/gsl_specfunc__bessel_y.c000066400000000000000000000172521261542461700222010ustar00rootroot00000000000000/* specfunc/bessel_y.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_pow_int.h" #include "gsl_sf_gamma.h" #include "gsl_sf_trig.h" #include "gsl_sf_bessel.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__bessel.h" #include "gsl_specfunc__bessel_olver.h" /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/ /* [Abramowitz+Stegun, 10.1.3] * with lmax=15, precision ~ 15D for x < 3 * * checked OK [GJ] Wed May 13 15:41:25 MDT 1998 */ static int bessel_yl_small_x(int l, const double x, gsl_sf_result * result) { gsl_sf_result num_fact; double den = gsl_sf_pow_int(x, l+1); int stat_df = gsl_sf_doublefact_e(2*l-1, &num_fact); if(stat_df != GSL_SUCCESS || den == 0.0) { OVERFLOW_ERROR(result); } else { const int lmax = 200; double t = -0.5*x*x; double sum = 1.0; double t_coeff = 1.0; double t_power = 1.0; double delta; int i; for(i=1; i<=lmax; i++) { t_coeff /= i*(2*(i-l) - 1); t_power *= t; delta = t_power*t_coeff; sum += delta; if(fabs(delta/sum) < 0.5*GSL_DBL_EPSILON) break; } result->val = -num_fact.val/den * sum; result->err = GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_bessel_y0_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= 0.0) { DOMAIN_ERROR(result); } else if(1.0/GSL_DBL_MAX > 0.0 && x < 1.0/GSL_DBL_MAX) { OVERFLOW_ERROR(result); } else { gsl_sf_result cos_result; const int stat = gsl_sf_cos_e(x, &cos_result); result->val = -cos_result.val/x; result->err = fabs(cos_result.err/x); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat; } } int gsl_sf_bessel_y1_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= 0.0) { DOMAIN_ERROR(result); } else if(x < 1.0/GSL_SQRT_DBL_MAX) { OVERFLOW_ERROR(result); } else if(x < 0.25) { const double y = x*x; const double c1 = 1.0/2.0; const double c2 = -1.0/8.0; const double c3 = 1.0/144.0; const double c4 = -1.0/5760.0; const double c5 = 1.0/403200.0; const double c6 = -1.0/43545600.0; const double sum = 1.0 + y*(c1 + y*(c2 + y*(c3 + y*(c4 + y*(c5 + y*c6))))); result->val = -sum/y; result->err = GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { gsl_sf_result cos_result; gsl_sf_result sin_result; const int stat_cos = gsl_sf_cos_e(x, &cos_result); const int stat_sin = gsl_sf_sin_e(x, &sin_result); const double cx = cos_result.val; const double sx = sin_result.val; result->val = -(cx/x + sx)/x; result->err = (fabs(cos_result.err/x) + sin_result.err)/fabs(x); result->err += GSL_DBL_EPSILON * (fabs(sx/x) + fabs(cx/(x*x))); return GSL_ERROR_SELECT_2(stat_cos, stat_sin); } } int gsl_sf_bessel_y2_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= 0.0) { DOMAIN_ERROR(result); } else if(x < 1.0/GSL_ROOT3_DBL_MAX) { OVERFLOW_ERROR(result); } else if(x < 0.5) { const double y = x*x; const double c1 = 1.0/6.0; const double c2 = 1.0/24.0; const double c3 = -1.0/144.0; const double c4 = 1.0/3456.0; const double c5 = -1.0/172800.0; const double c6 = 1.0/14515200.0; const double c7 = -1.0/1828915200.0; const double sum = 1.0 + y*(c1 + y*(c2 + y*(c3 + y*(c4 + y*(c5 + y*(c6 + y*c7)))))); result->val = -3.0/(x*x*x) * sum; result->err = GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { gsl_sf_result cos_result; gsl_sf_result sin_result; const int stat_cos = gsl_sf_cos_e(x, &cos_result); const int stat_sin = gsl_sf_sin_e(x, &sin_result); const double sx = sin_result.val; const double cx = cos_result.val; const double a = 3.0/(x*x); result->val = (1.0 - a)/x * cx - a * sx; result->err = cos_result.err * fabs((1.0 - a)/x) + sin_result.err * fabs(a); result->err += GSL_DBL_EPSILON * (fabs(cx/x) + fabs(sx/(x*x))); return GSL_ERROR_SELECT_2(stat_cos, stat_sin); } } int gsl_sf_bessel_yl_e(int l, const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(l < 0 || x <= 0.0) { DOMAIN_ERROR(result); } else if(l == 0) { return gsl_sf_bessel_y0_e(x, result); } else if(l == 1) { return gsl_sf_bessel_y1_e(x, result); } else if(l == 2) { return gsl_sf_bessel_y2_e(x, result); } else if(x < 3.0) { return bessel_yl_small_x(l, x, result); } else if(GSL_ROOT3_DBL_EPSILON * x > (l*l + l + 1.0)) { int status = gsl_sf_bessel_Ynu_asympx_e(l + 0.5, x, result); double pre = sqrt((0.5*M_PI)/x); result->val *= pre; result->err *= pre; return status; } else if(l > 40) { int status = gsl_sf_bessel_Ynu_asymp_Olver_e(l + 0.5, x, result); double pre = sqrt((0.5*M_PI)/x); result->val *= pre; result->err *= pre; return status; } else { /* recurse upward */ gsl_sf_result r_by; gsl_sf_result r_bym; int stat_1 = gsl_sf_bessel_y1_e(x, &r_by); int stat_0 = gsl_sf_bessel_y0_e(x, &r_bym); double bym = r_bym.val; double by = r_by.val; double byp; int j; for(j=1; jval = by; result->err = fabs(result->val) * (GSL_DBL_EPSILON + fabs(r_by.err/r_by.val) + fabs(r_bym.err/r_bym.val)); return GSL_ERROR_SELECT_2(stat_1, stat_0); } } int gsl_sf_bessel_yl_array(const int lmax, const double x, double * result_array) { /* CHECK_POINTER(result_array) */ if(lmax < 0 || x <= 0.0) { GSL_ERROR ("error", GSL_EDOM); } else if (lmax == 0) { gsl_sf_result result; int stat = gsl_sf_bessel_y0_e(x, &result); result_array[0] = result.val; return stat; } else { gsl_sf_result r_yell; gsl_sf_result r_yellm1; int stat_1 = gsl_sf_bessel_y1_e(x, &r_yell); int stat_0 = gsl_sf_bessel_y0_e(x, &r_yellm1); double yellp1; double yell = r_yell.val; double yellm1 = r_yellm1.val; int ell; result_array[0] = yellm1; result_array[1] = yell; for(ell = 1; ell < lmax; ell++) { yellp1 = (2*ell+1)/x * yell - yellm1; result_array[ell+1] = yellp1; yellm1 = yell; yell = yellp1; } return GSL_ERROR_SELECT_2(stat_0, stat_1); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_bessel_y0(const double x) { EVAL_RESULT(gsl_sf_bessel_y0_e(x, &result)); } double gsl_sf_bessel_y1(const double x) { EVAL_RESULT(gsl_sf_bessel_y1_e(x, &result)); } double gsl_sf_bessel_y2(const double x) { EVAL_RESULT(gsl_sf_bessel_y2_e(x, &result)); } double gsl_sf_bessel_yl(const int l, const double x) { EVAL_RESULT(gsl_sf_bessel_yl_e(l, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__bessel_zero.c000066400000000000000000000702411261542461700227050ustar00rootroot00000000000000/* specfunc/bessel_zero.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_airy.h" #include "gsl_sf_pow_int.h" #include "gsl_sf_bessel.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__bessel_olver.h" /* For Chebyshev expansions of the roots as functions of nu, * see [G. Nemeth, Mathematical Approximation of Special Functions]. * This gives the fits for all nu and s <= 10. * I made the fits for other values of s myself [GJ]. */ /* Chebyshev expansion: j_{nu,1} = c_k T_k*(nu/2), nu <= 2 */ static const double coef_jnu1_a[] = { 3.801775243633476, 1.360704737511120, -0.030707710261106, 0.004526823746202, -0.000808682832134, 0.000159218792489, -0.000033225189761, 0.000007205599763, -0.000001606110397, 0.000000365439424, -0.000000084498039, 0.000000019793815, -0.000000004687054, 0.000000001120052, -0.000000000269767, 0.000000000065420, -0.000000000015961, 0.000000000003914, -0.000000000000965, 0.000000000000239, -0.000000000000059, 0.000000000000015, -0.000000000000004, 0.000000000000001 }; /* Chebyshev expansion: j_{nu,1} = nu c_k T_k*((2/nu)^(2/3)), nu >= 2 */ static const double coef_jnu1_b[] = { 1.735063412537096, 0.784478100951978, 0.048881473180370, -0.000578279783021, -0.000038984957864, 0.000005758297879, -0.000000327583229, -0.000000003853878, 0.000000002284653, -0.000000000153079, -0.000000000000895, 0.000000000000283, 0.000000000000043, 0.000000000000010, -0.000000000000003 }; /* Chebyshev expansion: j_{nu,2} = c_k T_k*(nu/2), nu <= 2 */ static const double coef_jnu2_a[] = { 6.992370244046161, 1.446379282056534, -0.023458616207293, 0.002172149448700, -0.000246262775620, 0.000030990180959, -0.000004154183047, 0.000000580766328, -0.000000083648175, 0.000000012317355, -0.000000001844887, 0.000000000280076, -0.000000000042986, 0.000000000006658, -0.000000000001039, 0.000000000000163, -0.000000000000026, 0.000000000000004, -0.000000000000001 }; /* Chebyshev expansion: j_{nu,2} = nu c_k T_k*((2/nu)^(2/3)), nu >= 2 */ static const double coef_jnu2_b[] = { 2.465611864263400, 1.607952988471069, 0.138758034431497, -0.003687791182054, -0.000051276007868, 0.000045113570749, -0.000007579172152, 0.000000736469208, -0.000000011118527, -0.000000011919884, 0.000000002696788, -0.000000000314488, 0.000000000008124, 0.000000000005211, -0.000000000001292, 0.000000000000158, -0.000000000000004, -0.000000000000003, 0.000000000000001 }; /* Chebyshev expansion: j_{nu,3} = c_k T_k*(nu/3), nu <= 3 */ static const double coef_jnu3_a[] = { 10.869647065239236, 2.177524286141710, -0.034822817125293, 0.003167249102413, -0.000353960349344, 0.000044039086085, -0.000005851380981, 0.000000812575483, -0.000000116463617, 0.000000017091246, -0.000000002554376, 0.000000000387335, -0.000000000059428, 0.000000000009207, -0.000000000001438, 0.000000000000226, -0.000000000000036, 0.000000000000006, -0.000000000000001 }; /* Chebyshev expansion: j_{nu,3} = nu c_k T_k*((3/nu)^(2/3)), nu >= 3 */ static const double coef_jnu3_b[] = { 2.522816775173244, 1.673199424973720, 0.146431617506314, -0.004049001763912, -0.000039517767244, 0.000048781729288, -0.000008729705695, 0.000000928737310, -0.000000028388244, -0.000000012927432, 0.000000003441008, -0.000000000471695, 0.000000000025590, 0.000000000005502, -0.000000000001881, 0.000000000000295, -0.000000000000020, -0.000000000000003, 0.000000000000001 }; /* Chebyshev expansion: j_{nu,4} = c_k T_k*(nu/4), nu <= 4 */ static const double coef_jnu4_a[] = { 14.750310252773009, 2.908010932941708, -0.046093293420315, 0.004147172321412, -0.000459092310473, 0.000056646951906, -0.000007472351546, 0.000001031210065, -0.000000147008137, 0.000000021475218, -0.000000003197208, 0.000000000483249, -0.000000000073946, 0.000000000011431, -0.000000000001782, 0.000000000000280, -0.000000000000044, 0.000000000000007, -0.000000000000001 }; /* Chebyshev expansion: j_{nu,4} = nu c_k T_k*((4/nu)^(2/3)), nu >= 4 */ static const double coef_jnu4_b[] = { 2.551681323117914, 1.706177978336572, 0.150357658406131, -0.004234001378590, -0.000033854229898, 0.000050763551485, -0.000009337464057, 0.000001029717834, -0.000000037474196, -0.000000013450153, 0.000000003836180, -0.000000000557404, 0.000000000035748, 0.000000000005487, -0.000000000002187, 0.000000000000374, -0.000000000000031, -0.000000000000003, 0.000000000000001 }; /* Chebyshev expansion: j_{nu,5} = c_k T_k*(nu/5), nu <= 5 */ static const double coef_jnu5_a[] = { 18.632261081028211, 3.638249012596966, -0.057329705998828, 0.005121709126820, -0.000563325259487, 0.000069100826174, -0.000009066603030, 0.000001245181383, -0.000000176737282, 0.000000025716695, -0.000000003815184, 0.000000000574839, -0.000000000087715, 0.000000000013526, -0.000000000002104, 0.000000000000330, -0.000000000000052, 0.000000000000008, -0.000000000000001 }; /* Chebyshev expansion: j_{nu,5} = nu c_k T_k*((5/nu)^(2/3)), nu >= 5 */ /* FIXME: There is something wrong with this fit, in about the * 9th or 10th decimal place. */ static const double coef_jnu5_b[] = { 2.569079487591442, 1.726073360882134, 0.152740776809531, -0.004346449660148, -0.000030512461856, 0.000052000821080, -0.000009713343981, 0.000001091997863, -0.000000043061707, -0.000000013779413, 0.000000004082870, -0.000000000611259, 0.000000000042242, 0.000000000005448, -0.000000000002377, 0.000000000000424, -0.000000000000038, -0.000000000000002, 0.000000000000002 }; /* Chebyshev expansion: j_{nu,6} = c_k T_k*(nu/6), nu <= 6 */ static const double coef_jnu6_a[] = { 22.514836143374042, 4.368367257557198, -0.068550155285562, 0.006093776505822, -0.000667152784957, 0.000081486022398, -0.000010649011647, 0.000001457089679, -0.000000206105082, 0.000000029894724, -0.000000004422012, 0.000000000664471, -0.000000000101140, 0.000000000015561, -0.000000000002416, 0.000000000000378, -0.000000000000060, 0.000000000000009, -0.000000000000002 }; /* Chebyshev expansion: j_{nu,6} = nu c_k T_k*((6/nu)^(2/3)), nu >= 6 */ static const double coef_jnu6_b[] = { 2.580710285494837, 1.739380728566154, 0.154340696401691, -0.004422028860168, -0.000028305272624, 0.000052845975269, -0.000009968794373, 0.000001134252926, -0.000000046841241, -0.000000014007555, 0.000000004251816, -0.000000000648213, 0.000000000046728, 0.000000000005414, -0.000000000002508, 0.000000000000459, -0.000000000000043, -0.000000000000002, 0.000000000000002 }; /* Chebyshev expansion: j_{nu,7} = c_k T_k*(nu/7), nu <= 7 */ static const double coef_jnu7_a[] = { 26.397760539730869, 5.098418721711790, -0.079761896398948, 0.007064521280487, -0.000770766522482, 0.000093835449636, -0.000012225308542, 0.000001667939800, -0.000000235288157, 0.000000034040347, -0.000000005023142, 0.000000000753101, -0.000000000114389, 0.000000000017564, -0.000000000002722, 0.000000000000425, -0.000000000000067, 0.000000000000011, -0.000000000000002 }; /* Chebyshev expansion: j_{nu,7} = nu c_k T_k*((7/nu)^(2/3)), nu >= 7 */ static const double coef_jnu7_b[] = { 2.589033335856773, 1.748907007612678, 0.155488900387653, -0.004476317805688, -0.000026737952924, 0.000053459680946, -0.000010153699240, 0.000001164804272, -0.000000049566917, -0.000000014175403, 0.000000004374840, -0.000000000675135, 0.000000000050004, 0.000000000005387, -0.000000000002603, 0.000000000000485, -0.000000000000047, -0.000000000000002, 0.000000000000002 }; /* Chebyshev expansion: j_{nu,8} = c_k T_k*(nu/8), nu <= 8 */ static const double coef_jnu8_a[] = { 30.280900001606662, 5.828429205461221, -0.090968381181069, 0.008034479731033, -0.000874254899080, 0.000106164151611, -0.000013798098749, 0.000001878187386, -0.000000264366627, 0.000000038167685, -0.000000005621060, 0.000000000841165, -0.000000000127538, 0.000000000019550, -0.000000000003025, 0.000000000000472, -0.000000000000074, 0.000000000000012, -0.000000000000002 }; /* Chebyshev expansion: j_{nu,8} = nu c_k T_k*((8/nu)^(2/3)), nu >= 8 */ static const double coef_jnu8_b[] = { 2.595283877150078, 1.756063044986928, 0.156352972371030, -0.004517201896761, -0.000025567187878, 0.000053925472558, -0.000010293734486, 0.000001187923085, -0.000000051625122, -0.000000014304212, 0.000000004468450, -0.000000000695620, 0.000000000052500, 0.000000000005367, -0.000000000002676, 0.000000000000505, -0.000000000000050, -0.000000000000002, 0.000000000000002 }; /* Chebyshev expansion: j_{nu,9} = c_k T_k*(nu/9), nu <= 9 */ static const double coef_jnu9_a[] = { 34.164181213238386, 6.558412747925228, -0.102171455365016, 0.009003934361201, -0.000977663914535, 0.000118479876579, -0.000015368714220, 0.000002088064285, -0.000000293381154, 0.000000042283900, -0.000000006217033, 0.000000000928887, -0.000000000140627, 0.000000000021526, -0.000000000003326, 0.000000000000518, -0.000000000000081, 0.000000000000013, -0.000000000000002 }; /* Chebyshev expansion: j_{nu,9} = nu c_k T_k*((9/nu)^(2/3)), nu >= 9 */ static const double coef_jnu9_b[] = { 2.600150240905079, 1.761635491694032, 0.157026743724010, -0.004549100368716, -0.000024659248617, 0.000054291035068, -0.000010403464334, 0.000001206027524, -0.000000053234089, -0.000000014406241, 0.000000004542078, -0.000000000711728, 0.000000000054464, 0.000000000005350, -0.000000000002733, 0.000000000000521, -0.000000000000052, -0.000000000000002, 0.000000000000002 }; /* Chebyshev expansion: j_{nu,10} = c_k T_k*(nu/10), nu <= 10 */ static const double coef_jnu10_a[] = { 38.047560766184647, 7.288377637926008, -0.113372193277897, 0.009973047509098, -0.001081019701335, 0.000130786983847, -0.000016937898538, 0.000002297699179, -0.000000322354218, 0.000000046392941, -0.000000006811759, 0.000000001016395, -0.000000000153677, 0.000000000023486, -0.000000000003616, 0.000000000000561, -0.000000000000095, 0.000000000000027, -0.000000000000013, 0.000000000000005 }; /* Chebyshev expansion: j_{nu,10} = nu c_k T_k*((10/nu)^(2/3)), nu >= 10 */ static const double coef_jnu10_b[] = { 2.604046346867949, 1.766097596481182, 0.157566834446511, -0.004574682244089, -0.000023934500688, 0.000054585558231, -0.000010491765415, 0.000001220589364, -0.000000054526331, -0.000000014489078, 0.000000004601510, -0.000000000724727, 0.000000000056049, 0.000000000005337, -0.000000000002779, 0.000000000000533, -0.000000000000054, -0.000000000000002, 0.000000000000002 }; /* Chebyshev expansion: j_{nu,11} = c_k T_k*(nu/22), nu <= 22 */ static const double coef_jnu11_a[] = { 49.5054081076848637, 15.33692279367165101, -0.33677234163517130, 0.04623235772920729, -0.00781084960665093, 0.00147217395434708, -0.00029695043846867, 0.00006273356860235, -0.00001370575125628, 3.07171282012e-6, -7.0235041249e-7, 1.6320559339e-7, -3.843117306e-8, 9.15083800e-9, -2.19957642e-9, 5.3301703e-10, -1.3007541e-10, 3.193827e-11, -7.88605e-12, 1.95918e-12, -4.9020e-13, 1.2207e-13, -2.820e-14, 5.25e-15, -1.88e-15, 2.80e-15, -2.45e-15 }; /* Chebyshev expansion: j_{nu,12} = c_k T_k*(nu/24), nu <= 24 */ static const double coef_jnu12_a[] = { 54.0787833216641519, 16.7336367772863598, -0.36718411124537953, 0.05035523375053820, -0.00849884978867533, 0.00160027692813434, -0.00032248114889921, 0.00006806354127199, -0.00001485665901339, 3.32668783672e-6, -7.5998952729e-7, 1.7644939709e-7, -4.151538210e-8, 9.87722772e-9, -2.37230133e-9, 5.7442875e-10, -1.4007767e-10, 3.437166e-11, -8.48215e-12, 2.10554e-12, -5.2623e-13, 1.3189e-13, -3.175e-14, 5.73e-15, 5.6e-16, -8.7e-16, -6.5e-16 }; /* Chebyshev expansion: j_{nu,13} = c_k T_k*(nu/26), nu <= 26 */ static const double coef_jnu13_a[] = { 58.6521941921708890, 18.1303398137970284, -0.39759381380126650, 0.05447765240465494, -0.00918674227679980, 0.00172835361420579, -0.00034800528297612, 0.00007339183835188, -0.00001600713368099, 3.58154960392e-6, -8.1759873497e-7, 1.8968523220e-7, -4.459745253e-8, 1.060304419e-8, -2.54487624e-9, 6.1580214e-10, -1.5006751e-10, 3.679707e-11, -9.07159e-12, 2.24713e-12, -5.5943e-13, 1.4069e-13, -3.679e-14, 1.119e-14, -4.99e-15, 3.43e-15, -2.85e-15, 2.3e-15, -1.7e-15, 8.7e-16 }; /* Chebyshev expansion: j_{nu,14} = c_k T_k*(nu/28), nu <= 28 */ static const double coef_jnu14_a[] = { 63.2256329577315566, 19.5270342832914901, -0.42800190567884337, 0.05859971627729398, -0.00987455163523582, 0.00185641011402081, -0.00037352439419968, 0.00007871886257265, -0.00001715728110045, 3.83632624437e-6, -8.7518558668e-7, 2.0291515353e-7, -4.767795233e-8, 1.132844415e-8, -2.71734219e-9, 6.5714886e-10, -1.6005342e-10, 3.922557e-11, -9.66637e-12, 2.39379e-12, -5.9541e-13, 1.4868e-13, -3.726e-14, 9.37e-15, -2.36e-15, 6.0e-16 }; /* Chebyshev expansion: j_{nu,15} = c_k T_k*(nu/30), nu <= 30 */ static const double coef_jnu15_a[] = { 67.7990939565631635, 20.9237219226859859, -0.45840871823085836, 0.06272149946755639, -0.01056229551143042, 0.00198445078693100, -0.00039903958650729, 0.00008404489865469, -0.00001830717574922, 4.09103745566e-6, -9.3275533309e-7, 2.1614056403e-7, -5.075725222e-8, 1.205352081e-8, -2.88971837e-9, 6.9846848e-10, -1.7002946e-10, 4.164941e-11, -1.025859e-11, 2.53921e-12, -6.3128e-13, 1.5757e-13, -3.947e-14, 9.92e-15, -2.50e-15, 6.3e-16 }; /* Chebyshev expansion: j_{nu,16} = c_k T_k*(nu/32), nu <= 32 */ static const double coef_jnu16_a[] = { 72.3725729616724770, 22.32040402918608585, -0.48881449782358690, 0.06684305681828766, -0.01124998690363398, 0.00211247882775445, -0.00042455166484632, 0.00008937015316346, -0.00001945687139551, 4.34569739281e-6, -9.9031173548e-7, 2.2936247195e-7, -5.383562595e-8, 1.277835103e-8, -3.06202860e-9, 7.3977037e-10, -1.8000071e-10, 4.407196e-11, -1.085046e-11, 2.68453e-12, -6.6712e-13, 1.6644e-13, -4.168e-14, 1.047e-14, -2.64e-15, 6.7e-16 }; /* Chebyshev expansion: j_{nu,17} = c_k T_k*(nu/34), nu <= 34 */ static const double coef_jnu17_a[] = { 76.9460667535209549, 23.71708159112252670, -0.51921943142405352, 0.07096442978067622, -0.01193763559341369, 0.00224049662974902, -0.00045006122941781, 0.00009469477941684, -0.00002060640777107, 4.60031647195e-6, -1.04785755046e-6, 2.4258161247e-7, -5.691327087e-8, 1.350298805e-8, -3.23428733e-9, 7.8105847e-10, -1.8996825e-10, 4.649350e-11, -1.144205e-11, 2.82979e-12, -7.0294e-13, 1.7531e-13, -4.388e-14, 1.102e-14, -2.78e-15, 7.0e-16 }; /* Chebyshev expansion: j_{nu,18} = c_k T_k*(nu/36), nu <= 36 */ static const double coef_jnu18_a[] = { 81.5195728368096659, 25.11375537470259305, -0.54962366347317668, 0.07508565026117689, -0.01262524908033818, 0.00236850602019778, -0.00047556873651929, 0.00010001889347161, -0.00002175581482429, 4.85490251239e-6, -1.10539483940e-6, 2.5579853343e-7, -5.999033352e-8, 1.422747129e-8, -3.40650521e-9, 8.2233565e-10, -1.9993286e-10, 4.891426e-11, -1.203343e-11, 2.97498e-12, -7.3875e-13, 1.8418e-13, -4.608e-14, 1.157e-14, -2.91e-15, 7.4e-16 }; /* Chebyshev expansion: j_{nu,19} = c_k T_k*(nu/38), nu <= 38 */ static const double coef_jnu19_a[] = { 86.0930892477047512, 26.51042598308271729, -0.58002730731948358, 0.07920674321589394, -0.01331283320930301, 0.00249650841778073, -0.00050107453900793, 0.00010534258471335, -0.00002290511552874, 5.10946148897e-6, -1.16292517157e-6, 2.6901365037e-7, -6.306692473e-8, 1.495183048e-8, -3.57869025e-9, 8.6360410e-10, -2.0989514e-10, 5.133439e-11, -1.262465e-11, 3.12013e-12, -7.7455e-13, 1.9304e-13, -4.829e-14, 1.212e-14, -3.05e-15, 7.7e-16 }; /* Chebyshev expansion: j_{nu,20} = c_k T_k*(nu/40), nu <= 40 */ static const double coef_jnu20_a[] = { 90.6666144195163770, 27.9070938975436823, -0.61043045315390591, 0.08332772844325554, -0.01400039260208282, 0.00262450494035660, -0.00052657891389470, 0.00011066592304919, -0.00002405432778364, 5.36399803946e-6, -1.22044976064e-6, 2.8222728362e-7, -6.614312964e-8, 1.567608839e-8, -3.75084856e-9, 9.0486546e-10, -2.1985553e-10, 5.375401e-11, -1.321572e-11, 3.26524e-12, -8.1033e-13, 2.0190e-13, -5.049e-14, 1.267e-14, -3.19e-15, 8.0e-16, -2.0e-16 }; static const double * coef_jnu_a[] = { 0, coef_jnu1_a, coef_jnu2_a, coef_jnu3_a, coef_jnu4_a, coef_jnu5_a, coef_jnu6_a, coef_jnu7_a, coef_jnu8_a, coef_jnu9_a, coef_jnu10_a, coef_jnu11_a, coef_jnu12_a, coef_jnu13_a, coef_jnu14_a, coef_jnu15_a, coef_jnu16_a, coef_jnu17_a, coef_jnu18_a, coef_jnu19_a, coef_jnu20_a }; static const size_t size_jnu_a[] = { 0, sizeof(coef_jnu1_a)/sizeof(double), sizeof(coef_jnu2_a)/sizeof(double), sizeof(coef_jnu3_a)/sizeof(double), sizeof(coef_jnu4_a)/sizeof(double), sizeof(coef_jnu5_a)/sizeof(double), sizeof(coef_jnu6_a)/sizeof(double), sizeof(coef_jnu7_a)/sizeof(double), sizeof(coef_jnu8_a)/sizeof(double), sizeof(coef_jnu9_a)/sizeof(double), sizeof(coef_jnu10_a)/sizeof(double), sizeof(coef_jnu11_a)/sizeof(double), sizeof(coef_jnu12_a)/sizeof(double), sizeof(coef_jnu13_a)/sizeof(double), sizeof(coef_jnu14_a)/sizeof(double), sizeof(coef_jnu15_a)/sizeof(double), sizeof(coef_jnu16_a)/sizeof(double), sizeof(coef_jnu17_a)/sizeof(double), sizeof(coef_jnu18_a)/sizeof(double), sizeof(coef_jnu19_a)/sizeof(double), sizeof(coef_jnu20_a)/sizeof(double) }; static const double * coef_jnu_b[] = { 0, coef_jnu1_b, coef_jnu2_b, coef_jnu3_b, coef_jnu4_b, coef_jnu5_b, coef_jnu6_b, coef_jnu7_b, coef_jnu8_b, coef_jnu9_b, coef_jnu10_b }; static const size_t size_jnu_b[] = { 0, sizeof(coef_jnu1_b)/sizeof(double), sizeof(coef_jnu2_b)/sizeof(double), sizeof(coef_jnu3_b)/sizeof(double), sizeof(coef_jnu4_b)/sizeof(double), sizeof(coef_jnu5_b)/sizeof(double), sizeof(coef_jnu6_b)/sizeof(double), sizeof(coef_jnu7_b)/sizeof(double), sizeof(coef_jnu8_b)/sizeof(double), sizeof(coef_jnu9_b)/sizeof(double), sizeof(coef_jnu10_b)/sizeof(double) }; /* Evaluate Clenshaw recurrence for * a T* Chebyshev series. * sizeof(c) = N+1 */ static double clenshaw(const double * c, int N, double u) { double B_np1 = 0.0; double B_n = c[N]; double B_nm1; int n; for(n=N; n>0; n--) { B_nm1 = 2.0*(2.0*u-1.0) * B_n - B_np1 + c[n-1]; B_np1 = B_n; B_n = B_nm1; } return B_n - (2.0*u-1.0)*B_np1; } /* correction terms to leading McMahon expansion * [Abramowitz+Stegun 9.5.12] * [Olver, Royal Society Math. Tables, v. 7] * We factor out a beta, so that this is a multiplicative * correction: * j_{nu,s} = beta(s,nu) * mcmahon_correction(nu, beta(s,nu)) * macmahon_correction --> 1 as s --> Inf */ static double mcmahon_correction(const double mu, const double beta) { const double eb = 8.0*beta; const double ebsq = eb*eb; if(mu < GSL_DBL_EPSILON) { /* Prevent division by zero below. */ const double term1 = 1.0/ebsq; const double term2 = -4.0*31.0/(3*ebsq*ebsq); const double term3 = 32.0*3779.0/(15.0*ebsq*ebsq*ebsq); const double term4 = -64.0*6277237.0/(105.0*ebsq*ebsq*ebsq*ebsq); const double term5 = 512.0*2092163573.0/(315.0*ebsq*ebsq*ebsq*ebsq*ebsq); return 1.0 + 8.0*(term1 + term2 + term3 + term4 + term5); } else { /* Here we do things in terms of 1/mu, which * is purely to prevent overflow in the very * unlikely case that mu is really big. */ const double mi = 1.0/mu; const double r = mu/ebsq; const double n2 = 4.0/3.0 * (7.0 - 31.0*mi); const double n3 = 32.0/15.0 * (83.0 + (-982.0 + 3779.0*mi)*mi); const double n4 = 64.0/105.0 * (6949.0 + (-153855.0 + (1585743.0 - 6277237.0*mi)*mi)*mi); const double n5 = 512.0/315.0 * (70197.0 + (-2479316.0 + (48010494.0 + (-512062548.0 + 2092163573.0*mi)*mi)*mi)*mi); const double n6 = 2048.0/3465.0 * (5592657.0 + (-287149133.0 + (8903961290.0 + (-179289628602.0 + (1982611456181.0 - 8249725736393.0*mi)*mi)*mi)*mi)*mi); const double term1 = (1.0 - mi) * r; const double term2 = term1 * n2 * r; const double term3 = term1 * n3 * r*r; const double term4 = term1 * n4 * r*r*r; const double term5 = term1 * n5 * r*r*r*r; const double term6 = term1 * n6 * r*r*r*r*r; return 1.0 - 8.0*(term1 + term2 + term3 + term4 + term5 + term6); } } /* Assumes z >= 1.0 */ static double olver_b0(double z, double minus_zeta) { if(z < 1.02) { const double a = 1.0-z; const double c0 = 0.0179988721413553309252458658183; const double c1 = 0.0111992982212877614645974276203; const double c2 = 0.0059404069786014304317781160605; const double c3 = 0.0028676724516390040844556450173; const double c4 = 0.0012339189052567271708525111185; const double c5 = 0.0004169250674535178764734660248; const double c6 = 0.0000330173385085949806952777365; const double c7 = -0.0001318076238578203009990106425; const double c8 = -0.0001906870370050847239813945647; return c0 + a*(c1 + a*(c2 + a*(c3 + a*(c4 + a*(c5 + a*(c6 + a*(c7 + a*c8))))))); } else { const double abs_zeta = minus_zeta; const double t = 1.0/(z*sqrt(1.0 - 1.0/(z*z))); return -5.0/(48.0*abs_zeta*abs_zeta) + t*(3.0 + 5.0*t*t)/(24.0*sqrt(abs_zeta)); } } inline static double olver_f1(double z, double minus_zeta) { const double b0 = olver_b0(z, minus_zeta); const double h2 = sqrt(4.0*minus_zeta/(z*z-1.0)); /* FIXME */ return 0.5 * z * h2 * b0; } int gsl_sf_bessel_zero_J0_e(unsigned int s, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(s == 0){ result->val = 0.0; result->err = 0.0; GSL_ERROR ("error", GSL_EINVAL); } else { /* See [F. Lether, J. Comp. Appl .Math. 67, 167 (1996)]. */ static const double P[] = { 1567450796.0/12539606369.0, 8903660.0/2365861.0, 10747040.0/536751.0, 17590991.0/1696654.0 }; static const double Q[] = { 1.0, 29354255.0/954518.0, 76900001.0/431847.0, 67237052.0/442411.0 }; const double beta = (s - 0.25) * M_PI; const double bi2 = 1.0/(beta*beta); const double R33num = P[0] + bi2 * (P[1] + bi2 * (P[2] + P[3] * bi2)); const double R33den = Q[0] + bi2 * (Q[1] + bi2 * (Q[2] + Q[3] * bi2)); const double R33 = R33num/R33den; result->val = beta + R33/beta; result->err = fabs(3.0e-15 * result->val); return GSL_SUCCESS; } } int gsl_sf_bessel_zero_J1_e(unsigned int s, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(s == 0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else { /* See [M. Branders et al., J. Comp. Phys. 42, 403 (1981)]. */ static const double a[] = { -0.362804405737084, 0.120341279038597, 0.439454547101171e-01, 0.159340088474713e-02 }; static const double b[] = { 1.0, -0.325641790801361, -0.117453445968927, -0.424906902601794e-02 }; const double beta = (s + 0.25) * M_PI; const double bi2 = 1.0/(beta*beta); const double Rnum = a[3] + bi2 * (a[2] + bi2 * (a[1] + bi2 * a[0])); const double Rden = b[3] + bi2 * (b[2] + bi2 * (b[1] + bi2 * b[0])); const double R = Rnum/Rden; result->val = beta * (1.0 + R*bi2); result->err = fabs(2.0e-14 * result->val); return GSL_SUCCESS; } } int gsl_sf_bessel_zero_Jnu_e(double nu, unsigned int s, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(nu <= -1.0) { DOMAIN_ERROR(result); } else if(s == 0) { result->val = 0.0; result->err = 0.0; if (nu == 0.0) { GSL_ERROR ("no zero-th root for nu = 0.0", GSL_EINVAL); } return GSL_SUCCESS; } else if(nu < 0.0) { /* This can be done, I'm just lazy now. */ result->val = 0.0; result->err = 0.0; GSL_ERROR("unimplemented", GSL_EUNIMPL); } else if(s == 1) { /* Chebyshev fits for the first positive zero. * For some reason Nemeth made this different from the others. */ if(nu < 2.0) { const double * c = coef_jnu_a[s]; const size_t L = size_jnu_a[s]; const double arg = nu/2.0; const double chb = clenshaw(c, L-1, arg); result->val = chb; result->err = 2.0e-15 * result->val; } else { const double * c = coef_jnu_b[s]; const size_t L = size_jnu_b[s]; const double arg = pow(2.0/nu, 2.0/3.0); const double chb = clenshaw(c, L-1, arg); result->val = nu * chb; result->err = 2.0e-15 * result->val; } return GSL_SUCCESS; } else if(s <= 10) { /* Chebyshev fits for the first 10 positive zeros. */ if(nu < s) { const double * c = coef_jnu_a[s]; const size_t L = size_jnu_a[s]; const double arg = nu/s; const double chb = clenshaw(c, L-1, arg); result->val = chb; result->err = 2.0e-15 * result->val; } else { const double * c = coef_jnu_b[s]; const size_t L = size_jnu_b[s]; const double arg = pow(s/nu, 2.0/3.0); const double chb = clenshaw(c, L-1, arg); result->val = nu * chb; result->err = 2.0e-15 * result->val; /* FIXME: truth in advertising for the screwed up * s = 5 fit. Need to fix that. */ if(s == 5) { result->err *= 5.0e+06; } } return GSL_SUCCESS; } else if(s > 0.5*nu && s <= 20) { /* Chebyshev fits for 10 < s <= 20. */ const double * c = coef_jnu_a[s]; const size_t L = size_jnu_a[s]; const double arg = nu/(2.0*s); const double chb = clenshaw(c, L-1, arg); result->val = chb; result->err = 4.0e-15 * chb; return GSL_SUCCESS; } else if(s > 2.0 * nu) { /* McMahon expansion if s is large compared to nu. */ const double beta = (s + 0.5*nu - 0.25) * M_PI; const double mc = mcmahon_correction(4.0*nu*nu, beta); gsl_sf_result rat12; gsl_sf_pow_int_e(nu/beta, 14, &rat12); result->val = beta * mc; result->err = 4.0 * fabs(beta) * rat12.val; result->err += 4.0 * fabs(GSL_DBL_EPSILON * result->val); return GSL_SUCCESS; } else { /* Olver uniform asymptotic. */ gsl_sf_result as; const int stat_as = gsl_sf_airy_zero_Ai_e(s, &as); const double minus_zeta = -pow(nu,-2.0/3.0) * as.val; const double z = gsl_sf_bessel_Olver_zofmzeta(minus_zeta); const double f1 = olver_f1(z, minus_zeta); result->val = nu * (z + f1/(nu*nu)); result->err = 0.001/(nu*nu*nu); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_as; } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_bessel_zero_J0(unsigned int s) { EVAL_RESULT(gsl_sf_bessel_zero_J0_e(s, &result)); } double gsl_sf_bessel_zero_J1(unsigned int s) { EVAL_RESULT(gsl_sf_bessel_zero_J1_e(s, &result)); } double gsl_sf_bessel_zero_Jnu(double nu, unsigned int s) { EVAL_RESULT(gsl_sf_bessel_zero_Jnu_e(nu, s, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__beta.c000066400000000000000000000115231261542461700213020ustar00rootroot00000000000000/* specfunc/beta.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_exp.h" #include "gsl_sf_log.h" #include "gsl_sf_psi.h" #include "gsl_sf_gamma.h" #include "gsl_specfunc__error.h" static double isnegint (const double x) { return (x < 0) && (x == floor(x)); } int gsl_sf_lnbeta_e(const double x, const double y, gsl_sf_result * result) { double sgn; int status = gsl_sf_lnbeta_sgn_e(x,y,result,&sgn); if (sgn == -1) { DOMAIN_ERROR(result); } return status; } int gsl_sf_lnbeta_sgn_e(const double x, const double y, gsl_sf_result * result, double * sgn) { /* CHECK_POINTER(result) */ if(x == 0.0 || y == 0.0) { *sgn = 0.0; DOMAIN_ERROR(result); } else if (isnegint(x) || isnegint(y)) { *sgn = 0.0; DOMAIN_ERROR(result); /* not defined for negative integers */ } /* See if we can handle the postive case with min/max < 0.2 */ if (x > 0 && y > 0) { const double max = GSL_MAX(x,y); const double min = GSL_MIN(x,y); const double rat = min/max; if(rat < 0.2) { /* min << max, so be careful * with the subtraction */ double lnpre_val; double lnpre_err; double lnpow_val; double lnpow_err; double t1, t2, t3; gsl_sf_result lnopr; gsl_sf_result gsx, gsy, gsxy; gsl_sf_gammastar_e(x, &gsx); gsl_sf_gammastar_e(y, &gsy); gsl_sf_gammastar_e(x+y, &gsxy); gsl_sf_log_1plusx_e(rat, &lnopr); lnpre_val = log(gsx.val*gsy.val/gsxy.val * M_SQRT2*M_SQRTPI); lnpre_err = gsx.err/gsx.val + gsy.err/gsy.val + gsxy.err/gsxy.val; t1 = min*log(rat); t2 = 0.5*log(min); t3 = (x+y-0.5)*lnopr.val; lnpow_val = t1 - t2 - t3; lnpow_err = GSL_DBL_EPSILON * (fabs(t1) + fabs(t2) + fabs(t3)); lnpow_err += fabs(x+y-0.5) * lnopr.err; result->val = lnpre_val + lnpow_val; result->err = lnpre_err + lnpow_err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); *sgn = 1.0; return GSL_SUCCESS; } } /* General case - Fallback */ { gsl_sf_result lgx, lgy, lgxy; double sgx, sgy, sgxy, xy = x+y; int stat_gx = gsl_sf_lngamma_sgn_e(x, &lgx, &sgx); int stat_gy = gsl_sf_lngamma_sgn_e(y, &lgy, &sgy); int stat_gxy = gsl_sf_lngamma_sgn_e(xy, &lgxy, &sgxy); *sgn = sgx * sgy * sgxy; result->val = lgx.val + lgy.val - lgxy.val; result->err = lgx.err + lgy.err + lgxy.err; result->err += 2.0 * GSL_DBL_EPSILON * (fabs(lgx.val) + fabs(lgy.val) + fabs(lgxy.val)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_3(stat_gx, stat_gy, stat_gxy); } } int gsl_sf_beta_e(const double x, const double y, gsl_sf_result * result) { if((x > 0 && y > 0) && x < 50.0 && y < 50.0) { /* Handle the easy case */ gsl_sf_result gx, gy, gxy; gsl_sf_gamma_e(x, &gx); gsl_sf_gamma_e(y, &gy); gsl_sf_gamma_e(x+y, &gxy); result->val = (gx.val*gy.val)/gxy.val; result->err = gx.err * fabs(gy.val/gxy.val); result->err += gy.err * fabs(gx.val/gxy.val); result->err += fabs((gx.val*gy.val)/(gxy.val*gxy.val)) * gxy.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if (isnegint(x) || isnegint(y)) { DOMAIN_ERROR(result); } else if (isnegint(x+y)) { /* infinity in the denominator */ result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else { gsl_sf_result lb; double sgn; int stat_lb = gsl_sf_lnbeta_sgn_e(x, y, &lb, &sgn); if(stat_lb == GSL_SUCCESS) { int status = gsl_sf_exp_err_e(lb.val, lb.err, result); result->val *= sgn; return status; } else { result->val = 0.0; result->err = 0.0; return stat_lb; } } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_lnbeta(const double x, const double y) { EVAL_RESULT(gsl_sf_lnbeta_e(x, y, &result)); } double gsl_sf_beta(const double x, const double y) { EVAL_RESULT(gsl_sf_beta_e(x, y, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__beta_inc.c000066400000000000000000000133701261542461700221350ustar00rootroot00000000000000/* specfunc/beta_inc.c * * Copyright (C) 2007 Brian Gough * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_log.h" #include "gsl_sf_exp.h" #include "gsl_sf_gamma.h" #include "gsl_sf_hyperg.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__check.h" static double isnegint (const double x) { return (x < 0) && (x == floor(x)); } static int beta_cont_frac( const double a, const double b, const double x, gsl_sf_result * result ) { const unsigned int max_iter = 512; /* control iterations */ const double cutoff = 2.0 * GSL_DBL_MIN; /* control the zero cutoff */ unsigned int iter_count = 0; double cf; /* standard initialization for continued fraction */ double num_term = 1.0; double den_term = 1.0 - (a+b)*x/(a+1.0); if (fabs(den_term) < cutoff) den_term = cutoff; den_term = 1.0/den_term; cf = den_term; while(iter_count < max_iter) { const int k = iter_count + 1; double coeff = k*(b-k)*x/(((a-1.0)+2*k)*(a+2*k)); double delta_frac; /* first step */ den_term = 1.0 + coeff*den_term; num_term = 1.0 + coeff/num_term; if(fabs(den_term) < cutoff) den_term = cutoff; if(fabs(num_term) < cutoff) num_term = cutoff; den_term = 1.0/den_term; delta_frac = den_term * num_term; cf *= delta_frac; coeff = -(a+k)*(a+b+k)*x/((a+2*k)*(a+2*k+1.0)); /* second step */ den_term = 1.0 + coeff*den_term; num_term = 1.0 + coeff/num_term; if(fabs(den_term) < cutoff) den_term = cutoff; if(fabs(num_term) < cutoff) num_term = cutoff; den_term = 1.0/den_term; delta_frac = den_term*num_term; cf *= delta_frac; if(fabs(delta_frac-1.0) < 2.0*GSL_DBL_EPSILON) break; ++iter_count; } result->val = cf; result->err = iter_count * 4.0 * GSL_DBL_EPSILON * fabs(cf); if(iter_count >= max_iter) GSL_ERROR ("error", GSL_EMAXITER); else return GSL_SUCCESS; } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_beta_inc_e( const double a, const double b, const double x, gsl_sf_result * result ) { if(x < 0.0 || x > 1.0) { DOMAIN_ERROR(result); } else if (isnegint(a) || isnegint(b)) { DOMAIN_ERROR(result); } else if (isnegint(a+b)) { DOMAIN_ERROR(result); } else if(x == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(x == 1.0) { result->val = 1.0; result->err = 0.0; return GSL_SUCCESS; } else if (a <= 0 || b <= 0) { gsl_sf_result f, beta; int stat; const int stat_f = gsl_sf_hyperg_2F1_e(a, 1-b, a+1, x, &f); const int stat_beta = gsl_sf_beta_e(a, b, &beta); double prefactor = (pow(x, a) / a); result->val = prefactor * f.val / beta.val; result->err = fabs(prefactor) * f.err/ fabs(beta.val) + fabs(result->val/beta.val) * beta.err; stat = GSL_ERROR_SELECT_2(stat_f, stat_beta); if(stat == GSL_SUCCESS) { CHECK_UNDERFLOW(result); } return stat; } else { gsl_sf_result ln_beta; gsl_sf_result ln_x; gsl_sf_result ln_1mx; gsl_sf_result prefactor; const int stat_ln_beta = gsl_sf_lnbeta_e(a, b, &ln_beta); const int stat_ln_1mx = gsl_sf_log_1plusx_e(-x, &ln_1mx); const int stat_ln_x = gsl_sf_log_e(x, &ln_x); const int stat_ln = GSL_ERROR_SELECT_3(stat_ln_beta, stat_ln_1mx, stat_ln_x); const double ln_pre_val = -ln_beta.val + a * ln_x.val + b * ln_1mx.val; const double ln_pre_err = ln_beta.err + fabs(a*ln_x.err) + fabs(b*ln_1mx.err); const int stat_exp = gsl_sf_exp_err_e(ln_pre_val, ln_pre_err, &prefactor); if(stat_ln != GSL_SUCCESS) { result->val = 0.0; result->err = 0.0; GSL_ERROR ("error", GSL_ESANITY); } if(x < (a + 1.0)/(a+b+2.0)) { /* Apply continued fraction directly. */ gsl_sf_result cf; const int stat_cf = beta_cont_frac(a, b, x, &cf); int stat; result->val = prefactor.val * cf.val / a; result->err = (fabs(prefactor.err * cf.val) + fabs(prefactor.val * cf.err))/a; stat = GSL_ERROR_SELECT_2(stat_exp, stat_cf); if(stat == GSL_SUCCESS) { CHECK_UNDERFLOW(result); } return stat; } else { /* Apply continued fraction after hypergeometric transformation. */ gsl_sf_result cf; const int stat_cf = beta_cont_frac(b, a, 1.0-x, &cf); int stat; const double term = prefactor.val * cf.val / b; result->val = 1.0 - term; result->err = fabs(prefactor.err * cf.val)/b; result->err += fabs(prefactor.val * cf.err)/b; result->err += 2.0 * GSL_DBL_EPSILON * (1.0 + fabs(term)); stat = GSL_ERROR_SELECT_2(stat_exp, stat_cf); if(stat == GSL_SUCCESS) { CHECK_UNDERFLOW(result); } return stat; } } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_beta_inc(const double a, const double b, const double x) { EVAL_RESULT(gsl_sf_beta_inc_e(a, b, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__cheb_eval.c000066400000000000000000000012201261542461700222700ustar00rootroot00000000000000 static inline int cheb_eval_e(const cheb_series * cs, const double x, gsl_sf_result * result) { int j; double d = 0.0; double dd = 0.0; double y = (2.0*x - cs->a - cs->b) / (cs->b - cs->a); double y2 = 2.0 * y; double e = 0.0; for(j = cs->order; j>=1; j--) { double temp = d; d = y2*d - dd + cs->c[j]; e += fabs(y2*temp) + fabs(dd) + fabs(cs->c[j]); dd = temp; } { double temp = d; d = y*d - dd + 0.5 * cs->c[0]; e += fabs(y*temp) + fabs(dd) + 0.5 * fabs(cs->c[0]); } result->val = d; result->err = GSL_DBL_EPSILON * e + fabs(cs->c[cs->order]); return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_specfunc__cheb_eval_mode.c000066400000000000000000000012501261542461700232770ustar00rootroot00000000000000static inline int cheb_eval_mode_e(const cheb_series * cs, const double x, gsl_mode_t mode, gsl_sf_result * result) { int j; double d = 0.0; double dd = 0.0; double y = (2.*x - cs->a - cs->b) / (cs->b - cs->a); double y2 = 2.0 * y; int eval_order; if(GSL_MODE_PREC(mode) == GSL_PREC_DOUBLE) eval_order = cs->order; else eval_order = cs->order_sp; for(j = eval_order; j>=1; j--) { double temp = d; d = y2*d - dd + cs->c[j]; dd = temp; } result->val = y*d - dd + 0.5 * cs->c[0]; result->err = GSL_DBL_EPSILON * fabs(result->val) + fabs(cs->c[eval_order]); return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_specfunc__chebyshev.h000066400000000000000000000022721261542461700223550ustar00rootroot00000000000000/* specfunc/chebyshev.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* data for a Chebyshev series over a given interval */ struct cheb_series_struct { double * c; /* coefficients */ int order; /* order of expansion */ double a; /* lower interval point */ double b; /* upper interval point */ int order_sp; /* effective single precision order */ }; typedef struct cheb_series_struct cheb_series; praat-6.0.04/external/gsl/gsl_specfunc__check.h000066400000000000000000000001761261542461700214530ustar00rootroot00000000000000/* check for underflow */ #define CHECK_UNDERFLOW(r) if (fabs((r)->val) < GSL_DBL_MIN) GSL_ERROR("underflow", GSL_EUNDRFLW); praat-6.0.04/external/gsl/gsl_specfunc__clausen.c000066400000000000000000000053211261542461700220200ustar00rootroot00000000000000/* specfunc/clausen.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_trig.h" #include "gsl_sf_clausen.h" #include "gsl_specfunc__chebyshev.h" #include "gsl_specfunc__cheb_eval.c" static double aclaus_data[15] = { 2.142694363766688447e+00, 0.723324281221257925e-01, 0.101642475021151164e-02, 0.3245250328531645e-04, 0.133315187571472e-05, 0.6213240591653e-07, 0.313004135337e-08, 0.16635723056e-09, 0.919659293e-11, 0.52400462e-12, 0.3058040e-13, 0.18197e-14, 0.1100e-15, 0.68e-17, 0.4e-18 }; static cheb_series aclaus_cs = { aclaus_data, 14, -1, 1, 8 /* FIXME: this is a guess, correct value needed here BJG */ }; /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_clausen_e(double x, gsl_sf_result *result) { const double x_cut = M_PI * GSL_SQRT_DBL_EPSILON; double sgn = 1.0; int status_red; if(x < 0.0) { x = -x; sgn = -1.0; } /* Argument reduction to [0, 2pi) */ status_red = gsl_sf_angle_restrict_pos_e(&x); /* Further reduction to [0,pi) */ if(x > M_PI) { /* simulated extra precision: 2PI = p0 + p1 */ const double p0 = 6.28125; const double p1 = 0.19353071795864769253e-02; x = (p0 - x) + p1; sgn = -sgn; } if(x == 0.0) { result->val = 0.0; result->err = 0.0; } else if(x < x_cut) { result->val = x * (1.0 - log(x)); result->err = x * GSL_DBL_EPSILON; } else { const double t = 2.0*(x*x / (M_PI*M_PI) - 0.5); gsl_sf_result result_c; cheb_eval_e(&aclaus_cs, t, &result_c); result->val = x * (result_c.val - log(x)); result->err = x * (result_c.err + GSL_DBL_EPSILON); } result->val *= sgn; return status_red; } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_clausen(const double x) { EVAL_RESULT(gsl_sf_clausen_e(x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__coulomb.c000066400000000000000000001150021261542461700220240ustar00rootroot00000000000000/* specfunc/coulomb.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ /* Evaluation of Coulomb wave functions F_L(eta, x), G_L(eta, x), * and their derivatives. A combination of Steed's method, asymptotic * results, and power series. * * Steed's method: * [Barnett, CPC 21, 297 (1981)] * Power series and other methods: * [Biedenharn et al., PR 97, 542 (1954)] * [Bardin et al., CPC 3, 73 (1972)] * [Abad+Sesma, CPC 71, 110 (1992)] */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_exp.h" #include "gsl_sf_psi.h" #include "gsl_sf_airy.h" #include "gsl_sf_pow_int.h" #include "gsl_sf_gamma.h" #include "gsl_sf_coulomb.h" #include "gsl_specfunc__error.h" /* the L=0 normalization constant * [Abramowitz+Stegun 14.1.8] */ static double C0sq(double eta) { double twopieta = 2.0*M_PI*eta; if(fabs(eta) < GSL_DBL_EPSILON) { return 1.0; } else if(twopieta > GSL_LOG_DBL_MAX) { return 0.0; } else { gsl_sf_result scale; gsl_sf_expm1_e(twopieta, &scale); return twopieta/scale.val; } } /* the full definition of C_L(eta) for any valid L and eta * [Abramowitz and Stegun 14.1.7] * This depends on the complex gamma function. For large * arguments the phase of the complex gamma function is not * very accurately determined. However the modulus is, and that * is all that we need to calculate C_L. * * This is not valid for L <= -3/2 or L = -1. */ static int CLeta(double L, double eta, gsl_sf_result * result) { gsl_sf_result ln1; /* log of numerator Gamma function */ gsl_sf_result ln2; /* log of denominator Gamma function */ double sgn = 1.0; double arg_val, arg_err; if(fabs(eta/(L+1.0)) < GSL_DBL_EPSILON) { gsl_sf_lngamma_e(L+1.0, &ln1); } else { gsl_sf_result p1; /* phase of numerator Gamma -- not used */ gsl_sf_lngamma_complex_e(L+1.0, eta, &ln1, &p1); /* should be ok */ } gsl_sf_lngamma_e(2.0*(L+1.0), &ln2); if(L < -1.0) sgn = -sgn; arg_val = L*M_LN2 - 0.5*eta*M_PI + ln1.val - ln2.val; arg_err = ln1.err + ln2.err; arg_err += GSL_DBL_EPSILON * (fabs(L*M_LN2) + fabs(0.5*eta*M_PI)); return gsl_sf_exp_err_e(arg_val, arg_err, result); } int gsl_sf_coulomb_CL_e(double lam, double eta, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(lam <= -1.0) { DOMAIN_ERROR(result); } else if(fabs(lam) < GSL_DBL_EPSILON) { /* saves a calculation of complex_lngamma(), otherwise not necessary */ result->val = sqrt(C0sq(eta)); result->err = 2.0 * GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; } else { return CLeta(lam, eta, result); } } /* cl[0] .. cl[kmax] = C_{lam_min}(eta) .. C_{lam_min+kmax}(eta) */ int gsl_sf_coulomb_CL_array(double lam_min, int kmax, double eta, double * cl) { int k; gsl_sf_result cl_0; gsl_sf_coulomb_CL_e(lam_min, eta, &cl_0); cl[0] = cl_0.val; for(k=1; k<=kmax; k++) { double L = lam_min + k; cl[k] = cl[k-1] * hypot(L, eta)/(L*(2.0*L+1.0)); } return GSL_SUCCESS; } /* Evaluate the series for Phi_L(eta,x) and Phi_L*(eta,x) * [Abramowitz+Stegun 14.1.5] * [Abramowitz+Stegun 14.1.13] * * The sequence of coefficients A_k^L is * manifestly well-controlled for L >= -1/2 * and eta < 10. * * This makes sense since this is the region * away from threshold, and you expect * the evaluation to become easier as you * get farther from threshold. * * Empirically, this is quite well-behaved for * L >= -1/2 * eta < 10 * x < 10 */ #if 0 static int coulomb_Phi_series(const double lam, const double eta, const double x, double * result, double * result_star) { int kmin = 5; int kmax = 200; int k; double Akm2 = 1.0; double Akm1 = eta/(lam+1.0); double Ak; double xpow = x; double sum = Akm2 + Akm1*x; double sump = (lam+1.0)*Akm2 + (lam+2.0)*Akm1*x; double prev_abs_del = fabs(Akm1*x); double prev_abs_del_p = (lam+2.0) * prev_abs_del; for(k=2; k kmin ) break; /* We need to keep track of the previous delta because when * eta is near zero the odd terms of the sum are very small * and this could lead to premature termination. */ prev_abs_del = abs_del; prev_abs_del_p = abs_del_p; Akm2 = Akm1; Akm1 = Ak; } *result = sum; *result_star = sump; if(k==kmax) { GSL_ERROR ("error", GSL_EMAXITER); } else { return GSL_SUCCESS; } } #endif /* 0 */ /* Determine the connection phase, phi_lambda. * See coulomb_FG_series() below. We have * to be careful about sin(phi)->0. Note that * there is an underflow condition for large * positive eta in any case. */ static int coulomb_connection(const double lam, const double eta, double * cos_phi, double * sin_phi) { if(eta > -GSL_LOG_DBL_MIN/2.0*M_PI-1.0) { *cos_phi = 1.0; *sin_phi = 0.0; GSL_ERROR ("error", GSL_EUNDRFLW); } else if(eta > -GSL_LOG_DBL_EPSILON/(4.0*M_PI)) { const double eps = 2.0 * exp(-2.0*M_PI*eta); const double tpl = tan(M_PI * lam); const double dth = eps * tpl / (tpl*tpl + 1.0); *cos_phi = -1.0 + 0.5 * dth*dth; *sin_phi = -dth; return GSL_SUCCESS; } else { double X = tanh(M_PI * eta) / tan(M_PI * lam); double phi = -atan(X) - (lam + 0.5) * M_PI; *cos_phi = cos(phi); *sin_phi = sin(phi); return GSL_SUCCESS; } } /* Evaluate the Frobenius series for F_lam(eta,x) and G_lam(eta,x). * Homegrown algebra. Evaluates the series for F_{lam} and * F_{-lam-1}, then uses * G_{lam} = (F_{lam} cos(phi) - F_{-lam-1}) / sin(phi) * where * phi = Arg[Gamma[1+lam+I eta]] - Arg[Gamma[-lam + I eta]] - (lam+1/2)Pi * = Arg[Sin[Pi(-lam+I eta)] - (lam+1/2)Pi * = atan2(-cos(lam Pi)sinh(eta Pi), -sin(lam Pi)cosh(eta Pi)) - (lam+1/2)Pi * * = -atan(X) - (lam+1/2) Pi, X = tanh(eta Pi)/tan(lam Pi) * * Not appropriate for lam <= -1/2, lam = 0, or lam >= 1/2. */ static int coulomb_FG_series(const double lam, const double eta, const double x, gsl_sf_result * F, gsl_sf_result * G) { const int max_iter = 800; gsl_sf_result ClamA; gsl_sf_result ClamB; int stat_A = CLeta(lam, eta, &ClamA); int stat_B = CLeta(-lam-1.0, eta, &ClamB); const double tlp1 = 2.0*lam + 1.0; const double pow_x = pow(x, lam); double cos_phi_lam; double sin_phi_lam; double uA_mm2 = 1.0; /* uA sum is for F_{lam} */ double uA_mm1 = x*eta/(lam+1.0); double uA_m; double uB_mm2 = 1.0; /* uB sum is for F_{-lam-1} */ double uB_mm1 = -x*eta/lam; double uB_m; double A_sum = uA_mm2 + uA_mm1; double B_sum = uB_mm2 + uB_mm1; double A_abs_del_prev = fabs(A_sum); double B_abs_del_prev = fabs(B_sum); gsl_sf_result FA, FB; int m = 2; int stat_conn = coulomb_connection(lam, eta, &cos_phi_lam, &sin_phi_lam); if(stat_conn == GSL_EUNDRFLW) { F->val = 0.0; /* FIXME: should this be set to Inf too like G? */ F->err = 0.0; OVERFLOW_ERROR(G); } while(m < max_iter) { double abs_dA; double abs_dB; uA_m = x*(2.0*eta*uA_mm1 - x*uA_mm2)/(m*(m+tlp1)); uB_m = x*(2.0*eta*uB_mm1 - x*uB_mm2)/(m*(m-tlp1)); A_sum += uA_m; B_sum += uB_m; abs_dA = fabs(uA_m); abs_dB = fabs(uB_m); if(m > 15) { /* Don't bother checking until we have gone out a little ways; * a minor optimization. Also make sure to check both the * current and the previous increment because the odd and even * terms of the sum can have very different behaviour, depending * on the value of eta. */ double max_abs_dA = GSL_MAX(abs_dA, A_abs_del_prev); double max_abs_dB = GSL_MAX(abs_dB, B_abs_del_prev); double abs_A = fabs(A_sum); double abs_B = fabs(B_sum); if( max_abs_dA/(max_abs_dA + abs_A) < 4.0*GSL_DBL_EPSILON && max_abs_dB/(max_abs_dB + abs_B) < 4.0*GSL_DBL_EPSILON ) break; } A_abs_del_prev = abs_dA; B_abs_del_prev = abs_dB; uA_mm2 = uA_mm1; uA_mm1 = uA_m; uB_mm2 = uB_mm1; uB_mm1 = uB_m; m++; } FA.val = A_sum * ClamA.val * pow_x * x; FA.err = fabs(A_sum) * ClamA.err * pow_x * x + 2.0*GSL_DBL_EPSILON*fabs(FA.val); FB.val = B_sum * ClamB.val / pow_x; FB.err = fabs(B_sum) * ClamB.err / pow_x + 2.0*GSL_DBL_EPSILON*fabs(FB.val); F->val = FA.val; F->err = FA.err; G->val = (FA.val * cos_phi_lam - FB.val)/sin_phi_lam; G->err = (FA.err * fabs(cos_phi_lam) + FB.err)/fabs(sin_phi_lam); if(m >= max_iter) GSL_ERROR ("error", GSL_EMAXITER); else return GSL_ERROR_SELECT_2(stat_A, stat_B); } /* Evaluate the Frobenius series for F_0(eta,x) and G_0(eta,x). * See [Bardin et al., CPC 3, 73 (1972), (14)-(17)]; * note the misprint in (17): nu_0=1 is correct, not nu_0=0. */ static int coulomb_FG0_series(const double eta, const double x, gsl_sf_result * F, gsl_sf_result * G) { const int max_iter = 800; const double x2 = x*x; const double tex = 2.0*eta*x; gsl_sf_result C0; int stat_CL = CLeta(0.0, eta, &C0); gsl_sf_result r1pie; int psi_stat = gsl_sf_psi_1piy_e(eta, &r1pie); double u_mm2 = 0.0; /* u_0 */ double u_mm1 = x; /* u_1 */ double u_m; double v_mm2 = 1.0; /* nu_0 */ double v_mm1 = tex*(2.0*M_EULER-1.0+r1pie.val); /* nu_1 */ double v_m; double u_sum = u_mm2 + u_mm1; double v_sum = v_mm2 + v_mm1; double u_abs_del_prev = fabs(u_sum); double v_abs_del_prev = fabs(v_sum); int m = 2; double u_sum_err = 2.0 * GSL_DBL_EPSILON * fabs(u_sum); double v_sum_err = 2.0 * GSL_DBL_EPSILON * fabs(v_sum); double ln2x = log(2.0*x); while(m < max_iter) { double abs_du; double abs_dv; double m_mm1 = m*(m-1.0); u_m = (tex*u_mm1 - x2*u_mm2)/m_mm1; v_m = (tex*v_mm1 - x2*v_mm2 - 2.0*eta*(2*m-1)*u_m)/m_mm1; u_sum += u_m; v_sum += v_m; abs_du = fabs(u_m); abs_dv = fabs(v_m); u_sum_err += 2.0 * GSL_DBL_EPSILON * abs_du; v_sum_err += 2.0 * GSL_DBL_EPSILON * abs_dv; if(m > 15) { /* Don't bother checking until we have gone out a little ways; * a minor optimization. Also make sure to check both the * current and the previous increment because the odd and even * terms of the sum can have very different behaviour, depending * on the value of eta. */ double max_abs_du = GSL_MAX(abs_du, u_abs_del_prev); double max_abs_dv = GSL_MAX(abs_dv, v_abs_del_prev); double abs_u = fabs(u_sum); double abs_v = fabs(v_sum); if( max_abs_du/(max_abs_du + abs_u) < 40.0*GSL_DBL_EPSILON && max_abs_dv/(max_abs_dv + abs_v) < 40.0*GSL_DBL_EPSILON ) break; } u_abs_del_prev = abs_du; v_abs_del_prev = abs_dv; u_mm2 = u_mm1; u_mm1 = u_m; v_mm2 = v_mm1; v_mm1 = v_m; m++; } F->val = C0.val * u_sum; F->err = C0.err * fabs(u_sum); F->err += fabs(C0.val) * u_sum_err; F->err += 2.0 * GSL_DBL_EPSILON * fabs(F->val); G->val = (v_sum + 2.0*eta*u_sum * ln2x) / C0.val; G->err = (fabs(v_sum) + fabs(2.0*eta*u_sum * ln2x)) / fabs(C0.val) * fabs(C0.err/C0.val); G->err += (v_sum_err + fabs(2.0*eta*u_sum_err*ln2x)) / fabs(C0.val); G->err += 2.0 * GSL_DBL_EPSILON * fabs(G->val); if(m == max_iter) GSL_ERROR ("error", GSL_EMAXITER); else return GSL_ERROR_SELECT_2(psi_stat, stat_CL); } /* Evaluate the Frobenius series for F_{-1/2}(eta,x) and G_{-1/2}(eta,x). * Homegrown algebra. */ static int coulomb_FGmhalf_series(const double eta, const double x, gsl_sf_result * F, gsl_sf_result * G) { const int max_iter = 800; const double rx = sqrt(x); const double x2 = x*x; const double tex = 2.0*eta*x; gsl_sf_result Cmhalf; int stat_CL = CLeta(-0.5, eta, &Cmhalf); double u_mm2 = 1.0; /* u_0 */ double u_mm1 = tex * u_mm2; /* u_1 */ double u_m; double v_mm2, v_mm1, v_m; double f_sum, g_sum; double tmp1; gsl_sf_result rpsi_1pe; gsl_sf_result rpsi_1p2e; int m = 2; gsl_sf_psi_1piy_e(eta, &rpsi_1pe); gsl_sf_psi_1piy_e(2.0*eta, &rpsi_1p2e); v_mm2 = 2.0*M_EULER - M_LN2 - rpsi_1pe.val + 2.0*rpsi_1p2e.val; v_mm1 = tex*(v_mm2 - 2.0*u_mm2); f_sum = u_mm2 + u_mm1; g_sum = v_mm2 + v_mm1; while(m < max_iter) { double m2 = m*m; u_m = (tex*u_mm1 - x2*u_mm2)/m2; v_m = (tex*v_mm1 - x2*v_mm2 - 2.0*m*u_m)/m2; f_sum += u_m; g_sum += v_m; if( f_sum != 0.0 && g_sum != 0.0 && (fabs(u_m/f_sum) + fabs(v_m/g_sum) < 10.0*GSL_DBL_EPSILON)) break; u_mm2 = u_mm1; u_mm1 = u_m; v_mm2 = v_mm1; v_mm1 = v_m; m++; } F->val = Cmhalf.val * rx * f_sum; F->err = Cmhalf.err * fabs(rx * f_sum) + 2.0*GSL_DBL_EPSILON*fabs(F->val); tmp1 = f_sum*log(x); G->val = -rx*(tmp1 + g_sum)/Cmhalf.val; G->err = fabs(rx)*(fabs(tmp1) + fabs(g_sum))/fabs(Cmhalf.val) * fabs(Cmhalf.err/Cmhalf.val); if(m == max_iter) GSL_ERROR ("error", GSL_EMAXITER); else return stat_CL; } /* Evolve the backwards recurrence for F,F'. * * F_{lam-1} = (S_lam F_lam + F_lam') / R_lam * F_{lam-1}' = (S_lam F_{lam-1} - R_lam F_lam) * where * R_lam = sqrt(1 + (eta/lam)^2) * S_lam = lam/x + eta/lam * */ static int coulomb_F_recur(double lam_min, int kmax, double eta, double x, double F_lam_max, double Fp_lam_max, double * F_lam_min, double * Fp_lam_min ) { double x_inv = 1.0/x; double fcl = F_lam_max; double fpl = Fp_lam_max; double lam_max = lam_min + kmax; double lam = lam_max; int k; for(k=kmax-1; k>=0; k--) { double el = eta/lam; double rl = hypot(1.0, el); double sl = el + lam*x_inv; double fc_lm1; fc_lm1 = (fcl*sl + fpl)/rl; fpl = fc_lm1*sl - fcl*rl; fcl = fc_lm1; lam -= 1.0; } *F_lam_min = fcl; *Fp_lam_min = fpl; return GSL_SUCCESS; } /* Evolve the forward recurrence for G,G'. * * G_{lam+1} = (S_lam G_lam - G_lam')/R_lam * G_{lam+1}' = R_{lam+1} G_lam - S_lam G_{lam+1} * * where S_lam and R_lam are as above in the F recursion. */ static int coulomb_G_recur(const double lam_min, const int kmax, const double eta, const double x, const double G_lam_min, const double Gp_lam_min, double * G_lam_max, double * Gp_lam_max ) { double x_inv = 1.0/x; double gcl = G_lam_min; double gpl = Gp_lam_min; double lam = lam_min + 1.0; int k; for(k=1; k<=kmax; k++) { double el = eta/lam; double rl = hypot(1.0, el); double sl = el + lam*x_inv; double gcl1 = (sl*gcl - gpl)/rl; gpl = rl*gcl - sl*gcl1; gcl = gcl1; lam += 1.0; } *G_lam_max = gcl; *Gp_lam_max = gpl; return GSL_SUCCESS; } /* Evaluate the first continued fraction, giving * the ratio F'/F at the upper lambda value. * We also determine the sign of F at that point, * since it is the sign of the last denominator * in the continued fraction. */ static int coulomb_CF1(double lambda, double eta, double x, double * fcl_sign, double * result, int * count ) { const double CF1_small = 1.e-30; const double CF1_abort = 1.0e+05; const double CF1_acc = 2.0*GSL_DBL_EPSILON; const double x_inv = 1.0/x; const double px = lambda + 1.0 + CF1_abort; double pk = lambda + 1.0; double F = eta/pk + pk*x_inv; double D, C; double df; *fcl_sign = 1.0; *count = 0; if(fabs(F) < CF1_small) F = CF1_small; D = 0.0; C = F; do { double pk1 = pk + 1.0; double ek = eta / pk; double rk2 = 1.0 + ek*ek; double tk = (pk + pk1)*(x_inv + ek/pk1); D = tk - rk2 * D; C = tk - rk2 / C; if(fabs(C) < CF1_small) C = CF1_small; if(fabs(D) < CF1_small) D = CF1_small; D = 1.0/D; df = D * C; F = F * df; if(D < 0.0) { /* sign of result depends on sign of denominator */ *fcl_sign = - *fcl_sign; } pk = pk1; if( pk > px ) { *result = F; GSL_ERROR ("error", GSL_ERUNAWAY); } ++(*count); } while(fabs(df-1.0) > CF1_acc); *result = F; return GSL_SUCCESS; } #if 0 static int old_coulomb_CF1(const double lambda, double eta, double x, double * fcl_sign, double * result ) { const double CF1_abort = 1.e5; const double CF1_acc = 10.0*GSL_DBL_EPSILON; const double x_inv = 1.0/x; const double px = lambda + 1.0 + CF1_abort; double pk = lambda + 1.0; double D; double df; double F; double p; double pk1; double ek; double fcl = 1.0; double tk; while(1) { ek = eta/pk; F = (ek + pk*x_inv)*fcl + (fcl - 1.0)*x_inv; pk1 = pk + 1.0; if(fabs(eta*x + pk*pk1) > CF1_acc) break; fcl = (1.0 + ek*ek)/(1.0 + eta*eta/(pk1*pk1)); pk = 2.0 + pk; } D = 1.0/((pk + pk1)*(x_inv + ek/pk1)); df = -fcl*(1.0 + ek*ek)*D; if(fcl != 1.0) fcl = -1.0; if(D < 0.0) fcl = -fcl; F = F + df; p = 1.0; do { pk = pk1; pk1 = pk + 1.0; ek = eta / pk; tk = (pk + pk1)*(x_inv + ek/pk1); D = tk - D*(1.0+ek*ek); if(fabs(D) < sqrt(CF1_acc)) { p += 1.0; if(p > 2.0) { printf("HELP............\n"); } } D = 1.0/D; if(D < 0.0) { /* sign of result depends on sign of denominator */ fcl = -fcl; } df = df*(D*tk - 1.0); F = F + df; if( pk > px ) { GSL_ERROR ("error", GSL_ERUNAWAY); } } while(fabs(df) > fabs(F)*CF1_acc); *fcl_sign = fcl; *result = F; return GSL_SUCCESS; } #endif /* 0 */ /* Evaluate the second continued fraction to * obtain the ratio * (G' + i F')/(G + i F) := P + i Q * at the specified lambda value. */ static int coulomb_CF2(const double lambda, const double eta, const double x, double * result_P, double * result_Q, int * count ) { int status = GSL_SUCCESS; const double CF2_acc = 4.0*GSL_DBL_EPSILON; const double CF2_abort = 2.0e+05; const double wi = 2.0*eta; const double x_inv = 1.0/x; const double e2mm1 = eta*eta + lambda*(lambda + 1.0); double ar = -e2mm1; double ai = eta; double br = 2.0*(x - eta); double bi = 2.0; double dr = br/(br*br + bi*bi); double di = -bi/(br*br + bi*bi); double dp = -x_inv*(ar*di + ai*dr); double dq = x_inv*(ar*dr - ai*di); double A, B, C, D; double pk = 0.0; double P = 0.0; double Q = 1.0 - eta*x_inv; *count = 0; do { P += dp; Q += dq; pk += 2.0; ar += pk; ai += wi; bi += 2.0; D = ar*dr - ai*di + br; di = ai*dr + ar*di + bi; C = 1.0/(D*D + di*di); dr = C*D; di = -C*di; A = br*dr - bi*di - 1.; B = bi*dr + br*di; C = dp*A - dq*B; dq = dp*B + dq*A; dp = C; if(pk > CF2_abort) { status = GSL_ERUNAWAY; break; } ++(*count); } while(fabs(dp)+fabs(dq) > (fabs(P)+fabs(Q))*CF2_acc); if(Q < CF2_abort*GSL_DBL_EPSILON*fabs(P)) { status = GSL_ELOSS; } *result_P = P; *result_Q = Q; return status; } /* WKB evaluation of F, G. Assumes 0 < x < turning point. * Overflows are trapped, GSL_EOVRFLW is signalled, * and an exponent is returned such that: * * result_F = fjwkb * exp(-exponent) * result_G = gjwkb * exp( exponent) * * See [Biedenharn et al. Phys. Rev. 97, 542-554 (1955), Section IV] * * Unfortunately, this is not very accurate in general. The * test cases typically have 3-4 digits of precision. One could * argue that this is ok for general use because, for instance, * F is exponentially small in this region and so the absolute * accuracy is still roughly acceptable. But it would be better * to have a systematic method for improving the precision. See * the Abad+Sesma method discussion below. */ static int coulomb_jwkb(const double lam, const double eta, const double x, gsl_sf_result * fjwkb, gsl_sf_result * gjwkb, double * exponent) { const double llp1 = lam*(lam+1.0) + 6.0/35.0; const double llp1_eff = GSL_MAX(llp1, 0.0); const double rho_ghalf = sqrt(x*(2.0*eta - x) + llp1_eff); const double sinh_arg = sqrt(llp1_eff/(eta*eta+llp1_eff)) * rho_ghalf / x; const double sinh_inv = log(sinh_arg + hypot(1.0,sinh_arg)); const double phi = fabs(rho_ghalf - eta*atan2(rho_ghalf,x-eta) - sqrt(llp1_eff) * sinh_inv); const double zeta_half = pow(3.0*phi/2.0, 1.0/3.0); const double prefactor = sqrt(M_PI*phi*x/(6.0 * rho_ghalf)); double F = prefactor * 3.0/zeta_half; double G = prefactor * 3.0/zeta_half; /* Note the sqrt(3) from Bi normalization */ double F_exp; double G_exp; const double airy_scale_exp = phi; gsl_sf_result ai; gsl_sf_result bi; gsl_sf_airy_Ai_scaled_e(zeta_half*zeta_half, GSL_MODE_DEFAULT, &ai); gsl_sf_airy_Bi_scaled_e(zeta_half*zeta_half, GSL_MODE_DEFAULT, &bi); F *= ai.val; G *= bi.val; F_exp = log(F) - airy_scale_exp; G_exp = log(G) + airy_scale_exp; if(G_exp >= GSL_LOG_DBL_MAX) { fjwkb->val = F; gjwkb->val = G; fjwkb->err = 1.0e-3 * fabs(F); /* FIXME: real error here ... could be smaller */ gjwkb->err = 1.0e-3 * fabs(G); *exponent = airy_scale_exp; GSL_ERROR ("error", GSL_EOVRFLW); } else { fjwkb->val = exp(F_exp); gjwkb->val = exp(G_exp); fjwkb->err = 1.0e-3 * fabs(fjwkb->val); gjwkb->err = 1.0e-3 * fabs(gjwkb->val); *exponent = 0.0; return GSL_SUCCESS; } } /* Asymptotic evaluation of F and G below the minimal turning point. * * This is meant to be a drop-in replacement for coulomb_jwkb(). * It uses the expressions in [Abad+Sesma]. This requires some * work because I am not sure where it is valid. They mumble * something about |x| < |lam|^(-1/2) or 8|eta x| > lam when |x| < 1. * This seems true, but I thought the result was based on a uniform * expansion and could be controlled by simply using more terms. */ #if 0 static int coulomb_AS_xlt2eta(const double lam, const double eta, const double x, gsl_sf_result * f_AS, gsl_sf_result * g_AS, double * exponent) { /* no time to do this now... */ } #endif /* 0 */ /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_coulomb_wave_FG_e(const double eta, const double x, const double lam_F, const int k_lam_G, /* lam_G = lam_F - k_lam_G */ gsl_sf_result * F, gsl_sf_result * Fp, gsl_sf_result * G, gsl_sf_result * Gp, double * exp_F, double * exp_G) { const double lam_G = lam_F - k_lam_G; if(x < 0.0 || lam_F <= -0.5 || lam_G <= -0.5) { GSL_SF_RESULT_SET(F, 0.0, 0.0); GSL_SF_RESULT_SET(Fp, 0.0, 0.0); GSL_SF_RESULT_SET(G, 0.0, 0.0); GSL_SF_RESULT_SET(Gp, 0.0, 0.0); *exp_F = 0.0; *exp_G = 0.0; GSL_ERROR ("domain error", GSL_EDOM); } else if(x == 0.0) { gsl_sf_result C0; CLeta(0.0, eta, &C0); GSL_SF_RESULT_SET(F, 0.0, 0.0); GSL_SF_RESULT_SET(Fp, 0.0, 0.0); GSL_SF_RESULT_SET(G, 0.0, 0.0); /* FIXME: should be Inf */ GSL_SF_RESULT_SET(Gp, 0.0, 0.0); /* FIXME: should be Inf */ *exp_F = 0.0; *exp_G = 0.0; if(lam_F == 0.0){ GSL_SF_RESULT_SET(Fp, C0.val, C0.err); } if(lam_G == 0.0) { GSL_SF_RESULT_SET(Gp, 1.0/C0.val, fabs(C0.err/C0.val)/fabs(C0.val)); } GSL_ERROR ("domain error", GSL_EDOM); /* After all, since we are asking for G, this is a domain error... */ } else if(x < 1.2 && 2.0*M_PI*eta < 0.9*(-GSL_LOG_DBL_MIN) && fabs(eta*x) < 10.0) { /* Reduce to a small lambda value and use the series * representations for F and G. We cannot allow eta to * be large and positive because the connection formula * for G_lam is badly behaved due to an underflow in sin(phi_lam) * [see coulomb_FG_series() and coulomb_connection() above]. * Note that large negative eta is ok however. */ const double SMALL = GSL_SQRT_DBL_EPSILON; const int N = (int)(lam_F + 0.5); const int span = GSL_MAX(k_lam_G, N); const double lam_min = lam_F - N; /* -1/2 <= lam_min < 1/2 */ double F_lam_F, Fp_lam_F; double G_lam_G, Gp_lam_G; double F_lam_F_err, Fp_lam_F_err; double Fp_over_F_lam_F; double F_sign_lam_F; double F_lam_min_unnorm, Fp_lam_min_unnorm; double Fp_over_F_lam_min; gsl_sf_result F_lam_min; gsl_sf_result G_lam_min, Gp_lam_min; double F_scale; double Gerr_frac; double F_scale_frac_err; double F_unnorm_frac_err; /* Determine F'/F at lam_F. */ int CF1_count; int stat_CF1 = coulomb_CF1(lam_F, eta, x, &F_sign_lam_F, &Fp_over_F_lam_F, &CF1_count); int stat_ser; int stat_Fr; int stat_Gr; /* Recurse down with unnormalized F,F' values. */ F_lam_F = SMALL; Fp_lam_F = Fp_over_F_lam_F * F_lam_F; if(span != 0) { stat_Fr = coulomb_F_recur(lam_min, span, eta, x, F_lam_F, Fp_lam_F, &F_lam_min_unnorm, &Fp_lam_min_unnorm ); } else { F_lam_min_unnorm = F_lam_F; Fp_lam_min_unnorm = Fp_lam_F; stat_Fr = GSL_SUCCESS; } /* Determine F and G at lam_min. */ if(lam_min == -0.5) { stat_ser = coulomb_FGmhalf_series(eta, x, &F_lam_min, &G_lam_min); } else if(lam_min == 0.0) { stat_ser = coulomb_FG0_series(eta, x, &F_lam_min, &G_lam_min); } else if(lam_min == 0.5) { /* This cannot happen. */ F->val = F_lam_F; F->err = 2.0 * GSL_DBL_EPSILON * fabs(F->val); Fp->val = Fp_lam_F; Fp->err = 2.0 * GSL_DBL_EPSILON * fabs(Fp->val); G->val = G_lam_G; G->err = 2.0 * GSL_DBL_EPSILON * fabs(G->val); Gp->val = Gp_lam_G; Gp->err = 2.0 * GSL_DBL_EPSILON * fabs(Gp->val); *exp_F = 0.0; *exp_G = 0.0; GSL_ERROR ("error", GSL_ESANITY); } else { stat_ser = coulomb_FG_series(lam_min, eta, x, &F_lam_min, &G_lam_min); } /* Determine remaining quantities. */ Fp_over_F_lam_min = Fp_lam_min_unnorm / F_lam_min_unnorm; Gp_lam_min.val = Fp_over_F_lam_min*G_lam_min.val - 1.0/F_lam_min.val; Gp_lam_min.err = fabs(Fp_over_F_lam_min)*G_lam_min.err; Gp_lam_min.err += fabs(1.0/F_lam_min.val) * fabs(F_lam_min.err/F_lam_min.val); F_scale = F_lam_min.val / F_lam_min_unnorm; /* Apply scale to the original F,F' values. */ F_scale_frac_err = fabs(F_lam_min.err/F_lam_min.val); F_unnorm_frac_err = 2.0*GSL_DBL_EPSILON*(CF1_count+span+1); F_lam_F *= F_scale; F_lam_F_err = fabs(F_lam_F) * (F_unnorm_frac_err + F_scale_frac_err); Fp_lam_F *= F_scale; Fp_lam_F_err = fabs(Fp_lam_F) * (F_unnorm_frac_err + F_scale_frac_err); /* Recurse up to get the required G,G' values. */ stat_Gr = coulomb_G_recur(lam_min, GSL_MAX(N-k_lam_G,0), eta, x, G_lam_min.val, Gp_lam_min.val, &G_lam_G, &Gp_lam_G ); F->val = F_lam_F; F->err = F_lam_F_err; F->err += 2.0 * GSL_DBL_EPSILON * fabs(F_lam_F); Fp->val = Fp_lam_F; Fp->err = Fp_lam_F_err; Fp->err += 2.0 * GSL_DBL_EPSILON * fabs(Fp_lam_F); Gerr_frac = fabs(G_lam_min.err/G_lam_min.val) + fabs(Gp_lam_min.err/Gp_lam_min.val); G->val = G_lam_G; G->err = Gerr_frac * fabs(G_lam_G); G->err += 2.0 * (CF1_count+1) * GSL_DBL_EPSILON * fabs(G->val); Gp->val = Gp_lam_G; Gp->err = Gerr_frac * fabs(Gp->val); Gp->err += 2.0 * (CF1_count+1) * GSL_DBL_EPSILON * fabs(Gp->val); *exp_F = 0.0; *exp_G = 0.0; return GSL_ERROR_SELECT_4(stat_ser, stat_CF1, stat_Fr, stat_Gr); } else if(x < 2.0*eta) { /* Use WKB approximation to obtain F and G at the two * lambda values, and use the Wronskian and the * continued fractions for F'/F to obtain F' and G'. */ gsl_sf_result F_lam_F, G_lam_F; gsl_sf_result F_lam_G, G_lam_G; double exp_lam_F, exp_lam_G; int stat_lam_F; int stat_lam_G; int stat_CF1_lam_F; int stat_CF1_lam_G; int CF1_count; double Fp_over_F_lam_F; double Fp_over_F_lam_G; double F_sign_lam_F; double F_sign_lam_G; stat_lam_F = coulomb_jwkb(lam_F, eta, x, &F_lam_F, &G_lam_F, &exp_lam_F); if(k_lam_G == 0) { stat_lam_G = stat_lam_F; F_lam_G = F_lam_F; G_lam_G = G_lam_F; exp_lam_G = exp_lam_F; } else { stat_lam_G = coulomb_jwkb(lam_G, eta, x, &F_lam_G, &G_lam_G, &exp_lam_G); } stat_CF1_lam_F = coulomb_CF1(lam_F, eta, x, &F_sign_lam_F, &Fp_over_F_lam_F, &CF1_count); if(k_lam_G == 0) { stat_CF1_lam_G = stat_CF1_lam_F; F_sign_lam_G = F_sign_lam_F; Fp_over_F_lam_G = Fp_over_F_lam_F; } else { stat_CF1_lam_G = coulomb_CF1(lam_G, eta, x, &F_sign_lam_G, &Fp_over_F_lam_G, &CF1_count); } F->val = F_lam_F.val; F->err = F_lam_F.err; G->val = G_lam_G.val; G->err = G_lam_G.err; Fp->val = Fp_over_F_lam_F * F_lam_F.val; Fp->err = fabs(Fp_over_F_lam_F) * F_lam_F.err; Fp->err += 2.0*GSL_DBL_EPSILON*fabs(Fp->val); Gp->val = Fp_over_F_lam_G * G_lam_G.val - 1.0/F_lam_G.val; Gp->err = fabs(Fp_over_F_lam_G) * G_lam_G.err; Gp->err += fabs(1.0/F_lam_G.val) * fabs(F_lam_G.err/F_lam_G.val); *exp_F = exp_lam_F; *exp_G = exp_lam_G; if(stat_lam_F == GSL_EOVRFLW || stat_lam_G == GSL_EOVRFLW) { GSL_ERROR ("overflow", GSL_EOVRFLW); } else { return GSL_ERROR_SELECT_2(stat_lam_F, stat_lam_G); } } else { /* x > 2 eta, so we know that we can find a lambda value such * that x is above the turning point. We do this, evaluate * using Steed's method at that oscillatory point, then * use recursion on F and G to obtain the required values. * * lam_0 = a value of lambda such that x is below the turning point * lam_min = minimum of lam_0 and the requested lam_G, since * we must go at least as low as lam_G */ const double SMALL = GSL_SQRT_DBL_EPSILON; const double C = sqrt(1.0 + 4.0*x*(x-2.0*eta)); const int N = ceil(lam_F - C + 0.5); const double lam_0 = lam_F - GSL_MAX(N, 0); const double lam_min = GSL_MIN(lam_0, lam_G); double F_lam_F, Fp_lam_F; double G_lam_G, Gp_lam_G; double F_lam_min_unnorm, Fp_lam_min_unnorm; double F_lam_min, Fp_lam_min; double G_lam_min, Gp_lam_min; double Fp_over_F_lam_F; double Fp_over_F_lam_min; double F_sign_lam_F, F_sign_lam_min; double P_lam_min, Q_lam_min; double alpha; double gamma; double F_scale; int CF1_count; int CF2_count; int stat_CF1 = coulomb_CF1(lam_F, eta, x, &F_sign_lam_F, &Fp_over_F_lam_F, &CF1_count); int stat_CF2; int stat_Fr; int stat_Gr; int F_recur_count; int G_recur_count; double err_amplify; F_lam_F = F_sign_lam_F * SMALL; /* unnormalized */ Fp_lam_F = Fp_over_F_lam_F * F_lam_F; /* Backward recurrence to get F,Fp at lam_min */ F_recur_count = GSL_MAX(k_lam_G, N); stat_Fr = coulomb_F_recur(lam_min, F_recur_count, eta, x, F_lam_F, Fp_lam_F, &F_lam_min_unnorm, &Fp_lam_min_unnorm ); Fp_over_F_lam_min = Fp_lam_min_unnorm / F_lam_min_unnorm; /* Steed evaluation to complete evaluation of F,Fp,G,Gp at lam_min */ stat_CF2 = coulomb_CF2(lam_min, eta, x, &P_lam_min, &Q_lam_min, &CF2_count); alpha = Fp_over_F_lam_min - P_lam_min; gamma = alpha/Q_lam_min; F_sign_lam_min = GSL_SIGN(F_lam_min_unnorm) ; F_lam_min = F_sign_lam_min / sqrt(alpha*alpha/Q_lam_min + Q_lam_min); Fp_lam_min = Fp_over_F_lam_min * F_lam_min; G_lam_min = gamma * F_lam_min; Gp_lam_min = (P_lam_min * gamma - Q_lam_min) * F_lam_min; /* Apply scale to values of F,Fp at lam_F (the top). */ F_scale = F_lam_min / F_lam_min_unnorm; F_lam_F *= F_scale; Fp_lam_F *= F_scale; /* Forward recurrence to get G,Gp at lam_G (the top). */ G_recur_count = GSL_MAX(N-k_lam_G,0); stat_Gr = coulomb_G_recur(lam_min, G_recur_count, eta, x, G_lam_min, Gp_lam_min, &G_lam_G, &Gp_lam_G ); err_amplify = CF1_count + CF2_count + F_recur_count + G_recur_count + 1; F->val = F_lam_F; F->err = 8.0*err_amplify*GSL_DBL_EPSILON * fabs(F->val); Fp->val = Fp_lam_F; Fp->err = 8.0*err_amplify*GSL_DBL_EPSILON * fabs(Fp->val); G->val = G_lam_G; G->err = 8.0*err_amplify*GSL_DBL_EPSILON * fabs(G->val); Gp->val = Gp_lam_G; Gp->err = 8.0*err_amplify*GSL_DBL_EPSILON * fabs(Gp->val); *exp_F = 0.0; *exp_G = 0.0; return GSL_ERROR_SELECT_4(stat_CF1, stat_CF2, stat_Fr, stat_Gr); } } int gsl_sf_coulomb_wave_F_array(double lam_min, int kmax, double eta, double x, double * fc_array, double * F_exp) { if(x == 0.0) { int k; *F_exp = 0.0; for(k=0; k<=kmax; k++) { fc_array[k] = 0.0; } if(lam_min == 0.0){ gsl_sf_result f_0; CLeta(0.0, eta, &f_0); fc_array[0] = f_0.val; } return GSL_SUCCESS; } else { const double x_inv = 1.0/x; const double lam_max = lam_min + kmax; gsl_sf_result F, Fp; gsl_sf_result G, Gp; double G_exp; int stat_FG = gsl_sf_coulomb_wave_FG_e(eta, x, lam_max, 0, &F, &Fp, &G, &Gp, F_exp, &G_exp); double fcl = F.val; double fpl = Fp.val; double lam = lam_max; int k; fc_array[kmax] = F.val; for(k=kmax-1; k>=0; k--) { double el = eta/lam; double rl = hypot(1.0, el); double sl = el + lam*x_inv; double fc_lm1 = (fcl*sl + fpl)/rl; fc_array[k] = fc_lm1; fpl = fc_lm1*sl - fcl*rl; fcl = fc_lm1; lam -= 1.0; } return stat_FG; } } int gsl_sf_coulomb_wave_FG_array(double lam_min, int kmax, double eta, double x, double * fc_array, double * gc_array, double * F_exp, double * G_exp) { const double x_inv = 1.0/x; const double lam_max = lam_min + kmax; gsl_sf_result F, Fp; gsl_sf_result G, Gp; int stat_FG = gsl_sf_coulomb_wave_FG_e(eta, x, lam_max, kmax, &F, &Fp, &G, &Gp, F_exp, G_exp); double fcl = F.val; double fpl = Fp.val; double lam = lam_max; int k; double gcl, gpl; fc_array[kmax] = F.val; for(k=kmax-1; k>=0; k--) { double el = eta/lam; double rl = hypot(1.0, el); double sl = el + lam*x_inv; double fc_lm1; fc_lm1 = (fcl*sl + fpl)/rl; fc_array[k] = fc_lm1; fpl = fc_lm1*sl - fcl*rl; fcl = fc_lm1; lam -= 1.0; } gcl = G.val; gpl = Gp.val; lam = lam_min + 1.0; gc_array[0] = G.val; for(k=1; k<=kmax; k++) { double el = eta/lam; double rl = hypot(1.0, el); double sl = el + lam*x_inv; double gcl1 = (sl*gcl - gpl)/rl; gc_array[k] = gcl1; gpl = rl*gcl - sl*gcl1; gcl = gcl1; lam += 1.0; } return stat_FG; } int gsl_sf_coulomb_wave_FGp_array(double lam_min, int kmax, double eta, double x, double * fc_array, double * fcp_array, double * gc_array, double * gcp_array, double * F_exp, double * G_exp) { const double x_inv = 1.0/x; const double lam_max = lam_min + kmax; gsl_sf_result F, Fp; gsl_sf_result G, Gp; int stat_FG = gsl_sf_coulomb_wave_FG_e(eta, x, lam_max, kmax, &F, &Fp, &G, &Gp, F_exp, G_exp); double fcl = F.val; double fpl = Fp.val; double lam = lam_max; int k; double gcl, gpl; fc_array[kmax] = F.val; fcp_array[kmax] = Fp.val; for(k=kmax-1; k>=0; k--) { double el = eta/lam; double rl = hypot(1.0, el); double sl = el + lam*x_inv; double fc_lm1; fc_lm1 = (fcl*sl + fpl)/rl; fc_array[k] = fc_lm1; fpl = fc_lm1*sl - fcl*rl; fcp_array[k] = fpl; fcl = fc_lm1; lam -= 1.0; } gcl = G.val; gpl = Gp.val; lam = lam_min + 1.0; gc_array[0] = G.val; gcp_array[0] = Gp.val; for(k=1; k<=kmax; k++) { double el = eta/lam; double rl = hypot(1.0, el); double sl = el + lam*x_inv; double gcl1 = (sl*gcl - gpl)/rl; gc_array[k] = gcl1; gpl = rl*gcl - sl*gcl1; gcp_array[k] = gpl; gcl = gcl1; lam += 1.0; } return stat_FG; } int gsl_sf_coulomb_wave_sphF_array(double lam_min, int kmax, double eta, double x, double * fc_array, double * F_exp) { if(x < 0.0 || lam_min < -0.5) { GSL_ERROR ("domain error", GSL_EDOM); } else if(x < 10.0/GSL_DBL_MAX) { int k; for(k=0; k<=kmax; k++) { fc_array[k] = 0.0; } if(lam_min == 0.0) { fc_array[0] = sqrt(C0sq(eta)); } *F_exp = 0.0; if(x == 0.0) return GSL_SUCCESS; else GSL_ERROR ("underflow", GSL_EUNDRFLW); } else { int k; int stat_F = gsl_sf_coulomb_wave_F_array(lam_min, kmax, eta, x, fc_array, F_exp); for(k=0; k<=kmax; k++) { fc_array[k] = fc_array[k] / x; } return stat_F; } } praat-6.0.04/external/gsl/gsl_specfunc__coulomb_bound.c000066400000000000000000000072761261542461700232300ustar00rootroot00000000000000/* specfunc/coulomb_bound.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_exp.h" #include "gsl_sf_gamma.h" #include "gsl_sf_pow_int.h" #include "gsl_sf_laguerre.h" #include "gsl_sf_coulomb.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__check.h" /* normalization for hydrogenic wave functions */ static int R_norm(const int n, const int l, const double Z, gsl_sf_result * result) { double A = 2.0*Z/n; double pre = sqrt(A*A*A /(2.0*n)); gsl_sf_result ln_a, ln_b; gsl_sf_result ex; int stat_a = gsl_sf_lnfact_e(n+l, &ln_a); int stat_b = gsl_sf_lnfact_e(n-l-1, &ln_b); double diff_val = 0.5*(ln_b.val - ln_a.val); double diff_err = 0.5*(ln_b.err + ln_a.err) + GSL_DBL_EPSILON * fabs(diff_val); int stat_e = gsl_sf_exp_err_e(diff_val, diff_err, &ex); result->val = pre * ex.val; result->err = pre * ex.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_3(stat_e, stat_a, stat_b); } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_hydrogenicR_1_e(const double Z, const double r, gsl_sf_result * result) { if(Z > 0.0 && r >= 0.0) { double A = 2.0*Z; double norm = A*sqrt(Z); double ea = exp(-Z*r); result->val = norm*ea; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val) * fabs(Z*r); CHECK_UNDERFLOW(result); return GSL_SUCCESS; } else { DOMAIN_ERROR(result); } } int gsl_sf_hydrogenicR_e(const int n, const int l, const double Z, const double r, gsl_sf_result * result) { if(n < 1 || l > n-1 || Z <= 0.0 || r < 0.0) { DOMAIN_ERROR(result); } else { double A = 2.0*Z/n; gsl_sf_result norm; int stat_norm = R_norm(n, l, Z, &norm); double rho = A*r; double ea = exp(-0.5*rho); double pp = gsl_sf_pow_int(rho, l); gsl_sf_result lag; int stat_lag = gsl_sf_laguerre_n_e(n-l-1, 2*l+1, rho, &lag); double W_val = norm.val * ea * pp; double W_err = norm.err * ea * pp; W_err += norm.val * ((0.5*rho + 1.0) * GSL_DBL_EPSILON) * ea * pp; W_err += norm.val * ea * ((l+1.0) * GSL_DBL_EPSILON) * pp; result->val = W_val * lag.val; result->err = W_val * lag.err + W_err * fabs(lag.val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); if ((l == 0 || (r > 0 && l > 0)) && lag.val != 0.0 && stat_lag == GSL_SUCCESS && stat_norm == GSL_SUCCESS) { CHECK_UNDERFLOW(result); }; return GSL_ERROR_SELECT_2(stat_lag, stat_norm); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_hydrogenicR_1(const double Z, const double r) { EVAL_RESULT(gsl_sf_hydrogenicR_1_e(Z, r, &result)); } double gsl_sf_hydrogenicR(const int n, const int l, const double Z, const double r) { EVAL_RESULT(gsl_sf_hydrogenicR_e(n, l, Z, r, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__coupling.c000066400000000000000000000326171261542461700222160ustar00rootroot00000000000000/* specfunc/coupling.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_gamma.h" #include "gsl_sf_coupling.h" #include "gsl_specfunc__error.h" inline static int locMax3(const int a, const int b, const int c) { int d = GSL_MAX(a, b); return GSL_MAX(d, c); } inline static int locMin3(const int a, const int b, const int c) { int d = GSL_MIN(a, b); return GSL_MIN(d, c); } inline static int locMin5(const int a, const int b, const int c, const int d, const int e) { int f = GSL_MIN(a, b); int g = GSL_MIN(c, d); int h = GSL_MIN(f, g); return GSL_MIN(e, h); } /* See: [Thompson, Atlas for Computing Mathematical Functions] */ static int delta(int ta, int tb, int tc, gsl_sf_result * d) { gsl_sf_result f1, f2, f3, f4; int status = 0; status += gsl_sf_fact_e((ta + tb - tc)/2, &f1); status += gsl_sf_fact_e((ta + tc - tb)/2, &f2); status += gsl_sf_fact_e((tb + tc - ta)/2, &f3); status += gsl_sf_fact_e((ta + tb + tc)/2 + 1, &f4); if(status != 0) { OVERFLOW_ERROR(d); } d->val = f1.val * f2.val * f3.val / f4.val; d->err = 4.0 * GSL_DBL_EPSILON * fabs(d->val); return GSL_SUCCESS; } static int triangle_selection_fails(int two_ja, int two_jb, int two_jc) { return ((two_jb < abs(two_ja - two_jc)) || (two_jb > two_ja + two_jc)); } static int m_selection_fails(int two_ja, int two_jb, int two_jc, int two_ma, int two_mb, int two_mc) { return ( abs(two_ma) > two_ja || abs(two_mb) > two_jb || abs(two_mc) > two_jc || GSL_IS_ODD(two_ja + two_ma) || GSL_IS_ODD(two_jb + two_mb) || GSL_IS_ODD(two_jc + two_mc) || (two_ma + two_mb + two_mc) != 0 ); } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_coupling_3j_e (int two_ja, int two_jb, int two_jc, int two_ma, int two_mb, int two_mc, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(two_ja < 0 || two_jb < 0 || two_jc < 0) { DOMAIN_ERROR(result); } else if ( triangle_selection_fails(two_ja, two_jb, two_jc) || m_selection_fails(two_ja, two_jb, two_jc, two_ma, two_mb, two_mc) ) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else { int jca = (-two_ja + two_jb + two_jc) / 2, jcb = ( two_ja - two_jb + two_jc) / 2, jcc = ( two_ja + two_jb - two_jc) / 2, jmma = ( two_ja - two_ma) / 2, jmmb = ( two_jb - two_mb) / 2, jmmc = ( two_jc - two_mc) / 2, jpma = ( two_ja + two_ma) / 2, jpmb = ( two_jb + two_mb) / 2, jpmc = ( two_jc + two_mc) / 2, jsum = ( two_ja + two_jb + two_jc) / 2, kmin = locMax3 (0, jpmb - jmmc, jmma - jpmc), kmax = locMin3 (jcc, jmma, jpmb), k, sign = GSL_IS_ODD (kmin - jpma + jmmb) ? -1 : 1, status = 0; double sum_pos = 0.0, sum_neg = 0.0, norm, term; gsl_sf_result bc1, bc2, bc3, bcn1, bcn2, bcd1, bcd2, bcd3, bcd4; status += gsl_sf_choose_e (two_ja, jcc , &bcn1); status += gsl_sf_choose_e (two_jb, jcc , &bcn2); status += gsl_sf_choose_e (jsum+1, jcc , &bcd1); status += gsl_sf_choose_e (two_ja, jmma, &bcd2); status += gsl_sf_choose_e (two_jb, jmmb, &bcd3); status += gsl_sf_choose_e (two_jc, jpmc, &bcd4); if (status != 0) { OVERFLOW_ERROR (result); } norm = sqrt (bcn1.val * bcn2.val) / sqrt (bcd1.val * bcd2.val * bcd3.val * bcd4.val * ((double) two_jc + 1.0)); for (k = kmin; k <= kmax; k++) { status += gsl_sf_choose_e (jcc, k, &bc1); status += gsl_sf_choose_e (jcb, jmma - k, &bc2); status += gsl_sf_choose_e (jca, jpmb - k, &bc3); if (status != 0) { OVERFLOW_ERROR (result); } term = bc1.val * bc2.val * bc3.val; if (sign < 0) { sum_neg += norm * term; } else { sum_pos += norm * term; } sign = -sign; } result->val = sum_pos - sum_neg; result->err = 2.0 * GSL_DBL_EPSILON * (sum_pos + sum_neg); result->err += 2.0 * GSL_DBL_EPSILON * (kmax - kmin) * fabs(result->val); return GSL_SUCCESS; } } #if ! defined (GSL_DISABLE_DEPRECATED) int gsl_sf_coupling_6j_INCORRECT_e(int two_ja, int two_jb, int two_jc, int two_jd, int two_je, int two_jf, gsl_sf_result * result) { return gsl_sf_coupling_6j_e(two_ja, two_jb, two_je, two_jd, two_jc, two_jf, result); } #endif int gsl_sf_coupling_6j_e(int two_ja, int two_jb, int two_jc, int two_jd, int two_je, int two_jf, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if( two_ja < 0 || two_jb < 0 || two_jc < 0 || two_jd < 0 || two_je < 0 || two_jf < 0 ) { DOMAIN_ERROR(result); } else if( triangle_selection_fails(two_ja, two_jb, two_jc) || triangle_selection_fails(two_ja, two_je, two_jf) || triangle_selection_fails(two_jb, two_jd, two_jf) || triangle_selection_fails(two_je, two_jd, two_jc) ) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else { gsl_sf_result n1; gsl_sf_result d1, d2, d3, d4, d5, d6; double norm; int tk, tkmin, tkmax; double phase; double sum_pos = 0.0; double sum_neg = 0.0; double sumsq_err = 0.0; int status = 0; status += delta(two_ja, two_jb, two_jc, &d1); status += delta(two_ja, two_je, two_jf, &d2); status += delta(two_jb, two_jd, two_jf, &d3); status += delta(two_je, two_jd, two_jc, &d4); if(status != GSL_SUCCESS) { OVERFLOW_ERROR(result); } norm = sqrt(d1.val) * sqrt(d2.val) * sqrt(d3.val) * sqrt(d4.val); tkmin = locMax3(0, two_ja + two_jd - two_jc - two_jf, two_jb + two_je - two_jc - two_jf); tkmax = locMin5(two_ja + two_jb + two_je + two_jd + 2, two_ja + two_jb - two_jc, two_je + two_jd - two_jc, two_ja + two_je - two_jf, two_jb + two_jd - two_jf); phase = GSL_IS_ODD((two_ja + two_jb + two_je + two_jd + tkmin)/2) ? -1.0 : 1.0; for(tk=tkmin; tk<=tkmax; tk += 2) { double term; double term_err; gsl_sf_result den_1, den_2; gsl_sf_result d1_a, d1_b; status = 0; status += gsl_sf_fact_e((two_ja + two_jb + two_je + two_jd - tk)/2 + 1, &n1); status += gsl_sf_fact_e(tk/2, &d1_a); status += gsl_sf_fact_e((two_jc + two_jf - two_ja - two_jd + tk)/2, &d1_b); status += gsl_sf_fact_e((two_jc + two_jf - two_jb - two_je + tk)/2, &d2); status += gsl_sf_fact_e((two_ja + two_jb - two_jc - tk)/2, &d3); status += gsl_sf_fact_e((two_je + two_jd - two_jc - tk)/2, &d4); status += gsl_sf_fact_e((two_ja + two_je - two_jf - tk)/2, &d5); status += gsl_sf_fact_e((two_jb + two_jd - two_jf - tk)/2, &d6); if(status != GSL_SUCCESS) { OVERFLOW_ERROR(result); } d1.val = d1_a.val * d1_b.val; d1.err = d1_a.err * fabs(d1_b.val) + fabs(d1_a.val) * d1_b.err; den_1.val = d1.val*d2.val*d3.val; den_1.err = d1.err * fabs(d2.val*d3.val); den_1.err += d2.err * fabs(d1.val*d3.val); den_1.err += d3.err * fabs(d1.val*d2.val); den_2.val = d4.val*d5.val*d6.val; den_2.err = d4.err * fabs(d5.val*d6.val); den_2.err += d5.err * fabs(d4.val*d6.val); den_2.err += d6.err * fabs(d4.val*d5.val); term = phase * n1.val / den_1.val / den_2.val; phase = -phase; term_err = n1.err / fabs(den_1.val) / fabs(den_2.val); term_err += fabs(term / den_1.val) * den_1.err; term_err += fabs(term / den_2.val) * den_2.err; if(term >= 0.0) { sum_pos += norm*term; } else { sum_neg -= norm*term; } sumsq_err += norm*norm * term_err*term_err; } result->val = sum_pos - sum_neg; result->err = 2.0 * GSL_DBL_EPSILON * (sum_pos + sum_neg); result->err += sqrt(sumsq_err / (0.5*(tkmax-tkmin)+1.0)); result->err += 2.0 * GSL_DBL_EPSILON * (tkmax - tkmin + 2.0) * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_coupling_RacahW_e(int two_ja, int two_jb, int two_jc, int two_jd, int two_je, int two_jf, gsl_sf_result * result) { int status = gsl_sf_coupling_6j_e(two_ja, two_jb, two_je, two_jd, two_jc, two_jf, result); int phase_sum = (two_ja + two_jb + two_jc + two_jd)/2; result->val *= ( GSL_IS_ODD(phase_sum) ? -1.0 : 1.0 ); return status; } int gsl_sf_coupling_9j_e(int two_ja, int two_jb, int two_jc, int two_jd, int two_je, int two_jf, int two_jg, int two_jh, int two_ji, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if( two_ja < 0 || two_jb < 0 || two_jc < 0 || two_jd < 0 || two_je < 0 || two_jf < 0 || two_jg < 0 || two_jh < 0 || two_ji < 0 ) { DOMAIN_ERROR(result); } else if( triangle_selection_fails(two_ja, two_jb, two_jc) || triangle_selection_fails(two_jd, two_je, two_jf) || triangle_selection_fails(two_jg, two_jh, two_ji) || triangle_selection_fails(two_ja, two_jd, two_jg) || triangle_selection_fails(two_jb, two_je, two_jh) || triangle_selection_fails(two_jc, two_jf, two_ji) ) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else { int tk; int tkmin = locMax3(abs(two_ja-two_ji), abs(two_jh-two_jd), abs(two_jb-two_jf)); int tkmax = locMin3(two_ja + two_ji, two_jh + two_jd, two_jb + two_jf); double sum_pos = 0.0; double sum_neg = 0.0; double sumsq_err = 0.0; double phase; for(tk=tkmin; tk<=tkmax; tk += 2) { gsl_sf_result s1, s2, s3; double term; double term_err; int status = 0; status += gsl_sf_coupling_6j_e(two_ja, two_ji, tk, two_jh, two_jd, two_jg, &s1); status += gsl_sf_coupling_6j_e(two_jb, two_jf, tk, two_jd, two_jh, two_je, &s2); status += gsl_sf_coupling_6j_e(two_ja, two_ji, tk, two_jf, two_jb, two_jc, &s3); if(status != GSL_SUCCESS) { OVERFLOW_ERROR(result); } term = s1.val * s2.val * s3.val; term_err = s1.err * fabs(s2.val*s3.val); term_err += s2.err * fabs(s1.val*s3.val); term_err += s3.err * fabs(s1.val*s2.val); if(term >= 0.0) { sum_pos += (tk + 1) * term; } else { sum_neg -= (tk + 1) * term; } sumsq_err += ((tk+1) * term_err) * ((tk+1) * term_err); } phase = GSL_IS_ODD(tkmin) ? -1.0 : 1.0; result->val = phase * (sum_pos - sum_neg); result->err = 2.0 * GSL_DBL_EPSILON * (sum_pos + sum_neg); result->err += sqrt(sumsq_err / (0.5*(tkmax-tkmin)+1.0)); result->err += 2.0 * GSL_DBL_EPSILON * (tkmax-tkmin + 2.0) * fabs(result->val); return GSL_SUCCESS; } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_coupling_3j(int two_ja, int two_jb, int two_jc, int two_ma, int two_mb, int two_mc) { EVAL_RESULT(gsl_sf_coupling_3j_e(two_ja, two_jb, two_jc, two_ma, two_mb, two_mc, &result)); } #if ! defined (GSL_DISABLE_DEPRECATED) double gsl_sf_coupling_6j_INCORRECT(int two_ja, int two_jb, int two_jc, int two_jd, int two_je, int two_jf) { EVAL_RESULT(gsl_sf_coupling_6j_INCORRECT_e(two_ja, two_jb, two_jc, two_jd, two_je, two_jf, &result)); } #endif double gsl_sf_coupling_6j(int two_ja, int two_jb, int two_jc, int two_jd, int two_je, int two_jf) { EVAL_RESULT(gsl_sf_coupling_6j_e(two_ja, two_jb, two_jc, two_jd, two_je, two_jf, &result)); } double gsl_sf_coupling_RacahW(int two_ja, int two_jb, int two_jc, int two_jd, int two_je, int two_jf) { EVAL_RESULT(gsl_sf_coupling_RacahW_e(two_ja, two_jb, two_jc, two_jd, two_je, two_jf, &result)); } double gsl_sf_coupling_9j(int two_ja, int two_jb, int two_jc, int two_jd, int two_je, int two_jf, int two_jg, int two_jh, int two_ji) { EVAL_RESULT(gsl_sf_coupling_9j_e(two_ja, two_jb, two_jc, two_jd, two_je, two_jf, two_jg, two_jh, two_ji, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__dawson.c000066400000000000000000000235151261542461700216660ustar00rootroot00000000000000/* specfunc/dawson.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_dawson.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__chebyshev.h" #include "gsl_specfunc__cheb_eval.c" /* Based on ddaws.f, Fullerton, W., (LANL) */ /* Chebyshev expansions Series for DAW on the interval 0. to 1.00000E+00 with weighted error 8.95E-32 log weighted error 31.05 significant figures required 30.41 decimal places required 31.71 Series for DAW2 on the interval 0. to 1.60000E+01 with weighted error 1.61E-32 log weighted error 31.79 significant figures required 31.40 decimal places required 32.62 Series for DAWA on the interval 0. to 6.25000E-02 with weighted error 1.97E-32 log weighted error 31.71 significant figures required 29.79 decimal places required 32.64 */ static double daw_data[21] = { -0.6351734375145949201065127736293e-02, -0.2294071479677386939899824125866e+00, 0.2213050093908476441683979161786e-01, -0.1549265453892985046743057753375e-02, 0.8497327715684917456777542948066e-04, -0.3828266270972014924994099521309e-05, 0.1462854806250163197757148949539e-06, -0.4851982381825991798846715425114e-08, 0.1421463577759139790347568183304e-09, -0.3728836087920596525335493054088e-11, 0.8854942961778203370194565231369e-13, -0.1920757131350206355421648417493e-14, 0.3834325867246327588241074439253e-16, -0.7089154168175881633584099327999e-18, 0.1220552135889457674416901120000e-19, -0.1966204826605348760299451733333e-21, 0.2975845541376597189113173333333e-23, -0.4247069514800596951039999999999e-25, 0.5734270767391742798506666666666e-27, -0.7345836823178450261333333333333e-29, 0.8951937667516552533333333333333e-31 }; static cheb_series daw_cs = { daw_data, 15, /* 20, */ -1, 1, 9 }; static double daw2_data[45] = { -0.56886544105215527114160533733674e-01, -0.31811346996168131279322878048822e+00, 0.20873845413642236789741580198858e+00, -0.12475409913779131214073498314784e+00, 0.67869305186676777092847516423676e-01, -0.33659144895270939503068230966587e-01, 0.15260781271987971743682460381640e-01, -0.63483709625962148230586094788535e-02, 0.24326740920748520596865966109343e-02, -0.86219541491065032038526983549637e-03, 0.28376573336321625302857636538295e-03, -0.87057549874170423699396581464335e-04, 0.24986849985481658331800044137276e-04, -0.67319286764160294344603050339520e-05, 0.17078578785573543710504524047844e-05, -0.40917551226475381271896592490038e-06, 0.92828292216755773260751785312273e-07, -0.19991403610147617829845096332198e-07, 0.40963490644082195241210487868917e-08, -0.80032409540993168075706781753561e-09, 0.14938503128761465059143225550110e-09, -0.26687999885622329284924651063339e-10, 0.45712216985159458151405617724103e-11, -0.75187305222043565872243727326771e-12, 0.11893100052629681879029828987302e-12, -0.18116907933852346973490318263084e-13, 0.26611733684358969193001612199626e-14, -0.37738863052129419795444109905930e-15, 0.51727953789087172679680082229329e-16, -0.68603684084077500979419564670102e-17, 0.88123751354161071806469337321745e-18, -0.10974248249996606292106299624652e-18, 0.13261199326367178513595545891635e-19, -0.15562732768137380785488776571562e-20, 0.17751425583655720607833415570773e-21, -0.19695006967006578384953608765439e-22, 0.21270074896998699661924010120533e-23, -0.22375398124627973794182113962666e-24, 0.22942768578582348946971383125333e-25, -0.22943788846552928693329592319999e-26, 0.22391702100592453618342297600000e-27, -0.21338230616608897703678225066666e-28, 0.19866196585123531518028458666666e-29, -0.18079295866694391771955199999999e-30, 0.16090686015283030305450666666666e-31 }; static cheb_series daw2_cs = { daw2_data, 32, /* 44, */ -1, 1, 21 }; static double dawa_data[75] = { 0.1690485637765703755422637438849e-01, 0.8683252278406957990536107850768e-02, 0.2424864042417715453277703459889e-03, 0.1261182399572690001651949240377e-04, 0.1066453314636176955705691125906e-05, 0.1358159794790727611348424505728e-06, 0.2171042356577298398904312744743e-07, 0.2867010501805295270343676804813e-08, -0.1901336393035820112282492378024e-09, -0.3097780484395201125532065774268e-09, -0.1029414876057509247398132286413e-09, -0.6260356459459576150417587283121e-11, 0.8563132497446451216262303166276e-11, 0.3033045148075659292976266276257e-11, -0.2523618306809291372630886938826e-12, -0.4210604795440664513175461934510e-12, -0.4431140826646238312143429452036e-13, 0.4911210272841205205940037065117e-13, 0.1235856242283903407076477954739e-13, -0.5788733199016569246955765071069e-14, -0.2282723294807358620978183957030e-14, 0.7637149411014126476312362917590e-15, 0.3851546883566811728777594002095e-15, -0.1199932056928290592803237283045e-15, -0.6313439150094572347334270285250e-16, 0.2239559965972975375254912790237e-16, 0.9987925830076495995132891200749e-17, -0.4681068274322495334536246507252e-17, -0.1436303644349721337241628751534e-17, 0.1020822731410541112977908032130e-17, 0.1538908873136092072837389822372e-18, -0.2189157877645793888894790926056e-18, 0.2156879197938651750392359152517e-20, 0.4370219827442449851134792557395e-19, -0.8234581460977207241098927905177e-20, -0.7498648721256466222903202835420e-20, 0.3282536720735671610957612930039e-20, 0.8858064309503921116076561515151e-21, -0.9185087111727002988094460531485e-21, 0.2978962223788748988314166045791e-22, 0.1972132136618471883159505468041e-21, -0.5974775596362906638089584995117e-22, -0.2834410031503850965443825182441e-22, 0.2209560791131554514777150489012e-22, -0.5439955741897144300079480307711e-25, -0.5213549243294848668017136696470e-23, 0.1702350556813114199065671499076e-23, 0.6917400860836148343022185660197e-24, -0.6540941793002752512239445125802e-24, 0.6093576580439328960371824654636e-25, 0.1408070432905187461501945080272e-24, -0.6785886121054846331167674943755e-25, -0.9799732036214295711741583102225e-26, 0.2121244903099041332598960939160e-25, -0.5954455022548790938238802154487e-26, -0.3093088861875470177838847232049e-26, 0.2854389216344524682400691986104e-26, -0.3951289447379305566023477271811e-27, -0.5906000648607628478116840894453e-27, 0.3670236964668687003647889980609e-27, -0.4839958238042276256598303038941e-29, -0.9799265984210443869597404017022e-28, 0.4684773732612130606158908804300e-28, 0.5030877696993461051647667603155e-29, -0.1547395051706028239247552068295e-28, 0.6112180185086419243976005662714e-29, 0.1357913399124811650343602736158e-29, -0.2417687752768673088385304299044e-29, 0.8369074582074298945292887587291e-30, 0.2665413042788979165838319401566e-30, -0.3811653692354890336935691003712e-30, 0.1230054721884951464371706872585e-30, 0.4622506399041493508805536929983e-31, -0.6120087296881677722911435593001e-31, 0.1966024640193164686956230217896e-31 }; static cheb_series dawa_cs = { dawa_data, 34, /* 74, */ -1, 1, 12 }; /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_dawson_e(double x, gsl_sf_result * result) { const double xsml = 1.225 * GSL_SQRT_DBL_EPSILON; const double xbig = 1.0/(M_SQRT2*GSL_SQRT_DBL_EPSILON); const double xmax = 0.1 * GSL_DBL_MAX; const double y = fabs(x); if(y < xsml) { result->val = x; result->err = 0.0; return GSL_SUCCESS; } else if(y < 1.0) { gsl_sf_result result_c; cheb_eval_e(&daw_cs, 2.0*y*y - 1.0, &result_c); result->val = x * (0.75 + result_c.val); result->err = y * result_c.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(y < 4.0) { gsl_sf_result result_c; cheb_eval_e(&daw2_cs, 0.125*y*y - 1.0, &result_c); result->val = x * (0.25 + result_c.val); result->err = y * result_c.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(y < xbig) { gsl_sf_result result_c; cheb_eval_e(&dawa_cs, 32.0/(y*y) - 1.0, &result_c); result->val = (0.5 + result_c.val) / x; result->err = result_c.err / y; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(y < xmax) { result->val = 0.5/x; result->err = 2.0 * GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; } else { UNDERFLOW_ERROR(result); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_dawson(double x) { EVAL_RESULT(gsl_sf_dawson_e(x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__debye.c000066400000000000000000000334771261542461700214730ustar00rootroot00000000000000/* specfunc/debye.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ /* augmented to n=5 and 6 2005-11-08 by R. J. Mathar, http://www.strw.leidenuniv.nl/~mathar */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_debye.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__check.h" #include "gsl_specfunc__chebyshev.h" #include "gsl_specfunc__cheb_eval.c" static double adeb1_data[17] = { 2.4006597190381410194, 0.1937213042189360089, -0.62329124554895770e-02, 0.3511174770206480e-03, -0.228222466701231e-04, 0.15805467875030e-05, -0.1135378197072e-06, 0.83583361188e-08, -0.6264424787e-09, 0.476033489e-10, -0.36574154e-11, 0.2835431e-12, -0.221473e-13, 0.17409e-14, -0.1376e-15, 0.109e-16, -0.9e-18 }; static cheb_series adeb1_cs = { adeb1_data, 16, -1.0, 1.0, 9 }; static double adeb2_data[18] = { 2.5943810232570770282, 0.2863357204530719834, -0.102062656158046713e-01, 0.6049109775346844e-03, -0.405257658950210e-04, 0.28633826328811e-05, -0.2086394303065e-06, 0.155237875826e-07, -0.11731280087e-08, 0.897358589e-10, -0.69317614e-11, 0.5398057e-12, -0.423241e-13, 0.33378e-14, -0.2645e-15, 0.211e-16, -0.17e-17, 0.1e-18 }; static cheb_series adeb2_cs = { adeb2_data, 17, -1.0, 1.0, 10 }; static double adeb3_data[17] = { 2.707737068327440945, 0.340068135211091751, -0.12945150184440869e-01, 0.7963755380173816e-03, -0.546360009590824e-04, 0.39243019598805e-05, -0.2894032823539e-06, 0.217317613962e-07, -0.16542099950e-08, 0.1272796189e-09, -0.987963460e-11, 0.7725074e-12, -0.607797e-13, 0.48076e-14, -0.3820e-15, 0.305e-16, -0.24e-17 }; static cheb_series adeb3_cs = { adeb3_data, 16, -1.0, 1.0, 10 }; static double adeb4_data[17] = { 2.781869415020523460, 0.374976783526892863, -0.14940907399031583e-01, 0.945679811437042e-03, -0.66132916138933e-04, 0.4815632982144e-05, -0.3588083958759e-06, 0.271601187416e-07, -0.20807099122e-08, 0.1609383869e-09, -0.125470979e-10, 0.9847265e-12, -0.777237e-13, 0.61648e-14, -0.4911e-15, 0.393e-16, -0.32e-17 }; static cheb_series adeb4_cs = { adeb4_data, 16, -1.0, 1.0, 10 }; static double adeb5_data[17] = { 2.8340269546834530149, 0.3994098857106266445, -0.164566764773099646e-1, 0.10652138340664541e-2, -0.756730374875418e-4, 0.55745985240273e-5, -0.4190692330918e-6, 0.319456143678e-7, -0.24613318171e-8, 0.1912801633e-9, -0.149720049e-10, 0.11790312e-11, -0.933329e-13, 0.74218e-14, -0.5925e-15, 0.475e-16, -0.39e-17 }; static cheb_series adeb5_cs = { adeb5_data, 16, -1.0, 1.0, 10 }; static double adeb6_data[17] = { 2.8726727134130122113, 0.4174375352339027746, -0.176453849354067873e-1, 0.11629852733494556e-2, -0.837118027357117e-4, 0.62283611596189e-5, -0.4718644465636e-6, 0.361950397806e-7, -0.28030368010e-8, 0.2187681983e-9, -0.171857387e-10, 0.13575809e-11, -0.1077580e-12, 0.85893e-14, -0.6872e-15, 0.552e-16, -0.44e-17 }; static cheb_series adeb6_cs = { adeb6_data, 16, -1.0, 1.0, 10 }; /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_debye_1_e(const double x, gsl_sf_result * result) { const double val_infinity = 1.64493406684822644; const double xcut = -GSL_LOG_DBL_MIN; /* CHECK_POINTER(result) */ if(x < 0.0) { DOMAIN_ERROR(result); } else if(x < 2.0*GSL_SQRT_DBL_EPSILON) { result->val = 1.0 - 0.25*x + x*x/36.0; result->err = GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x <= 4.0) { const double t = x*x/8.0 - 1.0; gsl_sf_result c; cheb_eval_e(&adeb1_cs, t, &c); result->val = c.val - 0.25 * x; result->err = c.err + 0.25 * x * GSL_DBL_EPSILON; return GSL_SUCCESS; } else if(x < -(M_LN2 + GSL_LOG_DBL_EPSILON)) { const int nexp = floor(xcut/x); const double ex = exp(-x); double sum = 0.0; double xk = nexp * x; double rk = nexp; int i; for(i=nexp; i>=1; i--) { sum *= ex; sum += (1.0 + 1.0/xk)/rk; rk -= 1.0; xk -= x; } result->val = val_infinity/x - sum*ex; result->err = GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < xcut) { result->val = (val_infinity - exp(-x)*(x+1.0)) / x; result->err = GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { result->val = val_infinity/x; result->err = GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_debye_2_e(const double x, gsl_sf_result * result) { const double val_infinity = 4.80822761263837714; const double xcut = -GSL_LOG_DBL_MIN; /* CHECK_POINTER(result) */ if(x < 0.0) { DOMAIN_ERROR(result); } else if(x < 2.0*M_SQRT2*GSL_SQRT_DBL_EPSILON) { result->val = 1.0 - x/3.0 + x*x/24.0; result->err = GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; } else if(x <= 4.0) { const double t = x*x/8.0 - 1.0; gsl_sf_result c; cheb_eval_e(&adeb2_cs, t, &c); result->val = c.val - x/3.0; result->err = c.err + GSL_DBL_EPSILON * x/3.0; return GSL_SUCCESS; } else if(x < -(M_LN2 + GSL_LOG_DBL_EPSILON)) { const int nexp = floor(xcut/x); const double ex = exp(-x); double xk = nexp * x; double rk = nexp; double sum = 0.0; int i; for(i=nexp; i>=1; i--) { sum *= ex; sum += (1.0 + 2.0/xk + 2.0/(xk*xk)) / rk; rk -= 1.0; xk -= x; } result->val = val_infinity/(x*x) - 2.0 * sum * ex; result->err = GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < xcut) { const double x2 = x*x; const double sum = 2.0 + 2.0*x + x2; result->val = (val_infinity - 2.0 * sum * exp(-x)) / x2; result->err = GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { result->val = (val_infinity/x)/x; result->err = GSL_DBL_EPSILON * result->val; CHECK_UNDERFLOW(result); return GSL_SUCCESS; } } int gsl_sf_debye_3_e(const double x, gsl_sf_result * result) { const double val_infinity = 19.4818182068004875; const double xcut = -GSL_LOG_DBL_MIN; /* CHECK_POINTER(result) */ if(x < 0.0) { DOMAIN_ERROR(result); } else if(x < 2.0*M_SQRT2*GSL_SQRT_DBL_EPSILON) { result->val = 1.0 - 3.0*x/8.0 + x*x/20.0; result->err = GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; } else if(x <= 4.0) { const double t = x*x/8.0 - 1.0; gsl_sf_result c; cheb_eval_e(&adeb3_cs, t, &c); result->val = c.val - 0.375*x; result->err = c.err + GSL_DBL_EPSILON * 0.375*x; return GSL_SUCCESS; } else if(x < -(M_LN2 + GSL_LOG_DBL_EPSILON)) { const int nexp = floor(xcut/x); const double ex = exp(-x); double xk = nexp * x; double rk = nexp; double sum = 0.0; int i; for(i=nexp; i>=1; i--) { double xk_inv = 1.0/xk; sum *= ex; sum += (((6.0*xk_inv + 6.0)*xk_inv + 3.0)*xk_inv + 1.0) / rk; rk -= 1.0; xk -= x; } result->val = val_infinity/(x*x*x) - 3.0 * sum * ex; result->err = GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; } else if(x < xcut) { const double x3 = x*x*x; const double sum = 6.0 + 6.0*x + 3.0*x*x + x3; result->val = (val_infinity - 3.0 * sum * exp(-x)) / x3; result->err = GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; } else { result->val = ((val_infinity/x)/x)/x; result->err = GSL_DBL_EPSILON * result->val; CHECK_UNDERFLOW(result); return GSL_SUCCESS; } } int gsl_sf_debye_4_e(const double x, gsl_sf_result * result) { const double val_infinity = 99.5450644937635129; const double xcut = -GSL_LOG_DBL_MIN; /* CHECK_POINTER(result) */ if(x < 0.0) { DOMAIN_ERROR(result); } else if(x < 2.0*M_SQRT2*GSL_SQRT_DBL_EPSILON) { result->val = 1.0 - 2.0*x/5.0 + x*x/18.0; result->err = GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; } else if(x <= 4.0) { const double t = x*x/8.0 - 1.0; gsl_sf_result c; cheb_eval_e(&adeb4_cs, t, &c); result->val = c.val - 2.0*x/5.0; result->err = c.err + GSL_DBL_EPSILON * 2.0*x/5.0; return GSL_SUCCESS; } else if(x < -(M_LN2 + GSL_LOG_DBL_EPSILON)) { const int nexp = floor(xcut/x); const double ex = exp(-x); double xk = nexp * x; double rk = nexp; double sum = 0.0; int i; for(i=nexp; i>=1; i--) { double xk_inv = 1.0/xk; sum *= ex; sum += ((((24.0*xk_inv + 24.0)*xk_inv + 12.0)*xk_inv + 4.0)*xk_inv + 1.0) / rk; rk -= 1.0; xk -= x; } result->val = val_infinity/(x*x*x*x) - 4.0 * sum * ex; result->err = GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; } else if(x < xcut) { const double x2 = x*x; const double x4 = x2*x2; const double sum = 24.0 + 24.0*x + 12.0*x2 + 4.0*x2*x + x4; result->val = (val_infinity - 4.0 * sum * exp(-x)) / x4; result->err = GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; } else { result->val = (((val_infinity/x)/x)/x)/x; result->err = GSL_DBL_EPSILON * result->val; CHECK_UNDERFLOW(result); return GSL_SUCCESS; } } int gsl_sf_debye_5_e(const double x, gsl_sf_result * result) { const double val_infinity = 610.405837190669483828710757875 ; const double xcut = -GSL_LOG_DBL_MIN; /* CHECK_POINTER(result) */ if(x < 0.0) { DOMAIN_ERROR(result); } else if(x < 2.0*M_SQRT2*GSL_SQRT_DBL_EPSILON) { result->val = 1.0 - 5.0*x/12.0 + 5.0*x*x/84.0; result->err = GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; } else if(x <= 4.0) { const double t = x*x/8.0 - 1.0; gsl_sf_result c; cheb_eval_e(&adeb5_cs, t, &c); result->val = c.val - 5.0*x/12.0; result->err = c.err + GSL_DBL_EPSILON * 5.0*x/12.0; return GSL_SUCCESS; } else if(x < -(M_LN2 + GSL_LOG_DBL_EPSILON)) { const int nexp = floor(xcut/x); const double ex = exp(-x); double xk = nexp * x; double rk = nexp; double sum = 0.0; int i; for(i=nexp; i>=1; i--) { double xk_inv = 1.0/xk; sum *= ex; sum += (((((120.0*xk_inv + 120.0)*xk_inv + 60.0)*xk_inv + 20.0)*xk_inv + 5.0)*xk_inv+ 1.0) / rk; rk -= 1.0; xk -= x; } result->val = val_infinity/(x*x*x*x*x) - 5.0 * sum * ex; result->err = GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; } else if(x < xcut) { const double x2 = x*x; const double x4 = x2*x2; const double x5 = x4*x; const double sum = 120.0 + 120.0*x + 60.0*x2 + 20.0*x2*x + 5.0*x4 + x5; result->val = (val_infinity - 5.0 * sum * exp(-x)) / x5; result->err = GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; } else { result->val = ((((val_infinity/x)/x)/x)/x)/x; result->err = GSL_DBL_EPSILON * result->val; CHECK_UNDERFLOW(result); return GSL_SUCCESS; } } int gsl_sf_debye_6_e(const double x, gsl_sf_result * result) { const double val_infinity = 4356.06887828990661194792541535 ; const double xcut = -GSL_LOG_DBL_MIN; /* CHECK_POINTER(result) */ if(x < 0.0) { DOMAIN_ERROR(result); } else if(x < 2.0*M_SQRT2*GSL_SQRT_DBL_EPSILON) { result->val = 1.0 - 3.0*x/7.0 + x*x/16.0; result->err = GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; } else if(x <= 4.0) { const double t = x*x/8.0 - 1.0; gsl_sf_result c; cheb_eval_e(&adeb6_cs, t, &c); result->val = c.val - 3.0*x/7.0; result->err = c.err + GSL_DBL_EPSILON * 3.0*x/7.0; return GSL_SUCCESS; } else if(x < -(M_LN2 + GSL_LOG_DBL_EPSILON)) { const int nexp = floor(xcut/x); const double ex = exp(-x); double xk = nexp * x; double rk = nexp; double sum = 0.0; int i; for(i=nexp; i>=1; i--) { double xk_inv = 1.0/xk; sum *= ex; sum += ((((((720.0*xk_inv + 720.0)*xk_inv + 360.0)*xk_inv + 120.0)*xk_inv + 30.0)*xk_inv+ 6.0)*xk_inv+ 1.0) / rk; rk -= 1.0; xk -= x; } result->val = val_infinity/(x*x*x*x*x*x) - 6.0 * sum * ex; result->err = GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; } else if(x < xcut) { const double x2 = x*x; const double x4 = x2*x2; const double x6 = x4*x2; const double sum = 720.0 + 720.0*x + 360.0*x2 + 120.0*x2*x + 30.0*x4 + 6.0*x4*x +x6 ; result->val = (val_infinity - 6.0 * sum * exp(-x)) / x6; result->err = GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; } else { result->val = (((((val_infinity/x)/x)/x)/x)/x)/x ; result->err = GSL_DBL_EPSILON * result->val; CHECK_UNDERFLOW(result); return GSL_SUCCESS; } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_debye_1(const double x) { EVAL_RESULT(gsl_sf_debye_1_e(x, &result)); } double gsl_sf_debye_2(const double x) { EVAL_RESULT(gsl_sf_debye_2_e(x, &result)); } double gsl_sf_debye_3(const double x) { EVAL_RESULT(gsl_sf_debye_3_e(x, &result)); } double gsl_sf_debye_4(const double x) { EVAL_RESULT(gsl_sf_debye_4_e(x, &result)); } double gsl_sf_debye_5(const double x) { EVAL_RESULT(gsl_sf_debye_5_e(x, &result)); } double gsl_sf_debye_6(const double x) { EVAL_RESULT(gsl_sf_debye_6_e(x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__dilog.c000066400000000000000000000431771261542461700214770ustar00rootroot00000000000000/* specfunc/dilog.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_clausen.h" #include "gsl_sf_trig.h" #include "gsl_sf_log.h" #include "gsl_sf_dilog.h" /* Evaluate series for real dilog(x) * Sum[ x^k / k^2, {k,1,Infinity}] * * Converges rapidly for |x| < 1/2. */ static int dilog_series_1(const double x, gsl_sf_result * result) { const int kmax = 1000; double sum = x; double term = x; int k; for(k=2; kval = sum; result->err = 2.0 * fabs(term); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); if(k == kmax) GSL_ERROR ("error", GSL_EMAXITER); else return GSL_SUCCESS; } /* Compute the associated series * * sum_{k=1}{infty} r^k / (k^2 (k+1)) * * This is a series which appears in the one-step accelerated * method, which splits out one elementary function from the * full definition of Li_2(x). See below. */ static int series_2(double r, gsl_sf_result * result) { static const int kmax = 100; double rk = r; double sum = 0.5 * r; int k; for(k=2; k<10; k++) { double ds; rk *= r; ds = rk/(k*k*(k+1.0)); sum += ds; } for(; kval = sum; result->err = 2.0 * kmax * GSL_DBL_EPSILON * fabs(sum); return GSL_SUCCESS; } /* Compute Li_2(x) using the accelerated series representation. * * Li_2(x) = 1 + (1-x)ln(1-x)/x + series_2(x) * * assumes: -1 < x < 1 */ static int dilog_series_2(double x, gsl_sf_result * result) { const int stat_s3 = series_2(x, result); double t; if(x > 0.01) t = (1.0 - x) * log(1.0-x) / x; else { static const double c3 = 1.0/3.0; static const double c4 = 1.0/4.0; static const double c5 = 1.0/5.0; static const double c6 = 1.0/6.0; static const double c7 = 1.0/7.0; static const double c8 = 1.0/8.0; const double t68 = c6 + x*(c7 + x*c8); const double t38 = c3 + x *(c4 + x *(c5 + x * t68)); t = (x - 1.0) * (1.0 + x*(0.5 + x*t38)); } result->val += 1.0 + t; result->err += 2.0 * GSL_DBL_EPSILON * fabs(t); return stat_s3; } /* Calculates Li_2(x) for real x. Assumes x >= 0.0. */ static int dilog_xge0(const double x, gsl_sf_result * result) { if(x > 2.0) { gsl_sf_result ser; const int stat_ser = dilog_series_2(1.0/x, &ser); const double log_x = log(x); const double t1 = M_PI*M_PI/3.0; const double t2 = ser.val; const double t3 = 0.5*log_x*log_x; result->val = t1 - t2 - t3; result->err = GSL_DBL_EPSILON * fabs(log_x) + ser.err; result->err += GSL_DBL_EPSILON * (fabs(t1) + fabs(t2) + fabs(t3)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_ser; } else if(x > 1.01) { gsl_sf_result ser; const int stat_ser = dilog_series_2(1.0 - 1.0/x, &ser); const double log_x = log(x); const double log_term = log_x * (log(1.0-1.0/x) + 0.5*log_x); const double t1 = M_PI*M_PI/6.0; const double t2 = ser.val; const double t3 = log_term; result->val = t1 + t2 - t3; result->err = GSL_DBL_EPSILON * fabs(log_x) + ser.err; result->err += GSL_DBL_EPSILON * (fabs(t1) + fabs(t2) + fabs(t3)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_ser; } else if(x > 1.0) { /* series around x = 1.0 */ const double eps = x - 1.0; const double lne = log(eps); const double c0 = M_PI*M_PI/6.0; const double c1 = 1.0 - lne; const double c2 = -(1.0 - 2.0*lne)/4.0; const double c3 = (1.0 - 3.0*lne)/9.0; const double c4 = -(1.0 - 4.0*lne)/16.0; const double c5 = (1.0 - 5.0*lne)/25.0; const double c6 = -(1.0 - 6.0*lne)/36.0; const double c7 = (1.0 - 7.0*lne)/49.0; const double c8 = -(1.0 - 8.0*lne)/64.0; result->val = c0+eps*(c1+eps*(c2+eps*(c3+eps*(c4+eps*(c5+eps*(c6+eps*(c7+eps*c8))))))); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x == 1.0) { result->val = M_PI*M_PI/6.0; result->err = 2.0 * GSL_DBL_EPSILON * M_PI*M_PI/6.0; return GSL_SUCCESS; } else if(x > 0.5) { gsl_sf_result ser; const int stat_ser = dilog_series_2(1.0-x, &ser); const double log_x = log(x); const double t1 = M_PI*M_PI/6.0; const double t2 = ser.val; const double t3 = log_x*log(1.0-x); result->val = t1 - t2 - t3; result->err = GSL_DBL_EPSILON * fabs(log_x) + ser.err; result->err += GSL_DBL_EPSILON * (fabs(t1) + fabs(t2) + fabs(t3)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_ser; } else if(x > 0.25) { return dilog_series_2(x, result); } else if(x > 0.0) { return dilog_series_1(x, result); } else { /* x == 0.0 */ result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } } /* Evaluate the series representation for Li2(z): * * Li2(z) = Sum[ |z|^k / k^2 Exp[i k arg(z)], {k,1,Infinity}] * |z| = r * arg(z) = theta * * Assumes 0 < r < 1. * It is used only for small r. */ static int dilogc_series_1( const double r, const double x, const double y, gsl_sf_result * real_result, gsl_sf_result * imag_result ) { const double cos_theta = x/r; const double sin_theta = y/r; const double alpha = 1.0 - cos_theta; const double beta = sin_theta; double ck = cos_theta; double sk = sin_theta; double rk = r; double real_sum = r*ck; double imag_sum = r*sk; const int kmax = 50 + (int)(22.0/(-log(r))); /* tuned for double-precision */ int k; for(k=2; kval = real_sum; real_result->err = 2.0 * kmax * GSL_DBL_EPSILON * fabs(real_sum); imag_result->val = imag_sum; imag_result->err = 2.0 * kmax * GSL_DBL_EPSILON * fabs(imag_sum); return GSL_SUCCESS; } /* Compute * * sum_{k=1}{infty} z^k / (k^2 (k+1)) * * This is a series which appears in the one-step accelerated * method, which splits out one elementary function from the * full definition of Li_2. */ static int series_2_c( double r, double x, double y, gsl_sf_result * sum_re, gsl_sf_result * sum_im ) { const double cos_theta = x/r; const double sin_theta = y/r; const double alpha = 1.0 - cos_theta; const double beta = sin_theta; double ck = cos_theta; double sk = sin_theta; double rk = r; double real_sum = 0.5 * r*ck; double imag_sum = 0.5 * r*sk; const int kmax = 30 + (int)(18.0/(-log(r))); /* tuned for double-precision */ int k; for(k=2; kval = real_sum; sum_re->err = 2.0 * kmax * GSL_DBL_EPSILON * fabs(real_sum); sum_im->val = imag_sum; sum_im->err = 2.0 * kmax * GSL_DBL_EPSILON * fabs(imag_sum); return GSL_SUCCESS; } /* Compute Li_2(z) using the one-step accelerated series. * * Li_2(z) = 1 + (1-z)ln(1-z)/z + series_2_c(z) * * z = r exp(i theta) * assumes: r < 1 * assumes: r > epsilon, so that we take no special care with log(1-z) */ static int dilogc_series_2( const double r, const double x, const double y, gsl_sf_result * real_dl, gsl_sf_result * imag_dl ) { if(r == 0.0) { real_dl->val = 0.0; imag_dl->val = 0.0; real_dl->err = 0.0; imag_dl->err = 0.0; return GSL_SUCCESS; } else { gsl_sf_result sum_re; gsl_sf_result sum_im; const int stat_s3 = series_2_c(r, x, y, &sum_re, &sum_im); /* t = ln(1-z)/z */ gsl_sf_result ln_omz_r; gsl_sf_result ln_omz_theta; const int stat_log = gsl_sf_complex_log_e(1.0-x, -y, &ln_omz_r, &ln_omz_theta); const double t_x = ( ln_omz_r.val * x + ln_omz_theta.val * y)/(r*r); const double t_y = (-ln_omz_r.val * y + ln_omz_theta.val * x)/(r*r); /* r = (1-z) ln(1-z)/z */ const double r_x = (1.0 - x) * t_x + y * t_y; const double r_y = (1.0 - x) * t_y - y * t_x; real_dl->val = sum_re.val + r_x + 1.0; imag_dl->val = sum_im.val + r_y; real_dl->err = sum_re.err + 2.0*GSL_DBL_EPSILON*(fabs(real_dl->val) + fabs(r_x)); imag_dl->err = sum_im.err + 2.0*GSL_DBL_EPSILON*(fabs(imag_dl->val) + fabs(r_y)); return GSL_ERROR_SELECT_2(stat_s3, stat_log); } } /* Evaluate a series for Li_2(z) when |z| is near 1. * This is uniformly good away from z=1. * * Li_2(z) = Sum[ a^n/n! H_n(theta), {n, 0, Infinity}] * * where * H_n(theta) = Sum[ e^(i m theta) m^n / m^2, {m, 1, Infinity}] * a = ln(r) * * H_0(t) = Gl_2(t) + i Cl_2(t) * H_1(t) = 1/2 ln(2(1-c)) + I atan2(-s, 1-c) * H_2(t) = -1/2 + I/2 s/(1-c) * H_3(t) = -1/2 /(1-c) * H_4(t) = -I/2 s/(1-c)^2 * H_5(t) = 1/2 (2 + c)/(1-c)^2 * H_6(t) = I/2 s/(1-c)^5 (8(1-c) - s^2 (3 + c)) */ static int dilogc_series_3( const double r, const double x, const double y, gsl_sf_result * real_result, gsl_sf_result * imag_result ) { const double theta = atan2(y, x); const double cos_theta = x/r; const double sin_theta = y/r; const double a = log(r); const double omc = 1.0 - cos_theta; const double omc2 = omc*omc; double H_re[7]; double H_im[7]; double an, nfact; double sum_re, sum_im; gsl_sf_result Him0; int n; H_re[0] = M_PI*M_PI/6.0 + 0.25*(theta*theta - 2.0*M_PI*fabs(theta)); gsl_sf_clausen_e(theta, &Him0); H_im[0] = Him0.val; H_re[1] = -0.5*log(2.0*omc); H_im[1] = -atan2(-sin_theta, omc); H_re[2] = -0.5; H_im[2] = 0.5 * sin_theta/omc; H_re[3] = -0.5/omc; H_im[3] = 0.0; H_re[4] = 0.0; H_im[4] = -0.5*sin_theta/omc2; H_re[5] = 0.5 * (2.0 + cos_theta)/omc2; H_im[5] = 0.0; H_re[6] = 0.0; H_im[6] = 0.5 * sin_theta/(omc2*omc2*omc) * (8.0*omc - sin_theta*sin_theta*(3.0 + cos_theta)); sum_re = H_re[0]; sum_im = H_im[0]; an = 1.0; nfact = 1.0; for(n=1; n<=6; n++) { double t; an *= a; nfact *= n; t = an/nfact; sum_re += t * H_re[n]; sum_im += t * H_im[n]; } real_result->val = sum_re; real_result->err = 2.0 * 6.0 * GSL_DBL_EPSILON * fabs(sum_re) + fabs(an/nfact); imag_result->val = sum_im; imag_result->err = 2.0 * 6.0 * GSL_DBL_EPSILON * fabs(sum_im) + Him0.err + fabs(an/nfact); return GSL_SUCCESS; } /* Calculate complex dilogarithm Li_2(z) in the fundamental region, * which we take to be the intersection of the unit disk with the * half-space x < MAGIC_SPLIT_VALUE. It turns out that 0.732 is a * nice choice for MAGIC_SPLIT_VALUE since then points mapped out * of the x > MAGIC_SPLIT_VALUE region and into another part of the * unit disk are bounded in radius by MAGIC_SPLIT_VALUE itself. * * If |z| < 0.98 we use a direct series summation. Otherwise z is very * near the unit circle, and the series_2 expansion is used; see above. * Because the fundamental region is bounded away from z = 1, this * works well. */ static int dilogc_fundamental(double r, double x, double y, gsl_sf_result * real_dl, gsl_sf_result * imag_dl) { if(r > 0.98) return dilogc_series_3(r, x, y, real_dl, imag_dl); else if(r > 0.25) return dilogc_series_2(r, x, y, real_dl, imag_dl); else return dilogc_series_1(r, x, y, real_dl, imag_dl); } /* Compute Li_2(z) for z in the unit disk, |z| < 1. If z is outside * the fundamental region, which means that it is too close to z = 1, * then it is reflected into the fundamental region using the identity * * Li2(z) = -Li2(1-z) + zeta(2) - ln(z) ln(1-z). */ static int dilogc_unitdisk(double x, double y, gsl_sf_result * real_dl, gsl_sf_result * imag_dl) { static const double MAGIC_SPLIT_VALUE = 0.732; static const double zeta2 = M_PI*M_PI/6.0; const double r = hypot(x, y); if(x > MAGIC_SPLIT_VALUE) { /* Reflect away from z = 1 if we are too close. The magic value * insures that the reflected value of the radius satisfies the * related inequality r_tmp < MAGIC_SPLIT_VALUE. */ const double x_tmp = 1.0 - x; const double y_tmp = - y; const double r_tmp = hypot(x_tmp, y_tmp); /* const double cos_theta_tmp = x_tmp/r_tmp; */ /* const double sin_theta_tmp = y_tmp/r_tmp; */ gsl_sf_result result_re_tmp; gsl_sf_result result_im_tmp; const int stat_dilog = dilogc_fundamental(r_tmp, x_tmp, y_tmp, &result_re_tmp, &result_im_tmp); const double lnz = log(r); /* log(|z|) */ const double lnomz = log(r_tmp); /* log(|1-z|) */ const double argz = atan2(y, x); /* arg(z) assuming principal branch */ const double argomz = atan2(y_tmp, x_tmp); /* arg(1-z) */ real_dl->val = -result_re_tmp.val + zeta2 - lnz*lnomz + argz*argomz; real_dl->err = result_re_tmp.err; real_dl->err += 2.0 * GSL_DBL_EPSILON * (zeta2 + fabs(lnz*lnomz) + fabs(argz*argomz)); imag_dl->val = -result_im_tmp.val - argz*lnomz - argomz*lnz; imag_dl->err = result_im_tmp.err; imag_dl->err += 2.0 * GSL_DBL_EPSILON * (fabs(argz*lnomz) + fabs(argomz*lnz)); return stat_dilog; } else { return dilogc_fundamental(r, x, y, real_dl, imag_dl); } } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_dilog_e(const double x, gsl_sf_result * result) { if(x >= 0.0) { return dilog_xge0(x, result); } else { gsl_sf_result d1, d2; int stat_d1 = dilog_xge0( -x, &d1); int stat_d2 = dilog_xge0(x*x, &d2); result->val = -d1.val + 0.5 * d2.val; result->err = d1.err + 0.5 * d2.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_d1, stat_d2); } } int gsl_sf_complex_dilog_xy_e( const double x, const double y, gsl_sf_result * real_dl, gsl_sf_result * imag_dl ) { const double zeta2 = M_PI*M_PI/6.0; const double r2 = x*x + y*y; if(y == 0.0) { if(x >= 1.0) { imag_dl->val = -M_PI * log(x); imag_dl->err = 2.0 * GSL_DBL_EPSILON * fabs(imag_dl->val); } else { imag_dl->val = 0.0; imag_dl->err = 0.0; } return gsl_sf_dilog_e(x, real_dl); } else if(fabs(r2 - 1.0) < GSL_DBL_EPSILON) { /* Lewin A.2.4.1 and A.2.4.2 */ const double theta = atan2(y, x); const double term1 = theta*theta/4.0; const double term2 = M_PI*fabs(theta)/2.0; real_dl->val = zeta2 + term1 - term2; real_dl->err = 2.0 * GSL_DBL_EPSILON * (zeta2 + term1 + term2); return gsl_sf_clausen_e(theta, imag_dl); } else if(r2 < 1.0) { return dilogc_unitdisk(x, y, real_dl, imag_dl); } else { /* Reduce argument to unit disk. */ const double r = sqrt(r2); const double x_tmp = x/r2; const double y_tmp = -y/r2; /* const double r_tmp = 1.0/r; */ gsl_sf_result result_re_tmp, result_im_tmp; const int stat_dilog = dilogc_unitdisk(x_tmp, y_tmp, &result_re_tmp, &result_im_tmp); /* Unwind the inversion. * * Li_2(z) + Li_2(1/z) = -zeta(2) - 1/2 ln(-z)^2 */ const double theta = atan2(y, x); const double theta_abs = fabs(theta); const double theta_sgn = ( theta < 0.0 ? -1.0 : 1.0 ); const double ln_minusz_re = log(r); const double ln_minusz_im = theta_sgn * (theta_abs - M_PI); const double lmz2_re = ln_minusz_re*ln_minusz_re - ln_minusz_im*ln_minusz_im; const double lmz2_im = 2.0*ln_minusz_re*ln_minusz_im; real_dl->val = -result_re_tmp.val - 0.5 * lmz2_re - zeta2; real_dl->err = result_re_tmp.err + 2.0*GSL_DBL_EPSILON*(0.5 * fabs(lmz2_re) + zeta2); imag_dl->val = -result_im_tmp.val - 0.5 * lmz2_im; imag_dl->err = result_im_tmp.err + 2.0*GSL_DBL_EPSILON*fabs(lmz2_im); return stat_dilog; } } int gsl_sf_complex_dilog_e( const double r, const double theta, gsl_sf_result * real_dl, gsl_sf_result * imag_dl ) { const double cos_theta = cos(theta); const double sin_theta = sin(theta); const double x = r * cos_theta; const double y = r * sin_theta; return gsl_sf_complex_dilog_xy_e(x, y, real_dl, imag_dl); } int gsl_sf_complex_spence_xy_e( const double x, const double y, gsl_sf_result * real_sp, gsl_sf_result * imag_sp ) { const double oms_x = 1.0 - x; const double oms_y = - y; return gsl_sf_complex_dilog_xy_e(oms_x, oms_y, real_sp, imag_sp); } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_dilog(const double x) { EVAL_RESULT(gsl_sf_dilog_e(x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__elementary.c000066400000000000000000000047001261542461700225330ustar00rootroot00000000000000/* specfunc/elementary.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_elementary.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__check.h" int gsl_sf_multiply_e(const double x, const double y, gsl_sf_result * result) { const double ax = fabs(x); const double ay = fabs(y); if(x == 0.0 || y == 0.0) { /* It is necessary to eliminate this immediately. */ result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if((ax <= 1.0 && ay >= 1.0) || (ay <= 1.0 && ax >= 1.0)) { /* Straddling 1.0 is always safe. */ result->val = x*y; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { const double f = 1.0 - 2.0 * GSL_DBL_EPSILON; const double min = GSL_MIN_DBL(fabs(x), fabs(y)); const double max = GSL_MAX_DBL(fabs(x), fabs(y)); if(max < 0.9 * GSL_SQRT_DBL_MAX || min < (f * DBL_MAX)/max) { result->val = GSL_COERCE_DBL(x*y); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); CHECK_UNDERFLOW(result); return GSL_SUCCESS; } else { OVERFLOW_ERROR(result); } } } int gsl_sf_multiply_err_e(const double x, const double dx, const double y, const double dy, gsl_sf_result * result) { int status = gsl_sf_multiply_e(x, y, result); result->err += fabs(dx*y) + fabs(dy*x); return status; } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_multiply(const double x, const double y) { EVAL_RESULT(gsl_sf_multiply_e(x, y, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__ellint.c000066400000000000000000000460101261542461700216550ustar00rootroot00000000000000/* specfunc/ellint.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_precision.h" #include "gsl_sf_ellint.h" #include "gsl_specfunc__error.h" /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/ inline static double locMAX3(double x, double y, double z) { double xy = GSL_MAX(x, y); return GSL_MAX(xy, z); } inline static double locMAX4(double x, double y, double z, double w) { double xy = GSL_MAX(x, y); double xyz = GSL_MAX(xy, z); return GSL_MAX(xyz, w); } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ /* based on Carlson's algorithms: [B. C. Carlson Numer. Math. 33, 1 (1979)] see also: [B.C. Carlson, Special Functions of Applied Mathematics (1977)] */ /* According to Carlson's algorithm, the errtol parameter typically effects the relative error in the following way: relative error < 16 errtol^6 / (1 - 2 errtol) errtol precision ------ ---------- 0.001 1.0e-17 0.003 2.0e-14 0.01 2.0e-11 0.03 2.0e-8 0.1 2.0e-5 */ int gsl_sf_ellint_RC_e(double x, double y, gsl_mode_t mode, gsl_sf_result * result) { const double lolim = 5.0 * GSL_DBL_MIN; const double uplim = 0.2 * GSL_DBL_MAX; const gsl_prec_t goal = GSL_MODE_PREC(mode); const double errtol = ( goal == GSL_PREC_DOUBLE ? 0.001 : 0.03 ); const double prec = gsl_prec_eps[goal]; if(x < 0.0 || y < 0.0 || x + y < lolim) { DOMAIN_ERROR(result); } else if(GSL_MAX(x, y) < uplim) { const double c1 = 1.0 / 7.0; const double c2 = 9.0 / 22.0; double xn = x; double yn = y; double mu, sn, lamda, s; while(1) { mu = (xn + yn + yn) / 3.0; sn = (yn + mu) / mu - 2.0; if (fabs(sn) < errtol) break; lamda = 2.0 * sqrt(xn) * sqrt(yn) + yn; xn = (xn + lamda) * 0.25; yn = (yn + lamda) * 0.25; } s = sn * sn * (0.3 + sn * (c1 + sn * (0.375 + sn * c2))); result->val = (1.0 + s) / sqrt(mu); result->err = prec * fabs(result->val); return GSL_SUCCESS; } else { DOMAIN_ERROR(result); } } int gsl_sf_ellint_RD_e(double x, double y, double z, gsl_mode_t mode, gsl_sf_result * result) { const gsl_prec_t goal = GSL_MODE_PREC(mode); const double errtol = ( goal == GSL_PREC_DOUBLE ? 0.001 : 0.03 ); const double prec = gsl_prec_eps[goal]; const double lolim = 2.0/pow(GSL_DBL_MAX, 2.0/3.0); const double uplim = pow(0.1*errtol/GSL_DBL_MIN, 2.0/3.0); if(GSL_MIN(x,y) < 0.0 || GSL_MIN(x+y,z) < lolim) { DOMAIN_ERROR(result); } else if(locMAX3(x,y,z) < uplim) { const double c1 = 3.0 / 14.0; const double c2 = 1.0 / 6.0; const double c3 = 9.0 / 22.0; const double c4 = 3.0 / 26.0; double xn = x; double yn = y; double zn = z; double sigma = 0.0; double power4 = 1.0; double ea, eb, ec, ed, ef, s1, s2; double mu, xndev, yndev, zndev; while(1) { double xnroot, ynroot, znroot, lamda; double epslon; mu = (xn + yn + 3.0 * zn) * 0.2; xndev = (mu - xn) / mu; yndev = (mu - yn) / mu; zndev = (mu - zn) / mu; epslon = locMAX3(fabs(xndev), fabs(yndev), fabs(zndev)); if (epslon < errtol) break; xnroot = sqrt(xn); ynroot = sqrt(yn); znroot = sqrt(zn); lamda = xnroot * (ynroot + znroot) + ynroot * znroot; sigma += power4 / (znroot * (zn + lamda)); power4 *= 0.25; xn = (xn + lamda) * 0.25; yn = (yn + lamda) * 0.25; zn = (zn + lamda) * 0.25; } ea = xndev * yndev; eb = zndev * zndev; ec = ea - eb; ed = ea - 6.0 * eb; ef = ed + ec + ec; s1 = ed * (- c1 + 0.25 * c3 * ed - 1.5 * c4 * zndev * ef); s2 = zndev * (c2 * ef + zndev * (- c3 * ec + zndev * c4 * ea)); result->val = 3.0 * sigma + power4 * (1.0 + s1 + s2) / (mu * sqrt(mu)); result->err = prec * fabs(result->val); return GSL_SUCCESS; } else { DOMAIN_ERROR(result); } } int gsl_sf_ellint_RF_e(double x, double y, double z, gsl_mode_t mode, gsl_sf_result * result) { const double lolim = 5.0 * GSL_DBL_MIN; const double uplim = 0.2 * GSL_DBL_MAX; const gsl_prec_t goal = GSL_MODE_PREC(mode); const double errtol = ( goal == GSL_PREC_DOUBLE ? 0.001 : 0.03 ); const double prec = gsl_prec_eps[goal]; if(x < 0.0 || y < 0.0 || z < 0.0) { DOMAIN_ERROR(result); } else if(x+y < lolim || x+z < lolim || y+z < lolim) { DOMAIN_ERROR(result); } else if(locMAX3(x,y,z) < uplim) { const double c1 = 1.0 / 24.0; const double c2 = 3.0 / 44.0; const double c3 = 1.0 / 14.0; double xn = x; double yn = y; double zn = z; double mu, xndev, yndev, zndev, e2, e3, s; while(1) { double epslon, lamda; double xnroot, ynroot, znroot; mu = (xn + yn + zn) / 3.0; xndev = 2.0 - (mu + xn) / mu; yndev = 2.0 - (mu + yn) / mu; zndev = 2.0 - (mu + zn) / mu; epslon = locMAX3(fabs(xndev), fabs(yndev), fabs(zndev)); if (epslon < errtol) break; xnroot = sqrt(xn); ynroot = sqrt(yn); znroot = sqrt(zn); lamda = xnroot * (ynroot + znroot) + ynroot * znroot; xn = (xn + lamda) * 0.25; yn = (yn + lamda) * 0.25; zn = (zn + lamda) * 0.25; } e2 = xndev * yndev - zndev * zndev; e3 = xndev * yndev * zndev; s = 1.0 + (c1 * e2 - 0.1 - c2 * e3) * e2 + c3 * e3; result->val = s / sqrt(mu); result->err = prec * fabs(result->val); return GSL_SUCCESS; } else { DOMAIN_ERROR(result); } } int gsl_sf_ellint_RJ_e(double x, double y, double z, double p, gsl_mode_t mode, gsl_sf_result * result) { const gsl_prec_t goal = GSL_MODE_PREC(mode); const double errtol = ( goal == GSL_PREC_DOUBLE ? 0.001 : 0.03 ); const double prec = gsl_prec_eps[goal]; const double lolim = pow(5.0 * GSL_DBL_MIN, 1.0/3.0); const double uplim = 0.3 * pow(0.2 * GSL_DBL_MAX, 1.0/3.0); if(x < 0.0 || y < 0.0 || z < 0.0) { DOMAIN_ERROR(result); } else if(x + y < lolim || x + z < lolim || y + z < lolim || p < lolim) { DOMAIN_ERROR(result); } else if(locMAX4(x,y,z,p) < uplim) { const double c1 = 3.0 / 14.0; const double c2 = 1.0 / 3.0; const double c3 = 3.0 / 22.0; const double c4 = 3.0 / 26.0; double xn = x; double yn = y; double zn = z; double pn = p; double sigma = 0.0; double power4 = 1.0; double mu, xndev, yndev, zndev, pndev; double ea, eb, ec, e2, e3, s1, s2, s3; while(1) { double xnroot, ynroot, znroot; double lamda, alfa, beta; double epslon; gsl_sf_result rcresult; int rcstatus; mu = (xn + yn + zn + pn + pn) * 0.2; xndev = (mu - xn) / mu; yndev = (mu - yn) / mu; zndev = (mu - zn) / mu; pndev = (mu - pn) / mu; epslon = locMAX4(fabs(xndev), fabs(yndev), fabs(zndev), fabs(pndev)); if(epslon < errtol) break; xnroot = sqrt(xn); ynroot = sqrt(yn); znroot = sqrt(zn); lamda = xnroot * (ynroot + znroot) + ynroot * znroot; alfa = pn * (xnroot + ynroot + znroot) + xnroot * ynroot * znroot; alfa = alfa * alfa; beta = pn * (pn + lamda) * (pn + lamda); rcstatus = gsl_sf_ellint_RC_e(alfa, beta, mode, &rcresult); if(rcstatus != GSL_SUCCESS) { result->val = 0.0; result->err = 0.0; return rcstatus; } sigma += power4 * rcresult.val; power4 *= 0.25; xn = (xn + lamda) * 0.25; yn = (yn + lamda) * 0.25; zn = (zn + lamda) * 0.25; pn = (pn + lamda) * 0.25; } ea = xndev * (yndev + zndev) + yndev * zndev; eb = xndev * yndev * zndev; ec = pndev * pndev; e2 = ea - 3.0 * ec; e3 = eb + 2.0 * pndev * (ea - ec); s1 = 1.0 + e2 * (- c1 + 0.75 * c3 * e2 - 1.5 * c4 * e3); s2 = eb * (0.5 * c2 + pndev * (- c3 - c3 + pndev * c4)); s3 = pndev * ea * (c2 - pndev * c3) - c2 * pndev * ec; result->val = 3.0 * sigma + power4 * (s1 + s2 + s3) / (mu * sqrt(mu)); result->err = prec * fabs(result->val); return GSL_SUCCESS; } else { DOMAIN_ERROR(result); } } /* [Carlson, Numer. Math. 33 (1979) 1, (4.1)] */ int gsl_sf_ellint_F_e(double phi, double k, gsl_mode_t mode, gsl_sf_result * result) { /* Angular reduction to -pi/2 < phi < pi/2 (we should really use an exact reduction but this will have to do for now) BJG */ double nc = floor(phi/M_PI + 0.5); double phi_red = phi - nc * M_PI; phi = phi_red; { double sin_phi = sin(phi); double sin2_phi = sin_phi*sin_phi; double x = 1.0 - sin2_phi; double y = 1.0 - k*k*sin2_phi; gsl_sf_result rf; int status = gsl_sf_ellint_RF_e(x, y, 1.0, mode, &rf); result->val = sin_phi * rf.val; result->err = GSL_DBL_EPSILON * fabs(result->val) + fabs(sin_phi*rf.err); if (nc == 0) { return status; } else { gsl_sf_result rk; /* add extra terms from periodicity */ const int rkstatus = gsl_sf_ellint_Kcomp_e(k, mode, &rk); result->val += 2*nc*rk.val; result->err += 2*fabs(nc)*rk.err; return GSL_ERROR_SELECT_2(status, rkstatus); } } } /* [Carlson, Numer. Math. 33 (1979) 1, (4.2)] */ int gsl_sf_ellint_E_e(double phi, double k, gsl_mode_t mode, gsl_sf_result * result) { /* Angular reduction to -pi/2 < phi < pi/2 (we should really use an exact reduction but this will have to do for now) BJG */ double nc = floor(phi/M_PI + 0.5); double phi_red = phi - nc * M_PI; phi = phi_red; { const double sin_phi = sin(phi); const double sin2_phi = sin_phi * sin_phi; const double x = 1.0 - sin2_phi; const double y = 1.0 - k*k*sin2_phi; if(x < GSL_DBL_EPSILON) { gsl_sf_result re; const int status = gsl_sf_ellint_Ecomp_e(k, mode, &re); /* could use A&S 17.4.14 to improve the value below */ result->val = 2*nc*re.val + GSL_SIGN(sin_phi) * re.val; result->err = 2*fabs(nc)*re.err + re.err; return status; } else { gsl_sf_result rf, rd; const double sin3_phi = sin2_phi * sin_phi; const int rfstatus = gsl_sf_ellint_RF_e(x, y, 1.0, mode, &rf); const int rdstatus = gsl_sf_ellint_RD_e(x, y, 1.0, mode, &rd); result->val = sin_phi * rf.val - k*k/3.0 * sin3_phi * rd.val; result->err = GSL_DBL_EPSILON * fabs(sin_phi * rf.val); result->err += fabs(sin_phi*rf.err); result->err += k*k/3.0 * GSL_DBL_EPSILON * fabs(sin3_phi * rd.val); result->err += k*k/3.0 * fabs(sin3_phi*rd.err); if (nc == 0) { return GSL_ERROR_SELECT_2(rfstatus, rdstatus); } else { gsl_sf_result re; /* add extra terms from periodicity */ const int restatus = gsl_sf_ellint_Ecomp_e(k, mode, &re); result->val += 2*nc*re.val; result->err += 2*fabs(nc)*re.err; return GSL_ERROR_SELECT_3(rfstatus, rdstatus, restatus); } } } } /* [Carlson, Numer. Math. 33 (1979) 1, (4.3)] */ int gsl_sf_ellint_P_e(double phi, double k, double n, gsl_mode_t mode, gsl_sf_result * result) { /* Angular reduction to -pi/2 < phi < pi/2 (we should really use an exact reduction but this will have to do for now) BJG */ double nc = floor(phi/M_PI + 0.5); double phi_red = phi - nc * M_PI; phi = phi_red; /* FIXME: need to handle the case of small x, as for E,F */ { const double sin_phi = sin(phi); const double sin2_phi = sin_phi * sin_phi; const double sin3_phi = sin2_phi * sin_phi; const double x = 1.0 - sin2_phi; const double y = 1.0 - k*k*sin2_phi; gsl_sf_result rf; gsl_sf_result rj; const int rfstatus = gsl_sf_ellint_RF_e(x, y, 1.0, mode, &rf); const int rjstatus = gsl_sf_ellint_RJ_e(x, y, 1.0, 1.0 + n*sin2_phi, mode, &rj); result->val = sin_phi * rf.val - n/3.0*sin3_phi * rj.val; result->err = GSL_DBL_EPSILON * fabs(sin_phi * rf.val); result->err += fabs(sin_phi * rf.err); result->err += n/3.0 * GSL_DBL_EPSILON * fabs(sin3_phi*rj.val); result->err += n/3.0 * fabs(sin3_phi*rj.err); if (nc == 0) { return GSL_ERROR_SELECT_2(rfstatus, rjstatus); } else { gsl_sf_result rp; /* add extra terms from periodicity */ const int rpstatus = gsl_sf_ellint_Pcomp_e(k, n, mode, &rp); result->val += 2*nc*rp.val; result->err += 2*fabs(nc)*rp.err; return GSL_ERROR_SELECT_3(rfstatus, rjstatus, rpstatus); } } } /* [Carlson, Numer. Math. 33 (1979) 1, (4.4)] */ int gsl_sf_ellint_D_e(double phi, double k, double n, gsl_mode_t mode, gsl_sf_result * result) { /* Angular reduction to -pi/2 < phi < pi/2 (we should really use an exact reduction but this will have to do for now) BJG */ double nc = floor(phi/M_PI + 0.5); double phi_red = phi - nc * M_PI; phi = phi_red; /* FIXME: need to handle the case of small x, as for E,F */ { const double sin_phi = sin(phi); const double sin2_phi = sin_phi * sin_phi; const double sin3_phi = sin2_phi * sin_phi; const double x = 1.0 - sin2_phi; const double y = 1.0 - k*k*sin2_phi; gsl_sf_result rd; const int status = gsl_sf_ellint_RD_e(x, y, 1.0, mode, &rd); result->val = sin3_phi/3.0 * rd.val; result->err = GSL_DBL_EPSILON * fabs(result->val) + fabs(sin3_phi/3.0 * rd.err); if (nc == 0) { return status; } else { gsl_sf_result rd; /* add extra terms from periodicity */ const int rdstatus = gsl_sf_ellint_Dcomp_e(k, mode, &rd); result->val += 2*nc*rd.val; result->err += 2*fabs(nc)*rd.err; return GSL_ERROR_SELECT_2(status, rdstatus); } } } int gsl_sf_ellint_Dcomp_e(double k, gsl_mode_t mode, gsl_sf_result * result) { if(k*k >= 1.0) { DOMAIN_ERROR(result); } else { const double y = 1.0 - k*k; /* FIXME: still need to handle k~=~1 */ gsl_sf_result rd; const int status = gsl_sf_ellint_RD_e(0.0, y, 1.0, mode, &rd); result->val = (1.0/3.0) * rd.val; result->err = GSL_DBL_EPSILON * fabs(result->val) + fabs(1.0/3.0 * rd.err); return status; } } /* [Carlson, Numer. Math. 33 (1979) 1, (4.5)] */ int gsl_sf_ellint_Kcomp_e(double k, gsl_mode_t mode, gsl_sf_result * result) { if(k*k >= 1.0) { DOMAIN_ERROR(result); } else if(k*k >= 1.0 - GSL_SQRT_DBL_EPSILON) { /* [Abramowitz+Stegun, 17.3.33] */ const double y = 1.0 - k*k; const double a[] = { 1.38629436112, 0.09666344259, 0.03590092383 }; const double b[] = { 0.5, 0.12498593597, 0.06880248576 }; const double ta = a[0] + y*(a[1] + y*a[2]); const double tb = -log(y) * (b[0] * y*(b[1] + y*b[2])); result->val = ta + tb; result->err = 2.0 * GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; } else { /* This was previously computed as, return gsl_sf_ellint_RF_e(0.0, 1.0 - k*k, 1.0, mode, result); but this underestimated the total error for small k, since the argument y=1-k^2 is not exact (there is an absolute error of GSL_DBL_EPSILON near y=0 due to cancellation in the subtraction). Taking the singular behavior of -log(y) above gives an error of 0.5*epsilon/y near y=0. (BJG) */ double y = 1.0 - k*k; int status = gsl_sf_ellint_RF_e(0.0, y, 1.0, mode, result); result->err += 0.5 * GSL_DBL_EPSILON / y; return status ; } } /* [Carlson, Numer. Math. 33 (1979) 1, (4.6)] */ int gsl_sf_ellint_Ecomp_e(double k, gsl_mode_t mode, gsl_sf_result * result) { if(k*k >= 1.0) { DOMAIN_ERROR(result); } else if(k*k >= 1.0 - GSL_SQRT_DBL_EPSILON) { /* [Abramowitz+Stegun, 17.3.36] */ const double y = 1.0 - k*k; const double a[] = { 0.44325141463, 0.06260601220, 0.04757383546 }; const double b[] = { 0.24998368310, 0.09200180037, 0.04069697526 }; const double ta = 1.0 + y*(a[0] + y*(a[1] + a[2]*y)); const double tb = -y*log(y) * (b[0] + y*(b[1] + b[2]*y)); result->val = ta + tb; result->err = 2.0 * GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; } else { gsl_sf_result rf; gsl_sf_result rd; const double y = 1.0 - k*k; const int rfstatus = gsl_sf_ellint_RF_e(0.0, y, 1.0, mode, &rf); const int rdstatus = gsl_sf_ellint_RD_e(0.0, y, 1.0, mode, &rd); result->val = rf.val - k*k/3.0 * rd.val; result->err = rf.err + k*k/3.0 * rd.err; return GSL_ERROR_SELECT_2(rfstatus, rdstatus); } } /* [Carlson, Numer. Math. 33 (1979) 1, (4.3) phi=pi/2] */ int gsl_sf_ellint_Pcomp_e(double k, double n, gsl_mode_t mode, gsl_sf_result * result) { if(k*k >= 1.0) { DOMAIN_ERROR(result); } /* FIXME: need to handle k ~=~ 1 cancellations */ else { gsl_sf_result rf; gsl_sf_result rj; const double y = 1.0 - k*k; const int rfstatus = gsl_sf_ellint_RF_e(0.0, y, 1.0, mode, &rf); const int rjstatus = gsl_sf_ellint_RJ_e(0.0, y, 1.0, 1.0 + n, mode, &rj); result->val = rf.val - (n/3.0) * rj.val; result->err = rf.err + fabs(n/3.0) * rj.err; return GSL_ERROR_SELECT_2(rfstatus, rjstatus); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_ellint_Kcomp(double k, gsl_mode_t mode) { EVAL_RESULT(gsl_sf_ellint_Kcomp_e(k, mode, &result)); } double gsl_sf_ellint_Ecomp(double k, gsl_mode_t mode) { EVAL_RESULT(gsl_sf_ellint_Ecomp_e(k, mode, &result)); } double gsl_sf_ellint_Pcomp(double k, double n, gsl_mode_t mode) { EVAL_RESULT(gsl_sf_ellint_Pcomp_e(k, n, mode, &result)); } double gsl_sf_ellint_Dcomp(double k, gsl_mode_t mode) { EVAL_RESULT(gsl_sf_ellint_Dcomp_e(k, mode, &result)); } double gsl_sf_ellint_F(double phi, double k, gsl_mode_t mode) { EVAL_RESULT(gsl_sf_ellint_F_e(phi, k, mode, &result)); } double gsl_sf_ellint_E(double phi, double k, gsl_mode_t mode) { EVAL_RESULT(gsl_sf_ellint_E_e(phi, k, mode, &result)); } double gsl_sf_ellint_P(double phi, double k, double n, gsl_mode_t mode) { EVAL_RESULT(gsl_sf_ellint_P_e(phi, k, n, mode, &result)); } double gsl_sf_ellint_D(double phi, double k, double n, gsl_mode_t mode) { EVAL_RESULT(gsl_sf_ellint_D_e(phi, k, n, mode, &result)); } double gsl_sf_ellint_RC(double x, double y, gsl_mode_t mode) { EVAL_RESULT(gsl_sf_ellint_RC_e(x, y, mode, &result)); } double gsl_sf_ellint_RD(double x, double y, double z, gsl_mode_t mode) { EVAL_RESULT(gsl_sf_ellint_RD_e(x, y, z, mode, &result)); } double gsl_sf_ellint_RF(double x, double y, double z, gsl_mode_t mode) { EVAL_RESULT(gsl_sf_ellint_RF_e(x, y, z, mode, &result)); } double gsl_sf_ellint_RJ(double x, double y, double z, double p, gsl_mode_t mode) { EVAL_RESULT(gsl_sf_ellint_RJ_e(x, y, z, p, mode, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__elljac.c000066400000000000000000000065451261542461700216310ustar00rootroot00000000000000/* specfunc/elljac.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_pow_int.h" #include "gsl_sf_elljac.h" /* GJ: See [Thompson, Atlas for Computing Mathematical Functions] */ /* BJG 2005-07: New algorithm based on Algorithm 5 from Numerische Mathematik 7, 78-90 (1965) "Numerical Calculation of Elliptic Integrals and Elliptic Functions" R. Bulirsch. Minor tweak is to avoid division by zero when sin(x u_l) = 0 by computing reflected values sn(K-u) cn(K-u) dn(K-u) and using transformation from Abramowitz & Stegun table 16.8 column "K-u"*/ int gsl_sf_elljac_e(double u, double m, double * sn, double * cn, double * dn) { if(fabs(m) > 1.0) { *sn = 0.0; *cn = 0.0; *dn = 0.0; GSL_ERROR ("|m| > 1.0", GSL_EDOM); } else if(fabs(m) < 2.0*GSL_DBL_EPSILON) { *sn = sin(u); *cn = cos(u); *dn = 1.0; return GSL_SUCCESS; } else if(fabs(m - 1.0) < 2.0*GSL_DBL_EPSILON) { *sn = tanh(u); *cn = 1.0/cosh(u); *dn = *cn; return GSL_SUCCESS; } else { int status = GSL_SUCCESS; const int N = 16; double mu[16]; double nu[16]; double c[16]; double d[16]; double sin_umu, cos_umu, t, r; int n = 0; mu[0] = 1.0; nu[0] = sqrt(1.0 - m); while( fabs(mu[n] - nu[n]) > 4.0 * GSL_DBL_EPSILON * fabs(mu[n]+nu[n])) { mu[n+1] = 0.5 * (mu[n] + nu[n]); nu[n+1] = sqrt(mu[n] * nu[n]); ++n; if(n >= N - 1) { status = GSL_EMAXITER; break; } } sin_umu = sin(u * mu[n]); cos_umu = cos(u * mu[n]); /* Since sin(u*mu(n)) can be zero we switch to computing sn(K-u), cn(K-u), dn(K-u) when |sin| < |cos| */ if (fabs(sin_umu) < fabs(cos_umu)) { t = sin_umu / cos_umu; c[n] = mu[n] * t; d[n] = 1.0; while(n > 0) { n--; c[n] = d[n+1] * c[n+1]; r = (c[n+1] * c[n+1]) / mu[n+1]; d[n] = (r + nu[n]) / (r + mu[n]); } *dn = sqrt(1.0-m) / d[n]; *cn = (*dn) * GSL_SIGN(cos_umu) / gsl_hypot(1.0, c[n]); *sn = (*cn) * c[n] /sqrt(1.0-m); } else { t = cos_umu / sin_umu; c[n] = mu[n] * t; d[n] = 1.0; while(n > 0) { --n; c[n] = d[n+1] * c[n+1]; r = (c[n+1] * c[n+1]) / mu[n+1]; d[n] = (r + nu[n]) / (r + mu[n]); } *dn = d[n]; *sn = GSL_SIGN(sin_umu) / gsl_hypot(1.0, c[n]); *cn = c[n] * (*sn); } return status; } } praat-6.0.04/external/gsl/gsl_specfunc__erfc.c000066400000000000000000000277611261542461700213210ustar00rootroot00000000000000/* specfunc/erfc.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: J. Theiler (modifications by G. Jungman) */ /* * See Hart et al, Computer Approximations, John Wiley and Sons, New York (1968) * (This applies only to the erfc8 stuff, which is the part * of the original code that survives. I have replaced much of * the other stuff with Chebyshev fits. These are simpler and * more precise than the original approximations. [GJ]) */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_exp.h" #include "gsl_sf_erf.h" #include "gsl_specfunc__check.h" #include "gsl_specfunc__chebyshev.h" #include "gsl_specfunc__cheb_eval.c" #define LogRootPi_ 0.57236494292470008706 static double erfc8_sum(double x) { /* estimates erfc(x) valid for 8 < x < 100 */ /* This is based on index 5725 in Hart et al */ static double P[] = { 2.97886562639399288862, 7.409740605964741794425, 6.1602098531096305440906, 5.019049726784267463450058, 1.275366644729965952479585264, 0.5641895835477550741253201704 }; static double Q[] = { 3.3690752069827527677, 9.608965327192787870698, 17.08144074746600431571095, 12.0489519278551290360340491, 9.396034016235054150430579648, 2.260528520767326969591866945, 1.0 }; double num=0.0, den=0.0; int i; num = P[5]; for (i=4; i>=0; --i) { num = x*num + P[i]; } den = Q[6]; for (i=5; i>=0; --i) { den = x*den + Q[i]; } return num/den; } inline static double erfc8(double x) { double e; e = erfc8_sum(x); e *= exp(-x*x); return e; } inline static double log_erfc8(double x) { double e; e = erfc8_sum(x); e = log(e) - x*x; return e; } #if 0 /* Abramowitz+Stegun, 7.2.14 */ static double erfcasympsum(double x) { int i; double e = 1.; double coef = 1.; for (i=1; i<5; ++i) { /* coef *= -(2*i-1)/(2*x*x); ??? [GJ] */ coef *= -(2*i+1)/(i*(4*x*x*x*x)); e += coef; /* if (fabs(coef) < 1.0e-15) break; if (fabs(coef) > 1.0e10) break; [GJ]: These tests are not useful. This function is only used below. Took them out; they gum up the pipeline. */ } return e; } #endif /* 0 */ /* Abramowitz+Stegun, 7.1.5 */ static int erfseries(double x, gsl_sf_result * result) { double coef = x; double e = coef; double del; int k; for (k=1; k<30; ++k) { coef *= -x*x/k; del = coef/(2.0*k+1.0); e += del; } result->val = 2.0 / M_SQRTPI * e; result->err = 2.0 / M_SQRTPI * (fabs(del) + GSL_DBL_EPSILON); return GSL_SUCCESS; } /* Chebyshev fit for erfc((t+1)/2), -1 < t < 1 */ static double erfc_xlt1_data[20] = { 1.06073416421769980345174155056, -0.42582445804381043569204735291, 0.04955262679620434040357683080, 0.00449293488768382749558001242, -0.00129194104658496953494224761, -0.00001836389292149396270416979, 0.00002211114704099526291538556, -5.23337485234257134673693179020e-7, -2.78184788833537885382530989578e-7, 1.41158092748813114560316684249e-8, 2.72571296330561699984539141865e-9, -2.06343904872070629406401492476e-10, -2.14273991996785367924201401812e-11, 2.22990255539358204580285098119e-12, 1.36250074650698280575807934155e-13, -1.95144010922293091898995913038e-14, -6.85627169231704599442806370690e-16, 1.44506492869699938239521607493e-16, 2.45935306460536488037576200030e-18, -9.29599561220523396007359328540e-19 }; static cheb_series erfc_xlt1_cs = { erfc_xlt1_data, 19, -1, 1, 12 }; /* Chebyshev fit for erfc(x) exp(x^2), 1 < x < 5, x = 2t + 3, -1 < t < 1 */ static double erfc_x15_data[25] = { 0.44045832024338111077637466616, -0.143958836762168335790826895326, 0.044786499817939267247056666937, -0.013343124200271211203618353102, 0.003824682739750469767692372556, -0.001058699227195126547306482530, 0.000283859419210073742736310108, -0.000073906170662206760483959432, 0.000018725312521489179015872934, -4.62530981164919445131297264430e-6, 1.11558657244432857487884006422e-6, -2.63098662650834130067808832725e-7, 6.07462122724551777372119408710e-8, -1.37460865539865444777251011793e-8, 3.05157051905475145520096717210e-9, -6.65174789720310713757307724790e-10, 1.42483346273207784489792999706e-10, -3.00141127395323902092018744545e-11, 6.22171792645348091472914001250e-12, -1.26994639225668496876152836555e-12, 2.55385883033257575402681845385e-13, -5.06258237507038698392265499770e-14, 9.89705409478327321641264227110e-15, -1.90685978789192181051961024995e-15, 3.50826648032737849245113757340e-16 }; static cheb_series erfc_x15_cs = { erfc_x15_data, 24, -1, 1, 16 }; /* Chebyshev fit for erfc(x) x exp(x^2), 5 < x < 10, x = (5t + 15)/2, -1 < t < 1 */ static double erfc_x510_data[20] = { 1.11684990123545698684297865808, 0.003736240359381998520654927536, -0.000916623948045470238763619870, 0.000199094325044940833965078819, -0.000040276384918650072591781859, 7.76515264697061049477127605790e-6, -1.44464794206689070402099225301e-6, 2.61311930343463958393485241947e-7, -4.61833026634844152345304095560e-8, 8.00253111512943601598732144340e-9, -1.36291114862793031395712122089e-9, 2.28570483090160869607683087722e-10, -3.78022521563251805044056974560e-11, 6.17253683874528285729910462130e-12, -9.96019290955316888445830597430e-13, 1.58953143706980770269506726000e-13, -2.51045971047162509999527428316e-14, 3.92607828989125810013581287560e-15, -6.07970619384160374392535453420e-16, 9.12600607264794717315507477670e-17 }; static cheb_series erfc_x510_cs = { erfc_x510_data, 19, -1, 1, 12 }; #if 0 inline static double erfc_asymptotic(double x) { return exp(-x*x)/x * erfcasympsum(x) / M_SQRTPI; } inline static double log_erfc_asymptotic(double x) { return log(erfcasympsum(x)/x) - x*x - LogRootPi_; } #endif /* 0 */ /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_erfc_e(double x, gsl_sf_result * result) { const double ax = fabs(x); double e_val, e_err; /* CHECK_POINTER(result) */ if(ax <= 1.0) { double t = 2.0*ax - 1.0; gsl_sf_result c; cheb_eval_e(&erfc_xlt1_cs, t, &c); e_val = c.val; e_err = c.err; } else if(ax <= 5.0) { double ex2 = exp(-x*x); double t = 0.5*(ax-3.0); gsl_sf_result c; cheb_eval_e(&erfc_x15_cs, t, &c); e_val = ex2 * c.val; e_err = ex2 * (c.err + 2.0*fabs(x)*GSL_DBL_EPSILON); } else if(ax < 10.0) { double exterm = exp(-x*x) / ax; double t = (2.0*ax - 15.0)/5.0; gsl_sf_result c; cheb_eval_e(&erfc_x510_cs, t, &c); e_val = exterm * c.val; e_err = exterm * (c.err + 2.0*fabs(x)*GSL_DBL_EPSILON + GSL_DBL_EPSILON); } else { e_val = erfc8(ax); e_err = (x*x + 1.0) * GSL_DBL_EPSILON * fabs(e_val); } if(x < 0.0) { result->val = 2.0 - e_val; result->err = e_err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); } else { result->val = e_val; result->err = e_err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); } return GSL_SUCCESS; } int gsl_sf_log_erfc_e(double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x*x < 10.0*GSL_ROOT6_DBL_EPSILON) { const double y = x / M_SQRTPI; /* series for -1/2 Log[Erfc[Sqrt[Pi] y]] */ const double c3 = (4.0 - M_PI)/3.0; const double c4 = 2.0*(1.0 - M_PI/3.0); const double c5 = -0.001829764677455021; /* (96.0 - 40.0*M_PI + 3.0*M_PI*M_PI)/30.0 */ const double c6 = 0.02629651521057465; /* 2.0*(120.0 - 60.0*M_PI + 7.0*M_PI*M_PI)/45.0 */ const double c7 = -0.01621575378835404; const double c8 = 0.00125993961762116; const double c9 = 0.00556964649138; const double c10 = -0.0045563339802; const double c11 = 0.0009461589032; const double c12 = 0.0013200243174; const double c13 = -0.00142906; const double c14 = 0.00048204; double series = c8 + y*(c9 + y*(c10 + y*(c11 + y*(c12 + y*(c13 + c14*y))))); series = y*(1.0 + y*(1.0 + y*(c3 + y*(c4 + y*(c5 + y*(c6 + y*(c7 + y*series))))))); result->val = -2.0 * series; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } /* don't like use of log1p(); added above series stuff for small x instead, should be ok [GJ] else if (fabs(x) < 1.0) { gsl_sf_result result_erf; gsl_sf_erf_e(x, &result_erf); result->val = log1p(-result_erf.val); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } */ else if(x > 8.0) { result->val = log_erfc8(x); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { gsl_sf_result result_erfc; gsl_sf_erfc_e(x, &result_erfc); result->val = log(result_erfc.val); result->err = fabs(result_erfc.err / result_erfc.val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_erf_e(double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(fabs(x) < 1.0) { return erfseries(x, result); } else { gsl_sf_result result_erfc; gsl_sf_erfc_e(x, &result_erfc); result->val = 1.0 - result_erfc.val; result->err = result_erfc.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_erf_Z_e(double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ { const double ex2 = exp(-x*x/2.0); result->val = ex2 / (M_SQRT2 * M_SQRTPI); result->err = fabs(x * result->val) * GSL_DBL_EPSILON; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); CHECK_UNDERFLOW(result); return GSL_SUCCESS; } } int gsl_sf_erf_Q_e(double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ { gsl_sf_result result_erfc; int stat = gsl_sf_erfc_e(x/M_SQRT2, &result_erfc); result->val = 0.5 * result_erfc.val; result->err = 0.5 * result_erfc.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat; } } int gsl_sf_hazard_e(double x, gsl_sf_result * result) { if(x < 25.0) { gsl_sf_result result_ln_erfc; const int stat_l = gsl_sf_log_erfc_e(x/M_SQRT2, &result_ln_erfc); const double lnc = -0.22579135264472743236; /* ln(sqrt(2/pi)) */ const double arg = lnc - 0.5*x*x - result_ln_erfc.val; const int stat_e = gsl_sf_exp_e(arg, result); result->err += 3.0 * (1.0 + fabs(x)) * GSL_DBL_EPSILON * fabs(result->val); result->err += fabs(result_ln_erfc.err * result->val); return GSL_ERROR_SELECT_2(stat_l, stat_e); } else { const double ix2 = 1.0/(x*x); const double corrB = 1.0 - 9.0*ix2 * (1.0 - 11.0*ix2); const double corrM = 1.0 - 5.0*ix2 * (1.0 - 7.0*ix2 * corrB); const double corrT = 1.0 - ix2 * (1.0 - 3.0*ix2*corrM); result->val = x / corrT; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_erfc(double x) { EVAL_RESULT(gsl_sf_erfc_e(x, &result)); } double gsl_sf_log_erfc(double x) { EVAL_RESULT(gsl_sf_log_erfc_e(x, &result)); } double gsl_sf_erf(double x) { EVAL_RESULT(gsl_sf_erf_e(x, &result)); } double gsl_sf_erf_Z(double x) { EVAL_RESULT(gsl_sf_erf_Z_e(x, &result)); } double gsl_sf_erf_Q(double x) { EVAL_RESULT(gsl_sf_erf_Q_e(x, &result)); } double gsl_sf_hazard(double x) { EVAL_RESULT(gsl_sf_hazard_e(x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__error.h000066400000000000000000000034351261542461700215300ustar00rootroot00000000000000#define OVERFLOW_ERROR(result) do { (result)->val = GSL_POSINF; (result)->err = GSL_POSINF; GSL_ERROR ("overflow", GSL_EOVRFLW); } while(0) #define UNDERFLOW_ERROR(result) do { (result)->val = 0.0; (result)->err = GSL_DBL_MIN; GSL_ERROR ("underflow", GSL_EUNDRFLW); } while(0) #define INTERNAL_OVERFLOW_ERROR(result) do { (result)->val = GSL_POSINF; (result)->err = GSL_POSINF; return GSL_EOVRFLW; } while(0) #define INTERNAL_UNDERFLOW_ERROR(result) do { (result)->val = 0.0; (result)->err = GSL_DBL_MIN; return GSL_EUNDRFLW; } while(0) #define DOMAIN_ERROR(result) do { (result)->val = GSL_NAN; (result)->err = GSL_NAN; GSL_ERROR ("domain error", GSL_EDOM); } while(0) #define DOMAIN_ERROR_MSG(msg, result) do { (result)->val = GSL_NAN; (result)->err = GSL_NAN; GSL_ERROR ((msg), GSL_EDOM); } while(0) #define DOMAIN_ERROR_E10(result) do { (result)->val = GSL_NAN; (result)->err = GSL_NAN; (result)->e10 = 0 ; GSL_ERROR ("domain error", GSL_EDOM); } while(0) #define OVERFLOW_ERROR_E10(result) do { (result)->val = GSL_POSINF; (result)->err = GSL_POSINF; (result)->e10 = 0; GSL_ERROR ("overflow", GSL_EOVRFLW); } while(0) #define UNDERFLOW_ERROR_E10(result) do { (result)->val = 0.0; (result)->err = GSL_DBL_MIN; (result)->e10 = 0; GSL_ERROR ("underflow", GSL_EUNDRFLW); } while(0) #define OVERFLOW_ERROR_2(r1,r2) do { (r1)->val = GSL_POSINF; (r1)->err = GSL_POSINF; (r2)->val = GSL_POSINF ; (r2)->err=GSL_POSINF; GSL_ERROR ("overflow", GSL_EOVRFLW); } while(0) #define UNDERFLOW_ERROR_2(r1,r2) do { (r1)->val = 0.0; (r1)->err = GSL_DBL_MIN; (r2)->val = 0.0 ; (r2)->err = GSL_DBL_MIN; GSL_ERROR ("underflow", GSL_EUNDRFLW); } while(0) #define DOMAIN_ERROR_2(r1,r2) do { (r1)->val = GSL_NAN; (r1)->err = GSL_NAN; (r2)->val = GSL_NAN; (r2)->err = GSL_NAN; GSL_ERROR ("domain error", GSL_EDOM); } while(0) praat-6.0.04/external/gsl/gsl_specfunc__eval.h000066400000000000000000000006401261542461700213210ustar00rootroot00000000000000/* evaluate a function discarding the status value in a modifiable way */ #define EVAL_RESULT(fn) \ gsl_sf_result result; \ int status = fn; \ if (status != GSL_SUCCESS) { \ GSL_ERROR_VAL(#fn, status, result.val); \ } ; \ return result.val; #define EVAL_DOUBLE(fn) \ int status = fn; \ if (status != GSL_SUCCESS) { \ GSL_ERROR_VAL(#fn, status, result); \ } ; \ return result; praat-6.0.04/external/gsl/gsl_specfunc__exp.c000066400000000000000000000367421261542461700211750ustar00rootroot00000000000000/* specfunc/exp.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_gamma.h" #include "gsl_sf_exp.h" #include "gsl_specfunc__error.h" /* Evaluate the continued fraction for exprel. * [Abramowitz+Stegun, 4.2.41] */ static int exprel_n_CF(const int N, const double x, gsl_sf_result * result) { const double RECUR_BIG = GSL_SQRT_DBL_MAX; const int maxiter = 5000; int n = 1; double Anm2 = 1.0; double Bnm2 = 0.0; double Anm1 = 0.0; double Bnm1 = 1.0; double a1 = 1.0; double b1 = 1.0; double a2 = -x; double b2 = N+1; double an, bn; double fn; double An = b1*Anm1 + a1*Anm2; /* A1 */ double Bn = b1*Bnm1 + a1*Bnm2; /* B1 */ /* One explicit step, before we get to the main pattern. */ n++; Anm2 = Anm1; Bnm2 = Bnm1; Anm1 = An; Bnm1 = Bn; An = b2*Anm1 + a2*Anm2; /* A2 */ Bn = b2*Bnm1 + a2*Bnm2; /* B2 */ fn = An/Bn; while(n < maxiter) { double old_fn; double del; n++; Anm2 = Anm1; Bnm2 = Bnm1; Anm1 = An; Bnm1 = Bn; an = ( GSL_IS_ODD(n) ? ((n-1)/2)*x : -(N+(n/2)-1)*x ); bn = N + n - 1; An = bn*Anm1 + an*Anm2; Bn = bn*Bnm1 + an*Bnm2; if(fabs(An) > RECUR_BIG || fabs(Bn) > RECUR_BIG) { An /= RECUR_BIG; Bn /= RECUR_BIG; Anm1 /= RECUR_BIG; Bnm1 /= RECUR_BIG; Anm2 /= RECUR_BIG; Bnm2 /= RECUR_BIG; } old_fn = fn; fn = An/Bn; del = old_fn/fn; if(fabs(del - 1.0) < 2.0*GSL_DBL_EPSILON) break; } result->val = fn; result->err = 2.0*(n+1.0)*GSL_DBL_EPSILON*fabs(fn); if(n == maxiter) GSL_ERROR ("error", GSL_EMAXITER); else return GSL_SUCCESS; } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_exp_e(const double x, gsl_sf_result * result) { if(x > GSL_LOG_DBL_MAX) { OVERFLOW_ERROR(result); } else if(x < GSL_LOG_DBL_MIN) { UNDERFLOW_ERROR(result); } else { result->val = exp(x); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_exp_e10_e(const double x, gsl_sf_result_e10 * result) { if(x > INT_MAX-1) { OVERFLOW_ERROR_E10(result); } else if(x < INT_MIN+1) { UNDERFLOW_ERROR_E10(result); } else { const int N = (int) floor(x/M_LN10); result->val = exp(x-N*M_LN10); result->err = 2.0 * (fabs(x)+1.0) * GSL_DBL_EPSILON * fabs(result->val); result->e10 = N; return GSL_SUCCESS; } } int gsl_sf_exp_mult_e(const double x, const double y, gsl_sf_result * result) { const double ay = fabs(y); if(y == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if( ( x < 0.5*GSL_LOG_DBL_MAX && x > 0.5*GSL_LOG_DBL_MIN) && (ay < 0.8*GSL_SQRT_DBL_MAX && ay > 1.2*GSL_SQRT_DBL_MIN) ) { const double ex = exp(x); result->val = y * ex; result->err = (2.0 + fabs(x)) * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { const double ly = log(ay); const double lnr = x + ly; if(lnr > GSL_LOG_DBL_MAX - 0.01) { OVERFLOW_ERROR(result); } else if(lnr < GSL_LOG_DBL_MIN + 0.01) { UNDERFLOW_ERROR(result); } else { const double sy = GSL_SIGN(y); const double M = floor(x); const double N = floor(ly); const double a = x - M; const double b = ly - N; const double berr = 2.0 * GSL_DBL_EPSILON * (fabs(ly) + fabs(N)); result->val = sy * exp(M+N) * exp(a+b); result->err = berr * fabs(result->val); result->err += 2.0 * GSL_DBL_EPSILON * (M + N + 1.0) * fabs(result->val); return GSL_SUCCESS; } } } int gsl_sf_exp_mult_e10_e(const double x, const double y, gsl_sf_result_e10 * result) { const double ay = fabs(y); if(y == 0.0) { result->val = 0.0; result->err = 0.0; result->e10 = 0; return GSL_SUCCESS; } else if( ( x < 0.5*GSL_LOG_DBL_MAX && x > 0.5*GSL_LOG_DBL_MIN) && (ay < 0.8*GSL_SQRT_DBL_MAX && ay > 1.2*GSL_SQRT_DBL_MIN) ) { const double ex = exp(x); result->val = y * ex; result->err = (2.0 + fabs(x)) * GSL_DBL_EPSILON * fabs(result->val); result->e10 = 0; return GSL_SUCCESS; } else { const double ly = log(ay); const double l10_val = (x + ly)/M_LN10; if(l10_val > INT_MAX-1) { OVERFLOW_ERROR_E10(result); } else if(l10_val < INT_MIN+1) { UNDERFLOW_ERROR_E10(result); } else { const double sy = GSL_SIGN(y); const int N = (int) floor(l10_val); const double arg_val = (l10_val - N) * M_LN10; const double arg_err = 2.0 * GSL_DBL_EPSILON * fabs(ly); result->val = sy * exp(arg_val); result->err = arg_err * fabs(result->val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); result->e10 = N; return GSL_SUCCESS; } } } int gsl_sf_exp_mult_err_e(const double x, const double dx, const double y, const double dy, gsl_sf_result * result) { const double ay = fabs(y); if(y == 0.0) { result->val = 0.0; result->err = fabs(dy * exp(x)); return GSL_SUCCESS; } else if( ( x < 0.5*GSL_LOG_DBL_MAX && x > 0.5*GSL_LOG_DBL_MIN) && (ay < 0.8*GSL_SQRT_DBL_MAX && ay > 1.2*GSL_SQRT_DBL_MIN) ) { double ex = exp(x); result->val = y * ex; result->err = ex * (fabs(dy) + fabs(y*dx)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { const double ly = log(ay); const double lnr = x + ly; if(lnr > GSL_LOG_DBL_MAX - 0.01) { OVERFLOW_ERROR(result); } else if(lnr < GSL_LOG_DBL_MIN + 0.01) { UNDERFLOW_ERROR(result); } else { const double sy = GSL_SIGN(y); const double M = floor(x); const double N = floor(ly); const double a = x - M; const double b = ly - N; const double eMN = exp(M+N); const double eab = exp(a+b); result->val = sy * eMN * eab; result->err = eMN * eab * 2.0*GSL_DBL_EPSILON; result->err += eMN * eab * fabs(dy/y); result->err += eMN * eab * fabs(dx); return GSL_SUCCESS; } } } int gsl_sf_exp_mult_err_e10_e(const double x, const double dx, const double y, const double dy, gsl_sf_result_e10 * result) { const double ay = fabs(y); if(y == 0.0) { result->val = 0.0; result->err = fabs(dy * exp(x)); result->e10 = 0; return GSL_SUCCESS; } else if( ( x < 0.5*GSL_LOG_DBL_MAX && x > 0.5*GSL_LOG_DBL_MIN) && (ay < 0.8*GSL_SQRT_DBL_MAX && ay > 1.2*GSL_SQRT_DBL_MIN) ) { const double ex = exp(x); result->val = y * ex; result->err = ex * (fabs(dy) + fabs(y*dx)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); result->e10 = 0; return GSL_SUCCESS; } else { const double ly = log(ay); const double l10_val = (x + ly)/M_LN10; if(l10_val > INT_MAX-1) { OVERFLOW_ERROR_E10(result); } else if(l10_val < INT_MIN+1) { UNDERFLOW_ERROR_E10(result); } else { const double sy = GSL_SIGN(y); const int N = (int) floor(l10_val); const double arg_val = (l10_val - N) * M_LN10; const double arg_err = dy/fabs(y) + dx + 2.0*GSL_DBL_EPSILON*fabs(arg_val); result->val = sy * exp(arg_val); result->err = arg_err * fabs(result->val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); result->e10 = N; return GSL_SUCCESS; } } } int gsl_sf_expm1_e(const double x, gsl_sf_result * result) { const double cut = 0.002; if(x < GSL_LOG_DBL_MIN) { result->val = -1.0; result->err = GSL_DBL_EPSILON; return GSL_SUCCESS; } else if(x < -cut) { result->val = exp(x) - 1.0; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < cut) { result->val = x * (1.0 + 0.5*x*(1.0 + x/3.0*(1.0 + 0.25*x*(1.0 + 0.2*x)))); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < GSL_LOG_DBL_MAX) { result->val = exp(x) - 1.0; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { OVERFLOW_ERROR(result); } } int gsl_sf_exprel_e(const double x, gsl_sf_result * result) { const double cut = 0.002; if(x < GSL_LOG_DBL_MIN) { result->val = -1.0/x; result->err = GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < -cut) { result->val = (exp(x) - 1.0)/x; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < cut) { result->val = (1.0 + 0.5*x*(1.0 + x/3.0*(1.0 + 0.25*x*(1.0 + 0.2*x)))); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < GSL_LOG_DBL_MAX) { result->val = (exp(x) - 1.0)/x; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { OVERFLOW_ERROR(result); } } int gsl_sf_exprel_2_e(double x, gsl_sf_result * result) { const double cut = 0.002; if(x < GSL_LOG_DBL_MIN) { result->val = -2.0/x*(1.0 + 1.0/x); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < -cut) { result->val = 2.0*(exp(x) - 1.0 - x)/(x*x); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < cut) { result->val = (1.0 + 1.0/3.0*x*(1.0 + 0.25*x*(1.0 + 0.2*x*(1.0 + 1.0/6.0*x)))); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < GSL_LOG_DBL_MAX) { result->val = 2.0*(exp(x) - 1.0 - x)/(x*x); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { OVERFLOW_ERROR(result); } } int gsl_sf_exprel_n_e(const int N, const double x, gsl_sf_result * result) { if(N < 0) { DOMAIN_ERROR(result); } else if(x == 0.0) { result->val = 1.0; result->err = 0.0; return GSL_SUCCESS; } else if(fabs(x) < GSL_ROOT3_DBL_EPSILON * N) { result->val = 1.0 + x/(N+1) * (1.0 + x/(N+2)); result->err = 2.0 * GSL_DBL_EPSILON; return GSL_SUCCESS; } else if(N == 0) { return gsl_sf_exp_e(x, result); } else if(N == 1) { return gsl_sf_exprel_e(x, result); } else if(N == 2) { return gsl_sf_exprel_2_e(x, result); } else { if(x > N && (-x + N*(1.0 + log(x/N)) < GSL_LOG_DBL_EPSILON)) { /* x is much larger than n. * Ignore polynomial part, so * exprel_N(x) ~= e^x N!/x^N */ gsl_sf_result lnf_N; double lnr_val; double lnr_err; double lnterm; gsl_sf_lnfact_e(N, &lnf_N); lnterm = N*log(x); lnr_val = x + lnf_N.val - lnterm; lnr_err = GSL_DBL_EPSILON * (fabs(x) + fabs(lnf_N.val) + fabs(lnterm)); lnr_err += lnf_N.err; return gsl_sf_exp_err_e(lnr_val, lnr_err, result); } else if(x > N) { /* Write the identity * exprel_n(x) = e^x n! / x^n (1 - Gamma[n,x]/Gamma[n]) * then use the asymptotic expansion * Gamma[n,x] ~ x^(n-1) e^(-x) (1 + (n-1)/x + (n-1)(n-2)/x^2 + ...) */ double ln_x = log(x); gsl_sf_result lnf_N; double lg_N; double lnpre_val; double lnpre_err; gsl_sf_lnfact_e(N, &lnf_N); /* log(N!) */ lg_N = lnf_N.val - log(N); /* log(Gamma(N)) */ lnpre_val = x + lnf_N.val - N*ln_x; lnpre_err = GSL_DBL_EPSILON * (fabs(x) + fabs(lnf_N.val) + fabs(N*ln_x)); lnpre_err += lnf_N.err; if(lnpre_val < GSL_LOG_DBL_MAX - 5.0) { int stat_eG; gsl_sf_result bigG_ratio; gsl_sf_result pre; int stat_ex = gsl_sf_exp_err_e(lnpre_val, lnpre_err, &pre); double ln_bigG_ratio_pre = -x + (N-1)*ln_x - lg_N; double bigGsum = 1.0; double term = 1.0; int k; for(k=1; kval = pre.val * (1.0 - bigG_ratio.val); result->err = pre.val * (2.0*GSL_DBL_EPSILON + bigG_ratio.err); result->err += pre.err * fabs(1.0 - bigG_ratio.val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_ex; } else { result->val = 0.0; result->err = 0.0; return stat_eG; } } else { OVERFLOW_ERROR(result); } } else if(x > -10.0*N) { return exprel_n_CF(N, x, result); } else { /* x -> -Inf asymptotic: * exprel_n(x) ~ e^x n!/x^n - n/x (1 + (n-1)/x + (n-1)(n-2)/x + ...) * ~ - n/x (1 + (n-1)/x + (n-1)(n-2)/x + ...) */ double sum = 1.0; double term = 1.0; int k; for(k=1; kval = -N/x * sum; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } } int gsl_sf_exp_err_e(const double x, const double dx, gsl_sf_result * result) { const double adx = fabs(dx); /* CHECK_POINTER(result) */ if(x + adx > GSL_LOG_DBL_MAX) { OVERFLOW_ERROR(result); } else if(x - adx < GSL_LOG_DBL_MIN) { UNDERFLOW_ERROR(result); } else { const double ex = exp(x); const double edx = exp(adx); result->val = ex; result->err = ex * GSL_MAX_DBL(GSL_DBL_EPSILON, edx - 1.0/edx); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_exp_err_e10_e(const double x, const double dx, gsl_sf_result_e10 * result) { const double adx = fabs(dx); /* CHECK_POINTER(result) */ if(x + adx > INT_MAX - 1) { OVERFLOW_ERROR_E10(result); } else if(x - adx < INT_MIN + 1) { UNDERFLOW_ERROR_E10(result); } else { const int N = (int)floor(x/M_LN10); const double ex = exp(x-N*M_LN10); result->val = ex; result->err = ex * (2.0 * GSL_DBL_EPSILON * (fabs(x) + 1.0) + adx); result->e10 = N; return GSL_SUCCESS; } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_exp(const double x) { EVAL_RESULT(gsl_sf_exp_e(x, &result)); } double gsl_sf_exp_mult(const double x, const double y) { EVAL_RESULT(gsl_sf_exp_mult_e(x, y, &result)); } double gsl_sf_expm1(const double x) { EVAL_RESULT(gsl_sf_expm1_e(x, &result)); } double gsl_sf_exprel(const double x) { EVAL_RESULT(gsl_sf_exprel_e(x, &result)); } double gsl_sf_exprel_2(const double x) { EVAL_RESULT(gsl_sf_exprel_2_e(x, &result)); } double gsl_sf_exprel_n(const int n, const double x) { EVAL_RESULT(gsl_sf_exprel_n_e(n, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__expint.c000066400000000000000000000367261261542461700217120ustar00rootroot00000000000000/* specfunc/expint.c * * Copyright (C) 2007 Brian Gough * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_expint.h" #include "gsl_sf_gamma.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__check.h" #include "gsl_specfunc__chebyshev.h" #include "gsl_specfunc__cheb_eval.c" /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/ /* Chebyshev expansions: based on SLATEC e1.f, W. Fullerton Series for AE11 on the interval -1.00000D-01 to 0. with weighted error 1.76E-17 log weighted error 16.75 significant figures required 15.70 decimal places required 17.55 Series for AE12 on the interval -2.50000D-01 to -1.00000D-01 with weighted error 5.83E-17 log weighted error 16.23 significant figures required 15.76 decimal places required 16.93 Series for E11 on the interval -4.00000D+00 to -1.00000D+00 with weighted error 1.08E-18 log weighted error 17.97 significant figures required 19.02 decimal places required 18.61 Series for E12 on the interval -1.00000D+00 to 1.00000D+00 with weighted error 3.15E-18 log weighted error 17.50 approx significant figures required 15.8 decimal places required 18.10 Series for AE13 on the interval 2.50000D-01 to 1.00000D+00 with weighted error 2.34E-17 log weighted error 16.63 significant figures required 16.14 decimal places required 17.33 Series for AE14 on the interval 0. to 2.50000D-01 with weighted error 5.41E-17 log weighted error 16.27 significant figures required 15.38 decimal places required 16.97 */ static double AE11_data[39] = { 0.121503239716065790, -0.065088778513550150, 0.004897651357459670, -0.000649237843027216, 0.000093840434587471, 0.000000420236380882, -0.000008113374735904, 0.000002804247688663, 0.000000056487164441, -0.000000344809174450, 0.000000058209273578, 0.000000038711426349, -0.000000012453235014, -0.000000005118504888, 0.000000002148771527, 0.000000000868459898, -0.000000000343650105, -0.000000000179796603, 0.000000000047442060, 0.000000000040423282, -0.000000000003543928, -0.000000000008853444, -0.000000000000960151, 0.000000000001692921, 0.000000000000607990, -0.000000000000224338, -0.000000000000200327, -0.000000000000006246, 0.000000000000045571, 0.000000000000016383, -0.000000000000005561, -0.000000000000006074, -0.000000000000000862, 0.000000000000001223, 0.000000000000000716, -0.000000000000000024, -0.000000000000000201, -0.000000000000000082, 0.000000000000000017 }; static cheb_series AE11_cs = { AE11_data, 38, -1, 1, 20 }; static double AE12_data[25] = { 0.582417495134726740, -0.158348850905782750, -0.006764275590323141, 0.005125843950185725, 0.000435232492169391, -0.000143613366305483, -0.000041801320556301, -0.000002713395758640, 0.000001151381913647, 0.000000420650022012, 0.000000066581901391, 0.000000000662143777, -0.000000002844104870, -0.000000000940724197, -0.000000000177476602, -0.000000000015830222, 0.000000000002905732, 0.000000000001769356, 0.000000000000492735, 0.000000000000093709, 0.000000000000010707, -0.000000000000000537, -0.000000000000000716, -0.000000000000000244, -0.000000000000000058 }; static cheb_series AE12_cs = { AE12_data, 24, -1, 1, 15 }; static double E11_data[19] = { -16.11346165557149402600, 7.79407277874268027690, -1.95540581886314195070, 0.37337293866277945612, -0.05692503191092901938, 0.00721107776966009185, -0.00078104901449841593, 0.00007388093356262168, -0.00000620286187580820, 0.00000046816002303176, -0.00000003209288853329, 0.00000000201519974874, -0.00000000011673686816, 0.00000000000627627066, -0.00000000000031481541, 0.00000000000001479904, -0.00000000000000065457, 0.00000000000000002733, -0.00000000000000000108 }; static cheb_series E11_cs = { E11_data, 18, -1, 1, 13 }; static double E12_data[16] = { -0.03739021479220279500, 0.04272398606220957700, -0.13031820798497005440, 0.01441912402469889073, -0.00134617078051068022, 0.00010731029253063780, -0.00000742999951611943, 0.00000045377325690753, -0.00000002476417211390, 0.00000000122076581374, -0.00000000005485141480, 0.00000000000226362142, -0.00000000000008635897, 0.00000000000000306291, -0.00000000000000010148, 0.00000000000000000315 }; static cheb_series E12_cs = { E12_data, 15, -1, 1, 10 }; static double AE13_data[25] = { -0.605773246640603460, -0.112535243483660900, 0.013432266247902779, -0.001926845187381145, 0.000309118337720603, -0.000053564132129618, 0.000009827812880247, -0.000001885368984916, 0.000000374943193568, -0.000000076823455870, 0.000000016143270567, -0.000000003466802211, 0.000000000758754209, -0.000000000168864333, 0.000000000038145706, -0.000000000008733026, 0.000000000002023672, -0.000000000000474132, 0.000000000000112211, -0.000000000000026804, 0.000000000000006457, -0.000000000000001568, 0.000000000000000383, -0.000000000000000094, 0.000000000000000023 }; static cheb_series AE13_cs = { AE13_data, 24, -1, 1, 15 }; static double AE14_data[26] = { -0.18929180007530170, -0.08648117855259871, 0.00722410154374659, -0.00080975594575573, 0.00010999134432661, -0.00001717332998937, 0.00000298562751447, -0.00000056596491457, 0.00000011526808397, -0.00000002495030440, 0.00000000569232420, -0.00000000135995766, 0.00000000033846628, -0.00000000008737853, 0.00000000002331588, -0.00000000000641148, 0.00000000000181224, -0.00000000000052538, 0.00000000000015592, -0.00000000000004729, 0.00000000000001463, -0.00000000000000461, 0.00000000000000148, -0.00000000000000048, 0.00000000000000016, -0.00000000000000005 }; static cheb_series AE14_cs = { AE14_data, 25, -1, 1, 13 }; /* implementation for E1, allowing for scaling by exp(x) */ static int expint_E1_impl(const double x, gsl_sf_result * result, const int scale) { const double xmaxt = -GSL_LOG_DBL_MIN; /* XMAXT = -LOG (R1MACH(1)) */ const double xmax = xmaxt - log(xmaxt); /* XMAX = XMAXT - LOG(XMAXT) */ /* CHECK_POINTER(result) */ if(x < -xmax && !scale) { OVERFLOW_ERROR(result); } else if(x <= -10.0) { const double s = 1.0/x * ( scale ? 1.0 : exp(-x) ); gsl_sf_result result_c; cheb_eval_e(&AE11_cs, 20.0/x+1.0, &result_c); result->val = s * (1.0 + result_c.val); result->err = s * result_c.err; result->err += 2.0 * GSL_DBL_EPSILON * (fabs(x) + 1.0) * fabs(result->val); return GSL_SUCCESS; } else if(x <= -4.0) { const double s = 1.0/x * ( scale ? 1.0 : exp(-x) ); gsl_sf_result result_c; cheb_eval_e(&AE12_cs, (40.0/x+7.0)/3.0, &result_c); result->val = s * (1.0 + result_c.val); result->err = s * result_c.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x <= -1.0) { const double ln_term = -log(fabs(x)); const double scale_factor = ( scale ? exp(x) : 1.0 ); gsl_sf_result result_c; cheb_eval_e(&E11_cs, (2.0*x+5.0)/3.0, &result_c); result->val = scale_factor * (ln_term + result_c.val); result->err = scale_factor * (result_c.err + GSL_DBL_EPSILON * fabs(ln_term)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x == 0.0) { DOMAIN_ERROR(result); } else if(x <= 1.0) { const double ln_term = -log(fabs(x)); const double scale_factor = ( scale ? exp(x) : 1.0 ); gsl_sf_result result_c; cheb_eval_e(&E12_cs, x, &result_c); result->val = scale_factor * (ln_term - 0.6875 + x + result_c.val); result->err = scale_factor * (result_c.err + GSL_DBL_EPSILON * fabs(ln_term)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x <= 4.0) { const double s = 1.0/x * ( scale ? 1.0 : exp(-x) ); gsl_sf_result result_c; cheb_eval_e(&AE13_cs, (8.0/x-5.0)/3.0, &result_c); result->val = s * (1.0 + result_c.val); result->err = s * result_c.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x <= xmax || scale) { const double s = 1.0/x * ( scale ? 1.0 : exp(-x) ); gsl_sf_result result_c; cheb_eval_e(&AE14_cs, 8.0/x-1.0, &result_c); result->val = s * (1.0 + result_c.val); result->err = s * (GSL_DBL_EPSILON + result_c.err); result->err += 2.0 * (x + 1.0) * GSL_DBL_EPSILON * fabs(result->val); if(result->val == 0.0) UNDERFLOW_ERROR(result); else return GSL_SUCCESS; } else { UNDERFLOW_ERROR(result); } } static int expint_E2_impl(const double x, gsl_sf_result * result, const int scale) { const double xmaxt = -GSL_LOG_DBL_MIN; const double xmax = xmaxt - log(xmaxt); /* CHECK_POINTER(result) */ if(x < -xmax && !scale) { OVERFLOW_ERROR(result); } else if (x == 0.0) { result->val = (scale ? 1.0 : 1.0); result->err = 0.0; return GSL_SUCCESS; } else if(x < 100.0) { const double ex = ( scale ? 1.0 : exp(-x) ); gsl_sf_result result_E1; int stat_E1 = expint_E1_impl(x, &result_E1, scale); result->val = ex - x*result_E1.val; result->err = GSL_DBL_EPSILON*ex + fabs(x) * result_E1.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_E1; } else if(x < xmax || scale) { const double s = ( scale ? 1.0 : exp(-x) ); const double c1 = -2.0; const double c2 = 6.0; const double c3 = -24.0; const double c4 = 120.0; const double c5 = -720.0; const double c6 = 5040.0; const double c7 = -40320.0; const double c8 = 362880.0; const double c9 = -3628800.0; const double c10 = 39916800.0; const double c11 = -479001600.0; const double c12 = 6227020800.0; const double c13 = -87178291200.0; const double y = 1.0/x; const double sum6 = c6+y*(c7+y*(c8+y*(c9+y*(c10+y*(c11+y*(c12+y*c13)))))); const double sum = y*(c1+y*(c2+y*(c3+y*(c4+y*(c5+y*sum6))))); result->val = s * (1.0 + sum)/x; result->err = 2.0 * (x + 1.0) * GSL_DBL_EPSILON * result->val; if(result->val == 0.0) UNDERFLOW_ERROR(result); else return GSL_SUCCESS; } else { UNDERFLOW_ERROR(result); } } static int expint_En_impl(const int n, const double x, gsl_sf_result * result, const int scale) { if (n < 0) { DOMAIN_ERROR(result); } else if (n == 0) { if (x == 0) { DOMAIN_ERROR(result); } else { result->val = (scale ? 1.0 : exp(-x)) / x; result->err = 2 * GSL_DBL_EPSILON * fabs(result->val); CHECK_UNDERFLOW(result); return GSL_SUCCESS; } } else if (n == 1) { return expint_E1_impl(x, result, scale); } else if (n == 2) { return expint_E2_impl(x, result, scale); } else { if(x < 0) { DOMAIN_ERROR(result); } if (x == 0) { result->val = (scale ? exp(x) : 1 ) * (1/(n-1.0)); result->err = 2 * GSL_DBL_EPSILON * fabs(result->val); CHECK_UNDERFLOW(result); return GSL_SUCCESS; } else { gsl_sf_result result_g; double prefactor = pow(x, n-1); int status = gsl_sf_gamma_inc_e (1-n, x, &result_g); double scale_factor = ( scale ? exp(x) : 1.0 ); result->val = scale_factor * prefactor * result_g.val; result->err = 2 * GSL_DBL_EPSILON * fabs(result->val); result->err += 2 * fabs(scale_factor * prefactor * result_g.err); if (status == GSL_SUCCESS) CHECK_UNDERFLOW(result); return status; } } } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_expint_E1_e(const double x, gsl_sf_result * result) { return expint_E1_impl(x, result, 0); } int gsl_sf_expint_E1_scaled_e(const double x, gsl_sf_result * result) { return expint_E1_impl(x, result, 1); } int gsl_sf_expint_E2_e(const double x, gsl_sf_result * result) { return expint_E2_impl(x, result, 0); } int gsl_sf_expint_E2_scaled_e(const double x, gsl_sf_result * result) { return expint_E2_impl(x, result, 1); } int gsl_sf_expint_En_e(const int n, const double x, gsl_sf_result * result) { return expint_En_impl(n, x, result, 0); } int gsl_sf_expint_En_scaled_e(const int n, const double x, gsl_sf_result * result) { return expint_En_impl(n, x, result, 1); } int gsl_sf_expint_Ei_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ { int status = gsl_sf_expint_E1_e(-x, result); result->val = -result->val; return status; } } int gsl_sf_expint_Ei_scaled_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ { int status = gsl_sf_expint_E1_scaled_e(-x, result); result->val = -result->val; return status; } } #if 0 static double recurse_En(int n, double x, double E1) { int i; double En = E1; double ex = exp(-x); for(i=2; i<=n; i++) { En = 1./(i-1) * (ex - x * En); } return En; } #endif /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_expint_E1(const double x) { EVAL_RESULT(gsl_sf_expint_E1_e(x, &result)); } double gsl_sf_expint_E1_scaled(const double x) { EVAL_RESULT(gsl_sf_expint_E1_scaled_e(x, &result)); } double gsl_sf_expint_E2(const double x) { EVAL_RESULT(gsl_sf_expint_E2_e(x, &result)); } double gsl_sf_expint_E2_scaled(const double x) { EVAL_RESULT(gsl_sf_expint_E2_scaled_e(x, &result)); } double gsl_sf_expint_En(const int n, const double x) { EVAL_RESULT(gsl_sf_expint_En_e(n, x, &result)); } double gsl_sf_expint_En_scaled(const int n, const double x) { EVAL_RESULT(gsl_sf_expint_En_scaled_e(n, x, &result)); } double gsl_sf_expint_Ei(const double x) { EVAL_RESULT(gsl_sf_expint_Ei_e(x, &result)); } double gsl_sf_expint_Ei_scaled(const double x) { EVAL_RESULT(gsl_sf_expint_Ei_scaled_e(x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__expint3.c000066400000000000000000000066761261542461700217760ustar00rootroot00000000000000/* specfunc/expint3.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_expint.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__chebyshev.h" #include "gsl_specfunc__cheb_eval.c" static double expint3_data[24] = { 1.269198414221126014, -0.248846446384140982, 0.80526220717231041e-01, -0.25772733251968330e-01, 0.7599878873073774e-02, -0.2030695581940405e-02, 0.490834586699330e-03, -0.107682239142021e-03, 0.21551726264290e-04, -0.3956705137384e-05, 0.6699240933896e-06, -0.105132180807e-06, 0.15362580199e-07, -0.20990960364e-08, 0.2692109538e-09, -0.325195242e-10, 0.37114816e-11, -0.4013652e-12, 0.412334e-13, -0.40338e-14, 0.3766e-15, -0.336e-16, 0.29e-17, -0.2e-18 }; static cheb_series expint3_cs = { expint3_data, 23, -1.0, 1.0, 15 }; static double expint3a_data[23] = { 1.9270464955068273729, -0.349293565204813805e-01, 0.14503383718983009e-02, -0.8925336718327903e-04, 0.70542392191184e-05, -0.6671727454761e-06, 0.724267589982e-07, -0.87825825606e-08, 0.11672234428e-08, -0.1676631281e-09, 0.257550158e-10, -0.41957888e-11, 0.7201041e-12, -0.1294906e-12, 0.24287e-13, -0.47331e-14, 0.95531e-15, -0.1991e-15, 0.428e-16, -0.94e-17, 0.21e-17, -0.5e-18, 0.1e-18 }; static cheb_series expint3a_cs = { expint3a_data, 22, -1.0, 1.0, 10 }; /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_expint_3_e(const double x, gsl_sf_result * result) { const double val_infinity = 0.892979511569249211; /* CHECK_POINTER(result) */ if(x < 0.0) { DOMAIN_ERROR(result); } else if(x < 1.6*GSL_ROOT3_DBL_EPSILON) { result->val = x; result->err = 0.0; return GSL_SUCCESS; } else if(x <= 2.0) { const double t = x*x*x/4.0 - 1.0; gsl_sf_result result_c; cheb_eval_e(&expint3_cs, t, &result_c); result->val = x * result_c.val; result->err = x * result_c.err; return GSL_SUCCESS; } else if(x < pow(-GSL_LOG_DBL_EPSILON, 1.0/3.0)) { const double t = 16.0/(x*x*x) - 1.0; const double s = exp(-x*x*x)/(3.0*x*x); gsl_sf_result result_c; cheb_eval_e(&expint3a_cs, t, &result_c); result->val = val_infinity - result_c.val * s; result->err = val_infinity * GSL_DBL_EPSILON + s * result_c.err; return GSL_SUCCESS; } else { result->val = val_infinity; result->err = val_infinity * GSL_DBL_EPSILON; return GSL_SUCCESS; } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_expint_3(double x) { EVAL_RESULT(gsl_sf_expint_3_e(x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__fermi_dirac.c000066400000000000000000001032151261542461700226330ustar00rootroot00000000000000/* specfunc/fermi_dirac.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_exp.h" #include "gsl_sf_gamma.h" #include "gsl_sf_hyperg.h" #include "gsl_sf_pow_int.h" #include "gsl_sf_zeta.h" #include "gsl_sf_fermi_dirac.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__chebyshev.h" #include "gsl_specfunc__cheb_eval.c" #define locEPS (1000.0*GSL_DBL_EPSILON) /* Chebyshev fit for F_{1}(t); -1 < t < 1, -1 < x < 1 */ static double fd_1_a_data[22] = { 1.8949340668482264365, 0.7237719066890052793, 0.1250000000000000000, 0.0101065196435973942, 0.0, -0.0000600615242174119, 0.0, 6.816528764623e-7, 0.0, -9.5895779195e-9, 0.0, 1.515104135e-10, 0.0, -2.5785616e-12, 0.0, 4.62270e-14, 0.0, -8.612e-16, 0.0, 1.65e-17, 0.0, -3.e-19 }; static cheb_series fd_1_a_cs = { fd_1_a_data, 21, -1, 1, 12 }; /* Chebyshev fit for F_{1}(3/2(t+1) + 1); -1 < t < 1, 1 < x < 4 */ static double fd_1_b_data[22] = { 10.409136795234611872, 3.899445098225161947, 0.513510935510521222, 0.010618736770218426, -0.001584468020659694, 0.000146139297161640, -1.408095734499e-6, -2.177993899484e-6, 3.91423660640e-7, -2.3860262660e-8, -4.138309573e-9, 1.283965236e-9, -1.39695990e-10, -4.907743e-12, 4.399878e-12, -7.17291e-13, 2.4320e-14, 1.4230e-14, -3.446e-15, 2.93e-16, 3.7e-17, -1.6e-17 }; static cheb_series fd_1_b_cs = { fd_1_b_data, 21, -1, 1, 11 }; /* Chebyshev fit for F_{1}(3(t+1) + 4); -1 < t < 1, 4 < x < 10 */ static double fd_1_c_data[23] = { 56.78099449124299762, 21.00718468237668011, 2.24592457063193457, 0.00173793640425994, -0.00058716468739423, 0.00016306958492437, -0.00003817425583020, 7.64527252009e-6, -1.31348500162e-6, 1.9000646056e-7, -2.141328223e-8, 1.23906372e-9, 2.1848049e-10, -1.0134282e-10, 2.484728e-11, -4.73067e-12, 7.3555e-13, -8.740e-14, 4.85e-15, 1.23e-15, -5.6e-16, 1.4e-16, -3.e-17 }; static cheb_series fd_1_c_cs = { fd_1_c_data, 22, -1, 1, 13 }; /* Chebyshev fit for F_{1}(x) / x^2 * 10 < x < 30 * -1 < t < 1 * t = 1/10 (x-10) - 1 = x/10 - 2 * x = 10(t+2) */ static double fd_1_d_data[30] = { 1.0126626021151374442, -0.0063312525536433793, 0.0024837319237084326, -0.0008764333697726109, 0.0002913344438921266, -0.0000931877907705692, 0.0000290151342040275, -8.8548707259955e-6, 2.6603474114517e-6, -7.891415690452e-7, 2.315730237195e-7, -6.73179452963e-8, 1.94048035606e-8, -5.5507129189e-9, 1.5766090896e-9, -4.449310875e-10, 1.248292745e-10, -3.48392894e-11, 9.6791550e-12, -2.6786240e-12, 7.388852e-13, -2.032828e-13, 5.58115e-14, -1.52987e-14, 4.1886e-15, -1.1458e-15, 3.132e-16, -8.56e-17, 2.33e-17, -5.9e-18 }; static cheb_series fd_1_d_cs = { fd_1_d_data, 29, -1, 1, 14 }; /* Chebyshev fit for F_{1}(x) / x^2 * 30 < x < Inf * -1 < t < 1 * t = 60/x - 1 * x = 60/(t+1) */ static double fd_1_e_data[10] = { 1.0013707783890401683, 0.0009138522593601060, 0.0002284630648400133, -1.57e-17, -1.27e-17, -9.7e-18, -6.9e-18, -4.6e-18, -2.9e-18, -1.7e-18 }; static cheb_series fd_1_e_cs = { fd_1_e_data, 9, -1, 1, 4 }; /* Chebyshev fit for F_{2}(t); -1 < t < 1, -1 < x < 1 */ static double fd_2_a_data[21] = { 2.1573661917148458336, 0.8849670334241132182, 0.1784163467613519713, 0.0208333333333333333, 0.0012708226459768508, 0.0, -5.0619314244895e-6, 0.0, 4.32026533989e-8, 0.0, -4.870544166e-10, 0.0, 6.4203740e-12, 0.0, -9.37424e-14, 0.0, 1.4715e-15, 0.0, -2.44e-17, 0.0, 4.e-19 }; static cheb_series fd_2_a_cs = { fd_2_a_data, 20, -1, 1, 12 }; /* Chebyshev fit for F_{2}(3/2(t+1) + 1); -1 < t < 1, 1 < x < 4 */ static double fd_2_b_data[22] = { 16.508258811798623599, 7.421719394793067988, 1.458309885545603821, 0.128773850882795229, 0.001963612026198147, -0.000237458988738779, 0.000018539661382641, -1.92805649479e-7, -2.01950028452e-7, 3.2963497518e-8, -1.885817092e-9, -2.72632744e-10, 8.0554561e-11, -8.313223e-12, -2.24489e-13, 2.18778e-13, -3.4290e-14, 1.225e-15, 5.81e-16, -1.37e-16, 1.2e-17, 1.e-18 }; static cheb_series fd_2_b_cs = { fd_2_b_data, 21, -1, 1, 12 }; /* Chebyshev fit for F_{1}(3(t+1) + 4); -1 < t < 1, 4 < x < 10 */ static double fd_2_c_data[20] = { 168.87129776686440711, 81.80260488091659458, 15.75408505947931513, 1.12325586765966440, 0.00059057505725084, -0.00016469712946921, 0.00003885607810107, -7.89873660613e-6, 1.39786238616e-6, -2.1534528656e-7, 2.831510953e-8, -2.94978583e-9, 1.6755082e-10, 2.234229e-11, -1.035130e-11, 2.41117e-12, -4.3531e-13, 6.447e-14, -7.39e-15, 4.3e-16 }; static cheb_series fd_2_c_cs = { fd_2_c_data, 19, -1, 1, 12 }; /* Chebyshev fit for F_{1}(x) / x^3 * 10 < x < 30 * -1 < t < 1 * t = 1/10 (x-10) - 1 = x/10 - 2 * x = 10(t+2) */ static double fd_2_d_data[30] = { 0.3459960518965277589, -0.00633136397691958024, 0.00248382959047594408, -0.00087651191884005114, 0.00029139255351719932, -0.00009322746111846199, 0.00002904021914564786, -8.86962264810663e-6, 2.66844972574613e-6, -7.9331564996004e-7, 2.3359868615516e-7, -6.824790880436e-8, 1.981036528154e-8, -5.71940426300e-9, 1.64379426579e-9, -4.7064937566e-10, 1.3432614122e-10, -3.823400534e-11, 1.085771994e-11, -3.07727465e-12, 8.7064848e-13, -2.4595431e-13, 6.938531e-14, -1.954939e-14, 5.50162e-15, -1.54657e-15, 4.3429e-16, -1.2178e-16, 3.394e-17, -8.81e-18 }; static cheb_series fd_2_d_cs = { fd_2_d_data, 29, -1, 1, 14 }; /* Chebyshev fit for F_{2}(x) / x^3 * 30 < x < Inf * -1 < t < 1 * t = 60/x - 1 * x = 60/(t+1) */ static double fd_2_e_data[4] = { 0.3347041117223735227, 0.00091385225936012645, 0.00022846306484003205, 5.2e-19 }; static cheb_series fd_2_e_cs = { fd_2_e_data, 3, -1, 1, 3 }; /* Chebyshev fit for F_{-1/2}(t); -1 < t < 1, -1 < x < 1 */ static double fd_mhalf_a_data[20] = { 1.2663290042859741974, 0.3697876251911153071, 0.0278131011214405055, -0.0033332848565672007, -0.0004438108265412038, 0.0000616495177243839, 8.7589611449897e-6, -1.2622936986172e-6, -1.837464037221e-7, 2.69495091400e-8, 3.9760866257e-9, -5.894468795e-10, -8.77321638e-11, 1.31016571e-11, 1.9621619e-12, -2.945887e-13, -4.43234e-14, 6.6816e-15, 1.0084e-15, -1.561e-16 }; static cheb_series fd_mhalf_a_cs = { fd_mhalf_a_data, 19, -1, 1, 12 }; /* Chebyshev fit for F_{-1/2}(3/2(t+1) + 1); -1 < t < 1, 1 < x < 4 */ static double fd_mhalf_b_data[20] = { 3.270796131942071484, 0.5809004935853417887, -0.0299313438794694987, -0.0013287935412612198, 0.0009910221228704198, -0.0001690954939688554, 6.5955849946915e-6, 3.5953966033618e-6, -9.430672023181e-7, 8.75773958291e-8, 1.06247652607e-8, -4.9587006215e-9, 7.160432795e-10, 4.5072219e-12, -2.3695425e-11, 4.9122208e-12, -2.905277e-13, -9.59291e-14, 3.00028e-14, -3.4970e-15 }; static cheb_series fd_mhalf_b_cs = { fd_mhalf_b_data, 19, -1, 1, 12 }; /* Chebyshev fit for F_{-1/2}(3(t+1) + 4); -1 < t < 1, 4 < x < 10 */ static double fd_mhalf_c_data[25] = { 5.828283273430595507, 0.677521118293264655, -0.043946248736481554, 0.005825595781828244, -0.000864858907380668, 0.000110017890076539, -6.973305225404e-6, -1.716267414672e-6, 8.59811582041e-7, -2.33066786976e-7, 4.8503191159e-8, -8.130620247e-9, 1.021068250e-9, -5.3188423e-11, -1.9430559e-11, 8.750506e-12, -2.324897e-12, 4.83102e-13, -8.1207e-14, 1.0132e-14, -4.64e-16, -2.24e-16, 9.7e-17, -2.6e-17, 5.e-18 }; static cheb_series fd_mhalf_c_cs = { fd_mhalf_c_data, 24, -1, 1, 13 }; /* Chebyshev fit for F_{-1/2}(x) / x^(1/2) * 10 < x < 30 * -1 < t < 1 * t = 1/10 (x-10) - 1 = x/10 - 2 */ static double fd_mhalf_d_data[30] = { 2.2530744202862438709, 0.0018745152720114692, -0.0007550198497498903, 0.0002759818676644382, -0.0000959406283465913, 0.0000324056855537065, -0.0000107462396145761, 3.5126865219224e-6, -1.1313072730092e-6, 3.577454162766e-7, -1.104926666238e-7, 3.31304165692e-8, -9.5837381008e-9, 2.6575790141e-9, -7.015201447e-10, 1.747111336e-10, -4.04909605e-11, 8.5104999e-12, -1.5261885e-12, 1.876851e-13, 1.00574e-14, -1.82002e-14, 8.6634e-15, -3.2058e-15, 1.0572e-15, -3.259e-16, 9.60e-17, -2.74e-17, 7.6e-18, -1.9e-18 }; static cheb_series fd_mhalf_d_cs = { fd_mhalf_d_data, 29, -1, 1, 15 }; /* Chebyshev fit for F_{1/2}(t); -1 < t < 1, -1 < x < 1 */ static double fd_half_a_data[23] = { 1.7177138871306189157, 0.6192579515822668460, 0.0932802275119206269, 0.0047094853246636182, -0.0004243667967864481, -0.0000452569787686193, 5.2426509519168e-6, 6.387648249080e-7, -8.05777004848e-8, -1.04290272415e-8, 1.3769478010e-9, 1.847190359e-10, -2.51061890e-11, -3.4497818e-12, 4.784373e-13, 6.68828e-14, -9.4147e-15, -1.3333e-15, 1.898e-16, 2.72e-17, -3.9e-18, -6.e-19, 1.e-19 }; static cheb_series fd_half_a_cs = { fd_half_a_data, 22, -1, 1, 11 }; /* Chebyshev fit for F_{1/2}(3/2(t+1) + 1); -1 < t < 1, 1 < x < 4 */ static double fd_half_b_data[20] = { 7.651013792074984027, 2.475545606866155737, 0.218335982672476128, -0.007730591500584980, -0.000217443383867318, 0.000147663980681359, -0.000021586361321527, 8.07712735394e-7, 3.28858050706e-7, -7.9474330632e-8, 6.940207234e-9, 6.75594681e-10, -3.10200490e-10, 4.2677233e-11, -2.1696e-14, -1.170245e-12, 2.34757e-13, -1.4139e-14, -3.864e-15, 1.202e-15 }; static cheb_series fd_half_b_cs = { fd_half_b_data, 19, -1, 1, 12 }; /* Chebyshev fit for F_{1/2}(3(t+1) + 4); -1 < t < 1, 4 < x < 10 */ static double fd_half_c_data[23] = { 29.584339348839816528, 8.808344283250615592, 0.503771641883577308, -0.021540694914550443, 0.002143341709406890, -0.000257365680646579, 0.000027933539372803, -1.678525030167e-6, -2.78100117693e-7, 1.35218065147e-7, -3.3740425009e-8, 6.474834942e-9, -1.009678978e-9, 1.20057555e-10, -6.636314e-12, -1.710566e-12, 7.75069e-13, -1.97973e-13, 3.9414e-14, -6.374e-15, 7.77e-16, -4.0e-17, -1.4e-17 }; static cheb_series fd_half_c_cs = { fd_half_c_data, 22, -1, 1, 13 }; /* Chebyshev fit for F_{1/2}(x) / x^(3/2) * 10 < x < 30 * -1 < t < 1 * t = 1/10 (x-10) - 1 = x/10 - 2 */ static double fd_half_d_data[30] = { 1.5116909434145508537, -0.0036043405371630468, 0.0014207743256393359, -0.0005045399052400260, 0.0001690758006957347, -0.0000546305872688307, 0.0000172223228484571, -5.3352603788706e-6, 1.6315287543662e-6, -4.939021084898e-7, 1.482515450316e-7, -4.41552276226e-8, 1.30503160961e-8, -3.8262599802e-9, 1.1123226976e-9, -3.204765534e-10, 9.14870489e-11, -2.58778946e-11, 7.2550731e-12, -2.0172226e-12, 5.566891e-13, -1.526247e-13, 4.16121e-14, -1.12933e-14, 3.0537e-15, -8.234e-16, 2.215e-16, -5.95e-17, 1.59e-17, -4.0e-18 }; static cheb_series fd_half_d_cs = { fd_half_d_data, 29, -1, 1, 15 }; /* Chebyshev fit for F_{3/2}(t); -1 < t < 1, -1 < x < 1 */ static double fd_3half_a_data[20] = { 2.0404775940601704976, 0.8122168298093491444, 0.1536371165644008069, 0.0156174323847845125, 0.0005943427879290297, -0.0000429609447738365, -3.8246452994606e-6, 3.802306180287e-7, 4.05746157593e-8, -4.5530360159e-9, -5.306873139e-10, 6.37297268e-11, 7.8403674e-12, -9.840241e-13, -1.255952e-13, 1.62617e-14, 2.1318e-15, -2.825e-16, -3.78e-17, 5.1e-18 }; static cheb_series fd_3half_a_cs = { fd_3half_a_data, 19, -1, 1, 11 }; /* Chebyshev fit for F_{3/2}(3/2(t+1) + 1); -1 < t < 1, 1 < x < 4 */ static double fd_3half_b_data[22] = { 13.403206654624176674, 5.574508357051880924, 0.931228574387527769, 0.054638356514085862, -0.001477172902737439, -0.000029378553381869, 0.000018357033493246, -2.348059218454e-6, 8.3173787440e-8, 2.6826486956e-8, -6.011244398e-9, 4.94345981e-10, 3.9557340e-11, -1.7894930e-11, 2.348972e-12, -1.2823e-14, -5.4192e-14, 1.0527e-14, -6.39e-16, -1.47e-16, 4.5e-17, -5.e-18 }; static cheb_series fd_3half_b_cs = { fd_3half_b_data, 21, -1, 1, 12 }; /* Chebyshev fit for F_{3/2}(3(t+1) + 4); -1 < t < 1, 4 < x < 10 */ static double fd_3half_c_data[21] = { 101.03685253378877642, 43.62085156043435883, 6.62241373362387453, 0.25081415008708521, -0.00798124846271395, 0.00063462245101023, -0.00006392178890410, 6.04535131939e-6, -3.4007683037e-7, -4.072661545e-8, 1.931148453e-8, -4.46328355e-9, 7.9434717e-10, -1.1573569e-10, 1.304658e-11, -7.4114e-13, -1.4181e-13, 6.491e-14, -1.597e-14, 3.05e-15, -4.8e-16 }; static cheb_series fd_3half_c_cs = { fd_3half_c_data, 20, -1, 1, 12 }; /* Chebyshev fit for F_{3/2}(x) / x^(5/2) * 10 < x < 30 * -1 < t < 1 * t = 1/10 (x-10) - 1 = x/10 - 2 */ static double fd_3half_d_data[25] = { 0.6160645215171852381, -0.0071239478492671463, 0.0027906866139659846, -0.0009829521424317718, 0.0003260229808519545, -0.0001040160912910890, 0.0000322931223232439, -9.8243506588102e-6, 2.9420132351277e-6, -8.699154670418e-7, 2.545460071999e-7, -7.38305056331e-8, 2.12545670310e-8, -6.0796532462e-9, 1.7294556741e-9, -4.896540687e-10, 1.380786037e-10, -3.88057305e-11, 1.08753212e-11, -3.0407308e-12, 8.485626e-13, -2.364275e-13, 6.57636e-14, -1.81807e-14, 4.6884e-15 }; static cheb_series fd_3half_d_cs = { fd_3half_d_data, 24, -1, 1, 16 }; /* Goano's modification of the Levin-u implementation. * This is a simplification of the original WHIZ algorithm. * See [Fessler et al., ACM Toms 9, 346 (1983)]. */ static int fd_whiz(const double term, const int iterm, double * qnum, double * qden, double * result, double * s) { if(iterm == 0) *s = 0.0; *s += term; qden[iterm] = 1.0/(term*(iterm+1.0)*(iterm+1.0)); qnum[iterm] = *s * qden[iterm]; if(iterm > 0) { double factor = 1.0; double ratio = iterm/(iterm+1.0); int j; for(j=iterm-1; j>=0; j--) { double c = factor * (j+1.0) / (iterm+1.0); factor *= ratio; qden[j] = qden[j+1] - c * qden[j]; qnum[j] = qnum[j+1] - c * qnum[j]; } } *result = qnum[0] / qden[0]; return GSL_SUCCESS; } /* Handle case of integer j <= -2. */ static int fd_nint(const int j, const double x, gsl_sf_result * result) { /* const int nsize = 100 + 1; */ enum { nsize = 100+1 }; double qcoeff[nsize]; if(j >= -1) { result->val = 0.0; result->err = 0.0; GSL_ERROR ("error", GSL_ESANITY); } else if(j < -(nsize)) { result->val = 0.0; result->err = 0.0; GSL_ERROR ("error", GSL_EUNIMPL); } else { double a, p, f; int i, k; int n = -(j+1); qcoeff[1] = 1.0; for(k=2; k<=n; k++) { qcoeff[k] = -qcoeff[k-1]; for(i=k-1; i>=2; i--) { qcoeff[i] = i*qcoeff[i] - (k-(i-1))*qcoeff[i-1]; } } if(x >= 0.0) { a = exp(-x); f = qcoeff[1]; for(i=2; i<=n; i++) { f = f*a + qcoeff[i]; } } else { a = exp(x); f = qcoeff[n]; for(i=n-1; i>=1; i--) { f = f*a + qcoeff[i]; } } p = gsl_sf_pow_int(1.0+a, j); result->val = f*a*p; result->err = 3.0 * GSL_DBL_EPSILON * fabs(f*a*p); return GSL_SUCCESS; } } /* x < 0 */ static int fd_neg(const double j, const double x, gsl_sf_result * result) { enum { itmax = 100, qsize = 100+1 }; /* const int itmax = 100; */ /* const int qsize = 100 + 1; */ double qnum[qsize], qden[qsize]; if(x < GSL_LOG_DBL_MIN) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(x < -1.0 && x < -fabs(j+1.0)) { /* Simple series implementation. Avoid the * complexity and extra work of the series * acceleration method below. */ double ex = exp(x); double term = ex; double sum = term; int n; for(n=2; n<100; n++) { double rat = (n-1.0)/n; double p = pow(rat, j+1.0); term *= -ex * p; sum += term; if(fabs(term/sum) < GSL_DBL_EPSILON) break; } result->val = sum; result->err = 2.0 * GSL_DBL_EPSILON * fabs(sum); return GSL_SUCCESS; } else { double s = 0.0; double xn = x; double ex = -exp(x); double enx = -ex; double f = 0.0; double f_previous; int jterm; for(jterm=0; jterm<=itmax; jterm++) { double p = pow(jterm+1.0, j+1.0); double term = enx/p; f_previous = f; fd_whiz(term, jterm, qnum, qden, &f, &s); xn += x; if(fabs(f-f_previous) < fabs(f)*2.0*GSL_DBL_EPSILON || xn < GSL_LOG_DBL_MIN) break; enx *= ex; } result->val = f; result->err = fabs(f-f_previous); result->err += 2.0 * GSL_DBL_EPSILON * fabs(f); if(jterm == itmax) GSL_ERROR ("error", GSL_EMAXITER); else return GSL_SUCCESS; } } /* asymptotic expansion * j + 2.0 > 0.0 */ static int fd_asymp(const double j, const double x, gsl_sf_result * result) { const int j_integer = ( fabs(j - floor(j+0.5)) < 100.0*GSL_DBL_EPSILON ); const int itmax = 200; gsl_sf_result lg; int stat_lg = gsl_sf_lngamma_e(j + 2.0, &lg); double seqn_val = 0.5; double seqn_err = 0.0; double xm2 = (1.0/x)/x; double xgam = 1.0; double add = GSL_DBL_MAX; double cos_term; double ln_x; double ex_term_1; double ex_term_2; gsl_sf_result fneg; gsl_sf_result ex_arg; gsl_sf_result ex; int stat_fneg; int stat_e; int n; for(n=1; n<=itmax; n++) { double add_previous = add; gsl_sf_result eta; gsl_sf_eta_int_e(2*n, &eta); xgam = xgam * xm2 * (j + 1.0 - (2*n-2)) * (j + 1.0 - (2*n-1)); add = eta.val * xgam; if(!j_integer && fabs(add) > fabs(add_previous)) break; if(fabs(add/seqn_val) < GSL_DBL_EPSILON) break; seqn_val += add; seqn_err += 2.0 * GSL_DBL_EPSILON * fabs(add); } seqn_err += fabs(add); stat_fneg = fd_neg(j, -x, &fneg); ln_x = log(x); ex_term_1 = (j+1.0)*ln_x; ex_term_2 = lg.val; ex_arg.val = ex_term_1 - ex_term_2; /*(j+1.0)*ln_x - lg.val; */ ex_arg.err = GSL_DBL_EPSILON*(fabs(ex_term_1) + fabs(ex_term_2)) + lg.err; stat_e = gsl_sf_exp_err_e(ex_arg.val, ex_arg.err, &ex); cos_term = cos(j*M_PI); result->val = cos_term * fneg.val + 2.0 * seqn_val * ex.val; result->err = fabs(2.0 * ex.err * seqn_val); result->err += fabs(2.0 * ex.val * seqn_err); result->err += fabs(cos_term) * fneg.err; result->err += 4.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_3(stat_e, stat_fneg, stat_lg); } /* Series evaluation for small x, generic j. * [Goano (8)] */ #if 0 static int fd_series(const double j, const double x, double * result) { const int nmax = 1000; int n; double sum = 0.0; double prev; double pow_factor = 1.0; double eta_factor; gsl_sf_eta_e(j + 1.0, &eta_factor); prev = pow_factor * eta_factor; sum += prev; for(n=1; n 0, integer j > 0; x < Pi. * [Goano (8)] */ static int fd_series_int(const int j, const double x, gsl_sf_result * result) { int n; double sum = 0.0; double del; double pow_factor = 1.0; gsl_sf_result eta_factor; gsl_sf_eta_int_e(j + 1, &eta_factor); del = pow_factor * eta_factor.val; sum += del; /* Sum terms where the argument * of eta() is positive. */ for(n=1; n<=j+2; n++) { gsl_sf_eta_int_e(j+1-n, &eta_factor); pow_factor *= x/n; del = pow_factor * eta_factor.val; sum += del; if(fabs(del/sum) < GSL_DBL_EPSILON) break; } /* Now sum the terms where eta() is negative. * The argument of eta() must be odd as well, * so it is convenient to transform the series * as follows: * * Sum[ eta(j+1-n) x^n / n!, {n,j+4,Infinity}] * = x^j / j! Sum[ eta(1-2m) x^(2m) j! / (2m+j)! , {m,2,Infinity}] * * We do not need to do this sum if j is large enough. */ if(j < 32) { int m; gsl_sf_result jfact; double sum2; double pre2; gsl_sf_fact_e((unsigned int)j, &jfact); pre2 = gsl_sf_pow_int(x, j) / jfact.val; gsl_sf_eta_int_e(-3, &eta_factor); pow_factor = x*x*x*x / ((j+4)*(j+3)*(j+2)*(j+1)); sum2 = eta_factor.val * pow_factor; for(m=3; m<24; m++) { gsl_sf_eta_int_e(1-2*m, &eta_factor); pow_factor *= x*x / ((j+2*m)*(j+2*m-1)); sum2 += eta_factor.val * pow_factor; } sum += pre2 * sum2; } result->val = sum; result->err = 2.0 * GSL_DBL_EPSILON * fabs(sum); return GSL_SUCCESS; } /* series of hypergeometric functions for integer j > 0, x > 0 * [Goano (7)] */ static int fd_UMseries_int(const int j, const double x, gsl_sf_result * result) { const int nmax = 2000; double pre; double lnpre_val; double lnpre_err; double sum_even_val = 1.0; double sum_even_err = 0.0; double sum_odd_val = 0.0; double sum_odd_err = 0.0; int stat_sum; int stat_e; int stat_h = GSL_SUCCESS; int n; if(x < 500.0 && j < 80) { double p = gsl_sf_pow_int(x, j+1); gsl_sf_result g; gsl_sf_fact_e(j+1, &g); /* Gamma(j+2) */ lnpre_val = 0.0; lnpre_err = 0.0; pre = p/g.val; } else { double lnx = log(x); gsl_sf_result lg; gsl_sf_lngamma_e(j + 2.0, &lg); lnpre_val = (j+1.0)*lnx - lg.val; lnpre_err = 2.0 * GSL_DBL_EPSILON * fabs((j+1.0)*lnx) + lg.err; pre = 1.0; } /* Add up the odd terms of the sum. */ for(n=1; n= nmax ? GSL_EMAXITER : GSL_SUCCESS ); stat_e = gsl_sf_exp_mult_err_e(lnpre_val, lnpre_err, pre*(sum_even_val + sum_odd_val), pre*(sum_even_err + sum_odd_err), result); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_3(stat_e, stat_h, stat_sum); } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ /* [Goano (4)] */ int gsl_sf_fermi_dirac_m1_e(const double x, gsl_sf_result * result) { if(x < GSL_LOG_DBL_MIN) { UNDERFLOW_ERROR(result); } else if(x < 0.0) { const double ex = exp(x); result->val = ex/(1.0+ex); result->err = 2.0 * (fabs(x) + 1.0) * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { double ex = exp(-x); result->val = 1.0/(1.0 + ex); result->err = 2.0 * GSL_DBL_EPSILON * (x + 1.0) * ex; return GSL_SUCCESS; } } /* [Goano (3)] */ int gsl_sf_fermi_dirac_0_e(const double x, gsl_sf_result * result) { if(x < GSL_LOG_DBL_MIN) { UNDERFLOW_ERROR(result); } else if(x < -5.0) { double ex = exp(x); double ser = 1.0 - ex*(0.5 - ex*(1.0/3.0 - ex*(1.0/4.0 - ex*(1.0/5.0 - ex/6.0)))); result->val = ex * ser; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < 10.0) { result->val = log(1.0 + exp(x)); result->err = fabs(x * GSL_DBL_EPSILON); return GSL_SUCCESS; } else { double ex = exp(-x); result->val = x + ex * (1.0 - 0.5*ex + ex*ex/3.0 - ex*ex*ex/4.0); result->err = (x + ex) * GSL_DBL_EPSILON; return GSL_SUCCESS; } } int gsl_sf_fermi_dirac_1_e(const double x, gsl_sf_result * result) { if(x < GSL_LOG_DBL_MIN) { UNDERFLOW_ERROR(result); } else if(x < -1.0) { /* series [Goano (6)] */ double ex = exp(x); double term = ex; double sum = term; int n; for(n=2; n<100 ; n++) { double rat = (n-1.0)/n; term *= -ex * rat * rat; sum += term; if(fabs(term/sum) < GSL_DBL_EPSILON) break; } result->val = sum; result->err = 2.0 * fabs(sum) * GSL_DBL_EPSILON; return GSL_SUCCESS; } else if(x < 1.0) { return cheb_eval_e(&fd_1_a_cs, x, result); } else if(x < 4.0) { double t = 2.0/3.0*(x-1.0) - 1.0; return cheb_eval_e(&fd_1_b_cs, t, result); } else if(x < 10.0) { double t = 1.0/3.0*(x-4.0) - 1.0; return cheb_eval_e(&fd_1_c_cs, t, result); } else if(x < 30.0) { double t = 0.1*x - 2.0; gsl_sf_result c; cheb_eval_e(&fd_1_d_cs, t, &c); result->val = c.val * x*x; result->err = c.err * x*x + GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < 1.0/GSL_SQRT_DBL_EPSILON) { double t = 60.0/x - 1.0; gsl_sf_result c; cheb_eval_e(&fd_1_e_cs, t, &c); result->val = c.val * x*x; result->err = c.err * x*x + GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < GSL_SQRT_DBL_MAX) { result->val = 0.5 * x*x; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { OVERFLOW_ERROR(result); } } int gsl_sf_fermi_dirac_2_e(const double x, gsl_sf_result * result) { if(x < GSL_LOG_DBL_MIN) { UNDERFLOW_ERROR(result); } else if(x < -1.0) { /* series [Goano (6)] */ double ex = exp(x); double term = ex; double sum = term; int n; for(n=2; n<100 ; n++) { double rat = (n-1.0)/n; term *= -ex * rat * rat * rat; sum += term; if(fabs(term/sum) < GSL_DBL_EPSILON) break; } result->val = sum; result->err = 2.0 * GSL_DBL_EPSILON * fabs(sum); return GSL_SUCCESS; } else if(x < 1.0) { return cheb_eval_e(&fd_2_a_cs, x, result); } else if(x < 4.0) { double t = 2.0/3.0*(x-1.0) - 1.0; return cheb_eval_e(&fd_2_b_cs, t, result); } else if(x < 10.0) { double t = 1.0/3.0*(x-4.0) - 1.0; return cheb_eval_e(&fd_2_c_cs, t, result); } else if(x < 30.0) { double t = 0.1*x - 2.0; gsl_sf_result c; cheb_eval_e(&fd_2_d_cs, t, &c); result->val = c.val * x*x*x; result->err = c.err * x*x*x + 3.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < 1.0/GSL_ROOT3_DBL_EPSILON) { double t = 60.0/x - 1.0; gsl_sf_result c; cheb_eval_e(&fd_2_e_cs, t, &c); result->val = c.val * x*x*x; result->err = c.err * x*x*x + 3.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < GSL_ROOT3_DBL_MAX) { result->val = 1.0/6.0 * x*x*x; result->err = 3.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { OVERFLOW_ERROR(result); } } int gsl_sf_fermi_dirac_int_e(const int j, const double x, gsl_sf_result * result) { if(j < -1) { return fd_nint(j, x, result); } else if (j == -1) { return gsl_sf_fermi_dirac_m1_e(x, result); } else if(j == 0) { return gsl_sf_fermi_dirac_0_e(x, result); } else if(j == 1) { return gsl_sf_fermi_dirac_1_e(x, result); } else if(j == 2) { return gsl_sf_fermi_dirac_2_e(x, result); } else if(x < 0.0) { return fd_neg(j, x, result); } else if(x == 0.0) { return gsl_sf_eta_int_e(j+1, result); } else if(x < 1.5) { return fd_series_int(j, x, result); } else { gsl_sf_result fasymp; int stat_asymp = fd_asymp(j, x, &fasymp); if(stat_asymp == GSL_SUCCESS) { result->val = fasymp.val; result->err = fasymp.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_asymp; } else { return fd_UMseries_int(j, x, result); } } } int gsl_sf_fermi_dirac_mhalf_e(const double x, gsl_sf_result * result) { if(x < GSL_LOG_DBL_MIN) { UNDERFLOW_ERROR(result); } else if(x < -1.0) { /* series [Goano (6)] */ double ex = exp(x); double term = ex; double sum = term; int n; for(n=2; n<200 ; n++) { double rat = (n-1.0)/n; term *= -ex * sqrt(rat); sum += term; if(fabs(term/sum) < GSL_DBL_EPSILON) break; } result->val = sum; result->err = 2.0 * fabs(sum) * GSL_DBL_EPSILON; return GSL_SUCCESS; } else if(x < 1.0) { return cheb_eval_e(&fd_mhalf_a_cs, x, result); } else if(x < 4.0) { double t = 2.0/3.0*(x-1.0) - 1.0; return cheb_eval_e(&fd_mhalf_b_cs, t, result); } else if(x < 10.0) { double t = 1.0/3.0*(x-4.0) - 1.0; return cheb_eval_e(&fd_mhalf_c_cs, t, result); } else if(x < 30.0) { double rtx = sqrt(x); double t = 0.1*x - 2.0; gsl_sf_result c; cheb_eval_e(&fd_mhalf_d_cs, t, &c); result->val = c.val * rtx; result->err = c.err * rtx + 0.5 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { return fd_asymp(-0.5, x, result); } } int gsl_sf_fermi_dirac_half_e(const double x, gsl_sf_result * result) { if(x < GSL_LOG_DBL_MIN) { UNDERFLOW_ERROR(result); } else if(x < -1.0) { /* series [Goano (6)] */ double ex = exp(x); double term = ex; double sum = term; int n; for(n=2; n<100 ; n++) { double rat = (n-1.0)/n; term *= -ex * rat * sqrt(rat); sum += term; if(fabs(term/sum) < GSL_DBL_EPSILON) break; } result->val = sum; result->err = 2.0 * fabs(sum) * GSL_DBL_EPSILON; return GSL_SUCCESS; } else if(x < 1.0) { return cheb_eval_e(&fd_half_a_cs, x, result); } else if(x < 4.0) { double t = 2.0/3.0*(x-1.0) - 1.0; return cheb_eval_e(&fd_half_b_cs, t, result); } else if(x < 10.0) { double t = 1.0/3.0*(x-4.0) - 1.0; return cheb_eval_e(&fd_half_c_cs, t, result); } else if(x < 30.0) { double x32 = x*sqrt(x); double t = 0.1*x - 2.0; gsl_sf_result c; cheb_eval_e(&fd_half_d_cs, t, &c); result->val = c.val * x32; result->err = c.err * x32 + 1.5 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { return fd_asymp(0.5, x, result); } } int gsl_sf_fermi_dirac_3half_e(const double x, gsl_sf_result * result) { if(x < GSL_LOG_DBL_MIN) { UNDERFLOW_ERROR(result); } else if(x < -1.0) { /* series [Goano (6)] */ double ex = exp(x); double term = ex; double sum = term; int n; for(n=2; n<100 ; n++) { double rat = (n-1.0)/n; term *= -ex * rat * rat * sqrt(rat); sum += term; if(fabs(term/sum) < GSL_DBL_EPSILON) break; } result->val = sum; result->err = 2.0 * fabs(sum) * GSL_DBL_EPSILON; return GSL_SUCCESS; } else if(x < 1.0) { return cheb_eval_e(&fd_3half_a_cs, x, result); } else if(x < 4.0) { double t = 2.0/3.0*(x-1.0) - 1.0; return cheb_eval_e(&fd_3half_b_cs, t, result); } else if(x < 10.0) { double t = 1.0/3.0*(x-4.0) - 1.0; return cheb_eval_e(&fd_3half_c_cs, t, result); } else if(x < 30.0) { double x52 = x*x*sqrt(x); double t = 0.1*x - 2.0; gsl_sf_result c; cheb_eval_e(&fd_3half_d_cs, t, &c); result->val = c.val * x52; result->err = c.err * x52 + 2.5 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { return fd_asymp(1.5, x, result); } } /* [Goano p. 222] */ int gsl_sf_fermi_dirac_inc_0_e(const double x, const double b, gsl_sf_result * result) { if(b < 0.0) { DOMAIN_ERROR(result); } else { double arg = b - x; gsl_sf_result f0; int status = gsl_sf_fermi_dirac_0_e(arg, &f0); result->val = f0.val - arg; result->err = f0.err + GSL_DBL_EPSILON * (fabs(x) + fabs(b)); return status; } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_fermi_dirac_m1(const double x) { EVAL_RESULT(gsl_sf_fermi_dirac_m1_e(x, &result)); } double gsl_sf_fermi_dirac_0(const double x) { EVAL_RESULT(gsl_sf_fermi_dirac_0_e(x, &result)); } double gsl_sf_fermi_dirac_1(const double x) { EVAL_RESULT(gsl_sf_fermi_dirac_1_e(x, &result)); } double gsl_sf_fermi_dirac_2(const double x) { EVAL_RESULT(gsl_sf_fermi_dirac_2_e(x, &result)); } double gsl_sf_fermi_dirac_int(const int j, const double x) { EVAL_RESULT(gsl_sf_fermi_dirac_int_e(j, x, &result)); } double gsl_sf_fermi_dirac_mhalf(const double x) { EVAL_RESULT(gsl_sf_fermi_dirac_mhalf_e(x, &result)); } double gsl_sf_fermi_dirac_half(const double x) { EVAL_RESULT(gsl_sf_fermi_dirac_half_e(x, &result)); } double gsl_sf_fermi_dirac_3half(const double x) { EVAL_RESULT(gsl_sf_fermi_dirac_3half_e(x, &result)); } double gsl_sf_fermi_dirac_inc_0(const double x, const double b) { EVAL_RESULT(gsl_sf_fermi_dirac_inc_0_e(x, b, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__gamma.c000066400000000000000000001666041261542461700214640ustar00rootroot00000000000000/* specfunc/gamma.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_exp.h" #include "gsl_sf_log.h" #include "gsl_sf_psi.h" #include "gsl_sf_trig.h" #include "gsl_sf_gamma.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__check.h" #include "gsl_specfunc__chebyshev.h" #include "gsl_specfunc__cheb_eval.c" #define LogRootTwoPi_ 0.9189385332046727418 /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/ static struct {int n; double f; long i; } fact_table[GSL_SF_FACT_NMAX + 1] = { { 0, 1.0, 1L }, { 1, 1.0, 1L }, { 2, 2.0, 2L }, { 3, 6.0, 6L }, { 4, 24.0, 24L }, { 5, 120.0, 120L }, { 6, 720.0, 720L }, { 7, 5040.0, 5040L }, { 8, 40320.0, 40320L }, { 9, 362880.0, 362880L }, { 10, 3628800.0, 3628800L }, { 11, 39916800.0, 39916800L }, { 12, 479001600.0, 479001600L }, { 13, 6227020800.0, 0 }, { 14, 87178291200.0, 0 }, { 15, 1307674368000.0, 0 }, { 16, 20922789888000.0, 0 }, { 17, 355687428096000.0, 0 }, { 18, 6402373705728000.0, 0 }, { 19, 121645100408832000.0, 0 }, { 20, 2432902008176640000.0, 0 }, { 21, 51090942171709440000.0, 0 }, { 22, 1124000727777607680000.0, 0 }, { 23, 25852016738884976640000.0, 0 }, { 24, 620448401733239439360000.0, 0 }, { 25, 15511210043330985984000000.0, 0 }, { 26, 403291461126605635584000000.0, 0 }, { 27, 10888869450418352160768000000.0, 0 }, { 28, 304888344611713860501504000000.0, 0 }, { 29, 8841761993739701954543616000000.0, 0 }, { 30, 265252859812191058636308480000000.0, 0 }, { 31, 8222838654177922817725562880000000.0, 0 }, { 32, 263130836933693530167218012160000000.0, 0 }, { 33, 8683317618811886495518194401280000000.0, 0 }, { 34, 2.95232799039604140847618609644e38, 0 }, { 35, 1.03331479663861449296666513375e40, 0 }, { 36, 3.71993326789901217467999448151e41, 0 }, { 37, 1.37637530912263450463159795816e43, 0 }, { 38, 5.23022617466601111760007224100e44, 0 }, { 39, 2.03978820811974433586402817399e46, 0 }, { 40, 8.15915283247897734345611269600e47, 0 }, { 41, 3.34525266131638071081700620534e49, 0 }, { 42, 1.40500611775287989854314260624e51, 0 }, { 43, 6.04152630633738356373551320685e52, 0 }, { 44, 2.65827157478844876804362581101e54, 0 }, { 45, 1.19622220865480194561963161496e56, 0 }, { 46, 5.50262215981208894985030542880e57, 0 }, { 47, 2.58623241511168180642964355154e59, 0 }, { 48, 1.24139155925360726708622890474e61, 0 }, { 49, 6.08281864034267560872252163321e62, 0 }, { 50, 3.04140932017133780436126081661e64, 0 }, { 51, 1.55111875328738228022424301647e66, 0 }, { 52, 8.06581751709438785716606368564e67, 0 }, { 53, 4.27488328406002556429801375339e69, 0 }, { 54, 2.30843697339241380472092742683e71, 0 }, { 55, 1.26964033536582759259651008476e73, 0 }, { 56, 7.10998587804863451854045647464e74, 0 }, { 57, 4.05269195048772167556806019054e76, 0 }, { 58, 2.35056133128287857182947491052e78, 0 }, { 59, 1.38683118545689835737939019720e80, 0 }, { 60, 8.32098711274139014427634118320e81, 0 }, { 61, 5.07580213877224798800856812177e83, 0 }, { 62, 3.14699732603879375256531223550e85, 0 }, { 63, 1.982608315404440064116146708360e87, 0 }, { 64, 1.268869321858841641034333893350e89, 0 }, { 65, 8.247650592082470666723170306800e90, 0 }, { 66, 5.443449390774430640037292402480e92, 0 }, { 67, 3.647111091818868528824985909660e94, 0 }, { 68, 2.480035542436830599600990418570e96, 0 }, { 69, 1.711224524281413113724683388810e98, 0 }, { 70, 1.197857166996989179607278372170e100, 0 }, { 71, 8.504785885678623175211676442400e101, 0 }, { 72, 6.123445837688608686152407038530e103, 0 }, { 73, 4.470115461512684340891257138130e105, 0 }, { 74, 3.307885441519386412259530282210e107, 0 }, { 75, 2.480914081139539809194647711660e109, 0 }, { 76, 1.885494701666050254987932260860e111, 0 }, { 77, 1.451830920282858696340707840860e113, 0 }, { 78, 1.132428117820629783145752115870e115, 0 }, { 79, 8.946182130782975286851441715400e116, 0 }, { 80, 7.156945704626380229481153372320e118, 0 }, { 81, 5.797126020747367985879734231580e120, 0 }, { 82, 4.753643337012841748421382069890e122, 0 }, { 83, 3.945523969720658651189747118010e124, 0 }, { 84, 3.314240134565353266999387579130e126, 0 }, { 85, 2.817104114380550276949479442260e128, 0 }, { 86, 2.422709538367273238176552320340e130, 0 }, { 87, 2.107757298379527717213600518700e132, 0 }, { 88, 1.854826422573984391147968456460e134, 0 }, { 89, 1.650795516090846108121691926250e136, 0 }, { 90, 1.485715964481761497309522733620e138, 0 }, { 91, 1.352001527678402962551665687590e140, 0 }, { 92, 1.243841405464130725547532432590e142, 0 }, { 93, 1.156772507081641574759205162310e144, 0 }, { 94, 1.087366156656743080273652852570e146, 0 }, { 95, 1.032997848823905926259970209940e148, 0 }, { 96, 9.916779348709496892095714015400e149, 0 }, { 97, 9.619275968248211985332842594960e151, 0 }, { 98, 9.426890448883247745626185743100e153, 0 }, { 99, 9.332621544394415268169923885600e155, 0 }, { 100, 9.33262154439441526816992388563e157, 0 }, { 101, 9.42594775983835942085162312450e159, 0 }, { 102, 9.61446671503512660926865558700e161, 0 }, { 103, 9.90290071648618040754671525458e163, 0 }, { 104, 1.02990167451456276238485838648e166, 0 }, { 105, 1.08139675824029090050410130580e168, 0 }, { 106, 1.146280563734708354534347384148e170, 0 }, { 107, 1.226520203196137939351751701040e172, 0 }, { 108, 1.324641819451828974499891837120e174, 0 }, { 109, 1.443859583202493582204882102460e176, 0 }, { 110, 1.588245541522742940425370312710e178, 0 }, { 111, 1.762952551090244663872161047110e180, 0 }, { 112, 1.974506857221074023536820372760e182, 0 }, { 113, 2.231192748659813646596607021220e184, 0 }, { 114, 2.543559733472187557120132004190e186, 0 }, { 115, 2.925093693493015690688151804820e188, 0 }, { 116, 3.393108684451898201198256093590e190, 0 }, { 117, 3.96993716080872089540195962950e192, 0 }, { 118, 4.68452584975429065657431236281e194, 0 }, { 119, 5.57458576120760588132343171174e196, 0 }, { 120, 6.68950291344912705758811805409e198, 0 }, { 121, 8.09429852527344373968162284545e200, 0 }, { 122, 9.87504420083360136241157987140e202, 0 }, { 123, 1.21463043670253296757662432419e205, 0 }, { 124, 1.50614174151114087979501416199e207, 0 }, { 125, 1.88267717688892609974376770249e209, 0 }, { 126, 2.37217324288004688567714730514e211, 0 }, { 127, 3.01266001845765954480997707753e213, 0 }, { 128, 3.85620482362580421735677065923e215, 0 }, { 129, 4.97450422247728744039023415041e217, 0 }, { 130, 6.46685548922047367250730439554e219, 0 }, { 131, 8.47158069087882051098456875820e221, 0 }, { 132, 1.11824865119600430744996307608e224, 0 }, { 133, 1.48727070609068572890845089118e226, 0 }, { 134, 1.99294274616151887673732419418e228, 0 }, { 135, 2.69047270731805048359538766215e230, 0 }, { 136, 3.65904288195254865768972722052e232, 0 }, { 137, 5.01288874827499166103492629211e234, 0 }, { 138, 6.91778647261948849222819828311e236, 0 }, { 139, 9.61572319694108900419719561353e238, 0 }, { 140, 1.34620124757175246058760738589e241, 0 }, { 141, 1.89814375907617096942852641411e243, 0 }, { 142, 2.69536413788816277658850750804e245, 0 }, { 143, 3.85437071718007277052156573649e247, 0 }, { 144, 5.55029383273930478955105466055e249, 0 }, { 145, 8.04792605747199194484902925780e251, 0 }, { 146, 1.17499720439091082394795827164e254, 0 }, { 147, 1.72724589045463891120349865931e256, 0 }, { 148, 2.55632391787286558858117801578e258, 0 }, { 149, 3.80892263763056972698595524351e260, 0 }, { 150, 5.71338395644585459047893286526e262, 0 }, { 151, 8.62720977423324043162318862650e264, 0 }, { 152, 1.31133588568345254560672467123e267, 0 }, { 153, 2.00634390509568239477828874699e269, 0 }, { 154, 3.08976961384735088795856467036e271, 0 }, { 155, 4.78914290146339387633577523906e273, 0 }, { 156, 7.47106292628289444708380937294e275, 0 }, { 157, 1.17295687942641442819215807155e278, 0 }, { 158, 1.85327186949373479654360975305e280, 0 }, { 159, 2.94670227249503832650433950735e282, 0 }, { 160, 4.71472363599206132240694321176e284, 0 }, { 161, 7.59070505394721872907517857094e286, 0 }, { 162, 1.22969421873944943411017892849e289, 0 }, { 163, 2.00440157654530257759959165344e291, 0 }, { 164, 3.28721858553429622726333031164e293, 0 }, { 165, 5.42391066613158877498449501421e295, 0 }, { 166, 9.00369170577843736647426172359e297, 0 }, { 167, 1.50361651486499904020120170784e300, 0 }, { 168, 2.52607574497319838753801886917e302, 0 }, { 169, 4.26906800900470527493925188890e304, 0 }, { 170, 7.25741561530799896739672821113e306, 0 }, /* { 171, 1.24101807021766782342484052410e309, 0 }, { 172, 2.13455108077438865629072570146e311, 0 }, { 173, 3.69277336973969237538295546352e313, 0 }, { 174, 6.42542566334706473316634250653e315, 0 }, { 175, 1.12444949108573632830410993864e318, 0 }, { 176, 1.97903110431089593781523349201e320, 0 }, { 177, 3.50288505463028580993296328086e322, 0 }, { 178, 6.23513539724190874168067463993e324, 0 }, { 179, 1.11608923610630166476084076055e327, 0 }, { 180, 2.00896062499134299656951336898e329, 0 }, { 181, 3.63621873123433082379081919786e331, 0 }, { 182, 6.61791809084648209929929094011e333, 0 }, { 183, 1.21107901062490622417177024204e336, 0 }, { 184, 2.22838537954982745247605724535e338, 0 }, { 185, 4.12251295216718078708070590390e340, 0 }, { 186, 7.66787409103095626397011298130e342, 0 }, { 187, 1.43389245502278882136241112750e345, 0 }, { 188, 2.69571781544284298416133291969e347, 0 }, { 189, 5.09490667118697324006491921822e349, 0 }, { 190, 9.68032267525524915612334651460e351, 0 }, { 191, 1.84894163097375258881955918429e354, 0 }, { 192, 3.54996793146960497053355363384e356, 0 }, { 193, 6.85143810773633759312975851330e358, 0 }, { 194, 1.32917899290084949306717315158e361, 0 }, { 195, 2.59189903615665651148098764559e363, 0 }, { 196, 5.08012211086704676250273578535e365, 0 }, { 197, 1.00078405584080821221303894971e368, 0 }, { 198, 1.98155243056480026018181712043e370, 0 }, { 199, 3.94328933682395251776181606966e372, 0 }, { 200, 7.88657867364790503552363213932e374, 0 } */ }; static struct {int n; double f; long i; } doub_fact_table[GSL_SF_DOUBLEFACT_NMAX + 1] = { { 0, 1.000000000000000000000000000, 1L }, { 1, 1.000000000000000000000000000, 1L }, { 2, 2.000000000000000000000000000, 2L }, { 3, 3.000000000000000000000000000, 3L }, { 4, 8.000000000000000000000000000, 8L }, { 5, 15.00000000000000000000000000, 15L }, { 6, 48.00000000000000000000000000, 48L }, { 7, 105.0000000000000000000000000, 105L }, { 8, 384.0000000000000000000000000, 384L }, { 9, 945.0000000000000000000000000, 945L }, { 10, 3840.000000000000000000000000, 3840L }, { 11, 10395.00000000000000000000000, 10395L }, { 12, 46080.00000000000000000000000, 46080L }, { 13, 135135.0000000000000000000000, 135135L }, { 14, 645120.00000000000000000000000, 645120L }, { 15, 2.02702500000000000000000000000e6, 2027025L }, { 16, 1.03219200000000000000000000000e7, 10321920L }, { 17, 3.4459425000000000000000000000e7, 34459425L }, { 18, 1.85794560000000000000000000000e8, 185794560L }, { 19, 6.5472907500000000000000000000e8, 0 }, { 20, 3.7158912000000000000000000000e9, 0 }, { 21, 1.37493105750000000000000000000e10, 0 }, { 22, 8.1749606400000000000000000000e10, 0 }, { 23, 3.1623414322500000000000000000e11, 0 }, { 24, 1.96199055360000000000000000000e12, 0 }, { 25, 7.9058535806250000000000000000e12, 0 }, { 26, 5.1011754393600000000000000000e13, 0 }, { 27, 2.13458046676875000000000000000e14, 0 }, { 28, 1.42832912302080000000000000000e15, 0 }, { 29, 6.1902833536293750000000000000e15, 0 }, { 30, 4.2849873690624000000000000000e16, 0 }, { 31, 1.91898783962510625000000000000e17, 0 }, { 32, 1.37119595809996800000000000000e18, 0 }, { 33, 6.3326598707628506250000000000e18, 0 }, { 34, 4.6620662575398912000000000000e19, 0 }, { 35, 2.21643095476699771875000000000e20, 0 }, { 36, 1.67834385271436083200000000000e21, 0 }, { 37, 8.2007945326378915593750000000e21, 0 }, { 38, 6.3777066403145711616000000000e22, 0 }, { 39, 3.1983098677287777081562500000e23, 0 }, { 40, 2.55108265612582846464000000000e24, 0 }, { 41, 1.31130704576879886034406250000e25, 0 }, { 42, 1.07145471557284795514880000000e26, 0 }, { 43, 5.6386202968058350994794687500e26, 0 }, { 44, 4.7144007485205310026547200000e27, 0 }, { 45, 2.53737913356262579476576093750e28, 0 }, { 46, 2.16862434431944426122117120000e29, 0 }, { 47, 1.19256819277443412353990764062e30, 0 }, { 48, 1.04093968527333324538616217600e31, 0 }, { 49, 5.8435841445947272053455474391e31, 0 }, { 50, 5.2046984263666662269308108800e32, 0 }, { 51, 2.98022791374331087472622919392e33, 0 }, { 52, 2.70644318171066643800402165760e34, 0 }, { 53, 1.57952079428395476360490147278e35, 0 }, { 54, 1.46147931812375987652217169510e36, 0 }, { 55, 8.6873643685617511998269581003e36, 0 }, { 56, 8.1842841814930553085241614926e37, 0 }, { 57, 4.9517976900801981839013661172e38, 0 }, { 58, 4.7468848252659720789440136657e39, 0 }, { 59, 2.92156063714731692850180600912e40, 0 }, { 60, 2.84813089515958324736640819942e41, 0 }, { 61, 1.78215198865986332638610166557e42, 0 }, { 62, 1.76584115499894161336717308364e43, 0 }, { 63, 1.12275575285571389562324404931e44, 0 }, { 64, 1.13013833919932263255499077353e45, 0 }, { 65, 7.2979123935621403215510863205e45, 0 }, { 66, 7.4589130387155293748629391053e46, 0 }, { 67, 4.8896013036866340154392278347e47, 0 }, { 68, 5.0720608663265599749067985916e48, 0 }, { 69, 3.3738248995437774706530672060e49, 0 }, { 70, 3.5504426064285919824347590141e50, 0 }, { 71, 2.39541567867608200416367771623e51, 0 }, { 72, 2.55631867662858622735302649017e52, 0 }, { 73, 1.74865344543353986303948473285e53, 0 }, { 74, 1.89167582070515380824123960272e54, 0 }, { 75, 1.31149008407515489727961354964e55, 0 }, { 76, 1.43767362373591689426334209807e56, 0 }, { 77, 1.00984736473786927090530243322e57, 0 }, { 78, 1.12138542651401517752540683649e58, 0 }, { 79, 7.9777941814291672401518892225e58, 0 }, { 80, 8.9710834121121214202032546920e59, 0 }, { 81, 6.4620132869576254645230302702e60, 0 }, { 82, 7.3562883979319395645666688474e61, 0 }, { 83, 5.3634710281748291355541151243e62, 0 }, { 84, 6.1792822542628292342360018318e63, 0 }, { 85, 4.5589503739486047652209978556e64, 0 }, { 86, 5.3141827386660331414429615754e65, 0 }, { 87, 3.9662868253352861457422681344e66, 0 }, { 88, 4.6764808100261091644698061863e67, 0 }, { 89, 3.5299952745484046697106186396e68, 0 }, { 90, 4.2088327290234982480228255677e69, 0 }, { 91, 3.2122956998390482494366629620e70, 0 }, { 92, 3.8721261107016183881809995223e71, 0 }, { 93, 2.98743500085031487197609655470e72, 0 }, { 94, 3.6397985440595212848901395509e73, 0 }, { 95, 2.83806325080779912837729172696e74, 0 }, { 96, 3.4942066022971404334945339689e75, 0 }, { 97, 2.75292135328356515452597297515e76, 0 }, { 98, 3.4243224702511976248246432895e77, 0 }, { 99, 2.72539213975072950298071324540e78, 0 }, { 100, 3.4243224702511976248246432895e79, 0 }, { 101, 2.75264606114823679801052037785e80, 0 }, { 102, 3.4928089196562215773211361553e81, 0 }, { 103, 2.83522544298268390195083598919e82, 0 }, { 104, 3.6325212764424704404139816015e83, 0 }, { 105, 2.97698671513181809704837778865e84, 0 }, { 106, 3.8504725530290186668388204976e85, 0 }, { 107, 3.1853757851910453638417642339e86, 0 }, { 108, 4.1585103572713401601859261374e87, 0 }, { 109, 3.4720596058582394465875230149e88, 0 }, { 110, 4.5743613929984741762045187512e89, 0 }, { 111, 3.8539861625026457857121505465e90, 0 }, { 112, 5.1232847601582910773490610013e91, 0 }, { 113, 4.3550043636279897378547301176e92, 0 }, { 114, 5.8405446265804518281779295415e93, 0 }, { 115, 5.0082550181721881985329396352e94, 0 }, { 116, 6.7750317668333241206863982681e95, 0 }, { 117, 5.8596583712614601922835393732e96, 0 }, { 118, 7.9945374848633224624099499564e97, 0 }, { 119, 6.9729934618011376288174118541e98, 0 }, { 120, 9.5934449818359869548919399477e99, 0 }, { 121, 8.4373220887793765308690683435e100, 0 }, { 122, 1.17040028778399040849681667362e102, 0 }, { 123, 1.03779061691986331329689540625e103, 0 }, { 124, 1.45129635685214810653605267528e104, 0 }, { 125, 1.29723827114982914162111925781e105, 0 }, { 126, 1.82863340963370661423542637086e106, 0 }, { 127, 1.64749260436028300985882145742e107, 0 }, { 128, 2.34065076433114446622134575470e108, 0 }, { 129, 2.12526545962476508271787968008e109, 0 }, { 130, 3.04284599363048780608774948111e110, 0 }, { 131, 2.78409775210844225836042238090e111, 0 }, { 132, 4.0165567115922439040358293151e112, 0 }, { 133, 3.7028500103042282036193617666e113, 0 }, { 134, 5.3821859935336068314080112822e114, 0 }, { 135, 4.9988475139107080748861383849e115, 0 }, { 136, 7.3197729512057052907148953438e116, 0 }, { 137, 6.8484210940576700625940095873e117, 0 }, { 138, 1.01012866726638733011865555744e119, 0 }, { 139, 9.5193053207401613870056733264e119, 0 }, { 140, 1.41418013417294226216611778042e121, 0 }, { 141, 1.34222205022436275556779993902e122, 0 }, { 142, 2.00813579052557801227588724819e123, 0 }, { 143, 1.91937753182083874046195391280e124, 0 }, { 144, 2.89171553835683233767727763739e125, 0 }, { 145, 2.78309742114021617366983317355e126, 0 }, { 146, 4.2219046860009752130088253506e127, 0 }, { 147, 4.0911532090761177752946547651e128, 0 }, { 148, 6.2484189352814433152530615189e129, 0 }, { 149, 6.0958182815234154851890356000e130, 0 }, { 150, 9.3726284029221649728795922783e131, 0 }, { 151, 9.2046856051003573826354437561e132, 0 }, { 152, 1.42463951724416907587769802630e134, 0 }, { 153, 1.40831689758035467954322289468e135, 0 }, { 154, 2.19394485655602037685165496051e136, 0 }, { 155, 2.18289119124954975329199548675e137, 0 }, { 156, 3.4225539762273917878885817384e138, 0 }, { 157, 3.4271391702617931126684329142e139, 0 }, { 158, 5.4076352824392790248639591467e140, 0 }, { 159, 5.4491512807162510491428083336e141, 0 }, { 160, 8.6522164519028464397823346347e142, 0 }, { 161, 8.7731335619531641891199214170e143, 0 }, { 162, 1.40165906520826112324473821082e145, 0 }, { 163, 1.43002077059836576282654719098e146, 0 }, { 164, 2.29872086694154824212137066574e147, 0 }, { 165, 2.35953427148730350866380286512e148, 0 }, { 166, 3.8158766391229700819214753051e149, 0 }, { 167, 3.9404222333837968594685507847e150, 0 }, { 168, 6.4106727537265897376280785126e151, 0 }, { 169, 6.6593135744186166925018508262e152, 0 }, { 170, 1.08981436813352025539677334714e154, 0 }, { 171, 1.13874262122558345441781649128e155, 0 }, { 172, 1.87448071318965483928245015709e156, 0 }, { 173, 1.97002473472025937614282252992e157, 0 }, { 174, 3.2615964409499994203514632733e158, 0 }, { 175, 3.4475432857604539082499394274e159, 0 }, { 176, 5.7404097360719989798185753611e160, 0 }, { 177, 6.1021516157960034176023927864e161, 0 }, { 178, 1.02179293302081581840770641427e163, 0 }, { 179, 1.09228513922748461175082830877e164, 0 }, { 180, 1.83922727943746847313387154568e165, 0 }, { 181, 1.97703610200174714726899923887e166, 0 }, { 182, 3.3473936485761926211036462131e167, 0 }, { 183, 3.6179760666631972795022686071e168, 0 }, { 184, 6.1592043133801944228307090322e169, 0 }, { 185, 6.6932557233269149670791969232e170, 0 }, { 186, 1.14561200228871616264651187999e172, 0 }, { 187, 1.25163882026213309884380982464e173, 0 }, { 188, 2.15375056430278638577544233437e174, 0 }, { 189, 2.36559737029543155681480056857e175, 0 }, { 190, 4.0921260721752941329733404353e176, 0 }, { 191, 4.5182909772642742735162690860e177, 0 }, { 192, 7.8568820585765647353088136358e178, 0 }, { 193, 8.7203015861200493478863993359e179, 0 }, { 194, 1.52423511936385355864990984535e181, 0 }, { 195, 1.70045880929340962283784787050e182, 0 }, { 196, 2.98750083395315297495382329688e183, 0 }, { 197, 3.3499038543080169569905603049e184, 0 }, { 198, 5.9152516512272428904085701278e185, 0 }, { 199, 6.6663086700729537444112150067e186, 0 }, { 200, 1.18305033024544857808171402556e188, 0 }, { 201, 1.33992804268466370262665421635e189, 0 }, { 202, 2.38976166709580612772506233164e190, 0 }, { 203, 2.72005392664986731633210805920e191, 0 }, { 204, 4.8751138008754445005591271565e192, 0 }, { 205, 5.5761105496322279984808215214e193, 0 }, { 206, 1.00427344298034156711518019425e195, 0 }, { 207, 1.15425488377387119568553005492e196, 0 }, { 208, 2.08888876139911045959957480403e197, 0 }, { 209, 2.41239270708739079898275781478e198, 0 }, { 210, 4.3866663989381319651591070885e199, 0 }, { 211, 5.0901486119543945858536189892e200, 0 }, { 212, 9.2997327657488397661373070276e201, 0 }, { 213, 1.08420165434628604678682084470e203, 0 }, { 214, 1.99014281187025170995338370390e204, 0 }, { 215, 2.33103355684451500059166481610e205, 0 }, { 216, 4.2987084736397436934993088004e206, 0 }, { 217, 5.0583428183525975512839126509e207, 0 }, { 218, 9.3711844725346412518284931849e208, 0 }, { 219, 1.10777707721921886373117687056e210, 0 }, { 220, 2.06166058395762107540226850068e211, 0 }, { 221, 2.44818734065447368884590088393e212, 0 }, { 222, 4.5768864963859187873930360715e213, 0 }, { 223, 5.4594577696594763261263589712e214, 0 }, { 224, 1.02522257519044580837604008002e216, 0 }, { 225, 1.22837799817338217337843076851e217, 0 }, { 226, 2.31700301993040752692985058084e218, 0 }, { 227, 2.78841805585357753356903784452e219, 0 }, { 228, 5.2827668854413291614000593243e220, 0 }, { 229, 6.3854773479046925518730966640e221, 0 }, { 230, 1.21503638365150570712201364459e223, 0 }, { 231, 1.47504526736598397948268532937e224, 0 }, { 232, 2.81888441007149324052307165546e225, 0 }, { 233, 3.4368554729627426721946568174e226, 0 }, { 234, 6.5961895195672941828239876738e227, 0 }, { 235, 8.0766103614624452796574435210e228, 0 }, { 236, 1.55670072661788142714646109101e230, 0 }, { 237, 1.91415665566659953127881411447e231, 0 }, { 238, 3.7049477293505577966085773966e232, 0 }, { 239, 4.5748344070431728797563657336e233, 0 }, { 240, 8.8918745504413387118605857518e234, 0 }, { 241, 1.10253509209740466402128414180e236, 0 }, { 242, 2.15183364120680396827026175195e237, 0 }, { 243, 2.67916027379669333357172046456e238, 0 }, { 244, 5.2504740845446016825794386748e239, 0 }, { 245, 6.5639426708018986672507151382e240, 0 }, { 246, 1.29161662479797201391454191399e242, 0 }, { 247, 1.62129383968806897081092663913e243, 0 }, { 248, 3.2032092294989705945080639467e244, 0 }, { 249, 4.0370216608232917373192073314e245, 0 }, { 250, 8.0080230737474264862701598667e246, 0 }, { 251, 1.01329243686664622606712104019e248, 0 }, { 252, 2.01802181458435147454008028642e249, 0 }, { 253, 2.56362986527261495194981623168e250, 0 }, { 254, 5.1257754090442527453318039275e251, 0 }, { 255, 6.5372561564451681274720313908e252, 0 }, { 256, 1.31219850471532870280494180544e254, 0 }, { 257, 1.68007483220640820876031206743e255, 0 }, { 258, 3.3854721421655480532367498580e256, 0 }, { 259, 4.3513938154145972606892082546e257, 0 }, { 260, 8.8022275696304249384155496309e258, 0 }, { 261, 1.13571378582320988503988335446e260, 0 }, { 262, 2.30618362324317133386487400329e261, 0 }, { 263, 2.98692725671504199765489322224e262, 0 }, { 264, 6.0883247653619723214032673687e263, 0 }, { 265, 7.9153572302948612937854670389e264, 0 }, { 266, 1.61949438758628463749326912007e266, 0 }, { 267, 2.11340038048872796544071969939e267, 0 }, { 268, 4.3402449587312428284819612418e268, 0 }, { 269, 5.6850470235146782270355359914e269, 0 }, { 270, 1.17186613885743556369012953528e271, 0 }, { 271, 1.54064774337247779952663025366e272, 0 }, { 272, 3.1874758976922247332371523360e273, 0 }, { 273, 4.2059683394068643927077005925e274, 0 }, { 274, 8.7336839596766957690697974006e275, 0 }, { 275, 1.15664129333688770799461766294e277, 0 }, { 276, 2.41049677287076803226326408256e278, 0 }, { 277, 3.2038963825431789511450909263e279, 0 }, { 278, 6.7011810285807351296918741495e280, 0 }, { 279, 8.9388709072954692736948036845e281, 0 }, { 280, 1.87633068800260583631372476186e283, 0 }, { 281, 2.51182272495002686590823983534e284, 0 }, { 282, 5.2912525401673484584047038284e285, 0 }, { 283, 7.1084583116085760305203187340e286, 0 }, { 284, 1.50271572140752696218693588728e288, 0 }, { 285, 2.02591061880844416869829083919e289, 0 }, { 286, 4.2977669632255271118546366376e290, 0 }, { 287, 5.8143634759802347641640947085e291, 0 }, { 288, 1.23775688540895180821413535163e293, 0 }, { 289, 1.68035104455828784684342337075e294, 0 }, { 290, 3.5894949676859602438209925197e295, 0 }, { 291, 4.8898215396646176343143620089e296, 0 }, { 292, 1.04813253056430039119572981576e298, 0 }, { 293, 1.43271771112173296685410806860e299, 0 }, { 294, 3.08150963985904315011544565835e300, 0 }, { 295, 4.2265172478091122522196188024e301, 0 }, { 296, 9.1212685339827677243417191487e302, 0 }, { 297, 1.25527562259930633890922678431e304, 0 }, /* { 298, 2.71813802312686478185383230631e305, 0 }, { 299, 3.7532741115719259533385880851e306, 0 }, { 300, 8.1544140693805943455614969189e307, } */ }; /* Chebyshev coefficients for Gamma*(3/4(t+1)+1/2), -1val = (zr+0.5)*log1_r.val - zi*log1_i.val - (zr+7.5) + LogRootTwoPi_ + logAg_r.val; yi->val = zi*log1_r.val + (zr+0.5)*log1_i.val - zi + logAg_i.val; yr->err = 4.0 * GSL_DBL_EPSILON * fabs(yr->val); yi->err = 4.0 * GSL_DBL_EPSILON * fabs(yi->val); yi_tmp_val = yi->val; yi_tmp_err = yi->err; gsl_sf_angle_restrict_symm_err_e(yi_tmp_val, yi); yi->err += yi_tmp_err; return GSL_SUCCESS; } /* Lanczos method for real x > 0; * gamma=7, truncated at 1/(z+8) * [J. SIAM Numer. Anal, Ser. B, 1 (1964) 86] */ static int lngamma_lanczos(double x, gsl_sf_result * result) { int k; double Ag; double term1, term2; x -= 1.0; /* Lanczos writes z! instead of Gamma(z) */ Ag = lanczos_7_c[0]; for(k=1; k<=8; k++) { Ag += lanczos_7_c[k]/(x+k); } /* (x+0.5)*log(x+7.5) - (x+7.5) + LogRootTwoPi_ + log(Ag(x)) */ term1 = (x+0.5)*log((x+7.5)/M_E); term2 = LogRootTwoPi_ + log(Ag); result->val = term1 + (term2 - 7.0); result->err = 2.0 * GSL_DBL_EPSILON * (fabs(term1) + fabs(term2) + 7.0); result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } /* x = eps near zero * gives double-precision for |eps| < 0.02 */ static int lngamma_sgn_0(double eps, gsl_sf_result * lng, double * sgn) { /* calculate series for g(eps) = Gamma(eps) eps - 1/(1+eps) - eps/2 */ const double c1 = -0.07721566490153286061; const double c2 = -0.01094400467202744461; const double c3 = 0.09252092391911371098; const double c4 = -0.01827191316559981266; const double c5 = 0.01800493109685479790; const double c6 = -0.00685088537872380685; const double c7 = 0.00399823955756846603; const double c8 = -0.00189430621687107802; const double c9 = 0.00097473237804513221; const double c10 = -0.00048434392722255893; const double g6 = c6+eps*(c7+eps*(c8 + eps*(c9 + eps*c10))); const double g = eps*(c1+eps*(c2+eps*(c3+eps*(c4+eps*(c5+eps*g6))))); /* calculate Gamma(eps) eps, a positive quantity */ const double gee = g + 1.0/(1.0+eps) + 0.5*eps; lng->val = log(gee/fabs(eps)); lng->err = 4.0 * GSL_DBL_EPSILON * fabs(lng->val); *sgn = GSL_SIGN(eps); return GSL_SUCCESS; } /* x near a negative integer * Calculates sign as well as log(|gamma(x)|). * x = -N + eps * assumes N >= 1 */ static int lngamma_sgn_sing(int N, double eps, gsl_sf_result * lng, double * sgn) { if(eps == 0.0) { lng->val = 0.0; lng->err = 0.0; *sgn = 0.0; GSL_ERROR ("error", GSL_EDOM); } else if(N == 1) { /* calculate series for * g = eps gamma(-1+eps) + 1 + eps/2 (1+3eps)/(1-eps^2) * double-precision for |eps| < 0.02 */ const double c0 = 0.07721566490153286061; const double c1 = 0.08815966957356030521; const double c2 = -0.00436125434555340577; const double c3 = 0.01391065882004640689; const double c4 = -0.00409427227680839100; const double c5 = 0.00275661310191541584; const double c6 = -0.00124162645565305019; const double c7 = 0.00065267976121802783; const double c8 = -0.00032205261682710437; const double c9 = 0.00016229131039545456; const double g5 = c5 + eps*(c6 + eps*(c7 + eps*(c8 + eps*c9))); const double g = eps*(c0 + eps*(c1 + eps*(c2 + eps*(c3 + eps*(c4 + eps*g5))))); /* calculate eps gamma(-1+eps), a negative quantity */ const double gam_e = g - 1.0 - 0.5*eps*(1.0+3.0*eps)/(1.0 - eps*eps); lng->val = log(fabs(gam_e)/fabs(eps)); lng->err = 2.0 * GSL_DBL_EPSILON * fabs(lng->val); *sgn = ( eps > 0.0 ? -1.0 : 1.0 ); return GSL_SUCCESS; } else { double g; /* series for sin(Pi(N+1-eps))/(Pi eps) modulo the sign * double-precision for |eps| < 0.02 */ const double cs1 = -1.6449340668482264365; const double cs2 = 0.8117424252833536436; const double cs3 = -0.1907518241220842137; const double cs4 = 0.0261478478176548005; const double cs5 = -0.0023460810354558236; const double e2 = eps*eps; const double sin_ser = 1.0 + e2*(cs1+e2*(cs2+e2*(cs3+e2*(cs4+e2*cs5)))); /* calculate series for ln(gamma(1+N-eps)) * double-precision for |eps| < 0.02 */ double aeps = fabs(eps); double c1, c2, c3, c4, c5, c6, c7; double lng_ser; gsl_sf_result c0; gsl_sf_result psi_0; gsl_sf_result psi_1; gsl_sf_result psi_2; gsl_sf_result psi_3; gsl_sf_result psi_4; gsl_sf_result psi_5; gsl_sf_result psi_6; psi_2.val = 0.0; psi_3.val = 0.0; psi_4.val = 0.0; psi_5.val = 0.0; psi_6.val = 0.0; gsl_sf_lnfact_e(N, &c0); gsl_sf_psi_int_e(N+1, &psi_0); gsl_sf_psi_1_int_e(N+1, &psi_1); if(aeps > 0.00001) gsl_sf_psi_n_e(2, N+1.0, &psi_2); if(aeps > 0.0002) gsl_sf_psi_n_e(3, N+1.0, &psi_3); if(aeps > 0.001) gsl_sf_psi_n_e(4, N+1.0, &psi_4); if(aeps > 0.005) gsl_sf_psi_n_e(5, N+1.0, &psi_5); if(aeps > 0.01) gsl_sf_psi_n_e(6, N+1.0, &psi_6); c1 = psi_0.val; c2 = psi_1.val/2.0; c3 = psi_2.val/6.0; c4 = psi_3.val/24.0; c5 = psi_4.val/120.0; c6 = psi_5.val/720.0; c7 = psi_6.val/5040.0; lng_ser = c0.val-eps*(c1-eps*(c2-eps*(c3-eps*(c4-eps*(c5-eps*(c6-eps*c7)))))); /* calculate * g = ln(|eps gamma(-N+eps)|) * = -ln(gamma(1+N-eps)) + ln(|eps Pi/sin(Pi(N+1+eps))|) */ g = -lng_ser - log(sin_ser); lng->val = g - log(fabs(eps)); lng->err = c0.err + 2.0 * GSL_DBL_EPSILON * (fabs(g) + fabs(lng->val)); *sgn = ( GSL_IS_ODD(N) ? -1.0 : 1.0 ) * ( eps > 0.0 ? 1.0 : -1.0 ); return GSL_SUCCESS; } } /* This gets bad near the negative half axis. However, this * region can be avoided by use of the reflection formula, as usual. * Only the first two terms of the series are kept. */ #if 0 static int lngamma_complex_stirling(const double zr, const double zi, double * lg_r, double * arg) { double re_zinv, im_zinv; double re_zinv2, im_zinv2; double re_zinv3, im_zinv3; double re_zhlnz, im_zhlnz; double r, lnr, theta; gsl_sf_complex_log_e(zr, zi, &lnr, &theta); /* z = r e^{i theta} */ r = exp(lnr); re_zinv = (zr/r)/r; im_zinv = -(zi/r)/r; re_zinv2 = re_zinv*re_zinv - im_zinv*im_zinv; re_zinv2 = 2.0*re_zinv*im_zinv; re_zinv3 = re_zinv2*re_zinv - im_zinv2*im_zinv; re_zinv3 = re_zinv2*im_zinv + im_zinv2*re_zinv; re_zhlnz = (zr - 0.5)*lnr - zi*theta; im_zhlnz = zi*lnr + zr*theta; *lg_r = re_zhlnz - zr + 0.5*(M_LN2+M_LNPI) + re_zinv/12.0 - re_zinv3/360.0; *arg = im_zhlnz - zi + 1.0/12.0*im_zinv - im_zinv3/360.0; return GSL_SUCCESS; } #endif /* 0 */ inline static int lngamma_1_pade(const double eps, gsl_sf_result * result) { /* Use (2,2) Pade for Log[Gamma[1+eps]]/eps * plus a correction series. */ const double n1 = -1.0017419282349508699871138440; const double n2 = 1.7364839209922879823280541733; const double d1 = 1.2433006018858751556055436011; const double d2 = 5.0456274100274010152489597514; const double num = (eps + n1) * (eps + n2); const double den = (eps + d1) * (eps + d2); const double pade = 2.0816265188662692474880210318 * num / den; const double c0 = 0.004785324257581753; const double c1 = -0.01192457083645441; const double c2 = 0.01931961413960498; const double c3 = -0.02594027398725020; const double c4 = 0.03141928755021455; const double eps5 = eps*eps*eps*eps*eps; const double corr = eps5 * (c0 + eps*(c1 + eps*(c2 + eps*(c3 + c4*eps)))); result->val = eps * (pade + corr); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } inline static int lngamma_2_pade(const double eps, gsl_sf_result * result) { /* Use (2,2) Pade for Log[Gamma[2+eps]]/eps * plus a correction series. */ const double n1 = 1.000895834786669227164446568; const double n2 = 4.209376735287755081642901277; const double d1 = 2.618851904903217274682578255; const double d2 = 10.85766559900983515322922936; const double num = (eps + n1) * (eps + n2); const double den = (eps + d1) * (eps + d2); const double pade = 2.85337998765781918463568869 * num/den; const double c0 = 0.0001139406357036744; const double c1 = -0.0001365435269792533; const double c2 = 0.0001067287169183665; const double c3 = -0.0000693271800931282; const double c4 = 0.0000407220927867950; const double eps5 = eps*eps*eps*eps*eps; const double corr = eps5 * (c0 + eps*(c1 + eps*(c2 + eps*(c3 + c4*eps)))); result->val = eps * (pade + corr); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } /* series for gammastar(x) * double-precision for x > 10.0 */ static int gammastar_ser(const double x, gsl_sf_result * result) { /* Use the Stirling series for the correction to Log(Gamma(x)), * which is better behaved and easier to compute than the * regular Stirling series for Gamma(x). */ const double y = 1.0/(x*x); const double c0 = 1.0/12.0; const double c1 = -1.0/360.0; const double c2 = 1.0/1260.0; const double c3 = -1.0/1680.0; const double c4 = 1.0/1188.0; const double c5 = -691.0/360360.0; const double c6 = 1.0/156.0; const double c7 = -3617.0/122400.0; const double ser = c0 + y*(c1 + y*(c2 + y*(c3 + y*(c4 + y*(c5 + y*(c6 + y*c7)))))); result->val = exp(ser/x); result->err = 2.0 * GSL_DBL_EPSILON * result->val * GSL_MAX_DBL(1.0, ser/x); return GSL_SUCCESS; } /* Chebyshev expansion for log(gamma(x)/gamma(8)) * 5 < x < 10 * -1 < t < 1 */ static double gamma_5_10_data[24] = { -1.5285594096661578881275075214, 4.8259152300595906319768555035, 0.2277712320977614992970601978, -0.0138867665685617873604917300, 0.0012704876495201082588139723, -0.0001393841240254993658962470, 0.0000169709242992322702260663, -2.2108528820210580075775889168e-06, 3.0196602854202309805163918716e-07, -4.2705675000079118380587357358e-08, 6.2026423818051402794663551945e-09, -9.1993973208880910416311405656e-10, 1.3875551258028145778301211638e-10, -2.1218861491906788718519522978e-11, 3.2821736040381439555133562600e-12, -5.1260001009953791220611135264e-13, 8.0713532554874636696982146610e-14, -1.2798522376569209083811628061e-14, 2.0417711600852502310258808643e-15, -3.2745239502992355776882614137e-16, 5.2759418422036579482120897453e-17, -8.5354147151695233960425725513e-18, 1.3858639703888078291599886143e-18, -2.2574398807738626571560124396e-19 }; static const cheb_series gamma_5_10_cs = { gamma_5_10_data, 23, -1, 1, 11 }; /* gamma(x) for x >= 1/2 * assumes x >= 1/2 */ static int gamma_xgthalf(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x == 0.5) { result->val = 1.77245385090551602729817; result->err = GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; } else if (x <= (GSL_SF_FACT_NMAX + 1.0) && x == floor(x)) { int n = (int) floor (x); result->val = fact_table[n - 1].f; result->err = GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; } else if(fabs(x - 1.0) < 0.01) { /* Use series for Gamma[1+eps] - 1/(1+eps). */ const double eps = x - 1.0; const double c1 = 0.4227843350984671394; const double c2 = -0.01094400467202744461; const double c3 = 0.09252092391911371098; const double c4 = -0.018271913165599812664; const double c5 = 0.018004931096854797895; const double c6 = -0.006850885378723806846; const double c7 = 0.003998239557568466030; result->val = 1.0/x + eps*(c1+eps*(c2+eps*(c3+eps*(c4+eps*(c5+eps*(c6+eps*c7)))))); result->err = GSL_DBL_EPSILON; return GSL_SUCCESS; } else if(fabs(x - 2.0) < 0.01) { /* Use series for Gamma[1 + eps]. */ const double eps = x - 2.0; const double c1 = 0.4227843350984671394; const double c2 = 0.4118403304264396948; const double c3 = 0.08157691924708626638; const double c4 = 0.07424901075351389832; const double c5 = -0.00026698206874501476832; const double c6 = 0.011154045718130991049; const double c7 = -0.002852645821155340816; const double c8 = 0.0021039333406973880085; result->val = 1.0 + eps*(c1+eps*(c2+eps*(c3+eps*(c4+eps*(c5+eps*(c6+eps*(c7+eps*c8))))))); result->err = GSL_DBL_EPSILON; return GSL_SUCCESS; } else if(x < 5.0) { /* Exponentiating the logarithm is fine, as * long as the exponential is not so large * that it greatly amplifies the error. */ gsl_sf_result lg; lngamma_lanczos(x, &lg); result->val = exp(lg.val); result->err = result->val * (lg.err + 2.0 * GSL_DBL_EPSILON); return GSL_SUCCESS; } else if(x < 10.0) { /* This is a sticky area. The logarithm * is too large and the gammastar series * is not good. */ const double gamma_8 = 5040.0; const double t = (2.0*x - 15.0)/5.0; gsl_sf_result c; cheb_eval_e(&gamma_5_10_cs, t, &c); result->val = exp(c.val) * gamma_8; result->err = result->val * c.err; result->err += 2.0 * GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; } else if(x < GSL_SF_GAMMA_XMAX) { /* We do not want to exponentiate the logarithm * if x is large because of the inevitable * inflation of the error. So we carefully * use pow() and exp() with exact quantities. */ double p = pow(x, 0.5*x); double e = exp(-x); double q = (p * e) * p; double pre = M_SQRT2 * M_SQRTPI * q/sqrt(x); gsl_sf_result gstar; int stat_gs = gammastar_ser(x, &gstar); result->val = pre * gstar.val; result->err = (x + 2.5) * GSL_DBL_EPSILON * result->val; return stat_gs; } else { OVERFLOW_ERROR(result); } } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_lngamma_e(double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(fabs(x - 1.0) < 0.01) { /* Note that we must amplify the errors * from the Pade evaluations because of * the way we must pass the argument, i.e. * writing (1-x) is a loss of precision * when x is near 1. */ int stat = lngamma_1_pade(x - 1.0, result); result->err *= 1.0/(GSL_DBL_EPSILON + fabs(x - 1.0)); return stat; } else if(fabs(x - 2.0) < 0.01) { int stat = lngamma_2_pade(x - 2.0, result); result->err *= 1.0/(GSL_DBL_EPSILON + fabs(x - 2.0)); return stat; } else if(x >= 0.5) { return lngamma_lanczos(x, result); } else if(x == 0.0) { DOMAIN_ERROR(result); } else if(fabs(x) < 0.02) { double sgn; return lngamma_sgn_0(x, result, &sgn); } else if(x > -0.5/(GSL_DBL_EPSILON*M_PI)) { /* Try to extract a fractional * part from x. */ double z = 1.0 - x; double s = sin(M_PI*z); double as = fabs(s); if(s == 0.0) { DOMAIN_ERROR(result); } else if(as < M_PI*0.015) { /* x is near a negative integer, -N */ if(x < INT_MIN + 2.0) { result->val = 0.0; result->err = 0.0; GSL_ERROR ("error", GSL_EROUND); } else { int N = -(int)(x - 0.5); double eps = x + N; double sgn; return lngamma_sgn_sing(N, eps, result, &sgn); } } else { gsl_sf_result lg_z; lngamma_lanczos(z, &lg_z); result->val = M_LNPI - (log(as) + lg_z.val); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val) + lg_z.err; return GSL_SUCCESS; } } else { /* |x| was too large to extract any fractional part */ result->val = 0.0; result->err = 0.0; GSL_ERROR ("error", GSL_EROUND); } } int gsl_sf_lngamma_sgn_e(double x, gsl_sf_result * result_lg, double * sgn) { if(fabs(x - 1.0) < 0.01) { int stat = lngamma_1_pade(x - 1.0, result_lg); result_lg->err *= 1.0/(GSL_DBL_EPSILON + fabs(x - 1.0)); *sgn = 1.0; return stat; } else if(fabs(x - 2.0) < 0.01) { int stat = lngamma_2_pade(x - 2.0, result_lg); result_lg->err *= 1.0/(GSL_DBL_EPSILON + fabs(x - 2.0)); *sgn = 1.0; return stat; } else if(x >= 0.5) { *sgn = 1.0; return lngamma_lanczos(x, result_lg); } else if(x == 0.0) { *sgn = 0.0; DOMAIN_ERROR(result_lg); } else if(fabs(x) < 0.02) { return lngamma_sgn_0(x, result_lg, sgn); } else if(x > -0.5/(GSL_DBL_EPSILON*M_PI)) { /* Try to extract a fractional * part from x. */ double z = 1.0 - x; double s = sin(M_PI*x); double as = fabs(s); if(s == 0.0) { *sgn = 0.0; DOMAIN_ERROR(result_lg); } else if(as < M_PI*0.015) { /* x is near a negative integer, -N */ if(x < INT_MIN + 2.0) { result_lg->val = 0.0; result_lg->err = 0.0; *sgn = 0.0; GSL_ERROR ("error", GSL_EROUND); } else { int N = -(int)(x - 0.5); double eps = x + N; return lngamma_sgn_sing(N, eps, result_lg, sgn); } } else { gsl_sf_result lg_z; lngamma_lanczos(z, &lg_z); *sgn = (s > 0.0 ? 1.0 : -1.0); result_lg->val = M_LNPI - (log(as) + lg_z.val); result_lg->err = 2.0 * GSL_DBL_EPSILON * fabs(result_lg->val) + lg_z.err; return GSL_SUCCESS; } } else { /* |x| was too large to extract any fractional part */ result_lg->val = 0.0; result_lg->err = 0.0; *sgn = 0.0; GSL_ERROR ("x too large to extract fraction part", GSL_EROUND); } } int gsl_sf_gamma_e(const double x, gsl_sf_result * result) { if(x < 0.5) { int rint_x = (int)floor(x+0.5); double f_x = x - rint_x; double sgn_gamma = ( GSL_IS_EVEN(rint_x) ? 1.0 : -1.0 ); double sin_term = sgn_gamma * sin(M_PI * f_x) / M_PI; if(sin_term == 0.0) { DOMAIN_ERROR(result); } else if(x > -169.0) { gsl_sf_result g; gamma_xgthalf(1.0-x, &g); if(fabs(sin_term) * g.val * GSL_DBL_MIN < 1.0) { result->val = 1.0/(sin_term * g.val); result->err = fabs(g.err/g.val) * fabs(result->val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { UNDERFLOW_ERROR(result); } } else { /* It is hard to control it here. * We can only exponentiate the * logarithm and eat the loss of * precision. */ gsl_sf_result lng; double sgn; int stat_lng = gsl_sf_lngamma_sgn_e(x, &lng, &sgn); int stat_e = gsl_sf_exp_mult_err_e(lng.val, lng.err, sgn, 0.0, result); return GSL_ERROR_SELECT_2(stat_e, stat_lng); } } else { return gamma_xgthalf(x, result); } } int gsl_sf_gammastar_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= 0.0) { DOMAIN_ERROR(result); } else if(x < 0.5) { gsl_sf_result lg; const int stat_lg = gsl_sf_lngamma_e(x, &lg); const double lx = log(x); const double c = 0.5*(M_LN2+M_LNPI); const double lnr_val = lg.val - (x-0.5)*lx + x - c; const double lnr_err = lg.err + 2.0 * GSL_DBL_EPSILON *((x+0.5)*fabs(lx) + c); const int stat_e = gsl_sf_exp_err_e(lnr_val, lnr_err, result); return GSL_ERROR_SELECT_2(stat_lg, stat_e); } else if(x < 2.0) { const double t = 4.0/3.0*(x-0.5) - 1.0; return cheb_eval_e(&gstar_a_cs, t, result); } else if(x < 10.0) { const double t = 0.25*(x-2.0) - 1.0; gsl_sf_result c; cheb_eval_e(&gstar_b_cs, t, &c); result->val = c.val/(x*x) + 1.0 + 1.0/(12.0*x); result->err = c.err/(x*x); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < 1.0/GSL_ROOT4_DBL_EPSILON) { return gammastar_ser(x, result); } else if(x < 1.0/GSL_DBL_EPSILON) { /* Use Stirling formula for Gamma(x). */ const double xi = 1.0/x; result->val = 1.0 + xi/12.0*(1.0 + xi/24.0*(1.0 - xi*(139.0/180.0 + 571.0/8640.0*xi))); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { result->val = 1.0; result->err = 1.0/x; return GSL_SUCCESS; } } int gsl_sf_gammainv_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if (x <= 0.0 && x == floor(x)) { /* negative integer */ result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(x < 0.5) { gsl_sf_result lng; double sgn; int stat_lng = gsl_sf_lngamma_sgn_e(x, &lng, &sgn); if(stat_lng == GSL_EDOM) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(stat_lng != GSL_SUCCESS) { result->val = 0.0; result->err = 0.0; return stat_lng; } else { return gsl_sf_exp_mult_err_e(-lng.val, lng.err, sgn, 0.0, result); } } else { gsl_sf_result g; int stat_g = gamma_xgthalf(x, &g); if(stat_g == GSL_EOVRFLW) { UNDERFLOW_ERROR(result); } else { result->val = 1.0/g.val; result->err = fabs(g.err/g.val) * fabs(result->val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); CHECK_UNDERFLOW(result); return GSL_SUCCESS; } } } int gsl_sf_lngamma_complex_e(double zr, double zi, gsl_sf_result * lnr, gsl_sf_result * arg) { if(zr <= 0.5) { /* Transform to right half plane using reflection; * in fact we do a little better by stopping at 1/2. */ double x = 1.0-zr; double y = -zi; gsl_sf_result a, b; gsl_sf_result lnsin_r, lnsin_i; int stat_l = lngamma_lanczos_complex(x, y, &a, &b); int stat_s = gsl_sf_complex_logsin_e(M_PI*zr, M_PI*zi, &lnsin_r, &lnsin_i); if(stat_s == GSL_SUCCESS) { int stat_r; lnr->val = M_LNPI - lnsin_r.val - a.val; lnr->err = lnsin_r.err + a.err + 2.0 * GSL_DBL_EPSILON * fabs(lnr->val); arg->val = -lnsin_i.val - b.val; arg->err = lnsin_i.err + b.err + 2.0 * GSL_DBL_EPSILON * fabs(arg->val); stat_r = gsl_sf_angle_restrict_symm_e(&(arg->val)); return GSL_ERROR_SELECT_2(stat_r, stat_l); } else { DOMAIN_ERROR_2(lnr,arg); } } else { /* otherwise plain vanilla Lanczos */ return lngamma_lanczos_complex(zr, zi, lnr, arg); } } int gsl_sf_taylorcoeff_e(const int n, const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x < 0.0 || n < 0) { DOMAIN_ERROR(result); } else if(n == 0) { result->val = 1.0; result->err = 0.0; return GSL_SUCCESS; } else if(n == 1) { result->val = x; result->err = 0.0; return GSL_SUCCESS; } else if(x == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else { const double log2pi = M_LNPI + M_LN2; const double ln_test = n*(log(x)+1.0) + 1.0 - (n+0.5)*log(n+1.0) + 0.5*log2pi; if(ln_test < GSL_LOG_DBL_MIN+1.0) { UNDERFLOW_ERROR(result); } else if(ln_test > GSL_LOG_DBL_MAX-1.0) { OVERFLOW_ERROR(result); } else { double product = 1.0; int k; for(k=1; k<=n; k++) { product *= (x/k); } result->val = product; result->err = n * GSL_DBL_EPSILON * product; CHECK_UNDERFLOW(result); return GSL_SUCCESS; } } } int gsl_sf_fact_e(const unsigned int n, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(n < 18) { result->val = fact_table[n].f; result->err = 0.0; return GSL_SUCCESS; } else if(n <= GSL_SF_FACT_NMAX){ result->val = fact_table[n].f; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { OVERFLOW_ERROR(result); } } int gsl_sf_doublefact_e(const unsigned int n, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(n < 26) { result->val = doub_fact_table[n].f; result->err = 0.0; return GSL_SUCCESS; } else if(n <= GSL_SF_DOUBLEFACT_NMAX){ result->val = doub_fact_table[n].f; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { OVERFLOW_ERROR(result); } } int gsl_sf_lnfact_e(const unsigned int n, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(n <= GSL_SF_FACT_NMAX){ result->val = log(fact_table[n].f); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { gsl_sf_lngamma_e(n+1.0, result); return GSL_SUCCESS; } } int gsl_sf_lndoublefact_e(const unsigned int n, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(n <= GSL_SF_DOUBLEFACT_NMAX){ result->val = log(doub_fact_table[n].f); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(GSL_IS_ODD(n)) { gsl_sf_result lg; gsl_sf_lngamma_e(0.5*(n+2.0), &lg); result->val = 0.5*(n+1.0) * M_LN2 - 0.5*M_LNPI + lg.val; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val) + lg.err; return GSL_SUCCESS; } else { gsl_sf_result lg; gsl_sf_lngamma_e(0.5*n+1.0, &lg); result->val = 0.5*n*M_LN2 + lg.val; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val) + lg.err; return GSL_SUCCESS; } } int gsl_sf_lnchoose_e(unsigned int n, unsigned int m, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(m > n) { DOMAIN_ERROR(result); } else if(m == n || m == 0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else { gsl_sf_result nf; gsl_sf_result mf; gsl_sf_result nmmf; if(m*2 > n) m = n-m; gsl_sf_lnfact_e(n, &nf); gsl_sf_lnfact_e(m, &mf); gsl_sf_lnfact_e(n-m, &nmmf); result->val = nf.val - mf.val - nmmf.val; result->err = nf.err + mf.err + nmmf.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_choose_e(unsigned int n, unsigned int m, gsl_sf_result * result) { if(m > n) { DOMAIN_ERROR(result); } else if(m == n || m == 0) { result->val = 1.0; result->err = 0.0; return GSL_SUCCESS; } else if (n <= GSL_SF_FACT_NMAX) { result->val = (fact_table[n].f / fact_table[m].f) / fact_table[n-m].f; result->err = 6.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { if(m*2 < n) m = n-m; if (n - m < 64) /* compute product for a manageable number of terms */ { double prod = 1.0; unsigned int k; for(k=n; k>=m+1; k--) { double tk = (double)k / (double)(k-m); if(tk > GSL_DBL_MAX/prod) { OVERFLOW_ERROR(result); } prod *= tk; } result->val = prod; result->err = 2.0 * GSL_DBL_EPSILON * prod * fabs(n-m); return GSL_SUCCESS; } else { gsl_sf_result lc; const int stat_lc = gsl_sf_lnchoose_e (n, m, &lc); const int stat_e = gsl_sf_exp_err_e(lc.val, lc.err, result); return GSL_ERROR_SELECT_2(stat_lc, stat_e); } } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_fact(const unsigned int n) { EVAL_RESULT(gsl_sf_fact_e(n, &result)); } double gsl_sf_lnfact(const unsigned int n) { EVAL_RESULT(gsl_sf_lnfact_e(n, &result)); } double gsl_sf_doublefact(const unsigned int n) { EVAL_RESULT(gsl_sf_doublefact_e(n, &result)); } double gsl_sf_lndoublefact(const unsigned int n) { EVAL_RESULT(gsl_sf_lndoublefact_e(n, &result)); } double gsl_sf_lngamma(const double x) { EVAL_RESULT(gsl_sf_lngamma_e(x, &result)); } double gsl_sf_gamma(const double x) { EVAL_RESULT(gsl_sf_gamma_e(x, &result)); } double gsl_sf_gammastar(const double x) { EVAL_RESULT(gsl_sf_gammastar_e(x, &result)); } double gsl_sf_gammainv(const double x) { EVAL_RESULT(gsl_sf_gammainv_e(x, &result)); } double gsl_sf_taylorcoeff(const int n, const double x) { EVAL_RESULT(gsl_sf_taylorcoeff_e(n, x, &result)); } double gsl_sf_choose(unsigned int n, unsigned int m) { EVAL_RESULT(gsl_sf_choose_e(n, m, &result)); } double gsl_sf_lnchoose(unsigned int n, unsigned int m) { EVAL_RESULT(gsl_sf_lnchoose_e(n, m, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__gamma_inc.c000066400000000000000000000451631261542461700223110ustar00rootroot00000000000000/* specfunc/gamma_inc.c * * Copyright (C) 2007 Brian Gough * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_erf.h" #include "gsl_sf_exp.h" #include "gsl_sf_log.h" #include "gsl_sf_gamma.h" #include "gsl_sf_expint.h" #include "gsl_specfunc__error.h" /* The dominant part, * D(a,x) := x^a e^(-x) / Gamma(a+1) */ static int gamma_inc_D(const double a, const double x, gsl_sf_result * result) { if(a < 10.0) { double lnr; gsl_sf_result lg; gsl_sf_lngamma_e(a+1.0, &lg); lnr = a * log(x) - x - lg.val; result->val = exp(lnr); result->err = 2.0 * GSL_DBL_EPSILON * (fabs(lnr) + 1.0) * fabs(result->val); return GSL_SUCCESS; } else { gsl_sf_result gstar; gsl_sf_result ln_term; double term1; if (x < 0.5*a) { double u = x/a; double ln_u = log(u); ln_term.val = ln_u - u + 1.0; ln_term.err = (fabs(ln_u) + fabs(u) + 1.0) * GSL_DBL_EPSILON; } else { double mu = (x-a)/a; gsl_sf_log_1plusx_mx_e(mu, &ln_term); /* log(1+mu) - mu */ }; gsl_sf_gammastar_e(a, &gstar); term1 = exp(a*ln_term.val)/sqrt(2.0*M_PI*a); result->val = term1/gstar.val; result->err = 2.0 * GSL_DBL_EPSILON * (fabs(a*ln_term.val) + 1.0) * fabs(result->val); result->err += gstar.err/fabs(gstar.val) * fabs(result->val); return GSL_SUCCESS; } } /* P series representation. */ static int gamma_inc_P_series(const double a, const double x, gsl_sf_result * result) { const int nmax = 5000; gsl_sf_result D; int stat_D = gamma_inc_D(a, x, &D); double sum = 1.0; double term = 1.0; int n; for(n=1; nval = D.val * sum; result->err = D.err * fabs(sum); result->err += (1.0 + n) * GSL_DBL_EPSILON * fabs(result->val); if(n == nmax) GSL_ERROR ("error", GSL_EMAXITER); else return stat_D; } /* Q large x asymptotic */ static int gamma_inc_Q_large_x(const double a, const double x, gsl_sf_result * result) { const int nmax = 5000; gsl_sf_result D; const int stat_D = gamma_inc_D(a, x, &D); double sum = 1.0; double term = 1.0; double last = 1.0; int n; for(n=1; n 1.0) break; if(fabs(term/sum) < GSL_DBL_EPSILON) break; sum += term; last = term; } result->val = D.val * (a/x) * sum; result->err = D.err * fabs((a/x) * sum); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); if(n == nmax) GSL_ERROR ("error in large x asymptotic", GSL_EMAXITER); else return stat_D; } /* Uniform asymptotic for x near a, a and x large. * See [Temme, p. 285] */ static int gamma_inc_Q_asymp_unif(const double a, const double x, gsl_sf_result * result) { const double rta = sqrt(a); const double eps = (x-a)/a; gsl_sf_result ln_term; const int stat_ln = gsl_sf_log_1plusx_mx_e(eps, &ln_term); /* log(1+eps) - eps */ const double eta = GSL_SIGN(eps) * sqrt(-2.0*ln_term.val); gsl_sf_result erfc; double R; double c0, c1; /* This used to say erfc(eta*M_SQRT2*rta), which is wrong. * The sqrt(2) is in the denominator. Oops. * Fixed: [GJ] Mon Nov 15 13:25:32 MST 2004 */ gsl_sf_erfc_e(eta*rta/M_SQRT2, &erfc); if(fabs(eps) < GSL_ROOT5_DBL_EPSILON) { c0 = -1.0/3.0 + eps*(1.0/12.0 - eps*(23.0/540.0 - eps*(353.0/12960.0 - eps*589.0/30240.0))); c1 = -1.0/540.0 - eps/288.0; } else { const double rt_term = sqrt(-2.0 * ln_term.val/(eps*eps)); const double lam = x/a; c0 = (1.0 - 1.0/rt_term)/eps; c1 = -(eta*eta*eta * (lam*lam + 10.0*lam + 1.0) - 12.0 * eps*eps*eps) / (12.0 * eta*eta*eta*eps*eps*eps); } R = exp(-0.5*a*eta*eta)/(M_SQRT2*M_SQRTPI*rta) * (c0 + c1/a); result->val = 0.5 * erfc.val + R; result->err = GSL_DBL_EPSILON * fabs(R * 0.5 * a*eta*eta) + 0.5 * erfc.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_ln; } /* Continued fraction which occurs in evaluation * of Q(a,x) or Gamma(a,x). * * 1 (1-a)/x 1/x (2-a)/x 2/x (3-a)/x * F(a,x) = ---- ------- ----- -------- ----- -------- ... * 1 + 1 + 1 + 1 + 1 + 1 + * * Hans E. Plesser, 2002-01-22 (hans dot plesser at itf dot nlh dot no). * * Split out from gamma_inc_Q_CF() by GJ [Tue Apr 1 13:16:41 MST 2003]. * See gamma_inc_Q_CF() below. * */ static int gamma_inc_F_CF(const double a, const double x, gsl_sf_result * result) { const int nmax = 5000; const double small = gsl_pow_3 (GSL_DBL_EPSILON); double hn = 1.0; /* convergent */ double Cn = 1.0 / small; double Dn = 1.0; int n; /* n == 1 has a_1, b_1, b_0 independent of a,x, so that has been done by hand */ for ( n = 2 ; n < nmax ; n++ ) { double an; double delta; if(GSL_IS_ODD(n)) an = 0.5*(n-1)/x; else an = (0.5*n-a)/x; Dn = 1.0 + an * Dn; if ( fabs(Dn) < small ) Dn = small; Cn = 1.0 + an/Cn; if ( fabs(Cn) < small ) Cn = small; Dn = 1.0 / Dn; delta = Cn * Dn; hn *= delta; if(fabs(delta-1.0) < GSL_DBL_EPSILON) break; } result->val = hn; result->err = 2.0*GSL_DBL_EPSILON * fabs(hn); result->err += GSL_DBL_EPSILON * (2.0 + 0.5*n) * fabs(result->val); if(n == nmax) GSL_ERROR ("error in CF for F(a,x)", GSL_EMAXITER); else return GSL_SUCCESS; } /* Continued fraction for Q. * * Q(a,x) = D(a,x) a/x F(a,x) * * Hans E. Plesser, 2002-01-22 (hans dot plesser at itf dot nlh dot no): * * Since the Gautschi equivalent series method for CF evaluation may lead * to singularities, I have replaced it with the modified Lentz algorithm * given in * * I J Thompson and A R Barnett * Coulomb and Bessel Functions of Complex Arguments and Order * J Computational Physics 64:490-509 (1986) * * In consequence, gamma_inc_Q_CF_protected() is now obsolete and has been * removed. * * Identification of terms between the above equation for F(a, x) and * the first equation in the appendix of Thompson&Barnett is as follows: * * b_0 = 0, b_n = 1 for all n > 0 * * a_1 = 1 * a_n = (n/2-a)/x for n even * a_n = (n-1)/(2x) for n odd * */ static int gamma_inc_Q_CF(const double a, const double x, gsl_sf_result * result) { gsl_sf_result D; gsl_sf_result F; const int stat_D = gamma_inc_D(a, x, &D); const int stat_F = gamma_inc_F_CF(a, x, &F); result->val = D.val * (a/x) * F.val; result->err = D.err * fabs((a/x) * F.val) + fabs(D.val * a/x * F.err); return GSL_ERROR_SELECT_2(stat_F, stat_D); } /* Useful for small a and x. Handles the subtraction analytically. */ static int gamma_inc_Q_series(const double a, const double x, gsl_sf_result * result) { double term1; /* 1 - x^a/Gamma(a+1) */ double sum; /* 1 + (a+1)/(a+2)(-x)/2! + (a+1)/(a+3)(-x)^2/3! + ... */ int stat_sum; double term2; /* a temporary variable used at the end */ { /* Evaluate series for 1 - x^a/Gamma(a+1), small a */ const double pg21 = -2.404113806319188570799476; /* PolyGamma[2,1] */ const double lnx = log(x); const double el = M_EULER+lnx; const double c1 = -el; const double c2 = M_PI*M_PI/12.0 - 0.5*el*el; const double c3 = el*(M_PI*M_PI/12.0 - el*el/6.0) + pg21/6.0; const double c4 = -0.04166666666666666667 * (-1.758243446661483480 + lnx) * (-0.764428657272716373 + lnx) * ( 0.723980571623507657 + lnx) * ( 4.107554191916823640 + lnx); const double c5 = -0.0083333333333333333 * (-2.06563396085715900 + lnx) * (-1.28459889470864700 + lnx) * (-0.27583535756454143 + lnx) * ( 1.33677371336239618 + lnx) * ( 5.17537282427561550 + lnx); const double c6 = -0.0013888888888888889 * (-2.30814336454783200 + lnx) * (-1.65846557706987300 + lnx) * (-0.88768082560020400 + lnx) * ( 0.17043847751371778 + lnx) * ( 1.92135970115863890 + lnx) * ( 6.22578557795474900 + lnx); const double c7 = -0.00019841269841269841 * (-2.5078657901291800 + lnx) * (-1.9478900888958200 + lnx) * (-1.3194837322612730 + lnx) * (-0.5281322700249279 + lnx) * ( 0.5913834939078759 + lnx) * ( 2.4876819633378140 + lnx) * ( 7.2648160783762400 + lnx); const double c8 = -0.00002480158730158730 * (-2.677341544966400 + lnx) * (-2.182810448271700 + lnx) * (-1.649350342277400 + lnx) * (-1.014099048290790 + lnx) * (-0.191366955370652 + lnx) * ( 0.995403817918724 + lnx) * ( 3.041323283529310 + lnx) * ( 8.295966556941250 + lnx); const double c9 = -2.75573192239859e-6 * (-2.8243487670469080 + lnx) * (-2.3798494322701120 + lnx) * (-1.9143674728689960 + lnx) * (-1.3814529102920370 + lnx) * (-0.7294312810261694 + lnx) * ( 0.1299079285269565 + lnx) * ( 1.3873333251885240 + lnx) * ( 3.5857258865210760 + lnx) * ( 9.3214237073814600 + lnx); const double c10 = -2.75573192239859e-7 * (-2.9540329644556910 + lnx) * (-2.5491366926991850 + lnx) * (-2.1348279229279880 + lnx) * (-1.6741881076349450 + lnx) * (-1.1325949616098420 + lnx) * (-0.4590034650618494 + lnx) * ( 0.4399352987435699 + lnx) * ( 1.7702236517651670 + lnx) * ( 4.1231539047474080 + lnx) * ( 10.342627908148680 + lnx); term1 = a*(c1+a*(c2+a*(c3+a*(c4+a*(c5+a*(c6+a*(c7+a*(c8+a*(c9+a*c10))))))))); } { /* Evaluate the sum. */ const int nmax = 5000; double t = 1.0; int n; sum = 1.0; for(n=1; nval = term1 + term2; result->err = GSL_DBL_EPSILON * (fabs(term1) + 2.0*fabs(term2)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_sum; } /* series for small a and x, but not defined for a == 0 */ static int gamma_inc_series(double a, double x, gsl_sf_result * result) { gsl_sf_result Q; gsl_sf_result G; const int stat_Q = gamma_inc_Q_series(a, x, &Q); const int stat_G = gsl_sf_gamma_e(a, &G); result->val = Q.val * G.val; result->err = fabs(Q.val * G.err) + fabs(Q.err * G.val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_Q, stat_G); } static int gamma_inc_a_gt_0(double a, double x, gsl_sf_result * result) { /* x > 0 and a > 0; use result for Q */ gsl_sf_result Q; gsl_sf_result G; const int stat_Q = gsl_sf_gamma_inc_Q_e(a, x, &Q); const int stat_G = gsl_sf_gamma_e(a, &G); result->val = G.val * Q.val; result->err = fabs(G.val * Q.err) + fabs(G.err * Q.val); result->err += 2.0*GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_G, stat_Q); } static int gamma_inc_CF(double a, double x, gsl_sf_result * result) { gsl_sf_result F; gsl_sf_result pre; const double am1lgx = (a-1.0)*log(x); const int stat_F = gamma_inc_F_CF(a, x, &F); const int stat_E = gsl_sf_exp_err_e(am1lgx - x, GSL_DBL_EPSILON*fabs(am1lgx), &pre); result->val = F.val * pre.val; result->err = fabs(F.err * pre.val) + fabs(F.val * pre.err); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_F, stat_E); } /* evaluate Gamma(0,x), x > 0 */ #define GAMMA_INC_A_0(x, result) gsl_sf_expint_E1_e(x, result) /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_gamma_inc_Q_e(const double a, const double x, gsl_sf_result * result) { if(a < 0.0 || x < 0.0) { DOMAIN_ERROR(result); } else if(x == 0.0) { result->val = 1.0; result->err = 0.0; return GSL_SUCCESS; } else if(a == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(x <= 0.5*a) { /* If the series is quick, do that. It is * robust and simple. */ gsl_sf_result P; int stat_P = gamma_inc_P_series(a, x, &P); result->val = 1.0 - P.val; result->err = P.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_P; } else if(a >= 1.0e+06 && (x-a)*(x-a) < a) { /* Then try the difficult asymptotic regime. * This is the only way to do this region. */ return gamma_inc_Q_asymp_unif(a, x, result); } else if(a < 0.2 && x < 5.0) { /* Cancellations at small a must be handled * analytically; x should not be too big * either since the series terms grow * with x and log(x). */ return gamma_inc_Q_series(a, x, result); } else if(a <= x) { if(x <= 1.0e+06) { /* Continued fraction is excellent for x >~ a. * We do not let x be too large when x > a since * it is somewhat pointless to try this there; * the function is rapidly decreasing for * x large and x > a, and it will just * underflow in that region anyway. We * catch that case in the standard * large-x method. */ return gamma_inc_Q_CF(a, x, result); } else { return gamma_inc_Q_large_x(a, x, result); } } else { if(x > a - sqrt(a)) { /* Continued fraction again. The convergence * is a little slower here, but that is fine. * We have to trade that off against the slow * convergence of the series, which is the * only other option. */ return gamma_inc_Q_CF(a, x, result); } else { gsl_sf_result P; int stat_P = gamma_inc_P_series(a, x, &P); result->val = 1.0 - P.val; result->err = P.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_P; } } } int gsl_sf_gamma_inc_P_e(const double a, const double x, gsl_sf_result * result) { if(a <= 0.0 || x < 0.0) { DOMAIN_ERROR(result); } else if(x == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(x < 20.0 || x < 0.5*a) { /* Do the easy series cases. Robust and quick. */ return gamma_inc_P_series(a, x, result); } else if(a > 1.0e+06 && (x-a)*(x-a) < a) { /* Crossover region. Note that Q and P are * roughly the same order of magnitude here, * so the subtraction is stable. */ gsl_sf_result Q; int stat_Q = gamma_inc_Q_asymp_unif(a, x, &Q); result->val = 1.0 - Q.val; result->err = Q.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_Q; } else if(a <= x) { /* Q <~ P in this area, so the * subtractions are stable. */ gsl_sf_result Q; int stat_Q; if(a > 0.2*x) { stat_Q = gamma_inc_Q_CF(a, x, &Q); } else { stat_Q = gamma_inc_Q_large_x(a, x, &Q); } result->val = 1.0 - Q.val; result->err = Q.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_Q; } else { if((x-a)*(x-a) < a) { /* This condition is meant to insure * that Q is not very close to 1, * so the subtraction is stable. */ gsl_sf_result Q; int stat_Q = gamma_inc_Q_CF(a, x, &Q); result->val = 1.0 - Q.val; result->err = Q.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_Q; } else { return gamma_inc_P_series(a, x, result); } } } int gsl_sf_gamma_inc_e(const double a, const double x, gsl_sf_result * result) { if(x < 0.0) { DOMAIN_ERROR(result); } else if(x == 0.0) { return gsl_sf_gamma_e(a, result); } else if(a == 0.0) { return GAMMA_INC_A_0(x, result); } else if(a > 0.0) { return gamma_inc_a_gt_0(a, x, result); } else if(x > 0.25) { /* continued fraction seems to fail for x too small; otherwise it is ok, independent of the value of |x/a|, because of the non-oscillation in the expansion, i.e. the CF is un-conditionally convergent for a < 0 and x > 0 */ return gamma_inc_CF(a, x, result); } else if(fabs(a) < 0.5) { return gamma_inc_series(a, x, result); } else { /* a = fa + da; da >= 0 */ const double fa = floor(a); const double da = a - fa; gsl_sf_result g_da; const int stat_g_da = ( da > 0.0 ? gamma_inc_a_gt_0(da, x, &g_da) : GAMMA_INC_A_0(x, &g_da)); double alpha = da; double gax = g_da.val; /* Gamma(alpha-1,x) = 1/(alpha-1) (Gamma(a,x) - x^(alpha-1) e^-x) */ do { const double shift = exp(-x + (alpha-1.0)*log(x)); gax = (gax - shift) / (alpha - 1.0); alpha -= 1.0; } while(alpha > a); result->val = gax; result->err = 2.0*(1.0 + fabs(a))*GSL_DBL_EPSILON*fabs(gax); return stat_g_da; } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_gamma_inc_P(const double a, const double x) { EVAL_RESULT(gsl_sf_gamma_inc_P_e(a, x, &result)); } double gsl_sf_gamma_inc_Q(const double a, const double x) { EVAL_RESULT(gsl_sf_gamma_inc_Q_e(a, x, &result)); } double gsl_sf_gamma_inc(const double a, const double x) { EVAL_RESULT(gsl_sf_gamma_inc_e(a, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__gegenbauer.c000066400000000000000000000116251261542461700224760ustar00rootroot00000000000000/* specfunc/gegenbauer.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_gegenbauer.h" #include "gsl_specfunc__error.h" /* See: [Thompson, Atlas for Computing Mathematical Functions] */ int gsl_sf_gegenpoly_1_e(double lambda, double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(lambda == 0.0) { result->val = 2.0*x; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { result->val = 2.0*lambda*x; result->err = 4.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_gegenpoly_2_e(double lambda, double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(lambda == 0.0) { const double txx = 2.0*x*x; result->val = -1.0 + txx; result->err = 2.0 * GSL_DBL_EPSILON * fabs(txx); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { result->val = lambda*(-1.0 + 2.0*(1.0+lambda)*x*x); result->err = GSL_DBL_EPSILON * (2.0 * fabs(result->val) + fabs(lambda)); return GSL_SUCCESS; } } int gsl_sf_gegenpoly_3_e(double lambda, double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(lambda == 0.0) { result->val = x*(-2.0 + 4.0/3.0*x*x); result->err = GSL_DBL_EPSILON * (2.0 * fabs(result->val) + fabs(x)); return GSL_SUCCESS; } else { double c = 4.0 + lambda*(6.0 + 2.0*lambda); result->val = 2.0*lambda * x * ( -1.0 - lambda + c*x*x/3.0 ); result->err = GSL_DBL_EPSILON * (2.0 * fabs(result->val) + fabs(lambda * x)); return GSL_SUCCESS; } } int gsl_sf_gegenpoly_n_e(int n, double lambda, double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(lambda <= -0.5 || n < 0) { DOMAIN_ERROR(result); } else if(n == 0) { result->val = 1.0; result->err = 0.0; return GSL_SUCCESS; } else if(n == 1) { return gsl_sf_gegenpoly_1_e(lambda, x, result); } else if(n == 2) { return gsl_sf_gegenpoly_2_e(lambda, x, result); } else if(n == 3) { return gsl_sf_gegenpoly_3_e(lambda, x, result); } else { if(lambda == 0.0 && (x >= -1.0 || x <= 1.0)) { /* 2 T_n(x)/n */ const double z = n * acos(x); result->val = 2.0 * cos(z) / n; result->err = 2.0 * GSL_DBL_EPSILON * fabs(z * result->val); return GSL_SUCCESS; } else { int k; gsl_sf_result g2; gsl_sf_result g3; int stat_g2 = gsl_sf_gegenpoly_2_e(lambda, x, &g2); int stat_g3 = gsl_sf_gegenpoly_3_e(lambda, x, &g3); int stat_g = GSL_ERROR_SELECT_2(stat_g2, stat_g3); double gkm2 = g2.val; double gkm1 = g3.val; double gk = 0.0; for(k=4; k<=n; k++) { gk = (2.0*(k+lambda-1.0)*x*gkm1 - (k+2.0*lambda-2.0)*gkm2) / k; gkm2 = gkm1; gkm1 = gk; } result->val = gk; result->err = 2.0 * GSL_DBL_EPSILON * 0.5 * n * fabs(gk); return stat_g; } } } int gsl_sf_gegenpoly_array(int nmax, double lambda, double x, double * result_array) { int k; /* CHECK_POINTER(result_array) */ if(lambda <= -0.5 || nmax < 0) { GSL_ERROR("domain error", GSL_EDOM); } /* n == 0 */ result_array[0] = 1.0; if(nmax == 0) return GSL_SUCCESS; /* n == 1 */ if(lambda == 0.0) result_array[1] = 2.0*x; else result_array[1] = 2.0*lambda*x; /* n <= nmax */ for(k=2; k<=nmax; k++) { double term1 = 2.0*(k+lambda-1.0) * x * result_array[k-1]; double term2 = (k+2.0*lambda-2.0) * result_array[k-2]; result_array[k] = (term1 - term2) / k; } return GSL_SUCCESS; } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_gegenpoly_1(double lambda, double x) { EVAL_RESULT(gsl_sf_gegenpoly_1_e(lambda, x, &result)); } double gsl_sf_gegenpoly_2(double lambda, double x) { EVAL_RESULT(gsl_sf_gegenpoly_2_e(lambda, x, &result)); } double gsl_sf_gegenpoly_3(double lambda, double x) { EVAL_RESULT(gsl_sf_gegenpoly_3_e(lambda, x, &result)); } double gsl_sf_gegenpoly_n(int n, double lambda, double x) { EVAL_RESULT(gsl_sf_gegenpoly_n_e(n, lambda, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__hyperg.c000066400000000000000000000211161261542461700216640ustar00rootroot00000000000000/* specfunc/hyperg.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ /* Miscellaneous implementations of use * for evaluation of hypergeometric functions. */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_exp.h" #include "gsl_sf_gamma.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__hyperg.h" #define SUM_LARGE (1.0e-5*GSL_DBL_MAX) int gsl_sf_hyperg_1F1_series_e(const double a, const double b, const double x, gsl_sf_result * result ) { double an = a; double bn = b; double n = 1.0; double del = 1.0; double abs_del = 1.0; double max_abs_del = 1.0; double sum_val = 1.0; double sum_err = 0.0; while(abs_del/fabs(sum_val) > 0.25*GSL_DBL_EPSILON) { double u, abs_u; if(bn == 0.0) { DOMAIN_ERROR(result); } if(an == 0.0) { result->val = sum_val; result->err = sum_err; result->err += 2.0 * GSL_DBL_EPSILON * n * fabs(sum_val); return GSL_SUCCESS; } if (n > 10000.0) { result->val = sum_val; result->err = sum_err; GSL_ERROR ("hypergeometric series failed to converge", GSL_EFAILED); } u = x * (an/(bn*n)); abs_u = fabs(u); if(abs_u > 1.0 && max_abs_del > GSL_DBL_MAX/abs_u) { result->val = sum_val; result->err = fabs(sum_val); GSL_ERROR ("overflow", GSL_EOVRFLW); } del *= u; sum_val += del; if(fabs(sum_val) > SUM_LARGE) { result->val = sum_val; result->err = fabs(sum_val); GSL_ERROR ("overflow", GSL_EOVRFLW); } abs_del = fabs(del); max_abs_del = GSL_MAX_DBL(abs_del, max_abs_del); sum_err += 2.0*GSL_DBL_EPSILON*abs_del; an += 1.0; bn += 1.0; n += 1.0; } result->val = sum_val; result->err = sum_err; result->err += abs_del; result->err += 2.0 * GSL_DBL_EPSILON * n * fabs(sum_val); return GSL_SUCCESS; } int gsl_sf_hyperg_1F1_large_b_e(const double a, const double b, const double x, gsl_sf_result * result) { if(fabs(x/b) < 1.0) { const double u = x/b; const double v = 1.0/(1.0-u); const double pre = pow(v,a); const double uv = u*v; const double uv2 = uv*uv; const double t1 = a*(a+1.0)/(2.0*b)*uv2; const double t2a = a*(a+1.0)/(24.0*b*b)*uv2; const double t2b = 12.0 + 16.0*(a+2.0)*uv + 3.0*(a+2.0)*(a+3.0)*uv2; const double t2 = t2a*t2b; result->val = pre * (1.0 - t1 + t2); result->err = pre * GSL_DBL_EPSILON * (1.0 + fabs(t1) + fabs(t2)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { DOMAIN_ERROR(result); } } int gsl_sf_hyperg_U_large_b_e(const double a, const double b, const double x, gsl_sf_result * result, double * ln_multiplier ) { double N = floor(b); /* b = N + eps */ double eps = b - N; if(fabs(eps) < GSL_SQRT_DBL_EPSILON) { double lnpre_val; double lnpre_err; gsl_sf_result M; if(b > 1.0) { double tmp = (1.0-b)*log(x); gsl_sf_result lg_bm1; gsl_sf_result lg_a; gsl_sf_lngamma_e(b-1.0, &lg_bm1); gsl_sf_lngamma_e(a, &lg_a); lnpre_val = tmp + x + lg_bm1.val - lg_a.val; lnpre_err = lg_bm1.err + lg_a.err + GSL_DBL_EPSILON * (fabs(x) + fabs(tmp)); gsl_sf_hyperg_1F1_large_b_e(1.0-a, 2.0-b, -x, &M); } else { gsl_sf_result lg_1mb; gsl_sf_result lg_1pamb; gsl_sf_lngamma_e(1.0-b, &lg_1mb); gsl_sf_lngamma_e(1.0+a-b, &lg_1pamb); lnpre_val = lg_1mb.val - lg_1pamb.val; lnpre_err = lg_1mb.err + lg_1pamb.err; gsl_sf_hyperg_1F1_large_b_e(a, b, x, &M); } if(lnpre_val > GSL_LOG_DBL_MAX-10.0) { result->val = M.val; result->err = M.err; *ln_multiplier = lnpre_val; GSL_ERROR ("overflow", GSL_EOVRFLW); } else { gsl_sf_result epre; int stat_e = gsl_sf_exp_err_e(lnpre_val, lnpre_err, &epre); result->val = epre.val * M.val; result->err = epre.val * M.err + epre.err * fabs(M.val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); *ln_multiplier = 0.0; return stat_e; } } else { double omb_lnx = (1.0-b)*log(x); gsl_sf_result lg_1mb; double sgn_1mb; gsl_sf_result lg_1pamb; double sgn_1pamb; gsl_sf_result lg_bm1; double sgn_bm1; gsl_sf_result lg_a; double sgn_a; gsl_sf_result M1, M2; double lnpre1_val, lnpre2_val; double lnpre1_err, lnpre2_err; double sgpre1, sgpre2; gsl_sf_hyperg_1F1_large_b_e( a, b, x, &M1); gsl_sf_hyperg_1F1_large_b_e(1.0-a, 2.0-b, x, &M2); gsl_sf_lngamma_sgn_e(1.0-b, &lg_1mb, &sgn_1mb); gsl_sf_lngamma_sgn_e(1.0+a-b, &lg_1pamb, &sgn_1pamb); gsl_sf_lngamma_sgn_e(b-1.0, &lg_bm1, &sgn_bm1); gsl_sf_lngamma_sgn_e(a, &lg_a, &sgn_a); lnpre1_val = lg_1mb.val - lg_1pamb.val; lnpre1_err = lg_1mb.err + lg_1pamb.err; lnpre2_val = lg_bm1.val - lg_a.val - omb_lnx - x; lnpre2_err = lg_bm1.err + lg_a.err + GSL_DBL_EPSILON * (fabs(omb_lnx)+fabs(x)); sgpre1 = sgn_1mb * sgn_1pamb; sgpre2 = sgn_bm1 * sgn_a; if(lnpre1_val > GSL_LOG_DBL_MAX-10.0 || lnpre2_val > GSL_LOG_DBL_MAX-10.0) { double max_lnpre_val = GSL_MAX(lnpre1_val,lnpre2_val); double max_lnpre_err = GSL_MAX(lnpre1_err,lnpre2_err); double lp1 = lnpre1_val - max_lnpre_val; double lp2 = lnpre2_val - max_lnpre_val; double t1 = sgpre1*exp(lp1); double t2 = sgpre2*exp(lp2); result->val = t1*M1.val + t2*M2.val; result->err = fabs(t1)*M1.err + fabs(t2)*M2.err; result->err += GSL_DBL_EPSILON * exp(max_lnpre_err) * (fabs(t1*M1.val) + fabs(t2*M2.val)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); *ln_multiplier = max_lnpre_val; GSL_ERROR ("overflow", GSL_EOVRFLW); } else { double t1 = sgpre1*exp(lnpre1_val); double t2 = sgpre2*exp(lnpre2_val); result->val = t1*M1.val + t2*M2.val; result->err = fabs(t1) * M1.err + fabs(t2)*M2.err; result->err += GSL_DBL_EPSILON * (exp(lnpre1_err)*fabs(t1*M1.val) + exp(lnpre2_err)*fabs(t2*M2.val)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); *ln_multiplier = 0.0; return GSL_SUCCESS; } } } /* [Carlson, p.109] says the error in truncating this asymptotic series * is less than the absolute value of the first neglected term. * * A termination argument is provided, so that the series will * be summed at most up to n=n_trunc. If n_trunc is set negative, * then the series is summed until it appears to start diverging. */ int gsl_sf_hyperg_2F0_series_e(const double a, const double b, const double x, int n_trunc, gsl_sf_result * result ) { const int maxiter = 2000; double an = a; double bn = b; double n = 1.0; double sum = 1.0; double del = 1.0; double abs_del = 1.0; double max_abs_del = 1.0; double last_abs_del = 1.0; while(abs_del/fabs(sum) > GSL_DBL_EPSILON && n < maxiter) { double u = an * (bn/n * x); double abs_u = fabs(u); if(abs_u > 1.0 && (max_abs_del > GSL_DBL_MAX/abs_u)) { result->val = sum; result->err = fabs(sum); GSL_ERROR ("overflow", GSL_EOVRFLW); } del *= u; sum += del; abs_del = fabs(del); if(abs_del > last_abs_del) break; /* series is probably starting to grow */ last_abs_del = abs_del; max_abs_del = GSL_MAX(abs_del, max_abs_del); an += 1.0; bn += 1.0; n += 1.0; if(an == 0.0 || bn == 0.0) break; /* series terminated */ if(n_trunc >= 0 && n >= n_trunc) break; /* reached requested timeout */ } result->val = sum; result->err = GSL_DBL_EPSILON * n + abs_del; if(n >= maxiter) GSL_ERROR ("error", GSL_EMAXITER); else return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_specfunc__hyperg.h000066400000000000000000000043321261542461700216720ustar00rootroot00000000000000/* specfunc/hyperg.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ /* Miscellaneous implementations of use * for evaluation of hypergeometric functions. */ #ifndef _HYPERG_H_ #define _HYPERG_H_ #include "gsl_sf_result.h" /* Direct implementation of 1F1 series. */ int gsl_sf_hyperg_1F1_series_e(const double a, const double b, const double x, gsl_sf_result * result); /* Implementation of the 1F1 related to the * incomplete gamma function: 1F1(1,b,x), b >= 1. */ int gsl_sf_hyperg_1F1_1_e(double b, double x, gsl_sf_result * result); /* 1F1(1,b,x) for integer b >= 1 */ int gsl_sf_hyperg_1F1_1_int_e(int b, double x, gsl_sf_result * result); /* Implementation of large b asymptotic. * [Bateman v. I, 6.13.3 (18)] * [Luke, The Special Functions and Their Approximations v. I, p. 129, 4.8 (4)] * * a^2 << b, |x|/|b| < 1 - delta */ int gsl_sf_hyperg_1F1_large_b_e(const double a, const double b, const double x, gsl_sf_result * result); /* Implementation of large b asymptotic. * * Assumes a > 0 is small, x > 0, and |x|<|b|. */ int gsl_sf_hyperg_U_large_b_e(const double a, const double b, const double x, gsl_sf_result * result, double * ln_multiplier ); /* Implementation of 2F0 asymptotic series. */ int gsl_sf_hyperg_2F0_series_e(const double a, const double b, const double x, int n_trunc, gsl_sf_result * result); #endif /* !_HYPERG_H_ */ praat-6.0.04/external/gsl/gsl_specfunc__hyperg_0F1.c000066400000000000000000000120121261542461700222650ustar00rootroot00000000000000/* specfunc/hyperg_0F1.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_exp.h" #include "gsl_sf_gamma.h" #include "gsl_sf_bessel.h" #include "gsl_sf_hyperg.h" #include "gsl_specfunc__error.h" #define locEPS (1000.0*GSL_DBL_EPSILON) /* Evaluate bessel_I(nu, x), allowing nu < 0. * This is fine here because we do not not allow * nu to be a negative integer. * x > 0. */ static int hyperg_0F1_bessel_I(const double nu, const double x, gsl_sf_result * result) { if(x > GSL_LOG_DBL_MAX) { OVERFLOW_ERROR(result); } if(nu < 0.0) { const double anu = -nu; const double s = 2.0/M_PI * sin(anu*M_PI); const double ex = exp(x); gsl_sf_result I; gsl_sf_result K; int stat_I = gsl_sf_bessel_Inu_scaled_e(anu, x, &I); int stat_K = gsl_sf_bessel_Knu_scaled_e(anu, x, &K); result->val = ex * I.val + s * (K.val / ex); result->err = ex * I.err + fabs(s * K.err/ex); result->err += fabs(s * (K.val/ex)) * GSL_DBL_EPSILON * anu * M_PI; return GSL_ERROR_SELECT_2(stat_K, stat_I); } else { const double ex = exp(x); gsl_sf_result I; int stat_I = gsl_sf_bessel_Inu_scaled_e(nu, x, &I); result->val = ex * I.val; result->err = ex * I.err + GSL_DBL_EPSILON * fabs(result->val); return stat_I; } } /* Evaluate bessel_J(nu, x), allowing nu < 0. * This is fine here because we do not not allow * nu to be a negative integer. * x > 0. */ static int hyperg_0F1_bessel_J(const double nu, const double x, gsl_sf_result * result) { if(nu < 0.0) { const double anu = -nu; const double s = sin(anu*M_PI); const double c = cos(anu*M_PI); gsl_sf_result J; gsl_sf_result Y; int stat_J = gsl_sf_bessel_Jnu_e(anu, x, &J); int stat_Y = gsl_sf_bessel_Ynu_e(anu, x, &Y); result->val = c * J.val - s * Y.val; result->err = fabs(c * J.err) + fabs(s * Y.err); result->err += fabs(anu * M_PI) * GSL_DBL_EPSILON * fabs(J.val + Y.val); return GSL_ERROR_SELECT_2(stat_Y, stat_J); } else { return gsl_sf_bessel_Jnu_e(nu, x, result); } } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_hyperg_0F1_e(double c, double x, gsl_sf_result * result) { const double rintc = floor(c + 0.5); const int c_neg_integer = (c < 0.0 && fabs(c - rintc) < locEPS); /* CHECK_POINTER(result) */ if(c == 0.0 || c_neg_integer) { DOMAIN_ERROR(result); } else if(x < 0.0) { gsl_sf_result Jcm1; gsl_sf_result lg_c; double sgn; int stat_g = gsl_sf_lngamma_sgn_e(c, &lg_c, &sgn); int stat_J = hyperg_0F1_bessel_J(c-1.0, 2.0*sqrt(-x), &Jcm1); if(stat_g != GSL_SUCCESS) { result->val = 0.0; result->err = 0.0; return stat_g; } else if(Jcm1.val == 0.0) { result->val = 0.0; result->err = 0.0; return stat_J; } else { const double tl = log(-x)*0.5*(1.0-c); double ln_pre_val = lg_c.val + tl; double ln_pre_err = lg_c.err + 2.0 * GSL_DBL_EPSILON * fabs(tl); return gsl_sf_exp_mult_err_e(ln_pre_val, ln_pre_err, sgn*Jcm1.val, Jcm1.err, result); } } else if(x == 0.0) { result->val = 1.0; result->err = 1.0; return GSL_SUCCESS; } else { gsl_sf_result Icm1; gsl_sf_result lg_c; double sgn; int stat_g = gsl_sf_lngamma_sgn_e(c, &lg_c, &sgn); int stat_I = hyperg_0F1_bessel_I(c-1.0, 2.0*sqrt(x), &Icm1); if(stat_g != GSL_SUCCESS) { result->val = 0.0; result->err = 0.0; return stat_g; } else if(Icm1.val == 0.0) { result->val = 0.0; result->err = 0.0; return stat_I; } else { const double tl = log(x)*0.5*(1.0-c); const double ln_pre_val = lg_c.val + tl; const double ln_pre_err = lg_c.err + 2.0 * GSL_DBL_EPSILON * fabs(tl); return gsl_sf_exp_mult_err_e(ln_pre_val, ln_pre_err, sgn*Icm1.val, Icm1.err, result); } } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_hyperg_0F1(const double c, const double x) { EVAL_RESULT(gsl_sf_hyperg_0F1_e(c, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__hyperg_1F1.c000066400000000000000000001703721261542461700223040ustar00rootroot00000000000000/* specfunc/hyperg_1F1.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_elementary.h" #include "gsl_sf_exp.h" #include "gsl_sf_bessel.h" #include "gsl_sf_gamma.h" #include "gsl_sf_laguerre.h" #include "gsl_sf_hyperg.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__hyperg.h" #define _1F1_INT_THRESHOLD (100.0*GSL_DBL_EPSILON) /* Asymptotic result for 1F1(a, b, x) x -> -Infinity. * Assumes b-a != neg integer and b != neg integer. */ static int hyperg_1F1_asymp_negx(const double a, const double b, const double x, gsl_sf_result * result) { gsl_sf_result lg_b; gsl_sf_result lg_bma; double sgn_b; double sgn_bma; int stat_b = gsl_sf_lngamma_sgn_e(b, &lg_b, &sgn_b); int stat_bma = gsl_sf_lngamma_sgn_e(b-a, &lg_bma, &sgn_bma); if(stat_b == GSL_SUCCESS && stat_bma == GSL_SUCCESS) { gsl_sf_result F; int stat_F = gsl_sf_hyperg_2F0_series_e(a, 1.0+a-b, -1.0/x, -1, &F); if(F.val != 0) { double ln_term_val = a*log(-x); double ln_term_err = 2.0 * GSL_DBL_EPSILON * (fabs(a) + fabs(ln_term_val)); double ln_pre_val = lg_b.val - lg_bma.val - ln_term_val; double ln_pre_err = lg_b.err + lg_bma.err + ln_term_err; int stat_e = gsl_sf_exp_mult_err_e(ln_pre_val, ln_pre_err, sgn_bma*sgn_b*F.val, F.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_F); } else { result->val = 0.0; result->err = 0.0; return stat_F; } } else { DOMAIN_ERROR(result); } } /* Asymptotic result for 1F1(a, b, x) x -> +Infinity * Assumes b != neg integer and a != neg integer */ static int hyperg_1F1_asymp_posx(const double a, const double b, const double x, gsl_sf_result * result) { gsl_sf_result lg_b; gsl_sf_result lg_a; double sgn_b; double sgn_a; int stat_b = gsl_sf_lngamma_sgn_e(b, &lg_b, &sgn_b); int stat_a = gsl_sf_lngamma_sgn_e(a, &lg_a, &sgn_a); if(stat_a == GSL_SUCCESS && stat_b == GSL_SUCCESS) { gsl_sf_result F; int stat_F = gsl_sf_hyperg_2F0_series_e(b-a, 1.0-a, 1.0/x, -1, &F); if(stat_F == GSL_SUCCESS && F.val != 0) { double lnx = log(x); double ln_term_val = (a-b)*lnx; double ln_term_err = 2.0 * GSL_DBL_EPSILON * (fabs(a) + fabs(b)) * fabs(lnx) + 2.0 * GSL_DBL_EPSILON * fabs(a-b); double ln_pre_val = lg_b.val - lg_a.val + ln_term_val + x; double ln_pre_err = lg_b.err + lg_a.err + ln_term_err + 2.0 * GSL_DBL_EPSILON * fabs(x); int stat_e = gsl_sf_exp_mult_err_e(ln_pre_val, ln_pre_err, sgn_a*sgn_b*F.val, F.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_F); } else { result->val = 0.0; result->err = 0.0; return stat_F; } } else { DOMAIN_ERROR(result); } } /* Asymptotic result from Slater 4.3.7 * * To get the general series, write M(a,b,x) as * * M(a,b,x)=sum ((a)_n/(b)_n) (x^n / n!) * * and expand (b)_n in inverse powers of b as follows * * -log(1/(b)_n) = sum_(k=0)^(n-1) log(b+k) * = n log(b) + sum_(k=0)^(n-1) log(1+k/b) * * Do a taylor expansion of the log in 1/b and sum the resulting terms * using the standard algebraic formulas for finite sums of powers of * k. This should then give * * M(a,b,x) = sum_(n=0)^(inf) (a_n/n!) (x/b)^n * (1 - n(n-1)/(2b) * + (n-1)n(n+1)(3n-2)/(24b^2) + ... * * which can be summed explicitly. The trick for summing it is to take * derivatives of sum_(i=0)^(inf) a_n*y^n/n! = (1-y)^(-a); * * [BJG 16/01/2007] */ static int hyperg_1F1_largebx(const double a, const double b, const double x, gsl_sf_result * result) { double y = x/b; double f = exp(-a*log1p(-y)); double t1 = -((a*(a+1.0))/(2*b))*pow((y/(1.0-y)),2.0); double t2 = (1/(24*b*b))*((a*(a+1)*y*y)/pow(1-y,4))*(12+8*(2*a+1)*y+(3*a*a-a-2)*y*y); double t3 = (-1/(48*b*b*b*pow(1-y,6)))*a*((a + 1)*((y*((a + 1)*(a*(y*(y*((y*(a - 2) + 16)*(a - 1)) + 72)) + 96)) + 24)*pow(y, 2))); result->val = f * (1 + t1 + t2 + t3); result->err = 2*fabs(f*t3) + 2*GSL_DBL_EPSILON*fabs(result->val); return GSL_SUCCESS; } /* Asymptotic result for x < 2b-4a, 2b-4a large. * [Abramowitz+Stegun, 13.5.21] * * assumes 0 <= x/(2b-4a) <= 1 */ static int hyperg_1F1_large2bm4a(const double a, const double b, const double x, gsl_sf_result * result) { double eta = 2.0*b - 4.0*a; double cos2th = x/eta; double sin2th = 1.0 - cos2th; double th = acos(sqrt(cos2th)); double pre_h = 0.25*M_PI*M_PI*eta*eta*cos2th*sin2th; gsl_sf_result lg_b; int stat_lg = gsl_sf_lngamma_e(b, &lg_b); double t1 = 0.5*(1.0-b)*log(0.25*x*eta); double t2 = 0.25*log(pre_h); double lnpre_val = lg_b.val + 0.5*x + t1 - t2; double lnpre_err = lg_b.err + 2.0 * GSL_DBL_EPSILON * (fabs(0.5*x) + fabs(t1) + fabs(t2)); #if SMALL_ANGLE const double eps = asin(sqrt(cos2th)); /* theta = pi/2 - eps */ double s1 = (fmod(a, 1.0) == 0.0) ? 0.0 : sin(a*M_PI); double eta_reduc = (fmod(eta + 1, 4.0) == 0.0) ? 0.0 : fmod(eta + 1, 8.0); double phi1 = 0.25*eta_reduc*M_PI; double phi2 = 0.25*eta*(2*eps + sin(2.0*eps)); double s2 = sin(phi1 - phi2); #else double s1 = sin(a*M_PI); double s2 = sin(0.25*eta*(2.0*th - sin(2.0*th)) + 0.25*M_PI); #endif double ser_val = s1 + s2; double ser_err = 2.0 * GSL_DBL_EPSILON * (fabs(s1) + fabs(s2)); int stat_e = gsl_sf_exp_mult_err_e(lnpre_val, lnpre_err, ser_val, ser_err, result); return GSL_ERROR_SELECT_2(stat_e, stat_lg); } /* Luke's rational approximation. * See [Luke, Algorithms for the Computation of Mathematical Functions, p.182] * * Like the case of the 2F1 rational approximations, these are * probably guaranteed to converge for x < 0, barring gross * numerical instability in the pre-asymptotic regime. */ static int hyperg_1F1_luke(const double a, const double c, const double xin, gsl_sf_result * result) { const double RECUR_BIG = 1.0e+50; const int nmax = 5000; int n = 3; const double x = -xin; const double x3 = x*x*x; const double t0 = a/c; const double t1 = (a+1.0)/(2.0*c); const double t2 = (a+2.0)/(2.0*(c+1.0)); double F = 1.0; double prec; double Bnm3 = 1.0; /* B0 */ double Bnm2 = 1.0 + t1 * x; /* B1 */ double Bnm1 = 1.0 + t2 * x * (1.0 + t1/3.0 * x); /* B2 */ double Anm3 = 1.0; /* A0 */ double Anm2 = Bnm2 - t0 * x; /* A1 */ double Anm1 = Bnm1 - t0*(1.0 + t2*x)*x + t0 * t1 * (c/(c+1.0)) * x*x; /* A2 */ while(1) { double npam1 = n + a - 1; double npcm1 = n + c - 1; double npam2 = n + a - 2; double npcm2 = n + c - 2; double tnm1 = 2*n - 1; double tnm3 = 2*n - 3; double tnm5 = 2*n - 5; double F1 = (n-a-2) / (2*tnm3*npcm1); double F2 = (n+a)*npam1 / (4*tnm1*tnm3*npcm2*npcm1); double F3 = -npam2*npam1*(n-a-2) / (8*tnm3*tnm3*tnm5*(n+c-3)*npcm2*npcm1); double E = -npam1*(n-c-1) / (2*tnm3*npcm2*npcm1); double An = (1.0+F1*x)*Anm1 + (E + F2*x)*x*Anm2 + F3*x3*Anm3; double Bn = (1.0+F1*x)*Bnm1 + (E + F2*x)*x*Bnm2 + F3*x3*Bnm3; double r = An/Bn; prec = fabs((F - r)/F); F = r; if(prec < GSL_DBL_EPSILON || n > nmax) break; if(fabs(An) > RECUR_BIG || fabs(Bn) > RECUR_BIG) { An /= RECUR_BIG; Bn /= RECUR_BIG; Anm1 /= RECUR_BIG; Bnm1 /= RECUR_BIG; Anm2 /= RECUR_BIG; Bnm2 /= RECUR_BIG; Anm3 /= RECUR_BIG; Bnm3 /= RECUR_BIG; } else if(fabs(An) < 1.0/RECUR_BIG || fabs(Bn) < 1.0/RECUR_BIG) { An *= RECUR_BIG; Bn *= RECUR_BIG; Anm1 *= RECUR_BIG; Bnm1 *= RECUR_BIG; Anm2 *= RECUR_BIG; Bnm2 *= RECUR_BIG; Anm3 *= RECUR_BIG; Bnm3 *= RECUR_BIG; } n++; Bnm3 = Bnm2; Bnm2 = Bnm1; Bnm1 = Bn; Anm3 = Anm2; Anm2 = Anm1; Anm1 = An; } result->val = F; result->err = 2.0 * fabs(F * prec); result->err += 2.0 * GSL_DBL_EPSILON * (n-1.0) * fabs(F); return GSL_SUCCESS; } /* Series for 1F1(1,b,x) * b > 0 */ static int hyperg_1F1_1_series(const double b, const double x, gsl_sf_result * result) { double sum_val = 1.0; double sum_err = 0.0; double term = 1.0; double n = 1.0; while(fabs(term/sum_val) > 0.25*GSL_DBL_EPSILON) { term *= x/(b+n-1); sum_val += term; sum_err += 8.0*GSL_DBL_EPSILON*fabs(term) + GSL_DBL_EPSILON*fabs(sum_val); n += 1.0; } result->val = sum_val; result->err = sum_err; result->err += 2.0 * fabs(term); return GSL_SUCCESS; } /* 1F1(1,b,x) * b >= 1, b integer */ static int hyperg_1F1_1_int(const int b, const double x, gsl_sf_result * result) { if(b < 1) { DOMAIN_ERROR(result); } else if(b == 1) { return gsl_sf_exp_e(x, result); } else if(b == 2) { return gsl_sf_exprel_e(x, result); } else if(b == 3) { return gsl_sf_exprel_2_e(x, result); } else { return gsl_sf_exprel_n_e(b-1, x, result); } } /* 1F1(1,b,x) * b >=1, b real * * checked OK: [GJ] Thu Oct 1 16:46:35 MDT 1998 */ static int hyperg_1F1_1(const double b, const double x, gsl_sf_result * result) { double ax = fabs(x); double ib = floor(b + 0.1); if(b < 1.0) { DOMAIN_ERROR(result); } else if(b == 1.0) { return gsl_sf_exp_e(x, result); } else if(b >= 1.4*ax) { return hyperg_1F1_1_series(b, x, result); } else if(fabs(b - ib) < _1F1_INT_THRESHOLD && ib < INT_MAX) { return hyperg_1F1_1_int((int)ib, x, result); } else if(x > 0.0) { if(x > 100.0 && b < 0.75*x) { return hyperg_1F1_asymp_posx(1.0, b, x, result); } else if(b < 1.0e+05) { /* Recurse backward on b, from a * chosen offset point. For x > 0, * which holds here, this should * be a stable direction. */ const double off = ceil(1.4*x-b) + 1.0; double bp = b + off; gsl_sf_result M; int stat_s = hyperg_1F1_1_series(bp, x, &M); const double err_rat = M.err / fabs(M.val); while(bp > b+0.1) { /* M(1,b-1) = x/(b-1) M(1,b) + 1 */ bp -= 1.0; M.val = 1.0 + x/bp * M.val; } result->val = M.val; result->err = err_rat * fabs(M.val); result->err += 2.0 * GSL_DBL_EPSILON * (fabs(off)+1.0) * fabs(M.val); return stat_s; } else if (fabs(x) < fabs(b) && fabs(x) < sqrt(fabs(b)) * fabs(b-x)) { return hyperg_1F1_largebx(1.0, b, x, result); } else if (fabs(x) > fabs(b)) { return hyperg_1F1_1_series(b, x, result); } else { return hyperg_1F1_large2bm4a(1.0, b, x, result); } } else { /* x <= 0 and b not large compared to |x| */ if(ax < 10.0 && b < 10.0) { return hyperg_1F1_1_series(b, x, result); } else if(ax >= 100.0 && GSL_MAX_DBL(fabs(2.0-b),1.0) < 0.99*ax) { return hyperg_1F1_asymp_negx(1.0, b, x, result); } else { return hyperg_1F1_luke(1.0, b, x, result); } } } /* 1F1(a,b,x)/Gamma(b) for b->0 * [limit of Abramowitz+Stegun 13.3.7] */ static int hyperg_1F1_renorm_b0(const double a, const double x, gsl_sf_result * result) { double eta = a*x; if(eta > 0.0) { double root_eta = sqrt(eta); gsl_sf_result I1_scaled; int stat_I = gsl_sf_bessel_I1_scaled_e(2.0*root_eta, &I1_scaled); if(I1_scaled.val <= 0.0) { result->val = 0.0; result->err = 0.0; return GSL_ERROR_SELECT_2(stat_I, GSL_EDOM); } else { /* Note that 13.3.7 contains higher terms which are zeroth order in b. These make a non-negligible contribution to the sum. With the first correction term, the I1 above is replaced by I1 + (2/3)*a*(x/(4a))**(3/2)*I2(2*root_eta). We will add this as part of the result and error estimate. */ const double corr1 =(2.0/3.0)*a*pow(x/(4.0*a),1.5)*gsl_sf_bessel_In_scaled(2, 2.0*root_eta) ; const double lnr_val = 0.5*x + 0.5*log(eta) + fabs(2.0*root_eta) + log(I1_scaled.val+corr1); const double lnr_err = GSL_DBL_EPSILON * (1.5*fabs(x) + 1.0) + fabs((I1_scaled.err+corr1)/I1_scaled.val); return gsl_sf_exp_err_e(lnr_val, lnr_err, result); } } else if(eta == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else { /* eta < 0 */ double root_eta = sqrt(-eta); gsl_sf_result J1; int stat_J = gsl_sf_bessel_J1_e(2.0*root_eta, &J1); if(J1.val <= 0.0) { result->val = 0.0; result->err = 0.0; return GSL_ERROR_SELECT_2(stat_J, GSL_EDOM); } else { const double t1 = 0.5*x; const double t2 = 0.5*log(-eta); const double t3 = fabs(x); const double t4 = log(J1.val); const double lnr_val = t1 + t2 + t3 + t4; const double lnr_err = GSL_DBL_EPSILON * (1.5*fabs(x) + 1.0) + fabs(J1.err/J1.val); gsl_sf_result ex; int stat_e = gsl_sf_exp_err_e(lnr_val, lnr_err, &ex); result->val = -ex.val; result->err = ex.err; return stat_e; } } } /* 1F1'(a,b,x)/1F1(a,b,x) * Uses Gautschi's version of the CF. * [Gautschi, Math. Comp. 31, 994 (1977)] * * Supposedly this suffers from the "anomalous convergence" * problem when b < x. I have seen anomalous convergence * in several of the continued fractions associated with * 1F1(a,b,x). This particular CF formulation seems stable * for b > x. However, it does display a painful artifact * of the anomalous convergence; the convergence plateaus * unless b >>> x. For example, even for b=1000, x=1, this * method locks onto a ratio which is only good to about * 4 digits. Apparently the rest of the digits are hiding * way out on the plateau, but finite-precision lossage * means you will never get them. */ #if 0 static int hyperg_1F1_CF1_p(const double a, const double b, const double x, double * result) { const double RECUR_BIG = GSL_SQRT_DBL_MAX; const int maxiter = 5000; int n = 1; double Anm2 = 1.0; double Bnm2 = 0.0; double Anm1 = 0.0; double Bnm1 = 1.0; double a1 = 1.0; double b1 = 1.0; double An = b1*Anm1 + a1*Anm2; double Bn = b1*Bnm1 + a1*Bnm2; double an, bn; double fn = An/Bn; while(n < maxiter) { double old_fn; double del; n++; Anm2 = Anm1; Bnm2 = Bnm1; Anm1 = An; Bnm1 = Bn; an = (a+n)*x/((b-x+n-1)*(b-x+n)); bn = 1.0; An = bn*Anm1 + an*Anm2; Bn = bn*Bnm1 + an*Bnm2; if(fabs(An) > RECUR_BIG || fabs(Bn) > RECUR_BIG) { An /= RECUR_BIG; Bn /= RECUR_BIG; Anm1 /= RECUR_BIG; Bnm1 /= RECUR_BIG; Anm2 /= RECUR_BIG; Bnm2 /= RECUR_BIG; } old_fn = fn; fn = An/Bn; del = old_fn/fn; if(fabs(del - 1.0) < 10.0*GSL_DBL_EPSILON) break; } *result = a/(b-x) * fn; if(n == maxiter) GSL_ERROR ("error", GSL_EMAXITER); else return GSL_SUCCESS; } #endif /* 0 */ /* 1F1'(a,b,x)/1F1(a,b,x) * Uses Gautschi's series transformation of the * continued fraction. This is apparently the best * method for getting this ratio in the stable region. * The convergence is monotone and supergeometric * when b > x. * Assumes a >= -1. */ static int hyperg_1F1_CF1_p_ser(const double a, const double b, const double x, double * result) { if(a == 0.0) { *result = 0.0; return GSL_SUCCESS; } else { const int maxiter = 5000; double sum = 1.0; double pk = 1.0; double rhok = 0.0; int k; for(k=1; k RECUR_BIG || fabs(Bn) > RECUR_BIG) { An /= RECUR_BIG; Bn /= RECUR_BIG; Anm1 /= RECUR_BIG; Bnm1 /= RECUR_BIG; Anm2 /= RECUR_BIG; Bnm2 /= RECUR_BIG; } old_fn = fn; fn = An/Bn; del = old_fn/fn; if(fabs(del - 1.0) < 10.0*GSL_DBL_EPSILON) break; } *result = fn; if(n == maxiter) GSL_ERROR ("error", GSL_EMAXITER); else return GSL_SUCCESS; } #endif /* 0 */ /* 1F1(a,b+1,x)/1F1(a,b,x) * * This seemed to suffer from "anomalous convergence". * However, I have no theory for this recurrence. */ #if 0 static int hyperg_1F1_CF1_b(const double a, const double b, const double x, double * result) { const double RECUR_BIG = GSL_SQRT_DBL_MAX; const int maxiter = 5000; int n = 1; double Anm2 = 1.0; double Bnm2 = 0.0; double Anm1 = 0.0; double Bnm1 = 1.0; double a1 = b + 1.0; double b1 = (b + 1.0) * (b - x); double An = b1*Anm1 + a1*Anm2; double Bn = b1*Bnm1 + a1*Bnm2; double an, bn; double fn = An/Bn; while(n < maxiter) { double old_fn; double del; n++; Anm2 = Anm1; Bnm2 = Bnm1; Anm1 = An; Bnm1 = Bn; an = (b + n) * (b + n - 1.0 - a) * x; bn = (b + n) * (b + n - 1.0 - x); An = bn*Anm1 + an*Anm2; Bn = bn*Bnm1 + an*Bnm2; if(fabs(An) > RECUR_BIG || fabs(Bn) > RECUR_BIG) { An /= RECUR_BIG; Bn /= RECUR_BIG; Anm1 /= RECUR_BIG; Bnm1 /= RECUR_BIG; Anm2 /= RECUR_BIG; Bnm2 /= RECUR_BIG; } old_fn = fn; fn = An/Bn; del = old_fn/fn; if(fabs(del - 1.0) < 10.0*GSL_DBL_EPSILON) break; } *result = fn; if(n == maxiter) GSL_ERROR ("error", GSL_EMAXITER); else return GSL_SUCCESS; } #endif /* 0 */ /* 1F1(a,b,x) * |a| <= 1, b > 0 */ static int hyperg_1F1_small_a_bgt0(const double a, const double b, const double x, gsl_sf_result * result) { const double bma = b-a; const double oma = 1.0-a; const double ap1mb = 1.0+a-b; const double abs_bma = fabs(bma); const double abs_oma = fabs(oma); const double abs_ap1mb = fabs(ap1mb); const double ax = fabs(x); if(a == 0.0) { result->val = 1.0; result->err = 0.0; return GSL_SUCCESS; } else if(a == 1.0 && b >= 1.0) { return hyperg_1F1_1(b, x, result); } else if(a == -1.0) { result->val = 1.0 + a/b * x; result->err = GSL_DBL_EPSILON * (1.0 + fabs(a/b * x)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(b >= 1.4*ax) { return gsl_sf_hyperg_1F1_series_e(a, b, x, result); } else if(x > 0.0) { if(x > 100.0 && abs_bma*abs_oma < 0.5*x) { return hyperg_1F1_asymp_posx(a, b, x, result); } else if(b < 5.0e+06) { /* Recurse backward on b from * a suitably high point. */ const double b_del = ceil(1.4*x-b) + 1.0; double bp = b + b_del; gsl_sf_result r_Mbp1; gsl_sf_result r_Mb; double Mbp1; double Mb; double Mbm1; int stat_0 = gsl_sf_hyperg_1F1_series_e(a, bp+1.0, x, &r_Mbp1); int stat_1 = gsl_sf_hyperg_1F1_series_e(a, bp, x, &r_Mb); const double err_rat = fabs(r_Mbp1.err/r_Mbp1.val) + fabs(r_Mb.err/r_Mb.val); Mbp1 = r_Mbp1.val; Mb = r_Mb.val; while(bp > b+0.1) { /* Do backward recursion. */ Mbm1 = ((x+bp-1.0)*Mb - x*(bp-a)/bp*Mbp1)/(bp-1.0); bp -= 1.0; Mbp1 = Mb; Mb = Mbm1; } result->val = Mb; result->err = err_rat * (fabs(b_del)+1.0) * fabs(Mb); result->err += 2.0 * GSL_DBL_EPSILON * fabs(Mb); return GSL_ERROR_SELECT_2(stat_0, stat_1); } else if (fabs(x) < fabs(b) && fabs(a*x) < sqrt(fabs(b)) * fabs(b-x)) { return hyperg_1F1_largebx(a, b, x, result); } else { return hyperg_1F1_large2bm4a(a, b, x, result); } } else { /* x < 0 and b not large compared to |x| */ if(ax < 10.0 && b < 10.0) { return gsl_sf_hyperg_1F1_series_e(a, b, x, result); } else if(ax >= 100.0 && GSL_MAX(abs_ap1mb,1.0) < 0.99*ax) { return hyperg_1F1_asymp_negx(a, b, x, result); } else { return hyperg_1F1_luke(a, b, x, result); } } } /* 1F1(b+eps,b,x) * |eps|<=1, b > 0 */ static int hyperg_1F1_beps_bgt0(const double eps, const double b, const double x, gsl_sf_result * result) { if(b > fabs(x) && fabs(eps) < GSL_SQRT_DBL_EPSILON) { /* If b-a is very small and x/b is not too large we can * use this explicit approximation. * * 1F1(b+eps,b,x) = exp(ax/b) (1 - eps x^2 (v2 + v3 x + ...) + ...) * * v2 = a/(2b^2(b+1)) * v3 = a(b-2a)/(3b^3(b+1)(b+2)) * ... * * See [Luke, Mathematical Functions and Their Approximations, p.292] * * This cannot be used for b near a negative integer or zero. * Also, if x/b is large the deviation from exp(x) behaviour grows. */ double a = b + eps; gsl_sf_result exab; int stat_e = gsl_sf_exp_e(a*x/b, &exab); double v2 = a/(2.0*b*b*(b+1.0)); double v3 = a*(b-2.0*a)/(3.0*b*b*b*(b+1.0)*(b+2.0)); double v = v2 + v3 * x; double f = (1.0 - eps*x*x*v); result->val = exab.val * f; result->err = exab.err * fabs(f); result->err += fabs(exab.val) * GSL_DBL_EPSILON * (1.0 + fabs(eps*x*x*v)); result->err += 4.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_e; } else { /* Otherwise use a Kummer transformation to reduce * it to the small a case. */ gsl_sf_result Kummer_1F1; int stat_K = hyperg_1F1_small_a_bgt0(-eps, b, -x, &Kummer_1F1); if(Kummer_1F1.val != 0.0) { int stat_e = gsl_sf_exp_mult_err_e(x, 2.0*GSL_DBL_EPSILON*fabs(x), Kummer_1F1.val, Kummer_1F1.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_K); } else { result->val = 0.0; result->err = 0.0; return stat_K; } } } /* 1F1(a,2a,x) = Gamma(a + 1/2) E(x) (|x|/4)^(-a+1/2) scaled_I(a-1/2,|x|/2) * * E(x) = exp(x) x > 0 * = 1 x < 0 * * a >= 1/2 */ static int hyperg_1F1_beq2a_pos(const double a, const double x, gsl_sf_result * result) { if(x == 0.0) { result->val = 1.0; result->err = 0.0; return GSL_SUCCESS; } else { gsl_sf_result I; int stat_I = gsl_sf_bessel_Inu_scaled_e(a-0.5, 0.5*fabs(x), &I); gsl_sf_result lg; int stat_g = gsl_sf_lngamma_e(a + 0.5, &lg); double ln_term = (0.5-a)*log(0.25*fabs(x)); double lnpre_val = lg.val + GSL_MAX_DBL(x,0.0) + ln_term; double lnpre_err = lg.err + GSL_DBL_EPSILON * (fabs(ln_term) + fabs(x)); int stat_e = gsl_sf_exp_mult_err_e(lnpre_val, lnpre_err, I.val, I.err, result); return GSL_ERROR_SELECT_3(stat_e, stat_g, stat_I); } } /* Determine middle parts of diagonal recursion along b=2a * from two endpoints, i.e. * * given: M(a,b) and M(a+1,b+2) * get: M(a+1,b+1) and M(a,b+1) */ #if 0 inline static int hyperg_1F1_diag_step(const double a, const double b, const double x, const double Mab, const double Map1bp2, double * Map1bp1, double * Mabp1) { if(a == b) { *Map1bp1 = Mab; *Mabp1 = Mab - x/(b+1.0) * Map1bp2; } else { *Map1bp1 = Mab - x * (a-b)/(b*(b+1.0)) * Map1bp2; *Mabp1 = (a * *Map1bp1 - b * Mab)/(a-b); } return GSL_SUCCESS; } #endif /* 0 */ /* Determine endpoint of diagonal recursion. * * given: M(a,b) and M(a+1,b+2) * get: M(a+1,b) and M(a+1,b+1) */ #if 0 inline static int hyperg_1F1_diag_end_step(const double a, const double b, const double x, const double Mab, const double Map1bp2, double * Map1b, double * Map1bp1) { *Map1bp1 = Mab - x * (a-b)/(b*(b+1.0)) * Map1bp2; *Map1b = Mab + x/b * *Map1bp1; return GSL_SUCCESS; } #endif /* 0 */ /* Handle the case of a and b both positive integers. * Assumes a > 0 and b > 0. */ static int hyperg_1F1_ab_posint(const int a, const int b, const double x, gsl_sf_result * result) { double ax = fabs(x); if(a == b) { return gsl_sf_exp_e(x, result); /* 1F1(a,a,x) */ } else if(a == 1) { return gsl_sf_exprel_n_e(b-1, x, result); /* 1F1(1,b,x) */ } else if(b == a + 1) { gsl_sf_result K; int stat_K = gsl_sf_exprel_n_e(a, -x, &K); /* 1F1(1,1+a,-x) */ int stat_e = gsl_sf_exp_mult_err_e(x, 2.0 * GSL_DBL_EPSILON * fabs(x), K.val, K.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_K); } else if(a == b + 1) { gsl_sf_result ex; int stat_e = gsl_sf_exp_e(x, &ex); result->val = ex.val * (1.0 + x/b); result->err = ex.err * (1.0 + x/b); result->err += ex.val * GSL_DBL_EPSILON * (1.0 + fabs(x/b)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_e; } else if(a == b + 2) { gsl_sf_result ex; int stat_e = gsl_sf_exp_e(x, &ex); double poly = (1.0 + x/b*(2.0 + x/(b+1.0))); result->val = ex.val * poly; result->err = ex.err * fabs(poly); result->err += ex.val * GSL_DBL_EPSILON * (1.0 + fabs(x/b) * (2.0 + fabs(x/(b+1.0)))); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_e; } else if(b == 2*a) { return hyperg_1F1_beq2a_pos(a, x, result); /* 1F1(a,2a,x) */ } else if( ( b < 10 && a < 10 && ax < 5.0 ) || ( b > a*ax ) || ( b > a && ax < 5.0 ) ) { return gsl_sf_hyperg_1F1_series_e(a, b, x, result); } else if(b > a && b >= 2*a + x) { /* Use the Gautschi CF series, then * recurse backward to a=0 for normalization. * This will work for either sign of x. */ double rap; int stat_CF1 = hyperg_1F1_CF1_p_ser(a, b, x, &rap); double ra = 1.0 + x/a * rap; double Ma = GSL_SQRT_DBL_MIN; double Map1 = ra * Ma; double Mnp1 = Map1; double Mn = Ma; double Mnm1; int n; for(n=a; n>0; n--) { Mnm1 = (n * Mnp1 - (2*n-b+x) * Mn) / (b-n); Mnp1 = Mn; Mn = Mnm1; } result->val = Ma/Mn; result->err = 2.0 * GSL_DBL_EPSILON * (fabs(a) + 1.0) * fabs(Ma/Mn); return stat_CF1; } else if(b > a && b < 2*a + x && b > x) { /* Use the Gautschi series representation of * the continued fraction. Then recurse forward * to the a=b line for normalization. This will * work for either sign of x, although we do need * to check for b > x, for when x is positive. */ double rap; int stat_CF1 = hyperg_1F1_CF1_p_ser(a, b, x, &rap); double ra = 1.0 + x/a * rap; gsl_sf_result ex; int stat_ex; double Ma = GSL_SQRT_DBL_MIN; double Map1 = ra * Ma; double Mnm1 = Ma; double Mn = Map1; double Mnp1; int n; for(n=a+1; nval = ex.val * Ma/Mn; result->err = ex.err * fabs(Ma/Mn); result->err += 4.0 * GSL_DBL_EPSILON * (fabs(b-a)+1.0) * fabs(result->val); return GSL_ERROR_SELECT_2(stat_ex, stat_CF1); } else if(x >= 0.0) { if(b < a) { /* The point b,b is below the b=2a+x line. * Forward recursion on a from b,b+1 is possible. * Note that a > b + 1 as well, since we already tried a = b + 1. */ if(x + log(fabs(x/b)) < GSL_LOG_DBL_MAX-2.0) { double ex = exp(x); int n; double Mnm1 = ex; /* 1F1(b,b,x) */ double Mn = ex * (1.0 + x/b); /* 1F1(b+1,b,x) */ double Mnp1; for(n=b+1; nval = Mn; result->err = (x + 1.0) * GSL_DBL_EPSILON * fabs(Mn); result->err *= fabs(a-b)+1.0; return GSL_SUCCESS; } else { OVERFLOW_ERROR(result); } } else { /* b > a * b < 2a + x * b <= x (otherwise we would have finished above) * * Gautschi anomalous convergence region. However, we can * recurse forward all the way from a=0,1 because we are * always underneath the b=2a+x line. */ gsl_sf_result r_Mn; double Mnm1 = 1.0; /* 1F1(0,b,x) */ double Mn; /* 1F1(1,b,x) */ double Mnp1; int n; gsl_sf_exprel_n_e(b-1, x, &r_Mn); Mn = r_Mn.val; for(n=1; nval = Mn; result->err = fabs(Mn) * (1.0 + fabs(a)) * fabs(r_Mn.err / r_Mn.val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(Mn); return GSL_SUCCESS; } } else { /* x < 0 * b < a (otherwise we would have tripped one of the above) */ if(a <= 0.5*(b-x) || a >= -x) { /* Gautschi continued fraction is in the anomalous region, * so we must find another way. We recurse down in b, * from the a=b line. */ double ex = exp(x); double Manp1 = ex; double Man = ex * (1.0 + x/(a-1.0)); double Manm1; int n; for(n=a-1; n>b; n--) { Manm1 = (-n*(1-n-x)*Man - x*(n-a)*Manp1)/(n*(n-1.0)); Manp1 = Man; Man = Manm1; } result->val = Man; result->err = (fabs(x) + 1.0) * GSL_DBL_EPSILON * fabs(Man); result->err *= fabs(b-a)+1.0; return GSL_SUCCESS; } else { /* Pick a0 such that b ~= 2a0 + x, then * recurse down in b from a0,a0 to determine * the values near the line b=2a+x. Then recurse * forward on a from a0. */ int a0 = ceil(0.5*(b-x)); double Ma0b; /* M(a0,b) */ double Ma0bp1; /* M(a0,b+1) */ double Ma0p1b; /* M(a0+1,b) */ double Mnm1; double Mn; double Mnp1; int n; { double ex = exp(x); double Ma0np1 = ex; double Ma0n = ex * (1.0 + x/(a0-1.0)); double Ma0nm1; for(n=a0-1; n>b; n--) { Ma0nm1 = (-n*(1-n-x)*Ma0n - x*(n-a0)*Ma0np1)/(n*(n-1.0)); Ma0np1 = Ma0n; Ma0n = Ma0nm1; } Ma0bp1 = Ma0np1; Ma0b = Ma0n; Ma0p1b = (b*(a0+x)*Ma0b + x*(a0-b)*Ma0bp1)/(a0*b); } /* Initialise the recurrence correctly BJG */ if (a0 >= a) { Mn = Ma0b; } else if (a0 + 1>= a) { Mn = Ma0p1b; } else { Mnm1 = Ma0b; Mn = Ma0p1b; for(n=a0+1; nval = Mn; result->err = (fabs(x) + 1.0) * GSL_DBL_EPSILON * fabs(Mn); result->err *= fabs(b-a)+1.0; return GSL_SUCCESS; } } } /* Evaluate a <= 0, a integer, cases directly. (Polynomial; Horner) * When the terms are all positive, this * must work. We will assume this here. */ static int hyperg_1F1_a_negint_poly(const int a, const double b, const double x, gsl_sf_result * result) { if(a == 0) { result->val = 1.0; result->err = 1.0; return GSL_SUCCESS; } else { int N = -a; double poly = 1.0; int k; for(k=N-1; k>=0; k--) { double t = (a+k)/(b+k) * (x/(k+1)); double r = t + 1.0/poly; if(r > 0.9*GSL_DBL_MAX/poly) { OVERFLOW_ERROR(result); } else { poly *= r; /* P_n = 1 + t_n P_{n-1} */ } } result->val = poly; result->err = 2.0 * (sqrt(N) + 1.0) * GSL_DBL_EPSILON * fabs(poly); return GSL_SUCCESS; } } /* Evaluate negative integer a case by relation * to Laguerre polynomials. This is more general than * the direct polynomial evaluation, but is safe * for all values of x. * * 1F1(-n,b,x) = n!/(b)_n Laguerre[n,b-1,x] * = n B(b,n) Laguerre[n,b-1,x] * * assumes b is not a negative integer */ static int hyperg_1F1_a_negint_lag(const int a, const double b, const double x, gsl_sf_result * result) { const int n = -a; gsl_sf_result lag; const int stat_l = gsl_sf_laguerre_n_e(n, b-1.0, x, &lag); if(b < 0.0) { gsl_sf_result lnfact; gsl_sf_result lng1; gsl_sf_result lng2; double s1, s2; const int stat_f = gsl_sf_lnfact_e(n, &lnfact); const int stat_g1 = gsl_sf_lngamma_sgn_e(b + n, &lng1, &s1); const int stat_g2 = gsl_sf_lngamma_sgn_e(b, &lng2, &s2); const double lnpre_val = lnfact.val - (lng1.val - lng2.val); const double lnpre_err = lnfact.err + lng1.err + lng2.err + 2.0 * GSL_DBL_EPSILON * fabs(lnpre_val); const int stat_e = gsl_sf_exp_mult_err_e(lnpre_val, lnpre_err, s1*s2*lag.val, lag.err, result); return GSL_ERROR_SELECT_5(stat_e, stat_l, stat_g1, stat_g2, stat_f); } else { gsl_sf_result lnbeta; gsl_sf_lnbeta_e(b, n, &lnbeta); if(fabs(lnbeta.val) < 0.1) { /* As we have noted, when B(x,y) is near 1, * evaluating log(B(x,y)) is not accurate. * Instead we evaluate B(x,y) directly. */ const double ln_term_val = log(1.25*n); const double ln_term_err = 2.0 * GSL_DBL_EPSILON * ln_term_val; gsl_sf_result beta; int stat_b = gsl_sf_beta_e(b, n, &beta); int stat_e = gsl_sf_exp_mult_err_e(ln_term_val, ln_term_err, lag.val, lag.err, result); result->val *= beta.val/1.25; result->err *= beta.val/1.25; return GSL_ERROR_SELECT_3(stat_e, stat_l, stat_b); } else { /* B(x,y) was not near 1, so it is safe to use * the logarithmic values. */ const double ln_n = log(n); const double ln_term_val = lnbeta.val + ln_n; const double ln_term_err = lnbeta.err + 2.0 * GSL_DBL_EPSILON * fabs(ln_n); int stat_e = gsl_sf_exp_mult_err_e(ln_term_val, ln_term_err, lag.val, lag.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_l); } } } /* Handle negative integer a case for x > 0 and * generic b. * * Combine [Abramowitz+Stegun, 13.6.9 + 13.6.27] * M(-n,b,x) = (-1)^n / (b)_n U(-n,b,x) = n! / (b)_n Laguerre^(b-1)_n(x) */ #if 0 static int hyperg_1F1_a_negint_U(const int a, const double b, const double x, gsl_sf_result * result) { const int n = -a; const double sgn = ( GSL_IS_ODD(n) ? -1.0 : 1.0 ); double sgpoch; gsl_sf_result lnpoch; gsl_sf_result U; const int stat_p = gsl_sf_lnpoch_sgn_e(b, n, &lnpoch, &sgpoch); const int stat_U = gsl_sf_hyperg_U_e(-n, b, x, &U); const int stat_e = gsl_sf_exp_mult_err_e(-lnpoch.val, lnpoch.err, sgn * sgpoch * U.val, U.err, result); return GSL_ERROR_SELECT_3(stat_e, stat_U, stat_p); } #endif /* Assumes a <= -1, b <= -1, and b <= a. */ static int hyperg_1F1_ab_negint(const int a, const int b, const double x, gsl_sf_result * result) { if(x == 0.0) { result->val = 1.0; result->err = 0.0; return GSL_SUCCESS; } else if(x > 0.0) { return hyperg_1F1_a_negint_poly(a, b, x, result); } else { /* Apply a Kummer transformation to make x > 0 so * we can evaluate the polynomial safely. Of course, * this assumes b <= a, which must be true for * a<0 and b<0, since otherwise the thing is undefined. */ gsl_sf_result K; int stat_K = hyperg_1F1_a_negint_poly(b-a, b, -x, &K); int stat_e = gsl_sf_exp_mult_err_e(x, 2.0 * GSL_DBL_EPSILON * fabs(x), K.val, K.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_K); } } /* [Abramowitz+Stegun, 13.1.3] * * M(a,b,x) = Gamma(1+a-b)/Gamma(2-b) x^(1-b) * * { Gamma(b)/Gamma(a) M(1+a-b,2-b,x) - (b-1) U(1+a-b,2-b,x) } * * b not an integer >= 2 * a-b not a negative integer */ static int hyperg_1F1_U(const double a, const double b, const double x, gsl_sf_result * result) { const double bp = 2.0 - b; const double ap = a - b + 1.0; gsl_sf_result lg_ap, lg_bp; double sg_ap; int stat_lg0 = gsl_sf_lngamma_sgn_e(ap, &lg_ap, &sg_ap); int stat_lg1 = gsl_sf_lngamma_e(bp, &lg_bp); int stat_lg2 = GSL_ERROR_SELECT_2(stat_lg0, stat_lg1); double t1 = (bp-1.0) * log(x); double lnpre_val = lg_ap.val - lg_bp.val + t1; double lnpre_err = lg_ap.err + lg_bp.err + 2.0 * GSL_DBL_EPSILON * fabs(t1); gsl_sf_result lg_2mbp, lg_1papmbp; double sg_2mbp, sg_1papmbp; int stat_lg3 = gsl_sf_lngamma_sgn_e(2.0-bp, &lg_2mbp, &sg_2mbp); int stat_lg4 = gsl_sf_lngamma_sgn_e(1.0+ap-bp, &lg_1papmbp, &sg_1papmbp); int stat_lg5 = GSL_ERROR_SELECT_2(stat_lg3, stat_lg4); double lnc1_val = lg_2mbp.val - lg_1papmbp.val; double lnc1_err = lg_2mbp.err + lg_1papmbp.err + GSL_DBL_EPSILON * (fabs(lg_2mbp.val) + fabs(lg_1papmbp.val)); gsl_sf_result M; gsl_sf_result_e10 U; int stat_F = gsl_sf_hyperg_1F1_e(ap, bp, x, &M); int stat_U = gsl_sf_hyperg_U_e10_e(ap, bp, x, &U); int stat_FU = GSL_ERROR_SELECT_2(stat_F, stat_U); gsl_sf_result_e10 term_M; int stat_e0 = gsl_sf_exp_mult_err_e10_e(lnc1_val, lnc1_err, sg_2mbp*sg_1papmbp*M.val, M.err, &term_M); const double ombp = 1.0 - bp; const double Uee_val = U.e10*M_LN10; const double Uee_err = 2.0 * GSL_DBL_EPSILON * fabs(Uee_val); const double Mee_val = term_M.e10*M_LN10; const double Mee_err = 2.0 * GSL_DBL_EPSILON * fabs(Mee_val); int stat_e1; /* Do a little dance with the exponential prefactors * to avoid overflows in intermediate results. */ if(Uee_val > Mee_val) { const double factorM_val = exp(Mee_val-Uee_val); const double factorM_err = 2.0 * GSL_DBL_EPSILON * (fabs(Mee_val-Uee_val)+1.0) * factorM_val; const double inner_val = term_M.val*factorM_val - ombp*U.val; const double inner_err = term_M.err*factorM_val + fabs(ombp) * U.err + fabs(term_M.val) * factorM_err + GSL_DBL_EPSILON * (fabs(term_M.val*factorM_val) + fabs(ombp*U.val)); stat_e1 = gsl_sf_exp_mult_err_e(lnpre_val+Uee_val, lnpre_err+Uee_err, sg_ap*inner_val, inner_err, result); } else { const double factorU_val = exp(Uee_val - Mee_val); const double factorU_err = 2.0 * GSL_DBL_EPSILON * (fabs(Mee_val-Uee_val)+1.0) * factorU_val; const double inner_val = term_M.val - ombp*factorU_val*U.val; const double inner_err = term_M.err + fabs(ombp*factorU_val*U.err) + fabs(ombp*factorU_err*U.val) + GSL_DBL_EPSILON * (fabs(term_M.val) + fabs(ombp*factorU_val*U.val)); stat_e1 = gsl_sf_exp_mult_err_e(lnpre_val+Mee_val, lnpre_err+Mee_err, sg_ap*inner_val, inner_err, result); } return GSL_ERROR_SELECT_5(stat_e1, stat_e0, stat_FU, stat_lg5, stat_lg2); } /* Handle case of generic positive a, b. * Assumes b-a is not a negative integer. */ static int hyperg_1F1_ab_pos(const double a, const double b, const double x, gsl_sf_result * result) { const double ax = fabs(x); if( ( b < 10.0 && a < 10.0 && ax < 5.0 ) || ( b > a*ax ) || ( b > a && ax < 5.0 ) ) { return gsl_sf_hyperg_1F1_series_e(a, b, x, result); } else if( x < -100.0 && GSL_MAX_DBL(fabs(a),1.0)*GSL_MAX_DBL(fabs(1.0+a-b),1.0) < 0.7*fabs(x) ) { /* Large negative x asymptotic. */ return hyperg_1F1_asymp_negx(a, b, x, result); } else if( x > 100.0 && GSL_MAX_DBL(fabs(b-a),1.0)*GSL_MAX_DBL(fabs(1.0-a),1.0) < 0.7*fabs(x) ) { /* Large positive x asymptotic. */ return hyperg_1F1_asymp_posx(a, b, x, result); } else if(fabs(b-a) <= 1.0) { /* Directly handle b near a. */ return hyperg_1F1_beps_bgt0(a-b, b, x, result); /* a = b + eps */ } else if(b > a && b >= 2*a + x) { /* Use the Gautschi CF series, then * recurse backward to a near 0 for normalization. * This will work for either sign of x. */ double rap; int stat_CF1 = hyperg_1F1_CF1_p_ser(a, b, x, &rap); double ra = 1.0 + x/a * rap; double Ma = GSL_SQRT_DBL_MIN; double Map1 = ra * Ma; double Mnp1 = Map1; double Mn = Ma; double Mnm1; gsl_sf_result Mn_true; int stat_Mt; double n; for(n=a; n>0.5; n -= 1.0) { Mnm1 = (n * Mnp1 - (2.0*n-b+x) * Mn) / (b-n); Mnp1 = Mn; Mn = Mnm1; } stat_Mt = hyperg_1F1_small_a_bgt0(n, b, x, &Mn_true); result->val = (Ma/Mn) * Mn_true.val; result->err = fabs(Ma/Mn) * Mn_true.err; result->err += 2.0 * GSL_DBL_EPSILON * (fabs(a)+1.0) * fabs(result->val); return GSL_ERROR_SELECT_2(stat_Mt, stat_CF1); } else if(b > a && b < 2*a + x && b > x) { /* Use the Gautschi series representation of * the continued fraction. Then recurse forward * to near the a=b line for normalization. This will * work for either sign of x, although we do need * to check for b > x, which is relevant when x is positive. */ gsl_sf_result Mn_true; int stat_Mt; double rap; int stat_CF1 = hyperg_1F1_CF1_p_ser(a, b, x, &rap); double ra = 1.0 + x/a * rap; double Ma = GSL_SQRT_DBL_MIN; double Mnm1 = Ma; double Mn = ra * Mnm1; double Mnp1; double n; for(n=a+1.0; nval = Ma/Mn * Mn_true.val; result->err = fabs(Ma/Mn) * Mn_true.err; result->err += 2.0 * GSL_DBL_EPSILON * (fabs(b-a)+1.0) * fabs(result->val); return GSL_ERROR_SELECT_2(stat_Mt, stat_CF1); } else if(x >= 0.0) { if(b < a) { /* Forward recursion on a from a=b+eps-1,b+eps. */ double N = floor(a-b); double eps = a - b - N; gsl_sf_result r_M0; gsl_sf_result r_M1; int stat_0 = hyperg_1F1_beps_bgt0(eps-1.0, b, x, &r_M0); int stat_1 = hyperg_1F1_beps_bgt0(eps, b, x, &r_M1); double M0 = r_M0.val; double M1 = r_M1.val; double Mam1 = M0; double Ma = M1; double Map1; double ap; double start_pair = fabs(M0) + fabs(M1); double minim_pair = GSL_DBL_MAX; double pair_ratio; double rat_0 = fabs(r_M0.err/r_M0.val); double rat_1 = fabs(r_M1.err/r_M1.val); for(ap=b+eps; apval = Ma; result->err = 2.0 * (rat_0 + rat_1 + GSL_DBL_EPSILON) * (fabs(b-a)+1.0) * fabs(Ma); result->err += 2.0 * (rat_0 + rat_1) * pair_ratio*pair_ratio * fabs(Ma); result->err += 2.0 * GSL_DBL_EPSILON * fabs(Ma); return GSL_ERROR_SELECT_2(stat_0, stat_1); } else { /* b > a * b < 2a + x * b <= x * * Recurse forward on a from a=eps,eps+1. */ double eps = a - floor(a); gsl_sf_result r_Mnm1; gsl_sf_result r_Mn; int stat_0 = hyperg_1F1_small_a_bgt0(eps, b, x, &r_Mnm1); int stat_1 = hyperg_1F1_small_a_bgt0(eps+1.0, b, x, &r_Mn); double Mnm1 = r_Mnm1.val; double Mn = r_Mn.val; double Mnp1; double n; double start_pair = fabs(Mn) + fabs(Mnm1); double minim_pair = GSL_DBL_MAX; double pair_ratio; double rat_0 = fabs(r_Mnm1.err/r_Mnm1.val); double rat_1 = fabs(r_Mn.err/r_Mn.val); for(n=eps+1.0; nval = Mn; result->err = 2.0 * (rat_0 + rat_1 + GSL_DBL_EPSILON) * (fabs(a)+1.0) * fabs(Mn); result->err += 2.0 * (rat_0 + rat_1) * pair_ratio*pair_ratio * fabs(Mn); result->err += 2.0 * GSL_DBL_EPSILON * fabs(Mn); return GSL_ERROR_SELECT_2(stat_0, stat_1); } } else { /* x < 0 * b < a */ if(a <= 0.5*(b-x) || a >= -x) { /* Recurse down in b, from near the a=b line, b=a+eps,a+eps-1. */ double N = floor(a - b); double eps = 1.0 + N - a + b; gsl_sf_result r_Manp1; gsl_sf_result r_Man; int stat_0 = hyperg_1F1_beps_bgt0(-eps, a+eps, x, &r_Manp1); int stat_1 = hyperg_1F1_beps_bgt0(1.0-eps, a+eps-1.0, x, &r_Man); double Manp1 = r_Manp1.val; double Man = r_Man.val; double Manm1; double n; double start_pair = fabs(Manp1) + fabs(Man); double minim_pair = GSL_DBL_MAX; double pair_ratio; double rat_0 = fabs(r_Manp1.err/r_Manp1.val); double rat_1 = fabs(r_Man.err/r_Man.val); for(n=a+eps-1.0; n>b+0.1; n -= 1.0) { Manm1 = (-n*(1-n-x)*Man - x*(n-a)*Manp1)/(n*(n-1.0)); Manp1 = Man; Man = Manm1; minim_pair = GSL_MIN_DBL(fabs(Manp1) + fabs(Man), minim_pair); } /* FIXME: this is a nasty little hack; there is some (transient?) instability in this recurrence for some values. I can tell when it happens, which is when this pair_ratio is large. But I do not know how to measure the error in terms of it. I guessed quadratic below, but it is probably worse than that. */ pair_ratio = start_pair/minim_pair; result->val = Man; result->err = 2.0 * (rat_0 + rat_1 + GSL_DBL_EPSILON) * (fabs(b-a)+1.0) * fabs(Man); result->err *= pair_ratio*pair_ratio + 1.0; return GSL_ERROR_SELECT_2(stat_0, stat_1); } else { /* Pick a0 such that b ~= 2a0 + x, then * recurse down in b from a0,a0 to determine * the values near the line b=2a+x. Then recurse * forward on a from a0. */ double epsa = a - floor(a); double a0 = floor(0.5*(b-x)) + epsa; double N = floor(a0 - b); double epsb = 1.0 + N - a0 + b; double Ma0b; double Ma0bp1; double Ma0p1b; int stat_a0; double Mnm1; double Mn; double Mnp1; double n; double err_rat; { gsl_sf_result r_Ma0np1; gsl_sf_result r_Ma0n; int stat_0 = hyperg_1F1_beps_bgt0(-epsb, a0+epsb, x, &r_Ma0np1); int stat_1 = hyperg_1F1_beps_bgt0(1.0-epsb, a0+epsb-1.0, x, &r_Ma0n); double Ma0np1 = r_Ma0np1.val; double Ma0n = r_Ma0n.val; double Ma0nm1; err_rat = fabs(r_Ma0np1.err/r_Ma0np1.val) + fabs(r_Ma0n.err/r_Ma0n.val); for(n=a0+epsb-1.0; n>b+0.1; n -= 1.0) { Ma0nm1 = (-n*(1-n-x)*Ma0n - x*(n-a0)*Ma0np1)/(n*(n-1.0)); Ma0np1 = Ma0n; Ma0n = Ma0nm1; } Ma0bp1 = Ma0np1; Ma0b = Ma0n; Ma0p1b = (b*(a0+x)*Ma0b+x*(a0-b)*Ma0bp1)/(a0*b); /* right-down hook */ stat_a0 = GSL_ERROR_SELECT_2(stat_0, stat_1); } /* Initialise the recurrence correctly BJG */ if (a0 >= a - 0.1) { Mn = Ma0b; } else if (a0 + 1>= a - 0.1) { Mn = Ma0p1b; } else { Mnm1 = Ma0b; Mn = Ma0p1b; for(n=a0+1.0; nval = Mn; result->err = (err_rat + GSL_DBL_EPSILON) * (fabs(b-a)+1.0) * fabs(Mn); return stat_a0; } } } /* Assumes b != integer * Assumes a != integer when x > 0 * Assumes b-a != neg integer when x < 0 */ static int hyperg_1F1_ab_neg(const double a, const double b, const double x, gsl_sf_result * result) { const double bma = b - a; const double abs_x = fabs(x); const double abs_a = fabs(a); const double abs_b = fabs(b); const double size_a = GSL_MAX(abs_a, 1.0); const double size_b = GSL_MAX(abs_b, 1.0); const int bma_integer = ( bma - floor(bma+0.5) < _1F1_INT_THRESHOLD ); if( (abs_a < 10.0 && abs_b < 10.0 && abs_x < 5.0) || (b > 0.8*GSL_MAX(fabs(a),1.0)*fabs(x)) ) { return gsl_sf_hyperg_1F1_series_e(a, b, x, result); } else if( x > 0.0 && size_b > size_a && size_a*log(M_E*x/size_b) < GSL_LOG_DBL_EPSILON+7.0 ) { /* Series terms are positive definite up until * there is a sign change. But by then the * terms are small due to the last condition. */ return gsl_sf_hyperg_1F1_series_e(a, b, x, result); } else if( (abs_x < 5.0 && fabs(bma) < 10.0 && abs_b < 10.0) || (b > 0.8*GSL_MAX_DBL(fabs(bma),1.0)*abs_x) ) { /* Use Kummer transformation to render series safe. */ gsl_sf_result Kummer_1F1; int stat_K = gsl_sf_hyperg_1F1_series_e(bma, b, -x, &Kummer_1F1); int stat_e = gsl_sf_exp_mult_err_e(x, GSL_DBL_EPSILON * fabs(x), Kummer_1F1.val, Kummer_1F1.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_K); } else if( x < -30.0 && GSL_MAX_DBL(fabs(a),1.0)*GSL_MAX_DBL(fabs(1.0+a-b),1.0) < 0.99*fabs(x) ) { /* Large negative x asymptotic. * Note that we do not check if b-a is a negative integer. */ return hyperg_1F1_asymp_negx(a, b, x, result); } else if( x > 100.0 && GSL_MAX_DBL(fabs(bma),1.0)*GSL_MAX_DBL(fabs(1.0-a),1.0) < 0.99*fabs(x) ) { /* Large positive x asymptotic. * Note that we do not check if a is a negative integer. */ return hyperg_1F1_asymp_posx(a, b, x, result); } else if(x > 0.0 && !(bma_integer && bma > 0.0)) { return hyperg_1F1_U(a, b, x, result); } else { /* FIXME: if all else fails, try the series... BJG */ if (x < 0.0) { /* Apply Kummer Transformation */ int status = gsl_sf_hyperg_1F1_series_e(b-a, b, -x, result); double K_factor = exp(x); result->val *= K_factor; result->err *= K_factor; return status; } else { int status = gsl_sf_hyperg_1F1_series_e(a, b, x, result); return status; } /* Sadness... */ /* result->val = 0.0; */ /* result->err = 0.0; */ /* GSL_ERROR ("error", GSL_EUNIMPL); */ } } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_hyperg_1F1_int_e(const int a, const int b, const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x == 0.0) { result->val = 1.0; result->err = 0.0; return GSL_SUCCESS; } else if(a == b) { return gsl_sf_exp_e(x, result); } else if(b == 0) { DOMAIN_ERROR(result); } else if(a == 0) { result->val = 1.0; result->err = 0.0; return GSL_SUCCESS; } else if(b < 0 && (a < b || a > 0)) { /* Standard domain error due to singularity. */ DOMAIN_ERROR(result); } else if(x > 100.0 && GSL_MAX_DBL(1.0,fabs(b-a))*GSL_MAX_DBL(1.0,fabs(1-a)) < 0.5 * x) { /* x -> +Inf asymptotic */ return hyperg_1F1_asymp_posx(a, b, x, result); } else if(x < -100.0 && GSL_MAX_DBL(1.0,fabs(a))*GSL_MAX_DBL(1.0,fabs(1+a-b)) < 0.5 * fabs(x)) { /* x -> -Inf asymptotic */ return hyperg_1F1_asymp_negx(a, b, x, result); } else if(a < 0 && b < 0) { return hyperg_1F1_ab_negint(a, b, x, result); } else if(a < 0 && b > 0) { /* Use Kummer to reduce it to the positive integer case. * Note that b > a, strictly, since we already trapped b = a. */ gsl_sf_result Kummer_1F1; int stat_K = hyperg_1F1_ab_posint(b-a, b, -x, &Kummer_1F1); int stat_e = gsl_sf_exp_mult_err_e(x, GSL_DBL_EPSILON * fabs(x), Kummer_1F1.val, Kummer_1F1.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_K); } else { /* a > 0 and b > 0 */ return hyperg_1F1_ab_posint(a, b, x, result); } } int gsl_sf_hyperg_1F1_e(const double a, const double b, const double x, gsl_sf_result * result ) { const double bma = b - a; const double rinta = floor(a + 0.5); const double rintb = floor(b + 0.5); const double rintbma = floor(bma + 0.5); const int a_integer = ( fabs(a-rinta) < _1F1_INT_THRESHOLD && rinta > INT_MIN && rinta < INT_MAX ); const int b_integer = ( fabs(b-rintb) < _1F1_INT_THRESHOLD && rintb > INT_MIN && rintb < INT_MAX ); const int bma_integer = ( fabs(bma-rintbma) < _1F1_INT_THRESHOLD && rintbma > INT_MIN && rintbma < INT_MAX ); const int b_neg_integer = ( b < -0.1 && b_integer ); const int a_neg_integer = ( a < -0.1 && a_integer ); const int bma_neg_integer = ( bma < -0.1 && bma_integer ); /* CHECK_POINTER(result) */ if(x == 0.0) { /* Testing for this before testing a and b * is somewhat arbitrary. The result is that * we have 1F1(a,0,0) = 1. */ result->val = 1.0; result->err = 0.0; return GSL_SUCCESS; } else if(b == 0.0) { DOMAIN_ERROR(result); } else if(a == 0.0) { result->val = 1.0; result->err = 0.0; return GSL_SUCCESS; } else if(a == b) { /* case: a==b; exp(x) * It's good to test exact equality now. * We also test approximate equality later. */ return gsl_sf_exp_e(x, result); } else if(fabs(b) < _1F1_INT_THRESHOLD && fabs(a) < _1F1_INT_THRESHOLD) { /* a and b near zero: 1 + a/b (exp(x)-1) */ /* Note that neither a nor b is zero, since * we eliminated that with the above tests. */ gsl_sf_result exm1; int stat_e = gsl_sf_expm1_e(x, &exm1); double sa = ( a > 0.0 ? 1.0 : -1.0 ); double sb = ( b > 0.0 ? 1.0 : -1.0 ); double lnab = log(fabs(a/b)); /* safe */ gsl_sf_result hx; int stat_hx = gsl_sf_exp_mult_err_e(lnab, GSL_DBL_EPSILON * fabs(lnab), sa * sb * exm1.val, exm1.err, &hx); result->val = (hx.val == GSL_DBL_MAX ? hx.val : 1.0 + hx.val); /* FIXME: excessive paranoia ? what is DBL_MAX+1 ?*/ result->err = hx.err; return GSL_ERROR_SELECT_2(stat_hx, stat_e); } else if (fabs(b) < _1F1_INT_THRESHOLD && fabs(x*a) < 1) { /* b near zero and a not near zero */ const double m_arg = 1.0/(0.5*b); gsl_sf_result F_renorm; int stat_F = hyperg_1F1_renorm_b0(a, x, &F_renorm); int stat_m = gsl_sf_multiply_err_e(m_arg, 2.0 * GSL_DBL_EPSILON * m_arg, 0.5*F_renorm.val, 0.5*F_renorm.err, result); return GSL_ERROR_SELECT_2(stat_m, stat_F); } else if(a_integer && b_integer) { /* Check for reduction to the integer case. * Relies on the arbitrary "near an integer" test. */ return gsl_sf_hyperg_1F1_int_e((int)rinta, (int)rintb, x, result); } else if(b_neg_integer && !(a_neg_integer && a > b)) { /* Standard domain error due to * uncancelled singularity. */ DOMAIN_ERROR(result); } else if(a_neg_integer) { return hyperg_1F1_a_negint_lag((int)rinta, b, x, result); } else if(b > 0.0) { if(-1.0 <= a && a <= 1.0) { /* Handle small a explicitly. */ return hyperg_1F1_small_a_bgt0(a, b, x, result); } else if(bma_neg_integer) { /* Catch this now, to avoid problems in the * generic evaluation code. */ gsl_sf_result Kummer_1F1; int stat_K = hyperg_1F1_a_negint_lag((int)rintbma, b, -x, &Kummer_1F1); int stat_e = gsl_sf_exp_mult_err_e(x, GSL_DBL_EPSILON * fabs(x), Kummer_1F1.val, Kummer_1F1.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_K); } else if(a < 0.0 && fabs(x) < 100.0) { /* Use Kummer to reduce it to the generic positive case. * Note that b > a, strictly, since we already trapped b = a. * Also b-(b-a)=a, and a is not a negative integer here, * so the generic evaluation is safe. */ gsl_sf_result Kummer_1F1; int stat_K = hyperg_1F1_ab_pos(b-a, b, -x, &Kummer_1F1); int stat_e = gsl_sf_exp_mult_err_e(x, GSL_DBL_EPSILON * fabs(x), Kummer_1F1.val, Kummer_1F1.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_K); } else if (a > 0) { /* a > 0.0 */ return hyperg_1F1_ab_pos(a, b, x, result); } else { return gsl_sf_hyperg_1F1_series_e(a, b, x, result); } } else { /* b < 0.0 */ if(bma_neg_integer && x < 0.0) { /* Handle this now to prevent problems * in the generic evaluation. */ gsl_sf_result K; int stat_K; int stat_e; if(a < 0.0) { /* Kummer transformed version of safe polynomial. * The condition a < 0 is equivalent to b < b-a, * which is the condition required for the series * to be positive definite here. */ stat_K = hyperg_1F1_a_negint_poly((int)rintbma, b, -x, &K); } else { /* Generic eval for negative integer a. */ stat_K = hyperg_1F1_a_negint_lag((int)rintbma, b, -x, &K); } stat_e = gsl_sf_exp_mult_err_e(x, GSL_DBL_EPSILON * fabs(x), K.val, K.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_K); } else if(a > 0.0) { /* Use Kummer to reduce it to the generic negative case. */ gsl_sf_result K; int stat_K = hyperg_1F1_ab_neg(b-a, b, -x, &K); int stat_e = gsl_sf_exp_mult_err_e(x, GSL_DBL_EPSILON * fabs(x), K.val, K.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_K); } else { return hyperg_1F1_ab_neg(a, b, x, result); } } } #if 0 /* Luke in the canonical case. */ if(x < 0.0 && !a_neg_integer && !bma_neg_integer) { double prec; return hyperg_1F1_luke(a, b, x, result, &prec); } /* Luke with Kummer transformation. */ if(x > 0.0 && !a_neg_integer && !bma_neg_integer) { double prec; double Kummer_1F1; double ex; int stat_F = hyperg_1F1_luke(b-a, b, -x, &Kummer_1F1, &prec); int stat_e = gsl_sf_exp_e(x, &ex); if(stat_F == GSL_SUCCESS && stat_e == GSL_SUCCESS) { double lnr = log(fabs(Kummer_1F1)) + x; if(lnr < GSL_LOG_DBL_MAX) { *result = ex * Kummer_1F1; return GSL_SUCCESS; } else { *result = GSL_POSINF; GSL_ERROR ("overflow", GSL_EOVRFLW); } } else if(stat_F != GSL_SUCCESS) { *result = 0.0; return stat_F; } else { *result = 0.0; return stat_e; } } #endif /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_hyperg_1F1_int(const int m, const int n, double x) { EVAL_RESULT(gsl_sf_hyperg_1F1_int_e(m, n, x, &result)); } double gsl_sf_hyperg_1F1(double a, double b, double x) { EVAL_RESULT(gsl_sf_hyperg_1F1_e(a, b, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__hyperg_2F0.c000066400000000000000000000035761261542461700223050ustar00rootroot00000000000000/* specfunc/hyperg_2F0.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_hyperg.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__hyperg.h" int gsl_sf_hyperg_2F0_e(const double a, const double b, const double x, gsl_sf_result * result) { if(x < 0.0) { /* Use "definition" 2F0(a,b,x) = (-1/x)^a U(a,1+a-b,-1/x). */ gsl_sf_result U; double pre = pow(-1.0/x, a); int stat_U = gsl_sf_hyperg_U_e(a, 1.0+a-b, -1.0/x, &U); result->val = pre * U.val; result->err = GSL_DBL_EPSILON * fabs(result->val) + pre * U.err; return stat_U; } else if(x == 0.0) { result->val = 1.0; result->err = 0.0; return GSL_SUCCESS; } else { /* Use asymptotic series. ?? */ /* return hyperg_2F0_series(a, b, x, -1, result, &prec); */ DOMAIN_ERROR(result); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_hyperg_2F0(const double a, const double b, const double x) { EVAL_RESULT(gsl_sf_hyperg_2F0_e(a, b, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__hyperg_2F1.c000066400000000000000000000660201261542461700222770ustar00rootroot00000000000000/* specfunc/hyperg_2F1.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_exp.h" #include "gsl_sf_pow_int.h" #include "gsl_sf_gamma.h" #include "gsl_sf_psi.h" #include "gsl_sf_hyperg.h" #include "gsl_specfunc__error.h" #define locEPS (1000.0*GSL_DBL_EPSILON) /* Assumes c != negative integer. */ static int hyperg_2F1_series(const double a, const double b, const double c, const double x, gsl_sf_result * result ) { double sum_pos = 1.0; double sum_neg = 0.0; double del_pos = 1.0; double del_neg = 0.0; double del = 1.0; double k = 0.0; int i = 0; if(fabs(c) < GSL_DBL_EPSILON) { result->val = 0.0; /* FIXME: ?? */ result->err = 1.0; GSL_ERROR ("error", GSL_EDOM); } do { if(++i > 30000) { result->val = sum_pos - sum_neg; result->err = del_pos + del_neg; result->err += 2.0 * GSL_DBL_EPSILON * (sum_pos + sum_neg); result->err += 2.0 * GSL_DBL_EPSILON * (2.0*sqrt(k)+1.0) * fabs(result->val); GSL_ERROR ("error", GSL_EMAXITER); } del *= (a+k)*(b+k) * x / ((c+k) * (k+1.0)); /* Gauss series */ if(del > 0.0) { del_pos = del; sum_pos += del; } else if(del == 0.0) { /* Exact termination (a or b was a negative integer). */ del_pos = 0.0; del_neg = 0.0; break; } else { del_neg = -del; sum_neg -= del; } k += 1.0; } while(fabs((del_pos + del_neg)/(sum_pos-sum_neg)) > GSL_DBL_EPSILON); result->val = sum_pos - sum_neg; result->err = del_pos + del_neg; result->err += 2.0 * GSL_DBL_EPSILON * (sum_pos + sum_neg); result->err += 2.0 * GSL_DBL_EPSILON * (2.0*sqrt(k) + 1.0) * fabs(result->val); return GSL_SUCCESS; } /* a = aR + i aI, b = aR - i aI */ static int hyperg_2F1_conj_series(const double aR, const double aI, const double c, double x, gsl_sf_result * result) { if(c == 0.0) { result->val = 0.0; /* FIXME: should be Inf */ result->err = 0.0; GSL_ERROR ("error", GSL_EDOM); } else { double sum_pos = 1.0; double sum_neg = 0.0; double del_pos = 1.0; double del_neg = 0.0; double del = 1.0; double k = 0.0; do { del *= ((aR+k)*(aR+k) + aI*aI)/((k+1.0)*(c+k)) * x; if(del >= 0.0) { del_pos = del; sum_pos += del; } else { del_neg = -del; sum_neg -= del; } if(k > 30000) { result->val = sum_pos - sum_neg; result->err = del_pos + del_neg; result->err += 2.0 * GSL_DBL_EPSILON * (sum_pos + sum_neg); result->err += 2.0 * GSL_DBL_EPSILON * (2.0*sqrt(k)+1.0) * fabs(result->val); GSL_ERROR ("error", GSL_EMAXITER); } k += 1.0; } while(fabs((del_pos + del_neg)/(sum_pos - sum_neg)) > GSL_DBL_EPSILON); result->val = sum_pos - sum_neg; result->err = del_pos + del_neg; result->err += 2.0 * GSL_DBL_EPSILON * (sum_pos + sum_neg); result->err += 2.0 * GSL_DBL_EPSILON * (2.0*sqrt(k) + 1.0) * fabs(result->val); return GSL_SUCCESS; } } /* Luke's rational approximation. The most accesible * discussion is in [Kolbig, CPC 23, 51 (1981)]. * The convergence is supposedly guaranteed for x < 0. * You have to read Luke's books to see this and other * results. Unfortunately, the stability is not so * clear to me, although it seems very efficient when * it works. */ static int hyperg_2F1_luke(const double a, const double b, const double c, const double xin, gsl_sf_result * result) { int stat_iter; const double RECUR_BIG = 1.0e+50; const int nmax = 20000; int n = 3; const double x = -xin; const double x3 = x*x*x; const double t0 = a*b/c; const double t1 = (a+1.0)*(b+1.0)/(2.0*c); const double t2 = (a+2.0)*(b+2.0)/(2.0*(c+1.0)); double F = 1.0; double prec; double Bnm3 = 1.0; /* B0 */ double Bnm2 = 1.0 + t1 * x; /* B1 */ double Bnm1 = 1.0 + t2 * x * (1.0 + t1/3.0 * x); /* B2 */ double Anm3 = 1.0; /* A0 */ double Anm2 = Bnm2 - t0 * x; /* A1 */ double Anm1 = Bnm1 - t0*(1.0 + t2*x)*x + t0 * t1 * (c/(c+1.0)) * x*x; /* A2 */ while(1) { double npam1 = n + a - 1; double npbm1 = n + b - 1; double npcm1 = n + c - 1; double npam2 = n + a - 2; double npbm2 = n + b - 2; double npcm2 = n + c - 2; double tnm1 = 2*n - 1; double tnm3 = 2*n - 3; double tnm5 = 2*n - 5; double n2 = n*n; double F1 = (3.0*n2 + (a+b-6)*n + 2 - a*b - 2*(a+b)) / (2*tnm3*npcm1); double F2 = -(3.0*n2 - (a+b+6)*n + 2 - a*b)*npam1*npbm1/(4*tnm1*tnm3*npcm2*npcm1); double F3 = (npam2*npam1*npbm2*npbm1*(n-a-2)*(n-b-2)) / (8*tnm3*tnm3*tnm5*(n+c-3)*npcm2*npcm1); double E = -npam1*npbm1*(n-c-1) / (2*tnm3*npcm2*npcm1); double An = (1.0+F1*x)*Anm1 + (E + F2*x)*x*Anm2 + F3*x3*Anm3; double Bn = (1.0+F1*x)*Bnm1 + (E + F2*x)*x*Bnm2 + F3*x3*Bnm3; double r = An/Bn; prec = fabs((F - r)/F); F = r; if(prec < GSL_DBL_EPSILON || n > nmax) break; if(fabs(An) > RECUR_BIG || fabs(Bn) > RECUR_BIG) { An /= RECUR_BIG; Bn /= RECUR_BIG; Anm1 /= RECUR_BIG; Bnm1 /= RECUR_BIG; Anm2 /= RECUR_BIG; Bnm2 /= RECUR_BIG; Anm3 /= RECUR_BIG; Bnm3 /= RECUR_BIG; } else if(fabs(An) < 1.0/RECUR_BIG || fabs(Bn) < 1.0/RECUR_BIG) { An *= RECUR_BIG; Bn *= RECUR_BIG; Anm1 *= RECUR_BIG; Bnm1 *= RECUR_BIG; Anm2 *= RECUR_BIG; Bnm2 *= RECUR_BIG; Anm3 *= RECUR_BIG; Bnm3 *= RECUR_BIG; } n++; Bnm3 = Bnm2; Bnm2 = Bnm1; Bnm1 = Bn; Anm3 = Anm2; Anm2 = Anm1; Anm1 = An; } result->val = F; result->err = 2.0 * fabs(prec * F); result->err += 2.0 * GSL_DBL_EPSILON * (n+1.0) * fabs(F); /* FIXME: just a hack: there's a lot of shit going on here */ result->err *= 8.0 * (fabs(a) + fabs(b) + 1.0); stat_iter = (n >= nmax ? GSL_EMAXITER : GSL_SUCCESS ); return stat_iter; } /* Luke's rational approximation for the * case a = aR + i aI, b = aR - i aI. */ static int hyperg_2F1_conj_luke(const double aR, const double aI, const double c, const double xin, gsl_sf_result * result) { int stat_iter; const double RECUR_BIG = 1.0e+50; const int nmax = 10000; int n = 3; const double x = -xin; const double x3 = x*x*x; const double atimesb = aR*aR + aI*aI; const double apb = 2.0*aR; const double t0 = atimesb/c; const double t1 = (atimesb + apb + 1.0)/(2.0*c); const double t2 = (atimesb + 2.0*apb + 4.0)/(2.0*(c+1.0)); double F = 1.0; double prec; double Bnm3 = 1.0; /* B0 */ double Bnm2 = 1.0 + t1 * x; /* B1 */ double Bnm1 = 1.0 + t2 * x * (1.0 + t1/3.0 * x); /* B2 */ double Anm3 = 1.0; /* A0 */ double Anm2 = Bnm2 - t0 * x; /* A1 */ double Anm1 = Bnm1 - t0*(1.0 + t2*x)*x + t0 * t1 * (c/(c+1.0)) * x*x; /* A2 */ while(1) { double nm1 = n - 1; double nm2 = n - 2; double npam1_npbm1 = atimesb + nm1*apb + nm1*nm1; double npam2_npbm2 = atimesb + nm2*apb + nm2*nm2; double npcm1 = nm1 + c; double npcm2 = nm2 + c; double tnm1 = 2*n - 1; double tnm3 = 2*n - 3; double tnm5 = 2*n - 5; double n2 = n*n; double F1 = (3.0*n2 + (apb-6)*n + 2 - atimesb - 2*apb) / (2*tnm3*npcm1); double F2 = -(3.0*n2 - (apb+6)*n + 2 - atimesb)*npam1_npbm1/(4*tnm1*tnm3*npcm2*npcm1); double F3 = (npam2_npbm2*npam1_npbm1*(nm2*nm2 - nm2*apb + atimesb)) / (8*tnm3*tnm3*tnm5*(n+c-3)*npcm2*npcm1); double E = -npam1_npbm1*(n-c-1) / (2*tnm3*npcm2*npcm1); double An = (1.0+F1*x)*Anm1 + (E + F2*x)*x*Anm2 + F3*x3*Anm3; double Bn = (1.0+F1*x)*Bnm1 + (E + F2*x)*x*Bnm2 + F3*x3*Bnm3; double r = An/Bn; prec = fabs(F - r)/fabs(F); F = r; if(prec < GSL_DBL_EPSILON || n > nmax) break; if(fabs(An) > RECUR_BIG || fabs(Bn) > RECUR_BIG) { An /= RECUR_BIG; Bn /= RECUR_BIG; Anm1 /= RECUR_BIG; Bnm1 /= RECUR_BIG; Anm2 /= RECUR_BIG; Bnm2 /= RECUR_BIG; Anm3 /= RECUR_BIG; Bnm3 /= RECUR_BIG; } else if(fabs(An) < 1.0/RECUR_BIG || fabs(Bn) < 1.0/RECUR_BIG) { An *= RECUR_BIG; Bn *= RECUR_BIG; Anm1 *= RECUR_BIG; Bnm1 *= RECUR_BIG; Anm2 *= RECUR_BIG; Bnm2 *= RECUR_BIG; Anm3 *= RECUR_BIG; Bnm3 *= RECUR_BIG; } n++; Bnm3 = Bnm2; Bnm2 = Bnm1; Bnm1 = Bn; Anm3 = Anm2; Anm2 = Anm1; Anm1 = An; } result->val = F; result->err = 2.0 * fabs(prec * F); result->err += 2.0 * GSL_DBL_EPSILON * (n+1.0) * fabs(F); /* FIXME: see above */ result->err *= 8.0 * (fabs(aR) + fabs(aI) + 1.0); stat_iter = (n >= nmax ? GSL_EMAXITER : GSL_SUCCESS ); return stat_iter; } /* Do the reflection described in [Moshier, p. 334]. * Assumes a,b,c != neg integer. */ static int hyperg_2F1_reflect(const double a, const double b, const double c, const double x, gsl_sf_result * result) { const double d = c - a - b; const int intd = floor(d+0.5); const int d_integer = ( fabs(d - intd) < locEPS ); if(d_integer) { const double ln_omx = log(1.0 - x); const double ad = fabs(d); int stat_F2 = GSL_SUCCESS; double sgn_2; gsl_sf_result F1; gsl_sf_result F2; double d1, d2; gsl_sf_result lng_c; gsl_sf_result lng_ad2; gsl_sf_result lng_bd2; int stat_c; int stat_ad2; int stat_bd2; if(d >= 0.0) { d1 = d; d2 = 0.0; } else { d1 = 0.0; d2 = d; } stat_ad2 = gsl_sf_lngamma_e(a+d2, &lng_ad2); stat_bd2 = gsl_sf_lngamma_e(b+d2, &lng_bd2); stat_c = gsl_sf_lngamma_e(c, &lng_c); /* Evaluate F1. */ if(ad < GSL_DBL_EPSILON) { /* d = 0 */ F1.val = 0.0; F1.err = 0.0; } else { gsl_sf_result lng_ad; gsl_sf_result lng_ad1; gsl_sf_result lng_bd1; int stat_ad = gsl_sf_lngamma_e(ad, &lng_ad); int stat_ad1 = gsl_sf_lngamma_e(a+d1, &lng_ad1); int stat_bd1 = gsl_sf_lngamma_e(b+d1, &lng_bd1); if(stat_ad1 == GSL_SUCCESS && stat_bd1 == GSL_SUCCESS && stat_ad == GSL_SUCCESS) { /* Gamma functions in the denominator are ok. * Proceed with evaluation. */ int i; double sum1 = 1.0; double term = 1.0; double ln_pre1_val = lng_ad.val + lng_c.val + d2*ln_omx - lng_ad1.val - lng_bd1.val; double ln_pre1_err = lng_ad.err + lng_c.err + lng_ad1.err + lng_bd1.err + GSL_DBL_EPSILON * fabs(ln_pre1_val); int stat_e; /* Do F1 sum. */ for(i=1; ival = 0.0; result->err = 0.0; GSL_ERROR ("error", GSL_EOVRFLW); } } stat_F2 = GSL_ERROR_SELECT_2(stat_F2, stat_dall); } else { /* Gamma functions in the denominator not ok. * So the F2 term is zero. */ F2.val = 0.0; F2.err = 0.0; } /* end F2 evaluation */ sgn_2 = ( GSL_IS_ODD(intd) ? -1.0 : 1.0 ); result->val = F1.val + sgn_2 * F2.val; result->err = F1.err + F2. err; result->err += 2.0 * GSL_DBL_EPSILON * (fabs(F1.val) + fabs(F2.val)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_F2; } else { /* d not an integer */ gsl_sf_result pre1, pre2; double sgn1, sgn2; gsl_sf_result F1, F2; int status_F1, status_F2; /* These gamma functions appear in the denominator, so we * catch their harmless domain errors and set the terms to zero. */ gsl_sf_result ln_g1ca, ln_g1cb, ln_g2a, ln_g2b; double sgn_g1ca, sgn_g1cb, sgn_g2a, sgn_g2b; int stat_1ca = gsl_sf_lngamma_sgn_e(c-a, &ln_g1ca, &sgn_g1ca); int stat_1cb = gsl_sf_lngamma_sgn_e(c-b, &ln_g1cb, &sgn_g1cb); int stat_2a = gsl_sf_lngamma_sgn_e(a, &ln_g2a, &sgn_g2a); int stat_2b = gsl_sf_lngamma_sgn_e(b, &ln_g2b, &sgn_g2b); int ok1 = (stat_1ca == GSL_SUCCESS && stat_1cb == GSL_SUCCESS); int ok2 = (stat_2a == GSL_SUCCESS && stat_2b == GSL_SUCCESS); gsl_sf_result ln_gc, ln_gd, ln_gmd; double sgn_gc, sgn_gd, sgn_gmd; gsl_sf_lngamma_sgn_e( c, &ln_gc, &sgn_gc); gsl_sf_lngamma_sgn_e( d, &ln_gd, &sgn_gd); gsl_sf_lngamma_sgn_e(-d, &ln_gmd, &sgn_gmd); sgn1 = sgn_gc * sgn_gd * sgn_g1ca * sgn_g1cb; sgn2 = sgn_gc * sgn_gmd * sgn_g2a * sgn_g2b; if(ok1 && ok2) { double ln_pre1_val = ln_gc.val + ln_gd.val - ln_g1ca.val - ln_g1cb.val; double ln_pre2_val = ln_gc.val + ln_gmd.val - ln_g2a.val - ln_g2b.val + d*log(1.0-x); double ln_pre1_err = ln_gc.err + ln_gd.err + ln_g1ca.err + ln_g1cb.err; double ln_pre2_err = ln_gc.err + ln_gmd.err + ln_g2a.err + ln_g2b.err; if(ln_pre1_val < GSL_LOG_DBL_MAX && ln_pre2_val < GSL_LOG_DBL_MAX) { gsl_sf_exp_err_e(ln_pre1_val, ln_pre1_err, &pre1); gsl_sf_exp_err_e(ln_pre2_val, ln_pre2_err, &pre2); pre1.val *= sgn1; pre2.val *= sgn2; } else { OVERFLOW_ERROR(result); } } else if(ok1 && !ok2) { double ln_pre1_val = ln_gc.val + ln_gd.val - ln_g1ca.val - ln_g1cb.val; double ln_pre1_err = ln_gc.err + ln_gd.err + ln_g1ca.err + ln_g1cb.err; if(ln_pre1_val < GSL_LOG_DBL_MAX) { gsl_sf_exp_err_e(ln_pre1_val, ln_pre1_err, &pre1); pre1.val *= sgn1; pre2.val = 0.0; pre2.err = 0.0; } else { OVERFLOW_ERROR(result); } } else if(!ok1 && ok2) { double ln_pre2_val = ln_gc.val + ln_gmd.val - ln_g2a.val - ln_g2b.val + d*log(1.0-x); double ln_pre2_err = ln_gc.err + ln_gmd.err + ln_g2a.err + ln_g2b.err; if(ln_pre2_val < GSL_LOG_DBL_MAX) { pre1.val = 0.0; pre1.err = 0.0; gsl_sf_exp_err_e(ln_pre2_val, ln_pre2_err, &pre2); pre2.val *= sgn2; } else { OVERFLOW_ERROR(result); } } else { pre1.val = 0.0; pre2.val = 0.0; UNDERFLOW_ERROR(result); } status_F1 = hyperg_2F1_series( a, b, 1.0-d, 1.0-x, &F1); status_F2 = hyperg_2F1_series(c-a, c-b, 1.0+d, 1.0-x, &F2); result->val = pre1.val*F1.val + pre2.val*F2.val; result->err = fabs(pre1.val*F1.err) + fabs(pre2.val*F2.err); result->err += fabs(pre1.err*F1.val) + fabs(pre2.err*F2.val); result->err += 2.0 * GSL_DBL_EPSILON * (fabs(pre1.val*F1.val) + fabs(pre2.val*F2.val)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } static int pow_omx(const double x, const double p, gsl_sf_result * result) { double ln_omx; double ln_result; if(fabs(x) < GSL_ROOT5_DBL_EPSILON) { ln_omx = -x*(1.0 + x*(1.0/2.0 + x*(1.0/3.0 + x/4.0 + x*x/5.0))); } else { ln_omx = log(1.0-x); } ln_result = p * ln_omx; return gsl_sf_exp_err_e(ln_result, GSL_DBL_EPSILON * fabs(ln_result), result); } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_hyperg_2F1_e(double a, double b, const double c, const double x, gsl_sf_result * result) { const double d = c - a - b; const double rinta = floor(a + 0.5); const double rintb = floor(b + 0.5); const double rintc = floor(c + 0.5); const int a_neg_integer = ( a < 0.0 && fabs(a - rinta) < locEPS ); const int b_neg_integer = ( b < 0.0 && fabs(b - rintb) < locEPS ); const int c_neg_integer = ( c < 0.0 && fabs(c - rintc) < locEPS ); result->val = 0.0; result->err = 0.0; if(x < -1.0 || 1.0 <= x) { DOMAIN_ERROR(result); } if(c_neg_integer) { if(! (a_neg_integer && a > c + 0.1)) DOMAIN_ERROR(result); if(! (b_neg_integer && b > c + 0.1)) DOMAIN_ERROR(result); } if(fabs(c-b) < locEPS || fabs(c-a) < locEPS) { return pow_omx(x, d, result); /* (1-x)^(c-a-b) */ } if(a >= 0.0 && b >= 0.0 && c >=0.0 && x >= 0.0 && x < 0.995) { /* Series has all positive definite * terms and x is not close to 1. */ return hyperg_2F1_series(a, b, c, x, result); } if(fabs(a) < 10.0 && fabs(b) < 10.0) { /* a and b are not too large, so we attempt * variations on the series summation. */ if(a_neg_integer) { return hyperg_2F1_series(rinta, b, c, x, result); } if(b_neg_integer) { return hyperg_2F1_series(a, rintb, c, x, result); } if(x < -0.25) { return hyperg_2F1_luke(a, b, c, x, result); } else if(x < 0.5) { return hyperg_2F1_series(a, b, c, x, result); } else { if(fabs(c) > 10.0) { return hyperg_2F1_series(a, b, c, x, result); } else { return hyperg_2F1_reflect(a, b, c, x, result); } } } else { /* Either a or b or both large. * Introduce some new variables ap,bp so that bp is * the larger in magnitude. */ double ap, bp; if(fabs(a) > fabs(b)) { bp = a; ap = b; } else { bp = b; ap = a; } if(x < 0.0) { /* What the hell, maybe Luke will converge. */ return hyperg_2F1_luke(a, b, c, x, result); } if(GSL_MAX_DBL(fabs(a),1.0)*fabs(bp)*fabs(x) < 2.0*fabs(c)) { /* If c is large enough or x is small enough, * we can attempt the series anyway. */ return hyperg_2F1_series(a, b, c, x, result); } if(fabs(bp*bp*x*x) < 0.001*fabs(bp) && fabs(a) < 10.0) { /* The famous but nearly worthless "large b" asymptotic. */ int stat = gsl_sf_hyperg_1F1_e(a, c, bp*x, result); result->err = 0.001 * fabs(result->val); return stat; } /* We give up. */ result->val = 0.0; result->err = 0.0; GSL_ERROR ("error", GSL_EUNIMPL); } } int gsl_sf_hyperg_2F1_conj_e(const double aR, const double aI, const double c, const double x, gsl_sf_result * result) { const double ax = fabs(x); const double rintc = floor(c + 0.5); const int c_neg_integer = ( c < 0.0 && fabs(c - rintc) < locEPS ); result->val = 0.0; result->err = 0.0; if(ax >= 1.0 || c_neg_integer || c == 0.0) { DOMAIN_ERROR(result); } if( (ax < 0.25 && fabs(aR) < 20.0 && fabs(aI) < 20.0) || (c > 0.0 && x > 0.0) ) { return hyperg_2F1_conj_series(aR, aI, c, x, result); } else if(fabs(aR) < 10.0 && fabs(aI) < 10.0) { if(x < -0.25) { return hyperg_2F1_conj_luke(aR, aI, c, x, result); } else { return hyperg_2F1_conj_series(aR, aI, c, x, result); } } else { if(x < 0.0) { /* What the hell, maybe Luke will converge. */ return hyperg_2F1_conj_luke(aR, aI, c, x, result); } /* Give up. */ result->val = 0.0; result->err = 0.0; GSL_ERROR ("error", GSL_EUNIMPL); } } int gsl_sf_hyperg_2F1_renorm_e(const double a, const double b, const double c, const double x, gsl_sf_result * result ) { const double rinta = floor(a + 0.5); const double rintb = floor(b + 0.5); const double rintc = floor(c + 0.5); const int a_neg_integer = ( a < 0.0 && fabs(a - rinta) < locEPS ); const int b_neg_integer = ( b < 0.0 && fabs(b - rintb) < locEPS ); const int c_neg_integer = ( c < 0.0 && fabs(c - rintc) < locEPS ); if(c_neg_integer) { if((a_neg_integer && a > c+0.1) || (b_neg_integer && b > c+0.1)) { /* 2F1 terminates early */ result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else { /* 2F1 does not terminate early enough, so something survives */ /* [Abramowitz+Stegun, 15.1.2] */ gsl_sf_result g1, g2, g3, g4, g5; double s1, s2, s3, s4, s5; int stat = 0; stat += gsl_sf_lngamma_sgn_e(a-c+1, &g1, &s1); stat += gsl_sf_lngamma_sgn_e(b-c+1, &g2, &s2); stat += gsl_sf_lngamma_sgn_e(a, &g3, &s3); stat += gsl_sf_lngamma_sgn_e(b, &g4, &s4); stat += gsl_sf_lngamma_sgn_e(-c+2, &g5, &s5); if(stat != 0) { DOMAIN_ERROR(result); } else { gsl_sf_result F; int stat_F = gsl_sf_hyperg_2F1_e(a-c+1, b-c+1, -c+2, x, &F); double ln_pre_val = g1.val + g2.val - g3.val - g4.val - g5.val; double ln_pre_err = g1.err + g2.err + g3.err + g4.err + g5.err; double sg = s1 * s2 * s3 * s4 * s5; int stat_e = gsl_sf_exp_mult_err_e(ln_pre_val, ln_pre_err, sg * F.val, F.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_F); } } } else { /* generic c */ gsl_sf_result F; gsl_sf_result lng; double sgn; int stat_g = gsl_sf_lngamma_sgn_e(c, &lng, &sgn); int stat_F = gsl_sf_hyperg_2F1_e(a, b, c, x, &F); int stat_e = gsl_sf_exp_mult_err_e(-lng.val, lng.err, sgn*F.val, F.err, result); return GSL_ERROR_SELECT_3(stat_e, stat_F, stat_g); } } int gsl_sf_hyperg_2F1_conj_renorm_e(const double aR, const double aI, const double c, const double x, gsl_sf_result * result ) { const double rintc = floor(c + 0.5); const double rinta = floor(aR + 0.5); const int a_neg_integer = ( aR < 0.0 && fabs(aR-rinta) < locEPS && aI == 0.0); const int c_neg_integer = ( c < 0.0 && fabs(c - rintc) < locEPS ); if(c_neg_integer) { if(a_neg_integer && aR > c+0.1) { /* 2F1 terminates early */ result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else { /* 2F1 does not terminate early enough, so something survives */ /* [Abramowitz+Stegun, 15.1.2] */ gsl_sf_result g1, g2; gsl_sf_result g3; gsl_sf_result a1, a2; int stat = 0; stat += gsl_sf_lngamma_complex_e(aR-c+1, aI, &g1, &a1); stat += gsl_sf_lngamma_complex_e(aR, aI, &g2, &a2); stat += gsl_sf_lngamma_e(-c+2.0, &g3); if(stat != 0) { DOMAIN_ERROR(result); } else { gsl_sf_result F; int stat_F = gsl_sf_hyperg_2F1_conj_e(aR-c+1, aI, -c+2, x, &F); double ln_pre_val = 2.0*(g1.val - g2.val) - g3.val; double ln_pre_err = 2.0 * (g1.err + g2.err) + g3.err; int stat_e = gsl_sf_exp_mult_err_e(ln_pre_val, ln_pre_err, F.val, F.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_F); } } } else { /* generic c */ gsl_sf_result F; gsl_sf_result lng; double sgn; int stat_g = gsl_sf_lngamma_sgn_e(c, &lng, &sgn); int stat_F = gsl_sf_hyperg_2F1_conj_e(aR, aI, c, x, &F); int stat_e = gsl_sf_exp_mult_err_e(-lng.val, lng.err, sgn*F.val, F.err, result); return GSL_ERROR_SELECT_3(stat_e, stat_F, stat_g); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_hyperg_2F1(double a, double b, double c, double x) { EVAL_RESULT(gsl_sf_hyperg_2F1_e(a, b, c, x, &result)); } double gsl_sf_hyperg_2F1_conj(double aR, double aI, double c, double x) { EVAL_RESULT(gsl_sf_hyperg_2F1_conj_e(aR, aI, c, x, &result)); } double gsl_sf_hyperg_2F1_renorm(double a, double b, double c, double x) { EVAL_RESULT(gsl_sf_hyperg_2F1_renorm_e(a, b, c, x, &result)); } double gsl_sf_hyperg_2F1_conj_renorm(double aR, double aI, double c, double x) { EVAL_RESULT(gsl_sf_hyperg_2F1_conj_renorm_e(aR, aI, c, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__hyperg_U.c000066400000000000000000001274201261542461700221550ustar00rootroot00000000000000/* specfunc/hyperg_U.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_exp.h" #include "gsl_sf_gamma.h" #include "gsl_sf_bessel.h" #include "gsl_sf_laguerre.h" #include "gsl_sf_pow_int.h" #include "gsl_sf_hyperg.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__hyperg.h" #define INT_THRESHOLD (1000.0*GSL_DBL_EPSILON) #define SERIES_EVAL_OK(a,b,x) ((fabs(a) < 5 && b < 5 && x < 2.0) || (fabs(a) < 10 && b < 10 && x < 1.0)) #define ASYMP_EVAL_OK(a,b,x) (GSL_MAX_DBL(fabs(a),1.0)*GSL_MAX_DBL(fabs(1.0+a-b),1.0) < 0.99*fabs(x)) /* Log[U(a,2a,x)] * [Abramowitz+stegun, 13.6.21] * Assumes x > 0, a > 1/2. */ static int hyperg_lnU_beq2a(const double a, const double x, gsl_sf_result * result) { const double lx = log(x); const double nu = a - 0.5; const double lnpre = 0.5*(x - M_LNPI) - nu*lx; gsl_sf_result lnK; gsl_sf_bessel_lnKnu_e(nu, 0.5*x, &lnK); result->val = lnpre + lnK.val; result->err = 2.0 * GSL_DBL_EPSILON * (fabs(0.5*x) + 0.5*M_LNPI + fabs(nu*lx)); result->err += lnK.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } /* Evaluate u_{N+1}/u_N by Steed's continued fraction method. * * u_N := Gamma[a+N]/Gamma[a] U(a + N, b, x) * * u_{N+1}/u_N = (a+N) U(a+N+1,b,x)/U(a+N,b,x) */ static int hyperg_U_CF1(const double a, const double b, const int N, const double x, double * result, int * count) { const double RECUR_BIG = GSL_SQRT_DBL_MAX; const int maxiter = 20000; int n = 1; double Anm2 = 1.0; double Bnm2 = 0.0; double Anm1 = 0.0; double Bnm1 = 1.0; double a1 = -(a + N); double b1 = (b - 2.0*a - x - 2.0*(N+1)); double An = b1*Anm1 + a1*Anm2; double Bn = b1*Bnm1 + a1*Bnm2; double an, bn; double fn = An/Bn; while(n < maxiter) { double old_fn; double del; n++; Anm2 = Anm1; Bnm2 = Bnm1; Anm1 = An; Bnm1 = Bn; an = -(a + N + n - b)*(a + N + n - 1.0); bn = (b - 2.0*a - x - 2.0*(N+n)); An = bn*Anm1 + an*Anm2; Bn = bn*Bnm1 + an*Bnm2; if(fabs(An) > RECUR_BIG || fabs(Bn) > RECUR_BIG) { An /= RECUR_BIG; Bn /= RECUR_BIG; Anm1 /= RECUR_BIG; Bnm1 /= RECUR_BIG; Anm2 /= RECUR_BIG; Bnm2 /= RECUR_BIG; } old_fn = fn; fn = An/Bn; del = old_fn/fn; if(fabs(del - 1.0) < 10.0*GSL_DBL_EPSILON) break; } *result = fn; *count = n; if(n == maxiter) GSL_ERROR ("error", GSL_EMAXITER); else return GSL_SUCCESS; } /* Large x asymptotic for x^a U(a,b,x) * Based on SLATEC D9CHU() [W. Fullerton] * * Uses a rational approximation due to Luke. * See [Luke, Algorithms for the Computation of Special Functions, p. 252] * [Luke, Utilitas Math. (1977)] * * z^a U(a,b,z) ~ 2F0(a,1+a-b,-1/z) * * This assumes that a is not a negative integer and * that 1+a-b is not a negative integer. If one of them * is, then the 2F0 actually terminates, the above * relation is an equality, and the sum should be * evaluated directly [see below]. */ static int d9chu(const double a, const double b, const double x, gsl_sf_result * result) { const double EPS = 8.0 * GSL_DBL_EPSILON; /* EPS = 4.0D0*D1MACH(4) */ const int maxiter = 500; double aa[4], bb[4]; int i; double bp = 1.0 + a - b; double ab = a*bp; double ct2 = 2.0 * (x - ab); double sab = a + bp; double ct3 = sab + 1.0 + ab; double anbn = ct3 + sab + 3.0; double ct1 = 1.0 + 2.0*x/anbn; bb[0] = 1.0; aa[0] = 1.0; bb[1] = 1.0 + 2.0*x/ct3; aa[1] = 1.0 + ct2/ct3; bb[2] = 1.0 + 6.0*ct1*x/ct3; aa[2] = 1.0 + 6.0*ab/anbn + 3.0*ct1*ct2/ct3; for(i=4; ival = aa[3]/bb[3]; result->err = 8.0 * GSL_DBL_EPSILON * fabs(result->val); if(i == maxiter) { GSL_ERROR ("error", GSL_EMAXITER); } else { return GSL_SUCCESS; } } /* Evaluate asymptotic for z^a U(a,b,z) ~ 2F0(a,1+a-b,-1/z) * We check for termination of the 2F0 as a special case. * Assumes x > 0. * Also assumes a,b are not too large compared to x. */ static int hyperg_zaU_asymp(const double a, const double b, const double x, gsl_sf_result *result) { const double ap = a; const double bp = 1.0 + a - b; const double rintap = floor(ap + 0.5); const double rintbp = floor(bp + 0.5); const int ap_neg_int = ( ap < 0.0 && fabs(ap - rintap) < INT_THRESHOLD ); const int bp_neg_int = ( bp < 0.0 && fabs(bp - rintbp) < INT_THRESHOLD ); if(ap_neg_int || bp_neg_int) { /* Evaluate 2F0 polynomial. */ double mxi = -1.0/x; double nmax = -(int)(GSL_MIN(ap,bp) - 0.1); double tn = 1.0; double sum = 1.0; double n = 1.0; double sum_err = 0.0; while(n <= nmax) { double apn = (ap+n-1.0); double bpn = (bp+n-1.0); tn *= ((apn/n)*mxi)*bpn; sum += tn; sum_err += 2.0 * GSL_DBL_EPSILON * fabs(tn); n += 1.0; } result->val = sum; result->err = sum_err; result->err += 2.0 * GSL_DBL_EPSILON * (fabs(nmax)+1.0) * fabs(sum); return GSL_SUCCESS; } else { return d9chu(a,b,x,result); } } /* Evaluate finite sum which appears below. */ static int hyperg_U_finite_sum(int N, double a, double b, double x, double xeps, gsl_sf_result * result) { int i; double sum_val; double sum_err; if(N <= 0) { double t_val = 1.0; double t_err = 0.0; gsl_sf_result poch; int stat_poch; sum_val = 1.0; sum_err = 0.0; for(i=1; i<= -N; i++) { const double xi1 = i - 1; const double mult = (a+xi1)*x/((b+xi1)*(xi1+1.0)); t_val *= mult; t_err += fabs(mult) * t_err + fabs(t_val) * 8.0 * 2.0 * GSL_DBL_EPSILON; sum_val += t_val; sum_err += t_err; } stat_poch = gsl_sf_poch_e(1.0+a-b, -a, &poch); result->val = sum_val * poch.val; result->err = fabs(sum_val) * poch.err + sum_err * fabs(poch.val); result->err += fabs(poch.val) * (fabs(N) + 2.0) * GSL_DBL_EPSILON * fabs(sum_val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); result->err *= 2.0; /* FIXME: fudge factor... why is the error estimate too small? */ return stat_poch; } else { const int M = N - 2; if(M < 0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else { gsl_sf_result gbm1; gsl_sf_result gamr; int stat_gbm1; int stat_gamr; double t_val = 1.0; double t_err = 0.0; sum_val = 1.0; sum_err = 0.0; for(i=1; i<=M; i++) { const double mult = (a-b+i)*x/((1.0-b+i)*i); t_val *= mult; t_err += t_err * fabs(mult) + fabs(t_val) * 8.0 * 2.0 * GSL_DBL_EPSILON; sum_val += t_val; sum_err += t_err; } stat_gbm1 = gsl_sf_gamma_e(b-1.0, &gbm1); stat_gamr = gsl_sf_gammainv_e(a, &gamr); if(stat_gbm1 == GSL_SUCCESS) { gsl_sf_result powx1N; int stat_p = gsl_sf_pow_int_e(x, 1-N, &powx1N); double pe_val = powx1N.val * xeps; double pe_err = powx1N.err * fabs(xeps) + 2.0 * GSL_DBL_EPSILON * fabs(pe_val); double coeff_val = gbm1.val * gamr.val * pe_val; double coeff_err = gbm1.err * fabs(gamr.val * pe_val) + gamr.err * fabs(gbm1.val * pe_val) + fabs(gbm1.val * gamr.val) * pe_err + 2.0 * GSL_DBL_EPSILON * fabs(coeff_val); result->val = sum_val * coeff_val; result->err = fabs(sum_val) * coeff_err + sum_err * fabs(coeff_val); result->err += 2.0 * GSL_DBL_EPSILON * (M+2.0) * fabs(result->val); result->err *= 2.0; /* FIXME: fudge factor... why is the error estimate too small? */ return stat_p; } else { result->val = 0.0; result->err = 0.0; return stat_gbm1; } } } } /* Based on SLATEC DCHU() [W. Fullerton] * Assumes x > 0. * This is just a series summation method, and * it is not good for large a. * * I patched up the window for 1+a-b near zero. [GJ] */ static int hyperg_U_series(const double a, const double b, const double x, gsl_sf_result * result) { const double EPS = 2.0 * GSL_DBL_EPSILON; /* EPS = D1MACH(3) */ const double SQRT_EPS = M_SQRT2 * GSL_SQRT_DBL_EPSILON; if(fabs(1.0 + a - b) < SQRT_EPS) { /* Original Comment: ALGORITHM IS BAD WHEN 1+A-B IS NEAR ZERO FOR SMALL X */ /* We can however do the following: * U(a,b,x) = U(a,a+1,x) when 1+a-b=0 * and U(a,a+1,x) = x^(-a). */ double lnr = -a * log(x); int stat_e = gsl_sf_exp_e(lnr, result); result->err += 2.0 * SQRT_EPS * fabs(result->val); return stat_e; } else { double aintb = ( b < 0.0 ? ceil(b-0.5) : floor(b+0.5) ); double beps = b - aintb; int N = aintb; double lnx = log(x); double xeps = exp(-beps*lnx); /* Evaluate finite sum. */ gsl_sf_result sum; int stat_sum = hyperg_U_finite_sum(N, a, b, x, xeps, &sum); /* Evaluate infinite sum. */ int istrt = ( N < 1 ? 1-N : 0 ); double xi = istrt; gsl_sf_result gamr; gsl_sf_result powx; int stat_gamr = gsl_sf_gammainv_e(1.0+a-b, &gamr); int stat_powx = gsl_sf_pow_int_e(x, istrt, &powx); double sarg = beps*M_PI; double sfact = ( sarg != 0.0 ? sarg/sin(sarg) : 1.0 ); double factor_val = sfact * ( GSL_IS_ODD(N) ? -1.0 : 1.0 ) * gamr.val * powx.val; double factor_err = fabs(gamr.val) * powx.err + fabs(powx.val) * gamr.err + 2.0 * GSL_DBL_EPSILON * fabs(factor_val); gsl_sf_result pochai; gsl_sf_result gamri1; gsl_sf_result gamrni; int stat_pochai = gsl_sf_poch_e(a, xi, &pochai); int stat_gamri1 = gsl_sf_gammainv_e(xi + 1.0, &gamri1); int stat_gamrni = gsl_sf_gammainv_e(aintb + xi, &gamrni); int stat_gam123 = GSL_ERROR_SELECT_3(stat_gamr, stat_gamri1, stat_gamrni); int stat_gamall = GSL_ERROR_SELECT_4(stat_sum, stat_gam123, stat_pochai, stat_powx); gsl_sf_result pochaxibeps; gsl_sf_result gamrxi1beps; int stat_pochaxibeps = gsl_sf_poch_e(a, xi-beps, &pochaxibeps); int stat_gamrxi1beps = gsl_sf_gammainv_e(xi + 1.0 - beps, &gamrxi1beps); int stat_all = GSL_ERROR_SELECT_3(stat_gamall, stat_pochaxibeps, stat_gamrxi1beps); double b0_val = factor_val * pochaxibeps.val * gamrni.val * gamrxi1beps.val; double b0_err = fabs(factor_val * pochaxibeps.val * gamrni.val) * gamrxi1beps.err + fabs(factor_val * pochaxibeps.val * gamrxi1beps.val) * gamrni.err + fabs(factor_val * gamrni.val * gamrxi1beps.val) * pochaxibeps.err + fabs(pochaxibeps.val * gamrni.val * gamrxi1beps.val) * factor_err + 2.0 * GSL_DBL_EPSILON * fabs(b0_val); if(fabs(xeps-1.0) < 0.5) { /* C X**(-BEPS) IS CLOSE TO 1.0D0, SO WE MUST BE C CAREFUL IN EVALUATING THE DIFFERENCES. */ int i; gsl_sf_result pch1ai; gsl_sf_result pch1i; gsl_sf_result poch1bxibeps; int stat_pch1ai = gsl_sf_pochrel_e(a + xi, -beps, &pch1ai); int stat_pch1i = gsl_sf_pochrel_e(xi + 1.0 - beps, beps, &pch1i); int stat_poch1bxibeps = gsl_sf_pochrel_e(b+xi, -beps, &poch1bxibeps); double c0_t1_val = beps*pch1ai.val*pch1i.val; double c0_t1_err = fabs(beps) * fabs(pch1ai.val) * pch1i.err + fabs(beps) * fabs(pch1i.val) * pch1ai.err + 2.0 * GSL_DBL_EPSILON * fabs(c0_t1_val); double c0_t2_val = -poch1bxibeps.val + pch1ai.val - pch1i.val + c0_t1_val; double c0_t2_err = poch1bxibeps.err + pch1ai.err + pch1i.err + c0_t1_err + 2.0 * GSL_DBL_EPSILON * fabs(c0_t2_val); double c0_val = factor_val * pochai.val * gamrni.val * gamri1.val * c0_t2_val; double c0_err = fabs(factor_val * pochai.val * gamrni.val * gamri1.val) * c0_t2_err + fabs(factor_val * pochai.val * gamrni.val * c0_t2_val) * gamri1.err + fabs(factor_val * pochai.val * gamri1.val * c0_t2_val) * gamrni.err + fabs(factor_val * gamrni.val * gamri1.val * c0_t2_val) * pochai.err + fabs(pochai.val * gamrni.val * gamri1.val * c0_t2_val) * factor_err + 2.0 * GSL_DBL_EPSILON * fabs(c0_val); /* C XEPS1 = (1.0 - X**(-BEPS))/BEPS = (X**(-BEPS) - 1.0)/(-BEPS) */ gsl_sf_result dexprl; int stat_dexprl = gsl_sf_exprel_e(-beps*lnx, &dexprl); double xeps1_val = lnx * dexprl.val; double xeps1_err = 2.0 * GSL_DBL_EPSILON * (1.0 + fabs(beps*lnx)) * fabs(dexprl.val) + fabs(lnx) * dexprl.err + 2.0 * GSL_DBL_EPSILON * fabs(xeps1_val); double dchu_val = sum.val + c0_val + xeps1_val*b0_val; double dchu_err = sum.err + c0_err + fabs(xeps1_val)*b0_err + xeps1_err * fabs(b0_val) + fabs(b0_val*lnx)*dexprl.err + 2.0 * GSL_DBL_EPSILON * (fabs(sum.val) + fabs(c0_val) + fabs(xeps1_val*b0_val)); double xn = N; double t_val; double t_err; stat_all = GSL_ERROR_SELECT_5(stat_all, stat_dexprl, stat_poch1bxibeps, stat_pch1i, stat_pch1ai); for(i=1; i<2000; i++) { const double xi = istrt + i; const double xi1 = istrt + i - 1; const double tmp = (a-1.0)*(xn+2.0*xi-1.0) + xi*(xi-beps); const double b0_multiplier = (a+xi1-beps)*x/((xn+xi1)*(xi-beps)); const double c0_multiplier_1 = (a+xi1)*x/((b+xi1)*xi); const double c0_multiplier_2 = tmp / (xi*(b+xi1)*(a+xi1-beps)); b0_val *= b0_multiplier; b0_err += fabs(b0_multiplier) * b0_err + fabs(b0_val) * 8.0 * 2.0 * GSL_DBL_EPSILON; c0_val = c0_multiplier_1 * c0_val - c0_multiplier_2 * b0_val; c0_err = fabs(c0_multiplier_1) * c0_err + fabs(c0_multiplier_2) * b0_err + fabs(c0_val) * 8.0 * 2.0 * GSL_DBL_EPSILON + fabs(b0_val * c0_multiplier_2) * 16.0 * 2.0 * GSL_DBL_EPSILON; t_val = c0_val + xeps1_val*b0_val; t_err = c0_err + fabs(xeps1_val)*b0_err; t_err += fabs(b0_val*lnx) * dexprl.err; t_err += fabs(b0_val)*xeps1_err; dchu_val += t_val; dchu_err += t_err; if(fabs(t_val) < EPS*fabs(dchu_val)) break; } result->val = dchu_val; result->err = 2.0 * dchu_err; result->err += 2.0 * fabs(t_val); result->err += 4.0 * GSL_DBL_EPSILON * (i+2.0) * fabs(dchu_val); result->err *= 2.0; /* FIXME: fudge factor */ if(i >= 2000) { GSL_ERROR ("error", GSL_EMAXITER); } else { return stat_all; } } else { /* C X**(-BEPS) IS VERY DIFFERENT FROM 1.0, SO THE C STRAIGHTFORWARD FORMULATION IS STABLE. */ int i; double dchu_val; double dchu_err; double t_val; double t_err; gsl_sf_result dgamrbxi; int stat_dgamrbxi = gsl_sf_gammainv_e(b+xi, &dgamrbxi); double a0_val = factor_val * pochai.val * dgamrbxi.val * gamri1.val / beps; double a0_err = fabs(factor_val * pochai.val * dgamrbxi.val / beps) * gamri1.err + fabs(factor_val * pochai.val * gamri1.val / beps) * dgamrbxi.err + fabs(factor_val * dgamrbxi.val * gamri1.val / beps) * pochai.err + fabs(pochai.val * dgamrbxi.val * gamri1.val / beps) * factor_err + 2.0 * GSL_DBL_EPSILON * fabs(a0_val); stat_all = GSL_ERROR_SELECT_2(stat_all, stat_dgamrbxi); b0_val = xeps * b0_val / beps; b0_err = fabs(xeps / beps) * b0_err + 4.0 * GSL_DBL_EPSILON * fabs(b0_val); dchu_val = sum.val + a0_val - b0_val; dchu_err = sum.err + a0_err + b0_err + 2.0 * GSL_DBL_EPSILON * (fabs(sum.val) + fabs(a0_val) + fabs(b0_val)); for(i=1; i<2000; i++) { double xi = istrt + i; double xi1 = istrt + i - 1; double a0_multiplier = (a+xi1)*x/((b+xi1)*xi); double b0_multiplier = (a+xi1-beps)*x/((aintb+xi1)*(xi-beps)); a0_val *= a0_multiplier; a0_err += fabs(a0_multiplier) * a0_err; b0_val *= b0_multiplier; b0_err += fabs(b0_multiplier) * b0_err; t_val = a0_val - b0_val; t_err = a0_err + b0_err; dchu_val += t_val; dchu_err += t_err; if(fabs(t_val) < EPS*fabs(dchu_val)) break; } result->val = dchu_val; result->err = 2.0 * dchu_err; result->err += 2.0 * fabs(t_val); result->err += 4.0 * GSL_DBL_EPSILON * (i+2.0) * fabs(dchu_val); result->err *= 2.0; /* FIXME: fudge factor */ if(i >= 2000) { GSL_ERROR ("error", GSL_EMAXITER); } else { return stat_all; } } } } /* Assumes b > 0 and x > 0. */ static int hyperg_U_small_ab(const double a, const double b, const double x, gsl_sf_result * result) { if(a == -1.0) { /* U(-1,c+1,x) = Laguerre[c,0,x] = -b + x */ result->val = -b + x; result->err = 2.0 * GSL_DBL_EPSILON * (fabs(b) + fabs(x)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(a == 0.0) { /* U(0,c+1,x) = Laguerre[c,0,x] = 1 */ result->val = 1.0; result->err = 0.0; return GSL_SUCCESS; } else if(ASYMP_EVAL_OK(a,b,x)) { double p = pow(x, -a); gsl_sf_result asymp; int stat_asymp = hyperg_zaU_asymp(a, b, x, &asymp); result->val = asymp.val * p; result->err = asymp.err * p; result->err += fabs(asymp.val) * GSL_DBL_EPSILON * fabs(a) * p; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_asymp; } else { return hyperg_U_series(a, b, x, result); } } /* Assumes b > 0 and x > 0. */ static int hyperg_U_small_a_bgt0(const double a, const double b, const double x, gsl_sf_result * result, double * ln_multiplier ) { if(a == 0.0) { result->val = 1.0; result->err = 1.0; *ln_multiplier = 0.0; return GSL_SUCCESS; } else if( (b > 5000.0 && x < 0.90 * fabs(b)) || (b > 500.0 && x < 0.50 * fabs(b)) ) { int stat = gsl_sf_hyperg_U_large_b_e(a, b, x, result, ln_multiplier); if(stat == GSL_EOVRFLW) return GSL_SUCCESS; else return stat; } else if(b > 15.0) { /* Recurse up from b near 1. */ double eps = b - floor(b); double b0 = 1.0 + eps; gsl_sf_result r_Ubm1; gsl_sf_result r_Ub; int stat_0 = hyperg_U_small_ab(a, b0, x, &r_Ubm1); int stat_1 = hyperg_U_small_ab(a, b0+1.0, x, &r_Ub); double Ubm1 = r_Ubm1.val; double Ub = r_Ub.val; double Ubp1; double bp; for(bp = b0+1.0; bpval = Ub; result->err = (fabs(r_Ubm1.err/r_Ubm1.val) + fabs(r_Ub.err/r_Ub.val)) * fabs(Ub); result->err += 2.0 * GSL_DBL_EPSILON * (fabs(b-b0)+1.0) * fabs(Ub); *ln_multiplier = 0.0; return GSL_ERROR_SELECT_2(stat_0, stat_1); } else { *ln_multiplier = 0.0; return hyperg_U_small_ab(a, b, x, result); } } /* We use this to keep track of large * dynamic ranges in the recursions. * This can be important because sometimes * we want to calculate a very large and * a very small number and the answer is * the product, of order 1. This happens, * for instance, when we apply a Kummer * transform to make b positive and * both x and b are large. */ #define RESCALE_2(u0,u1,factor,count) \ do { \ double au0 = fabs(u0); \ if(au0 > factor) { \ u0 /= factor; \ u1 /= factor; \ count++; \ } \ else if(au0 < 1.0/factor) { \ u0 *= factor; \ u1 *= factor; \ count--; \ } \ } while (0) /* Specialization to b >= 1, for integer parameters. * Assumes x > 0. */ static int hyperg_U_int_bge1(const int a, const int b, const double x, gsl_sf_result_e10 * result) { if(a == 0) { result->val = 1.0; result->err = 0.0; result->e10 = 0; return GSL_SUCCESS; } else if(a == -1) { result->val = -b + x; result->err = 2.0 * GSL_DBL_EPSILON * (fabs(b) + fabs(x)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); result->e10 = 0; return GSL_SUCCESS; } else if(b == a + 1) { /* U(a,a+1,x) = x^(-a) */ return gsl_sf_exp_e10_e(-a*log(x), result); } else if(ASYMP_EVAL_OK(a,b,x)) { const double ln_pre_val = -a*log(x); const double ln_pre_err = 2.0 * GSL_DBL_EPSILON * fabs(ln_pre_val); gsl_sf_result asymp; int stat_asymp = hyperg_zaU_asymp(a, b, x, &asymp); int stat_e = gsl_sf_exp_mult_err_e10_e(ln_pre_val, ln_pre_err, asymp.val, asymp.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_asymp); } else if(SERIES_EVAL_OK(a,b,x)) { gsl_sf_result ser; const int stat_ser = hyperg_U_series(a, b, x, &ser); result->val = ser.val; result->err = ser.err; result->e10 = 0; return stat_ser; } else if(a < 0) { /* Recurse backward from a = -1,0. */ int scale_count = 0; const double scale_factor = GSL_SQRT_DBL_MAX; gsl_sf_result lnm; gsl_sf_result y; double lnscale; double Uap1 = 1.0; /* U(0,b,x) */ double Ua = -b + x; /* U(-1,b,x) */ double Uam1; int ap; for(ap=-1; ap>a; ap--) { Uam1 = ap*(b-ap-1.0)*Uap1 + (x+2.0*ap-b)*Ua; Uap1 = Ua; Ua = Uam1; RESCALE_2(Ua,Uap1,scale_factor,scale_count); } lnscale = log(scale_factor); lnm.val = scale_count*lnscale; lnm.err = 2.0 * GSL_DBL_EPSILON * fabs(lnm.val); y.val = Ua; y.err = 4.0 * GSL_DBL_EPSILON * (fabs(a)+1.0) * fabs(Ua); return gsl_sf_exp_mult_err_e10_e(lnm.val, lnm.err, y.val, y.err, result); } else if(b >= 2.0*a + x) { /* Recurse forward from a = 0,1. */ int scale_count = 0; const double scale_factor = GSL_SQRT_DBL_MAX; gsl_sf_result r_Ua; gsl_sf_result lnm; gsl_sf_result y; double lnscale; double lm; int stat_1 = hyperg_U_small_a_bgt0(1.0, b, x, &r_Ua, &lm); /* U(1,b,x) */ int stat_e; double Uam1 = 1.0; /* U(0,b,x) */ double Ua = r_Ua.val; double Uap1; int ap; Uam1 *= exp(-lm); for(ap=1; apa_target; ap--) { Uam1 = -((b-2.0*ap-x)*Ua + ap*(1.0+ap-b)*Uap1); Uap1 = Ua; Ua = Uam1; RESCALE_2(Ua,Uap1,scale_factor,scale_count); } if(Ua == 0.0) { result->val = 0.0; result->err = 0.0; result->e10 = 0; GSL_ERROR ("error", GSL_EZERODIV); } else { double lnscl = -scale_count*log(scale_factor); double lnpre_val = lnU_target + lnscl; double lnpre_err = 2.0 * GSL_DBL_EPSILON * (fabs(lnU_target) + fabs(lnscl)); double oUa_err = 2.0 * (fabs(a_target-a) + CF1_count + 1.0) * GSL_DBL_EPSILON * fabs(1.0/Ua); int stat_e = gsl_sf_exp_mult_err_e10_e(lnpre_val, lnpre_err, 1.0/Ua, oUa_err, result); return GSL_ERROR_SELECT_2(stat_e, stat_CF1); } } else { /* Recurse backward to near the b=2a+x line, then * determine normalization by either direct evaluation * or by a forward recursion. The direct evaluation * is needed when x is small (which is precisely * when it is easy to do). */ const double scale_factor = GSL_SQRT_DBL_MAX; int scale_count_for = 0; int scale_count_bck = 0; int a0 = 1; int a1 = a0 + ceil(0.5*(b-x) - a0); double Ua1_bck_val; double Ua1_bck_err; double Ua1_for_val; double Ua1_for_err; int stat_for; int stat_bck; gsl_sf_result lm_for; { /* Recurse back to determine U(a1,b), sans normalization. */ double ru; int CF1_count; int stat_CF1 = hyperg_U_CF1(a, b, 0, x, &ru, &CF1_count); double Ua = 1.0; double Uap1 = ru/a * Ua; double Uam1; int ap; for(ap=a; ap>a1; ap--) { Uam1 = -((b-2.0*ap-x)*Ua + ap*(1.0+ap-b)*Uap1); Uap1 = Ua; Ua = Uam1; RESCALE_2(Ua,Uap1,scale_factor,scale_count_bck); } Ua1_bck_val = Ua; Ua1_bck_err = 2.0 * GSL_DBL_EPSILON * (fabs(a1-a)+CF1_count+1.0) * fabs(Ua); stat_bck = stat_CF1; } if(b == 2*a1 && a1 > 1) { /* This can happen when x is small, which is * precisely when we need to be careful with * this evaluation. */ hyperg_lnU_beq2a((double)a1, x, &lm_for); Ua1_for_val = 1.0; Ua1_for_err = 0.0; stat_for = GSL_SUCCESS; } else if(b == 2*a1 - 1 && a1 > 1) { /* Similar to the above. Happens when x is small. * Use * U(a,2a-1) = (x U(a,2a) - U(a-1,2(a-1))) / (2a - 2) */ gsl_sf_result lnU00, lnU12; gsl_sf_result U00, U12; hyperg_lnU_beq2a(a1-1.0, x, &lnU00); hyperg_lnU_beq2a(a1, x, &lnU12); if(lnU00.val > lnU12.val) { lm_for.val = lnU00.val; lm_for.err = lnU00.err; U00.val = 1.0; U00.err = 0.0; gsl_sf_exp_err_e(lnU12.val - lm_for.val, lnU12.err + lm_for.err, &U12); } else { lm_for.val = lnU12.val; lm_for.err = lnU12.err; U12.val = 1.0; U12.err = 0.0; gsl_sf_exp_err_e(lnU00.val - lm_for.val, lnU00.err + lm_for.err, &U00); } Ua1_for_val = (x * U12.val - U00.val) / (2.0*a1 - 2.0); Ua1_for_err = (fabs(x)*U12.err + U00.err) / fabs(2.0*a1 - 2.0); Ua1_for_err += 2.0 * GSL_DBL_EPSILON * fabs(Ua1_for_val); stat_for = GSL_SUCCESS; } else { /* Recurse forward to determine U(a1,b) with * absolute normalization. */ gsl_sf_result r_Ua; double Uam1 = 1.0; /* U(a0-1,b,x) = U(0,b,x) */ double Ua; double Uap1; int ap; double lm_for_local; stat_for = hyperg_U_small_a_bgt0(a0, b, x, &r_Ua, &lm_for_local); /* U(1,b,x) */ Ua = r_Ua.val; Uam1 *= exp(-lm_for_local); lm_for.val = lm_for_local; lm_for.err = 0.0; for(ap=a0; apval = 0.0; result->err = 0.0; result->e10 = 0; GSL_ERROR ("error", GSL_EZERODIV); } else if(Ua1_for_val == 0.0) { /* Should never happen. */ UNDERFLOW_ERROR_E10(result); } else { double lns = (scale_count_for - scale_count_bck)*log(scale_factor); double ln_for_val = log(fabs(Ua1_for_val)); double ln_for_err = GSL_DBL_EPSILON + fabs(Ua1_for_err/Ua1_for_val); double ln_bck_val = log(fabs(Ua1_bck_val)); double ln_bck_err = GSL_DBL_EPSILON + fabs(Ua1_bck_err/Ua1_bck_val); double lnr_val = lm_for.val + ln_for_val - ln_bck_val + lns; double lnr_err = lm_for.err + ln_for_err + ln_bck_err + 2.0 * GSL_DBL_EPSILON * (fabs(lm_for.val) + fabs(ln_for_val) + fabs(ln_bck_val) + fabs(lns)); double sgn = GSL_SIGN(Ua1_for_val) * GSL_SIGN(Ua1_bck_val); int stat_e = gsl_sf_exp_err_e10_e(lnr_val, lnr_err, result); result->val *= sgn; return GSL_ERROR_SELECT_3(stat_e, stat_bck, stat_for); } } } } /* Handle b >= 1 for generic a,b values. */ static int hyperg_U_bge1(const double a, const double b, const double x, gsl_sf_result_e10 * result) { const double rinta = floor(a+0.5); const int a_neg_integer = (a < 0.0 && fabs(a - rinta) < INT_THRESHOLD); if(a == 0.0) { result->val = 1.0; result->err = 0.0; result->e10 = 0; return GSL_SUCCESS; } else if(a_neg_integer && fabs(rinta) < INT_MAX) { /* U(-n,b,x) = (-1)^n n! Laguerre[n,b-1,x] */ const int n = -(int)rinta; const double sgn = (GSL_IS_ODD(n) ? -1.0 : 1.0); gsl_sf_result lnfact; gsl_sf_result L; const int stat_L = gsl_sf_laguerre_n_e(n, b-1.0, x, &L); gsl_sf_lnfact_e(n, &lnfact); { const int stat_e = gsl_sf_exp_mult_err_e10_e(lnfact.val, lnfact.err, sgn*L.val, L.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_L); } } else if(ASYMP_EVAL_OK(a,b,x)) { const double ln_pre_val = -a*log(x); const double ln_pre_err = 2.0 * GSL_DBL_EPSILON * fabs(ln_pre_val); gsl_sf_result asymp; int stat_asymp = hyperg_zaU_asymp(a, b, x, &asymp); int stat_e = gsl_sf_exp_mult_err_e10_e(ln_pre_val, ln_pre_err, asymp.val, asymp.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_asymp); } else if(fabs(a) <= 1.0) { gsl_sf_result rU; double ln_multiplier; int stat_U = hyperg_U_small_a_bgt0(a, b, x, &rU, &ln_multiplier); int stat_e = gsl_sf_exp_mult_err_e10_e(ln_multiplier, 2.0*GSL_DBL_EPSILON*fabs(ln_multiplier), rU.val, rU.err, result); return GSL_ERROR_SELECT_2(stat_U, stat_e); } else if(SERIES_EVAL_OK(a,b,x)) { gsl_sf_result ser; const int stat_ser = hyperg_U_series(a, b, x, &ser); result->val = ser.val; result->err = ser.err; result->e10 = 0; return stat_ser; } else if(a < 0.0) { /* Recurse backward on a and then upward on b. */ const double scale_factor = GSL_SQRT_DBL_MAX; const double a0 = a - floor(a) - 1.0; const double b0 = b - floor(b) + 1.0; int scale_count = 0; double lm_0, lm_1; double lm_max; gsl_sf_result r_Uap1; gsl_sf_result r_Ua; int stat_0 = hyperg_U_small_a_bgt0(a0+1.0, b0, x, &r_Uap1, &lm_0); int stat_1 = hyperg_U_small_a_bgt0(a0, b0, x, &r_Ua, &lm_1); int stat_e; double Uap1 = r_Uap1.val; double Ua = r_Ua.val; double Uam1; double ap; lm_max = GSL_MAX(lm_0, lm_1); Uap1 *= exp(lm_0-lm_max); Ua *= exp(lm_1-lm_max); /* Downward recursion on a. */ for(ap=a0; ap>a+0.1; ap -= 1.0) { Uam1 = ap*(b0-ap-1.0)*Uap1 + (x+2.0*ap-b0)*Ua; Uap1 = Ua; Ua = Uam1; RESCALE_2(Ua,Uap1,scale_factor,scale_count); } if(b < 2.0) { /* b == b0, so no recursion necessary */ const double lnscale = log(scale_factor); gsl_sf_result lnm; gsl_sf_result y; lnm.val = lm_max + scale_count * lnscale; lnm.err = 2.0 * GSL_DBL_EPSILON * (fabs(lm_max) + scale_count * fabs(lnscale)); y.val = Ua; y.err = fabs(r_Uap1.err/r_Uap1.val) * fabs(Ua); y.err += fabs(r_Ua.err/r_Ua.val) * fabs(Ua); y.err += 2.0 * GSL_DBL_EPSILON * (fabs(a-a0) + 1.0) * fabs(Ua); y.err *= fabs(lm_0-lm_max) + 1.0; y.err *= fabs(lm_1-lm_max) + 1.0; stat_e = gsl_sf_exp_mult_err_e10_e(lnm.val, lnm.err, y.val, y.err, result); } else { /* Upward recursion on b. */ const double err_mult = fabs(b-b0) + fabs(a-a0) + 1.0; const double lnscale = log(scale_factor); gsl_sf_result lnm; gsl_sf_result y; double Ubm1 = Ua; /* U(a,b0) */ double Ub = (a*(b0-a-1.0)*Uap1 + (a+x)*Ua)/x; /* U(a,b0+1) */ double Ubp1; double bp; for(bp=b0+1.0; bp= 2*a + x) { /* Recurse forward from a near zero. * Note that we cannot cross the singularity at * the line b=a+1, because the only way we could * be in that little wedge is if a < 1. But we * have already dealt with the small a case. */ int scale_count = 0; const double a0 = a - floor(a); const double scale_factor = GSL_SQRT_DBL_MAX; double lnscale; double lm_0, lm_1, lm_max; gsl_sf_result r_Uam1; gsl_sf_result r_Ua; int stat_0 = hyperg_U_small_a_bgt0(a0-1.0, b, x, &r_Uam1, &lm_0); int stat_1 = hyperg_U_small_a_bgt0(a0, b, x, &r_Ua, &lm_1); int stat_e; gsl_sf_result lnm; gsl_sf_result y; double Uam1 = r_Uam1.val; double Ua = r_Ua.val; double Uap1; double ap; lm_max = GSL_MAX(lm_0, lm_1); Uam1 *= exp(lm_0-lm_max); Ua *= exp(lm_1-lm_max); for(ap=a0; apa0+0.1; ap -= 1.0) { Uam1 = -((b-2.0*ap-x)*Ua + ap*(1.0+ap-b)*Uap1); Uap1 = Ua; Ua = Uam1; RESCALE_2(Ua,Uap1,scale_factor,scale_count); } stat_U0 = hyperg_U_small_a_bgt0(a0, b, x, &U0, &lm_0); lnscale = log(scale_factor); lnm.val = lm_0 - scale_count * lnscale; lnm.err = 2.0 * GSL_DBL_EPSILON * (fabs(lm_0) + fabs(scale_count * lnscale)); y.val = GSL_SQRT_DBL_MIN*(U0.val/Ua); y.err = GSL_SQRT_DBL_MIN*(U0.err/fabs(Ua)); y.err += 2.0 * GSL_DBL_EPSILON * (fabs(a0-a) + CF1_count + 1.0) * fabs(y.val); stat_e = gsl_sf_exp_mult_err_e10_e(lnm.val, lnm.err, y.val, y.err, result); return GSL_ERROR_SELECT_3(stat_e, stat_U0, stat_CF1); } else { /* Recurse backward to near the b=2a+x line, then * forward from a near zero to get the normalization. */ int scale_count_for = 0; int scale_count_bck = 0; const double scale_factor = GSL_SQRT_DBL_MAX; const double eps = a - floor(a); const double a0 = ( eps == 0.0 ? 1.0 : eps ); const double a1 = a0 + ceil(0.5*(b-x) - a0); gsl_sf_result lnm; gsl_sf_result y; double lm_for; double lnscale; double Ua1_bck; double Ua1_for; int stat_for; int stat_bck; int stat_e; int CF1_count; { /* Recurse back to determine U(a1,b), sans normalization. */ double Uap1; double Ua; double Uam1; double ap; double ru; double r; int stat_CF1 = hyperg_U_CF1(a, b, 0, x, &ru, &CF1_count); r = ru/a; Ua = GSL_SQRT_DBL_MIN; Uap1 = r * Ua; for(ap=a; ap>a1+0.1; ap -= 1.0) { Uam1 = -((b-2.0*ap-x)*Ua + ap*(1.0+ap-b)*Uap1); Uap1 = Ua; Ua = Uam1; RESCALE_2(Ua,Uap1,scale_factor,scale_count_bck); } Ua1_bck = Ua; stat_bck = stat_CF1; } { /* Recurse forward to determine U(a1,b) with * absolute normalization. */ gsl_sf_result r_Uam1; gsl_sf_result r_Ua; double lm_0, lm_1; int stat_0 = hyperg_U_small_a_bgt0(a0-1.0, b, x, &r_Uam1, &lm_0); int stat_1 = hyperg_U_small_a_bgt0(a0, b, x, &r_Ua, &lm_1); double Uam1 = r_Uam1.val; double Ua = r_Ua.val; double Uap1; double ap; lm_for = GSL_MAX(lm_0, lm_1); Uam1 *= exp(lm_0 - lm_for); Ua *= exp(lm_1 - lm_for); for(ap=a0; ap= 1) { return hyperg_U_int_bge1(a, b, x, result); } else { /* Use the reflection formula * U(a,b,x) = x^(1-b) U(1+a-b,2-b,x) */ gsl_sf_result_e10 U; double ln_x = log(x); int ap = 1 + a - b; int bp = 2 - b; int stat_e; int stat_U = hyperg_U_int_bge1(ap, bp, x, &U); double ln_pre_val = (1.0-b)*ln_x; double ln_pre_err = 2.0 * GSL_DBL_EPSILON * (fabs(b)+1.0) * fabs(ln_x); ln_pre_err += 2.0 * GSL_DBL_EPSILON * fabs(1.0-b); /* error in log(x) */ stat_e = gsl_sf_exp_mult_err_e10_e(ln_pre_val + U.e10*M_LN10, ln_pre_err, U.val, U.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_U); } } } int gsl_sf_hyperg_U_e10_e(const double a, const double b, const double x, gsl_sf_result_e10 * result) { const double rinta = floor(a + 0.5); const double rintb = floor(b + 0.5); const int a_integer = ( fabs(a - rinta) < INT_THRESHOLD ); const int b_integer = ( fabs(b - rintb) < INT_THRESHOLD ); /* CHECK_POINTER(result) */ if(x <= 0.0) { DOMAIN_ERROR_E10(result); } else if(a == 0.0) { result->val = 1.0; result->err = 0.0; result->e10 = 0; return GSL_SUCCESS; } else if(a_integer && b_integer) { return gsl_sf_hyperg_U_int_e10_e(rinta, rintb, x, result); } else { if(b >= 1.0) { /* Use b >= 1 function. */ return hyperg_U_bge1(a, b, x, result); } else { /* Use the reflection formula * U(a,b,x) = x^(1-b) U(1+a-b,2-b,x) */ const double lnx = log(x); const double ln_pre_val = (1.0-b)*lnx; const double ln_pre_err = fabs(lnx) * 2.0 * GSL_DBL_EPSILON * (1.0 + fabs(b)); const double ap = 1.0 + a - b; const double bp = 2.0 - b; gsl_sf_result_e10 U; int stat_U = hyperg_U_bge1(ap, bp, x, &U); int stat_e = gsl_sf_exp_mult_err_e10_e(ln_pre_val + U.e10*M_LN10, ln_pre_err, U.val, U.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_U); } } } int gsl_sf_hyperg_U_int_e(const int a, const int b, const double x, gsl_sf_result * result) { gsl_sf_result_e10 re; int stat_U = gsl_sf_hyperg_U_int_e10_e(a, b, x, &re); int stat_c = gsl_sf_result_smash_e(&re, result); return GSL_ERROR_SELECT_2(stat_c, stat_U); } int gsl_sf_hyperg_U_e(const double a, const double b, const double x, gsl_sf_result * result) { gsl_sf_result_e10 re; int stat_U = gsl_sf_hyperg_U_e10_e(a, b, x, &re); int stat_c = gsl_sf_result_smash_e(&re, result); return GSL_ERROR_SELECT_2(stat_c, stat_U); } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_hyperg_U_int(const int a, const int b, const double x) { EVAL_RESULT(gsl_sf_hyperg_U_int_e(a, b, x, &result)); } double gsl_sf_hyperg_U(const double a, const double b, const double x) { EVAL_RESULT(gsl_sf_hyperg_U_e(a, b, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__laguerre.c000066400000000000000000000233651261542461700222040ustar00rootroot00000000000000/* specfunc/laguerre.c * * Copyright (C) 2007 Brian Gough * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_exp.h" #include "gsl_sf_gamma.h" #include "gsl_sf_laguerre.h" #include "gsl_specfunc__error.h" /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/ /* based on the large 2b-4a asymptotic for 1F1 * [Abramowitz+Stegun, 13.5.21] * L^a_n(x) = (a+1)_n / n! 1F1(-n,a+1,x) * * The second term (ser_term2) is from Slater,"The Confluent * Hypergeometric Function" p.73. I think there may be an error in * the first term of the expression given there, comparing with AS * 13.5.21 (cf sin(a\pi+\Theta) vs sin(a\pi) + sin(\Theta)) - but the * second term appears correct. * */ static int laguerre_large_n(const int n, const double alpha, const double x, gsl_sf_result * result) { const double a = -n; const double b = alpha + 1.0; const double eta = 2.0*b - 4.0*a; const double cos2th = x/eta; const double sin2th = 1.0 - cos2th; const double eps = asin(sqrt(cos2th)); /* theta = pi/2 - eps */ const double pre_h = 0.25*M_PI*M_PI*eta*eta*cos2th*sin2th; gsl_sf_result lg_b; gsl_sf_result lnfact; int stat_lg = gsl_sf_lngamma_e(b+n, &lg_b); int stat_lf = gsl_sf_lnfact_e(n, &lnfact); double pre_term1 = 0.5*(1.0-b)*log(0.25*x*eta); double pre_term2 = 0.25*log(pre_h); double lnpre_val = lg_b.val - lnfact.val + 0.5*x + pre_term1 - pre_term2; double lnpre_err = lg_b.err + lnfact.err + GSL_DBL_EPSILON * (fabs(pre_term1)+fabs(pre_term2)); double phi1 = 0.25*eta*(2*eps + sin(2.0*eps)); double ser_term1 = -sin(phi1); double A1 = (1.0/12.0)*(5.0/(4.0*sin2th)+(3.0*b*b-6.0*b+2.0)*sin2th - 1.0); double ser_term2 = -A1 * cos(phi1)/(0.25*eta*sin(2.0*eps)); double ser_val = ser_term1 + ser_term2; double ser_err = ser_term2*ser_term2 + GSL_DBL_EPSILON * (fabs(ser_term1) + fabs(ser_term2)); int stat_e = gsl_sf_exp_mult_err_e(lnpre_val, lnpre_err, ser_val, ser_err, result); result->err += 2.0 * GSL_SQRT_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_3(stat_e, stat_lf, stat_lg); } /* Evaluate polynomial based on confluent hypergeometric representation. * * L^a_n(x) = (a+1)_n / n! 1F1(-n,a+1,x) * * assumes n > 0 and a != negative integer greater than -n */ static int laguerre_n_cp(const int n, const double a, const double x, gsl_sf_result * result) { gsl_sf_result lnfact; gsl_sf_result lg1; gsl_sf_result lg2; double s1, s2; int stat_f = gsl_sf_lnfact_e(n, &lnfact); int stat_g1 = gsl_sf_lngamma_sgn_e(a+1.0+n, &lg1, &s1); int stat_g2 = gsl_sf_lngamma_sgn_e(a+1.0, &lg2, &s2); double poly_1F1_val = 1.0; double poly_1F1_err = 0.0; int stat_e; int k; double lnpre_val = (lg1.val - lg2.val) - lnfact.val; double lnpre_err = lg1.err + lg2.err + lnfact.err + 2.0 * GSL_DBL_EPSILON * fabs(lnpre_val); for(k=n-1; k>=0; k--) { double t = (-n+k)/(a+1.0+k) * (x/(k+1)); double r = t + 1.0/poly_1F1_val; if(r > 0.9*GSL_DBL_MAX/poly_1F1_val) { /* internal error only, don't call the error handler */ INTERNAL_OVERFLOW_ERROR(result); } else { /* Collect the Horner terms. */ poly_1F1_val = 1.0 + t * poly_1F1_val; poly_1F1_err += GSL_DBL_EPSILON + fabs(t) * poly_1F1_err; } } stat_e = gsl_sf_exp_mult_err_e(lnpre_val, lnpre_err, poly_1F1_val, poly_1F1_err, result); return GSL_ERROR_SELECT_4(stat_e, stat_f, stat_g1, stat_g2); } /* Evaluate the polynomial based on the confluent hypergeometric * function in a safe way, with no restriction on the arguments. * * assumes x != 0 */ static int laguerre_n_poly_safe(const int n, const double a, const double x, gsl_sf_result * result) { const double b = a + 1.0; const double mx = -x; const double tc_sgn = (x < 0.0 ? 1.0 : (GSL_IS_ODD(n) ? -1.0 : 1.0)); gsl_sf_result tc; int stat_tc = gsl_sf_taylorcoeff_e(n, fabs(x), &tc); if(stat_tc == GSL_SUCCESS) { double term = tc.val * tc_sgn; double sum_val = term; double sum_err = tc.err; int k; for(k=n-1; k>=0; k--) { term *= ((b+k)/(n-k))*(k+1.0)/mx; sum_val += term; sum_err += 4.0 * GSL_DBL_EPSILON * fabs(term); } result->val = sum_val; result->err = sum_err + 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(stat_tc == GSL_EOVRFLW) { result->val = 0.0; /* FIXME: should be Inf */ result->err = 0.0; return stat_tc; } else { result->val = 0.0; result->err = 0.0; return stat_tc; } } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_laguerre_1_e(const double a, const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ { result->val = 1.0 + a - x; result->err = 2.0 * GSL_DBL_EPSILON * (1.0 + fabs(a) + fabs(x)); return GSL_SUCCESS; } } int gsl_sf_laguerre_2_e(const double a, const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(a == -2.0) { result->val = 0.5*x*x; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { double c0 = 0.5 * (2.0+a)*(1.0+a); double c1 = -(2.0+a); double c2 = -0.5/(2.0+a); result->val = c0 + c1*x*(1.0 + c2*x); result->err = 2.0 * GSL_DBL_EPSILON * (fabs(c0) + 2.0 * fabs(c1*x) * (1.0 + 2.0 * fabs(c2*x))); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_laguerre_3_e(const double a, const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(a == -2.0) { double x2_6 = x*x/6.0; result->val = x2_6 * (3.0 - x); result->err = x2_6 * (3.0 + fabs(x)) * 2.0 * GSL_DBL_EPSILON; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(a == -3.0) { result->val = -x*x/6.0; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { double c0 = (3.0+a)*(2.0+a)*(1.0+a) / 6.0; double c1 = -c0 * 3.0 / (1.0+a); double c2 = -1.0/(2.0+a); double c3 = -1.0/(3.0*(3.0+a)); result->val = c0 + c1*x*(1.0 + c2*x*(1.0 + c3*x)); result->err = 1.0 + 2.0 * fabs(c3*x); result->err = 1.0 + 2.0 * fabs(c2*x) * result->err; result->err = 2.0 * GSL_DBL_EPSILON * (fabs(c0) + 2.0 * fabs(c1*x) * result->err); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_laguerre_n_e(const int n, const double a, const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(n < 0) { DOMAIN_ERROR(result); } else if(n == 0) { result->val = 1.0; result->err = 0.0; return GSL_SUCCESS; } else if(n == 1) { result->val = 1.0 + a - x; result->err = 2.0 * GSL_DBL_EPSILON * (1.0 + fabs(a) + fabs(x)); return GSL_SUCCESS; } else if(x == 0.0) { double product = a + 1.0; int k; for(k=2; k<=n; k++) { product *= (a + k)/k; } result->val = product; result->err = 2.0 * (n + 1.0) * GSL_DBL_EPSILON * fabs(product) + GSL_DBL_EPSILON; return GSL_SUCCESS; } else if(x < 0.0 && a > -1.0) { /* In this case all the terms in the polynomial * are of the same sign. Note that this also * catches overflows correctly. */ return laguerre_n_cp(n, a, x, result); } else if(n < 5 || (x > 0.0 && a < -n-1)) { /* Either the polynomial will not lose too much accuracy * or all the terms are negative. In any case, * the error estimate here is good. We try both * explicit summation methods, as they have different * characteristics. One may underflow/overflow while the * other does not. */ if(laguerre_n_cp(n, a, x, result) == GSL_SUCCESS) return GSL_SUCCESS; else return laguerre_n_poly_safe(n, a, x, result); } else if(n > 1.0e+07 && x > 0.0 && a > -1.0 && x < 2.0*(a+1.0)+4.0*n) { return laguerre_large_n(n, a, x, result); } else if(a >= 0.0 || (x > 0.0 && a < -n-1)) { gsl_sf_result lg2; int stat_lg2 = gsl_sf_laguerre_2_e(a, x, &lg2); double Lkm1 = 1.0 + a - x; double Lk = lg2.val; double Lkp1; int k; for(k=2; kval = Lk; result->err = (fabs(lg2.err/lg2.val) + GSL_DBL_EPSILON) * n * fabs(Lk); return stat_lg2; } else { /* Despair... or magic? */ return laguerre_n_poly_safe(n, a, x, result); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_laguerre_1(double a, double x) { EVAL_RESULT(gsl_sf_laguerre_1_e(a, x, &result)); } double gsl_sf_laguerre_2(double a, double x) { EVAL_RESULT(gsl_sf_laguerre_2_e(a, x, &result)); } double gsl_sf_laguerre_3(double a, double x) { EVAL_RESULT(gsl_sf_laguerre_3_e(a, x, &result)); } double gsl_sf_laguerre_n(int n, double a, double x) { EVAL_RESULT(gsl_sf_laguerre_n_e(n, a, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__lambert.c000066400000000000000000000140471261542461700220210ustar00rootroot00000000000000/* specfunc/lambert.c * * Copyright (C) 2007 Brian Gough * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_lambert.h" /* Started with code donated by K. Briggs; added * error estimates, GSL foo, and minor tweaks. * Some Lambert-ology from * [Corless, Gonnet, Hare, and Jeffrey, "On Lambert's W Function".] */ /* Halley iteration (eqn. 5.12, Corless et al) */ static int halley_iteration( double x, double w_initial, unsigned int max_iters, gsl_sf_result * result ) { double w = w_initial; unsigned int i; for(i=0; i 0) { t = (t/p)/e; /* Newton iteration */ } else { t /= e*p - 0.5*(p + 1.0)*t/p; /* Halley iteration */ }; w -= t; tol = 10 * GSL_DBL_EPSILON * GSL_MAX_DBL(fabs(w), 1.0/(fabs(p)*e)); if(fabs(t) < tol) { result->val = w; result->err = 2.0*tol; return GSL_SUCCESS; } } /* should never get here */ result->val = w; result->err = fabs(w); return GSL_EMAXITER; } /* series which appears for q near zero; * only the argument is different for the different branches */ static double series_eval(double r) { static const double c[12] = { -1.0, 2.331643981597124203363536062168, -1.812187885639363490240191647568, 1.936631114492359755363277457668, -2.353551201881614516821543561516, 3.066858901050631912893148922704, -4.175335600258177138854984177460, 5.858023729874774148815053846119, -8.401032217523977370984161688514, 12.250753501314460424, -18.100697012472442755, 27.029044799010561650 }; const double t_8 = c[8] + r*(c[9] + r*(c[10] + r*c[11])); const double t_5 = c[5] + r*(c[6] + r*(c[7] + r*t_8)); const double t_1 = c[1] + r*(c[2] + r*(c[3] + r*(c[4] + r*t_5))); return c[0] + r*t_1; } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_lambert_W0_e(double x, gsl_sf_result * result) { const double one_over_E = 1.0/M_E; const double q = x + one_over_E; if(x == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(q < 0.0) { /* Strictly speaking this is an error. But because of the * arithmetic operation connecting x and q, I am a little * lenient in case of some epsilon overshoot. The following * answer is quite accurate in that case. Anyway, we have * to return GSL_EDOM. */ result->val = -1.0; result->err = sqrt(-q); return GSL_EDOM; } else if(q == 0.0) { result->val = -1.0; result->err = GSL_DBL_EPSILON; /* cannot error is zero, maybe q == 0 by "accident" */ return GSL_SUCCESS; } else if(q < 1.0e-03) { /* series near -1/E in sqrt(q) */ const double r = sqrt(q); result->val = series_eval(r); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { static const unsigned int MAX_ITERS = 10; double w; if (x < 1.0) { /* obtain initial approximation from series near x=0; * no need for extra care, since the Halley iteration * converges nicely on this branch */ const double p = sqrt(2.0 * M_E * q); w = -1.0 + p*(1.0 + p*(-1.0/3.0 + p*11.0/72.0)); } else { /* obtain initial approximation from rough asymptotic */ w = log(x); if(x > 3.0) w -= log(w); } return halley_iteration(x, w, MAX_ITERS, result); } } int gsl_sf_lambert_Wm1_e(double x, gsl_sf_result * result) { if(x > 0.0) { return gsl_sf_lambert_W0_e(x, result); } else if(x == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else { static const unsigned int MAX_ITERS = 32; const double one_over_E = 1.0/M_E; const double q = x + one_over_E; double w; if (q < 0.0) { /* As in the W0 branch above, return some reasonable answer anyway. */ result->val = -1.0; result->err = sqrt(-q); return GSL_EDOM; } if(x < -1.0e-6) { /* Obtain initial approximation from series about q = 0, * as long as we're not very close to x = 0. * Use full series and try to bail out if q is too small, * since the Halley iteration has bad convergence properties * in finite arithmetic for q very small, because the * increment alternates and p is near zero. */ const double r = -sqrt(q); w = series_eval(r); if(q < 3.0e-3) { /* this approximation is good enough */ result->val = w; result->err = 5.0 * GSL_DBL_EPSILON * fabs(w); return GSL_SUCCESS; } } else { /* Obtain initial approximation from asymptotic near zero. */ const double L_1 = log(-x); const double L_2 = log(-L_1); w = L_1 - L_2 + L_2/L_1; } return halley_iteration(x, w, MAX_ITERS, result); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_lambert_W0(double x) { EVAL_RESULT(gsl_sf_lambert_W0_e(x, &result)); } double gsl_sf_lambert_Wm1(double x) { EVAL_RESULT(gsl_sf_lambert_Wm1_e(x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__legendre.h000066400000000000000000000044731261542461700221670ustar00rootroot00000000000000/* specfunc/legendre.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ /* Declare private but non-local support functions * used in various Legendre function evaluations. */ #include "gsl_sf_result.h" /* Large negative mu asymptotic * P^{-mu}_{-1/2 + I tau}, mu -> Inf * |x| < 1 */ int gsl_sf_conicalP_xlt1_large_neg_mu_e(double mu, double tau, double x, gsl_sf_result * result, double * ln_multiplier); /* Large tau uniform asymptotics * P^{-mu}_{-1/2 + I tau}, tau -> Inf * 1 < x */ int gsl_sf_conicalP_xgt1_neg_mu_largetau_e(const double mu, const double tau, const double x, double acosh_x, gsl_sf_result * result, double * ln_multiplier); /* Large tau uniform asymptotics * P^{-mu}_{-1/2 + I tau}, tau -> Inf * -1 < x < 1 */ int gsl_sf_conicalP_xlt1_neg_mu_largetau_e(const double mu, const double tau, const double x, const double acos_x, gsl_sf_result * result, double * ln_multiplier); /* P^{mu}_{-1/2 + I tau} * x->Inf * * * This is effective to precision EPS for * * (mu^2 + tau^2)/((1 + tau^2)^(1/2) x^2) < EPS^{1/3} * * since it goes only to a fixed order, based on the * representation in terms of hypegeometric functions * of argument 1/x^2. * [Zhurina+Karmazina, (3.8)] */ int gsl_sf_conicalP_large_x_e(const double mu, const double tau, const double x, gsl_sf_result * result, double * ln_multiplier); praat-6.0.04/external/gsl/gsl_specfunc__legendre_H3d.c000066400000000000000000000421041261542461700226510ustar00rootroot00000000000000/* specfunc/legendre_H3d.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_exp.h" #include "gsl_sf_gamma.h" #include "gsl_sf_trig.h" #include "gsl_sf_legendre.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__legendre.h" /* See [Abbott+Schaefer, Ap.J. 308, 546 (1986)] for * enough details to follow what is happening here. */ /* Logarithm of normalization factor, Log[N(ell,lambda)]. * N(ell,lambda) = Product[ lambda^2 + n^2, {n,0,ell} ] * = |Gamma(ell + 1 + I lambda)|^2 lambda sinh(Pi lambda) / Pi * Assumes ell >= 0. */ static int legendre_H3d_lnnorm(const int ell, const double lambda, double * result) { double abs_lam = fabs(lambda); if(abs_lam == 0.0) { *result = 0.0; GSL_ERROR ("error", GSL_EDOM); } else if(lambda > (ell + 1.0)/GSL_ROOT3_DBL_EPSILON) { /* There is a cancellation between the sinh(Pi lambda) * term and the log(gamma(ell + 1 + i lambda) in the * result below, so we show some care and save some digits. * Note that the above guarantees that lambda is large, * since ell >= 0. We use Stirling and a simple expansion * of sinh. */ double rat = (ell+1.0)/lambda; double ln_lam2ell2 = 2.0*log(lambda) + log(1.0 + rat*rat); double lg_corrected = -2.0*(ell+1.0) + M_LNPI + (ell+0.5)*ln_lam2ell2 + 1.0/(288.0*lambda*lambda); double angle_terms = lambda * 2.0 * rat * (1.0 - rat*rat/3.0); *result = log(abs_lam) + lg_corrected + angle_terms - M_LNPI; return GSL_SUCCESS; } else { gsl_sf_result lg_r; gsl_sf_result lg_theta; gsl_sf_result ln_sinh; gsl_sf_lngamma_complex_e(ell+1.0, lambda, &lg_r, &lg_theta); gsl_sf_lnsinh_e(M_PI * abs_lam, &ln_sinh); *result = log(abs_lam) + ln_sinh.val + 2.0*lg_r.val - M_LNPI; return GSL_SUCCESS; } } /* Calculate series for small eta*lambda. * Assumes eta > 0, lambda != 0. * * This is just the defining hypergeometric for the Legendre function. * * P^{mu}_{-1/2 + I lam}(z) = 1/Gamma(l+3/2) ((z+1)/(z-1)^(mu/2) * 2F1(1/2 - I lam, 1/2 + I lam; l+3/2; (1-z)/2) * We use * z = cosh(eta) * (z-1)/2 = sinh^2(eta/2) * * And recall * H3d = sqrt(Pi Norm /(2 lam^2 sinh(eta))) P^{-l-1/2}_{-1/2 + I lam}(cosh(eta)) */ static int legendre_H3d_series(const int ell, const double lambda, const double eta, gsl_sf_result * result) { const int nmax = 5000; const double shheta = sinh(0.5*eta); const double ln_zp1 = M_LN2 + log(1.0 + shheta*shheta); const double ln_zm1 = M_LN2 + 2.0*log(shheta); const double zeta = -shheta*shheta; gsl_sf_result lg_lp32; double term = 1.0; double sum = 1.0; double sum_err = 0.0; gsl_sf_result lnsheta; double lnN; double lnpre_val, lnpre_err, lnprepow; int stat_e; int n; gsl_sf_lngamma_e(ell + 3.0/2.0, &lg_lp32); gsl_sf_lnsinh_e(eta, &lnsheta); legendre_H3d_lnnorm(ell, lambda, &lnN); lnprepow = 0.5*(ell + 0.5) * (ln_zm1 - ln_zp1); lnpre_val = lnprepow + 0.5*(lnN + M_LNPI - M_LN2 - lnsheta.val) - lg_lp32.val - log(fabs(lambda)); lnpre_err = lnsheta.err + lg_lp32.err + GSL_DBL_EPSILON * fabs(lnpre_val); lnpre_err += 2.0*GSL_DBL_EPSILON * (fabs(lnN) + M_LNPI + M_LN2); lnpre_err += 2.0*GSL_DBL_EPSILON * (0.5*(ell + 0.5) * (fabs(ln_zm1) + fabs(ln_zp1))); for(n=1; n RECUR_BIG || fabs(Bn) > RECUR_BIG) { An /= RECUR_BIG; Bn /= RECUR_BIG; Anm1 /= RECUR_BIG; Bnm1 /= RECUR_BIG; Anm2 /= RECUR_BIG; Bnm2 /= RECUR_BIG; } old_fn = fn; fn = An/Bn; del = old_fn/fn; if(fabs(del - 1.0) < 4.0*GSL_DBL_EPSILON) break; } result->val = fn; result->err = 2.0 * GSL_DBL_EPSILON * (sqrt(n)+1.0) * fabs(fn); if(n >= maxiter) GSL_ERROR ("error", GSL_EMAXITER); else return GSL_SUCCESS; } #endif /* 0 */ /* Evaluate legendre_H3d(ell+1)/legendre_H3d(ell) * by continued fraction. Use the Gautschi (Euler) * equivalent series. */ /* FIXME: Maybe we have to worry about this. The a_k are * not positive and there can be a blow-up. It happened * for J_nu once or twice. Then we should probably use * the method above. */ static int legendre_H3d_CF1_ser(const int ell, const double lambda, const double coth_eta, gsl_sf_result * result) { const double pre = hypot(lambda, ell+1.0)/((2.0*ell+3)*coth_eta); const int maxk = 20000; double tk = 1.0; double sum = 1.0; double rhok = 0.0; double sum_err = 0.0; int k; for(k=1; kval = pre * sum; result->err = fabs(pre * tk); result->err += fabs(pre * sum_err); result->err += 4.0 * GSL_DBL_EPSILON * fabs(result->val); if(k >= maxk) GSL_ERROR ("error", GSL_EMAXITER); else return GSL_SUCCESS; } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_legendre_H3d_0_e(const double lambda, const double eta, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(eta < 0.0) { DOMAIN_ERROR(result); } else if(eta == 0.0 || lambda == 0.0) { result->val = 1.0; result->err = 0.0; return GSL_SUCCESS; } else { const double lam_eta = lambda * eta; gsl_sf_result s; gsl_sf_sin_err_e(lam_eta, 2.0*GSL_DBL_EPSILON * fabs(lam_eta), &s); if(eta > -0.5*GSL_LOG_DBL_EPSILON) { double f = 2.0 / lambda * exp(-eta); result->val = f * s.val; result->err = fabs(f * s.val) * (fabs(eta) + 1.0) * GSL_DBL_EPSILON; result->err += fabs(f) * s.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); } else { double f = 1.0/(lambda*sinh(eta)); result->val = f * s.val; result->err = fabs(f * s.val) * (fabs(eta) + 1.0) * GSL_DBL_EPSILON; result->err += fabs(f) * s.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); } return GSL_SUCCESS; } } int gsl_sf_legendre_H3d_1_e(const double lambda, const double eta, gsl_sf_result * result) { const double xi = fabs(eta*lambda); const double lsq = lambda*lambda; const double lsqp1 = lsq + 1.0; /* CHECK_POINTER(result) */ if(eta < 0.0) { DOMAIN_ERROR(result); } else if(eta == 0.0 || lambda == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(xi < GSL_ROOT5_DBL_EPSILON && eta < GSL_ROOT5_DBL_EPSILON) { double etasq = eta*eta; double xisq = xi*xi; double term1 = (etasq + xisq)/3.0; double term2 = -(2.0*etasq*etasq + 5.0*etasq*xisq + 3.0*xisq*xisq)/90.0; double sinh_term = 1.0 - eta*eta/6.0 * (1.0 - 7.0/60.0*eta*eta); double pre = sinh_term/sqrt(lsqp1) / eta; result->val = pre * (term1 + term2); result->err = pre * GSL_DBL_EPSILON * (fabs(term1) + fabs(term2)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { double sin_term; /* Sin(xi)/xi */ double cos_term; /* Cos(xi) */ double coth_term; /* eta/Tanh(eta) */ double sinh_term; /* eta/Sinh(eta) */ double sin_term_err; double cos_term_err; double t1; double pre_val; double pre_err; double term1; double term2; if(xi < GSL_ROOT5_DBL_EPSILON) { sin_term = 1.0 - xi*xi/6.0 * (1.0 - xi*xi/20.0); cos_term = 1.0 - 0.5*xi*xi * (1.0 - xi*xi/12.0); sin_term_err = GSL_DBL_EPSILON; cos_term_err = GSL_DBL_EPSILON; } else { gsl_sf_result sin_xi_result; gsl_sf_result cos_xi_result; gsl_sf_sin_e(xi, &sin_xi_result); gsl_sf_cos_e(xi, &cos_xi_result); sin_term = sin_xi_result.val/xi; cos_term = cos_xi_result.val; sin_term_err = sin_xi_result.err/fabs(xi); cos_term_err = cos_xi_result.err; } if(eta < GSL_ROOT5_DBL_EPSILON) { coth_term = 1.0 + eta*eta/3.0 * (1.0 - eta*eta/15.0); sinh_term = 1.0 - eta*eta/6.0 * (1.0 - 7.0/60.0*eta*eta); } else { coth_term = eta/tanh(eta); sinh_term = eta/sinh(eta); } t1 = sqrt(lsqp1) * eta; pre_val = sinh_term/t1; pre_err = 2.0 * GSL_DBL_EPSILON * fabs(pre_val); term1 = sin_term*coth_term; term2 = cos_term; result->val = pre_val * (term1 - term2); result->err = pre_err * fabs(term1 - term2); result->err += pre_val * (sin_term_err * coth_term + cos_term_err); result->err += pre_val * fabs(term1-term2) * (fabs(eta) + 1.0) * GSL_DBL_EPSILON; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_legendre_H3d_e(const int ell, const double lambda, const double eta, gsl_sf_result * result) { const double abs_lam = fabs(lambda); const double lsq = abs_lam*abs_lam; const double xi = abs_lam * eta; const double cosh_eta = cosh(eta); /* CHECK_POINTER(result) */ if(eta < 0.0) { DOMAIN_ERROR(result); } else if(eta > GSL_LOG_DBL_MAX) { /* cosh(eta) is too big. */ OVERFLOW_ERROR(result); } else if(ell == 0) { return gsl_sf_legendre_H3d_0_e(lambda, eta, result); } else if(ell == 1) { return gsl_sf_legendre_H3d_1_e(lambda, eta, result); } else if(eta == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(xi < 1.0) { return legendre_H3d_series(ell, lambda, eta, result); } else if((ell*ell+lsq)/sqrt(1.0+lsq)/(cosh_eta*cosh_eta) < 5.0*GSL_ROOT3_DBL_EPSILON) { /* Large argument. */ gsl_sf_result P; double lm; int stat_P = gsl_sf_conicalP_large_x_e(-ell-0.5, lambda, cosh_eta, &P, &lm); if(P.val == 0.0) { result->val = 0.0; result->err = 0.0; return stat_P; } else { double lnN; gsl_sf_result lnsh; double ln_abslam; double lnpre_val, lnpre_err; int stat_e; gsl_sf_lnsinh_e(eta, &lnsh); legendre_H3d_lnnorm(ell, lambda, &lnN); ln_abslam = log(abs_lam); lnpre_val = 0.5*(M_LNPI + lnN - M_LN2 - lnsh.val) - ln_abslam; lnpre_err = lnsh.err; lnpre_err += 2.0 * GSL_DBL_EPSILON * (0.5*(M_LNPI + M_LN2 + fabs(lnN)) + fabs(ln_abslam)); lnpre_err += 2.0 * GSL_DBL_EPSILON * fabs(lnpre_val); stat_e = gsl_sf_exp_mult_err_e(lnpre_val + lm, lnpre_err, P.val, P.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_P); } } else if(abs_lam > 1000.0*ell*ell) { /* Large degree. */ gsl_sf_result P; double lm; int stat_P = gsl_sf_conicalP_xgt1_neg_mu_largetau_e(ell+0.5, lambda, cosh_eta, eta, &P, &lm); if(P.val == 0.0) { result->val = 0.0; result->err = 0.0; return stat_P; } else { double lnN; gsl_sf_result lnsh; double ln_abslam; double lnpre_val, lnpre_err; int stat_e; gsl_sf_lnsinh_e(eta, &lnsh); legendre_H3d_lnnorm(ell, lambda, &lnN); ln_abslam = log(abs_lam); lnpre_val = 0.5*(M_LNPI + lnN - M_LN2 - lnsh.val) - ln_abslam; lnpre_err = lnsh.err; lnpre_err += GSL_DBL_EPSILON * (0.5*(M_LNPI + M_LN2 + fabs(lnN)) + fabs(ln_abslam)); lnpre_err += 2.0 * GSL_DBL_EPSILON * fabs(lnpre_val); stat_e = gsl_sf_exp_mult_err_e(lnpre_val + lm, lnpre_err, P.val, P.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_P); } } else { /* Backward recurrence. */ const double coth_eta = 1.0/tanh(eta); const double coth_err_mult = fabs(eta) + 1.0; gsl_sf_result rH; int stat_CF1 = legendre_H3d_CF1_ser(ell, lambda, coth_eta, &rH); double Hlm1; double Hl = GSL_SQRT_DBL_MIN; double Hlp1 = rH.val * Hl; int lp; for(lp=ell; lp>0; lp--) { double root_term_0 = hypot(lambda,lp); double root_term_1 = hypot(lambda,lp+1.0); Hlm1 = ((2.0*lp + 1.0)*coth_eta*Hl - root_term_1 * Hlp1)/root_term_0; Hlp1 = Hl; Hl = Hlm1; } if(fabs(Hl) > fabs(Hlp1)) { gsl_sf_result H0; int stat_H0 = gsl_sf_legendre_H3d_0_e(lambda, eta, &H0); result->val = GSL_SQRT_DBL_MIN/Hl * H0.val; result->err = GSL_SQRT_DBL_MIN/fabs(Hl) * H0.err; result->err += fabs(rH.err/rH.val) * (ell+1.0) * coth_err_mult * fabs(result->val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_H0, stat_CF1); } else { gsl_sf_result H1; int stat_H1 = gsl_sf_legendre_H3d_1_e(lambda, eta, &H1); result->val = GSL_SQRT_DBL_MIN/Hlp1 * H1.val; result->err = GSL_SQRT_DBL_MIN/fabs(Hlp1) * H1.err; result->err += fabs(rH.err/rH.val) * (ell+1.0) * coth_err_mult * fabs(result->val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_H1, stat_CF1); } } } int gsl_sf_legendre_H3d_array(const int lmax, const double lambda, const double eta, double * result_array) { /* CHECK_POINTER(result_array) */ if(eta < 0.0 || lmax < 0) { int ell; for(ell=0; ell<=lmax; ell++) result_array[ell] = 0.0; GSL_ERROR ("domain error", GSL_EDOM); } else if(eta > GSL_LOG_DBL_MAX) { /* cosh(eta) is too big. */ int ell; for(ell=0; ell<=lmax; ell++) result_array[ell] = 0.0; GSL_ERROR ("overflow", GSL_EOVRFLW); } else if(lmax == 0) { gsl_sf_result H0; int stat = gsl_sf_legendre_H3d_e(0, lambda, eta, &H0); result_array[0] = H0.val; return stat; } else { /* Not the most efficient method. But what the hell... it's simple. */ gsl_sf_result r_Hlp1; gsl_sf_result r_Hl; int stat_lmax = gsl_sf_legendre_H3d_e(lmax, lambda, eta, &r_Hlp1); int stat_lmaxm1 = gsl_sf_legendre_H3d_e(lmax-1, lambda, eta, &r_Hl); int stat_max = GSL_ERROR_SELECT_2(stat_lmax, stat_lmaxm1); const double coth_eta = 1.0/tanh(eta); int stat_recursion = GSL_SUCCESS; double Hlp1 = r_Hlp1.val; double Hl = r_Hl.val; double Hlm1; int ell; result_array[lmax] = Hlp1; result_array[lmax-1] = Hl; for(ell=lmax-1; ell>0; ell--) { double root_term_0 = hypot(lambda,ell); double root_term_1 = hypot(lambda,ell+1.0); Hlm1 = ((2.0*ell + 1.0)*coth_eta*Hl - root_term_1 * Hlp1)/root_term_0; result_array[ell-1] = Hlm1; if(!(Hlm1 < GSL_DBL_MAX)) stat_recursion = GSL_EOVRFLW; Hlp1 = Hl; Hl = Hlm1; } return GSL_ERROR_SELECT_2(stat_recursion, stat_max); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_legendre_H3d_0(const double lambda, const double eta) { EVAL_RESULT(gsl_sf_legendre_H3d_0_e(lambda, eta, &result)); } double gsl_sf_legendre_H3d_1(const double lambda, const double eta) { EVAL_RESULT(gsl_sf_legendre_H3d_1_e(lambda, eta, &result)); } double gsl_sf_legendre_H3d(const int l, const double lambda, const double eta) { EVAL_RESULT(gsl_sf_legendre_H3d_e(l, lambda, eta, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__legendre_Qn.c000066400000000000000000000227721261542461700226220ustar00rootroot00000000000000/* specfunc/legendre_Qn.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_bessel.h" #include "gsl_sf_elementary.h" #include "gsl_sf_exp.h" #include "gsl_sf_pow_int.h" #include "gsl_sf_legendre.h" #include "gsl_specfunc__error.h" /* Evaluate f_{ell+1}/f_ell * f_ell := Q^{b}_{a+ell}(x) * x > 1 */ static int legendreQ_CF1_xgt1(int ell, double a, double b, double x, double * result) { const double RECUR_BIG = GSL_SQRT_DBL_MAX; const int maxiter = 5000; int n = 1; double Anm2 = 1.0; double Bnm2 = 0.0; double Anm1 = 0.0; double Bnm1 = 1.0; double a1 = ell + 1.0 + a + b; double b1 = (2.0*(ell+1.0+a) + 1.0) * x; double An = b1*Anm1 + a1*Anm2; double Bn = b1*Bnm1 + a1*Bnm2; double an, bn; double fn = An/Bn; while(n < maxiter) { double old_fn; double del; double lna; n++; Anm2 = Anm1; Bnm2 = Bnm1; Anm1 = An; Bnm1 = Bn; lna = ell + n + a; an = b*b - lna*lna; bn = (2.0*lna + 1.0) * x; An = bn*Anm1 + an*Anm2; Bn = bn*Bnm1 + an*Bnm2; if(fabs(An) > RECUR_BIG || fabs(Bn) > RECUR_BIG) { An /= RECUR_BIG; Bn /= RECUR_BIG; Anm1 /= RECUR_BIG; Bnm1 /= RECUR_BIG; Anm2 /= RECUR_BIG; Bnm2 /= RECUR_BIG; } old_fn = fn; fn = An/Bn; del = old_fn/fn; if(fabs(del - 1.0) < 4.0*GSL_DBL_EPSILON) break; } *result = fn; if(n == maxiter) GSL_ERROR ("error", GSL_EMAXITER); else return GSL_SUCCESS; } /* Uniform asymptotic for Q_l(x). * Assumes x > -1.0 and x != 1.0. * Discards second order and higher terms. */ static int legendre_Ql_asymp_unif(const double ell, const double x, gsl_sf_result * result) { if(x < 1.0) { double u = ell + 0.5; double th = acos(x); gsl_sf_result Y0, Y1; int stat_Y0, stat_Y1; int stat_m; double pre; double B00; double sum; /* B00 = 1/8 (1 - th cot(th) / th^2 * pre = sqrt(th/sin(th)) */ if(th < GSL_ROOT4_DBL_EPSILON) { B00 = (1.0 + th*th/15.0)/24.0; pre = 1.0 + th*th/12.0; } else { double sin_th = sqrt(1.0 - x*x); double cot_th = x / sin_th; B00 = 1.0/8.0 * (1.0 - th * cot_th) / (th*th); pre = sqrt(th/sin_th); } stat_Y0 = gsl_sf_bessel_Y0_e(u*th, &Y0); stat_Y1 = gsl_sf_bessel_Y1_e(u*th, &Y1); sum = -0.5*M_PI * (Y0.val + th/u * Y1.val * B00); stat_m = gsl_sf_multiply_e(pre, sum, result); result->err += 0.5*M_PI * fabs(pre) * (Y0.err + fabs(th/u*B00)*Y1.err); result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_3(stat_m, stat_Y0, stat_Y1); } else { double u = ell + 0.5; double xi = acosh(x); gsl_sf_result K0_scaled, K1_scaled; int stat_K0, stat_K1; int stat_e; double pre; double B00; double sum; /* B00 = -1/8 (1 - xi coth(xi) / xi^2 * pre = sqrt(xi/sinh(xi)) */ if(xi < GSL_ROOT4_DBL_EPSILON) { B00 = (1.0-xi*xi/15.0)/24.0; pre = 1.0 - xi*xi/12.0; } else { double sinh_xi = sqrt(x*x - 1.0); double coth_xi = x / sinh_xi; B00 = -1.0/8.0 * (1.0 - xi * coth_xi) / (xi*xi); pre = sqrt(xi/sinh_xi); } stat_K0 = gsl_sf_bessel_K0_scaled_e(u*xi, &K0_scaled); stat_K1 = gsl_sf_bessel_K1_scaled_e(u*xi, &K1_scaled); sum = K0_scaled.val - xi/u * K1_scaled.val * B00; stat_e = gsl_sf_exp_mult_e(-u*xi, pre * sum, result); result->err = GSL_DBL_EPSILON * fabs(result->val) * fabs(u*xi); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_3(stat_e, stat_K0, stat_K1); } } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_legendre_Q0_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= -1.0 || x == 1.0) { DOMAIN_ERROR(result); } else if(x*x < GSL_ROOT6_DBL_EPSILON) { /* |x| <~ 0.05 */ const double c3 = 1.0/3.0; const double c5 = 1.0/5.0; const double c7 = 1.0/7.0; const double c9 = 1.0/9.0; const double c11 = 1.0/11.0; const double y = x * x; const double series = 1.0 + y*(c3 + y*(c5 + y*(c7 + y*(c9 + y*c11)))); result->val = x * series; result->err = 2.0 * GSL_DBL_EPSILON * fabs(x); return GSL_SUCCESS; } else if(x < 1.0) { result->val = 0.5 * log((1.0+x)/(1.0-x)); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < 10.0) { result->val = 0.5 * log((x+1.0)/(x-1.0)); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x*GSL_DBL_MIN < 2.0) { const double y = 1.0/(x*x); const double c1 = 1.0/3.0; const double c2 = 1.0/5.0; const double c3 = 1.0/7.0; const double c4 = 1.0/9.0; const double c5 = 1.0/11.0; const double c6 = 1.0/13.0; const double c7 = 1.0/15.0; result->val = (1.0/x) * (1.0 + y*(c1 + y*(c2 + y*(c3 + y*(c4 + y*(c5 + y*(c6 + y*c7))))))); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { UNDERFLOW_ERROR(result); } } int gsl_sf_legendre_Q1_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= -1.0 || x == 1.0) { DOMAIN_ERROR(result); } else if(x*x < GSL_ROOT6_DBL_EPSILON) { /* |x| <~ 0.05 */ const double c3 = 1.0/3.0; const double c5 = 1.0/5.0; const double c7 = 1.0/7.0; const double c9 = 1.0/9.0; const double c11 = 1.0/11.0; const double y = x * x; const double series = 1.0 + y*(c3 + y*(c5 + y*(c7 + y*(c9 + y*c11)))); result->val = x * x * series - 1.0; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < 1.0){ result->val = 0.5 * x * (log((1.0+x)/(1.0-x))) - 1.0; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < 6.0) { result->val = 0.5 * x * log((x+1.0)/(x-1.0)) - 1.0; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x*GSL_SQRT_DBL_MIN < 0.99/M_SQRT3) { const double y = 1/(x*x); const double c1 = 3.0/5.0; const double c2 = 3.0/7.0; const double c3 = 3.0/9.0; const double c4 = 3.0/11.0; const double c5 = 3.0/13.0; const double c6 = 3.0/15.0; const double c7 = 3.0/17.0; const double c8 = 3.0/19.0; const double sum = 1.0 + y*(c1 + y*(c2 + y*(c3 + y*(c4 + y*(c5 + y*(c6 + y*(c7 + y*c8))))))); result->val = sum / (3.0*x*x); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { UNDERFLOW_ERROR(result); } } int gsl_sf_legendre_Ql_e(const int l, const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= -1.0 || x == 1.0 || l < 0) { DOMAIN_ERROR(result); } else if(l == 0) { return gsl_sf_legendre_Q0_e(x, result); } else if(l == 1) { return gsl_sf_legendre_Q1_e(x, result); } else if(l > 100000) { return legendre_Ql_asymp_unif(l, x, result); } else if(x < 1.0){ /* Forward recurrence. */ gsl_sf_result Q0, Q1; int stat_Q0 = gsl_sf_legendre_Q0_e(x, &Q0); int stat_Q1 = gsl_sf_legendre_Q1_e(x, &Q1); double Qellm1 = Q0.val; double Qell = Q1.val; double Qellp1; int ell; for(ell=1; ellval = Qell; result->err = GSL_DBL_EPSILON * l * fabs(result->val); return GSL_ERROR_SELECT_2(stat_Q0, stat_Q1); } else { /* x > 1.0 */ double rat; int stat_CF1 = legendreQ_CF1_xgt1(l, 0.0, 0.0, x, &rat); int stat_Q; double Qellp1 = rat * GSL_SQRT_DBL_MIN; double Qell = GSL_SQRT_DBL_MIN; double Qellm1; int ell; for(ell=l; ell>0; ell--) { Qellm1 = (x * (2.0*ell + 1.0) * Qell - (ell+1.0) * Qellp1) / ell; Qellp1 = Qell; Qell = Qellm1; } if(fabs(Qell) > fabs(Qellp1)) { gsl_sf_result Q0; stat_Q = gsl_sf_legendre_Q0_e(x, &Q0); result->val = GSL_SQRT_DBL_MIN * Q0.val / Qell; result->err = l * GSL_DBL_EPSILON * fabs(result->val); } else { gsl_sf_result Q1; stat_Q = gsl_sf_legendre_Q1_e(x, &Q1); result->val = GSL_SQRT_DBL_MIN * Q1.val / Qellp1; result->err = l * GSL_DBL_EPSILON * fabs(result->val); } return GSL_ERROR_SELECT_2(stat_Q, stat_CF1); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_legendre_Q0(const double x) { EVAL_RESULT(gsl_sf_legendre_Q0_e(x, &result)); } double gsl_sf_legendre_Q1(const double x) { EVAL_RESULT(gsl_sf_legendre_Q1_e(x, &result)); } double gsl_sf_legendre_Ql(const int l, const double x) { EVAL_RESULT(gsl_sf_legendre_Ql_e(l, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__legendre_con.c000066400000000000000000001243521261542461700230200ustar00rootroot00000000000000/* specfunc/legendre_con.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_poly.h" #include "gsl_sf_exp.h" #include "gsl_sf_trig.h" #include "gsl_sf_gamma.h" #include "gsl_sf_ellint.h" #include "gsl_sf_pow_int.h" #include "gsl_sf_bessel.h" #include "gsl_sf_hyperg.h" #include "gsl_sf_legendre.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__legendre.h" #define Root_2OverPi_ 0.797884560802865355879892 #define locEPS (1000.0*GSL_DBL_EPSILON) /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/ #define RECURSE_LARGE (1.0e-5*GSL_DBL_MAX) #define RECURSE_SMALL (1.0e+5*GSL_DBL_MIN) /* Continued fraction for f_{ell+1}/f_ell * f_ell := P^{-mu-ell}_{-1/2 + I tau}(x), x < 1.0 * * Uses standard CF method from Temme's book. */ static int conicalP_negmu_xlt1_CF1(const double mu, const int ell, const double tau, const double x, gsl_sf_result * result) { const double RECUR_BIG = GSL_SQRT_DBL_MAX; const int maxiter = 5000; int n = 1; double xi = x/(sqrt(1.0-x)*sqrt(1.0+x)); double Anm2 = 1.0; double Bnm2 = 0.0; double Anm1 = 0.0; double Bnm1 = 1.0; double a1 = 1.0; double b1 = 2.0*(mu + ell + 1.0) * xi; double An = b1*Anm1 + a1*Anm2; double Bn = b1*Bnm1 + a1*Bnm2; double an, bn; double fn = An/Bn; while(n < maxiter) { double old_fn; double del; n++; Anm2 = Anm1; Bnm2 = Bnm1; Anm1 = An; Bnm1 = Bn; an = tau*tau + (mu - 0.5 + ell + n)*(mu - 0.5 + ell + n); bn = 2.0*(ell + mu + n) * xi; An = bn*Anm1 + an*Anm2; Bn = bn*Bnm1 + an*Bnm2; if(fabs(An) > RECUR_BIG || fabs(Bn) > RECUR_BIG) { An /= RECUR_BIG; Bn /= RECUR_BIG; Anm1 /= RECUR_BIG; Bnm1 /= RECUR_BIG; Anm2 /= RECUR_BIG; Bnm2 /= RECUR_BIG; } old_fn = fn; fn = An/Bn; del = old_fn/fn; if(fabs(del - 1.0) < 2.0*GSL_DBL_EPSILON) break; } result->val = fn; result->err = 4.0 * GSL_DBL_EPSILON * (sqrt(n) + 1.0) * fabs(fn); if(n >= maxiter) GSL_ERROR ("error", GSL_EMAXITER); else return GSL_SUCCESS; } /* Continued fraction for f_{ell+1}/f_ell * f_ell := P^{-mu-ell}_{-1/2 + I tau}(x), x >= 1.0 * * Uses Gautschi (Euler) equivalent series. */ static int conicalP_negmu_xgt1_CF1(const double mu, const int ell, const double tau, const double x, gsl_sf_result * result) { const int maxk = 20000; const double gamma = 1.0-1.0/(x*x); const double pre = sqrt(x-1.0)*sqrt(x+1.0) / (x*(2.0*(ell+mu+1.0))); double tk = 1.0; double sum = 1.0; double rhok = 0.0; int k; for(k=1; kval = pre * sum; result->err = fabs(pre * tk); result->err += 2.0 * GSL_DBL_EPSILON * (sqrt(k) + 1.0) * fabs(pre*sum); if(k >= maxk) GSL_ERROR ("error", GSL_EMAXITER); else return GSL_SUCCESS; } /* Implementation of large negative mu asymptotic * [Dunster, Proc. Roy. Soc. Edinburgh 119A, 311 (1991), p. 326] */ inline static double olver_U1(double beta2, double p) { return (p-1.0)/(24.0*(1.0+beta2)) * (3.0 + beta2*(2.0 + 5.0*p*(1.0+p))); } inline static double olver_U2(double beta2, double p) { double beta4 = beta2*beta2; double p2 = p*p; double poly1 = 4.0*beta4 + 84.0*beta2 - 63.0; double poly2 = 16.0*beta4 + 90.0*beta2 - 81.0; double poly3 = beta2*p2*(97.0*beta2 - 432.0 + 77.0*p*(beta2-6.0) - 385.0*beta2*p2*(1.0 + p)); return (1.0-p)/(1152.0*(1.0+beta2)) * (poly1 + poly2 + poly3); } static const double U3c1[] = { -1307.0, -1647.0, 3375.0, 3675.0 }; static const double U3c2[] = { 29366.0, 35835.0, -252360.0, -272630.0, 276810.0, 290499.0 }; static const double U3c3[] = { -29748.0, -8840.0, 1725295.0, 1767025.0, -7313470.0, -754778.0, 6309875.0, 6480045.0 }; static const double U3c4[] = { 2696.0, -16740.0, -524250.0, -183975.0, 14670540.0, 14172939.0, -48206730.0, -48461985.0, 36756720.0, 37182145.0 }; static const double U3c5[] = { 9136.0, 22480.0, 12760.0, -252480.0, -4662165.0, -1705341.0, 92370135.0, 86244015.0, -263678415.0, -260275015.0, 185910725.0, 185910725.0 }; #if 0 static double olver_U3(double beta2, double p) { double beta4 = beta2*beta2; double beta6 = beta4*beta2; double opb2s = (1.0+beta2)*(1.0+beta2); double den = 39813120.0 * opb2s*opb2s; double poly1 = gsl_poly_eval(U3c1, 4, p); double poly2 = gsl_poly_eval(U3c2, 6, p); double poly3 = gsl_poly_eval(U3c3, 8, p); double poly4 = gsl_poly_eval(U3c4, 10, p); double poly5 = gsl_poly_eval(U3c5, 12, p); return (p-1.0)*( 1215.0*poly1 + 324.0*beta2*poly2 + 54.0*beta4*poly3 + 12.0*beta6*poly4 + beta4*beta4*poly5 ) / den; } #endif /* 0 */ /* Large negative mu asymptotic * P^{-mu}_{-1/2 + I tau}, mu -> Inf * |x| < 1 * * [Dunster, Proc. Roy. Soc. Edinburgh 119A, 311 (1991), p. 326] */ int gsl_sf_conicalP_xlt1_large_neg_mu_e(double mu, double tau, double x, gsl_sf_result * result, double * ln_multiplier) { double beta = tau/mu; double beta2 = beta*beta; double S = beta * acos((1.0-beta2)/(1.0+beta2)); double p = x/sqrt(beta2*(1.0-x*x) + 1.0); gsl_sf_result lg_mup1; int lg_stat = gsl_sf_lngamma_e(mu+1.0, &lg_mup1); double ln_pre_1 = 0.5*mu*(S - log(1.0+beta2) + log((1.0-p)/(1.0+p))) - lg_mup1.val; double ln_pre_2 = -0.25 * log(1.0 + beta2*(1.0-x)); double ln_pre_3 = -tau * atan(p*beta); double ln_pre = ln_pre_1 + ln_pre_2 + ln_pre_3; double sum = 1.0 - olver_U1(beta2, p)/mu + olver_U2(beta2, p)/(mu*mu); if(sum == 0.0) { result->val = 0.0; result->err = 0.0; *ln_multiplier = 0.0; return GSL_SUCCESS; } else { int stat_e = gsl_sf_exp_mult_e(ln_pre, sum, result); if(stat_e != GSL_SUCCESS) { result->val = sum; result->err = 2.0 * GSL_DBL_EPSILON * fabs(sum); *ln_multiplier = ln_pre; } else { *ln_multiplier = 0.0; } return lg_stat; } } /* Implementation of large tau asymptotic * * A_n^{-mu}, B_n^{-mu} [Olver, p.465, 469] */ inline static double olver_B0_xi(double mu, double xi) { return (1.0 - 4.0*mu*mu)/(8.0*xi) * (1.0/tanh(xi) - 1.0/xi); } static double olver_A1_xi(double mu, double xi, double x) { double B = olver_B0_xi(mu, xi); double psi; if(fabs(x - 1.0) < GSL_ROOT4_DBL_EPSILON) { double y = x - 1.0; double s = -1.0/3.0 + y*(2.0/15.0 - y *(61.0/945.0 - 452.0/14175.0*y)); psi = (4.0*mu*mu - 1.0)/16.0 * s; } else { psi = (4.0*mu*mu - 1.0)/16.0 * (1.0/(x*x-1.0) - 1.0/(xi*xi)); } return 0.5*xi*xi*B*B + (mu+0.5)*B - psi + mu/6.0*(0.25 - mu*mu); } inline static double olver_B0_th(double mu, double theta) { return -(1.0 - 4.0*mu*mu)/(8.0*theta) * (1.0/tan(theta) - 1.0/theta); } static double olver_A1_th(double mu, double theta, double x) { double B = olver_B0_th(mu, theta); double psi; if(fabs(x - 1.0) < GSL_ROOT4_DBL_EPSILON) { double y = 1.0 - x; double s = -1.0/3.0 + y*(2.0/15.0 - y *(61.0/945.0 - 452.0/14175.0*y)); psi = (4.0*mu*mu - 1.0)/16.0 * s; } else { psi = (4.0*mu*mu - 1.0)/16.0 * (1.0/(x*x-1.0) + 1.0/(theta*theta)); } return -0.5*theta*theta*B*B + (mu+0.5)*B - psi + mu/6.0*(0.25 - mu*mu); } /* Large tau uniform asymptotics * P^{-mu}_{-1/2 + I tau} * 1 < x * tau -> Inf * [Olver, p. 469] */ int gsl_sf_conicalP_xgt1_neg_mu_largetau_e(const double mu, const double tau, const double x, double acosh_x, gsl_sf_result * result, double * ln_multiplier) { double xi = acosh_x; double ln_xi_pre; double ln_pre; double sumA, sumB, sum; double arg; gsl_sf_result J_mup1; gsl_sf_result J_mu; double J_mum1; if(xi < GSL_ROOT4_DBL_EPSILON) { ln_xi_pre = -xi*xi/6.0; /* log(1.0 - xi*xi/6.0) */ } else { gsl_sf_result lnshxi; gsl_sf_lnsinh_e(xi, &lnshxi); ln_xi_pre = log(xi) - lnshxi.val; /* log(xi/sinh(xi) */ } ln_pre = 0.5*ln_xi_pre - mu*log(tau); arg = tau*xi; gsl_sf_bessel_Jnu_e(mu + 1.0, arg, &J_mup1); gsl_sf_bessel_Jnu_e(mu, arg, &J_mu); J_mum1 = -J_mup1.val + 2.0*mu/arg*J_mu.val; /* careful of mu < 1 */ sumA = 1.0 - olver_A1_xi(-mu, xi, x)/(tau*tau); sumB = olver_B0_xi(-mu, xi); sum = J_mu.val * sumA - xi/tau * J_mum1 * sumB; if(sum == 0.0) { result->val = 0.0; result->err = 0.0; *ln_multiplier = 0.0; return GSL_SUCCESS; } else { int stat_e = gsl_sf_exp_mult_e(ln_pre, sum, result); if(stat_e != GSL_SUCCESS) { result->val = sum; result->err = 2.0 * GSL_DBL_EPSILON * fabs(sum); *ln_multiplier = ln_pre; } else { *ln_multiplier = 0.0; } return GSL_SUCCESS; } } /* Large tau uniform asymptotics * P^{-mu}_{-1/2 + I tau} * -1 < x < 1 * tau -> Inf * [Olver, p. 473] */ int gsl_sf_conicalP_xlt1_neg_mu_largetau_e(const double mu, const double tau, const double x, const double acos_x, gsl_sf_result * result, double * ln_multiplier) { double theta = acos_x; double ln_th_pre; double ln_pre; double sumA, sumB, sum, sumerr; double arg; gsl_sf_result I_mup1, I_mu; double I_mum1; if(theta < GSL_ROOT4_DBL_EPSILON) { ln_th_pre = theta*theta/6.0; /* log(1.0 + theta*theta/6.0) */ } else { ln_th_pre = log(theta/sin(theta)); } ln_pre = 0.5 * ln_th_pre - mu * log(tau); arg = tau*theta; gsl_sf_bessel_Inu_e(mu + 1.0, arg, &I_mup1); gsl_sf_bessel_Inu_e(mu, arg, &I_mu); I_mum1 = I_mup1.val + 2.0*mu/arg * I_mu.val; /* careful of mu < 1 */ sumA = 1.0 - olver_A1_th(-mu, theta, x)/(tau*tau); sumB = olver_B0_th(-mu, theta); sum = I_mu.val * sumA - theta/tau * I_mum1 * sumB; sumerr = fabs(I_mu.err * sumA); sumerr += fabs(I_mup1.err * theta/tau * sumB); sumerr += fabs(I_mu.err * theta/tau * sumB * 2.0 * mu/arg); if(sum == 0.0) { result->val = 0.0; result->err = 0.0; *ln_multiplier = 0.0; return GSL_SUCCESS; } else { int stat_e = gsl_sf_exp_mult_e(ln_pre, sum, result); if(stat_e != GSL_SUCCESS) { result->val = sum; result->err = sumerr; result->err += GSL_DBL_EPSILON * fabs(sum); *ln_multiplier = ln_pre; } else { *ln_multiplier = 0.0; } return GSL_SUCCESS; } } /* Hypergeometric function which appears in the * large x expansion below: * * 2F1(1/4 - mu/2 - I tau/2, 3/4 - mu/2 - I tau/2, 1 - I tau, y) * * Note that for the usage below y = 1/x^2; */ static int conicalP_hyperg_large_x(const double mu, const double tau, const double y, double * reF, double * imF) { const int kmax = 1000; const double re_a = 0.25 - 0.5*mu; const double re_b = 0.75 - 0.5*mu; const double re_c = 1.0; const double im_a = -0.5*tau; const double im_b = -0.5*tau; const double im_c = -tau; double re_sum = 1.0; double im_sum = 0.0; double re_term = 1.0; double im_term = 0.0; int k; for(k=1; k<=kmax; k++) { double re_ak = re_a + k - 1.0; double re_bk = re_b + k - 1.0; double re_ck = re_c + k - 1.0; double im_ak = im_a; double im_bk = im_b; double im_ck = im_c; double den = re_ck*re_ck + im_ck*im_ck; double re_multiplier = ((re_ak*re_bk - im_ak*im_bk)*re_ck + im_ck*(im_ak*re_bk + re_ak*im_bk)) / den; double im_multiplier = ((im_ak*re_bk + re_ak*im_bk)*re_ck - im_ck*(re_ak*re_bk - im_ak*im_bk)) / den; double re_tmp = re_multiplier*re_term - im_multiplier*im_term; double im_tmp = im_multiplier*re_term + re_multiplier*im_term; double asum = fabs(re_sum) + fabs(im_sum); re_term = y/k * re_tmp; im_term = y/k * im_tmp; if(fabs(re_term/asum) < GSL_DBL_EPSILON && fabs(im_term/asum) < GSL_DBL_EPSILON) break; re_sum += re_term; im_sum += im_term; } *reF = re_sum; *imF = im_sum; if(k == kmax) GSL_ERROR ("error", GSL_EMAXITER); else return GSL_SUCCESS; } /* P^{mu}_{-1/2 + I tau} * x->Inf */ int gsl_sf_conicalP_large_x_e(const double mu, const double tau, const double x, gsl_sf_result * result, double * ln_multiplier) { /* 2F1 term */ double y = ( x < 0.5*GSL_SQRT_DBL_MAX ? 1.0/(x*x) : 0.0 ); double reF, imF; int stat_F = conicalP_hyperg_large_x(mu, tau, y, &reF, &imF); /* f = Gamma(+i tau)/Gamma(1/2 - mu + i tau) * FIXME: shift so it's better for tau-> 0 */ gsl_sf_result lgr_num, lgth_num; gsl_sf_result lgr_den, lgth_den; int stat_gn = gsl_sf_lngamma_complex_e(0.0,tau,&lgr_num,&lgth_num); int stat_gd = gsl_sf_lngamma_complex_e(0.5-mu,tau,&lgr_den,&lgth_den); double angle = lgth_num.val - lgth_den.val + atan2(imF,reF); double lnx = log(x); double lnxp1 = log(x+1.0); double lnxm1 = log(x-1.0); double lnpre_const = 0.5*M_LN2 - 0.5*M_LNPI; double lnpre_comm = (mu-0.5)*lnx - 0.5*mu*(lnxp1 + lnxm1); double lnpre_err = GSL_DBL_EPSILON * (0.5*M_LN2 + 0.5*M_LNPI) + GSL_DBL_EPSILON * fabs((mu-0.5)*lnx) + GSL_DBL_EPSILON * fabs(0.5*mu)*(fabs(lnxp1)+fabs(lnxm1)); /* result = pre*|F|*|f| * cos(angle - tau * (log(x)+M_LN2)) */ gsl_sf_result cos_result; int stat_cos = gsl_sf_cos_e(angle + tau*(log(x) + M_LN2), &cos_result); int status = GSL_ERROR_SELECT_4(stat_cos, stat_gd, stat_gn, stat_F); if(cos_result.val == 0.0) { result->val = 0.0; result->err = 0.0; return status; } else { double lnFf_val = 0.5*log(reF*reF+imF*imF) + lgr_num.val - lgr_den.val; double lnFf_err = lgr_num.err + lgr_den.err + GSL_DBL_EPSILON * fabs(lnFf_val); double lnnoc_val = lnpre_const + lnpre_comm + lnFf_val; double lnnoc_err = lnpre_err + lnFf_err + GSL_DBL_EPSILON * fabs(lnnoc_val); int stat_e = gsl_sf_exp_mult_err_e(lnnoc_val, lnnoc_err, cos_result.val, cos_result.err, result); if(stat_e == GSL_SUCCESS) { *ln_multiplier = 0.0; } else { result->val = cos_result.val; result->err = cos_result.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); *ln_multiplier = lnnoc_val; } return status; } } /* P^{mu}_{-1/2 + I tau} first hypergeometric representation * -1 < x < 1 * This is more effective for |x| small, however it will work w/o * reservation for any x < 0 because everything is positive * definite in that case. * * [Kolbig, (3)] (note typo in args of gamma functions) * [Bateman, (22)] (correct form) */ static int conicalP_xlt1_hyperg_A(double mu, double tau, double x, gsl_sf_result * result) { double x2 = x*x; double err_amp = 1.0 + 1.0/(GSL_DBL_EPSILON + fabs(1.0-fabs(x))); double pre_val = M_SQRTPI / pow(0.5*sqrt(1-x2), mu); double pre_err = err_amp * GSL_DBL_EPSILON * (fabs(mu)+1.0) * fabs(pre_val) ; gsl_sf_result ln_g1, ln_g2, arg_g1, arg_g2; gsl_sf_result F1, F2; gsl_sf_result pre1, pre2; double t1_val, t1_err; double t2_val, t2_err; int stat_F1 = gsl_sf_hyperg_2F1_conj_e(0.25 - 0.5*mu, 0.5*tau, 0.5, x2, &F1); int stat_F2 = gsl_sf_hyperg_2F1_conj_e(0.75 - 0.5*mu, 0.5*tau, 1.5, x2, &F2); int status = GSL_ERROR_SELECT_2(stat_F1, stat_F2); gsl_sf_lngamma_complex_e(0.75 - 0.5*mu, -0.5*tau, &ln_g1, &arg_g1); gsl_sf_lngamma_complex_e(0.25 - 0.5*mu, -0.5*tau, &ln_g2, &arg_g2); gsl_sf_exp_err_e(-2.0*ln_g1.val, 2.0*ln_g1.err, &pre1); gsl_sf_exp_err_e(-2.0*ln_g2.val, 2.0*ln_g2.err, &pre2); pre2.val *= -2.0*x; pre2.err *= 2.0*fabs(x); pre2.err += GSL_DBL_EPSILON * fabs(pre2.val); t1_val = pre1.val * F1.val; t1_err = fabs(pre1.val) * F1.err + pre1.err * fabs(F1.val); t2_val = pre2.val * F2.val; t2_err = fabs(pre2.val) * F2.err + pre2.err * fabs(F2.val); result->val = pre_val * (t1_val + t2_val); result->err = pre_val * (t1_err + t2_err); result->err += pre_err * fabs(t1_val + t2_val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return status; } /* P^{mu}_{-1/2 + I tau} * defining hypergeometric representation * [Abramowitz+Stegun, 8.1.2] * 1 < x < 3 * effective for x near 1 * */ #if 0 static int conicalP_def_hyperg(double mu, double tau, double x, double * result) { double F; int stat_F = gsl_sf_hyperg_2F1_conj_renorm_e(0.5, tau, 1.0-mu, 0.5*(1.0-x), &F); *result = pow((x+1.0)/(x-1.0), 0.5*mu) * F; return stat_F; } #endif /* 0 */ /* P^{mu}_{-1/2 + I tau} second hypergeometric representation * [Zhurina+Karmazina, (3.1)] * -1 < x < 3 * effective for x near 1 * */ #if 0 static int conicalP_xnear1_hyperg_C(double mu, double tau, double x, double * result) { double ln_pre, arg_pre; double ln_g1, arg_g1; double ln_g2, arg_g2; double F; int stat_F = gsl_sf_hyperg_2F1_conj_renorm_e(0.5+mu, tau, 1.0+mu, 0.5*(1.0-x), &F); gsl_sf_lngamma_complex_e(0.5+mu, tau, &ln_g1, &arg_g1); gsl_sf_lngamma_complex_e(0.5-mu, tau, &ln_g2, &arg_g2); ln_pre = mu*M_LN2 - 0.5*mu*log(fabs(x*x-1.0)) + ln_g1 - ln_g2; arg_pre = arg_g1 - arg_g2; *result = exp(ln_pre) * F; return stat_F; } #endif /* 0 */ /* V0, V1 from Kolbig, m = 0 */ static int conicalP_0_V(const double t, const double f, const double tau, const double sgn, double * V0, double * V1) { double C[8]; double T[8]; double H[8]; double V[12]; int i; T[0] = 1.0; H[0] = 1.0; V[0] = 1.0; for(i=1; i<=7; i++) { T[i] = T[i-1] * t; H[i] = H[i-1] * (t*f); } for(i=1; i<=11; i++) { V[i] = V[i-1] * tau; } C[0] = 1.0; C[1] = (H[1]-1.0)/(8.0*T[1]); C[2] = (9.0*H[2] + 6.0*H[1] - 15.0 - sgn*8.0*T[2])/(128.0*T[2]); C[3] = 5.0*(15.0*H[3] + 27.0*H[2] + 21.0*H[1] - 63.0 - sgn*T[2]*(16.0*H[1]+24.0))/(1024.0*T[3]); C[4] = 7.0*(525.0*H[4] + 1500.0*H[3] + 2430.0*H[2] + 1980.0*H[1] - 6435.0 + 192.0*T[4] - sgn*T[2]*(720.0*H[2]+1600.0*H[1]+2160.0) ) / (32768.0*T[4]); C[5] = 21.0*(2835.0*H[5] + 11025.0*H[4] + 24750.0*H[3] + 38610.0*H[2] + 32175.0*H[1] - 109395.0 + T[4]*(1984.0*H[1]+4032.0) - sgn*T[2]*(4800.0*H[3]+15120.0*H[2]+26400.0*H[1]+34320.0) ) / (262144.0*T[5]); C[6] = 11.0*(218295.0*H[6] + 1071630.0*H[5] + 3009825.0*H[4] + 6142500.0*H[3] + 9398025.0*H[2] + 7936110.0*H[1] - 27776385.0 + T[4]*(254016.0*H[2]+749952.0*H[1]+1100736.0) - sgn*T[2]*(441000.0*H[4] + 1814400.0*H[3] + 4127760.0*H[2] + 6552000.0*H[1] + 8353800.0 + 31232.0*T[4] ) ) / (4194304.0*T[6]); *V0 = C[0] + (-4.0*C[3]/T[1]+C[4])/V[4] + (-192.0*C[5]/T[3]+144.0*C[6]/T[2])/V[8] + sgn * (-C[2]/V[2] + (-24.0*C[4]/T[2]+12.0*C[5]/T[1]-C[6])/V[6] + (-1920.0*C[6]/T[4])/V[10] ); *V1 = C[1]/V[1] + (8.0*(C[3]/T[2]-C[4]/T[1])+C[5])/V[5] + (384.0*C[5]/T[4] - 768.0*C[6]/T[3])/V[9] + sgn * ((2.0*C[2]/T[1]-C[3])/V[3] + (48.0*C[4]/T[3]-72.0*C[5]/T[2] + 18.0*C[6]/T[1])/V[7] + (3840.0*C[6]/T[5])/V[11] ); return GSL_SUCCESS; } /* V0, V1 from Kolbig, m = 1 */ static int conicalP_1_V(const double t, const double f, const double tau, const double sgn, double * V0, double * V1) { double Cm1; double C[8]; double T[8]; double H[8]; double V[12]; int i; T[0] = 1.0; H[0] = 1.0; V[0] = 1.0; for(i=1; i<=7; i++) { T[i] = T[i-1] * t; H[i] = H[i-1] * (t*f); } for(i=1; i<=11; i++) { V[i] = V[i-1] * tau; } Cm1 = -1.0; C[0] = 3.0*(1.0-H[1])/(8.0*T[1]); C[1] = (-15.0*H[2]+6.0*H[1]+9.0+sgn*8.0*T[2])/(128.0*T[2]); C[2] = 3.0*(-35.0*H[3] - 15.0*H[2] + 15.0*H[1] + 35.0 + sgn*T[2]*(32.0*H[1]+8.0))/(1024.0*T[3]); C[3] = (-4725.0*H[4] - 6300.0*H[3] - 3150.0*H[2] + 3780.0*H[1] + 10395.0 -1216.0*T[4] + sgn*T[2]*(6000.0*H[2]+5760.0*H[1]+1680.0)) / (32768.0*T[4]); C[4] = 7.0*(-10395.0*H[5] - 23625.0*H[4] - 28350.0*H[3] - 14850.0*H[2] +19305.0*H[1] + 57915.0 - T[4]*(6336.0*H[1]+6080.0) + sgn*T[2]*(16800.0*H[3] + 30000.0*H[2] + 25920.0*H[1] + 7920.0) ) / (262144.0*T[5]); C[5] = (-2837835.0*H[6] - 9168390.0*H[5] - 16372125.0*H[4] - 18918900*H[3] -10135125.0*H[2] + 13783770.0*H[1] + 43648605.0 -T[4]*(3044160.0*H[2] + 5588352.0*H[1] + 4213440.0) +sgn*T[2]*(5556600.0*H[4] + 14817600.0*H[3] + 20790000.0*H[2] + 17297280.0*H[1] + 5405400.0 + 323072.0*T[4] ) ) / (4194304.0*T[6]); C[6] = 0.0; *V0 = C[0] + (-4.0*C[3]/T[1]+C[4])/V[4] + (-192.0*C[5]/T[3]+144.0*C[6]/T[2])/V[8] + sgn * (-C[2]/V[2] + (-24.0*C[4]/T[2]+12.0*C[5]/T[1]-C[6])/V[6] ); *V1 = C[1]/V[1] + (8.0*(C[3]/T[2]-C[4]/T[1])+C[5])/V[5] + (384.0*C[5]/T[4] - 768.0*C[6]/T[3])/V[9] + sgn * (Cm1*V[1] + (2.0*C[2]/T[1]-C[3])/V[3] + (48.0*C[4]/T[3]-72.0*C[5]/T[2] + 18.0*C[6]/T[1])/V[7] ); return GSL_SUCCESS; } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ /* P^0_{-1/2 + I lambda} */ int gsl_sf_conicalP_0_e(const double lambda, const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= -1.0) { DOMAIN_ERROR(result); } else if(x == 1.0) { result->val = 1.0; result->err = 0.0; return GSL_SUCCESS; } else if(lambda == 0.0) { gsl_sf_result K; int stat_K; if(x < 1.0) { const double th = acos(x); const double s = sin(0.5*th); stat_K = gsl_sf_ellint_Kcomp_e(s, GSL_MODE_DEFAULT, &K); result->val = 2.0/M_PI * K.val; result->err = 2.0/M_PI * K.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_K; } else { const double xi = acosh(x); const double c = cosh(0.5*xi); const double t = tanh(0.5*xi); stat_K = gsl_sf_ellint_Kcomp_e(t, GSL_MODE_DEFAULT, &K); result->val = 2.0/M_PI / c * K.val; result->err = 2.0/M_PI / c * K.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_K; } } else if( (x <= 0.0 && lambda < 1000.0) || (x < 0.1 && lambda < 17.0) || (x < 0.2 && lambda < 5.0 ) ) { return conicalP_xlt1_hyperg_A(0.0, lambda, x, result); } else if( (x <= 0.2 && lambda < 17.0) || (x <= 1.5 && lambda < 20.0) ) { return gsl_sf_hyperg_2F1_conj_e(0.5, lambda, 1.0, (1.0-x)/2, result); } else if(1.5 < x && lambda < GSL_MAX(x,20.0)) { gsl_sf_result P; double lm; int stat_P = gsl_sf_conicalP_large_x_e(0.0, lambda, x, &P, &lm ); int stat_e = gsl_sf_exp_mult_err_e(lm, 2.0*GSL_DBL_EPSILON * fabs(lm), P.val, P.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_P); } else { double V0, V1; if(x < 1.0) { double th = acos(x); double sth = sqrt(1.0-x*x); /* sin(th) */ gsl_sf_result I0, I1; int stat_I0 = gsl_sf_bessel_I0_scaled_e(th * lambda, &I0); int stat_I1 = gsl_sf_bessel_I1_scaled_e(th * lambda, &I1); int stat_I = GSL_ERROR_SELECT_2(stat_I0, stat_I1); int stat_V = conicalP_0_V(th, x/sth, lambda, -1.0, &V0, &V1); double bessterm = V0 * I0.val + V1 * I1.val; double besserr = fabs(V0) * I0.err + fabs(V1) * I1.err; double arg1 = th*lambda; double sqts = sqrt(th/sth); int stat_e = gsl_sf_exp_mult_err_e(arg1, 4.0 * GSL_DBL_EPSILON * fabs(arg1), sqts * bessterm, sqts * besserr, result); return GSL_ERROR_SELECT_3(stat_e, stat_V, stat_I); } else { double sh = sqrt(x-1.0)*sqrt(x+1.0); /* sinh(xi) */ double xi = log(x + sh); /* xi = acosh(x) */ gsl_sf_result J0, J1; int stat_J0 = gsl_sf_bessel_J0_e(xi * lambda, &J0); int stat_J1 = gsl_sf_bessel_J1_e(xi * lambda, &J1); int stat_J = GSL_ERROR_SELECT_2(stat_J0, stat_J1); int stat_V = conicalP_0_V(xi, x/sh, lambda, 1.0, &V0, &V1); double bessterm = V0 * J0.val + V1 * J1.val; double besserr = fabs(V0) * J0.err + fabs(V1) * J1.err; double pre_val = sqrt(xi/sh); double pre_err = 2.0 * fabs(pre_val); result->val = pre_val * bessterm; result->err = pre_val * besserr; result->err += pre_err * fabs(bessterm); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_V, stat_J); } } } /* P^1_{-1/2 + I lambda} */ int gsl_sf_conicalP_1_e(const double lambda, const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= -1.0) { DOMAIN_ERROR(result); } else if(lambda == 0.0) { gsl_sf_result K, E; int stat_K, stat_E; if(x == 1.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(x < 1.0) { if(1.0-x < GSL_SQRT_DBL_EPSILON) { double err_amp = GSL_MAX_DBL(1.0, 1.0/(GSL_DBL_EPSILON + fabs(1.0-x))); result->val = 0.25/M_SQRT2 * sqrt(1.0-x) * (1.0 + 5.0/16.0 * (1.0-x)); result->err = err_amp * 3.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { const double th = acos(x); const double s = sin(0.5*th); const double c2 = 1.0 - s*s; const double sth = sin(th); const double pre = 2.0/(M_PI*sth); stat_K = gsl_sf_ellint_Kcomp_e(s, GSL_MODE_DEFAULT, &K); stat_E = gsl_sf_ellint_Ecomp_e(s, GSL_MODE_DEFAULT, &E); result->val = pre * (E.val - c2 * K.val); result->err = pre * (E.err + fabs(c2) * K.err); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_K; } } else { if(x-1.0 < GSL_SQRT_DBL_EPSILON) { double err_amp = GSL_MAX_DBL(1.0, 1.0/(GSL_DBL_EPSILON + fabs(1.0-x))); result->val = -0.25/M_SQRT2 * sqrt(x-1.0) * (1.0 - 5.0/16.0 * (x-1.0)); result->err = err_amp * 3.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { const double xi = acosh(x); const double c = cosh(0.5*xi); const double t = tanh(0.5*xi); const double sxi = sinh(xi); const double pre = 2.0/(M_PI*sxi) * c; stat_K = gsl_sf_ellint_Kcomp_e(t, GSL_MODE_DEFAULT, &K); stat_E = gsl_sf_ellint_Ecomp_e(t, GSL_MODE_DEFAULT, &E); result->val = pre * (E.val - K.val); result->err = pre * (E.err + K.err); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_K; } } } else if( (x <= 0.0 && lambda < 1000.0) || (x < 0.1 && lambda < 17.0) || (x < 0.2 && lambda < 5.0 ) ) { return conicalP_xlt1_hyperg_A(1.0, lambda, x, result); } else if( (x <= 0.2 && lambda < 17.0) || (x < 1.5 && lambda < 20.0) ) { const double arg = fabs(x*x - 1.0); const double sgn = GSL_SIGN(1.0 - x); const double pre = 0.5*(lambda*lambda + 0.25) * sgn * sqrt(arg); gsl_sf_result F; int stat_F = gsl_sf_hyperg_2F1_conj_e(1.5, lambda, 2.0, (1.0-x)/2, &F); result->val = pre * F.val; result->err = fabs(pre) * F.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_F; } else if(1.5 <= x && lambda < GSL_MAX(x,20.0)) { gsl_sf_result P; double lm; int stat_P = gsl_sf_conicalP_large_x_e(1.0, lambda, x, &P, &lm ); int stat_e = gsl_sf_exp_mult_err_e(lm, 2.0 * GSL_DBL_EPSILON * fabs(lm), P.val, P.err, result); return GSL_ERROR_SELECT_2(stat_e, stat_P); } else { double V0, V1; if(x < 1.0) { const double sqrt_1mx = sqrt(1.0 - x); const double sqrt_1px = sqrt(1.0 + x); const double th = acos(x); const double sth = sqrt_1mx * sqrt_1px; /* sin(th) */ gsl_sf_result I0, I1; int stat_I0 = gsl_sf_bessel_I0_scaled_e(th * lambda, &I0); int stat_I1 = gsl_sf_bessel_I1_scaled_e(th * lambda, &I1); int stat_I = GSL_ERROR_SELECT_2(stat_I0, stat_I1); int stat_V = conicalP_1_V(th, x/sth, lambda, -1.0, &V0, &V1); double bessterm = V0 * I0.val + V1 * I1.val; double besserr = fabs(V0) * I0.err + fabs(V1) * I1.err + 2.0 * GSL_DBL_EPSILON * fabs(V0 * I0.val) + 2.0 * GSL_DBL_EPSILON * fabs(V1 * I1.val); double arg1 = th * lambda; double sqts = sqrt(th/sth); int stat_e = gsl_sf_exp_mult_err_e(arg1, 2.0 * GSL_DBL_EPSILON * fabs(arg1), sqts * bessterm, sqts * besserr, result); result->err *= 1.0/sqrt_1mx; return GSL_ERROR_SELECT_3(stat_e, stat_V, stat_I); } else { const double sqrt_xm1 = sqrt(x - 1.0); const double sqrt_xp1 = sqrt(x + 1.0); const double sh = sqrt_xm1 * sqrt_xp1; /* sinh(xi) */ const double xi = log(x + sh); /* xi = acosh(x) */ const double xi_lam = xi * lambda; gsl_sf_result J0, J1; const int stat_J0 = gsl_sf_bessel_J0_e(xi_lam, &J0); const int stat_J1 = gsl_sf_bessel_J1_e(xi_lam, &J1); const int stat_J = GSL_ERROR_SELECT_2(stat_J0, stat_J1); const int stat_V = conicalP_1_V(xi, x/sh, lambda, 1.0, &V0, &V1); const double bessterm = V0 * J0.val + V1 * J1.val; const double besserr = fabs(V0) * J0.err + fabs(V1) * J1.err + 512.0 * 2.0 * GSL_DBL_EPSILON * fabs(V0 * J0.val) + 512.0 * 2.0 * GSL_DBL_EPSILON * fabs(V1 * J1.val) + GSL_DBL_EPSILON * fabs(xi_lam * V0 * J1.val) + GSL_DBL_EPSILON * fabs(xi_lam * V1 * J0.val); const double pre = sqrt(xi/sh); result->val = pre * bessterm; result->err = pre * besserr * sqrt_xp1 / sqrt_xm1; result->err += 4.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_V, stat_J); } } } /* P^{1/2}_{-1/2 + I lambda} (x) * [Abramowitz+Stegun 8.6.8, 8.6.12] * checked OK [GJ] Fri May 8 12:24:36 MDT 1998 */ int gsl_sf_conicalP_half_e(const double lambda, const double x, gsl_sf_result * result ) { /* CHECK_POINTER(result) */ if(x <= -1.0) { DOMAIN_ERROR(result); } else if(x < 1.0) { double err_amp = 1.0 + 1.0/(GSL_DBL_EPSILON + fabs(1.0-fabs(x))); double ac = acos(x); double den = sqrt(sqrt(1.0-x)*sqrt(1.0+x)); result->val = Root_2OverPi_ / den * cosh(ac * lambda); result->err = err_amp * 3.0 * GSL_DBL_EPSILON * fabs(result->val); result->err *= fabs(ac * lambda) + 1.0; return GSL_SUCCESS; } else if(x == 1.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else { /* x > 1 */ double err_amp = 1.0 + 1.0/(GSL_DBL_EPSILON + fabs(1.0-fabs(x))); double sq_term = sqrt(x-1.0)*sqrt(x+1.0); double ln_term = log(x + sq_term); double den = sqrt(sq_term); double carg_val = lambda * ln_term; double carg_err = 2.0 * GSL_DBL_EPSILON * fabs(carg_val); gsl_sf_result cos_result; int stat_cos = gsl_sf_cos_err_e(carg_val, carg_err, &cos_result); result->val = Root_2OverPi_ / den * cos_result.val; result->err = err_amp * Root_2OverPi_ / den * cos_result.err; result->err += 4.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_cos; } } /* P^{-1/2}_{-1/2 + I lambda} (x) * [Abramowitz+Stegun 8.6.9, 8.6.14] * checked OK [GJ] Fri May 8 12:24:43 MDT 1998 */ int gsl_sf_conicalP_mhalf_e(const double lambda, const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= -1.0) { DOMAIN_ERROR(result); } else if(x < 1.0) { double ac = acos(x); double den = sqrt(sqrt(1.0-x)*sqrt(1.0+x)); double arg = ac * lambda; double err_amp = 1.0 + 1.0/(GSL_DBL_EPSILON + fabs(1.0-fabs(x))); if(fabs(arg) < GSL_SQRT_DBL_EPSILON) { result->val = Root_2OverPi_ / den * ac; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); result->err *= err_amp; } else { result->val = Root_2OverPi_ / (den*lambda) * sinh(arg); result->err = GSL_DBL_EPSILON * (fabs(arg)+1.0) * fabs(result->val); result->err *= err_amp; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); } return GSL_SUCCESS; } else if(x == 1.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else { /* x > 1 */ double sq_term = sqrt(x-1.0)*sqrt(x+1.0); double ln_term = log(x + sq_term); double den = sqrt(sq_term); double arg_val = lambda * ln_term; double arg_err = 2.0 * GSL_DBL_EPSILON * fabs(arg_val); if(arg_val < GSL_SQRT_DBL_EPSILON) { result->val = Root_2OverPi_ / den * ln_term; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { gsl_sf_result sin_result; int stat_sin = gsl_sf_sin_err_e(arg_val, arg_err, &sin_result); result->val = Root_2OverPi_ / (den*lambda) * sin_result.val; result->err = Root_2OverPi_ / fabs(den*lambda) * sin_result.err; result->err += 3.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_sin; } } } int gsl_sf_conicalP_sph_reg_e(const int l, const double lambda, const double x, gsl_sf_result * result ) { /* CHECK_POINTER(result) */ if(x <= -1.0 || l < -1) { DOMAIN_ERROR(result); } else if(l == -1) { return gsl_sf_conicalP_half_e(lambda, x, result); } else if(l == 0) { return gsl_sf_conicalP_mhalf_e(lambda, x, result); } else if(x == 1.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(x < 0.0) { double c = 1.0/sqrt(1.0-x*x); gsl_sf_result r_Pellm1; gsl_sf_result r_Pell; int stat_0 = gsl_sf_conicalP_half_e(lambda, x, &r_Pellm1); /* P^( 1/2) */ int stat_1 = gsl_sf_conicalP_mhalf_e(lambda, x, &r_Pell); /* P^(-1/2) */ int stat_P = GSL_ERROR_SELECT_2(stat_0, stat_1); double Pellm1 = r_Pellm1.val; double Pell = r_Pell.val; double Pellp1; int ell; for(ell=0; ellval = Pell; result->err = (0.5*l + 1.0) * GSL_DBL_EPSILON * fabs(Pell); result->err += GSL_DBL_EPSILON * l * fabs(result->val); return stat_P; } else if(x < 1.0) { const double xi = x/(sqrt(1.0-x)*sqrt(1.0+x)); gsl_sf_result rat; gsl_sf_result Phf; int stat_CF1 = conicalP_negmu_xlt1_CF1(0.5, l, lambda, x, &rat); int stat_Phf = gsl_sf_conicalP_half_e(lambda, x, &Phf); double Pellp1 = rat.val * GSL_SQRT_DBL_MIN; double Pell = GSL_SQRT_DBL_MIN; double Pellm1; int ell; for(ell=l; ell>=0; ell--) { double d = (ell+1.0)*(ell+1.0) + lambda*lambda; Pellm1 = (2.0*ell+1.0)*xi * Pell + d * Pellp1; Pellp1 = Pell; Pell = Pellm1; } result->val = GSL_SQRT_DBL_MIN * Phf.val / Pell; result->err = GSL_SQRT_DBL_MIN * Phf.err / fabs(Pell); result->err += fabs(rat.err/rat.val) * (l + 1.0) * fabs(result->val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_Phf, stat_CF1); } else if(x == 1.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else { /* x > 1.0 */ const double xi = x/sqrt((x-1.0)*(x+1.0)); gsl_sf_result rat; int stat_CF1 = conicalP_negmu_xgt1_CF1(0.5, l, lambda, x, &rat); int stat_P; double Pellp1 = rat.val * GSL_SQRT_DBL_MIN; double Pell = GSL_SQRT_DBL_MIN; double Pellm1; int ell; for(ell=l; ell>=0; ell--) { double d = (ell+1.0)*(ell+1.0) + lambda*lambda; Pellm1 = (2.0*ell+1.0)*xi * Pell - d * Pellp1; Pellp1 = Pell; Pell = Pellm1; } if(fabs(Pell) > fabs(Pellp1)){ gsl_sf_result Phf; stat_P = gsl_sf_conicalP_half_e(lambda, x, &Phf); result->val = GSL_SQRT_DBL_MIN * Phf.val / Pell; result->err = 2.0 * GSL_SQRT_DBL_MIN * Phf.err / fabs(Pell); result->err += 2.0 * fabs(rat.err/rat.val) * (l + 1.0) * fabs(result->val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); } else { gsl_sf_result Pmhf; stat_P = gsl_sf_conicalP_mhalf_e(lambda, x, &Pmhf); result->val = GSL_SQRT_DBL_MIN * Pmhf.val / Pellp1; result->err = 2.0 * GSL_SQRT_DBL_MIN * Pmhf.err / fabs(Pellp1); result->err += 2.0 * fabs(rat.err/rat.val) * (l + 1.0) * fabs(result->val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); } return GSL_ERROR_SELECT_2(stat_P, stat_CF1); } } int gsl_sf_conicalP_cyl_reg_e(const int m, const double lambda, const double x, gsl_sf_result * result ) { /* CHECK_POINTER(result) */ if(x <= -1.0 || m < -1) { DOMAIN_ERROR(result); } else if(m == -1) { return gsl_sf_conicalP_1_e(lambda, x, result); } else if(m == 0) { return gsl_sf_conicalP_0_e(lambda, x, result); } else if(x == 1.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(x < 0.0) { double c = 1.0/sqrt(1.0-x*x); gsl_sf_result r_Pkm1; gsl_sf_result r_Pk; int stat_0 = gsl_sf_conicalP_1_e(lambda, x, &r_Pkm1); /* P^1 */ int stat_1 = gsl_sf_conicalP_0_e(lambda, x, &r_Pk); /* P^0 */ int stat_P = GSL_ERROR_SELECT_2(stat_0, stat_1); double Pkm1 = r_Pkm1.val; double Pk = r_Pk.val; double Pkp1; int k; for(k=0; kval = Pk; result->err = (m + 2.0) * GSL_DBL_EPSILON * fabs(Pk); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_P; } else if(x < 1.0) { const double xi = x/(sqrt(1.0-x)*sqrt(1.0+x)); gsl_sf_result rat; gsl_sf_result P0; int stat_CF1 = conicalP_negmu_xlt1_CF1(0.0, m, lambda, x, &rat); int stat_P0 = gsl_sf_conicalP_0_e(lambda, x, &P0); double Pkp1 = rat.val * GSL_SQRT_DBL_MIN; double Pk = GSL_SQRT_DBL_MIN; double Pkm1; int k; for(k=m; k>0; k--) { double d = (k+0.5)*(k+0.5) + lambda*lambda; Pkm1 = 2.0*k*xi * Pk + d * Pkp1; Pkp1 = Pk; Pk = Pkm1; } result->val = GSL_SQRT_DBL_MIN * P0.val / Pk; result->err = 2.0 * GSL_SQRT_DBL_MIN * P0.err / fabs(Pk); result->err += 2.0 * fabs(rat.err/rat.val) * (m + 1.0) * fabs(result->val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_P0, stat_CF1); } else if(x == 1.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else { /* x > 1.0 */ const double xi = x/sqrt((x-1.0)*(x+1.0)); gsl_sf_result rat; int stat_CF1 = conicalP_negmu_xgt1_CF1(0.0, m, lambda, x, &rat); int stat_P; double Pkp1 = rat.val * GSL_SQRT_DBL_MIN; double Pk = GSL_SQRT_DBL_MIN; double Pkm1; int k; for(k=m; k>-1; k--) { double d = (k+0.5)*(k+0.5) + lambda*lambda; Pkm1 = 2.0*k*xi * Pk - d * Pkp1; Pkp1 = Pk; Pk = Pkm1; } if(fabs(Pk) > fabs(Pkp1)){ gsl_sf_result P1; stat_P = gsl_sf_conicalP_1_e(lambda, x, &P1); result->val = GSL_SQRT_DBL_MIN * P1.val / Pk; result->err = 2.0 * GSL_SQRT_DBL_MIN * P1.err / fabs(Pk); result->err += 2.0 * fabs(rat.err/rat.val) * (m+2.0) * fabs(result->val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); } else { gsl_sf_result P0; stat_P = gsl_sf_conicalP_0_e(lambda, x, &P0); result->val = GSL_SQRT_DBL_MIN * P0.val / Pkp1; result->err = 2.0 * GSL_SQRT_DBL_MIN * P0.err / fabs(Pkp1); result->err += 2.0 * fabs(rat.err/rat.val) * (m+2.0) * fabs(result->val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); } return GSL_ERROR_SELECT_2(stat_P, stat_CF1); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_conicalP_0(const double lambda, const double x) { EVAL_RESULT(gsl_sf_conicalP_0_e(lambda, x, &result)); } double gsl_sf_conicalP_1(const double lambda, const double x) { EVAL_RESULT(gsl_sf_conicalP_1_e(lambda, x, &result)); } double gsl_sf_conicalP_half(const double lambda, const double x) { EVAL_RESULT(gsl_sf_conicalP_half_e(lambda, x, &result)); } double gsl_sf_conicalP_mhalf(const double lambda, const double x) { EVAL_RESULT(gsl_sf_conicalP_mhalf_e(lambda, x, &result)); } double gsl_sf_conicalP_sph_reg(const int l, const double lambda, const double x) { EVAL_RESULT(gsl_sf_conicalP_sph_reg_e(l, lambda, x, &result)); } double gsl_sf_conicalP_cyl_reg(const int m, const double lambda, const double x) { EVAL_RESULT(gsl_sf_conicalP_cyl_reg_e(m, lambda, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__legendre_poly.c000066400000000000000000000511751261542461700232260ustar00rootroot00000000000000/* specfunc/legendre_poly.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_bessel.h" #include "gsl_sf_exp.h" #include "gsl_sf_gamma.h" #include "gsl_sf_log.h" #include "gsl_sf_pow_int.h" #include "gsl_sf_legendre.h" #include "gsl_specfunc__error.h" /* Calculate P_m^m(x) from the analytic result: * P_m^m(x) = (-1)^m (2m-1)!! (1-x^2)^(m/2) , m > 0 * = 1 , m = 0 */ static double legendre_Pmm(int m, double x) { if(m == 0) { return 1.0; } else { double p_mm = 1.0; double root_factor = sqrt(1.0-x)*sqrt(1.0+x); double fact_coeff = 1.0; int i; for(i=1; i<=m; i++) { p_mm *= -fact_coeff * root_factor; fact_coeff += 2.0; } return p_mm; } } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_legendre_P1_e(double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ { result->val = x; result->err = 0.0; return GSL_SUCCESS; } } int gsl_sf_legendre_P2_e(double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ { result->val = 0.5*(3.0*x*x - 1.0); result->err = GSL_DBL_EPSILON * (fabs(3.0*x*x) + 1.0); return GSL_SUCCESS; } } int gsl_sf_legendre_P3_e(double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ { result->val = 0.5*x*(5.0*x*x - 3.0); result->err = GSL_DBL_EPSILON * (fabs(result->val) + 0.5 * fabs(x) * (fabs(5.0*x*x) + 3.0)); return GSL_SUCCESS; } } int gsl_sf_legendre_Pl_e(const int l, const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(l < 0 || x < -1.0 || x > 1.0) { DOMAIN_ERROR(result); } else if(l == 0) { result->val = 1.0; result->err = 0.0; return GSL_SUCCESS; } else if(l == 1) { result->val = x; result->err = 0.0; return GSL_SUCCESS; } else if(l == 2) { result->val = 0.5 * (3.0*x*x - 1.0); result->err = GSL_DBL_EPSILON * (fabs(3.0*x*x) + 1.0); /*result->err = 3.0 * GSL_DBL_EPSILON * fabs(result->val); removed this old bogus estimate [GJ] */ return GSL_SUCCESS; } else if(x == 1.0) { result->val = 1.0; result->err = 0.0; return GSL_SUCCESS; } else if(x == -1.0) { result->val = ( GSL_IS_ODD(l) ? -1.0 : 1.0 ); result->err = 0.0; return GSL_SUCCESS; } else if(l < 100000) { /* upward recurrence: l P_l = (2l-1) z P_{l-1} - (l-1) P_{l-2} */ double p_ellm2 = 1.0; /* P_0(x) */ double p_ellm1 = x; /* P_1(x) */ double p_ell = p_ellm1; double e_ellm2 = GSL_DBL_EPSILON; double e_ellm1 = fabs(x)*GSL_DBL_EPSILON; double e_ell = e_ellm1; int ell; for(ell=2; ell <= l; ell++){ p_ell = (x*(2*ell-1)*p_ellm1 - (ell-1)*p_ellm2) / ell; p_ellm2 = p_ellm1; p_ellm1 = p_ell; e_ell = 0.5*(fabs(x)*(2*ell-1.0) * e_ellm1 + (ell-1.0)*e_ellm2)/ell; e_ellm2 = e_ellm1; e_ellm1 = e_ell; } result->val = p_ell; result->err = e_ell + l*fabs(p_ell)*GSL_DBL_EPSILON; return GSL_SUCCESS; } else { /* Asymptotic expansion. * [Olver, p. 473] */ double u = l + 0.5; double th = acos(x); gsl_sf_result J0; gsl_sf_result Jm1; int stat_J0 = gsl_sf_bessel_J0_e(u*th, &J0); int stat_Jm1 = gsl_sf_bessel_Jn_e(-1, u*th, &Jm1); double pre; double B00; double c1; /* B00 = 1/8 (1 - th cot(th) / th^2 * pre = sqrt(th/sin(th)) */ if(th < GSL_ROOT4_DBL_EPSILON) { B00 = (1.0 + th*th/15.0)/24.0; pre = 1.0 + th*th/12.0; } else { double sin_th = sqrt(1.0 - x*x); double cot_th = x / sin_th; B00 = 1.0/8.0 * (1.0 - th * cot_th) / (th*th); pre = sqrt(th/sin_th); } c1 = th/u * B00; result->val = pre * (J0.val + c1 * Jm1.val); result->err = pre * (J0.err + fabs(c1) * Jm1.err); result->err += GSL_SQRT_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_J0, stat_Jm1); } } int gsl_sf_legendre_Pl_array(const int lmax, const double x, double * result_array) { /* CHECK_POINTER(result_array) */ if(lmax < 0 || x < -1.0 || x > 1.0) { GSL_ERROR ("domain error", GSL_EDOM); } else if(lmax == 0) { result_array[0] = 1.0; return GSL_SUCCESS; } else if(lmax == 1) { result_array[0] = 1.0; result_array[1] = x; return GSL_SUCCESS; } else { /* upward recurrence: l P_l = (2l-1) z P_{l-1} - (l-1) P_{l-2} */ double p_ellm2 = 1.0; /* P_0(x) */ double p_ellm1 = x; /* P_1(x) */ double p_ell = p_ellm1; int ell; result_array[0] = 1.0; result_array[1] = x; for(ell=2; ell <= lmax; ell++){ p_ell = (x*(2*ell-1)*p_ellm1 - (ell-1)*p_ellm2) / ell; p_ellm2 = p_ellm1; p_ellm1 = p_ell; result_array[ell] = p_ell; } return GSL_SUCCESS; } } int gsl_sf_legendre_Pl_deriv_array(const int lmax, const double x, double * result_array, double * result_deriv_array) { int stat_array = gsl_sf_legendre_Pl_array(lmax, x, result_array); if(lmax >= 0) result_deriv_array[0] = 0.0; if(lmax >= 1) result_deriv_array[1] = 1.0; if(stat_array == GSL_SUCCESS) { int ell; if(fabs(x - 1.0)*(lmax+1.0)*(lmax+1.0) < GSL_SQRT_DBL_EPSILON) { /* x is near 1 */ for(ell = 2; ell <= lmax; ell++) { const double pre = 0.5 * ell * (ell+1.0); result_deriv_array[ell] = pre * (1.0 - 0.25 * (1.0-x) * (ell+2.0)*(ell-1.0)); } } else if(fabs(x + 1.0)*(lmax+1.0)*(lmax+1.0) < GSL_SQRT_DBL_EPSILON) { /* x is near -1 */ for(ell = 2; ell <= lmax; ell++) { const double sgn = ( GSL_IS_ODD(ell) ? 1.0 : -1.0 ); /* derivative is odd in x for even ell */ const double pre = sgn * 0.5 * ell * (ell+1.0); result_deriv_array[ell] = pre * (1.0 - 0.25 * (1.0+x) * (ell+2.0)*(ell-1.0)); } } else { const double diff_a = 1.0 + x; const double diff_b = 1.0 - x; for(ell = 2; ell <= lmax; ell++) { result_deriv_array[ell] = - ell * (x * result_array[ell] - result_array[ell-1]) / (diff_a * diff_b); } } return GSL_SUCCESS; } else { return stat_array; } } int gsl_sf_legendre_Plm_e(const int l, const int m, const double x, gsl_sf_result * result) { /* If l is large and m is large, then we have to worry * about overflow. Calculate an approximate exponent which * measures the normalization of this thing. */ const double dif = l-m; const double sum = l+m; const double t_d = ( dif == 0.0 ? 0.0 : 0.5 * dif * (log(dif)-1.0) ); const double t_s = ( dif == 0.0 ? 0.0 : 0.5 * sum * (log(sum)-1.0) ); const double exp_check = 0.5 * log(2.0*l+1.0) + t_d - t_s; /* CHECK_POINTER(result) */ if(m < 0 || l < m || x < -1.0 || x > 1.0) { DOMAIN_ERROR(result); } else if(exp_check < GSL_LOG_DBL_MIN + 10.0){ /* Bail out. */ OVERFLOW_ERROR(result); } else { /* Account for the error due to the * representation of 1-x. */ const double err_amp = 1.0 / (GSL_DBL_EPSILON + fabs(1.0-fabs(x))); /* P_m^m(x) and P_{m+1}^m(x) */ double p_mm = legendre_Pmm(m, x); double p_mmp1 = x * (2*m + 1) * p_mm; if(l == m){ result->val = p_mm; result->err = err_amp * 2.0 * GSL_DBL_EPSILON * fabs(p_mm); return GSL_SUCCESS; } else if(l == m + 1) { result->val = p_mmp1; result->err = err_amp * 2.0 * GSL_DBL_EPSILON * fabs(p_mmp1); return GSL_SUCCESS; } else{ /* upward recurrence: (l-m) P(l,m) = (2l-1) z P(l-1,m) - (l+m-1) P(l-2,m) * start at P(m,m), P(m+1,m) */ double p_ellm2 = p_mm; double p_ellm1 = p_mmp1; double p_ell = 0.0; int ell; for(ell=m+2; ell <= l; ell++){ p_ell = (x*(2*ell-1)*p_ellm1 - (ell+m-1)*p_ellm2) / (ell-m); p_ellm2 = p_ellm1; p_ellm1 = p_ell; } result->val = p_ell; result->err = err_amp * (0.5*(l-m) + 1.0) * GSL_DBL_EPSILON * fabs(p_ell); return GSL_SUCCESS; } } } int gsl_sf_legendre_Plm_array(const int lmax, const int m, const double x, double * result_array) { /* If l is large and m is large, then we have to worry * about overflow. Calculate an approximate exponent which * measures the normalization of this thing. */ const double dif = lmax-m; const double sum = lmax+m; const double t_d = ( dif == 0.0 ? 0.0 : 0.5 * dif * (log(dif)-1.0) ); const double t_s = ( dif == 0.0 ? 0.0 : 0.5 * sum * (log(sum)-1.0) ); const double exp_check = 0.5 * log(2.0*lmax+1.0) + t_d - t_s; /* CHECK_POINTER(result_array) */ if(m < 0 || lmax < m || x < -1.0 || x > 1.0) { GSL_ERROR ("domain error", GSL_EDOM); } else if(m > 0 && (x == 1.0 || x == -1.0)) { int ell; for(ell=m; ell<=lmax; ell++) result_array[ell-m] = 0.0; return GSL_SUCCESS; } else if(exp_check < GSL_LOG_DBL_MIN + 10.0){ /* Bail out. */ GSL_ERROR ("overflow", GSL_EOVRFLW); } else { double p_mm = legendre_Pmm(m, x); double p_mmp1 = x * (2.0*m + 1.0) * p_mm; if(lmax == m){ result_array[0] = p_mm; return GSL_SUCCESS; } else if(lmax == m + 1) { result_array[0] = p_mm; result_array[1] = p_mmp1; return GSL_SUCCESS; } else { double p_ellm2 = p_mm; double p_ellm1 = p_mmp1; double p_ell = 0.0; int ell; result_array[0] = p_mm; result_array[1] = p_mmp1; for(ell=m+2; ell <= lmax; ell++){ p_ell = (x*(2.0*ell-1.0)*p_ellm1 - (ell+m-1)*p_ellm2) / (ell-m); p_ellm2 = p_ellm1; p_ellm1 = p_ell; result_array[ell-m] = p_ell; } return GSL_SUCCESS; } } } int gsl_sf_legendre_Plm_deriv_array( const int lmax, const int m, const double x, double * result_array, double * result_deriv_array) { if(m < 0 || m > lmax) { GSL_ERROR("m < 0 or m > lmax", GSL_EDOM); } else if(m == 0) { /* It is better to do m=0 this way, so we can more easily * trap the divergent case which can occur when m == 1. */ return gsl_sf_legendre_Pl_deriv_array(lmax, x, result_array, result_deriv_array); } else { int stat_array = gsl_sf_legendre_Plm_array(lmax, m, x, result_array); if(stat_array == GSL_SUCCESS) { int ell; if(m == 1 && (1.0 - fabs(x) < GSL_DBL_EPSILON)) { /* This divergence is real and comes from the cusp-like * behaviour for m = 1. For example, P[1,1] = - Sqrt[1-x^2]. */ GSL_ERROR("divergence near |x| = 1.0 since m = 1", GSL_EOVRFLW); } else if(m == 2 && (1.0 - fabs(x) < GSL_DBL_EPSILON)) { /* m = 2 gives a finite nonzero result for |x| near 1 */ if(fabs(x - 1.0) < GSL_DBL_EPSILON) { for(ell = m; ell <= lmax; ell++) result_deriv_array[ell-m] = -0.25 * x * (ell - 1.0)*ell*(ell+1.0)*(ell+2.0); } else if(fabs(x + 1.0) < GSL_DBL_EPSILON) { for(ell = m; ell <= lmax; ell++) { const double sgn = ( GSL_IS_ODD(ell) ? 1.0 : -1.0 ); result_deriv_array[ell-m] = -0.25 * sgn * x * (ell - 1.0)*ell*(ell+1.0)*(ell+2.0); } } return GSL_SUCCESS; } else { /* m > 2 is easier to deal with since the endpoints always vanish */ if(1.0 - fabs(x) < GSL_DBL_EPSILON) { for(ell = m; ell <= lmax; ell++) result_deriv_array[ell-m] = 0.0; return GSL_SUCCESS; } else { const double diff_a = 1.0 + x; const double diff_b = 1.0 - x; result_deriv_array[0] = - m * x / (diff_a * diff_b) * result_array[0]; if(lmax-m >= 1) result_deriv_array[1] = (2.0 * m + 1.0) * (x * result_deriv_array[0] + result_array[0]); for(ell = m+2; ell <= lmax; ell++) { result_deriv_array[ell-m] = - (ell * x * result_array[ell-m] - (ell+m) * result_array[ell-1-m]) / (diff_a * diff_b); } return GSL_SUCCESS; } } } else { return stat_array; } } } int gsl_sf_legendre_sphPlm_e(const int l, int m, const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(m < 0 || l < m || x < -1.0 || x > 1.0) { DOMAIN_ERROR(result); } else if(m == 0) { gsl_sf_result P; int stat_P = gsl_sf_legendre_Pl_e(l, x, &P); double pre = sqrt((2.0*l + 1.0)/(4.0*M_PI)); result->val = pre * P.val; result->err = pre * P.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_P; } else if(x == 1.0 || x == -1.0) { /* m > 0 here */ result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else { /* m > 0 and |x| < 1 here */ /* Starting value for recursion. * Y_m^m(x) = sqrt( (2m+1)/(4pi m) gamma(m+1/2)/gamma(m) ) (-1)^m (1-x^2)^(m/2) / pi^(1/4) */ gsl_sf_result lncirc; gsl_sf_result lnpoch; double lnpre_val; double lnpre_err; gsl_sf_result ex_pre; double sr; const double sgn = ( GSL_IS_ODD(m) ? -1.0 : 1.0); const double y_mmp1_factor = x * sqrt(2.0*m + 3.0); double y_mm, y_mm_err; double y_mmp1, y_mmp1_err; gsl_sf_log_1plusx_e(-x*x, &lncirc); gsl_sf_lnpoch_e(m, 0.5, &lnpoch); /* Gamma(m+1/2)/Gamma(m) */ lnpre_val = -0.25*M_LNPI + 0.5 * (lnpoch.val + m*lncirc.val); lnpre_err = 0.25*M_LNPI*GSL_DBL_EPSILON + 0.5 * (lnpoch.err + fabs(m)*lncirc.err); /* Compute exp(ln_pre) with error term, avoiding call to gsl_sf_exp_err BJG */ ex_pre.val = exp(lnpre_val); ex_pre.err = 2.0*(sinh(lnpre_err) + GSL_DBL_EPSILON)*ex_pre.val; sr = sqrt((2.0+1.0/m)/(4.0*M_PI)); y_mm = sgn * sr * ex_pre.val; y_mm_err = 2.0 * GSL_DBL_EPSILON * fabs(y_mm) + sr * ex_pre.err; y_mm_err *= 1.0 + 1.0/(GSL_DBL_EPSILON + fabs(1.0-x)); y_mmp1 = y_mmp1_factor * y_mm; y_mmp1_err=fabs(y_mmp1_factor) * y_mm_err; if(l == m){ result->val = y_mm; result->err = y_mm_err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(y_mm); return GSL_SUCCESS; } else if(l == m + 1) { result->val = y_mmp1; result->err = y_mmp1_err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(y_mmp1); return GSL_SUCCESS; } else{ double y_ell = 0.0; double y_ell_err; int ell; /* Compute Y_l^m, l > m+1, upward recursion on l. */ for(ell=m+2; ell <= l; ell++){ const double rat1 = (double)(ell-m)/(double)(ell+m); const double rat2 = (ell-m-1.0)/(ell+m-1.0); const double factor1 = sqrt(rat1*(2.0*ell+1.0)*(2.0*ell-1.0)); const double factor2 = sqrt(rat1*rat2*(2.0*ell+1.0)/(2.0*ell-3.0)); y_ell = (x*y_mmp1*factor1 - (ell+m-1.0)*y_mm*factor2) / (ell-m); y_mm = y_mmp1; y_mmp1 = y_ell; y_ell_err = 0.5*(fabs(x*factor1)*y_mmp1_err + fabs((ell+m-1.0)*factor2)*y_mm_err) / fabs(ell-m); y_mm_err = y_mmp1_err; y_mmp1_err = y_ell_err; } result->val = y_ell; result->err = y_ell_err + (0.5*(l-m) + 1.0) * GSL_DBL_EPSILON * fabs(y_ell); return GSL_SUCCESS; } } } int gsl_sf_legendre_sphPlm_array(const int lmax, int m, const double x, double * result_array) { /* CHECK_POINTER(result_array) */ if(m < 0 || lmax < m || x < -1.0 || x > 1.0) { GSL_ERROR ("error", GSL_EDOM); } else if(m > 0 && (x == 1.0 || x == -1.0)) { int ell; for(ell=m; ell<=lmax; ell++) result_array[ell-m] = 0.0; return GSL_SUCCESS; } else { double y_mm; double y_mmp1; if(m == 0) { y_mm = 0.5/M_SQRTPI; /* Y00 = 1/sqrt(4pi) */ y_mmp1 = x * M_SQRT3 * y_mm; } else { /* |x| < 1 here */ gsl_sf_result lncirc; gsl_sf_result lnpoch; double lnpre; const double sgn = ( GSL_IS_ODD(m) ? -1.0 : 1.0); gsl_sf_log_1plusx_e(-x*x, &lncirc); gsl_sf_lnpoch_e(m, 0.5, &lnpoch); /* Gamma(m+1/2)/Gamma(m) */ lnpre = -0.25*M_LNPI + 0.5 * (lnpoch.val + m*lncirc.val); y_mm = sqrt((2.0+1.0/m)/(4.0*M_PI)) * sgn * exp(lnpre); y_mmp1 = x * sqrt(2.0*m + 3.0) * y_mm; } if(lmax == m){ result_array[0] = y_mm; return GSL_SUCCESS; } else if(lmax == m + 1) { result_array[0] = y_mm; result_array[1] = y_mmp1; return GSL_SUCCESS; } else{ double y_ell; int ell; result_array[0] = y_mm; result_array[1] = y_mmp1; /* Compute Y_l^m, l > m+1, upward recursion on l. */ for(ell=m+2; ell <= lmax; ell++){ const double rat1 = (double)(ell-m)/(double)(ell+m); const double rat2 = (ell-m-1.0)/(ell+m-1.0); const double factor1 = sqrt(rat1*(2*ell+1)*(2*ell-1)); const double factor2 = sqrt(rat1*rat2*(2*ell+1)/(2*ell-3)); y_ell = (x*y_mmp1*factor1 - (ell+m-1)*y_mm*factor2) / (ell-m); y_mm = y_mmp1; y_mmp1 = y_ell; result_array[ell-m] = y_ell; } } return GSL_SUCCESS; } } int gsl_sf_legendre_sphPlm_deriv_array( const int lmax, const int m, const double x, double * result_array, double * result_deriv_array) { if(m < 0 || lmax < m || x < -1.0 || x > 1.0) { GSL_ERROR ("domain", GSL_EDOM); } else if(m == 0) { /* m = 0 is easy to trap */ const int stat_array = gsl_sf_legendre_Pl_deriv_array(lmax, x, result_array, result_deriv_array); int ell; for(ell = 0; ell <= lmax; ell++) { const double prefactor = sqrt((2.0 * ell + 1.0)/(4.0*M_PI)); result_array[ell] *= prefactor; result_deriv_array[ell] *= prefactor; } return stat_array; } else if(m == 1) { /* Trapping m = 1 is necessary because of the possible divergence. * Recall that this divergence is handled properly in ..._Plm_deriv_array(), * and the scaling factor is not large for small m, so we just scale. */ const int stat_array = gsl_sf_legendre_Plm_deriv_array(lmax, m, x, result_array, result_deriv_array); int ell; for(ell = 1; ell <= lmax; ell++) { const double prefactor = sqrt((2.0 * ell + 1.0)/(ell + 1.0) / (4.0*M_PI*ell)); result_array[ell-1] *= prefactor; result_deriv_array[ell-1] *= prefactor; } return stat_array; } else { /* as for the derivative of P_lm, everything is regular for m >= 2 */ int stat_array = gsl_sf_legendre_sphPlm_array(lmax, m, x, result_array); if(stat_array == GSL_SUCCESS) { int ell; if(1.0 - fabs(x) < GSL_DBL_EPSILON) { for(ell = m; ell <= lmax; ell++) result_deriv_array[ell-m] = 0.0; return GSL_SUCCESS; } else { const double diff_a = 1.0 + x; const double diff_b = 1.0 - x; result_deriv_array[0] = - m * x / (diff_a * diff_b) * result_array[0]; if(lmax-m >= 1) result_deriv_array[1] = sqrt(2.0 * m + 3.0) * (x * result_deriv_array[0] + result_array[0]); for(ell = m+2; ell <= lmax; ell++) { const double c1 = sqrt(((2.0*ell+1.0)/(2.0*ell-1.0)) * ((double)(ell-m)/(double)(ell+m))); result_deriv_array[ell-m] = - (ell * x * result_array[ell-m] - c1 * (ell+m) * result_array[ell-1-m]) / (diff_a * diff_b); } return GSL_SUCCESS; } } else { return stat_array; } } } #ifndef HIDE_INLINE_STATIC int gsl_sf_legendre_array_size(const int lmax, const int m) { return lmax-m+1; } #endif /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_legendre_P1(const double x) { EVAL_RESULT(gsl_sf_legendre_P1_e(x, &result)); } double gsl_sf_legendre_P2(const double x) { EVAL_RESULT(gsl_sf_legendre_P2_e(x, &result)); } double gsl_sf_legendre_P3(const double x) { EVAL_RESULT(gsl_sf_legendre_P3_e(x, &result)); } double gsl_sf_legendre_Pl(const int l, const double x) { EVAL_RESULT(gsl_sf_legendre_Pl_e(l, x, &result)); } double gsl_sf_legendre_Plm(const int l, const int m, const double x) { EVAL_RESULT(gsl_sf_legendre_Plm_e(l, m, x, &result)); } double gsl_sf_legendre_sphPlm(const int l, const int m, const double x) { EVAL_RESULT(gsl_sf_legendre_sphPlm_e(l, m, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__log.c000066400000000000000000000154311261542461700211520ustar00rootroot00000000000000/* specfunc/log.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_log.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__chebyshev.h" #include "gsl_specfunc__cheb_eval.c" /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/ /* Chebyshev expansion for log(1 + x(t))/x(t) * * x(t) = (4t-1)/(2(4-t)) * t(x) = (8x+1)/(2(x+2)) * -1/2 < x < 1/2 * -1 < t < 1 */ static double lopx_data[21] = { 2.16647910664395270521272590407, -0.28565398551049742084877469679, 0.01517767255690553732382488171, -0.00200215904941415466274422081, 0.00019211375164056698287947962, -0.00002553258886105542567601400, 2.9004512660400621301999384544e-06, -3.8873813517057343800270917900e-07, 4.7743678729400456026672697926e-08, -6.4501969776090319441714445454e-09, 8.2751976628812389601561347296e-10, -1.1260499376492049411710290413e-10, 1.4844576692270934446023686322e-11, -2.0328515972462118942821556033e-12, 2.7291231220549214896095654769e-13, -3.7581977830387938294437434651e-14, 5.1107345870861673561462339876e-15, -7.0722150011433276578323272272e-16, 9.7089758328248469219003866867e-17, -1.3492637457521938883731579510e-17, 1.8657327910677296608121390705e-18 }; static cheb_series lopx_cs = { lopx_data, 20, -1, 1, 10 }; /* Chebyshev expansion for (log(1 + x(t)) - x(t))/x(t)^2 * * x(t) = (4t-1)/(2(4-t)) * t(x) = (8x+1)/(2(x+2)) * -1/2 < x < 1/2 * -1 < t < 1 */ static double lopxmx_data[20] = { -1.12100231323744103373737274541, 0.19553462773379386241549597019, -0.01467470453808083971825344956, 0.00166678250474365477643629067, -0.00018543356147700369785746902, 0.00002280154021771635036301071, -2.8031253116633521699214134172e-06, 3.5936568872522162983669541401e-07, -4.6241857041062060284381167925e-08, 6.0822637459403991012451054971e-09, -8.0339824424815790302621320732e-10, 1.0751718277499375044851551587e-10, -1.4445310914224613448759230882e-11, 1.9573912180610336168921438426e-12, -2.6614436796793061741564104510e-13, 3.6402634315269586532158344584e-14, -4.9937495922755006545809120531e-15, 6.8802890218846809524646902703e-16, -9.5034129794804273611403251480e-17, 1.3170135013050997157326965813e-17 }; static cheb_series lopxmx_cs = { lopxmx_data, 19, -1, 1, 9 }; /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_log_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= 0.0) { DOMAIN_ERROR(result); } else { result->val = log(x); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_log_abs_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x == 0.0) { DOMAIN_ERROR(result); } else { result->val = log(fabs(x)); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_complex_log_e(const double zr, const double zi, gsl_sf_result * lnr, gsl_sf_result * theta) { /* CHECK_POINTER(lnr) */ /* CHECK_POINTER(theta) */ if(zr != 0.0 || zi != 0.0) { const double ax = fabs(zr); const double ay = fabs(zi); const double min = GSL_MIN(ax, ay); const double max = GSL_MAX(ax, ay); lnr->val = log(max) + 0.5 * log(1.0 + (min/max)*(min/max)); lnr->err = 2.0 * GSL_DBL_EPSILON * fabs(lnr->val); theta->val = atan2(zi, zr); theta->err = GSL_DBL_EPSILON * fabs(lnr->val); return GSL_SUCCESS; } else { DOMAIN_ERROR_2(lnr, theta); } } int gsl_sf_log_1plusx_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= -1.0) { DOMAIN_ERROR(result); } else if(fabs(x) < GSL_ROOT6_DBL_EPSILON) { const double c1 = -0.5; const double c2 = 1.0/3.0; const double c3 = -1.0/4.0; const double c4 = 1.0/5.0; const double c5 = -1.0/6.0; const double c6 = 1.0/7.0; const double c7 = -1.0/8.0; const double c8 = 1.0/9.0; const double c9 = -1.0/10.0; const double t = c5 + x*(c6 + x*(c7 + x*(c8 + x*c9))); result->val = x * (1.0 + x*(c1 + x*(c2 + x*(c3 + x*(c4 + x*t))))); result->err = GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(fabs(x) < 0.5) { double t = 0.5*(8.0*x + 1.0)/(x+2.0); gsl_sf_result c; cheb_eval_e(&lopx_cs, t, &c); result->val = x * c.val; result->err = fabs(x * c.err); return GSL_SUCCESS; } else { result->val = log(1.0 + x); result->err = GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_log_1plusx_mx_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= -1.0) { DOMAIN_ERROR(result); } else if(fabs(x) < GSL_ROOT5_DBL_EPSILON) { const double c1 = -0.5; const double c2 = 1.0/3.0; const double c3 = -1.0/4.0; const double c4 = 1.0/5.0; const double c5 = -1.0/6.0; const double c6 = 1.0/7.0; const double c7 = -1.0/8.0; const double c8 = 1.0/9.0; const double c9 = -1.0/10.0; const double t = c5 + x*(c6 + x*(c7 + x*(c8 + x*c9))); result->val = x*x * (c1 + x*(c2 + x*(c3 + x*(c4 + x*t)))); result->err = GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(fabs(x) < 0.5) { double t = 0.5*(8.0*x + 1.0)/(x+2.0); gsl_sf_result c; cheb_eval_e(&lopxmx_cs, t, &c); result->val = x*x * c.val; result->err = x*x * c.err; return GSL_SUCCESS; } else { const double lterm = log(1.0 + x); result->val = lterm - x; result->err = GSL_DBL_EPSILON * (fabs(lterm) + fabs(x)); return GSL_SUCCESS; } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_log(const double x) { EVAL_RESULT(gsl_sf_log_e(x, &result)); } double gsl_sf_log_abs(const double x) { EVAL_RESULT(gsl_sf_log_abs_e(x, &result)); } double gsl_sf_log_1plusx(const double x) { EVAL_RESULT(gsl_sf_log_1plusx_e(x, &result)); } double gsl_sf_log_1plusx_mx(const double x) { EVAL_RESULT(gsl_sf_log_1plusx_mx_e(x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__mathieu_angfunc.c000066400000000000000000000174721261542461700235350ustar00rootroot00000000000000/* specfunc/mathieu_angfunc.c * * Copyright (C) 2002 Lowell Johnson * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Author: L. Johnson */ #include "gsl__config.h" #include #include #include #include "gsl_math.h" #include "gsl_sf_mathieu.h" int gsl_sf_mathieu_ce(int order, double qq, double zz, gsl_sf_result *result) { int even_odd, ii, status; double coeff[GSL_SF_MATHIEU_COEFF], norm, fn, factor; gsl_sf_result aa; norm = 0.0; even_odd = 0; if (order % 2 != 0) even_odd = 1; /* Handle the trivial case where q = 0. */ if (qq == 0.0) { norm = 1.0; if (order == 0) norm = sqrt(2.0); fn = cos(order*zz)/norm; result->val = fn; result->err = 2.0*GSL_DBL_EPSILON; factor = fabs(fn); if (factor > 1.0) result->err *= factor; return GSL_SUCCESS; } /* Use symmetry characteristics of the functions to handle cases with negative order. */ if (order < 0) order *= -1; /* Compute the characteristic value. */ status = gsl_sf_mathieu_a(order, qq, &aa); if (status != GSL_SUCCESS) { return status; } /* Compute the series coefficients. */ status = gsl_sf_mathieu_a_coeff(order, qq, aa.val, coeff); if (status != GSL_SUCCESS) { return status; } if (even_odd == 0) { fn = 0.0; norm = coeff[0]*coeff[0]; for (ii=0; iival = fn; result->err = 2.0*GSL_DBL_EPSILON; factor = fabs(fn); if (factor > 1.0) result->err *= factor; return GSL_SUCCESS; } int gsl_sf_mathieu_se(int order, double qq, double zz, gsl_sf_result *result) { int even_odd, ii, status; double coeff[GSL_SF_MATHIEU_COEFF], norm, fn, factor; gsl_sf_result aa; norm = 0.0; even_odd = 0; if (order % 2 != 0) even_odd = 1; /* Handle the trivial cases where order = 0 and/or q = 0. */ if (order == 0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } if (qq == 0.0) { norm = 1.0; fn = sin(order*zz); result->val = fn; result->err = 2.0*GSL_DBL_EPSILON; factor = fabs(fn); if (factor > 1.0) result->err *= factor; return GSL_SUCCESS; } /* Use symmetry characteristics of the functions to handle cases with negative order. */ if (order < 0) order *= -1; /* Compute the characteristic value. */ status = gsl_sf_mathieu_b(order, qq, &aa); if (status != GSL_SUCCESS) { return status; } /* Compute the series coefficients. */ status = gsl_sf_mathieu_b_coeff(order, qq, aa.val, coeff); if (status != GSL_SUCCESS) { return status; } if (even_odd == 0) { fn = 0.0; for (ii=0; iival = fn; result->err = 2.0*GSL_DBL_EPSILON; factor = fabs(fn); if (factor > 1.0) result->err *= factor; return GSL_SUCCESS; } int gsl_sf_mathieu_ce_array(int nmin, int nmax, double qq, double zz, gsl_sf_mathieu_workspace *work, double result_array[]) { int even_odd, order, ii, jj, status; double coeff[GSL_SF_MATHIEU_COEFF], *aa = work->aa, norm; /* Initialize the result array to zeroes. */ for (ii=0; iisize < (unsigned int)nmax) { GSL_ERROR("Work space not large enough", GSL_EINVAL); } if (nmin < 0 || nmax < nmin) { GSL_ERROR("domain error", GSL_EDOM); } /* Compute all of the eigenvalues up to nmax. */ gsl_sf_mathieu_a_array(0, nmax, qq, work, aa); for (ii=0, order=nmin; order<=nmax; ii++, order++) { norm = 0.0; even_odd = 0; if (order % 2 != 0) even_odd = 1; /* Handle the trivial case where q = 0. */ if (qq == 0.0) { norm = 1.0; if (order == 0) norm = sqrt(2.0); result_array[ii] = cos(order*zz)/norm; continue; } /* Compute the series coefficients. */ status = gsl_sf_mathieu_a_coeff(order, qq, aa[order], coeff); if (status != GSL_SUCCESS) return status; if (even_odd == 0) { norm = coeff[0]*coeff[0]; for (jj=0; jjbb, norm; /* Initialize the result array to zeroes. */ for (ii=0; iisize < (unsigned int)nmax) { GSL_ERROR("Work space not large enough", GSL_EINVAL); } if (nmin < 0 || nmax < nmin) { GSL_ERROR("domain error", GSL_EDOM); } /* Compute all of the eigenvalues up to nmax. */ gsl_sf_mathieu_b_array(0, nmax, qq, work, bb); for (ii=0, order=nmin; order<=nmax; ii++, order++) { norm = 0.0; even_odd = 0; if (order % 2 != 0) even_odd = 1; /* Handle the trivial case where q = 0. */ if (qq == 0.0) { norm = 1.0; result_array[ii] = sin(order*zz); continue; } /* Compute the series coefficients. */ status = gsl_sf_mathieu_b_coeff(order, qq, bb[order], coeff); if (status != GSL_SUCCESS) { return status; } if (even_odd == 0) { for (jj=0; jj #include #include #include "gsl_math.h" #include "gsl_eigen.h" #include "gsl_errno.h" #include "gsl_sf_mathieu.h" /* prototypes */ static double solve_cubic(double c2, double c1, double c0); static double ceer(int order, double qq, double aa, int nterms) { double term, term1; int ii, n1; if (order == 0) term = 0.0; else { term = 2.0*qq*qq/aa; if (order != 2) { n1 = order/2 - 1; for (ii=0; ii= 0) { double t1 = rr + sqrt(ww); ss = fabs(t1)/t1*pow(fabs(t1), 1/3.); t1 = rr - sqrt(ww); tt = fabs(t1)/t1*pow(fabs(t1), 1/3.); } else { double theta = acos(rr/sqrt(-qq*qq*qq)); ss = 2*sqrt(-qq)*cos((theta + 4*M_PI)/3.); tt = 0.0; } return (ss + tt - c2/3); } /* Compute an initial approximation for the characteristic value. */ static double approx_c(int order, double qq) { double approx; double c0, c1, c2; if (order < 0) { GSL_ERROR_VAL("Undefined order for Mathieu function", GSL_EINVAL, 0.0); } switch (order) { case 0: if (qq <= 4) return (2 - sqrt(4 + 2*qq*qq)); /* Eqn. 31 */ else return asymptotic(order, qq); break; case 1: if (qq <= 4) return (5 + 0.5*(qq - sqrt(5*qq*qq - 16*qq + 64))); /* Eqn. 32 */ else return asymptotic(order, qq); break; case 2: if (qq <= 3) { c2 = -8.0; /* Eqn. 33 */ c1 = -48 - 3*qq*qq; c0 = 20*qq*qq; } else return asymptotic(order, qq); break; case 3: if (qq <= 6.25) { c2 = -qq - 8; /* Eqn. 34 */ c1 = 16*qq - 128 - 2*qq*qq; c0 = qq*qq*(qq + 8); } else return asymptotic(order, qq); break; default: if (order < 70) { if (1.7*order > 2*sqrt(qq)) { /* Eqn. 30 */ double n2 = (double)(order*order); double n22 = (double)((n2 - 1)*(n2 - 1)); double q2 = qq*qq; double q4 = q2*q2; approx = n2 + 0.5*q2/(n2 - 1); approx += (5*n2 + 7)*q4/(32*n22*(n2 - 1)*(n2 - 4)); approx += (9*n2*n2 + 58*n2 + 29)*q4*q2/ (64*n22*n22*(n2 - 1)*(n2 - 4)*(n2 - 9)); if (1.4*order < 2*sqrt(qq)) { approx += asymptotic(order, qq); approx *= 0.5; } } else approx = asymptotic(order, qq); return approx; } else return order*order; } /* Solve the cubic x^3 + c2*x^2 + c1*x + c0 = 0 */ approx = solve_cubic(c2, c1, c0); if ( approx < 0 && sqrt(qq) > 0.1*order ) return asymptotic(order-1, qq); else return (order*order + fabs(approx)); } static double approx_s(int order, double qq) { double approx; double c0, c1, c2; if (order < 1) { GSL_ERROR_VAL("Undefined order for Mathieu function", GSL_EINVAL, 0.0); } switch (order) { case 1: if (qq <= 4) return (5 - 0.5*(qq + sqrt(5*qq*qq + 16*qq + 64))); /* Eqn. 35 */ else return asymptotic(order-1, qq); break; case 2: if (qq <= 5) return (10 - sqrt(36 + qq*qq)); /* Eqn. 36 */ else return asymptotic(order-1, qq); break; case 3: if (qq <= 6.25) { c2 = qq - 8; /* Eqn. 37 */ c1 = -128 - 16*qq - 2*qq*qq; c0 = qq*qq*(8 - qq); } else return asymptotic(order-1, qq); break; default: if (order < 70) { if (1.7*order > 2*sqrt(qq)) { /* Eqn. 30 */ double n2 = (double)(order*order); double n22 = (double)((n2 - 1)*(n2 - 1)); double q2 = qq*qq; double q4 = q2*q2; approx = n2 + 0.5*q2/(n2 - 1); approx += (5*n2 + 7)*q4/(32*n22*(n2 - 1)*(n2 - 4)); approx += (9*n2*n2 + 58*n2 + 29)*q4*q2/ (64*n22*n22*(n2 - 1)*(n2 - 4)*(n2 - 9)); if (1.4*order < 2*sqrt(qq)) { approx += asymptotic(order-1, qq); approx *= 0.5; } } else approx = asymptotic(order-1, qq); return approx; } else return order*order; } /* Solve the cubic x^3 + c2*x^2 + c1*x + c0 = 0 */ approx = solve_cubic(c2, c1, c0); if ( approx < 0 && sqrt(qq) > 0.1*order ) return asymptotic(order-1, qq); else return (order*order + fabs(approx)); } int gsl_sf_mathieu_a(int order, double qq, gsl_sf_result *result) { int even_odd, nterms = 50, ii, counter = 0, maxcount = 200; double a1, a2, fa, fa1, dela, aa_orig, da = 0.025, aa; even_odd = 0; if (order % 2 != 0) even_odd = 1; /* If the argument is 0, then the coefficient is simply the square of the order. */ if (qq == 0) { result->val = order*order; result->err = 0.0; return GSL_SUCCESS; } /* Use symmetry characteristics of the functions to handle cases with negative order and/or argument q. See Abramowitz & Stegun, 20.8.3. */ if (order < 0) order *= -1; if (qq < 0.0) { if (even_odd == 0) return gsl_sf_mathieu_a(order, -qq, result); else return gsl_sf_mathieu_b(order, -qq, result); } /* Compute an initial approximation for the characteristic value. */ aa = approx_c(order, qq); /* Save the original approximation for later comparison. */ aa_orig = aa; /* Loop as long as the final value is not near the approximate value (with a max limit to avoid potential infinite loop). */ while (counter < maxcount) { a1 = aa + 0.001; ii = 0; if (even_odd == 0) fa1 = ceer(order, qq, a1, nterms); else fa1 = ceor(order, qq, a1, nterms); for (;;) { if (even_odd == 0) fa = ceer(order, qq, aa, nterms); else fa = ceor(order, qq, aa, nterms); a2 = a1; a1 = aa; if (fa == fa1) { result->err = GSL_DBL_EPSILON; break; } aa -= (aa - a2)/(fa - fa1)*fa; dela = fabs(aa - a2); if (dela < GSL_DBL_EPSILON) { result->err = GSL_DBL_EPSILON; break; } if (ii > 20) { result->err = dela; break; } fa1 = fa; ii++; } /* If the solution found is not near the original approximation, tweak the approximate value, and try again. */ if (fabs(aa - aa_orig) > (3 + 0.01*order*fabs(aa_orig))) { counter++; if (counter == maxcount) { result->err = fabs(aa - aa_orig); break; } if (aa > aa_orig) aa = aa_orig - da*counter; else aa = aa_orig + da*counter; continue; } else break; } result->val = aa; /* If we went through the maximum number of retries and still didn't find the solution, let us know. */ if (counter == maxcount) { GSL_ERROR("Wrong characteristic Mathieu value", GSL_EFAILED); } return GSL_SUCCESS; } int gsl_sf_mathieu_b(int order, double qq, gsl_sf_result *result) { int even_odd, nterms = 50, ii, counter = 0, maxcount = 200; double a1, a2, fa, fa1, dela, aa_orig, da = 0.025, aa; even_odd = 0; if (order % 2 != 0) even_odd = 1; /* The order cannot be 0. */ if (order == 0) { GSL_ERROR("Characteristic value undefined for order 0", GSL_EFAILED); } /* If the argument is 0, then the coefficient is simply the square of the order. */ if (qq == 0) { result->val = order*order; result->err = 0.0; return GSL_SUCCESS; } /* Use symmetry characteristics of the functions to handle cases with negative order and/or argument q. See Abramowitz & Stegun, 20.8.3. */ if (order < 0) order *= -1; if (qq < 0.0) { if (even_odd == 0) return gsl_sf_mathieu_b(order, -qq, result); else return gsl_sf_mathieu_a(order, -qq, result); } /* Compute an initial approximation for the characteristic value. */ aa = approx_s(order, qq); /* Save the original approximation for later comparison. */ aa_orig = aa; /* Loop as long as the final value is not near the approximate value (with a max limit to avoid potential infinite loop). */ while (counter < maxcount) { a1 = aa + 0.001; ii = 0; if (even_odd == 0) fa1 = seer(order, qq, a1, nterms); else fa1 = seor(order, qq, a1, nterms); for (;;) { if (even_odd == 0) fa = seer(order, qq, aa, nterms); else fa = seor(order, qq, aa, nterms); a2 = a1; a1 = aa; if (fa == fa1) { result->err = GSL_DBL_EPSILON; break; } aa -= (aa - a2)/(fa - fa1)*fa; dela = fabs(aa - a2); if (dela < 1e-18) { result->err = GSL_DBL_EPSILON; break; } if (ii > 20) { result->err = dela; break; } fa1 = fa; ii++; } /* If the solution found is not near the original approximation, tweak the approximate value, and try again. */ if (fabs(aa - aa_orig) > (3 + 0.01*order*fabs(aa_orig))) { counter++; if (counter == maxcount) { result->err = fabs(aa - aa_orig); break; } if (aa > aa_orig) aa = aa_orig - da*counter; else aa = aa_orig + da*counter; continue; } else break; } result->val = aa; /* If we went through the maximum number of retries and still didn't find the solution, let us know. */ if (counter == maxcount) { GSL_ERROR("Wrong characteristic Mathieu value", GSL_EFAILED); } return GSL_SUCCESS; } /* Eigenvalue solutions for characteristic values below. */ /* figi.c converted from EISPACK Fortran FIGI.F. * * given a nonsymmetric tridiagonal matrix such that the products * of corresponding pairs of off-diagonal elements are all * non-negative, this subroutine reduces it to a symmetric * tridiagonal matrix with the same eigenvalues. if, further, * a zero product only occurs when both factors are zero, * the reduced matrix is similar to the original matrix. * * on input * * n is the order of the matrix. * * t contains the input matrix. its subdiagonal is * stored in the last n-1 positions of the first column, * its diagonal in the n positions of the second column, * and its superdiagonal in the first n-1 positions of * the third column. t(1,1) and t(n,3) are arbitrary. * * on output * * t is unaltered. * * d contains the diagonal elements of the symmetric matrix. * * e contains the subdiagonal elements of the symmetric * matrix in its last n-1 positions. e(1) is not set. * * e2 contains the squares of the corresponding elements of e. * e2 may coincide with e if the squares are not needed. * * ierr is set to * zero for normal return, * n+i if t(i,1)*t(i-1,3) is negative, * -(3*n+i) if t(i,1)*t(i-1,3) is zero with one factor * non-zero. in this case, the eigenvectors of * the symmetric matrix are not simply related * to those of t and should not be sought. * * questions and comments should be directed to burton s. garbow, * mathematics and computer science div, argonne national laboratory * * this version dated august 1983. */ static int figi(int nn, double *tt, double *dd, double *ee, double *e2) { int ii; for (ii=0; iieven_order, odd_order = work->odd_order, extra_values = work->extra_values, ii, jj; int status; double *tt = work->tt, *dd = work->dd, *ee = work->ee, *e2 = work->e2, *zz = work->zz, *aa = work->aa; gsl_matrix_view mat, evec; gsl_vector_view eval; gsl_eigen_symmv_workspace *wmat = work->wmat; if (order_max > work->size || order_max <= order_min || order_min < 0) { GSL_ERROR ("invalid range [order_min,order_max]", GSL_EINVAL); } /* Convert the nonsymmetric tridiagonal matrix to a symmetric tridiagonal form. */ tt[0] = 0.0; tt[1] = 0.0; tt[2] = qq; for (ii=1; iieval, 0, even_order); evec = gsl_matrix_submatrix(work->evec, 0, 0, even_order, even_order); gsl_eigen_symmv(&mat.matrix, &eval.vector, &evec.matrix, wmat); gsl_eigen_symmv_sort(&eval.vector, &evec.matrix, GSL_EIGEN_SORT_VAL_ASC); for (ii=0; iieval, 0, odd_order); evec = gsl_matrix_submatrix(work->evec, 0, 0, odd_order, odd_order); gsl_eigen_symmv(&mat.matrix, &eval.vector, &evec.matrix, wmat); gsl_eigen_symmv_sort(&eval.vector, &evec.matrix, GSL_EIGEN_SORT_VAL_ASC); for (ii=0; iieven_order-1, odd_order = work->odd_order, extra_values = work->extra_values, ii, jj; double *zz = work->zz, *bb = work->bb; gsl_matrix_view mat, evec; gsl_vector_view eval; gsl_eigen_symmv_workspace *wmat = work->wmat; if (order_max > work->size || order_max <= order_min || order_min < 0) { GSL_ERROR ("invalid range [order_min,order_max]", GSL_EINVAL); } /* Fill the period \pi matrix. */ for (ii=0; iieval, 0, even_order); evec = gsl_matrix_submatrix(work->evec, 0, 0, even_order, even_order); gsl_eigen_symmv(&mat.matrix, &eval.vector, &evec.matrix, wmat); gsl_eigen_symmv_sort(&eval.vector, &evec.matrix, GSL_EIGEN_SORT_VAL_ASC); bb[0] = 0.0; for (ii=0; iieval, 0, odd_order); evec = gsl_matrix_submatrix(work->evec, 0, 0, odd_order, odd_order); gsl_eigen_symmv(&mat.matrix, &eval.vector, &evec.matrix, wmat); gsl_eigen_symmv_sort(&eval.vector, &evec.matrix, GSL_EIGEN_SORT_VAL_ASC); for (ii=0; ii #include #include "gsl_sf_mathieu.h" /***************************************************************************** * backward_recurse * * Purpose: ****************************************************************************/ static void backward_recurse_c(double aa, double qq, double xx, double *ff, double *gx, int even_odd, int ni) { int ii, nn; double g1; g1 = *gx; ff[ni] = xx; if (even_odd == 0) { for (ii=0; ii GSL_SF_MATHIEU_COEFF) return GSL_FAILURE; /* Handle the trivial case where q = 0. */ if (qq == 0.0) { for (ii=0; ii GSL_SF_MATHIEU_COEFF) return GSL_FAILURE; /* Handle the trivial case where q = 0. */ if (qq == 0.0) { for (ii=0; ii #include #include "gsl_math.h" #include "gsl_sf.h" #include "gsl_sf_mathieu.h" int gsl_sf_mathieu_Mc(int kind, int order, double qq, double zz, gsl_sf_result *result) { int even_odd, kk, mm, status; double maxerr = 1e-14, amax, pi = M_PI, fn, factor; double coeff[GSL_SF_MATHIEU_COEFF], fc; double j1c, z2c, j1pc, z2pc; double u1, u2; gsl_sf_result aa; /* Check for out of bounds parameters. */ if (qq <= 0.0) { GSL_ERROR("q must be greater than zero", GSL_EINVAL); } if (kind < 1 || kind > 2) { GSL_ERROR("kind must be 1 or 2", GSL_EINVAL); } mm = 0; amax = 0.0; fn = 0.0; u1 = sqrt(qq)*exp(-1.0*zz); u2 = sqrt(qq)*exp(zz); even_odd = 0; if (order % 2 != 0) even_odd = 1; /* Compute the characteristic value. */ status = gsl_sf_mathieu_a(order, qq, &aa); if (status != GSL_SUCCESS) { return status; } /* Compute the series coefficients. */ status = gsl_sf_mathieu_a_coeff(order, qq, aa.val, coeff); if (status != GSL_SUCCESS) { return status; } if (even_odd == 0) { for (kk=0; kkval = fn; result->err = 2.0*GSL_DBL_EPSILON; factor = fabs(fn); if (factor > 1.0) result->err *= factor; return GSL_SUCCESS; } int gsl_sf_mathieu_Ms(int kind, int order, double qq, double zz, gsl_sf_result *result) { int even_odd, kk, mm, status; double maxerr = 1e-14, amax, pi = M_PI, fn, factor; double coeff[GSL_SF_MATHIEU_COEFF], fc; double j1c, z2c, j1mc, z2mc, j1pc, z2pc; double u1, u2; gsl_sf_result aa; /* Check for out of bounds parameters. */ if (qq <= 0.0) { GSL_ERROR("q must be greater than zero", GSL_EINVAL); } if (kind < 1 || kind > 2) { GSL_ERROR("kind must be 1 or 2", GSL_EINVAL); } mm = 0; amax = 0.0; fn = 0.0; u1 = sqrt(qq)*exp(-1.0*zz); u2 = sqrt(qq)*exp(zz); even_odd = 0; if (order % 2 != 0) even_odd = 1; /* Compute the characteristic value. */ status = gsl_sf_mathieu_b(order, qq, &aa); if (status != GSL_SUCCESS) { return status; } /* Compute the series coefficients. */ status = gsl_sf_mathieu_b_coeff(order, qq, aa.val, coeff); if (status != GSL_SUCCESS) { return status; } if (even_odd == 0) { for (kk=0; kkval = fn; result->err = 2.0*GSL_DBL_EPSILON; factor = fabs(fn); if (factor > 1.0) result->err *= factor; return GSL_SUCCESS; } int gsl_sf_mathieu_Mc_array(int kind, int nmin, int nmax, double qq, double zz, gsl_sf_mathieu_workspace *work, double result_array[]) { int even_odd, order, ii, kk, mm, status; double maxerr = 1e-14, amax, pi = M_PI, fn; double coeff[GSL_SF_MATHIEU_COEFF], fc; double j1c, z2c, j1pc, z2pc; double u1, u2; double *aa = work->aa; /* Initialize the result array to zeroes. */ for (ii=0; ii 2) { GSL_ERROR("kind must be 1 or 2", GSL_EINVAL); } mm = 0; amax = 0.0; fn = 0.0; u1 = sqrt(qq)*exp(-1.0*zz); u2 = sqrt(qq)*exp(zz); /* Compute all eigenvalues up to nmax. */ gsl_sf_mathieu_a_array(0, nmax, qq, work, aa); for (ii=0, order=nmin; order<=nmax; ii++, order++) { even_odd = 0; if (order % 2 != 0) even_odd = 1; /* Compute the series coefficients. */ status = gsl_sf_mathieu_a_coeff(order, qq, aa[order], coeff); if (status != GSL_SUCCESS) { return status; } if (even_odd == 0) { for (kk=0; kkbb; /* Initialize the result array to zeroes. */ for (ii=0; ii 2) { GSL_ERROR("kind must be 1 or 2", GSL_EINVAL); } mm = 0; amax = 0.0; fn = 0.0; u1 = sqrt(qq)*exp(-1.0*zz); u2 = sqrt(qq)*exp(zz); /* Compute all eigenvalues up to nmax. */ gsl_sf_mathieu_b_array(0, nmax, qq, work, bb); for (ii=0, order=nmin; order<=nmax; ii++, order++) { even_odd = 0; if (order % 2 != 0) even_odd = 1; /* Compute the series coefficients. */ status = gsl_sf_mathieu_b_coeff(order, qq, bb[order], coeff); if (status != GSL_SUCCESS) { return status; } if (even_odd == 0) { for (kk=0; kk #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_mathieu.h" gsl_sf_mathieu_workspace *gsl_sf_mathieu_alloc(const size_t nn, const double qq) { gsl_sf_mathieu_workspace *workspace; unsigned int even_order = nn/2 + 1, odd_order = (nn + 1)/2, extra_values; /* Compute the maximum number of extra terms required for 10^-18 root accuracy for a given value of q (contributed by Brian Gladman). */ extra_values = (int)(2.1*pow(fabs(qq), 0.37)) + 9; if (nn + 1 == 0) { GSL_ERROR_NULL("matrix dimension must be positive integer", GSL_EINVAL); } workspace = (gsl_sf_mathieu_workspace *)malloc(sizeof(gsl_sf_mathieu_workspace)); if (workspace == NULL) { GSL_ERROR_NULL("failed to allocate space for workspace", GSL_ENOMEM); } /* Extend matrices to ensure accuracy. */ even_order += extra_values; odd_order += extra_values; workspace->size = nn; workspace->even_order = even_order; workspace->odd_order = odd_order; workspace->extra_values = extra_values; /* Allocate space for the characteristic values. */ workspace->aa = (double *)malloc((nn+1)*sizeof(double)); if (workspace->aa == NULL) { free(workspace); GSL_ERROR_NULL("Error allocating memory for characteristic a values", GSL_ENOMEM); } workspace->bb = (double *)malloc((nn+1)*sizeof(double)); if (workspace->bb == NULL) { free(workspace->aa); free(workspace); GSL_ERROR_NULL("Error allocating memory for characteristic b values", GSL_ENOMEM); } /* Since even_order is always >= odd_order, dimension the arrays for even_order. */ workspace->dd = (double *)malloc(even_order*sizeof(double)); if (workspace->dd == NULL) { free(workspace->aa); free(workspace->bb); free(workspace); GSL_ERROR_NULL("failed to allocate space for diagonal", GSL_ENOMEM); } workspace->ee = (double *)malloc(even_order*sizeof(double)); if (workspace->ee == NULL) { free(workspace->dd); free(workspace->aa); free(workspace->bb); free(workspace); GSL_ERROR_NULL("failed to allocate space for diagonal", GSL_ENOMEM); } workspace->tt = (double *)malloc(3*even_order*sizeof(double)); if (workspace->tt == NULL) { free(workspace->ee); free(workspace->dd); free(workspace->aa); free(workspace->bb); free(workspace); GSL_ERROR_NULL("failed to allocate space for diagonal", GSL_ENOMEM); } workspace->e2 = (double *)malloc(even_order*sizeof(double)); if (workspace->e2 == NULL) { free(workspace->tt); free(workspace->ee); free(workspace->dd); free(workspace->aa); free(workspace->bb); free(workspace); GSL_ERROR_NULL("failed to allocate space for diagonal", GSL_ENOMEM); } workspace->zz = (double *)malloc(even_order*even_order*sizeof(double)); if (workspace->zz == NULL) { free(workspace->e2); free(workspace->tt); free(workspace->ee); free(workspace->dd); free(workspace->aa); free(workspace->bb); free(workspace); GSL_ERROR_NULL("failed to allocate space for diagonal", GSL_ENOMEM); } workspace->eval = gsl_vector_alloc(even_order); if (workspace->eval == NULL) { free(workspace->zz); free(workspace->e2); free(workspace->tt); free(workspace->ee); free(workspace->dd); free(workspace->aa); free(workspace->bb); free(workspace); GSL_ERROR_NULL("failed to allocate space for eval", GSL_ENOMEM); } workspace->evec = gsl_matrix_alloc(even_order, even_order); if (workspace->evec == NULL) { gsl_vector_free (workspace->eval); free(workspace->zz); free(workspace->e2); free(workspace->tt); free(workspace->ee); free(workspace->dd); free(workspace->aa); free(workspace->bb); free(workspace); GSL_ERROR_NULL("failed to allocate space for evec", GSL_ENOMEM); } workspace->wmat = gsl_eigen_symmv_alloc(even_order); if (workspace->wmat == NULL) { gsl_matrix_free (workspace->evec); gsl_vector_free (workspace->eval); free(workspace->zz); free(workspace->e2); free(workspace->tt); free(workspace->ee); free(workspace->dd); free(workspace->aa); free(workspace->bb); free(workspace); GSL_ERROR_NULL("failed to allocate space for wmat", GSL_ENOMEM); } return workspace; } void gsl_sf_mathieu_free(gsl_sf_mathieu_workspace *workspace) { gsl_vector_free(workspace->eval); gsl_matrix_free(workspace->evec); gsl_eigen_symmv_free(workspace->wmat); free(workspace->aa); free(workspace->bb); free(workspace->dd); free(workspace->ee); free(workspace->tt); free(workspace->e2); free(workspace->zz); free(workspace); } praat-6.0.04/external/gsl/gsl_specfunc__poch.c000066400000000000000000000316021261542461700213200ustar00rootroot00000000000000/* specfunc/poch.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_exp.h" #include "gsl_sf_log.h" #include "gsl_sf_pow_int.h" #include "gsl_sf_psi.h" #include "gsl_sf_gamma.h" #include "gsl_specfunc__error.h" static const double bern[21] = { 0.0 /* no element 0 */, +0.833333333333333333333333333333333e-01, -0.138888888888888888888888888888888e-02, +0.330687830687830687830687830687830e-04, -0.826719576719576719576719576719576e-06, +0.208767569878680989792100903212014e-07, -0.528419013868749318484768220217955e-09, +0.133825365306846788328269809751291e-10, -0.338968029632258286683019539124944e-12, +0.858606205627784456413590545042562e-14, -0.217486869855806187304151642386591e-15, +0.550900282836022951520265260890225e-17, -0.139544646858125233407076862640635e-18, +0.353470703962946747169322997780379e-20, -0.895351742703754685040261131811274e-22, +0.226795245233768306031095073886816e-23, -0.574472439520264523834847971943400e-24, +0.145517247561486490186626486727132e-26, -0.368599494066531017818178247990866e-28, +0.933673425709504467203255515278562e-30, -0.236502241570062993455963519636983e-31 }; /* ((a)_x - 1)/x in the "small x" region where * cancellation must be controlled. * * Based on SLATEC DPOCH1(). */ /* C When ABS(X) is so small that substantial cancellation will occur if C the straightforward formula is used, we use an expansion due C to Fields and discussed by Y. L. Luke, The Special Functions and Their C Approximations, Vol. 1, Academic Press, 1969, page 34. C C The ratio POCH(A,X) = GAMMA(A+X)/GAMMA(A) is written by Luke as C (A+(X-1)/2)**X * polynomial in (A+(X-1)/2)**(-2) . C In order to maintain significance in POCH1, we write for positive a C (A+(X-1)/2)**X = EXP(X*LOG(A+(X-1)/2)) = EXP(Q) C = 1.0 + Q*EXPREL(Q) . C Likewise the polynomial is written C POLY = 1.0 + X*POLY1(A,X) . C Thus, C POCH1(A,X) = (POCH(A,X) - 1) / X C = EXPREL(Q)*(Q/X + Q*POLY1(A,X)) + POLY1(A,X) C */ static int pochrel_smallx(const double a, const double x, gsl_sf_result * result) { /* SQTBIG = 1.0D0/SQRT(24.0D0*D1MACH(1)) ALNEPS = LOG(D1MACH(3)) */ const double SQTBIG = 1.0/(2.0*M_SQRT2*M_SQRT3*GSL_SQRT_DBL_MIN); const double ALNEPS = GSL_LOG_DBL_EPSILON - M_LN2; if(x == 0.0) { return gsl_sf_psi_e(a, result); } else { const double bp = ( (a < -0.5) ? 1.0-a-x : a ); const int incr = ( (bp < 10.0) ? 11.0-bp : 0 ); const double b = bp + incr; double dpoch1; gsl_sf_result dexprl; int stat_dexprl; int i; double var = b + 0.5*(x-1.0); double alnvar = log(var); double q = x*alnvar; double poly1 = 0.0; if(var < SQTBIG) { const int nterms = (int)(-0.5*ALNEPS/alnvar + 1.0); const double var2 = (1.0/var)/var; const double rho = 0.5 * (x + 1.0); double term = var2; double gbern[24]; int k, j; gbern[1] = 1.0; gbern[2] = -rho/12.0; poly1 = gbern[2] * term; if(nterms > 20) { /* NTERMS IS TOO BIG, MAYBE D1MACH(3) IS BAD */ /* nterms = 20; */ result->val = 0.0; result->err = 0.0; GSL_ERROR ("error", GSL_ESANITY); } for(k=2; k<=nterms; k++) { double gbk = 0.0; for(j=1; j<=k; j++) { gbk += bern[k-j+1]*gbern[j]; } gbern[k+1] = -rho*gbk/k; term *= (2*k-2-x)*(2*k-1-x)*var2; poly1 += gbern[k+1]*term; } } stat_dexprl = gsl_sf_expm1_e(q, &dexprl); if(stat_dexprl != GSL_SUCCESS) { result->val = 0.0; result->err = 0.0; return stat_dexprl; } dexprl.val = dexprl.val/q; poly1 *= (x - 1.0); dpoch1 = dexprl.val * (alnvar + q * poly1) + poly1; for(i=incr-1; i >= 0; i--) { /* C WE HAVE DPOCH1(B,X), BUT BP IS SMALL, SO WE USE BACKWARDS RECURSION C TO OBTAIN DPOCH1(BP,X). */ double binv = 1.0/(bp+i); dpoch1 = (dpoch1 - binv) / (1.0 + x*binv); } if(bp == a) { result->val = dpoch1; result->err = 2.0 * GSL_DBL_EPSILON * (fabs(incr) + 1.0) * fabs(result->val); return GSL_SUCCESS; } else { /* C WE HAVE DPOCH1(BP,X), BUT A IS LT -0.5. WE THEREFORE USE A C REFLECTION FORMULA TO OBTAIN DPOCH1(A,X). */ double sinpxx = sin(M_PI*x)/x; double sinpx2 = sin(0.5*M_PI*x); double t1 = sinpxx/tan(M_PI*b); double t2 = 2.0*sinpx2*(sinpx2/x); double trig = t1 - t2; result->val = dpoch1 * (1.0 + x*trig) + trig; result->err = (fabs(dpoch1*x) + 1.0) * GSL_DBL_EPSILON * (fabs(t1) + fabs(t2)); result->err += 2.0 * GSL_DBL_EPSILON * (fabs(incr) + 1.0) * fabs(result->val); return GSL_SUCCESS; } } } /* Assumes a>0 and a+x>0. */ static int lnpoch_pos(const double a, const double x, gsl_sf_result * result) { double absx = fabs(x); if(absx > 0.1*a || absx*log(GSL_MAX_DBL(a,2.0)) > 0.1) { if(a < GSL_SF_GAMMA_XMAX && a+x < GSL_SF_GAMMA_XMAX) { /* If we can do it by calculating the gamma functions * directly, then that will be more accurate than * doing the subtraction of the logs. */ gsl_sf_result g1; gsl_sf_result g2; gsl_sf_gammainv_e(a, &g1); gsl_sf_gammainv_e(a+x, &g2); result->val = -log(g2.val/g1.val); result->err = g1.err/fabs(g1.val) + g2.err/fabs(g2.val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { /* Otherwise we must do the subtraction. */ gsl_sf_result lg1; gsl_sf_result lg2; int stat_1 = gsl_sf_lngamma_e(a, &lg1); int stat_2 = gsl_sf_lngamma_e(a+x, &lg2); result->val = lg2.val - lg1.val; result->err = lg2.err + lg1.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_1, stat_2); } } else if(absx < 0.1*a && a > 15.0) { /* Be careful about the implied subtraction. * Note that both a+x and and a must be * large here since a is not small * and x is not relatively large. * So we calculate using Stirling for Log[Gamma(z)]. * * Log[Gamma(a+x)/Gamma(a)] = x(Log[a]-1) + (x+a-1/2)Log[1+x/a] * + (1/(1+eps) - 1) / (12 a) * - (1/(1+eps)^3 - 1) / (360 a^3) * + (1/(1+eps)^5 - 1) / (1260 a^5) * - (1/(1+eps)^7 - 1) / (1680 a^7) * + ... */ const double eps = x/a; const double den = 1.0 + eps; const double d3 = den*den*den; const double d5 = d3*den*den; const double d7 = d5*den*den; const double c1 = -eps/den; const double c3 = -eps*(3.0+eps*(3.0+eps))/d3; const double c5 = -eps*(5.0+eps*(10.0+eps*(10.0+eps*(5.0+eps))))/d5; const double c7 = -eps*(7.0+eps*(21.0+eps*(35.0+eps*(35.0+eps*(21.0+eps*(7.0+eps))))))/d7; const double p8 = gsl_sf_pow_int(1.0+eps,8); const double c8 = 1.0/p8 - 1.0; /* these need not */ const double c9 = 1.0/(p8*(1.0+eps)) - 1.0; /* be very accurate */ const double a4 = a*a*a*a; const double a6 = a4*a*a; const double ser_1 = c1 + c3/(30.0*a*a) + c5/(105.0*a4) + c7/(140.0*a6); const double ser_2 = c8/(99.0*a6*a*a) - 691.0/360360.0 * c9/(a6*a4); const double ser = (ser_1 + ser_2)/ (12.0*a); double term1 = x * log(a/M_E); double term2; gsl_sf_result ln_1peps; gsl_sf_log_1plusx_e(eps, &ln_1peps); /* log(1 + x/a) */ term2 = (x + a - 0.5) * ln_1peps.val; result->val = term1 + term2 + ser; result->err = GSL_DBL_EPSILON*fabs(term1); result->err += fabs((x + a - 0.5)*ln_1peps.err); result->err += fabs(ln_1peps.val) * GSL_DBL_EPSILON * (fabs(x) + fabs(a) + 0.5); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { gsl_sf_result poch_rel; int stat_p = pochrel_smallx(a, x, &poch_rel); double eps = x*poch_rel.val; int stat_e = gsl_sf_log_1plusx_e(eps, result); result->err = 2.0 * fabs(x * poch_rel.err / (1.0 + eps)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_e, stat_p); } } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_lnpoch_e(const double a, const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(a <= 0.0 || a+x <= 0.0) { DOMAIN_ERROR(result); } else if(x == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else { return lnpoch_pos(a, x, result); } } int gsl_sf_lnpoch_sgn_e(const double a, const double x, gsl_sf_result * result, double * sgn) { if(a == 0.0 || a+x == 0.0) { *sgn = 0.0; DOMAIN_ERROR(result); } else if(x == 0.0) { *sgn = 1.0; result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(a > 0.0 && a+x > 0.0) { *sgn = 1.0; return lnpoch_pos(a, x, result); } else if(a < 0.0 && a+x < 0.0) { /* Reduce to positive case using reflection. */ double sin_1 = sin(M_PI * (1.0 - a)); double sin_2 = sin(M_PI * (1.0 - a - x)); if(sin_1 == 0.0 || sin_2 == 0.0) { *sgn = 0.0; DOMAIN_ERROR(result); } else { gsl_sf_result lnp_pos; int stat_pp = lnpoch_pos(1.0-a, -x, &lnp_pos); double lnterm = log(fabs(sin_1/sin_2)); result->val = lnterm - lnp_pos.val; result->err = lnp_pos.err; result->err += 2.0 * GSL_DBL_EPSILON * (fabs(1.0-a) + fabs(1.0-a-x)) * fabs(lnterm); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); *sgn = GSL_SIGN(sin_1*sin_2); return stat_pp; } } else { /* Evaluate gamma ratio directly. */ gsl_sf_result lg_apn; gsl_sf_result lg_a; double s_apn, s_a; int stat_apn = gsl_sf_lngamma_sgn_e(a+x, &lg_apn, &s_apn); int stat_a = gsl_sf_lngamma_sgn_e(a, &lg_a, &s_a); if(stat_apn == GSL_SUCCESS && stat_a == GSL_SUCCESS) { result->val = lg_apn.val - lg_a.val; result->err = lg_apn.err + lg_a.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); *sgn = s_a * s_apn; return GSL_SUCCESS; } else if(stat_apn == GSL_EDOM || stat_a == GSL_EDOM){ *sgn = 0.0; DOMAIN_ERROR(result); } else { result->val = 0.0; result->err = 0.0; *sgn = 0.0; return GSL_FAILURE; } } } int gsl_sf_poch_e(const double a, const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x == 0.0) { result->val = 1.0; result->err = 0.0; return GSL_SUCCESS; } else { gsl_sf_result lnpoch; double sgn; int stat_lnpoch = gsl_sf_lnpoch_sgn_e(a, x, &lnpoch, &sgn); int stat_exp = gsl_sf_exp_err_e(lnpoch.val, lnpoch.err, result); result->val *= sgn; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_exp, stat_lnpoch); } } int gsl_sf_pochrel_e(const double a, const double x, gsl_sf_result * result) { const double absx = fabs(x); const double absa = fabs(a); /* CHECK_POINTER(result) */ if(absx > 0.1*absa || absx*log(GSL_MAX(absa,2.0)) > 0.1) { gsl_sf_result lnpoch; double sgn; int stat_poch = gsl_sf_lnpoch_sgn_e(a, x, &lnpoch, &sgn); if(lnpoch.val > GSL_LOG_DBL_MAX) { OVERFLOW_ERROR(result); } else { const double el = exp(lnpoch.val); result->val = (sgn*el - 1.0)/x; result->err = fabs(result->val) * (lnpoch.err + 2.0 * GSL_DBL_EPSILON); result->err += 2.0 * GSL_DBL_EPSILON * (fabs(sgn*el) + 1.0) / fabs(x); return stat_poch; } } else { return pochrel_smallx(a, x, result); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_lnpoch(const double a, const double x) { EVAL_RESULT(gsl_sf_lnpoch_e(a, x, &result)); } double gsl_sf_poch(const double a, const double x) { EVAL_RESULT(gsl_sf_poch_e(a, x, &result)); } double gsl_sf_pochrel(const double a, const double x) { EVAL_RESULT(gsl_sf_pochrel_e(a, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__pow_int.c000066400000000000000000000036011261542461700220440ustar00rootroot00000000000000/* specfunc/pow_int.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_pow_int.h" /*-*-*-*-*-*-*-*-*-*-*-* Functions w/ Error handling *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_pow_int_e(double x, int n, gsl_sf_result * result) { double value = 1.0; int count = 0; /* CHECK_POINTER(result) */ if(n < 0) { n = -n; if(x == 0.0) { double u = 1.0 / x; result->val = (n % 2) ? u : (u * u) ; /* correct sign of infinity */ result->err = GSL_POSINF; GSL_ERROR ("overflow", GSL_EOVRFLW); } x = 1.0/x; } /* repeated squaring method * returns 0.0^0 = 1.0, so continuous in x */ do { if(GSL_IS_ODD(n)) value *= x; n >>= 1; x *= x; ++count; } while (n); result->val = value; result->err = 2.0 * GSL_DBL_EPSILON * (count + 1.0) * fabs(value); return GSL_SUCCESS; } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_pow_int(const double x, const int n) { EVAL_RESULT(gsl_sf_pow_int_e(x, n, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__psi.c000066400000000000000000000604251261542461700211670ustar00rootroot00000000000000/* specfunc/psi.c * * Copyright (C) 2007 Brian Gough * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004, 2005, 2006 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_exp.h" #include "gsl_sf_gamma.h" #include "gsl_sf_zeta.h" #include "gsl_sf_psi.h" #include "gsl_complex_math.h" #include #include "gsl_specfunc__error.h" #include "gsl_specfunc__chebyshev.h" #include "gsl_specfunc__cheb_eval.c" /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/ /* Chebyshev fit for f(y) = Re(Psi(1+Iy)) + M_EULER - y^2/(1+y^2) - y^2/(2(4+y^2)) * 1 < y < 10 * ==> * y(x) = (9x + 11)/2, -1 < x < 1 * x(y) = (2y - 11)/9 * * g(x) := f(y(x)) */ static double r1py_data[] = { 1.59888328244976954803168395603, 0.67905625353213463845115658455, -0.068485802980122530009506482524, -0.005788184183095866792008831182, 0.008511258167108615980419855648, -0.004042656134699693434334556409, 0.001352328406159402601778462956, -0.000311646563930660566674525382, 0.000018507563785249135437219139, 0.000028348705427529850296492146, -0.000019487536014574535567541960, 8.0709788710834469408621587335e-06, -2.2983564321340518037060346561e-06, 3.0506629599604749843855962658e-07, 1.3042238632418364610774284846e-07, -1.2308657181048950589464690208e-07, 5.7710855710682427240667414345e-08, -1.8275559342450963966092636354e-08, 3.1020471300626589420759518930e-09, 6.8989327480593812470039430640e-10, -8.7182290258923059852334818997e-10, 4.4069147710243611798213548777e-10, -1.4727311099198535963467200277e-10, 2.7589682523262644748825844248e-11, 4.1871826756975856411554363568e-12, -6.5673460487260087541400767340e-12, 3.4487900886723214020103638000e-12, -1.1807251417448690607973794078e-12, 2.3798314343969589258709315574e-13, 2.1663630410818831824259465821e-15 }; static cheb_series r1py_cs = { r1py_data, 29, -1,1, 18 }; /* Chebyshev fits from SLATEC code for psi(x) Series for PSI on the interval 0. to 1.00000D+00 with weighted error 2.03E-17 log weighted error 16.69 significant figures required 16.39 decimal places required 17.37 Series for APSI on the interval 0. to 2.50000D-01 with weighted error 5.54E-17 log weighted error 16.26 significant figures required 14.42 decimal places required 16.86 */ static double psics_data[23] = { -.038057080835217922, .491415393029387130, -.056815747821244730, .008357821225914313, -.001333232857994342, .000220313287069308, -.000037040238178456, .000006283793654854, -.000001071263908506, .000000183128394654, -.000000031353509361, .000000005372808776, -.000000000921168141, .000000000157981265, -.000000000027098646, .000000000004648722, -.000000000000797527, .000000000000136827, -.000000000000023475, .000000000000004027, -.000000000000000691, .000000000000000118, -.000000000000000020 }; static cheb_series psi_cs = { psics_data, 22, -1, 1, 17 }; static double apsics_data[16] = { -.0204749044678185, -.0101801271534859, .0000559718725387, -.0000012917176570, .0000000572858606, -.0000000038213539, .0000000003397434, -.0000000000374838, .0000000000048990, -.0000000000007344, .0000000000001233, -.0000000000000228, .0000000000000045, -.0000000000000009, .0000000000000002, -.0000000000000000 }; static cheb_series apsi_cs = { apsics_data, 15, -1, 1, 9 }; #define PSI_TABLE_NMAX 100 static double psi_table[PSI_TABLE_NMAX+1] = { 0.0, /* Infinity */ /* psi(0) */ -M_EULER, /* psi(1) */ 0.42278433509846713939348790992, /* ... */ 0.92278433509846713939348790992, 1.25611766843180047272682124325, 1.50611766843180047272682124325, 1.70611766843180047272682124325, 1.87278433509846713939348790992, 2.01564147795560999653634505277, 2.14064147795560999653634505277, 2.25175258906672110764745616389, 2.35175258906672110764745616389, 2.44266167997581201673836525479, 2.52599501330914535007169858813, 2.60291809023222227314862166505, 2.67434666166079370172005023648, 2.74101332832746036838671690315, 2.80351332832746036838671690315, 2.86233685773922507426906984432, 2.91789241329478062982462539988, 2.97052399224214905087725697883, 3.02052399224214905087725697883, 3.06814303986119666992487602645, 3.11359758531574212447033057190, 3.15707584618530734186163491973, 3.1987425128519740085283015864, 3.2387425128519740085283015864, 3.2772040513135124700667631249, 3.3142410883505495071038001619, 3.3499553740648352213895144476, 3.3844381326855248765619282407, 3.4177714660188582098952615740, 3.4500295305349872421533260902, 3.4812795305349872421533260902, 3.5115825608380175451836291205, 3.5409943255438998981248055911, 3.5695657541153284695533770196, 3.5973435318931062473311547974, 3.6243705589201332743581818244, 3.6506863483938174848844976139, 3.6763273740348431259101386396, 3.7013273740348431259101386396, 3.7257176179372821503003825420, 3.7495271417468059598241920658, 3.7727829557002943319172153216, 3.7955102284275670591899425943, 3.8177324506497892814121648166, 3.8394715810845718901078169905, 3.8607481768292527411716467777, 3.8815815101625860745049801110, 3.9019896734278921969539597029, 3.9219896734278921969539597029, 3.9415975165651470989147440166, 3.9608282857959163296839747858, 3.9796962103242182164764276160, 3.9982147288427367349949461345, 4.0163965470245549168131279527, 4.0342536898816977739559850956, 4.0517975495308205809735289552, 4.0690389288411654085597358518, 4.0859880813835382899156680552, 4.1026547480502049565823347218, 4.1190481906731557762544658694, 4.1351772229312202923834981274, 4.1510502388042361653993711433, 4.1666752388042361653993711433, 4.1820598541888515500147557587, 4.1972113693403667015299072739, 4.2121367424746950597388624977, 4.2268426248276362362094507330, 4.2413353784508246420065521823, 4.2556210927365389277208378966, 4.2697055997787924488475984600, 4.2835944886676813377364873489, 4.2972931188046676391063503626, 4.3108066323181811526198638761, 4.3241399656515144859531972094, 4.3372978603883565912163551041, 4.3502848733753695782293421171, 4.3631053861958823987421626300, 4.3757636140439836645649474401, 4.3882636140439836645649474401, 4.4006092930563293435772931191, 4.4128044150075488557724150703, 4.4248526077786331931218126607, 4.4367573696833950978837174226, 4.4485220755657480390601880108, 4.4601499825424922251066996387, 4.4716442354160554434975042364, 4.4830078717796918071338678728, 4.4942438268358715824147667492, 4.5053549379469826935258778603, 4.5163439489359936825368668713, 4.5272135141533849868846929582, 4.5379662023254279976373811303, 4.5486045001977684231692960239, 4.5591308159872421073798223397, 4.5695474826539087740464890064, 4.5798567610044242379640147796, 4.5900608426370772991885045755, 4.6001618527380874001986055856 }; #define PSI_1_TABLE_NMAX 100 static double psi_1_table[PSI_1_TABLE_NMAX+1] = { 0.0, /* Infinity */ /* psi(1,0) */ M_PI*M_PI/6.0, /* psi(1,1) */ 0.644934066848226436472415, /* ... */ 0.394934066848226436472415, 0.2838229557371153253613041, 0.2213229557371153253613041, 0.1813229557371153253613041, 0.1535451779593375475835263, 0.1331370146940314251345467, 0.1175120146940314251345467, 0.1051663356816857461222010, 0.0951663356816857461222010, 0.0869018728717683907503002, 0.0799574284273239463058557, 0.0740402686640103368384001, 0.0689382278476838062261552, 0.0644937834032393617817108, 0.0605875334032393617817108, 0.0571273257907826143768665, 0.0540409060376961946237801, 0.0512708229352031198315363, 0.0487708229352031198315363, 0.0465032492390579951149830, 0.0444371335365786562720078, 0.0425467743683366902984728, 0.0408106632572255791873617, 0.0392106632572255791873617, 0.0377313733163971768204978, 0.0363596312039143235969038, 0.0350841209998326909438426, 0.0338950603577399442137594, 0.0327839492466288331026483, 0.0317433665203020901265817, 0.03076680402030209012658168, 0.02984853037475571730748159, 0.02898347847164153045627052, 0.02816715194102928555831133, 0.02739554700275768062003973, 0.02666508681283803124093089, 0.02597256603721476254286995, 0.02531510384129102815759710, 0.02469010384129102815759710, 0.02409521984367056414807896, 0.02352832641963428296894063, 0.02298749353699501850166102, 0.02247096461137518379091722, 0.02197713745088135663042339, 0.02150454765882086513703965, 0.02105185413233829383780923, 0.02061782635456051606003145, 0.02020133322669712580597065, 0.01980133322669712580597065, 0.01941686571420193164987683, 0.01904704322899483105816086, 0.01869104465298913508094477, 0.01834810912486842177504628, 0.01801753061247172756017024, 0.01769865306145131939690494, 0.01739086605006319997554452, 0.01709360088954001329302371, 0.01680632711763538818529605, 0.01652854933985761040751827, 0.01625980437882562975715546, 0.01599965869724394401313881, 0.01574770606433893015574400, 0.01550356543933893015574400, 0.01526687904880638577704578, 0.01503731063741979257227076, 0.01481454387422086185273411, 0.01459828089844231513993134, 0.01438824099085987447620523, 0.01418415935820681325171544, 0.01398578601958352422176106, 0.01379288478501562298719316, 0.01360523231738567365335942, 0.01342261726990576130858221, 0.01324483949212798353080444, 0.01307170929822216635628920, 0.01290304679189732236910755, 0.01273868124291638877278934, 0.01257845051066194236996928, 0.01242220051066194236996928, 0.01226978472038606978956995, 0.01212106372098095378719041, 0.01197590477193174490346273, 0.01183418141592267460867815, 0.01169577311142440471248438, 0.01156056489076458859566448, 0.01142844704164317229232189, 0.01129931481023821361463594, 0.01117306812421372175754719, 0.01104961133409026496742374, 0.01092885297157366069257770, 0.01081070552355853781923177, 0.01069508522063334415522437, 0.01058191183901270133041676, 0.01047110851491297833872701, 0.01036260157046853389428257, 0.01025632035036012704977199, /* ... */ 0.01015219706839427948625679, /* psi(1,99) */ 0.01005016666333357139524567 /* psi(1,100) */ }; /* digamma for x both positive and negative; we do both * cases here because of the way we use even/odd parts * of the function */ static int psi_x(const double x, gsl_sf_result * result) { const double y = fabs(x); if(x == 0.0 || x == -1.0 || x == -2.0) { DOMAIN_ERROR(result); } else if(y >= 2.0) { const double t = 8.0/(y*y)-1.0; gsl_sf_result result_c; cheb_eval_e(&apsi_cs, t, &result_c); if(x < 0.0) { const double s = sin(M_PI*x); const double c = cos(M_PI*x); if(fabs(s) < 2.0*GSL_SQRT_DBL_MIN) { DOMAIN_ERROR(result); } else { result->val = log(y) - 0.5/x + result_c.val - M_PI * c/s; result->err = M_PI*fabs(x)*GSL_DBL_EPSILON/(s*s); result->err += result_c.err; result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } else { result->val = log(y) - 0.5/x + result_c.val; result->err = result_c.err; result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } else { /* -2 < x < 2 */ gsl_sf_result result_c; if(x < -1.0) { /* x = -2 + v */ const double v = x + 2.0; const double t1 = 1.0/x; const double t2 = 1.0/(x+1.0); const double t3 = 1.0/v; cheb_eval_e(&psi_cs, 2.0*v-1.0, &result_c); result->val = -(t1 + t2 + t3) + result_c.val; result->err = GSL_DBL_EPSILON * (fabs(t1) + fabs(x/(t2*t2)) + fabs(x/(t3*t3))); result->err += result_c.err; result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < 0.0) { /* x = -1 + v */ const double v = x + 1.0; const double t1 = 1.0/x; const double t2 = 1.0/v; cheb_eval_e(&psi_cs, 2.0*v-1.0, &result_c); result->val = -(t1 + t2) + result_c.val; result->err = GSL_DBL_EPSILON * (fabs(t1) + fabs(x/(t2*t2))); result->err += result_c.err; result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < 1.0) { /* x = v */ const double t1 = 1.0/x; cheb_eval_e(&psi_cs, 2.0*x-1.0, &result_c); result->val = -t1 + result_c.val; result->err = GSL_DBL_EPSILON * t1; result->err += result_c.err; result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { /* x = 1 + v */ const double v = x - 1.0; return cheb_eval_e(&psi_cs, 2.0*v-1.0, result); } } } /* psi(z) for large |z| in the right half-plane; [Abramowitz + Stegun, 6.3.18] */ static gsl_complex psi_complex_asymp(gsl_complex z) { /* coefficients in the asymptotic expansion for large z; * let w = z^(-2) and write the expression in the form * * ln(z) - 1/(2z) - 1/12 w (1 + c1 w + c2 w + c3 w + ... ) */ static const double c1 = -0.1; static const double c2 = 1.0/21.0; static const double c3 = -0.05; gsl_complex zi = gsl_complex_inverse(z); gsl_complex w = gsl_complex_mul(zi, zi); gsl_complex cs; /* Horner method evaluation of term in parentheses */ gsl_complex sum; sum = gsl_complex_mul_real(w, c3/c2); sum = gsl_complex_add_real(sum, 1.0); sum = gsl_complex_mul_real(sum, c2/c1); sum = gsl_complex_mul(sum, w); sum = gsl_complex_add_real(sum, 1.0); sum = gsl_complex_mul_real(sum, c1); sum = gsl_complex_mul(sum, w); sum = gsl_complex_add_real(sum, 1.0); /* correction added to log(z) */ cs = gsl_complex_mul(sum, w); cs = gsl_complex_mul_real(cs, -1.0/12.0); cs = gsl_complex_add(cs, gsl_complex_mul_real(zi, -0.5)); return gsl_complex_add(gsl_complex_log(z), cs); } /* psi(z) for complex z in the right half-plane */ static int psi_complex_rhp( gsl_complex z, gsl_sf_result * result_re, gsl_sf_result * result_im ) { int n_recurse = 0; int i; gsl_complex a; if(GSL_REAL(z) == 0.0 && GSL_IMAG(z) == 0.0) { result_re->val = 0.0; result_im->val = 0.0; result_re->err = 0.0; result_im->err = 0.0; return GSL_EDOM; } /* compute the number of recurrences to apply */ if(GSL_REAL(z) < 20.0 && fabs(GSL_IMAG(z)) < 20.0) { const double sp = sqrt(20.0 + GSL_IMAG(z)); const double sn = sqrt(20.0 - GSL_IMAG(z)); const double rhs = sp*sn - GSL_REAL(z); if(rhs > 0.0) n_recurse = ceil(rhs); } /* compute asymptotic at the large value z + n_recurse */ a = psi_complex_asymp(gsl_complex_add_real(z, n_recurse)); result_re->err = 2.0 * GSL_DBL_EPSILON * fabs(GSL_REAL(a)); result_im->err = 2.0 * GSL_DBL_EPSILON * fabs(GSL_IMAG(a)); /* descend recursively, if necessary */ for(i = n_recurse; i >= 1; --i) { gsl_complex zn = gsl_complex_add_real(z, i - 1.0); gsl_complex zn_inverse = gsl_complex_inverse(zn); a = gsl_complex_sub(a, zn_inverse); /* accumulate the error, to catch cancellations */ result_re->err += 2.0 * GSL_DBL_EPSILON * fabs(GSL_REAL(zn_inverse)); result_im->err += 2.0 * GSL_DBL_EPSILON * fabs(GSL_IMAG(zn_inverse)); } result_re->val = GSL_REAL(a); result_im->val = GSL_IMAG(a); result_re->err += 2.0 * GSL_DBL_EPSILON * fabs(result_re->val); result_im->err += 2.0 * GSL_DBL_EPSILON * fabs(result_im->val); return GSL_SUCCESS; } /* generic polygamma; assumes n >= 0 and x > 0 */ static int psi_n_xg0(const int n, const double x, gsl_sf_result * result) { if(n == 0) { return gsl_sf_psi_e(x, result); } else { /* Abramowitz + Stegun 6.4.10 */ gsl_sf_result ln_nf; gsl_sf_result hzeta; int stat_hz = gsl_sf_hzeta_e(n+1.0, x, &hzeta); int stat_nf = gsl_sf_lnfact_e((unsigned int) n, &ln_nf); int stat_e = gsl_sf_exp_mult_err_e(ln_nf.val, ln_nf.err, hzeta.val, hzeta.err, result); if(GSL_IS_EVEN(n)) result->val = -result->val; return GSL_ERROR_SELECT_3(stat_e, stat_nf, stat_hz); } } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_psi_int_e(const int n, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(n <= 0) { DOMAIN_ERROR(result); } else if(n <= PSI_TABLE_NMAX) { result->val = psi_table[n]; result->err = GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { /* Abramowitz+Stegun 6.3.18 */ const double c2 = -1.0/12.0; const double c3 = 1.0/120.0; const double c4 = -1.0/252.0; const double c5 = 1.0/240.0; const double ni2 = (1.0/n)*(1.0/n); const double ser = ni2 * (c2 + ni2 * (c3 + ni2 * (c4 + ni2*c5))); result->val = log(n) - 0.5/n + ser; result->err = GSL_DBL_EPSILON * (fabs(log(n)) + fabs(0.5/n) + fabs(ser)); result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_psi_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ return psi_x(x, result); } int gsl_sf_psi_1piy_e(const double y, gsl_sf_result * result) { const double ay = fabs(y); /* CHECK_POINTER(result) */ if(ay > 1000.0) { /* [Abramowitz+Stegun, 6.3.19] */ const double yi2 = 1.0/(ay*ay); const double lny = log(ay); const double sum = yi2 * (1.0/12.0 + 1.0/120.0 * yi2 + 1.0/252.0 * yi2*yi2); result->val = lny + sum; result->err = 2.0 * GSL_DBL_EPSILON * (fabs(lny) + fabs(sum)); return GSL_SUCCESS; } else if(ay > 10.0) { /* [Abramowitz+Stegun, 6.3.19] */ const double yi2 = 1.0/(ay*ay); const double lny = log(ay); const double sum = yi2 * (1.0/12.0 + yi2 * (1.0/120.0 + yi2 * (1.0/252.0 + yi2 * (1.0/240.0 + yi2 * (1.0/132.0 + 691.0/32760.0 * yi2))))); result->val = lny + sum; result->err = 2.0 * GSL_DBL_EPSILON * (fabs(lny) + fabs(sum)); return GSL_SUCCESS; } else if(ay > 1.0){ const double y2 = ay*ay; const double x = (2.0*ay - 11.0)/9.0; const double v = y2*(1.0/(1.0+y2) + 0.5/(4.0+y2)); gsl_sf_result result_c; cheb_eval_e(&r1py_cs, x, &result_c); result->val = result_c.val - M_EULER + v; result->err = result_c.err; result->err += 2.0 * GSL_DBL_EPSILON * (fabs(v) + M_EULER + fabs(result_c.val)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); result->err *= 5.0; /* FIXME: losing a digit somewhere... maybe at x=... ? */ return GSL_SUCCESS; } else { /* [Abramowitz+Stegun, 6.3.17] * * -M_EULER + y^2 Sum[1/n 1/(n^2 + y^2), {n,1,M}] * + Sum[1/n^3, {n,M+1,Infinity}] * - y^2 Sum[1/n^5, {n,M+1,Infinity}] * + y^4 Sum[1/n^7, {n,M+1,Infinity}] * - y^6 Sum[1/n^9, {n,M+1,Infinity}] * + O(y^8) * * We take M=50 for at least 15 digit precision. */ const int M = 50; const double y2 = y*y; const double c0 = 0.00019603999466879846570; const double c2 = 3.8426659205114376860e-08; const double c4 = 1.0041592839497643554e-11; const double c6 = 2.9516743763500191289e-15; const double p = c0 + y2 *(-c2 + y2*(c4 - y2*c6)); double sum = 0.0; double v; int n; for(n=1; n<=M; n++) { sum += 1.0/(n * (n*n + y*y)); } v = y2 * (sum + p); result->val = -M_EULER + v; result->err = GSL_DBL_EPSILON * (M_EULER + fabs(v)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_psi_1_int_e(const int n, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(n <= 0) { DOMAIN_ERROR(result); } else if(n <= PSI_1_TABLE_NMAX) { result->val = psi_1_table[n]; result->err = GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; } else { /* Abramowitz+Stegun 6.4.12 * double-precision for n > 100 */ const double c0 = -1.0/30.0; const double c1 = 1.0/42.0; const double c2 = -1.0/30.0; const double ni2 = (1.0/n)*(1.0/n); const double ser = ni2*ni2 * (c0 + ni2*(c1 + c2*ni2)); result->val = (1.0 + 0.5/n + 1.0/(6.0*n*n) + ser) / n; result->err = GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; } } int gsl_sf_psi_1_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x == 0.0 || x == -1.0 || x == -2.0) { DOMAIN_ERROR(result); } else if(x > 0.0) { return psi_n_xg0(1, x, result); } else if(x > -5.0) { /* Abramowitz + Stegun 6.4.6 */ int M = -floor(x); double fx = x + M; double sum = 0.0; int m; if(fx == 0.0) DOMAIN_ERROR(result); for(m = 0; m < M; ++m) sum += 1.0/((x+m)*(x+m)); { int stat_psi = psi_n_xg0(1, fx, result); result->val += sum; result->err += M * GSL_DBL_EPSILON * sum; return stat_psi; } } else { /* Abramowitz + Stegun 6.4.7 */ const double sin_px = sin(M_PI * x); const double d = M_PI*M_PI/(sin_px*sin_px); gsl_sf_result r; int stat_psi = psi_n_xg0(1, 1.0-x, &r); result->val = d - r.val; result->err = r.err + 2.0*GSL_DBL_EPSILON*d; return stat_psi; } } int gsl_sf_psi_n_e(const int n, const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(n == 0) { return gsl_sf_psi_e(x, result); } else if(n == 1) { return gsl_sf_psi_1_e(x, result); } else if(n < 0 || x <= 0.0) { DOMAIN_ERROR(result); } else { gsl_sf_result ln_nf; gsl_sf_result hzeta; int stat_hz = gsl_sf_hzeta_e(n+1.0, x, &hzeta); int stat_nf = gsl_sf_lnfact_e((unsigned int) n, &ln_nf); int stat_e = gsl_sf_exp_mult_err_e(ln_nf.val, ln_nf.err, hzeta.val, hzeta.err, result); if(GSL_IS_EVEN(n)) result->val = -result->val; return GSL_ERROR_SELECT_3(stat_e, stat_nf, stat_hz); } } int gsl_sf_complex_psi_e( const double x, const double y, gsl_sf_result * result_re, gsl_sf_result * result_im ) { if(x >= 0.0) { gsl_complex z = gsl_complex_rect(x, y); return psi_complex_rhp(z, result_re, result_im); } else { /* reflection formula [Abramowitz+Stegun, 6.3.7] */ gsl_complex z = gsl_complex_rect(x, y); gsl_complex omz = gsl_complex_rect(1.0 - x, -y); gsl_complex zpi = gsl_complex_mul_real(z, M_PI); gsl_complex cotzpi = gsl_complex_cot(zpi); int ret_val = psi_complex_rhp(omz, result_re, result_im); if(GSL_IS_REAL(GSL_REAL(cotzpi)) && GSL_IS_REAL(GSL_IMAG(cotzpi))) { result_re->val -= M_PI * GSL_REAL(cotzpi); result_im->val -= M_PI * GSL_IMAG(cotzpi); return ret_val; } else { GSL_ERROR("singularity", GSL_EDOM); } } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_psi_int(const int n) { EVAL_RESULT(gsl_sf_psi_int_e(n, &result)); } double gsl_sf_psi(const double x) { EVAL_RESULT(gsl_sf_psi_e(x, &result)); } double gsl_sf_psi_1piy(const double x) { EVAL_RESULT(gsl_sf_psi_1piy_e(x, &result)); } double gsl_sf_psi_1_int(const int n) { EVAL_RESULT(gsl_sf_psi_1_int_e(n, &result)); } double gsl_sf_psi_1(const double x) { EVAL_RESULT(gsl_sf_psi_1_e(x, &result)); } double gsl_sf_psi_n(const int n, const double x) { EVAL_RESULT(gsl_sf_psi_n_e(n, x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__recurse.h000066400000000000000000000172461261542461700220540ustar00rootroot00000000000000/* specfunc/recurse.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef _RECURSE_H_ #define _RECURSE_H_ #define CONCAT(a,b) a ## _ ## b /* n_max >= n_min + 2 * f[n+1] + a[n] f[n] + b[n] f[n-1] = 0 * * Trivial forward recurrence. */ #define GEN_RECURSE_FORWARD_SIMPLE(func) \ int CONCAT(recurse_forward_simple, func) ( \ const int n_max, const int n_min, \ const double parameters[], \ const double f_n_min, \ const double f_n_min_p1, \ double * f, \ double * f_n_max \ ) \ { \ int n; \ \ if(f == 0) { \ double f2 = f_n_min; \ double f1 = f_n_min_p1; \ double f0; \ for(n=n_min+2; n<=n_max; n++) { \ f0 = -REC_COEFF_A(n-1,parameters) * f1 - REC_COEFF_B(n-1, parameters) * f2; \ f2 = f1; \ f1 = f0; \ } \ *f_n_max = f0; \ } \ else { \ f[n_min] = f_n_min; \ f[n_min + 1] = f_n_min_p1; \ for(n=n_min+2; n<=n_max; n++) { \ f[n] = -REC_COEFF_A(n-1,parameters) * f[n-1] - REC_COEFF_B(n-1, parameters) * f[n-2]; \ } \ *f_n_max = f[n_max]; \ } \ \ return GSL_SUCCESS; \ } \ /* n_start >= n_max >= n_min * f[n+1] + a[n] f[n] + b[n] f[n-1] = 0 * * Generate the minimal solution of the above recursion relation, * with the simplest form of the normalization condition, f[n_min] given. * [Gautschi, SIAM Rev. 9, 24 (1967); (3.9) with s[n]=0] */ #define GEN_RECURSE_BACKWARD_MINIMAL_SIMPLE(func) \ int CONCAT(recurse_backward_minimal_simple, func) ( \ const int n_start, \ const int n_max, const int n_min, \ const double parameters[], \ const double f_n_min, \ double * f, \ double * f_n_max \ ) \ { \ int n; \ double r_n = 0.; \ double r_nm1; \ double ratio; \ \ for(n=n_start; n > n_max; n--) { \ r_nm1 = -REC_COEFF_B(n, parameters) / (REC_COEFF_A(n, parameters) + r_n); \ r_n = r_nm1; \ } \ \ if(f != 0) { \ f[n_max] = 10.*DBL_MIN; \ for(n=n_max; n > n_min; n--) { \ r_nm1 = -REC_COEFF_B(n, parameters) / (REC_COEFF_A(n, parameters) + r_n); \ f[n-1] = f[n] / r_nm1; \ r_n = r_nm1; \ } \ ratio = f_n_min / f[n_min]; \ for(n=n_min; n<=n_max; n++) { \ f[n] *= ratio; \ } \ } \ else { \ double f_nm1; \ double f_n = 10.*DBL_MIN; \ *f_n_max = f_n; \ for(n=n_max; n > n_min; n--) { \ r_nm1 = -REC_COEFF_B(n, parameters) / (REC_COEFF_A(n, parameters) + r_n); \ f_nm1 = f_n / r_nm1; \ r_n = r_nm1; \ } \ ratio = f_n_min / f_nm1; \ *f_n_max *= ratio; \ } \ \ return GSL_SUCCESS; \ } \ #endif /* !_RECURSE_H_ */ praat-6.0.04/external/gsl/gsl_specfunc__result.c000066400000000000000000000045261261542461700217120ustar00rootroot00000000000000/* specfunc/result.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_exp.h" #include "gsl_sf_result.h" int gsl_sf_result_smash_e(const gsl_sf_result_e10 * re, gsl_sf_result * r) { if(re->e10 == 0) { /* nothing to smash */ r->val = re->val; r->err = re->err; return GSL_SUCCESS; } else { const double av = fabs(re->val); const double ae = fabs(re->err); if( GSL_SQRT_DBL_MIN < av && av < GSL_SQRT_DBL_MAX && GSL_SQRT_DBL_MIN < ae && ae < GSL_SQRT_DBL_MAX && 0.49*GSL_LOG_DBL_MIN < re->e10 && re->e10 < 0.49*GSL_LOG_DBL_MAX ) { const double scale = exp(re->e10 * M_LN10); r->val = re->val * scale; r->err = re->err * scale; return GSL_SUCCESS; } else { return gsl_sf_exp_mult_err_e(re->e10*M_LN10, 0.0, re->val, re->err, r); } } /* int stat_v; int stat_e; if(re->val == 0.0) { r->val = 0.0; stat_v = GSL_SUCCESS; } else { gsl_sf_result r_val; const double s = GSL_SIGN(re->val); const double x_v = re->e10*M_LN10 + log(fabs(re->val)); stat_v = gsl_sf_exp_e(x_v, &r_val); r->val = s * r_val.val; } if(re->err == 0.0) { r->err = 0.0; stat_e = GSL_SUCCESS; } else if(re->val != 0.0) { r->err = fabs(r->val * re->err/re->val); stat_e = GSL_SUCCESS; } else { gsl_sf_result r_err; const double x_e = re->e10*M_LN10 + log(fabs(re->err)); stat_e = gsl_sf_exp_e(x_e, &r_err); r->err = r_err.val; } return GSL_ERROR_SELECT_2(stat_v, stat_e); */ } praat-6.0.04/external/gsl/gsl_specfunc__shint.c000066400000000000000000000076711261542461700215250ustar00rootroot00000000000000/* specfunc/shint.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_expint.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__chebyshev.h" #include "gsl_specfunc__cheb_eval.c" /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/ /* based on SLATEC shi.f, W. Fullerton series for shi on the interval 0.00000e+00 to 1.40625e-01 with weighted error 4.67e-20 log weighted error 19.33 significant figures required 17.07 decimal places required 19.75 */ static double shi_data[7] = { 0.0078372685688900950695, 0.0039227664934234563973, 0.0000041346787887617267, 0.0000000024707480372883, 0.0000000000009379295591, 0.0000000000000002451817, 0.0000000000000000000467 }; static cheb_series shi_cs = { shi_data, 6, -1, 1, 6 }; /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_Shi_e(const double x, gsl_sf_result * result) { const double xsml = GSL_SQRT_DBL_EPSILON; /* sqrt (r1mach(3)) */ const double ax = fabs(x); if(ax < xsml) { result->val = x; result->err = 0.0; return GSL_SUCCESS; } else if(ax <= 0.375) { gsl_sf_result result_c; cheb_eval_e(&shi_cs, 128.0*x*x/9.0-1.0, &result_c); result->val = x * (1.0 + result_c.val); result->err = x * result_c.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { gsl_sf_result result_Ei; gsl_sf_result result_E1; int status_Ei = gsl_sf_expint_Ei_e(x, &result_Ei); int status_E1 = gsl_sf_expint_E1_e(x, &result_E1); result->val = 0.5*(result_Ei.val + result_E1.val); result->err = 0.5*(result_Ei.err + result_E1.err); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); if(status_Ei == GSL_EUNDRFLW && status_E1 == GSL_EUNDRFLW) { GSL_ERROR ("underflow", GSL_EUNDRFLW); } else if(status_Ei == GSL_EOVRFLW || status_E1 == GSL_EOVRFLW) { GSL_ERROR ("overflow", GSL_EOVRFLW); } else { return GSL_SUCCESS; } } } int gsl_sf_Chi_e(const double x, gsl_sf_result * result) { gsl_sf_result result_Ei; gsl_sf_result result_E1; int status_Ei = gsl_sf_expint_Ei_e(x, &result_Ei); int status_E1 = gsl_sf_expint_E1_e(x, &result_E1); if(status_Ei == GSL_EDOM || status_E1 == GSL_EDOM) { DOMAIN_ERROR(result); } else if(status_Ei == GSL_EUNDRFLW && status_E1 == GSL_EUNDRFLW) { UNDERFLOW_ERROR(result); } else if(status_Ei == GSL_EOVRFLW || status_E1 == GSL_EOVRFLW) { OVERFLOW_ERROR(result); } else { result->val = 0.5 * (result_Ei.val - result_E1.val); result->err = 0.5 * (result_Ei.err + result_E1.err); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_Shi(const double x) { EVAL_RESULT(gsl_sf_Shi_e(x, &result)); } double gsl_sf_Chi(const double x) { EVAL_RESULT(gsl_sf_Chi_e(x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__sinint.c000066400000000000000000000256641261542461700217060ustar00rootroot00000000000000/* specfunc/sinint.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_trig.h" #include "gsl_sf_expint.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__chebyshev.h" #include "gsl_specfunc__cheb_eval.c" /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/ /* based on SLATEC r9sifg.f, W. Fullerton */ /* series for f1 on the interval 2.00000e-02 to 6.25000e-02 with weighted error 2.82e-17 log weighted error 16.55 significant figures required 15.36 decimal places required 17.20 */ static double f1_data[20] = { -0.1191081969051363610, -0.0247823144996236248, 0.0011910281453357821, -0.0000927027714388562, 0.0000093373141568271, -0.0000011058287820557, 0.0000001464772071460, -0.0000000210694496288, 0.0000000032293492367, -0.0000000005206529618, 0.0000000000874878885, -0.0000000000152176187, 0.0000000000027257192, -0.0000000000005007053, 0.0000000000000940241, -0.0000000000000180014, 0.0000000000000035063, -0.0000000000000006935, 0.0000000000000001391, -0.0000000000000000282 }; static cheb_series f1_cs = { f1_data, 19, -1, 1, 10 }; /* series for f2 on the interval 0.00000e+00 to 2.00000e-02 with weighted error 4.32e-17 log weighted error 16.36 significant figures required 14.75 decimal places required 17.10 */ static double f2_data[29] = { -0.0348409253897013234, -0.0166842205677959686, 0.0006752901241237738, -0.0000535066622544701, 0.0000062693421779007, -0.0000009526638801991, 0.0000001745629224251, -0.0000000368795403065, 0.0000000087202677705, -0.0000000022601970392, 0.0000000006324624977, -0.0000000001888911889, 0.0000000000596774674, -0.0000000000198044313, 0.0000000000068641396, -0.0000000000024731020, 0.0000000000009226360, -0.0000000000003552364, 0.0000000000001407606, -0.0000000000000572623, 0.0000000000000238654, -0.0000000000000101714, 0.0000000000000044259, -0.0000000000000019634, 0.0000000000000008868, -0.0000000000000004074, 0.0000000000000001901, -0.0000000000000000900, 0.0000000000000000432 }; static cheb_series f2_cs = { f2_data, 28, -1, 1, 14 }; /* series for g1 on the interval 2.00000e-02 to 6.25000e-02 with weighted error 5.48e-17 log weighted error 16.26 significant figures required 15.47 decimal places required 16.92 */ static double g1_data[21] = { -0.3040578798253495954, -0.0566890984597120588, 0.0039046158173275644, -0.0003746075959202261, 0.0000435431556559844, -0.0000057417294453025, 0.0000008282552104503, -0.0000001278245892595, 0.0000000207978352949, -0.0000000035313205922, 0.0000000006210824236, -0.0000000001125215474, 0.0000000000209088918, -0.0000000000039715832, 0.0000000000007690431, -0.0000000000001514697, 0.0000000000000302892, -0.0000000000000061400, 0.0000000000000012601, -0.0000000000000002615, 0.0000000000000000548 }; static cheb_series g1_cs = { g1_data, 20, -1, 1, 13 }; /* series for g2 on the interval 0.00000e+00 to 2.00000e-02 with weighted error 5.01e-17 log weighted error 16.30 significant figures required 15.12 decimal places required 17.07 */ static double g2_data[34] = { -0.0967329367532432218, -0.0452077907957459871, 0.0028190005352706523, -0.0002899167740759160, 0.0000407444664601121, -0.0000071056382192354, 0.0000014534723163019, -0.0000003364116512503, 0.0000000859774367886, -0.0000000238437656302, 0.0000000070831906340, -0.0000000022318068154, 0.0000000007401087359, -0.0000000002567171162, 0.0000000000926707021, -0.0000000000346693311, 0.0000000000133950573, -0.0000000000053290754, 0.0000000000021775312, -0.0000000000009118621, 0.0000000000003905864, -0.0000000000001708459, 0.0000000000000762015, -0.0000000000000346151, 0.0000000000000159996, -0.0000000000000075213, 0.0000000000000035970, -0.0000000000000017530, 0.0000000000000008738, -0.0000000000000004487, 0.0000000000000002397, -0.0000000000000001347, 0.0000000000000000801, -0.0000000000000000501 }; static cheb_series g2_cs = { g2_data, 33, -1, 1, 20 }; /* x >= 4.0 */ static void fg_asymp(const double x, gsl_sf_result * f, gsl_sf_result * g) { /* xbig = sqrt (1.0/r1mach(3)) xmaxf = exp (amin1(-alog(r1mach(1)), alog(r1mach(2))) - 0.01) xmaxg = 1.0/sqrt(r1mach(1)) xbnd = sqrt(50.0) */ const double xbig = 1.0/GSL_SQRT_DBL_EPSILON; const double xmaxf = 1.0/GSL_DBL_MIN; const double xmaxg = 1.0/GSL_SQRT_DBL_MIN; const double xbnd = 7.07106781187; const double x2 = x*x; if(x <= xbnd) { gsl_sf_result result_c1; gsl_sf_result result_c2; cheb_eval_e(&f1_cs, (1.0/x2-0.04125)/0.02125, &result_c1); cheb_eval_e(&g1_cs, (1.0/x2-0.04125)/0.02125, &result_c2); f->val = (1.0 + result_c1.val)/x; g->val = (1.0 + result_c2.val)/x2; f->err = result_c1.err/x + 2.0 * GSL_DBL_EPSILON * fabs(f->val); g->err = result_c2.err/x2 + 2.0 * GSL_DBL_EPSILON * fabs(g->val); } else if(x <= xbig) { gsl_sf_result result_c1; gsl_sf_result result_c2; cheb_eval_e(&f2_cs, 100.0/x2-1.0, &result_c1); cheb_eval_e(&g2_cs, 100.0/x2-1.0, &result_c2); f->val = (1.0 + result_c1.val)/x; g->val = (1.0 + result_c2.val)/x2; f->err = result_c1.err/x + 2.0 * GSL_DBL_EPSILON * fabs(f->val); g->err = result_c2.err/x2 + 2.0 * GSL_DBL_EPSILON * fabs(g->val); } else { f->val = (x < xmaxf ? 1.0/x : 0.0); g->val = (x < xmaxg ? 1.0/x2 : 0.0); f->err = 2.0 * GSL_DBL_EPSILON * fabs(f->val); g->err = 2.0 * GSL_DBL_EPSILON * fabs(g->val); } return; } /* based on SLATEC si.f, W. Fullerton series for si on the interval 0.00000e+00 to 1.60000e+01 with weighted error 1.22e-17 log weighted error 16.91 significant figures required 16.37 decimal places required 17.45 */ static double si_data[12] = { -0.1315646598184841929, -0.2776578526973601892, 0.0354414054866659180, -0.0025631631447933978, 0.0001162365390497009, -0.0000035904327241606, 0.0000000802342123706, -0.0000000013562997693, 0.0000000000179440722, -0.0000000000001908387, 0.0000000000000016670, -0.0000000000000000122 }; static cheb_series si_cs = { si_data, 11, -1, 1, 9 }; /* series for ci on the interval 0.00000e+00 to 1.60000e+01 with weighted error 1.94e-18 log weighted error 17.71 significant figures required 17.74 decimal places required 18.27 */ static double ci_data[13] = { -0.34004281856055363156, -1.03302166401177456807, 0.19388222659917082877, -0.01918260436019865894, 0.00110789252584784967, -0.00004157234558247209, 0.00000109278524300229, -0.00000002123285954183, 0.00000000031733482164, -0.00000000000376141548, 0.00000000000003622653, -0.00000000000000028912, 0.00000000000000000194 }; static cheb_series ci_cs = { ci_data, 12, -1, 1, 9 }; /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_Si_e(const double x, gsl_sf_result * result) { double ax = fabs(x); /* CHECK_POINTER(result) */ if(ax < GSL_SQRT_DBL_EPSILON) { result->val = x; result->err = 0.0; return GSL_SUCCESS; } else if(ax <= 4.0) { gsl_sf_result result_c; cheb_eval_e(&si_cs, (x*x-8.0)*0.125, &result_c); result->val = x * (0.75 + result_c.val); result->err = ax * result_c.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { /* Note there is no loss of precision * here bcause of the leading constant. */ gsl_sf_result f; gsl_sf_result g; fg_asymp(ax, &f, &g); result->val = 0.5 * M_PI - f.val*cos(ax) - g.val*sin(ax); result->err = f.err + g.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); if(x < 0.0) result->val = -result->val; return GSL_SUCCESS; } } int gsl_sf_Ci_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= 0.0) { DOMAIN_ERROR(result); } else if(x <= 4.0) { const double lx = log(x); const double y = (x*x-8.0)*0.125; gsl_sf_result result_c; cheb_eval_e(&ci_cs, y, &result_c); result->val = lx - 0.5 + result_c.val; result->err = 2.0 * GSL_DBL_EPSILON * (fabs(lx) + 0.5) + result_c.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { gsl_sf_result sin_result; gsl_sf_result cos_result; int stat_sin = gsl_sf_sin_e(x, &sin_result); int stat_cos = gsl_sf_cos_e(x, &cos_result); gsl_sf_result f; gsl_sf_result g; fg_asymp(x, &f, &g); result->val = f.val*sin_result.val - g.val*cos_result.val; result->err = fabs(f.err*sin_result.val); result->err += fabs(g.err*cos_result.val); result->err += fabs(f.val*sin_result.err); result->err += fabs(g.val*cos_result.err); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_sin, stat_cos); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_Si(const double x) { EVAL_RESULT(gsl_sf_Si_e(x, &result)); } double gsl_sf_Ci(const double x) { EVAL_RESULT(gsl_sf_Ci_e(x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__synchrotron.c000066400000000000000000000163351261542461700227650ustar00rootroot00000000000000/* specfunc/synchrotron.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_exp.h" #include "gsl_sf_pow_int.h" #include "gsl_sf_synchrotron.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__chebyshev.h" #include "gsl_specfunc__cheb_eval.c" static double synchrotron1_data[13] = { 30.364682982501076273, 17.079395277408394574, 4.560132133545072889, 0.549281246730419979, 0.372976075069301172e-01, 0.161362430201041242e-02, 0.481916772120371e-04, 0.10512425288938e-05, 0.174638504670e-07, 0.22815486544e-09, 0.240443082e-11, 0.2086588e-13, 0.15167e-15 }; static cheb_series synchrotron1_cs = { synchrotron1_data, 12, -1.0, 1.0, 9 }; static double synchrotron2_data[12] = { 0.4490721623532660844, 0.898353677994187218e-01, 0.81044573772151290e-02, 0.4261716991089162e-03, 0.147609631270746e-04, 0.3628633615300e-06, 0.66634807498e-08, 0.949077166e-10, 0.1079125e-11, 0.10022e-13, 0.77e-16, 0.5e-18 }; static cheb_series synchrotron2_cs = { synchrotron2_data, 11, -1.0, 1.0, 7 }; static double synchrotron1a_data[23] = { 2.1329305161355000985, 0.741352864954200240e-01, 0.86968099909964198e-02, 0.11703826248775692e-02, 0.1645105798619192e-03, 0.240201021420640e-04, 0.35827756389389e-05, 0.5447747626984e-06, 0.838802856196e-07, 0.13069882684e-07, 0.2053099071e-08, 0.325187537e-09, 0.517914041e-10, 0.83002988e-11, 0.13352728e-11, 0.2159150e-12, 0.349967e-13, 0.56994e-14, 0.9291e-15, 0.152e-15, 0.249e-16, 0.41e-17, 0.7e-18 }; static cheb_series synchrotron1a_cs = { synchrotron1a_data, 22, -1.0, 1.0, 11 }; static double synchrotron21_data[13] = { 38.617839923843085480, 23.037715594963734597, 5.3802499868335705968, 0.6156793806995710776, 0.406688004668895584e-01, 0.17296274552648414e-02, 0.51061258836577e-04, 0.110459595022e-05, 0.18235530206e-07, 0.2370769803e-09, 0.24887296e-11, 0.21529e-13, 0.156e-15 }; static cheb_series synchrotron21_cs = { synchrotron21_data, 12, -1.0, 1.0, 9 }; static double synchrotron22_data[13] = { 7.9063148270660804288, 3.1353463612853425684, 0.4854879477453714538, 0.394816675827237234e-01, 0.19661622334808802e-02, 0.659078932293042e-04, 0.15857561349856e-05, 0.286865301123e-07, 0.4041202360e-09, 0.45568444e-11, 0.420459e-13, 0.3232e-15, 0.21e-17 }; static cheb_series synchrotron22_cs = { synchrotron22_data, 12, -1.0, 1.0, 8 }; static double synchrotron2a_data[17] = { 2.020337094170713600, 0.10956237121807404e-01, 0.8542384730114676e-03, 0.723430242132822e-04, 0.63124427962699e-05, 0.5648193141174e-06, 0.512832480138e-07, 0.47196532914e-08, 0.4380744214e-09, 0.410268149e-10, 0.38623072e-11, 0.3661323e-12, 0.348023e-13, 0.33301e-14, 0.319e-15, 0.307e-16, 0.3e-17 }; static cheb_series synchrotron2a_cs = { synchrotron2a_data, 16, -1.0, 1.0, 8 }; /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_synchrotron_1_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x < 0.0) { DOMAIN_ERROR(result); } else if(x < 2.0*M_SQRT2 * GSL_SQRT_DBL_EPSILON) { /* BJG: added first order correction term. The taylor series is S1(x) = ((4pi)/(sqrt(3)gamma(1/3))) * (x/2)^(1/3) * (1 - (gamma(1/3)/2)*(x/2)^2/3 + (3/4) * (x/2)^2 ....) */ double z = pow(x, 1.0/3.0); double cf = 1 - 8.43812762813205e-01 * z * z; result->val = 2.14952824153447863671 * z * cf; result->err = GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; } else if(x <= 4.0) { const double c0 = M_PI/M_SQRT3; const double px = pow(x,1.0/3.0); const double px11 = gsl_sf_pow_int(px,11); const double t = x*x/8.0 - 1.0; gsl_sf_result result_c1; gsl_sf_result result_c2; cheb_eval_e(&synchrotron1_cs, t, &result_c1); cheb_eval_e(&synchrotron2_cs, t, &result_c2); result->val = px * result_c1.val - px11 * result_c2.val - c0 * x; result->err = px * result_c1.err + px11 * result_c2.err + c0 * x * GSL_DBL_EPSILON; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < -8.0*GSL_LOG_DBL_MIN/7.0) { const double c0 = 0.2257913526447274323630976; /* log(sqrt(pi/2)) */ const double t = (12.0 - x) / (x + 4.0); gsl_sf_result result_c1; cheb_eval_e(&synchrotron1a_cs, t, &result_c1); result->val = sqrt(x) * result_c1.val * exp(c0 - x); result->err = 2.0 * GSL_DBL_EPSILON * result->val * (fabs(c0-x)+1.0); return GSL_SUCCESS; } else { UNDERFLOW_ERROR(result); } } int gsl_sf_synchrotron_2_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x < 0.0) { DOMAIN_ERROR(result); } else if(x < 2.0*M_SQRT2*GSL_SQRT_DBL_EPSILON) { /* BJG: added first order correction term. The taylor series is S2(x) = ((2pi)/(sqrt(3)*gamma(1/3))) * (x/2)^(1/3) * (1 - (gamma(1/3)/gamma(4/3))*(x/2)^(4/3) + (gamma(1/3)/gamma(4/3))*(x/2)^2...) */ double z = pow(x, 1.0/3.0); double cf = 1 - 1.17767156510235e+00 * z * x; result->val = 1.07476412076723931836 * z * cf ; result->err = 2.0 * GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; } else if(x <= 4.0) { const double px = pow(x, 1.0/3.0); const double px5 = gsl_sf_pow_int(px,5); const double t = x*x/8.0 - 1.0; gsl_sf_result cheb1; gsl_sf_result cheb2; cheb_eval_e(&synchrotron21_cs, t, &cheb1); cheb_eval_e(&synchrotron22_cs, t, &cheb2); result->val = px * cheb1.val - px5 * cheb2.val; result->err = px * cheb1.err + px5 * cheb2.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < -8.0*GSL_LOG_DBL_MIN/7.0) { const double c0 = 0.22579135264472743236; /* log(sqrt(pi/2)) */ const double t = (10.0 - x) / (x + 2.0); gsl_sf_result cheb1; cheb_eval_e(&synchrotron2a_cs, t, &cheb1); result->val = sqrt(x) * exp(c0-x) * cheb1.val; result->err = GSL_DBL_EPSILON * result->val * (fabs(c0-x)+1.0); return GSL_SUCCESS; } else { UNDERFLOW_ERROR(result); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_synchrotron_1(const double x) { EVAL_RESULT(gsl_sf_synchrotron_1_e(x, &result)); } double gsl_sf_synchrotron_2(const double x) { EVAL_RESULT(gsl_sf_synchrotron_2_e(x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__transport.c000066400000000000000000000311411261542461700224210ustar00rootroot00000000000000/* specfunc/transport.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_transport.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__check.h" #include "gsl_specfunc__chebyshev.h" #include "gsl_specfunc__cheb_eval.c" static double transport2_data[18] = { 1.671760446434538503, -0.147735359946794490, 0.148213819946936338e-01, -0.14195330326305613e-02, 0.1306541324415708e-03, -0.117155795867579e-04, 0.10333498445756e-05, -0.901911304223e-07, 0.78177169833e-08, -0.6744565684e-09, 0.579946394e-10, -0.49747619e-11, 0.425961e-12, -0.36422e-13, 0.3111e-14, -0.265e-15, 0.23e-16, -0.19e-17 }; static cheb_series transport2_cs = { transport2_data, 17, -1, 1, 9 }; static double transport3_data[18] = { 0.762012543243872007, -0.105674387705058533, 0.119778084819657810e-01, -0.12144015203698307e-02, 0.1155099769392855e-03, -0.105815992124423e-04, 0.9474663385302e-06, -0.836221212858e-07, 0.73109099278e-08, -0.6350594779e-09, 0.549118282e-10, -0.47321395e-11, 0.4067695e-12, -0.348971e-13, 0.29892e-14, -0.256e-15, 0.219e-16, -0.19e-17 }; static cheb_series transport3_cs = { transport3_data, 17, -1, 1, 9 }; static double transport4_data[18] = { 0.4807570994615110579, -0.8175378810321083956e-01, 0.1002700665975162973e-01, -0.10599339359820151e-02, 0.1034506245030405e-03, -0.96442705485899e-05, 0.8745544408515e-06, -0.779321207981e-07, 0.68649886141e-08, -0.5999571076e-09, 0.521366241e-10, -0.45118382e-11, 0.3892159e-12, -0.334936e-13, 0.28767e-14, -0.2467e-15, 0.211e-16, -0.18e-17 }; static cheb_series transport4_cs = { transport4_data, 17, -1, 1, 9 }; static double transport5_data[18] = { 0.347777777133910789, -0.66456988976050428e-01, 0.8611072656883309e-02, -0.9396682223755538e-03, 0.936324806081513e-04, -0.88571319340833e-05, 0.811914989145e-06, -0.72957654233e-07, 0.646971455e-08, -0.568490283e-09, 0.49625598e-10, -0.4310940e-11, 0.373100e-12, -0.32198e-13, 0.2772e-14, -0.238e-15, 0.21e-16, -0.18e-17 }; static cheb_series transport5_cs = { transport5_data, 17, -1, 1, 9 }; static double transport_sumexp(const int numexp, const int order, const double t, double x) { double rk = (double)numexp; double sumexp = 0.0; int k; for(k=1; k<=numexp; k++) { double sum2 = 1.0; double xk = 1.0/(rk*x); double xk1 = 1.0; int j; for(j=1; j<=order; j++) { sum2 = sum2*xk1*xk + 1.0; xk1 += 1.0; } sumexp *= t; sumexp += sum2; rk -= 1.0; } return sumexp; } /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_transport_2_e(const double x, gsl_sf_result * result) { const double val_infinity = 3.289868133696452873; /* CHECK_POINTER(result) */ if(x < 0.0) { DOMAIN_ERROR(result); } else if(x < 3.0*GSL_SQRT_DBL_EPSILON) { result->val = x; result->err = GSL_DBL_EPSILON*fabs(x) + x*x/2.0; return GSL_SUCCESS; } else if(x <= 4.0) { double t = (x*x/8.0 - 0.5) - 0.5; gsl_sf_result result_c; cheb_eval_e(&transport2_cs, t, &result_c); result->val = x * result_c.val; result->err = x * result_c.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < -GSL_LOG_DBL_EPSILON) { const int numexp = (int)((-GSL_LOG_DBL_EPSILON)/x) + 1; const double sumexp = transport_sumexp(numexp, 2, exp(-x), x); const double t = 2.0 * log(x) - x + log(sumexp); if(t < GSL_LOG_DBL_EPSILON) { result->val = val_infinity; result->err = 2.0 * GSL_DBL_EPSILON * val_infinity; } else { const double et = exp(t); result->val = val_infinity - et; result->err = 2.0 * GSL_DBL_EPSILON * (val_infinity + fabs(t) * et); } return GSL_SUCCESS; } else if(x < 2.0/GSL_DBL_EPSILON) { const int numexp = 1; const double sumexp = transport_sumexp(numexp, 2, 1.0, x); const double t = 2.0 * log(x) - x + log(sumexp); if(t < GSL_LOG_DBL_EPSILON) { result->val = val_infinity; result->err = 2.0 * GSL_DBL_EPSILON * val_infinity; } else { const double et = exp(t); result->val = val_infinity - et; result->err = 2.0 * GSL_DBL_EPSILON * (val_infinity + (fabs(t)+1.0) * et); } return GSL_SUCCESS; } else { const double t = 2.0 * log(x) - x; if(t < GSL_LOG_DBL_EPSILON) { result->val = val_infinity; result->err = 2.0 * GSL_DBL_EPSILON * val_infinity; } else { const double et = exp(t); result->val = val_infinity - et; result->err = 2.0 * GSL_DBL_EPSILON * (val_infinity + (fabs(t)+1.0) * et); } return GSL_SUCCESS; } } int gsl_sf_transport_3_e(const double x, gsl_sf_result * result) { const double val_infinity = 7.212341418957565712; /* CHECK_POINTER(result) */ if(x < 0.0) { DOMAIN_ERROR(result); } else if(x == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(x < 3.0*GSL_SQRT_DBL_EPSILON) { result->val = 0.5*x*x; result->err = 2.0 * GSL_DBL_EPSILON * result->val; CHECK_UNDERFLOW(result); return GSL_SUCCESS; } else if(x <= 4.0) { const double x2 = x*x; const double t = (x2/8.0 - 0.5) - 0.5; gsl_sf_result result_c; cheb_eval_e(&transport3_cs, t, &result_c); result->val = x2 * result_c.val; result->err = x2 * result_c.err; result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < -GSL_LOG_DBL_EPSILON) { const int numexp = (int)((-GSL_LOG_DBL_EPSILON)/x) + 1; const double sumexp = transport_sumexp(numexp, 3, exp(-x), x); const double t = 3.0 * log(x) - x + log(sumexp); if(t < GSL_LOG_DBL_EPSILON) { result->val = val_infinity; result->err = 2.0 * GSL_DBL_EPSILON * val_infinity; } else { const double et = exp(t); result->val = val_infinity - et; result->err = 2.0 * GSL_DBL_EPSILON * (val_infinity + fabs(t) * et); } return GSL_SUCCESS; } else if(x < 3.0/GSL_DBL_EPSILON) { const int numexp = 1; const double sumexp = transport_sumexp(numexp, 3, 1.0, x); const double t = 3.0 * log(x) - x + log(sumexp); if(t < GSL_LOG_DBL_EPSILON) { result->val = val_infinity; result->err = 2.0 * GSL_DBL_EPSILON * val_infinity; } else { const double et = exp(t); result->val = val_infinity - et; result->err = 2.0 * GSL_DBL_EPSILON * (val_infinity + (fabs(t)+1.0) * et); } return GSL_SUCCESS; } else { const double t = 3.0 * log(x) - x; if(t < GSL_LOG_DBL_EPSILON) { result->val = val_infinity; result->err = 2.0 * GSL_DBL_EPSILON * val_infinity; } else { const double et = exp(t); result->val = val_infinity - et; result->err = 2.0 * GSL_DBL_EPSILON * (val_infinity + (fabs(t)+1.0) * et); } return GSL_SUCCESS; } } int gsl_sf_transport_4_e(const double x, gsl_sf_result * result) { const double val_infinity = 25.97575760906731660; /* CHECK_POINTER(result) */ if(x < 0.0) { DOMAIN_ERROR(result); } else if(x == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(x < 3.0*GSL_SQRT_DBL_EPSILON) { result->val = x*x*x/3.0; result->err = 3.0 * GSL_DBL_EPSILON * result->val; CHECK_UNDERFLOW(result); return GSL_SUCCESS; } else if(x <= 4.0) { const double x2 = x*x; const double t = (x2/8.0 - 0.5) - 0.5; gsl_sf_result result_c; cheb_eval_e(&transport4_cs, t, &result_c); result->val = x2*x * result_c.val; result->err = x2*x * result_c.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < -GSL_LOG_DBL_EPSILON) { const int numexp = (int)((-GSL_LOG_DBL_EPSILON)/x) + 1; const double sumexp = transport_sumexp(numexp, 4, exp(-x), x); const double t = 4.0 * log(x) - x + log(sumexp); if(t < GSL_LOG_DBL_EPSILON) { result->val = val_infinity; result->err = 2.0 * GSL_DBL_EPSILON * val_infinity; } else { const double et = exp(t); result->val = val_infinity - et; result->err = 2.0 * GSL_DBL_EPSILON * (val_infinity + (fabs(t)+1.0) * et); } return GSL_SUCCESS; } else if(x < 3.0/GSL_DBL_EPSILON) { const int numexp = 1; const double sumexp = transport_sumexp(numexp, 4, 1.0, x); const double t = 4.0 * log(x) - x + log(sumexp); if(t < GSL_LOG_DBL_EPSILON) { result->val = val_infinity; result->err = 2.0 * GSL_DBL_EPSILON * val_infinity; } else { const double et = exp(t); result->val = val_infinity - et; result->err = 2.0 * GSL_DBL_EPSILON * (val_infinity + (fabs(t)+1.0) * et); } return GSL_SUCCESS; } else { const double t = 4.0 * log(x) - x; if(t < GSL_LOG_DBL_EPSILON) { result->val = val_infinity; result->err = 2.0 * GSL_DBL_EPSILON * val_infinity; } else { const double et = exp(t); result->val = val_infinity - et; result->err = 2.0 * GSL_DBL_EPSILON * (val_infinity + (fabs(t)+1.0) * et); } return GSL_SUCCESS; } } int gsl_sf_transport_5_e(const double x, gsl_sf_result * result) { const double val_infinity = 124.4313306172043912; /* CHECK_POINTER(result) */ if(x < 0.0) { DOMAIN_ERROR(result); } else if(x == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(x < 3.0*GSL_SQRT_DBL_EPSILON) { result->val = x*x*x*x/4.0; result->err = 4.0 * GSL_DBL_EPSILON * result->val; CHECK_UNDERFLOW(result); return GSL_SUCCESS; } else if(x <= 4.0) { const double x2 = x*x; const double t = (x2/8.0 - 0.5) - 0.5; gsl_sf_result result_c; cheb_eval_e(&transport5_cs, t, &result_c); result->val = x2*x2 * result_c.val; result->err = x2*x2 * result_c.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < -GSL_LOG_DBL_EPSILON) { const int numexp = (int)((-GSL_LOG_DBL_EPSILON)/x) + 1; const double sumexp = transport_sumexp(numexp, 5, exp(-x), x); const double t = 5.0 * log(x) - x + log(sumexp); if(t < GSL_LOG_DBL_EPSILON) { result->val = val_infinity; result->err = 2.0 * GSL_DBL_EPSILON * val_infinity; } else { const double et = exp(t); result->val = val_infinity - et; result->err = 2.0 * GSL_DBL_EPSILON * (val_infinity + (fabs(t)+1.0) * et); } return GSL_SUCCESS; } else if(x < 3.0/GSL_DBL_EPSILON) { const int numexp = 1; const double sumexp = transport_sumexp(numexp, 5, 1.0, x); const double t = 5.0 * log(x) - x + log(sumexp); if(t < GSL_LOG_DBL_EPSILON) { result->val = val_infinity; result->err = 2.0 * GSL_DBL_EPSILON * val_infinity; } else { const double et = exp(t); result->val = val_infinity - et; result->err = 2.0 * GSL_DBL_EPSILON * (val_infinity + (fabs(t)+1.0) * et); } return GSL_SUCCESS; } else { const double t = 5.0 * log(x) - x; if(t < GSL_LOG_DBL_EPSILON) { result->val = val_infinity; result->err = 2.0 * GSL_DBL_EPSILON * val_infinity; } else { const double et = exp(t); result->val = val_infinity - et; result->err = 2.0 * GSL_DBL_EPSILON * (val_infinity + (fabs(t)+1.0) * et); } return GSL_SUCCESS; } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_transport_2(const double x) { EVAL_RESULT(gsl_sf_transport_2_e(x, &result)); } double gsl_sf_transport_3(const double x) { EVAL_RESULT(gsl_sf_transport_3_e(x, &result)); } double gsl_sf_transport_4(const double x) { EVAL_RESULT(gsl_sf_transport_4_e(x, &result)); } double gsl_sf_transport_5(const double x) { EVAL_RESULT(gsl_sf_transport_5_e(x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__trig.c000066400000000000000000000464561261542461700213510ustar00rootroot00000000000000/* specfunc/trig.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_log.h" #include "gsl_sf_trig.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__chebyshev.h" #include "gsl_specfunc__cheb_eval.c" /* sinh(x) series * double-precision for |x| < 1.0 */ inline static int sinh_series(const double x, double * result) { const double y = x*x; const double c0 = 1.0/6.0; const double c1 = 1.0/120.0; const double c2 = 1.0/5040.0; const double c3 = 1.0/362880.0; const double c4 = 1.0/39916800.0; const double c5 = 1.0/6227020800.0; const double c6 = 1.0/1307674368000.0; const double c7 = 1.0/355687428096000.0; *result = x*(1.0 + y*(c0+y*(c1+y*(c2+y*(c3+y*(c4+y*(c5+y*(c6+y*c7)))))))); return GSL_SUCCESS; } /* cosh(x)-1 series * double-precision for |x| < 1.0 */ inline static int cosh_m1_series(const double x, double * result) { const double y = x*x; const double c0 = 0.5; const double c1 = 1.0/24.0; const double c2 = 1.0/720.0; const double c3 = 1.0/40320.0; const double c4 = 1.0/3628800.0; const double c5 = 1.0/479001600.0; const double c6 = 1.0/87178291200.0; const double c7 = 1.0/20922789888000.0; const double c8 = 1.0/6402373705728000.0; *result = y*(c0+y*(c1+y*(c2+y*(c3+y*(c4+y*(c5+y*(c6+y*(c7+y*c8)))))))); return GSL_SUCCESS; } /* Chebyshev expansion for f(t) = sinc((t+1)/2), -1 < t < 1 */ static double sinc_data[17] = { 1.133648177811747875422, -0.532677564732557348781, -0.068293048346633177859, 0.033403684226353715020, 0.001485679893925747818, -0.000734421305768455295, -0.000016837282388837229, 0.000008359950146618018, 0.000000117382095601192, -0.000000058413665922724, -0.000000000554763755743, 0.000000000276434190426, 0.000000000001895374892, -0.000000000000945237101, -0.000000000000004900690, 0.000000000000002445383, 0.000000000000000009925 }; static cheb_series sinc_cs = { sinc_data, 16, -1, 1, 10 }; /* Chebyshev expansion for f(t) = g((t+1)Pi/8), -1val = x * (1.0 - x2/6.0); result->err = fabs(x*x2*x2 / 100.0); return GSL_SUCCESS; } else { double sgn_result = sgn_x; double y = floor(abs_x/(0.25*M_PI)); int octant = y - ldexp(floor(ldexp(y,-3)),3); int stat_cs; double z; if(GSL_IS_ODD(octant)) { octant += 1; octant &= 07; y += 1.0; } if(octant > 3) { octant -= 4; sgn_result = -sgn_result; } z = ((abs_x - y * P1) - y * P2) - y * P3; if(octant == 0) { gsl_sf_result sin_cs_result; const double t = 8.0*fabs(z)/M_PI - 1.0; stat_cs = cheb_eval_e(&sin_cs, t, &sin_cs_result); result->val = z * (1.0 + z*z * sin_cs_result.val); } else { /* octant == 2 */ gsl_sf_result cos_cs_result; const double t = 8.0*fabs(z)/M_PI - 1.0; stat_cs = cheb_eval_e(&cos_cs, t, &cos_cs_result); result->val = 1.0 - 0.5*z*z * (1.0 - z*z * cos_cs_result.val); } result->val *= sgn_result; if(abs_x > 1.0/GSL_DBL_EPSILON) { result->err = fabs(result->val); } else if(abs_x > 100.0/GSL_SQRT_DBL_EPSILON) { result->err = 2.0 * abs_x * GSL_DBL_EPSILON * fabs(result->val); } else if(abs_x > 0.1/GSL_SQRT_DBL_EPSILON) { result->err = 2.0 * GSL_SQRT_DBL_EPSILON * fabs(result->val); } else { result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); } return stat_cs; } } } int gsl_sf_cos_e(double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ { const double P1 = 7.85398125648498535156e-1; const double P2 = 3.77489470793079817668e-8; const double P3 = 2.69515142907905952645e-15; const double abs_x = fabs(x); if(abs_x < GSL_ROOT4_DBL_EPSILON) { const double x2 = x*x; result->val = 1.0 - 0.5*x2; result->err = fabs(x2*x2/12.0); return GSL_SUCCESS; } else { double sgn_result = 1.0; double y = floor(abs_x/(0.25*M_PI)); int octant = y - ldexp(floor(ldexp(y,-3)),3); int stat_cs; double z; if(GSL_IS_ODD(octant)) { octant += 1; octant &= 07; y += 1.0; } if(octant > 3) { octant -= 4; sgn_result = -sgn_result; } if(octant > 1) { sgn_result = -sgn_result; } z = ((abs_x - y * P1) - y * P2) - y * P3; if(octant == 0) { gsl_sf_result cos_cs_result; const double t = 8.0*fabs(z)/M_PI - 1.0; stat_cs = cheb_eval_e(&cos_cs, t, &cos_cs_result); result->val = 1.0 - 0.5*z*z * (1.0 - z*z * cos_cs_result.val); } else { /* octant == 2 */ gsl_sf_result sin_cs_result; const double t = 8.0*fabs(z)/M_PI - 1.0; stat_cs = cheb_eval_e(&sin_cs, t, &sin_cs_result); result->val = z * (1.0 + z*z * sin_cs_result.val); } result->val *= sgn_result; if(abs_x > 1.0/GSL_DBL_EPSILON) { result->err = fabs(result->val); } else if(abs_x > 100.0/GSL_SQRT_DBL_EPSILON) { result->err = 2.0 * abs_x * GSL_DBL_EPSILON * fabs(result->val); } else if(abs_x > 0.1/GSL_SQRT_DBL_EPSILON) { result->err = 2.0 * GSL_SQRT_DBL_EPSILON * fabs(result->val); } else { result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); } return stat_cs; } } } int gsl_sf_hypot_e(const double x, const double y, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x == 0.0 && y == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else { const double a = fabs(x); const double b = fabs(y); const double min = GSL_MIN_DBL(a,b); const double max = GSL_MAX_DBL(a,b); const double rat = min/max; const double root_term = sqrt(1.0 + rat*rat); if(max < GSL_DBL_MAX/root_term) { result->val = max * root_term; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { OVERFLOW_ERROR(result); } } } int gsl_sf_complex_sin_e(const double zr, const double zi, gsl_sf_result * szr, gsl_sf_result * szi) { /* CHECK_POINTER(szr) */ /* CHECK_POINTER(szi) */ if(fabs(zi) < 1.0) { double ch_m1, sh; sinh_series(zi, &sh); cosh_m1_series(zi, &ch_m1); szr->val = sin(zr)*(ch_m1 + 1.0); szi->val = cos(zr)*sh; szr->err = 2.0 * GSL_DBL_EPSILON * fabs(szr->val); szi->err = 2.0 * GSL_DBL_EPSILON * fabs(szi->val); return GSL_SUCCESS; } else if(fabs(zi) < GSL_LOG_DBL_MAX) { double ex = exp(zi); double ch = 0.5*(ex+1.0/ex); double sh = 0.5*(ex-1.0/ex); szr->val = sin(zr)*ch; szi->val = cos(zr)*sh; szr->err = 2.0 * GSL_DBL_EPSILON * fabs(szr->val); szi->err = 2.0 * GSL_DBL_EPSILON * fabs(szi->val); return GSL_SUCCESS; } else { OVERFLOW_ERROR_2(szr, szi); } } int gsl_sf_complex_cos_e(const double zr, const double zi, gsl_sf_result * czr, gsl_sf_result * czi) { /* CHECK_POINTER(czr) */ /* CHECK_POINTER(czi) */ if(fabs(zi) < 1.0) { double ch_m1, sh; sinh_series(zi, &sh); cosh_m1_series(zi, &ch_m1); czr->val = cos(zr)*(ch_m1 + 1.0); czi->val = -sin(zr)*sh; czr->err = 2.0 * GSL_DBL_EPSILON * fabs(czr->val); czi->err = 2.0 * GSL_DBL_EPSILON * fabs(czi->val); return GSL_SUCCESS; } else if(fabs(zi) < GSL_LOG_DBL_MAX) { double ex = exp(zi); double ch = 0.5*(ex+1.0/ex); double sh = 0.5*(ex-1.0/ex); czr->val = cos(zr)*ch; czi->val = -sin(zr)*sh; czr->err = 2.0 * GSL_DBL_EPSILON * fabs(czr->val); czi->err = 2.0 * GSL_DBL_EPSILON * fabs(czi->val); return GSL_SUCCESS; } else { OVERFLOW_ERROR_2(czr,czi); } } int gsl_sf_complex_logsin_e(const double zr, const double zi, gsl_sf_result * lszr, gsl_sf_result * lszi) { /* CHECK_POINTER(lszr) */ /* CHECK_POINTER(lszi) */ if(zi > 60.0) { lszr->val = -M_LN2 + zi; lszi->val = 0.5*M_PI - zr; lszr->err = 2.0 * GSL_DBL_EPSILON * fabs(lszr->val); lszi->err = 2.0 * GSL_DBL_EPSILON * fabs(lszi->val); } else if(zi < -60.0) { lszr->val = -M_LN2 - zi; lszi->val = -0.5*M_PI + zr; lszr->err = 2.0 * GSL_DBL_EPSILON * fabs(lszr->val); lszi->err = 2.0 * GSL_DBL_EPSILON * fabs(lszi->val); } else { gsl_sf_result sin_r, sin_i; int status; gsl_sf_complex_sin_e(zr, zi, &sin_r, &sin_i); /* ok by construction */ status = gsl_sf_complex_log_e(sin_r.val, sin_i.val, lszr, lszi); if(status == GSL_EDOM) { DOMAIN_ERROR_2(lszr, lszi); } } return gsl_sf_angle_restrict_symm_e(&(lszi->val)); } int gsl_sf_lnsinh_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= 0.0) { DOMAIN_ERROR(result); } else if(fabs(x) < 1.0) { double eps; sinh_series(x, &eps); result->val = log(eps); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < -0.5*GSL_LOG_DBL_EPSILON) { result->val = x + log(0.5*(1.0 - exp(-2.0*x))); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { result->val = -M_LN2 + x; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } int gsl_sf_lncosh_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(fabs(x) < 1.0) { double eps; cosh_m1_series(x, &eps); return gsl_sf_log_1plusx_e(eps, result); } else if(x < -0.5*GSL_LOG_DBL_EPSILON) { result->val = x + log(0.5*(1.0 + exp(-2.0*x))); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { result->val = -M_LN2 + x; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } /* inline int gsl_sf_sincos_e(const double theta, double * s, double * c) { double tan_half = tan(0.5 * theta); double den = 1. + tan_half*tan_half; double cos_theta = (1.0 - tan_half*tan_half) / den; double sin_theta = 2.0 * tan_half / den; } */ int gsl_sf_polar_to_rect(const double r, const double theta, gsl_sf_result * x, gsl_sf_result * y) { double t = theta; int status = gsl_sf_angle_restrict_symm_e(&t); double c = cos(t); double s = sin(t); x->val = r * cos(t); y->val = r * sin(t); x->err = r * fabs(s * GSL_DBL_EPSILON * t); x->err += 2.0 * GSL_DBL_EPSILON * fabs(x->val); y->err = r * fabs(c * GSL_DBL_EPSILON * t); y->err += 2.0 * GSL_DBL_EPSILON * fabs(y->val); return status; } int gsl_sf_rect_to_polar(const double x, const double y, gsl_sf_result * r, gsl_sf_result * theta) { int stat_h = gsl_sf_hypot_e(x, y, r); if(r->val > 0.0) { theta->val = atan2(y, x); theta->err = 2.0 * GSL_DBL_EPSILON * fabs(theta->val); return stat_h; } else { DOMAIN_ERROR(theta); } } int gsl_sf_angle_restrict_symm_err_e(const double theta, gsl_sf_result * result) { /* synthetic extended precision constants */ const double P1 = 4 * 7.8539812564849853515625e-01; const double P2 = 4 * 3.7748947079307981766760e-08; const double P3 = 4 * 2.6951514290790594840552e-15; const double TwoPi = 2*(P1 + P2 + P3); const double y = GSL_SIGN(theta) * 2 * floor(fabs(theta)/TwoPi); double r = ((theta - y*P1) - y*P2) - y*P3; if(r > M_PI) { r = (((r-2*P1)-2*P2)-2*P3); } /* r-TwoPi */ else if (r < -M_PI) r = (((r+2*P1)+2*P2)+2*P3); /* r+TwoPi */ result->val = r; if(fabs(theta) > 0.0625/GSL_DBL_EPSILON) { result->val = GSL_NAN; result->err = GSL_NAN; GSL_ERROR ("error", GSL_ELOSS); } else if(fabs(theta) > 0.0625/GSL_SQRT_DBL_EPSILON) { result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val - theta); return GSL_SUCCESS; } else { double delta = fabs(result->val - theta); result->err = 2.0 * GSL_DBL_EPSILON * ((delta < M_PI) ? delta : M_PI); return GSL_SUCCESS; } } int gsl_sf_angle_restrict_pos_err_e(const double theta, gsl_sf_result * result) { /* synthetic extended precision constants */ const double P1 = 4 * 7.85398125648498535156e-01; const double P2 = 4 * 3.77489470793079817668e-08; const double P3 = 4 * 2.69515142907905952645e-15; const double TwoPi = 2*(P1 + P2 + P3); const double y = 2*floor(theta/TwoPi); double r = ((theta - y*P1) - y*P2) - y*P3; if(r > TwoPi) {r = (((r-2*P1)-2*P2)-2*P3); } /* r-TwoPi */ else if (r < 0) { /* may happen due to FP rounding */ r = (((r+2*P1)+2*P2)+2*P3); /* r+TwoPi */ } result->val = r; if(fabs(theta) > 0.0625/GSL_DBL_EPSILON) { result->val = GSL_NAN; result->err = fabs(result->val); GSL_ERROR ("error", GSL_ELOSS); } else if(fabs(theta) > 0.0625/GSL_SQRT_DBL_EPSILON) { result->err = GSL_DBL_EPSILON * fabs(result->val - theta); return GSL_SUCCESS; } else { double delta = fabs(result->val - theta); result->err = 2.0 * GSL_DBL_EPSILON * ((delta < M_PI) ? delta : M_PI); return GSL_SUCCESS; } } int gsl_sf_angle_restrict_symm_e(double * theta) { gsl_sf_result r; int stat = gsl_sf_angle_restrict_symm_err_e(*theta, &r); *theta = r.val; return stat; } int gsl_sf_angle_restrict_pos_e(double * theta) { gsl_sf_result r; int stat = gsl_sf_angle_restrict_pos_err_e(*theta, &r); *theta = r.val; return stat; } int gsl_sf_sin_err_e(const double x, const double dx, gsl_sf_result * result) { int stat_s = gsl_sf_sin_e(x, result); result->err += fabs(cos(x) * dx); result->err += GSL_DBL_EPSILON * fabs(result->val); return stat_s; } int gsl_sf_cos_err_e(const double x, const double dx, gsl_sf_result * result) { int stat_c = gsl_sf_cos_e(x, result); result->err += fabs(sin(x) * dx); result->err += GSL_DBL_EPSILON * fabs(result->val); return stat_c; } #if 0 int gsl_sf_sin_pi_x_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(-100.0 < x && x < 100.0) { result->val = sin(M_PI * x) / (M_PI * x); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { const double N = floor(x + 0.5); const double f = x - N; if(N < INT_MAX && N > INT_MIN) { /* Make it an integer if we can. Saves another * call to floor(). */ const int intN = (int)N; const double sign = ( GSL_IS_ODD(intN) ? -1.0 : 1.0 ); result->val = sign * sin(M_PI * f); result->err = GSL_DBL_EPSILON * fabs(result->val); } else if(N > 2.0/GSL_DBL_EPSILON || N < -2.0/GSL_DBL_EPSILON) { /* All integer-valued floating point numbers * bigger than 2/eps=2^53 are actually even. */ result->val = 0.0; result->err = 0.0; } else { const double resN = N - 2.0*floor(0.5*N); /* 0 for even N, 1 for odd N */ const double sign = ( fabs(resN) > 0.5 ? -1.0 : 1.0 ); result->val = sign * sin(M_PI*f); result->err = GSL_DBL_EPSILON * fabs(result->val); } return GSL_SUCCESS; } } #endif int gsl_sf_sinc_e(double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ { const double ax = fabs(x); if(ax < 0.8) { /* Do not go to the limit of the fit since * there is a zero there and the Chebyshev * accuracy will go to zero. */ return cheb_eval_e(&sinc_cs, 2.0*ax-1.0, result); } else if(ax < 100.0) { /* Small arguments are no problem. * We trust the library sin() to * roughly machine precision. */ result->val = sin(M_PI * ax)/(M_PI * ax); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { /* Large arguments must be handled separately. */ const double r = M_PI*ax; gsl_sf_result s; int stat_s = gsl_sf_sin_e(r, &s); result->val = s.val/r; result->err = s.err/r + 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_s; } } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_sin(const double x) { EVAL_RESULT(gsl_sf_sin_e(x, &result)); } double gsl_sf_cos(const double x) { EVAL_RESULT(gsl_sf_cos_e(x, &result)); } double gsl_sf_hypot(const double x, const double y) { EVAL_RESULT(gsl_sf_hypot_e(x, y, &result)); } double gsl_sf_lnsinh(const double x) { EVAL_RESULT(gsl_sf_lnsinh_e(x, &result)); } double gsl_sf_lncosh(const double x) { EVAL_RESULT(gsl_sf_lncosh_e(x, &result)); } double gsl_sf_angle_restrict_symm(const double theta) { double result = theta; EVAL_DOUBLE(gsl_sf_angle_restrict_symm_e(&result)); } double gsl_sf_angle_restrict_pos(const double theta) { double result = theta; EVAL_DOUBLE(gsl_sf_angle_restrict_pos_e(&result)); } #if 0 double gsl_sf_sin_pi_x(const double x) { EVAL_RESULT(gsl_sf_sin_pi_x_e(x, &result)); } #endif double gsl_sf_sinc(const double x) { EVAL_RESULT(gsl_sf_sinc_e(x, &result)); } praat-6.0.04/external/gsl/gsl_specfunc__zeta.c000066400000000000000000001010211261542461700213230ustar00rootroot00000000000000/* specfunc/zeta.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sf_elementary.h" #include "gsl_sf_exp.h" #include "gsl_sf_gamma.h" #include "gsl_sf_pow_int.h" #include "gsl_sf_zeta.h" #include "gsl_specfunc__error.h" #include "gsl_specfunc__chebyshev.h" #include "gsl_specfunc__cheb_eval.c" #define LogTwoPi_ 1.8378770664093454835606594728111235279723 /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/ /* chebyshev fit for (s(t)-1)Zeta[s(t)] * s(t)= (t+1)/2 * -1 <= t <= 1 */ static double zeta_xlt1_data[14] = { 1.48018677156931561235192914649, 0.25012062539889426471999938167, 0.00991137502135360774243761467, -0.00012084759656676410329833091, -4.7585866367662556504652535281e-06, 2.2229946694466391855561441361e-07, -2.2237496498030257121309056582e-09, -1.0173226513229028319420799028e-10, 4.3756643450424558284466248449e-12, -6.2229632593100551465504090814e-14, -6.6116201003272207115277520305e-16, 4.9477279533373912324518463830e-17, -1.0429819093456189719660003522e-18, 6.9925216166580021051464412040e-21, }; static cheb_series zeta_xlt1_cs = { zeta_xlt1_data, 13, -1, 1, 8 }; /* chebyshev fit for (s(t)-1)Zeta[s(t)] * s(t)= (19t+21)/2 * -1 <= t <= 1 */ static double zeta_xgt1_data[30] = { 19.3918515726724119415911269006, 9.1525329692510756181581271500, 0.2427897658867379985365270155, -0.1339000688262027338316641329, 0.0577827064065028595578410202, -0.0187625983754002298566409700, 0.0039403014258320354840823803, -0.0000581508273158127963598882, -0.0003756148907214820704594549, 0.0001892530548109214349092999, -0.0000549032199695513496115090, 8.7086484008939038610413331863e-6, 6.4609477924811889068410083425e-7, -9.6749773915059089205835337136e-7, 3.6585400766767257736982342461e-7, -8.4592516427275164351876072573e-8, 9.9956786144497936572288988883e-9, 1.4260036420951118112457144842e-9, -1.1761968823382879195380320948e-9, 3.7114575899785204664648987295e-10, -7.4756855194210961661210215325e-11, 7.8536934209183700456512982968e-12, 9.9827182259685539619810406271e-13, -7.5276687030192221587850302453e-13, 2.1955026393964279988917878654e-13, -4.1934859852834647427576319246e-14, 4.6341149635933550715779074274e-15, 2.3742488509048340106830309402e-16, -2.7276516388124786119323824391e-16, 7.8473570134636044722154797225e-17 }; static cheb_series zeta_xgt1_cs = { zeta_xgt1_data, 29, -1, 1, 17 }; /* chebyshev fit for Ln[Zeta[s(t)] - 1 - 2^(-s(t))] * s(t)= 10 + 5t * -1 <= t <= 1; 5 <= s <= 15 */ static double zetam1_inter_data[24] = { -21.7509435653088483422022339374, -5.63036877698121782876372020472, 0.0528041358684229425504861579635, -0.0156381809179670789342700883562, 0.00408218474372355881195080781927, -0.0010264867349474874045036628282, 0.000260469880409886900143834962387, -0.0000676175847209968878098566819447, 0.0000179284472587833525426660171124, -4.83238651318556188834107605116e-6, 1.31913788964999288471371329447e-6, -3.63760500656329972578222188542e-7, 1.01146847513194744989748396574e-7, -2.83215225141806501619105289509e-8, 7.97733710252021423361012829496e-9, -2.25850168553956886676250696891e-9, 6.42269392950164306086395744145e-10, -1.83363861846127284505060843614e-10, 5.25309763895283179960368072104e-11, -1.50958687042589821074710575446e-11, 4.34997545516049244697776942981e-12, -1.25597782748190416118082322061e-12, 3.61280740072222650030134104162e-13, -9.66437239205745207188920348801e-14 }; static cheb_series zetam1_inter_cs = { zetam1_inter_data, 22, -1, 1, 12 }; /* assumes s >= 0 and s != 1.0 */ inline static int riemann_zeta_sgt0(double s, gsl_sf_result * result) { if(s < 1.0) { gsl_sf_result c; cheb_eval_e(&zeta_xlt1_cs, 2.0*s - 1.0, &c); result->val = c.val / (s - 1.0); result->err = c.err / fabs(s-1.0) + GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(s <= 20.0) { double x = (2.0*s - 21.0)/19.0; gsl_sf_result c; cheb_eval_e(&zeta_xgt1_cs, x, &c); result->val = c.val / (s - 1.0); result->err = c.err / (s - 1.0) + GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { double f2 = 1.0 - pow(2.0,-s); double f3 = 1.0 - pow(3.0,-s); double f5 = 1.0 - pow(5.0,-s); double f7 = 1.0 - pow(7.0,-s); result->val = 1.0/(f2*f3*f5*f7); result->err = 3.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } inline static int riemann_zeta1ms_slt0(double s, gsl_sf_result * result) { if(s > -19.0) { double x = (-19 - 2.0*s)/19.0; gsl_sf_result c; cheb_eval_e(&zeta_xgt1_cs, x, &c); result->val = c.val / (-s); result->err = c.err / (-s) + GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { double f2 = 1.0 - pow(2.0,-(1.0-s)); double f3 = 1.0 - pow(3.0,-(1.0-s)); double f5 = 1.0 - pow(5.0,-(1.0-s)); double f7 = 1.0 - pow(7.0,-(1.0-s)); result->val = 1.0/(f2*f3*f5*f7); result->err = 3.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } /* works for 5 < s < 15*/ static int riemann_zeta_minus_1_intermediate_s(double s, gsl_sf_result * result) { double t = (s - 10.0)/5.0; gsl_sf_result c; cheb_eval_e(&zetam1_inter_cs, t, &c); result->val = exp(c.val) + pow(2.0, -s); result->err = (c.err + 2.0*GSL_DBL_EPSILON)*result->val; return GSL_SUCCESS; } /* assumes s is large and positive * write: zeta(s) - 1 = zeta(s) * (1 - 1/zeta(s)) * and expand a few terms of the product formula to evaluate 1 - 1/zeta(s) * * works well for s > 15 */ static int riemann_zeta_minus1_large_s(double s, gsl_sf_result * result) { double a = pow( 2.0,-s); double b = pow( 3.0,-s); double c = pow( 5.0,-s); double d = pow( 7.0,-s); double e = pow(11.0,-s); double f = pow(13.0,-s); double t1 = a + b + c + d + e + f; double t2 = a*(b+c+d+e+f) + b*(c+d+e+f) + c*(d+e+f) + d*(e+f) + e*f; /* double t3 = a*(b*(c+d+e+f) + c*(d+e+f) + d*(e+f) + e*f) + b*(c*(d+e+f) + d*(e+f) + e*f) + c*(d*(e+f) + e*f) + d*e*f; double t4 = a*(b*(c*(d + e + f) + d*(e + f) + e*f) + c*(d*(e+f) + e*f) + d*e*f) + b*(c*(d*(e+f) + e*f) + d*e*f) + c*d*e*f; double t5 = b*c*d*e*f + a*c*d*e*f+ a*b*d*e*f+ a*b*c*e*f+ a*b*c*d*f+ a*b*c*d*e; double t6 = a*b*c*d*e*f; */ double numt = t1 - t2 /* + t3 - t4 + t5 - t6 */; double zeta = 1.0/((1.0-a)*(1.0-b)*(1.0-c)*(1.0-d)*(1.0-e)*(1.0-f)); result->val = numt*zeta; result->err = (15.0/s + 1.0) * 6.0*GSL_DBL_EPSILON*result->val; return GSL_SUCCESS; } #if 0 /* zeta(n) */ #define ZETA_POS_TABLE_NMAX 100 static double zeta_pos_int_table_OLD[ZETA_POS_TABLE_NMAX+1] = { -0.50000000000000000000000000000, /* zeta(0) */ 0.0 /* FIXME: DirectedInfinity() */, /* zeta(1) */ 1.64493406684822643647241516665, /* ... */ 1.20205690315959428539973816151, 1.08232323371113819151600369654, 1.03692775514336992633136548646, 1.01734306198444913971451792979, 1.00834927738192282683979754985, 1.00407735619794433937868523851, 1.00200839282608221441785276923, 1.00099457512781808533714595890, 1.00049418860411946455870228253, 1.00024608655330804829863799805, 1.00012271334757848914675183653, 1.00006124813505870482925854511, 1.00003058823630702049355172851, 1.00001528225940865187173257149, 1.00000763719763789976227360029, 1.00000381729326499983985646164, 1.00000190821271655393892565696, 1.00000095396203387279611315204, 1.00000047693298678780646311672, 1.00000023845050272773299000365, 1.00000011921992596531107306779, 1.00000005960818905125947961244, 1.00000002980350351465228018606, 1.00000001490155482836504123466, 1.00000000745071178983542949198, 1.00000000372533402478845705482, 1.00000000186265972351304900640, 1.00000000093132743241966818287, 1.00000000046566290650337840730, 1.00000000023283118336765054920, 1.00000000011641550172700519776, 1.00000000005820772087902700889, 1.00000000002910385044497099687, 1.00000000001455192189104198424, 1.00000000000727595983505748101, 1.00000000000363797954737865119, 1.00000000000181898965030706595, 1.00000000000090949478402638893, 1.00000000000045474737830421540, 1.00000000000022737368458246525, 1.00000000000011368684076802278, 1.00000000000005684341987627586, 1.00000000000002842170976889302, 1.00000000000001421085482803161, 1.00000000000000710542739521085, 1.00000000000000355271369133711, 1.00000000000000177635684357912, 1.00000000000000088817842109308, 1.00000000000000044408921031438, 1.00000000000000022204460507980, 1.00000000000000011102230251411, 1.00000000000000005551115124845, 1.00000000000000002775557562136, 1.00000000000000001387778780973, 1.00000000000000000693889390454, 1.00000000000000000346944695217, 1.00000000000000000173472347605, 1.00000000000000000086736173801, 1.00000000000000000043368086900, 1.00000000000000000021684043450, 1.00000000000000000010842021725, 1.00000000000000000005421010862, 1.00000000000000000002710505431, 1.00000000000000000001355252716, 1.00000000000000000000677626358, 1.00000000000000000000338813179, 1.00000000000000000000169406589, 1.00000000000000000000084703295, 1.00000000000000000000042351647, 1.00000000000000000000021175824, 1.00000000000000000000010587912, 1.00000000000000000000005293956, 1.00000000000000000000002646978, 1.00000000000000000000001323489, 1.00000000000000000000000661744, 1.00000000000000000000000330872, 1.00000000000000000000000165436, 1.00000000000000000000000082718, 1.00000000000000000000000041359, 1.00000000000000000000000020680, 1.00000000000000000000000010340, 1.00000000000000000000000005170, 1.00000000000000000000000002585, 1.00000000000000000000000001292, 1.00000000000000000000000000646, 1.00000000000000000000000000323, 1.00000000000000000000000000162, 1.00000000000000000000000000081, 1.00000000000000000000000000040, 1.00000000000000000000000000020, 1.00000000000000000000000000010, 1.00000000000000000000000000005, 1.00000000000000000000000000003, 1.00000000000000000000000000001, 1.00000000000000000000000000001, 1.00000000000000000000000000000, 1.00000000000000000000000000000, 1.00000000000000000000000000000 }; #endif /* 0 */ /* zeta(n) - 1 */ #define ZETA_POS_TABLE_NMAX 100 static double zetam1_pos_int_table[ZETA_POS_TABLE_NMAX+1] = { -1.5, /* zeta(0) */ 0.0, /* FIXME: Infinity */ /* zeta(1) - 1 */ 0.644934066848226436472415166646, /* zeta(2) - 1 */ 0.202056903159594285399738161511, 0.082323233711138191516003696541, 0.036927755143369926331365486457, 0.017343061984449139714517929790, 0.008349277381922826839797549849, 0.004077356197944339378685238508, 0.002008392826082214417852769232, 0.000994575127818085337145958900, 0.000494188604119464558702282526, 0.000246086553308048298637998047, 0.000122713347578489146751836526, 0.000061248135058704829258545105, 0.000030588236307020493551728510, 0.000015282259408651871732571487, 7.6371976378997622736002935630e-6, 3.8172932649998398564616446219e-6, 1.9082127165539389256569577951e-6, 9.5396203387279611315203868344e-7, 4.7693298678780646311671960437e-7, 2.3845050272773299000364818675e-7, 1.1921992596531107306778871888e-7, 5.9608189051259479612440207935e-8, 2.9803503514652280186063705069e-8, 1.4901554828365041234658506630e-8, 7.4507117898354294919810041706e-9, 3.7253340247884570548192040184e-9, 1.8626597235130490064039099454e-9, 9.3132743241966818287176473502e-10, 4.6566290650337840729892332512e-10, 2.3283118336765054920014559759e-10, 1.1641550172700519775929738354e-10, 5.8207720879027008892436859891e-11, 2.9103850444970996869294252278e-11, 1.4551921891041984235929632245e-11, 7.2759598350574810145208690123e-12, 3.6379795473786511902372363558e-12, 1.8189896503070659475848321007e-12, 9.0949478402638892825331183869e-13, 4.5474737830421540267991120294e-13, 2.2737368458246525152268215779e-13, 1.1368684076802278493491048380e-13, 5.6843419876275856092771829675e-14, 2.8421709768893018554550737049e-14, 1.4210854828031606769834307141e-14, 7.1054273952108527128773544799e-15, 3.5527136913371136732984695340e-15, 1.7763568435791203274733490144e-15, 8.8817842109308159030960913863e-16, 4.4408921031438133641977709402e-16, 2.2204460507980419839993200942e-16, 1.1102230251410661337205445699e-16, 5.5511151248454812437237365905e-17, 2.7755575621361241725816324538e-17, 1.3877787809725232762839094906e-17, 6.9388939045441536974460853262e-18, 3.4694469521659226247442714961e-18, 1.7347234760475765720489729699e-18, 8.6736173801199337283420550673e-19, 4.3368086900206504874970235659e-19, 2.1684043449972197850139101683e-19, 1.0842021724942414063012711165e-19, 5.4210108624566454109187004043e-20, 2.7105054312234688319546213119e-20, 1.3552527156101164581485233996e-20, 6.7762635780451890979952987415e-21, 3.3881317890207968180857031004e-21, 1.6940658945097991654064927471e-21, 8.4703294725469983482469926091e-22, 4.2351647362728333478622704833e-22, 2.1175823681361947318442094398e-22, 1.0587911840680233852265001539e-22, 5.2939559203398703238139123029e-23, 2.6469779601698529611341166842e-23, 1.3234889800848990803094510250e-23, 6.6174449004244040673552453323e-24, 3.3087224502121715889469563843e-24, 1.6543612251060756462299236771e-24, 8.2718061255303444036711056167e-25, 4.1359030627651609260093824555e-25, 2.0679515313825767043959679193e-25, 1.0339757656912870993284095591e-25, 5.1698788284564313204101332166e-26, 2.5849394142282142681277617708e-26, 1.2924697071141066700381126118e-26, 6.4623485355705318034380021611e-27, 3.2311742677852653861348141180e-27, 1.6155871338926325212060114057e-27, 8.0779356694631620331587381863e-28, 4.0389678347315808256222628129e-28, 2.0194839173657903491587626465e-28, 1.0097419586828951533619250700e-28, 5.0487097934144756960847711725e-29, 2.5243548967072378244674341938e-29, 1.2621774483536189043753999660e-29, 6.3108872417680944956826093943e-30, 3.1554436208840472391098412184e-30, 1.5777218104420236166444327830e-30, 7.8886090522101180735205378276e-31 }; #define ZETA_NEG_TABLE_NMAX 99 #define ZETA_NEG_TABLE_SIZE 50 static double zeta_neg_int_table[ZETA_NEG_TABLE_SIZE] = { -0.083333333333333333333333333333, /* zeta(-1) */ 0.008333333333333333333333333333, /* zeta(-3) */ -0.003968253968253968253968253968, /* ... */ 0.004166666666666666666666666667, -0.007575757575757575757575757576, 0.021092796092796092796092796093, -0.083333333333333333333333333333, 0.44325980392156862745098039216, -3.05395433027011974380395433027, 26.4562121212121212121212121212, -281.460144927536231884057971014, 3607.5105463980463980463980464, -54827.583333333333333333333333, 974936.82385057471264367816092, -2.0052695796688078946143462272e+07, 4.7238486772162990196078431373e+08, -1.2635724795916666666666666667e+10, 3.8087931125245368811553022079e+11, -1.2850850499305083333333333333e+13, 4.8241448354850170371581670362e+14, -2.0040310656516252738108421663e+16, 9.1677436031953307756992753623e+17, -4.5979888343656503490437943262e+19, 2.5180471921451095697089023320e+21, -1.5001733492153928733711440151e+23, 9.6899578874635940656497942895e+24, -6.7645882379292820990945242302e+26, 5.0890659468662289689766332916e+28, -4.1147288792557978697665486068e+30, 3.5666582095375556109684574609e+32, -3.3066089876577576725680214670e+34, 3.2715634236478716264211227016e+36, -3.4473782558278053878256455080e+38, 3.8614279832705258893092720200e+40, -4.5892974432454332168863989006e+42, 5.7775386342770431824884825688e+44, -7.6919858759507135167410075972e+46, 1.0813635449971654696354033351e+49, -1.6029364522008965406067102346e+51, 2.5019479041560462843656661499e+53, -4.1067052335810212479752045004e+55, 7.0798774408494580617452972433e+57, -1.2804546887939508790190849756e+60, 2.4267340392333524078020892067e+62, -4.8143218874045769355129570066e+64, 9.9875574175727530680652777408e+66, -2.1645634868435185631335136160e+69, 4.8962327039620553206849224516e+71, /* ... */ -1.1549023923963519663954271692e+74, /* zeta(-97) */ 2.8382249570693706959264156336e+76 /* zeta(-99) */ }; /* coefficients for Maclaurin summation in hzeta() * B_{2j}/(2j)! */ static double hzeta_c[15] = { 1.00000000000000000000000000000, 0.083333333333333333333333333333, -0.00138888888888888888888888888889, 0.000033068783068783068783068783069, -8.2671957671957671957671957672e-07, 2.0876756987868098979210090321e-08, -5.2841901386874931848476822022e-10, 1.3382536530684678832826980975e-11, -3.3896802963225828668301953912e-13, 8.5860620562778445641359054504e-15, -2.1748686985580618730415164239e-16, 5.5090028283602295152026526089e-18, -1.3954464685812523340707686264e-19, 3.5347070396294674716932299778e-21, -8.9535174270375468504026113181e-23 }; #define ETA_POS_TABLE_NMAX 100 static double eta_pos_int_table[ETA_POS_TABLE_NMAX+1] = { 0.50000000000000000000000000000, /* eta(0) */ M_LN2, /* eta(1) */ 0.82246703342411321823620758332, /* ... */ 0.90154267736969571404980362113, 0.94703282949724591757650323447, 0.97211977044690930593565514355, 0.98555109129743510409843924448, 0.99259381992283028267042571313, 0.99623300185264789922728926008, 0.99809429754160533076778303185, 0.99903950759827156563922184570, 0.99951714349806075414409417483, 0.99975768514385819085317967871, 0.99987854276326511549217499282, 0.99993917034597971817095419226, 0.99996955121309923808263293263, 0.99998476421490610644168277496, 0.99999237829204101197693787224, 0.99999618786961011347968922641, 0.99999809350817167510685649297, 0.99999904661158152211505084256, 0.99999952325821554281631666433, 0.99999976161323082254789720494, 0.99999988080131843950322382485, 0.99999994039889239462836140314, 0.99999997019885696283441513311, 0.99999998509923199656878766181, 0.99999999254955048496351585274, 0.99999999627475340010872752767, 0.99999999813736941811218674656, 0.99999999906868228145397862728, 0.99999999953434033145421751469, 0.99999999976716989595149082282, 0.99999999988358485804603047265, 0.99999999994179239904531592388, 0.99999999997089618952980952258, 0.99999999998544809143388476396, 0.99999999999272404460658475006, 0.99999999999636202193316875550, 0.99999999999818101084320873555, 0.99999999999909050538047887809, 0.99999999999954525267653087357, 0.99999999999977262633369589773, 0.99999999999988631316532476488, 0.99999999999994315658215465336, 0.99999999999997157829090808339, 0.99999999999998578914539762720, 0.99999999999999289457268000875, 0.99999999999999644728633373609, 0.99999999999999822364316477861, 0.99999999999999911182158169283, 0.99999999999999955591079061426, 0.99999999999999977795539522974, 0.99999999999999988897769758908, 0.99999999999999994448884878594, 0.99999999999999997224442439010, 0.99999999999999998612221219410, 0.99999999999999999306110609673, 0.99999999999999999653055304826, 0.99999999999999999826527652409, 0.99999999999999999913263826204, 0.99999999999999999956631913101, 0.99999999999999999978315956551, 0.99999999999999999989157978275, 0.99999999999999999994578989138, 0.99999999999999999997289494569, 0.99999999999999999998644747284, 0.99999999999999999999322373642, 0.99999999999999999999661186821, 0.99999999999999999999830593411, 0.99999999999999999999915296705, 0.99999999999999999999957648353, 0.99999999999999999999978824176, 0.99999999999999999999989412088, 0.99999999999999999999994706044, 0.99999999999999999999997353022, 0.99999999999999999999998676511, 0.99999999999999999999999338256, 0.99999999999999999999999669128, 0.99999999999999999999999834564, 0.99999999999999999999999917282, 0.99999999999999999999999958641, 0.99999999999999999999999979320, 0.99999999999999999999999989660, 0.99999999999999999999999994830, 0.99999999999999999999999997415, 0.99999999999999999999999998708, 0.99999999999999999999999999354, 0.99999999999999999999999999677, 0.99999999999999999999999999838, 0.99999999999999999999999999919, 0.99999999999999999999999999960, 0.99999999999999999999999999980, 0.99999999999999999999999999990, 0.99999999999999999999999999995, 0.99999999999999999999999999997, 0.99999999999999999999999999999, 0.99999999999999999999999999999, 1.00000000000000000000000000000, 1.00000000000000000000000000000, 1.00000000000000000000000000000, }; #define ETA_NEG_TABLE_NMAX 99 #define ETA_NEG_TABLE_SIZE 50 static double eta_neg_int_table[ETA_NEG_TABLE_SIZE] = { 0.25000000000000000000000000000, /* eta(-1) */ -0.12500000000000000000000000000, /* eta(-3) */ 0.25000000000000000000000000000, /* ... */ -1.06250000000000000000000000000, 7.75000000000000000000000000000, -86.3750000000000000000000000000, 1365.25000000000000000000000000, -29049.0312500000000000000000000, 800572.750000000000000000000000, -2.7741322625000000000000000000e+7, 1.1805291302500000000000000000e+9, -6.0523980051687500000000000000e+10, 3.6794167785377500000000000000e+12, -2.6170760990658387500000000000e+14, 2.1531418140800295250000000000e+16, -2.0288775575173015930156250000e+18, 2.1708009902623770590275000000e+20, -2.6173826968455814932120125000e+22, 3.5324148876863877826668602500e+24, -5.3042033406864906641493838981e+26, 8.8138218364311576767253114668e+28, -1.6128065107490778547354654864e+31, 3.2355470001722734208527794569e+33, -7.0876727476537493198506645215e+35, 1.6890450341293965779175629389e+38, -4.3639690731216831157655651358e+40, 1.2185998827061261322605065672e+43, -3.6670584803153006180101262324e+45, 1.1859898526302099104271449748e+48, -4.1120769493584015047981746438e+50, 1.5249042436787620309090168687e+53, -6.0349693196941307074572991901e+55, 2.5437161764210695823197691519e+58, -1.1396923802632287851130360170e+61, 5.4180861064753979196802726455e+63, -2.7283654799994373847287197104e+66, 1.4529750514918543238511171663e+69, -8.1705519371067450079777183386e+71, 4.8445781606678367790247757259e+74, -3.0246694206649519336179448018e+77, 1.9858807961690493054169047970e+80, -1.3694474620720086994386818232e+83, 9.9070382984295807826303785989e+85, -7.5103780796592645925968460677e+88, 5.9598418264260880840077992227e+91, -4.9455988887500020399263196307e+94, 4.2873596927020241277675775935e+97, -3.8791952037716162900707994047e+100, 3.6600317773156342245401829308e+103, -3.5978775704117283875784869570e+106 /* eta(-99) */ }; /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/ int gsl_sf_hzeta_e(const double s, const double q, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(s <= 1.0 || q <= 0.0) { DOMAIN_ERROR(result); } else { const double max_bits = 54.0; const double ln_term0 = -s * log(q); if(ln_term0 < GSL_LOG_DBL_MIN + 1.0) { UNDERFLOW_ERROR(result); } else if(ln_term0 > GSL_LOG_DBL_MAX - 1.0) { OVERFLOW_ERROR (result); } else if((s > max_bits && q < 1.0) || (s > 0.5*max_bits && q < 0.25)) { result->val = pow(q, -s); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(s > 0.5*max_bits && q < 1.0) { const double p1 = pow(q, -s); const double p2 = pow(q/(1.0+q), s); const double p3 = pow(q/(2.0+q), s); result->val = p1 * (1.0 + p2 + p3); result->err = GSL_DBL_EPSILON * (0.5*s + 2.0) * fabs(result->val); return GSL_SUCCESS; } else { /* Euler-Maclaurin summation formula * [Moshier, p. 400, with several typo corrections] */ const int jmax = 12; const int kmax = 10; int j, k; const double pmax = pow(kmax + q, -s); double scp = s; double pcp = pmax / (kmax + q); double ans = pmax*((kmax+q)/(s-1.0) + 0.5); for(k=0; kval = ans; result->err = 2.0 * (jmax + 1.0) * GSL_DBL_EPSILON * fabs(ans); return GSL_SUCCESS; } } } int gsl_sf_zeta_e(const double s, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(s == 1.0) { DOMAIN_ERROR(result); } else if(s >= 0.0) { return riemann_zeta_sgt0(s, result); } else { /* reflection formula, [Abramowitz+Stegun, 23.2.5] */ gsl_sf_result zeta_one_minus_s; const int stat_zoms = riemann_zeta1ms_slt0(s, &zeta_one_minus_s); const double sin_term = (fmod(s,2.0) == 0.0) ? 0.0 : sin(0.5*M_PI*fmod(s,4.0))/M_PI; if(sin_term == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(s > -170) { /* We have to be careful about losing digits * in calculating pow(2 Pi, s). The gamma * function is fine because we were careful * with that implementation. * We keep an array of (2 Pi)^(10 n). */ const double twopi_pow[18] = { 1.0, 9.589560061550901348e+007, 9.195966217409212684e+015, 8.818527036583869903e+023, 8.456579467173150313e+031, 8.109487671573504384e+039, 7.776641909496069036e+047, 7.457457466828644277e+055, 7.151373628461452286e+063, 6.857852693272229709e+071, 6.576379029540265771e+079, 6.306458169130020789e+087, 6.047615938853066678e+095, 5.799397627482402614e+103, 5.561367186955830005e+111, 5.333106466365131227e+119, 5.114214477385391780e+127, 4.904306689854036836e+135 }; const int n = floor((-s)/10.0); const double fs = s + 10.0*n; const double p = pow(2.0*M_PI, fs) / twopi_pow[n]; gsl_sf_result g; const int stat_g = gsl_sf_gamma_e(1.0-s, &g); result->val = p * g.val * sin_term * zeta_one_minus_s.val; result->err = fabs(p * g.val * sin_term) * zeta_one_minus_s.err; result->err += fabs(p * sin_term * zeta_one_minus_s.val) * g.err; result->err += GSL_DBL_EPSILON * (fabs(s)+2.0) * fabs(result->val); return GSL_ERROR_SELECT_2(stat_g, stat_zoms); } else { /* The actual zeta function may or may not * overflow here. But we have no easy way * to calculate it when the prefactor(s) * overflow. Trying to use log's and exp * is no good because we loose a couple * digits to the exp error amplification. * When we gather a little more patience, * we can implement something here. Until * then just give up. */ OVERFLOW_ERROR(result); } } } int gsl_sf_zeta_int_e(const int n, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(n < 0) { if(!GSL_IS_ODD(n)) { result->val = 0.0; /* exactly zero at even negative integers */ result->err = 0.0; return GSL_SUCCESS; } else if(n > -ZETA_NEG_TABLE_NMAX) { result->val = zeta_neg_int_table[-(n+1)/2]; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { return gsl_sf_zeta_e((double)n, result); } } else if(n == 1){ DOMAIN_ERROR(result); } else if(n <= ZETA_POS_TABLE_NMAX){ result->val = 1.0 + zetam1_pos_int_table[n]; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { result->val = 1.0; result->err = GSL_DBL_EPSILON; return GSL_SUCCESS; } } int gsl_sf_zetam1_e(const double s, gsl_sf_result * result) { if(s <= 5.0) { int stat = gsl_sf_zeta_e(s, result); result->val = result->val - 1.0; return stat; } else if(s < 15.0) { return riemann_zeta_minus_1_intermediate_s(s, result); } else { return riemann_zeta_minus1_large_s(s, result); } } int gsl_sf_zetam1_int_e(const int n, gsl_sf_result * result) { if(n < 0) { if(!GSL_IS_ODD(n)) { result->val = -1.0; /* at even negative integers zetam1 == -1 since zeta is exactly zero */ result->err = 0.0; return GSL_SUCCESS; } else if(n > -ZETA_NEG_TABLE_NMAX) { result->val = zeta_neg_int_table[-(n+1)/2] - 1.0; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { /* could use gsl_sf_zetam1_e here but subtracting 1 makes no difference for such large values, so go straight to the result */ return gsl_sf_zeta_e((double)n, result); } } else if(n == 1){ DOMAIN_ERROR(result); } else if(n <= ZETA_POS_TABLE_NMAX){ result->val = zetam1_pos_int_table[n]; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { return gsl_sf_zetam1_e(n, result); } } int gsl_sf_eta_int_e(int n, gsl_sf_result * result) { if(n > ETA_POS_TABLE_NMAX) { result->val = 1.0; result->err = GSL_DBL_EPSILON; return GSL_SUCCESS; } else if(n >= 0) { result->val = eta_pos_int_table[n]; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { /* n < 0 */ if(!GSL_IS_ODD(n)) { /* exactly zero at even negative integers */ result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(n > -ETA_NEG_TABLE_NMAX) { result->val = eta_neg_int_table[-(n+1)/2]; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { gsl_sf_result z; gsl_sf_result p; int stat_z = gsl_sf_zeta_int_e(n, &z); int stat_p = gsl_sf_exp_e((1.0-n)*M_LN2, &p); int stat_m = gsl_sf_multiply_e(-p.val, z.val, result); result->err = fabs(p.err * (M_LN2*(1.0-n)) * z.val) + z.err * fabs(p.val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_3(stat_m, stat_p, stat_z); } } } int gsl_sf_eta_e(const double s, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(s > 100.0) { result->val = 1.0; result->err = GSL_DBL_EPSILON; return GSL_SUCCESS; } else if(fabs(s-1.0) < 10.0*GSL_ROOT5_DBL_EPSILON) { double del = s-1.0; double c0 = M_LN2; double c1 = M_LN2 * (M_EULER - 0.5*M_LN2); double c2 = -0.0326862962794492996; double c3 = 0.0015689917054155150; double c4 = 0.00074987242112047532; result->val = c0 + del * (c1 + del * (c2 + del * (c3 + del * c4))); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { gsl_sf_result z; gsl_sf_result p; int stat_z = gsl_sf_zeta_e(s, &z); int stat_p = gsl_sf_exp_e((1.0-s)*M_LN2, &p); int stat_m = gsl_sf_multiply_e(1.0-p.val, z.val, result); result->err = fabs(p.err * (M_LN2*(1.0-s)) * z.val) + z.err * fabs(p.val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_3(stat_m, stat_p, stat_z); } } /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/ #include "gsl_specfunc__eval.h" double gsl_sf_zeta(const double s) { EVAL_RESULT(gsl_sf_zeta_e(s, &result)); } double gsl_sf_hzeta(const double s, const double a) { EVAL_RESULT(gsl_sf_hzeta_e(s, a, &result)); } double gsl_sf_zeta_int(const int s) { EVAL_RESULT(gsl_sf_zeta_int_e(s, &result)); } double gsl_sf_zetam1(const double s) { EVAL_RESULT(gsl_sf_zetam1_e(s, &result)); } double gsl_sf_zetam1_int(const int s) { EVAL_RESULT(gsl_sf_zetam1_int_e(s, &result)); } double gsl_sf_eta_int(const int s) { EVAL_RESULT(gsl_sf_eta_int_e(s, &result)); } double gsl_sf_eta(const double s) { EVAL_RESULT(gsl_sf_eta_e(s, &result)); } praat-6.0.04/external/gsl/gsl_spline.h000066400000000000000000000053311261542461700176410ustar00rootroot00000000000000/* interpolation/gsl_spline.h * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_SPLINE_H__ #define __GSL_SPLINE_H__ #include #include "gsl_interp.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* general interpolation object */ typedef struct { gsl_interp * interp; double * x; double * y; size_t size; } gsl_spline; gsl_spline * gsl_spline_alloc(const gsl_interp_type * T, size_t size); int gsl_spline_init(gsl_spline * spline, const double xa[], const double ya[], size_t size); const char * gsl_spline_name(const gsl_spline * spline); unsigned int gsl_spline_min_size(const gsl_spline * spline); int gsl_spline_eval_e(const gsl_spline * spline, double x, gsl_interp_accel * a, double * y); double gsl_spline_eval(const gsl_spline * spline, double x, gsl_interp_accel * a); int gsl_spline_eval_deriv_e(const gsl_spline * spline, double x, gsl_interp_accel * a, double * y); double gsl_spline_eval_deriv(const gsl_spline * spline, double x, gsl_interp_accel * a); int gsl_spline_eval_deriv2_e(const gsl_spline * spline, double x, gsl_interp_accel * a, double * y); double gsl_spline_eval_deriv2(const gsl_spline * spline, double x, gsl_interp_accel * a); int gsl_spline_eval_integ_e(const gsl_spline * spline, double a, double b, gsl_interp_accel * acc, double * y); double gsl_spline_eval_integ(const gsl_spline * spline, double a, double b, gsl_interp_accel * acc); void gsl_spline_free(gsl_spline * spline); __END_DECLS #endif /* __GSL_INTERP_H__ */ praat-6.0.04/external/gsl/gsl_statistics.h000066400000000000000000000007331261542461700205420ustar00rootroot00000000000000#ifndef __GSL_STATISTICS_H__ #define __GSL_STATISTICS_H__ #include "gsl_statistics_long_double.h" #include "gsl_statistics_double.h" #include "gsl_statistics_float.h" #include "gsl_statistics_ulong.h" #include "gsl_statistics_long.h" #include "gsl_statistics_uint.h" #include "gsl_statistics_int.h" #include "gsl_statistics_ushort.h" #include "gsl_statistics_short.h" #include "gsl_statistics_uchar.h" #include "gsl_statistics_char.h" #endif /* __GSL_STATISTICS_H__ */ praat-6.0.04/external/gsl/gsl_statistics__absdev.c000066400000000000000000000030331261542461700222140ustar00rootroot00000000000000#include "gsl__config.h" #include #include "gsl_statistics.h" #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_statistics__absdev_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_statistics__absdev_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_statistics__absdev_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_statistics__absdev_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_statistics__absdev_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_statistics__absdev_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_statistics__absdev_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_statistics__absdev_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_statistics__absdev_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_statistics__absdev_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_statistics__absdev_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_statistics__absdev_source.c000066400000000000000000000030501261542461700235730ustar00rootroot00000000000000/* statistics/absdev_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ double FUNCTION(gsl_stats,absdev) (const BASE data[], const size_t stride, const size_t n) { const double mean = FUNCTION(gsl_stats,mean)(data, stride, n); return FUNCTION(gsl_stats,absdev_m)(data, stride, n, mean); } double FUNCTION(gsl_stats,absdev_m) (const BASE data[], const size_t stride, const size_t n, const double mean) { /* takes a dataset and finds the absolute deviation */ double sum = 0, absdev; size_t i; /* find the sum of the absolute deviations */ for (i = 0; i < n; i++) { const double delta = fabs(data[i * stride] - mean); sum += delta; } absdev = sum / n; return absdev; } praat-6.0.04/external/gsl/gsl_statistics__covariance.c000066400000000000000000000031111261542461700230570ustar00rootroot00000000000000#include "gsl__config.h" #include #include "gsl_statistics.h" #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_statistics__covariance_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_statistics__covariance_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_statistics__covariance_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_statistics__covariance_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_statistics__covariance_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_statistics__covariance_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_statistics__covariance_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_statistics__covariance_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_statistics__covariance_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_statistics__covariance_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_statistics__covariance_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_statistics__covariance_source.c000066400000000000000000000110531261542461700244430ustar00rootroot00000000000000/* statistics/covar_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static double FUNCTION(compute,covariance) (const BASE data1[], const size_t stride1, const BASE data2[], const size_t stride2, const size_t n, const double mean1, const double mean2); static double FUNCTION(compute,covariance) (const BASE data1[], const size_t stride1, const BASE data2[], const size_t stride2, const size_t n, const double mean1, const double mean2) { /* takes a dataset and finds the covariance */ long double covariance = 0 ; size_t i; /* find the sum of the squares */ for (i = 0; i < n; i++) { const long double delta1 = (data1[i * stride1] - mean1); const long double delta2 = (data2[i * stride2] - mean2); covariance += (delta1 * delta2 - covariance) / (i + 1); } return covariance ; } double FUNCTION(gsl_stats,covariance_m) (const BASE data1[], const size_t stride1, const BASE data2[], const size_t stride2, const size_t n, const double mean1, const double mean2) { const double covariance = FUNCTION(compute,covariance) (data1, stride1, data2, stride2, n, mean1, mean2); return covariance * ((double)n / (double)(n - 1)); } double FUNCTION(gsl_stats,covariance) (const BASE data1[], const size_t stride1, const BASE data2[], const size_t stride2, const size_t n) { const double mean1 = FUNCTION(gsl_stats,mean) (data1, stride1, n); const double mean2 = FUNCTION(gsl_stats,mean) (data2, stride2, n); return FUNCTION(gsl_stats,covariance_m)(data1, stride1, data2, stride2, n, mean1, mean2); } /* gsl_stats_correlation() Calculate Pearson correlation = cov(X, Y) / (sigma_X * sigma_Y) This routine efficiently computes the correlation in one pass of the data and makes use of the algorithm described in: B. P. Welford, "Note on a Method for Calculating Corrected Sums of Squares and Products", Technometrics, Vol 4, No 3, 1962. This paper derives a numerically stable recurrence to compute a sum of products S = sum_{i=1..N} [ (x_i - mu_x) * (y_i - mu_y) ] with the relation S_n = S_{n-1} + ((n-1)/n) * (x_n - mu_x_{n-1}) * (y_n - mu_y_{n-1}) */ double FUNCTION(gsl_stats,correlation) (const BASE data1[], const size_t stride1, const BASE data2[], const size_t stride2, const size_t n) { size_t i; long double sum_xsq = 0.0; long double sum_ysq = 0.0; long double sum_cross = 0.0; long double ratio; long double delta_x, delta_y; long double mean_x, mean_y; long double r; /* * Compute: * sum_xsq = Sum [ (x_i - mu_x)^2 ], * sum_ysq = Sum [ (y_i - mu_y)^2 ] and * sum_cross = Sum [ (x_i - mu_x) * (y_i - mu_y) ] * using the above relation from Welford's paper */ mean_x = data1[0 * stride1]; mean_y = data2[0 * stride2]; for (i = 1; i < n; ++i) { ratio = i / (i + 1.0); delta_x = data1[i * stride1] - mean_x; delta_y = data2[i * stride2] - mean_y; sum_xsq += delta_x * delta_x * ratio; sum_ysq += delta_y * delta_y * ratio; sum_cross += delta_x * delta_y * ratio; mean_x += delta_x / (i + 1.0); mean_y += delta_y / (i + 1.0); } r = sum_cross / (sqrt(sum_xsq) * sqrt(sum_ysq)); return r; } praat-6.0.04/external/gsl/gsl_statistics__kurtosis.c000066400000000000000000000030621261542461700226350ustar00rootroot00000000000000#include "gsl__config.h" #include #include "gsl_statistics.h" #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_statistics__kurtosis_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_statistics__kurtosis_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_statistics__kurtosis_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_statistics__kurtosis_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_statistics__kurtosis_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_statistics__kurtosis_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_statistics__kurtosis_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_statistics__kurtosis_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_statistics__kurtosis_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_statistics__kurtosis_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_statistics__kurtosis_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_statistics__kurtosis_source.c000066400000000000000000000036441261542461700242230ustar00rootroot00000000000000/* statistics/kurtosis_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ double FUNCTION(gsl_stats,kurtosis) (const BASE data[], const size_t stride, const size_t n) { const double mean = FUNCTION(gsl_stats,mean)(data, stride, n); const double est_sd = FUNCTION(gsl_stats,sd_m)(data, stride, n, mean); return FUNCTION(gsl_stats,kurtosis_m_sd)(data, stride, n, mean, est_sd); } double FUNCTION(gsl_stats,kurtosis_m_sd) (const BASE data[], const size_t stride, const size_t n, const double mean, const double sd) { /* takes a dataset and finds the kurtosis */ long double avg = 0, kurtosis; size_t i; /* find the fourth moment the deviations, normalized by the sd */ /* we use a recurrence relation to stably update a running value so there aren't any large sums that can overflow */ for (i = 0; i < n; i++) { const long double x = (data[i * stride] - mean) / sd; avg += (x * x * x * x - avg)/(i + 1); } kurtosis = avg - 3.0; /* makes kurtosis zero for a Gaussian */ return kurtosis; } praat-6.0.04/external/gsl/gsl_statistics__lag1.c000066400000000000000000000027641261542461700216060ustar00rootroot00000000000000#include "gsl__config.h" #include "gsl_statistics.h" #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_statistics__lag1_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_statistics__lag1_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_statistics__lag1_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_statistics__lag1_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_statistics__lag1_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_statistics__lag1_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_statistics__lag1_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_statistics__lag1_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_statistics__lag1_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_statistics__lag1_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_statistics__lag1_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_statistics__lag1_source.c000066400000000000000000000032751261542461700231640ustar00rootroot00000000000000/* statistics/lag1_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ double FUNCTION(gsl_stats,lag1_autocorrelation) (const BASE data[], const size_t stride, const size_t n) { const double mean = FUNCTION(gsl_stats,mean) (data, stride, n); return FUNCTION(gsl_stats,lag1_autocorrelation_m)(data, stride, n, mean); } double FUNCTION(gsl_stats,lag1_autocorrelation_m) (const BASE data[], const size_t stride, const size_t size, const double mean) { /* Compute the lag-1 autocorrelation of a dataset using the recurrence relation */ size_t i; long double r1 ; long double q = 0 ; long double v = (data[0 * stride] - mean) * (data[0 * stride] - mean) ; for (i = 1; i < size ; i++) { const long double delta0 = (data[(i-1) * stride] - mean); const long double delta1 = (data[i * stride] - mean); q += (delta0 * delta1 - q)/(i + 1); v += (delta1 * delta1 - v)/(i + 1); } r1 = q / v ; return r1; } praat-6.0.04/external/gsl/gsl_statistics__mean.c000066400000000000000000000027641261542461700217020ustar00rootroot00000000000000#include "gsl__config.h" #include "gsl_statistics.h" #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_statistics__mean_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_statistics__mean_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_statistics__mean_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_statistics__mean_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_statistics__mean_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_statistics__mean_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_statistics__mean_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_statistics__mean_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_statistics__mean_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_statistics__mean_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_statistics__mean_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_statistics__mean_source.c000066400000000000000000000023031261542461700232470ustar00rootroot00000000000000/* statistics/mean_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ double FUNCTION (gsl_stats, mean) (const BASE data[], const size_t stride, const size_t size) { /* Compute the arithmetic mean of a dataset using the recurrence relation mean_(n) = mean(n-1) + (data[n] - mean(n-1))/(n+1) */ long double mean = 0; size_t i; for (i = 0; i < size; i++) { mean += (data[i * stride] - mean) / (i + 1); } return mean; } praat-6.0.04/external/gsl/gsl_statistics__median.c000066400000000000000000000030131261542461700222030ustar00rootroot00000000000000#include "gsl__config.h" #include "gsl_statistics.h" #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_statistics__median_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_statistics__median_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_statistics__median_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_statistics__median_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_statistics__median_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_statistics__median_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_statistics__median_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_statistics__median_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_statistics__median_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_statistics__median_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_statistics__median_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_statistics__median_source.c000066400000000000000000000025141261542461700235700ustar00rootroot00000000000000/* statistics/median_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ double FUNCTION(gsl_stats,median_from_sorted_data) (const BASE sorted_data[], const size_t stride, const size_t n) { double median ; const size_t lhs = (n - 1) / 2 ; const size_t rhs = n / 2 ; if (n == 0) return 0.0 ; if (lhs == rhs) { median = sorted_data[lhs * stride] ; } else { median = (sorted_data[lhs * stride] + sorted_data[rhs * stride])/2.0 ; } return median ; } praat-6.0.04/external/gsl/gsl_statistics__minmax.c000066400000000000000000000030641261542461700222450ustar00rootroot00000000000000#include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_statistics.h" #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_statistics__minmax_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_statistics__minmax_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_statistics__minmax_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_statistics__minmax_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_statistics__minmax_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_statistics__minmax_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_statistics__minmax_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_statistics__minmax_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_statistics__minmax_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_statistics__minmax_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_statistics__minmax_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_statistics__minmax_source.c000066400000000000000000000102161261542461700236220ustar00rootroot00000000000000/* statistics/minmax_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ BASE FUNCTION (gsl_stats,max) (const BASE data[], const size_t stride, const size_t n) { /* finds the largest member of a dataset */ BASE max = data[0 * stride]; size_t i; for (i = 0; i < n; i++) { BASE xi = data[i * stride]; if (xi > max) max = xi; #ifdef FP if (isnan (xi)) return xi; #endif } return max; } BASE FUNCTION (gsl_stats,min) (const BASE data[], const size_t stride, const size_t n) { /* finds the smallest member of a dataset */ BASE min = data[0 * stride]; size_t i; for (i = 0; i < n; i++) { BASE xi = data[i * stride]; if (xi < min) min = xi; #ifdef FP if (isnan (xi)) return xi; #endif } return min; } void FUNCTION (gsl_stats,minmax) (BASE * min_out, BASE * max_out, const BASE data[], const size_t stride, const size_t n) { /* finds the smallest and largest members of a dataset */ BASE min = data[0 * stride]; BASE max = data[0 * stride]; size_t i; for (i = 0; i < n; i++) { BASE xi = data[i * stride]; if (xi < min) min = xi; if (xi > max) max = xi; #ifdef FP if (isnan (xi)) { min = xi; max = xi; break; } #endif } *min_out = min; *max_out = max; } size_t FUNCTION (gsl_stats,max_index) (const BASE data[], const size_t stride, const size_t n) { /* finds the index of the largest member of a dataset */ /* if there is more than one largest value then we choose the first */ BASE max = data[0 * stride]; size_t i, max_index = 0; for (i = 0; i < n; i++) { BASE xi = data[i * stride]; if (xi > max) { max = xi; max_index = i; } #ifdef FP if (isnan (xi)) { return i; } #endif } return max_index; } size_t FUNCTION (gsl_stats,min_index) (const BASE data[], const size_t stride, const size_t n) { /* finds the index of the smallest member of a dataset */ /* if there is more than one largest value then we choose the first */ BASE min = data[0 * stride]; size_t i, min_index = 0; for (i = 0; i < n; i++) { BASE xi = data[i * stride]; if (xi < min) { min = xi; min_index = i; } #ifdef FP if (isnan (xi)) { return i; } #endif } return min_index; } void FUNCTION (gsl_stats,minmax_index) (size_t * min_index_out, size_t * max_index_out, const BASE data[], const size_t stride, const size_t n) { /* finds the smallest and largest members of a dataset */ BASE min = data[0 * stride]; BASE max = data[0 * stride]; size_t i, min_index = 0, max_index = 0; for (i = 0; i < n; i++) { BASE xi = data[i * stride]; if (xi < min) { min = xi; min_index = i; } if (xi > max) { max = xi; max_index = i; } #ifdef FP if (isnan (xi)) { min_index = i; max_index = i; break; } #endif } *min_index_out = min_index; *max_index_out = max_index; } praat-6.0.04/external/gsl/gsl_statistics__p_variance.c000066400000000000000000000030671261542461700230660ustar00rootroot00000000000000#include "gsl__config.h" #include "gsl_statistics.h" #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_statistics__p_variance_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_statistics__p_variance_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_statistics__p_variance_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_statistics__p_variance_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_statistics__p_variance_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_statistics__p_variance_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_statistics__p_variance_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_statistics__p_variance_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_statistics__p_variance_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_statistics__p_variance_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_statistics__p_variance_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_statistics__p_variance_source.c000066400000000000000000000026641261542461700244500ustar00rootroot00000000000000/* statistics/p_variance_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ double FUNCTION(gsl_stats,pvariance) (const BASE data1[], const size_t stride1, const size_t n1, const BASE data2[], const size_t stride2, const size_t n2) { /* Find the pooled variance of two datasets */ const double var1 = FUNCTION(gsl_stats,variance) (data1, stride1, n1); const double var2 = FUNCTION(gsl_stats,variance) (data2, stride2, n2); /* calculate the pooled variance */ const double pooled_variance = (((n1 - 1) * var1) + ((n2 - 1) * var2)) / (n1 + n2 - 2); return pooled_variance; } praat-6.0.04/external/gsl/gsl_statistics__quantiles.c000066400000000000000000000030541261542461700227600ustar00rootroot00000000000000#include "gsl__config.h" #include "gsl_statistics.h" #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_statistics__quantiles_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_statistics__quantiles_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_statistics__quantiles_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_statistics__quantiles_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_statistics__quantiles_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_statistics__quantiles_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_statistics__quantiles_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_statistics__quantiles_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_statistics__quantiles_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_statistics__quantiles_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_statistics__quantiles_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_statistics__quantiles_source.c000066400000000000000000000027251261542461700243440ustar00rootroot00000000000000/* statistics/quantiles_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ double FUNCTION(gsl_stats,quantile_from_sorted_data) (const BASE sorted_data[], const size_t stride, const size_t n, const double f) { const double index = f * (n - 1) ; const size_t lhs = (int)index ; const double delta = index - lhs ; double result; if (n == 0) return 0.0 ; if (lhs == n - 1) { result = sorted_data[lhs * stride] ; } else { result = (1 - delta) * sorted_data[lhs * stride] + delta * sorted_data[(lhs + 1) * stride] ; } return result ; } praat-6.0.04/external/gsl/gsl_statistics__skew.c000066400000000000000000000030071261542461700217220ustar00rootroot00000000000000#include "gsl__config.h" #include #include "gsl_statistics.h" #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_statistics__skew_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_statistics__skew_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_statistics__skew_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_statistics__skew_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_statistics__skew_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_statistics__skew_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_statistics__skew_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_statistics__skew_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_statistics__skew_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_statistics__skew_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_statistics__skew_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_statistics__skew_source.c000066400000000000000000000033551261542461700233100ustar00rootroot00000000000000/* statistics/skew_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ double FUNCTION(gsl_stats,skew) (const BASE data[], const size_t stride, const size_t n) { const double mean = FUNCTION(gsl_stats,mean)(data, stride, n); const double sd = FUNCTION(gsl_stats,sd_m)(data, stride, n, mean); return FUNCTION(gsl_stats,skew_m_sd)(data, stride, n, mean, sd); } double FUNCTION(gsl_stats,skew_m_sd) (const BASE data[], const size_t stride, const size_t n, const double mean, const double sd) { /* takes a dataset and finds the skewness */ long double skew = 0; size_t i; /* find the sum of the cubed deviations, normalized by the sd. */ /* we use a recurrence relation to stably update a running value so there aren't any large sums that can overflow */ for (i = 0; i < n; i++) { const long double x = (data[i * stride] - mean) / sd; skew += (x * x * x - skew) / (i + 1); } return skew; } praat-6.0.04/external/gsl/gsl_statistics__ttest.c000066400000000000000000000030221261542461700221110ustar00rootroot00000000000000#include "gsl__config.h" #include #include "gsl_statistics.h" #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_statistics__ttest_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_statistics__ttest_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_statistics__ttest_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_statistics__ttest_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_statistics__ttest_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_statistics__ttest_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_statistics__ttest_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_statistics__ttest_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_statistics__ttest_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_statistics__ttest_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_statistics__ttest_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_statistics__ttest_source.c000066400000000000000000000032411261542461700234740ustar00rootroot00000000000000/* statistics/ttest_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ double FUNCTION(gsl_stats,ttest) (const BASE data1[], const size_t stride1, const size_t n1, const BASE data2[], const size_t stride2, const size_t n2) { /* runs a t-test between two datasets representing independent samples. Tests to see if the difference between means of the samples is different from zero */ /* find means for the two samples */ const double mean1 = FUNCTION(gsl_stats,mean) (data1, stride1, n1); const double mean2 = FUNCTION(gsl_stats,mean) (data2, stride2, n2); /* find pooled variance for the two samples */ const double pv = FUNCTION(gsl_stats,pvariance) (data1, stride1, n1, data2, stride2, n2); /* calculate the t statistic */ const double t = (mean1 - mean2) / (sqrt (pv * ((1.0 / n1) + (1.0 / n2)))); return t; } praat-6.0.04/external/gsl/gsl_statistics__variance.c000066400000000000000000000030631261542461700225430ustar00rootroot00000000000000#include "gsl__config.h" #include #include "gsl_statistics.h" #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_statistics__variance_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_statistics__variance_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_statistics__variance_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_statistics__variance_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_statistics__variance_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_statistics__variance_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_statistics__variance_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_statistics__variance_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_statistics__variance_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_statistics__variance_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_statistics__variance_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_statistics__variance_source.c000066400000000000000000000054401261542461700241240ustar00rootroot00000000000000/* statistics/variance_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static double FUNCTION(compute,variance) (const BASE data[], const size_t stride, const size_t n, const double mean); static double FUNCTION(compute,variance) (const BASE data[], const size_t stride, const size_t n, const double mean) { /* takes a dataset and finds the variance */ long double variance = 0 ; size_t i; /* find the sum of the squares */ for (i = 0; i < n; i++) { const long double delta = (data[i * stride] - mean); variance += (delta * delta - variance) / (i + 1); } return variance ; } double FUNCTION(gsl_stats,variance_with_fixed_mean) (const BASE data[], const size_t stride, const size_t n, const double mean) { const double variance = FUNCTION(compute,variance) (data, stride, n, mean); return variance; } double FUNCTION(gsl_stats,sd_with_fixed_mean) (const BASE data[], const size_t stride, const size_t n, const double mean) { const double variance = FUNCTION(compute,variance) (data, stride, n, mean); const double sd = sqrt (variance); return sd; } double FUNCTION(gsl_stats,variance_m) (const BASE data[], const size_t stride, const size_t n, const double mean) { const double variance = FUNCTION(compute,variance) (data, stride, n, mean); return variance * ((double)n / (double)(n - 1)); } double FUNCTION(gsl_stats,sd_m) (const BASE data[], const size_t stride, const size_t n, const double mean) { const double variance = FUNCTION(compute,variance) (data, stride, n, mean); const double sd = sqrt (variance * ((double)n / (double)(n - 1))); return sd; } double FUNCTION(gsl_stats,variance) (const BASE data[], const size_t stride, const size_t n) { const double mean = FUNCTION(gsl_stats,mean) (data, stride, n); return FUNCTION(gsl_stats,variance_m)(data, stride, n, mean); } double FUNCTION(gsl_stats,sd) (const BASE data[], const size_t stride, const size_t n) { const double mean = FUNCTION(gsl_stats,mean) (data, stride, n); return FUNCTION(gsl_stats,sd_m) (data, stride, n, mean); } praat-6.0.04/external/gsl/gsl_statistics__wabsdev.c000066400000000000000000000007551261542461700224130ustar00rootroot00000000000000#include "gsl__config.h" #include #include "gsl_statistics.h" #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_statistics__wabsdev_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_statistics__wabsdev_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_statistics__wabsdev_source.c" #include "templates_off.h" #undef BASE_FLOAT praat-6.0.04/external/gsl/gsl_statistics__wabsdev_source.c000066400000000000000000000032711261542461700237670ustar00rootroot00000000000000/* statistics/wabsdev_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ double FUNCTION(gsl_stats,wabsdev) (const BASE w[], const size_t wstride, const BASE data[], const size_t stride, const size_t n) { const double wmean = FUNCTION(gsl_stats,wmean)(w, wstride, data, stride, n); return FUNCTION(gsl_stats,wabsdev_m)(w, wstride, data, stride, n, wmean); } double FUNCTION(gsl_stats,wabsdev_m) (const BASE w[], const size_t wstride, const BASE data[], const size_t stride, const size_t n, const double wmean) { /* Compute the weighted absolute deviation of a dataset */ long double wabsdev = 0; long double W = 0; size_t i; /* find the sum of the absolute deviations */ for (i = 0; i < n; i++) { BASE wi = w[i * wstride]; if (wi > 0) { const long double delta = fabs(data[i * stride] - wmean); W += wi ; wabsdev += (delta - wabsdev) * (wi / W); } } return wabsdev; } praat-6.0.04/external/gsl/gsl_statistics__wkurtosis.c000066400000000000000000000007631261542461700230310ustar00rootroot00000000000000#include "gsl__config.h" #include #include "gsl_statistics.h" #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_statistics__wkurtosis_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_statistics__wkurtosis_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_statistics__wkurtosis_source.c" #include "templates_off.h" #undef BASE_FLOAT praat-6.0.04/external/gsl/gsl_statistics__wkurtosis_source.c000066400000000000000000000042701261542461700244060ustar00rootroot00000000000000/* statistics/wkurtosis_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ double FUNCTION(gsl_stats,wkurtosis) (const BASE w[], const size_t wstride, const BASE data[], const size_t stride, const size_t n) { const double wmean = FUNCTION(gsl_stats,wmean)(w, wstride, data, stride, n); const double wsd = FUNCTION(gsl_stats,wsd_m)(w, wstride, data, stride, n, wmean); return FUNCTION(gsl_stats,wkurtosis_m_sd)(w, wstride, data, stride, n, wmean, wsd); } double FUNCTION(gsl_stats,wkurtosis_m_sd) (const BASE w[], const size_t wstride, const BASE data[], const size_t stride, const size_t n, const double wmean, const double wsd) { /* takes a dataset and finds the kurtosis */ long double wavg = 0, kurtosis; long double W = 0; size_t i; /* find the fourth moment the deviations, normalized by the sd */ /* we use a recurrence relation to stably update a running value so there aren't any large sums that can overflow */ for (i = 0; i < n; i++) { BASE wi = w[i * wstride]; if (wi > 0) { const long double x = (data[i * stride] - wmean) / wsd; W += wi ; wavg += (x * x * x * x - wavg) * (wi / W); } } kurtosis = wavg - 3.0; /* makes kurtosis zero for a Gaussian */ return kurtosis; } praat-6.0.04/external/gsl/gsl_statistics__wmean.c000066400000000000000000000007261261542461700220650ustar00rootroot00000000000000#include "gsl__config.h" #include "gsl_statistics.h" #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_statistics__wmean_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_statistics__wmean_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_statistics__wmean_source.c" #include "templates_off.h" #undef BASE_FLOAT praat-6.0.04/external/gsl/gsl_statistics__wmean_source.c000066400000000000000000000026301261542461700234410ustar00rootroot00000000000000/* statistics/wmean_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ double FUNCTION (gsl_stats, wmean) (const BASE w[], const size_t wstride, const BASE data[], const size_t stride, const size_t size) { /* Compute the weighted arithmetic mean M of a dataset using the recurrence relation M(n) = M(n-1) + (data[n] - M(n-1)) (w(n)/(W(n-1) + w(n))) W(n) = W(n-1) + w(n) */ long double wmean = 0; long double W = 0; size_t i; for (i = 0; i < size; i++) { BASE wi = w[i * wstride]; if (wi > 0) { W += wi; wmean += (data[i * stride] - wmean) * (wi / W); } } return wmean; } praat-6.0.04/external/gsl/gsl_statistics__wskew.c000066400000000000000000000007501261542461700221130ustar00rootroot00000000000000#include "gsl__config.h" #include #include "gsl_statistics.h" #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_statistics__wskew_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_statistics__wskew_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_statistics__wskew_source.c" #include "templates_off.h" #undef BASE_FLOAT praat-6.0.04/external/gsl/gsl_statistics__wskew_source.c000066400000000000000000000040071261542461700234720ustar00rootroot00000000000000/* statistics/wskew_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ double FUNCTION(gsl_stats,wskew) (const BASE w[], const size_t wstride, const BASE data[], const size_t stride, const size_t n) { const double wmean = FUNCTION(gsl_stats,wmean)(w, wstride, data, stride, n); const double wsd = FUNCTION(gsl_stats,wsd_m)(w, wstride, data, stride, n, wmean); return FUNCTION(gsl_stats,wskew_m_sd)(w, wstride, data, stride, n, wmean, wsd); } double FUNCTION(gsl_stats,wskew_m_sd) (const BASE w[], const size_t wstride, const BASE data[], const size_t stride, const size_t n, const double wmean, const double wsd) { /* Compute the weighted skewness of a dataset */ long double wskew = 0; long double W = 0; size_t i; /* find the sum of the cubed deviations, normalized by the sd. */ /* we use a recurrence relation to stably update a running value so there aren't any large sums that can overflow */ for (i = 0; i < n; i++) { BASE wi = w[i * wstride]; if (wi > 0) { const long double x = (data[i * stride] - wmean) / wsd; W += wi ; wskew += (x * x * x - wskew) * (wi / W); } } return wskew; } praat-6.0.04/external/gsl/gsl_statistics__wvariance.c000066400000000000000000000007631261542461700227360ustar00rootroot00000000000000#include "gsl__config.h" #include #include "gsl_statistics.h" #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_statistics__wvariance_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_statistics__wvariance_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_statistics__wvariance_source.c" #include "templates_off.h" #undef BASE_FLOAT praat-6.0.04/external/gsl/gsl_statistics__wvariance_source.c000066400000000000000000000077511261542461700243220ustar00rootroot00000000000000/* statistics/wvariance_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ static double FUNCTION(compute,wvariance) (const BASE w[], const size_t wstride, const BASE data[], const size_t stride, const size_t n, const double wmean); static double FUNCTION(compute,factor) (const BASE w[], const size_t wstride, const size_t n); static double FUNCTION(compute,wvariance) (const BASE w[], const size_t wstride, const BASE data[], const size_t stride, const size_t n, const double wmean) { /* takes a dataset and finds the weighted variance */ long double wvariance = 0 ; long double W = 0; size_t i; /* find the sum of the squares */ for (i = 0; i < n; i++) { BASE wi = w[i * wstride]; if (wi > 0) { const long double delta = (data[i * stride] - wmean); W += wi ; wvariance += (delta * delta - wvariance) * (wi / W); } } return wvariance ; } static double FUNCTION(compute,factor) (const BASE w[], const size_t wstride, const size_t n) { /* Find the factor ``N/(N-1)'' which multiplies the raw std dev */ long double a = 0 ; long double b = 0; long double factor; size_t i; /* find the sum of the squares */ for (i = 0; i < n; i++) { BASE wi = w[i * wstride]; if (wi > 0) { a += wi ; b += wi * wi ; } } factor = (a*a) / ((a*a) - b); return factor ; } double FUNCTION(gsl_stats,wvariance_with_fixed_mean) (const BASE w[], const size_t wstride, const BASE data[], const size_t stride, const size_t n, const double wmean) { const double wvariance = FUNCTION(compute,wvariance) (w, wstride, data, stride, n, wmean); return wvariance; } double FUNCTION(gsl_stats,wsd_with_fixed_mean) (const BASE w[], const size_t wstride, const BASE data[], const size_t stride, const size_t n, const double wmean) { const double wvariance = FUNCTION(compute,wvariance) (w, wstride, data, stride, n, wmean); const double wsd = sqrt (wvariance); return wsd; } double FUNCTION(gsl_stats,wvariance_m) (const BASE w[], const size_t wstride, const BASE data[], const size_t stride, const size_t n, const double wmean) { const double variance = FUNCTION(compute,wvariance) (w, wstride, data, stride, n, wmean); const double scale = FUNCTION(compute,factor)(w, wstride, n); return scale * variance; } double FUNCTION(gsl_stats,wsd_m) (const BASE w[], const size_t wstride, const BASE data[], const size_t stride, const size_t n, const double wmean) { const double variance = FUNCTION(compute,wvariance) (w, wstride, data, stride, n, wmean); const double scale = FUNCTION(compute,factor)(w, wstride, n); const double wsd = sqrt(scale * variance) ; return wsd; } double FUNCTION(gsl_stats,wsd) (const BASE w[], const size_t wstride, const BASE data[], const size_t stride, const size_t n) { const double wmean = FUNCTION(gsl_stats,wmean) (w, wstride, data, stride, n); return FUNCTION(gsl_stats,wsd_m) (w, wstride, data, stride, n, wmean) ; } double FUNCTION(gsl_stats,wvariance) (const BASE w[], const size_t wstride, const BASE data[], const size_t stride, const size_t n) { const double wmean = FUNCTION(gsl_stats,wmean) (w, wstride, data, stride, n); return FUNCTION(gsl_stats,wvariance_m)(w, wstride, data, stride, n, wmean); } praat-6.0.04/external/gsl/gsl_statistics_char.h000066400000000000000000000103671261542461700215430ustar00rootroot00000000000000/* statistics/gsl_statistics_char.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_STATISTICS_CHAR_H__ #define __GSL_STATISTICS_CHAR_H__ #include #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS double gsl_stats_char_mean (const char data[], const size_t stride, const size_t n); double gsl_stats_char_variance (const char data[], const size_t stride, const size_t n); double gsl_stats_char_sd (const char data[], const size_t stride, const size_t n); double gsl_stats_char_variance_with_fixed_mean (const char data[], const size_t stride, const size_t n, const double mean); double gsl_stats_char_sd_with_fixed_mean (const char data[], const size_t stride, const size_t n, const double mean); double gsl_stats_char_absdev (const char data[], const size_t stride, const size_t n); double gsl_stats_char_skew (const char data[], const size_t stride, const size_t n); double gsl_stats_char_kurtosis (const char data[], const size_t stride, const size_t n); double gsl_stats_char_lag1_autocorrelation (const char data[], const size_t stride, const size_t n); double gsl_stats_char_covariance (const char data1[], const size_t stride1,const char data2[], const size_t stride2, const size_t n); double gsl_stats_char_correlation (const char data1[], const size_t stride1,const char data2[], const size_t stride2, const size_t n); double gsl_stats_char_variance_m (const char data[], const size_t stride, const size_t n, const double mean); double gsl_stats_char_sd_m (const char data[], const size_t stride, const size_t n, const double mean); double gsl_stats_char_absdev_m (const char data[], const size_t stride, const size_t n, const double mean); double gsl_stats_char_skew_m_sd (const char data[], const size_t stride, const size_t n, const double mean, const double sd); double gsl_stats_char_kurtosis_m_sd (const char data[], const size_t stride, const size_t n, const double mean, const double sd); double gsl_stats_char_lag1_autocorrelation_m (const char data[], const size_t stride, const size_t n, const double mean); double gsl_stats_char_covariance_m (const char data1[], const size_t stride1,const char data2[], const size_t stride2, const size_t n, const double mean1, const double mean2); double gsl_stats_char_pvariance (const char data1[], const size_t stride1, const size_t n1, const char data2[], const size_t stride2, const size_t n2); double gsl_stats_char_ttest (const char data1[], const size_t stride1, const size_t n1, const char data2[], const size_t stride2, const size_t n2); char gsl_stats_char_max (const char data[], const size_t stride, const size_t n); char gsl_stats_char_min (const char data[], const size_t stride, const size_t n); void gsl_stats_char_minmax (char * min, char * max, const char data[], const size_t stride, const size_t n); size_t gsl_stats_char_max_index (const char data[], const size_t stride, const size_t n); size_t gsl_stats_char_min_index (const char data[], const size_t stride, const size_t n); void gsl_stats_char_minmax_index (size_t * min_index, size_t * max_index, const char data[], const size_t stride, const size_t n); double gsl_stats_char_median_from_sorted_data (const char sorted_data[], const size_t stride, const size_t n) ; double gsl_stats_char_quantile_from_sorted_data (const char sorted_data[], const size_t stride, const size_t n, const double f) ; __END_DECLS #endif /* __GSL_STATISTICS_CHAR_H__ */ praat-6.0.04/external/gsl/gsl_statistics_double.h000066400000000000000000000140751261542461700221000ustar00rootroot00000000000000/* statistics/gsl_statistics_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_STATISTICS_DOUBLE_H__ #define __GSL_STATISTICS_DOUBLE_H__ #include #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS double gsl_stats_mean (const double data[], const size_t stride, const size_t n); double gsl_stats_variance (const double data[], const size_t stride, const size_t n); double gsl_stats_sd (const double data[], const size_t stride, const size_t n); double gsl_stats_variance_with_fixed_mean (const double data[], const size_t stride, const size_t n, const double mean); double gsl_stats_sd_with_fixed_mean (const double data[], const size_t stride, const size_t n, const double mean); double gsl_stats_absdev (const double data[], const size_t stride, const size_t n); double gsl_stats_skew (const double data[], const size_t stride, const size_t n); double gsl_stats_kurtosis (const double data[], const size_t stride, const size_t n); double gsl_stats_lag1_autocorrelation (const double data[], const size_t stride, const size_t n); double gsl_stats_covariance (const double data1[], const size_t stride1,const double data2[], const size_t stride2, const size_t n); double gsl_stats_correlation (const double data1[], const size_t stride1,const double data2[], const size_t stride2, const size_t n); double gsl_stats_variance_m (const double data[], const size_t stride, const size_t n, const double mean); double gsl_stats_sd_m (const double data[], const size_t stride, const size_t n, const double mean); double gsl_stats_absdev_m (const double data[], const size_t stride, const size_t n, const double mean); double gsl_stats_skew_m_sd (const double data[], const size_t stride, const size_t n, const double mean, const double sd); double gsl_stats_kurtosis_m_sd (const double data[], const size_t stride, const size_t n, const double mean, const double sd); double gsl_stats_lag1_autocorrelation_m (const double data[], const size_t stride, const size_t n, const double mean); double gsl_stats_covariance_m (const double data1[], const size_t stride1,const double data2[], const size_t stride2, const size_t n, const double mean1, const double mean2); /* DEFINED FOR FLOATING POINT TYPES ONLY */ double gsl_stats_wmean (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n); double gsl_stats_wvariance (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n); double gsl_stats_wsd (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n); double gsl_stats_wvariance_with_fixed_mean (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n, const double mean); double gsl_stats_wsd_with_fixed_mean (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n, const double mean); double gsl_stats_wabsdev (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n); double gsl_stats_wskew (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n); double gsl_stats_wkurtosis (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n); double gsl_stats_wvariance_m (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n, const double wmean); double gsl_stats_wsd_m (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n, const double wmean); double gsl_stats_wabsdev_m (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n, const double wmean); double gsl_stats_wskew_m_sd (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n, const double wmean, const double wsd); double gsl_stats_wkurtosis_m_sd (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n, const double wmean, const double wsd); /* END OF FLOATING POINT TYPES */ double gsl_stats_pvariance (const double data1[], const size_t stride1, const size_t n1, const double data2[], const size_t stride2, const size_t n2); double gsl_stats_ttest (const double data1[], const size_t stride1, const size_t n1, const double data2[], const size_t stride2, const size_t n2); double gsl_stats_max (const double data[], const size_t stride, const size_t n); double gsl_stats_min (const double data[], const size_t stride, const size_t n); void gsl_stats_minmax (double * min, double * max, const double data[], const size_t stride, const size_t n); size_t gsl_stats_max_index (const double data[], const size_t stride, const size_t n); size_t gsl_stats_min_index (const double data[], const size_t stride, const size_t n); void gsl_stats_minmax_index (size_t * min_index, size_t * max_index, const double data[], const size_t stride, const size_t n); double gsl_stats_median_from_sorted_data (const double sorted_data[], const size_t stride, const size_t n) ; double gsl_stats_quantile_from_sorted_data (const double sorted_data[], const size_t stride, const size_t n, const double f) ; __END_DECLS #endif /* __GSL_STATISTICS_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_statistics_float.h000066400000000000000000000143601261542461700217300ustar00rootroot00000000000000/* statistics/gsl_statistics_float.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_STATISTICS_FLOAT_H__ #define __GSL_STATISTICS_FLOAT_H__ #include #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS double gsl_stats_float_mean (const float data[], const size_t stride, const size_t n); double gsl_stats_float_variance (const float data[], const size_t stride, const size_t n); double gsl_stats_float_sd (const float data[], const size_t stride, const size_t n); double gsl_stats_float_variance_with_fixed_mean (const float data[], const size_t stride, const size_t n, const double mean); double gsl_stats_float_sd_with_fixed_mean (const float data[], const size_t stride, const size_t n, const double mean); double gsl_stats_float_absdev (const float data[], const size_t stride, const size_t n); double gsl_stats_float_skew (const float data[], const size_t stride, const size_t n); double gsl_stats_float_kurtosis (const float data[], const size_t stride, const size_t n); double gsl_stats_float_lag1_autocorrelation (const float data[], const size_t stride, const size_t n); double gsl_stats_float_covariance (const float data1[], const size_t stride1,const float data2[], const size_t stride2, const size_t n); double gsl_stats_float_correlation (const float data1[], const size_t stride1,const float data2[], const size_t stride2, const size_t n); double gsl_stats_float_variance_m (const float data[], const size_t stride, const size_t n, const double mean); double gsl_stats_float_sd_m (const float data[], const size_t stride, const size_t n, const double mean); double gsl_stats_float_absdev_m (const float data[], const size_t stride, const size_t n, const double mean); double gsl_stats_float_skew_m_sd (const float data[], const size_t stride, const size_t n, const double mean, const double sd); double gsl_stats_float_kurtosis_m_sd (const float data[], const size_t stride, const size_t n, const double mean, const double sd); double gsl_stats_float_lag1_autocorrelation_m (const float data[], const size_t stride, const size_t n, const double mean); double gsl_stats_float_covariance_m (const float data1[], const size_t stride1,const float data2[], const size_t stride2, const size_t n, const double mean1, const double mean2); /* DEFINED FOR FLOATING POINT TYPES ONLY */ double gsl_stats_float_wmean (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n); double gsl_stats_float_wvariance (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n); double gsl_stats_float_wsd (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n); double gsl_stats_float_wvariance_with_fixed_mean (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n, const double mean); double gsl_stats_float_wsd_with_fixed_mean (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n, const double mean); double gsl_stats_float_wabsdev (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n); double gsl_stats_float_wskew (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n); double gsl_stats_float_wkurtosis (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n); double gsl_stats_float_wvariance_m (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n, const double wmean); double gsl_stats_float_wsd_m (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n, const double wmean); double gsl_stats_float_wabsdev_m (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n, const double wmean); double gsl_stats_float_wskew_m_sd (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n, const double wmean, const double wsd); double gsl_stats_float_wkurtosis_m_sd (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n, const double wmean, const double wsd); /* END OF FLOATING POINT TYPES */ double gsl_stats_float_pvariance (const float data1[], const size_t stride1, const size_t n1, const float data2[], const size_t stride2, const size_t n2); double gsl_stats_float_ttest (const float data1[], const size_t stride1, const size_t n1, const float data2[], const size_t stride2, const size_t n2); float gsl_stats_float_max (const float data[], const size_t stride, const size_t n); float gsl_stats_float_min (const float data[], const size_t stride, const size_t n); void gsl_stats_float_minmax (float * min, float * max, const float data[], const size_t stride, const size_t n); size_t gsl_stats_float_max_index (const float data[], const size_t stride, const size_t n); size_t gsl_stats_float_min_index (const float data[], const size_t stride, const size_t n); void gsl_stats_float_minmax_index (size_t * min_index, size_t * max_index, const float data[], const size_t stride, const size_t n); double gsl_stats_float_median_from_sorted_data (const float sorted_data[], const size_t stride, const size_t n) ; double gsl_stats_float_quantile_from_sorted_data (const float sorted_data[], const size_t stride, const size_t n, const double f) ; __END_DECLS #endif /* __GSL_STATISTICS_FLOAT_H__ */ praat-6.0.04/external/gsl/gsl_statistics_int.h000066400000000000000000000102621261542461700214120ustar00rootroot00000000000000/* statistics/gsl_statistics_int.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_STATISTICS_INT_H__ #define __GSL_STATISTICS_INT_H__ #include #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS double gsl_stats_int_mean (const int data[], const size_t stride, const size_t n); double gsl_stats_int_variance (const int data[], const size_t stride, const size_t n); double gsl_stats_int_sd (const int data[], const size_t stride, const size_t n); double gsl_stats_int_variance_with_fixed_mean (const int data[], const size_t stride, const size_t n, const double mean); double gsl_stats_int_sd_with_fixed_mean (const int data[], const size_t stride, const size_t n, const double mean); double gsl_stats_int_absdev (const int data[], const size_t stride, const size_t n); double gsl_stats_int_skew (const int data[], const size_t stride, const size_t n); double gsl_stats_int_kurtosis (const int data[], const size_t stride, const size_t n); double gsl_stats_int_lag1_autocorrelation (const int data[], const size_t stride, const size_t n); double gsl_stats_int_covariance (const int data1[], const size_t stride1,const int data2[], const size_t stride2, const size_t n); double gsl_stats_int_correlation (const int data1[], const size_t stride1,const int data2[], const size_t stride2, const size_t n); double gsl_stats_int_variance_m (const int data[], const size_t stride, const size_t n, const double mean); double gsl_stats_int_sd_m (const int data[], const size_t stride, const size_t n, const double mean); double gsl_stats_int_absdev_m (const int data[], const size_t stride, const size_t n, const double mean); double gsl_stats_int_skew_m_sd (const int data[], const size_t stride, const size_t n, const double mean, const double sd); double gsl_stats_int_kurtosis_m_sd (const int data[], const size_t stride, const size_t n, const double mean, const double sd); double gsl_stats_int_lag1_autocorrelation_m (const int data[], const size_t stride, const size_t n, const double mean); double gsl_stats_int_covariance_m (const int data1[], const size_t stride1,const int data2[], const size_t stride2, const size_t n, const double mean1, const double mean2); double gsl_stats_int_pvariance (const int data1[], const size_t stride1, const size_t n1, const int data2[], const size_t stride2, const size_t n2); double gsl_stats_int_ttest (const int data1[], const size_t stride1, const size_t n1, const int data2[], const size_t stride2, const size_t n2); int gsl_stats_int_max (const int data[], const size_t stride, const size_t n); int gsl_stats_int_min (const int data[], const size_t stride, const size_t n); void gsl_stats_int_minmax (int * min, int * max, const int data[], const size_t stride, const size_t n); size_t gsl_stats_int_max_index (const int data[], const size_t stride, const size_t n); size_t gsl_stats_int_min_index (const int data[], const size_t stride, const size_t n); void gsl_stats_int_minmax_index (size_t * min_index, size_t * max_index, const int data[], const size_t stride, const size_t n); double gsl_stats_int_median_from_sorted_data (const int sorted_data[], const size_t stride, const size_t n) ; double gsl_stats_int_quantile_from_sorted_data (const int sorted_data[], const size_t stride, const size_t n, const double f) ; __END_DECLS #endif /* __GSL_STATISTICS_INT_H__ */ praat-6.0.04/external/gsl/gsl_statistics_long.h000066400000000000000000000103671261542461700215650ustar00rootroot00000000000000/* statistics/gsl_statistics_long.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_STATISTICS_LONG_H__ #define __GSL_STATISTICS_LONG_H__ #include #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS double gsl_stats_long_mean (const long data[], const size_t stride, const size_t n); double gsl_stats_long_variance (const long data[], const size_t stride, const size_t n); double gsl_stats_long_sd (const long data[], const size_t stride, const size_t n); double gsl_stats_long_variance_with_fixed_mean (const long data[], const size_t stride, const size_t n, const double mean); double gsl_stats_long_sd_with_fixed_mean (const long data[], const size_t stride, const size_t n, const double mean); double gsl_stats_long_absdev (const long data[], const size_t stride, const size_t n); double gsl_stats_long_skew (const long data[], const size_t stride, const size_t n); double gsl_stats_long_kurtosis (const long data[], const size_t stride, const size_t n); double gsl_stats_long_lag1_autocorrelation (const long data[], const size_t stride, const size_t n); double gsl_stats_long_covariance (const long data1[], const size_t stride1,const long data2[], const size_t stride2, const size_t n); double gsl_stats_long_correlation (const long data1[], const size_t stride1,const long data2[], const size_t stride2, const size_t n); double gsl_stats_long_variance_m (const long data[], const size_t stride, const size_t n, const double mean); double gsl_stats_long_sd_m (const long data[], const size_t stride, const size_t n, const double mean); double gsl_stats_long_absdev_m (const long data[], const size_t stride, const size_t n, const double mean); double gsl_stats_long_skew_m_sd (const long data[], const size_t stride, const size_t n, const double mean, const double sd); double gsl_stats_long_kurtosis_m_sd (const long data[], const size_t stride, const size_t n, const double mean, const double sd); double gsl_stats_long_lag1_autocorrelation_m (const long data[], const size_t stride, const size_t n, const double mean); double gsl_stats_long_covariance_m (const long data1[], const size_t stride1,const long data2[], const size_t stride2, const size_t n, const double mean1, const double mean2); double gsl_stats_long_pvariance (const long data1[], const size_t stride1, const size_t n1, const long data2[], const size_t stride2, const size_t n2); double gsl_stats_long_ttest (const long data1[], const size_t stride1, const size_t n1, const long data2[], const size_t stride2, const size_t n2); long gsl_stats_long_max (const long data[], const size_t stride, const size_t n); long gsl_stats_long_min (const long data[], const size_t stride, const size_t n); void gsl_stats_long_minmax (long * min, long * max, const long data[], const size_t stride, const size_t n); size_t gsl_stats_long_max_index (const long data[], const size_t stride, const size_t n); size_t gsl_stats_long_min_index (const long data[], const size_t stride, const size_t n); void gsl_stats_long_minmax_index (size_t * min_index, size_t * max_index, const long data[], const size_t stride, const size_t n); double gsl_stats_long_median_from_sorted_data (const long sorted_data[], const size_t stride, const size_t n) ; double gsl_stats_long_quantile_from_sorted_data (const long sorted_data[], const size_t stride, const size_t n, const double f) ; __END_DECLS #endif /* __GSL_STATISTICS_LONG_H__ */ praat-6.0.04/external/gsl/gsl_statistics_long_double.h000066400000000000000000000155701261542461700231200ustar00rootroot00000000000000/* statistics/gsl_statistics_long_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_STATISTICS_LONG_DOUBLE_H__ #define __GSL_STATISTICS_LONG_DOUBLE_H__ #include #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS double gsl_stats_long_double_mean (const long double data[], const size_t stride, const size_t n); double gsl_stats_long_double_variance (const long double data[], const size_t stride, const size_t n); double gsl_stats_long_double_sd (const long double data[], const size_t stride, const size_t n); double gsl_stats_long_double_variance_with_fixed_mean (const long double data[], const size_t stride, const size_t n, const double mean); double gsl_stats_long_double_sd_with_fixed_mean (const long double data[], const size_t stride, const size_t n, const double mean); double gsl_stats_long_double_absdev (const long double data[], const size_t stride, const size_t n); double gsl_stats_long_double_skew (const long double data[], const size_t stride, const size_t n); double gsl_stats_long_double_kurtosis (const long double data[], const size_t stride, const size_t n); double gsl_stats_long_double_lag1_autocorrelation (const long double data[], const size_t stride, const size_t n); double gsl_stats_long_double_covariance (const long double data1[], const size_t stride1,const long double data2[], const size_t stride2, const size_t n); double gsl_stats_long_double_correlation (const long double data1[], const size_t stride1,const long double data2[], const size_t stride2, const size_t n); double gsl_stats_long_double_variance_m (const long double data[], const size_t stride, const size_t n, const double mean); double gsl_stats_long_double_sd_m (const long double data[], const size_t stride, const size_t n, const double mean); double gsl_stats_long_double_absdev_m (const long double data[], const size_t stride, const size_t n, const double mean); double gsl_stats_long_double_skew_m_sd (const long double data[], const size_t stride, const size_t n, const double mean, const double sd); double gsl_stats_long_double_kurtosis_m_sd (const long double data[], const size_t stride, const size_t n, const double mean, const double sd); double gsl_stats_long_double_lag1_autocorrelation_m (const long double data[], const size_t stride, const size_t n, const double mean); double gsl_stats_long_double_covariance_m (const long double data1[], const size_t stride1,const long double data2[], const size_t stride2, const size_t n, const double mean1, const double mean2); /* DEFINED FOR FLOATING POINT TYPES ONLY */ double gsl_stats_long_double_wmean (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n); double gsl_stats_long_double_wvariance (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n); double gsl_stats_long_double_wsd (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n); double gsl_stats_long_double_wvariance_with_fixed_mean (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n, const double mean); double gsl_stats_long_double_wsd_with_fixed_mean (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n, const double mean); double gsl_stats_long_double_wabsdev (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n); double gsl_stats_long_double_wskew (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n); double gsl_stats_long_double_wkurtosis (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n); double gsl_stats_long_double_wvariance_m (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n, const double wmean); double gsl_stats_long_double_wsd_m (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n, const double wmean); double gsl_stats_long_double_wabsdev_m (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n, const double wmean); double gsl_stats_long_double_wskew_m_sd (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n, const double wmean, const double wsd); double gsl_stats_long_double_wkurtosis_m_sd (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n, const double wmean, const double wsd); /* END OF FLOATING POINT TYPES */ double gsl_stats_long_double_pvariance (const long double data1[], const size_t stride1, const size_t n1, const long double data2[], const size_t stride2, const size_t n2); double gsl_stats_long_double_ttest (const long double data1[], const size_t stride1, const size_t n1, const long double data2[], const size_t stride2, const size_t n2); long double gsl_stats_long_double_max (const long double data[], const size_t stride, const size_t n); long double gsl_stats_long_double_min (const long double data[], const size_t stride, const size_t n); void gsl_stats_long_double_minmax (long double * min, long double * max, const long double data[], const size_t stride, const size_t n); size_t gsl_stats_long_double_max_index (const long double data[], const size_t stride, const size_t n); size_t gsl_stats_long_double_min_index (const long double data[], const size_t stride, const size_t n); void gsl_stats_long_double_minmax_index (size_t * min_index, size_t * max_index, const long double data[], const size_t stride, const size_t n); double gsl_stats_long_double_median_from_sorted_data (const long double sorted_data[], const size_t stride, const size_t n) ; double gsl_stats_long_double_quantile_from_sorted_data (const long double sorted_data[], const size_t stride, const size_t n, const double f) ; __END_DECLS #endif /* __GSL_STATISTICS_LONG_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_statistics_short.h000066400000000000000000000104741261542461700217640ustar00rootroot00000000000000/* statistics/gsl_statistics_short.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_STATISTICS_SHORT_H__ #define __GSL_STATISTICS_SHORT_H__ #include #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS double gsl_stats_short_mean (const short data[], const size_t stride, const size_t n); double gsl_stats_short_variance (const short data[], const size_t stride, const size_t n); double gsl_stats_short_sd (const short data[], const size_t stride, const size_t n); double gsl_stats_short_variance_with_fixed_mean (const short data[], const size_t stride, const size_t n, const double mean); double gsl_stats_short_sd_with_fixed_mean (const short data[], const size_t stride, const size_t n, const double mean); double gsl_stats_short_absdev (const short data[], const size_t stride, const size_t n); double gsl_stats_short_skew (const short data[], const size_t stride, const size_t n); double gsl_stats_short_kurtosis (const short data[], const size_t stride, const size_t n); double gsl_stats_short_lag1_autocorrelation (const short data[], const size_t stride, const size_t n); double gsl_stats_short_covariance (const short data1[], const size_t stride1,const short data2[], const size_t stride2, const size_t n); double gsl_stats_short_correlation (const short data1[], const size_t stride1,const short data2[], const size_t stride2, const size_t n); double gsl_stats_short_variance_m (const short data[], const size_t stride, const size_t n, const double mean); double gsl_stats_short_sd_m (const short data[], const size_t stride, const size_t n, const double mean); double gsl_stats_short_absdev_m (const short data[], const size_t stride, const size_t n, const double mean); double gsl_stats_short_skew_m_sd (const short data[], const size_t stride, const size_t n, const double mean, const double sd); double gsl_stats_short_kurtosis_m_sd (const short data[], const size_t stride, const size_t n, const double mean, const double sd); double gsl_stats_short_lag1_autocorrelation_m (const short data[], const size_t stride, const size_t n, const double mean); double gsl_stats_short_covariance_m (const short data1[], const size_t stride1,const short data2[], const size_t stride2, const size_t n, const double mean1, const double mean2); double gsl_stats_short_pvariance (const short data1[], const size_t stride1, const size_t n1, const short data2[], const size_t stride2, const size_t n2); double gsl_stats_short_ttest (const short data1[], const size_t stride1, const size_t n1, const short data2[], const size_t stride2, const size_t n2); short gsl_stats_short_max (const short data[], const size_t stride, const size_t n); short gsl_stats_short_min (const short data[], const size_t stride, const size_t n); void gsl_stats_short_minmax (short * min, short * max, const short data[], const size_t stride, const size_t n); size_t gsl_stats_short_max_index (const short data[], const size_t stride, const size_t n); size_t gsl_stats_short_min_index (const short data[], const size_t stride, const size_t n); void gsl_stats_short_minmax_index (size_t * min_index, size_t * max_index, const short data[], const size_t stride, const size_t n); double gsl_stats_short_median_from_sorted_data (const short sorted_data[], const size_t stride, const size_t n) ; double gsl_stats_short_quantile_from_sorted_data (const short sorted_data[], const size_t stride, const size_t n, const double f) ; __END_DECLS #endif /* __GSL_STATISTICS_SHORT_H__ */ praat-6.0.04/external/gsl/gsl_statistics_uchar.h000066400000000000000000000111441261542461700217220ustar00rootroot00000000000000/* statistics/gsl_statistics_uchar.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_STATISTICS_UCHAR_H__ #define __GSL_STATISTICS_UCHAR_H__ #include #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS double gsl_stats_uchar_mean (const unsigned char data[], const size_t stride, const size_t n); double gsl_stats_uchar_variance (const unsigned char data[], const size_t stride, const size_t n); double gsl_stats_uchar_sd (const unsigned char data[], const size_t stride, const size_t n); double gsl_stats_uchar_variance_with_fixed_mean (const unsigned char data[], const size_t stride, const size_t n, const double mean); double gsl_stats_uchar_sd_with_fixed_mean (const unsigned char data[], const size_t stride, const size_t n, const double mean); double gsl_stats_uchar_absdev (const unsigned char data[], const size_t stride, const size_t n); double gsl_stats_uchar_skew (const unsigned char data[], const size_t stride, const size_t n); double gsl_stats_uchar_kurtosis (const unsigned char data[], const size_t stride, const size_t n); double gsl_stats_uchar_lag1_autocorrelation (const unsigned char data[], const size_t stride, const size_t n); double gsl_stats_uchar_covariance (const unsigned char data1[], const size_t stride1,const unsigned char data2[], const size_t stride2, const size_t n); double gsl_stats_uchar_correlation (const unsigned char data1[], const size_t stride1,const unsigned char data2[], const size_t stride2, const size_t n); double gsl_stats_uchar_variance_m (const unsigned char data[], const size_t stride, const size_t n, const double mean); double gsl_stats_uchar_sd_m (const unsigned char data[], const size_t stride, const size_t n, const double mean); double gsl_stats_uchar_absdev_m (const unsigned char data[], const size_t stride, const size_t n, const double mean); double gsl_stats_uchar_skew_m_sd (const unsigned char data[], const size_t stride, const size_t n, const double mean, const double sd); double gsl_stats_uchar_kurtosis_m_sd (const unsigned char data[], const size_t stride, const size_t n, const double mean, const double sd); double gsl_stats_uchar_lag1_autocorrelation_m (const unsigned char data[], const size_t stride, const size_t n, const double mean); double gsl_stats_uchar_covariance_m (const unsigned char data1[], const size_t stride1,const unsigned char data2[], const size_t stride2, const size_t n, const double mean1, const double mean2); double gsl_stats_uchar_pvariance (const unsigned char data1[], const size_t stride1, const size_t n1, const unsigned char data2[], const size_t stride2, const size_t n2); double gsl_stats_uchar_ttest (const unsigned char data1[], const size_t stride1, const size_t n1, const unsigned char data2[], const size_t stride2, const size_t n2); unsigned char gsl_stats_uchar_max (const unsigned char data[], const size_t stride, const size_t n); unsigned char gsl_stats_uchar_min (const unsigned char data[], const size_t stride, const size_t n); void gsl_stats_uchar_minmax (unsigned char * min, unsigned char * max, const unsigned char data[], const size_t stride, const size_t n); size_t gsl_stats_uchar_max_index (const unsigned char data[], const size_t stride, const size_t n); size_t gsl_stats_uchar_min_index (const unsigned char data[], const size_t stride, const size_t n); void gsl_stats_uchar_minmax_index (size_t * min_index, size_t * max_index, const unsigned char data[], const size_t stride, const size_t n); double gsl_stats_uchar_median_from_sorted_data (const unsigned char sorted_data[], const size_t stride, const size_t n) ; double gsl_stats_uchar_quantile_from_sorted_data (const unsigned char sorted_data[], const size_t stride, const size_t n, const double f) ; __END_DECLS #endif /* __GSL_STATISTICS_UCHAR_H__ */ praat-6.0.04/external/gsl/gsl_statistics_uint.h000066400000000000000000000110371261542461700216000ustar00rootroot00000000000000/* statistics/gsl_statistics_uint.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_STATISTICS_UINT_H__ #define __GSL_STATISTICS_UINT_H__ #include #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS double gsl_stats_uint_mean (const unsigned int data[], const size_t stride, const size_t n); double gsl_stats_uint_variance (const unsigned int data[], const size_t stride, const size_t n); double gsl_stats_uint_sd (const unsigned int data[], const size_t stride, const size_t n); double gsl_stats_uint_variance_with_fixed_mean (const unsigned int data[], const size_t stride, const size_t n, const double mean); double gsl_stats_uint_sd_with_fixed_mean (const unsigned int data[], const size_t stride, const size_t n, const double mean); double gsl_stats_uint_absdev (const unsigned int data[], const size_t stride, const size_t n); double gsl_stats_uint_skew (const unsigned int data[], const size_t stride, const size_t n); double gsl_stats_uint_kurtosis (const unsigned int data[], const size_t stride, const size_t n); double gsl_stats_uint_lag1_autocorrelation (const unsigned int data[], const size_t stride, const size_t n); double gsl_stats_uint_covariance (const unsigned int data1[], const size_t stride1,const unsigned int data2[], const size_t stride2, const size_t n); double gsl_stats_uint_correlation (const unsigned int data1[], const size_t stride1,const unsigned int data2[], const size_t stride2, const size_t n); double gsl_stats_uint_variance_m (const unsigned int data[], const size_t stride, const size_t n, const double mean); double gsl_stats_uint_sd_m (const unsigned int data[], const size_t stride, const size_t n, const double mean); double gsl_stats_uint_absdev_m (const unsigned int data[], const size_t stride, const size_t n, const double mean); double gsl_stats_uint_skew_m_sd (const unsigned int data[], const size_t stride, const size_t n, const double mean, const double sd); double gsl_stats_uint_kurtosis_m_sd (const unsigned int data[], const size_t stride, const size_t n, const double mean, const double sd); double gsl_stats_uint_lag1_autocorrelation_m (const unsigned int data[], const size_t stride, const size_t n, const double mean); double gsl_stats_uint_covariance_m (const unsigned int data1[], const size_t stride1,const unsigned int data2[], const size_t stride2, const size_t n, const double mean1, const double mean2); double gsl_stats_uint_pvariance (const unsigned int data1[], const size_t stride1, const size_t n1, const unsigned int data2[], const size_t stride2, const size_t n2); double gsl_stats_uint_ttest (const unsigned int data1[], const size_t stride1, const size_t n1, const unsigned int data2[], const size_t stride2, const size_t n2); unsigned int gsl_stats_uint_max (const unsigned int data[], const size_t stride, const size_t n); unsigned int gsl_stats_uint_min (const unsigned int data[], const size_t stride, const size_t n); void gsl_stats_uint_minmax (unsigned int * min, unsigned int * max, const unsigned int data[], const size_t stride, const size_t n); size_t gsl_stats_uint_max_index (const unsigned int data[], const size_t stride, const size_t n); size_t gsl_stats_uint_min_index (const unsigned int data[], const size_t stride, const size_t n); void gsl_stats_uint_minmax_index (size_t * min_index, size_t * max_index, const unsigned int data[], const size_t stride, const size_t n); double gsl_stats_uint_median_from_sorted_data (const unsigned int sorted_data[], const size_t stride, const size_t n) ; double gsl_stats_uint_quantile_from_sorted_data (const unsigned int sorted_data[], const size_t stride, const size_t n, const double f) ; __END_DECLS #endif /* __GSL_STATISTICS_UINT_H__ */ praat-6.0.04/external/gsl/gsl_statistics_ulong.h000066400000000000000000000111441261542461700217440ustar00rootroot00000000000000/* statistics/gsl_statistics_ulong.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_STATISTICS_ULONG_H__ #define __GSL_STATISTICS_ULONG_H__ #include #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS double gsl_stats_ulong_mean (const unsigned long data[], const size_t stride, const size_t n); double gsl_stats_ulong_variance (const unsigned long data[], const size_t stride, const size_t n); double gsl_stats_ulong_sd (const unsigned long data[], const size_t stride, const size_t n); double gsl_stats_ulong_variance_with_fixed_mean (const unsigned long data[], const size_t stride, const size_t n, const double mean); double gsl_stats_ulong_sd_with_fixed_mean (const unsigned long data[], const size_t stride, const size_t n, const double mean); double gsl_stats_ulong_absdev (const unsigned long data[], const size_t stride, const size_t n); double gsl_stats_ulong_skew (const unsigned long data[], const size_t stride, const size_t n); double gsl_stats_ulong_kurtosis (const unsigned long data[], const size_t stride, const size_t n); double gsl_stats_ulong_lag1_autocorrelation (const unsigned long data[], const size_t stride, const size_t n); double gsl_stats_ulong_covariance (const unsigned long data1[], const size_t stride1,const unsigned long data2[], const size_t stride2, const size_t n); double gsl_stats_ulong_correlation (const unsigned long data1[], const size_t stride1,const unsigned long data2[], const size_t stride2, const size_t n); double gsl_stats_ulong_variance_m (const unsigned long data[], const size_t stride, const size_t n, const double mean); double gsl_stats_ulong_sd_m (const unsigned long data[], const size_t stride, const size_t n, const double mean); double gsl_stats_ulong_absdev_m (const unsigned long data[], const size_t stride, const size_t n, const double mean); double gsl_stats_ulong_skew_m_sd (const unsigned long data[], const size_t stride, const size_t n, const double mean, const double sd); double gsl_stats_ulong_kurtosis_m_sd (const unsigned long data[], const size_t stride, const size_t n, const double mean, const double sd); double gsl_stats_ulong_lag1_autocorrelation_m (const unsigned long data[], const size_t stride, const size_t n, const double mean); double gsl_stats_ulong_covariance_m (const unsigned long data1[], const size_t stride1,const unsigned long data2[], const size_t stride2, const size_t n, const double mean1, const double mean2); double gsl_stats_ulong_pvariance (const unsigned long data1[], const size_t stride1, const size_t n1, const unsigned long data2[], const size_t stride2, const size_t n2); double gsl_stats_ulong_ttest (const unsigned long data1[], const size_t stride1, const size_t n1, const unsigned long data2[], const size_t stride2, const size_t n2); unsigned long gsl_stats_ulong_max (const unsigned long data[], const size_t stride, const size_t n); unsigned long gsl_stats_ulong_min (const unsigned long data[], const size_t stride, const size_t n); void gsl_stats_ulong_minmax (unsigned long * min, unsigned long * max, const unsigned long data[], const size_t stride, const size_t n); size_t gsl_stats_ulong_max_index (const unsigned long data[], const size_t stride, const size_t n); size_t gsl_stats_ulong_min_index (const unsigned long data[], const size_t stride, const size_t n); void gsl_stats_ulong_minmax_index (size_t * min_index, size_t * max_index, const unsigned long data[], const size_t stride, const size_t n); double gsl_stats_ulong_median_from_sorted_data (const unsigned long sorted_data[], const size_t stride, const size_t n) ; double gsl_stats_ulong_quantile_from_sorted_data (const unsigned long sorted_data[], const size_t stride, const size_t n, const double f) ; __END_DECLS #endif /* __GSL_STATISTICS_ULONG_H__ */ praat-6.0.04/external/gsl/gsl_statistics_ushort.h000066400000000000000000000112511261542461700221430ustar00rootroot00000000000000/* statistics/gsl_statistics_ushort.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_STATISTICS_USHORT_H__ #define __GSL_STATISTICS_USHORT_H__ #include #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS double gsl_stats_ushort_mean (const unsigned short data[], const size_t stride, const size_t n); double gsl_stats_ushort_variance (const unsigned short data[], const size_t stride, const size_t n); double gsl_stats_ushort_sd (const unsigned short data[], const size_t stride, const size_t n); double gsl_stats_ushort_variance_with_fixed_mean (const unsigned short data[], const size_t stride, const size_t n, const double mean); double gsl_stats_ushort_sd_with_fixed_mean (const unsigned short data[], const size_t stride, const size_t n, const double mean); double gsl_stats_ushort_absdev (const unsigned short data[], const size_t stride, const size_t n); double gsl_stats_ushort_skew (const unsigned short data[], const size_t stride, const size_t n); double gsl_stats_ushort_kurtosis (const unsigned short data[], const size_t stride, const size_t n); double gsl_stats_ushort_lag1_autocorrelation (const unsigned short data[], const size_t stride, const size_t n); double gsl_stats_ushort_covariance (const unsigned short data1[], const size_t stride1,const unsigned short data2[], const size_t stride2, const size_t n); double gsl_stats_ushort_correlation (const unsigned short data1[], const size_t stride1,const unsigned short data2[], const size_t stride2, const size_t n); double gsl_stats_ushort_variance_m (const unsigned short data[], const size_t stride, const size_t n, const double mean); double gsl_stats_ushort_sd_m (const unsigned short data[], const size_t stride, const size_t n, const double mean); double gsl_stats_ushort_absdev_m (const unsigned short data[], const size_t stride, const size_t n, const double mean); double gsl_stats_ushort_skew_m_sd (const unsigned short data[], const size_t stride, const size_t n, const double mean, const double sd); double gsl_stats_ushort_kurtosis_m_sd (const unsigned short data[], const size_t stride, const size_t n, const double mean, const double sd); double gsl_stats_ushort_lag1_autocorrelation_m (const unsigned short data[], const size_t stride, const size_t n, const double mean); double gsl_stats_ushort_covariance_m (const unsigned short data1[], const size_t stride1,const unsigned short data2[], const size_t stride2, const size_t n, const double mean1, const double mean2); double gsl_stats_ushort_pvariance (const unsigned short data1[], const size_t stride1, const size_t n1, const unsigned short data2[], const size_t stride2, const size_t n2); double gsl_stats_ushort_ttest (const unsigned short data1[], const size_t stride1, const size_t n1, const unsigned short data2[], const size_t stride2, const size_t n2); unsigned short gsl_stats_ushort_max (const unsigned short data[], const size_t stride, const size_t n); unsigned short gsl_stats_ushort_min (const unsigned short data[], const size_t stride, const size_t n); void gsl_stats_ushort_minmax (unsigned short * min, unsigned short * max, const unsigned short data[], const size_t stride, const size_t n); size_t gsl_stats_ushort_max_index (const unsigned short data[], const size_t stride, const size_t n); size_t gsl_stats_ushort_min_index (const unsigned short data[], const size_t stride, const size_t n); void gsl_stats_ushort_minmax_index (size_t * min_index, size_t * max_index, const unsigned short data[], const size_t stride, const size_t n); double gsl_stats_ushort_median_from_sorted_data (const unsigned short sorted_data[], const size_t stride, const size_t n) ; double gsl_stats_ushort_quantile_from_sorted_data (const unsigned short sorted_data[], const size_t stride, const size_t n, const double f) ; __END_DECLS #endif /* __GSL_STATISTICS_USHORT_H__ */ praat-6.0.04/external/gsl/gsl_sum.h000066400000000000000000000125341261542461700171560ustar00rootroot00000000000000/* sum/gsl_sum.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #ifndef __GSL_SUM_H__ #define __GSL_SUM_H__ #include #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS /* Workspace for Levin U Transform with error estimation, * * size = number of terms the workspace can handle * sum_plain = simple sum of series * q_num = backward diagonal of numerator; length = size * q_den = backward diagonal of denominator; length = size * dq_num = table of numerator derivatives; length = size**2 * dq_den = table of denominator derivatives; length = size**2 * dsum = derivative of sum wrt term i; length = size */ typedef struct { size_t size; size_t i; /* position in array */ size_t terms_used; /* number of calls */ double sum_plain; double *q_num; double *q_den; double *dq_num; double *dq_den; double *dsum; } gsl_sum_levin_u_workspace; gsl_sum_levin_u_workspace *gsl_sum_levin_u_alloc (size_t n); void gsl_sum_levin_u_free (gsl_sum_levin_u_workspace * w); /* Basic Levin-u acceleration method. * * array = array of series elements * n = size of array * sum_accel = result of summation acceleration * err = estimated error * * See [Fessler et al., ACM TOMS 9, 346 (1983) and TOMS-602] */ int gsl_sum_levin_u_accel (const double *array, const size_t n, gsl_sum_levin_u_workspace * w, double *sum_accel, double *abserr); /* Basic Levin-u acceleration method with constraints on the terms * used, * * array = array of series elements * n = size of array * min_terms = minimum number of terms to sum * max_terms = maximum number of terms to sum * sum_accel = result of summation acceleration * err = estimated error * * See [Fessler et al., ACM TOMS 9, 346 (1983) and TOMS-602] */ int gsl_sum_levin_u_minmax (const double *array, const size_t n, const size_t min_terms, const size_t max_terms, gsl_sum_levin_u_workspace * w, double *sum_accel, double *abserr); /* Basic Levin-u step w/o reference to the array of terms. * We only need to specify the value of the current term * to execute the step. See TOMS-745. * * sum = t0 + ... + t_{n-1} + term; term = t_{n} * * term = value of the series term to be added * n = position of term in series (starting from 0) * sum_accel = result of summation acceleration * sum_plain = simple sum of series */ int gsl_sum_levin_u_step (const double term, const size_t n, const size_t nmax, gsl_sum_levin_u_workspace * w, double *sum_accel); /* The following functions perform the same calculation without estimating the errors. They require O(N) storage instead of O(N^2). This may be useful for summing many similar series where the size of the error has already been estimated reliably and is not expected to change. */ typedef struct { size_t size; size_t i; /* position in array */ size_t terms_used; /* number of calls */ double sum_plain; double *q_num; double *q_den; double *dsum; } gsl_sum_levin_utrunc_workspace; gsl_sum_levin_utrunc_workspace *gsl_sum_levin_utrunc_alloc (size_t n); void gsl_sum_levin_utrunc_free (gsl_sum_levin_utrunc_workspace * w); int gsl_sum_levin_utrunc_accel (const double *array, const size_t n, gsl_sum_levin_utrunc_workspace * w, double *sum_accel, double *abserr_trunc); int gsl_sum_levin_utrunc_minmax (const double *array, const size_t n, const size_t min_terms, const size_t max_terms, gsl_sum_levin_utrunc_workspace * w, double *sum_accel, double *abserr_trunc); int gsl_sum_levin_utrunc_step (const double term, const size_t n, gsl_sum_levin_utrunc_workspace * w, double *sum_accel); __END_DECLS #endif /* __GSL_SUM_H__ */ praat-6.0.04/external/gsl/gsl_sum__levin_u.c000066400000000000000000000157561261542461700210420ustar00rootroot00000000000000/* sum/levin_u.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_test.h" #include "gsl_errno.h" #include "gsl_sum.h" int gsl_sum_levin_u_accel (const double *array, const size_t array_size, gsl_sum_levin_u_workspace * w, double *sum_accel, double *abserr) { return gsl_sum_levin_u_minmax (array, array_size, 0, array_size - 1, w, sum_accel, abserr); } int gsl_sum_levin_u_minmax (const double *array, const size_t array_size, const size_t min_terms, const size_t max_terms, gsl_sum_levin_u_workspace * w, double *sum_accel, double *abserr) { if (array_size == 0) { *sum_accel = 0.0; *abserr = 0.0; w->sum_plain = 0.0; w->terms_used = 0; return GSL_SUCCESS; } else if (array_size == 1) { *sum_accel = array[0]; *abserr = 0.0; w->sum_plain = array[0]; w->terms_used = 1; return GSL_SUCCESS; } else { const double SMALL = 0.01; const size_t nmax = GSL_MAX (max_terms, array_size) - 1; double noise_n = 0.0, noise_nm1 = 0.0; double trunc_n = 0.0, trunc_nm1 = 0.0; double actual_trunc_n = 0.0, actual_trunc_nm1 = 0.0; double result_n = 0.0, result_nm1 = 0.0; double variance = 0; size_t n; unsigned int i; int better = 0; int before = 0; int converging = 0; double least_trunc = GSL_DBL_MAX; double least_trunc_noise = GSL_DBL_MAX; double least_trunc_result; /* Calculate specified minimum number of terms. No convergence tests are made, and no truncation information is stored. */ for (n = 0; n < min_terms; n++) { const double t = array[n]; result_nm1 = result_n; gsl_sum_levin_u_step (t, n, nmax, w, &result_n); } least_trunc_result = result_n; variance = 0; for (i = 0; i < n; i++) { double dn = w->dsum[i] * GSL_MACH_EPS * array[i]; variance += dn * dn; } noise_n = sqrt (variance); /* Calculate up to maximum number of terms. Check truncation condition. */ for (; n <= nmax; n++) { const double t = array[n]; result_nm1 = result_n; gsl_sum_levin_u_step (t, n, nmax, w, &result_n); /* Compute the truncation error directly */ actual_trunc_nm1 = actual_trunc_n; actual_trunc_n = fabs (result_n - result_nm1); /* Average results to make a more reliable estimate of the real truncation error */ trunc_nm1 = trunc_n; trunc_n = 0.5 * (actual_trunc_n + actual_trunc_nm1); noise_nm1 = noise_n; variance = 0; for (i = 0; i <= n; i++) { double dn = w->dsum[i] * GSL_MACH_EPS * array[i]; variance += dn * dn; } noise_n = sqrt (variance); /* Determine if we are in the convergence region. */ better = (trunc_n < trunc_nm1 || trunc_n < SMALL * fabs (result_n)); converging = converging || (better && before); before = better; if (converging) { if (trunc_n < least_trunc) { /* Found a low truncation point in the convergence region. Save it. */ least_trunc_result = result_n; least_trunc = trunc_n; least_trunc_noise = noise_n; } if (noise_n > trunc_n / 3.0) break; if (trunc_n < 10.0 * GSL_MACH_EPS * fabs (result_n)) break; } } if (converging) { /* Stopped in the convergence region. Return result and error estimate. */ *sum_accel = least_trunc_result; *abserr = GSL_MAX_DBL (least_trunc, least_trunc_noise); w->terms_used = n; return GSL_SUCCESS; } else { /* Never reached the convergence region. Use the last calculated values. */ *sum_accel = result_n; *abserr = GSL_MAX_DBL (trunc_n, noise_n); w->terms_used = n; return GSL_SUCCESS; } } } int gsl_sum_levin_u_step (const double term, const size_t n, const size_t nmax, gsl_sum_levin_u_workspace * w, double *sum_accel) { #define I(i,j) ((i)*(nmax+1) + (j)) if (n == 0) { *sum_accel = term; w->sum_plain = term; w->q_den[0] = 1.0 / term; w->q_num[0] = 1.0; w->dq_den[I (0, 0)] = -1.0 / (term * term); w->dq_num[I (0, 0)] = 0.0; w->dsum[0] = 1.0; return GSL_SUCCESS; } else { double result; double factor = 1.0; double ratio = (double) n / (n + 1.0); unsigned int i; int j; w->sum_plain += term; w->q_den[n] = 1.0 / (term * (n + 1.0) * (n + 1.0)); w->q_num[n] = w->sum_plain * w->q_den[n]; for (i = 0; i < n; i++) { w->dq_den[I (i, n)] = 0; w->dq_num[I (i, n)] = w->q_den[n]; } w->dq_den[I (n, n)] = -w->q_den[n] / term; w->dq_num[I (n, n)] = w->q_den[n] + w->sum_plain * (w->dq_den[I (n, n)]); for (j = n - 1; j >= 0; j--) { double c = factor * (j + 1) / (n + 1); factor *= ratio; w->q_den[j] = w->q_den[j + 1] - c * w->q_den[j]; w->q_num[j] = w->q_num[j + 1] - c * w->q_num[j]; for (i = 0; i < n; i++) { w->dq_den[I (i, j)] = w->dq_den[I (i, j + 1)] - c * w->dq_den[I (i, j)]; w->dq_num[I (i, j)] = w->dq_num[I (i, j + 1)] - c * w->dq_num[I (i, j)]; } w->dq_den[I (n, j)] = w->dq_den[I (n, j + 1)]; w->dq_num[I (n, j)] = w->dq_num[I (n, j + 1)]; } result = w->q_num[0] / w->q_den[0]; *sum_accel = result; for (i = 0; i <= n; i++) { w->dsum[i] = (w->dq_num[I (i, 0)] - result * w->dq_den[I (i, 0)]) / w->q_den[0]; } return GSL_SUCCESS; } } praat-6.0.04/external/gsl/gsl_sum__levin_utrunc.c000066400000000000000000000135351261542461700221070ustar00rootroot00000000000000/* sum/levin_utrunc.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_math.h" #include "gsl_test.h" #include "gsl_errno.h" #include "gsl_sum.h" int gsl_sum_levin_utrunc_accel (const double *array, const size_t array_size, gsl_sum_levin_utrunc_workspace * w, double *sum_accel, double *abserr_trunc) { return gsl_sum_levin_utrunc_minmax (array, array_size, 0, array_size - 1, w, sum_accel, abserr_trunc); } int gsl_sum_levin_utrunc_minmax (const double *array, const size_t array_size, const size_t min_terms, const size_t max_terms, gsl_sum_levin_utrunc_workspace * w, double *sum_accel, double *abserr_trunc) { if (array_size == 0) { *sum_accel = 0.0; *abserr_trunc = 0.0; w->sum_plain = 0.0; w->terms_used = 0; return GSL_SUCCESS; } else if (array_size == 1) { *sum_accel = array[0]; *abserr_trunc = GSL_POSINF; w->sum_plain = array[0]; w->terms_used = 1; return GSL_SUCCESS; } else { const double SMALL = 0.01; const size_t nmax = GSL_MAX (max_terms, array_size) - 1; double trunc_n = 0.0, trunc_nm1 = 0.0; double actual_trunc_n = 0.0, actual_trunc_nm1 = 0.0; double result_n = 0.0, result_nm1 = 0.0; size_t n; int better = 0; int before = 0; int converging = 0; double least_trunc = GSL_DBL_MAX; double result_least_trunc; /* Calculate specified minimum number of terms. No convergence tests are made, and no truncation information is stored. */ for (n = 0; n < min_terms; n++) { const double t = array[n]; result_nm1 = result_n; gsl_sum_levin_utrunc_step (t, n, w, &result_n); } /* Assume the result after the minimum calculation is the best. */ result_least_trunc = result_n; /* Calculate up to maximum number of terms. Check truncation condition. */ for (; n <= nmax; n++) { const double t = array[n]; result_nm1 = result_n; gsl_sum_levin_utrunc_step (t, n, w, &result_n); /* Compute the truncation error directly */ actual_trunc_nm1 = actual_trunc_n; actual_trunc_n = fabs (result_n - result_nm1); /* Average results to make a more reliable estimate of the real truncation error */ trunc_nm1 = trunc_n; trunc_n = 0.5 * (actual_trunc_n + actual_trunc_nm1); /* Determine if we are in the convergence region. */ better = (trunc_n < trunc_nm1 || trunc_n < SMALL * fabs (result_n)); converging = converging || (better && before); before = better; if (converging) { if (trunc_n < least_trunc) { /* Found a low truncation point in the convergence region. Save it. */ least_trunc = trunc_n; result_least_trunc = result_n; } if (fabs (trunc_n / result_n) < 10.0 * GSL_MACH_EPS) break; } } if (converging) { /* Stopped in the convergence region. Return result and error estimate. */ *sum_accel = result_least_trunc; *abserr_trunc = least_trunc; w->terms_used = n; return GSL_SUCCESS; } else { /* Never reached the convergence region. Use the last calculated values. */ *sum_accel = result_n; *abserr_trunc = trunc_n; w->terms_used = n; return GSL_SUCCESS; } } } int gsl_sum_levin_utrunc_step (const double term, const size_t n, gsl_sum_levin_utrunc_workspace * w, double *sum_accel) { if (term == 0.0) { /* This is actually harmless when treated in this way. A term which is exactly zero is simply ignored; the state is not changed. We return GSL_EZERODIV as an indicator that this occured. */ return GSL_EZERODIV; } else if (n == 0) { *sum_accel = term; w->sum_plain = term; w->q_den[0] = 1.0 / term; w->q_num[0] = 1.0; return GSL_SUCCESS; } else { double factor = 1.0; double ratio = (double) n / (n + 1.0); int j; w->sum_plain += term; w->q_den[n] = 1.0 / (term * (n + 1.0) * (n + 1.0)); w->q_num[n] = w->sum_plain * w->q_den[n]; for (j = n - 1; j >= 0; j--) { double c = factor * (j + 1) / (n + 1); factor *= ratio; w->q_den[j] = w->q_den[j + 1] - c * w->q_den[j]; w->q_num[j] = w->q_num[j + 1] - c * w->q_num[j]; } *sum_accel = w->q_num[0] / w->q_den[0]; return GSL_SUCCESS; } } praat-6.0.04/external/gsl/gsl_sum__work_u.c000066400000000000000000000041021261542461700206660ustar00rootroot00000000000000#include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sum.h" gsl_sum_levin_u_workspace * gsl_sum_levin_u_alloc (size_t n) { gsl_sum_levin_u_workspace * w; if (n == 0) { GSL_ERROR_VAL ("length n must be positive integer", GSL_EDOM, 0); } w = (gsl_sum_levin_u_workspace *) malloc(sizeof(gsl_sum_levin_u_workspace)); if (w == NULL) { GSL_ERROR_VAL ("failed to allocate struct", GSL_ENOMEM, 0); } w->q_num = (double *) malloc (n * sizeof (double)); if (w->q_num == NULL) { free(w) ; /* error in constructor, prevent memory leak */ GSL_ERROR_VAL ("failed to allocate space for q_num", GSL_ENOMEM, 0); } w->q_den = (double *) malloc (n * sizeof (double)); if (w->q_den == NULL) { free (w->q_num); free (w) ; /* error in constructor, prevent memory leak */ GSL_ERROR_VAL ("failed to allocate space for q_den", GSL_ENOMEM, 0); } w->dq_num = (double *) malloc (n * n * sizeof (double)); if (w->dq_num == NULL) { free (w->q_den); free (w->q_num); free(w) ; /* error in constructor, prevent memory leak */ GSL_ERROR_VAL ("failed to allocate space for dq_num", GSL_ENOMEM, 0); } w->dq_den = (double *) malloc (n * n * sizeof (double)); if (w->dq_den == NULL) { free (w->dq_num); free (w->q_den); free (w->q_num); free (w) ; /* error in constructor, prevent memory leak */ GSL_ERROR_VAL ("failed to allocate space for dq_den", GSL_ENOMEM, 0); } w->dsum = (double *) malloc (n * sizeof (double)); if (w->dsum == NULL) { free (w->dq_den); free (w->dq_num); free (w->q_den); free (w->q_num); free (w) ; /* error in constructor, prevent memory leak */ GSL_ERROR_VAL ("failed to allocate space for dsum", GSL_ENOMEM, 0); } w->size = n; w->terms_used = 0; w->sum_plain = 0; return w; } void gsl_sum_levin_u_free (gsl_sum_levin_u_workspace * w) { free (w->dsum); free (w->dq_den); free (w->dq_num); free (w->q_den); free (w->q_num); free (w); } praat-6.0.04/external/gsl/gsl_sum__work_utrunc.c000066400000000000000000000026721261542461700217540ustar00rootroot00000000000000#include "gsl__config.h" #include "gsl_math.h" #include "gsl_errno.h" #include "gsl_sum.h" gsl_sum_levin_utrunc_workspace * gsl_sum_levin_utrunc_alloc (size_t n) { gsl_sum_levin_utrunc_workspace * w; if (n == 0) { GSL_ERROR_VAL ("length n must be positive integer", GSL_EDOM, 0); } w = (gsl_sum_levin_utrunc_workspace *) malloc(sizeof(gsl_sum_levin_utrunc_workspace)); if (w == NULL) { GSL_ERROR_VAL ("failed to allocate struct", GSL_ENOMEM, 0); } w->q_num = (double *) malloc (n * sizeof (double)); if (w->q_num == NULL) { free(w) ; /* error in constructor, prevent memory leak */ GSL_ERROR_VAL ("failed to allocate space for q_num", GSL_ENOMEM, 0); } w->q_den = (double *) malloc (n * sizeof (double)); if (w->q_den == NULL) { free (w->q_num); free (w) ; /* error in constructor, prevent memory leak */ GSL_ERROR_VAL ("failed to allocate space for q_den", GSL_ENOMEM, 0); } w->dsum = (double *) malloc (n * sizeof (double)); if (w->dsum == NULL) { free (w->q_den); free (w->q_num); free (w) ; /* error in constructor, prevent memory leak */ GSL_ERROR_VAL ("failed to allocate space for dsum", GSL_ENOMEM, 0); } w->size = n; w->terms_used = 0; w->sum_plain = 0; return w; } void gsl_sum_levin_utrunc_free (gsl_sum_levin_utrunc_workspace * w) { free (w->dsum); free (w->q_den); free (w->q_num); free (w); } praat-6.0.04/external/gsl/gsl_sys.h000066400000000000000000000036421261542461700171700ustar00rootroot00000000000000/* sys/gsl_sys.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_SYS_H__ #define __GSL_SYS_H__ #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS double gsl_log1p (const double x); double gsl_expm1 (const double x); double gsl_hypot (const double x, const double y); double gsl_hypot3 (const double x, const double y, const double z); double gsl_acosh (const double x); double gsl_asinh (const double x); double gsl_atanh (const double x); int gsl_isnan (const double x); int gsl_isinf (const double x); int gsl_finite (const double x); double gsl_nan (void); double gsl_posinf (void); double gsl_neginf (void); double gsl_fdiv (const double x, const double y); double gsl_coerce_double (const double x); float gsl_coerce_float (const float x); long double gsl_coerce_long_double (const long double x); double gsl_ldexp(const double x, const int e); double gsl_frexp(const double x, int * e); int gsl_fcmp (const double x1, const double x2, const double epsilon); __END_DECLS #endif /* __GSL_SYS_H__ */ praat-6.0.04/external/gsl/gsl_sys__coerce.c000066400000000000000000000025251261542461700206410ustar00rootroot00000000000000/* sys/coerce.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include double gsl_coerce_double (const double x); double gsl_coerce_double (const double x) { volatile double y; y = x; return y; } float gsl_coerce_float (const float x); float gsl_coerce_float (const float x) { volatile float y; y = x; return y; } /* The following function is not needed, but is included for completeness */ long double gsl_coerce_long_double (const long double x); long double gsl_coerce_long_double (const long double x) { volatile long double y; y = x; return y; } praat-6.0.04/external/gsl/gsl_sys__expm1.c000066400000000000000000000025401261542461700204300ustar00rootroot00000000000000/* sys/expm1.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" double gsl_expm1 (const double x) { /* FIXME: this should be improved */ if (fabs(x) < M_LN2) { /* Compute the taylor series S = x + (1/2!) x^2 + (1/3!) x^3 + ... */ double i = 1.0; double sum = x; double term = x / 1.0; do { i++ ; term *= x/i; sum += term; } while (fabs(term) > fabs(sum) * GSL_DBL_EPSILON) ; return sum ; } else { return exp(x) - 1; } } praat-6.0.04/external/gsl/gsl_sys__fcmp.c000066400000000000000000000032101261542461700203160ustar00rootroot00000000000000/* sys/gsl_compare.c * * Copyright (C) 2002 Gert Van den Eynde * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Based on fcmp 1.2.2 Copyright (c) 1998-2000 Theodore C. Belding * University of Michigan Center for the Study of Complex Systems * Ted.Belding@umich.edu * */ #include "gsl__config.h" #include "gsl_sys.h" #include int gsl_fcmp (const double x1, const double x2, const double epsilon) { int exponent; double delta, difference; /* Find exponent of largest absolute value */ { double max = (fabs (x1) > fabs (x2)) ? x1 : x2; frexp (max, &exponent); } /* Form a neighborhood of size 2 * delta */ delta = ldexp (epsilon, exponent); difference = x1 - x2; if (difference > delta) /* x1 > x2 */ { return 1; } else if (difference < -delta) /* x1 < x2 */ { return -1; } else /* -delta <= difference <= delta */ { return 0; /* x1 ~=~ x2 */ } } praat-6.0.04/external/gsl/gsl_sys__fdiv.c000066400000000000000000000016701261542461700203310ustar00rootroot00000000000000/* sys/fdiv.c * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include double gsl_fdiv (const double x, const double y); double gsl_fdiv (const double x, const double y) { return x / y; } praat-6.0.04/external/gsl/gsl_sys__hypot.c000066400000000000000000000034271261542461700205460ustar00rootroot00000000000000/* sys/hypot.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough, Patrick Alken * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" double gsl_hypot (const double x, const double y); double gsl_hypot3 (const double x, const double y, const double z); double gsl_hypot (const double x, const double y) { double xabs = fabs(x) ; double yabs = fabs(y) ; double min, max; if (xabs < yabs) { min = xabs ; max = yabs ; } else { min = yabs ; max = xabs ; } if (min == 0) { return max ; } { double u = min / max ; return max * sqrt (1 + u * u) ; } } double gsl_hypot3(const double x, const double y, const double z) { double xabs = fabs(x); double yabs = fabs(y); double zabs = fabs(z); double w = GSL_MAX(xabs, GSL_MAX(yabs, zabs)); if (w == 0.0) { return (0.0); } else { double r = w * sqrt((xabs / w) * (xabs / w) + (yabs / w) * (yabs / w) + (zabs / w) * (zabs / w)); return r; } } praat-6.0.04/external/gsl/gsl_sys__infnan.c000066400000000000000000000045461261542461700206570ustar00rootroot00000000000000/* sys/infnan.c * * Copyright (C) 2001, 2004, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #if HAVE_IEEEFP_H #include #endif double gsl_nan (void); double gsl_posinf (void); double gsl_neginf (void); double gsl_fdiv (const double x, const double y); double gsl_nan (void) { return gsl_fdiv (0.0, 0.0); } double gsl_posinf (void) { return gsl_fdiv (+1.0, 0.0); } double gsl_neginf (void) { return gsl_fdiv (-1.0, 0.0); } int gsl_isnan (const double x); int gsl_isinf (const double x); int gsl_finite (const double x); #if defined(_MSC_VER) /* Microsoft Visual C++ */ #include int gsl_isnan (const double x) { return _isnan(x); } int gsl_isinf (const double x) { int fpc = _fpclass(x); if (fpc == _FPCLASS_PINF) return +1; else if (fpc == _FPCLASS_NINF) return -1; else return 0; } int gsl_finite (const double x) { return _finite(x); } #else # if HAVE_DECL_ISFINITE int gsl_finite (const double x) { return isfinite(x); } # elif HAVE_DECL_FINITE int gsl_finite (const double x) { return finite(x); } # elif HAVE_IEEE_COMPARISONS int gsl_finite (const double x) { const double y = x - x; int status = (y == y); return status; } # endif # if HAVE_DECL_ISNAN int gsl_isnan (const double x) { return isnan(x); } #elif HAVE_IEEE_COMPARISONS int gsl_isnan (const double x) { int status = (x != x); return status; } # endif # if HAVE_DECL_ISINF int gsl_isinf (const double x) { return isinf(x); } # else int gsl_isinf (const double x) { if (! gsl_finite(x) && ! gsl_isnan(x)) { return (x > 0 ? +1 : -1); } else { return 0; } } # endif #endif praat-6.0.04/external/gsl/gsl_sys__invhyp.c000066400000000000000000000041671261542461700207220ustar00rootroot00000000000000/* sys/invhyp.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_machine.h" double gsl_acosh (const double x) { if (x > 1.0 / GSL_SQRT_DBL_EPSILON) { return log (x) + M_LN2; } else if (x > 2) { return log (2 * x - 1 / (sqrt (x * x - 1) + x)); } else if (x > 1) { double t = x - 1; return log1p (t + sqrt (2 * t + t * t)); } else if (x == 1) { return 0; } else { return GSL_NAN; } } double gsl_asinh (const double x) { double a = fabs (x); double s = (x < 0) ? -1 : 1; if (a > 1 / GSL_SQRT_DBL_EPSILON) { return s * (log (a) + M_LN2); } else if (a > 2) { return s * log (2 * a + 1 / (a + sqrt (a * a + 1))); } else if (a > GSL_SQRT_DBL_EPSILON) { double a2 = a * a; return s * log1p (a + a2 / (1 + sqrt (1 + a2))); } else { return x; } } double gsl_atanh (const double x) { double a = fabs (x); double s = (x < 0) ? -1 : 1; if (a > 1) { return GSL_NAN; } else if (a == 1) { return (x < 0) ? GSL_NEGINF : GSL_POSINF; } else if (a >= 0.5) { return s * 0.5 * log1p (2 * a / (1 - a)); } else if (a > GSL_DBL_EPSILON) { return s * 0.5 * log1p (2 * a + 2 * a * a / (1 - a)); } else { return x; } } praat-6.0.04/external/gsl/gsl_sys__ldfrexp.c000066400000000000000000000026021261542461700210410ustar00rootroot00000000000000/* sys/ldfrexp.c * * Copyright (C) 2002, Gert Van den Eynde * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_math.h" double gsl_ldexp (const double x, const int e) { double p2 = pow (2.0, (double)e); return x * p2; } double gsl_frexp (const double x, int *e) { if (x == 0.0) { *e = 0; return 0.0; } else { double ex = ceil (log (fabs (x)) / M_LN2); int ei = (int) ex; double f = gsl_ldexp (x, -ei); while (fabs (f) >= 1.0) { ei++; f /= 2.0; } while (fabs (f) < 0.5) { ei--; f *= 2.0; } *e = ei; return f; } } praat-6.0.04/external/gsl/gsl_sys__log1p.c000066400000000000000000000020531261542461700204170ustar00rootroot00000000000000/* sys/log1p.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include double gsl_log1p (const double x); double gsl_log1p (const double x) { volatile double y, z; y = 1 + x; z = y - 1; return log(y) - (z-x)/y ; /* cancels errors with IEEE arithmetic */ } praat-6.0.04/external/gsl/gsl_sys__minmax.c000066400000000000000000000036311261542461700206710ustar00rootroot00000000000000/* sys/minmax.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #define GSL_MAX(a,b) ((a) > (b) ? (a) : (b)) #define GSL_MIN(a,b) ((a) < (b) ? (a) : (b)) #ifndef HIDE_INLINE_STATIC int GSL_MAX_INT (int a, int b); int GSL_MIN_INT (int a, int b); double GSL_MAX_DBL (double a, double b); double GSL_MIN_DBL (double a, double b); long double GSL_MAX_LDBL (long double a, long double b); long double GSL_MIN_LDBL (long double a, long double b); int GSL_MAX_INT (int a, int b) { return GSL_MAX (a, b); } int GSL_MIN_INT (int a, int b) { return GSL_MIN (a, b); } double GSL_MAX_DBL (double a, double b) { return GSL_MAX (a, b); } double GSL_MIN_DBL (double a, double b) { return GSL_MIN (a, b); } long double GSL_MAX_LDBL (long double a, long double b) { return GSL_MAX (a, b); } long double GSL_MIN_LDBL (long double a, long double b) { return GSL_MIN (a, b); } #endif /* Define some static functions which are always available */ double gsl_max (double a, double b); double gsl_min (double a, double b); double gsl_max (double a, double b) { return GSL_MAX (a, b); } double gsl_min (double a, double b) { return GSL_MIN (a, b); } praat-6.0.04/external/gsl/gsl_sys__pow_int.c000066400000000000000000000033541261542461700210610ustar00rootroot00000000000000/* sys/pow_int.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_pow_int.h" #ifndef HIDE_INLINE_STATIC double gsl_pow_2(const double x) { return x*x; } double gsl_pow_3(const double x) { return x*x*x; } double gsl_pow_4(const double x) { double x2 = x*x; return x2*x2; } double gsl_pow_5(const double x) { double x2 = x*x; return x2*x2*x; } double gsl_pow_6(const double x) { double x2 = x*x; return x2*x2*x2; } double gsl_pow_7(const double x) { double x3 = x*x*x; return x3*x3*x; } double gsl_pow_8(const double x) { double x2 = x*x; double x4 = x2*x2; return x4*x4; } double gsl_pow_9(const double x) { double x3 = x*x*x; return x3*x3*x3; } #endif double gsl_pow_int(double x, int n) { double value = 1.0; if(n < 0) { x = 1.0/x; n = -n; } /* repeated squaring method * returns 0.0^0 = 1.0, so continuous in x */ do { if(n & 1) value *= x; /* for n odd */ n >>= 1; x *= x; } while (n); return value; } praat-6.0.04/external/gsl/gsl_sys__prec.c000066400000000000000000000036411261542461700203320ustar00rootroot00000000000000/* sys/prec.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Author: G. Jungman */ #include "gsl__config.h" #include "gsl_machine.h" #include "gsl_precision.h" const double gsl_prec_eps[_GSL_PREC_T_NUM] = { GSL_DBL_EPSILON, GSL_FLT_EPSILON, GSL_SFLT_EPSILON }; const double gsl_prec_sqrt_eps[_GSL_PREC_T_NUM] = { GSL_SQRT_DBL_EPSILON, GSL_SQRT_FLT_EPSILON, GSL_SQRT_SFLT_EPSILON }; const double gsl_prec_root3_eps[_GSL_PREC_T_NUM] = { GSL_ROOT3_DBL_EPSILON, GSL_ROOT3_FLT_EPSILON, GSL_ROOT3_SFLT_EPSILON }; const double gsl_prec_root4_eps[_GSL_PREC_T_NUM] = { GSL_ROOT4_DBL_EPSILON, GSL_ROOT4_FLT_EPSILON, GSL_ROOT4_SFLT_EPSILON }; const double gsl_prec_root5_eps[_GSL_PREC_T_NUM] = { GSL_ROOT5_DBL_EPSILON, GSL_ROOT5_FLT_EPSILON, GSL_ROOT5_SFLT_EPSILON }; const double gsl_prec_root6_eps[_GSL_PREC_T_NUM] = { GSL_ROOT6_DBL_EPSILON, GSL_ROOT6_FLT_EPSILON, GSL_ROOT6_SFLT_EPSILON }; typedef unsigned int gsl_mode_t; #ifndef HIDE_INLINE_STATIC /* We need this somewhere, in case the inline is ignored. */ unsigned int GSL_MODE_PREC(gsl_mode_t mt); unsigned int GSL_MODE_PREC(gsl_mode_t mt) { return (mt & (unsigned int)7); } #endif praat-6.0.04/external/gsl/gsl_test.h000066400000000000000000000034721261542461700173320ustar00rootroot00000000000000/* err/gsl_test.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_TEST_H__ #define __GSL_TEST_H__ #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS void gsl_test (int status, const char *test_description, ...); void gsl_test_rel (double result, double expected, double relative_error, const char *test_description, ...) ; void gsl_test_abs (double result, double expected, double absolute_error, const char *test_description, ...) ; void gsl_test_factor (double result, double expected, double factor, const char *test_description, ...) ; void gsl_test_int (int result, int expected, const char *test_description, ...) ; void gsl_test_str (const char * result, const char * expected, const char *test_description, ...) ; void gsl_test_verbose (int verbose) ; int gsl_test_summary (void) ; __END_DECLS #endif /* __GSL_TEST_H__ */ praat-6.0.04/external/gsl/gsl_types.h000066400000000000000000000021751261542461700175160ustar00rootroot00000000000000/* gsl_types.h * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_TYPES_H__ #define __GSL_TYPES_H__ #ifndef GSL_VAR #ifdef WIN32 # ifdef GSL_DLL # ifdef DLL_EXPORT # define GSL_VAR extern __declspec(dllexport) # else # define GSL_VAR extern __declspec(dllimport) # endif # else # define GSL_VAR extern # endif #else # define GSL_VAR extern #endif #endif #endif /* __GSL_TYPES_H__ */ praat-6.0.04/external/gsl/gsl_vector.h000066400000000000000000000010361261542461700176470ustar00rootroot00000000000000#ifndef __GSL_VECTOR_H__ #define __GSL_VECTOR_H__ #include "gsl_vector_complex_long_double.h" #include "gsl_vector_complex_double.h" #include "gsl_vector_complex_float.h" #include "gsl_vector_long_double.h" #include "gsl_vector_double.h" #include "gsl_vector_float.h" #include "gsl_vector_ulong.h" #include "gsl_vector_long.h" #include "gsl_vector_uint.h" #include "gsl_vector_int.h" #include "gsl_vector_ushort.h" #include "gsl_vector_short.h" #include "gsl_vector_uchar.h" #include "gsl_vector_char.h" #endif /* __GSL_VECTOR_H__ */ praat-6.0.04/external/gsl/gsl_vector__copy.c000066400000000000000000000036261261542461700210420ustar00rootroot00000000000000#include "gsl__config.h" #include "gsl_vector.h" #include "gsl_errno.h" #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_vector__copy_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_vector__copy_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_vector__copy_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_vector__copy_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_vector__copy_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_vector__copy_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_vector__copy_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_vector__copy_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_vector__copy_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_vector__copy_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_vector__copy_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_vector__copy_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_vector__copy_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_vector__copy_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_vector__copy_source.c000066400000000000000000000030071261542461700224130ustar00rootroot00000000000000/* vector/copy_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ int FUNCTION (gsl_vector, memcpy) (TYPE (gsl_vector) * dest, const TYPE (gsl_vector) * src) { const size_t src_size = src->size; const size_t dest_size = dest->size; if (src_size != dest_size) { GSL_ERROR ("vector lengths are not equal", GSL_EBADLEN); } { const size_t src_stride = src->stride ; const size_t dest_stride = dest->stride ; size_t j; for (j = 0; j < src_size; j++) { size_t k; for (k = 0; k < MULTIPLICITY; k++) { dest->data[MULTIPLICITY * dest_stride * j + k] = src->data[MULTIPLICITY * src_stride * j + k]; } } } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_vector__file.c000066400000000000000000000037001261542461700210000ustar00rootroot00000000000000#include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_block.h" #include "gsl_vector.h" #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_vector__file_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_vector__file_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_vector__file_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_vector__file_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_vector__file_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_vector__file_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_vector__file_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_vector__file_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_vector__file_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_vector__file_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_vector__file_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_vector__file_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_vector__file_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_vector__file_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_vector__file_source.c000066400000000000000000000044341261542461700223650ustar00rootroot00000000000000/* vector/file_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ int FUNCTION (gsl_vector, fread) (FILE * stream, TYPE (gsl_vector) * v) { int status = FUNCTION (gsl_block, raw_fread) (stream, v->data, v->size, v->stride); return status; } int FUNCTION (gsl_vector, fwrite) (FILE * stream, const TYPE (gsl_vector) * v) { int status = FUNCTION (gsl_block, raw_fwrite) (stream, v->data, v->size, v->stride); return status; } #if !(USES_LONGDOUBLE && !HAVE_PRINTF_LONGDOUBLE) int FUNCTION (gsl_vector, fprintf) (FILE * stream, const TYPE (gsl_vector) * v, const char *format) { int status = FUNCTION (gsl_block, raw_fprintf) (stream, v->data, v->size, v->stride, format); return status; } int FUNCTION (gsl_vector, fscanf) (FILE * stream, TYPE (gsl_vector) * v) { int status = FUNCTION (gsl_block, raw_fscanf) (stream, v->data, v->size, v->stride); return status; } #endif praat-6.0.04/external/gsl/gsl_vector__init.c000066400000000000000000000036231261542461700210300ustar00rootroot00000000000000#include "gsl__config.h" #include #include "gsl_vector.h" #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_vector__init_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_vector__init_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_vector__init_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_vector__init_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_vector__init_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_vector__init_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_vector__init_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_vector__init_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_vector__init_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_vector__init_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_vector__init_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_vector__init_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_vector__init_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_vector__init_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_vector__init_source.c000066400000000000000000000120411261542461700224020ustar00rootroot00000000000000/* vector/init_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ TYPE (gsl_vector) * FUNCTION (gsl_vector, alloc) (const size_t n) { TYPE (gsl_block) * block; TYPE (gsl_vector) * v; if (n == 0) { GSL_ERROR_VAL ("vector length n must be positive integer", GSL_EINVAL, 0); } v = (TYPE (gsl_vector) *) malloc (sizeof (TYPE (gsl_vector))); if (v == 0) { GSL_ERROR_VAL ("failed to allocate space for vector struct", GSL_ENOMEM, 0); } block = FUNCTION (gsl_block,alloc) (n); if (block == 0) { free (v) ; GSL_ERROR_VAL ("failed to allocate space for block", GSL_ENOMEM, 0); } v->data = block->data ; v->size = n; v->stride = 1; v->block = block; v->owner = 1; return v; } TYPE (gsl_vector) * FUNCTION (gsl_vector, calloc) (const size_t n) { size_t i; TYPE (gsl_vector) * v = FUNCTION (gsl_vector, alloc) (n); if (v == 0) return 0; /* initialize vector to zero */ for (i = 0; i < MULTIPLICITY * n; i++) { v->data[i] = 0; } return v; } TYPE (gsl_vector) * FUNCTION (gsl_vector, alloc_from_block) (TYPE(gsl_block) * block, const size_t offset, const size_t n, const size_t stride) { TYPE (gsl_vector) * v; if (n == 0) { GSL_ERROR_VAL ("vector length n must be positive integer", GSL_EINVAL, 0); } if (stride == 0) { GSL_ERROR_VAL ("stride must be positive integer", GSL_EINVAL, 0); } if (block->size <= offset + (n - 1) * stride) { GSL_ERROR_VAL ("vector would extend past end of block", GSL_EINVAL, 0); } v = (TYPE (gsl_vector) *) malloc (sizeof (TYPE (gsl_vector))); if (v == 0) { GSL_ERROR_VAL ("failed to allocate space for vector struct", GSL_ENOMEM, 0); } v->data = block->data + MULTIPLICITY * offset ; v->size = n; v->stride = stride; v->block = block; v->owner = 0; return v; } TYPE (gsl_vector) * FUNCTION (gsl_vector, alloc_from_vector) (TYPE(gsl_vector) * w, const size_t offset, const size_t n, const size_t stride) { TYPE (gsl_vector) * v; if (n == 0) { GSL_ERROR_VAL ("vector length n must be positive integer", GSL_EINVAL, 0); } if (stride == 0) { GSL_ERROR_VAL ("stride must be positive integer", GSL_EINVAL, 0); } if (offset + (n - 1) * stride >= w->size) { GSL_ERROR_VAL ("vector would extend past end of block", GSL_EINVAL, 0); } v = (TYPE (gsl_vector) *) malloc (sizeof (TYPE (gsl_vector))); if (v == 0) { GSL_ERROR_VAL ("failed to allocate space for vector struct", GSL_ENOMEM, 0); } v->data = w->data + MULTIPLICITY * w->stride * offset ; v->size = n; v->stride = stride * w->stride; v->block = w->block; v->owner = 0; return v; } void FUNCTION (gsl_vector, free) (TYPE (gsl_vector) * v) { if (v->owner) { FUNCTION(gsl_block, free) (v->block) ; } free (v); } void FUNCTION (gsl_vector, set_all) (TYPE (gsl_vector) * v, BASE x) { ATOMIC * const data = v->data; const size_t n = v->size; const size_t stride = v->stride; size_t i; for (i = 0; i < n; i++) { *(BASE *) (data + MULTIPLICITY * i * stride) = x; } } void FUNCTION (gsl_vector, set_zero) (TYPE (gsl_vector) * v) { ATOMIC * const data = v->data; const size_t n = v->size; const size_t stride = v->stride; const BASE zero = ZERO ; size_t i; for (i = 0; i < n; i++) { *(BASE *) (data + MULTIPLICITY * i * stride) = zero; } } int FUNCTION (gsl_vector, set_basis) (TYPE (gsl_vector) * v, size_t i) { ATOMIC * const data = v->data; const size_t n = v->size; const size_t stride = v->stride; const BASE zero = ZERO ; const BASE one = ONE; size_t k; if (i >= n) { GSL_ERROR ("index out of range", GSL_EINVAL); } for (k = 0; k < n; k++) { *(BASE *) (data + MULTIPLICITY * k * stride) = zero; } *(BASE *) (data + MULTIPLICITY * i * stride) = one; return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_vector__minmax.c000066400000000000000000000030041261542461700213470ustar00rootroot00000000000000#include "gsl__config.h" #include #include "gsl_math.h" #include "gsl_vector.h" #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_vector__minmax_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_vector__minmax_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_vector__minmax_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_vector__minmax_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_vector__minmax_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_vector__minmax_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_vector__minmax_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_vector__minmax_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_vector__minmax_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_vector__minmax_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_vector__minmax_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_vector__minmax_source.c000066400000000000000000000100711261542461700227310ustar00rootroot00000000000000/* vector/minmax_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ BASE FUNCTION(gsl_vector,max) (const TYPE(gsl_vector) * v) { /* finds the largest element of a vector */ const size_t N = v->size ; const size_t stride = v->stride ; BASE max = v->data[0 * stride]; size_t i; for (i = 0; i < N; i++) { BASE x = v->data[i*stride]; if (x > max) max = x; #ifdef FP if (isnan (x)) return x; #endif } return max; } BASE FUNCTION(gsl_vector,min) (const TYPE(gsl_vector) * v) { /* finds the smallest element of a vector */ const size_t N = v->size ; const size_t stride = v->stride ; BASE min = v->data[0 * stride]; size_t i; for (i = 0; i < N; i++) { BASE x = v->data[i*stride]; if (x < min) min = x; #ifdef FP if (isnan (x)) return x; #endif } return min; } void FUNCTION(gsl_vector,minmax) (const TYPE(gsl_vector) * v, BASE * min_out, BASE * max_out) { /* finds the smallest and largest elements of a vector */ const size_t N = v->size ; const size_t stride = v->stride ; BASE max = v->data[0 * stride]; BASE min = v->data[0 * stride]; size_t i; for (i = 0; i < N; i++) { BASE x = v->data[i*stride]; if (x < min) { min = x; } if (x > max) { max = x; } #ifdef FP if (isnan (x)) { min = x; max = x; break; } #endif } *min_out = min; *max_out = max; } size_t FUNCTION(gsl_vector,max_index) (const TYPE(gsl_vector) * v) { /* finds the largest element of a vector */ const size_t N = v->size ; const size_t stride = v->stride ; BASE max = v->data[0 * stride]; size_t imax = 0; size_t i; for (i = 0; i < N; i++) { BASE x = v->data[i*stride]; if (x > max) { max = x; imax = i; } #ifdef FP if (isnan (x)) { return i; } #endif } return imax; } size_t FUNCTION(gsl_vector,min_index) (const TYPE(gsl_vector) * v) { /* finds the smallest element of a vector */ const size_t N = v->size ; const size_t stride = v->stride ; BASE min = v->data[0 * stride]; size_t imin = 0; size_t i; for (i = 0; i < N; i++) { BASE x = v->data[i*stride]; if (x < min) { min = x; imin = i; } #ifdef FP if (isnan (x)) { return i; } #endif } return imin; } void FUNCTION(gsl_vector,minmax_index) (const TYPE(gsl_vector) * v, size_t * imin_out, size_t * imax_out) { /* finds the smallest and largest elements of a vector */ const size_t N = v->size ; const size_t stride = v->stride ; size_t imin = 0, imax = 0; BASE max = v->data[0 * stride]; BASE min = v->data[0 * stride]; size_t i; for (i = 0; i < N; i++) { BASE x = v->data[i*stride]; if (x < min) { min = x; imin = i; } if (x > max) { max = x; imax = i; } #ifdef FP if (isnan (x)) { imin = i; imax = i; break; } #endif } *imin_out = imin; *imax_out = imax; } praat-6.0.04/external/gsl/gsl_vector__oper.c000066400000000000000000000027301261542461700210300ustar00rootroot00000000000000#include "gsl__config.h" #include #include "gsl_vector.h" #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_vector__oper_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_vector__oper_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_vector__oper_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_vector__oper_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_vector__oper_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_vector__oper_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_vector__oper_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_vector__oper_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_vector__oper_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_vector__oper_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_vector__oper_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_vector__oper_source.c000066400000000000000000000062311261542461700224100ustar00rootroot00000000000000/* vector/oper_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ int FUNCTION(gsl_vector, add) (TYPE(gsl_vector) * a, const TYPE(gsl_vector) * b) { const size_t N = a->size; if (b->size != N) { GSL_ERROR ("vectors must have same length", GSL_EBADLEN); } else { const size_t stride_a = a->stride; const size_t stride_b = b->stride; size_t i; for (i = 0; i < N; i++) { a->data[i * stride_a] += b->data[i * stride_b]; } return GSL_SUCCESS; } } int FUNCTION(gsl_vector, sub) (TYPE(gsl_vector) * a, const TYPE(gsl_vector) * b) { const size_t N = a->size; if (b->size != N) { GSL_ERROR ("vectors must have same length", GSL_EBADLEN); } else { const size_t stride_a = a->stride; const size_t stride_b = b->stride; size_t i; for (i = 0; i < N; i++) { a->data[i * stride_a] -= b->data[i * stride_b]; } return GSL_SUCCESS; } } int FUNCTION(gsl_vector, mul) (TYPE(gsl_vector) * a, const TYPE(gsl_vector) * b) { const size_t N = a->size; if (b->size != N) { GSL_ERROR ("vectors must have same length", GSL_EBADLEN); } else { const size_t stride_a = a->stride; const size_t stride_b = b->stride; size_t i; for (i = 0; i < N; i++) { a->data[i * stride_a] *= b->data[i * stride_b]; } return GSL_SUCCESS; } } int FUNCTION(gsl_vector, div) (TYPE(gsl_vector) * a, const TYPE(gsl_vector) * b) { const size_t N = a->size; if (b->size != N) { GSL_ERROR ("vectors must have same length", GSL_EBADLEN); } else { const size_t stride_a = a->stride; const size_t stride_b = b->stride; size_t i; for (i = 0; i < N; i++) { a->data[i * stride_a] /= b->data[i * stride_b]; } return GSL_SUCCESS; } } int FUNCTION(gsl_vector, scale) (TYPE(gsl_vector) * a, const double x) { const size_t N = a->size; const size_t stride = a->stride; size_t i; for (i = 0; i < N; i++) { a->data[i * stride] *= x; } return GSL_SUCCESS; } int FUNCTION(gsl_vector, add_constant) (TYPE(gsl_vector) * a, const double x) { const size_t N = a->size; const size_t stride = a->stride; size_t i; for (i = 0; i < N; i++) { a->data[i * stride] += x; } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_vector__prop.c000066400000000000000000000036261261542461700210500ustar00rootroot00000000000000#include "gsl__config.h" #include "gsl_vector.h" #include "gsl_errno.h" #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_vector__prop_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_vector__prop_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_vector__prop_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_vector__prop_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_vector__prop_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_vector__prop_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_vector__prop_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_vector__prop_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_vector__prop_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_vector__prop_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_vector__prop_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_vector__prop_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_vector__prop_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_vector__prop_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_vector__prop_source.c000066400000000000000000000045741261542461700224330ustar00rootroot00000000000000/* vector/prop_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ int FUNCTION (gsl_vector, isnull) (const TYPE (gsl_vector) * v) { const size_t n = v->size; const size_t stride = v->stride ; size_t j; for (j = 0; j < n; j++) { size_t k; for (k = 0; k < MULTIPLICITY; k++) { if (v->data[MULTIPLICITY * stride * j + k] != 0.0) { return 0; } } } return 1; } int FUNCTION (gsl_vector, ispos) (const TYPE (gsl_vector) * v) { const size_t n = v->size; const size_t stride = v->stride ; size_t j; for (j = 0; j < n; j++) { size_t k; for (k = 0; k < MULTIPLICITY; k++) { if (v->data[MULTIPLICITY * stride * j + k] <= 0.0) { return 0; } } } return 1; } int FUNCTION (gsl_vector, isneg) (const TYPE (gsl_vector) * v) { const size_t n = v->size; const size_t stride = v->stride ; size_t j; for (j = 0; j < n; j++) { size_t k; for (k = 0; k < MULTIPLICITY; k++) { if (v->data[MULTIPLICITY * stride * j + k] >= 0.0) { return 0; } } } return 1; } int FUNCTION (gsl_vector, isnonneg) (const TYPE (gsl_vector) * v) { const size_t n = v->size; const size_t stride = v->stride ; size_t j; for (j = 0; j < n; j++) { size_t k; for (k = 0; k < MULTIPLICITY; k++) { if (v->data[MULTIPLICITY * stride * j + k] < 0.0) { return 0; } } } return 1; } praat-6.0.04/external/gsl/gsl_vector__reim.c000066400000000000000000000020151261542461700210130ustar00rootroot00000000000000#include "gsl__config.h" #include #include "gsl_vector.h" #include "gsl_vector__view.h" #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_vector__reim_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_vector__reim_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_vector__reim_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define USE_QUALIFIER #define QUALIFIER const #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_vector__reim_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_vector__reim_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_vector__reim_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT praat-6.0.04/external/gsl/gsl_vector__reim_source.c000066400000000000000000000032321261542461700223750ustar00rootroot00000000000000/* vector/reim_source.c * * Copyright (C) 2001, 2007 Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ QUALIFIED_REAL_VIEW(_gsl_vector, view) FUNCTION(gsl_vector, real) (QUALIFIED_TYPE(gsl_vector) * v) { REAL_TYPE(gsl_vector) s = NULL_VECTOR; s.data = v->data; s.size = v->size; s.stride = MULTIPLICITY * v->stride; s.block = 0; /* FIXME: should be v->block, but cannot point to block of different type */ s.owner = 0; { QUALIFIED_REAL_VIEW(_gsl_vector,view) view = NULL_VECTOR_VIEW; view.vector = s; return view; } } QUALIFIED_REAL_VIEW(_gsl_vector, view) FUNCTION(gsl_vector, imag) (QUALIFIED_TYPE(gsl_vector) * v) { REAL_TYPE(gsl_vector) s = NULL_VECTOR; s.data = v->data + 1; s.size = v->size; s.stride = MULTIPLICITY * v->stride; s.block = 0; /* FIXME: cannot point to block of different type */ s.owner = 0; { QUALIFIED_REAL_VIEW(_gsl_vector,view) view = NULL_VECTOR_VIEW; view.vector = s; return view; } } praat-6.0.04/external/gsl/gsl_vector__subvector.c000066400000000000000000000076731261542461700221120ustar00rootroot00000000000000#include "gsl__config.h" #include #include "gsl_vector.h" #include "gsl_vector__view.h" #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_CHAR #define USE_QUALIFIER #define QUALIFIER const #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_vector__subvector_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_vector__subvector_source.c000066400000000000000000000045661261542461700234700ustar00rootroot00000000000000/* vector/subvector_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ QUALIFIED_VIEW(_gsl_vector, view) FUNCTION(gsl_vector, subvector) (QUALIFIED_TYPE(gsl_vector) * v, size_t offset, size_t n) { QUALIFIED_VIEW(_gsl_vector,view) view = NULL_VECTOR_VIEW; if (n == 0) { GSL_ERROR_VAL ("vector length n must be positive integer", GSL_EINVAL, view); } if (offset + (n - 1) >= v->size) { GSL_ERROR_VAL ("view would extend past end of vector", GSL_EINVAL, view); } { TYPE(gsl_vector) s = NULL_VECTOR; s.data = v->data + MULTIPLICITY * v->stride * offset ; s.size = n; s.stride = v->stride; s.block = v->block; s.owner = 0; view.vector = s; return view; } } QUALIFIED_VIEW(_gsl_vector, view) FUNCTION(gsl_vector, subvector_with_stride) (QUALIFIED_TYPE(gsl_vector) * v, size_t offset, size_t stride, size_t n) { QUALIFIED_VIEW(_gsl_vector,view) view = NULL_VECTOR_VIEW; if (n == 0) { GSL_ERROR_VAL ("vector length n must be positive integer", GSL_EINVAL, view); } if (stride == 0) { GSL_ERROR_VAL ("stride must be positive integer", GSL_EINVAL, view); } if (offset + (n - 1) * stride >= v->size) { GSL_ERROR_VAL ("view would extend past end of vector", GSL_EINVAL, view); } { TYPE(gsl_vector) s = NULL_VECTOR; s.data = v->data + MULTIPLICITY * v->stride * offset ; s.size = n; s.stride = v->stride * stride; s.block = v->block; s.owner = 0; view.vector = s; return view; } } praat-6.0.04/external/gsl/gsl_vector__swap.c000066400000000000000000000036261261542461700210420ustar00rootroot00000000000000#include "gsl__config.h" #include "gsl_errno.h" #include "gsl_vector.h" #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_vector__swap_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_vector__swap_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_vector__swap_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_vector__swap_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_vector__swap_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_vector__swap_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_vector__swap_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_vector__swap_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_vector__swap_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_vector__swap_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_vector__swap_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_vector__swap_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_vector__swap_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_vector__swap_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_vector__swap_source.c000066400000000000000000000050731261542461700224200ustar00rootroot00000000000000/* vector/swap_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ int FUNCTION (gsl_vector, swap) (TYPE (gsl_vector) * v, TYPE (gsl_vector) * w) { ATOMIC * d1 = v->data ; ATOMIC * d2 = w->data ; const size_t size = v->size ; const size_t s1 = MULTIPLICITY * v->stride ; const size_t s2 = MULTIPLICITY * w->stride ; size_t i, k ; if (v->size != w->size) { GSL_ERROR("vector lengths must be equal", GSL_EINVAL); } for (i = 0; i < size; i++) { for (k = 0; k < MULTIPLICITY; k++) { ATOMIC tmp = d1[i*s1 + k]; d1[i*s1+k] = d2[i*s2 + k]; d2[i*s2+k] = tmp; } } return GSL_SUCCESS; } int FUNCTION (gsl_vector, swap_elements) (TYPE (gsl_vector) * v, const size_t i, const size_t j) { ATOMIC * data = v->data ; const size_t size = v->size ; const size_t stride = v->stride ; if (i >= size) { GSL_ERROR("first index is out of range", GSL_EINVAL); } if (j >= size) { GSL_ERROR("second index is out of range", GSL_EINVAL); } if (i != j) { const size_t s = MULTIPLICITY * stride ; size_t k ; for (k = 0; k < MULTIPLICITY; k++) { ATOMIC tmp = data[j*s + k]; data[j*s+k] = data[i*s + k]; data[i*s+k] = tmp; } } return GSL_SUCCESS; } int FUNCTION (gsl_vector, reverse) (TYPE (gsl_vector) * v) { ATOMIC * data = v->data ; const size_t size = v->size ; const size_t stride = v->stride ; const size_t s = MULTIPLICITY * stride ; size_t i ; for (i = 0 ; i < (size / 2) ; i++) { size_t j = size - i - 1 ; size_t k; for (k = 0; k < MULTIPLICITY; k++) { ATOMIC tmp = data[j*s + k]; data[j*s+k] = data[i*s + k]; data[i*s+k] = tmp; } } return GSL_SUCCESS; } praat-6.0.04/external/gsl/gsl_vector__vector.c000066400000000000000000000054751261542461700213760ustar00rootroot00000000000000/* vector/vector.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_vector.h" /* turn off range checking at runtime if zero */ int gsl_check_range = 1; #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_vector__vector_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_vector__vector_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_vector__vector_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_vector__vector_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_vector__vector_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_vector__vector_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_vector__vector_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_vector__vector_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_vector__vector_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_vector__vector_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_vector__vector_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_vector__vector_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_vector__vector_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_vector__vector_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_vector__vector_source.c000066400000000000000000000046461261542461700227550ustar00rootroot00000000000000/* vector/vector_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef HIDE_INLINE_STATIC BASE FUNCTION (gsl_vector, get) (const TYPE (gsl_vector) * v, const size_t i) { if (gsl_check_range) { if (i >= v->size) /* size_t is unsigned, can't be negative */ { BASE zero = ZERO; GSL_ERROR_VAL ("index out of range", GSL_EINVAL, zero); } } /* The following line is a generalization of return v->data[i] */ return *(BASE *) (v->data + MULTIPLICITY * i * v->stride); } void FUNCTION (gsl_vector, set) (TYPE (gsl_vector) * v, const size_t i, BASE x) { if (gsl_check_range) { if (i >= v->size) /* size_t is unsigned, can't be negative */ { GSL_ERROR_VOID ("index out of range", GSL_EINVAL); } } /* The following line is a generalization of v->data[i] = x */ *(BASE *) (v->data + MULTIPLICITY * i * v->stride) = x; } BASE * FUNCTION (gsl_vector, ptr) (TYPE (gsl_vector) * v, const size_t i) { if (gsl_check_range) { if (i >= v->size) /* size_t is unsigned, can't be negative */ { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } } return (BASE *) (v->data + MULTIPLICITY * i * v->stride); } const BASE * FUNCTION (gsl_vector, const_ptr) (const TYPE (gsl_vector) * v, const size_t i) { if (gsl_check_range) { if (i >= v->size) /* size_t is unsigned, can't be negative */ { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } } /* The following line is a generalization of return v->data[i] */ return (const BASE *) (v->data + MULTIPLICITY * i * v->stride); } #endif praat-6.0.04/external/gsl/gsl_vector__view.c000066400000000000000000000074571261542461700210500ustar00rootroot00000000000000#include "gsl__config.h" #include #include "gsl_vector.h" #include "gsl_vector__view.h" #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_CHAR #define USE_QUALIFIER #define QUALIFIER const #define BASE_GSL_COMPLEX_LONG #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_LONG #define BASE_GSL_COMPLEX #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX #define BASE_GSL_COMPLEX_FLOAT #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_GSL_COMPLEX_FLOAT #define BASE_LONG_DOUBLE #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_LONG_DOUBLE #define BASE_DOUBLE #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_DOUBLE #define BASE_FLOAT #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_FLOAT #define BASE_ULONG #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_ULONG #define BASE_LONG #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_LONG #define BASE_UINT #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_UINT #define BASE_INT #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_INT #define BASE_USHORT #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_USHORT #define BASE_SHORT #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_SHORT #define BASE_UCHAR #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_UCHAR #define BASE_CHAR #include "templates_on.h" #include "gsl_vector__view_source.c" #include "templates_off.h" #undef BASE_CHAR praat-6.0.04/external/gsl/gsl_vector__view.h000066400000000000000000000001171261542461700210370ustar00rootroot00000000000000#define NULL_VECTOR {0, 0, 0, 0, 0} #define NULL_VECTOR_VIEW {{0, 0, 0, 0, 0}} praat-6.0.04/external/gsl/gsl_vector__view_source.c000066400000000000000000000040271261542461700224160ustar00rootroot00000000000000/* vector/view_source.c * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ QUALIFIED_VIEW(_gsl_vector,view) FUNCTION(gsl_vector, view_array) (QUALIFIER ATOMIC * base, size_t n) { QUALIFIED_VIEW(_gsl_vector,view) view = NULL_VECTOR_VIEW; if (n == 0) { GSL_ERROR_VAL ("vector length n must be positive integer", GSL_EINVAL, view); } { TYPE(gsl_vector) v = NULL_VECTOR; v.data = (ATOMIC *)base ; v.size = n; v.stride = 1; v.block = 0; v.owner = 0; view.vector = v; return view; } } QUALIFIED_VIEW(_gsl_vector,view) FUNCTION(gsl_vector, view_array_with_stride) (QUALIFIER ATOMIC * base, size_t stride, size_t n) { QUALIFIED_VIEW(_gsl_vector,view) view = NULL_VECTOR_VIEW; if (n == 0) { GSL_ERROR_VAL ("vector length n must be positive integer", GSL_EINVAL, view); } if (stride == 0) { GSL_ERROR_VAL ("stride must be positive integer", GSL_EINVAL, view); } { TYPE(gsl_vector) v = NULL_VECTOR; v.data = (ATOMIC *)base ; v.size = n; v.stride = stride; v.block = 0; v.owner = 0; view.vector = v; return view; } } praat-6.0.04/external/gsl/gsl_vector_char.h000066400000000000000000000156631261542461700206570ustar00rootroot00000000000000/* vector/gsl_vector_char.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_VECTOR_CHAR_H__ #define __GSL_VECTOR_CHAR_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_check_range.h" #include "gsl_block_char.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size; size_t stride; char *data; gsl_block_char *block; int owner; } gsl_vector_char; typedef struct { gsl_vector_char vector; } _gsl_vector_char_view; typedef _gsl_vector_char_view gsl_vector_char_view; typedef struct { gsl_vector_char vector; } _gsl_vector_char_const_view; typedef const _gsl_vector_char_const_view gsl_vector_char_const_view; /* Allocation */ gsl_vector_char *gsl_vector_char_alloc (const size_t n); gsl_vector_char *gsl_vector_char_calloc (const size_t n); gsl_vector_char *gsl_vector_char_alloc_from_block (gsl_block_char * b, const size_t offset, const size_t n, const size_t stride); gsl_vector_char *gsl_vector_char_alloc_from_vector (gsl_vector_char * v, const size_t offset, const size_t n, const size_t stride); void gsl_vector_char_free (gsl_vector_char * v); /* Views */ _gsl_vector_char_view gsl_vector_char_view_array (char *v, size_t n); _gsl_vector_char_view gsl_vector_char_view_array_with_stride (char *base, size_t stride, size_t n); _gsl_vector_char_const_view gsl_vector_char_const_view_array (const char *v, size_t n); _gsl_vector_char_const_view gsl_vector_char_const_view_array_with_stride (const char *base, size_t stride, size_t n); _gsl_vector_char_view gsl_vector_char_subvector (gsl_vector_char *v, size_t i, size_t n); _gsl_vector_char_view gsl_vector_char_subvector_with_stride (gsl_vector_char *v, size_t i, size_t stride, size_t n); _gsl_vector_char_const_view gsl_vector_char_const_subvector (const gsl_vector_char *v, size_t i, size_t n); _gsl_vector_char_const_view gsl_vector_char_const_subvector_with_stride (const gsl_vector_char *v, size_t i, size_t stride, size_t n); /* Operations */ char gsl_vector_char_get (const gsl_vector_char * v, const size_t i); void gsl_vector_char_set (gsl_vector_char * v, const size_t i, char x); char *gsl_vector_char_ptr (gsl_vector_char * v, const size_t i); const char *gsl_vector_char_const_ptr (const gsl_vector_char * v, const size_t i); void gsl_vector_char_set_zero (gsl_vector_char * v); void gsl_vector_char_set_all (gsl_vector_char * v, char x); int gsl_vector_char_set_basis (gsl_vector_char * v, size_t i); int gsl_vector_char_fread (FILE * stream, gsl_vector_char * v); int gsl_vector_char_fwrite (FILE * stream, const gsl_vector_char * v); int gsl_vector_char_fscanf (FILE * stream, gsl_vector_char * v); int gsl_vector_char_fprintf (FILE * stream, const gsl_vector_char * v, const char *format); int gsl_vector_char_memcpy (gsl_vector_char * dest, const gsl_vector_char * src); int gsl_vector_char_reverse (gsl_vector_char * v); int gsl_vector_char_swap (gsl_vector_char * v, gsl_vector_char * w); int gsl_vector_char_swap_elements (gsl_vector_char * v, const size_t i, const size_t j); char gsl_vector_char_max (const gsl_vector_char * v); char gsl_vector_char_min (const gsl_vector_char * v); void gsl_vector_char_minmax (const gsl_vector_char * v, char * min_out, char * max_out); size_t gsl_vector_char_max_index (const gsl_vector_char * v); size_t gsl_vector_char_min_index (const gsl_vector_char * v); void gsl_vector_char_minmax_index (const gsl_vector_char * v, size_t * imin, size_t * imax); int gsl_vector_char_add (gsl_vector_char * a, const gsl_vector_char * b); int gsl_vector_char_sub (gsl_vector_char * a, const gsl_vector_char * b); int gsl_vector_char_mul (gsl_vector_char * a, const gsl_vector_char * b); int gsl_vector_char_div (gsl_vector_char * a, const gsl_vector_char * b); int gsl_vector_char_scale (gsl_vector_char * a, const double x); int gsl_vector_char_add_constant (gsl_vector_char * a, const double x); int gsl_vector_char_isnull (const gsl_vector_char * v); int gsl_vector_char_ispos (const gsl_vector_char * v); int gsl_vector_char_isneg (const gsl_vector_char * v); int gsl_vector_char_isnonneg (const gsl_vector_char * v); #ifdef HAVE_INLINE extern inline char gsl_vector_char_get (const gsl_vector_char * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); } #endif return v->data[i * v->stride]; } extern inline void gsl_vector_char_set (gsl_vector_char * v, const size_t i, char x) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_VOID ("index out of range", GSL_EINVAL); } #endif v->data[i * v->stride] = x; } extern inline char * gsl_vector_char_ptr (gsl_vector_char * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return (char *) (v->data + i * v->stride); } extern inline const char * gsl_vector_char_const_ptr (const gsl_vector_char * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return (const char *) (v->data + i * v->stride); } #endif /* HAVE_INLINE */ __END_DECLS #endif /* __GSL_VECTOR_CHAR_H__ */ praat-6.0.04/external/gsl/gsl_vector_complex.h000066400000000000000000000013731261542461700214020ustar00rootroot00000000000000#ifndef __GSL_VECTOR_COMPLEX_H__ #define __GSL_VECTOR_COMPLEX_H__ #define GSL_VECTOR_REAL(z, i) ((z)->data[2*(i)*(z)->stride]) #define GSL_VECTOR_IMAG(z, i) ((z)->data[2*(i)*(z)->stride + 1]) #if GSL_RANGE_CHECK #define GSL_VECTOR_COMPLEX(zv, i) (((i) >= (zv)->size ? (gsl_error ("index out of range", __FILE__, __LINE__, GSL_EINVAL), 0):0 , *GSL_COMPLEX_AT((zv),(i)))) #else #define GSL_VECTOR_COMPLEX(zv, i) (GSL_COMPLEX_AT((zv),(i))) #endif #define GSL_COMPLEX_AT(zv,i) ((gsl_complex*)&((zv)->data[2*(i)*(zv)->stride])) #define GSL_COMPLEX_FLOAT_AT(zv,i) ((gsl_complex_float*)&((zv)->data[2*(i)*(zv)->stride])) #define GSL_COMPLEX_LONG_DOUBLE_AT(zv,i) ((gsl_complex_long_double*)&((zv)->data[2*(i)*(zv)->stride])) #endif /* __GSL_VECTOR_COMPLEX_H__ */ praat-6.0.04/external/gsl/gsl_vector_complex_double.h000066400000000000000000000166101261542461700227340ustar00rootroot00000000000000/* vector/gsl_vector_complex_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_VECTOR_COMPLEX_DOUBLE_H__ #define __GSL_VECTOR_COMPLEX_DOUBLE_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_complex.h" #include "gsl_check_range.h" #include "gsl_vector_double.h" #include "gsl_vector_complex.h" #include "gsl_block_complex_double.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size; size_t stride; double *data; gsl_block_complex *block; int owner; } gsl_vector_complex; typedef struct { gsl_vector_complex vector; } _gsl_vector_complex_view; typedef _gsl_vector_complex_view gsl_vector_complex_view; typedef struct { gsl_vector_complex vector; } _gsl_vector_complex_const_view; typedef const _gsl_vector_complex_const_view gsl_vector_complex_const_view; /* Allocation */ gsl_vector_complex *gsl_vector_complex_alloc (const size_t n); gsl_vector_complex *gsl_vector_complex_calloc (const size_t n); gsl_vector_complex * gsl_vector_complex_alloc_from_block (gsl_block_complex * b, const size_t offset, const size_t n, const size_t stride); gsl_vector_complex * gsl_vector_complex_alloc_from_vector (gsl_vector_complex * v, const size_t offset, const size_t n, const size_t stride); void gsl_vector_complex_free (gsl_vector_complex * v); /* Views */ _gsl_vector_complex_view gsl_vector_complex_view_array (double *base, size_t n); _gsl_vector_complex_view gsl_vector_complex_view_array_with_stride (double *base, size_t stride, size_t n); _gsl_vector_complex_const_view gsl_vector_complex_const_view_array (const double *base, size_t n); _gsl_vector_complex_const_view gsl_vector_complex_const_view_array_with_stride (const double *base, size_t stride, size_t n); _gsl_vector_complex_view gsl_vector_complex_subvector (gsl_vector_complex *base, size_t i, size_t n); _gsl_vector_complex_view gsl_vector_complex_subvector_with_stride (gsl_vector_complex *v, size_t i, size_t stride, size_t n); _gsl_vector_complex_const_view gsl_vector_complex_const_subvector (const gsl_vector_complex *base, size_t i, size_t n); _gsl_vector_complex_const_view gsl_vector_complex_const_subvector_with_stride (const gsl_vector_complex *v, size_t i, size_t stride, size_t n); _gsl_vector_view gsl_vector_complex_real (gsl_vector_complex *v); _gsl_vector_view gsl_vector_complex_imag (gsl_vector_complex *v); _gsl_vector_const_view gsl_vector_complex_const_real (const gsl_vector_complex *v); _gsl_vector_const_view gsl_vector_complex_const_imag (const gsl_vector_complex *v); /* Operations */ gsl_complex gsl_vector_complex_get (const gsl_vector_complex * v, const size_t i); void gsl_vector_complex_set (gsl_vector_complex * v, const size_t i, gsl_complex z); gsl_complex *gsl_vector_complex_ptr (gsl_vector_complex * v, const size_t i); const gsl_complex *gsl_vector_complex_const_ptr (const gsl_vector_complex * v, const size_t i); void gsl_vector_complex_set_zero (gsl_vector_complex * v); void gsl_vector_complex_set_all (gsl_vector_complex * v, gsl_complex z); int gsl_vector_complex_set_basis (gsl_vector_complex * v, size_t i); int gsl_vector_complex_fread (FILE * stream, gsl_vector_complex * v); int gsl_vector_complex_fwrite (FILE * stream, const gsl_vector_complex * v); int gsl_vector_complex_fscanf (FILE * stream, gsl_vector_complex * v); int gsl_vector_complex_fprintf (FILE * stream, const gsl_vector_complex * v, const char *format); int gsl_vector_complex_memcpy (gsl_vector_complex * dest, const gsl_vector_complex * src); int gsl_vector_complex_reverse (gsl_vector_complex * v); int gsl_vector_complex_swap (gsl_vector_complex * v, gsl_vector_complex * w); int gsl_vector_complex_swap_elements (gsl_vector_complex * v, const size_t i, const size_t j); int gsl_vector_complex_isnull (const gsl_vector_complex * v); int gsl_vector_complex_ispos (const gsl_vector_complex * v); int gsl_vector_complex_isneg (const gsl_vector_complex * v); int gsl_vector_complex_isnonneg (const gsl_vector_complex * v); #ifdef HAVE_INLINE extern inline gsl_complex gsl_vector_complex_get (const gsl_vector_complex * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { gsl_complex zero = {{0, 0}}; GSL_ERROR_VAL ("index out of range", GSL_EINVAL, zero); } #endif return *GSL_COMPLEX_AT (v, i); } extern inline void gsl_vector_complex_set (gsl_vector_complex * v, const size_t i, gsl_complex z) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_VOID ("index out of range", GSL_EINVAL); } #endif *GSL_COMPLEX_AT (v, i) = z; } extern inline gsl_complex * gsl_vector_complex_ptr (gsl_vector_complex * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return GSL_COMPLEX_AT (v, i); } extern inline const gsl_complex * gsl_vector_complex_const_ptr (const gsl_vector_complex * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return GSL_COMPLEX_AT (v, i); } #endif /* HAVE_INLINE */ __END_DECLS #endif /* __GSL_VECTOR_COMPLEX_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_vector_complex_float.h000066400000000000000000000200651261542461700225660ustar00rootroot00000000000000/* vector/gsl_vector_complex_float.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_VECTOR_COMPLEX_FLOAT_H__ #define __GSL_VECTOR_COMPLEX_FLOAT_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_complex.h" #include "gsl_check_range.h" #include "gsl_vector_float.h" #include "gsl_vector_complex.h" #include "gsl_block_complex_float.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size; size_t stride; float *data; gsl_block_complex_float *block; int owner; } gsl_vector_complex_float; typedef struct { gsl_vector_complex_float vector; } _gsl_vector_complex_float_view; typedef _gsl_vector_complex_float_view gsl_vector_complex_float_view; typedef struct { gsl_vector_complex_float vector; } _gsl_vector_complex_float_const_view; typedef const _gsl_vector_complex_float_const_view gsl_vector_complex_float_const_view; /* Allocation */ gsl_vector_complex_float *gsl_vector_complex_float_alloc (const size_t n); gsl_vector_complex_float *gsl_vector_complex_float_calloc (const size_t n); gsl_vector_complex_float * gsl_vector_complex_float_alloc_from_block (gsl_block_complex_float * b, const size_t offset, const size_t n, const size_t stride); gsl_vector_complex_float * gsl_vector_complex_float_alloc_from_vector (gsl_vector_complex_float * v, const size_t offset, const size_t n, const size_t stride); void gsl_vector_complex_float_free (gsl_vector_complex_float * v); /* Views */ _gsl_vector_complex_float_view gsl_vector_complex_float_view_array (float *base, size_t n); _gsl_vector_complex_float_view gsl_vector_complex_float_view_array_with_stride (float *base, size_t stride, size_t n); _gsl_vector_complex_float_const_view gsl_vector_complex_float_const_view_array (const float *base, size_t n); _gsl_vector_complex_float_const_view gsl_vector_complex_float_const_view_array_with_stride (const float *base, size_t stride, size_t n); _gsl_vector_complex_float_view gsl_vector_complex_float_subvector (gsl_vector_complex_float *base, size_t i, size_t n); _gsl_vector_complex_float_view gsl_vector_complex_float_subvector_with_stride (gsl_vector_complex_float *v, size_t i, size_t stride, size_t n); _gsl_vector_complex_float_const_view gsl_vector_complex_float_const_subvector (const gsl_vector_complex_float *base, size_t i, size_t n); _gsl_vector_complex_float_const_view gsl_vector_complex_float_const_subvector_with_stride (const gsl_vector_complex_float *v, size_t i, size_t stride, size_t n); _gsl_vector_float_view gsl_vector_complex_float_real (gsl_vector_complex_float *v); _gsl_vector_float_view gsl_vector_complex_float_imag (gsl_vector_complex_float *v); _gsl_vector_float_const_view gsl_vector_complex_float_const_real (const gsl_vector_complex_float *v); _gsl_vector_float_const_view gsl_vector_complex_float_const_imag (const gsl_vector_complex_float *v); /* Operations */ gsl_complex_float gsl_vector_complex_float_get (const gsl_vector_complex_float * v, const size_t i); void gsl_vector_complex_float_set (gsl_vector_complex_float * v, const size_t i, gsl_complex_float z); gsl_complex_float *gsl_vector_complex_float_ptr (gsl_vector_complex_float * v, const size_t i); const gsl_complex_float *gsl_vector_complex_float_const_ptr (const gsl_vector_complex_float * v, const size_t i); void gsl_vector_complex_float_set_zero (gsl_vector_complex_float * v); void gsl_vector_complex_float_set_all (gsl_vector_complex_float * v, gsl_complex_float z); int gsl_vector_complex_float_set_basis (gsl_vector_complex_float * v, size_t i); int gsl_vector_complex_float_fread (FILE * stream, gsl_vector_complex_float * v); int gsl_vector_complex_float_fwrite (FILE * stream, const gsl_vector_complex_float * v); int gsl_vector_complex_float_fscanf (FILE * stream, gsl_vector_complex_float * v); int gsl_vector_complex_float_fprintf (FILE * stream, const gsl_vector_complex_float * v, const char *format); int gsl_vector_complex_float_memcpy (gsl_vector_complex_float * dest, const gsl_vector_complex_float * src); int gsl_vector_complex_float_reverse (gsl_vector_complex_float * v); int gsl_vector_complex_float_swap (gsl_vector_complex_float * v, gsl_vector_complex_float * w); int gsl_vector_complex_float_swap_elements (gsl_vector_complex_float * v, const size_t i, const size_t j); int gsl_vector_complex_float_isnull (const gsl_vector_complex_float * v); int gsl_vector_complex_float_ispos (const gsl_vector_complex_float * v); int gsl_vector_complex_float_isneg (const gsl_vector_complex_float * v); int gsl_vector_complex_float_isnonneg (const gsl_vector_complex_float * v); #ifdef HAVE_INLINE extern inline gsl_complex_float gsl_vector_complex_float_get (const gsl_vector_complex_float * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { gsl_complex_float zero = {{0, 0}}; GSL_ERROR_VAL ("index out of range", GSL_EINVAL, zero); } #endif return *GSL_COMPLEX_FLOAT_AT (v, i); } extern inline void gsl_vector_complex_float_set (gsl_vector_complex_float * v, const size_t i, gsl_complex_float z) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_VOID ("index out of range", GSL_EINVAL); } #endif *GSL_COMPLEX_FLOAT_AT (v, i) = z; } extern inline gsl_complex_float * gsl_vector_complex_float_ptr (gsl_vector_complex_float * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return GSL_COMPLEX_FLOAT_AT (v, i); } extern inline const gsl_complex_float * gsl_vector_complex_float_const_ptr (const gsl_vector_complex_float * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return GSL_COMPLEX_FLOAT_AT (v, i); } #endif /* HAVE_INLINE */ __END_DECLS #endif /* __GSL_VECTOR_COMPLEX_FLOAT_H__ */ praat-6.0.04/external/gsl/gsl_vector_complex_long_double.h000066400000000000000000000214571261542461700237600ustar00rootroot00000000000000/* vector/gsl_vector_complex_long_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_VECTOR_COMPLEX_LONG_DOUBLE_H__ #define __GSL_VECTOR_COMPLEX_LONG_DOUBLE_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_complex.h" #include "gsl_check_range.h" #include "gsl_vector_long_double.h" #include "gsl_vector_complex.h" #include "gsl_block_complex_long_double.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size; size_t stride; long double *data; gsl_block_complex_long_double *block; int owner; } gsl_vector_complex_long_double; typedef struct { gsl_vector_complex_long_double vector; } _gsl_vector_complex_long_double_view; typedef _gsl_vector_complex_long_double_view gsl_vector_complex_long_double_view; typedef struct { gsl_vector_complex_long_double vector; } _gsl_vector_complex_long_double_const_view; typedef const _gsl_vector_complex_long_double_const_view gsl_vector_complex_long_double_const_view; /* Allocation */ gsl_vector_complex_long_double *gsl_vector_complex_long_double_alloc (const size_t n); gsl_vector_complex_long_double *gsl_vector_complex_long_double_calloc (const size_t n); gsl_vector_complex_long_double * gsl_vector_complex_long_double_alloc_from_block (gsl_block_complex_long_double * b, const size_t offset, const size_t n, const size_t stride); gsl_vector_complex_long_double * gsl_vector_complex_long_double_alloc_from_vector (gsl_vector_complex_long_double * v, const size_t offset, const size_t n, const size_t stride); void gsl_vector_complex_long_double_free (gsl_vector_complex_long_double * v); /* Views */ _gsl_vector_complex_long_double_view gsl_vector_complex_long_double_view_array (long double *base, size_t n); _gsl_vector_complex_long_double_view gsl_vector_complex_long_double_view_array_with_stride (long double *base, size_t stride, size_t n); _gsl_vector_complex_long_double_const_view gsl_vector_complex_long_double_const_view_array (const long double *base, size_t n); _gsl_vector_complex_long_double_const_view gsl_vector_complex_long_double_const_view_array_with_stride (const long double *base, size_t stride, size_t n); _gsl_vector_complex_long_double_view gsl_vector_complex_long_double_subvector (gsl_vector_complex_long_double *base, size_t i, size_t n); _gsl_vector_complex_long_double_view gsl_vector_complex_long_double_subvector_with_stride (gsl_vector_complex_long_double *v, size_t i, size_t stride, size_t n); _gsl_vector_complex_long_double_const_view gsl_vector_complex_long_double_const_subvector (const gsl_vector_complex_long_double *base, size_t i, size_t n); _gsl_vector_complex_long_double_const_view gsl_vector_complex_long_double_const_subvector_with_stride (const gsl_vector_complex_long_double *v, size_t i, size_t stride, size_t n); _gsl_vector_long_double_view gsl_vector_complex_long_double_real (gsl_vector_complex_long_double *v); _gsl_vector_long_double_view gsl_vector_complex_long_double_imag (gsl_vector_complex_long_double *v); _gsl_vector_long_double_const_view gsl_vector_complex_long_double_const_real (const gsl_vector_complex_long_double *v); _gsl_vector_long_double_const_view gsl_vector_complex_long_double_const_imag (const gsl_vector_complex_long_double *v); /* Operations */ gsl_complex_long_double gsl_vector_complex_long_double_get (const gsl_vector_complex_long_double * v, const size_t i); void gsl_vector_complex_long_double_set (gsl_vector_complex_long_double * v, const size_t i, gsl_complex_long_double z); gsl_complex_long_double *gsl_vector_complex_long_double_ptr (gsl_vector_complex_long_double * v, const size_t i); const gsl_complex_long_double *gsl_vector_complex_long_double_const_ptr (const gsl_vector_complex_long_double * v, const size_t i); void gsl_vector_complex_long_double_set_zero (gsl_vector_complex_long_double * v); void gsl_vector_complex_long_double_set_all (gsl_vector_complex_long_double * v, gsl_complex_long_double z); int gsl_vector_complex_long_double_set_basis (gsl_vector_complex_long_double * v, size_t i); int gsl_vector_complex_long_double_fread (FILE * stream, gsl_vector_complex_long_double * v); int gsl_vector_complex_long_double_fwrite (FILE * stream, const gsl_vector_complex_long_double * v); int gsl_vector_complex_long_double_fscanf (FILE * stream, gsl_vector_complex_long_double * v); int gsl_vector_complex_long_double_fprintf (FILE * stream, const gsl_vector_complex_long_double * v, const char *format); int gsl_vector_complex_long_double_memcpy (gsl_vector_complex_long_double * dest, const gsl_vector_complex_long_double * src); int gsl_vector_complex_long_double_reverse (gsl_vector_complex_long_double * v); int gsl_vector_complex_long_double_swap (gsl_vector_complex_long_double * v, gsl_vector_complex_long_double * w); int gsl_vector_complex_long_double_swap_elements (gsl_vector_complex_long_double * v, const size_t i, const size_t j); int gsl_vector_complex_long_double_isnull (const gsl_vector_complex_long_double * v); int gsl_vector_complex_long_double_ispos (const gsl_vector_complex_long_double * v); int gsl_vector_complex_long_double_isneg (const gsl_vector_complex_long_double * v); int gsl_vector_complex_long_double_isnonneg (const gsl_vector_complex_long_double * v); #ifdef HAVE_INLINE extern inline gsl_complex_long_double gsl_vector_complex_long_double_get (const gsl_vector_complex_long_double * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { gsl_complex_long_double zero = {{0, 0}}; GSL_ERROR_VAL ("index out of range", GSL_EINVAL, zero); } #endif return *GSL_COMPLEX_LONG_DOUBLE_AT (v, i); } extern inline void gsl_vector_complex_long_double_set (gsl_vector_complex_long_double * v, const size_t i, gsl_complex_long_double z) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_VOID ("index out of range", GSL_EINVAL); } #endif *GSL_COMPLEX_LONG_DOUBLE_AT (v, i) = z; } extern inline gsl_complex_long_double * gsl_vector_complex_long_double_ptr (gsl_vector_complex_long_double * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return GSL_COMPLEX_LONG_DOUBLE_AT (v, i); } extern inline const gsl_complex_long_double * gsl_vector_complex_long_double_const_ptr (const gsl_vector_complex_long_double * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return GSL_COMPLEX_LONG_DOUBLE_AT (v, i); } #endif /* HAVE_INLINE */ __END_DECLS #endif /* __GSL_VECTOR_COMPLEX_LONG_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_vector_double.h000066400000000000000000000146271261542461700212130ustar00rootroot00000000000000/* vector/gsl_vector_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_VECTOR_DOUBLE_H__ #define __GSL_VECTOR_DOUBLE_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_check_range.h" #include "gsl_block_double.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size; size_t stride; double *data; gsl_block *block; int owner; } gsl_vector; typedef struct { gsl_vector vector; } _gsl_vector_view; typedef _gsl_vector_view gsl_vector_view; typedef struct { gsl_vector vector; } _gsl_vector_const_view; typedef const _gsl_vector_const_view gsl_vector_const_view; /* Allocation */ gsl_vector *gsl_vector_alloc (const size_t n); gsl_vector *gsl_vector_calloc (const size_t n); gsl_vector *gsl_vector_alloc_from_block (gsl_block * b, const size_t offset, const size_t n, const size_t stride); gsl_vector *gsl_vector_alloc_from_vector (gsl_vector * v, const size_t offset, const size_t n, const size_t stride); void gsl_vector_free (gsl_vector * v); /* Views */ _gsl_vector_view gsl_vector_view_array (double *v, size_t n); _gsl_vector_view gsl_vector_view_array_with_stride (double *base, size_t stride, size_t n); _gsl_vector_const_view gsl_vector_const_view_array (const double *v, size_t n); _gsl_vector_const_view gsl_vector_const_view_array_with_stride (const double *base, size_t stride, size_t n); _gsl_vector_view gsl_vector_subvector (gsl_vector *v, size_t i, size_t n); _gsl_vector_view gsl_vector_subvector_with_stride (gsl_vector *v, size_t i, size_t stride, size_t n); _gsl_vector_const_view gsl_vector_const_subvector (const gsl_vector *v, size_t i, size_t n); _gsl_vector_const_view gsl_vector_const_subvector_with_stride (const gsl_vector *v, size_t i, size_t stride, size_t n); /* Operations */ double gsl_vector_get (const gsl_vector * v, const size_t i); void gsl_vector_set (gsl_vector * v, const size_t i, double x); double *gsl_vector_ptr (gsl_vector * v, const size_t i); const double *gsl_vector_const_ptr (const gsl_vector * v, const size_t i); void gsl_vector_set_zero (gsl_vector * v); void gsl_vector_set_all (gsl_vector * v, double x); int gsl_vector_set_basis (gsl_vector * v, size_t i); int gsl_vector_fread (FILE * stream, gsl_vector * v); int gsl_vector_fwrite (FILE * stream, const gsl_vector * v); int gsl_vector_fscanf (FILE * stream, gsl_vector * v); int gsl_vector_fprintf (FILE * stream, const gsl_vector * v, const char *format); int gsl_vector_memcpy (gsl_vector * dest, const gsl_vector * src); int gsl_vector_reverse (gsl_vector * v); int gsl_vector_swap (gsl_vector * v, gsl_vector * w); int gsl_vector_swap_elements (gsl_vector * v, const size_t i, const size_t j); double gsl_vector_max (const gsl_vector * v); double gsl_vector_min (const gsl_vector * v); void gsl_vector_minmax (const gsl_vector * v, double * min_out, double * max_out); size_t gsl_vector_max_index (const gsl_vector * v); size_t gsl_vector_min_index (const gsl_vector * v); void gsl_vector_minmax_index (const gsl_vector * v, size_t * imin, size_t * imax); int gsl_vector_add (gsl_vector * a, const gsl_vector * b); int gsl_vector_sub (gsl_vector * a, const gsl_vector * b); int gsl_vector_mul (gsl_vector * a, const gsl_vector * b); int gsl_vector_div (gsl_vector * a, const gsl_vector * b); int gsl_vector_scale (gsl_vector * a, const double x); int gsl_vector_add_constant (gsl_vector * a, const double x); int gsl_vector_isnull (const gsl_vector * v); int gsl_vector_ispos (const gsl_vector * v); int gsl_vector_isneg (const gsl_vector * v); int gsl_vector_isnonneg (const gsl_vector * v); #ifdef HAVE_INLINE extern inline double gsl_vector_get (const gsl_vector * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); } #endif return v->data[i * v->stride]; } extern inline void gsl_vector_set (gsl_vector * v, const size_t i, double x) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_VOID ("index out of range", GSL_EINVAL); } #endif v->data[i * v->stride] = x; } extern inline double * gsl_vector_ptr (gsl_vector * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return (double *) (v->data + i * v->stride); } extern inline const double * gsl_vector_const_ptr (const gsl_vector * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return (const double *) (v->data + i * v->stride); } #endif /* HAVE_INLINE */ __END_DECLS #endif /* __GSL_VECTOR_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_vector_float.h000066400000000000000000000161021261542461700210340ustar00rootroot00000000000000/* vector/gsl_vector_float.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_VECTOR_FLOAT_H__ #define __GSL_VECTOR_FLOAT_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_check_range.h" #include "gsl_block_float.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size; size_t stride; float *data; gsl_block_float *block; int owner; } gsl_vector_float; typedef struct { gsl_vector_float vector; } _gsl_vector_float_view; typedef _gsl_vector_float_view gsl_vector_float_view; typedef struct { gsl_vector_float vector; } _gsl_vector_float_const_view; typedef const _gsl_vector_float_const_view gsl_vector_float_const_view; /* Allocation */ gsl_vector_float *gsl_vector_float_alloc (const size_t n); gsl_vector_float *gsl_vector_float_calloc (const size_t n); gsl_vector_float *gsl_vector_float_alloc_from_block (gsl_block_float * b, const size_t offset, const size_t n, const size_t stride); gsl_vector_float *gsl_vector_float_alloc_from_vector (gsl_vector_float * v, const size_t offset, const size_t n, const size_t stride); void gsl_vector_float_free (gsl_vector_float * v); /* Views */ _gsl_vector_float_view gsl_vector_float_view_array (float *v, size_t n); _gsl_vector_float_view gsl_vector_float_view_array_with_stride (float *base, size_t stride, size_t n); _gsl_vector_float_const_view gsl_vector_float_const_view_array (const float *v, size_t n); _gsl_vector_float_const_view gsl_vector_float_const_view_array_with_stride (const float *base, size_t stride, size_t n); _gsl_vector_float_view gsl_vector_float_subvector (gsl_vector_float *v, size_t i, size_t n); _gsl_vector_float_view gsl_vector_float_subvector_with_stride (gsl_vector_float *v, size_t i, size_t stride, size_t n); _gsl_vector_float_const_view gsl_vector_float_const_subvector (const gsl_vector_float *v, size_t i, size_t n); _gsl_vector_float_const_view gsl_vector_float_const_subvector_with_stride (const gsl_vector_float *v, size_t i, size_t stride, size_t n); /* Operations */ float gsl_vector_float_get (const gsl_vector_float * v, const size_t i); void gsl_vector_float_set (gsl_vector_float * v, const size_t i, float x); float *gsl_vector_float_ptr (gsl_vector_float * v, const size_t i); const float *gsl_vector_float_const_ptr (const gsl_vector_float * v, const size_t i); void gsl_vector_float_set_zero (gsl_vector_float * v); void gsl_vector_float_set_all (gsl_vector_float * v, float x); int gsl_vector_float_set_basis (gsl_vector_float * v, size_t i); int gsl_vector_float_fread (FILE * stream, gsl_vector_float * v); int gsl_vector_float_fwrite (FILE * stream, const gsl_vector_float * v); int gsl_vector_float_fscanf (FILE * stream, gsl_vector_float * v); int gsl_vector_float_fprintf (FILE * stream, const gsl_vector_float * v, const char *format); int gsl_vector_float_memcpy (gsl_vector_float * dest, const gsl_vector_float * src); int gsl_vector_float_reverse (gsl_vector_float * v); int gsl_vector_float_swap (gsl_vector_float * v, gsl_vector_float * w); int gsl_vector_float_swap_elements (gsl_vector_float * v, const size_t i, const size_t j); float gsl_vector_float_max (const gsl_vector_float * v); float gsl_vector_float_min (const gsl_vector_float * v); void gsl_vector_float_minmax (const gsl_vector_float * v, float * min_out, float * max_out); size_t gsl_vector_float_max_index (const gsl_vector_float * v); size_t gsl_vector_float_min_index (const gsl_vector_float * v); void gsl_vector_float_minmax_index (const gsl_vector_float * v, size_t * imin, size_t * imax); int gsl_vector_float_add (gsl_vector_float * a, const gsl_vector_float * b); int gsl_vector_float_sub (gsl_vector_float * a, const gsl_vector_float * b); int gsl_vector_float_mul (gsl_vector_float * a, const gsl_vector_float * b); int gsl_vector_float_div (gsl_vector_float * a, const gsl_vector_float * b); int gsl_vector_float_scale (gsl_vector_float * a, const double x); int gsl_vector_float_add_constant (gsl_vector_float * a, const double x); int gsl_vector_float_isnull (const gsl_vector_float * v); int gsl_vector_float_ispos (const gsl_vector_float * v); int gsl_vector_float_isneg (const gsl_vector_float * v); int gsl_vector_float_isnonneg (const gsl_vector_float * v); #ifdef HAVE_INLINE extern inline float gsl_vector_float_get (const gsl_vector_float * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); } #endif return v->data[i * v->stride]; } extern inline void gsl_vector_float_set (gsl_vector_float * v, const size_t i, float x) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_VOID ("index out of range", GSL_EINVAL); } #endif v->data[i * v->stride] = x; } extern inline float * gsl_vector_float_ptr (gsl_vector_float * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return (float *) (v->data + i * v->stride); } extern inline const float * gsl_vector_float_const_ptr (const gsl_vector_float * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return (const float *) (v->data + i * v->stride); } #endif /* HAVE_INLINE */ __END_DECLS #endif /* __GSL_VECTOR_FLOAT_H__ */ praat-6.0.04/external/gsl/gsl_vector_int.h000066400000000000000000000154441261542461700205310ustar00rootroot00000000000000/* vector/gsl_vector_int.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_VECTOR_INT_H__ #define __GSL_VECTOR_INT_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_check_range.h" #include "gsl_block_int.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size; size_t stride; int *data; gsl_block_int *block; int owner; } gsl_vector_int; typedef struct { gsl_vector_int vector; } _gsl_vector_int_view; typedef _gsl_vector_int_view gsl_vector_int_view; typedef struct { gsl_vector_int vector; } _gsl_vector_int_const_view; typedef const _gsl_vector_int_const_view gsl_vector_int_const_view; /* Allocation */ gsl_vector_int *gsl_vector_int_alloc (const size_t n); gsl_vector_int *gsl_vector_int_calloc (const size_t n); gsl_vector_int *gsl_vector_int_alloc_from_block (gsl_block_int * b, const size_t offset, const size_t n, const size_t stride); gsl_vector_int *gsl_vector_int_alloc_from_vector (gsl_vector_int * v, const size_t offset, const size_t n, const size_t stride); void gsl_vector_int_free (gsl_vector_int * v); /* Views */ _gsl_vector_int_view gsl_vector_int_view_array (int *v, size_t n); _gsl_vector_int_view gsl_vector_int_view_array_with_stride (int *base, size_t stride, size_t n); _gsl_vector_int_const_view gsl_vector_int_const_view_array (const int *v, size_t n); _gsl_vector_int_const_view gsl_vector_int_const_view_array_with_stride (const int *base, size_t stride, size_t n); _gsl_vector_int_view gsl_vector_int_subvector (gsl_vector_int *v, size_t i, size_t n); _gsl_vector_int_view gsl_vector_int_subvector_with_stride (gsl_vector_int *v, size_t i, size_t stride, size_t n); _gsl_vector_int_const_view gsl_vector_int_const_subvector (const gsl_vector_int *v, size_t i, size_t n); _gsl_vector_int_const_view gsl_vector_int_const_subvector_with_stride (const gsl_vector_int *v, size_t i, size_t stride, size_t n); /* Operations */ int gsl_vector_int_get (const gsl_vector_int * v, const size_t i); void gsl_vector_int_set (gsl_vector_int * v, const size_t i, int x); int *gsl_vector_int_ptr (gsl_vector_int * v, const size_t i); const int *gsl_vector_int_const_ptr (const gsl_vector_int * v, const size_t i); void gsl_vector_int_set_zero (gsl_vector_int * v); void gsl_vector_int_set_all (gsl_vector_int * v, int x); int gsl_vector_int_set_basis (gsl_vector_int * v, size_t i); int gsl_vector_int_fread (FILE * stream, gsl_vector_int * v); int gsl_vector_int_fwrite (FILE * stream, const gsl_vector_int * v); int gsl_vector_int_fscanf (FILE * stream, gsl_vector_int * v); int gsl_vector_int_fprintf (FILE * stream, const gsl_vector_int * v, const char *format); int gsl_vector_int_memcpy (gsl_vector_int * dest, const gsl_vector_int * src); int gsl_vector_int_reverse (gsl_vector_int * v); int gsl_vector_int_swap (gsl_vector_int * v, gsl_vector_int * w); int gsl_vector_int_swap_elements (gsl_vector_int * v, const size_t i, const size_t j); int gsl_vector_int_max (const gsl_vector_int * v); int gsl_vector_int_min (const gsl_vector_int * v); void gsl_vector_int_minmax (const gsl_vector_int * v, int * min_out, int * max_out); size_t gsl_vector_int_max_index (const gsl_vector_int * v); size_t gsl_vector_int_min_index (const gsl_vector_int * v); void gsl_vector_int_minmax_index (const gsl_vector_int * v, size_t * imin, size_t * imax); int gsl_vector_int_add (gsl_vector_int * a, const gsl_vector_int * b); int gsl_vector_int_sub (gsl_vector_int * a, const gsl_vector_int * b); int gsl_vector_int_mul (gsl_vector_int * a, const gsl_vector_int * b); int gsl_vector_int_div (gsl_vector_int * a, const gsl_vector_int * b); int gsl_vector_int_scale (gsl_vector_int * a, const double x); int gsl_vector_int_add_constant (gsl_vector_int * a, const double x); int gsl_vector_int_isnull (const gsl_vector_int * v); int gsl_vector_int_ispos (const gsl_vector_int * v); int gsl_vector_int_isneg (const gsl_vector_int * v); int gsl_vector_int_isnonneg (const gsl_vector_int * v); #ifdef HAVE_INLINE extern inline int gsl_vector_int_get (const gsl_vector_int * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); } #endif return v->data[i * v->stride]; } extern inline void gsl_vector_int_set (gsl_vector_int * v, const size_t i, int x) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_VOID ("index out of range", GSL_EINVAL); } #endif v->data[i * v->stride] = x; } extern inline int * gsl_vector_int_ptr (gsl_vector_int * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return (int *) (v->data + i * v->stride); } extern inline const int * gsl_vector_int_const_ptr (const gsl_vector_int * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return (const int *) (v->data + i * v->stride); } #endif /* HAVE_INLINE */ __END_DECLS #endif /* __GSL_VECTOR_INT_H__ */ praat-6.0.04/external/gsl/gsl_vector_long.h000066400000000000000000000156631261542461700207010ustar00rootroot00000000000000/* vector/gsl_vector_long.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_VECTOR_LONG_H__ #define __GSL_VECTOR_LONG_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_check_range.h" #include "gsl_block_long.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size; size_t stride; long *data; gsl_block_long *block; int owner; } gsl_vector_long; typedef struct { gsl_vector_long vector; } _gsl_vector_long_view; typedef _gsl_vector_long_view gsl_vector_long_view; typedef struct { gsl_vector_long vector; } _gsl_vector_long_const_view; typedef const _gsl_vector_long_const_view gsl_vector_long_const_view; /* Allocation */ gsl_vector_long *gsl_vector_long_alloc (const size_t n); gsl_vector_long *gsl_vector_long_calloc (const size_t n); gsl_vector_long *gsl_vector_long_alloc_from_block (gsl_block_long * b, const size_t offset, const size_t n, const size_t stride); gsl_vector_long *gsl_vector_long_alloc_from_vector (gsl_vector_long * v, const size_t offset, const size_t n, const size_t stride); void gsl_vector_long_free (gsl_vector_long * v); /* Views */ _gsl_vector_long_view gsl_vector_long_view_array (long *v, size_t n); _gsl_vector_long_view gsl_vector_long_view_array_with_stride (long *base, size_t stride, size_t n); _gsl_vector_long_const_view gsl_vector_long_const_view_array (const long *v, size_t n); _gsl_vector_long_const_view gsl_vector_long_const_view_array_with_stride (const long *base, size_t stride, size_t n); _gsl_vector_long_view gsl_vector_long_subvector (gsl_vector_long *v, size_t i, size_t n); _gsl_vector_long_view gsl_vector_long_subvector_with_stride (gsl_vector_long *v, size_t i, size_t stride, size_t n); _gsl_vector_long_const_view gsl_vector_long_const_subvector (const gsl_vector_long *v, size_t i, size_t n); _gsl_vector_long_const_view gsl_vector_long_const_subvector_with_stride (const gsl_vector_long *v, size_t i, size_t stride, size_t n); /* Operations */ long gsl_vector_long_get (const gsl_vector_long * v, const size_t i); void gsl_vector_long_set (gsl_vector_long * v, const size_t i, long x); long *gsl_vector_long_ptr (gsl_vector_long * v, const size_t i); const long *gsl_vector_long_const_ptr (const gsl_vector_long * v, const size_t i); void gsl_vector_long_set_zero (gsl_vector_long * v); void gsl_vector_long_set_all (gsl_vector_long * v, long x); int gsl_vector_long_set_basis (gsl_vector_long * v, size_t i); int gsl_vector_long_fread (FILE * stream, gsl_vector_long * v); int gsl_vector_long_fwrite (FILE * stream, const gsl_vector_long * v); int gsl_vector_long_fscanf (FILE * stream, gsl_vector_long * v); int gsl_vector_long_fprintf (FILE * stream, const gsl_vector_long * v, const char *format); int gsl_vector_long_memcpy (gsl_vector_long * dest, const gsl_vector_long * src); int gsl_vector_long_reverse (gsl_vector_long * v); int gsl_vector_long_swap (gsl_vector_long * v, gsl_vector_long * w); int gsl_vector_long_swap_elements (gsl_vector_long * v, const size_t i, const size_t j); long gsl_vector_long_max (const gsl_vector_long * v); long gsl_vector_long_min (const gsl_vector_long * v); void gsl_vector_long_minmax (const gsl_vector_long * v, long * min_out, long * max_out); size_t gsl_vector_long_max_index (const gsl_vector_long * v); size_t gsl_vector_long_min_index (const gsl_vector_long * v); void gsl_vector_long_minmax_index (const gsl_vector_long * v, size_t * imin, size_t * imax); int gsl_vector_long_add (gsl_vector_long * a, const gsl_vector_long * b); int gsl_vector_long_sub (gsl_vector_long * a, const gsl_vector_long * b); int gsl_vector_long_mul (gsl_vector_long * a, const gsl_vector_long * b); int gsl_vector_long_div (gsl_vector_long * a, const gsl_vector_long * b); int gsl_vector_long_scale (gsl_vector_long * a, const double x); int gsl_vector_long_add_constant (gsl_vector_long * a, const double x); int gsl_vector_long_isnull (const gsl_vector_long * v); int gsl_vector_long_ispos (const gsl_vector_long * v); int gsl_vector_long_isneg (const gsl_vector_long * v); int gsl_vector_long_isnonneg (const gsl_vector_long * v); #ifdef HAVE_INLINE extern inline long gsl_vector_long_get (const gsl_vector_long * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); } #endif return v->data[i * v->stride]; } extern inline void gsl_vector_long_set (gsl_vector_long * v, const size_t i, long x) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_VOID ("index out of range", GSL_EINVAL); } #endif v->data[i * v->stride] = x; } extern inline long * gsl_vector_long_ptr (gsl_vector_long * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return (long *) (v->data + i * v->stride); } extern inline const long * gsl_vector_long_const_ptr (const gsl_vector_long * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return (const long *) (v->data + i * v->stride); } #endif /* HAVE_INLINE */ __END_DECLS #endif /* __GSL_VECTOR_LONG_H__ */ praat-6.0.04/external/gsl/gsl_vector_long_double.h000066400000000000000000000176341261542461700222330ustar00rootroot00000000000000/* vector/gsl_vector_long_double.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_VECTOR_LONG_DOUBLE_H__ #define __GSL_VECTOR_LONG_DOUBLE_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_check_range.h" #include "gsl_block_long_double.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size; size_t stride; long double *data; gsl_block_long_double *block; int owner; } gsl_vector_long_double; typedef struct { gsl_vector_long_double vector; } _gsl_vector_long_double_view; typedef _gsl_vector_long_double_view gsl_vector_long_double_view; typedef struct { gsl_vector_long_double vector; } _gsl_vector_long_double_const_view; typedef const _gsl_vector_long_double_const_view gsl_vector_long_double_const_view; /* Allocation */ gsl_vector_long_double *gsl_vector_long_double_alloc (const size_t n); gsl_vector_long_double *gsl_vector_long_double_calloc (const size_t n); gsl_vector_long_double *gsl_vector_long_double_alloc_from_block (gsl_block_long_double * b, const size_t offset, const size_t n, const size_t stride); gsl_vector_long_double *gsl_vector_long_double_alloc_from_vector (gsl_vector_long_double * v, const size_t offset, const size_t n, const size_t stride); void gsl_vector_long_double_free (gsl_vector_long_double * v); /* Views */ _gsl_vector_long_double_view gsl_vector_long_double_view_array (long double *v, size_t n); _gsl_vector_long_double_view gsl_vector_long_double_view_array_with_stride (long double *base, size_t stride, size_t n); _gsl_vector_long_double_const_view gsl_vector_long_double_const_view_array (const long double *v, size_t n); _gsl_vector_long_double_const_view gsl_vector_long_double_const_view_array_with_stride (const long double *base, size_t stride, size_t n); _gsl_vector_long_double_view gsl_vector_long_double_subvector (gsl_vector_long_double *v, size_t i, size_t n); _gsl_vector_long_double_view gsl_vector_long_double_subvector_with_stride (gsl_vector_long_double *v, size_t i, size_t stride, size_t n); _gsl_vector_long_double_const_view gsl_vector_long_double_const_subvector (const gsl_vector_long_double *v, size_t i, size_t n); _gsl_vector_long_double_const_view gsl_vector_long_double_const_subvector_with_stride (const gsl_vector_long_double *v, size_t i, size_t stride, size_t n); /* Operations */ long double gsl_vector_long_double_get (const gsl_vector_long_double * v, const size_t i); void gsl_vector_long_double_set (gsl_vector_long_double * v, const size_t i, long double x); long double *gsl_vector_long_double_ptr (gsl_vector_long_double * v, const size_t i); const long double *gsl_vector_long_double_const_ptr (const gsl_vector_long_double * v, const size_t i); void gsl_vector_long_double_set_zero (gsl_vector_long_double * v); void gsl_vector_long_double_set_all (gsl_vector_long_double * v, long double x); int gsl_vector_long_double_set_basis (gsl_vector_long_double * v, size_t i); int gsl_vector_long_double_fread (FILE * stream, gsl_vector_long_double * v); int gsl_vector_long_double_fwrite (FILE * stream, const gsl_vector_long_double * v); int gsl_vector_long_double_fscanf (FILE * stream, gsl_vector_long_double * v); int gsl_vector_long_double_fprintf (FILE * stream, const gsl_vector_long_double * v, const char *format); int gsl_vector_long_double_memcpy (gsl_vector_long_double * dest, const gsl_vector_long_double * src); int gsl_vector_long_double_reverse (gsl_vector_long_double * v); int gsl_vector_long_double_swap (gsl_vector_long_double * v, gsl_vector_long_double * w); int gsl_vector_long_double_swap_elements (gsl_vector_long_double * v, const size_t i, const size_t j); long double gsl_vector_long_double_max (const gsl_vector_long_double * v); long double gsl_vector_long_double_min (const gsl_vector_long_double * v); void gsl_vector_long_double_minmax (const gsl_vector_long_double * v, long double * min_out, long double * max_out); size_t gsl_vector_long_double_max_index (const gsl_vector_long_double * v); size_t gsl_vector_long_double_min_index (const gsl_vector_long_double * v); void gsl_vector_long_double_minmax_index (const gsl_vector_long_double * v, size_t * imin, size_t * imax); int gsl_vector_long_double_add (gsl_vector_long_double * a, const gsl_vector_long_double * b); int gsl_vector_long_double_sub (gsl_vector_long_double * a, const gsl_vector_long_double * b); int gsl_vector_long_double_mul (gsl_vector_long_double * a, const gsl_vector_long_double * b); int gsl_vector_long_double_div (gsl_vector_long_double * a, const gsl_vector_long_double * b); int gsl_vector_long_double_scale (gsl_vector_long_double * a, const double x); int gsl_vector_long_double_add_constant (gsl_vector_long_double * a, const double x); int gsl_vector_long_double_isnull (const gsl_vector_long_double * v); int gsl_vector_long_double_ispos (const gsl_vector_long_double * v); int gsl_vector_long_double_isneg (const gsl_vector_long_double * v); int gsl_vector_long_double_isnonneg (const gsl_vector_long_double * v); #ifdef HAVE_INLINE extern inline long double gsl_vector_long_double_get (const gsl_vector_long_double * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); } #endif return v->data[i * v->stride]; } extern inline void gsl_vector_long_double_set (gsl_vector_long_double * v, const size_t i, long double x) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_VOID ("index out of range", GSL_EINVAL); } #endif v->data[i * v->stride] = x; } extern inline long double * gsl_vector_long_double_ptr (gsl_vector_long_double * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return (long double *) (v->data + i * v->stride); } extern inline const long double * gsl_vector_long_double_const_ptr (const gsl_vector_long_double * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return (const long double *) (v->data + i * v->stride); } #endif /* HAVE_INLINE */ __END_DECLS #endif /* __GSL_VECTOR_LONG_DOUBLE_H__ */ praat-6.0.04/external/gsl/gsl_vector_short.h000066400000000000000000000161021261542461700210660ustar00rootroot00000000000000/* vector/gsl_vector_short.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_VECTOR_SHORT_H__ #define __GSL_VECTOR_SHORT_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_check_range.h" #include "gsl_block_short.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size; size_t stride; short *data; gsl_block_short *block; int owner; } gsl_vector_short; typedef struct { gsl_vector_short vector; } _gsl_vector_short_view; typedef _gsl_vector_short_view gsl_vector_short_view; typedef struct { gsl_vector_short vector; } _gsl_vector_short_const_view; typedef const _gsl_vector_short_const_view gsl_vector_short_const_view; /* Allocation */ gsl_vector_short *gsl_vector_short_alloc (const size_t n); gsl_vector_short *gsl_vector_short_calloc (const size_t n); gsl_vector_short *gsl_vector_short_alloc_from_block (gsl_block_short * b, const size_t offset, const size_t n, const size_t stride); gsl_vector_short *gsl_vector_short_alloc_from_vector (gsl_vector_short * v, const size_t offset, const size_t n, const size_t stride); void gsl_vector_short_free (gsl_vector_short * v); /* Views */ _gsl_vector_short_view gsl_vector_short_view_array (short *v, size_t n); _gsl_vector_short_view gsl_vector_short_view_array_with_stride (short *base, size_t stride, size_t n); _gsl_vector_short_const_view gsl_vector_short_const_view_array (const short *v, size_t n); _gsl_vector_short_const_view gsl_vector_short_const_view_array_with_stride (const short *base, size_t stride, size_t n); _gsl_vector_short_view gsl_vector_short_subvector (gsl_vector_short *v, size_t i, size_t n); _gsl_vector_short_view gsl_vector_short_subvector_with_stride (gsl_vector_short *v, size_t i, size_t stride, size_t n); _gsl_vector_short_const_view gsl_vector_short_const_subvector (const gsl_vector_short *v, size_t i, size_t n); _gsl_vector_short_const_view gsl_vector_short_const_subvector_with_stride (const gsl_vector_short *v, size_t i, size_t stride, size_t n); /* Operations */ short gsl_vector_short_get (const gsl_vector_short * v, const size_t i); void gsl_vector_short_set (gsl_vector_short * v, const size_t i, short x); short *gsl_vector_short_ptr (gsl_vector_short * v, const size_t i); const short *gsl_vector_short_const_ptr (const gsl_vector_short * v, const size_t i); void gsl_vector_short_set_zero (gsl_vector_short * v); void gsl_vector_short_set_all (gsl_vector_short * v, short x); int gsl_vector_short_set_basis (gsl_vector_short * v, size_t i); int gsl_vector_short_fread (FILE * stream, gsl_vector_short * v); int gsl_vector_short_fwrite (FILE * stream, const gsl_vector_short * v); int gsl_vector_short_fscanf (FILE * stream, gsl_vector_short * v); int gsl_vector_short_fprintf (FILE * stream, const gsl_vector_short * v, const char *format); int gsl_vector_short_memcpy (gsl_vector_short * dest, const gsl_vector_short * src); int gsl_vector_short_reverse (gsl_vector_short * v); int gsl_vector_short_swap (gsl_vector_short * v, gsl_vector_short * w); int gsl_vector_short_swap_elements (gsl_vector_short * v, const size_t i, const size_t j); short gsl_vector_short_max (const gsl_vector_short * v); short gsl_vector_short_min (const gsl_vector_short * v); void gsl_vector_short_minmax (const gsl_vector_short * v, short * min_out, short * max_out); size_t gsl_vector_short_max_index (const gsl_vector_short * v); size_t gsl_vector_short_min_index (const gsl_vector_short * v); void gsl_vector_short_minmax_index (const gsl_vector_short * v, size_t * imin, size_t * imax); int gsl_vector_short_add (gsl_vector_short * a, const gsl_vector_short * b); int gsl_vector_short_sub (gsl_vector_short * a, const gsl_vector_short * b); int gsl_vector_short_mul (gsl_vector_short * a, const gsl_vector_short * b); int gsl_vector_short_div (gsl_vector_short * a, const gsl_vector_short * b); int gsl_vector_short_scale (gsl_vector_short * a, const double x); int gsl_vector_short_add_constant (gsl_vector_short * a, const double x); int gsl_vector_short_isnull (const gsl_vector_short * v); int gsl_vector_short_ispos (const gsl_vector_short * v); int gsl_vector_short_isneg (const gsl_vector_short * v); int gsl_vector_short_isnonneg (const gsl_vector_short * v); #ifdef HAVE_INLINE extern inline short gsl_vector_short_get (const gsl_vector_short * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); } #endif return v->data[i * v->stride]; } extern inline void gsl_vector_short_set (gsl_vector_short * v, const size_t i, short x) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_VOID ("index out of range", GSL_EINVAL); } #endif v->data[i * v->stride] = x; } extern inline short * gsl_vector_short_ptr (gsl_vector_short * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return (short *) (v->data + i * v->stride); } extern inline const short * gsl_vector_short_const_ptr (const gsl_vector_short * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return (const short *) (v->data + i * v->stride); } #endif /* HAVE_INLINE */ __END_DECLS #endif /* __GSL_VECTOR_SHORT_H__ */ praat-6.0.04/external/gsl/gsl_vector_uchar.h000066400000000000000000000163421261542461700210370ustar00rootroot00000000000000/* vector/gsl_vector_uchar.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_VECTOR_UCHAR_H__ #define __GSL_VECTOR_UCHAR_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_check_range.h" #include "gsl_block_uchar.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size; size_t stride; unsigned char *data; gsl_block_uchar *block; int owner; } gsl_vector_uchar; typedef struct { gsl_vector_uchar vector; } _gsl_vector_uchar_view; typedef _gsl_vector_uchar_view gsl_vector_uchar_view; typedef struct { gsl_vector_uchar vector; } _gsl_vector_uchar_const_view; typedef const _gsl_vector_uchar_const_view gsl_vector_uchar_const_view; /* Allocation */ gsl_vector_uchar *gsl_vector_uchar_alloc (const size_t n); gsl_vector_uchar *gsl_vector_uchar_calloc (const size_t n); gsl_vector_uchar *gsl_vector_uchar_alloc_from_block (gsl_block_uchar * b, const size_t offset, const size_t n, const size_t stride); gsl_vector_uchar *gsl_vector_uchar_alloc_from_vector (gsl_vector_uchar * v, const size_t offset, const size_t n, const size_t stride); void gsl_vector_uchar_free (gsl_vector_uchar * v); /* Views */ _gsl_vector_uchar_view gsl_vector_uchar_view_array (unsigned char *v, size_t n); _gsl_vector_uchar_view gsl_vector_uchar_view_array_with_stride (unsigned char *base, size_t stride, size_t n); _gsl_vector_uchar_const_view gsl_vector_uchar_const_view_array (const unsigned char *v, size_t n); _gsl_vector_uchar_const_view gsl_vector_uchar_const_view_array_with_stride (const unsigned char *base, size_t stride, size_t n); _gsl_vector_uchar_view gsl_vector_uchar_subvector (gsl_vector_uchar *v, size_t i, size_t n); _gsl_vector_uchar_view gsl_vector_uchar_subvector_with_stride (gsl_vector_uchar *v, size_t i, size_t stride, size_t n); _gsl_vector_uchar_const_view gsl_vector_uchar_const_subvector (const gsl_vector_uchar *v, size_t i, size_t n); _gsl_vector_uchar_const_view gsl_vector_uchar_const_subvector_with_stride (const gsl_vector_uchar *v, size_t i, size_t stride, size_t n); /* Operations */ unsigned char gsl_vector_uchar_get (const gsl_vector_uchar * v, const size_t i); void gsl_vector_uchar_set (gsl_vector_uchar * v, const size_t i, unsigned char x); unsigned char *gsl_vector_uchar_ptr (gsl_vector_uchar * v, const size_t i); const unsigned char *gsl_vector_uchar_const_ptr (const gsl_vector_uchar * v, const size_t i); void gsl_vector_uchar_set_zero (gsl_vector_uchar * v); void gsl_vector_uchar_set_all (gsl_vector_uchar * v, unsigned char x); int gsl_vector_uchar_set_basis (gsl_vector_uchar * v, size_t i); int gsl_vector_uchar_fread (FILE * stream, gsl_vector_uchar * v); int gsl_vector_uchar_fwrite (FILE * stream, const gsl_vector_uchar * v); int gsl_vector_uchar_fscanf (FILE * stream, gsl_vector_uchar * v); int gsl_vector_uchar_fprintf (FILE * stream, const gsl_vector_uchar * v, const char *format); int gsl_vector_uchar_memcpy (gsl_vector_uchar * dest, const gsl_vector_uchar * src); int gsl_vector_uchar_reverse (gsl_vector_uchar * v); int gsl_vector_uchar_swap (gsl_vector_uchar * v, gsl_vector_uchar * w); int gsl_vector_uchar_swap_elements (gsl_vector_uchar * v, const size_t i, const size_t j); unsigned char gsl_vector_uchar_max (const gsl_vector_uchar * v); unsigned char gsl_vector_uchar_min (const gsl_vector_uchar * v); void gsl_vector_uchar_minmax (const gsl_vector_uchar * v, unsigned char * min_out, unsigned char * max_out); size_t gsl_vector_uchar_max_index (const gsl_vector_uchar * v); size_t gsl_vector_uchar_min_index (const gsl_vector_uchar * v); void gsl_vector_uchar_minmax_index (const gsl_vector_uchar * v, size_t * imin, size_t * imax); int gsl_vector_uchar_add (gsl_vector_uchar * a, const gsl_vector_uchar * b); int gsl_vector_uchar_sub (gsl_vector_uchar * a, const gsl_vector_uchar * b); int gsl_vector_uchar_mul (gsl_vector_uchar * a, const gsl_vector_uchar * b); int gsl_vector_uchar_div (gsl_vector_uchar * a, const gsl_vector_uchar * b); int gsl_vector_uchar_scale (gsl_vector_uchar * a, const double x); int gsl_vector_uchar_add_constant (gsl_vector_uchar * a, const double x); int gsl_vector_uchar_isnull (const gsl_vector_uchar * v); int gsl_vector_uchar_ispos (const gsl_vector_uchar * v); int gsl_vector_uchar_isneg (const gsl_vector_uchar * v); int gsl_vector_uchar_isnonneg (const gsl_vector_uchar * v); #ifdef HAVE_INLINE extern inline unsigned char gsl_vector_uchar_get (const gsl_vector_uchar * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); } #endif return v->data[i * v->stride]; } extern inline void gsl_vector_uchar_set (gsl_vector_uchar * v, const size_t i, unsigned char x) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_VOID ("index out of range", GSL_EINVAL); } #endif v->data[i * v->stride] = x; } extern inline unsigned char * gsl_vector_uchar_ptr (gsl_vector_uchar * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return (unsigned char *) (v->data + i * v->stride); } extern inline const unsigned char * gsl_vector_uchar_const_ptr (const gsl_vector_uchar * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return (const unsigned char *) (v->data + i * v->stride); } #endif /* HAVE_INLINE */ __END_DECLS #endif /* __GSL_VECTOR_UCHAR_H__ */ praat-6.0.04/external/gsl/gsl_vector_uint.h000066400000000000000000000161231261542461700207110ustar00rootroot00000000000000/* vector/gsl_vector_uint.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_VECTOR_UINT_H__ #define __GSL_VECTOR_UINT_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_check_range.h" #include "gsl_block_uint.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size; size_t stride; unsigned int *data; gsl_block_uint *block; int owner; } gsl_vector_uint; typedef struct { gsl_vector_uint vector; } _gsl_vector_uint_view; typedef _gsl_vector_uint_view gsl_vector_uint_view; typedef struct { gsl_vector_uint vector; } _gsl_vector_uint_const_view; typedef const _gsl_vector_uint_const_view gsl_vector_uint_const_view; /* Allocation */ gsl_vector_uint *gsl_vector_uint_alloc (const size_t n); gsl_vector_uint *gsl_vector_uint_calloc (const size_t n); gsl_vector_uint *gsl_vector_uint_alloc_from_block (gsl_block_uint * b, const size_t offset, const size_t n, const size_t stride); gsl_vector_uint *gsl_vector_uint_alloc_from_vector (gsl_vector_uint * v, const size_t offset, const size_t n, const size_t stride); void gsl_vector_uint_free (gsl_vector_uint * v); /* Views */ _gsl_vector_uint_view gsl_vector_uint_view_array (unsigned int *v, size_t n); _gsl_vector_uint_view gsl_vector_uint_view_array_with_stride (unsigned int *base, size_t stride, size_t n); _gsl_vector_uint_const_view gsl_vector_uint_const_view_array (const unsigned int *v, size_t n); _gsl_vector_uint_const_view gsl_vector_uint_const_view_array_with_stride (const unsigned int *base, size_t stride, size_t n); _gsl_vector_uint_view gsl_vector_uint_subvector (gsl_vector_uint *v, size_t i, size_t n); _gsl_vector_uint_view gsl_vector_uint_subvector_with_stride (gsl_vector_uint *v, size_t i, size_t stride, size_t n); _gsl_vector_uint_const_view gsl_vector_uint_const_subvector (const gsl_vector_uint *v, size_t i, size_t n); _gsl_vector_uint_const_view gsl_vector_uint_const_subvector_with_stride (const gsl_vector_uint *v, size_t i, size_t stride, size_t n); /* Operations */ unsigned int gsl_vector_uint_get (const gsl_vector_uint * v, const size_t i); void gsl_vector_uint_set (gsl_vector_uint * v, const size_t i, unsigned int x); unsigned int *gsl_vector_uint_ptr (gsl_vector_uint * v, const size_t i); const unsigned int *gsl_vector_uint_const_ptr (const gsl_vector_uint * v, const size_t i); void gsl_vector_uint_set_zero (gsl_vector_uint * v); void gsl_vector_uint_set_all (gsl_vector_uint * v, unsigned int x); int gsl_vector_uint_set_basis (gsl_vector_uint * v, size_t i); int gsl_vector_uint_fread (FILE * stream, gsl_vector_uint * v); int gsl_vector_uint_fwrite (FILE * stream, const gsl_vector_uint * v); int gsl_vector_uint_fscanf (FILE * stream, gsl_vector_uint * v); int gsl_vector_uint_fprintf (FILE * stream, const gsl_vector_uint * v, const char *format); int gsl_vector_uint_memcpy (gsl_vector_uint * dest, const gsl_vector_uint * src); int gsl_vector_uint_reverse (gsl_vector_uint * v); int gsl_vector_uint_swap (gsl_vector_uint * v, gsl_vector_uint * w); int gsl_vector_uint_swap_elements (gsl_vector_uint * v, const size_t i, const size_t j); unsigned int gsl_vector_uint_max (const gsl_vector_uint * v); unsigned int gsl_vector_uint_min (const gsl_vector_uint * v); void gsl_vector_uint_minmax (const gsl_vector_uint * v, unsigned int * min_out, unsigned int * max_out); size_t gsl_vector_uint_max_index (const gsl_vector_uint * v); size_t gsl_vector_uint_min_index (const gsl_vector_uint * v); void gsl_vector_uint_minmax_index (const gsl_vector_uint * v, size_t * imin, size_t * imax); int gsl_vector_uint_add (gsl_vector_uint * a, const gsl_vector_uint * b); int gsl_vector_uint_sub (gsl_vector_uint * a, const gsl_vector_uint * b); int gsl_vector_uint_mul (gsl_vector_uint * a, const gsl_vector_uint * b); int gsl_vector_uint_div (gsl_vector_uint * a, const gsl_vector_uint * b); int gsl_vector_uint_scale (gsl_vector_uint * a, const double x); int gsl_vector_uint_add_constant (gsl_vector_uint * a, const double x); int gsl_vector_uint_isnull (const gsl_vector_uint * v); int gsl_vector_uint_ispos (const gsl_vector_uint * v); int gsl_vector_uint_isneg (const gsl_vector_uint * v); int gsl_vector_uint_isnonneg (const gsl_vector_uint * v); #ifdef HAVE_INLINE extern inline unsigned int gsl_vector_uint_get (const gsl_vector_uint * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); } #endif return v->data[i * v->stride]; } extern inline void gsl_vector_uint_set (gsl_vector_uint * v, const size_t i, unsigned int x) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_VOID ("index out of range", GSL_EINVAL); } #endif v->data[i * v->stride] = x; } extern inline unsigned int * gsl_vector_uint_ptr (gsl_vector_uint * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return (unsigned int *) (v->data + i * v->stride); } extern inline const unsigned int * gsl_vector_uint_const_ptr (const gsl_vector_uint * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return (const unsigned int *) (v->data + i * v->stride); } #endif /* HAVE_INLINE */ __END_DECLS #endif /* __GSL_VECTOR_UINT_H__ */ praat-6.0.04/external/gsl/gsl_vector_ulong.h000066400000000000000000000163421261542461700210610ustar00rootroot00000000000000/* vector/gsl_vector_ulong.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_VECTOR_ULONG_H__ #define __GSL_VECTOR_ULONG_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_check_range.h" #include "gsl_block_ulong.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size; size_t stride; unsigned long *data; gsl_block_ulong *block; int owner; } gsl_vector_ulong; typedef struct { gsl_vector_ulong vector; } _gsl_vector_ulong_view; typedef _gsl_vector_ulong_view gsl_vector_ulong_view; typedef struct { gsl_vector_ulong vector; } _gsl_vector_ulong_const_view; typedef const _gsl_vector_ulong_const_view gsl_vector_ulong_const_view; /* Allocation */ gsl_vector_ulong *gsl_vector_ulong_alloc (const size_t n); gsl_vector_ulong *gsl_vector_ulong_calloc (const size_t n); gsl_vector_ulong *gsl_vector_ulong_alloc_from_block (gsl_block_ulong * b, const size_t offset, const size_t n, const size_t stride); gsl_vector_ulong *gsl_vector_ulong_alloc_from_vector (gsl_vector_ulong * v, const size_t offset, const size_t n, const size_t stride); void gsl_vector_ulong_free (gsl_vector_ulong * v); /* Views */ _gsl_vector_ulong_view gsl_vector_ulong_view_array (unsigned long *v, size_t n); _gsl_vector_ulong_view gsl_vector_ulong_view_array_with_stride (unsigned long *base, size_t stride, size_t n); _gsl_vector_ulong_const_view gsl_vector_ulong_const_view_array (const unsigned long *v, size_t n); _gsl_vector_ulong_const_view gsl_vector_ulong_const_view_array_with_stride (const unsigned long *base, size_t stride, size_t n); _gsl_vector_ulong_view gsl_vector_ulong_subvector (gsl_vector_ulong *v, size_t i, size_t n); _gsl_vector_ulong_view gsl_vector_ulong_subvector_with_stride (gsl_vector_ulong *v, size_t i, size_t stride, size_t n); _gsl_vector_ulong_const_view gsl_vector_ulong_const_subvector (const gsl_vector_ulong *v, size_t i, size_t n); _gsl_vector_ulong_const_view gsl_vector_ulong_const_subvector_with_stride (const gsl_vector_ulong *v, size_t i, size_t stride, size_t n); /* Operations */ unsigned long gsl_vector_ulong_get (const gsl_vector_ulong * v, const size_t i); void gsl_vector_ulong_set (gsl_vector_ulong * v, const size_t i, unsigned long x); unsigned long *gsl_vector_ulong_ptr (gsl_vector_ulong * v, const size_t i); const unsigned long *gsl_vector_ulong_const_ptr (const gsl_vector_ulong * v, const size_t i); void gsl_vector_ulong_set_zero (gsl_vector_ulong * v); void gsl_vector_ulong_set_all (gsl_vector_ulong * v, unsigned long x); int gsl_vector_ulong_set_basis (gsl_vector_ulong * v, size_t i); int gsl_vector_ulong_fread (FILE * stream, gsl_vector_ulong * v); int gsl_vector_ulong_fwrite (FILE * stream, const gsl_vector_ulong * v); int gsl_vector_ulong_fscanf (FILE * stream, gsl_vector_ulong * v); int gsl_vector_ulong_fprintf (FILE * stream, const gsl_vector_ulong * v, const char *format); int gsl_vector_ulong_memcpy (gsl_vector_ulong * dest, const gsl_vector_ulong * src); int gsl_vector_ulong_reverse (gsl_vector_ulong * v); int gsl_vector_ulong_swap (gsl_vector_ulong * v, gsl_vector_ulong * w); int gsl_vector_ulong_swap_elements (gsl_vector_ulong * v, const size_t i, const size_t j); unsigned long gsl_vector_ulong_max (const gsl_vector_ulong * v); unsigned long gsl_vector_ulong_min (const gsl_vector_ulong * v); void gsl_vector_ulong_minmax (const gsl_vector_ulong * v, unsigned long * min_out, unsigned long * max_out); size_t gsl_vector_ulong_max_index (const gsl_vector_ulong * v); size_t gsl_vector_ulong_min_index (const gsl_vector_ulong * v); void gsl_vector_ulong_minmax_index (const gsl_vector_ulong * v, size_t * imin, size_t * imax); int gsl_vector_ulong_add (gsl_vector_ulong * a, const gsl_vector_ulong * b); int gsl_vector_ulong_sub (gsl_vector_ulong * a, const gsl_vector_ulong * b); int gsl_vector_ulong_mul (gsl_vector_ulong * a, const gsl_vector_ulong * b); int gsl_vector_ulong_div (gsl_vector_ulong * a, const gsl_vector_ulong * b); int gsl_vector_ulong_scale (gsl_vector_ulong * a, const double x); int gsl_vector_ulong_add_constant (gsl_vector_ulong * a, const double x); int gsl_vector_ulong_isnull (const gsl_vector_ulong * v); int gsl_vector_ulong_ispos (const gsl_vector_ulong * v); int gsl_vector_ulong_isneg (const gsl_vector_ulong * v); int gsl_vector_ulong_isnonneg (const gsl_vector_ulong * v); #ifdef HAVE_INLINE extern inline unsigned long gsl_vector_ulong_get (const gsl_vector_ulong * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); } #endif return v->data[i * v->stride]; } extern inline void gsl_vector_ulong_set (gsl_vector_ulong * v, const size_t i, unsigned long x) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_VOID ("index out of range", GSL_EINVAL); } #endif v->data[i * v->stride] = x; } extern inline unsigned long * gsl_vector_ulong_ptr (gsl_vector_ulong * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return (unsigned long *) (v->data + i * v->stride); } extern inline const unsigned long * gsl_vector_ulong_const_ptr (const gsl_vector_ulong * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return (const unsigned long *) (v->data + i * v->stride); } #endif /* HAVE_INLINE */ __END_DECLS #endif /* __GSL_VECTOR_ULONG_H__ */ praat-6.0.04/external/gsl/gsl_vector_ushort.h000066400000000000000000000165611261542461700212640ustar00rootroot00000000000000/* vector/gsl_vector_ushort.h * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_VECTOR_USHORT_H__ #define __GSL_VECTOR_USHORT_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #include "gsl_check_range.h" #include "gsl_block_ushort.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS typedef struct { size_t size; size_t stride; unsigned short *data; gsl_block_ushort *block; int owner; } gsl_vector_ushort; typedef struct { gsl_vector_ushort vector; } _gsl_vector_ushort_view; typedef _gsl_vector_ushort_view gsl_vector_ushort_view; typedef struct { gsl_vector_ushort vector; } _gsl_vector_ushort_const_view; typedef const _gsl_vector_ushort_const_view gsl_vector_ushort_const_view; /* Allocation */ gsl_vector_ushort *gsl_vector_ushort_alloc (const size_t n); gsl_vector_ushort *gsl_vector_ushort_calloc (const size_t n); gsl_vector_ushort *gsl_vector_ushort_alloc_from_block (gsl_block_ushort * b, const size_t offset, const size_t n, const size_t stride); gsl_vector_ushort *gsl_vector_ushort_alloc_from_vector (gsl_vector_ushort * v, const size_t offset, const size_t n, const size_t stride); void gsl_vector_ushort_free (gsl_vector_ushort * v); /* Views */ _gsl_vector_ushort_view gsl_vector_ushort_view_array (unsigned short *v, size_t n); _gsl_vector_ushort_view gsl_vector_ushort_view_array_with_stride (unsigned short *base, size_t stride, size_t n); _gsl_vector_ushort_const_view gsl_vector_ushort_const_view_array (const unsigned short *v, size_t n); _gsl_vector_ushort_const_view gsl_vector_ushort_const_view_array_with_stride (const unsigned short *base, size_t stride, size_t n); _gsl_vector_ushort_view gsl_vector_ushort_subvector (gsl_vector_ushort *v, size_t i, size_t n); _gsl_vector_ushort_view gsl_vector_ushort_subvector_with_stride (gsl_vector_ushort *v, size_t i, size_t stride, size_t n); _gsl_vector_ushort_const_view gsl_vector_ushort_const_subvector (const gsl_vector_ushort *v, size_t i, size_t n); _gsl_vector_ushort_const_view gsl_vector_ushort_const_subvector_with_stride (const gsl_vector_ushort *v, size_t i, size_t stride, size_t n); /* Operations */ unsigned short gsl_vector_ushort_get (const gsl_vector_ushort * v, const size_t i); void gsl_vector_ushort_set (gsl_vector_ushort * v, const size_t i, unsigned short x); unsigned short *gsl_vector_ushort_ptr (gsl_vector_ushort * v, const size_t i); const unsigned short *gsl_vector_ushort_const_ptr (const gsl_vector_ushort * v, const size_t i); void gsl_vector_ushort_set_zero (gsl_vector_ushort * v); void gsl_vector_ushort_set_all (gsl_vector_ushort * v, unsigned short x); int gsl_vector_ushort_set_basis (gsl_vector_ushort * v, size_t i); int gsl_vector_ushort_fread (FILE * stream, gsl_vector_ushort * v); int gsl_vector_ushort_fwrite (FILE * stream, const gsl_vector_ushort * v); int gsl_vector_ushort_fscanf (FILE * stream, gsl_vector_ushort * v); int gsl_vector_ushort_fprintf (FILE * stream, const gsl_vector_ushort * v, const char *format); int gsl_vector_ushort_memcpy (gsl_vector_ushort * dest, const gsl_vector_ushort * src); int gsl_vector_ushort_reverse (gsl_vector_ushort * v); int gsl_vector_ushort_swap (gsl_vector_ushort * v, gsl_vector_ushort * w); int gsl_vector_ushort_swap_elements (gsl_vector_ushort * v, const size_t i, const size_t j); unsigned short gsl_vector_ushort_max (const gsl_vector_ushort * v); unsigned short gsl_vector_ushort_min (const gsl_vector_ushort * v); void gsl_vector_ushort_minmax (const gsl_vector_ushort * v, unsigned short * min_out, unsigned short * max_out); size_t gsl_vector_ushort_max_index (const gsl_vector_ushort * v); size_t gsl_vector_ushort_min_index (const gsl_vector_ushort * v); void gsl_vector_ushort_minmax_index (const gsl_vector_ushort * v, size_t * imin, size_t * imax); int gsl_vector_ushort_add (gsl_vector_ushort * a, const gsl_vector_ushort * b); int gsl_vector_ushort_sub (gsl_vector_ushort * a, const gsl_vector_ushort * b); int gsl_vector_ushort_mul (gsl_vector_ushort * a, const gsl_vector_ushort * b); int gsl_vector_ushort_div (gsl_vector_ushort * a, const gsl_vector_ushort * b); int gsl_vector_ushort_scale (gsl_vector_ushort * a, const double x); int gsl_vector_ushort_add_constant (gsl_vector_ushort * a, const double x); int gsl_vector_ushort_isnull (const gsl_vector_ushort * v); int gsl_vector_ushort_ispos (const gsl_vector_ushort * v); int gsl_vector_ushort_isneg (const gsl_vector_ushort * v); int gsl_vector_ushort_isnonneg (const gsl_vector_ushort * v); #ifdef HAVE_INLINE extern inline unsigned short gsl_vector_ushort_get (const gsl_vector_ushort * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); } #endif return v->data[i * v->stride]; } extern inline void gsl_vector_ushort_set (gsl_vector_ushort * v, const size_t i, unsigned short x) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_VOID ("index out of range", GSL_EINVAL); } #endif v->data[i * v->stride] = x; } extern inline unsigned short * gsl_vector_ushort_ptr (gsl_vector_ushort * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return (unsigned short *) (v->data + i * v->stride); } extern inline const unsigned short * gsl_vector_ushort_const_ptr (const gsl_vector_ushort * v, const size_t i) { #if GSL_RANGE_CHECK if (i >= v->size) { GSL_ERROR_NULL ("index out of range", GSL_EINVAL); } #endif return (const unsigned short *) (v->data + i * v->stride); } #endif /* HAVE_INLINE */ __END_DECLS #endif /* __GSL_VECTOR_USHORT_H__ */ praat-6.0.04/external/gsl/gsl_version.h000066400000000000000000000006171261542461700200360ustar00rootroot00000000000000#ifndef __GSL_VERSION_H__ #define __GSL_VERSION_H__ #include "gsl_types.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS #define GSL_VERSION "1.10" GSL_VAR const char * gsl_version; __END_DECLS #endif /* __GSL_VERSION_H__ */ praat-6.0.04/external/gsl/gsl_wavelet.h000066400000000000000000000062031261542461700200150ustar00rootroot00000000000000/* wavelet/gsl_wavelet.h * * Copyright (C) 2004 Ivo Alxneit * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_WAVELET_H__ #define __GSL_WAVELET_H__ #include #include "gsl_types.h" #include "gsl_errno.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS #ifndef GSL_DISABLE_DEPRECATED typedef enum { forward = 1, backward = -1, gsl_wavelet_forward = 1, gsl_wavelet_backward = -1 } gsl_wavelet_direction; #else typedef enum { gsl_wavelet_forward = 1, gsl_wavelet_backward = -1 } gsl_wavelet_direction; #endif typedef struct { const char *name; int (*init) (const double **h1, const double **g1, const double **h2, const double **g2, size_t * nc, size_t * offset, size_t member); } gsl_wavelet_type; typedef struct { const gsl_wavelet_type *type; const double *h1; const double *g1; const double *h2; const double *g2; size_t nc; size_t offset; } gsl_wavelet; typedef struct { double *scratch; size_t n; } gsl_wavelet_workspace; GSL_VAR const gsl_wavelet_type *gsl_wavelet_daubechies; GSL_VAR const gsl_wavelet_type *gsl_wavelet_daubechies_centered; GSL_VAR const gsl_wavelet_type *gsl_wavelet_haar; GSL_VAR const gsl_wavelet_type *gsl_wavelet_haar_centered; GSL_VAR const gsl_wavelet_type *gsl_wavelet_bspline; GSL_VAR const gsl_wavelet_type *gsl_wavelet_bspline_centered; gsl_wavelet *gsl_wavelet_alloc (const gsl_wavelet_type * T, size_t k); void gsl_wavelet_free (gsl_wavelet * w); const char *gsl_wavelet_name (const gsl_wavelet * w); gsl_wavelet_workspace *gsl_wavelet_workspace_alloc (size_t n); void gsl_wavelet_workspace_free (gsl_wavelet_workspace * work); int gsl_wavelet_transform (const gsl_wavelet * w, double *data, size_t stride, size_t n, gsl_wavelet_direction dir, gsl_wavelet_workspace * work); int gsl_wavelet_transform_forward (const gsl_wavelet * w, double *data, size_t stride, size_t n, gsl_wavelet_workspace * work); int gsl_wavelet_transform_inverse (const gsl_wavelet * w, double *data, size_t stride, size_t n, gsl_wavelet_workspace * work); __END_DECLS #endif /* __GSL_WAVELET_H__ */ praat-6.0.04/external/gsl/gsl_wavelet2d.h000066400000000000000000000101071261542461700202410ustar00rootroot00000000000000/* wavelet/gsl_wavelet.h * * Copyright (C) 2004 Ivo Alxneit * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GSL_WAVELET2D_H__ #define __GSL_WAVELET2D_H__ #include #include "gsl_errno.h" #include "gsl_vector_double.h" #include "gsl_matrix_double.h" #include "gsl_wavelet.h" #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS /* empty */ # define __END_DECLS /* empty */ #endif __BEGIN_DECLS int gsl_wavelet2d_transform (const gsl_wavelet * w, double *data, size_t tda, size_t size1, size_t size2, gsl_wavelet_direction dir, gsl_wavelet_workspace * work); int gsl_wavelet2d_transform_forward (const gsl_wavelet * w, double *data, size_t tda, size_t size1, size_t size2, gsl_wavelet_workspace * work); int gsl_wavelet2d_transform_inverse (const gsl_wavelet * w, double *data, size_t tda, size_t size1, size_t size2, gsl_wavelet_workspace * work); int gsl_wavelet2d_nstransform (const gsl_wavelet * w, double *data, size_t tda, size_t size1, size_t size2, gsl_wavelet_direction dir, gsl_wavelet_workspace * work); int gsl_wavelet2d_nstransform_forward (const gsl_wavelet * w, double *data, size_t tda, size_t size1, size_t size2, gsl_wavelet_workspace * work); int gsl_wavelet2d_nstransform_inverse (const gsl_wavelet * w, double *data, size_t tda, size_t size1, size_t size2, gsl_wavelet_workspace * work); int gsl_wavelet2d_transform_matrix (const gsl_wavelet * w, gsl_matrix * a, gsl_wavelet_direction dir, gsl_wavelet_workspace * work); int gsl_wavelet2d_transform_matrix_forward (const gsl_wavelet * w, gsl_matrix * a, gsl_wavelet_workspace * work); int gsl_wavelet2d_transform_matrix_inverse (const gsl_wavelet * w, gsl_matrix * a, gsl_wavelet_workspace * work); int gsl_wavelet2d_nstransform_matrix (const gsl_wavelet * w, gsl_matrix * a, gsl_wavelet_direction dir, gsl_wavelet_workspace * work); int gsl_wavelet2d_nstransform_matrix_forward (const gsl_wavelet * w, gsl_matrix * a, gsl_wavelet_workspace * work); int gsl_wavelet2d_nstransform_matrix_inverse (const gsl_wavelet * w, gsl_matrix * a, gsl_wavelet_workspace * work); __END_DECLS #endif /* __GSL_WAVELET2D_H__ */ praat-6.0.04/external/gsl/gsl_wavelet__bspline.c000066400000000000000000000367371261542461700217020ustar00rootroot00000000000000/* wavelet/bspline.c * * Copyright (C) 2004 Ivo Alxneit * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Coefficients are from A. Cohen, I. Daubechies, and J.-C. Feauveau; * "Biorthogonal Bases of Compactly Supported Wavelets", Communications * on Pure and Applied Mathematics, 45 (1992) 485--560 (table 6.1). * * Note the following errors in table 1: * * N = 2, N~ = 4, m0~ * the second term in z^-1 (45/64 z^-1) should be left out. * * N = 3, N~ = 7, m0~ * the term 336z^-3 should read 363z^-3. */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_math.h" #include "gsl_wavelet.h" static const double h1_103[6] = { -0.0883883476483184405501055452631, 0.0883883476483184405501055452631, M_SQRT1_2, M_SQRT1_2, 0.0883883476483184405501055452631, -0.0883883476483184405501055452631 }; static const double g2_103[6] = { -0.0883883476483184405501055452631, -0.0883883476483184405501055452631, M_SQRT1_2, -(M_SQRT1_2), 0.0883883476483184405501055452631, 0.0883883476483184405501055452631 }; static const double h1_105[10] = { 0.0165728151840597076031447897368, -0.0165728151840597076031447897368, -0.1215339780164378557563951247368, 0.1215339780164378557563951247368, M_SQRT1_2, M_SQRT1_2, 0.1215339780164378557563951247368, -0.1215339780164378557563951247368, -0.0165728151840597076031447897368, 0.0165728151840597076031447897368 }; static const double g2_105[10] = { 0.0165728151840597076031447897368, 0.0165728151840597076031447897368, -0.1215339780164378557563951247368, -0.1215339780164378557563951247368, M_SQRT1_2, -(M_SQRT1_2), 0.1215339780164378557563951247368, 0.1215339780164378557563951247368, -0.0165728151840597076031447897368, -0.0165728151840597076031447897368 }; static const double g1_1[10] = { 0.0, 0.0, 0.0, 0.0, M_SQRT1_2, -(M_SQRT1_2), 0.0, 0.0, 0.0, 0.0 }; static const double h2_1[10] = { 0.0, 0.0, 0.0, 0.0, M_SQRT1_2, M_SQRT1_2, 0.0, 0.0, 0.0, 0.0 }; static const double h1_202[6] = { -0.1767766952966368811002110905262, 0.3535533905932737622004221810524, 1.0606601717798212866012665431573, 0.3535533905932737622004221810524, -0.1767766952966368811002110905262, 0.0 }; static const double g2_202[6] = { 0.0, -0.1767766952966368811002110905262, -0.3535533905932737622004221810524, 1.0606601717798212866012665431573, -0.3535533905932737622004221810524, -0.1767766952966368811002110905262 }; static const double h1_204[10] = { 0.0331456303681194152062895794737, -0.0662912607362388304125791589473, -0.1767766952966368811002110905262, 0.4198446513295125926130013399998, 0.9943689110435824561886873842099, 0.4198446513295125926130013399998, -0.1767766952966368811002110905262, -0.0662912607362388304125791589473, 0.0331456303681194152062895794737, 0.0 }; static const double g2_204[10] = { 0.0, 0.0331456303681194152062895794737, 0.0662912607362388304125791589473, -0.1767766952966368811002110905262, -0.4198446513295125926130013399998, 0.9943689110435824561886873842099, -0.4198446513295125926130013399998, -0.1767766952966368811002110905262, 0.0662912607362388304125791589473, 0.0331456303681194152062895794737 }; static const double h1_206[14] = { -0.0069053396600248781679769957237, 0.0138106793200497563359539914474, 0.0469563096881691715422435709210, -0.1077232986963880994204411332894, -0.1698713556366120029322340948025, 0.4474660099696121052849093228945, 0.9667475524034829435167794013152, 0.4474660099696121052849093228945, -0.1698713556366120029322340948025, -0.1077232986963880994204411332894, 0.0469563096881691715422435709210, 0.0138106793200497563359539914474, -0.0069053396600248781679769957237, 0.0 }; static const double g2_206[14] = { 0.0, -0.0069053396600248781679769957237, -0.0138106793200497563359539914474, 0.0469563096881691715422435709210, 0.1077232986963880994204411332894, -0.1698713556366120029322340948025, -0.4474660099696121052849093228945, 0.9667475524034829435167794013152, -0.4474660099696121052849093228945, -0.1698713556366120029322340948025, 0.1077232986963880994204411332894, 0.0469563096881691715422435709210, -0.0138106793200497563359539914474, -0.0069053396600248781679769957237, }; static const double h1_208[18] = { 0.0015105430506304420992449678146, -0.0030210861012608841984899356291, -0.0129475118625466465649568669819, 0.0289161098263541773284036695929, 0.0529984818906909399392234421792, -0.1349130736077360572068505539514, -0.1638291834340902345352542235443, 0.4625714404759165262773590010400, 0.9516421218971785225243297231697, 0.4625714404759165262773590010400, -0.1638291834340902345352542235443, -0.1349130736077360572068505539514, 0.0529984818906909399392234421792, 0.0289161098263541773284036695929, -0.0129475118625466465649568669819, -0.0030210861012608841984899356291, 0.0015105430506304420992449678146, 0.0 }; static const double g2_208[18] = { 0.0, 0.0015105430506304420992449678146, 0.0030210861012608841984899356291, -0.0129475118625466465649568669819, -0.0289161098263541773284036695929, 0.0529984818906909399392234421792, 0.1349130736077360572068505539514, -0.1638291834340902345352542235443, -0.4625714404759165262773590010400, 0.9516421218971785225243297231697, -0.4625714404759165262773590010400, -0.1638291834340902345352542235443, 0.1349130736077360572068505539514, 0.0529984818906909399392234421792, -0.0289161098263541773284036695929, -0.0129475118625466465649568669819, 0.0030210861012608841984899356291, 0.0015105430506304420992449678146, }; static const double h2_2[18] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3535533905932737622004221810524, 0.7071067811865475244008443621048, 0.3535533905932737622004221810524, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; static const double g1_2[18] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.3535533905932737622004221810524, 0.7071067811865475244008443621048, -0.3535533905932737622004221810524, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; static const double h1_301[4] = { -0.3535533905932737622004221810524, 1.0606601717798212866012665431573, 1.0606601717798212866012665431573, -0.3535533905932737622004221810524 }; static const double g2_301[4] = { 0.3535533905932737622004221810524, 1.0606601717798212866012665431573, -1.0606601717798212866012665431573, -0.3535533905932737622004221810524 }; static const double h1_303[8] = { 0.0662912607362388304125791589473, -0.1988737822087164912377374768420, -0.1546796083845572709626847042104, 0.9943689110435824561886873842099, 0.9943689110435824561886873842099, -0.1546796083845572709626847042104, -0.1988737822087164912377374768420, 0.0662912607362388304125791589473 }; static const double g2_303[8] = { -0.0662912607362388304125791589473, -0.1988737822087164912377374768420, 0.1546796083845572709626847042104, 0.9943689110435824561886873842099, -0.9943689110435824561886873842099, -0.1546796083845572709626847042104, 0.1988737822087164912377374768420, 0.0662912607362388304125791589473 }; static const double h1_305[12] = { -0.0138106793200497563359539914474, 0.0414320379601492690078619743421, 0.0524805814161890740766251675000, -0.2679271788089652729175074340788, -0.0718155324642587329469607555263, 0.9667475524034829435167794013152, 0.9667475524034829435167794013152, -0.0718155324642587329469607555263, -0.2679271788089652729175074340788, 0.0524805814161890740766251675000, 0.0414320379601492690078619743421, -0.0138106793200497563359539914474 }; static const double g2_305[12] = { 0.0138106793200497563359539914474, 0.0414320379601492690078619743421, -0.0524805814161890740766251675000, -0.2679271788089652729175074340788, 0.0718155324642587329469607555263, 0.9667475524034829435167794013152, -0.9667475524034829435167794013152, -0.0718155324642587329469607555263, 0.2679271788089652729175074340788, 0.0524805814161890740766251675000, -0.0414320379601492690078619743421, -0.0138106793200497563359539914474 }; static const double h1_307[16] = { 0.0030210861012608841984899356291, -0.0090632583037826525954698068873, -0.0168317654213106405344439270765, 0.0746639850740189951912512662623, 0.0313329787073628846871956180962, -0.3011591259228349991008967259990, -0.0264992409453454699696117210896, 0.9516421218971785225243297231697, 0.9516421218971785225243297231697, -0.0264992409453454699696117210896, -0.3011591259228349991008967259990, 0.0313329787073628846871956180962, 0.0746639850740189951912512662623, -0.0168317654213106405344439270765, -0.0090632583037826525954698068873, 0.0030210861012608841984899356291 }; static const double g2_307[16] = { -0.0030210861012608841984899356291, -0.0090632583037826525954698068873, 0.0168317654213106405344439270765, 0.0746639850740189951912512662623, -0.0313329787073628846871956180962, -0.3011591259228349991008967259990, 0.0264992409453454699696117210896, 0.9516421218971785225243297231697, -0.9516421218971785225243297231697, -0.0264992409453454699696117210896, 0.3011591259228349991008967259990, 0.0313329787073628846871956180962, -0.0746639850740189951912512662623, -0.0168317654213106405344439270765, 0.0090632583037826525954698068873, 0.0030210861012608841984899356291 }; static const double h1_309[20] = { -0.0006797443727836989446602355165, 0.0020392331183510968339807065496, 0.0050603192196119810324706421788, -0.0206189126411055346546938106687, -0.0141127879301758447558029850103, 0.0991347824942321571990197448581, 0.0123001362694193142367090236328, -0.3201919683607785695513833204624, 0.0020500227115698857061181706055, 0.9421257006782067372990864259380, 0.9421257006782067372990864259380, 0.0020500227115698857061181706055, -0.3201919683607785695513833204624, 0.0123001362694193142367090236328, 0.0991347824942321571990197448581, -0.0141127879301758447558029850103, -0.0206189126411055346546938106687, 0.0050603192196119810324706421788, 0.0020392331183510968339807065496, -0.0006797443727836989446602355165 }; static const double g2_309[20] = { 0.0006797443727836989446602355165, 0.0020392331183510968339807065496, -0.0050603192196119810324706421788, -0.0206189126411055346546938106687, 0.0141127879301758447558029850103, 0.0991347824942321571990197448581, -0.0123001362694193142367090236328, -0.3201919683607785695513833204624, -0.0020500227115698857061181706055, 0.9421257006782067372990864259380, -0.9421257006782067372990864259380, 0.0020500227115698857061181706055, 0.3201919683607785695513833204624, 0.0123001362694193142367090236328, -0.0991347824942321571990197448581, -0.0141127879301758447558029850103, 0.0206189126411055346546938106687, 0.0050603192196119810324706421788, -0.0020392331183510968339807065496, -0.0006797443727836989446602355165 }; static const double h2_3[20] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1767766952966368811002110905262, 0.5303300858899106433006332715786, 0.5303300858899106433006332715786, 0.1767766952966368811002110905262, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; static const double g1_3[20] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.1767766952966368811002110905262, 0.5303300858899106433006332715786, -0.5303300858899106433006332715786, 0.1767766952966368811002110905262, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; static int bspline_init (const double **h1, const double **g1, const double **h2, const double **g2, size_t * nc, size_t * offset, size_t member) { switch (member) { case 103: *nc = 6; *h1 = h1_103; *g1 = &g1_1[2]; *h2 = &h2_1[2]; *g2 = g2_103; break; case 105: *nc = 10; *h1 = h1_105; *g1 = g1_1; *h2 = h2_1; *g2 = g2_105; break; case 202: *nc = 6; *h1 = h1_202; *g1 = &g1_2[6]; *h2 = &h2_2[6]; *g2 = g2_202; break; case 204: *nc = 10; *h1 = h1_204; *g1 = &g1_2[4]; *h2 = &h2_2[4]; *g2 = g2_204; break; case 206: *nc = 14; *h1 = h1_206; *g1 = &g1_2[2]; *h2 = &h2_2[2]; *g2 = g2_206; break; case 208: *nc = 18; *h1 = h1_208; *g1 = g1_2; *h2 = h2_2; *g2 = g2_208; break; case 301: *nc = 4; *h1 = h1_301; *g1 = &g1_3[8]; *h2 = &h2_3[8]; *g2 = g2_301; break; case 303: *nc = 8; *h1 = h1_303; *g1 = &g1_3[6]; *h2 = &h2_3[6]; *g2 = g2_303; break; case 305: *nc = 12; *h1 = h1_305; *g1 = &g1_3[4]; *h2 = &h2_3[4]; *g2 = g2_305; break; case 307: *nc = 16; *h1 = h1_307; *g1 = &g1_3[2]; *h2 = &h2_3[2]; *g2 = g2_307; break; case 309: *nc = 20; *h1 = h1_309; *g1 = g1_3; *h2 = h2_3; *g2 = g2_309; break; default: return GSL_FAILURE; } *offset = 0; return GSL_SUCCESS; } static int bspline_centered_init (const double **h1, const double **g1, const double **h2, const double **g2, size_t * nc, size_t * offset, size_t member) { switch (member) { case 103: *nc = 6; *h1 = h1_103; *g1 = &g1_1[2]; *h2 = &h2_1[2]; *g2 = g2_103; break; case 105: *nc = 10; *h1 = h1_105; *g1 = g1_1; *h2 = h2_1; *g2 = g2_105; break; case 202: *nc = 6; *h1 = h1_202; *g1 = &g1_2[6]; *h2 = &h2_2[6]; *g2 = g2_202; break; case 204: *nc = 10; *h1 = h1_204; *g1 = &g1_2[4]; *h2 = &h2_2[4]; *g2 = g2_204; break; case 206: *nc = 14; *h1 = h1_206; *g1 = &g1_2[2]; *h2 = &h2_2[2]; *g2 = g2_206; break; case 208: *nc = 18; *h1 = h1_208; *g1 = g1_2; *h2 = h2_2; *g2 = g2_208; break; case 301: *nc = 4; *h1 = h1_301; *g1 = &g1_3[8]; *h2 = &h2_3[8]; *g2 = g2_301; break; case 303: *nc = 8; *h1 = h1_303; *g1 = &g1_3[6]; *h2 = &h2_3[6]; *g2 = g2_303; break; case 305: *nc = 12; *h1 = h1_305; *g1 = &g1_3[4]; *h2 = &h2_3[4]; *g2 = g2_305; break; case 307: *nc = 16; *h1 = h1_307; *g1 = &g1_3[2]; *h2 = &h2_3[2]; *g2 = g2_307; break; case 309: *nc = 20; *h1 = h1_309; *g1 = g1_3; *h2 = h2_3; *g2 = g2_309; break; default: return GSL_FAILURE; } *offset = ((*nc) >> 1); return GSL_SUCCESS; } static const gsl_wavelet_type bspline_type = { "bspline", &bspline_init }; static const gsl_wavelet_type bspline_centered_type = { "bspline-centered", &bspline_centered_init }; const gsl_wavelet_type *gsl_wavelet_bspline = &bspline_type; const gsl_wavelet_type *gsl_wavelet_bspline_centered = &bspline_centered_type; praat-6.0.04/external/gsl/gsl_wavelet__daubechies.c000066400000000000000000000300011261542461700223140ustar00rootroot00000000000000/* wavelet/daubechies.c * * Copyright (C) 2004 Ivo Alxneit * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Coefficients for Daubechies wavelets of extremal phase are from * I. Daubechies, "Orthonormal Bases of Compactly Supported Wavelets", * Communications on Pure and Applied Mathematics, 41 (1988) 909--996 * (table 1). * Additional digits have been obtained using the Mathematica package * Daubechies.m by Tong Chen & Meng Xu available at * http://www.cwp.mines.edu/wavelets/. */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_wavelet.h" static const double h_4[4] = { 0.48296291314453414337487159986, 0.83651630373780790557529378092, 0.22414386804201338102597276224, -0.12940952255126038117444941881 }; static const double g_4[4] = { -0.12940952255126038117444941881, -0.22414386804201338102597276224, 0.83651630373780790557529378092, -0.48296291314453414337487159986 }; static const double h_6[6] = { 0.33267055295008261599851158914, 0.80689150931109257649449360409, 0.45987750211849157009515194215, -0.13501102001025458869638990670, -0.08544127388202666169281916918, 0.03522629188570953660274066472 }; static const double g_6[6] = { 0.03522629188570953660274066472, 0.08544127388202666169281916918, -0.13501102001025458869638990670, -0.45987750211849157009515194215, 0.80689150931109257649449360409, -0.33267055295008261599851158914 }; static const double h_8[8] = { 0.23037781330889650086329118304, 0.71484657055291564708992195527, 0.63088076792985890788171633830, -0.02798376941685985421141374718, -0.18703481171909308407957067279, 0.03084138183556076362721936253, 0.03288301166688519973540751355, -0.01059740178506903210488320852 }; static const double g_8[8] = { -0.01059740178506903210488320852, -0.03288301166688519973540751355, 0.03084138183556076362721936253, 0.18703481171909308407957067279, -0.02798376941685985421141374718, -0.63088076792985890788171633830, 0.71484657055291564708992195527, -0.23037781330889650086329118304 }; static const double h_10[10] = { 0.16010239797419291448072374802, 0.60382926979718967054011930653, 0.72430852843777292772807124410, 0.13842814590132073150539714634, -0.24229488706638203186257137947, -0.03224486958463837464847975506, 0.07757149384004571352313048939, -0.00624149021279827427419051911, -0.01258075199908199946850973993, 0.00333572528547377127799818342 }; static const double g_10[10] = { 0.00333572528547377127799818342, 0.01258075199908199946850973993, -0.00624149021279827427419051911, -0.07757149384004571352313048939, -0.03224486958463837464847975506, 0.24229488706638203186257137947, 0.13842814590132073150539714634, -0.72430852843777292772807124410, 0.60382926979718967054011930653, -0.16010239797419291448072374802 }; static const double h_12[12] = { 0.11154074335010946362132391724, 0.49462389039845308567720417688, 0.75113390802109535067893449844, 0.31525035170919762908598965481, -0.22626469396543982007631450066, -0.12976686756726193556228960588, 0.09750160558732304910234355254, 0.02752286553030572862554083950, -0.03158203931748602956507908070, 0.00055384220116149613925191840, 0.00477725751094551063963597525, -0.00107730108530847956485262161 }; static const double g_12[12] = { -0.00107730108530847956485262161, -0.00477725751094551063963597525, 0.00055384220116149613925191840, 0.03158203931748602956507908070, 0.02752286553030572862554083950, -0.09750160558732304910234355254, -0.12976686756726193556228960588, 0.22626469396543982007631450066, 0.31525035170919762908598965481, -0.75113390802109535067893449844, 0.49462389039845308567720417688, -0.11154074335010946362132391724 }; static const double h_14[14] = { 0.07785205408500917901996352196, 0.39653931948191730653900039094, 0.72913209084623511991694307034, 0.46978228740519312247159116097, -0.14390600392856497540506836221, -0.22403618499387498263814042023, 0.07130921926683026475087657050, 0.08061260915108307191292248036, -0.03802993693501441357959206160, -0.01657454163066688065410767489, 0.01255099855609984061298988603, 0.00042957797292136652113212912, -0.00180164070404749091526826291, 0.00035371379997452024844629584 }; static const double g_14[14] = { 0.00035371379997452024844629584, 0.00180164070404749091526826291, 0.00042957797292136652113212912, -0.01255099855609984061298988603, -0.01657454163066688065410767489, 0.03802993693501441357959206160, 0.08061260915108307191292248036, -0.07130921926683026475087657050, -0.22403618499387498263814042023, 0.14390600392856497540506836221, 0.46978228740519312247159116097, -0.72913209084623511991694307034, 0.39653931948191730653900039094, -0.07785205408500917901996352196 }; static const double h_16[16] = { 0.05441584224310400995500940520, 0.31287159091429997065916237551, 0.67563073629728980680780076705, 0.58535468365420671277126552005, -0.01582910525634930566738054788, -0.28401554296154692651620313237, 0.00047248457391328277036059001, 0.12874742662047845885702928751, -0.01736930100180754616961614887, -0.04408825393079475150676372324, 0.01398102791739828164872293057, 0.00874609404740577671638274325, -0.00487035299345157431042218156, -0.00039174037337694704629808036, 0.00067544940645056936636954757, -0.00011747678412476953373062823 }; static const double g_16[16] = { -0.00011747678412476953373062823, -0.00067544940645056936636954757, -0.00039174037337694704629808036, 0.00487035299345157431042218156, 0.00874609404740577671638274325, -0.01398102791739828164872293057, -0.04408825393079475150676372324, 0.01736930100180754616961614887, 0.12874742662047845885702928751, -0.00047248457391328277036059001, -0.28401554296154692651620313237, 0.01582910525634930566738054788, 0.58535468365420671277126552005, -0.67563073629728980680780076705, 0.31287159091429997065916237551, -0.05441584224310400995500940520 }; static const double h_18[18] = { 0.03807794736387834658869765888, 0.24383467461259035373204158165, 0.60482312369011111190307686743, 0.65728807805130053807821263905, 0.13319738582500757619095494590, -0.29327378327917490880640319524, -0.09684078322297646051350813354, 0.14854074933810638013507271751, 0.03072568147933337921231740072, -0.06763282906132997367564227483, 0.00025094711483145195758718975, 0.02236166212367909720537378270, -0.00472320475775139727792570785, -0.00428150368246342983449679500, 0.00184764688305622647661912949, 0.00023038576352319596720521639, -0.00025196318894271013697498868, 0.00003934732031627159948068988 }; static const double g_18[18] = { 0.00003934732031627159948068988, 0.00025196318894271013697498868, 0.00023038576352319596720521639, -0.00184764688305622647661912949, -0.00428150368246342983449679500, 0.00472320475775139727792570785, 0.02236166212367909720537378270, -0.00025094711483145195758718975, -0.06763282906132997367564227483, -0.03072568147933337921231740072, 0.14854074933810638013507271751, 0.09684078322297646051350813354, -0.29327378327917490880640319524, -0.13319738582500757619095494590, 0.65728807805130053807821263905, -0.60482312369011111190307686743, 0.24383467461259035373204158165, -0.03807794736387834658869765888 }; static const double h_20[20] = { 0.02667005790055555358661744877, 0.18817680007769148902089297368, 0.52720118893172558648174482796, 0.68845903945360356574187178255, 0.28117234366057746074872699845, -0.24984642432731537941610189792, -0.19594627437737704350429925432, 0.12736934033579326008267723320, 0.09305736460357235116035228984, -0.07139414716639708714533609308, -0.02945753682187581285828323760, 0.03321267405934100173976365318, 0.00360655356695616965542329142, -0.01073317548333057504431811411, 0.00139535174705290116578931845, 0.00199240529518505611715874224, -0.00068585669495971162656137098, -0.00011646685512928545095148097, 0.00009358867032006959133405013, -0.00001326420289452124481243668 }; static const double g_20[20] = { -0.00001326420289452124481243668, -0.00009358867032006959133405013, -0.00011646685512928545095148097, 0.00068585669495971162656137098, 0.00199240529518505611715874224, -0.00139535174705290116578931845, -0.01073317548333057504431811411, -0.00360655356695616965542329142, 0.03321267405934100173976365318, 0.02945753682187581285828323760, -0.07139414716639708714533609308, -0.09305736460357235116035228984, 0.12736934033579326008267723320, 0.19594627437737704350429925432, -0.24984642432731537941610189792, -0.28117234366057746074872699845, 0.68845903945360356574187178255, -0.52720118893172558648174482796, 0.18817680007769148902089297368, -0.02667005790055555358661744877 }; static int daubechies_init (const double **h1, const double **g1, const double **h2, const double **g2, size_t * nc, size_t * offset, size_t member) { switch (member) { case 4: *h1 = h_4; *g1 = g_4; *h2 = h_4; *g2 = g_4; break; case 6: *h1 = h_6; *g1 = g_6; *h2 = h_6; *g2 = g_6; break; case 8: *h1 = h_8; *g1 = g_8; *h2 = h_8; *g2 = g_8; break; case 10: *h1 = h_10; *g1 = g_10; *h2 = h_10; *g2 = g_10; break; case 12: *h1 = h_12; *g1 = g_12; *h2 = h_12; *g2 = g_12; break; case 14: *h1 = h_14; *g1 = g_14; *h2 = h_14; *g2 = g_14; break; case 16: *h1 = h_16; *g1 = g_16; *h2 = h_16; *g2 = g_16; break; case 18: *h1 = h_18; *g1 = g_18; *h2 = h_18; *g2 = g_18; break; case 20: *h1 = h_20; *g1 = g_20; *h2 = h_20; *g2 = g_20; break; default: return GSL_FAILURE; } *nc = member; *offset = 0; return GSL_SUCCESS; } static int daubechies_centered_init (const double **h1, const double **g1, const double **h2, const double **g2, size_t * nc, size_t * offset, size_t member) { switch (member) { case 4: *h1 = h_4; *g1 = g_4; *h2 = h_4; *g2 = g_4; break; case 6: *h1 = h_6; *g1 = g_6; *h2 = h_6; *g2 = g_6; break; case 8: *h1 = h_8; *g1 = g_8; *h2 = h_8; *g2 = g_8; break; case 10: *h1 = h_10; *g1 = g_10; *h2 = h_10; *g2 = g_10; break; case 12: *h1 = h_12; *g1 = g_12; *h2 = h_12; *g2 = g_12; break; case 14: *h1 = h_14; *g1 = g_14; *h2 = h_14; *g2 = g_14; break; case 16: *h1 = h_16; *g1 = g_16; *h2 = h_16; *g2 = g_16; break; case 18: *h1 = h_18; *g1 = g_18; *h2 = h_18; *g2 = g_18; break; case 20: *h1 = h_20; *g1 = g_20; *h2 = h_20; *g2 = g_20; break; default: return GSL_FAILURE; } *nc = member; *offset = (member >> 1); return GSL_SUCCESS; } static const gsl_wavelet_type daubechies_type = { "daubechies", &daubechies_init }; static const gsl_wavelet_type daubechies_centered_type = { "daubechies-centered", &daubechies_centered_init }; const gsl_wavelet_type *gsl_wavelet_daubechies = &daubechies_type; const gsl_wavelet_type *gsl_wavelet_daubechies_centered = &daubechies_centered_type; praat-6.0.04/external/gsl/gsl_wavelet__dwt.c000066400000000000000000000247621261542461700210370ustar00rootroot00000000000000/* wavelet/dwt.c * * Copyright (C) 2004 Ivo Alxneit * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* function dwt_step is based on the public domain function pwt.c * available from http://www.numerical-recipes.com */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_wavelet.h" #include "gsl_wavelet2d.h" #define ELEMENT(a,stride,i) ((a)[(stride)*(i)]) static int binary_logn (const size_t n); static void dwt_step (const gsl_wavelet * w, double *a, size_t stride, size_t n, gsl_wavelet_direction dir, gsl_wavelet_workspace * work); static int binary_logn (const size_t n) { size_t ntest; size_t logn = 0; size_t k = 1; while (k < n) { k *= 2; logn++; } ntest = (1 << logn); if (n != ntest) { return -1; /* n is not a power of 2 */ } return logn; } static void dwt_step (const gsl_wavelet * w, double *a, size_t stride, size_t n, gsl_wavelet_direction dir, gsl_wavelet_workspace * work) { double ai, ai1; size_t i, ii; size_t jf; size_t k; size_t n1, ni, nh, nmod; for (i = 0; i < work->n; i++) { work->scratch[i] = 0.0; } nmod = w->nc * n; nmod -= w->offset; /* center support */ n1 = n - 1; nh = n >> 1; if (dir == gsl_wavelet_forward) { for (ii = 0, i = 0; i < n; i += 2, ii++) { ni = i + nmod; for (k = 0; k < w->nc; k++) { jf = n1 & (ni + k); work->scratch[ii] += w->h1[k] * ELEMENT (a, stride, jf); work->scratch[ii + nh] += w->g1[k] * ELEMENT (a, stride, jf); } } } else { for (ii = 0, i = 0; i < n; i += 2, ii++) { ai = ELEMENT (a, stride, ii); ai1 = ELEMENT (a, stride, ii + nh); ni = i + nmod; for (k = 0; k < w->nc; k++) { jf = (n1 & (ni + k)); work->scratch[jf] += (w->h2[k] * ai + w->g2[k] * ai1); } } } for (i = 0; i < n; i++) { ELEMENT (a, stride, i) = work->scratch[i]; } } int gsl_wavelet_transform (const gsl_wavelet * w, double *data, size_t stride, size_t n, gsl_wavelet_direction dir, gsl_wavelet_workspace * work) { size_t i; if (work->n < n) { GSL_ERROR ("not enough workspace provided", GSL_EINVAL); } if (binary_logn (n) == -1) { GSL_ERROR ("n is not a power of 2", GSL_EINVAL); } if (n < 2) { return GSL_SUCCESS; } if (dir == gsl_wavelet_forward) { for (i = n; i >= 2; i >>= 1) { dwt_step (w, data, stride, i, dir, work); } } else { for (i = 2; i <= n; i <<= 1) { dwt_step (w, data, stride, i, dir, work); } } return GSL_SUCCESS; } int gsl_wavelet_transform_forward (const gsl_wavelet * w, double *data, size_t stride, size_t n, gsl_wavelet_workspace * work) { return gsl_wavelet_transform (w, data, stride, n, gsl_wavelet_forward, work); } int gsl_wavelet_transform_inverse (const gsl_wavelet * w, double *data, size_t stride, size_t n, gsl_wavelet_workspace * work) { return gsl_wavelet_transform (w, data, stride, n, gsl_wavelet_backward, work); } /* Leaving this out for now BJG */ #if 0 int gsl_dwt_vector (const gsl_wavelet * w, gsl_vector *v, gsl_wavelet_direction dir, gsl_wavelet_workspace * work) { return gsl_dwt (w, v->data, v->stride, v->size, dir, work); } #endif int gsl_wavelet2d_transform (const gsl_wavelet * w, double *data, size_t tda, size_t size1, size_t size2, gsl_wavelet_direction dir, gsl_wavelet_workspace * work) { size_t i; if (size1 != size2) { GSL_ERROR ("2d dwt works only with square matrix", GSL_EINVAL); } if (work->n < size1) { GSL_ERROR ("not enough workspace provided", GSL_EINVAL); } if (binary_logn (size1) == -1) { GSL_ERROR ("n is not a power of 2", GSL_EINVAL); } if (size1 < 2) { return GSL_SUCCESS; } if (dir == gsl_wavelet_forward) { for (i = 0; i < size1; i++) /* for every row j */ { gsl_wavelet_transform (w, &ELEMENT(data, tda, i), 1, size1, dir, work); } for (i = 0; i < size2; i++) /* for every column j */ { gsl_wavelet_transform (w, &ELEMENT(data, 1, i), tda, size2, dir, work); } } else { for (i = 0; i < size2; i++) /* for every column j */ { gsl_wavelet_transform (w, &ELEMENT(data, 1, i), tda, size2, dir, work); } for (i = 0; i < size1; i++) /* for every row j */ { gsl_wavelet_transform (w, &ELEMENT(data, tda, i), 1, size1, dir, work); } } return GSL_SUCCESS; } int gsl_wavelet2d_nstransform (const gsl_wavelet * w, double *data, size_t tda, size_t size1, size_t size2, gsl_wavelet_direction dir, gsl_wavelet_workspace * work) { size_t i, j; if (size1 != size2) { GSL_ERROR ("2d dwt works only with square matrix", GSL_EINVAL); } if (work->n < size1) { GSL_ERROR ("not enough workspace provided", GSL_EINVAL); } if (binary_logn (size1) == -1) { GSL_ERROR ("n is not a power of 2", GSL_EINVAL); } if (size1 < 2) { return GSL_SUCCESS; } if (dir == gsl_wavelet_forward) { for (i = size1; i >= 2; i >>= 1) { for (j = 0; j < i; j++) /* for every row j */ { dwt_step (w, &ELEMENT(data, tda, j), 1, i, dir, work); } for (j = 0; j < i; j++) /* for every column j */ { dwt_step (w, &ELEMENT(data, 1, j), tda, i, dir, work); } } } else { for (i = 2; i <= size1; i <<= 1) { for (j = 0; j < i; j++) /* for every column j */ { dwt_step (w, &ELEMENT(data, 1, j), tda, i, dir, work); } for (j = 0; j < i; j++) /* for every row j */ { dwt_step (w, &ELEMENT(data, tda, j), 1, i, dir, work); } } } return GSL_SUCCESS; } int gsl_wavelet2d_transform_forward (const gsl_wavelet * w, double *data, size_t tda, size_t size1, size_t size2, gsl_wavelet_workspace * work) { return gsl_wavelet2d_transform (w, data, tda, size1, size2, gsl_wavelet_forward, work); } int gsl_wavelet2d_transform_inverse (const gsl_wavelet * w, double *data, size_t tda, size_t size1, size_t size2, gsl_wavelet_workspace * work) { return gsl_wavelet2d_transform (w, data, tda, size1, size2, gsl_wavelet_backward, work); } int gsl_wavelet2d_nstransform_forward (const gsl_wavelet * w, double *data, size_t tda, size_t size1, size_t size2, gsl_wavelet_workspace * work) { return gsl_wavelet2d_nstransform (w, data, tda, size1, size2, gsl_wavelet_forward, work); } int gsl_wavelet2d_nstransform_inverse (const gsl_wavelet * w, double *data, size_t tda, size_t size1, size_t size2, gsl_wavelet_workspace * work) { return gsl_wavelet2d_nstransform (w, data, tda, size1, size2, gsl_wavelet_backward, work); } int gsl_wavelet2d_transform_matrix (const gsl_wavelet * w, gsl_matrix * a, gsl_wavelet_direction dir, gsl_wavelet_workspace * work) { return gsl_wavelet2d_transform (w, a->data, a->tda, a->size1, a->size2, dir, work); } int gsl_wavelet2d_transform_matrix_forward (const gsl_wavelet * w, gsl_matrix * a, gsl_wavelet_workspace * work) { return gsl_wavelet2d_transform (w, a->data, a->tda, a->size1, a->size2, gsl_wavelet_forward, work); } int gsl_wavelet2d_transform_matrix_inverse (const gsl_wavelet * w, gsl_matrix * a, gsl_wavelet_workspace * work) { return gsl_wavelet2d_transform (w, a->data, a->tda, a->size1, a->size2, gsl_wavelet_backward, work); } int gsl_wavelet2d_nstransform_matrix (const gsl_wavelet * w, gsl_matrix * a, gsl_wavelet_direction dir, gsl_wavelet_workspace * work) { return gsl_wavelet2d_nstransform (w, a->data, a->tda, a->size1, a->size2, dir, work); } int gsl_wavelet2d_nstransform_matrix_forward (const gsl_wavelet * w, gsl_matrix * a, gsl_wavelet_workspace * work) { return gsl_wavelet2d_nstransform (w, a->data, a->tda, a->size1, a->size2, gsl_wavelet_forward, work); } int gsl_wavelet2d_nstransform_matrix_inverse (const gsl_wavelet * w, gsl_matrix * a, gsl_wavelet_workspace * work) { return gsl_wavelet2d_nstransform (w, a->data, a->tda, a->size1, a->size2, gsl_wavelet_backward, work); } praat-6.0.04/external/gsl/gsl_wavelet__haar.c000066400000000000000000000037211261542461700211440ustar00rootroot00000000000000/* wavelet/haar.c * * Copyright (C) 2004 Ivo Alxneit * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include "gsl_errno.h" #include "gsl_math.h" #include "gsl_wavelet.h" static const double ch_2[2] = { M_SQRT1_2, M_SQRT1_2 }; static const double cg_2[2] = { M_SQRT1_2, -(M_SQRT1_2) }; static int haar_init (const double **h1, const double **g1, const double **h2, const double **g2, size_t * nc, size_t * offset, const size_t member) { if (member != 2) { return GSL_FAILURE; } *h1 = ch_2; *g1 = cg_2; *h2 = ch_2; *g2 = cg_2; *nc = 2; *offset = 0; return GSL_SUCCESS; } static int haar_centered_init (const double **h1, const double **g1, const double **h2, const double **g2, size_t * nc, size_t * offset, const size_t member) { if (member != 2) { return GSL_FAILURE; } *h1 = ch_2; *g1 = cg_2; *h2 = ch_2; *g2 = cg_2; *nc = 2; *offset = 1; return GSL_SUCCESS; } static const gsl_wavelet_type haar_type = { "haar", &haar_init }; static const gsl_wavelet_type haar_centered_type = { "haar-centered", &haar_centered_init }; const gsl_wavelet_type *gsl_wavelet_haar = &haar_type; const gsl_wavelet_type *gsl_wavelet_haar_centered = &haar_centered_type; praat-6.0.04/external/gsl/gsl_wavelet__wavelet.c000066400000000000000000000060431261542461700217000ustar00rootroot00000000000000/* wavelet/wavelet.c * * Copyright (C) 2004 Ivo Alxneit * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gsl__config.h" #include #include "gsl_errno.h" #include "gsl_wavelet.h" gsl_wavelet * gsl_wavelet_alloc (const gsl_wavelet_type * T, size_t k) { int status; gsl_wavelet *w = (gsl_wavelet *) malloc (sizeof (gsl_wavelet)); if (w == NULL) { GSL_ERROR_VAL ("failed to allocate space for wavelet struct", GSL_ENOMEM, 0); }; w->type = T; status = (T->init) (&(w->h1), &(w->g1), &(w->h2), &(w->g2), &(w->nc), &(w->offset), k); if (status) { free (w); GSL_ERROR_VAL ("invalid wavelet member", GSL_EINVAL, 0); } return w; } void gsl_wavelet_free (gsl_wavelet * w) { free (w); } const char * gsl_wavelet_name (const gsl_wavelet * w) { return w->type->name; } /* Let's not export this for now (BJG) */ #if 0 void gsl_wavelet_print (const gsl_wavelet * w) { size_t n = w->nc; size_t i; printf ("Wavelet type: %s\n", w->type->name); printf (" h1(%d):%12.8f g1(%d):%12.8f h2(%d):%12.8f g2(%d):%12.8f\n", 0, w->h1[0], 0, w->g1[0], 0, w->h2[0], 0, w->g2[0]); for (i = 1; i < (n < 10 ? n : 10); i++) { printf (" h1(%d):%12.8f g1(%d):%12.8f h2(%d):%12.8f g2(%d):%12.8f\n", i, w->h1[i], i, w->g1[i], i, w->h2[i], i, w->g2[i]); } for (; i < n; i++) { printf ("h1(%d):%12.8f g1(%d):%12.8f h2(%d):%12.8f g2(%d):%12.8f\n", i, w->h1[i], i, w->g1[i], i, w->h2[i], i, w->g2[i]); } } #endif gsl_wavelet_workspace * gsl_wavelet_workspace_alloc (size_t n) { gsl_wavelet_workspace *work; if (n == 0) { GSL_ERROR_VAL ("length n must be positive integer", GSL_EDOM, 0); } work = (gsl_wavelet_workspace *) malloc (sizeof (gsl_wavelet_workspace)); if (work == NULL) { GSL_ERROR_VAL ("failed to allocate struct", GSL_ENOMEM, 0); } work->n = n; work->scratch = (double *) malloc (n * sizeof (double)); if (work->scratch == NULL) { /* error in constructor, prevent memory leak */ free (work); GSL_ERROR_VAL ("failed to allocate scratch space", GSL_ENOMEM, 0); } return work; } void gsl_wavelet_workspace_free (gsl_wavelet_workspace * work) { /* release scratch space */ free (work->scratch); work->scratch = NULL; free (work); } praat-6.0.04/external/gsl/templates_off.h000066400000000000000000000020411261542461700203250ustar00rootroot00000000000000#ifdef FUNCTION #undef FUNCTION #endif #ifdef CONCAT4 #undef CONCAT4 #endif #ifdef CONCAT4x #undef CONCAT4x #endif #ifdef CONCAT3 #undef CONCAT3 #endif #ifdef CONCAT3x #undef CONCAT3x #endif #ifdef CONCAT2 #undef CONCAT2 #endif #ifdef CONCAT2x #undef CONCAT2x #endif #ifdef TYPE #undef TYPE #endif #ifdef REAL_TYPE #undef REAL_TYPE #endif #ifdef QUALIFIED_TYPE #undef QUALIFIED_TYPE #endif #ifdef VIEW #undef VIEW #endif #ifdef REAL_VIEW #undef REAL_VIEW #endif #ifdef QUALIFIED_VIEW #undef QUALIFIED_VIEW #endif #ifdef QUALIFIED_REAL_TYPE #undef QUALIFIED_REAL_TYPE #endif #ifdef QUALIFIED_REAL_VIEW #undef QUALIFIED_REAL_VIEW #endif #ifdef USES_LONGDOUBLE #undef USES_LONGDOUBLE #endif #ifdef SHORT_REAL #undef SHORT_REAL #endif #ifndef USE_QUALIFIER #ifdef QUALIFIER #undef QUALIFIER #endif #endif #undef BASE #undef BASE_EPSILON #undef SHORT #undef ATOMIC #undef MULTIPLICITY #undef IN_FORMAT #undef OUT_FORMAT #undef ATOMIC_IO #undef ZERO #undef ONE #undef NAME #undef STRING #undef EXPAND #undef UNSIGNED #ifdef FP #undef FP #endif praat-6.0.04/external/gsl/templates_on.h000066400000000000000000000143371261542461700202020ustar00rootroot00000000000000/* If BASE is undefined we use function names like gsl_name() and assume that we are using doubles. If BASE is defined we used function names like gsl_BASE_name() and use BASE as the base datatype */ #if defined(BASE_GSL_COMPLEX_LONG) #define BASE gsl_complex_long_double #define SHORT complex_long_double #define SHORT_REAL long_double #define ATOMIC long double #define USES_LONGDOUBLE 1 #define MULTIPLICITY 2 #define FP 1 #define IN_FORMAT "%Lg" #define OUT_FORMAT "%Lg" #define ATOMIC_IO ATOMIC #define ZERO {{0.0L,0.0L}} #define ONE {{1.0L,0.0L}} #define BASE_EPSILON GSL_DBL_EPSILON #elif defined(BASE_GSL_COMPLEX) #define BASE gsl_complex #define SHORT complex #define SHORT_REAL #define ATOMIC double #define MULTIPLICITY 2 #define FP 1 #define IN_FORMAT "%lg" #define OUT_FORMAT "%g" #define ATOMIC_IO ATOMIC #define ZERO {{0.0,0.0}} #define ONE {{1.0,0.0}} #define BASE_EPSILON GSL_DBL_EPSILON #elif defined(BASE_GSL_COMPLEX_FLOAT) #define BASE gsl_complex_float #define SHORT complex_float #define SHORT_REAL float #define ATOMIC float #define MULTIPLICITY 2 #define FP 1 #define IN_FORMAT "%g" #define OUT_FORMAT "%g" #define ATOMIC_IO ATOMIC #define ZERO {{0.0F,0.0F}} #define ONE {{1.0F,0.0F}} #define BASE_EPSILON GSL_FLT_EPSILON #elif defined(BASE_LONG_DOUBLE) #define BASE long double #define SHORT long_double #define ATOMIC long double #define USES_LONGDOUBLE 1 #define MULTIPLICITY 1 #define FP 1 #define IN_FORMAT "%Lg" #define OUT_FORMAT "%Lg" #define ATOMIC_IO ATOMIC #define ZERO 0.0L #define ONE 1.0L #define BASE_EPSILON GSL_DBL_EPSILON #elif defined(BASE_DOUBLE) #define BASE double #define SHORT #define ATOMIC double #define MULTIPLICITY 1 #define FP 1 #define IN_FORMAT "%lg" #define OUT_FORMAT "%g" #define ATOMIC_IO ATOMIC #define ZERO 0.0 #define ONE 1.0 #define BASE_EPSILON GSL_DBL_EPSILON #elif defined(BASE_FLOAT) #define BASE float #define SHORT float #define ATOMIC float #define MULTIPLICITY 1 #define FP 1 #define IN_FORMAT "%g" #define OUT_FORMAT "%g" #define ATOMIC_IO ATOMIC #define ZERO 0.0F #define ONE 1.0F #define BASE_EPSILON GSL_FLT_EPSILON #elif defined(BASE_ULONG) #define BASE unsigned long #define SHORT ulong #define ATOMIC unsigned long #define MULTIPLICITY 1 #define IN_FORMAT "%lu" #define OUT_FORMAT "%lu" #define ATOMIC_IO ATOMIC #define ZERO 0UL #define ONE 1UL #define UNSIGNED 1 #elif defined(BASE_LONG) #define BASE long #define SHORT long #define ATOMIC long #define MULTIPLICITY 1 #define IN_FORMAT "%ld" #define OUT_FORMAT "%ld" #define ATOMIC_IO ATOMIC #define ZERO 0L #define ONE 1L #elif defined(BASE_UINT) #define BASE unsigned int #define SHORT uint #define ATOMIC unsigned int #define MULTIPLICITY 1 #define IN_FORMAT "%u" #define OUT_FORMAT "%u" #define ATOMIC_IO ATOMIC #define ZERO 0U #define ONE 1U #define UNSIGNED 1 #elif defined(BASE_INT) #define BASE int #define SHORT int #define ATOMIC int #define MULTIPLICITY 1 #define IN_FORMAT "%d" #define OUT_FORMAT "%d" #define ATOMIC_IO ATOMIC #define ZERO 0 #define ONE 1 #elif defined(BASE_USHORT) #define BASE unsigned short #define SHORT ushort #define ATOMIC unsigned short #define MULTIPLICITY 1 #define IN_FORMAT "%hu" #define OUT_FORMAT "%hu" #define ATOMIC_IO ATOMIC #define ZERO 0U #define ONE 1U #define UNSIGNED 1 #elif defined(BASE_SHORT) #define BASE short #define SHORT short #define ATOMIC short #define MULTIPLICITY 1 #define IN_FORMAT "%hd" #define OUT_FORMAT "%hd" #define ATOMIC_IO ATOMIC #define ZERO 0 #define ONE 1 #elif defined(BASE_UCHAR) #define BASE unsigned char #define SHORT uchar #define ATOMIC unsigned char #define MULTIPLICITY 1 #define IN_FORMAT "%u" #define OUT_FORMAT "%u" #define ATOMIC_IO unsigned int #define ZERO 0U #define ONE 1U #define UNSIGNED 1 #elif defined(BASE_CHAR) #define BASE char #define SHORT char #define ATOMIC char #define MULTIPLICITY 1 #define IN_FORMAT "%d" #define OUT_FORMAT "%d" #define ATOMIC_IO int #define ZERO 0 #define ONE 1 #ifdef __CHAR_UNSIGNED__ #define UNSIGNED 1 #endif #else #error unknown BASE_ directive in source.h #endif #define CONCAT2x(a,b) a ## _ ## b #define CONCAT2(a,b) CONCAT2x(a,b) #define CONCAT3x(a,b,c) a ## _ ## b ## _ ## c #define CONCAT3(a,b,c) CONCAT3x(a,b,c) #define CONCAT4x(a,b,c,d) a ## _ ## b ## _ ## c ## _ ## d #define CONCAT4(a,b,c,d) CONCAT4x(a,b,c,d) #ifndef USE_QUALIFIER #define QUALIFIER #endif #ifdef USE_QUALIFIER #if defined(BASE_DOUBLE) #define FUNCTION(dir,name) CONCAT3(dir,QUALIFIER,name) #define TYPE(dir) dir #define VIEW(dir,name) CONCAT2(dir,name) #define QUALIFIED_TYPE(dir) QUALIFIER dir #define QUALIFIED_VIEW(dir,name) CONCAT3(dir,QUALIFIER,name) #else #define FUNCTION(a,c) CONCAT4(a,SHORT,QUALIFIER,c) #define TYPE(dir) CONCAT2(dir,SHORT) #define VIEW(dir,name) CONCAT3(dir,SHORT,name) #define QUALIFIED_TYPE(dir) QUALIFIER CONCAT2(dir,SHORT) #define QUALIFIED_VIEW(dir,name) CONCAT4(dir,SHORT,QUALIFIER,name) #endif #if defined(BASE_GSL_COMPLEX) #define REAL_TYPE(dir) dir #define REAL_VIEW(dir,name) CONCAT2(dir,name) #define QUALIFIED_REAL_TYPE(dir) QUALIFIER dir #define QUALIFIED_REAL_VIEW(dir,name) CONCAT3(dir,QUALIFIER,name) #else #define REAL_TYPE(dir) CONCAT2(dir,SHORT_REAL) #define REAL_VIEW(dir,name) CONCAT3(dir,SHORT_REAL,name) #define QUALIFIED_REAL_TYPE(dir) QUALIFIER CONCAT2(dir,SHORT_REAL) #define QUALIFIED_REAL_VIEW(dir,name) CONCAT4(dir,SHORT_REAL,QUALIFIER,name) #endif #else #if defined(BASE_DOUBLE) #define FUNCTION(dir,name) CONCAT2(dir,name) #define TYPE(dir) dir #define VIEW(dir,name) CONCAT2(dir,name) #define QUALIFIED_TYPE(dir) TYPE(dir) #define QUALIFIED_VIEW(dir,name) CONCAT2(dir,name) #else #define FUNCTION(a,c) CONCAT3(a,SHORT,c) #define TYPE(dir) CONCAT2(dir,SHORT) #define VIEW(dir,name) CONCAT3(dir,SHORT,name) #define QUALIFIED_TYPE(dir) TYPE(dir) #define QUALIFIED_VIEW(dir,name) CONCAT3(dir,SHORT,name) #endif #if defined(BASE_GSL_COMPLEX) #define REAL_TYPE(dir) dir #define REAL_VIEW(dir,name) CONCAT2(dir,name) #define QUALIFIED_REAL_TYPE(dir) dir #define QUALIFIED_REAL_VIEW(dir,name) CONCAT2(dir,name) #else #define REAL_TYPE(dir) CONCAT2(dir,SHORT_REAL) #define REAL_VIEW(dir,name) CONCAT3(dir,SHORT_REAL,name) #define QUALIFIED_REAL_TYPE(dir) CONCAT2(dir,SHORT_REAL) #define QUALIFIED_REAL_VIEW(dir,name) CONCAT3(dir,SHORT_REAL,name) #endif #endif #define STRING(x) #x #define EXPAND(x) STRING(x) #define NAME(x) EXPAND(TYPE(x)) praat-6.0.04/external/mp3/000077500000000000000000000000001261542461700152415ustar00rootroot00000000000000praat-6.0.04/external/mp3/Makefile000066400000000000000000000010451261542461700167010ustar00rootroot00000000000000# Makefile of the library "external/mp3" # Erez Volk, 24 May 2007 # Paul Boersma, 24 August 2013 include ../../makefile.defs CPPFLAGS = -I ../../sys OBJECTS = mp3.o \ mad_bit.o \ mad_decoder.o \ mad_fixed.o \ mad_frame.o \ mad_huffman.o \ mad_layer12.o \ mad_layer3.o \ mad_stream.o \ mad_synth.o \ mad_timer.o \ mad_version.o .PHONY: all clean all: libmp3.a clean: $(RM) $(OBJECTS) $(RM) libmp3.a libmp3.a: $(OBJECTS) touch libmp3.a rm libmp3.a $(AR) cq libmp3.a $(OBJECTS) $(RANLIB) libmp3.a $(OBJECTS): *.h ../../sys/*.h praat-6.0.04/external/mp3/mad_D.dat000066400000000000000000000635511261542461700167510ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: D.dat,v 1.9 2004/01/23 09:41:32 rob Exp $ */ /* * These are the coefficients for the subband synthesis window. This is a * reordered version of Table B.3 from ISO/IEC 11172-3. * * Every value is parameterized so that shift optimizations can be made at * compile-time. For example, every value can be right-shifted 12 bits to * minimize multiply instruction times without any loss of accuracy. */ { PRESHIFT(0x00000000) /* 0.000000000 */, /* 0 */ -PRESHIFT(0x0001d000) /* -0.000442505 */, PRESHIFT(0x000d5000) /* 0.003250122 */, -PRESHIFT(0x001cb000) /* -0.007003784 */, PRESHIFT(0x007f5000) /* 0.031082153 */, -PRESHIFT(0x01421000) /* -0.078628540 */, PRESHIFT(0x019ae000) /* 0.100311279 */, -PRESHIFT(0x09271000) /* -0.572036743 */, PRESHIFT(0x1251e000) /* 1.144989014 */, PRESHIFT(0x09271000) /* 0.572036743 */, PRESHIFT(0x019ae000) /* 0.100311279 */, PRESHIFT(0x01421000) /* 0.078628540 */, PRESHIFT(0x007f5000) /* 0.031082153 */, PRESHIFT(0x001cb000) /* 0.007003784 */, PRESHIFT(0x000d5000) /* 0.003250122 */, PRESHIFT(0x0001d000) /* 0.000442505 */, PRESHIFT(0x00000000) /* 0.000000000 */, -PRESHIFT(0x0001d000) /* -0.000442505 */, PRESHIFT(0x000d5000) /* 0.003250122 */, -PRESHIFT(0x001cb000) /* -0.007003784 */, PRESHIFT(0x007f5000) /* 0.031082153 */, -PRESHIFT(0x01421000) /* -0.078628540 */, PRESHIFT(0x019ae000) /* 0.100311279 */, -PRESHIFT(0x09271000) /* -0.572036743 */, PRESHIFT(0x1251e000) /* 1.144989014 */, PRESHIFT(0x09271000) /* 0.572036743 */, PRESHIFT(0x019ae000) /* 0.100311279 */, PRESHIFT(0x01421000) /* 0.078628540 */, PRESHIFT(0x007f5000) /* 0.031082153 */, PRESHIFT(0x001cb000) /* 0.007003784 */, PRESHIFT(0x000d5000) /* 0.003250122 */, PRESHIFT(0x0001d000) /* 0.000442505 */ }, { -PRESHIFT(0x00001000) /* -0.000015259 */, /* 1 */ -PRESHIFT(0x0001f000) /* -0.000473022 */, PRESHIFT(0x000da000) /* 0.003326416 */, -PRESHIFT(0x00207000) /* -0.007919312 */, PRESHIFT(0x007d0000) /* 0.030517578 */, -PRESHIFT(0x0158d000) /* -0.084182739 */, PRESHIFT(0x01747000) /* 0.090927124 */, -PRESHIFT(0x099a8000) /* -0.600219727 */, PRESHIFT(0x124f0000) /* 1.144287109 */, PRESHIFT(0x08b38000) /* 0.543823242 */, PRESHIFT(0x01bde000) /* 0.108856201 */, PRESHIFT(0x012b4000) /* 0.073059082 */, PRESHIFT(0x0080f000) /* 0.031478882 */, PRESHIFT(0x00191000) /* 0.006118774 */, PRESHIFT(0x000d0000) /* 0.003173828 */, PRESHIFT(0x0001a000) /* 0.000396729 */, -PRESHIFT(0x00001000) /* -0.000015259 */, -PRESHIFT(0x0001f000) /* -0.000473022 */, PRESHIFT(0x000da000) /* 0.003326416 */, -PRESHIFT(0x00207000) /* -0.007919312 */, PRESHIFT(0x007d0000) /* 0.030517578 */, -PRESHIFT(0x0158d000) /* -0.084182739 */, PRESHIFT(0x01747000) /* 0.090927124 */, -PRESHIFT(0x099a8000) /* -0.600219727 */, PRESHIFT(0x124f0000) /* 1.144287109 */, PRESHIFT(0x08b38000) /* 0.543823242 */, PRESHIFT(0x01bde000) /* 0.108856201 */, PRESHIFT(0x012b4000) /* 0.073059082 */, PRESHIFT(0x0080f000) /* 0.031478882 */, PRESHIFT(0x00191000) /* 0.006118774 */, PRESHIFT(0x000d0000) /* 0.003173828 */, PRESHIFT(0x0001a000) /* 0.000396729 */ }, { -PRESHIFT(0x00001000) /* -0.000015259 */, /* 2 */ -PRESHIFT(0x00023000) /* -0.000534058 */, PRESHIFT(0x000de000) /* 0.003387451 */, -PRESHIFT(0x00245000) /* -0.008865356 */, PRESHIFT(0x007a0000) /* 0.029785156 */, -PRESHIFT(0x016f7000) /* -0.089706421 */, PRESHIFT(0x014a8000) /* 0.080688477 */, -PRESHIFT(0x0a0d8000) /* -0.628295898 */, PRESHIFT(0x12468000) /* 1.142211914 */, PRESHIFT(0x083ff000) /* 0.515609741 */, PRESHIFT(0x01dd8000) /* 0.116577148 */, PRESHIFT(0x01149000) /* 0.067520142 */, PRESHIFT(0x00820000) /* 0.031738281 */, PRESHIFT(0x0015b000) /* 0.005294800 */, PRESHIFT(0x000ca000) /* 0.003082275 */, PRESHIFT(0x00018000) /* 0.000366211 */, -PRESHIFT(0x00001000) /* -0.000015259 */, -PRESHIFT(0x00023000) /* -0.000534058 */, PRESHIFT(0x000de000) /* 0.003387451 */, -PRESHIFT(0x00245000) /* -0.008865356 */, PRESHIFT(0x007a0000) /* 0.029785156 */, -PRESHIFT(0x016f7000) /* -0.089706421 */, PRESHIFT(0x014a8000) /* 0.080688477 */, -PRESHIFT(0x0a0d8000) /* -0.628295898 */, PRESHIFT(0x12468000) /* 1.142211914 */, PRESHIFT(0x083ff000) /* 0.515609741 */, PRESHIFT(0x01dd8000) /* 0.116577148 */, PRESHIFT(0x01149000) /* 0.067520142 */, PRESHIFT(0x00820000) /* 0.031738281 */, PRESHIFT(0x0015b000) /* 0.005294800 */, PRESHIFT(0x000ca000) /* 0.003082275 */, PRESHIFT(0x00018000) /* 0.000366211 */ }, { -PRESHIFT(0x00001000) /* -0.000015259 */, /* 3 */ -PRESHIFT(0x00026000) /* -0.000579834 */, PRESHIFT(0x000e1000) /* 0.003433228 */, -PRESHIFT(0x00285000) /* -0.009841919 */, PRESHIFT(0x00765000) /* 0.028884888 */, -PRESHIFT(0x0185d000) /* -0.095169067 */, PRESHIFT(0x011d1000) /* 0.069595337 */, -PRESHIFT(0x0a7fe000) /* -0.656219482 */, PRESHIFT(0x12386000) /* 1.138763428 */, PRESHIFT(0x07ccb000) /* 0.487472534 */, PRESHIFT(0x01f9c000) /* 0.123474121 */, PRESHIFT(0x00fdf000) /* 0.061996460 */, PRESHIFT(0x00827000) /* 0.031845093 */, PRESHIFT(0x00126000) /* 0.004486084 */, PRESHIFT(0x000c4000) /* 0.002990723 */, PRESHIFT(0x00015000) /* 0.000320435 */, -PRESHIFT(0x00001000) /* -0.000015259 */, -PRESHIFT(0x00026000) /* -0.000579834 */, PRESHIFT(0x000e1000) /* 0.003433228 */, -PRESHIFT(0x00285000) /* -0.009841919 */, PRESHIFT(0x00765000) /* 0.028884888 */, -PRESHIFT(0x0185d000) /* -0.095169067 */, PRESHIFT(0x011d1000) /* 0.069595337 */, -PRESHIFT(0x0a7fe000) /* -0.656219482 */, PRESHIFT(0x12386000) /* 1.138763428 */, PRESHIFT(0x07ccb000) /* 0.487472534 */, PRESHIFT(0x01f9c000) /* 0.123474121 */, PRESHIFT(0x00fdf000) /* 0.061996460 */, PRESHIFT(0x00827000) /* 0.031845093 */, PRESHIFT(0x00126000) /* 0.004486084 */, PRESHIFT(0x000c4000) /* 0.002990723 */, PRESHIFT(0x00015000) /* 0.000320435 */ }, { -PRESHIFT(0x00001000) /* -0.000015259 */, /* 4 */ -PRESHIFT(0x00029000) /* -0.000625610 */, PRESHIFT(0x000e3000) /* 0.003463745 */, -PRESHIFT(0x002c7000) /* -0.010848999 */, PRESHIFT(0x0071e000) /* 0.027801514 */, -PRESHIFT(0x019bd000) /* -0.100540161 */, PRESHIFT(0x00ec0000) /* 0.057617187 */, -PRESHIFT(0x0af15000) /* -0.683914185 */, PRESHIFT(0x12249000) /* 1.133926392 */, PRESHIFT(0x075a0000) /* 0.459472656 */, PRESHIFT(0x0212c000) /* 0.129577637 */, PRESHIFT(0x00e79000) /* 0.056533813 */, PRESHIFT(0x00825000) /* 0.031814575 */, PRESHIFT(0x000f4000) /* 0.003723145 */, PRESHIFT(0x000be000) /* 0.002899170 */, PRESHIFT(0x00013000) /* 0.000289917 */, -PRESHIFT(0x00001000) /* -0.000015259 */, -PRESHIFT(0x00029000) /* -0.000625610 */, PRESHIFT(0x000e3000) /* 0.003463745 */, -PRESHIFT(0x002c7000) /* -0.010848999 */, PRESHIFT(0x0071e000) /* 0.027801514 */, -PRESHIFT(0x019bd000) /* -0.100540161 */, PRESHIFT(0x00ec0000) /* 0.057617187 */, -PRESHIFT(0x0af15000) /* -0.683914185 */, PRESHIFT(0x12249000) /* 1.133926392 */, PRESHIFT(0x075a0000) /* 0.459472656 */, PRESHIFT(0x0212c000) /* 0.129577637 */, PRESHIFT(0x00e79000) /* 0.056533813 */, PRESHIFT(0x00825000) /* 0.031814575 */, PRESHIFT(0x000f4000) /* 0.003723145 */, PRESHIFT(0x000be000) /* 0.002899170 */, PRESHIFT(0x00013000) /* 0.000289917 */ }, { -PRESHIFT(0x00001000) /* -0.000015259 */, /* 5 */ -PRESHIFT(0x0002d000) /* -0.000686646 */, PRESHIFT(0x000e4000) /* 0.003479004 */, -PRESHIFT(0x0030b000) /* -0.011886597 */, PRESHIFT(0x006cb000) /* 0.026535034 */, -PRESHIFT(0x01b17000) /* -0.105819702 */, PRESHIFT(0x00b77000) /* 0.044784546 */, -PRESHIFT(0x0b619000) /* -0.711318970 */, PRESHIFT(0x120b4000) /* 1.127746582 */, PRESHIFT(0x06e81000) /* 0.431655884 */, PRESHIFT(0x02288000) /* 0.134887695 */, PRESHIFT(0x00d17000) /* 0.051132202 */, PRESHIFT(0x0081b000) /* 0.031661987 */, PRESHIFT(0x000c5000) /* 0.003005981 */, PRESHIFT(0x000b7000) /* 0.002792358 */, PRESHIFT(0x00011000) /* 0.000259399 */, -PRESHIFT(0x00001000) /* -0.000015259 */, -PRESHIFT(0x0002d000) /* -0.000686646 */, PRESHIFT(0x000e4000) /* 0.003479004 */, -PRESHIFT(0x0030b000) /* -0.011886597 */, PRESHIFT(0x006cb000) /* 0.026535034 */, -PRESHIFT(0x01b17000) /* -0.105819702 */, PRESHIFT(0x00b77000) /* 0.044784546 */, -PRESHIFT(0x0b619000) /* -0.711318970 */, PRESHIFT(0x120b4000) /* 1.127746582 */, PRESHIFT(0x06e81000) /* 0.431655884 */, PRESHIFT(0x02288000) /* 0.134887695 */, PRESHIFT(0x00d17000) /* 0.051132202 */, PRESHIFT(0x0081b000) /* 0.031661987 */, PRESHIFT(0x000c5000) /* 0.003005981 */, PRESHIFT(0x000b7000) /* 0.002792358 */, PRESHIFT(0x00011000) /* 0.000259399 */ }, { -PRESHIFT(0x00001000) /* -0.000015259 */, /* 6 */ -PRESHIFT(0x00031000) /* -0.000747681 */, PRESHIFT(0x000e4000) /* 0.003479004 */, -PRESHIFT(0x00350000) /* -0.012939453 */, PRESHIFT(0x0066c000) /* 0.025085449 */, -PRESHIFT(0x01c67000) /* -0.110946655 */, PRESHIFT(0x007f5000) /* 0.031082153 */, -PRESHIFT(0x0bd06000) /* -0.738372803 */, PRESHIFT(0x11ec7000) /* 1.120223999 */, PRESHIFT(0x06772000) /* 0.404083252 */, PRESHIFT(0x023b3000) /* 0.139450073 */, PRESHIFT(0x00bbc000) /* 0.045837402 */, PRESHIFT(0x00809000) /* 0.031387329 */, PRESHIFT(0x00099000) /* 0.002334595 */, PRESHIFT(0x000b0000) /* 0.002685547 */, PRESHIFT(0x00010000) /* 0.000244141 */, -PRESHIFT(0x00001000) /* -0.000015259 */, -PRESHIFT(0x00031000) /* -0.000747681 */, PRESHIFT(0x000e4000) /* 0.003479004 */, -PRESHIFT(0x00350000) /* -0.012939453 */, PRESHIFT(0x0066c000) /* 0.025085449 */, -PRESHIFT(0x01c67000) /* -0.110946655 */, PRESHIFT(0x007f5000) /* 0.031082153 */, -PRESHIFT(0x0bd06000) /* -0.738372803 */, PRESHIFT(0x11ec7000) /* 1.120223999 */, PRESHIFT(0x06772000) /* 0.404083252 */, PRESHIFT(0x023b3000) /* 0.139450073 */, PRESHIFT(0x00bbc000) /* 0.045837402 */, PRESHIFT(0x00809000) /* 0.031387329 */, PRESHIFT(0x00099000) /* 0.002334595 */, PRESHIFT(0x000b0000) /* 0.002685547 */, PRESHIFT(0x00010000) /* 0.000244141 */ }, { -PRESHIFT(0x00002000) /* -0.000030518 */, /* 7 */ -PRESHIFT(0x00035000) /* -0.000808716 */, PRESHIFT(0x000e3000) /* 0.003463745 */, -PRESHIFT(0x00397000) /* -0.014022827 */, PRESHIFT(0x005ff000) /* 0.023422241 */, -PRESHIFT(0x01dad000) /* -0.115921021 */, PRESHIFT(0x0043a000) /* 0.016510010 */, -PRESHIFT(0x0c3d9000) /* -0.765029907 */, PRESHIFT(0x11c83000) /* 1.111373901 */, PRESHIFT(0x06076000) /* 0.376800537 */, PRESHIFT(0x024ad000) /* 0.143264771 */, PRESHIFT(0x00a67000) /* 0.040634155 */, PRESHIFT(0x007f0000) /* 0.031005859 */, PRESHIFT(0x0006f000) /* 0.001693726 */, PRESHIFT(0x000a9000) /* 0.002578735 */, PRESHIFT(0x0000e000) /* 0.000213623 */, -PRESHIFT(0x00002000) /* -0.000030518 */, -PRESHIFT(0x00035000) /* -0.000808716 */, PRESHIFT(0x000e3000) /* 0.003463745 */, -PRESHIFT(0x00397000) /* -0.014022827 */, PRESHIFT(0x005ff000) /* 0.023422241 */, -PRESHIFT(0x01dad000) /* -0.115921021 */, PRESHIFT(0x0043a000) /* 0.016510010 */, -PRESHIFT(0x0c3d9000) /* -0.765029907 */, PRESHIFT(0x11c83000) /* 1.111373901 */, PRESHIFT(0x06076000) /* 0.376800537 */, PRESHIFT(0x024ad000) /* 0.143264771 */, PRESHIFT(0x00a67000) /* 0.040634155 */, PRESHIFT(0x007f0000) /* 0.031005859 */, PRESHIFT(0x0006f000) /* 0.001693726 */, PRESHIFT(0x000a9000) /* 0.002578735 */, PRESHIFT(0x0000e000) /* 0.000213623 */ }, { -PRESHIFT(0x00002000) /* -0.000030518 */, /* 8 */ -PRESHIFT(0x0003a000) /* -0.000885010 */, PRESHIFT(0x000e0000) /* 0.003417969 */, -PRESHIFT(0x003df000) /* -0.015121460 */, PRESHIFT(0x00586000) /* 0.021575928 */, -PRESHIFT(0x01ee6000) /* -0.120697021 */, PRESHIFT(0x00046000) /* 0.001068115 */, -PRESHIFT(0x0ca8d000) /* -0.791213989 */, PRESHIFT(0x119e9000) /* 1.101211548 */, PRESHIFT(0x05991000) /* 0.349868774 */, PRESHIFT(0x02578000) /* 0.146362305 */, PRESHIFT(0x0091a000) /* 0.035552979 */, PRESHIFT(0x007d1000) /* 0.030532837 */, PRESHIFT(0x00048000) /* 0.001098633 */, PRESHIFT(0x000a1000) /* 0.002456665 */, PRESHIFT(0x0000d000) /* 0.000198364 */, -PRESHIFT(0x00002000) /* -0.000030518 */, -PRESHIFT(0x0003a000) /* -0.000885010 */, PRESHIFT(0x000e0000) /* 0.003417969 */, -PRESHIFT(0x003df000) /* -0.015121460 */, PRESHIFT(0x00586000) /* 0.021575928 */, -PRESHIFT(0x01ee6000) /* -0.120697021 */, PRESHIFT(0x00046000) /* 0.001068115 */, -PRESHIFT(0x0ca8d000) /* -0.791213989 */, PRESHIFT(0x119e9000) /* 1.101211548 */, PRESHIFT(0x05991000) /* 0.349868774 */, PRESHIFT(0x02578000) /* 0.146362305 */, PRESHIFT(0x0091a000) /* 0.035552979 */, PRESHIFT(0x007d1000) /* 0.030532837 */, PRESHIFT(0x00048000) /* 0.001098633 */, PRESHIFT(0x000a1000) /* 0.002456665 */, PRESHIFT(0x0000d000) /* 0.000198364 */ }, { -PRESHIFT(0x00002000) /* -0.000030518 */, /* 9 */ -PRESHIFT(0x0003f000) /* -0.000961304 */, PRESHIFT(0x000dd000) /* 0.003372192 */, -PRESHIFT(0x00428000) /* -0.016235352 */, PRESHIFT(0x00500000) /* 0.019531250 */, -PRESHIFT(0x02011000) /* -0.125259399 */, -PRESHIFT(0x003e6000) /* -0.015228271 */, -PRESHIFT(0x0d11e000) /* -0.816864014 */, PRESHIFT(0x116fc000) /* 1.089782715 */, PRESHIFT(0x052c5000) /* 0.323318481 */, PRESHIFT(0x02616000) /* 0.148773193 */, PRESHIFT(0x007d6000) /* 0.030609131 */, PRESHIFT(0x007aa000) /* 0.029937744 */, PRESHIFT(0x00024000) /* 0.000549316 */, PRESHIFT(0x0009a000) /* 0.002349854 */, PRESHIFT(0x0000b000) /* 0.000167847 */, -PRESHIFT(0x00002000) /* -0.000030518 */, -PRESHIFT(0x0003f000) /* -0.000961304 */, PRESHIFT(0x000dd000) /* 0.003372192 */, -PRESHIFT(0x00428000) /* -0.016235352 */, PRESHIFT(0x00500000) /* 0.019531250 */, -PRESHIFT(0x02011000) /* -0.125259399 */, -PRESHIFT(0x003e6000) /* -0.015228271 */, -PRESHIFT(0x0d11e000) /* -0.816864014 */, PRESHIFT(0x116fc000) /* 1.089782715 */, PRESHIFT(0x052c5000) /* 0.323318481 */, PRESHIFT(0x02616000) /* 0.148773193 */, PRESHIFT(0x007d6000) /* 0.030609131 */, PRESHIFT(0x007aa000) /* 0.029937744 */, PRESHIFT(0x00024000) /* 0.000549316 */, PRESHIFT(0x0009a000) /* 0.002349854 */, PRESHIFT(0x0000b000) /* 0.000167847 */ }, { -PRESHIFT(0x00002000) /* -0.000030518 */, /* 10 */ -PRESHIFT(0x00044000) /* -0.001037598 */, PRESHIFT(0x000d7000) /* 0.003280640 */, -PRESHIFT(0x00471000) /* -0.017349243 */, PRESHIFT(0x0046b000) /* 0.017257690 */, -PRESHIFT(0x0212b000) /* -0.129562378 */, -PRESHIFT(0x0084a000) /* -0.032379150 */, -PRESHIFT(0x0d78a000) /* -0.841949463 */, PRESHIFT(0x113be000) /* 1.077117920 */, PRESHIFT(0x04c16000) /* 0.297210693 */, PRESHIFT(0x02687000) /* 0.150497437 */, PRESHIFT(0x0069c000) /* 0.025817871 */, PRESHIFT(0x0077f000) /* 0.029281616 */, PRESHIFT(0x00002000) /* 0.000030518 */, PRESHIFT(0x00093000) /* 0.002243042 */, PRESHIFT(0x0000a000) /* 0.000152588 */, -PRESHIFT(0x00002000) /* -0.000030518 */, -PRESHIFT(0x00044000) /* -0.001037598 */, PRESHIFT(0x000d7000) /* 0.003280640 */, -PRESHIFT(0x00471000) /* -0.017349243 */, PRESHIFT(0x0046b000) /* 0.017257690 */, -PRESHIFT(0x0212b000) /* -0.129562378 */, -PRESHIFT(0x0084a000) /* -0.032379150 */, -PRESHIFT(0x0d78a000) /* -0.841949463 */, PRESHIFT(0x113be000) /* 1.077117920 */, PRESHIFT(0x04c16000) /* 0.297210693 */, PRESHIFT(0x02687000) /* 0.150497437 */, PRESHIFT(0x0069c000) /* 0.025817871 */, PRESHIFT(0x0077f000) /* 0.029281616 */, PRESHIFT(0x00002000) /* 0.000030518 */, PRESHIFT(0x00093000) /* 0.002243042 */, PRESHIFT(0x0000a000) /* 0.000152588 */ }, { -PRESHIFT(0x00003000) /* -0.000045776 */, /* 11 */ -PRESHIFT(0x00049000) /* -0.001113892 */, PRESHIFT(0x000d0000) /* 0.003173828 */, -PRESHIFT(0x004ba000) /* -0.018463135 */, PRESHIFT(0x003ca000) /* 0.014801025 */, -PRESHIFT(0x02233000) /* -0.133590698 */, -PRESHIFT(0x00ce4000) /* -0.050354004 */, -PRESHIFT(0x0ddca000) /* -0.866363525 */, PRESHIFT(0x1102f000) /* 1.063217163 */, PRESHIFT(0x04587000) /* 0.271591187 */, PRESHIFT(0x026cf000) /* 0.151596069 */, PRESHIFT(0x0056c000) /* 0.021179199 */, PRESHIFT(0x0074e000) /* 0.028533936 */, -PRESHIFT(0x0001d000) /* -0.000442505 */, PRESHIFT(0x0008b000) /* 0.002120972 */, PRESHIFT(0x00009000) /* 0.000137329 */, -PRESHIFT(0x00003000) /* -0.000045776 */, -PRESHIFT(0x00049000) /* -0.001113892 */, PRESHIFT(0x000d0000) /* 0.003173828 */, -PRESHIFT(0x004ba000) /* -0.018463135 */, PRESHIFT(0x003ca000) /* 0.014801025 */, -PRESHIFT(0x02233000) /* -0.133590698 */, -PRESHIFT(0x00ce4000) /* -0.050354004 */, -PRESHIFT(0x0ddca000) /* -0.866363525 */, PRESHIFT(0x1102f000) /* 1.063217163 */, PRESHIFT(0x04587000) /* 0.271591187 */, PRESHIFT(0x026cf000) /* 0.151596069 */, PRESHIFT(0x0056c000) /* 0.021179199 */, PRESHIFT(0x0074e000) /* 0.028533936 */, -PRESHIFT(0x0001d000) /* -0.000442505 */, PRESHIFT(0x0008b000) /* 0.002120972 */, PRESHIFT(0x00009000) /* 0.000137329 */ }, { -PRESHIFT(0x00003000) /* -0.000045776 */, /* 12 */ -PRESHIFT(0x0004f000) /* -0.001205444 */, PRESHIFT(0x000c8000) /* 0.003051758 */, -PRESHIFT(0x00503000) /* -0.019577026 */, PRESHIFT(0x0031a000) /* 0.012115479 */, -PRESHIFT(0x02326000) /* -0.137298584 */, -PRESHIFT(0x011b5000) /* -0.069168091 */, -PRESHIFT(0x0e3dd000) /* -0.890090942 */, PRESHIFT(0x10c54000) /* 1.048156738 */, PRESHIFT(0x03f1b000) /* 0.246505737 */, PRESHIFT(0x026ee000) /* 0.152069092 */, PRESHIFT(0x00447000) /* 0.016708374 */, PRESHIFT(0x00719000) /* 0.027725220 */, -PRESHIFT(0x00039000) /* -0.000869751 */, PRESHIFT(0x00084000) /* 0.002014160 */, PRESHIFT(0x00008000) /* 0.000122070 */, -PRESHIFT(0x00003000) /* -0.000045776 */, -PRESHIFT(0x0004f000) /* -0.001205444 */, PRESHIFT(0x000c8000) /* 0.003051758 */, -PRESHIFT(0x00503000) /* -0.019577026 */, PRESHIFT(0x0031a000) /* 0.012115479 */, -PRESHIFT(0x02326000) /* -0.137298584 */, -PRESHIFT(0x011b5000) /* -0.069168091 */, -PRESHIFT(0x0e3dd000) /* -0.890090942 */, PRESHIFT(0x10c54000) /* 1.048156738 */, PRESHIFT(0x03f1b000) /* 0.246505737 */, PRESHIFT(0x026ee000) /* 0.152069092 */, PRESHIFT(0x00447000) /* 0.016708374 */, PRESHIFT(0x00719000) /* 0.027725220 */, -PRESHIFT(0x00039000) /* -0.000869751 */, PRESHIFT(0x00084000) /* 0.002014160 */, PRESHIFT(0x00008000) /* 0.000122070 */ }, { -PRESHIFT(0x00004000) /* -0.000061035 */, /* 13 */ -PRESHIFT(0x00055000) /* -0.001296997 */, PRESHIFT(0x000bd000) /* 0.002883911 */, -PRESHIFT(0x0054c000) /* -0.020690918 */, PRESHIFT(0x0025d000) /* 0.009231567 */, -PRESHIFT(0x02403000) /* -0.140670776 */, -PRESHIFT(0x016ba000) /* -0.088775635 */, -PRESHIFT(0x0e9be000) /* -0.913055420 */, PRESHIFT(0x1082d000) /* 1.031936646 */, PRESHIFT(0x038d4000) /* 0.221984863 */, PRESHIFT(0x026e7000) /* 0.151962280 */, PRESHIFT(0x0032e000) /* 0.012420654 */, PRESHIFT(0x006df000) /* 0.026840210 */, -PRESHIFT(0x00053000) /* -0.001266479 */, PRESHIFT(0x0007d000) /* 0.001907349 */, PRESHIFT(0x00007000) /* 0.000106812 */, -PRESHIFT(0x00004000) /* -0.000061035 */, -PRESHIFT(0x00055000) /* -0.001296997 */, PRESHIFT(0x000bd000) /* 0.002883911 */, -PRESHIFT(0x0054c000) /* -0.020690918 */, PRESHIFT(0x0025d000) /* 0.009231567 */, -PRESHIFT(0x02403000) /* -0.140670776 */, -PRESHIFT(0x016ba000) /* -0.088775635 */, -PRESHIFT(0x0e9be000) /* -0.913055420 */, PRESHIFT(0x1082d000) /* 1.031936646 */, PRESHIFT(0x038d4000) /* 0.221984863 */, PRESHIFT(0x026e7000) /* 0.151962280 */, PRESHIFT(0x0032e000) /* 0.012420654 */, PRESHIFT(0x006df000) /* 0.026840210 */, -PRESHIFT(0x00053000) /* -0.001266479 */, PRESHIFT(0x0007d000) /* 0.001907349 */, PRESHIFT(0x00007000) /* 0.000106812 */ }, { -PRESHIFT(0x00004000) /* -0.000061035 */, /* 14 */ -PRESHIFT(0x0005b000) /* -0.001388550 */, PRESHIFT(0x000b1000) /* 0.002700806 */, -PRESHIFT(0x00594000) /* -0.021789551 */, PRESHIFT(0x00192000) /* 0.006134033 */, -PRESHIFT(0x024c8000) /* -0.143676758 */, -PRESHIFT(0x01bf2000) /* -0.109161377 */, -PRESHIFT(0x0ef69000) /* -0.935195923 */, PRESHIFT(0x103be000) /* 1.014617920 */, PRESHIFT(0x032b4000) /* 0.198059082 */, PRESHIFT(0x026bc000) /* 0.151306152 */, PRESHIFT(0x00221000) /* 0.008316040 */, PRESHIFT(0x006a2000) /* 0.025909424 */, -PRESHIFT(0x0006a000) /* -0.001617432 */, PRESHIFT(0x00075000) /* 0.001785278 */, PRESHIFT(0x00007000) /* 0.000106812 */, -PRESHIFT(0x00004000) /* -0.000061035 */, -PRESHIFT(0x0005b000) /* -0.001388550 */, PRESHIFT(0x000b1000) /* 0.002700806 */, -PRESHIFT(0x00594000) /* -0.021789551 */, PRESHIFT(0x00192000) /* 0.006134033 */, -PRESHIFT(0x024c8000) /* -0.143676758 */, -PRESHIFT(0x01bf2000) /* -0.109161377 */, -PRESHIFT(0x0ef69000) /* -0.935195923 */, PRESHIFT(0x103be000) /* 1.014617920 */, PRESHIFT(0x032b4000) /* 0.198059082 */, PRESHIFT(0x026bc000) /* 0.151306152 */, PRESHIFT(0x00221000) /* 0.008316040 */, PRESHIFT(0x006a2000) /* 0.025909424 */, -PRESHIFT(0x0006a000) /* -0.001617432 */, PRESHIFT(0x00075000) /* 0.001785278 */, PRESHIFT(0x00007000) /* 0.000106812 */ }, { -PRESHIFT(0x00005000) /* -0.000076294 */, /* 15 */ -PRESHIFT(0x00061000) /* -0.001480103 */, PRESHIFT(0x000a3000) /* 0.002487183 */, -PRESHIFT(0x005da000) /* -0.022857666 */, PRESHIFT(0x000b9000) /* 0.002822876 */, -PRESHIFT(0x02571000) /* -0.146255493 */, -PRESHIFT(0x0215c000) /* -0.130310059 */, -PRESHIFT(0x0f4dc000) /* -0.956481934 */, PRESHIFT(0x0ff0a000) /* 0.996246338 */, PRESHIFT(0x02cbf000) /* 0.174789429 */, PRESHIFT(0x0266e000) /* 0.150115967 */, PRESHIFT(0x00120000) /* 0.004394531 */, PRESHIFT(0x00662000) /* 0.024932861 */, -PRESHIFT(0x0007f000) /* -0.001937866 */, PRESHIFT(0x0006f000) /* 0.001693726 */, PRESHIFT(0x00006000) /* 0.000091553 */, -PRESHIFT(0x00005000) /* -0.000076294 */, -PRESHIFT(0x00061000) /* -0.001480103 */, PRESHIFT(0x000a3000) /* 0.002487183 */, -PRESHIFT(0x005da000) /* -0.022857666 */, PRESHIFT(0x000b9000) /* 0.002822876 */, -PRESHIFT(0x02571000) /* -0.146255493 */, -PRESHIFT(0x0215c000) /* -0.130310059 */, -PRESHIFT(0x0f4dc000) /* -0.956481934 */, PRESHIFT(0x0ff0a000) /* 0.996246338 */, PRESHIFT(0x02cbf000) /* 0.174789429 */, PRESHIFT(0x0266e000) /* 0.150115967 */, PRESHIFT(0x00120000) /* 0.004394531 */, PRESHIFT(0x00662000) /* 0.024932861 */, -PRESHIFT(0x0007f000) /* -0.001937866 */, PRESHIFT(0x0006f000) /* 0.001693726 */, PRESHIFT(0x00006000) /* 0.000091553 */ }, { -PRESHIFT(0x00005000) /* -0.000076294 */, /* 16 */ -PRESHIFT(0x00068000) /* -0.001586914 */, PRESHIFT(0x00092000) /* 0.002227783 */, -PRESHIFT(0x0061f000) /* -0.023910522 */, -PRESHIFT(0x0002d000) /* -0.000686646 */, -PRESHIFT(0x025ff000) /* -0.148422241 */, -PRESHIFT(0x026f7000) /* -0.152206421 */, -PRESHIFT(0x0fa13000) /* -0.976852417 */, PRESHIFT(0x0fa13000) /* 0.976852417 */, PRESHIFT(0x026f7000) /* 0.152206421 */, PRESHIFT(0x025ff000) /* 0.148422241 */, PRESHIFT(0x0002d000) /* 0.000686646 */, PRESHIFT(0x0061f000) /* 0.023910522 */, -PRESHIFT(0x00092000) /* -0.002227783 */, PRESHIFT(0x00068000) /* 0.001586914 */, PRESHIFT(0x00005000) /* 0.000076294 */, -PRESHIFT(0x00005000) /* -0.000076294 */, -PRESHIFT(0x00068000) /* -0.001586914 */, PRESHIFT(0x00092000) /* 0.002227783 */, -PRESHIFT(0x0061f000) /* -0.023910522 */, -PRESHIFT(0x0002d000) /* -0.000686646 */, -PRESHIFT(0x025ff000) /* -0.148422241 */, -PRESHIFT(0x026f7000) /* -0.152206421 */, -PRESHIFT(0x0fa13000) /* -0.976852417 */, PRESHIFT(0x0fa13000) /* 0.976852417 */, PRESHIFT(0x026f7000) /* 0.152206421 */, PRESHIFT(0x025ff000) /* 0.148422241 */, PRESHIFT(0x0002d000) /* 0.000686646 */, PRESHIFT(0x0061f000) /* 0.023910522 */, -PRESHIFT(0x00092000) /* -0.002227783 */, PRESHIFT(0x00068000) /* 0.001586914 */, PRESHIFT(0x00005000) /* 0.000076294 */ } praat-6.0.04/external/mp3/mad_bit.c000066400000000000000000000153311261542461700170070ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: bit.c,v 1.12 2004/01/23 09:41:32 rob Exp $ */ /*# ifdef HAVE_CONFIG_H*/ # include "mad_config.h" /*# endif*/ # include "mad_global.h" # ifdef HAVE_LIMITS_H # include # else # define CHAR_BIT 8 # endif # include "mad_bit.h" /* * This is the lookup table for computing the CRC-check word. * As described in section 2.4.3.1 and depicted in Figure A.9 * of ISO/IEC 11172-3, the generator polynomial is: * * G(X) = X^16 + X^15 + X^2 + 1 */ static unsigned short const crc_table[256] = { 0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011, 0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022, 0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072, 0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041, 0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2, 0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1, 0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1, 0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087, 0x0082, 0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192, 0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1, 0x01e0, 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1, 0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2, 0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151, 0x8173, 0x0176, 0x017c, 0x8179, 0x0168, 0x816d, 0x8167, 0x0162, 0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132, 0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101, 0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317, 0x0312, 0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321, 0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371, 0x8353, 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342, 0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1, 0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2, 0x83a3, 0x03a6, 0x03ac, 0x83a9, 0x03b8, 0x83bd, 0x83b7, 0x03b2, 0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381, 0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291, 0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7, 0x02a2, 0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2, 0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1, 0x8243, 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252, 0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261, 0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231, 0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202 }; # define CRC_POLY 0x8005 /* * NAME: bit->init() * DESCRIPTION: initialize bit pointer struct */ void mad_bit_init(struct mad_bitptr *bitptr, unsigned char const *byte) { bitptr->byte = byte; bitptr->cache = 0; bitptr->left = CHAR_BIT; } /* * NAME: bit->length() * DESCRIPTION: return number of bits between start and end points */ unsigned int mad_bit_length(struct mad_bitptr const *begin, struct mad_bitptr const *end) { return begin->left + CHAR_BIT * (end->byte - (begin->byte + 1)) + (CHAR_BIT - end->left); } /* * NAME: bit->nextbyte() * DESCRIPTION: return pointer to next unprocessed byte */ unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *bitptr) { return bitptr->left == CHAR_BIT ? bitptr->byte : bitptr->byte + 1; } /* * NAME: bit->skip() * DESCRIPTION: advance bit pointer */ void mad_bit_skip(struct mad_bitptr *bitptr, unsigned int len) { bitptr->byte += len / CHAR_BIT; bitptr->left -= len % CHAR_BIT; if (bitptr->left > CHAR_BIT) { bitptr->byte++; bitptr->left += CHAR_BIT; } if (bitptr->left < CHAR_BIT) bitptr->cache = *bitptr->byte; } /* * NAME: bit->read() * DESCRIPTION: read an arbitrary number of bits and return their UIMSBF value */ unsigned long mad_bit_read(struct mad_bitptr *bitptr, unsigned int len) { register unsigned long value; if (bitptr->left == CHAR_BIT) bitptr->cache = *bitptr->byte; if (len < bitptr->left) { value = (bitptr->cache & ((1 << bitptr->left) - 1)) >> (bitptr->left - len); bitptr->left -= len; return value; } /* remaining bits in current byte */ value = bitptr->cache & ((1 << bitptr->left) - 1); len -= bitptr->left; bitptr->byte++; bitptr->left = CHAR_BIT; /* more bytes */ while (len >= CHAR_BIT) { value = (value << CHAR_BIT) | *bitptr->byte++; len -= CHAR_BIT; } if (len > 0) { bitptr->cache = *bitptr->byte; value = (value << len) | (bitptr->cache >> (CHAR_BIT - len)); bitptr->left -= len; } return value; } # if 0 /* * NAME: bit->write() * DESCRIPTION: write an arbitrary number of bits */ void mad_bit_write(struct mad_bitptr *bitptr, unsigned int len, unsigned long value) { unsigned char *ptr; ptr = (unsigned char *) bitptr->byte; /* ... */ } # endif /* * NAME: bit->crc() * DESCRIPTION: compute CRC-check word */ unsigned short mad_bit_crc(struct mad_bitptr bitptr, unsigned int len, unsigned short init) { register unsigned int crc; for (crc = init; len >= 32; len -= 32) { register unsigned long data; data = mad_bit_read(&bitptr, 32); crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 24)) & 0xff]; crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 16)) & 0xff]; crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 8)) & 0xff]; crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 0)) & 0xff]; } switch (len / 8) { case 3: crc = (crc << 8) ^ crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff]; case 2: crc = (crc << 8) ^ crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff]; case 1: crc = (crc << 8) ^ crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff]; len %= 8; case 0: break; } while (len--) { register unsigned int msb; msb = mad_bit_read(&bitptr, 1) ^ (crc >> 15); crc <<= 1; if (msb & 1) crc ^= CRC_POLY; } return crc & 0xffff; } praat-6.0.04/external/mp3/mad_bit.h000066400000000000000000000031151261542461700170110ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: bit.h,v 1.12 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBMAD_BIT_H # define LIBMAD_BIT_H struct mad_bitptr { unsigned char const *byte; unsigned short cache; unsigned short left; }; void mad_bit_init(struct mad_bitptr *, unsigned char const *); # define mad_bit_finish(bitptr) /* nothing */ unsigned int mad_bit_length(struct mad_bitptr const *, struct mad_bitptr const *); # define mad_bit_bitsleft(bitptr) ((bitptr)->left) unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *); void mad_bit_skip(struct mad_bitptr *, unsigned int); unsigned long mad_bit_read(struct mad_bitptr *, unsigned int); void mad_bit_write(struct mad_bitptr *, unsigned int, unsigned long); unsigned short mad_bit_crc(struct mad_bitptr, unsigned int, unsigned short); # endif praat-6.0.04/external/mp3/mad_config.h000066400000000000000000000100661261542461700175030ustar00rootroot00000000000000/* config.h. */ /* Edited by Erez Volk for Praat. */ /* Luckily we assume C99, which makes life easier. */ /* Compile with Intel implementation for Win32, otherwise 64-bit */ #if defined (_WIN32) && defined (_MSC_VER) || defined (__GNUC__) && defined (__i386__) && ! defined (macintosh) # define FPM_INTEL #else /* !_WIN32 */ # define FPM_64BIT #endif /* _WIN32 */ /* Define to enable diagnostic debugging support. */ /* #undef DEBUG */ /* Define to enable experimental code. */ /* #undef EXPERIMENTAL */ /* Define to 1 if you have the header file. */ #define HAVE_ASSERT_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_DLFCN_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_ERRNO_H */ /* Define to 1 if you have the `fcntl' function. */ /* #undef HAVE_FCNTL */ /* Define to 1 if you have the header file. */ /* #undef HAVE_FCNTL_H */ /* Define to 1 if you have the `fork' function. */ /* #undef HAVE_FORK */ /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_LIMITS_H 1 /* Define if your MIPS CPU supports a 2-operand MADD16 instruction. */ /* #undef HAVE_MADD16_ASM */ /* Define if your MIPS CPU supports a 2-operand MADD instruction. */ /* #undef HAVE_MADD_ASM */ /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the `pipe' function. */ /* #undef HAVE_PIPE */ /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have that is POSIX.1 compatible. */ /* #undef HAVE_SYS_WAIT_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_UNISTD_H */ /* Define to 1 if you have the `waitpid' function. */ /* #undef HAVE_WAITPID */ /* Define to disable debugging assertions. */ /* #undef NDEBUG */ /* Define to optimize for accuracy over speed. */ /* #undef OPT_ACCURACY */ /* Define to optimize for speed over accuracy. */ /* #undef OPT_SPEED */ /* Define to enable a fast subband synthesis approximation optimization. */ /* #undef OPT_SSO */ /* Define to influence a strict interpretation of the ISO/IEC standards, even if this is in opposition with best accepted practices. */ /* #undef OPT_STRICT */ /* Name of package */ #define PACKAGE "libmad" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "support@underbit.com" /* Define to the full name of this package. */ #define PACKAGE_NAME "MPEG Audio Decoder" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "MPEG Audio Decoder 0.15.1b" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "libmad" /* Define to the version of this package. */ #define PACKAGE_VERSION "0.15.1b" /* Erez Volk: Let's hope these sizes are correct. */ /* I've added a runtime test for them just in case. */ /* The size of a `int', as computed by sizeof. */ #define SIZEOF_INT 4 /* The size of a `long', as computed by sizeof. */ #define SIZEOF_LONG 4 /* The size of a `long long', as computed by sizeof. */ #define SIZEOF_LONG_LONG 8 /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ #define VERSION "0.15.1b" /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Define as `__inline' if that's what the C compiler calls it, or to nothing if it is not supported. */ #ifdef _MSC_VER # define inline __inline #endif /* _MSC_VER */ /* Define to `int' if does not define. */ /* #undef pid_t */ praat-6.0.04/external/mp3/mad_decoder.c000066400000000000000000000266351261542461700176470ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: decoder.c,v 1.22 2004/01/23 09:41:32 rob Exp $ */ /*# ifdef HAVE_CONFIG_H*/ # include "mad_config.h" /*# endif*/ # include "mad_global.h" # ifdef HAVE_SYS_TYPES_H # include # endif # ifdef HAVE_SYS_WAIT_H # include # endif # ifdef HAVE_UNISTD_H # include # endif # ifdef HAVE_FCNTL_H # include # endif # include # ifdef HAVE_ERRNO_H # include # endif # include "mad_stream.h" # include "mad_frame.h" # include "mad_synth.h" # include "mad_decoder.h" /* * NAME: decoder->init() * DESCRIPTION: initialize a decoder object with callback routines */ void mad_decoder_init(struct mad_decoder *decoder, void *data, enum mad_flow (*input_func)(void *, struct mad_stream *), enum mad_flow (*header_func)(void *, struct mad_header const *), enum mad_flow (*filter_func)(void *, struct mad_stream const *, struct mad_frame *), enum mad_flow (*output_func)(void *, struct mad_header const *, struct mad_pcm *), enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *), enum mad_flow (*message_func)(void *, void *, unsigned int *)) { decoder->mode = -1; decoder->options = 0; decoder->async.pid = 0; decoder->async.in = -1; decoder->async.out = -1; decoder->sync = 0; decoder->cb_data = data; decoder->input_func = input_func; decoder->header_func = header_func; decoder->filter_func = filter_func; decoder->output_func = output_func; decoder->error_func = error_func; decoder->message_func = message_func; } int mad_decoder_finish(struct mad_decoder *decoder) { # if defined(USE_ASYNC) if (decoder->mode == MAD_DECODER_MODE_ASYNC && decoder->async.pid) { pid_t pid; int status; close(decoder->async.in); do pid = waitpid(decoder->async.pid, &status, 0); while (pid == -1 && errno == EINTR); decoder->mode = -1; close(decoder->async.out); decoder->async.pid = 0; decoder->async.in = -1; decoder->async.out = -1; if (pid == -1) return -1; return (!WIFEXITED(status) || WEXITSTATUS(status)) ? -1 : 0; } # else (void) decoder; # endif return 0; } # if defined(USE_ASYNC) static enum mad_flow send_io(int fd, void const *data, size_t len) { char const *ptr = data; ssize_t count; while (len) { do count = write(fd, ptr, len); while (count == -1 && errno == EINTR); if (count == -1) return MAD_FLOW_BREAK; len -= count; ptr += count; } return MAD_FLOW_CONTINUE; } static enum mad_flow receive_io(int fd, void *buffer, size_t len) { char *ptr = buffer; ssize_t count; while (len) { do count = read(fd, ptr, len); while (count == -1 && errno == EINTR); if (count == -1) return (errno == EAGAIN) ? MAD_FLOW_IGNORE : MAD_FLOW_BREAK; else if (count == 0) return MAD_FLOW_STOP; len -= count; ptr += count; } return MAD_FLOW_CONTINUE; } static enum mad_flow receive_io_blocking(int fd, void *buffer, size_t len) { int flags, blocking; enum mad_flow result; flags = fcntl(fd, F_GETFL); if (flags == -1) return MAD_FLOW_BREAK; blocking = flags & ~O_NONBLOCK; if (blocking != flags && fcntl(fd, F_SETFL, blocking) == -1) return MAD_FLOW_BREAK; result = receive_io(fd, buffer, len); if (flags != blocking && fcntl(fd, F_SETFL, flags) == -1) return MAD_FLOW_BREAK; return result; } static enum mad_flow send(int fd, void const *message, unsigned int size) { enum mad_flow result; /* send size */ result = send_io(fd, &size, sizeof(size)); /* send message */ if (result == MAD_FLOW_CONTINUE) result = send_io(fd, message, size); return result; } static enum mad_flow receive(int fd, void **message, unsigned int *size) { enum mad_flow result; unsigned int actual; if (*message == 0) *size = 0; /* receive size */ result = receive_io(fd, &actual, sizeof(actual)); /* receive message */ if (result == MAD_FLOW_CONTINUE) { if (actual > *size) actual -= *size; else { *size = actual; actual = 0; } if (*size > 0) { if (*message == 0) { *message = malloc(*size); if (*message == 0) return MAD_FLOW_BREAK; } result = receive_io_blocking(fd, *message, *size); } /* throw away remainder of message */ while (actual && result == MAD_FLOW_CONTINUE) { char sink[256]; unsigned int len; len = actual > sizeof(sink) ? sizeof(sink) : actual; result = receive_io_blocking(fd, sink, len); actual -= len; } } return result; } static enum mad_flow check_message(struct mad_decoder *decoder) { enum mad_flow result; void *message = 0; unsigned int size; result = receive(decoder->async.in, &message, &size); if (result == MAD_FLOW_CONTINUE) { if (decoder->message_func == 0) size = 0; else { result = decoder->message_func(decoder->cb_data, message, &size); if (result == MAD_FLOW_IGNORE || result == MAD_FLOW_BREAK) size = 0; } if (send(decoder->async.out, message, size) != MAD_FLOW_CONTINUE) result = MAD_FLOW_BREAK; } if (message) free(message); return result; } # endif static enum mad_flow error_default(void *data, struct mad_stream *stream, struct mad_frame *frame) { int *bad_last_frame = data; switch (stream->error) { case MAD_ERROR_BADCRC: if (*bad_last_frame) mad_frame_mute(frame); else *bad_last_frame = 1; return MAD_FLOW_IGNORE; default: return MAD_FLOW_CONTINUE; } } static int run_sync(struct mad_decoder *decoder) { enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *); void *error_data; int bad_last_frame = 0; struct mad_stream *stream; struct mad_frame *frame; struct mad_synth *synth; int result = 0; if (decoder->input_func == 0) return 0; if (decoder->error_func) { error_func = decoder->error_func; error_data = decoder->cb_data; } else { error_func = error_default; error_data = &bad_last_frame; } stream = &decoder->sync->stream; frame = &decoder->sync->frame; synth = &decoder->sync->synth; mad_stream_init(stream); mad_frame_init(frame); mad_synth_init(synth); mad_stream_options(stream, decoder->options); do { switch (decoder->input_func(decoder->cb_data, stream)) { case MAD_FLOW_STOP: goto done; case MAD_FLOW_BREAK: goto fail; case MAD_FLOW_IGNORE: continue; case MAD_FLOW_CONTINUE: break; } while (1) { # if defined(USE_ASYNC) if (decoder->mode == MAD_DECODER_MODE_ASYNC) { switch (check_message(decoder)) { case MAD_FLOW_IGNORE: case MAD_FLOW_CONTINUE: break; case MAD_FLOW_BREAK: goto fail; case MAD_FLOW_STOP: goto done; } } # endif if (decoder->header_func) { if (mad_header_decode(&frame->header, stream) == -1) { if (!MAD_RECOVERABLE(stream->error)) break; switch (error_func(error_data, stream, frame)) { case MAD_FLOW_STOP: goto done; case MAD_FLOW_BREAK: goto fail; case MAD_FLOW_IGNORE: case MAD_FLOW_CONTINUE: default: continue; } } switch (decoder->header_func(decoder->cb_data, &frame->header)) { case MAD_FLOW_STOP: goto done; case MAD_FLOW_BREAK: goto fail; case MAD_FLOW_IGNORE: continue; case MAD_FLOW_CONTINUE: break; } } if (mad_frame_decode(frame, stream) == -1) { if (!MAD_RECOVERABLE(stream->error)) break; switch (error_func(error_data, stream, frame)) { case MAD_FLOW_STOP: goto done; case MAD_FLOW_BREAK: goto fail; case MAD_FLOW_IGNORE: break; case MAD_FLOW_CONTINUE: default: continue; } } else bad_last_frame = 0; if (decoder->filter_func) { switch (decoder->filter_func(decoder->cb_data, stream, frame)) { case MAD_FLOW_STOP: goto done; case MAD_FLOW_BREAK: goto fail; case MAD_FLOW_IGNORE: continue; case MAD_FLOW_CONTINUE: break; } } mad_synth_frame(synth, frame); if (decoder->output_func) { switch (decoder->output_func(decoder->cb_data, &frame->header, &synth->pcm)) { case MAD_FLOW_STOP: goto done; case MAD_FLOW_BREAK: goto fail; case MAD_FLOW_IGNORE: case MAD_FLOW_CONTINUE: break; } } } } while (stream->error == MAD_ERROR_BUFLEN); fail: result = -1; done: mad_synth_finish(synth); mad_frame_finish(frame); mad_stream_finish(stream); return result; } # if defined(USE_ASYNC) static int run_async(struct mad_decoder *decoder) { pid_t pid; int ptoc[2], ctop[2], flags; if (pipe(ptoc) == -1) return -1; if (pipe(ctop) == -1) { close(ptoc[0]); close(ptoc[1]); return -1; } flags = fcntl(ptoc[0], F_GETFL); if (flags == -1 || fcntl(ptoc[0], F_SETFL, flags | O_NONBLOCK) == -1) { close(ctop[0]); close(ctop[1]); close(ptoc[0]); close(ptoc[1]); return -1; } pid = fork(); if (pid == -1) { close(ctop[0]); close(ctop[1]); close(ptoc[0]); close(ptoc[1]); return -1; } decoder->async.pid = pid; if (pid) { /* parent */ close(ptoc[0]); close(ctop[1]); decoder->async.in = ctop[0]; decoder->async.out = ptoc[1]; return 0; } /* child */ close(ptoc[1]); close(ctop[0]); decoder->async.in = ptoc[0]; decoder->async.out = ctop[1]; _exit(run_sync(decoder)); /* not reached */ return -1; } # endif /* * NAME: decoder->run() * DESCRIPTION: run the decoder thread either synchronously or asynchronously */ int mad_decoder_run(struct mad_decoder *decoder, enum mad_decoder_mode mode) { int result; int (*run)(struct mad_decoder *) = 0; switch (decoder->mode = mode) { case MAD_DECODER_MODE_SYNC: run = run_sync; break; case MAD_DECODER_MODE_ASYNC: # if defined(USE_ASYNC) run = run_async; # endif break; } if (run == 0) return -1; decoder->sync = malloc(sizeof(*decoder->sync)); if (decoder->sync == 0) return -1; result = run(decoder); free(decoder->sync); decoder->sync = 0; return result; } /* * NAME: decoder->message() * DESCRIPTION: send a message to and receive a reply from the decoder process */ int mad_decoder_message(struct mad_decoder *decoder, void *message, unsigned int *len) { # if defined(USE_ASYNC) if (decoder->mode != MAD_DECODER_MODE_ASYNC || send(decoder->async.out, message, *len) != MAD_FLOW_CONTINUE || receive(decoder->async.in, &message, len) != MAD_FLOW_CONTINUE) return -1; return 0; # else (void) decoder; (void) message; (void) len; return -1; # endif } praat-6.0.04/external/mp3/mad_decoder.h000066400000000000000000000054501261542461700176440ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: decoder.h,v 1.17 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBMAD_DECODER_H # define LIBMAD_DECODER_H # include "mad_stream.h" # include "mad_frame.h" # include "mad_synth.h" enum mad_decoder_mode { MAD_DECODER_MODE_SYNC = 0, MAD_DECODER_MODE_ASYNC }; enum mad_flow { MAD_FLOW_CONTINUE = 0x0000, /* continue normally */ MAD_FLOW_STOP = 0x0010, /* stop decoding normally */ MAD_FLOW_BREAK = 0x0011, /* stop decoding and signal an error */ MAD_FLOW_IGNORE = 0x0020 /* ignore the current frame */ }; struct mad_decoder { enum mad_decoder_mode mode; int options; struct { long pid; int in; int out; } async; struct { struct mad_stream stream; struct mad_frame frame; struct mad_synth synth; } *sync; void *cb_data; enum mad_flow (*input_func)(void *, struct mad_stream *); enum mad_flow (*header_func)(void *, struct mad_header const *); enum mad_flow (*filter_func)(void *, struct mad_stream const *, struct mad_frame *); enum mad_flow (*output_func)(void *, struct mad_header const *, struct mad_pcm *); enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *); enum mad_flow (*message_func)(void *, void *, unsigned int *); }; void mad_decoder_init(struct mad_decoder *, void *, enum mad_flow (*)(void *, struct mad_stream *), enum mad_flow (*)(void *, struct mad_header const *), enum mad_flow (*)(void *, struct mad_stream const *, struct mad_frame *), enum mad_flow (*)(void *, struct mad_header const *, struct mad_pcm *), enum mad_flow (*)(void *, struct mad_stream *, struct mad_frame *), enum mad_flow (*)(void *, void *, unsigned int *)); int mad_decoder_finish(struct mad_decoder *); # define mad_decoder_options(decoder, opts) \ ((void) ((decoder)->options = (opts))) int mad_decoder_run(struct mad_decoder *, enum mad_decoder_mode); int mad_decoder_message(struct mad_decoder *, void *, unsigned int *); # endif praat-6.0.04/external/mp3/mad_fixed.c000066400000000000000000000034271261542461700173330ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: fixed.c,v 1.13 2004/01/23 09:41:32 rob Exp $ */ /*# ifdef HAVE_CONFIG_H*/ # include "mad_config.h" /*# endif*/ # include "mad_global.h" # include "mad_fixed.h" /* * NAME: fixed->abs() * DESCRIPTION: return absolute value of a fixed-point number */ mad_fixed_t mad_f_abs(mad_fixed_t x) { return x < 0 ? -x : x; } /* * NAME: fixed->div() * DESCRIPTION: perform division using fixed-point math */ mad_fixed_t mad_f_div(mad_fixed_t x, mad_fixed_t y) { mad_fixed_t q, r; unsigned int bits; q = mad_f_abs(x / y); if (x < 0) { x = -x; y = -y; } r = x % y; if (y < 0) { x = -x; y = -y; } if (q > mad_f_intpart(MAD_F_MAX) && !(q == -mad_f_intpart(MAD_F_MIN) && r == 0 && (x < 0) != (y < 0))) return 0; for (bits = MAD_F_FRACBITS; bits && r; --bits) { q <<= 1, r <<= 1; if (r >= y) r -= y, ++q; } /* round */ if (2 * r >= y) ++q; /* fix sign */ if ((x < 0) != (y < 0)) q = -q; return q << bits; } praat-6.0.04/external/mp3/mad_fixed.h000066400000000000000000000323701261542461700173370ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: fixed.h,v 1.38 2004/02/17 02:02:03 rob Exp $ */ # ifndef LIBMAD_FIXED_H # define LIBMAD_FIXED_H # if SIZEOF_INT >= 4 typedef signed int mad_fixed_t; typedef signed int mad_fixed64hi_t; typedef unsigned int mad_fixed64lo_t; # else typedef signed long mad_fixed_t; typedef signed long mad_fixed64hi_t; typedef unsigned long mad_fixed64lo_t; # endif # if defined(_MSC_VER) # define mad_fixed64_t signed __int64 # elif 1 || defined(__GNUC__) # define mad_fixed64_t signed long long # endif # if defined(FPM_FLOAT) typedef double mad_sample_t; # else typedef mad_fixed_t mad_sample_t; # endif /* * Fixed-point format: 0xABBBBBBB * A == whole part (sign + 3 bits) * B == fractional part (28 bits) * * Values are signed two's complement, so the effective range is: * 0x80000000 to 0x7fffffff * -8.0 to +7.9999999962747097015380859375 * * The smallest representable value is: * 0x00000001 == 0.0000000037252902984619140625 (i.e. about 3.725e-9) * * 28 bits of fractional accuracy represent about * 8.6 digits of decimal accuracy. * * Fixed-point numbers can be added or subtracted as normal * integers, but multiplication requires shifting the 64-bit result * from 56 fractional bits back to 28 (and rounding.) * * Changing the definition of MAD_F_FRACBITS is only partially * supported, and must be done with care. */ # define MAD_F_FRACBITS 28 # if MAD_F_FRACBITS == 28 # define MAD_F(x) ((mad_fixed_t) (x##L)) # else # if MAD_F_FRACBITS < 28 # warning "MAD_F_FRACBITS < 28" # define MAD_F(x) ((mad_fixed_t) \ (((x##L) + \ (1L << (28 - MAD_F_FRACBITS - 1))) >> \ (28 - MAD_F_FRACBITS))) # elif MAD_F_FRACBITS > 28 # error "MAD_F_FRACBITS > 28 not currently supported" # define MAD_F(x) ((mad_fixed_t) \ ((x##L) << (MAD_F_FRACBITS - 28))) # endif # endif # define MAD_F_MIN ((mad_fixed_t) -0x80000000L) # define MAD_F_MAX ((mad_fixed_t) +0x7fffffffL) # define MAD_F_ONE MAD_F(0x10000000) # define mad_f_tofixed(x) ((mad_fixed_t) \ ((x) * (double) (1L << MAD_F_FRACBITS) + 0.5)) # define mad_f_todouble(x) ((double) \ ((x) / (double) (1L << MAD_F_FRACBITS))) # define mad_f_intpart(x) ((x) >> MAD_F_FRACBITS) # define mad_f_fracpart(x) ((x) & ((1L << MAD_F_FRACBITS) - 1)) /* (x should be positive) */ # define mad_f_fromint(x) ((x) << MAD_F_FRACBITS) # define mad_f_add(x, y) ((x) + (y)) # define mad_f_sub(x, y) ((x) - (y)) # if defined(FPM_FLOAT) # error "FPM_FLOAT not yet supported" # undef MAD_F # define MAD_F(x) mad_f_todouble(x) # define mad_f_mul(x, y) ((x) * (y)) # define mad_f_scale64 # undef ASO_ZEROCHECK # elif defined(FPM_64BIT) /* * This version should be the most accurate if 64-bit types are supported by * the compiler, although it may not be the most efficient. */ # if defined(OPT_ACCURACY) # define mad_f_mul(x, y) \ ((mad_fixed_t) \ ((((mad_fixed64_t) (x) * (y)) + \ (1L << (MAD_F_SCALEBITS - 1))) >> MAD_F_SCALEBITS)) # else # define mad_f_mul(x, y) \ ((mad_fixed_t) (((mad_fixed64_t) (x) * (y)) >> MAD_F_SCALEBITS)) # endif # define MAD_F_SCALEBITS MAD_F_FRACBITS /* --- Intel --------------------------------------------------------------- */ # elif defined(FPM_INTEL) # if defined(_MSC_VER) # pragma warning(push) # pragma warning(disable: 4035) /* no return value */ static __forceinline mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) { enum { fracbits = MAD_F_FRACBITS }; __asm { mov eax, x imul y shrd eax, edx, fracbits } /* implicit return of eax */ } # pragma warning(pop) # define mad_f_mul mad_f_mul_inline # define mad_f_scale64 # else /* * This Intel version is fast and accurate; the disposition of the least * significant bit depends on OPT_ACCURACY via mad_f_scale64(). */ # define MAD_F_MLX(hi, lo, x, y) \ asm ("imull %3" \ : "=a" (lo), "=d" (hi) \ : "%a" (x), "rm" (y) \ : "cc") # if defined(OPT_ACCURACY) /* * This gives best accuracy but is not very fast. */ # define MAD_F_MLA(hi, lo, x, y) \ ({ mad_fixed64hi_t __hi; \ mad_fixed64lo_t __lo; \ MAD_F_MLX(__hi, __lo, (x), (y)); \ asm ("addl %2,%0\n\t" \ "adcl %3,%1" \ : "=rm" (lo), "=rm" (hi) \ : "r" (__lo), "r" (__hi), "0" (lo), "1" (hi) \ : "cc"); \ }) # endif /* OPT_ACCURACY */ # if defined(OPT_ACCURACY) /* * Surprisingly, this is faster than SHRD followed by ADC. */ # define mad_f_scale64(hi, lo) \ ({ mad_fixed64hi_t __hi_; \ mad_fixed64lo_t __lo_; \ mad_fixed_t __result; \ asm ("addl %4,%2\n\t" \ "adcl %5,%3" \ : "=rm" (__lo_), "=rm" (__hi_) \ : "0" (lo), "1" (hi), \ "ir" (1L << (MAD_F_SCALEBITS - 1)), "ir" (0) \ : "cc"); \ asm ("shrdl %3,%2,%1" \ : "=rm" (__result) \ : "0" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS) \ : "cc"); \ __result; \ }) # elif defined(OPT_INTEL) /* * Alternate Intel scaling that may or may not perform better. */ # define mad_f_scale64(hi, lo) \ ({ mad_fixed_t __result; \ asm ("shrl %3,%1\n\t" \ "shll %4,%2\n\t" \ "orl %2,%1" \ : "=rm" (__result) \ : "0" (lo), "r" (hi), \ "I" (MAD_F_SCALEBITS), "I" (32 - MAD_F_SCALEBITS) \ : "cc"); \ __result; \ }) # else # define mad_f_scale64(hi, lo) \ ({ mad_fixed_t __result; \ asm ("shrdl %3,%2,%1" \ : "=rm" (__result) \ : "0" (lo), "r" (hi), "I" (MAD_F_SCALEBITS) \ : "cc"); \ __result; \ }) # endif /* OPT_ACCURACY */ # define MAD_F_SCALEBITS MAD_F_FRACBITS # endif /* --- ARM ----------------------------------------------------------------- */ # elif defined(FPM_ARM) /* * This ARM V4 version is as accurate as FPM_64BIT but much faster. The * least significant bit is properly rounded at no CPU cycle cost! */ # if 1 /* * This is faster than the default implementation via MAD_F_MLX() and * mad_f_scale64(). */ # define mad_f_mul(x, y) \ ({ mad_fixed64hi_t __hi; \ mad_fixed64lo_t __lo; \ mad_fixed_t __result; \ asm ("smull %0, %1, %3, %4\n\t" \ "movs %0, %0, lsr %5\n\t" \ "adc %2, %0, %1, lsl %6" \ : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \ : "%r" (x), "r" (y), \ "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \ : "cc"); \ __result; \ }) # endif # define MAD_F_MLX(hi, lo, x, y) \ asm ("smull %0, %1, %2, %3" \ : "=&r" (lo), "=&r" (hi) \ : "%r" (x), "r" (y)) # define MAD_F_MLA(hi, lo, x, y) \ asm ("smlal %0, %1, %2, %3" \ : "+r" (lo), "+r" (hi) \ : "%r" (x), "r" (y)) # define MAD_F_MLN(hi, lo) \ asm ("rsbs %0, %2, #0\n\t" \ "rsc %1, %3, #0" \ : "=r" (lo), "=r" (hi) \ : "0" (lo), "1" (hi) \ : "cc") # define mad_f_scale64(hi, lo) \ ({ mad_fixed_t __result; \ asm ("movs %0, %1, lsr %3\n\t" \ "adc %0, %0, %2, lsl %4" \ : "=&r" (__result) \ : "r" (lo), "r" (hi), \ "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \ : "cc"); \ __result; \ }) # define MAD_F_SCALEBITS MAD_F_FRACBITS /* --- MIPS ---------------------------------------------------------------- */ # elif defined(FPM_MIPS) /* * This MIPS version is fast and accurate; the disposition of the least * significant bit depends on OPT_ACCURACY via mad_f_scale64(). */ # define MAD_F_MLX(hi, lo, x, y) \ asm ("mult %2,%3" \ : "=l" (lo), "=h" (hi) \ : "%r" (x), "r" (y)) # if defined(HAVE_MADD_ASM) # define MAD_F_MLA(hi, lo, x, y) \ asm ("madd %2,%3" \ : "+l" (lo), "+h" (hi) \ : "%r" (x), "r" (y)) # elif defined(HAVE_MADD16_ASM) /* * This loses significant accuracy due to the 16-bit integer limit in the * multiply/accumulate instruction. */ # define MAD_F_ML0(hi, lo, x, y) \ asm ("mult %2,%3" \ : "=l" (lo), "=h" (hi) \ : "%r" ((x) >> 12), "r" ((y) >> 16)) # define MAD_F_MLA(hi, lo, x, y) \ asm ("madd16 %2,%3" \ : "+l" (lo), "+h" (hi) \ : "%r" ((x) >> 12), "r" ((y) >> 16)) # define MAD_F_MLZ(hi, lo) ((mad_fixed_t) (lo)) # endif # if defined(OPT_SPEED) # define mad_f_scale64(hi, lo) \ ((mad_fixed_t) ((hi) << (32 - MAD_F_SCALEBITS))) # define MAD_F_SCALEBITS MAD_F_FRACBITS # endif /* --- SPARC --------------------------------------------------------------- */ # elif defined(FPM_SPARC) /* * This SPARC V8 version is fast and accurate; the disposition of the least * significant bit depends on OPT_ACCURACY via mad_f_scale64(). */ # define MAD_F_MLX(hi, lo, x, y) \ asm ("smul %2, %3, %0\n\t" \ "rd %%y, %1" \ : "=r" (lo), "=r" (hi) \ : "%r" (x), "rI" (y)) /* --- PowerPC ------------------------------------------------------------- */ # elif defined(FPM_PPC) /* * This PowerPC version is fast and accurate; the disposition of the least * significant bit depends on OPT_ACCURACY via mad_f_scale64(). */ # define MAD_F_MLX(hi, lo, x, y) \ do { \ asm ("mullw %0,%1,%2" \ : "=r" (lo) \ : "%r" (x), "r" (y)); \ asm ("mulhw %0,%1,%2" \ : "=r" (hi) \ : "%r" (x), "r" (y)); \ } \ while (0) # if defined(OPT_ACCURACY) /* * This gives best accuracy but is not very fast. */ # define MAD_F_MLA(hi, lo, x, y) \ ({ mad_fixed64hi_t __hi; \ mad_fixed64lo_t __lo; \ MAD_F_MLX(__hi, __lo, (x), (y)); \ asm ("addc %0,%2,%3\n\t" \ "adde %1,%4,%5" \ : "=r" (lo), "=r" (hi) \ : "%r" (lo), "r" (__lo), \ "%r" (hi), "r" (__hi) \ : "xer"); \ }) # endif # if defined(OPT_ACCURACY) /* * This is slower than the truncating version below it. */ # define mad_f_scale64(hi, lo) \ ({ mad_fixed_t __result, __round; \ asm ("rotrwi %0,%1,%2" \ : "=r" (__result) \ : "r" (lo), "i" (MAD_F_SCALEBITS)); \ asm ("extrwi %0,%1,1,0" \ : "=r" (__round) \ : "r" (__result)); \ asm ("insrwi %0,%1,%2,0" \ : "+r" (__result) \ : "r" (hi), "i" (MAD_F_SCALEBITS)); \ asm ("add %0,%1,%2" \ : "=r" (__result) \ : "%r" (__result), "r" (__round)); \ __result; \ }) # else # define mad_f_scale64(hi, lo) \ ({ mad_fixed_t __result; \ asm ("rotrwi %0,%1,%2" \ : "=r" (__result) \ : "r" (lo), "i" (MAD_F_SCALEBITS)); \ asm ("insrwi %0,%1,%2,0" \ : "+r" (__result) \ : "r" (hi), "i" (MAD_F_SCALEBITS)); \ __result; \ }) # endif # define MAD_F_SCALEBITS MAD_F_FRACBITS /* --- Default ------------------------------------------------------------- */ # elif defined(FPM_DEFAULT) /* * This version is the most portable but it loses significant accuracy. * Furthermore, accuracy is biased against the second argument, so care * should be taken when ordering operands. * * The scale factors are constant as this is not used with SSO. * * Pre-rounding is required to stay within the limits of compliance. */ # if defined(OPT_SPEED) # define mad_f_mul(x, y) (((x) >> 12) * ((y) >> 16)) # else # define mad_f_mul(x, y) ((((x) + (1L << 11)) >> 12) * \ (((y) + (1L << 15)) >> 16)) # endif /* ------------------------------------------------------------------------- */ # else # error "no FPM selected" # endif /* default implementations */ # if !defined(mad_f_mul) # define mad_f_mul(x, y) \ ({ register mad_fixed64hi_t __hi; \ register mad_fixed64lo_t __lo; \ MAD_F_MLX(__hi, __lo, (x), (y)); \ mad_f_scale64(__hi, __lo); \ }) # endif # if !defined(MAD_F_MLA) # define MAD_F_ML0(hi, lo, x, y) ((lo) = mad_f_mul((x), (y))) # define MAD_F_MLA(hi, lo, x, y) ((lo) += mad_f_mul((x), (y))) # define MAD_F_MLN(hi, lo) ((lo) = -(lo)) # define MAD_F_MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo)) # endif # if !defined(MAD_F_ML0) # define MAD_F_ML0(hi, lo, x, y) MAD_F_MLX((hi), (lo), (x), (y)) # endif # if !defined(MAD_F_MLN) # define MAD_F_MLN(hi, lo) ((hi) = ((lo) = -(lo)) ? ~(hi) : -(hi)) # endif # if !defined(MAD_F_MLZ) # define MAD_F_MLZ(hi, lo) mad_f_scale64((hi), (lo)) # endif # if !defined(mad_f_scale64) # if defined(OPT_ACCURACY) # define mad_f_scale64(hi, lo) \ ((((mad_fixed_t) \ (((hi) << (32 - (MAD_F_SCALEBITS - 1))) | \ ((lo) >> (MAD_F_SCALEBITS - 1)))) + 1) >> 1) # else # define mad_f_scale64(hi, lo) \ ((mad_fixed_t) \ (((hi) << (32 - MAD_F_SCALEBITS)) | \ ((lo) >> MAD_F_SCALEBITS))) # endif # define MAD_F_SCALEBITS MAD_F_FRACBITS # endif /* C routines */ mad_fixed_t mad_f_abs(mad_fixed_t); mad_fixed_t mad_f_div(mad_fixed_t, mad_fixed_t); # endif praat-6.0.04/external/mp3/mad_frame.c000066400000000000000000000300461261542461700173230ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: frame.c,v 1.29 2004/02/04 22:59:19 rob Exp $ */ /*# ifdef HAVE_CONFIG_H*/ # include "mad_config.h" /*# endif*/ # include "mad_global.h" # include # include "mad_bit.h" # include "mad_stream.h" # include "mad_frame.h" # include "mad_timer.h" # include "mad_layer12.h" # include "mad_layer3.h" static unsigned long const bitrate_table[5][15] = { /* MPEG-1 */ { 0, 32000, 64000, 96000, 128000, 160000, 192000, 224000, /* Layer I */ 256000, 288000, 320000, 352000, 384000, 416000, 448000 }, { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer II */ 128000, 160000, 192000, 224000, 256000, 320000, 384000 }, { 0, 32000, 40000, 48000, 56000, 64000, 80000, 96000, /* Layer III */ 112000, 128000, 160000, 192000, 224000, 256000, 320000 }, /* MPEG-2 LSF */ { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer I */ 128000, 144000, 160000, 176000, 192000, 224000, 256000 }, { 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000, /* Layers */ 64000, 80000, 96000, 112000, 128000, 144000, 160000 } /* II & III */ }; static unsigned int const samplerate_table[3] = { 44100, 48000, 32000 }; static int (*const decoder_table[3])(struct mad_stream *, struct mad_frame *) = { mad_layer_I, mad_layer_II, mad_layer_III }; /* * NAME: header->init() * DESCRIPTION: initialize header struct */ void mad_header_init(struct mad_header *header) { header->layer = 0; header->mode = 0; header->mode_extension = 0; header->emphasis = 0; header->bitrate = 0; header->samplerate = 0; header->crc_check = 0; header->crc_target = 0; header->flags = 0; header->private_bits = 0; header->duration = mad_timer_zero; } /* * NAME: frame->init() * DESCRIPTION: initialize frame struct */ void mad_frame_init(struct mad_frame *frame) { mad_header_init(&frame->header); frame->options = 0; frame->overlap = 0; mad_frame_mute(frame); } /* * NAME: frame->finish() * DESCRIPTION: deallocate any dynamic memory associated with frame */ void mad_frame_finish(struct mad_frame *frame) { mad_header_finish(&frame->header); if (frame->overlap) { free(frame->overlap); frame->overlap = 0; } } /* * NAME: decode_header() * DESCRIPTION: read header data and following CRC word */ static int decode_header(struct mad_header *header, struct mad_stream *stream) { unsigned int index; header->offset = stream->this_offset; header->flags = 0; header->private_bits = 0; /* header() */ /* syncword */ mad_bit_skip(&stream->ptr, 11); /* MPEG 2.5 indicator (really part of syncword) */ if (mad_bit_read(&stream->ptr, 1) == 0) header->flags |= MAD_FLAG_MPEG_2_5_EXT; /* ID */ if (mad_bit_read(&stream->ptr, 1) == 0) header->flags |= MAD_FLAG_LSF_EXT; else if (header->flags & MAD_FLAG_MPEG_2_5_EXT) { stream->error = MAD_ERROR_LOSTSYNC; return -1; } /* layer */ header->layer = 4 - mad_bit_read(&stream->ptr, 2); if (header->layer == 4) { stream->error = MAD_ERROR_BADLAYER; return -1; } /* protection_bit */ if (mad_bit_read(&stream->ptr, 1) == 0) { header->flags |= MAD_FLAG_PROTECTION; header->crc_check = mad_bit_crc(stream->ptr, 16, 0xffff); } /* bitrate_index */ index = mad_bit_read(&stream->ptr, 4); if (index == 15) { stream->error = MAD_ERROR_BADBITRATE; return -1; } if (header->flags & MAD_FLAG_LSF_EXT) header->bitrate = bitrate_table[3 + (header->layer >> 1)][index]; else header->bitrate = bitrate_table[header->layer - 1][index]; /* sampling_frequency */ index = mad_bit_read(&stream->ptr, 2); if (index == 3) { stream->error = MAD_ERROR_BADSAMPLERATE; return -1; } header->samplerate = samplerate_table[index]; if (header->flags & MAD_FLAG_LSF_EXT) { header->samplerate /= 2; if (header->flags & MAD_FLAG_MPEG_2_5_EXT) header->samplerate /= 2; } /* padding_bit */ if (mad_bit_read(&stream->ptr, 1)) header->flags |= MAD_FLAG_PADDING; /* private_bit */ if (mad_bit_read(&stream->ptr, 1)) header->private_bits |= MAD_PRIVATE_HEADER; /* mode */ header->mode = 3 - mad_bit_read(&stream->ptr, 2); /* mode_extension */ header->mode_extension = mad_bit_read(&stream->ptr, 2); /* copyright */ if (mad_bit_read(&stream->ptr, 1)) header->flags |= MAD_FLAG_COPYRIGHT; /* original/copy */ if (mad_bit_read(&stream->ptr, 1)) header->flags |= MAD_FLAG_ORIGINAL; /* emphasis */ header->emphasis = mad_bit_read(&stream->ptr, 2); # if defined(OPT_STRICT) /* * ISO/IEC 11172-3 says this is a reserved emphasis value, but * streams exist which use it anyway. Since the value is not important * to the decoder proper, we allow it unless OPT_STRICT is defined. */ if (header->emphasis == MAD_EMPHASIS_RESERVED) { stream->error = MAD_ERROR_BADEMPHASIS; return -1; } # endif /* error_check() */ /* crc_check */ if (header->flags & MAD_FLAG_PROTECTION) header->crc_target = mad_bit_read(&stream->ptr, 16); return 0; } /* * NAME: free_bitrate() * DESCRIPTION: attempt to discover the bitstream's free bitrate */ static int free_bitrate(struct mad_stream *stream, struct mad_header const *header) { struct mad_bitptr keep_ptr; unsigned long rate = 0; unsigned int pad_slot, slots_per_frame; unsigned char const *ptr = 0; keep_ptr = stream->ptr; pad_slot = (header->flags & MAD_FLAG_PADDING) ? 1 : 0; slots_per_frame = (header->layer == MAD_LAYER_III && (header->flags & MAD_FLAG_LSF_EXT)) ? 72 : 144; while (mad_stream_sync(stream) == 0) { struct mad_stream peek_stream; struct mad_header peek_header; peek_stream = *stream; peek_header = *header; if (decode_header(&peek_header, &peek_stream) == 0 && peek_header.layer == header->layer && peek_header.samplerate == header->samplerate) { unsigned int N; ptr = mad_bit_nextbyte(&stream->ptr); N = ptr - stream->this_frame; if (header->layer == MAD_LAYER_I) { rate = (unsigned long) header->samplerate * (N - 4 * pad_slot + 4) / 48 / 1000; } else { rate = (unsigned long) header->samplerate * (N - pad_slot + 1) / slots_per_frame / 1000; } if (rate >= 8) break; } mad_bit_skip(&stream->ptr, 8); } stream->ptr = keep_ptr; if (rate < 8 || (header->layer == MAD_LAYER_III && rate > 640)) { stream->error = MAD_ERROR_LOSTSYNC; return -1; } stream->freerate = rate * 1000; return 0; } /* * NAME: header->decode() * DESCRIPTION: read the next frame header from the stream */ int mad_header_decode(struct mad_header *header, struct mad_stream *stream) { register unsigned char const *ptr, *end; unsigned int pad_slot, N; ptr = stream->next_frame; end = stream->bufend; if (ptr == 0) { stream->error = MAD_ERROR_BUFPTR; goto fail; } /* stream skip */ if (stream->skiplen) { if (!stream->sync) ptr = stream->this_frame; if (end - ptr < stream->skiplen) { stream->skiplen -= end - ptr; stream->next_frame = end; stream->error = MAD_ERROR_BUFLEN; goto fail; } ptr += stream->skiplen; stream->skiplen = 0; stream->sync = 1; } sync: /* synchronize */ if (stream->sync) { if (end - ptr < MAD_BUFFER_GUARD) { stream->next_frame = ptr; stream->error = MAD_ERROR_BUFLEN; goto fail; } else if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) { /* mark point where frame sync word was expected */ stream->this_offset += (ptr - stream->this_frame); /* Erez Volk */ stream->this_frame = ptr; stream->next_frame = ptr + 1; stream->error = MAD_ERROR_LOSTSYNC; goto fail; } } else { mad_bit_init(&stream->ptr, ptr); if (mad_stream_sync(stream) == -1) { if (end - stream->next_frame >= MAD_BUFFER_GUARD) stream->next_frame = end - MAD_BUFFER_GUARD; stream->error = MAD_ERROR_BUFLEN; goto fail; } ptr = mad_bit_nextbyte(&stream->ptr); } /* begin processing */ stream->this_offset += (ptr - stream->this_frame); /* Erez Volk */ stream->this_frame = ptr; stream->next_frame = ptr + 1; /* possibly bogus sync word */ mad_bit_init(&stream->ptr, stream->this_frame); if (decode_header(header, stream) == -1) goto fail; /* calculate frame duration */ mad_timer_set(&header->duration, 0, 32 * MAD_NSBSAMPLES(header), header->samplerate); /* calculate free bit rate */ if (header->bitrate == 0) { if ((stream->freerate == 0 || !stream->sync || (header->layer == MAD_LAYER_III && stream->freerate > 640000)) && free_bitrate(stream, header) == -1) goto fail; header->bitrate = stream->freerate; header->flags |= MAD_FLAG_FREEFORMAT; } /* calculate beginning of next frame */ pad_slot = (header->flags & MAD_FLAG_PADDING) ? 1 : 0; if (header->layer == MAD_LAYER_I) N = ((12 * header->bitrate / header->samplerate) + pad_slot) * 4; else { unsigned int slots_per_frame; slots_per_frame = (header->layer == MAD_LAYER_III && (header->flags & MAD_FLAG_LSF_EXT)) ? 72 : 144; N = (slots_per_frame * header->bitrate / header->samplerate) + pad_slot; } /* verify there is enough data left in buffer to decode this frame */ if (N + MAD_BUFFER_GUARD > end - stream->this_frame) { stream->next_frame = stream->this_frame; stream->error = MAD_ERROR_BUFLEN; goto fail; } stream->next_frame = stream->this_frame + N; if (!stream->sync) { /* check that a valid frame header follows this frame */ ptr = stream->next_frame; if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) { ptr = stream->next_frame = stream->this_frame + 1; goto sync; } stream->sync = 1; } header->flags |= MAD_FLAG_INCOMPLETE; return 0; fail: stream->sync = 0; return -1; } /* * NAME: frame->decode() * DESCRIPTION: decode a single frame from a bitstream */ int mad_frame_decode(struct mad_frame *frame, struct mad_stream *stream) { frame->options = stream->options; /* header() */ /* error_check() */ if (!(frame->header.flags & MAD_FLAG_INCOMPLETE) && mad_header_decode(&frame->header, stream) == -1) goto fail; /* audio_data() */ frame->header.flags &= ~MAD_FLAG_INCOMPLETE; if (decoder_table[frame->header.layer - 1](stream, frame) == -1) { if (!MAD_RECOVERABLE(stream->error)) stream->next_frame = stream->this_frame; goto fail; } /* ancillary_data() */ if (frame->header.layer != MAD_LAYER_III) { struct mad_bitptr next_frame; mad_bit_init(&next_frame, stream->next_frame); stream->anc_ptr = stream->ptr; stream->anc_bitlen = mad_bit_length(&stream->ptr, &next_frame); mad_bit_finish(&next_frame); } return 0; fail: stream->anc_bitlen = 0; return -1; } /* * NAME: frame->mute() * DESCRIPTION: zero all subband values so the frame becomes silent */ void mad_frame_mute(struct mad_frame *frame) { unsigned int s, sb; for (s = 0; s < 36; ++s) { for (sb = 0; sb < 32; ++sb) { frame->sbsample[0][s][sb] = frame->sbsample[1][s][sb] = 0; } } if (frame->overlap) { for (s = 0; s < 18; ++s) { for (sb = 0; sb < 32; ++sb) { (*frame->overlap)[0][sb][s] = (*frame->overlap)[1][sb][s] = 0; } } } } praat-6.0.04/external/mp3/mad_frame.h000066400000000000000000000101061261542461700173230ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: frame.h,v 1.20 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBMAD_FRAME_H # define LIBMAD_FRAME_H # include "mad_fixed.h" # include "mad_timer.h" # include "mad_stream.h" enum mad_layer { MAD_LAYER_I = 1, /* Layer I */ MAD_LAYER_II = 2, /* Layer II */ MAD_LAYER_III = 3 /* Layer III */ }; enum mad_mode { MAD_MODE_SINGLE_CHANNEL = 0, /* single channel */ MAD_MODE_DUAL_CHANNEL = 1, /* dual channel */ MAD_MODE_JOINT_STEREO = 2, /* joint (MS/intensity) stereo */ MAD_MODE_STEREO = 3 /* normal LR stereo */ }; enum mad_emphasis { MAD_EMPHASIS_NONE = 0, /* no emphasis */ MAD_EMPHASIS_50_15_US = 1, /* 50/15 microseconds emphasis */ MAD_EMPHASIS_CCITT_J_17 = 3, /* CCITT J.17 emphasis */ MAD_EMPHASIS_RESERVED = 2 /* unknown emphasis */ }; struct mad_header { enum mad_layer layer; /* audio layer (1, 2, or 3) */ enum mad_mode mode; /* channel mode (see above) */ int mode_extension; /* additional mode info */ enum mad_emphasis emphasis; /* de-emphasis to use (see above) */ unsigned long bitrate; /* stream bitrate (bps) */ unsigned int samplerate; /* sampling frequency (Hz) */ unsigned short crc_check; /* frame CRC accumulator */ unsigned short crc_target; /* final target CRC checksum */ int flags; /* flags (see below) */ int private_bits; /* private bits (see below) */ mad_timer_t duration; /* audio playing time of frame */ /* Erez Volk 2007-05-30: */ unsigned long offset; /* Offset of frame in stream */ }; struct mad_frame { struct mad_header header; /* MPEG audio header */ int options; /* decoding options (from stream) */ mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */ mad_fixed_t (*overlap)[2][32][18]; /* Layer III block overlap data */ }; # define MAD_NCHANNELS(header) ((header)->mode ? 2 : 1) # define MAD_NSBSAMPLES(header) \ ((header)->layer == MAD_LAYER_I ? 12 : \ (((header)->layer == MAD_LAYER_III && \ ((header)->flags & MAD_FLAG_LSF_EXT)) ? 18 : 36)) enum { MAD_FLAG_NPRIVATE_III = 0x0007, /* number of Layer III private bits */ MAD_FLAG_INCOMPLETE = 0x0008, /* header but not data is decoded */ MAD_FLAG_PROTECTION = 0x0010, /* frame has CRC protection */ MAD_FLAG_COPYRIGHT = 0x0020, /* frame is copyright */ MAD_FLAG_ORIGINAL = 0x0040, /* frame is original (else copy) */ MAD_FLAG_PADDING = 0x0080, /* frame has additional slot */ MAD_FLAG_I_STEREO = 0x0100, /* uses intensity joint stereo */ MAD_FLAG_MS_STEREO = 0x0200, /* uses middle/side joint stereo */ MAD_FLAG_FREEFORMAT = 0x0400, /* uses free format bitrate */ MAD_FLAG_LSF_EXT = 0x1000, /* lower sampling freq. extension */ MAD_FLAG_MC_EXT = 0x2000, /* multichannel audio extension */ MAD_FLAG_MPEG_2_5_EXT = 0x4000 /* MPEG 2.5 (unofficial) extension */ }; enum { MAD_PRIVATE_HEADER = 0x0100, /* header private bit */ MAD_PRIVATE_III = 0x001f /* Layer III private bits (up to 5) */ }; void mad_header_init(struct mad_header *); # define mad_header_finish(header) /* nothing */ int mad_header_decode(struct mad_header *, struct mad_stream *); void mad_frame_init(struct mad_frame *); void mad_frame_finish(struct mad_frame *); int mad_frame_decode(struct mad_frame *, struct mad_stream *); void mad_frame_mute(struct mad_frame *); # endif praat-6.0.04/external/mp3/mad_global.h000066400000000000000000000031561261542461700175000ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: global.h,v 1.11 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBMAD_GLOBAL_H # define LIBMAD_GLOBAL_H /* conditional debugging */ # if defined(DEBUG) && defined(NDEBUG) # error "cannot define both DEBUG and NDEBUG" # endif # if defined(DEBUG) # include # endif /* conditional features */ # if defined(OPT_SPEED) && defined(OPT_ACCURACY) # error "cannot optimize for both speed and accuracy" # endif # if defined(OPT_SPEED) && !defined(OPT_SSO) # define OPT_SSO # endif # if defined(HAVE_UNISTD_H) && defined(HAVE_WAITPID) && \ defined(HAVE_FCNTL) && defined(HAVE_PIPE) && defined(HAVE_FORK) # define USE_ASYNC # endif # if !defined(HAVE_ASSERT_H) # if defined(NDEBUG) # define assert(x) /* nothing */ # else # define assert(x) do { if (!(x)) abort(); } while (0) # endif # endif # endif praat-6.0.04/external/mp3/mad_huffman.c000066400000000000000000002167521261542461700176670ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: huffman.c,v 1.10 2004/01/23 09:41:32 rob Exp $ */ /*# ifdef HAVE_CONFIG_H*/ # include "mad_config.h" /*# endif*/ # include "mad_global.h" # include "mad_huffman.h" /* * These are the Huffman code words for Layer III. * The data for these tables are derived from Table B.7 of ISO/IEC 11172-3. * * These tables support decoding up to 4 Huffman code bits at a time. */ # if defined(__GNUC__) || \ (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901) # define PTR(offs, bits) { .ptr = { 0, bits, offs } } # define V(v, w, x, y, hlen) { .value = { 1, hlen, v, w, x, y } } # else # define PTR(offs, bits) { { 0, bits, offs } } # if defined(WORDS_BIGENDIAN) # define V(v, w, x, y, hlen) { { 1, hlen, (v << 11) | (w << 10) | \ (x << 9) | (y << 8) } } # else # define V(v, w, x, y, hlen) { { 1, hlen, (v << 0) | (w << 1) | \ (x << 2) | (y << 3) } } # endif # endif static union huffquad const hufftabA[] = { /* 0000 */ PTR(16, 2), /* 0001 */ PTR(20, 2), /* 0010 */ PTR(24, 1), /* 0011 */ PTR(26, 1), /* 0100 */ V(0, 0, 1, 0, 4), /* 0101 */ V(0, 0, 0, 1, 4), /* 0110 */ V(0, 1, 0, 0, 4), /* 0111 */ V(1, 0, 0, 0, 4), /* 1000 */ V(0, 0, 0, 0, 1), /* 1001 */ V(0, 0, 0, 0, 1), /* 1010 */ V(0, 0, 0, 0, 1), /* 1011 */ V(0, 0, 0, 0, 1), /* 1100 */ V(0, 0, 0, 0, 1), /* 1101 */ V(0, 0, 0, 0, 1), /* 1110 */ V(0, 0, 0, 0, 1), /* 1111 */ V(0, 0, 0, 0, 1), /* 0000 ... */ /* 00 */ V(1, 0, 1, 1, 2), /* 16 */ /* 01 */ V(1, 1, 1, 1, 2), /* 10 */ V(1, 1, 0, 1, 2), /* 11 */ V(1, 1, 1, 0, 2), /* 0001 ... */ /* 00 */ V(0, 1, 1, 1, 2), /* 20 */ /* 01 */ V(0, 1, 0, 1, 2), /* 10 */ V(1, 0, 0, 1, 1), /* 11 */ V(1, 0, 0, 1, 1), /* 0010 ... */ /* 0 */ V(0, 1, 1, 0, 1), /* 24 */ /* 1 */ V(0, 0, 1, 1, 1), /* 0011 ... */ /* 0 */ V(1, 0, 1, 0, 1), /* 26 */ /* 1 */ V(1, 1, 0, 0, 1) }; static union huffquad const hufftabB[] = { /* 0000 */ V(1, 1, 1, 1, 4), /* 0001 */ V(1, 1, 1, 0, 4), /* 0010 */ V(1, 1, 0, 1, 4), /* 0011 */ V(1, 1, 0, 0, 4), /* 0100 */ V(1, 0, 1, 1, 4), /* 0101 */ V(1, 0, 1, 0, 4), /* 0110 */ V(1, 0, 0, 1, 4), /* 0111 */ V(1, 0, 0, 0, 4), /* 1000 */ V(0, 1, 1, 1, 4), /* 1001 */ V(0, 1, 1, 0, 4), /* 1010 */ V(0, 1, 0, 1, 4), /* 1011 */ V(0, 1, 0, 0, 4), /* 1100 */ V(0, 0, 1, 1, 4), /* 1101 */ V(0, 0, 1, 0, 4), /* 1110 */ V(0, 0, 0, 1, 4), /* 1111 */ V(0, 0, 0, 0, 4) }; # undef V # undef PTR # if defined(__GNUC__) || \ (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901) # define PTR(offs, bits) { .ptr = { 0, bits, offs } } # define V(x, y, hlen) { .value = { 1, hlen, x, y } } # else # define PTR(offs, bits) { { 0, bits, offs } } # if defined(WORDS_BIGENDIAN) # define V(x, y, hlen) { { 1, hlen, (x << 8) | (y << 4) } } # else # define V(x, y, hlen) { { 1, hlen, (x << 0) | (y << 4) } } # endif # endif static union huffpair const hufftab0[] = { /* */ V(0, 0, 0) }; static union huffpair const hufftab1[] = { /* 000 */ V(1, 1, 3), /* 001 */ V(0, 1, 3), /* 010 */ V(1, 0, 2), /* 011 */ V(1, 0, 2), /* 100 */ V(0, 0, 1), /* 101 */ V(0, 0, 1), /* 110 */ V(0, 0, 1), /* 111 */ V(0, 0, 1) }; static union huffpair const hufftab2[] = { /* 000 */ PTR(8, 3), /* 001 */ V(1, 1, 3), /* 010 */ V(0, 1, 3), /* 011 */ V(1, 0, 3), /* 100 */ V(0, 0, 1), /* 101 */ V(0, 0, 1), /* 110 */ V(0, 0, 1), /* 111 */ V(0, 0, 1), /* 000 ... */ /* 000 */ V(2, 2, 3), /* 8 */ /* 001 */ V(0, 2, 3), /* 010 */ V(1, 2, 2), /* 011 */ V(1, 2, 2), /* 100 */ V(2, 1, 2), /* 101 */ V(2, 1, 2), /* 110 */ V(2, 0, 2), /* 111 */ V(2, 0, 2) }; static union huffpair const hufftab3[] = { /* 000 */ PTR(8, 3), /* 001 */ V(1, 0, 3), /* 010 */ V(1, 1, 2), /* 011 */ V(1, 1, 2), /* 100 */ V(0, 1, 2), /* 101 */ V(0, 1, 2), /* 110 */ V(0, 0, 2), /* 111 */ V(0, 0, 2), /* 000 ... */ /* 000 */ V(2, 2, 3), /* 8 */ /* 001 */ V(0, 2, 3), /* 010 */ V(1, 2, 2), /* 011 */ V(1, 2, 2), /* 100 */ V(2, 1, 2), /* 101 */ V(2, 1, 2), /* 110 */ V(2, 0, 2), /* 111 */ V(2, 0, 2) }; static union huffpair const hufftab5[] = { /* 000 */ PTR(8, 4), /* 001 */ V(1, 1, 3), /* 010 */ V(0, 1, 3), /* 011 */ V(1, 0, 3), /* 100 */ V(0, 0, 1), /* 101 */ V(0, 0, 1), /* 110 */ V(0, 0, 1), /* 111 */ V(0, 0, 1), /* 000 ... */ /* 0000 */ PTR(24, 1), /* 8 */ /* 0001 */ V(3, 2, 4), /* 0010 */ V(3, 1, 3), /* 0011 */ V(3, 1, 3), /* 0100 */ V(1, 3, 4), /* 0101 */ V(0, 3, 4), /* 0110 */ V(3, 0, 4), /* 0111 */ V(2, 2, 4), /* 1000 */ V(1, 2, 3), /* 1001 */ V(1, 2, 3), /* 1010 */ V(2, 1, 3), /* 1011 */ V(2, 1, 3), /* 1100 */ V(0, 2, 3), /* 1101 */ V(0, 2, 3), /* 1110 */ V(2, 0, 3), /* 1111 */ V(2, 0, 3), /* 000 0000 ... */ /* 0 */ V(3, 3, 1), /* 24 */ /* 1 */ V(2, 3, 1) }; static union huffpair const hufftab6[] = { /* 0000 */ PTR(16, 3), /* 0001 */ PTR(24, 1), /* 0010 */ PTR(26, 1), /* 0011 */ V(1, 2, 4), /* 0100 */ V(2, 1, 4), /* 0101 */ V(2, 0, 4), /* 0110 */ V(0, 1, 3), /* 0111 */ V(0, 1, 3), /* 1000 */ V(1, 1, 2), /* 1001 */ V(1, 1, 2), /* 1010 */ V(1, 1, 2), /* 1011 */ V(1, 1, 2), /* 1100 */ V(1, 0, 3), /* 1101 */ V(1, 0, 3), /* 1110 */ V(0, 0, 3), /* 1111 */ V(0, 0, 3), /* 0000 ... */ /* 000 */ V(3, 3, 3), /* 16 */ /* 001 */ V(0, 3, 3), /* 010 */ V(2, 3, 2), /* 011 */ V(2, 3, 2), /* 100 */ V(3, 2, 2), /* 101 */ V(3, 2, 2), /* 110 */ V(3, 0, 2), /* 111 */ V(3, 0, 2), /* 0001 ... */ /* 0 */ V(1, 3, 1), /* 24 */ /* 1 */ V(3, 1, 1), /* 0010 ... */ /* 0 */ V(2, 2, 1), /* 26 */ /* 1 */ V(0, 2, 1) }; static union huffpair const hufftab7[] = { /* 0000 */ PTR(16, 4), /* 0001 */ PTR(32, 4), /* 0010 */ PTR(48, 2), /* 0011 */ V(1, 1, 4), /* 0100 */ V(0, 1, 3), /* 0101 */ V(0, 1, 3), /* 0110 */ V(1, 0, 3), /* 0111 */ V(1, 0, 3), /* 1000 */ V(0, 0, 1), /* 1001 */ V(0, 0, 1), /* 1010 */ V(0, 0, 1), /* 1011 */ V(0, 0, 1), /* 1100 */ V(0, 0, 1), /* 1101 */ V(0, 0, 1), /* 1110 */ V(0, 0, 1), /* 1111 */ V(0, 0, 1), /* 0000 ... */ /* 0000 */ PTR(52, 2), /* 16 */ /* 0001 */ PTR(56, 1), /* 0010 */ PTR(58, 1), /* 0011 */ V(1, 5, 4), /* 0100 */ V(5, 1, 4), /* 0101 */ PTR(60, 1), /* 0110 */ V(5, 0, 4), /* 0111 */ PTR(62, 1), /* 1000 */ V(2, 4, 4), /* 1001 */ V(4, 2, 4), /* 1010 */ V(1, 4, 3), /* 1011 */ V(1, 4, 3), /* 1100 */ V(4, 1, 3), /* 1101 */ V(4, 1, 3), /* 1110 */ V(4, 0, 3), /* 1111 */ V(4, 0, 3), /* 0001 ... */ /* 0000 */ V(0, 4, 4), /* 32 */ /* 0001 */ V(2, 3, 4), /* 0010 */ V(3, 2, 4), /* 0011 */ V(0, 3, 4), /* 0100 */ V(1, 3, 3), /* 0101 */ V(1, 3, 3), /* 0110 */ V(3, 1, 3), /* 0111 */ V(3, 1, 3), /* 1000 */ V(3, 0, 3), /* 1001 */ V(3, 0, 3), /* 1010 */ V(2, 2, 3), /* 1011 */ V(2, 2, 3), /* 1100 */ V(1, 2, 2), /* 1101 */ V(1, 2, 2), /* 1110 */ V(1, 2, 2), /* 1111 */ V(1, 2, 2), /* 0010 ... */ /* 00 */ V(2, 1, 1), /* 48 */ /* 01 */ V(2, 1, 1), /* 10 */ V(0, 2, 2), /* 11 */ V(2, 0, 2), /* 0000 0000 ... */ /* 00 */ V(5, 5, 2), /* 52 */ /* 01 */ V(4, 5, 2), /* 10 */ V(5, 4, 2), /* 11 */ V(5, 3, 2), /* 0000 0001 ... */ /* 0 */ V(3, 5, 1), /* 56 */ /* 1 */ V(4, 4, 1), /* 0000 0010 ... */ /* 0 */ V(2, 5, 1), /* 58 */ /* 1 */ V(5, 2, 1), /* 0000 0101 ... */ /* 0 */ V(0, 5, 1), /* 60 */ /* 1 */ V(3, 4, 1), /* 0000 0111 ... */ /* 0 */ V(4, 3, 1), /* 62 */ /* 1 */ V(3, 3, 1) }; # if 0 /* this version saves 8 entries (16 bytes) at the expense of an extra lookup in 4 out of 36 cases */ static union huffpair const hufftab8[] = { /* 0000 */ PTR(16, 4), /* 0001 */ PTR(32, 2), /* 0010 */ V(1, 2, 4), /* 0011 */ V(2, 1, 4), /* 0100 */ V(1, 1, 2), /* 0101 */ V(1, 1, 2), /* 0110 */ V(1, 1, 2), /* 0111 */ V(1, 1, 2), /* 1000 */ V(0, 1, 3), /* 1001 */ V(0, 1, 3), /* 1010 */ V(1, 0, 3), /* 1011 */ V(1, 0, 3), /* 1100 */ V(0, 0, 2), /* 1101 */ V(0, 0, 2), /* 1110 */ V(0, 0, 2), /* 1111 */ V(0, 0, 2), /* 0000 ... */ /* 0000 */ PTR(36, 3), /* 16 */ /* 0001 */ PTR(44, 2), /* 0010 */ PTR(48, 1), /* 0011 */ V(1, 5, 4), /* 0100 */ V(5, 1, 4), /* 0101 */ PTR(50, 1), /* 0110 */ PTR(52, 1), /* 0111 */ V(2, 4, 4), /* 1000 */ V(4, 2, 4), /* 1001 */ V(1, 4, 4), /* 1010 */ V(4, 1, 3), /* 1011 */ V(4, 1, 3), /* 1100 */ V(0, 4, 4), /* 1101 */ V(4, 0, 4), /* 1110 */ V(2, 3, 4), /* 1111 */ V(3, 2, 4), /* 0001 ... */ /* 00 */ PTR(54, 2), /* 32 */ /* 01 */ V(2, 2, 2), /* 10 */ V(0, 2, 2), /* 11 */ V(2, 0, 2), /* 0000 0000 ... */ /* 000 */ V(5, 5, 3), /* 36 */ /* 001 */ V(5, 4, 3), /* 010 */ V(4, 5, 2), /* 011 */ V(4, 5, 2), /* 100 */ V(5, 3, 1), /* 101 */ V(5, 3, 1), /* 110 */ V(5, 3, 1), /* 111 */ V(5, 3, 1), /* 0000 0001 ... */ /* 00 */ V(3, 5, 2), /* 44 */ /* 01 */ V(4, 4, 2), /* 10 */ V(2, 5, 1), /* 11 */ V(2, 5, 1), /* 0000 0010 ... */ /* 0 */ V(5, 2, 1), /* 48 */ /* 1 */ V(0, 5, 1), /* 0000 0101 ... */ /* 0 */ V(3, 4, 1), /* 50 */ /* 1 */ V(4, 3, 1), /* 0000 0110 ... */ /* 0 */ V(5, 0, 1), /* 52 */ /* 1 */ V(3, 3, 1), /* 0001 00 ... */ /* 00 */ V(1, 3, 2), /* 54 */ /* 01 */ V(3, 1, 2), /* 10 */ V(0, 3, 2), /* 11 */ V(3, 0, 2), }; # else static union huffpair const hufftab8[] = { /* 0000 */ PTR(16, 4), /* 0001 */ PTR(32, 4), /* 0010 */ V(1, 2, 4), /* 0011 */ V(2, 1, 4), /* 0100 */ V(1, 1, 2), /* 0101 */ V(1, 1, 2), /* 0110 */ V(1, 1, 2), /* 0111 */ V(1, 1, 2), /* 1000 */ V(0, 1, 3), /* 1001 */ V(0, 1, 3), /* 1010 */ V(1, 0, 3), /* 1011 */ V(1, 0, 3), /* 1100 */ V(0, 0, 2), /* 1101 */ V(0, 0, 2), /* 1110 */ V(0, 0, 2), /* 1111 */ V(0, 0, 2), /* 0000 ... */ /* 0000 */ PTR(48, 3), /* 16 */ /* 0001 */ PTR(56, 2), /* 0010 */ PTR(60, 1), /* 0011 */ V(1, 5, 4), /* 0100 */ V(5, 1, 4), /* 0101 */ PTR(62, 1), /* 0110 */ PTR(64, 1), /* 0111 */ V(2, 4, 4), /* 1000 */ V(4, 2, 4), /* 1001 */ V(1, 4, 4), /* 1010 */ V(4, 1, 3), /* 1011 */ V(4, 1, 3), /* 1100 */ V(0, 4, 4), /* 1101 */ V(4, 0, 4), /* 1110 */ V(2, 3, 4), /* 1111 */ V(3, 2, 4), /* 0001 ... */ /* 0000 */ V(1, 3, 4), /* 32 */ /* 0001 */ V(3, 1, 4), /* 0010 */ V(0, 3, 4), /* 0011 */ V(3, 0, 4), /* 0100 */ V(2, 2, 2), /* 0101 */ V(2, 2, 2), /* 0110 */ V(2, 2, 2), /* 0111 */ V(2, 2, 2), /* 1000 */ V(0, 2, 2), /* 1001 */ V(0, 2, 2), /* 1010 */ V(0, 2, 2), /* 1011 */ V(0, 2, 2), /* 1100 */ V(2, 0, 2), /* 1101 */ V(2, 0, 2), /* 1110 */ V(2, 0, 2), /* 1111 */ V(2, 0, 2), /* 0000 0000 ... */ /* 000 */ V(5, 5, 3), /* 48 */ /* 001 */ V(5, 4, 3), /* 010 */ V(4, 5, 2), /* 011 */ V(4, 5, 2), /* 100 */ V(5, 3, 1), /* 101 */ V(5, 3, 1), /* 110 */ V(5, 3, 1), /* 111 */ V(5, 3, 1), /* 0000 0001 ... */ /* 00 */ V(3, 5, 2), /* 56 */ /* 01 */ V(4, 4, 2), /* 10 */ V(2, 5, 1), /* 11 */ V(2, 5, 1), /* 0000 0010 ... */ /* 0 */ V(5, 2, 1), /* 60 */ /* 1 */ V(0, 5, 1), /* 0000 0101 ... */ /* 0 */ V(3, 4, 1), /* 62 */ /* 1 */ V(4, 3, 1), /* 0000 0110 ... */ /* 0 */ V(5, 0, 1), /* 64 */ /* 1 */ V(3, 3, 1) }; # endif static union huffpair const hufftab9[] = { /* 0000 */ PTR(16, 4), /* 0001 */ PTR(32, 3), /* 0010 */ PTR(40, 2), /* 0011 */ PTR(44, 2), /* 0100 */ PTR(48, 1), /* 0101 */ V(1, 2, 4), /* 0110 */ V(2, 1, 4), /* 0111 */ V(2, 0, 4), /* 1000 */ V(1, 1, 3), /* 1001 */ V(1, 1, 3), /* 1010 */ V(0, 1, 3), /* 1011 */ V(0, 1, 3), /* 1100 */ V(1, 0, 3), /* 1101 */ V(1, 0, 3), /* 1110 */ V(0, 0, 3), /* 1111 */ V(0, 0, 3), /* 0000 ... */ /* 0000 */ PTR(50, 1), /* 16 */ /* 0001 */ V(3, 5, 4), /* 0010 */ V(5, 3, 4), /* 0011 */ PTR(52, 1), /* 0100 */ V(4, 4, 4), /* 0101 */ V(2, 5, 4), /* 0110 */ V(5, 2, 4), /* 0111 */ V(1, 5, 4), /* 1000 */ V(5, 1, 3), /* 1001 */ V(5, 1, 3), /* 1010 */ V(3, 4, 3), /* 1011 */ V(3, 4, 3), /* 1100 */ V(4, 3, 3), /* 1101 */ V(4, 3, 3), /* 1110 */ V(5, 0, 4), /* 1111 */ V(0, 4, 4), /* 0001 ... */ /* 000 */ V(2, 4, 3), /* 32 */ /* 001 */ V(4, 2, 3), /* 010 */ V(3, 3, 3), /* 011 */ V(4, 0, 3), /* 100 */ V(1, 4, 2), /* 101 */ V(1, 4, 2), /* 110 */ V(4, 1, 2), /* 111 */ V(4, 1, 2), /* 0010 ... */ /* 00 */ V(2, 3, 2), /* 40 */ /* 01 */ V(3, 2, 2), /* 10 */ V(1, 3, 1), /* 11 */ V(1, 3, 1), /* 0011 ... */ /* 00 */ V(3, 1, 1), /* 44 */ /* 01 */ V(3, 1, 1), /* 10 */ V(0, 3, 2), /* 11 */ V(3, 0, 2), /* 0100 ... */ /* 0 */ V(2, 2, 1), /* 48 */ /* 1 */ V(0, 2, 1), /* 0000 0000 ... */ /* 0 */ V(5, 5, 1), /* 50 */ /* 1 */ V(4, 5, 1), /* 0000 0011 ... */ /* 0 */ V(5, 4, 1), /* 52 */ /* 1 */ V(0, 5, 1) }; static union huffpair const hufftab10[] = { /* 0000 */ PTR(16, 4), /* 0001 */ PTR(32, 4), /* 0010 */ PTR(48, 2), /* 0011 */ V(1, 1, 4), /* 0100 */ V(0, 1, 3), /* 0101 */ V(0, 1, 3), /* 0110 */ V(1, 0, 3), /* 0111 */ V(1, 0, 3), /* 1000 */ V(0, 0, 1), /* 1001 */ V(0, 0, 1), /* 1010 */ V(0, 0, 1), /* 1011 */ V(0, 0, 1), /* 1100 */ V(0, 0, 1), /* 1101 */ V(0, 0, 1), /* 1110 */ V(0, 0, 1), /* 1111 */ V(0, 0, 1), /* 0000 ... */ /* 0000 */ PTR(52, 3), /* 16 */ /* 0001 */ PTR(60, 2), /* 0010 */ PTR(64, 3), /* 0011 */ PTR(72, 1), /* 0100 */ PTR(74, 2), /* 0101 */ PTR(78, 2), /* 0110 */ PTR(82, 2), /* 0111 */ V(1, 7, 4), /* 1000 */ V(7, 1, 4), /* 1001 */ PTR(86, 1), /* 1010 */ PTR(88, 2), /* 1011 */ PTR(92, 2), /* 1100 */ V(1, 6, 4), /* 1101 */ V(6, 1, 4), /* 1110 */ V(6, 0, 4), /* 1111 */ PTR(96, 1), /* 0001 ... */ /* 0000 */ PTR(98, 1), /* 32 */ /* 0001 */ PTR(100, 1), /* 0010 */ V(1, 4, 4), /* 0011 */ V(4, 1, 4), /* 0100 */ V(4, 0, 4), /* 0101 */ V(2, 3, 4), /* 0110 */ V(3, 2, 4), /* 0111 */ V(0, 3, 4), /* 1000 */ V(1, 3, 3), /* 1001 */ V(1, 3, 3), /* 1010 */ V(3, 1, 3), /* 1011 */ V(3, 1, 3), /* 1100 */ V(3, 0, 3), /* 1101 */ V(3, 0, 3), /* 1110 */ V(2, 2, 3), /* 1111 */ V(2, 2, 3), /* 0010 ... */ /* 00 */ V(1, 2, 2), /* 48 */ /* 01 */ V(2, 1, 2), /* 10 */ V(0, 2, 2), /* 11 */ V(2, 0, 2), /* 0000 0000 ... */ /* 000 */ V(7, 7, 3), /* 52 */ /* 001 */ V(6, 7, 3), /* 010 */ V(7, 6, 3), /* 011 */ V(5, 7, 3), /* 100 */ V(7, 5, 3), /* 101 */ V(6, 6, 3), /* 110 */ V(4, 7, 2), /* 111 */ V(4, 7, 2), /* 0000 0001 ... */ /* 00 */ V(7, 4, 2), /* 60 */ /* 01 */ V(5, 6, 2), /* 10 */ V(6, 5, 2), /* 11 */ V(3, 7, 2), /* 0000 0010 ... */ /* 000 */ V(7, 3, 2), /* 64 */ /* 001 */ V(7, 3, 2), /* 010 */ V(4, 6, 2), /* 011 */ V(4, 6, 2), /* 100 */ V(5, 5, 3), /* 101 */ V(5, 4, 3), /* 110 */ V(6, 3, 2), /* 111 */ V(6, 3, 2), /* 0000 0011 ... */ /* 0 */ V(2, 7, 1), /* 72 */ /* 1 */ V(7, 2, 1), /* 0000 0100 ... */ /* 00 */ V(6, 4, 2), /* 74 */ /* 01 */ V(0, 7, 2), /* 10 */ V(7, 0, 1), /* 11 */ V(7, 0, 1), /* 0000 0101 ... */ /* 00 */ V(6, 2, 1), /* 78 */ /* 01 */ V(6, 2, 1), /* 10 */ V(4, 5, 2), /* 11 */ V(3, 5, 2), /* 0000 0110 ... */ /* 00 */ V(0, 6, 1), /* 82 */ /* 01 */ V(0, 6, 1), /* 10 */ V(5, 3, 2), /* 11 */ V(4, 4, 2), /* 0000 1001 ... */ /* 0 */ V(3, 6, 1), /* 86 */ /* 1 */ V(2, 6, 1), /* 0000 1010 ... */ /* 00 */ V(2, 5, 2), /* 88 */ /* 01 */ V(5, 2, 2), /* 10 */ V(1, 5, 1), /* 11 */ V(1, 5, 1), /* 0000 1011 ... */ /* 00 */ V(5, 1, 1), /* 92 */ /* 01 */ V(5, 1, 1), /* 10 */ V(3, 4, 2), /* 11 */ V(4, 3, 2), /* 0000 1111 ... */ /* 0 */ V(0, 5, 1), /* 96 */ /* 1 */ V(5, 0, 1), /* 0001 0000 ... */ /* 0 */ V(2, 4, 1), /* 98 */ /* 1 */ V(4, 2, 1), /* 0001 0001 ... */ /* 0 */ V(3, 3, 1), /* 100 */ /* 1 */ V(0, 4, 1) }; static union huffpair const hufftab11[] = { /* 0000 */ PTR(16, 4), /* 0001 */ PTR(32, 4), /* 0010 */ PTR(48, 4), /* 0011 */ PTR(64, 3), /* 0100 */ V(1, 2, 4), /* 0101 */ PTR(72, 1), /* 0110 */ V(1, 1, 3), /* 0111 */ V(1, 1, 3), /* 1000 */ V(0, 1, 3), /* 1001 */ V(0, 1, 3), /* 1010 */ V(1, 0, 3), /* 1011 */ V(1, 0, 3), /* 1100 */ V(0, 0, 2), /* 1101 */ V(0, 0, 2), /* 1110 */ V(0, 0, 2), /* 1111 */ V(0, 0, 2), /* 0000 ... */ /* 0000 */ PTR(74, 2), /* 16 */ /* 0001 */ PTR(78, 3), /* 0010 */ PTR(86, 2), /* 0011 */ PTR(90, 1), /* 0100 */ PTR(92, 2), /* 0101 */ V(2, 7, 4), /* 0110 */ V(7, 2, 4), /* 0111 */ PTR(96, 1), /* 1000 */ V(7, 1, 3), /* 1001 */ V(7, 1, 3), /* 1010 */ V(1, 7, 4), /* 1011 */ V(7, 0, 4), /* 1100 */ V(3, 6, 4), /* 1101 */ V(6, 3, 4), /* 1110 */ V(6, 0, 4), /* 1111 */ PTR(98, 1), /* 0001 ... */ /* 0000 */ PTR(100, 1), /* 32 */ /* 0001 */ V(1, 5, 4), /* 0010 */ V(6, 2, 3), /* 0011 */ V(6, 2, 3), /* 0100 */ V(2, 6, 4), /* 0101 */ V(0, 6, 4), /* 0110 */ V(1, 6, 3), /* 0111 */ V(1, 6, 3), /* 1000 */ V(6, 1, 3), /* 1001 */ V(6, 1, 3), /* 1010 */ V(5, 1, 4), /* 1011 */ V(3, 4, 4), /* 1100 */ V(5, 0, 4), /* 1101 */ PTR(102, 1), /* 1110 */ V(2, 4, 4), /* 1111 */ V(4, 2, 4), /* 0010 ... */ /* 0000 */ V(1, 4, 4), /* 48 */ /* 0001 */ V(4, 1, 4), /* 0010 */ V(0, 4, 4), /* 0011 */ V(4, 0, 4), /* 0100 */ V(2, 3, 3), /* 0101 */ V(2, 3, 3), /* 0110 */ V(3, 2, 3), /* 0111 */ V(3, 2, 3), /* 1000 */ V(1, 3, 2), /* 1001 */ V(1, 3, 2), /* 1010 */ V(1, 3, 2), /* 1011 */ V(1, 3, 2), /* 1100 */ V(3, 1, 2), /* 1101 */ V(3, 1, 2), /* 1110 */ V(3, 1, 2), /* 1111 */ V(3, 1, 2), /* 0011 ... */ /* 000 */ V(0, 3, 3), /* 64 */ /* 001 */ V(3, 0, 3), /* 010 */ V(2, 2, 2), /* 011 */ V(2, 2, 2), /* 100 */ V(2, 1, 1), /* 101 */ V(2, 1, 1), /* 110 */ V(2, 1, 1), /* 111 */ V(2, 1, 1), /* 0101 ... */ /* 0 */ V(0, 2, 1), /* 72 */ /* 1 */ V(2, 0, 1), /* 0000 0000 ... */ /* 00 */ V(7, 7, 2), /* 74 */ /* 01 */ V(6, 7, 2), /* 10 */ V(7, 6, 2), /* 11 */ V(7, 5, 2), /* 0000 0001 ... */ /* 000 */ V(6, 6, 2), /* 78 */ /* 001 */ V(6, 6, 2), /* 010 */ V(4, 7, 2), /* 011 */ V(4, 7, 2), /* 100 */ V(7, 4, 2), /* 101 */ V(7, 4, 2), /* 110 */ V(5, 7, 3), /* 111 */ V(5, 5, 3), /* 0000 0010 ... */ /* 00 */ V(5, 6, 2), /* 86 */ /* 01 */ V(6, 5, 2), /* 10 */ V(3, 7, 1), /* 11 */ V(3, 7, 1), /* 0000 0011 ... */ /* 0 */ V(7, 3, 1), /* 90 */ /* 1 */ V(4, 6, 1), /* 0000 0100 ... */ /* 00 */ V(4, 5, 2), /* 92 */ /* 01 */ V(5, 4, 2), /* 10 */ V(3, 5, 2), /* 11 */ V(5, 3, 2), /* 0000 0111 ... */ /* 0 */ V(6, 4, 1), /* 96 */ /* 1 */ V(0, 7, 1), /* 0000 1111 ... */ /* 0 */ V(4, 4, 1), /* 98 */ /* 1 */ V(2, 5, 1), /* 0001 0000 ... */ /* 0 */ V(5, 2, 1), /* 100 */ /* 1 */ V(0, 5, 1), /* 0001 1101 ... */ /* 0 */ V(4, 3, 1), /* 102 */ /* 1 */ V(3, 3, 1) }; static union huffpair const hufftab12[] = { /* 0000 */ PTR(16, 4), /* 0001 */ PTR(32, 4), /* 0010 */ PTR(48, 4), /* 0011 */ PTR(64, 2), /* 0100 */ PTR(68, 3), /* 0101 */ PTR(76, 1), /* 0110 */ V(1, 2, 4), /* 0111 */ V(2, 1, 4), /* 1000 */ PTR(78, 1), /* 1001 */ V(0, 0, 4), /* 1010 */ V(1, 1, 3), /* 1011 */ V(1, 1, 3), /* 1100 */ V(0, 1, 3), /* 1101 */ V(0, 1, 3), /* 1110 */ V(1, 0, 3), /* 1111 */ V(1, 0, 3), /* 0000 ... */ /* 0000 */ PTR(80, 2), /* 16 */ /* 0001 */ PTR(84, 1), /* 0010 */ PTR(86, 1), /* 0011 */ PTR(88, 1), /* 0100 */ V(5, 6, 4), /* 0101 */ V(3, 7, 4), /* 0110 */ PTR(90, 1), /* 0111 */ V(2, 7, 4), /* 1000 */ V(7, 2, 4), /* 1001 */ V(4, 6, 4), /* 1010 */ V(6, 4, 4), /* 1011 */ V(1, 7, 4), /* 1100 */ V(7, 1, 4), /* 1101 */ PTR(92, 1), /* 1110 */ V(3, 6, 4), /* 1111 */ V(6, 3, 4), /* 0001 ... */ /* 0000 */ V(4, 5, 4), /* 32 */ /* 0001 */ V(5, 4, 4), /* 0010 */ V(4, 4, 4), /* 0011 */ PTR(94, 1), /* 0100 */ V(2, 6, 3), /* 0101 */ V(2, 6, 3), /* 0110 */ V(6, 2, 3), /* 0111 */ V(6, 2, 3), /* 1000 */ V(6, 1, 3), /* 1001 */ V(6, 1, 3), /* 1010 */ V(1, 6, 4), /* 1011 */ V(6, 0, 4), /* 1100 */ V(3, 5, 4), /* 1101 */ V(5, 3, 4), /* 1110 */ V(2, 5, 4), /* 1111 */ V(5, 2, 4), /* 0010 ... */ /* 0000 */ V(1, 5, 3), /* 48 */ /* 0001 */ V(1, 5, 3), /* 0010 */ V(5, 1, 3), /* 0011 */ V(5, 1, 3), /* 0100 */ V(3, 4, 3), /* 0101 */ V(3, 4, 3), /* 0110 */ V(4, 3, 3), /* 0111 */ V(4, 3, 3), /* 1000 */ V(5, 0, 4), /* 1001 */ V(0, 4, 4), /* 1010 */ V(2, 4, 3), /* 1011 */ V(2, 4, 3), /* 1100 */ V(4, 2, 3), /* 1101 */ V(4, 2, 3), /* 1110 */ V(1, 4, 3), /* 1111 */ V(1, 4, 3), /* 0011 ... */ /* 00 */ V(3, 3, 2), /* 64 */ /* 01 */ V(4, 1, 2), /* 10 */ V(2, 3, 2), /* 11 */ V(3, 2, 2), /* 0100 ... */ /* 000 */ V(4, 0, 3), /* 68 */ /* 001 */ V(0, 3, 3), /* 010 */ V(3, 0, 2), /* 011 */ V(3, 0, 2), /* 100 */ V(1, 3, 1), /* 101 */ V(1, 3, 1), /* 110 */ V(1, 3, 1), /* 111 */ V(1, 3, 1), /* 0101 ... */ /* 0 */ V(3, 1, 1), /* 76 */ /* 1 */ V(2, 2, 1), /* 1000 ... */ /* 0 */ V(0, 2, 1), /* 78 */ /* 1 */ V(2, 0, 1), /* 0000 0000 ... */ /* 00 */ V(7, 7, 2), /* 80 */ /* 01 */ V(6, 7, 2), /* 10 */ V(7, 6, 1), /* 11 */ V(7, 6, 1), /* 0000 0001 ... */ /* 0 */ V(5, 7, 1), /* 84 */ /* 1 */ V(7, 5, 1), /* 0000 0010 ... */ /* 0 */ V(6, 6, 1), /* 86 */ /* 1 */ V(4, 7, 1), /* 0000 0011 ... */ /* 0 */ V(7, 4, 1), /* 88 */ /* 1 */ V(6, 5, 1), /* 0000 0110 ... */ /* 0 */ V(7, 3, 1), /* 90 */ /* 1 */ V(5, 5, 1), /* 0000 1101 ... */ /* 0 */ V(0, 7, 1), /* 92 */ /* 1 */ V(7, 0, 1), /* 0001 0011 ... */ /* 0 */ V(0, 6, 1), /* 94 */ /* 1 */ V(0, 5, 1) }; static union huffpair const hufftab13[] = { /* 0000 */ PTR(16, 4), /* 0001 */ PTR(32, 4), /* 0010 */ PTR(48, 4), /* 0011 */ PTR(64, 2), /* 0100 */ V(1, 1, 4), /* 0101 */ V(0, 1, 4), /* 0110 */ V(1, 0, 3), /* 0111 */ V(1, 0, 3), /* 1000 */ V(0, 0, 1), /* 1001 */ V(0, 0, 1), /* 1010 */ V(0, 0, 1), /* 1011 */ V(0, 0, 1), /* 1100 */ V(0, 0, 1), /* 1101 */ V(0, 0, 1), /* 1110 */ V(0, 0, 1), /* 1111 */ V(0, 0, 1), /* 0000 ... */ /* 0000 */ PTR(68, 4), /* 16 */ /* 0001 */ PTR(84, 4), /* 0010 */ PTR(100, 4), /* 0011 */ PTR(116, 4), /* 0100 */ PTR(132, 4), /* 0101 */ PTR(148, 4), /* 0110 */ PTR(164, 3), /* 0111 */ PTR(172, 3), /* 1000 */ PTR(180, 3), /* 1001 */ PTR(188, 3), /* 1010 */ PTR(196, 3), /* 1011 */ PTR(204, 3), /* 1100 */ PTR(212, 1), /* 1101 */ PTR(214, 2), /* 1110 */ PTR(218, 3), /* 1111 */ PTR(226, 1), /* 0001 ... */ /* 0000 */ PTR(228, 2), /* 32 */ /* 0001 */ PTR(232, 2), /* 0010 */ PTR(236, 2), /* 0011 */ PTR(240, 2), /* 0100 */ V(8, 1, 4), /* 0101 */ PTR(244, 1), /* 0110 */ PTR(246, 1), /* 0111 */ PTR(248, 1), /* 1000 */ PTR(250, 2), /* 1001 */ PTR(254, 1), /* 1010 */ V(1, 5, 4), /* 1011 */ V(5, 1, 4), /* 1100 */ PTR(256, 1), /* 1101 */ PTR(258, 1), /* 1110 */ PTR(260, 1), /* 1111 */ V(1, 4, 4), /* 0010 ... */ /* 0000 */ V(4, 1, 3), /* 48 */ /* 0001 */ V(4, 1, 3), /* 0010 */ V(0, 4, 4), /* 0011 */ V(4, 0, 4), /* 0100 */ V(2, 3, 4), /* 0101 */ V(3, 2, 4), /* 0110 */ V(1, 3, 3), /* 0111 */ V(1, 3, 3), /* 1000 */ V(3, 1, 3), /* 1001 */ V(3, 1, 3), /* 1010 */ V(0, 3, 3), /* 1011 */ V(0, 3, 3), /* 1100 */ V(3, 0, 3), /* 1101 */ V(3, 0, 3), /* 1110 */ V(2, 2, 3), /* 1111 */ V(2, 2, 3), /* 0011 ... */ /* 00 */ V(1, 2, 2), /* 64 */ /* 01 */ V(2, 1, 2), /* 10 */ V(0, 2, 2), /* 11 */ V(2, 0, 2), /* 0000 0000 ... */ /* 0000 */ PTR(262, 4), /* 68 */ /* 0001 */ PTR(278, 4), /* 0010 */ PTR(294, 4), /* 0011 */ PTR(310, 3), /* 0100 */ PTR(318, 2), /* 0101 */ PTR(322, 2), /* 0110 */ PTR(326, 3), /* 0111 */ PTR(334, 2), /* 1000 */ PTR(338, 1), /* 1001 */ PTR(340, 2), /* 1010 */ PTR(344, 2), /* 1011 */ PTR(348, 2), /* 1100 */ PTR(352, 2), /* 1101 */ PTR(356, 2), /* 1110 */ V(1, 15, 4), /* 1111 */ V(15, 1, 4), /* 0000 0001 ... */ /* 0000 */ V(15, 0, 4), /* 84 */ /* 0001 */ PTR(360, 1), /* 0010 */ PTR(362, 1), /* 0011 */ PTR(364, 1), /* 0100 */ V(14, 2, 4), /* 0101 */ PTR(366, 1), /* 0110 */ V(1, 14, 4), /* 0111 */ V(14, 1, 4), /* 1000 */ PTR(368, 1), /* 1001 */ PTR(370, 1), /* 1010 */ PTR(372, 1), /* 1011 */ PTR(374, 1), /* 1100 */ PTR(376, 1), /* 1101 */ PTR(378, 1), /* 1110 */ V(12, 6, 4), /* 1111 */ V(3, 13, 4), /* 0000 0010 ... */ /* 0000 */ PTR(380, 1), /* 100 */ /* 0001 */ V(2, 13, 4), /* 0010 */ V(13, 2, 4), /* 0011 */ V(1, 13, 4), /* 0100 */ V(11, 7, 4), /* 0101 */ PTR(382, 1), /* 0110 */ PTR(384, 1), /* 0111 */ V(12, 3, 4), /* 1000 */ PTR(386, 1), /* 1001 */ V(4, 11, 4), /* 1010 */ V(13, 1, 3), /* 1011 */ V(13, 1, 3), /* 1100 */ V(0, 13, 4), /* 1101 */ V(13, 0, 4), /* 1110 */ V(8, 10, 4), /* 1111 */ V(10, 8, 4), /* 0000 0011 ... */ /* 0000 */ V(4, 12, 4), /* 116 */ /* 0001 */ V(12, 4, 4), /* 0010 */ V(6, 11, 4), /* 0011 */ V(11, 6, 4), /* 0100 */ V(3, 12, 3), /* 0101 */ V(3, 12, 3), /* 0110 */ V(2, 12, 3), /* 0111 */ V(2, 12, 3), /* 1000 */ V(12, 2, 3), /* 1001 */ V(12, 2, 3), /* 1010 */ V(5, 11, 3), /* 1011 */ V(5, 11, 3), /* 1100 */ V(11, 5, 4), /* 1101 */ V(8, 9, 4), /* 1110 */ V(1, 12, 3), /* 1111 */ V(1, 12, 3), /* 0000 0100 ... */ /* 0000 */ V(12, 1, 3), /* 132 */ /* 0001 */ V(12, 1, 3), /* 0010 */ V(9, 8, 4), /* 0011 */ V(0, 12, 4), /* 0100 */ V(12, 0, 3), /* 0101 */ V(12, 0, 3), /* 0110 */ V(11, 4, 4), /* 0111 */ V(6, 10, 4), /* 1000 */ V(10, 6, 4), /* 1001 */ V(7, 9, 4), /* 1010 */ V(3, 11, 3), /* 1011 */ V(3, 11, 3), /* 1100 */ V(11, 3, 3), /* 1101 */ V(11, 3, 3), /* 1110 */ V(8, 8, 4), /* 1111 */ V(5, 10, 4), /* 0000 0101 ... */ /* 0000 */ V(2, 11, 3), /* 148 */ /* 0001 */ V(2, 11, 3), /* 0010 */ V(10, 5, 4), /* 0011 */ V(6, 9, 4), /* 0100 */ V(10, 4, 3), /* 0101 */ V(10, 4, 3), /* 0110 */ V(7, 8, 4), /* 0111 */ V(8, 7, 4), /* 1000 */ V(9, 4, 3), /* 1001 */ V(9, 4, 3), /* 1010 */ V(7, 7, 4), /* 1011 */ V(7, 6, 4), /* 1100 */ V(11, 2, 2), /* 1101 */ V(11, 2, 2), /* 1110 */ V(11, 2, 2), /* 1111 */ V(11, 2, 2), /* 0000 0110 ... */ /* 000 */ V(1, 11, 2), /* 164 */ /* 001 */ V(1, 11, 2), /* 010 */ V(11, 1, 2), /* 011 */ V(11, 1, 2), /* 100 */ V(0, 11, 3), /* 101 */ V(11, 0, 3), /* 110 */ V(9, 6, 3), /* 111 */ V(4, 10, 3), /* 0000 0111 ... */ /* 000 */ V(3, 10, 3), /* 172 */ /* 001 */ V(10, 3, 3), /* 010 */ V(5, 9, 3), /* 011 */ V(9, 5, 3), /* 100 */ V(2, 10, 2), /* 101 */ V(2, 10, 2), /* 110 */ V(10, 2, 2), /* 111 */ V(10, 2, 2), /* 0000 1000 ... */ /* 000 */ V(1, 10, 2), /* 180 */ /* 001 */ V(1, 10, 2), /* 010 */ V(10, 1, 2), /* 011 */ V(10, 1, 2), /* 100 */ V(0, 10, 3), /* 101 */ V(6, 8, 3), /* 110 */ V(10, 0, 2), /* 111 */ V(10, 0, 2), /* 0000 1001 ... */ /* 000 */ V(8, 6, 3), /* 188 */ /* 001 */ V(4, 9, 3), /* 010 */ V(9, 3, 2), /* 011 */ V(9, 3, 2), /* 100 */ V(3, 9, 3), /* 101 */ V(5, 8, 3), /* 110 */ V(8, 5, 3), /* 111 */ V(6, 7, 3), /* 0000 1010 ... */ /* 000 */ V(2, 9, 2), /* 196 */ /* 001 */ V(2, 9, 2), /* 010 */ V(9, 2, 2), /* 011 */ V(9, 2, 2), /* 100 */ V(5, 7, 3), /* 101 */ V(7, 5, 3), /* 110 */ V(3, 8, 2), /* 111 */ V(3, 8, 2), /* 0000 1011 ... */ /* 000 */ V(8, 3, 2), /* 204 */ /* 001 */ V(8, 3, 2), /* 010 */ V(6, 6, 3), /* 011 */ V(4, 7, 3), /* 100 */ V(7, 4, 3), /* 101 */ V(5, 6, 3), /* 110 */ V(6, 5, 3), /* 111 */ V(7, 3, 3), /* 0000 1100 ... */ /* 0 */ V(1, 9, 1), /* 212 */ /* 1 */ V(9, 1, 1), /* 0000 1101 ... */ /* 00 */ V(0, 9, 2), /* 214 */ /* 01 */ V(9, 0, 2), /* 10 */ V(4, 8, 2), /* 11 */ V(8, 4, 2), /* 0000 1110 ... */ /* 000 */ V(7, 2, 2), /* 218 */ /* 001 */ V(7, 2, 2), /* 010 */ V(4, 6, 3), /* 011 */ V(6, 4, 3), /* 100 */ V(2, 8, 1), /* 101 */ V(2, 8, 1), /* 110 */ V(2, 8, 1), /* 111 */ V(2, 8, 1), /* 0000 1111 ... */ /* 0 */ V(8, 2, 1), /* 226 */ /* 1 */ V(1, 8, 1), /* 0001 0000 ... */ /* 00 */ V(3, 7, 2), /* 228 */ /* 01 */ V(2, 7, 2), /* 10 */ V(1, 7, 1), /* 11 */ V(1, 7, 1), /* 0001 0001 ... */ /* 00 */ V(7, 1, 1), /* 232 */ /* 01 */ V(7, 1, 1), /* 10 */ V(5, 5, 2), /* 11 */ V(0, 7, 2), /* 0001 0010 ... */ /* 00 */ V(7, 0, 2), /* 236 */ /* 01 */ V(3, 6, 2), /* 10 */ V(6, 3, 2), /* 11 */ V(4, 5, 2), /* 0001 0011 ... */ /* 00 */ V(5, 4, 2), /* 240 */ /* 01 */ V(2, 6, 2), /* 10 */ V(6, 2, 2), /* 11 */ V(3, 5, 2), /* 0001 0101 ... */ /* 0 */ V(0, 8, 1), /* 244 */ /* 1 */ V(8, 0, 1), /* 0001 0110 ... */ /* 0 */ V(1, 6, 1), /* 246 */ /* 1 */ V(6, 1, 1), /* 0001 0111 ... */ /* 0 */ V(0, 6, 1), /* 248 */ /* 1 */ V(6, 0, 1), /* 0001 1000 ... */ /* 00 */ V(5, 3, 2), /* 250 */ /* 01 */ V(4, 4, 2), /* 10 */ V(2, 5, 1), /* 11 */ V(2, 5, 1), /* 0001 1001 ... */ /* 0 */ V(5, 2, 1), /* 254 */ /* 1 */ V(0, 5, 1), /* 0001 1100 ... */ /* 0 */ V(3, 4, 1), /* 256 */ /* 1 */ V(4, 3, 1), /* 0001 1101 ... */ /* 0 */ V(5, 0, 1), /* 258 */ /* 1 */ V(2, 4, 1), /* 0001 1110 ... */ /* 0 */ V(4, 2, 1), /* 260 */ /* 1 */ V(3, 3, 1), /* 0000 0000 0000 ... */ /* 0000 */ PTR(388, 3), /* 262 */ /* 0001 */ V(15, 15, 4), /* 0010 */ V(14, 15, 4), /* 0011 */ V(13, 15, 4), /* 0100 */ V(14, 14, 4), /* 0101 */ V(12, 15, 4), /* 0110 */ V(13, 14, 4), /* 0111 */ V(11, 15, 4), /* 1000 */ V(15, 11, 4), /* 1001 */ V(12, 14, 4), /* 1010 */ V(13, 12, 4), /* 1011 */ PTR(396, 1), /* 1100 */ V(14, 12, 3), /* 1101 */ V(14, 12, 3), /* 1110 */ V(13, 13, 3), /* 1111 */ V(13, 13, 3), /* 0000 0000 0001 ... */ /* 0000 */ V(15, 10, 4), /* 278 */ /* 0001 */ V(12, 13, 4), /* 0010 */ V(11, 14, 3), /* 0011 */ V(11, 14, 3), /* 0100 */ V(14, 11, 3), /* 0101 */ V(14, 11, 3), /* 0110 */ V(9, 15, 3), /* 0111 */ V(9, 15, 3), /* 1000 */ V(15, 9, 3), /* 1001 */ V(15, 9, 3), /* 1010 */ V(14, 10, 3), /* 1011 */ V(14, 10, 3), /* 1100 */ V(11, 13, 3), /* 1101 */ V(11, 13, 3), /* 1110 */ V(13, 11, 3), /* 1111 */ V(13, 11, 3), /* 0000 0000 0010 ... */ /* 0000 */ V(8, 15, 3), /* 294 */ /* 0001 */ V(8, 15, 3), /* 0010 */ V(15, 8, 3), /* 0011 */ V(15, 8, 3), /* 0100 */ V(12, 12, 3), /* 0101 */ V(12, 12, 3), /* 0110 */ V(10, 14, 4), /* 0111 */ V(9, 14, 4), /* 1000 */ V(8, 14, 3), /* 1001 */ V(8, 14, 3), /* 1010 */ V(7, 15, 4), /* 1011 */ V(7, 14, 4), /* 1100 */ V(15, 7, 2), /* 1101 */ V(15, 7, 2), /* 1110 */ V(15, 7, 2), /* 1111 */ V(15, 7, 2), /* 0000 0000 0011 ... */ /* 000 */ V(13, 10, 2), /* 310 */ /* 001 */ V(13, 10, 2), /* 010 */ V(10, 13, 3), /* 011 */ V(11, 12, 3), /* 100 */ V(12, 11, 3), /* 101 */ V(15, 6, 3), /* 110 */ V(6, 15, 2), /* 111 */ V(6, 15, 2), /* 0000 0000 0100 ... */ /* 00 */ V(14, 8, 2), /* 318 */ /* 01 */ V(5, 15, 2), /* 10 */ V(9, 13, 2), /* 11 */ V(13, 9, 2), /* 0000 0000 0101 ... */ /* 00 */ V(15, 5, 2), /* 322 */ /* 01 */ V(14, 7, 2), /* 10 */ V(10, 12, 2), /* 11 */ V(11, 11, 2), /* 0000 0000 0110 ... */ /* 000 */ V(4, 15, 2), /* 326 */ /* 001 */ V(4, 15, 2), /* 010 */ V(15, 4, 2), /* 011 */ V(15, 4, 2), /* 100 */ V(12, 10, 3), /* 101 */ V(14, 6, 3), /* 110 */ V(15, 3, 2), /* 111 */ V(15, 3, 2), /* 0000 0000 0111 ... */ /* 00 */ V(3, 15, 1), /* 334 */ /* 01 */ V(3, 15, 1), /* 10 */ V(8, 13, 2), /* 11 */ V(13, 8, 2), /* 0000 0000 1000 ... */ /* 0 */ V(2, 15, 1), /* 338 */ /* 1 */ V(15, 2, 1), /* 0000 0000 1001 ... */ /* 00 */ V(6, 14, 2), /* 340 */ /* 01 */ V(9, 12, 2), /* 10 */ V(0, 15, 1), /* 11 */ V(0, 15, 1), /* 0000 0000 1010 ... */ /* 00 */ V(12, 9, 2), /* 344 */ /* 01 */ V(5, 14, 2), /* 10 */ V(10, 11, 1), /* 11 */ V(10, 11, 1), /* 0000 0000 1011 ... */ /* 00 */ V(7, 13, 2), /* 348 */ /* 01 */ V(13, 7, 2), /* 10 */ V(4, 14, 1), /* 11 */ V(4, 14, 1), /* 0000 0000 1100 ... */ /* 00 */ V(12, 8, 2), /* 352 */ /* 01 */ V(13, 6, 2), /* 10 */ V(3, 14, 1), /* 11 */ V(3, 14, 1), /* 0000 0000 1101 ... */ /* 00 */ V(11, 9, 1), /* 356 */ /* 01 */ V(11, 9, 1), /* 10 */ V(9, 11, 2), /* 11 */ V(10, 10, 2), /* 0000 0001 0001 ... */ /* 0 */ V(11, 10, 1), /* 360 */ /* 1 */ V(14, 5, 1), /* 0000 0001 0010 ... */ /* 0 */ V(14, 4, 1), /* 362 */ /* 1 */ V(8, 12, 1), /* 0000 0001 0011 ... */ /* 0 */ V(6, 13, 1), /* 364 */ /* 1 */ V(14, 3, 1), /* 0000 0001 0101 ... */ /* 0 */ V(2, 14, 1), /* 366 */ /* 1 */ V(0, 14, 1), /* 0000 0001 1000 ... */ /* 0 */ V(14, 0, 1), /* 368 */ /* 1 */ V(5, 13, 1), /* 0000 0001 1001 ... */ /* 0 */ V(13, 5, 1), /* 370 */ /* 1 */ V(7, 12, 1), /* 0000 0001 1010 ... */ /* 0 */ V(12, 7, 1), /* 372 */ /* 1 */ V(4, 13, 1), /* 0000 0001 1011 ... */ /* 0 */ V(8, 11, 1), /* 374 */ /* 1 */ V(11, 8, 1), /* 0000 0001 1100 ... */ /* 0 */ V(13, 4, 1), /* 376 */ /* 1 */ V(9, 10, 1), /* 0000 0001 1101 ... */ /* 0 */ V(10, 9, 1), /* 378 */ /* 1 */ V(6, 12, 1), /* 0000 0010 0000 ... */ /* 0 */ V(13, 3, 1), /* 380 */ /* 1 */ V(7, 11, 1), /* 0000 0010 0101 ... */ /* 0 */ V(5, 12, 1), /* 382 */ /* 1 */ V(12, 5, 1), /* 0000 0010 0110 ... */ /* 0 */ V(9, 9, 1), /* 384 */ /* 1 */ V(7, 10, 1), /* 0000 0010 1000 ... */ /* 0 */ V(10, 7, 1), /* 386 */ /* 1 */ V(9, 7, 1), /* 0000 0000 0000 0000 ... */ /* 000 */ V(15, 14, 3), /* 388 */ /* 001 */ V(15, 12, 3), /* 010 */ V(15, 13, 2), /* 011 */ V(15, 13, 2), /* 100 */ V(14, 13, 1), /* 101 */ V(14, 13, 1), /* 110 */ V(14, 13, 1), /* 111 */ V(14, 13, 1), /* 0000 0000 0000 1011 ... */ /* 0 */ V(10, 15, 1), /* 396 */ /* 1 */ V(14, 9, 1) }; static union huffpair const hufftab15[] = { /* 0000 */ PTR(16, 4), /* 0001 */ PTR(32, 4), /* 0010 */ PTR(48, 4), /* 0011 */ PTR(64, 4), /* 0100 */ PTR(80, 4), /* 0101 */ PTR(96, 3), /* 0110 */ PTR(104, 3), /* 0111 */ PTR(112, 2), /* 1000 */ PTR(116, 1), /* 1001 */ PTR(118, 1), /* 1010 */ V(1, 1, 3), /* 1011 */ V(1, 1, 3), /* 1100 */ V(0, 1, 4), /* 1101 */ V(1, 0, 4), /* 1110 */ V(0, 0, 3), /* 1111 */ V(0, 0, 3), /* 0000 ... */ /* 0000 */ PTR(120, 4), /* 16 */ /* 0001 */ PTR(136, 4), /* 0010 */ PTR(152, 4), /* 0011 */ PTR(168, 4), /* 0100 */ PTR(184, 4), /* 0101 */ PTR(200, 3), /* 0110 */ PTR(208, 3), /* 0111 */ PTR(216, 4), /* 1000 */ PTR(232, 3), /* 1001 */ PTR(240, 3), /* 1010 */ PTR(248, 3), /* 1011 */ PTR(256, 3), /* 1100 */ PTR(264, 2), /* 1101 */ PTR(268, 3), /* 1110 */ PTR(276, 3), /* 1111 */ PTR(284, 2), /* 0001 ... */ /* 0000 */ PTR(288, 2), /* 32 */ /* 0001 */ PTR(292, 2), /* 0010 */ PTR(296, 2), /* 0011 */ PTR(300, 2), /* 0100 */ PTR(304, 2), /* 0101 */ PTR(308, 2), /* 0110 */ PTR(312, 2), /* 0111 */ PTR(316, 2), /* 1000 */ PTR(320, 1), /* 1001 */ PTR(322, 1), /* 1010 */ PTR(324, 1), /* 1011 */ PTR(326, 2), /* 1100 */ PTR(330, 1), /* 1101 */ PTR(332, 1), /* 1110 */ PTR(334, 2), /* 1111 */ PTR(338, 1), /* 0010 ... */ /* 0000 */ PTR(340, 1), /* 48 */ /* 0001 */ PTR(342, 1), /* 0010 */ V(9, 1, 4), /* 0011 */ PTR(344, 1), /* 0100 */ PTR(346, 1), /* 0101 */ PTR(348, 1), /* 0110 */ PTR(350, 1), /* 0111 */ PTR(352, 1), /* 1000 */ V(2, 8, 4), /* 1001 */ V(8, 2, 4), /* 1010 */ V(1, 8, 4), /* 1011 */ V(8, 1, 4), /* 1100 */ PTR(354, 1), /* 1101 */ PTR(356, 1), /* 1110 */ PTR(358, 1), /* 1111 */ PTR(360, 1), /* 0011 ... */ /* 0000 */ V(2, 7, 4), /* 64 */ /* 0001 */ V(7, 2, 4), /* 0010 */ V(6, 4, 4), /* 0011 */ V(1, 7, 4), /* 0100 */ V(5, 5, 4), /* 0101 */ V(7, 1, 4), /* 0110 */ PTR(362, 1), /* 0111 */ V(3, 6, 4), /* 1000 */ V(6, 3, 4), /* 1001 */ V(4, 5, 4), /* 1010 */ V(5, 4, 4), /* 1011 */ V(2, 6, 4), /* 1100 */ V(6, 2, 4), /* 1101 */ V(1, 6, 4), /* 1110 */ PTR(364, 1), /* 1111 */ V(3, 5, 4), /* 0100 ... */ /* 0000 */ V(6, 1, 3), /* 80 */ /* 0001 */ V(6, 1, 3), /* 0010 */ V(5, 3, 4), /* 0011 */ V(4, 4, 4), /* 0100 */ V(2, 5, 3), /* 0101 */ V(2, 5, 3), /* 0110 */ V(5, 2, 3), /* 0111 */ V(5, 2, 3), /* 1000 */ V(1, 5, 3), /* 1001 */ V(1, 5, 3), /* 1010 */ V(5, 1, 3), /* 1011 */ V(5, 1, 3), /* 1100 */ V(0, 5, 4), /* 1101 */ V(5, 0, 4), /* 1110 */ V(3, 4, 3), /* 1111 */ V(3, 4, 3), /* 0101 ... */ /* 000 */ V(4, 3, 3), /* 96 */ /* 001 */ V(2, 4, 3), /* 010 */ V(4, 2, 3), /* 011 */ V(3, 3, 3), /* 100 */ V(4, 1, 2), /* 101 */ V(4, 1, 2), /* 110 */ V(1, 4, 3), /* 111 */ V(0, 4, 3), /* 0110 ... */ /* 000 */ V(2, 3, 2), /* 104 */ /* 001 */ V(2, 3, 2), /* 010 */ V(3, 2, 2), /* 011 */ V(3, 2, 2), /* 100 */ V(4, 0, 3), /* 101 */ V(0, 3, 3), /* 110 */ V(1, 3, 2), /* 111 */ V(1, 3, 2), /* 0111 ... */ /* 00 */ V(3, 1, 2), /* 112 */ /* 01 */ V(3, 0, 2), /* 10 */ V(2, 2, 1), /* 11 */ V(2, 2, 1), /* 1000 ... */ /* 0 */ V(1, 2, 1), /* 116 */ /* 1 */ V(2, 1, 1), /* 1001 ... */ /* 0 */ V(0, 2, 1), /* 118 */ /* 1 */ V(2, 0, 1), /* 0000 0000 ... */ /* 0000 */ PTR(366, 1), /* 120 */ /* 0001 */ PTR(368, 1), /* 0010 */ V(14, 14, 4), /* 0011 */ PTR(370, 1), /* 0100 */ PTR(372, 1), /* 0101 */ PTR(374, 1), /* 0110 */ V(15, 11, 4), /* 0111 */ PTR(376, 1), /* 1000 */ V(13, 13, 4), /* 1001 */ V(10, 15, 4), /* 1010 */ V(15, 10, 4), /* 1011 */ V(11, 14, 4), /* 1100 */ V(14, 11, 4), /* 1101 */ V(12, 13, 4), /* 1110 */ V(13, 12, 4), /* 1111 */ V(9, 15, 4), /* 0000 0001 ... */ /* 0000 */ V(15, 9, 4), /* 136 */ /* 0001 */ V(14, 10, 4), /* 0010 */ V(11, 13, 4), /* 0011 */ V(13, 11, 4), /* 0100 */ V(8, 15, 4), /* 0101 */ V(15, 8, 4), /* 0110 */ V(12, 12, 4), /* 0111 */ V(9, 14, 4), /* 1000 */ V(14, 9, 4), /* 1001 */ V(7, 15, 4), /* 1010 */ V(15, 7, 4), /* 1011 */ V(10, 13, 4), /* 1100 */ V(13, 10, 4), /* 1101 */ V(11, 12, 4), /* 1110 */ V(6, 15, 4), /* 1111 */ PTR(378, 1), /* 0000 0010 ... */ /* 0000 */ V(12, 11, 3), /* 152 */ /* 0001 */ V(12, 11, 3), /* 0010 */ V(15, 6, 3), /* 0011 */ V(15, 6, 3), /* 0100 */ V(8, 14, 4), /* 0101 */ V(14, 8, 4), /* 0110 */ V(5, 15, 4), /* 0111 */ V(9, 13, 4), /* 1000 */ V(15, 5, 3), /* 1001 */ V(15, 5, 3), /* 1010 */ V(7, 14, 3), /* 1011 */ V(7, 14, 3), /* 1100 */ V(14, 7, 3), /* 1101 */ V(14, 7, 3), /* 1110 */ V(10, 12, 3), /* 1111 */ V(10, 12, 3), /* 0000 0011 ... */ /* 0000 */ V(12, 10, 3), /* 168 */ /* 0001 */ V(12, 10, 3), /* 0010 */ V(11, 11, 3), /* 0011 */ V(11, 11, 3), /* 0100 */ V(13, 9, 4), /* 0101 */ V(8, 13, 4), /* 0110 */ V(4, 15, 3), /* 0111 */ V(4, 15, 3), /* 1000 */ V(15, 4, 3), /* 1001 */ V(15, 4, 3), /* 1010 */ V(3, 15, 3), /* 1011 */ V(3, 15, 3), /* 1100 */ V(15, 3, 3), /* 1101 */ V(15, 3, 3), /* 1110 */ V(13, 8, 3), /* 1111 */ V(13, 8, 3), /* 0000 0100 ... */ /* 0000 */ V(14, 6, 3), /* 184 */ /* 0001 */ V(14, 6, 3), /* 0010 */ V(2, 15, 3), /* 0011 */ V(2, 15, 3), /* 0100 */ V(15, 2, 3), /* 0101 */ V(15, 2, 3), /* 0110 */ V(6, 14, 4), /* 0111 */ V(15, 0, 4), /* 1000 */ V(1, 15, 3), /* 1001 */ V(1, 15, 3), /* 1010 */ V(15, 1, 3), /* 1011 */ V(15, 1, 3), /* 1100 */ V(9, 12, 3), /* 1101 */ V(9, 12, 3), /* 1110 */ V(12, 9, 3), /* 1111 */ V(12, 9, 3), /* 0000 0101 ... */ /* 000 */ V(5, 14, 3), /* 200 */ /* 001 */ V(10, 11, 3), /* 010 */ V(11, 10, 3), /* 011 */ V(14, 5, 3), /* 100 */ V(7, 13, 3), /* 101 */ V(13, 7, 3), /* 110 */ V(4, 14, 3), /* 111 */ V(14, 4, 3), /* 0000 0110 ... */ /* 000 */ V(8, 12, 3), /* 208 */ /* 001 */ V(12, 8, 3), /* 010 */ V(3, 14, 3), /* 011 */ V(6, 13, 3), /* 100 */ V(13, 6, 3), /* 101 */ V(14, 3, 3), /* 110 */ V(9, 11, 3), /* 111 */ V(11, 9, 3), /* 0000 0111 ... */ /* 0000 */ V(2, 14, 3), /* 216 */ /* 0001 */ V(2, 14, 3), /* 0010 */ V(10, 10, 3), /* 0011 */ V(10, 10, 3), /* 0100 */ V(14, 2, 3), /* 0101 */ V(14, 2, 3), /* 0110 */ V(1, 14, 3), /* 0111 */ V(1, 14, 3), /* 1000 */ V(14, 1, 3), /* 1001 */ V(14, 1, 3), /* 1010 */ V(0, 14, 4), /* 1011 */ V(14, 0, 4), /* 1100 */ V(5, 13, 3), /* 1101 */ V(5, 13, 3), /* 1110 */ V(13, 5, 3), /* 1111 */ V(13, 5, 3), /* 0000 1000 ... */ /* 000 */ V(7, 12, 3), /* 232 */ /* 001 */ V(12, 7, 3), /* 010 */ V(4, 13, 3), /* 011 */ V(8, 11, 3), /* 100 */ V(13, 4, 2), /* 101 */ V(13, 4, 2), /* 110 */ V(11, 8, 3), /* 111 */ V(9, 10, 3), /* 0000 1001 ... */ /* 000 */ V(10, 9, 3), /* 240 */ /* 001 */ V(6, 12, 3), /* 010 */ V(12, 6, 3), /* 011 */ V(3, 13, 3), /* 100 */ V(13, 3, 2), /* 101 */ V(13, 3, 2), /* 110 */ V(13, 2, 2), /* 111 */ V(13, 2, 2), /* 0000 1010 ... */ /* 000 */ V(2, 13, 3), /* 248 */ /* 001 */ V(0, 13, 3), /* 010 */ V(1, 13, 2), /* 011 */ V(1, 13, 2), /* 100 */ V(7, 11, 2), /* 101 */ V(7, 11, 2), /* 110 */ V(11, 7, 2), /* 111 */ V(11, 7, 2), /* 0000 1011 ... */ /* 000 */ V(13, 1, 2), /* 256 */ /* 001 */ V(13, 1, 2), /* 010 */ V(5, 12, 3), /* 011 */ V(13, 0, 3), /* 100 */ V(12, 5, 2), /* 101 */ V(12, 5, 2), /* 110 */ V(8, 10, 2), /* 111 */ V(8, 10, 2), /* 0000 1100 ... */ /* 00 */ V(10, 8, 2), /* 264 */ /* 01 */ V(4, 12, 2), /* 10 */ V(12, 4, 2), /* 11 */ V(6, 11, 2), /* 0000 1101 ... */ /* 000 */ V(11, 6, 2), /* 268 */ /* 001 */ V(11, 6, 2), /* 010 */ V(9, 9, 3), /* 011 */ V(0, 12, 3), /* 100 */ V(3, 12, 2), /* 101 */ V(3, 12, 2), /* 110 */ V(12, 3, 2), /* 111 */ V(12, 3, 2), /* 0000 1110 ... */ /* 000 */ V(7, 10, 2), /* 276 */ /* 001 */ V(7, 10, 2), /* 010 */ V(10, 7, 2), /* 011 */ V(10, 7, 2), /* 100 */ V(10, 6, 2), /* 101 */ V(10, 6, 2), /* 110 */ V(12, 0, 3), /* 111 */ V(0, 11, 3), /* 0000 1111 ... */ /* 00 */ V(12, 2, 1), /* 284 */ /* 01 */ V(12, 2, 1), /* 10 */ V(2, 12, 2), /* 11 */ V(5, 11, 2), /* 0001 0000 ... */ /* 00 */ V(11, 5, 2), /* 288 */ /* 01 */ V(1, 12, 2), /* 10 */ V(8, 9, 2), /* 11 */ V(9, 8, 2), /* 0001 0001 ... */ /* 00 */ V(12, 1, 2), /* 292 */ /* 01 */ V(4, 11, 2), /* 10 */ V(11, 4, 2), /* 11 */ V(6, 10, 2), /* 0001 0010 ... */ /* 00 */ V(3, 11, 2), /* 296 */ /* 01 */ V(7, 9, 2), /* 10 */ V(11, 3, 1), /* 11 */ V(11, 3, 1), /* 0001 0011 ... */ /* 00 */ V(9, 7, 2), /* 300 */ /* 01 */ V(8, 8, 2), /* 10 */ V(2, 11, 2), /* 11 */ V(5, 10, 2), /* 0001 0100 ... */ /* 00 */ V(11, 2, 1), /* 304 */ /* 01 */ V(11, 2, 1), /* 10 */ V(10, 5, 2), /* 11 */ V(1, 11, 2), /* 0001 0101 ... */ /* 00 */ V(11, 1, 1), /* 308 */ /* 01 */ V(11, 1, 1), /* 10 */ V(11, 0, 2), /* 11 */ V(6, 9, 2), /* 0001 0110 ... */ /* 00 */ V(9, 6, 2), /* 312 */ /* 01 */ V(4, 10, 2), /* 10 */ V(10, 4, 2), /* 11 */ V(7, 8, 2), /* 0001 0111 ... */ /* 00 */ V(8, 7, 2), /* 316 */ /* 01 */ V(3, 10, 2), /* 10 */ V(10, 3, 1), /* 11 */ V(10, 3, 1), /* 0001 1000 ... */ /* 0 */ V(5, 9, 1), /* 320 */ /* 1 */ V(9, 5, 1), /* 0001 1001 ... */ /* 0 */ V(2, 10, 1), /* 322 */ /* 1 */ V(10, 2, 1), /* 0001 1010 ... */ /* 0 */ V(1, 10, 1), /* 324 */ /* 1 */ V(10, 1, 1), /* 0001 1011 ... */ /* 00 */ V(0, 10, 2), /* 326 */ /* 01 */ V(10, 0, 2), /* 10 */ V(6, 8, 1), /* 11 */ V(6, 8, 1), /* 0001 1100 ... */ /* 0 */ V(8, 6, 1), /* 330 */ /* 1 */ V(4, 9, 1), /* 0001 1101 ... */ /* 0 */ V(9, 4, 1), /* 332 */ /* 1 */ V(3, 9, 1), /* 0001 1110 ... */ /* 00 */ V(9, 3, 1), /* 334 */ /* 01 */ V(9, 3, 1), /* 10 */ V(7, 7, 2), /* 11 */ V(0, 9, 2), /* 0001 1111 ... */ /* 0 */ V(5, 8, 1), /* 338 */ /* 1 */ V(8, 5, 1), /* 0010 0000 ... */ /* 0 */ V(2, 9, 1), /* 340 */ /* 1 */ V(6, 7, 1), /* 0010 0001 ... */ /* 0 */ V(7, 6, 1), /* 342 */ /* 1 */ V(9, 2, 1), /* 0010 0011 ... */ /* 0 */ V(1, 9, 1), /* 344 */ /* 1 */ V(9, 0, 1), /* 0010 0100 ... */ /* 0 */ V(4, 8, 1), /* 346 */ /* 1 */ V(8, 4, 1), /* 0010 0101 ... */ /* 0 */ V(5, 7, 1), /* 348 */ /* 1 */ V(7, 5, 1), /* 0010 0110 ... */ /* 0 */ V(3, 8, 1), /* 350 */ /* 1 */ V(8, 3, 1), /* 0010 0111 ... */ /* 0 */ V(6, 6, 1), /* 352 */ /* 1 */ V(4, 7, 1), /* 0010 1100 ... */ /* 0 */ V(7, 4, 1), /* 354 */ /* 1 */ V(0, 8, 1), /* 0010 1101 ... */ /* 0 */ V(8, 0, 1), /* 356 */ /* 1 */ V(5, 6, 1), /* 0010 1110 ... */ /* 0 */ V(6, 5, 1), /* 358 */ /* 1 */ V(3, 7, 1), /* 0010 1111 ... */ /* 0 */ V(7, 3, 1), /* 360 */ /* 1 */ V(4, 6, 1), /* 0011 0110 ... */ /* 0 */ V(0, 7, 1), /* 362 */ /* 1 */ V(7, 0, 1), /* 0011 1110 ... */ /* 0 */ V(0, 6, 1), /* 364 */ /* 1 */ V(6, 0, 1), /* 0000 0000 0000 ... */ /* 0 */ V(15, 15, 1), /* 366 */ /* 1 */ V(14, 15, 1), /* 0000 0000 0001 ... */ /* 0 */ V(15, 14, 1), /* 368 */ /* 1 */ V(13, 15, 1), /* 0000 0000 0011 ... */ /* 0 */ V(15, 13, 1), /* 370 */ /* 1 */ V(12, 15, 1), /* 0000 0000 0100 ... */ /* 0 */ V(15, 12, 1), /* 372 */ /* 1 */ V(13, 14, 1), /* 0000 0000 0101 ... */ /* 0 */ V(14, 13, 1), /* 374 */ /* 1 */ V(11, 15, 1), /* 0000 0000 0111 ... */ /* 0 */ V(12, 14, 1), /* 376 */ /* 1 */ V(14, 12, 1), /* 0000 0001 1111 ... */ /* 0 */ V(10, 14, 1), /* 378 */ /* 1 */ V(0, 15, 1) }; static union huffpair const hufftab16[] = { /* 0000 */ PTR(16, 4), /* 0001 */ PTR(32, 4), /* 0010 */ PTR(48, 4), /* 0011 */ PTR(64, 2), /* 0100 */ V(1, 1, 4), /* 0101 */ V(0, 1, 4), /* 0110 */ V(1, 0, 3), /* 0111 */ V(1, 0, 3), /* 1000 */ V(0, 0, 1), /* 1001 */ V(0, 0, 1), /* 1010 */ V(0, 0, 1), /* 1011 */ V(0, 0, 1), /* 1100 */ V(0, 0, 1), /* 1101 */ V(0, 0, 1), /* 1110 */ V(0, 0, 1), /* 1111 */ V(0, 0, 1), /* 0000 ... */ /* 0000 */ PTR(68, 3), /* 16 */ /* 0001 */ PTR(76, 3), /* 0010 */ PTR(84, 2), /* 0011 */ V(15, 15, 4), /* 0100 */ PTR(88, 2), /* 0101 */ PTR(92, 1), /* 0110 */ PTR(94, 4), /* 0111 */ V(15, 2, 4), /* 1000 */ PTR(110, 1), /* 1001 */ V(1, 15, 4), /* 1010 */ V(15, 1, 4), /* 1011 */ PTR(112, 4), /* 1100 */ PTR(128, 4), /* 1101 */ PTR(144, 4), /* 1110 */ PTR(160, 4), /* 1111 */ PTR(176, 4), /* 0001 ... */ /* 0000 */ PTR(192, 4), /* 32 */ /* 0001 */ PTR(208, 3), /* 0010 */ PTR(216, 3), /* 0011 */ PTR(224, 3), /* 0100 */ PTR(232, 3), /* 0101 */ PTR(240, 3), /* 0110 */ PTR(248, 3), /* 0111 */ PTR(256, 3), /* 1000 */ PTR(264, 2), /* 1001 */ PTR(268, 2), /* 1010 */ PTR(272, 1), /* 1011 */ PTR(274, 2), /* 1100 */ PTR(278, 2), /* 1101 */ PTR(282, 1), /* 1110 */ V(5, 1, 4), /* 1111 */ PTR(284, 1), /* 0010 ... */ /* 0000 */ PTR(286, 1), /* 48 */ /* 0001 */ PTR(288, 1), /* 0010 */ PTR(290, 1), /* 0011 */ V(1, 4, 4), /* 0100 */ V(4, 1, 4), /* 0101 */ PTR(292, 1), /* 0110 */ V(2, 3, 4), /* 0111 */ V(3, 2, 4), /* 1000 */ V(1, 3, 3), /* 1001 */ V(1, 3, 3), /* 1010 */ V(3, 1, 3), /* 1011 */ V(3, 1, 3), /* 1100 */ V(0, 3, 4), /* 1101 */ V(3, 0, 4), /* 1110 */ V(2, 2, 3), /* 1111 */ V(2, 2, 3), /* 0011 ... */ /* 00 */ V(1, 2, 2), /* 64 */ /* 01 */ V(2, 1, 2), /* 10 */ V(0, 2, 2), /* 11 */ V(2, 0, 2), /* 0000 0000 ... */ /* 000 */ V(14, 15, 3), /* 68 */ /* 001 */ V(15, 14, 3), /* 010 */ V(13, 15, 3), /* 011 */ V(15, 13, 3), /* 100 */ V(12, 15, 3), /* 101 */ V(15, 12, 3), /* 110 */ V(11, 15, 3), /* 111 */ V(15, 11, 3), /* 0000 0001 ... */ /* 000 */ V(10, 15, 2), /* 76 */ /* 001 */ V(10, 15, 2), /* 010 */ V(15, 10, 3), /* 011 */ V(9, 15, 3), /* 100 */ V(15, 9, 3), /* 101 */ V(15, 8, 3), /* 110 */ V(8, 15, 2), /* 111 */ V(8, 15, 2), /* 0000 0010 ... */ /* 00 */ V(7, 15, 2), /* 84 */ /* 01 */ V(15, 7, 2), /* 10 */ V(6, 15, 2), /* 11 */ V(15, 6, 2), /* 0000 0100 ... */ /* 00 */ V(5, 15, 2), /* 88 */ /* 01 */ V(15, 5, 2), /* 10 */ V(4, 15, 1), /* 11 */ V(4, 15, 1), /* 0000 0101 ... */ /* 0 */ V(15, 4, 1), /* 92 */ /* 1 */ V(15, 3, 1), /* 0000 0110 ... */ /* 0000 */ V(15, 0, 1), /* 94 */ /* 0001 */ V(15, 0, 1), /* 0010 */ V(15, 0, 1), /* 0011 */ V(15, 0, 1), /* 0100 */ V(15, 0, 1), /* 0101 */ V(15, 0, 1), /* 0110 */ V(15, 0, 1), /* 0111 */ V(15, 0, 1), /* 1000 */ V(3, 15, 2), /* 1001 */ V(3, 15, 2), /* 1010 */ V(3, 15, 2), /* 1011 */ V(3, 15, 2), /* 1100 */ PTR(294, 4), /* 1101 */ PTR(310, 3), /* 1110 */ PTR(318, 3), /* 1111 */ PTR(326, 3), /* 0000 1000 ... */ /* 0 */ V(2, 15, 1), /* 110 */ /* 1 */ V(0, 15, 1), /* 0000 1011 ... */ /* 0000 */ PTR(334, 2), /* 112 */ /* 0001 */ PTR(338, 2), /* 0010 */ PTR(342, 2), /* 0011 */ PTR(346, 1), /* 0100 */ PTR(348, 2), /* 0101 */ PTR(352, 2), /* 0110 */ PTR(356, 1), /* 0111 */ PTR(358, 2), /* 1000 */ PTR(362, 2), /* 1001 */ PTR(366, 2), /* 1010 */ PTR(370, 2), /* 1011 */ V(14, 3, 4), /* 1100 */ PTR(374, 1), /* 1101 */ PTR(376, 1), /* 1110 */ PTR(378, 1), /* 1111 */ PTR(380, 1), /* 0000 1100 ... */ /* 0000 */ PTR(382, 1), /* 128 */ /* 0001 */ PTR(384, 1), /* 0010 */ PTR(386, 1), /* 0011 */ V(0, 13, 4), /* 0100 */ PTR(388, 1), /* 0101 */ PTR(390, 1), /* 0110 */ PTR(392, 1), /* 0111 */ V(3, 12, 4), /* 1000 */ PTR(394, 1), /* 1001 */ V(1, 12, 4), /* 1010 */ V(12, 0, 4), /* 1011 */ PTR(396, 1), /* 1100 */ V(14, 2, 3), /* 1101 */ V(14, 2, 3), /* 1110 */ V(2, 14, 4), /* 1111 */ V(1, 14, 4), /* 0000 1101 ... */ /* 0000 */ V(13, 3, 4), /* 144 */ /* 0001 */ V(2, 13, 4), /* 0010 */ V(13, 2, 4), /* 0011 */ V(13, 1, 4), /* 0100 */ V(3, 11, 4), /* 0101 */ PTR(398, 1), /* 0110 */ V(1, 13, 3), /* 0111 */ V(1, 13, 3), /* 1000 */ V(12, 4, 4), /* 1001 */ V(6, 11, 4), /* 1010 */ V(12, 3, 4), /* 1011 */ V(10, 7, 4), /* 1100 */ V(2, 12, 3), /* 1101 */ V(2, 12, 3), /* 1110 */ V(12, 2, 4), /* 1111 */ V(11, 5, 4), /* 0000 1110 ... */ /* 0000 */ V(12, 1, 4), /* 160 */ /* 0001 */ V(0, 12, 4), /* 0010 */ V(4, 11, 4), /* 0011 */ V(11, 4, 4), /* 0100 */ V(6, 10, 4), /* 0101 */ V(10, 6, 4), /* 0110 */ V(11, 3, 3), /* 0111 */ V(11, 3, 3), /* 1000 */ V(5, 10, 4), /* 1001 */ V(10, 5, 4), /* 1010 */ V(2, 11, 3), /* 1011 */ V(2, 11, 3), /* 1100 */ V(11, 2, 3), /* 1101 */ V(11, 2, 3), /* 1110 */ V(1, 11, 3), /* 1111 */ V(1, 11, 3), /* 0000 1111 ... */ /* 0000 */ V(11, 1, 3), /* 176 */ /* 0001 */ V(11, 1, 3), /* 0010 */ V(0, 11, 4), /* 0011 */ V(11, 0, 4), /* 0100 */ V(6, 9, 4), /* 0101 */ V(9, 6, 4), /* 0110 */ V(4, 10, 4), /* 0111 */ V(10, 4, 4), /* 1000 */ V(7, 8, 4), /* 1001 */ V(8, 7, 4), /* 1010 */ V(10, 3, 3), /* 1011 */ V(10, 3, 3), /* 1100 */ V(3, 10, 4), /* 1101 */ V(5, 9, 4), /* 1110 */ V(2, 10, 3), /* 1111 */ V(2, 10, 3), /* 0001 0000 ... */ /* 0000 */ V(9, 5, 4), /* 192 */ /* 0001 */ V(6, 8, 4), /* 0010 */ V(10, 1, 3), /* 0011 */ V(10, 1, 3), /* 0100 */ V(8, 6, 4), /* 0101 */ V(7, 7, 4), /* 0110 */ V(9, 4, 3), /* 0111 */ V(9, 4, 3), /* 1000 */ V(4, 9, 4), /* 1001 */ V(5, 7, 4), /* 1010 */ V(6, 7, 3), /* 1011 */ V(6, 7, 3), /* 1100 */ V(10, 2, 2), /* 1101 */ V(10, 2, 2), /* 1110 */ V(10, 2, 2), /* 1111 */ V(10, 2, 2), /* 0001 0001 ... */ /* 000 */ V(1, 10, 2), /* 208 */ /* 001 */ V(1, 10, 2), /* 010 */ V(0, 10, 3), /* 011 */ V(10, 0, 3), /* 100 */ V(3, 9, 3), /* 101 */ V(9, 3, 3), /* 110 */ V(5, 8, 3), /* 111 */ V(8, 5, 3), /* 0001 0010 ... */ /* 000 */ V(2, 9, 2), /* 216 */ /* 001 */ V(2, 9, 2), /* 010 */ V(9, 2, 2), /* 011 */ V(9, 2, 2), /* 100 */ V(7, 6, 3), /* 101 */ V(0, 9, 3), /* 110 */ V(1, 9, 2), /* 111 */ V(1, 9, 2), /* 0001 0011 ... */ /* 000 */ V(9, 1, 2), /* 224 */ /* 001 */ V(9, 1, 2), /* 010 */ V(9, 0, 3), /* 011 */ V(4, 8, 3), /* 100 */ V(8, 4, 3), /* 101 */ V(7, 5, 3), /* 110 */ V(3, 8, 3), /* 111 */ V(8, 3, 3), /* 0001 0100 ... */ /* 000 */ V(6, 6, 3), /* 232 */ /* 001 */ V(2, 8, 3), /* 010 */ V(8, 2, 2), /* 011 */ V(8, 2, 2), /* 100 */ V(4, 7, 3), /* 101 */ V(7, 4, 3), /* 110 */ V(1, 8, 2), /* 111 */ V(1, 8, 2), /* 0001 0101 ... */ /* 000 */ V(8, 1, 2), /* 240 */ /* 001 */ V(8, 1, 2), /* 010 */ V(8, 0, 2), /* 011 */ V(8, 0, 2), /* 100 */ V(0, 8, 3), /* 101 */ V(5, 6, 3), /* 110 */ V(3, 7, 2), /* 111 */ V(3, 7, 2), /* 0001 0110 ... */ /* 000 */ V(7, 3, 2), /* 248 */ /* 001 */ V(7, 3, 2), /* 010 */ V(6, 5, 3), /* 011 */ V(4, 6, 3), /* 100 */ V(2, 7, 2), /* 101 */ V(2, 7, 2), /* 110 */ V(7, 2, 2), /* 111 */ V(7, 2, 2), /* 0001 0111 ... */ /* 000 */ V(6, 4, 3), /* 256 */ /* 001 */ V(5, 5, 3), /* 010 */ V(0, 7, 2), /* 011 */ V(0, 7, 2), /* 100 */ V(1, 7, 1), /* 101 */ V(1, 7, 1), /* 110 */ V(1, 7, 1), /* 111 */ V(1, 7, 1), /* 0001 1000 ... */ /* 00 */ V(7, 1, 1), /* 264 */ /* 01 */ V(7, 1, 1), /* 10 */ V(7, 0, 2), /* 11 */ V(3, 6, 2), /* 0001 1001 ... */ /* 00 */ V(6, 3, 2), /* 268 */ /* 01 */ V(4, 5, 2), /* 10 */ V(5, 4, 2), /* 11 */ V(2, 6, 2), /* 0001 1010 ... */ /* 0 */ V(6, 2, 1), /* 272 */ /* 1 */ V(1, 6, 1), /* 0001 1011 ... */ /* 00 */ V(6, 1, 1), /* 274 */ /* 01 */ V(6, 1, 1), /* 10 */ V(0, 6, 2), /* 11 */ V(6, 0, 2), /* 0001 1100 ... */ /* 00 */ V(5, 3, 1), /* 278 */ /* 01 */ V(5, 3, 1), /* 10 */ V(3, 5, 2), /* 11 */ V(4, 4, 2), /* 0001 1101 ... */ /* 0 */ V(2, 5, 1), /* 282 */ /* 1 */ V(5, 2, 1), /* 0001 1111 ... */ /* 0 */ V(1, 5, 1), /* 284 */ /* 1 */ V(0, 5, 1), /* 0010 0000 ... */ /* 0 */ V(3, 4, 1), /* 286 */ /* 1 */ V(4, 3, 1), /* 0010 0001 ... */ /* 0 */ V(5, 0, 1), /* 288 */ /* 1 */ V(2, 4, 1), /* 0010 0010 ... */ /* 0 */ V(4, 2, 1), /* 290 */ /* 1 */ V(3, 3, 1), /* 0010 0101 ... */ /* 0 */ V(0, 4, 1), /* 292 */ /* 1 */ V(4, 0, 1), /* 0000 0110 1100 ... */ /* 0000 */ V(12, 14, 4), /* 294 */ /* 0001 */ PTR(400, 1), /* 0010 */ V(13, 14, 3), /* 0011 */ V(13, 14, 3), /* 0100 */ V(14, 9, 3), /* 0101 */ V(14, 9, 3), /* 0110 */ V(14, 10, 4), /* 0111 */ V(13, 9, 4), /* 1000 */ V(14, 14, 2), /* 1001 */ V(14, 14, 2), /* 1010 */ V(14, 14, 2), /* 1011 */ V(14, 14, 2), /* 1100 */ V(14, 13, 3), /* 1101 */ V(14, 13, 3), /* 1110 */ V(14, 11, 3), /* 1111 */ V(14, 11, 3), /* 0000 0110 1101 ... */ /* 000 */ V(11, 14, 2), /* 310 */ /* 001 */ V(11, 14, 2), /* 010 */ V(12, 13, 2), /* 011 */ V(12, 13, 2), /* 100 */ V(13, 12, 3), /* 101 */ V(13, 11, 3), /* 110 */ V(10, 14, 2), /* 111 */ V(10, 14, 2), /* 0000 0110 1110 ... */ /* 000 */ V(12, 12, 2), /* 318 */ /* 001 */ V(12, 12, 2), /* 010 */ V(10, 13, 3), /* 011 */ V(13, 10, 3), /* 100 */ V(7, 14, 3), /* 101 */ V(10, 12, 3), /* 110 */ V(12, 10, 2), /* 111 */ V(12, 10, 2), /* 0000 0110 1111 ... */ /* 000 */ V(12, 9, 3), /* 326 */ /* 001 */ V(7, 13, 3), /* 010 */ V(5, 14, 2), /* 011 */ V(5, 14, 2), /* 100 */ V(11, 13, 1), /* 101 */ V(11, 13, 1), /* 110 */ V(11, 13, 1), /* 111 */ V(11, 13, 1), /* 0000 1011 0000 ... */ /* 00 */ V(9, 14, 1), /* 334 */ /* 01 */ V(9, 14, 1), /* 10 */ V(11, 12, 2), /* 11 */ V(12, 11, 2), /* 0000 1011 0001 ... */ /* 00 */ V(8, 14, 2), /* 338 */ /* 01 */ V(14, 8, 2), /* 10 */ V(9, 13, 2), /* 11 */ V(14, 7, 2), /* 0000 1011 0010 ... */ /* 00 */ V(11, 11, 2), /* 342 */ /* 01 */ V(8, 13, 2), /* 10 */ V(13, 8, 2), /* 11 */ V(6, 14, 2), /* 0000 1011 0011 ... */ /* 0 */ V(14, 6, 1), /* 346 */ /* 1 */ V(9, 12, 1), /* 0000 1011 0100 ... */ /* 00 */ V(10, 11, 2), /* 348 */ /* 01 */ V(11, 10, 2), /* 10 */ V(14, 5, 2), /* 11 */ V(13, 7, 2), /* 0000 1011 0101 ... */ /* 00 */ V(4, 14, 1), /* 352 */ /* 01 */ V(4, 14, 1), /* 10 */ V(14, 4, 2), /* 11 */ V(8, 12, 2), /* 0000 1011 0110 ... */ /* 0 */ V(12, 8, 1), /* 356 */ /* 1 */ V(3, 14, 1), /* 0000 1011 0111 ... */ /* 00 */ V(6, 13, 1), /* 358 */ /* 01 */ V(6, 13, 1), /* 10 */ V(13, 6, 2), /* 11 */ V(9, 11, 2), /* 0000 1011 1000 ... */ /* 00 */ V(11, 9, 2), /* 362 */ /* 01 */ V(10, 10, 2), /* 10 */ V(14, 1, 1), /* 11 */ V(14, 1, 1), /* 0000 1011 1001 ... */ /* 00 */ V(13, 4, 1), /* 366 */ /* 01 */ V(13, 4, 1), /* 10 */ V(11, 8, 2), /* 11 */ V(10, 9, 2), /* 0000 1011 1010 ... */ /* 00 */ V(7, 11, 1), /* 370 */ /* 01 */ V(7, 11, 1), /* 10 */ V(11, 7, 2), /* 11 */ V(13, 0, 2), /* 0000 1011 1100 ... */ /* 0 */ V(0, 14, 1), /* 374 */ /* 1 */ V(14, 0, 1), /* 0000 1011 1101 ... */ /* 0 */ V(5, 13, 1), /* 376 */ /* 1 */ V(13, 5, 1), /* 0000 1011 1110 ... */ /* 0 */ V(7, 12, 1), /* 378 */ /* 1 */ V(12, 7, 1), /* 0000 1011 1111 ... */ /* 0 */ V(4, 13, 1), /* 380 */ /* 1 */ V(8, 11, 1), /* 0000 1100 0000 ... */ /* 0 */ V(9, 10, 1), /* 382 */ /* 1 */ V(6, 12, 1), /* 0000 1100 0001 ... */ /* 0 */ V(12, 6, 1), /* 384 */ /* 1 */ V(3, 13, 1), /* 0000 1100 0010 ... */ /* 0 */ V(5, 12, 1), /* 386 */ /* 1 */ V(12, 5, 1), /* 0000 1100 0100 ... */ /* 0 */ V(8, 10, 1), /* 388 */ /* 1 */ V(10, 8, 1), /* 0000 1100 0101 ... */ /* 0 */ V(9, 9, 1), /* 390 */ /* 1 */ V(4, 12, 1), /* 0000 1100 0110 ... */ /* 0 */ V(11, 6, 1), /* 392 */ /* 1 */ V(7, 10, 1), /* 0000 1100 1000 ... */ /* 0 */ V(5, 11, 1), /* 394 */ /* 1 */ V(8, 9, 1), /* 0000 1100 1011 ... */ /* 0 */ V(9, 8, 1), /* 396 */ /* 1 */ V(7, 9, 1), /* 0000 1101 0101 ... */ /* 0 */ V(9, 7, 1), /* 398 */ /* 1 */ V(8, 8, 1), /* 0000 0110 1100 0001 ... */ /* 0 */ V(14, 12, 1), /* 400 */ /* 1 */ V(13, 13, 1) }; static union huffpair const hufftab24[] = { /* 0000 */ PTR(16, 4), /* 0001 */ PTR(32, 4), /* 0010 */ PTR(48, 4), /* 0011 */ V(15, 15, 4), /* 0100 */ PTR(64, 4), /* 0101 */ PTR(80, 4), /* 0110 */ PTR(96, 4), /* 0111 */ PTR(112, 4), /* 1000 */ PTR(128, 4), /* 1001 */ PTR(144, 4), /* 1010 */ PTR(160, 3), /* 1011 */ PTR(168, 2), /* 1100 */ V(1, 1, 4), /* 1101 */ V(0, 1, 4), /* 1110 */ V(1, 0, 4), /* 1111 */ V(0, 0, 4), /* 0000 ... */ /* 0000 */ V(14, 15, 4), /* 16 */ /* 0001 */ V(15, 14, 4), /* 0010 */ V(13, 15, 4), /* 0011 */ V(15, 13, 4), /* 0100 */ V(12, 15, 4), /* 0101 */ V(15, 12, 4), /* 0110 */ V(11, 15, 4), /* 0111 */ V(15, 11, 4), /* 1000 */ V(15, 10, 3), /* 1001 */ V(15, 10, 3), /* 1010 */ V(10, 15, 4), /* 1011 */ V(9, 15, 4), /* 1100 */ V(15, 9, 3), /* 1101 */ V(15, 9, 3), /* 1110 */ V(15, 8, 3), /* 1111 */ V(15, 8, 3), /* 0001 ... */ /* 0000 */ V(8, 15, 4), /* 32 */ /* 0001 */ V(7, 15, 4), /* 0010 */ V(15, 7, 3), /* 0011 */ V(15, 7, 3), /* 0100 */ V(6, 15, 3), /* 0101 */ V(6, 15, 3), /* 0110 */ V(15, 6, 3), /* 0111 */ V(15, 6, 3), /* 1000 */ V(5, 15, 3), /* 1001 */ V(5, 15, 3), /* 1010 */ V(15, 5, 3), /* 1011 */ V(15, 5, 3), /* 1100 */ V(4, 15, 3), /* 1101 */ V(4, 15, 3), /* 1110 */ V(15, 4, 3), /* 1111 */ V(15, 4, 3), /* 0010 ... */ /* 0000 */ V(3, 15, 3), /* 48 */ /* 0001 */ V(3, 15, 3), /* 0010 */ V(15, 3, 3), /* 0011 */ V(15, 3, 3), /* 0100 */ V(2, 15, 3), /* 0101 */ V(2, 15, 3), /* 0110 */ V(15, 2, 3), /* 0111 */ V(15, 2, 3), /* 1000 */ V(15, 1, 3), /* 1001 */ V(15, 1, 3), /* 1010 */ V(1, 15, 4), /* 1011 */ V(15, 0, 4), /* 1100 */ PTR(172, 3), /* 1101 */ PTR(180, 3), /* 1110 */ PTR(188, 3), /* 1111 */ PTR(196, 3), /* 0100 ... */ /* 0000 */ PTR(204, 4), /* 64 */ /* 0001 */ PTR(220, 3), /* 0010 */ PTR(228, 3), /* 0011 */ PTR(236, 3), /* 0100 */ PTR(244, 2), /* 0101 */ PTR(248, 2), /* 0110 */ PTR(252, 2), /* 0111 */ PTR(256, 2), /* 1000 */ PTR(260, 2), /* 1001 */ PTR(264, 2), /* 1010 */ PTR(268, 2), /* 1011 */ PTR(272, 2), /* 1100 */ PTR(276, 2), /* 1101 */ PTR(280, 3), /* 1110 */ PTR(288, 2), /* 1111 */ PTR(292, 2), /* 0101 ... */ /* 0000 */ PTR(296, 2), /* 80 */ /* 0001 */ PTR(300, 3), /* 0010 */ PTR(308, 2), /* 0011 */ PTR(312, 3), /* 0100 */ PTR(320, 1), /* 0101 */ PTR(322, 2), /* 0110 */ PTR(326, 2), /* 0111 */ PTR(330, 1), /* 1000 */ PTR(332, 2), /* 1001 */ PTR(336, 1), /* 1010 */ PTR(338, 1), /* 1011 */ PTR(340, 1), /* 1100 */ PTR(342, 1), /* 1101 */ PTR(344, 1), /* 1110 */ PTR(346, 1), /* 1111 */ PTR(348, 1), /* 0110 ... */ /* 0000 */ PTR(350, 1), /* 96 */ /* 0001 */ PTR(352, 1), /* 0010 */ PTR(354, 1), /* 0011 */ PTR(356, 1), /* 0100 */ PTR(358, 1), /* 0101 */ PTR(360, 1), /* 0110 */ PTR(362, 1), /* 0111 */ PTR(364, 1), /* 1000 */ PTR(366, 1), /* 1001 */ PTR(368, 1), /* 1010 */ PTR(370, 2), /* 1011 */ PTR(374, 1), /* 1100 */ PTR(376, 2), /* 1101 */ V(7, 3, 4), /* 1110 */ PTR(380, 1), /* 1111 */ V(7, 2, 4), /* 0111 ... */ /* 0000 */ V(4, 6, 4), /* 112 */ /* 0001 */ V(6, 4, 4), /* 0010 */ V(5, 5, 4), /* 0011 */ V(7, 1, 4), /* 0100 */ V(3, 6, 4), /* 0101 */ V(6, 3, 4), /* 0110 */ V(4, 5, 4), /* 0111 */ V(5, 4, 4), /* 1000 */ V(2, 6, 4), /* 1001 */ V(6, 2, 4), /* 1010 */ V(1, 6, 4), /* 1011 */ V(6, 1, 4), /* 1100 */ PTR(382, 1), /* 1101 */ V(3, 5, 4), /* 1110 */ V(5, 3, 4), /* 1111 */ V(4, 4, 4), /* 1000 ... */ /* 0000 */ V(2, 5, 4), /* 128 */ /* 0001 */ V(5, 2, 4), /* 0010 */ V(1, 5, 4), /* 0011 */ PTR(384, 1), /* 0100 */ V(5, 1, 3), /* 0101 */ V(5, 1, 3), /* 0110 */ V(3, 4, 4), /* 0111 */ V(4, 3, 4), /* 1000 */ V(2, 4, 3), /* 1001 */ V(2, 4, 3), /* 1010 */ V(4, 2, 3), /* 1011 */ V(4, 2, 3), /* 1100 */ V(3, 3, 3), /* 1101 */ V(3, 3, 3), /* 1110 */ V(1, 4, 3), /* 1111 */ V(1, 4, 3), /* 1001 ... */ /* 0000 */ V(4, 1, 3), /* 144 */ /* 0001 */ V(4, 1, 3), /* 0010 */ V(0, 4, 4), /* 0011 */ V(4, 0, 4), /* 0100 */ V(2, 3, 3), /* 0101 */ V(2, 3, 3), /* 0110 */ V(3, 2, 3), /* 0111 */ V(3, 2, 3), /* 1000 */ V(1, 3, 2), /* 1001 */ V(1, 3, 2), /* 1010 */ V(1, 3, 2), /* 1011 */ V(1, 3, 2), /* 1100 */ V(3, 1, 2), /* 1101 */ V(3, 1, 2), /* 1110 */ V(3, 1, 2), /* 1111 */ V(3, 1, 2), /* 1010 ... */ /* 000 */ V(0, 3, 3), /* 160 */ /* 001 */ V(3, 0, 3), /* 010 */ V(2, 2, 2), /* 011 */ V(2, 2, 2), /* 100 */ V(1, 2, 1), /* 101 */ V(1, 2, 1), /* 110 */ V(1, 2, 1), /* 111 */ V(1, 2, 1), /* 1011 ... */ /* 00 */ V(2, 1, 1), /* 168 */ /* 01 */ V(2, 1, 1), /* 10 */ V(0, 2, 2), /* 11 */ V(2, 0, 2), /* 0010 1100 ... */ /* 000 */ V(0, 15, 1), /* 172 */ /* 001 */ V(0, 15, 1), /* 010 */ V(0, 15, 1), /* 011 */ V(0, 15, 1), /* 100 */ V(14, 14, 3), /* 101 */ V(13, 14, 3), /* 110 */ V(14, 13, 3), /* 111 */ V(12, 14, 3), /* 0010 1101 ... */ /* 000 */ V(14, 12, 3), /* 180 */ /* 001 */ V(13, 13, 3), /* 010 */ V(11, 14, 3), /* 011 */ V(14, 11, 3), /* 100 */ V(12, 13, 3), /* 101 */ V(13, 12, 3), /* 110 */ V(10, 14, 3), /* 111 */ V(14, 10, 3), /* 0010 1110 ... */ /* 000 */ V(11, 13, 3), /* 188 */ /* 001 */ V(13, 11, 3), /* 010 */ V(12, 12, 3), /* 011 */ V(9, 14, 3), /* 100 */ V(14, 9, 3), /* 101 */ V(10, 13, 3), /* 110 */ V(13, 10, 3), /* 111 */ V(11, 12, 3), /* 0010 1111 ... */ /* 000 */ V(12, 11, 3), /* 196 */ /* 001 */ V(8, 14, 3), /* 010 */ V(14, 8, 3), /* 011 */ V(9, 13, 3), /* 100 */ V(13, 9, 3), /* 101 */ V(7, 14, 3), /* 110 */ V(14, 7, 3), /* 111 */ V(10, 12, 3), /* 0100 0000 ... */ /* 0000 */ V(12, 10, 3), /* 204 */ /* 0001 */ V(12, 10, 3), /* 0010 */ V(11, 11, 3), /* 0011 */ V(11, 11, 3), /* 0100 */ V(8, 13, 3), /* 0101 */ V(8, 13, 3), /* 0110 */ V(13, 8, 3), /* 0111 */ V(13, 8, 3), /* 1000 */ V(0, 14, 4), /* 1001 */ V(14, 0, 4), /* 1010 */ V(0, 13, 3), /* 1011 */ V(0, 13, 3), /* 1100 */ V(14, 6, 2), /* 1101 */ V(14, 6, 2), /* 1110 */ V(14, 6, 2), /* 1111 */ V(14, 6, 2), /* 0100 0001 ... */ /* 000 */ V(6, 14, 3), /* 220 */ /* 001 */ V(9, 12, 3), /* 010 */ V(12, 9, 2), /* 011 */ V(12, 9, 2), /* 100 */ V(5, 14, 2), /* 101 */ V(5, 14, 2), /* 110 */ V(11, 10, 2), /* 111 */ V(11, 10, 2), /* 0100 0010 ... */ /* 000 */ V(14, 5, 2), /* 228 */ /* 001 */ V(14, 5, 2), /* 010 */ V(10, 11, 3), /* 011 */ V(7, 13, 3), /* 100 */ V(13, 7, 2), /* 101 */ V(13, 7, 2), /* 110 */ V(14, 4, 2), /* 111 */ V(14, 4, 2), /* 0100 0011 ... */ /* 000 */ V(8, 12, 2), /* 236 */ /* 001 */ V(8, 12, 2), /* 010 */ V(12, 8, 2), /* 011 */ V(12, 8, 2), /* 100 */ V(4, 14, 3), /* 101 */ V(2, 14, 3), /* 110 */ V(3, 14, 2), /* 111 */ V(3, 14, 2), /* 0100 0100 ... */ /* 00 */ V(6, 13, 2), /* 244 */ /* 01 */ V(13, 6, 2), /* 10 */ V(14, 3, 2), /* 11 */ V(9, 11, 2), /* 0100 0101 ... */ /* 00 */ V(11, 9, 2), /* 248 */ /* 01 */ V(10, 10, 2), /* 10 */ V(14, 2, 2), /* 11 */ V(1, 14, 2), /* 0100 0110 ... */ /* 00 */ V(14, 1, 2), /* 252 */ /* 01 */ V(5, 13, 2), /* 10 */ V(13, 5, 2), /* 11 */ V(7, 12, 2), /* 0100 0111 ... */ /* 00 */ V(12, 7, 2), /* 256 */ /* 01 */ V(4, 13, 2), /* 10 */ V(8, 11, 2), /* 11 */ V(11, 8, 2), /* 0100 1000 ... */ /* 00 */ V(13, 4, 2), /* 260 */ /* 01 */ V(9, 10, 2), /* 10 */ V(10, 9, 2), /* 11 */ V(6, 12, 2), /* 0100 1001 ... */ /* 00 */ V(12, 6, 2), /* 264 */ /* 01 */ V(3, 13, 2), /* 10 */ V(13, 3, 2), /* 11 */ V(2, 13, 2), /* 0100 1010 ... */ /* 00 */ V(13, 2, 2), /* 268 */ /* 01 */ V(1, 13, 2), /* 10 */ V(7, 11, 2), /* 11 */ V(11, 7, 2), /* 0100 1011 ... */ /* 00 */ V(13, 1, 2), /* 272 */ /* 01 */ V(5, 12, 2), /* 10 */ V(12, 5, 2), /* 11 */ V(8, 10, 2), /* 0100 1100 ... */ /* 00 */ V(10, 8, 2), /* 276 */ /* 01 */ V(9, 9, 2), /* 10 */ V(4, 12, 2), /* 11 */ V(12, 4, 2), /* 0100 1101 ... */ /* 000 */ V(6, 11, 2), /* 280 */ /* 001 */ V(6, 11, 2), /* 010 */ V(11, 6, 2), /* 011 */ V(11, 6, 2), /* 100 */ V(13, 0, 3), /* 101 */ V(0, 12, 3), /* 110 */ V(3, 12, 2), /* 111 */ V(3, 12, 2), /* 0100 1110 ... */ /* 00 */ V(12, 3, 2), /* 288 */ /* 01 */ V(7, 10, 2), /* 10 */ V(10, 7, 2), /* 11 */ V(2, 12, 2), /* 0100 1111 ... */ /* 00 */ V(12, 2, 2), /* 292 */ /* 01 */ V(5, 11, 2), /* 10 */ V(11, 5, 2), /* 11 */ V(1, 12, 2), /* 0101 0000 ... */ /* 00 */ V(8, 9, 2), /* 296 */ /* 01 */ V(9, 8, 2), /* 10 */ V(12, 1, 2), /* 11 */ V(4, 11, 2), /* 0101 0001 ... */ /* 000 */ V(12, 0, 3), /* 300 */ /* 001 */ V(0, 11, 3), /* 010 */ V(3, 11, 2), /* 011 */ V(3, 11, 2), /* 100 */ V(11, 0, 3), /* 101 */ V(0, 10, 3), /* 110 */ V(1, 10, 2), /* 111 */ V(1, 10, 2), /* 0101 0010 ... */ /* 00 */ V(11, 4, 1), /* 308 */ /* 01 */ V(11, 4, 1), /* 10 */ V(6, 10, 2), /* 11 */ V(10, 6, 2), /* 0101 0011 ... */ /* 000 */ V(7, 9, 2), /* 312 */ /* 001 */ V(7, 9, 2), /* 010 */ V(9, 7, 2), /* 011 */ V(9, 7, 2), /* 100 */ V(10, 0, 3), /* 101 */ V(0, 9, 3), /* 110 */ V(9, 0, 2), /* 111 */ V(9, 0, 2), /* 0101 0100 ... */ /* 0 */ V(11, 3, 1), /* 320 */ /* 1 */ V(8, 8, 1), /* 0101 0101 ... */ /* 00 */ V(2, 11, 2), /* 322 */ /* 01 */ V(5, 10, 2), /* 10 */ V(11, 2, 1), /* 11 */ V(11, 2, 1), /* 0101 0110 ... */ /* 00 */ V(10, 5, 2), /* 326 */ /* 01 */ V(1, 11, 2), /* 10 */ V(11, 1, 2), /* 11 */ V(6, 9, 2), /* 0101 0111 ... */ /* 0 */ V(9, 6, 1), /* 330 */ /* 1 */ V(10, 4, 1), /* 0101 1000 ... */ /* 00 */ V(4, 10, 2), /* 332 */ /* 01 */ V(7, 8, 2), /* 10 */ V(8, 7, 1), /* 11 */ V(8, 7, 1), /* 0101 1001 ... */ /* 0 */ V(3, 10, 1), /* 336 */ /* 1 */ V(10, 3, 1), /* 0101 1010 ... */ /* 0 */ V(5, 9, 1), /* 338 */ /* 1 */ V(9, 5, 1), /* 0101 1011 ... */ /* 0 */ V(2, 10, 1), /* 340 */ /* 1 */ V(10, 2, 1), /* 0101 1100 ... */ /* 0 */ V(10, 1, 1), /* 342 */ /* 1 */ V(6, 8, 1), /* 0101 1101 ... */ /* 0 */ V(8, 6, 1), /* 344 */ /* 1 */ V(7, 7, 1), /* 0101 1110 ... */ /* 0 */ V(4, 9, 1), /* 346 */ /* 1 */ V(9, 4, 1), /* 0101 1111 ... */ /* 0 */ V(3, 9, 1), /* 348 */ /* 1 */ V(9, 3, 1), /* 0110 0000 ... */ /* 0 */ V(5, 8, 1), /* 350 */ /* 1 */ V(8, 5, 1), /* 0110 0001 ... */ /* 0 */ V(2, 9, 1), /* 352 */ /* 1 */ V(6, 7, 1), /* 0110 0010 ... */ /* 0 */ V(7, 6, 1), /* 354 */ /* 1 */ V(9, 2, 1), /* 0110 0011 ... */ /* 0 */ V(1, 9, 1), /* 356 */ /* 1 */ V(9, 1, 1), /* 0110 0100 ... */ /* 0 */ V(4, 8, 1), /* 358 */ /* 1 */ V(8, 4, 1), /* 0110 0101 ... */ /* 0 */ V(5, 7, 1), /* 360 */ /* 1 */ V(7, 5, 1), /* 0110 0110 ... */ /* 0 */ V(3, 8, 1), /* 362 */ /* 1 */ V(8, 3, 1), /* 0110 0111 ... */ /* 0 */ V(6, 6, 1), /* 364 */ /* 1 */ V(2, 8, 1), /* 0110 1000 ... */ /* 0 */ V(8, 2, 1), /* 366 */ /* 1 */ V(1, 8, 1), /* 0110 1001 ... */ /* 0 */ V(4, 7, 1), /* 368 */ /* 1 */ V(7, 4, 1), /* 0110 1010 ... */ /* 00 */ V(8, 1, 1), /* 370 */ /* 01 */ V(8, 1, 1), /* 10 */ V(0, 8, 2), /* 11 */ V(8, 0, 2), /* 0110 1011 ... */ /* 0 */ V(5, 6, 1), /* 374 */ /* 1 */ V(6, 5, 1), /* 0110 1100 ... */ /* 00 */ V(1, 7, 1), /* 376 */ /* 01 */ V(1, 7, 1), /* 10 */ V(0, 7, 2), /* 11 */ V(7, 0, 2), /* 0110 1110 ... */ /* 0 */ V(3, 7, 1), /* 380 */ /* 1 */ V(2, 7, 1), /* 0111 1100 ... */ /* 0 */ V(0, 6, 1), /* 382 */ /* 1 */ V(6, 0, 1), /* 1000 0011 ... */ /* 0 */ V(0, 5, 1), /* 384 */ /* 1 */ V(5, 0, 1) }; # undef V # undef PTR /* external tables */ union huffquad const *const mad_huff_quad_table[2] = { hufftabA, hufftabB }; struct hufftable const mad_huff_pair_table[32] = { /* 0 */ { hufftab0, 0, 0 }, /* 1 */ { hufftab1, 0, 3 }, /* 2 */ { hufftab2, 0, 3 }, /* 3 */ { hufftab3, 0, 3 }, /* 4 */ { 0 /* not used */ }, /* 5 */ { hufftab5, 0, 3 }, /* 6 */ { hufftab6, 0, 4 }, /* 7 */ { hufftab7, 0, 4 }, /* 8 */ { hufftab8, 0, 4 }, /* 9 */ { hufftab9, 0, 4 }, /* 10 */ { hufftab10, 0, 4 }, /* 11 */ { hufftab11, 0, 4 }, /* 12 */ { hufftab12, 0, 4 }, /* 13 */ { hufftab13, 0, 4 }, /* 14 */ { 0 /* not used */ }, /* 15 */ { hufftab15, 0, 4 }, /* 16 */ { hufftab16, 1, 4 }, /* 17 */ { hufftab16, 2, 4 }, /* 18 */ { hufftab16, 3, 4 }, /* 19 */ { hufftab16, 4, 4 }, /* 20 */ { hufftab16, 6, 4 }, /* 21 */ { hufftab16, 8, 4 }, /* 22 */ { hufftab16, 10, 4 }, /* 23 */ { hufftab16, 13, 4 }, /* 24 */ { hufftab24, 4, 4 }, /* 25 */ { hufftab24, 5, 4 }, /* 26 */ { hufftab24, 6, 4 }, /* 27 */ { hufftab24, 7, 4 }, /* 28 */ { hufftab24, 8, 4 }, /* 29 */ { hufftab24, 9, 4 }, /* 30 */ { hufftab24, 11, 4 }, /* 31 */ { hufftab24, 13, 4 } }; praat-6.0.04/external/mp3/mad_huffman.h000066400000000000000000000035061261542461700176630ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: huffman.h,v 1.11 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBMAD_HUFFMAN_H # define LIBMAD_HUFFMAN_H union huffquad { struct { unsigned short final : 1; unsigned short bits : 3; unsigned short offset : 12; } ptr; struct { unsigned short final : 1; unsigned short hlen : 3; unsigned short v : 1; unsigned short w : 1; unsigned short x : 1; unsigned short y : 1; } value; unsigned short final : 1; }; union huffpair { struct { unsigned short final : 1; unsigned short bits : 3; unsigned short offset : 12; } ptr; struct { unsigned short final : 1; unsigned short hlen : 3; unsigned short x : 4; unsigned short y : 4; } value; unsigned short final : 1; }; struct hufftable { union huffpair const *table; unsigned short linbits; unsigned short startbits; }; extern union huffquad const *const mad_huff_quad_table[2]; extern struct hufftable const mad_huff_pair_table[32]; # endif praat-6.0.04/external/mp3/mad_imdct_s.dat000066400000000000000000000050371261542461700202030ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: imdct_s.dat,v 1.8 2004/01/23 09:41:32 rob Exp $ */ /* 0 */ { MAD_F(0x09bd7ca0) /* 0.608761429 */, -MAD_F(0x0ec835e8) /* -0.923879533 */, -MAD_F(0x0216a2a2) /* -0.130526192 */, MAD_F(0x0fdcf549) /* 0.991444861 */, -MAD_F(0x061f78aa) /* -0.382683432 */, -MAD_F(0x0cb19346) /* -0.793353340 */ }, /* 6 */ { -MAD_F(0x0cb19346) /* -0.793353340 */, MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x0fdcf549) /* 0.991444861 */, MAD_F(0x0216a2a2) /* 0.130526192 */, -MAD_F(0x0ec835e8) /* -0.923879533 */, -MAD_F(0x09bd7ca0) /* -0.608761429 */ }, /* 1 */ { MAD_F(0x061f78aa) /* 0.382683432 */, -MAD_F(0x0ec835e8) /* -0.923879533 */, MAD_F(0x0ec835e8) /* 0.923879533 */, -MAD_F(0x061f78aa) /* -0.382683432 */, -MAD_F(0x061f78aa) /* -0.382683432 */, MAD_F(0x0ec835e8) /* 0.923879533 */ }, /* 7 */ { -MAD_F(0x0ec835e8) /* -0.923879533 */, -MAD_F(0x061f78aa) /* -0.382683432 */, MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x061f78aa) /* 0.382683432 */ }, /* 2 */ { MAD_F(0x0216a2a2) /* 0.130526192 */, -MAD_F(0x061f78aa) /* -0.382683432 */, MAD_F(0x09bd7ca0) /* 0.608761429 */, -MAD_F(0x0cb19346) /* -0.793353340 */, MAD_F(0x0ec835e8) /* 0.923879533 */, -MAD_F(0x0fdcf549) /* -0.991444861 */ }, /* 8 */ { -MAD_F(0x0fdcf549) /* -0.991444861 */, -MAD_F(0x0ec835e8) /* -0.923879533 */, -MAD_F(0x0cb19346) /* -0.793353340 */, -MAD_F(0x09bd7ca0) /* -0.608761429 */, -MAD_F(0x061f78aa) /* -0.382683432 */, -MAD_F(0x0216a2a2) /* -0.130526192 */ } praat-6.0.04/external/mp3/mad_layer12.c000066400000000000000000000325431261542461700175140ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: layer12.c,v 1.17 2004/02/05 09:02:39 rob Exp $ */ /*# ifdef HAVE_CONFIG_H*/ # include "mad_config.h" /*# endif*/ # include "mad_global.h" # ifdef HAVE_LIMITS_H # include # else # define CHAR_BIT 8 # endif # include "mad_fixed.h" # include "mad_bit.h" # include "mad_stream.h" # include "mad_frame.h" # include "mad_layer12.h" /* * scalefactor table * used in both Layer I and Layer II decoding */ static mad_fixed_t const sf_table[64] = { # include "mad_sf_table.dat" }; /* --- Layer I ------------------------------------------------------------- */ /* linear scaling table */ static mad_fixed_t const linear_table[14] = { MAD_F(0x15555555), /* 2^2 / (2^2 - 1) == 1.33333333333333 */ MAD_F(0x12492492), /* 2^3 / (2^3 - 1) == 1.14285714285714 */ MAD_F(0x11111111), /* 2^4 / (2^4 - 1) == 1.06666666666667 */ MAD_F(0x10842108), /* 2^5 / (2^5 - 1) == 1.03225806451613 */ MAD_F(0x10410410), /* 2^6 / (2^6 - 1) == 1.01587301587302 */ MAD_F(0x10204081), /* 2^7 / (2^7 - 1) == 1.00787401574803 */ MAD_F(0x10101010), /* 2^8 / (2^8 - 1) == 1.00392156862745 */ MAD_F(0x10080402), /* 2^9 / (2^9 - 1) == 1.00195694716243 */ MAD_F(0x10040100), /* 2^10 / (2^10 - 1) == 1.00097751710655 */ MAD_F(0x10020040), /* 2^11 / (2^11 - 1) == 1.00048851978505 */ MAD_F(0x10010010), /* 2^12 / (2^12 - 1) == 1.00024420024420 */ MAD_F(0x10008004), /* 2^13 / (2^13 - 1) == 1.00012208521548 */ MAD_F(0x10004001), /* 2^14 / (2^14 - 1) == 1.00006103888177 */ MAD_F(0x10002000) /* 2^15 / (2^15 - 1) == 1.00003051850948 */ }; /* * NAME: I_sample() * DESCRIPTION: decode one requantized Layer I sample from a bitstream */ static mad_fixed_t I_sample(struct mad_bitptr *ptr, unsigned int nb) { mad_fixed_t sample; sample = mad_bit_read(ptr, nb); /* invert most significant bit, extend sign, then scale to fixed format */ sample ^= 1 << (nb - 1); sample |= -(sample & (1 << (nb - 1))); sample <<= MAD_F_FRACBITS - (nb - 1); /* requantize the sample */ /* s'' = (2^nb / (2^nb - 1)) * (s''' + 2^(-nb + 1)) */ sample += MAD_F_ONE >> (nb - 1); return mad_f_mul(sample, linear_table[nb - 2]); /* s' = factor * s'' */ /* (to be performed by caller) */ } /* * NAME: layer->I() * DESCRIPTION: decode a single Layer I frame */ int mad_layer_I(struct mad_stream *stream, struct mad_frame *frame) { struct mad_header *header = &frame->header; unsigned int nch, bound, ch, s, sb, nb; unsigned char allocation[2][32], scalefactor[2][32]; nch = MAD_NCHANNELS(header); bound = 32; if (header->mode == MAD_MODE_JOINT_STEREO) { header->flags |= MAD_FLAG_I_STEREO; bound = 4 + header->mode_extension * 4; } /* check CRC word */ if (header->flags & MAD_FLAG_PROTECTION) { header->crc_check = mad_bit_crc(stream->ptr, 4 * (bound * nch + (32 - bound)), header->crc_check); if (header->crc_check != header->crc_target && !(frame->options & MAD_OPTION_IGNORECRC)) { stream->error = MAD_ERROR_BADCRC; return -1; } } /* decode bit allocations */ for (sb = 0; sb < bound; ++sb) { for (ch = 0; ch < nch; ++ch) { nb = mad_bit_read(&stream->ptr, 4); if (nb == 15) { stream->error = MAD_ERROR_BADBITALLOC; return -1; } allocation[ch][sb] = nb ? nb + 1 : 0; } } for (sb = bound; sb < 32; ++sb) { nb = mad_bit_read(&stream->ptr, 4); if (nb == 15) { stream->error = MAD_ERROR_BADBITALLOC; return -1; } allocation[0][sb] = allocation[1][sb] = nb ? nb + 1 : 0; } /* decode scalefactors */ for (sb = 0; sb < 32; ++sb) { for (ch = 0; ch < nch; ++ch) { if (allocation[ch][sb]) { scalefactor[ch][sb] = mad_bit_read(&stream->ptr, 6); # if defined(OPT_STRICT) /* * Scalefactor index 63 does not appear in Table B.1 of * ISO/IEC 11172-3. Nonetheless, other implementations accept it, * so we only reject it if OPT_STRICT is defined. */ if (scalefactor[ch][sb] == 63) { stream->error = MAD_ERROR_BADSCALEFACTOR; return -1; } # endif } } } /* decode samples */ for (s = 0; s < 12; ++s) { for (sb = 0; sb < bound; ++sb) { for (ch = 0; ch < nch; ++ch) { nb = allocation[ch][sb]; frame->sbsample[ch][s][sb] = nb ? mad_f_mul(I_sample(&stream->ptr, nb), sf_table[scalefactor[ch][sb]]) : 0; } } for (sb = bound; sb < 32; ++sb) { if ((nb = allocation[0][sb])) { mad_fixed_t sample; sample = I_sample(&stream->ptr, nb); for (ch = 0; ch < nch; ++ch) { frame->sbsample[ch][s][sb] = mad_f_mul(sample, sf_table[scalefactor[ch][sb]]); } } else { for (ch = 0; ch < nch; ++ch) frame->sbsample[ch][s][sb] = 0; } } } return 0; } /* --- Layer II ------------------------------------------------------------ */ /* possible quantization per subband table */ static struct { unsigned int sblimit; unsigned char const offsets[30]; } const sbquant_table[5] = { /* ISO/IEC 11172-3 Table B.2a */ { 27, { 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, /* 0 */ 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0 } }, /* ISO/IEC 11172-3 Table B.2b */ { 30, { 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, /* 1 */ 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0 } }, /* ISO/IEC 11172-3 Table B.2c */ { 8, { 5, 5, 2, 2, 2, 2, 2, 2 } }, /* 2 */ /* ISO/IEC 11172-3 Table B.2d */ { 12, { 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 } }, /* 3 */ /* ISO/IEC 13818-3 Table B.1 */ { 30, { 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, /* 4 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } } }; /* bit allocation table */ static struct { unsigned short nbal; unsigned short offset; } const bitalloc_table[8] = { { 2, 0 }, /* 0 */ { 2, 3 }, /* 1 */ { 3, 3 }, /* 2 */ { 3, 1 }, /* 3 */ { 4, 2 }, /* 4 */ { 4, 3 }, /* 5 */ { 4, 4 }, /* 6 */ { 4, 5 } /* 7 */ }; /* offsets into quantization class table */ static unsigned char const offset_table[6][15] = { { 0, 1, 16 }, /* 0 */ { 0, 1, 2, 3, 4, 5, 16 }, /* 1 */ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }, /* 2 */ { 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, /* 3 */ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16 }, /* 4 */ { 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 } /* 5 */ }; /* quantization class table */ static struct quantclass { unsigned short nlevels; unsigned char group; unsigned char bits; mad_fixed_t C; mad_fixed_t D; } const qc_table[17] = { # include "mad_qc_table.dat" }; /* * NAME: II_samples() * DESCRIPTION: decode three requantized Layer II samples from a bitstream */ static void II_samples(struct mad_bitptr *ptr, struct quantclass const *quantclass, mad_fixed_t output[3]) { unsigned int nb, s, sample[3]; if ((nb = quantclass->group)) { unsigned int c, nlevels; /* degrouping */ c = mad_bit_read(ptr, quantclass->bits); nlevels = quantclass->nlevels; for (s = 0; s < 3; ++s) { sample[s] = c % nlevels; c /= nlevels; } } else { nb = quantclass->bits; for (s = 0; s < 3; ++s) sample[s] = mad_bit_read(ptr, nb); } for (s = 0; s < 3; ++s) { mad_fixed_t requantized; /* invert most significant bit, extend sign, then scale to fixed format */ requantized = sample[s] ^ (1 << (nb - 1)); requantized |= -(requantized & (1 << (nb - 1))); requantized <<= MAD_F_FRACBITS - (nb - 1); /* requantize the sample */ /* s'' = C * (s''' + D) */ output[s] = mad_f_mul(requantized + quantclass->D, quantclass->C); /* s' = factor * s'' */ /* (to be performed by caller) */ } } /* * NAME: layer->II() * DESCRIPTION: decode a single Layer II frame */ int mad_layer_II(struct mad_stream *stream, struct mad_frame *frame) { struct mad_header *header = &frame->header; struct mad_bitptr start; unsigned int index, sblimit, nbal, nch, bound, gr, ch, s, sb; unsigned char const *offsets; unsigned char allocation[2][32], scfsi[2][32], scalefactor[2][32][3]; mad_fixed_t samples[3]; nch = MAD_NCHANNELS(header); if (header->flags & MAD_FLAG_LSF_EXT) index = 4; else if (header->flags & MAD_FLAG_FREEFORMAT) goto freeformat; else { unsigned long bitrate_per_channel; bitrate_per_channel = header->bitrate; if (nch == 2) { bitrate_per_channel /= 2; # if defined(OPT_STRICT) /* * ISO/IEC 11172-3 allows only single channel mode for 32, 48, 56, and * 80 kbps bitrates in Layer II, but some encoders ignore this * restriction. We enforce it if OPT_STRICT is defined. */ if (bitrate_per_channel <= 28000 || bitrate_per_channel == 40000) { stream->error = MAD_ERROR_BADMODE; return -1; } # endif } else { /* nch == 1 */ if (bitrate_per_channel > 192000) { /* * ISO/IEC 11172-3 does not allow single channel mode for 224, 256, * 320, or 384 kbps bitrates in Layer II. */ stream->error = MAD_ERROR_BADMODE; return -1; } } if (bitrate_per_channel <= 48000) index = (header->samplerate == 32000) ? 3 : 2; else if (bitrate_per_channel <= 80000) index = 0; else { freeformat: index = (header->samplerate == 48000) ? 0 : 1; } } sblimit = sbquant_table[index].sblimit; offsets = sbquant_table[index].offsets; bound = 32; if (header->mode == MAD_MODE_JOINT_STEREO) { header->flags |= MAD_FLAG_I_STEREO; bound = 4 + header->mode_extension * 4; } if (bound > sblimit) bound = sblimit; start = stream->ptr; /* decode bit allocations */ for (sb = 0; sb < bound; ++sb) { nbal = bitalloc_table[offsets[sb]].nbal; for (ch = 0; ch < nch; ++ch) allocation[ch][sb] = mad_bit_read(&stream->ptr, nbal); } for (sb = bound; sb < sblimit; ++sb) { nbal = bitalloc_table[offsets[sb]].nbal; allocation[0][sb] = allocation[1][sb] = mad_bit_read(&stream->ptr, nbal); } /* decode scalefactor selection info */ for (sb = 0; sb < sblimit; ++sb) { for (ch = 0; ch < nch; ++ch) { if (allocation[ch][sb]) scfsi[ch][sb] = mad_bit_read(&stream->ptr, 2); } } /* check CRC word */ if (header->flags & MAD_FLAG_PROTECTION) { header->crc_check = mad_bit_crc(start, mad_bit_length(&start, &stream->ptr), header->crc_check); if (header->crc_check != header->crc_target && !(frame->options & MAD_OPTION_IGNORECRC)) { stream->error = MAD_ERROR_BADCRC; return -1; } } /* decode scalefactors */ for (sb = 0; sb < sblimit; ++sb) { for (ch = 0; ch < nch; ++ch) { if (allocation[ch][sb]) { scalefactor[ch][sb][0] = mad_bit_read(&stream->ptr, 6); switch (scfsi[ch][sb]) { case 2: scalefactor[ch][sb][2] = scalefactor[ch][sb][1] = scalefactor[ch][sb][0]; break; case 0: scalefactor[ch][sb][1] = mad_bit_read(&stream->ptr, 6); /* fall through */ case 1: case 3: scalefactor[ch][sb][2] = mad_bit_read(&stream->ptr, 6); } if (scfsi[ch][sb] & 1) scalefactor[ch][sb][1] = scalefactor[ch][sb][scfsi[ch][sb] - 1]; # if defined(OPT_STRICT) /* * Scalefactor index 63 does not appear in Table B.1 of * ISO/IEC 11172-3. Nonetheless, other implementations accept it, * so we only reject it if OPT_STRICT is defined. */ if (scalefactor[ch][sb][0] == 63 || scalefactor[ch][sb][1] == 63 || scalefactor[ch][sb][2] == 63) { stream->error = MAD_ERROR_BADSCALEFACTOR; return -1; } # endif } } } /* decode samples */ for (gr = 0; gr < 12; ++gr) { for (sb = 0; sb < bound; ++sb) { for (ch = 0; ch < nch; ++ch) { if ((index = allocation[ch][sb])) { index = offset_table[bitalloc_table[offsets[sb]].offset][index - 1]; II_samples(&stream->ptr, &qc_table[index], samples); for (s = 0; s < 3; ++s) { frame->sbsample[ch][3 * gr + s][sb] = mad_f_mul(samples[s], sf_table[scalefactor[ch][sb][gr / 4]]); } } else { for (s = 0; s < 3; ++s) frame->sbsample[ch][3 * gr + s][sb] = 0; } } } for (sb = bound; sb < sblimit; ++sb) { if ((index = allocation[0][sb])) { index = offset_table[bitalloc_table[offsets[sb]].offset][index - 1]; II_samples(&stream->ptr, &qc_table[index], samples); for (ch = 0; ch < nch; ++ch) { for (s = 0; s < 3; ++s) { frame->sbsample[ch][3 * gr + s][sb] = mad_f_mul(samples[s], sf_table[scalefactor[ch][sb][gr / 4]]); } } } else { for (ch = 0; ch < nch; ++ch) { for (s = 0; s < 3; ++s) frame->sbsample[ch][3 * gr + s][sb] = 0; } } } for (ch = 0; ch < nch; ++ch) { for (s = 0; s < 3; ++s) { for (sb = sblimit; sb < 32; ++sb) frame->sbsample[ch][3 * gr + s][sb] = 0; } } } return 0; } praat-6.0.04/external/mp3/mad_layer12.h000066400000000000000000000021211261542461700175060ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: layer12.h,v 1.10 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBMAD_LAYER12_H # define LIBMAD_LAYER12_H # include "mad_stream.h" # include "mad_frame.h" int mad_layer_I(struct mad_stream *, struct mad_frame *); int mad_layer_II(struct mad_stream *, struct mad_frame *); # endif praat-6.0.04/external/mp3/mad_layer3.c000066400000000000000000002110631261542461700174300ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: layer3.c,v 1.43 2004/01/23 09:41:32 rob Exp $ */ /*# ifdef HAVE_CONFIG_H*/ # include "mad_config.h" /*# endif*/ # include "mad_global.h" # include # include # ifdef HAVE_ASSERT_H # include # endif # ifdef HAVE_LIMITS_H # include # else # define CHAR_BIT 8 # endif # include "mad_fixed.h" # include "mad_bit.h" # include "mad_stream.h" # include "mad_frame.h" # include "mad_huffman.h" # include "mad_layer3.h" /* --- Layer III ----------------------------------------------------------- */ enum { count1table_select = 0x01, scalefac_scale = 0x02, preflag = 0x04, mixed_block_flag = 0x08 }; enum { I_STEREO = 0x1, MS_STEREO = 0x2 }; struct sideinfo { unsigned int main_data_begin; unsigned int private_bits; unsigned char scfsi[2]; struct granule { struct channel { /* from side info */ unsigned short part2_3_length; unsigned short big_values; unsigned short global_gain; unsigned short scalefac_compress; unsigned char flags; unsigned char block_type; unsigned char table_select[3]; unsigned char subblock_gain[3]; unsigned char region0_count; unsigned char region1_count; /* from main_data */ unsigned char scalefac[39]; /* scalefac_l and/or scalefac_s */ } ch[2]; } gr[2]; }; /* * scalefactor bit lengths * derived from section 2.4.2.7 of ISO/IEC 11172-3 */ static struct { unsigned char slen1; unsigned char slen2; } const sflen_table[16] = { { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, { 3, 0 }, { 1, 1 }, { 1, 2 }, { 1, 3 }, { 2, 1 }, { 2, 2 }, { 2, 3 }, { 3, 1 }, { 3, 2 }, { 3, 3 }, { 4, 2 }, { 4, 3 } }; /* * number of LSF scalefactor band values * derived from section 2.4.3.2 of ISO/IEC 13818-3 */ static unsigned char const nsfb_table[6][3][4] = { { { 6, 5, 5, 5 }, { 9, 9, 9, 9 }, { 6, 9, 9, 9 } }, { { 6, 5, 7, 3 }, { 9, 9, 12, 6 }, { 6, 9, 12, 6 } }, { { 11, 10, 0, 0 }, { 18, 18, 0, 0 }, { 15, 18, 0, 0 } }, { { 7, 7, 7, 0 }, { 12, 12, 12, 0 }, { 6, 15, 12, 0 } }, { { 6, 6, 6, 3 }, { 12, 9, 9, 6 }, { 6, 12, 9, 6 } }, { { 8, 8, 5, 0 }, { 15, 12, 9, 0 }, { 6, 18, 9, 0 } } }; /* * MPEG-1 scalefactor band widths * derived from Table B.8 of ISO/IEC 11172-3 */ static unsigned char const sfb_48000_long[] = { 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 10, 12, 16, 18, 22, 28, 34, 40, 46, 54, 54, 192 }; static unsigned char const sfb_44100_long[] = { 4, 4, 4, 4, 4, 4, 6, 6, 8, 8, 10, 12, 16, 20, 24, 28, 34, 42, 50, 54, 76, 158 }; static unsigned char const sfb_32000_long[] = { 4, 4, 4, 4, 4, 4, 6, 6, 8, 10, 12, 16, 20, 24, 30, 38, 46, 56, 68, 84, 102, 26 }; static unsigned char const sfb_48000_short[] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, 10, 10, 10, 12, 12, 12, 14, 14, 14, 16, 16, 16, 20, 20, 20, 26, 26, 26, 66, 66, 66 }; static unsigned char const sfb_44100_short[] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18, 18, 22, 22, 22, 30, 30, 30, 56, 56, 56 }; static unsigned char const sfb_32000_short[] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 8, 8, 12, 12, 12, 16, 16, 16, 20, 20, 20, 26, 26, 26, 34, 34, 34, 42, 42, 42, 12, 12, 12 }; static unsigned char const sfb_48000_mixed[] = { /* long */ 4, 4, 4, 4, 4, 4, 6, 6, /* short */ 4, 4, 4, 6, 6, 6, 6, 6, 6, 10, 10, 10, 12, 12, 12, 14, 14, 14, 16, 16, 16, 20, 20, 20, 26, 26, 26, 66, 66, 66 }; static unsigned char const sfb_44100_mixed[] = { /* long */ 4, 4, 4, 4, 4, 4, 6, 6, /* short */ 4, 4, 4, 6, 6, 6, 8, 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18, 18, 22, 22, 22, 30, 30, 30, 56, 56, 56 }; static unsigned char const sfb_32000_mixed[] = { /* long */ 4, 4, 4, 4, 4, 4, 6, 6, /* short */ 4, 4, 4, 6, 6, 6, 8, 8, 8, 12, 12, 12, 16, 16, 16, 20, 20, 20, 26, 26, 26, 34, 34, 34, 42, 42, 42, 12, 12, 12 }; /* * MPEG-2 scalefactor band widths * derived from Table B.2 of ISO/IEC 13818-3 */ static unsigned char const sfb_24000_long[] = { 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, 18, 22, 26, 32, 38, 46, 54, 62, 70, 76, 36 }; static unsigned char const sfb_22050_long[] = { 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54 }; # define sfb_16000_long sfb_22050_long static unsigned char const sfb_24000_short[] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18, 18, 24, 24, 24, 32, 32, 32, 44, 44, 44, 12, 12, 12 }; static unsigned char const sfb_22050_short[] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, 8, 8, 8, 10, 10, 10, 14, 14, 14, 18, 18, 18, 26, 26, 26, 32, 32, 32, 42, 42, 42, 18, 18, 18 }; static unsigned char const sfb_16000_short[] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18, 18, 24, 24, 24, 30, 30, 30, 40, 40, 40, 18, 18, 18 }; static unsigned char const sfb_24000_mixed[] = { /* long */ 6, 6, 6, 6, 6, 6, /* short */ 6, 6, 6, 8, 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18, 18, 24, 24, 24, 32, 32, 32, 44, 44, 44, 12, 12, 12 }; static unsigned char const sfb_22050_mixed[] = { /* long */ 6, 6, 6, 6, 6, 6, /* short */ 6, 6, 6, 6, 6, 6, 8, 8, 8, 10, 10, 10, 14, 14, 14, 18, 18, 18, 26, 26, 26, 32, 32, 32, 42, 42, 42, 18, 18, 18 }; static unsigned char const sfb_16000_mixed[] = { /* long */ 6, 6, 6, 6, 6, 6, /* short */ 6, 6, 6, 8, 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18, 18, 24, 24, 24, 30, 30, 30, 40, 40, 40, 18, 18, 18 }; /* * MPEG 2.5 scalefactor band widths * derived from public sources */ # define sfb_12000_long sfb_16000_long # define sfb_11025_long sfb_12000_long static unsigned char const sfb_8000_long[] = { 12, 12, 12, 12, 12, 12, 16, 20, 24, 28, 32, 40, 48, 56, 64, 76, 90, 2, 2, 2, 2, 2 }; # define sfb_12000_short sfb_16000_short # define sfb_11025_short sfb_12000_short static unsigned char const sfb_8000_short[] = { 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 16, 16, 16, 20, 20, 20, 24, 24, 24, 28, 28, 28, 36, 36, 36, 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26 }; # define sfb_12000_mixed sfb_16000_mixed # define sfb_11025_mixed sfb_12000_mixed /* the 8000 Hz short block scalefactor bands do not break after the first 36 frequency lines, so this is probably wrong */ static unsigned char const sfb_8000_mixed[] = { /* long */ 12, 12, 12, /* short */ 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16, 20, 20, 20, 24, 24, 24, 28, 28, 28, 36, 36, 36, 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26 }; static struct { unsigned char const *l; unsigned char const *s; unsigned char const *m; } const sfbwidth_table[9] = { { sfb_48000_long, sfb_48000_short, sfb_48000_mixed }, { sfb_44100_long, sfb_44100_short, sfb_44100_mixed }, { sfb_32000_long, sfb_32000_short, sfb_32000_mixed }, { sfb_24000_long, sfb_24000_short, sfb_24000_mixed }, { sfb_22050_long, sfb_22050_short, sfb_22050_mixed }, { sfb_16000_long, sfb_16000_short, sfb_16000_mixed }, { sfb_12000_long, sfb_12000_short, sfb_12000_mixed }, { sfb_11025_long, sfb_11025_short, sfb_11025_mixed }, { sfb_8000_long, sfb_8000_short, sfb_8000_mixed } }; /* * scalefactor band preemphasis (used only when preflag is set) * derived from Table B.6 of ISO/IEC 11172-3 */ static unsigned char const pretab[22] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0 }; /* * table for requantization * * rq_table[x].mantissa * 2^(rq_table[x].exponent) = x^(4/3) */ static struct fixedfloat { unsigned long mantissa : 27; unsigned short exponent : 5; } const rq_table[8207] = { # include "mad_rq_table.dat" }; /* * fractional powers of two * used for requantization and joint stereo decoding * * root_table[3 + x] = 2^(x/4) */ static mad_fixed_t const root_table[7] = { MAD_F(0x09837f05) /* 2^(-3/4) == 0.59460355750136 */, MAD_F(0x0b504f33) /* 2^(-2/4) == 0.70710678118655 */, MAD_F(0x0d744fcd) /* 2^(-1/4) == 0.84089641525371 */, MAD_F(0x10000000) /* 2^( 0/4) == 1.00000000000000 */, MAD_F(0x1306fe0a) /* 2^(+1/4) == 1.18920711500272 */, MAD_F(0x16a09e66) /* 2^(+2/4) == 1.41421356237310 */, MAD_F(0x1ae89f99) /* 2^(+3/4) == 1.68179283050743 */ }; /* * coefficients for aliasing reduction * derived from Table B.9 of ISO/IEC 11172-3 * * c[] = { -0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037 } * cs[i] = 1 / sqrt(1 + c[i]^2) * ca[i] = c[i] / sqrt(1 + c[i]^2) */ static mad_fixed_t const cs[8] = { +MAD_F(0x0db84a81) /* +0.857492926 */, +MAD_F(0x0e1b9d7f) /* +0.881741997 */, +MAD_F(0x0f31adcf) /* +0.949628649 */, +MAD_F(0x0fbba815) /* +0.983314592 */, +MAD_F(0x0feda417) /* +0.995517816 */, +MAD_F(0x0ffc8fc8) /* +0.999160558 */, +MAD_F(0x0fff964c) /* +0.999899195 */, +MAD_F(0x0ffff8d3) /* +0.999993155 */ }; static mad_fixed_t const ca[8] = { -MAD_F(0x083b5fe7) /* -0.514495755 */, -MAD_F(0x078c36d2) /* -0.471731969 */, -MAD_F(0x05039814) /* -0.313377454 */, -MAD_F(0x02e91dd1) /* -0.181913200 */, -MAD_F(0x0183603a) /* -0.094574193 */, -MAD_F(0x00a7cb87) /* -0.040965583 */, -MAD_F(0x003a2847) /* -0.014198569 */, -MAD_F(0x000f27b4) /* -0.003699975 */ }; /* * IMDCT coefficients for short blocks * derived from section 2.4.3.4.10.2 of ISO/IEC 11172-3 * * imdct_s[i/even][k] = cos((PI / 24) * (2 * (i / 2) + 7) * (2 * k + 1)) * imdct_s[i /odd][k] = cos((PI / 24) * (2 * (6 + (i-1)/2) + 7) * (2 * k + 1)) */ static mad_fixed_t const imdct_s[6][6] = { # include "mad_imdct_s.dat" }; # if !defined(ASO_IMDCT) /* * windowing coefficients for long blocks * derived from section 2.4.3.4.10.3 of ISO/IEC 11172-3 * * window_l[i] = sin((PI / 36) * (i + 1/2)) */ static mad_fixed_t const window_l[36] = { MAD_F(0x00b2aa3e) /* 0.043619387 */, MAD_F(0x0216a2a2) /* 0.130526192 */, MAD_F(0x03768962) /* 0.216439614 */, MAD_F(0x04cfb0e2) /* 0.300705800 */, MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x07635284) /* 0.461748613 */, MAD_F(0x0898c779) /* 0.537299608 */, MAD_F(0x09bd7ca0) /* 0.608761429 */, MAD_F(0x0acf37ad) /* 0.675590208 */, MAD_F(0x0bcbe352) /* 0.737277337 */, MAD_F(0x0cb19346) /* 0.793353340 */, MAD_F(0x0d7e8807) /* 0.843391446 */, MAD_F(0x0e313245) /* 0.887010833 */, MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0f426cb5) /* 0.953716951 */, MAD_F(0x0f9ee890) /* 0.976296007 */, MAD_F(0x0fdcf549) /* 0.991444861 */, MAD_F(0x0ffc19fd) /* 0.999048222 */, MAD_F(0x0ffc19fd) /* 0.999048222 */, MAD_F(0x0fdcf549) /* 0.991444861 */, MAD_F(0x0f9ee890) /* 0.976296007 */, MAD_F(0x0f426cb5) /* 0.953716951 */, MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0e313245) /* 0.887010833 */, MAD_F(0x0d7e8807) /* 0.843391446 */, MAD_F(0x0cb19346) /* 0.793353340 */, MAD_F(0x0bcbe352) /* 0.737277337 */, MAD_F(0x0acf37ad) /* 0.675590208 */, MAD_F(0x09bd7ca0) /* 0.608761429 */, MAD_F(0x0898c779) /* 0.537299608 */, MAD_F(0x07635284) /* 0.461748613 */, MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x04cfb0e2) /* 0.300705800 */, MAD_F(0x03768962) /* 0.216439614 */, MAD_F(0x0216a2a2) /* 0.130526192 */, MAD_F(0x00b2aa3e) /* 0.043619387 */, }; # endif /* ASO_IMDCT */ /* * windowing coefficients for short blocks * derived from section 2.4.3.4.10.3 of ISO/IEC 11172-3 * * window_s[i] = sin((PI / 12) * (i + 1/2)) */ static mad_fixed_t const window_s[12] = { MAD_F(0x0216a2a2) /* 0.130526192 */, MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x09bd7ca0) /* 0.608761429 */, MAD_F(0x0cb19346) /* 0.793353340 */, MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0fdcf549) /* 0.991444861 */, MAD_F(0x0fdcf549) /* 0.991444861 */, MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0cb19346) /* 0.793353340 */, MAD_F(0x09bd7ca0) /* 0.608761429 */, MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x0216a2a2) /* 0.130526192 */, }; /* * coefficients for intensity stereo processing * derived from section 2.4.3.4.9.3 of ISO/IEC 11172-3 * * is_ratio[i] = tan(i * (PI / 12)) * is_table[i] = is_ratio[i] / (1 + is_ratio[i]) */ static mad_fixed_t const is_table[7] = { MAD_F(0x00000000) /* 0.000000000 */, MAD_F(0x0361962f) /* 0.211324865 */, MAD_F(0x05db3d74) /* 0.366025404 */, MAD_F(0x08000000) /* 0.500000000 */, MAD_F(0x0a24c28c) /* 0.633974596 */, MAD_F(0x0c9e69d1) /* 0.788675135 */, MAD_F(0x10000000) /* 1.000000000 */ }; /* * coefficients for LSF intensity stereo processing * derived from section 2.4.3.2 of ISO/IEC 13818-3 * * is_lsf_table[0][i] = (1 / sqrt(sqrt(2)))^(i + 1) * is_lsf_table[1][i] = (1 / sqrt(2)) ^(i + 1) */ static mad_fixed_t const is_lsf_table[2][15] = { { MAD_F(0x0d744fcd) /* 0.840896415 */, MAD_F(0x0b504f33) /* 0.707106781 */, MAD_F(0x09837f05) /* 0.594603558 */, MAD_F(0x08000000) /* 0.500000000 */, MAD_F(0x06ba27e6) /* 0.420448208 */, MAD_F(0x05a8279a) /* 0.353553391 */, MAD_F(0x04c1bf83) /* 0.297301779 */, MAD_F(0x04000000) /* 0.250000000 */, MAD_F(0x035d13f3) /* 0.210224104 */, MAD_F(0x02d413cd) /* 0.176776695 */, MAD_F(0x0260dfc1) /* 0.148650889 */, MAD_F(0x02000000) /* 0.125000000 */, MAD_F(0x01ae89fa) /* 0.105112052 */, MAD_F(0x016a09e6) /* 0.088388348 */, MAD_F(0x01306fe1) /* 0.074325445 */ }, { MAD_F(0x0b504f33) /* 0.707106781 */, MAD_F(0x08000000) /* 0.500000000 */, MAD_F(0x05a8279a) /* 0.353553391 */, MAD_F(0x04000000) /* 0.250000000 */, MAD_F(0x02d413cd) /* 0.176776695 */, MAD_F(0x02000000) /* 0.125000000 */, MAD_F(0x016a09e6) /* 0.088388348 */, MAD_F(0x01000000) /* 0.062500000 */, MAD_F(0x00b504f3) /* 0.044194174 */, MAD_F(0x00800000) /* 0.031250000 */, MAD_F(0x005a827a) /* 0.022097087 */, MAD_F(0x00400000) /* 0.015625000 */, MAD_F(0x002d413d) /* 0.011048543 */, MAD_F(0x00200000) /* 0.007812500 */, MAD_F(0x0016a09e) /* 0.005524272 */ } }; /* * NAME: III_sideinfo() * DESCRIPTION: decode frame side information from a bitstream */ static enum mad_error III_sideinfo(struct mad_bitptr *ptr, unsigned int nch, int lsf, struct sideinfo *si, unsigned int *data_bitlen, unsigned int *priv_bitlen) { unsigned int ngr, gr, ch, i; enum mad_error result = MAD_ERROR_NONE; *data_bitlen = 0; *priv_bitlen = lsf ? ((nch == 1) ? 1 : 2) : ((nch == 1) ? 5 : 3); si->main_data_begin = mad_bit_read(ptr, lsf ? 8 : 9); si->private_bits = mad_bit_read(ptr, *priv_bitlen); ngr = 1; if (!lsf) { ngr = 2; for (ch = 0; ch < nch; ++ch) si->scfsi[ch] = mad_bit_read(ptr, 4); } for (gr = 0; gr < ngr; ++gr) { struct granule *granule = &si->gr[gr]; for (ch = 0; ch < nch; ++ch) { struct channel *channel = &granule->ch[ch]; channel->part2_3_length = mad_bit_read(ptr, 12); channel->big_values = mad_bit_read(ptr, 9); channel->global_gain = mad_bit_read(ptr, 8); channel->scalefac_compress = mad_bit_read(ptr, lsf ? 9 : 4); *data_bitlen += channel->part2_3_length; if (channel->big_values > 288 && result == 0) result = MAD_ERROR_BADBIGVALUES; channel->flags = 0; /* window_switching_flag */ if (mad_bit_read(ptr, 1)) { channel->block_type = mad_bit_read(ptr, 2); if (channel->block_type == 0 && result == 0) result = MAD_ERROR_BADBLOCKTYPE; if (!lsf && channel->block_type == 2 && si->scfsi[ch] && result == 0) result = MAD_ERROR_BADSCFSI; channel->region0_count = 7; channel->region1_count = 36; if (mad_bit_read(ptr, 1)) channel->flags |= mixed_block_flag; else if (channel->block_type == 2) channel->region0_count = 8; for (i = 0; i < 2; ++i) channel->table_select[i] = mad_bit_read(ptr, 5); # if defined(DEBUG) channel->table_select[2] = 4; /* not used */ # endif for (i = 0; i < 3; ++i) channel->subblock_gain[i] = mad_bit_read(ptr, 3); } else { channel->block_type = 0; for (i = 0; i < 3; ++i) channel->table_select[i] = mad_bit_read(ptr, 5); channel->region0_count = mad_bit_read(ptr, 4); channel->region1_count = mad_bit_read(ptr, 3); } /* [preflag,] scalefac_scale, count1table_select */ channel->flags |= mad_bit_read(ptr, lsf ? 2 : 3); } } return result; } /* * NAME: III_scalefactors_lsf() * DESCRIPTION: decode channel scalefactors for LSF from a bitstream */ static unsigned int III_scalefactors_lsf(struct mad_bitptr *ptr, struct channel *channel, struct channel *gr1ch, int mode_extension) { struct mad_bitptr start; unsigned int scalefac_compress, index, slen[4], part, n, i; unsigned char const *nsfb; start = *ptr; scalefac_compress = channel->scalefac_compress; index = (channel->block_type == 2) ? ((channel->flags & mixed_block_flag) ? 2 : 1) : 0; if (!((mode_extension & I_STEREO) && gr1ch)) { if (scalefac_compress < 400) { slen[0] = (scalefac_compress >> 4) / 5; slen[1] = (scalefac_compress >> 4) % 5; slen[2] = (scalefac_compress % 16) >> 2; slen[3] = scalefac_compress % 4; nsfb = nsfb_table[0][index]; } else if (scalefac_compress < 500) { scalefac_compress -= 400; slen[0] = (scalefac_compress >> 2) / 5; slen[1] = (scalefac_compress >> 2) % 5; slen[2] = scalefac_compress % 4; slen[3] = 0; nsfb = nsfb_table[1][index]; } else { scalefac_compress -= 500; slen[0] = scalefac_compress / 3; slen[1] = scalefac_compress % 3; slen[2] = 0; slen[3] = 0; channel->flags |= preflag; nsfb = nsfb_table[2][index]; } n = 0; for (part = 0; part < 4; ++part) { for (i = 0; i < nsfb[part]; ++i) channel->scalefac[n++] = mad_bit_read(ptr, slen[part]); } while (n < 39) channel->scalefac[n++] = 0; } else { /* (mode_extension & I_STEREO) && gr1ch (i.e. ch == 1) */ scalefac_compress >>= 1; if (scalefac_compress < 180) { slen[0] = scalefac_compress / 36; slen[1] = (scalefac_compress % 36) / 6; slen[2] = (scalefac_compress % 36) % 6; slen[3] = 0; nsfb = nsfb_table[3][index]; } else if (scalefac_compress < 244) { scalefac_compress -= 180; slen[0] = (scalefac_compress % 64) >> 4; slen[1] = (scalefac_compress % 16) >> 2; slen[2] = scalefac_compress % 4; slen[3] = 0; nsfb = nsfb_table[4][index]; } else { scalefac_compress -= 244; slen[0] = scalefac_compress / 3; slen[1] = scalefac_compress % 3; slen[2] = 0; slen[3] = 0; nsfb = nsfb_table[5][index]; } n = 0; for (part = 0; part < 4; ++part) { unsigned int max, is_pos; max = (1 << slen[part]) - 1; for (i = 0; i < nsfb[part]; ++i) { is_pos = mad_bit_read(ptr, slen[part]); channel->scalefac[n] = is_pos; gr1ch->scalefac[n++] = (is_pos == max); } } while (n < 39) { channel->scalefac[n] = 0; gr1ch->scalefac[n++] = 0; /* apparently not illegal */ } } return mad_bit_length(&start, ptr); } /* * NAME: III_scalefactors() * DESCRIPTION: decode channel scalefactors of one granule from a bitstream */ static unsigned int III_scalefactors(struct mad_bitptr *ptr, struct channel *channel, struct channel const *gr0ch, unsigned int scfsi) { struct mad_bitptr start; unsigned int slen1, slen2, sfbi; start = *ptr; slen1 = sflen_table[channel->scalefac_compress].slen1; slen2 = sflen_table[channel->scalefac_compress].slen2; if (channel->block_type == 2) { unsigned int nsfb; sfbi = 0; nsfb = (channel->flags & mixed_block_flag) ? 8 + 3 * 3 : 6 * 3; while (nsfb--) channel->scalefac[sfbi++] = mad_bit_read(ptr, slen1); nsfb = 6 * 3; while (nsfb--) channel->scalefac[sfbi++] = mad_bit_read(ptr, slen2); nsfb = 1 * 3; while (nsfb--) channel->scalefac[sfbi++] = 0; } else { /* channel->block_type != 2 */ if (scfsi & 0x8) { for (sfbi = 0; sfbi < 6; ++sfbi) channel->scalefac[sfbi] = gr0ch->scalefac[sfbi]; } else { for (sfbi = 0; sfbi < 6; ++sfbi) channel->scalefac[sfbi] = mad_bit_read(ptr, slen1); } if (scfsi & 0x4) { for (sfbi = 6; sfbi < 11; ++sfbi) channel->scalefac[sfbi] = gr0ch->scalefac[sfbi]; } else { for (sfbi = 6; sfbi < 11; ++sfbi) channel->scalefac[sfbi] = mad_bit_read(ptr, slen1); } if (scfsi & 0x2) { for (sfbi = 11; sfbi < 16; ++sfbi) channel->scalefac[sfbi] = gr0ch->scalefac[sfbi]; } else { for (sfbi = 11; sfbi < 16; ++sfbi) channel->scalefac[sfbi] = mad_bit_read(ptr, slen2); } if (scfsi & 0x1) { for (sfbi = 16; sfbi < 21; ++sfbi) channel->scalefac[sfbi] = gr0ch->scalefac[sfbi]; } else { for (sfbi = 16; sfbi < 21; ++sfbi) channel->scalefac[sfbi] = mad_bit_read(ptr, slen2); } channel->scalefac[21] = 0; } return mad_bit_length(&start, ptr); } /* * The Layer III formula for requantization and scaling is defined by * section 2.4.3.4.7.1 of ISO/IEC 11172-3, as follows: * * long blocks: * xr[i] = sign(is[i]) * abs(is[i])^(4/3) * * 2^((1/4) * (global_gain - 210)) * * 2^-(scalefac_multiplier * * (scalefac_l[sfb] + preflag * pretab[sfb])) * * short blocks: * xr[i] = sign(is[i]) * abs(is[i])^(4/3) * * 2^((1/4) * (global_gain - 210 - 8 * subblock_gain[w])) * * 2^-(scalefac_multiplier * scalefac_s[sfb][w]) * * where: * scalefac_multiplier = (scalefac_scale + 1) / 2 * * The routines III_exponents() and III_requantize() facilitate this * calculation. */ /* * NAME: III_exponents() * DESCRIPTION: calculate scalefactor exponents */ static void III_exponents(struct channel const *channel, unsigned char const *sfbwidth, signed int exponents[39]) { signed int gain; unsigned int scalefac_multiplier, sfbi; gain = (signed int) channel->global_gain - 210; scalefac_multiplier = (channel->flags & scalefac_scale) ? 2 : 1; if (channel->block_type == 2) { unsigned int l; signed int gain0, gain1, gain2; sfbi = l = 0; if (channel->flags & mixed_block_flag) { unsigned int premask; premask = (channel->flags & preflag) ? ~0 : 0; /* long block subbands 0-1 */ while (l < 36) { exponents[sfbi] = gain - (signed int) ((channel->scalefac[sfbi] + (pretab[sfbi] & premask)) << scalefac_multiplier); l += sfbwidth[sfbi++]; } } /* this is probably wrong for 8000 Hz short/mixed blocks */ gain0 = gain - 8 * (signed int) channel->subblock_gain[0]; gain1 = gain - 8 * (signed int) channel->subblock_gain[1]; gain2 = gain - 8 * (signed int) channel->subblock_gain[2]; while (l < 576) { exponents[sfbi + 0] = gain0 - (signed int) (channel->scalefac[sfbi + 0] << scalefac_multiplier); exponents[sfbi + 1] = gain1 - (signed int) (channel->scalefac[sfbi + 1] << scalefac_multiplier); exponents[sfbi + 2] = gain2 - (signed int) (channel->scalefac[sfbi + 2] << scalefac_multiplier); l += 3 * sfbwidth[sfbi]; sfbi += 3; } } else { /* channel->block_type != 2 */ if (channel->flags & preflag) { for (sfbi = 0; sfbi < 22; ++sfbi) { exponents[sfbi] = gain - (signed int) ((channel->scalefac[sfbi] + pretab[sfbi]) << scalefac_multiplier); } } else { for (sfbi = 0; sfbi < 22; ++sfbi) { exponents[sfbi] = gain - (signed int) (channel->scalefac[sfbi] << scalefac_multiplier); } } } } /* * NAME: III_requantize() * DESCRIPTION: requantize one (positive) value */ static mad_fixed_t III_requantize(unsigned int value, signed int exp) { mad_fixed_t requantized; signed int frac; struct fixedfloat const *power; frac = exp % 4; /* assumes sign(frac) == sign(exp) */ exp /= 4; power = &rq_table[value]; requantized = power->mantissa; exp += power->exponent; if (exp < 0) { if (-exp >= sizeof(mad_fixed_t) * CHAR_BIT) { /* underflow */ requantized = 0; } else { requantized += 1L << (-exp - 1); requantized >>= -exp; } } else { if (exp >= 5) { /* overflow */ # if defined(DEBUG) fprintf(stderr, "requantize overflow (%f * 2^%d)\n", mad_f_todouble(requantized), exp); # endif requantized = MAD_F_MAX; } else requantized <<= exp; } return frac ? mad_f_mul(requantized, root_table[3 + frac]) : requantized; } /* we must take care that sz >= bits and sz < sizeof(long) lest bits == 0 */ # define MASK(cache, sz, bits) \ (((cache) >> ((sz) - (bits))) & ((1 << (bits)) - 1)) # define MASK1BIT(cache, sz) \ ((cache) & (1 << ((sz) - 1))) /* * NAME: III_huffdecode() * DESCRIPTION: decode Huffman code words of one channel of one granule */ static enum mad_error III_huffdecode(struct mad_bitptr *ptr, mad_fixed_t xr[576], struct channel *channel, unsigned char const *sfbwidth, unsigned int part2_length) { signed int exponents[39], exp; signed int const *expptr; struct mad_bitptr peek; signed int bits_left, cachesz; register mad_fixed_t *xrptr; mad_fixed_t const *sfbound; register unsigned long bitcache; bits_left = (signed) channel->part2_3_length - (signed) part2_length; if (bits_left < 0) return MAD_ERROR_BADPART3LEN; III_exponents(channel, sfbwidth, exponents); peek = *ptr; mad_bit_skip(ptr, bits_left); /* align bit reads to byte boundaries */ cachesz = mad_bit_bitsleft(&peek); cachesz += ((32 - 1 - 24) + (24 - cachesz)) & ~7; bitcache = mad_bit_read(&peek, cachesz); bits_left -= cachesz; xrptr = &xr[0]; /* big_values */ { unsigned int region, rcount; struct hufftable const *entry; union huffpair const *table; unsigned int linbits, startbits, big_values, reqhits; mad_fixed_t reqcache[16]; sfbound = xrptr + *sfbwidth++; rcount = channel->region0_count + 1; entry = &mad_huff_pair_table[channel->table_select[region = 0]]; table = entry->table; linbits = entry->linbits; startbits = entry->startbits; if (table == 0) return MAD_ERROR_BADHUFFTABLE; expptr = &exponents[0]; exp = *expptr++; reqhits = 0; big_values = channel->big_values; while (big_values-- && cachesz + bits_left > 0) { union huffpair const *pair; unsigned int clumpsz, value; register mad_fixed_t requantized; if (xrptr == sfbound) { sfbound += *sfbwidth++; /* change table if region boundary */ if (--rcount == 0) { if (region == 0) rcount = channel->region1_count + 1; else rcount = 0; /* all remaining */ entry = &mad_huff_pair_table[channel->table_select[++region]]; table = entry->table; linbits = entry->linbits; startbits = entry->startbits; if (table == 0) return MAD_ERROR_BADHUFFTABLE; } if (exp != *expptr) { exp = *expptr; reqhits = 0; } ++expptr; } if (cachesz < 21) { unsigned int bits; bits = ((32 - 1 - 21) + (21 - cachesz)) & ~7; bitcache = (bitcache << bits) | mad_bit_read(&peek, bits); cachesz += bits; bits_left -= bits; } /* hcod (0..19) */ clumpsz = startbits; pair = &table[MASK(bitcache, cachesz, clumpsz)]; while (!pair->final) { cachesz -= clumpsz; clumpsz = pair->ptr.bits; pair = &table[pair->ptr.offset + MASK(bitcache, cachesz, clumpsz)]; } cachesz -= pair->value.hlen; if (linbits) { /* x (0..14) */ value = pair->value.x; switch (value) { case 0: xrptr[0] = 0; break; case 15: if (cachesz < linbits + 2) { bitcache = (bitcache << 16) | mad_bit_read(&peek, 16); cachesz += 16; bits_left -= 16; } value += MASK(bitcache, cachesz, linbits); cachesz -= linbits; requantized = III_requantize(value, exp); goto x_final; default: if (reqhits & (1 << value)) requantized = reqcache[value]; else { reqhits |= (1 << value); requantized = reqcache[value] = III_requantize(value, exp); } x_final: xrptr[0] = MASK1BIT(bitcache, cachesz--) ? -requantized : requantized; } /* y (0..14) */ value = pair->value.y; switch (value) { case 0: xrptr[1] = 0; break; case 15: if (cachesz < linbits + 1) { bitcache = (bitcache << 16) | mad_bit_read(&peek, 16); cachesz += 16; bits_left -= 16; } value += MASK(bitcache, cachesz, linbits); cachesz -= linbits; requantized = III_requantize(value, exp); goto y_final; default: if (reqhits & (1 << value)) requantized = reqcache[value]; else { reqhits |= (1 << value); requantized = reqcache[value] = III_requantize(value, exp); } y_final: xrptr[1] = MASK1BIT(bitcache, cachesz--) ? -requantized : requantized; } } else { /* x (0..1) */ value = pair->value.x; if (value == 0) xrptr[0] = 0; else { if (reqhits & (1 << value)) requantized = reqcache[value]; else { reqhits |= (1 << value); requantized = reqcache[value] = III_requantize(value, exp); } xrptr[0] = MASK1BIT(bitcache, cachesz--) ? -requantized : requantized; } /* y (0..1) */ value = pair->value.y; if (value == 0) xrptr[1] = 0; else { if (reqhits & (1 << value)) requantized = reqcache[value]; else { reqhits |= (1 << value); requantized = reqcache[value] = III_requantize(value, exp); } xrptr[1] = MASK1BIT(bitcache, cachesz--) ? -requantized : requantized; } } xrptr += 2; } } if (cachesz + bits_left < 0) return MAD_ERROR_BADHUFFDATA; /* big_values overrun */ /* count1 */ { union huffquad const *table; register mad_fixed_t requantized; table = mad_huff_quad_table[channel->flags & count1table_select]; requantized = III_requantize(1, exp); while (cachesz + bits_left > 0 && xrptr <= &xr[572]) { union huffquad const *quad; /* hcod (1..6) */ if (cachesz < 10) { bitcache = (bitcache << 16) | mad_bit_read(&peek, 16); cachesz += 16; bits_left -= 16; } quad = &table[MASK(bitcache, cachesz, 4)]; /* quad tables guaranteed to have at most one extra lookup */ if (!quad->final) { cachesz -= 4; quad = &table[quad->ptr.offset + MASK(bitcache, cachesz, quad->ptr.bits)]; } cachesz -= quad->value.hlen; if (xrptr == sfbound) { sfbound += *sfbwidth++; if (exp != *expptr) { exp = *expptr; requantized = III_requantize(1, exp); } ++expptr; } /* v (0..1) */ xrptr[0] = quad->value.v ? (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0; /* w (0..1) */ xrptr[1] = quad->value.w ? (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0; xrptr += 2; if (xrptr == sfbound) { sfbound += *sfbwidth++; if (exp != *expptr) { exp = *expptr; requantized = III_requantize(1, exp); } ++expptr; } /* x (0..1) */ xrptr[0] = quad->value.x ? (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0; /* y (0..1) */ xrptr[1] = quad->value.y ? (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0; xrptr += 2; } if (cachesz + bits_left < 0) { # if 0 && defined(DEBUG) fprintf(stderr, "huffman count1 overrun (%d bits)\n", -(cachesz + bits_left)); # endif /* technically the bitstream is misformatted, but apparently some encoders are just a bit sloppy with stuffing bits */ xrptr -= 4; } } assert(-bits_left <= MAD_BUFFER_GUARD * CHAR_BIT); # if 0 && defined(DEBUG) if (bits_left < 0) fprintf(stderr, "read %d bits too many\n", -bits_left); else if (cachesz + bits_left > 0) fprintf(stderr, "%d stuffing bits\n", cachesz + bits_left); # endif /* rzero */ while (xrptr < &xr[576]) { xrptr[0] = 0; xrptr[1] = 0; xrptr += 2; } return MAD_ERROR_NONE; } # undef MASK # undef MASK1BIT /* * NAME: III_reorder() * DESCRIPTION: reorder frequency lines of a short block into subband order */ static void III_reorder(mad_fixed_t xr[576], struct channel const *channel, unsigned char const sfbwidth[39]) { mad_fixed_t tmp[32][3][6]; unsigned int sb, l, f, w, sbw[3], sw[3]; /* this is probably wrong for 8000 Hz mixed blocks */ sb = 0; if (channel->flags & mixed_block_flag) { sb = 2; l = 0; while (l < 36) l += *sfbwidth++; } for (w = 0; w < 3; ++w) { sbw[w] = sb; sw[w] = 0; } f = *sfbwidth++; w = 0; for (l = 18 * sb; l < 576; ++l) { if (f-- == 0) { f = *sfbwidth++ - 1; w = (w + 1) % 3; } tmp[sbw[w]][w][sw[w]++] = xr[l]; if (sw[w] == 6) { sw[w] = 0; ++sbw[w]; } } memcpy(&xr[18 * sb], &tmp[sb], (576 - 18 * sb) * sizeof(mad_fixed_t)); } /* * NAME: III_stereo() * DESCRIPTION: perform joint stereo processing on a granule */ static enum mad_error III_stereo(mad_fixed_t xr[2][576], struct granule const *granule, struct mad_header *header, unsigned char const *sfbwidth) { short modes[39]; unsigned int sfbi, l, n, i; if (granule->ch[0].block_type != granule->ch[1].block_type || (granule->ch[0].flags & mixed_block_flag) != (granule->ch[1].flags & mixed_block_flag)) return MAD_ERROR_BADSTEREO; for (i = 0; i < 39; ++i) modes[i] = header->mode_extension; /* intensity stereo */ if (header->mode_extension & I_STEREO) { struct channel const *right_ch = &granule->ch[1]; mad_fixed_t const *right_xr = xr[1]; unsigned int is_pos; header->flags |= MAD_FLAG_I_STEREO; /* first determine which scalefactor bands are to be processed */ if (right_ch->block_type == 2) { unsigned int lower, start, max, bound[3], w; lower = start = max = bound[0] = bound[1] = bound[2] = 0; sfbi = l = 0; if (right_ch->flags & mixed_block_flag) { while (l < 36) { n = sfbwidth[sfbi++]; for (i = 0; i < n; ++i) { if (right_xr[i]) { lower = sfbi; break; } } right_xr += n; l += n; } start = sfbi; } w = 0; while (l < 576) { n = sfbwidth[sfbi++]; for (i = 0; i < n; ++i) { if (right_xr[i]) { max = bound[w] = sfbi; break; } } right_xr += n; l += n; w = (w + 1) % 3; } if (max) lower = start; /* long blocks */ for (i = 0; i < lower; ++i) modes[i] = header->mode_extension & ~I_STEREO; /* short blocks */ w = 0; for (i = start; i < max; ++i) { if (i < bound[w]) modes[i] = header->mode_extension & ~I_STEREO; w = (w + 1) % 3; } } else { /* right_ch->block_type != 2 */ unsigned int bound; bound = 0; for (sfbi = l = 0; l < 576; l += n) { n = sfbwidth[sfbi++]; for (i = 0; i < n; ++i) { if (right_xr[i]) { bound = sfbi; break; } } right_xr += n; } for (i = 0; i < bound; ++i) modes[i] = header->mode_extension & ~I_STEREO; } /* now do the actual processing */ if (header->flags & MAD_FLAG_LSF_EXT) { unsigned char const *illegal_pos = granule[1].ch[1].scalefac; mad_fixed_t const *lsf_scale; /* intensity_scale */ lsf_scale = is_lsf_table[right_ch->scalefac_compress & 0x1]; for (sfbi = l = 0; l < 576; ++sfbi, l += n) { n = sfbwidth[sfbi]; if (!(modes[sfbi] & I_STEREO)) continue; if (illegal_pos[sfbi]) { modes[sfbi] &= ~I_STEREO; continue; } is_pos = right_ch->scalefac[sfbi]; for (i = 0; i < n; ++i) { register mad_fixed_t left; left = xr[0][l + i]; if (is_pos == 0) xr[1][l + i] = left; else { register mad_fixed_t opposite; opposite = mad_f_mul(left, lsf_scale[(is_pos - 1) / 2]); if (is_pos & 1) { xr[0][l + i] = opposite; xr[1][l + i] = left; } else xr[1][l + i] = opposite; } } } } else { /* !(header->flags & MAD_FLAG_LSF_EXT) */ for (sfbi = l = 0; l < 576; ++sfbi, l += n) { n = sfbwidth[sfbi]; if (!(modes[sfbi] & I_STEREO)) continue; is_pos = right_ch->scalefac[sfbi]; if (is_pos >= 7) { /* illegal intensity position */ modes[sfbi] &= ~I_STEREO; continue; } for (i = 0; i < n; ++i) { register mad_fixed_t left; left = xr[0][l + i]; xr[0][l + i] = mad_f_mul(left, is_table[ is_pos]); xr[1][l + i] = mad_f_mul(left, is_table[6 - is_pos]); } } } } /* middle/side stereo */ if (header->mode_extension & MS_STEREO) { register mad_fixed_t invsqrt2; header->flags |= MAD_FLAG_MS_STEREO; invsqrt2 = root_table[3 + -2]; for (sfbi = l = 0; l < 576; ++sfbi, l += n) { n = sfbwidth[sfbi]; if (modes[sfbi] != MS_STEREO) continue; for (i = 0; i < n; ++i) { register mad_fixed_t m, s; m = xr[0][l + i]; s = xr[1][l + i]; xr[0][l + i] = mad_f_mul(m + s, invsqrt2); /* l = (m + s) / sqrt(2) */ xr[1][l + i] = mad_f_mul(m - s, invsqrt2); /* r = (m - s) / sqrt(2) */ } } } return MAD_ERROR_NONE; } /* * NAME: III_aliasreduce() * DESCRIPTION: perform frequency line alias reduction */ static void III_aliasreduce(mad_fixed_t xr[576], int lines) { mad_fixed_t const *bound; int i; bound = &xr[lines]; for (xr += 18; xr < bound; xr += 18) { for (i = 0; i < 8; ++i) { register mad_fixed_t a, b; register mad_fixed64hi_t hi; register mad_fixed64lo_t lo; a = xr[-1 - i]; b = xr[ i]; # if defined(ASO_ZEROCHECK) if (a | b) { # endif MAD_F_ML0(hi, lo, a, cs[i]); MAD_F_MLA(hi, lo, -b, ca[i]); xr[-1 - i] = MAD_F_MLZ(hi, lo); MAD_F_ML0(hi, lo, b, cs[i]); MAD_F_MLA(hi, lo, a, ca[i]); xr[ i] = MAD_F_MLZ(hi, lo); # if defined(ASO_ZEROCHECK) } # endif } } } # if defined(ASO_IMDCT) void III_imdct_l(mad_fixed_t const [18], mad_fixed_t [36], unsigned int); # else # if 1 static void fastsdct(mad_fixed_t const x[9], mad_fixed_t y[18]) { mad_fixed_t a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12; mad_fixed_t a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25; mad_fixed_t m0, m1, m2, m3, m4, m5, m6, m7; enum { c0 = MAD_F(0x1f838b8d), /* 2 * cos( 1 * PI / 18) */ c1 = MAD_F(0x1bb67ae8), /* 2 * cos( 3 * PI / 18) */ c2 = MAD_F(0x18836fa3), /* 2 * cos( 4 * PI / 18) */ c3 = MAD_F(0x1491b752), /* 2 * cos( 5 * PI / 18) */ c4 = MAD_F(0x0af1d43a), /* 2 * cos( 7 * PI / 18) */ c5 = MAD_F(0x058e86a0), /* 2 * cos( 8 * PI / 18) */ c6 = -MAD_F(0x1e11f642) /* 2 * cos(16 * PI / 18) */ }; a0 = x[3] + x[5]; a1 = x[3] - x[5]; a2 = x[6] + x[2]; a3 = x[6] - x[2]; a4 = x[1] + x[7]; a5 = x[1] - x[7]; a6 = x[8] + x[0]; a7 = x[8] - x[0]; a8 = a0 + a2; a9 = a0 - a2; a10 = a0 - a6; a11 = a2 - a6; a12 = a8 + a6; a13 = a1 - a3; a14 = a13 + a7; a15 = a3 + a7; a16 = a1 - a7; a17 = a1 + a3; m0 = mad_f_mul(a17, -c3); m1 = mad_f_mul(a16, -c0); m2 = mad_f_mul(a15, -c4); m3 = mad_f_mul(a14, -c1); m4 = mad_f_mul(a5, -c1); m5 = mad_f_mul(a11, -c6); m6 = mad_f_mul(a10, -c5); m7 = mad_f_mul(a9, -c2); a18 = x[4] + a4; a19 = 2 * x[4] - a4; a20 = a19 + m5; a21 = a19 - m5; a22 = a19 + m6; a23 = m4 + m2; a24 = m4 - m2; a25 = m4 + m1; /* output to every other slot for convenience */ y[ 0] = a18 + a12; y[ 2] = m0 - a25; y[ 4] = m7 - a20; y[ 6] = m3; y[ 8] = a21 - m6; y[10] = a24 - m1; y[12] = a12 - 2 * a18; y[14] = a23 + m0; y[16] = a22 + m7; } static inline void sdctII(mad_fixed_t const x[18], mad_fixed_t X[18]) { mad_fixed_t tmp[9]; int i; /* scale[i] = 2 * cos(PI * (2 * i + 1) / (2 * 18)) */ static mad_fixed_t const scale[9] = { MAD_F(0x1fe0d3b4), MAD_F(0x1ee8dd47), MAD_F(0x1d007930), MAD_F(0x1a367e59), MAD_F(0x16a09e66), MAD_F(0x125abcf8), MAD_F(0x0d8616bc), MAD_F(0x08483ee1), MAD_F(0x02c9fad7) }; /* divide the 18-point SDCT-II into two 9-point SDCT-IIs */ /* even input butterfly */ for (i = 0; i < 9; i += 3) { tmp[i + 0] = x[i + 0] + x[18 - (i + 0) - 1]; tmp[i + 1] = x[i + 1] + x[18 - (i + 1) - 1]; tmp[i + 2] = x[i + 2] + x[18 - (i + 2) - 1]; } fastsdct(tmp, &X[0]); /* odd input butterfly and scaling */ for (i = 0; i < 9; i += 3) { tmp[i + 0] = mad_f_mul(x[i + 0] - x[18 - (i + 0) - 1], scale[i + 0]); tmp[i + 1] = mad_f_mul(x[i + 1] - x[18 - (i + 1) - 1], scale[i + 1]); tmp[i + 2] = mad_f_mul(x[i + 2] - x[18 - (i + 2) - 1], scale[i + 2]); } fastsdct(tmp, &X[1]); /* output accumulation */ for (i = 3; i < 18; i += 8) { X[i + 0] -= X[(i + 0) - 2]; X[i + 2] -= X[(i + 2) - 2]; X[i + 4] -= X[(i + 4) - 2]; X[i + 6] -= X[(i + 6) - 2]; } } static inline void dctIV(mad_fixed_t const y[18], mad_fixed_t X[18]) { mad_fixed_t tmp[18]; int i; /* scale[i] = 2 * cos(PI * (2 * i + 1) / (4 * 18)) */ static mad_fixed_t const scale[18] = { MAD_F(0x1ff833fa), MAD_F(0x1fb9ea93), MAD_F(0x1f3dd120), MAD_F(0x1e84d969), MAD_F(0x1d906bcf), MAD_F(0x1c62648b), MAD_F(0x1afd100f), MAD_F(0x1963268b), MAD_F(0x1797c6a4), MAD_F(0x159e6f5b), MAD_F(0x137af940), MAD_F(0x11318ef3), MAD_F(0x0ec6a507), MAD_F(0x0c3ef153), MAD_F(0x099f61c5), MAD_F(0x06ed12c5), MAD_F(0x042d4544), MAD_F(0x0165547c) }; /* scaling */ for (i = 0; i < 18; i += 3) { tmp[i + 0] = mad_f_mul(y[i + 0], scale[i + 0]); tmp[i + 1] = mad_f_mul(y[i + 1], scale[i + 1]); tmp[i + 2] = mad_f_mul(y[i + 2], scale[i + 2]); } /* SDCT-II */ sdctII(tmp, X); /* scale reduction and output accumulation */ X[0] /= 2; for (i = 1; i < 17; i += 4) { X[i + 0] = X[i + 0] / 2 - X[(i + 0) - 1]; X[i + 1] = X[i + 1] / 2 - X[(i + 1) - 1]; X[i + 2] = X[i + 2] / 2 - X[(i + 2) - 1]; X[i + 3] = X[i + 3] / 2 - X[(i + 3) - 1]; } X[17] = X[17] / 2 - X[16]; } /* * NAME: imdct36 * DESCRIPTION: perform X[18]->x[36] IMDCT using Szu-Wei Lee's fast algorithm */ static inline void imdct36(mad_fixed_t const x[18], mad_fixed_t y[36]) { mad_fixed_t tmp[18]; int i; /* DCT-IV */ dctIV(x, tmp); /* convert 18-point DCT-IV to 36-point IMDCT */ for (i = 0; i < 9; i += 3) { y[i + 0] = tmp[9 + (i + 0)]; y[i + 1] = tmp[9 + (i + 1)]; y[i + 2] = tmp[9 + (i + 2)]; } for (i = 9; i < 27; i += 3) { y[i + 0] = -tmp[36 - (9 + (i + 0)) - 1]; y[i + 1] = -tmp[36 - (9 + (i + 1)) - 1]; y[i + 2] = -tmp[36 - (9 + (i + 2)) - 1]; } for (i = 27; i < 36; i += 3) { y[i + 0] = -tmp[(i + 0) - 27]; y[i + 1] = -tmp[(i + 1) - 27]; y[i + 2] = -tmp[(i + 2) - 27]; } } # else /* * NAME: imdct36 * DESCRIPTION: perform X[18]->x[36] IMDCT */ static inline void imdct36(mad_fixed_t const X[18], mad_fixed_t x[36]) { mad_fixed_t t0, t1, t2, t3, t4, t5, t6, t7; mad_fixed_t t8, t9, t10, t11, t12, t13, t14, t15; register mad_fixed64hi_t hi; register mad_fixed64lo_t lo; MAD_F_ML0(hi, lo, X[4], MAD_F(0x0ec835e8)); MAD_F_MLA(hi, lo, X[13], MAD_F(0x061f78aa)); t6 = MAD_F_MLZ(hi, lo); MAD_F_MLA(hi, lo, (t14 = X[1] - X[10]), -MAD_F(0x061f78aa)); MAD_F_MLA(hi, lo, (t15 = X[7] + X[16]), -MAD_F(0x0ec835e8)); t0 = MAD_F_MLZ(hi, lo); MAD_F_MLA(hi, lo, (t8 = X[0] - X[11] - X[12]), MAD_F(0x0216a2a2)); MAD_F_MLA(hi, lo, (t9 = X[2] - X[9] - X[14]), MAD_F(0x09bd7ca0)); MAD_F_MLA(hi, lo, (t10 = X[3] - X[8] - X[15]), -MAD_F(0x0cb19346)); MAD_F_MLA(hi, lo, (t11 = X[5] - X[6] - X[17]), -MAD_F(0x0fdcf549)); x[7] = MAD_F_MLZ(hi, lo); x[10] = -x[7]; MAD_F_ML0(hi, lo, t8, -MAD_F(0x0cb19346)); MAD_F_MLA(hi, lo, t9, MAD_F(0x0fdcf549)); MAD_F_MLA(hi, lo, t10, MAD_F(0x0216a2a2)); MAD_F_MLA(hi, lo, t11, -MAD_F(0x09bd7ca0)); x[19] = x[34] = MAD_F_MLZ(hi, lo) - t0; t12 = X[0] - X[3] + X[8] - X[11] - X[12] + X[15]; t13 = X[2] + X[5] - X[6] - X[9] - X[14] - X[17]; MAD_F_ML0(hi, lo, t12, -MAD_F(0x0ec835e8)); MAD_F_MLA(hi, lo, t13, MAD_F(0x061f78aa)); x[22] = x[31] = MAD_F_MLZ(hi, lo) + t0; MAD_F_ML0(hi, lo, X[1], -MAD_F(0x09bd7ca0)); MAD_F_MLA(hi, lo, X[7], MAD_F(0x0216a2a2)); MAD_F_MLA(hi, lo, X[10], -MAD_F(0x0fdcf549)); MAD_F_MLA(hi, lo, X[16], MAD_F(0x0cb19346)); t1 = MAD_F_MLZ(hi, lo) + t6; MAD_F_ML0(hi, lo, X[0], MAD_F(0x03768962)); MAD_F_MLA(hi, lo, X[2], MAD_F(0x0e313245)); MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0ffc19fd)); MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0acf37ad)); MAD_F_MLA(hi, lo, X[6], MAD_F(0x04cfb0e2)); MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0898c779)); MAD_F_MLA(hi, lo, X[9], MAD_F(0x0d7e8807)); MAD_F_MLA(hi, lo, X[11], MAD_F(0x0f426cb5)); MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0bcbe352)); MAD_F_MLA(hi, lo, X[14], MAD_F(0x00b2aa3e)); MAD_F_MLA(hi, lo, X[15], -MAD_F(0x07635284)); MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0f9ee890)); x[6] = MAD_F_MLZ(hi, lo) + t1; x[11] = -x[6]; MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0f426cb5)); MAD_F_MLA(hi, lo, X[2], -MAD_F(0x00b2aa3e)); MAD_F_MLA(hi, lo, X[3], MAD_F(0x0898c779)); MAD_F_MLA(hi, lo, X[5], MAD_F(0x0f9ee890)); MAD_F_MLA(hi, lo, X[6], MAD_F(0x0acf37ad)); MAD_F_MLA(hi, lo, X[8], -MAD_F(0x07635284)); MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0e313245)); MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0bcbe352)); MAD_F_MLA(hi, lo, X[12], -MAD_F(0x03768962)); MAD_F_MLA(hi, lo, X[14], MAD_F(0x0d7e8807)); MAD_F_MLA(hi, lo, X[15], MAD_F(0x0ffc19fd)); MAD_F_MLA(hi, lo, X[17], MAD_F(0x04cfb0e2)); x[23] = x[30] = MAD_F_MLZ(hi, lo) + t1; MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0bcbe352)); MAD_F_MLA(hi, lo, X[2], MAD_F(0x0d7e8807)); MAD_F_MLA(hi, lo, X[3], -MAD_F(0x07635284)); MAD_F_MLA(hi, lo, X[5], MAD_F(0x04cfb0e2)); MAD_F_MLA(hi, lo, X[6], MAD_F(0x0f9ee890)); MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0ffc19fd)); MAD_F_MLA(hi, lo, X[9], -MAD_F(0x00b2aa3e)); MAD_F_MLA(hi, lo, X[11], MAD_F(0x03768962)); MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0f426cb5)); MAD_F_MLA(hi, lo, X[14], MAD_F(0x0e313245)); MAD_F_MLA(hi, lo, X[15], MAD_F(0x0898c779)); MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0acf37ad)); x[18] = x[35] = MAD_F_MLZ(hi, lo) - t1; MAD_F_ML0(hi, lo, X[4], MAD_F(0x061f78aa)); MAD_F_MLA(hi, lo, X[13], -MAD_F(0x0ec835e8)); t7 = MAD_F_MLZ(hi, lo); MAD_F_MLA(hi, lo, X[1], -MAD_F(0x0cb19346)); MAD_F_MLA(hi, lo, X[7], MAD_F(0x0fdcf549)); MAD_F_MLA(hi, lo, X[10], MAD_F(0x0216a2a2)); MAD_F_MLA(hi, lo, X[16], -MAD_F(0x09bd7ca0)); t2 = MAD_F_MLZ(hi, lo); MAD_F_MLA(hi, lo, X[0], MAD_F(0x04cfb0e2)); MAD_F_MLA(hi, lo, X[2], MAD_F(0x0ffc19fd)); MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0d7e8807)); MAD_F_MLA(hi, lo, X[5], MAD_F(0x03768962)); MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0bcbe352)); MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0e313245)); MAD_F_MLA(hi, lo, X[9], MAD_F(0x07635284)); MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0acf37ad)); MAD_F_MLA(hi, lo, X[12], MAD_F(0x0f9ee890)); MAD_F_MLA(hi, lo, X[14], MAD_F(0x0898c779)); MAD_F_MLA(hi, lo, X[15], MAD_F(0x00b2aa3e)); MAD_F_MLA(hi, lo, X[17], MAD_F(0x0f426cb5)); x[5] = MAD_F_MLZ(hi, lo); x[12] = -x[5]; MAD_F_ML0(hi, lo, X[0], MAD_F(0x0acf37ad)); MAD_F_MLA(hi, lo, X[2], -MAD_F(0x0898c779)); MAD_F_MLA(hi, lo, X[3], MAD_F(0x0e313245)); MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0f426cb5)); MAD_F_MLA(hi, lo, X[6], -MAD_F(0x03768962)); MAD_F_MLA(hi, lo, X[8], MAD_F(0x00b2aa3e)); MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0ffc19fd)); MAD_F_MLA(hi, lo, X[11], MAD_F(0x0f9ee890)); MAD_F_MLA(hi, lo, X[12], -MAD_F(0x04cfb0e2)); MAD_F_MLA(hi, lo, X[14], MAD_F(0x07635284)); MAD_F_MLA(hi, lo, X[15], MAD_F(0x0d7e8807)); MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0bcbe352)); x[0] = MAD_F_MLZ(hi, lo) + t2; x[17] = -x[0]; MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0f9ee890)); MAD_F_MLA(hi, lo, X[2], -MAD_F(0x07635284)); MAD_F_MLA(hi, lo, X[3], -MAD_F(0x00b2aa3e)); MAD_F_MLA(hi, lo, X[5], MAD_F(0x0bcbe352)); MAD_F_MLA(hi, lo, X[6], MAD_F(0x0f426cb5)); MAD_F_MLA(hi, lo, X[8], MAD_F(0x0d7e8807)); MAD_F_MLA(hi, lo, X[9], MAD_F(0x0898c779)); MAD_F_MLA(hi, lo, X[11], -MAD_F(0x04cfb0e2)); MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0acf37ad)); MAD_F_MLA(hi, lo, X[14], -MAD_F(0x0ffc19fd)); MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0e313245)); MAD_F_MLA(hi, lo, X[17], -MAD_F(0x03768962)); x[24] = x[29] = MAD_F_MLZ(hi, lo) + t2; MAD_F_ML0(hi, lo, X[1], -MAD_F(0x0216a2a2)); MAD_F_MLA(hi, lo, X[7], -MAD_F(0x09bd7ca0)); MAD_F_MLA(hi, lo, X[10], MAD_F(0x0cb19346)); MAD_F_MLA(hi, lo, X[16], MAD_F(0x0fdcf549)); t3 = MAD_F_MLZ(hi, lo) + t7; MAD_F_ML0(hi, lo, X[0], MAD_F(0x00b2aa3e)); MAD_F_MLA(hi, lo, X[2], MAD_F(0x03768962)); MAD_F_MLA(hi, lo, X[3], -MAD_F(0x04cfb0e2)); MAD_F_MLA(hi, lo, X[5], -MAD_F(0x07635284)); MAD_F_MLA(hi, lo, X[6], MAD_F(0x0898c779)); MAD_F_MLA(hi, lo, X[8], MAD_F(0x0acf37ad)); MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0bcbe352)); MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0d7e8807)); MAD_F_MLA(hi, lo, X[12], MAD_F(0x0e313245)); MAD_F_MLA(hi, lo, X[14], MAD_F(0x0f426cb5)); MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0f9ee890)); MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0ffc19fd)); x[8] = MAD_F_MLZ(hi, lo) + t3; x[9] = -x[8]; MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0e313245)); MAD_F_MLA(hi, lo, X[2], MAD_F(0x0bcbe352)); MAD_F_MLA(hi, lo, X[3], MAD_F(0x0f9ee890)); MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0898c779)); MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0ffc19fd)); MAD_F_MLA(hi, lo, X[8], MAD_F(0x04cfb0e2)); MAD_F_MLA(hi, lo, X[9], MAD_F(0x0f426cb5)); MAD_F_MLA(hi, lo, X[11], -MAD_F(0x00b2aa3e)); MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0d7e8807)); MAD_F_MLA(hi, lo, X[14], -MAD_F(0x03768962)); MAD_F_MLA(hi, lo, X[15], MAD_F(0x0acf37ad)); MAD_F_MLA(hi, lo, X[17], MAD_F(0x07635284)); x[21] = x[32] = MAD_F_MLZ(hi, lo) + t3; MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0d7e8807)); MAD_F_MLA(hi, lo, X[2], MAD_F(0x0f426cb5)); MAD_F_MLA(hi, lo, X[3], MAD_F(0x0acf37ad)); MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0ffc19fd)); MAD_F_MLA(hi, lo, X[6], -MAD_F(0x07635284)); MAD_F_MLA(hi, lo, X[8], MAD_F(0x0f9ee890)); MAD_F_MLA(hi, lo, X[9], MAD_F(0x03768962)); MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0e313245)); MAD_F_MLA(hi, lo, X[12], MAD_F(0x00b2aa3e)); MAD_F_MLA(hi, lo, X[14], MAD_F(0x0bcbe352)); MAD_F_MLA(hi, lo, X[15], -MAD_F(0x04cfb0e2)); MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0898c779)); x[20] = x[33] = MAD_F_MLZ(hi, lo) - t3; MAD_F_ML0(hi, lo, t14, -MAD_F(0x0ec835e8)); MAD_F_MLA(hi, lo, t15, MAD_F(0x061f78aa)); t4 = MAD_F_MLZ(hi, lo) - t7; MAD_F_ML0(hi, lo, t12, MAD_F(0x061f78aa)); MAD_F_MLA(hi, lo, t13, MAD_F(0x0ec835e8)); x[4] = MAD_F_MLZ(hi, lo) + t4; x[13] = -x[4]; MAD_F_ML0(hi, lo, t8, MAD_F(0x09bd7ca0)); MAD_F_MLA(hi, lo, t9, -MAD_F(0x0216a2a2)); MAD_F_MLA(hi, lo, t10, MAD_F(0x0fdcf549)); MAD_F_MLA(hi, lo, t11, -MAD_F(0x0cb19346)); x[1] = MAD_F_MLZ(hi, lo) + t4; x[16] = -x[1]; MAD_F_ML0(hi, lo, t8, -MAD_F(0x0fdcf549)); MAD_F_MLA(hi, lo, t9, -MAD_F(0x0cb19346)); MAD_F_MLA(hi, lo, t10, -MAD_F(0x09bd7ca0)); MAD_F_MLA(hi, lo, t11, -MAD_F(0x0216a2a2)); x[25] = x[28] = MAD_F_MLZ(hi, lo) + t4; MAD_F_ML0(hi, lo, X[1], -MAD_F(0x0fdcf549)); MAD_F_MLA(hi, lo, X[7], -MAD_F(0x0cb19346)); MAD_F_MLA(hi, lo, X[10], -MAD_F(0x09bd7ca0)); MAD_F_MLA(hi, lo, X[16], -MAD_F(0x0216a2a2)); t5 = MAD_F_MLZ(hi, lo) - t6; MAD_F_ML0(hi, lo, X[0], MAD_F(0x0898c779)); MAD_F_MLA(hi, lo, X[2], MAD_F(0x04cfb0e2)); MAD_F_MLA(hi, lo, X[3], MAD_F(0x0bcbe352)); MAD_F_MLA(hi, lo, X[5], MAD_F(0x00b2aa3e)); MAD_F_MLA(hi, lo, X[6], MAD_F(0x0e313245)); MAD_F_MLA(hi, lo, X[8], -MAD_F(0x03768962)); MAD_F_MLA(hi, lo, X[9], MAD_F(0x0f9ee890)); MAD_F_MLA(hi, lo, X[11], -MAD_F(0x07635284)); MAD_F_MLA(hi, lo, X[12], MAD_F(0x0ffc19fd)); MAD_F_MLA(hi, lo, X[14], -MAD_F(0x0acf37ad)); MAD_F_MLA(hi, lo, X[15], MAD_F(0x0f426cb5)); MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0d7e8807)); x[2] = MAD_F_MLZ(hi, lo) + t5; x[15] = -x[2]; MAD_F_ML0(hi, lo, X[0], MAD_F(0x07635284)); MAD_F_MLA(hi, lo, X[2], MAD_F(0x0acf37ad)); MAD_F_MLA(hi, lo, X[3], MAD_F(0x03768962)); MAD_F_MLA(hi, lo, X[5], MAD_F(0x0d7e8807)); MAD_F_MLA(hi, lo, X[6], -MAD_F(0x00b2aa3e)); MAD_F_MLA(hi, lo, X[8], MAD_F(0x0f426cb5)); MAD_F_MLA(hi, lo, X[9], -MAD_F(0x04cfb0e2)); MAD_F_MLA(hi, lo, X[11], MAD_F(0x0ffc19fd)); MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0898c779)); MAD_F_MLA(hi, lo, X[14], MAD_F(0x0f9ee890)); MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0bcbe352)); MAD_F_MLA(hi, lo, X[17], MAD_F(0x0e313245)); x[3] = MAD_F_MLZ(hi, lo) + t5; x[14] = -x[3]; MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0ffc19fd)); MAD_F_MLA(hi, lo, X[2], -MAD_F(0x0f9ee890)); MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0f426cb5)); MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0e313245)); MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0d7e8807)); MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0bcbe352)); MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0acf37ad)); MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0898c779)); MAD_F_MLA(hi, lo, X[12], -MAD_F(0x07635284)); MAD_F_MLA(hi, lo, X[14], -MAD_F(0x04cfb0e2)); MAD_F_MLA(hi, lo, X[15], -MAD_F(0x03768962)); MAD_F_MLA(hi, lo, X[17], -MAD_F(0x00b2aa3e)); x[26] = x[27] = MAD_F_MLZ(hi, lo) + t5; } # endif /* * NAME: III_imdct_l() * DESCRIPTION: perform IMDCT and windowing for long blocks */ static void III_imdct_l(mad_fixed_t const X[18], mad_fixed_t z[36], unsigned int block_type) { unsigned int i; /* IMDCT */ imdct36(X, z); /* windowing */ switch (block_type) { case 0: /* normal window */ # if defined(ASO_INTERLEAVE1) { register mad_fixed_t tmp1, tmp2; tmp1 = window_l[0]; tmp2 = window_l[1]; for (i = 0; i < 34; i += 2) { z[i + 0] = mad_f_mul(z[i + 0], tmp1); tmp1 = window_l[i + 2]; z[i + 1] = mad_f_mul(z[i + 1], tmp2); tmp2 = window_l[i + 3]; } z[34] = mad_f_mul(z[34], tmp1); z[35] = mad_f_mul(z[35], tmp2); } # elif defined(ASO_INTERLEAVE2) { register mad_fixed_t tmp1, tmp2; tmp1 = z[0]; tmp2 = window_l[0]; for (i = 0; i < 35; ++i) { z[i] = mad_f_mul(tmp1, tmp2); tmp1 = z[i + 1]; tmp2 = window_l[i + 1]; } z[35] = mad_f_mul(tmp1, tmp2); } # elif 1 for (i = 0; i < 36; i += 4) { z[i + 0] = mad_f_mul(z[i + 0], window_l[i + 0]); z[i + 1] = mad_f_mul(z[i + 1], window_l[i + 1]); z[i + 2] = mad_f_mul(z[i + 2], window_l[i + 2]); z[i + 3] = mad_f_mul(z[i + 3], window_l[i + 3]); } # else for (i = 0; i < 36; ++i) z[i] = mad_f_mul(z[i], window_l[i]); # endif break; case 1: /* start block */ for (i = 0; i < 18; i += 3) { z[i + 0] = mad_f_mul(z[i + 0], window_l[i + 0]); z[i + 1] = mad_f_mul(z[i + 1], window_l[i + 1]); z[i + 2] = mad_f_mul(z[i + 2], window_l[i + 2]); } /* (i = 18; i < 24; ++i) z[i] unchanged */ for (i = 24; i < 30; ++i) z[i] = mad_f_mul(z[i], window_s[i - 18]); for (i = 30; i < 36; ++i) z[i] = 0; break; case 3: /* stop block */ for (i = 0; i < 6; ++i) z[i] = 0; for (i = 6; i < 12; ++i) z[i] = mad_f_mul(z[i], window_s[i - 6]); /* (i = 12; i < 18; ++i) z[i] unchanged */ for (i = 18; i < 36; i += 3) { z[i + 0] = mad_f_mul(z[i + 0], window_l[i + 0]); z[i + 1] = mad_f_mul(z[i + 1], window_l[i + 1]); z[i + 2] = mad_f_mul(z[i + 2], window_l[i + 2]); } break; } } # endif /* ASO_IMDCT */ /* * NAME: III_imdct_s() * DESCRIPTION: perform IMDCT and windowing for short blocks */ static void III_imdct_s(mad_fixed_t const X[18], mad_fixed_t z[36]) { mad_fixed_t y[36], *yptr; mad_fixed_t const *wptr; int w, i; register mad_fixed64hi_t hi; register mad_fixed64lo_t lo; /* IMDCT */ yptr = &y[0]; for (w = 0; w < 3; ++w) { register mad_fixed_t const (*s)[6]; s = imdct_s; for (i = 0; i < 3; ++i) { MAD_F_ML0(hi, lo, X[0], (*s)[0]); MAD_F_MLA(hi, lo, X[1], (*s)[1]); MAD_F_MLA(hi, lo, X[2], (*s)[2]); MAD_F_MLA(hi, lo, X[3], (*s)[3]); MAD_F_MLA(hi, lo, X[4], (*s)[4]); MAD_F_MLA(hi, lo, X[5], (*s)[5]); yptr[i + 0] = MAD_F_MLZ(hi, lo); yptr[5 - i] = -yptr[i + 0]; ++s; MAD_F_ML0(hi, lo, X[0], (*s)[0]); MAD_F_MLA(hi, lo, X[1], (*s)[1]); MAD_F_MLA(hi, lo, X[2], (*s)[2]); MAD_F_MLA(hi, lo, X[3], (*s)[3]); MAD_F_MLA(hi, lo, X[4], (*s)[4]); MAD_F_MLA(hi, lo, X[5], (*s)[5]); yptr[ i + 6] = MAD_F_MLZ(hi, lo); yptr[11 - i] = yptr[i + 6]; ++s; } yptr += 12; X += 6; } /* windowing, overlapping and concatenation */ yptr = &y[0]; wptr = &window_s[0]; for (i = 0; i < 6; ++i) { z[i + 0] = 0; z[i + 6] = mad_f_mul(yptr[ 0 + 0], wptr[0]); MAD_F_ML0(hi, lo, yptr[ 0 + 6], wptr[6]); MAD_F_MLA(hi, lo, yptr[12 + 0], wptr[0]); z[i + 12] = MAD_F_MLZ(hi, lo); MAD_F_ML0(hi, lo, yptr[12 + 6], wptr[6]); MAD_F_MLA(hi, lo, yptr[24 + 0], wptr[0]); z[i + 18] = MAD_F_MLZ(hi, lo); z[i + 24] = mad_f_mul(yptr[24 + 6], wptr[6]); z[i + 30] = 0; ++yptr; ++wptr; } } /* * NAME: III_overlap() * DESCRIPTION: perform overlap-add of windowed IMDCT outputs */ static void III_overlap(mad_fixed_t const output[36], mad_fixed_t overlap[18], mad_fixed_t sample[18][32], unsigned int sb) { unsigned int i; # if defined(ASO_INTERLEAVE2) { register mad_fixed_t tmp1, tmp2; tmp1 = overlap[0]; tmp2 = overlap[1]; for (i = 0; i < 16; i += 2) { sample[i + 0][sb] = output[i + 0 + 0] + tmp1; overlap[i + 0] = output[i + 0 + 18]; tmp1 = overlap[i + 2]; sample[i + 1][sb] = output[i + 1 + 0] + tmp2; overlap[i + 1] = output[i + 1 + 18]; tmp2 = overlap[i + 3]; } sample[16][sb] = output[16 + 0] + tmp1; overlap[16] = output[16 + 18]; sample[17][sb] = output[17 + 0] + tmp2; overlap[17] = output[17 + 18]; } # elif 0 for (i = 0; i < 18; i += 2) { sample[i + 0][sb] = output[i + 0 + 0] + overlap[i + 0]; overlap[i + 0] = output[i + 0 + 18]; sample[i + 1][sb] = output[i + 1 + 0] + overlap[i + 1]; overlap[i + 1] = output[i + 1 + 18]; } # else for (i = 0; i < 18; ++i) { sample[i][sb] = output[i + 0] + overlap[i]; overlap[i] = output[i + 18]; } # endif } /* * NAME: III_overlap_z() * DESCRIPTION: perform "overlap-add" of zero IMDCT outputs */ static inline void III_overlap_z(mad_fixed_t overlap[18], mad_fixed_t sample[18][32], unsigned int sb) { unsigned int i; # if defined(ASO_INTERLEAVE2) { register mad_fixed_t tmp1, tmp2; tmp1 = overlap[0]; tmp2 = overlap[1]; for (i = 0; i < 16; i += 2) { sample[i + 0][sb] = tmp1; overlap[i + 0] = 0; tmp1 = overlap[i + 2]; sample[i + 1][sb] = tmp2; overlap[i + 1] = 0; tmp2 = overlap[i + 3]; } sample[16][sb] = tmp1; overlap[16] = 0; sample[17][sb] = tmp2; overlap[17] = 0; } # else for (i = 0; i < 18; ++i) { sample[i][sb] = overlap[i]; overlap[i] = 0; } # endif } /* * NAME: III_freqinver() * DESCRIPTION: perform subband frequency inversion for odd sample lines */ static void III_freqinver(mad_fixed_t sample[18][32], unsigned int sb) { unsigned int i; # if 1 || defined(ASO_INTERLEAVE1) || defined(ASO_INTERLEAVE2) { register mad_fixed_t tmp1, tmp2; tmp1 = sample[1][sb]; tmp2 = sample[3][sb]; for (i = 1; i < 13; i += 4) { sample[i + 0][sb] = -tmp1; tmp1 = sample[i + 4][sb]; sample[i + 2][sb] = -tmp2; tmp2 = sample[i + 6][sb]; } sample[13][sb] = -tmp1; tmp1 = sample[17][sb]; sample[15][sb] = -tmp2; sample[17][sb] = -tmp1; } # else for (i = 1; i < 18; i += 2) sample[i][sb] = -sample[i][sb]; # endif } /* * NAME: III_decode() * DESCRIPTION: decode frame main_data */ static enum mad_error III_decode(struct mad_bitptr *ptr, struct mad_frame *frame, struct sideinfo *si, unsigned int nch) { struct mad_header *header = &frame->header; unsigned int sfreqi, ngr, gr; { unsigned int sfreq; sfreq = header->samplerate; if (header->flags & MAD_FLAG_MPEG_2_5_EXT) sfreq *= 2; /* 48000 => 0, 44100 => 1, 32000 => 2, 24000 => 3, 22050 => 4, 16000 => 5 */ sfreqi = ((sfreq >> 7) & 0x000f) + ((sfreq >> 15) & 0x0001) - 8; if (header->flags & MAD_FLAG_MPEG_2_5_EXT) sfreqi += 3; } /* scalefactors, Huffman decoding, requantization */ ngr = (header->flags & MAD_FLAG_LSF_EXT) ? 1 : 2; for (gr = 0; gr < ngr; ++gr) { struct granule *granule = &si->gr[gr]; unsigned char const *sfbwidth[2]; mad_fixed_t xr[2][576]; unsigned int ch; enum mad_error error; for (ch = 0; ch < nch; ++ch) { struct channel *channel = &granule->ch[ch]; unsigned int part2_length; sfbwidth[ch] = sfbwidth_table[sfreqi].l; if (channel->block_type == 2) { sfbwidth[ch] = (channel->flags & mixed_block_flag) ? sfbwidth_table[sfreqi].m : sfbwidth_table[sfreqi].s; } if (header->flags & MAD_FLAG_LSF_EXT) { part2_length = III_scalefactors_lsf(ptr, channel, ch == 0 ? 0 : &si->gr[1].ch[1], header->mode_extension); } else { part2_length = III_scalefactors(ptr, channel, &si->gr[0].ch[ch], gr == 0 ? 0 : si->scfsi[ch]); } error = III_huffdecode(ptr, xr[ch], channel, sfbwidth[ch], part2_length); if (error) return error; } /* joint stereo processing */ if (header->mode == MAD_MODE_JOINT_STEREO && header->mode_extension) { error = III_stereo(xr, granule, header, sfbwidth[0]); if (error) return error; } /* reordering, alias reduction, IMDCT, overlap-add, frequency inversion */ for (ch = 0; ch < nch; ++ch) { struct channel const *channel = &granule->ch[ch]; mad_fixed_t (*sample)[32] = &frame->sbsample[ch][18 * gr]; unsigned int sb, l, i, sblimit; mad_fixed_t output[36]; if (channel->block_type == 2) { III_reorder(xr[ch], channel, sfbwidth[ch]); # if !defined(OPT_STRICT) /* * According to ISO/IEC 11172-3, "Alias reduction is not applied for * granules with block_type == 2 (short block)." However, other * sources suggest alias reduction should indeed be performed on the * lower two subbands of mixed blocks. Most other implementations do * this, so by default we will too. */ if (channel->flags & mixed_block_flag) III_aliasreduce(xr[ch], 36); # endif } else III_aliasreduce(xr[ch], 576); l = 0; /* subbands 0-1 */ if (channel->block_type != 2 || (channel->flags & mixed_block_flag)) { unsigned int block_type; block_type = channel->block_type; if (channel->flags & mixed_block_flag) block_type = 0; /* long blocks */ for (sb = 0; sb < 2; ++sb, l += 18) { III_imdct_l(&xr[ch][l], output, block_type); III_overlap(output, (*frame->overlap)[ch][sb], sample, sb); } } else { /* short blocks */ for (sb = 0; sb < 2; ++sb, l += 18) { III_imdct_s(&xr[ch][l], output); III_overlap(output, (*frame->overlap)[ch][sb], sample, sb); } } III_freqinver(sample, 1); /* (nonzero) subbands 2-31 */ i = 576; while (i > 36 && xr[ch][i - 1] == 0) --i; sblimit = 32 - (576 - i) / 18; if (channel->block_type != 2) { /* long blocks */ for (sb = 2; sb < sblimit; ++sb, l += 18) { III_imdct_l(&xr[ch][l], output, channel->block_type); III_overlap(output, (*frame->overlap)[ch][sb], sample, sb); if (sb & 1) III_freqinver(sample, sb); } } else { /* short blocks */ for (sb = 2; sb < sblimit; ++sb, l += 18) { III_imdct_s(&xr[ch][l], output); III_overlap(output, (*frame->overlap)[ch][sb], sample, sb); if (sb & 1) III_freqinver(sample, sb); } } /* remaining (zero) subbands */ for (sb = sblimit; sb < 32; ++sb) { III_overlap_z((*frame->overlap)[ch][sb], sample, sb); if (sb & 1) III_freqinver(sample, sb); } } } return MAD_ERROR_NONE; } /* * NAME: layer->III() * DESCRIPTION: decode a single Layer III frame */ int mad_layer_III(struct mad_stream *stream, struct mad_frame *frame) { struct mad_header *header = &frame->header; unsigned int nch, priv_bitlen, next_md_begin = 0; unsigned int si_len, data_bitlen, md_len; unsigned int frame_space, frame_used, frame_free; struct mad_bitptr ptr; struct sideinfo si; enum mad_error error; int result = 0; /* allocate Layer III dynamic structures */ if (stream->main_data == 0) { stream->main_data = malloc(MAD_BUFFER_MDLEN); if (stream->main_data == 0) { stream->error = MAD_ERROR_NOMEM; return -1; } } if (frame->overlap == 0) { frame->overlap = calloc(2 * 32 * 18, sizeof(mad_fixed_t)); if (frame->overlap == 0) { stream->error = MAD_ERROR_NOMEM; return -1; } } nch = MAD_NCHANNELS(header); si_len = (header->flags & MAD_FLAG_LSF_EXT) ? (nch == 1 ? 9 : 17) : (nch == 1 ? 17 : 32); /* check frame sanity */ if (stream->next_frame - mad_bit_nextbyte(&stream->ptr) < (signed int) si_len) { stream->error = MAD_ERROR_BADFRAMELEN; stream->md_len = 0; return -1; } /* check CRC word */ if (header->flags & MAD_FLAG_PROTECTION) { header->crc_check = mad_bit_crc(stream->ptr, si_len * CHAR_BIT, header->crc_check); if (header->crc_check != header->crc_target && !(frame->options & MAD_OPTION_IGNORECRC)) { stream->error = MAD_ERROR_BADCRC; result = -1; } } /* decode frame side information */ error = III_sideinfo(&stream->ptr, nch, header->flags & MAD_FLAG_LSF_EXT, &si, &data_bitlen, &priv_bitlen); if (error && result == 0) { stream->error = error; result = -1; } header->flags |= priv_bitlen; header->private_bits |= si.private_bits; /* find main_data of next frame */ { struct mad_bitptr peek; unsigned long header; mad_bit_init(&peek, stream->next_frame); header = mad_bit_read(&peek, 32); if ((header & 0xffe60000L) /* syncword | layer */ == 0xffe20000L) { if (!(header & 0x00010000L)) /* protection_bit */ mad_bit_skip(&peek, 16); /* crc_check */ next_md_begin = mad_bit_read(&peek, (header & 0x00080000L) /* ID */ ? 9 : 8); } mad_bit_finish(&peek); } /* find main_data of this frame */ frame_space = stream->next_frame - mad_bit_nextbyte(&stream->ptr); if (next_md_begin > si.main_data_begin + frame_space) next_md_begin = 0; md_len = si.main_data_begin + frame_space - next_md_begin; frame_used = 0; if (si.main_data_begin == 0) { ptr = stream->ptr; stream->md_len = 0; frame_used = md_len; } else { if (si.main_data_begin > stream->md_len) { if (result == 0) { stream->error = MAD_ERROR_BADDATAPTR; result = -1; } } else { mad_bit_init(&ptr, *stream->main_data + stream->md_len - si.main_data_begin); if (md_len > si.main_data_begin) { assert(stream->md_len + md_len - si.main_data_begin <= MAD_BUFFER_MDLEN); memcpy(*stream->main_data + stream->md_len, mad_bit_nextbyte(&stream->ptr), frame_used = md_len - si.main_data_begin); stream->md_len += frame_used; } } } frame_free = frame_space - frame_used; /* decode main_data */ if (result == 0) { error = III_decode(&ptr, frame, &si, nch); if (error) { stream->error = error; result = -1; } /* designate ancillary bits */ stream->anc_ptr = ptr; stream->anc_bitlen = md_len * CHAR_BIT - data_bitlen; } # if 0 && defined(DEBUG) fprintf(stderr, "main_data_begin:%u, md_len:%u, frame_free:%u, " "data_bitlen:%u, anc_bitlen: %u\n", si.main_data_begin, md_len, frame_free, data_bitlen, stream->anc_bitlen); # endif /* preload main_data buffer with up to 511 bytes for next frame(s) */ if (frame_free >= next_md_begin) { memcpy(*stream->main_data, stream->next_frame - next_md_begin, next_md_begin); stream->md_len = next_md_begin; } else { if (md_len < si.main_data_begin) { unsigned int extra; extra = si.main_data_begin - md_len; if (extra + frame_free > next_md_begin) extra = next_md_begin - frame_free; if (extra < stream->md_len) { memmove(*stream->main_data, *stream->main_data + stream->md_len - extra, extra); stream->md_len = extra; } } else stream->md_len = 0; memcpy(*stream->main_data + stream->md_len, stream->next_frame - frame_free, frame_free); stream->md_len += frame_free; } return result; } praat-6.0.04/external/mp3/mad_layer3.h000066400000000000000000000020251261542461700174310ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: layer3.h,v 1.10 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBMAD_LAYER3_H # define LIBMAD_LAYER3_H # include "mad_stream.h" # include "mad_frame.h" int mad_layer_III(struct mad_stream *, struct mad_frame *); # endif praat-6.0.04/external/mp3/mad_qc_table.dat000066400000000000000000000076231261542461700203360ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: qc_table.dat,v 1.7 2004/01/23 09:41:32 rob Exp $ */ /* * These are the Layer II classes of quantization. * The table is derived from Table B.4 of ISO/IEC 11172-3. */ { 3, 2, 5, MAD_F(0x15555555) /* 1.33333333333 => 1.33333333209, e 0.00000000124 */, MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ }, { 5, 3, 7, MAD_F(0x1999999a) /* 1.60000000000 => 1.60000000149, e -0.00000000149 */, MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ }, { 7, 0, 3, MAD_F(0x12492492) /* 1.14285714286 => 1.14285714179, e 0.00000000107 */, MAD_F(0x04000000) /* 0.25000000000 => 0.25000000000, e 0.00000000000 */ }, { 9, 4, 10, MAD_F(0x1c71c71c) /* 1.77777777777 => 1.77777777612, e 0.00000000165 */, MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ }, { 15, 0, 4, MAD_F(0x11111111) /* 1.06666666666 => 1.06666666642, e 0.00000000024 */, MAD_F(0x02000000) /* 0.12500000000 => 0.12500000000, e 0.00000000000 */ }, { 31, 0, 5, MAD_F(0x10842108) /* 1.03225806452 => 1.03225806355, e 0.00000000097 */, MAD_F(0x01000000) /* 0.06250000000 => 0.06250000000, e 0.00000000000 */ }, { 63, 0, 6, MAD_F(0x10410410) /* 1.01587301587 => 1.01587301493, e 0.00000000094 */, MAD_F(0x00800000) /* 0.03125000000 => 0.03125000000, e 0.00000000000 */ }, { 127, 0, 7, MAD_F(0x10204081) /* 1.00787401575 => 1.00787401572, e 0.00000000003 */, MAD_F(0x00400000) /* 0.01562500000 => 0.01562500000, e 0.00000000000 */ }, { 255, 0, 8, MAD_F(0x10101010) /* 1.00392156863 => 1.00392156839, e 0.00000000024 */, MAD_F(0x00200000) /* 0.00781250000 => 0.00781250000, e 0.00000000000 */ }, { 511, 0, 9, MAD_F(0x10080402) /* 1.00195694716 => 1.00195694715, e 0.00000000001 */, MAD_F(0x00100000) /* 0.00390625000 => 0.00390625000, e 0.00000000000 */ }, { 1023, 0, 10, MAD_F(0x10040100) /* 1.00097751711 => 1.00097751617, e 0.00000000094 */, MAD_F(0x00080000) /* 0.00195312500 => 0.00195312500, e 0.00000000000 */ }, { 2047, 0, 11, MAD_F(0x10020040) /* 1.00048851979 => 1.00048851967, e 0.00000000012 */, MAD_F(0x00040000) /* 0.00097656250 => 0.00097656250, e 0.00000000000 */ }, { 4095, 0, 12, MAD_F(0x10010010) /* 1.00024420024 => 1.00024420023, e 0.00000000001 */, MAD_F(0x00020000) /* 0.00048828125 => 0.00048828125, e 0.00000000000 */ }, { 8191, 0, 13, MAD_F(0x10008004) /* 1.00012208522 => 1.00012208521, e 0.00000000001 */, MAD_F(0x00010000) /* 0.00024414063 => 0.00024414062, e 0.00000000000 */ }, { 16383, 0, 14, MAD_F(0x10004001) /* 1.00006103888 => 1.00006103888, e -0.00000000000 */, MAD_F(0x00008000) /* 0.00012207031 => 0.00012207031, e -0.00000000000 */ }, { 32767, 0, 15, MAD_F(0x10002000) /* 1.00003051851 => 1.00003051758, e 0.00000000093 */, MAD_F(0x00004000) /* 0.00006103516 => 0.00006103516, e 0.00000000000 */ }, { 65535, 0, 16, MAD_F(0x10001000) /* 1.00001525902 => 1.00001525879, e 0.00000000023 */, MAD_F(0x00002000) /* 0.00003051758 => 0.00003051758, e 0.00000000000 */ } praat-6.0.04/external/mp3/mad_rq_table.dat000066400000000000000000016647671261542461700204000ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: rq_table.dat,v 1.7 2004/01/23 09:41:32 rob Exp $ */ /* * This is the lookup table used to compute x^(4/3) for Layer III * requantization. To maintain the best possible accuracy, the value is * stored as a normalized mantissa with exponent. The requantization * algorithm recombines these parts with appropriate scaling. */ /* 0 */ { MAD_F(0x00000000) /* 0.000000000 */, 0 }, /* 1 */ { MAD_F(0x04000000) /* 0.250000000 */, 2 }, /* 2 */ { MAD_F(0x050a28be) /* 0.314980262 */, 3 }, /* 3 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 4 }, /* 4 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 4 }, /* 5 */ { MAD_F(0x04466275) /* 0.267183742 */, 5 }, /* 6 */ { MAD_F(0x05738c72) /* 0.340710111 */, 5 }, /* 7 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 5 }, /* 8 */ { MAD_F(0x04000000) /* 0.250000000 */, 6 }, /* 9 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 6 }, /* 10 */ { MAD_F(0x0562d694) /* 0.336630420 */, 6 }, /* 11 */ { MAD_F(0x061dae96) /* 0.382246578 */, 6 }, /* 12 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 6 }, /* 13 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 6 }, /* 14 */ { MAD_F(0x0437be65) /* 0.263609310 */, 7 }, /* 15 */ { MAD_F(0x049fc824) /* 0.289009227 */, 7 }, /* 16 */ { MAD_F(0x050a28be) /* 0.314980262 */, 7 }, /* 17 */ { MAD_F(0x0576c6f5) /* 0.341498336 */, 7 }, /* 18 */ { MAD_F(0x05e58c0b) /* 0.368541759 */, 7 }, /* 19 */ { MAD_F(0x06566361) /* 0.396090870 */, 7 }, /* 20 */ { MAD_F(0x06c93a2e) /* 0.424127753 */, 7 }, /* 21 */ { MAD_F(0x073dff3e) /* 0.452635998 */, 7 }, /* 22 */ { MAD_F(0x07b4a2bc) /* 0.481600510 */, 7 }, /* 23 */ { MAD_F(0x04168b05) /* 0.255503674 */, 8 }, /* 24 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 8 }, /* 25 */ { MAD_F(0x04919b6a) /* 0.285548607 */, 8 }, /* 26 */ { MAD_F(0x04d065fb) /* 0.300878507 */, 8 }, /* 27 */ { MAD_F(0x05100000) /* 0.316406250 */, 8 }, /* 28 */ { MAD_F(0x05506451) /* 0.332126919 */, 8 }, /* 29 */ { MAD_F(0x05918e15) /* 0.348035890 */, 8 }, /* 30 */ { MAD_F(0x05d378bb) /* 0.364128809 */, 8 }, /* 31 */ { MAD_F(0x06161ff3) /* 0.380401563 */, 8 }, /* 32 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 8 }, /* 33 */ { MAD_F(0x069d9400) /* 0.413471222 */, 8 }, /* 34 */ { MAD_F(0x06e2594c) /* 0.430260942 */, 8 }, /* 35 */ { MAD_F(0x0727cc11) /* 0.447216097 */, 8 }, /* 36 */ { MAD_F(0x076de8fc) /* 0.464333519 */, 8 }, /* 37 */ { MAD_F(0x07b4ace3) /* 0.481610189 */, 8 }, /* 38 */ { MAD_F(0x07fc14bf) /* 0.499043224 */, 8 }, /* 39 */ { MAD_F(0x04220ed7) /* 0.258314934 */, 9 }, /* 40 */ { MAD_F(0x04466275) /* 0.267183742 */, 9 }, /* 41 */ { MAD_F(0x046b03e7) /* 0.276126771 */, 9 }, /* 42 */ { MAD_F(0x048ff1e8) /* 0.285142811 */, 9 }, /* 43 */ { MAD_F(0x04b52b3f) /* 0.294230696 */, 9 }, /* 44 */ { MAD_F(0x04daaec0) /* 0.303389310 */, 9 }, /* 45 */ { MAD_F(0x05007b49) /* 0.312617576 */, 9 }, /* 46 */ { MAD_F(0x05268fc6) /* 0.321914457 */, 9 }, /* 47 */ { MAD_F(0x054ceb2a) /* 0.331278957 */, 9 }, /* 48 */ { MAD_F(0x05738c72) /* 0.340710111 */, 9 }, /* 49 */ { MAD_F(0x059a72a5) /* 0.350206992 */, 9 }, /* 50 */ { MAD_F(0x05c19cd3) /* 0.359768701 */, 9 }, /* 51 */ { MAD_F(0x05e90a12) /* 0.369394372 */, 9 }, /* 52 */ { MAD_F(0x0610b982) /* 0.379083164 */, 9 }, /* 53 */ { MAD_F(0x0638aa48) /* 0.388834268 */, 9 }, /* 54 */ { MAD_F(0x0660db91) /* 0.398646895 */, 9 }, /* 55 */ { MAD_F(0x06894c90) /* 0.408520284 */, 9 }, /* 56 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 9 }, /* 57 */ { MAD_F(0x06daeaa1) /* 0.428446415 */, 9 }, /* 58 */ { MAD_F(0x07041636) /* 0.438497744 */, 9 }, /* 59 */ { MAD_F(0x072d7e8b) /* 0.448607009 */, 9 }, /* 60 */ { MAD_F(0x075722ef) /* 0.458773552 */, 9 }, /* 61 */ { MAD_F(0x078102b8) /* 0.468996735 */, 9 }, /* 62 */ { MAD_F(0x07ab1d3e) /* 0.479275937 */, 9 }, /* 63 */ { MAD_F(0x07d571e0) /* 0.489610555 */, 9 }, /* 64 */ { MAD_F(0x04000000) /* 0.250000000 */, 10 }, /* 65 */ { MAD_F(0x04156381) /* 0.255221850 */, 10 }, /* 66 */ { MAD_F(0x042ae32a) /* 0.260470548 */, 10 }, /* 67 */ { MAD_F(0x04407eb1) /* 0.265745823 */, 10 }, /* 68 */ { MAD_F(0x045635cf) /* 0.271047409 */, 10 }, /* 69 */ { MAD_F(0x046c083e) /* 0.276375048 */, 10 }, /* 70 */ { MAD_F(0x0481f5bb) /* 0.281728487 */, 10 }, /* 71 */ { MAD_F(0x0497fe03) /* 0.287107481 */, 10 }, /* 72 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 10 }, /* 73 */ { MAD_F(0x04c45df6) /* 0.297941173 */, 10 }, /* 74 */ { MAD_F(0x04dab524) /* 0.303395408 */, 10 }, /* 75 */ { MAD_F(0x04f12624) /* 0.308874267 */, 10 }, /* 76 */ { MAD_F(0x0507b0bc) /* 0.314377532 */, 10 }, /* 77 */ { MAD_F(0x051e54b1) /* 0.319904987 */, 10 }, /* 78 */ { MAD_F(0x053511cb) /* 0.325456423 */, 10 }, /* 79 */ { MAD_F(0x054be7d4) /* 0.331031635 */, 10 }, /* 80 */ { MAD_F(0x0562d694) /* 0.336630420 */, 10 }, /* 81 */ { MAD_F(0x0579ddd8) /* 0.342252584 */, 10 }, /* 82 */ { MAD_F(0x0590fd6c) /* 0.347897931 */, 10 }, /* 83 */ { MAD_F(0x05a8351c) /* 0.353566275 */, 10 }, /* 84 */ { MAD_F(0x05bf84b8) /* 0.359257429 */, 10 }, /* 85 */ { MAD_F(0x05d6ec0e) /* 0.364971213 */, 10 }, /* 86 */ { MAD_F(0x05ee6aef) /* 0.370707448 */, 10 }, /* 87 */ { MAD_F(0x0606012b) /* 0.376465960 */, 10 }, /* 88 */ { MAD_F(0x061dae96) /* 0.382246578 */, 10 }, /* 89 */ { MAD_F(0x06357302) /* 0.388049134 */, 10 }, /* 90 */ { MAD_F(0x064d4e43) /* 0.393873464 */, 10 }, /* 91 */ { MAD_F(0x0665402d) /* 0.399719406 */, 10 }, /* 92 */ { MAD_F(0x067d4896) /* 0.405586801 */, 10 }, /* 93 */ { MAD_F(0x06956753) /* 0.411475493 */, 10 }, /* 94 */ { MAD_F(0x06ad9c3d) /* 0.417385331 */, 10 }, /* 95 */ { MAD_F(0x06c5e72b) /* 0.423316162 */, 10 }, /* 96 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 10 }, /* 97 */ { MAD_F(0x06f6be73) /* 0.435240221 */, 10 }, /* 98 */ { MAD_F(0x070f4a80) /* 0.441233161 */, 10 }, /* 99 */ { MAD_F(0x0727ebf7) /* 0.447246519 */, 10 }, /* 100 */ { MAD_F(0x0740a2b2) /* 0.453280160 */, 10 }, /* 101 */ { MAD_F(0x07596e8d) /* 0.459333946 */, 10 }, /* 102 */ { MAD_F(0x07724f64) /* 0.465407744 */, 10 }, /* 103 */ { MAD_F(0x078b4514) /* 0.471501425 */, 10 }, /* 104 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 10 }, /* 105 */ { MAD_F(0x07bd6e75) /* 0.483747918 */, 10 }, /* 106 */ { MAD_F(0x07d6a1e2) /* 0.489900479 */, 10 }, /* 107 */ { MAD_F(0x07efe9a1) /* 0.496072418 */, 10 }, /* 108 */ { MAD_F(0x0404a2c9) /* 0.251131807 */, 11 }, /* 109 */ { MAD_F(0x04115aca) /* 0.254236974 */, 11 }, /* 110 */ { MAD_F(0x041e1cc4) /* 0.257351652 */, 11 }, /* 111 */ { MAD_F(0x042ae8a7) /* 0.260475783 */, 11 }, /* 112 */ { MAD_F(0x0437be65) /* 0.263609310 */, 11 }, /* 113 */ { MAD_F(0x04449dee) /* 0.266752177 */, 11 }, /* 114 */ { MAD_F(0x04518733) /* 0.269904329 */, 11 }, /* 115 */ { MAD_F(0x045e7a26) /* 0.273065710 */, 11 }, /* 116 */ { MAD_F(0x046b76b9) /* 0.276236269 */, 11 }, /* 117 */ { MAD_F(0x04787cdc) /* 0.279415952 */, 11 }, /* 118 */ { MAD_F(0x04858c83) /* 0.282604707 */, 11 }, /* 119 */ { MAD_F(0x0492a59f) /* 0.285802482 */, 11 }, /* 120 */ { MAD_F(0x049fc824) /* 0.289009227 */, 11 }, /* 121 */ { MAD_F(0x04acf402) /* 0.292224893 */, 11 }, /* 122 */ { MAD_F(0x04ba292e) /* 0.295449429 */, 11 }, /* 123 */ { MAD_F(0x04c7679a) /* 0.298682788 */, 11 }, /* 124 */ { MAD_F(0x04d4af3a) /* 0.301924921 */, 11 }, /* 125 */ { MAD_F(0x04e20000) /* 0.305175781 */, 11 }, /* 126 */ { MAD_F(0x04ef59e0) /* 0.308435322 */, 11 }, /* 127 */ { MAD_F(0x04fcbcce) /* 0.311703498 */, 11 }, /* 128 */ { MAD_F(0x050a28be) /* 0.314980262 */, 11 }, /* 129 */ { MAD_F(0x05179da4) /* 0.318265572 */, 11 }, /* 130 */ { MAD_F(0x05251b73) /* 0.321559381 */, 11 }, /* 131 */ { MAD_F(0x0532a220) /* 0.324861647 */, 11 }, /* 132 */ { MAD_F(0x054031a0) /* 0.328172327 */, 11 }, /* 133 */ { MAD_F(0x054dc9e7) /* 0.331491377 */, 11 }, /* 134 */ { MAD_F(0x055b6ae9) /* 0.334818756 */, 11 }, /* 135 */ { MAD_F(0x0569149c) /* 0.338154423 */, 11 }, /* 136 */ { MAD_F(0x0576c6f5) /* 0.341498336 */, 11 }, /* 137 */ { MAD_F(0x058481e9) /* 0.344850455 */, 11 }, /* 138 */ { MAD_F(0x0592456d) /* 0.348210741 */, 11 }, /* 139 */ { MAD_F(0x05a01176) /* 0.351579152 */, 11 }, /* 140 */ { MAD_F(0x05ade5fa) /* 0.354955651 */, 11 }, /* 141 */ { MAD_F(0x05bbc2ef) /* 0.358340200 */, 11 }, /* 142 */ { MAD_F(0x05c9a84a) /* 0.361732758 */, 11 }, /* 143 */ { MAD_F(0x05d79601) /* 0.365133291 */, 11 }, /* 144 */ { MAD_F(0x05e58c0b) /* 0.368541759 */, 11 }, /* 145 */ { MAD_F(0x05f38a5d) /* 0.371958126 */, 11 }, /* 146 */ { MAD_F(0x060190ee) /* 0.375382356 */, 11 }, /* 147 */ { MAD_F(0x060f9fb3) /* 0.378814413 */, 11 }, /* 148 */ { MAD_F(0x061db6a5) /* 0.382254261 */, 11 }, /* 149 */ { MAD_F(0x062bd5b8) /* 0.385701865 */, 11 }, /* 150 */ { MAD_F(0x0639fce4) /* 0.389157191 */, 11 }, /* 151 */ { MAD_F(0x06482c1f) /* 0.392620204 */, 11 }, /* 152 */ { MAD_F(0x06566361) /* 0.396090870 */, 11 }, /* 153 */ { MAD_F(0x0664a2a0) /* 0.399569155 */, 11 }, /* 154 */ { MAD_F(0x0672e9d4) /* 0.403055027 */, 11 }, /* 155 */ { MAD_F(0x068138f3) /* 0.406548452 */, 11 }, /* 156 */ { MAD_F(0x068f8ff5) /* 0.410049398 */, 11 }, /* 157 */ { MAD_F(0x069deed1) /* 0.413557833 */, 11 }, /* 158 */ { MAD_F(0x06ac557f) /* 0.417073724 */, 11 }, /* 159 */ { MAD_F(0x06bac3f6) /* 0.420597041 */, 11 }, /* 160 */ { MAD_F(0x06c93a2e) /* 0.424127753 */, 11 }, /* 161 */ { MAD_F(0x06d7b81f) /* 0.427665827 */, 11 }, /* 162 */ { MAD_F(0x06e63dc0) /* 0.431211234 */, 11 }, /* 163 */ { MAD_F(0x06f4cb09) /* 0.434763944 */, 11 }, /* 164 */ { MAD_F(0x07035ff3) /* 0.438323927 */, 11 }, /* 165 */ { MAD_F(0x0711fc75) /* 0.441891153 */, 11 }, /* 166 */ { MAD_F(0x0720a087) /* 0.445465593 */, 11 }, /* 167 */ { MAD_F(0x072f4c22) /* 0.449047217 */, 11 }, /* 168 */ { MAD_F(0x073dff3e) /* 0.452635998 */, 11 }, /* 169 */ { MAD_F(0x074cb9d3) /* 0.456231906 */, 11 }, /* 170 */ { MAD_F(0x075b7bdb) /* 0.459834914 */, 11 }, /* 171 */ { MAD_F(0x076a454c) /* 0.463444993 */, 11 }, /* 172 */ { MAD_F(0x07791620) /* 0.467062117 */, 11 }, /* 173 */ { MAD_F(0x0787ee50) /* 0.470686258 */, 11 }, /* 174 */ { MAD_F(0x0796cdd4) /* 0.474317388 */, 11 }, /* 175 */ { MAD_F(0x07a5b4a5) /* 0.477955481 */, 11 }, /* 176 */ { MAD_F(0x07b4a2bc) /* 0.481600510 */, 11 }, /* 177 */ { MAD_F(0x07c39812) /* 0.485252449 */, 11 }, /* 178 */ { MAD_F(0x07d294a0) /* 0.488911273 */, 11 }, /* 179 */ { MAD_F(0x07e1985f) /* 0.492576954 */, 11 }, /* 180 */ { MAD_F(0x07f0a348) /* 0.496249468 */, 11 }, /* 181 */ { MAD_F(0x07ffb554) /* 0.499928790 */, 11 }, /* 182 */ { MAD_F(0x0407673f) /* 0.251807447 */, 12 }, /* 183 */ { MAD_F(0x040ef75e) /* 0.253653877 */, 12 }, /* 184 */ { MAD_F(0x04168b05) /* 0.255503674 */, 12 }, /* 185 */ { MAD_F(0x041e2230) /* 0.257356825 */, 12 }, /* 186 */ { MAD_F(0x0425bcdd) /* 0.259213318 */, 12 }, /* 187 */ { MAD_F(0x042d5b07) /* 0.261073141 */, 12 }, /* 188 */ { MAD_F(0x0434fcad) /* 0.262936282 */, 12 }, /* 189 */ { MAD_F(0x043ca1c9) /* 0.264802730 */, 12 }, /* 190 */ { MAD_F(0x04444a5a) /* 0.266672472 */, 12 }, /* 191 */ { MAD_F(0x044bf65d) /* 0.268545497 */, 12 }, /* 192 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 12 }, /* 193 */ { MAD_F(0x045b58a9) /* 0.272301352 */, 12 }, /* 194 */ { MAD_F(0x04630eed) /* 0.274184158 */, 12 }, /* 195 */ { MAD_F(0x046ac896) /* 0.276070203 */, 12 }, /* 196 */ { MAD_F(0x047285a2) /* 0.277959474 */, 12 }, /* 197 */ { MAD_F(0x047a460c) /* 0.279851960 */, 12 }, /* 198 */ { MAD_F(0x048209d3) /* 0.281747652 */, 12 }, /* 199 */ { MAD_F(0x0489d0f4) /* 0.283646538 */, 12 }, /* 200 */ { MAD_F(0x04919b6a) /* 0.285548607 */, 12 }, /* 201 */ { MAD_F(0x04996935) /* 0.287453849 */, 12 }, /* 202 */ { MAD_F(0x04a13a50) /* 0.289362253 */, 12 }, /* 203 */ { MAD_F(0x04a90eba) /* 0.291273810 */, 12 }, /* 204 */ { MAD_F(0x04b0e66e) /* 0.293188507 */, 12 }, /* 205 */ { MAD_F(0x04b8c16c) /* 0.295106336 */, 12 }, /* 206 */ { MAD_F(0x04c09faf) /* 0.297027285 */, 12 }, /* 207 */ { MAD_F(0x04c88135) /* 0.298951346 */, 12 }, /* 208 */ { MAD_F(0x04d065fb) /* 0.300878507 */, 12 }, /* 209 */ { MAD_F(0x04d84dff) /* 0.302808759 */, 12 }, /* 210 */ { MAD_F(0x04e0393e) /* 0.304742092 */, 12 }, /* 211 */ { MAD_F(0x04e827b6) /* 0.306678497 */, 12 }, /* 212 */ { MAD_F(0x04f01963) /* 0.308617963 */, 12 }, /* 213 */ { MAD_F(0x04f80e44) /* 0.310560480 */, 12 }, /* 214 */ { MAD_F(0x05000655) /* 0.312506041 */, 12 }, /* 215 */ { MAD_F(0x05080195) /* 0.314454634 */, 12 }, /* 216 */ { MAD_F(0x05100000) /* 0.316406250 */, 12 }, /* 217 */ { MAD_F(0x05180194) /* 0.318360880 */, 12 }, /* 218 */ { MAD_F(0x0520064f) /* 0.320318516 */, 12 }, /* 219 */ { MAD_F(0x05280e2d) /* 0.322279147 */, 12 }, /* 220 */ { MAD_F(0x0530192e) /* 0.324242764 */, 12 }, /* 221 */ { MAD_F(0x0538274e) /* 0.326209359 */, 12 }, /* 222 */ { MAD_F(0x0540388a) /* 0.328178922 */, 12 }, /* 223 */ { MAD_F(0x05484ce2) /* 0.330151445 */, 12 }, /* 224 */ { MAD_F(0x05506451) /* 0.332126919 */, 12 }, /* 225 */ { MAD_F(0x05587ed5) /* 0.334105334 */, 12 }, /* 226 */ { MAD_F(0x05609c6e) /* 0.336086683 */, 12 }, /* 227 */ { MAD_F(0x0568bd17) /* 0.338070956 */, 12 }, /* 228 */ { MAD_F(0x0570e0cf) /* 0.340058145 */, 12 }, /* 229 */ { MAD_F(0x05790793) /* 0.342048241 */, 12 }, /* 230 */ { MAD_F(0x05813162) /* 0.344041237 */, 12 }, /* 231 */ { MAD_F(0x05895e39) /* 0.346037122 */, 12 }, /* 232 */ { MAD_F(0x05918e15) /* 0.348035890 */, 12 }, /* 233 */ { MAD_F(0x0599c0f4) /* 0.350037532 */, 12 }, /* 234 */ { MAD_F(0x05a1f6d5) /* 0.352042040 */, 12 }, /* 235 */ { MAD_F(0x05aa2fb5) /* 0.354049405 */, 12 }, /* 236 */ { MAD_F(0x05b26b92) /* 0.356059619 */, 12 }, /* 237 */ { MAD_F(0x05baaa69) /* 0.358072674 */, 12 }, /* 238 */ { MAD_F(0x05c2ec39) /* 0.360088563 */, 12 }, /* 239 */ { MAD_F(0x05cb3100) /* 0.362107278 */, 12 }, /* 240 */ { MAD_F(0x05d378bb) /* 0.364128809 */, 12 }, /* 241 */ { MAD_F(0x05dbc368) /* 0.366153151 */, 12 }, /* 242 */ { MAD_F(0x05e41105) /* 0.368180294 */, 12 }, /* 243 */ { MAD_F(0x05ec6190) /* 0.370210231 */, 12 }, /* 244 */ { MAD_F(0x05f4b507) /* 0.372242955 */, 12 }, /* 245 */ { MAD_F(0x05fd0b68) /* 0.374278458 */, 12 }, /* 246 */ { MAD_F(0x060564b1) /* 0.376316732 */, 12 }, /* 247 */ { MAD_F(0x060dc0e0) /* 0.378357769 */, 12 }, /* 248 */ { MAD_F(0x06161ff3) /* 0.380401563 */, 12 }, /* 249 */ { MAD_F(0x061e81e8) /* 0.382448106 */, 12 }, /* 250 */ { MAD_F(0x0626e6bc) /* 0.384497391 */, 12 }, /* 251 */ { MAD_F(0x062f4e6f) /* 0.386549409 */, 12 }, /* 252 */ { MAD_F(0x0637b8fd) /* 0.388604155 */, 12 }, /* 253 */ { MAD_F(0x06402666) /* 0.390661620 */, 12 }, /* 254 */ { MAD_F(0x064896a7) /* 0.392721798 */, 12 }, /* 255 */ { MAD_F(0x065109be) /* 0.394784681 */, 12 }, /* 256 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 12 }, /* 257 */ { MAD_F(0x0661f867) /* 0.398918536 */, 12 }, /* 258 */ { MAD_F(0x066a73f5) /* 0.400989493 */, 12 }, /* 259 */ { MAD_F(0x0672f252) /* 0.403063128 */, 12 }, /* 260 */ { MAD_F(0x067b737c) /* 0.405139433 */, 12 }, /* 261 */ { MAD_F(0x0683f771) /* 0.407218402 */, 12 }, /* 262 */ { MAD_F(0x068c7e2f) /* 0.409300027 */, 12 }, /* 263 */ { MAD_F(0x069507b5) /* 0.411384303 */, 12 }, /* 264 */ { MAD_F(0x069d9400) /* 0.413471222 */, 12 }, /* 265 */ { MAD_F(0x06a6230f) /* 0.415560778 */, 12 }, /* 266 */ { MAD_F(0x06aeb4e0) /* 0.417652964 */, 12 }, /* 267 */ { MAD_F(0x06b74971) /* 0.419747773 */, 12 }, /* 268 */ { MAD_F(0x06bfe0c0) /* 0.421845199 */, 12 }, /* 269 */ { MAD_F(0x06c87acc) /* 0.423945235 */, 12 }, /* 270 */ { MAD_F(0x06d11794) /* 0.426047876 */, 12 }, /* 271 */ { MAD_F(0x06d9b714) /* 0.428153114 */, 12 }, /* 272 */ { MAD_F(0x06e2594c) /* 0.430260942 */, 12 }, /* 273 */ { MAD_F(0x06eafe3a) /* 0.432371356 */, 12 }, /* 274 */ { MAD_F(0x06f3a5dc) /* 0.434484348 */, 12 }, /* 275 */ { MAD_F(0x06fc5030) /* 0.436599912 */, 12 }, /* 276 */ { MAD_F(0x0704fd35) /* 0.438718042 */, 12 }, /* 277 */ { MAD_F(0x070dacea) /* 0.440838732 */, 12 }, /* 278 */ { MAD_F(0x07165f4b) /* 0.442961975 */, 12 }, /* 279 */ { MAD_F(0x071f1459) /* 0.445087765 */, 12 }, /* 280 */ { MAD_F(0x0727cc11) /* 0.447216097 */, 12 }, /* 281 */ { MAD_F(0x07308671) /* 0.449346964 */, 12 }, /* 282 */ { MAD_F(0x07394378) /* 0.451480360 */, 12 }, /* 283 */ { MAD_F(0x07420325) /* 0.453616280 */, 12 }, /* 284 */ { MAD_F(0x074ac575) /* 0.455754717 */, 12 }, /* 285 */ { MAD_F(0x07538a67) /* 0.457895665 */, 12 }, /* 286 */ { MAD_F(0x075c51fa) /* 0.460039119 */, 12 }, /* 287 */ { MAD_F(0x07651c2c) /* 0.462185072 */, 12 }, /* 288 */ { MAD_F(0x076de8fc) /* 0.464333519 */, 12 }, /* 289 */ { MAD_F(0x0776b867) /* 0.466484455 */, 12 }, /* 290 */ { MAD_F(0x077f8a6d) /* 0.468637872 */, 12 }, /* 291 */ { MAD_F(0x07885f0b) /* 0.470793767 */, 12 }, /* 292 */ { MAD_F(0x07913641) /* 0.472952132 */, 12 }, /* 293 */ { MAD_F(0x079a100c) /* 0.475112962 */, 12 }, /* 294 */ { MAD_F(0x07a2ec6c) /* 0.477276252 */, 12 }, /* 295 */ { MAD_F(0x07abcb5f) /* 0.479441997 */, 12 }, /* 296 */ { MAD_F(0x07b4ace3) /* 0.481610189 */, 12 }, /* 297 */ { MAD_F(0x07bd90f6) /* 0.483780825 */, 12 }, /* 298 */ { MAD_F(0x07c67798) /* 0.485953899 */, 12 }, /* 299 */ { MAD_F(0x07cf60c7) /* 0.488129404 */, 12 }, /* 300 */ { MAD_F(0x07d84c81) /* 0.490307336 */, 12 }, /* 301 */ { MAD_F(0x07e13ac5) /* 0.492487690 */, 12 }, /* 302 */ { MAD_F(0x07ea2b92) /* 0.494670459 */, 12 }, /* 303 */ { MAD_F(0x07f31ee6) /* 0.496855639 */, 12 }, /* 304 */ { MAD_F(0x07fc14bf) /* 0.499043224 */, 12 }, /* 305 */ { MAD_F(0x0402868e) /* 0.250616605 */, 13 }, /* 306 */ { MAD_F(0x040703ff) /* 0.251712795 */, 13 }, /* 307 */ { MAD_F(0x040b82b0) /* 0.252810180 */, 13 }, /* 308 */ { MAD_F(0x041002a1) /* 0.253908756 */, 13 }, /* 309 */ { MAD_F(0x041483d1) /* 0.255008523 */, 13 }, /* 310 */ { MAD_F(0x04190640) /* 0.256109476 */, 13 }, /* 311 */ { MAD_F(0x041d89ed) /* 0.257211614 */, 13 }, /* 312 */ { MAD_F(0x04220ed7) /* 0.258314934 */, 13 }, /* 313 */ { MAD_F(0x042694fe) /* 0.259419433 */, 13 }, /* 314 */ { MAD_F(0x042b1c60) /* 0.260525110 */, 13 }, /* 315 */ { MAD_F(0x042fa4fe) /* 0.261631960 */, 13 }, /* 316 */ { MAD_F(0x04342ed7) /* 0.262739982 */, 13 }, /* 317 */ { MAD_F(0x0438b9e9) /* 0.263849174 */, 13 }, /* 318 */ { MAD_F(0x043d4635) /* 0.264959533 */, 13 }, /* 319 */ { MAD_F(0x0441d3b9) /* 0.266071056 */, 13 }, /* 320 */ { MAD_F(0x04466275) /* 0.267183742 */, 13 }, /* 321 */ { MAD_F(0x044af269) /* 0.268297587 */, 13 }, /* 322 */ { MAD_F(0x044f8393) /* 0.269412589 */, 13 }, /* 323 */ { MAD_F(0x045415f3) /* 0.270528746 */, 13 }, /* 324 */ { MAD_F(0x0458a989) /* 0.271646056 */, 13 }, /* 325 */ { MAD_F(0x045d3e53) /* 0.272764515 */, 13 }, /* 326 */ { MAD_F(0x0461d451) /* 0.273884123 */, 13 }, /* 327 */ { MAD_F(0x04666b83) /* 0.275004875 */, 13 }, /* 328 */ { MAD_F(0x046b03e7) /* 0.276126771 */, 13 }, /* 329 */ { MAD_F(0x046f9d7e) /* 0.277249808 */, 13 }, /* 330 */ { MAD_F(0x04743847) /* 0.278373983 */, 13 }, /* 331 */ { MAD_F(0x0478d440) /* 0.279499294 */, 13 }, /* 332 */ { MAD_F(0x047d716a) /* 0.280625739 */, 13 }, /* 333 */ { MAD_F(0x04820fc3) /* 0.281753315 */, 13 }, /* 334 */ { MAD_F(0x0486af4c) /* 0.282882021 */, 13 }, /* 335 */ { MAD_F(0x048b5003) /* 0.284011853 */, 13 }, /* 336 */ { MAD_F(0x048ff1e8) /* 0.285142811 */, 13 }, /* 337 */ { MAD_F(0x049494fb) /* 0.286274891 */, 13 }, /* 338 */ { MAD_F(0x0499393a) /* 0.287408091 */, 13 }, /* 339 */ { MAD_F(0x049ddea5) /* 0.288542409 */, 13 }, /* 340 */ { MAD_F(0x04a2853c) /* 0.289677844 */, 13 }, /* 341 */ { MAD_F(0x04a72cfe) /* 0.290814392 */, 13 }, /* 342 */ { MAD_F(0x04abd5ea) /* 0.291952051 */, 13 }, /* 343 */ { MAD_F(0x04b08000) /* 0.293090820 */, 13 }, /* 344 */ { MAD_F(0x04b52b3f) /* 0.294230696 */, 13 }, /* 345 */ { MAD_F(0x04b9d7a7) /* 0.295371678 */, 13 }, /* 346 */ { MAD_F(0x04be8537) /* 0.296513762 */, 13 }, /* 347 */ { MAD_F(0x04c333ee) /* 0.297656947 */, 13 }, /* 348 */ { MAD_F(0x04c7e3cc) /* 0.298801231 */, 13 }, /* 349 */ { MAD_F(0x04cc94d1) /* 0.299946611 */, 13 }, /* 350 */ { MAD_F(0x04d146fb) /* 0.301093085 */, 13 }, /* 351 */ { MAD_F(0x04d5fa4b) /* 0.302240653 */, 13 }, /* 352 */ { MAD_F(0x04daaec0) /* 0.303389310 */, 13 }, /* 353 */ { MAD_F(0x04df6458) /* 0.304539056 */, 13 }, /* 354 */ { MAD_F(0x04e41b14) /* 0.305689888 */, 13 }, /* 355 */ { MAD_F(0x04e8d2f3) /* 0.306841804 */, 13 }, /* 356 */ { MAD_F(0x04ed8bf5) /* 0.307994802 */, 13 }, /* 357 */ { MAD_F(0x04f24618) /* 0.309148880 */, 13 }, /* 358 */ { MAD_F(0x04f7015d) /* 0.310304037 */, 13 }, /* 359 */ { MAD_F(0x04fbbdc3) /* 0.311460269 */, 13 }, /* 360 */ { MAD_F(0x05007b49) /* 0.312617576 */, 13 }, /* 361 */ { MAD_F(0x050539ef) /* 0.313775954 */, 13 }, /* 362 */ { MAD_F(0x0509f9b4) /* 0.314935403 */, 13 }, /* 363 */ { MAD_F(0x050eba98) /* 0.316095920 */, 13 }, /* 364 */ { MAD_F(0x05137c9a) /* 0.317257503 */, 13 }, /* 365 */ { MAD_F(0x05183fba) /* 0.318420150 */, 13 }, /* 366 */ { MAD_F(0x051d03f7) /* 0.319583859 */, 13 }, /* 367 */ { MAD_F(0x0521c950) /* 0.320748629 */, 13 }, /* 368 */ { MAD_F(0x05268fc6) /* 0.321914457 */, 13 }, /* 369 */ { MAD_F(0x052b5757) /* 0.323081342 */, 13 }, /* 370 */ { MAD_F(0x05302003) /* 0.324249281 */, 13 }, /* 371 */ { MAD_F(0x0534e9ca) /* 0.325418273 */, 13 }, /* 372 */ { MAD_F(0x0539b4ab) /* 0.326588316 */, 13 }, /* 373 */ { MAD_F(0x053e80a6) /* 0.327759407 */, 13 }, /* 374 */ { MAD_F(0x05434db9) /* 0.328931546 */, 13 }, /* 375 */ { MAD_F(0x05481be5) /* 0.330104730 */, 13 }, /* 376 */ { MAD_F(0x054ceb2a) /* 0.331278957 */, 13 }, /* 377 */ { MAD_F(0x0551bb85) /* 0.332454225 */, 13 }, /* 378 */ { MAD_F(0x05568cf8) /* 0.333630533 */, 13 }, /* 379 */ { MAD_F(0x055b5f81) /* 0.334807879 */, 13 }, /* 380 */ { MAD_F(0x05603321) /* 0.335986261 */, 13 }, /* 381 */ { MAD_F(0x056507d6) /* 0.337165677 */, 13 }, /* 382 */ { MAD_F(0x0569dda0) /* 0.338346125 */, 13 }, /* 383 */ { MAD_F(0x056eb47f) /* 0.339527604 */, 13 }, /* 384 */ { MAD_F(0x05738c72) /* 0.340710111 */, 13 }, /* 385 */ { MAD_F(0x05786578) /* 0.341893646 */, 13 }, /* 386 */ { MAD_F(0x057d3f92) /* 0.343078205 */, 13 }, /* 387 */ { MAD_F(0x05821abf) /* 0.344263788 */, 13 }, /* 388 */ { MAD_F(0x0586f6fd) /* 0.345450393 */, 13 }, /* 389 */ { MAD_F(0x058bd44e) /* 0.346638017 */, 13 }, /* 390 */ { MAD_F(0x0590b2b0) /* 0.347826659 */, 13 }, /* 391 */ { MAD_F(0x05959222) /* 0.349016318 */, 13 }, /* 392 */ { MAD_F(0x059a72a5) /* 0.350206992 */, 13 }, /* 393 */ { MAD_F(0x059f5438) /* 0.351398678 */, 13 }, /* 394 */ { MAD_F(0x05a436da) /* 0.352591376 */, 13 }, /* 395 */ { MAD_F(0x05a91a8c) /* 0.353785083 */, 13 }, /* 396 */ { MAD_F(0x05adff4c) /* 0.354979798 */, 13 }, /* 397 */ { MAD_F(0x05b2e51a) /* 0.356175519 */, 13 }, /* 398 */ { MAD_F(0x05b7cbf5) /* 0.357372244 */, 13 }, /* 399 */ { MAD_F(0x05bcb3de) /* 0.358569972 */, 13 }, /* 400 */ { MAD_F(0x05c19cd3) /* 0.359768701 */, 13 }, /* 401 */ { MAD_F(0x05c686d5) /* 0.360968429 */, 13 }, /* 402 */ { MAD_F(0x05cb71e2) /* 0.362169156 */, 13 }, /* 403 */ { MAD_F(0x05d05dfb) /* 0.363370878 */, 13 }, /* 404 */ { MAD_F(0x05d54b1f) /* 0.364573594 */, 13 }, /* 405 */ { MAD_F(0x05da394d) /* 0.365777304 */, 13 }, /* 406 */ { MAD_F(0x05df2885) /* 0.366982004 */, 13 }, /* 407 */ { MAD_F(0x05e418c7) /* 0.368187694 */, 13 }, /* 408 */ { MAD_F(0x05e90a12) /* 0.369394372 */, 13 }, /* 409 */ { MAD_F(0x05edfc66) /* 0.370602036 */, 13 }, /* 410 */ { MAD_F(0x05f2efc2) /* 0.371810684 */, 13 }, /* 411 */ { MAD_F(0x05f7e426) /* 0.373020316 */, 13 }, /* 412 */ { MAD_F(0x05fcd992) /* 0.374230929 */, 13 }, /* 413 */ { MAD_F(0x0601d004) /* 0.375442522 */, 13 }, /* 414 */ { MAD_F(0x0606c77d) /* 0.376655093 */, 13 }, /* 415 */ { MAD_F(0x060bbffd) /* 0.377868641 */, 13 }, /* 416 */ { MAD_F(0x0610b982) /* 0.379083164 */, 13 }, /* 417 */ { MAD_F(0x0615b40c) /* 0.380298661 */, 13 }, /* 418 */ { MAD_F(0x061aaf9c) /* 0.381515130 */, 13 }, /* 419 */ { MAD_F(0x061fac2f) /* 0.382732569 */, 13 }, /* 420 */ { MAD_F(0x0624a9c7) /* 0.383950977 */, 13 }, /* 421 */ { MAD_F(0x0629a863) /* 0.385170352 */, 13 }, /* 422 */ { MAD_F(0x062ea802) /* 0.386390694 */, 13 }, /* 423 */ { MAD_F(0x0633a8a3) /* 0.387611999 */, 13 }, /* 424 */ { MAD_F(0x0638aa48) /* 0.388834268 */, 13 }, /* 425 */ { MAD_F(0x063dacee) /* 0.390057497 */, 13 }, /* 426 */ { MAD_F(0x0642b096) /* 0.391281687 */, 13 }, /* 427 */ { MAD_F(0x0647b53f) /* 0.392506834 */, 13 }, /* 428 */ { MAD_F(0x064cbae9) /* 0.393732939 */, 13 }, /* 429 */ { MAD_F(0x0651c193) /* 0.394959999 */, 13 }, /* 430 */ { MAD_F(0x0656c93d) /* 0.396188012 */, 13 }, /* 431 */ { MAD_F(0x065bd1e7) /* 0.397416978 */, 13 }, /* 432 */ { MAD_F(0x0660db91) /* 0.398646895 */, 13 }, /* 433 */ { MAD_F(0x0665e639) /* 0.399877761 */, 13 }, /* 434 */ { MAD_F(0x066af1df) /* 0.401109575 */, 13 }, /* 435 */ { MAD_F(0x066ffe84) /* 0.402342335 */, 13 }, /* 436 */ { MAD_F(0x06750c26) /* 0.403576041 */, 13 }, /* 437 */ { MAD_F(0x067a1ac6) /* 0.404810690 */, 13 }, /* 438 */ { MAD_F(0x067f2a62) /* 0.406046281 */, 13 }, /* 439 */ { MAD_F(0x06843afb) /* 0.407282813 */, 13 }, /* 440 */ { MAD_F(0x06894c90) /* 0.408520284 */, 13 }, /* 441 */ { MAD_F(0x068e5f21) /* 0.409758693 */, 13 }, /* 442 */ { MAD_F(0x069372ae) /* 0.410998038 */, 13 }, /* 443 */ { MAD_F(0x06988735) /* 0.412238319 */, 13 }, /* 444 */ { MAD_F(0x069d9cb7) /* 0.413479532 */, 13 }, /* 445 */ { MAD_F(0x06a2b333) /* 0.414721679 */, 13 }, /* 446 */ { MAD_F(0x06a7caa9) /* 0.415964756 */, 13 }, /* 447 */ { MAD_F(0x06ace318) /* 0.417208762 */, 13 }, /* 448 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 13 }, /* 449 */ { MAD_F(0x06b716e2) /* 0.419699557 */, 13 }, /* 450 */ { MAD_F(0x06bc323b) /* 0.420946343 */, 13 }, /* 451 */ { MAD_F(0x06c14e8d) /* 0.422194054 */, 13 }, /* 452 */ { MAD_F(0x06c66bd6) /* 0.423442686 */, 13 }, /* 453 */ { MAD_F(0x06cb8a17) /* 0.424692240 */, 13 }, /* 454 */ { MAD_F(0x06d0a94e) /* 0.425942714 */, 13 }, /* 455 */ { MAD_F(0x06d5c97c) /* 0.427194106 */, 13 }, /* 456 */ { MAD_F(0x06daeaa1) /* 0.428446415 */, 13 }, /* 457 */ { MAD_F(0x06e00cbb) /* 0.429699640 */, 13 }, /* 458 */ { MAD_F(0x06e52fca) /* 0.430953779 */, 13 }, /* 459 */ { MAD_F(0x06ea53cf) /* 0.432208832 */, 13 }, /* 460 */ { MAD_F(0x06ef78c8) /* 0.433464796 */, 13 }, /* 461 */ { MAD_F(0x06f49eb6) /* 0.434721671 */, 13 }, /* 462 */ { MAD_F(0x06f9c597) /* 0.435979455 */, 13 }, /* 463 */ { MAD_F(0x06feed6d) /* 0.437238146 */, 13 }, /* 464 */ { MAD_F(0x07041636) /* 0.438497744 */, 13 }, /* 465 */ { MAD_F(0x07093ff2) /* 0.439758248 */, 13 }, /* 466 */ { MAD_F(0x070e6aa0) /* 0.441019655 */, 13 }, /* 467 */ { MAD_F(0x07139641) /* 0.442281965 */, 13 }, /* 468 */ { MAD_F(0x0718c2d3) /* 0.443545176 */, 13 }, /* 469 */ { MAD_F(0x071df058) /* 0.444809288 */, 13 }, /* 470 */ { MAD_F(0x07231ecd) /* 0.446074298 */, 13 }, /* 471 */ { MAD_F(0x07284e34) /* 0.447340205 */, 13 }, /* 472 */ { MAD_F(0x072d7e8b) /* 0.448607009 */, 13 }, /* 473 */ { MAD_F(0x0732afd2) /* 0.449874708 */, 13 }, /* 474 */ { MAD_F(0x0737e209) /* 0.451143300 */, 13 }, /* 475 */ { MAD_F(0x073d1530) /* 0.452412785 */, 13 }, /* 476 */ { MAD_F(0x07424946) /* 0.453683161 */, 13 }, /* 477 */ { MAD_F(0x07477e4b) /* 0.454954427 */, 13 }, /* 478 */ { MAD_F(0x074cb43e) /* 0.456226581 */, 13 }, /* 479 */ { MAD_F(0x0751eb20) /* 0.457499623 */, 13 }, /* 480 */ { MAD_F(0x075722ef) /* 0.458773552 */, 13 }, /* 481 */ { MAD_F(0x075c5bac) /* 0.460048365 */, 13 }, /* 482 */ { MAD_F(0x07619557) /* 0.461324062 */, 13 }, /* 483 */ { MAD_F(0x0766cfee) /* 0.462600642 */, 13 }, /* 484 */ { MAD_F(0x076c0b72) /* 0.463878102 */, 13 }, /* 485 */ { MAD_F(0x077147e2) /* 0.465156443 */, 13 }, /* 486 */ { MAD_F(0x0776853e) /* 0.466435663 */, 13 }, /* 487 */ { MAD_F(0x077bc385) /* 0.467715761 */, 13 }, /* 488 */ { MAD_F(0x078102b8) /* 0.468996735 */, 13 }, /* 489 */ { MAD_F(0x078642d6) /* 0.470278584 */, 13 }, /* 490 */ { MAD_F(0x078b83de) /* 0.471561307 */, 13 }, /* 491 */ { MAD_F(0x0790c5d1) /* 0.472844904 */, 13 }, /* 492 */ { MAD_F(0x079608ae) /* 0.474129372 */, 13 }, /* 493 */ { MAD_F(0x079b4c74) /* 0.475414710 */, 13 }, /* 494 */ { MAD_F(0x07a09124) /* 0.476700918 */, 13 }, /* 495 */ { MAD_F(0x07a5d6bd) /* 0.477987994 */, 13 }, /* 496 */ { MAD_F(0x07ab1d3e) /* 0.479275937 */, 13 }, /* 497 */ { MAD_F(0x07b064a8) /* 0.480564746 */, 13 }, /* 498 */ { MAD_F(0x07b5acfb) /* 0.481854420 */, 13 }, /* 499 */ { MAD_F(0x07baf635) /* 0.483144957 */, 13 }, /* 500 */ { MAD_F(0x07c04056) /* 0.484436356 */, 13 }, /* 501 */ { MAD_F(0x07c58b5f) /* 0.485728617 */, 13 }, /* 502 */ { MAD_F(0x07cad74e) /* 0.487021738 */, 13 }, /* 503 */ { MAD_F(0x07d02424) /* 0.488315717 */, 13 }, /* 504 */ { MAD_F(0x07d571e0) /* 0.489610555 */, 13 }, /* 505 */ { MAD_F(0x07dac083) /* 0.490906249 */, 13 }, /* 506 */ { MAD_F(0x07e0100a) /* 0.492202799 */, 13 }, /* 507 */ { MAD_F(0x07e56078) /* 0.493500203 */, 13 }, /* 508 */ { MAD_F(0x07eab1ca) /* 0.494798460 */, 13 }, /* 509 */ { MAD_F(0x07f00401) /* 0.496097570 */, 13 }, /* 510 */ { MAD_F(0x07f5571d) /* 0.497397530 */, 13 }, /* 511 */ { MAD_F(0x07faab1c) /* 0.498698341 */, 13 }, /* 512 */ { MAD_F(0x04000000) /* 0.250000000 */, 14 }, /* 513 */ { MAD_F(0x0402aae3) /* 0.250651254 */, 14 }, /* 514 */ { MAD_F(0x04055638) /* 0.251302930 */, 14 }, /* 515 */ { MAD_F(0x040801ff) /* 0.251955030 */, 14 }, /* 516 */ { MAD_F(0x040aae37) /* 0.252607552 */, 14 }, /* 517 */ { MAD_F(0x040d5ae0) /* 0.253260495 */, 14 }, /* 518 */ { MAD_F(0x041007fa) /* 0.253913860 */, 14 }, /* 519 */ { MAD_F(0x0412b586) /* 0.254567645 */, 14 }, /* 520 */ { MAD_F(0x04156381) /* 0.255221850 */, 14 }, /* 521 */ { MAD_F(0x041811ee) /* 0.255876475 */, 14 }, /* 522 */ { MAD_F(0x041ac0cb) /* 0.256531518 */, 14 }, /* 523 */ { MAD_F(0x041d7018) /* 0.257186980 */, 14 }, /* 524 */ { MAD_F(0x04201fd5) /* 0.257842860 */, 14 }, /* 525 */ { MAD_F(0x0422d003) /* 0.258499157 */, 14 }, /* 526 */ { MAD_F(0x042580a0) /* 0.259155872 */, 14 }, /* 527 */ { MAD_F(0x042831ad) /* 0.259813002 */, 14 }, /* 528 */ { MAD_F(0x042ae32a) /* 0.260470548 */, 14 }, /* 529 */ { MAD_F(0x042d9516) /* 0.261128510 */, 14 }, /* 530 */ { MAD_F(0x04304772) /* 0.261786886 */, 14 }, /* 531 */ { MAD_F(0x0432fa3d) /* 0.262445676 */, 14 }, /* 532 */ { MAD_F(0x0435ad76) /* 0.263104880 */, 14 }, /* 533 */ { MAD_F(0x0438611f) /* 0.263764497 */, 14 }, /* 534 */ { MAD_F(0x043b1536) /* 0.264424527 */, 14 }, /* 535 */ { MAD_F(0x043dc9bc) /* 0.265084969 */, 14 }, /* 536 */ { MAD_F(0x04407eb1) /* 0.265745823 */, 14 }, /* 537 */ { MAD_F(0x04433414) /* 0.266407088 */, 14 }, /* 538 */ { MAD_F(0x0445e9e5) /* 0.267068763 */, 14 }, /* 539 */ { MAD_F(0x0448a024) /* 0.267730848 */, 14 }, /* 540 */ { MAD_F(0x044b56d1) /* 0.268393343 */, 14 }, /* 541 */ { MAD_F(0x044e0dec) /* 0.269056248 */, 14 }, /* 542 */ { MAD_F(0x0450c575) /* 0.269719560 */, 14 }, /* 543 */ { MAD_F(0x04537d6b) /* 0.270383281 */, 14 }, /* 544 */ { MAD_F(0x045635cf) /* 0.271047409 */, 14 }, /* 545 */ { MAD_F(0x0458ee9f) /* 0.271711944 */, 14 }, /* 546 */ { MAD_F(0x045ba7dd) /* 0.272376886 */, 14 }, /* 547 */ { MAD_F(0x045e6188) /* 0.273042234 */, 14 }, /* 548 */ { MAD_F(0x04611ba0) /* 0.273707988 */, 14 }, /* 549 */ { MAD_F(0x0463d625) /* 0.274374147 */, 14 }, /* 550 */ { MAD_F(0x04669116) /* 0.275040710 */, 14 }, /* 551 */ { MAD_F(0x04694c74) /* 0.275707677 */, 14 }, /* 552 */ { MAD_F(0x046c083e) /* 0.276375048 */, 14 }, /* 553 */ { MAD_F(0x046ec474) /* 0.277042822 */, 14 }, /* 554 */ { MAD_F(0x04718116) /* 0.277710999 */, 14 }, /* 555 */ { MAD_F(0x04743e25) /* 0.278379578 */, 14 }, /* 556 */ { MAD_F(0x0476fb9f) /* 0.279048558 */, 14 }, /* 557 */ { MAD_F(0x0479b984) /* 0.279717940 */, 14 }, /* 558 */ { MAD_F(0x047c77d6) /* 0.280387722 */, 14 }, /* 559 */ { MAD_F(0x047f3693) /* 0.281057905 */, 14 }, /* 560 */ { MAD_F(0x0481f5bb) /* 0.281728487 */, 14 }, /* 561 */ { MAD_F(0x0484b54e) /* 0.282399469 */, 14 }, /* 562 */ { MAD_F(0x0487754c) /* 0.283070849 */, 14 }, /* 563 */ { MAD_F(0x048a35b6) /* 0.283742628 */, 14 }, /* 564 */ { MAD_F(0x048cf68a) /* 0.284414805 */, 14 }, /* 565 */ { MAD_F(0x048fb7c8) /* 0.285087379 */, 14 }, /* 566 */ { MAD_F(0x04927972) /* 0.285760350 */, 14 }, /* 567 */ { MAD_F(0x04953b85) /* 0.286433717 */, 14 }, /* 568 */ { MAD_F(0x0497fe03) /* 0.287107481 */, 14 }, /* 569 */ { MAD_F(0x049ac0eb) /* 0.287781640 */, 14 }, /* 570 */ { MAD_F(0x049d843e) /* 0.288456194 */, 14 }, /* 571 */ { MAD_F(0x04a047fa) /* 0.289131142 */, 14 }, /* 572 */ { MAD_F(0x04a30c20) /* 0.289806485 */, 14 }, /* 573 */ { MAD_F(0x04a5d0af) /* 0.290482221 */, 14 }, /* 574 */ { MAD_F(0x04a895a8) /* 0.291158351 */, 14 }, /* 575 */ { MAD_F(0x04ab5b0b) /* 0.291834873 */, 14 }, /* 576 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 14 }, /* 577 */ { MAD_F(0x04b0e70c) /* 0.293189094 */, 14 }, /* 578 */ { MAD_F(0x04b3adaa) /* 0.293866792 */, 14 }, /* 579 */ { MAD_F(0x04b674b1) /* 0.294544881 */, 14 }, /* 580 */ { MAD_F(0x04b93c21) /* 0.295223360 */, 14 }, /* 581 */ { MAD_F(0x04bc03fa) /* 0.295902229 */, 14 }, /* 582 */ { MAD_F(0x04becc3b) /* 0.296581488 */, 14 }, /* 583 */ { MAD_F(0x04c194e4) /* 0.297261136 */, 14 }, /* 584 */ { MAD_F(0x04c45df6) /* 0.297941173 */, 14 }, /* 585 */ { MAD_F(0x04c72771) /* 0.298621598 */, 14 }, /* 586 */ { MAD_F(0x04c9f153) /* 0.299302411 */, 14 }, /* 587 */ { MAD_F(0x04ccbb9d) /* 0.299983611 */, 14 }, /* 588 */ { MAD_F(0x04cf864f) /* 0.300665198 */, 14 }, /* 589 */ { MAD_F(0x04d25169) /* 0.301347172 */, 14 }, /* 590 */ { MAD_F(0x04d51ceb) /* 0.302029532 */, 14 }, /* 591 */ { MAD_F(0x04d7e8d4) /* 0.302712277 */, 14 }, /* 592 */ { MAD_F(0x04dab524) /* 0.303395408 */, 14 }, /* 593 */ { MAD_F(0x04dd81dc) /* 0.304078923 */, 14 }, /* 594 */ { MAD_F(0x04e04efb) /* 0.304762823 */, 14 }, /* 595 */ { MAD_F(0x04e31c81) /* 0.305447106 */, 14 }, /* 596 */ { MAD_F(0x04e5ea6e) /* 0.306131773 */, 14 }, /* 597 */ { MAD_F(0x04e8b8c2) /* 0.306816823 */, 14 }, /* 598 */ { MAD_F(0x04eb877c) /* 0.307502256 */, 14 }, /* 599 */ { MAD_F(0x04ee569d) /* 0.308188071 */, 14 }, /* 600 */ { MAD_F(0x04f12624) /* 0.308874267 */, 14 }, /* 601 */ { MAD_F(0x04f3f612) /* 0.309560845 */, 14 }, /* 602 */ { MAD_F(0x04f6c666) /* 0.310247804 */, 14 }, /* 603 */ { MAD_F(0x04f99721) /* 0.310935143 */, 14 }, /* 604 */ { MAD_F(0x04fc6841) /* 0.311622862 */, 14 }, /* 605 */ { MAD_F(0x04ff39c7) /* 0.312310961 */, 14 }, /* 606 */ { MAD_F(0x05020bb3) /* 0.312999439 */, 14 }, /* 607 */ { MAD_F(0x0504de05) /* 0.313688296 */, 14 }, /* 608 */ { MAD_F(0x0507b0bc) /* 0.314377532 */, 14 }, /* 609 */ { MAD_F(0x050a83d8) /* 0.315067145 */, 14 }, /* 610 */ { MAD_F(0x050d575b) /* 0.315757136 */, 14 }, /* 611 */ { MAD_F(0x05102b42) /* 0.316447504 */, 14 }, /* 612 */ { MAD_F(0x0512ff8e) /* 0.317138249 */, 14 }, /* 613 */ { MAD_F(0x0515d440) /* 0.317829370 */, 14 }, /* 614 */ { MAD_F(0x0518a956) /* 0.318520867 */, 14 }, /* 615 */ { MAD_F(0x051b7ed1) /* 0.319212739 */, 14 }, /* 616 */ { MAD_F(0x051e54b1) /* 0.319904987 */, 14 }, /* 617 */ { MAD_F(0x05212af5) /* 0.320597609 */, 14 }, /* 618 */ { MAD_F(0x0524019e) /* 0.321290606 */, 14 }, /* 619 */ { MAD_F(0x0526d8ab) /* 0.321983976 */, 14 }, /* 620 */ { MAD_F(0x0529b01d) /* 0.322677720 */, 14 }, /* 621 */ { MAD_F(0x052c87f2) /* 0.323371837 */, 14 }, /* 622 */ { MAD_F(0x052f602c) /* 0.324066327 */, 14 }, /* 623 */ { MAD_F(0x053238ca) /* 0.324761189 */, 14 }, /* 624 */ { MAD_F(0x053511cb) /* 0.325456423 */, 14 }, /* 625 */ { MAD_F(0x0537eb30) /* 0.326152028 */, 14 }, /* 626 */ { MAD_F(0x053ac4f9) /* 0.326848005 */, 14 }, /* 627 */ { MAD_F(0x053d9f25) /* 0.327544352 */, 14 }, /* 628 */ { MAD_F(0x054079b5) /* 0.328241070 */, 14 }, /* 629 */ { MAD_F(0x054354a8) /* 0.328938157 */, 14 }, /* 630 */ { MAD_F(0x05462ffe) /* 0.329635614 */, 14 }, /* 631 */ { MAD_F(0x05490bb7) /* 0.330333440 */, 14 }, /* 632 */ { MAD_F(0x054be7d4) /* 0.331031635 */, 14 }, /* 633 */ { MAD_F(0x054ec453) /* 0.331730198 */, 14 }, /* 634 */ { MAD_F(0x0551a134) /* 0.332429129 */, 14 }, /* 635 */ { MAD_F(0x05547e79) /* 0.333128427 */, 14 }, /* 636 */ { MAD_F(0x05575c20) /* 0.333828093 */, 14 }, /* 637 */ { MAD_F(0x055a3a2a) /* 0.334528126 */, 14 }, /* 638 */ { MAD_F(0x055d1896) /* 0.335228525 */, 14 }, /* 639 */ { MAD_F(0x055ff764) /* 0.335929290 */, 14 }, /* 640 */ { MAD_F(0x0562d694) /* 0.336630420 */, 14 }, /* 641 */ { MAD_F(0x0565b627) /* 0.337331916 */, 14 }, /* 642 */ { MAD_F(0x0568961b) /* 0.338033777 */, 14 }, /* 643 */ { MAD_F(0x056b7671) /* 0.338736002 */, 14 }, /* 644 */ { MAD_F(0x056e5729) /* 0.339438592 */, 14 }, /* 645 */ { MAD_F(0x05713843) /* 0.340141545 */, 14 }, /* 646 */ { MAD_F(0x057419be) /* 0.340844862 */, 14 }, /* 647 */ { MAD_F(0x0576fb9a) /* 0.341548541 */, 14 }, /* 648 */ { MAD_F(0x0579ddd8) /* 0.342252584 */, 14 }, /* 649 */ { MAD_F(0x057cc077) /* 0.342956988 */, 14 }, /* 650 */ { MAD_F(0x057fa378) /* 0.343661754 */, 14 }, /* 651 */ { MAD_F(0x058286d9) /* 0.344366882 */, 14 }, /* 652 */ { MAD_F(0x05856a9b) /* 0.345072371 */, 14 }, /* 653 */ { MAD_F(0x05884ebe) /* 0.345778221 */, 14 }, /* 654 */ { MAD_F(0x058b3342) /* 0.346484431 */, 14 }, /* 655 */ { MAD_F(0x058e1827) /* 0.347191002 */, 14 }, /* 656 */ { MAD_F(0x0590fd6c) /* 0.347897931 */, 14 }, /* 657 */ { MAD_F(0x0593e311) /* 0.348605221 */, 14 }, /* 658 */ { MAD_F(0x0596c917) /* 0.349312869 */, 14 }, /* 659 */ { MAD_F(0x0599af7d) /* 0.350020876 */, 14 }, /* 660 */ { MAD_F(0x059c9643) /* 0.350729240 */, 14 }, /* 661 */ { MAD_F(0x059f7d6a) /* 0.351437963 */, 14 }, /* 662 */ { MAD_F(0x05a264f0) /* 0.352147044 */, 14 }, /* 663 */ { MAD_F(0x05a54cd6) /* 0.352856481 */, 14 }, /* 664 */ { MAD_F(0x05a8351c) /* 0.353566275 */, 14 }, /* 665 */ { MAD_F(0x05ab1dc2) /* 0.354276426 */, 14 }, /* 666 */ { MAD_F(0x05ae06c7) /* 0.354986932 */, 14 }, /* 667 */ { MAD_F(0x05b0f02b) /* 0.355697795 */, 14 }, /* 668 */ { MAD_F(0x05b3d9f0) /* 0.356409012 */, 14 }, /* 669 */ { MAD_F(0x05b6c413) /* 0.357120585 */, 14 }, /* 670 */ { MAD_F(0x05b9ae95) /* 0.357832512 */, 14 }, /* 671 */ { MAD_F(0x05bc9977) /* 0.358544794 */, 14 }, /* 672 */ { MAD_F(0x05bf84b8) /* 0.359257429 */, 14 }, /* 673 */ { MAD_F(0x05c27057) /* 0.359970419 */, 14 }, /* 674 */ { MAD_F(0x05c55c56) /* 0.360683761 */, 14 }, /* 675 */ { MAD_F(0x05c848b3) /* 0.361397456 */, 14 }, /* 676 */ { MAD_F(0x05cb356e) /* 0.362111504 */, 14 }, /* 677 */ { MAD_F(0x05ce2289) /* 0.362825904 */, 14 }, /* 678 */ { MAD_F(0x05d11001) /* 0.363540655 */, 14 }, /* 679 */ { MAD_F(0x05d3fdd8) /* 0.364255759 */, 14 }, /* 680 */ { MAD_F(0x05d6ec0e) /* 0.364971213 */, 14 }, /* 681 */ { MAD_F(0x05d9daa1) /* 0.365687018 */, 14 }, /* 682 */ { MAD_F(0x05dcc993) /* 0.366403174 */, 14 }, /* 683 */ { MAD_F(0x05dfb8e2) /* 0.367119680 */, 14 }, /* 684 */ { MAD_F(0x05e2a890) /* 0.367836535 */, 14 }, /* 685 */ { MAD_F(0x05e5989b) /* 0.368553740 */, 14 }, /* 686 */ { MAD_F(0x05e88904) /* 0.369271294 */, 14 }, /* 687 */ { MAD_F(0x05eb79cb) /* 0.369989197 */, 14 }, /* 688 */ { MAD_F(0x05ee6aef) /* 0.370707448 */, 14 }, /* 689 */ { MAD_F(0x05f15c70) /* 0.371426047 */, 14 }, /* 690 */ { MAD_F(0x05f44e4f) /* 0.372144994 */, 14 }, /* 691 */ { MAD_F(0x05f7408b) /* 0.372864289 */, 14 }, /* 692 */ { MAD_F(0x05fa3324) /* 0.373583930 */, 14 }, /* 693 */ { MAD_F(0x05fd261b) /* 0.374303918 */, 14 }, /* 694 */ { MAD_F(0x0600196e) /* 0.375024253 */, 14 }, /* 695 */ { MAD_F(0x06030d1e) /* 0.375744934 */, 14 }, /* 696 */ { MAD_F(0x0606012b) /* 0.376465960 */, 14 }, /* 697 */ { MAD_F(0x0608f595) /* 0.377187332 */, 14 }, /* 698 */ { MAD_F(0x060bea5c) /* 0.377909049 */, 14 }, /* 699 */ { MAD_F(0x060edf7f) /* 0.378631110 */, 14 }, /* 700 */ { MAD_F(0x0611d4fe) /* 0.379353516 */, 14 }, /* 701 */ { MAD_F(0x0614cada) /* 0.380076266 */, 14 }, /* 702 */ { MAD_F(0x0617c112) /* 0.380799360 */, 14 }, /* 703 */ { MAD_F(0x061ab7a6) /* 0.381522798 */, 14 }, /* 704 */ { MAD_F(0x061dae96) /* 0.382246578 */, 14 }, /* 705 */ { MAD_F(0x0620a5e3) /* 0.382970701 */, 14 }, /* 706 */ { MAD_F(0x06239d8b) /* 0.383695167 */, 14 }, /* 707 */ { MAD_F(0x0626958f) /* 0.384419975 */, 14 }, /* 708 */ { MAD_F(0x06298def) /* 0.385145124 */, 14 }, /* 709 */ { MAD_F(0x062c86aa) /* 0.385870615 */, 14 }, /* 710 */ { MAD_F(0x062f7fc1) /* 0.386596448 */, 14 }, /* 711 */ { MAD_F(0x06327934) /* 0.387322621 */, 14 }, /* 712 */ { MAD_F(0x06357302) /* 0.388049134 */, 14 }, /* 713 */ { MAD_F(0x06386d2b) /* 0.388775988 */, 14 }, /* 714 */ { MAD_F(0x063b67b0) /* 0.389503182 */, 14 }, /* 715 */ { MAD_F(0x063e6290) /* 0.390230715 */, 14 }, /* 716 */ { MAD_F(0x06415dcb) /* 0.390958588 */, 14 }, /* 717 */ { MAD_F(0x06445960) /* 0.391686799 */, 14 }, /* 718 */ { MAD_F(0x06475551) /* 0.392415349 */, 14 }, /* 719 */ { MAD_F(0x064a519c) /* 0.393144238 */, 14 }, /* 720 */ { MAD_F(0x064d4e43) /* 0.393873464 */, 14 }, /* 721 */ { MAD_F(0x06504b44) /* 0.394603028 */, 14 }, /* 722 */ { MAD_F(0x0653489f) /* 0.395332930 */, 14 }, /* 723 */ { MAD_F(0x06564655) /* 0.396063168 */, 14 }, /* 724 */ { MAD_F(0x06594465) /* 0.396793743 */, 14 }, /* 725 */ { MAD_F(0x065c42d0) /* 0.397524655 */, 14 }, /* 726 */ { MAD_F(0x065f4195) /* 0.398255903 */, 14 }, /* 727 */ { MAD_F(0x066240b4) /* 0.398987487 */, 14 }, /* 728 */ { MAD_F(0x0665402d) /* 0.399719406 */, 14 }, /* 729 */ { MAD_F(0x06684000) /* 0.400451660 */, 14 }, /* 730 */ { MAD_F(0x066b402d) /* 0.401184249 */, 14 }, /* 731 */ { MAD_F(0x066e40b3) /* 0.401917173 */, 14 }, /* 732 */ { MAD_F(0x06714194) /* 0.402650431 */, 14 }, /* 733 */ { MAD_F(0x067442ce) /* 0.403384024 */, 14 }, /* 734 */ { MAD_F(0x06774462) /* 0.404117949 */, 14 }, /* 735 */ { MAD_F(0x067a464f) /* 0.404852209 */, 14 }, /* 736 */ { MAD_F(0x067d4896) /* 0.405586801 */, 14 }, /* 737 */ { MAD_F(0x06804b36) /* 0.406321726 */, 14 }, /* 738 */ { MAD_F(0x06834e2f) /* 0.407056983 */, 14 }, /* 739 */ { MAD_F(0x06865181) /* 0.407792573 */, 14 }, /* 740 */ { MAD_F(0x0689552c) /* 0.408528495 */, 14 }, /* 741 */ { MAD_F(0x068c5931) /* 0.409264748 */, 14 }, /* 742 */ { MAD_F(0x068f5d8e) /* 0.410001332 */, 14 }, /* 743 */ { MAD_F(0x06926245) /* 0.410738247 */, 14 }, /* 744 */ { MAD_F(0x06956753) /* 0.411475493 */, 14 }, /* 745 */ { MAD_F(0x06986cbb) /* 0.412213070 */, 14 }, /* 746 */ { MAD_F(0x069b727b) /* 0.412950976 */, 14 }, /* 747 */ { MAD_F(0x069e7894) /* 0.413689213 */, 14 }, /* 748 */ { MAD_F(0x06a17f05) /* 0.414427779 */, 14 }, /* 749 */ { MAD_F(0x06a485cf) /* 0.415166674 */, 14 }, /* 750 */ { MAD_F(0x06a78cf1) /* 0.415905897 */, 14 }, /* 751 */ { MAD_F(0x06aa946b) /* 0.416645450 */, 14 }, /* 752 */ { MAD_F(0x06ad9c3d) /* 0.417385331 */, 14 }, /* 753 */ { MAD_F(0x06b0a468) /* 0.418125540 */, 14 }, /* 754 */ { MAD_F(0x06b3acea) /* 0.418866076 */, 14 }, /* 755 */ { MAD_F(0x06b6b5c4) /* 0.419606940 */, 14 }, /* 756 */ { MAD_F(0x06b9bef6) /* 0.420348132 */, 14 }, /* 757 */ { MAD_F(0x06bcc880) /* 0.421089650 */, 14 }, /* 758 */ { MAD_F(0x06bfd261) /* 0.421831494 */, 14 }, /* 759 */ { MAD_F(0x06c2dc9a) /* 0.422573665 */, 14 }, /* 760 */ { MAD_F(0x06c5e72b) /* 0.423316162 */, 14 }, /* 761 */ { MAD_F(0x06c8f213) /* 0.424058985 */, 14 }, /* 762 */ { MAD_F(0x06cbfd52) /* 0.424802133 */, 14 }, /* 763 */ { MAD_F(0x06cf08e9) /* 0.425545607 */, 14 }, /* 764 */ { MAD_F(0x06d214d7) /* 0.426289405 */, 14 }, /* 765 */ { MAD_F(0x06d5211c) /* 0.427033528 */, 14 }, /* 766 */ { MAD_F(0x06d82db8) /* 0.427777975 */, 14 }, /* 767 */ { MAD_F(0x06db3aaa) /* 0.428522746 */, 14 }, /* 768 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 14 }, /* 769 */ { MAD_F(0x06e15595) /* 0.430013259 */, 14 }, /* 770 */ { MAD_F(0x06e4638d) /* 0.430759001 */, 14 }, /* 771 */ { MAD_F(0x06e771db) /* 0.431505065 */, 14 }, /* 772 */ { MAD_F(0x06ea807f) /* 0.432251452 */, 14 }, /* 773 */ { MAD_F(0x06ed8f7b) /* 0.432998162 */, 14 }, /* 774 */ { MAD_F(0x06f09ecc) /* 0.433745193 */, 14 }, /* 775 */ { MAD_F(0x06f3ae75) /* 0.434492546 */, 14 }, /* 776 */ { MAD_F(0x06f6be73) /* 0.435240221 */, 14 }, /* 777 */ { MAD_F(0x06f9cec8) /* 0.435988217 */, 14 }, /* 778 */ { MAD_F(0x06fcdf72) /* 0.436736534 */, 14 }, /* 779 */ { MAD_F(0x06fff073) /* 0.437485172 */, 14 }, /* 780 */ { MAD_F(0x070301ca) /* 0.438234130 */, 14 }, /* 781 */ { MAD_F(0x07061377) /* 0.438983408 */, 14 }, /* 782 */ { MAD_F(0x0709257a) /* 0.439733006 */, 14 }, /* 783 */ { MAD_F(0x070c37d2) /* 0.440482924 */, 14 }, /* 784 */ { MAD_F(0x070f4a80) /* 0.441233161 */, 14 }, /* 785 */ { MAD_F(0x07125d84) /* 0.441983717 */, 14 }, /* 786 */ { MAD_F(0x071570de) /* 0.442734592 */, 14 }, /* 787 */ { MAD_F(0x0718848d) /* 0.443485785 */, 14 }, /* 788 */ { MAD_F(0x071b9891) /* 0.444237296 */, 14 }, /* 789 */ { MAD_F(0x071eaceb) /* 0.444989126 */, 14 }, /* 790 */ { MAD_F(0x0721c19a) /* 0.445741273 */, 14 }, /* 791 */ { MAD_F(0x0724d69e) /* 0.446493738 */, 14 }, /* 792 */ { MAD_F(0x0727ebf7) /* 0.447246519 */, 14 }, /* 793 */ { MAD_F(0x072b01a6) /* 0.447999618 */, 14 }, /* 794 */ { MAD_F(0x072e17a9) /* 0.448753033 */, 14 }, /* 795 */ { MAD_F(0x07312e01) /* 0.449506765 */, 14 }, /* 796 */ { MAD_F(0x073444ae) /* 0.450260813 */, 14 }, /* 797 */ { MAD_F(0x07375bb0) /* 0.451015176 */, 14 }, /* 798 */ { MAD_F(0x073a7307) /* 0.451769856 */, 14 }, /* 799 */ { MAD_F(0x073d8ab2) /* 0.452524850 */, 14 }, /* 800 */ { MAD_F(0x0740a2b2) /* 0.453280160 */, 14 }, /* 801 */ { MAD_F(0x0743bb06) /* 0.454035784 */, 14 }, /* 802 */ { MAD_F(0x0746d3af) /* 0.454791723 */, 14 }, /* 803 */ { MAD_F(0x0749ecac) /* 0.455547976 */, 14 }, /* 804 */ { MAD_F(0x074d05fe) /* 0.456304543 */, 14 }, /* 805 */ { MAD_F(0x07501fa3) /* 0.457061423 */, 14 }, /* 806 */ { MAD_F(0x0753399d) /* 0.457818618 */, 14 }, /* 807 */ { MAD_F(0x075653eb) /* 0.458576125 */, 14 }, /* 808 */ { MAD_F(0x07596e8d) /* 0.459333946 */, 14 }, /* 809 */ { MAD_F(0x075c8983) /* 0.460092079 */, 14 }, /* 810 */ { MAD_F(0x075fa4cc) /* 0.460850524 */, 14 }, /* 811 */ { MAD_F(0x0762c06a) /* 0.461609282 */, 14 }, /* 812 */ { MAD_F(0x0765dc5b) /* 0.462368352 */, 14 }, /* 813 */ { MAD_F(0x0768f8a0) /* 0.463127733 */, 14 }, /* 814 */ { MAD_F(0x076c1538) /* 0.463887426 */, 14 }, /* 815 */ { MAD_F(0x076f3224) /* 0.464647430 */, 14 }, /* 816 */ { MAD_F(0x07724f64) /* 0.465407744 */, 14 }, /* 817 */ { MAD_F(0x07756cf7) /* 0.466168370 */, 14 }, /* 818 */ { MAD_F(0x07788add) /* 0.466929306 */, 14 }, /* 819 */ { MAD_F(0x077ba916) /* 0.467690552 */, 14 }, /* 820 */ { MAD_F(0x077ec7a3) /* 0.468452108 */, 14 }, /* 821 */ { MAD_F(0x0781e683) /* 0.469213973 */, 14 }, /* 822 */ { MAD_F(0x078505b5) /* 0.469976148 */, 14 }, /* 823 */ { MAD_F(0x0788253b) /* 0.470738632 */, 14 }, /* 824 */ { MAD_F(0x078b4514) /* 0.471501425 */, 14 }, /* 825 */ { MAD_F(0x078e653f) /* 0.472264527 */, 14 }, /* 826 */ { MAD_F(0x079185be) /* 0.473027937 */, 14 }, /* 827 */ { MAD_F(0x0794a68f) /* 0.473791655 */, 14 }, /* 828 */ { MAD_F(0x0797c7b2) /* 0.474555681 */, 14 }, /* 829 */ { MAD_F(0x079ae929) /* 0.475320014 */, 14 }, /* 830 */ { MAD_F(0x079e0af1) /* 0.476084655 */, 14 }, /* 831 */ { MAD_F(0x07a12d0c) /* 0.476849603 */, 14 }, /* 832 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 14 }, /* 833 */ { MAD_F(0x07a7723a) /* 0.478380420 */, 14 }, /* 834 */ { MAD_F(0x07aa954c) /* 0.479146288 */, 14 }, /* 835 */ { MAD_F(0x07adb8b0) /* 0.479912463 */, 14 }, /* 836 */ { MAD_F(0x07b0dc67) /* 0.480678943 */, 14 }, /* 837 */ { MAD_F(0x07b4006f) /* 0.481445729 */, 14 }, /* 838 */ { MAD_F(0x07b724ca) /* 0.482212820 */, 14 }, /* 839 */ { MAD_F(0x07ba4976) /* 0.482980216 */, 14 }, /* 840 */ { MAD_F(0x07bd6e75) /* 0.483747918 */, 14 }, /* 841 */ { MAD_F(0x07c093c5) /* 0.484515924 */, 14 }, /* 842 */ { MAD_F(0x07c3b967) /* 0.485284235 */, 14 }, /* 843 */ { MAD_F(0x07c6df5a) /* 0.486052849 */, 14 }, /* 844 */ { MAD_F(0x07ca059f) /* 0.486821768 */, 14 }, /* 845 */ { MAD_F(0x07cd2c36) /* 0.487590991 */, 14 }, /* 846 */ { MAD_F(0x07d0531e) /* 0.488360517 */, 14 }, /* 847 */ { MAD_F(0x07d37a57) /* 0.489130346 */, 14 }, /* 848 */ { MAD_F(0x07d6a1e2) /* 0.489900479 */, 14 }, /* 849 */ { MAD_F(0x07d9c9be) /* 0.490670914 */, 14 }, /* 850 */ { MAD_F(0x07dcf1ec) /* 0.491441651 */, 14 }, /* 851 */ { MAD_F(0x07e01a6a) /* 0.492212691 */, 14 }, /* 852 */ { MAD_F(0x07e3433a) /* 0.492984033 */, 14 }, /* 853 */ { MAD_F(0x07e66c5a) /* 0.493755677 */, 14 }, /* 854 */ { MAD_F(0x07e995cc) /* 0.494527623 */, 14 }, /* 855 */ { MAD_F(0x07ecbf8e) /* 0.495299870 */, 14 }, /* 856 */ { MAD_F(0x07efe9a1) /* 0.496072418 */, 14 }, /* 857 */ { MAD_F(0x07f31405) /* 0.496845266 */, 14 }, /* 858 */ { MAD_F(0x07f63eba) /* 0.497618416 */, 14 }, /* 859 */ { MAD_F(0x07f969c0) /* 0.498391866 */, 14 }, /* 860 */ { MAD_F(0x07fc9516) /* 0.499165616 */, 14 }, /* 861 */ { MAD_F(0x07ffc0bc) /* 0.499939666 */, 14 }, /* 862 */ { MAD_F(0x04017659) /* 0.250357008 */, 15 }, /* 863 */ { MAD_F(0x04030c7d) /* 0.250744333 */, 15 }, /* 864 */ { MAD_F(0x0404a2c9) /* 0.251131807 */, 15 }, /* 865 */ { MAD_F(0x0406393d) /* 0.251519431 */, 15 }, /* 866 */ { MAD_F(0x0407cfd9) /* 0.251907204 */, 15 }, /* 867 */ { MAD_F(0x0409669d) /* 0.252295127 */, 15 }, /* 868 */ { MAD_F(0x040afd89) /* 0.252683198 */, 15 }, /* 869 */ { MAD_F(0x040c949e) /* 0.253071419 */, 15 }, /* 870 */ { MAD_F(0x040e2bda) /* 0.253459789 */, 15 }, /* 871 */ { MAD_F(0x040fc33e) /* 0.253848307 */, 15 }, /* 872 */ { MAD_F(0x04115aca) /* 0.254236974 */, 15 }, /* 873 */ { MAD_F(0x0412f27e) /* 0.254625790 */, 15 }, /* 874 */ { MAD_F(0x04148a5a) /* 0.255014755 */, 15 }, /* 875 */ { MAD_F(0x0416225d) /* 0.255403867 */, 15 }, /* 876 */ { MAD_F(0x0417ba89) /* 0.255793128 */, 15 }, /* 877 */ { MAD_F(0x041952dc) /* 0.256182537 */, 15 }, /* 878 */ { MAD_F(0x041aeb57) /* 0.256572095 */, 15 }, /* 879 */ { MAD_F(0x041c83fa) /* 0.256961800 */, 15 }, /* 880 */ { MAD_F(0x041e1cc4) /* 0.257351652 */, 15 }, /* 881 */ { MAD_F(0x041fb5b6) /* 0.257741653 */, 15 }, /* 882 */ { MAD_F(0x04214ed0) /* 0.258131801 */, 15 }, /* 883 */ { MAD_F(0x0422e811) /* 0.258522097 */, 15 }, /* 884 */ { MAD_F(0x04248179) /* 0.258912540 */, 15 }, /* 885 */ { MAD_F(0x04261b0a) /* 0.259303130 */, 15 }, /* 886 */ { MAD_F(0x0427b4c2) /* 0.259693868 */, 15 }, /* 887 */ { MAD_F(0x04294ea1) /* 0.260084752 */, 15 }, /* 888 */ { MAD_F(0x042ae8a7) /* 0.260475783 */, 15 }, /* 889 */ { MAD_F(0x042c82d6) /* 0.260866961 */, 15 }, /* 890 */ { MAD_F(0x042e1d2b) /* 0.261258286 */, 15 }, /* 891 */ { MAD_F(0x042fb7a8) /* 0.261649758 */, 15 }, /* 892 */ { MAD_F(0x0431524c) /* 0.262041376 */, 15 }, /* 893 */ { MAD_F(0x0432ed17) /* 0.262433140 */, 15 }, /* 894 */ { MAD_F(0x0434880a) /* 0.262825051 */, 15 }, /* 895 */ { MAD_F(0x04362324) /* 0.263217107 */, 15 }, /* 896 */ { MAD_F(0x0437be65) /* 0.263609310 */, 15 }, /* 897 */ { MAD_F(0x043959cd) /* 0.264001659 */, 15 }, /* 898 */ { MAD_F(0x043af55d) /* 0.264394153 */, 15 }, /* 899 */ { MAD_F(0x043c9113) /* 0.264786794 */, 15 }, /* 900 */ { MAD_F(0x043e2cf1) /* 0.265179580 */, 15 }, /* 901 */ { MAD_F(0x043fc8f6) /* 0.265572511 */, 15 }, /* 902 */ { MAD_F(0x04416522) /* 0.265965588 */, 15 }, /* 903 */ { MAD_F(0x04430174) /* 0.266358810 */, 15 }, /* 904 */ { MAD_F(0x04449dee) /* 0.266752177 */, 15 }, /* 905 */ { MAD_F(0x04463a8f) /* 0.267145689 */, 15 }, /* 906 */ { MAD_F(0x0447d756) /* 0.267539347 */, 15 }, /* 907 */ { MAD_F(0x04497445) /* 0.267933149 */, 15 }, /* 908 */ { MAD_F(0x044b115a) /* 0.268327096 */, 15 }, /* 909 */ { MAD_F(0x044cae96) /* 0.268721187 */, 15 }, /* 910 */ { MAD_F(0x044e4bf9) /* 0.269115423 */, 15 }, /* 911 */ { MAD_F(0x044fe983) /* 0.269509804 */, 15 }, /* 912 */ { MAD_F(0x04518733) /* 0.269904329 */, 15 }, /* 913 */ { MAD_F(0x0453250a) /* 0.270298998 */, 15 }, /* 914 */ { MAD_F(0x0454c308) /* 0.270693811 */, 15 }, /* 915 */ { MAD_F(0x0456612d) /* 0.271088768 */, 15 }, /* 916 */ { MAD_F(0x0457ff78) /* 0.271483869 */, 15 }, /* 917 */ { MAD_F(0x04599dea) /* 0.271879114 */, 15 }, /* 918 */ { MAD_F(0x045b3c82) /* 0.272274503 */, 15 }, /* 919 */ { MAD_F(0x045cdb41) /* 0.272670035 */, 15 }, /* 920 */ { MAD_F(0x045e7a26) /* 0.273065710 */, 15 }, /* 921 */ { MAD_F(0x04601932) /* 0.273461530 */, 15 }, /* 922 */ { MAD_F(0x0461b864) /* 0.273857492 */, 15 }, /* 923 */ { MAD_F(0x046357bd) /* 0.274253597 */, 15 }, /* 924 */ { MAD_F(0x0464f73c) /* 0.274649846 */, 15 }, /* 925 */ { MAD_F(0x046696e2) /* 0.275046238 */, 15 }, /* 926 */ { MAD_F(0x046836ae) /* 0.275442772 */, 15 }, /* 927 */ { MAD_F(0x0469d6a0) /* 0.275839449 */, 15 }, /* 928 */ { MAD_F(0x046b76b9) /* 0.276236269 */, 15 }, /* 929 */ { MAD_F(0x046d16f7) /* 0.276633232 */, 15 }, /* 930 */ { MAD_F(0x046eb75c) /* 0.277030337 */, 15 }, /* 931 */ { MAD_F(0x047057e8) /* 0.277427584 */, 15 }, /* 932 */ { MAD_F(0x0471f899) /* 0.277824973 */, 15 }, /* 933 */ { MAD_F(0x04739971) /* 0.278222505 */, 15 }, /* 934 */ { MAD_F(0x04753a6f) /* 0.278620179 */, 15 }, /* 935 */ { MAD_F(0x0476db92) /* 0.279017995 */, 15 }, /* 936 */ { MAD_F(0x04787cdc) /* 0.279415952 */, 15 }, /* 937 */ { MAD_F(0x047a1e4c) /* 0.279814051 */, 15 }, /* 938 */ { MAD_F(0x047bbfe2) /* 0.280212292 */, 15 }, /* 939 */ { MAD_F(0x047d619e) /* 0.280610675 */, 15 }, /* 940 */ { MAD_F(0x047f0380) /* 0.281009199 */, 15 }, /* 941 */ { MAD_F(0x0480a588) /* 0.281407864 */, 15 }, /* 942 */ { MAD_F(0x048247b6) /* 0.281806670 */, 15 }, /* 943 */ { MAD_F(0x0483ea0a) /* 0.282205618 */, 15 }, /* 944 */ { MAD_F(0x04858c83) /* 0.282604707 */, 15 }, /* 945 */ { MAD_F(0x04872f22) /* 0.283003936 */, 15 }, /* 946 */ { MAD_F(0x0488d1e8) /* 0.283403307 */, 15 }, /* 947 */ { MAD_F(0x048a74d3) /* 0.283802818 */, 15 }, /* 948 */ { MAD_F(0x048c17e3) /* 0.284202470 */, 15 }, /* 949 */ { MAD_F(0x048dbb1a) /* 0.284602263 */, 15 }, /* 950 */ { MAD_F(0x048f5e76) /* 0.285002195 */, 15 }, /* 951 */ { MAD_F(0x049101f8) /* 0.285402269 */, 15 }, /* 952 */ { MAD_F(0x0492a59f) /* 0.285802482 */, 15 }, /* 953 */ { MAD_F(0x0494496c) /* 0.286202836 */, 15 }, /* 954 */ { MAD_F(0x0495ed5f) /* 0.286603329 */, 15 }, /* 955 */ { MAD_F(0x04979177) /* 0.287003963 */, 15 }, /* 956 */ { MAD_F(0x049935b5) /* 0.287404737 */, 15 }, /* 957 */ { MAD_F(0x049ada19) /* 0.287805650 */, 15 }, /* 958 */ { MAD_F(0x049c7ea1) /* 0.288206703 */, 15 }, /* 959 */ { MAD_F(0x049e2350) /* 0.288607895 */, 15 }, /* 960 */ { MAD_F(0x049fc824) /* 0.289009227 */, 15 }, /* 961 */ { MAD_F(0x04a16d1d) /* 0.289410699 */, 15 }, /* 962 */ { MAD_F(0x04a3123b) /* 0.289812309 */, 15 }, /* 963 */ { MAD_F(0x04a4b77f) /* 0.290214059 */, 15 }, /* 964 */ { MAD_F(0x04a65ce8) /* 0.290615948 */, 15 }, /* 965 */ { MAD_F(0x04a80277) /* 0.291017976 */, 15 }, /* 966 */ { MAD_F(0x04a9a82b) /* 0.291420143 */, 15 }, /* 967 */ { MAD_F(0x04ab4e04) /* 0.291822449 */, 15 }, /* 968 */ { MAD_F(0x04acf402) /* 0.292224893 */, 15 }, /* 969 */ { MAD_F(0x04ae9a26) /* 0.292627476 */, 15 }, /* 970 */ { MAD_F(0x04b0406e) /* 0.293030197 */, 15 }, /* 971 */ { MAD_F(0x04b1e6dc) /* 0.293433057 */, 15 }, /* 972 */ { MAD_F(0x04b38d6f) /* 0.293836055 */, 15 }, /* 973 */ { MAD_F(0x04b53427) /* 0.294239192 */, 15 }, /* 974 */ { MAD_F(0x04b6db05) /* 0.294642466 */, 15 }, /* 975 */ { MAD_F(0x04b88207) /* 0.295045879 */, 15 }, /* 976 */ { MAD_F(0x04ba292e) /* 0.295449429 */, 15 }, /* 977 */ { MAD_F(0x04bbd07a) /* 0.295853118 */, 15 }, /* 978 */ { MAD_F(0x04bd77ec) /* 0.296256944 */, 15 }, /* 979 */ { MAD_F(0x04bf1f82) /* 0.296660907 */, 15 }, /* 980 */ { MAD_F(0x04c0c73d) /* 0.297065009 */, 15 }, /* 981 */ { MAD_F(0x04c26f1d) /* 0.297469248 */, 15 }, /* 982 */ { MAD_F(0x04c41722) /* 0.297873624 */, 15 }, /* 983 */ { MAD_F(0x04c5bf4c) /* 0.298278137 */, 15 }, /* 984 */ { MAD_F(0x04c7679a) /* 0.298682788 */, 15 }, /* 985 */ { MAD_F(0x04c9100d) /* 0.299087576 */, 15 }, /* 986 */ { MAD_F(0x04cab8a6) /* 0.299492500 */, 15 }, /* 987 */ { MAD_F(0x04cc6163) /* 0.299897562 */, 15 }, /* 988 */ { MAD_F(0x04ce0a44) /* 0.300302761 */, 15 }, /* 989 */ { MAD_F(0x04cfb34b) /* 0.300708096 */, 15 }, /* 990 */ { MAD_F(0x04d15c76) /* 0.301113568 */, 15 }, /* 991 */ { MAD_F(0x04d305c5) /* 0.301519176 */, 15 }, /* 992 */ { MAD_F(0x04d4af3a) /* 0.301924921 */, 15 }, /* 993 */ { MAD_F(0x04d658d2) /* 0.302330802 */, 15 }, /* 994 */ { MAD_F(0x04d80290) /* 0.302736820 */, 15 }, /* 995 */ { MAD_F(0x04d9ac72) /* 0.303142973 */, 15 }, /* 996 */ { MAD_F(0x04db5679) /* 0.303549263 */, 15 }, /* 997 */ { MAD_F(0x04dd00a4) /* 0.303955689 */, 15 }, /* 998 */ { MAD_F(0x04deaaf3) /* 0.304362251 */, 15 }, /* 999 */ { MAD_F(0x04e05567) /* 0.304768948 */, 15 }, /* 1000 */ { MAD_F(0x04e20000) /* 0.305175781 */, 15 }, /* 1001 */ { MAD_F(0x04e3aabd) /* 0.305582750 */, 15 }, /* 1002 */ { MAD_F(0x04e5559e) /* 0.305989854 */, 15 }, /* 1003 */ { MAD_F(0x04e700a3) /* 0.306397094 */, 15 }, /* 1004 */ { MAD_F(0x04e8abcd) /* 0.306804470 */, 15 }, /* 1005 */ { MAD_F(0x04ea571c) /* 0.307211980 */, 15 }, /* 1006 */ { MAD_F(0x04ec028e) /* 0.307619626 */, 15 }, /* 1007 */ { MAD_F(0x04edae25) /* 0.308027406 */, 15 }, /* 1008 */ { MAD_F(0x04ef59e0) /* 0.308435322 */, 15 }, /* 1009 */ { MAD_F(0x04f105bf) /* 0.308843373 */, 15 }, /* 1010 */ { MAD_F(0x04f2b1c3) /* 0.309251558 */, 15 }, /* 1011 */ { MAD_F(0x04f45dea) /* 0.309659879 */, 15 }, /* 1012 */ { MAD_F(0x04f60a36) /* 0.310068333 */, 15 }, /* 1013 */ { MAD_F(0x04f7b6a6) /* 0.310476923 */, 15 }, /* 1014 */ { MAD_F(0x04f9633a) /* 0.310885647 */, 15 }, /* 1015 */ { MAD_F(0x04fb0ff2) /* 0.311294505 */, 15 }, /* 1016 */ { MAD_F(0x04fcbcce) /* 0.311703498 */, 15 }, /* 1017 */ { MAD_F(0x04fe69ce) /* 0.312112625 */, 15 }, /* 1018 */ { MAD_F(0x050016f3) /* 0.312521885 */, 15 }, /* 1019 */ { MAD_F(0x0501c43b) /* 0.312931280 */, 15 }, /* 1020 */ { MAD_F(0x050371a7) /* 0.313340809 */, 15 }, /* 1021 */ { MAD_F(0x05051f37) /* 0.313750472 */, 15 }, /* 1022 */ { MAD_F(0x0506cceb) /* 0.314160269 */, 15 }, /* 1023 */ { MAD_F(0x05087ac2) /* 0.314570199 */, 15 }, /* 1024 */ { MAD_F(0x050a28be) /* 0.314980262 */, 15 }, /* 1025 */ { MAD_F(0x050bd6de) /* 0.315390460 */, 15 }, /* 1026 */ { MAD_F(0x050d8521) /* 0.315800790 */, 15 }, /* 1027 */ { MAD_F(0x050f3388) /* 0.316211255 */, 15 }, /* 1028 */ { MAD_F(0x0510e213) /* 0.316621852 */, 15 }, /* 1029 */ { MAD_F(0x051290c2) /* 0.317032582 */, 15 }, /* 1030 */ { MAD_F(0x05143f94) /* 0.317443446 */, 15 }, /* 1031 */ { MAD_F(0x0515ee8a) /* 0.317854442 */, 15 }, /* 1032 */ { MAD_F(0x05179da4) /* 0.318265572 */, 15 }, /* 1033 */ { MAD_F(0x05194ce1) /* 0.318676834 */, 15 }, /* 1034 */ { MAD_F(0x051afc42) /* 0.319088229 */, 15 }, /* 1035 */ { MAD_F(0x051cabc7) /* 0.319499756 */, 15 }, /* 1036 */ { MAD_F(0x051e5b6f) /* 0.319911417 */, 15 }, /* 1037 */ { MAD_F(0x05200b3a) /* 0.320323209 */, 15 }, /* 1038 */ { MAD_F(0x0521bb2a) /* 0.320735134 */, 15 }, /* 1039 */ { MAD_F(0x05236b3d) /* 0.321147192 */, 15 }, /* 1040 */ { MAD_F(0x05251b73) /* 0.321559381 */, 15 }, /* 1041 */ { MAD_F(0x0526cbcd) /* 0.321971703 */, 15 }, /* 1042 */ { MAD_F(0x05287c4a) /* 0.322384156 */, 15 }, /* 1043 */ { MAD_F(0x052a2cea) /* 0.322796742 */, 15 }, /* 1044 */ { MAD_F(0x052bddae) /* 0.323209460 */, 15 }, /* 1045 */ { MAD_F(0x052d8e96) /* 0.323622309 */, 15 }, /* 1046 */ { MAD_F(0x052f3fa1) /* 0.324035290 */, 15 }, /* 1047 */ { MAD_F(0x0530f0cf) /* 0.324448403 */, 15 }, /* 1048 */ { MAD_F(0x0532a220) /* 0.324861647 */, 15 }, /* 1049 */ { MAD_F(0x05345395) /* 0.325275023 */, 15 }, /* 1050 */ { MAD_F(0x0536052d) /* 0.325688530 */, 15 }, /* 1051 */ { MAD_F(0x0537b6e8) /* 0.326102168 */, 15 }, /* 1052 */ { MAD_F(0x053968c6) /* 0.326515938 */, 15 }, /* 1053 */ { MAD_F(0x053b1ac8) /* 0.326929839 */, 15 }, /* 1054 */ { MAD_F(0x053ccced) /* 0.327343870 */, 15 }, /* 1055 */ { MAD_F(0x053e7f35) /* 0.327758033 */, 15 }, /* 1056 */ { MAD_F(0x054031a0) /* 0.328172327 */, 15 }, /* 1057 */ { MAD_F(0x0541e42e) /* 0.328586751 */, 15 }, /* 1058 */ { MAD_F(0x054396df) /* 0.329001306 */, 15 }, /* 1059 */ { MAD_F(0x054549b4) /* 0.329415992 */, 15 }, /* 1060 */ { MAD_F(0x0546fcab) /* 0.329830808 */, 15 }, /* 1061 */ { MAD_F(0x0548afc6) /* 0.330245755 */, 15 }, /* 1062 */ { MAD_F(0x054a6303) /* 0.330660832 */, 15 }, /* 1063 */ { MAD_F(0x054c1663) /* 0.331076039 */, 15 }, /* 1064 */ { MAD_F(0x054dc9e7) /* 0.331491377 */, 15 }, /* 1065 */ { MAD_F(0x054f7d8d) /* 0.331906845 */, 15 }, /* 1066 */ { MAD_F(0x05513156) /* 0.332322443 */, 15 }, /* 1067 */ { MAD_F(0x0552e542) /* 0.332738170 */, 15 }, /* 1068 */ { MAD_F(0x05549951) /* 0.333154028 */, 15 }, /* 1069 */ { MAD_F(0x05564d83) /* 0.333570016 */, 15 }, /* 1070 */ { MAD_F(0x055801d8) /* 0.333986133 */, 15 }, /* 1071 */ { MAD_F(0x0559b64f) /* 0.334402380 */, 15 }, /* 1072 */ { MAD_F(0x055b6ae9) /* 0.334818756 */, 15 }, /* 1073 */ { MAD_F(0x055d1fa6) /* 0.335235262 */, 15 }, /* 1074 */ { MAD_F(0x055ed486) /* 0.335651898 */, 15 }, /* 1075 */ { MAD_F(0x05608988) /* 0.336068662 */, 15 }, /* 1076 */ { MAD_F(0x05623ead) /* 0.336485556 */, 15 }, /* 1077 */ { MAD_F(0x0563f3f5) /* 0.336902579 */, 15 }, /* 1078 */ { MAD_F(0x0565a960) /* 0.337319732 */, 15 }, /* 1079 */ { MAD_F(0x05675eed) /* 0.337737013 */, 15 }, /* 1080 */ { MAD_F(0x0569149c) /* 0.338154423 */, 15 }, /* 1081 */ { MAD_F(0x056aca6f) /* 0.338571962 */, 15 }, /* 1082 */ { MAD_F(0x056c8064) /* 0.338989630 */, 15 }, /* 1083 */ { MAD_F(0x056e367b) /* 0.339407426 */, 15 }, /* 1084 */ { MAD_F(0x056fecb5) /* 0.339825351 */, 15 }, /* 1085 */ { MAD_F(0x0571a311) /* 0.340243405 */, 15 }, /* 1086 */ { MAD_F(0x05735990) /* 0.340661587 */, 15 }, /* 1087 */ { MAD_F(0x05751032) /* 0.341079898 */, 15 }, /* 1088 */ { MAD_F(0x0576c6f5) /* 0.341498336 */, 15 }, /* 1089 */ { MAD_F(0x05787ddc) /* 0.341916903 */, 15 }, /* 1090 */ { MAD_F(0x057a34e4) /* 0.342335598 */, 15 }, /* 1091 */ { MAD_F(0x057bec0f) /* 0.342754421 */, 15 }, /* 1092 */ { MAD_F(0x057da35d) /* 0.343173373 */, 15 }, /* 1093 */ { MAD_F(0x057f5acc) /* 0.343592452 */, 15 }, /* 1094 */ { MAD_F(0x0581125e) /* 0.344011659 */, 15 }, /* 1095 */ { MAD_F(0x0582ca12) /* 0.344430993 */, 15 }, /* 1096 */ { MAD_F(0x058481e9) /* 0.344850455 */, 15 }, /* 1097 */ { MAD_F(0x058639e2) /* 0.345270045 */, 15 }, /* 1098 */ { MAD_F(0x0587f1fd) /* 0.345689763 */, 15 }, /* 1099 */ { MAD_F(0x0589aa3a) /* 0.346109608 */, 15 }, /* 1100 */ { MAD_F(0x058b629a) /* 0.346529580 */, 15 }, /* 1101 */ { MAD_F(0x058d1b1b) /* 0.346949679 */, 15 }, /* 1102 */ { MAD_F(0x058ed3bf) /* 0.347369906 */, 15 }, /* 1103 */ { MAD_F(0x05908c85) /* 0.347790260 */, 15 }, /* 1104 */ { MAD_F(0x0592456d) /* 0.348210741 */, 15 }, /* 1105 */ { MAD_F(0x0593fe77) /* 0.348631348 */, 15 }, /* 1106 */ { MAD_F(0x0595b7a3) /* 0.349052083 */, 15 }, /* 1107 */ { MAD_F(0x059770f1) /* 0.349472945 */, 15 }, /* 1108 */ { MAD_F(0x05992a61) /* 0.349893933 */, 15 }, /* 1109 */ { MAD_F(0x059ae3f3) /* 0.350315048 */, 15 }, /* 1110 */ { MAD_F(0x059c9da8) /* 0.350736290 */, 15 }, /* 1111 */ { MAD_F(0x059e577e) /* 0.351157658 */, 15 }, /* 1112 */ { MAD_F(0x05a01176) /* 0.351579152 */, 15 }, /* 1113 */ { MAD_F(0x05a1cb90) /* 0.352000773 */, 15 }, /* 1114 */ { MAD_F(0x05a385cc) /* 0.352422520 */, 15 }, /* 1115 */ { MAD_F(0x05a5402a) /* 0.352844394 */, 15 }, /* 1116 */ { MAD_F(0x05a6faa9) /* 0.353266393 */, 15 }, /* 1117 */ { MAD_F(0x05a8b54b) /* 0.353688519 */, 15 }, /* 1118 */ { MAD_F(0x05aa700e) /* 0.354110771 */, 15 }, /* 1119 */ { MAD_F(0x05ac2af3) /* 0.354533148 */, 15 }, /* 1120 */ { MAD_F(0x05ade5fa) /* 0.354955651 */, 15 }, /* 1121 */ { MAD_F(0x05afa123) /* 0.355378281 */, 15 }, /* 1122 */ { MAD_F(0x05b15c6d) /* 0.355801035 */, 15 }, /* 1123 */ { MAD_F(0x05b317d9) /* 0.356223916 */, 15 }, /* 1124 */ { MAD_F(0x05b4d367) /* 0.356646922 */, 15 }, /* 1125 */ { MAD_F(0x05b68f16) /* 0.357070053 */, 15 }, /* 1126 */ { MAD_F(0x05b84ae7) /* 0.357493310 */, 15 }, /* 1127 */ { MAD_F(0x05ba06da) /* 0.357916692 */, 15 }, /* 1128 */ { MAD_F(0x05bbc2ef) /* 0.358340200 */, 15 }, /* 1129 */ { MAD_F(0x05bd7f25) /* 0.358763832 */, 15 }, /* 1130 */ { MAD_F(0x05bf3b7c) /* 0.359187590 */, 15 }, /* 1131 */ { MAD_F(0x05c0f7f5) /* 0.359611472 */, 15 }, /* 1132 */ { MAD_F(0x05c2b490) /* 0.360035480 */, 15 }, /* 1133 */ { MAD_F(0x05c4714c) /* 0.360459613 */, 15 }, /* 1134 */ { MAD_F(0x05c62e2a) /* 0.360883870 */, 15 }, /* 1135 */ { MAD_F(0x05c7eb29) /* 0.361308252 */, 15 }, /* 1136 */ { MAD_F(0x05c9a84a) /* 0.361732758 */, 15 }, /* 1137 */ { MAD_F(0x05cb658c) /* 0.362157390 */, 15 }, /* 1138 */ { MAD_F(0x05cd22ef) /* 0.362582145 */, 15 }, /* 1139 */ { MAD_F(0x05cee074) /* 0.363007026 */, 15 }, /* 1140 */ { MAD_F(0x05d09e1b) /* 0.363432030 */, 15 }, /* 1141 */ { MAD_F(0x05d25be2) /* 0.363857159 */, 15 }, /* 1142 */ { MAD_F(0x05d419cb) /* 0.364282412 */, 15 }, /* 1143 */ { MAD_F(0x05d5d7d5) /* 0.364707789 */, 15 }, /* 1144 */ { MAD_F(0x05d79601) /* 0.365133291 */, 15 }, /* 1145 */ { MAD_F(0x05d9544e) /* 0.365558916 */, 15 }, /* 1146 */ { MAD_F(0x05db12bc) /* 0.365984665 */, 15 }, /* 1147 */ { MAD_F(0x05dcd14c) /* 0.366410538 */, 15 }, /* 1148 */ { MAD_F(0x05de8ffc) /* 0.366836535 */, 15 }, /* 1149 */ { MAD_F(0x05e04ece) /* 0.367262655 */, 15 }, /* 1150 */ { MAD_F(0x05e20dc1) /* 0.367688900 */, 15 }, /* 1151 */ { MAD_F(0x05e3ccd5) /* 0.368115267 */, 15 }, /* 1152 */ { MAD_F(0x05e58c0b) /* 0.368541759 */, 15 }, /* 1153 */ { MAD_F(0x05e74b61) /* 0.368968373 */, 15 }, /* 1154 */ { MAD_F(0x05e90ad9) /* 0.369395111 */, 15 }, /* 1155 */ { MAD_F(0x05eaca72) /* 0.369821973 */, 15 }, /* 1156 */ { MAD_F(0x05ec8a2b) /* 0.370248957 */, 15 }, /* 1157 */ { MAD_F(0x05ee4a06) /* 0.370676065 */, 15 }, /* 1158 */ { MAD_F(0x05f00a02) /* 0.371103295 */, 15 }, /* 1159 */ { MAD_F(0x05f1ca1f) /* 0.371530649 */, 15 }, /* 1160 */ { MAD_F(0x05f38a5d) /* 0.371958126 */, 15 }, /* 1161 */ { MAD_F(0x05f54abc) /* 0.372385725 */, 15 }, /* 1162 */ { MAD_F(0x05f70b3c) /* 0.372813448 */, 15 }, /* 1163 */ { MAD_F(0x05f8cbdc) /* 0.373241292 */, 15 }, /* 1164 */ { MAD_F(0x05fa8c9e) /* 0.373669260 */, 15 }, /* 1165 */ { MAD_F(0x05fc4d81) /* 0.374097350 */, 15 }, /* 1166 */ { MAD_F(0x05fe0e84) /* 0.374525563 */, 15 }, /* 1167 */ { MAD_F(0x05ffcfa8) /* 0.374953898 */, 15 }, /* 1168 */ { MAD_F(0x060190ee) /* 0.375382356 */, 15 }, /* 1169 */ { MAD_F(0x06035254) /* 0.375810936 */, 15 }, /* 1170 */ { MAD_F(0x060513da) /* 0.376239638 */, 15 }, /* 1171 */ { MAD_F(0x0606d582) /* 0.376668462 */, 15 }, /* 1172 */ { MAD_F(0x0608974a) /* 0.377097408 */, 15 }, /* 1173 */ { MAD_F(0x060a5934) /* 0.377526476 */, 15 }, /* 1174 */ { MAD_F(0x060c1b3d) /* 0.377955667 */, 15 }, /* 1175 */ { MAD_F(0x060ddd68) /* 0.378384979 */, 15 }, /* 1176 */ { MAD_F(0x060f9fb3) /* 0.378814413 */, 15 }, /* 1177 */ { MAD_F(0x0611621f) /* 0.379243968 */, 15 }, /* 1178 */ { MAD_F(0x061324ac) /* 0.379673646 */, 15 }, /* 1179 */ { MAD_F(0x0614e759) /* 0.380103444 */, 15 }, /* 1180 */ { MAD_F(0x0616aa27) /* 0.380533365 */, 15 }, /* 1181 */ { MAD_F(0x06186d16) /* 0.380963407 */, 15 }, /* 1182 */ { MAD_F(0x061a3025) /* 0.381393570 */, 15 }, /* 1183 */ { MAD_F(0x061bf354) /* 0.381823855 */, 15 }, /* 1184 */ { MAD_F(0x061db6a5) /* 0.382254261 */, 15 }, /* 1185 */ { MAD_F(0x061f7a15) /* 0.382684788 */, 15 }, /* 1186 */ { MAD_F(0x06213da7) /* 0.383115436 */, 15 }, /* 1187 */ { MAD_F(0x06230158) /* 0.383546205 */, 15 }, /* 1188 */ { MAD_F(0x0624c52a) /* 0.383977096 */, 15 }, /* 1189 */ { MAD_F(0x0626891d) /* 0.384408107 */, 15 }, /* 1190 */ { MAD_F(0x06284d30) /* 0.384839239 */, 15 }, /* 1191 */ { MAD_F(0x062a1164) /* 0.385270492 */, 15 }, /* 1192 */ { MAD_F(0x062bd5b8) /* 0.385701865 */, 15 }, /* 1193 */ { MAD_F(0x062d9a2c) /* 0.386133359 */, 15 }, /* 1194 */ { MAD_F(0x062f5ec1) /* 0.386564974 */, 15 }, /* 1195 */ { MAD_F(0x06312376) /* 0.386996709 */, 15 }, /* 1196 */ { MAD_F(0x0632e84b) /* 0.387428565 */, 15 }, /* 1197 */ { MAD_F(0x0634ad41) /* 0.387860541 */, 15 }, /* 1198 */ { MAD_F(0x06367257) /* 0.388292637 */, 15 }, /* 1199 */ { MAD_F(0x0638378d) /* 0.388724854 */, 15 }, /* 1200 */ { MAD_F(0x0639fce4) /* 0.389157191 */, 15 }, /* 1201 */ { MAD_F(0x063bc25b) /* 0.389589648 */, 15 }, /* 1202 */ { MAD_F(0x063d87f2) /* 0.390022225 */, 15 }, /* 1203 */ { MAD_F(0x063f4da9) /* 0.390454922 */, 15 }, /* 1204 */ { MAD_F(0x06411380) /* 0.390887739 */, 15 }, /* 1205 */ { MAD_F(0x0642d978) /* 0.391320675 */, 15 }, /* 1206 */ { MAD_F(0x06449f8f) /* 0.391753732 */, 15 }, /* 1207 */ { MAD_F(0x064665c7) /* 0.392186908 */, 15 }, /* 1208 */ { MAD_F(0x06482c1f) /* 0.392620204 */, 15 }, /* 1209 */ { MAD_F(0x0649f297) /* 0.393053619 */, 15 }, /* 1210 */ { MAD_F(0x064bb92f) /* 0.393487154 */, 15 }, /* 1211 */ { MAD_F(0x064d7fe8) /* 0.393920808 */, 15 }, /* 1212 */ { MAD_F(0x064f46c0) /* 0.394354582 */, 15 }, /* 1213 */ { MAD_F(0x06510db8) /* 0.394788475 */, 15 }, /* 1214 */ { MAD_F(0x0652d4d0) /* 0.395222488 */, 15 }, /* 1215 */ { MAD_F(0x06549c09) /* 0.395656619 */, 15 }, /* 1216 */ { MAD_F(0x06566361) /* 0.396090870 */, 15 }, /* 1217 */ { MAD_F(0x06582ad9) /* 0.396525239 */, 15 }, /* 1218 */ { MAD_F(0x0659f271) /* 0.396959728 */, 15 }, /* 1219 */ { MAD_F(0x065bba29) /* 0.397394336 */, 15 }, /* 1220 */ { MAD_F(0x065d8201) /* 0.397829062 */, 15 }, /* 1221 */ { MAD_F(0x065f49f9) /* 0.398263907 */, 15 }, /* 1222 */ { MAD_F(0x06611211) /* 0.398698871 */, 15 }, /* 1223 */ { MAD_F(0x0662da49) /* 0.399133954 */, 15 }, /* 1224 */ { MAD_F(0x0664a2a0) /* 0.399569155 */, 15 }, /* 1225 */ { MAD_F(0x06666b17) /* 0.400004475 */, 15 }, /* 1226 */ { MAD_F(0x066833ae) /* 0.400439913 */, 15 }, /* 1227 */ { MAD_F(0x0669fc65) /* 0.400875470 */, 15 }, /* 1228 */ { MAD_F(0x066bc53c) /* 0.401311145 */, 15 }, /* 1229 */ { MAD_F(0x066d8e32) /* 0.401746938 */, 15 }, /* 1230 */ { MAD_F(0x066f5748) /* 0.402182850 */, 15 }, /* 1231 */ { MAD_F(0x0671207e) /* 0.402618879 */, 15 }, /* 1232 */ { MAD_F(0x0672e9d4) /* 0.403055027 */, 15 }, /* 1233 */ { MAD_F(0x0674b349) /* 0.403491293 */, 15 }, /* 1234 */ { MAD_F(0x06767cde) /* 0.403927676 */, 15 }, /* 1235 */ { MAD_F(0x06784692) /* 0.404364178 */, 15 }, /* 1236 */ { MAD_F(0x067a1066) /* 0.404800797 */, 15 }, /* 1237 */ { MAD_F(0x067bda5a) /* 0.405237535 */, 15 }, /* 1238 */ { MAD_F(0x067da46d) /* 0.405674390 */, 15 }, /* 1239 */ { MAD_F(0x067f6ea0) /* 0.406111362 */, 15 }, /* 1240 */ { MAD_F(0x068138f3) /* 0.406548452 */, 15 }, /* 1241 */ { MAD_F(0x06830365) /* 0.406985660 */, 15 }, /* 1242 */ { MAD_F(0x0684cdf6) /* 0.407422985 */, 15 }, /* 1243 */ { MAD_F(0x068698a8) /* 0.407860427 */, 15 }, /* 1244 */ { MAD_F(0x06886378) /* 0.408297987 */, 15 }, /* 1245 */ { MAD_F(0x068a2e68) /* 0.408735664 */, 15 }, /* 1246 */ { MAD_F(0x068bf978) /* 0.409173458 */, 15 }, /* 1247 */ { MAD_F(0x068dc4a7) /* 0.409611370 */, 15 }, /* 1248 */ { MAD_F(0x068f8ff5) /* 0.410049398 */, 15 }, /* 1249 */ { MAD_F(0x06915b63) /* 0.410487544 */, 15 }, /* 1250 */ { MAD_F(0x069326f0) /* 0.410925806 */, 15 }, /* 1251 */ { MAD_F(0x0694f29c) /* 0.411364185 */, 15 }, /* 1252 */ { MAD_F(0x0696be68) /* 0.411802681 */, 15 }, /* 1253 */ { MAD_F(0x06988a54) /* 0.412241294 */, 15 }, /* 1254 */ { MAD_F(0x069a565e) /* 0.412680024 */, 15 }, /* 1255 */ { MAD_F(0x069c2288) /* 0.413118870 */, 15 }, /* 1256 */ { MAD_F(0x069deed1) /* 0.413557833 */, 15 }, /* 1257 */ { MAD_F(0x069fbb3a) /* 0.413996912 */, 15 }, /* 1258 */ { MAD_F(0x06a187c1) /* 0.414436108 */, 15 }, /* 1259 */ { MAD_F(0x06a35468) /* 0.414875420 */, 15 }, /* 1260 */ { MAD_F(0x06a5212f) /* 0.415314849 */, 15 }, /* 1261 */ { MAD_F(0x06a6ee14) /* 0.415754393 */, 15 }, /* 1262 */ { MAD_F(0x06a8bb18) /* 0.416194054 */, 15 }, /* 1263 */ { MAD_F(0x06aa883c) /* 0.416633831 */, 15 }, /* 1264 */ { MAD_F(0x06ac557f) /* 0.417073724 */, 15 }, /* 1265 */ { MAD_F(0x06ae22e1) /* 0.417513734 */, 15 }, /* 1266 */ { MAD_F(0x06aff062) /* 0.417953859 */, 15 }, /* 1267 */ { MAD_F(0x06b1be03) /* 0.418394100 */, 15 }, /* 1268 */ { MAD_F(0x06b38bc2) /* 0.418834457 */, 15 }, /* 1269 */ { MAD_F(0x06b559a1) /* 0.419274929 */, 15 }, /* 1270 */ { MAD_F(0x06b7279e) /* 0.419715518 */, 15 }, /* 1271 */ { MAD_F(0x06b8f5bb) /* 0.420156222 */, 15 }, /* 1272 */ { MAD_F(0x06bac3f6) /* 0.420597041 */, 15 }, /* 1273 */ { MAD_F(0x06bc9251) /* 0.421037977 */, 15 }, /* 1274 */ { MAD_F(0x06be60cb) /* 0.421479027 */, 15 }, /* 1275 */ { MAD_F(0x06c02f63) /* 0.421920193 */, 15 }, /* 1276 */ { MAD_F(0x06c1fe1b) /* 0.422361475 */, 15 }, /* 1277 */ { MAD_F(0x06c3ccf1) /* 0.422802871 */, 15 }, /* 1278 */ { MAD_F(0x06c59be7) /* 0.423244383 */, 15 }, /* 1279 */ { MAD_F(0x06c76afb) /* 0.423686010 */, 15 }, /* 1280 */ { MAD_F(0x06c93a2e) /* 0.424127753 */, 15 }, /* 1281 */ { MAD_F(0x06cb0981) /* 0.424569610 */, 15 }, /* 1282 */ { MAD_F(0x06ccd8f2) /* 0.425011582 */, 15 }, /* 1283 */ { MAD_F(0x06cea881) /* 0.425453669 */, 15 }, /* 1284 */ { MAD_F(0x06d07830) /* 0.425895871 */, 15 }, /* 1285 */ { MAD_F(0x06d247fe) /* 0.426338188 */, 15 }, /* 1286 */ { MAD_F(0x06d417ea) /* 0.426780620 */, 15 }, /* 1287 */ { MAD_F(0x06d5e7f5) /* 0.427223166 */, 15 }, /* 1288 */ { MAD_F(0x06d7b81f) /* 0.427665827 */, 15 }, /* 1289 */ { MAD_F(0x06d98868) /* 0.428108603 */, 15 }, /* 1290 */ { MAD_F(0x06db58cf) /* 0.428551493 */, 15 }, /* 1291 */ { MAD_F(0x06dd2955) /* 0.428994497 */, 15 }, /* 1292 */ { MAD_F(0x06def9fa) /* 0.429437616 */, 15 }, /* 1293 */ { MAD_F(0x06e0cabe) /* 0.429880849 */, 15 }, /* 1294 */ { MAD_F(0x06e29ba0) /* 0.430324197 */, 15 }, /* 1295 */ { MAD_F(0x06e46ca1) /* 0.430767659 */, 15 }, /* 1296 */ { MAD_F(0x06e63dc0) /* 0.431211234 */, 15 }, /* 1297 */ { MAD_F(0x06e80efe) /* 0.431654924 */, 15 }, /* 1298 */ { MAD_F(0x06e9e05b) /* 0.432098728 */, 15 }, /* 1299 */ { MAD_F(0x06ebb1d6) /* 0.432542647 */, 15 }, /* 1300 */ { MAD_F(0x06ed8370) /* 0.432986678 */, 15 }, /* 1301 */ { MAD_F(0x06ef5529) /* 0.433430824 */, 15 }, /* 1302 */ { MAD_F(0x06f12700) /* 0.433875084 */, 15 }, /* 1303 */ { MAD_F(0x06f2f8f5) /* 0.434319457 */, 15 }, /* 1304 */ { MAD_F(0x06f4cb09) /* 0.434763944 */, 15 }, /* 1305 */ { MAD_F(0x06f69d3c) /* 0.435208545 */, 15 }, /* 1306 */ { MAD_F(0x06f86f8d) /* 0.435653259 */, 15 }, /* 1307 */ { MAD_F(0x06fa41fd) /* 0.436098087 */, 15 }, /* 1308 */ { MAD_F(0x06fc148b) /* 0.436543029 */, 15 }, /* 1309 */ { MAD_F(0x06fde737) /* 0.436988083 */, 15 }, /* 1310 */ { MAD_F(0x06ffba02) /* 0.437433251 */, 15 }, /* 1311 */ { MAD_F(0x07018ceb) /* 0.437878533 */, 15 }, /* 1312 */ { MAD_F(0x07035ff3) /* 0.438323927 */, 15 }, /* 1313 */ { MAD_F(0x07053319) /* 0.438769435 */, 15 }, /* 1314 */ { MAD_F(0x0707065d) /* 0.439215056 */, 15 }, /* 1315 */ { MAD_F(0x0708d9c0) /* 0.439660790 */, 15 }, /* 1316 */ { MAD_F(0x070aad41) /* 0.440106636 */, 15 }, /* 1317 */ { MAD_F(0x070c80e1) /* 0.440552596 */, 15 }, /* 1318 */ { MAD_F(0x070e549f) /* 0.440998669 */, 15 }, /* 1319 */ { MAD_F(0x0710287b) /* 0.441444855 */, 15 }, /* 1320 */ { MAD_F(0x0711fc75) /* 0.441891153 */, 15 }, /* 1321 */ { MAD_F(0x0713d08d) /* 0.442337564 */, 15 }, /* 1322 */ { MAD_F(0x0715a4c4) /* 0.442784088 */, 15 }, /* 1323 */ { MAD_F(0x07177919) /* 0.443230724 */, 15 }, /* 1324 */ { MAD_F(0x07194d8c) /* 0.443677473 */, 15 }, /* 1325 */ { MAD_F(0x071b221e) /* 0.444124334 */, 15 }, /* 1326 */ { MAD_F(0x071cf6ce) /* 0.444571308 */, 15 }, /* 1327 */ { MAD_F(0x071ecb9b) /* 0.445018394 */, 15 }, /* 1328 */ { MAD_F(0x0720a087) /* 0.445465593 */, 15 }, /* 1329 */ { MAD_F(0x07227591) /* 0.445912903 */, 15 }, /* 1330 */ { MAD_F(0x07244ab9) /* 0.446360326 */, 15 }, /* 1331 */ { MAD_F(0x07262000) /* 0.446807861 */, 15 }, /* 1332 */ { MAD_F(0x0727f564) /* 0.447255509 */, 15 }, /* 1333 */ { MAD_F(0x0729cae7) /* 0.447703268 */, 15 }, /* 1334 */ { MAD_F(0x072ba087) /* 0.448151139 */, 15 }, /* 1335 */ { MAD_F(0x072d7646) /* 0.448599122 */, 15 }, /* 1336 */ { MAD_F(0x072f4c22) /* 0.449047217 */, 15 }, /* 1337 */ { MAD_F(0x0731221d) /* 0.449495424 */, 15 }, /* 1338 */ { MAD_F(0x0732f835) /* 0.449943742 */, 15 }, /* 1339 */ { MAD_F(0x0734ce6c) /* 0.450392173 */, 15 }, /* 1340 */ { MAD_F(0x0736a4c1) /* 0.450840715 */, 15 }, /* 1341 */ { MAD_F(0x07387b33) /* 0.451289368 */, 15 }, /* 1342 */ { MAD_F(0x073a51c4) /* 0.451738133 */, 15 }, /* 1343 */ { MAD_F(0x073c2872) /* 0.452187010 */, 15 }, /* 1344 */ { MAD_F(0x073dff3e) /* 0.452635998 */, 15 }, /* 1345 */ { MAD_F(0x073fd628) /* 0.453085097 */, 15 }, /* 1346 */ { MAD_F(0x0741ad30) /* 0.453534308 */, 15 }, /* 1347 */ { MAD_F(0x07438456) /* 0.453983630 */, 15 }, /* 1348 */ { MAD_F(0x07455b9a) /* 0.454433063 */, 15 }, /* 1349 */ { MAD_F(0x074732fc) /* 0.454882607 */, 15 }, /* 1350 */ { MAD_F(0x07490a7b) /* 0.455332262 */, 15 }, /* 1351 */ { MAD_F(0x074ae218) /* 0.455782029 */, 15 }, /* 1352 */ { MAD_F(0x074cb9d3) /* 0.456231906 */, 15 }, /* 1353 */ { MAD_F(0x074e91ac) /* 0.456681894 */, 15 }, /* 1354 */ { MAD_F(0x075069a3) /* 0.457131993 */, 15 }, /* 1355 */ { MAD_F(0x075241b7) /* 0.457582203 */, 15 }, /* 1356 */ { MAD_F(0x075419e9) /* 0.458032524 */, 15 }, /* 1357 */ { MAD_F(0x0755f239) /* 0.458482956 */, 15 }, /* 1358 */ { MAD_F(0x0757caa7) /* 0.458933498 */, 15 }, /* 1359 */ { MAD_F(0x0759a332) /* 0.459384151 */, 15 }, /* 1360 */ { MAD_F(0x075b7bdb) /* 0.459834914 */, 15 }, /* 1361 */ { MAD_F(0x075d54a1) /* 0.460285788 */, 15 }, /* 1362 */ { MAD_F(0x075f2d85) /* 0.460736772 */, 15 }, /* 1363 */ { MAD_F(0x07610687) /* 0.461187867 */, 15 }, /* 1364 */ { MAD_F(0x0762dfa6) /* 0.461639071 */, 15 }, /* 1365 */ { MAD_F(0x0764b8e3) /* 0.462090387 */, 15 }, /* 1366 */ { MAD_F(0x0766923e) /* 0.462541812 */, 15 }, /* 1367 */ { MAD_F(0x07686bb6) /* 0.462993348 */, 15 }, /* 1368 */ { MAD_F(0x076a454c) /* 0.463444993 */, 15 }, /* 1369 */ { MAD_F(0x076c1eff) /* 0.463896749 */, 15 }, /* 1370 */ { MAD_F(0x076df8d0) /* 0.464348615 */, 15 }, /* 1371 */ { MAD_F(0x076fd2be) /* 0.464800591 */, 15 }, /* 1372 */ { MAD_F(0x0771acca) /* 0.465252676 */, 15 }, /* 1373 */ { MAD_F(0x077386f3) /* 0.465704872 */, 15 }, /* 1374 */ { MAD_F(0x0775613a) /* 0.466157177 */, 15 }, /* 1375 */ { MAD_F(0x07773b9e) /* 0.466609592 */, 15 }, /* 1376 */ { MAD_F(0x07791620) /* 0.467062117 */, 15 }, /* 1377 */ { MAD_F(0x077af0bf) /* 0.467514751 */, 15 }, /* 1378 */ { MAD_F(0x077ccb7c) /* 0.467967495 */, 15 }, /* 1379 */ { MAD_F(0x077ea656) /* 0.468420349 */, 15 }, /* 1380 */ { MAD_F(0x0780814d) /* 0.468873312 */, 15 }, /* 1381 */ { MAD_F(0x07825c62) /* 0.469326384 */, 15 }, /* 1382 */ { MAD_F(0x07843794) /* 0.469779566 */, 15 }, /* 1383 */ { MAD_F(0x078612e3) /* 0.470232857 */, 15 }, /* 1384 */ { MAD_F(0x0787ee50) /* 0.470686258 */, 15 }, /* 1385 */ { MAD_F(0x0789c9da) /* 0.471139767 */, 15 }, /* 1386 */ { MAD_F(0x078ba581) /* 0.471593386 */, 15 }, /* 1387 */ { MAD_F(0x078d8146) /* 0.472047114 */, 15 }, /* 1388 */ { MAD_F(0x078f5d28) /* 0.472500951 */, 15 }, /* 1389 */ { MAD_F(0x07913927) /* 0.472954896 */, 15 }, /* 1390 */ { MAD_F(0x07931543) /* 0.473408951 */, 15 }, /* 1391 */ { MAD_F(0x0794f17d) /* 0.473863115 */, 15 }, /* 1392 */ { MAD_F(0x0796cdd4) /* 0.474317388 */, 15 }, /* 1393 */ { MAD_F(0x0798aa48) /* 0.474771769 */, 15 }, /* 1394 */ { MAD_F(0x079a86d9) /* 0.475226259 */, 15 }, /* 1395 */ { MAD_F(0x079c6388) /* 0.475680858 */, 15 }, /* 1396 */ { MAD_F(0x079e4053) /* 0.476135565 */, 15 }, /* 1397 */ { MAD_F(0x07a01d3c) /* 0.476590381 */, 15 }, /* 1398 */ { MAD_F(0x07a1fa42) /* 0.477045306 */, 15 }, /* 1399 */ { MAD_F(0x07a3d765) /* 0.477500339 */, 15 }, /* 1400 */ { MAD_F(0x07a5b4a5) /* 0.477955481 */, 15 }, /* 1401 */ { MAD_F(0x07a79202) /* 0.478410731 */, 15 }, /* 1402 */ { MAD_F(0x07a96f7d) /* 0.478866089 */, 15 }, /* 1403 */ { MAD_F(0x07ab4d14) /* 0.479321555 */, 15 }, /* 1404 */ { MAD_F(0x07ad2ac8) /* 0.479777130 */, 15 }, /* 1405 */ { MAD_F(0x07af089a) /* 0.480232813 */, 15 }, /* 1406 */ { MAD_F(0x07b0e688) /* 0.480688604 */, 15 }, /* 1407 */ { MAD_F(0x07b2c494) /* 0.481144503 */, 15 }, /* 1408 */ { MAD_F(0x07b4a2bc) /* 0.481600510 */, 15 }, /* 1409 */ { MAD_F(0x07b68102) /* 0.482056625 */, 15 }, /* 1410 */ { MAD_F(0x07b85f64) /* 0.482512848 */, 15 }, /* 1411 */ { MAD_F(0x07ba3de4) /* 0.482969179 */, 15 }, /* 1412 */ { MAD_F(0x07bc1c80) /* 0.483425618 */, 15 }, /* 1413 */ { MAD_F(0x07bdfb39) /* 0.483882164 */, 15 }, /* 1414 */ { MAD_F(0x07bfda0f) /* 0.484338818 */, 15 }, /* 1415 */ { MAD_F(0x07c1b902) /* 0.484795580 */, 15 }, /* 1416 */ { MAD_F(0x07c39812) /* 0.485252449 */, 15 }, /* 1417 */ { MAD_F(0x07c5773f) /* 0.485709426 */, 15 }, /* 1418 */ { MAD_F(0x07c75689) /* 0.486166511 */, 15 }, /* 1419 */ { MAD_F(0x07c935ef) /* 0.486623703 */, 15 }, /* 1420 */ { MAD_F(0x07cb1573) /* 0.487081002 */, 15 }, /* 1421 */ { MAD_F(0x07ccf513) /* 0.487538409 */, 15 }, /* 1422 */ { MAD_F(0x07ced4d0) /* 0.487995923 */, 15 }, /* 1423 */ { MAD_F(0x07d0b4aa) /* 0.488453544 */, 15 }, /* 1424 */ { MAD_F(0x07d294a0) /* 0.488911273 */, 15 }, /* 1425 */ { MAD_F(0x07d474b3) /* 0.489369108 */, 15 }, /* 1426 */ { MAD_F(0x07d654e4) /* 0.489827051 */, 15 }, /* 1427 */ { MAD_F(0x07d83530) /* 0.490285101 */, 15 }, /* 1428 */ { MAD_F(0x07da159a) /* 0.490743258 */, 15 }, /* 1429 */ { MAD_F(0x07dbf620) /* 0.491201522 */, 15 }, /* 1430 */ { MAD_F(0x07ddd6c3) /* 0.491659892 */, 15 }, /* 1431 */ { MAD_F(0x07dfb783) /* 0.492118370 */, 15 }, /* 1432 */ { MAD_F(0x07e1985f) /* 0.492576954 */, 15 }, /* 1433 */ { MAD_F(0x07e37958) /* 0.493035645 */, 15 }, /* 1434 */ { MAD_F(0x07e55a6e) /* 0.493494443 */, 15 }, /* 1435 */ { MAD_F(0x07e73ba0) /* 0.493953348 */, 15 }, /* 1436 */ { MAD_F(0x07e91cef) /* 0.494412359 */, 15 }, /* 1437 */ { MAD_F(0x07eafe5a) /* 0.494871476 */, 15 }, /* 1438 */ { MAD_F(0x07ecdfe2) /* 0.495330701 */, 15 }, /* 1439 */ { MAD_F(0x07eec187) /* 0.495790031 */, 15 }, /* 1440 */ { MAD_F(0x07f0a348) /* 0.496249468 */, 15 }, /* 1441 */ { MAD_F(0x07f28526) /* 0.496709012 */, 15 }, /* 1442 */ { MAD_F(0x07f46720) /* 0.497168662 */, 15 }, /* 1443 */ { MAD_F(0x07f64937) /* 0.497628418 */, 15 }, /* 1444 */ { MAD_F(0x07f82b6a) /* 0.498088280 */, 15 }, /* 1445 */ { MAD_F(0x07fa0dba) /* 0.498548248 */, 15 }, /* 1446 */ { MAD_F(0x07fbf026) /* 0.499008323 */, 15 }, /* 1447 */ { MAD_F(0x07fdd2af) /* 0.499468503 */, 15 }, /* 1448 */ { MAD_F(0x07ffb554) /* 0.499928790 */, 15 }, /* 1449 */ { MAD_F(0x0400cc0b) /* 0.250194591 */, 16 }, /* 1450 */ { MAD_F(0x0401bd7a) /* 0.250424840 */, 16 }, /* 1451 */ { MAD_F(0x0402aef7) /* 0.250655143 */, 16 }, /* 1452 */ { MAD_F(0x0403a083) /* 0.250885498 */, 16 }, /* 1453 */ { MAD_F(0x0404921c) /* 0.251115906 */, 16 }, /* 1454 */ { MAD_F(0x040583c4) /* 0.251346367 */, 16 }, /* 1455 */ { MAD_F(0x0406757a) /* 0.251576880 */, 16 }, /* 1456 */ { MAD_F(0x0407673f) /* 0.251807447 */, 16 }, /* 1457 */ { MAD_F(0x04085911) /* 0.252038066 */, 16 }, /* 1458 */ { MAD_F(0x04094af1) /* 0.252268738 */, 16 }, /* 1459 */ { MAD_F(0x040a3ce0) /* 0.252499463 */, 16 }, /* 1460 */ { MAD_F(0x040b2edd) /* 0.252730240 */, 16 }, /* 1461 */ { MAD_F(0x040c20e8) /* 0.252961071 */, 16 }, /* 1462 */ { MAD_F(0x040d1301) /* 0.253191953 */, 16 }, /* 1463 */ { MAD_F(0x040e0529) /* 0.253422889 */, 16 }, /* 1464 */ { MAD_F(0x040ef75e) /* 0.253653877 */, 16 }, /* 1465 */ { MAD_F(0x040fe9a1) /* 0.253884918 */, 16 }, /* 1466 */ { MAD_F(0x0410dbf3) /* 0.254116011 */, 16 }, /* 1467 */ { MAD_F(0x0411ce53) /* 0.254347157 */, 16 }, /* 1468 */ { MAD_F(0x0412c0c1) /* 0.254578356 */, 16 }, /* 1469 */ { MAD_F(0x0413b33d) /* 0.254809606 */, 16 }, /* 1470 */ { MAD_F(0x0414a5c7) /* 0.255040910 */, 16 }, /* 1471 */ { MAD_F(0x0415985f) /* 0.255272266 */, 16 }, /* 1472 */ { MAD_F(0x04168b05) /* 0.255503674 */, 16 }, /* 1473 */ { MAD_F(0x04177db9) /* 0.255735135 */, 16 }, /* 1474 */ { MAD_F(0x0418707c) /* 0.255966648 */, 16 }, /* 1475 */ { MAD_F(0x0419634c) /* 0.256198213 */, 16 }, /* 1476 */ { MAD_F(0x041a562a) /* 0.256429831 */, 16 }, /* 1477 */ { MAD_F(0x041b4917) /* 0.256661501 */, 16 }, /* 1478 */ { MAD_F(0x041c3c11) /* 0.256893223 */, 16 }, /* 1479 */ { MAD_F(0x041d2f1a) /* 0.257124998 */, 16 }, /* 1480 */ { MAD_F(0x041e2230) /* 0.257356825 */, 16 }, /* 1481 */ { MAD_F(0x041f1555) /* 0.257588704 */, 16 }, /* 1482 */ { MAD_F(0x04200888) /* 0.257820635 */, 16 }, /* 1483 */ { MAD_F(0x0420fbc8) /* 0.258052619 */, 16 }, /* 1484 */ { MAD_F(0x0421ef17) /* 0.258284654 */, 16 }, /* 1485 */ { MAD_F(0x0422e273) /* 0.258516742 */, 16 }, /* 1486 */ { MAD_F(0x0423d5de) /* 0.258748882 */, 16 }, /* 1487 */ { MAD_F(0x0424c956) /* 0.258981074 */, 16 }, /* 1488 */ { MAD_F(0x0425bcdd) /* 0.259213318 */, 16 }, /* 1489 */ { MAD_F(0x0426b071) /* 0.259445614 */, 16 }, /* 1490 */ { MAD_F(0x0427a414) /* 0.259677962 */, 16 }, /* 1491 */ { MAD_F(0x042897c4) /* 0.259910362 */, 16 }, /* 1492 */ { MAD_F(0x04298b83) /* 0.260142814 */, 16 }, /* 1493 */ { MAD_F(0x042a7f4f) /* 0.260375318 */, 16 }, /* 1494 */ { MAD_F(0x042b7329) /* 0.260607874 */, 16 }, /* 1495 */ { MAD_F(0x042c6711) /* 0.260840481 */, 16 }, /* 1496 */ { MAD_F(0x042d5b07) /* 0.261073141 */, 16 }, /* 1497 */ { MAD_F(0x042e4f0b) /* 0.261305852 */, 16 }, /* 1498 */ { MAD_F(0x042f431d) /* 0.261538616 */, 16 }, /* 1499 */ { MAD_F(0x0430373d) /* 0.261771431 */, 16 }, /* 1500 */ { MAD_F(0x04312b6b) /* 0.262004297 */, 16 }, /* 1501 */ { MAD_F(0x04321fa6) /* 0.262237216 */, 16 }, /* 1502 */ { MAD_F(0x043313f0) /* 0.262470186 */, 16 }, /* 1503 */ { MAD_F(0x04340847) /* 0.262703208 */, 16 }, /* 1504 */ { MAD_F(0x0434fcad) /* 0.262936282 */, 16 }, /* 1505 */ { MAD_F(0x0435f120) /* 0.263169407 */, 16 }, /* 1506 */ { MAD_F(0x0436e5a1) /* 0.263402584 */, 16 }, /* 1507 */ { MAD_F(0x0437da2f) /* 0.263635813 */, 16 }, /* 1508 */ { MAD_F(0x0438cecc) /* 0.263869093 */, 16 }, /* 1509 */ { MAD_F(0x0439c377) /* 0.264102425 */, 16 }, /* 1510 */ { MAD_F(0x043ab82f) /* 0.264335808 */, 16 }, /* 1511 */ { MAD_F(0x043bacf5) /* 0.264569243 */, 16 }, /* 1512 */ { MAD_F(0x043ca1c9) /* 0.264802730 */, 16 }, /* 1513 */ { MAD_F(0x043d96ab) /* 0.265036267 */, 16 }, /* 1514 */ { MAD_F(0x043e8b9b) /* 0.265269857 */, 16 }, /* 1515 */ { MAD_F(0x043f8098) /* 0.265503498 */, 16 }, /* 1516 */ { MAD_F(0x044075a3) /* 0.265737190 */, 16 }, /* 1517 */ { MAD_F(0x04416abc) /* 0.265970933 */, 16 }, /* 1518 */ { MAD_F(0x04425fe3) /* 0.266204728 */, 16 }, /* 1519 */ { MAD_F(0x04435518) /* 0.266438574 */, 16 }, /* 1520 */ { MAD_F(0x04444a5a) /* 0.266672472 */, 16 }, /* 1521 */ { MAD_F(0x04453fab) /* 0.266906421 */, 16 }, /* 1522 */ { MAD_F(0x04463508) /* 0.267140421 */, 16 }, /* 1523 */ { MAD_F(0x04472a74) /* 0.267374472 */, 16 }, /* 1524 */ { MAD_F(0x04481fee) /* 0.267608575 */, 16 }, /* 1525 */ { MAD_F(0x04491575) /* 0.267842729 */, 16 }, /* 1526 */ { MAD_F(0x044a0b0a) /* 0.268076934 */, 16 }, /* 1527 */ { MAD_F(0x044b00ac) /* 0.268311190 */, 16 }, /* 1528 */ { MAD_F(0x044bf65d) /* 0.268545497 */, 16 }, /* 1529 */ { MAD_F(0x044cec1b) /* 0.268779856 */, 16 }, /* 1530 */ { MAD_F(0x044de1e7) /* 0.269014265 */, 16 }, /* 1531 */ { MAD_F(0x044ed7c0) /* 0.269248726 */, 16 }, /* 1532 */ { MAD_F(0x044fcda8) /* 0.269483238 */, 16 }, /* 1533 */ { MAD_F(0x0450c39c) /* 0.269717800 */, 16 }, /* 1534 */ { MAD_F(0x0451b99f) /* 0.269952414 */, 16 }, /* 1535 */ { MAD_F(0x0452afaf) /* 0.270187079 */, 16 }, /* 1536 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 16 }, /* 1537 */ { MAD_F(0x04549bf9) /* 0.270656561 */, 16 }, /* 1538 */ { MAD_F(0x04559232) /* 0.270891379 */, 16 }, /* 1539 */ { MAD_F(0x04568879) /* 0.271126247 */, 16 }, /* 1540 */ { MAD_F(0x04577ece) /* 0.271361166 */, 16 }, /* 1541 */ { MAD_F(0x04587530) /* 0.271596136 */, 16 }, /* 1542 */ { MAD_F(0x04596ba0) /* 0.271831157 */, 16 }, /* 1543 */ { MAD_F(0x045a621e) /* 0.272066229 */, 16 }, /* 1544 */ { MAD_F(0x045b58a9) /* 0.272301352 */, 16 }, /* 1545 */ { MAD_F(0x045c4f42) /* 0.272536525 */, 16 }, /* 1546 */ { MAD_F(0x045d45e9) /* 0.272771749 */, 16 }, /* 1547 */ { MAD_F(0x045e3c9d) /* 0.273007024 */, 16 }, /* 1548 */ { MAD_F(0x045f335e) /* 0.273242350 */, 16 }, /* 1549 */ { MAD_F(0x04602a2e) /* 0.273477726 */, 16 }, /* 1550 */ { MAD_F(0x0461210b) /* 0.273713153 */, 16 }, /* 1551 */ { MAD_F(0x046217f5) /* 0.273948630 */, 16 }, /* 1552 */ { MAD_F(0x04630eed) /* 0.274184158 */, 16 }, /* 1553 */ { MAD_F(0x046405f3) /* 0.274419737 */, 16 }, /* 1554 */ { MAD_F(0x0464fd06) /* 0.274655366 */, 16 }, /* 1555 */ { MAD_F(0x0465f427) /* 0.274891046 */, 16 }, /* 1556 */ { MAD_F(0x0466eb55) /* 0.275126776 */, 16 }, /* 1557 */ { MAD_F(0x0467e291) /* 0.275362557 */, 16 }, /* 1558 */ { MAD_F(0x0468d9db) /* 0.275598389 */, 16 }, /* 1559 */ { MAD_F(0x0469d132) /* 0.275834270 */, 16 }, /* 1560 */ { MAD_F(0x046ac896) /* 0.276070203 */, 16 }, /* 1561 */ { MAD_F(0x046bc009) /* 0.276306185 */, 16 }, /* 1562 */ { MAD_F(0x046cb788) /* 0.276542218 */, 16 }, /* 1563 */ { MAD_F(0x046daf15) /* 0.276778302 */, 16 }, /* 1564 */ { MAD_F(0x046ea6b0) /* 0.277014435 */, 16 }, /* 1565 */ { MAD_F(0x046f9e58) /* 0.277250619 */, 16 }, /* 1566 */ { MAD_F(0x0470960e) /* 0.277486854 */, 16 }, /* 1567 */ { MAD_F(0x04718dd1) /* 0.277723139 */, 16 }, /* 1568 */ { MAD_F(0x047285a2) /* 0.277959474 */, 16 }, /* 1569 */ { MAD_F(0x04737d80) /* 0.278195859 */, 16 }, /* 1570 */ { MAD_F(0x0474756c) /* 0.278432294 */, 16 }, /* 1571 */ { MAD_F(0x04756d65) /* 0.278668780 */, 16 }, /* 1572 */ { MAD_F(0x0476656b) /* 0.278905316 */, 16 }, /* 1573 */ { MAD_F(0x04775d7f) /* 0.279141902 */, 16 }, /* 1574 */ { MAD_F(0x047855a1) /* 0.279378538 */, 16 }, /* 1575 */ { MAD_F(0x04794dd0) /* 0.279615224 */, 16 }, /* 1576 */ { MAD_F(0x047a460c) /* 0.279851960 */, 16 }, /* 1577 */ { MAD_F(0x047b3e56) /* 0.280088747 */, 16 }, /* 1578 */ { MAD_F(0x047c36ae) /* 0.280325583 */, 16 }, /* 1579 */ { MAD_F(0x047d2f12) /* 0.280562470 */, 16 }, /* 1580 */ { MAD_F(0x047e2784) /* 0.280799406 */, 16 }, /* 1581 */ { MAD_F(0x047f2004) /* 0.281036393 */, 16 }, /* 1582 */ { MAD_F(0x04801891) /* 0.281273429 */, 16 }, /* 1583 */ { MAD_F(0x0481112b) /* 0.281510516 */, 16 }, /* 1584 */ { MAD_F(0x048209d3) /* 0.281747652 */, 16 }, /* 1585 */ { MAD_F(0x04830288) /* 0.281984838 */, 16 }, /* 1586 */ { MAD_F(0x0483fb4b) /* 0.282222075 */, 16 }, /* 1587 */ { MAD_F(0x0484f41b) /* 0.282459361 */, 16 }, /* 1588 */ { MAD_F(0x0485ecf8) /* 0.282696697 */, 16 }, /* 1589 */ { MAD_F(0x0486e5e3) /* 0.282934082 */, 16 }, /* 1590 */ { MAD_F(0x0487dedb) /* 0.283171518 */, 16 }, /* 1591 */ { MAD_F(0x0488d7e1) /* 0.283409003 */, 16 }, /* 1592 */ { MAD_F(0x0489d0f4) /* 0.283646538 */, 16 }, /* 1593 */ { MAD_F(0x048aca14) /* 0.283884123 */, 16 }, /* 1594 */ { MAD_F(0x048bc341) /* 0.284121757 */, 16 }, /* 1595 */ { MAD_F(0x048cbc7c) /* 0.284359441 */, 16 }, /* 1596 */ { MAD_F(0x048db5c4) /* 0.284597175 */, 16 }, /* 1597 */ { MAD_F(0x048eaf1a) /* 0.284834959 */, 16 }, /* 1598 */ { MAD_F(0x048fa87d) /* 0.285072792 */, 16 }, /* 1599 */ { MAD_F(0x0490a1ed) /* 0.285310675 */, 16 }, /* 1600 */ { MAD_F(0x04919b6a) /* 0.285548607 */, 16 }, /* 1601 */ { MAD_F(0x049294f5) /* 0.285786589 */, 16 }, /* 1602 */ { MAD_F(0x04938e8d) /* 0.286024621 */, 16 }, /* 1603 */ { MAD_F(0x04948833) /* 0.286262702 */, 16 }, /* 1604 */ { MAD_F(0x049581e5) /* 0.286500832 */, 16 }, /* 1605 */ { MAD_F(0x04967ba5) /* 0.286739012 */, 16 }, /* 1606 */ { MAD_F(0x04977573) /* 0.286977242 */, 16 }, /* 1607 */ { MAD_F(0x04986f4d) /* 0.287215521 */, 16 }, /* 1608 */ { MAD_F(0x04996935) /* 0.287453849 */, 16 }, /* 1609 */ { MAD_F(0x049a632a) /* 0.287692227 */, 16 }, /* 1610 */ { MAD_F(0x049b5d2c) /* 0.287930654 */, 16 }, /* 1611 */ { MAD_F(0x049c573c) /* 0.288169131 */, 16 }, /* 1612 */ { MAD_F(0x049d5159) /* 0.288407657 */, 16 }, /* 1613 */ { MAD_F(0x049e4b83) /* 0.288646232 */, 16 }, /* 1614 */ { MAD_F(0x049f45ba) /* 0.288884857 */, 16 }, /* 1615 */ { MAD_F(0x04a03ffe) /* 0.289123530 */, 16 }, /* 1616 */ { MAD_F(0x04a13a50) /* 0.289362253 */, 16 }, /* 1617 */ { MAD_F(0x04a234af) /* 0.289601026 */, 16 }, /* 1618 */ { MAD_F(0x04a32f1b) /* 0.289839847 */, 16 }, /* 1619 */ { MAD_F(0x04a42995) /* 0.290078718 */, 16 }, /* 1620 */ { MAD_F(0x04a5241b) /* 0.290317638 */, 16 }, /* 1621 */ { MAD_F(0x04a61eaf) /* 0.290556607 */, 16 }, /* 1622 */ { MAD_F(0x04a71950) /* 0.290795626 */, 16 }, /* 1623 */ { MAD_F(0x04a813fe) /* 0.291034693 */, 16 }, /* 1624 */ { MAD_F(0x04a90eba) /* 0.291273810 */, 16 }, /* 1625 */ { MAD_F(0x04aa0982) /* 0.291512975 */, 16 }, /* 1626 */ { MAD_F(0x04ab0458) /* 0.291752190 */, 16 }, /* 1627 */ { MAD_F(0x04abff3b) /* 0.291991453 */, 16 }, /* 1628 */ { MAD_F(0x04acfa2b) /* 0.292230766 */, 16 }, /* 1629 */ { MAD_F(0x04adf528) /* 0.292470128 */, 16 }, /* 1630 */ { MAD_F(0x04aef032) /* 0.292709539 */, 16 }, /* 1631 */ { MAD_F(0x04afeb4a) /* 0.292948998 */, 16 }, /* 1632 */ { MAD_F(0x04b0e66e) /* 0.293188507 */, 16 }, /* 1633 */ { MAD_F(0x04b1e1a0) /* 0.293428065 */, 16 }, /* 1634 */ { MAD_F(0x04b2dcdf) /* 0.293667671 */, 16 }, /* 1635 */ { MAD_F(0x04b3d82b) /* 0.293907326 */, 16 }, /* 1636 */ { MAD_F(0x04b4d384) /* 0.294147031 */, 16 }, /* 1637 */ { MAD_F(0x04b5ceea) /* 0.294386784 */, 16 }, /* 1638 */ { MAD_F(0x04b6ca5e) /* 0.294626585 */, 16 }, /* 1639 */ { MAD_F(0x04b7c5de) /* 0.294866436 */, 16 }, /* 1640 */ { MAD_F(0x04b8c16c) /* 0.295106336 */, 16 }, /* 1641 */ { MAD_F(0x04b9bd06) /* 0.295346284 */, 16 }, /* 1642 */ { MAD_F(0x04bab8ae) /* 0.295586281 */, 16 }, /* 1643 */ { MAD_F(0x04bbb463) /* 0.295826327 */, 16 }, /* 1644 */ { MAD_F(0x04bcb024) /* 0.296066421 */, 16 }, /* 1645 */ { MAD_F(0x04bdabf3) /* 0.296306564 */, 16 }, /* 1646 */ { MAD_F(0x04bea7cf) /* 0.296546756 */, 16 }, /* 1647 */ { MAD_F(0x04bfa3b8) /* 0.296786996 */, 16 }, /* 1648 */ { MAD_F(0x04c09faf) /* 0.297027285 */, 16 }, /* 1649 */ { MAD_F(0x04c19bb2) /* 0.297267623 */, 16 }, /* 1650 */ { MAD_F(0x04c297c2) /* 0.297508009 */, 16 }, /* 1651 */ { MAD_F(0x04c393df) /* 0.297748444 */, 16 }, /* 1652 */ { MAD_F(0x04c49009) /* 0.297988927 */, 16 }, /* 1653 */ { MAD_F(0x04c58c41) /* 0.298229459 */, 16 }, /* 1654 */ { MAD_F(0x04c68885) /* 0.298470039 */, 16 }, /* 1655 */ { MAD_F(0x04c784d6) /* 0.298710668 */, 16 }, /* 1656 */ { MAD_F(0x04c88135) /* 0.298951346 */, 16 }, /* 1657 */ { MAD_F(0x04c97da0) /* 0.299192071 */, 16 }, /* 1658 */ { MAD_F(0x04ca7a18) /* 0.299432846 */, 16 }, /* 1659 */ { MAD_F(0x04cb769e) /* 0.299673668 */, 16 }, /* 1660 */ { MAD_F(0x04cc7330) /* 0.299914539 */, 16 }, /* 1661 */ { MAD_F(0x04cd6fcf) /* 0.300155459 */, 16 }, /* 1662 */ { MAD_F(0x04ce6c7b) /* 0.300396426 */, 16 }, /* 1663 */ { MAD_F(0x04cf6935) /* 0.300637443 */, 16 }, /* 1664 */ { MAD_F(0x04d065fb) /* 0.300878507 */, 16 }, /* 1665 */ { MAD_F(0x04d162ce) /* 0.301119620 */, 16 }, /* 1666 */ { MAD_F(0x04d25fae) /* 0.301360781 */, 16 }, /* 1667 */ { MAD_F(0x04d35c9b) /* 0.301601990 */, 16 }, /* 1668 */ { MAD_F(0x04d45995) /* 0.301843247 */, 16 }, /* 1669 */ { MAD_F(0x04d5569c) /* 0.302084553 */, 16 }, /* 1670 */ { MAD_F(0x04d653b0) /* 0.302325907 */, 16 }, /* 1671 */ { MAD_F(0x04d750d1) /* 0.302567309 */, 16 }, /* 1672 */ { MAD_F(0x04d84dff) /* 0.302808759 */, 16 }, /* 1673 */ { MAD_F(0x04d94b3a) /* 0.303050257 */, 16 }, /* 1674 */ { MAD_F(0x04da4881) /* 0.303291804 */, 16 }, /* 1675 */ { MAD_F(0x04db45d6) /* 0.303533399 */, 16 }, /* 1676 */ { MAD_F(0x04dc4337) /* 0.303775041 */, 16 }, /* 1677 */ { MAD_F(0x04dd40a6) /* 0.304016732 */, 16 }, /* 1678 */ { MAD_F(0x04de3e21) /* 0.304258471 */, 16 }, /* 1679 */ { MAD_F(0x04df3ba9) /* 0.304500257 */, 16 }, /* 1680 */ { MAD_F(0x04e0393e) /* 0.304742092 */, 16 }, /* 1681 */ { MAD_F(0x04e136e0) /* 0.304983975 */, 16 }, /* 1682 */ { MAD_F(0x04e2348f) /* 0.305225906 */, 16 }, /* 1683 */ { MAD_F(0x04e3324b) /* 0.305467885 */, 16 }, /* 1684 */ { MAD_F(0x04e43013) /* 0.305709911 */, 16 }, /* 1685 */ { MAD_F(0x04e52de9) /* 0.305951986 */, 16 }, /* 1686 */ { MAD_F(0x04e62bcb) /* 0.306194108 */, 16 }, /* 1687 */ { MAD_F(0x04e729ba) /* 0.306436279 */, 16 }, /* 1688 */ { MAD_F(0x04e827b6) /* 0.306678497 */, 16 }, /* 1689 */ { MAD_F(0x04e925bf) /* 0.306920763 */, 16 }, /* 1690 */ { MAD_F(0x04ea23d4) /* 0.307163077 */, 16 }, /* 1691 */ { MAD_F(0x04eb21f7) /* 0.307405438 */, 16 }, /* 1692 */ { MAD_F(0x04ec2026) /* 0.307647848 */, 16 }, /* 1693 */ { MAD_F(0x04ed1e62) /* 0.307890305 */, 16 }, /* 1694 */ { MAD_F(0x04ee1cab) /* 0.308132810 */, 16 }, /* 1695 */ { MAD_F(0x04ef1b01) /* 0.308375362 */, 16 }, /* 1696 */ { MAD_F(0x04f01963) /* 0.308617963 */, 16 }, /* 1697 */ { MAD_F(0x04f117d3) /* 0.308860611 */, 16 }, /* 1698 */ { MAD_F(0x04f2164f) /* 0.309103306 */, 16 }, /* 1699 */ { MAD_F(0x04f314d8) /* 0.309346050 */, 16 }, /* 1700 */ { MAD_F(0x04f4136d) /* 0.309588841 */, 16 }, /* 1701 */ { MAD_F(0x04f51210) /* 0.309831679 */, 16 }, /* 1702 */ { MAD_F(0x04f610bf) /* 0.310074565 */, 16 }, /* 1703 */ { MAD_F(0x04f70f7b) /* 0.310317499 */, 16 }, /* 1704 */ { MAD_F(0x04f80e44) /* 0.310560480 */, 16 }, /* 1705 */ { MAD_F(0x04f90d19) /* 0.310803509 */, 16 }, /* 1706 */ { MAD_F(0x04fa0bfc) /* 0.311046586 */, 16 }, /* 1707 */ { MAD_F(0x04fb0aeb) /* 0.311289710 */, 16 }, /* 1708 */ { MAD_F(0x04fc09e7) /* 0.311532881 */, 16 }, /* 1709 */ { MAD_F(0x04fd08ef) /* 0.311776100 */, 16 }, /* 1710 */ { MAD_F(0x04fe0805) /* 0.312019366 */, 16 }, /* 1711 */ { MAD_F(0x04ff0727) /* 0.312262680 */, 16 }, /* 1712 */ { MAD_F(0x05000655) /* 0.312506041 */, 16 }, /* 1713 */ { MAD_F(0x05010591) /* 0.312749449 */, 16 }, /* 1714 */ { MAD_F(0x050204d9) /* 0.312992905 */, 16 }, /* 1715 */ { MAD_F(0x0503042e) /* 0.313236408 */, 16 }, /* 1716 */ { MAD_F(0x0504038f) /* 0.313479959 */, 16 }, /* 1717 */ { MAD_F(0x050502fe) /* 0.313723556 */, 16 }, /* 1718 */ { MAD_F(0x05060279) /* 0.313967202 */, 16 }, /* 1719 */ { MAD_F(0x05070200) /* 0.314210894 */, 16 }, /* 1720 */ { MAD_F(0x05080195) /* 0.314454634 */, 16 }, /* 1721 */ { MAD_F(0x05090136) /* 0.314698420 */, 16 }, /* 1722 */ { MAD_F(0x050a00e3) /* 0.314942255 */, 16 }, /* 1723 */ { MAD_F(0x050b009e) /* 0.315186136 */, 16 }, /* 1724 */ { MAD_F(0x050c0065) /* 0.315430064 */, 16 }, /* 1725 */ { MAD_F(0x050d0039) /* 0.315674040 */, 16 }, /* 1726 */ { MAD_F(0x050e0019) /* 0.315918063 */, 16 }, /* 1727 */ { MAD_F(0x050f0006) /* 0.316162133 */, 16 }, /* 1728 */ { MAD_F(0x05100000) /* 0.316406250 */, 16 }, /* 1729 */ { MAD_F(0x05110006) /* 0.316650414 */, 16 }, /* 1730 */ { MAD_F(0x05120019) /* 0.316894625 */, 16 }, /* 1731 */ { MAD_F(0x05130039) /* 0.317138884 */, 16 }, /* 1732 */ { MAD_F(0x05140065) /* 0.317383189 */, 16 }, /* 1733 */ { MAD_F(0x0515009e) /* 0.317627541 */, 16 }, /* 1734 */ { MAD_F(0x051600e3) /* 0.317871941 */, 16 }, /* 1735 */ { MAD_F(0x05170135) /* 0.318116387 */, 16 }, /* 1736 */ { MAD_F(0x05180194) /* 0.318360880 */, 16 }, /* 1737 */ { MAD_F(0x051901ff) /* 0.318605421 */, 16 }, /* 1738 */ { MAD_F(0x051a0277) /* 0.318850008 */, 16 }, /* 1739 */ { MAD_F(0x051b02fc) /* 0.319094642 */, 16 }, /* 1740 */ { MAD_F(0x051c038d) /* 0.319339323 */, 16 }, /* 1741 */ { MAD_F(0x051d042a) /* 0.319584051 */, 16 }, /* 1742 */ { MAD_F(0x051e04d4) /* 0.319828826 */, 16 }, /* 1743 */ { MAD_F(0x051f058b) /* 0.320073647 */, 16 }, /* 1744 */ { MAD_F(0x0520064f) /* 0.320318516 */, 16 }, /* 1745 */ { MAD_F(0x0521071f) /* 0.320563431 */, 16 }, /* 1746 */ { MAD_F(0x052207fb) /* 0.320808393 */, 16 }, /* 1747 */ { MAD_F(0x052308e4) /* 0.321053402 */, 16 }, /* 1748 */ { MAD_F(0x052409da) /* 0.321298457 */, 16 }, /* 1749 */ { MAD_F(0x05250adc) /* 0.321543560 */, 16 }, /* 1750 */ { MAD_F(0x05260bea) /* 0.321788709 */, 16 }, /* 1751 */ { MAD_F(0x05270d06) /* 0.322033904 */, 16 }, /* 1752 */ { MAD_F(0x05280e2d) /* 0.322279147 */, 16 }, /* 1753 */ { MAD_F(0x05290f62) /* 0.322524436 */, 16 }, /* 1754 */ { MAD_F(0x052a10a3) /* 0.322769771 */, 16 }, /* 1755 */ { MAD_F(0x052b11f0) /* 0.323015154 */, 16 }, /* 1756 */ { MAD_F(0x052c134a) /* 0.323260583 */, 16 }, /* 1757 */ { MAD_F(0x052d14b0) /* 0.323506058 */, 16 }, /* 1758 */ { MAD_F(0x052e1623) /* 0.323751580 */, 16 }, /* 1759 */ { MAD_F(0x052f17a2) /* 0.323997149 */, 16 }, /* 1760 */ { MAD_F(0x0530192e) /* 0.324242764 */, 16 }, /* 1761 */ { MAD_F(0x05311ac6) /* 0.324488426 */, 16 }, /* 1762 */ { MAD_F(0x05321c6b) /* 0.324734134 */, 16 }, /* 1763 */ { MAD_F(0x05331e1c) /* 0.324979889 */, 16 }, /* 1764 */ { MAD_F(0x05341fda) /* 0.325225690 */, 16 }, /* 1765 */ { MAD_F(0x053521a4) /* 0.325471538 */, 16 }, /* 1766 */ { MAD_F(0x0536237b) /* 0.325717432 */, 16 }, /* 1767 */ { MAD_F(0x0537255e) /* 0.325963372 */, 16 }, /* 1768 */ { MAD_F(0x0538274e) /* 0.326209359 */, 16 }, /* 1769 */ { MAD_F(0x0539294a) /* 0.326455392 */, 16 }, /* 1770 */ { MAD_F(0x053a2b52) /* 0.326701472 */, 16 }, /* 1771 */ { MAD_F(0x053b2d67) /* 0.326947598 */, 16 }, /* 1772 */ { MAD_F(0x053c2f89) /* 0.327193770 */, 16 }, /* 1773 */ { MAD_F(0x053d31b6) /* 0.327439989 */, 16 }, /* 1774 */ { MAD_F(0x053e33f1) /* 0.327686254 */, 16 }, /* 1775 */ { MAD_F(0x053f3637) /* 0.327932565 */, 16 }, /* 1776 */ { MAD_F(0x0540388a) /* 0.328178922 */, 16 }, /* 1777 */ { MAD_F(0x05413aea) /* 0.328425326 */, 16 }, /* 1778 */ { MAD_F(0x05423d56) /* 0.328671776 */, 16 }, /* 1779 */ { MAD_F(0x05433fce) /* 0.328918272 */, 16 }, /* 1780 */ { MAD_F(0x05444253) /* 0.329164814 */, 16 }, /* 1781 */ { MAD_F(0x054544e4) /* 0.329411403 */, 16 }, /* 1782 */ { MAD_F(0x05464781) /* 0.329658038 */, 16 }, /* 1783 */ { MAD_F(0x05474a2b) /* 0.329904718 */, 16 }, /* 1784 */ { MAD_F(0x05484ce2) /* 0.330151445 */, 16 }, /* 1785 */ { MAD_F(0x05494fa4) /* 0.330398218 */, 16 }, /* 1786 */ { MAD_F(0x054a5273) /* 0.330645037 */, 16 }, /* 1787 */ { MAD_F(0x054b554e) /* 0.330891903 */, 16 }, /* 1788 */ { MAD_F(0x054c5836) /* 0.331138814 */, 16 }, /* 1789 */ { MAD_F(0x054d5b2a) /* 0.331385771 */, 16 }, /* 1790 */ { MAD_F(0x054e5e2b) /* 0.331632774 */, 16 }, /* 1791 */ { MAD_F(0x054f6138) /* 0.331879824 */, 16 }, /* 1792 */ { MAD_F(0x05506451) /* 0.332126919 */, 16 }, /* 1793 */ { MAD_F(0x05516776) /* 0.332374060 */, 16 }, /* 1794 */ { MAD_F(0x05526aa8) /* 0.332621247 */, 16 }, /* 1795 */ { MAD_F(0x05536de6) /* 0.332868480 */, 16 }, /* 1796 */ { MAD_F(0x05547131) /* 0.333115759 */, 16 }, /* 1797 */ { MAD_F(0x05557487) /* 0.333363084 */, 16 }, /* 1798 */ { MAD_F(0x055677ea) /* 0.333610455 */, 16 }, /* 1799 */ { MAD_F(0x05577b5a) /* 0.333857872 */, 16 }, /* 1800 */ { MAD_F(0x05587ed5) /* 0.334105334 */, 16 }, /* 1801 */ { MAD_F(0x0559825e) /* 0.334352843 */, 16 }, /* 1802 */ { MAD_F(0x055a85f2) /* 0.334600397 */, 16 }, /* 1803 */ { MAD_F(0x055b8992) /* 0.334847997 */, 16 }, /* 1804 */ { MAD_F(0x055c8d3f) /* 0.335095642 */, 16 }, /* 1805 */ { MAD_F(0x055d90f9) /* 0.335343334 */, 16 }, /* 1806 */ { MAD_F(0x055e94be) /* 0.335591071 */, 16 }, /* 1807 */ { MAD_F(0x055f9890) /* 0.335838854 */, 16 }, /* 1808 */ { MAD_F(0x05609c6e) /* 0.336086683 */, 16 }, /* 1809 */ { MAD_F(0x0561a058) /* 0.336334557 */, 16 }, /* 1810 */ { MAD_F(0x0562a44f) /* 0.336582477 */, 16 }, /* 1811 */ { MAD_F(0x0563a851) /* 0.336830443 */, 16 }, /* 1812 */ { MAD_F(0x0564ac60) /* 0.337078454 */, 16 }, /* 1813 */ { MAD_F(0x0565b07c) /* 0.337326511 */, 16 }, /* 1814 */ { MAD_F(0x0566b4a3) /* 0.337574614 */, 16 }, /* 1815 */ { MAD_F(0x0567b8d7) /* 0.337822762 */, 16 }, /* 1816 */ { MAD_F(0x0568bd17) /* 0.338070956 */, 16 }, /* 1817 */ { MAD_F(0x0569c163) /* 0.338319195 */, 16 }, /* 1818 */ { MAD_F(0x056ac5bc) /* 0.338567480 */, 16 }, /* 1819 */ { MAD_F(0x056bca20) /* 0.338815811 */, 16 }, /* 1820 */ { MAD_F(0x056cce91) /* 0.339064186 */, 16 }, /* 1821 */ { MAD_F(0x056dd30e) /* 0.339312608 */, 16 }, /* 1822 */ { MAD_F(0x056ed798) /* 0.339561075 */, 16 }, /* 1823 */ { MAD_F(0x056fdc2d) /* 0.339809587 */, 16 }, /* 1824 */ { MAD_F(0x0570e0cf) /* 0.340058145 */, 16 }, /* 1825 */ { MAD_F(0x0571e57d) /* 0.340306748 */, 16 }, /* 1826 */ { MAD_F(0x0572ea37) /* 0.340555397 */, 16 }, /* 1827 */ { MAD_F(0x0573eefd) /* 0.340804091 */, 16 }, /* 1828 */ { MAD_F(0x0574f3d0) /* 0.341052830 */, 16 }, /* 1829 */ { MAD_F(0x0575f8ae) /* 0.341301615 */, 16 }, /* 1830 */ { MAD_F(0x0576fd99) /* 0.341550445 */, 16 }, /* 1831 */ { MAD_F(0x05780290) /* 0.341799321 */, 16 }, /* 1832 */ { MAD_F(0x05790793) /* 0.342048241 */, 16 }, /* 1833 */ { MAD_F(0x057a0ca3) /* 0.342297207 */, 16 }, /* 1834 */ { MAD_F(0x057b11be) /* 0.342546219 */, 16 }, /* 1835 */ { MAD_F(0x057c16e6) /* 0.342795275 */, 16 }, /* 1836 */ { MAD_F(0x057d1c1a) /* 0.343044377 */, 16 }, /* 1837 */ { MAD_F(0x057e2159) /* 0.343293524 */, 16 }, /* 1838 */ { MAD_F(0x057f26a6) /* 0.343542717 */, 16 }, /* 1839 */ { MAD_F(0x05802bfe) /* 0.343791954 */, 16 }, /* 1840 */ { MAD_F(0x05813162) /* 0.344041237 */, 16 }, /* 1841 */ { MAD_F(0x058236d2) /* 0.344290564 */, 16 }, /* 1842 */ { MAD_F(0x05833c4f) /* 0.344539937 */, 16 }, /* 1843 */ { MAD_F(0x058441d8) /* 0.344789356 */, 16 }, /* 1844 */ { MAD_F(0x0585476c) /* 0.345038819 */, 16 }, /* 1845 */ { MAD_F(0x05864d0d) /* 0.345288327 */, 16 }, /* 1846 */ { MAD_F(0x058752ba) /* 0.345537880 */, 16 }, /* 1847 */ { MAD_F(0x05885873) /* 0.345787479 */, 16 }, /* 1848 */ { MAD_F(0x05895e39) /* 0.346037122 */, 16 }, /* 1849 */ { MAD_F(0x058a640a) /* 0.346286811 */, 16 }, /* 1850 */ { MAD_F(0x058b69e7) /* 0.346536545 */, 16 }, /* 1851 */ { MAD_F(0x058c6fd1) /* 0.346786323 */, 16 }, /* 1852 */ { MAD_F(0x058d75c6) /* 0.347036147 */, 16 }, /* 1853 */ { MAD_F(0x058e7bc8) /* 0.347286015 */, 16 }, /* 1854 */ { MAD_F(0x058f81d5) /* 0.347535929 */, 16 }, /* 1855 */ { MAD_F(0x059087ef) /* 0.347785887 */, 16 }, /* 1856 */ { MAD_F(0x05918e15) /* 0.348035890 */, 16 }, /* 1857 */ { MAD_F(0x05929447) /* 0.348285939 */, 16 }, /* 1858 */ { MAD_F(0x05939a84) /* 0.348536032 */, 16 }, /* 1859 */ { MAD_F(0x0594a0ce) /* 0.348786170 */, 16 }, /* 1860 */ { MAD_F(0x0595a724) /* 0.349036353 */, 16 }, /* 1861 */ { MAD_F(0x0596ad86) /* 0.349286580 */, 16 }, /* 1862 */ { MAD_F(0x0597b3f4) /* 0.349536853 */, 16 }, /* 1863 */ { MAD_F(0x0598ba6e) /* 0.349787170 */, 16 }, /* 1864 */ { MAD_F(0x0599c0f4) /* 0.350037532 */, 16 }, /* 1865 */ { MAD_F(0x059ac786) /* 0.350287939 */, 16 }, /* 1866 */ { MAD_F(0x059bce25) /* 0.350538391 */, 16 }, /* 1867 */ { MAD_F(0x059cd4cf) /* 0.350788887 */, 16 }, /* 1868 */ { MAD_F(0x059ddb85) /* 0.351039428 */, 16 }, /* 1869 */ { MAD_F(0x059ee247) /* 0.351290014 */, 16 }, /* 1870 */ { MAD_F(0x059fe915) /* 0.351540645 */, 16 }, /* 1871 */ { MAD_F(0x05a0efef) /* 0.351791320 */, 16 }, /* 1872 */ { MAD_F(0x05a1f6d5) /* 0.352042040 */, 16 }, /* 1873 */ { MAD_F(0x05a2fdc7) /* 0.352292804 */, 16 }, /* 1874 */ { MAD_F(0x05a404c5) /* 0.352543613 */, 16 }, /* 1875 */ { MAD_F(0x05a50bcf) /* 0.352794467 */, 16 }, /* 1876 */ { MAD_F(0x05a612e5) /* 0.353045365 */, 16 }, /* 1877 */ { MAD_F(0x05a71a07) /* 0.353296308 */, 16 }, /* 1878 */ { MAD_F(0x05a82135) /* 0.353547296 */, 16 }, /* 1879 */ { MAD_F(0x05a9286f) /* 0.353798328 */, 16 }, /* 1880 */ { MAD_F(0x05aa2fb5) /* 0.354049405 */, 16 }, /* 1881 */ { MAD_F(0x05ab3707) /* 0.354300526 */, 16 }, /* 1882 */ { MAD_F(0x05ac3e65) /* 0.354551691 */, 16 }, /* 1883 */ { MAD_F(0x05ad45ce) /* 0.354802901 */, 16 }, /* 1884 */ { MAD_F(0x05ae4d44) /* 0.355054156 */, 16 }, /* 1885 */ { MAD_F(0x05af54c6) /* 0.355305455 */, 16 }, /* 1886 */ { MAD_F(0x05b05c53) /* 0.355556799 */, 16 }, /* 1887 */ { MAD_F(0x05b163ed) /* 0.355808187 */, 16 }, /* 1888 */ { MAD_F(0x05b26b92) /* 0.356059619 */, 16 }, /* 1889 */ { MAD_F(0x05b37343) /* 0.356311096 */, 16 }, /* 1890 */ { MAD_F(0x05b47b00) /* 0.356562617 */, 16 }, /* 1891 */ { MAD_F(0x05b582c9) /* 0.356814182 */, 16 }, /* 1892 */ { MAD_F(0x05b68a9e) /* 0.357065792 */, 16 }, /* 1893 */ { MAD_F(0x05b7927f) /* 0.357317446 */, 16 }, /* 1894 */ { MAD_F(0x05b89a6c) /* 0.357569145 */, 16 }, /* 1895 */ { MAD_F(0x05b9a265) /* 0.357820887 */, 16 }, /* 1896 */ { MAD_F(0x05baaa69) /* 0.358072674 */, 16 }, /* 1897 */ { MAD_F(0x05bbb27a) /* 0.358324506 */, 16 }, /* 1898 */ { MAD_F(0x05bcba96) /* 0.358576381 */, 16 }, /* 1899 */ { MAD_F(0x05bdc2be) /* 0.358828301 */, 16 }, /* 1900 */ { MAD_F(0x05becaf2) /* 0.359080265 */, 16 }, /* 1901 */ { MAD_F(0x05bfd332) /* 0.359332273 */, 16 }, /* 1902 */ { MAD_F(0x05c0db7e) /* 0.359584326 */, 16 }, /* 1903 */ { MAD_F(0x05c1e3d6) /* 0.359836423 */, 16 }, /* 1904 */ { MAD_F(0x05c2ec39) /* 0.360088563 */, 16 }, /* 1905 */ { MAD_F(0x05c3f4a9) /* 0.360340748 */, 16 }, /* 1906 */ { MAD_F(0x05c4fd24) /* 0.360592977 */, 16 }, /* 1907 */ { MAD_F(0x05c605ab) /* 0.360845251 */, 16 }, /* 1908 */ { MAD_F(0x05c70e3e) /* 0.361097568 */, 16 }, /* 1909 */ { MAD_F(0x05c816dd) /* 0.361349929 */, 16 }, /* 1910 */ { MAD_F(0x05c91f87) /* 0.361602335 */, 16 }, /* 1911 */ { MAD_F(0x05ca283e) /* 0.361854784 */, 16 }, /* 1912 */ { MAD_F(0x05cb3100) /* 0.362107278 */, 16 }, /* 1913 */ { MAD_F(0x05cc39ce) /* 0.362359815 */, 16 }, /* 1914 */ { MAD_F(0x05cd42a8) /* 0.362612397 */, 16 }, /* 1915 */ { MAD_F(0x05ce4b8d) /* 0.362865022 */, 16 }, /* 1916 */ { MAD_F(0x05cf547f) /* 0.363117692 */, 16 }, /* 1917 */ { MAD_F(0x05d05d7c) /* 0.363370405 */, 16 }, /* 1918 */ { MAD_F(0x05d16685) /* 0.363623163 */, 16 }, /* 1919 */ { MAD_F(0x05d26f9a) /* 0.363875964 */, 16 }, /* 1920 */ { MAD_F(0x05d378bb) /* 0.364128809 */, 16 }, /* 1921 */ { MAD_F(0x05d481e7) /* 0.364381698 */, 16 }, /* 1922 */ { MAD_F(0x05d58b1f) /* 0.364634632 */, 16 }, /* 1923 */ { MAD_F(0x05d69463) /* 0.364887608 */, 16 }, /* 1924 */ { MAD_F(0x05d79db3) /* 0.365140629 */, 16 }, /* 1925 */ { MAD_F(0x05d8a70f) /* 0.365393694 */, 16 }, /* 1926 */ { MAD_F(0x05d9b076) /* 0.365646802 */, 16 }, /* 1927 */ { MAD_F(0x05dab9e9) /* 0.365899955 */, 16 }, /* 1928 */ { MAD_F(0x05dbc368) /* 0.366153151 */, 16 }, /* 1929 */ { MAD_F(0x05dcccf2) /* 0.366406390 */, 16 }, /* 1930 */ { MAD_F(0x05ddd689) /* 0.366659674 */, 16 }, /* 1931 */ { MAD_F(0x05dee02b) /* 0.366913001 */, 16 }, /* 1932 */ { MAD_F(0x05dfe9d8) /* 0.367166372 */, 16 }, /* 1933 */ { MAD_F(0x05e0f392) /* 0.367419787 */, 16 }, /* 1934 */ { MAD_F(0x05e1fd57) /* 0.367673246 */, 16 }, /* 1935 */ { MAD_F(0x05e30728) /* 0.367926748 */, 16 }, /* 1936 */ { MAD_F(0x05e41105) /* 0.368180294 */, 16 }, /* 1937 */ { MAD_F(0x05e51aed) /* 0.368433883 */, 16 }, /* 1938 */ { MAD_F(0x05e624e1) /* 0.368687517 */, 16 }, /* 1939 */ { MAD_F(0x05e72ee1) /* 0.368941193 */, 16 }, /* 1940 */ { MAD_F(0x05e838ed) /* 0.369194914 */, 16 }, /* 1941 */ { MAD_F(0x05e94304) /* 0.369448678 */, 16 }, /* 1942 */ { MAD_F(0x05ea4d27) /* 0.369702485 */, 16 }, /* 1943 */ { MAD_F(0x05eb5756) /* 0.369956336 */, 16 }, /* 1944 */ { MAD_F(0x05ec6190) /* 0.370210231 */, 16 }, /* 1945 */ { MAD_F(0x05ed6bd6) /* 0.370464169 */, 16 }, /* 1946 */ { MAD_F(0x05ee7628) /* 0.370718151 */, 16 }, /* 1947 */ { MAD_F(0x05ef8085) /* 0.370972177 */, 16 }, /* 1948 */ { MAD_F(0x05f08aee) /* 0.371226245 */, 16 }, /* 1949 */ { MAD_F(0x05f19563) /* 0.371480358 */, 16 }, /* 1950 */ { MAD_F(0x05f29fe3) /* 0.371734513 */, 16 }, /* 1951 */ { MAD_F(0x05f3aa6f) /* 0.371988712 */, 16 }, /* 1952 */ { MAD_F(0x05f4b507) /* 0.372242955 */, 16 }, /* 1953 */ { MAD_F(0x05f5bfab) /* 0.372497241 */, 16 }, /* 1954 */ { MAD_F(0x05f6ca5a) /* 0.372751570 */, 16 }, /* 1955 */ { MAD_F(0x05f7d514) /* 0.373005943 */, 16 }, /* 1956 */ { MAD_F(0x05f8dfdb) /* 0.373260359 */, 16 }, /* 1957 */ { MAD_F(0x05f9eaad) /* 0.373514819 */, 16 }, /* 1958 */ { MAD_F(0x05faf58a) /* 0.373769322 */, 16 }, /* 1959 */ { MAD_F(0x05fc0073) /* 0.374023868 */, 16 }, /* 1960 */ { MAD_F(0x05fd0b68) /* 0.374278458 */, 16 }, /* 1961 */ { MAD_F(0x05fe1669) /* 0.374533091 */, 16 }, /* 1962 */ { MAD_F(0x05ff2175) /* 0.374787767 */, 16 }, /* 1963 */ { MAD_F(0x06002c8d) /* 0.375042486 */, 16 }, /* 1964 */ { MAD_F(0x060137b0) /* 0.375297249 */, 16 }, /* 1965 */ { MAD_F(0x060242df) /* 0.375552055 */, 16 }, /* 1966 */ { MAD_F(0x06034e19) /* 0.375806904 */, 16 }, /* 1967 */ { MAD_F(0x0604595f) /* 0.376061796 */, 16 }, /* 1968 */ { MAD_F(0x060564b1) /* 0.376316732 */, 16 }, /* 1969 */ { MAD_F(0x0606700f) /* 0.376571710 */, 16 }, /* 1970 */ { MAD_F(0x06077b77) /* 0.376826732 */, 16 }, /* 1971 */ { MAD_F(0x060886ec) /* 0.377081797 */, 16 }, /* 1972 */ { MAD_F(0x0609926c) /* 0.377336905 */, 16 }, /* 1973 */ { MAD_F(0x060a9df8) /* 0.377592057 */, 16 }, /* 1974 */ { MAD_F(0x060ba98f) /* 0.377847251 */, 16 }, /* 1975 */ { MAD_F(0x060cb532) /* 0.378102489 */, 16 }, /* 1976 */ { MAD_F(0x060dc0e0) /* 0.378357769 */, 16 }, /* 1977 */ { MAD_F(0x060ecc9a) /* 0.378613093 */, 16 }, /* 1978 */ { MAD_F(0x060fd860) /* 0.378868460 */, 16 }, /* 1979 */ { MAD_F(0x0610e431) /* 0.379123870 */, 16 }, /* 1980 */ { MAD_F(0x0611f00d) /* 0.379379322 */, 16 }, /* 1981 */ { MAD_F(0x0612fbf5) /* 0.379634818 */, 16 }, /* 1982 */ { MAD_F(0x061407e9) /* 0.379890357 */, 16 }, /* 1983 */ { MAD_F(0x061513e8) /* 0.380145939 */, 16 }, /* 1984 */ { MAD_F(0x06161ff3) /* 0.380401563 */, 16 }, /* 1985 */ { MAD_F(0x06172c09) /* 0.380657231 */, 16 }, /* 1986 */ { MAD_F(0x0618382b) /* 0.380912942 */, 16 }, /* 1987 */ { MAD_F(0x06194458) /* 0.381168695 */, 16 }, /* 1988 */ { MAD_F(0x061a5091) /* 0.381424492 */, 16 }, /* 1989 */ { MAD_F(0x061b5cd5) /* 0.381680331 */, 16 }, /* 1990 */ { MAD_F(0x061c6925) /* 0.381936213 */, 16 }, /* 1991 */ { MAD_F(0x061d7581) /* 0.382192138 */, 16 }, /* 1992 */ { MAD_F(0x061e81e8) /* 0.382448106 */, 16 }, /* 1993 */ { MAD_F(0x061f8e5a) /* 0.382704117 */, 16 }, /* 1994 */ { MAD_F(0x06209ad8) /* 0.382960171 */, 16 }, /* 1995 */ { MAD_F(0x0621a761) /* 0.383216267 */, 16 }, /* 1996 */ { MAD_F(0x0622b3f6) /* 0.383472406 */, 16 }, /* 1997 */ { MAD_F(0x0623c096) /* 0.383728588 */, 16 }, /* 1998 */ { MAD_F(0x0624cd42) /* 0.383984813 */, 16 }, /* 1999 */ { MAD_F(0x0625d9f9) /* 0.384241080 */, 16 }, /* 2000 */ { MAD_F(0x0626e6bc) /* 0.384497391 */, 16 }, /* 2001 */ { MAD_F(0x0627f38a) /* 0.384753744 */, 16 }, /* 2002 */ { MAD_F(0x06290064) /* 0.385010139 */, 16 }, /* 2003 */ { MAD_F(0x062a0d49) /* 0.385266578 */, 16 }, /* 2004 */ { MAD_F(0x062b1a3a) /* 0.385523059 */, 16 }, /* 2005 */ { MAD_F(0x062c2736) /* 0.385779582 */, 16 }, /* 2006 */ { MAD_F(0x062d343d) /* 0.386036149 */, 16 }, /* 2007 */ { MAD_F(0x062e4150) /* 0.386292758 */, 16 }, /* 2008 */ { MAD_F(0x062f4e6f) /* 0.386549409 */, 16 }, /* 2009 */ { MAD_F(0x06305b99) /* 0.386806104 */, 16 }, /* 2010 */ { MAD_F(0x063168ce) /* 0.387062840 */, 16 }, /* 2011 */ { MAD_F(0x0632760f) /* 0.387319620 */, 16 }, /* 2012 */ { MAD_F(0x0633835b) /* 0.387576442 */, 16 }, /* 2013 */ { MAD_F(0x063490b2) /* 0.387833306 */, 16 }, /* 2014 */ { MAD_F(0x06359e15) /* 0.388090213 */, 16 }, /* 2015 */ { MAD_F(0x0636ab83) /* 0.388347163 */, 16 }, /* 2016 */ { MAD_F(0x0637b8fd) /* 0.388604155 */, 16 }, /* 2017 */ { MAD_F(0x0638c682) /* 0.388861190 */, 16 }, /* 2018 */ { MAD_F(0x0639d413) /* 0.389118267 */, 16 }, /* 2019 */ { MAD_F(0x063ae1af) /* 0.389375386 */, 16 }, /* 2020 */ { MAD_F(0x063bef56) /* 0.389632548 */, 16 }, /* 2021 */ { MAD_F(0x063cfd09) /* 0.389889752 */, 16 }, /* 2022 */ { MAD_F(0x063e0ac7) /* 0.390146999 */, 16 }, /* 2023 */ { MAD_F(0x063f1891) /* 0.390404289 */, 16 }, /* 2024 */ { MAD_F(0x06402666) /* 0.390661620 */, 16 }, /* 2025 */ { MAD_F(0x06413446) /* 0.390918994 */, 16 }, /* 2026 */ { MAD_F(0x06424232) /* 0.391176411 */, 16 }, /* 2027 */ { MAD_F(0x06435029) /* 0.391433869 */, 16 }, /* 2028 */ { MAD_F(0x06445e2b) /* 0.391691371 */, 16 }, /* 2029 */ { MAD_F(0x06456c39) /* 0.391948914 */, 16 }, /* 2030 */ { MAD_F(0x06467a52) /* 0.392206500 */, 16 }, /* 2031 */ { MAD_F(0x06478877) /* 0.392464128 */, 16 }, /* 2032 */ { MAD_F(0x064896a7) /* 0.392721798 */, 16 }, /* 2033 */ { MAD_F(0x0649a4e2) /* 0.392979511 */, 16 }, /* 2034 */ { MAD_F(0x064ab328) /* 0.393237266 */, 16 }, /* 2035 */ { MAD_F(0x064bc17a) /* 0.393495063 */, 16 }, /* 2036 */ { MAD_F(0x064ccfd8) /* 0.393752902 */, 16 }, /* 2037 */ { MAD_F(0x064dde40) /* 0.394010784 */, 16 }, /* 2038 */ { MAD_F(0x064eecb4) /* 0.394268707 */, 16 }, /* 2039 */ { MAD_F(0x064ffb33) /* 0.394526673 */, 16 }, /* 2040 */ { MAD_F(0x065109be) /* 0.394784681 */, 16 }, /* 2041 */ { MAD_F(0x06521854) /* 0.395042732 */, 16 }, /* 2042 */ { MAD_F(0x065326f5) /* 0.395300824 */, 16 }, /* 2043 */ { MAD_F(0x065435a1) /* 0.395558959 */, 16 }, /* 2044 */ { MAD_F(0x06554459) /* 0.395817135 */, 16 }, /* 2045 */ { MAD_F(0x0656531c) /* 0.396075354 */, 16 }, /* 2046 */ { MAD_F(0x065761ea) /* 0.396333615 */, 16 }, /* 2047 */ { MAD_F(0x065870c4) /* 0.396591918 */, 16 }, /* 2048 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 16 }, /* 2049 */ { MAD_F(0x065a8e99) /* 0.397108650 */, 16 }, /* 2050 */ { MAD_F(0x065b9d95) /* 0.397367079 */, 16 }, /* 2051 */ { MAD_F(0x065cac9c) /* 0.397625550 */, 16 }, /* 2052 */ { MAD_F(0x065dbbae) /* 0.397884063 */, 16 }, /* 2053 */ { MAD_F(0x065ecacb) /* 0.398142619 */, 16 }, /* 2054 */ { MAD_F(0x065fd9f4) /* 0.398401216 */, 16 }, /* 2055 */ { MAD_F(0x0660e928) /* 0.398659855 */, 16 }, /* 2056 */ { MAD_F(0x0661f867) /* 0.398918536 */, 16 }, /* 2057 */ { MAD_F(0x066307b1) /* 0.399177259 */, 16 }, /* 2058 */ { MAD_F(0x06641707) /* 0.399436024 */, 16 }, /* 2059 */ { MAD_F(0x06652668) /* 0.399694831 */, 16 }, /* 2060 */ { MAD_F(0x066635d4) /* 0.399953679 */, 16 }, /* 2061 */ { MAD_F(0x0667454c) /* 0.400212570 */, 16 }, /* 2062 */ { MAD_F(0x066854ce) /* 0.400471503 */, 16 }, /* 2063 */ { MAD_F(0x0669645c) /* 0.400730477 */, 16 }, /* 2064 */ { MAD_F(0x066a73f5) /* 0.400989493 */, 16 }, /* 2065 */ { MAD_F(0x066b839a) /* 0.401248551 */, 16 }, /* 2066 */ { MAD_F(0x066c9349) /* 0.401507651 */, 16 }, /* 2067 */ { MAD_F(0x066da304) /* 0.401766793 */, 16 }, /* 2068 */ { MAD_F(0x066eb2ca) /* 0.402025976 */, 16 }, /* 2069 */ { MAD_F(0x066fc29b) /* 0.402285202 */, 16 }, /* 2070 */ { MAD_F(0x0670d278) /* 0.402544469 */, 16 }, /* 2071 */ { MAD_F(0x0671e25f) /* 0.402803777 */, 16 }, /* 2072 */ { MAD_F(0x0672f252) /* 0.403063128 */, 16 }, /* 2073 */ { MAD_F(0x06740250) /* 0.403322520 */, 16 }, /* 2074 */ { MAD_F(0x0675125a) /* 0.403581954 */, 16 }, /* 2075 */ { MAD_F(0x0676226e) /* 0.403841430 */, 16 }, /* 2076 */ { MAD_F(0x0677328e) /* 0.404100947 */, 16 }, /* 2077 */ { MAD_F(0x067842b9) /* 0.404360506 */, 16 }, /* 2078 */ { MAD_F(0x067952ef) /* 0.404620107 */, 16 }, /* 2079 */ { MAD_F(0x067a6330) /* 0.404879749 */, 16 }, /* 2080 */ { MAD_F(0x067b737c) /* 0.405139433 */, 16 }, /* 2081 */ { MAD_F(0x067c83d4) /* 0.405399159 */, 16 }, /* 2082 */ { MAD_F(0x067d9436) /* 0.405658926 */, 16 }, /* 2083 */ { MAD_F(0x067ea4a4) /* 0.405918735 */, 16 }, /* 2084 */ { MAD_F(0x067fb51d) /* 0.406178585 */, 16 }, /* 2085 */ { MAD_F(0x0680c5a2) /* 0.406438477 */, 16 }, /* 2086 */ { MAD_F(0x0681d631) /* 0.406698410 */, 16 }, /* 2087 */ { MAD_F(0x0682e6cb) /* 0.406958385 */, 16 }, /* 2088 */ { MAD_F(0x0683f771) /* 0.407218402 */, 16 }, /* 2089 */ { MAD_F(0x06850822) /* 0.407478460 */, 16 }, /* 2090 */ { MAD_F(0x068618de) /* 0.407738559 */, 16 }, /* 2091 */ { MAD_F(0x068729a5) /* 0.407998700 */, 16 }, /* 2092 */ { MAD_F(0x06883a77) /* 0.408258883 */, 16 }, /* 2093 */ { MAD_F(0x06894b55) /* 0.408519107 */, 16 }, /* 2094 */ { MAD_F(0x068a5c3d) /* 0.408779372 */, 16 }, /* 2095 */ { MAD_F(0x068b6d31) /* 0.409039679 */, 16 }, /* 2096 */ { MAD_F(0x068c7e2f) /* 0.409300027 */, 16 }, /* 2097 */ { MAD_F(0x068d8f39) /* 0.409560417 */, 16 }, /* 2098 */ { MAD_F(0x068ea04e) /* 0.409820848 */, 16 }, /* 2099 */ { MAD_F(0x068fb16e) /* 0.410081321 */, 16 }, /* 2100 */ { MAD_F(0x0690c299) /* 0.410341834 */, 16 }, /* 2101 */ { MAD_F(0x0691d3cf) /* 0.410602390 */, 16 }, /* 2102 */ { MAD_F(0x0692e511) /* 0.410862986 */, 16 }, /* 2103 */ { MAD_F(0x0693f65d) /* 0.411123624 */, 16 }, /* 2104 */ { MAD_F(0x069507b5) /* 0.411384303 */, 16 }, /* 2105 */ { MAD_F(0x06961917) /* 0.411645024 */, 16 }, /* 2106 */ { MAD_F(0x06972a85) /* 0.411905785 */, 16 }, /* 2107 */ { MAD_F(0x06983bfe) /* 0.412166588 */, 16 }, /* 2108 */ { MAD_F(0x06994d82) /* 0.412427433 */, 16 }, /* 2109 */ { MAD_F(0x069a5f11) /* 0.412688318 */, 16 }, /* 2110 */ { MAD_F(0x069b70ab) /* 0.412949245 */, 16 }, /* 2111 */ { MAD_F(0x069c8250) /* 0.413210213 */, 16 }, /* 2112 */ { MAD_F(0x069d9400) /* 0.413471222 */, 16 }, /* 2113 */ { MAD_F(0x069ea5bb) /* 0.413732273 */, 16 }, /* 2114 */ { MAD_F(0x069fb781) /* 0.413993364 */, 16 }, /* 2115 */ { MAD_F(0x06a0c953) /* 0.414254497 */, 16 }, /* 2116 */ { MAD_F(0x06a1db2f) /* 0.414515671 */, 16 }, /* 2117 */ { MAD_F(0x06a2ed16) /* 0.414776886 */, 16 }, /* 2118 */ { MAD_F(0x06a3ff09) /* 0.415038142 */, 16 }, /* 2119 */ { MAD_F(0x06a51106) /* 0.415299440 */, 16 }, /* 2120 */ { MAD_F(0x06a6230f) /* 0.415560778 */, 16 }, /* 2121 */ { MAD_F(0x06a73522) /* 0.415822157 */, 16 }, /* 2122 */ { MAD_F(0x06a84741) /* 0.416083578 */, 16 }, /* 2123 */ { MAD_F(0x06a9596a) /* 0.416345040 */, 16 }, /* 2124 */ { MAD_F(0x06aa6b9f) /* 0.416606542 */, 16 }, /* 2125 */ { MAD_F(0x06ab7ddf) /* 0.416868086 */, 16 }, /* 2126 */ { MAD_F(0x06ac9029) /* 0.417129671 */, 16 }, /* 2127 */ { MAD_F(0x06ada27f) /* 0.417391297 */, 16 }, /* 2128 */ { MAD_F(0x06aeb4e0) /* 0.417652964 */, 16 }, /* 2129 */ { MAD_F(0x06afc74b) /* 0.417914672 */, 16 }, /* 2130 */ { MAD_F(0x06b0d9c2) /* 0.418176420 */, 16 }, /* 2131 */ { MAD_F(0x06b1ec43) /* 0.418438210 */, 16 }, /* 2132 */ { MAD_F(0x06b2fed0) /* 0.418700041 */, 16 }, /* 2133 */ { MAD_F(0x06b41168) /* 0.418961912 */, 16 }, /* 2134 */ { MAD_F(0x06b5240a) /* 0.419223825 */, 16 }, /* 2135 */ { MAD_F(0x06b636b8) /* 0.419485778 */, 16 }, /* 2136 */ { MAD_F(0x06b74971) /* 0.419747773 */, 16 }, /* 2137 */ { MAD_F(0x06b85c34) /* 0.420009808 */, 16 }, /* 2138 */ { MAD_F(0x06b96f03) /* 0.420271884 */, 16 }, /* 2139 */ { MAD_F(0x06ba81dc) /* 0.420534001 */, 16 }, /* 2140 */ { MAD_F(0x06bb94c1) /* 0.420796159 */, 16 }, /* 2141 */ { MAD_F(0x06bca7b0) /* 0.421058358 */, 16 }, /* 2142 */ { MAD_F(0x06bdbaaa) /* 0.421320597 */, 16 }, /* 2143 */ { MAD_F(0x06becdb0) /* 0.421582878 */, 16 }, /* 2144 */ { MAD_F(0x06bfe0c0) /* 0.421845199 */, 16 }, /* 2145 */ { MAD_F(0x06c0f3db) /* 0.422107561 */, 16 }, /* 2146 */ { MAD_F(0x06c20702) /* 0.422369964 */, 16 }, /* 2147 */ { MAD_F(0x06c31a33) /* 0.422632407 */, 16 }, /* 2148 */ { MAD_F(0x06c42d6f) /* 0.422894891 */, 16 }, /* 2149 */ { MAD_F(0x06c540b6) /* 0.423157416 */, 16 }, /* 2150 */ { MAD_F(0x06c65408) /* 0.423419982 */, 16 }, /* 2151 */ { MAD_F(0x06c76765) /* 0.423682588 */, 16 }, /* 2152 */ { MAD_F(0x06c87acc) /* 0.423945235 */, 16 }, /* 2153 */ { MAD_F(0x06c98e3f) /* 0.424207923 */, 16 }, /* 2154 */ { MAD_F(0x06caa1bd) /* 0.424470652 */, 16 }, /* 2155 */ { MAD_F(0x06cbb545) /* 0.424733421 */, 16 }, /* 2156 */ { MAD_F(0x06ccc8d9) /* 0.424996230 */, 16 }, /* 2157 */ { MAD_F(0x06cddc77) /* 0.425259081 */, 16 }, /* 2158 */ { MAD_F(0x06cef020) /* 0.425521972 */, 16 }, /* 2159 */ { MAD_F(0x06d003d4) /* 0.425784903 */, 16 }, /* 2160 */ { MAD_F(0x06d11794) /* 0.426047876 */, 16 }, /* 2161 */ { MAD_F(0x06d22b5e) /* 0.426310889 */, 16 }, /* 2162 */ { MAD_F(0x06d33f32) /* 0.426573942 */, 16 }, /* 2163 */ { MAD_F(0x06d45312) /* 0.426837036 */, 16 }, /* 2164 */ { MAD_F(0x06d566fd) /* 0.427100170 */, 16 }, /* 2165 */ { MAD_F(0x06d67af2) /* 0.427363345 */, 16 }, /* 2166 */ { MAD_F(0x06d78ef3) /* 0.427626561 */, 16 }, /* 2167 */ { MAD_F(0x06d8a2fe) /* 0.427889817 */, 16 }, /* 2168 */ { MAD_F(0x06d9b714) /* 0.428153114 */, 16 }, /* 2169 */ { MAD_F(0x06dacb35) /* 0.428416451 */, 16 }, /* 2170 */ { MAD_F(0x06dbdf61) /* 0.428679828 */, 16 }, /* 2171 */ { MAD_F(0x06dcf398) /* 0.428943246 */, 16 }, /* 2172 */ { MAD_F(0x06de07d9) /* 0.429206704 */, 16 }, /* 2173 */ { MAD_F(0x06df1c26) /* 0.429470203 */, 16 }, /* 2174 */ { MAD_F(0x06e0307d) /* 0.429733743 */, 16 }, /* 2175 */ { MAD_F(0x06e144df) /* 0.429997322 */, 16 }, /* 2176 */ { MAD_F(0x06e2594c) /* 0.430260942 */, 16 }, /* 2177 */ { MAD_F(0x06e36dc4) /* 0.430524603 */, 16 }, /* 2178 */ { MAD_F(0x06e48246) /* 0.430788304 */, 16 }, /* 2179 */ { MAD_F(0x06e596d4) /* 0.431052045 */, 16 }, /* 2180 */ { MAD_F(0x06e6ab6c) /* 0.431315826 */, 16 }, /* 2181 */ { MAD_F(0x06e7c00f) /* 0.431579648 */, 16 }, /* 2182 */ { MAD_F(0x06e8d4bd) /* 0.431843511 */, 16 }, /* 2183 */ { MAD_F(0x06e9e976) /* 0.432107413 */, 16 }, /* 2184 */ { MAD_F(0x06eafe3a) /* 0.432371356 */, 16 }, /* 2185 */ { MAD_F(0x06ec1308) /* 0.432635339 */, 16 }, /* 2186 */ { MAD_F(0x06ed27e2) /* 0.432899362 */, 16 }, /* 2187 */ { MAD_F(0x06ee3cc6) /* 0.433163426 */, 16 }, /* 2188 */ { MAD_F(0x06ef51b4) /* 0.433427530 */, 16 }, /* 2189 */ { MAD_F(0x06f066ae) /* 0.433691674 */, 16 }, /* 2190 */ { MAD_F(0x06f17bb3) /* 0.433955859 */, 16 }, /* 2191 */ { MAD_F(0x06f290c2) /* 0.434220083 */, 16 }, /* 2192 */ { MAD_F(0x06f3a5dc) /* 0.434484348 */, 16 }, /* 2193 */ { MAD_F(0x06f4bb01) /* 0.434748653 */, 16 }, /* 2194 */ { MAD_F(0x06f5d030) /* 0.435012998 */, 16 }, /* 2195 */ { MAD_F(0x06f6e56b) /* 0.435277383 */, 16 }, /* 2196 */ { MAD_F(0x06f7fab0) /* 0.435541809 */, 16 }, /* 2197 */ { MAD_F(0x06f91000) /* 0.435806274 */, 16 }, /* 2198 */ { MAD_F(0x06fa255a) /* 0.436070780 */, 16 }, /* 2199 */ { MAD_F(0x06fb3ac0) /* 0.436335326 */, 16 }, /* 2200 */ { MAD_F(0x06fc5030) /* 0.436599912 */, 16 }, /* 2201 */ { MAD_F(0x06fd65ab) /* 0.436864538 */, 16 }, /* 2202 */ { MAD_F(0x06fe7b31) /* 0.437129204 */, 16 }, /* 2203 */ { MAD_F(0x06ff90c2) /* 0.437393910 */, 16 }, /* 2204 */ { MAD_F(0x0700a65d) /* 0.437658657 */, 16 }, /* 2205 */ { MAD_F(0x0701bc03) /* 0.437923443 */, 16 }, /* 2206 */ { MAD_F(0x0702d1b4) /* 0.438188269 */, 16 }, /* 2207 */ { MAD_F(0x0703e76f) /* 0.438453136 */, 16 }, /* 2208 */ { MAD_F(0x0704fd35) /* 0.438718042 */, 16 }, /* 2209 */ { MAD_F(0x07061306) /* 0.438982988 */, 16 }, /* 2210 */ { MAD_F(0x070728e2) /* 0.439247975 */, 16 }, /* 2211 */ { MAD_F(0x07083ec9) /* 0.439513001 */, 16 }, /* 2212 */ { MAD_F(0x070954ba) /* 0.439778067 */, 16 }, /* 2213 */ { MAD_F(0x070a6ab6) /* 0.440043173 */, 16 }, /* 2214 */ { MAD_F(0x070b80bc) /* 0.440308320 */, 16 }, /* 2215 */ { MAD_F(0x070c96ce) /* 0.440573506 */, 16 }, /* 2216 */ { MAD_F(0x070dacea) /* 0.440838732 */, 16 }, /* 2217 */ { MAD_F(0x070ec310) /* 0.441103997 */, 16 }, /* 2218 */ { MAD_F(0x070fd942) /* 0.441369303 */, 16 }, /* 2219 */ { MAD_F(0x0710ef7e) /* 0.441634649 */, 16 }, /* 2220 */ { MAD_F(0x071205c5) /* 0.441900034 */, 16 }, /* 2221 */ { MAD_F(0x07131c17) /* 0.442165460 */, 16 }, /* 2222 */ { MAD_F(0x07143273) /* 0.442430925 */, 16 }, /* 2223 */ { MAD_F(0x071548da) /* 0.442696430 */, 16 }, /* 2224 */ { MAD_F(0x07165f4b) /* 0.442961975 */, 16 }, /* 2225 */ { MAD_F(0x071775c8) /* 0.443227559 */, 16 }, /* 2226 */ { MAD_F(0x07188c4f) /* 0.443493184 */, 16 }, /* 2227 */ { MAD_F(0x0719a2e0) /* 0.443758848 */, 16 }, /* 2228 */ { MAD_F(0x071ab97d) /* 0.444024552 */, 16 }, /* 2229 */ { MAD_F(0x071bd024) /* 0.444290296 */, 16 }, /* 2230 */ { MAD_F(0x071ce6d6) /* 0.444556079 */, 16 }, /* 2231 */ { MAD_F(0x071dfd92) /* 0.444821902 */, 16 }, /* 2232 */ { MAD_F(0x071f1459) /* 0.445087765 */, 16 }, /* 2233 */ { MAD_F(0x07202b2b) /* 0.445353668 */, 16 }, /* 2234 */ { MAD_F(0x07214207) /* 0.445619610 */, 16 }, /* 2235 */ { MAD_F(0x072258ee) /* 0.445885592 */, 16 }, /* 2236 */ { MAD_F(0x07236fe0) /* 0.446151614 */, 16 }, /* 2237 */ { MAD_F(0x072486dc) /* 0.446417675 */, 16 }, /* 2238 */ { MAD_F(0x07259de3) /* 0.446683776 */, 16 }, /* 2239 */ { MAD_F(0x0726b4f4) /* 0.446949917 */, 16 }, /* 2240 */ { MAD_F(0x0727cc11) /* 0.447216097 */, 16 }, /* 2241 */ { MAD_F(0x0728e338) /* 0.447482317 */, 16 }, /* 2242 */ { MAD_F(0x0729fa69) /* 0.447748576 */, 16 }, /* 2243 */ { MAD_F(0x072b11a5) /* 0.448014875 */, 16 }, /* 2244 */ { MAD_F(0x072c28ec) /* 0.448281214 */, 16 }, /* 2245 */ { MAD_F(0x072d403d) /* 0.448547592 */, 16 }, /* 2246 */ { MAD_F(0x072e5799) /* 0.448814010 */, 16 }, /* 2247 */ { MAD_F(0x072f6f00) /* 0.449080467 */, 16 }, /* 2248 */ { MAD_F(0x07308671) /* 0.449346964 */, 16 }, /* 2249 */ { MAD_F(0x07319ded) /* 0.449613501 */, 16 }, /* 2250 */ { MAD_F(0x0732b573) /* 0.449880076 */, 16 }, /* 2251 */ { MAD_F(0x0733cd04) /* 0.450146692 */, 16 }, /* 2252 */ { MAD_F(0x0734e4a0) /* 0.450413347 */, 16 }, /* 2253 */ { MAD_F(0x0735fc46) /* 0.450680041 */, 16 }, /* 2254 */ { MAD_F(0x073713f7) /* 0.450946775 */, 16 }, /* 2255 */ { MAD_F(0x07382bb2) /* 0.451213548 */, 16 }, /* 2256 */ { MAD_F(0x07394378) /* 0.451480360 */, 16 }, /* 2257 */ { MAD_F(0x073a5b49) /* 0.451747213 */, 16 }, /* 2258 */ { MAD_F(0x073b7324) /* 0.452014104 */, 16 }, /* 2259 */ { MAD_F(0x073c8b0a) /* 0.452281035 */, 16 }, /* 2260 */ { MAD_F(0x073da2fa) /* 0.452548005 */, 16 }, /* 2261 */ { MAD_F(0x073ebaf5) /* 0.452815015 */, 16 }, /* 2262 */ { MAD_F(0x073fd2fa) /* 0.453082064 */, 16 }, /* 2263 */ { MAD_F(0x0740eb0a) /* 0.453349152 */, 16 }, /* 2264 */ { MAD_F(0x07420325) /* 0.453616280 */, 16 }, /* 2265 */ { MAD_F(0x07431b4a) /* 0.453883447 */, 16 }, /* 2266 */ { MAD_F(0x0744337a) /* 0.454150653 */, 16 }, /* 2267 */ { MAD_F(0x07454bb4) /* 0.454417899 */, 16 }, /* 2268 */ { MAD_F(0x074663f8) /* 0.454685184 */, 16 }, /* 2269 */ { MAD_F(0x07477c48) /* 0.454952508 */, 16 }, /* 2270 */ { MAD_F(0x074894a2) /* 0.455219872 */, 16 }, /* 2271 */ { MAD_F(0x0749ad06) /* 0.455487275 */, 16 }, /* 2272 */ { MAD_F(0x074ac575) /* 0.455754717 */, 16 }, /* 2273 */ { MAD_F(0x074bddee) /* 0.456022198 */, 16 }, /* 2274 */ { MAD_F(0x074cf672) /* 0.456289719 */, 16 }, /* 2275 */ { MAD_F(0x074e0f01) /* 0.456557278 */, 16 }, /* 2276 */ { MAD_F(0x074f279a) /* 0.456824877 */, 16 }, /* 2277 */ { MAD_F(0x0750403e) /* 0.457092516 */, 16 }, /* 2278 */ { MAD_F(0x075158ec) /* 0.457360193 */, 16 }, /* 2279 */ { MAD_F(0x075271a4) /* 0.457627909 */, 16 }, /* 2280 */ { MAD_F(0x07538a67) /* 0.457895665 */, 16 }, /* 2281 */ { MAD_F(0x0754a335) /* 0.458163460 */, 16 }, /* 2282 */ { MAD_F(0x0755bc0d) /* 0.458431294 */, 16 }, /* 2283 */ { MAD_F(0x0756d4f0) /* 0.458699167 */, 16 }, /* 2284 */ { MAD_F(0x0757eddd) /* 0.458967079 */, 16 }, /* 2285 */ { MAD_F(0x075906d5) /* 0.459235030 */, 16 }, /* 2286 */ { MAD_F(0x075a1fd7) /* 0.459503021 */, 16 }, /* 2287 */ { MAD_F(0x075b38e3) /* 0.459771050 */, 16 }, /* 2288 */ { MAD_F(0x075c51fa) /* 0.460039119 */, 16 }, /* 2289 */ { MAD_F(0x075d6b1c) /* 0.460307226 */, 16 }, /* 2290 */ { MAD_F(0x075e8448) /* 0.460575373 */, 16 }, /* 2291 */ { MAD_F(0x075f9d7f) /* 0.460843559 */, 16 }, /* 2292 */ { MAD_F(0x0760b6c0) /* 0.461111783 */, 16 }, /* 2293 */ { MAD_F(0x0761d00b) /* 0.461380047 */, 16 }, /* 2294 */ { MAD_F(0x0762e961) /* 0.461648350 */, 16 }, /* 2295 */ { MAD_F(0x076402c1) /* 0.461916691 */, 16 }, /* 2296 */ { MAD_F(0x07651c2c) /* 0.462185072 */, 16 }, /* 2297 */ { MAD_F(0x076635a2) /* 0.462453492 */, 16 }, /* 2298 */ { MAD_F(0x07674f22) /* 0.462721950 */, 16 }, /* 2299 */ { MAD_F(0x076868ac) /* 0.462990448 */, 16 }, /* 2300 */ { MAD_F(0x07698240) /* 0.463258984 */, 16 }, /* 2301 */ { MAD_F(0x076a9be0) /* 0.463527560 */, 16 }, /* 2302 */ { MAD_F(0x076bb589) /* 0.463796174 */, 16 }, /* 2303 */ { MAD_F(0x076ccf3d) /* 0.464064827 */, 16 }, /* 2304 */ { MAD_F(0x076de8fc) /* 0.464333519 */, 16 }, /* 2305 */ { MAD_F(0x076f02c5) /* 0.464602250 */, 16 }, /* 2306 */ { MAD_F(0x07701c98) /* 0.464871020 */, 16 }, /* 2307 */ { MAD_F(0x07713676) /* 0.465139829 */, 16 }, /* 2308 */ { MAD_F(0x0772505e) /* 0.465408676 */, 16 }, /* 2309 */ { MAD_F(0x07736a51) /* 0.465677563 */, 16 }, /* 2310 */ { MAD_F(0x0774844e) /* 0.465946488 */, 16 }, /* 2311 */ { MAD_F(0x07759e55) /* 0.466215452 */, 16 }, /* 2312 */ { MAD_F(0x0776b867) /* 0.466484455 */, 16 }, /* 2313 */ { MAD_F(0x0777d283) /* 0.466753496 */, 16 }, /* 2314 */ { MAD_F(0x0778ecaa) /* 0.467022577 */, 16 }, /* 2315 */ { MAD_F(0x077a06db) /* 0.467291696 */, 16 }, /* 2316 */ { MAD_F(0x077b2117) /* 0.467560854 */, 16 }, /* 2317 */ { MAD_F(0x077c3b5d) /* 0.467830050 */, 16 }, /* 2318 */ { MAD_F(0x077d55ad) /* 0.468099285 */, 16 }, /* 2319 */ { MAD_F(0x077e7008) /* 0.468368560 */, 16 }, /* 2320 */ { MAD_F(0x077f8a6d) /* 0.468637872 */, 16 }, /* 2321 */ { MAD_F(0x0780a4dc) /* 0.468907224 */, 16 }, /* 2322 */ { MAD_F(0x0781bf56) /* 0.469176614 */, 16 }, /* 2323 */ { MAD_F(0x0782d9da) /* 0.469446043 */, 16 }, /* 2324 */ { MAD_F(0x0783f469) /* 0.469715510 */, 16 }, /* 2325 */ { MAD_F(0x07850f02) /* 0.469985016 */, 16 }, /* 2326 */ { MAD_F(0x078629a5) /* 0.470254561 */, 16 }, /* 2327 */ { MAD_F(0x07874453) /* 0.470524145 */, 16 }, /* 2328 */ { MAD_F(0x07885f0b) /* 0.470793767 */, 16 }, /* 2329 */ { MAD_F(0x078979ce) /* 0.471063427 */, 16 }, /* 2330 */ { MAD_F(0x078a949a) /* 0.471333126 */, 16 }, /* 2331 */ { MAD_F(0x078baf72) /* 0.471602864 */, 16 }, /* 2332 */ { MAD_F(0x078cca53) /* 0.471872641 */, 16 }, /* 2333 */ { MAD_F(0x078de53f) /* 0.472142456 */, 16 }, /* 2334 */ { MAD_F(0x078f0035) /* 0.472412309 */, 16 }, /* 2335 */ { MAD_F(0x07901b36) /* 0.472682201 */, 16 }, /* 2336 */ { MAD_F(0x07913641) /* 0.472952132 */, 16 }, /* 2337 */ { MAD_F(0x07925156) /* 0.473222101 */, 16 }, /* 2338 */ { MAD_F(0x07936c76) /* 0.473492108 */, 16 }, /* 2339 */ { MAD_F(0x079487a0) /* 0.473762155 */, 16 }, /* 2340 */ { MAD_F(0x0795a2d4) /* 0.474032239 */, 16 }, /* 2341 */ { MAD_F(0x0796be13) /* 0.474302362 */, 16 }, /* 2342 */ { MAD_F(0x0797d95c) /* 0.474572524 */, 16 }, /* 2343 */ { MAD_F(0x0798f4af) /* 0.474842724 */, 16 }, /* 2344 */ { MAD_F(0x079a100c) /* 0.475112962 */, 16 }, /* 2345 */ { MAD_F(0x079b2b74) /* 0.475383239 */, 16 }, /* 2346 */ { MAD_F(0x079c46e7) /* 0.475653554 */, 16 }, /* 2347 */ { MAD_F(0x079d6263) /* 0.475923908 */, 16 }, /* 2348 */ { MAD_F(0x079e7dea) /* 0.476194300 */, 16 }, /* 2349 */ { MAD_F(0x079f997b) /* 0.476464731 */, 16 }, /* 2350 */ { MAD_F(0x07a0b516) /* 0.476735200 */, 16 }, /* 2351 */ { MAD_F(0x07a1d0bc) /* 0.477005707 */, 16 }, /* 2352 */ { MAD_F(0x07a2ec6c) /* 0.477276252 */, 16 }, /* 2353 */ { MAD_F(0x07a40827) /* 0.477546836 */, 16 }, /* 2354 */ { MAD_F(0x07a523eb) /* 0.477817459 */, 16 }, /* 2355 */ { MAD_F(0x07a63fba) /* 0.478088119 */, 16 }, /* 2356 */ { MAD_F(0x07a75b93) /* 0.478358818 */, 16 }, /* 2357 */ { MAD_F(0x07a87777) /* 0.478629555 */, 16 }, /* 2358 */ { MAD_F(0x07a99364) /* 0.478900331 */, 16 }, /* 2359 */ { MAD_F(0x07aaaf5c) /* 0.479171145 */, 16 }, /* 2360 */ { MAD_F(0x07abcb5f) /* 0.479441997 */, 16 }, /* 2361 */ { MAD_F(0x07ace76b) /* 0.479712887 */, 16 }, /* 2362 */ { MAD_F(0x07ae0382) /* 0.479983816 */, 16 }, /* 2363 */ { MAD_F(0x07af1fa3) /* 0.480254782 */, 16 }, /* 2364 */ { MAD_F(0x07b03bcf) /* 0.480525787 */, 16 }, /* 2365 */ { MAD_F(0x07b15804) /* 0.480796831 */, 16 }, /* 2366 */ { MAD_F(0x07b27444) /* 0.481067912 */, 16 }, /* 2367 */ { MAD_F(0x07b3908e) /* 0.481339032 */, 16 }, /* 2368 */ { MAD_F(0x07b4ace3) /* 0.481610189 */, 16 }, /* 2369 */ { MAD_F(0x07b5c941) /* 0.481881385 */, 16 }, /* 2370 */ { MAD_F(0x07b6e5aa) /* 0.482152620 */, 16 }, /* 2371 */ { MAD_F(0x07b8021d) /* 0.482423892 */, 16 }, /* 2372 */ { MAD_F(0x07b91e9b) /* 0.482695202 */, 16 }, /* 2373 */ { MAD_F(0x07ba3b22) /* 0.482966551 */, 16 }, /* 2374 */ { MAD_F(0x07bb57b4) /* 0.483237938 */, 16 }, /* 2375 */ { MAD_F(0x07bc7450) /* 0.483509362 */, 16 }, /* 2376 */ { MAD_F(0x07bd90f6) /* 0.483780825 */, 16 }, /* 2377 */ { MAD_F(0x07beada7) /* 0.484052326 */, 16 }, /* 2378 */ { MAD_F(0x07bfca61) /* 0.484323865 */, 16 }, /* 2379 */ { MAD_F(0x07c0e726) /* 0.484595443 */, 16 }, /* 2380 */ { MAD_F(0x07c203f5) /* 0.484867058 */, 16 }, /* 2381 */ { MAD_F(0x07c320cf) /* 0.485138711 */, 16 }, /* 2382 */ { MAD_F(0x07c43db2) /* 0.485410402 */, 16 }, /* 2383 */ { MAD_F(0x07c55aa0) /* 0.485682131 */, 16 }, /* 2384 */ { MAD_F(0x07c67798) /* 0.485953899 */, 16 }, /* 2385 */ { MAD_F(0x07c7949a) /* 0.486225704 */, 16 }, /* 2386 */ { MAD_F(0x07c8b1a7) /* 0.486497547 */, 16 }, /* 2387 */ { MAD_F(0x07c9cebd) /* 0.486769429 */, 16 }, /* 2388 */ { MAD_F(0x07caebde) /* 0.487041348 */, 16 }, /* 2389 */ { MAD_F(0x07cc0909) /* 0.487313305 */, 16 }, /* 2390 */ { MAD_F(0x07cd263e) /* 0.487585300 */, 16 }, /* 2391 */ { MAD_F(0x07ce437d) /* 0.487857333 */, 16 }, /* 2392 */ { MAD_F(0x07cf60c7) /* 0.488129404 */, 16 }, /* 2393 */ { MAD_F(0x07d07e1b) /* 0.488401513 */, 16 }, /* 2394 */ { MAD_F(0x07d19b79) /* 0.488673660 */, 16 }, /* 2395 */ { MAD_F(0x07d2b8e1) /* 0.488945845 */, 16 }, /* 2396 */ { MAD_F(0x07d3d653) /* 0.489218067 */, 16 }, /* 2397 */ { MAD_F(0x07d4f3cf) /* 0.489490328 */, 16 }, /* 2398 */ { MAD_F(0x07d61156) /* 0.489762626 */, 16 }, /* 2399 */ { MAD_F(0x07d72ee6) /* 0.490034962 */, 16 }, /* 2400 */ { MAD_F(0x07d84c81) /* 0.490307336 */, 16 }, /* 2401 */ { MAD_F(0x07d96a26) /* 0.490579748 */, 16 }, /* 2402 */ { MAD_F(0x07da87d5) /* 0.490852198 */, 16 }, /* 2403 */ { MAD_F(0x07dba58f) /* 0.491124686 */, 16 }, /* 2404 */ { MAD_F(0x07dcc352) /* 0.491397211 */, 16 }, /* 2405 */ { MAD_F(0x07dde120) /* 0.491669774 */, 16 }, /* 2406 */ { MAD_F(0x07defef7) /* 0.491942375 */, 16 }, /* 2407 */ { MAD_F(0x07e01cd9) /* 0.492215014 */, 16 }, /* 2408 */ { MAD_F(0x07e13ac5) /* 0.492487690 */, 16 }, /* 2409 */ { MAD_F(0x07e258bc) /* 0.492760404 */, 16 }, /* 2410 */ { MAD_F(0x07e376bc) /* 0.493033156 */, 16 }, /* 2411 */ { MAD_F(0x07e494c6) /* 0.493305946 */, 16 }, /* 2412 */ { MAD_F(0x07e5b2db) /* 0.493578773 */, 16 }, /* 2413 */ { MAD_F(0x07e6d0f9) /* 0.493851638 */, 16 }, /* 2414 */ { MAD_F(0x07e7ef22) /* 0.494124541 */, 16 }, /* 2415 */ { MAD_F(0x07e90d55) /* 0.494397481 */, 16 }, /* 2416 */ { MAD_F(0x07ea2b92) /* 0.494670459 */, 16 }, /* 2417 */ { MAD_F(0x07eb49d9) /* 0.494943475 */, 16 }, /* 2418 */ { MAD_F(0x07ec682a) /* 0.495216529 */, 16 }, /* 2419 */ { MAD_F(0x07ed8686) /* 0.495489620 */, 16 }, /* 2420 */ { MAD_F(0x07eea4eb) /* 0.495762748 */, 16 }, /* 2421 */ { MAD_F(0x07efc35b) /* 0.496035915 */, 16 }, /* 2422 */ { MAD_F(0x07f0e1d4) /* 0.496309119 */, 16 }, /* 2423 */ { MAD_F(0x07f20058) /* 0.496582360 */, 16 }, /* 2424 */ { MAD_F(0x07f31ee6) /* 0.496855639 */, 16 }, /* 2425 */ { MAD_F(0x07f43d7e) /* 0.497128956 */, 16 }, /* 2426 */ { MAD_F(0x07f55c20) /* 0.497402310 */, 16 }, /* 2427 */ { MAD_F(0x07f67acc) /* 0.497675702 */, 16 }, /* 2428 */ { MAD_F(0x07f79982) /* 0.497949132 */, 16 }, /* 2429 */ { MAD_F(0x07f8b842) /* 0.498222598 */, 16 }, /* 2430 */ { MAD_F(0x07f9d70c) /* 0.498496103 */, 16 }, /* 2431 */ { MAD_F(0x07faf5e1) /* 0.498769645 */, 16 }, /* 2432 */ { MAD_F(0x07fc14bf) /* 0.499043224 */, 16 }, /* 2433 */ { MAD_F(0x07fd33a8) /* 0.499316841 */, 16 }, /* 2434 */ { MAD_F(0x07fe529a) /* 0.499590496 */, 16 }, /* 2435 */ { MAD_F(0x07ff7197) /* 0.499864188 */, 16 }, /* 2436 */ { MAD_F(0x0400484f) /* 0.250068959 */, 17 }, /* 2437 */ { MAD_F(0x0400d7d7) /* 0.250205842 */, 17 }, /* 2438 */ { MAD_F(0x04016764) /* 0.250342744 */, 17 }, /* 2439 */ { MAD_F(0x0401f6f7) /* 0.250479665 */, 17 }, /* 2440 */ { MAD_F(0x0402868e) /* 0.250616605 */, 17 }, /* 2441 */ { MAD_F(0x0403162b) /* 0.250753563 */, 17 }, /* 2442 */ { MAD_F(0x0403a5cc) /* 0.250890540 */, 17 }, /* 2443 */ { MAD_F(0x04043573) /* 0.251027536 */, 17 }, /* 2444 */ { MAD_F(0x0404c51e) /* 0.251164550 */, 17 }, /* 2445 */ { MAD_F(0x040554cf) /* 0.251301583 */, 17 }, /* 2446 */ { MAD_F(0x0405e484) /* 0.251438635 */, 17 }, /* 2447 */ { MAD_F(0x0406743f) /* 0.251575706 */, 17 }, /* 2448 */ { MAD_F(0x040703ff) /* 0.251712795 */, 17 }, /* 2449 */ { MAD_F(0x040793c3) /* 0.251849903 */, 17 }, /* 2450 */ { MAD_F(0x0408238d) /* 0.251987029 */, 17 }, /* 2451 */ { MAD_F(0x0408b35b) /* 0.252124174 */, 17 }, /* 2452 */ { MAD_F(0x0409432f) /* 0.252261338 */, 17 }, /* 2453 */ { MAD_F(0x0409d308) /* 0.252398520 */, 17 }, /* 2454 */ { MAD_F(0x040a62e5) /* 0.252535721 */, 17 }, /* 2455 */ { MAD_F(0x040af2c8) /* 0.252672941 */, 17 }, /* 2456 */ { MAD_F(0x040b82b0) /* 0.252810180 */, 17 }, /* 2457 */ { MAD_F(0x040c129c) /* 0.252947436 */, 17 }, /* 2458 */ { MAD_F(0x040ca28e) /* 0.253084712 */, 17 }, /* 2459 */ { MAD_F(0x040d3284) /* 0.253222006 */, 17 }, /* 2460 */ { MAD_F(0x040dc280) /* 0.253359319 */, 17 }, /* 2461 */ { MAD_F(0x040e5281) /* 0.253496651 */, 17 }, /* 2462 */ { MAD_F(0x040ee286) /* 0.253634001 */, 17 }, /* 2463 */ { MAD_F(0x040f7291) /* 0.253771369 */, 17 }, /* 2464 */ { MAD_F(0x041002a1) /* 0.253908756 */, 17 }, /* 2465 */ { MAD_F(0x041092b5) /* 0.254046162 */, 17 }, /* 2466 */ { MAD_F(0x041122cf) /* 0.254183587 */, 17 }, /* 2467 */ { MAD_F(0x0411b2ed) /* 0.254321030 */, 17 }, /* 2468 */ { MAD_F(0x04124311) /* 0.254458491 */, 17 }, /* 2469 */ { MAD_F(0x0412d339) /* 0.254595971 */, 17 }, /* 2470 */ { MAD_F(0x04136367) /* 0.254733470 */, 17 }, /* 2471 */ { MAD_F(0x0413f399) /* 0.254870987 */, 17 }, /* 2472 */ { MAD_F(0x041483d1) /* 0.255008523 */, 17 }, /* 2473 */ { MAD_F(0x0415140d) /* 0.255146077 */, 17 }, /* 2474 */ { MAD_F(0x0415a44f) /* 0.255283650 */, 17 }, /* 2475 */ { MAD_F(0x04163495) /* 0.255421241 */, 17 }, /* 2476 */ { MAD_F(0x0416c4e1) /* 0.255558851 */, 17 }, /* 2477 */ { MAD_F(0x04175531) /* 0.255696480 */, 17 }, /* 2478 */ { MAD_F(0x0417e586) /* 0.255834127 */, 17 }, /* 2479 */ { MAD_F(0x041875e1) /* 0.255971792 */, 17 }, /* 2480 */ { MAD_F(0x04190640) /* 0.256109476 */, 17 }, /* 2481 */ { MAD_F(0x041996a4) /* 0.256247179 */, 17 }, /* 2482 */ { MAD_F(0x041a270d) /* 0.256384900 */, 17 }, /* 2483 */ { MAD_F(0x041ab77b) /* 0.256522639 */, 17 }, /* 2484 */ { MAD_F(0x041b47ef) /* 0.256660397 */, 17 }, /* 2485 */ { MAD_F(0x041bd867) /* 0.256798174 */, 17 }, /* 2486 */ { MAD_F(0x041c68e4) /* 0.256935969 */, 17 }, /* 2487 */ { MAD_F(0x041cf966) /* 0.257073782 */, 17 }, /* 2488 */ { MAD_F(0x041d89ed) /* 0.257211614 */, 17 }, /* 2489 */ { MAD_F(0x041e1a79) /* 0.257349465 */, 17 }, /* 2490 */ { MAD_F(0x041eab0a) /* 0.257487334 */, 17 }, /* 2491 */ { MAD_F(0x041f3b9f) /* 0.257625221 */, 17 }, /* 2492 */ { MAD_F(0x041fcc3a) /* 0.257763127 */, 17 }, /* 2493 */ { MAD_F(0x04205cda) /* 0.257901051 */, 17 }, /* 2494 */ { MAD_F(0x0420ed7f) /* 0.258038994 */, 17 }, /* 2495 */ { MAD_F(0x04217e28) /* 0.258176955 */, 17 }, /* 2496 */ { MAD_F(0x04220ed7) /* 0.258314934 */, 17 }, /* 2497 */ { MAD_F(0x04229f8a) /* 0.258452932 */, 17 }, /* 2498 */ { MAD_F(0x04233043) /* 0.258590948 */, 17 }, /* 2499 */ { MAD_F(0x0423c100) /* 0.258728983 */, 17 }, /* 2500 */ { MAD_F(0x042451c3) /* 0.258867036 */, 17 }, /* 2501 */ { MAD_F(0x0424e28a) /* 0.259005108 */, 17 }, /* 2502 */ { MAD_F(0x04257356) /* 0.259143198 */, 17 }, /* 2503 */ { MAD_F(0x04260428) /* 0.259281307 */, 17 }, /* 2504 */ { MAD_F(0x042694fe) /* 0.259419433 */, 17 }, /* 2505 */ { MAD_F(0x042725d9) /* 0.259557579 */, 17 }, /* 2506 */ { MAD_F(0x0427b6b9) /* 0.259695742 */, 17 }, /* 2507 */ { MAD_F(0x0428479e) /* 0.259833924 */, 17 }, /* 2508 */ { MAD_F(0x0428d888) /* 0.259972124 */, 17 }, /* 2509 */ { MAD_F(0x04296976) /* 0.260110343 */, 17 }, /* 2510 */ { MAD_F(0x0429fa6a) /* 0.260248580 */, 17 }, /* 2511 */ { MAD_F(0x042a8b63) /* 0.260386836 */, 17 }, /* 2512 */ { MAD_F(0x042b1c60) /* 0.260525110 */, 17 }, /* 2513 */ { MAD_F(0x042bad63) /* 0.260663402 */, 17 }, /* 2514 */ { MAD_F(0x042c3e6a) /* 0.260801712 */, 17 }, /* 2515 */ { MAD_F(0x042ccf77) /* 0.260940041 */, 17 }, /* 2516 */ { MAD_F(0x042d6088) /* 0.261078388 */, 17 }, /* 2517 */ { MAD_F(0x042df19e) /* 0.261216754 */, 17 }, /* 2518 */ { MAD_F(0x042e82b9) /* 0.261355137 */, 17 }, /* 2519 */ { MAD_F(0x042f13d9) /* 0.261493540 */, 17 }, /* 2520 */ { MAD_F(0x042fa4fe) /* 0.261631960 */, 17 }, /* 2521 */ { MAD_F(0x04303628) /* 0.261770399 */, 17 }, /* 2522 */ { MAD_F(0x0430c757) /* 0.261908856 */, 17 }, /* 2523 */ { MAD_F(0x0431588b) /* 0.262047331 */, 17 }, /* 2524 */ { MAD_F(0x0431e9c3) /* 0.262185825 */, 17 }, /* 2525 */ { MAD_F(0x04327b01) /* 0.262324337 */, 17 }, /* 2526 */ { MAD_F(0x04330c43) /* 0.262462867 */, 17 }, /* 2527 */ { MAD_F(0x04339d8a) /* 0.262601416 */, 17 }, /* 2528 */ { MAD_F(0x04342ed7) /* 0.262739982 */, 17 }, /* 2529 */ { MAD_F(0x0434c028) /* 0.262878568 */, 17 }, /* 2530 */ { MAD_F(0x0435517e) /* 0.263017171 */, 17 }, /* 2531 */ { MAD_F(0x0435e2d9) /* 0.263155792 */, 17 }, /* 2532 */ { MAD_F(0x04367439) /* 0.263294432 */, 17 }, /* 2533 */ { MAD_F(0x0437059e) /* 0.263433090 */, 17 }, /* 2534 */ { MAD_F(0x04379707) /* 0.263571767 */, 17 }, /* 2535 */ { MAD_F(0x04382876) /* 0.263710461 */, 17 }, /* 2536 */ { MAD_F(0x0438b9e9) /* 0.263849174 */, 17 }, /* 2537 */ { MAD_F(0x04394b61) /* 0.263987905 */, 17 }, /* 2538 */ { MAD_F(0x0439dcdf) /* 0.264126655 */, 17 }, /* 2539 */ { MAD_F(0x043a6e61) /* 0.264265422 */, 17 }, /* 2540 */ { MAD_F(0x043affe8) /* 0.264404208 */, 17 }, /* 2541 */ { MAD_F(0x043b9174) /* 0.264543012 */, 17 }, /* 2542 */ { MAD_F(0x043c2305) /* 0.264681834 */, 17 }, /* 2543 */ { MAD_F(0x043cb49a) /* 0.264820674 */, 17 }, /* 2544 */ { MAD_F(0x043d4635) /* 0.264959533 */, 17 }, /* 2545 */ { MAD_F(0x043dd7d4) /* 0.265098410 */, 17 }, /* 2546 */ { MAD_F(0x043e6979) /* 0.265237305 */, 17 }, /* 2547 */ { MAD_F(0x043efb22) /* 0.265376218 */, 17 }, /* 2548 */ { MAD_F(0x043f8cd0) /* 0.265515149 */, 17 }, /* 2549 */ { MAD_F(0x04401e83) /* 0.265654099 */, 17 }, /* 2550 */ { MAD_F(0x0440b03b) /* 0.265793066 */, 17 }, /* 2551 */ { MAD_F(0x044141f7) /* 0.265932052 */, 17 }, /* 2552 */ { MAD_F(0x0441d3b9) /* 0.266071056 */, 17 }, /* 2553 */ { MAD_F(0x04426580) /* 0.266210078 */, 17 }, /* 2554 */ { MAD_F(0x0442f74b) /* 0.266349119 */, 17 }, /* 2555 */ { MAD_F(0x0443891b) /* 0.266488177 */, 17 }, /* 2556 */ { MAD_F(0x04441af0) /* 0.266627254 */, 17 }, /* 2557 */ { MAD_F(0x0444acca) /* 0.266766349 */, 17 }, /* 2558 */ { MAD_F(0x04453ea9) /* 0.266905462 */, 17 }, /* 2559 */ { MAD_F(0x0445d08d) /* 0.267044593 */, 17 }, /* 2560 */ { MAD_F(0x04466275) /* 0.267183742 */, 17 }, /* 2561 */ { MAD_F(0x0446f463) /* 0.267322909 */, 17 }, /* 2562 */ { MAD_F(0x04478655) /* 0.267462094 */, 17 }, /* 2563 */ { MAD_F(0x0448184c) /* 0.267601298 */, 17 }, /* 2564 */ { MAD_F(0x0448aa48) /* 0.267740519 */, 17 }, /* 2565 */ { MAD_F(0x04493c49) /* 0.267879759 */, 17 }, /* 2566 */ { MAD_F(0x0449ce4f) /* 0.268019017 */, 17 }, /* 2567 */ { MAD_F(0x044a6059) /* 0.268158293 */, 17 }, /* 2568 */ { MAD_F(0x044af269) /* 0.268297587 */, 17 }, /* 2569 */ { MAD_F(0x044b847d) /* 0.268436899 */, 17 }, /* 2570 */ { MAD_F(0x044c1696) /* 0.268576229 */, 17 }, /* 2571 */ { MAD_F(0x044ca8b4) /* 0.268715577 */, 17 }, /* 2572 */ { MAD_F(0x044d3ad7) /* 0.268854943 */, 17 }, /* 2573 */ { MAD_F(0x044dccff) /* 0.268994328 */, 17 }, /* 2574 */ { MAD_F(0x044e5f2b) /* 0.269133730 */, 17 }, /* 2575 */ { MAD_F(0x044ef15d) /* 0.269273150 */, 17 }, /* 2576 */ { MAD_F(0x044f8393) /* 0.269412589 */, 17 }, /* 2577 */ { MAD_F(0x045015ce) /* 0.269552045 */, 17 }, /* 2578 */ { MAD_F(0x0450a80e) /* 0.269691520 */, 17 }, /* 2579 */ { MAD_F(0x04513a53) /* 0.269831013 */, 17 }, /* 2580 */ { MAD_F(0x0451cc9c) /* 0.269970523 */, 17 }, /* 2581 */ { MAD_F(0x04525eeb) /* 0.270110052 */, 17 }, /* 2582 */ { MAD_F(0x0452f13e) /* 0.270249599 */, 17 }, /* 2583 */ { MAD_F(0x04538396) /* 0.270389163 */, 17 }, /* 2584 */ { MAD_F(0x045415f3) /* 0.270528746 */, 17 }, /* 2585 */ { MAD_F(0x0454a855) /* 0.270668347 */, 17 }, /* 2586 */ { MAD_F(0x04553abb) /* 0.270807965 */, 17 }, /* 2587 */ { MAD_F(0x0455cd27) /* 0.270947602 */, 17 }, /* 2588 */ { MAD_F(0x04565f97) /* 0.271087257 */, 17 }, /* 2589 */ { MAD_F(0x0456f20c) /* 0.271226930 */, 17 }, /* 2590 */ { MAD_F(0x04578486) /* 0.271366620 */, 17 }, /* 2591 */ { MAD_F(0x04581705) /* 0.271506329 */, 17 }, /* 2592 */ { MAD_F(0x0458a989) /* 0.271646056 */, 17 }, /* 2593 */ { MAD_F(0x04593c11) /* 0.271785800 */, 17 }, /* 2594 */ { MAD_F(0x0459ce9e) /* 0.271925563 */, 17 }, /* 2595 */ { MAD_F(0x045a6130) /* 0.272065343 */, 17 }, /* 2596 */ { MAD_F(0x045af3c7) /* 0.272205142 */, 17 }, /* 2597 */ { MAD_F(0x045b8663) /* 0.272344958 */, 17 }, /* 2598 */ { MAD_F(0x045c1903) /* 0.272484793 */, 17 }, /* 2599 */ { MAD_F(0x045caba9) /* 0.272624645 */, 17 }, /* 2600 */ { MAD_F(0x045d3e53) /* 0.272764515 */, 17 }, /* 2601 */ { MAD_F(0x045dd102) /* 0.272904403 */, 17 }, /* 2602 */ { MAD_F(0x045e63b6) /* 0.273044310 */, 17 }, /* 2603 */ { MAD_F(0x045ef66e) /* 0.273184234 */, 17 }, /* 2604 */ { MAD_F(0x045f892b) /* 0.273324176 */, 17 }, /* 2605 */ { MAD_F(0x04601bee) /* 0.273464136 */, 17 }, /* 2606 */ { MAD_F(0x0460aeb5) /* 0.273604113 */, 17 }, /* 2607 */ { MAD_F(0x04614180) /* 0.273744109 */, 17 }, /* 2608 */ { MAD_F(0x0461d451) /* 0.273884123 */, 17 }, /* 2609 */ { MAD_F(0x04626727) /* 0.274024154 */, 17 }, /* 2610 */ { MAD_F(0x0462fa01) /* 0.274164204 */, 17 }, /* 2611 */ { MAD_F(0x04638ce0) /* 0.274304271 */, 17 }, /* 2612 */ { MAD_F(0x04641fc4) /* 0.274444356 */, 17 }, /* 2613 */ { MAD_F(0x0464b2ac) /* 0.274584459 */, 17 }, /* 2614 */ { MAD_F(0x0465459a) /* 0.274724580 */, 17 }, /* 2615 */ { MAD_F(0x0465d88c) /* 0.274864719 */, 17 }, /* 2616 */ { MAD_F(0x04666b83) /* 0.275004875 */, 17 }, /* 2617 */ { MAD_F(0x0466fe7f) /* 0.275145050 */, 17 }, /* 2618 */ { MAD_F(0x0467917f) /* 0.275285242 */, 17 }, /* 2619 */ { MAD_F(0x04682485) /* 0.275425452 */, 17 }, /* 2620 */ { MAD_F(0x0468b78f) /* 0.275565681 */, 17 }, /* 2621 */ { MAD_F(0x04694a9e) /* 0.275705926 */, 17 }, /* 2622 */ { MAD_F(0x0469ddb2) /* 0.275846190 */, 17 }, /* 2623 */ { MAD_F(0x046a70ca) /* 0.275986472 */, 17 }, /* 2624 */ { MAD_F(0x046b03e7) /* 0.276126771 */, 17 }, /* 2625 */ { MAD_F(0x046b970a) /* 0.276267088 */, 17 }, /* 2626 */ { MAD_F(0x046c2a31) /* 0.276407423 */, 17 }, /* 2627 */ { MAD_F(0x046cbd5c) /* 0.276547776 */, 17 }, /* 2628 */ { MAD_F(0x046d508d) /* 0.276688147 */, 17 }, /* 2629 */ { MAD_F(0x046de3c2) /* 0.276828535 */, 17 }, /* 2630 */ { MAD_F(0x046e76fc) /* 0.276968942 */, 17 }, /* 2631 */ { MAD_F(0x046f0a3b) /* 0.277109366 */, 17 }, /* 2632 */ { MAD_F(0x046f9d7e) /* 0.277249808 */, 17 }, /* 2633 */ { MAD_F(0x047030c7) /* 0.277390267 */, 17 }, /* 2634 */ { MAD_F(0x0470c414) /* 0.277530745 */, 17 }, /* 2635 */ { MAD_F(0x04715766) /* 0.277671240 */, 17 }, /* 2636 */ { MAD_F(0x0471eabc) /* 0.277811753 */, 17 }, /* 2637 */ { MAD_F(0x04727e18) /* 0.277952284 */, 17 }, /* 2638 */ { MAD_F(0x04731178) /* 0.278092832 */, 17 }, /* 2639 */ { MAD_F(0x0473a4dd) /* 0.278233399 */, 17 }, /* 2640 */ { MAD_F(0x04743847) /* 0.278373983 */, 17 }, /* 2641 */ { MAD_F(0x0474cbb5) /* 0.278514584 */, 17 }, /* 2642 */ { MAD_F(0x04755f29) /* 0.278655204 */, 17 }, /* 2643 */ { MAD_F(0x0475f2a1) /* 0.278795841 */, 17 }, /* 2644 */ { MAD_F(0x0476861d) /* 0.278936496 */, 17 }, /* 2645 */ { MAD_F(0x0477199f) /* 0.279077169 */, 17 }, /* 2646 */ { MAD_F(0x0477ad25) /* 0.279217860 */, 17 }, /* 2647 */ { MAD_F(0x047840b0) /* 0.279358568 */, 17 }, /* 2648 */ { MAD_F(0x0478d440) /* 0.279499294 */, 17 }, /* 2649 */ { MAD_F(0x047967d5) /* 0.279640037 */, 17 }, /* 2650 */ { MAD_F(0x0479fb6e) /* 0.279780799 */, 17 }, /* 2651 */ { MAD_F(0x047a8f0c) /* 0.279921578 */, 17 }, /* 2652 */ { MAD_F(0x047b22af) /* 0.280062375 */, 17 }, /* 2653 */ { MAD_F(0x047bb657) /* 0.280203189 */, 17 }, /* 2654 */ { MAD_F(0x047c4a03) /* 0.280344021 */, 17 }, /* 2655 */ { MAD_F(0x047cddb4) /* 0.280484871 */, 17 }, /* 2656 */ { MAD_F(0x047d716a) /* 0.280625739 */, 17 }, /* 2657 */ { MAD_F(0x047e0524) /* 0.280766624 */, 17 }, /* 2658 */ { MAD_F(0x047e98e4) /* 0.280907527 */, 17 }, /* 2659 */ { MAD_F(0x047f2ca8) /* 0.281048447 */, 17 }, /* 2660 */ { MAD_F(0x047fc071) /* 0.281189385 */, 17 }, /* 2661 */ { MAD_F(0x0480543e) /* 0.281330341 */, 17 }, /* 2662 */ { MAD_F(0x0480e811) /* 0.281471315 */, 17 }, /* 2663 */ { MAD_F(0x04817be8) /* 0.281612306 */, 17 }, /* 2664 */ { MAD_F(0x04820fc3) /* 0.281753315 */, 17 }, /* 2665 */ { MAD_F(0x0482a3a4) /* 0.281894341 */, 17 }, /* 2666 */ { MAD_F(0x04833789) /* 0.282035386 */, 17 }, /* 2667 */ { MAD_F(0x0483cb73) /* 0.282176447 */, 17 }, /* 2668 */ { MAD_F(0x04845f62) /* 0.282317527 */, 17 }, /* 2669 */ { MAD_F(0x0484f355) /* 0.282458624 */, 17 }, /* 2670 */ { MAD_F(0x0485874d) /* 0.282599738 */, 17 }, /* 2671 */ { MAD_F(0x04861b4a) /* 0.282740871 */, 17 }, /* 2672 */ { MAD_F(0x0486af4c) /* 0.282882021 */, 17 }, /* 2673 */ { MAD_F(0x04874352) /* 0.283023188 */, 17 }, /* 2674 */ { MAD_F(0x0487d75d) /* 0.283164373 */, 17 }, /* 2675 */ { MAD_F(0x04886b6d) /* 0.283305576 */, 17 }, /* 2676 */ { MAD_F(0x0488ff82) /* 0.283446796 */, 17 }, /* 2677 */ { MAD_F(0x0489939b) /* 0.283588034 */, 17 }, /* 2678 */ { MAD_F(0x048a27b9) /* 0.283729290 */, 17 }, /* 2679 */ { MAD_F(0x048abbdc) /* 0.283870563 */, 17 }, /* 2680 */ { MAD_F(0x048b5003) /* 0.284011853 */, 17 }, /* 2681 */ { MAD_F(0x048be42f) /* 0.284153161 */, 17 }, /* 2682 */ { MAD_F(0x048c7860) /* 0.284294487 */, 17 }, /* 2683 */ { MAD_F(0x048d0c96) /* 0.284435831 */, 17 }, /* 2684 */ { MAD_F(0x048da0d0) /* 0.284577192 */, 17 }, /* 2685 */ { MAD_F(0x048e350f) /* 0.284718570 */, 17 }, /* 2686 */ { MAD_F(0x048ec953) /* 0.284859966 */, 17 }, /* 2687 */ { MAD_F(0x048f5d9b) /* 0.285001380 */, 17 }, /* 2688 */ { MAD_F(0x048ff1e8) /* 0.285142811 */, 17 }, /* 2689 */ { MAD_F(0x0490863a) /* 0.285284259 */, 17 }, /* 2690 */ { MAD_F(0x04911a91) /* 0.285425726 */, 17 }, /* 2691 */ { MAD_F(0x0491aeec) /* 0.285567209 */, 17 }, /* 2692 */ { MAD_F(0x0492434c) /* 0.285708711 */, 17 }, /* 2693 */ { MAD_F(0x0492d7b0) /* 0.285850229 */, 17 }, /* 2694 */ { MAD_F(0x04936c1a) /* 0.285991766 */, 17 }, /* 2695 */ { MAD_F(0x04940088) /* 0.286133319 */, 17 }, /* 2696 */ { MAD_F(0x049494fb) /* 0.286274891 */, 17 }, /* 2697 */ { MAD_F(0x04952972) /* 0.286416480 */, 17 }, /* 2698 */ { MAD_F(0x0495bdee) /* 0.286558086 */, 17 }, /* 2699 */ { MAD_F(0x0496526f) /* 0.286699710 */, 17 }, /* 2700 */ { MAD_F(0x0496e6f5) /* 0.286841351 */, 17 }, /* 2701 */ { MAD_F(0x04977b7f) /* 0.286983010 */, 17 }, /* 2702 */ { MAD_F(0x0498100e) /* 0.287124686 */, 17 }, /* 2703 */ { MAD_F(0x0498a4a1) /* 0.287266380 */, 17 }, /* 2704 */ { MAD_F(0x0499393a) /* 0.287408091 */, 17 }, /* 2705 */ { MAD_F(0x0499cdd7) /* 0.287549820 */, 17 }, /* 2706 */ { MAD_F(0x049a6278) /* 0.287691566 */, 17 }, /* 2707 */ { MAD_F(0x049af71f) /* 0.287833330 */, 17 }, /* 2708 */ { MAD_F(0x049b8bca) /* 0.287975111 */, 17 }, /* 2709 */ { MAD_F(0x049c207a) /* 0.288116909 */, 17 }, /* 2710 */ { MAD_F(0x049cb52e) /* 0.288258725 */, 17 }, /* 2711 */ { MAD_F(0x049d49e7) /* 0.288400559 */, 17 }, /* 2712 */ { MAD_F(0x049ddea5) /* 0.288542409 */, 17 }, /* 2713 */ { MAD_F(0x049e7367) /* 0.288684278 */, 17 }, /* 2714 */ { MAD_F(0x049f082f) /* 0.288826163 */, 17 }, /* 2715 */ { MAD_F(0x049f9cfa) /* 0.288968067 */, 17 }, /* 2716 */ { MAD_F(0x04a031cb) /* 0.289109987 */, 17 }, /* 2717 */ { MAD_F(0x04a0c6a0) /* 0.289251925 */, 17 }, /* 2718 */ { MAD_F(0x04a15b7a) /* 0.289393881 */, 17 }, /* 2719 */ { MAD_F(0x04a1f059) /* 0.289535854 */, 17 }, /* 2720 */ { MAD_F(0x04a2853c) /* 0.289677844 */, 17 }, /* 2721 */ { MAD_F(0x04a31a24) /* 0.289819851 */, 17 }, /* 2722 */ { MAD_F(0x04a3af10) /* 0.289961876 */, 17 }, /* 2723 */ { MAD_F(0x04a44401) /* 0.290103919 */, 17 }, /* 2724 */ { MAD_F(0x04a4d8f7) /* 0.290245979 */, 17 }, /* 2725 */ { MAD_F(0x04a56df2) /* 0.290388056 */, 17 }, /* 2726 */ { MAD_F(0x04a602f1) /* 0.290530150 */, 17 }, /* 2727 */ { MAD_F(0x04a697f5) /* 0.290672262 */, 17 }, /* 2728 */ { MAD_F(0x04a72cfe) /* 0.290814392 */, 17 }, /* 2729 */ { MAD_F(0x04a7c20b) /* 0.290956538 */, 17 }, /* 2730 */ { MAD_F(0x04a8571d) /* 0.291098703 */, 17 }, /* 2731 */ { MAD_F(0x04a8ec33) /* 0.291240884 */, 17 }, /* 2732 */ { MAD_F(0x04a9814e) /* 0.291383083 */, 17 }, /* 2733 */ { MAD_F(0x04aa166e) /* 0.291525299 */, 17 }, /* 2734 */ { MAD_F(0x04aaab93) /* 0.291667532 */, 17 }, /* 2735 */ { MAD_F(0x04ab40bc) /* 0.291809783 */, 17 }, /* 2736 */ { MAD_F(0x04abd5ea) /* 0.291952051 */, 17 }, /* 2737 */ { MAD_F(0x04ac6b1c) /* 0.292094337 */, 17 }, /* 2738 */ { MAD_F(0x04ad0053) /* 0.292236640 */, 17 }, /* 2739 */ { MAD_F(0x04ad958f) /* 0.292378960 */, 17 }, /* 2740 */ { MAD_F(0x04ae2ad0) /* 0.292521297 */, 17 }, /* 2741 */ { MAD_F(0x04aec015) /* 0.292663652 */, 17 }, /* 2742 */ { MAD_F(0x04af555e) /* 0.292806024 */, 17 }, /* 2743 */ { MAD_F(0x04afeaad) /* 0.292948414 */, 17 }, /* 2744 */ { MAD_F(0x04b08000) /* 0.293090820 */, 17 }, /* 2745 */ { MAD_F(0x04b11557) /* 0.293233244 */, 17 }, /* 2746 */ { MAD_F(0x04b1aab4) /* 0.293375686 */, 17 }, /* 2747 */ { MAD_F(0x04b24015) /* 0.293518144 */, 17 }, /* 2748 */ { MAD_F(0x04b2d57a) /* 0.293660620 */, 17 }, /* 2749 */ { MAD_F(0x04b36ae4) /* 0.293803113 */, 17 }, /* 2750 */ { MAD_F(0x04b40053) /* 0.293945624 */, 17 }, /* 2751 */ { MAD_F(0x04b495c7) /* 0.294088151 */, 17 }, /* 2752 */ { MAD_F(0x04b52b3f) /* 0.294230696 */, 17 }, /* 2753 */ { MAD_F(0x04b5c0bc) /* 0.294373259 */, 17 }, /* 2754 */ { MAD_F(0x04b6563d) /* 0.294515838 */, 17 }, /* 2755 */ { MAD_F(0x04b6ebc3) /* 0.294658435 */, 17 }, /* 2756 */ { MAD_F(0x04b7814e) /* 0.294801049 */, 17 }, /* 2757 */ { MAD_F(0x04b816dd) /* 0.294943680 */, 17 }, /* 2758 */ { MAD_F(0x04b8ac71) /* 0.295086329 */, 17 }, /* 2759 */ { MAD_F(0x04b9420a) /* 0.295228995 */, 17 }, /* 2760 */ { MAD_F(0x04b9d7a7) /* 0.295371678 */, 17 }, /* 2761 */ { MAD_F(0x04ba6d49) /* 0.295514378 */, 17 }, /* 2762 */ { MAD_F(0x04bb02ef) /* 0.295657095 */, 17 }, /* 2763 */ { MAD_F(0x04bb989a) /* 0.295799830 */, 17 }, /* 2764 */ { MAD_F(0x04bc2e4a) /* 0.295942582 */, 17 }, /* 2765 */ { MAD_F(0x04bcc3fe) /* 0.296085351 */, 17 }, /* 2766 */ { MAD_F(0x04bd59b7) /* 0.296228138 */, 17 }, /* 2767 */ { MAD_F(0x04bdef74) /* 0.296370941 */, 17 }, /* 2768 */ { MAD_F(0x04be8537) /* 0.296513762 */, 17 }, /* 2769 */ { MAD_F(0x04bf1afd) /* 0.296656600 */, 17 }, /* 2770 */ { MAD_F(0x04bfb0c9) /* 0.296799455 */, 17 }, /* 2771 */ { MAD_F(0x04c04699) /* 0.296942327 */, 17 }, /* 2772 */ { MAD_F(0x04c0dc6d) /* 0.297085217 */, 17 }, /* 2773 */ { MAD_F(0x04c17247) /* 0.297228124 */, 17 }, /* 2774 */ { MAD_F(0x04c20824) /* 0.297371048 */, 17 }, /* 2775 */ { MAD_F(0x04c29e07) /* 0.297513989 */, 17 }, /* 2776 */ { MAD_F(0x04c333ee) /* 0.297656947 */, 17 }, /* 2777 */ { MAD_F(0x04c3c9da) /* 0.297799922 */, 17 }, /* 2778 */ { MAD_F(0x04c45fca) /* 0.297942915 */, 17 }, /* 2779 */ { MAD_F(0x04c4f5bf) /* 0.298085925 */, 17 }, /* 2780 */ { MAD_F(0x04c58bb8) /* 0.298228951 */, 17 }, /* 2781 */ { MAD_F(0x04c621b6) /* 0.298371996 */, 17 }, /* 2782 */ { MAD_F(0x04c6b7b9) /* 0.298515057 */, 17 }, /* 2783 */ { MAD_F(0x04c74dc0) /* 0.298658135 */, 17 }, /* 2784 */ { MAD_F(0x04c7e3cc) /* 0.298801231 */, 17 }, /* 2785 */ { MAD_F(0x04c879dd) /* 0.298944343 */, 17 }, /* 2786 */ { MAD_F(0x04c90ff2) /* 0.299087473 */, 17 }, /* 2787 */ { MAD_F(0x04c9a60c) /* 0.299230620 */, 17 }, /* 2788 */ { MAD_F(0x04ca3c2a) /* 0.299373784 */, 17 }, /* 2789 */ { MAD_F(0x04cad24d) /* 0.299516965 */, 17 }, /* 2790 */ { MAD_F(0x04cb6874) /* 0.299660163 */, 17 }, /* 2791 */ { MAD_F(0x04cbfea0) /* 0.299803378 */, 17 }, /* 2792 */ { MAD_F(0x04cc94d1) /* 0.299946611 */, 17 }, /* 2793 */ { MAD_F(0x04cd2b06) /* 0.300089860 */, 17 }, /* 2794 */ { MAD_F(0x04cdc140) /* 0.300233127 */, 17 }, /* 2795 */ { MAD_F(0x04ce577f) /* 0.300376411 */, 17 }, /* 2796 */ { MAD_F(0x04ceedc2) /* 0.300519711 */, 17 }, /* 2797 */ { MAD_F(0x04cf8409) /* 0.300663029 */, 17 }, /* 2798 */ { MAD_F(0x04d01a55) /* 0.300806364 */, 17 }, /* 2799 */ { MAD_F(0x04d0b0a6) /* 0.300949716 */, 17 }, /* 2800 */ { MAD_F(0x04d146fb) /* 0.301093085 */, 17 }, /* 2801 */ { MAD_F(0x04d1dd55) /* 0.301236472 */, 17 }, /* 2802 */ { MAD_F(0x04d273b4) /* 0.301379875 */, 17 }, /* 2803 */ { MAD_F(0x04d30a17) /* 0.301523295 */, 17 }, /* 2804 */ { MAD_F(0x04d3a07f) /* 0.301666733 */, 17 }, /* 2805 */ { MAD_F(0x04d436eb) /* 0.301810187 */, 17 }, /* 2806 */ { MAD_F(0x04d4cd5c) /* 0.301953659 */, 17 }, /* 2807 */ { MAD_F(0x04d563d1) /* 0.302097147 */, 17 }, /* 2808 */ { MAD_F(0x04d5fa4b) /* 0.302240653 */, 17 }, /* 2809 */ { MAD_F(0x04d690ca) /* 0.302384175 */, 17 }, /* 2810 */ { MAD_F(0x04d7274d) /* 0.302527715 */, 17 }, /* 2811 */ { MAD_F(0x04d7bdd5) /* 0.302671271 */, 17 }, /* 2812 */ { MAD_F(0x04d85461) /* 0.302814845 */, 17 }, /* 2813 */ { MAD_F(0x04d8eaf2) /* 0.302958436 */, 17 }, /* 2814 */ { MAD_F(0x04d98187) /* 0.303102044 */, 17 }, /* 2815 */ { MAD_F(0x04da1821) /* 0.303245668 */, 17 }, /* 2816 */ { MAD_F(0x04daaec0) /* 0.303389310 */, 17 }, /* 2817 */ { MAD_F(0x04db4563) /* 0.303532969 */, 17 }, /* 2818 */ { MAD_F(0x04dbdc0a) /* 0.303676645 */, 17 }, /* 2819 */ { MAD_F(0x04dc72b7) /* 0.303820337 */, 17 }, /* 2820 */ { MAD_F(0x04dd0967) /* 0.303964047 */, 17 }, /* 2821 */ { MAD_F(0x04dda01d) /* 0.304107774 */, 17 }, /* 2822 */ { MAD_F(0x04de36d7) /* 0.304251517 */, 17 }, /* 2823 */ { MAD_F(0x04decd95) /* 0.304395278 */, 17 }, /* 2824 */ { MAD_F(0x04df6458) /* 0.304539056 */, 17 }, /* 2825 */ { MAD_F(0x04dffb20) /* 0.304682850 */, 17 }, /* 2826 */ { MAD_F(0x04e091ec) /* 0.304826662 */, 17 }, /* 2827 */ { MAD_F(0x04e128bc) /* 0.304970491 */, 17 }, /* 2828 */ { MAD_F(0x04e1bf92) /* 0.305114336 */, 17 }, /* 2829 */ { MAD_F(0x04e2566b) /* 0.305258199 */, 17 }, /* 2830 */ { MAD_F(0x04e2ed4a) /* 0.305402078 */, 17 }, /* 2831 */ { MAD_F(0x04e3842d) /* 0.305545974 */, 17 }, /* 2832 */ { MAD_F(0x04e41b14) /* 0.305689888 */, 17 }, /* 2833 */ { MAD_F(0x04e4b200) /* 0.305833818 */, 17 }, /* 2834 */ { MAD_F(0x04e548f1) /* 0.305977765 */, 17 }, /* 2835 */ { MAD_F(0x04e5dfe6) /* 0.306121729 */, 17 }, /* 2836 */ { MAD_F(0x04e676df) /* 0.306265710 */, 17 }, /* 2837 */ { MAD_F(0x04e70dde) /* 0.306409708 */, 17 }, /* 2838 */ { MAD_F(0x04e7a4e0) /* 0.306553723 */, 17 }, /* 2839 */ { MAD_F(0x04e83be7) /* 0.306697755 */, 17 }, /* 2840 */ { MAD_F(0x04e8d2f3) /* 0.306841804 */, 17 }, /* 2841 */ { MAD_F(0x04e96a04) /* 0.306985869 */, 17 }, /* 2842 */ { MAD_F(0x04ea0118) /* 0.307129952 */, 17 }, /* 2843 */ { MAD_F(0x04ea9832) /* 0.307274051 */, 17 }, /* 2844 */ { MAD_F(0x04eb2f50) /* 0.307418168 */, 17 }, /* 2845 */ { MAD_F(0x04ebc672) /* 0.307562301 */, 17 }, /* 2846 */ { MAD_F(0x04ec5d99) /* 0.307706451 */, 17 }, /* 2847 */ { MAD_F(0x04ecf4c5) /* 0.307850618 */, 17 }, /* 2848 */ { MAD_F(0x04ed8bf5) /* 0.307994802 */, 17 }, /* 2849 */ { MAD_F(0x04ee2329) /* 0.308139003 */, 17 }, /* 2850 */ { MAD_F(0x04eeba63) /* 0.308283220 */, 17 }, /* 2851 */ { MAD_F(0x04ef51a0) /* 0.308427455 */, 17 }, /* 2852 */ { MAD_F(0x04efe8e2) /* 0.308571706 */, 17 }, /* 2853 */ { MAD_F(0x04f08029) /* 0.308715974 */, 17 }, /* 2854 */ { MAD_F(0x04f11774) /* 0.308860260 */, 17 }, /* 2855 */ { MAD_F(0x04f1aec4) /* 0.309004561 */, 17 }, /* 2856 */ { MAD_F(0x04f24618) /* 0.309148880 */, 17 }, /* 2857 */ { MAD_F(0x04f2dd71) /* 0.309293216 */, 17 }, /* 2858 */ { MAD_F(0x04f374cf) /* 0.309437568 */, 17 }, /* 2859 */ { MAD_F(0x04f40c30) /* 0.309581938 */, 17 }, /* 2860 */ { MAD_F(0x04f4a397) /* 0.309726324 */, 17 }, /* 2861 */ { MAD_F(0x04f53b02) /* 0.309870727 */, 17 }, /* 2862 */ { MAD_F(0x04f5d271) /* 0.310015147 */, 17 }, /* 2863 */ { MAD_F(0x04f669e5) /* 0.310159583 */, 17 }, /* 2864 */ { MAD_F(0x04f7015d) /* 0.310304037 */, 17 }, /* 2865 */ { MAD_F(0x04f798da) /* 0.310448507 */, 17 }, /* 2866 */ { MAD_F(0x04f8305c) /* 0.310592994 */, 17 }, /* 2867 */ { MAD_F(0x04f8c7e2) /* 0.310737498 */, 17 }, /* 2868 */ { MAD_F(0x04f95f6c) /* 0.310882018 */, 17 }, /* 2869 */ { MAD_F(0x04f9f6fb) /* 0.311026556 */, 17 }, /* 2870 */ { MAD_F(0x04fa8e8f) /* 0.311171110 */, 17 }, /* 2871 */ { MAD_F(0x04fb2627) /* 0.311315681 */, 17 }, /* 2872 */ { MAD_F(0x04fbbdc3) /* 0.311460269 */, 17 }, /* 2873 */ { MAD_F(0x04fc5564) /* 0.311604874 */, 17 }, /* 2874 */ { MAD_F(0x04fced0a) /* 0.311749495 */, 17 }, /* 2875 */ { MAD_F(0x04fd84b4) /* 0.311894133 */, 17 }, /* 2876 */ { MAD_F(0x04fe1c62) /* 0.312038788 */, 17 }, /* 2877 */ { MAD_F(0x04feb415) /* 0.312183460 */, 17 }, /* 2878 */ { MAD_F(0x04ff4bcd) /* 0.312328148 */, 17 }, /* 2879 */ { MAD_F(0x04ffe389) /* 0.312472854 */, 17 }, /* 2880 */ { MAD_F(0x05007b49) /* 0.312617576 */, 17 }, /* 2881 */ { MAD_F(0x0501130e) /* 0.312762314 */, 17 }, /* 2882 */ { MAD_F(0x0501aad8) /* 0.312907070 */, 17 }, /* 2883 */ { MAD_F(0x050242a6) /* 0.313051842 */, 17 }, /* 2884 */ { MAD_F(0x0502da78) /* 0.313196631 */, 17 }, /* 2885 */ { MAD_F(0x0503724f) /* 0.313341437 */, 17 }, /* 2886 */ { MAD_F(0x05040a2b) /* 0.313486259 */, 17 }, /* 2887 */ { MAD_F(0x0504a20b) /* 0.313631098 */, 17 }, /* 2888 */ { MAD_F(0x050539ef) /* 0.313775954 */, 17 }, /* 2889 */ { MAD_F(0x0505d1d8) /* 0.313920827 */, 17 }, /* 2890 */ { MAD_F(0x050669c5) /* 0.314065716 */, 17 }, /* 2891 */ { MAD_F(0x050701b7) /* 0.314210622 */, 17 }, /* 2892 */ { MAD_F(0x050799ae) /* 0.314355545 */, 17 }, /* 2893 */ { MAD_F(0x050831a9) /* 0.314500484 */, 17 }, /* 2894 */ { MAD_F(0x0508c9a8) /* 0.314645440 */, 17 }, /* 2895 */ { MAD_F(0x050961ac) /* 0.314790413 */, 17 }, /* 2896 */ { MAD_F(0x0509f9b4) /* 0.314935403 */, 17 }, /* 2897 */ { MAD_F(0x050a91c1) /* 0.315080409 */, 17 }, /* 2898 */ { MAD_F(0x050b29d2) /* 0.315225432 */, 17 }, /* 2899 */ { MAD_F(0x050bc1e8) /* 0.315370472 */, 17 }, /* 2900 */ { MAD_F(0x050c5a02) /* 0.315515528 */, 17 }, /* 2901 */ { MAD_F(0x050cf221) /* 0.315660601 */, 17 }, /* 2902 */ { MAD_F(0x050d8a44) /* 0.315805690 */, 17 }, /* 2903 */ { MAD_F(0x050e226c) /* 0.315950797 */, 17 }, /* 2904 */ { MAD_F(0x050eba98) /* 0.316095920 */, 17 }, /* 2905 */ { MAD_F(0x050f52c9) /* 0.316241059 */, 17 }, /* 2906 */ { MAD_F(0x050feafe) /* 0.316386216 */, 17 }, /* 2907 */ { MAD_F(0x05108337) /* 0.316531388 */, 17 }, /* 2908 */ { MAD_F(0x05111b75) /* 0.316676578 */, 17 }, /* 2909 */ { MAD_F(0x0511b3b8) /* 0.316821784 */, 17 }, /* 2910 */ { MAD_F(0x05124bff) /* 0.316967007 */, 17 }, /* 2911 */ { MAD_F(0x0512e44a) /* 0.317112247 */, 17 }, /* 2912 */ { MAD_F(0x05137c9a) /* 0.317257503 */, 17 }, /* 2913 */ { MAD_F(0x051414ee) /* 0.317402775 */, 17 }, /* 2914 */ { MAD_F(0x0514ad47) /* 0.317548065 */, 17 }, /* 2915 */ { MAD_F(0x051545a5) /* 0.317693371 */, 17 }, /* 2916 */ { MAD_F(0x0515de06) /* 0.317838693 */, 17 }, /* 2917 */ { MAD_F(0x0516766d) /* 0.317984033 */, 17 }, /* 2918 */ { MAD_F(0x05170ed7) /* 0.318129388 */, 17 }, /* 2919 */ { MAD_F(0x0517a746) /* 0.318274761 */, 17 }, /* 2920 */ { MAD_F(0x05183fba) /* 0.318420150 */, 17 }, /* 2921 */ { MAD_F(0x0518d832) /* 0.318565555 */, 17 }, /* 2922 */ { MAD_F(0x051970ae) /* 0.318710978 */, 17 }, /* 2923 */ { MAD_F(0x051a092f) /* 0.318856416 */, 17 }, /* 2924 */ { MAD_F(0x051aa1b5) /* 0.319001872 */, 17 }, /* 2925 */ { MAD_F(0x051b3a3f) /* 0.319147344 */, 17 }, /* 2926 */ { MAD_F(0x051bd2cd) /* 0.319292832 */, 17 }, /* 2927 */ { MAD_F(0x051c6b60) /* 0.319438338 */, 17 }, /* 2928 */ { MAD_F(0x051d03f7) /* 0.319583859 */, 17 }, /* 2929 */ { MAD_F(0x051d9c92) /* 0.319729398 */, 17 }, /* 2930 */ { MAD_F(0x051e3532) /* 0.319874952 */, 17 }, /* 2931 */ { MAD_F(0x051ecdd7) /* 0.320020524 */, 17 }, /* 2932 */ { MAD_F(0x051f6680) /* 0.320166112 */, 17 }, /* 2933 */ { MAD_F(0x051fff2d) /* 0.320311716 */, 17 }, /* 2934 */ { MAD_F(0x052097df) /* 0.320457337 */, 17 }, /* 2935 */ { MAD_F(0x05213095) /* 0.320602975 */, 17 }, /* 2936 */ { MAD_F(0x0521c950) /* 0.320748629 */, 17 }, /* 2937 */ { MAD_F(0x0522620f) /* 0.320894300 */, 17 }, /* 2938 */ { MAD_F(0x0522fad3) /* 0.321039987 */, 17 }, /* 2939 */ { MAD_F(0x0523939b) /* 0.321185691 */, 17 }, /* 2940 */ { MAD_F(0x05242c68) /* 0.321331411 */, 17 }, /* 2941 */ { MAD_F(0x0524c538) /* 0.321477148 */, 17 }, /* 2942 */ { MAD_F(0x05255e0e) /* 0.321622901 */, 17 }, /* 2943 */ { MAD_F(0x0525f6e8) /* 0.321768671 */, 17 }, /* 2944 */ { MAD_F(0x05268fc6) /* 0.321914457 */, 17 }, /* 2945 */ { MAD_F(0x052728a9) /* 0.322060260 */, 17 }, /* 2946 */ { MAD_F(0x0527c190) /* 0.322206079 */, 17 }, /* 2947 */ { MAD_F(0x05285a7b) /* 0.322351915 */, 17 }, /* 2948 */ { MAD_F(0x0528f36b) /* 0.322497768 */, 17 }, /* 2949 */ { MAD_F(0x05298c5f) /* 0.322643636 */, 17 }, /* 2950 */ { MAD_F(0x052a2558) /* 0.322789522 */, 17 }, /* 2951 */ { MAD_F(0x052abe55) /* 0.322935424 */, 17 }, /* 2952 */ { MAD_F(0x052b5757) /* 0.323081342 */, 17 }, /* 2953 */ { MAD_F(0x052bf05d) /* 0.323227277 */, 17 }, /* 2954 */ { MAD_F(0x052c8968) /* 0.323373228 */, 17 }, /* 2955 */ { MAD_F(0x052d2277) /* 0.323519196 */, 17 }, /* 2956 */ { MAD_F(0x052dbb8a) /* 0.323665180 */, 17 }, /* 2957 */ { MAD_F(0x052e54a2) /* 0.323811180 */, 17 }, /* 2958 */ { MAD_F(0x052eedbe) /* 0.323957197 */, 17 }, /* 2959 */ { MAD_F(0x052f86de) /* 0.324103231 */, 17 }, /* 2960 */ { MAD_F(0x05302003) /* 0.324249281 */, 17 }, /* 2961 */ { MAD_F(0x0530b92d) /* 0.324395347 */, 17 }, /* 2962 */ { MAD_F(0x0531525b) /* 0.324541430 */, 17 }, /* 2963 */ { MAD_F(0x0531eb8d) /* 0.324687530 */, 17 }, /* 2964 */ { MAD_F(0x053284c4) /* 0.324833646 */, 17 }, /* 2965 */ { MAD_F(0x05331dff) /* 0.324979778 */, 17 }, /* 2966 */ { MAD_F(0x0533b73e) /* 0.325125926 */, 17 }, /* 2967 */ { MAD_F(0x05345082) /* 0.325272091 */, 17 }, /* 2968 */ { MAD_F(0x0534e9ca) /* 0.325418273 */, 17 }, /* 2969 */ { MAD_F(0x05358317) /* 0.325564471 */, 17 }, /* 2970 */ { MAD_F(0x05361c68) /* 0.325710685 */, 17 }, /* 2971 */ { MAD_F(0x0536b5be) /* 0.325856916 */, 17 }, /* 2972 */ { MAD_F(0x05374f17) /* 0.326003163 */, 17 }, /* 2973 */ { MAD_F(0x0537e876) /* 0.326149427 */, 17 }, /* 2974 */ { MAD_F(0x053881d9) /* 0.326295707 */, 17 }, /* 2975 */ { MAD_F(0x05391b40) /* 0.326442003 */, 17 }, /* 2976 */ { MAD_F(0x0539b4ab) /* 0.326588316 */, 17 }, /* 2977 */ { MAD_F(0x053a4e1b) /* 0.326734645 */, 17 }, /* 2978 */ { MAD_F(0x053ae78f) /* 0.326880990 */, 17 }, /* 2979 */ { MAD_F(0x053b8108) /* 0.327027352 */, 17 }, /* 2980 */ { MAD_F(0x053c1a85) /* 0.327173730 */, 17 }, /* 2981 */ { MAD_F(0x053cb407) /* 0.327320125 */, 17 }, /* 2982 */ { MAD_F(0x053d4d8d) /* 0.327466536 */, 17 }, /* 2983 */ { MAD_F(0x053de717) /* 0.327612963 */, 17 }, /* 2984 */ { MAD_F(0x053e80a6) /* 0.327759407 */, 17 }, /* 2985 */ { MAD_F(0x053f1a39) /* 0.327905867 */, 17 }, /* 2986 */ { MAD_F(0x053fb3d0) /* 0.328052344 */, 17 }, /* 2987 */ { MAD_F(0x05404d6c) /* 0.328198837 */, 17 }, /* 2988 */ { MAD_F(0x0540e70c) /* 0.328345346 */, 17 }, /* 2989 */ { MAD_F(0x054180b1) /* 0.328491871 */, 17 }, /* 2990 */ { MAD_F(0x05421a5a) /* 0.328638413 */, 17 }, /* 2991 */ { MAD_F(0x0542b407) /* 0.328784971 */, 17 }, /* 2992 */ { MAD_F(0x05434db9) /* 0.328931546 */, 17 }, /* 2993 */ { MAD_F(0x0543e76f) /* 0.329078137 */, 17 }, /* 2994 */ { MAD_F(0x0544812a) /* 0.329224744 */, 17 }, /* 2995 */ { MAD_F(0x05451ae9) /* 0.329371367 */, 17 }, /* 2996 */ { MAD_F(0x0545b4ac) /* 0.329518007 */, 17 }, /* 2997 */ { MAD_F(0x05464e74) /* 0.329664663 */, 17 }, /* 2998 */ { MAD_F(0x0546e840) /* 0.329811336 */, 17 }, /* 2999 */ { MAD_F(0x05478211) /* 0.329958024 */, 17 }, /* 3000 */ { MAD_F(0x05481be5) /* 0.330104730 */, 17 }, /* 3001 */ { MAD_F(0x0548b5bf) /* 0.330251451 */, 17 }, /* 3002 */ { MAD_F(0x05494f9c) /* 0.330398189 */, 17 }, /* 3003 */ { MAD_F(0x0549e97e) /* 0.330544943 */, 17 }, /* 3004 */ { MAD_F(0x054a8364) /* 0.330691713 */, 17 }, /* 3005 */ { MAD_F(0x054b1d4f) /* 0.330838499 */, 17 }, /* 3006 */ { MAD_F(0x054bb73e) /* 0.330985302 */, 17 }, /* 3007 */ { MAD_F(0x054c5132) /* 0.331132121 */, 17 }, /* 3008 */ { MAD_F(0x054ceb2a) /* 0.331278957 */, 17 }, /* 3009 */ { MAD_F(0x054d8526) /* 0.331425808 */, 17 }, /* 3010 */ { MAD_F(0x054e1f26) /* 0.331572676 */, 17 }, /* 3011 */ { MAD_F(0x054eb92b) /* 0.331719560 */, 17 }, /* 3012 */ { MAD_F(0x054f5334) /* 0.331866461 */, 17 }, /* 3013 */ { MAD_F(0x054fed42) /* 0.332013377 */, 17 }, /* 3014 */ { MAD_F(0x05508754) /* 0.332160310 */, 17 }, /* 3015 */ { MAD_F(0x0551216b) /* 0.332307260 */, 17 }, /* 3016 */ { MAD_F(0x0551bb85) /* 0.332454225 */, 17 }, /* 3017 */ { MAD_F(0x055255a4) /* 0.332601207 */, 17 }, /* 3018 */ { MAD_F(0x0552efc8) /* 0.332748205 */, 17 }, /* 3019 */ { MAD_F(0x055389f0) /* 0.332895219 */, 17 }, /* 3020 */ { MAD_F(0x0554241c) /* 0.333042249 */, 17 }, /* 3021 */ { MAD_F(0x0554be4c) /* 0.333189296 */, 17 }, /* 3022 */ { MAD_F(0x05555881) /* 0.333336359 */, 17 }, /* 3023 */ { MAD_F(0x0555f2ba) /* 0.333483438 */, 17 }, /* 3024 */ { MAD_F(0x05568cf8) /* 0.333630533 */, 17 }, /* 3025 */ { MAD_F(0x0557273a) /* 0.333777645 */, 17 }, /* 3026 */ { MAD_F(0x0557c180) /* 0.333924772 */, 17 }, /* 3027 */ { MAD_F(0x05585bcb) /* 0.334071916 */, 17 }, /* 3028 */ { MAD_F(0x0558f61a) /* 0.334219076 */, 17 }, /* 3029 */ { MAD_F(0x0559906d) /* 0.334366253 */, 17 }, /* 3030 */ { MAD_F(0x055a2ac5) /* 0.334513445 */, 17 }, /* 3031 */ { MAD_F(0x055ac521) /* 0.334660654 */, 17 }, /* 3032 */ { MAD_F(0x055b5f81) /* 0.334807879 */, 17 }, /* 3033 */ { MAD_F(0x055bf9e6) /* 0.334955120 */, 17 }, /* 3034 */ { MAD_F(0x055c944f) /* 0.335102377 */, 17 }, /* 3035 */ { MAD_F(0x055d2ebd) /* 0.335249651 */, 17 }, /* 3036 */ { MAD_F(0x055dc92e) /* 0.335396941 */, 17 }, /* 3037 */ { MAD_F(0x055e63a5) /* 0.335544246 */, 17 }, /* 3038 */ { MAD_F(0x055efe1f) /* 0.335691568 */, 17 }, /* 3039 */ { MAD_F(0x055f989e) /* 0.335838906 */, 17 }, /* 3040 */ { MAD_F(0x05603321) /* 0.335986261 */, 17 }, /* 3041 */ { MAD_F(0x0560cda8) /* 0.336133631 */, 17 }, /* 3042 */ { MAD_F(0x05616834) /* 0.336281018 */, 17 }, /* 3043 */ { MAD_F(0x056202c4) /* 0.336428421 */, 17 }, /* 3044 */ { MAD_F(0x05629d59) /* 0.336575840 */, 17 }, /* 3045 */ { MAD_F(0x056337f2) /* 0.336723275 */, 17 }, /* 3046 */ { MAD_F(0x0563d28f) /* 0.336870726 */, 17 }, /* 3047 */ { MAD_F(0x05646d30) /* 0.337018193 */, 17 }, /* 3048 */ { MAD_F(0x056507d6) /* 0.337165677 */, 17 }, /* 3049 */ { MAD_F(0x0565a280) /* 0.337313176 */, 17 }, /* 3050 */ { MAD_F(0x05663d2f) /* 0.337460692 */, 17 }, /* 3051 */ { MAD_F(0x0566d7e1) /* 0.337608224 */, 17 }, /* 3052 */ { MAD_F(0x05677298) /* 0.337755772 */, 17 }, /* 3053 */ { MAD_F(0x05680d54) /* 0.337903336 */, 17 }, /* 3054 */ { MAD_F(0x0568a814) /* 0.338050916 */, 17 }, /* 3055 */ { MAD_F(0x056942d8) /* 0.338198513 */, 17 }, /* 3056 */ { MAD_F(0x0569dda0) /* 0.338346125 */, 17 }, /* 3057 */ { MAD_F(0x056a786d) /* 0.338493753 */, 17 }, /* 3058 */ { MAD_F(0x056b133e) /* 0.338641398 */, 17 }, /* 3059 */ { MAD_F(0x056bae13) /* 0.338789059 */, 17 }, /* 3060 */ { MAD_F(0x056c48ed) /* 0.338936736 */, 17 }, /* 3061 */ { MAD_F(0x056ce3cb) /* 0.339084429 */, 17 }, /* 3062 */ { MAD_F(0x056d7ead) /* 0.339232138 */, 17 }, /* 3063 */ { MAD_F(0x056e1994) /* 0.339379863 */, 17 }, /* 3064 */ { MAD_F(0x056eb47f) /* 0.339527604 */, 17 }, /* 3065 */ { MAD_F(0x056f4f6e) /* 0.339675361 */, 17 }, /* 3066 */ { MAD_F(0x056fea62) /* 0.339823134 */, 17 }, /* 3067 */ { MAD_F(0x0570855a) /* 0.339970924 */, 17 }, /* 3068 */ { MAD_F(0x05712056) /* 0.340118729 */, 17 }, /* 3069 */ { MAD_F(0x0571bb56) /* 0.340266550 */, 17 }, /* 3070 */ { MAD_F(0x0572565b) /* 0.340414388 */, 17 }, /* 3071 */ { MAD_F(0x0572f164) /* 0.340562242 */, 17 }, /* 3072 */ { MAD_F(0x05738c72) /* 0.340710111 */, 17 }, /* 3073 */ { MAD_F(0x05742784) /* 0.340857997 */, 17 }, /* 3074 */ { MAD_F(0x0574c29a) /* 0.341005899 */, 17 }, /* 3075 */ { MAD_F(0x05755db4) /* 0.341153816 */, 17 }, /* 3076 */ { MAD_F(0x0575f8d3) /* 0.341301750 */, 17 }, /* 3077 */ { MAD_F(0x057693f6) /* 0.341449700 */, 17 }, /* 3078 */ { MAD_F(0x05772f1d) /* 0.341597666 */, 17 }, /* 3079 */ { MAD_F(0x0577ca49) /* 0.341745648 */, 17 }, /* 3080 */ { MAD_F(0x05786578) /* 0.341893646 */, 17 }, /* 3081 */ { MAD_F(0x057900ad) /* 0.342041659 */, 17 }, /* 3082 */ { MAD_F(0x05799be5) /* 0.342189689 */, 17 }, /* 3083 */ { MAD_F(0x057a3722) /* 0.342337735 */, 17 }, /* 3084 */ { MAD_F(0x057ad263) /* 0.342485797 */, 17 }, /* 3085 */ { MAD_F(0x057b6da8) /* 0.342633875 */, 17 }, /* 3086 */ { MAD_F(0x057c08f2) /* 0.342781969 */, 17 }, /* 3087 */ { MAD_F(0x057ca440) /* 0.342930079 */, 17 }, /* 3088 */ { MAD_F(0x057d3f92) /* 0.343078205 */, 17 }, /* 3089 */ { MAD_F(0x057ddae9) /* 0.343226347 */, 17 }, /* 3090 */ { MAD_F(0x057e7644) /* 0.343374505 */, 17 }, /* 3091 */ { MAD_F(0x057f11a3) /* 0.343522679 */, 17 }, /* 3092 */ { MAD_F(0x057fad06) /* 0.343670869 */, 17 }, /* 3093 */ { MAD_F(0x0580486e) /* 0.343819075 */, 17 }, /* 3094 */ { MAD_F(0x0580e3da) /* 0.343967296 */, 17 }, /* 3095 */ { MAD_F(0x05817f4a) /* 0.344115534 */, 17 }, /* 3096 */ { MAD_F(0x05821abf) /* 0.344263788 */, 17 }, /* 3097 */ { MAD_F(0x0582b638) /* 0.344412058 */, 17 }, /* 3098 */ { MAD_F(0x058351b5) /* 0.344560343 */, 17 }, /* 3099 */ { MAD_F(0x0583ed36) /* 0.344708645 */, 17 }, /* 3100 */ { MAD_F(0x058488bc) /* 0.344856963 */, 17 }, /* 3101 */ { MAD_F(0x05852446) /* 0.345005296 */, 17 }, /* 3102 */ { MAD_F(0x0585bfd4) /* 0.345153646 */, 17 }, /* 3103 */ { MAD_F(0x05865b67) /* 0.345302011 */, 17 }, /* 3104 */ { MAD_F(0x0586f6fd) /* 0.345450393 */, 17 }, /* 3105 */ { MAD_F(0x05879298) /* 0.345598790 */, 17 }, /* 3106 */ { MAD_F(0x05882e38) /* 0.345747203 */, 17 }, /* 3107 */ { MAD_F(0x0588c9dc) /* 0.345895632 */, 17 }, /* 3108 */ { MAD_F(0x05896583) /* 0.346044077 */, 17 }, /* 3109 */ { MAD_F(0x058a0130) /* 0.346192538 */, 17 }, /* 3110 */ { MAD_F(0x058a9ce0) /* 0.346341015 */, 17 }, /* 3111 */ { MAD_F(0x058b3895) /* 0.346489508 */, 17 }, /* 3112 */ { MAD_F(0x058bd44e) /* 0.346638017 */, 17 }, /* 3113 */ { MAD_F(0x058c700b) /* 0.346786542 */, 17 }, /* 3114 */ { MAD_F(0x058d0bcd) /* 0.346935082 */, 17 }, /* 3115 */ { MAD_F(0x058da793) /* 0.347083639 */, 17 }, /* 3116 */ { MAD_F(0x058e435d) /* 0.347232211 */, 17 }, /* 3117 */ { MAD_F(0x058edf2b) /* 0.347380799 */, 17 }, /* 3118 */ { MAD_F(0x058f7afe) /* 0.347529403 */, 17 }, /* 3119 */ { MAD_F(0x059016d5) /* 0.347678023 */, 17 }, /* 3120 */ { MAD_F(0x0590b2b0) /* 0.347826659 */, 17 }, /* 3121 */ { MAD_F(0x05914e8f) /* 0.347975311 */, 17 }, /* 3122 */ { MAD_F(0x0591ea73) /* 0.348123979 */, 17 }, /* 3123 */ { MAD_F(0x0592865b) /* 0.348272662 */, 17 }, /* 3124 */ { MAD_F(0x05932247) /* 0.348421362 */, 17 }, /* 3125 */ { MAD_F(0x0593be37) /* 0.348570077 */, 17 }, /* 3126 */ { MAD_F(0x05945a2c) /* 0.348718808 */, 17 }, /* 3127 */ { MAD_F(0x0594f625) /* 0.348867555 */, 17 }, /* 3128 */ { MAD_F(0x05959222) /* 0.349016318 */, 17 }, /* 3129 */ { MAD_F(0x05962e24) /* 0.349165097 */, 17 }, /* 3130 */ { MAD_F(0x0596ca2a) /* 0.349313892 */, 17 }, /* 3131 */ { MAD_F(0x05976634) /* 0.349462702 */, 17 }, /* 3132 */ { MAD_F(0x05980242) /* 0.349611528 */, 17 }, /* 3133 */ { MAD_F(0x05989e54) /* 0.349760370 */, 17 }, /* 3134 */ { MAD_F(0x05993a6b) /* 0.349909228 */, 17 }, /* 3135 */ { MAD_F(0x0599d686) /* 0.350058102 */, 17 }, /* 3136 */ { MAD_F(0x059a72a5) /* 0.350206992 */, 17 }, /* 3137 */ { MAD_F(0x059b0ec9) /* 0.350355897 */, 17 }, /* 3138 */ { MAD_F(0x059baaf1) /* 0.350504818 */, 17 }, /* 3139 */ { MAD_F(0x059c471d) /* 0.350653756 */, 17 }, /* 3140 */ { MAD_F(0x059ce34d) /* 0.350802708 */, 17 }, /* 3141 */ { MAD_F(0x059d7f81) /* 0.350951677 */, 17 }, /* 3142 */ { MAD_F(0x059e1bba) /* 0.351100662 */, 17 }, /* 3143 */ { MAD_F(0x059eb7f7) /* 0.351249662 */, 17 }, /* 3144 */ { MAD_F(0x059f5438) /* 0.351398678 */, 17 }, /* 3145 */ { MAD_F(0x059ff07e) /* 0.351547710 */, 17 }, /* 3146 */ { MAD_F(0x05a08cc7) /* 0.351696758 */, 17 }, /* 3147 */ { MAD_F(0x05a12915) /* 0.351845821 */, 17 }, /* 3148 */ { MAD_F(0x05a1c567) /* 0.351994901 */, 17 }, /* 3149 */ { MAD_F(0x05a261be) /* 0.352143996 */, 17 }, /* 3150 */ { MAD_F(0x05a2fe18) /* 0.352293107 */, 17 }, /* 3151 */ { MAD_F(0x05a39a77) /* 0.352442233 */, 17 }, /* 3152 */ { MAD_F(0x05a436da) /* 0.352591376 */, 17 }, /* 3153 */ { MAD_F(0x05a4d342) /* 0.352740534 */, 17 }, /* 3154 */ { MAD_F(0x05a56fad) /* 0.352889708 */, 17 }, /* 3155 */ { MAD_F(0x05a60c1d) /* 0.353038898 */, 17 }, /* 3156 */ { MAD_F(0x05a6a891) /* 0.353188103 */, 17 }, /* 3157 */ { MAD_F(0x05a7450a) /* 0.353337325 */, 17 }, /* 3158 */ { MAD_F(0x05a7e186) /* 0.353486562 */, 17 }, /* 3159 */ { MAD_F(0x05a87e07) /* 0.353635814 */, 17 }, /* 3160 */ { MAD_F(0x05a91a8c) /* 0.353785083 */, 17 }, /* 3161 */ { MAD_F(0x05a9b715) /* 0.353934367 */, 17 }, /* 3162 */ { MAD_F(0x05aa53a2) /* 0.354083667 */, 17 }, /* 3163 */ { MAD_F(0x05aaf034) /* 0.354232983 */, 17 }, /* 3164 */ { MAD_F(0x05ab8cca) /* 0.354382314 */, 17 }, /* 3165 */ { MAD_F(0x05ac2964) /* 0.354531662 */, 17 }, /* 3166 */ { MAD_F(0x05acc602) /* 0.354681025 */, 17 }, /* 3167 */ { MAD_F(0x05ad62a5) /* 0.354830403 */, 17 }, /* 3168 */ { MAD_F(0x05adff4c) /* 0.354979798 */, 17 }, /* 3169 */ { MAD_F(0x05ae9bf7) /* 0.355129208 */, 17 }, /* 3170 */ { MAD_F(0x05af38a6) /* 0.355278634 */, 17 }, /* 3171 */ { MAD_F(0x05afd559) /* 0.355428075 */, 17 }, /* 3172 */ { MAD_F(0x05b07211) /* 0.355577533 */, 17 }, /* 3173 */ { MAD_F(0x05b10ecd) /* 0.355727006 */, 17 }, /* 3174 */ { MAD_F(0x05b1ab8d) /* 0.355876494 */, 17 }, /* 3175 */ { MAD_F(0x05b24851) /* 0.356025999 */, 17 }, /* 3176 */ { MAD_F(0x05b2e51a) /* 0.356175519 */, 17 }, /* 3177 */ { MAD_F(0x05b381e6) /* 0.356325054 */, 17 }, /* 3178 */ { MAD_F(0x05b41eb7) /* 0.356474606 */, 17 }, /* 3179 */ { MAD_F(0x05b4bb8c) /* 0.356624173 */, 17 }, /* 3180 */ { MAD_F(0x05b55866) /* 0.356773756 */, 17 }, /* 3181 */ { MAD_F(0x05b5f543) /* 0.356923354 */, 17 }, /* 3182 */ { MAD_F(0x05b69225) /* 0.357072969 */, 17 }, /* 3183 */ { MAD_F(0x05b72f0b) /* 0.357222598 */, 17 }, /* 3184 */ { MAD_F(0x05b7cbf5) /* 0.357372244 */, 17 }, /* 3185 */ { MAD_F(0x05b868e3) /* 0.357521905 */, 17 }, /* 3186 */ { MAD_F(0x05b905d6) /* 0.357671582 */, 17 }, /* 3187 */ { MAD_F(0x05b9a2cd) /* 0.357821275 */, 17 }, /* 3188 */ { MAD_F(0x05ba3fc8) /* 0.357970983 */, 17 }, /* 3189 */ { MAD_F(0x05badcc7) /* 0.358120707 */, 17 }, /* 3190 */ { MAD_F(0x05bb79ca) /* 0.358270446 */, 17 }, /* 3191 */ { MAD_F(0x05bc16d2) /* 0.358420201 */, 17 }, /* 3192 */ { MAD_F(0x05bcb3de) /* 0.358569972 */, 17 }, /* 3193 */ { MAD_F(0x05bd50ee) /* 0.358719758 */, 17 }, /* 3194 */ { MAD_F(0x05bdee02) /* 0.358869560 */, 17 }, /* 3195 */ { MAD_F(0x05be8b1a) /* 0.359019378 */, 17 }, /* 3196 */ { MAD_F(0x05bf2837) /* 0.359169211 */, 17 }, /* 3197 */ { MAD_F(0x05bfc558) /* 0.359319060 */, 17 }, /* 3198 */ { MAD_F(0x05c0627d) /* 0.359468925 */, 17 }, /* 3199 */ { MAD_F(0x05c0ffa6) /* 0.359618805 */, 17 }, /* 3200 */ { MAD_F(0x05c19cd3) /* 0.359768701 */, 17 }, /* 3201 */ { MAD_F(0x05c23a05) /* 0.359918612 */, 17 }, /* 3202 */ { MAD_F(0x05c2d73a) /* 0.360068540 */, 17 }, /* 3203 */ { MAD_F(0x05c37474) /* 0.360218482 */, 17 }, /* 3204 */ { MAD_F(0x05c411b2) /* 0.360368440 */, 17 }, /* 3205 */ { MAD_F(0x05c4aef5) /* 0.360518414 */, 17 }, /* 3206 */ { MAD_F(0x05c54c3b) /* 0.360668404 */, 17 }, /* 3207 */ { MAD_F(0x05c5e986) /* 0.360818409 */, 17 }, /* 3208 */ { MAD_F(0x05c686d5) /* 0.360968429 */, 17 }, /* 3209 */ { MAD_F(0x05c72428) /* 0.361118466 */, 17 }, /* 3210 */ { MAD_F(0x05c7c17f) /* 0.361268517 */, 17 }, /* 3211 */ { MAD_F(0x05c85eda) /* 0.361418585 */, 17 }, /* 3212 */ { MAD_F(0x05c8fc3a) /* 0.361568668 */, 17 }, /* 3213 */ { MAD_F(0x05c9999e) /* 0.361718766 */, 17 }, /* 3214 */ { MAD_F(0x05ca3706) /* 0.361868881 */, 17 }, /* 3215 */ { MAD_F(0x05cad472) /* 0.362019010 */, 17 }, /* 3216 */ { MAD_F(0x05cb71e2) /* 0.362169156 */, 17 }, /* 3217 */ { MAD_F(0x05cc0f57) /* 0.362319316 */, 17 }, /* 3218 */ { MAD_F(0x05ccaccf) /* 0.362469493 */, 17 }, /* 3219 */ { MAD_F(0x05cd4a4c) /* 0.362619685 */, 17 }, /* 3220 */ { MAD_F(0x05cde7cd) /* 0.362769892 */, 17 }, /* 3221 */ { MAD_F(0x05ce8552) /* 0.362920115 */, 17 }, /* 3222 */ { MAD_F(0x05cf22dc) /* 0.363070354 */, 17 }, /* 3223 */ { MAD_F(0x05cfc069) /* 0.363220608 */, 17 }, /* 3224 */ { MAD_F(0x05d05dfb) /* 0.363370878 */, 17 }, /* 3225 */ { MAD_F(0x05d0fb91) /* 0.363521163 */, 17 }, /* 3226 */ { MAD_F(0x05d1992b) /* 0.363671464 */, 17 }, /* 3227 */ { MAD_F(0x05d236c9) /* 0.363821780 */, 17 }, /* 3228 */ { MAD_F(0x05d2d46c) /* 0.363972112 */, 17 }, /* 3229 */ { MAD_F(0x05d37212) /* 0.364122459 */, 17 }, /* 3230 */ { MAD_F(0x05d40fbd) /* 0.364272822 */, 17 }, /* 3231 */ { MAD_F(0x05d4ad6c) /* 0.364423200 */, 17 }, /* 3232 */ { MAD_F(0x05d54b1f) /* 0.364573594 */, 17 }, /* 3233 */ { MAD_F(0x05d5e8d6) /* 0.364724004 */, 17 }, /* 3234 */ { MAD_F(0x05d68691) /* 0.364874429 */, 17 }, /* 3235 */ { MAD_F(0x05d72451) /* 0.365024869 */, 17 }, /* 3236 */ { MAD_F(0x05d7c215) /* 0.365175325 */, 17 }, /* 3237 */ { MAD_F(0x05d85fdc) /* 0.365325796 */, 17 }, /* 3238 */ { MAD_F(0x05d8fda8) /* 0.365476283 */, 17 }, /* 3239 */ { MAD_F(0x05d99b79) /* 0.365626786 */, 17 }, /* 3240 */ { MAD_F(0x05da394d) /* 0.365777304 */, 17 }, /* 3241 */ { MAD_F(0x05dad726) /* 0.365927837 */, 17 }, /* 3242 */ { MAD_F(0x05db7502) /* 0.366078386 */, 17 }, /* 3243 */ { MAD_F(0x05dc12e3) /* 0.366228950 */, 17 }, /* 3244 */ { MAD_F(0x05dcb0c8) /* 0.366379530 */, 17 }, /* 3245 */ { MAD_F(0x05dd4eb1) /* 0.366530125 */, 17 }, /* 3246 */ { MAD_F(0x05ddec9e) /* 0.366680736 */, 17 }, /* 3247 */ { MAD_F(0x05de8a90) /* 0.366831362 */, 17 }, /* 3248 */ { MAD_F(0x05df2885) /* 0.366982004 */, 17 }, /* 3249 */ { MAD_F(0x05dfc67f) /* 0.367132661 */, 17 }, /* 3250 */ { MAD_F(0x05e0647d) /* 0.367283334 */, 17 }, /* 3251 */ { MAD_F(0x05e1027f) /* 0.367434022 */, 17 }, /* 3252 */ { MAD_F(0x05e1a085) /* 0.367584725 */, 17 }, /* 3253 */ { MAD_F(0x05e23e8f) /* 0.367735444 */, 17 }, /* 3254 */ { MAD_F(0x05e2dc9e) /* 0.367886179 */, 17 }, /* 3255 */ { MAD_F(0x05e37ab0) /* 0.368036929 */, 17 }, /* 3256 */ { MAD_F(0x05e418c7) /* 0.368187694 */, 17 }, /* 3257 */ { MAD_F(0x05e4b6e2) /* 0.368338475 */, 17 }, /* 3258 */ { MAD_F(0x05e55501) /* 0.368489271 */, 17 }, /* 3259 */ { MAD_F(0x05e5f324) /* 0.368640082 */, 17 }, /* 3260 */ { MAD_F(0x05e6914c) /* 0.368790909 */, 17 }, /* 3261 */ { MAD_F(0x05e72f77) /* 0.368941752 */, 17 }, /* 3262 */ { MAD_F(0x05e7cda7) /* 0.369092610 */, 17 }, /* 3263 */ { MAD_F(0x05e86bda) /* 0.369243483 */, 17 }, /* 3264 */ { MAD_F(0x05e90a12) /* 0.369394372 */, 17 }, /* 3265 */ { MAD_F(0x05e9a84e) /* 0.369545276 */, 17 }, /* 3266 */ { MAD_F(0x05ea468e) /* 0.369696195 */, 17 }, /* 3267 */ { MAD_F(0x05eae4d3) /* 0.369847130 */, 17 }, /* 3268 */ { MAD_F(0x05eb831b) /* 0.369998080 */, 17 }, /* 3269 */ { MAD_F(0x05ec2168) /* 0.370149046 */, 17 }, /* 3270 */ { MAD_F(0x05ecbfb8) /* 0.370300027 */, 17 }, /* 3271 */ { MAD_F(0x05ed5e0d) /* 0.370451024 */, 17 }, /* 3272 */ { MAD_F(0x05edfc66) /* 0.370602036 */, 17 }, /* 3273 */ { MAD_F(0x05ee9ac3) /* 0.370753063 */, 17 }, /* 3274 */ { MAD_F(0x05ef3924) /* 0.370904105 */, 17 }, /* 3275 */ { MAD_F(0x05efd78a) /* 0.371055163 */, 17 }, /* 3276 */ { MAD_F(0x05f075f3) /* 0.371206237 */, 17 }, /* 3277 */ { MAD_F(0x05f11461) /* 0.371357326 */, 17 }, /* 3278 */ { MAD_F(0x05f1b2d3) /* 0.371508430 */, 17 }, /* 3279 */ { MAD_F(0x05f25148) /* 0.371659549 */, 17 }, /* 3280 */ { MAD_F(0x05f2efc2) /* 0.371810684 */, 17 }, /* 3281 */ { MAD_F(0x05f38e40) /* 0.371961834 */, 17 }, /* 3282 */ { MAD_F(0x05f42cc3) /* 0.372113000 */, 17 }, /* 3283 */ { MAD_F(0x05f4cb49) /* 0.372264181 */, 17 }, /* 3284 */ { MAD_F(0x05f569d3) /* 0.372415377 */, 17 }, /* 3285 */ { MAD_F(0x05f60862) /* 0.372566589 */, 17 }, /* 3286 */ { MAD_F(0x05f6a6f5) /* 0.372717816 */, 17 }, /* 3287 */ { MAD_F(0x05f7458b) /* 0.372869058 */, 17 }, /* 3288 */ { MAD_F(0x05f7e426) /* 0.373020316 */, 17 }, /* 3289 */ { MAD_F(0x05f882c5) /* 0.373171589 */, 17 }, /* 3290 */ { MAD_F(0x05f92169) /* 0.373322877 */, 17 }, /* 3291 */ { MAD_F(0x05f9c010) /* 0.373474181 */, 17 }, /* 3292 */ { MAD_F(0x05fa5ebb) /* 0.373625500 */, 17 }, /* 3293 */ { MAD_F(0x05fafd6b) /* 0.373776834 */, 17 }, /* 3294 */ { MAD_F(0x05fb9c1e) /* 0.373928184 */, 17 }, /* 3295 */ { MAD_F(0x05fc3ad6) /* 0.374079549 */, 17 }, /* 3296 */ { MAD_F(0x05fcd992) /* 0.374230929 */, 17 }, /* 3297 */ { MAD_F(0x05fd7852) /* 0.374382325 */, 17 }, /* 3298 */ { MAD_F(0x05fe1716) /* 0.374533735 */, 17 }, /* 3299 */ { MAD_F(0x05feb5de) /* 0.374685162 */, 17 }, /* 3300 */ { MAD_F(0x05ff54aa) /* 0.374836603 */, 17 }, /* 3301 */ { MAD_F(0x05fff37b) /* 0.374988060 */, 17 }, /* 3302 */ { MAD_F(0x0600924f) /* 0.375139532 */, 17 }, /* 3303 */ { MAD_F(0x06013128) /* 0.375291019 */, 17 }, /* 3304 */ { MAD_F(0x0601d004) /* 0.375442522 */, 17 }, /* 3305 */ { MAD_F(0x06026ee5) /* 0.375594040 */, 17 }, /* 3306 */ { MAD_F(0x06030dca) /* 0.375745573 */, 17 }, /* 3307 */ { MAD_F(0x0603acb3) /* 0.375897122 */, 17 }, /* 3308 */ { MAD_F(0x06044ba0) /* 0.376048685 */, 17 }, /* 3309 */ { MAD_F(0x0604ea91) /* 0.376200265 */, 17 }, /* 3310 */ { MAD_F(0x06058987) /* 0.376351859 */, 17 }, /* 3311 */ { MAD_F(0x06062880) /* 0.376503468 */, 17 }, /* 3312 */ { MAD_F(0x0606c77d) /* 0.376655093 */, 17 }, /* 3313 */ { MAD_F(0x0607667f) /* 0.376806733 */, 17 }, /* 3314 */ { MAD_F(0x06080585) /* 0.376958389 */, 17 }, /* 3315 */ { MAD_F(0x0608a48f) /* 0.377110059 */, 17 }, /* 3316 */ { MAD_F(0x0609439c) /* 0.377261745 */, 17 }, /* 3317 */ { MAD_F(0x0609e2ae) /* 0.377413446 */, 17 }, /* 3318 */ { MAD_F(0x060a81c4) /* 0.377565163 */, 17 }, /* 3319 */ { MAD_F(0x060b20df) /* 0.377716894 */, 17 }, /* 3320 */ { MAD_F(0x060bbffd) /* 0.377868641 */, 17 }, /* 3321 */ { MAD_F(0x060c5f1f) /* 0.378020403 */, 17 }, /* 3322 */ { MAD_F(0x060cfe46) /* 0.378172181 */, 17 }, /* 3323 */ { MAD_F(0x060d9d70) /* 0.378323973 */, 17 }, /* 3324 */ { MAD_F(0x060e3c9f) /* 0.378475781 */, 17 }, /* 3325 */ { MAD_F(0x060edbd1) /* 0.378627604 */, 17 }, /* 3326 */ { MAD_F(0x060f7b08) /* 0.378779442 */, 17 }, /* 3327 */ { MAD_F(0x06101a43) /* 0.378931296 */, 17 }, /* 3328 */ { MAD_F(0x0610b982) /* 0.379083164 */, 17 }, /* 3329 */ { MAD_F(0x061158c5) /* 0.379235048 */, 17 }, /* 3330 */ { MAD_F(0x0611f80c) /* 0.379386947 */, 17 }, /* 3331 */ { MAD_F(0x06129757) /* 0.379538862 */, 17 }, /* 3332 */ { MAD_F(0x061336a6) /* 0.379690791 */, 17 }, /* 3333 */ { MAD_F(0x0613d5fa) /* 0.379842736 */, 17 }, /* 3334 */ { MAD_F(0x06147551) /* 0.379994696 */, 17 }, /* 3335 */ { MAD_F(0x061514ad) /* 0.380146671 */, 17 }, /* 3336 */ { MAD_F(0x0615b40c) /* 0.380298661 */, 17 }, /* 3337 */ { MAD_F(0x06165370) /* 0.380450666 */, 17 }, /* 3338 */ { MAD_F(0x0616f2d8) /* 0.380602687 */, 17 }, /* 3339 */ { MAD_F(0x06179243) /* 0.380754723 */, 17 }, /* 3340 */ { MAD_F(0x061831b3) /* 0.380906774 */, 17 }, /* 3341 */ { MAD_F(0x0618d127) /* 0.381058840 */, 17 }, /* 3342 */ { MAD_F(0x0619709f) /* 0.381210921 */, 17 }, /* 3343 */ { MAD_F(0x061a101b) /* 0.381363018 */, 17 }, /* 3344 */ { MAD_F(0x061aaf9c) /* 0.381515130 */, 17 }, /* 3345 */ { MAD_F(0x061b4f20) /* 0.381667257 */, 17 }, /* 3346 */ { MAD_F(0x061beea8) /* 0.381819399 */, 17 }, /* 3347 */ { MAD_F(0x061c8e34) /* 0.381971556 */, 17 }, /* 3348 */ { MAD_F(0x061d2dc5) /* 0.382123728 */, 17 }, /* 3349 */ { MAD_F(0x061dcd59) /* 0.382275916 */, 17 }, /* 3350 */ { MAD_F(0x061e6cf2) /* 0.382428118 */, 17 }, /* 3351 */ { MAD_F(0x061f0c8f) /* 0.382580336 */, 17 }, /* 3352 */ { MAD_F(0x061fac2f) /* 0.382732569 */, 17 }, /* 3353 */ { MAD_F(0x06204bd4) /* 0.382884817 */, 17 }, /* 3354 */ { MAD_F(0x0620eb7d) /* 0.383037080 */, 17 }, /* 3355 */ { MAD_F(0x06218b2a) /* 0.383189358 */, 17 }, /* 3356 */ { MAD_F(0x06222adb) /* 0.383341652 */, 17 }, /* 3357 */ { MAD_F(0x0622ca90) /* 0.383493960 */, 17 }, /* 3358 */ { MAD_F(0x06236a49) /* 0.383646284 */, 17 }, /* 3359 */ { MAD_F(0x06240a06) /* 0.383798623 */, 17 }, /* 3360 */ { MAD_F(0x0624a9c7) /* 0.383950977 */, 17 }, /* 3361 */ { MAD_F(0x0625498d) /* 0.384103346 */, 17 }, /* 3362 */ { MAD_F(0x0625e956) /* 0.384255730 */, 17 }, /* 3363 */ { MAD_F(0x06268923) /* 0.384408129 */, 17 }, /* 3364 */ { MAD_F(0x062728f5) /* 0.384560544 */, 17 }, /* 3365 */ { MAD_F(0x0627c8ca) /* 0.384712973 */, 17 }, /* 3366 */ { MAD_F(0x062868a4) /* 0.384865418 */, 17 }, /* 3367 */ { MAD_F(0x06290881) /* 0.385017878 */, 17 }, /* 3368 */ { MAD_F(0x0629a863) /* 0.385170352 */, 17 }, /* 3369 */ { MAD_F(0x062a4849) /* 0.385322842 */, 17 }, /* 3370 */ { MAD_F(0x062ae832) /* 0.385475347 */, 17 }, /* 3371 */ { MAD_F(0x062b8820) /* 0.385627867 */, 17 }, /* 3372 */ { MAD_F(0x062c2812) /* 0.385780402 */, 17 }, /* 3373 */ { MAD_F(0x062cc808) /* 0.385932953 */, 17 }, /* 3374 */ { MAD_F(0x062d6802) /* 0.386085518 */, 17 }, /* 3375 */ { MAD_F(0x062e0800) /* 0.386238098 */, 17 }, /* 3376 */ { MAD_F(0x062ea802) /* 0.386390694 */, 17 }, /* 3377 */ { MAD_F(0x062f4808) /* 0.386543304 */, 17 }, /* 3378 */ { MAD_F(0x062fe812) /* 0.386695930 */, 17 }, /* 3379 */ { MAD_F(0x06308820) /* 0.386848570 */, 17 }, /* 3380 */ { MAD_F(0x06312832) /* 0.387001226 */, 17 }, /* 3381 */ { MAD_F(0x0631c849) /* 0.387153897 */, 17 }, /* 3382 */ { MAD_F(0x06326863) /* 0.387306582 */, 17 }, /* 3383 */ { MAD_F(0x06330881) /* 0.387459283 */, 17 }, /* 3384 */ { MAD_F(0x0633a8a3) /* 0.387611999 */, 17 }, /* 3385 */ { MAD_F(0x063448ca) /* 0.387764730 */, 17 }, /* 3386 */ { MAD_F(0x0634e8f4) /* 0.387917476 */, 17 }, /* 3387 */ { MAD_F(0x06358923) /* 0.388070237 */, 17 }, /* 3388 */ { MAD_F(0x06362955) /* 0.388223013 */, 17 }, /* 3389 */ { MAD_F(0x0636c98c) /* 0.388375804 */, 17 }, /* 3390 */ { MAD_F(0x063769c6) /* 0.388528610 */, 17 }, /* 3391 */ { MAD_F(0x06380a05) /* 0.388681431 */, 17 }, /* 3392 */ { MAD_F(0x0638aa48) /* 0.388834268 */, 17 }, /* 3393 */ { MAD_F(0x06394a8e) /* 0.388987119 */, 17 }, /* 3394 */ { MAD_F(0x0639ead9) /* 0.389139985 */, 17 }, /* 3395 */ { MAD_F(0x063a8b28) /* 0.389292866 */, 17 }, /* 3396 */ { MAD_F(0x063b2b7b) /* 0.389445762 */, 17 }, /* 3397 */ { MAD_F(0x063bcbd1) /* 0.389598674 */, 17 }, /* 3398 */ { MAD_F(0x063c6c2c) /* 0.389751600 */, 17 }, /* 3399 */ { MAD_F(0x063d0c8b) /* 0.389904541 */, 17 }, /* 3400 */ { MAD_F(0x063dacee) /* 0.390057497 */, 17 }, /* 3401 */ { MAD_F(0x063e4d55) /* 0.390210468 */, 17 }, /* 3402 */ { MAD_F(0x063eedc0) /* 0.390363455 */, 17 }, /* 3403 */ { MAD_F(0x063f8e2f) /* 0.390516456 */, 17 }, /* 3404 */ { MAD_F(0x06402ea2) /* 0.390669472 */, 17 }, /* 3405 */ { MAD_F(0x0640cf19) /* 0.390822503 */, 17 }, /* 3406 */ { MAD_F(0x06416f94) /* 0.390975549 */, 17 }, /* 3407 */ { MAD_F(0x06421013) /* 0.391128611 */, 17 }, /* 3408 */ { MAD_F(0x0642b096) /* 0.391281687 */, 17 }, /* 3409 */ { MAD_F(0x0643511d) /* 0.391434778 */, 17 }, /* 3410 */ { MAD_F(0x0643f1a8) /* 0.391587884 */, 17 }, /* 3411 */ { MAD_F(0x06449237) /* 0.391741005 */, 17 }, /* 3412 */ { MAD_F(0x064532ca) /* 0.391894141 */, 17 }, /* 3413 */ { MAD_F(0x0645d361) /* 0.392047292 */, 17 }, /* 3414 */ { MAD_F(0x064673fc) /* 0.392200458 */, 17 }, /* 3415 */ { MAD_F(0x0647149c) /* 0.392353638 */, 17 }, /* 3416 */ { MAD_F(0x0647b53f) /* 0.392506834 */, 17 }, /* 3417 */ { MAD_F(0x064855e6) /* 0.392660045 */, 17 }, /* 3418 */ { MAD_F(0x0648f691) /* 0.392813271 */, 17 }, /* 3419 */ { MAD_F(0x06499740) /* 0.392966511 */, 17 }, /* 3420 */ { MAD_F(0x064a37f4) /* 0.393119767 */, 17 }, /* 3421 */ { MAD_F(0x064ad8ab) /* 0.393273038 */, 17 }, /* 3422 */ { MAD_F(0x064b7966) /* 0.393426323 */, 17 }, /* 3423 */ { MAD_F(0x064c1a25) /* 0.393579623 */, 17 }, /* 3424 */ { MAD_F(0x064cbae9) /* 0.393732939 */, 17 }, /* 3425 */ { MAD_F(0x064d5bb0) /* 0.393886269 */, 17 }, /* 3426 */ { MAD_F(0x064dfc7b) /* 0.394039614 */, 17 }, /* 3427 */ { MAD_F(0x064e9d4b) /* 0.394192974 */, 17 }, /* 3428 */ { MAD_F(0x064f3e1e) /* 0.394346349 */, 17 }, /* 3429 */ { MAD_F(0x064fdef5) /* 0.394499739 */, 17 }, /* 3430 */ { MAD_F(0x06507fd0) /* 0.394653144 */, 17 }, /* 3431 */ { MAD_F(0x065120b0) /* 0.394806564 */, 17 }, /* 3432 */ { MAD_F(0x0651c193) /* 0.394959999 */, 17 }, /* 3433 */ { MAD_F(0x0652627a) /* 0.395113448 */, 17 }, /* 3434 */ { MAD_F(0x06530366) /* 0.395266913 */, 17 }, /* 3435 */ { MAD_F(0x0653a455) /* 0.395420392 */, 17 }, /* 3436 */ { MAD_F(0x06544548) /* 0.395573886 */, 17 }, /* 3437 */ { MAD_F(0x0654e640) /* 0.395727395 */, 17 }, /* 3438 */ { MAD_F(0x0655873b) /* 0.395880919 */, 17 }, /* 3439 */ { MAD_F(0x0656283a) /* 0.396034458 */, 17 }, /* 3440 */ { MAD_F(0x0656c93d) /* 0.396188012 */, 17 }, /* 3441 */ { MAD_F(0x06576a45) /* 0.396341581 */, 17 }, /* 3442 */ { MAD_F(0x06580b50) /* 0.396495164 */, 17 }, /* 3443 */ { MAD_F(0x0658ac5f) /* 0.396648763 */, 17 }, /* 3444 */ { MAD_F(0x06594d73) /* 0.396802376 */, 17 }, /* 3445 */ { MAD_F(0x0659ee8a) /* 0.396956004 */, 17 }, /* 3446 */ { MAD_F(0x065a8fa5) /* 0.397109647 */, 17 }, /* 3447 */ { MAD_F(0x065b30c4) /* 0.397263305 */, 17 }, /* 3448 */ { MAD_F(0x065bd1e7) /* 0.397416978 */, 17 }, /* 3449 */ { MAD_F(0x065c730f) /* 0.397570666 */, 17 }, /* 3450 */ { MAD_F(0x065d143a) /* 0.397724368 */, 17 }, /* 3451 */ { MAD_F(0x065db569) /* 0.397878085 */, 17 }, /* 3452 */ { MAD_F(0x065e569c) /* 0.398031818 */, 17 }, /* 3453 */ { MAD_F(0x065ef7d3) /* 0.398185565 */, 17 }, /* 3454 */ { MAD_F(0x065f990e) /* 0.398339326 */, 17 }, /* 3455 */ { MAD_F(0x06603a4e) /* 0.398493103 */, 17 }, /* 3456 */ { MAD_F(0x0660db91) /* 0.398646895 */, 17 }, /* 3457 */ { MAD_F(0x06617cd8) /* 0.398800701 */, 17 }, /* 3458 */ { MAD_F(0x06621e23) /* 0.398954522 */, 17 }, /* 3459 */ { MAD_F(0x0662bf72) /* 0.399108358 */, 17 }, /* 3460 */ { MAD_F(0x066360c5) /* 0.399262209 */, 17 }, /* 3461 */ { MAD_F(0x0664021c) /* 0.399416075 */, 17 }, /* 3462 */ { MAD_F(0x0664a377) /* 0.399569955 */, 17 }, /* 3463 */ { MAD_F(0x066544d6) /* 0.399723851 */, 17 }, /* 3464 */ { MAD_F(0x0665e639) /* 0.399877761 */, 17 }, /* 3465 */ { MAD_F(0x066687a0) /* 0.400031686 */, 17 }, /* 3466 */ { MAD_F(0x0667290b) /* 0.400185625 */, 17 }, /* 3467 */ { MAD_F(0x0667ca79) /* 0.400339580 */, 17 }, /* 3468 */ { MAD_F(0x06686bec) /* 0.400493549 */, 17 }, /* 3469 */ { MAD_F(0x06690d63) /* 0.400647534 */, 17 }, /* 3470 */ { MAD_F(0x0669aede) /* 0.400801533 */, 17 }, /* 3471 */ { MAD_F(0x066a505d) /* 0.400955546 */, 17 }, /* 3472 */ { MAD_F(0x066af1df) /* 0.401109575 */, 17 }, /* 3473 */ { MAD_F(0x066b9366) /* 0.401263618 */, 17 }, /* 3474 */ { MAD_F(0x066c34f1) /* 0.401417676 */, 17 }, /* 3475 */ { MAD_F(0x066cd67f) /* 0.401571749 */, 17 }, /* 3476 */ { MAD_F(0x066d7812) /* 0.401725837 */, 17 }, /* 3477 */ { MAD_F(0x066e19a9) /* 0.401879939 */, 17 }, /* 3478 */ { MAD_F(0x066ebb43) /* 0.402034056 */, 17 }, /* 3479 */ { MAD_F(0x066f5ce2) /* 0.402188188 */, 17 }, /* 3480 */ { MAD_F(0x066ffe84) /* 0.402342335 */, 17 }, /* 3481 */ { MAD_F(0x0670a02a) /* 0.402496497 */, 17 }, /* 3482 */ { MAD_F(0x067141d5) /* 0.402650673 */, 17 }, /* 3483 */ { MAD_F(0x0671e383) /* 0.402804864 */, 17 }, /* 3484 */ { MAD_F(0x06728535) /* 0.402959070 */, 17 }, /* 3485 */ { MAD_F(0x067326ec) /* 0.403113291 */, 17 }, /* 3486 */ { MAD_F(0x0673c8a6) /* 0.403267526 */, 17 }, /* 3487 */ { MAD_F(0x06746a64) /* 0.403421776 */, 17 }, /* 3488 */ { MAD_F(0x06750c26) /* 0.403576041 */, 17 }, /* 3489 */ { MAD_F(0x0675adec) /* 0.403730320 */, 17 }, /* 3490 */ { MAD_F(0x06764fb6) /* 0.403884615 */, 17 }, /* 3491 */ { MAD_F(0x0676f184) /* 0.404038924 */, 17 }, /* 3492 */ { MAD_F(0x06779356) /* 0.404193247 */, 17 }, /* 3493 */ { MAD_F(0x0678352c) /* 0.404347586 */, 17 }, /* 3494 */ { MAD_F(0x0678d706) /* 0.404501939 */, 17 }, /* 3495 */ { MAD_F(0x067978e4) /* 0.404656307 */, 17 }, /* 3496 */ { MAD_F(0x067a1ac6) /* 0.404810690 */, 17 }, /* 3497 */ { MAD_F(0x067abcac) /* 0.404965087 */, 17 }, /* 3498 */ { MAD_F(0x067b5e95) /* 0.405119499 */, 17 }, /* 3499 */ { MAD_F(0x067c0083) /* 0.405273926 */, 17 }, /* 3500 */ { MAD_F(0x067ca275) /* 0.405428368 */, 17 }, /* 3501 */ { MAD_F(0x067d446a) /* 0.405582824 */, 17 }, /* 3502 */ { MAD_F(0x067de664) /* 0.405737295 */, 17 }, /* 3503 */ { MAD_F(0x067e8861) /* 0.405891781 */, 17 }, /* 3504 */ { MAD_F(0x067f2a62) /* 0.406046281 */, 17 }, /* 3505 */ { MAD_F(0x067fcc68) /* 0.406200796 */, 17 }, /* 3506 */ { MAD_F(0x06806e71) /* 0.406355326 */, 17 }, /* 3507 */ { MAD_F(0x0681107e) /* 0.406509870 */, 17 }, /* 3508 */ { MAD_F(0x0681b28f) /* 0.406664429 */, 17 }, /* 3509 */ { MAD_F(0x068254a4) /* 0.406819003 */, 17 }, /* 3510 */ { MAD_F(0x0682f6bd) /* 0.406973592 */, 17 }, /* 3511 */ { MAD_F(0x068398da) /* 0.407128195 */, 17 }, /* 3512 */ { MAD_F(0x06843afb) /* 0.407282813 */, 17 }, /* 3513 */ { MAD_F(0x0684dd20) /* 0.407437445 */, 17 }, /* 3514 */ { MAD_F(0x06857f49) /* 0.407592093 */, 17 }, /* 3515 */ { MAD_F(0x06862176) /* 0.407746754 */, 17 }, /* 3516 */ { MAD_F(0x0686c3a6) /* 0.407901431 */, 17 }, /* 3517 */ { MAD_F(0x068765db) /* 0.408056122 */, 17 }, /* 3518 */ { MAD_F(0x06880814) /* 0.408210828 */, 17 }, /* 3519 */ { MAD_F(0x0688aa50) /* 0.408365549 */, 17 }, /* 3520 */ { MAD_F(0x06894c90) /* 0.408520284 */, 17 }, /* 3521 */ { MAD_F(0x0689eed5) /* 0.408675034 */, 17 }, /* 3522 */ { MAD_F(0x068a911d) /* 0.408829798 */, 17 }, /* 3523 */ { MAD_F(0x068b3369) /* 0.408984577 */, 17 }, /* 3524 */ { MAD_F(0x068bd5b9) /* 0.409139371 */, 17 }, /* 3525 */ { MAD_F(0x068c780e) /* 0.409294180 */, 17 }, /* 3526 */ { MAD_F(0x068d1a66) /* 0.409449003 */, 17 }, /* 3527 */ { MAD_F(0x068dbcc1) /* 0.409603840 */, 17 }, /* 3528 */ { MAD_F(0x068e5f21) /* 0.409758693 */, 17 }, /* 3529 */ { MAD_F(0x068f0185) /* 0.409913560 */, 17 }, /* 3530 */ { MAD_F(0x068fa3ed) /* 0.410068441 */, 17 }, /* 3531 */ { MAD_F(0x06904658) /* 0.410223338 */, 17 }, /* 3532 */ { MAD_F(0x0690e8c8) /* 0.410378249 */, 17 }, /* 3533 */ { MAD_F(0x06918b3c) /* 0.410533174 */, 17 }, /* 3534 */ { MAD_F(0x06922db3) /* 0.410688114 */, 17 }, /* 3535 */ { MAD_F(0x0692d02e) /* 0.410843069 */, 17 }, /* 3536 */ { MAD_F(0x069372ae) /* 0.410998038 */, 17 }, /* 3537 */ { MAD_F(0x06941531) /* 0.411153022 */, 17 }, /* 3538 */ { MAD_F(0x0694b7b8) /* 0.411308021 */, 17 }, /* 3539 */ { MAD_F(0x06955a43) /* 0.411463034 */, 17 }, /* 3540 */ { MAD_F(0x0695fcd2) /* 0.411618062 */, 17 }, /* 3541 */ { MAD_F(0x06969f65) /* 0.411773104 */, 17 }, /* 3542 */ { MAD_F(0x069741fb) /* 0.411928161 */, 17 }, /* 3543 */ { MAD_F(0x0697e496) /* 0.412083232 */, 17 }, /* 3544 */ { MAD_F(0x06988735) /* 0.412238319 */, 17 }, /* 3545 */ { MAD_F(0x069929d7) /* 0.412393419 */, 17 }, /* 3546 */ { MAD_F(0x0699cc7e) /* 0.412548535 */, 17 }, /* 3547 */ { MAD_F(0x069a6f28) /* 0.412703664 */, 17 }, /* 3548 */ { MAD_F(0x069b11d6) /* 0.412858809 */, 17 }, /* 3549 */ { MAD_F(0x069bb489) /* 0.413013968 */, 17 }, /* 3550 */ { MAD_F(0x069c573f) /* 0.413169142 */, 17 }, /* 3551 */ { MAD_F(0x069cf9f9) /* 0.413324330 */, 17 }, /* 3552 */ { MAD_F(0x069d9cb7) /* 0.413479532 */, 17 }, /* 3553 */ { MAD_F(0x069e3f78) /* 0.413634750 */, 17 }, /* 3554 */ { MAD_F(0x069ee23e) /* 0.413789982 */, 17 }, /* 3555 */ { MAD_F(0x069f8508) /* 0.413945228 */, 17 }, /* 3556 */ { MAD_F(0x06a027d5) /* 0.414100489 */, 17 }, /* 3557 */ { MAD_F(0x06a0caa7) /* 0.414255765 */, 17 }, /* 3558 */ { MAD_F(0x06a16d7c) /* 0.414411055 */, 17 }, /* 3559 */ { MAD_F(0x06a21055) /* 0.414566359 */, 17 }, /* 3560 */ { MAD_F(0x06a2b333) /* 0.414721679 */, 17 }, /* 3561 */ { MAD_F(0x06a35614) /* 0.414877012 */, 17 }, /* 3562 */ { MAD_F(0x06a3f8f9) /* 0.415032361 */, 17 }, /* 3563 */ { MAD_F(0x06a49be2) /* 0.415187723 */, 17 }, /* 3564 */ { MAD_F(0x06a53ece) /* 0.415343101 */, 17 }, /* 3565 */ { MAD_F(0x06a5e1bf) /* 0.415498493 */, 17 }, /* 3566 */ { MAD_F(0x06a684b4) /* 0.415653899 */, 17 }, /* 3567 */ { MAD_F(0x06a727ac) /* 0.415809320 */, 17 }, /* 3568 */ { MAD_F(0x06a7caa9) /* 0.415964756 */, 17 }, /* 3569 */ { MAD_F(0x06a86da9) /* 0.416120206 */, 17 }, /* 3570 */ { MAD_F(0x06a910ad) /* 0.416275670 */, 17 }, /* 3571 */ { MAD_F(0x06a9b3b5) /* 0.416431149 */, 17 }, /* 3572 */ { MAD_F(0x06aa56c1) /* 0.416586643 */, 17 }, /* 3573 */ { MAD_F(0x06aaf9d1) /* 0.416742151 */, 17 }, /* 3574 */ { MAD_F(0x06ab9ce5) /* 0.416897673 */, 17 }, /* 3575 */ { MAD_F(0x06ac3ffc) /* 0.417053210 */, 17 }, /* 3576 */ { MAD_F(0x06ace318) /* 0.417208762 */, 17 }, /* 3577 */ { MAD_F(0x06ad8637) /* 0.417364328 */, 17 }, /* 3578 */ { MAD_F(0x06ae295b) /* 0.417519909 */, 17 }, /* 3579 */ { MAD_F(0x06aecc82) /* 0.417675504 */, 17 }, /* 3580 */ { MAD_F(0x06af6fad) /* 0.417831113 */, 17 }, /* 3581 */ { MAD_F(0x06b012dc) /* 0.417986737 */, 17 }, /* 3582 */ { MAD_F(0x06b0b60f) /* 0.418142376 */, 17 }, /* 3583 */ { MAD_F(0x06b15946) /* 0.418298029 */, 17 }, /* 3584 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 17 }, /* 3585 */ { MAD_F(0x06b29fbf) /* 0.418609378 */, 17 }, /* 3586 */ { MAD_F(0x06b34302) /* 0.418765075 */, 17 }, /* 3587 */ { MAD_F(0x06b3e648) /* 0.418920786 */, 17 }, /* 3588 */ { MAD_F(0x06b48992) /* 0.419076511 */, 17 }, /* 3589 */ { MAD_F(0x06b52ce0) /* 0.419232251 */, 17 }, /* 3590 */ { MAD_F(0x06b5d032) /* 0.419388005 */, 17 }, /* 3591 */ { MAD_F(0x06b67388) /* 0.419543774 */, 17 }, /* 3592 */ { MAD_F(0x06b716e2) /* 0.419699557 */, 17 }, /* 3593 */ { MAD_F(0x06b7ba3f) /* 0.419855355 */, 17 }, /* 3594 */ { MAD_F(0x06b85da1) /* 0.420011167 */, 17 }, /* 3595 */ { MAD_F(0x06b90106) /* 0.420166994 */, 17 }, /* 3596 */ { MAD_F(0x06b9a470) /* 0.420322835 */, 17 }, /* 3597 */ { MAD_F(0x06ba47dd) /* 0.420478690 */, 17 }, /* 3598 */ { MAD_F(0x06baeb4e) /* 0.420634560 */, 17 }, /* 3599 */ { MAD_F(0x06bb8ec3) /* 0.420790445 */, 17 }, /* 3600 */ { MAD_F(0x06bc323b) /* 0.420946343 */, 17 }, /* 3601 */ { MAD_F(0x06bcd5b8) /* 0.421102257 */, 17 }, /* 3602 */ { MAD_F(0x06bd7939) /* 0.421258184 */, 17 }, /* 3603 */ { MAD_F(0x06be1cbd) /* 0.421414127 */, 17 }, /* 3604 */ { MAD_F(0x06bec045) /* 0.421570083 */, 17 }, /* 3605 */ { MAD_F(0x06bf63d1) /* 0.421726054 */, 17 }, /* 3606 */ { MAD_F(0x06c00761) /* 0.421882040 */, 17 }, /* 3607 */ { MAD_F(0x06c0aaf5) /* 0.422038039 */, 17 }, /* 3608 */ { MAD_F(0x06c14e8d) /* 0.422194054 */, 17 }, /* 3609 */ { MAD_F(0x06c1f229) /* 0.422350082 */, 17 }, /* 3610 */ { MAD_F(0x06c295c8) /* 0.422506125 */, 17 }, /* 3611 */ { MAD_F(0x06c3396c) /* 0.422662183 */, 17 }, /* 3612 */ { MAD_F(0x06c3dd13) /* 0.422818255 */, 17 }, /* 3613 */ { MAD_F(0x06c480be) /* 0.422974341 */, 17 }, /* 3614 */ { MAD_F(0x06c5246d) /* 0.423130442 */, 17 }, /* 3615 */ { MAD_F(0x06c5c820) /* 0.423286557 */, 17 }, /* 3616 */ { MAD_F(0x06c66bd6) /* 0.423442686 */, 17 }, /* 3617 */ { MAD_F(0x06c70f91) /* 0.423598830 */, 17 }, /* 3618 */ { MAD_F(0x06c7b34f) /* 0.423754988 */, 17 }, /* 3619 */ { MAD_F(0x06c85712) /* 0.423911161 */, 17 }, /* 3620 */ { MAD_F(0x06c8fad8) /* 0.424067348 */, 17 }, /* 3621 */ { MAD_F(0x06c99ea2) /* 0.424223550 */, 17 }, /* 3622 */ { MAD_F(0x06ca4270) /* 0.424379765 */, 17 }, /* 3623 */ { MAD_F(0x06cae641) /* 0.424535996 */, 17 }, /* 3624 */ { MAD_F(0x06cb8a17) /* 0.424692240 */, 17 }, /* 3625 */ { MAD_F(0x06cc2df0) /* 0.424848499 */, 17 }, /* 3626 */ { MAD_F(0x06ccd1ce) /* 0.425004772 */, 17 }, /* 3627 */ { MAD_F(0x06cd75af) /* 0.425161060 */, 17 }, /* 3628 */ { MAD_F(0x06ce1994) /* 0.425317362 */, 17 }, /* 3629 */ { MAD_F(0x06cebd7d) /* 0.425473678 */, 17 }, /* 3630 */ { MAD_F(0x06cf6169) /* 0.425630009 */, 17 }, /* 3631 */ { MAD_F(0x06d0055a) /* 0.425786354 */, 17 }, /* 3632 */ { MAD_F(0x06d0a94e) /* 0.425942714 */, 17 }, /* 3633 */ { MAD_F(0x06d14d47) /* 0.426099088 */, 17 }, /* 3634 */ { MAD_F(0x06d1f143) /* 0.426255476 */, 17 }, /* 3635 */ { MAD_F(0x06d29543) /* 0.426411878 */, 17 }, /* 3636 */ { MAD_F(0x06d33947) /* 0.426568295 */, 17 }, /* 3637 */ { MAD_F(0x06d3dd4e) /* 0.426724726 */, 17 }, /* 3638 */ { MAD_F(0x06d4815a) /* 0.426881172 */, 17 }, /* 3639 */ { MAD_F(0x06d52569) /* 0.427037632 */, 17 }, /* 3640 */ { MAD_F(0x06d5c97c) /* 0.427194106 */, 17 }, /* 3641 */ { MAD_F(0x06d66d93) /* 0.427350594 */, 17 }, /* 3642 */ { MAD_F(0x06d711ae) /* 0.427507097 */, 17 }, /* 3643 */ { MAD_F(0x06d7b5cd) /* 0.427663614 */, 17 }, /* 3644 */ { MAD_F(0x06d859f0) /* 0.427820146 */, 17 }, /* 3645 */ { MAD_F(0x06d8fe16) /* 0.427976692 */, 17 }, /* 3646 */ { MAD_F(0x06d9a240) /* 0.428133252 */, 17 }, /* 3647 */ { MAD_F(0x06da466f) /* 0.428289826 */, 17 }, /* 3648 */ { MAD_F(0x06daeaa1) /* 0.428446415 */, 17 }, /* 3649 */ { MAD_F(0x06db8ed6) /* 0.428603018 */, 17 }, /* 3650 */ { MAD_F(0x06dc3310) /* 0.428759635 */, 17 }, /* 3651 */ { MAD_F(0x06dcd74d) /* 0.428916267 */, 17 }, /* 3652 */ { MAD_F(0x06dd7b8f) /* 0.429072913 */, 17 }, /* 3653 */ { MAD_F(0x06de1fd4) /* 0.429229573 */, 17 }, /* 3654 */ { MAD_F(0x06dec41d) /* 0.429386248 */, 17 }, /* 3655 */ { MAD_F(0x06df686a) /* 0.429542937 */, 17 }, /* 3656 */ { MAD_F(0x06e00cbb) /* 0.429699640 */, 17 }, /* 3657 */ { MAD_F(0x06e0b10f) /* 0.429856357 */, 17 }, /* 3658 */ { MAD_F(0x06e15567) /* 0.430013089 */, 17 }, /* 3659 */ { MAD_F(0x06e1f9c4) /* 0.430169835 */, 17 }, /* 3660 */ { MAD_F(0x06e29e24) /* 0.430326595 */, 17 }, /* 3661 */ { MAD_F(0x06e34287) /* 0.430483370 */, 17 }, /* 3662 */ { MAD_F(0x06e3e6ef) /* 0.430640159 */, 17 }, /* 3663 */ { MAD_F(0x06e48b5b) /* 0.430796962 */, 17 }, /* 3664 */ { MAD_F(0x06e52fca) /* 0.430953779 */, 17 }, /* 3665 */ { MAD_F(0x06e5d43d) /* 0.431110611 */, 17 }, /* 3666 */ { MAD_F(0x06e678b4) /* 0.431267457 */, 17 }, /* 3667 */ { MAD_F(0x06e71d2f) /* 0.431424317 */, 17 }, /* 3668 */ { MAD_F(0x06e7c1ae) /* 0.431581192 */, 17 }, /* 3669 */ { MAD_F(0x06e86630) /* 0.431738080 */, 17 }, /* 3670 */ { MAD_F(0x06e90ab7) /* 0.431894983 */, 17 }, /* 3671 */ { MAD_F(0x06e9af41) /* 0.432051900 */, 17 }, /* 3672 */ { MAD_F(0x06ea53cf) /* 0.432208832 */, 17 }, /* 3673 */ { MAD_F(0x06eaf860) /* 0.432365778 */, 17 }, /* 3674 */ { MAD_F(0x06eb9cf6) /* 0.432522737 */, 17 }, /* 3675 */ { MAD_F(0x06ec418f) /* 0.432679712 */, 17 }, /* 3676 */ { MAD_F(0x06ece62d) /* 0.432836700 */, 17 }, /* 3677 */ { MAD_F(0x06ed8ace) /* 0.432993703 */, 17 }, /* 3678 */ { MAD_F(0x06ee2f73) /* 0.433150720 */, 17 }, /* 3679 */ { MAD_F(0x06eed41b) /* 0.433307751 */, 17 }, /* 3680 */ { MAD_F(0x06ef78c8) /* 0.433464796 */, 17 }, /* 3681 */ { MAD_F(0x06f01d78) /* 0.433621856 */, 17 }, /* 3682 */ { MAD_F(0x06f0c22c) /* 0.433778929 */, 17 }, /* 3683 */ { MAD_F(0x06f166e4) /* 0.433936017 */, 17 }, /* 3684 */ { MAD_F(0x06f20ba0) /* 0.434093120 */, 17 }, /* 3685 */ { MAD_F(0x06f2b060) /* 0.434250236 */, 17 }, /* 3686 */ { MAD_F(0x06f35523) /* 0.434407367 */, 17 }, /* 3687 */ { MAD_F(0x06f3f9eb) /* 0.434564512 */, 17 }, /* 3688 */ { MAD_F(0x06f49eb6) /* 0.434721671 */, 17 }, /* 3689 */ { MAD_F(0x06f54385) /* 0.434878844 */, 17 }, /* 3690 */ { MAD_F(0x06f5e857) /* 0.435036032 */, 17 }, /* 3691 */ { MAD_F(0x06f68d2e) /* 0.435193233 */, 17 }, /* 3692 */ { MAD_F(0x06f73208) /* 0.435350449 */, 17 }, /* 3693 */ { MAD_F(0x06f7d6e6) /* 0.435507679 */, 17 }, /* 3694 */ { MAD_F(0x06f87bc8) /* 0.435664924 */, 17 }, /* 3695 */ { MAD_F(0x06f920ae) /* 0.435822182 */, 17 }, /* 3696 */ { MAD_F(0x06f9c597) /* 0.435979455 */, 17 }, /* 3697 */ { MAD_F(0x06fa6a85) /* 0.436136741 */, 17 }, /* 3698 */ { MAD_F(0x06fb0f76) /* 0.436294042 */, 17 }, /* 3699 */ { MAD_F(0x06fbb46b) /* 0.436451358 */, 17 }, /* 3700 */ { MAD_F(0x06fc5964) /* 0.436608687 */, 17 }, /* 3701 */ { MAD_F(0x06fcfe60) /* 0.436766031 */, 17 }, /* 3702 */ { MAD_F(0x06fda361) /* 0.436923388 */, 17 }, /* 3703 */ { MAD_F(0x06fe4865) /* 0.437080760 */, 17 }, /* 3704 */ { MAD_F(0x06feed6d) /* 0.437238146 */, 17 }, /* 3705 */ { MAD_F(0x06ff9279) /* 0.437395547 */, 17 }, /* 3706 */ { MAD_F(0x07003788) /* 0.437552961 */, 17 }, /* 3707 */ { MAD_F(0x0700dc9c) /* 0.437710389 */, 17 }, /* 3708 */ { MAD_F(0x070181b3) /* 0.437867832 */, 17 }, /* 3709 */ { MAD_F(0x070226ce) /* 0.438025289 */, 17 }, /* 3710 */ { MAD_F(0x0702cbed) /* 0.438182760 */, 17 }, /* 3711 */ { MAD_F(0x0703710f) /* 0.438340245 */, 17 }, /* 3712 */ { MAD_F(0x07041636) /* 0.438497744 */, 17 }, /* 3713 */ { MAD_F(0x0704bb60) /* 0.438655258 */, 17 }, /* 3714 */ { MAD_F(0x0705608e) /* 0.438812785 */, 17 }, /* 3715 */ { MAD_F(0x070605c0) /* 0.438970327 */, 17 }, /* 3716 */ { MAD_F(0x0706aaf5) /* 0.439127883 */, 17 }, /* 3717 */ { MAD_F(0x0707502f) /* 0.439285453 */, 17 }, /* 3718 */ { MAD_F(0x0707f56c) /* 0.439443037 */, 17 }, /* 3719 */ { MAD_F(0x07089aad) /* 0.439600635 */, 17 }, /* 3720 */ { MAD_F(0x07093ff2) /* 0.439758248 */, 17 }, /* 3721 */ { MAD_F(0x0709e53a) /* 0.439915874 */, 17 }, /* 3722 */ { MAD_F(0x070a8a86) /* 0.440073515 */, 17 }, /* 3723 */ { MAD_F(0x070b2fd7) /* 0.440231170 */, 17 }, /* 3724 */ { MAD_F(0x070bd52a) /* 0.440388839 */, 17 }, /* 3725 */ { MAD_F(0x070c7a82) /* 0.440546522 */, 17 }, /* 3726 */ { MAD_F(0x070d1fde) /* 0.440704219 */, 17 }, /* 3727 */ { MAD_F(0x070dc53d) /* 0.440861930 */, 17 }, /* 3728 */ { MAD_F(0x070e6aa0) /* 0.441019655 */, 17 }, /* 3729 */ { MAD_F(0x070f1007) /* 0.441177395 */, 17 }, /* 3730 */ { MAD_F(0x070fb571) /* 0.441335148 */, 17 }, /* 3731 */ { MAD_F(0x07105ae0) /* 0.441492916 */, 17 }, /* 3732 */ { MAD_F(0x07110052) /* 0.441650697 */, 17 }, /* 3733 */ { MAD_F(0x0711a5c8) /* 0.441808493 */, 17 }, /* 3734 */ { MAD_F(0x07124b42) /* 0.441966303 */, 17 }, /* 3735 */ { MAD_F(0x0712f0bf) /* 0.442124127 */, 17 }, /* 3736 */ { MAD_F(0x07139641) /* 0.442281965 */, 17 }, /* 3737 */ { MAD_F(0x07143bc6) /* 0.442439817 */, 17 }, /* 3738 */ { MAD_F(0x0714e14f) /* 0.442597683 */, 17 }, /* 3739 */ { MAD_F(0x071586db) /* 0.442755564 */, 17 }, /* 3740 */ { MAD_F(0x07162c6c) /* 0.442913458 */, 17 }, /* 3741 */ { MAD_F(0x0716d200) /* 0.443071366 */, 17 }, /* 3742 */ { MAD_F(0x07177798) /* 0.443229289 */, 17 }, /* 3743 */ { MAD_F(0x07181d34) /* 0.443387226 */, 17 }, /* 3744 */ { MAD_F(0x0718c2d3) /* 0.443545176 */, 17 }, /* 3745 */ { MAD_F(0x07196877) /* 0.443703141 */, 17 }, /* 3746 */ { MAD_F(0x071a0e1e) /* 0.443861120 */, 17 }, /* 3747 */ { MAD_F(0x071ab3c9) /* 0.444019113 */, 17 }, /* 3748 */ { MAD_F(0x071b5977) /* 0.444177119 */, 17 }, /* 3749 */ { MAD_F(0x071bff2a) /* 0.444335140 */, 17 }, /* 3750 */ { MAD_F(0x071ca4e0) /* 0.444493175 */, 17 }, /* 3751 */ { MAD_F(0x071d4a9a) /* 0.444651224 */, 17 }, /* 3752 */ { MAD_F(0x071df058) /* 0.444809288 */, 17 }, /* 3753 */ { MAD_F(0x071e9619) /* 0.444967365 */, 17 }, /* 3754 */ { MAD_F(0x071f3bde) /* 0.445125456 */, 17 }, /* 3755 */ { MAD_F(0x071fe1a8) /* 0.445283561 */, 17 }, /* 3756 */ { MAD_F(0x07208774) /* 0.445441680 */, 17 }, /* 3757 */ { MAD_F(0x07212d45) /* 0.445599814 */, 17 }, /* 3758 */ { MAD_F(0x0721d319) /* 0.445757961 */, 17 }, /* 3759 */ { MAD_F(0x072278f1) /* 0.445916122 */, 17 }, /* 3760 */ { MAD_F(0x07231ecd) /* 0.446074298 */, 17 }, /* 3761 */ { MAD_F(0x0723c4ad) /* 0.446232487 */, 17 }, /* 3762 */ { MAD_F(0x07246a90) /* 0.446390690 */, 17 }, /* 3763 */ { MAD_F(0x07251077) /* 0.446548908 */, 17 }, /* 3764 */ { MAD_F(0x0725b662) /* 0.446707139 */, 17 }, /* 3765 */ { MAD_F(0x07265c51) /* 0.446865385 */, 17 }, /* 3766 */ { MAD_F(0x07270244) /* 0.447023644 */, 17 }, /* 3767 */ { MAD_F(0x0727a83a) /* 0.447181918 */, 17 }, /* 3768 */ { MAD_F(0x07284e34) /* 0.447340205 */, 17 }, /* 3769 */ { MAD_F(0x0728f431) /* 0.447498507 */, 17 }, /* 3770 */ { MAD_F(0x07299a33) /* 0.447656822 */, 17 }, /* 3771 */ { MAD_F(0x072a4038) /* 0.447815152 */, 17 }, /* 3772 */ { MAD_F(0x072ae641) /* 0.447973495 */, 17 }, /* 3773 */ { MAD_F(0x072b8c4e) /* 0.448131853 */, 17 }, /* 3774 */ { MAD_F(0x072c325e) /* 0.448290224 */, 17 }, /* 3775 */ { MAD_F(0x072cd873) /* 0.448448609 */, 17 }, /* 3776 */ { MAD_F(0x072d7e8b) /* 0.448607009 */, 17 }, /* 3777 */ { MAD_F(0x072e24a7) /* 0.448765422 */, 17 }, /* 3778 */ { MAD_F(0x072ecac6) /* 0.448923850 */, 17 }, /* 3779 */ { MAD_F(0x072f70e9) /* 0.449082291 */, 17 }, /* 3780 */ { MAD_F(0x07301710) /* 0.449240746 */, 17 }, /* 3781 */ { MAD_F(0x0730bd3b) /* 0.449399216 */, 17 }, /* 3782 */ { MAD_F(0x0731636a) /* 0.449557699 */, 17 }, /* 3783 */ { MAD_F(0x0732099c) /* 0.449716196 */, 17 }, /* 3784 */ { MAD_F(0x0732afd2) /* 0.449874708 */, 17 }, /* 3785 */ { MAD_F(0x0733560c) /* 0.450033233 */, 17 }, /* 3786 */ { MAD_F(0x0733fc49) /* 0.450191772 */, 17 }, /* 3787 */ { MAD_F(0x0734a28b) /* 0.450350325 */, 17 }, /* 3788 */ { MAD_F(0x073548d0) /* 0.450508892 */, 17 }, /* 3789 */ { MAD_F(0x0735ef18) /* 0.450667473 */, 17 }, /* 3790 */ { MAD_F(0x07369565) /* 0.450826068 */, 17 }, /* 3791 */ { MAD_F(0x07373bb5) /* 0.450984677 */, 17 }, /* 3792 */ { MAD_F(0x0737e209) /* 0.451143300 */, 17 }, /* 3793 */ { MAD_F(0x07388861) /* 0.451301937 */, 17 }, /* 3794 */ { MAD_F(0x07392ebc) /* 0.451460588 */, 17 }, /* 3795 */ { MAD_F(0x0739d51c) /* 0.451619252 */, 17 }, /* 3796 */ { MAD_F(0x073a7b7f) /* 0.451777931 */, 17 }, /* 3797 */ { MAD_F(0x073b21e5) /* 0.451936623 */, 17 }, /* 3798 */ { MAD_F(0x073bc850) /* 0.452095330 */, 17 }, /* 3799 */ { MAD_F(0x073c6ebe) /* 0.452254050 */, 17 }, /* 3800 */ { MAD_F(0x073d1530) /* 0.452412785 */, 17 }, /* 3801 */ { MAD_F(0x073dbba6) /* 0.452571533 */, 17 }, /* 3802 */ { MAD_F(0x073e621f) /* 0.452730295 */, 17 }, /* 3803 */ { MAD_F(0x073f089c) /* 0.452889071 */, 17 }, /* 3804 */ { MAD_F(0x073faf1d) /* 0.453047861 */, 17 }, /* 3805 */ { MAD_F(0x074055a2) /* 0.453206665 */, 17 }, /* 3806 */ { MAD_F(0x0740fc2a) /* 0.453365483 */, 17 }, /* 3807 */ { MAD_F(0x0741a2b6) /* 0.453524315 */, 17 }, /* 3808 */ { MAD_F(0x07424946) /* 0.453683161 */, 17 }, /* 3809 */ { MAD_F(0x0742efd9) /* 0.453842020 */, 17 }, /* 3810 */ { MAD_F(0x07439671) /* 0.454000894 */, 17 }, /* 3811 */ { MAD_F(0x07443d0c) /* 0.454159781 */, 17 }, /* 3812 */ { MAD_F(0x0744e3aa) /* 0.454318683 */, 17 }, /* 3813 */ { MAD_F(0x07458a4d) /* 0.454477598 */, 17 }, /* 3814 */ { MAD_F(0x074630f3) /* 0.454636527 */, 17 }, /* 3815 */ { MAD_F(0x0746d79d) /* 0.454795470 */, 17 }, /* 3816 */ { MAD_F(0x07477e4b) /* 0.454954427 */, 17 }, /* 3817 */ { MAD_F(0x074824fc) /* 0.455113397 */, 17 }, /* 3818 */ { MAD_F(0x0748cbb1) /* 0.455272382 */, 17 }, /* 3819 */ { MAD_F(0x0749726a) /* 0.455431381 */, 17 }, /* 3820 */ { MAD_F(0x074a1927) /* 0.455590393 */, 17 }, /* 3821 */ { MAD_F(0x074abfe7) /* 0.455749419 */, 17 }, /* 3822 */ { MAD_F(0x074b66ab) /* 0.455908459 */, 17 }, /* 3823 */ { MAD_F(0x074c0d73) /* 0.456067513 */, 17 }, /* 3824 */ { MAD_F(0x074cb43e) /* 0.456226581 */, 17 }, /* 3825 */ { MAD_F(0x074d5b0d) /* 0.456385663 */, 17 }, /* 3826 */ { MAD_F(0x074e01e0) /* 0.456544759 */, 17 }, /* 3827 */ { MAD_F(0x074ea8b7) /* 0.456703868 */, 17 }, /* 3828 */ { MAD_F(0x074f4f91) /* 0.456862992 */, 17 }, /* 3829 */ { MAD_F(0x074ff66f) /* 0.457022129 */, 17 }, /* 3830 */ { MAD_F(0x07509d51) /* 0.457181280 */, 17 }, /* 3831 */ { MAD_F(0x07514437) /* 0.457340445 */, 17 }, /* 3832 */ { MAD_F(0x0751eb20) /* 0.457499623 */, 17 }, /* 3833 */ { MAD_F(0x0752920d) /* 0.457658816 */, 17 }, /* 3834 */ { MAD_F(0x075338fd) /* 0.457818022 */, 17 }, /* 3835 */ { MAD_F(0x0753dff2) /* 0.457977243 */, 17 }, /* 3836 */ { MAD_F(0x075486ea) /* 0.458136477 */, 17 }, /* 3837 */ { MAD_F(0x07552de6) /* 0.458295725 */, 17 }, /* 3838 */ { MAD_F(0x0755d4e5) /* 0.458454987 */, 17 }, /* 3839 */ { MAD_F(0x07567be8) /* 0.458614262 */, 17 }, /* 3840 */ { MAD_F(0x075722ef) /* 0.458773552 */, 17 }, /* 3841 */ { MAD_F(0x0757c9fa) /* 0.458932855 */, 17 }, /* 3842 */ { MAD_F(0x07587108) /* 0.459092172 */, 17 }, /* 3843 */ { MAD_F(0x0759181a) /* 0.459251503 */, 17 }, /* 3844 */ { MAD_F(0x0759bf30) /* 0.459410848 */, 17 }, /* 3845 */ { MAD_F(0x075a664a) /* 0.459570206 */, 17 }, /* 3846 */ { MAD_F(0x075b0d67) /* 0.459729579 */, 17 }, /* 3847 */ { MAD_F(0x075bb488) /* 0.459888965 */, 17 }, /* 3848 */ { MAD_F(0x075c5bac) /* 0.460048365 */, 17 }, /* 3849 */ { MAD_F(0x075d02d5) /* 0.460207779 */, 17 }, /* 3850 */ { MAD_F(0x075daa01) /* 0.460367206 */, 17 }, /* 3851 */ { MAD_F(0x075e5130) /* 0.460526648 */, 17 }, /* 3852 */ { MAD_F(0x075ef864) /* 0.460686103 */, 17 }, /* 3853 */ { MAD_F(0x075f9f9b) /* 0.460845572 */, 17 }, /* 3854 */ { MAD_F(0x076046d6) /* 0.461005055 */, 17 }, /* 3855 */ { MAD_F(0x0760ee14) /* 0.461164552 */, 17 }, /* 3856 */ { MAD_F(0x07619557) /* 0.461324062 */, 17 }, /* 3857 */ { MAD_F(0x07623c9d) /* 0.461483586 */, 17 }, /* 3858 */ { MAD_F(0x0762e3e6) /* 0.461643124 */, 17 }, /* 3859 */ { MAD_F(0x07638b34) /* 0.461802676 */, 17 }, /* 3860 */ { MAD_F(0x07643285) /* 0.461962242 */, 17 }, /* 3861 */ { MAD_F(0x0764d9d9) /* 0.462121821 */, 17 }, /* 3862 */ { MAD_F(0x07658132) /* 0.462281414 */, 17 }, /* 3863 */ { MAD_F(0x0766288e) /* 0.462441021 */, 17 }, /* 3864 */ { MAD_F(0x0766cfee) /* 0.462600642 */, 17 }, /* 3865 */ { MAD_F(0x07677751) /* 0.462760276 */, 17 }, /* 3866 */ { MAD_F(0x07681eb9) /* 0.462919924 */, 17 }, /* 3867 */ { MAD_F(0x0768c624) /* 0.463079586 */, 17 }, /* 3868 */ { MAD_F(0x07696d92) /* 0.463239262 */, 17 }, /* 3869 */ { MAD_F(0x076a1505) /* 0.463398951 */, 17 }, /* 3870 */ { MAD_F(0x076abc7b) /* 0.463558655 */, 17 }, /* 3871 */ { MAD_F(0x076b63f4) /* 0.463718372 */, 17 }, /* 3872 */ { MAD_F(0x076c0b72) /* 0.463878102 */, 17 }, /* 3873 */ { MAD_F(0x076cb2f3) /* 0.464037847 */, 17 }, /* 3874 */ { MAD_F(0x076d5a78) /* 0.464197605 */, 17 }, /* 3875 */ { MAD_F(0x076e0200) /* 0.464357377 */, 17 }, /* 3876 */ { MAD_F(0x076ea98c) /* 0.464517163 */, 17 }, /* 3877 */ { MAD_F(0x076f511c) /* 0.464676962 */, 17 }, /* 3878 */ { MAD_F(0x076ff8b0) /* 0.464836776 */, 17 }, /* 3879 */ { MAD_F(0x0770a047) /* 0.464996603 */, 17 }, /* 3880 */ { MAD_F(0x077147e2) /* 0.465156443 */, 17 }, /* 3881 */ { MAD_F(0x0771ef80) /* 0.465316298 */, 17 }, /* 3882 */ { MAD_F(0x07729723) /* 0.465476166 */, 17 }, /* 3883 */ { MAD_F(0x07733ec9) /* 0.465636048 */, 17 }, /* 3884 */ { MAD_F(0x0773e672) /* 0.465795943 */, 17 }, /* 3885 */ { MAD_F(0x07748e20) /* 0.465955853 */, 17 }, /* 3886 */ { MAD_F(0x077535d1) /* 0.466115776 */, 17 }, /* 3887 */ { MAD_F(0x0775dd85) /* 0.466275713 */, 17 }, /* 3888 */ { MAD_F(0x0776853e) /* 0.466435663 */, 17 }, /* 3889 */ { MAD_F(0x07772cfa) /* 0.466595627 */, 17 }, /* 3890 */ { MAD_F(0x0777d4ba) /* 0.466755605 */, 17 }, /* 3891 */ { MAD_F(0x07787c7d) /* 0.466915597 */, 17 }, /* 3892 */ { MAD_F(0x07792444) /* 0.467075602 */, 17 }, /* 3893 */ { MAD_F(0x0779cc0f) /* 0.467235621 */, 17 }, /* 3894 */ { MAD_F(0x077a73dd) /* 0.467395654 */, 17 }, /* 3895 */ { MAD_F(0x077b1baf) /* 0.467555701 */, 17 }, /* 3896 */ { MAD_F(0x077bc385) /* 0.467715761 */, 17 }, /* 3897 */ { MAD_F(0x077c6b5f) /* 0.467875835 */, 17 }, /* 3898 */ { MAD_F(0x077d133c) /* 0.468035922 */, 17 }, /* 3899 */ { MAD_F(0x077dbb1d) /* 0.468196023 */, 17 }, /* 3900 */ { MAD_F(0x077e6301) /* 0.468356138 */, 17 }, /* 3901 */ { MAD_F(0x077f0ae9) /* 0.468516267 */, 17 }, /* 3902 */ { MAD_F(0x077fb2d5) /* 0.468676409 */, 17 }, /* 3903 */ { MAD_F(0x07805ac5) /* 0.468836565 */, 17 }, /* 3904 */ { MAD_F(0x078102b8) /* 0.468996735 */, 17 }, /* 3905 */ { MAD_F(0x0781aaaf) /* 0.469156918 */, 17 }, /* 3906 */ { MAD_F(0x078252aa) /* 0.469317115 */, 17 }, /* 3907 */ { MAD_F(0x0782faa8) /* 0.469477326 */, 17 }, /* 3908 */ { MAD_F(0x0783a2aa) /* 0.469637550 */, 17 }, /* 3909 */ { MAD_F(0x07844aaf) /* 0.469797788 */, 17 }, /* 3910 */ { MAD_F(0x0784f2b8) /* 0.469958040 */, 17 }, /* 3911 */ { MAD_F(0x07859ac5) /* 0.470118305 */, 17 }, /* 3912 */ { MAD_F(0x078642d6) /* 0.470278584 */, 17 }, /* 3913 */ { MAD_F(0x0786eaea) /* 0.470438877 */, 17 }, /* 3914 */ { MAD_F(0x07879302) /* 0.470599183 */, 17 }, /* 3915 */ { MAD_F(0x07883b1e) /* 0.470759503 */, 17 }, /* 3916 */ { MAD_F(0x0788e33d) /* 0.470919836 */, 17 }, /* 3917 */ { MAD_F(0x07898b60) /* 0.471080184 */, 17 }, /* 3918 */ { MAD_F(0x078a3386) /* 0.471240545 */, 17 }, /* 3919 */ { MAD_F(0x078adbb0) /* 0.471400919 */, 17 }, /* 3920 */ { MAD_F(0x078b83de) /* 0.471561307 */, 17 }, /* 3921 */ { MAD_F(0x078c2c10) /* 0.471721709 */, 17 }, /* 3922 */ { MAD_F(0x078cd445) /* 0.471882125 */, 17 }, /* 3923 */ { MAD_F(0x078d7c7e) /* 0.472042554 */, 17 }, /* 3924 */ { MAD_F(0x078e24ba) /* 0.472202996 */, 17 }, /* 3925 */ { MAD_F(0x078eccfb) /* 0.472363453 */, 17 }, /* 3926 */ { MAD_F(0x078f753e) /* 0.472523923 */, 17 }, /* 3927 */ { MAD_F(0x07901d86) /* 0.472684406 */, 17 }, /* 3928 */ { MAD_F(0x0790c5d1) /* 0.472844904 */, 17 }, /* 3929 */ { MAD_F(0x07916e20) /* 0.473005414 */, 17 }, /* 3930 */ { MAD_F(0x07921672) /* 0.473165939 */, 17 }, /* 3931 */ { MAD_F(0x0792bec8) /* 0.473326477 */, 17 }, /* 3932 */ { MAD_F(0x07936722) /* 0.473487029 */, 17 }, /* 3933 */ { MAD_F(0x07940f80) /* 0.473647594 */, 17 }, /* 3934 */ { MAD_F(0x0794b7e1) /* 0.473808173 */, 17 }, /* 3935 */ { MAD_F(0x07956045) /* 0.473968765 */, 17 }, /* 3936 */ { MAD_F(0x079608ae) /* 0.474129372 */, 17 }, /* 3937 */ { MAD_F(0x0796b11a) /* 0.474289991 */, 17 }, /* 3938 */ { MAD_F(0x0797598a) /* 0.474450625 */, 17 }, /* 3939 */ { MAD_F(0x079801fd) /* 0.474611272 */, 17 }, /* 3940 */ { MAD_F(0x0798aa74) /* 0.474771932 */, 17 }, /* 3941 */ { MAD_F(0x079952ee) /* 0.474932606 */, 17 }, /* 3942 */ { MAD_F(0x0799fb6d) /* 0.475093294 */, 17 }, /* 3943 */ { MAD_F(0x079aa3ef) /* 0.475253995 */, 17 }, /* 3944 */ { MAD_F(0x079b4c74) /* 0.475414710 */, 17 }, /* 3945 */ { MAD_F(0x079bf4fd) /* 0.475575439 */, 17 }, /* 3946 */ { MAD_F(0x079c9d8a) /* 0.475736181 */, 17 }, /* 3947 */ { MAD_F(0x079d461b) /* 0.475896936 */, 17 }, /* 3948 */ { MAD_F(0x079deeaf) /* 0.476057705 */, 17 }, /* 3949 */ { MAD_F(0x079e9747) /* 0.476218488 */, 17 }, /* 3950 */ { MAD_F(0x079f3fe2) /* 0.476379285 */, 17 }, /* 3951 */ { MAD_F(0x079fe881) /* 0.476540095 */, 17 }, /* 3952 */ { MAD_F(0x07a09124) /* 0.476700918 */, 17 }, /* 3953 */ { MAD_F(0x07a139ca) /* 0.476861755 */, 17 }, /* 3954 */ { MAD_F(0x07a1e274) /* 0.477022606 */, 17 }, /* 3955 */ { MAD_F(0x07a28b22) /* 0.477183470 */, 17 }, /* 3956 */ { MAD_F(0x07a333d3) /* 0.477344348 */, 17 }, /* 3957 */ { MAD_F(0x07a3dc88) /* 0.477505239 */, 17 }, /* 3958 */ { MAD_F(0x07a48541) /* 0.477666144 */, 17 }, /* 3959 */ { MAD_F(0x07a52dfd) /* 0.477827062 */, 17 }, /* 3960 */ { MAD_F(0x07a5d6bd) /* 0.477987994 */, 17 }, /* 3961 */ { MAD_F(0x07a67f80) /* 0.478148940 */, 17 }, /* 3962 */ { MAD_F(0x07a72847) /* 0.478309899 */, 17 }, /* 3963 */ { MAD_F(0x07a7d112) /* 0.478470871 */, 17 }, /* 3964 */ { MAD_F(0x07a879e1) /* 0.478631857 */, 17 }, /* 3965 */ { MAD_F(0x07a922b3) /* 0.478792857 */, 17 }, /* 3966 */ { MAD_F(0x07a9cb88) /* 0.478953870 */, 17 }, /* 3967 */ { MAD_F(0x07aa7462) /* 0.479114897 */, 17 }, /* 3968 */ { MAD_F(0x07ab1d3e) /* 0.479275937 */, 17 }, /* 3969 */ { MAD_F(0x07abc61f) /* 0.479436991 */, 17 }, /* 3970 */ { MAD_F(0x07ac6f03) /* 0.479598058 */, 17 }, /* 3971 */ { MAD_F(0x07ad17eb) /* 0.479759139 */, 17 }, /* 3972 */ { MAD_F(0x07adc0d6) /* 0.479920233 */, 17 }, /* 3973 */ { MAD_F(0x07ae69c6) /* 0.480081341 */, 17 }, /* 3974 */ { MAD_F(0x07af12b8) /* 0.480242463 */, 17 }, /* 3975 */ { MAD_F(0x07afbbaf) /* 0.480403598 */, 17 }, /* 3976 */ { MAD_F(0x07b064a8) /* 0.480564746 */, 17 }, /* 3977 */ { MAD_F(0x07b10da6) /* 0.480725908 */, 17 }, /* 3978 */ { MAD_F(0x07b1b6a7) /* 0.480887083 */, 17 }, /* 3979 */ { MAD_F(0x07b25fac) /* 0.481048272 */, 17 }, /* 3980 */ { MAD_F(0x07b308b5) /* 0.481209475 */, 17 }, /* 3981 */ { MAD_F(0x07b3b1c1) /* 0.481370691 */, 17 }, /* 3982 */ { MAD_F(0x07b45ad0) /* 0.481531920 */, 17 }, /* 3983 */ { MAD_F(0x07b503e4) /* 0.481693163 */, 17 }, /* 3984 */ { MAD_F(0x07b5acfb) /* 0.481854420 */, 17 }, /* 3985 */ { MAD_F(0x07b65615) /* 0.482015690 */, 17 }, /* 3986 */ { MAD_F(0x07b6ff33) /* 0.482176973 */, 17 }, /* 3987 */ { MAD_F(0x07b7a855) /* 0.482338270 */, 17 }, /* 3988 */ { MAD_F(0x07b8517b) /* 0.482499580 */, 17 }, /* 3989 */ { MAD_F(0x07b8faa4) /* 0.482660904 */, 17 }, /* 3990 */ { MAD_F(0x07b9a3d0) /* 0.482822242 */, 17 }, /* 3991 */ { MAD_F(0x07ba4d01) /* 0.482983592 */, 17 }, /* 3992 */ { MAD_F(0x07baf635) /* 0.483144957 */, 17 }, /* 3993 */ { MAD_F(0x07bb9f6c) /* 0.483306335 */, 17 }, /* 3994 */ { MAD_F(0x07bc48a7) /* 0.483467726 */, 17 }, /* 3995 */ { MAD_F(0x07bcf1e6) /* 0.483629131 */, 17 }, /* 3996 */ { MAD_F(0x07bd9b28) /* 0.483790549 */, 17 }, /* 3997 */ { MAD_F(0x07be446e) /* 0.483951980 */, 17 }, /* 3998 */ { MAD_F(0x07beedb8) /* 0.484113426 */, 17 }, /* 3999 */ { MAD_F(0x07bf9705) /* 0.484274884 */, 17 }, /* 4000 */ { MAD_F(0x07c04056) /* 0.484436356 */, 17 }, /* 4001 */ { MAD_F(0x07c0e9aa) /* 0.484597842 */, 17 }, /* 4002 */ { MAD_F(0x07c19302) /* 0.484759341 */, 17 }, /* 4003 */ { MAD_F(0x07c23c5e) /* 0.484920853 */, 17 }, /* 4004 */ { MAD_F(0x07c2e5bd) /* 0.485082379 */, 17 }, /* 4005 */ { MAD_F(0x07c38f20) /* 0.485243918 */, 17 }, /* 4006 */ { MAD_F(0x07c43887) /* 0.485405471 */, 17 }, /* 4007 */ { MAD_F(0x07c4e1f1) /* 0.485567037 */, 17 }, /* 4008 */ { MAD_F(0x07c58b5f) /* 0.485728617 */, 17 }, /* 4009 */ { MAD_F(0x07c634d0) /* 0.485890210 */, 17 }, /* 4010 */ { MAD_F(0x07c6de45) /* 0.486051817 */, 17 }, /* 4011 */ { MAD_F(0x07c787bd) /* 0.486213436 */, 17 }, /* 4012 */ { MAD_F(0x07c83139) /* 0.486375070 */, 17 }, /* 4013 */ { MAD_F(0x07c8dab9) /* 0.486536717 */, 17 }, /* 4014 */ { MAD_F(0x07c9843c) /* 0.486698377 */, 17 }, /* 4015 */ { MAD_F(0x07ca2dc3) /* 0.486860051 */, 17 }, /* 4016 */ { MAD_F(0x07cad74e) /* 0.487021738 */, 17 }, /* 4017 */ { MAD_F(0x07cb80dc) /* 0.487183438 */, 17 }, /* 4018 */ { MAD_F(0x07cc2a6e) /* 0.487345152 */, 17 }, /* 4019 */ { MAD_F(0x07ccd403) /* 0.487506879 */, 17 }, /* 4020 */ { MAD_F(0x07cd7d9c) /* 0.487668620 */, 17 }, /* 4021 */ { MAD_F(0x07ce2739) /* 0.487830374 */, 17 }, /* 4022 */ { MAD_F(0x07ced0d9) /* 0.487992142 */, 17 }, /* 4023 */ { MAD_F(0x07cf7a7d) /* 0.488153923 */, 17 }, /* 4024 */ { MAD_F(0x07d02424) /* 0.488315717 */, 17 }, /* 4025 */ { MAD_F(0x07d0cdcf) /* 0.488477525 */, 17 }, /* 4026 */ { MAD_F(0x07d1777e) /* 0.488639346 */, 17 }, /* 4027 */ { MAD_F(0x07d22130) /* 0.488801181 */, 17 }, /* 4028 */ { MAD_F(0x07d2cae5) /* 0.488963029 */, 17 }, /* 4029 */ { MAD_F(0x07d3749f) /* 0.489124890 */, 17 }, /* 4030 */ { MAD_F(0x07d41e5c) /* 0.489286765 */, 17 }, /* 4031 */ { MAD_F(0x07d4c81c) /* 0.489448653 */, 17 }, /* 4032 */ { MAD_F(0x07d571e0) /* 0.489610555 */, 17 }, /* 4033 */ { MAD_F(0x07d61ba8) /* 0.489772470 */, 17 }, /* 4034 */ { MAD_F(0x07d6c573) /* 0.489934398 */, 17 }, /* 4035 */ { MAD_F(0x07d76f42) /* 0.490096340 */, 17 }, /* 4036 */ { MAD_F(0x07d81915) /* 0.490258295 */, 17 }, /* 4037 */ { MAD_F(0x07d8c2eb) /* 0.490420263 */, 17 }, /* 4038 */ { MAD_F(0x07d96cc4) /* 0.490582245 */, 17 }, /* 4039 */ { MAD_F(0x07da16a2) /* 0.490744240 */, 17 }, /* 4040 */ { MAD_F(0x07dac083) /* 0.490906249 */, 17 }, /* 4041 */ { MAD_F(0x07db6a67) /* 0.491068271 */, 17 }, /* 4042 */ { MAD_F(0x07dc144f) /* 0.491230306 */, 17 }, /* 4043 */ { MAD_F(0x07dcbe3b) /* 0.491392355 */, 17 }, /* 4044 */ { MAD_F(0x07dd682a) /* 0.491554417 */, 17 }, /* 4045 */ { MAD_F(0x07de121d) /* 0.491716492 */, 17 }, /* 4046 */ { MAD_F(0x07debc13) /* 0.491878581 */, 17 }, /* 4047 */ { MAD_F(0x07df660d) /* 0.492040683 */, 17 }, /* 4048 */ { MAD_F(0x07e0100a) /* 0.492202799 */, 17 }, /* 4049 */ { MAD_F(0x07e0ba0c) /* 0.492364928 */, 17 }, /* 4050 */ { MAD_F(0x07e16410) /* 0.492527070 */, 17 }, /* 4051 */ { MAD_F(0x07e20e19) /* 0.492689225 */, 17 }, /* 4052 */ { MAD_F(0x07e2b824) /* 0.492851394 */, 17 }, /* 4053 */ { MAD_F(0x07e36234) /* 0.493013576 */, 17 }, /* 4054 */ { MAD_F(0x07e40c47) /* 0.493175772 */, 17 }, /* 4055 */ { MAD_F(0x07e4b65e) /* 0.493337981 */, 17 }, /* 4056 */ { MAD_F(0x07e56078) /* 0.493500203 */, 17 }, /* 4057 */ { MAD_F(0x07e60a95) /* 0.493662438 */, 17 }, /* 4058 */ { MAD_F(0x07e6b4b7) /* 0.493824687 */, 17 }, /* 4059 */ { MAD_F(0x07e75edc) /* 0.493986949 */, 17 }, /* 4060 */ { MAD_F(0x07e80904) /* 0.494149225 */, 17 }, /* 4061 */ { MAD_F(0x07e8b330) /* 0.494311514 */, 17 }, /* 4062 */ { MAD_F(0x07e95d60) /* 0.494473816 */, 17 }, /* 4063 */ { MAD_F(0x07ea0793) /* 0.494636131 */, 17 }, /* 4064 */ { MAD_F(0x07eab1ca) /* 0.494798460 */, 17 }, /* 4065 */ { MAD_F(0x07eb5c04) /* 0.494960802 */, 17 }, /* 4066 */ { MAD_F(0x07ec0642) /* 0.495123158 */, 17 }, /* 4067 */ { MAD_F(0x07ecb084) /* 0.495285526 */, 17 }, /* 4068 */ { MAD_F(0x07ed5ac9) /* 0.495447908 */, 17 }, /* 4069 */ { MAD_F(0x07ee0512) /* 0.495610304 */, 17 }, /* 4070 */ { MAD_F(0x07eeaf5e) /* 0.495772712 */, 17 }, /* 4071 */ { MAD_F(0x07ef59ae) /* 0.495935134 */, 17 }, /* 4072 */ { MAD_F(0x07f00401) /* 0.496097570 */, 17 }, /* 4073 */ { MAD_F(0x07f0ae58) /* 0.496260018 */, 17 }, /* 4074 */ { MAD_F(0x07f158b3) /* 0.496422480 */, 17 }, /* 4075 */ { MAD_F(0x07f20311) /* 0.496584955 */, 17 }, /* 4076 */ { MAD_F(0x07f2ad72) /* 0.496747444 */, 17 }, /* 4077 */ { MAD_F(0x07f357d8) /* 0.496909945 */, 17 }, /* 4078 */ { MAD_F(0x07f40240) /* 0.497072460 */, 17 }, /* 4079 */ { MAD_F(0x07f4acad) /* 0.497234989 */, 17 }, /* 4080 */ { MAD_F(0x07f5571d) /* 0.497397530 */, 17 }, /* 4081 */ { MAD_F(0x07f60190) /* 0.497560085 */, 17 }, /* 4082 */ { MAD_F(0x07f6ac07) /* 0.497722653 */, 17 }, /* 4083 */ { MAD_F(0x07f75682) /* 0.497885235 */, 17 }, /* 4084 */ { MAD_F(0x07f80100) /* 0.498047829 */, 17 }, /* 4085 */ { MAD_F(0x07f8ab82) /* 0.498210437 */, 17 }, /* 4086 */ { MAD_F(0x07f95607) /* 0.498373058 */, 17 }, /* 4087 */ { MAD_F(0x07fa0090) /* 0.498535693 */, 17 }, /* 4088 */ { MAD_F(0x07faab1c) /* 0.498698341 */, 17 }, /* 4089 */ { MAD_F(0x07fb55ac) /* 0.498861002 */, 17 }, /* 4090 */ { MAD_F(0x07fc0040) /* 0.499023676 */, 17 }, /* 4091 */ { MAD_F(0x07fcaad7) /* 0.499186364 */, 17 }, /* 4092 */ { MAD_F(0x07fd5572) /* 0.499349064 */, 17 }, /* 4093 */ { MAD_F(0x07fe0010) /* 0.499511778 */, 17 }, /* 4094 */ { MAD_F(0x07feaab2) /* 0.499674506 */, 17 }, /* 4095 */ { MAD_F(0x07ff5557) /* 0.499837246 */, 17 }, /* 4096 */ { MAD_F(0x04000000) /* 0.250000000 */, 18 }, /* 4097 */ { MAD_F(0x04005556) /* 0.250081384 */, 18 }, /* 4098 */ { MAD_F(0x0400aaae) /* 0.250162774 */, 18 }, /* 4099 */ { MAD_F(0x04010008) /* 0.250244170 */, 18 }, /* 4100 */ { MAD_F(0x04015563) /* 0.250325574 */, 18 }, /* 4101 */ { MAD_F(0x0401aac1) /* 0.250406984 */, 18 }, /* 4102 */ { MAD_F(0x04020020) /* 0.250488400 */, 18 }, /* 4103 */ { MAD_F(0x04025581) /* 0.250569824 */, 18 }, /* 4104 */ { MAD_F(0x0402aae3) /* 0.250651254 */, 18 }, /* 4105 */ { MAD_F(0x04030048) /* 0.250732690 */, 18 }, /* 4106 */ { MAD_F(0x040355ae) /* 0.250814133 */, 18 }, /* 4107 */ { MAD_F(0x0403ab16) /* 0.250895583 */, 18 }, /* 4108 */ { MAD_F(0x04040080) /* 0.250977039 */, 18 }, /* 4109 */ { MAD_F(0x040455eb) /* 0.251058502 */, 18 }, /* 4110 */ { MAD_F(0x0404ab59) /* 0.251139971 */, 18 }, /* 4111 */ { MAD_F(0x040500c8) /* 0.251221448 */, 18 }, /* 4112 */ { MAD_F(0x04055638) /* 0.251302930 */, 18 }, /* 4113 */ { MAD_F(0x0405abab) /* 0.251384420 */, 18 }, /* 4114 */ { MAD_F(0x0406011f) /* 0.251465916 */, 18 }, /* 4115 */ { MAD_F(0x04065696) /* 0.251547418 */, 18 }, /* 4116 */ { MAD_F(0x0406ac0e) /* 0.251628927 */, 18 }, /* 4117 */ { MAD_F(0x04070187) /* 0.251710443 */, 18 }, /* 4118 */ { MAD_F(0x04075703) /* 0.251791965 */, 18 }, /* 4119 */ { MAD_F(0x0407ac80) /* 0.251873494 */, 18 }, /* 4120 */ { MAD_F(0x040801ff) /* 0.251955030 */, 18 }, /* 4121 */ { MAD_F(0x04085780) /* 0.252036572 */, 18 }, /* 4122 */ { MAD_F(0x0408ad02) /* 0.252118121 */, 18 }, /* 4123 */ { MAD_F(0x04090287) /* 0.252199676 */, 18 }, /* 4124 */ { MAD_F(0x0409580d) /* 0.252281238 */, 18 }, /* 4125 */ { MAD_F(0x0409ad95) /* 0.252362807 */, 18 }, /* 4126 */ { MAD_F(0x040a031e) /* 0.252444382 */, 18 }, /* 4127 */ { MAD_F(0x040a58aa) /* 0.252525963 */, 18 }, /* 4128 */ { MAD_F(0x040aae37) /* 0.252607552 */, 18 }, /* 4129 */ { MAD_F(0x040b03c6) /* 0.252689147 */, 18 }, /* 4130 */ { MAD_F(0x040b5957) /* 0.252770748 */, 18 }, /* 4131 */ { MAD_F(0x040baee9) /* 0.252852356 */, 18 }, /* 4132 */ { MAD_F(0x040c047e) /* 0.252933971 */, 18 }, /* 4133 */ { MAD_F(0x040c5a14) /* 0.253015592 */, 18 }, /* 4134 */ { MAD_F(0x040cafab) /* 0.253097220 */, 18 }, /* 4135 */ { MAD_F(0x040d0545) /* 0.253178854 */, 18 }, /* 4136 */ { MAD_F(0x040d5ae0) /* 0.253260495 */, 18 }, /* 4137 */ { MAD_F(0x040db07d) /* 0.253342143 */, 18 }, /* 4138 */ { MAD_F(0x040e061c) /* 0.253423797 */, 18 }, /* 4139 */ { MAD_F(0x040e5bbd) /* 0.253505457 */, 18 }, /* 4140 */ { MAD_F(0x040eb15f) /* 0.253587125 */, 18 }, /* 4141 */ { MAD_F(0x040f0703) /* 0.253668799 */, 18 }, /* 4142 */ { MAD_F(0x040f5ca9) /* 0.253750479 */, 18 }, /* 4143 */ { MAD_F(0x040fb251) /* 0.253832166 */, 18 }, /* 4144 */ { MAD_F(0x041007fa) /* 0.253913860 */, 18 }, /* 4145 */ { MAD_F(0x04105da6) /* 0.253995560 */, 18 }, /* 4146 */ { MAD_F(0x0410b353) /* 0.254077266 */, 18 }, /* 4147 */ { MAD_F(0x04110901) /* 0.254158980 */, 18 }, /* 4148 */ { MAD_F(0x04115eb2) /* 0.254240700 */, 18 }, /* 4149 */ { MAD_F(0x0411b464) /* 0.254322426 */, 18 }, /* 4150 */ { MAD_F(0x04120a18) /* 0.254404159 */, 18 }, /* 4151 */ { MAD_F(0x04125fce) /* 0.254485899 */, 18 }, /* 4152 */ { MAD_F(0x0412b586) /* 0.254567645 */, 18 }, /* 4153 */ { MAD_F(0x04130b3f) /* 0.254649397 */, 18 }, /* 4154 */ { MAD_F(0x041360fa) /* 0.254731157 */, 18 }, /* 4155 */ { MAD_F(0x0413b6b7) /* 0.254812922 */, 18 }, /* 4156 */ { MAD_F(0x04140c75) /* 0.254894695 */, 18 }, /* 4157 */ { MAD_F(0x04146236) /* 0.254976474 */, 18 }, /* 4158 */ { MAD_F(0x0414b7f8) /* 0.255058259 */, 18 }, /* 4159 */ { MAD_F(0x04150dbc) /* 0.255140051 */, 18 }, /* 4160 */ { MAD_F(0x04156381) /* 0.255221850 */, 18 }, /* 4161 */ { MAD_F(0x0415b949) /* 0.255303655 */, 18 }, /* 4162 */ { MAD_F(0x04160f12) /* 0.255385467 */, 18 }, /* 4163 */ { MAD_F(0x041664dd) /* 0.255467285 */, 18 }, /* 4164 */ { MAD_F(0x0416baaa) /* 0.255549110 */, 18 }, /* 4165 */ { MAD_F(0x04171078) /* 0.255630941 */, 18 }, /* 4166 */ { MAD_F(0x04176648) /* 0.255712779 */, 18 }, /* 4167 */ { MAD_F(0x0417bc1a) /* 0.255794624 */, 18 }, /* 4168 */ { MAD_F(0x041811ee) /* 0.255876475 */, 18 }, /* 4169 */ { MAD_F(0x041867c3) /* 0.255958332 */, 18 }, /* 4170 */ { MAD_F(0x0418bd9b) /* 0.256040196 */, 18 }, /* 4171 */ { MAD_F(0x04191374) /* 0.256122067 */, 18 }, /* 4172 */ { MAD_F(0x0419694e) /* 0.256203944 */, 18 }, /* 4173 */ { MAD_F(0x0419bf2b) /* 0.256285828 */, 18 }, /* 4174 */ { MAD_F(0x041a1509) /* 0.256367718 */, 18 }, /* 4175 */ { MAD_F(0x041a6ae9) /* 0.256449615 */, 18 }, /* 4176 */ { MAD_F(0x041ac0cb) /* 0.256531518 */, 18 }, /* 4177 */ { MAD_F(0x041b16ae) /* 0.256613428 */, 18 }, /* 4178 */ { MAD_F(0x041b6c94) /* 0.256695344 */, 18 }, /* 4179 */ { MAD_F(0x041bc27b) /* 0.256777267 */, 18 }, /* 4180 */ { MAD_F(0x041c1863) /* 0.256859197 */, 18 }, /* 4181 */ { MAD_F(0x041c6e4e) /* 0.256941133 */, 18 }, /* 4182 */ { MAD_F(0x041cc43a) /* 0.257023076 */, 18 }, /* 4183 */ { MAD_F(0x041d1a28) /* 0.257105025 */, 18 }, /* 4184 */ { MAD_F(0x041d7018) /* 0.257186980 */, 18 }, /* 4185 */ { MAD_F(0x041dc60a) /* 0.257268942 */, 18 }, /* 4186 */ { MAD_F(0x041e1bfd) /* 0.257350911 */, 18 }, /* 4187 */ { MAD_F(0x041e71f2) /* 0.257432886 */, 18 }, /* 4188 */ { MAD_F(0x041ec7e9) /* 0.257514868 */, 18 }, /* 4189 */ { MAD_F(0x041f1de1) /* 0.257596856 */, 18 }, /* 4190 */ { MAD_F(0x041f73dc) /* 0.257678851 */, 18 }, /* 4191 */ { MAD_F(0x041fc9d8) /* 0.257760852 */, 18 }, /* 4192 */ { MAD_F(0x04201fd5) /* 0.257842860 */, 18 }, /* 4193 */ { MAD_F(0x042075d5) /* 0.257924875 */, 18 }, /* 4194 */ { MAD_F(0x0420cbd6) /* 0.258006895 */, 18 }, /* 4195 */ { MAD_F(0x042121d9) /* 0.258088923 */, 18 }, /* 4196 */ { MAD_F(0x042177de) /* 0.258170957 */, 18 }, /* 4197 */ { MAD_F(0x0421cde5) /* 0.258252997 */, 18 }, /* 4198 */ { MAD_F(0x042223ed) /* 0.258335044 */, 18 }, /* 4199 */ { MAD_F(0x042279f7) /* 0.258417097 */, 18 }, /* 4200 */ { MAD_F(0x0422d003) /* 0.258499157 */, 18 }, /* 4201 */ { MAD_F(0x04232611) /* 0.258581224 */, 18 }, /* 4202 */ { MAD_F(0x04237c20) /* 0.258663297 */, 18 }, /* 4203 */ { MAD_F(0x0423d231) /* 0.258745376 */, 18 }, /* 4204 */ { MAD_F(0x04242844) /* 0.258827462 */, 18 }, /* 4205 */ { MAD_F(0x04247e58) /* 0.258909555 */, 18 }, /* 4206 */ { MAD_F(0x0424d46e) /* 0.258991654 */, 18 }, /* 4207 */ { MAD_F(0x04252a87) /* 0.259073760 */, 18 }, /* 4208 */ { MAD_F(0x042580a0) /* 0.259155872 */, 18 }, /* 4209 */ { MAD_F(0x0425d6bc) /* 0.259237990 */, 18 }, /* 4210 */ { MAD_F(0x04262cd9) /* 0.259320115 */, 18 }, /* 4211 */ { MAD_F(0x042682f8) /* 0.259402247 */, 18 }, /* 4212 */ { MAD_F(0x0426d919) /* 0.259484385 */, 18 }, /* 4213 */ { MAD_F(0x04272f3b) /* 0.259566529 */, 18 }, /* 4214 */ { MAD_F(0x04278560) /* 0.259648680 */, 18 }, /* 4215 */ { MAD_F(0x0427db86) /* 0.259730838 */, 18 }, /* 4216 */ { MAD_F(0x042831ad) /* 0.259813002 */, 18 }, /* 4217 */ { MAD_F(0x042887d7) /* 0.259895173 */, 18 }, /* 4218 */ { MAD_F(0x0428de02) /* 0.259977350 */, 18 }, /* 4219 */ { MAD_F(0x0429342f) /* 0.260059533 */, 18 }, /* 4220 */ { MAD_F(0x04298a5e) /* 0.260141723 */, 18 }, /* 4221 */ { MAD_F(0x0429e08e) /* 0.260223920 */, 18 }, /* 4222 */ { MAD_F(0x042a36c0) /* 0.260306123 */, 18 }, /* 4223 */ { MAD_F(0x042a8cf4) /* 0.260388332 */, 18 }, /* 4224 */ { MAD_F(0x042ae32a) /* 0.260470548 */, 18 }, /* 4225 */ { MAD_F(0x042b3962) /* 0.260552771 */, 18 }, /* 4226 */ { MAD_F(0x042b8f9b) /* 0.260635000 */, 18 }, /* 4227 */ { MAD_F(0x042be5d6) /* 0.260717235 */, 18 }, /* 4228 */ { MAD_F(0x042c3c12) /* 0.260799477 */, 18 }, /* 4229 */ { MAD_F(0x042c9251) /* 0.260881725 */, 18 }, /* 4230 */ { MAD_F(0x042ce891) /* 0.260963980 */, 18 }, /* 4231 */ { MAD_F(0x042d3ed3) /* 0.261046242 */, 18 }, /* 4232 */ { MAD_F(0x042d9516) /* 0.261128510 */, 18 }, /* 4233 */ { MAD_F(0x042deb5c) /* 0.261210784 */, 18 }, /* 4234 */ { MAD_F(0x042e41a3) /* 0.261293065 */, 18 }, /* 4235 */ { MAD_F(0x042e97ec) /* 0.261375352 */, 18 }, /* 4236 */ { MAD_F(0x042eee36) /* 0.261457646 */, 18 }, /* 4237 */ { MAD_F(0x042f4482) /* 0.261539946 */, 18 }, /* 4238 */ { MAD_F(0x042f9ad1) /* 0.261622253 */, 18 }, /* 4239 */ { MAD_F(0x042ff120) /* 0.261704566 */, 18 }, /* 4240 */ { MAD_F(0x04304772) /* 0.261786886 */, 18 }, /* 4241 */ { MAD_F(0x04309dc5) /* 0.261869212 */, 18 }, /* 4242 */ { MAD_F(0x0430f41a) /* 0.261951545 */, 18 }, /* 4243 */ { MAD_F(0x04314a71) /* 0.262033884 */, 18 }, /* 4244 */ { MAD_F(0x0431a0c9) /* 0.262116229 */, 18 }, /* 4245 */ { MAD_F(0x0431f723) /* 0.262198581 */, 18 }, /* 4246 */ { MAD_F(0x04324d7f) /* 0.262280940 */, 18 }, /* 4247 */ { MAD_F(0x0432a3dd) /* 0.262363305 */, 18 }, /* 4248 */ { MAD_F(0x0432fa3d) /* 0.262445676 */, 18 }, /* 4249 */ { MAD_F(0x0433509e) /* 0.262528054 */, 18 }, /* 4250 */ { MAD_F(0x0433a701) /* 0.262610438 */, 18 }, /* 4251 */ { MAD_F(0x0433fd65) /* 0.262692829 */, 18 }, /* 4252 */ { MAD_F(0x043453cc) /* 0.262775227 */, 18 }, /* 4253 */ { MAD_F(0x0434aa34) /* 0.262857630 */, 18 }, /* 4254 */ { MAD_F(0x0435009d) /* 0.262940040 */, 18 }, /* 4255 */ { MAD_F(0x04355709) /* 0.263022457 */, 18 }, /* 4256 */ { MAD_F(0x0435ad76) /* 0.263104880 */, 18 }, /* 4257 */ { MAD_F(0x043603e5) /* 0.263187310 */, 18 }, /* 4258 */ { MAD_F(0x04365a56) /* 0.263269746 */, 18 }, /* 4259 */ { MAD_F(0x0436b0c9) /* 0.263352188 */, 18 }, /* 4260 */ { MAD_F(0x0437073d) /* 0.263434637 */, 18 }, /* 4261 */ { MAD_F(0x04375db3) /* 0.263517093 */, 18 }, /* 4262 */ { MAD_F(0x0437b42a) /* 0.263599554 */, 18 }, /* 4263 */ { MAD_F(0x04380aa4) /* 0.263682023 */, 18 }, /* 4264 */ { MAD_F(0x0438611f) /* 0.263764497 */, 18 }, /* 4265 */ { MAD_F(0x0438b79c) /* 0.263846979 */, 18 }, /* 4266 */ { MAD_F(0x04390e1a) /* 0.263929466 */, 18 }, /* 4267 */ { MAD_F(0x0439649b) /* 0.264011960 */, 18 }, /* 4268 */ { MAD_F(0x0439bb1d) /* 0.264094461 */, 18 }, /* 4269 */ { MAD_F(0x043a11a1) /* 0.264176968 */, 18 }, /* 4270 */ { MAD_F(0x043a6826) /* 0.264259481 */, 18 }, /* 4271 */ { MAD_F(0x043abead) /* 0.264342001 */, 18 }, /* 4272 */ { MAD_F(0x043b1536) /* 0.264424527 */, 18 }, /* 4273 */ { MAD_F(0x043b6bc1) /* 0.264507060 */, 18 }, /* 4274 */ { MAD_F(0x043bc24d) /* 0.264589599 */, 18 }, /* 4275 */ { MAD_F(0x043c18dc) /* 0.264672145 */, 18 }, /* 4276 */ { MAD_F(0x043c6f6c) /* 0.264754697 */, 18 }, /* 4277 */ { MAD_F(0x043cc5fd) /* 0.264837255 */, 18 }, /* 4278 */ { MAD_F(0x043d1c91) /* 0.264919820 */, 18 }, /* 4279 */ { MAD_F(0x043d7326) /* 0.265002392 */, 18 }, /* 4280 */ { MAD_F(0x043dc9bc) /* 0.265084969 */, 18 }, /* 4281 */ { MAD_F(0x043e2055) /* 0.265167554 */, 18 }, /* 4282 */ { MAD_F(0x043e76ef) /* 0.265250144 */, 18 }, /* 4283 */ { MAD_F(0x043ecd8b) /* 0.265332741 */, 18 }, /* 4284 */ { MAD_F(0x043f2429) /* 0.265415345 */, 18 }, /* 4285 */ { MAD_F(0x043f7ac8) /* 0.265497955 */, 18 }, /* 4286 */ { MAD_F(0x043fd169) /* 0.265580571 */, 18 }, /* 4287 */ { MAD_F(0x0440280c) /* 0.265663194 */, 18 }, /* 4288 */ { MAD_F(0x04407eb1) /* 0.265745823 */, 18 }, /* 4289 */ { MAD_F(0x0440d557) /* 0.265828459 */, 18 }, /* 4290 */ { MAD_F(0x04412bff) /* 0.265911101 */, 18 }, /* 4291 */ { MAD_F(0x044182a9) /* 0.265993749 */, 18 }, /* 4292 */ { MAD_F(0x0441d955) /* 0.266076404 */, 18 }, /* 4293 */ { MAD_F(0x04423002) /* 0.266159065 */, 18 }, /* 4294 */ { MAD_F(0x044286b1) /* 0.266241733 */, 18 }, /* 4295 */ { MAD_F(0x0442dd61) /* 0.266324407 */, 18 }, /* 4296 */ { MAD_F(0x04433414) /* 0.266407088 */, 18 }, /* 4297 */ { MAD_F(0x04438ac8) /* 0.266489775 */, 18 }, /* 4298 */ { MAD_F(0x0443e17e) /* 0.266572468 */, 18 }, /* 4299 */ { MAD_F(0x04443835) /* 0.266655168 */, 18 }, /* 4300 */ { MAD_F(0x04448eef) /* 0.266737874 */, 18 }, /* 4301 */ { MAD_F(0x0444e5aa) /* 0.266820587 */, 18 }, /* 4302 */ { MAD_F(0x04453c66) /* 0.266903306 */, 18 }, /* 4303 */ { MAD_F(0x04459325) /* 0.266986031 */, 18 }, /* 4304 */ { MAD_F(0x0445e9e5) /* 0.267068763 */, 18 }, /* 4305 */ { MAD_F(0x044640a7) /* 0.267151501 */, 18 }, /* 4306 */ { MAD_F(0x0446976a) /* 0.267234246 */, 18 }, /* 4307 */ { MAD_F(0x0446ee30) /* 0.267316997 */, 18 }, /* 4308 */ { MAD_F(0x044744f7) /* 0.267399755 */, 18 }, /* 4309 */ { MAD_F(0x04479bc0) /* 0.267482518 */, 18 }, /* 4310 */ { MAD_F(0x0447f28a) /* 0.267565289 */, 18 }, /* 4311 */ { MAD_F(0x04484956) /* 0.267648065 */, 18 }, /* 4312 */ { MAD_F(0x0448a024) /* 0.267730848 */, 18 }, /* 4313 */ { MAD_F(0x0448f6f4) /* 0.267813638 */, 18 }, /* 4314 */ { MAD_F(0x04494dc5) /* 0.267896434 */, 18 }, /* 4315 */ { MAD_F(0x0449a498) /* 0.267979236 */, 18 }, /* 4316 */ { MAD_F(0x0449fb6d) /* 0.268062045 */, 18 }, /* 4317 */ { MAD_F(0x044a5243) /* 0.268144860 */, 18 }, /* 4318 */ { MAD_F(0x044aa91c) /* 0.268227681 */, 18 }, /* 4319 */ { MAD_F(0x044afff6) /* 0.268310509 */, 18 }, /* 4320 */ { MAD_F(0x044b56d1) /* 0.268393343 */, 18 }, /* 4321 */ { MAD_F(0x044badaf) /* 0.268476184 */, 18 }, /* 4322 */ { MAD_F(0x044c048e) /* 0.268559031 */, 18 }, /* 4323 */ { MAD_F(0x044c5b6f) /* 0.268641885 */, 18 }, /* 4324 */ { MAD_F(0x044cb251) /* 0.268724744 */, 18 }, /* 4325 */ { MAD_F(0x044d0935) /* 0.268807611 */, 18 }, /* 4326 */ { MAD_F(0x044d601b) /* 0.268890483 */, 18 }, /* 4327 */ { MAD_F(0x044db703) /* 0.268973362 */, 18 }, /* 4328 */ { MAD_F(0x044e0dec) /* 0.269056248 */, 18 }, /* 4329 */ { MAD_F(0x044e64d7) /* 0.269139139 */, 18 }, /* 4330 */ { MAD_F(0x044ebbc4) /* 0.269222037 */, 18 }, /* 4331 */ { MAD_F(0x044f12b3) /* 0.269304942 */, 18 }, /* 4332 */ { MAD_F(0x044f69a3) /* 0.269387853 */, 18 }, /* 4333 */ { MAD_F(0x044fc095) /* 0.269470770 */, 18 }, /* 4334 */ { MAD_F(0x04501788) /* 0.269553694 */, 18 }, /* 4335 */ { MAD_F(0x04506e7e) /* 0.269636624 */, 18 }, /* 4336 */ { MAD_F(0x0450c575) /* 0.269719560 */, 18 }, /* 4337 */ { MAD_F(0x04511c6e) /* 0.269802503 */, 18 }, /* 4338 */ { MAD_F(0x04517368) /* 0.269885452 */, 18 }, /* 4339 */ { MAD_F(0x0451ca64) /* 0.269968408 */, 18 }, /* 4340 */ { MAD_F(0x04522162) /* 0.270051370 */, 18 }, /* 4341 */ { MAD_F(0x04527862) /* 0.270134338 */, 18 }, /* 4342 */ { MAD_F(0x0452cf63) /* 0.270217312 */, 18 }, /* 4343 */ { MAD_F(0x04532666) /* 0.270300293 */, 18 }, /* 4344 */ { MAD_F(0x04537d6b) /* 0.270383281 */, 18 }, /* 4345 */ { MAD_F(0x0453d472) /* 0.270466275 */, 18 }, /* 4346 */ { MAD_F(0x04542b7a) /* 0.270549275 */, 18 }, /* 4347 */ { MAD_F(0x04548284) /* 0.270632281 */, 18 }, /* 4348 */ { MAD_F(0x0454d98f) /* 0.270715294 */, 18 }, /* 4349 */ { MAD_F(0x0455309c) /* 0.270798313 */, 18 }, /* 4350 */ { MAD_F(0x045587ab) /* 0.270881339 */, 18 }, /* 4351 */ { MAD_F(0x0455debc) /* 0.270964371 */, 18 }, /* 4352 */ { MAD_F(0x045635cf) /* 0.271047409 */, 18 }, /* 4353 */ { MAD_F(0x04568ce3) /* 0.271130454 */, 18 }, /* 4354 */ { MAD_F(0x0456e3f9) /* 0.271213505 */, 18 }, /* 4355 */ { MAD_F(0x04573b10) /* 0.271296562 */, 18 }, /* 4356 */ { MAD_F(0x04579229) /* 0.271379626 */, 18 }, /* 4357 */ { MAD_F(0x0457e944) /* 0.271462696 */, 18 }, /* 4358 */ { MAD_F(0x04584061) /* 0.271545772 */, 18 }, /* 4359 */ { MAD_F(0x0458977f) /* 0.271628855 */, 18 }, /* 4360 */ { MAD_F(0x0458ee9f) /* 0.271711944 */, 18 }, /* 4361 */ { MAD_F(0x045945c1) /* 0.271795040 */, 18 }, /* 4362 */ { MAD_F(0x04599ce5) /* 0.271878142 */, 18 }, /* 4363 */ { MAD_F(0x0459f40a) /* 0.271961250 */, 18 }, /* 4364 */ { MAD_F(0x045a4b31) /* 0.272044365 */, 18 }, /* 4365 */ { MAD_F(0x045aa259) /* 0.272127486 */, 18 }, /* 4366 */ { MAD_F(0x045af984) /* 0.272210613 */, 18 }, /* 4367 */ { MAD_F(0x045b50b0) /* 0.272293746 */, 18 }, /* 4368 */ { MAD_F(0x045ba7dd) /* 0.272376886 */, 18 }, /* 4369 */ { MAD_F(0x045bff0d) /* 0.272460033 */, 18 }, /* 4370 */ { MAD_F(0x045c563e) /* 0.272543185 */, 18 }, /* 4371 */ { MAD_F(0x045cad71) /* 0.272626344 */, 18 }, /* 4372 */ { MAD_F(0x045d04a5) /* 0.272709510 */, 18 }, /* 4373 */ { MAD_F(0x045d5bdc) /* 0.272792681 */, 18 }, /* 4374 */ { MAD_F(0x045db313) /* 0.272875859 */, 18 }, /* 4375 */ { MAD_F(0x045e0a4d) /* 0.272959044 */, 18 }, /* 4376 */ { MAD_F(0x045e6188) /* 0.273042234 */, 18 }, /* 4377 */ { MAD_F(0x045eb8c5) /* 0.273125431 */, 18 }, /* 4378 */ { MAD_F(0x045f1004) /* 0.273208635 */, 18 }, /* 4379 */ { MAD_F(0x045f6745) /* 0.273291844 */, 18 }, /* 4380 */ { MAD_F(0x045fbe87) /* 0.273375060 */, 18 }, /* 4381 */ { MAD_F(0x046015cb) /* 0.273458283 */, 18 }, /* 4382 */ { MAD_F(0x04606d10) /* 0.273541511 */, 18 }, /* 4383 */ { MAD_F(0x0460c457) /* 0.273624747 */, 18 }, /* 4384 */ { MAD_F(0x04611ba0) /* 0.273707988 */, 18 }, /* 4385 */ { MAD_F(0x046172eb) /* 0.273791236 */, 18 }, /* 4386 */ { MAD_F(0x0461ca37) /* 0.273874490 */, 18 }, /* 4387 */ { MAD_F(0x04622185) /* 0.273957750 */, 18 }, /* 4388 */ { MAD_F(0x046278d5) /* 0.274041017 */, 18 }, /* 4389 */ { MAD_F(0x0462d026) /* 0.274124290 */, 18 }, /* 4390 */ { MAD_F(0x0463277a) /* 0.274207569 */, 18 }, /* 4391 */ { MAD_F(0x04637ece) /* 0.274290855 */, 18 }, /* 4392 */ { MAD_F(0x0463d625) /* 0.274374147 */, 18 }, /* 4393 */ { MAD_F(0x04642d7d) /* 0.274457445 */, 18 }, /* 4394 */ { MAD_F(0x046484d7) /* 0.274540749 */, 18 }, /* 4395 */ { MAD_F(0x0464dc33) /* 0.274624060 */, 18 }, /* 4396 */ { MAD_F(0x04653390) /* 0.274707378 */, 18 }, /* 4397 */ { MAD_F(0x04658aef) /* 0.274790701 */, 18 }, /* 4398 */ { MAD_F(0x0465e250) /* 0.274874031 */, 18 }, /* 4399 */ { MAD_F(0x046639b2) /* 0.274957367 */, 18 }, /* 4400 */ { MAD_F(0x04669116) /* 0.275040710 */, 18 }, /* 4401 */ { MAD_F(0x0466e87c) /* 0.275124059 */, 18 }, /* 4402 */ { MAD_F(0x04673fe3) /* 0.275207414 */, 18 }, /* 4403 */ { MAD_F(0x0467974d) /* 0.275290775 */, 18 }, /* 4404 */ { MAD_F(0x0467eeb7) /* 0.275374143 */, 18 }, /* 4405 */ { MAD_F(0x04684624) /* 0.275457517 */, 18 }, /* 4406 */ { MAD_F(0x04689d92) /* 0.275540897 */, 18 }, /* 4407 */ { MAD_F(0x0468f502) /* 0.275624284 */, 18 }, /* 4408 */ { MAD_F(0x04694c74) /* 0.275707677 */, 18 }, /* 4409 */ { MAD_F(0x0469a3e7) /* 0.275791076 */, 18 }, /* 4410 */ { MAD_F(0x0469fb5c) /* 0.275874482 */, 18 }, /* 4411 */ { MAD_F(0x046a52d3) /* 0.275957894 */, 18 }, /* 4412 */ { MAD_F(0x046aaa4b) /* 0.276041312 */, 18 }, /* 4413 */ { MAD_F(0x046b01c5) /* 0.276124737 */, 18 }, /* 4414 */ { MAD_F(0x046b5941) /* 0.276208167 */, 18 }, /* 4415 */ { MAD_F(0x046bb0bf) /* 0.276291605 */, 18 }, /* 4416 */ { MAD_F(0x046c083e) /* 0.276375048 */, 18 }, /* 4417 */ { MAD_F(0x046c5fbf) /* 0.276458498 */, 18 }, /* 4418 */ { MAD_F(0x046cb741) /* 0.276541954 */, 18 }, /* 4419 */ { MAD_F(0x046d0ec5) /* 0.276625416 */, 18 }, /* 4420 */ { MAD_F(0x046d664b) /* 0.276708885 */, 18 }, /* 4421 */ { MAD_F(0x046dbdd3) /* 0.276792360 */, 18 }, /* 4422 */ { MAD_F(0x046e155c) /* 0.276875841 */, 18 }, /* 4423 */ { MAD_F(0x046e6ce7) /* 0.276959328 */, 18 }, /* 4424 */ { MAD_F(0x046ec474) /* 0.277042822 */, 18 }, /* 4425 */ { MAD_F(0x046f1c02) /* 0.277126322 */, 18 }, /* 4426 */ { MAD_F(0x046f7392) /* 0.277209829 */, 18 }, /* 4427 */ { MAD_F(0x046fcb24) /* 0.277293341 */, 18 }, /* 4428 */ { MAD_F(0x047022b8) /* 0.277376860 */, 18 }, /* 4429 */ { MAD_F(0x04707a4d) /* 0.277460385 */, 18 }, /* 4430 */ { MAD_F(0x0470d1e4) /* 0.277543917 */, 18 }, /* 4431 */ { MAD_F(0x0471297c) /* 0.277627455 */, 18 }, /* 4432 */ { MAD_F(0x04718116) /* 0.277710999 */, 18 }, /* 4433 */ { MAD_F(0x0471d8b2) /* 0.277794549 */, 18 }, /* 4434 */ { MAD_F(0x04723050) /* 0.277878106 */, 18 }, /* 4435 */ { MAD_F(0x047287ef) /* 0.277961669 */, 18 }, /* 4436 */ { MAD_F(0x0472df90) /* 0.278045238 */, 18 }, /* 4437 */ { MAD_F(0x04733733) /* 0.278128813 */, 18 }, /* 4438 */ { MAD_F(0x04738ed7) /* 0.278212395 */, 18 }, /* 4439 */ { MAD_F(0x0473e67d) /* 0.278295983 */, 18 }, /* 4440 */ { MAD_F(0x04743e25) /* 0.278379578 */, 18 }, /* 4441 */ { MAD_F(0x047495ce) /* 0.278463178 */, 18 }, /* 4442 */ { MAD_F(0x0474ed79) /* 0.278546785 */, 18 }, /* 4443 */ { MAD_F(0x04754526) /* 0.278630398 */, 18 }, /* 4444 */ { MAD_F(0x04759cd4) /* 0.278714018 */, 18 }, /* 4445 */ { MAD_F(0x0475f484) /* 0.278797643 */, 18 }, /* 4446 */ { MAD_F(0x04764c36) /* 0.278881275 */, 18 }, /* 4447 */ { MAD_F(0x0476a3ea) /* 0.278964914 */, 18 }, /* 4448 */ { MAD_F(0x0476fb9f) /* 0.279048558 */, 18 }, /* 4449 */ { MAD_F(0x04775356) /* 0.279132209 */, 18 }, /* 4450 */ { MAD_F(0x0477ab0e) /* 0.279215866 */, 18 }, /* 4451 */ { MAD_F(0x047802c8) /* 0.279299529 */, 18 }, /* 4452 */ { MAD_F(0x04785a84) /* 0.279383199 */, 18 }, /* 4453 */ { MAD_F(0x0478b242) /* 0.279466875 */, 18 }, /* 4454 */ { MAD_F(0x04790a01) /* 0.279550557 */, 18 }, /* 4455 */ { MAD_F(0x047961c2) /* 0.279634245 */, 18 }, /* 4456 */ { MAD_F(0x0479b984) /* 0.279717940 */, 18 }, /* 4457 */ { MAD_F(0x047a1149) /* 0.279801641 */, 18 }, /* 4458 */ { MAD_F(0x047a690f) /* 0.279885348 */, 18 }, /* 4459 */ { MAD_F(0x047ac0d6) /* 0.279969061 */, 18 }, /* 4460 */ { MAD_F(0x047b18a0) /* 0.280052781 */, 18 }, /* 4461 */ { MAD_F(0x047b706b) /* 0.280136507 */, 18 }, /* 4462 */ { MAD_F(0x047bc837) /* 0.280220239 */, 18 }, /* 4463 */ { MAD_F(0x047c2006) /* 0.280303978 */, 18 }, /* 4464 */ { MAD_F(0x047c77d6) /* 0.280387722 */, 18 }, /* 4465 */ { MAD_F(0x047ccfa8) /* 0.280471473 */, 18 }, /* 4466 */ { MAD_F(0x047d277b) /* 0.280555230 */, 18 }, /* 4467 */ { MAD_F(0x047d7f50) /* 0.280638994 */, 18 }, /* 4468 */ { MAD_F(0x047dd727) /* 0.280722764 */, 18 }, /* 4469 */ { MAD_F(0x047e2eff) /* 0.280806540 */, 18 }, /* 4470 */ { MAD_F(0x047e86d9) /* 0.280890322 */, 18 }, /* 4471 */ { MAD_F(0x047edeb5) /* 0.280974110 */, 18 }, /* 4472 */ { MAD_F(0x047f3693) /* 0.281057905 */, 18 }, /* 4473 */ { MAD_F(0x047f8e72) /* 0.281141706 */, 18 }, /* 4474 */ { MAD_F(0x047fe653) /* 0.281225513 */, 18 }, /* 4475 */ { MAD_F(0x04803e35) /* 0.281309326 */, 18 }, /* 4476 */ { MAD_F(0x04809619) /* 0.281393146 */, 18 }, /* 4477 */ { MAD_F(0x0480edff) /* 0.281476972 */, 18 }, /* 4478 */ { MAD_F(0x048145e7) /* 0.281560804 */, 18 }, /* 4479 */ { MAD_F(0x04819dd0) /* 0.281644643 */, 18 }, /* 4480 */ { MAD_F(0x0481f5bb) /* 0.281728487 */, 18 }, /* 4481 */ { MAD_F(0x04824da7) /* 0.281812338 */, 18 }, /* 4482 */ { MAD_F(0x0482a595) /* 0.281896195 */, 18 }, /* 4483 */ { MAD_F(0x0482fd85) /* 0.281980059 */, 18 }, /* 4484 */ { MAD_F(0x04835577) /* 0.282063928 */, 18 }, /* 4485 */ { MAD_F(0x0483ad6a) /* 0.282147804 */, 18 }, /* 4486 */ { MAD_F(0x0484055f) /* 0.282231686 */, 18 }, /* 4487 */ { MAD_F(0x04845d56) /* 0.282315574 */, 18 }, /* 4488 */ { MAD_F(0x0484b54e) /* 0.282399469 */, 18 }, /* 4489 */ { MAD_F(0x04850d48) /* 0.282483370 */, 18 }, /* 4490 */ { MAD_F(0x04856544) /* 0.282567277 */, 18 }, /* 4491 */ { MAD_F(0x0485bd41) /* 0.282651190 */, 18 }, /* 4492 */ { MAD_F(0x04861540) /* 0.282735109 */, 18 }, /* 4493 */ { MAD_F(0x04866d40) /* 0.282819035 */, 18 }, /* 4494 */ { MAD_F(0x0486c543) /* 0.282902967 */, 18 }, /* 4495 */ { MAD_F(0x04871d47) /* 0.282986905 */, 18 }, /* 4496 */ { MAD_F(0x0487754c) /* 0.283070849 */, 18 }, /* 4497 */ { MAD_F(0x0487cd54) /* 0.283154800 */, 18 }, /* 4498 */ { MAD_F(0x0488255d) /* 0.283238757 */, 18 }, /* 4499 */ { MAD_F(0x04887d67) /* 0.283322720 */, 18 }, /* 4500 */ { MAD_F(0x0488d574) /* 0.283406689 */, 18 }, /* 4501 */ { MAD_F(0x04892d82) /* 0.283490665 */, 18 }, /* 4502 */ { MAD_F(0x04898591) /* 0.283574646 */, 18 }, /* 4503 */ { MAD_F(0x0489dda3) /* 0.283658634 */, 18 }, /* 4504 */ { MAD_F(0x048a35b6) /* 0.283742628 */, 18 }, /* 4505 */ { MAD_F(0x048a8dca) /* 0.283826629 */, 18 }, /* 4506 */ { MAD_F(0x048ae5e1) /* 0.283910635 */, 18 }, /* 4507 */ { MAD_F(0x048b3df9) /* 0.283994648 */, 18 }, /* 4508 */ { MAD_F(0x048b9612) /* 0.284078667 */, 18 }, /* 4509 */ { MAD_F(0x048bee2e) /* 0.284162692 */, 18 }, /* 4510 */ { MAD_F(0x048c464b) /* 0.284246723 */, 18 }, /* 4511 */ { MAD_F(0x048c9e69) /* 0.284330761 */, 18 }, /* 4512 */ { MAD_F(0x048cf68a) /* 0.284414805 */, 18 }, /* 4513 */ { MAD_F(0x048d4eac) /* 0.284498855 */, 18 }, /* 4514 */ { MAD_F(0x048da6cf) /* 0.284582911 */, 18 }, /* 4515 */ { MAD_F(0x048dfef5) /* 0.284666974 */, 18 }, /* 4516 */ { MAD_F(0x048e571c) /* 0.284751042 */, 18 }, /* 4517 */ { MAD_F(0x048eaf44) /* 0.284835117 */, 18 }, /* 4518 */ { MAD_F(0x048f076f) /* 0.284919198 */, 18 }, /* 4519 */ { MAD_F(0x048f5f9b) /* 0.285003285 */, 18 }, /* 4520 */ { MAD_F(0x048fb7c8) /* 0.285087379 */, 18 }, /* 4521 */ { MAD_F(0x04900ff8) /* 0.285171479 */, 18 }, /* 4522 */ { MAD_F(0x04906829) /* 0.285255584 */, 18 }, /* 4523 */ { MAD_F(0x0490c05b) /* 0.285339697 */, 18 }, /* 4524 */ { MAD_F(0x04911890) /* 0.285423815 */, 18 }, /* 4525 */ { MAD_F(0x049170c6) /* 0.285507939 */, 18 }, /* 4526 */ { MAD_F(0x0491c8fd) /* 0.285592070 */, 18 }, /* 4527 */ { MAD_F(0x04922137) /* 0.285676207 */, 18 }, /* 4528 */ { MAD_F(0x04927972) /* 0.285760350 */, 18 }, /* 4529 */ { MAD_F(0x0492d1ae) /* 0.285844499 */, 18 }, /* 4530 */ { MAD_F(0x049329ed) /* 0.285928655 */, 18 }, /* 4531 */ { MAD_F(0x0493822c) /* 0.286012816 */, 18 }, /* 4532 */ { MAD_F(0x0493da6e) /* 0.286096984 */, 18 }, /* 4533 */ { MAD_F(0x049432b1) /* 0.286181158 */, 18 }, /* 4534 */ { MAD_F(0x04948af6) /* 0.286265338 */, 18 }, /* 4535 */ { MAD_F(0x0494e33d) /* 0.286349525 */, 18 }, /* 4536 */ { MAD_F(0x04953b85) /* 0.286433717 */, 18 }, /* 4537 */ { MAD_F(0x049593cf) /* 0.286517916 */, 18 }, /* 4538 */ { MAD_F(0x0495ec1b) /* 0.286602121 */, 18 }, /* 4539 */ { MAD_F(0x04964468) /* 0.286686332 */, 18 }, /* 4540 */ { MAD_F(0x04969cb7) /* 0.286770550 */, 18 }, /* 4541 */ { MAD_F(0x0496f508) /* 0.286854773 */, 18 }, /* 4542 */ { MAD_F(0x04974d5a) /* 0.286939003 */, 18 }, /* 4543 */ { MAD_F(0x0497a5ae) /* 0.287023239 */, 18 }, /* 4544 */ { MAD_F(0x0497fe03) /* 0.287107481 */, 18 }, /* 4545 */ { MAD_F(0x0498565a) /* 0.287191729 */, 18 }, /* 4546 */ { MAD_F(0x0498aeb3) /* 0.287275983 */, 18 }, /* 4547 */ { MAD_F(0x0499070e) /* 0.287360244 */, 18 }, /* 4548 */ { MAD_F(0x04995f6a) /* 0.287444511 */, 18 }, /* 4549 */ { MAD_F(0x0499b7c8) /* 0.287528784 */, 18 }, /* 4550 */ { MAD_F(0x049a1027) /* 0.287613063 */, 18 }, /* 4551 */ { MAD_F(0x049a6889) /* 0.287697348 */, 18 }, /* 4552 */ { MAD_F(0x049ac0eb) /* 0.287781640 */, 18 }, /* 4553 */ { MAD_F(0x049b1950) /* 0.287865937 */, 18 }, /* 4554 */ { MAD_F(0x049b71b6) /* 0.287950241 */, 18 }, /* 4555 */ { MAD_F(0x049bca1e) /* 0.288034551 */, 18 }, /* 4556 */ { MAD_F(0x049c2287) /* 0.288118867 */, 18 }, /* 4557 */ { MAD_F(0x049c7af2) /* 0.288203190 */, 18 }, /* 4558 */ { MAD_F(0x049cd35f) /* 0.288287518 */, 18 }, /* 4559 */ { MAD_F(0x049d2bce) /* 0.288371853 */, 18 }, /* 4560 */ { MAD_F(0x049d843e) /* 0.288456194 */, 18 }, /* 4561 */ { MAD_F(0x049ddcaf) /* 0.288540541 */, 18 }, /* 4562 */ { MAD_F(0x049e3523) /* 0.288624894 */, 18 }, /* 4563 */ { MAD_F(0x049e8d98) /* 0.288709253 */, 18 }, /* 4564 */ { MAD_F(0x049ee60e) /* 0.288793619 */, 18 }, /* 4565 */ { MAD_F(0x049f3e87) /* 0.288877990 */, 18 }, /* 4566 */ { MAD_F(0x049f9701) /* 0.288962368 */, 18 }, /* 4567 */ { MAD_F(0x049fef7c) /* 0.289046752 */, 18 }, /* 4568 */ { MAD_F(0x04a047fa) /* 0.289131142 */, 18 }, /* 4569 */ { MAD_F(0x04a0a079) /* 0.289215538 */, 18 }, /* 4570 */ { MAD_F(0x04a0f8f9) /* 0.289299941 */, 18 }, /* 4571 */ { MAD_F(0x04a1517c) /* 0.289384349 */, 18 }, /* 4572 */ { MAD_F(0x04a1a9ff) /* 0.289468764 */, 18 }, /* 4573 */ { MAD_F(0x04a20285) /* 0.289553185 */, 18 }, /* 4574 */ { MAD_F(0x04a25b0c) /* 0.289637612 */, 18 }, /* 4575 */ { MAD_F(0x04a2b395) /* 0.289722045 */, 18 }, /* 4576 */ { MAD_F(0x04a30c20) /* 0.289806485 */, 18 }, /* 4577 */ { MAD_F(0x04a364ac) /* 0.289890930 */, 18 }, /* 4578 */ { MAD_F(0x04a3bd3a) /* 0.289975382 */, 18 }, /* 4579 */ { MAD_F(0x04a415c9) /* 0.290059840 */, 18 }, /* 4580 */ { MAD_F(0x04a46e5a) /* 0.290144304 */, 18 }, /* 4581 */ { MAD_F(0x04a4c6ed) /* 0.290228774 */, 18 }, /* 4582 */ { MAD_F(0x04a51f81) /* 0.290313250 */, 18 }, /* 4583 */ { MAD_F(0x04a57818) /* 0.290397733 */, 18 }, /* 4584 */ { MAD_F(0x04a5d0af) /* 0.290482221 */, 18 }, /* 4585 */ { MAD_F(0x04a62949) /* 0.290566716 */, 18 }, /* 4586 */ { MAD_F(0x04a681e4) /* 0.290651217 */, 18 }, /* 4587 */ { MAD_F(0x04a6da80) /* 0.290735724 */, 18 }, /* 4588 */ { MAD_F(0x04a7331f) /* 0.290820237 */, 18 }, /* 4589 */ { MAD_F(0x04a78bbf) /* 0.290904756 */, 18 }, /* 4590 */ { MAD_F(0x04a7e460) /* 0.290989281 */, 18 }, /* 4591 */ { MAD_F(0x04a83d03) /* 0.291073813 */, 18 }, /* 4592 */ { MAD_F(0x04a895a8) /* 0.291158351 */, 18 }, /* 4593 */ { MAD_F(0x04a8ee4f) /* 0.291242894 */, 18 }, /* 4594 */ { MAD_F(0x04a946f7) /* 0.291327444 */, 18 }, /* 4595 */ { MAD_F(0x04a99fa1) /* 0.291412001 */, 18 }, /* 4596 */ { MAD_F(0x04a9f84c) /* 0.291496563 */, 18 }, /* 4597 */ { MAD_F(0x04aa50fa) /* 0.291581131 */, 18 }, /* 4598 */ { MAD_F(0x04aaa9a8) /* 0.291665706 */, 18 }, /* 4599 */ { MAD_F(0x04ab0259) /* 0.291750286 */, 18 }, /* 4600 */ { MAD_F(0x04ab5b0b) /* 0.291834873 */, 18 }, /* 4601 */ { MAD_F(0x04abb3bf) /* 0.291919466 */, 18 }, /* 4602 */ { MAD_F(0x04ac0c74) /* 0.292004065 */, 18 }, /* 4603 */ { MAD_F(0x04ac652b) /* 0.292088670 */, 18 }, /* 4604 */ { MAD_F(0x04acbde4) /* 0.292173281 */, 18 }, /* 4605 */ { MAD_F(0x04ad169e) /* 0.292257899 */, 18 }, /* 4606 */ { MAD_F(0x04ad6f5a) /* 0.292342522 */, 18 }, /* 4607 */ { MAD_F(0x04adc818) /* 0.292427152 */, 18 }, /* 4608 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 18 }, /* 4609 */ { MAD_F(0x04ae7998) /* 0.292596430 */, 18 }, /* 4610 */ { MAD_F(0x04aed25a) /* 0.292681078 */, 18 }, /* 4611 */ { MAD_F(0x04af2b1e) /* 0.292765732 */, 18 }, /* 4612 */ { MAD_F(0x04af83e4) /* 0.292850392 */, 18 }, /* 4613 */ { MAD_F(0x04afdcac) /* 0.292935058 */, 18 }, /* 4614 */ { MAD_F(0x04b03575) /* 0.293019731 */, 18 }, /* 4615 */ { MAD_F(0x04b08e40) /* 0.293104409 */, 18 }, /* 4616 */ { MAD_F(0x04b0e70c) /* 0.293189094 */, 18 }, /* 4617 */ { MAD_F(0x04b13fda) /* 0.293273785 */, 18 }, /* 4618 */ { MAD_F(0x04b198aa) /* 0.293358482 */, 18 }, /* 4619 */ { MAD_F(0x04b1f17b) /* 0.293443185 */, 18 }, /* 4620 */ { MAD_F(0x04b24a4e) /* 0.293527894 */, 18 }, /* 4621 */ { MAD_F(0x04b2a322) /* 0.293612609 */, 18 }, /* 4622 */ { MAD_F(0x04b2fbf9) /* 0.293697331 */, 18 }, /* 4623 */ { MAD_F(0x04b354d1) /* 0.293782058 */, 18 }, /* 4624 */ { MAD_F(0x04b3adaa) /* 0.293866792 */, 18 }, /* 4625 */ { MAD_F(0x04b40685) /* 0.293951532 */, 18 }, /* 4626 */ { MAD_F(0x04b45f62) /* 0.294036278 */, 18 }, /* 4627 */ { MAD_F(0x04b4b840) /* 0.294121029 */, 18 }, /* 4628 */ { MAD_F(0x04b51120) /* 0.294205788 */, 18 }, /* 4629 */ { MAD_F(0x04b56a02) /* 0.294290552 */, 18 }, /* 4630 */ { MAD_F(0x04b5c2e6) /* 0.294375322 */, 18 }, /* 4631 */ { MAD_F(0x04b61bcb) /* 0.294460098 */, 18 }, /* 4632 */ { MAD_F(0x04b674b1) /* 0.294544881 */, 18 }, /* 4633 */ { MAD_F(0x04b6cd99) /* 0.294629669 */, 18 }, /* 4634 */ { MAD_F(0x04b72683) /* 0.294714464 */, 18 }, /* 4635 */ { MAD_F(0x04b77f6f) /* 0.294799265 */, 18 }, /* 4636 */ { MAD_F(0x04b7d85c) /* 0.294884072 */, 18 }, /* 4637 */ { MAD_F(0x04b8314b) /* 0.294968885 */, 18 }, /* 4638 */ { MAD_F(0x04b88a3b) /* 0.295053704 */, 18 }, /* 4639 */ { MAD_F(0x04b8e32d) /* 0.295138529 */, 18 }, /* 4640 */ { MAD_F(0x04b93c21) /* 0.295223360 */, 18 }, /* 4641 */ { MAD_F(0x04b99516) /* 0.295308197 */, 18 }, /* 4642 */ { MAD_F(0x04b9ee0d) /* 0.295393041 */, 18 }, /* 4643 */ { MAD_F(0x04ba4706) /* 0.295477890 */, 18 }, /* 4644 */ { MAD_F(0x04baa000) /* 0.295562746 */, 18 }, /* 4645 */ { MAD_F(0x04baf8fc) /* 0.295647608 */, 18 }, /* 4646 */ { MAD_F(0x04bb51fa) /* 0.295732476 */, 18 }, /* 4647 */ { MAD_F(0x04bbaaf9) /* 0.295817349 */, 18 }, /* 4648 */ { MAD_F(0x04bc03fa) /* 0.295902229 */, 18 }, /* 4649 */ { MAD_F(0x04bc5cfc) /* 0.295987115 */, 18 }, /* 4650 */ { MAD_F(0x04bcb600) /* 0.296072008 */, 18 }, /* 4651 */ { MAD_F(0x04bd0f06) /* 0.296156906 */, 18 }, /* 4652 */ { MAD_F(0x04bd680d) /* 0.296241810 */, 18 }, /* 4653 */ { MAD_F(0x04bdc116) /* 0.296326721 */, 18 }, /* 4654 */ { MAD_F(0x04be1a21) /* 0.296411637 */, 18 }, /* 4655 */ { MAD_F(0x04be732d) /* 0.296496560 */, 18 }, /* 4656 */ { MAD_F(0x04becc3b) /* 0.296581488 */, 18 }, /* 4657 */ { MAD_F(0x04bf254a) /* 0.296666423 */, 18 }, /* 4658 */ { MAD_F(0x04bf7e5b) /* 0.296751364 */, 18 }, /* 4659 */ { MAD_F(0x04bfd76e) /* 0.296836311 */, 18 }, /* 4660 */ { MAD_F(0x04c03083) /* 0.296921264 */, 18 }, /* 4661 */ { MAD_F(0x04c08999) /* 0.297006223 */, 18 }, /* 4662 */ { MAD_F(0x04c0e2b0) /* 0.297091188 */, 18 }, /* 4663 */ { MAD_F(0x04c13bca) /* 0.297176159 */, 18 }, /* 4664 */ { MAD_F(0x04c194e4) /* 0.297261136 */, 18 }, /* 4665 */ { MAD_F(0x04c1ee01) /* 0.297346120 */, 18 }, /* 4666 */ { MAD_F(0x04c2471f) /* 0.297431109 */, 18 }, /* 4667 */ { MAD_F(0x04c2a03f) /* 0.297516105 */, 18 }, /* 4668 */ { MAD_F(0x04c2f960) /* 0.297601106 */, 18 }, /* 4669 */ { MAD_F(0x04c35283) /* 0.297686114 */, 18 }, /* 4670 */ { MAD_F(0x04c3aba8) /* 0.297771128 */, 18 }, /* 4671 */ { MAD_F(0x04c404ce) /* 0.297856147 */, 18 }, /* 4672 */ { MAD_F(0x04c45df6) /* 0.297941173 */, 18 }, /* 4673 */ { MAD_F(0x04c4b720) /* 0.298026205 */, 18 }, /* 4674 */ { MAD_F(0x04c5104b) /* 0.298111243 */, 18 }, /* 4675 */ { MAD_F(0x04c56978) /* 0.298196287 */, 18 }, /* 4676 */ { MAD_F(0x04c5c2a7) /* 0.298281337 */, 18 }, /* 4677 */ { MAD_F(0x04c61bd7) /* 0.298366393 */, 18 }, /* 4678 */ { MAD_F(0x04c67508) /* 0.298451456 */, 18 }, /* 4679 */ { MAD_F(0x04c6ce3c) /* 0.298536524 */, 18 }, /* 4680 */ { MAD_F(0x04c72771) /* 0.298621598 */, 18 }, /* 4681 */ { MAD_F(0x04c780a7) /* 0.298706679 */, 18 }, /* 4682 */ { MAD_F(0x04c7d9df) /* 0.298791765 */, 18 }, /* 4683 */ { MAD_F(0x04c83319) /* 0.298876858 */, 18 }, /* 4684 */ { MAD_F(0x04c88c55) /* 0.298961956 */, 18 }, /* 4685 */ { MAD_F(0x04c8e592) /* 0.299047061 */, 18 }, /* 4686 */ { MAD_F(0x04c93ed1) /* 0.299132172 */, 18 }, /* 4687 */ { MAD_F(0x04c99811) /* 0.299217288 */, 18 }, /* 4688 */ { MAD_F(0x04c9f153) /* 0.299302411 */, 18 }, /* 4689 */ { MAD_F(0x04ca4a97) /* 0.299387540 */, 18 }, /* 4690 */ { MAD_F(0x04caa3dc) /* 0.299472675 */, 18 }, /* 4691 */ { MAD_F(0x04cafd23) /* 0.299557816 */, 18 }, /* 4692 */ { MAD_F(0x04cb566b) /* 0.299642963 */, 18 }, /* 4693 */ { MAD_F(0x04cbafb5) /* 0.299728116 */, 18 }, /* 4694 */ { MAD_F(0x04cc0901) /* 0.299813275 */, 18 }, /* 4695 */ { MAD_F(0x04cc624e) /* 0.299898440 */, 18 }, /* 4696 */ { MAD_F(0x04ccbb9d) /* 0.299983611 */, 18 }, /* 4697 */ { MAD_F(0x04cd14ee) /* 0.300068789 */, 18 }, /* 4698 */ { MAD_F(0x04cd6e40) /* 0.300153972 */, 18 }, /* 4699 */ { MAD_F(0x04cdc794) /* 0.300239161 */, 18 }, /* 4700 */ { MAD_F(0x04ce20e9) /* 0.300324357 */, 18 }, /* 4701 */ { MAD_F(0x04ce7a40) /* 0.300409558 */, 18 }, /* 4702 */ { MAD_F(0x04ced399) /* 0.300494765 */, 18 }, /* 4703 */ { MAD_F(0x04cf2cf3) /* 0.300579979 */, 18 }, /* 4704 */ { MAD_F(0x04cf864f) /* 0.300665198 */, 18 }, /* 4705 */ { MAD_F(0x04cfdfad) /* 0.300750424 */, 18 }, /* 4706 */ { MAD_F(0x04d0390c) /* 0.300835656 */, 18 }, /* 4707 */ { MAD_F(0x04d0926d) /* 0.300920893 */, 18 }, /* 4708 */ { MAD_F(0x04d0ebcf) /* 0.301006137 */, 18 }, /* 4709 */ { MAD_F(0x04d14533) /* 0.301091387 */, 18 }, /* 4710 */ { MAD_F(0x04d19e99) /* 0.301176643 */, 18 }, /* 4711 */ { MAD_F(0x04d1f800) /* 0.301261904 */, 18 }, /* 4712 */ { MAD_F(0x04d25169) /* 0.301347172 */, 18 }, /* 4713 */ { MAD_F(0x04d2aad4) /* 0.301432446 */, 18 }, /* 4714 */ { MAD_F(0x04d30440) /* 0.301517726 */, 18 }, /* 4715 */ { MAD_F(0x04d35dae) /* 0.301603012 */, 18 }, /* 4716 */ { MAD_F(0x04d3b71d) /* 0.301688304 */, 18 }, /* 4717 */ { MAD_F(0x04d4108e) /* 0.301773602 */, 18 }, /* 4718 */ { MAD_F(0x04d46a01) /* 0.301858906 */, 18 }, /* 4719 */ { MAD_F(0x04d4c375) /* 0.301944216 */, 18 }, /* 4720 */ { MAD_F(0x04d51ceb) /* 0.302029532 */, 18 }, /* 4721 */ { MAD_F(0x04d57662) /* 0.302114854 */, 18 }, /* 4722 */ { MAD_F(0x04d5cfdb) /* 0.302200182 */, 18 }, /* 4723 */ { MAD_F(0x04d62956) /* 0.302285516 */, 18 }, /* 4724 */ { MAD_F(0x04d682d2) /* 0.302370856 */, 18 }, /* 4725 */ { MAD_F(0x04d6dc50) /* 0.302456203 */, 18 }, /* 4726 */ { MAD_F(0x04d735d0) /* 0.302541555 */, 18 }, /* 4727 */ { MAD_F(0x04d78f51) /* 0.302626913 */, 18 }, /* 4728 */ { MAD_F(0x04d7e8d4) /* 0.302712277 */, 18 }, /* 4729 */ { MAD_F(0x04d84258) /* 0.302797648 */, 18 }, /* 4730 */ { MAD_F(0x04d89bde) /* 0.302883024 */, 18 }, /* 4731 */ { MAD_F(0x04d8f566) /* 0.302968406 */, 18 }, /* 4732 */ { MAD_F(0x04d94eef) /* 0.303053794 */, 18 }, /* 4733 */ { MAD_F(0x04d9a87a) /* 0.303139189 */, 18 }, /* 4734 */ { MAD_F(0x04da0207) /* 0.303224589 */, 18 }, /* 4735 */ { MAD_F(0x04da5b95) /* 0.303309995 */, 18 }, /* 4736 */ { MAD_F(0x04dab524) /* 0.303395408 */, 18 }, /* 4737 */ { MAD_F(0x04db0eb6) /* 0.303480826 */, 18 }, /* 4738 */ { MAD_F(0x04db6849) /* 0.303566251 */, 18 }, /* 4739 */ { MAD_F(0x04dbc1dd) /* 0.303651681 */, 18 }, /* 4740 */ { MAD_F(0x04dc1b73) /* 0.303737117 */, 18 }, /* 4741 */ { MAD_F(0x04dc750b) /* 0.303822560 */, 18 }, /* 4742 */ { MAD_F(0x04dccea5) /* 0.303908008 */, 18 }, /* 4743 */ { MAD_F(0x04dd2840) /* 0.303993463 */, 18 }, /* 4744 */ { MAD_F(0x04dd81dc) /* 0.304078923 */, 18 }, /* 4745 */ { MAD_F(0x04dddb7a) /* 0.304164390 */, 18 }, /* 4746 */ { MAD_F(0x04de351a) /* 0.304249862 */, 18 }, /* 4747 */ { MAD_F(0x04de8ebc) /* 0.304335340 */, 18 }, /* 4748 */ { MAD_F(0x04dee85f) /* 0.304420825 */, 18 }, /* 4749 */ { MAD_F(0x04df4203) /* 0.304506315 */, 18 }, /* 4750 */ { MAD_F(0x04df9baa) /* 0.304591812 */, 18 }, /* 4751 */ { MAD_F(0x04dff552) /* 0.304677314 */, 18 }, /* 4752 */ { MAD_F(0x04e04efb) /* 0.304762823 */, 18 }, /* 4753 */ { MAD_F(0x04e0a8a6) /* 0.304848337 */, 18 }, /* 4754 */ { MAD_F(0x04e10253) /* 0.304933858 */, 18 }, /* 4755 */ { MAD_F(0x04e15c01) /* 0.305019384 */, 18 }, /* 4756 */ { MAD_F(0x04e1b5b1) /* 0.305104917 */, 18 }, /* 4757 */ { MAD_F(0x04e20f63) /* 0.305190455 */, 18 }, /* 4758 */ { MAD_F(0x04e26916) /* 0.305275999 */, 18 }, /* 4759 */ { MAD_F(0x04e2c2cb) /* 0.305361550 */, 18 }, /* 4760 */ { MAD_F(0x04e31c81) /* 0.305447106 */, 18 }, /* 4761 */ { MAD_F(0x04e37639) /* 0.305532669 */, 18 }, /* 4762 */ { MAD_F(0x04e3cff3) /* 0.305618237 */, 18 }, /* 4763 */ { MAD_F(0x04e429ae) /* 0.305703811 */, 18 }, /* 4764 */ { MAD_F(0x04e4836b) /* 0.305789392 */, 18 }, /* 4765 */ { MAD_F(0x04e4dd29) /* 0.305874978 */, 18 }, /* 4766 */ { MAD_F(0x04e536e9) /* 0.305960571 */, 18 }, /* 4767 */ { MAD_F(0x04e590ab) /* 0.306046169 */, 18 }, /* 4768 */ { MAD_F(0x04e5ea6e) /* 0.306131773 */, 18 }, /* 4769 */ { MAD_F(0x04e64433) /* 0.306217383 */, 18 }, /* 4770 */ { MAD_F(0x04e69df9) /* 0.306303000 */, 18 }, /* 4771 */ { MAD_F(0x04e6f7c1) /* 0.306388622 */, 18 }, /* 4772 */ { MAD_F(0x04e7518b) /* 0.306474250 */, 18 }, /* 4773 */ { MAD_F(0x04e7ab56) /* 0.306559885 */, 18 }, /* 4774 */ { MAD_F(0x04e80523) /* 0.306645525 */, 18 }, /* 4775 */ { MAD_F(0x04e85ef2) /* 0.306731171 */, 18 }, /* 4776 */ { MAD_F(0x04e8b8c2) /* 0.306816823 */, 18 }, /* 4777 */ { MAD_F(0x04e91293) /* 0.306902481 */, 18 }, /* 4778 */ { MAD_F(0x04e96c67) /* 0.306988145 */, 18 }, /* 4779 */ { MAD_F(0x04e9c63b) /* 0.307073816 */, 18 }, /* 4780 */ { MAD_F(0x04ea2012) /* 0.307159492 */, 18 }, /* 4781 */ { MAD_F(0x04ea79ea) /* 0.307245174 */, 18 }, /* 4782 */ { MAD_F(0x04ead3c4) /* 0.307330862 */, 18 }, /* 4783 */ { MAD_F(0x04eb2d9f) /* 0.307416556 */, 18 }, /* 4784 */ { MAD_F(0x04eb877c) /* 0.307502256 */, 18 }, /* 4785 */ { MAD_F(0x04ebe15b) /* 0.307587962 */, 18 }, /* 4786 */ { MAD_F(0x04ec3b3b) /* 0.307673674 */, 18 }, /* 4787 */ { MAD_F(0x04ec951c) /* 0.307759392 */, 18 }, /* 4788 */ { MAD_F(0x04ecef00) /* 0.307845115 */, 18 }, /* 4789 */ { MAD_F(0x04ed48e5) /* 0.307930845 */, 18 }, /* 4790 */ { MAD_F(0x04eda2cb) /* 0.308016581 */, 18 }, /* 4791 */ { MAD_F(0x04edfcb3) /* 0.308102323 */, 18 }, /* 4792 */ { MAD_F(0x04ee569d) /* 0.308188071 */, 18 }, /* 4793 */ { MAD_F(0x04eeb088) /* 0.308273824 */, 18 }, /* 4794 */ { MAD_F(0x04ef0a75) /* 0.308359584 */, 18 }, /* 4795 */ { MAD_F(0x04ef6464) /* 0.308445350 */, 18 }, /* 4796 */ { MAD_F(0x04efbe54) /* 0.308531121 */, 18 }, /* 4797 */ { MAD_F(0x04f01846) /* 0.308616899 */, 18 }, /* 4798 */ { MAD_F(0x04f07239) /* 0.308702682 */, 18 }, /* 4799 */ { MAD_F(0x04f0cc2e) /* 0.308788472 */, 18 }, /* 4800 */ { MAD_F(0x04f12624) /* 0.308874267 */, 18 }, /* 4801 */ { MAD_F(0x04f1801d) /* 0.308960068 */, 18 }, /* 4802 */ { MAD_F(0x04f1da16) /* 0.309045876 */, 18 }, /* 4803 */ { MAD_F(0x04f23412) /* 0.309131689 */, 18 }, /* 4804 */ { MAD_F(0x04f28e0f) /* 0.309217508 */, 18 }, /* 4805 */ { MAD_F(0x04f2e80d) /* 0.309303334 */, 18 }, /* 4806 */ { MAD_F(0x04f3420d) /* 0.309389165 */, 18 }, /* 4807 */ { MAD_F(0x04f39c0f) /* 0.309475002 */, 18 }, /* 4808 */ { MAD_F(0x04f3f612) /* 0.309560845 */, 18 }, /* 4809 */ { MAD_F(0x04f45017) /* 0.309646694 */, 18 }, /* 4810 */ { MAD_F(0x04f4aa1e) /* 0.309732549 */, 18 }, /* 4811 */ { MAD_F(0x04f50426) /* 0.309818410 */, 18 }, /* 4812 */ { MAD_F(0x04f55e30) /* 0.309904277 */, 18 }, /* 4813 */ { MAD_F(0x04f5b83b) /* 0.309990150 */, 18 }, /* 4814 */ { MAD_F(0x04f61248) /* 0.310076028 */, 18 }, /* 4815 */ { MAD_F(0x04f66c56) /* 0.310161913 */, 18 }, /* 4816 */ { MAD_F(0x04f6c666) /* 0.310247804 */, 18 }, /* 4817 */ { MAD_F(0x04f72078) /* 0.310333700 */, 18 }, /* 4818 */ { MAD_F(0x04f77a8b) /* 0.310419603 */, 18 }, /* 4819 */ { MAD_F(0x04f7d4a0) /* 0.310505511 */, 18 }, /* 4820 */ { MAD_F(0x04f82eb7) /* 0.310591426 */, 18 }, /* 4821 */ { MAD_F(0x04f888cf) /* 0.310677346 */, 18 }, /* 4822 */ { MAD_F(0x04f8e2e9) /* 0.310763272 */, 18 }, /* 4823 */ { MAD_F(0x04f93d04) /* 0.310849205 */, 18 }, /* 4824 */ { MAD_F(0x04f99721) /* 0.310935143 */, 18 }, /* 4825 */ { MAD_F(0x04f9f13f) /* 0.311021087 */, 18 }, /* 4826 */ { MAD_F(0x04fa4b5f) /* 0.311107037 */, 18 }, /* 4827 */ { MAD_F(0x04faa581) /* 0.311192993 */, 18 }, /* 4828 */ { MAD_F(0x04faffa4) /* 0.311278955 */, 18 }, /* 4829 */ { MAD_F(0x04fb59c9) /* 0.311364923 */, 18 }, /* 4830 */ { MAD_F(0x04fbb3ef) /* 0.311450897 */, 18 }, /* 4831 */ { MAD_F(0x04fc0e17) /* 0.311536877 */, 18 }, /* 4832 */ { MAD_F(0x04fc6841) /* 0.311622862 */, 18 }, /* 4833 */ { MAD_F(0x04fcc26c) /* 0.311708854 */, 18 }, /* 4834 */ { MAD_F(0x04fd1c99) /* 0.311794851 */, 18 }, /* 4835 */ { MAD_F(0x04fd76c7) /* 0.311880855 */, 18 }, /* 4836 */ { MAD_F(0x04fdd0f7) /* 0.311966864 */, 18 }, /* 4837 */ { MAD_F(0x04fe2b29) /* 0.312052880 */, 18 }, /* 4838 */ { MAD_F(0x04fe855c) /* 0.312138901 */, 18 }, /* 4839 */ { MAD_F(0x04fedf91) /* 0.312224928 */, 18 }, /* 4840 */ { MAD_F(0x04ff39c7) /* 0.312310961 */, 18 }, /* 4841 */ { MAD_F(0x04ff93ff) /* 0.312397000 */, 18 }, /* 4842 */ { MAD_F(0x04ffee38) /* 0.312483045 */, 18 }, /* 4843 */ { MAD_F(0x05004874) /* 0.312569096 */, 18 }, /* 4844 */ { MAD_F(0x0500a2b0) /* 0.312655153 */, 18 }, /* 4845 */ { MAD_F(0x0500fcef) /* 0.312741216 */, 18 }, /* 4846 */ { MAD_F(0x0501572e) /* 0.312827284 */, 18 }, /* 4847 */ { MAD_F(0x0501b170) /* 0.312913359 */, 18 }, /* 4848 */ { MAD_F(0x05020bb3) /* 0.312999439 */, 18 }, /* 4849 */ { MAD_F(0x050265f8) /* 0.313085526 */, 18 }, /* 4850 */ { MAD_F(0x0502c03e) /* 0.313171618 */, 18 }, /* 4851 */ { MAD_F(0x05031a86) /* 0.313257716 */, 18 }, /* 4852 */ { MAD_F(0x050374cf) /* 0.313343820 */, 18 }, /* 4853 */ { MAD_F(0x0503cf1a) /* 0.313429931 */, 18 }, /* 4854 */ { MAD_F(0x05042967) /* 0.313516047 */, 18 }, /* 4855 */ { MAD_F(0x050483b5) /* 0.313602168 */, 18 }, /* 4856 */ { MAD_F(0x0504de05) /* 0.313688296 */, 18 }, /* 4857 */ { MAD_F(0x05053856) /* 0.313774430 */, 18 }, /* 4858 */ { MAD_F(0x050592a9) /* 0.313860570 */, 18 }, /* 4859 */ { MAD_F(0x0505ecfd) /* 0.313946715 */, 18 }, /* 4860 */ { MAD_F(0x05064754) /* 0.314032867 */, 18 }, /* 4861 */ { MAD_F(0x0506a1ab) /* 0.314119024 */, 18 }, /* 4862 */ { MAD_F(0x0506fc04) /* 0.314205187 */, 18 }, /* 4863 */ { MAD_F(0x0507565f) /* 0.314291357 */, 18 }, /* 4864 */ { MAD_F(0x0507b0bc) /* 0.314377532 */, 18 }, /* 4865 */ { MAD_F(0x05080b1a) /* 0.314463713 */, 18 }, /* 4866 */ { MAD_F(0x05086579) /* 0.314549900 */, 18 }, /* 4867 */ { MAD_F(0x0508bfdb) /* 0.314636092 */, 18 }, /* 4868 */ { MAD_F(0x05091a3d) /* 0.314722291 */, 18 }, /* 4869 */ { MAD_F(0x050974a2) /* 0.314808496 */, 18 }, /* 4870 */ { MAD_F(0x0509cf08) /* 0.314894706 */, 18 }, /* 4871 */ { MAD_F(0x050a296f) /* 0.314980923 */, 18 }, /* 4872 */ { MAD_F(0x050a83d8) /* 0.315067145 */, 18 }, /* 4873 */ { MAD_F(0x050ade43) /* 0.315153373 */, 18 }, /* 4874 */ { MAD_F(0x050b38af) /* 0.315239607 */, 18 }, /* 4875 */ { MAD_F(0x050b931d) /* 0.315325847 */, 18 }, /* 4876 */ { MAD_F(0x050bed8d) /* 0.315412093 */, 18 }, /* 4877 */ { MAD_F(0x050c47fe) /* 0.315498345 */, 18 }, /* 4878 */ { MAD_F(0x050ca271) /* 0.315584603 */, 18 }, /* 4879 */ { MAD_F(0x050cfce5) /* 0.315670866 */, 18 }, /* 4880 */ { MAD_F(0x050d575b) /* 0.315757136 */, 18 }, /* 4881 */ { MAD_F(0x050db1d2) /* 0.315843411 */, 18 }, /* 4882 */ { MAD_F(0x050e0c4b) /* 0.315929693 */, 18 }, /* 4883 */ { MAD_F(0x050e66c5) /* 0.316015980 */, 18 }, /* 4884 */ { MAD_F(0x050ec141) /* 0.316102273 */, 18 }, /* 4885 */ { MAD_F(0x050f1bbf) /* 0.316188572 */, 18 }, /* 4886 */ { MAD_F(0x050f763e) /* 0.316274877 */, 18 }, /* 4887 */ { MAD_F(0x050fd0bf) /* 0.316361187 */, 18 }, /* 4888 */ { MAD_F(0x05102b42) /* 0.316447504 */, 18 }, /* 4889 */ { MAD_F(0x051085c6) /* 0.316533826 */, 18 }, /* 4890 */ { MAD_F(0x0510e04b) /* 0.316620155 */, 18 }, /* 4891 */ { MAD_F(0x05113ad3) /* 0.316706489 */, 18 }, /* 4892 */ { MAD_F(0x0511955b) /* 0.316792829 */, 18 }, /* 4893 */ { MAD_F(0x0511efe6) /* 0.316879175 */, 18 }, /* 4894 */ { MAD_F(0x05124a72) /* 0.316965527 */, 18 }, /* 4895 */ { MAD_F(0x0512a4ff) /* 0.317051885 */, 18 }, /* 4896 */ { MAD_F(0x0512ff8e) /* 0.317138249 */, 18 }, /* 4897 */ { MAD_F(0x05135a1f) /* 0.317224618 */, 18 }, /* 4898 */ { MAD_F(0x0513b4b1) /* 0.317310994 */, 18 }, /* 4899 */ { MAD_F(0x05140f45) /* 0.317397375 */, 18 }, /* 4900 */ { MAD_F(0x051469da) /* 0.317483762 */, 18 }, /* 4901 */ { MAD_F(0x0514c471) /* 0.317570155 */, 18 }, /* 4902 */ { MAD_F(0x05151f0a) /* 0.317656554 */, 18 }, /* 4903 */ { MAD_F(0x051579a4) /* 0.317742959 */, 18 }, /* 4904 */ { MAD_F(0x0515d440) /* 0.317829370 */, 18 }, /* 4905 */ { MAD_F(0x05162edd) /* 0.317915786 */, 18 }, /* 4906 */ { MAD_F(0x0516897c) /* 0.318002209 */, 18 }, /* 4907 */ { MAD_F(0x0516e41c) /* 0.318088637 */, 18 }, /* 4908 */ { MAD_F(0x05173ebe) /* 0.318175071 */, 18 }, /* 4909 */ { MAD_F(0x05179962) /* 0.318261511 */, 18 }, /* 4910 */ { MAD_F(0x0517f407) /* 0.318347957 */, 18 }, /* 4911 */ { MAD_F(0x05184eae) /* 0.318434409 */, 18 }, /* 4912 */ { MAD_F(0x0518a956) /* 0.318520867 */, 18 }, /* 4913 */ { MAD_F(0x05190400) /* 0.318607330 */, 18 }, /* 4914 */ { MAD_F(0x05195eab) /* 0.318693800 */, 18 }, /* 4915 */ { MAD_F(0x0519b958) /* 0.318780275 */, 18 }, /* 4916 */ { MAD_F(0x051a1407) /* 0.318866756 */, 18 }, /* 4917 */ { MAD_F(0x051a6eb7) /* 0.318953243 */, 18 }, /* 4918 */ { MAD_F(0x051ac969) /* 0.319039736 */, 18 }, /* 4919 */ { MAD_F(0x051b241c) /* 0.319126235 */, 18 }, /* 4920 */ { MAD_F(0x051b7ed1) /* 0.319212739 */, 18 }, /* 4921 */ { MAD_F(0x051bd987) /* 0.319299250 */, 18 }, /* 4922 */ { MAD_F(0x051c3440) /* 0.319385766 */, 18 }, /* 4923 */ { MAD_F(0x051c8ef9) /* 0.319472288 */, 18 }, /* 4924 */ { MAD_F(0x051ce9b4) /* 0.319558816 */, 18 }, /* 4925 */ { MAD_F(0x051d4471) /* 0.319645350 */, 18 }, /* 4926 */ { MAD_F(0x051d9f2f) /* 0.319731890 */, 18 }, /* 4927 */ { MAD_F(0x051df9ef) /* 0.319818435 */, 18 }, /* 4928 */ { MAD_F(0x051e54b1) /* 0.319904987 */, 18 }, /* 4929 */ { MAD_F(0x051eaf74) /* 0.319991544 */, 18 }, /* 4930 */ { MAD_F(0x051f0a38) /* 0.320078107 */, 18 }, /* 4931 */ { MAD_F(0x051f64ff) /* 0.320164676 */, 18 }, /* 4932 */ { MAD_F(0x051fbfc6) /* 0.320251251 */, 18 }, /* 4933 */ { MAD_F(0x05201a90) /* 0.320337832 */, 18 }, /* 4934 */ { MAD_F(0x0520755b) /* 0.320424419 */, 18 }, /* 4935 */ { MAD_F(0x0520d027) /* 0.320511011 */, 18 }, /* 4936 */ { MAD_F(0x05212af5) /* 0.320597609 */, 18 }, /* 4937 */ { MAD_F(0x052185c5) /* 0.320684213 */, 18 }, /* 4938 */ { MAD_F(0x0521e096) /* 0.320770823 */, 18 }, /* 4939 */ { MAD_F(0x05223b69) /* 0.320857439 */, 18 }, /* 4940 */ { MAD_F(0x0522963d) /* 0.320944061 */, 18 }, /* 4941 */ { MAD_F(0x0522f113) /* 0.321030688 */, 18 }, /* 4942 */ { MAD_F(0x05234bea) /* 0.321117322 */, 18 }, /* 4943 */ { MAD_F(0x0523a6c3) /* 0.321203961 */, 18 }, /* 4944 */ { MAD_F(0x0524019e) /* 0.321290606 */, 18 }, /* 4945 */ { MAD_F(0x05245c7a) /* 0.321377257 */, 18 }, /* 4946 */ { MAD_F(0x0524b758) /* 0.321463913 */, 18 }, /* 4947 */ { MAD_F(0x05251237) /* 0.321550576 */, 18 }, /* 4948 */ { MAD_F(0x05256d18) /* 0.321637244 */, 18 }, /* 4949 */ { MAD_F(0x0525c7fb) /* 0.321723919 */, 18 }, /* 4950 */ { MAD_F(0x052622df) /* 0.321810599 */, 18 }, /* 4951 */ { MAD_F(0x05267dc4) /* 0.321897285 */, 18 }, /* 4952 */ { MAD_F(0x0526d8ab) /* 0.321983976 */, 18 }, /* 4953 */ { MAD_F(0x05273394) /* 0.322070674 */, 18 }, /* 4954 */ { MAD_F(0x05278e7e) /* 0.322157377 */, 18 }, /* 4955 */ { MAD_F(0x0527e96a) /* 0.322244087 */, 18 }, /* 4956 */ { MAD_F(0x05284457) /* 0.322330802 */, 18 }, /* 4957 */ { MAD_F(0x05289f46) /* 0.322417523 */, 18 }, /* 4958 */ { MAD_F(0x0528fa37) /* 0.322504249 */, 18 }, /* 4959 */ { MAD_F(0x05295529) /* 0.322590982 */, 18 }, /* 4960 */ { MAD_F(0x0529b01d) /* 0.322677720 */, 18 }, /* 4961 */ { MAD_F(0x052a0b12) /* 0.322764465 */, 18 }, /* 4962 */ { MAD_F(0x052a6609) /* 0.322851215 */, 18 }, /* 4963 */ { MAD_F(0x052ac101) /* 0.322937971 */, 18 }, /* 4964 */ { MAD_F(0x052b1bfb) /* 0.323024732 */, 18 }, /* 4965 */ { MAD_F(0x052b76f7) /* 0.323111500 */, 18 }, /* 4966 */ { MAD_F(0x052bd1f4) /* 0.323198273 */, 18 }, /* 4967 */ { MAD_F(0x052c2cf2) /* 0.323285052 */, 18 }, /* 4968 */ { MAD_F(0x052c87f2) /* 0.323371837 */, 18 }, /* 4969 */ { MAD_F(0x052ce2f4) /* 0.323458628 */, 18 }, /* 4970 */ { MAD_F(0x052d3df7) /* 0.323545425 */, 18 }, /* 4971 */ { MAD_F(0x052d98fc) /* 0.323632227 */, 18 }, /* 4972 */ { MAD_F(0x052df403) /* 0.323719036 */, 18 }, /* 4973 */ { MAD_F(0x052e4f0b) /* 0.323805850 */, 18 }, /* 4974 */ { MAD_F(0x052eaa14) /* 0.323892670 */, 18 }, /* 4975 */ { MAD_F(0x052f051f) /* 0.323979496 */, 18 }, /* 4976 */ { MAD_F(0x052f602c) /* 0.324066327 */, 18 }, /* 4977 */ { MAD_F(0x052fbb3a) /* 0.324153165 */, 18 }, /* 4978 */ { MAD_F(0x0530164a) /* 0.324240008 */, 18 }, /* 4979 */ { MAD_F(0x0530715b) /* 0.324326857 */, 18 }, /* 4980 */ { MAD_F(0x0530cc6e) /* 0.324413712 */, 18 }, /* 4981 */ { MAD_F(0x05312783) /* 0.324500572 */, 18 }, /* 4982 */ { MAD_F(0x05318299) /* 0.324587439 */, 18 }, /* 4983 */ { MAD_F(0x0531ddb0) /* 0.324674311 */, 18 }, /* 4984 */ { MAD_F(0x053238ca) /* 0.324761189 */, 18 }, /* 4985 */ { MAD_F(0x053293e4) /* 0.324848073 */, 18 }, /* 4986 */ { MAD_F(0x0532ef01) /* 0.324934963 */, 18 }, /* 4987 */ { MAD_F(0x05334a1e) /* 0.325021858 */, 18 }, /* 4988 */ { MAD_F(0x0533a53e) /* 0.325108760 */, 18 }, /* 4989 */ { MAD_F(0x0534005f) /* 0.325195667 */, 18 }, /* 4990 */ { MAD_F(0x05345b81) /* 0.325282580 */, 18 }, /* 4991 */ { MAD_F(0x0534b6a5) /* 0.325369498 */, 18 }, /* 4992 */ { MAD_F(0x053511cb) /* 0.325456423 */, 18 }, /* 4993 */ { MAD_F(0x05356cf2) /* 0.325543353 */, 18 }, /* 4994 */ { MAD_F(0x0535c81b) /* 0.325630290 */, 18 }, /* 4995 */ { MAD_F(0x05362345) /* 0.325717232 */, 18 }, /* 4996 */ { MAD_F(0x05367e71) /* 0.325804179 */, 18 }, /* 4997 */ { MAD_F(0x0536d99f) /* 0.325891133 */, 18 }, /* 4998 */ { MAD_F(0x053734ce) /* 0.325978092 */, 18 }, /* 4999 */ { MAD_F(0x05378ffe) /* 0.326065057 */, 18 }, /* 5000 */ { MAD_F(0x0537eb30) /* 0.326152028 */, 18 }, /* 5001 */ { MAD_F(0x05384664) /* 0.326239005 */, 18 }, /* 5002 */ { MAD_F(0x0538a199) /* 0.326325988 */, 18 }, /* 5003 */ { MAD_F(0x0538fcd0) /* 0.326412976 */, 18 }, /* 5004 */ { MAD_F(0x05395808) /* 0.326499970 */, 18 }, /* 5005 */ { MAD_F(0x0539b342) /* 0.326586970 */, 18 }, /* 5006 */ { MAD_F(0x053a0e7d) /* 0.326673976 */, 18 }, /* 5007 */ { MAD_F(0x053a69ba) /* 0.326760988 */, 18 }, /* 5008 */ { MAD_F(0x053ac4f9) /* 0.326848005 */, 18 }, /* 5009 */ { MAD_F(0x053b2039) /* 0.326935028 */, 18 }, /* 5010 */ { MAD_F(0x053b7b7b) /* 0.327022057 */, 18 }, /* 5011 */ { MAD_F(0x053bd6be) /* 0.327109092 */, 18 }, /* 5012 */ { MAD_F(0x053c3203) /* 0.327196132 */, 18 }, /* 5013 */ { MAD_F(0x053c8d49) /* 0.327283178 */, 18 }, /* 5014 */ { MAD_F(0x053ce891) /* 0.327370231 */, 18 }, /* 5015 */ { MAD_F(0x053d43da) /* 0.327457288 */, 18 }, /* 5016 */ { MAD_F(0x053d9f25) /* 0.327544352 */, 18 }, /* 5017 */ { MAD_F(0x053dfa72) /* 0.327631421 */, 18 }, /* 5018 */ { MAD_F(0x053e55c0) /* 0.327718497 */, 18 }, /* 5019 */ { MAD_F(0x053eb10f) /* 0.327805578 */, 18 }, /* 5020 */ { MAD_F(0x053f0c61) /* 0.327892665 */, 18 }, /* 5021 */ { MAD_F(0x053f67b3) /* 0.327979757 */, 18 }, /* 5022 */ { MAD_F(0x053fc308) /* 0.328066855 */, 18 }, /* 5023 */ { MAD_F(0x05401e5e) /* 0.328153960 */, 18 }, /* 5024 */ { MAD_F(0x054079b5) /* 0.328241070 */, 18 }, /* 5025 */ { MAD_F(0x0540d50e) /* 0.328328185 */, 18 }, /* 5026 */ { MAD_F(0x05413068) /* 0.328415307 */, 18 }, /* 5027 */ { MAD_F(0x05418bc4) /* 0.328502434 */, 18 }, /* 5028 */ { MAD_F(0x0541e722) /* 0.328589567 */, 18 }, /* 5029 */ { MAD_F(0x05424281) /* 0.328676706 */, 18 }, /* 5030 */ { MAD_F(0x05429de2) /* 0.328763850 */, 18 }, /* 5031 */ { MAD_F(0x0542f944) /* 0.328851001 */, 18 }, /* 5032 */ { MAD_F(0x054354a8) /* 0.328938157 */, 18 }, /* 5033 */ { MAD_F(0x0543b00d) /* 0.329025319 */, 18 }, /* 5034 */ { MAD_F(0x05440b74) /* 0.329112486 */, 18 }, /* 5035 */ { MAD_F(0x054466dd) /* 0.329199660 */, 18 }, /* 5036 */ { MAD_F(0x0544c247) /* 0.329286839 */, 18 }, /* 5037 */ { MAD_F(0x05451db2) /* 0.329374024 */, 18 }, /* 5038 */ { MAD_F(0x0545791f) /* 0.329461215 */, 18 }, /* 5039 */ { MAD_F(0x0545d48e) /* 0.329548411 */, 18 }, /* 5040 */ { MAD_F(0x05462ffe) /* 0.329635614 */, 18 }, /* 5041 */ { MAD_F(0x05468b70) /* 0.329722822 */, 18 }, /* 5042 */ { MAD_F(0x0546e6e3) /* 0.329810036 */, 18 }, /* 5043 */ { MAD_F(0x05474258) /* 0.329897255 */, 18 }, /* 5044 */ { MAD_F(0x05479dce) /* 0.329984481 */, 18 }, /* 5045 */ { MAD_F(0x0547f946) /* 0.330071712 */, 18 }, /* 5046 */ { MAD_F(0x054854c0) /* 0.330158949 */, 18 }, /* 5047 */ { MAD_F(0x0548b03b) /* 0.330246191 */, 18 }, /* 5048 */ { MAD_F(0x05490bb7) /* 0.330333440 */, 18 }, /* 5049 */ { MAD_F(0x05496735) /* 0.330420694 */, 18 }, /* 5050 */ { MAD_F(0x0549c2b5) /* 0.330507954 */, 18 }, /* 5051 */ { MAD_F(0x054a1e36) /* 0.330595220 */, 18 }, /* 5052 */ { MAD_F(0x054a79b9) /* 0.330682491 */, 18 }, /* 5053 */ { MAD_F(0x054ad53d) /* 0.330769768 */, 18 }, /* 5054 */ { MAD_F(0x054b30c3) /* 0.330857051 */, 18 }, /* 5055 */ { MAD_F(0x054b8c4b) /* 0.330944340 */, 18 }, /* 5056 */ { MAD_F(0x054be7d4) /* 0.331031635 */, 18 }, /* 5057 */ { MAD_F(0x054c435e) /* 0.331118935 */, 18 }, /* 5058 */ { MAD_F(0x054c9eea) /* 0.331206241 */, 18 }, /* 5059 */ { MAD_F(0x054cfa78) /* 0.331293553 */, 18 }, /* 5060 */ { MAD_F(0x054d5607) /* 0.331380870 */, 18 }, /* 5061 */ { MAD_F(0x054db197) /* 0.331468193 */, 18 }, /* 5062 */ { MAD_F(0x054e0d2a) /* 0.331555522 */, 18 }, /* 5063 */ { MAD_F(0x054e68bd) /* 0.331642857 */, 18 }, /* 5064 */ { MAD_F(0x054ec453) /* 0.331730198 */, 18 }, /* 5065 */ { MAD_F(0x054f1fe9) /* 0.331817544 */, 18 }, /* 5066 */ { MAD_F(0x054f7b82) /* 0.331904896 */, 18 }, /* 5067 */ { MAD_F(0x054fd71c) /* 0.331992254 */, 18 }, /* 5068 */ { MAD_F(0x055032b7) /* 0.332079617 */, 18 }, /* 5069 */ { MAD_F(0x05508e54) /* 0.332166986 */, 18 }, /* 5070 */ { MAD_F(0x0550e9f3) /* 0.332254361 */, 18 }, /* 5071 */ { MAD_F(0x05514593) /* 0.332341742 */, 18 }, /* 5072 */ { MAD_F(0x0551a134) /* 0.332429129 */, 18 }, /* 5073 */ { MAD_F(0x0551fcd8) /* 0.332516521 */, 18 }, /* 5074 */ { MAD_F(0x0552587c) /* 0.332603919 */, 18 }, /* 5075 */ { MAD_F(0x0552b423) /* 0.332691323 */, 18 }, /* 5076 */ { MAD_F(0x05530fca) /* 0.332778732 */, 18 }, /* 5077 */ { MAD_F(0x05536b74) /* 0.332866147 */, 18 }, /* 5078 */ { MAD_F(0x0553c71f) /* 0.332953568 */, 18 }, /* 5079 */ { MAD_F(0x055422cb) /* 0.333040995 */, 18 }, /* 5080 */ { MAD_F(0x05547e79) /* 0.333128427 */, 18 }, /* 5081 */ { MAD_F(0x0554da29) /* 0.333215865 */, 18 }, /* 5082 */ { MAD_F(0x055535da) /* 0.333303309 */, 18 }, /* 5083 */ { MAD_F(0x0555918c) /* 0.333390759 */, 18 }, /* 5084 */ { MAD_F(0x0555ed40) /* 0.333478214 */, 18 }, /* 5085 */ { MAD_F(0x055648f6) /* 0.333565675 */, 18 }, /* 5086 */ { MAD_F(0x0556a4ad) /* 0.333653142 */, 18 }, /* 5087 */ { MAD_F(0x05570066) /* 0.333740615 */, 18 }, /* 5088 */ { MAD_F(0x05575c20) /* 0.333828093 */, 18 }, /* 5089 */ { MAD_F(0x0557b7dc) /* 0.333915577 */, 18 }, /* 5090 */ { MAD_F(0x05581399) /* 0.334003067 */, 18 }, /* 5091 */ { MAD_F(0x05586f58) /* 0.334090562 */, 18 }, /* 5092 */ { MAD_F(0x0558cb19) /* 0.334178063 */, 18 }, /* 5093 */ { MAD_F(0x055926db) /* 0.334265570 */, 18 }, /* 5094 */ { MAD_F(0x0559829e) /* 0.334353083 */, 18 }, /* 5095 */ { MAD_F(0x0559de63) /* 0.334440601 */, 18 }, /* 5096 */ { MAD_F(0x055a3a2a) /* 0.334528126 */, 18 }, /* 5097 */ { MAD_F(0x055a95f2) /* 0.334615655 */, 18 }, /* 5098 */ { MAD_F(0x055af1bb) /* 0.334703191 */, 18 }, /* 5099 */ { MAD_F(0x055b4d87) /* 0.334790732 */, 18 }, /* 5100 */ { MAD_F(0x055ba953) /* 0.334878279 */, 18 }, /* 5101 */ { MAD_F(0x055c0522) /* 0.334965832 */, 18 }, /* 5102 */ { MAD_F(0x055c60f1) /* 0.335053391 */, 18 }, /* 5103 */ { MAD_F(0x055cbcc3) /* 0.335140955 */, 18 }, /* 5104 */ { MAD_F(0x055d1896) /* 0.335228525 */, 18 }, /* 5105 */ { MAD_F(0x055d746a) /* 0.335316100 */, 18 }, /* 5106 */ { MAD_F(0x055dd040) /* 0.335403682 */, 18 }, /* 5107 */ { MAD_F(0x055e2c17) /* 0.335491269 */, 18 }, /* 5108 */ { MAD_F(0x055e87f0) /* 0.335578861 */, 18 }, /* 5109 */ { MAD_F(0x055ee3cb) /* 0.335666460 */, 18 }, /* 5110 */ { MAD_F(0x055f3fa7) /* 0.335754064 */, 18 }, /* 5111 */ { MAD_F(0x055f9b85) /* 0.335841674 */, 18 }, /* 5112 */ { MAD_F(0x055ff764) /* 0.335929290 */, 18 }, /* 5113 */ { MAD_F(0x05605344) /* 0.336016911 */, 18 }, /* 5114 */ { MAD_F(0x0560af27) /* 0.336104538 */, 18 }, /* 5115 */ { MAD_F(0x05610b0a) /* 0.336192171 */, 18 }, /* 5116 */ { MAD_F(0x056166f0) /* 0.336279809 */, 18 }, /* 5117 */ { MAD_F(0x0561c2d7) /* 0.336367453 */, 18 }, /* 5118 */ { MAD_F(0x05621ebf) /* 0.336455103 */, 18 }, /* 5119 */ { MAD_F(0x05627aa9) /* 0.336542759 */, 18 }, /* 5120 */ { MAD_F(0x0562d694) /* 0.336630420 */, 18 }, /* 5121 */ { MAD_F(0x05633281) /* 0.336718087 */, 18 }, /* 5122 */ { MAD_F(0x05638e70) /* 0.336805760 */, 18 }, /* 5123 */ { MAD_F(0x0563ea60) /* 0.336893439 */, 18 }, /* 5124 */ { MAD_F(0x05644651) /* 0.336981123 */, 18 }, /* 5125 */ { MAD_F(0x0564a244) /* 0.337068813 */, 18 }, /* 5126 */ { MAD_F(0x0564fe39) /* 0.337156508 */, 18 }, /* 5127 */ { MAD_F(0x05655a2f) /* 0.337244209 */, 18 }, /* 5128 */ { MAD_F(0x0565b627) /* 0.337331916 */, 18 }, /* 5129 */ { MAD_F(0x05661220) /* 0.337419629 */, 18 }, /* 5130 */ { MAD_F(0x05666e1a) /* 0.337507347 */, 18 }, /* 5131 */ { MAD_F(0x0566ca17) /* 0.337595071 */, 18 }, /* 5132 */ { MAD_F(0x05672614) /* 0.337682801 */, 18 }, /* 5133 */ { MAD_F(0x05678214) /* 0.337770537 */, 18 }, /* 5134 */ { MAD_F(0x0567de15) /* 0.337858278 */, 18 }, /* 5135 */ { MAD_F(0x05683a17) /* 0.337946025 */, 18 }, /* 5136 */ { MAD_F(0x0568961b) /* 0.338033777 */, 18 }, /* 5137 */ { MAD_F(0x0568f220) /* 0.338121535 */, 18 }, /* 5138 */ { MAD_F(0x05694e27) /* 0.338209299 */, 18 }, /* 5139 */ { MAD_F(0x0569aa30) /* 0.338297069 */, 18 }, /* 5140 */ { MAD_F(0x056a063a) /* 0.338384844 */, 18 }, /* 5141 */ { MAD_F(0x056a6245) /* 0.338472625 */, 18 }, /* 5142 */ { MAD_F(0x056abe52) /* 0.338560412 */, 18 }, /* 5143 */ { MAD_F(0x056b1a61) /* 0.338648204 */, 18 }, /* 5144 */ { MAD_F(0x056b7671) /* 0.338736002 */, 18 }, /* 5145 */ { MAD_F(0x056bd283) /* 0.338823806 */, 18 }, /* 5146 */ { MAD_F(0x056c2e96) /* 0.338911616 */, 18 }, /* 5147 */ { MAD_F(0x056c8aab) /* 0.338999431 */, 18 }, /* 5148 */ { MAD_F(0x056ce6c1) /* 0.339087252 */, 18 }, /* 5149 */ { MAD_F(0x056d42d9) /* 0.339175078 */, 18 }, /* 5150 */ { MAD_F(0x056d9ef2) /* 0.339262910 */, 18 }, /* 5151 */ { MAD_F(0x056dfb0d) /* 0.339350748 */, 18 }, /* 5152 */ { MAD_F(0x056e5729) /* 0.339438592 */, 18 }, /* 5153 */ { MAD_F(0x056eb347) /* 0.339526441 */, 18 }, /* 5154 */ { MAD_F(0x056f0f66) /* 0.339614296 */, 18 }, /* 5155 */ { MAD_F(0x056f6b87) /* 0.339702157 */, 18 }, /* 5156 */ { MAD_F(0x056fc7aa) /* 0.339790023 */, 18 }, /* 5157 */ { MAD_F(0x057023cd) /* 0.339877895 */, 18 }, /* 5158 */ { MAD_F(0x05707ff3) /* 0.339965773 */, 18 }, /* 5159 */ { MAD_F(0x0570dc1a) /* 0.340053656 */, 18 }, /* 5160 */ { MAD_F(0x05713843) /* 0.340141545 */, 18 }, /* 5161 */ { MAD_F(0x0571946d) /* 0.340229440 */, 18 }, /* 5162 */ { MAD_F(0x0571f098) /* 0.340317340 */, 18 }, /* 5163 */ { MAD_F(0x05724cc5) /* 0.340405246 */, 18 }, /* 5164 */ { MAD_F(0x0572a8f4) /* 0.340493158 */, 18 }, /* 5165 */ { MAD_F(0x05730524) /* 0.340581075 */, 18 }, /* 5166 */ { MAD_F(0x05736156) /* 0.340668999 */, 18 }, /* 5167 */ { MAD_F(0x0573bd89) /* 0.340756927 */, 18 }, /* 5168 */ { MAD_F(0x057419be) /* 0.340844862 */, 18 }, /* 5169 */ { MAD_F(0x057475f4) /* 0.340932802 */, 18 }, /* 5170 */ { MAD_F(0x0574d22c) /* 0.341020748 */, 18 }, /* 5171 */ { MAD_F(0x05752e65) /* 0.341108699 */, 18 }, /* 5172 */ { MAD_F(0x05758aa0) /* 0.341196656 */, 18 }, /* 5173 */ { MAD_F(0x0575e6dc) /* 0.341284619 */, 18 }, /* 5174 */ { MAD_F(0x0576431a) /* 0.341372587 */, 18 }, /* 5175 */ { MAD_F(0x05769f59) /* 0.341460562 */, 18 }, /* 5176 */ { MAD_F(0x0576fb9a) /* 0.341548541 */, 18 }, /* 5177 */ { MAD_F(0x057757dd) /* 0.341636527 */, 18 }, /* 5178 */ { MAD_F(0x0577b421) /* 0.341724518 */, 18 }, /* 5179 */ { MAD_F(0x05781066) /* 0.341812515 */, 18 }, /* 5180 */ { MAD_F(0x05786cad) /* 0.341900517 */, 18 }, /* 5181 */ { MAD_F(0x0578c8f5) /* 0.341988525 */, 18 }, /* 5182 */ { MAD_F(0x0579253f) /* 0.342076539 */, 18 }, /* 5183 */ { MAD_F(0x0579818b) /* 0.342164558 */, 18 }, /* 5184 */ { MAD_F(0x0579ddd8) /* 0.342252584 */, 18 }, /* 5185 */ { MAD_F(0x057a3a27) /* 0.342340614 */, 18 }, /* 5186 */ { MAD_F(0x057a9677) /* 0.342428651 */, 18 }, /* 5187 */ { MAD_F(0x057af2c8) /* 0.342516693 */, 18 }, /* 5188 */ { MAD_F(0x057b4f1c) /* 0.342604741 */, 18 }, /* 5189 */ { MAD_F(0x057bab70) /* 0.342692794 */, 18 }, /* 5190 */ { MAD_F(0x057c07c6) /* 0.342780853 */, 18 }, /* 5191 */ { MAD_F(0x057c641e) /* 0.342868918 */, 18 }, /* 5192 */ { MAD_F(0x057cc077) /* 0.342956988 */, 18 }, /* 5193 */ { MAD_F(0x057d1cd2) /* 0.343045064 */, 18 }, /* 5194 */ { MAD_F(0x057d792e) /* 0.343133146 */, 18 }, /* 5195 */ { MAD_F(0x057dd58c) /* 0.343221233 */, 18 }, /* 5196 */ { MAD_F(0x057e31eb) /* 0.343309326 */, 18 }, /* 5197 */ { MAD_F(0x057e8e4c) /* 0.343397425 */, 18 }, /* 5198 */ { MAD_F(0x057eeaae) /* 0.343485529 */, 18 }, /* 5199 */ { MAD_F(0x057f4712) /* 0.343573639 */, 18 }, /* 5200 */ { MAD_F(0x057fa378) /* 0.343661754 */, 18 }, /* 5201 */ { MAD_F(0x057fffde) /* 0.343749876 */, 18 }, /* 5202 */ { MAD_F(0x05805c47) /* 0.343838003 */, 18 }, /* 5203 */ { MAD_F(0x0580b8b1) /* 0.343926135 */, 18 }, /* 5204 */ { MAD_F(0x0581151c) /* 0.344014273 */, 18 }, /* 5205 */ { MAD_F(0x05817189) /* 0.344102417 */, 18 }, /* 5206 */ { MAD_F(0x0581cdf7) /* 0.344190566 */, 18 }, /* 5207 */ { MAD_F(0x05822a67) /* 0.344278722 */, 18 }, /* 5208 */ { MAD_F(0x058286d9) /* 0.344366882 */, 18 }, /* 5209 */ { MAD_F(0x0582e34c) /* 0.344455049 */, 18 }, /* 5210 */ { MAD_F(0x05833fc0) /* 0.344543221 */, 18 }, /* 5211 */ { MAD_F(0x05839c36) /* 0.344631398 */, 18 }, /* 5212 */ { MAD_F(0x0583f8ae) /* 0.344719582 */, 18 }, /* 5213 */ { MAD_F(0x05845527) /* 0.344807771 */, 18 }, /* 5214 */ { MAD_F(0x0584b1a1) /* 0.344895965 */, 18 }, /* 5215 */ { MAD_F(0x05850e1e) /* 0.344984165 */, 18 }, /* 5216 */ { MAD_F(0x05856a9b) /* 0.345072371 */, 18 }, /* 5217 */ { MAD_F(0x0585c71a) /* 0.345160583 */, 18 }, /* 5218 */ { MAD_F(0x0586239b) /* 0.345248800 */, 18 }, /* 5219 */ { MAD_F(0x0586801d) /* 0.345337023 */, 18 }, /* 5220 */ { MAD_F(0x0586dca1) /* 0.345425251 */, 18 }, /* 5221 */ { MAD_F(0x05873926) /* 0.345513485 */, 18 }, /* 5222 */ { MAD_F(0x058795ac) /* 0.345601725 */, 18 }, /* 5223 */ { MAD_F(0x0587f235) /* 0.345689970 */, 18 }, /* 5224 */ { MAD_F(0x05884ebe) /* 0.345778221 */, 18 }, /* 5225 */ { MAD_F(0x0588ab49) /* 0.345866478 */, 18 }, /* 5226 */ { MAD_F(0x058907d6) /* 0.345954740 */, 18 }, /* 5227 */ { MAD_F(0x05896464) /* 0.346043008 */, 18 }, /* 5228 */ { MAD_F(0x0589c0f4) /* 0.346131281 */, 18 }, /* 5229 */ { MAD_F(0x058a1d85) /* 0.346219560 */, 18 }, /* 5230 */ { MAD_F(0x058a7a18) /* 0.346307845 */, 18 }, /* 5231 */ { MAD_F(0x058ad6ac) /* 0.346396135 */, 18 }, /* 5232 */ { MAD_F(0x058b3342) /* 0.346484431 */, 18 }, /* 5233 */ { MAD_F(0x058b8fd9) /* 0.346572733 */, 18 }, /* 5234 */ { MAD_F(0x058bec72) /* 0.346661040 */, 18 }, /* 5235 */ { MAD_F(0x058c490c) /* 0.346749353 */, 18 }, /* 5236 */ { MAD_F(0x058ca5a8) /* 0.346837671 */, 18 }, /* 5237 */ { MAD_F(0x058d0246) /* 0.346925996 */, 18 }, /* 5238 */ { MAD_F(0x058d5ee4) /* 0.347014325 */, 18 }, /* 5239 */ { MAD_F(0x058dbb85) /* 0.347102661 */, 18 }, /* 5240 */ { MAD_F(0x058e1827) /* 0.347191002 */, 18 }, /* 5241 */ { MAD_F(0x058e74ca) /* 0.347279348 */, 18 }, /* 5242 */ { MAD_F(0x058ed16f) /* 0.347367700 */, 18 }, /* 5243 */ { MAD_F(0x058f2e15) /* 0.347456058 */, 18 }, /* 5244 */ { MAD_F(0x058f8abd) /* 0.347544422 */, 18 }, /* 5245 */ { MAD_F(0x058fe766) /* 0.347632791 */, 18 }, /* 5246 */ { MAD_F(0x05904411) /* 0.347721165 */, 18 }, /* 5247 */ { MAD_F(0x0590a0be) /* 0.347809546 */, 18 }, /* 5248 */ { MAD_F(0x0590fd6c) /* 0.347897931 */, 18 }, /* 5249 */ { MAD_F(0x05915a1b) /* 0.347986323 */, 18 }, /* 5250 */ { MAD_F(0x0591b6cc) /* 0.348074720 */, 18 }, /* 5251 */ { MAD_F(0x0592137e) /* 0.348163123 */, 18 }, /* 5252 */ { MAD_F(0x05927032) /* 0.348251531 */, 18 }, /* 5253 */ { MAD_F(0x0592cce8) /* 0.348339945 */, 18 }, /* 5254 */ { MAD_F(0x0593299f) /* 0.348428365 */, 18 }, /* 5255 */ { MAD_F(0x05938657) /* 0.348516790 */, 18 }, /* 5256 */ { MAD_F(0x0593e311) /* 0.348605221 */, 18 }, /* 5257 */ { MAD_F(0x05943fcd) /* 0.348693657 */, 18 }, /* 5258 */ { MAD_F(0x05949c8a) /* 0.348782099 */, 18 }, /* 5259 */ { MAD_F(0x0594f948) /* 0.348870547 */, 18 }, /* 5260 */ { MAD_F(0x05955608) /* 0.348959000 */, 18 }, /* 5261 */ { MAD_F(0x0595b2ca) /* 0.349047459 */, 18 }, /* 5262 */ { MAD_F(0x05960f8c) /* 0.349135923 */, 18 }, /* 5263 */ { MAD_F(0x05966c51) /* 0.349224393 */, 18 }, /* 5264 */ { MAD_F(0x0596c917) /* 0.349312869 */, 18 }, /* 5265 */ { MAD_F(0x059725de) /* 0.349401350 */, 18 }, /* 5266 */ { MAD_F(0x059782a7) /* 0.349489837 */, 18 }, /* 5267 */ { MAD_F(0x0597df72) /* 0.349578329 */, 18 }, /* 5268 */ { MAD_F(0x05983c3e) /* 0.349666827 */, 18 }, /* 5269 */ { MAD_F(0x0598990c) /* 0.349755331 */, 18 }, /* 5270 */ { MAD_F(0x0598f5db) /* 0.349843840 */, 18 }, /* 5271 */ { MAD_F(0x059952ab) /* 0.349932355 */, 18 }, /* 5272 */ { MAD_F(0x0599af7d) /* 0.350020876 */, 18 }, /* 5273 */ { MAD_F(0x059a0c51) /* 0.350109402 */, 18 }, /* 5274 */ { MAD_F(0x059a6926) /* 0.350197933 */, 18 }, /* 5275 */ { MAD_F(0x059ac5fc) /* 0.350286470 */, 18 }, /* 5276 */ { MAD_F(0x059b22d4) /* 0.350375013 */, 18 }, /* 5277 */ { MAD_F(0x059b7fae) /* 0.350463562 */, 18 }, /* 5278 */ { MAD_F(0x059bdc89) /* 0.350552116 */, 18 }, /* 5279 */ { MAD_F(0x059c3965) /* 0.350640675 */, 18 }, /* 5280 */ { MAD_F(0x059c9643) /* 0.350729240 */, 18 }, /* 5281 */ { MAD_F(0x059cf323) /* 0.350817811 */, 18 }, /* 5282 */ { MAD_F(0x059d5004) /* 0.350906388 */, 18 }, /* 5283 */ { MAD_F(0x059dace6) /* 0.350994970 */, 18 }, /* 5284 */ { MAD_F(0x059e09cb) /* 0.351083557 */, 18 }, /* 5285 */ { MAD_F(0x059e66b0) /* 0.351172150 */, 18 }, /* 5286 */ { MAD_F(0x059ec397) /* 0.351260749 */, 18 }, /* 5287 */ { MAD_F(0x059f2080) /* 0.351349353 */, 18 }, /* 5288 */ { MAD_F(0x059f7d6a) /* 0.351437963 */, 18 }, /* 5289 */ { MAD_F(0x059fda55) /* 0.351526579 */, 18 }, /* 5290 */ { MAD_F(0x05a03742) /* 0.351615200 */, 18 }, /* 5291 */ { MAD_F(0x05a09431) /* 0.351703827 */, 18 }, /* 5292 */ { MAD_F(0x05a0f121) /* 0.351792459 */, 18 }, /* 5293 */ { MAD_F(0x05a14e12) /* 0.351881097 */, 18 }, /* 5294 */ { MAD_F(0x05a1ab05) /* 0.351969740 */, 18 }, /* 5295 */ { MAD_F(0x05a207fa) /* 0.352058389 */, 18 }, /* 5296 */ { MAD_F(0x05a264f0) /* 0.352147044 */, 18 }, /* 5297 */ { MAD_F(0x05a2c1e7) /* 0.352235704 */, 18 }, /* 5298 */ { MAD_F(0x05a31ee1) /* 0.352324369 */, 18 }, /* 5299 */ { MAD_F(0x05a37bdb) /* 0.352413041 */, 18 }, /* 5300 */ { MAD_F(0x05a3d8d7) /* 0.352501718 */, 18 }, /* 5301 */ { MAD_F(0x05a435d5) /* 0.352590400 */, 18 }, /* 5302 */ { MAD_F(0x05a492d4) /* 0.352679088 */, 18 }, /* 5303 */ { MAD_F(0x05a4efd4) /* 0.352767782 */, 18 }, /* 5304 */ { MAD_F(0x05a54cd6) /* 0.352856481 */, 18 }, /* 5305 */ { MAD_F(0x05a5a9da) /* 0.352945186 */, 18 }, /* 5306 */ { MAD_F(0x05a606df) /* 0.353033896 */, 18 }, /* 5307 */ { MAD_F(0x05a663e5) /* 0.353122612 */, 18 }, /* 5308 */ { MAD_F(0x05a6c0ed) /* 0.353211333 */, 18 }, /* 5309 */ { MAD_F(0x05a71df7) /* 0.353300061 */, 18 }, /* 5310 */ { MAD_F(0x05a77b02) /* 0.353388793 */, 18 }, /* 5311 */ { MAD_F(0x05a7d80e) /* 0.353477531 */, 18 }, /* 5312 */ { MAD_F(0x05a8351c) /* 0.353566275 */, 18 }, /* 5313 */ { MAD_F(0x05a8922c) /* 0.353655024 */, 18 }, /* 5314 */ { MAD_F(0x05a8ef3c) /* 0.353743779 */, 18 }, /* 5315 */ { MAD_F(0x05a94c4f) /* 0.353832540 */, 18 }, /* 5316 */ { MAD_F(0x05a9a963) /* 0.353921306 */, 18 }, /* 5317 */ { MAD_F(0x05aa0678) /* 0.354010077 */, 18 }, /* 5318 */ { MAD_F(0x05aa638f) /* 0.354098855 */, 18 }, /* 5319 */ { MAD_F(0x05aac0a8) /* 0.354187637 */, 18 }, /* 5320 */ { MAD_F(0x05ab1dc2) /* 0.354276426 */, 18 }, /* 5321 */ { MAD_F(0x05ab7add) /* 0.354365220 */, 18 }, /* 5322 */ { MAD_F(0x05abd7fa) /* 0.354454019 */, 18 }, /* 5323 */ { MAD_F(0x05ac3518) /* 0.354542824 */, 18 }, /* 5324 */ { MAD_F(0x05ac9238) /* 0.354631635 */, 18 }, /* 5325 */ { MAD_F(0x05acef5a) /* 0.354720451 */, 18 }, /* 5326 */ { MAD_F(0x05ad4c7d) /* 0.354809272 */, 18 }, /* 5327 */ { MAD_F(0x05ada9a1) /* 0.354898100 */, 18 }, /* 5328 */ { MAD_F(0x05ae06c7) /* 0.354986932 */, 18 }, /* 5329 */ { MAD_F(0x05ae63ee) /* 0.355075771 */, 18 }, /* 5330 */ { MAD_F(0x05aec117) /* 0.355164615 */, 18 }, /* 5331 */ { MAD_F(0x05af1e41) /* 0.355253464 */, 18 }, /* 5332 */ { MAD_F(0x05af7b6d) /* 0.355342319 */, 18 }, /* 5333 */ { MAD_F(0x05afd89b) /* 0.355431180 */, 18 }, /* 5334 */ { MAD_F(0x05b035c9) /* 0.355520046 */, 18 }, /* 5335 */ { MAD_F(0x05b092fa) /* 0.355608917 */, 18 }, /* 5336 */ { MAD_F(0x05b0f02b) /* 0.355697795 */, 18 }, /* 5337 */ { MAD_F(0x05b14d5f) /* 0.355786677 */, 18 }, /* 5338 */ { MAD_F(0x05b1aa94) /* 0.355875566 */, 18 }, /* 5339 */ { MAD_F(0x05b207ca) /* 0.355964460 */, 18 }, /* 5340 */ { MAD_F(0x05b26502) /* 0.356053359 */, 18 }, /* 5341 */ { MAD_F(0x05b2c23b) /* 0.356142264 */, 18 }, /* 5342 */ { MAD_F(0x05b31f76) /* 0.356231175 */, 18 }, /* 5343 */ { MAD_F(0x05b37cb2) /* 0.356320091 */, 18 }, /* 5344 */ { MAD_F(0x05b3d9f0) /* 0.356409012 */, 18 }, /* 5345 */ { MAD_F(0x05b4372f) /* 0.356497940 */, 18 }, /* 5346 */ { MAD_F(0x05b4946f) /* 0.356586872 */, 18 }, /* 5347 */ { MAD_F(0x05b4f1b2) /* 0.356675811 */, 18 }, /* 5348 */ { MAD_F(0x05b54ef5) /* 0.356764754 */, 18 }, /* 5349 */ { MAD_F(0x05b5ac3a) /* 0.356853704 */, 18 }, /* 5350 */ { MAD_F(0x05b60981) /* 0.356942659 */, 18 }, /* 5351 */ { MAD_F(0x05b666c9) /* 0.357031619 */, 18 }, /* 5352 */ { MAD_F(0x05b6c413) /* 0.357120585 */, 18 }, /* 5353 */ { MAD_F(0x05b7215e) /* 0.357209557 */, 18 }, /* 5354 */ { MAD_F(0x05b77eab) /* 0.357298534 */, 18 }, /* 5355 */ { MAD_F(0x05b7dbf9) /* 0.357387516 */, 18 }, /* 5356 */ { MAD_F(0x05b83948) /* 0.357476504 */, 18 }, /* 5357 */ { MAD_F(0x05b89699) /* 0.357565498 */, 18 }, /* 5358 */ { MAD_F(0x05b8f3ec) /* 0.357654497 */, 18 }, /* 5359 */ { MAD_F(0x05b95140) /* 0.357743502 */, 18 }, /* 5360 */ { MAD_F(0x05b9ae95) /* 0.357832512 */, 18 }, /* 5361 */ { MAD_F(0x05ba0bec) /* 0.357921528 */, 18 }, /* 5362 */ { MAD_F(0x05ba6945) /* 0.358010550 */, 18 }, /* 5363 */ { MAD_F(0x05bac69f) /* 0.358099576 */, 18 }, /* 5364 */ { MAD_F(0x05bb23fa) /* 0.358188609 */, 18 }, /* 5365 */ { MAD_F(0x05bb8157) /* 0.358277647 */, 18 }, /* 5366 */ { MAD_F(0x05bbdeb6) /* 0.358366690 */, 18 }, /* 5367 */ { MAD_F(0x05bc3c16) /* 0.358455739 */, 18 }, /* 5368 */ { MAD_F(0x05bc9977) /* 0.358544794 */, 18 }, /* 5369 */ { MAD_F(0x05bcf6da) /* 0.358633854 */, 18 }, /* 5370 */ { MAD_F(0x05bd543e) /* 0.358722920 */, 18 }, /* 5371 */ { MAD_F(0x05bdb1a4) /* 0.358811991 */, 18 }, /* 5372 */ { MAD_F(0x05be0f0b) /* 0.358901067 */, 18 }, /* 5373 */ { MAD_F(0x05be6c74) /* 0.358990150 */, 18 }, /* 5374 */ { MAD_F(0x05bec9df) /* 0.359079237 */, 18 }, /* 5375 */ { MAD_F(0x05bf274a) /* 0.359168331 */, 18 }, /* 5376 */ { MAD_F(0x05bf84b8) /* 0.359257429 */, 18 }, /* 5377 */ { MAD_F(0x05bfe226) /* 0.359346534 */, 18 }, /* 5378 */ { MAD_F(0x05c03f97) /* 0.359435644 */, 18 }, /* 5379 */ { MAD_F(0x05c09d08) /* 0.359524759 */, 18 }, /* 5380 */ { MAD_F(0x05c0fa7c) /* 0.359613880 */, 18 }, /* 5381 */ { MAD_F(0x05c157f0) /* 0.359703006 */, 18 }, /* 5382 */ { MAD_F(0x05c1b566) /* 0.359792138 */, 18 }, /* 5383 */ { MAD_F(0x05c212de) /* 0.359881276 */, 18 }, /* 5384 */ { MAD_F(0x05c27057) /* 0.359970419 */, 18 }, /* 5385 */ { MAD_F(0x05c2cdd2) /* 0.360059567 */, 18 }, /* 5386 */ { MAD_F(0x05c32b4e) /* 0.360148721 */, 18 }, /* 5387 */ { MAD_F(0x05c388cb) /* 0.360237881 */, 18 }, /* 5388 */ { MAD_F(0x05c3e64b) /* 0.360327046 */, 18 }, /* 5389 */ { MAD_F(0x05c443cb) /* 0.360416216 */, 18 }, /* 5390 */ { MAD_F(0x05c4a14d) /* 0.360505392 */, 18 }, /* 5391 */ { MAD_F(0x05c4fed1) /* 0.360594574 */, 18 }, /* 5392 */ { MAD_F(0x05c55c56) /* 0.360683761 */, 18 }, /* 5393 */ { MAD_F(0x05c5b9dc) /* 0.360772953 */, 18 }, /* 5394 */ { MAD_F(0x05c61764) /* 0.360862152 */, 18 }, /* 5395 */ { MAD_F(0x05c674ed) /* 0.360951355 */, 18 }, /* 5396 */ { MAD_F(0x05c6d278) /* 0.361040564 */, 18 }, /* 5397 */ { MAD_F(0x05c73005) /* 0.361129779 */, 18 }, /* 5398 */ { MAD_F(0x05c78d93) /* 0.361218999 */, 18 }, /* 5399 */ { MAD_F(0x05c7eb22) /* 0.361308225 */, 18 }, /* 5400 */ { MAD_F(0x05c848b3) /* 0.361397456 */, 18 }, /* 5401 */ { MAD_F(0x05c8a645) /* 0.361486693 */, 18 }, /* 5402 */ { MAD_F(0x05c903d9) /* 0.361575935 */, 18 }, /* 5403 */ { MAD_F(0x05c9616e) /* 0.361665183 */, 18 }, /* 5404 */ { MAD_F(0x05c9bf05) /* 0.361754436 */, 18 }, /* 5405 */ { MAD_F(0x05ca1c9d) /* 0.361843695 */, 18 }, /* 5406 */ { MAD_F(0x05ca7a37) /* 0.361932959 */, 18 }, /* 5407 */ { MAD_F(0x05cad7d2) /* 0.362022229 */, 18 }, /* 5408 */ { MAD_F(0x05cb356e) /* 0.362111504 */, 18 }, /* 5409 */ { MAD_F(0x05cb930d) /* 0.362200785 */, 18 }, /* 5410 */ { MAD_F(0x05cbf0ac) /* 0.362290071 */, 18 }, /* 5411 */ { MAD_F(0x05cc4e4d) /* 0.362379362 */, 18 }, /* 5412 */ { MAD_F(0x05ccabf0) /* 0.362468660 */, 18 }, /* 5413 */ { MAD_F(0x05cd0994) /* 0.362557962 */, 18 }, /* 5414 */ { MAD_F(0x05cd6739) /* 0.362647271 */, 18 }, /* 5415 */ { MAD_F(0x05cdc4e0) /* 0.362736584 */, 18 }, /* 5416 */ { MAD_F(0x05ce2289) /* 0.362825904 */, 18 }, /* 5417 */ { MAD_F(0x05ce8033) /* 0.362915228 */, 18 }, /* 5418 */ { MAD_F(0x05ceddde) /* 0.363004559 */, 18 }, /* 5419 */ { MAD_F(0x05cf3b8b) /* 0.363093894 */, 18 }, /* 5420 */ { MAD_F(0x05cf9939) /* 0.363183236 */, 18 }, /* 5421 */ { MAD_F(0x05cff6e9) /* 0.363272582 */, 18 }, /* 5422 */ { MAD_F(0x05d0549a) /* 0.363361935 */, 18 }, /* 5423 */ { MAD_F(0x05d0b24d) /* 0.363451292 */, 18 }, /* 5424 */ { MAD_F(0x05d11001) /* 0.363540655 */, 18 }, /* 5425 */ { MAD_F(0x05d16db7) /* 0.363630024 */, 18 }, /* 5426 */ { MAD_F(0x05d1cb6e) /* 0.363719398 */, 18 }, /* 5427 */ { MAD_F(0x05d22927) /* 0.363808778 */, 18 }, /* 5428 */ { MAD_F(0x05d286e1) /* 0.363898163 */, 18 }, /* 5429 */ { MAD_F(0x05d2e49d) /* 0.363987554 */, 18 }, /* 5430 */ { MAD_F(0x05d3425a) /* 0.364076950 */, 18 }, /* 5431 */ { MAD_F(0x05d3a018) /* 0.364166352 */, 18 }, /* 5432 */ { MAD_F(0x05d3fdd8) /* 0.364255759 */, 18 }, /* 5433 */ { MAD_F(0x05d45b9a) /* 0.364345171 */, 18 }, /* 5434 */ { MAD_F(0x05d4b95d) /* 0.364434589 */, 18 }, /* 5435 */ { MAD_F(0x05d51721) /* 0.364524013 */, 18 }, /* 5436 */ { MAD_F(0x05d574e7) /* 0.364613442 */, 18 }, /* 5437 */ { MAD_F(0x05d5d2af) /* 0.364702877 */, 18 }, /* 5438 */ { MAD_F(0x05d63078) /* 0.364792317 */, 18 }, /* 5439 */ { MAD_F(0x05d68e42) /* 0.364881762 */, 18 }, /* 5440 */ { MAD_F(0x05d6ec0e) /* 0.364971213 */, 18 }, /* 5441 */ { MAD_F(0x05d749db) /* 0.365060669 */, 18 }, /* 5442 */ { MAD_F(0x05d7a7aa) /* 0.365150131 */, 18 }, /* 5443 */ { MAD_F(0x05d8057a) /* 0.365239599 */, 18 }, /* 5444 */ { MAD_F(0x05d8634c) /* 0.365329072 */, 18 }, /* 5445 */ { MAD_F(0x05d8c11f) /* 0.365418550 */, 18 }, /* 5446 */ { MAD_F(0x05d91ef4) /* 0.365508034 */, 18 }, /* 5447 */ { MAD_F(0x05d97cca) /* 0.365597523 */, 18 }, /* 5448 */ { MAD_F(0x05d9daa1) /* 0.365687018 */, 18 }, /* 5449 */ { MAD_F(0x05da387a) /* 0.365776518 */, 18 }, /* 5450 */ { MAD_F(0x05da9655) /* 0.365866024 */, 18 }, /* 5451 */ { MAD_F(0x05daf431) /* 0.365955536 */, 18 }, /* 5452 */ { MAD_F(0x05db520e) /* 0.366045052 */, 18 }, /* 5453 */ { MAD_F(0x05dbafed) /* 0.366134574 */, 18 }, /* 5454 */ { MAD_F(0x05dc0dce) /* 0.366224102 */, 18 }, /* 5455 */ { MAD_F(0x05dc6baf) /* 0.366313635 */, 18 }, /* 5456 */ { MAD_F(0x05dcc993) /* 0.366403174 */, 18 }, /* 5457 */ { MAD_F(0x05dd2778) /* 0.366492718 */, 18 }, /* 5458 */ { MAD_F(0x05dd855e) /* 0.366582267 */, 18 }, /* 5459 */ { MAD_F(0x05dde346) /* 0.366671822 */, 18 }, /* 5460 */ { MAD_F(0x05de412f) /* 0.366761383 */, 18 }, /* 5461 */ { MAD_F(0x05de9f1a) /* 0.366850949 */, 18 }, /* 5462 */ { MAD_F(0x05defd06) /* 0.366940520 */, 18 }, /* 5463 */ { MAD_F(0x05df5af3) /* 0.367030097 */, 18 }, /* 5464 */ { MAD_F(0x05dfb8e2) /* 0.367119680 */, 18 }, /* 5465 */ { MAD_F(0x05e016d3) /* 0.367209267 */, 18 }, /* 5466 */ { MAD_F(0x05e074c5) /* 0.367298861 */, 18 }, /* 5467 */ { MAD_F(0x05e0d2b8) /* 0.367388459 */, 18 }, /* 5468 */ { MAD_F(0x05e130ad) /* 0.367478064 */, 18 }, /* 5469 */ { MAD_F(0x05e18ea4) /* 0.367567673 */, 18 }, /* 5470 */ { MAD_F(0x05e1ec9c) /* 0.367657288 */, 18 }, /* 5471 */ { MAD_F(0x05e24a95) /* 0.367746909 */, 18 }, /* 5472 */ { MAD_F(0x05e2a890) /* 0.367836535 */, 18 }, /* 5473 */ { MAD_F(0x05e3068c) /* 0.367926167 */, 18 }, /* 5474 */ { MAD_F(0x05e3648a) /* 0.368015804 */, 18 }, /* 5475 */ { MAD_F(0x05e3c289) /* 0.368105446 */, 18 }, /* 5476 */ { MAD_F(0x05e4208a) /* 0.368195094 */, 18 }, /* 5477 */ { MAD_F(0x05e47e8c) /* 0.368284747 */, 18 }, /* 5478 */ { MAD_F(0x05e4dc8f) /* 0.368374406 */, 18 }, /* 5479 */ { MAD_F(0x05e53a94) /* 0.368464070 */, 18 }, /* 5480 */ { MAD_F(0x05e5989b) /* 0.368553740 */, 18 }, /* 5481 */ { MAD_F(0x05e5f6a3) /* 0.368643415 */, 18 }, /* 5482 */ { MAD_F(0x05e654ac) /* 0.368733096 */, 18 }, /* 5483 */ { MAD_F(0x05e6b2b7) /* 0.368822782 */, 18 }, /* 5484 */ { MAD_F(0x05e710c4) /* 0.368912473 */, 18 }, /* 5485 */ { MAD_F(0x05e76ed2) /* 0.369002170 */, 18 }, /* 5486 */ { MAD_F(0x05e7cce1) /* 0.369091873 */, 18 }, /* 5487 */ { MAD_F(0x05e82af2) /* 0.369181581 */, 18 }, /* 5488 */ { MAD_F(0x05e88904) /* 0.369271294 */, 18 }, /* 5489 */ { MAD_F(0x05e8e718) /* 0.369361013 */, 18 }, /* 5490 */ { MAD_F(0x05e9452d) /* 0.369450737 */, 18 }, /* 5491 */ { MAD_F(0x05e9a343) /* 0.369540467 */, 18 }, /* 5492 */ { MAD_F(0x05ea015c) /* 0.369630202 */, 18 }, /* 5493 */ { MAD_F(0x05ea5f75) /* 0.369719942 */, 18 }, /* 5494 */ { MAD_F(0x05eabd90) /* 0.369809688 */, 18 }, /* 5495 */ { MAD_F(0x05eb1bad) /* 0.369899440 */, 18 }, /* 5496 */ { MAD_F(0x05eb79cb) /* 0.369989197 */, 18 }, /* 5497 */ { MAD_F(0x05ebd7ea) /* 0.370078959 */, 18 }, /* 5498 */ { MAD_F(0x05ec360b) /* 0.370168727 */, 18 }, /* 5499 */ { MAD_F(0x05ec942d) /* 0.370258500 */, 18 }, /* 5500 */ { MAD_F(0x05ecf251) /* 0.370348279 */, 18 }, /* 5501 */ { MAD_F(0x05ed5076) /* 0.370438063 */, 18 }, /* 5502 */ { MAD_F(0x05edae9d) /* 0.370527853 */, 18 }, /* 5503 */ { MAD_F(0x05ee0cc5) /* 0.370617648 */, 18 }, /* 5504 */ { MAD_F(0x05ee6aef) /* 0.370707448 */, 18 }, /* 5505 */ { MAD_F(0x05eec91a) /* 0.370797254 */, 18 }, /* 5506 */ { MAD_F(0x05ef2746) /* 0.370887065 */, 18 }, /* 5507 */ { MAD_F(0x05ef8574) /* 0.370976882 */, 18 }, /* 5508 */ { MAD_F(0x05efe3a4) /* 0.371066704 */, 18 }, /* 5509 */ { MAD_F(0x05f041d5) /* 0.371156532 */, 18 }, /* 5510 */ { MAD_F(0x05f0a007) /* 0.371246365 */, 18 }, /* 5511 */ { MAD_F(0x05f0fe3b) /* 0.371336203 */, 18 }, /* 5512 */ { MAD_F(0x05f15c70) /* 0.371426047 */, 18 }, /* 5513 */ { MAD_F(0x05f1baa7) /* 0.371515897 */, 18 }, /* 5514 */ { MAD_F(0x05f218df) /* 0.371605751 */, 18 }, /* 5515 */ { MAD_F(0x05f27719) /* 0.371695612 */, 18 }, /* 5516 */ { MAD_F(0x05f2d554) /* 0.371785477 */, 18 }, /* 5517 */ { MAD_F(0x05f33390) /* 0.371875348 */, 18 }, /* 5518 */ { MAD_F(0x05f391cf) /* 0.371965225 */, 18 }, /* 5519 */ { MAD_F(0x05f3f00e) /* 0.372055107 */, 18 }, /* 5520 */ { MAD_F(0x05f44e4f) /* 0.372144994 */, 18 }, /* 5521 */ { MAD_F(0x05f4ac91) /* 0.372234887 */, 18 }, /* 5522 */ { MAD_F(0x05f50ad5) /* 0.372324785 */, 18 }, /* 5523 */ { MAD_F(0x05f5691b) /* 0.372414689 */, 18 }, /* 5524 */ { MAD_F(0x05f5c761) /* 0.372504598 */, 18 }, /* 5525 */ { MAD_F(0x05f625aa) /* 0.372594513 */, 18 }, /* 5526 */ { MAD_F(0x05f683f3) /* 0.372684433 */, 18 }, /* 5527 */ { MAD_F(0x05f6e23f) /* 0.372774358 */, 18 }, /* 5528 */ { MAD_F(0x05f7408b) /* 0.372864289 */, 18 }, /* 5529 */ { MAD_F(0x05f79ed9) /* 0.372954225 */, 18 }, /* 5530 */ { MAD_F(0x05f7fd29) /* 0.373044167 */, 18 }, /* 5531 */ { MAD_F(0x05f85b7a) /* 0.373134114 */, 18 }, /* 5532 */ { MAD_F(0x05f8b9cc) /* 0.373224066 */, 18 }, /* 5533 */ { MAD_F(0x05f91820) /* 0.373314024 */, 18 }, /* 5534 */ { MAD_F(0x05f97675) /* 0.373403987 */, 18 }, /* 5535 */ { MAD_F(0x05f9d4cc) /* 0.373493956 */, 18 }, /* 5536 */ { MAD_F(0x05fa3324) /* 0.373583930 */, 18 }, /* 5537 */ { MAD_F(0x05fa917e) /* 0.373673910 */, 18 }, /* 5538 */ { MAD_F(0x05faefd9) /* 0.373763895 */, 18 }, /* 5539 */ { MAD_F(0x05fb4e36) /* 0.373853885 */, 18 }, /* 5540 */ { MAD_F(0x05fbac94) /* 0.373943881 */, 18 }, /* 5541 */ { MAD_F(0x05fc0af3) /* 0.374033882 */, 18 }, /* 5542 */ { MAD_F(0x05fc6954) /* 0.374123889 */, 18 }, /* 5543 */ { MAD_F(0x05fcc7b7) /* 0.374213901 */, 18 }, /* 5544 */ { MAD_F(0x05fd261b) /* 0.374303918 */, 18 }, /* 5545 */ { MAD_F(0x05fd8480) /* 0.374393941 */, 18 }, /* 5546 */ { MAD_F(0x05fde2e7) /* 0.374483970 */, 18 }, /* 5547 */ { MAD_F(0x05fe414f) /* 0.374574003 */, 18 }, /* 5548 */ { MAD_F(0x05fe9fb9) /* 0.374664042 */, 18 }, /* 5549 */ { MAD_F(0x05fefe24) /* 0.374754087 */, 18 }, /* 5550 */ { MAD_F(0x05ff5c91) /* 0.374844137 */, 18 }, /* 5551 */ { MAD_F(0x05ffbaff) /* 0.374934192 */, 18 }, /* 5552 */ { MAD_F(0x0600196e) /* 0.375024253 */, 18 }, /* 5553 */ { MAD_F(0x060077df) /* 0.375114319 */, 18 }, /* 5554 */ { MAD_F(0x0600d651) /* 0.375204391 */, 18 }, /* 5555 */ { MAD_F(0x060134c5) /* 0.375294468 */, 18 }, /* 5556 */ { MAD_F(0x0601933b) /* 0.375384550 */, 18 }, /* 5557 */ { MAD_F(0x0601f1b1) /* 0.375474638 */, 18 }, /* 5558 */ { MAD_F(0x0602502a) /* 0.375564731 */, 18 }, /* 5559 */ { MAD_F(0x0602aea3) /* 0.375654830 */, 18 }, /* 5560 */ { MAD_F(0x06030d1e) /* 0.375744934 */, 18 }, /* 5561 */ { MAD_F(0x06036b9b) /* 0.375835043 */, 18 }, /* 5562 */ { MAD_F(0x0603ca19) /* 0.375925158 */, 18 }, /* 5563 */ { MAD_F(0x06042898) /* 0.376015278 */, 18 }, /* 5564 */ { MAD_F(0x06048719) /* 0.376105404 */, 18 }, /* 5565 */ { MAD_F(0x0604e59c) /* 0.376195535 */, 18 }, /* 5566 */ { MAD_F(0x0605441f) /* 0.376285671 */, 18 }, /* 5567 */ { MAD_F(0x0605a2a5) /* 0.376375813 */, 18 }, /* 5568 */ { MAD_F(0x0606012b) /* 0.376465960 */, 18 }, /* 5569 */ { MAD_F(0x06065fb4) /* 0.376556113 */, 18 }, /* 5570 */ { MAD_F(0x0606be3d) /* 0.376646271 */, 18 }, /* 5571 */ { MAD_F(0x06071cc8) /* 0.376736434 */, 18 }, /* 5572 */ { MAD_F(0x06077b55) /* 0.376826603 */, 18 }, /* 5573 */ { MAD_F(0x0607d9e3) /* 0.376916777 */, 18 }, /* 5574 */ { MAD_F(0x06083872) /* 0.377006957 */, 18 }, /* 5575 */ { MAD_F(0x06089703) /* 0.377097141 */, 18 }, /* 5576 */ { MAD_F(0x0608f595) /* 0.377187332 */, 18 }, /* 5577 */ { MAD_F(0x06095429) /* 0.377277528 */, 18 }, /* 5578 */ { MAD_F(0x0609b2be) /* 0.377367729 */, 18 }, /* 5579 */ { MAD_F(0x060a1155) /* 0.377457935 */, 18 }, /* 5580 */ { MAD_F(0x060a6fed) /* 0.377548147 */, 18 }, /* 5581 */ { MAD_F(0x060ace86) /* 0.377638364 */, 18 }, /* 5582 */ { MAD_F(0x060b2d21) /* 0.377728587 */, 18 }, /* 5583 */ { MAD_F(0x060b8bbe) /* 0.377818815 */, 18 }, /* 5584 */ { MAD_F(0x060bea5c) /* 0.377909049 */, 18 }, /* 5585 */ { MAD_F(0x060c48fb) /* 0.377999288 */, 18 }, /* 5586 */ { MAD_F(0x060ca79c) /* 0.378089532 */, 18 }, /* 5587 */ { MAD_F(0x060d063e) /* 0.378179781 */, 18 }, /* 5588 */ { MAD_F(0x060d64e1) /* 0.378270036 */, 18 }, /* 5589 */ { MAD_F(0x060dc387) /* 0.378360297 */, 18 }, /* 5590 */ { MAD_F(0x060e222d) /* 0.378450563 */, 18 }, /* 5591 */ { MAD_F(0x060e80d5) /* 0.378540834 */, 18 }, /* 5592 */ { MAD_F(0x060edf7f) /* 0.378631110 */, 18 }, /* 5593 */ { MAD_F(0x060f3e29) /* 0.378721392 */, 18 }, /* 5594 */ { MAD_F(0x060f9cd6) /* 0.378811680 */, 18 }, /* 5595 */ { MAD_F(0x060ffb83) /* 0.378901972 */, 18 }, /* 5596 */ { MAD_F(0x06105a33) /* 0.378992270 */, 18 }, /* 5597 */ { MAD_F(0x0610b8e3) /* 0.379082574 */, 18 }, /* 5598 */ { MAD_F(0x06111795) /* 0.379172883 */, 18 }, /* 5599 */ { MAD_F(0x06117649) /* 0.379263197 */, 18 }, /* 5600 */ { MAD_F(0x0611d4fe) /* 0.379353516 */, 18 }, /* 5601 */ { MAD_F(0x061233b4) /* 0.379443841 */, 18 }, /* 5602 */ { MAD_F(0x0612926c) /* 0.379534172 */, 18 }, /* 5603 */ { MAD_F(0x0612f125) /* 0.379624507 */, 18 }, /* 5604 */ { MAD_F(0x06134fe0) /* 0.379714848 */, 18 }, /* 5605 */ { MAD_F(0x0613ae9c) /* 0.379805195 */, 18 }, /* 5606 */ { MAD_F(0x06140d5a) /* 0.379895547 */, 18 }, /* 5607 */ { MAD_F(0x06146c19) /* 0.379985904 */, 18 }, /* 5608 */ { MAD_F(0x0614cada) /* 0.380076266 */, 18 }, /* 5609 */ { MAD_F(0x0615299c) /* 0.380166634 */, 18 }, /* 5610 */ { MAD_F(0x0615885f) /* 0.380257008 */, 18 }, /* 5611 */ { MAD_F(0x0615e724) /* 0.380347386 */, 18 }, /* 5612 */ { MAD_F(0x061645ea) /* 0.380437770 */, 18 }, /* 5613 */ { MAD_F(0x0616a4b2) /* 0.380528160 */, 18 }, /* 5614 */ { MAD_F(0x0617037b) /* 0.380618555 */, 18 }, /* 5615 */ { MAD_F(0x06176246) /* 0.380708955 */, 18 }, /* 5616 */ { MAD_F(0x0617c112) /* 0.380799360 */, 18 }, /* 5617 */ { MAD_F(0x06181fdf) /* 0.380889771 */, 18 }, /* 5618 */ { MAD_F(0x06187eae) /* 0.380980187 */, 18 }, /* 5619 */ { MAD_F(0x0618dd7e) /* 0.381070609 */, 18 }, /* 5620 */ { MAD_F(0x06193c50) /* 0.381161036 */, 18 }, /* 5621 */ { MAD_F(0x06199b24) /* 0.381251468 */, 18 }, /* 5622 */ { MAD_F(0x0619f9f8) /* 0.381341906 */, 18 }, /* 5623 */ { MAD_F(0x061a58ce) /* 0.381432349 */, 18 }, /* 5624 */ { MAD_F(0x061ab7a6) /* 0.381522798 */, 18 }, /* 5625 */ { MAD_F(0x061b167f) /* 0.381613251 */, 18 }, /* 5626 */ { MAD_F(0x061b7559) /* 0.381703711 */, 18 }, /* 5627 */ { MAD_F(0x061bd435) /* 0.381794175 */, 18 }, /* 5628 */ { MAD_F(0x061c3313) /* 0.381884645 */, 18 }, /* 5629 */ { MAD_F(0x061c91f1) /* 0.381975120 */, 18 }, /* 5630 */ { MAD_F(0x061cf0d2) /* 0.382065601 */, 18 }, /* 5631 */ { MAD_F(0x061d4fb3) /* 0.382156087 */, 18 }, /* 5632 */ { MAD_F(0x061dae96) /* 0.382246578 */, 18 }, /* 5633 */ { MAD_F(0x061e0d7b) /* 0.382337075 */, 18 }, /* 5634 */ { MAD_F(0x061e6c61) /* 0.382427577 */, 18 }, /* 5635 */ { MAD_F(0x061ecb48) /* 0.382518084 */, 18 }, /* 5636 */ { MAD_F(0x061f2a31) /* 0.382608597 */, 18 }, /* 5637 */ { MAD_F(0x061f891b) /* 0.382699115 */, 18 }, /* 5638 */ { MAD_F(0x061fe807) /* 0.382789638 */, 18 }, /* 5639 */ { MAD_F(0x062046f4) /* 0.382880167 */, 18 }, /* 5640 */ { MAD_F(0x0620a5e3) /* 0.382970701 */, 18 }, /* 5641 */ { MAD_F(0x062104d3) /* 0.383061241 */, 18 }, /* 5642 */ { MAD_F(0x062163c4) /* 0.383151786 */, 18 }, /* 5643 */ { MAD_F(0x0621c2b7) /* 0.383242336 */, 18 }, /* 5644 */ { MAD_F(0x062221ab) /* 0.383332891 */, 18 }, /* 5645 */ { MAD_F(0x062280a1) /* 0.383423452 */, 18 }, /* 5646 */ { MAD_F(0x0622df98) /* 0.383514018 */, 18 }, /* 5647 */ { MAD_F(0x06233e91) /* 0.383604590 */, 18 }, /* 5648 */ { MAD_F(0x06239d8b) /* 0.383695167 */, 18 }, /* 5649 */ { MAD_F(0x0623fc86) /* 0.383785749 */, 18 }, /* 5650 */ { MAD_F(0x06245b83) /* 0.383876337 */, 18 }, /* 5651 */ { MAD_F(0x0624ba82) /* 0.383966930 */, 18 }, /* 5652 */ { MAD_F(0x06251981) /* 0.384057528 */, 18 }, /* 5653 */ { MAD_F(0x06257883) /* 0.384148132 */, 18 }, /* 5654 */ { MAD_F(0x0625d785) /* 0.384238741 */, 18 }, /* 5655 */ { MAD_F(0x06263689) /* 0.384329355 */, 18 }, /* 5656 */ { MAD_F(0x0626958f) /* 0.384419975 */, 18 }, /* 5657 */ { MAD_F(0x0626f496) /* 0.384510600 */, 18 }, /* 5658 */ { MAD_F(0x0627539e) /* 0.384601230 */, 18 }, /* 5659 */ { MAD_F(0x0627b2a8) /* 0.384691866 */, 18 }, /* 5660 */ { MAD_F(0x062811b3) /* 0.384782507 */, 18 }, /* 5661 */ { MAD_F(0x062870c0) /* 0.384873153 */, 18 }, /* 5662 */ { MAD_F(0x0628cfce) /* 0.384963805 */, 18 }, /* 5663 */ { MAD_F(0x06292ede) /* 0.385054462 */, 18 }, /* 5664 */ { MAD_F(0x06298def) /* 0.385145124 */, 18 }, /* 5665 */ { MAD_F(0x0629ed01) /* 0.385235792 */, 18 }, /* 5666 */ { MAD_F(0x062a4c15) /* 0.385326465 */, 18 }, /* 5667 */ { MAD_F(0x062aab2a) /* 0.385417143 */, 18 }, /* 5668 */ { MAD_F(0x062b0a41) /* 0.385507827 */, 18 }, /* 5669 */ { MAD_F(0x062b6959) /* 0.385598516 */, 18 }, /* 5670 */ { MAD_F(0x062bc873) /* 0.385689211 */, 18 }, /* 5671 */ { MAD_F(0x062c278e) /* 0.385779910 */, 18 }, /* 5672 */ { MAD_F(0x062c86aa) /* 0.385870615 */, 18 }, /* 5673 */ { MAD_F(0x062ce5c8) /* 0.385961326 */, 18 }, /* 5674 */ { MAD_F(0x062d44e8) /* 0.386052041 */, 18 }, /* 5675 */ { MAD_F(0x062da408) /* 0.386142762 */, 18 }, /* 5676 */ { MAD_F(0x062e032a) /* 0.386233489 */, 18 }, /* 5677 */ { MAD_F(0x062e624e) /* 0.386324221 */, 18 }, /* 5678 */ { MAD_F(0x062ec173) /* 0.386414958 */, 18 }, /* 5679 */ { MAD_F(0x062f209a) /* 0.386505700 */, 18 }, /* 5680 */ { MAD_F(0x062f7fc1) /* 0.386596448 */, 18 }, /* 5681 */ { MAD_F(0x062fdeeb) /* 0.386687201 */, 18 }, /* 5682 */ { MAD_F(0x06303e16) /* 0.386777959 */, 18 }, /* 5683 */ { MAD_F(0x06309d42) /* 0.386868723 */, 18 }, /* 5684 */ { MAD_F(0x0630fc6f) /* 0.386959492 */, 18 }, /* 5685 */ { MAD_F(0x06315b9e) /* 0.387050266 */, 18 }, /* 5686 */ { MAD_F(0x0631bacf) /* 0.387141045 */, 18 }, /* 5687 */ { MAD_F(0x06321a01) /* 0.387231830 */, 18 }, /* 5688 */ { MAD_F(0x06327934) /* 0.387322621 */, 18 }, /* 5689 */ { MAD_F(0x0632d869) /* 0.387413416 */, 18 }, /* 5690 */ { MAD_F(0x0633379f) /* 0.387504217 */, 18 }, /* 5691 */ { MAD_F(0x063396d7) /* 0.387595023 */, 18 }, /* 5692 */ { MAD_F(0x0633f610) /* 0.387685835 */, 18 }, /* 5693 */ { MAD_F(0x0634554a) /* 0.387776652 */, 18 }, /* 5694 */ { MAD_F(0x0634b486) /* 0.387867474 */, 18 }, /* 5695 */ { MAD_F(0x063513c3) /* 0.387958301 */, 18 }, /* 5696 */ { MAD_F(0x06357302) /* 0.388049134 */, 18 }, /* 5697 */ { MAD_F(0x0635d242) /* 0.388139972 */, 18 }, /* 5698 */ { MAD_F(0x06363184) /* 0.388230816 */, 18 }, /* 5699 */ { MAD_F(0x063690c7) /* 0.388321665 */, 18 }, /* 5700 */ { MAD_F(0x0636f00b) /* 0.388412519 */, 18 }, /* 5701 */ { MAD_F(0x06374f51) /* 0.388503378 */, 18 }, /* 5702 */ { MAD_F(0x0637ae99) /* 0.388594243 */, 18 }, /* 5703 */ { MAD_F(0x06380de1) /* 0.388685113 */, 18 }, /* 5704 */ { MAD_F(0x06386d2b) /* 0.388775988 */, 18 }, /* 5705 */ { MAD_F(0x0638cc77) /* 0.388866869 */, 18 }, /* 5706 */ { MAD_F(0x06392bc4) /* 0.388957755 */, 18 }, /* 5707 */ { MAD_F(0x06398b12) /* 0.389048646 */, 18 }, /* 5708 */ { MAD_F(0x0639ea62) /* 0.389139542 */, 18 }, /* 5709 */ { MAD_F(0x063a49b4) /* 0.389230444 */, 18 }, /* 5710 */ { MAD_F(0x063aa906) /* 0.389321352 */, 18 }, /* 5711 */ { MAD_F(0x063b085a) /* 0.389412264 */, 18 }, /* 5712 */ { MAD_F(0x063b67b0) /* 0.389503182 */, 18 }, /* 5713 */ { MAD_F(0x063bc707) /* 0.389594105 */, 18 }, /* 5714 */ { MAD_F(0x063c265f) /* 0.389685033 */, 18 }, /* 5715 */ { MAD_F(0x063c85b9) /* 0.389775967 */, 18 }, /* 5716 */ { MAD_F(0x063ce514) /* 0.389866906 */, 18 }, /* 5717 */ { MAD_F(0x063d4471) /* 0.389957850 */, 18 }, /* 5718 */ { MAD_F(0x063da3cf) /* 0.390048800 */, 18 }, /* 5719 */ { MAD_F(0x063e032f) /* 0.390139755 */, 18 }, /* 5720 */ { MAD_F(0x063e6290) /* 0.390230715 */, 18 }, /* 5721 */ { MAD_F(0x063ec1f2) /* 0.390321681 */, 18 }, /* 5722 */ { MAD_F(0x063f2156) /* 0.390412651 */, 18 }, /* 5723 */ { MAD_F(0x063f80bb) /* 0.390503628 */, 18 }, /* 5724 */ { MAD_F(0x063fe022) /* 0.390594609 */, 18 }, /* 5725 */ { MAD_F(0x06403f8a) /* 0.390685596 */, 18 }, /* 5726 */ { MAD_F(0x06409ef3) /* 0.390776588 */, 18 }, /* 5727 */ { MAD_F(0x0640fe5e) /* 0.390867585 */, 18 }, /* 5728 */ { MAD_F(0x06415dcb) /* 0.390958588 */, 18 }, /* 5729 */ { MAD_F(0x0641bd38) /* 0.391049596 */, 18 }, /* 5730 */ { MAD_F(0x06421ca7) /* 0.391140609 */, 18 }, /* 5731 */ { MAD_F(0x06427c18) /* 0.391231627 */, 18 }, /* 5732 */ { MAD_F(0x0642db8a) /* 0.391322651 */, 18 }, /* 5733 */ { MAD_F(0x06433afd) /* 0.391413680 */, 18 }, /* 5734 */ { MAD_F(0x06439a72) /* 0.391504714 */, 18 }, /* 5735 */ { MAD_F(0x0643f9e9) /* 0.391595754 */, 18 }, /* 5736 */ { MAD_F(0x06445960) /* 0.391686799 */, 18 }, /* 5737 */ { MAD_F(0x0644b8d9) /* 0.391777849 */, 18 }, /* 5738 */ { MAD_F(0x06451854) /* 0.391868905 */, 18 }, /* 5739 */ { MAD_F(0x064577d0) /* 0.391959966 */, 18 }, /* 5740 */ { MAD_F(0x0645d74d) /* 0.392051032 */, 18 }, /* 5741 */ { MAD_F(0x064636cc) /* 0.392142103 */, 18 }, /* 5742 */ { MAD_F(0x0646964c) /* 0.392233180 */, 18 }, /* 5743 */ { MAD_F(0x0646f5ce) /* 0.392324262 */, 18 }, /* 5744 */ { MAD_F(0x06475551) /* 0.392415349 */, 18 }, /* 5745 */ { MAD_F(0x0647b4d5) /* 0.392506442 */, 18 }, /* 5746 */ { MAD_F(0x0648145b) /* 0.392597540 */, 18 }, /* 5747 */ { MAD_F(0x064873e3) /* 0.392688643 */, 18 }, /* 5748 */ { MAD_F(0x0648d36b) /* 0.392779751 */, 18 }, /* 5749 */ { MAD_F(0x064932f6) /* 0.392870865 */, 18 }, /* 5750 */ { MAD_F(0x06499281) /* 0.392961984 */, 18 }, /* 5751 */ { MAD_F(0x0649f20e) /* 0.393053108 */, 18 }, /* 5752 */ { MAD_F(0x064a519c) /* 0.393144238 */, 18 }, /* 5753 */ { MAD_F(0x064ab12c) /* 0.393235372 */, 18 }, /* 5754 */ { MAD_F(0x064b10be) /* 0.393326513 */, 18 }, /* 5755 */ { MAD_F(0x064b7050) /* 0.393417658 */, 18 }, /* 5756 */ { MAD_F(0x064bcfe4) /* 0.393508809 */, 18 }, /* 5757 */ { MAD_F(0x064c2f7a) /* 0.393599965 */, 18 }, /* 5758 */ { MAD_F(0x064c8f11) /* 0.393691126 */, 18 }, /* 5759 */ { MAD_F(0x064ceea9) /* 0.393782292 */, 18 }, /* 5760 */ { MAD_F(0x064d4e43) /* 0.393873464 */, 18 }, /* 5761 */ { MAD_F(0x064dadde) /* 0.393964641 */, 18 }, /* 5762 */ { MAD_F(0x064e0d7a) /* 0.394055823 */, 18 }, /* 5763 */ { MAD_F(0x064e6d18) /* 0.394147011 */, 18 }, /* 5764 */ { MAD_F(0x064eccb8) /* 0.394238204 */, 18 }, /* 5765 */ { MAD_F(0x064f2c59) /* 0.394329402 */, 18 }, /* 5766 */ { MAD_F(0x064f8bfb) /* 0.394420605 */, 18 }, /* 5767 */ { MAD_F(0x064feb9e) /* 0.394511814 */, 18 }, /* 5768 */ { MAD_F(0x06504b44) /* 0.394603028 */, 18 }, /* 5769 */ { MAD_F(0x0650aaea) /* 0.394694247 */, 18 }, /* 5770 */ { MAD_F(0x06510a92) /* 0.394785472 */, 18 }, /* 5771 */ { MAD_F(0x06516a3b) /* 0.394876702 */, 18 }, /* 5772 */ { MAD_F(0x0651c9e6) /* 0.394967937 */, 18 }, /* 5773 */ { MAD_F(0x06522992) /* 0.395059177 */, 18 }, /* 5774 */ { MAD_F(0x06528940) /* 0.395150423 */, 18 }, /* 5775 */ { MAD_F(0x0652e8ef) /* 0.395241673 */, 18 }, /* 5776 */ { MAD_F(0x0653489f) /* 0.395332930 */, 18 }, /* 5777 */ { MAD_F(0x0653a851) /* 0.395424191 */, 18 }, /* 5778 */ { MAD_F(0x06540804) /* 0.395515458 */, 18 }, /* 5779 */ { MAD_F(0x065467b9) /* 0.395606730 */, 18 }, /* 5780 */ { MAD_F(0x0654c76f) /* 0.395698007 */, 18 }, /* 5781 */ { MAD_F(0x06552726) /* 0.395789289 */, 18 }, /* 5782 */ { MAD_F(0x065586df) /* 0.395880577 */, 18 }, /* 5783 */ { MAD_F(0x0655e699) /* 0.395971870 */, 18 }, /* 5784 */ { MAD_F(0x06564655) /* 0.396063168 */, 18 }, /* 5785 */ { MAD_F(0x0656a612) /* 0.396154472 */, 18 }, /* 5786 */ { MAD_F(0x065705d0) /* 0.396245780 */, 18 }, /* 5787 */ { MAD_F(0x06576590) /* 0.396337094 */, 18 }, /* 5788 */ { MAD_F(0x0657c552) /* 0.396428414 */, 18 }, /* 5789 */ { MAD_F(0x06582514) /* 0.396519738 */, 18 }, /* 5790 */ { MAD_F(0x065884d9) /* 0.396611068 */, 18 }, /* 5791 */ { MAD_F(0x0658e49e) /* 0.396702403 */, 18 }, /* 5792 */ { MAD_F(0x06594465) /* 0.396793743 */, 18 }, /* 5793 */ { MAD_F(0x0659a42e) /* 0.396885089 */, 18 }, /* 5794 */ { MAD_F(0x065a03f7) /* 0.396976440 */, 18 }, /* 5795 */ { MAD_F(0x065a63c3) /* 0.397067796 */, 18 }, /* 5796 */ { MAD_F(0x065ac38f) /* 0.397159157 */, 18 }, /* 5797 */ { MAD_F(0x065b235d) /* 0.397250524 */, 18 }, /* 5798 */ { MAD_F(0x065b832d) /* 0.397341896 */, 18 }, /* 5799 */ { MAD_F(0x065be2fe) /* 0.397433273 */, 18 }, /* 5800 */ { MAD_F(0x065c42d0) /* 0.397524655 */, 18 }, /* 5801 */ { MAD_F(0x065ca2a3) /* 0.397616043 */, 18 }, /* 5802 */ { MAD_F(0x065d0279) /* 0.397707436 */, 18 }, /* 5803 */ { MAD_F(0x065d624f) /* 0.397798834 */, 18 }, /* 5804 */ { MAD_F(0x065dc227) /* 0.397890237 */, 18 }, /* 5805 */ { MAD_F(0x065e2200) /* 0.397981646 */, 18 }, /* 5806 */ { MAD_F(0x065e81db) /* 0.398073059 */, 18 }, /* 5807 */ { MAD_F(0x065ee1b7) /* 0.398164479 */, 18 }, /* 5808 */ { MAD_F(0x065f4195) /* 0.398255903 */, 18 }, /* 5809 */ { MAD_F(0x065fa174) /* 0.398347333 */, 18 }, /* 5810 */ { MAD_F(0x06600154) /* 0.398438767 */, 18 }, /* 5811 */ { MAD_F(0x06606136) /* 0.398530207 */, 18 }, /* 5812 */ { MAD_F(0x0660c119) /* 0.398621653 */, 18 }, /* 5813 */ { MAD_F(0x066120fd) /* 0.398713103 */, 18 }, /* 5814 */ { MAD_F(0x066180e3) /* 0.398804559 */, 18 }, /* 5815 */ { MAD_F(0x0661e0cb) /* 0.398896020 */, 18 }, /* 5816 */ { MAD_F(0x066240b4) /* 0.398987487 */, 18 }, /* 5817 */ { MAD_F(0x0662a09e) /* 0.399078958 */, 18 }, /* 5818 */ { MAD_F(0x06630089) /* 0.399170435 */, 18 }, /* 5819 */ { MAD_F(0x06636077) /* 0.399261917 */, 18 }, /* 5820 */ { MAD_F(0x0663c065) /* 0.399353404 */, 18 }, /* 5821 */ { MAD_F(0x06642055) /* 0.399444897 */, 18 }, /* 5822 */ { MAD_F(0x06648046) /* 0.399536395 */, 18 }, /* 5823 */ { MAD_F(0x0664e039) /* 0.399627898 */, 18 }, /* 5824 */ { MAD_F(0x0665402d) /* 0.399719406 */, 18 }, /* 5825 */ { MAD_F(0x0665a022) /* 0.399810919 */, 18 }, /* 5826 */ { MAD_F(0x06660019) /* 0.399902438 */, 18 }, /* 5827 */ { MAD_F(0x06666011) /* 0.399993962 */, 18 }, /* 5828 */ { MAD_F(0x0666c00b) /* 0.400085491 */, 18 }, /* 5829 */ { MAD_F(0x06672006) /* 0.400177026 */, 18 }, /* 5830 */ { MAD_F(0x06678003) /* 0.400268565 */, 18 }, /* 5831 */ { MAD_F(0x0667e000) /* 0.400360110 */, 18 }, /* 5832 */ { MAD_F(0x06684000) /* 0.400451660 */, 18 }, /* 5833 */ { MAD_F(0x0668a000) /* 0.400543216 */, 18 }, /* 5834 */ { MAD_F(0x06690003) /* 0.400634776 */, 18 }, /* 5835 */ { MAD_F(0x06696006) /* 0.400726342 */, 18 }, /* 5836 */ { MAD_F(0x0669c00b) /* 0.400817913 */, 18 }, /* 5837 */ { MAD_F(0x066a2011) /* 0.400909489 */, 18 }, /* 5838 */ { MAD_F(0x066a8019) /* 0.401001071 */, 18 }, /* 5839 */ { MAD_F(0x066ae022) /* 0.401092657 */, 18 }, /* 5840 */ { MAD_F(0x066b402d) /* 0.401184249 */, 18 }, /* 5841 */ { MAD_F(0x066ba039) /* 0.401275847 */, 18 }, /* 5842 */ { MAD_F(0x066c0046) /* 0.401367449 */, 18 }, /* 5843 */ { MAD_F(0x066c6055) /* 0.401459057 */, 18 }, /* 5844 */ { MAD_F(0x066cc065) /* 0.401550670 */, 18 }, /* 5845 */ { MAD_F(0x066d2076) /* 0.401642288 */, 18 }, /* 5846 */ { MAD_F(0x066d8089) /* 0.401733911 */, 18 }, /* 5847 */ { MAD_F(0x066de09e) /* 0.401825540 */, 18 }, /* 5848 */ { MAD_F(0x066e40b3) /* 0.401917173 */, 18 }, /* 5849 */ { MAD_F(0x066ea0cb) /* 0.402008812 */, 18 }, /* 5850 */ { MAD_F(0x066f00e3) /* 0.402100457 */, 18 }, /* 5851 */ { MAD_F(0x066f60fd) /* 0.402192106 */, 18 }, /* 5852 */ { MAD_F(0x066fc118) /* 0.402283761 */, 18 }, /* 5853 */ { MAD_F(0x06702135) /* 0.402375420 */, 18 }, /* 5854 */ { MAD_F(0x06708153) /* 0.402467086 */, 18 }, /* 5855 */ { MAD_F(0x0670e173) /* 0.402558756 */, 18 }, /* 5856 */ { MAD_F(0x06714194) /* 0.402650431 */, 18 }, /* 5857 */ { MAD_F(0x0671a1b6) /* 0.402742112 */, 18 }, /* 5858 */ { MAD_F(0x067201da) /* 0.402833798 */, 18 }, /* 5859 */ { MAD_F(0x067261ff) /* 0.402925489 */, 18 }, /* 5860 */ { MAD_F(0x0672c226) /* 0.403017186 */, 18 }, /* 5861 */ { MAD_F(0x0673224e) /* 0.403108887 */, 18 }, /* 5862 */ { MAD_F(0x06738277) /* 0.403200594 */, 18 }, /* 5863 */ { MAD_F(0x0673e2a2) /* 0.403292306 */, 18 }, /* 5864 */ { MAD_F(0x067442ce) /* 0.403384024 */, 18 }, /* 5865 */ { MAD_F(0x0674a2fc) /* 0.403475746 */, 18 }, /* 5866 */ { MAD_F(0x0675032b) /* 0.403567474 */, 18 }, /* 5867 */ { MAD_F(0x0675635b) /* 0.403659207 */, 18 }, /* 5868 */ { MAD_F(0x0675c38d) /* 0.403750945 */, 18 }, /* 5869 */ { MAD_F(0x067623c0) /* 0.403842688 */, 18 }, /* 5870 */ { MAD_F(0x067683f4) /* 0.403934437 */, 18 }, /* 5871 */ { MAD_F(0x0676e42a) /* 0.404026190 */, 18 }, /* 5872 */ { MAD_F(0x06774462) /* 0.404117949 */, 18 }, /* 5873 */ { MAD_F(0x0677a49b) /* 0.404209714 */, 18 }, /* 5874 */ { MAD_F(0x067804d5) /* 0.404301483 */, 18 }, /* 5875 */ { MAD_F(0x06786510) /* 0.404393258 */, 18 }, /* 5876 */ { MAD_F(0x0678c54d) /* 0.404485037 */, 18 }, /* 5877 */ { MAD_F(0x0679258c) /* 0.404576822 */, 18 }, /* 5878 */ { MAD_F(0x067985cb) /* 0.404668613 */, 18 }, /* 5879 */ { MAD_F(0x0679e60c) /* 0.404760408 */, 18 }, /* 5880 */ { MAD_F(0x067a464f) /* 0.404852209 */, 18 }, /* 5881 */ { MAD_F(0x067aa693) /* 0.404944014 */, 18 }, /* 5882 */ { MAD_F(0x067b06d8) /* 0.405035825 */, 18 }, /* 5883 */ { MAD_F(0x067b671f) /* 0.405127642 */, 18 }, /* 5884 */ { MAD_F(0x067bc767) /* 0.405219463 */, 18 }, /* 5885 */ { MAD_F(0x067c27b1) /* 0.405311290 */, 18 }, /* 5886 */ { MAD_F(0x067c87fc) /* 0.405403122 */, 18 }, /* 5887 */ { MAD_F(0x067ce848) /* 0.405494959 */, 18 }, /* 5888 */ { MAD_F(0x067d4896) /* 0.405586801 */, 18 }, /* 5889 */ { MAD_F(0x067da8e5) /* 0.405678648 */, 18 }, /* 5890 */ { MAD_F(0x067e0935) /* 0.405770501 */, 18 }, /* 5891 */ { MAD_F(0x067e6987) /* 0.405862359 */, 18 }, /* 5892 */ { MAD_F(0x067ec9da) /* 0.405954222 */, 18 }, /* 5893 */ { MAD_F(0x067f2a2f) /* 0.406046090 */, 18 }, /* 5894 */ { MAD_F(0x067f8a85) /* 0.406137963 */, 18 }, /* 5895 */ { MAD_F(0x067feadd) /* 0.406229842 */, 18 }, /* 5896 */ { MAD_F(0x06804b36) /* 0.406321726 */, 18 }, /* 5897 */ { MAD_F(0x0680ab90) /* 0.406413615 */, 18 }, /* 5898 */ { MAD_F(0x06810beb) /* 0.406505509 */, 18 }, /* 5899 */ { MAD_F(0x06816c49) /* 0.406597408 */, 18 }, /* 5900 */ { MAD_F(0x0681cca7) /* 0.406689313 */, 18 }, /* 5901 */ { MAD_F(0x06822d07) /* 0.406781223 */, 18 }, /* 5902 */ { MAD_F(0x06828d68) /* 0.406873138 */, 18 }, /* 5903 */ { MAD_F(0x0682edcb) /* 0.406965058 */, 18 }, /* 5904 */ { MAD_F(0x06834e2f) /* 0.407056983 */, 18 }, /* 5905 */ { MAD_F(0x0683ae94) /* 0.407148914 */, 18 }, /* 5906 */ { MAD_F(0x06840efb) /* 0.407240850 */, 18 }, /* 5907 */ { MAD_F(0x06846f63) /* 0.407332791 */, 18 }, /* 5908 */ { MAD_F(0x0684cfcd) /* 0.407424737 */, 18 }, /* 5909 */ { MAD_F(0x06853038) /* 0.407516688 */, 18 }, /* 5910 */ { MAD_F(0x068590a4) /* 0.407608645 */, 18 }, /* 5911 */ { MAD_F(0x0685f112) /* 0.407700606 */, 18 }, /* 5912 */ { MAD_F(0x06865181) /* 0.407792573 */, 18 }, /* 5913 */ { MAD_F(0x0686b1f2) /* 0.407884545 */, 18 }, /* 5914 */ { MAD_F(0x06871264) /* 0.407976522 */, 18 }, /* 5915 */ { MAD_F(0x068772d7) /* 0.408068505 */, 18 }, /* 5916 */ { MAD_F(0x0687d34c) /* 0.408160492 */, 18 }, /* 5917 */ { MAD_F(0x068833c2) /* 0.408252485 */, 18 }, /* 5918 */ { MAD_F(0x06889439) /* 0.408344483 */, 18 }, /* 5919 */ { MAD_F(0x0688f4b2) /* 0.408436486 */, 18 }, /* 5920 */ { MAD_F(0x0689552c) /* 0.408528495 */, 18 }, /* 5921 */ { MAD_F(0x0689b5a8) /* 0.408620508 */, 18 }, /* 5922 */ { MAD_F(0x068a1625) /* 0.408712527 */, 18 }, /* 5923 */ { MAD_F(0x068a76a4) /* 0.408804551 */, 18 }, /* 5924 */ { MAD_F(0x068ad724) /* 0.408896580 */, 18 }, /* 5925 */ { MAD_F(0x068b37a5) /* 0.408988614 */, 18 }, /* 5926 */ { MAD_F(0x068b9827) /* 0.409080653 */, 18 }, /* 5927 */ { MAD_F(0x068bf8ac) /* 0.409172698 */, 18 }, /* 5928 */ { MAD_F(0x068c5931) /* 0.409264748 */, 18 }, /* 5929 */ { MAD_F(0x068cb9b8) /* 0.409356803 */, 18 }, /* 5930 */ { MAD_F(0x068d1a40) /* 0.409448863 */, 18 }, /* 5931 */ { MAD_F(0x068d7aca) /* 0.409540928 */, 18 }, /* 5932 */ { MAD_F(0x068ddb54) /* 0.409632999 */, 18 }, /* 5933 */ { MAD_F(0x068e3be1) /* 0.409725074 */, 18 }, /* 5934 */ { MAD_F(0x068e9c6f) /* 0.409817155 */, 18 }, /* 5935 */ { MAD_F(0x068efcfe) /* 0.409909241 */, 18 }, /* 5936 */ { MAD_F(0x068f5d8e) /* 0.410001332 */, 18 }, /* 5937 */ { MAD_F(0x068fbe20) /* 0.410093428 */, 18 }, /* 5938 */ { MAD_F(0x06901eb4) /* 0.410185530 */, 18 }, /* 5939 */ { MAD_F(0x06907f48) /* 0.410277637 */, 18 }, /* 5940 */ { MAD_F(0x0690dfde) /* 0.410369748 */, 18 }, /* 5941 */ { MAD_F(0x06914076) /* 0.410461865 */, 18 }, /* 5942 */ { MAD_F(0x0691a10f) /* 0.410553988 */, 18 }, /* 5943 */ { MAD_F(0x069201a9) /* 0.410646115 */, 18 }, /* 5944 */ { MAD_F(0x06926245) /* 0.410738247 */, 18 }, /* 5945 */ { MAD_F(0x0692c2e2) /* 0.410830385 */, 18 }, /* 5946 */ { MAD_F(0x06932380) /* 0.410922528 */, 18 }, /* 5947 */ { MAD_F(0x06938420) /* 0.411014676 */, 18 }, /* 5948 */ { MAD_F(0x0693e4c1) /* 0.411106829 */, 18 }, /* 5949 */ { MAD_F(0x06944563) /* 0.411198987 */, 18 }, /* 5950 */ { MAD_F(0x0694a607) /* 0.411291151 */, 18 }, /* 5951 */ { MAD_F(0x069506ad) /* 0.411383320 */, 18 }, /* 5952 */ { MAD_F(0x06956753) /* 0.411475493 */, 18 }, /* 5953 */ { MAD_F(0x0695c7fc) /* 0.411567672 */, 18 }, /* 5954 */ { MAD_F(0x069628a5) /* 0.411659857 */, 18 }, /* 5955 */ { MAD_F(0x06968950) /* 0.411752046 */, 18 }, /* 5956 */ { MAD_F(0x0696e9fc) /* 0.411844240 */, 18 }, /* 5957 */ { MAD_F(0x06974aaa) /* 0.411936440 */, 18 }, /* 5958 */ { MAD_F(0x0697ab59) /* 0.412028645 */, 18 }, /* 5959 */ { MAD_F(0x06980c09) /* 0.412120855 */, 18 }, /* 5960 */ { MAD_F(0x06986cbb) /* 0.412213070 */, 18 }, /* 5961 */ { MAD_F(0x0698cd6e) /* 0.412305290 */, 18 }, /* 5962 */ { MAD_F(0x06992e23) /* 0.412397516 */, 18 }, /* 5963 */ { MAD_F(0x06998ed9) /* 0.412489746 */, 18 }, /* 5964 */ { MAD_F(0x0699ef90) /* 0.412581982 */, 18 }, /* 5965 */ { MAD_F(0x069a5049) /* 0.412674223 */, 18 }, /* 5966 */ { MAD_F(0x069ab103) /* 0.412766469 */, 18 }, /* 5967 */ { MAD_F(0x069b11bf) /* 0.412858720 */, 18 }, /* 5968 */ { MAD_F(0x069b727b) /* 0.412950976 */, 18 }, /* 5969 */ { MAD_F(0x069bd33a) /* 0.413043238 */, 18 }, /* 5970 */ { MAD_F(0x069c33f9) /* 0.413135505 */, 18 }, /* 5971 */ { MAD_F(0x069c94ba) /* 0.413227776 */, 18 }, /* 5972 */ { MAD_F(0x069cf57d) /* 0.413320053 */, 18 }, /* 5973 */ { MAD_F(0x069d5641) /* 0.413412335 */, 18 }, /* 5974 */ { MAD_F(0x069db706) /* 0.413504623 */, 18 }, /* 5975 */ { MAD_F(0x069e17cc) /* 0.413596915 */, 18 }, /* 5976 */ { MAD_F(0x069e7894) /* 0.413689213 */, 18 }, /* 5977 */ { MAD_F(0x069ed95e) /* 0.413781515 */, 18 }, /* 5978 */ { MAD_F(0x069f3a28) /* 0.413873823 */, 18 }, /* 5979 */ { MAD_F(0x069f9af4) /* 0.413966136 */, 18 }, /* 5980 */ { MAD_F(0x069ffbc2) /* 0.414058454 */, 18 }, /* 5981 */ { MAD_F(0x06a05c91) /* 0.414150778 */, 18 }, /* 5982 */ { MAD_F(0x06a0bd61) /* 0.414243106 */, 18 }, /* 5983 */ { MAD_F(0x06a11e32) /* 0.414335440 */, 18 }, /* 5984 */ { MAD_F(0x06a17f05) /* 0.414427779 */, 18 }, /* 5985 */ { MAD_F(0x06a1dfda) /* 0.414520122 */, 18 }, /* 5986 */ { MAD_F(0x06a240b0) /* 0.414612471 */, 18 }, /* 5987 */ { MAD_F(0x06a2a187) /* 0.414704826 */, 18 }, /* 5988 */ { MAD_F(0x06a3025f) /* 0.414797185 */, 18 }, /* 5989 */ { MAD_F(0x06a36339) /* 0.414889549 */, 18 }, /* 5990 */ { MAD_F(0x06a3c414) /* 0.414981919 */, 18 }, /* 5991 */ { MAD_F(0x06a424f1) /* 0.415074294 */, 18 }, /* 5992 */ { MAD_F(0x06a485cf) /* 0.415166674 */, 18 }, /* 5993 */ { MAD_F(0x06a4e6ae) /* 0.415259059 */, 18 }, /* 5994 */ { MAD_F(0x06a5478f) /* 0.415351449 */, 18 }, /* 5995 */ { MAD_F(0x06a5a871) /* 0.415443844 */, 18 }, /* 5996 */ { MAD_F(0x06a60955) /* 0.415536244 */, 18 }, /* 5997 */ { MAD_F(0x06a66a3a) /* 0.415628650 */, 18 }, /* 5998 */ { MAD_F(0x06a6cb20) /* 0.415721061 */, 18 }, /* 5999 */ { MAD_F(0x06a72c08) /* 0.415813476 */, 18 }, /* 6000 */ { MAD_F(0x06a78cf1) /* 0.415905897 */, 18 }, /* 6001 */ { MAD_F(0x06a7eddb) /* 0.415998324 */, 18 }, /* 6002 */ { MAD_F(0x06a84ec7) /* 0.416090755 */, 18 }, /* 6003 */ { MAD_F(0x06a8afb4) /* 0.416183191 */, 18 }, /* 6004 */ { MAD_F(0x06a910a3) /* 0.416275633 */, 18 }, /* 6005 */ { MAD_F(0x06a97193) /* 0.416368079 */, 18 }, /* 6006 */ { MAD_F(0x06a9d284) /* 0.416460531 */, 18 }, /* 6007 */ { MAD_F(0x06aa3377) /* 0.416552988 */, 18 }, /* 6008 */ { MAD_F(0x06aa946b) /* 0.416645450 */, 18 }, /* 6009 */ { MAD_F(0x06aaf561) /* 0.416737917 */, 18 }, /* 6010 */ { MAD_F(0x06ab5657) /* 0.416830389 */, 18 }, /* 6011 */ { MAD_F(0x06abb750) /* 0.416922867 */, 18 }, /* 6012 */ { MAD_F(0x06ac1849) /* 0.417015349 */, 18 }, /* 6013 */ { MAD_F(0x06ac7944) /* 0.417107837 */, 18 }, /* 6014 */ { MAD_F(0x06acda41) /* 0.417200330 */, 18 }, /* 6015 */ { MAD_F(0x06ad3b3e) /* 0.417292828 */, 18 }, /* 6016 */ { MAD_F(0x06ad9c3d) /* 0.417385331 */, 18 }, /* 6017 */ { MAD_F(0x06adfd3e) /* 0.417477839 */, 18 }, /* 6018 */ { MAD_F(0x06ae5e40) /* 0.417570352 */, 18 }, /* 6019 */ { MAD_F(0x06aebf43) /* 0.417662871 */, 18 }, /* 6020 */ { MAD_F(0x06af2047) /* 0.417755394 */, 18 }, /* 6021 */ { MAD_F(0x06af814d) /* 0.417847923 */, 18 }, /* 6022 */ { MAD_F(0x06afe255) /* 0.417940457 */, 18 }, /* 6023 */ { MAD_F(0x06b0435e) /* 0.418032996 */, 18 }, /* 6024 */ { MAD_F(0x06b0a468) /* 0.418125540 */, 18 }, /* 6025 */ { MAD_F(0x06b10573) /* 0.418218089 */, 18 }, /* 6026 */ { MAD_F(0x06b16680) /* 0.418310643 */, 18 }, /* 6027 */ { MAD_F(0x06b1c78e) /* 0.418403203 */, 18 }, /* 6028 */ { MAD_F(0x06b2289e) /* 0.418495767 */, 18 }, /* 6029 */ { MAD_F(0x06b289af) /* 0.418588337 */, 18 }, /* 6030 */ { MAD_F(0x06b2eac1) /* 0.418680911 */, 18 }, /* 6031 */ { MAD_F(0x06b34bd5) /* 0.418773491 */, 18 }, /* 6032 */ { MAD_F(0x06b3acea) /* 0.418866076 */, 18 }, /* 6033 */ { MAD_F(0x06b40e00) /* 0.418958666 */, 18 }, /* 6034 */ { MAD_F(0x06b46f18) /* 0.419051262 */, 18 }, /* 6035 */ { MAD_F(0x06b4d031) /* 0.419143862 */, 18 }, /* 6036 */ { MAD_F(0x06b5314c) /* 0.419236467 */, 18 }, /* 6037 */ { MAD_F(0x06b59268) /* 0.419329078 */, 18 }, /* 6038 */ { MAD_F(0x06b5f385) /* 0.419421694 */, 18 }, /* 6039 */ { MAD_F(0x06b654a4) /* 0.419514314 */, 18 }, /* 6040 */ { MAD_F(0x06b6b5c4) /* 0.419606940 */, 18 }, /* 6041 */ { MAD_F(0x06b716e6) /* 0.419699571 */, 18 }, /* 6042 */ { MAD_F(0x06b77808) /* 0.419792208 */, 18 }, /* 6043 */ { MAD_F(0x06b7d92d) /* 0.419884849 */, 18 }, /* 6044 */ { MAD_F(0x06b83a52) /* 0.419977495 */, 18 }, /* 6045 */ { MAD_F(0x06b89b79) /* 0.420070147 */, 18 }, /* 6046 */ { MAD_F(0x06b8fca1) /* 0.420162803 */, 18 }, /* 6047 */ { MAD_F(0x06b95dcb) /* 0.420255465 */, 18 }, /* 6048 */ { MAD_F(0x06b9bef6) /* 0.420348132 */, 18 }, /* 6049 */ { MAD_F(0x06ba2023) /* 0.420440803 */, 18 }, /* 6050 */ { MAD_F(0x06ba8150) /* 0.420533481 */, 18 }, /* 6051 */ { MAD_F(0x06bae280) /* 0.420626163 */, 18 }, /* 6052 */ { MAD_F(0x06bb43b0) /* 0.420718850 */, 18 }, /* 6053 */ { MAD_F(0x06bba4e2) /* 0.420811542 */, 18 }, /* 6054 */ { MAD_F(0x06bc0615) /* 0.420904240 */, 18 }, /* 6055 */ { MAD_F(0x06bc674a) /* 0.420996942 */, 18 }, /* 6056 */ { MAD_F(0x06bcc880) /* 0.421089650 */, 18 }, /* 6057 */ { MAD_F(0x06bd29b7) /* 0.421182362 */, 18 }, /* 6058 */ { MAD_F(0x06bd8af0) /* 0.421275080 */, 18 }, /* 6059 */ { MAD_F(0x06bdec2a) /* 0.421367803 */, 18 }, /* 6060 */ { MAD_F(0x06be4d66) /* 0.421460531 */, 18 }, /* 6061 */ { MAD_F(0x06beaea3) /* 0.421553264 */, 18 }, /* 6062 */ { MAD_F(0x06bf0fe1) /* 0.421646003 */, 18 }, /* 6063 */ { MAD_F(0x06bf7120) /* 0.421738746 */, 18 }, /* 6064 */ { MAD_F(0x06bfd261) /* 0.421831494 */, 18 }, /* 6065 */ { MAD_F(0x06c033a4) /* 0.421924248 */, 18 }, /* 6066 */ { MAD_F(0x06c094e7) /* 0.422017007 */, 18 }, /* 6067 */ { MAD_F(0x06c0f62c) /* 0.422109770 */, 18 }, /* 6068 */ { MAD_F(0x06c15773) /* 0.422202539 */, 18 }, /* 6069 */ { MAD_F(0x06c1b8bb) /* 0.422295313 */, 18 }, /* 6070 */ { MAD_F(0x06c21a04) /* 0.422388092 */, 18 }, /* 6071 */ { MAD_F(0x06c27b4e) /* 0.422480876 */, 18 }, /* 6072 */ { MAD_F(0x06c2dc9a) /* 0.422573665 */, 18 }, /* 6073 */ { MAD_F(0x06c33de8) /* 0.422666460 */, 18 }, /* 6074 */ { MAD_F(0x06c39f36) /* 0.422759259 */, 18 }, /* 6075 */ { MAD_F(0x06c40086) /* 0.422852064 */, 18 }, /* 6076 */ { MAD_F(0x06c461d8) /* 0.422944873 */, 18 }, /* 6077 */ { MAD_F(0x06c4c32a) /* 0.423037688 */, 18 }, /* 6078 */ { MAD_F(0x06c5247f) /* 0.423130508 */, 18 }, /* 6079 */ { MAD_F(0x06c585d4) /* 0.423223333 */, 18 }, /* 6080 */ { MAD_F(0x06c5e72b) /* 0.423316162 */, 18 }, /* 6081 */ { MAD_F(0x06c64883) /* 0.423408997 */, 18 }, /* 6082 */ { MAD_F(0x06c6a9dd) /* 0.423501838 */, 18 }, /* 6083 */ { MAD_F(0x06c70b38) /* 0.423594683 */, 18 }, /* 6084 */ { MAD_F(0x06c76c94) /* 0.423687533 */, 18 }, /* 6085 */ { MAD_F(0x06c7cdf2) /* 0.423780389 */, 18 }, /* 6086 */ { MAD_F(0x06c82f51) /* 0.423873249 */, 18 }, /* 6087 */ { MAD_F(0x06c890b1) /* 0.423966115 */, 18 }, /* 6088 */ { MAD_F(0x06c8f213) /* 0.424058985 */, 18 }, /* 6089 */ { MAD_F(0x06c95376) /* 0.424151861 */, 18 }, /* 6090 */ { MAD_F(0x06c9b4da) /* 0.424244742 */, 18 }, /* 6091 */ { MAD_F(0x06ca1640) /* 0.424337628 */, 18 }, /* 6092 */ { MAD_F(0x06ca77a8) /* 0.424430519 */, 18 }, /* 6093 */ { MAD_F(0x06cad910) /* 0.424523415 */, 18 }, /* 6094 */ { MAD_F(0x06cb3a7a) /* 0.424616316 */, 18 }, /* 6095 */ { MAD_F(0x06cb9be5) /* 0.424709222 */, 18 }, /* 6096 */ { MAD_F(0x06cbfd52) /* 0.424802133 */, 18 }, /* 6097 */ { MAD_F(0x06cc5ec0) /* 0.424895050 */, 18 }, /* 6098 */ { MAD_F(0x06ccc030) /* 0.424987971 */, 18 }, /* 6099 */ { MAD_F(0x06cd21a0) /* 0.425080898 */, 18 }, /* 6100 */ { MAD_F(0x06cd8313) /* 0.425173829 */, 18 }, /* 6101 */ { MAD_F(0x06cde486) /* 0.425266766 */, 18 }, /* 6102 */ { MAD_F(0x06ce45fb) /* 0.425359708 */, 18 }, /* 6103 */ { MAD_F(0x06cea771) /* 0.425452655 */, 18 }, /* 6104 */ { MAD_F(0x06cf08e9) /* 0.425545607 */, 18 }, /* 6105 */ { MAD_F(0x06cf6a62) /* 0.425638564 */, 18 }, /* 6106 */ { MAD_F(0x06cfcbdc) /* 0.425731526 */, 18 }, /* 6107 */ { MAD_F(0x06d02d58) /* 0.425824493 */, 18 }, /* 6108 */ { MAD_F(0x06d08ed5) /* 0.425917465 */, 18 }, /* 6109 */ { MAD_F(0x06d0f053) /* 0.426010443 */, 18 }, /* 6110 */ { MAD_F(0x06d151d3) /* 0.426103425 */, 18 }, /* 6111 */ { MAD_F(0x06d1b354) /* 0.426196412 */, 18 }, /* 6112 */ { MAD_F(0x06d214d7) /* 0.426289405 */, 18 }, /* 6113 */ { MAD_F(0x06d2765a) /* 0.426382403 */, 18 }, /* 6114 */ { MAD_F(0x06d2d7e0) /* 0.426475405 */, 18 }, /* 6115 */ { MAD_F(0x06d33966) /* 0.426568413 */, 18 }, /* 6116 */ { MAD_F(0x06d39aee) /* 0.426661426 */, 18 }, /* 6117 */ { MAD_F(0x06d3fc77) /* 0.426754444 */, 18 }, /* 6118 */ { MAD_F(0x06d45e02) /* 0.426847467 */, 18 }, /* 6119 */ { MAD_F(0x06d4bf8e) /* 0.426940495 */, 18 }, /* 6120 */ { MAD_F(0x06d5211c) /* 0.427033528 */, 18 }, /* 6121 */ { MAD_F(0x06d582aa) /* 0.427126566 */, 18 }, /* 6122 */ { MAD_F(0x06d5e43a) /* 0.427219609 */, 18 }, /* 6123 */ { MAD_F(0x06d645cc) /* 0.427312657 */, 18 }, /* 6124 */ { MAD_F(0x06d6a75f) /* 0.427405711 */, 18 }, /* 6125 */ { MAD_F(0x06d708f3) /* 0.427498769 */, 18 }, /* 6126 */ { MAD_F(0x06d76a88) /* 0.427591833 */, 18 }, /* 6127 */ { MAD_F(0x06d7cc1f) /* 0.427684901 */, 18 }, /* 6128 */ { MAD_F(0x06d82db8) /* 0.427777975 */, 18 }, /* 6129 */ { MAD_F(0x06d88f51) /* 0.427871054 */, 18 }, /* 6130 */ { MAD_F(0x06d8f0ec) /* 0.427964137 */, 18 }, /* 6131 */ { MAD_F(0x06d95288) /* 0.428057226 */, 18 }, /* 6132 */ { MAD_F(0x06d9b426) /* 0.428150320 */, 18 }, /* 6133 */ { MAD_F(0x06da15c5) /* 0.428243419 */, 18 }, /* 6134 */ { MAD_F(0x06da7766) /* 0.428336523 */, 18 }, /* 6135 */ { MAD_F(0x06dad907) /* 0.428429632 */, 18 }, /* 6136 */ { MAD_F(0x06db3aaa) /* 0.428522746 */, 18 }, /* 6137 */ { MAD_F(0x06db9c4f) /* 0.428615865 */, 18 }, /* 6138 */ { MAD_F(0x06dbfdf5) /* 0.428708989 */, 18 }, /* 6139 */ { MAD_F(0x06dc5f9c) /* 0.428802119 */, 18 }, /* 6140 */ { MAD_F(0x06dcc145) /* 0.428895253 */, 18 }, /* 6141 */ { MAD_F(0x06dd22ee) /* 0.428988392 */, 18 }, /* 6142 */ { MAD_F(0x06dd849a) /* 0.429081537 */, 18 }, /* 6143 */ { MAD_F(0x06dde646) /* 0.429174686 */, 18 }, /* 6144 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 18 }, /* 6145 */ { MAD_F(0x06dea9a4) /* 0.429361001 */, 18 }, /* 6146 */ { MAD_F(0x06df0b54) /* 0.429454165 */, 18 }, /* 6147 */ { MAD_F(0x06df6d06) /* 0.429547335 */, 18 }, /* 6148 */ { MAD_F(0x06dfceba) /* 0.429640510 */, 18 }, /* 6149 */ { MAD_F(0x06e0306f) /* 0.429733690 */, 18 }, /* 6150 */ { MAD_F(0x06e09225) /* 0.429826874 */, 18 }, /* 6151 */ { MAD_F(0x06e0f3dc) /* 0.429920064 */, 18 }, /* 6152 */ { MAD_F(0x06e15595) /* 0.430013259 */, 18 }, /* 6153 */ { MAD_F(0x06e1b74f) /* 0.430106459 */, 18 }, /* 6154 */ { MAD_F(0x06e2190b) /* 0.430199664 */, 18 }, /* 6155 */ { MAD_F(0x06e27ac8) /* 0.430292875 */, 18 }, /* 6156 */ { MAD_F(0x06e2dc86) /* 0.430386090 */, 18 }, /* 6157 */ { MAD_F(0x06e33e46) /* 0.430479310 */, 18 }, /* 6158 */ { MAD_F(0x06e3a007) /* 0.430572535 */, 18 }, /* 6159 */ { MAD_F(0x06e401c9) /* 0.430665765 */, 18 }, /* 6160 */ { MAD_F(0x06e4638d) /* 0.430759001 */, 18 }, /* 6161 */ { MAD_F(0x06e4c552) /* 0.430852241 */, 18 }, /* 6162 */ { MAD_F(0x06e52718) /* 0.430945487 */, 18 }, /* 6163 */ { MAD_F(0x06e588e0) /* 0.431038737 */, 18 }, /* 6164 */ { MAD_F(0x06e5eaa9) /* 0.431131993 */, 18 }, /* 6165 */ { MAD_F(0x06e64c73) /* 0.431225253 */, 18 }, /* 6166 */ { MAD_F(0x06e6ae3f) /* 0.431318519 */, 18 }, /* 6167 */ { MAD_F(0x06e7100c) /* 0.431411790 */, 18 }, /* 6168 */ { MAD_F(0x06e771db) /* 0.431505065 */, 18 }, /* 6169 */ { MAD_F(0x06e7d3ab) /* 0.431598346 */, 18 }, /* 6170 */ { MAD_F(0x06e8357c) /* 0.431691632 */, 18 }, /* 6171 */ { MAD_F(0x06e8974e) /* 0.431784923 */, 18 }, /* 6172 */ { MAD_F(0x06e8f922) /* 0.431878218 */, 18 }, /* 6173 */ { MAD_F(0x06e95af8) /* 0.431971519 */, 18 }, /* 6174 */ { MAD_F(0x06e9bcce) /* 0.432064825 */, 18 }, /* 6175 */ { MAD_F(0x06ea1ea6) /* 0.432158136 */, 18 }, /* 6176 */ { MAD_F(0x06ea807f) /* 0.432251452 */, 18 }, /* 6177 */ { MAD_F(0x06eae25a) /* 0.432344773 */, 18 }, /* 6178 */ { MAD_F(0x06eb4436) /* 0.432438099 */, 18 }, /* 6179 */ { MAD_F(0x06eba614) /* 0.432531431 */, 18 }, /* 6180 */ { MAD_F(0x06ec07f2) /* 0.432624767 */, 18 }, /* 6181 */ { MAD_F(0x06ec69d2) /* 0.432718108 */, 18 }, /* 6182 */ { MAD_F(0x06eccbb4) /* 0.432811454 */, 18 }, /* 6183 */ { MAD_F(0x06ed2d97) /* 0.432904805 */, 18 }, /* 6184 */ { MAD_F(0x06ed8f7b) /* 0.432998162 */, 18 }, /* 6185 */ { MAD_F(0x06edf160) /* 0.433091523 */, 18 }, /* 6186 */ { MAD_F(0x06ee5347) /* 0.433184889 */, 18 }, /* 6187 */ { MAD_F(0x06eeb52f) /* 0.433278261 */, 18 }, /* 6188 */ { MAD_F(0x06ef1719) /* 0.433371637 */, 18 }, /* 6189 */ { MAD_F(0x06ef7904) /* 0.433465019 */, 18 }, /* 6190 */ { MAD_F(0x06efdaf0) /* 0.433558405 */, 18 }, /* 6191 */ { MAD_F(0x06f03cde) /* 0.433651797 */, 18 }, /* 6192 */ { MAD_F(0x06f09ecc) /* 0.433745193 */, 18 }, /* 6193 */ { MAD_F(0x06f100bd) /* 0.433838595 */, 18 }, /* 6194 */ { MAD_F(0x06f162ae) /* 0.433932001 */, 18 }, /* 6195 */ { MAD_F(0x06f1c4a1) /* 0.434025413 */, 18 }, /* 6196 */ { MAD_F(0x06f22696) /* 0.434118830 */, 18 }, /* 6197 */ { MAD_F(0x06f2888b) /* 0.434212251 */, 18 }, /* 6198 */ { MAD_F(0x06f2ea82) /* 0.434305678 */, 18 }, /* 6199 */ { MAD_F(0x06f34c7b) /* 0.434399110 */, 18 }, /* 6200 */ { MAD_F(0x06f3ae75) /* 0.434492546 */, 18 }, /* 6201 */ { MAD_F(0x06f41070) /* 0.434585988 */, 18 }, /* 6202 */ { MAD_F(0x06f4726c) /* 0.434679435 */, 18 }, /* 6203 */ { MAD_F(0x06f4d46a) /* 0.434772887 */, 18 }, /* 6204 */ { MAD_F(0x06f53669) /* 0.434866344 */, 18 }, /* 6205 */ { MAD_F(0x06f59869) /* 0.434959806 */, 18 }, /* 6206 */ { MAD_F(0x06f5fa6b) /* 0.435053272 */, 18 }, /* 6207 */ { MAD_F(0x06f65c6e) /* 0.435146744 */, 18 }, /* 6208 */ { MAD_F(0x06f6be73) /* 0.435240221 */, 18 }, /* 6209 */ { MAD_F(0x06f72079) /* 0.435333703 */, 18 }, /* 6210 */ { MAD_F(0x06f78280) /* 0.435427190 */, 18 }, /* 6211 */ { MAD_F(0x06f7e489) /* 0.435520682 */, 18 }, /* 6212 */ { MAD_F(0x06f84693) /* 0.435614179 */, 18 }, /* 6213 */ { MAD_F(0x06f8a89e) /* 0.435707681 */, 18 }, /* 6214 */ { MAD_F(0x06f90aaa) /* 0.435801188 */, 18 }, /* 6215 */ { MAD_F(0x06f96cb8) /* 0.435894700 */, 18 }, /* 6216 */ { MAD_F(0x06f9cec8) /* 0.435988217 */, 18 }, /* 6217 */ { MAD_F(0x06fa30d8) /* 0.436081739 */, 18 }, /* 6218 */ { MAD_F(0x06fa92ea) /* 0.436175266 */, 18 }, /* 6219 */ { MAD_F(0x06faf4fe) /* 0.436268799 */, 18 }, /* 6220 */ { MAD_F(0x06fb5712) /* 0.436362336 */, 18 }, /* 6221 */ { MAD_F(0x06fbb928) /* 0.436455878 */, 18 }, /* 6222 */ { MAD_F(0x06fc1b40) /* 0.436549425 */, 18 }, /* 6223 */ { MAD_F(0x06fc7d58) /* 0.436642977 */, 18 }, /* 6224 */ { MAD_F(0x06fcdf72) /* 0.436736534 */, 18 }, /* 6225 */ { MAD_F(0x06fd418e) /* 0.436830096 */, 18 }, /* 6226 */ { MAD_F(0x06fda3ab) /* 0.436923664 */, 18 }, /* 6227 */ { MAD_F(0x06fe05c9) /* 0.437017236 */, 18 }, /* 6228 */ { MAD_F(0x06fe67e8) /* 0.437110813 */, 18 }, /* 6229 */ { MAD_F(0x06feca09) /* 0.437204395 */, 18 }, /* 6230 */ { MAD_F(0x06ff2c2b) /* 0.437297982 */, 18 }, /* 6231 */ { MAD_F(0x06ff8e4f) /* 0.437391575 */, 18 }, /* 6232 */ { MAD_F(0x06fff073) /* 0.437485172 */, 18 }, /* 6233 */ { MAD_F(0x0700529a) /* 0.437578774 */, 18 }, /* 6234 */ { MAD_F(0x0700b4c1) /* 0.437672381 */, 18 }, /* 6235 */ { MAD_F(0x070116ea) /* 0.437765994 */, 18 }, /* 6236 */ { MAD_F(0x07017914) /* 0.437859611 */, 18 }, /* 6237 */ { MAD_F(0x0701db40) /* 0.437953233 */, 18 }, /* 6238 */ { MAD_F(0x07023d6c) /* 0.438046860 */, 18 }, /* 6239 */ { MAD_F(0x07029f9b) /* 0.438140493 */, 18 }, /* 6240 */ { MAD_F(0x070301ca) /* 0.438234130 */, 18 }, /* 6241 */ { MAD_F(0x070363fb) /* 0.438327772 */, 18 }, /* 6242 */ { MAD_F(0x0703c62d) /* 0.438421419 */, 18 }, /* 6243 */ { MAD_F(0x07042861) /* 0.438515072 */, 18 }, /* 6244 */ { MAD_F(0x07048a96) /* 0.438608729 */, 18 }, /* 6245 */ { MAD_F(0x0704eccc) /* 0.438702391 */, 18 }, /* 6246 */ { MAD_F(0x07054f04) /* 0.438796059 */, 18 }, /* 6247 */ { MAD_F(0x0705b13d) /* 0.438889731 */, 18 }, /* 6248 */ { MAD_F(0x07061377) /* 0.438983408 */, 18 }, /* 6249 */ { MAD_F(0x070675b3) /* 0.439077090 */, 18 }, /* 6250 */ { MAD_F(0x0706d7f0) /* 0.439170778 */, 18 }, /* 6251 */ { MAD_F(0x07073a2e) /* 0.439264470 */, 18 }, /* 6252 */ { MAD_F(0x07079c6e) /* 0.439358167 */, 18 }, /* 6253 */ { MAD_F(0x0707feaf) /* 0.439451869 */, 18 }, /* 6254 */ { MAD_F(0x070860f1) /* 0.439545577 */, 18 }, /* 6255 */ { MAD_F(0x0708c335) /* 0.439639289 */, 18 }, /* 6256 */ { MAD_F(0x0709257a) /* 0.439733006 */, 18 }, /* 6257 */ { MAD_F(0x070987c0) /* 0.439826728 */, 18 }, /* 6258 */ { MAD_F(0x0709ea08) /* 0.439920456 */, 18 }, /* 6259 */ { MAD_F(0x070a4c51) /* 0.440014188 */, 18 }, /* 6260 */ { MAD_F(0x070aae9b) /* 0.440107925 */, 18 }, /* 6261 */ { MAD_F(0x070b10e7) /* 0.440201667 */, 18 }, /* 6262 */ { MAD_F(0x070b7334) /* 0.440295414 */, 18 }, /* 6263 */ { MAD_F(0x070bd583) /* 0.440389167 */, 18 }, /* 6264 */ { MAD_F(0x070c37d2) /* 0.440482924 */, 18 }, /* 6265 */ { MAD_F(0x070c9a23) /* 0.440576686 */, 18 }, /* 6266 */ { MAD_F(0x070cfc76) /* 0.440670453 */, 18 }, /* 6267 */ { MAD_F(0x070d5eca) /* 0.440764225 */, 18 }, /* 6268 */ { MAD_F(0x070dc11f) /* 0.440858002 */, 18 }, /* 6269 */ { MAD_F(0x070e2375) /* 0.440951784 */, 18 }, /* 6270 */ { MAD_F(0x070e85cd) /* 0.441045572 */, 18 }, /* 6271 */ { MAD_F(0x070ee826) /* 0.441139364 */, 18 }, /* 6272 */ { MAD_F(0x070f4a80) /* 0.441233161 */, 18 }, /* 6273 */ { MAD_F(0x070facdc) /* 0.441326963 */, 18 }, /* 6274 */ { MAD_F(0x07100f39) /* 0.441420770 */, 18 }, /* 6275 */ { MAD_F(0x07107198) /* 0.441514582 */, 18 }, /* 6276 */ { MAD_F(0x0710d3f8) /* 0.441608399 */, 18 }, /* 6277 */ { MAD_F(0x07113659) /* 0.441702221 */, 18 }, /* 6278 */ { MAD_F(0x071198bb) /* 0.441796048 */, 18 }, /* 6279 */ { MAD_F(0x0711fb1f) /* 0.441889880 */, 18 }, /* 6280 */ { MAD_F(0x07125d84) /* 0.441983717 */, 18 }, /* 6281 */ { MAD_F(0x0712bfeb) /* 0.442077559 */, 18 }, /* 6282 */ { MAD_F(0x07132253) /* 0.442171406 */, 18 }, /* 6283 */ { MAD_F(0x071384bc) /* 0.442265257 */, 18 }, /* 6284 */ { MAD_F(0x0713e726) /* 0.442359114 */, 18 }, /* 6285 */ { MAD_F(0x07144992) /* 0.442452976 */, 18 }, /* 6286 */ { MAD_F(0x0714abff) /* 0.442546843 */, 18 }, /* 6287 */ { MAD_F(0x07150e6e) /* 0.442640715 */, 18 }, /* 6288 */ { MAD_F(0x071570de) /* 0.442734592 */, 18 }, /* 6289 */ { MAD_F(0x0715d34f) /* 0.442828473 */, 18 }, /* 6290 */ { MAD_F(0x071635c1) /* 0.442922360 */, 18 }, /* 6291 */ { MAD_F(0x07169835) /* 0.443016252 */, 18 }, /* 6292 */ { MAD_F(0x0716faaa) /* 0.443110148 */, 18 }, /* 6293 */ { MAD_F(0x07175d21) /* 0.443204050 */, 18 }, /* 6294 */ { MAD_F(0x0717bf99) /* 0.443297957 */, 18 }, /* 6295 */ { MAD_F(0x07182212) /* 0.443391868 */, 18 }, /* 6296 */ { MAD_F(0x0718848d) /* 0.443485785 */, 18 }, /* 6297 */ { MAD_F(0x0718e709) /* 0.443579706 */, 18 }, /* 6298 */ { MAD_F(0x07194986) /* 0.443673633 */, 18 }, /* 6299 */ { MAD_F(0x0719ac04) /* 0.443767564 */, 18 }, /* 6300 */ { MAD_F(0x071a0e84) /* 0.443861501 */, 18 }, /* 6301 */ { MAD_F(0x071a7105) /* 0.443955442 */, 18 }, /* 6302 */ { MAD_F(0x071ad388) /* 0.444049389 */, 18 }, /* 6303 */ { MAD_F(0x071b360c) /* 0.444143340 */, 18 }, /* 6304 */ { MAD_F(0x071b9891) /* 0.444237296 */, 18 }, /* 6305 */ { MAD_F(0x071bfb18) /* 0.444331258 */, 18 }, /* 6306 */ { MAD_F(0x071c5d9f) /* 0.444425224 */, 18 }, /* 6307 */ { MAD_F(0x071cc029) /* 0.444519195 */, 18 }, /* 6308 */ { MAD_F(0x071d22b3) /* 0.444613171 */, 18 }, /* 6309 */ { MAD_F(0x071d853f) /* 0.444707153 */, 18 }, /* 6310 */ { MAD_F(0x071de7cc) /* 0.444801139 */, 18 }, /* 6311 */ { MAD_F(0x071e4a5b) /* 0.444895130 */, 18 }, /* 6312 */ { MAD_F(0x071eaceb) /* 0.444989126 */, 18 }, /* 6313 */ { MAD_F(0x071f0f7c) /* 0.445083127 */, 18 }, /* 6314 */ { MAD_F(0x071f720e) /* 0.445177133 */, 18 }, /* 6315 */ { MAD_F(0x071fd4a2) /* 0.445271144 */, 18 }, /* 6316 */ { MAD_F(0x07203737) /* 0.445365160 */, 18 }, /* 6317 */ { MAD_F(0x072099ce) /* 0.445459181 */, 18 }, /* 6318 */ { MAD_F(0x0720fc66) /* 0.445553206 */, 18 }, /* 6319 */ { MAD_F(0x07215eff) /* 0.445647237 */, 18 }, /* 6320 */ { MAD_F(0x0721c19a) /* 0.445741273 */, 18 }, /* 6321 */ { MAD_F(0x07222436) /* 0.445835314 */, 18 }, /* 6322 */ { MAD_F(0x072286d3) /* 0.445929359 */, 18 }, /* 6323 */ { MAD_F(0x0722e971) /* 0.446023410 */, 18 }, /* 6324 */ { MAD_F(0x07234c11) /* 0.446117466 */, 18 }, /* 6325 */ { MAD_F(0x0723aeb2) /* 0.446211526 */, 18 }, /* 6326 */ { MAD_F(0x07241155) /* 0.446305592 */, 18 }, /* 6327 */ { MAD_F(0x072473f9) /* 0.446399662 */, 18 }, /* 6328 */ { MAD_F(0x0724d69e) /* 0.446493738 */, 18 }, /* 6329 */ { MAD_F(0x07253944) /* 0.446587818 */, 18 }, /* 6330 */ { MAD_F(0x07259bec) /* 0.446681903 */, 18 }, /* 6331 */ { MAD_F(0x0725fe95) /* 0.446775994 */, 18 }, /* 6332 */ { MAD_F(0x07266140) /* 0.446870089 */, 18 }, /* 6333 */ { MAD_F(0x0726c3ec) /* 0.446964189 */, 18 }, /* 6334 */ { MAD_F(0x07272699) /* 0.447058294 */, 18 }, /* 6335 */ { MAD_F(0x07278947) /* 0.447152404 */, 18 }, /* 6336 */ { MAD_F(0x0727ebf7) /* 0.447246519 */, 18 }, /* 6337 */ { MAD_F(0x07284ea8) /* 0.447340639 */, 18 }, /* 6338 */ { MAD_F(0x0728b15b) /* 0.447434764 */, 18 }, /* 6339 */ { MAD_F(0x0729140f) /* 0.447528894 */, 18 }, /* 6340 */ { MAD_F(0x072976c4) /* 0.447623029 */, 18 }, /* 6341 */ { MAD_F(0x0729d97a) /* 0.447717169 */, 18 }, /* 6342 */ { MAD_F(0x072a3c32) /* 0.447811314 */, 18 }, /* 6343 */ { MAD_F(0x072a9eeb) /* 0.447905463 */, 18 }, /* 6344 */ { MAD_F(0x072b01a6) /* 0.447999618 */, 18 }, /* 6345 */ { MAD_F(0x072b6461) /* 0.448093778 */, 18 }, /* 6346 */ { MAD_F(0x072bc71e) /* 0.448187942 */, 18 }, /* 6347 */ { MAD_F(0x072c29dd) /* 0.448282112 */, 18 }, /* 6348 */ { MAD_F(0x072c8c9d) /* 0.448376286 */, 18 }, /* 6349 */ { MAD_F(0x072cef5e) /* 0.448470466 */, 18 }, /* 6350 */ { MAD_F(0x072d5220) /* 0.448564650 */, 18 }, /* 6351 */ { MAD_F(0x072db4e4) /* 0.448658839 */, 18 }, /* 6352 */ { MAD_F(0x072e17a9) /* 0.448753033 */, 18 }, /* 6353 */ { MAD_F(0x072e7a6f) /* 0.448847233 */, 18 }, /* 6354 */ { MAD_F(0x072edd37) /* 0.448941437 */, 18 }, /* 6355 */ { MAD_F(0x072f4000) /* 0.449035646 */, 18 }, /* 6356 */ { MAD_F(0x072fa2ca) /* 0.449129860 */, 18 }, /* 6357 */ { MAD_F(0x07300596) /* 0.449224079 */, 18 }, /* 6358 */ { MAD_F(0x07306863) /* 0.449318303 */, 18 }, /* 6359 */ { MAD_F(0x0730cb32) /* 0.449412531 */, 18 }, /* 6360 */ { MAD_F(0x07312e01) /* 0.449506765 */, 18 }, /* 6361 */ { MAD_F(0x073190d2) /* 0.449601004 */, 18 }, /* 6362 */ { MAD_F(0x0731f3a5) /* 0.449695247 */, 18 }, /* 6363 */ { MAD_F(0x07325678) /* 0.449789496 */, 18 }, /* 6364 */ { MAD_F(0x0732b94d) /* 0.449883749 */, 18 }, /* 6365 */ { MAD_F(0x07331c23) /* 0.449978008 */, 18 }, /* 6366 */ { MAD_F(0x07337efb) /* 0.450072271 */, 18 }, /* 6367 */ { MAD_F(0x0733e1d4) /* 0.450166540 */, 18 }, /* 6368 */ { MAD_F(0x073444ae) /* 0.450260813 */, 18 }, /* 6369 */ { MAD_F(0x0734a78a) /* 0.450355091 */, 18 }, /* 6370 */ { MAD_F(0x07350a67) /* 0.450449374 */, 18 }, /* 6371 */ { MAD_F(0x07356d45) /* 0.450543662 */, 18 }, /* 6372 */ { MAD_F(0x0735d025) /* 0.450637955 */, 18 }, /* 6373 */ { MAD_F(0x07363306) /* 0.450732253 */, 18 }, /* 6374 */ { MAD_F(0x073695e8) /* 0.450826556 */, 18 }, /* 6375 */ { MAD_F(0x0736f8cb) /* 0.450920864 */, 18 }, /* 6376 */ { MAD_F(0x07375bb0) /* 0.451015176 */, 18 }, /* 6377 */ { MAD_F(0x0737be96) /* 0.451109494 */, 18 }, /* 6378 */ { MAD_F(0x0738217e) /* 0.451203817 */, 18 }, /* 6379 */ { MAD_F(0x07388467) /* 0.451298144 */, 18 }, /* 6380 */ { MAD_F(0x0738e751) /* 0.451392477 */, 18 }, /* 6381 */ { MAD_F(0x07394a3d) /* 0.451486814 */, 18 }, /* 6382 */ { MAD_F(0x0739ad29) /* 0.451581156 */, 18 }, /* 6383 */ { MAD_F(0x073a1017) /* 0.451675503 */, 18 }, /* 6384 */ { MAD_F(0x073a7307) /* 0.451769856 */, 18 }, /* 6385 */ { MAD_F(0x073ad5f8) /* 0.451864213 */, 18 }, /* 6386 */ { MAD_F(0x073b38ea) /* 0.451958575 */, 18 }, /* 6387 */ { MAD_F(0x073b9bdd) /* 0.452052942 */, 18 }, /* 6388 */ { MAD_F(0x073bfed2) /* 0.452147313 */, 18 }, /* 6389 */ { MAD_F(0x073c61c8) /* 0.452241690 */, 18 }, /* 6390 */ { MAD_F(0x073cc4bf) /* 0.452336072 */, 18 }, /* 6391 */ { MAD_F(0x073d27b8) /* 0.452430458 */, 18 }, /* 6392 */ { MAD_F(0x073d8ab2) /* 0.452524850 */, 18 }, /* 6393 */ { MAD_F(0x073dedae) /* 0.452619246 */, 18 }, /* 6394 */ { MAD_F(0x073e50aa) /* 0.452713648 */, 18 }, /* 6395 */ { MAD_F(0x073eb3a8) /* 0.452808054 */, 18 }, /* 6396 */ { MAD_F(0x073f16a8) /* 0.452902465 */, 18 }, /* 6397 */ { MAD_F(0x073f79a8) /* 0.452996882 */, 18 }, /* 6398 */ { MAD_F(0x073fdcaa) /* 0.453091303 */, 18 }, /* 6399 */ { MAD_F(0x07403fad) /* 0.453185729 */, 18 }, /* 6400 */ { MAD_F(0x0740a2b2) /* 0.453280160 */, 18 }, /* 6401 */ { MAD_F(0x074105b8) /* 0.453374595 */, 18 }, /* 6402 */ { MAD_F(0x074168bf) /* 0.453469036 */, 18 }, /* 6403 */ { MAD_F(0x0741cbc8) /* 0.453563482 */, 18 }, /* 6404 */ { MAD_F(0x07422ed2) /* 0.453657932 */, 18 }, /* 6405 */ { MAD_F(0x074291dd) /* 0.453752388 */, 18 }, /* 6406 */ { MAD_F(0x0742f4e9) /* 0.453846848 */, 18 }, /* 6407 */ { MAD_F(0x074357f7) /* 0.453941314 */, 18 }, /* 6408 */ { MAD_F(0x0743bb06) /* 0.454035784 */, 18 }, /* 6409 */ { MAD_F(0x07441e17) /* 0.454130259 */, 18 }, /* 6410 */ { MAD_F(0x07448129) /* 0.454224739 */, 18 }, /* 6411 */ { MAD_F(0x0744e43c) /* 0.454319224 */, 18 }, /* 6412 */ { MAD_F(0x07454750) /* 0.454413714 */, 18 }, /* 6413 */ { MAD_F(0x0745aa66) /* 0.454508209 */, 18 }, /* 6414 */ { MAD_F(0x07460d7d) /* 0.454602708 */, 18 }, /* 6415 */ { MAD_F(0x07467095) /* 0.454697213 */, 18 }, /* 6416 */ { MAD_F(0x0746d3af) /* 0.454791723 */, 18 }, /* 6417 */ { MAD_F(0x074736ca) /* 0.454886237 */, 18 }, /* 6418 */ { MAD_F(0x074799e7) /* 0.454980756 */, 18 }, /* 6419 */ { MAD_F(0x0747fd04) /* 0.455075281 */, 18 }, /* 6420 */ { MAD_F(0x07486023) /* 0.455169810 */, 18 }, /* 6421 */ { MAD_F(0x0748c344) /* 0.455264344 */, 18 }, /* 6422 */ { MAD_F(0x07492665) /* 0.455358883 */, 18 }, /* 6423 */ { MAD_F(0x07498988) /* 0.455453427 */, 18 }, /* 6424 */ { MAD_F(0x0749ecac) /* 0.455547976 */, 18 }, /* 6425 */ { MAD_F(0x074a4fd2) /* 0.455642529 */, 18 }, /* 6426 */ { MAD_F(0x074ab2f9) /* 0.455737088 */, 18 }, /* 6427 */ { MAD_F(0x074b1621) /* 0.455831652 */, 18 }, /* 6428 */ { MAD_F(0x074b794b) /* 0.455926220 */, 18 }, /* 6429 */ { MAD_F(0x074bdc75) /* 0.456020793 */, 18 }, /* 6430 */ { MAD_F(0x074c3fa1) /* 0.456115372 */, 18 }, /* 6431 */ { MAD_F(0x074ca2cf) /* 0.456209955 */, 18 }, /* 6432 */ { MAD_F(0x074d05fe) /* 0.456304543 */, 18 }, /* 6433 */ { MAD_F(0x074d692e) /* 0.456399136 */, 18 }, /* 6434 */ { MAD_F(0x074dcc5f) /* 0.456493733 */, 18 }, /* 6435 */ { MAD_F(0x074e2f92) /* 0.456588336 */, 18 }, /* 6436 */ { MAD_F(0x074e92c6) /* 0.456682944 */, 18 }, /* 6437 */ { MAD_F(0x074ef5fb) /* 0.456777556 */, 18 }, /* 6438 */ { MAD_F(0x074f5932) /* 0.456872174 */, 18 }, /* 6439 */ { MAD_F(0x074fbc6a) /* 0.456966796 */, 18 }, /* 6440 */ { MAD_F(0x07501fa3) /* 0.457061423 */, 18 }, /* 6441 */ { MAD_F(0x075082de) /* 0.457156056 */, 18 }, /* 6442 */ { MAD_F(0x0750e61a) /* 0.457250693 */, 18 }, /* 6443 */ { MAD_F(0x07514957) /* 0.457345335 */, 18 }, /* 6444 */ { MAD_F(0x0751ac96) /* 0.457439981 */, 18 }, /* 6445 */ { MAD_F(0x07520fd6) /* 0.457534633 */, 18 }, /* 6446 */ { MAD_F(0x07527317) /* 0.457629290 */, 18 }, /* 6447 */ { MAD_F(0x0752d659) /* 0.457723951 */, 18 }, /* 6448 */ { MAD_F(0x0753399d) /* 0.457818618 */, 18 }, /* 6449 */ { MAD_F(0x07539ce2) /* 0.457913289 */, 18 }, /* 6450 */ { MAD_F(0x07540029) /* 0.458007965 */, 18 }, /* 6451 */ { MAD_F(0x07546371) /* 0.458102646 */, 18 }, /* 6452 */ { MAD_F(0x0754c6ba) /* 0.458197332 */, 18 }, /* 6453 */ { MAD_F(0x07552a04) /* 0.458292023 */, 18 }, /* 6454 */ { MAD_F(0x07558d50) /* 0.458386719 */, 18 }, /* 6455 */ { MAD_F(0x0755f09d) /* 0.458481420 */, 18 }, /* 6456 */ { MAD_F(0x075653eb) /* 0.458576125 */, 18 }, /* 6457 */ { MAD_F(0x0756b73b) /* 0.458670836 */, 18 }, /* 6458 */ { MAD_F(0x07571a8c) /* 0.458765551 */, 18 }, /* 6459 */ { MAD_F(0x07577dde) /* 0.458860271 */, 18 }, /* 6460 */ { MAD_F(0x0757e131) /* 0.458954996 */, 18 }, /* 6461 */ { MAD_F(0x07584486) /* 0.459049726 */, 18 }, /* 6462 */ { MAD_F(0x0758a7dd) /* 0.459144461 */, 18 }, /* 6463 */ { MAD_F(0x07590b34) /* 0.459239201 */, 18 }, /* 6464 */ { MAD_F(0x07596e8d) /* 0.459333946 */, 18 }, /* 6465 */ { MAD_F(0x0759d1e7) /* 0.459428695 */, 18 }, /* 6466 */ { MAD_F(0x075a3542) /* 0.459523450 */, 18 }, /* 6467 */ { MAD_F(0x075a989f) /* 0.459618209 */, 18 }, /* 6468 */ { MAD_F(0x075afbfd) /* 0.459712973 */, 18 }, /* 6469 */ { MAD_F(0x075b5f5d) /* 0.459807742 */, 18 }, /* 6470 */ { MAD_F(0x075bc2bd) /* 0.459902516 */, 18 }, /* 6471 */ { MAD_F(0x075c261f) /* 0.459997295 */, 18 }, /* 6472 */ { MAD_F(0x075c8983) /* 0.460092079 */, 18 }, /* 6473 */ { MAD_F(0x075cece7) /* 0.460186867 */, 18 }, /* 6474 */ { MAD_F(0x075d504d) /* 0.460281661 */, 18 }, /* 6475 */ { MAD_F(0x075db3b5) /* 0.460376459 */, 18 }, /* 6476 */ { MAD_F(0x075e171d) /* 0.460471262 */, 18 }, /* 6477 */ { MAD_F(0x075e7a87) /* 0.460566071 */, 18 }, /* 6478 */ { MAD_F(0x075eddf2) /* 0.460660884 */, 18 }, /* 6479 */ { MAD_F(0x075f415f) /* 0.460755701 */, 18 }, /* 6480 */ { MAD_F(0x075fa4cc) /* 0.460850524 */, 18 }, /* 6481 */ { MAD_F(0x0760083b) /* 0.460945352 */, 18 }, /* 6482 */ { MAD_F(0x07606bac) /* 0.461040184 */, 18 }, /* 6483 */ { MAD_F(0x0760cf1e) /* 0.461135022 */, 18 }, /* 6484 */ { MAD_F(0x07613291) /* 0.461229864 */, 18 }, /* 6485 */ { MAD_F(0x07619605) /* 0.461324711 */, 18 }, /* 6486 */ { MAD_F(0x0761f97b) /* 0.461419563 */, 18 }, /* 6487 */ { MAD_F(0x07625cf2) /* 0.461514420 */, 18 }, /* 6488 */ { MAD_F(0x0762c06a) /* 0.461609282 */, 18 }, /* 6489 */ { MAD_F(0x076323e3) /* 0.461704149 */, 18 }, /* 6490 */ { MAD_F(0x0763875e) /* 0.461799020 */, 18 }, /* 6491 */ { MAD_F(0x0763eadb) /* 0.461893897 */, 18 }, /* 6492 */ { MAD_F(0x07644e58) /* 0.461988778 */, 18 }, /* 6493 */ { MAD_F(0x0764b1d7) /* 0.462083664 */, 18 }, /* 6494 */ { MAD_F(0x07651557) /* 0.462178555 */, 18 }, /* 6495 */ { MAD_F(0x076578d8) /* 0.462273451 */, 18 }, /* 6496 */ { MAD_F(0x0765dc5b) /* 0.462368352 */, 18 }, /* 6497 */ { MAD_F(0x07663fdf) /* 0.462463257 */, 18 }, /* 6498 */ { MAD_F(0x0766a364) /* 0.462558168 */, 18 }, /* 6499 */ { MAD_F(0x076706eb) /* 0.462653083 */, 18 }, /* 6500 */ { MAD_F(0x07676a73) /* 0.462748003 */, 18 }, /* 6501 */ { MAD_F(0x0767cdfc) /* 0.462842928 */, 18 }, /* 6502 */ { MAD_F(0x07683187) /* 0.462937858 */, 18 }, /* 6503 */ { MAD_F(0x07689513) /* 0.463032793 */, 18 }, /* 6504 */ { MAD_F(0x0768f8a0) /* 0.463127733 */, 18 }, /* 6505 */ { MAD_F(0x07695c2e) /* 0.463222678 */, 18 }, /* 6506 */ { MAD_F(0x0769bfbe) /* 0.463317627 */, 18 }, /* 6507 */ { MAD_F(0x076a234f) /* 0.463412581 */, 18 }, /* 6508 */ { MAD_F(0x076a86e2) /* 0.463507540 */, 18 }, /* 6509 */ { MAD_F(0x076aea75) /* 0.463602504 */, 18 }, /* 6510 */ { MAD_F(0x076b4e0a) /* 0.463697473 */, 18 }, /* 6511 */ { MAD_F(0x076bb1a1) /* 0.463792447 */, 18 }, /* 6512 */ { MAD_F(0x076c1538) /* 0.463887426 */, 18 }, /* 6513 */ { MAD_F(0x076c78d1) /* 0.463982409 */, 18 }, /* 6514 */ { MAD_F(0x076cdc6c) /* 0.464077398 */, 18 }, /* 6515 */ { MAD_F(0x076d4007) /* 0.464172391 */, 18 }, /* 6516 */ { MAD_F(0x076da3a4) /* 0.464267389 */, 18 }, /* 6517 */ { MAD_F(0x076e0742) /* 0.464362392 */, 18 }, /* 6518 */ { MAD_F(0x076e6ae2) /* 0.464457399 */, 18 }, /* 6519 */ { MAD_F(0x076ece82) /* 0.464552412 */, 18 }, /* 6520 */ { MAD_F(0x076f3224) /* 0.464647430 */, 18 }, /* 6521 */ { MAD_F(0x076f95c8) /* 0.464742452 */, 18 }, /* 6522 */ { MAD_F(0x076ff96c) /* 0.464837479 */, 18 }, /* 6523 */ { MAD_F(0x07705d12) /* 0.464932511 */, 18 }, /* 6524 */ { MAD_F(0x0770c0ba) /* 0.465027548 */, 18 }, /* 6525 */ { MAD_F(0x07712462) /* 0.465122590 */, 18 }, /* 6526 */ { MAD_F(0x0771880c) /* 0.465217637 */, 18 }, /* 6527 */ { MAD_F(0x0771ebb7) /* 0.465312688 */, 18 }, /* 6528 */ { MAD_F(0x07724f64) /* 0.465407744 */, 18 }, /* 6529 */ { MAD_F(0x0772b312) /* 0.465502806 */, 18 }, /* 6530 */ { MAD_F(0x077316c1) /* 0.465597872 */, 18 }, /* 6531 */ { MAD_F(0x07737a71) /* 0.465692943 */, 18 }, /* 6532 */ { MAD_F(0x0773de23) /* 0.465788018 */, 18 }, /* 6533 */ { MAD_F(0x077441d6) /* 0.465883099 */, 18 }, /* 6534 */ { MAD_F(0x0774a58a) /* 0.465978184 */, 18 }, /* 6535 */ { MAD_F(0x07750940) /* 0.466073275 */, 18 }, /* 6536 */ { MAD_F(0x07756cf7) /* 0.466168370 */, 18 }, /* 6537 */ { MAD_F(0x0775d0af) /* 0.466263470 */, 18 }, /* 6538 */ { MAD_F(0x07763468) /* 0.466358575 */, 18 }, /* 6539 */ { MAD_F(0x07769823) /* 0.466453684 */, 18 }, /* 6540 */ { MAD_F(0x0776fbdf) /* 0.466548799 */, 18 }, /* 6541 */ { MAD_F(0x07775f9d) /* 0.466643918 */, 18 }, /* 6542 */ { MAD_F(0x0777c35c) /* 0.466739043 */, 18 }, /* 6543 */ { MAD_F(0x0778271c) /* 0.466834172 */, 18 }, /* 6544 */ { MAD_F(0x07788add) /* 0.466929306 */, 18 }, /* 6545 */ { MAD_F(0x0778ee9f) /* 0.467024445 */, 18 }, /* 6546 */ { MAD_F(0x07795263) /* 0.467119588 */, 18 }, /* 6547 */ { MAD_F(0x0779b629) /* 0.467214737 */, 18 }, /* 6548 */ { MAD_F(0x077a19ef) /* 0.467309890 */, 18 }, /* 6549 */ { MAD_F(0x077a7db7) /* 0.467405048 */, 18 }, /* 6550 */ { MAD_F(0x077ae180) /* 0.467500211 */, 18 }, /* 6551 */ { MAD_F(0x077b454b) /* 0.467595379 */, 18 }, /* 6552 */ { MAD_F(0x077ba916) /* 0.467690552 */, 18 }, /* 6553 */ { MAD_F(0x077c0ce3) /* 0.467785729 */, 18 }, /* 6554 */ { MAD_F(0x077c70b2) /* 0.467880912 */, 18 }, /* 6555 */ { MAD_F(0x077cd481) /* 0.467976099 */, 18 }, /* 6556 */ { MAD_F(0x077d3852) /* 0.468071291 */, 18 }, /* 6557 */ { MAD_F(0x077d9c24) /* 0.468166488 */, 18 }, /* 6558 */ { MAD_F(0x077dfff8) /* 0.468261690 */, 18 }, /* 6559 */ { MAD_F(0x077e63cd) /* 0.468356896 */, 18 }, /* 6560 */ { MAD_F(0x077ec7a3) /* 0.468452108 */, 18 }, /* 6561 */ { MAD_F(0x077f2b7a) /* 0.468547324 */, 18 }, /* 6562 */ { MAD_F(0x077f8f53) /* 0.468642545 */, 18 }, /* 6563 */ { MAD_F(0x077ff32d) /* 0.468737771 */, 18 }, /* 6564 */ { MAD_F(0x07805708) /* 0.468833002 */, 18 }, /* 6565 */ { MAD_F(0x0780bae5) /* 0.468928237 */, 18 }, /* 6566 */ { MAD_F(0x07811ec3) /* 0.469023478 */, 18 }, /* 6567 */ { MAD_F(0x078182a2) /* 0.469118723 */, 18 }, /* 6568 */ { MAD_F(0x0781e683) /* 0.469213973 */, 18 }, /* 6569 */ { MAD_F(0x07824a64) /* 0.469309228 */, 18 }, /* 6570 */ { MAD_F(0x0782ae47) /* 0.469404488 */, 18 }, /* 6571 */ { MAD_F(0x0783122c) /* 0.469499752 */, 18 }, /* 6572 */ { MAD_F(0x07837612) /* 0.469595022 */, 18 }, /* 6573 */ { MAD_F(0x0783d9f9) /* 0.469690296 */, 18 }, /* 6574 */ { MAD_F(0x07843de1) /* 0.469785575 */, 18 }, /* 6575 */ { MAD_F(0x0784a1ca) /* 0.469880859 */, 18 }, /* 6576 */ { MAD_F(0x078505b5) /* 0.469976148 */, 18 }, /* 6577 */ { MAD_F(0x078569a2) /* 0.470071442 */, 18 }, /* 6578 */ { MAD_F(0x0785cd8f) /* 0.470166740 */, 18 }, /* 6579 */ { MAD_F(0x0786317e) /* 0.470262043 */, 18 }, /* 6580 */ { MAD_F(0x0786956e) /* 0.470357351 */, 18 }, /* 6581 */ { MAD_F(0x0786f95f) /* 0.470452664 */, 18 }, /* 6582 */ { MAD_F(0x07875d52) /* 0.470547982 */, 18 }, /* 6583 */ { MAD_F(0x0787c146) /* 0.470643305 */, 18 }, /* 6584 */ { MAD_F(0x0788253b) /* 0.470738632 */, 18 }, /* 6585 */ { MAD_F(0x07888932) /* 0.470833964 */, 18 }, /* 6586 */ { MAD_F(0x0788ed2a) /* 0.470929301 */, 18 }, /* 6587 */ { MAD_F(0x07895123) /* 0.471024643 */, 18 }, /* 6588 */ { MAD_F(0x0789b51d) /* 0.471119990 */, 18 }, /* 6589 */ { MAD_F(0x078a1919) /* 0.471215341 */, 18 }, /* 6590 */ { MAD_F(0x078a7d16) /* 0.471310698 */, 18 }, /* 6591 */ { MAD_F(0x078ae114) /* 0.471406059 */, 18 }, /* 6592 */ { MAD_F(0x078b4514) /* 0.471501425 */, 18 }, /* 6593 */ { MAD_F(0x078ba915) /* 0.471596796 */, 18 }, /* 6594 */ { MAD_F(0x078c0d17) /* 0.471692171 */, 18 }, /* 6595 */ { MAD_F(0x078c711a) /* 0.471787552 */, 18 }, /* 6596 */ { MAD_F(0x078cd51f) /* 0.471882937 */, 18 }, /* 6597 */ { MAD_F(0x078d3925) /* 0.471978327 */, 18 }, /* 6598 */ { MAD_F(0x078d9d2d) /* 0.472073722 */, 18 }, /* 6599 */ { MAD_F(0x078e0135) /* 0.472169122 */, 18 }, /* 6600 */ { MAD_F(0x078e653f) /* 0.472264527 */, 18 }, /* 6601 */ { MAD_F(0x078ec94b) /* 0.472359936 */, 18 }, /* 6602 */ { MAD_F(0x078f2d57) /* 0.472455350 */, 18 }, /* 6603 */ { MAD_F(0x078f9165) /* 0.472550769 */, 18 }, /* 6604 */ { MAD_F(0x078ff574) /* 0.472646193 */, 18 }, /* 6605 */ { MAD_F(0x07905985) /* 0.472741622 */, 18 }, /* 6606 */ { MAD_F(0x0790bd96) /* 0.472837055 */, 18 }, /* 6607 */ { MAD_F(0x079121a9) /* 0.472932493 */, 18 }, /* 6608 */ { MAD_F(0x079185be) /* 0.473027937 */, 18 }, /* 6609 */ { MAD_F(0x0791e9d3) /* 0.473123384 */, 18 }, /* 6610 */ { MAD_F(0x07924dea) /* 0.473218837 */, 18 }, /* 6611 */ { MAD_F(0x0792b202) /* 0.473314295 */, 18 }, /* 6612 */ { MAD_F(0x0793161c) /* 0.473409757 */, 18 }, /* 6613 */ { MAD_F(0x07937a37) /* 0.473505224 */, 18 }, /* 6614 */ { MAD_F(0x0793de53) /* 0.473600696 */, 18 }, /* 6615 */ { MAD_F(0x07944270) /* 0.473696173 */, 18 }, /* 6616 */ { MAD_F(0x0794a68f) /* 0.473791655 */, 18 }, /* 6617 */ { MAD_F(0x07950aaf) /* 0.473887141 */, 18 }, /* 6618 */ { MAD_F(0x07956ed0) /* 0.473982632 */, 18 }, /* 6619 */ { MAD_F(0x0795d2f2) /* 0.474078128 */, 18 }, /* 6620 */ { MAD_F(0x07963716) /* 0.474173629 */, 18 }, /* 6621 */ { MAD_F(0x07969b3b) /* 0.474269135 */, 18 }, /* 6622 */ { MAD_F(0x0796ff62) /* 0.474364645 */, 18 }, /* 6623 */ { MAD_F(0x07976389) /* 0.474460161 */, 18 }, /* 6624 */ { MAD_F(0x0797c7b2) /* 0.474555681 */, 18 }, /* 6625 */ { MAD_F(0x07982bdd) /* 0.474651205 */, 18 }, /* 6626 */ { MAD_F(0x07989008) /* 0.474746735 */, 18 }, /* 6627 */ { MAD_F(0x0798f435) /* 0.474842270 */, 18 }, /* 6628 */ { MAD_F(0x07995863) /* 0.474937809 */, 18 }, /* 6629 */ { MAD_F(0x0799bc92) /* 0.475033353 */, 18 }, /* 6630 */ { MAD_F(0x079a20c3) /* 0.475128902 */, 18 }, /* 6631 */ { MAD_F(0x079a84f5) /* 0.475224456 */, 18 }, /* 6632 */ { MAD_F(0x079ae929) /* 0.475320014 */, 18 }, /* 6633 */ { MAD_F(0x079b4d5d) /* 0.475415578 */, 18 }, /* 6634 */ { MAD_F(0x079bb193) /* 0.475511146 */, 18 }, /* 6635 */ { MAD_F(0x079c15ca) /* 0.475606719 */, 18 }, /* 6636 */ { MAD_F(0x079c7a03) /* 0.475702296 */, 18 }, /* 6637 */ { MAD_F(0x079cde3c) /* 0.475797879 */, 18 }, /* 6638 */ { MAD_F(0x079d4277) /* 0.475893466 */, 18 }, /* 6639 */ { MAD_F(0x079da6b4) /* 0.475989058 */, 18 }, /* 6640 */ { MAD_F(0x079e0af1) /* 0.476084655 */, 18 }, /* 6641 */ { MAD_F(0x079e6f30) /* 0.476180257 */, 18 }, /* 6642 */ { MAD_F(0x079ed370) /* 0.476275863 */, 18 }, /* 6643 */ { MAD_F(0x079f37b2) /* 0.476371475 */, 18 }, /* 6644 */ { MAD_F(0x079f9bf5) /* 0.476467091 */, 18 }, /* 6645 */ { MAD_F(0x07a00039) /* 0.476562712 */, 18 }, /* 6646 */ { MAD_F(0x07a0647e) /* 0.476658338 */, 18 }, /* 6647 */ { MAD_F(0x07a0c8c5) /* 0.476753968 */, 18 }, /* 6648 */ { MAD_F(0x07a12d0c) /* 0.476849603 */, 18 }, /* 6649 */ { MAD_F(0x07a19156) /* 0.476945243 */, 18 }, /* 6650 */ { MAD_F(0x07a1f5a0) /* 0.477040888 */, 18 }, /* 6651 */ { MAD_F(0x07a259ec) /* 0.477136538 */, 18 }, /* 6652 */ { MAD_F(0x07a2be39) /* 0.477232193 */, 18 }, /* 6653 */ { MAD_F(0x07a32287) /* 0.477327852 */, 18 }, /* 6654 */ { MAD_F(0x07a386d7) /* 0.477423516 */, 18 }, /* 6655 */ { MAD_F(0x07a3eb28) /* 0.477519185 */, 18 }, /* 6656 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 18 }, /* 6657 */ { MAD_F(0x07a4b3ce) /* 0.477710537 */, 18 }, /* 6658 */ { MAD_F(0x07a51822) /* 0.477806220 */, 18 }, /* 6659 */ { MAD_F(0x07a57c78) /* 0.477901908 */, 18 }, /* 6660 */ { MAD_F(0x07a5e0d0) /* 0.477997601 */, 18 }, /* 6661 */ { MAD_F(0x07a64528) /* 0.478093299 */, 18 }, /* 6662 */ { MAD_F(0x07a6a982) /* 0.478189001 */, 18 }, /* 6663 */ { MAD_F(0x07a70ddd) /* 0.478284708 */, 18 }, /* 6664 */ { MAD_F(0x07a7723a) /* 0.478380420 */, 18 }, /* 6665 */ { MAD_F(0x07a7d698) /* 0.478476137 */, 18 }, /* 6666 */ { MAD_F(0x07a83af7) /* 0.478571858 */, 18 }, /* 6667 */ { MAD_F(0x07a89f57) /* 0.478667585 */, 18 }, /* 6668 */ { MAD_F(0x07a903b9) /* 0.478763316 */, 18 }, /* 6669 */ { MAD_F(0x07a9681c) /* 0.478859052 */, 18 }, /* 6670 */ { MAD_F(0x07a9cc80) /* 0.478954793 */, 18 }, /* 6671 */ { MAD_F(0x07aa30e5) /* 0.479050538 */, 18 }, /* 6672 */ { MAD_F(0x07aa954c) /* 0.479146288 */, 18 }, /* 6673 */ { MAD_F(0x07aaf9b4) /* 0.479242043 */, 18 }, /* 6674 */ { MAD_F(0x07ab5e1e) /* 0.479337803 */, 18 }, /* 6675 */ { MAD_F(0x07abc288) /* 0.479433568 */, 18 }, /* 6676 */ { MAD_F(0x07ac26f4) /* 0.479529337 */, 18 }, /* 6677 */ { MAD_F(0x07ac8b61) /* 0.479625111 */, 18 }, /* 6678 */ { MAD_F(0x07acefd0) /* 0.479720890 */, 18 }, /* 6679 */ { MAD_F(0x07ad543f) /* 0.479816674 */, 18 }, /* 6680 */ { MAD_F(0x07adb8b0) /* 0.479912463 */, 18 }, /* 6681 */ { MAD_F(0x07ae1d23) /* 0.480008256 */, 18 }, /* 6682 */ { MAD_F(0x07ae8196) /* 0.480104054 */, 18 }, /* 6683 */ { MAD_F(0x07aee60b) /* 0.480199857 */, 18 }, /* 6684 */ { MAD_F(0x07af4a81) /* 0.480295664 */, 18 }, /* 6685 */ { MAD_F(0x07afaef9) /* 0.480391477 */, 18 }, /* 6686 */ { MAD_F(0x07b01372) /* 0.480487294 */, 18 }, /* 6687 */ { MAD_F(0x07b077ec) /* 0.480583116 */, 18 }, /* 6688 */ { MAD_F(0x07b0dc67) /* 0.480678943 */, 18 }, /* 6689 */ { MAD_F(0x07b140e4) /* 0.480774774 */, 18 }, /* 6690 */ { MAD_F(0x07b1a561) /* 0.480870611 */, 18 }, /* 6691 */ { MAD_F(0x07b209e1) /* 0.480966452 */, 18 }, /* 6692 */ { MAD_F(0x07b26e61) /* 0.481062298 */, 18 }, /* 6693 */ { MAD_F(0x07b2d2e3) /* 0.481158148 */, 18 }, /* 6694 */ { MAD_F(0x07b33766) /* 0.481254004 */, 18 }, /* 6695 */ { MAD_F(0x07b39bea) /* 0.481349864 */, 18 }, /* 6696 */ { MAD_F(0x07b4006f) /* 0.481445729 */, 18 }, /* 6697 */ { MAD_F(0x07b464f6) /* 0.481541598 */, 18 }, /* 6698 */ { MAD_F(0x07b4c97e) /* 0.481637473 */, 18 }, /* 6699 */ { MAD_F(0x07b52e08) /* 0.481733352 */, 18 }, /* 6700 */ { MAD_F(0x07b59292) /* 0.481829236 */, 18 }, /* 6701 */ { MAD_F(0x07b5f71e) /* 0.481925125 */, 18 }, /* 6702 */ { MAD_F(0x07b65bac) /* 0.482021019 */, 18 }, /* 6703 */ { MAD_F(0x07b6c03a) /* 0.482116917 */, 18 }, /* 6704 */ { MAD_F(0x07b724ca) /* 0.482212820 */, 18 }, /* 6705 */ { MAD_F(0x07b7895b) /* 0.482308728 */, 18 }, /* 6706 */ { MAD_F(0x07b7eded) /* 0.482404640 */, 18 }, /* 6707 */ { MAD_F(0x07b85281) /* 0.482500558 */, 18 }, /* 6708 */ { MAD_F(0x07b8b716) /* 0.482596480 */, 18 }, /* 6709 */ { MAD_F(0x07b91bac) /* 0.482692407 */, 18 }, /* 6710 */ { MAD_F(0x07b98044) /* 0.482788339 */, 18 }, /* 6711 */ { MAD_F(0x07b9e4dc) /* 0.482884275 */, 18 }, /* 6712 */ { MAD_F(0x07ba4976) /* 0.482980216 */, 18 }, /* 6713 */ { MAD_F(0x07baae12) /* 0.483076162 */, 18 }, /* 6714 */ { MAD_F(0x07bb12ae) /* 0.483172113 */, 18 }, /* 6715 */ { MAD_F(0x07bb774c) /* 0.483268069 */, 18 }, /* 6716 */ { MAD_F(0x07bbdbeb) /* 0.483364029 */, 18 }, /* 6717 */ { MAD_F(0x07bc408c) /* 0.483459994 */, 18 }, /* 6718 */ { MAD_F(0x07bca52d) /* 0.483555964 */, 18 }, /* 6719 */ { MAD_F(0x07bd09d0) /* 0.483651939 */, 18 }, /* 6720 */ { MAD_F(0x07bd6e75) /* 0.483747918 */, 18 }, /* 6721 */ { MAD_F(0x07bdd31a) /* 0.483843902 */, 18 }, /* 6722 */ { MAD_F(0x07be37c1) /* 0.483939891 */, 18 }, /* 6723 */ { MAD_F(0x07be9c69) /* 0.484035885 */, 18 }, /* 6724 */ { MAD_F(0x07bf0113) /* 0.484131883 */, 18 }, /* 6725 */ { MAD_F(0x07bf65bd) /* 0.484227886 */, 18 }, /* 6726 */ { MAD_F(0x07bfca69) /* 0.484323894 */, 18 }, /* 6727 */ { MAD_F(0x07c02f16) /* 0.484419907 */, 18 }, /* 6728 */ { MAD_F(0x07c093c5) /* 0.484515924 */, 18 }, /* 6729 */ { MAD_F(0x07c0f875) /* 0.484611946 */, 18 }, /* 6730 */ { MAD_F(0x07c15d26) /* 0.484707973 */, 18 }, /* 6731 */ { MAD_F(0x07c1c1d8) /* 0.484804005 */, 18 }, /* 6732 */ { MAD_F(0x07c2268b) /* 0.484900041 */, 18 }, /* 6733 */ { MAD_F(0x07c28b40) /* 0.484996083 */, 18 }, /* 6734 */ { MAD_F(0x07c2eff6) /* 0.485092128 */, 18 }, /* 6735 */ { MAD_F(0x07c354ae) /* 0.485188179 */, 18 }, /* 6736 */ { MAD_F(0x07c3b967) /* 0.485284235 */, 18 }, /* 6737 */ { MAD_F(0x07c41e21) /* 0.485380295 */, 18 }, /* 6738 */ { MAD_F(0x07c482dc) /* 0.485476360 */, 18 }, /* 6739 */ { MAD_F(0x07c4e798) /* 0.485572430 */, 18 }, /* 6740 */ { MAD_F(0x07c54c56) /* 0.485668504 */, 18 }, /* 6741 */ { MAD_F(0x07c5b115) /* 0.485764583 */, 18 }, /* 6742 */ { MAD_F(0x07c615d6) /* 0.485860667 */, 18 }, /* 6743 */ { MAD_F(0x07c67a97) /* 0.485956756 */, 18 }, /* 6744 */ { MAD_F(0x07c6df5a) /* 0.486052849 */, 18 }, /* 6745 */ { MAD_F(0x07c7441e) /* 0.486148948 */, 18 }, /* 6746 */ { MAD_F(0x07c7a8e4) /* 0.486245051 */, 18 }, /* 6747 */ { MAD_F(0x07c80daa) /* 0.486341158 */, 18 }, /* 6748 */ { MAD_F(0x07c87272) /* 0.486437271 */, 18 }, /* 6749 */ { MAD_F(0x07c8d73c) /* 0.486533388 */, 18 }, /* 6750 */ { MAD_F(0x07c93c06) /* 0.486629510 */, 18 }, /* 6751 */ { MAD_F(0x07c9a0d2) /* 0.486725637 */, 18 }, /* 6752 */ { MAD_F(0x07ca059f) /* 0.486821768 */, 18 }, /* 6753 */ { MAD_F(0x07ca6a6d) /* 0.486917905 */, 18 }, /* 6754 */ { MAD_F(0x07cacf3d) /* 0.487014045 */, 18 }, /* 6755 */ { MAD_F(0x07cb340e) /* 0.487110191 */, 18 }, /* 6756 */ { MAD_F(0x07cb98e0) /* 0.487206342 */, 18 }, /* 6757 */ { MAD_F(0x07cbfdb4) /* 0.487302497 */, 18 }, /* 6758 */ { MAD_F(0x07cc6288) /* 0.487398657 */, 18 }, /* 6759 */ { MAD_F(0x07ccc75e) /* 0.487494821 */, 18 }, /* 6760 */ { MAD_F(0x07cd2c36) /* 0.487590991 */, 18 }, /* 6761 */ { MAD_F(0x07cd910e) /* 0.487687165 */, 18 }, /* 6762 */ { MAD_F(0x07cdf5e8) /* 0.487783344 */, 18 }, /* 6763 */ { MAD_F(0x07ce5ac3) /* 0.487879528 */, 18 }, /* 6764 */ { MAD_F(0x07cebfa0) /* 0.487975716 */, 18 }, /* 6765 */ { MAD_F(0x07cf247d) /* 0.488071909 */, 18 }, /* 6766 */ { MAD_F(0x07cf895c) /* 0.488168107 */, 18 }, /* 6767 */ { MAD_F(0x07cfee3c) /* 0.488264310 */, 18 }, /* 6768 */ { MAD_F(0x07d0531e) /* 0.488360517 */, 18 }, /* 6769 */ { MAD_F(0x07d0b801) /* 0.488456729 */, 18 }, /* 6770 */ { MAD_F(0x07d11ce5) /* 0.488552946 */, 18 }, /* 6771 */ { MAD_F(0x07d181ca) /* 0.488649167 */, 18 }, /* 6772 */ { MAD_F(0x07d1e6b0) /* 0.488745394 */, 18 }, /* 6773 */ { MAD_F(0x07d24b98) /* 0.488841625 */, 18 }, /* 6774 */ { MAD_F(0x07d2b081) /* 0.488937860 */, 18 }, /* 6775 */ { MAD_F(0x07d3156c) /* 0.489034101 */, 18 }, /* 6776 */ { MAD_F(0x07d37a57) /* 0.489130346 */, 18 }, /* 6777 */ { MAD_F(0x07d3df44) /* 0.489226596 */, 18 }, /* 6778 */ { MAD_F(0x07d44432) /* 0.489322851 */, 18 }, /* 6779 */ { MAD_F(0x07d4a922) /* 0.489419110 */, 18 }, /* 6780 */ { MAD_F(0x07d50e13) /* 0.489515375 */, 18 }, /* 6781 */ { MAD_F(0x07d57305) /* 0.489611643 */, 18 }, /* 6782 */ { MAD_F(0x07d5d7f8) /* 0.489707917 */, 18 }, /* 6783 */ { MAD_F(0x07d63cec) /* 0.489804195 */, 18 }, /* 6784 */ { MAD_F(0x07d6a1e2) /* 0.489900479 */, 18 }, /* 6785 */ { MAD_F(0x07d706d9) /* 0.489996766 */, 18 }, /* 6786 */ { MAD_F(0x07d76bd2) /* 0.490093059 */, 18 }, /* 6787 */ { MAD_F(0x07d7d0cb) /* 0.490189356 */, 18 }, /* 6788 */ { MAD_F(0x07d835c6) /* 0.490285658 */, 18 }, /* 6789 */ { MAD_F(0x07d89ac2) /* 0.490381965 */, 18 }, /* 6790 */ { MAD_F(0x07d8ffc0) /* 0.490478277 */, 18 }, /* 6791 */ { MAD_F(0x07d964be) /* 0.490574593 */, 18 }, /* 6792 */ { MAD_F(0x07d9c9be) /* 0.490670914 */, 18 }, /* 6793 */ { MAD_F(0x07da2ebf) /* 0.490767239 */, 18 }, /* 6794 */ { MAD_F(0x07da93c2) /* 0.490863570 */, 18 }, /* 6795 */ { MAD_F(0x07daf8c6) /* 0.490959905 */, 18 }, /* 6796 */ { MAD_F(0x07db5dcb) /* 0.491056245 */, 18 }, /* 6797 */ { MAD_F(0x07dbc2d1) /* 0.491152589 */, 18 }, /* 6798 */ { MAD_F(0x07dc27d9) /* 0.491248939 */, 18 }, /* 6799 */ { MAD_F(0x07dc8ce1) /* 0.491345293 */, 18 }, /* 6800 */ { MAD_F(0x07dcf1ec) /* 0.491441651 */, 18 }, /* 6801 */ { MAD_F(0x07dd56f7) /* 0.491538015 */, 18 }, /* 6802 */ { MAD_F(0x07ddbc04) /* 0.491634383 */, 18 }, /* 6803 */ { MAD_F(0x07de2111) /* 0.491730756 */, 18 }, /* 6804 */ { MAD_F(0x07de8621) /* 0.491827134 */, 18 }, /* 6805 */ { MAD_F(0x07deeb31) /* 0.491923516 */, 18 }, /* 6806 */ { MAD_F(0x07df5043) /* 0.492019903 */, 18 }, /* 6807 */ { MAD_F(0x07dfb556) /* 0.492116295 */, 18 }, /* 6808 */ { MAD_F(0x07e01a6a) /* 0.492212691 */, 18 }, /* 6809 */ { MAD_F(0x07e07f80) /* 0.492309093 */, 18 }, /* 6810 */ { MAD_F(0x07e0e496) /* 0.492405499 */, 18 }, /* 6811 */ { MAD_F(0x07e149ae) /* 0.492501909 */, 18 }, /* 6812 */ { MAD_F(0x07e1aec8) /* 0.492598325 */, 18 }, /* 6813 */ { MAD_F(0x07e213e2) /* 0.492694745 */, 18 }, /* 6814 */ { MAD_F(0x07e278fe) /* 0.492791170 */, 18 }, /* 6815 */ { MAD_F(0x07e2de1b) /* 0.492887599 */, 18 }, /* 6816 */ { MAD_F(0x07e3433a) /* 0.492984033 */, 18 }, /* 6817 */ { MAD_F(0x07e3a859) /* 0.493080472 */, 18 }, /* 6818 */ { MAD_F(0x07e40d7a) /* 0.493176916 */, 18 }, /* 6819 */ { MAD_F(0x07e4729c) /* 0.493273365 */, 18 }, /* 6820 */ { MAD_F(0x07e4d7c0) /* 0.493369818 */, 18 }, /* 6821 */ { MAD_F(0x07e53ce4) /* 0.493466275 */, 18 }, /* 6822 */ { MAD_F(0x07e5a20a) /* 0.493562738 */, 18 }, /* 6823 */ { MAD_F(0x07e60732) /* 0.493659205 */, 18 }, /* 6824 */ { MAD_F(0x07e66c5a) /* 0.493755677 */, 18 }, /* 6825 */ { MAD_F(0x07e6d184) /* 0.493852154 */, 18 }, /* 6826 */ { MAD_F(0x07e736af) /* 0.493948635 */, 18 }, /* 6827 */ { MAD_F(0x07e79bdb) /* 0.494045122 */, 18 }, /* 6828 */ { MAD_F(0x07e80109) /* 0.494141612 */, 18 }, /* 6829 */ { MAD_F(0x07e86638) /* 0.494238108 */, 18 }, /* 6830 */ { MAD_F(0x07e8cb68) /* 0.494334608 */, 18 }, /* 6831 */ { MAD_F(0x07e93099) /* 0.494431113 */, 18 }, /* 6832 */ { MAD_F(0x07e995cc) /* 0.494527623 */, 18 }, /* 6833 */ { MAD_F(0x07e9fb00) /* 0.494624137 */, 18 }, /* 6834 */ { MAD_F(0x07ea6035) /* 0.494720656 */, 18 }, /* 6835 */ { MAD_F(0x07eac56b) /* 0.494817180 */, 18 }, /* 6836 */ { MAD_F(0x07eb2aa3) /* 0.494913709 */, 18 }, /* 6837 */ { MAD_F(0x07eb8fdc) /* 0.495010242 */, 18 }, /* 6838 */ { MAD_F(0x07ebf516) /* 0.495106780 */, 18 }, /* 6839 */ { MAD_F(0x07ec5a51) /* 0.495203322 */, 18 }, /* 6840 */ { MAD_F(0x07ecbf8e) /* 0.495299870 */, 18 }, /* 6841 */ { MAD_F(0x07ed24cc) /* 0.495396422 */, 18 }, /* 6842 */ { MAD_F(0x07ed8a0b) /* 0.495492978 */, 18 }, /* 6843 */ { MAD_F(0x07edef4c) /* 0.495589540 */, 18 }, /* 6844 */ { MAD_F(0x07ee548e) /* 0.495686106 */, 18 }, /* 6845 */ { MAD_F(0x07eeb9d1) /* 0.495782677 */, 18 }, /* 6846 */ { MAD_F(0x07ef1f15) /* 0.495879252 */, 18 }, /* 6847 */ { MAD_F(0x07ef845b) /* 0.495975833 */, 18 }, /* 6848 */ { MAD_F(0x07efe9a1) /* 0.496072418 */, 18 }, /* 6849 */ { MAD_F(0x07f04ee9) /* 0.496169007 */, 18 }, /* 6850 */ { MAD_F(0x07f0b433) /* 0.496265602 */, 18 }, /* 6851 */ { MAD_F(0x07f1197d) /* 0.496362201 */, 18 }, /* 6852 */ { MAD_F(0x07f17ec9) /* 0.496458804 */, 18 }, /* 6853 */ { MAD_F(0x07f1e416) /* 0.496555413 */, 18 }, /* 6854 */ { MAD_F(0x07f24965) /* 0.496652026 */, 18 }, /* 6855 */ { MAD_F(0x07f2aeb5) /* 0.496748644 */, 18 }, /* 6856 */ { MAD_F(0x07f31405) /* 0.496845266 */, 18 }, /* 6857 */ { MAD_F(0x07f37958) /* 0.496941894 */, 18 }, /* 6858 */ { MAD_F(0x07f3deab) /* 0.497038526 */, 18 }, /* 6859 */ { MAD_F(0x07f44400) /* 0.497135162 */, 18 }, /* 6860 */ { MAD_F(0x07f4a956) /* 0.497231804 */, 18 }, /* 6861 */ { MAD_F(0x07f50ead) /* 0.497328450 */, 18 }, /* 6862 */ { MAD_F(0x07f57405) /* 0.497425100 */, 18 }, /* 6863 */ { MAD_F(0x07f5d95f) /* 0.497521756 */, 18 }, /* 6864 */ { MAD_F(0x07f63eba) /* 0.497618416 */, 18 }, /* 6865 */ { MAD_F(0x07f6a416) /* 0.497715081 */, 18 }, /* 6866 */ { MAD_F(0x07f70974) /* 0.497811750 */, 18 }, /* 6867 */ { MAD_F(0x07f76ed3) /* 0.497908425 */, 18 }, /* 6868 */ { MAD_F(0x07f7d433) /* 0.498005103 */, 18 }, /* 6869 */ { MAD_F(0x07f83994) /* 0.498101787 */, 18 }, /* 6870 */ { MAD_F(0x07f89ef7) /* 0.498198475 */, 18 }, /* 6871 */ { MAD_F(0x07f9045a) /* 0.498295168 */, 18 }, /* 6872 */ { MAD_F(0x07f969c0) /* 0.498391866 */, 18 }, /* 6873 */ { MAD_F(0x07f9cf26) /* 0.498488568 */, 18 }, /* 6874 */ { MAD_F(0x07fa348e) /* 0.498585275 */, 18 }, /* 6875 */ { MAD_F(0x07fa99f6) /* 0.498681987 */, 18 }, /* 6876 */ { MAD_F(0x07faff60) /* 0.498778704 */, 18 }, /* 6877 */ { MAD_F(0x07fb64cc) /* 0.498875425 */, 18 }, /* 6878 */ { MAD_F(0x07fbca38) /* 0.498972150 */, 18 }, /* 6879 */ { MAD_F(0x07fc2fa6) /* 0.499068881 */, 18 }, /* 6880 */ { MAD_F(0x07fc9516) /* 0.499165616 */, 18 }, /* 6881 */ { MAD_F(0x07fcfa86) /* 0.499262356 */, 18 }, /* 6882 */ { MAD_F(0x07fd5ff8) /* 0.499359101 */, 18 }, /* 6883 */ { MAD_F(0x07fdc56b) /* 0.499455850 */, 18 }, /* 6884 */ { MAD_F(0x07fe2adf) /* 0.499552604 */, 18 }, /* 6885 */ { MAD_F(0x07fe9054) /* 0.499649362 */, 18 }, /* 6886 */ { MAD_F(0x07fef5cb) /* 0.499746126 */, 18 }, /* 6887 */ { MAD_F(0x07ff5b43) /* 0.499842894 */, 18 }, /* 6888 */ { MAD_F(0x07ffc0bc) /* 0.499939666 */, 18 }, /* 6889 */ { MAD_F(0x0400131b) /* 0.250018222 */, 19 }, /* 6890 */ { MAD_F(0x040045d9) /* 0.250066613 */, 19 }, /* 6891 */ { MAD_F(0x04007897) /* 0.250115006 */, 19 }, /* 6892 */ { MAD_F(0x0400ab57) /* 0.250163402 */, 19 }, /* 6893 */ { MAD_F(0x0400de16) /* 0.250211800 */, 19 }, /* 6894 */ { MAD_F(0x040110d7) /* 0.250260200 */, 19 }, /* 6895 */ { MAD_F(0x04014398) /* 0.250308603 */, 19 }, /* 6896 */ { MAD_F(0x04017659) /* 0.250357008 */, 19 }, /* 6897 */ { MAD_F(0x0401a91c) /* 0.250405415 */, 19 }, /* 6898 */ { MAD_F(0x0401dbdf) /* 0.250453825 */, 19 }, /* 6899 */ { MAD_F(0x04020ea2) /* 0.250502237 */, 19 }, /* 6900 */ { MAD_F(0x04024166) /* 0.250550652 */, 19 }, /* 6901 */ { MAD_F(0x0402742b) /* 0.250599068 */, 19 }, /* 6902 */ { MAD_F(0x0402a6f0) /* 0.250647488 */, 19 }, /* 6903 */ { MAD_F(0x0402d9b6) /* 0.250695909 */, 19 }, /* 6904 */ { MAD_F(0x04030c7d) /* 0.250744333 */, 19 }, /* 6905 */ { MAD_F(0x04033f44) /* 0.250792759 */, 19 }, /* 6906 */ { MAD_F(0x0403720c) /* 0.250841187 */, 19 }, /* 6907 */ { MAD_F(0x0403a4d5) /* 0.250889618 */, 19 }, /* 6908 */ { MAD_F(0x0403d79e) /* 0.250938051 */, 19 }, /* 6909 */ { MAD_F(0x04040a68) /* 0.250986487 */, 19 }, /* 6910 */ { MAD_F(0x04043d32) /* 0.251034924 */, 19 }, /* 6911 */ { MAD_F(0x04046ffd) /* 0.251083365 */, 19 }, /* 6912 */ { MAD_F(0x0404a2c9) /* 0.251131807 */, 19 }, /* 6913 */ { MAD_F(0x0404d595) /* 0.251180252 */, 19 }, /* 6914 */ { MAD_F(0x04050862) /* 0.251228699 */, 19 }, /* 6915 */ { MAD_F(0x04053b30) /* 0.251277148 */, 19 }, /* 6916 */ { MAD_F(0x04056dfe) /* 0.251325600 */, 19 }, /* 6917 */ { MAD_F(0x0405a0cd) /* 0.251374054 */, 19 }, /* 6918 */ { MAD_F(0x0405d39c) /* 0.251422511 */, 19 }, /* 6919 */ { MAD_F(0x0406066c) /* 0.251470970 */, 19 }, /* 6920 */ { MAD_F(0x0406393d) /* 0.251519431 */, 19 }, /* 6921 */ { MAD_F(0x04066c0e) /* 0.251567894 */, 19 }, /* 6922 */ { MAD_F(0x04069ee0) /* 0.251616360 */, 19 }, /* 6923 */ { MAD_F(0x0406d1b3) /* 0.251664828 */, 19 }, /* 6924 */ { MAD_F(0x04070486) /* 0.251713299 */, 19 }, /* 6925 */ { MAD_F(0x0407375a) /* 0.251761772 */, 19 }, /* 6926 */ { MAD_F(0x04076a2e) /* 0.251810247 */, 19 }, /* 6927 */ { MAD_F(0x04079d03) /* 0.251858724 */, 19 }, /* 6928 */ { MAD_F(0x0407cfd9) /* 0.251907204 */, 19 }, /* 6929 */ { MAD_F(0x040802af) /* 0.251955686 */, 19 }, /* 6930 */ { MAD_F(0x04083586) /* 0.252004171 */, 19 }, /* 6931 */ { MAD_F(0x0408685e) /* 0.252052658 */, 19 }, /* 6932 */ { MAD_F(0x04089b36) /* 0.252101147 */, 19 }, /* 6933 */ { MAD_F(0x0408ce0f) /* 0.252149638 */, 19 }, /* 6934 */ { MAD_F(0x040900e8) /* 0.252198132 */, 19 }, /* 6935 */ { MAD_F(0x040933c2) /* 0.252246628 */, 19 }, /* 6936 */ { MAD_F(0x0409669d) /* 0.252295127 */, 19 }, /* 6937 */ { MAD_F(0x04099978) /* 0.252343627 */, 19 }, /* 6938 */ { MAD_F(0x0409cc54) /* 0.252392131 */, 19 }, /* 6939 */ { MAD_F(0x0409ff31) /* 0.252440636 */, 19 }, /* 6940 */ { MAD_F(0x040a320e) /* 0.252489144 */, 19 }, /* 6941 */ { MAD_F(0x040a64ec) /* 0.252537654 */, 19 }, /* 6942 */ { MAD_F(0x040a97cb) /* 0.252586166 */, 19 }, /* 6943 */ { MAD_F(0x040acaaa) /* 0.252634681 */, 19 }, /* 6944 */ { MAD_F(0x040afd89) /* 0.252683198 */, 19 }, /* 6945 */ { MAD_F(0x040b306a) /* 0.252731718 */, 19 }, /* 6946 */ { MAD_F(0x040b634b) /* 0.252780240 */, 19 }, /* 6947 */ { MAD_F(0x040b962c) /* 0.252828764 */, 19 }, /* 6948 */ { MAD_F(0x040bc90e) /* 0.252877290 */, 19 }, /* 6949 */ { MAD_F(0x040bfbf1) /* 0.252925819 */, 19 }, /* 6950 */ { MAD_F(0x040c2ed5) /* 0.252974350 */, 19 }, /* 6951 */ { MAD_F(0x040c61b9) /* 0.253022883 */, 19 }, /* 6952 */ { MAD_F(0x040c949e) /* 0.253071419 */, 19 }, /* 6953 */ { MAD_F(0x040cc783) /* 0.253119957 */, 19 }, /* 6954 */ { MAD_F(0x040cfa69) /* 0.253168498 */, 19 }, /* 6955 */ { MAD_F(0x040d2d4f) /* 0.253217040 */, 19 }, /* 6956 */ { MAD_F(0x040d6037) /* 0.253265585 */, 19 }, /* 6957 */ { MAD_F(0x040d931e) /* 0.253314133 */, 19 }, /* 6958 */ { MAD_F(0x040dc607) /* 0.253362682 */, 19 }, /* 6959 */ { MAD_F(0x040df8f0) /* 0.253411234 */, 19 }, /* 6960 */ { MAD_F(0x040e2bda) /* 0.253459789 */, 19 }, /* 6961 */ { MAD_F(0x040e5ec4) /* 0.253508345 */, 19 }, /* 6962 */ { MAD_F(0x040e91af) /* 0.253556904 */, 19 }, /* 6963 */ { MAD_F(0x040ec49b) /* 0.253605466 */, 19 }, /* 6964 */ { MAD_F(0x040ef787) /* 0.253654029 */, 19 }, /* 6965 */ { MAD_F(0x040f2a74) /* 0.253702595 */, 19 }, /* 6966 */ { MAD_F(0x040f5d61) /* 0.253751164 */, 19 }, /* 6967 */ { MAD_F(0x040f904f) /* 0.253799734 */, 19 }, /* 6968 */ { MAD_F(0x040fc33e) /* 0.253848307 */, 19 }, /* 6969 */ { MAD_F(0x040ff62d) /* 0.253896883 */, 19 }, /* 6970 */ { MAD_F(0x0410291d) /* 0.253945460 */, 19 }, /* 6971 */ { MAD_F(0x04105c0e) /* 0.253994040 */, 19 }, /* 6972 */ { MAD_F(0x04108eff) /* 0.254042622 */, 19 }, /* 6973 */ { MAD_F(0x0410c1f1) /* 0.254091207 */, 19 }, /* 6974 */ { MAD_F(0x0410f4e3) /* 0.254139794 */, 19 }, /* 6975 */ { MAD_F(0x041127d6) /* 0.254188383 */, 19 }, /* 6976 */ { MAD_F(0x04115aca) /* 0.254236974 */, 19 }, /* 6977 */ { MAD_F(0x04118dbe) /* 0.254285568 */, 19 }, /* 6978 */ { MAD_F(0x0411c0b3) /* 0.254334165 */, 19 }, /* 6979 */ { MAD_F(0x0411f3a9) /* 0.254382763 */, 19 }, /* 6980 */ { MAD_F(0x0412269f) /* 0.254431364 */, 19 }, /* 6981 */ { MAD_F(0x04125996) /* 0.254479967 */, 19 }, /* 6982 */ { MAD_F(0x04128c8d) /* 0.254528572 */, 19 }, /* 6983 */ { MAD_F(0x0412bf85) /* 0.254577180 */, 19 }, /* 6984 */ { MAD_F(0x0412f27e) /* 0.254625790 */, 19 }, /* 6985 */ { MAD_F(0x04132577) /* 0.254674403 */, 19 }, /* 6986 */ { MAD_F(0x04135871) /* 0.254723017 */, 19 }, /* 6987 */ { MAD_F(0x04138b6c) /* 0.254771635 */, 19 }, /* 6988 */ { MAD_F(0x0413be67) /* 0.254820254 */, 19 }, /* 6989 */ { MAD_F(0x0413f163) /* 0.254868876 */, 19 }, /* 6990 */ { MAD_F(0x0414245f) /* 0.254917500 */, 19 }, /* 6991 */ { MAD_F(0x0414575c) /* 0.254966126 */, 19 }, /* 6992 */ { MAD_F(0x04148a5a) /* 0.255014755 */, 19 }, /* 6993 */ { MAD_F(0x0414bd58) /* 0.255063386 */, 19 }, /* 6994 */ { MAD_F(0x0414f057) /* 0.255112019 */, 19 }, /* 6995 */ { MAD_F(0x04152356) /* 0.255160655 */, 19 }, /* 6996 */ { MAD_F(0x04155657) /* 0.255209292 */, 19 }, /* 6997 */ { MAD_F(0x04158957) /* 0.255257933 */, 19 }, /* 6998 */ { MAD_F(0x0415bc59) /* 0.255306575 */, 19 }, /* 6999 */ { MAD_F(0x0415ef5b) /* 0.255355220 */, 19 }, /* 7000 */ { MAD_F(0x0416225d) /* 0.255403867 */, 19 }, /* 7001 */ { MAD_F(0x04165561) /* 0.255452517 */, 19 }, /* 7002 */ { MAD_F(0x04168864) /* 0.255501169 */, 19 }, /* 7003 */ { MAD_F(0x0416bb69) /* 0.255549823 */, 19 }, /* 7004 */ { MAD_F(0x0416ee6e) /* 0.255598479 */, 19 }, /* 7005 */ { MAD_F(0x04172174) /* 0.255647138 */, 19 }, /* 7006 */ { MAD_F(0x0417547a) /* 0.255695799 */, 19 }, /* 7007 */ { MAD_F(0x04178781) /* 0.255744463 */, 19 }, /* 7008 */ { MAD_F(0x0417ba89) /* 0.255793128 */, 19 }, /* 7009 */ { MAD_F(0x0417ed91) /* 0.255841796 */, 19 }, /* 7010 */ { MAD_F(0x0418209a) /* 0.255890467 */, 19 }, /* 7011 */ { MAD_F(0x041853a3) /* 0.255939139 */, 19 }, /* 7012 */ { MAD_F(0x041886ad) /* 0.255987814 */, 19 }, /* 7013 */ { MAD_F(0x0418b9b8) /* 0.256036492 */, 19 }, /* 7014 */ { MAD_F(0x0418ecc3) /* 0.256085171 */, 19 }, /* 7015 */ { MAD_F(0x04191fcf) /* 0.256133853 */, 19 }, /* 7016 */ { MAD_F(0x041952dc) /* 0.256182537 */, 19 }, /* 7017 */ { MAD_F(0x041985e9) /* 0.256231224 */, 19 }, /* 7018 */ { MAD_F(0x0419b8f7) /* 0.256279913 */, 19 }, /* 7019 */ { MAD_F(0x0419ec05) /* 0.256328604 */, 19 }, /* 7020 */ { MAD_F(0x041a1f15) /* 0.256377297 */, 19 }, /* 7021 */ { MAD_F(0x041a5224) /* 0.256425993 */, 19 }, /* 7022 */ { MAD_F(0x041a8534) /* 0.256474691 */, 19 }, /* 7023 */ { MAD_F(0x041ab845) /* 0.256523392 */, 19 }, /* 7024 */ { MAD_F(0x041aeb57) /* 0.256572095 */, 19 }, /* 7025 */ { MAD_F(0x041b1e69) /* 0.256620800 */, 19 }, /* 7026 */ { MAD_F(0x041b517c) /* 0.256669507 */, 19 }, /* 7027 */ { MAD_F(0x041b848f) /* 0.256718217 */, 19 }, /* 7028 */ { MAD_F(0x041bb7a3) /* 0.256766929 */, 19 }, /* 7029 */ { MAD_F(0x041beab8) /* 0.256815643 */, 19 }, /* 7030 */ { MAD_F(0x041c1dcd) /* 0.256864359 */, 19 }, /* 7031 */ { MAD_F(0x041c50e3) /* 0.256913078 */, 19 }, /* 7032 */ { MAD_F(0x041c83fa) /* 0.256961800 */, 19 }, /* 7033 */ { MAD_F(0x041cb711) /* 0.257010523 */, 19 }, /* 7034 */ { MAD_F(0x041cea28) /* 0.257059249 */, 19 }, /* 7035 */ { MAD_F(0x041d1d41) /* 0.257107977 */, 19 }, /* 7036 */ { MAD_F(0x041d505a) /* 0.257156708 */, 19 }, /* 7037 */ { MAD_F(0x041d8373) /* 0.257205440 */, 19 }, /* 7038 */ { MAD_F(0x041db68e) /* 0.257254175 */, 19 }, /* 7039 */ { MAD_F(0x041de9a8) /* 0.257302913 */, 19 }, /* 7040 */ { MAD_F(0x041e1cc4) /* 0.257351652 */, 19 }, /* 7041 */ { MAD_F(0x041e4fe0) /* 0.257400394 */, 19 }, /* 7042 */ { MAD_F(0x041e82fd) /* 0.257449139 */, 19 }, /* 7043 */ { MAD_F(0x041eb61a) /* 0.257497885 */, 19 }, /* 7044 */ { MAD_F(0x041ee938) /* 0.257546634 */, 19 }, /* 7045 */ { MAD_F(0x041f1c57) /* 0.257595386 */, 19 }, /* 7046 */ { MAD_F(0x041f4f76) /* 0.257644139 */, 19 }, /* 7047 */ { MAD_F(0x041f8296) /* 0.257692895 */, 19 }, /* 7048 */ { MAD_F(0x041fb5b6) /* 0.257741653 */, 19 }, /* 7049 */ { MAD_F(0x041fe8d7) /* 0.257790414 */, 19 }, /* 7050 */ { MAD_F(0x04201bf9) /* 0.257839176 */, 19 }, /* 7051 */ { MAD_F(0x04204f1b) /* 0.257887941 */, 19 }, /* 7052 */ { MAD_F(0x0420823e) /* 0.257936709 */, 19 }, /* 7053 */ { MAD_F(0x0420b561) /* 0.257985478 */, 19 }, /* 7054 */ { MAD_F(0x0420e885) /* 0.258034250 */, 19 }, /* 7055 */ { MAD_F(0x04211baa) /* 0.258083025 */, 19 }, /* 7056 */ { MAD_F(0x04214ed0) /* 0.258131801 */, 19 }, /* 7057 */ { MAD_F(0x042181f6) /* 0.258180580 */, 19 }, /* 7058 */ { MAD_F(0x0421b51c) /* 0.258229361 */, 19 }, /* 7059 */ { MAD_F(0x0421e843) /* 0.258278145 */, 19 }, /* 7060 */ { MAD_F(0x04221b6b) /* 0.258326931 */, 19 }, /* 7061 */ { MAD_F(0x04224e94) /* 0.258375719 */, 19 }, /* 7062 */ { MAD_F(0x042281bd) /* 0.258424509 */, 19 }, /* 7063 */ { MAD_F(0x0422b4e6) /* 0.258473302 */, 19 }, /* 7064 */ { MAD_F(0x0422e811) /* 0.258522097 */, 19 }, /* 7065 */ { MAD_F(0x04231b3c) /* 0.258570894 */, 19 }, /* 7066 */ { MAD_F(0x04234e67) /* 0.258619694 */, 19 }, /* 7067 */ { MAD_F(0x04238193) /* 0.258668496 */, 19 }, /* 7068 */ { MAD_F(0x0423b4c0) /* 0.258717300 */, 19 }, /* 7069 */ { MAD_F(0x0423e7ee) /* 0.258766106 */, 19 }, /* 7070 */ { MAD_F(0x04241b1c) /* 0.258814915 */, 19 }, /* 7071 */ { MAD_F(0x04244e4a) /* 0.258863726 */, 19 }, /* 7072 */ { MAD_F(0x04248179) /* 0.258912540 */, 19 }, /* 7073 */ { MAD_F(0x0424b4a9) /* 0.258961356 */, 19 }, /* 7074 */ { MAD_F(0x0424e7da) /* 0.259010174 */, 19 }, /* 7075 */ { MAD_F(0x04251b0b) /* 0.259058994 */, 19 }, /* 7076 */ { MAD_F(0x04254e3d) /* 0.259107817 */, 19 }, /* 7077 */ { MAD_F(0x0425816f) /* 0.259156642 */, 19 }, /* 7078 */ { MAD_F(0x0425b4a2) /* 0.259205469 */, 19 }, /* 7079 */ { MAD_F(0x0425e7d6) /* 0.259254298 */, 19 }, /* 7080 */ { MAD_F(0x04261b0a) /* 0.259303130 */, 19 }, /* 7081 */ { MAD_F(0x04264e3f) /* 0.259351964 */, 19 }, /* 7082 */ { MAD_F(0x04268174) /* 0.259400801 */, 19 }, /* 7083 */ { MAD_F(0x0426b4aa) /* 0.259449639 */, 19 }, /* 7084 */ { MAD_F(0x0426e7e1) /* 0.259498480 */, 19 }, /* 7085 */ { MAD_F(0x04271b18) /* 0.259547324 */, 19 }, /* 7086 */ { MAD_F(0x04274e50) /* 0.259596169 */, 19 }, /* 7087 */ { MAD_F(0x04278188) /* 0.259645017 */, 19 }, /* 7088 */ { MAD_F(0x0427b4c2) /* 0.259693868 */, 19 }, /* 7089 */ { MAD_F(0x0427e7fb) /* 0.259742720 */, 19 }, /* 7090 */ { MAD_F(0x04281b36) /* 0.259791575 */, 19 }, /* 7091 */ { MAD_F(0x04284e71) /* 0.259840432 */, 19 }, /* 7092 */ { MAD_F(0x042881ac) /* 0.259889291 */, 19 }, /* 7093 */ { MAD_F(0x0428b4e8) /* 0.259938153 */, 19 }, /* 7094 */ { MAD_F(0x0428e825) /* 0.259987017 */, 19 }, /* 7095 */ { MAD_F(0x04291b63) /* 0.260035883 */, 19 }, /* 7096 */ { MAD_F(0x04294ea1) /* 0.260084752 */, 19 }, /* 7097 */ { MAD_F(0x042981df) /* 0.260133623 */, 19 }, /* 7098 */ { MAD_F(0x0429b51f) /* 0.260182496 */, 19 }, /* 7099 */ { MAD_F(0x0429e85f) /* 0.260231372 */, 19 }, /* 7100 */ { MAD_F(0x042a1b9f) /* 0.260280249 */, 19 }, /* 7101 */ { MAD_F(0x042a4ee0) /* 0.260329129 */, 19 }, /* 7102 */ { MAD_F(0x042a8222) /* 0.260378012 */, 19 }, /* 7103 */ { MAD_F(0x042ab564) /* 0.260426896 */, 19 }, /* 7104 */ { MAD_F(0x042ae8a7) /* 0.260475783 */, 19 }, /* 7105 */ { MAD_F(0x042b1beb) /* 0.260524673 */, 19 }, /* 7106 */ { MAD_F(0x042b4f2f) /* 0.260573564 */, 19 }, /* 7107 */ { MAD_F(0x042b8274) /* 0.260622458 */, 19 }, /* 7108 */ { MAD_F(0x042bb5ba) /* 0.260671354 */, 19 }, /* 7109 */ { MAD_F(0x042be900) /* 0.260720252 */, 19 }, /* 7110 */ { MAD_F(0x042c1c46) /* 0.260769153 */, 19 }, /* 7111 */ { MAD_F(0x042c4f8e) /* 0.260818056 */, 19 }, /* 7112 */ { MAD_F(0x042c82d6) /* 0.260866961 */, 19 }, /* 7113 */ { MAD_F(0x042cb61e) /* 0.260915869 */, 19 }, /* 7114 */ { MAD_F(0x042ce967) /* 0.260964779 */, 19 }, /* 7115 */ { MAD_F(0x042d1cb1) /* 0.261013691 */, 19 }, /* 7116 */ { MAD_F(0x042d4ffb) /* 0.261062606 */, 19 }, /* 7117 */ { MAD_F(0x042d8346) /* 0.261111522 */, 19 }, /* 7118 */ { MAD_F(0x042db692) /* 0.261160441 */, 19 }, /* 7119 */ { MAD_F(0x042de9de) /* 0.261209363 */, 19 }, /* 7120 */ { MAD_F(0x042e1d2b) /* 0.261258286 */, 19 }, /* 7121 */ { MAD_F(0x042e5078) /* 0.261307212 */, 19 }, /* 7122 */ { MAD_F(0x042e83c6) /* 0.261356140 */, 19 }, /* 7123 */ { MAD_F(0x042eb715) /* 0.261405071 */, 19 }, /* 7124 */ { MAD_F(0x042eea64) /* 0.261454004 */, 19 }, /* 7125 */ { MAD_F(0x042f1db4) /* 0.261502939 */, 19 }, /* 7126 */ { MAD_F(0x042f5105) /* 0.261551876 */, 19 }, /* 7127 */ { MAD_F(0x042f8456) /* 0.261600816 */, 19 }, /* 7128 */ { MAD_F(0x042fb7a8) /* 0.261649758 */, 19 }, /* 7129 */ { MAD_F(0x042feafa) /* 0.261698702 */, 19 }, /* 7130 */ { MAD_F(0x04301e4d) /* 0.261747649 */, 19 }, /* 7131 */ { MAD_F(0x043051a1) /* 0.261796597 */, 19 }, /* 7132 */ { MAD_F(0x043084f5) /* 0.261845548 */, 19 }, /* 7133 */ { MAD_F(0x0430b84a) /* 0.261894502 */, 19 }, /* 7134 */ { MAD_F(0x0430eb9f) /* 0.261943458 */, 19 }, /* 7135 */ { MAD_F(0x04311ef5) /* 0.261992416 */, 19 }, /* 7136 */ { MAD_F(0x0431524c) /* 0.262041376 */, 19 }, /* 7137 */ { MAD_F(0x043185a3) /* 0.262090338 */, 19 }, /* 7138 */ { MAD_F(0x0431b8fb) /* 0.262139303 */, 19 }, /* 7139 */ { MAD_F(0x0431ec54) /* 0.262188270 */, 19 }, /* 7140 */ { MAD_F(0x04321fad) /* 0.262237240 */, 19 }, /* 7141 */ { MAD_F(0x04325306) /* 0.262286211 */, 19 }, /* 7142 */ { MAD_F(0x04328661) /* 0.262335185 */, 19 }, /* 7143 */ { MAD_F(0x0432b9bc) /* 0.262384162 */, 19 }, /* 7144 */ { MAD_F(0x0432ed17) /* 0.262433140 */, 19 }, /* 7145 */ { MAD_F(0x04332074) /* 0.262482121 */, 19 }, /* 7146 */ { MAD_F(0x043353d0) /* 0.262531104 */, 19 }, /* 7147 */ { MAD_F(0x0433872e) /* 0.262580089 */, 19 }, /* 7148 */ { MAD_F(0x0433ba8c) /* 0.262629077 */, 19 }, /* 7149 */ { MAD_F(0x0433edea) /* 0.262678067 */, 19 }, /* 7150 */ { MAD_F(0x0434214a) /* 0.262727059 */, 19 }, /* 7151 */ { MAD_F(0x043454aa) /* 0.262776054 */, 19 }, /* 7152 */ { MAD_F(0x0434880a) /* 0.262825051 */, 19 }, /* 7153 */ { MAD_F(0x0434bb6b) /* 0.262874050 */, 19 }, /* 7154 */ { MAD_F(0x0434eecd) /* 0.262923051 */, 19 }, /* 7155 */ { MAD_F(0x0435222f) /* 0.262972055 */, 19 }, /* 7156 */ { MAD_F(0x04355592) /* 0.263021061 */, 19 }, /* 7157 */ { MAD_F(0x043588f6) /* 0.263070069 */, 19 }, /* 7158 */ { MAD_F(0x0435bc5a) /* 0.263119079 */, 19 }, /* 7159 */ { MAD_F(0x0435efbf) /* 0.263168092 */, 19 }, /* 7160 */ { MAD_F(0x04362324) /* 0.263217107 */, 19 }, /* 7161 */ { MAD_F(0x0436568a) /* 0.263266125 */, 19 }, /* 7162 */ { MAD_F(0x043689f1) /* 0.263315144 */, 19 }, /* 7163 */ { MAD_F(0x0436bd58) /* 0.263364166 */, 19 }, /* 7164 */ { MAD_F(0x0436f0c0) /* 0.263413191 */, 19 }, /* 7165 */ { MAD_F(0x04372428) /* 0.263462217 */, 19 }, /* 7166 */ { MAD_F(0x04375791) /* 0.263511246 */, 19 }, /* 7167 */ { MAD_F(0x04378afb) /* 0.263560277 */, 19 }, /* 7168 */ { MAD_F(0x0437be65) /* 0.263609310 */, 19 }, /* 7169 */ { MAD_F(0x0437f1d0) /* 0.263658346 */, 19 }, /* 7170 */ { MAD_F(0x0438253c) /* 0.263707384 */, 19 }, /* 7171 */ { MAD_F(0x043858a8) /* 0.263756424 */, 19 }, /* 7172 */ { MAD_F(0x04388c14) /* 0.263805466 */, 19 }, /* 7173 */ { MAD_F(0x0438bf82) /* 0.263854511 */, 19 }, /* 7174 */ { MAD_F(0x0438f2f0) /* 0.263903558 */, 19 }, /* 7175 */ { MAD_F(0x0439265e) /* 0.263952607 */, 19 }, /* 7176 */ { MAD_F(0x043959cd) /* 0.264001659 */, 19 }, /* 7177 */ { MAD_F(0x04398d3d) /* 0.264050713 */, 19 }, /* 7178 */ { MAD_F(0x0439c0ae) /* 0.264099769 */, 19 }, /* 7179 */ { MAD_F(0x0439f41f) /* 0.264148827 */, 19 }, /* 7180 */ { MAD_F(0x043a2790) /* 0.264197888 */, 19 }, /* 7181 */ { MAD_F(0x043a5b02) /* 0.264246951 */, 19 }, /* 7182 */ { MAD_F(0x043a8e75) /* 0.264296016 */, 19 }, /* 7183 */ { MAD_F(0x043ac1e9) /* 0.264345084 */, 19 }, /* 7184 */ { MAD_F(0x043af55d) /* 0.264394153 */, 19 }, /* 7185 */ { MAD_F(0x043b28d2) /* 0.264443225 */, 19 }, /* 7186 */ { MAD_F(0x043b5c47) /* 0.264492300 */, 19 }, /* 7187 */ { MAD_F(0x043b8fbd) /* 0.264541376 */, 19 }, /* 7188 */ { MAD_F(0x043bc333) /* 0.264590455 */, 19 }, /* 7189 */ { MAD_F(0x043bf6aa) /* 0.264639536 */, 19 }, /* 7190 */ { MAD_F(0x043c2a22) /* 0.264688620 */, 19 }, /* 7191 */ { MAD_F(0x043c5d9a) /* 0.264737706 */, 19 }, /* 7192 */ { MAD_F(0x043c9113) /* 0.264786794 */, 19 }, /* 7193 */ { MAD_F(0x043cc48d) /* 0.264835884 */, 19 }, /* 7194 */ { MAD_F(0x043cf807) /* 0.264884976 */, 19 }, /* 7195 */ { MAD_F(0x043d2b82) /* 0.264934071 */, 19 }, /* 7196 */ { MAD_F(0x043d5efd) /* 0.264983168 */, 19 }, /* 7197 */ { MAD_F(0x043d9279) /* 0.265032268 */, 19 }, /* 7198 */ { MAD_F(0x043dc5f6) /* 0.265081369 */, 19 }, /* 7199 */ { MAD_F(0x043df973) /* 0.265130473 */, 19 }, /* 7200 */ { MAD_F(0x043e2cf1) /* 0.265179580 */, 19 }, /* 7201 */ { MAD_F(0x043e6070) /* 0.265228688 */, 19 }, /* 7202 */ { MAD_F(0x043e93ef) /* 0.265277799 */, 19 }, /* 7203 */ { MAD_F(0x043ec76e) /* 0.265326912 */, 19 }, /* 7204 */ { MAD_F(0x043efaef) /* 0.265376027 */, 19 }, /* 7205 */ { MAD_F(0x043f2e6f) /* 0.265425145 */, 19 }, /* 7206 */ { MAD_F(0x043f61f1) /* 0.265474264 */, 19 }, /* 7207 */ { MAD_F(0x043f9573) /* 0.265523387 */, 19 }, /* 7208 */ { MAD_F(0x043fc8f6) /* 0.265572511 */, 19 }, /* 7209 */ { MAD_F(0x043ffc79) /* 0.265621638 */, 19 }, /* 7210 */ { MAD_F(0x04402ffd) /* 0.265670766 */, 19 }, /* 7211 */ { MAD_F(0x04406382) /* 0.265719898 */, 19 }, /* 7212 */ { MAD_F(0x04409707) /* 0.265769031 */, 19 }, /* 7213 */ { MAD_F(0x0440ca8d) /* 0.265818167 */, 19 }, /* 7214 */ { MAD_F(0x0440fe13) /* 0.265867305 */, 19 }, /* 7215 */ { MAD_F(0x0441319a) /* 0.265916445 */, 19 }, /* 7216 */ { MAD_F(0x04416522) /* 0.265965588 */, 19 }, /* 7217 */ { MAD_F(0x044198aa) /* 0.266014732 */, 19 }, /* 7218 */ { MAD_F(0x0441cc33) /* 0.266063880 */, 19 }, /* 7219 */ { MAD_F(0x0441ffbc) /* 0.266113029 */, 19 }, /* 7220 */ { MAD_F(0x04423346) /* 0.266162181 */, 19 }, /* 7221 */ { MAD_F(0x044266d1) /* 0.266211334 */, 19 }, /* 7222 */ { MAD_F(0x04429a5c) /* 0.266260491 */, 19 }, /* 7223 */ { MAD_F(0x0442cde8) /* 0.266309649 */, 19 }, /* 7224 */ { MAD_F(0x04430174) /* 0.266358810 */, 19 }, /* 7225 */ { MAD_F(0x04433501) /* 0.266407973 */, 19 }, /* 7226 */ { MAD_F(0x0443688f) /* 0.266457138 */, 19 }, /* 7227 */ { MAD_F(0x04439c1d) /* 0.266506305 */, 19 }, /* 7228 */ { MAD_F(0x0443cfac) /* 0.266555475 */, 19 }, /* 7229 */ { MAD_F(0x0444033c) /* 0.266604647 */, 19 }, /* 7230 */ { MAD_F(0x044436cc) /* 0.266653822 */, 19 }, /* 7231 */ { MAD_F(0x04446a5d) /* 0.266702998 */, 19 }, /* 7232 */ { MAD_F(0x04449dee) /* 0.266752177 */, 19 }, /* 7233 */ { MAD_F(0x0444d180) /* 0.266801358 */, 19 }, /* 7234 */ { MAD_F(0x04450513) /* 0.266850541 */, 19 }, /* 7235 */ { MAD_F(0x044538a6) /* 0.266899727 */, 19 }, /* 7236 */ { MAD_F(0x04456c39) /* 0.266948915 */, 19 }, /* 7237 */ { MAD_F(0x04459fce) /* 0.266998105 */, 19 }, /* 7238 */ { MAD_F(0x0445d363) /* 0.267047298 */, 19 }, /* 7239 */ { MAD_F(0x044606f8) /* 0.267096492 */, 19 }, /* 7240 */ { MAD_F(0x04463a8f) /* 0.267145689 */, 19 }, /* 7241 */ { MAD_F(0x04466e25) /* 0.267194888 */, 19 }, /* 7242 */ { MAD_F(0x0446a1bd) /* 0.267244090 */, 19 }, /* 7243 */ { MAD_F(0x0446d555) /* 0.267293294 */, 19 }, /* 7244 */ { MAD_F(0x044708ee) /* 0.267342500 */, 19 }, /* 7245 */ { MAD_F(0x04473c87) /* 0.267391708 */, 19 }, /* 7246 */ { MAD_F(0x04477021) /* 0.267440919 */, 19 }, /* 7247 */ { MAD_F(0x0447a3bb) /* 0.267490131 */, 19 }, /* 7248 */ { MAD_F(0x0447d756) /* 0.267539347 */, 19 }, /* 7249 */ { MAD_F(0x04480af2) /* 0.267588564 */, 19 }, /* 7250 */ { MAD_F(0x04483e8e) /* 0.267637783 */, 19 }, /* 7251 */ { MAD_F(0x0448722b) /* 0.267687005 */, 19 }, /* 7252 */ { MAD_F(0x0448a5c9) /* 0.267736229 */, 19 }, /* 7253 */ { MAD_F(0x0448d967) /* 0.267785456 */, 19 }, /* 7254 */ { MAD_F(0x04490d05) /* 0.267834685 */, 19 }, /* 7255 */ { MAD_F(0x044940a5) /* 0.267883915 */, 19 }, /* 7256 */ { MAD_F(0x04497445) /* 0.267933149 */, 19 }, /* 7257 */ { MAD_F(0x0449a7e5) /* 0.267982384 */, 19 }, /* 7258 */ { MAD_F(0x0449db86) /* 0.268031622 */, 19 }, /* 7259 */ { MAD_F(0x044a0f28) /* 0.268080862 */, 19 }, /* 7260 */ { MAD_F(0x044a42ca) /* 0.268130104 */, 19 }, /* 7261 */ { MAD_F(0x044a766d) /* 0.268179349 */, 19 }, /* 7262 */ { MAD_F(0x044aaa11) /* 0.268228595 */, 19 }, /* 7263 */ { MAD_F(0x044addb5) /* 0.268277844 */, 19 }, /* 7264 */ { MAD_F(0x044b115a) /* 0.268327096 */, 19 }, /* 7265 */ { MAD_F(0x044b44ff) /* 0.268376349 */, 19 }, /* 7266 */ { MAD_F(0x044b78a5) /* 0.268425605 */, 19 }, /* 7267 */ { MAD_F(0x044bac4c) /* 0.268474863 */, 19 }, /* 7268 */ { MAD_F(0x044bdff3) /* 0.268524123 */, 19 }, /* 7269 */ { MAD_F(0x044c139b) /* 0.268573386 */, 19 }, /* 7270 */ { MAD_F(0x044c4743) /* 0.268622651 */, 19 }, /* 7271 */ { MAD_F(0x044c7aec) /* 0.268671918 */, 19 }, /* 7272 */ { MAD_F(0x044cae96) /* 0.268721187 */, 19 }, /* 7273 */ { MAD_F(0x044ce240) /* 0.268770459 */, 19 }, /* 7274 */ { MAD_F(0x044d15eb) /* 0.268819733 */, 19 }, /* 7275 */ { MAD_F(0x044d4997) /* 0.268869009 */, 19 }, /* 7276 */ { MAD_F(0x044d7d43) /* 0.268918287 */, 19 }, /* 7277 */ { MAD_F(0x044db0ef) /* 0.268967568 */, 19 }, /* 7278 */ { MAD_F(0x044de49d) /* 0.269016851 */, 19 }, /* 7279 */ { MAD_F(0x044e184b) /* 0.269066136 */, 19 }, /* 7280 */ { MAD_F(0x044e4bf9) /* 0.269115423 */, 19 }, /* 7281 */ { MAD_F(0x044e7fa8) /* 0.269164713 */, 19 }, /* 7282 */ { MAD_F(0x044eb358) /* 0.269214005 */, 19 }, /* 7283 */ { MAD_F(0x044ee708) /* 0.269263299 */, 19 }, /* 7284 */ { MAD_F(0x044f1ab9) /* 0.269312595 */, 19 }, /* 7285 */ { MAD_F(0x044f4e6b) /* 0.269361894 */, 19 }, /* 7286 */ { MAD_F(0x044f821d) /* 0.269411195 */, 19 }, /* 7287 */ { MAD_F(0x044fb5cf) /* 0.269460498 */, 19 }, /* 7288 */ { MAD_F(0x044fe983) /* 0.269509804 */, 19 }, /* 7289 */ { MAD_F(0x04501d37) /* 0.269559111 */, 19 }, /* 7290 */ { MAD_F(0x045050eb) /* 0.269608421 */, 19 }, /* 7291 */ { MAD_F(0x045084a0) /* 0.269657734 */, 19 }, /* 7292 */ { MAD_F(0x0450b856) /* 0.269707048 */, 19 }, /* 7293 */ { MAD_F(0x0450ec0d) /* 0.269756365 */, 19 }, /* 7294 */ { MAD_F(0x04511fc4) /* 0.269805684 */, 19 }, /* 7295 */ { MAD_F(0x0451537b) /* 0.269855005 */, 19 }, /* 7296 */ { MAD_F(0x04518733) /* 0.269904329 */, 19 }, /* 7297 */ { MAD_F(0x0451baec) /* 0.269953654 */, 19 }, /* 7298 */ { MAD_F(0x0451eea5) /* 0.270002982 */, 19 }, /* 7299 */ { MAD_F(0x0452225f) /* 0.270052313 */, 19 }, /* 7300 */ { MAD_F(0x0452561a) /* 0.270101645 */, 19 }, /* 7301 */ { MAD_F(0x045289d5) /* 0.270150980 */, 19 }, /* 7302 */ { MAD_F(0x0452bd91) /* 0.270200317 */, 19 }, /* 7303 */ { MAD_F(0x0452f14d) /* 0.270249656 */, 19 }, /* 7304 */ { MAD_F(0x0453250a) /* 0.270298998 */, 19 }, /* 7305 */ { MAD_F(0x045358c8) /* 0.270348341 */, 19 }, /* 7306 */ { MAD_F(0x04538c86) /* 0.270397687 */, 19 }, /* 7307 */ { MAD_F(0x0453c045) /* 0.270447036 */, 19 }, /* 7308 */ { MAD_F(0x0453f405) /* 0.270496386 */, 19 }, /* 7309 */ { MAD_F(0x045427c5) /* 0.270545739 */, 19 }, /* 7310 */ { MAD_F(0x04545b85) /* 0.270595094 */, 19 }, /* 7311 */ { MAD_F(0x04548f46) /* 0.270644451 */, 19 }, /* 7312 */ { MAD_F(0x0454c308) /* 0.270693811 */, 19 }, /* 7313 */ { MAD_F(0x0454f6cb) /* 0.270743173 */, 19 }, /* 7314 */ { MAD_F(0x04552a8e) /* 0.270792537 */, 19 }, /* 7315 */ { MAD_F(0x04555e51) /* 0.270841903 */, 19 }, /* 7316 */ { MAD_F(0x04559216) /* 0.270891271 */, 19 }, /* 7317 */ { MAD_F(0x0455c5db) /* 0.270940642 */, 19 }, /* 7318 */ { MAD_F(0x0455f9a0) /* 0.270990015 */, 19 }, /* 7319 */ { MAD_F(0x04562d66) /* 0.271039390 */, 19 }, /* 7320 */ { MAD_F(0x0456612d) /* 0.271088768 */, 19 }, /* 7321 */ { MAD_F(0x045694f4) /* 0.271138148 */, 19 }, /* 7322 */ { MAD_F(0x0456c8bc) /* 0.271187530 */, 19 }, /* 7323 */ { MAD_F(0x0456fc84) /* 0.271236914 */, 19 }, /* 7324 */ { MAD_F(0x0457304e) /* 0.271286301 */, 19 }, /* 7325 */ { MAD_F(0x04576417) /* 0.271335689 */, 19 }, /* 7326 */ { MAD_F(0x045797e2) /* 0.271385080 */, 19 }, /* 7327 */ { MAD_F(0x0457cbac) /* 0.271434474 */, 19 }, /* 7328 */ { MAD_F(0x0457ff78) /* 0.271483869 */, 19 }, /* 7329 */ { MAD_F(0x04583344) /* 0.271533267 */, 19 }, /* 7330 */ { MAD_F(0x04586711) /* 0.271582667 */, 19 }, /* 7331 */ { MAD_F(0x04589ade) /* 0.271632069 */, 19 }, /* 7332 */ { MAD_F(0x0458ceac) /* 0.271681474 */, 19 }, /* 7333 */ { MAD_F(0x0459027b) /* 0.271730880 */, 19 }, /* 7334 */ { MAD_F(0x0459364a) /* 0.271780289 */, 19 }, /* 7335 */ { MAD_F(0x04596a19) /* 0.271829701 */, 19 }, /* 7336 */ { MAD_F(0x04599dea) /* 0.271879114 */, 19 }, /* 7337 */ { MAD_F(0x0459d1bb) /* 0.271928530 */, 19 }, /* 7338 */ { MAD_F(0x045a058c) /* 0.271977948 */, 19 }, /* 7339 */ { MAD_F(0x045a395e) /* 0.272027368 */, 19 }, /* 7340 */ { MAD_F(0x045a6d31) /* 0.272076790 */, 19 }, /* 7341 */ { MAD_F(0x045aa104) /* 0.272126215 */, 19 }, /* 7342 */ { MAD_F(0x045ad4d8) /* 0.272175642 */, 19 }, /* 7343 */ { MAD_F(0x045b08ad) /* 0.272225071 */, 19 }, /* 7344 */ { MAD_F(0x045b3c82) /* 0.272274503 */, 19 }, /* 7345 */ { MAD_F(0x045b7058) /* 0.272323936 */, 19 }, /* 7346 */ { MAD_F(0x045ba42e) /* 0.272373372 */, 19 }, /* 7347 */ { MAD_F(0x045bd805) /* 0.272422810 */, 19 }, /* 7348 */ { MAD_F(0x045c0bdd) /* 0.272472251 */, 19 }, /* 7349 */ { MAD_F(0x045c3fb5) /* 0.272521693 */, 19 }, /* 7350 */ { MAD_F(0x045c738e) /* 0.272571138 */, 19 }, /* 7351 */ { MAD_F(0x045ca767) /* 0.272620585 */, 19 }, /* 7352 */ { MAD_F(0x045cdb41) /* 0.272670035 */, 19 }, /* 7353 */ { MAD_F(0x045d0f1b) /* 0.272719486 */, 19 }, /* 7354 */ { MAD_F(0x045d42f7) /* 0.272768940 */, 19 }, /* 7355 */ { MAD_F(0x045d76d2) /* 0.272818396 */, 19 }, /* 7356 */ { MAD_F(0x045daaaf) /* 0.272867855 */, 19 }, /* 7357 */ { MAD_F(0x045dde8c) /* 0.272917315 */, 19 }, /* 7358 */ { MAD_F(0x045e1269) /* 0.272966778 */, 19 }, /* 7359 */ { MAD_F(0x045e4647) /* 0.273016243 */, 19 }, /* 7360 */ { MAD_F(0x045e7a26) /* 0.273065710 */, 19 }, /* 7361 */ { MAD_F(0x045eae06) /* 0.273115180 */, 19 }, /* 7362 */ { MAD_F(0x045ee1e6) /* 0.273164652 */, 19 }, /* 7363 */ { MAD_F(0x045f15c6) /* 0.273214126 */, 19 }, /* 7364 */ { MAD_F(0x045f49a7) /* 0.273263602 */, 19 }, /* 7365 */ { MAD_F(0x045f7d89) /* 0.273313081 */, 19 }, /* 7366 */ { MAD_F(0x045fb16c) /* 0.273362561 */, 19 }, /* 7367 */ { MAD_F(0x045fe54f) /* 0.273412044 */, 19 }, /* 7368 */ { MAD_F(0x04601932) /* 0.273461530 */, 19 }, /* 7369 */ { MAD_F(0x04604d16) /* 0.273511017 */, 19 }, /* 7370 */ { MAD_F(0x046080fb) /* 0.273560507 */, 19 }, /* 7371 */ { MAD_F(0x0460b4e1) /* 0.273609999 */, 19 }, /* 7372 */ { MAD_F(0x0460e8c7) /* 0.273659493 */, 19 }, /* 7373 */ { MAD_F(0x04611cad) /* 0.273708989 */, 19 }, /* 7374 */ { MAD_F(0x04615094) /* 0.273758488 */, 19 }, /* 7375 */ { MAD_F(0x0461847c) /* 0.273807989 */, 19 }, /* 7376 */ { MAD_F(0x0461b864) /* 0.273857492 */, 19 }, /* 7377 */ { MAD_F(0x0461ec4d) /* 0.273906997 */, 19 }, /* 7378 */ { MAD_F(0x04622037) /* 0.273956505 */, 19 }, /* 7379 */ { MAD_F(0x04625421) /* 0.274006015 */, 19 }, /* 7380 */ { MAD_F(0x0462880c) /* 0.274055527 */, 19 }, /* 7381 */ { MAD_F(0x0462bbf7) /* 0.274105041 */, 19 }, /* 7382 */ { MAD_F(0x0462efe3) /* 0.274154558 */, 19 }, /* 7383 */ { MAD_F(0x046323d0) /* 0.274204076 */, 19 }, /* 7384 */ { MAD_F(0x046357bd) /* 0.274253597 */, 19 }, /* 7385 */ { MAD_F(0x04638bab) /* 0.274303121 */, 19 }, /* 7386 */ { MAD_F(0x0463bf99) /* 0.274352646 */, 19 }, /* 7387 */ { MAD_F(0x0463f388) /* 0.274402174 */, 19 }, /* 7388 */ { MAD_F(0x04642778) /* 0.274451704 */, 19 }, /* 7389 */ { MAD_F(0x04645b68) /* 0.274501236 */, 19 }, /* 7390 */ { MAD_F(0x04648f59) /* 0.274550771 */, 19 }, /* 7391 */ { MAD_F(0x0464c34a) /* 0.274600307 */, 19 }, /* 7392 */ { MAD_F(0x0464f73c) /* 0.274649846 */, 19 }, /* 7393 */ { MAD_F(0x04652b2f) /* 0.274699387 */, 19 }, /* 7394 */ { MAD_F(0x04655f22) /* 0.274748931 */, 19 }, /* 7395 */ { MAD_F(0x04659316) /* 0.274798476 */, 19 }, /* 7396 */ { MAD_F(0x0465c70a) /* 0.274848024 */, 19 }, /* 7397 */ { MAD_F(0x0465faff) /* 0.274897574 */, 19 }, /* 7398 */ { MAD_F(0x04662ef5) /* 0.274947126 */, 19 }, /* 7399 */ { MAD_F(0x046662eb) /* 0.274996681 */, 19 }, /* 7400 */ { MAD_F(0x046696e2) /* 0.275046238 */, 19 }, /* 7401 */ { MAD_F(0x0466cad9) /* 0.275095797 */, 19 }, /* 7402 */ { MAD_F(0x0466fed1) /* 0.275145358 */, 19 }, /* 7403 */ { MAD_F(0x046732ca) /* 0.275194921 */, 19 }, /* 7404 */ { MAD_F(0x046766c3) /* 0.275244487 */, 19 }, /* 7405 */ { MAD_F(0x04679abd) /* 0.275294055 */, 19 }, /* 7406 */ { MAD_F(0x0467ceb7) /* 0.275343625 */, 19 }, /* 7407 */ { MAD_F(0x046802b2) /* 0.275393198 */, 19 }, /* 7408 */ { MAD_F(0x046836ae) /* 0.275442772 */, 19 }, /* 7409 */ { MAD_F(0x04686aaa) /* 0.275492349 */, 19 }, /* 7410 */ { MAD_F(0x04689ea7) /* 0.275541928 */, 19 }, /* 7411 */ { MAD_F(0x0468d2a4) /* 0.275591509 */, 19 }, /* 7412 */ { MAD_F(0x046906a2) /* 0.275641093 */, 19 }, /* 7413 */ { MAD_F(0x04693aa1) /* 0.275690679 */, 19 }, /* 7414 */ { MAD_F(0x04696ea0) /* 0.275740267 */, 19 }, /* 7415 */ { MAD_F(0x0469a2a0) /* 0.275789857 */, 19 }, /* 7416 */ { MAD_F(0x0469d6a0) /* 0.275839449 */, 19 }, /* 7417 */ { MAD_F(0x046a0aa1) /* 0.275889044 */, 19 }, /* 7418 */ { MAD_F(0x046a3ea3) /* 0.275938641 */, 19 }, /* 7419 */ { MAD_F(0x046a72a5) /* 0.275988240 */, 19 }, /* 7420 */ { MAD_F(0x046aa6a8) /* 0.276037842 */, 19 }, /* 7421 */ { MAD_F(0x046adaab) /* 0.276087445 */, 19 }, /* 7422 */ { MAD_F(0x046b0eaf) /* 0.276137051 */, 19 }, /* 7423 */ { MAD_F(0x046b42b3) /* 0.276186659 */, 19 }, /* 7424 */ { MAD_F(0x046b76b9) /* 0.276236269 */, 19 }, /* 7425 */ { MAD_F(0x046baabe) /* 0.276285882 */, 19 }, /* 7426 */ { MAD_F(0x046bdec5) /* 0.276335497 */, 19 }, /* 7427 */ { MAD_F(0x046c12cc) /* 0.276385113 */, 19 }, /* 7428 */ { MAD_F(0x046c46d3) /* 0.276434733 */, 19 }, /* 7429 */ { MAD_F(0x046c7adb) /* 0.276484354 */, 19 }, /* 7430 */ { MAD_F(0x046caee4) /* 0.276533978 */, 19 }, /* 7431 */ { MAD_F(0x046ce2ee) /* 0.276583604 */, 19 }, /* 7432 */ { MAD_F(0x046d16f7) /* 0.276633232 */, 19 }, /* 7433 */ { MAD_F(0x046d4b02) /* 0.276682862 */, 19 }, /* 7434 */ { MAD_F(0x046d7f0d) /* 0.276732495 */, 19 }, /* 7435 */ { MAD_F(0x046db319) /* 0.276782129 */, 19 }, /* 7436 */ { MAD_F(0x046de725) /* 0.276831766 */, 19 }, /* 7437 */ { MAD_F(0x046e1b32) /* 0.276881406 */, 19 }, /* 7438 */ { MAD_F(0x046e4f40) /* 0.276931047 */, 19 }, /* 7439 */ { MAD_F(0x046e834e) /* 0.276980691 */, 19 }, /* 7440 */ { MAD_F(0x046eb75c) /* 0.277030337 */, 19 }, /* 7441 */ { MAD_F(0x046eeb6c) /* 0.277079985 */, 19 }, /* 7442 */ { MAD_F(0x046f1f7c) /* 0.277129635 */, 19 }, /* 7443 */ { MAD_F(0x046f538c) /* 0.277179288 */, 19 }, /* 7444 */ { MAD_F(0x046f879d) /* 0.277228942 */, 19 }, /* 7445 */ { MAD_F(0x046fbbaf) /* 0.277278600 */, 19 }, /* 7446 */ { MAD_F(0x046fefc1) /* 0.277328259 */, 19 }, /* 7447 */ { MAD_F(0x047023d4) /* 0.277377920 */, 19 }, /* 7448 */ { MAD_F(0x047057e8) /* 0.277427584 */, 19 }, /* 7449 */ { MAD_F(0x04708bfc) /* 0.277477250 */, 19 }, /* 7450 */ { MAD_F(0x0470c011) /* 0.277526918 */, 19 }, /* 7451 */ { MAD_F(0x0470f426) /* 0.277576588 */, 19 }, /* 7452 */ { MAD_F(0x0471283c) /* 0.277626261 */, 19 }, /* 7453 */ { MAD_F(0x04715c52) /* 0.277675936 */, 19 }, /* 7454 */ { MAD_F(0x04719069) /* 0.277725613 */, 19 }, /* 7455 */ { MAD_F(0x0471c481) /* 0.277775292 */, 19 }, /* 7456 */ { MAD_F(0x0471f899) /* 0.277824973 */, 19 }, /* 7457 */ { MAD_F(0x04722cb2) /* 0.277874657 */, 19 }, /* 7458 */ { MAD_F(0x047260cc) /* 0.277924343 */, 19 }, /* 7459 */ { MAD_F(0x047294e6) /* 0.277974031 */, 19 }, /* 7460 */ { MAD_F(0x0472c900) /* 0.278023722 */, 19 }, /* 7461 */ { MAD_F(0x0472fd1b) /* 0.278073414 */, 19 }, /* 7462 */ { MAD_F(0x04733137) /* 0.278123109 */, 19 }, /* 7463 */ { MAD_F(0x04736554) /* 0.278172806 */, 19 }, /* 7464 */ { MAD_F(0x04739971) /* 0.278222505 */, 19 }, /* 7465 */ { MAD_F(0x0473cd8e) /* 0.278272207 */, 19 }, /* 7466 */ { MAD_F(0x047401ad) /* 0.278321910 */, 19 }, /* 7467 */ { MAD_F(0x047435cb) /* 0.278371616 */, 19 }, /* 7468 */ { MAD_F(0x047469eb) /* 0.278421324 */, 19 }, /* 7469 */ { MAD_F(0x04749e0b) /* 0.278471035 */, 19 }, /* 7470 */ { MAD_F(0x0474d22c) /* 0.278520747 */, 19 }, /* 7471 */ { MAD_F(0x0475064d) /* 0.278570462 */, 19 }, /* 7472 */ { MAD_F(0x04753a6f) /* 0.278620179 */, 19 }, /* 7473 */ { MAD_F(0x04756e91) /* 0.278669898 */, 19 }, /* 7474 */ { MAD_F(0x0475a2b4) /* 0.278719619 */, 19 }, /* 7475 */ { MAD_F(0x0475d6d7) /* 0.278769343 */, 19 }, /* 7476 */ { MAD_F(0x04760afc) /* 0.278819069 */, 19 }, /* 7477 */ { MAD_F(0x04763f20) /* 0.278868797 */, 19 }, /* 7478 */ { MAD_F(0x04767346) /* 0.278918527 */, 19 }, /* 7479 */ { MAD_F(0x0476a76c) /* 0.278968260 */, 19 }, /* 7480 */ { MAD_F(0x0476db92) /* 0.279017995 */, 19 }, /* 7481 */ { MAD_F(0x04770fba) /* 0.279067731 */, 19 }, /* 7482 */ { MAD_F(0x047743e1) /* 0.279117471 */, 19 }, /* 7483 */ { MAD_F(0x0477780a) /* 0.279167212 */, 19 }, /* 7484 */ { MAD_F(0x0477ac33) /* 0.279216956 */, 19 }, /* 7485 */ { MAD_F(0x0477e05c) /* 0.279266701 */, 19 }, /* 7486 */ { MAD_F(0x04781486) /* 0.279316449 */, 19 }, /* 7487 */ { MAD_F(0x047848b1) /* 0.279366200 */, 19 }, /* 7488 */ { MAD_F(0x04787cdc) /* 0.279415952 */, 19 }, /* 7489 */ { MAD_F(0x0478b108) /* 0.279465707 */, 19 }, /* 7490 */ { MAD_F(0x0478e535) /* 0.279515464 */, 19 }, /* 7491 */ { MAD_F(0x04791962) /* 0.279565223 */, 19 }, /* 7492 */ { MAD_F(0x04794d8f) /* 0.279614984 */, 19 }, /* 7493 */ { MAD_F(0x047981be) /* 0.279664748 */, 19 }, /* 7494 */ { MAD_F(0x0479b5ed) /* 0.279714513 */, 19 }, /* 7495 */ { MAD_F(0x0479ea1c) /* 0.279764281 */, 19 }, /* 7496 */ { MAD_F(0x047a1e4c) /* 0.279814051 */, 19 }, /* 7497 */ { MAD_F(0x047a527d) /* 0.279863824 */, 19 }, /* 7498 */ { MAD_F(0x047a86ae) /* 0.279913598 */, 19 }, /* 7499 */ { MAD_F(0x047abae0) /* 0.279963375 */, 19 }, /* 7500 */ { MAD_F(0x047aef12) /* 0.280013154 */, 19 }, /* 7501 */ { MAD_F(0x047b2346) /* 0.280062935 */, 19 }, /* 7502 */ { MAD_F(0x047b5779) /* 0.280112719 */, 19 }, /* 7503 */ { MAD_F(0x047b8bad) /* 0.280162504 */, 19 }, /* 7504 */ { MAD_F(0x047bbfe2) /* 0.280212292 */, 19 }, /* 7505 */ { MAD_F(0x047bf418) /* 0.280262082 */, 19 }, /* 7506 */ { MAD_F(0x047c284e) /* 0.280311875 */, 19 }, /* 7507 */ { MAD_F(0x047c5c84) /* 0.280361669 */, 19 }, /* 7508 */ { MAD_F(0x047c90bb) /* 0.280411466 */, 19 }, /* 7509 */ { MAD_F(0x047cc4f3) /* 0.280461265 */, 19 }, /* 7510 */ { MAD_F(0x047cf92c) /* 0.280511066 */, 19 }, /* 7511 */ { MAD_F(0x047d2d65) /* 0.280560869 */, 19 }, /* 7512 */ { MAD_F(0x047d619e) /* 0.280610675 */, 19 }, /* 7513 */ { MAD_F(0x047d95d8) /* 0.280660483 */, 19 }, /* 7514 */ { MAD_F(0x047dca13) /* 0.280710292 */, 19 }, /* 7515 */ { MAD_F(0x047dfe4e) /* 0.280760105 */, 19 }, /* 7516 */ { MAD_F(0x047e328a) /* 0.280809919 */, 19 }, /* 7517 */ { MAD_F(0x047e66c7) /* 0.280859736 */, 19 }, /* 7518 */ { MAD_F(0x047e9b04) /* 0.280909554 */, 19 }, /* 7519 */ { MAD_F(0x047ecf42) /* 0.280959375 */, 19 }, /* 7520 */ { MAD_F(0x047f0380) /* 0.281009199 */, 19 }, /* 7521 */ { MAD_F(0x047f37bf) /* 0.281059024 */, 19 }, /* 7522 */ { MAD_F(0x047f6bff) /* 0.281108852 */, 19 }, /* 7523 */ { MAD_F(0x047fa03f) /* 0.281158682 */, 19 }, /* 7524 */ { MAD_F(0x047fd47f) /* 0.281208514 */, 19 }, /* 7525 */ { MAD_F(0x048008c1) /* 0.281258348 */, 19 }, /* 7526 */ { MAD_F(0x04803d02) /* 0.281308184 */, 19 }, /* 7527 */ { MAD_F(0x04807145) /* 0.281358023 */, 19 }, /* 7528 */ { MAD_F(0x0480a588) /* 0.281407864 */, 19 }, /* 7529 */ { MAD_F(0x0480d9cc) /* 0.281457707 */, 19 }, /* 7530 */ { MAD_F(0x04810e10) /* 0.281507552 */, 19 }, /* 7531 */ { MAD_F(0x04814255) /* 0.281557400 */, 19 }, /* 7532 */ { MAD_F(0x0481769a) /* 0.281607250 */, 19 }, /* 7533 */ { MAD_F(0x0481aae0) /* 0.281657101 */, 19 }, /* 7534 */ { MAD_F(0x0481df27) /* 0.281706956 */, 19 }, /* 7535 */ { MAD_F(0x0482136e) /* 0.281756812 */, 19 }, /* 7536 */ { MAD_F(0x048247b6) /* 0.281806670 */, 19 }, /* 7537 */ { MAD_F(0x04827bfe) /* 0.281856531 */, 19 }, /* 7538 */ { MAD_F(0x0482b047) /* 0.281906394 */, 19 }, /* 7539 */ { MAD_F(0x0482e491) /* 0.281956259 */, 19 }, /* 7540 */ { MAD_F(0x048318db) /* 0.282006127 */, 19 }, /* 7541 */ { MAD_F(0x04834d26) /* 0.282055996 */, 19 }, /* 7542 */ { MAD_F(0x04838171) /* 0.282105868 */, 19 }, /* 7543 */ { MAD_F(0x0483b5bd) /* 0.282155742 */, 19 }, /* 7544 */ { MAD_F(0x0483ea0a) /* 0.282205618 */, 19 }, /* 7545 */ { MAD_F(0x04841e57) /* 0.282255496 */, 19 }, /* 7546 */ { MAD_F(0x048452a4) /* 0.282305377 */, 19 }, /* 7547 */ { MAD_F(0x048486f3) /* 0.282355260 */, 19 }, /* 7548 */ { MAD_F(0x0484bb42) /* 0.282405145 */, 19 }, /* 7549 */ { MAD_F(0x0484ef91) /* 0.282455032 */, 19 }, /* 7550 */ { MAD_F(0x048523e1) /* 0.282504921 */, 19 }, /* 7551 */ { MAD_F(0x04855832) /* 0.282554813 */, 19 }, /* 7552 */ { MAD_F(0x04858c83) /* 0.282604707 */, 19 }, /* 7553 */ { MAD_F(0x0485c0d5) /* 0.282654603 */, 19 }, /* 7554 */ { MAD_F(0x0485f527) /* 0.282704501 */, 19 }, /* 7555 */ { MAD_F(0x0486297a) /* 0.282754401 */, 19 }, /* 7556 */ { MAD_F(0x04865dce) /* 0.282804304 */, 19 }, /* 7557 */ { MAD_F(0x04869222) /* 0.282854209 */, 19 }, /* 7558 */ { MAD_F(0x0486c677) /* 0.282904116 */, 19 }, /* 7559 */ { MAD_F(0x0486facc) /* 0.282954025 */, 19 }, /* 7560 */ { MAD_F(0x04872f22) /* 0.283003936 */, 19 }, /* 7561 */ { MAD_F(0x04876379) /* 0.283053850 */, 19 }, /* 7562 */ { MAD_F(0x048797d0) /* 0.283103766 */, 19 }, /* 7563 */ { MAD_F(0x0487cc28) /* 0.283153684 */, 19 }, /* 7564 */ { MAD_F(0x04880080) /* 0.283203604 */, 19 }, /* 7565 */ { MAD_F(0x048834d9) /* 0.283253527 */, 19 }, /* 7566 */ { MAD_F(0x04886933) /* 0.283303451 */, 19 }, /* 7567 */ { MAD_F(0x04889d8d) /* 0.283353378 */, 19 }, /* 7568 */ { MAD_F(0x0488d1e8) /* 0.283403307 */, 19 }, /* 7569 */ { MAD_F(0x04890643) /* 0.283453238 */, 19 }, /* 7570 */ { MAD_F(0x04893a9f) /* 0.283503172 */, 19 }, /* 7571 */ { MAD_F(0x04896efb) /* 0.283553107 */, 19 }, /* 7572 */ { MAD_F(0x0489a358) /* 0.283603045 */, 19 }, /* 7573 */ { MAD_F(0x0489d7b6) /* 0.283652985 */, 19 }, /* 7574 */ { MAD_F(0x048a0c14) /* 0.283702927 */, 19 }, /* 7575 */ { MAD_F(0x048a4073) /* 0.283752872 */, 19 }, /* 7576 */ { MAD_F(0x048a74d3) /* 0.283802818 */, 19 }, /* 7577 */ { MAD_F(0x048aa933) /* 0.283852767 */, 19 }, /* 7578 */ { MAD_F(0x048add93) /* 0.283902718 */, 19 }, /* 7579 */ { MAD_F(0x048b11f5) /* 0.283952671 */, 19 }, /* 7580 */ { MAD_F(0x048b4656) /* 0.284002627 */, 19 }, /* 7581 */ { MAD_F(0x048b7ab9) /* 0.284052584 */, 19 }, /* 7582 */ { MAD_F(0x048baf1c) /* 0.284102544 */, 19 }, /* 7583 */ { MAD_F(0x048be37f) /* 0.284152506 */, 19 }, /* 7584 */ { MAD_F(0x048c17e3) /* 0.284202470 */, 19 }, /* 7585 */ { MAD_F(0x048c4c48) /* 0.284252436 */, 19 }, /* 7586 */ { MAD_F(0x048c80ad) /* 0.284302405 */, 19 }, /* 7587 */ { MAD_F(0x048cb513) /* 0.284352376 */, 19 }, /* 7588 */ { MAD_F(0x048ce97a) /* 0.284402349 */, 19 }, /* 7589 */ { MAD_F(0x048d1de1) /* 0.284452324 */, 19 }, /* 7590 */ { MAD_F(0x048d5249) /* 0.284502301 */, 19 }, /* 7591 */ { MAD_F(0x048d86b1) /* 0.284552281 */, 19 }, /* 7592 */ { MAD_F(0x048dbb1a) /* 0.284602263 */, 19 }, /* 7593 */ { MAD_F(0x048def83) /* 0.284652246 */, 19 }, /* 7594 */ { MAD_F(0x048e23ed) /* 0.284702233 */, 19 }, /* 7595 */ { MAD_F(0x048e5858) /* 0.284752221 */, 19 }, /* 7596 */ { MAD_F(0x048e8cc3) /* 0.284802211 */, 19 }, /* 7597 */ { MAD_F(0x048ec12f) /* 0.284852204 */, 19 }, /* 7598 */ { MAD_F(0x048ef59b) /* 0.284902199 */, 19 }, /* 7599 */ { MAD_F(0x048f2a08) /* 0.284952196 */, 19 }, /* 7600 */ { MAD_F(0x048f5e76) /* 0.285002195 */, 19 }, /* 7601 */ { MAD_F(0x048f92e4) /* 0.285052197 */, 19 }, /* 7602 */ { MAD_F(0x048fc753) /* 0.285102201 */, 19 }, /* 7603 */ { MAD_F(0x048ffbc2) /* 0.285152206 */, 19 }, /* 7604 */ { MAD_F(0x04903032) /* 0.285202214 */, 19 }, /* 7605 */ { MAD_F(0x049064a3) /* 0.285252225 */, 19 }, /* 7606 */ { MAD_F(0x04909914) /* 0.285302237 */, 19 }, /* 7607 */ { MAD_F(0x0490cd86) /* 0.285352252 */, 19 }, /* 7608 */ { MAD_F(0x049101f8) /* 0.285402269 */, 19 }, /* 7609 */ { MAD_F(0x0491366b) /* 0.285452288 */, 19 }, /* 7610 */ { MAD_F(0x04916ade) /* 0.285502309 */, 19 }, /* 7611 */ { MAD_F(0x04919f52) /* 0.285552332 */, 19 }, /* 7612 */ { MAD_F(0x0491d3c7) /* 0.285602358 */, 19 }, /* 7613 */ { MAD_F(0x0492083c) /* 0.285652386 */, 19 }, /* 7614 */ { MAD_F(0x04923cb2) /* 0.285702416 */, 19 }, /* 7615 */ { MAD_F(0x04927128) /* 0.285752448 */, 19 }, /* 7616 */ { MAD_F(0x0492a59f) /* 0.285802482 */, 19 }, /* 7617 */ { MAD_F(0x0492da17) /* 0.285852519 */, 19 }, /* 7618 */ { MAD_F(0x04930e8f) /* 0.285902557 */, 19 }, /* 7619 */ { MAD_F(0x04934308) /* 0.285952598 */, 19 }, /* 7620 */ { MAD_F(0x04937781) /* 0.286002641 */, 19 }, /* 7621 */ { MAD_F(0x0493abfb) /* 0.286052687 */, 19 }, /* 7622 */ { MAD_F(0x0493e076) /* 0.286102734 */, 19 }, /* 7623 */ { MAD_F(0x049414f1) /* 0.286152784 */, 19 }, /* 7624 */ { MAD_F(0x0494496c) /* 0.286202836 */, 19 }, /* 7625 */ { MAD_F(0x04947de9) /* 0.286252890 */, 19 }, /* 7626 */ { MAD_F(0x0494b266) /* 0.286302946 */, 19 }, /* 7627 */ { MAD_F(0x0494e6e3) /* 0.286353005 */, 19 }, /* 7628 */ { MAD_F(0x04951b61) /* 0.286403065 */, 19 }, /* 7629 */ { MAD_F(0x04954fe0) /* 0.286453128 */, 19 }, /* 7630 */ { MAD_F(0x0495845f) /* 0.286503193 */, 19 }, /* 7631 */ { MAD_F(0x0495b8df) /* 0.286553260 */, 19 }, /* 7632 */ { MAD_F(0x0495ed5f) /* 0.286603329 */, 19 }, /* 7633 */ { MAD_F(0x049621e0) /* 0.286653401 */, 19 }, /* 7634 */ { MAD_F(0x04965662) /* 0.286703475 */, 19 }, /* 7635 */ { MAD_F(0x04968ae4) /* 0.286753551 */, 19 }, /* 7636 */ { MAD_F(0x0496bf67) /* 0.286803629 */, 19 }, /* 7637 */ { MAD_F(0x0496f3ea) /* 0.286853709 */, 19 }, /* 7638 */ { MAD_F(0x0497286e) /* 0.286903792 */, 19 }, /* 7639 */ { MAD_F(0x04975cf2) /* 0.286953876 */, 19 }, /* 7640 */ { MAD_F(0x04979177) /* 0.287003963 */, 19 }, /* 7641 */ { MAD_F(0x0497c5fd) /* 0.287054052 */, 19 }, /* 7642 */ { MAD_F(0x0497fa83) /* 0.287104143 */, 19 }, /* 7643 */ { MAD_F(0x04982f0a) /* 0.287154237 */, 19 }, /* 7644 */ { MAD_F(0x04986392) /* 0.287204332 */, 19 }, /* 7645 */ { MAD_F(0x0498981a) /* 0.287254430 */, 19 }, /* 7646 */ { MAD_F(0x0498cca2) /* 0.287304530 */, 19 }, /* 7647 */ { MAD_F(0x0499012c) /* 0.287354632 */, 19 }, /* 7648 */ { MAD_F(0x049935b5) /* 0.287404737 */, 19 }, /* 7649 */ { MAD_F(0x04996a40) /* 0.287454843 */, 19 }, /* 7650 */ { MAD_F(0x04999ecb) /* 0.287504952 */, 19 }, /* 7651 */ { MAD_F(0x0499d356) /* 0.287555063 */, 19 }, /* 7652 */ { MAD_F(0x049a07e2) /* 0.287605176 */, 19 }, /* 7653 */ { MAD_F(0x049a3c6f) /* 0.287655291 */, 19 }, /* 7654 */ { MAD_F(0x049a70fc) /* 0.287705409 */, 19 }, /* 7655 */ { MAD_F(0x049aa58a) /* 0.287755528 */, 19 }, /* 7656 */ { MAD_F(0x049ada19) /* 0.287805650 */, 19 }, /* 7657 */ { MAD_F(0x049b0ea8) /* 0.287855774 */, 19 }, /* 7658 */ { MAD_F(0x049b4337) /* 0.287905900 */, 19 }, /* 7659 */ { MAD_F(0x049b77c8) /* 0.287956028 */, 19 }, /* 7660 */ { MAD_F(0x049bac58) /* 0.288006159 */, 19 }, /* 7661 */ { MAD_F(0x049be0ea) /* 0.288056292 */, 19 }, /* 7662 */ { MAD_F(0x049c157c) /* 0.288106427 */, 19 }, /* 7663 */ { MAD_F(0x049c4a0e) /* 0.288156564 */, 19 }, /* 7664 */ { MAD_F(0x049c7ea1) /* 0.288206703 */, 19 }, /* 7665 */ { MAD_F(0x049cb335) /* 0.288256844 */, 19 }, /* 7666 */ { MAD_F(0x049ce7ca) /* 0.288306988 */, 19 }, /* 7667 */ { MAD_F(0x049d1c5e) /* 0.288357134 */, 19 }, /* 7668 */ { MAD_F(0x049d50f4) /* 0.288407282 */, 19 }, /* 7669 */ { MAD_F(0x049d858a) /* 0.288457432 */, 19 }, /* 7670 */ { MAD_F(0x049dba21) /* 0.288507584 */, 19 }, /* 7671 */ { MAD_F(0x049deeb8) /* 0.288557739 */, 19 }, /* 7672 */ { MAD_F(0x049e2350) /* 0.288607895 */, 19 }, /* 7673 */ { MAD_F(0x049e57e8) /* 0.288658054 */, 19 }, /* 7674 */ { MAD_F(0x049e8c81) /* 0.288708215 */, 19 }, /* 7675 */ { MAD_F(0x049ec11b) /* 0.288758379 */, 19 }, /* 7676 */ { MAD_F(0x049ef5b5) /* 0.288808544 */, 19 }, /* 7677 */ { MAD_F(0x049f2a50) /* 0.288858712 */, 19 }, /* 7678 */ { MAD_F(0x049f5eeb) /* 0.288908881 */, 19 }, /* 7679 */ { MAD_F(0x049f9387) /* 0.288959053 */, 19 }, /* 7680 */ { MAD_F(0x049fc824) /* 0.289009227 */, 19 }, /* 7681 */ { MAD_F(0x049ffcc1) /* 0.289059404 */, 19 }, /* 7682 */ { MAD_F(0x04a0315e) /* 0.289109582 */, 19 }, /* 7683 */ { MAD_F(0x04a065fd) /* 0.289159763 */, 19 }, /* 7684 */ { MAD_F(0x04a09a9b) /* 0.289209946 */, 19 }, /* 7685 */ { MAD_F(0x04a0cf3b) /* 0.289260131 */, 19 }, /* 7686 */ { MAD_F(0x04a103db) /* 0.289310318 */, 19 }, /* 7687 */ { MAD_F(0x04a1387b) /* 0.289360507 */, 19 }, /* 7688 */ { MAD_F(0x04a16d1d) /* 0.289410699 */, 19 }, /* 7689 */ { MAD_F(0x04a1a1be) /* 0.289460893 */, 19 }, /* 7690 */ { MAD_F(0x04a1d661) /* 0.289511088 */, 19 }, /* 7691 */ { MAD_F(0x04a20b04) /* 0.289561287 */, 19 }, /* 7692 */ { MAD_F(0x04a23fa7) /* 0.289611487 */, 19 }, /* 7693 */ { MAD_F(0x04a2744b) /* 0.289661689 */, 19 }, /* 7694 */ { MAD_F(0x04a2a8f0) /* 0.289711894 */, 19 }, /* 7695 */ { MAD_F(0x04a2dd95) /* 0.289762101 */, 19 }, /* 7696 */ { MAD_F(0x04a3123b) /* 0.289812309 */, 19 }, /* 7697 */ { MAD_F(0x04a346e2) /* 0.289862521 */, 19 }, /* 7698 */ { MAD_F(0x04a37b89) /* 0.289912734 */, 19 }, /* 7699 */ { MAD_F(0x04a3b030) /* 0.289962949 */, 19 }, /* 7700 */ { MAD_F(0x04a3e4d8) /* 0.290013167 */, 19 }, /* 7701 */ { MAD_F(0x04a41981) /* 0.290063387 */, 19 }, /* 7702 */ { MAD_F(0x04a44e2b) /* 0.290113609 */, 19 }, /* 7703 */ { MAD_F(0x04a482d5) /* 0.290163833 */, 19 }, /* 7704 */ { MAD_F(0x04a4b77f) /* 0.290214059 */, 19 }, /* 7705 */ { MAD_F(0x04a4ec2a) /* 0.290264288 */, 19 }, /* 7706 */ { MAD_F(0x04a520d6) /* 0.290314519 */, 19 }, /* 7707 */ { MAD_F(0x04a55582) /* 0.290364751 */, 19 }, /* 7708 */ { MAD_F(0x04a58a2f) /* 0.290414986 */, 19 }, /* 7709 */ { MAD_F(0x04a5bedd) /* 0.290465224 */, 19 }, /* 7710 */ { MAD_F(0x04a5f38b) /* 0.290515463 */, 19 }, /* 7711 */ { MAD_F(0x04a62839) /* 0.290565705 */, 19 }, /* 7712 */ { MAD_F(0x04a65ce8) /* 0.290615948 */, 19 }, /* 7713 */ { MAD_F(0x04a69198) /* 0.290666194 */, 19 }, /* 7714 */ { MAD_F(0x04a6c648) /* 0.290716442 */, 19 }, /* 7715 */ { MAD_F(0x04a6faf9) /* 0.290766692 */, 19 }, /* 7716 */ { MAD_F(0x04a72fab) /* 0.290816945 */, 19 }, /* 7717 */ { MAD_F(0x04a7645d) /* 0.290867199 */, 19 }, /* 7718 */ { MAD_F(0x04a79910) /* 0.290917456 */, 19 }, /* 7719 */ { MAD_F(0x04a7cdc3) /* 0.290967715 */, 19 }, /* 7720 */ { MAD_F(0x04a80277) /* 0.291017976 */, 19 }, /* 7721 */ { MAD_F(0x04a8372b) /* 0.291068239 */, 19 }, /* 7722 */ { MAD_F(0x04a86be0) /* 0.291118505 */, 19 }, /* 7723 */ { MAD_F(0x04a8a096) /* 0.291168772 */, 19 }, /* 7724 */ { MAD_F(0x04a8d54c) /* 0.291219042 */, 19 }, /* 7725 */ { MAD_F(0x04a90a03) /* 0.291269314 */, 19 }, /* 7726 */ { MAD_F(0x04a93eba) /* 0.291319588 */, 19 }, /* 7727 */ { MAD_F(0x04a97372) /* 0.291369865 */, 19 }, /* 7728 */ { MAD_F(0x04a9a82b) /* 0.291420143 */, 19 }, /* 7729 */ { MAD_F(0x04a9dce4) /* 0.291470424 */, 19 }, /* 7730 */ { MAD_F(0x04aa119d) /* 0.291520706 */, 19 }, /* 7731 */ { MAD_F(0x04aa4658) /* 0.291570991 */, 19 }, /* 7732 */ { MAD_F(0x04aa7b13) /* 0.291621278 */, 19 }, /* 7733 */ { MAD_F(0x04aaafce) /* 0.291671568 */, 19 }, /* 7734 */ { MAD_F(0x04aae48a) /* 0.291721859 */, 19 }, /* 7735 */ { MAD_F(0x04ab1947) /* 0.291772153 */, 19 }, /* 7736 */ { MAD_F(0x04ab4e04) /* 0.291822449 */, 19 }, /* 7737 */ { MAD_F(0x04ab82c2) /* 0.291872747 */, 19 }, /* 7738 */ { MAD_F(0x04abb780) /* 0.291923047 */, 19 }, /* 7739 */ { MAD_F(0x04abec3f) /* 0.291973349 */, 19 }, /* 7740 */ { MAD_F(0x04ac20fe) /* 0.292023653 */, 19 }, /* 7741 */ { MAD_F(0x04ac55be) /* 0.292073960 */, 19 }, /* 7742 */ { MAD_F(0x04ac8a7f) /* 0.292124269 */, 19 }, /* 7743 */ { MAD_F(0x04acbf40) /* 0.292174580 */, 19 }, /* 7744 */ { MAD_F(0x04acf402) /* 0.292224893 */, 19 }, /* 7745 */ { MAD_F(0x04ad28c5) /* 0.292275208 */, 19 }, /* 7746 */ { MAD_F(0x04ad5d88) /* 0.292325526 */, 19 }, /* 7747 */ { MAD_F(0x04ad924b) /* 0.292375845 */, 19 }, /* 7748 */ { MAD_F(0x04adc70f) /* 0.292426167 */, 19 }, /* 7749 */ { MAD_F(0x04adfbd4) /* 0.292476491 */, 19 }, /* 7750 */ { MAD_F(0x04ae3099) /* 0.292526817 */, 19 }, /* 7751 */ { MAD_F(0x04ae655f) /* 0.292577145 */, 19 }, /* 7752 */ { MAD_F(0x04ae9a26) /* 0.292627476 */, 19 }, /* 7753 */ { MAD_F(0x04aeceed) /* 0.292677808 */, 19 }, /* 7754 */ { MAD_F(0x04af03b4) /* 0.292728143 */, 19 }, /* 7755 */ { MAD_F(0x04af387d) /* 0.292778480 */, 19 }, /* 7756 */ { MAD_F(0x04af6d45) /* 0.292828819 */, 19 }, /* 7757 */ { MAD_F(0x04afa20f) /* 0.292879160 */, 19 }, /* 7758 */ { MAD_F(0x04afd6d9) /* 0.292929504 */, 19 }, /* 7759 */ { MAD_F(0x04b00ba3) /* 0.292979849 */, 19 }, /* 7760 */ { MAD_F(0x04b0406e) /* 0.293030197 */, 19 }, /* 7761 */ { MAD_F(0x04b0753a) /* 0.293080547 */, 19 }, /* 7762 */ { MAD_F(0x04b0aa06) /* 0.293130899 */, 19 }, /* 7763 */ { MAD_F(0x04b0ded3) /* 0.293181253 */, 19 }, /* 7764 */ { MAD_F(0x04b113a1) /* 0.293231610 */, 19 }, /* 7765 */ { MAD_F(0x04b1486f) /* 0.293281968 */, 19 }, /* 7766 */ { MAD_F(0x04b17d3d) /* 0.293332329 */, 19 }, /* 7767 */ { MAD_F(0x04b1b20c) /* 0.293382692 */, 19 }, /* 7768 */ { MAD_F(0x04b1e6dc) /* 0.293433057 */, 19 }, /* 7769 */ { MAD_F(0x04b21bad) /* 0.293483424 */, 19 }, /* 7770 */ { MAD_F(0x04b2507d) /* 0.293533794 */, 19 }, /* 7771 */ { MAD_F(0x04b2854f) /* 0.293584165 */, 19 }, /* 7772 */ { MAD_F(0x04b2ba21) /* 0.293634539 */, 19 }, /* 7773 */ { MAD_F(0x04b2eef4) /* 0.293684915 */, 19 }, /* 7774 */ { MAD_F(0x04b323c7) /* 0.293735293 */, 19 }, /* 7775 */ { MAD_F(0x04b3589b) /* 0.293785673 */, 19 }, /* 7776 */ { MAD_F(0x04b38d6f) /* 0.293836055 */, 19 }, /* 7777 */ { MAD_F(0x04b3c244) /* 0.293886440 */, 19 }, /* 7778 */ { MAD_F(0x04b3f71a) /* 0.293936826 */, 19 }, /* 7779 */ { MAD_F(0x04b42bf0) /* 0.293987215 */, 19 }, /* 7780 */ { MAD_F(0x04b460c7) /* 0.294037606 */, 19 }, /* 7781 */ { MAD_F(0x04b4959e) /* 0.294087999 */, 19 }, /* 7782 */ { MAD_F(0x04b4ca76) /* 0.294138395 */, 19 }, /* 7783 */ { MAD_F(0x04b4ff4e) /* 0.294188792 */, 19 }, /* 7784 */ { MAD_F(0x04b53427) /* 0.294239192 */, 19 }, /* 7785 */ { MAD_F(0x04b56901) /* 0.294289593 */, 19 }, /* 7786 */ { MAD_F(0x04b59ddb) /* 0.294339997 */, 19 }, /* 7787 */ { MAD_F(0x04b5d2b6) /* 0.294390403 */, 19 }, /* 7788 */ { MAD_F(0x04b60791) /* 0.294440812 */, 19 }, /* 7789 */ { MAD_F(0x04b63c6d) /* 0.294491222 */, 19 }, /* 7790 */ { MAD_F(0x04b6714a) /* 0.294541635 */, 19 }, /* 7791 */ { MAD_F(0x04b6a627) /* 0.294592049 */, 19 }, /* 7792 */ { MAD_F(0x04b6db05) /* 0.294642466 */, 19 }, /* 7793 */ { MAD_F(0x04b70fe3) /* 0.294692885 */, 19 }, /* 7794 */ { MAD_F(0x04b744c2) /* 0.294743306 */, 19 }, /* 7795 */ { MAD_F(0x04b779a1) /* 0.294793730 */, 19 }, /* 7796 */ { MAD_F(0x04b7ae81) /* 0.294844155 */, 19 }, /* 7797 */ { MAD_F(0x04b7e362) /* 0.294894583 */, 19 }, /* 7798 */ { MAD_F(0x04b81843) /* 0.294945013 */, 19 }, /* 7799 */ { MAD_F(0x04b84d24) /* 0.294995445 */, 19 }, /* 7800 */ { MAD_F(0x04b88207) /* 0.295045879 */, 19 }, /* 7801 */ { MAD_F(0x04b8b6ea) /* 0.295096315 */, 19 }, /* 7802 */ { MAD_F(0x04b8ebcd) /* 0.295146753 */, 19 }, /* 7803 */ { MAD_F(0x04b920b1) /* 0.295197194 */, 19 }, /* 7804 */ { MAD_F(0x04b95596) /* 0.295247637 */, 19 }, /* 7805 */ { MAD_F(0x04b98a7b) /* 0.295298082 */, 19 }, /* 7806 */ { MAD_F(0x04b9bf61) /* 0.295348529 */, 19 }, /* 7807 */ { MAD_F(0x04b9f447) /* 0.295398978 */, 19 }, /* 7808 */ { MAD_F(0x04ba292e) /* 0.295449429 */, 19 }, /* 7809 */ { MAD_F(0x04ba5e16) /* 0.295499883 */, 19 }, /* 7810 */ { MAD_F(0x04ba92fe) /* 0.295550338 */, 19 }, /* 7811 */ { MAD_F(0x04bac7e6) /* 0.295600796 */, 19 }, /* 7812 */ { MAD_F(0x04bafcd0) /* 0.295651256 */, 19 }, /* 7813 */ { MAD_F(0x04bb31b9) /* 0.295701718 */, 19 }, /* 7814 */ { MAD_F(0x04bb66a4) /* 0.295752183 */, 19 }, /* 7815 */ { MAD_F(0x04bb9b8f) /* 0.295802649 */, 19 }, /* 7816 */ { MAD_F(0x04bbd07a) /* 0.295853118 */, 19 }, /* 7817 */ { MAD_F(0x04bc0566) /* 0.295903588 */, 19 }, /* 7818 */ { MAD_F(0x04bc3a53) /* 0.295954061 */, 19 }, /* 7819 */ { MAD_F(0x04bc6f40) /* 0.296004536 */, 19 }, /* 7820 */ { MAD_F(0x04bca42e) /* 0.296055013 */, 19 }, /* 7821 */ { MAD_F(0x04bcd91d) /* 0.296105493 */, 19 }, /* 7822 */ { MAD_F(0x04bd0e0c) /* 0.296155974 */, 19 }, /* 7823 */ { MAD_F(0x04bd42fb) /* 0.296206458 */, 19 }, /* 7824 */ { MAD_F(0x04bd77ec) /* 0.296256944 */, 19 }, /* 7825 */ { MAD_F(0x04bdacdc) /* 0.296307432 */, 19 }, /* 7826 */ { MAD_F(0x04bde1ce) /* 0.296357922 */, 19 }, /* 7827 */ { MAD_F(0x04be16c0) /* 0.296408414 */, 19 }, /* 7828 */ { MAD_F(0x04be4bb2) /* 0.296458908 */, 19 }, /* 7829 */ { MAD_F(0x04be80a5) /* 0.296509405 */, 19 }, /* 7830 */ { MAD_F(0x04beb599) /* 0.296559904 */, 19 }, /* 7831 */ { MAD_F(0x04beea8d) /* 0.296610404 */, 19 }, /* 7832 */ { MAD_F(0x04bf1f82) /* 0.296660907 */, 19 }, /* 7833 */ { MAD_F(0x04bf5477) /* 0.296711413 */, 19 }, /* 7834 */ { MAD_F(0x04bf896d) /* 0.296761920 */, 19 }, /* 7835 */ { MAD_F(0x04bfbe64) /* 0.296812429 */, 19 }, /* 7836 */ { MAD_F(0x04bff35b) /* 0.296862941 */, 19 }, /* 7837 */ { MAD_F(0x04c02852) /* 0.296913455 */, 19 }, /* 7838 */ { MAD_F(0x04c05d4b) /* 0.296963971 */, 19 }, /* 7839 */ { MAD_F(0x04c09243) /* 0.297014489 */, 19 }, /* 7840 */ { MAD_F(0x04c0c73d) /* 0.297065009 */, 19 }, /* 7841 */ { MAD_F(0x04c0fc37) /* 0.297115531 */, 19 }, /* 7842 */ { MAD_F(0x04c13131) /* 0.297166056 */, 19 }, /* 7843 */ { MAD_F(0x04c1662d) /* 0.297216582 */, 19 }, /* 7844 */ { MAD_F(0x04c19b28) /* 0.297267111 */, 19 }, /* 7845 */ { MAD_F(0x04c1d025) /* 0.297317642 */, 19 }, /* 7846 */ { MAD_F(0x04c20521) /* 0.297368175 */, 19 }, /* 7847 */ { MAD_F(0x04c23a1f) /* 0.297418710 */, 19 }, /* 7848 */ { MAD_F(0x04c26f1d) /* 0.297469248 */, 19 }, /* 7849 */ { MAD_F(0x04c2a41b) /* 0.297519787 */, 19 }, /* 7850 */ { MAD_F(0x04c2d91b) /* 0.297570329 */, 19 }, /* 7851 */ { MAD_F(0x04c30e1a) /* 0.297620873 */, 19 }, /* 7852 */ { MAD_F(0x04c3431b) /* 0.297671418 */, 19 }, /* 7853 */ { MAD_F(0x04c3781c) /* 0.297721967 */, 19 }, /* 7854 */ { MAD_F(0x04c3ad1d) /* 0.297772517 */, 19 }, /* 7855 */ { MAD_F(0x04c3e21f) /* 0.297823069 */, 19 }, /* 7856 */ { MAD_F(0x04c41722) /* 0.297873624 */, 19 }, /* 7857 */ { MAD_F(0x04c44c25) /* 0.297924180 */, 19 }, /* 7858 */ { MAD_F(0x04c48129) /* 0.297974739 */, 19 }, /* 7859 */ { MAD_F(0x04c4b62d) /* 0.298025300 */, 19 }, /* 7860 */ { MAD_F(0x04c4eb32) /* 0.298075863 */, 19 }, /* 7861 */ { MAD_F(0x04c52038) /* 0.298126429 */, 19 }, /* 7862 */ { MAD_F(0x04c5553e) /* 0.298176996 */, 19 }, /* 7863 */ { MAD_F(0x04c58a44) /* 0.298227565 */, 19 }, /* 7864 */ { MAD_F(0x04c5bf4c) /* 0.298278137 */, 19 }, /* 7865 */ { MAD_F(0x04c5f453) /* 0.298328711 */, 19 }, /* 7866 */ { MAD_F(0x04c6295c) /* 0.298379287 */, 19 }, /* 7867 */ { MAD_F(0x04c65e65) /* 0.298429865 */, 19 }, /* 7868 */ { MAD_F(0x04c6936e) /* 0.298480445 */, 19 }, /* 7869 */ { MAD_F(0x04c6c878) /* 0.298531028 */, 19 }, /* 7870 */ { MAD_F(0x04c6fd83) /* 0.298581612 */, 19 }, /* 7871 */ { MAD_F(0x04c7328e) /* 0.298632199 */, 19 }, /* 7872 */ { MAD_F(0x04c7679a) /* 0.298682788 */, 19 }, /* 7873 */ { MAD_F(0x04c79ca7) /* 0.298733379 */, 19 }, /* 7874 */ { MAD_F(0x04c7d1b4) /* 0.298783972 */, 19 }, /* 7875 */ { MAD_F(0x04c806c1) /* 0.298834567 */, 19 }, /* 7876 */ { MAD_F(0x04c83bcf) /* 0.298885165 */, 19 }, /* 7877 */ { MAD_F(0x04c870de) /* 0.298935764 */, 19 }, /* 7878 */ { MAD_F(0x04c8a5ed) /* 0.298986366 */, 19 }, /* 7879 */ { MAD_F(0x04c8dafd) /* 0.299036970 */, 19 }, /* 7880 */ { MAD_F(0x04c9100d) /* 0.299087576 */, 19 }, /* 7881 */ { MAD_F(0x04c9451e) /* 0.299138184 */, 19 }, /* 7882 */ { MAD_F(0x04c97a30) /* 0.299188794 */, 19 }, /* 7883 */ { MAD_F(0x04c9af42) /* 0.299239406 */, 19 }, /* 7884 */ { MAD_F(0x04c9e455) /* 0.299290021 */, 19 }, /* 7885 */ { MAD_F(0x04ca1968) /* 0.299340638 */, 19 }, /* 7886 */ { MAD_F(0x04ca4e7c) /* 0.299391256 */, 19 }, /* 7887 */ { MAD_F(0x04ca8391) /* 0.299441877 */, 19 }, /* 7888 */ { MAD_F(0x04cab8a6) /* 0.299492500 */, 19 }, /* 7889 */ { MAD_F(0x04caedbb) /* 0.299543126 */, 19 }, /* 7890 */ { MAD_F(0x04cb22d1) /* 0.299593753 */, 19 }, /* 7891 */ { MAD_F(0x04cb57e8) /* 0.299644382 */, 19 }, /* 7892 */ { MAD_F(0x04cb8d00) /* 0.299695014 */, 19 }, /* 7893 */ { MAD_F(0x04cbc217) /* 0.299745648 */, 19 }, /* 7894 */ { MAD_F(0x04cbf730) /* 0.299796284 */, 19 }, /* 7895 */ { MAD_F(0x04cc2c49) /* 0.299846922 */, 19 }, /* 7896 */ { MAD_F(0x04cc6163) /* 0.299897562 */, 19 }, /* 7897 */ { MAD_F(0x04cc967d) /* 0.299948204 */, 19 }, /* 7898 */ { MAD_F(0x04cccb98) /* 0.299998849 */, 19 }, /* 7899 */ { MAD_F(0x04cd00b3) /* 0.300049495 */, 19 }, /* 7900 */ { MAD_F(0x04cd35cf) /* 0.300100144 */, 19 }, /* 7901 */ { MAD_F(0x04cd6aeb) /* 0.300150795 */, 19 }, /* 7902 */ { MAD_F(0x04cda008) /* 0.300201448 */, 19 }, /* 7903 */ { MAD_F(0x04cdd526) /* 0.300252103 */, 19 }, /* 7904 */ { MAD_F(0x04ce0a44) /* 0.300302761 */, 19 }, /* 7905 */ { MAD_F(0x04ce3f63) /* 0.300353420 */, 19 }, /* 7906 */ { MAD_F(0x04ce7482) /* 0.300404082 */, 19 }, /* 7907 */ { MAD_F(0x04cea9a2) /* 0.300454745 */, 19 }, /* 7908 */ { MAD_F(0x04cedec3) /* 0.300505411 */, 19 }, /* 7909 */ { MAD_F(0x04cf13e4) /* 0.300556079 */, 19 }, /* 7910 */ { MAD_F(0x04cf4906) /* 0.300606749 */, 19 }, /* 7911 */ { MAD_F(0x04cf7e28) /* 0.300657421 */, 19 }, /* 7912 */ { MAD_F(0x04cfb34b) /* 0.300708096 */, 19 }, /* 7913 */ { MAD_F(0x04cfe86e) /* 0.300758772 */, 19 }, /* 7914 */ { MAD_F(0x04d01d92) /* 0.300809451 */, 19 }, /* 7915 */ { MAD_F(0x04d052b6) /* 0.300860132 */, 19 }, /* 7916 */ { MAD_F(0x04d087db) /* 0.300910815 */, 19 }, /* 7917 */ { MAD_F(0x04d0bd01) /* 0.300961500 */, 19 }, /* 7918 */ { MAD_F(0x04d0f227) /* 0.301012187 */, 19 }, /* 7919 */ { MAD_F(0x04d1274e) /* 0.301062876 */, 19 }, /* 7920 */ { MAD_F(0x04d15c76) /* 0.301113568 */, 19 }, /* 7921 */ { MAD_F(0x04d1919e) /* 0.301164261 */, 19 }, /* 7922 */ { MAD_F(0x04d1c6c6) /* 0.301214957 */, 19 }, /* 7923 */ { MAD_F(0x04d1fbef) /* 0.301265655 */, 19 }, /* 7924 */ { MAD_F(0x04d23119) /* 0.301316355 */, 19 }, /* 7925 */ { MAD_F(0x04d26643) /* 0.301367057 */, 19 }, /* 7926 */ { MAD_F(0x04d29b6e) /* 0.301417761 */, 19 }, /* 7927 */ { MAD_F(0x04d2d099) /* 0.301468468 */, 19 }, /* 7928 */ { MAD_F(0x04d305c5) /* 0.301519176 */, 19 }, /* 7929 */ { MAD_F(0x04d33af2) /* 0.301569887 */, 19 }, /* 7930 */ { MAD_F(0x04d3701f) /* 0.301620599 */, 19 }, /* 7931 */ { MAD_F(0x04d3a54d) /* 0.301671314 */, 19 }, /* 7932 */ { MAD_F(0x04d3da7b) /* 0.301722031 */, 19 }, /* 7933 */ { MAD_F(0x04d40faa) /* 0.301772751 */, 19 }, /* 7934 */ { MAD_F(0x04d444d9) /* 0.301823472 */, 19 }, /* 7935 */ { MAD_F(0x04d47a09) /* 0.301874195 */, 19 }, /* 7936 */ { MAD_F(0x04d4af3a) /* 0.301924921 */, 19 }, /* 7937 */ { MAD_F(0x04d4e46b) /* 0.301975649 */, 19 }, /* 7938 */ { MAD_F(0x04d5199c) /* 0.302026378 */, 19 }, /* 7939 */ { MAD_F(0x04d54ecf) /* 0.302077110 */, 19 }, /* 7940 */ { MAD_F(0x04d58401) /* 0.302127845 */, 19 }, /* 7941 */ { MAD_F(0x04d5b935) /* 0.302178581 */, 19 }, /* 7942 */ { MAD_F(0x04d5ee69) /* 0.302229319 */, 19 }, /* 7943 */ { MAD_F(0x04d6239d) /* 0.302280060 */, 19 }, /* 7944 */ { MAD_F(0x04d658d2) /* 0.302330802 */, 19 }, /* 7945 */ { MAD_F(0x04d68e08) /* 0.302381547 */, 19 }, /* 7946 */ { MAD_F(0x04d6c33e) /* 0.302432294 */, 19 }, /* 7947 */ { MAD_F(0x04d6f875) /* 0.302483043 */, 19 }, /* 7948 */ { MAD_F(0x04d72dad) /* 0.302533794 */, 19 }, /* 7949 */ { MAD_F(0x04d762e5) /* 0.302584547 */, 19 }, /* 7950 */ { MAD_F(0x04d7981d) /* 0.302635303 */, 19 }, /* 7951 */ { MAD_F(0x04d7cd56) /* 0.302686060 */, 19 }, /* 7952 */ { MAD_F(0x04d80290) /* 0.302736820 */, 19 }, /* 7953 */ { MAD_F(0x04d837ca) /* 0.302787581 */, 19 }, /* 7954 */ { MAD_F(0x04d86d05) /* 0.302838345 */, 19 }, /* 7955 */ { MAD_F(0x04d8a240) /* 0.302889111 */, 19 }, /* 7956 */ { MAD_F(0x04d8d77c) /* 0.302939879 */, 19 }, /* 7957 */ { MAD_F(0x04d90cb9) /* 0.302990650 */, 19 }, /* 7958 */ { MAD_F(0x04d941f6) /* 0.303041422 */, 19 }, /* 7959 */ { MAD_F(0x04d97734) /* 0.303092197 */, 19 }, /* 7960 */ { MAD_F(0x04d9ac72) /* 0.303142973 */, 19 }, /* 7961 */ { MAD_F(0x04d9e1b1) /* 0.303193752 */, 19 }, /* 7962 */ { MAD_F(0x04da16f0) /* 0.303244533 */, 19 }, /* 7963 */ { MAD_F(0x04da4c30) /* 0.303295316 */, 19 }, /* 7964 */ { MAD_F(0x04da8171) /* 0.303346101 */, 19 }, /* 7965 */ { MAD_F(0x04dab6b2) /* 0.303396889 */, 19 }, /* 7966 */ { MAD_F(0x04daebf4) /* 0.303447678 */, 19 }, /* 7967 */ { MAD_F(0x04db2136) /* 0.303498469 */, 19 }, /* 7968 */ { MAD_F(0x04db5679) /* 0.303549263 */, 19 }, /* 7969 */ { MAD_F(0x04db8bbc) /* 0.303600059 */, 19 }, /* 7970 */ { MAD_F(0x04dbc100) /* 0.303650857 */, 19 }, /* 7971 */ { MAD_F(0x04dbf644) /* 0.303701657 */, 19 }, /* 7972 */ { MAD_F(0x04dc2b8a) /* 0.303752459 */, 19 }, /* 7973 */ { MAD_F(0x04dc60cf) /* 0.303803263 */, 19 }, /* 7974 */ { MAD_F(0x04dc9616) /* 0.303854070 */, 19 }, /* 7975 */ { MAD_F(0x04dccb5c) /* 0.303904878 */, 19 }, /* 7976 */ { MAD_F(0x04dd00a4) /* 0.303955689 */, 19 }, /* 7977 */ { MAD_F(0x04dd35ec) /* 0.304006502 */, 19 }, /* 7978 */ { MAD_F(0x04dd6b34) /* 0.304057317 */, 19 }, /* 7979 */ { MAD_F(0x04dda07d) /* 0.304108134 */, 19 }, /* 7980 */ { MAD_F(0x04ddd5c7) /* 0.304158953 */, 19 }, /* 7981 */ { MAD_F(0x04de0b11) /* 0.304209774 */, 19 }, /* 7982 */ { MAD_F(0x04de405c) /* 0.304260597 */, 19 }, /* 7983 */ { MAD_F(0x04de75a7) /* 0.304311423 */, 19 }, /* 7984 */ { MAD_F(0x04deaaf3) /* 0.304362251 */, 19 }, /* 7985 */ { MAD_F(0x04dee040) /* 0.304413080 */, 19 }, /* 7986 */ { MAD_F(0x04df158d) /* 0.304463912 */, 19 }, /* 7987 */ { MAD_F(0x04df4adb) /* 0.304514746 */, 19 }, /* 7988 */ { MAD_F(0x04df8029) /* 0.304565582 */, 19 }, /* 7989 */ { MAD_F(0x04dfb578) /* 0.304616421 */, 19 }, /* 7990 */ { MAD_F(0x04dfeac7) /* 0.304667261 */, 19 }, /* 7991 */ { MAD_F(0x04e02017) /* 0.304718103 */, 19 }, /* 7992 */ { MAD_F(0x04e05567) /* 0.304768948 */, 19 }, /* 7993 */ { MAD_F(0x04e08ab8) /* 0.304819795 */, 19 }, /* 7994 */ { MAD_F(0x04e0c00a) /* 0.304870644 */, 19 }, /* 7995 */ { MAD_F(0x04e0f55c) /* 0.304921495 */, 19 }, /* 7996 */ { MAD_F(0x04e12aaf) /* 0.304972348 */, 19 }, /* 7997 */ { MAD_F(0x04e16002) /* 0.305023203 */, 19 }, /* 7998 */ { MAD_F(0x04e19556) /* 0.305074060 */, 19 }, /* 7999 */ { MAD_F(0x04e1caab) /* 0.305124920 */, 19 }, /* 8000 */ { MAD_F(0x04e20000) /* 0.305175781 */, 19 }, /* 8001 */ { MAD_F(0x04e23555) /* 0.305226645 */, 19 }, /* 8002 */ { MAD_F(0x04e26aac) /* 0.305277511 */, 19 }, /* 8003 */ { MAD_F(0x04e2a002) /* 0.305328379 */, 19 }, /* 8004 */ { MAD_F(0x04e2d55a) /* 0.305379249 */, 19 }, /* 8005 */ { MAD_F(0x04e30ab2) /* 0.305430121 */, 19 }, /* 8006 */ { MAD_F(0x04e3400a) /* 0.305480995 */, 19 }, /* 8007 */ { MAD_F(0x04e37563) /* 0.305531872 */, 19 }, /* 8008 */ { MAD_F(0x04e3aabd) /* 0.305582750 */, 19 }, /* 8009 */ { MAD_F(0x04e3e017) /* 0.305633631 */, 19 }, /* 8010 */ { MAD_F(0x04e41572) /* 0.305684513 */, 19 }, /* 8011 */ { MAD_F(0x04e44acd) /* 0.305735398 */, 19 }, /* 8012 */ { MAD_F(0x04e48029) /* 0.305786285 */, 19 }, /* 8013 */ { MAD_F(0x04e4b585) /* 0.305837174 */, 19 }, /* 8014 */ { MAD_F(0x04e4eae2) /* 0.305888066 */, 19 }, /* 8015 */ { MAD_F(0x04e52040) /* 0.305938959 */, 19 }, /* 8016 */ { MAD_F(0x04e5559e) /* 0.305989854 */, 19 }, /* 8017 */ { MAD_F(0x04e58afd) /* 0.306040752 */, 19 }, /* 8018 */ { MAD_F(0x04e5c05c) /* 0.306091652 */, 19 }, /* 8019 */ { MAD_F(0x04e5f5bc) /* 0.306142554 */, 19 }, /* 8020 */ { MAD_F(0x04e62b1c) /* 0.306193457 */, 19 }, /* 8021 */ { MAD_F(0x04e6607d) /* 0.306244364 */, 19 }, /* 8022 */ { MAD_F(0x04e695df) /* 0.306295272 */, 19 }, /* 8023 */ { MAD_F(0x04e6cb41) /* 0.306346182 */, 19 }, /* 8024 */ { MAD_F(0x04e700a3) /* 0.306397094 */, 19 }, /* 8025 */ { MAD_F(0x04e73607) /* 0.306448009 */, 19 }, /* 8026 */ { MAD_F(0x04e76b6b) /* 0.306498925 */, 19 }, /* 8027 */ { MAD_F(0x04e7a0cf) /* 0.306549844 */, 19 }, /* 8028 */ { MAD_F(0x04e7d634) /* 0.306600765 */, 19 }, /* 8029 */ { MAD_F(0x04e80b99) /* 0.306651688 */, 19 }, /* 8030 */ { MAD_F(0x04e84100) /* 0.306702613 */, 19 }, /* 8031 */ { MAD_F(0x04e87666) /* 0.306753540 */, 19 }, /* 8032 */ { MAD_F(0x04e8abcd) /* 0.306804470 */, 19 }, /* 8033 */ { MAD_F(0x04e8e135) /* 0.306855401 */, 19 }, /* 8034 */ { MAD_F(0x04e9169e) /* 0.306906334 */, 19 }, /* 8035 */ { MAD_F(0x04e94c07) /* 0.306957270 */, 19 }, /* 8036 */ { MAD_F(0x04e98170) /* 0.307008208 */, 19 }, /* 8037 */ { MAD_F(0x04e9b6da) /* 0.307059148 */, 19 }, /* 8038 */ { MAD_F(0x04e9ec45) /* 0.307110090 */, 19 }, /* 8039 */ { MAD_F(0x04ea21b0) /* 0.307161034 */, 19 }, /* 8040 */ { MAD_F(0x04ea571c) /* 0.307211980 */, 19 }, /* 8041 */ { MAD_F(0x04ea8c88) /* 0.307262928 */, 19 }, /* 8042 */ { MAD_F(0x04eac1f5) /* 0.307313879 */, 19 }, /* 8043 */ { MAD_F(0x04eaf762) /* 0.307364831 */, 19 }, /* 8044 */ { MAD_F(0x04eb2cd0) /* 0.307415786 */, 19 }, /* 8045 */ { MAD_F(0x04eb623f) /* 0.307466743 */, 19 }, /* 8046 */ { MAD_F(0x04eb97ae) /* 0.307517702 */, 19 }, /* 8047 */ { MAD_F(0x04ebcd1e) /* 0.307568663 */, 19 }, /* 8048 */ { MAD_F(0x04ec028e) /* 0.307619626 */, 19 }, /* 8049 */ { MAD_F(0x04ec37ff) /* 0.307670591 */, 19 }, /* 8050 */ { MAD_F(0x04ec6d71) /* 0.307721558 */, 19 }, /* 8051 */ { MAD_F(0x04eca2e3) /* 0.307772528 */, 19 }, /* 8052 */ { MAD_F(0x04ecd855) /* 0.307823499 */, 19 }, /* 8053 */ { MAD_F(0x04ed0dc8) /* 0.307874473 */, 19 }, /* 8054 */ { MAD_F(0x04ed433c) /* 0.307925449 */, 19 }, /* 8055 */ { MAD_F(0x04ed78b0) /* 0.307976426 */, 19 }, /* 8056 */ { MAD_F(0x04edae25) /* 0.308027406 */, 19 }, /* 8057 */ { MAD_F(0x04ede39a) /* 0.308078389 */, 19 }, /* 8058 */ { MAD_F(0x04ee1910) /* 0.308129373 */, 19 }, /* 8059 */ { MAD_F(0x04ee4e87) /* 0.308180359 */, 19 }, /* 8060 */ { MAD_F(0x04ee83fe) /* 0.308231347 */, 19 }, /* 8061 */ { MAD_F(0x04eeb976) /* 0.308282338 */, 19 }, /* 8062 */ { MAD_F(0x04eeeeee) /* 0.308333331 */, 19 }, /* 8063 */ { MAD_F(0x04ef2467) /* 0.308384325 */, 19 }, /* 8064 */ { MAD_F(0x04ef59e0) /* 0.308435322 */, 19 }, /* 8065 */ { MAD_F(0x04ef8f5a) /* 0.308486321 */, 19 }, /* 8066 */ { MAD_F(0x04efc4d5) /* 0.308537322 */, 19 }, /* 8067 */ { MAD_F(0x04effa50) /* 0.308588325 */, 19 }, /* 8068 */ { MAD_F(0x04f02fcb) /* 0.308639331 */, 19 }, /* 8069 */ { MAD_F(0x04f06547) /* 0.308690338 */, 19 }, /* 8070 */ { MAD_F(0x04f09ac4) /* 0.308741348 */, 19 }, /* 8071 */ { MAD_F(0x04f0d041) /* 0.308792359 */, 19 }, /* 8072 */ { MAD_F(0x04f105bf) /* 0.308843373 */, 19 }, /* 8073 */ { MAD_F(0x04f13b3e) /* 0.308894389 */, 19 }, /* 8074 */ { MAD_F(0x04f170bd) /* 0.308945407 */, 19 }, /* 8075 */ { MAD_F(0x04f1a63c) /* 0.308996427 */, 19 }, /* 8076 */ { MAD_F(0x04f1dbbd) /* 0.309047449 */, 19 }, /* 8077 */ { MAD_F(0x04f2113d) /* 0.309098473 */, 19 }, /* 8078 */ { MAD_F(0x04f246bf) /* 0.309149499 */, 19 }, /* 8079 */ { MAD_F(0x04f27c40) /* 0.309200528 */, 19 }, /* 8080 */ { MAD_F(0x04f2b1c3) /* 0.309251558 */, 19 }, /* 8081 */ { MAD_F(0x04f2e746) /* 0.309302591 */, 19 }, /* 8082 */ { MAD_F(0x04f31cc9) /* 0.309353626 */, 19 }, /* 8083 */ { MAD_F(0x04f3524d) /* 0.309404663 */, 19 }, /* 8084 */ { MAD_F(0x04f387d2) /* 0.309455702 */, 19 }, /* 8085 */ { MAD_F(0x04f3bd57) /* 0.309506743 */, 19 }, /* 8086 */ { MAD_F(0x04f3f2dd) /* 0.309557786 */, 19 }, /* 8087 */ { MAD_F(0x04f42864) /* 0.309608831 */, 19 }, /* 8088 */ { MAD_F(0x04f45dea) /* 0.309659879 */, 19 }, /* 8089 */ { MAD_F(0x04f49372) /* 0.309710928 */, 19 }, /* 8090 */ { MAD_F(0x04f4c8fa) /* 0.309761980 */, 19 }, /* 8091 */ { MAD_F(0x04f4fe83) /* 0.309813033 */, 19 }, /* 8092 */ { MAD_F(0x04f5340c) /* 0.309864089 */, 19 }, /* 8093 */ { MAD_F(0x04f56996) /* 0.309915147 */, 19 }, /* 8094 */ { MAD_F(0x04f59f20) /* 0.309966207 */, 19 }, /* 8095 */ { MAD_F(0x04f5d4ab) /* 0.310017269 */, 19 }, /* 8096 */ { MAD_F(0x04f60a36) /* 0.310068333 */, 19 }, /* 8097 */ { MAD_F(0x04f63fc2) /* 0.310119400 */, 19 }, /* 8098 */ { MAD_F(0x04f6754f) /* 0.310170468 */, 19 }, /* 8099 */ { MAD_F(0x04f6aadc) /* 0.310221539 */, 19 }, /* 8100 */ { MAD_F(0x04f6e06a) /* 0.310272611 */, 19 }, /* 8101 */ { MAD_F(0x04f715f8) /* 0.310323686 */, 19 }, /* 8102 */ { MAD_F(0x04f74b87) /* 0.310374763 */, 19 }, /* 8103 */ { MAD_F(0x04f78116) /* 0.310425842 */, 19 }, /* 8104 */ { MAD_F(0x04f7b6a6) /* 0.310476923 */, 19 }, /* 8105 */ { MAD_F(0x04f7ec37) /* 0.310528006 */, 19 }, /* 8106 */ { MAD_F(0x04f821c8) /* 0.310579091 */, 19 }, /* 8107 */ { MAD_F(0x04f85759) /* 0.310630179 */, 19 }, /* 8108 */ { MAD_F(0x04f88cec) /* 0.310681268 */, 19 }, /* 8109 */ { MAD_F(0x04f8c27e) /* 0.310732360 */, 19 }, /* 8110 */ { MAD_F(0x04f8f812) /* 0.310783453 */, 19 }, /* 8111 */ { MAD_F(0x04f92da6) /* 0.310834549 */, 19 }, /* 8112 */ { MAD_F(0x04f9633a) /* 0.310885647 */, 19 }, /* 8113 */ { MAD_F(0x04f998cf) /* 0.310936747 */, 19 }, /* 8114 */ { MAD_F(0x04f9ce65) /* 0.310987849 */, 19 }, /* 8115 */ { MAD_F(0x04fa03fb) /* 0.311038953 */, 19 }, /* 8116 */ { MAD_F(0x04fa3992) /* 0.311090059 */, 19 }, /* 8117 */ { MAD_F(0x04fa6f29) /* 0.311141168 */, 19 }, /* 8118 */ { MAD_F(0x04faa4c1) /* 0.311192278 */, 19 }, /* 8119 */ { MAD_F(0x04fada59) /* 0.311243390 */, 19 }, /* 8120 */ { MAD_F(0x04fb0ff2) /* 0.311294505 */, 19 }, /* 8121 */ { MAD_F(0x04fb458c) /* 0.311345622 */, 19 }, /* 8122 */ { MAD_F(0x04fb7b26) /* 0.311396741 */, 19 }, /* 8123 */ { MAD_F(0x04fbb0c1) /* 0.311447862 */, 19 }, /* 8124 */ { MAD_F(0x04fbe65c) /* 0.311498985 */, 19 }, /* 8125 */ { MAD_F(0x04fc1bf8) /* 0.311550110 */, 19 }, /* 8126 */ { MAD_F(0x04fc5194) /* 0.311601237 */, 19 }, /* 8127 */ { MAD_F(0x04fc8731) /* 0.311652366 */, 19 }, /* 8128 */ { MAD_F(0x04fcbcce) /* 0.311703498 */, 19 }, /* 8129 */ { MAD_F(0x04fcf26c) /* 0.311754631 */, 19 }, /* 8130 */ { MAD_F(0x04fd280b) /* 0.311805767 */, 19 }, /* 8131 */ { MAD_F(0x04fd5daa) /* 0.311856905 */, 19 }, /* 8132 */ { MAD_F(0x04fd934a) /* 0.311908044 */, 19 }, /* 8133 */ { MAD_F(0x04fdc8ea) /* 0.311959186 */, 19 }, /* 8134 */ { MAD_F(0x04fdfe8b) /* 0.312010330 */, 19 }, /* 8135 */ { MAD_F(0x04fe342c) /* 0.312061476 */, 19 }, /* 8136 */ { MAD_F(0x04fe69ce) /* 0.312112625 */, 19 }, /* 8137 */ { MAD_F(0x04fe9f71) /* 0.312163775 */, 19 }, /* 8138 */ { MAD_F(0x04fed514) /* 0.312214927 */, 19 }, /* 8139 */ { MAD_F(0x04ff0ab8) /* 0.312266082 */, 19 }, /* 8140 */ { MAD_F(0x04ff405c) /* 0.312317238 */, 19 }, /* 8141 */ { MAD_F(0x04ff7601) /* 0.312368397 */, 19 }, /* 8142 */ { MAD_F(0x04ffaba6) /* 0.312419558 */, 19 }, /* 8143 */ { MAD_F(0x04ffe14c) /* 0.312470720 */, 19 }, /* 8144 */ { MAD_F(0x050016f3) /* 0.312521885 */, 19 }, /* 8145 */ { MAD_F(0x05004c9a) /* 0.312573052 */, 19 }, /* 8146 */ { MAD_F(0x05008241) /* 0.312624222 */, 19 }, /* 8147 */ { MAD_F(0x0500b7e9) /* 0.312675393 */, 19 }, /* 8148 */ { MAD_F(0x0500ed92) /* 0.312726566 */, 19 }, /* 8149 */ { MAD_F(0x0501233b) /* 0.312777742 */, 19 }, /* 8150 */ { MAD_F(0x050158e5) /* 0.312828919 */, 19 }, /* 8151 */ { MAD_F(0x05018e90) /* 0.312880099 */, 19 }, /* 8152 */ { MAD_F(0x0501c43b) /* 0.312931280 */, 19 }, /* 8153 */ { MAD_F(0x0501f9e6) /* 0.312982464 */, 19 }, /* 8154 */ { MAD_F(0x05022f92) /* 0.313033650 */, 19 }, /* 8155 */ { MAD_F(0x0502653f) /* 0.313084838 */, 19 }, /* 8156 */ { MAD_F(0x05029aec) /* 0.313136028 */, 19 }, /* 8157 */ { MAD_F(0x0502d09a) /* 0.313187220 */, 19 }, /* 8158 */ { MAD_F(0x05030648) /* 0.313238414 */, 19 }, /* 8159 */ { MAD_F(0x05033bf7) /* 0.313289611 */, 19 }, /* 8160 */ { MAD_F(0x050371a7) /* 0.313340809 */, 19 }, /* 8161 */ { MAD_F(0x0503a757) /* 0.313392010 */, 19 }, /* 8162 */ { MAD_F(0x0503dd07) /* 0.313443212 */, 19 }, /* 8163 */ { MAD_F(0x050412b9) /* 0.313494417 */, 19 }, /* 8164 */ { MAD_F(0x0504486a) /* 0.313545624 */, 19 }, /* 8165 */ { MAD_F(0x05047e1d) /* 0.313596833 */, 19 }, /* 8166 */ { MAD_F(0x0504b3cf) /* 0.313648044 */, 19 }, /* 8167 */ { MAD_F(0x0504e983) /* 0.313699257 */, 19 }, /* 8168 */ { MAD_F(0x05051f37) /* 0.313750472 */, 19 }, /* 8169 */ { MAD_F(0x050554eb) /* 0.313801689 */, 19 }, /* 8170 */ { MAD_F(0x05058aa0) /* 0.313852909 */, 19 }, /* 8171 */ { MAD_F(0x0505c056) /* 0.313904130 */, 19 }, /* 8172 */ { MAD_F(0x0505f60c) /* 0.313955354 */, 19 }, /* 8173 */ { MAD_F(0x05062bc3) /* 0.314006579 */, 19 }, /* 8174 */ { MAD_F(0x0506617a) /* 0.314057807 */, 19 }, /* 8175 */ { MAD_F(0x05069732) /* 0.314109037 */, 19 }, /* 8176 */ { MAD_F(0x0506cceb) /* 0.314160269 */, 19 }, /* 8177 */ { MAD_F(0x050702a4) /* 0.314211502 */, 19 }, /* 8178 */ { MAD_F(0x0507385d) /* 0.314262739 */, 19 }, /* 8179 */ { MAD_F(0x05076e17) /* 0.314313977 */, 19 }, /* 8180 */ { MAD_F(0x0507a3d2) /* 0.314365217 */, 19 }, /* 8181 */ { MAD_F(0x0507d98d) /* 0.314416459 */, 19 }, /* 8182 */ { MAD_F(0x05080f49) /* 0.314467704 */, 19 }, /* 8183 */ { MAD_F(0x05084506) /* 0.314518950 */, 19 }, /* 8184 */ { MAD_F(0x05087ac2) /* 0.314570199 */, 19 }, /* 8185 */ { MAD_F(0x0508b080) /* 0.314621449 */, 19 }, /* 8186 */ { MAD_F(0x0508e63e) /* 0.314672702 */, 19 }, /* 8187 */ { MAD_F(0x05091bfd) /* 0.314723957 */, 19 }, /* 8188 */ { MAD_F(0x050951bc) /* 0.314775214 */, 19 }, /* 8189 */ { MAD_F(0x0509877c) /* 0.314826473 */, 19 }, /* 8190 */ { MAD_F(0x0509bd3c) /* 0.314877734 */, 19 }, /* 8191 */ { MAD_F(0x0509f2fd) /* 0.314928997 */, 19 }, /* 8192 */ { MAD_F(0x050a28be) /* 0.314980262 */, 19 }, /* 8193 */ { MAD_F(0x050a5e80) /* 0.315031530 */, 19 }, /* 8194 */ { MAD_F(0x050a9443) /* 0.315082799 */, 19 }, /* 8195 */ { MAD_F(0x050aca06) /* 0.315134071 */, 19 }, /* 8196 */ { MAD_F(0x050affc9) /* 0.315185344 */, 19 }, /* 8197 */ { MAD_F(0x050b358e) /* 0.315236620 */, 19 }, /* 8198 */ { MAD_F(0x050b6b52) /* 0.315287898 */, 19 }, /* 8199 */ { MAD_F(0x050ba118) /* 0.315339178 */, 19 }, /* 8200 */ { MAD_F(0x050bd6de) /* 0.315390460 */, 19 }, /* 8201 */ { MAD_F(0x050c0ca4) /* 0.315441744 */, 19 }, /* 8202 */ { MAD_F(0x050c426b) /* 0.315493030 */, 19 }, /* 8203 */ { MAD_F(0x050c7833) /* 0.315544318 */, 19 }, /* 8204 */ { MAD_F(0x050cadfb) /* 0.315595608 */, 19 }, /* 8205 */ { MAD_F(0x050ce3c4) /* 0.315646901 */, 19 }, /* 8206 */ { MAD_F(0x050d198d) /* 0.315698195 */, 19 } praat-6.0.04/external/mp3/mad_sf_table.dat000066400000000000000000000146411261542461700203410ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: sf_table.dat,v 1.7 2004/01/23 09:41:33 rob Exp $ */ /* * These are the scalefactor values for Layer I and Layer II. * The values are from Table B.1 of ISO/IEC 11172-3. * * There is some error introduced by the 32-bit fixed-point representation; * the amount of error is shown. For 16-bit PCM output, this shouldn't be * too much of a problem. * * Strictly speaking, Table B.1 has only 63 entries (0-62), thus a strict * interpretation of ISO/IEC 11172-3 would suggest that a scalefactor index of * 63 is invalid. However, for better compatibility with current practices, we * add a 64th entry. */ MAD_F(0x20000000), /* 2.000000000000 => 2.000000000000, e 0.000000000000 */ MAD_F(0x1965fea5), /* 1.587401051968 => 1.587401051074, e 0.000000000894 */ MAD_F(0x1428a2fa), /* 1.259921049895 => 1.259921051562, e -0.000000001667 */ MAD_F(0x10000000), /* 1.000000000000 => 1.000000000000, e 0.000000000000 */ MAD_F(0x0cb2ff53), /* 0.793700525984 => 0.793700527400, e -0.000000001416 */ MAD_F(0x0a14517d), /* 0.629960524947 => 0.629960525781, e -0.000000000833 */ MAD_F(0x08000000), /* 0.500000000000 => 0.500000000000, e 0.000000000000 */ MAD_F(0x06597fa9), /* 0.396850262992 => 0.396850261837, e 0.000000001155 */ MAD_F(0x050a28be), /* 0.314980262474 => 0.314980261028, e 0.000000001446 */ MAD_F(0x04000000), /* 0.250000000000 => 0.250000000000, e 0.000000000000 */ MAD_F(0x032cbfd5), /* 0.198425131496 => 0.198425132781, e -0.000000001285 */ MAD_F(0x0285145f), /* 0.157490131237 => 0.157490130514, e 0.000000000723 */ MAD_F(0x02000000), /* 0.125000000000 => 0.125000000000, e 0.000000000000 */ MAD_F(0x01965fea), /* 0.099212565748 => 0.099212564528, e 0.000000001220 */ MAD_F(0x01428a30), /* 0.078745065618 => 0.078745067120, e -0.000000001501 */ MAD_F(0x01000000), /* 0.062500000000 => 0.062500000000, e 0.000000000000 */ MAD_F(0x00cb2ff5), /* 0.049606282874 => 0.049606282264, e 0.000000000610 */ MAD_F(0x00a14518), /* 0.039372532809 => 0.039372533560, e -0.000000000751 */ MAD_F(0x00800000), /* 0.031250000000 => 0.031250000000, e 0.000000000000 */ MAD_F(0x006597fb), /* 0.024803141437 => 0.024803142995, e -0.000000001558 */ MAD_F(0x0050a28c), /* 0.019686266405 => 0.019686266780, e -0.000000000375 */ MAD_F(0x00400000), /* 0.015625000000 => 0.015625000000, e 0.000000000000 */ MAD_F(0x0032cbfd), /* 0.012401570719 => 0.012401569635, e 0.000000001084 */ MAD_F(0x00285146), /* 0.009843133202 => 0.009843133390, e -0.000000000188 */ MAD_F(0x00200000), /* 0.007812500000 => 0.007812500000, e 0.000000000000 */ MAD_F(0x001965ff), /* 0.006200785359 => 0.006200786680, e -0.000000001321 */ MAD_F(0x001428a3), /* 0.004921566601 => 0.004921566695, e -0.000000000094 */ MAD_F(0x00100000), /* 0.003906250000 => 0.003906250000, e 0.000000000000 */ MAD_F(0x000cb2ff), /* 0.003100392680 => 0.003100391477, e 0.000000001202 */ MAD_F(0x000a1451), /* 0.002460783301 => 0.002460781485, e 0.000000001816 */ MAD_F(0x00080000), /* 0.001953125000 => 0.001953125000, e 0.000000000000 */ MAD_F(0x00065980), /* 0.001550196340 => 0.001550197601, e -0.000000001262 */ MAD_F(0x00050a29), /* 0.001230391650 => 0.001230392605, e -0.000000000955 */ MAD_F(0x00040000), /* 0.000976562500 => 0.000976562500, e 0.000000000000 */ MAD_F(0x00032cc0), /* 0.000775098170 => 0.000775098801, e -0.000000000631 */ MAD_F(0x00028514), /* 0.000615195825 => 0.000615194440, e 0.000000001385 */ MAD_F(0x00020000), /* 0.000488281250 => 0.000488281250, e 0.000000000000 */ MAD_F(0x00019660), /* 0.000387549085 => 0.000387549400, e -0.000000000315 */ MAD_F(0x0001428a), /* 0.000307597913 => 0.000307597220, e 0.000000000693 */ MAD_F(0x00010000), /* 0.000244140625 => 0.000244140625, e 0.000000000000 */ MAD_F(0x0000cb30), /* 0.000193774542 => 0.000193774700, e -0.000000000158 */ MAD_F(0x0000a145), /* 0.000153798956 => 0.000153798610, e 0.000000000346 */ MAD_F(0x00008000), /* 0.000122070313 => 0.000122070313, e 0.000000000000 */ MAD_F(0x00006598), /* 0.000096887271 => 0.000096887350, e -0.000000000079 */ MAD_F(0x000050a3), /* 0.000076899478 => 0.000076901168, e -0.000000001689 */ MAD_F(0x00004000), /* 0.000061035156 => 0.000061035156, e 0.000000000000 */ MAD_F(0x000032cc), /* 0.000048443636 => 0.000048443675, e -0.000000000039 */ MAD_F(0x00002851), /* 0.000038449739 => 0.000038448721, e 0.000000001018 */ MAD_F(0x00002000), /* 0.000030517578 => 0.000030517578, e 0.000000000000 */ MAD_F(0x00001966), /* 0.000024221818 => 0.000024221838, e -0.000000000020 */ MAD_F(0x00001429), /* 0.000019224870 => 0.000019226223, e -0.000000001354 */ MAD_F(0x00001000), /* 0.000015258789 => 0.000015258789, e -0.000000000000 */ MAD_F(0x00000cb3), /* 0.000012110909 => 0.000012110919, e -0.000000000010 */ MAD_F(0x00000a14), /* 0.000009612435 => 0.000009611249, e 0.000000001186 */ MAD_F(0x00000800), /* 0.000007629395 => 0.000007629395, e -0.000000000000 */ MAD_F(0x00000659), /* 0.000006055454 => 0.000006053597, e 0.000000001858 */ MAD_F(0x0000050a), /* 0.000004806217 => 0.000004805624, e 0.000000000593 */ MAD_F(0x00000400), /* 0.000003814697 => 0.000003814697, e 0.000000000000 */ MAD_F(0x0000032d), /* 0.000003027727 => 0.000003028661, e -0.000000000934 */ MAD_F(0x00000285), /* 0.000002403109 => 0.000002402812, e 0.000000000296 */ MAD_F(0x00000200), /* 0.000001907349 => 0.000001907349, e -0.000000000000 */ MAD_F(0x00000196), /* 0.000001513864 => 0.000001512468, e 0.000000001396 */ MAD_F(0x00000143), /* 0.000001201554 => 0.000001203269, e -0.000000001714 */ MAD_F(0x00000000) /* this compatibility entry is not part of Table B.1 */ praat-6.0.04/external/mp3/mad_stream.c000066400000000000000000000114341261542461700175240ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: stream.c,v 1.12 2004/02/05 09:02:39 rob Exp $ */ /*# ifdef HAVE_CONFIG_H*/ # include "mad_config.h" /*# endif*/ # include "mad_global.h" # include # include "mad_bit.h" # include "mad_stream.h" /* * NAME: stream->init() * DESCRIPTION: initialize stream struct */ void mad_stream_init(struct mad_stream *stream) { stream->buffer = 0; stream->bufend = 0; stream->skiplen = 0; stream->sync = 0; stream->freerate = 0; stream->this_frame = 0; stream->next_frame = 0; mad_bit_init(&stream->ptr, 0); mad_bit_init(&stream->anc_ptr, 0); stream->anc_bitlen = 0; stream->main_data = 0; stream->md_len = 0; stream->options = 0; stream->error = MAD_ERROR_NONE; stream->this_offset = 0; /* Erez Volk */ } /* * NAME: stream->finish() * DESCRIPTION: deallocate any dynamic memory associated with stream */ void mad_stream_finish(struct mad_stream *stream) { if (stream->main_data) { free(stream->main_data); stream->main_data = 0; } mad_bit_finish(&stream->anc_ptr); mad_bit_finish(&stream->ptr); } /* * NAME: stream->buffer() * DESCRIPTION: set stream buffer pointers */ void mad_stream_buffer(struct mad_stream *stream, unsigned char const *buffer, unsigned long length) { stream->buffer = buffer; stream->bufend = buffer + length; stream->this_frame = buffer; stream->next_frame = buffer; stream->sync = 1; mad_bit_init(&stream->ptr, buffer); } /* * NAME: stream->buffer_offset() * DESCRIPTION: set stream buffer pointers and offset * Erez Volk */ void mad_stream_buffer_offset(struct mad_stream *stream, unsigned char const *buffer, unsigned long length, unsigned long offset) { mad_stream_buffer(stream, buffer, length); stream->this_offset = offset; } /* * NAME: stream->skip() * DESCRIPTION: arrange to skip bytes before the next frame */ void mad_stream_skip(struct mad_stream *stream, unsigned long length) { stream->skiplen += length; } /* * NAME: stream->sync() * DESCRIPTION: locate the next stream sync word */ int mad_stream_sync(struct mad_stream *stream) { register unsigned char const *ptr, *end; ptr = mad_bit_nextbyte(&stream->ptr); end = stream->bufend; while (ptr < end - 1 && !(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) { ++ptr; } if (end - ptr < MAD_BUFFER_GUARD) return -1; mad_bit_init(&stream->ptr, ptr); return 0; } /* * NAME: stream->errorstr() * DESCRIPTION: return a string description of the current error condition */ char const *mad_stream_errorstr(struct mad_stream const *stream) { switch (stream->error) { case MAD_ERROR_NONE: return "no error"; case MAD_ERROR_BUFLEN: return "input buffer too small (or EOF)"; case MAD_ERROR_BUFPTR: return "invalid (null) buffer pointer"; case MAD_ERROR_NOMEM: return "not enough memory"; case MAD_ERROR_LOSTSYNC: return "lost synchronization"; case MAD_ERROR_BADLAYER: return "reserved header layer value"; case MAD_ERROR_BADBITRATE: return "forbidden bitrate value"; case MAD_ERROR_BADSAMPLERATE: return "reserved sample frequency value"; case MAD_ERROR_BADEMPHASIS: return "reserved emphasis value"; case MAD_ERROR_BADCRC: return "CRC check failed"; case MAD_ERROR_BADBITALLOC: return "forbidden bit allocation value"; case MAD_ERROR_BADSCALEFACTOR: return "bad scalefactor index"; case MAD_ERROR_BADMODE: return "bad bitrate/mode combination"; case MAD_ERROR_BADFRAMELEN: return "bad frame length"; case MAD_ERROR_BADBIGVALUES: return "bad big_values count"; case MAD_ERROR_BADBLOCKTYPE: return "reserved block_type"; case MAD_ERROR_BADSCFSI: return "bad scalefactor selection info"; case MAD_ERROR_BADDATAPTR: return "bad main_data_begin pointer"; case MAD_ERROR_BADPART3LEN: return "bad audio data length"; case MAD_ERROR_BADHUFFTABLE: return "bad Huffman table select"; case MAD_ERROR_BADHUFFDATA: return "Huffman data overrun"; case MAD_ERROR_BADSTEREO: return "incompatible block_type for JS"; } return 0; } praat-6.0.04/external/mp3/mad_stream.h000066400000000000000000000105721261542461700175330ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: stream.h,v 1.20 2004/02/05 09:02:39 rob Exp $ */ # ifndef LIBMAD_STREAM_H # define LIBMAD_STREAM_H # include "mad_bit.h" # define MAD_BUFFER_GUARD 8 # define MAD_BUFFER_MDLEN (511 + 2048 + MAD_BUFFER_GUARD) enum mad_error { MAD_ERROR_NONE = 0x0000, /* no error */ MAD_ERROR_BUFLEN = 0x0001, /* input buffer too small (or EOF) */ MAD_ERROR_BUFPTR = 0x0002, /* invalid (null) buffer pointer */ MAD_ERROR_NOMEM = 0x0031, /* not enough memory */ MAD_ERROR_LOSTSYNC = 0x0101, /* lost synchronization */ MAD_ERROR_BADLAYER = 0x0102, /* reserved header layer value */ MAD_ERROR_BADBITRATE = 0x0103, /* forbidden bitrate value */ MAD_ERROR_BADSAMPLERATE = 0x0104, /* reserved sample frequency value */ MAD_ERROR_BADEMPHASIS = 0x0105, /* reserved emphasis value */ MAD_ERROR_BADCRC = 0x0201, /* CRC check failed */ MAD_ERROR_BADBITALLOC = 0x0211, /* forbidden bit allocation value */ MAD_ERROR_BADSCALEFACTOR = 0x0221, /* bad scalefactor index */ MAD_ERROR_BADMODE = 0x0222, /* bad bitrate/mode combination */ MAD_ERROR_BADFRAMELEN = 0x0231, /* bad frame length */ MAD_ERROR_BADBIGVALUES = 0x0232, /* bad big_values count */ MAD_ERROR_BADBLOCKTYPE = 0x0233, /* reserved block_type */ MAD_ERROR_BADSCFSI = 0x0234, /* bad scalefactor selection info */ MAD_ERROR_BADDATAPTR = 0x0235, /* bad main_data_begin pointer */ MAD_ERROR_BADPART3LEN = 0x0236, /* bad audio data length */ MAD_ERROR_BADHUFFTABLE = 0x0237, /* bad Huffman table select */ MAD_ERROR_BADHUFFDATA = 0x0238, /* Huffman data overrun */ MAD_ERROR_BADSTEREO = 0x0239 /* incompatible block_type for JS */ }; # define MAD_RECOVERABLE(error) ((error) & 0xff00) struct mad_stream { unsigned char const *buffer; /* input bitstream buffer */ unsigned char const *bufend; /* end of buffer */ unsigned long skiplen; /* bytes to skip before next frame */ int sync; /* stream sync found */ unsigned long freerate; /* free bitrate (fixed) */ unsigned char const *this_frame; /* start of current frame */ unsigned char const *next_frame; /* start of next frame */ struct mad_bitptr ptr; /* current processing bit pointer */ struct mad_bitptr anc_ptr; /* ancillary bits pointer */ unsigned int anc_bitlen; /* number of ancillary bits */ unsigned char (*main_data)[MAD_BUFFER_MDLEN]; /* Layer III main_data() */ unsigned int md_len; /* bytes in main_data */ int options; /* decoding options (see below) */ enum mad_error error; /* error code (see above) */ /* Erez Volk 2007-05-30: */ unsigned long this_offset; /* Offset in stream of current frame */ }; enum { MAD_OPTION_IGNORECRC = 0x0001, /* ignore CRC errors */ MAD_OPTION_HALFSAMPLERATE = 0x0002 /* generate PCM at 1/2 sample rate */ # if 0 /* not yet implemented */ MAD_OPTION_LEFTCHANNEL = 0x0010, /* decode left channel only */ MAD_OPTION_RIGHTCHANNEL = 0x0020, /* decode right channel only */ MAD_OPTION_SINGLECHANNEL = 0x0030 /* combine channels */ # endif }; void mad_stream_init(struct mad_stream *); void mad_stream_finish(struct mad_stream *); # define mad_stream_options(stream, opts) \ ((void) ((stream)->options = (opts))) void mad_stream_buffer(struct mad_stream *, unsigned char const *, unsigned long); void mad_stream_skip(struct mad_stream *, unsigned long); /* Erez Volk */ void mad_stream_buffer_offset(struct mad_stream *, unsigned char const *, unsigned long, unsigned long); int mad_stream_sync(struct mad_stream *); char const *mad_stream_errorstr(struct mad_stream const *); # endif praat-6.0.04/external/mp3/mad_synth.c000066400000000000000000000575161261542461700174110ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: synth.c,v 1.25 2004/01/23 09:41:33 rob Exp $ */ /*# ifdef HAVE_CONFIG_H*/ # include "mad_config.h" /*# endif*/ # include "mad_global.h" # include "mad_fixed.h" # include "mad_frame.h" # include "mad_synth.h" /* * NAME: synth->init() * DESCRIPTION: initialize synth struct */ void mad_synth_init(struct mad_synth *synth) { mad_synth_mute(synth); synth->phase = 0; synth->pcm.samplerate = 0; synth->pcm.channels = 0; synth->pcm.length = 0; } /* * NAME: synth->mute() * DESCRIPTION: zero all polyphase filterbank values, resetting synthesis */ void mad_synth_mute(struct mad_synth *synth) { unsigned int ch, s, v; for (ch = 0; ch < 2; ++ch) { for (s = 0; s < 16; ++s) { for (v = 0; v < 8; ++v) { synth->filter[ch][0][0][s][v] = synth->filter[ch][0][1][s][v] = synth->filter[ch][1][0][s][v] = synth->filter[ch][1][1][s][v] = 0; } } } } /* * An optional optimization called here the Subband Synthesis Optimization * (SSO) improves the performance of subband synthesis at the expense of * accuracy. * * The idea is to simplify 32x32->64-bit multiplication to 32x32->32 such * that extra scaling and rounding are not necessary. This often allows the * compiler to use faster 32-bit multiply-accumulate instructions instead of * explicit 64-bit multiply, shift, and add instructions. * * SSO works like this: a full 32x32->64-bit multiply of two mad_fixed_t * values requires the result to be right-shifted 28 bits to be properly * scaled to the same fixed-point format. Right shifts can be applied at any * time to either operand or to the result, so the optimization involves * careful placement of these shifts to minimize the loss of accuracy. * * First, a 14-bit shift is applied with rounding at compile-time to the D[] * table of coefficients for the subband synthesis window. This only loses 2 * bits of accuracy because the lower 12 bits are always zero. A second * 12-bit shift occurs after the DCT calculation. This loses 12 bits of * accuracy. Finally, a third 2-bit shift occurs just before the sample is * saved in the PCM buffer. 14 + 12 + 2 == 28 bits. */ /* FPM_DEFAULT without OPT_SSO will actually lose accuracy and performance */ # if defined(FPM_DEFAULT) && !defined(OPT_SSO) # define OPT_SSO # endif /* second SSO shift, with rounding */ # if defined(OPT_SSO) # define SHIFT(x) (((x) + (1L << 11)) >> 12) # else # define SHIFT(x) (x) # endif /* possible DCT speed optimization */ # if defined(OPT_SPEED) && defined(MAD_F_MLX) # define OPT_DCTO # define MUL(x, y) \ ({ mad_fixed64hi_t hi; \ mad_fixed64lo_t lo; \ MAD_F_MLX(hi, lo, (x), (y)); \ hi << (32 - MAD_F_SCALEBITS - 3); \ }) # else # undef OPT_DCTO # define MUL(x, y) mad_f_mul((x), (y)) # endif /* * NAME: dct32() * DESCRIPTION: perform fast in[32]->out[32] DCT */ static void dct32(mad_fixed_t const in[32], unsigned int slot, mad_fixed_t lo[16][8], mad_fixed_t hi[16][8]) { mad_fixed_t t0, t1, t2, t3, t4, t5, t6, t7; mad_fixed_t t8, t9, t10, t11, t12, t13, t14, t15; mad_fixed_t t16, t17, t18, t19, t20, t21, t22, t23; mad_fixed_t t24, t25, t26, t27, t28, t29, t30, t31; mad_fixed_t t32, t33, t34, t35, t36, t37, t38, t39; mad_fixed_t t40, t41, t42, t43, t44, t45, t46, t47; mad_fixed_t t48, t49, t50, t51, t52, t53, t54, t55; mad_fixed_t t56, t57, t58, t59, t60, t61, t62, t63; mad_fixed_t t64, t65, t66, t67, t68, t69, t70, t71; mad_fixed_t t72, t73, t74, t75, t76, t77, t78, t79; mad_fixed_t t80, t81, t82, t83, t84, t85, t86, t87; mad_fixed_t t88, t89, t90, t91, t92, t93, t94, t95; mad_fixed_t t96, t97, t98, t99, t100, t101, t102, t103; mad_fixed_t t104, t105, t106, t107, t108, t109, t110, t111; mad_fixed_t t112, t113, t114, t115, t116, t117, t118, t119; mad_fixed_t t120, t121, t122, t123, t124, t125, t126, t127; mad_fixed_t t128, t129, t130, t131, t132, t133, t134, t135; mad_fixed_t t136, t137, t138, t139, t140, t141, t142, t143; mad_fixed_t t144, t145, t146, t147, t148, t149, t150, t151; mad_fixed_t t152, t153, t154, t155, t156, t157, t158, t159; mad_fixed_t t160, t161, t162, t163, t164, t165, t166, t167; mad_fixed_t t168, t169, t170, t171, t172, t173, t174, t175; mad_fixed_t t176; /* costab[i] = cos(PI / (2 * 32) * i) */ # if defined(OPT_DCTO) # define costab1 MAD_F(0x7fd8878e) # define costab2 MAD_F(0x7f62368f) # define costab3 MAD_F(0x7e9d55fc) # define costab4 MAD_F(0x7d8a5f40) # define costab5 MAD_F(0x7c29fbee) # define costab6 MAD_F(0x7a7d055b) # define costab7 MAD_F(0x78848414) # define costab8 MAD_F(0x7641af3d) # define costab9 MAD_F(0x73b5ebd1) # define costab10 MAD_F(0x70e2cbc6) # define costab11 MAD_F(0x6dca0d14) # define costab12 MAD_F(0x6a6d98a4) # define costab13 MAD_F(0x66cf8120) # define costab14 MAD_F(0x62f201ac) # define costab15 MAD_F(0x5ed77c8a) # define costab16 MAD_F(0x5a82799a) # define costab17 MAD_F(0x55f5a4d2) # define costab18 MAD_F(0x5133cc94) # define costab19 MAD_F(0x4c3fdff4) # define costab20 MAD_F(0x471cece7) # define costab21 MAD_F(0x41ce1e65) # define costab22 MAD_F(0x3c56ba70) # define costab23 MAD_F(0x36ba2014) # define costab24 MAD_F(0x30fbc54d) # define costab25 MAD_F(0x2b1f34eb) # define costab26 MAD_F(0x25280c5e) # define costab27 MAD_F(0x1f19f97b) # define costab28 MAD_F(0x18f8b83c) # define costab29 MAD_F(0x12c8106f) # define costab30 MAD_F(0x0c8bd35e) # define costab31 MAD_F(0x0647d97c) # else # define costab1 MAD_F(0x0ffb10f2) /* 0.998795456 */ # define costab2 MAD_F(0x0fec46d2) /* 0.995184727 */ # define costab3 MAD_F(0x0fd3aac0) /* 0.989176510 */ # define costab4 MAD_F(0x0fb14be8) /* 0.980785280 */ # define costab5 MAD_F(0x0f853f7e) /* 0.970031253 */ # define costab6 MAD_F(0x0f4fa0ab) /* 0.956940336 */ # define costab7 MAD_F(0x0f109082) /* 0.941544065 */ # define costab8 MAD_F(0x0ec835e8) /* 0.923879533 */ # define costab9 MAD_F(0x0e76bd7a) /* 0.903989293 */ # define costab10 MAD_F(0x0e1c5979) /* 0.881921264 */ # define costab11 MAD_F(0x0db941a3) /* 0.857728610 */ # define costab12 MAD_F(0x0d4db315) /* 0.831469612 */ # define costab13 MAD_F(0x0cd9f024) /* 0.803207531 */ # define costab14 MAD_F(0x0c5e4036) /* 0.773010453 */ # define costab15 MAD_F(0x0bdaef91) /* 0.740951125 */ # define costab16 MAD_F(0x0b504f33) /* 0.707106781 */ # define costab17 MAD_F(0x0abeb49a) /* 0.671558955 */ # define costab18 MAD_F(0x0a267993) /* 0.634393284 */ # define costab19 MAD_F(0x0987fbfe) /* 0.595699304 */ # define costab20 MAD_F(0x08e39d9d) /* 0.555570233 */ # define costab21 MAD_F(0x0839c3cd) /* 0.514102744 */ # define costab22 MAD_F(0x078ad74e) /* 0.471396737 */ # define costab23 MAD_F(0x06d74402) /* 0.427555093 */ # define costab24 MAD_F(0x061f78aa) /* 0.382683432 */ # define costab25 MAD_F(0x0563e69d) /* 0.336889853 */ # define costab26 MAD_F(0x04a5018c) /* 0.290284677 */ # define costab27 MAD_F(0x03e33f2f) /* 0.242980180 */ # define costab28 MAD_F(0x031f1708) /* 0.195090322 */ # define costab29 MAD_F(0x0259020e) /* 0.146730474 */ # define costab30 MAD_F(0x01917a6c) /* 0.098017140 */ # define costab31 MAD_F(0x00c8fb30) /* 0.049067674 */ # endif t0 = in[0] + in[31]; t16 = MUL(in[0] - in[31], costab1); t1 = in[15] + in[16]; t17 = MUL(in[15] - in[16], costab31); t41 = t16 + t17; t59 = MUL(t16 - t17, costab2); t33 = t0 + t1; t50 = MUL(t0 - t1, costab2); t2 = in[7] + in[24]; t18 = MUL(in[7] - in[24], costab15); t3 = in[8] + in[23]; t19 = MUL(in[8] - in[23], costab17); t42 = t18 + t19; t60 = MUL(t18 - t19, costab30); t34 = t2 + t3; t51 = MUL(t2 - t3, costab30); t4 = in[3] + in[28]; t20 = MUL(in[3] - in[28], costab7); t5 = in[12] + in[19]; t21 = MUL(in[12] - in[19], costab25); t43 = t20 + t21; t61 = MUL(t20 - t21, costab14); t35 = t4 + t5; t52 = MUL(t4 - t5, costab14); t6 = in[4] + in[27]; t22 = MUL(in[4] - in[27], costab9); t7 = in[11] + in[20]; t23 = MUL(in[11] - in[20], costab23); t44 = t22 + t23; t62 = MUL(t22 - t23, costab18); t36 = t6 + t7; t53 = MUL(t6 - t7, costab18); t8 = in[1] + in[30]; t24 = MUL(in[1] - in[30], costab3); t9 = in[14] + in[17]; t25 = MUL(in[14] - in[17], costab29); t45 = t24 + t25; t63 = MUL(t24 - t25, costab6); t37 = t8 + t9; t54 = MUL(t8 - t9, costab6); t10 = in[6] + in[25]; t26 = MUL(in[6] - in[25], costab13); t11 = in[9] + in[22]; t27 = MUL(in[9] - in[22], costab19); t46 = t26 + t27; t64 = MUL(t26 - t27, costab26); t38 = t10 + t11; t55 = MUL(t10 - t11, costab26); t12 = in[2] + in[29]; t28 = MUL(in[2] - in[29], costab5); t13 = in[13] + in[18]; t29 = MUL(in[13] - in[18], costab27); t47 = t28 + t29; t65 = MUL(t28 - t29, costab10); t39 = t12 + t13; t56 = MUL(t12 - t13, costab10); t14 = in[5] + in[26]; t30 = MUL(in[5] - in[26], costab11); t15 = in[10] + in[21]; t31 = MUL(in[10] - in[21], costab21); t48 = t30 + t31; t66 = MUL(t30 - t31, costab22); t40 = t14 + t15; t57 = MUL(t14 - t15, costab22); t69 = t33 + t34; t89 = MUL(t33 - t34, costab4); t70 = t35 + t36; t90 = MUL(t35 - t36, costab28); t71 = t37 + t38; t91 = MUL(t37 - t38, costab12); t72 = t39 + t40; t92 = MUL(t39 - t40, costab20); t73 = t41 + t42; t94 = MUL(t41 - t42, costab4); t74 = t43 + t44; t95 = MUL(t43 - t44, costab28); t75 = t45 + t46; t96 = MUL(t45 - t46, costab12); t76 = t47 + t48; t97 = MUL(t47 - t48, costab20); t78 = t50 + t51; t100 = MUL(t50 - t51, costab4); t79 = t52 + t53; t101 = MUL(t52 - t53, costab28); t80 = t54 + t55; t102 = MUL(t54 - t55, costab12); t81 = t56 + t57; t103 = MUL(t56 - t57, costab20); t83 = t59 + t60; t106 = MUL(t59 - t60, costab4); t84 = t61 + t62; t107 = MUL(t61 - t62, costab28); t85 = t63 + t64; t108 = MUL(t63 - t64, costab12); t86 = t65 + t66; t109 = MUL(t65 - t66, costab20); t113 = t69 + t70; t114 = t71 + t72; /* 0 */ hi[15][slot] = SHIFT(t113 + t114); /* 16 */ lo[ 0][slot] = SHIFT(MUL(t113 - t114, costab16)); t115 = t73 + t74; t116 = t75 + t76; t32 = t115 + t116; /* 1 */ hi[14][slot] = SHIFT(t32); t118 = t78 + t79; t119 = t80 + t81; t58 = t118 + t119; /* 2 */ hi[13][slot] = SHIFT(t58); t121 = t83 + t84; t122 = t85 + t86; t67 = t121 + t122; t49 = (t67 * 2) - t32; /* 3 */ hi[12][slot] = SHIFT(t49); t125 = t89 + t90; t126 = t91 + t92; t93 = t125 + t126; /* 4 */ hi[11][slot] = SHIFT(t93); t128 = t94 + t95; t129 = t96 + t97; t98 = t128 + t129; t68 = (t98 * 2) - t49; /* 5 */ hi[10][slot] = SHIFT(t68); t132 = t100 + t101; t133 = t102 + t103; t104 = t132 + t133; t82 = (t104 * 2) - t58; /* 6 */ hi[ 9][slot] = SHIFT(t82); t136 = t106 + t107; t137 = t108 + t109; t110 = t136 + t137; t87 = (t110 * 2) - t67; t77 = (t87 * 2) - t68; /* 7 */ hi[ 8][slot] = SHIFT(t77); t141 = MUL(t69 - t70, costab8); t142 = MUL(t71 - t72, costab24); t143 = t141 + t142; /* 8 */ hi[ 7][slot] = SHIFT(t143); /* 24 */ lo[ 8][slot] = SHIFT((MUL(t141 - t142, costab16) * 2) - t143); t144 = MUL(t73 - t74, costab8); t145 = MUL(t75 - t76, costab24); t146 = t144 + t145; t88 = (t146 * 2) - t77; /* 9 */ hi[ 6][slot] = SHIFT(t88); t148 = MUL(t78 - t79, costab8); t149 = MUL(t80 - t81, costab24); t150 = t148 + t149; t105 = (t150 * 2) - t82; /* 10 */ hi[ 5][slot] = SHIFT(t105); t152 = MUL(t83 - t84, costab8); t153 = MUL(t85 - t86, costab24); t154 = t152 + t153; t111 = (t154 * 2) - t87; t99 = (t111 * 2) - t88; /* 11 */ hi[ 4][slot] = SHIFT(t99); t157 = MUL(t89 - t90, costab8); t158 = MUL(t91 - t92, costab24); t159 = t157 + t158; t127 = (t159 * 2) - t93; /* 12 */ hi[ 3][slot] = SHIFT(t127); t160 = (MUL(t125 - t126, costab16) * 2) - t127; /* 20 */ lo[ 4][slot] = SHIFT(t160); /* 28 */ lo[12][slot] = SHIFT((((MUL(t157 - t158, costab16) * 2) - t159) * 2) - t160); t161 = MUL(t94 - t95, costab8); t162 = MUL(t96 - t97, costab24); t163 = t161 + t162; t130 = (t163 * 2) - t98; t112 = (t130 * 2) - t99; /* 13 */ hi[ 2][slot] = SHIFT(t112); t164 = (MUL(t128 - t129, costab16) * 2) - t130; t166 = MUL(t100 - t101, costab8); t167 = MUL(t102 - t103, costab24); t168 = t166 + t167; t134 = (t168 * 2) - t104; t120 = (t134 * 2) - t105; /* 14 */ hi[ 1][slot] = SHIFT(t120); t135 = (MUL(t118 - t119, costab16) * 2) - t120; /* 18 */ lo[ 2][slot] = SHIFT(t135); t169 = (MUL(t132 - t133, costab16) * 2) - t134; t151 = (t169 * 2) - t135; /* 22 */ lo[ 6][slot] = SHIFT(t151); t170 = (((MUL(t148 - t149, costab16) * 2) - t150) * 2) - t151; /* 26 */ lo[10][slot] = SHIFT(t170); /* 30 */ lo[14][slot] = SHIFT((((((MUL(t166 - t167, costab16) * 2) - t168) * 2) - t169) * 2) - t170); t171 = MUL(t106 - t107, costab8); t172 = MUL(t108 - t109, costab24); t173 = t171 + t172; t138 = (t173 * 2) - t110; t123 = (t138 * 2) - t111; t139 = (MUL(t121 - t122, costab16) * 2) - t123; t117 = (t123 * 2) - t112; /* 15 */ hi[ 0][slot] = SHIFT(t117); t124 = (MUL(t115 - t116, costab16) * 2) - t117; /* 17 */ lo[ 1][slot] = SHIFT(t124); t131 = (t139 * 2) - t124; /* 19 */ lo[ 3][slot] = SHIFT(t131); t140 = (t164 * 2) - t131; /* 21 */ lo[ 5][slot] = SHIFT(t140); t174 = (MUL(t136 - t137, costab16) * 2) - t138; t155 = (t174 * 2) - t139; t147 = (t155 * 2) - t140; /* 23 */ lo[ 7][slot] = SHIFT(t147); t156 = (((MUL(t144 - t145, costab16) * 2) - t146) * 2) - t147; /* 25 */ lo[ 9][slot] = SHIFT(t156); t175 = (((MUL(t152 - t153, costab16) * 2) - t154) * 2) - t155; t165 = (t175 * 2) - t156; /* 27 */ lo[11][slot] = SHIFT(t165); t176 = (((((MUL(t161 - t162, costab16) * 2) - t163) * 2) - t164) * 2) - t165; /* 29 */ lo[13][slot] = SHIFT(t176); /* 31 */ lo[15][slot] = SHIFT((((((((MUL(t171 - t172, costab16) * 2) - t173) * 2) - t174) * 2) - t175) * 2) - t176); /* * Totals: * 80 multiplies * 80 additions * 119 subtractions * 49 shifts (not counting SSO) */ } # undef MUL # undef SHIFT /* third SSO shift and/or D[] optimization preshift */ # if defined(OPT_SSO) # if MAD_F_FRACBITS != 28 # error "MAD_F_FRACBITS must be 28 to use OPT_SSO" # endif # define ML0(hi, lo, x, y) ((lo) = (x) * (y)) # define MLA(hi, lo, x, y) ((lo) += (x) * (y)) # define MLN(hi, lo) ((lo) = -(lo)) # define MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo)) # define SHIFT(x) ((x) >> 2) # define PRESHIFT(x) ((MAD_F(x) + (1L << 13)) >> 14) # else # define ML0(hi, lo, x, y) MAD_F_ML0((hi), (lo), (x), (y)) # define MLA(hi, lo, x, y) MAD_F_MLA((hi), (lo), (x), (y)) # define MLN(hi, lo) MAD_F_MLN((hi), (lo)) # define MLZ(hi, lo) MAD_F_MLZ((hi), (lo)) # define SHIFT(x) (x) # if defined(MAD_F_SCALEBITS) # undef MAD_F_SCALEBITS # define MAD_F_SCALEBITS (MAD_F_FRACBITS - 12) # define PRESHIFT(x) (MAD_F(x) >> 12) # else # define PRESHIFT(x) MAD_F(x) # endif # endif static mad_fixed_t const D[17][32] = { # include "mad_D.dat" }; # if defined(ASO_SYNTH) void synth_full(struct mad_synth *, struct mad_frame const *, unsigned int, unsigned int); # else /* * NAME: synth->full() * DESCRIPTION: perform full frequency PCM synthesis */ static void synth_full(struct mad_synth *synth, struct mad_frame const *frame, unsigned int nch, unsigned int ns) { unsigned int phase, ch, s, sb, pe, po; mad_fixed_t *pcm1, *pcm2, (*filter)[2][2][16][8]; mad_fixed_t const (*sbsample)[36][32]; register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8]; register mad_fixed_t const (*Dptr)[32], *ptr; register mad_fixed64hi_t hi; register mad_fixed64lo_t lo; for (ch = 0; ch < nch; ++ch) { sbsample = &frame->sbsample[ch]; filter = &synth->filter[ch]; phase = synth->phase; pcm1 = synth->pcm.samples[ch]; for (s = 0; s < ns; ++s) { dct32((*sbsample)[s], phase >> 1, (*filter)[0][phase & 1], (*filter)[1][phase & 1]); pe = phase & ~1; po = ((phase - 1) & 0xf) | 1; /* calculate 32 samples */ fe = &(*filter)[0][ phase & 1][0]; fx = &(*filter)[0][~phase & 1][0]; fo = &(*filter)[1][~phase & 1][0]; Dptr = &D[0]; ptr = *Dptr + po; ML0(hi, lo, (*fx)[0], ptr[ 0]); MLA(hi, lo, (*fx)[1], ptr[14]); MLA(hi, lo, (*fx)[2], ptr[12]); MLA(hi, lo, (*fx)[3], ptr[10]); MLA(hi, lo, (*fx)[4], ptr[ 8]); MLA(hi, lo, (*fx)[5], ptr[ 6]); MLA(hi, lo, (*fx)[6], ptr[ 4]); MLA(hi, lo, (*fx)[7], ptr[ 2]); MLN(hi, lo); ptr = *Dptr + pe; MLA(hi, lo, (*fe)[0], ptr[ 0]); MLA(hi, lo, (*fe)[1], ptr[14]); MLA(hi, lo, (*fe)[2], ptr[12]); MLA(hi, lo, (*fe)[3], ptr[10]); MLA(hi, lo, (*fe)[4], ptr[ 8]); MLA(hi, lo, (*fe)[5], ptr[ 6]); MLA(hi, lo, (*fe)[6], ptr[ 4]); MLA(hi, lo, (*fe)[7], ptr[ 2]); *pcm1++ = SHIFT(MLZ(hi, lo)); pcm2 = pcm1 + 30; for (sb = 1; sb < 16; ++sb) { ++fe; ++Dptr; /* D[32 - sb][i] == -D[sb][31 - i] */ ptr = *Dptr + po; ML0(hi, lo, (*fo)[0], ptr[ 0]); MLA(hi, lo, (*fo)[1], ptr[14]); MLA(hi, lo, (*fo)[2], ptr[12]); MLA(hi, lo, (*fo)[3], ptr[10]); MLA(hi, lo, (*fo)[4], ptr[ 8]); MLA(hi, lo, (*fo)[5], ptr[ 6]); MLA(hi, lo, (*fo)[6], ptr[ 4]); MLA(hi, lo, (*fo)[7], ptr[ 2]); MLN(hi, lo); ptr = *Dptr + pe; MLA(hi, lo, (*fe)[7], ptr[ 2]); MLA(hi, lo, (*fe)[6], ptr[ 4]); MLA(hi, lo, (*fe)[5], ptr[ 6]); MLA(hi, lo, (*fe)[4], ptr[ 8]); MLA(hi, lo, (*fe)[3], ptr[10]); MLA(hi, lo, (*fe)[2], ptr[12]); MLA(hi, lo, (*fe)[1], ptr[14]); MLA(hi, lo, (*fe)[0], ptr[ 0]); *pcm1++ = SHIFT(MLZ(hi, lo)); ptr = *Dptr - pe; ML0(hi, lo, (*fe)[0], ptr[31 - 16]); MLA(hi, lo, (*fe)[1], ptr[31 - 14]); MLA(hi, lo, (*fe)[2], ptr[31 - 12]); MLA(hi, lo, (*fe)[3], ptr[31 - 10]); MLA(hi, lo, (*fe)[4], ptr[31 - 8]); MLA(hi, lo, (*fe)[5], ptr[31 - 6]); MLA(hi, lo, (*fe)[6], ptr[31 - 4]); MLA(hi, lo, (*fe)[7], ptr[31 - 2]); ptr = *Dptr - po; MLA(hi, lo, (*fo)[7], ptr[31 - 2]); MLA(hi, lo, (*fo)[6], ptr[31 - 4]); MLA(hi, lo, (*fo)[5], ptr[31 - 6]); MLA(hi, lo, (*fo)[4], ptr[31 - 8]); MLA(hi, lo, (*fo)[3], ptr[31 - 10]); MLA(hi, lo, (*fo)[2], ptr[31 - 12]); MLA(hi, lo, (*fo)[1], ptr[31 - 14]); MLA(hi, lo, (*fo)[0], ptr[31 - 16]); *pcm2-- = SHIFT(MLZ(hi, lo)); ++fo; } ++Dptr; ptr = *Dptr + po; ML0(hi, lo, (*fo)[0], ptr[ 0]); MLA(hi, lo, (*fo)[1], ptr[14]); MLA(hi, lo, (*fo)[2], ptr[12]); MLA(hi, lo, (*fo)[3], ptr[10]); MLA(hi, lo, (*fo)[4], ptr[ 8]); MLA(hi, lo, (*fo)[5], ptr[ 6]); MLA(hi, lo, (*fo)[6], ptr[ 4]); MLA(hi, lo, (*fo)[7], ptr[ 2]); *pcm1 = SHIFT(-MLZ(hi, lo)); pcm1 += 16; phase = (phase + 1) % 16; } } } # endif /* * NAME: synth->half() * DESCRIPTION: perform half frequency PCM synthesis */ static void synth_half(struct mad_synth *synth, struct mad_frame const *frame, unsigned int nch, unsigned int ns) { unsigned int phase, ch, s, sb, pe, po; mad_fixed_t *pcm1, *pcm2, (*filter)[2][2][16][8]; mad_fixed_t const (*sbsample)[36][32]; register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8]; register mad_fixed_t const (*Dptr)[32], *ptr; register mad_fixed64hi_t hi; register mad_fixed64lo_t lo; for (ch = 0; ch < nch; ++ch) { sbsample = &frame->sbsample[ch]; filter = &synth->filter[ch]; phase = synth->phase; pcm1 = synth->pcm.samples[ch]; for (s = 0; s < ns; ++s) { dct32((*sbsample)[s], phase >> 1, (*filter)[0][phase & 1], (*filter)[1][phase & 1]); pe = phase & ~1; po = ((phase - 1) & 0xf) | 1; /* calculate 16 samples */ fe = &(*filter)[0][ phase & 1][0]; fx = &(*filter)[0][~phase & 1][0]; fo = &(*filter)[1][~phase & 1][0]; Dptr = &D[0]; ptr = *Dptr + po; ML0(hi, lo, (*fx)[0], ptr[ 0]); MLA(hi, lo, (*fx)[1], ptr[14]); MLA(hi, lo, (*fx)[2], ptr[12]); MLA(hi, lo, (*fx)[3], ptr[10]); MLA(hi, lo, (*fx)[4], ptr[ 8]); MLA(hi, lo, (*fx)[5], ptr[ 6]); MLA(hi, lo, (*fx)[6], ptr[ 4]); MLA(hi, lo, (*fx)[7], ptr[ 2]); MLN(hi, lo); ptr = *Dptr + pe; MLA(hi, lo, (*fe)[0], ptr[ 0]); MLA(hi, lo, (*fe)[1], ptr[14]); MLA(hi, lo, (*fe)[2], ptr[12]); MLA(hi, lo, (*fe)[3], ptr[10]); MLA(hi, lo, (*fe)[4], ptr[ 8]); MLA(hi, lo, (*fe)[5], ptr[ 6]); MLA(hi, lo, (*fe)[6], ptr[ 4]); MLA(hi, lo, (*fe)[7], ptr[ 2]); *pcm1++ = SHIFT(MLZ(hi, lo)); pcm2 = pcm1 + 14; for (sb = 1; sb < 16; ++sb) { ++fe; ++Dptr; /* D[32 - sb][i] == -D[sb][31 - i] */ if (!(sb & 1)) { ptr = *Dptr + po; ML0(hi, lo, (*fo)[0], ptr[ 0]); MLA(hi, lo, (*fo)[1], ptr[14]); MLA(hi, lo, (*fo)[2], ptr[12]); MLA(hi, lo, (*fo)[3], ptr[10]); MLA(hi, lo, (*fo)[4], ptr[ 8]); MLA(hi, lo, (*fo)[5], ptr[ 6]); MLA(hi, lo, (*fo)[6], ptr[ 4]); MLA(hi, lo, (*fo)[7], ptr[ 2]); MLN(hi, lo); ptr = *Dptr + pe; MLA(hi, lo, (*fe)[7], ptr[ 2]); MLA(hi, lo, (*fe)[6], ptr[ 4]); MLA(hi, lo, (*fe)[5], ptr[ 6]); MLA(hi, lo, (*fe)[4], ptr[ 8]); MLA(hi, lo, (*fe)[3], ptr[10]); MLA(hi, lo, (*fe)[2], ptr[12]); MLA(hi, lo, (*fe)[1], ptr[14]); MLA(hi, lo, (*fe)[0], ptr[ 0]); *pcm1++ = SHIFT(MLZ(hi, lo)); ptr = *Dptr - po; ML0(hi, lo, (*fo)[7], ptr[31 - 2]); MLA(hi, lo, (*fo)[6], ptr[31 - 4]); MLA(hi, lo, (*fo)[5], ptr[31 - 6]); MLA(hi, lo, (*fo)[4], ptr[31 - 8]); MLA(hi, lo, (*fo)[3], ptr[31 - 10]); MLA(hi, lo, (*fo)[2], ptr[31 - 12]); MLA(hi, lo, (*fo)[1], ptr[31 - 14]); MLA(hi, lo, (*fo)[0], ptr[31 - 16]); ptr = *Dptr - pe; MLA(hi, lo, (*fe)[0], ptr[31 - 16]); MLA(hi, lo, (*fe)[1], ptr[31 - 14]); MLA(hi, lo, (*fe)[2], ptr[31 - 12]); MLA(hi, lo, (*fe)[3], ptr[31 - 10]); MLA(hi, lo, (*fe)[4], ptr[31 - 8]); MLA(hi, lo, (*fe)[5], ptr[31 - 6]); MLA(hi, lo, (*fe)[6], ptr[31 - 4]); MLA(hi, lo, (*fe)[7], ptr[31 - 2]); *pcm2-- = SHIFT(MLZ(hi, lo)); } ++fo; } ++Dptr; ptr = *Dptr + po; ML0(hi, lo, (*fo)[0], ptr[ 0]); MLA(hi, lo, (*fo)[1], ptr[14]); MLA(hi, lo, (*fo)[2], ptr[12]); MLA(hi, lo, (*fo)[3], ptr[10]); MLA(hi, lo, (*fo)[4], ptr[ 8]); MLA(hi, lo, (*fo)[5], ptr[ 6]); MLA(hi, lo, (*fo)[6], ptr[ 4]); MLA(hi, lo, (*fo)[7], ptr[ 2]); *pcm1 = SHIFT(-MLZ(hi, lo)); pcm1 += 8; phase = (phase + 1) % 16; } } } /* * NAME: synth->frame() * DESCRIPTION: perform PCM synthesis of frame subband samples */ void mad_synth_frame(struct mad_synth *synth, struct mad_frame const *frame) { unsigned int nch, ns; void (*synth_frame)(struct mad_synth *, struct mad_frame const *, unsigned int, unsigned int); nch = MAD_NCHANNELS(&frame->header); ns = MAD_NSBSAMPLES(&frame->header); synth->pcm.samplerate = frame->header.samplerate; synth->pcm.channels = nch; synth->pcm.length = 32 * ns; synth_frame = synth_full; if (frame->options & MAD_OPTION_HALFSAMPLERATE) { synth->pcm.samplerate /= 2; synth->pcm.length /= 2; synth_frame = synth_half; } synth_frame(synth, frame, nch, ns); synth->phase = (synth->phase + ns) % 16; } praat-6.0.04/external/mp3/mad_synth.h000066400000000000000000000036461261542461700174110ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: synth.h,v 1.15 2004/01/23 09:41:33 rob Exp $ */ # ifndef LIBMAD_SYNTH_H # define LIBMAD_SYNTH_H # include "mad_fixed.h" # include "mad_frame.h" struct mad_pcm { unsigned int samplerate; /* sampling frequency (Hz) */ unsigned short channels; /* number of channels */ unsigned short length; /* number of samples per channel */ mad_fixed_t samples[2][1152]; /* PCM output samples [ch][sample] */ }; struct mad_synth { mad_fixed_t filter[2][2][2][16][8]; /* polyphase filterbank outputs */ /* [ch][eo][peo][s][v] */ unsigned int phase; /* current processing phase */ struct mad_pcm pcm; /* PCM output */ }; /* single channel PCM selector */ enum { MAD_PCM_CHANNEL_SINGLE = 0 }; /* dual channel PCM selector */ enum { MAD_PCM_CHANNEL_DUAL_1 = 0, MAD_PCM_CHANNEL_DUAL_2 = 1 }; /* stereo PCM selector */ enum { MAD_PCM_CHANNEL_STEREO_LEFT = 0, MAD_PCM_CHANNEL_STEREO_RIGHT = 1 }; void mad_synth_init(struct mad_synth *); # define mad_synth_finish(synth) /* nothing */ void mad_synth_mute(struct mad_synth *); void mad_synth_frame(struct mad_synth *, struct mad_frame const *); # endif praat-6.0.04/external/mp3/mad_timer.c000066400000000000000000000245451261542461700173600ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: timer.c,v 1.18 2004/01/23 09:41:33 rob Exp $ */ /*# ifdef HAVE_CONFIG_H*/ # include "mad_config.h" /*# endif*/ # include "mad_global.h" # include # ifdef HAVE_ASSERT_H # include # endif # include "mad_timer.h" mad_timer_t const mad_timer_zero = { 0, 0 }; /* * NAME: timer->compare() * DESCRIPTION: indicate relative order of two timers */ int mad_timer_compare(mad_timer_t timer1, mad_timer_t timer2) { signed long diff; diff = timer1.seconds - timer2.seconds; if (diff < 0) return -1; else if (diff > 0) return +1; diff = timer1.fraction - timer2.fraction; if (diff < 0) return -1; else if (diff > 0) return +1; return 0; } /* * NAME: timer->negate() * DESCRIPTION: invert the sign of a timer */ void mad_timer_negate(mad_timer_t *timer) { timer->seconds = -timer->seconds; if (timer->fraction) { timer->seconds -= 1; timer->fraction = MAD_TIMER_RESOLUTION - timer->fraction; } } /* * NAME: timer->abs() * DESCRIPTION: return the absolute value of a timer */ mad_timer_t mad_timer_abs(mad_timer_t timer) { if (timer.seconds < 0) mad_timer_negate(&timer); return timer; } /* * NAME: reduce_timer() * DESCRIPTION: carry timer fraction into seconds */ static void reduce_timer(mad_timer_t *timer) { timer->seconds += timer->fraction / MAD_TIMER_RESOLUTION; timer->fraction %= MAD_TIMER_RESOLUTION; } /* * NAME: gcd() * DESCRIPTION: compute greatest common denominator */ static unsigned long gcd(unsigned long num1, unsigned long num2) { unsigned long tmp; while (num2) { tmp = num2; num2 = num1 % num2; num1 = tmp; } return num1; } /* * NAME: reduce_rational() * DESCRIPTION: convert rational expression to lowest terms */ static void reduce_rational(unsigned long *numer, unsigned long *denom) { unsigned long factor; factor = gcd(*numer, *denom); assert(factor != 0); *numer /= factor; *denom /= factor; } /* * NAME: scale_rational() * DESCRIPTION: solve numer/denom == ?/scale avoiding overflowing */ static unsigned long scale_rational(unsigned long numer, unsigned long denom, unsigned long scale) { reduce_rational(&numer, &denom); reduce_rational(&scale, &denom); assert(denom != 0); if (denom < scale) return numer * (scale / denom) + numer * (scale % denom) / denom; if (denom < numer) return scale * (numer / denom) + scale * (numer % denom) / denom; return numer * scale / denom; } /* * NAME: timer->set() * DESCRIPTION: set timer to specific (positive) value */ void mad_timer_set(mad_timer_t *timer, unsigned long seconds, unsigned long numer, unsigned long denom) { timer->seconds = seconds; if (numer >= denom && denom > 0) { timer->seconds += numer / denom; numer %= denom; } switch (denom) { case 0: case 1: timer->fraction = 0; break; case MAD_TIMER_RESOLUTION: timer->fraction = numer; break; case 1000: timer->fraction = numer * (MAD_TIMER_RESOLUTION / 1000); break; case 8000: timer->fraction = numer * (MAD_TIMER_RESOLUTION / 8000); break; case 11025: timer->fraction = numer * (MAD_TIMER_RESOLUTION / 11025); break; case 12000: timer->fraction = numer * (MAD_TIMER_RESOLUTION / 12000); break; case 16000: timer->fraction = numer * (MAD_TIMER_RESOLUTION / 16000); break; case 22050: timer->fraction = numer * (MAD_TIMER_RESOLUTION / 22050); break; case 24000: timer->fraction = numer * (MAD_TIMER_RESOLUTION / 24000); break; case 32000: timer->fraction = numer * (MAD_TIMER_RESOLUTION / 32000); break; case 44100: timer->fraction = numer * (MAD_TIMER_RESOLUTION / 44100); break; case 48000: timer->fraction = numer * (MAD_TIMER_RESOLUTION / 48000); break; default: timer->fraction = scale_rational(numer, denom, MAD_TIMER_RESOLUTION); break; } if (timer->fraction >= MAD_TIMER_RESOLUTION) reduce_timer(timer); } /* * NAME: timer->add() * DESCRIPTION: add one timer to another */ void mad_timer_add(mad_timer_t *timer, mad_timer_t incr) { timer->seconds += incr.seconds; timer->fraction += incr.fraction; if (timer->fraction >= MAD_TIMER_RESOLUTION) reduce_timer(timer); } /* * NAME: timer->multiply() * DESCRIPTION: multiply a timer by a scalar value */ void mad_timer_multiply(mad_timer_t *timer, signed long scalar) { mad_timer_t addend; unsigned long factor; factor = scalar; if (scalar < 0) { factor = -scalar; mad_timer_negate(timer); } addend = *timer; *timer = mad_timer_zero; while (factor) { if (factor & 1) mad_timer_add(timer, addend); mad_timer_add(&addend, addend); factor >>= 1; } } /* * NAME: timer->count() * DESCRIPTION: return timer value in selected units */ signed long mad_timer_count(mad_timer_t timer, enum mad_units units) { switch (units) { case MAD_UNITS_HOURS: return timer.seconds / 60 / 60; case MAD_UNITS_MINUTES: return timer.seconds / 60; case MAD_UNITS_SECONDS: return timer.seconds; case MAD_UNITS_DECISECONDS: case MAD_UNITS_CENTISECONDS: case MAD_UNITS_MILLISECONDS: case MAD_UNITS_8000_HZ: case MAD_UNITS_11025_HZ: case MAD_UNITS_12000_HZ: case MAD_UNITS_16000_HZ: case MAD_UNITS_22050_HZ: case MAD_UNITS_24000_HZ: case MAD_UNITS_32000_HZ: case MAD_UNITS_44100_HZ: case MAD_UNITS_48000_HZ: case MAD_UNITS_24_FPS: case MAD_UNITS_25_FPS: case MAD_UNITS_30_FPS: case MAD_UNITS_48_FPS: case MAD_UNITS_50_FPS: case MAD_UNITS_60_FPS: case MAD_UNITS_75_FPS: return timer.seconds * (signed long) units + (signed long) scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, units); case MAD_UNITS_23_976_FPS: case MAD_UNITS_24_975_FPS: case MAD_UNITS_29_97_FPS: case MAD_UNITS_47_952_FPS: case MAD_UNITS_49_95_FPS: case MAD_UNITS_59_94_FPS: return (mad_timer_count(timer, -units) + 1) * 1000 / 1001; } /* unsupported units */ return 0; } /* * NAME: timer->fraction() * DESCRIPTION: return fractional part of timer in arbitrary terms */ unsigned long mad_timer_fraction(mad_timer_t timer, unsigned long denom) { timer = mad_timer_abs(timer); switch (denom) { case 0: return timer.fraction ? MAD_TIMER_RESOLUTION / timer.fraction : MAD_TIMER_RESOLUTION + 1; case MAD_TIMER_RESOLUTION: return timer.fraction; default: return scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, denom); } } /* * NAME: timer->string() * DESCRIPTION: write a string representation of a timer using a template */ void mad_timer_string(mad_timer_t timer, char *dest, char const *format, enum mad_units units, enum mad_units fracunits, unsigned long subparts) { unsigned long hours, minutes, seconds, sub; unsigned int frac; timer = mad_timer_abs(timer); seconds = timer.seconds; frac = sub = 0; switch (fracunits) { case MAD_UNITS_HOURS: case MAD_UNITS_MINUTES: case MAD_UNITS_SECONDS: break; case MAD_UNITS_DECISECONDS: case MAD_UNITS_CENTISECONDS: case MAD_UNITS_MILLISECONDS: case MAD_UNITS_8000_HZ: case MAD_UNITS_11025_HZ: case MAD_UNITS_12000_HZ: case MAD_UNITS_16000_HZ: case MAD_UNITS_22050_HZ: case MAD_UNITS_24000_HZ: case MAD_UNITS_32000_HZ: case MAD_UNITS_44100_HZ: case MAD_UNITS_48000_HZ: case MAD_UNITS_24_FPS: case MAD_UNITS_25_FPS: case MAD_UNITS_30_FPS: case MAD_UNITS_48_FPS: case MAD_UNITS_50_FPS: case MAD_UNITS_60_FPS: case MAD_UNITS_75_FPS: { unsigned long denom; denom = MAD_TIMER_RESOLUTION / fracunits; frac = timer.fraction / denom; sub = scale_rational(timer.fraction % denom, denom, subparts); } break; case MAD_UNITS_23_976_FPS: case MAD_UNITS_24_975_FPS: case MAD_UNITS_29_97_FPS: case MAD_UNITS_47_952_FPS: case MAD_UNITS_49_95_FPS: case MAD_UNITS_59_94_FPS: /* drop-frame encoding */ /* N.B. this is only well-defined for MAD_UNITS_29_97_FPS */ { unsigned long frame, cycle, d, m; frame = mad_timer_count(timer, fracunits); cycle = -fracunits * 60 * 10 - (10 - 1) * 2; d = frame / cycle; m = frame % cycle; frame += (10 - 1) * 2 * d; if (m > 2) frame += 2 * ((m - 2) / (cycle / 10)); frac = frame % -fracunits; seconds = frame / -fracunits; } break; } switch (units) { case MAD_UNITS_HOURS: minutes = seconds / 60; hours = minutes / 60; sprintf(dest, format, hours, (unsigned int) (minutes % 60), (unsigned int) (seconds % 60), frac, sub); break; case MAD_UNITS_MINUTES: minutes = seconds / 60; sprintf(dest, format, minutes, (unsigned int) (seconds % 60), frac, sub); break; case MAD_UNITS_SECONDS: sprintf(dest, format, seconds, frac, sub); break; case MAD_UNITS_23_976_FPS: case MAD_UNITS_24_975_FPS: case MAD_UNITS_29_97_FPS: case MAD_UNITS_47_952_FPS: case MAD_UNITS_49_95_FPS: case MAD_UNITS_59_94_FPS: if (fracunits < 0) { /* not yet implemented */ sub = 0; } /* fall through */ case MAD_UNITS_DECISECONDS: case MAD_UNITS_CENTISECONDS: case MAD_UNITS_MILLISECONDS: case MAD_UNITS_8000_HZ: case MAD_UNITS_11025_HZ: case MAD_UNITS_12000_HZ: case MAD_UNITS_16000_HZ: case MAD_UNITS_22050_HZ: case MAD_UNITS_24000_HZ: case MAD_UNITS_32000_HZ: case MAD_UNITS_44100_HZ: case MAD_UNITS_48000_HZ: case MAD_UNITS_24_FPS: case MAD_UNITS_25_FPS: case MAD_UNITS_30_FPS: case MAD_UNITS_48_FPS: case MAD_UNITS_50_FPS: case MAD_UNITS_60_FPS: case MAD_UNITS_75_FPS: sprintf(dest, format, mad_timer_count(timer, units), sub); break; } } praat-6.0.04/external/mp3/mad_timer.h000066400000000000000000000054771261542461700173700ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: timer.h,v 1.16 2004/01/23 09:41:33 rob Exp $ */ # ifndef LIBMAD_TIMER_H # define LIBMAD_TIMER_H typedef struct { signed long seconds; /* whole seconds */ unsigned long fraction; /* 1/MAD_TIMER_RESOLUTION seconds */ } mad_timer_t; extern mad_timer_t const mad_timer_zero; # define MAD_TIMER_RESOLUTION 352800000UL enum mad_units { MAD_UNITS_HOURS = -2, MAD_UNITS_MINUTES = -1, MAD_UNITS_SECONDS = 0, /* metric units */ MAD_UNITS_DECISECONDS = 10, MAD_UNITS_CENTISECONDS = 100, MAD_UNITS_MILLISECONDS = 1000, /* audio sample units */ MAD_UNITS_8000_HZ = 8000, MAD_UNITS_11025_HZ = 11025, MAD_UNITS_12000_HZ = 12000, MAD_UNITS_16000_HZ = 16000, MAD_UNITS_22050_HZ = 22050, MAD_UNITS_24000_HZ = 24000, MAD_UNITS_32000_HZ = 32000, MAD_UNITS_44100_HZ = 44100, MAD_UNITS_48000_HZ = 48000, /* video frame/field units */ MAD_UNITS_24_FPS = 24, MAD_UNITS_25_FPS = 25, MAD_UNITS_30_FPS = 30, MAD_UNITS_48_FPS = 48, MAD_UNITS_50_FPS = 50, MAD_UNITS_60_FPS = 60, /* CD audio frames */ MAD_UNITS_75_FPS = 75, /* video drop-frame units */ MAD_UNITS_23_976_FPS = -24, MAD_UNITS_24_975_FPS = -25, MAD_UNITS_29_97_FPS = -30, MAD_UNITS_47_952_FPS = -48, MAD_UNITS_49_95_FPS = -50, MAD_UNITS_59_94_FPS = -60 }; # define mad_timer_reset(timer) ((void) (*(timer) = mad_timer_zero)) int mad_timer_compare(mad_timer_t, mad_timer_t); # define mad_timer_sign(timer) mad_timer_compare((timer), mad_timer_zero) void mad_timer_negate(mad_timer_t *); mad_timer_t mad_timer_abs(mad_timer_t); void mad_timer_set(mad_timer_t *, unsigned long, unsigned long, unsigned long); void mad_timer_add(mad_timer_t *, mad_timer_t); void mad_timer_multiply(mad_timer_t *, signed long); signed long mad_timer_count(mad_timer_t, enum mad_units); unsigned long mad_timer_fraction(mad_timer_t, unsigned long); void mad_timer_string(mad_timer_t, char *, char const *, enum mad_units, enum mad_units, unsigned long); # endif praat-6.0.04/external/mp3/mad_version.c000066400000000000000000000041151261542461700177140ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: version.c,v 1.15 2004/01/23 09:41:33 rob Exp $ */ /*# ifdef HAVE_CONFIG_H*/ # include "mad_config.h" /*# endif*/ # include "mad_global.h" # include "mad_version.h" char const mad_version[] = "MPEG Audio Decoder " MAD_VERSION; char const mad_copyright[] = "Copyright (C) " MAD_PUBLISHYEAR " " MAD_AUTHOR; char const mad_author[] = MAD_AUTHOR " <" MAD_EMAIL ">"; char const mad_build[] = "" # if defined(DEBUG) "DEBUG " # elif defined(NDEBUG) "NDEBUG " # endif # if defined(EXPERIMENTAL) "EXPERIMENTAL " # endif # if defined(FPM_64BIT) "FPM_64BIT " # elif defined(FPM_INTEL) "FPM_INTEL " # elif defined(FPM_ARM) "FPM_ARM " # elif defined(FPM_MIPS) "FPM_MIPS " # elif defined(FPM_SPARC) "FPM_SPARC " # elif defined(FPM_PPC) "FPM_PPC " # elif defined(FPM_DEFAULT) "FPM_DEFAULT " # endif # if defined(ASO_IMDCT) "ASO_IMDCT " # endif # if defined(ASO_INTERLEAVE1) "ASO_INTERLEAVE1 " # endif # if defined(ASO_INTERLEAVE2) "ASO_INTERLEAVE2 " # endif # if defined(ASO_ZEROCHECK) "ASO_ZEROCHECK " # endif # if defined(OPT_SPEED) "OPT_SPEED " # elif defined(OPT_ACCURACY) "OPT_ACCURACY " # endif # if defined(OPT_SSO) "OPT_SSO " # endif # if defined(OPT_DCTO) /* never defined here */ "OPT_DCTO " # endif # if defined(OPT_STRICT) "OPT_STRICT " # endif ; praat-6.0.04/external/mp3/mad_version.h000066400000000000000000000031121261542461700177150ustar00rootroot00000000000000/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: version.h,v 1.26 2004/01/23 09:41:33 rob Exp $ */ # ifndef LIBMAD_VERSION_H # define LIBMAD_VERSION_H # define MAD_VERSION_MAJOR 0 # define MAD_VERSION_MINOR 15 # define MAD_VERSION_PATCH 1 # define MAD_VERSION_EXTRA " (beta)" # define MAD_VERSION_STRINGIZE(str) #str # define MAD_VERSION_STRING(num) MAD_VERSION_STRINGIZE(num) # define MAD_VERSION MAD_VERSION_STRING(MAD_VERSION_MAJOR) "." \ MAD_VERSION_STRING(MAD_VERSION_MINOR) "." \ MAD_VERSION_STRING(MAD_VERSION_PATCH) \ MAD_VERSION_EXTRA # define MAD_PUBLISHYEAR "2000-2004" # define MAD_AUTHOR "Underbit Technologies, Inc." # define MAD_EMAIL "info@underbit.com" extern char const mad_version[]; extern char const mad_copyright[]; extern char const mad_author[]; extern char const mad_build[]; # endif praat-6.0.04/external/mp3/mp3.cpp000066400000000000000000000461621261542461700164550ustar00rootroot00000000000000/* * Praat wrappers for libMAD (MPEG Audio Decoder) Copyright 2007 Erez Volk * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * * * Exact seeking in an MP3 file turns out to be quite complex. * * For constant bit rate (CBR) files, frame size is fixed and we can calculate * in advance the location of every frame. * * For variable bit rate (VBR) files, no option gives us more than a rough * estimate of where every percent of the file is lcoated, with no way of * checking (after we make a seek) where we ended up. The only reliable way we * have, then, is to scan the entire file in advance and keep a table with the * offsets of all (or some) frames. In the worst case, we will have to scan * the file *twice*, since we can't know the exact number of frames. * * What's worse, there is no guaranteed standard way of checking whether an MP3 * file is CBR or VBR. We therefore use the following compromise, which is * guaranteed to work on all files: * * - If there is a Xing header, read it to get the number of frames. * - Otherwise *estimate* the number of frames. * - Keep a reasonably (?) sized table of "key" offsets. * - Scan all the headers and keep required offsets in the table. * - After the scan, we also know the precise number of frames and samples. * * TODO: Find exactly what the encoder delay is. * (see http://mp3decoders.mp3-tech.org/decoders_lame.html) * TODO: Compensate for end padding. * TODO: Better conversion to short. * */ /*#define MP3_DEBUG*/ #include #include "mp3.h" #include "melder.h" extern "C" { #include "mad_config.h" #include "mad_decoder.h" } #define MP3F_BUFFER_SIZE (8 * 1024) #define MP3F_MAX_LOCATIONS 1024 /* * MP3 encoders and decoders add a number of silent samples at the beginning. * I don't know of any reliable way to detect these delays in an MP3 file. * The numbers below are (hopefully reasonable) estimates based on LAME and * some testing; it is more important to preserve all the meaningful samples * than to eliminate all silent ones. */ #define MP3F_DECODER_DELAY 529 /*#define MP3F_ENCODER_DELAY 576*/ #define MP3F_ENCODER_DELAY 96 #ifdef MP3_DEBUG # define MP3_DPRINTF(x) printf x # define MP3_PERCENT(base, value) (((float)(value) - (float)(base)) * 100.0 / (float)(base)) #else /* !MP3_DEBUG */ # define MP3_DPRINTF(x) #endif /* MP3_DEBUG */ struct _MP3_FILE { struct mad_decoder decoder; FILE *f; unsigned char buffer [MP3F_BUFFER_SIZE]; int xing; unsigned channels; unsigned frequency; unsigned frames; unsigned samples_per_frame; MP3F_OFFSET samples; MP3F_OFFSET locations[MP3F_MAX_LOCATIONS]; unsigned num_locations; unsigned frames_per_location; unsigned delay; MP3F_CALLBACK callback; void *context; MP3F_OFFSET next_read_position; MP3F_OFFSET read_amount; MP3F_OFFSET first_offset; unsigned skip_amount; int need_seek; MP3F_OFFSET id3TagSize_bytes; /* David Weenink */ }; static enum mad_flow mp3f_mad_error (void *context, struct mad_stream *stream, struct mad_frame *frame); static enum mad_flow mp3f_mad_input (void *context, struct mad_stream *stream); static enum mad_flow mp3f_mad_first_header (void *context, struct mad_header const *header); static enum mad_flow mp3f_mad_first_filter (void *context, struct mad_stream const *stream, struct mad_frame *frame); static int mp3f_check_xing (MP3_FILE mp3f, struct mad_stream const *stream); static enum mad_flow mp3f_mad_scan_header (void *context, struct mad_header const *header); static enum mad_flow mp3f_mad_report_samples (void *context, struct mad_header const *header, struct mad_pcm *pcm); int mp3_recognize (int nread, const char *data) { const unsigned char *bytes = (const unsigned char *)data; if (nread < 3) return 0; /* MP3 files can start with an ID3 tag */ if (bytes [0] == 'I' && bytes [1] == 'D' && bytes [2] == '3') return 1; /* Otherwise the beginning of the file must be an MP3 frame */ if (bytes [0] != 0xFF) return 0; /* This is not a foolproof check, but it is similar to file(1) */ return ((bytes [1] & 0xFE) == 0xFA) || /* MPEG ADTS, layer III, v1 */ ((bytes [1] & 0xFE) == 0xFC) || /* MPEG ADTS, layer II, v1 */ ((bytes [1] & 0xFE) == 0xFE) || /* MPEG ADTS, layer I, v1 */ ((bytes [1] & 0xFE) == 0xF2) || /* MPEG ADTS, layer III, v2 */ ((bytes [1] & 0xFE) == 0xF4) || /* MPEG ADTS, layer II, v2 */ ((bytes [1] & 0xFE) == 0xF6) || /* MPEG ADTS, layer I, v2 */ ((bytes [1] & 0xFE) == 0xE2); /* MPEG ADTS, layer III, v2.5 */ } MP3_FILE mp3f_new () { try { return Melder_calloc (struct _MP3_FILE, 1); } catch (MelderError) { Melder_throw (U"Cannot create MP3 file object."); } } void mp3f_delete (MP3_FILE mp3f) { Melder_free (mp3f); } void mp3f_set_file (MP3_FILE mp3f, FILE *f) { mp3f -> f = f; if (! f) return; fseek (f, 0, SEEK_SET); /* David Weenink 20151005 Check if an ID3 header version 2 or newer is present at the START of the file (older header types are always at the END of the file). We calculate the size of the header (in bytes), store it in the mp3f -> id3TagSize_bytes field and simply skip this amount of bytes before analyzing/decoding starts. According to http://id3.org/id3v2-00: The ID3v2 tag header, which should be the FIRST information in the file, is 10 bytes as follows: ID3/file identifier "ID3" ID3 version $02 00 ID3 flags %xx000000 ID3 size 4 * %0xxxxxxx The first three bytes of the tag are always "ID3" to indicate that this is an ID3 tag, directly followed by the two version bytes. The first byte of ID3 version is it's major version, while the second byte is its revision number. All revisions are backwards compatible while major versions are not. If software with ID3v2 and below support should encounter version three or higher it should simply ignore the whole tag. Version and revision will never be $FF. The first bit (bit 7) in the 'ID3 flags' is indicating whether or not unsynchronisation is used (see section 5 for details); a set bit indicates usage. The second bit (bit 6) is indicating whether or not compression is used; a set bit indicates usage. Since no compression scheme has been decided yet, the ID3 decoder (for now) should just ignore the entire tag if the compression bit is set. The ID3 tag size is encoded with four bytes where the first bit (bit 7) is set to zero in every byte, making a total of 28 bits. The zeroed bits are ignored, so a 257 bytes long tag is represented as $00 00 02 01. The ID3 tag size is the size of the complete tag after unsychronisation, including padding, excluding the header (total tag size - 10). The reason to use 28 bits (representing up to 256MB) for size description is that we don't want to run out of space here. A ID3v2 tag can be detected with the following pattern: $49 44 33 yy yy xx zz zz zz zz Where yy is less than $FF, xx is the 'flags' byte and zz is less than$80. */ { unsigned char bytes [10]; (void) fread (& bytes, 1, 10, mp3f -> f); mp3f -> id3TagSize_bytes = 0; if (bytes[0] == 'I' && bytes[1] == 'D' && bytes[2] == '3') { if (bytes[3] < 0xFF && bytes[4] < 0xFF && bytes[6] < 0x80 && bytes[7] < 0x80 && bytes[8] < 0x80 && bytes[9] < 0x80 ) { /* Ignore version: bytes[3] & bytes[4] Ignore flags: bytes[5] The only purpose of the 'unsychronisation scheme' is to make the ID3v2 tag as compatible as possible with existing software. There is no use in 'unsynchronising' tags if the file is only to be processed by new software. Unsynchronisation may only be made with MPEG 2 layer I, II and III and MPEG 2.5 files. */ mp3f -> id3TagSize_bytes = (bytes[6] << 21 | bytes[7] << 14 | bytes[8] << 7 | bytes[9]) + 10; } } } fseek (f, mp3f -> id3TagSize_bytes, SEEK_SET); // David Weenink mp3f -> next_read_position = 0; mp3f -> need_seek = 0; mp3f -> delay = MP3F_DECODER_DELAY + MP3F_ENCODER_DELAY; mp3f -> skip_amount = mp3f -> delay; mp3f -> first_offset = 0; } int mp3f_analyze (MP3_FILE mp3f) { struct mad_decoder *decoder = & mp3f -> decoder; int status; #ifdef MP3_DEBUG unsigned estimate, last; #endif /* MP3_DEBUG */ if (! mp3f || ! mp3f -> f) return 0; fseek (mp3f -> f, mp3f -> id3TagSize_bytes, SEEK_SET); // David Weenink mp3f -> xing = 0; mp3f -> channels = 0; mp3f -> frequency = 0; mp3f -> frames = 0; mp3f -> samples = 0; mp3f -> samples_per_frame = 0; mp3f -> num_locations = 0; /* Read first frames to get basic parameters and hopefully Xing */ mad_decoder_init (decoder, mp3f, mp3f_mad_input, mp3f_mad_first_header, mp3f_mad_first_filter, nullptr /* Output: Don't actually decode for now */, mp3f_mad_error, nullptr /* Message */); status = mad_decoder_run (decoder, MAD_DECODER_MODE_SYNC); if (status != 0) goto end; /* * If we don't have a Xing header we need to estimate the frame count. * This doesn't have to be accurate since we're going to count them * later when we scan for header offsets. */ if (! mp3f -> xing) { MP3F_OFFSET file_size, frame_size; /* Take size of first frame */ frame_size = mp3f -> locations [1] - mp3f -> locations[0]; /* For file size, seek to end */ fseek (mp3f -> f, mp3f -> id3TagSize_bytes, SEEK_END); // David Weenink file_size = ftell (mp3f -> f); /* This estimate will be pretty accurate for CBR */ mp3f -> frames = file_size / frame_size; MP3_DPRINTF (("File size: %lu bytes\n", (unsigned long)file_size)); MP3_DPRINTF (("First frame size: %lu bytes\n", (unsigned long)frame_size)); MP3_DPRINTF (("Estimated frames: %lu\n", (unsigned long)mp3f -> frames)); } /* Calculate how many frames can fit in a "location" */ if (mp3f -> frames <= MP3F_MAX_LOCATIONS) mp3f -> frames_per_location = 1; else mp3f -> frames_per_location = (mp3f -> frames + MP3F_MAX_LOCATIONS - 1) / MP3F_MAX_LOCATIONS; MP3_DPRINTF (("MP3: Each location is %u frame(s) (%.3fs), each %u samples\n", mp3f -> frames_per_location, mp3f -> frames_per_location * mp3f -> samples_per_frame / (float)mp3f -> frequency, mp3f -> samples_per_frame)); /* Read all frames to get offsets*/ #ifdef MP3_DEBUG estimate = mp3f -> frames; #endif /* MP3_DEBUG */ mp3f -> num_locations = 0; mp3f -> frames = 0; mp3f -> samples = 0; fseek (mp3f -> f, mp3f -> id3TagSize_bytes, SEEK_SET); // David Weenink mad_decoder_init (decoder, mp3f, mp3f_mad_input, mp3f_mad_scan_header, nullptr /* Filter */, nullptr /* Output */, mp3f_mad_error, nullptr /* Message */); status = mad_decoder_run (decoder, MAD_DECODER_MODE_SYNC); MP3_DPRINTF (("MP3 Frames: %u, estimated %u (%+.2f%%)\n", mp3f -> frames, estimate, MP3_PERCENT (mp3f -> frames, estimate))); #ifdef MP3_DEBUG last = mp3f -> frames - (mp3f -> frames_per_location * (mp3f -> num_locations - 1)); MP3_DPRINTF (("MP3F: Last location frames = %u (%+.2f%%) = %.3fs\n", last, MP3_PERCENT (mp3f -> frames_per_location, last), last * mp3f -> samples_per_frame / (float)mp3f -> frequency)); #endif /* MP3_DEBUG */ if(status!=-1) // ppgb 2015-01-17 mp3f_seek (mp3f, 0); end: mad_decoder_finish (decoder); return (status == 0); } unsigned mp3f_channels (MP3_FILE mp3f) { return mp3f -> channels; } unsigned mp3f_frequency (MP3_FILE mp3f) { return mp3f -> frequency; } MP3F_OFFSET mp3f_samples (MP3_FILE mp3f) { return mp3f -> samples - mp3f -> delay; } void mp3f_set_callback (MP3_FILE mp3f, MP3F_CALLBACK callback, void *context) { mp3f -> callback = callback; mp3f -> context = context; } int mp3f_seek (MP3_FILE mp3f, MP3F_OFFSET sample) { MP3F_OFFSET frame, location, base, offset; if (! mp3f || ! mp3f -> f) return 0; if (! mp3f -> frames_per_location) if (! mp3f_analyze (mp3f)) return 0; /* Compensate for initial empty frames */ sample += mp3f -> delay; /* Calculate where we need to seek */ frame = sample / mp3f -> samples_per_frame; if ( frame ) /* libMAD can skip the first frame... */ -- frame; if ( frame ) /* ...and the first frame it decodes is useless */ -- frame; Melder_assert (mp3f -> frames_per_location > 0); Melder_assert (mp3f -> num_locations > 0); location = frame / mp3f -> frames_per_location; if (location >= mp3f -> num_locations) location = mp3f -> num_locations - 1; frame = location * mp3f -> frames_per_location; base = frame * mp3f -> samples_per_frame; Melder_assert (location >= 0); offset = mp3f -> locations [location]; if (fseek (mp3f -> f, offset, SEEK_SET) < 0) return 0; mp3f -> first_offset = offset; mp3f -> skip_amount = sample - base; mp3f -> need_seek = 0; MP3_DPRINTF (("SEEK to %lu (%lu + %u): Frame %lu, location %lu, offset %lu, base %lu, skip %u\n", (unsigned long)sample, (unsigned long)sample - mp3f -> delay, mp3f -> delay, (unsigned long)frame, (unsigned long)location, (unsigned long)offset, (unsigned long)base, mp3f -> skip_amount)); return 1; } int mp3f_read (MP3_FILE mp3f, MP3F_OFFSET num_samples) { int status; struct mad_decoder *decoder = &(mp3f -> decoder); if (! mp3f || ! mp3f -> f || ! mp3f -> callback) return 0; /* Seek if the last read left us in mid-frame */ if (mp3f -> need_seek) if (! mp3f_seek (mp3f, mp3f -> next_read_position)) return 0; mad_decoder_init (decoder, mp3f, mp3f_mad_input, nullptr /* Header */, nullptr /* Filter */, mp3f_mad_report_samples, mp3f_mad_error, nullptr /* Message */); mp3f -> read_amount = num_samples; status = mad_decoder_run (decoder, MAD_DECODER_MODE_SYNC); mad_decoder_finish (decoder); mp3f -> next_read_position += num_samples; return (status == 0); } static enum mad_flow mp3f_mad_report_samples (void *context, struct mad_header const *header, struct mad_pcm *pcm) { MP3_FILE mp3f = (MP3_FILE) context; const int *channels [] = { pcm -> samples [0], pcm -> samples [1] }; unsigned length = pcm -> length; if (! mp3f || ! mp3f -> callback) return MAD_FLOW_BREAK; if (mp3f -> first_offset) { /* libMAD can decide to skip the first frame */ if (header -> offset > mp3f -> first_offset) { MP3_DPRINTF (("Skip %u of %lu\n", length, mp3f -> skip_amount)); mp3f -> skip_amount -= length; } mp3f -> first_offset = 0; } if (mp3f -> skip_amount >= length) { mp3f -> skip_amount -= length; return MAD_FLOW_IGNORE; } if (mp3f -> skip_amount > 0) { channels [0] += mp3f -> skip_amount; channels [1] += mp3f -> skip_amount; length -= mp3f -> skip_amount; mp3f -> skip_amount = 0; } if (length > mp3f -> read_amount) { length = mp3f -> read_amount; mp3f -> need_seek = 1; } if (length > 0) mp3f -> callback (channels, length, mp3f -> context); mp3f -> read_amount -= length; return (mp3f -> read_amount > 0) ? MAD_FLOW_CONTINUE : MAD_FLOW_STOP; } /* This conversion function was taken from minimad, and it could be better */ short mp3f_sample_to_short (MP3F_SAMPLE sample) { /* round */ sample += (1L << (MAD_F_FRACBITS - 16)); /* clip */ if (sample >= MAD_F_ONE) sample = MAD_F_ONE - 1; else if (sample < -MAD_F_ONE) sample = -MAD_F_ONE; /* quantize */ return sample >> (MAD_F_FRACBITS + 1 - 16); } /* This function was adapted from libmad */ static enum mad_flow mp3f_mad_error(void *context, struct mad_stream *stream, struct mad_frame *frame) { (void) context; (void) stream; (void) frame; return MAD_FLOW_CONTINUE; } /* This function was adapted from Audacity */ static enum mad_flow mp3f_mad_input(void *context, struct mad_stream *stream) { MP3_FILE mp3f = (MP3_FILE) context; FILE *f = mp3f -> f; unsigned char *buffer = nullptr; unsigned nthrown = 0, ncopied = 0, size = 0; size_t nread = 0; MP3F_OFFSET offset; if (feof (f)) return MAD_FLOW_STOP; if (stream -> next_frame) { nthrown = stream -> next_frame - mp3f -> buffer; ncopied = MP3F_BUFFER_SIZE - nthrown; memmove (mp3f -> buffer, stream -> next_frame, ncopied); } buffer = mp3f -> buffer + ncopied; size = MP3F_BUFFER_SIZE - ncopied; offset = ftell (f) - ncopied; if (size > 0) nread = fread (buffer, 1, size, f); mad_stream_buffer_offset (stream, mp3f -> buffer, nread + ncopied, offset); return MAD_FLOW_CONTINUE; } static enum mad_flow mp3f_mad_first_header(void *context, struct mad_header const *header) { MP3_FILE mp3f = (MP3_FILE) context; mp3f -> channels = MAD_NCHANNELS (header); mp3f -> frequency = header -> samplerate; mp3f -> samples_per_frame = 32 * MAD_NSBSAMPLES (header); /* Just in case there is no Xing header: */ mp3f -> locations [mp3f -> num_locations ++] = header -> offset; return MAD_FLOW_CONTINUE; } static enum mad_flow mp3f_mad_first_filter (void *context, struct mad_stream const *stream, struct mad_frame *frame) { MP3_FILE mp3f = (MP3_FILE) context; (void) frame; mp3f -> xing = mp3f_check_xing (mp3f, stream); /* Xing? No need to look further */ if (mp3f -> xing) return MAD_FLOW_STOP; /* Otherwise, read two frames for size estimate */ return (mp3f -> num_locations < 2) ? MAD_FLOW_IGNORE : MAD_FLOW_STOP; } static enum mad_flow mp3f_mad_scan_header(void *context, struct mad_header const *header) { MP3_FILE mp3f = (MP3_FILE) context; /* Some sanity checks */ if (mp3f -> channels != MAD_NCHANNELS (header)) return MAD_FLOW_BREAK; if (mp3f -> frequency != header -> samplerate) return MAD_FLOW_BREAK; if (mp3f -> samples_per_frame != 32 * MAD_NSBSAMPLES (header)) return MAD_FLOW_BREAK; /* Check whether to log this offset in the table */ if ((mp3f -> frames % mp3f -> frames_per_location) == 0 && mp3f -> num_locations < MP3F_MAX_LOCATIONS) mp3f -> locations [mp3f -> num_locations ++] = header -> offset; /* Count this frame */ ++ mp3f -> frames; mp3f -> samples += mp3f -> samples_per_frame; return MAD_FLOW_IGNORE; } /* * Identify a Xing VBR header. * This was adapted from madplay. */ # define XING_VBR_MAGIC (('X' << 24) | ('i' << 16) | ('n' << 8) | 'g') # define XING_CBR_MAGIC (('I' << 24) | ('n' << 16) | ('f' << 8) | 'o') enum { XING_FLAGS_FRAMES = 0x00000001L, XING_FLAGS_BYTES = 0x00000002L, XING_FLAGS_TOC = 0x00000004L, XING_FLAGS_SCALE = 0x00000008L }; static int mp3f_check_xing (MP3_FILE mp3f, struct mad_stream const *stream) { struct mad_bitptr ptr = stream -> anc_ptr; unsigned long magic, flags; /* When we get here we have the following data from the header: * channels * frequency * samples_per_frame * We need to calculate the total number of frames and samples. */ magic = mad_bit_read (&ptr, 32); if (magic != XING_CBR_MAGIC && magic != XING_VBR_MAGIC) return 0; flags = mad_bit_read (&ptr, 32); if ((flags & XING_FLAGS_FRAMES) != XING_FLAGS_FRAMES) return 0; mp3f -> frames = mad_bit_read (&ptr, 32); mp3f -> samples = mp3f -> samples_per_frame * mp3f -> frames; return 1; } praat-6.0.04/external/mp3/mp3.h000066400000000000000000000037231261542461700161160ustar00rootroot00000000000000#ifndef __MP3_H #define __MP3_H /* * Praat wrappers for libMAD (MPEG Audio Decoder) * Copyright 2007 Erez Volk * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include /* The following function is used to identify MP3 files */ int mp3_recognize (int nread, const char *data); /* Actual decoding is done with an MP3_FILE object */ typedef struct _MP3_FILE *MP3_FILE; typedef int MP3F_SAMPLE; #if defined (_OFF_T) || defined (__off_t_defined) typedef off_t MP3F_OFFSET; #else typedef unsigned long MP3F_OFFSET; #endif #define MP3F_MAX_CHANNELS 2 #define MP3F_MAX_SAMPLES 1152 /* Per callback */ typedef void (*MP3F_CALLBACK) ( const MP3F_SAMPLE *channels[MP3F_MAX_CHANNELS], long num_samples, void *context); MP3_FILE mp3f_new (); void mp3f_delete (MP3_FILE mp3f); void mp3f_set_file (MP3_FILE mp3f, FILE *f); int mp3f_analyze (MP3_FILE mp3f); unsigned mp3f_channels (MP3_FILE mp3f); unsigned mp3f_frequency (MP3_FILE mp3f); MP3F_OFFSET mp3f_samples (MP3_FILE mp3f); void mp3f_set_callback (MP3_FILE mp3f, MP3F_CALLBACK callback, void *context); int mp3f_seek (MP3_FILE mp3f, MP3F_OFFSET sample); int mp3f_read (MP3_FILE mp3f, MP3F_OFFSET num_samples); #define mp3f_sample_to_float(s) ((float)((s) / (float)(1L << 28))) short mp3f_sample_to_short (MP3F_SAMPLE sample); #endif /* __MP3_H */ praat-6.0.04/external/mp3/test.c000066400000000000000000000174411261542461700163730ustar00rootroot00000000000000#include #include #include #include #include "mp3.h" #include "mad_config.h" #include "mad_decoder.h" /* * This small program tests that my offset addition to libMAD actually works. * Erez Volk 2007-05-30 */ static void dump_file( const char *filename ); static void test_file( const char *filename ); static void test_mad( FILE *f ); static void test_mp3f( FILE *f ); static void get_offsets( FILE *f ); static enum mad_flow cb_input( void *context, struct mad_stream *stream ); static enum mad_flow cb_header( void *context, struct mad_header const *header ); static enum mad_flow cb_accept_header( void *context, struct mad_header const *header ); static enum mad_flow cb_dump( void *context, struct mad_header const *header, struct mad_pcm *pcm ); static void cb_samples( const int *channels[MP3F_MAX_CHANNELS], unsigned num_samples, void *context ); #define BUFFER_SIZE 2048 static unsigned char the_buffer[BUFFER_SIZE]; #define MAX_OFFSETS 4096 static unsigned long offsets[MAX_OFFSETS]; static unsigned num_offsets; int main( int argc, char *argv[] ) { int i; if ( argc <= 1 ) { printf( "Usage: %s MP3_FILE [MP3_FILE...]\n", argv[0] ); return -1; } if ( argc > 2 && !strcmp( argv[1], "-dump" ) ) dump_file( argv[2] ); else for ( i = 1; i < argc; ++ i ) test_file( argv[i] ); return 0; } typedef struct { FILE *f; unsigned done; unsigned left; FILE *f2; } DUMP_CONTEXT; static void dump_file( const char *filename ) { enum { MAX_FRAMES = 16 }; FILE *f; unsigned i; printf( "Dumping file: \"%s\"...\n", filename ); if ( (f = fopen( filename, "rb" )) == NULL ) { printf( " Cannot open file.\n" ); return; } get_offsets( f ); printf( " Header offsets: %lu, %lu, %lu, %lu, ... %lu\n", offsets[0], offsets[1], offsets[2], offsets[3], offsets[num_offsets - 1] ); for ( i = 0; i < MAX_FRAMES; ++ i ) { char dumpname[128]; struct mad_decoder d; DUMP_CONTEXT c = { f, i, MAX_FRAMES - i }; sprintf( dumpname, "%02u.dump", i ); printf( " Creating %s...\n", dumpname ); c.f2 = fopen( dumpname, "w" ); fseek( f, offsets[i], SEEK_SET ); mad_decoder_init( &d, &c, cb_input, cb_accept_header, NULL, cb_dump, NULL, NULL ); mad_decoder_run( &d, MAD_DECODER_MODE_SYNC ); mad_decoder_finish( &d ); fclose( c.f2 ); } fclose( f ); } static void test_file( const char *filename ) { FILE *f; printf( "Testing file: \"%s\"...\n", filename ); if ( (f = fopen( filename, "rb" )) == NULL ) { printf( " Cannot open file.\n" ); return; } test_mad( f ); test_mp3f( f ); fclose( f ); } static void test_mad( FILE *f ) { enum { MAX_BAD = 16 }; unsigned i, bad; get_offsets( f ); if ( num_offsets >= MAX_OFFSETS ) printf( " Reached maximum number of headers (%u)\n", MAX_OFFSETS ); else printf( " Number of headers found: %u\n", num_offsets ); printf( " Header offsets: %lu, %lu, %lu, %lu, ... %lu\n", offsets[0], offsets[1], offsets[2], offsets[3], offsets[num_offsets - 1] ); printf( " Checking header validity...\n" ); for ( i = bad = 0; i < num_offsets && bad < MAX_BAD; ++ i ) { unsigned char header[2] = { 0, 0 }; if ( i > 0 && offsets[i] <= offsets[i - 1] ) { printf( " Invalid offset table.\n" ); return; } fseek( f, offsets[i], SEEK_SET ); fread( header, 1, sizeof(header), f ); if ( (header[0] != 0xFF) || ((header[1] & 0xE0) != 0xE0) ) { ++ bad; printf( " ERROR: No header at file offset %lu\n", offsets[i] ); } else if ( bad > 0 ) printf( " Good header at file offset %lu\n", offsets[i] ); } if ( bad == 0 ) printf( " All offsets have valid MP3 headers\n" ); } static void get_offsets( FILE *f ) { struct mad_decoder d; /* Make sure there are no leftovers */ memset( &d, time(NULL), sizeof(d) ); num_offsets = 0; mad_decoder_init( &d, &f, cb_input, cb_header, NULL, NULL, NULL, NULL ); if ( mad_decoder_run( &d, MAD_DECODER_MODE_SYNC ) != 0 ) { printf( " Error scanning file.\n" ); return; } mad_decoder_finish( &d ); } static enum mad_flow cb_input( void *context, struct mad_stream *stream ) { FILE *f = *(FILE **)context; unsigned char *data = NULL; unsigned nthrown = 0, ncopied = 0, size = 0; unsigned offset; size_t nread = 0; if (feof (f)) return MAD_FLOW_STOP; if (stream -> next_frame) { nthrown = stream -> next_frame - the_buffer; ncopied = BUFFER_SIZE - nthrown; memmove (the_buffer, stream -> next_frame, ncopied); } data = the_buffer + ncopied; size = BUFFER_SIZE - ncopied; offset = ftell (f) - ncopied; if (size > 0) nread = fread (data, 1, size, f); mad_stream_buffer_offset (stream, the_buffer, nread + ncopied, offset); stream -> this_offset = offset; return MAD_FLOW_CONTINUE; } static enum mad_flow cb_header( void *context, struct mad_header const *header ) { FILE *f = *(FILE **)context; unsigned long foff = ftell( f ); if ( foff > header->offset + BUFFER_SIZE ) printf( " ??? %lu <-> %lu\n", foff, header->offset ); offsets[num_offsets] = header->offset; if ( ++ num_offsets >= MAX_OFFSETS ) return MAD_FLOW_STOP; return MAD_FLOW_CONTINUE; } static enum mad_flow cb_accept_header( void *context, struct mad_header const *header ) { (void)context; (void)header; return MAD_FLOW_CONTINUE; } static enum mad_flow cb_dump( void *context, struct mad_header const *header, struct mad_pcm *pcm ) { DUMP_CONTEXT *c = (DUMP_CONTEXT *)context; FILE *f = c->f2; unsigned i, j, length = pcm->length; const mad_fixed_t *samples = pcm->samples[0]; (void)header; fprintf( f, "FRAME %u, OFFSET %lu (expected %lu)\n", c->done, header->offset, offsets[c->done] ); for ( i = 0; i < length; i += 8 ) { for ( j = i; i < length && j < i + 8; ++ j ) fprintf( f, "%9i ", samples[j] ); fprintf( f, "\n" ); } fprintf( f, "\n" ); ++ c->done; -- c->left; return c->left == 0 ? MAD_FLOW_STOP : MAD_FLOW_CONTINUE; } static void test_mp3f( FILE *f ) { enum { FIRST = 15000, SECOND = 2000, TOTAL = FIRST + SECOND }; enum { MID_OFFSET = 16000, MID_SIZE = 800 }; static int x[TOTAL], y[TOTAL], z[MID_SIZE]; int *p; MP3_FILE mp3f = mp3f_new(); mp3f_set_file( mp3f, f ); if ( mp3f_analyze( mp3f ) ) { printf( " MP3F: Channels = %u\n", mp3f_channels( mp3f ) ); printf( " MP3F: Frequency = %u\n", mp3f_frequency( mp3f ) ); printf( " MP3F: Samples = %lu\n", (unsigned long)mp3f_samples( mp3f ) ); printf( " MP3F: Time => %.2lfs\n", (double)mp3f_samples(mp3f) / (double)mp3f_frequency(mp3f) ); } else printf( " MP3F: Cannot analyze\n" ); memset( x, 0x22, sizeof(x) ); memset( y, 0x22, sizeof(y) ); memset( z, 0x22, sizeof(z) ); mp3f_set_file( mp3f, f ); p = x; mp3f_set_callback( mp3f, cb_samples, &p ); mp3f_read( mp3f, TOTAL ); mp3f_set_file( mp3f, f ); p = y; mp3f_set_callback( mp3f, cb_samples, &p ); mp3f_read( mp3f, FIRST ); mp3f_read( mp3f, SECOND ); mp3f_set_file( mp3f, f ); p = z; mp3f_set_callback( mp3f, cb_samples, &p ); if ( mp3f_seek( mp3f, MID_OFFSET ) ) mp3f_read( mp3f, MID_SIZE ); else printf( " MP3F: Seek failed\n" ); if ( memcmp( x, y, FIRST * sizeof(int) ) != 0 ) printf( " MP3F: Difference in first samples!\n" ); else printf( " MP3F: First samples OK\n" ); if ( memcmp( x + FIRST, y + FIRST, SECOND * sizeof(int) ) != 0 ) printf( " MP3F: Difference in later samples!\n" ); else printf( " MP3F: Later samples OK\n" ); if ( memcmp( x + MID_OFFSET, z, MID_SIZE * sizeof(int) ) != 0 ) printf( " MP3F: Seek doesn't work\n" ); else printf( " MP3F: Seek works\n" ); mp3f_delete( mp3f ); } static void cb_samples( const int *channels[MP3F_MAX_CHANNELS], unsigned num_samples, void *context ) { int **pp = (int **)context; int *p = *pp; unsigned i; for ( i = 0; i < num_samples; ++ i ) p[i] = channels[0][i]; *pp += num_samples; } /* Needed for libMP3 */ void *Melder_malloc( unsigned size ) { return malloc( size ); } void _Melder_free( void **p ) { free( *p ); } praat-6.0.04/external/portaudio/000077500000000000000000000000001261542461700165505ustar00rootroot00000000000000praat-6.0.04/external/portaudio/Makefile000066400000000000000000000011211261542461700202030ustar00rootroot00000000000000# Makefile of the library "external/portaudio" # Paul Boersma, 14 February 2014 include ../../makefile.defs OBJECTS = \ pa_unix_hostapis.o pa_unix_util.o pa_linux_alsa.o \ pa_win_hostapis.o pa_win_util.o pa_win_wmme.o pa_win_waveformat.o \ pa_front.o pa_debugprint.o pa_cpuload.o \ pa_allocation.o pa_process.o pa_converters.o pa_dither.o \ pa_stream.o .PHONY: all clean all: libportaudio.a clean: $(RM) $(OBJECTS) $(RM) libportaudio.a libportaudio.a: $(OBJECTS) touch libportaudio.a rm libportaudio.a ar cq libportaudio.a $(OBJECTS) $(RANLIB) libportaudio.a $(OBJECTS): *.h praat-6.0.04/external/portaudio/READ_ME.TXT000066400000000000000000000015621261542461700202510ustar00rootroot00000000000000Praats/external/portaudio/READ_ME.TXT Paul Boersma, 14 February 2014 This file describes the adaptations to the PortAudio v19 sources (2014/01) that are needed to make them compatible with Praat. Deleted many lines in pa_***_hostapis.c. (At the top of pa_win_*.c: #undef UNICODE) Duplicate pa_unix_util.c to pa_mac_util.c, but only for allocation and time routines. Remove the hard-coded definition of SIZEOF_LONG from pa_types.h and instead use to define PaInt32 and the like. Around pa_linux_alsa.c, do #if defined (UNIX) && defined (ALSA) ... #endif Around pa_win_*.c, do #ifdef _WIN32 ... #endif Around pa_unix_util.c, do #if defined (UNIX) ... #endif Add prototype for PaError PaAlsa_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ); in pa_linux_als.h Insert void in declaration and definition of PaUnix_InitializeThreading. praat-6.0.04/external/portaudio/pa_allocation.c000066400000000000000000000154051261542461700215260ustar00rootroot00000000000000/* * $Id: pa_allocation.c 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library allocation group implementation * memory allocation group for tracking allocation groups * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Allocation Group implementation. */ #include "pa_allocation.h" #include "pa_util.h" /* Maintain 3 singly linked lists... linkBlocks: the buffers used to allocate the links spareLinks: links available for use in the allocations list allocations: the buffers currently allocated using PaUtil_ContextAllocateMemory() Link block size is doubled every time new links are allocated. */ #define PA_INITIAL_LINK_COUNT_ 16 struct PaUtilAllocationGroupLink { struct PaUtilAllocationGroupLink *next; void *buffer; }; /* Allocate a block of links. The first link will have it's buffer member pointing to the block, and it's next member set to . The remaining links will have NULL buffer members, and each link will point to the next link except the last, which will point to */ static struct PaUtilAllocationGroupLink *AllocateLinks( long count, struct PaUtilAllocationGroupLink *nextBlock, struct PaUtilAllocationGroupLink *nextSpare ) { struct PaUtilAllocationGroupLink *result; int i; result = (struct PaUtilAllocationGroupLink *)PaUtil_AllocateMemory( sizeof(struct PaUtilAllocationGroupLink) * count ); if( result ) { /* the block link */ result[0].buffer = result; result[0].next = nextBlock; /* the spare links */ for( i=1; ilinkCount = PA_INITIAL_LINK_COUNT_; result->linkBlocks = &links[0]; result->spareLinks = &links[1]; result->allocations = 0; } else { PaUtil_FreeMemory( links ); } } return result; } void PaUtil_DestroyAllocationGroup( PaUtilAllocationGroup* group ) { struct PaUtilAllocationGroupLink *current = group->linkBlocks; struct PaUtilAllocationGroupLink *next; while( current ) { next = current->next; PaUtil_FreeMemory( current->buffer ); current = next; } PaUtil_FreeMemory( group ); } void* PaUtil_GroupAllocateMemory( PaUtilAllocationGroup* group, long size ) { struct PaUtilAllocationGroupLink *links, *link; void *result = 0; /* allocate more links if necessary */ if( !group->spareLinks ) { /* double the link count on each block allocation */ links = AllocateLinks( group->linkCount, group->linkBlocks, group->spareLinks ); if( links ) { group->linkCount += group->linkCount; group->linkBlocks = &links[0]; group->spareLinks = &links[1]; } } if( group->spareLinks ) { result = PaUtil_AllocateMemory( size ); if( result ) { link = group->spareLinks; group->spareLinks = link->next; link->buffer = result; link->next = group->allocations; group->allocations = link; } } return result; } void PaUtil_GroupFreeMemory( PaUtilAllocationGroup* group, void *buffer ) { struct PaUtilAllocationGroupLink *current = group->allocations; struct PaUtilAllocationGroupLink *previous = 0; if( buffer == 0 ) return; /* find the right link and remove it */ while( current ) { if( current->buffer == buffer ) { if( previous ) { previous->next = current->next; } else { group->allocations = current->next; } current->buffer = 0; current->next = group->spareLinks; group->spareLinks = current; break; } previous = current; current = current->next; } PaUtil_FreeMemory( buffer ); /* free the memory whether we found it in the list or not */ } void PaUtil_FreeAllAllocations( PaUtilAllocationGroup* group ) { struct PaUtilAllocationGroupLink *current = group->allocations; struct PaUtilAllocationGroupLink *previous = 0; /* free all buffers in the allocations list */ while( current ) { PaUtil_FreeMemory( current->buffer ); current->buffer = 0; previous = current; current = current->next; } /* link the former allocations list onto the front of the spareLinks list */ if( previous ) { previous->next = group->spareLinks; group->spareLinks = group->allocations; group->allocations = 0; } } praat-6.0.04/external/portaudio/pa_allocation.h000066400000000000000000000074301261542461700215320ustar00rootroot00000000000000#ifndef PA_ALLOCATION_H #define PA_ALLOCATION_H /* * $Id: pa_allocation.h 1339 2008-02-15 07:50:33Z rossb $ * Portable Audio I/O Library allocation context header * memory allocation context for tracking allocation groups * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2008 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Allocation Group prototypes. An Allocation Group makes it easy to allocate multiple blocks of memory and free them all at once. An allocation group is useful for keeping track of multiple blocks of memory which are allocated at the same time (such as during initialization) and need to be deallocated at the same time. The allocation group maintains a list of allocated blocks, and can free all allocations at once. This can be usefull for cleaning up after a partially initialized object fails. The allocation group implementation is built on top of the lower level allocation functions defined in pa_util.h */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ typedef struct { long linkCount; struct PaUtilAllocationGroupLink *linkBlocks; struct PaUtilAllocationGroupLink *spareLinks; struct PaUtilAllocationGroupLink *allocations; }PaUtilAllocationGroup; /** Create an allocation group. */ PaUtilAllocationGroup* PaUtil_CreateAllocationGroup( void ); /** Destroy an allocation group, but not the memory allocated through the group. */ void PaUtil_DestroyAllocationGroup( PaUtilAllocationGroup* group ); /** Allocate a block of memory though an allocation group. */ void* PaUtil_GroupAllocateMemory( PaUtilAllocationGroup* group, long size ); /** Free a block of memory that was previously allocated though an allocation group. Calling this function is a relatively time consuming operation. Under normal circumstances clients should call PaUtil_FreeAllAllocations to free all allocated blocks simultaneously. @see PaUtil_FreeAllAllocations */ void PaUtil_GroupFreeMemory( PaUtilAllocationGroup* group, void *buffer ); /** Free all blocks of memory which have been allocated through the allocation group. This function doesn't destroy the group itself. */ void PaUtil_FreeAllAllocations( PaUtilAllocationGroup* group ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_ALLOCATION_H */ praat-6.0.04/external/portaudio/pa_asio.cpp000066400000000000000000004755771261542461700207200ustar00rootroot00000000000000/* * $Id: pa_asio.cpp 1890 2013-05-02 01:06:01Z rbencina $ * Portable Audio I/O Library for ASIO Drivers * * Author: Stephane Letz * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 2000-2002 Stephane Letz, Phil Burk, Ross Bencina * Blocking i/o implementation by Sven Fischer, Institute of Hearing * Technology and Audiology (www.hoertechnik-audiologie.de) * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /* Modification History 08-03-01 First version : Stephane Letz 08-06-01 Tweaks for PC, use C++, buffer allocation, Float32 to Int32 conversion : Phil Burk 08-20-01 More conversion, PA_StreamTime, Pa_GetHostError : Stephane Letz 08-21-01 PaUInt8 bug correction, implementation of ASIOSTFloat32LSB and ASIOSTFloat32MSB native formats : Stephane Letz 08-24-01 MAX_INT32_FP hack, another Uint8 fix : Stephane and Phil 08-27-01 Implementation of hostBufferSize < userBufferSize case, better management of the ouput buffer when the stream is stopped : Stephane Letz 08-28-01 Check the stream pointer for null in bufferSwitchTimeInfo, correct bug in bufferSwitchTimeInfo when the stream is stopped : Stephane Letz 10-12-01 Correct the PaHost_CalcNumHostBuffers function: computes FramesPerHostBuffer to be the lowest that respect requested FramesPerUserBuffer and userBuffersPerHostBuffer : Stephane Letz 10-26-01 Management of hostBufferSize and userBufferSize of any size : Stephane Letz 10-27-01 Improve calculus of hostBufferSize to be multiple or divisor of userBufferSize if possible : Stephane and Phil 10-29-01 Change MAX_INT32_FP to (2147483520.0f) to prevent roundup to 0x80000000 : Phil Burk 10-31-01 Clear the ouput buffer and user buffers in PaHost_StartOutput, correct bug in GetFirstMultiple : Stephane Letz 11-06-01 Rename functions : Stephane Letz 11-08-01 New Pa_ASIO_Adaptor_Init function to init Callback adpatation variables, cleanup of Pa_ASIO_Callback_Input: Stephane Letz 11-29-01 Break apart device loading to debug random failure in Pa_ASIO_QueryDeviceInfo ; Phil Burk 01-03-02 Desallocate all resources in PaHost_Term for cases where Pa_CloseStream is not called properly : Stephane Letz 02-01-02 Cleanup, test of multiple-stream opening : Stephane Letz 19-02-02 New Pa_ASIO_loadDriver that calls CoInitialize on each thread on Windows : Stephane Letz 09-04-02 Correct error code management in PaHost_Term, removes various compiler warning : Stephane Letz 12-04-02 Add Mac includes for and : Phil Burk 13-04-02 Removes another compiler warning : Stephane Letz 30-04-02 Pa_ASIO_QueryDeviceInfo bug correction, memory allocation checking, better error handling : D Viens, P Burk, S Letz 12-06-02 Rehashed into new multi-api infrastructure, added support for all ASIO sample formats : Ross Bencina 18-06-02 Added pa_asio.h, PaAsio_GetAvailableLatencyValues() : Ross B. 21-06-02 Added SelectHostBufferSize() which selects host buffer size based on user latency parameters : Ross Bencina ** NOTE maintanance history is now stored in CVS ** */ /** @file @ingroup hostapi_src Note that specific support for paInputUnderflow, paOutputOverflow and paNeverDropInput is not necessary or possible with this driver due to the synchronous full duplex double-buffered architecture of ASIO. */ #include #include #include //#include #include #include #include #include "portaudio.h" #include "pa_asio.h" #include "pa_util.h" #include "pa_allocation.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_cpuload.h" #include "pa_process.h" #include "pa_debugprint.h" #include "pa_ringbuffer.h" #include "pa_win_coinitialize.h" /* This version of pa_asio.cpp is currently only targetted at Win32, It would require a few tweaks to work with pre-OS X Macintosh. To make configuration easier, we define WIN32 here to make sure that the ASIO SDK knows this is Win32. */ #ifndef WIN32 #define WIN32 #endif #include "asiosys.h" #include "asio.h" #include "asiodrivers.h" #include "iasiothiscallresolver.h" /* #if MAC #include #include #include #else */ /* #include #include #include */ /* #endif */ /* winmm.lib is needed for timeGetTime() (this is in winmm.a if you're using gcc) */ #if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */ #pragma comment(lib, "winmm.lib") #endif /* external reference to ASIO SDK's asioDrivers. This is a bit messy because we want to explicitly manage allocation/deallocation of this structure, but some layers of the SDK which we currently use (eg the implementation in asio.cpp) still use this global version. For now we keep it in sync with our local instance in the host API representation structure, but later we should be able to remove all dependence on it. */ extern AsioDrivers* asioDrivers; /* We are trying to be compatible with CARBON but this has not been thoroughly tested. */ /* not tested at all since new V19 code was introduced. */ #define CARBON_COMPATIBLE (0) /* prototypes for functions declared in this file */ extern "C" PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ); static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); static PaError CloseStream( PaStream* stream ); static PaError StartStream( PaStream *stream ); static PaError StopStream( PaStream *stream ); static PaError AbortStream( PaStream *stream ); static PaError IsStreamStopped( PaStream *s ); static PaError IsStreamActive( PaStream *stream ); static PaTime GetStreamTime( PaStream *stream ); static double GetStreamCpuLoad( PaStream* stream ); static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ); static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ); static signed long GetStreamReadAvailable( PaStream* stream ); static signed long GetStreamWriteAvailable( PaStream* stream ); /* Blocking i/o callback function. */ static int BlockingIoPaCallback(const void *inputBuffer , void *outputBuffer , unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo , PaStreamCallbackFlags statusFlags , void *userData ); /* our ASIO callback functions */ static void bufferSwitch(long index, ASIOBool processNow); static ASIOTime *bufferSwitchTimeInfo(ASIOTime *timeInfo, long index, ASIOBool processNow); static void sampleRateChanged(ASIOSampleRate sRate); static long asioMessages(long selector, long value, void* message, double* opt); static ASIOCallbacks asioCallbacks_ = { bufferSwitch, sampleRateChanged, asioMessages, bufferSwitchTimeInfo }; #define PA_ASIO_SET_LAST_HOST_ERROR( errorCode, errorText ) \ PaUtil_SetLastHostErrorInfo( paASIO, errorCode, errorText ) static void PaAsio_SetLastSystemError( DWORD errorCode ) { LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); PaUtil_SetLastHostErrorInfo( paASIO, errorCode, (const char*)lpMsgBuf ); LocalFree( lpMsgBuf ); } #define PA_ASIO_SET_LAST_SYSTEM_ERROR( errorCode ) \ PaAsio_SetLastSystemError( errorCode ) static const char* PaAsio_GetAsioErrorText( ASIOError asioError ) { const char *result; switch( asioError ){ case ASE_OK: case ASE_SUCCESS: result = "Success"; break; case ASE_NotPresent: result = "Hardware input or output is not present or available"; break; case ASE_HWMalfunction: result = "Hardware is malfunctioning"; break; case ASE_InvalidParameter: result = "Input parameter invalid"; break; case ASE_InvalidMode: result = "Hardware is in a bad mode or used in a bad mode"; break; case ASE_SPNotAdvancing: result = "Hardware is not running when sample position is inquired"; break; case ASE_NoClock: result = "Sample clock or rate cannot be determined or is not present"; break; case ASE_NoMemory: result = "Not enough memory for completing the request"; break; default: result = "Unknown ASIO error"; break; } return result; } #define PA_ASIO_SET_LAST_ASIO_ERROR( asioError ) \ PaUtil_SetLastHostErrorInfo( paASIO, asioError, PaAsio_GetAsioErrorText( asioError ) ) // Atomic increment and decrement operations #if MAC /* need to be implemented on Mac */ inline long PaAsio_AtomicIncrement(volatile long* v) {return ++(*const_cast(v));} inline long PaAsio_AtomicDecrement(volatile long* v) {return --(*const_cast(v));} #elif WINDOWS inline long PaAsio_AtomicIncrement(volatile long* v) {return InterlockedIncrement(const_cast(v));} inline long PaAsio_AtomicDecrement(volatile long* v) {return InterlockedDecrement(const_cast(v));} #endif typedef struct PaAsioDriverInfo { ASIODriverInfo asioDriverInfo; long inputChannelCount, outputChannelCount; long bufferMinSize, bufferMaxSize, bufferPreferredSize, bufferGranularity; bool postOutput; } PaAsioDriverInfo; /* PaAsioHostApiRepresentation - host api datastructure specific to this implementation */ typedef struct { PaUtilHostApiRepresentation inheritedHostApiRep; PaUtilStreamInterface callbackStreamInterface; PaUtilStreamInterface blockingStreamInterface; PaUtilAllocationGroup *allocations; PaWinUtilComInitializationResult comInitializationResult; AsioDrivers *asioDrivers; void *systemSpecific; /* the ASIO C API only allows one ASIO driver to be open at a time, so we keep track of whether we have the driver open here, and use this information to return errors from OpenStream if the driver is already open. openAsioDeviceIndex will be PaNoDevice if there is no device open and a valid pa_asio (not global) device index otherwise. openAsioDriverInfo is populated with the driver info for the currently open device (if any) */ PaDeviceIndex openAsioDeviceIndex; PaAsioDriverInfo openAsioDriverInfo; } PaAsioHostApiRepresentation; /* Retrieve driver names from ASIO, returned in a char** allocated in . */ static char **GetAsioDriverNames( PaAsioHostApiRepresentation *asioHostApi, PaUtilAllocationGroup *group, long driverCount ) { char **result = 0; int i; result =(char**)PaUtil_GroupAllocateMemory( group, sizeof(char*) * driverCount ); if( !result ) goto error; result[0] = (char*)PaUtil_GroupAllocateMemory( group, 32 * driverCount ); if( !result[0] ) goto error; for( i=0; iasioDrivers->getDriverNames( result, driverCount ); error: return result; } static PaSampleFormat AsioSampleTypeToPaNativeSampleFormat(ASIOSampleType type) { switch (type) { case ASIOSTInt16MSB: case ASIOSTInt16LSB: return paInt16; case ASIOSTFloat32MSB: case ASIOSTFloat32LSB: case ASIOSTFloat64MSB: case ASIOSTFloat64LSB: return paFloat32; case ASIOSTInt32MSB: case ASIOSTInt32LSB: case ASIOSTInt32MSB16: case ASIOSTInt32LSB16: case ASIOSTInt32MSB18: case ASIOSTInt32MSB20: case ASIOSTInt32MSB24: case ASIOSTInt32LSB18: case ASIOSTInt32LSB20: case ASIOSTInt32LSB24: return paInt32; case ASIOSTInt24MSB: case ASIOSTInt24LSB: return paInt24; default: return paCustomFormat; } } void AsioSampleTypeLOG(ASIOSampleType type) { switch (type) { case ASIOSTInt16MSB: PA_DEBUG(("ASIOSTInt16MSB\n")); break; case ASIOSTInt16LSB: PA_DEBUG(("ASIOSTInt16LSB\n")); break; case ASIOSTFloat32MSB:PA_DEBUG(("ASIOSTFloat32MSB\n"));break; case ASIOSTFloat32LSB:PA_DEBUG(("ASIOSTFloat32LSB\n"));break; case ASIOSTFloat64MSB:PA_DEBUG(("ASIOSTFloat64MSB\n"));break; case ASIOSTFloat64LSB:PA_DEBUG(("ASIOSTFloat64LSB\n"));break; case ASIOSTInt32MSB: PA_DEBUG(("ASIOSTInt32MSB\n")); break; case ASIOSTInt32LSB: PA_DEBUG(("ASIOSTInt32LSB\n")); break; case ASIOSTInt32MSB16:PA_DEBUG(("ASIOSTInt32MSB16\n"));break; case ASIOSTInt32LSB16:PA_DEBUG(("ASIOSTInt32LSB16\n"));break; case ASIOSTInt32MSB18:PA_DEBUG(("ASIOSTInt32MSB18\n"));break; case ASIOSTInt32MSB20:PA_DEBUG(("ASIOSTInt32MSB20\n"));break; case ASIOSTInt32MSB24:PA_DEBUG(("ASIOSTInt32MSB24\n"));break; case ASIOSTInt32LSB18:PA_DEBUG(("ASIOSTInt32LSB18\n"));break; case ASIOSTInt32LSB20:PA_DEBUG(("ASIOSTInt32LSB20\n"));break; case ASIOSTInt32LSB24:PA_DEBUG(("ASIOSTInt32LSB24\n"));break; case ASIOSTInt24MSB: PA_DEBUG(("ASIOSTInt24MSB\n")); break; case ASIOSTInt24LSB: PA_DEBUG(("ASIOSTInt24LSB\n")); break; default: PA_DEBUG(("Custom Format%d\n",type));break; } } static int BytesPerAsioSample( ASIOSampleType sampleType ) { switch (sampleType) { case ASIOSTInt16MSB: case ASIOSTInt16LSB: return 2; case ASIOSTFloat64MSB: case ASIOSTFloat64LSB: return 8; case ASIOSTFloat32MSB: case ASIOSTFloat32LSB: case ASIOSTInt32MSB: case ASIOSTInt32LSB: case ASIOSTInt32MSB16: case ASIOSTInt32LSB16: case ASIOSTInt32MSB18: case ASIOSTInt32MSB20: case ASIOSTInt32MSB24: case ASIOSTInt32LSB18: case ASIOSTInt32LSB20: case ASIOSTInt32LSB24: return 4; case ASIOSTInt24MSB: case ASIOSTInt24LSB: return 3; default: return 0; } } static void Swap16( void *buffer, long shift, long count ) { unsigned short *p = (unsigned short*)buffer; unsigned short temp; (void) shift; /* unused parameter */ while( count-- ) { temp = *p; *p++ = (unsigned short)((temp<<8) | (temp>>8)); } } static void Swap24( void *buffer, long shift, long count ) { unsigned char *p = (unsigned char*)buffer; unsigned char temp; (void) shift; /* unused parameter */ while( count-- ) { temp = *p; *p = *(p+2); *(p+2) = temp; p += 3; } } #define PA_SWAP32_( x ) ((x>>24) | ((x>>8)&0xFF00) | ((x<<8)&0xFF0000) | (x<<24)); static void Swap32( void *buffer, long shift, long count ) { unsigned long *p = (unsigned long*)buffer; unsigned long temp; (void) shift; /* unused parameter */ while( count-- ) { temp = *p; *p++ = PA_SWAP32_( temp); } } static void SwapShiftLeft32( void *buffer, long shift, long count ) { unsigned long *p = (unsigned long*)buffer; unsigned long temp; while( count-- ) { temp = *p; temp = PA_SWAP32_( temp); *p++ = temp << shift; } } static void ShiftRightSwap32( void *buffer, long shift, long count ) { unsigned long *p = (unsigned long*)buffer; unsigned long temp; while( count-- ) { temp = *p >> shift; *p++ = PA_SWAP32_( temp); } } static void ShiftLeft32( void *buffer, long shift, long count ) { unsigned long *p = (unsigned long*)buffer; unsigned long temp; while( count-- ) { temp = *p; *p++ = temp << shift; } } static void ShiftRight32( void *buffer, long shift, long count ) { unsigned long *p = (unsigned long*)buffer; unsigned long temp; while( count-- ) { temp = *p; *p++ = temp >> shift; } } #define PA_SWAP_( x, y ) temp=x; x = y; y = temp; static void Swap64ConvertFloat64ToFloat32( void *buffer, long shift, long count ) { double *in = (double*)buffer; float *out = (float*)buffer; unsigned char *p; unsigned char temp; (void) shift; /* unused parameter */ while( count-- ) { p = (unsigned char*)in; PA_SWAP_( p[0], p[7] ); PA_SWAP_( p[1], p[6] ); PA_SWAP_( p[2], p[5] ); PA_SWAP_( p[3], p[4] ); *out++ = (float) (*in++); } } static void ConvertFloat64ToFloat32( void *buffer, long shift, long count ) { double *in = (double*)buffer; float *out = (float*)buffer; (void) shift; /* unused parameter */ while( count-- ) *out++ = (float) (*in++); } static void ConvertFloat32ToFloat64Swap64( void *buffer, long shift, long count ) { float *in = ((float*)buffer) + (count-1); double *out = ((double*)buffer) + (count-1); unsigned char *p; unsigned char temp; (void) shift; /* unused parameter */ while( count-- ) { *out = *in--; p = (unsigned char*)out; PA_SWAP_( p[0], p[7] ); PA_SWAP_( p[1], p[6] ); PA_SWAP_( p[2], p[5] ); PA_SWAP_( p[3], p[4] ); out--; } } static void ConvertFloat32ToFloat64( void *buffer, long shift, long count ) { float *in = ((float*)buffer) + (count-1); double *out = ((double*)buffer) + (count-1); (void) shift; /* unused parameter */ while( count-- ) *out-- = *in--; } #ifdef MAC #define PA_MSB_IS_NATIVE_ #undef PA_LSB_IS_NATIVE_ #endif #ifdef WINDOWS #undef PA_MSB_IS_NATIVE_ #define PA_LSB_IS_NATIVE_ #endif typedef void PaAsioBufferConverter( void *, long, long ); static void SelectAsioToPaConverter( ASIOSampleType type, PaAsioBufferConverter **converter, long *shift ) { *shift = 0; *converter = 0; switch (type) { case ASIOSTInt16MSB: /* dest: paInt16, no conversion necessary, possible byte swap*/ #ifdef PA_LSB_IS_NATIVE_ *converter = Swap16; #endif break; case ASIOSTInt16LSB: /* dest: paInt16, no conversion necessary, possible byte swap*/ #ifdef PA_MSB_IS_NATIVE_ *converter = Swap16; #endif break; case ASIOSTFloat32MSB: /* dest: paFloat32, no conversion necessary, possible byte swap*/ #ifdef PA_LSB_IS_NATIVE_ *converter = Swap32; #endif break; case ASIOSTFloat32LSB: /* dest: paFloat32, no conversion necessary, possible byte swap*/ #ifdef PA_MSB_IS_NATIVE_ *converter = Swap32; #endif break; case ASIOSTFloat64MSB: /* dest: paFloat32, in-place conversion to/from float32, possible byte swap*/ #ifdef PA_LSB_IS_NATIVE_ *converter = Swap64ConvertFloat64ToFloat32; #else *converter = ConvertFloat64ToFloat32; #endif break; case ASIOSTFloat64LSB: /* dest: paFloat32, in-place conversion to/from float32, possible byte swap*/ #ifdef PA_MSB_IS_NATIVE_ *converter = Swap64ConvertFloat64ToFloat32; #else *converter = ConvertFloat64ToFloat32; #endif break; case ASIOSTInt32MSB: /* dest: paInt32, no conversion necessary, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = Swap32; #endif break; case ASIOSTInt32LSB: /* dest: paInt32, no conversion necessary, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = Swap32; #endif break; case ASIOSTInt32MSB16: /* dest: paInt32, 16 bit shift, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = SwapShiftLeft32; #else *converter = ShiftLeft32; #endif *shift = 16; break; case ASIOSTInt32MSB18: /* dest: paInt32, 14 bit shift, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = SwapShiftLeft32; #else *converter = ShiftLeft32; #endif *shift = 14; break; case ASIOSTInt32MSB20: /* dest: paInt32, 12 bit shift, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = SwapShiftLeft32; #else *converter = ShiftLeft32; #endif *shift = 12; break; case ASIOSTInt32MSB24: /* dest: paInt32, 8 bit shift, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = SwapShiftLeft32; #else *converter = ShiftLeft32; #endif *shift = 8; break; case ASIOSTInt32LSB16: /* dest: paInt32, 16 bit shift, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = SwapShiftLeft32; #else *converter = ShiftLeft32; #endif *shift = 16; break; case ASIOSTInt32LSB18: /* dest: paInt32, 14 bit shift, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = SwapShiftLeft32; #else *converter = ShiftLeft32; #endif *shift = 14; break; case ASIOSTInt32LSB20: /* dest: paInt32, 12 bit shift, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = SwapShiftLeft32; #else *converter = ShiftLeft32; #endif *shift = 12; break; case ASIOSTInt32LSB24: /* dest: paInt32, 8 bit shift, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = SwapShiftLeft32; #else *converter = ShiftLeft32; #endif *shift = 8; break; case ASIOSTInt24MSB: /* dest: paInt24, no conversion necessary, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = Swap24; #endif break; case ASIOSTInt24LSB: /* dest: paInt24, no conversion necessary, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = Swap24; #endif break; } } static void SelectPaToAsioConverter( ASIOSampleType type, PaAsioBufferConverter **converter, long *shift ) { *shift = 0; *converter = 0; switch (type) { case ASIOSTInt16MSB: /* src: paInt16, no conversion necessary, possible byte swap*/ #ifdef PA_LSB_IS_NATIVE_ *converter = Swap16; #endif break; case ASIOSTInt16LSB: /* src: paInt16, no conversion necessary, possible byte swap*/ #ifdef PA_MSB_IS_NATIVE_ *converter = Swap16; #endif break; case ASIOSTFloat32MSB: /* src: paFloat32, no conversion necessary, possible byte swap*/ #ifdef PA_LSB_IS_NATIVE_ *converter = Swap32; #endif break; case ASIOSTFloat32LSB: /* src: paFloat32, no conversion necessary, possible byte swap*/ #ifdef PA_MSB_IS_NATIVE_ *converter = Swap32; #endif break; case ASIOSTFloat64MSB: /* src: paFloat32, in-place conversion to/from float32, possible byte swap*/ #ifdef PA_LSB_IS_NATIVE_ *converter = ConvertFloat32ToFloat64Swap64; #else *converter = ConvertFloat32ToFloat64; #endif break; case ASIOSTFloat64LSB: /* src: paFloat32, in-place conversion to/from float32, possible byte swap*/ #ifdef PA_MSB_IS_NATIVE_ *converter = ConvertFloat32ToFloat64Swap64; #else *converter = ConvertFloat32ToFloat64; #endif break; case ASIOSTInt32MSB: /* src: paInt32, no conversion necessary, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = Swap32; #endif break; case ASIOSTInt32LSB: /* src: paInt32, no conversion necessary, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = Swap32; #endif break; case ASIOSTInt32MSB16: /* src: paInt32, 16 bit shift, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = ShiftRightSwap32; #else *converter = ShiftRight32; #endif *shift = 16; break; case ASIOSTInt32MSB18: /* src: paInt32, 14 bit shift, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = ShiftRightSwap32; #else *converter = ShiftRight32; #endif *shift = 14; break; case ASIOSTInt32MSB20: /* src: paInt32, 12 bit shift, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = ShiftRightSwap32; #else *converter = ShiftRight32; #endif *shift = 12; break; case ASIOSTInt32MSB24: /* src: paInt32, 8 bit shift, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = ShiftRightSwap32; #else *converter = ShiftRight32; #endif *shift = 8; break; case ASIOSTInt32LSB16: /* src: paInt32, 16 bit shift, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = ShiftRightSwap32; #else *converter = ShiftRight32; #endif *shift = 16; break; case ASIOSTInt32LSB18: /* src: paInt32, 14 bit shift, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = ShiftRightSwap32; #else *converter = ShiftRight32; #endif *shift = 14; break; case ASIOSTInt32LSB20: /* src: paInt32, 12 bit shift, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = ShiftRightSwap32; #else *converter = ShiftRight32; #endif *shift = 12; break; case ASIOSTInt32LSB24: /* src: paInt32, 8 bit shift, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = ShiftRightSwap32; #else *converter = ShiftRight32; #endif *shift = 8; break; case ASIOSTInt24MSB: /* src: paInt24, no conversion necessary, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = Swap24; #endif break; case ASIOSTInt24LSB: /* src: paInt24, no conversion necessary, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = Swap24; #endif break; } } typedef struct PaAsioDeviceInfo { PaDeviceInfo commonDeviceInfo; long minBufferSize; long maxBufferSize; long preferredBufferSize; long bufferGranularity; ASIOChannelInfo *asioChannelInfos; } PaAsioDeviceInfo; PaError PaAsio_GetAvailableBufferSizes( PaDeviceIndex device, long *minBufferSizeFrames, long *maxBufferSizeFrames, long *preferredBufferSizeFrames, long *granularity ) { PaError result; PaUtilHostApiRepresentation *hostApi; PaDeviceIndex hostApiDevice; result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO ); if( result == paNoError ) { result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, device, hostApi ); if( result == paNoError ) { PaAsioDeviceInfo *asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[hostApiDevice]; *minBufferSizeFrames = asioDeviceInfo->minBufferSize; *maxBufferSizeFrames = asioDeviceInfo->maxBufferSize; *preferredBufferSizeFrames = asioDeviceInfo->preferredBufferSize; *granularity = asioDeviceInfo->bufferGranularity; } } return result; } /* Unload whatever we loaded in LoadAsioDriver(). */ static void UnloadAsioDriver( void ) { ASIOExit(); } /* load the asio driver named by and return statistics about the driver in info. If no error occurred, the driver will remain open and must be closed by the called by calling UnloadAsioDriver() - if an error is returned the driver will already be unloaded. */ static PaError LoadAsioDriver( PaAsioHostApiRepresentation *asioHostApi, const char *driverName, PaAsioDriverInfo *driverInfo, void *systemSpecific ) { PaError result = paNoError; ASIOError asioError; int asioIsInitialized = 0; if( !asioHostApi->asioDrivers->loadDriver( const_cast(driverName) ) ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_HOST_ERROR( 0, "Failed to load ASIO driver" ); goto error; } memset( &driverInfo->asioDriverInfo, 0, sizeof(ASIODriverInfo) ); driverInfo->asioDriverInfo.asioVersion = 2; driverInfo->asioDriverInfo.sysRef = systemSpecific; if( (asioError = ASIOInit( &driverInfo->asioDriverInfo )) != ASE_OK ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); goto error; } else { asioIsInitialized = 1; } if( (asioError = ASIOGetChannels(&driverInfo->inputChannelCount, &driverInfo->outputChannelCount)) != ASE_OK ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); goto error; } if( (asioError = ASIOGetBufferSize(&driverInfo->bufferMinSize, &driverInfo->bufferMaxSize, &driverInfo->bufferPreferredSize, &driverInfo->bufferGranularity)) != ASE_OK ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); goto error; } if( ASIOOutputReady() == ASE_OK ) driverInfo->postOutput = true; else driverInfo->postOutput = false; return result; error: if( asioIsInitialized ) { ASIOExit(); } return result; } #define PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_ 13 /* must be the same number of elements as in the array below */ static ASIOSampleRate defaultSampleRateSearchOrder_[] = {44100.0, 48000.0, 32000.0, 24000.0, 22050.0, 88200.0, 96000.0, 192000.0, 16000.0, 12000.0, 11025.0, 9600.0, 8000.0 }; static PaError InitPaDeviceInfoFromAsioDriver( PaAsioHostApiRepresentation *asioHostApi, const char *driverName, int driverIndex, PaDeviceInfo *deviceInfo, PaAsioDeviceInfo *asioDeviceInfo ) { PaError result = paNoError; /* Due to the headless design of the ASIO API, drivers are free to write over data given to them (like M-Audio drivers f.i.). This is an attempt to overcome that. */ union _tag_local { PaAsioDriverInfo info; char _padding[4096]; } paAsioDriver; asioDeviceInfo->asioChannelInfos = 0; /* we check this below to handle error cleanup */ result = LoadAsioDriver( asioHostApi, driverName, &paAsioDriver.info, asioHostApi->systemSpecific ); if( result == paNoError ) { PA_DEBUG(("PaAsio_Initialize: drv:%d name = %s\n", driverIndex,deviceInfo->name)); PA_DEBUG(("PaAsio_Initialize: drv:%d inputChannels = %d\n", driverIndex, paAsioDriver.info.inputChannelCount)); PA_DEBUG(("PaAsio_Initialize: drv:%d outputChannels = %d\n", driverIndex, paAsioDriver.info.outputChannelCount)); PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMinSize = %d\n", driverIndex, paAsioDriver.info.bufferMinSize)); PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMaxSize = %d\n", driverIndex, paAsioDriver.info.bufferMaxSize)); PA_DEBUG(("PaAsio_Initialize: drv:%d bufferPreferredSize = %d\n", driverIndex, paAsioDriver.info.bufferPreferredSize)); PA_DEBUG(("PaAsio_Initialize: drv:%d bufferGranularity = %d\n", driverIndex, paAsioDriver.info.bufferGranularity)); deviceInfo->maxInputChannels = paAsioDriver.info.inputChannelCount; deviceInfo->maxOutputChannels = paAsioDriver.info.outputChannelCount; deviceInfo->defaultSampleRate = 0.; bool foundDefaultSampleRate = false; for( int j=0; j < PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_; ++j ) { ASIOError asioError = ASIOCanSampleRate( defaultSampleRateSearchOrder_[j] ); if( asioError != ASE_NoClock && asioError != ASE_NotPresent ) { deviceInfo->defaultSampleRate = defaultSampleRateSearchOrder_[j]; foundDefaultSampleRate = true; break; } } PA_DEBUG(("PaAsio_Initialize: drv:%d defaultSampleRate = %f\n", driverIndex, deviceInfo->defaultSampleRate)); if( foundDefaultSampleRate ){ /* calculate default latency values from bufferPreferredSize for default low latency, and bufferMaxSize for default high latency. use the default sample rate to convert from samples to seconds. Without knowing what sample rate the user will use this is the best we can do. */ double defaultLowLatency = paAsioDriver.info.bufferPreferredSize / deviceInfo->defaultSampleRate; deviceInfo->defaultLowInputLatency = defaultLowLatency; deviceInfo->defaultLowOutputLatency = defaultLowLatency; double defaultHighLatency = paAsioDriver.info.bufferMaxSize / deviceInfo->defaultSampleRate; if( defaultHighLatency < defaultLowLatency ) defaultHighLatency = defaultLowLatency; /* just in case the driver returns something strange */ deviceInfo->defaultHighInputLatency = defaultHighLatency; deviceInfo->defaultHighOutputLatency = defaultHighLatency; }else{ deviceInfo->defaultLowInputLatency = 0.; deviceInfo->defaultLowOutputLatency = 0.; deviceInfo->defaultHighInputLatency = 0.; deviceInfo->defaultHighOutputLatency = 0.; } PA_DEBUG(("PaAsio_Initialize: drv:%d defaultLowInputLatency = %f\n", driverIndex, deviceInfo->defaultLowInputLatency)); PA_DEBUG(("PaAsio_Initialize: drv:%d defaultLowOutputLatency = %f\n", driverIndex, deviceInfo->defaultLowOutputLatency)); PA_DEBUG(("PaAsio_Initialize: drv:%d defaultHighInputLatency = %f\n", driverIndex, deviceInfo->defaultHighInputLatency)); PA_DEBUG(("PaAsio_Initialize: drv:%d defaultHighOutputLatency = %f\n", driverIndex, deviceInfo->defaultHighOutputLatency)); asioDeviceInfo->minBufferSize = paAsioDriver.info.bufferMinSize; asioDeviceInfo->maxBufferSize = paAsioDriver.info.bufferMaxSize; asioDeviceInfo->preferredBufferSize = paAsioDriver.info.bufferPreferredSize; asioDeviceInfo->bufferGranularity = paAsioDriver.info.bufferGranularity; asioDeviceInfo->asioChannelInfos = (ASIOChannelInfo*)PaUtil_GroupAllocateMemory( asioHostApi->allocations, sizeof(ASIOChannelInfo) * (deviceInfo->maxInputChannels + deviceInfo->maxOutputChannels) ); if( !asioDeviceInfo->asioChannelInfos ) { result = paInsufficientMemory; goto error_unload; } int a; for( a=0; a < deviceInfo->maxInputChannels; ++a ){ asioDeviceInfo->asioChannelInfos[a].channel = a; asioDeviceInfo->asioChannelInfos[a].isInput = ASIOTrue; ASIOError asioError = ASIOGetChannelInfo( &asioDeviceInfo->asioChannelInfos[a] ); if( asioError != ASE_OK ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); goto error_unload; } } for( a=0; a < deviceInfo->maxOutputChannels; ++a ){ int b = deviceInfo->maxInputChannels + a; asioDeviceInfo->asioChannelInfos[b].channel = a; asioDeviceInfo->asioChannelInfos[b].isInput = ASIOFalse; ASIOError asioError = ASIOGetChannelInfo( &asioDeviceInfo->asioChannelInfos[b] ); if( asioError != ASE_OK ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); goto error_unload; } } /* unload the driver */ UnloadAsioDriver(); } return result; error_unload: UnloadAsioDriver(); if( asioDeviceInfo->asioChannelInfos ){ PaUtil_GroupFreeMemory( asioHostApi->allocations, asioDeviceInfo->asioChannelInfos ); asioDeviceInfo->asioChannelInfos = 0; } return result; } /* we look up IsDebuggerPresent at runtime incase it isn't present (on Win95 for example) */ typedef BOOL (WINAPI *IsDebuggerPresentPtr)(VOID); IsDebuggerPresentPtr IsDebuggerPresent_ = 0; //FARPROC IsDebuggerPresent_ = 0; // this is the current way to do it apparently according to davidv PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) { PaError result = paNoError; int i, driverCount; PaAsioHostApiRepresentation *asioHostApi; PaAsioDeviceInfo *deviceInfoArray; char **names; asioHostApi = (PaAsioHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaAsioHostApiRepresentation) ); if( !asioHostApi ) { result = paInsufficientMemory; goto error; } memset( asioHostApi, 0, sizeof(PaAsioHostApiRepresentation) ); /* ensure all fields are zeroed. especially asioHostApi->allocations */ /* We initialize COM ourselves here and uninitialize it in Terminate(). This should be the only COM initialization needed in this module. The ASIO SDK may also initialize COM but since we want to reduce dependency on the ASIO SDK we manage COM initialization ourselves. There used to be code that initialized COM in other situations such as when creating a Stream. This made PA work when calling Pa_CreateStream from a non-main thread. However we currently consider initialization of COM in non-main threads to be the caller's responsibility. */ result = PaWinUtil_CoInitialize( paASIO, &asioHostApi->comInitializationResult ); if( result != paNoError ) { goto error; } asioHostApi->asioDrivers = 0; /* avoid surprises in our error handler below */ asioHostApi->allocations = PaUtil_CreateAllocationGroup(); if( !asioHostApi->allocations ) { result = paInsufficientMemory; goto error; } /* Allocate the AsioDrivers() driver list (class from ASIO SDK) */ try { asioHostApi->asioDrivers = new AsioDrivers(); /* invokes CoInitialize(0) in AsioDriverList::AsioDriverList */ } catch (std::bad_alloc) { asioHostApi->asioDrivers = 0; } /* some implementations of new (ie MSVC, see http://support.microsoft.com/?kbid=167733) don't throw std::bad_alloc, so we also explicitly test for a null return. */ if( asioHostApi->asioDrivers == 0 ) { result = paInsufficientMemory; goto error; } asioDrivers = asioHostApi->asioDrivers; /* keep SDK global in sync until we stop depending on it */ asioHostApi->systemSpecific = 0; asioHostApi->openAsioDeviceIndex = paNoDevice; *hostApi = &asioHostApi->inheritedHostApiRep; (*hostApi)->info.structVersion = 1; (*hostApi)->info.type = paASIO; (*hostApi)->info.name = "ASIO"; (*hostApi)->info.deviceCount = 0; #ifdef WINDOWS /* use desktop window as system specific ptr */ asioHostApi->systemSpecific = GetDesktopWindow(); #endif /* driverCount is the number of installed drivers - not necessarily the number of installed physical devices. */ #if MAC driverCount = asioHostApi->asioDrivers->getNumFragments(); #elif WINDOWS driverCount = asioHostApi->asioDrivers->asioGetNumDev(); #endif if( driverCount > 0 ) { names = GetAsioDriverNames( asioHostApi, asioHostApi->allocations, driverCount ); if( !names ) { result = paInsufficientMemory; goto error; } /* allocate enough space for all drivers, even if some aren't installed */ (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( asioHostApi->allocations, sizeof(PaDeviceInfo*) * driverCount ); if( !(*hostApi)->deviceInfos ) { result = paInsufficientMemory; goto error; } /* allocate all device info structs in a contiguous block */ deviceInfoArray = (PaAsioDeviceInfo*)PaUtil_GroupAllocateMemory( asioHostApi->allocations, sizeof(PaAsioDeviceInfo) * driverCount ); if( !deviceInfoArray ) { result = paInsufficientMemory; goto error; } IsDebuggerPresent_ = (IsDebuggerPresentPtr)GetProcAddress( LoadLibraryA( "Kernel32.dll" ), "IsDebuggerPresent" ); for( i=0; i < driverCount; ++i ) { PA_DEBUG(("ASIO names[%d]:%s\n",i,names[i])); // Since portaudio opens ALL ASIO drivers, and no one else does that, // we face fact that some drivers were not meant for it, drivers which act // like shells on top of REAL drivers, for instance. // so we get duplicate handles, locks and other problems. // so lets NOT try to load any such wrappers. // The ones i [davidv] know of so far are: if ( strcmp (names[i],"ASIO DirectX Full Duplex Driver") == 0 || strcmp (names[i],"ASIO Multimedia Driver") == 0 || strncmp(names[i],"Premiere",8) == 0 //"Premiere Elements Windows Sound 1.0" || strncmp(names[i],"Adobe",5) == 0 //"Adobe Default Windows Sound 1.5" ) { PA_DEBUG(("BLACKLISTED!!!\n")); continue; } if( IsDebuggerPresent_ && IsDebuggerPresent_() ) { /* ASIO Digidesign Driver uses PACE copy protection which quits out if a debugger is running. So we don't load it if a debugger is running. */ if( strcmp(names[i], "ASIO Digidesign Driver") == 0 ) { PA_DEBUG(("BLACKLISTED!!! ASIO Digidesign Driver would quit the debugger\n")); continue; } } /* Attempt to init device info from the asio driver... */ { PaAsioDeviceInfo *asioDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ]; PaDeviceInfo *deviceInfo = &asioDeviceInfo->commonDeviceInfo; deviceInfo->structVersion = 2; deviceInfo->hostApi = hostApiIndex; deviceInfo->name = names[i]; if( InitPaDeviceInfoFromAsioDriver( asioHostApi, names[i], i, deviceInfo, asioDeviceInfo ) == paNoError ) { (*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo; ++(*hostApi)->info.deviceCount; } else { PA_DEBUG(("Skipping ASIO device:%s\n",names[i])); continue; } } } } if( (*hostApi)->info.deviceCount > 0 ) { (*hostApi)->info.defaultInputDevice = 0; (*hostApi)->info.defaultOutputDevice = 0; } else { (*hostApi)->info.defaultInputDevice = paNoDevice; (*hostApi)->info.defaultOutputDevice = paNoDevice; } (*hostApi)->Terminate = Terminate; (*hostApi)->OpenStream = OpenStream; (*hostApi)->IsFormatSupported = IsFormatSupported; PaUtil_InitializeStreamInterface( &asioHostApi->callbackStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, GetStreamCpuLoad, PaUtil_DummyRead, PaUtil_DummyWrite, PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); PaUtil_InitializeStreamInterface( &asioHostApi->blockingStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, PaUtil_DummyGetCpuLoad, ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable ); return result; error: if( asioHostApi ) { if( asioHostApi->allocations ) { PaUtil_FreeAllAllocations( asioHostApi->allocations ); PaUtil_DestroyAllocationGroup( asioHostApi->allocations ); } delete asioHostApi->asioDrivers; asioDrivers = 0; /* keep SDK global in sync until we stop depending on it */ PaWinUtil_CoUninitialize( paASIO, &asioHostApi->comInitializationResult ); PaUtil_FreeMemory( asioHostApi ); } return result; } static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) { PaAsioHostApiRepresentation *asioHostApi = (PaAsioHostApiRepresentation*)hostApi; /* IMPLEMENT ME: - clean up any resources not handled by the allocation group (need to review if there are any) */ if( asioHostApi->allocations ) { PaUtil_FreeAllAllocations( asioHostApi->allocations ); PaUtil_DestroyAllocationGroup( asioHostApi->allocations ); } delete asioHostApi->asioDrivers; asioDrivers = 0; /* keep SDK global in sync until we stop depending on it */ PaWinUtil_CoUninitialize( paASIO, &asioHostApi->comInitializationResult ); PaUtil_FreeMemory( asioHostApi ); } static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { PaError result = paNoError; PaAsioHostApiRepresentation *asioHostApi = (PaAsioHostApiRepresentation*)hostApi; PaAsioDriverInfo *driverInfo = &asioHostApi->openAsioDriverInfo; int inputChannelCount, outputChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; PaDeviceIndex asioDeviceIndex; ASIOError asioError; if( inputParameters && outputParameters ) { /* full duplex ASIO stream must use the same device for input and output */ if( inputParameters->device != outputParameters->device ) return paBadIODeviceCombination; } if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( inputSampleFormat & paCustomFormat ) return paSampleFormatNotSupported; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; asioDeviceIndex = inputParameters->device; /* validate inputStreamInfo */ /** @todo do more validation here */ // if( inputParameters->hostApiSpecificStreamInfo ) // return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else { inputChannelCount = 0; } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( outputSampleFormat & paCustomFormat ) return paSampleFormatNotSupported; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; asioDeviceIndex = outputParameters->device; /* validate outputStreamInfo */ /** @todo do more validation here */ // if( outputParameters->hostApiSpecificStreamInfo ) // return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else { outputChannelCount = 0; } /* if an ASIO device is open we can only get format information for the currently open device */ if( asioHostApi->openAsioDeviceIndex != paNoDevice && asioHostApi->openAsioDeviceIndex != asioDeviceIndex ) { return paDeviceUnavailable; } /* NOTE: we load the driver and use its current settings rather than the ones in our device info structure which may be stale */ /* open the device if it's not already open */ if( asioHostApi->openAsioDeviceIndex == paNoDevice ) { result = LoadAsioDriver( asioHostApi, asioHostApi->inheritedHostApiRep.deviceInfos[ asioDeviceIndex ]->name, driverInfo, asioHostApi->systemSpecific ); if( result != paNoError ) return result; } /* check that input device can support inputChannelCount */ if( inputChannelCount > 0 ) { if( inputChannelCount > driverInfo->inputChannelCount ) { result = paInvalidChannelCount; goto done; } } /* check that output device can support outputChannelCount */ if( outputChannelCount ) { if( outputChannelCount > driverInfo->outputChannelCount ) { result = paInvalidChannelCount; goto done; } } /* query for sample rate support */ asioError = ASIOCanSampleRate( sampleRate ); if( asioError == ASE_NoClock || asioError == ASE_NotPresent ) { result = paInvalidSampleRate; goto done; } done: /* close the device if it wasn't already open */ if( asioHostApi->openAsioDeviceIndex == paNoDevice ) { UnloadAsioDriver(); /* not sure if we should check for errors here */ } if( result == paNoError ) return paFormatIsSupported; else return result; } /** A data structure specifically for storing blocking i/o related data. */ typedef struct PaAsioStreamBlockingState { int stopFlag; /**< Flag indicating that block processing is to be stopped. */ unsigned long writeBuffersRequested; /**< The number of available output buffers, requested by the #WriteStream() function. */ unsigned long readFramesRequested; /**< The number of available input frames, requested by the #ReadStream() function. */ int writeBuffersRequestedFlag; /**< Flag to indicate that #WriteStream() has requested more output buffers to be available. */ int readFramesRequestedFlag; /**< Flag to indicate that #ReadStream() requires more input frames to be available. */ HANDLE writeBuffersReadyEvent; /**< Event to signal that requested output buffers are available. */ HANDLE readFramesReadyEvent; /**< Event to signal that requested input frames are available. */ void *writeRingBufferData; /**< The actual ring buffer memory, used by the output ring buffer. */ void *readRingBufferData; /**< The actual ring buffer memory, used by the input ring buffer. */ PaUtilRingBuffer writeRingBuffer; /**< Frame-aligned blocking i/o ring buffer to store output data (interleaved user format). */ PaUtilRingBuffer readRingBuffer; /**< Frame-aligned blocking i/o ring buffer to store input data (interleaved user format). */ long writeRingBufferInitialFrames; /**< The initial number of silent frames within the output ring buffer. */ const void **writeStreamBuffer; /**< Temp buffer, used by #WriteStream() for handling non-interleaved data. */ void **readStreamBuffer; /**< Temp buffer, used by #ReadStream() for handling non-interleaved data. */ PaUtilBufferProcessor bufferProcessor; /**< Buffer processor, used to handle the blocking i/o ring buffers. */ int outputUnderflowFlag; /**< Flag to signal an output underflow from within the callback function. */ int inputOverflowFlag; /**< Flag to signal an input overflow from within the callback function. */ } PaAsioStreamBlockingState; /* PaAsioStream - a stream data structure specifically for this implementation */ typedef struct PaAsioStream { PaUtilStreamRepresentation streamRepresentation; PaUtilCpuLoadMeasurer cpuLoadMeasurer; PaUtilBufferProcessor bufferProcessor; PaAsioHostApiRepresentation *asioHostApi; unsigned long framesPerHostCallback; /* ASIO driver info - these may not be needed for the life of the stream, but store them here until we work out how format conversion is going to work. */ ASIOBufferInfo *asioBufferInfos; ASIOChannelInfo *asioChannelInfos; long asioInputLatencyFrames, asioOutputLatencyFrames; // actual latencies returned by asio long inputChannelCount, outputChannelCount; bool postOutput; void **bufferPtrs; /* this is carved up for inputBufferPtrs and outputBufferPtrs */ void **inputBufferPtrs[2]; void **outputBufferPtrs[2]; PaAsioBufferConverter *inputBufferConverter; long inputShift; PaAsioBufferConverter *outputBufferConverter; long outputShift; volatile bool stopProcessing; int stopPlayoutCount; HANDLE completedBuffersPlayedEvent; bool streamFinishedCallbackCalled; int isStopped; volatile int isActive; volatile bool zeroOutput; /* all future calls to the callback will output silence */ volatile long reenterCount; volatile long reenterError; PaStreamCallbackFlags callbackFlags; PaAsioStreamBlockingState *blockingState; /**< Blocking i/o data struct, or NULL when using callback interface. */ } PaAsioStream; static PaAsioStream *theAsioStream = 0; /* due to ASIO sdk limitations there can be only one stream */ static void ZeroOutputBuffers( PaAsioStream *stream, long index ) { int i; for( i=0; i < stream->outputChannelCount; ++i ) { void *buffer = stream->asioBufferInfos[ i + stream->inputChannelCount ].buffers[index]; int bytesPerSample = BytesPerAsioSample( stream->asioChannelInfos[ i + stream->inputChannelCount ].type ); memset( buffer, 0, stream->framesPerHostCallback * bytesPerSample ); } } /* return the next power of two >= x. Returns the input parameter if it is already a power of two. http://stackoverflow.com/questions/364985/algorithm-for-finding-the-smallest-power-of-two-thats-greater-or-equal-to-a-giv */ static unsigned long NextPowerOfTwo( unsigned long x ) { --x; x |= x >> 1; x |= x >> 2; x |= x >> 4; x |= x >> 8; x |= x >> 16; /* If you needed to deal with numbers > 2^32 the following would be needed. For latencies, we don't deal with values this large. x |= x >> 16; */ return x + 1; } static unsigned long SelectHostBufferSizeForUnspecifiedUserFramesPerBuffer( unsigned long targetBufferingLatencyFrames, PaAsioDriverInfo *driverInfo ) { /* Choose a host buffer size based only on targetBufferingLatencyFrames and the device's supported buffer sizes. Always returns a valid value. */ unsigned long result; if( targetBufferingLatencyFrames <= (unsigned long)driverInfo->bufferMinSize ) { result = driverInfo->bufferMinSize; } else if( targetBufferingLatencyFrames >= (unsigned long)driverInfo->bufferMaxSize ) { result = driverInfo->bufferMaxSize; } else { if( driverInfo->bufferGranularity == 0 ) /* single fixed host buffer size */ { /* The documentation states that bufferGranularity should be zero when bufferMinSize, bufferMaxSize and bufferPreferredSize are the same. We assume that is the case. */ result = driverInfo->bufferPreferredSize; } else if( driverInfo->bufferGranularity == -1 ) /* power-of-two */ { /* We assume bufferMinSize and bufferMaxSize are powers of two. */ result = NextPowerOfTwo( targetBufferingLatencyFrames ); if( result < (unsigned long)driverInfo->bufferMinSize ) result = driverInfo->bufferMinSize; if( result > (unsigned long)driverInfo->bufferMaxSize ) result = driverInfo->bufferMaxSize; } else /* modulo bufferGranularity */ { /* round up to the next multiple of granularity */ unsigned long n = (targetBufferingLatencyFrames + driverInfo->bufferGranularity - 1) / driverInfo->bufferGranularity; result = n * driverInfo->bufferGranularity; if( result < (unsigned long)driverInfo->bufferMinSize ) result = driverInfo->bufferMinSize; if( result > (unsigned long)driverInfo->bufferMaxSize ) result = driverInfo->bufferMaxSize; } } return result; } static unsigned long SelectHostBufferSizeForSpecifiedUserFramesPerBuffer( unsigned long targetBufferingLatencyFrames, unsigned long userFramesPerBuffer, PaAsioDriverInfo *driverInfo ) { /* Select a host buffer size conforming to targetBufferingLatencyFrames and the device's supported buffer sizes. The return value will always be a multiple of userFramesPerBuffer. If a valid buffer size can not be found the function returns 0. The current implementation uses a simple iterative search for clarity. Feel free to suggest a closed form solution. */ unsigned long result = 0; assert( userFramesPerBuffer != 0 ); if( driverInfo->bufferGranularity == 0 ) /* single fixed host buffer size */ { /* The documentation states that bufferGranularity should be zero when bufferMinSize, bufferMaxSize and bufferPreferredSize are the same. We assume that is the case. */ if( (driverInfo->bufferPreferredSize % userFramesPerBuffer) == 0 ) result = driverInfo->bufferPreferredSize; } else if( driverInfo->bufferGranularity == -1 ) /* power-of-two */ { /* We assume bufferMinSize and bufferMaxSize are powers of two. */ /* Search all powers of two in the range [bufferMinSize,bufferMaxSize] for multiples of userFramesPerBuffer. We prefer the first multiple that is equal or greater than targetBufferingLatencyFrames, or failing that, the largest multiple less than targetBufferingLatencyFrames. */ unsigned long x = (unsigned long)driverInfo->bufferMinSize; do { if( (x % userFramesPerBuffer) == 0 ) { /* any multiple of userFramesPerBuffer is acceptable */ result = x; if( result >= targetBufferingLatencyFrames ) break; /* stop. a value >= to targetBufferingLatencyFrames is ideal. */ } x *= 2; } while( x <= (unsigned long)driverInfo->bufferMaxSize ); } else /* modulo granularity */ { /* We assume bufferMinSize is a multiple of bufferGranularity. */ /* Search all multiples of bufferGranularity in the range [bufferMinSize,bufferMaxSize] for multiples of userFramesPerBuffer. We prefer the first multiple that is equal or greater than targetBufferingLatencyFrames, or failing that, the largest multiple less than targetBufferingLatencyFrames. */ unsigned long x = (unsigned long)driverInfo->bufferMinSize; do { if( (x % userFramesPerBuffer) == 0 ) { /* any multiple of userFramesPerBuffer is acceptable */ result = x; if( result >= targetBufferingLatencyFrames ) break; /* stop. a value >= to targetBufferingLatencyFrames is ideal. */ } x += driverInfo->bufferGranularity; } while( x <= (unsigned long)driverInfo->bufferMaxSize ); } return result; } static unsigned long SelectHostBufferSize( unsigned long targetBufferingLatencyFrames, unsigned long userFramesPerBuffer, PaAsioDriverInfo *driverInfo ) { unsigned long result = 0; /* We select a host buffer size based on the following requirements (in priority order): 1. The host buffer size must be permissible according to the ASIO driverInfo buffer size constraints (min, max, granularity or powers-of-two). 2. If the user specifies a non-zero framesPerBuffer parameter (userFramesPerBuffer here) the host buffer should be a multiple of this (subject to the constraints in (1) above). [NOTE: Where no permissible host buffer size is a multiple of userFramesPerBuffer, we choose a value as if userFramesPerBuffer were zero (i.e. we ignore it). This strategy is open for review ~ perhaps there are still "more optimal" buffer sizes related to userFramesPerBuffer that we could use.] 3. The host buffer size should be greater than or equal to targetBufferingLatencyFrames, subject to (1) and (2) above. Where it is not possible to select a host buffer size equal or greater than targetBufferingLatencyFrames, the highest buffer size conforming to (1) and (2) should be chosen. */ if( userFramesPerBuffer != 0 ) { /* userFramesPerBuffer is specified, try to find a buffer size that's a multiple of it */ result = SelectHostBufferSizeForSpecifiedUserFramesPerBuffer( targetBufferingLatencyFrames, userFramesPerBuffer, driverInfo ); } if( result == 0 ) { /* either userFramesPerBuffer was not specified, or we couldn't find a host buffer size that is a multiple of it. Select a host buffer size according to targetBufferingLatencyFrames and the ASIO driverInfo buffer size constraints. */ result = SelectHostBufferSizeForUnspecifiedUserFramesPerBuffer( targetBufferingLatencyFrames, driverInfo ); } return result; } /* returns channelSelectors if present */ static PaError ValidateAsioSpecificStreamInfo( const PaStreamParameters *streamParameters, const PaAsioStreamInfo *streamInfo, int deviceChannelCount, int **channelSelectors ) { if( streamInfo ) { if( streamInfo->size != sizeof( PaAsioStreamInfo ) || streamInfo->version != 1 ) { return paIncompatibleHostApiSpecificStreamInfo; } if( streamInfo->flags & paAsioUseChannelSelectors ) *channelSelectors = streamInfo->channelSelectors; if( !(*channelSelectors) ) return paIncompatibleHostApiSpecificStreamInfo; for( int i=0; i < streamParameters->channelCount; ++i ){ if( (*channelSelectors)[i] < 0 || (*channelSelectors)[i] >= deviceChannelCount ){ return paInvalidChannelCount; } } } return paNoError; } static bool IsUsingExternalClockSource() { bool result = false; ASIOError asioError; ASIOClockSource clocks[32]; long numSources=32; /* davidv: listing ASIO Clock sources. there is an ongoing investigation by me about whether or not to call ASIOSetSampleRate if an external Clock is used. A few drivers expected different things here */ asioError = ASIOGetClockSources(clocks, &numSources); if( asioError != ASE_OK ){ PA_DEBUG(("ERROR: ASIOGetClockSources: %s\n", PaAsio_GetAsioErrorText(asioError) )); }else{ PA_DEBUG(("INFO ASIOGetClockSources listing %d clocks\n", numSources )); for (int i=0;iopenAsioDeviceIndex != paNoDevice ) { PA_DEBUG(("OpenStream paDeviceUnavailable\n")); return paDeviceUnavailable; } assert( theAsioStream == 0 ); if( inputParameters && outputParameters ) { /* full duplex ASIO stream must use the same device for input and output */ if( inputParameters->device != outputParameters->device ) { PA_DEBUG(("OpenStream paBadIODeviceCombination\n")); return paBadIODeviceCombination; } } if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; suggestedInputLatencyFrames = (unsigned long)((inputParameters->suggestedLatency * sampleRate)+0.5f); /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; asioDeviceIndex = inputParameters->device; PaAsioDeviceInfo *asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[asioDeviceIndex]; /* validate hostApiSpecificStreamInfo */ inputStreamInfo = (PaAsioStreamInfo*)inputParameters->hostApiSpecificStreamInfo; result = ValidateAsioSpecificStreamInfo( inputParameters, inputStreamInfo, asioDeviceInfo->commonDeviceInfo.maxInputChannels, &inputChannelSelectors ); if( result != paNoError ) return result; } else { inputChannelCount = 0; inputSampleFormat = 0; suggestedInputLatencyFrames = 0; } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; suggestedOutputLatencyFrames = (unsigned long)((outputParameters->suggestedLatency * sampleRate)+0.5f); /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; asioDeviceIndex = outputParameters->device; PaAsioDeviceInfo *asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[asioDeviceIndex]; /* validate hostApiSpecificStreamInfo */ outputStreamInfo = (PaAsioStreamInfo*)outputParameters->hostApiSpecificStreamInfo; result = ValidateAsioSpecificStreamInfo( outputParameters, outputStreamInfo, asioDeviceInfo->commonDeviceInfo.maxOutputChannels, &outputChannelSelectors ); if( result != paNoError ) return result; } else { outputChannelCount = 0; outputSampleFormat = 0; suggestedOutputLatencyFrames = 0; } driverInfo = &asioHostApi->openAsioDriverInfo; /* NOTE: we load the driver and use its current settings rather than the ones in our device info structure which may be stale */ result = LoadAsioDriver( asioHostApi, asioHostApi->inheritedHostApiRep.deviceInfos[ asioDeviceIndex ]->name, driverInfo, asioHostApi->systemSpecific ); if( result == paNoError ) asioIsInitialized = 1; else{ PA_DEBUG(("OpenStream ERROR1 - LoadAsioDriver returned %d\n", result)); goto error; } /* check that input device can support inputChannelCount */ if( inputChannelCount > 0 ) { if( inputChannelCount > driverInfo->inputChannelCount ) { result = paInvalidChannelCount; PA_DEBUG(("OpenStream ERROR2\n")); goto error; } } /* check that output device can support outputChannelCount */ if( outputChannelCount ) { if( outputChannelCount > driverInfo->outputChannelCount ) { result = paInvalidChannelCount; PA_DEBUG(("OpenStream ERROR3\n")); goto error; } } result = ValidateAndSetSampleRate( sampleRate ); if( result != paNoError ) goto error; /* IMPLEMENT ME: - if a full duplex stream is requested, check that the combination of input and output parameters is supported */ /* validate platform specific flags */ if( (streamFlags & paPlatformSpecificFlags) != 0 ){ PA_DEBUG(("OpenStream invalid flags!!\n")); return paInvalidFlag; /* unexpected platform specific flag */ } stream = (PaAsioStream*)PaUtil_AllocateMemory( sizeof(PaAsioStream) ); if( !stream ) { result = paInsufficientMemory; PA_DEBUG(("OpenStream ERROR5\n")); goto error; } stream->blockingState = NULL; /* Blocking i/o not initialized, yet. */ stream->completedBuffersPlayedEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); if( stream->completedBuffersPlayedEvent == NULL ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() ); PA_DEBUG(("OpenStream ERROR6\n")); goto error; } completedBuffersPlayedEventInited = 1; stream->asioBufferInfos = 0; /* for deallocation in error */ stream->asioChannelInfos = 0; /* for deallocation in error */ stream->bufferPtrs = 0; /* for deallocation in error */ /* Using blocking i/o interface... */ if( usingBlockingIo ) { /* Blocking i/o is implemented by running callback mode, using a special blocking i/o callback. */ streamCallback = BlockingIoPaCallback; /* Setup PA to use the ASIO blocking i/o callback. */ userData = &theAsioStream; /* The callback user data will be the PA ASIO stream. */ PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &asioHostApi->blockingStreamInterface, streamCallback, userData ); } else /* Using callback interface... */ { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &asioHostApi->callbackStreamInterface, streamCallback, userData ); } PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate ); stream->asioBufferInfos = (ASIOBufferInfo*)PaUtil_AllocateMemory( sizeof(ASIOBufferInfo) * (inputChannelCount + outputChannelCount) ); if( !stream->asioBufferInfos ) { result = paInsufficientMemory; PA_DEBUG(("OpenStream ERROR7\n")); goto error; } for( i=0; i < inputChannelCount; ++i ) { ASIOBufferInfo *info = &stream->asioBufferInfos[i]; info->isInput = ASIOTrue; if( inputChannelSelectors ){ // inputChannelSelectors values have already been validated in // ValidateAsioSpecificStreamInfo() above info->channelNum = inputChannelSelectors[i]; }else{ info->channelNum = i; } info->buffers[0] = info->buffers[1] = 0; } for( i=0; i < outputChannelCount; ++i ){ ASIOBufferInfo *info = &stream->asioBufferInfos[inputChannelCount+i]; info->isInput = ASIOFalse; if( outputChannelSelectors ){ // outputChannelSelectors values have already been validated in // ValidateAsioSpecificStreamInfo() above info->channelNum = outputChannelSelectors[i]; }else{ info->channelNum = i; } info->buffers[0] = info->buffers[1] = 0; } /* Using blocking i/o interface... */ if( usingBlockingIo ) { /** @todo REVIEW selection of host buffer size for blocking i/o */ framesPerHostBuffer = SelectHostBufferSize( 0, framesPerBuffer, driverInfo ); } else /* Using callback interface... */ { /* Select the host buffer size based on user framesPerBuffer and the maximum of suggestedInputLatencyFrames and suggestedOutputLatencyFrames. We should subtract any fixed known driver latency from suggestedLatencyFrames before computing the host buffer size. However, the ASIO API doesn't provide a method for determining fixed latencies independent of the host buffer size. ASIOGetLatencies() only returns latencies after the buffer size has been configured, so we can't reliably use it to determine fixed latencies here. We could set the preferred buffer size and then subtract it from the values returned from ASIOGetLatencies, but this would not be 100% reliable, so we don't do it. */ unsigned long targetBufferingLatencyFrames = (( suggestedInputLatencyFrames > suggestedOutputLatencyFrames ) ? suggestedInputLatencyFrames : suggestedOutputLatencyFrames); framesPerHostBuffer = SelectHostBufferSize( targetBufferingLatencyFrames, framesPerBuffer, driverInfo ); } PA_DEBUG(("PaAsioOpenStream: framesPerHostBuffer :%d\n", framesPerHostBuffer)); asioError = ASIOCreateBuffers( stream->asioBufferInfos, inputChannelCount+outputChannelCount, framesPerHostBuffer, &asioCallbacks_ ); if( asioError != ASE_OK && framesPerHostBuffer != (unsigned long)driverInfo->bufferPreferredSize ) { PA_DEBUG(("ERROR: ASIOCreateBuffers: %s\n", PaAsio_GetAsioErrorText(asioError) )); /* Some buggy drivers (like the Hoontech DSP24) give incorrect [min, preferred, max] values They should work with the preferred size value, thus if Pa_ASIO_CreateBuffers fails with the hostBufferSize computed in SelectHostBufferSize, we try again with the preferred size. */ framesPerHostBuffer = driverInfo->bufferPreferredSize; PA_DEBUG(("PaAsioOpenStream: CORRECTED framesPerHostBuffer :%d\n", framesPerHostBuffer)); ASIOError asioError2 = ASIOCreateBuffers( stream->asioBufferInfos, inputChannelCount+outputChannelCount, framesPerHostBuffer, &asioCallbacks_ ); if( asioError2 == ASE_OK ) asioError = ASE_OK; } if( asioError != ASE_OK ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); PA_DEBUG(("OpenStream ERROR9\n")); goto error; } asioBuffersCreated = 1; stream->asioChannelInfos = (ASIOChannelInfo*)PaUtil_AllocateMemory( sizeof(ASIOChannelInfo) * (inputChannelCount + outputChannelCount) ); if( !stream->asioChannelInfos ) { result = paInsufficientMemory; PA_DEBUG(("OpenStream ERROR10\n")); goto error; } for( i=0; i < inputChannelCount + outputChannelCount; ++i ) { stream->asioChannelInfos[i].channel = stream->asioBufferInfos[i].channelNum; stream->asioChannelInfos[i].isInput = stream->asioBufferInfos[i].isInput; asioError = ASIOGetChannelInfo( &stream->asioChannelInfos[i] ); if( asioError != ASE_OK ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); PA_DEBUG(("OpenStream ERROR11\n")); goto error; } } stream->bufferPtrs = (void**)PaUtil_AllocateMemory( 2 * sizeof(void*) * (inputChannelCount + outputChannelCount) ); if( !stream->bufferPtrs ) { result = paInsufficientMemory; PA_DEBUG(("OpenStream ERROR12\n")); goto error; } if( inputChannelCount > 0 ) { stream->inputBufferPtrs[0] = stream-> bufferPtrs; stream->inputBufferPtrs[1] = &stream->bufferPtrs[inputChannelCount]; for( i=0; iinputBufferPtrs[0][i] = stream->asioBufferInfos[i].buffers[0]; stream->inputBufferPtrs[1][i] = stream->asioBufferInfos[i].buffers[1]; } } else { stream->inputBufferPtrs[0] = 0; stream->inputBufferPtrs[1] = 0; } if( outputChannelCount > 0 ) { stream->outputBufferPtrs[0] = &stream->bufferPtrs[inputChannelCount*2]; stream->outputBufferPtrs[1] = &stream->bufferPtrs[inputChannelCount*2 + outputChannelCount]; for( i=0; ioutputBufferPtrs[0][i] = stream->asioBufferInfos[inputChannelCount+i].buffers[0]; stream->outputBufferPtrs[1][i] = stream->asioBufferInfos[inputChannelCount+i].buffers[1]; } } else { stream->outputBufferPtrs[0] = 0; stream->outputBufferPtrs[1] = 0; } if( inputChannelCount > 0 ) { /* FIXME: assume all channels use the same type for now see: "ASIO devices with multiple sample formats are unsupported" http://www.portaudio.com/trac/ticket/106 */ ASIOSampleType inputType = stream->asioChannelInfos[0].type; PA_DEBUG(("ASIO Input type:%d",inputType)); AsioSampleTypeLOG(inputType); hostInputSampleFormat = AsioSampleTypeToPaNativeSampleFormat( inputType ); SelectAsioToPaConverter( inputType, &stream->inputBufferConverter, &stream->inputShift ); } else { hostInputSampleFormat = 0; stream->inputBufferConverter = 0; } if( outputChannelCount > 0 ) { /* FIXME: assume all channels use the same type for now see: "ASIO devices with multiple sample formats are unsupported" http://www.portaudio.com/trac/ticket/106 */ ASIOSampleType outputType = stream->asioChannelInfos[inputChannelCount].type; PA_DEBUG(("ASIO Output type:%d",outputType)); AsioSampleTypeLOG(outputType); hostOutputSampleFormat = AsioSampleTypeToPaNativeSampleFormat( outputType ); SelectPaToAsioConverter( outputType, &stream->outputBufferConverter, &stream->outputShift ); } else { hostOutputSampleFormat = 0; stream->outputBufferConverter = 0; } /* Values returned by ASIOGetLatencies() include the latency introduced by the ASIO double buffer. */ ASIOGetLatencies( &stream->asioInputLatencyFrames, &stream->asioOutputLatencyFrames ); /* Using blocking i/o interface... */ if( usingBlockingIo ) { /* Allocate the blocking i/o input ring buffer memory. */ stream->blockingState = (PaAsioStreamBlockingState*)PaUtil_AllocateMemory( sizeof(PaAsioStreamBlockingState) ); if( !stream->blockingState ) { result = paInsufficientMemory; PA_DEBUG(("ERROR! Blocking i/o interface struct allocation failed in OpenStream()\n")); goto error; } /* Initialize blocking i/o interface struct. */ stream->blockingState->readFramesReadyEvent = NULL; /* Uninitialized, yet. */ stream->blockingState->writeBuffersReadyEvent = NULL; /* Uninitialized, yet. */ stream->blockingState->readRingBufferData = NULL; /* Uninitialized, yet. */ stream->blockingState->writeRingBufferData = NULL; /* Uninitialized, yet. */ stream->blockingState->readStreamBuffer = NULL; /* Uninitialized, yet. */ stream->blockingState->writeStreamBuffer = NULL; /* Uninitialized, yet. */ stream->blockingState->stopFlag = TRUE; /* Not started, yet. */ /* If the user buffer is unspecified */ if( framesPerBuffer == paFramesPerBufferUnspecified ) { /* Make the user buffer the same size as the host buffer. */ framesPerBuffer = framesPerHostBuffer; } /* Initialize callback buffer processor. */ result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor , inputChannelCount , inputSampleFormat & ~paNonInterleaved , /* Ring buffer. */ (hostInputSampleFormat | paNonInterleaved), /* Host format. */ outputChannelCount , outputSampleFormat & ~paNonInterleaved, /* Ring buffer. */ (hostOutputSampleFormat | paNonInterleaved), /* Host format. */ sampleRate , streamFlags , framesPerBuffer , /* Frames per ring buffer block. */ framesPerHostBuffer , /* Frames per asio buffer. */ paUtilFixedHostBufferSize , streamCallback , userData ); if( result != paNoError ){ PA_DEBUG(("OpenStream ERROR13\n")); goto error; } callbackBufferProcessorInited = TRUE; /* Initialize the blocking i/o buffer processor. */ result = PaUtil_InitializeBufferProcessor(&stream->blockingState->bufferProcessor, inputChannelCount , inputSampleFormat , /* User format. */ inputSampleFormat & ~paNonInterleaved , /* Ring buffer. */ outputChannelCount , outputSampleFormat , /* User format. */ outputSampleFormat & ~paNonInterleaved, /* Ring buffer. */ sampleRate , paClipOff | paDitherOff , /* Don't use dither nor clipping. */ framesPerBuffer , /* Frames per user buffer. */ framesPerBuffer , /* Frames per ring buffer block. */ paUtilBoundedHostBufferSize , NULL, NULL );/* No callback! */ if( result != paNoError ){ PA_DEBUG(("ERROR! Blocking i/o buffer processor initialization failed in OpenStream()\n")); goto error; } blockingBufferProcessorInited = TRUE; /* If input is requested. */ if( inputChannelCount ) { /* Create the callback sync-event. */ stream->blockingState->readFramesReadyEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); if( stream->blockingState->readFramesReadyEvent == NULL ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() ); PA_DEBUG(("ERROR! Blocking i/o \"read frames ready\" event creation failed in OpenStream()\n")); goto error; } blockingReadFramesReadyEventInitialized = 1; /* Create pointer buffer to access non-interleaved data in ReadStream() */ stream->blockingState->readStreamBuffer = (void**)PaUtil_AllocateMemory( sizeof(void*) * inputChannelCount ); if( !stream->blockingState->readStreamBuffer ) { result = paInsufficientMemory; PA_DEBUG(("ERROR! Blocking i/o read stream buffer allocation failed in OpenStream()\n")); goto error; } /* The ring buffer should store as many data blocks as needed to achieve the requested latency. Whereas it must be large enough to store at least two complete data blocks. 1) Determine the amount of latency to be added to the prefered ASIO latency. 2) Make sure we have at lest one additional latency frame. 3) Divide the number of frames by the desired block size to get the number (rounded up to pure integer) of blocks to be stored in the buffer. 4) Add one additional block for block processing and convert to samples frames. 5) Get the next larger (or equal) power-of-two buffer size. */ lBlockingBufferSize = suggestedInputLatencyFrames - stream->asioInputLatencyFrames; lBlockingBufferSize = (lBlockingBufferSize > 0) ? lBlockingBufferSize : 1; lBlockingBufferSize = (lBlockingBufferSize + framesPerBuffer - 1) / framesPerBuffer; lBlockingBufferSize = (lBlockingBufferSize + 1) * framesPerBuffer; /* Get the next larger or equal power-of-two buffersize. */ lBlockingBufferSizePow2 = 1; while( lBlockingBufferSize > (lBlockingBufferSizePow2<<=1) ); lBlockingBufferSize = lBlockingBufferSizePow2; /* Compute total intput latency in seconds */ stream->streamRepresentation.streamInfo.inputLatency = (double)( PaUtil_GetBufferProcessorInputLatencyFrames(&stream->bufferProcessor ) + PaUtil_GetBufferProcessorInputLatencyFrames(&stream->blockingState->bufferProcessor) + (lBlockingBufferSize / framesPerBuffer - 1) * framesPerBuffer + stream->asioInputLatencyFrames ) / sampleRate; /* The code below prints the ASIO latency which doesn't include the buffer processor latency nor the blocking i/o latency. It reports the added latency separately. */ PA_DEBUG(("PaAsio : ASIO InputLatency = %ld (%ld ms),\n added buffProc:%ld (%ld ms),\n added blocking:%ld (%ld ms)\n", stream->asioInputLatencyFrames, (long)( stream->asioInputLatencyFrames * (1000.0 / sampleRate) ), PaUtil_GetBufferProcessorInputLatencyFrames(&stream->bufferProcessor), (long)( PaUtil_GetBufferProcessorInputLatencyFrames(&stream->bufferProcessor) * (1000.0 / sampleRate) ), PaUtil_GetBufferProcessorInputLatencyFrames(&stream->blockingState->bufferProcessor) + (lBlockingBufferSize / framesPerBuffer - 1) * framesPerBuffer, (long)( (PaUtil_GetBufferProcessorInputLatencyFrames(&stream->blockingState->bufferProcessor) + (lBlockingBufferSize / framesPerBuffer - 1) * framesPerBuffer) * (1000.0 / sampleRate) ) )); /* Determine the size of ring buffer in bytes. */ lBytesPerFrame = inputChannelCount * Pa_GetSampleSize(inputSampleFormat ); /* Allocate the blocking i/o input ring buffer memory. */ stream->blockingState->readRingBufferData = (void*)PaUtil_AllocateMemory( lBlockingBufferSize * lBytesPerFrame ); if( !stream->blockingState->readRingBufferData ) { result = paInsufficientMemory; PA_DEBUG(("ERROR! Blocking i/o input ring buffer allocation failed in OpenStream()\n")); goto error; } /* Initialize the input ring buffer struct. */ PaUtil_InitializeRingBuffer( &stream->blockingState->readRingBuffer , lBytesPerFrame , lBlockingBufferSize , stream->blockingState->readRingBufferData ); } /* If output is requested. */ if( outputChannelCount ) { stream->blockingState->writeBuffersReadyEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); if( stream->blockingState->writeBuffersReadyEvent == NULL ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() ); PA_DEBUG(("ERROR! Blocking i/o \"write buffers ready\" event creation failed in OpenStream()\n")); goto error; } blockingWriteBuffersReadyEventInitialized = 1; /* Create pointer buffer to access non-interleaved data in WriteStream() */ stream->blockingState->writeStreamBuffer = (const void**)PaUtil_AllocateMemory( sizeof(const void*) * outputChannelCount ); if( !stream->blockingState->writeStreamBuffer ) { result = paInsufficientMemory; PA_DEBUG(("ERROR! Blocking i/o write stream buffer allocation failed in OpenStream()\n")); goto error; } /* The ring buffer should store as many data blocks as needed to achieve the requested latency. Whereas it must be large enough to store at least two complete data blocks. 1) Determine the amount of latency to be added to the prefered ASIO latency. 2) Make sure we have at lest one additional latency frame. 3) Divide the number of frames by the desired block size to get the number (rounded up to pure integer) of blocks to be stored in the buffer. 4) Add one additional block for block processing and convert to samples frames. 5) Get the next larger (or equal) power-of-two buffer size. */ lBlockingBufferSize = suggestedOutputLatencyFrames - stream->asioOutputLatencyFrames; lBlockingBufferSize = (lBlockingBufferSize > 0) ? lBlockingBufferSize : 1; lBlockingBufferSize = (lBlockingBufferSize + framesPerBuffer - 1) / framesPerBuffer; lBlockingBufferSize = (lBlockingBufferSize + 1) * framesPerBuffer; /* The buffer size (without the additional block) corresponds to the initial number of silent samples in the output ring buffer. */ stream->blockingState->writeRingBufferInitialFrames = lBlockingBufferSize - framesPerBuffer; /* Get the next larger or equal power-of-two buffersize. */ lBlockingBufferSizePow2 = 1; while( lBlockingBufferSize > (lBlockingBufferSizePow2<<=1) ); lBlockingBufferSize = lBlockingBufferSizePow2; /* Compute total output latency in seconds */ stream->streamRepresentation.streamInfo.outputLatency = (double)( PaUtil_GetBufferProcessorOutputLatencyFrames(&stream->bufferProcessor) + PaUtil_GetBufferProcessorOutputLatencyFrames(&stream->blockingState->bufferProcessor) + (lBlockingBufferSize / framesPerBuffer - 1) * framesPerBuffer + stream->asioOutputLatencyFrames ) / sampleRate; /* The code below prints the ASIO latency which doesn't include the buffer processor latency nor the blocking i/o latency. It reports the added latency separately. */ PA_DEBUG(("PaAsio : ASIO OutputLatency = %ld (%ld ms),\n added buffProc:%ld (%ld ms),\n added blocking:%ld (%ld ms)\n", stream->asioOutputLatencyFrames, (long)( stream->asioOutputLatencyFrames * (1000.0 / sampleRate) ), PaUtil_GetBufferProcessorOutputLatencyFrames(&stream->bufferProcessor), (long)( PaUtil_GetBufferProcessorOutputLatencyFrames(&stream->bufferProcessor) * (1000.0 / sampleRate) ), PaUtil_GetBufferProcessorOutputLatencyFrames(&stream->blockingState->bufferProcessor) + (lBlockingBufferSize / framesPerBuffer - 1) * framesPerBuffer, (long)( (PaUtil_GetBufferProcessorOutputLatencyFrames(&stream->blockingState->bufferProcessor) + (lBlockingBufferSize / framesPerBuffer - 1) * framesPerBuffer) * (1000.0 / sampleRate) ) )); /* Determine the size of ring buffer in bytes. */ lBytesPerFrame = outputChannelCount * Pa_GetSampleSize(outputSampleFormat); /* Allocate the blocking i/o output ring buffer memory. */ stream->blockingState->writeRingBufferData = (void*)PaUtil_AllocateMemory( lBlockingBufferSize * lBytesPerFrame ); if( !stream->blockingState->writeRingBufferData ) { result = paInsufficientMemory; PA_DEBUG(("ERROR! Blocking i/o output ring buffer allocation failed in OpenStream()\n")); goto error; } /* Initialize the output ring buffer struct. */ PaUtil_InitializeRingBuffer( &stream->blockingState->writeRingBuffer , lBytesPerFrame , lBlockingBufferSize , stream->blockingState->writeRingBufferData ); } stream->streamRepresentation.streamInfo.sampleRate = sampleRate; } else /* Using callback interface... */ { result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, inputChannelCount, inputSampleFormat, (hostInputSampleFormat | paNonInterleaved), outputChannelCount, outputSampleFormat, (hostOutputSampleFormat | paNonInterleaved), sampleRate, streamFlags, framesPerBuffer, framesPerHostBuffer, paUtilFixedHostBufferSize, streamCallback, userData ); if( result != paNoError ){ PA_DEBUG(("OpenStream ERROR13\n")); goto error; } callbackBufferProcessorInited = TRUE; stream->streamRepresentation.streamInfo.inputLatency = (double)( PaUtil_GetBufferProcessorInputLatencyFrames(&stream->bufferProcessor) + stream->asioInputLatencyFrames) / sampleRate; // seconds stream->streamRepresentation.streamInfo.outputLatency = (double)( PaUtil_GetBufferProcessorOutputLatencyFrames(&stream->bufferProcessor) + stream->asioOutputLatencyFrames) / sampleRate; // seconds stream->streamRepresentation.streamInfo.sampleRate = sampleRate; // the code below prints the ASIO latency which doesn't include the // buffer processor latency. it reports the added latency separately PA_DEBUG(("PaAsio : ASIO InputLatency = %ld (%ld ms), added buffProc:%ld (%ld ms)\n", stream->asioInputLatencyFrames, (long)((stream->asioInputLatencyFrames*1000)/ sampleRate), PaUtil_GetBufferProcessorInputLatencyFrames(&stream->bufferProcessor), (long)((PaUtil_GetBufferProcessorInputLatencyFrames(&stream->bufferProcessor)*1000)/ sampleRate) )); PA_DEBUG(("PaAsio : ASIO OuputLatency = %ld (%ld ms), added buffProc:%ld (%ld ms)\n", stream->asioOutputLatencyFrames, (long)((stream->asioOutputLatencyFrames*1000)/ sampleRate), PaUtil_GetBufferProcessorOutputLatencyFrames(&stream->bufferProcessor), (long)((PaUtil_GetBufferProcessorOutputLatencyFrames(&stream->bufferProcessor)*1000)/ sampleRate) )); } stream->asioHostApi = asioHostApi; stream->framesPerHostCallback = framesPerHostBuffer; stream->inputChannelCount = inputChannelCount; stream->outputChannelCount = outputChannelCount; stream->postOutput = driverInfo->postOutput; stream->isStopped = 1; stream->isActive = 0; asioHostApi->openAsioDeviceIndex = asioDeviceIndex; theAsioStream = stream; *s = (PaStream*)stream; return result; error: PA_DEBUG(("goto errored\n")); if( stream ) { if( stream->blockingState ) { if( blockingBufferProcessorInited ) PaUtil_TerminateBufferProcessor( &stream->blockingState->bufferProcessor ); if( stream->blockingState->writeRingBufferData ) PaUtil_FreeMemory( stream->blockingState->writeRingBufferData ); if( stream->blockingState->writeStreamBuffer ) PaUtil_FreeMemory( stream->blockingState->writeStreamBuffer ); if( blockingWriteBuffersReadyEventInitialized ) CloseHandle( stream->blockingState->writeBuffersReadyEvent ); if( stream->blockingState->readRingBufferData ) PaUtil_FreeMemory( stream->blockingState->readRingBufferData ); if( stream->blockingState->readStreamBuffer ) PaUtil_FreeMemory( stream->blockingState->readStreamBuffer ); if( blockingReadFramesReadyEventInitialized ) CloseHandle( stream->blockingState->readFramesReadyEvent ); PaUtil_FreeMemory( stream->blockingState ); } if( callbackBufferProcessorInited ) PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); if( completedBuffersPlayedEventInited ) CloseHandle( stream->completedBuffersPlayedEvent ); if( stream->asioBufferInfos ) PaUtil_FreeMemory( stream->asioBufferInfos ); if( stream->asioChannelInfos ) PaUtil_FreeMemory( stream->asioChannelInfos ); if( stream->bufferPtrs ) PaUtil_FreeMemory( stream->bufferPtrs ); PaUtil_FreeMemory( stream ); } if( asioBuffersCreated ) ASIODisposeBuffers(); if( asioIsInitialized ) { UnloadAsioDriver(); } return result; } /* When CloseStream() is called, the multi-api layer ensures that the stream has already been stopped or aborted. */ static PaError CloseStream( PaStream* s ) { PaError result = paNoError; PaAsioStream *stream = (PaAsioStream*)s; /* IMPLEMENT ME: - additional stream closing + cleanup */ PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); stream->asioHostApi->openAsioDeviceIndex = paNoDevice; CloseHandle( stream->completedBuffersPlayedEvent ); /* Using blocking i/o interface... */ if( stream->blockingState ) { PaUtil_TerminateBufferProcessor( &stream->blockingState->bufferProcessor ); if( stream->inputChannelCount ) { PaUtil_FreeMemory( stream->blockingState->readRingBufferData ); PaUtil_FreeMemory( stream->blockingState->readStreamBuffer ); CloseHandle( stream->blockingState->readFramesReadyEvent ); } if( stream->outputChannelCount ) { PaUtil_FreeMemory( stream->blockingState->writeRingBufferData ); PaUtil_FreeMemory( stream->blockingState->writeStreamBuffer ); CloseHandle( stream->blockingState->writeBuffersReadyEvent ); } PaUtil_FreeMemory( stream->blockingState ); } PaUtil_FreeMemory( stream->asioBufferInfos ); PaUtil_FreeMemory( stream->asioChannelInfos ); PaUtil_FreeMemory( stream->bufferPtrs ); PaUtil_FreeMemory( stream ); ASIODisposeBuffers(); UnloadAsioDriver(); theAsioStream = 0; return result; } static void bufferSwitch(long index, ASIOBool directProcess) { //TAKEN FROM THE ASIO SDK // the actual processing callback. // Beware that this is normally in a seperate thread, hence be sure that // you take care about thread synchronization. This is omitted here for // simplicity. // as this is a "back door" into the bufferSwitchTimeInfo a timeInfo needs // to be created though it will only set the timeInfo.samplePosition and // timeInfo.systemTime fields and the according flags ASIOTime timeInfo; memset( &timeInfo, 0, sizeof (timeInfo) ); // get the time stamp of the buffer, not necessary if no // synchronization to other media is required if( ASIOGetSamplePosition(&timeInfo.timeInfo.samplePosition, &timeInfo.timeInfo.systemTime) == ASE_OK) timeInfo.timeInfo.flags = kSystemTimeValid | kSamplePositionValid; // Call the real callback bufferSwitchTimeInfo( &timeInfo, index, directProcess ); } // conversion from 64 bit ASIOSample/ASIOTimeStamp to double float #if NATIVE_INT64 #define ASIO64toDouble(a) (a) #else const double twoRaisedTo32 = 4294967296.; #define ASIO64toDouble(a) ((a).lo + (a).hi * twoRaisedTo32) #endif static ASIOTime *bufferSwitchTimeInfo( ASIOTime *timeInfo, long index, ASIOBool directProcess ) { // the actual processing callback. // Beware that this is normally in a seperate thread, hence be sure that // you take care about thread synchronization. /* The SDK says the following about the directProcess flag: suggests to the host whether it should immediately start processing (directProcess == ASIOTrue), or whether its process should be deferred because the call comes from a very low level (for instance, a high level priority interrupt), and direct processing would cause timing instabilities for the rest of the system. If in doubt, directProcess should be set to ASIOFalse. We just ignore directProcess. This could cause incompatibilities with drivers which really don't want the audio processing to occur in this callback, but none have been identified yet. */ (void) directProcess; /* suppress unused parameter warning */ #if 0 // store the timeInfo for later use asioDriverInfo.tInfo = *timeInfo; // get the time stamp of the buffer, not necessary if no // synchronization to other media is required if (timeInfo->timeInfo.flags & kSystemTimeValid) asioDriverInfo.nanoSeconds = ASIO64toDouble(timeInfo->timeInfo.systemTime); else asioDriverInfo.nanoSeconds = 0; if (timeInfo->timeInfo.flags & kSamplePositionValid) asioDriverInfo.samples = ASIO64toDouble(timeInfo->timeInfo.samplePosition); else asioDriverInfo.samples = 0; if (timeInfo->timeCode.flags & kTcValid) asioDriverInfo.tcSamples = ASIO64toDouble(timeInfo->timeCode.timeCodeSamples); else asioDriverInfo.tcSamples = 0; // get the system reference time asioDriverInfo.sysRefTime = get_sys_reference_time(); #endif #if 0 // a few debug messages for the Windows device driver developer // tells you the time when driver got its interrupt and the delay until the app receives // the event notification. static double last_samples = 0; char tmp[128]; sprintf (tmp, "diff: %d / %d ms / %d ms / %d samples \n", asioDriverInfo.sysRefTime - (long)(asioDriverInfo.nanoSeconds / 1000000.0), asioDriverInfo.sysRefTime, (long)(asioDriverInfo.nanoSeconds / 1000000.0), (long)(asioDriverInfo.samples - last_samples)); OutputDebugString (tmp); last_samples = asioDriverInfo.samples; #endif if( !theAsioStream ) return 0L; // protect against reentrancy if( PaAsio_AtomicIncrement(&theAsioStream->reenterCount) ) { theAsioStream->reenterError++; //DBUG(("bufferSwitchTimeInfo : reentrancy detection = %d\n", asioDriverInfo.reenterError)); return 0L; } int buffersDone = 0; do { if( buffersDone > 0 ) { // this is a reentered buffer, we missed processing it on time // set the input overflow and output underflow flags as appropriate if( theAsioStream->inputChannelCount > 0 ) theAsioStream->callbackFlags |= paInputOverflow; if( theAsioStream->outputChannelCount > 0 ) theAsioStream->callbackFlags |= paOutputUnderflow; } else { if( theAsioStream->zeroOutput ) { ZeroOutputBuffers( theAsioStream, index ); // Finally if the driver supports the ASIOOutputReady() optimization, // do it here, all data are in place if( theAsioStream->postOutput ) ASIOOutputReady(); if( theAsioStream->stopProcessing ) { if( theAsioStream->stopPlayoutCount < 2 ) { ++theAsioStream->stopPlayoutCount; if( theAsioStream->stopPlayoutCount == 2 ) { theAsioStream->isActive = 0; if( theAsioStream->streamRepresentation.streamFinishedCallback != 0 ) theAsioStream->streamRepresentation.streamFinishedCallback( theAsioStream->streamRepresentation.userData ); theAsioStream->streamFinishedCallbackCalled = true; SetEvent( theAsioStream->completedBuffersPlayedEvent ); } } } } else { #if 0 /* see: "ASIO callback underflow/overflow buffer slip detection doesn't work" http://www.portaudio.com/trac/ticket/110 */ // test code to try to detect slip conditions... these may work on some systems // but neither of them work on the RME Digi96 // check that sample delta matches buffer size (otherwise we must have skipped // a buffer. static double last_samples = -512; double samples; //if( timeInfo->timeCode.flags & kTcValid ) // samples = ASIO64toDouble(timeInfo->timeCode.timeCodeSamples); //else samples = ASIO64toDouble(timeInfo->timeInfo.samplePosition); int delta = samples - last_samples; //printf( "%d\n", delta); last_samples = samples; if( delta > theAsioStream->framesPerHostCallback ) { if( theAsioStream->inputChannelCount > 0 ) theAsioStream->callbackFlags |= paInputOverflow; if( theAsioStream->outputChannelCount > 0 ) theAsioStream->callbackFlags |= paOutputUnderflow; } // check that the buffer index is not the previous index (which would indicate // that a buffer was skipped. static int previousIndex = 1; if( index == previousIndex ) { if( theAsioStream->inputChannelCount > 0 ) theAsioStream->callbackFlags |= paInputOverflow; if( theAsioStream->outputChannelCount > 0 ) theAsioStream->callbackFlags |= paOutputUnderflow; } previousIndex = index; #endif int i; PaUtil_BeginCpuLoadMeasurement( &theAsioStream->cpuLoadMeasurer ); PaStreamCallbackTimeInfo paTimeInfo; // asio systemTime is supposed to be measured according to the same // clock as timeGetTime paTimeInfo.currentTime = (ASIO64toDouble( timeInfo->timeInfo.systemTime ) * .000000001); /* patch from Paul Boege */ paTimeInfo.inputBufferAdcTime = paTimeInfo.currentTime - ((double)theAsioStream->asioInputLatencyFrames/theAsioStream->streamRepresentation.streamInfo.sampleRate); paTimeInfo.outputBufferDacTime = paTimeInfo.currentTime + ((double)theAsioStream->asioOutputLatencyFrames/theAsioStream->streamRepresentation.streamInfo.sampleRate); /* old version is buggy because the buffer processor also adds in its latency to the time parameters paTimeInfo.inputBufferAdcTime = paTimeInfo.currentTime - theAsioStream->streamRepresentation.streamInfo.inputLatency; paTimeInfo.outputBufferDacTime = paTimeInfo.currentTime + theAsioStream->streamRepresentation.streamInfo.outputLatency; */ /* Disabled! Stopping and re-starting the stream causes an input overflow / output underflow. S.Fischer */ #if 0 // detect underflows by checking inter-callback time > 2 buffer period static double previousTime = -1; if( previousTime > 0 ){ double delta = paTimeInfo.currentTime - previousTime; if( delta >= 2. * (theAsioStream->framesPerHostCallback / theAsioStream->streamRepresentation.streamInfo.sampleRate) ){ if( theAsioStream->inputChannelCount > 0 ) theAsioStream->callbackFlags |= paInputOverflow; if( theAsioStream->outputChannelCount > 0 ) theAsioStream->callbackFlags |= paOutputUnderflow; } } previousTime = paTimeInfo.currentTime; #endif // note that the above input and output times do not need to be // adjusted for the latency of the buffer processor -- the buffer // processor handles that. if( theAsioStream->inputBufferConverter ) { for( i=0; iinputChannelCount; i++ ) { theAsioStream->inputBufferConverter( theAsioStream->inputBufferPtrs[index][i], theAsioStream->inputShift, theAsioStream->framesPerHostCallback ); } } PaUtil_BeginBufferProcessing( &theAsioStream->bufferProcessor, &paTimeInfo, theAsioStream->callbackFlags ); /* reset status flags once they've been passed to the callback */ theAsioStream->callbackFlags = 0; PaUtil_SetInputFrameCount( &theAsioStream->bufferProcessor, 0 /* default to host buffer size */ ); for( i=0; iinputChannelCount; ++i ) PaUtil_SetNonInterleavedInputChannel( &theAsioStream->bufferProcessor, i, theAsioStream->inputBufferPtrs[index][i] ); PaUtil_SetOutputFrameCount( &theAsioStream->bufferProcessor, 0 /* default to host buffer size */ ); for( i=0; ioutputChannelCount; ++i ) PaUtil_SetNonInterleavedOutputChannel( &theAsioStream->bufferProcessor, i, theAsioStream->outputBufferPtrs[index][i] ); int callbackResult; if( theAsioStream->stopProcessing ) callbackResult = paComplete; else callbackResult = paContinue; unsigned long framesProcessed = PaUtil_EndBufferProcessing( &theAsioStream->bufferProcessor, &callbackResult ); if( theAsioStream->outputBufferConverter ) { for( i=0; ioutputChannelCount; i++ ) { theAsioStream->outputBufferConverter( theAsioStream->outputBufferPtrs[index][i], theAsioStream->outputShift, theAsioStream->framesPerHostCallback ); } } PaUtil_EndCpuLoadMeasurement( &theAsioStream->cpuLoadMeasurer, framesProcessed ); // Finally if the driver supports the ASIOOutputReady() optimization, // do it here, all data are in place if( theAsioStream->postOutput ) ASIOOutputReady(); if( callbackResult == paContinue ) { /* nothing special to do */ } else if( callbackResult == paAbort ) { /* finish playback immediately */ theAsioStream->isActive = 0; if( theAsioStream->streamRepresentation.streamFinishedCallback != 0 ) theAsioStream->streamRepresentation.streamFinishedCallback( theAsioStream->streamRepresentation.userData ); theAsioStream->streamFinishedCallbackCalled = true; SetEvent( theAsioStream->completedBuffersPlayedEvent ); theAsioStream->zeroOutput = true; } else /* paComplete or other non-zero value indicating complete */ { /* Finish playback once currently queued audio has completed. */ theAsioStream->stopProcessing = true; if( PaUtil_IsBufferProcessorOutputEmpty( &theAsioStream->bufferProcessor ) ) { theAsioStream->zeroOutput = true; theAsioStream->stopPlayoutCount = 0; } } } } ++buffersDone; }while( PaAsio_AtomicDecrement(&theAsioStream->reenterCount) >= 0 ); return 0L; } static void sampleRateChanged(ASIOSampleRate sRate) { // TAKEN FROM THE ASIO SDK // do whatever you need to do if the sample rate changed // usually this only happens during external sync. // Audio processing is not stopped by the driver, actual sample rate // might not have even changed, maybe only the sample rate status of an // AES/EBU or S/PDIF digital input at the audio device. // You might have to update time/sample related conversion routines, etc. (void) sRate; /* unused parameter */ PA_DEBUG( ("sampleRateChanged : %d \n", sRate)); } static long asioMessages(long selector, long value, void* message, double* opt) { // TAKEN FROM THE ASIO SDK // currently the parameters "value", "message" and "opt" are not used. long ret = 0; (void) message; /* unused parameters */ (void) opt; PA_DEBUG( ("asioMessages : %d , %d \n", selector, value)); switch(selector) { case kAsioSelectorSupported: if(value == kAsioResetRequest || value == kAsioEngineVersion || value == kAsioResyncRequest || value == kAsioLatenciesChanged // the following three were added for ASIO 2.0, you don't necessarily have to support them || value == kAsioSupportsTimeInfo || value == kAsioSupportsTimeCode || value == kAsioSupportsInputMonitor) ret = 1L; break; case kAsioBufferSizeChange: //printf("kAsioBufferSizeChange \n"); break; case kAsioResetRequest: // defer the task and perform the reset of the driver during the next "safe" situation // You cannot reset the driver right now, as this code is called from the driver. // Reset the driver is done by completely destruct is. I.e. ASIOStop(), ASIODisposeBuffers(), Destruction // Afterwards you initialize the driver again. /*FIXME: commented the next line out see: "PA/ASIO ignores some driver notifications it probably shouldn't" http://www.portaudio.com/trac/ticket/108 */ //asioDriverInfo.stopped; // In this sample the processing will just stop ret = 1L; break; case kAsioResyncRequest: // This informs the application, that the driver encountered some non fatal data loss. // It is used for synchronization purposes of different media. // Added mainly to work around the Win16Mutex problems in Windows 95/98 with the // Windows Multimedia system, which could loose data because the Mutex was hold too long // by another thread. // However a driver can issue it in other situations, too. ret = 1L; break; case kAsioLatenciesChanged: // This will inform the host application that the drivers were latencies changed. // Beware, it this does not mean that the buffer sizes have changed! // You might need to update internal delay data. ret = 1L; //printf("kAsioLatenciesChanged \n"); break; case kAsioEngineVersion: // return the supported ASIO version of the host application // If a host applications does not implement this selector, ASIO 1.0 is assumed // by the driver ret = 2L; break; case kAsioSupportsTimeInfo: // informs the driver wether the asioCallbacks.bufferSwitchTimeInfo() callback // is supported. // For compatibility with ASIO 1.0 drivers the host application should always support // the "old" bufferSwitch method, too. ret = 1; break; case kAsioSupportsTimeCode: // informs the driver wether application is interested in time code info. // If an application does not need to know about time code, the driver has less work // to do. ret = 0; break; } return ret; } static PaError StartStream( PaStream *s ) { PaError result = paNoError; PaAsioStream *stream = (PaAsioStream*)s; PaAsioStreamBlockingState *blockingState = stream->blockingState; ASIOError asioError; if( stream->outputChannelCount > 0 ) { ZeroOutputBuffers( stream, 0 ); ZeroOutputBuffers( stream, 1 ); } PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); stream->stopProcessing = false; stream->zeroOutput = false; /* Reentrancy counter initialisation */ stream->reenterCount = -1; stream->reenterError = 0; stream->callbackFlags = 0; if( ResetEvent( stream->completedBuffersPlayedEvent ) == 0 ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() ); } /* Using blocking i/o interface... */ if( blockingState ) { /* Reset blocking i/o buffer processor. */ PaUtil_ResetBufferProcessor( &blockingState->bufferProcessor ); /* If we're about to process some input data. */ if( stream->inputChannelCount ) { /* Reset callback-ReadStream sync event. */ if( ResetEvent( blockingState->readFramesReadyEvent ) == 0 ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() ); } /* Flush blocking i/o ring buffer. */ PaUtil_FlushRingBuffer( &blockingState->readRingBuffer ); (*blockingState->bufferProcessor.inputZeroer)( blockingState->readRingBuffer.buffer, 1, blockingState->bufferProcessor.inputChannelCount * blockingState->readRingBuffer.bufferSize ); } /* If we're about to process some output data. */ if( stream->outputChannelCount ) { /* Reset callback-WriteStream sync event. */ if( ResetEvent( blockingState->writeBuffersReadyEvent ) == 0 ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() ); } /* Flush blocking i/o ring buffer. */ PaUtil_FlushRingBuffer( &blockingState->writeRingBuffer ); (*blockingState->bufferProcessor.outputZeroer)( blockingState->writeRingBuffer.buffer, 1, blockingState->bufferProcessor.outputChannelCount * blockingState->writeRingBuffer.bufferSize ); /* Initialize the output ring buffer to "silence". */ PaUtil_AdvanceRingBufferWriteIndex( &blockingState->writeRingBuffer, blockingState->writeRingBufferInitialFrames ); } /* Clear requested frames / buffers count. */ blockingState->writeBuffersRequested = 0; blockingState->readFramesRequested = 0; blockingState->writeBuffersRequestedFlag = FALSE; blockingState->readFramesRequestedFlag = FALSE; blockingState->outputUnderflowFlag = FALSE; blockingState->inputOverflowFlag = FALSE; blockingState->stopFlag = FALSE; } if( result == paNoError ) { assert( theAsioStream == stream ); /* theAsioStream should be set correctly in OpenStream */ /* initialize these variables before the callback has a chance to be invoked */ stream->isStopped = 0; stream->isActive = 1; stream->streamFinishedCallbackCalled = false; asioError = ASIOStart(); if( asioError != ASE_OK ) { stream->isStopped = 1; stream->isActive = 0; result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); } } return result; } static void EnsureCallbackHasCompleted( PaAsioStream *stream ) { // make sure that the callback is not still in-flight after ASIOStop() // returns. This has been observed to happen on the Hoontech DSP24 for // example. int count = 2000; // only wait for 2 seconds, rather than hanging. while( stream->reenterCount != -1 && count > 0 ) { Sleep(1); --count; } } static PaError StopStream( PaStream *s ) { PaError result = paNoError; PaAsioStream *stream = (PaAsioStream*)s; PaAsioStreamBlockingState *blockingState = stream->blockingState; ASIOError asioError; if( stream->isActive ) { /* If blocking i/o output is in use */ if( blockingState && stream->outputChannelCount ) { /* Request the whole output buffer to be available. */ blockingState->writeBuffersRequested = blockingState->writeRingBuffer.bufferSize; /* Signalize that additional buffers are need. */ blockingState->writeBuffersRequestedFlag = TRUE; /* Set flag to indicate the playback is to be stopped. */ blockingState->stopFlag = TRUE; /* Wait until requested number of buffers has been freed. Time out after twice the blocking i/o ouput buffer could have been consumed. */ DWORD timeout = (DWORD)( 2 * blockingState->writeRingBuffer.bufferSize * 1000 / stream->streamRepresentation.streamInfo.sampleRate ); DWORD waitResult = WaitForSingleObject( blockingState->writeBuffersReadyEvent, timeout ); /* If something seriously went wrong... */ if( waitResult == WAIT_FAILED ) { PA_DEBUG(("WaitForSingleObject() failed in StopStream()\n")); result = paUnanticipatedHostError; PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() ); } else if( waitResult == WAIT_TIMEOUT ) { PA_DEBUG(("WaitForSingleObject() timed out in StopStream()\n")); result = paTimedOut; } } stream->stopProcessing = true; /* wait for the stream to finish playing out enqueued buffers. timeout after four times the stream latency. @todo should use a better time out value - if the user buffer length is longer than the asio buffer size then that should be taken into account. */ if( WaitForSingleObject( stream->completedBuffersPlayedEvent, (DWORD)(stream->streamRepresentation.streamInfo.outputLatency * 1000. * 4.) ) == WAIT_TIMEOUT ) { PA_DEBUG(("WaitForSingleObject() timed out in StopStream()\n" )); } } asioError = ASIOStop(); if( asioError == ASE_OK ) { EnsureCallbackHasCompleted( stream ); } else { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); } stream->isStopped = 1; stream->isActive = 0; if( !stream->streamFinishedCallbackCalled ) { if( stream->streamRepresentation.streamFinishedCallback != 0 ) stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); } return result; } static PaError AbortStream( PaStream *s ) { PaError result = paNoError; PaAsioStream *stream = (PaAsioStream*)s; ASIOError asioError; stream->zeroOutput = true; asioError = ASIOStop(); if( asioError == ASE_OK ) { EnsureCallbackHasCompleted( stream ); } else { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); } stream->isStopped = 1; stream->isActive = 0; if( !stream->streamFinishedCallbackCalled ) { if( stream->streamRepresentation.streamFinishedCallback != 0 ) stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); } return result; } static PaError IsStreamStopped( PaStream *s ) { PaAsioStream *stream = (PaAsioStream*)s; return stream->isStopped; } static PaError IsStreamActive( PaStream *s ) { PaAsioStream *stream = (PaAsioStream*)s; return stream->isActive; } static PaTime GetStreamTime( PaStream *s ) { (void) s; /* unused parameter */ return (double)timeGetTime() * .001; } static double GetStreamCpuLoad( PaStream* s ) { PaAsioStream *stream = (PaAsioStream*)s; return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); } /* As separate stream interfaces are used for blocking and callback streams, the following functions can be guaranteed to only be called for blocking streams. */ static PaError ReadStream( PaStream *s , void *buffer, unsigned long frames ) { PaError result = paNoError; /* Initial return value. */ PaAsioStream *stream = (PaAsioStream*)s; /* The PA ASIO stream. */ /* Pointer to the blocking i/o data struct. */ PaAsioStreamBlockingState *blockingState = stream->blockingState; /* Get blocking i/o buffer processor and ring buffer pointers. */ PaUtilBufferProcessor *pBp = &blockingState->bufferProcessor; PaUtilRingBuffer *pRb = &blockingState->readRingBuffer; /* Ring buffer segment(s) used for writing. */ void *pRingBufferData1st = NULL; /* First segment. (Mandatory) */ void *pRingBufferData2nd = NULL; /* Second segment. (Optional) */ /* Number of frames per ring buffer segment. */ long lRingBufferSize1st = 0; /* First segment. (Mandatory) */ long lRingBufferSize2nd = 0; /* Second segment. (Optional) */ /* Get number of frames to be processed per data block. */ unsigned long lFramesPerBlock = stream->bufferProcessor.framesPerUserBuffer; /* Actual number of frames that has been copied into the ring buffer. */ unsigned long lFramesCopied = 0; /* The number of remaining unprocessed dtat frames. */ unsigned long lFramesRemaining = frames; /* Copy the input argument to avoid pointer increment! */ const void *userBuffer; unsigned int i; /* Just a counter. */ /* About the time, needed to process 8 data blocks. */ DWORD timeout = (DWORD)( 8 * lFramesPerBlock * 1000 / stream->streamRepresentation.streamInfo.sampleRate ); DWORD waitResult = 0; /* Check if the stream is still available ready to gather new data. */ if( blockingState->stopFlag || !stream->isActive ) { PA_DEBUG(("Warning! Stream no longer available for reading in ReadStream()\n")); result = paStreamIsStopped; return result; } /* If the stream is a input stream. */ if( stream->inputChannelCount ) { /* Prepare buffer access. */ if( !pBp->userOutputIsInterleaved ) { userBuffer = blockingState->readStreamBuffer; for( i = 0; iinputChannelCount; ++i ) { ((void**)userBuffer)[i] = ((void**)buffer)[i]; } } /* Use the unchanged buffer. */ else { userBuffer = buffer; } do /* Internal block processing for too large user data buffers. */ { /* Get the size of the current data block to be processed. */ lFramesPerBlock =(lFramesPerBlock < lFramesRemaining) ? lFramesPerBlock : lFramesRemaining; /* Use predefined block size for as long there are enough buffers available, thereafter reduce the processing block size to match the number of remaining buffers. So the final data block is processed although it may be incomplete. */ /* If the available amount of data frames is insufficient. */ if( PaUtil_GetRingBufferReadAvailable(pRb) < (long) lFramesPerBlock ) { /* Make sure, the event isn't already set! */ /* ResetEvent( blockingState->readFramesReadyEvent ); */ /* Set the number of requested buffers. */ blockingState->readFramesRequested = lFramesPerBlock; /* Signalize that additional buffers are need. */ blockingState->readFramesRequestedFlag = TRUE; /* Wait until requested number of buffers has been freed. */ waitResult = WaitForSingleObject( blockingState->readFramesReadyEvent, timeout ); /* If something seriously went wrong... */ if( waitResult == WAIT_FAILED ) { PA_DEBUG(("WaitForSingleObject() failed in ReadStream()\n")); result = paUnanticipatedHostError; PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() ); return result; } else if( waitResult == WAIT_TIMEOUT ) { PA_DEBUG(("WaitForSingleObject() timed out in ReadStream()\n")); /* If block processing has stopped, abort! */ if( blockingState->stopFlag ) { return result = paStreamIsStopped; } /* If a timeout is encountered, give up eventually. */ return result = paTimedOut; } } /* Now, the ring buffer contains the required amount of data frames. (Therefor we don't need to check the return argument of PaUtil_GetRingBufferReadRegions(). ;-) ) */ /* Retrieve pointer(s) to the ring buffer's current write position(s). If the first buffer segment is too small to store the requested number of bytes, an additional second segment is returned. Otherwise, i.e. if the first segment is large enough, the second segment's pointer will be NULL. */ PaUtil_GetRingBufferReadRegions(pRb , lFramesPerBlock , &pRingBufferData1st, &lRingBufferSize1st, &pRingBufferData2nd, &lRingBufferSize2nd); /* Set number of frames to be copied from the ring buffer. */ PaUtil_SetInputFrameCount( pBp, lRingBufferSize1st ); /* Setup ring buffer access. */ PaUtil_SetInterleavedInputChannels(pBp , /* Buffer processor. */ 0 , /* The first channel's index. */ pRingBufferData1st, /* First ring buffer segment. */ 0 ); /* Use all available channels. */ /* If a second ring buffer segment is required. */ if( lRingBufferSize2nd ) { /* Set number of frames to be copied from the ring buffer. */ PaUtil_Set2ndInputFrameCount( pBp, lRingBufferSize2nd ); /* Setup ring buffer access. */ PaUtil_Set2ndInterleavedInputChannels(pBp , /* Buffer processor. */ 0 , /* The first channel's index. */ pRingBufferData2nd, /* Second ring buffer segment. */ 0 ); /* Use all available channels. */ } /* Let the buffer processor handle "copy and conversion" and update the ring buffer indices manually. */ lFramesCopied = PaUtil_CopyInput( pBp, &buffer, lFramesPerBlock ); PaUtil_AdvanceRingBufferReadIndex( pRb, lFramesCopied ); /* Decrease number of unprocessed frames. */ lFramesRemaining -= lFramesCopied; } /* Continue with the next data chunk. */ while( lFramesRemaining ); /* If there has been an input overflow within the callback */ if( blockingState->inputOverflowFlag ) { blockingState->inputOverflowFlag = FALSE; /* Return the corresponding error code. */ result = paInputOverflowed; } } /* If this is not an input stream. */ else { result = paCanNotReadFromAnOutputOnlyStream; } return result; } static PaError WriteStream( PaStream *s , const void *buffer, unsigned long frames ) { PaError result = paNoError; /* Initial return value. */ PaAsioStream *stream = (PaAsioStream*)s; /* The PA ASIO stream. */ /* Pointer to the blocking i/o data struct. */ PaAsioStreamBlockingState *blockingState = stream->blockingState; /* Get blocking i/o buffer processor and ring buffer pointers. */ PaUtilBufferProcessor *pBp = &blockingState->bufferProcessor; PaUtilRingBuffer *pRb = &blockingState->writeRingBuffer; /* Ring buffer segment(s) used for writing. */ void *pRingBufferData1st = NULL; /* First segment. (Mandatory) */ void *pRingBufferData2nd = NULL; /* Second segment. (Optional) */ /* Number of frames per ring buffer segment. */ long lRingBufferSize1st = 0; /* First segment. (Mandatory) */ long lRingBufferSize2nd = 0; /* Second segment. (Optional) */ /* Get number of frames to be processed per data block. */ unsigned long lFramesPerBlock = stream->bufferProcessor.framesPerUserBuffer; /* Actual number of frames that has been copied into the ring buffer. */ unsigned long lFramesCopied = 0; /* The number of remaining unprocessed dtat frames. */ unsigned long lFramesRemaining = frames; /* About the time, needed to process 8 data blocks. */ DWORD timeout = (DWORD)( 8 * lFramesPerBlock * 1000 / stream->streamRepresentation.streamInfo.sampleRate ); DWORD waitResult = 0; /* Copy the input argument to avoid pointer increment! */ const void *userBuffer; unsigned int i; /* Just a counter. */ /* Check if the stream ist still available ready to recieve new data. */ if( blockingState->stopFlag || !stream->isActive ) { PA_DEBUG(("Warning! Stream no longer available for writing in WriteStream()\n")); result = paStreamIsStopped; return result; } /* If the stream is a output stream. */ if( stream->outputChannelCount ) { /* Prepare buffer access. */ if( !pBp->userOutputIsInterleaved ) { userBuffer = blockingState->writeStreamBuffer; for( i = 0; ioutputChannelCount; ++i ) { ((const void**)userBuffer)[i] = ((const void**)buffer)[i]; } } /* Use the unchanged buffer. */ else { userBuffer = buffer; } do /* Internal block processing for too large user data buffers. */ { /* Get the size of the current data block to be processed. */ lFramesPerBlock =(lFramesPerBlock < lFramesRemaining) ? lFramesPerBlock : lFramesRemaining; /* Use predefined block size for as long there are enough frames available, thereafter reduce the processing block size to match the number of remaining frames. So the final data block is processed although it may be incomplete. */ /* If the available amount of buffers is insufficient. */ if( PaUtil_GetRingBufferWriteAvailable(pRb) < (long) lFramesPerBlock ) { /* Make sure, the event isn't already set! */ /* ResetEvent( blockingState->writeBuffersReadyEvent ); */ /* Set the number of requested buffers. */ blockingState->writeBuffersRequested = lFramesPerBlock; /* Signalize that additional buffers are need. */ blockingState->writeBuffersRequestedFlag = TRUE; /* Wait until requested number of buffers has been freed. */ waitResult = WaitForSingleObject( blockingState->writeBuffersReadyEvent, timeout ); /* If something seriously went wrong... */ if( waitResult == WAIT_FAILED ) { PA_DEBUG(("WaitForSingleObject() failed in WriteStream()\n")); result = paUnanticipatedHostError; PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() ); return result; } else if( waitResult == WAIT_TIMEOUT ) { PA_DEBUG(("WaitForSingleObject() timed out in WriteStream()\n")); /* If block processing has stopped, abort! */ if( blockingState->stopFlag ) { return result = paStreamIsStopped; } /* If a timeout is encountered, give up eventually. */ return result = paTimedOut; } } /* Now, the ring buffer contains the required amount of free space to store the provided number of data frames. (Therefor we don't need to check the return argument of PaUtil_GetRingBufferWriteRegions(). ;-) ) */ /* Retrieve pointer(s) to the ring buffer's current write position(s). If the first buffer segment is too small to store the requested number of bytes, an additional second segment is returned. Otherwise, i.e. if the first segment is large enough, the second segment's pointer will be NULL. */ PaUtil_GetRingBufferWriteRegions(pRb , lFramesPerBlock , &pRingBufferData1st, &lRingBufferSize1st, &pRingBufferData2nd, &lRingBufferSize2nd); /* Set number of frames to be copied to the ring buffer. */ PaUtil_SetOutputFrameCount( pBp, lRingBufferSize1st ); /* Setup ring buffer access. */ PaUtil_SetInterleavedOutputChannels(pBp , /* Buffer processor. */ 0 , /* The first channel's index. */ pRingBufferData1st, /* First ring buffer segment. */ 0 ); /* Use all available channels. */ /* If a second ring buffer segment is required. */ if( lRingBufferSize2nd ) { /* Set number of frames to be copied to the ring buffer. */ PaUtil_Set2ndOutputFrameCount( pBp, lRingBufferSize2nd ); /* Setup ring buffer access. */ PaUtil_Set2ndInterleavedOutputChannels(pBp , /* Buffer processor. */ 0 , /* The first channel's index. */ pRingBufferData2nd, /* Second ring buffer segment. */ 0 ); /* Use all available channels. */ } /* Let the buffer processor handle "copy and conversion" and update the ring buffer indices manually. */ lFramesCopied = PaUtil_CopyOutput( pBp, &userBuffer, lFramesPerBlock ); PaUtil_AdvanceRingBufferWriteIndex( pRb, lFramesCopied ); /* Decrease number of unprocessed frames. */ lFramesRemaining -= lFramesCopied; } /* Continue with the next data chunk. */ while( lFramesRemaining ); /* If there has been an output underflow within the callback */ if( blockingState->outputUnderflowFlag ) { blockingState->outputUnderflowFlag = FALSE; /* Return the corresponding error code. */ result = paOutputUnderflowed; } } /* If this is not an output stream. */ else { result = paCanNotWriteToAnInputOnlyStream; } return result; } static signed long GetStreamReadAvailable( PaStream* s ) { PaAsioStream *stream = (PaAsioStream*)s; /* Call buffer utility routine to get the number of available frames. */ return PaUtil_GetRingBufferReadAvailable( &stream->blockingState->readRingBuffer ); } static signed long GetStreamWriteAvailable( PaStream* s ) { PaAsioStream *stream = (PaAsioStream*)s; /* Call buffer utility routine to get the number of empty buffers. */ return PaUtil_GetRingBufferWriteAvailable( &stream->blockingState->writeRingBuffer ); } /* This routine will be called by the PortAudio engine when audio is needed. ** It may called at interrupt level on some machines so don't do anything ** that could mess up the system like calling malloc() or free(). */ static int BlockingIoPaCallback(const void *inputBuffer , void *outputBuffer , unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo , PaStreamCallbackFlags statusFlags , void *userData ) { PaError result = paNoError; /* Initial return value. */ PaAsioStream *stream = *(PaAsioStream**)userData; /* The PA ASIO stream. */ PaAsioStreamBlockingState *blockingState = stream->blockingState; /* Persume blockingState is valid, otherwise the callback wouldn't be running. */ /* Get a pointer to the stream's blocking i/o buffer processor. */ PaUtilBufferProcessor *pBp = &blockingState->bufferProcessor; PaUtilRingBuffer *pRb = NULL; /* If output data has been requested. */ if( stream->outputChannelCount ) { /* If the callback input argument signalizes a output underflow, make sure the WriteStream() function knows about it, too! */ if( statusFlags & paOutputUnderflowed ) { blockingState->outputUnderflowFlag = TRUE; } /* Access the corresponding ring buffer. */ pRb = &blockingState->writeRingBuffer; /* If the blocking i/o buffer contains enough output data, */ if( PaUtil_GetRingBufferReadAvailable(pRb) >= (long) framesPerBuffer ) { /* Extract the requested data from the ring buffer. */ PaUtil_ReadRingBuffer( pRb, outputBuffer, framesPerBuffer ); } else /* If no output data is available :-( */ { /* Signalize a write-buffer underflow. */ blockingState->outputUnderflowFlag = TRUE; /* Fill the output buffer with silence. */ (*pBp->outputZeroer)( outputBuffer, 1, pBp->outputChannelCount * framesPerBuffer ); /* If playback is to be stopped */ if( blockingState->stopFlag && PaUtil_GetRingBufferReadAvailable(pRb) < (long) framesPerBuffer ) { /* Extract all the remaining data from the ring buffer, whether it is a complete data block or not. */ PaUtil_ReadRingBuffer( pRb, outputBuffer, PaUtil_GetRingBufferReadAvailable(pRb) ); } } /* Set blocking i/o event? */ if( blockingState->writeBuffersRequestedFlag && PaUtil_GetRingBufferWriteAvailable(pRb) >= (long) blockingState->writeBuffersRequested ) { /* Reset buffer request. */ blockingState->writeBuffersRequestedFlag = FALSE; blockingState->writeBuffersRequested = 0; /* Signalize that requested buffers are ready. */ SetEvent( blockingState->writeBuffersReadyEvent ); /* What do we do if SetEvent() returns zero, i.e. the event could not be set? How to return errors from within the callback? - S.Fischer */ } } /* If input data has been supplied. */ if( stream->inputChannelCount ) { /* If the callback input argument signalizes a input overflow, make sure the ReadStream() function knows about it, too! */ if( statusFlags & paInputOverflowed ) { blockingState->inputOverflowFlag = TRUE; } /* Access the corresponding ring buffer. */ pRb = &blockingState->readRingBuffer; /* If the blocking i/o buffer contains not enough input buffers */ if( PaUtil_GetRingBufferWriteAvailable(pRb) < (long) framesPerBuffer ) { /* Signalize a read-buffer overflow. */ blockingState->inputOverflowFlag = TRUE; /* Remove some old data frames from the buffer. */ PaUtil_AdvanceRingBufferReadIndex( pRb, framesPerBuffer ); } /* Insert the current input data into the ring buffer. */ PaUtil_WriteRingBuffer( pRb, inputBuffer, framesPerBuffer ); /* Set blocking i/o event? */ if( blockingState->readFramesRequestedFlag && PaUtil_GetRingBufferReadAvailable(pRb) >= (long) blockingState->readFramesRequested ) { /* Reset buffer request. */ blockingState->readFramesRequestedFlag = FALSE; blockingState->readFramesRequested = 0; /* Signalize that requested buffers are ready. */ SetEvent( blockingState->readFramesReadyEvent ); /* What do we do if SetEvent() returns zero, i.e. the event could not be set? How to return errors from within the callback? - S.Fischer */ /** @todo report an error with PA_DEBUG */ } } return paContinue; } PaError PaAsio_ShowControlPanel( PaDeviceIndex device, void* systemSpecific ) { PaError result = paNoError; PaUtilHostApiRepresentation *hostApi; PaDeviceIndex hostApiDevice; ASIODriverInfo asioDriverInfo; ASIOError asioError; int asioIsInitialized = 0; PaAsioHostApiRepresentation *asioHostApi; PaAsioDeviceInfo *asioDeviceInfo; PaWinUtilComInitializationResult comInitializationResult; /* initialize COM again here, we might be in another thread */ result = PaWinUtil_CoInitialize( paASIO, &comInitializationResult ); if( result != paNoError ) return result; result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO ); if( result != paNoError ) goto error; result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, device, hostApi ); if( result != paNoError ) goto error; /* In theory we could proceed if the currently open device was the same one for which the control panel was requested, however because the window pointer is not available until this function is called we currently need to call ASIOInit() again here, which of course can't be done safely while a stream is open. */ asioHostApi = (PaAsioHostApiRepresentation*)hostApi; if( asioHostApi->openAsioDeviceIndex != paNoDevice ) { result = paDeviceUnavailable; goto error; } asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[hostApiDevice]; if( !asioHostApi->asioDrivers->loadDriver( const_cast(asioDeviceInfo->commonDeviceInfo.name) ) ) { result = paUnanticipatedHostError; goto error; } /* CRUCIAL!!! */ memset( &asioDriverInfo, 0, sizeof(ASIODriverInfo) ); asioDriverInfo.asioVersion = 2; asioDriverInfo.sysRef = systemSpecific; asioError = ASIOInit( &asioDriverInfo ); if( asioError != ASE_OK ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); goto error; } else { asioIsInitialized = 1; } PA_DEBUG(("PaAsio_ShowControlPanel: ASIOInit(): %s\n", PaAsio_GetAsioErrorText(asioError) )); PA_DEBUG(("asioVersion: ASIOInit(): %ld\n", asioDriverInfo.asioVersion )); PA_DEBUG(("driverVersion: ASIOInit(): %ld\n", asioDriverInfo.driverVersion )); PA_DEBUG(("Name: ASIOInit(): %s\n", asioDriverInfo.name )); PA_DEBUG(("ErrorMessage: ASIOInit(): %s\n", asioDriverInfo.errorMessage )); asioError = ASIOControlPanel(); if( asioError != ASE_OK ) { PA_DEBUG(("PaAsio_ShowControlPanel: ASIOControlPanel(): %s\n", PaAsio_GetAsioErrorText(asioError) )); result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); goto error; } PA_DEBUG(("PaAsio_ShowControlPanel: ASIOControlPanel(): %s\n", PaAsio_GetAsioErrorText(asioError) )); asioError = ASIOExit(); if( asioError != ASE_OK ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); asioIsInitialized = 0; goto error; } PA_DEBUG(("PaAsio_ShowControlPanel: ASIOExit(): %s\n", PaAsio_GetAsioErrorText(asioError) )); return result; error: if( asioIsInitialized ) { ASIOExit(); } PaWinUtil_CoUninitialize( paASIO, &comInitializationResult ); return result; } PaError PaAsio_GetInputChannelName( PaDeviceIndex device, int channelIndex, const char** channelName ) { PaError result = paNoError; PaUtilHostApiRepresentation *hostApi; PaDeviceIndex hostApiDevice; PaAsioDeviceInfo *asioDeviceInfo; result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO ); if( result != paNoError ) goto error; result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, device, hostApi ); if( result != paNoError ) goto error; asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[hostApiDevice]; if( channelIndex < 0 || channelIndex >= asioDeviceInfo->commonDeviceInfo.maxInputChannels ){ result = paInvalidChannelCount; goto error; } *channelName = asioDeviceInfo->asioChannelInfos[channelIndex].name; return paNoError; error: return result; } PaError PaAsio_GetOutputChannelName( PaDeviceIndex device, int channelIndex, const char** channelName ) { PaError result = paNoError; PaUtilHostApiRepresentation *hostApi; PaDeviceIndex hostApiDevice; PaAsioDeviceInfo *asioDeviceInfo; result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO ); if( result != paNoError ) goto error; result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, device, hostApi ); if( result != paNoError ) goto error; asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[hostApiDevice]; if( channelIndex < 0 || channelIndex >= asioDeviceInfo->commonDeviceInfo.maxOutputChannels ){ result = paInvalidChannelCount; goto error; } *channelName = asioDeviceInfo->asioChannelInfos[ asioDeviceInfo->commonDeviceInfo.maxInputChannels + channelIndex].name; return paNoError; error: return result; } /* NOTE: the following functions are ASIO-stream specific, and are called directly by client code. We need to check for many more error conditions here because we don't have the benefit of pa_front.c's parameter checking. */ static PaError GetAsioStreamPointer( PaAsioStream **stream, PaStream *s ) { PaError result; PaUtilHostApiRepresentation *hostApi; PaAsioHostApiRepresentation *asioHostApi; result = PaUtil_ValidateStreamPointer( s ); if( result != paNoError ) return result; result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO ); if( result != paNoError ) return result; asioHostApi = (PaAsioHostApiRepresentation*)hostApi; if( PA_STREAM_REP( s )->streamInterface == &asioHostApi->callbackStreamInterface || PA_STREAM_REP( s )->streamInterface == &asioHostApi->blockingStreamInterface ) { /* s is an ASIO stream */ *stream = (PaAsioStream *)s; return paNoError; } else { return paIncompatibleStreamHostApi; } } PaError PaAsio_SetStreamSampleRate( PaStream* s, double sampleRate ) { PaAsioStream *stream; PaError result = GetAsioStreamPointer( &stream, s ); if( result != paNoError ) return result; if( stream != theAsioStream ) return paBadStreamPtr; return ValidateAndSetSampleRate( sampleRate ); } praat-6.0.04/external/portaudio/pa_asio.h000066400000000000000000000131651261542461700203420ustar00rootroot00000000000000#ifndef PA_ASIO_H #define PA_ASIO_H /* * $Id: pa_asio.h 1667 2011-05-02 15:49:20Z rossb $ * PortAudio Portable Real-Time Audio Library * ASIO specific extensions * * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup public_header @brief ASIO-specific PortAudio API extension header file. */ #include "portaudio.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** Retrieve legal native buffer sizes for the specificed device, in sample frames. @param device The global index of the device about which the query is being made. @param minBufferSizeFrames A pointer to the location which will receive the minimum buffer size value. @param maxBufferSizeFrames A pointer to the location which will receive the maximum buffer size value. @param preferredBufferSizeFrames A pointer to the location which will receive the preferred buffer size value. @param granularity A pointer to the location which will receive the "granularity". This value determines the step size used to compute the legal values between minBufferSizeFrames and maxBufferSizeFrames. If granularity is -1 then available buffer size values are powers of two. @see ASIOGetBufferSize in the ASIO SDK. @note: this function used to be called PaAsio_GetAvailableLatencyValues. There is a #define that maps PaAsio_GetAvailableLatencyValues to this function for backwards compatibility. */ PaError PaAsio_GetAvailableBufferSizes( PaDeviceIndex device, long *minBufferSizeFrames, long *maxBufferSizeFrames, long *preferredBufferSizeFrames, long *granularity ); /** Backwards compatibility alias for PaAsio_GetAvailableBufferSizes @see PaAsio_GetAvailableBufferSizes */ #define PaAsio_GetAvailableLatencyValues PaAsio_GetAvailableBufferSizes /** Display the ASIO control panel for the specified device. @param device The global index of the device whose control panel is to be displayed. @param systemSpecific On Windows, the calling application's main window handle, on Macintosh this value should be zero. */ PaError PaAsio_ShowControlPanel( PaDeviceIndex device, void* systemSpecific ); /** Retrieve a pointer to a string containing the name of the specified input channel. The string is valid until Pa_Terminate is called. The string will be no longer than 32 characters including the null terminator. */ PaError PaAsio_GetInputChannelName( PaDeviceIndex device, int channelIndex, const char** channelName ); /** Retrieve a pointer to a string containing the name of the specified input channel. The string is valid until Pa_Terminate is called. The string will be no longer than 32 characters including the null terminator. */ PaError PaAsio_GetOutputChannelName( PaDeviceIndex device, int channelIndex, const char** channelName ); /** Set the sample rate of an open paASIO stream. @param stream The stream to operate on. @param sampleRate The new sample rate. Note that this function may fail if the stream is alredy running and the ASIO driver does not support switching the sample rate of a running stream. Returns paIncompatibleStreamHostApi if stream is not a paASIO stream. */ PaError PaAsio_SetStreamSampleRate( PaStream* stream, double sampleRate ); #define paAsioUseChannelSelectors (0x01) typedef struct PaAsioStreamInfo{ unsigned long size; /**< sizeof(PaAsioStreamInfo) */ PaHostApiTypeId hostApiType; /**< paASIO */ unsigned long version; /**< 1 */ unsigned long flags; /* Support for opening only specific channels of an ASIO device. If the paAsioUseChannelSelectors flag is set, channelSelectors is a pointer to an array of integers specifying the device channels to use. When used, the length of the channelSelectors array must match the corresponding channelCount parameter to Pa_OpenStream() otherwise a crash may result. The values in the selectors array must specify channels within the range of supported channels for the device or paInvalidChannelCount will result. */ int *channelSelectors; }PaAsioStreamInfo; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_ASIO_H */ praat-6.0.04/external/portaudio/pa_converters.c000066400000000000000000002070611261542461700215740ustar00rootroot00000000000000/* * $Id: pa_converters.c 1748 2011-09-01 22:08:32Z philburk $ * Portable Audio I/O Library sample conversion mechanism * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Phil Burk, Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Conversion function implementations. If the C9x function lrintf() is available, define PA_USE_C99_LRINTF to use it @todo Consider whether functions which dither but don't clip should exist, V18 automatically enabled clipping whenever dithering was selected. Perhaps we should do the same. see: "require clipping for dithering sample conversion functions?" http://www.portaudio.com/trac/ticket/112 @todo implement the converters marked IMPLEMENT ME: Int32_To_Int24_Dither, Int32_To_UInt8_Dither, Int24_To_Int16_Dither, Int24_To_Int8_Dither, Int24_To_UInt8_Dither, Int16_To_Int8_Dither, Int16_To_UInt8_Dither see: "some conversion functions are not implemented in pa_converters.c" http://www.portaudio.com/trac/ticket/35 @todo review the converters marked REVIEW: Float32_To_Int32, Float32_To_Int32_Dither, Float32_To_Int32_Clip, Float32_To_Int32_DitherClip, Int32_To_Int16_Dither, Int32_To_Int8_Dither, Int16_To_Int32 */ #include "pa_converters.h" #include "pa_dither.h" #include "pa_endianness.h" #include "pa_types.h" PaSampleFormat PaUtil_SelectClosestAvailableFormat( PaSampleFormat availableFormats, PaSampleFormat format ) { PaSampleFormat result; format &= ~paNonInterleaved; availableFormats &= ~paNonInterleaved; if( (format & availableFormats) == 0 ) { /* NOTE: this code depends on the sample format constants being in descending order of quality - ie best quality is 0 FIXME: should write an assert which checks that all of the known constants conform to that requirement. */ if( format != 0x01 ) { /* scan for better formats */ result = format; do { result >>= 1; } while( (result & availableFormats) == 0 && result != 0 ); } else { result = 0; } if( result == 0 ){ /* scan for worse formats */ result = format; do { result <<= 1; } while( (result & availableFormats) == 0 && result != paCustomFormat ); if( (result & availableFormats) == 0 ) result = paSampleFormatNotSupported; } }else{ result = format; } return result; } /* -------------------------------------------------------------------------- */ #define PA_SELECT_FORMAT_( format, float32, int32, int24, int16, int8, uint8 ) \ switch( format & ~paNonInterleaved ){ \ case paFloat32: \ float32 \ case paInt32: \ int32 \ case paInt24: \ int24 \ case paInt16: \ int16 \ case paInt8: \ int8 \ case paUInt8: \ uint8 \ default: return 0; \ } /* -------------------------------------------------------------------------- */ #define PA_SELECT_CONVERTER_DITHER_CLIP_( flags, source, destination ) \ if( flags & paClipOff ){ /* no clip */ \ if( flags & paDitherOff ){ /* no dither */ \ return paConverters. source ## _To_ ## destination; \ }else{ /* dither */ \ return paConverters. source ## _To_ ## destination ## _Dither; \ } \ }else{ /* clip */ \ if( flags & paDitherOff ){ /* no dither */ \ return paConverters. source ## _To_ ## destination ## _Clip; \ }else{ /* dither */ \ return paConverters. source ## _To_ ## destination ## _DitherClip; \ } \ } /* -------------------------------------------------------------------------- */ #define PA_SELECT_CONVERTER_DITHER_( flags, source, destination ) \ if( flags & paDitherOff ){ /* no dither */ \ return paConverters. source ## _To_ ## destination; \ }else{ /* dither */ \ return paConverters. source ## _To_ ## destination ## _Dither; \ } /* -------------------------------------------------------------------------- */ #define PA_USE_CONVERTER_( source, destination )\ return paConverters. source ## _To_ ## destination; /* -------------------------------------------------------------------------- */ #define PA_UNITY_CONVERSION_( wordlength )\ return paConverters. Copy_ ## wordlength ## _To_ ## wordlength; /* -------------------------------------------------------------------------- */ PaUtilConverter* PaUtil_SelectConverter( PaSampleFormat sourceFormat, PaSampleFormat destinationFormat, PaStreamFlags flags ) { PA_SELECT_FORMAT_( sourceFormat, /* paFloat32: */ PA_SELECT_FORMAT_( destinationFormat, /* paFloat32: */ PA_UNITY_CONVERSION_( 32 ), /* paInt32: */ PA_SELECT_CONVERTER_DITHER_CLIP_( flags, Float32, Int32 ), /* paInt24: */ PA_SELECT_CONVERTER_DITHER_CLIP_( flags, Float32, Int24 ), /* paInt16: */ PA_SELECT_CONVERTER_DITHER_CLIP_( flags, Float32, Int16 ), /* paInt8: */ PA_SELECT_CONVERTER_DITHER_CLIP_( flags, Float32, Int8 ), /* paUInt8: */ PA_SELECT_CONVERTER_DITHER_CLIP_( flags, Float32, UInt8 ) ), /* paInt32: */ PA_SELECT_FORMAT_( destinationFormat, /* paFloat32: */ PA_USE_CONVERTER_( Int32, Float32 ), /* paInt32: */ PA_UNITY_CONVERSION_( 32 ), /* paInt24: */ PA_SELECT_CONVERTER_DITHER_( flags, Int32, Int24 ), /* paInt16: */ PA_SELECT_CONVERTER_DITHER_( flags, Int32, Int16 ), /* paInt8: */ PA_SELECT_CONVERTER_DITHER_( flags, Int32, Int8 ), /* paUInt8: */ PA_SELECT_CONVERTER_DITHER_( flags, Int32, UInt8 ) ), /* paInt24: */ PA_SELECT_FORMAT_( destinationFormat, /* paFloat32: */ PA_USE_CONVERTER_( Int24, Float32 ), /* paInt32: */ PA_USE_CONVERTER_( Int24, Int32 ), /* paInt24: */ PA_UNITY_CONVERSION_( 24 ), /* paInt16: */ PA_SELECT_CONVERTER_DITHER_( flags, Int24, Int16 ), /* paInt8: */ PA_SELECT_CONVERTER_DITHER_( flags, Int24, Int8 ), /* paUInt8: */ PA_SELECT_CONVERTER_DITHER_( flags, Int24, UInt8 ) ), /* paInt16: */ PA_SELECT_FORMAT_( destinationFormat, /* paFloat32: */ PA_USE_CONVERTER_( Int16, Float32 ), /* paInt32: */ PA_USE_CONVERTER_( Int16, Int32 ), /* paInt24: */ PA_USE_CONVERTER_( Int16, Int24 ), /* paInt16: */ PA_UNITY_CONVERSION_( 16 ), /* paInt8: */ PA_SELECT_CONVERTER_DITHER_( flags, Int16, Int8 ), /* paUInt8: */ PA_SELECT_CONVERTER_DITHER_( flags, Int16, UInt8 ) ), /* paInt8: */ PA_SELECT_FORMAT_( destinationFormat, /* paFloat32: */ PA_USE_CONVERTER_( Int8, Float32 ), /* paInt32: */ PA_USE_CONVERTER_( Int8, Int32 ), /* paInt24: */ PA_USE_CONVERTER_( Int8, Int24 ), /* paInt16: */ PA_USE_CONVERTER_( Int8, Int16 ), /* paInt8: */ PA_UNITY_CONVERSION_( 8 ), /* paUInt8: */ PA_USE_CONVERTER_( Int8, UInt8 ) ), /* paUInt8: */ PA_SELECT_FORMAT_( destinationFormat, /* paFloat32: */ PA_USE_CONVERTER_( UInt8, Float32 ), /* paInt32: */ PA_USE_CONVERTER_( UInt8, Int32 ), /* paInt24: */ PA_USE_CONVERTER_( UInt8, Int24 ), /* paInt16: */ PA_USE_CONVERTER_( UInt8, Int16 ), /* paInt8: */ PA_USE_CONVERTER_( UInt8, Int8 ), /* paUInt8: */ PA_UNITY_CONVERSION_( 8 ) ) ) } /* -------------------------------------------------------------------------- */ #ifdef PA_NO_STANDARD_CONVERTERS /* -------------------------------------------------------------------------- */ PaUtilConverterTable paConverters = { 0, /* PaUtilConverter *Float32_To_Int32; */ 0, /* PaUtilConverter *Float32_To_Int32_Dither; */ 0, /* PaUtilConverter *Float32_To_Int32_Clip; */ 0, /* PaUtilConverter *Float32_To_Int32_DitherClip; */ 0, /* PaUtilConverter *Float32_To_Int24; */ 0, /* PaUtilConverter *Float32_To_Int24_Dither; */ 0, /* PaUtilConverter *Float32_To_Int24_Clip; */ 0, /* PaUtilConverter *Float32_To_Int24_DitherClip; */ 0, /* PaUtilConverter *Float32_To_Int16; */ 0, /* PaUtilConverter *Float32_To_Int16_Dither; */ 0, /* PaUtilConverter *Float32_To_Int16_Clip; */ 0, /* PaUtilConverter *Float32_To_Int16_DitherClip; */ 0, /* PaUtilConverter *Float32_To_Int8; */ 0, /* PaUtilConverter *Float32_To_Int8_Dither; */ 0, /* PaUtilConverter *Float32_To_Int8_Clip; */ 0, /* PaUtilConverter *Float32_To_Int8_DitherClip; */ 0, /* PaUtilConverter *Float32_To_UInt8; */ 0, /* PaUtilConverter *Float32_To_UInt8_Dither; */ 0, /* PaUtilConverter *Float32_To_UInt8_Clip; */ 0, /* PaUtilConverter *Float32_To_UInt8_DitherClip; */ 0, /* PaUtilConverter *Int32_To_Float32; */ 0, /* PaUtilConverter *Int32_To_Int24; */ 0, /* PaUtilConverter *Int32_To_Int24_Dither; */ 0, /* PaUtilConverter *Int32_To_Int16; */ 0, /* PaUtilConverter *Int32_To_Int16_Dither; */ 0, /* PaUtilConverter *Int32_To_Int8; */ 0, /* PaUtilConverter *Int32_To_Int8_Dither; */ 0, /* PaUtilConverter *Int32_To_UInt8; */ 0, /* PaUtilConverter *Int32_To_UInt8_Dither; */ 0, /* PaUtilConverter *Int24_To_Float32; */ 0, /* PaUtilConverter *Int24_To_Int32; */ 0, /* PaUtilConverter *Int24_To_Int16; */ 0, /* PaUtilConverter *Int24_To_Int16_Dither; */ 0, /* PaUtilConverter *Int24_To_Int8; */ 0, /* PaUtilConverter *Int24_To_Int8_Dither; */ 0, /* PaUtilConverter *Int24_To_UInt8; */ 0, /* PaUtilConverter *Int24_To_UInt8_Dither; */ 0, /* PaUtilConverter *Int16_To_Float32; */ 0, /* PaUtilConverter *Int16_To_Int32; */ 0, /* PaUtilConverter *Int16_To_Int24; */ 0, /* PaUtilConverter *Int16_To_Int8; */ 0, /* PaUtilConverter *Int16_To_Int8_Dither; */ 0, /* PaUtilConverter *Int16_To_UInt8; */ 0, /* PaUtilConverter *Int16_To_UInt8_Dither; */ 0, /* PaUtilConverter *Int8_To_Float32; */ 0, /* PaUtilConverter *Int8_To_Int32; */ 0, /* PaUtilConverter *Int8_To_Int24 */ 0, /* PaUtilConverter *Int8_To_Int16; */ 0, /* PaUtilConverter *Int8_To_UInt8; */ 0, /* PaUtilConverter *UInt8_To_Float32; */ 0, /* PaUtilConverter *UInt8_To_Int32; */ 0, /* PaUtilConverter *UInt8_To_Int24; */ 0, /* PaUtilConverter *UInt8_To_Int16; */ 0, /* PaUtilConverter *UInt8_To_Int8; */ 0, /* PaUtilConverter *Copy_8_To_8; */ 0, /* PaUtilConverter *Copy_16_To_16; */ 0, /* PaUtilConverter *Copy_24_To_24; */ 0 /* PaUtilConverter *Copy_32_To_32; */ }; /* -------------------------------------------------------------------------- */ #else /* PA_NO_STANDARD_CONVERTERS is not defined */ /* -------------------------------------------------------------------------- */ #define PA_CLIP_( val, min, max )\ { val = ((val) < (min)) ? (min) : (((val) > (max)) ? (max) : (val)); } static const float const_1_div_128_ = 1.0f / 128.0f; /* 8 bit multiplier */ static const float const_1_div_32768_ = 1.0f / 32768.f; /* 16 bit multiplier */ static const double const_1_div_2147483648_ = 1.0 / 2147483648.0; /* 32 bit multiplier */ /* -------------------------------------------------------------------------- */ static void Float32_To_Int32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; PaInt32 *dest = (PaInt32*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { /* REVIEW */ #ifdef PA_USE_C99_LRINTF float scaled = *src * 0x7FFFFFFF; *dest = lrintf(scaled-0.5f); #else double scaled = *src * 0x7FFFFFFF; *dest = (PaInt32) scaled; #endif src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int32_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; PaInt32 *dest = (PaInt32*)destinationBuffer; while( count-- ) { /* REVIEW */ #ifdef PA_USE_C99_LRINTF float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ float dithered = ((float)*src * (2147483646.0f)) + dither; *dest = lrintf(dithered - 0.5f); #else double dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ double dithered = ((double)*src * (2147483646.0)) + dither; *dest = (PaInt32) dithered; #endif src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int32_Clip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; PaInt32 *dest = (PaInt32*)destinationBuffer; (void) ditherGenerator; /* unused parameter */ while( count-- ) { /* REVIEW */ #ifdef PA_USE_C99_LRINTF float scaled = *src * 0x7FFFFFFF; PA_CLIP_( scaled, -2147483648.f, 2147483647.f ); *dest = lrintf(scaled-0.5f); #else double scaled = *src * 0x7FFFFFFF; PA_CLIP_( scaled, -2147483648., 2147483647. ); *dest = (PaInt32) scaled; #endif src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int32_DitherClip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; PaInt32 *dest = (PaInt32*)destinationBuffer; while( count-- ) { /* REVIEW */ #ifdef PA_USE_C99_LRINTF float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ float dithered = ((float)*src * (2147483646.0f)) + dither; PA_CLIP_( dithered, -2147483648.f, 2147483647.f ); *dest = lrintf(dithered-0.5f); #else double dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ double dithered = ((double)*src * (2147483646.0)) + dither; PA_CLIP_( dithered, -2147483648., 2147483647. ); *dest = (PaInt32) dithered; #endif src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int24( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; PaInt32 temp; (void) ditherGenerator; /* unused parameter */ while( count-- ) { /* convert to 32 bit and drop the low 8 bits */ double scaled = (double)(*src) * 2147483647.0; temp = (PaInt32) scaled; #if defined(PA_LITTLE_ENDIAN) dest[0] = (unsigned char)(temp >> 8); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 24); #elif defined(PA_BIG_ENDIAN) dest[0] = (unsigned char)(temp >> 24); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 8); #endif src += sourceStride; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int24_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; PaInt32 temp; while( count-- ) { /* convert to 32 bit and drop the low 8 bits */ double dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ double dithered = ((double)*src * (2147483646.0)) + dither; temp = (PaInt32) dithered; #if defined(PA_LITTLE_ENDIAN) dest[0] = (unsigned char)(temp >> 8); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 24); #elif defined(PA_BIG_ENDIAN) dest[0] = (unsigned char)(temp >> 24); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 8); #endif src += sourceStride; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int24_Clip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; PaInt32 temp; (void) ditherGenerator; /* unused parameter */ while( count-- ) { /* convert to 32 bit and drop the low 8 bits */ double scaled = *src * 0x7FFFFFFF; PA_CLIP_( scaled, -2147483648., 2147483647. ); temp = (PaInt32) scaled; #if defined(PA_LITTLE_ENDIAN) dest[0] = (unsigned char)(temp >> 8); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 24); #elif defined(PA_BIG_ENDIAN) dest[0] = (unsigned char)(temp >> 24); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 8); #endif src += sourceStride; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int24_DitherClip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; PaInt32 temp; while( count-- ) { /* convert to 32 bit and drop the low 8 bits */ double dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ double dithered = ((double)*src * (2147483646.0)) + dither; PA_CLIP_( dithered, -2147483648., 2147483647. ); temp = (PaInt32) dithered; #if defined(PA_LITTLE_ENDIAN) dest[0] = (unsigned char)(temp >> 8); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 24); #elif defined(PA_BIG_ENDIAN) dest[0] = (unsigned char)(temp >> 24); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 8); #endif src += sourceStride; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int16( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { #ifdef PA_USE_C99_LRINTF float tempf = (*src * (32767.0f)) ; *dest = lrintf(tempf-0.5f); #else short samp = (short) (*src * (32767.0f)); *dest = samp; #endif src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int16_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; while( count-- ) { float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ float dithered = (*src * (32766.0f)) + dither; #ifdef PA_USE_C99_LRINTF *dest = lrintf(dithered-0.5f); #else *dest = (PaInt16) dithered; #endif src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int16_Clip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { #ifdef PA_USE_C99_LRINTF long samp = lrintf((*src * (32767.0f)) -0.5f); #else long samp = (PaInt32) (*src * (32767.0f)); #endif PA_CLIP_( samp, -0x8000, 0x7FFF ); *dest = (PaInt16) samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int16_DitherClip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ float dithered = (*src * (32766.0f)) + dither; PaInt32 samp = (PaInt32) dithered; PA_CLIP_( samp, -0x8000, 0x7FFF ); #ifdef PA_USE_C99_LRINTF *dest = lrintf(samp-0.5f); #else *dest = (PaInt16) samp; #endif src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { signed char samp = (signed char) (*src * (127.0f)); *dest = samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int8_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; while( count-- ) { float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ float dithered = (*src * (126.0f)) + dither; PaInt32 samp = (PaInt32) dithered; *dest = (signed char) samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int8_Clip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { PaInt32 samp = (PaInt32)(*src * (127.0f)); PA_CLIP_( samp, -0x80, 0x7F ); *dest = (signed char) samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int8_DitherClip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ float dithered = (*src * (126.0f)) + dither; PaInt32 samp = (PaInt32) dithered; PA_CLIP_( samp, -0x80, 0x7F ); *dest = (signed char) samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_UInt8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { unsigned char samp = (unsigned char)(128 + ((unsigned char) (*src * (127.0f)))); *dest = samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_UInt8_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; while( count-- ) { float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ float dithered = (*src * (126.0f)) + dither; PaInt32 samp = (PaInt32) dithered; *dest = (unsigned char) (128 + samp); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_UInt8_Clip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { PaInt32 samp = 128 + (PaInt32)(*src * (127.0f)); PA_CLIP_( samp, 0x0000, 0x00FF ); *dest = (unsigned char) samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_UInt8_DitherClip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ float dithered = (*src * (126.0f)) + dither; PaInt32 samp = 128 + (PaInt32) dithered; PA_CLIP_( samp, 0x0000, 0x00FF ); *dest = (unsigned char) samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int32_To_Float32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt32 *src = (PaInt32*)sourceBuffer; float *dest = (float*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { *dest = (float) ((double)*src * const_1_div_2147483648_); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int32_To_Int24( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt32 *src = (PaInt32*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void) ditherGenerator; /* unused parameter */ while( count-- ) { /* REVIEW */ #if defined(PA_LITTLE_ENDIAN) dest[0] = (unsigned char)(*src >> 8); dest[1] = (unsigned char)(*src >> 16); dest[2] = (unsigned char)(*src >> 24); #elif defined(PA_BIG_ENDIAN) dest[0] = (unsigned char)(*src >> 24); dest[1] = (unsigned char)(*src >> 16); dest[2] = (unsigned char)(*src >> 8); #endif src += sourceStride; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Int32_To_Int24_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { (void) destinationBuffer; /* unused parameters */ (void) destinationStride; /* unused parameters */ (void) sourceBuffer; /* unused parameters */ (void) sourceStride; /* unused parameters */ (void) count; /* unused parameters */ (void) ditherGenerator; /* unused parameters */ /* IMPLEMENT ME */ } /* -------------------------------------------------------------------------- */ static void Int32_To_Int16( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt32 *src = (PaInt32*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { *dest = (PaInt16) ((*src) >> 16); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int32_To_Int16_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt32 *src = (PaInt32*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; PaInt32 dither; while( count-- ) { /* REVIEW */ dither = PaUtil_Generate16BitTriangularDither( ditherGenerator ); *dest = (PaInt16) ((((*src)>>1) + dither) >> 15); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int32_To_Int8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt32 *src = (PaInt32*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { *dest = (signed char) ((*src) >> 24); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int32_To_Int8_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt32 *src = (PaInt32*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; PaInt32 dither; while( count-- ) { /* REVIEW */ dither = PaUtil_Generate16BitTriangularDither( ditherGenerator ); *dest = (signed char) ((((*src)>>1) + dither) >> 23); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int32_To_UInt8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt32 *src = (PaInt32*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (unsigned char)(((*src) >> 24) + 128); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int32_To_UInt8_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt32 *src = (PaInt32*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { /* IMPLEMENT ME */ src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int24_To_Float32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; float *dest = (float*)destinationBuffer; PaInt32 temp; (void) ditherGenerator; /* unused parameter */ while( count-- ) { #if defined(PA_LITTLE_ENDIAN) temp = (((PaInt32)src[0]) << 8); temp = temp | (((PaInt32)src[1]) << 16); temp = temp | (((PaInt32)src[2]) << 24); #elif defined(PA_BIG_ENDIAN) temp = (((PaInt32)src[0]) << 24); temp = temp | (((PaInt32)src[1]) << 16); temp = temp | (((PaInt32)src[2]) << 8); #endif *dest = (float) ((double)temp * const_1_div_2147483648_); src += sourceStride * 3; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int24_To_Int32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; PaInt32 *dest = (PaInt32*) destinationBuffer; PaInt32 temp; (void) ditherGenerator; /* unused parameter */ while( count-- ) { #if defined(PA_LITTLE_ENDIAN) temp = (((PaInt32)src[0]) << 8); temp = temp | (((PaInt32)src[1]) << 16); temp = temp | (((PaInt32)src[2]) << 24); #elif defined(PA_BIG_ENDIAN) temp = (((PaInt32)src[0]) << 24); temp = temp | (((PaInt32)src[1]) << 16); temp = temp | (((PaInt32)src[2]) << 8); #endif *dest = temp; src += sourceStride * 3; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int24_To_Int16( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; PaInt16 temp; (void) ditherGenerator; /* unused parameter */ while( count-- ) { #if defined(PA_LITTLE_ENDIAN) /* src[0] is discarded */ temp = (((PaInt16)src[1])); temp = temp | (PaInt16)(((PaInt16)src[2]) << 8); #elif defined(PA_BIG_ENDIAN) /* src[2] is discarded */ temp = (PaInt16)(((PaInt16)src[0]) << 8); temp = temp | (((PaInt16)src[1])); #endif *dest = temp; src += sourceStride * 3; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int24_To_Int16_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; PaInt32 temp, dither; while( count-- ) { #if defined(PA_LITTLE_ENDIAN) temp = (((PaInt32)src[0]) << 8); temp = temp | (((PaInt32)src[1]) << 16); temp = temp | (((PaInt32)src[2]) << 24); #elif defined(PA_BIG_ENDIAN) temp = (((PaInt32)src[0]) << 24); temp = temp | (((PaInt32)src[1]) << 16); temp = temp | (((PaInt32)src[2]) << 8); #endif /* REVIEW */ dither = PaUtil_Generate16BitTriangularDither( ditherGenerator ); *dest = (PaInt16) (((temp >> 1) + dither) >> 15); src += sourceStride * 3; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int24_To_Int8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; (void) ditherGenerator; /* unused parameter */ while( count-- ) { #if defined(PA_LITTLE_ENDIAN) /* src[0] is discarded */ /* src[1] is discarded */ *dest = src[2]; #elif defined(PA_BIG_ENDIAN) /* src[2] is discarded */ /* src[1] is discarded */ *dest = src[0]; #endif src += sourceStride * 3; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int24_To_Int8_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; PaInt32 temp, dither; while( count-- ) { #if defined(PA_LITTLE_ENDIAN) temp = (((PaInt32)src[0]) << 8); temp = temp | (((PaInt32)src[1]) << 16); temp = temp | (((PaInt32)src[2]) << 24); #elif defined(PA_BIG_ENDIAN) temp = (((PaInt32)src[0]) << 24); temp = temp | (((PaInt32)src[1]) << 16); temp = temp | (((PaInt32)src[2]) << 8); #endif /* REVIEW */ dither = PaUtil_Generate16BitTriangularDither( ditherGenerator ); *dest = (signed char) (((temp >> 1) + dither) >> 23); src += sourceStride * 3; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int24_To_UInt8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void) ditherGenerator; /* unused parameter */ while( count-- ) { #if defined(PA_LITTLE_ENDIAN) /* src[0] is discarded */ /* src[1] is discarded */ *dest = (unsigned char)(src[2] + 128); #elif defined(PA_BIG_ENDIAN) *dest = (unsigned char)(src[0] + 128); /* src[1] is discarded */ /* src[2] is discarded */ #endif src += sourceStride * 3; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int24_To_UInt8_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { (void) destinationBuffer; /* unused parameters */ (void) destinationStride; /* unused parameters */ (void) sourceBuffer; /* unused parameters */ (void) sourceStride; /* unused parameters */ (void) count; /* unused parameters */ (void) ditherGenerator; /* unused parameters */ /* IMPLEMENT ME */ } /* -------------------------------------------------------------------------- */ static void Int16_To_Float32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt16 *src = (PaInt16*)sourceBuffer; float *dest = (float*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { float samp = *src * const_1_div_32768_; /* FIXME: i'm concerned about this being asymetrical with float->int16 -rb */ *dest = samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int16_To_Int32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt16 *src = (PaInt16*)sourceBuffer; PaInt32 *dest = (PaInt32*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { /* REVIEW: we should consider something like (*src << 16) | (*src & 0xFFFF) */ *dest = *src << 16; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int16_To_Int24( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt16 *src = (PaInt16*) sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; PaInt16 temp; (void) ditherGenerator; /* unused parameter */ while( count-- ) { temp = *src; #if defined(PA_LITTLE_ENDIAN) dest[0] = 0; dest[1] = (unsigned char)(temp); dest[2] = (unsigned char)(temp >> 8); #elif defined(PA_BIG_ENDIAN) dest[0] = (unsigned char)(temp >> 8); dest[1] = (unsigned char)(temp); dest[2] = 0; #endif src += sourceStride; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Int16_To_Int8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt16 *src = (PaInt16*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (signed char)((*src) >> 8); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int16_To_Int8_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt16 *src = (PaInt16*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { /* IMPLEMENT ME */ src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int16_To_UInt8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt16 *src = (PaInt16*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (unsigned char)(((*src) >> 8) + 128); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int16_To_UInt8_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt16 *src = (PaInt16*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { /* IMPLEMENT ME */ src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int8_To_Float32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { signed char *src = (signed char*)sourceBuffer; float *dest = (float*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { float samp = *src * const_1_div_128_; *dest = samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int8_To_Int32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { signed char *src = (signed char*)sourceBuffer; PaInt32 *dest = (PaInt32*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (*src) << 24; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int8_To_Int24( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { signed char *src = (signed char*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { #if defined(PA_LITTLE_ENDIAN) dest[0] = 0; dest[1] = 0; dest[2] = (*src); #elif defined(PA_BIG_ENDIAN) dest[0] = (*src); dest[1] = 0; dest[2] = 0; #endif src += sourceStride; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Int8_To_Int16( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { signed char *src = (signed char*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (PaInt16)((*src) << 8); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int8_To_UInt8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { signed char *src = (signed char*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (unsigned char)(*src + 128); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void UInt8_To_Float32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; float *dest = (float*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { float samp = (*src - 128) * const_1_div_128_; *dest = samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void UInt8_To_Int32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; PaInt32 *dest = (PaInt32*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (*src - 128) << 24; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void UInt8_To_Int24( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void) ditherGenerator; /* unused parameters */ while( count-- ) { #if defined(PA_LITTLE_ENDIAN) dest[0] = 0; dest[1] = 0; dest[2] = (unsigned char)(*src - 128); #elif defined(PA_BIG_ENDIAN) dest[0] = (unsigned char)(*src - 128); dest[1] = 0; dest[2] = 0; #endif src += sourceStride; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void UInt8_To_Int16( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (PaInt16)((*src - 128) << 8); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void UInt8_To_Int8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (signed char)(*src - 128); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Copy_8_To_8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void) ditherGenerator; /* unused parameter */ while( count-- ) { *dest = *src; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Copy_16_To_16( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaUint16 *src = (PaUint16 *)sourceBuffer; PaUint16 *dest = (PaUint16 *)destinationBuffer; (void) ditherGenerator; /* unused parameter */ while( count-- ) { *dest = *src; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Copy_24_To_24( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void) ditherGenerator; /* unused parameter */ while( count-- ) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; src += sourceStride * 3; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Copy_32_To_32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaUint32 *dest = (PaUint32 *)destinationBuffer; PaUint32 *src = (PaUint32 *)sourceBuffer; (void) ditherGenerator; /* unused parameter */ while( count-- ) { *dest = *src; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ PaUtilConverterTable paConverters = { Float32_To_Int32, /* PaUtilConverter *Float32_To_Int32; */ Float32_To_Int32_Dither, /* PaUtilConverter *Float32_To_Int32_Dither; */ Float32_To_Int32_Clip, /* PaUtilConverter *Float32_To_Int32_Clip; */ Float32_To_Int32_DitherClip, /* PaUtilConverter *Float32_To_Int32_DitherClip; */ Float32_To_Int24, /* PaUtilConverter *Float32_To_Int24; */ Float32_To_Int24_Dither, /* PaUtilConverter *Float32_To_Int24_Dither; */ Float32_To_Int24_Clip, /* PaUtilConverter *Float32_To_Int24_Clip; */ Float32_To_Int24_DitherClip, /* PaUtilConverter *Float32_To_Int24_DitherClip; */ Float32_To_Int16, /* PaUtilConverter *Float32_To_Int16; */ Float32_To_Int16_Dither, /* PaUtilConverter *Float32_To_Int16_Dither; */ Float32_To_Int16_Clip, /* PaUtilConverter *Float32_To_Int16_Clip; */ Float32_To_Int16_DitherClip, /* PaUtilConverter *Float32_To_Int16_DitherClip; */ Float32_To_Int8, /* PaUtilConverter *Float32_To_Int8; */ Float32_To_Int8_Dither, /* PaUtilConverter *Float32_To_Int8_Dither; */ Float32_To_Int8_Clip, /* PaUtilConverter *Float32_To_Int8_Clip; */ Float32_To_Int8_DitherClip, /* PaUtilConverter *Float32_To_Int8_DitherClip; */ Float32_To_UInt8, /* PaUtilConverter *Float32_To_UInt8; */ Float32_To_UInt8_Dither, /* PaUtilConverter *Float32_To_UInt8_Dither; */ Float32_To_UInt8_Clip, /* PaUtilConverter *Float32_To_UInt8_Clip; */ Float32_To_UInt8_DitherClip, /* PaUtilConverter *Float32_To_UInt8_DitherClip; */ Int32_To_Float32, /* PaUtilConverter *Int32_To_Float32; */ Int32_To_Int24, /* PaUtilConverter *Int32_To_Int24; */ Int32_To_Int24_Dither, /* PaUtilConverter *Int32_To_Int24_Dither; */ Int32_To_Int16, /* PaUtilConverter *Int32_To_Int16; */ Int32_To_Int16_Dither, /* PaUtilConverter *Int32_To_Int16_Dither; */ Int32_To_Int8, /* PaUtilConverter *Int32_To_Int8; */ Int32_To_Int8_Dither, /* PaUtilConverter *Int32_To_Int8_Dither; */ Int32_To_UInt8, /* PaUtilConverter *Int32_To_UInt8; */ Int32_To_UInt8_Dither, /* PaUtilConverter *Int32_To_UInt8_Dither; */ Int24_To_Float32, /* PaUtilConverter *Int24_To_Float32; */ Int24_To_Int32, /* PaUtilConverter *Int24_To_Int32; */ Int24_To_Int16, /* PaUtilConverter *Int24_To_Int16; */ Int24_To_Int16_Dither, /* PaUtilConverter *Int24_To_Int16_Dither; */ Int24_To_Int8, /* PaUtilConverter *Int24_To_Int8; */ Int24_To_Int8_Dither, /* PaUtilConverter *Int24_To_Int8_Dither; */ Int24_To_UInt8, /* PaUtilConverter *Int24_To_UInt8; */ Int24_To_UInt8_Dither, /* PaUtilConverter *Int24_To_UInt8_Dither; */ Int16_To_Float32, /* PaUtilConverter *Int16_To_Float32; */ Int16_To_Int32, /* PaUtilConverter *Int16_To_Int32; */ Int16_To_Int24, /* PaUtilConverter *Int16_To_Int24; */ Int16_To_Int8, /* PaUtilConverter *Int16_To_Int8; */ Int16_To_Int8_Dither, /* PaUtilConverter *Int16_To_Int8_Dither; */ Int16_To_UInt8, /* PaUtilConverter *Int16_To_UInt8; */ Int16_To_UInt8_Dither, /* PaUtilConverter *Int16_To_UInt8_Dither; */ Int8_To_Float32, /* PaUtilConverter *Int8_To_Float32; */ Int8_To_Int32, /* PaUtilConverter *Int8_To_Int32; */ Int8_To_Int24, /* PaUtilConverter *Int8_To_Int24 */ Int8_To_Int16, /* PaUtilConverter *Int8_To_Int16; */ Int8_To_UInt8, /* PaUtilConverter *Int8_To_UInt8; */ UInt8_To_Float32, /* PaUtilConverter *UInt8_To_Float32; */ UInt8_To_Int32, /* PaUtilConverter *UInt8_To_Int32; */ UInt8_To_Int24, /* PaUtilConverter *UInt8_To_Int24; */ UInt8_To_Int16, /* PaUtilConverter *UInt8_To_Int16; */ UInt8_To_Int8, /* PaUtilConverter *UInt8_To_Int8; */ Copy_8_To_8, /* PaUtilConverter *Copy_8_To_8; */ Copy_16_To_16, /* PaUtilConverter *Copy_16_To_16; */ Copy_24_To_24, /* PaUtilConverter *Copy_24_To_24; */ Copy_32_To_32 /* PaUtilConverter *Copy_32_To_32; */ }; /* -------------------------------------------------------------------------- */ #endif /* PA_NO_STANDARD_CONVERTERS */ /* -------------------------------------------------------------------------- */ PaUtilZeroer* PaUtil_SelectZeroer( PaSampleFormat destinationFormat ) { switch( destinationFormat & ~paNonInterleaved ){ case paFloat32: return paZeroers.Zero32; case paInt32: return paZeroers.Zero32; case paInt24: return paZeroers.Zero24; case paInt16: return paZeroers.Zero16; case paInt8: return paZeroers.Zero8; case paUInt8: return paZeroers.ZeroU8; default: return 0; } } /* -------------------------------------------------------------------------- */ #ifdef PA_NO_STANDARD_ZEROERS /* -------------------------------------------------------------------------- */ PaUtilZeroerTable paZeroers = { 0, /* PaUtilZeroer *ZeroU8; */ 0, /* PaUtilZeroer *Zero8; */ 0, /* PaUtilZeroer *Zero16; */ 0, /* PaUtilZeroer *Zero24; */ 0, /* PaUtilZeroer *Zero32; */ }; /* -------------------------------------------------------------------------- */ #else /* PA_NO_STANDARD_ZEROERS is not defined */ /* -------------------------------------------------------------------------- */ static void ZeroU8( void *destinationBuffer, signed int destinationStride, unsigned int count ) { unsigned char *dest = (unsigned char*)destinationBuffer; while( count-- ) { *dest = 128; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Zero8( void *destinationBuffer, signed int destinationStride, unsigned int count ) { unsigned char *dest = (unsigned char*)destinationBuffer; while( count-- ) { *dest = 0; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Zero16( void *destinationBuffer, signed int destinationStride, unsigned int count ) { PaUint16 *dest = (PaUint16 *)destinationBuffer; while( count-- ) { *dest = 0; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Zero24( void *destinationBuffer, signed int destinationStride, unsigned int count ) { unsigned char *dest = (unsigned char*)destinationBuffer; while( count-- ) { dest[0] = 0; dest[1] = 0; dest[2] = 0; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Zero32( void *destinationBuffer, signed int destinationStride, unsigned int count ) { PaUint32 *dest = (PaUint32 *)destinationBuffer; while( count-- ) { *dest = 0; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ PaUtilZeroerTable paZeroers = { ZeroU8, /* PaUtilZeroer *ZeroU8; */ Zero8, /* PaUtilZeroer *Zero8; */ Zero16, /* PaUtilZeroer *Zero16; */ Zero24, /* PaUtilZeroer *Zero24; */ Zero32, /* PaUtilZeroer *Zero32; */ }; /* -------------------------------------------------------------------------- */ #endif /* PA_NO_STANDARD_ZEROERS */ praat-6.0.04/external/portaudio/pa_converters.h000066400000000000000000000237601261542461700216030ustar00rootroot00000000000000#ifndef PA_CONVERTERS_H #define PA_CONVERTERS_H /* * $Id: pa_converters.h 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library sample conversion mechanism * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Phil Burk, Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Conversion functions used to convert buffers of samples from one format to another. */ #include "portaudio.h" /* for PaSampleFormat */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ struct PaUtilTriangularDitherGenerator; /** Choose an available sample format which is most appropriate for representing the requested format. If the requested format is not available higher quality formats are considered before lower quality formates. @param availableFormats A variable containing the logical OR of all available formats. @param format The desired format. @return The most appropriate available format for representing the requested format. */ PaSampleFormat PaUtil_SelectClosestAvailableFormat( PaSampleFormat availableFormats, PaSampleFormat format ); /* high level conversions functions for use by implementations */ /** The generic sample converter prototype. Sample converters convert count samples from sourceBuffer to destinationBuffer. The actual type of the data pointed to by these parameters varys for different converter functions. @param destinationBuffer A pointer to the first sample of the destination. @param destinationStride An offset between successive destination samples expressed in samples (not bytes.) It may be negative. @param sourceBuffer A pointer to the first sample of the source. @param sourceStride An offset between successive source samples expressed in samples (not bytes.) It may be negative. @param count The number of samples to convert. @param ditherState State information used to calculate dither. Converters that do not perform dithering will ignore this parameter, in which case NULL or invalid dither state may be passed. */ typedef void PaUtilConverter( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ); /** Find a sample converter function for the given source and destinations formats and flags (clip and dither.) @return A pointer to a PaUtilConverter which will perform the requested conversion, or NULL if the given format conversion is not supported. For conversions where clipping or dithering is not necessary, the clip and dither flags are ignored and a non-clipping or dithering version is returned. If the source and destination formats are the same, a function which copies data of the appropriate size will be returned. */ PaUtilConverter* PaUtil_SelectConverter( PaSampleFormat sourceFormat, PaSampleFormat destinationFormat, PaStreamFlags flags ); /** The generic buffer zeroer prototype. Buffer zeroers copy count zeros to destinationBuffer. The actual type of the data pointed to varys for different zeroer functions. @param destinationBuffer A pointer to the first sample of the destination. @param destinationStride An offset between successive destination samples expressed in samples (not bytes.) It may be negative. @param count The number of samples to zero. */ typedef void PaUtilZeroer( void *destinationBuffer, signed int destinationStride, unsigned int count ); /** Find a buffer zeroer function for the given destination format. @return A pointer to a PaUtilZeroer which will perform the requested zeroing. */ PaUtilZeroer* PaUtil_SelectZeroer( PaSampleFormat destinationFormat ); /*----------------------------------------------------------------------------*/ /* low level functions and data structures which may be used for substituting conversion functions */ /** The type used to store all sample conversion functions. @see paConverters; */ typedef struct{ PaUtilConverter *Float32_To_Int32; PaUtilConverter *Float32_To_Int32_Dither; PaUtilConverter *Float32_To_Int32_Clip; PaUtilConverter *Float32_To_Int32_DitherClip; PaUtilConverter *Float32_To_Int24; PaUtilConverter *Float32_To_Int24_Dither; PaUtilConverter *Float32_To_Int24_Clip; PaUtilConverter *Float32_To_Int24_DitherClip; PaUtilConverter *Float32_To_Int16; PaUtilConverter *Float32_To_Int16_Dither; PaUtilConverter *Float32_To_Int16_Clip; PaUtilConverter *Float32_To_Int16_DitherClip; PaUtilConverter *Float32_To_Int8; PaUtilConverter *Float32_To_Int8_Dither; PaUtilConverter *Float32_To_Int8_Clip; PaUtilConverter *Float32_To_Int8_DitherClip; PaUtilConverter *Float32_To_UInt8; PaUtilConverter *Float32_To_UInt8_Dither; PaUtilConverter *Float32_To_UInt8_Clip; PaUtilConverter *Float32_To_UInt8_DitherClip; PaUtilConverter *Int32_To_Float32; PaUtilConverter *Int32_To_Int24; PaUtilConverter *Int32_To_Int24_Dither; PaUtilConverter *Int32_To_Int16; PaUtilConverter *Int32_To_Int16_Dither; PaUtilConverter *Int32_To_Int8; PaUtilConverter *Int32_To_Int8_Dither; PaUtilConverter *Int32_To_UInt8; PaUtilConverter *Int32_To_UInt8_Dither; PaUtilConverter *Int24_To_Float32; PaUtilConverter *Int24_To_Int32; PaUtilConverter *Int24_To_Int16; PaUtilConverter *Int24_To_Int16_Dither; PaUtilConverter *Int24_To_Int8; PaUtilConverter *Int24_To_Int8_Dither; PaUtilConverter *Int24_To_UInt8; PaUtilConverter *Int24_To_UInt8_Dither; PaUtilConverter *Int16_To_Float32; PaUtilConverter *Int16_To_Int32; PaUtilConverter *Int16_To_Int24; PaUtilConverter *Int16_To_Int8; PaUtilConverter *Int16_To_Int8_Dither; PaUtilConverter *Int16_To_UInt8; PaUtilConverter *Int16_To_UInt8_Dither; PaUtilConverter *Int8_To_Float32; PaUtilConverter *Int8_To_Int32; PaUtilConverter *Int8_To_Int24; PaUtilConverter *Int8_To_Int16; PaUtilConverter *Int8_To_UInt8; PaUtilConverter *UInt8_To_Float32; PaUtilConverter *UInt8_To_Int32; PaUtilConverter *UInt8_To_Int24; PaUtilConverter *UInt8_To_Int16; PaUtilConverter *UInt8_To_Int8; PaUtilConverter *Copy_8_To_8; /* copy without any conversion */ PaUtilConverter *Copy_16_To_16; /* copy without any conversion */ PaUtilConverter *Copy_24_To_24; /* copy without any conversion */ PaUtilConverter *Copy_32_To_32; /* copy without any conversion */ } PaUtilConverterTable; /** A table of pointers to all required converter functions. PaUtil_SelectConverter() uses this table to lookup the appropriate conversion functions. The fields of this structure are initialized with default conversion functions. Fields may be NULL, indicating that no conversion function is available. User code may substitue optimised conversion functions by assigning different function pointers to these fields. @note If the PA_NO_STANDARD_CONVERTERS preprocessor variable is defined, PortAudio's standard converters will not be compiled, and all fields of this structure will be initialized to NULL. In such cases, users should supply their own conversion functions if the require PortAudio to open a stream that requires sample conversion. @see PaUtilConverterTable, PaUtilConverter, PaUtil_SelectConverter */ extern PaUtilConverterTable paConverters; /** The type used to store all buffer zeroing functions. @see paZeroers; */ typedef struct{ PaUtilZeroer *ZeroU8; /* unsigned 8 bit, zero == 128 */ PaUtilZeroer *Zero8; PaUtilZeroer *Zero16; PaUtilZeroer *Zero24; PaUtilZeroer *Zero32; } PaUtilZeroerTable; /** A table of pointers to all required zeroer functions. PaUtil_SelectZeroer() uses this table to lookup the appropriate conversion functions. The fields of this structure are initialized with default conversion functions. User code may substitue optimised conversion functions by assigning different function pointers to these fields. @note If the PA_NO_STANDARD_ZEROERS preprocessor variable is defined, PortAudio's standard zeroers will not be compiled, and all fields of this structure will be initialized to NULL. In such cases, users should supply their own zeroing functions for the sample sizes which they intend to use. @see PaUtilZeroerTable, PaUtilZeroer, PaUtil_SelectZeroer */ extern PaUtilZeroerTable paZeroers; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_CONVERTERS_H */ praat-6.0.04/external/portaudio/pa_cpuload.c000066400000000000000000000074331261542461700210320ustar00rootroot00000000000000/* * $Id: pa_cpuload.c 1577 2011-02-01 13:03:45Z rossb $ * Portable Audio I/O Library CPU Load measurement functions * Portable CPU load measurement facility. * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 2002 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Functions to assist in measuring the CPU utilization of a callback stream. Used to implement the Pa_GetStreamCpuLoad() function. @todo Dynamically calculate the coefficients used to smooth the CPU Load Measurements over time to provide a uniform characterisation of CPU Load independent of rate at which PaUtil_BeginCpuLoadMeasurement / PaUtil_EndCpuLoadMeasurement are called. see http://www.portaudio.com/trac/ticket/113 */ #include "pa_cpuload.h" #include #include "pa_util.h" /* for PaUtil_GetTime() */ void PaUtil_InitializeCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer, double sampleRate ) { assert( sampleRate > 0 ); measurer->samplingPeriod = 1. / sampleRate; measurer->averageLoad = 0.; } void PaUtil_ResetCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer ) { measurer->averageLoad = 0.; } void PaUtil_BeginCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer ) { measurer->measurementStartTime = PaUtil_GetTime(); } void PaUtil_EndCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer, unsigned long framesProcessed ) { double measurementEndTime, secondsFor100Percent, measuredLoad; if( framesProcessed > 0 ){ measurementEndTime = PaUtil_GetTime(); assert( framesProcessed > 0 ); secondsFor100Percent = framesProcessed * measurer->samplingPeriod; measuredLoad = (measurementEndTime - measurer->measurementStartTime) / secondsFor100Percent; /* Low pass filter the calculated CPU load to reduce jitter using a simple IIR low pass filter. */ /** FIXME @todo these coefficients shouldn't be hardwired see: http://www.portaudio.com/trac/ticket/113 */ #define LOWPASS_COEFFICIENT_0 (0.9) #define LOWPASS_COEFFICIENT_1 (0.99999 - LOWPASS_COEFFICIENT_0) measurer->averageLoad = (LOWPASS_COEFFICIENT_0 * measurer->averageLoad) + (LOWPASS_COEFFICIENT_1 * measuredLoad); } } double PaUtil_GetCpuLoad( PaUtilCpuLoadMeasurer* measurer ) { return measurer->averageLoad; } praat-6.0.04/external/portaudio/pa_cpuload.h000066400000000000000000000052371261542461700210370ustar00rootroot00000000000000#ifndef PA_CPULOAD_H #define PA_CPULOAD_H /* * $Id: pa_cpuload.h 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library CPU Load measurement functions * Portable CPU load measurement facility. * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 2002 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Functions to assist in measuring the CPU utilization of a callback stream. Used to implement the Pa_GetStreamCpuLoad() function. */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ typedef struct { double samplingPeriod; double measurementStartTime; double averageLoad; } PaUtilCpuLoadMeasurer; /**< @todo need better name than measurer */ void PaUtil_InitializeCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer, double sampleRate ); void PaUtil_BeginCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer ); void PaUtil_EndCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer, unsigned long framesProcessed ); void PaUtil_ResetCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer ); double PaUtil_GetCpuLoad( PaUtilCpuLoadMeasurer* measurer ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_CPULOAD_H */ praat-6.0.04/external/portaudio/pa_debugprint.c000066400000000000000000000076421261542461700215500ustar00rootroot00000000000000/* * $Id: pa_log.c $ * Portable Audio I/O Library Multi-Host API front end * Validate function parameters and manage multiple host APIs. * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2006 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Implements log function. PaUtil_SetLogPrintFunction can be user called to replace the provided DefaultLogPrint function, which writes to stderr. One can NOT pass var_args across compiler/dll boundaries as it is not "byte code/abi portable". So the technique used here is to allocate a local a static array, write in it, then callback the user with a pointer to its start. */ #include #include #include "pa_debugprint.h" // for OutputDebugStringA #if defined(_MSC_VER) && defined(PA_ENABLE_MSVC_DEBUG_OUTPUT) #define WIN32_LEAN_AND_MEAN // exclude rare headers #include "windows.h" #endif // User callback static PaUtilLogCallback userCB = NULL; // Sets user callback void PaUtil_SetDebugPrintFunction(PaUtilLogCallback cb) { userCB = cb; } /* If your platform doesnt have vsnprintf, you are stuck with a VERY dangerous alternative, vsprintf (with no n) */ #if _MSC_VER /* Some Windows Mobile SDKs don't define vsnprintf but all define _vsnprintf (hopefully). According to MSDN "vsnprintf is identical to _vsnprintf". So we use _vsnprintf with MSC. */ #define VSNPRINTF _vsnprintf #else #define VSNPRINTF vsnprintf #endif #define PA_LOG_BUF_SIZE 2048 void PaUtil_DebugPrint( const char *format, ... ) { // Optional logging into Output console of Visual Studio #if defined(_MSC_VER) && defined(PA_ENABLE_MSVC_DEBUG_OUTPUT) { char buf[PA_LOG_BUF_SIZE]; va_list ap; va_start(ap, format); VSNPRINTF(buf, sizeof(buf), format, ap); buf[sizeof(buf)-1] = 0; OutputDebugStringA(buf); va_end(ap); } #endif // Output to User-Callback if (userCB != NULL) { char strdump[PA_LOG_BUF_SIZE]; va_list ap; va_start(ap, format); VSNPRINTF(strdump, sizeof(strdump), format, ap); strdump[sizeof(strdump)-1] = 0; userCB(strdump); va_end(ap); } else // Standard output to stderr { va_list ap; va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); fflush(stderr); } } praat-6.0.04/external/portaudio/pa_debugprint.h000066400000000000000000000116611261542461700215510ustar00rootroot00000000000000#ifndef PA_LOG_H #define PA_LOG_H /* * Log file redirector function * Copyright (c) 1999-2006 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ void PaUtil_DebugPrint( const char *format, ... ); /* The basic format for log messages is described below. If you need to add any log messages, please follow this format. Function entry (void function): "FunctionName called.\n" Function entry (non void function): "FunctionName called:\n" "\tParam1Type param1: param1Value\n" "\tParam2Type param2: param2Value\n" (etc...) Function exit (no return value): "FunctionName returned.\n" Function exit (simple return value): "FunctionName returned:\n" "\tReturnType: returnValue\n" If the return type is an error code, the error text is displayed in () If the return type is not an error code, but has taken a special value because an error occurred, then the reason for the error is shown in [] If the return type is a struct ptr, the struct is dumped. See the code below for examples */ /** PA_DEBUG() provides a simple debug message printing facility. The macro passes it's argument to a printf-like function called PaUtil_DebugPrint() which prints to stderr and always flushes the stream after printing. Because preprocessor macros cannot directly accept variable length argument lists, calls to the macro must include an additional set of parenthesis, eg: PA_DEBUG(("errorno: %d", 1001 )); */ #ifdef PA_ENABLE_DEBUG_OUTPUT #define PA_DEBUG(x) PaUtil_DebugPrint x ; #else #define PA_DEBUG(x) #endif #ifdef PA_LOG_API_CALLS #define PA_LOGAPI(x) PaUtil_DebugPrint x #define PA_LOGAPI_ENTER(functionName) PaUtil_DebugPrint( functionName " called.\n" ) #define PA_LOGAPI_ENTER_PARAMS(functionName) PaUtil_DebugPrint( functionName " called:\n" ) #define PA_LOGAPI_EXIT(functionName) PaUtil_DebugPrint( functionName " returned.\n" ) #define PA_LOGAPI_EXIT_PAERROR( functionName, result ) \ PaUtil_DebugPrint( functionName " returned:\n" ); \ PaUtil_DebugPrint("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ) #define PA_LOGAPI_EXIT_T( functionName, resultFormatString, result ) \ PaUtil_DebugPrint( functionName " returned:\n" ); \ PaUtil_DebugPrint("\t" resultFormatString "\n", result ) #define PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( functionName, positiveResultFormatString, result ) \ PaUtil_DebugPrint( functionName " returned:\n" ); \ if( result > 0 ) \ PaUtil_DebugPrint("\t" positiveResultFormatString "\n", result ); \ else \ PaUtil_DebugPrint("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ) #else #define PA_LOGAPI(x) #define PA_LOGAPI_ENTER(functionName) #define PA_LOGAPI_ENTER_PARAMS(functionName) #define PA_LOGAPI_EXIT(functionName) #define PA_LOGAPI_EXIT_PAERROR( functionName, result ) #define PA_LOGAPI_EXIT_T( functionName, resultFormatString, result ) #define PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( functionName, positiveResultFormatString, result ) #endif typedef void (*PaUtilLogCallback ) (const char *log); /** Install user provided log function */ void PaUtil_SetDebugPrintFunction(PaUtilLogCallback cb); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_LOG_H */ praat-6.0.04/external/portaudio/pa_dither.c000066400000000000000000000160111261542461700206520ustar00rootroot00000000000000/* * $Id: pa_dither.c 1418 2009-10-12 21:00:53Z philburk $ * Portable Audio I/O Library triangular dither generator * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Phil Burk, Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Functions for generating dither noise */ #include "pa_types.h" #include "pa_dither.h" /* Note that the linear congruential algorithm requires 32 bit integers * because it uses arithmetic overflow. So use PaUint32 instead of * unsigned long so it will work on 64 bit systems. */ #define PA_DITHER_BITS_ (15) void PaUtil_InitializeTriangularDitherState( PaUtilTriangularDitherGenerator *state ) { state->previous = 0; state->randSeed1 = 22222; state->randSeed2 = 5555555; } PaInt32 PaUtil_Generate16BitTriangularDither( PaUtilTriangularDitherGenerator *state ) { PaInt32 current, highPass; /* Generate two random numbers. */ state->randSeed1 = (state->randSeed1 * 196314165) + 907633515; state->randSeed2 = (state->randSeed2 * 196314165) + 907633515; /* Generate triangular distribution about 0. * Shift before adding to prevent overflow which would skew the distribution. * Also shift an extra bit for the high pass filter. */ #define DITHER_SHIFT_ ((sizeof(PaInt32)*8 - PA_DITHER_BITS_) + 1) current = (((PaInt32)state->randSeed1)>>DITHER_SHIFT_) + (((PaInt32)state->randSeed2)>>DITHER_SHIFT_); /* High pass filter to reduce audibility. */ highPass = current - state->previous; state->previous = current; return highPass; } /* Multiply by PA_FLOAT_DITHER_SCALE_ to get a float between -2.0 and +1.99999 */ #define PA_FLOAT_DITHER_SCALE_ (1.0f / ((1<randSeed1 = (state->randSeed1 * 196314165) + 907633515; state->randSeed2 = (state->randSeed2 * 196314165) + 907633515; /* Generate triangular distribution about 0. * Shift before adding to prevent overflow which would skew the distribution. * Also shift an extra bit for the high pass filter. */ current = (((PaInt32)state->randSeed1)>>DITHER_SHIFT_) + (((PaInt32)state->randSeed2)>>DITHER_SHIFT_); /* High pass filter to reduce audibility. */ highPass = current - state->previous; state->previous = current; return ((float)highPass) * const_float_dither_scale_; } /* The following alternate dither algorithms (from musicdsp.org) could be considered */ /*Noise shaped dither (March 2000) ------------------- This is a simple implementation of highpass triangular-PDF dither with 2nd-order noise shaping, for use when truncating floating point audio data to fixed point. The noise shaping lowers the noise floor by 11dB below 5kHz (@ 44100Hz sample rate) compared to triangular-PDF dither. The code below assumes input data is in the range +1 to -1 and doesn't check for overloads! To save time when generating dither for multiple channels you can do things like this: r3=(r1 & 0x7F)<<8; instead of calling rand() again. int r1, r2; //rectangular-PDF random numbers float s1, s2; //error feedback buffers float s = 0.5f; //set to 0.0f for no noise shaping float w = pow(2.0,bits-1); //word length (usually bits=16) float wi= 1.0f/w; float d = wi / RAND_MAX; //dither amplitude (2 lsb) float o = wi * 0.5f; //remove dc offset float in, tmp; int out; //for each sample... r2=r1; //can make HP-TRI dither by r1=rand(); //subtracting previous rand() in += s * (s1 + s1 - s2); //error feedback tmp = in + o + d * (float)(r1 - r2); //dc offset and dither out = (int)(w * tmp); //truncate downwards if(tmp<0.0f) out--; //this is faster than floor() s2 = s1; s1 = in - wi * (float)out; //error -- paul.kellett@maxim.abel.co.uk http://www.maxim.abel.co.uk */ /* 16-to-8-bit first-order dither Type : First order error feedforward dithering code References : Posted by Jon Watte Notes : This is about as simple a dithering algorithm as you can implement, but it's likely to sound better than just truncating to N bits. Note that you might not want to carry forward the full difference for infinity. It's probably likely that the worst performance hit comes from the saturation conditionals, which can be avoided with appropriate instructions on many DSPs and integer SIMD type instructions, or CMOV. Last, if sound quality is paramount (such as when going from > 16 bits to 16 bits) you probably want to use a higher-order dither function found elsewhere on this site. Code : // This code will down-convert and dither a 16-bit signed short // mono signal into an 8-bit unsigned char signal, using a first // order forward-feeding error term dither. #define uchar unsigned char void dither_one_channel_16_to_8( short * input, uchar * output, int count, int * memory ) { int m = *memory; while( count-- > 0 ) { int i = *input++; i += m; int j = i + 32768 - 128; uchar o; if( j < 0 ) { o = 0; } else if( j > 65535 ) { o = 255; } else { o = (uchar)((j>>8)&0xff); } m = ((j-32768+128)-i); *output++ = o; } *memory = m; } */ praat-6.0.04/external/portaudio/pa_dither.h000066400000000000000000000067761261542461700207000ustar00rootroot00000000000000#ifndef PA_DITHER_H #define PA_DITHER_H /* * $Id: pa_dither.h 1418 2009-10-12 21:00:53Z philburk $ * Portable Audio I/O Library triangular dither generator * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Phil Burk, Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Functions for generating dither noise */ #include "pa_types.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* Note that the linear congruential algorithm requires 32 bit integers * because it uses arithmetic overflow. So use PaUint32 instead of * unsigned long so it will work on 64 bit systems. */ /** @brief State needed to generate a dither signal */ typedef struct PaUtilTriangularDitherGenerator{ PaUint32 previous; PaUint32 randSeed1; PaUint32 randSeed2; } PaUtilTriangularDitherGenerator; /** @brief Initialize dither state */ void PaUtil_InitializeTriangularDitherState( PaUtilTriangularDitherGenerator *ditherState ); /** @brief Calculate 2 LSB dither signal with a triangular distribution. Ranged for adding to a 1 bit right-shifted 32 bit integer prior to >>15. eg:
    signed long in = *
    signed long dither = PaUtil_Generate16BitTriangularDither( ditherState );
    signed short out = (signed short)(((in>>1) + dither) >> 15);
@return A signed 32-bit integer with a range of +32767 to -32768 */ PaInt32 PaUtil_Generate16BitTriangularDither( PaUtilTriangularDitherGenerator *ditherState ); /** @brief Calculate 2 LSB dither signal with a triangular distribution. Ranged for adding to a pre-scaled float.
    float in = *
    float dither = PaUtil_GenerateFloatTriangularDither( ditherState );
    // use smaller scaler to prevent overflow when we add the dither
    signed short out = (signed short)(in*(32766.0f) + dither );
@return A float with a range of -2.0 to +1.99999. */ float PaUtil_GenerateFloatTriangularDither( PaUtilTriangularDitherGenerator *ditherState ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_DITHER_H */ praat-6.0.04/external/portaudio/pa_endianness.h000066400000000000000000000126201261542461700215310ustar00rootroot00000000000000#ifndef PA_ENDIANNESS_H #define PA_ENDIANNESS_H /* * $Id: pa_endianness.h 1324 2008-01-27 02:03:30Z bjornroche $ * Portable Audio I/O Library current platform endianness macros * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Phil Burk, Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Configure endianness symbols for the target processor. Arrange for either the PA_LITTLE_ENDIAN or PA_BIG_ENDIAN preprocessor symbols to be defined. The one that is defined reflects the endianness of the target platform and may be used to implement conditional compilation of byte-order dependent code. If either PA_LITTLE_ENDIAN or PA_BIG_ENDIAN is defined already, then no attempt is made to override that setting. This may be useful if you have a better way of determining the platform's endianness. The autoconf mechanism uses this for example. A PA_VALIDATE_ENDIANNESS macro is provided to compare the compile time and runtime endiannes and raise an assertion if they don't match. */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* If this is an apple, we need to do detect endianness this way */ #if defined(__APPLE__) /* we need to do some endian detection that is sensitive to harware arch */ #if defined(__LITTLE_ENDIAN__) #if !defined( PA_LITTLE_ENDIAN ) #define PA_LITTLE_ENDIAN #endif #if defined( PA_BIG_ENDIAN ) #undef PA_BIG_ENDIAN #endif #else #if !defined( PA_BIG_ENDIAN ) #define PA_BIG_ENDIAN #endif #if defined( PA_LITTLE_ENDIAN ) #undef PA_LITTLE_ENDIAN #endif #endif #else /* this is not an apple, so first check the existing defines, and, failing that, detect well-known architechtures. */ #if defined(PA_LITTLE_ENDIAN) || defined(PA_BIG_ENDIAN) /* endianness define has been set externally, such as by autoconf */ #if defined(PA_LITTLE_ENDIAN) && defined(PA_BIG_ENDIAN) #error both PA_LITTLE_ENDIAN and PA_BIG_ENDIAN have been defined externally to pa_endianness.h - only one endianness at a time please #endif #else /* endianness define has not been set externally */ /* set PA_LITTLE_ENDIAN or PA_BIG_ENDIAN by testing well known platform specific defines */ #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(LITTLE_ENDIAN) || defined(__i386) || defined(_M_IX86) || defined(__x86_64__) #define PA_LITTLE_ENDIAN /* win32, assume intel byte order */ #else #define PA_BIG_ENDIAN #endif #endif #if !defined(PA_LITTLE_ENDIAN) && !defined(PA_BIG_ENDIAN) /* If the following error is raised, you either need to modify the code above to automatically determine the endianness from other symbols defined on your platform, or define either PA_LITTLE_ENDIAN or PA_BIG_ENDIAN externally. */ #error pa_endianness.h was unable to automatically determine the endianness of the target platform #endif #endif /* PA_VALIDATE_ENDIANNESS compares the compile time and runtime endianness, and raises an assertion if they don't match. must be included in the context in which this macro is used. */ #if defined(NDEBUG) #define PA_VALIDATE_ENDIANNESS #else #if defined(PA_LITTLE_ENDIAN) #define PA_VALIDATE_ENDIANNESS \ { \ const long nativeOne = 1; \ assert( "PortAudio: compile time and runtime endianness don't match" && (((char *)&nativeOne)[0]) == 1 ); \ } #elif defined(PA_BIG_ENDIAN) #define PA_VALIDATE_ENDIANNESS \ { \ const long nativeOne = 1; \ assert( "PortAudio: compile time and runtime endianness don't match" && (((char *)&nativeOne)[0]) == 0 ); \ } #endif #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_ENDIANNESS_H */ praat-6.0.04/external/portaudio/pa_front.c000066400000000000000000001536031261542461700205340ustar00rootroot00000000000000/* * $Id: pa_front.c 1880 2012-12-04 18:39:48Z rbencina $ * Portable Audio I/O Library Multi-Host API front end * Validate function parameters and manage multiple host APIs. * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2008 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Implements PortAudio API functions defined in portaudio.h, checks some errors, delegates platform-specific behavior to host API implementations. Implements the functions defined in the PortAudio API (portaudio.h), validates some parameters and checks for state inconsistencies before forwarding API requests to specific Host API implementations (via the interface declared in pa_hostapi.h), and Streams (via the interface declared in pa_stream.h). This file manages initialization and termination of Host API implementations via initializer functions stored in the paHostApiInitializers global array (usually defined in an os-specific pa_[os]_hostapis.c file). This file maintains a list of all open streams and closes them at Pa_Terminate(). Some utility functions declared in pa_util.h are implemented in this file. All PortAudio API functions can be conditionally compiled with logging code. To compile with logging, define the PA_LOG_API_CALLS precompiler symbol. */ #include #include #include #include /* needed by PA_VALIDATE_ENDIANNESS */ #include "portaudio.h" #include "pa_util.h" #include "pa_endianness.h" #include "pa_types.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_trace.h" /* still usefull?*/ #include "pa_debugprint.h" #define PA_VERSION_ 1899 #define PA_VERSION_TEXT_ "PortAudio V19-devel (built " __DATE__ " " __TIME__ ")" int Pa_GetVersion( void ) { return PA_VERSION_; } const char* Pa_GetVersionText( void ) { return PA_VERSION_TEXT_; } #define PA_LAST_HOST_ERROR_TEXT_LENGTH_ 1024 static char lastHostErrorText_[ PA_LAST_HOST_ERROR_TEXT_LENGTH_ + 1 ] = {0}; static PaHostErrorInfo lastHostErrorInfo_ = { (PaHostApiTypeId)-1, 0, lastHostErrorText_ }; void PaUtil_SetLastHostErrorInfo( PaHostApiTypeId hostApiType, long errorCode, const char *errorText ) { lastHostErrorInfo_.hostApiType = hostApiType; lastHostErrorInfo_.errorCode = errorCode; strncpy( lastHostErrorText_, errorText, PA_LAST_HOST_ERROR_TEXT_LENGTH_ ); } static PaUtilHostApiRepresentation **hostApis_ = 0; static int hostApisCount_ = 0; static int defaultHostApiIndex_ = 0; static int initializationCount_ = 0; static int deviceCount_ = 0; PaUtilStreamRepresentation *firstOpenStream_ = NULL; #define PA_IS_INITIALISED_ (initializationCount_ != 0) static int CountHostApiInitializers( void ) { int result = 0; while( paHostApiInitializers[ result ] != 0 ) ++result; return result; } static void TerminateHostApis( void ) { /* terminate in reverse order from initialization */ PA_DEBUG(("TerminateHostApis in \n")); while( hostApisCount_ > 0 ) { --hostApisCount_; hostApis_[hostApisCount_]->Terminate( hostApis_[hostApisCount_] ); } hostApisCount_ = 0; defaultHostApiIndex_ = 0; deviceCount_ = 0; if( hostApis_ != 0 ) PaUtil_FreeMemory( hostApis_ ); hostApis_ = 0; PA_DEBUG(("TerminateHostApis out\n")); } static PaError InitializeHostApis( void ) { PaError result = paNoError; int i, initializerCount, baseDeviceIndex; initializerCount = CountHostApiInitializers(); hostApis_ = (PaUtilHostApiRepresentation**)PaUtil_AllocateMemory( sizeof(PaUtilHostApiRepresentation*) * initializerCount ); if( !hostApis_ ) { result = paInsufficientMemory; goto error; } hostApisCount_ = 0; defaultHostApiIndex_ = -1; /* indicates that we haven't determined the default host API yet */ deviceCount_ = 0; baseDeviceIndex = 0; for( i=0; i< initializerCount; ++i ) { hostApis_[hostApisCount_] = NULL; PA_DEBUG(( "before paHostApiInitializers[%d].\n",i)); result = paHostApiInitializers[i]( &hostApis_[hostApisCount_], hostApisCount_ ); if( result != paNoError ) goto error; PA_DEBUG(( "after paHostApiInitializers[%d].\n",i)); if( hostApis_[hostApisCount_] ) { PaUtilHostApiRepresentation* hostApi = hostApis_[hostApisCount_]; assert( hostApi->info.defaultInputDevice < hostApi->info.deviceCount ); assert( hostApi->info.defaultOutputDevice < hostApi->info.deviceCount ); /* the first successfully initialized host API with a default input *or* output device is used as the default host API. */ if( (defaultHostApiIndex_ == -1) && ( hostApi->info.defaultInputDevice != paNoDevice || hostApi->info.defaultOutputDevice != paNoDevice ) ) { defaultHostApiIndex_ = hostApisCount_; } hostApi->privatePaFrontInfo.baseDeviceIndex = baseDeviceIndex; if( hostApi->info.defaultInputDevice != paNoDevice ) hostApi->info.defaultInputDevice += baseDeviceIndex; if( hostApi->info.defaultOutputDevice != paNoDevice ) hostApi->info.defaultOutputDevice += baseDeviceIndex; baseDeviceIndex += hostApi->info.deviceCount; deviceCount_ += hostApi->info.deviceCount; ++hostApisCount_; } } /* if no host APIs have devices, the default host API is the first initialized host API */ if( defaultHostApiIndex_ == -1 ) defaultHostApiIndex_ = 0; return result; error: TerminateHostApis(); return result; } /* FindHostApi() finds the index of the host api to which belongs and returns it. if is non-null, the host specific device index is returned in it. returns -1 if is out of range. */ static int FindHostApi( PaDeviceIndex device, int *hostSpecificDeviceIndex ) { int i=0; if( !PA_IS_INITIALISED_ ) return -1; if( device < 0 ) return -1; while( i < hostApisCount_ && device >= hostApis_[i]->info.deviceCount ) { device -= hostApis_[i]->info.deviceCount; ++i; } if( i >= hostApisCount_ ) return -1; if( hostSpecificDeviceIndex ) *hostSpecificDeviceIndex = device; return i; } static void AddOpenStream( PaStream* stream ) { ((PaUtilStreamRepresentation*)stream)->nextOpenStream = firstOpenStream_; firstOpenStream_ = (PaUtilStreamRepresentation*)stream; } static void RemoveOpenStream( PaStream* stream ) { PaUtilStreamRepresentation *previous = NULL; PaUtilStreamRepresentation *current = firstOpenStream_; while( current != NULL ) { if( ((PaStream*)current) == stream ) { if( previous == NULL ) { firstOpenStream_ = current->nextOpenStream; } else { previous->nextOpenStream = current->nextOpenStream; } return; } else { previous = current; current = current->nextOpenStream; } } } static void CloseOpenStreams( void ) { /* we call Pa_CloseStream() here to ensure that the same destruction logic is used for automatically closed streams */ while( firstOpenStream_ != NULL ) Pa_CloseStream( firstOpenStream_ ); } PaError Pa_Initialize( void ) { PaError result; PA_LOGAPI_ENTER( "Pa_Initialize" ); if( PA_IS_INITIALISED_ ) { ++initializationCount_; result = paNoError; } else { PA_VALIDATE_TYPE_SIZES; PA_VALIDATE_ENDIANNESS; PaUtil_InitializeClock(); PaUtil_ResetTraceMessages(); result = InitializeHostApis(); if( result == paNoError ) ++initializationCount_; } PA_LOGAPI_EXIT_PAERROR( "Pa_Initialize", result ); return result; } PaError Pa_Terminate( void ) { PaError result; PA_LOGAPI_ENTER( "Pa_Terminate" ); if( PA_IS_INITIALISED_ ) { if( --initializationCount_ == 0 ) { CloseOpenStreams(); TerminateHostApis(); PaUtil_DumpTraceMessages(); } result = paNoError; } else { result= paNotInitialized; } PA_LOGAPI_EXIT_PAERROR( "Pa_Terminate", result ); return result; } const PaHostErrorInfo* Pa_GetLastHostErrorInfo( void ) { return &lastHostErrorInfo_; } const char *Pa_GetErrorText( PaError errorCode ) { const char *result; switch( errorCode ) { case paNoError: result = "Success"; break; case paNotInitialized: result = "PortAudio not initialized"; break; /** @todo could catenate the last host error text to result in the case of paUnanticipatedHostError. see: http://www.portaudio.com/trac/ticket/114 */ case paUnanticipatedHostError: result = "Unanticipated host error"; break; case paInvalidChannelCount: result = "Invalid number of channels"; break; case paInvalidSampleRate: result = "Invalid sample rate"; break; case paInvalidDevice: result = "Invalid device"; break; case paInvalidFlag: result = "Invalid flag"; break; case paSampleFormatNotSupported: result = "Sample format not supported"; break; case paBadIODeviceCombination: result = "Illegal combination of I/O devices"; break; case paInsufficientMemory: result = "Insufficient memory"; break; case paBufferTooBig: result = "Buffer too big"; break; case paBufferTooSmall: result = "Buffer too small"; break; case paNullCallback: result = "No callback routine specified"; break; case paBadStreamPtr: result = "Invalid stream pointer"; break; case paTimedOut: result = "Wait timed out"; break; case paInternalError: result = "Internal PortAudio error"; break; case paDeviceUnavailable: result = "Device unavailable"; break; case paIncompatibleHostApiSpecificStreamInfo: result = "Incompatible host API specific stream info"; break; case paStreamIsStopped: result = "Stream is stopped"; break; case paStreamIsNotStopped: result = "Stream is not stopped"; break; case paInputOverflowed: result = "Input overflowed"; break; case paOutputUnderflowed: result = "Output underflowed"; break; case paHostApiNotFound: result = "Host API not found"; break; case paInvalidHostApi: result = "Invalid host API"; break; case paCanNotReadFromACallbackStream: result = "Can't read from a callback stream"; break; case paCanNotWriteToACallbackStream: result = "Can't write to a callback stream"; break; case paCanNotReadFromAnOutputOnlyStream: result = "Can't read from an output only stream"; break; case paCanNotWriteToAnInputOnlyStream: result = "Can't write to an input only stream"; break; case paIncompatibleStreamHostApi: result = "Incompatible stream host API"; break; case paBadBufferPtr: result = "Bad buffer pointer"; break; default: if( errorCode > 0 ) result = "Invalid error code (value greater than zero)"; else result = "Invalid error code"; break; } return result; } PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type ) { PaHostApiIndex result; int i; PA_LOGAPI_ENTER_PARAMS( "Pa_HostApiTypeIdToHostApiIndex" ); PA_LOGAPI(("\tPaHostApiTypeId type: %d\n", type )); if( !PA_IS_INITIALISED_ ) { result = paNotInitialized; } else { result = paHostApiNotFound; for( i=0; i < hostApisCount_; ++i ) { if( hostApis_[i]->info.type == type ) { result = i; break; } } } PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_HostApiTypeIdToHostApiIndex", "PaHostApiIndex: %d", result ); return result; } PaError PaUtil_GetHostApiRepresentation( struct PaUtilHostApiRepresentation **hostApi, PaHostApiTypeId type ) { PaError result; int i; if( !PA_IS_INITIALISED_ ) { result = paNotInitialized; } else { result = paHostApiNotFound; for( i=0; i < hostApisCount_; ++i ) { if( hostApis_[i]->info.type == type ) { *hostApi = hostApis_[i]; result = paNoError; break; } } } return result; } PaError PaUtil_DeviceIndexToHostApiDeviceIndex( PaDeviceIndex *hostApiDevice, PaDeviceIndex device, struct PaUtilHostApiRepresentation *hostApi ) { PaError result; PaDeviceIndex x; x = device - hostApi->privatePaFrontInfo.baseDeviceIndex; if( x < 0 || x >= hostApi->info.deviceCount ) { result = paInvalidDevice; } else { *hostApiDevice = x; result = paNoError; } return result; } PaHostApiIndex Pa_GetHostApiCount( void ) { int result; PA_LOGAPI_ENTER( "Pa_GetHostApiCount" ); if( !PA_IS_INITIALISED_ ) { result = paNotInitialized; } else { result = hostApisCount_; } PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetHostApiCount", "PaHostApiIndex: %d", result ); return result; } PaHostApiIndex Pa_GetDefaultHostApi( void ) { int result; PA_LOGAPI_ENTER( "Pa_GetDefaultHostApi" ); if( !PA_IS_INITIALISED_ ) { result = paNotInitialized; } else { result = defaultHostApiIndex_; /* internal consistency check: make sure that the default host api index is within range */ if( result < 0 || result >= hostApisCount_ ) { result = paInternalError; } } PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetDefaultHostApi", "PaHostApiIndex: %d", result ); return result; } const PaHostApiInfo* Pa_GetHostApiInfo( PaHostApiIndex hostApi ) { PaHostApiInfo *info; PA_LOGAPI_ENTER_PARAMS( "Pa_GetHostApiInfo" ); PA_LOGAPI(("\tPaHostApiIndex hostApi: %d\n", hostApi )); if( !PA_IS_INITIALISED_ ) { info = NULL; PA_LOGAPI(("Pa_GetHostApiInfo returned:\n" )); PA_LOGAPI(("\tPaHostApiInfo*: NULL [ PortAudio not initialized ]\n" )); } else if( hostApi < 0 || hostApi >= hostApisCount_ ) { info = NULL; PA_LOGAPI(("Pa_GetHostApiInfo returned:\n" )); PA_LOGAPI(("\tPaHostApiInfo*: NULL [ hostApi out of range ]\n" )); } else { info = &hostApis_[hostApi]->info; PA_LOGAPI(("Pa_GetHostApiInfo returned:\n" )); PA_LOGAPI(("\tPaHostApiInfo*: 0x%p\n", info )); PA_LOGAPI(("\t{\n" )); PA_LOGAPI(("\t\tint structVersion: %d\n", info->structVersion )); PA_LOGAPI(("\t\tPaHostApiTypeId type: %d\n", info->type )); PA_LOGAPI(("\t\tconst char *name: %s\n", info->name )); PA_LOGAPI(("\t}\n" )); } return info; } PaDeviceIndex Pa_HostApiDeviceIndexToDeviceIndex( PaHostApiIndex hostApi, int hostApiDeviceIndex ) { PaDeviceIndex result; PA_LOGAPI_ENTER_PARAMS( "Pa_HostApiDeviceIndexToPaDeviceIndex" ); PA_LOGAPI(("\tPaHostApiIndex hostApi: %d\n", hostApi )); PA_LOGAPI(("\tint hostApiDeviceIndex: %d\n", hostApiDeviceIndex )); if( !PA_IS_INITIALISED_ ) { result = paNotInitialized; } else { if( hostApi < 0 || hostApi >= hostApisCount_ ) { result = paInvalidHostApi; } else { if( hostApiDeviceIndex < 0 || hostApiDeviceIndex >= hostApis_[hostApi]->info.deviceCount ) { result = paInvalidDevice; } else { result = hostApis_[hostApi]->privatePaFrontInfo.baseDeviceIndex + hostApiDeviceIndex; } } } PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_HostApiDeviceIndexToPaDeviceIndex", "PaDeviceIndex: %d", result ); return result; } PaDeviceIndex Pa_GetDeviceCount( void ) { PaDeviceIndex result; PA_LOGAPI_ENTER( "Pa_GetDeviceCount" ); if( !PA_IS_INITIALISED_ ) { result = paNotInitialized; } else { result = deviceCount_; } PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetDeviceCount", "PaDeviceIndex: %d", result ); return result; } PaDeviceIndex Pa_GetDefaultInputDevice( void ) { PaHostApiIndex hostApi; PaDeviceIndex result; PA_LOGAPI_ENTER( "Pa_GetDefaultInputDevice" ); hostApi = Pa_GetDefaultHostApi(); if( hostApi < 0 ) { result = paNoDevice; } else { result = hostApis_[hostApi]->info.defaultInputDevice; } PA_LOGAPI_EXIT_T( "Pa_GetDefaultInputDevice", "PaDeviceIndex: %d", result ); return result; } PaDeviceIndex Pa_GetDefaultOutputDevice( void ) { PaHostApiIndex hostApi; PaDeviceIndex result; PA_LOGAPI_ENTER( "Pa_GetDefaultOutputDevice" ); hostApi = Pa_GetDefaultHostApi(); if( hostApi < 0 ) { result = paNoDevice; } else { result = hostApis_[hostApi]->info.defaultOutputDevice; } PA_LOGAPI_EXIT_T( "Pa_GetDefaultOutputDevice", "PaDeviceIndex: %d", result ); return result; } const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceIndex device ) { int hostSpecificDeviceIndex; int hostApiIndex = FindHostApi( device, &hostSpecificDeviceIndex ); PaDeviceInfo *result; PA_LOGAPI_ENTER_PARAMS( "Pa_GetDeviceInfo" ); PA_LOGAPI(("\tPaDeviceIndex device: %d\n", device )); if( hostApiIndex < 0 ) { result = NULL; PA_LOGAPI(("Pa_GetDeviceInfo returned:\n" )); PA_LOGAPI(("\tPaDeviceInfo* NULL [ invalid device index ]\n" )); } else { result = hostApis_[hostApiIndex]->deviceInfos[ hostSpecificDeviceIndex ]; PA_LOGAPI(("Pa_GetDeviceInfo returned:\n" )); PA_LOGAPI(("\tPaDeviceInfo*: 0x%p:\n", result )); PA_LOGAPI(("\t{\n" )); PA_LOGAPI(("\t\tint structVersion: %d\n", result->structVersion )); PA_LOGAPI(("\t\tconst char *name: %s\n", result->name )); PA_LOGAPI(("\t\tPaHostApiIndex hostApi: %d\n", result->hostApi )); PA_LOGAPI(("\t\tint maxInputChannels: %d\n", result->maxInputChannels )); PA_LOGAPI(("\t\tint maxOutputChannels: %d\n", result->maxOutputChannels )); PA_LOGAPI(("\t}\n" )); } return result; } /* SampleFormatIsValid() returns 1 if sampleFormat is a sample format defined in portaudio.h, or 0 otherwise. */ static int SampleFormatIsValid( PaSampleFormat format ) { switch( format & ~paNonInterleaved ) { case paFloat32: return 1; case paInt16: return 1; case paInt32: return 1; case paInt24: return 1; case paInt8: return 1; case paUInt8: return 1; case paCustomFormat: return 1; default: return 0; } } /* NOTE: make sure this validation list is kept syncronised with the one in pa_hostapi.h ValidateOpenStreamParameters() checks that parameters to Pa_OpenStream() conform to the expected values as described below. This function is also designed to be used with the proposed Pa_IsFormatSupported() function. There are basically two types of validation that could be performed: Generic conformance validation, and device capability mismatch validation. This function performs only generic conformance validation. Validation that would require knowledge of device capabilities is not performed because of potentially complex relationships between combinations of parameters - for example, even if the sampleRate seems ok, it might not be for a duplex stream - we have no way of checking this in an API-neutral way, so we don't try. On success the function returns PaNoError and fills in hostApi, hostApiInputDeviceID, and hostApiOutputDeviceID fields. On failure the function returns an error code indicating the first encountered parameter error. If ValidateOpenStreamParameters() returns paNoError, the following assertions are guaranteed to be true. - at least one of inputParameters & outputParmeters is valid (not NULL) - if inputParameters & outputParameters are both valid, that inputParameters->device & outputParameters->device both use the same host api PaDeviceIndex inputParameters->device - is within range (0 to Pa_GetDeviceCount-1) Or: - is paUseHostApiSpecificDeviceSpecification and inputParameters->hostApiSpecificStreamInfo is non-NULL and refers to a valid host api int inputParameters->channelCount - if inputParameters->device is not paUseHostApiSpecificDeviceSpecification, channelCount is > 0 - upper bound is NOT validated against device capabilities PaSampleFormat inputParameters->sampleFormat - is one of the sample formats defined in portaudio.h void *inputParameters->hostApiSpecificStreamInfo - if supplied its hostApi field matches the input device's host Api PaDeviceIndex outputParmeters->device - is within range (0 to Pa_GetDeviceCount-1) int outputParmeters->channelCount - if inputDevice is valid, channelCount is > 0 - upper bound is NOT validated against device capabilities PaSampleFormat outputParmeters->sampleFormat - is one of the sample formats defined in portaudio.h void *outputParmeters->hostApiSpecificStreamInfo - if supplied its hostApi field matches the output device's host Api double sampleRate - is not an 'absurd' rate (less than 1000. or greater than 384000.) - sampleRate is NOT validated against device capabilities PaStreamFlags streamFlags - unused platform neutral flags are zero - paNeverDropInput is only used for full-duplex callback streams with variable buffer size (paFramesPerBufferUnspecified) */ static PaError ValidateOpenStreamParameters( const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, PaUtilHostApiRepresentation **hostApi, PaDeviceIndex *hostApiInputDevice, PaDeviceIndex *hostApiOutputDevice ) { int inputHostApiIndex = -1, /* Surpress uninitialised var warnings: compiler does */ outputHostApiIndex = -1; /* not see that if inputParameters and outputParame- */ /* ters are both nonzero, these indices are set. */ if( (inputParameters == NULL) && (outputParameters == NULL) ) { return paInvalidDevice; /** @todo should be a new error code "invalid device parameters" or something */ } else { if( inputParameters == NULL ) { *hostApiInputDevice = paNoDevice; } else if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) { if( inputParameters->hostApiSpecificStreamInfo ) { inputHostApiIndex = Pa_HostApiTypeIdToHostApiIndex( ((PaUtilHostApiSpecificStreamInfoHeader*)inputParameters->hostApiSpecificStreamInfo)->hostApiType ); if( inputHostApiIndex != -1 ) { *hostApiInputDevice = paUseHostApiSpecificDeviceSpecification; *hostApi = hostApis_[inputHostApiIndex]; } else { return paInvalidDevice; } } else { return paInvalidDevice; } } else { if( inputParameters->device < 0 || inputParameters->device >= deviceCount_ ) return paInvalidDevice; inputHostApiIndex = FindHostApi( inputParameters->device, hostApiInputDevice ); if( inputHostApiIndex < 0 ) return paInternalError; *hostApi = hostApis_[inputHostApiIndex]; if( inputParameters->channelCount <= 0 ) return paInvalidChannelCount; if( !SampleFormatIsValid( inputParameters->sampleFormat ) ) return paSampleFormatNotSupported; if( inputParameters->hostApiSpecificStreamInfo != NULL ) { if( ((PaUtilHostApiSpecificStreamInfoHeader*)inputParameters->hostApiSpecificStreamInfo)->hostApiType != (*hostApi)->info.type ) return paIncompatibleHostApiSpecificStreamInfo; } } if( outputParameters == NULL ) { *hostApiOutputDevice = paNoDevice; } else if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) { if( outputParameters->hostApiSpecificStreamInfo ) { outputHostApiIndex = Pa_HostApiTypeIdToHostApiIndex( ((PaUtilHostApiSpecificStreamInfoHeader*)outputParameters->hostApiSpecificStreamInfo)->hostApiType ); if( outputHostApiIndex != -1 ) { *hostApiOutputDevice = paUseHostApiSpecificDeviceSpecification; *hostApi = hostApis_[outputHostApiIndex]; } else { return paInvalidDevice; } } else { return paInvalidDevice; } } else { if( outputParameters->device < 0 || outputParameters->device >= deviceCount_ ) return paInvalidDevice; outputHostApiIndex = FindHostApi( outputParameters->device, hostApiOutputDevice ); if( outputHostApiIndex < 0 ) return paInternalError; *hostApi = hostApis_[outputHostApiIndex]; if( outputParameters->channelCount <= 0 ) return paInvalidChannelCount; if( !SampleFormatIsValid( outputParameters->sampleFormat ) ) return paSampleFormatNotSupported; if( outputParameters->hostApiSpecificStreamInfo != NULL ) { if( ((PaUtilHostApiSpecificStreamInfoHeader*)outputParameters->hostApiSpecificStreamInfo)->hostApiType != (*hostApi)->info.type ) return paIncompatibleHostApiSpecificStreamInfo; } } if( (inputParameters != NULL) && (outputParameters != NULL) ) { /* ensure that both devices use the same API */ if( inputHostApiIndex != outputHostApiIndex ) return paBadIODeviceCombination; } } /* Check for absurd sample rates. */ if( (sampleRate < 1000.0) || (sampleRate > 384000.0) ) return paInvalidSampleRate; if( ((streamFlags & ~paPlatformSpecificFlags) & ~(paClipOff | paDitherOff | paNeverDropInput | paPrimeOutputBuffersUsingStreamCallback ) ) != 0 ) return paInvalidFlag; if( streamFlags & paNeverDropInput ) { /* must be a callback stream */ if( !streamCallback ) return paInvalidFlag; /* must be a full duplex stream */ if( (inputParameters == NULL) || (outputParameters == NULL) ) return paInvalidFlag; /* must use paFramesPerBufferUnspecified */ if( framesPerBuffer != paFramesPerBufferUnspecified ) return paInvalidFlag; } return paNoError; } PaError Pa_IsFormatSupported( const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { PaError result; PaUtilHostApiRepresentation *hostApi = 0; PaDeviceIndex hostApiInputDevice = paNoDevice, hostApiOutputDevice = paNoDevice; PaStreamParameters hostApiInputParameters, hostApiOutputParameters; PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr; #ifdef PA_LOG_API_CALLS PA_LOGAPI_ENTER_PARAMS( "Pa_IsFormatSupported" ); if( inputParameters == NULL ){ PA_LOGAPI(("\tPaStreamParameters *inputParameters: NULL\n" )); }else{ PA_LOGAPI(("\tPaStreamParameters *inputParameters: 0x%p\n", inputParameters )); PA_LOGAPI(("\tPaDeviceIndex inputParameters->device: %d\n", inputParameters->device )); PA_LOGAPI(("\tint inputParameters->channelCount: %d\n", inputParameters->channelCount )); PA_LOGAPI(("\tPaSampleFormat inputParameters->sampleFormat: %d\n", inputParameters->sampleFormat )); PA_LOGAPI(("\tPaTime inputParameters->suggestedLatency: %f\n", inputParameters->suggestedLatency )); PA_LOGAPI(("\tvoid *inputParameters->hostApiSpecificStreamInfo: 0x%p\n", inputParameters->hostApiSpecificStreamInfo )); } if( outputParameters == NULL ){ PA_LOGAPI(("\tPaStreamParameters *outputParameters: NULL\n" )); }else{ PA_LOGAPI(("\tPaStreamParameters *outputParameters: 0x%p\n", outputParameters )); PA_LOGAPI(("\tPaDeviceIndex outputParameters->device: %d\n", outputParameters->device )); PA_LOGAPI(("\tint outputParameters->channelCount: %d\n", outputParameters->channelCount )); PA_LOGAPI(("\tPaSampleFormat outputParameters->sampleFormat: %d\n", outputParameters->sampleFormat )); PA_LOGAPI(("\tPaTime outputParameters->suggestedLatency: %f\n", outputParameters->suggestedLatency )); PA_LOGAPI(("\tvoid *outputParameters->hostApiSpecificStreamInfo: 0x%p\n", outputParameters->hostApiSpecificStreamInfo )); } PA_LOGAPI(("\tdouble sampleRate: %g\n", sampleRate )); #endif if( !PA_IS_INITIALISED_ ) { result = paNotInitialized; PA_LOGAPI_EXIT_PAERROR( "Pa_IsFormatSupported", result ); return result; } result = ValidateOpenStreamParameters( inputParameters, outputParameters, sampleRate, 0, paNoFlag, 0, &hostApi, &hostApiInputDevice, &hostApiOutputDevice ); if( result != paNoError ) { PA_LOGAPI_EXIT_PAERROR( "Pa_IsFormatSupported", result ); return result; } if( inputParameters ) { hostApiInputParameters.device = hostApiInputDevice; hostApiInputParameters.channelCount = inputParameters->channelCount; hostApiInputParameters.sampleFormat = inputParameters->sampleFormat; hostApiInputParameters.suggestedLatency = inputParameters->suggestedLatency; hostApiInputParameters.hostApiSpecificStreamInfo = inputParameters->hostApiSpecificStreamInfo; hostApiInputParametersPtr = &hostApiInputParameters; } else { hostApiInputParametersPtr = NULL; } if( outputParameters ) { hostApiOutputParameters.device = hostApiOutputDevice; hostApiOutputParameters.channelCount = outputParameters->channelCount; hostApiOutputParameters.sampleFormat = outputParameters->sampleFormat; hostApiOutputParameters.suggestedLatency = outputParameters->suggestedLatency; hostApiOutputParameters.hostApiSpecificStreamInfo = outputParameters->hostApiSpecificStreamInfo; hostApiOutputParametersPtr = &hostApiOutputParameters; } else { hostApiOutputParametersPtr = NULL; } result = hostApi->IsFormatSupported( hostApi, hostApiInputParametersPtr, hostApiOutputParametersPtr, sampleRate ); #ifdef PA_LOG_API_CALLS PA_LOGAPI(("Pa_OpenStream returned:\n" )); if( result == paFormatIsSupported ) PA_LOGAPI(("\tPaError: 0 [ paFormatIsSupported ]\n" )); else PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); #endif return result; } PaError Pa_OpenStream( PaStream** stream, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ) { PaError result; PaUtilHostApiRepresentation *hostApi = 0; PaDeviceIndex hostApiInputDevice = paNoDevice, hostApiOutputDevice = paNoDevice; PaStreamParameters hostApiInputParameters, hostApiOutputParameters; PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr; #ifdef PA_LOG_API_CALLS PA_LOGAPI_ENTER_PARAMS( "Pa_OpenStream" ); PA_LOGAPI(("\tPaStream** stream: 0x%p\n", stream )); if( inputParameters == NULL ){ PA_LOGAPI(("\tPaStreamParameters *inputParameters: NULL\n" )); }else{ PA_LOGAPI(("\tPaStreamParameters *inputParameters: 0x%p\n", inputParameters )); PA_LOGAPI(("\tPaDeviceIndex inputParameters->device: %d\n", inputParameters->device )); PA_LOGAPI(("\tint inputParameters->channelCount: %d\n", inputParameters->channelCount )); PA_LOGAPI(("\tPaSampleFormat inputParameters->sampleFormat: %d\n", inputParameters->sampleFormat )); PA_LOGAPI(("\tPaTime inputParameters->suggestedLatency: %f\n", inputParameters->suggestedLatency )); PA_LOGAPI(("\tvoid *inputParameters->hostApiSpecificStreamInfo: 0x%p\n", inputParameters->hostApiSpecificStreamInfo )); } if( outputParameters == NULL ){ PA_LOGAPI(("\tPaStreamParameters *outputParameters: NULL\n" )); }else{ PA_LOGAPI(("\tPaStreamParameters *outputParameters: 0x%p\n", outputParameters )); PA_LOGAPI(("\tPaDeviceIndex outputParameters->device: %d\n", outputParameters->device )); PA_LOGAPI(("\tint outputParameters->channelCount: %d\n", outputParameters->channelCount )); PA_LOGAPI(("\tPaSampleFormat outputParameters->sampleFormat: %d\n", outputParameters->sampleFormat )); PA_LOGAPI(("\tPaTime outputParameters->suggestedLatency: %f\n", outputParameters->suggestedLatency )); PA_LOGAPI(("\tvoid *outputParameters->hostApiSpecificStreamInfo: 0x%p\n", outputParameters->hostApiSpecificStreamInfo )); } PA_LOGAPI(("\tdouble sampleRate: %g\n", sampleRate )); PA_LOGAPI(("\tunsigned long framesPerBuffer: %d\n", framesPerBuffer )); PA_LOGAPI(("\tPaStreamFlags streamFlags: 0x%x\n", streamFlags )); PA_LOGAPI(("\tPaStreamCallback *streamCallback: 0x%p\n", streamCallback )); PA_LOGAPI(("\tvoid *userData: 0x%p\n", userData )); #endif if( !PA_IS_INITIALISED_ ) { result = paNotInitialized; PA_LOGAPI(("Pa_OpenStream returned:\n" )); PA_LOGAPI(("\t*(PaStream** stream): undefined\n" )); PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); return result; } /* Check for parameter errors. NOTE: make sure this validation list is kept syncronised with the one in pa_hostapi.h */ if( stream == NULL ) { result = paBadStreamPtr; PA_LOGAPI(("Pa_OpenStream returned:\n" )); PA_LOGAPI(("\t*(PaStream** stream): undefined\n" )); PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); return result; } result = ValidateOpenStreamParameters( inputParameters, outputParameters, sampleRate, framesPerBuffer, streamFlags, streamCallback, &hostApi, &hostApiInputDevice, &hostApiOutputDevice ); if( result != paNoError ) { PA_LOGAPI(("Pa_OpenStream returned:\n" )); PA_LOGAPI(("\t*(PaStream** stream): undefined\n" )); PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); return result; } if( inputParameters ) { hostApiInputParameters.device = hostApiInputDevice; hostApiInputParameters.channelCount = inputParameters->channelCount; hostApiInputParameters.sampleFormat = inputParameters->sampleFormat; hostApiInputParameters.suggestedLatency = inputParameters->suggestedLatency; hostApiInputParameters.hostApiSpecificStreamInfo = inputParameters->hostApiSpecificStreamInfo; hostApiInputParametersPtr = &hostApiInputParameters; } else { hostApiInputParametersPtr = NULL; } if( outputParameters ) { hostApiOutputParameters.device = hostApiOutputDevice; hostApiOutputParameters.channelCount = outputParameters->channelCount; hostApiOutputParameters.sampleFormat = outputParameters->sampleFormat; hostApiOutputParameters.suggestedLatency = outputParameters->suggestedLatency; hostApiOutputParameters.hostApiSpecificStreamInfo = outputParameters->hostApiSpecificStreamInfo; hostApiOutputParametersPtr = &hostApiOutputParameters; } else { hostApiOutputParametersPtr = NULL; } result = hostApi->OpenStream( hostApi, stream, hostApiInputParametersPtr, hostApiOutputParametersPtr, sampleRate, framesPerBuffer, streamFlags, streamCallback, userData ); if( result == paNoError ) AddOpenStream( *stream ); PA_LOGAPI(("Pa_OpenStream returned:\n" )); PA_LOGAPI(("\t*(PaStream** stream): 0x%p\n", *stream )); PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); return result; } PaError Pa_OpenDefaultStream( PaStream** stream, int inputChannelCount, int outputChannelCount, PaSampleFormat sampleFormat, double sampleRate, unsigned long framesPerBuffer, PaStreamCallback *streamCallback, void *userData ) { PaError result; PaStreamParameters hostApiInputParameters, hostApiOutputParameters; PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr; PA_LOGAPI_ENTER_PARAMS( "Pa_OpenDefaultStream" ); PA_LOGAPI(("\tPaStream** stream: 0x%p\n", stream )); PA_LOGAPI(("\tint inputChannelCount: %d\n", inputChannelCount )); PA_LOGAPI(("\tint outputChannelCount: %d\n", outputChannelCount )); PA_LOGAPI(("\tPaSampleFormat sampleFormat: %d\n", sampleFormat )); PA_LOGAPI(("\tdouble sampleRate: %g\n", sampleRate )); PA_LOGAPI(("\tunsigned long framesPerBuffer: %d\n", framesPerBuffer )); PA_LOGAPI(("\tPaStreamCallback *streamCallback: 0x%p\n", streamCallback )); PA_LOGAPI(("\tvoid *userData: 0x%p\n", userData )); if( inputChannelCount > 0 ) { hostApiInputParameters.device = Pa_GetDefaultInputDevice(); if( hostApiInputParameters.device == paNoDevice ) return paDeviceUnavailable; hostApiInputParameters.channelCount = inputChannelCount; hostApiInputParameters.sampleFormat = sampleFormat; /* defaultHighInputLatency is used below instead of defaultLowInputLatency because it is more important for the default stream to work reliably than it is for it to work with the lowest latency. */ hostApiInputParameters.suggestedLatency = Pa_GetDeviceInfo( hostApiInputParameters.device )->defaultHighInputLatency; hostApiInputParameters.hostApiSpecificStreamInfo = NULL; hostApiInputParametersPtr = &hostApiInputParameters; } else { hostApiInputParametersPtr = NULL; } if( outputChannelCount > 0 ) { hostApiOutputParameters.device = Pa_GetDefaultOutputDevice(); if( hostApiOutputParameters.device == paNoDevice ) return paDeviceUnavailable; hostApiOutputParameters.channelCount = outputChannelCount; hostApiOutputParameters.sampleFormat = sampleFormat; /* defaultHighOutputLatency is used below instead of defaultLowOutputLatency because it is more important for the default stream to work reliably than it is for it to work with the lowest latency. */ hostApiOutputParameters.suggestedLatency = Pa_GetDeviceInfo( hostApiOutputParameters.device )->defaultHighOutputLatency; hostApiOutputParameters.hostApiSpecificStreamInfo = NULL; hostApiOutputParametersPtr = &hostApiOutputParameters; } else { hostApiOutputParametersPtr = NULL; } result = Pa_OpenStream( stream, hostApiInputParametersPtr, hostApiOutputParametersPtr, sampleRate, framesPerBuffer, paNoFlag, streamCallback, userData ); PA_LOGAPI(("Pa_OpenDefaultStream returned:\n" )); PA_LOGAPI(("\t*(PaStream** stream): 0x%p", *stream )); PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); return result; } PaError PaUtil_ValidateStreamPointer( PaStream* stream ) { if( !PA_IS_INITIALISED_ ) return paNotInitialized; if( stream == NULL ) return paBadStreamPtr; if( ((PaUtilStreamRepresentation*)stream)->magic != PA_STREAM_MAGIC ) return paBadStreamPtr; return paNoError; } PaError Pa_CloseStream( PaStream* stream ) { PaUtilStreamInterface *interface; PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_CloseStream" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); /* always remove the open stream from our list, even if this function eventually returns an error. Otherwise CloseOpenStreams() will get stuck in an infinite loop */ RemoveOpenStream( stream ); /* be sure to call this _before_ closing the stream */ if( result == paNoError ) { interface = PA_STREAM_INTERFACE(stream); /* abort the stream if it isn't stopped */ result = interface->IsStopped( stream ); if( result == 1 ) result = paNoError; else if( result == 0 ) result = interface->Abort( stream ); if( result == paNoError ) /** @todo REVIEW: shouldn't we close anyway? see: http://www.portaudio.com/trac/ticket/115 */ result = interface->Close( stream ); } PA_LOGAPI_EXIT_PAERROR( "Pa_CloseStream", result ); return result; } PaError Pa_SetStreamFinishedCallback( PaStream *stream, PaStreamFinishedCallback* streamFinishedCallback ) { PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_SetStreamFinishedCallback" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); PA_LOGAPI(("\tPaStreamFinishedCallback* streamFinishedCallback: 0x%p\n", streamFinishedCallback )); if( result == paNoError ) { result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); if( result == 0 ) { result = paStreamIsNotStopped ; } if( result == 1 ) { PA_STREAM_REP( stream )->streamFinishedCallback = streamFinishedCallback; result = paNoError; } } PA_LOGAPI_EXIT_PAERROR( "Pa_SetStreamFinishedCallback", result ); return result; } PaError Pa_StartStream( PaStream *stream ) { PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_StartStream" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( result == paNoError ) { result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); if( result == 0 ) { result = paStreamIsNotStopped ; } else if( result == 1 ) { result = PA_STREAM_INTERFACE(stream)->Start( stream ); } } PA_LOGAPI_EXIT_PAERROR( "Pa_StartStream", result ); return result; } PaError Pa_StopStream( PaStream *stream ) { PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_StopStream" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( result == paNoError ) { result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); if( result == 0 ) { result = PA_STREAM_INTERFACE(stream)->Stop( stream ); } else if( result == 1 ) { result = paStreamIsStopped; } } PA_LOGAPI_EXIT_PAERROR( "Pa_StopStream", result ); return result; } PaError Pa_AbortStream( PaStream *stream ) { PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_AbortStream" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( result == paNoError ) { result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); if( result == 0 ) { result = PA_STREAM_INTERFACE(stream)->Abort( stream ); } else if( result == 1 ) { result = paStreamIsStopped; } } PA_LOGAPI_EXIT_PAERROR( "Pa_AbortStream", result ); return result; } PaError Pa_IsStreamStopped( PaStream *stream ) { PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_IsStreamStopped" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( result == paNoError ) result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); PA_LOGAPI_EXIT_PAERROR( "Pa_IsStreamStopped", result ); return result; } PaError Pa_IsStreamActive( PaStream *stream ) { PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_IsStreamActive" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( result == paNoError ) result = PA_STREAM_INTERFACE(stream)->IsActive( stream ); PA_LOGAPI_EXIT_PAERROR( "Pa_IsStreamActive", result ); return result; } const PaStreamInfo* Pa_GetStreamInfo( PaStream *stream ) { PaError error = PaUtil_ValidateStreamPointer( stream ); const PaStreamInfo *result; PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamInfo" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( error != paNoError ) { result = 0; PA_LOGAPI(("Pa_GetStreamInfo returned:\n" )); PA_LOGAPI(("\tconst PaStreamInfo*: 0 [PaError error:%d ( %s )]\n", error, Pa_GetErrorText( error ) )); } else { result = &PA_STREAM_REP( stream )->streamInfo; PA_LOGAPI(("Pa_GetStreamInfo returned:\n" )); PA_LOGAPI(("\tconst PaStreamInfo*: 0x%p:\n", result )); PA_LOGAPI(("\t{" )); PA_LOGAPI(("\t\tint structVersion: %d\n", result->structVersion )); PA_LOGAPI(("\t\tPaTime inputLatency: %f\n", result->inputLatency )); PA_LOGAPI(("\t\tPaTime outputLatency: %f\n", result->outputLatency )); PA_LOGAPI(("\t\tdouble sampleRate: %f\n", result->sampleRate )); PA_LOGAPI(("\t}\n" )); } return result; } PaTime Pa_GetStreamTime( PaStream *stream ) { PaError error = PaUtil_ValidateStreamPointer( stream ); PaTime result; PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamTime" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( error != paNoError ) { result = 0; PA_LOGAPI(("Pa_GetStreamTime returned:\n" )); PA_LOGAPI(("\tPaTime: 0 [PaError error:%d ( %s )]\n", result, error, Pa_GetErrorText( error ) )); } else { result = PA_STREAM_INTERFACE(stream)->GetTime( stream ); PA_LOGAPI(("Pa_GetStreamTime returned:\n" )); PA_LOGAPI(("\tPaTime: %g\n", result )); } return result; } double Pa_GetStreamCpuLoad( PaStream* stream ) { PaError error = PaUtil_ValidateStreamPointer( stream ); double result; PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamCpuLoad" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( error != paNoError ) { result = 0.0; PA_LOGAPI(("Pa_GetStreamCpuLoad returned:\n" )); PA_LOGAPI(("\tdouble: 0.0 [PaError error: %d ( %s )]\n", error, Pa_GetErrorText( error ) )); } else { result = PA_STREAM_INTERFACE(stream)->GetCpuLoad( stream ); PA_LOGAPI(("Pa_GetStreamCpuLoad returned:\n" )); PA_LOGAPI(("\tdouble: %g\n", result )); } return result; } PaError Pa_ReadStream( PaStream* stream, void *buffer, unsigned long frames ) { PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_ReadStream" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( result == paNoError ) { if( frames == 0 ) { /* @todo Should we not allow the implementation to signal any overflow condition? see: http://www.portaudio.com/trac/ticket/116*/ result = paNoError; } else if( buffer == 0 ) { result = paBadBufferPtr; } else { result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); if( result == 0 ) { result = PA_STREAM_INTERFACE(stream)->Read( stream, buffer, frames ); } else if( result == 1 ) { result = paStreamIsStopped; } } } PA_LOGAPI_EXIT_PAERROR( "Pa_ReadStream", result ); return result; } PaError Pa_WriteStream( PaStream* stream, const void *buffer, unsigned long frames ) { PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_WriteStream" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( result == paNoError ) { if( frames == 0 ) { /* @todo Should we not allow the implementation to signal any underflow condition? see: http://www.portaudio.com/trac/ticket/116*/ result = paNoError; } else if( buffer == 0 ) { result = paBadBufferPtr; } else { result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); if( result == 0 ) { result = PA_STREAM_INTERFACE(stream)->Write( stream, buffer, frames ); } else if( result == 1 ) { result = paStreamIsStopped; } } } PA_LOGAPI_EXIT_PAERROR( "Pa_WriteStream", result ); return result; } signed long Pa_GetStreamReadAvailable( PaStream* stream ) { PaError error = PaUtil_ValidateStreamPointer( stream ); signed long result; PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamReadAvailable" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( error != paNoError ) { result = 0; PA_LOGAPI(("Pa_GetStreamReadAvailable returned:\n" )); PA_LOGAPI(("\tunsigned long: 0 [ PaError error: %d ( %s ) ]\n", error, Pa_GetErrorText( error ) )); } else { result = PA_STREAM_INTERFACE(stream)->GetReadAvailable( stream ); PA_LOGAPI(("Pa_GetStreamReadAvailable returned:\n" )); PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); } return result; } signed long Pa_GetStreamWriteAvailable( PaStream* stream ) { PaError error = PaUtil_ValidateStreamPointer( stream ); signed long result; PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamWriteAvailable" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( error != paNoError ) { result = 0; PA_LOGAPI(("Pa_GetStreamWriteAvailable returned:\n" )); PA_LOGAPI(("\tunsigned long: 0 [ PaError error: %d ( %s ) ]\n", error, Pa_GetErrorText( error ) )); } else { result = PA_STREAM_INTERFACE(stream)->GetWriteAvailable( stream ); PA_LOGAPI(("Pa_GetStreamWriteAvailable returned:\n" )); PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); } return result; } PaError Pa_GetSampleSize( PaSampleFormat format ) { int result; PA_LOGAPI_ENTER_PARAMS( "Pa_GetSampleSize" ); PA_LOGAPI(("\tPaSampleFormat format: %d\n", format )); switch( format & ~paNonInterleaved ) { case paUInt8: case paInt8: result = 1; break; case paInt16: result = 2; break; case paInt24: result = 3; break; case paFloat32: case paInt32: result = 4; break; default: result = paSampleFormatNotSupported; break; } PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetSampleSize", "int: %d", result ); return (PaError) result; } praat-6.0.04/external/portaudio/pa_hostapi.h000066400000000000000000000320711261542461700210530ustar00rootroot00000000000000#ifndef PA_HOSTAPI_H #define PA_HOSTAPI_H /* * $Id: pa_hostapi.h 1880 2012-12-04 18:39:48Z rbencina $ * Portable Audio I/O Library * host api representation * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2008 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Interfaces and representation structures used by pa_front.c to manage and communicate with host API implementations. */ #include "portaudio.h" /** The PA_NO_* host API macros are now deprecated in favor of PA_USE_* macros. PA_USE_* indicates whether a particular host API will be initialized by PortAudio. An undefined or 0 value indicates that the host API will not be used. A value of 1 indicates that the host API will be used. PA_USE_* macros should be left undefined or defined to either 0 or 1. The code below ensures that PA_USE_* macros are always defined and have value 0 or 1. Undefined symbols are defaulted to 0. Symbols that are neither 0 nor 1 are defaulted to 1. */ #ifndef PA_USE_SKELETON #define PA_USE_SKELETON 0 #elif (PA_USE_SKELETON != 0) && (PA_USE_SKELETON != 1) #undef PA_USE_SKELETON #define PA_USE_SKELETON 1 #endif #if defined(PA_NO_ASIO) || defined(PA_NO_DS) || defined(PA_NO_WMME) || defined(PA_NO_WASAPI) || defined(PA_NO_WDMKS) #error "Portaudio: PA_NO_ is no longer supported, please remove definition and use PA_USE_ instead" #endif #ifndef PA_USE_ASIO #define PA_USE_ASIO 0 #elif (PA_USE_ASIO != 0) && (PA_USE_ASIO != 1) #undef PA_USE_ASIO #define PA_USE_ASIO 1 #endif #ifndef PA_USE_DS #define PA_USE_DS 0 #elif (PA_USE_DS != 0) && (PA_USE_DS != 1) #undef PA_USE_DS #define PA_USE_DS 1 #endif #ifndef PA_USE_WMME #define PA_USE_WMME 0 #elif (PA_USE_WMME != 0) && (PA_USE_WMME != 1) #undef PA_USE_WMME #define PA_USE_WMME 1 #endif #ifndef PA_USE_WASAPI #define PA_USE_WASAPI 0 #elif (PA_USE_WASAPI != 0) && (PA_USE_WASAPI != 1) #undef PA_USE_WASAPI #define PA_USE_WASAPI 1 #endif #ifndef PA_USE_WDMKS #define PA_USE_WDMKS 0 #elif (PA_USE_WDMKS != 0) && (PA_USE_WDMKS != 1) #undef PA_USE_WDMKS #define PA_USE_WDMKS 1 #endif /* Set default values for Unix based APIs. */ #if defined(PA_NO_OSS) || defined(PA_NO_ALSA) || defined(PA_NO_JACK) || defined(PA_NO_COREAUDIO) || defined(PA_NO_SGI) || defined(PA_NO_ASIHPI) #error "Portaudio: PA_NO_ is no longer supported, please remove definition and use PA_USE_ instead" #endif #ifndef PA_USE_OSS #define PA_USE_OSS 0 #elif (PA_USE_OSS != 0) && (PA_USE_OSS != 1) #undef PA_USE_OSS #define PA_USE_OSS 1 #endif #ifndef PA_USE_ALSA #define PA_USE_ALSA 0 #elif (PA_USE_ALSA != 0) && (PA_USE_ALSA != 1) #undef PA_USE_ALSA #define PA_USE_ALSA 1 #endif #ifndef PA_USE_JACK #define PA_USE_JACK 0 #elif (PA_USE_JACK != 0) && (PA_USE_JACK != 1) #undef PA_USE_JACK #define PA_USE_JACK 1 #endif #ifndef PA_USE_SGI #define PA_USE_SGI 0 #elif (PA_USE_SGI != 0) && (PA_USE_SGI != 1) #undef PA_USE_SGI #define PA_USE_SGI 1 #endif #ifndef PA_USE_COREAUDIO #define PA_USE_COREAUDIO 0 #elif (PA_USE_COREAUDIO != 0) && (PA_USE_COREAUDIO != 1) #undef PA_USE_COREAUDIO #define PA_USE_COREAUDIO 1 #endif #ifndef PA_USE_ASIHPI #define PA_USE_ASIHPI 0 #elif (PA_USE_ASIHPI != 0) && (PA_USE_ASIHPI != 1) #undef PA_USE_ASIHPI #define PA_USE_ASIHPI 1 #endif #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** **FOR THE USE OF pa_front.c ONLY** Do NOT use fields in this structure, they my change at any time. Use functions defined in pa_util.h if you think you need functionality which can be derived from here. */ typedef struct PaUtilPrivatePaFrontHostApiInfo { unsigned long baseDeviceIndex; }PaUtilPrivatePaFrontHostApiInfo; /** The common header for all data structures whose pointers are passed through the hostApiSpecificStreamInfo field of the PaStreamParameters structure. Note that in order to keep the public PortAudio interface clean, this structure is not used explicitly when declaring hostApiSpecificStreamInfo data structures. However, some code in pa_front depends on the first 3 members being equivalent with this structure. @see PaStreamParameters */ typedef struct PaUtilHostApiSpecificStreamInfoHeader { unsigned long size; /**< size of whole structure including this header */ PaHostApiTypeId hostApiType; /**< host API for which this data is intended */ unsigned long version; /**< structure version */ } PaUtilHostApiSpecificStreamInfoHeader; /** A structure representing the interface to a host API. Contains both concrete data and pointers to functions which implement the interface. */ typedef struct PaUtilHostApiRepresentation { PaUtilPrivatePaFrontHostApiInfo privatePaFrontInfo; /** The host api implementation should populate the info field. In the case of info.defaultInputDevice and info.defaultOutputDevice the values stored should be 0 based indices within the host api's own device index range (0 to deviceCount). These values will be converted to global device indices by pa_front after PaUtilHostApiInitializer() returns. */ PaHostApiInfo info; PaDeviceInfo** deviceInfos; /** (*Terminate)() is guaranteed to be called with a valid parameter, which was previously returned from the same implementation's initializer. */ void (*Terminate)( struct PaUtilHostApiRepresentation *hostApi ); /** The inputParameters and outputParameters pointers should not be saved as they will not remain valid after OpenStream is called. The following guarantees are made about parameters to (*OpenStream)(): [NOTE: the following list up to *END PA FRONT VALIDATIONS* should be kept in sync with the one for ValidateOpenStreamParameters and Pa_OpenStream in pa_front.c] PaHostApiRepresentation *hostApi - is valid for this implementation PaStream** stream - is non-null - at least one of inputParameters & outputParmeters is valid (not NULL) - if inputParameters & outputParmeters are both valid, that inputParameters->device & outputParmeters->device both use the same host api PaDeviceIndex inputParameters->device - is within range (0 to Pa_CountDevices-1) Or: - is paUseHostApiSpecificDeviceSpecification and inputParameters->hostApiSpecificStreamInfo is non-NULL and refers to a valid host api int inputParameters->numChannels - if inputParameters->device is not paUseHostApiSpecificDeviceSpecification, numInputChannels is > 0 - upper bound is NOT validated against device capabilities PaSampleFormat inputParameters->sampleFormat - is one of the sample formats defined in portaudio.h void *inputParameters->hostApiSpecificStreamInfo - if supplied its hostApi field matches the input device's host Api PaDeviceIndex outputParmeters->device - is within range (0 to Pa_CountDevices-1) int outputParmeters->numChannels - if inputDevice is valid, numInputChannels is > 0 - upper bound is NOT validated against device capabilities PaSampleFormat outputParmeters->sampleFormat - is one of the sample formats defined in portaudio.h void *outputParmeters->hostApiSpecificStreamInfo - if supplied its hostApi field matches the output device's host Api double sampleRate - is not an 'absurd' rate (less than 1000. or greater than 384000.) - sampleRate is NOT validated against device capabilities PaStreamFlags streamFlags - unused platform neutral flags are zero - paNeverDropInput is only used for full-duplex callback streams with variable buffer size (paFramesPerBufferUnspecified) [*END PA FRONT VALIDATIONS*] The following validations MUST be performed by (*OpenStream)(): - check that input device can support numInputChannels - check that input device can support inputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format - if inputStreamInfo is supplied, validate its contents, or return an error if no inputStreamInfo is expected - check that output device can support numOutputChannels - check that output device can support outputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format - if outputStreamInfo is supplied, validate its contents, or return an error if no outputStreamInfo is expected - if a full duplex stream is requested, check that the combination of input and output parameters is supported - check that the device supports sampleRate - alter sampleRate to a close allowable rate if necessary - validate inputLatency and outputLatency - validate any platform specific flags, if flags are supplied they must be valid. */ PaError (*OpenStream)( struct PaUtilHostApiRepresentation *hostApi, PaStream** stream, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerCallback, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); PaError (*IsFormatSupported)( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); } PaUtilHostApiRepresentation; /** Prototype for the initialization function which must be implemented by every host API. This function should only return an error other than paNoError if it encounters an unexpected and fatal error (memory allocation error for example). In general, there may be conditions under which it returns a NULL interface pointer and also returns paNoError. For example, if the ASIO implementation detects that ASIO is not installed, it should return a NULL interface, and paNoError. @see paHostApiInitializers */ typedef PaError PaUtilHostApiInitializer( PaUtilHostApiRepresentation**, PaHostApiIndex ); /** paHostApiInitializers is a NULL-terminated array of host API initialization functions. These functions are called by pa_front.c to initialize the host APIs when the client calls Pa_Initialize(). The initialization functions are invoked in order. The first successfully initialized host API that has a default input *or* output device is used as the default PortAudio host API. This is based on the logic that there is only one default host API, and it must contain the default input and output devices (if defined). There is a platform specific file that defines paHostApiInitializers for that platform, pa_win/pa_win_hostapis.c contains the Win32 definitions for example. */ extern PaUtilHostApiInitializer *paHostApiInitializers[]; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_HOSTAPI_H */ praat-6.0.04/external/portaudio/pa_jack.c000066400000000000000000001736401261542461700203170ustar00rootroot00000000000000/* * $Id: pa_jack.c 1912 2013-11-15 12:27:07Z gineera $ * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * JACK Implementation by Joshua Haberman * * Copyright (c) 2004 Stefan Westerfeld * Copyright (c) 2004 Arve Knudsen * Copyright (c) 2002 Joshua Haberman * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostapi_src */ #include #include #include #include #include #include #include #include /* EBUSY */ #include /* sig_atomic_t */ #include #include #include #include #include "pa_util.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_process.h" #include "pa_allocation.h" #include "pa_cpuload.h" #include "pa_ringbuffer.h" #include "pa_debugprint.h" static pthread_t mainThread_; static char *jackErr_ = NULL; static const char* clientName_ = "PortAudio"; #define STRINGIZE_HELPER(expr) #expr #define STRINGIZE(expr) STRINGIZE_HELPER(expr) /* Check PaError */ #define ENSURE_PA(expr) \ do { \ PaError paErr; \ if( (paErr = (expr)) < paNoError ) \ { \ if( (paErr) == paUnanticipatedHostError && pthread_self() == mainThread_ ) \ { \ const char *err = jackErr_; \ if (! err ) err = "unknown error"; \ PaUtil_SetLastHostErrorInfo( paJACK, -1, err ); \ } \ PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \ result = paErr; \ goto error; \ } \ } while( 0 ) #define UNLESS(expr, code) \ do { \ if( (expr) == 0 ) \ { \ if( (code) == paUnanticipatedHostError && pthread_self() == mainThread_ ) \ { \ const char *err = jackErr_; \ if (!err) err = "unknown error"; \ PaUtil_SetLastHostErrorInfo( paJACK, -1, err ); \ } \ PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \ result = (code); \ goto error; \ } \ } while( 0 ) #define ASSERT_CALL(expr, success) \ do { \ int err = (expr); \ assert( err == success ); \ } while( 0 ) /* * Functions that directly map to the PortAudio stream interface */ static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); static PaError CloseStream( PaStream* stream ); static PaError StartStream( PaStream *stream ); static PaError StopStream( PaStream *stream ); static PaError AbortStream( PaStream *stream ); static PaError IsStreamStopped( PaStream *s ); static PaError IsStreamActive( PaStream *stream ); /*static PaTime GetStreamInputLatency( PaStream *stream );*/ /*static PaTime GetStreamOutputLatency( PaStream *stream );*/ static PaTime GetStreamTime( PaStream *stream ); static double GetStreamCpuLoad( PaStream* stream ); /* * Data specific to this API */ struct PaJackStream; typedef struct { PaUtilHostApiRepresentation commonHostApiRep; PaUtilStreamInterface callbackStreamInterface; PaUtilStreamInterface blockingStreamInterface; PaUtilAllocationGroup *deviceInfoMemory; jack_client_t *jack_client; int jack_buffer_size; PaHostApiIndex hostApiIndex; pthread_mutex_t mtx; pthread_cond_t cond; unsigned long inputBase, outputBase; /* For dealing with the process thread */ volatile int xrun; /* Received xrun notification from JACK? */ struct PaJackStream * volatile toAdd, * volatile toRemove; struct PaJackStream *processQueue; volatile sig_atomic_t jackIsDown; } PaJackHostApiRepresentation; /* PaJackStream - a stream data structure specifically for this implementation */ typedef struct PaJackStream { PaUtilStreamRepresentation streamRepresentation; PaUtilBufferProcessor bufferProcessor; PaUtilCpuLoadMeasurer cpuLoadMeasurer; PaJackHostApiRepresentation *hostApi; /* our input and output ports */ jack_port_t **local_input_ports; jack_port_t **local_output_ports; /* the input and output ports of the client we are connecting to */ jack_port_t **remote_input_ports; jack_port_t **remote_output_ports; int num_incoming_connections; int num_outgoing_connections; jack_client_t *jack_client; /* The stream is running if it's still producing samples. * The stream is active if samples it produced are still being heard. */ volatile sig_atomic_t is_running; volatile sig_atomic_t is_active; /* Used to signal processing thread that stream should start or stop, respectively */ volatile sig_atomic_t doStart, doStop, doAbort; jack_nframes_t t0; PaUtilAllocationGroup *stream_memory; /* These are useful in the process callback */ int callbackResult; int isSilenced; int xrun; /* These are useful for the blocking API */ int isBlockingStream; PaUtilRingBuffer inFIFO; PaUtilRingBuffer outFIFO; volatile sig_atomic_t data_available; sem_t data_semaphore; int bytesPerFrame; int samplesPerFrame; struct PaJackStream *next; } PaJackStream; /* In calls to jack_get_ports() this filter expression is used instead of "" * to prevent any other types (eg Midi ports etc) being listed */ #define JACK_PORT_TYPE_FILTER "audio" #define TRUE 1 #define FALSE 0 /* * Functions specific to this API */ static int JackCallback( jack_nframes_t frames, void *userData ); /* * * Implementation * */ /* ---- blocking emulation layer ---- */ /* Allocate buffer. */ static PaError BlockingInitFIFO( PaUtilRingBuffer *rbuf, long numFrames, long bytesPerFrame ) { long numBytes = numFrames * bytesPerFrame; char *buffer = (char *) malloc( numBytes ); if( buffer == NULL ) return paInsufficientMemory; memset( buffer, 0, numBytes ); return (PaError) PaUtil_InitializeRingBuffer( rbuf, 1, numBytes, buffer ); } /* Free buffer. */ static PaError BlockingTermFIFO( PaUtilRingBuffer *rbuf ) { if( rbuf->buffer ) free( rbuf->buffer ); rbuf->buffer = NULL; return paNoError; } static int BlockingCallback( const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData ) { struct PaJackStream *stream = (PaJackStream *)userData; long numBytes = stream->bytesPerFrame * framesPerBuffer; /* This may get called with NULL inputBuffer during initial setup. */ if( inputBuffer != NULL ) { PaUtil_WriteRingBuffer( &stream->inFIFO, inputBuffer, numBytes ); } if( outputBuffer != NULL ) { int numRead = PaUtil_ReadRingBuffer( &stream->outFIFO, outputBuffer, numBytes ); /* Zero out remainder of buffer if we run out of data. */ memset( (char *)outputBuffer + numRead, 0, numBytes - numRead ); } if( !stream->data_available ) { stream->data_available = 1; sem_post( &stream->data_semaphore ); } return paContinue; } static PaError BlockingBegin( PaJackStream *stream, int minimum_buffer_size ) { long doRead = 0; long doWrite = 0; PaError result = paNoError; long numFrames; doRead = stream->local_input_ports != NULL; doWrite = stream->local_output_ports != NULL; /* */ stream->samplesPerFrame = 2; stream->bytesPerFrame = sizeof(float) * stream->samplesPerFrame; /* */ numFrames = 32; while (numFrames < minimum_buffer_size) numFrames *= 2; if( doRead ) { ENSURE_PA( BlockingInitFIFO( &stream->inFIFO, numFrames, stream->bytesPerFrame ) ); } if( doWrite ) { long numBytes; ENSURE_PA( BlockingInitFIFO( &stream->outFIFO, numFrames, stream->bytesPerFrame ) ); /* Make Write FIFO appear full initially. */ numBytes = PaUtil_GetRingBufferWriteAvailable( &stream->outFIFO ); PaUtil_AdvanceRingBufferWriteIndex( &stream->outFIFO, numBytes ); } stream->data_available = 0; sem_init( &stream->data_semaphore, 0, 0 ); error: return result; } static void BlockingEnd( PaJackStream *stream ) { BlockingTermFIFO( &stream->inFIFO ); BlockingTermFIFO( &stream->outFIFO ); sem_destroy( &stream->data_semaphore ); } static PaError BlockingReadStream( PaStream* s, void *data, unsigned long numFrames ) { PaError result = paNoError; PaJackStream *stream = (PaJackStream *)s; long bytesRead; char *p = (char *) data; long numBytes = stream->bytesPerFrame * numFrames; while( numBytes > 0 ) { bytesRead = PaUtil_ReadRingBuffer( &stream->inFIFO, p, numBytes ); numBytes -= bytesRead; p += bytesRead; if( numBytes > 0 ) { /* see write for an explanation */ if( stream->data_available ) stream->data_available = 0; else sem_wait( &stream->data_semaphore ); } } return result; } static PaError BlockingWriteStream( PaStream* s, const void *data, unsigned long numFrames ) { PaError result = paNoError; PaJackStream *stream = (PaJackStream *)s; long bytesWritten; char *p = (char *) data; long numBytes = stream->bytesPerFrame * numFrames; while( numBytes > 0 ) { bytesWritten = PaUtil_WriteRingBuffer( &stream->outFIFO, p, numBytes ); numBytes -= bytesWritten; p += bytesWritten; if( numBytes > 0 ) { /* we use the following algorithm: * (1) write data * (2) if some data didn't fit into the ringbuffer, set data_available to 0 * to indicate to the audio that if space becomes available, we want to know * (3) retry to write data (because it might be that between (1) and (2) * new space in the buffer became available) * (4) if this failed, we are sure that the buffer is really empty and * we will definitely receive a notification when it becomes available * thus we can safely sleep * * if the algorithm bailed out in step (3) before, it leaks a count of 1 * on the semaphore; however, it doesn't matter, because if we block in (4), * we also do it in a loop */ if( stream->data_available ) stream->data_available = 0; else sem_wait( &stream->data_semaphore ); } } return result; } static signed long BlockingGetStreamReadAvailable( PaStream* s ) { PaJackStream *stream = (PaJackStream *)s; int bytesFull = PaUtil_GetRingBufferReadAvailable( &stream->inFIFO ); return bytesFull / stream->bytesPerFrame; } static signed long BlockingGetStreamWriteAvailable( PaStream* s ) { PaJackStream *stream = (PaJackStream *)s; int bytesEmpty = PaUtil_GetRingBufferWriteAvailable( &stream->outFIFO ); return bytesEmpty / stream->bytesPerFrame; } static PaError BlockingWaitEmpty( PaStream *s ) { PaJackStream *stream = (PaJackStream *)s; while( PaUtil_GetRingBufferReadAvailable( &stream->outFIFO ) > 0 ) { stream->data_available = 0; sem_wait( &stream->data_semaphore ); } return 0; } /* ---- jack driver ---- */ /* BuildDeviceList(): * * The process of determining a list of PortAudio "devices" from * JACK's client/port system is fairly involved, so it is separated * into its own routine. */ static PaError BuildDeviceList( PaJackHostApiRepresentation *jackApi ) { /* Utility macros for the repetitive process of allocating memory */ /* JACK has no concept of a device. To JACK, there are clients * which have an arbitrary number of ports. To make this * intelligible to PortAudio clients, we will group each JACK client * into a device, and make each port of that client a channel */ PaError result = paNoError; PaUtilHostApiRepresentation *commonApi = &jackApi->commonHostApiRep; const char **jack_ports = NULL; char **client_names = NULL; char *regex_pattern = NULL; int port_index, client_index, i; double globalSampleRate; regex_t port_regex; unsigned long numClients = 0, numPorts = 0; char *tmp_client_name = NULL; commonApi->info.defaultInputDevice = paNoDevice; commonApi->info.defaultOutputDevice = paNoDevice; commonApi->info.deviceCount = 0; /* Parse the list of ports, using a regex to grab the client names */ ASSERT_CALL( regcomp( &port_regex, "^[^:]*", REG_EXTENDED ), 0 ); /* since we are rebuilding the list of devices, free all memory * associated with the previous list */ PaUtil_FreeAllAllocations( jackApi->deviceInfoMemory ); regex_pattern = PaUtil_GroupAllocateMemory( jackApi->deviceInfoMemory, jack_client_name_size() + 3 ); tmp_client_name = PaUtil_GroupAllocateMemory( jackApi->deviceInfoMemory, jack_client_name_size() ); /* We can only retrieve the list of clients indirectly, by first * asking for a list of all ports, then parsing the port names * according to the client_name:port_name convention (which is * enforced by jackd) * A: If jack_get_ports returns NULL, there's nothing for us to do */ UNLESS( (jack_ports = jack_get_ports( jackApi->jack_client, "", JACK_PORT_TYPE_FILTER, 0 )) && jack_ports[0], paNoError ); /* Find number of ports */ while( jack_ports[numPorts] ) ++numPorts; /* At least there will be one port per client :) */ UNLESS( client_names = PaUtil_GroupAllocateMemory( jackApi->deviceInfoMemory, numPorts * sizeof (char *) ), paInsufficientMemory ); /* Build a list of clients from the list of ports */ for( numClients = 0, port_index = 0; jack_ports[port_index] != NULL; port_index++ ) { int client_seen = FALSE; regmatch_t match_info; const char *port = jack_ports[port_index]; /* extract the client name from the port name, using a regex * that parses the clientname:portname syntax */ UNLESS( !regexec( &port_regex, port, 1, &match_info, 0 ), paInternalError ); assert(match_info.rm_eo - match_info.rm_so < jack_client_name_size()); memcpy( tmp_client_name, port + match_info.rm_so, match_info.rm_eo - match_info.rm_so ); tmp_client_name[match_info.rm_eo - match_info.rm_so] = '\0'; /* do we know about this port's client yet? */ for( i = 0; i < numClients; i++ ) { if( strcmp( tmp_client_name, client_names[i] ) == 0 ) client_seen = TRUE; } if (client_seen) continue; /* A: Nothing to see here, move along */ UNLESS( client_names[numClients] = (char*)PaUtil_GroupAllocateMemory( jackApi->deviceInfoMemory, strlen(tmp_client_name) + 1), paInsufficientMemory ); /* The alsa_pcm client should go in spot 0. If this * is the alsa_pcm client AND we are NOT about to put * it in spot 0 put it in spot 0 and move whatever * was already in spot 0 to the end. */ if( strcmp( "alsa_pcm", tmp_client_name ) == 0 && numClients > 0 ) { /* alsa_pcm goes in spot 0 */ strcpy( client_names[ numClients ], client_names[0] ); strcpy( client_names[0], tmp_client_name ); } else { /* put the new client at the end of the client list */ strcpy( client_names[ numClients ], tmp_client_name ); } ++numClients; } /* Now we have a list of clients, which will become the list of * PortAudio devices. */ /* there is one global sample rate all clients must conform to */ globalSampleRate = jack_get_sample_rate( jackApi->jack_client ); UNLESS( commonApi->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( jackApi->deviceInfoMemory, sizeof(PaDeviceInfo*) * numClients ), paInsufficientMemory ); assert( commonApi->info.deviceCount == 0 ); /* Create a PaDeviceInfo structure for every client */ for( client_index = 0; client_index < numClients; client_index++ ) { PaDeviceInfo *curDevInfo; const char **clientPorts = NULL; UNLESS( curDevInfo = (PaDeviceInfo*)PaUtil_GroupAllocateMemory( jackApi->deviceInfoMemory, sizeof(PaDeviceInfo) ), paInsufficientMemory ); UNLESS( curDevInfo->name = (char*)PaUtil_GroupAllocateMemory( jackApi->deviceInfoMemory, strlen(client_names[client_index]) + 1 ), paInsufficientMemory ); strcpy( (char *)curDevInfo->name, client_names[client_index] ); curDevInfo->structVersion = 2; curDevInfo->hostApi = jackApi->hostApiIndex; /* JACK is very inflexible: there is one sample rate the whole * system must run at, and all clients must speak IEEE float. */ curDevInfo->defaultSampleRate = globalSampleRate; /* To determine how many input and output channels are available, * we re-query jackd with more specific parameters. */ sprintf( regex_pattern, "%s:.*", client_names[client_index] ); /* ... what are your output ports (that we could input from)? */ clientPorts = jack_get_ports( jackApi->jack_client, regex_pattern, JACK_PORT_TYPE_FILTER, JackPortIsOutput); curDevInfo->maxInputChannels = 0; curDevInfo->defaultLowInputLatency = 0.; curDevInfo->defaultHighInputLatency = 0.; if( clientPorts ) { jack_port_t *p = jack_port_by_name( jackApi->jack_client, clientPorts[0] ); curDevInfo->defaultLowInputLatency = curDevInfo->defaultHighInputLatency = jack_port_get_latency( p ) / globalSampleRate; for( i = 0; clientPorts[i] != NULL; i++) { /* The number of ports returned is the number of output channels. * We don't care what they are, we just care how many */ curDevInfo->maxInputChannels++; } free(clientPorts); } /* ... what are your input ports (that we could output to)? */ clientPorts = jack_get_ports( jackApi->jack_client, regex_pattern, JACK_PORT_TYPE_FILTER, JackPortIsInput); curDevInfo->maxOutputChannels = 0; curDevInfo->defaultLowOutputLatency = 0.; curDevInfo->defaultHighOutputLatency = 0.; if( clientPorts ) { jack_port_t *p = jack_port_by_name( jackApi->jack_client, clientPorts[0] ); curDevInfo->defaultLowOutputLatency = curDevInfo->defaultHighOutputLatency = jack_port_get_latency( p ) / globalSampleRate; for( i = 0; clientPorts[i] != NULL; i++) { /* The number of ports returned is the number of input channels. * We don't care what they are, we just care how many */ curDevInfo->maxOutputChannels++; } free(clientPorts); } /* Add this client to the list of devices */ commonApi->deviceInfos[client_index] = curDevInfo; ++commonApi->info.deviceCount; if( commonApi->info.defaultInputDevice == paNoDevice && curDevInfo->maxInputChannels > 0 ) commonApi->info.defaultInputDevice = client_index; if( commonApi->info.defaultOutputDevice == paNoDevice && curDevInfo->maxOutputChannels > 0 ) commonApi->info.defaultOutputDevice = client_index; } error: regfree( &port_regex ); free( jack_ports ); return result; } static void UpdateSampleRate( PaJackStream *stream, double sampleRate ) { /* XXX: Maybe not the cleanest way of going about this? */ stream->cpuLoadMeasurer.samplingPeriod = stream->bufferProcessor.samplePeriod = 1. / sampleRate; stream->streamRepresentation.streamInfo.sampleRate = sampleRate; } static void JackErrorCallback( const char *msg ) { if( pthread_self() == mainThread_ ) { assert( msg ); jackErr_ = realloc( jackErr_, strlen( msg ) + 1 ); strcpy( jackErr_, msg ); } } static void JackOnShutdown( void *arg ) { PaJackHostApiRepresentation *jackApi = (PaJackHostApiRepresentation *)arg; PaJackStream *stream = jackApi->processQueue; PA_DEBUG(( "%s: JACK server is shutting down\n", __FUNCTION__ )); for( ; stream; stream = stream->next ) { stream->is_active = 0; } /* Make sure that the main thread doesn't get stuck waiting on the condition */ ASSERT_CALL( pthread_mutex_lock( &jackApi->mtx ), 0 ); jackApi->jackIsDown = 1; ASSERT_CALL( pthread_cond_signal( &jackApi->cond ), 0 ); ASSERT_CALL( pthread_mutex_unlock( &jackApi->mtx ), 0 ); } static int JackSrCb( jack_nframes_t nframes, void *arg ) { PaJackHostApiRepresentation *jackApi = (PaJackHostApiRepresentation *)arg; double sampleRate = (double)nframes; PaJackStream *stream = jackApi->processQueue; /* Update all streams in process queue */ PA_DEBUG(( "%s: Acting on change in JACK samplerate: %f\n", __FUNCTION__, sampleRate )); for( ; stream; stream = stream->next ) { if( stream->streamRepresentation.streamInfo.sampleRate != sampleRate ) { PA_DEBUG(( "%s: Updating samplerate\n", __FUNCTION__ )); UpdateSampleRate( stream, sampleRate ); } } return 0; } static int JackXRunCb(void *arg) { PaJackHostApiRepresentation *hostApi = (PaJackHostApiRepresentation *)arg; assert( hostApi ); hostApi->xrun = TRUE; PA_DEBUG(( "%s: JACK signalled xrun\n", __FUNCTION__ )); return 0; } PaError PaJack_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) { PaError result = paNoError; PaJackHostApiRepresentation *jackHostApi; int activated = 0; jack_status_t jackStatus = 0; *hostApi = NULL; /* Initialize to NULL */ UNLESS( jackHostApi = (PaJackHostApiRepresentation*) PaUtil_AllocateMemory( sizeof(PaJackHostApiRepresentation) ), paInsufficientMemory ); UNLESS( jackHostApi->deviceInfoMemory = PaUtil_CreateAllocationGroup(), paInsufficientMemory ); mainThread_ = pthread_self(); ASSERT_CALL( pthread_mutex_init( &jackHostApi->mtx, NULL ), 0 ); ASSERT_CALL( pthread_cond_init( &jackHostApi->cond, NULL ), 0 ); /* Try to become a client of the JACK server. If we cannot do * this, then this API cannot be used. * * Without the JackNoStartServer option, the jackd server is started * automatically which we do not want. */ jackHostApi->jack_client = jack_client_open( clientName_, JackNoStartServer, &jackStatus ); if( !jackHostApi->jack_client ) { /* the V19 development docs say that if an implementation * detects that it cannot be used, it should return a NULL * interface and paNoError */ PA_DEBUG(( "%s: Couldn't connect to JACK, status: %d\n", __FUNCTION__, jackStatus )); result = paNoError; goto error; } jackHostApi->hostApiIndex = hostApiIndex; *hostApi = &jackHostApi->commonHostApiRep; (*hostApi)->info.structVersion = 1; (*hostApi)->info.type = paJACK; (*hostApi)->info.name = "JACK Audio Connection Kit"; /* Build a device list by querying the JACK server */ ENSURE_PA( BuildDeviceList( jackHostApi ) ); /* Register functions */ (*hostApi)->Terminate = Terminate; (*hostApi)->OpenStream = OpenStream; (*hostApi)->IsFormatSupported = IsFormatSupported; PaUtil_InitializeStreamInterface( &jackHostApi->callbackStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, GetStreamCpuLoad, PaUtil_DummyRead, PaUtil_DummyWrite, PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); PaUtil_InitializeStreamInterface( &jackHostApi->blockingStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, PaUtil_DummyGetCpuLoad, BlockingReadStream, BlockingWriteStream, BlockingGetStreamReadAvailable, BlockingGetStreamWriteAvailable ); jackHostApi->inputBase = jackHostApi->outputBase = 0; jackHostApi->xrun = 0; jackHostApi->toAdd = jackHostApi->toRemove = NULL; jackHostApi->processQueue = NULL; jackHostApi->jackIsDown = 0; jack_on_shutdown( jackHostApi->jack_client, JackOnShutdown, jackHostApi ); jack_set_error_function( JackErrorCallback ); jackHostApi->jack_buffer_size = jack_get_buffer_size ( jackHostApi->jack_client ); /* Don't check for error, may not be supported (deprecated in at least jackdmp) */ jack_set_sample_rate_callback( jackHostApi->jack_client, JackSrCb, jackHostApi ); UNLESS( !jack_set_xrun_callback( jackHostApi->jack_client, JackXRunCb, jackHostApi ), paUnanticipatedHostError ); UNLESS( !jack_set_process_callback( jackHostApi->jack_client, JackCallback, jackHostApi ), paUnanticipatedHostError ); UNLESS( !jack_activate( jackHostApi->jack_client ), paUnanticipatedHostError ); activated = 1; return result; error: if( activated ) ASSERT_CALL( jack_deactivate( jackHostApi->jack_client ), 0 ); if( jackHostApi ) { if( jackHostApi->jack_client ) ASSERT_CALL( jack_client_close( jackHostApi->jack_client ), 0 ); if( jackHostApi->deviceInfoMemory ) { PaUtil_FreeAllAllocations( jackHostApi->deviceInfoMemory ); PaUtil_DestroyAllocationGroup( jackHostApi->deviceInfoMemory ); } PaUtil_FreeMemory( jackHostApi ); } return result; } static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) { PaJackHostApiRepresentation *jackHostApi = (PaJackHostApiRepresentation*)hostApi; /* note: this automatically disconnects all ports, since a deactivated * client is not allowed to have any ports connected */ ASSERT_CALL( jack_deactivate( jackHostApi->jack_client ), 0 ); ASSERT_CALL( pthread_mutex_destroy( &jackHostApi->mtx ), 0 ); ASSERT_CALL( pthread_cond_destroy( &jackHostApi->cond ), 0 ); ASSERT_CALL( jack_client_close( jackHostApi->jack_client ), 0 ); if( jackHostApi->deviceInfoMemory ) { PaUtil_FreeAllAllocations( jackHostApi->deviceInfoMemory ); PaUtil_DestroyAllocationGroup( jackHostApi->deviceInfoMemory ); } PaUtil_FreeMemory( jackHostApi ); free( jackErr_ ); jackErr_ = NULL; } static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { int inputChannelCount = 0, outputChannelCount = 0; PaSampleFormat inputSampleFormat, outputSampleFormat; if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that input device can support inputChannelCount */ if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) return paInvalidChannelCount; /* validate inputStreamInfo */ if( inputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else { inputChannelCount = 0; } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that output device can support inputChannelCount */ if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) return paInvalidChannelCount; /* validate outputStreamInfo */ if( outputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else { outputChannelCount = 0; } /* The following check is not necessary for JACK. - if a full duplex stream is requested, check that the combination of input and output parameters is supported Because the buffer adapter handles conversion between all standard sample formats, the following checks are only required if paCustomFormat is implemented, or under some other unusual conditions. - check that input device can support inputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format - check that output device can support outputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format */ /* check that the device supports sampleRate */ #define ABS(x) ( (x) > 0 ? (x) : -(x) ) if( ABS(sampleRate - jack_get_sample_rate(((PaJackHostApiRepresentation *) hostApi)->jack_client )) > 1 ) return paInvalidSampleRate; #undef ABS return paFormatIsSupported; } /* Basic stream initialization */ static PaError InitializeStream( PaJackStream *stream, PaJackHostApiRepresentation *hostApi, int numInputChannels, int numOutputChannels ) { PaError result = paNoError; assert( stream ); memset( stream, 0, sizeof (PaJackStream) ); UNLESS( stream->stream_memory = PaUtil_CreateAllocationGroup(), paInsufficientMemory ); stream->jack_client = hostApi->jack_client; stream->hostApi = hostApi; if( numInputChannels > 0 ) { UNLESS( stream->local_input_ports = (jack_port_t**) PaUtil_GroupAllocateMemory( stream->stream_memory, sizeof(jack_port_t*) * numInputChannels ), paInsufficientMemory ); memset( stream->local_input_ports, 0, sizeof(jack_port_t*) * numInputChannels ); UNLESS( stream->remote_output_ports = (jack_port_t**) PaUtil_GroupAllocateMemory( stream->stream_memory, sizeof(jack_port_t*) * numInputChannels ), paInsufficientMemory ); memset( stream->remote_output_ports, 0, sizeof(jack_port_t*) * numInputChannels ); } if( numOutputChannels > 0 ) { UNLESS( stream->local_output_ports = (jack_port_t**) PaUtil_GroupAllocateMemory( stream->stream_memory, sizeof(jack_port_t*) * numOutputChannels ), paInsufficientMemory ); memset( stream->local_output_ports, 0, sizeof(jack_port_t*) * numOutputChannels ); UNLESS( stream->remote_input_ports = (jack_port_t**) PaUtil_GroupAllocateMemory( stream->stream_memory, sizeof(jack_port_t*) * numOutputChannels ), paInsufficientMemory ); memset( stream->remote_input_ports, 0, sizeof(jack_port_t*) * numOutputChannels ); } stream->num_incoming_connections = numInputChannels; stream->num_outgoing_connections = numOutputChannels; error: return result; } /*! * Free resources associated with stream, and eventually stream itself. * * Frees allocated memory, and closes opened pcms. */ static void CleanUpStream( PaJackStream *stream, int terminateStreamRepresentation, int terminateBufferProcessor ) { int i; assert( stream ); if( stream->isBlockingStream ) BlockingEnd( stream ); for( i = 0; i < stream->num_incoming_connections; ++i ) { if( stream->local_input_ports[i] ) ASSERT_CALL( jack_port_unregister( stream->jack_client, stream->local_input_ports[i] ), 0 ); } for( i = 0; i < stream->num_outgoing_connections; ++i ) { if( stream->local_output_ports[i] ) ASSERT_CALL( jack_port_unregister( stream->jack_client, stream->local_output_ports[i] ), 0 ); } if( terminateStreamRepresentation ) PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); if( terminateBufferProcessor ) PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); if( stream->stream_memory ) { PaUtil_FreeAllAllocations( stream->stream_memory ); PaUtil_DestroyAllocationGroup( stream->stream_memory ); } PaUtil_FreeMemory( stream ); } static PaError WaitCondition( PaJackHostApiRepresentation *hostApi ) { PaError result = paNoError; int err = 0; PaTime pt = PaUtil_GetTime(); struct timespec ts; ts.tv_sec = (time_t) floor( pt + 10 * 60 /* 10 minutes */ ); ts.tv_nsec = (long) ((pt - floor( pt )) * 1000000000); /* XXX: Best enclose in loop, in case of spurious wakeups? */ err = pthread_cond_timedwait( &hostApi->cond, &hostApi->mtx, &ts ); /* Make sure we didn't time out */ UNLESS( err != ETIMEDOUT, paTimedOut ); UNLESS( !err, paInternalError ); error: return result; } static PaError AddStream( PaJackStream *stream ) { PaError result = paNoError; PaJackHostApiRepresentation *hostApi = stream->hostApi; /* Add to queue of streams that should be processed */ ASSERT_CALL( pthread_mutex_lock( &hostApi->mtx ), 0 ); if( !hostApi->jackIsDown ) { hostApi->toAdd = stream; /* Unlock mutex and await signal from processing thread */ result = WaitCondition( stream->hostApi ); } ASSERT_CALL( pthread_mutex_unlock( &hostApi->mtx ), 0 ); ENSURE_PA( result ); UNLESS( !hostApi->jackIsDown, paDeviceUnavailable ); error: return result; } /* Remove stream from processing queue */ static PaError RemoveStream( PaJackStream *stream ) { PaError result = paNoError; PaJackHostApiRepresentation *hostApi = stream->hostApi; /* Add to queue over streams that should be processed */ ASSERT_CALL( pthread_mutex_lock( &hostApi->mtx ), 0 ); if( !hostApi->jackIsDown ) { hostApi->toRemove = stream; /* Unlock mutex and await signal from processing thread */ result = WaitCondition( stream->hostApi ); } ASSERT_CALL( pthread_mutex_unlock( &hostApi->mtx ), 0 ); ENSURE_PA( result ); error: return result; } /* Add stream to JACK callback processing queue */ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ) { PaError result = paNoError; PaJackHostApiRepresentation *jackHostApi = (PaJackHostApiRepresentation*)hostApi; PaJackStream *stream = NULL; char *port_string = PaUtil_GroupAllocateMemory( jackHostApi->deviceInfoMemory, jack_port_name_size() ); unsigned long regexSz = jack_client_name_size() + 3; char *regex_pattern = PaUtil_GroupAllocateMemory( jackHostApi->deviceInfoMemory, regexSz ); const char **jack_ports = NULL; /* int jack_max_buffer_size = jack_get_buffer_size( jackHostApi->jack_client ); */ int i; int inputChannelCount, outputChannelCount; const double jackSr = jack_get_sample_rate( jackHostApi->jack_client ); PaSampleFormat inputSampleFormat = 0, outputSampleFormat = 0; int bpInitialized = 0, srInitialized = 0; /* Initialized buffer processor and stream representation? */ unsigned long ofs; /* validate platform specific flags */ if( (streamFlags & paPlatformSpecificFlags) != 0 ) return paInvalidFlag; /* unexpected platform specific flag */ if( (streamFlags & paPrimeOutputBuffersUsingStreamCallback) != 0 ) { streamFlags &= ~paPrimeOutputBuffersUsingStreamCallback; /*return paInvalidFlag;*/ /* This implementation does not support buffer priming */ } if( framesPerBuffer != paFramesPerBufferUnspecified ) { /* Jack operates with power of two buffers, and we don't support non-integer buffer adaption (yet) */ /*UNLESS( !(framesPerBuffer & (framesPerBuffer - 1)), paBufferTooBig );*/ /* TODO: Add descriptive error code? */ } /* Preliminary checks */ if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that input device can support inputChannelCount */ if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) return paInvalidChannelCount; /* validate inputStreamInfo */ if( inputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else { inputChannelCount = 0; } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that output device can support inputChannelCount */ if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) return paInvalidChannelCount; /* validate outputStreamInfo */ if( outputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else { outputChannelCount = 0; } /* ... check that the sample rate exactly matches the ONE acceptable rate * A: This rate isn't necessarily constant though? */ #define ABS(x) ( (x) > 0 ? (x) : -(x) ) if( ABS(sampleRate - jackSr) > 1 ) return paInvalidSampleRate; #undef ABS UNLESS( stream = (PaJackStream*)PaUtil_AllocateMemory( sizeof(PaJackStream) ), paInsufficientMemory ); ENSURE_PA( InitializeStream( stream, jackHostApi, inputChannelCount, outputChannelCount ) ); /* the blocking emulation, if necessary */ stream->isBlockingStream = !streamCallback; if( stream->isBlockingStream ) { float latency = 0.001; /* 1ms is the absolute minimum we support */ int minimum_buffer_frames = 0; if( inputParameters && inputParameters->suggestedLatency > latency ) latency = inputParameters->suggestedLatency; else if( outputParameters && outputParameters->suggestedLatency > latency ) latency = outputParameters->suggestedLatency; /* the latency the user asked for indicates the minimum buffer size in frames */ minimum_buffer_frames = (int) (latency * jack_get_sample_rate( jackHostApi->jack_client )); /* we also need to be able to store at least three full jack buffers to avoid dropouts */ if( jackHostApi->jack_buffer_size * 3 > minimum_buffer_frames ) minimum_buffer_frames = jackHostApi->jack_buffer_size * 3; /* setup blocking API data structures (FIXME: can fail) */ BlockingBegin( stream, minimum_buffer_frames ); /* install our own callback for the blocking API */ streamCallback = BlockingCallback; userData = stream; PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &jackHostApi->blockingStreamInterface, streamCallback, userData ); } else { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &jackHostApi->callbackStreamInterface, streamCallback, userData ); } srInitialized = 1; PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, jackSr ); /* create the JACK ports. We cannot connect them until audio * processing begins */ /* Register a unique set of ports for this stream * TODO: Robust allocation of new port names */ ofs = jackHostApi->inputBase; for( i = 0; i < inputChannelCount; i++ ) { snprintf( port_string, jack_port_name_size(), "in_%lu", ofs + i ); UNLESS( stream->local_input_ports[i] = jack_port_register( jackHostApi->jack_client, port_string, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 ), paInsufficientMemory ); } jackHostApi->inputBase += inputChannelCount; ofs = jackHostApi->outputBase; for( i = 0; i < outputChannelCount; i++ ) { snprintf( port_string, jack_port_name_size(), "out_%lu", ofs + i ); UNLESS( stream->local_output_ports[i] = jack_port_register( jackHostApi->jack_client, port_string, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 ), paInsufficientMemory ); } jackHostApi->outputBase += outputChannelCount; /* look up the jack_port_t's for the remote ports. We could do * this at stream start time, but doing it here ensures the * name lookup only happens once. */ if( inputChannelCount > 0 ) { int err = 0; /* Get output ports of our capture device */ snprintf( regex_pattern, regexSz, "%s:.*", hostApi->deviceInfos[ inputParameters->device ]->name ); UNLESS( jack_ports = jack_get_ports( jackHostApi->jack_client, regex_pattern, JACK_PORT_TYPE_FILTER, JackPortIsOutput ), paUnanticipatedHostError ); for( i = 0; i < inputChannelCount && jack_ports[i]; i++ ) { if( (stream->remote_output_ports[i] = jack_port_by_name( jackHostApi->jack_client, jack_ports[i] )) == NULL ) { err = 1; break; } } free( jack_ports ); UNLESS( !err, paInsufficientMemory ); /* Fewer ports than expected? */ UNLESS( i == inputChannelCount, paInternalError ); } if( outputChannelCount > 0 ) { int err = 0; /* Get input ports of our playback device */ snprintf( regex_pattern, regexSz, "%s:.*", hostApi->deviceInfos[ outputParameters->device ]->name ); UNLESS( jack_ports = jack_get_ports( jackHostApi->jack_client, regex_pattern, JACK_PORT_TYPE_FILTER, JackPortIsInput ), paUnanticipatedHostError ); for( i = 0; i < outputChannelCount && jack_ports[i]; i++ ) { if( (stream->remote_input_ports[i] = jack_port_by_name( jackHostApi->jack_client, jack_ports[i] )) == 0 ) { err = 1; break; } } free( jack_ports ); UNLESS( !err , paInsufficientMemory ); /* Fewer ports than expected? */ UNLESS( i == outputChannelCount, paInternalError ); } ENSURE_PA( PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, inputChannelCount, inputSampleFormat, paFloat32 | paNonInterleaved, /* hostInputSampleFormat */ outputChannelCount, outputSampleFormat, paFloat32 | paNonInterleaved, /* hostOutputSampleFormat */ jackSr, streamFlags, framesPerBuffer, 0, /* Ignored */ paUtilUnknownHostBufferSize, /* Buffer size may vary on JACK's discretion */ streamCallback, userData ) ); bpInitialized = 1; if( stream->num_incoming_connections > 0 ) stream->streamRepresentation.streamInfo.inputLatency = (jack_port_get_latency( stream->remote_output_ports[0] ) - jack_get_buffer_size( jackHostApi->jack_client ) /* One buffer is not counted as latency */ + PaUtil_GetBufferProcessorInputLatencyFrames( &stream->bufferProcessor )) / sampleRate; if( stream->num_outgoing_connections > 0 ) stream->streamRepresentation.streamInfo.outputLatency = (jack_port_get_latency( stream->remote_input_ports[0] ) - jack_get_buffer_size( jackHostApi->jack_client ) /* One buffer is not counted as latency */ + PaUtil_GetBufferProcessorOutputLatencyFrames( &stream->bufferProcessor )) / sampleRate; stream->streamRepresentation.streamInfo.sampleRate = jackSr; stream->t0 = jack_frame_time( jackHostApi->jack_client ); /* A: Time should run from Pa_OpenStream */ /* Add to queue of opened streams */ ENSURE_PA( AddStream( stream ) ); *s = (PaStream*)stream; return result; error: if( stream ) CleanUpStream( stream, srInitialized, bpInitialized ); return result; } /* When CloseStream() is called, the multi-api layer ensures that the stream has already been stopped or aborted. */ static PaError CloseStream( PaStream* s ) { PaError result = paNoError; PaJackStream *stream = (PaJackStream*)s; /* Remove this stream from the processing queue */ ENSURE_PA( RemoveStream( stream ) ); error: CleanUpStream( stream, 1, 1 ); return result; } static PaError RealProcess( PaJackStream *stream, jack_nframes_t frames ) { PaError result = paNoError; PaStreamCallbackTimeInfo timeInfo = {0,0,0}; int chn; int framesProcessed; const double sr = jack_get_sample_rate( stream->jack_client ); /* Shouldn't change during the process callback */ PaStreamCallbackFlags cbFlags = 0; /* If the user has returned !paContinue from the callback we'll want to flush the internal buffers, * when these are empty we can finally mark the stream as inactive */ if( stream->callbackResult != paContinue && PaUtil_IsBufferProcessorOutputEmpty( &stream->bufferProcessor ) ) { stream->is_active = 0; if( stream->streamRepresentation.streamFinishedCallback ) stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); PA_DEBUG(( "%s: Callback finished\n", __FUNCTION__ )); goto end; } timeInfo.currentTime = (jack_frame_time( stream->jack_client ) - stream->t0) / sr; if( stream->num_incoming_connections > 0 ) timeInfo.inputBufferAdcTime = timeInfo.currentTime - jack_port_get_latency( stream->remote_output_ports[0] ) / sr; if( stream->num_outgoing_connections > 0 ) timeInfo.outputBufferDacTime = timeInfo.currentTime + jack_port_get_latency( stream->remote_input_ports[0] ) / sr; PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); if( stream->xrun ) { /* XXX: Any way to tell which of these occurred? */ cbFlags = paOutputUnderflow | paInputOverflow; stream->xrun = FALSE; } PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, cbFlags ); if( stream->num_incoming_connections > 0 ) PaUtil_SetInputFrameCount( &stream->bufferProcessor, frames ); if( stream->num_outgoing_connections > 0 ) PaUtil_SetOutputFrameCount( &stream->bufferProcessor, frames ); for( chn = 0; chn < stream->num_incoming_connections; chn++ ) { jack_default_audio_sample_t *channel_buf = (jack_default_audio_sample_t*) jack_port_get_buffer( stream->local_input_ports[chn], frames ); PaUtil_SetNonInterleavedInputChannel( &stream->bufferProcessor, chn, channel_buf ); } for( chn = 0; chn < stream->num_outgoing_connections; chn++ ) { jack_default_audio_sample_t *channel_buf = (jack_default_audio_sample_t*) jack_port_get_buffer( stream->local_output_ports[chn], frames ); PaUtil_SetNonInterleavedOutputChannel( &stream->bufferProcessor, chn, channel_buf ); } framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &stream->callbackResult ); /* We've specified a host buffer size mode where every frame should be consumed by the buffer processor */ assert( framesProcessed == frames ); PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed ); end: return result; } /* Update the JACK callback's stream processing queue. */ static PaError UpdateQueue( PaJackHostApiRepresentation *hostApi ) { PaError result = paNoError; int queueModified = 0; const double jackSr = jack_get_sample_rate( hostApi->jack_client ); int err; if( (err = pthread_mutex_trylock( &hostApi->mtx )) != 0 ) { assert( err == EBUSY ); return paNoError; } if( hostApi->toAdd ) { if( hostApi->processQueue ) { PaJackStream *node = hostApi->processQueue; /* Advance to end of queue */ while( node->next ) node = node->next; node->next = hostApi->toAdd; } else { /* The only queue entry. */ hostApi->processQueue = (PaJackStream *)hostApi->toAdd; } /* If necessary, update stream state */ if( hostApi->toAdd->streamRepresentation.streamInfo.sampleRate != jackSr ) UpdateSampleRate( hostApi->toAdd, jackSr ); hostApi->toAdd = NULL; queueModified = 1; } if( hostApi->toRemove ) { int removed = 0; PaJackStream *node = hostApi->processQueue, *prev = NULL; assert( hostApi->processQueue ); while( node ) { if( node == hostApi->toRemove ) { if( prev ) prev->next = node->next; else hostApi->processQueue = (PaJackStream *)node->next; removed = 1; break; } prev = node; node = node->next; } UNLESS( removed, paInternalError ); hostApi->toRemove = NULL; PA_DEBUG(( "%s: Removed stream from processing queue\n", __FUNCTION__ )); queueModified = 1; } if( queueModified ) { /* Signal that we've done what was asked of us */ ASSERT_CALL( pthread_cond_signal( &hostApi->cond ), 0 ); } error: ASSERT_CALL( pthread_mutex_unlock( &hostApi->mtx ), 0 ); return result; } /* Audio processing callback invoked periodically from JACK. */ static int JackCallback( jack_nframes_t frames, void *userData ) { PaError result = paNoError; PaJackHostApiRepresentation *hostApi = (PaJackHostApiRepresentation *)userData; PaJackStream *stream = NULL; int xrun = hostApi->xrun; hostApi->xrun = 0; assert( hostApi ); ENSURE_PA( UpdateQueue( hostApi ) ); /* Process each stream */ stream = hostApi->processQueue; for( ; stream; stream = stream->next ) { if( xrun ) /* Don't override if already set */ stream->xrun = 1; /* See if this stream is to be started */ if( stream->doStart ) { /* If we can't obtain a lock, we'll try next time */ int err = pthread_mutex_trylock( &stream->hostApi->mtx ); if( !err ) { if( stream->doStart ) /* Could potentially change before obtaining the lock */ { stream->is_active = 1; stream->doStart = 0; PA_DEBUG(( "%s: Starting stream\n", __FUNCTION__ )); ASSERT_CALL( pthread_cond_signal( &stream->hostApi->cond ), 0 ); stream->callbackResult = paContinue; stream->isSilenced = 0; } ASSERT_CALL( pthread_mutex_unlock( &stream->hostApi->mtx ), 0 ); } else assert( err == EBUSY ); } else if( stream->doStop || stream->doAbort ) /* Should we stop/abort stream? */ { if( stream->callbackResult == paContinue ) /* Ok, make it stop */ { PA_DEBUG(( "%s: Stopping stream\n", __FUNCTION__ )); stream->callbackResult = stream->doStop ? paComplete : paAbort; } } if( stream->is_active ) ENSURE_PA( RealProcess( stream, frames ) ); /* If we have just entered inactive state, silence output */ if( !stream->is_active && !stream->isSilenced ) { int i; /* Silence buffer after entering inactive state */ PA_DEBUG(( "Silencing the output\n" )); for( i = 0; i < stream->num_outgoing_connections; ++i ) { jack_default_audio_sample_t *buffer = jack_port_get_buffer( stream->local_output_ports[i], frames ); memset( buffer, 0, sizeof (jack_default_audio_sample_t) * frames ); } stream->isSilenced = 1; } if( stream->doStop || stream->doAbort ) { /* See if RealProcess has acted on the request */ if( !stream->is_active ) /* Ok, signal to the main thread that we've carried out the operation */ { /* If we can't obtain a lock, we'll try next time */ int err = pthread_mutex_trylock( &stream->hostApi->mtx ); if( !err ) { stream->doStop = stream->doAbort = 0; ASSERT_CALL( pthread_cond_signal( &stream->hostApi->cond ), 0 ); ASSERT_CALL( pthread_mutex_unlock( &stream->hostApi->mtx ), 0 ); } else assert( err == EBUSY ); } } } return 0; error: return -1; } static PaError StartStream( PaStream *s ) { PaError result = paNoError; PaJackStream *stream = (PaJackStream*)s; int i; /* Ready the processor */ PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); /* Connect the ports. Note that the ports may already have been connected by someone else in * the meantime, in which case JACK returns EEXIST. */ if( stream->num_incoming_connections > 0 ) { for( i = 0; i < stream->num_incoming_connections; i++ ) { int r = jack_connect( stream->jack_client, jack_port_name( stream->remote_output_ports[i] ), jack_port_name( stream->local_input_ports[i] ) ); UNLESS( 0 == r || EEXIST == r, paUnanticipatedHostError ); } } if( stream->num_outgoing_connections > 0 ) { for( i = 0; i < stream->num_outgoing_connections; i++ ) { int r = jack_connect( stream->jack_client, jack_port_name( stream->local_output_ports[i] ), jack_port_name( stream->remote_input_ports[i] ) ); UNLESS( 0 == r || EEXIST == r, paUnanticipatedHostError ); } } stream->xrun = FALSE; /* Enable processing */ ASSERT_CALL( pthread_mutex_lock( &stream->hostApi->mtx ), 0 ); stream->doStart = 1; /* Wait for stream to be started */ result = WaitCondition( stream->hostApi ); /* do { err = pthread_cond_timedwait( &stream->hostApi->cond, &stream->hostApi->mtx, &ts ); } while( !stream->is_active && !err ); */ if( result != paNoError ) /* Something went wrong, call off the stream start */ { stream->doStart = 0; stream->is_active = 0; /* Cancel any processing */ } ASSERT_CALL( pthread_mutex_unlock( &stream->hostApi->mtx ), 0 ); ENSURE_PA( result ); stream->is_running = TRUE; PA_DEBUG(( "%s: Stream started\n", __FUNCTION__ )); error: return result; } static PaError RealStop( PaJackStream *stream, int abort ) { PaError result = paNoError; int i; if( stream->isBlockingStream ) BlockingWaitEmpty ( stream ); ASSERT_CALL( pthread_mutex_lock( &stream->hostApi->mtx ), 0 ); if( abort ) stream->doAbort = 1; else stream->doStop = 1; /* Wait for stream to be stopped */ result = WaitCondition( stream->hostApi ); ASSERT_CALL( pthread_mutex_unlock( &stream->hostApi->mtx ), 0 ); ENSURE_PA( result ); UNLESS( !stream->is_active, paInternalError ); PA_DEBUG(( "%s: Stream stopped\n", __FUNCTION__ )); error: stream->is_running = FALSE; /* Disconnect ports belonging to this stream */ if( !stream->hostApi->jackIsDown ) /* XXX: Well? */ { for( i = 0; i < stream->num_incoming_connections; i++ ) { if( jack_port_connected( stream->local_input_ports[i] ) ) { UNLESS( !jack_port_disconnect( stream->jack_client, stream->local_input_ports[i] ), paUnanticipatedHostError ); } } for( i = 0; i < stream->num_outgoing_connections; i++ ) { if( jack_port_connected( stream->local_output_ports[i] ) ) { UNLESS( !jack_port_disconnect( stream->jack_client, stream->local_output_ports[i] ), paUnanticipatedHostError ); } } } return result; } static PaError StopStream( PaStream *s ) { assert(s); return RealStop( (PaJackStream *)s, 0 ); } static PaError AbortStream( PaStream *s ) { assert(s); return RealStop( (PaJackStream *)s, 1 ); } static PaError IsStreamStopped( PaStream *s ) { PaJackStream *stream = (PaJackStream*)s; return !stream->is_running; } static PaError IsStreamActive( PaStream *s ) { PaJackStream *stream = (PaJackStream*)s; return stream->is_active; } static PaTime GetStreamTime( PaStream *s ) { PaJackStream *stream = (PaJackStream*)s; /* A: Is this relevant?? --> TODO: what if we're recording-only? */ return (jack_frame_time( stream->jack_client ) - stream->t0) / (PaTime)jack_get_sample_rate( stream->jack_client ); } static double GetStreamCpuLoad( PaStream* s ) { PaJackStream *stream = (PaJackStream*)s; return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); } PaError PaJack_SetClientName( const char* name ) { if( strlen( name ) > jack_client_name_size() ) { /* OK, I don't know any better error code */ return paInvalidFlag; } clientName_ = name; return paNoError; } PaError PaJack_GetClientName(const char** clientName) { PaError result = paNoError; PaJackHostApiRepresentation* jackHostApi = NULL; PaJackHostApiRepresentation** ref = &jackHostApi; ENSURE_PA( PaUtil_GetHostApiRepresentation( (PaUtilHostApiRepresentation**)ref, paJACK ) ); *clientName = jack_get_client_name( jackHostApi->jack_client ); error: return result; } praat-6.0.04/external/portaudio/pa_jack.h000066400000000000000000000053651261542461700203220ustar00rootroot00000000000000#ifndef PA_JACK_H #define PA_JACK_H /* * $Id: * PortAudio Portable Real-Time Audio Library * JACK-specific extensions * * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file * @ingroup public_header * @brief JACK-specific PortAudio API extension header file. */ #include "portaudio.h" #ifdef __cplusplus extern "C" { #endif /** Set the JACK client name. * * During Pa_Initialize, When PA JACK connects as a client of the JACK server, it requests a certain * name, which is for instance prepended to port names. By default this name is "PortAudio". The * JACK server may append a suffix to the client name, in order to avoid clashes among clients that * try to connect with the same name (e.g., different PA JACK clients). * * This function must be called before Pa_Initialize, otherwise it won't have any effect. Note that * the string is not copied, but instead referenced directly, so it must not be freed for as long as * PA might need it. * @sa PaJack_GetClientName */ PaError PaJack_SetClientName( const char* name ); /** Get the JACK client name used by PA JACK. * * The caller is responsible for freeing the returned pointer. */ PaError PaJack_GetClientName(const char** clientName); #ifdef __cplusplus } #endif #endif praat-6.0.04/external/portaudio/pa_linux_alsa.c000066400000000000000000005220131261542461700215360ustar00rootroot00000000000000#if defined (UNIX) && defined (ALSA) /* * $Id: pa_linux_alsa.c 1911 2013-10-17 12:44:09Z gineera $ * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * ALSA implementation by Joshua Haberman and Arve Knudsen * * Copyright (c) 2002 Joshua Haberman * Copyright (c) 2005-2009 Arve Knudsen * Copyright (c) 2008 Kevin Kofler * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostapi_src */ #define ALSA_PCM_NEW_HW_PARAMS_API #define ALSA_PCM_NEW_SW_PARAMS_API #include #undef ALSA_PCM_NEW_HW_PARAMS_API #undef ALSA_PCM_NEW_SW_PARAMS_API #include #include /* strlen() */ #include #include #include #include #include #include #include /* For sig_atomic_t */ #ifdef PA_ALSA_DYNAMIC #include /* For dlXXX functions */ #endif #include "portaudio.h" #include "pa_util.h" #include "pa_unix_util.h" #include "pa_allocation.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_cpuload.h" #include "pa_process.h" #include "pa_endianness.h" #include "pa_debugprint.h" #include "pa_linux_alsa.h" /* Add missing define (for compatibility with older ALSA versions) */ #ifndef SND_PCM_TSTAMP_ENABLE #define SND_PCM_TSTAMP_ENABLE SND_PCM_TSTAMP_MMAP #endif /* Combine version elements into a single (unsigned) integer */ #define ALSA_VERSION_INT(major, minor, subminor) ((major << 16) | (minor << 8) | subminor) /* The acceptable tolerance of sample rate set, to that requested (as a ratio, eg 50 is 2%, 100 is 1%) */ #define RATE_MAX_DEVIATE_RATIO 100 /* Defines Alsa function types and pointers to these functions. */ #define _PA_DEFINE_FUNC(x) typedef typeof(x) x##_ft; static x##_ft *alsa_##x = 0 /* Alloca helper. */ #define __alsa_snd_alloca(ptr,type) do { size_t __alsa_alloca_size = alsa_##type##_sizeof(); (*ptr) = (type##_t *) alloca(__alsa_alloca_size); memset(*ptr, 0, __alsa_alloca_size); } while (0) _PA_DEFINE_FUNC(snd_pcm_open); _PA_DEFINE_FUNC(snd_pcm_close); _PA_DEFINE_FUNC(snd_pcm_nonblock); _PA_DEFINE_FUNC(snd_pcm_frames_to_bytes); _PA_DEFINE_FUNC(snd_pcm_prepare); _PA_DEFINE_FUNC(snd_pcm_start); _PA_DEFINE_FUNC(snd_pcm_resume); _PA_DEFINE_FUNC(snd_pcm_wait); _PA_DEFINE_FUNC(snd_pcm_state); _PA_DEFINE_FUNC(snd_pcm_avail_update); _PA_DEFINE_FUNC(snd_pcm_areas_silence); _PA_DEFINE_FUNC(snd_pcm_mmap_begin); _PA_DEFINE_FUNC(snd_pcm_mmap_commit); _PA_DEFINE_FUNC(snd_pcm_readi); _PA_DEFINE_FUNC(snd_pcm_readn); _PA_DEFINE_FUNC(snd_pcm_writei); _PA_DEFINE_FUNC(snd_pcm_writen); _PA_DEFINE_FUNC(snd_pcm_drain); _PA_DEFINE_FUNC(snd_pcm_recover); _PA_DEFINE_FUNC(snd_pcm_drop); _PA_DEFINE_FUNC(snd_pcm_area_copy); _PA_DEFINE_FUNC(snd_pcm_poll_descriptors); _PA_DEFINE_FUNC(snd_pcm_poll_descriptors_count); _PA_DEFINE_FUNC(snd_pcm_poll_descriptors_revents); _PA_DEFINE_FUNC(snd_pcm_format_size); _PA_DEFINE_FUNC(snd_pcm_link); _PA_DEFINE_FUNC(snd_pcm_delay); _PA_DEFINE_FUNC(snd_pcm_hw_params_sizeof); _PA_DEFINE_FUNC(snd_pcm_hw_params_malloc); _PA_DEFINE_FUNC(snd_pcm_hw_params_free); _PA_DEFINE_FUNC(snd_pcm_hw_params_any); _PA_DEFINE_FUNC(snd_pcm_hw_params_set_access); _PA_DEFINE_FUNC(snd_pcm_hw_params_set_format); _PA_DEFINE_FUNC(snd_pcm_hw_params_set_channels); //_PA_DEFINE_FUNC(snd_pcm_hw_params_set_periods_near); _PA_DEFINE_FUNC(snd_pcm_hw_params_set_rate_near); //!!! _PA_DEFINE_FUNC(snd_pcm_hw_params_set_rate); _PA_DEFINE_FUNC(snd_pcm_hw_params_set_rate_resample); //_PA_DEFINE_FUNC(snd_pcm_hw_params_set_buffer_time_near); _PA_DEFINE_FUNC(snd_pcm_hw_params_set_buffer_size); _PA_DEFINE_FUNC(snd_pcm_hw_params_set_buffer_size_near); //!!! _PA_DEFINE_FUNC(snd_pcm_hw_params_set_buffer_size_min); //_PA_DEFINE_FUNC(snd_pcm_hw_params_set_period_time_near); _PA_DEFINE_FUNC(snd_pcm_hw_params_set_period_size_near); _PA_DEFINE_FUNC(snd_pcm_hw_params_set_periods_integer); _PA_DEFINE_FUNC(snd_pcm_hw_params_set_periods_min); _PA_DEFINE_FUNC(snd_pcm_hw_params_get_buffer_size); //_PA_DEFINE_FUNC(snd_pcm_hw_params_get_period_size); //_PA_DEFINE_FUNC(snd_pcm_hw_params_get_access); //_PA_DEFINE_FUNC(snd_pcm_hw_params_get_periods); //_PA_DEFINE_FUNC(snd_pcm_hw_params_get_rate); _PA_DEFINE_FUNC(snd_pcm_hw_params_get_channels_min); _PA_DEFINE_FUNC(snd_pcm_hw_params_get_channels_max); _PA_DEFINE_FUNC(snd_pcm_hw_params_test_period_size); _PA_DEFINE_FUNC(snd_pcm_hw_params_test_format); _PA_DEFINE_FUNC(snd_pcm_hw_params_test_access); _PA_DEFINE_FUNC(snd_pcm_hw_params_dump); _PA_DEFINE_FUNC(snd_pcm_hw_params); _PA_DEFINE_FUNC(snd_pcm_hw_params_get_periods_min); _PA_DEFINE_FUNC(snd_pcm_hw_params_get_periods_max); _PA_DEFINE_FUNC(snd_pcm_hw_params_set_period_size); _PA_DEFINE_FUNC(snd_pcm_hw_params_get_period_size_min); _PA_DEFINE_FUNC(snd_pcm_hw_params_get_period_size_max); _PA_DEFINE_FUNC(snd_pcm_hw_params_get_buffer_size_max); _PA_DEFINE_FUNC(snd_pcm_hw_params_get_rate_min); _PA_DEFINE_FUNC(snd_pcm_hw_params_get_rate_max); _PA_DEFINE_FUNC(snd_pcm_hw_params_get_rate_numden); #define alsa_snd_pcm_hw_params_alloca(ptr) __alsa_snd_alloca(ptr, snd_pcm_hw_params) _PA_DEFINE_FUNC(snd_pcm_sw_params_sizeof); _PA_DEFINE_FUNC(snd_pcm_sw_params_malloc); _PA_DEFINE_FUNC(snd_pcm_sw_params_current); _PA_DEFINE_FUNC(snd_pcm_sw_params_set_avail_min); _PA_DEFINE_FUNC(snd_pcm_sw_params); _PA_DEFINE_FUNC(snd_pcm_sw_params_free); _PA_DEFINE_FUNC(snd_pcm_sw_params_set_start_threshold); _PA_DEFINE_FUNC(snd_pcm_sw_params_set_stop_threshold); _PA_DEFINE_FUNC(snd_pcm_sw_params_get_boundary); _PA_DEFINE_FUNC(snd_pcm_sw_params_set_silence_threshold); _PA_DEFINE_FUNC(snd_pcm_sw_params_set_silence_size); _PA_DEFINE_FUNC(snd_pcm_sw_params_set_xfer_align); _PA_DEFINE_FUNC(snd_pcm_sw_params_set_tstamp_mode); #define alsa_snd_pcm_sw_params_alloca(ptr) __alsa_snd_alloca(ptr, snd_pcm_sw_params) _PA_DEFINE_FUNC(snd_pcm_info); _PA_DEFINE_FUNC(snd_pcm_info_sizeof); _PA_DEFINE_FUNC(snd_pcm_info_malloc); _PA_DEFINE_FUNC(snd_pcm_info_free); _PA_DEFINE_FUNC(snd_pcm_info_set_device); _PA_DEFINE_FUNC(snd_pcm_info_set_subdevice); _PA_DEFINE_FUNC(snd_pcm_info_set_stream); _PA_DEFINE_FUNC(snd_pcm_info_get_name); _PA_DEFINE_FUNC(snd_pcm_info_get_card); #define alsa_snd_pcm_info_alloca(ptr) __alsa_snd_alloca(ptr, snd_pcm_info) _PA_DEFINE_FUNC(snd_ctl_pcm_next_device); _PA_DEFINE_FUNC(snd_ctl_pcm_info); _PA_DEFINE_FUNC(snd_ctl_open); _PA_DEFINE_FUNC(snd_ctl_close); _PA_DEFINE_FUNC(snd_ctl_card_info_malloc); _PA_DEFINE_FUNC(snd_ctl_card_info_free); _PA_DEFINE_FUNC(snd_ctl_card_info); _PA_DEFINE_FUNC(snd_ctl_card_info_sizeof); _PA_DEFINE_FUNC(snd_ctl_card_info_get_name); #define alsa_snd_ctl_card_info_alloca(ptr) __alsa_snd_alloca(ptr, snd_ctl_card_info) _PA_DEFINE_FUNC(snd_config); _PA_DEFINE_FUNC(snd_config_update); _PA_DEFINE_FUNC(snd_config_search); _PA_DEFINE_FUNC(snd_config_iterator_entry); _PA_DEFINE_FUNC(snd_config_iterator_first); _PA_DEFINE_FUNC(snd_config_iterator_end); _PA_DEFINE_FUNC(snd_config_iterator_next); _PA_DEFINE_FUNC(snd_config_get_string); _PA_DEFINE_FUNC(snd_config_get_id); _PA_DEFINE_FUNC(snd_config_update_free_global); _PA_DEFINE_FUNC(snd_pcm_status); _PA_DEFINE_FUNC(snd_pcm_status_sizeof); _PA_DEFINE_FUNC(snd_pcm_status_get_tstamp); _PA_DEFINE_FUNC(snd_pcm_status_get_state); _PA_DEFINE_FUNC(snd_pcm_status_get_trigger_tstamp); _PA_DEFINE_FUNC(snd_pcm_status_get_delay); #define alsa_snd_pcm_status_alloca(ptr) __alsa_snd_alloca(ptr, snd_pcm_status) _PA_DEFINE_FUNC(snd_card_next); _PA_DEFINE_FUNC(snd_asoundlib_version); _PA_DEFINE_FUNC(snd_strerror); _PA_DEFINE_FUNC(snd_output_stdio_attach); #define alsa_snd_config_for_each(pos, next, node)\ for (pos = alsa_snd_config_iterator_first(node),\ next = alsa_snd_config_iterator_next(pos);\ pos != alsa_snd_config_iterator_end(node); pos = next, next = alsa_snd_config_iterator_next(pos)) #undef _PA_DEFINE_FUNC /* Redefine 'PA_ALSA_PATHNAME' to a different Alsa library name if desired. */ #ifndef PA_ALSA_PATHNAME #define PA_ALSA_PATHNAME "libasound.so" #endif static const char *g_AlsaLibName = PA_ALSA_PATHNAME; /* Handle to dynamically loaded library. */ static void *g_AlsaLib = NULL; #ifdef PA_ALSA_DYNAMIC #define _PA_LOCAL_IMPL(x) __pa_local_##x int _PA_LOCAL_IMPL(snd_pcm_hw_params_set_rate_near) (snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) { int ret; if(( ret = alsa_snd_pcm_hw_params_set_rate(pcm, params, (*val), (*dir)) ) < 0 ) return ret; return 0; } int _PA_LOCAL_IMPL(snd_pcm_hw_params_set_buffer_size_near) (snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val) { int ret; if(( ret = alsa_snd_pcm_hw_params_set_buffer_size(pcm, params, (*val)) ) < 0 ) return ret; return 0; } int _PA_LOCAL_IMPL(snd_pcm_hw_params_set_period_size_near) (snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir) { int ret; if(( ret = alsa_snd_pcm_hw_params_set_period_size(pcm, params, (*val), (*dir)) ) < 0 ) return ret; return 0; } int _PA_LOCAL_IMPL(snd_pcm_hw_params_get_channels_min) (const snd_pcm_hw_params_t *params, unsigned int *val) { (*val) = 1; return 0; } int _PA_LOCAL_IMPL(snd_pcm_hw_params_get_channels_max) (const snd_pcm_hw_params_t *params, unsigned int *val) { (*val) = 2; return 0; } int _PA_LOCAL_IMPL(snd_pcm_hw_params_get_periods_min) (const snd_pcm_hw_params_t *params, unsigned int *val, int *dir) { (*val) = 2; return 0; } int _PA_LOCAL_IMPL(snd_pcm_hw_params_get_periods_max) (const snd_pcm_hw_params_t *params, unsigned int *val, int *dir) { (*val) = 8; return 0; } int _PA_LOCAL_IMPL(snd_pcm_hw_params_get_period_size_min) (const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir) { (*frames) = 64; return 0; } int _PA_LOCAL_IMPL(snd_pcm_hw_params_get_period_size_max) (const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir) { (*frames) = 512; return 0; } int _PA_LOCAL_IMPL(snd_pcm_hw_params_get_buffer_size_max) (const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val) { int ret; int dir = 0; snd_pcm_uframes_t pmax = 0; unsigned int pcnt = 0; if(( ret = _PA_LOCAL_IMPL(snd_pcm_hw_params_get_period_size_max)(params, &pmax, &dir) ) < 0 ) return ret; if(( ret = _PA_LOCAL_IMPL(snd_pcm_hw_params_get_periods_max)(params, &pcnt, &dir) ) < 0 ) return ret; (*val) = pmax * pcnt; return 0; } int _PA_LOCAL_IMPL(snd_pcm_hw_params_get_rate_min) (const snd_pcm_hw_params_t *params, unsigned int *val, int *dir) { (*val) = 44100; return 0; } int _PA_LOCAL_IMPL(snd_pcm_hw_params_get_rate_max) (const snd_pcm_hw_params_t *params, unsigned int *val, int *dir) { (*val) = 44100; return 0; } #endif // PA_ALSA_DYNAMIC /* Trying to load Alsa library dynamically if 'PA_ALSA_DYNAMIC' is defined, othervise will link during compilation. */ static int PaAlsa_LoadLibrary() { #ifdef PA_ALSA_DYNAMIC PA_DEBUG(( "%s: loading ALSA library file - %s\n", __FUNCTION__, g_AlsaLibName )); dlerror(); g_AlsaLib = dlopen(g_AlsaLibName, (RTLD_NOW|RTLD_GLOBAL) ); if (g_AlsaLib == NULL) { PA_DEBUG(( "%s: failed dlopen() ALSA library file - %s, error: %s\n", __FUNCTION__, g_AlsaLibName, dlerror() )); return 0; } PA_DEBUG(( "%s: loading ALSA API\n", __FUNCTION__ )); #define _PA_LOAD_FUNC(x) do { \ alsa_##x = dlsym( g_AlsaLib, #x ); \ if( alsa_##x == NULL ) { \ PA_DEBUG(( "%s: symbol [%s] not found in - %s, error: %s\n", __FUNCTION__, #x, g_AlsaLibName, dlerror() )); }\ } while(0) #else #define _PA_LOAD_FUNC(x) alsa_##x = &x #endif _PA_LOAD_FUNC(snd_pcm_open); _PA_LOAD_FUNC(snd_pcm_close); _PA_LOAD_FUNC(snd_pcm_nonblock); _PA_LOAD_FUNC(snd_pcm_frames_to_bytes); _PA_LOAD_FUNC(snd_pcm_prepare); _PA_LOAD_FUNC(snd_pcm_start); _PA_LOAD_FUNC(snd_pcm_resume); _PA_LOAD_FUNC(snd_pcm_wait); _PA_LOAD_FUNC(snd_pcm_state); _PA_LOAD_FUNC(snd_pcm_avail_update); _PA_LOAD_FUNC(snd_pcm_areas_silence); _PA_LOAD_FUNC(snd_pcm_mmap_begin); _PA_LOAD_FUNC(snd_pcm_mmap_commit); _PA_LOAD_FUNC(snd_pcm_readi); _PA_LOAD_FUNC(snd_pcm_readn); _PA_LOAD_FUNC(snd_pcm_writei); _PA_LOAD_FUNC(snd_pcm_writen); _PA_LOAD_FUNC(snd_pcm_drain); _PA_LOAD_FUNC(snd_pcm_recover); _PA_LOAD_FUNC(snd_pcm_drop); _PA_LOAD_FUNC(snd_pcm_area_copy); _PA_LOAD_FUNC(snd_pcm_poll_descriptors); _PA_LOAD_FUNC(snd_pcm_poll_descriptors_count); _PA_LOAD_FUNC(snd_pcm_poll_descriptors_revents); _PA_LOAD_FUNC(snd_pcm_format_size); _PA_LOAD_FUNC(snd_pcm_link); _PA_LOAD_FUNC(snd_pcm_delay); _PA_LOAD_FUNC(snd_pcm_hw_params_sizeof); _PA_LOAD_FUNC(snd_pcm_hw_params_malloc); _PA_LOAD_FUNC(snd_pcm_hw_params_free); _PA_LOAD_FUNC(snd_pcm_hw_params_any); _PA_LOAD_FUNC(snd_pcm_hw_params_set_access); _PA_LOAD_FUNC(snd_pcm_hw_params_set_format); _PA_LOAD_FUNC(snd_pcm_hw_params_set_channels); // _PA_LOAD_FUNC(snd_pcm_hw_params_set_periods_near); _PA_LOAD_FUNC(snd_pcm_hw_params_set_rate_near); _PA_LOAD_FUNC(snd_pcm_hw_params_set_rate); _PA_LOAD_FUNC(snd_pcm_hw_params_set_rate_resample); // _PA_LOAD_FUNC(snd_pcm_hw_params_set_buffer_time_near); _PA_LOAD_FUNC(snd_pcm_hw_params_set_buffer_size); _PA_LOAD_FUNC(snd_pcm_hw_params_set_buffer_size_near); _PA_LOAD_FUNC(snd_pcm_hw_params_set_buffer_size_min); // _PA_LOAD_FUNC(snd_pcm_hw_params_set_period_time_near); _PA_LOAD_FUNC(snd_pcm_hw_params_set_period_size_near); _PA_LOAD_FUNC(snd_pcm_hw_params_set_periods_integer); _PA_LOAD_FUNC(snd_pcm_hw_params_set_periods_min); _PA_LOAD_FUNC(snd_pcm_hw_params_get_buffer_size); // _PA_LOAD_FUNC(snd_pcm_hw_params_get_period_size); // _PA_LOAD_FUNC(snd_pcm_hw_params_get_access); // _PA_LOAD_FUNC(snd_pcm_hw_params_get_periods); // _PA_LOAD_FUNC(snd_pcm_hw_params_get_rate); _PA_LOAD_FUNC(snd_pcm_hw_params_get_channels_min); _PA_LOAD_FUNC(snd_pcm_hw_params_get_channels_max); _PA_LOAD_FUNC(snd_pcm_hw_params_test_period_size); _PA_LOAD_FUNC(snd_pcm_hw_params_test_format); _PA_LOAD_FUNC(snd_pcm_hw_params_test_access); _PA_LOAD_FUNC(snd_pcm_hw_params_dump); _PA_LOAD_FUNC(snd_pcm_hw_params); _PA_LOAD_FUNC(snd_pcm_hw_params_get_periods_min); _PA_LOAD_FUNC(snd_pcm_hw_params_get_periods_max); _PA_LOAD_FUNC(snd_pcm_hw_params_set_period_size); _PA_LOAD_FUNC(snd_pcm_hw_params_get_period_size_min); _PA_LOAD_FUNC(snd_pcm_hw_params_get_period_size_max); _PA_LOAD_FUNC(snd_pcm_hw_params_get_buffer_size_max); _PA_LOAD_FUNC(snd_pcm_hw_params_get_rate_min); _PA_LOAD_FUNC(snd_pcm_hw_params_get_rate_max); _PA_LOAD_FUNC(snd_pcm_hw_params_get_rate_numden); _PA_LOAD_FUNC(snd_pcm_sw_params_sizeof); _PA_LOAD_FUNC(snd_pcm_sw_params_malloc); _PA_LOAD_FUNC(snd_pcm_sw_params_current); _PA_LOAD_FUNC(snd_pcm_sw_params_set_avail_min); _PA_LOAD_FUNC(snd_pcm_sw_params); _PA_LOAD_FUNC(snd_pcm_sw_params_free); _PA_LOAD_FUNC(snd_pcm_sw_params_set_start_threshold); _PA_LOAD_FUNC(snd_pcm_sw_params_set_stop_threshold); _PA_LOAD_FUNC(snd_pcm_sw_params_get_boundary); _PA_LOAD_FUNC(snd_pcm_sw_params_set_silence_threshold); _PA_LOAD_FUNC(snd_pcm_sw_params_set_silence_size); _PA_LOAD_FUNC(snd_pcm_sw_params_set_xfer_align); _PA_LOAD_FUNC(snd_pcm_sw_params_set_tstamp_mode); _PA_LOAD_FUNC(snd_pcm_info); _PA_LOAD_FUNC(snd_pcm_info_sizeof); _PA_LOAD_FUNC(snd_pcm_info_malloc); _PA_LOAD_FUNC(snd_pcm_info_free); _PA_LOAD_FUNC(snd_pcm_info_set_device); _PA_LOAD_FUNC(snd_pcm_info_set_subdevice); _PA_LOAD_FUNC(snd_pcm_info_set_stream); _PA_LOAD_FUNC(snd_pcm_info_get_name); _PA_LOAD_FUNC(snd_pcm_info_get_card); _PA_LOAD_FUNC(snd_ctl_pcm_next_device); _PA_LOAD_FUNC(snd_ctl_pcm_info); _PA_LOAD_FUNC(snd_ctl_open); _PA_LOAD_FUNC(snd_ctl_close); _PA_LOAD_FUNC(snd_ctl_card_info_malloc); _PA_LOAD_FUNC(snd_ctl_card_info_free); _PA_LOAD_FUNC(snd_ctl_card_info); _PA_LOAD_FUNC(snd_ctl_card_info_sizeof); _PA_LOAD_FUNC(snd_ctl_card_info_get_name); _PA_LOAD_FUNC(snd_config); _PA_LOAD_FUNC(snd_config_update); _PA_LOAD_FUNC(snd_config_search); _PA_LOAD_FUNC(snd_config_iterator_entry); _PA_LOAD_FUNC(snd_config_iterator_first); _PA_LOAD_FUNC(snd_config_iterator_end); _PA_LOAD_FUNC(snd_config_iterator_next); _PA_LOAD_FUNC(snd_config_get_string); _PA_LOAD_FUNC(snd_config_get_id); _PA_LOAD_FUNC(snd_config_update_free_global); _PA_LOAD_FUNC(snd_pcm_status); _PA_LOAD_FUNC(snd_pcm_status_sizeof); _PA_LOAD_FUNC(snd_pcm_status_get_tstamp); _PA_LOAD_FUNC(snd_pcm_status_get_state); _PA_LOAD_FUNC(snd_pcm_status_get_trigger_tstamp); _PA_LOAD_FUNC(snd_pcm_status_get_delay); _PA_LOAD_FUNC(snd_card_next); _PA_LOAD_FUNC(snd_asoundlib_version); _PA_LOAD_FUNC(snd_strerror); _PA_LOAD_FUNC(snd_output_stdio_attach); #undef _PA_LOAD_FUNC #ifdef PA_ALSA_DYNAMIC PA_DEBUG(( "%s: loaded ALSA API - ok\n", __FUNCTION__ )); #define _PA_VALIDATE_LOAD_REPLACEMENT(x)\ do {\ if( alsa_##x == NULL )\ {\ alsa_##x = &_PA_LOCAL_IMPL(x);\ PA_DEBUG(( "%s: replacing [%s] with local implementation\n", __FUNCTION__, #x ));\ }\ } while (0) _PA_VALIDATE_LOAD_REPLACEMENT(snd_pcm_hw_params_set_rate_near); _PA_VALIDATE_LOAD_REPLACEMENT(snd_pcm_hw_params_set_buffer_size_near); _PA_VALIDATE_LOAD_REPLACEMENT(snd_pcm_hw_params_set_period_size_near); _PA_VALIDATE_LOAD_REPLACEMENT(snd_pcm_hw_params_get_channels_min); _PA_VALIDATE_LOAD_REPLACEMENT(snd_pcm_hw_params_get_channels_max); _PA_VALIDATE_LOAD_REPLACEMENT(snd_pcm_hw_params_get_periods_min); _PA_VALIDATE_LOAD_REPLACEMENT(snd_pcm_hw_params_get_periods_max); _PA_VALIDATE_LOAD_REPLACEMENT(snd_pcm_hw_params_get_period_size_min); _PA_VALIDATE_LOAD_REPLACEMENT(snd_pcm_hw_params_get_period_size_max); _PA_VALIDATE_LOAD_REPLACEMENT(snd_pcm_hw_params_get_buffer_size_max); _PA_VALIDATE_LOAD_REPLACEMENT(snd_pcm_hw_params_get_rate_min); _PA_VALIDATE_LOAD_REPLACEMENT(snd_pcm_hw_params_get_rate_max); #undef _PA_LOCAL_IMPL #undef _PA_VALIDATE_LOAD_REPLACEMENT #endif // PA_ALSA_DYNAMIC return 1; } void PaAlsa_SetLibraryPathName( const char *pathName ) { #ifdef PA_ALSA_DYNAMIC g_AlsaLibName = pathName; #else (void)pathName; #endif } /* Close handle to Alsa library. */ static void PaAlsa_CloseLibrary() { #ifdef PA_ALSA_DYNAMIC dlclose(g_AlsaLib); g_AlsaLib = NULL; #endif } /* Check return value of ALSA function, and map it to PaError */ #define ENSURE_(expr, code) \ do { \ int __pa_unsure_error_id;\ if( UNLIKELY( (__pa_unsure_error_id = (expr)) < 0 ) ) \ { \ /* PaUtil_SetLastHostErrorInfo should only be used in the main thread */ \ if( (code) == paUnanticipatedHostError && pthread_equal( pthread_self(), paUnixMainThread) ) \ { \ PaUtil_SetLastHostErrorInfo( paALSA, __pa_unsure_error_id, alsa_snd_strerror( __pa_unsure_error_id ) ); \ } \ PaUtil_DebugPrint( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" ); \ if( (code) == paUnanticipatedHostError ) \ PA_DEBUG(( "Host error description: %s\n", alsa_snd_strerror( __pa_unsure_error_id ) )); \ result = (code); \ goto error; \ } \ } while (0) #define ASSERT_CALL_(expr, success) \ do {\ int __pa_assert_error_id;\ __pa_assert_error_id = (expr);\ assert( success == __pa_assert_error_id );\ } while (0) static int numPeriods_ = 4; static int busyRetries_ = 100; int PaAlsa_SetNumPeriods( int numPeriods ) { numPeriods_ = numPeriods; return paNoError; } typedef enum { StreamDirection_In, StreamDirection_Out } StreamDirection; typedef struct { PaSampleFormat hostSampleFormat; int numUserChannels, numHostChannels; int userInterleaved, hostInterleaved; int canMmap; void *nonMmapBuffer; unsigned int nonMmapBufferSize; PaDeviceIndex device; /* Keep the device index */ int deviceIsPlug; /* Distinguish plug types from direct 'hw:' devices */ int useReventFix; /* Alsa older than 1.0.16, plug devices need a fix */ snd_pcm_t *pcm; snd_pcm_uframes_t framesPerPeriod, alsaBufferSize; snd_pcm_format_t nativeFormat; unsigned int nfds; int ready; /* Marked ready from poll */ void **userBuffers; snd_pcm_uframes_t offset; StreamDirection streamDir; snd_pcm_channel_area_t *channelAreas; /* Needed for channel adaption */ } PaAlsaStreamComponent; /* Implementation specific stream structure */ typedef struct PaAlsaStream { PaUtilStreamRepresentation streamRepresentation; PaUtilCpuLoadMeasurer cpuLoadMeasurer; PaUtilBufferProcessor bufferProcessor; PaUnixThread thread; unsigned long framesPerUserBuffer, maxFramesPerHostBuffer; int primeBuffers; int callbackMode; /* bool: are we running in callback mode? */ int pcmsSynced; /* Have we successfully synced pcms */ int rtSched; /* the callback thread uses these to poll the sound device(s), waiting * for data to be ready/available */ struct pollfd* pfds; int pollTimeout; /* Used in communication between threads */ volatile sig_atomic_t callback_finished; /* bool: are we in the "callback finished" state? */ volatile sig_atomic_t callbackAbort; /* Drop frames? */ volatile sig_atomic_t isActive; /* Is stream in active state? (Between StartStream and StopStream || !paContinue) */ PaUnixMutex stateMtx; /* Used to synchronize access to stream state */ int neverDropInput; PaTime underrun; PaTime overrun; PaAlsaStreamComponent capture, playback; } PaAlsaStream; /* PaAlsaHostApiRepresentation - host api datastructure specific to this implementation */ typedef struct PaAlsaHostApiRepresentation { PaUtilHostApiRepresentation baseHostApiRep; PaUtilStreamInterface callbackStreamInterface; PaUtilStreamInterface blockingStreamInterface; PaUtilAllocationGroup *allocations; PaHostApiIndex hostApiIndex; PaUint32 alsaLibVersion; /* Retrieved from the library at run-time */ } PaAlsaHostApiRepresentation; typedef struct PaAlsaDeviceInfo { PaDeviceInfo baseDeviceInfo; char *alsaName; int isPlug; int minInputChannels; int minOutputChannels; } PaAlsaDeviceInfo; /* prototypes for functions declared in this file */ static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *callback, void *userData ); static PaError CloseStream( PaStream* stream ); static PaError StartStream( PaStream *stream ); static PaError StopStream( PaStream *stream ); static PaError AbortStream( PaStream *stream ); static PaError IsStreamStopped( PaStream *s ); static PaError IsStreamActive( PaStream *stream ); static PaTime GetStreamTime( PaStream *stream ); static double GetStreamCpuLoad( PaStream* stream ); static PaError BuildDeviceList( PaAlsaHostApiRepresentation *hostApi ); static int SetApproximateSampleRate( snd_pcm_t *pcm, snd_pcm_hw_params_t *hwParams, double sampleRate ); static int GetExactSampleRate( snd_pcm_hw_params_t *hwParams, double *sampleRate ); static PaUint32 PaAlsaVersionNum(void); /* Callback prototypes */ static void *CallbackThreadFunc( void *userData ); /* Blocking prototypes */ static signed long GetStreamReadAvailable( PaStream* s ); static signed long GetStreamWriteAvailable( PaStream* s ); static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ); static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ); static const PaAlsaDeviceInfo *GetDeviceInfo( const PaUtilHostApiRepresentation *hostApi, int device ) { return (const PaAlsaDeviceInfo *)hostApi->deviceInfos[device]; } /** Uncommented because AlsaErrorHandler is unused for anything good yet. If AlsaErrorHandler is to be used, do not forget to register this callback in PaAlsa_Initialize, and unregister in Terminate. */ /*static void AlsaErrorHandler(const char *file, int line, const char *function, int err, const char *fmt, ...) { }*/ PaError PaAlsa_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) { PaError result = paNoError; PaAlsaHostApiRepresentation *alsaHostApi = NULL; /* Try loading Alsa library. */ if (!PaAlsa_LoadLibrary()) return paHostApiNotFound; PA_UNLESS( alsaHostApi = (PaAlsaHostApiRepresentation*) PaUtil_AllocateMemory( sizeof(PaAlsaHostApiRepresentation) ), paInsufficientMemory ); PA_UNLESS( alsaHostApi->allocations = PaUtil_CreateAllocationGroup(), paInsufficientMemory ); alsaHostApi->hostApiIndex = hostApiIndex; alsaHostApi->alsaLibVersion = PaAlsaVersionNum(); *hostApi = (PaUtilHostApiRepresentation*)alsaHostApi; (*hostApi)->info.structVersion = 1; (*hostApi)->info.type = paALSA; (*hostApi)->info.name = "ALSA"; (*hostApi)->Terminate = Terminate; (*hostApi)->OpenStream = OpenStream; (*hostApi)->IsFormatSupported = IsFormatSupported; /** If AlsaErrorHandler is to be used, do not forget to unregister callback pointer in Terminate function. */ /*ENSURE_( snd_lib_error_set_handler(AlsaErrorHandler), paUnanticipatedHostError );*/ PA_ENSURE( BuildDeviceList( alsaHostApi ) ); PaUtil_InitializeStreamInterface( &alsaHostApi->callbackStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, GetStreamCpuLoad, PaUtil_DummyRead, PaUtil_DummyWrite, PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); PaUtil_InitializeStreamInterface( &alsaHostApi->blockingStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, PaUtil_DummyGetCpuLoad, ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable ); PA_ENSURE( PaUnixThreading_Initialize() ); return result; error: if( alsaHostApi ) { if( alsaHostApi->allocations ) { PaUtil_FreeAllAllocations( alsaHostApi->allocations ); PaUtil_DestroyAllocationGroup( alsaHostApi->allocations ); } PaUtil_FreeMemory( alsaHostApi ); } return result; } static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) { PaAlsaHostApiRepresentation *alsaHostApi = (PaAlsaHostApiRepresentation*)hostApi; assert( hostApi ); /** See AlsaErrorHandler and PaAlsa_Initialize for details. */ /*snd_lib_error_set_handler(NULL);*/ if( alsaHostApi->allocations ) { PaUtil_FreeAllAllocations( alsaHostApi->allocations ); PaUtil_DestroyAllocationGroup( alsaHostApi->allocations ); } PaUtil_FreeMemory( alsaHostApi ); alsa_snd_config_update_free_global(); /* Close Alsa library. */ PaAlsa_CloseLibrary(); } /** Determine max channels and default latencies. * * This function provides functionality to grope an opened (might be opened for capture or playback) pcm device for * traits like max channels, suitable default latencies and default sample rate. Upon error, max channels is set to zero, * and a suitable result returned. The device is closed before returning. */ static PaError GropeDevice( snd_pcm_t* pcm, int isPlug, StreamDirection mode, int openBlocking, PaAlsaDeviceInfo* devInfo ) { PaError result = paNoError; snd_pcm_hw_params_t *hwParams; snd_pcm_uframes_t alsaBufferFrames, alsaPeriodFrames; unsigned int minChans, maxChans; int* minChannels, * maxChannels; double * defaultLowLatency, * defaultHighLatency, * defaultSampleRate = &devInfo->baseDeviceInfo.defaultSampleRate; double defaultSr = *defaultSampleRate; int dir; assert( pcm ); PA_DEBUG(( "%s: collecting info ..\n", __FUNCTION__ )); if( StreamDirection_In == mode ) { minChannels = &devInfo->minInputChannels; maxChannels = &devInfo->baseDeviceInfo.maxInputChannels; defaultLowLatency = &devInfo->baseDeviceInfo.defaultLowInputLatency; defaultHighLatency = &devInfo->baseDeviceInfo.defaultHighInputLatency; } else { minChannels = &devInfo->minOutputChannels; maxChannels = &devInfo->baseDeviceInfo.maxOutputChannels; defaultLowLatency = &devInfo->baseDeviceInfo.defaultLowOutputLatency; defaultHighLatency = &devInfo->baseDeviceInfo.defaultHighOutputLatency; } ENSURE_( alsa_snd_pcm_nonblock( pcm, 0 ), paUnanticipatedHostError ); alsa_snd_pcm_hw_params_alloca( &hwParams ); alsa_snd_pcm_hw_params_any( pcm, hwParams ); if( defaultSr >= 0 ) { /* Could be that the device opened in one mode supports samplerates that the other mode wont have, * so try again .. */ if( SetApproximateSampleRate( pcm, hwParams, defaultSr ) < 0 ) { defaultSr = -1.; alsa_snd_pcm_hw_params_any( pcm, hwParams ); /* Clear any params (rate) that might have been set */ PA_DEBUG(( "%s: Original default samplerate failed, trying again ..\n", __FUNCTION__ )); } } if( defaultSr < 0. ) /* Default sample rate not set */ { unsigned int sampleRate = 44100; /* Will contain approximate rate returned by alsa-lib */ /* Don't allow rate resampling when probing for the default rate (but ignore if this call fails) */ alsa_snd_pcm_hw_params_set_rate_resample( pcm, hwParams, 0 ); if( alsa_snd_pcm_hw_params_set_rate_near( pcm, hwParams, &sampleRate, NULL ) < 0 ) { result = paUnanticipatedHostError; goto error; } ENSURE_( GetExactSampleRate( hwParams, &defaultSr ), paUnanticipatedHostError ); } ENSURE_( alsa_snd_pcm_hw_params_get_channels_min( hwParams, &minChans ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_get_channels_max( hwParams, &maxChans ), paUnanticipatedHostError ); assert( maxChans <= INT_MAX ); assert( maxChans > 0 ); /* Weird linking issue could cause wrong version of ALSA symbols to be called, resulting in zeroed values */ /* XXX: Limit to sensible number (ALSA plugins accept a crazy amount of channels)? */ if( isPlug && maxChans > 128 ) { maxChans = 128; PA_DEBUG(( "%s: Limiting number of plugin channels to %u\n", __FUNCTION__, maxChans )); } /* TWEAKME: * Giving values for default min and max latency is not straightforward. * * for low latency, we want to give the lowest value that will work reliably. * This varies based on the sound card, kernel, CPU, etc. Better to give * sub-optimal latency than to give a number too low and cause dropouts. * * for high latency we want to give a large enough value that dropouts are basically impossible. * This doesn't really require as much tweaking, since providing too large a number will * just cause us to select the nearest setting that will work at stream config time. */ /* Try low latency values, (sometimes the buffer & period that result are larger) */ alsaBufferFrames = 512; alsaPeriodFrames = 128; ENSURE_( alsa_snd_pcm_hw_params_set_buffer_size_near( pcm, hwParams, &alsaBufferFrames ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( pcm, hwParams, &alsaPeriodFrames, &dir ), paUnanticipatedHostError ); *defaultLowLatency = (double) (alsaBufferFrames - alsaPeriodFrames) / defaultSr; /* Base the high latency case on values four times larger */ alsaBufferFrames = 2048; alsaPeriodFrames = 512; /* Have to reset hwParams, to set new buffer size; need to also set sample rate again */ ENSURE_( alsa_snd_pcm_hw_params_any( pcm, hwParams ), paUnanticipatedHostError ); ENSURE_( SetApproximateSampleRate( pcm, hwParams, defaultSr ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_set_buffer_size_near( pcm, hwParams, &alsaBufferFrames ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( pcm, hwParams, &alsaPeriodFrames, &dir ), paUnanticipatedHostError ); *defaultHighLatency = (double) (alsaBufferFrames - alsaPeriodFrames) / defaultSr; *minChannels = (int)minChans; *maxChannels = (int)maxChans; *defaultSampleRate = defaultSr; end: alsa_snd_pcm_close( pcm ); return result; error: goto end; } /* Initialize device info with invalid values (maxInputChannels and maxOutputChannels are set to zero since these indicate * whether input/output is available) */ static void InitializeDeviceInfo( PaDeviceInfo *deviceInfo ) { deviceInfo->structVersion = -1; deviceInfo->name = NULL; deviceInfo->hostApi = -1; deviceInfo->maxInputChannels = 0; deviceInfo->maxOutputChannels = 0; deviceInfo->defaultLowInputLatency = -1.; deviceInfo->defaultLowOutputLatency = -1.; deviceInfo->defaultHighInputLatency = -1.; deviceInfo->defaultHighOutputLatency = -1.; deviceInfo->defaultSampleRate = -1.; } /* Retrieve the version of the runtime Alsa-lib, as a single number equivalent to * SND_LIB_VERSION. Only a version string is available ("a.b.c") so this has to be converted. * Assume 'a' and 'b' are single digits only. */ static PaUint32 PaAlsaVersionNum(void) { char* verStr; PaUint32 verNum; verStr = (char*) alsa_snd_asoundlib_version(); verNum = ALSA_VERSION_INT( atoi(verStr), atoi(verStr + 2), atoi(verStr + 4) ); PA_DEBUG(( "ALSA version (build): " SND_LIB_VERSION_STR "\nALSA version (runtime): %s\n", verStr )); return verNum; } /* Helper struct */ typedef struct { char *alsaName; char *name; int isPlug; int hasPlayback; int hasCapture; } HwDevInfo; HwDevInfo predefinedNames[] = { { "center_lfe", NULL, 0, 1, 0 }, /* { "default", NULL, 0, 1, 1 }, */ { "dmix", NULL, 0, 1, 0 }, /* { "dpl", NULL, 0, 1, 0 }, */ /* { "dsnoop", NULL, 0, 0, 1 }, */ { "front", NULL, 0, 1, 0 }, { "iec958", NULL, 0, 1, 0 }, /* { "modem", NULL, 0, 1, 0 }, */ { "rear", NULL, 0, 1, 0 }, { "side", NULL, 0, 1, 0 }, /* { "spdif", NULL, 0, 0, 0 }, */ { "surround40", NULL, 0, 1, 0 }, { "surround41", NULL, 0, 1, 0 }, { "surround50", NULL, 0, 1, 0 }, { "surround51", NULL, 0, 1, 0 }, { "surround71", NULL, 0, 1, 0 }, { "AndroidPlayback_Earpiece_normal", NULL, 0, 1, 0 }, { "AndroidPlayback_Speaker_normal", NULL, 0, 1, 0 }, { "AndroidPlayback_Bluetooth_normal", NULL, 0, 1, 0 }, { "AndroidPlayback_Headset_normal", NULL, 0, 1, 0 }, { "AndroidPlayback_Speaker_Headset_normal", NULL, 0, 1, 0 }, { "AndroidPlayback_Bluetooth-A2DP_normal", NULL, 0, 1, 0 }, { "AndroidPlayback_ExtraDockSpeaker_normal", NULL, 0, 1, 0 }, { "AndroidPlayback_TvOut_normal", NULL, 0, 1, 0 }, { "AndroidRecord_Microphone", NULL, 0, 0, 1 }, { "AndroidRecord_Earpiece_normal", NULL, 0, 0, 1 }, { "AndroidRecord_Speaker_normal", NULL, 0, 0, 1 }, { "AndroidRecord_Headset_normal", NULL, 0, 0, 1 }, { "AndroidRecord_Bluetooth_normal", NULL, 0, 0, 1 }, { "AndroidRecord_Speaker_Headset_normal", NULL, 0, 0, 1 }, { NULL, NULL, 0, 1, 0 } }; static const HwDevInfo *FindDeviceName( const char *name ) { int i; for( i = 0; predefinedNames[i].alsaName; i++ ) { if( strcmp( name, predefinedNames[i].alsaName ) == 0 ) { return &predefinedNames[i]; } } return NULL; } static PaError PaAlsa_StrDup( PaAlsaHostApiRepresentation *alsaApi, char **dst, const char *src) { PaError result = paNoError; int len = strlen( src ) + 1; /* PA_DEBUG(("PaStrDup %s %d\n", src, len)); */ PA_UNLESS( *dst = (char *)PaUtil_GroupAllocateMemory( alsaApi->allocations, len ), paInsufficientMemory ); strncpy( *dst, src, len ); error: return result; } /* Disregard some standard plugins */ static int IgnorePlugin( const char *pluginId ) { static const char *ignoredPlugins[] = {"hw", "plughw", "plug", "dsnoop", "tee", "file", "null", "shm", "cards", "rate_convert", NULL}; int i = 0; while( ignoredPlugins[i] ) { if( !strcmp( pluginId, ignoredPlugins[i] ) ) { return 1; } ++i; } return 0; } /* Skip past parts at the beginning of a (pcm) info name that are already in the card name, to avoid duplication */ static char *SkipCardDetailsInName( char *infoSkipName, char *cardRefName ) { char *lastSpacePosn = infoSkipName; /* Skip matching chars; but only in chunks separated by ' ' (not part words etc), so track lastSpacePosn */ while( *cardRefName ) { while( *infoSkipName && *cardRefName && *infoSkipName == *cardRefName) { infoSkipName++; cardRefName++; if( *infoSkipName == ' ' || *infoSkipName == '\0' ) lastSpacePosn = infoSkipName; } infoSkipName = lastSpacePosn; /* Look for another chunk; post-increment means ends pointing to next char */ while( *cardRefName && ( *cardRefName++ != ' ' )); } if( *infoSkipName == '\0' ) return "-"; /* The 2 names were identical; instead of a nul-string, return a marker string */ /* Now want to move to the first char after any spaces */ while( *lastSpacePosn && *lastSpacePosn == ' ' ) lastSpacePosn++; /* Skip a single separator char if present in the remaining pcm name; (pa will add its own) */ if(( *lastSpacePosn == '-' || *lastSpacePosn == ':' ) && *(lastSpacePosn + 1) == ' ' ) lastSpacePosn += 2; return lastSpacePosn; } /** Open PCM device. * * Wrapper around alsa_snd_pcm_open which may repeatedly retry opening a device if it is busy, for * a certain time. This is because dmix may temporarily hold on to a device after it (dmix) * has been opened and closed. * @param mode: Open mode (e.g., SND_PCM_BLOCKING). * @param waitOnBusy: Retry opening busy device for up to one second? **/ static int OpenPcm( snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t stream, int mode, int waitOnBusy ) { int ret, tries = 0, maxTries = waitOnBusy ? busyRetries_ : 0; ret = alsa_snd_pcm_open( pcmp, name, stream, mode ); for( tries = 0; tries < maxTries && -EBUSY == ret; ++tries ) { Pa_Sleep( 10 ); ret = alsa_snd_pcm_open( pcmp, name, stream, mode ); if( -EBUSY != ret ) { PA_DEBUG(( "%s: Successfully opened initially busy device after %d tries\n", __FUNCTION__, tries )); } } if( -EBUSY == ret ) { PA_DEBUG(( "%s: Failed to open busy device '%s'\n", __FUNCTION__, name )); } else { if( ret < 0 ) PA_DEBUG(( "%s: Opened device '%s' ptr[%p] - result: [%d:%s]\n", __FUNCTION__, name, *pcmp, ret, alsa_snd_strerror(ret) )); } return ret; } static PaError FillInDevInfo( PaAlsaHostApiRepresentation *alsaApi, HwDevInfo* deviceHwInfo, int blocking, PaAlsaDeviceInfo* devInfo, int* devIdx ) { PaError result = 0; PaDeviceInfo *baseDeviceInfo = &devInfo->baseDeviceInfo; snd_pcm_t *pcm = NULL; PaUtilHostApiRepresentation *baseApi = &alsaApi->baseHostApiRep; PA_DEBUG(( "%s: Filling device info for: %s\n", __FUNCTION__, deviceHwInfo->name )); /* Zero fields */ InitializeDeviceInfo( baseDeviceInfo ); /* To determine device capabilities, we must open the device and query the * hardware parameter configuration space */ /* Query capture */ if( deviceHwInfo->hasCapture && OpenPcm( &pcm, deviceHwInfo->alsaName, SND_PCM_STREAM_CAPTURE, blocking, 0 ) >= 0 ) { if( GropeDevice( pcm, deviceHwInfo->isPlug, StreamDirection_In, blocking, devInfo ) != paNoError ) { /* Error */ PA_DEBUG(( "%s: Failed groping %s for capture\n", __FUNCTION__, deviceHwInfo->alsaName )); goto end; } } /* Query playback */ if( deviceHwInfo->hasPlayback && OpenPcm( &pcm, deviceHwInfo->alsaName, SND_PCM_STREAM_PLAYBACK, blocking, 0 ) >= 0 ) { if( GropeDevice( pcm, deviceHwInfo->isPlug, StreamDirection_Out, blocking, devInfo ) != paNoError ) { /* Error */ PA_DEBUG(( "%s: Failed groping %s for playback\n", __FUNCTION__, deviceHwInfo->alsaName )); goto end; } } baseDeviceInfo->structVersion = 2; baseDeviceInfo->hostApi = alsaApi->hostApiIndex; baseDeviceInfo->name = deviceHwInfo->name; devInfo->alsaName = deviceHwInfo->alsaName; devInfo->isPlug = deviceHwInfo->isPlug; /* A: Storing pointer to PaAlsaDeviceInfo object as pointer to PaDeviceInfo object. * Should now be safe to add device info, unless the device supports neither capture nor playback */ if( baseDeviceInfo->maxInputChannels > 0 || baseDeviceInfo->maxOutputChannels > 0 ) { /* Make device default if there isn't already one or it is the ALSA "default" device */ if( ( baseApi->info.defaultInputDevice == paNoDevice || !strcmp( deviceHwInfo->alsaName, "default" ) ) && baseDeviceInfo->maxInputChannels > 0 ) { baseApi->info.defaultInputDevice = *devIdx; PA_DEBUG(( "Default input device: %s\n", deviceHwInfo->name )); } if( ( baseApi->info.defaultOutputDevice == paNoDevice || !strcmp( deviceHwInfo->alsaName, "default" ) ) && baseDeviceInfo->maxOutputChannels > 0 ) { baseApi->info.defaultOutputDevice = *devIdx; PA_DEBUG(( "Default output device: %s\n", deviceHwInfo->name )); } PA_DEBUG(( "%s: Adding device %s: %d\n", __FUNCTION__, deviceHwInfo->name, *devIdx )); baseApi->deviceInfos[*devIdx] = (PaDeviceInfo *) devInfo; (*devIdx) += 1; } else { PA_DEBUG(( "%s: Skipped device: %s, all channels == 0\n", __FUNCTION__, deviceHwInfo->name )); } end: return result; } /* Build PaDeviceInfo list, ignore devices for which we cannot determine capabilities (possibly busy, sigh) */ static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi ) { PaUtilHostApiRepresentation *baseApi = &alsaApi->baseHostApiRep; PaAlsaDeviceInfo *deviceInfoArray; int cardIdx = -1, devIdx = 0; snd_ctl_card_info_t *cardInfo; PaError result = paNoError; size_t numDeviceNames = 0, maxDeviceNames = 1, i; HwDevInfo *hwDevInfos = NULL; snd_config_t *topNode = NULL; snd_pcm_info_t *pcmInfo; int res; int blocking = SND_PCM_NONBLOCK; int usePlughw = 0; char *hwPrefix = ""; char alsaCardName[50]; #ifdef PA_ENABLE_DEBUG_OUTPUT PaTime startTime = PaUtil_GetTime(); #endif if( getenv( "PA_ALSA_INITIALIZE_BLOCK" ) && atoi( getenv( "PA_ALSA_INITIALIZE_BLOCK" ) ) ) blocking = 0; /* If PA_ALSA_PLUGHW is 1 (non-zero), use the plughw: pcm throughout instead of hw: */ if( getenv( "PA_ALSA_PLUGHW" ) && atoi( getenv( "PA_ALSA_PLUGHW" ) ) ) { usePlughw = 1; hwPrefix = "plug"; PA_DEBUG(( "%s: Using Plughw\n", __FUNCTION__ )); } /* These two will be set to the first working input and output device, respectively */ baseApi->info.defaultInputDevice = paNoDevice; baseApi->info.defaultOutputDevice = paNoDevice; /* Gather info about hw devices * alsa_snd_card_next() modifies the integer passed to it to be: * the index of the first card if the parameter is -1 * the index of the next card if the parameter is the index of a card * -1 if there are no more cards * * The function itself returns 0 if it succeeded. */ cardIdx = -1; alsa_snd_ctl_card_info_alloca( &cardInfo ); alsa_snd_pcm_info_alloca( &pcmInfo ); while( alsa_snd_card_next( &cardIdx ) == 0 && cardIdx >= 0 ) { char *cardName; int devIdx = -1; snd_ctl_t *ctl; char buf[50]; snprintf( alsaCardName, sizeof (alsaCardName), "hw:%d", cardIdx ); /* Acquire name of card */ if( alsa_snd_ctl_open( &ctl, alsaCardName, 0 ) < 0 ) { /* Unable to open card :( */ PA_DEBUG(( "%s: Unable to open device %s\n", __FUNCTION__, alsaCardName )); continue; } alsa_snd_ctl_card_info( ctl, cardInfo ); PA_ENSURE( PaAlsa_StrDup( alsaApi, &cardName, alsa_snd_ctl_card_info_get_name( cardInfo )) ); while( alsa_snd_ctl_pcm_next_device( ctl, &devIdx ) == 0 && devIdx >= 0 ) { char *alsaDeviceName, *deviceName, *infoName; size_t len; int hasPlayback = 0, hasCapture = 0; snprintf( buf, sizeof (buf), "%s%s,%d", hwPrefix, alsaCardName, devIdx ); /* Obtain info about this particular device */ alsa_snd_pcm_info_set_device( pcmInfo, devIdx ); alsa_snd_pcm_info_set_subdevice( pcmInfo, 0 ); alsa_snd_pcm_info_set_stream( pcmInfo, SND_PCM_STREAM_CAPTURE ); if( alsa_snd_ctl_pcm_info( ctl, pcmInfo ) >= 0 ) { hasCapture = 1; } alsa_snd_pcm_info_set_stream( pcmInfo, SND_PCM_STREAM_PLAYBACK ); if( alsa_snd_ctl_pcm_info( ctl, pcmInfo ) >= 0 ) { hasPlayback = 1; } if( !hasPlayback && !hasCapture ) { /* Error */ continue; } infoName = SkipCardDetailsInName( (char *)alsa_snd_pcm_info_get_name( pcmInfo ), cardName ); /* The length of the string written by snprintf plus terminating 0 */ len = snprintf( NULL, 0, "%s: %s (%s)", cardName, infoName, buf ) + 1; PA_UNLESS( deviceName = (char *)PaUtil_GroupAllocateMemory( alsaApi->allocations, len ), paInsufficientMemory ); snprintf( deviceName, len, "%s: %s (%s)", cardName, infoName, buf ); ++numDeviceNames; if( !hwDevInfos || numDeviceNames > maxDeviceNames ) { maxDeviceNames *= 2; PA_UNLESS( hwDevInfos = (HwDevInfo *) realloc( hwDevInfos, maxDeviceNames * sizeof (HwDevInfo) ), paInsufficientMemory ); } PA_ENSURE( PaAlsa_StrDup( alsaApi, &alsaDeviceName, buf ) ); hwDevInfos[ numDeviceNames - 1 ].alsaName = alsaDeviceName; hwDevInfos[ numDeviceNames - 1 ].name = deviceName; hwDevInfos[ numDeviceNames - 1 ].isPlug = usePlughw; hwDevInfos[ numDeviceNames - 1 ].hasPlayback = hasPlayback; hwDevInfos[ numDeviceNames - 1 ].hasCapture = hasCapture; } alsa_snd_ctl_close( ctl ); } /* Iterate over plugin devices */ if( NULL == (*alsa_snd_config) ) { /* alsa_snd_config_update is called implicitly by some functions, if this hasn't happened snd_config will be NULL (bleh) */ ENSURE_( alsa_snd_config_update(), paUnanticipatedHostError ); PA_DEBUG(( "Updating snd_config\n" )); } assert( *alsa_snd_config ); if( ( res = alsa_snd_config_search( *alsa_snd_config, "pcm", &topNode ) ) >= 0 ) { snd_config_iterator_t i, next; alsa_snd_config_for_each( i, next, topNode ) { const char *tpStr = "unknown", *idStr = NULL; int err = 0; char *alsaDeviceName, *deviceName; const HwDevInfo *predefined = NULL; snd_config_t *n = alsa_snd_config_iterator_entry( i ), * tp = NULL;; if( (err = alsa_snd_config_search( n, "type", &tp )) < 0 ) { if( -ENOENT != err ) { ENSURE_(err, paUnanticipatedHostError); } } else { ENSURE_( alsa_snd_config_get_string( tp, &tpStr ), paUnanticipatedHostError ); } ENSURE_( alsa_snd_config_get_id( n, &idStr ), paUnanticipatedHostError ); if( IgnorePlugin( idStr ) ) { PA_DEBUG(( "%s: Ignoring ALSA plugin device [%s] of type [%s]\n", __FUNCTION__, idStr, tpStr )); continue; } PA_DEBUG(( "%s: Found plugin [%s] of type [%s]\n", __FUNCTION__, idStr, tpStr )); PA_UNLESS( alsaDeviceName = (char*)PaUtil_GroupAllocateMemory( alsaApi->allocations, strlen(idStr) + 6 ), paInsufficientMemory ); strcpy( alsaDeviceName, idStr ); PA_UNLESS( deviceName = (char*)PaUtil_GroupAllocateMemory( alsaApi->allocations, strlen(idStr) + 1 ), paInsufficientMemory ); strcpy( deviceName, idStr ); ++numDeviceNames; if( !hwDevInfos || numDeviceNames > maxDeviceNames ) { maxDeviceNames *= 2; PA_UNLESS( hwDevInfos = (HwDevInfo *) realloc( hwDevInfos, maxDeviceNames * sizeof (HwDevInfo) ), paInsufficientMemory ); } predefined = FindDeviceName( alsaDeviceName ); hwDevInfos[numDeviceNames - 1].alsaName = alsaDeviceName; hwDevInfos[numDeviceNames - 1].name = deviceName; hwDevInfos[numDeviceNames - 1].isPlug = 1; if( predefined ) { hwDevInfos[numDeviceNames - 1].hasPlayback = predefined->hasPlayback; hwDevInfos[numDeviceNames - 1].hasCapture = predefined->hasCapture; } else { hwDevInfos[numDeviceNames - 1].hasPlayback = 1; hwDevInfos[numDeviceNames - 1].hasCapture = 1; } } } else PA_DEBUG(( "%s: Iterating over ALSA plugins failed: %s\n", __FUNCTION__, alsa_snd_strerror( res ) )); /* allocate deviceInfo memory based on the number of devices */ PA_UNLESS( baseApi->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( alsaApi->allocations, sizeof(PaDeviceInfo*) * (numDeviceNames) ), paInsufficientMemory ); /* allocate all device info structs in a contiguous block */ PA_UNLESS( deviceInfoArray = (PaAlsaDeviceInfo*)PaUtil_GroupAllocateMemory( alsaApi->allocations, sizeof(PaAlsaDeviceInfo) * numDeviceNames ), paInsufficientMemory ); /* Loop over list of cards, filling in info. If a device is deemed unavailable (can't get name), * it's ignored. * * Note that we do this in two stages. This is a workaround owing to the fact that the 'dmix' * plugin may cause the underlying hardware device to be busy for a short while even after it * (dmix) is closed. The 'default' plugin may also point to the dmix plugin, so the same goes * for this. */ PA_DEBUG(( "%s: Filling device info for %d devices\n", __FUNCTION__, numDeviceNames )); for( i = 0, devIdx = 0; i < numDeviceNames; ++i ) { PaAlsaDeviceInfo* devInfo = &deviceInfoArray[i]; HwDevInfo* hwInfo = &hwDevInfos[i]; if( !strcmp( hwInfo->name, "dmix" ) || !strcmp( hwInfo->name, "default" ) ) { continue; } PA_ENSURE( FillInDevInfo( alsaApi, hwInfo, blocking, devInfo, &devIdx ) ); } assert( devIdx < numDeviceNames ); /* Now inspect 'dmix' and 'default' plugins */ for( i = 0; i < numDeviceNames; ++i ) { PaAlsaDeviceInfo* devInfo = &deviceInfoArray[i]; HwDevInfo* hwInfo = &hwDevInfos[i]; if( strcmp( hwInfo->name, "dmix" ) && strcmp( hwInfo->name, "default" ) ) { continue; } PA_ENSURE( FillInDevInfo( alsaApi, hwInfo, blocking, devInfo, &devIdx ) ); } free( hwDevInfos ); baseApi->info.deviceCount = devIdx; /* Number of successfully queried devices */ #ifdef PA_ENABLE_DEBUG_OUTPUT PA_DEBUG(( "%s: Building device list took %f seconds\n", __FUNCTION__, PaUtil_GetTime() - startTime )); #endif end: return result; error: /* No particular action */ goto end; } /* Check against known device capabilities */ static PaError ValidateParameters( const PaStreamParameters *parameters, PaUtilHostApiRepresentation *hostApi, StreamDirection mode ) { PaError result = paNoError; int maxChans; const PaAlsaDeviceInfo *deviceInfo = NULL; assert( parameters ); if( parameters->device != paUseHostApiSpecificDeviceSpecification ) { assert( parameters->device < hostApi->info.deviceCount ); PA_UNLESS( parameters->hostApiSpecificStreamInfo == NULL, paBadIODeviceCombination ); deviceInfo = GetDeviceInfo( hostApi, parameters->device ); } else { const PaAlsaStreamInfo *streamInfo = parameters->hostApiSpecificStreamInfo; PA_UNLESS( parameters->device == paUseHostApiSpecificDeviceSpecification, paInvalidDevice ); PA_UNLESS( streamInfo->size == sizeof (PaAlsaStreamInfo) && streamInfo->version == 1, paIncompatibleHostApiSpecificStreamInfo ); PA_UNLESS( streamInfo->deviceString != NULL, paInvalidDevice ); /* Skip further checking */ return paNoError; } assert( deviceInfo ); assert( parameters->hostApiSpecificStreamInfo == NULL ); maxChans = ( StreamDirection_In == mode ? deviceInfo->baseDeviceInfo.maxInputChannels : deviceInfo->baseDeviceInfo.maxOutputChannels ); PA_UNLESS( parameters->channelCount <= maxChans, paInvalidChannelCount ); error: return result; } /* Given an open stream, what sample formats are available? */ static PaSampleFormat GetAvailableFormats( snd_pcm_t *pcm ) { PaSampleFormat available = 0; snd_pcm_hw_params_t *hwParams; alsa_snd_pcm_hw_params_alloca( &hwParams ); alsa_snd_pcm_hw_params_any( pcm, hwParams ); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_FLOAT ) >= 0) available |= paFloat32; if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S32 ) >= 0) available |= paInt32; #ifdef PA_LITTLE_ENDIAN if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3LE ) >= 0) available |= paInt24; #elif defined PA_BIG_ENDIAN if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3BE ) >= 0) available |= paInt24; #endif if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S16 ) >= 0) available |= paInt16; if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U8 ) >= 0) available |= paUInt8; if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S8 ) >= 0) available |= paInt8; return available; } /* Output to console all formats supported by device */ static void LogAllAvailableFormats( snd_pcm_t *pcm ) { PaSampleFormat available = 0; snd_pcm_hw_params_t *hwParams; alsa_snd_pcm_hw_params_alloca( &hwParams ); alsa_snd_pcm_hw_params_any( pcm, hwParams ); PA_DEBUG(( " --- Supported Formats ---\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S8 ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S8\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U8 ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U8\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S16_LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S16_LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S16_BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S16_BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U16_LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U16_LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U16_BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U16_BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S24_LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S24_BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U24_LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U24_LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U24_BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U24_BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_FLOAT_LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_FLOAT_LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_FLOAT_BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_FLOAT_BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_FLOAT64_LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_FLOAT64_LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_FLOAT64_BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_FLOAT64_BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_IEC958_SUBFRAME_LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_IEC958_SUBFRAME_LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_IEC958_SUBFRAME_BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_IEC958_SUBFRAME_BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_MU_LAW ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_MU_LAW\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_A_LAW ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_A_LAW\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_IMA_ADPCM ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_IMA_ADPCM\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_MPEG ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_MPEG\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_GSM ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_GSM\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_SPECIAL ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_SPECIAL\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S24_3LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S24_3BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U24_3LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U24_3LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U24_3BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U24_3BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S20_3LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S20_3LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S20_3BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S20_3BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U20_3LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U20_3LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U20_3BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U20_3BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S18_3LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S18_3LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S18_3BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S18_3BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U18_3LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U18_3LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U18_3BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U18_3BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S16 ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S16\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U16 ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U16\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24 ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S24\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U24 ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U24\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S32 ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S32\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U32 ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U32\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_FLOAT ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_FLOAT\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_FLOAT64 ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_FLOAT64\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_IEC958_SUBFRAME ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_IEC958_SUBFRAME\n" )); PA_DEBUG(( " -------------------------\n" )); } static snd_pcm_format_t Pa2AlsaFormat( PaSampleFormat paFormat ) { switch( paFormat ) { case paFloat32: return SND_PCM_FORMAT_FLOAT; case paInt16: return SND_PCM_FORMAT_S16; case paInt24: #ifdef PA_LITTLE_ENDIAN return SND_PCM_FORMAT_S24_3LE; #elif defined PA_BIG_ENDIAN return SND_PCM_FORMAT_S24_3BE; #endif case paInt32: return SND_PCM_FORMAT_S32; case paInt8: return SND_PCM_FORMAT_S8; case paUInt8: return SND_PCM_FORMAT_U8; default: return SND_PCM_FORMAT_UNKNOWN; } } /** Open an ALSA pcm handle. * * The device to be open can be specified by name in a custom PaAlsaStreamInfo struct, or it will be by * the Portaudio device number supplied in the stream parameters. */ static PaError AlsaOpen( const PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *params, StreamDirection streamDir, snd_pcm_t **pcm ) { PaError result = paNoError; int ret; const char* deviceName = ""; const PaAlsaDeviceInfo *deviceInfo = NULL; PaAlsaStreamInfo *streamInfo = (PaAlsaStreamInfo *)params->hostApiSpecificStreamInfo; if( !streamInfo ) { deviceInfo = GetDeviceInfo( hostApi, params->device ); deviceName = deviceInfo->alsaName; } else deviceName = streamInfo->deviceString; PA_DEBUG(( "%s: Opening device %s\n", __FUNCTION__, deviceName )); if( (ret = OpenPcm( pcm, deviceName, streamDir == StreamDirection_In ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK, 1 )) < 0 ) { /* Not to be closed */ *pcm = NULL; ENSURE_( ret, -EBUSY == ret ? paDeviceUnavailable : paBadIODeviceCombination ); } ENSURE_( alsa_snd_pcm_nonblock( *pcm, 0 ), paUnanticipatedHostError ); end: return result; error: goto end; } static PaError TestParameters( const PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *parameters, double sampleRate, StreamDirection streamDir ) { PaError result = paNoError; snd_pcm_t *pcm = NULL; PaSampleFormat availableFormats; /* We are able to adapt to a number of channels less than what the device supports */ unsigned int numHostChannels; PaSampleFormat hostFormat; snd_pcm_hw_params_t *hwParams; alsa_snd_pcm_hw_params_alloca( &hwParams ); if( !parameters->hostApiSpecificStreamInfo ) { const PaAlsaDeviceInfo *devInfo = GetDeviceInfo( hostApi, parameters->device ); numHostChannels = PA_MAX( parameters->channelCount, StreamDirection_In == streamDir ? devInfo->minInputChannels : devInfo->minOutputChannels ); } else numHostChannels = parameters->channelCount; PA_ENSURE( AlsaOpen( hostApi, parameters, streamDir, &pcm ) ); alsa_snd_pcm_hw_params_any( pcm, hwParams ); if( SetApproximateSampleRate( pcm, hwParams, sampleRate ) < 0 ) { result = paInvalidSampleRate; goto error; } if( alsa_snd_pcm_hw_params_set_channels( pcm, hwParams, numHostChannels ) < 0 ) { result = paInvalidChannelCount; goto error; } /* See if we can find a best possible match */ availableFormats = GetAvailableFormats( pcm ); PA_ENSURE( hostFormat = PaUtil_SelectClosestAvailableFormat( availableFormats, parameters->sampleFormat ) ); /* Some specific hardware (reported: Audio8 DJ) can fail with assertion during this step. */ ENSURE_( alsa_snd_pcm_hw_params_set_format( pcm, hwParams, Pa2AlsaFormat( hostFormat ) ), paUnanticipatedHostError ); { /* It happens that this call fails because the device is busy */ int ret = 0; if( ( ret = alsa_snd_pcm_hw_params( pcm, hwParams ) ) < 0 ) { if( -EINVAL == ret ) { /* Don't know what to return here */ result = paBadIODeviceCombination; goto error; } else if( -EBUSY == ret ) { result = paDeviceUnavailable; PA_DEBUG(( "%s: Device is busy\n", __FUNCTION__ )); } else { result = paUnanticipatedHostError; } ENSURE_( ret, result ); } } end: if( pcm ) { alsa_snd_pcm_close( pcm ); } return result; error: goto end; } static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { int inputChannelCount = 0, outputChannelCount = 0; PaSampleFormat inputSampleFormat, outputSampleFormat; PaError result = paFormatIsSupported; if( inputParameters ) { PA_ENSURE( ValidateParameters( inputParameters, hostApi, StreamDirection_In ) ); inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; } if( outputParameters ) { PA_ENSURE( ValidateParameters( outputParameters, hostApi, StreamDirection_Out ) ); outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; } if( inputChannelCount ) { if( ( result = TestParameters( hostApi, inputParameters, sampleRate, StreamDirection_In ) ) != paNoError ) goto error; } if ( outputChannelCount ) { if( ( result = TestParameters( hostApi, outputParameters, sampleRate, StreamDirection_Out ) ) != paNoError ) goto error; } return paFormatIsSupported; error: return result; } static PaError PaAlsaStreamComponent_Initialize( PaAlsaStreamComponent *self, PaAlsaHostApiRepresentation *alsaApi, const PaStreamParameters *params, StreamDirection streamDir, int callbackMode ) { PaError result = paNoError; PaSampleFormat userSampleFormat = params->sampleFormat, hostSampleFormat = paNoError; assert( params->channelCount > 0 ); /* Make sure things have an initial value */ memset( self, 0, sizeof (PaAlsaStreamComponent) ); if( NULL == params->hostApiSpecificStreamInfo ) { const PaAlsaDeviceInfo *devInfo = GetDeviceInfo( &alsaApi->baseHostApiRep, params->device ); self->numHostChannels = PA_MAX( params->channelCount, StreamDirection_In == streamDir ? devInfo->minInputChannels : devInfo->minOutputChannels ); self->deviceIsPlug = devInfo->isPlug; PA_DEBUG(( "%s: Host Chans %c %i\n", __FUNCTION__, streamDir == StreamDirection_In ? 'C' : 'P', self->numHostChannels )); } else { /* We're blissfully unaware of the minimum channelCount */ self->numHostChannels = params->channelCount; /* Check if device name does not start with hw: to determine if it is a 'plug' device */ if( strncmp( "hw:", ((PaAlsaStreamInfo *)params->hostApiSpecificStreamInfo)->deviceString, 3 ) != 0 ) self->deviceIsPlug = 1; /* An Alsa plug device, not a direct hw device */ } if( self->deviceIsPlug && alsaApi->alsaLibVersion < ALSA_VERSION_INT( 1, 0, 16 ) ) self->useReventFix = 1; /* Prior to Alsa1.0.16, plug devices may stutter without this fix */ self->device = params->device; PA_ENSURE( AlsaOpen( &alsaApi->baseHostApiRep, params, streamDir, &self->pcm ) ); self->nfds = alsa_snd_pcm_poll_descriptors_count( self->pcm ); PA_ENSURE( hostSampleFormat = PaUtil_SelectClosestAvailableFormat( GetAvailableFormats( self->pcm ), userSampleFormat ) ); self->hostSampleFormat = hostSampleFormat; self->nativeFormat = Pa2AlsaFormat( hostSampleFormat ); self->hostInterleaved = self->userInterleaved = !( userSampleFormat & paNonInterleaved ); self->numUserChannels = params->channelCount; self->streamDir = streamDir; self->canMmap = 0; self->nonMmapBuffer = NULL; self->nonMmapBufferSize = 0; if( !callbackMode && !self->userInterleaved ) { /* Pre-allocate non-interleaved user provided buffers */ PA_UNLESS( self->userBuffers = PaUtil_AllocateMemory( sizeof (void *) * self->numUserChannels ), paInsufficientMemory ); } error: /* Log all available formats. */ if ( hostSampleFormat == paSampleFormatNotSupported ) { LogAllAvailableFormats( self->pcm ); PA_DEBUG(( "%s: Please provide the log output to PortAudio developers, your hardware does not have any sample format implemented yet.\n", __FUNCTION__ )); } return result; } static void PaAlsaStreamComponent_Terminate( PaAlsaStreamComponent *self ) { alsa_snd_pcm_close( self->pcm ); PaUtil_FreeMemory( self->userBuffers ); /* (Ptr can be NULL; PaUtil_FreeMemory includes a NULL check) */ PaUtil_FreeMemory( self->nonMmapBuffer ); } /* static int nearbyint_(float value) { if( value - (int)value > .5 ) return (int)ceil( value ); return (int)floor( value ); } */ /** Initiate configuration, preparing for determining a period size suitable for both capture and playback components. * */ static PaError PaAlsaStreamComponent_InitialConfigure( PaAlsaStreamComponent *self, const PaStreamParameters *params, int primeBuffers, snd_pcm_hw_params_t *hwParams, double *sampleRate ) { /* Configuration consists of setting all of ALSA's parameters. * These parameters come in two flavors: hardware parameters * and software paramters. Hardware parameters will affect * the way the device is initialized, software parameters * affect the way ALSA interacts with me, the user-level client. */ PaError result = paNoError; snd_pcm_access_t accessMode, alternateAccessMode; int dir = 0; snd_pcm_t *pcm = self->pcm; double sr = *sampleRate; unsigned int minPeriods = 2; /* self->framesPerPeriod = framesPerHostBuffer; */ /* ... fill up the configuration space with all possibile * combinations of parameters this device will accept */ ENSURE_( alsa_snd_pcm_hw_params_any( pcm, hwParams ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_set_periods_integer( pcm, hwParams ), paUnanticipatedHostError ); /* I think there should be at least 2 periods (even though ALSA doesn't appear to enforce this) */ dir = 0; ENSURE_( alsa_snd_pcm_hw_params_set_periods_min( pcm, hwParams, &minPeriods, &dir ), paUnanticipatedHostError ); if( self->userInterleaved ) { accessMode = SND_PCM_ACCESS_MMAP_INTERLEAVED; alternateAccessMode = SND_PCM_ACCESS_MMAP_NONINTERLEAVED; /* test if MMAP supported */ self->canMmap = alsa_snd_pcm_hw_params_test_access( pcm, hwParams, accessMode ) >= 0 || alsa_snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0; PA_DEBUG(( "%s: device MMAP SND_PCM_ACCESS_MMAP_INTERLEAVED: %s\n", __FUNCTION__, ( alsa_snd_pcm_hw_params_test_access( pcm, hwParams, accessMode ) >= 0 ? "YES" : "NO" ) )); PA_DEBUG(( "%s: device MMAP SND_PCM_ACCESS_MMAP_NONINTERLEAVED: %s\n", __FUNCTION__, ( alsa_snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0 ? "YES" : "NO" ) )); if( !self->canMmap ) { accessMode = SND_PCM_ACCESS_RW_INTERLEAVED; alternateAccessMode = SND_PCM_ACCESS_RW_NONINTERLEAVED; } } else { accessMode = SND_PCM_ACCESS_MMAP_NONINTERLEAVED; alternateAccessMode = SND_PCM_ACCESS_MMAP_INTERLEAVED; /* test if MMAP supported */ self->canMmap = alsa_snd_pcm_hw_params_test_access( pcm, hwParams, accessMode ) >= 0 || alsa_snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0; PA_DEBUG((" %s: device MMAP SND_PCM_ACCESS_MMAP_NONINTERLEAVED: %s\n", __FUNCTION__, ( alsa_snd_pcm_hw_params_test_access( pcm, hwParams, accessMode ) >= 0 ? "YES" : "NO" ) )); PA_DEBUG(( "%s: device MMAP SND_PCM_ACCESS_MMAP_INTERLEAVED: %s\n", __FUNCTION__, ( alsa_snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0 ? "YES" : "NO" ) )); if( !self->canMmap ) { accessMode = SND_PCM_ACCESS_RW_NONINTERLEAVED; alternateAccessMode = SND_PCM_ACCESS_RW_INTERLEAVED; } } PA_DEBUG(( "%s: device can MMAP: %s\n", __FUNCTION__, ( self->canMmap ? "YES" : "NO" ) )); /* If requested access mode fails, try alternate mode */ if( alsa_snd_pcm_hw_params_set_access( pcm, hwParams, accessMode ) < 0 ) { int err = 0; if( ( err = alsa_snd_pcm_hw_params_set_access( pcm, hwParams, alternateAccessMode )) < 0 ) { result = paUnanticipatedHostError; PaUtil_SetLastHostErrorInfo( paALSA, err, alsa_snd_strerror( err ) ); goto error; } /* Flip mode */ self->hostInterleaved = !self->userInterleaved; } /* Some specific hardware (reported: Audio8 DJ) can fail with assertion during this step. */ ENSURE_( alsa_snd_pcm_hw_params_set_format( pcm, hwParams, self->nativeFormat ), paUnanticipatedHostError ); if( ( result = SetApproximateSampleRate( pcm, hwParams, sr )) != paUnanticipatedHostError ) { ENSURE_( GetExactSampleRate( hwParams, &sr ), paUnanticipatedHostError ); if( result == paInvalidSampleRate ) /* From the SetApproximateSampleRate() call above */ { /* The sample rate was returned as 'out of tolerance' of the one requested */ PA_DEBUG(( "%s: Wanted %.3f, closest sample rate was %.3f\n", __FUNCTION__, sampleRate, sr )); PA_ENSURE( paInvalidSampleRate ); } } else { PA_ENSURE( paUnanticipatedHostError ); } ENSURE_( alsa_snd_pcm_hw_params_set_channels( pcm, hwParams, self->numHostChannels ), paInvalidChannelCount ); *sampleRate = sr; end: return result; error: /* No particular action */ goto end; } /** Finish the configuration of the component's ALSA device. * * As part of this method, the component's alsaBufferSize attribute will be set. * @param latency: The latency for this component. */ static PaError PaAlsaStreamComponent_FinishConfigure( PaAlsaStreamComponent *self, snd_pcm_hw_params_t* hwParams, const PaStreamParameters *params, int primeBuffers, double sampleRate, PaTime* latency ) { PaError result = paNoError; snd_pcm_sw_params_t* swParams; snd_pcm_uframes_t bufSz = 0; *latency = -1.; alsa_snd_pcm_sw_params_alloca( &swParams ); bufSz = params->suggestedLatency * sampleRate + self->framesPerPeriod; ENSURE_( alsa_snd_pcm_hw_params_set_buffer_size_near( self->pcm, hwParams, &bufSz ), paUnanticipatedHostError ); /* Set the parameters! */ { int r = alsa_snd_pcm_hw_params( self->pcm, hwParams ); #ifdef PA_ENABLE_DEBUG_OUTPUT if( r < 0 ) { snd_output_t *output = NULL; alsa_snd_output_stdio_attach( &output, stderr, 0 ); alsa_snd_pcm_hw_params_dump( hwParams, output ); } #endif ENSURE_( r, paUnanticipatedHostError ); } if( alsa_snd_pcm_hw_params_get_buffer_size != NULL ) { ENSURE_( alsa_snd_pcm_hw_params_get_buffer_size( hwParams, &self->alsaBufferSize ), paUnanticipatedHostError ); } else { self->alsaBufferSize = bufSz; } /* Latency in seconds */ *latency = (self->alsaBufferSize - self->framesPerPeriod) / sampleRate; /* Now software parameters... */ ENSURE_( alsa_snd_pcm_sw_params_current( self->pcm, swParams ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_sw_params_set_start_threshold( self->pcm, swParams, self->framesPerPeriod ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_sw_params_set_stop_threshold( self->pcm, swParams, self->alsaBufferSize ), paUnanticipatedHostError ); /* Silence buffer in the case of underrun */ if( !primeBuffers ) /* XXX: Make sense? */ { snd_pcm_uframes_t boundary; ENSURE_( alsa_snd_pcm_sw_params_get_boundary( swParams, &boundary ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_sw_params_set_silence_threshold( self->pcm, swParams, 0 ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_sw_params_set_silence_size( self->pcm, swParams, boundary ), paUnanticipatedHostError ); } ENSURE_( alsa_snd_pcm_sw_params_set_avail_min( self->pcm, swParams, self->framesPerPeriod ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_sw_params_set_xfer_align( self->pcm, swParams, 1 ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_sw_params_set_tstamp_mode( self->pcm, swParams, SND_PCM_TSTAMP_ENABLE ), paUnanticipatedHostError ); /* Set the parameters! */ ENSURE_( alsa_snd_pcm_sw_params( self->pcm, swParams ), paUnanticipatedHostError ); error: return result; } static PaError PaAlsaStream_Initialize( PaAlsaStream *self, PaAlsaHostApiRepresentation *alsaApi, const PaStreamParameters *inParams, const PaStreamParameters *outParams, double sampleRate, unsigned long framesPerUserBuffer, PaStreamCallback callback, PaStreamFlags streamFlags, void *userData ) { PaError result = paNoError; assert( self ); memset( self, 0, sizeof( PaAlsaStream ) ); if( NULL != callback ) { PaUtil_InitializeStreamRepresentation( &self->streamRepresentation, &alsaApi->callbackStreamInterface, callback, userData ); self->callbackMode = 1; } else { PaUtil_InitializeStreamRepresentation( &self->streamRepresentation, &alsaApi->blockingStreamInterface, NULL, userData ); } self->framesPerUserBuffer = framesPerUserBuffer; self->neverDropInput = streamFlags & paNeverDropInput; /* XXX: Ignore paPrimeOutputBuffersUsingStreamCallback untill buffer priming is fully supported in pa_process.c */ /* if( outParams & streamFlags & paPrimeOutputBuffersUsingStreamCallback ) self->primeBuffers = 1; */ memset( &self->capture, 0, sizeof (PaAlsaStreamComponent) ); memset( &self->playback, 0, sizeof (PaAlsaStreamComponent) ); if( inParams ) { PA_ENSURE( PaAlsaStreamComponent_Initialize( &self->capture, alsaApi, inParams, StreamDirection_In, NULL != callback ) ); } if( outParams ) { PA_ENSURE( PaAlsaStreamComponent_Initialize( &self->playback, alsaApi, outParams, StreamDirection_Out, NULL != callback ) ); } assert( self->capture.nfds || self->playback.nfds ); PA_UNLESS( self->pfds = (struct pollfd*)PaUtil_AllocateMemory( ( self->capture.nfds + self->playback.nfds ) * sizeof( struct pollfd ) ), paInsufficientMemory ); PaUtil_InitializeCpuLoadMeasurer( &self->cpuLoadMeasurer, sampleRate ); ASSERT_CALL_( PaUnixMutex_Initialize( &self->stateMtx ), paNoError ); error: return result; } /** Free resources associated with stream, and eventually stream itself. * * Frees allocated memory, and terminates individual StreamComponents. */ static void PaAlsaStream_Terminate( PaAlsaStream *self ) { assert( self ); if( self->capture.pcm ) { PaAlsaStreamComponent_Terminate( &self->capture ); } if( self->playback.pcm ) { PaAlsaStreamComponent_Terminate( &self->playback ); } PaUtil_FreeMemory( self->pfds ); ASSERT_CALL_( PaUnixMutex_Terminate( &self->stateMtx ), paNoError ); PaUtil_FreeMemory( self ); } /** Calculate polling timeout * * @param frames Time to wait * @return Polling timeout in milliseconds */ static int CalculatePollTimeout( const PaAlsaStream *stream, unsigned long frames ) { assert( stream->streamRepresentation.streamInfo.sampleRate > 0.0 ); /* Period in msecs, rounded up */ return (int)ceil( 1000 * frames / stream->streamRepresentation.streamInfo.sampleRate ); } /** Align value in backward direction. * * @param v: Value to align. * @param align: Alignment. */ static unsigned long PaAlsa_AlignBackward(unsigned long v, unsigned long align) { return ( v - ( align ? v % align : 0 ) ); } /** Align value in forward direction. * * @param v: Value to align. * @param align: Alignment. */ static unsigned long PaAlsa_AlignForward(unsigned long v, unsigned long align) { unsigned long remainder = ( align ? ( v % align ) : 0); return ( remainder != 0 ? v + ( align - remainder ) : v ); } /** Get size of host buffer maintained from the number of user frames, sample rate and suggested latency. Minimum double buffering * is maintained to allow 100% CPU usage inside user callback. * * @param userFramesPerBuffer: User buffer size in number of frames. * @param suggestedLatency: User provided desired latency. * @param sampleRate: Sample rate. */ static unsigned long PaAlsa_GetFramesPerHostBuffer(unsigned long userFramesPerBuffer, PaTime suggestedLatency, double sampleRate) { unsigned long frames = userFramesPerBuffer + PA_MAX( userFramesPerBuffer, (unsigned long)( suggestedLatency * sampleRate ) ); return frames; } /** Determine size per host buffer. * * During this method call, the component's framesPerPeriod attribute gets computed, and the corresponding period size * gets configured for the device. * @param accurate: If the configured period size is non-integer, this will be set to 0. */ static PaError PaAlsaStreamComponent_DetermineFramesPerBuffer( PaAlsaStreamComponent* self, const PaStreamParameters* params, unsigned long framesPerUserBuffer, double sampleRate, snd_pcm_hw_params_t* hwParams, int* accurate ) { PaError result = paNoError; unsigned long bufferSize, framesPerHostBuffer; int dir = 0; /* Calculate host buffer size */ bufferSize = PaAlsa_GetFramesPerHostBuffer(framesPerUserBuffer, params->suggestedLatency, sampleRate); /* Log */ PA_DEBUG(( "%s: user-buffer (frames) = %lu\n", __FUNCTION__, framesPerUserBuffer )); PA_DEBUG(( "%s: user-buffer (sec) = %f\n", __FUNCTION__, (double)(framesPerUserBuffer / sampleRate) )); PA_DEBUG(( "%s: suggested latency (sec) = %f\n", __FUNCTION__, params->suggestedLatency )); PA_DEBUG(( "%s: suggested host buffer (frames) = %lu\n", __FUNCTION__, bufferSize )); PA_DEBUG(( "%s: suggested host buffer (sec) = %f\n", __FUNCTION__, (double)(bufferSize / sampleRate) )); #ifdef PA_ALSA_USE_OBSOLETE_HOST_BUFFER_CALC if( framesPerUserBuffer != paFramesPerBufferUnspecified ) { /* Preferably the host buffer size should be a multiple of the user buffer size */ if( bufferSize > framesPerUserBuffer ) { snd_pcm_uframes_t remainder = bufferSize % framesPerUserBuffer; if( remainder > framesPerUserBuffer / 2. ) bufferSize += framesPerUserBuffer - remainder; else bufferSize -= remainder; assert( bufferSize % framesPerUserBuffer == 0 ); } else if( framesPerUserBuffer % bufferSize != 0 ) { /* Find a good compromise between user specified latency and buffer size */ if( bufferSize > framesPerUserBuffer * .75 ) { bufferSize = framesPerUserBuffer; } else { snd_pcm_uframes_t newSz = framesPerUserBuffer; while( newSz / 2 >= bufferSize ) { if( framesPerUserBuffer % (newSz / 2) != 0 ) { /* No use dividing any further */ break; } newSz /= 2; } bufferSize = newSz; } assert( framesPerUserBuffer % bufferSize == 0 ); } } #endif { unsigned numPeriods = numPeriods_, maxPeriods = 0, minPeriods = numPeriods_; /* It may be that the device only supports 2 periods for instance */ dir = 0; ENSURE_( alsa_snd_pcm_hw_params_get_periods_min( hwParams, &minPeriods, &dir ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_get_periods_max( hwParams, &maxPeriods, &dir ), paUnanticipatedHostError ); assert( maxPeriods > 1 ); /* Clamp to min/max */ numPeriods = PA_MIN(maxPeriods, PA_MAX(minPeriods, numPeriods)); PA_DEBUG(( "%s: periods min = %lu, max = %lu, req = %lu \n", __FUNCTION__, minPeriods, maxPeriods, numPeriods )); #ifndef PA_ALSA_USE_OBSOLETE_HOST_BUFFER_CALC /* Calculate period size */ framesPerHostBuffer = (bufferSize / numPeriods); /* Align & test size */ if( framesPerUserBuffer != paFramesPerBufferUnspecified ) { /* Align to user buffer size */ framesPerHostBuffer = PaAlsa_AlignForward(framesPerHostBuffer, framesPerUserBuffer); /* Test (borrowed from older implementation) */ if( framesPerHostBuffer < framesPerUserBuffer ) { assert( framesPerUserBuffer % framesPerHostBuffer == 0 ); if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer, 0 ) < 0 ) { if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer * 2, 0 ) == 0 ) framesPerHostBuffer *= 2; else if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer / 2, 0 ) == 0 ) framesPerHostBuffer /= 2; } } else { assert( framesPerHostBuffer % framesPerUserBuffer == 0 ); if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer, 0 ) < 0 ) { if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer + framesPerUserBuffer, 0 ) == 0 ) framesPerHostBuffer += framesPerUserBuffer; else if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer - framesPerUserBuffer, 0 ) == 0 ) framesPerHostBuffer -= framesPerUserBuffer; } } } #endif #ifdef PA_ALSA_USE_OBSOLETE_HOST_BUFFER_CALC if( framesPerUserBuffer != paFramesPerBufferUnspecified ) { /* Try to get a power-of-two of the user buffer size. */ framesPerHostBuffer = framesPerUserBuffer; if( framesPerHostBuffer < bufferSize ) { while( bufferSize / framesPerHostBuffer > numPeriods ) { framesPerHostBuffer *= 2; } /* One extra period is preferrable to one less (should be more robust) */ if( bufferSize / framesPerHostBuffer < numPeriods ) { framesPerHostBuffer /= 2; } } else { while( bufferSize / framesPerHostBuffer < numPeriods ) { if( framesPerUserBuffer % ( framesPerHostBuffer / 2 ) != 0 ) { /* Can't be divided any further */ break; } framesPerHostBuffer /= 2; } } if( framesPerHostBuffer < framesPerUserBuffer ) { assert( framesPerUserBuffer % framesPerHostBuffer == 0 ); if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer, 0 ) < 0 ) { if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer * 2, 0 ) == 0 ) framesPerHostBuffer *= 2; else if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer / 2, 0 ) == 0 ) framesPerHostBuffer /= 2; } } else { assert( framesPerHostBuffer % framesPerUserBuffer == 0 ); if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer, 0 ) < 0 ) { if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer + framesPerUserBuffer, 0 ) == 0 ) framesPerHostBuffer += framesPerUserBuffer; else if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer - framesPerUserBuffer, 0 ) == 0 ) framesPerHostBuffer -= framesPerUserBuffer; } } } else { framesPerHostBuffer = bufferSize / numPeriods; } /* non-mmap mode needs a reasonably-sized buffer or it'll stutter */ if( !self->canMmap && framesPerHostBuffer < 2048 ) framesPerHostBuffer = 2048; #endif PA_DEBUG(( "%s: suggested host buffer period = %lu \n", __FUNCTION__, framesPerHostBuffer )); } { /* Get min/max period sizes and adjust our chosen */ snd_pcm_uframes_t min = 0, max = 0, minmax_diff; ENSURE_( alsa_snd_pcm_hw_params_get_period_size_min( hwParams, &min, NULL ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_get_period_size_max( hwParams, &max, NULL ), paUnanticipatedHostError ); minmax_diff = max - min; if( framesPerHostBuffer < min ) { PA_DEBUG(( "%s: The determined period size (%lu) is less than minimum (%lu)\n", __FUNCTION__, framesPerHostBuffer, min )); framesPerHostBuffer = (( minmax_diff == 2 ) ? min + 1 : min ); } else if( framesPerHostBuffer > max ) { PA_DEBUG(( "%s: The determined period size (%lu) is greater than maximum (%lu)\n", __FUNCTION__, framesPerHostBuffer, max )); framesPerHostBuffer = (( minmax_diff == 2 ) ? max - 1 : max ); } PA_DEBUG(( "%s: device period minimum = %lu\n", __FUNCTION__, min )); PA_DEBUG(( "%s: device period maximum = %lu\n", __FUNCTION__, max )); PA_DEBUG(( "%s: host buffer period = %lu\n", __FUNCTION__, framesPerHostBuffer )); PA_DEBUG(( "%s: host buffer period latency = %f\n", __FUNCTION__, (double)( framesPerHostBuffer / sampleRate ) )); /* Try setting period size */ dir = 0; ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( self->pcm, hwParams, &framesPerHostBuffer, &dir ), paUnanticipatedHostError ); if( dir != 0 ) { PA_DEBUG(( "%s: The configured period size is non-integer.\n", __FUNCTION__, dir )); *accurate = 0; } } /* Set result */ self->framesPerPeriod = framesPerHostBuffer; error: return result; } /* We need to determine how many frames per host buffer (period) to use. Our * goals are to provide the best possible performance, but also to * honor the requested latency settings as closely as we can. Therefore this * decision is based on: * * - the period sizes that playback and/or capture support. The * host buffer size has to be one of these. * - the number of periods that playback and/or capture support. * * We want to make period_size*(num_periods-1) to be as close as possible * to latency*rate for both playback and capture. * * This method will determine suitable period sizes for capture and playback handles, and report the maximum number of * frames per host buffer. The latter is relevant, in case we should be so unfortunate that the period size differs * between capture and playback. If this should happen, the stream's hostBufferSizeMode attribute will be set to * paUtilBoundedHostBufferSize, because the best we can do is limit the size of individual host buffers to the upper * bound. The size of host buffers scheduled for processing should only matter if the user has specified a buffer size, * but when he/she does we must strive for an optimal configuration. By default we'll opt for a fixed host buffer size, * which should be fine if the period size is the same for capture and playback. In general, if there is a specified user * buffer size, this method tries it best to determine a period size which is a multiple of the user buffer size. * * The framesPerPeriod attributes of the individual capture and playback components of the stream are set to corresponding * values determined here. Since these should be reported as * * This is one of those blocks of code that will just take a lot of * refinement to be any good. * * In the full-duplex case it is possible that the routine was unable * to find a number of frames per buffer acceptable to both devices * TODO: Implement an algorithm to find the value closest to acceptance * by both devices, to minimize difference between period sizes? * * @param determinedFramesPerHostBuffer: The determined host buffer size. */ static PaError PaAlsaStream_DetermineFramesPerBuffer( PaAlsaStream* self, double sampleRate, const PaStreamParameters* inputParameters, const PaStreamParameters* outputParameters, unsigned long framesPerUserBuffer, snd_pcm_hw_params_t* hwParamsCapture, snd_pcm_hw_params_t* hwParamsPlayback, PaUtilHostBufferSizeMode* hostBufferSizeMode ) { PaError result = paNoError; unsigned long framesPerHostBuffer = 0; int dir = 0; int accurate = 1; unsigned numPeriods = numPeriods_; if( self->capture.pcm && self->playback.pcm ) { if( framesPerUserBuffer == paFramesPerBufferUnspecified ) { /* Come up with a common desired latency */ snd_pcm_uframes_t desiredBufSz, e, minPeriodSize, maxPeriodSize, optimalPeriodSize, periodSize, minCapture, minPlayback, maxCapture, maxPlayback; dir = 0; ENSURE_( alsa_snd_pcm_hw_params_get_period_size_min( hwParamsCapture, &minCapture, &dir ), paUnanticipatedHostError ); dir = 0; ENSURE_( alsa_snd_pcm_hw_params_get_period_size_min( hwParamsPlayback, &minPlayback, &dir ), paUnanticipatedHostError ); dir = 0; ENSURE_( alsa_snd_pcm_hw_params_get_period_size_max( hwParamsCapture, &maxCapture, &dir ), paUnanticipatedHostError ); dir = 0; ENSURE_( alsa_snd_pcm_hw_params_get_period_size_max( hwParamsPlayback, &maxPlayback, &dir ), paUnanticipatedHostError ); minPeriodSize = PA_MAX( minPlayback, minCapture ); maxPeriodSize = PA_MIN( maxPlayback, maxCapture ); PA_UNLESS( minPeriodSize <= maxPeriodSize, paBadIODeviceCombination ); desiredBufSz = (snd_pcm_uframes_t)( PA_MIN( outputParameters->suggestedLatency, inputParameters->suggestedLatency ) * sampleRate ); /* Clamp desiredBufSz */ { snd_pcm_uframes_t maxBufferSize; snd_pcm_uframes_t maxBufferSizeCapture, maxBufferSizePlayback; ENSURE_( alsa_snd_pcm_hw_params_get_buffer_size_max( hwParamsCapture, &maxBufferSizeCapture ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_get_buffer_size_max( hwParamsPlayback, &maxBufferSizePlayback ), paUnanticipatedHostError ); maxBufferSize = PA_MIN( maxBufferSizeCapture, maxBufferSizePlayback ); desiredBufSz = PA_MIN( desiredBufSz, maxBufferSize ); } /* Find the closest power of 2 */ e = ilogb( minPeriodSize ); if( minPeriodSize & ( minPeriodSize - 1 ) ) e += 1; periodSize = (snd_pcm_uframes_t)pow( 2, e ); while( periodSize <= maxPeriodSize ) { if( alsa_snd_pcm_hw_params_test_period_size( self->playback.pcm, hwParamsPlayback, periodSize, 0 ) >= 0 && alsa_snd_pcm_hw_params_test_period_size( self->capture.pcm, hwParamsCapture, periodSize, 0 ) >= 0 ) { /* OK! */ break; } periodSize *= 2; } optimalPeriodSize = PA_MAX( desiredBufSz / numPeriods, minPeriodSize ); optimalPeriodSize = PA_MIN( optimalPeriodSize, maxPeriodSize ); /* Find the closest power of 2 */ e = ilogb( optimalPeriodSize ); if( optimalPeriodSize & (optimalPeriodSize - 1) ) e += 1; optimalPeriodSize = (snd_pcm_uframes_t)pow( 2, e ); while( optimalPeriodSize >= periodSize ) { if( alsa_snd_pcm_hw_params_test_period_size( self->capture.pcm, hwParamsCapture, optimalPeriodSize, 0 ) >= 0 && alsa_snd_pcm_hw_params_test_period_size( self->playback.pcm, hwParamsPlayback, optimalPeriodSize, 0 ) >= 0 ) { break; } optimalPeriodSize /= 2; } if( optimalPeriodSize > periodSize ) periodSize = optimalPeriodSize; if( periodSize <= maxPeriodSize ) { /* Looks good, the periodSize _should_ be acceptable by both devices */ ENSURE_( alsa_snd_pcm_hw_params_set_period_size( self->capture.pcm, hwParamsCapture, periodSize, 0 ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_set_period_size( self->playback.pcm, hwParamsPlayback, periodSize, 0 ), paUnanticipatedHostError ); self->capture.framesPerPeriod = self->playback.framesPerPeriod = periodSize; framesPerHostBuffer = periodSize; } else { /* Unable to find a common period size, oh well */ optimalPeriodSize = PA_MAX( desiredBufSz / numPeriods, minPeriodSize ); optimalPeriodSize = PA_MIN( optimalPeriodSize, maxPeriodSize ); self->capture.framesPerPeriod = optimalPeriodSize; dir = 0; ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( self->capture.pcm, hwParamsCapture, &self->capture.framesPerPeriod, &dir ), paUnanticipatedHostError ); self->playback.framesPerPeriod = optimalPeriodSize; dir = 0; ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( self->playback.pcm, hwParamsPlayback, &self->playback.framesPerPeriod, &dir ), paUnanticipatedHostError ); framesPerHostBuffer = PA_MAX( self->capture.framesPerPeriod, self->playback.framesPerPeriod ); *hostBufferSizeMode = paUtilBoundedHostBufferSize; } } else { /* We choose the simple route and determine a suitable number of frames per buffer for one component of * the stream, then we hope that this will work for the other component too (it should!). */ unsigned maxPeriods = 0; PaAlsaStreamComponent* first = &self->capture, * second = &self->playback; const PaStreamParameters* firstStreamParams = inputParameters; snd_pcm_hw_params_t* firstHwParams = hwParamsCapture, * secondHwParams = hwParamsPlayback; dir = 0; ENSURE_( alsa_snd_pcm_hw_params_get_periods_max( hwParamsPlayback, &maxPeriods, &dir ), paUnanticipatedHostError ); if( maxPeriods < numPeriods ) { /* The playback component is trickier to get right, try that first */ first = &self->playback; second = &self->capture; firstStreamParams = outputParameters; firstHwParams = hwParamsPlayback; secondHwParams = hwParamsCapture; } PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( first, firstStreamParams, framesPerUserBuffer, sampleRate, firstHwParams, &accurate ) ); second->framesPerPeriod = first->framesPerPeriod; dir = 0; ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( second->pcm, secondHwParams, &second->framesPerPeriod, &dir ), paUnanticipatedHostError ); if( self->capture.framesPerPeriod == self->playback.framesPerPeriod ) { framesPerHostBuffer = self->capture.framesPerPeriod; } else { framesPerHostBuffer = PA_MAX( self->capture.framesPerPeriod, self->playback.framesPerPeriod ); *hostBufferSizeMode = paUtilBoundedHostBufferSize; } } } else /* half-duplex is a slightly simpler case */ { if( self->capture.pcm ) { PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( &self->capture, inputParameters, framesPerUserBuffer, sampleRate, hwParamsCapture, &accurate) ); framesPerHostBuffer = self->capture.framesPerPeriod; } else { assert( self->playback.pcm ); PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( &self->playback, outputParameters, framesPerUserBuffer, sampleRate, hwParamsPlayback, &accurate ) ); framesPerHostBuffer = self->playback.framesPerPeriod; } } PA_UNLESS( framesPerHostBuffer != 0, paInternalError ); self->maxFramesPerHostBuffer = framesPerHostBuffer; if( !self->playback.canMmap || !accurate ) { /* Don't know the exact size per host buffer */ *hostBufferSizeMode = paUtilBoundedHostBufferSize; /* Raise upper bound */ if( !accurate ) ++self->maxFramesPerHostBuffer; } error: return result; } /** Set up ALSA stream parameters. * */ static PaError PaAlsaStream_Configure( PaAlsaStream *self, const PaStreamParameters *inParams, const PaStreamParameters* outParams, double sampleRate, unsigned long framesPerUserBuffer, double* inputLatency, double* outputLatency, PaUtilHostBufferSizeMode* hostBufferSizeMode ) { PaError result = paNoError; double realSr = sampleRate; snd_pcm_hw_params_t* hwParamsCapture, * hwParamsPlayback; alsa_snd_pcm_hw_params_alloca( &hwParamsCapture ); alsa_snd_pcm_hw_params_alloca( &hwParamsPlayback ); if( self->capture.pcm ) PA_ENSURE( PaAlsaStreamComponent_InitialConfigure( &self->capture, inParams, self->primeBuffers, hwParamsCapture, &realSr ) ); if( self->playback.pcm ) PA_ENSURE( PaAlsaStreamComponent_InitialConfigure( &self->playback, outParams, self->primeBuffers, hwParamsPlayback, &realSr ) ); PA_ENSURE( PaAlsaStream_DetermineFramesPerBuffer( self, realSr, inParams, outParams, framesPerUserBuffer, hwParamsCapture, hwParamsPlayback, hostBufferSizeMode ) ); if( self->capture.pcm ) { assert( self->capture.framesPerPeriod != 0 ); PA_ENSURE( PaAlsaStreamComponent_FinishConfigure( &self->capture, hwParamsCapture, inParams, self->primeBuffers, realSr, inputLatency ) ); PA_DEBUG(( "%s: Capture period size: %lu, latency: %f\n", __FUNCTION__, self->capture.framesPerPeriod, *inputLatency )); } if( self->playback.pcm ) { assert( self->playback.framesPerPeriod != 0 ); PA_ENSURE( PaAlsaStreamComponent_FinishConfigure( &self->playback, hwParamsPlayback, outParams, self->primeBuffers, realSr, outputLatency ) ); PA_DEBUG(( "%s: Playback period size: %lu, latency: %f\n", __FUNCTION__, self->playback.framesPerPeriod, *outputLatency )); } /* Should be exact now */ self->streamRepresentation.streamInfo.sampleRate = realSr; /* this will cause the two streams to automatically start/stop/prepare in sync. * We only need to execute these operations on one of the pair. * A: We don't want to do this on a blocking stream. */ if( self->callbackMode && self->capture.pcm && self->playback.pcm ) { int err = alsa_snd_pcm_link( self->capture.pcm, self->playback.pcm ); if( err == 0 ) self->pcmsSynced = 1; else PA_DEBUG(( "%s: Unable to sync pcms: %s\n", __FUNCTION__, alsa_snd_strerror( err ) )); } { unsigned long minFramesPerHostBuffer = PA_MIN( self->capture.pcm ? self->capture.framesPerPeriod : ULONG_MAX, self->playback.pcm ? self->playback.framesPerPeriod : ULONG_MAX ); self->pollTimeout = CalculatePollTimeout( self, minFramesPerHostBuffer ); /* Period in msecs, rounded up */ /* Time before watchdog unthrottles realtime thread == 1/4 of period time in msecs */ /* self->threading.throttledSleepTime = (unsigned long) (minFramesPerHostBuffer / sampleRate / 4 * 1000); */ } if( self->callbackMode ) { /* If the user expects a certain number of frames per callback we will either have to rely on block adaption * (framesPerHostBuffer is not an integer multiple of framesPerPeriod) or we can simply align the number * of host buffer frames with what the user specified */ if( self->framesPerUserBuffer != paFramesPerBufferUnspecified ) { /* self->alignFrames = 1; */ /* Unless the ratio between number of host and user buffer frames is an integer we will have to rely * on block adaption */ /* if( framesPerHostBuffer % framesPerPeriod != 0 || (self->capture.pcm && self->playback.pcm && self->capture.framesPerPeriod != self->playback.framesPerPeriod) ) self->useBlockAdaption = 1; else self->alignFrames = 1; */ } } error: return result; } static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback* callback, void *userData ) { PaError result = paNoError; PaAlsaHostApiRepresentation *alsaHostApi = (PaAlsaHostApiRepresentation*)hostApi; PaAlsaStream *stream = NULL; PaSampleFormat hostInputSampleFormat = 0, hostOutputSampleFormat = 0; PaSampleFormat inputSampleFormat = 0, outputSampleFormat = 0; int numInputChannels = 0, numOutputChannels = 0; PaTime inputLatency, outputLatency; /* Operate with fixed host buffer size by default, since other modes will invariably lead to block adaption */ /* XXX: Use Bounded by default? Output tends to get stuttery with Fixed ... */ PaUtilHostBufferSizeMode hostBufferSizeMode = paUtilFixedHostBufferSize; if( ( streamFlags & paPlatformSpecificFlags ) != 0 ) return paInvalidFlag; if( inputParameters ) { PA_ENSURE( ValidateParameters( inputParameters, hostApi, StreamDirection_In ) ); numInputChannels = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; } if( outputParameters ) { PA_ENSURE( ValidateParameters( outputParameters, hostApi, StreamDirection_Out ) ); numOutputChannels = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; } /* XXX: Why do we support this anyway? */ if( framesPerBuffer == paFramesPerBufferUnspecified && getenv( "PA_ALSA_PERIODSIZE" ) != NULL ) { PA_DEBUG(( "%s: Getting framesPerBuffer (Alsa period-size) from environment\n", __FUNCTION__ )); framesPerBuffer = atoi( getenv("PA_ALSA_PERIODSIZE") ); } PA_UNLESS( stream = (PaAlsaStream*)PaUtil_AllocateMemory( sizeof(PaAlsaStream) ), paInsufficientMemory ); PA_ENSURE( PaAlsaStream_Initialize( stream, alsaHostApi, inputParameters, outputParameters, sampleRate, framesPerBuffer, callback, streamFlags, userData ) ); PA_ENSURE( PaAlsaStream_Configure( stream, inputParameters, outputParameters, sampleRate, framesPerBuffer, &inputLatency, &outputLatency, &hostBufferSizeMode ) ); hostInputSampleFormat = stream->capture.hostSampleFormat | (!stream->capture.hostInterleaved ? paNonInterleaved : 0); hostOutputSampleFormat = stream->playback.hostSampleFormat | (!stream->playback.hostInterleaved ? paNonInterleaved : 0); PA_ENSURE( PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, numInputChannels, inputSampleFormat, hostInputSampleFormat, numOutputChannels, outputSampleFormat, hostOutputSampleFormat, sampleRate, streamFlags, framesPerBuffer, stream->maxFramesPerHostBuffer, hostBufferSizeMode, callback, userData ) ); /* Ok, buffer processor is initialized, now we can deduce it's latency */ if( numInputChannels > 0 ) stream->streamRepresentation.streamInfo.inputLatency = inputLatency + (PaTime)( PaUtil_GetBufferProcessorInputLatencyFrames( &stream->bufferProcessor ) / sampleRate); if( numOutputChannels > 0 ) stream->streamRepresentation.streamInfo.outputLatency = outputLatency + (PaTime)( PaUtil_GetBufferProcessorOutputLatencyFrames( &stream->bufferProcessor ) / sampleRate); PA_DEBUG(( "%s: Stream: framesPerBuffer = %lu, maxFramesPerHostBuffer = %lu, latency i=%f, o=%f\n", __FUNCTION__, framesPerBuffer, stream->maxFramesPerHostBuffer, stream->streamRepresentation.streamInfo.inputLatency, stream->streamRepresentation.streamInfo.outputLatency)); *s = (PaStream*)stream; return result; error: if( stream ) { PA_DEBUG(( "%s: Stream in error, terminating\n", __FUNCTION__ )); PaAlsaStream_Terminate( stream ); } return result; } static PaError CloseStream( PaStream* s ) { PaError result = paNoError; PaAlsaStream *stream = (PaAlsaStream*)s; PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); PaAlsaStream_Terminate( stream ); return result; } static void SilenceBuffer( PaAlsaStream *stream ) { const snd_pcm_channel_area_t *areas; snd_pcm_uframes_t frames = (snd_pcm_uframes_t)alsa_snd_pcm_avail_update( stream->playback.pcm ), offset; alsa_snd_pcm_mmap_begin( stream->playback.pcm, &areas, &offset, &frames ); alsa_snd_pcm_areas_silence( areas, offset, stream->playback.numHostChannels, frames, stream->playback.nativeFormat ); alsa_snd_pcm_mmap_commit( stream->playback.pcm, offset, frames ); } /** Start/prepare pcm(s) for streaming. * * Depending on whether the stream is in callback or blocking mode, we will respectively start or simply * prepare the playback pcm. If the buffer has _not_ been primed, we will in callback mode prepare and * silence the buffer before starting playback. In blocking mode we simply prepare, as the playback will * be started automatically as the user writes to output. * * The capture pcm, however, will simply be prepared and started. */ static PaError AlsaStart( PaAlsaStream *stream, int priming ) { PaError result = paNoError; if( stream->playback.pcm ) { if( stream->callbackMode ) { if( !priming ) { /* Buffer isn't primed, so prepare and silence */ ENSURE_( alsa_snd_pcm_prepare( stream->playback.pcm ), paUnanticipatedHostError ); if( stream->playback.canMmap ) SilenceBuffer( stream ); } if( stream->playback.canMmap ) ENSURE_( alsa_snd_pcm_start( stream->playback.pcm ), paUnanticipatedHostError ); } else ENSURE_( alsa_snd_pcm_prepare( stream->playback.pcm ), paUnanticipatedHostError ); } if( stream->capture.pcm && !stream->pcmsSynced ) { ENSURE_( alsa_snd_pcm_prepare( stream->capture.pcm ), paUnanticipatedHostError ); /* For a blocking stream we want to start capture as well, since nothing will happen otherwise */ ENSURE_( alsa_snd_pcm_start( stream->capture.pcm ), paUnanticipatedHostError ); } end: return result; error: goto end; } /** Utility function for determining if pcms are in running state. * */ #if 0 static int IsRunning( PaAlsaStream *stream ) { int result = 0; PA_ENSURE( PaUnixMutex_Lock( &stream->stateMtx ) ); if( stream->capture.pcm ) { snd_pcm_state_t capture_state = alsa_snd_pcm_state( stream->capture.pcm ); if( capture_state == SND_PCM_STATE_RUNNING || capture_state == SND_PCM_STATE_XRUN || capture_state == SND_PCM_STATE_DRAINING ) { result = 1; goto end; } } if( stream->playback.pcm ) { snd_pcm_state_t playback_state = alsa_snd_pcm_state( stream->playback.pcm ); if( playback_state == SND_PCM_STATE_RUNNING || playback_state == SND_PCM_STATE_XRUN || playback_state == SND_PCM_STATE_DRAINING ) { result = 1; goto end; } } end: ASSERT_CALL_( PaUnixMutex_Unlock( &stream->stateMtx ), paNoError ); return result; error: goto error; } #endif static PaError StartStream( PaStream *s ) { PaError result = paNoError; PaAlsaStream* stream = (PaAlsaStream*)s; int streamStarted = 0; /* So we can know whether we need to take the stream down */ /* Ready the processor */ PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); /* Set now, so we can test for activity further down */ stream->isActive = 1; if( stream->callbackMode ) { PA_ENSURE( PaUnixThread_New( &stream->thread, &CallbackThreadFunc, stream, 1., stream->rtSched ) ); } else { PA_ENSURE( AlsaStart( stream, 0 ) ); streamStarted = 1; } end: return result; error: if( streamStarted ) { AbortStream( stream ); } stream->isActive = 0; goto end; } /** Stop PCM handle, either softly or abruptly. */ static PaError AlsaStop( PaAlsaStream *stream, int abort ) { PaError result = paNoError; /* XXX: alsa_snd_pcm_drain tends to lock up, avoid it until we find out more */ abort = 1; /* if( stream->capture.pcm && !strcmp( Pa_GetDeviceInfo( stream->capture.device )->name, "dmix" ) ) { abort = 1; } else if( stream->playback.pcm && !strcmp( Pa_GetDeviceInfo( stream->playback.device )->name, "dmix" ) ) { abort = 1; } */ if( abort ) { if( stream->playback.pcm ) { PA_DEBUG(( "%s: Before dropping\n", __FUNCTION__ )); ENSURE_( alsa_snd_pcm_drop( stream->playback.pcm ), paUnanticipatedHostError ); PA_DEBUG(( "%s: After dropping\n", __FUNCTION__ )); } if( stream->capture.pcm && !stream->pcmsSynced ) { ENSURE_( alsa_snd_pcm_drop( stream->capture.pcm ), paUnanticipatedHostError ); } PA_DEBUG(( "%s: Dropped frames\n", __FUNCTION__ )); } else { if( stream->playback.pcm ) { ENSURE_( alsa_snd_pcm_nonblock( stream->playback.pcm, 0 ), paUnanticipatedHostError ); if( alsa_snd_pcm_drain( stream->playback.pcm ) < 0 ) { PA_DEBUG(( "%s: Draining playback handle failed!\n", __FUNCTION__ )); } } if( stream->capture.pcm && !stream->pcmsSynced ) { /* We don't need to retrieve any remaining frames */ if( alsa_snd_pcm_drain( stream->capture.pcm ) < 0 ) { PA_DEBUG(( "%s: Draining capture handle failed!\n", __FUNCTION__ )); } } } end: return result; error: goto end; } /** Stop or abort stream. * * If a stream is in callback mode we will have to inspect whether the background thread has * finished, or we will have to take it out. In either case we join the thread before * returning. In blocking mode, we simply tell ALSA to stop abruptly (abort) or finish * buffers (drain) * * Stream will be considered inactive (!PaAlsaStream::isActive) after a call to this function */ static PaError RealStop( PaAlsaStream *stream, int abort ) { PaError result = paNoError; /* First deal with the callback thread, cancelling and/or joining * it if necessary */ if( stream->callbackMode ) { PaError threadRes; stream->callbackAbort = abort; if( !abort ) { PA_DEBUG(( "Stopping callback\n" )); } PA_ENSURE( PaUnixThread_Terminate( &stream->thread, !abort, &threadRes ) ); if( threadRes != paNoError ) { PA_DEBUG(( "Callback thread returned: %d\n", threadRes )); } #if 0 if( watchdogRes != paNoError ) PA_DEBUG(( "Watchdog thread returned: %d\n", watchdogRes )); #endif stream->callback_finished = 0; } else { PA_ENSURE( AlsaStop( stream, abort ) ); } stream->isActive = 0; end: return result; error: goto end; } static PaError StopStream( PaStream *s ) { return RealStop( (PaAlsaStream *) s, 0 ); } static PaError AbortStream( PaStream *s ) { return RealStop( (PaAlsaStream * ) s, 1 ); } /** The stream is considered stopped before StartStream, or AFTER a call to Abort/StopStream (callback * returning !paContinue is not considered) * */ static PaError IsStreamStopped( PaStream *s ) { PaAlsaStream *stream = (PaAlsaStream *)s; /* callback_finished indicates we need to join callback thread (ie. in Abort/StopStream) */ return !IsStreamActive( s ) && !stream->callback_finished; } static PaError IsStreamActive( PaStream *s ) { PaAlsaStream *stream = (PaAlsaStream*)s; return stream->isActive; } static PaTime GetStreamTime( PaStream *s ) { PaAlsaStream *stream = (PaAlsaStream*)s; snd_timestamp_t timestamp; snd_pcm_status_t* status; alsa_snd_pcm_status_alloca( &status ); /* TODO: what if we have both? does it really matter? */ /* TODO: if running in callback mode, this will mean * libasound routines are being called from multiple threads. * need to verify that libasound is thread-safe. */ if( stream->capture.pcm ) { alsa_snd_pcm_status( stream->capture.pcm, status ); } else if( stream->playback.pcm ) { alsa_snd_pcm_status( stream->playback.pcm, status ); } alsa_snd_pcm_status_get_tstamp( status, ×tamp ); return timestamp.tv_sec + (PaTime)timestamp.tv_usec / 1e6; } static double GetStreamCpuLoad( PaStream* s ) { PaAlsaStream *stream = (PaAlsaStream*)s; return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); } /* Set the stream sample rate to a nominal value requested; allow only a defined tolerance range */ static int SetApproximateSampleRate( snd_pcm_t *pcm, snd_pcm_hw_params_t *hwParams, double sampleRate ) { PaError result = paNoError; unsigned int reqRate, setRate, deviation; assert( pcm && hwParams ); /* The Alsa sample rate is set by integer value; also the actual rate may differ */ reqRate = setRate = (unsigned int) sampleRate; ENSURE_( alsa_snd_pcm_hw_params_set_rate_near( pcm, hwParams, &setRate, NULL ), paUnanticipatedHostError ); /* The value actually set will be put in 'setRate' (may be way off); check the deviation as a proportion * of the requested-rate with reference to the max-deviate-ratio (larger values allow less deviation) */ deviation = abs( setRate - reqRate ); if( deviation > 0 && deviation * RATE_MAX_DEVIATE_RATIO > reqRate ) result = paInvalidSampleRate; end: return result; error: /* Log */ { unsigned int _min = 0, _max = 0; int _dir = 0; ENSURE_( alsa_snd_pcm_hw_params_get_rate_min( hwParams, &_min, &_dir ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_get_rate_max( hwParams, &_max, &_dir ), paUnanticipatedHostError ); PA_DEBUG(( "%s: SR min = %u, max = %u, req = %u\n", __FUNCTION__, _min, _max, reqRate )); } goto end; } /* Return exact sample rate in param sampleRate */ static int GetExactSampleRate( snd_pcm_hw_params_t *hwParams, double *sampleRate ) { unsigned int num, den = 1; int err; assert( hwParams ); err = alsa_snd_pcm_hw_params_get_rate_numden( hwParams, &num, &den ); *sampleRate = (double) num / den; return err; } /* Utility functions for blocking/callback interfaces */ /* Atomic restart of stream (we don't want the intermediate state visible) */ static PaError AlsaRestart( PaAlsaStream *stream ) { PaError result = paNoError; PA_ENSURE( PaUnixMutex_Lock( &stream->stateMtx ) ); PA_ENSURE( AlsaStop( stream, 0 ) ); PA_ENSURE( AlsaStart( stream, 0 ) ); PA_DEBUG(( "%s: Restarted audio\n", __FUNCTION__ )); error: PA_ENSURE( PaUnixMutex_Unlock( &stream->stateMtx ) ); return result; } /** Recover from xrun state. * */ static PaError PaAlsaStream_HandleXrun( PaAlsaStream *self ) { PaError result = paNoError; snd_pcm_status_t *st; PaTime now = PaUtil_GetTime(); snd_timestamp_t t; int restartAlsa = 0; /* do not restart Alsa by default */ alsa_snd_pcm_status_alloca( &st ); if( self->playback.pcm ) { alsa_snd_pcm_status( self->playback.pcm, st ); if( alsa_snd_pcm_status_get_state( st ) == SND_PCM_STATE_XRUN ) { alsa_snd_pcm_status_get_trigger_tstamp( st, &t ); self->underrun = now * 1000 - ( (PaTime)t.tv_sec * 1000 + (PaTime)t.tv_usec / 1000 ); if( !self->playback.canMmap ) { if( alsa_snd_pcm_recover( self->playback.pcm, -EPIPE, 0 ) < 0 ) { PA_DEBUG(( "%s: [playback] non-MMAP-PCM failed recovering from XRUN, will restart Alsa\n", __FUNCTION__ )); ++ restartAlsa; /* did not manage to recover */ } } else ++ restartAlsa; /* always restart MMAPed device */ } } if( self->capture.pcm ) { alsa_snd_pcm_status( self->capture.pcm, st ); if( alsa_snd_pcm_status_get_state( st ) == SND_PCM_STATE_XRUN ) { alsa_snd_pcm_status_get_trigger_tstamp( st, &t ); self->overrun = now * 1000 - ((PaTime) t.tv_sec * 1000 + (PaTime) t.tv_usec / 1000); if (!self->capture.canMmap) { if (alsa_snd_pcm_recover( self->capture.pcm, -EPIPE, 0 ) < 0) { PA_DEBUG(( "%s: [capture] non-MMAP-PCM failed recovering from XRUN, will restart Alsa\n", __FUNCTION__ )); ++ restartAlsa; /* did not manage to recover */ } } else ++ restartAlsa; /* always restart MMAPed device */ } } if( restartAlsa ) { PA_DEBUG(( "%s: restarting Alsa to recover from XRUN\n", __FUNCTION__ )); PA_ENSURE( AlsaRestart( self ) ); } end: return result; error: goto end; } /** Decide if we should continue polling for specified direction, eventually adjust the poll timeout. * */ static PaError ContinuePoll( const PaAlsaStream *stream, StreamDirection streamDir, int *pollTimeout, int *continuePoll ) { PaError result = paNoError; snd_pcm_sframes_t delay, margin; int err; const PaAlsaStreamComponent *component = NULL, *otherComponent = NULL; *continuePoll = 1; if( StreamDirection_In == streamDir ) { component = &stream->capture; otherComponent = &stream->playback; } else { component = &stream->playback; otherComponent = &stream->capture; } /* ALSA docs say that negative delay should indicate xrun, but in my experience alsa_snd_pcm_delay returns -EPIPE */ if( ( err = alsa_snd_pcm_delay( otherComponent->pcm, &delay ) ) < 0 ) { if( err == -EPIPE ) { /* Xrun */ *continuePoll = 0; goto error; } ENSURE_( err, paUnanticipatedHostError ); } if( StreamDirection_Out == streamDir ) { /* Number of eligible frames before capture overrun */ delay = otherComponent->alsaBufferSize - delay; } margin = delay - otherComponent->framesPerPeriod / 2; if( margin < 0 ) { PA_DEBUG(( "%s: Stopping poll for %s\n", __FUNCTION__, StreamDirection_In == streamDir ? "capture" : "playback" )); *continuePoll = 0; } else if( margin < otherComponent->framesPerPeriod ) { *pollTimeout = CalculatePollTimeout( stream, margin ); PA_DEBUG(( "%s: Trying to poll again for %s frames, pollTimeout: %d\n", __FUNCTION__, StreamDirection_In == streamDir ? "capture" : "playback", *pollTimeout )); } error: return result; } /* Callback interface */ static void OnExit( void *data ) { PaAlsaStream *stream = (PaAlsaStream *) data; assert( data ); PaUtil_ResetCpuLoadMeasurer( &stream->cpuLoadMeasurer ); stream->callback_finished = 1; /* Let the outside world know stream was stopped in callback */ PA_DEBUG(( "%s: Stopping ALSA handles\n", __FUNCTION__ )); AlsaStop( stream, stream->callbackAbort ); PA_DEBUG(( "%s: Stoppage\n", __FUNCTION__ )); /* Eventually notify user all buffers have played */ if( stream->streamRepresentation.streamFinishedCallback ) { stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); } stream->isActive = 0; } static void CalculateTimeInfo( PaAlsaStream *stream, PaStreamCallbackTimeInfo *timeInfo ) { snd_pcm_status_t *capture_status, *playback_status; snd_timestamp_t capture_timestamp, playback_timestamp; PaTime capture_time = 0., playback_time = 0.; alsa_snd_pcm_status_alloca( &capture_status ); alsa_snd_pcm_status_alloca( &playback_status ); if( stream->capture.pcm ) { snd_pcm_sframes_t capture_delay; alsa_snd_pcm_status( stream->capture.pcm, capture_status ); alsa_snd_pcm_status_get_tstamp( capture_status, &capture_timestamp ); capture_time = capture_timestamp.tv_sec + ( (PaTime)capture_timestamp.tv_usec / 1000000.0 ); timeInfo->currentTime = capture_time; capture_delay = alsa_snd_pcm_status_get_delay( capture_status ); timeInfo->inputBufferAdcTime = timeInfo->currentTime - (PaTime)capture_delay / stream->streamRepresentation.streamInfo.sampleRate; } if( stream->playback.pcm ) { snd_pcm_sframes_t playback_delay; alsa_snd_pcm_status( stream->playback.pcm, playback_status ); alsa_snd_pcm_status_get_tstamp( playback_status, &playback_timestamp ); playback_time = playback_timestamp.tv_sec + ((PaTime)playback_timestamp.tv_usec / 1000000.0); if( stream->capture.pcm ) /* Full duplex */ { /* Hmm, we have both a playback and a capture timestamp. * Hopefully they are the same... */ if( fabs( capture_time - playback_time ) > 0.01 ) PA_DEBUG(( "Capture time and playback time differ by %f\n", fabs( capture_time-playback_time ) )); } else timeInfo->currentTime = playback_time; playback_delay = alsa_snd_pcm_status_get_delay( playback_status ); timeInfo->outputBufferDacTime = timeInfo->currentTime + (PaTime)playback_delay / stream->streamRepresentation.streamInfo.sampleRate; } } /** Called after buffer processing is finished. * * A number of mmapped frames is committed, it is possible that an xrun has occurred in the meantime. * * @param numFrames The number of frames that has been processed * @param xrun Return whether an xrun has occurred */ static PaError PaAlsaStreamComponent_EndProcessing( PaAlsaStreamComponent *self, unsigned long numFrames, int *xrun ) { PaError result = paNoError; int res = 0; /* @concern FullDuplex It is possible that only one direction is marked ready after polling, and processed * afterwards */ if( !self->ready ) goto end; if( !self->canMmap && StreamDirection_Out == self->streamDir ) { /* Play sound */ if( self->hostInterleaved ) res = alsa_snd_pcm_writei( self->pcm, self->nonMmapBuffer, numFrames ); else { void *bufs[self->numHostChannels]; int bufsize = alsa_snd_pcm_format_size( self->nativeFormat, self->framesPerPeriod + 1 ); unsigned char *buffer = self->nonMmapBuffer; int i; for( i = 0; i < self->numHostChannels; ++i ) { bufs[i] = buffer; buffer += bufsize; } res = alsa_snd_pcm_writen( self->pcm, bufs, numFrames ); } } if( self->canMmap ) res = alsa_snd_pcm_mmap_commit( self->pcm, self->offset, numFrames ); if( res == -EPIPE || res == -ESTRPIPE ) { *xrun = 1; } else { ENSURE_( res, paUnanticipatedHostError ); } end: error: return result; } /* Extract buffer from channel area */ static unsigned char *ExtractAddress( const snd_pcm_channel_area_t *area, snd_pcm_uframes_t offset ) { return (unsigned char *) area->addr + ( area->first + offset * area->step ) / 8; } /** Do necessary adaption between user and host channels. * @concern ChannelAdaption Adapting between user and host channels can involve silencing unused channels and duplicating mono information if host outputs come in pairs. */ static PaError PaAlsaStreamComponent_DoChannelAdaption( PaAlsaStreamComponent *self, PaUtilBufferProcessor *bp, int numFrames ) { PaError result = paNoError; unsigned char *p; int i; int unusedChans = self->numHostChannels - self->numUserChannels; unsigned char *src, *dst; int convertMono = ( self->numHostChannels % 2 ) == 0 && ( self->numUserChannels % 2 ) != 0; assert( StreamDirection_Out == self->streamDir ); if( self->hostInterleaved ) { int swidth = alsa_snd_pcm_format_size( self->nativeFormat, 1 ); unsigned char *buffer = self->canMmap ? ExtractAddress( self->channelAreas, self->offset ) : self->nonMmapBuffer; /* Start after the last user channel */ p = buffer + self->numUserChannels * swidth; if( convertMono ) { /* Convert the last user channel into stereo pair */ src = buffer + ( self->numUserChannels - 1 ) * swidth; for( i = 0; i < numFrames; ++i ) { dst = src + swidth; memcpy( dst, src, swidth ); src += self->numHostChannels * swidth; } /* Don't touch the channel we just wrote to */ p += swidth; --unusedChans; } if( unusedChans > 0 ) { /* Silence unused output channels */ for( i = 0; i < numFrames; ++i ) { memset( p, 0, swidth * unusedChans ); p += self->numHostChannels * swidth; } } } else { /* We extract the last user channel */ if( convertMono ) { ENSURE_( alsa_snd_pcm_area_copy( self->channelAreas + self->numUserChannels, self->offset, self->channelAreas + ( self->numUserChannels - 1 ), self->offset, numFrames, self->nativeFormat ), paUnanticipatedHostError ); --unusedChans; } if( unusedChans > 0 ) { alsa_snd_pcm_areas_silence( self->channelAreas + ( self->numHostChannels - unusedChans ), self->offset, unusedChans, numFrames, self->nativeFormat ); } } error: return result; } static PaError PaAlsaStream_EndProcessing( PaAlsaStream *self, unsigned long numFrames, int *xrunOccurred ) { PaError result = paNoError; int xrun = 0; if( self->capture.pcm ) { PA_ENSURE( PaAlsaStreamComponent_EndProcessing( &self->capture, numFrames, &xrun ) ); } if( self->playback.pcm ) { if( self->playback.numHostChannels > self->playback.numUserChannels ) { PA_ENSURE( PaAlsaStreamComponent_DoChannelAdaption( &self->playback, &self->bufferProcessor, numFrames ) ); } PA_ENSURE( PaAlsaStreamComponent_EndProcessing( &self->playback, numFrames, &xrun ) ); } error: *xrunOccurred = xrun; return result; } /** Update the number of available frames. * */ static PaError PaAlsaStreamComponent_GetAvailableFrames( PaAlsaStreamComponent *self, unsigned long *numFrames, int *xrunOccurred ) { PaError result = paNoError; snd_pcm_sframes_t framesAvail = alsa_snd_pcm_avail_update( self->pcm ); *xrunOccurred = 0; if( -EPIPE == framesAvail ) { *xrunOccurred = 1; framesAvail = 0; } else { ENSURE_( framesAvail, paUnanticipatedHostError ); } *numFrames = framesAvail; error: return result; } /** Fill in pollfd objects. */ static PaError PaAlsaStreamComponent_BeginPolling( PaAlsaStreamComponent* self, struct pollfd* pfds ) { PaError result = paNoError; int ret = alsa_snd_pcm_poll_descriptors( self->pcm, pfds, self->nfds ); (void)ret; /* Prevent unused variable warning if asserts are turned off */ assert( ret == self->nfds ); self->ready = 0; return result; } /** Examine results from poll(). * * @param pfds pollfds to inspect * @param shouldPoll Should we continue to poll * @param xrun Has an xrun occurred */ static PaError PaAlsaStreamComponent_EndPolling( PaAlsaStreamComponent* self, struct pollfd* pfds, int* shouldPoll, int* xrun ) { PaError result = paNoError; unsigned short revents; ENSURE_( alsa_snd_pcm_poll_descriptors_revents( self->pcm, pfds, self->nfds, &revents ), paUnanticipatedHostError ); if( revents != 0 ) { if( revents & POLLERR ) { *xrun = 1; } else if( revents & POLLHUP ) { *xrun = 1; PA_DEBUG(( "%s: revents has POLLHUP, processing as XRUN\n", __FUNCTION__ )); } else self->ready = 1; *shouldPoll = 0; } else /* (A zero revent occurred) */ /* Work around an issue with Alsa older than 1.0.16 using some plugins (eg default with plug + dmix) where * POLLIN or POLLOUT are zeroed by Alsa-lib if _mmap_avail() is a few frames short of avail_min at period * boundary, possibly due to erratic dma interrupts at period boundary? Treat as a valid event. */ if( self->useReventFix ) { self->ready = 1; *shouldPoll = 0; } error: return result; } /** Return the number of available frames for this stream. * * @concern FullDuplex The minimum available for the two directions is calculated, it might be desirable to ignore * one direction however (not marked ready from poll), so this is controlled by queryCapture and queryPlayback. * * @param queryCapture Check available for capture * @param queryPlayback Check available for playback * @param available The returned number of frames * @param xrunOccurred Return whether an xrun has occurred */ static PaError PaAlsaStream_GetAvailableFrames( PaAlsaStream *self, int queryCapture, int queryPlayback, unsigned long *available, int *xrunOccurred ) { PaError result = paNoError; unsigned long captureFrames, playbackFrames; *xrunOccurred = 0; assert( queryCapture || queryPlayback ); if( queryCapture ) { assert( self->capture.pcm ); PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &self->capture, &captureFrames, xrunOccurred ) ); if( *xrunOccurred ) { goto end; } } if( queryPlayback ) { assert( self->playback.pcm ); PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &self->playback, &playbackFrames, xrunOccurred ) ); if( *xrunOccurred ) { goto end; } } if( queryCapture && queryPlayback ) { *available = PA_MIN( captureFrames, playbackFrames ); /*PA_DEBUG(("capture: %lu, playback: %lu, combined: %lu\n", captureFrames, playbackFrames, *available));*/ } else if( queryCapture ) { *available = captureFrames; } else { *available = playbackFrames; } end: error: return result; } /** Wait for and report available buffer space from ALSA. * * Unless ALSA reports a minimum of frames available for I/O, we poll the ALSA filedescriptors for more. * Both of these operations can uncover xrun conditions. * * @concern Xruns Both polling and querying available frames can report an xrun condition. * * @param framesAvail Return the number of available frames * @param xrunOccurred Return whether an xrun has occurred */ static PaError PaAlsaStream_WaitForFrames( PaAlsaStream *self, unsigned long *framesAvail, int *xrunOccurred ) { PaError result = paNoError; int pollPlayback = self->playback.pcm != NULL, pollCapture = self->capture.pcm != NULL; int pollTimeout = self->pollTimeout; int xrun = 0, timeouts = 0; int pollResults; assert( self ); assert( framesAvail ); if( !self->callbackMode ) { /* In blocking mode we will only wait if necessary */ PA_ENSURE( PaAlsaStream_GetAvailableFrames( self, self->capture.pcm != NULL, self->playback.pcm != NULL, framesAvail, &xrun ) ); if( xrun ) { goto end; } if( *framesAvail > 0 ) { /* Mark pcms ready from poll */ if( self->capture.pcm ) self->capture.ready = 1; if( self->playback.pcm ) self->playback.ready = 1; goto end; } } while( pollPlayback || pollCapture ) { int totalFds = 0; struct pollfd *capturePfds = NULL, *playbackPfds = NULL; #ifdef PTHREAD_CANCELED pthread_testcancel(); #endif if( pollCapture ) { capturePfds = self->pfds; PA_ENSURE( PaAlsaStreamComponent_BeginPolling( &self->capture, capturePfds ) ); totalFds += self->capture.nfds; } if( pollPlayback ) { /* self->pfds is in effect an array of fds; if necessary, index past the capture fds */ playbackPfds = self->pfds + (pollCapture ? self->capture.nfds : 0); PA_ENSURE( PaAlsaStreamComponent_BeginPolling( &self->playback, playbackPfds ) ); totalFds += self->playback.nfds; } pollResults = poll( self->pfds, totalFds, pollTimeout ); if( pollResults < 0 ) { /* XXX: Depend on preprocessor condition? */ if( errno == EINTR ) { /* gdb */ Pa_Sleep( 1 ); /* avoid hot loop */ continue; } /* TODO: Add macro for checking system calls */ PA_ENSURE( paInternalError ); } else if( pollResults == 0 ) { /* Suspended, paused or failed device can provide 0 poll results. To avoid deadloop in such situation * we simply run counter 'timeouts' which detects 0 poll result and accumulates. As soon as 2048 timouts (around 2 seconds) * are achieved we simply fail function with paTimedOut to notify waiting methods that device is not capable * of providing audio data anymore and needs some corresponding recovery action. * Note that 'timeouts' is reset to 0 if poll() managed to return non 0 results. */ /*PA_DEBUG(( "%s: poll == 0 results, timed out, %d times left\n", __FUNCTION__, 2048 - timeouts ));*/ ++ timeouts; if( timeouts > 1 ) /* sometimes device times out, but normally once, so we do not sleep any time */ { Pa_Sleep( 1 ); /* avoid hot loop */ } /* not else ! */ if( timeouts >= 2048 ) /* audio device not working, shall return error to notify waiters */ { *framesAvail = 0; /* no frames available for processing */ xrun = 1; /* try recovering device */ PA_DEBUG(( "%s: poll timed out\n", __FUNCTION__, timeouts )); goto end;/*PA_ENSURE( paTimedOut );*/ } } else if( pollResults > 0 ) { /* reset timouts counter */ timeouts = 0; /* check the return status of our pfds */ if( pollCapture ) { PA_ENSURE( PaAlsaStreamComponent_EndPolling( &self->capture, capturePfds, &pollCapture, &xrun ) ); } if( pollPlayback ) { PA_ENSURE( PaAlsaStreamComponent_EndPolling( &self->playback, playbackPfds, &pollPlayback, &xrun ) ); } if( xrun ) { break; } } /* @concern FullDuplex If only one of two pcms is ready we may want to compromise between the two. * If there is less than half a period's worth of samples left of frames in the other pcm's buffer we will * stop polling. */ if( self->capture.pcm && self->playback.pcm ) { if( pollCapture && !pollPlayback ) { PA_ENSURE( ContinuePoll( self, StreamDirection_In, &pollTimeout, &pollCapture ) ); } else if( pollPlayback && !pollCapture ) { PA_ENSURE( ContinuePoll( self, StreamDirection_Out, &pollTimeout, &pollPlayback ) ); } } } if( !xrun ) { /* Get the number of available frames for the pcms that are marked ready. * @concern FullDuplex If only one direction is marked ready (from poll), the number of frames available for * the other direction is returned. Output is normally preferred over capture however, so capture frames may be * discarded to avoid overrun unless paNeverDropInput is specified. */ int captureReady = self->capture.pcm ? self->capture.ready : 0, playbackReady = self->playback.pcm ? self->playback.ready : 0; PA_ENSURE( PaAlsaStream_GetAvailableFrames( self, captureReady, playbackReady, framesAvail, &xrun ) ); if( self->capture.pcm && self->playback.pcm ) { if( !self->playback.ready && !self->neverDropInput ) { /* Drop input, a period's worth */ assert( self->capture.ready ); PaAlsaStreamComponent_EndProcessing( &self->capture, PA_MIN( self->capture.framesPerPeriod, *framesAvail ), &xrun ); *framesAvail = 0; self->capture.ready = 0; } } else if( self->capture.pcm ) assert( self->capture.ready ); else assert( self->playback.ready ); } end: error: if( xrun ) { /* Recover from the xrun state */ PA_ENSURE( PaAlsaStream_HandleXrun( self ) ); *framesAvail = 0; } else { if( 0 != *framesAvail ) { /* If we're reporting frames eligible for processing, one of the handles better be ready */ PA_UNLESS( self->capture.ready || self->playback.ready, paInternalError ); } } *xrunOccurred = xrun; return result; } /** Register per-channel ALSA buffer information with buffer processor. * * Mmapped buffer space is acquired from ALSA, and registered with the buffer processor. Differences between the * number of host and user channels is taken into account. * * @param numFrames On entrance the number of requested frames, on exit the number of contiguously accessible frames. */ static PaError PaAlsaStreamComponent_RegisterChannels( PaAlsaStreamComponent* self, PaUtilBufferProcessor* bp, unsigned long* numFrames, int* xrun ) { PaError result = paNoError; const snd_pcm_channel_area_t *areas, *area; void (*setChannel)(PaUtilBufferProcessor *, unsigned int, void *, unsigned int) = StreamDirection_In == self->streamDir ? PaUtil_SetInputChannel : PaUtil_SetOutputChannel; unsigned char *buffer, *p; int i; unsigned long framesAvail; /* This _must_ be called before mmap_begin */ PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( self, &framesAvail, xrun ) ); if( *xrun ) { *numFrames = 0; goto end; } if( self->canMmap ) { ENSURE_( alsa_snd_pcm_mmap_begin( self->pcm, &areas, &self->offset, numFrames ), paUnanticipatedHostError ); /* @concern ChannelAdaption Buffer address is recorded so we can do some channel adaption later */ self->channelAreas = (snd_pcm_channel_area_t *)areas; } else { unsigned int bufferSize = self->numHostChannels * alsa_snd_pcm_format_size( self->nativeFormat, *numFrames ); if( bufferSize > self->nonMmapBufferSize ) { self->nonMmapBuffer = realloc( self->nonMmapBuffer, ( self->nonMmapBufferSize = bufferSize ) ); if( !self->nonMmapBuffer ) { result = paInsufficientMemory; goto error; } } } if( self->hostInterleaved ) { int swidth = alsa_snd_pcm_format_size( self->nativeFormat, 1 ); p = buffer = self->canMmap ? ExtractAddress( areas, self->offset ) : self->nonMmapBuffer; for( i = 0; i < self->numUserChannels; ++i ) { /* We're setting the channels up to userChannels, but the stride will be hostChannels samples */ setChannel( bp, i, p, self->numHostChannels ); p += swidth; } } else { if( self->canMmap ) { for( i = 0; i < self->numUserChannels; ++i ) { area = areas + i; buffer = ExtractAddress( area, self->offset ); setChannel( bp, i, buffer, 1 ); } } else { unsigned int buf_per_ch_size = self->nonMmapBufferSize / self->numHostChannels; buffer = self->nonMmapBuffer; for( i = 0; i < self->numUserChannels; ++i ) { setChannel( bp, i, buffer, 1 ); buffer += buf_per_ch_size; } } } if( !self->canMmap && StreamDirection_In == self->streamDir ) { /* Read sound */ int res; if( self->hostInterleaved ) res = alsa_snd_pcm_readi( self->pcm, self->nonMmapBuffer, *numFrames ); else { void *bufs[self->numHostChannels]; unsigned int buf_per_ch_size = self->nonMmapBufferSize / self->numHostChannels; unsigned char *buffer = self->nonMmapBuffer; int i; for( i = 0; i < self->numHostChannels; ++i ) { bufs[i] = buffer; buffer += buf_per_ch_size; } res = alsa_snd_pcm_readn( self->pcm, bufs, *numFrames ); } if( res == -EPIPE || res == -ESTRPIPE ) { *xrun = 1; *numFrames = 0; } } end: error: return result; } /** Initiate buffer processing. * * ALSA buffers are registered with the PA buffer processor and the buffer size (in frames) set. * * @concern FullDuplex If both directions are being processed, the minimum amount of frames for the two directions is * calculated. * * @param numFrames On entrance the number of available frames, on exit the number of received frames * @param xrunOccurred Return whether an xrun has occurred */ static PaError PaAlsaStream_SetUpBuffers( PaAlsaStream* self, unsigned long* numFrames, int* xrunOccurred ) { PaError result = paNoError; unsigned long captureFrames = ULONG_MAX, playbackFrames = ULONG_MAX, commonFrames = 0; int xrun = 0; if( *xrunOccurred ) { *numFrames = 0; return result; } /* If we got here at least one of the pcm's should be marked ready */ PA_UNLESS( self->capture.ready || self->playback.ready, paInternalError ); /* Extract per-channel ALSA buffer pointers and register them with the buffer processor. * It is possible that a direction is not marked ready however, because it is out of sync with the other. */ if( self->capture.pcm && self->capture.ready ) { captureFrames = *numFrames; PA_ENSURE( PaAlsaStreamComponent_RegisterChannels( &self->capture, &self->bufferProcessor, &captureFrames, &xrun ) ); } if( self->playback.pcm && self->playback.ready ) { playbackFrames = *numFrames; PA_ENSURE( PaAlsaStreamComponent_RegisterChannels( &self->playback, &self->bufferProcessor, &playbackFrames, &xrun ) ); } if( xrun ) { /* Nothing more to do */ assert( 0 == commonFrames ); goto end; } commonFrames = PA_MIN( captureFrames, playbackFrames ); /* assert( commonFrames <= *numFrames ); */ if( commonFrames > *numFrames ) { /* Hmmm ... how come there are more frames available than we requested!? Blah. */ PA_DEBUG(( "%s: Common available frames are reported to be more than number requested: %lu, %lu, callbackMode: %d\n", __FUNCTION__, commonFrames, *numFrames, self->callbackMode )); if( self->capture.pcm ) { PA_DEBUG(( "%s: captureFrames: %lu, capture.ready: %d\n", __FUNCTION__, captureFrames, self->capture.ready )); } if( self->playback.pcm ) { PA_DEBUG(( "%s: playbackFrames: %lu, playback.ready: %d\n", __FUNCTION__, playbackFrames, self->playback.ready )); } commonFrames = 0; goto end; } /* Inform PortAudio of the number of frames we got. * @concern FullDuplex We might be experiencing underflow in either end; if its an input underflow, we go on * with output. If its output underflow however, depending on the paNeverDropInput flag, we may want to simply * discard the excess input or call the callback with paOutputOverflow flagged. */ if( self->capture.pcm ) { if( self->capture.ready ) { PaUtil_SetInputFrameCount( &self->bufferProcessor, commonFrames ); } else { /* We have input underflow */ PaUtil_SetNoInput( &self->bufferProcessor ); } } if( self->playback.pcm ) { if( self->playback.ready ) { PaUtil_SetOutputFrameCount( &self->bufferProcessor, commonFrames ); } else { /* We have output underflow, but keeping input data (paNeverDropInput) */ assert( self->neverDropInput ); assert( self->capture.pcm != NULL ); PA_DEBUG(( "%s: Setting output buffers to NULL\n", __FUNCTION__ )); PaUtil_SetNoOutput( &self->bufferProcessor ); } } end: *numFrames = commonFrames; error: if( xrun ) { PA_ENSURE( PaAlsaStream_HandleXrun( self ) ); *numFrames = 0; } *xrunOccurred = xrun; return result; } /** Callback thread's function. * * Roughly, the workflow can be described in the following way: The number of available frames that can be processed * directly is obtained from ALSA, we then request as much directly accessible memory as possible within this amount * from ALSA. The buffer memory is registered with the PA buffer processor and processing is carried out with * PaUtil_EndBufferProcessing. Finally, the number of processed frames is reported to ALSA. The processing can * happen in several iterations untill we have consumed the known number of available frames (or an xrun is detected). */ static void *CallbackThreadFunc( void *userData ) { PaError result = paNoError; PaAlsaStream *stream = (PaAlsaStream*) userData; PaStreamCallbackTimeInfo timeInfo = {0, 0, 0}; snd_pcm_sframes_t startThreshold = 0; int callbackResult = paContinue; PaStreamCallbackFlags cbFlags = 0; /* We might want to keep state across iterations */ int streamStarted = 0; assert( stream ); /* Execute OnExit when exiting */ pthread_cleanup_push( &OnExit, stream ); /* Not implemented */ assert( !stream->primeBuffers ); /* @concern StreamStart If the output is being primed the output pcm needs to be prepared, otherwise the * stream is started immediately. The latter involves signaling the waiting main thread. */ if( stream->primeBuffers ) { snd_pcm_sframes_t avail; if( stream->playback.pcm ) ENSURE_( alsa_snd_pcm_prepare( stream->playback.pcm ), paUnanticipatedHostError ); if( stream->capture.pcm && !stream->pcmsSynced ) ENSURE_( alsa_snd_pcm_prepare( stream->capture.pcm ), paUnanticipatedHostError ); /* We can't be certain that the whole ring buffer is available for priming, but there should be * at least one period */ avail = alsa_snd_pcm_avail_update( stream->playback.pcm ); startThreshold = avail - (avail % stream->playback.framesPerPeriod); assert( startThreshold >= stream->playback.framesPerPeriod ); } else { PA_ENSURE( PaUnixThread_PrepareNotify( &stream->thread ) ); /* Buffer will be zeroed */ PA_ENSURE( AlsaStart( stream, 0 ) ); PA_ENSURE( PaUnixThread_NotifyParent( &stream->thread ) ); streamStarted = 1; } while( 1 ) { unsigned long framesAvail, framesGot; int xrun = 0; #ifdef PTHREAD_CANCELED pthread_testcancel(); #endif /* @concern StreamStop if the main thread has requested a stop and the stream has not been effectively * stopped we signal this condition by modifying callbackResult (we'll want to flush buffered output). */ if( PaUnixThread_StopRequested( &stream->thread ) && paContinue == callbackResult ) { PA_DEBUG(( "Setting callbackResult to paComplete\n" )); callbackResult = paComplete; } if( paContinue != callbackResult ) { stream->callbackAbort = ( paAbort == callbackResult ); if( stream->callbackAbort || /** @concern BlockAdaption: Go on if adaption buffers are empty */ PaUtil_IsBufferProcessorOutputEmpty( &stream->bufferProcessor ) ) { goto end; } PA_DEBUG(( "%s: Flushing buffer processor\n", __FUNCTION__ )); /* There is still buffered output that needs to be processed */ } /* Wait for data to become available, this comes down to polling the ALSA file descriptors untill we have * a number of available frames. */ PA_ENSURE( PaAlsaStream_WaitForFrames( stream, &framesAvail, &xrun ) ); if( xrun ) { assert( 0 == framesAvail ); continue; /* XXX: Report xruns to the user? A situation is conceivable where the callback is never invoked due * to constant xruns, it might be desirable to notify the user of this. */ } /* Consume buffer space. Once we have a number of frames available for consumption we must retrieve the * mmapped buffers from ALSA, this is contiguously accessible memory however, so we may receive smaller * portions at a time than is available as a whole. Therefore we should be prepared to process several * chunks successively. The buffers are passed to the PA buffer processor. */ while( framesAvail > 0 ) { xrun = 0; #ifdef PTHREAD_CANCELED pthread_testcancel(); #endif /** @concern Xruns Under/overflows are to be reported to the callback */ if( stream->underrun > 0.0 ) { cbFlags |= paOutputUnderflow; stream->underrun = 0.0; } if( stream->overrun > 0.0 ) { cbFlags |= paInputOverflow; stream->overrun = 0.0; } if( stream->capture.pcm && stream->playback.pcm ) { /** @concern FullDuplex It's possible that only one direction is being processed to avoid an * under- or overflow, this should be reported correspondingly */ if( !stream->capture.ready ) { cbFlags |= paInputUnderflow; PA_DEBUG(( "%s: Input underflow\n", __FUNCTION__ )); } else if( !stream->playback.ready ) { cbFlags |= paOutputOverflow; PA_DEBUG(( "%s: Output overflow\n", __FUNCTION__ )); } } #if 0 CallbackUpdate( &stream->threading ); #endif CalculateTimeInfo( stream, &timeInfo ); PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, cbFlags ); cbFlags = 0; /* CPU load measurement should include processing activivity external to the stream callback */ PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); framesGot = framesAvail; if( paUtilFixedHostBufferSize == stream->bufferProcessor.hostBufferSizeMode ) { /* We've committed to a fixed host buffer size, stick to that */ framesGot = framesGot >= stream->maxFramesPerHostBuffer ? stream->maxFramesPerHostBuffer : 0; } else { /* We've committed to an upper bound on the size of host buffers */ assert( paUtilBoundedHostBufferSize == stream->bufferProcessor.hostBufferSizeMode ); framesGot = PA_MIN( framesGot, stream->maxFramesPerHostBuffer ); } PA_ENSURE( PaAlsaStream_SetUpBuffers( stream, &framesGot, &xrun ) ); /* Check the host buffer size against the buffer processor configuration */ framesAvail -= framesGot; if( framesGot > 0 ) { assert( !xrun ); PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult ); PA_ENSURE( PaAlsaStream_EndProcessing( stream, framesGot, &xrun ) ); } PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesGot ); if( 0 == framesGot ) { /* Go back to polling for more frames */ break; } if( paContinue != callbackResult ) break; } } end: ; /* Hack to fix "label at end of compound statement" error caused by pthread_cleanup_pop(1) macro. */ /* Match pthread_cleanup_push */ pthread_cleanup_pop( 1 ); PA_DEBUG(( "%s: Thread %d exiting\n ", __FUNCTION__, pthread_self() )); PaUnixThreading_EXIT( result ); error: PA_DEBUG(( "%s: Thread %d is canceled due to error %d\n ", __FUNCTION__, pthread_self(), result )); goto end; } /* Blocking interface */ static PaError ReadStream( PaStream* s, void *buffer, unsigned long frames ) { PaError result = paNoError; PaAlsaStream *stream = (PaAlsaStream*)s; unsigned long framesGot, framesAvail; void *userBuffer; snd_pcm_t *save = stream->playback.pcm; assert( stream ); PA_UNLESS( stream->capture.pcm, paCanNotReadFromAnOutputOnlyStream ); /* Disregard playback */ stream->playback.pcm = NULL; if( stream->overrun > 0. ) { result = paInputOverflowed; stream->overrun = 0.0; } if( stream->capture.userInterleaved ) { userBuffer = buffer; } else { /* Copy channels into local array */ userBuffer = stream->capture.userBuffers; memcpy( userBuffer, buffer, sizeof (void *) * stream->capture.numUserChannels ); } /* Start stream if in prepared state */ if( alsa_snd_pcm_state( stream->capture.pcm ) == SND_PCM_STATE_PREPARED ) { ENSURE_( alsa_snd_pcm_start( stream->capture.pcm ), paUnanticipatedHostError ); } while( frames > 0 ) { int xrun = 0; PA_ENSURE( PaAlsaStream_WaitForFrames( stream, &framesAvail, &xrun ) ); framesGot = PA_MIN( framesAvail, frames ); PA_ENSURE( PaAlsaStream_SetUpBuffers( stream, &framesGot, &xrun ) ); if( framesGot > 0 ) { framesGot = PaUtil_CopyInput( &stream->bufferProcessor, &userBuffer, framesGot ); PA_ENSURE( PaAlsaStream_EndProcessing( stream, framesGot, &xrun ) ); frames -= framesGot; } } end: stream->playback.pcm = save; return result; error: goto end; } static PaError WriteStream( PaStream* s, const void *buffer, unsigned long frames ) { PaError result = paNoError; signed long err; PaAlsaStream *stream = (PaAlsaStream*)s; snd_pcm_uframes_t framesGot, framesAvail; const void *userBuffer; snd_pcm_t *save = stream->capture.pcm; assert( stream ); PA_UNLESS( stream->playback.pcm, paCanNotWriteToAnInputOnlyStream ); /* Disregard capture */ stream->capture.pcm = NULL; if( stream->underrun > 0. ) { result = paOutputUnderflowed; stream->underrun = 0.0; } if( stream->playback.userInterleaved ) userBuffer = buffer; else /* Copy channels into local array */ { userBuffer = stream->playback.userBuffers; memcpy( (void *)userBuffer, buffer, sizeof (void *) * stream->playback.numUserChannels ); } while( frames > 0 ) { int xrun = 0; snd_pcm_uframes_t hwAvail; PA_ENSURE( PaAlsaStream_WaitForFrames( stream, &framesAvail, &xrun ) ); framesGot = PA_MIN( framesAvail, frames ); PA_ENSURE( PaAlsaStream_SetUpBuffers( stream, &framesGot, &xrun ) ); if( framesGot > 0 ) { framesGot = PaUtil_CopyOutput( &stream->bufferProcessor, &userBuffer, framesGot ); PA_ENSURE( PaAlsaStream_EndProcessing( stream, framesGot, &xrun ) ); frames -= framesGot; } /* Start stream after one period of samples worth */ /* Frames residing in buffer */ PA_ENSURE( err = GetStreamWriteAvailable( stream ) ); framesAvail = err; hwAvail = stream->playback.alsaBufferSize - framesAvail; if( alsa_snd_pcm_state( stream->playback.pcm ) == SND_PCM_STATE_PREPARED && hwAvail >= stream->playback.framesPerPeriod ) { ENSURE_( alsa_snd_pcm_start( stream->playback.pcm ), paUnanticipatedHostError ); } } end: stream->capture.pcm = save; return result; error: goto end; } /* Return frames available for reading. In the event of an overflow, the capture pcm will be restarted */ static signed long GetStreamReadAvailable( PaStream* s ) { PaError result = paNoError; PaAlsaStream *stream = (PaAlsaStream*)s; unsigned long avail; int xrun; PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &stream->capture, &avail, &xrun ) ); if( xrun ) { PA_ENSURE( PaAlsaStream_HandleXrun( stream ) ); PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &stream->capture, &avail, &xrun ) ); if( xrun ) PA_ENSURE( paInputOverflowed ); } return (signed long)avail; error: return result; } static signed long GetStreamWriteAvailable( PaStream* s ) { PaError result = paNoError; PaAlsaStream *stream = (PaAlsaStream*)s; unsigned long avail; int xrun; PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &stream->playback, &avail, &xrun ) ); if( xrun ) { snd_pcm_sframes_t savail; PA_ENSURE( PaAlsaStream_HandleXrun( stream ) ); savail = alsa_snd_pcm_avail_update( stream->playback.pcm ); /* savail should not contain -EPIPE now, since PaAlsaStream_HandleXrun will only prepare the pcm */ ENSURE_( savail, paUnanticipatedHostError ); avail = (unsigned long) savail; } return (signed long)avail; error: return result; } /* Extensions */ void PaAlsa_InitializeStreamInfo( PaAlsaStreamInfo *info ) { info->size = sizeof (PaAlsaStreamInfo); info->hostApiType = paALSA; info->version = 1; info->deviceString = NULL; } void PaAlsa_EnableRealtimeScheduling( PaStream *s, int enable ) { PaAlsaStream *stream = (PaAlsaStream *) s; stream->rtSched = enable; } #if 0 void PaAlsa_EnableWatchdog( PaStream *s, int enable ) { PaAlsaStream *stream = (PaAlsaStream *) s; stream->thread.useWatchdog = enable; } #endif static PaError GetAlsaStreamPointer( PaStream* s, PaAlsaStream** stream ) { PaError result = paNoError; PaUtilHostApiRepresentation* hostApi; PaAlsaHostApiRepresentation* alsaHostApi; PA_ENSURE( PaUtil_ValidateStreamPointer( s ) ); PA_ENSURE( PaUtil_GetHostApiRepresentation( &hostApi, paALSA ) ); alsaHostApi = (PaAlsaHostApiRepresentation*)hostApi; PA_UNLESS( PA_STREAM_REP( s )->streamInterface == &alsaHostApi->callbackStreamInterface || PA_STREAM_REP( s )->streamInterface == &alsaHostApi->blockingStreamInterface, paIncompatibleStreamHostApi ); *stream = (PaAlsaStream*)s; error: return paNoError; } PaError PaAlsa_GetStreamInputCard( PaStream* s, int* card ) { PaAlsaStream *stream; PaError result = paNoError; snd_pcm_info_t* pcmInfo; PA_ENSURE( GetAlsaStreamPointer( s, &stream ) ); /* XXX: More descriptive error? */ PA_UNLESS( stream->capture.pcm, paDeviceUnavailable ); alsa_snd_pcm_info_alloca( &pcmInfo ); PA_ENSURE( alsa_snd_pcm_info( stream->capture.pcm, pcmInfo ) ); *card = alsa_snd_pcm_info_get_card( pcmInfo ); error: return result; } PaError PaAlsa_GetStreamOutputCard( PaStream* s, int* card ) { PaAlsaStream *stream; PaError result = paNoError; snd_pcm_info_t* pcmInfo; PA_ENSURE( GetAlsaStreamPointer( s, &stream ) ); /* XXX: More descriptive error? */ PA_UNLESS( stream->playback.pcm, paDeviceUnavailable ); alsa_snd_pcm_info_alloca( &pcmInfo ); PA_ENSURE( alsa_snd_pcm_info( stream->playback.pcm, pcmInfo ) ); *card = alsa_snd_pcm_info_get_card( pcmInfo ); error: return result; } PaError PaAlsa_SetRetriesBusy( int retries ) { busyRetries_ = retries; return paNoError; } #endifpraat-6.0.04/external/portaudio/pa_linux_alsa.h000066400000000000000000000076101261542461700215440ustar00rootroot00000000000000#ifndef PA_LINUX_ALSA_H #define PA_LINUX_ALSA_H /* * $Id: pa_linux_alsa.h 1597 2011-02-11 00:15:51Z dmitrykos $ * PortAudio Portable Real-Time Audio Library * ALSA-specific extensions * * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file * @ingroup public_header * @brief ALSA-specific PortAudio API extension header file. */ #include "portaudio.h" #ifdef __cplusplus extern "C" { #endif typedef struct PaAlsaStreamInfo { unsigned long size; PaHostApiTypeId hostApiType; unsigned long version; const char *deviceString; } PaAlsaStreamInfo; /** Initialize host API specific structure, call this before setting relevant attributes. */ void PaAlsa_InitializeStreamInfo( PaAlsaStreamInfo *info ); /** Instruct whether to enable real-time priority when starting the audio thread. * * If this is turned on by the stream is started, the audio callback thread will be created * with the FIFO scheduling policy, which is suitable for realtime operation. **/ void PaAlsa_EnableRealtimeScheduling( PaStream *s, int enable ); #if 0 void PaAlsa_EnableWatchdog( PaStream *s, int enable ); #endif /** Get the ALSA-lib card index of this stream's input device. */ PaError PaAlsa_GetStreamInputCard( PaStream *s, int *card ); /** Get the ALSA-lib card index of this stream's output device. */ PaError PaAlsa_GetStreamOutputCard( PaStream *s, int *card ); /** Set the number of periods (buffer fragments) to configure devices with. * * By default the number of periods is 4, this is the lowest number of periods that works well on * the author's soundcard. * @param numPeriods The number of periods. */ PaError PaAlsa_SetNumPeriods( int numPeriods ); /** Set the maximum number of times to retry opening busy device (sleeping for a * short interval inbetween). */ PaError PaAlsa_SetRetriesBusy( int retries ); /** Set the path and name of ALSA library file if PortAudio is configured to load it dynamically (see * PA_ALSA_DYNAMIC). This setting will overwrite the default name set by PA_ALSA_PATHNAME define. * @param pathName Full path with filename. Only filename can be used, but dlopen() will lookup default * searchable directories (/usr/lib;/usr/local/lib) then. */ void PaAlsa_SetLibraryPathName( const char *pathName ); PaError PaAlsa_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ); // ppgb #ifdef __cplusplus } #endif #endif praat-6.0.04/external/portaudio/pa_linux_asihpi.c000066400000000000000000003533431261542461700221030ustar00rootroot00000000000000/* * $Id:$ * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * AudioScience HPI implementation by Fred Gleason, Ludwig Schwardt and * Eliot Blennerhassett * * Copyright (c) 2003 Fred Gleason * Copyright (c) 2005,2006 Ludwig Schwardt * Copyright (c) 2011 Eliot Blennerhassett * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2008 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /* * Modification History * 12/2003 - Initial version * 09/2005 - v19 version [rewrite] */ /** @file @ingroup hostapi_src @brief Host API implementation supporting AudioScience cards via the Linux HPI interface.

Overview

This is a PortAudio implementation for the AudioScience HPI Audio API on the Linux platform. AudioScience makes a range of audio adapters customised for the broadcasting industry, with support for both Windows and Linux. More information on their products can be found on their website: http://www.audioscience.com Documentation for the HPI API can be found at: http://www.audioscience.com/internet/download/sdk/hpi_usermanual_html/html/index.html The Linux HPI driver itself (a kernel module + library) can be downloaded from: http://www.audioscience.com/internet/download/linux_drivers.htm

Implementation strategy

*Note* Ideally, AudioScience cards should be handled by the PortAudio ALSA implementation on Linux, as ALSA is the preferred Linux soundcard API. The existence of this host API implementation might therefore seem a bit flawed. Unfortunately, at the time of the creation of this implementation (June 2006), the PA ALSA implementation could not make use of the existing AudioScience ALSA driver. PA ALSA uses the "memory-mapped" (mmap) ALSA access mode to interact with the ALSA library, while the AudioScience ALSA driver only supports the "read-write" access mode. The appropriate solution to this problem is to add "read-write" support to PortAudio ALSA, thereby extending the range of soundcards it supports (AudioScience cards are not the only ones with this problem). Given the author's limited knowledge of ALSA and the simplicity of the HPI API, the second-best solution was born... The following mapping between HPI and PA was followed: HPI subsystem => PortAudio host API HPI adapter => nothing specific HPI stream => PortAudio device Each HPI stream is either input or output (not both), and can support different channel counts, sampling rates and sample formats. It is therefore a more natural fit to a PA device. A PA stream can therefore combine two HPI streams (one input and one output) into a "full-duplex" stream. These HPI streams can even be on different physical adapters. The two streams ought to be sample-synchronised when they reside on the same adapter, as most AudioScience adapters derive their ADC and DAC clocks from one master clock. When combining two adapters into one full-duplex stream, however, the use of a word clock connection between the adapters is strongly recommended. The HPI interface is inherently blocking, making use of read and write calls to transfer data between user buffers and driver buffers. The callback interface therefore requires a helper thread ("callback engine") which periodically transfers data (one thread per PA stream, in fact). The current implementation explicitly sleeps via Pa_Sleep() until enough samples can be transferred (select() or poll() would be better, but currently seems impossible...). The thread implementation makes use of the Unix thread helper functions and some pthread calls here and there. If a unified PA thread exists, this host API implementation might also compile on Windows, as this is the only real Linux-specific part of the code. There is no inherent fixed buffer size in the HPI interface, as in some other host APIs. The PortAudio implementation contains a buffer that is allocated during OpenStream and used to transfer data between the callback and the HPI driver buffer. The size of this buffer is quite flexible and is derived from latency suggestions and matched to the requested callback buffer size as far as possible. It can become quite huge, as the AudioScience cards are typically geared towards higher-latency applications and contain large hardware buffers. The HPI interface natively supports most common sample formats and sample rates (some conversion is done on the adapter itself). Stream time is measured based on the number of processed frames, which is adjusted by the number of frames currently buffered by the HPI driver. There is basic support for detecting overflow and underflow. The HPI interface does not explicitly indicate this, so thresholds on buffer levels are used in combination with stream state. Recovery from overflow and underflow is left to the PA client. Blocking streams are also implemented. It makes use of the same polling routines that the callback interface uses, in order to prevent the allocation of variable-sized buffers during reading and writing. The framesPerBuffer parameter is therefore still relevant, and this can be increased in the blocking case to improve efficiency. The implementation contains extensive reporting macros (slightly modified PA_ENSURE and PA_UNLESS versions) and a useful stream dump routine to provide debugging feedback. Output buffer priming via the user callback (i.e. paPrimeOutputBuffersUsingStreamCallback and friends) is not implemented yet. All output is primed with silence. */ #include #include #include #include /* strlen() */ #include /* pthreads and friends */ #include /* assert */ #include /* ceil, floor */ #include /* HPI API */ #include "portaudio.h" /* PortAudio API */ #include "pa_util.h" /* PA_DEBUG, other small utilities */ #include "pa_unix_util.h" /* Unix threading utilities */ #include "pa_allocation.h" /* Group memory allocation */ #include "pa_hostapi.h" /* Host API structs */ #include "pa_stream.h" /* Stream interface structs */ #include "pa_cpuload.h" /* CPU load measurer */ #include "pa_process.h" /* Buffer processor */ #include "pa_converters.h" /* PaUtilZeroer */ #include "pa_debugprint.h" /* -------------------------------------------------------------------------- */ /* * Defines */ /* Error reporting and assertions */ /** Evaluate expression, and return on any PortAudio errors */ #define PA_ENSURE_(expr) \ do { \ PaError paError = (expr); \ if( UNLIKELY( paError < paNoError ) ) \ { \ PA_DEBUG(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \ result = paError; \ goto error; \ } \ } while (0); /** Assert expression, else return the provided PaError */ #define PA_UNLESS_(expr, paError) \ do { \ if( UNLIKELY( (expr) == 0 ) ) \ { \ PA_DEBUG(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \ result = (paError); \ goto error; \ } \ } while( 0 ); /** Check return value of HPI function, and map it to PaError */ #define PA_ASIHPI_UNLESS_(expr, paError) \ do { \ hpi_err_t hpiError = (expr); \ /* If HPI error occurred */ \ if( UNLIKELY( hpiError ) ) \ { \ char szError[256]; \ HPI_GetErrorText( hpiError, szError ); \ PA_DEBUG(( "HPI error %d occurred: %s\n", hpiError, szError )); \ /* This message will always be displayed, even if debug info is disabled */ \ PA_DEBUG(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \ if( (paError) == paUnanticipatedHostError ) \ { \ PA_DEBUG(( "Host error description: %s\n", szError )); \ /* PaUtil_SetLastHostErrorInfo should only be used in the main thread */ \ if( pthread_equal( pthread_self(), paUnixMainThread ) ) \ { \ PaUtil_SetLastHostErrorInfo( paInDevelopment, hpiError, szError ); \ } \ } \ /* If paNoError is specified, continue as usual */ \ /* (useful if you only want to print out the debug messages above) */ \ if( (paError) < 0 ) \ { \ result = (paError); \ goto error; \ } \ } \ } while( 0 ); /** Report HPI error code and text */ #define PA_ASIHPI_REPORT_ERROR_(hpiErrorCode) \ do { \ char szError[256]; \ HPI_GetErrorText( hpiError, szError ); \ PA_DEBUG(( "HPI error %d occurred: %s\n", hpiError, szError )); \ /* PaUtil_SetLastHostErrorInfo should only be used in the main thread */ \ if( pthread_equal( pthread_self(), paUnixMainThread ) ) \ { \ PaUtil_SetLastHostErrorInfo( paInDevelopment, (hpiErrorCode), szError ); \ } \ } while( 0 ); /* Defaults */ /** Sample formats available natively on AudioScience hardware */ #define PA_ASIHPI_AVAILABLE_FORMATS_ (paFloat32 | paInt32 | paInt24 | paInt16 | paUInt8) /** Enable background bus mastering (BBM) for buffer transfers, if available (see HPI docs) */ #define PA_ASIHPI_USE_BBM_ 1 /** Minimum number of frames in HPI buffer (for either data or available space). If buffer contains less data/space, it indicates xrun or completion. */ #define PA_ASIHPI_MIN_FRAMES_ 1152 /** Minimum polling interval in milliseconds, which determines minimum host buffer size */ #define PA_ASIHPI_MIN_POLLING_INTERVAL_ 10 /* -------------------------------------------------------------------------- */ /* * Structures */ /** Host API global data */ typedef struct PaAsiHpiHostApiRepresentation { /* PortAudio "base class" - keep the baseRep first! (C-style inheritance) */ PaUtilHostApiRepresentation baseHostApiRep; PaUtilStreamInterface callbackStreamInterface; PaUtilStreamInterface blockingStreamInterface; PaUtilAllocationGroup *allocations; /* implementation specific data goes here */ PaHostApiIndex hostApiIndex; } PaAsiHpiHostApiRepresentation; /** Device data */ typedef struct PaAsiHpiDeviceInfo { /* PortAudio "base class" - keep the baseRep first! (C-style inheritance) */ /** Common PortAudio device information */ PaDeviceInfo baseDeviceInfo; /* implementation specific data goes here */ /** Adapter index */ uint16_t adapterIndex; /** Adapter model number (hex) */ uint16_t adapterType; /** Adapter HW/SW version */ uint16_t adapterVersion; /** Adapter serial number */ uint32_t adapterSerialNumber; /** Stream number */ uint16_t streamIndex; /** 0=Input, 1=Output (HPI streams are either input or output but not both) */ uint16_t streamIsOutput; } PaAsiHpiDeviceInfo; /** Stream state as defined by PortAudio. It seems that the host API implementation has to keep track of the PortAudio stream state. Please note that this is NOT the same as the state of the underlying HPI stream. By separating these two concepts, a lot of flexibility is gained. There is a rough match between the two, of course, but forcing a precise match is difficult. For example, HPI_STATE_DRAINED can occur during the Active state of PortAudio (due to underruns) and also during CallBackFinished in the case of an output stream. Similarly, HPI_STATE_STOPPED mostly coincides with the Stopped PortAudio state, by may also occur in the CallbackFinished state when recording is finished. Here is a rough match-up: PortAudio state => HPI state --------------- --------- Active => HPI_STATE_RECORDING, HPI_STATE_PLAYING, (HPI_STATE_DRAINED) Stopped => HPI_STATE_STOPPED CallbackFinished => HPI_STATE_STOPPED, HPI_STATE_DRAINED */ typedef enum PaAsiHpiStreamState { paAsiHpiStoppedState=0, paAsiHpiActiveState=1, paAsiHpiCallbackFinishedState=2 } PaAsiHpiStreamState; /** Stream component data (associated with one direction, i.e. either input or output) */ typedef struct PaAsiHpiStreamComponent { /** Device information (HPI handles, etc) */ PaAsiHpiDeviceInfo *hpiDevice; /** Stream handle, as passed to HPI interface. */ hpi_handle_t hpiStream; /** Stream format, as passed to HPI interface */ struct hpi_format hpiFormat; /** Number of bytes per frame, derived from hpiFormat and saved for convenience */ uint32_t bytesPerFrame; /** Size of hardware (on-card) buffer of stream in bytes */ uint32_t hardwareBufferSize; /** Size of host (BBM) buffer of stream in bytes (if used) */ uint32_t hostBufferSize; /** Upper limit on the utilization of output stream buffer (both hardware and host). This prevents large latencies in an output-only stream with a potentially huge buffer and a fast data generator, which would otherwise keep the hardware buffer filled to capacity. See also the "Hardware Buffering=off" option in the AudioScience WAV driver. */ uint32_t outputBufferCap; /** Sample buffer (halfway station between HPI and buffer processor) */ uint8_t *tempBuffer; /** Sample buffer size, in bytes */ uint32_t tempBufferSize; } PaAsiHpiStreamComponent; /** Stream data */ typedef struct PaAsiHpiStream { /* PortAudio "base class" - keep the baseRep first! (C-style inheritance) */ PaUtilStreamRepresentation baseStreamRep; PaUtilCpuLoadMeasurer cpuLoadMeasurer; PaUtilBufferProcessor bufferProcessor; PaUtilAllocationGroup *allocations; /* implementation specific data goes here */ /** Separate structs for input and output sides of stream */ PaAsiHpiStreamComponent *input, *output; /** Polling interval (in milliseconds) */ uint32_t pollingInterval; /** Are we running in callback mode? */ int callbackMode; /** Number of frames to transfer at a time to/from HPI */ unsigned long maxFramesPerHostBuffer; /** Indicates that the stream is in the paNeverDropInput mode */ int neverDropInput; /** Contains copy of user buffers, used by blocking interface to transfer non-interleaved data. It went here instead of to each stream component, as the stream component buffer setup in PaAsiHpi_SetupBuffers doesn't know the stream details such as callbackMode. (Maybe a problem later if ReadStream and WriteStream happens concurrently on same stream.) */ void **blockingUserBufferCopy; /* Thread-related variables */ /** Helper thread which will deliver data to user callback */ PaUnixThread thread; /** PortAudio stream state (Active/Stopped/CallbackFinished) */ volatile sig_atomic_t state; /** Hard abort, i.e. drop frames? */ volatile sig_atomic_t callbackAbort; /** True if stream stopped via exiting callback with paComplete/paAbort flag (as opposed to explicit call to StopStream/AbortStream) */ volatile sig_atomic_t callbackFinished; } PaAsiHpiStream; /** Stream state information, collected together for convenience */ typedef struct PaAsiHpiStreamInfo { /** HPI stream state (HPI_STATE_STOPPED, HPI_STATE_PLAYING, etc.) */ uint16_t state; /** Size (in bytes) of recording/playback data buffer in HPI driver */ uint32_t bufferSize; /** Amount of data (in bytes) available in the buffer */ uint32_t dataSize; /** Number of frames played/recorded since last stream reset */ uint32_t frameCounter; /** Amount of data (in bytes) in hardware (on-card) buffer. This differs from dataSize if bus mastering (BBM) is used, which introduces another driver-level buffer to which dataSize/bufferSize then refers. */ uint32_t auxDataSize; /** Total number of data frames currently buffered by HPI driver (host + hw buffers) */ uint32_t totalBufferedData; /** Size of immediately available data (for input) or space (for output) in frames. This only checks the first-level buffer (typically host buffer). This amount can be transferred immediately. */ uint32_t availableFrames; /** Indicates that hardware buffer is getting too full */ int overflow; /** Indicates that hardware buffer is getting too empty */ int underflow; } PaAsiHpiStreamInfo; /* -------------------------------------------------------------------------- */ /* * Function prototypes */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* The only exposed function in the entire host API implementation */ PaError PaAsiHpi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); #ifdef __cplusplus } #endif /* __cplusplus */ static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); /* Stream prototypes */ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream **s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); static PaError CloseStream( PaStream *s ); static PaError StartStream( PaStream *s ); static PaError StopStream( PaStream *s ); static PaError AbortStream( PaStream *s ); static PaError IsStreamStopped( PaStream *s ); static PaError IsStreamActive( PaStream *s ); static PaTime GetStreamTime( PaStream *s ); static double GetStreamCpuLoad( PaStream *s ); /* Blocking prototypes */ static PaError ReadStream( PaStream *s, void *buffer, unsigned long frames ); static PaError WriteStream( PaStream *s, const void *buffer, unsigned long frames ); static signed long GetStreamReadAvailable( PaStream *s ); static signed long GetStreamWriteAvailable( PaStream *s ); /* Callback prototypes */ static void *CallbackThreadFunc( void *userData ); /* Functions specific to this API */ static PaError PaAsiHpi_BuildDeviceList( PaAsiHpiHostApiRepresentation *hpiHostApi ); static uint16_t PaAsiHpi_PaToHpiFormat( PaSampleFormat paFormat ); static PaSampleFormat PaAsiHpi_HpiToPaFormat( uint16_t hpiFormat ); static PaError PaAsiHpi_CreateFormat( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *parameters, double sampleRate, PaAsiHpiDeviceInfo **hpiDevice, struct hpi_format *hpiFormat ); static PaError PaAsiHpi_OpenInput( struct PaUtilHostApiRepresentation *hostApi, const PaAsiHpiDeviceInfo *hpiDevice, const struct hpi_format *hpiFormat, hpi_handle_t *hpiStream ); static PaError PaAsiHpi_OpenOutput( struct PaUtilHostApiRepresentation *hostApi, const PaAsiHpiDeviceInfo *hpiDevice, const struct hpi_format *hpiFormat, hpi_handle_t *hpiStream ); static PaError PaAsiHpi_GetStreamInfo( PaAsiHpiStreamComponent *streamComp, PaAsiHpiStreamInfo *info ); static void PaAsiHpi_StreamComponentDump( PaAsiHpiStreamComponent *streamComp, PaAsiHpiStream *stream ); static void PaAsiHpi_StreamDump( PaAsiHpiStream *stream ); static PaError PaAsiHpi_SetupBuffers( PaAsiHpiStreamComponent *streamComp, uint32_t pollingInterval, unsigned long framesPerPaHostBuffer, PaTime suggestedLatency ); static PaError PaAsiHpi_PrimeOutputWithSilence( PaAsiHpiStream *stream ); static PaError PaAsiHpi_StartStream( PaAsiHpiStream *stream, int outputPrimed ); static PaError PaAsiHpi_StopStream( PaAsiHpiStream *stream, int abort ); static PaError PaAsiHpi_ExplicitStop( PaAsiHpiStream *stream, int abort ); static void PaAsiHpi_OnThreadExit( void *userData ); static PaError PaAsiHpi_WaitForFrames( PaAsiHpiStream *stream, unsigned long *framesAvail, PaStreamCallbackFlags *cbFlags ); static void PaAsiHpi_CalculateTimeInfo( PaAsiHpiStream *stream, PaStreamCallbackTimeInfo *timeInfo ); static PaError PaAsiHpi_BeginProcessing( PaAsiHpiStream* stream, unsigned long* numFrames, PaStreamCallbackFlags *cbFlags ); static PaError PaAsiHpi_EndProcessing( PaAsiHpiStream *stream, unsigned long numFrames, PaStreamCallbackFlags *cbFlags ); /* ========================================================================== * ============================= IMPLEMENTATION ============================= * ========================================================================== */ /* --------------------------- Host API Interface --------------------------- */ /** Enumerate all PA devices (= HPI streams). This compiles a list of all HPI adapters, and registers a PA device for each input and output stream it finds. Most errors are ignored, as missing or erroneous devices are simply skipped. @param hpiHostApi Pointer to HPI host API struct @return PortAudio error code (only paInsufficientMemory in practice) */ static PaError PaAsiHpi_BuildDeviceList( PaAsiHpiHostApiRepresentation *hpiHostApi ) { PaError result = paNoError; PaUtilHostApiRepresentation *hostApi = &hpiHostApi->baseHostApiRep; PaHostApiInfo *baseApiInfo = &hostApi->info; PaAsiHpiDeviceInfo *hpiDeviceList; int numAdapters; hpi_err_t hpiError = 0; int i, j, deviceCount = 0, deviceIndex = 0; assert( hpiHostApi ); /* Errors not considered critical here (subsystem may report 0 devices), but report them */ /* in debug mode. */ PA_ASIHPI_UNLESS_( HPI_SubSysGetNumAdapters( NULL, &numAdapters), paNoError ); for( i=0; i < numAdapters; ++i ) { uint16_t inStreams, outStreams; uint16_t version; uint32_t serial; uint16_t type; uint32_t idx; hpiError = HPI_SubSysGetAdapter(NULL, i, &idx, &type); if (hpiError) continue; /* Try to open adapter */ hpiError = HPI_AdapterOpen( NULL, idx ); /* Report error and skip to next device on failure */ if( hpiError ) { PA_ASIHPI_REPORT_ERROR_( hpiError ); continue; } hpiError = HPI_AdapterGetInfo( NULL, idx, &outStreams, &inStreams, &version, &serial, &type ); /* Skip to next device on failure */ if( hpiError ) { PA_ASIHPI_REPORT_ERROR_( hpiError ); continue; } else { /* Assign default devices if available and increment device count */ if( (baseApiInfo->defaultInputDevice == paNoDevice) && (inStreams > 0) ) baseApiInfo->defaultInputDevice = deviceCount; deviceCount += inStreams; if( (baseApiInfo->defaultOutputDevice == paNoDevice) && (outStreams > 0) ) baseApiInfo->defaultOutputDevice = deviceCount; deviceCount += outStreams; } } /* Register any discovered devices */ if( deviceCount > 0 ) { /* Memory allocation */ PA_UNLESS_( hostApi->deviceInfos = (PaDeviceInfo**) PaUtil_GroupAllocateMemory( hpiHostApi->allocations, sizeof(PaDeviceInfo*) * deviceCount ), paInsufficientMemory ); /* Allocate all device info structs in a contiguous block */ PA_UNLESS_( hpiDeviceList = (PaAsiHpiDeviceInfo*) PaUtil_GroupAllocateMemory( hpiHostApi->allocations, sizeof(PaAsiHpiDeviceInfo) * deviceCount ), paInsufficientMemory ); /* Now query devices again for information */ for( i=0; i < numAdapters; ++i ) { uint16_t inStreams, outStreams; uint16_t version; uint32_t serial; uint16_t type; uint32_t idx; hpiError = HPI_SubSysGetAdapter( NULL, i, &idx, &type ); if (hpiError) continue; /* Assume adapter is still open from previous round */ hpiError = HPI_AdapterGetInfo( NULL, idx, &outStreams, &inStreams, &version, &serial, &type ); /* Report error and skip to next device on failure */ if( hpiError ) { PA_ASIHPI_REPORT_ERROR_( hpiError ); continue; } else { PA_DEBUG(( "Found HPI Adapter ID=%4X Idx=%d #In=%d #Out=%d S/N=%d HWver=%c%d DSPver=%03d\n", type, idx, inStreams, outStreams, serial, ((version>>3)&0xf)+'A', /* Hw version major */ version&0x7, /* Hw version minor */ ((version>>13)*100)+((version>>7)&0x3f) /* DSP code version */ )); } /* First add all input streams as devices */ for( j=0; j < inStreams; ++j ) { PaAsiHpiDeviceInfo *hpiDevice = &hpiDeviceList[deviceIndex]; PaDeviceInfo *baseDeviceInfo = &hpiDevice->baseDeviceInfo; char srcName[72]; char *deviceName; memset( hpiDevice, 0, sizeof(PaAsiHpiDeviceInfo) ); /* Set implementation-specific device details */ hpiDevice->adapterIndex = idx; hpiDevice->adapterType = type; hpiDevice->adapterVersion = version; hpiDevice->adapterSerialNumber = serial; hpiDevice->streamIndex = j; hpiDevice->streamIsOutput = 0; /* Set common PortAudio device stats */ baseDeviceInfo->structVersion = 2; /* Make sure name string is owned by API info structure */ sprintf( srcName, "Adapter %d (%4X) - Input Stream %d", i+1, type, j+1 ); PA_UNLESS_( deviceName = (char *) PaUtil_GroupAllocateMemory( hpiHostApi->allocations, strlen(srcName) + 1 ), paInsufficientMemory ); strcpy( deviceName, srcName ); baseDeviceInfo->name = deviceName; baseDeviceInfo->hostApi = hpiHostApi->hostApiIndex; baseDeviceInfo->maxInputChannels = HPI_MAX_CHANNELS; baseDeviceInfo->maxOutputChannels = 0; /* Default latency values for interactive performance */ baseDeviceInfo->defaultLowInputLatency = 0.01; baseDeviceInfo->defaultLowOutputLatency = -1.0; /* Default latency values for robust non-interactive applications (eg. playing sound files) */ baseDeviceInfo->defaultHighInputLatency = 0.2; baseDeviceInfo->defaultHighOutputLatency = -1.0; /* HPI interface can actually handle any sampling rate to 1 Hz accuracy, * so this default is as good as any */ baseDeviceInfo->defaultSampleRate = 44100; /* Store device in global PortAudio list */ hostApi->deviceInfos[deviceIndex++] = (PaDeviceInfo *) hpiDevice; } /* Now add all output streams as devices (I know, the repetition is painful) */ for( j=0; j < outStreams; ++j ) { PaAsiHpiDeviceInfo *hpiDevice = &hpiDeviceList[deviceIndex]; PaDeviceInfo *baseDeviceInfo = &hpiDevice->baseDeviceInfo; char srcName[72]; char *deviceName; memset( hpiDevice, 0, sizeof(PaAsiHpiDeviceInfo) ); /* Set implementation-specific device details */ hpiDevice->adapterIndex = idx; hpiDevice->adapterType = type; hpiDevice->adapterVersion = version; hpiDevice->adapterSerialNumber = serial; hpiDevice->streamIndex = j; hpiDevice->streamIsOutput = 1; /* Set common PortAudio device stats */ baseDeviceInfo->structVersion = 2; /* Make sure name string is owned by API info structure */ sprintf( srcName, "Adapter %d (%4X) - Output Stream %d", i+1, type, j+1 ); PA_UNLESS_( deviceName = (char *) PaUtil_GroupAllocateMemory( hpiHostApi->allocations, strlen(srcName) + 1 ), paInsufficientMemory ); strcpy( deviceName, srcName ); baseDeviceInfo->name = deviceName; baseDeviceInfo->hostApi = hpiHostApi->hostApiIndex; baseDeviceInfo->maxInputChannels = 0; baseDeviceInfo->maxOutputChannels = HPI_MAX_CHANNELS; /* Default latency values for interactive performance. */ baseDeviceInfo->defaultLowInputLatency = -1.0; baseDeviceInfo->defaultLowOutputLatency = 0.01; /* Default latency values for robust non-interactive applications (eg. playing sound files). */ baseDeviceInfo->defaultHighInputLatency = -1.0; baseDeviceInfo->defaultHighOutputLatency = 0.2; /* HPI interface can actually handle any sampling rate to 1 Hz accuracy, * so this default is as good as any */ baseDeviceInfo->defaultSampleRate = 44100; /* Store device in global PortAudio list */ hostApi->deviceInfos[deviceIndex++] = (PaDeviceInfo *) hpiDevice; } } } /* Finally acknowledge checked devices */ baseApiInfo->deviceCount = deviceIndex; error: return result; } /** Initialize host API implementation. This is the only function exported beyond this file. It is called by PortAudio to initialize the host API. It stores API info, finds and registers all devices, and sets up callback and blocking interfaces. @param hostApi Pointer to host API struct @param hostApiIndex Index of current (HPI) host API @return PortAudio error code */ PaError PaAsiHpi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) { PaError result = paNoError; PaAsiHpiHostApiRepresentation *hpiHostApi = NULL; PaHostApiInfo *baseApiInfo; /* Try to initialize HPI subsystem */ if (!HPI_SubSysCreate()) { /* the V19 development docs say that if an implementation * detects that it cannot be used, it should return a NULL * interface and paNoError */ PA_DEBUG(( "Could not open HPI interface\n" )); *hostApi = NULL; return paNoError; } else { uint32_t hpiVersion; PA_ASIHPI_UNLESS_( HPI_SubSysGetVersionEx( NULL, &hpiVersion ), paUnanticipatedHostError ); PA_DEBUG(( "HPI interface v%d.%02d.%02d\n", hpiVersion >> 16, (hpiVersion >> 8) & 0x0F, (hpiVersion & 0x0F) )); } /* Allocate host API structure */ PA_UNLESS_( hpiHostApi = (PaAsiHpiHostApiRepresentation*) PaUtil_AllocateMemory( sizeof(PaAsiHpiHostApiRepresentation) ), paInsufficientMemory ); PA_UNLESS_( hpiHostApi->allocations = PaUtil_CreateAllocationGroup(), paInsufficientMemory ); hpiHostApi->hostApiIndex = hostApiIndex; *hostApi = &hpiHostApi->baseHostApiRep; baseApiInfo = &((*hostApi)->info); /* Fill in common API details */ baseApiInfo->structVersion = 1; baseApiInfo->type = paAudioScienceHPI; baseApiInfo->name = "AudioScience HPI"; baseApiInfo->deviceCount = 0; baseApiInfo->defaultInputDevice = paNoDevice; baseApiInfo->defaultOutputDevice = paNoDevice; PA_ENSURE_( PaAsiHpi_BuildDeviceList( hpiHostApi ) ); (*hostApi)->Terminate = Terminate; (*hostApi)->OpenStream = OpenStream; (*hostApi)->IsFormatSupported = IsFormatSupported; PaUtil_InitializeStreamInterface( &hpiHostApi->callbackStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, GetStreamCpuLoad, PaUtil_DummyRead, PaUtil_DummyWrite, PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); PaUtil_InitializeStreamInterface( &hpiHostApi->blockingStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, PaUtil_DummyGetCpuLoad, ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable ); /* Store identity of main thread */ PA_ENSURE_( PaUnixThreading_Initialize() ); return result; error: if (hpiHostApi) PaUtil_FreeMemory( hpiHostApi ); return result; } /** Terminate host API implementation. This closes all HPI adapters and frees the HPI subsystem. It also frees the host API struct memory. It should be called once for every PaAsiHpi_Initialize call. @param Pointer to host API struct */ static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) { PaAsiHpiHostApiRepresentation *hpiHostApi = (PaAsiHpiHostApiRepresentation*)hostApi; int i; PaError result = paNoError; if( hpiHostApi ) { /* Get rid of HPI-specific structures */ uint16_t lastAdapterIndex = HPI_MAX_ADAPTERS; /* Iterate through device list and close adapters */ for( i=0; i < hostApi->info.deviceCount; ++i ) { PaAsiHpiDeviceInfo *hpiDevice = (PaAsiHpiDeviceInfo *) hostApi->deviceInfos[ i ]; /* Close adapter only if it differs from previous one */ if( hpiDevice->adapterIndex != lastAdapterIndex ) { /* Ignore errors (report only during debugging) */ PA_ASIHPI_UNLESS_( HPI_AdapterClose( NULL, hpiDevice->adapterIndex ), paNoError ); lastAdapterIndex = hpiDevice->adapterIndex; } } /* Finally dismantle HPI subsystem */ HPI_SubSysFree( NULL ); if( hpiHostApi->allocations ) { PaUtil_FreeAllAllocations( hpiHostApi->allocations ); PaUtil_DestroyAllocationGroup( hpiHostApi->allocations ); } PaUtil_FreeMemory( hpiHostApi ); } error: return; } /** Converts PortAudio sample format to equivalent HPI format. @param paFormat PortAudio sample format @return HPI sample format */ static uint16_t PaAsiHpi_PaToHpiFormat( PaSampleFormat paFormat ) { /* Ignore interleaving flag */ switch( paFormat & ~paNonInterleaved ) { case paFloat32: return HPI_FORMAT_PCM32_FLOAT; case paInt32: return HPI_FORMAT_PCM32_SIGNED; case paInt24: return HPI_FORMAT_PCM24_SIGNED; case paInt16: return HPI_FORMAT_PCM16_SIGNED; case paUInt8: return HPI_FORMAT_PCM8_UNSIGNED; /* Default is 16-bit signed */ case paInt8: default: return HPI_FORMAT_PCM16_SIGNED; } } /** Converts HPI sample format to equivalent PortAudio format. @param paFormat HPI sample format @return PortAudio sample format */ static PaSampleFormat PaAsiHpi_HpiToPaFormat( uint16_t hpiFormat ) { switch( hpiFormat ) { case HPI_FORMAT_PCM32_FLOAT: return paFloat32; case HPI_FORMAT_PCM32_SIGNED: return paInt32; case HPI_FORMAT_PCM24_SIGNED: return paInt24; case HPI_FORMAT_PCM16_SIGNED: return paInt16; case HPI_FORMAT_PCM8_UNSIGNED: return paUInt8; /* Default is custom format (e.g. for HPI MP3 format) */ default: return paCustomFormat; } } /** Creates HPI format struct based on PortAudio parameters. This also does some checks to see whether the desired format is valid, and whether the device allows it. This only checks the format of one half (input or output) of the PortAudio stream. @param hostApi Pointer to host API struct @param parameters Pointer to stream parameter struct @param sampleRate Desired sample rate @param hpiDevice Pointer to HPI device struct @param hpiFormat Resulting HPI format returned here @return PortAudio error code (typically indicating a problem with stream format) */ static PaError PaAsiHpi_CreateFormat( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *parameters, double sampleRate, PaAsiHpiDeviceInfo **hpiDevice, struct hpi_format *hpiFormat ) { int maxChannelCount = 0; PaSampleFormat hostSampleFormat = 0; hpi_err_t hpiError = 0; /* Unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( parameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; else { assert( parameters->device < hostApi->info.deviceCount ); *hpiDevice = (PaAsiHpiDeviceInfo*) hostApi->deviceInfos[ parameters->device ]; } /* Validate streamInfo - this implementation doesn't use custom stream info */ if( parameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* Check that device can support channel count */ if( (*hpiDevice)->streamIsOutput ) { maxChannelCount = (*hpiDevice)->baseDeviceInfo.maxOutputChannels; } else { maxChannelCount = (*hpiDevice)->baseDeviceInfo.maxInputChannels; } if( (maxChannelCount == 0) || (parameters->channelCount > maxChannelCount) ) return paInvalidChannelCount; /* All standard sample formats are supported by the buffer adapter, and this implementation doesn't support any custom sample formats */ if( parameters->sampleFormat & paCustomFormat ) return paSampleFormatNotSupported; /* Switch to closest HPI native format */ hostSampleFormat = PaUtil_SelectClosestAvailableFormat(PA_ASIHPI_AVAILABLE_FORMATS_, parameters->sampleFormat ); /* Setup format + info objects */ hpiError = HPI_FormatCreate( hpiFormat, (uint16_t)parameters->channelCount, PaAsiHpi_PaToHpiFormat( hostSampleFormat ), (uint32_t)sampleRate, 0, 0 ); if( hpiError ) { PA_ASIHPI_REPORT_ERROR_( hpiError ); switch( hpiError ) { case HPI_ERROR_INVALID_FORMAT: return paSampleFormatNotSupported; case HPI_ERROR_INVALID_SAMPLERATE: case HPI_ERROR_INCOMPATIBLE_SAMPLERATE: return paInvalidSampleRate; case HPI_ERROR_INVALID_CHANNELS: return paInvalidChannelCount; } } return paNoError; } /** Open HPI input stream with given format. This attempts to open HPI input stream with desired format. If the format is not supported or the device is unavailable, the stream is closed and a PortAudio error code is returned. @param hostApi Pointer to host API struct @param hpiDevice Pointer to HPI device struct @param hpiFormat Pointer to HPI format struct @return PortAudio error code (typically indicating a problem with stream format or device) */ static PaError PaAsiHpi_OpenInput( struct PaUtilHostApiRepresentation *hostApi, const PaAsiHpiDeviceInfo *hpiDevice, const struct hpi_format *hpiFormat, hpi_handle_t *hpiStream ) { PaAsiHpiHostApiRepresentation *hpiHostApi = (PaAsiHpiHostApiRepresentation*)hostApi; PaError result = paNoError; hpi_err_t hpiError = 0; /* Catch misplaced output devices, as they typically have 0 input channels */ PA_UNLESS_( !hpiDevice->streamIsOutput, paInvalidChannelCount ); /* Try to open input stream */ PA_ASIHPI_UNLESS_( HPI_InStreamOpen( NULL, hpiDevice->adapterIndex, hpiDevice->streamIndex, hpiStream ), paDeviceUnavailable ); /* Set input format (checking it in the process) */ /* Could also use HPI_InStreamQueryFormat, but this economizes the process */ hpiError = HPI_InStreamSetFormat( NULL, *hpiStream, (struct hpi_format*)hpiFormat ); if( hpiError ) { PA_ASIHPI_REPORT_ERROR_( hpiError ); PA_ASIHPI_UNLESS_( HPI_InStreamClose( NULL, *hpiStream ), paNoError ); switch( hpiError ) { case HPI_ERROR_INVALID_FORMAT: return paSampleFormatNotSupported; case HPI_ERROR_INVALID_SAMPLERATE: case HPI_ERROR_INCOMPATIBLE_SAMPLERATE: return paInvalidSampleRate; case HPI_ERROR_INVALID_CHANNELS: return paInvalidChannelCount; default: /* In case anything else went wrong */ return paInvalidDevice; } } error: return result; } /** Open HPI output stream with given format. This attempts to open HPI output stream with desired format. If the format is not supported or the device is unavailable, the stream is closed and a PortAudio error code is returned. @param hostApi Pointer to host API struct @param hpiDevice Pointer to HPI device struct @param hpiFormat Pointer to HPI format struct @return PortAudio error code (typically indicating a problem with stream format or device) */ static PaError PaAsiHpi_OpenOutput( struct PaUtilHostApiRepresentation *hostApi, const PaAsiHpiDeviceInfo *hpiDevice, const struct hpi_format *hpiFormat, hpi_handle_t *hpiStream ) { PaAsiHpiHostApiRepresentation *hpiHostApi = (PaAsiHpiHostApiRepresentation*)hostApi; PaError result = paNoError; hpi_err_t hpiError = 0; /* Catch misplaced input devices, as they typically have 0 output channels */ PA_UNLESS_( hpiDevice->streamIsOutput, paInvalidChannelCount ); /* Try to open output stream */ PA_ASIHPI_UNLESS_( HPI_OutStreamOpen( NULL, hpiDevice->adapterIndex, hpiDevice->streamIndex, hpiStream ), paDeviceUnavailable ); /* Check output format (format is set on first write to output stream) */ hpiError = HPI_OutStreamQueryFormat( NULL, *hpiStream, (struct hpi_format*)hpiFormat ); if( hpiError ) { PA_ASIHPI_REPORT_ERROR_( hpiError ); PA_ASIHPI_UNLESS_( HPI_OutStreamClose( NULL, *hpiStream ), paNoError ); switch( hpiError ) { case HPI_ERROR_INVALID_FORMAT: return paSampleFormatNotSupported; case HPI_ERROR_INVALID_SAMPLERATE: case HPI_ERROR_INCOMPATIBLE_SAMPLERATE: return paInvalidSampleRate; case HPI_ERROR_INVALID_CHANNELS: return paInvalidChannelCount; default: /* In case anything else went wrong */ return paInvalidDevice; } } error: return result; } /** Checks whether the desired stream formats and devices are supported (for both input and output). This is done by actually opening the appropriate HPI streams and closing them again. @param hostApi Pointer to host API struct @param inputParameters Pointer to stream parameter struct for input side of stream @param outputParameters Pointer to stream parameter struct for output side of stream @param sampleRate Desired sample rate @return PortAudio error code (paFormatIsSupported on success) */ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { PaError result = paFormatIsSupported; PaAsiHpiHostApiRepresentation *hpiHostApi = (PaAsiHpiHostApiRepresentation*)hostApi; PaAsiHpiDeviceInfo *hpiDevice = NULL; struct hpi_format hpiFormat; /* Input stream */ if( inputParameters ) { hpi_handle_t hpiStream; PA_DEBUG(( "%s: Checking input params: dev=%d, sr=%d, chans=%d, fmt=%d\n", __FUNCTION__, inputParameters->device, (int)sampleRate, inputParameters->channelCount, inputParameters->sampleFormat )); /* Create and validate format */ PA_ENSURE_( PaAsiHpi_CreateFormat( hostApi, inputParameters, sampleRate, &hpiDevice, &hpiFormat ) ); /* Open stream to further check format */ PA_ENSURE_( PaAsiHpi_OpenInput( hostApi, hpiDevice, &hpiFormat, &hpiStream ) ); /* Close stream again */ PA_ASIHPI_UNLESS_( HPI_InStreamClose( NULL, hpiStream ), paNoError ); } /* Output stream */ if( outputParameters ) { hpi_handle_t hpiStream; PA_DEBUG(( "%s: Checking output params: dev=%d, sr=%d, chans=%d, fmt=%d\n", __FUNCTION__, outputParameters->device, (int)sampleRate, outputParameters->channelCount, outputParameters->sampleFormat )); /* Create and validate format */ PA_ENSURE_( PaAsiHpi_CreateFormat( hostApi, outputParameters, sampleRate, &hpiDevice, &hpiFormat ) ); /* Open stream to further check format */ PA_ENSURE_( PaAsiHpi_OpenOutput( hostApi, hpiDevice, &hpiFormat, &hpiStream ) ); /* Close stream again */ PA_ASIHPI_UNLESS_( HPI_OutStreamClose( NULL, hpiStream ), paNoError ); } error: return result; } /* ---------------------------- Stream Interface ---------------------------- */ /** Obtain HPI stream information. This obtains info such as stream state and available data/space in buffers. It also estimates whether an underflow or overflow occurred. @param streamComp Pointer to stream component (input or output) to query @param info Pointer to stream info struct that will contain result @return PortAudio error code (either paNoError, paDeviceUnavailable or paUnanticipatedHostError) */ static PaError PaAsiHpi_GetStreamInfo( PaAsiHpiStreamComponent *streamComp, PaAsiHpiStreamInfo *info ) { PaError result = paDeviceUnavailable; uint16_t state; uint32_t bufferSize, dataSize, frameCounter, auxDataSize, threshold; uint32_t hwBufferSize, hwDataSize; assert( streamComp ); assert( info ); /* First blank the stream info struct, in case something goes wrong below. This saves the caller from initializing the struct. */ info->state = 0; info->bufferSize = 0; info->dataSize = 0; info->frameCounter = 0; info->auxDataSize = 0; info->totalBufferedData = 0; info->availableFrames = 0; info->underflow = 0; info->overflow = 0; if( streamComp->hpiDevice && streamComp->hpiStream ) { /* Obtain detailed stream info (either input or output) */ if( streamComp->hpiDevice->streamIsOutput ) { PA_ASIHPI_UNLESS_( HPI_OutStreamGetInfoEx( NULL, streamComp->hpiStream, &state, &bufferSize, &dataSize, &frameCounter, &auxDataSize ), paUnanticipatedHostError ); } else { PA_ASIHPI_UNLESS_( HPI_InStreamGetInfoEx( NULL, streamComp->hpiStream, &state, &bufferSize, &dataSize, &frameCounter, &auxDataSize ), paUnanticipatedHostError ); } /* Load stream info */ info->state = state; info->bufferSize = bufferSize; info->dataSize = dataSize; info->frameCounter = frameCounter; info->auxDataSize = auxDataSize; /* Determine total buffered data */ info->totalBufferedData = dataSize; if( streamComp->hostBufferSize > 0 ) info->totalBufferedData += auxDataSize; info->totalBufferedData /= streamComp->bytesPerFrame; /* Determine immediately available frames */ info->availableFrames = streamComp->hpiDevice->streamIsOutput ? bufferSize - dataSize : dataSize; info->availableFrames /= streamComp->bytesPerFrame; /* Minimum space/data required in buffers */ threshold = PA_MIN( streamComp->tempBufferSize, streamComp->bytesPerFrame * PA_ASIHPI_MIN_FRAMES_ ); /* Obtain hardware buffer stats first, to simplify things */ hwBufferSize = streamComp->hardwareBufferSize; hwDataSize = streamComp->hostBufferSize > 0 ? auxDataSize : dataSize; /* Underflow is a bit tricky */ info->underflow = streamComp->hpiDevice->streamIsOutput ? /* Stream seems to start in drained state sometimes, so ignore initial underflow */ (frameCounter > 0) && ( (state == HPI_STATE_DRAINED) || (hwDataSize == 0) ) : /* Input streams check the first-level (host) buffer for underflow */ (state != HPI_STATE_STOPPED) && (dataSize < threshold); /* Check for overflow in second-level (hardware) buffer for both input and output */ info->overflow = (state != HPI_STATE_STOPPED) && (hwBufferSize - hwDataSize < threshold); return paNoError; } error: return result; } /** Display stream component information for debugging purposes. @param streamComp Pointer to stream component (input or output) to query @param stream Pointer to stream struct which contains the component above */ static void PaAsiHpi_StreamComponentDump( PaAsiHpiStreamComponent *streamComp, PaAsiHpiStream *stream ) { PaAsiHpiStreamInfo streamInfo; assert( streamComp ); assert( stream ); /* Name of soundcard/device used by component */ PA_DEBUG(( "device: %s\n", streamComp->hpiDevice->baseDeviceInfo.name )); /* Unfortunately some overlap between input and output here */ if( streamComp->hpiDevice->streamIsOutput ) { /* Settings on the user side (as experienced by user callback) */ PA_DEBUG(( "user: %d-bit, %d ", 8*stream->bufferProcessor.bytesPerUserOutputSample, stream->bufferProcessor.outputChannelCount)); if( stream->bufferProcessor.userOutputIsInterleaved ) { PA_DEBUG(( "interleaved channels, " )); } else { PA_DEBUG(( "non-interleaved channels, " )); } PA_DEBUG(( "%d frames/buffer, latency = %5.1f ms\n", stream->bufferProcessor.framesPerUserBuffer, 1000*stream->baseStreamRep.streamInfo.outputLatency )); /* Settings on the host side (internal to PortAudio host API) */ PA_DEBUG(( "host: %d-bit, %d interleaved channels, %d frames/buffer ", 8*stream->bufferProcessor.bytesPerHostOutputSample, stream->bufferProcessor.outputChannelCount, stream->bufferProcessor.framesPerHostBuffer )); } else { /* Settings on the user side (as experienced by user callback) */ PA_DEBUG(( "user: %d-bit, %d ", 8*stream->bufferProcessor.bytesPerUserInputSample, stream->bufferProcessor.inputChannelCount)); if( stream->bufferProcessor.userInputIsInterleaved ) { PA_DEBUG(( "interleaved channels, " )); } else { PA_DEBUG(( "non-interleaved channels, " )); } PA_DEBUG(( "%d frames/buffer, latency = %5.1f ms\n", stream->bufferProcessor.framesPerUserBuffer, 1000*stream->baseStreamRep.streamInfo.inputLatency )); /* Settings on the host side (internal to PortAudio host API) */ PA_DEBUG(( "host: %d-bit, %d interleaved channels, %d frames/buffer ", 8*stream->bufferProcessor.bytesPerHostInputSample, stream->bufferProcessor.inputChannelCount, stream->bufferProcessor.framesPerHostBuffer )); } switch( stream->bufferProcessor.hostBufferSizeMode ) { case paUtilFixedHostBufferSize: PA_DEBUG(( "[fixed] " )); break; case paUtilBoundedHostBufferSize: PA_DEBUG(( "[bounded] " )); break; case paUtilUnknownHostBufferSize: PA_DEBUG(( "[unknown] " )); break; case paUtilVariableHostBufferSizePartialUsageAllowed: PA_DEBUG(( "[variable] " )); break; } PA_DEBUG(( "(%d max)\n", streamComp->tempBufferSize / streamComp->bytesPerFrame )); /* HPI hardware settings */ PA_DEBUG(( "HPI: adapter %d stream %d, %d-bit, %d-channel, %d Hz\n", streamComp->hpiDevice->adapterIndex, streamComp->hpiDevice->streamIndex, 8 * streamComp->bytesPerFrame / streamComp->hpiFormat.wChannels, streamComp->hpiFormat.wChannels, streamComp->hpiFormat.dwSampleRate )); /* Stream state and buffer levels */ PA_DEBUG(( "HPI: " )); PaAsiHpi_GetStreamInfo( streamComp, &streamInfo ); switch( streamInfo.state ) { case HPI_STATE_STOPPED: PA_DEBUG(( "[STOPPED] " )); break; case HPI_STATE_PLAYING: PA_DEBUG(( "[PLAYING] " )); break; case HPI_STATE_RECORDING: PA_DEBUG(( "[RECORDING] " )); break; case HPI_STATE_DRAINED: PA_DEBUG(( "[DRAINED] " )); break; default: PA_DEBUG(( "[unknown state] " )); break; } if( streamComp->hostBufferSize ) { PA_DEBUG(( "host = %d/%d B, ", streamInfo.dataSize, streamComp->hostBufferSize )); PA_DEBUG(( "hw = %d/%d (%d) B, ", streamInfo.auxDataSize, streamComp->hardwareBufferSize, streamComp->outputBufferCap )); } else { PA_DEBUG(( "hw = %d/%d B, ", streamInfo.dataSize, streamComp->hardwareBufferSize )); } PA_DEBUG(( "count = %d", streamInfo.frameCounter )); if( streamInfo.overflow ) { PA_DEBUG(( " [overflow]" )); } else if( streamInfo.underflow ) { PA_DEBUG(( " [underflow]" )); } PA_DEBUG(( "\n" )); } /** Display stream information for debugging purposes. @param stream Pointer to stream to query */ static void PaAsiHpi_StreamDump( PaAsiHpiStream *stream ) { assert( stream ); PA_DEBUG(( "\n------------------------- STREAM INFO FOR %p ---------------------------\n", stream )); /* General stream info (input+output) */ if( stream->baseStreamRep.streamCallback ) { PA_DEBUG(( "[callback] " )); } else { PA_DEBUG(( "[blocking] " )); } PA_DEBUG(( "sr=%d Hz, poll=%d ms, max %d frames/buf ", (int)stream->baseStreamRep.streamInfo.sampleRate, stream->pollingInterval, stream->maxFramesPerHostBuffer )); switch( stream->state ) { case paAsiHpiStoppedState: PA_DEBUG(( "[stopped]\n" )); break; case paAsiHpiActiveState: PA_DEBUG(( "[active]\n" )); break; case paAsiHpiCallbackFinishedState: PA_DEBUG(( "[cb fin]\n" )); break; default: PA_DEBUG(( "[unknown state]\n" )); break; } if( stream->callbackMode ) { PA_DEBUG(( "cb info: thread=%p, cbAbort=%d, cbFinished=%d\n", stream->thread.thread, stream->callbackAbort, stream->callbackFinished )); } PA_DEBUG(( "----------------------------------- Input ------------------------------------\n" )); if( stream->input ) { PaAsiHpi_StreamComponentDump( stream->input, stream ); } else { PA_DEBUG(( "*none*\n" )); } PA_DEBUG(( "----------------------------------- Output ------------------------------------\n" )); if( stream->output ) { PaAsiHpi_StreamComponentDump( stream->output, stream ); } else { PA_DEBUG(( "*none*\n" )); } PA_DEBUG(( "-------------------------------------------------------------------------------\n\n" )); } /** Determine buffer sizes and allocate appropriate stream buffers. This attempts to allocate a BBM (host) buffer for the HPI stream component (either input or output, as both have similar buffer needs). Not all AudioScience adapters support BBM, in which case the hardware buffer has to suffice. The size of the HPI host buffer is chosen as a multiple of framesPerPaHostBuffer, and also influenced by the suggested latency and the estimated minimum polling interval. The HPI host and hardware buffer sizes are stored, and an appropriate cap for the hardware buffer is also calculated. Finally, the temporary stream buffer which serves as the PortAudio host buffer for this implementation is allocated. This buffer contains an integer number of user buffers, to simplify buffer adaption in the buffer processor. The function returns paBufferTooBig if the HPI interface cannot allocate an HPI host buffer of the desired size. @param streamComp Pointer to stream component struct @param pollingInterval Polling interval for stream, in milliseconds @param framesPerPaHostBuffer Size of PortAudio host buffer, in frames @param suggestedLatency Suggested latency for stream component, in seconds @return PortAudio error code (possibly paBufferTooBig or paInsufficientMemory) */ static PaError PaAsiHpi_SetupBuffers( PaAsiHpiStreamComponent *streamComp, uint32_t pollingInterval, unsigned long framesPerPaHostBuffer, PaTime suggestedLatency ) { PaError result = paNoError; PaAsiHpiStreamInfo streamInfo; unsigned long hpiBufferSize = 0, paHostBufferSize = 0; assert( streamComp ); assert( streamComp->hpiDevice ); /* Obtain size of hardware buffer of HPI stream, since we will be activating BBM shortly and afterwards the buffer size will refer to the BBM (host-side) buffer. This is necessary to enable reliable detection of xruns. */ PA_ENSURE_( PaAsiHpi_GetStreamInfo( streamComp, &streamInfo ) ); streamComp->hardwareBufferSize = streamInfo.bufferSize; hpiBufferSize = streamInfo.bufferSize; /* Check if BBM (background bus mastering) is to be enabled */ if( PA_ASIHPI_USE_BBM_ ) { uint32_t bbmBufferSize = 0, preLatencyBufferSize = 0; hpi_err_t hpiError = 0; PaTime pollingOverhead; /* Check overhead of Pa_Sleep() call (minimum sleep duration in ms -> OS dependent) */ pollingOverhead = PaUtil_GetTime(); Pa_Sleep( 0 ); pollingOverhead = 1000*(PaUtil_GetTime() - pollingOverhead); PA_DEBUG(( "polling overhead = %f ms (length of 0-second sleep)\n", pollingOverhead )); /* Obtain minimum recommended size for host buffer (in bytes) */ PA_ASIHPI_UNLESS_( HPI_StreamEstimateBufferSize( &streamComp->hpiFormat, pollingInterval + (uint32_t)ceil( pollingOverhead ), &bbmBufferSize ), paUnanticipatedHostError ); /* BBM places more stringent requirements on buffer size (see description */ /* of HPI_StreamEstimateBufferSize in HPI API document) */ bbmBufferSize *= 3; /* Make sure the BBM buffer contains multiple PA host buffers */ if( bbmBufferSize < 3 * streamComp->bytesPerFrame * framesPerPaHostBuffer ) bbmBufferSize = 3 * streamComp->bytesPerFrame * framesPerPaHostBuffer; /* Try to honor latency suggested by user by growing buffer (no decrease possible) */ if( suggestedLatency > 0.0 ) { PaTime bufferDuration = ((PaTime)bbmBufferSize) / streamComp->bytesPerFrame / streamComp->hpiFormat.dwSampleRate; /* Don't decrease buffer */ if( bufferDuration < suggestedLatency ) { /* Save old buffer size, to be retried if new size proves too big */ preLatencyBufferSize = bbmBufferSize; bbmBufferSize = (uint32_t)ceil( suggestedLatency * streamComp->bytesPerFrame * streamComp->hpiFormat.dwSampleRate ); } } /* Choose closest memory block boundary (HPI API document states that "a buffer size of Nx4096 - 20 makes the best use of memory" (under the entry for HPI_StreamEstimateBufferSize)) */ bbmBufferSize = ((uint32_t)ceil((bbmBufferSize + 20)/4096.0))*4096 - 20; streamComp->hostBufferSize = bbmBufferSize; /* Allocate BBM host buffer (this enables bus mastering transfers in background) */ if( streamComp->hpiDevice->streamIsOutput ) hpiError = HPI_OutStreamHostBufferAllocate( NULL, streamComp->hpiStream, bbmBufferSize ); else hpiError = HPI_InStreamHostBufferAllocate( NULL, streamComp->hpiStream, bbmBufferSize ); if( hpiError ) { /* Indicate that BBM is disabled */ streamComp->hostBufferSize = 0; /* Retry with smaller buffer size (transfers will still work, but not via BBM) */ if( hpiError == HPI_ERROR_INVALID_DATASIZE ) { /* Retry BBM allocation with smaller size if requested latency proved too big */ if( preLatencyBufferSize > 0 ) { PA_DEBUG(( "Retrying BBM allocation with smaller size (%d vs. %d bytes)\n", preLatencyBufferSize, bbmBufferSize )); bbmBufferSize = preLatencyBufferSize; if( streamComp->hpiDevice->streamIsOutput ) hpiError = HPI_OutStreamHostBufferAllocate( NULL, streamComp->hpiStream, bbmBufferSize ); else hpiError = HPI_InStreamHostBufferAllocate( NULL, streamComp->hpiStream, bbmBufferSize ); /* Another round of error checking */ if( hpiError ) { PA_ASIHPI_REPORT_ERROR_( hpiError ); /* No escapes this time */ if( hpiError == HPI_ERROR_INVALID_DATASIZE ) { result = paBufferTooBig; goto error; } else if( hpiError != HPI_ERROR_INVALID_OPERATION ) { result = paUnanticipatedHostError; goto error; } } else { streamComp->hostBufferSize = bbmBufferSize; hpiBufferSize = bbmBufferSize; } } else { result = paBufferTooBig; goto error; } } /* If BBM not supported, foreground transfers will be used, but not a show-stopper */ /* Anything else is an error */ else if (( hpiError != HPI_ERROR_INVALID_OPERATION ) && ( hpiError != HPI_ERROR_INVALID_FUNC )) { PA_ASIHPI_REPORT_ERROR_( hpiError ); result = paUnanticipatedHostError; goto error; } } else { hpiBufferSize = bbmBufferSize; } } /* Final check of buffer size */ paHostBufferSize = streamComp->bytesPerFrame * framesPerPaHostBuffer; if( hpiBufferSize < 3*paHostBufferSize ) { result = paBufferTooBig; goto error; } /* Set cap on output buffer size, based on latency suggestions */ if( streamComp->hpiDevice->streamIsOutput ) { PaTime latency = suggestedLatency > 0.0 ? suggestedLatency : streamComp->hpiDevice->baseDeviceInfo.defaultHighOutputLatency; streamComp->outputBufferCap = (uint32_t)ceil( latency * streamComp->bytesPerFrame * streamComp->hpiFormat.dwSampleRate ); /* The cap should not be too small, to prevent underflow */ if( streamComp->outputBufferCap < 4*paHostBufferSize ) streamComp->outputBufferCap = 4*paHostBufferSize; } else { streamComp->outputBufferCap = 0; } /* Temp buffer size should be multiple of PA host buffer size (or 1x, if using fixed blocks) */ streamComp->tempBufferSize = paHostBufferSize; /* Allocate temp buffer */ PA_UNLESS_( streamComp->tempBuffer = (uint8_t *)PaUtil_AllocateMemory( streamComp->tempBufferSize ), paInsufficientMemory ); error: return result; } /** Opens PortAudio stream. This determines a suitable value for framesPerBuffer, if the user didn't specify it, based on the suggested latency. It then opens each requested stream direction with the appropriate stream format, and allocates the required stream buffers. It sets up the various PortAudio structures dealing with streams, and estimates the stream latency. See pa_hostapi.h for a list of validity guarantees made about OpenStream parameters. @param hostApi Pointer to host API struct @param s List of open streams, where successfully opened stream will go @param inputParameters Pointer to stream parameter struct for input side of stream @param outputParameters Pointer to stream parameter struct for output side of stream @param sampleRate Desired sample rate @param framesPerBuffer Desired number of frames per buffer passed to user callback (or chunk size for blocking stream) @param streamFlags Stream flags @param streamCallback Pointer to user callback function (zero for blocking interface) @param userData Pointer to user data that will be passed to callback function along with data @return PortAudio error code */ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream **s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ) { PaError result = paNoError; PaAsiHpiHostApiRepresentation *hpiHostApi = (PaAsiHpiHostApiRepresentation*)hostApi; PaAsiHpiStream *stream = NULL; unsigned long framesPerHostBuffer = framesPerBuffer; int inputChannelCount = 0, outputChannelCount = 0; PaSampleFormat inputSampleFormat = 0, outputSampleFormat = 0; PaSampleFormat hostInputSampleFormat = 0, hostOutputSampleFormat = 0; PaTime maxSuggestedLatency = 0.0; /* Validate platform-specific flags -> none expected for HPI */ if( (streamFlags & paPlatformSpecificFlags) != 0 ) return paInvalidFlag; /* unexpected platform-specific flag */ /* Create blank stream structure */ PA_UNLESS_( stream = (PaAsiHpiStream *)PaUtil_AllocateMemory( sizeof(PaAsiHpiStream) ), paInsufficientMemory ); memset( stream, 0, sizeof(PaAsiHpiStream) ); /* If the number of frames per buffer is unspecified, we have to come up with one. */ if( framesPerHostBuffer == paFramesPerBufferUnspecified ) { if( inputParameters ) maxSuggestedLatency = inputParameters->suggestedLatency; if( outputParameters && (outputParameters->suggestedLatency > maxSuggestedLatency) ) maxSuggestedLatency = outputParameters->suggestedLatency; /* Use suggested latency if available */ if( maxSuggestedLatency > 0.0 ) framesPerHostBuffer = (unsigned long)ceil( maxSuggestedLatency * sampleRate ); else /* AudioScience cards like BIG buffers by default */ framesPerHostBuffer = 4096; } /* Lower bounds on host buffer size, due to polling and HPI constraints */ if( 1000.0*framesPerHostBuffer/sampleRate < PA_ASIHPI_MIN_POLLING_INTERVAL_ ) framesPerHostBuffer = (unsigned long)ceil( sampleRate * PA_ASIHPI_MIN_POLLING_INTERVAL_ / 1000.0 ); /* if( framesPerHostBuffer < PA_ASIHPI_MIN_FRAMES_ ) framesPerHostBuffer = PA_ASIHPI_MIN_FRAMES_; */ /* Efficient if host buffer size is integer multiple of user buffer size */ if( framesPerBuffer > 0 ) framesPerHostBuffer = (unsigned long)ceil( (double)framesPerHostBuffer / framesPerBuffer ) * framesPerBuffer; /* Buffer should always be a multiple of 4 bytes to facilitate 32-bit PCI transfers. By keeping the frames a multiple of 4, this is ensured even for 8-bit mono sound. */ framesPerHostBuffer = (framesPerHostBuffer / 4) * 4; /* Polling is based on time length (in milliseconds) of user-requested block size */ stream->pollingInterval = (uint32_t)ceil( 1000.0*framesPerHostBuffer/sampleRate ); assert( framesPerHostBuffer > 0 ); /* Open underlying streams, check formats and allocate buffers */ if( inputParameters ) { /* Create blank stream component structure */ PA_UNLESS_( stream->input = (PaAsiHpiStreamComponent *)PaUtil_AllocateMemory( sizeof(PaAsiHpiStreamComponent) ), paInsufficientMemory ); memset( stream->input, 0, sizeof(PaAsiHpiStreamComponent) ); /* Create/validate format */ PA_ENSURE_( PaAsiHpi_CreateFormat( hostApi, inputParameters, sampleRate, &stream->input->hpiDevice, &stream->input->hpiFormat ) ); /* Open stream and set format */ PA_ENSURE_( PaAsiHpi_OpenInput( hostApi, stream->input->hpiDevice, &stream->input->hpiFormat, &stream->input->hpiStream ) ); inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; hostInputSampleFormat = PaAsiHpi_HpiToPaFormat( stream->input->hpiFormat.wFormat ); stream->input->bytesPerFrame = inputChannelCount * Pa_GetSampleSize( hostInputSampleFormat ); assert( stream->input->bytesPerFrame > 0 ); /* Allocate host and temp buffers of appropriate size */ PA_ENSURE_( PaAsiHpi_SetupBuffers( stream->input, stream->pollingInterval, framesPerHostBuffer, inputParameters->suggestedLatency ) ); } if( outputParameters ) { /* Create blank stream component structure */ PA_UNLESS_( stream->output = (PaAsiHpiStreamComponent *)PaUtil_AllocateMemory( sizeof(PaAsiHpiStreamComponent) ), paInsufficientMemory ); memset( stream->output, 0, sizeof(PaAsiHpiStreamComponent) ); /* Create/validate format */ PA_ENSURE_( PaAsiHpi_CreateFormat( hostApi, outputParameters, sampleRate, &stream->output->hpiDevice, &stream->output->hpiFormat ) ); /* Open stream and check format */ PA_ENSURE_( PaAsiHpi_OpenOutput( hostApi, stream->output->hpiDevice, &stream->output->hpiFormat, &stream->output->hpiStream ) ); outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; hostOutputSampleFormat = PaAsiHpi_HpiToPaFormat( stream->output->hpiFormat.wFormat ); stream->output->bytesPerFrame = outputChannelCount * Pa_GetSampleSize( hostOutputSampleFormat ); /* Allocate host and temp buffers of appropriate size */ PA_ENSURE_( PaAsiHpi_SetupBuffers( stream->output, stream->pollingInterval, framesPerHostBuffer, outputParameters->suggestedLatency ) ); } /* Determine maximum frames per host buffer (least common denominator of input/output) */ if( inputParameters && outputParameters ) { stream->maxFramesPerHostBuffer = PA_MIN( stream->input->tempBufferSize / stream->input->bytesPerFrame, stream->output->tempBufferSize / stream->output->bytesPerFrame ); } else { stream->maxFramesPerHostBuffer = inputParameters ? stream->input->tempBufferSize / stream->input->bytesPerFrame : stream->output->tempBufferSize / stream->output->bytesPerFrame; } assert( stream->maxFramesPerHostBuffer > 0 ); /* Initialize various other stream parameters */ stream->neverDropInput = streamFlags & paNeverDropInput; stream->state = paAsiHpiStoppedState; /* Initialize either callback or blocking interface */ if( streamCallback ) { PaUtil_InitializeStreamRepresentation( &stream->baseStreamRep, &hpiHostApi->callbackStreamInterface, streamCallback, userData ); stream->callbackMode = 1; } else { PaUtil_InitializeStreamRepresentation( &stream->baseStreamRep, &hpiHostApi->blockingStreamInterface, streamCallback, userData ); /* Pre-allocate non-interleaved user buffer pointers for blocking interface */ PA_UNLESS_( stream->blockingUserBufferCopy = PaUtil_AllocateMemory( sizeof(void *) * PA_MAX( inputChannelCount, outputChannelCount ) ), paInsufficientMemory ); stream->callbackMode = 0; } PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate ); /* Following pa_linux_alsa's lead, we operate with fixed host buffer size by default, */ /* since other modes will invariably lead to block adaption (maybe Bounded better?) */ PA_ENSURE_( PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, inputChannelCount, inputSampleFormat, hostInputSampleFormat, outputChannelCount, outputSampleFormat, hostOutputSampleFormat, sampleRate, streamFlags, framesPerBuffer, framesPerHostBuffer, paUtilFixedHostBufferSize, streamCallback, userData ) ); stream->baseStreamRep.streamInfo.structVersion = 1; stream->baseStreamRep.streamInfo.sampleRate = sampleRate; /* Determine input latency from buffer processor and buffer sizes */ if( stream->input ) { PaTime bufferDuration = ( stream->input->hostBufferSize + stream->input->hardwareBufferSize ) / sampleRate / stream->input->bytesPerFrame; stream->baseStreamRep.streamInfo.inputLatency = bufferDuration + ((PaTime)PaUtil_GetBufferProcessorInputLatencyFrames( &stream->bufferProcessor ) - stream->maxFramesPerHostBuffer) / sampleRate; assert( stream->baseStreamRep.streamInfo.inputLatency > 0.0 ); } /* Determine output latency from buffer processor and buffer sizes */ if( stream->output ) { PaTime bufferDuration = ( stream->output->hostBufferSize + stream->output->hardwareBufferSize ) / sampleRate / stream->output->bytesPerFrame; /* Take buffer size cap into account (see PaAsiHpi_WaitForFrames) */ if( !stream->input && (stream->output->outputBufferCap > 0) ) { bufferDuration = PA_MIN( bufferDuration, stream->output->outputBufferCap / sampleRate / stream->output->bytesPerFrame ); } stream->baseStreamRep.streamInfo.outputLatency = bufferDuration + ((PaTime)PaUtil_GetBufferProcessorOutputLatencyFrames( &stream->bufferProcessor ) - stream->maxFramesPerHostBuffer) / sampleRate; assert( stream->baseStreamRep.streamInfo.outputLatency > 0.0 ); } /* Report stream info, for debugging purposes */ PaAsiHpi_StreamDump( stream ); /* Save initialized stream to PA stream list */ *s = (PaStream*)stream; return result; error: CloseStream( (PaStream*)stream ); return result; } /** Close PortAudio stream. When CloseStream() is called, the multi-api layer ensures that the stream has already been stopped or aborted. This closes the underlying HPI streams and deallocates stream buffers and structs. @param s Pointer to PortAudio stream @return PortAudio error code */ static PaError CloseStream( PaStream *s ) { PaError result = paNoError; PaAsiHpiStream *stream = (PaAsiHpiStream*)s; /* If stream is already gone, all is well */ if( stream == NULL ) return paNoError; /* Generic stream cleanup */ PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); PaUtil_TerminateStreamRepresentation( &stream->baseStreamRep ); /* Implementation-specific details - close internal streams */ if( stream->input ) { /* Close HPI stream (freeing BBM host buffer in the process, if used) */ if( stream->input->hpiStream ) { PA_ASIHPI_UNLESS_( HPI_InStreamClose( NULL, stream->input->hpiStream ), paUnanticipatedHostError ); } /* Free temp buffer and stream component */ PaUtil_FreeMemory( stream->input->tempBuffer ); PaUtil_FreeMemory( stream->input ); } if( stream->output ) { /* Close HPI stream (freeing BBM host buffer in the process, if used) */ if( stream->output->hpiStream ) { PA_ASIHPI_UNLESS_( HPI_OutStreamClose( NULL, stream->output->hpiStream ), paUnanticipatedHostError ); } /* Free temp buffer and stream component */ PaUtil_FreeMemory( stream->output->tempBuffer ); PaUtil_FreeMemory( stream->output ); } PaUtil_FreeMemory( stream->blockingUserBufferCopy ); PaUtil_FreeMemory( stream ); error: return result; } /** Prime HPI output stream with silence. This resets the output stream and uses PortAudio helper routines to fill the temp buffer with silence. It then writes two host buffers to the stream. This is supposed to be called before the stream is started. It has no effect on input-only streams. @param stream Pointer to stream struct @return PortAudio error code */ static PaError PaAsiHpi_PrimeOutputWithSilence( PaAsiHpiStream *stream ) { PaError result = paNoError; PaAsiHpiStreamComponent *out; PaUtilZeroer *zeroer; PaSampleFormat outputFormat; assert( stream ); out = stream->output; /* Only continue if stream has output channels */ if( !out ) return result; assert( out->tempBuffer ); /* Clear all existing data in hardware playback buffer */ PA_ASIHPI_UNLESS_( HPI_OutStreamReset( NULL, out->hpiStream ), paUnanticipatedHostError ); /* Fill temp buffer with silence */ outputFormat = PaAsiHpi_HpiToPaFormat( out->hpiFormat.wFormat ); zeroer = PaUtil_SelectZeroer( outputFormat ); zeroer(out->tempBuffer, 1, out->tempBufferSize / Pa_GetSampleSize(outputFormat) ); /* Write temp buffer to hardware fifo twice, to get started */ PA_ASIHPI_UNLESS_( HPI_OutStreamWriteBuf( NULL, out->hpiStream, out->tempBuffer, out->tempBufferSize, &out->hpiFormat), paUnanticipatedHostError ); PA_ASIHPI_UNLESS_( HPI_OutStreamWriteBuf( NULL, out->hpiStream, out->tempBuffer, out->tempBufferSize, &out->hpiFormat), paUnanticipatedHostError ); error: return result; } /** Start HPI streams (both input + output). This starts all HPI streams in the PortAudio stream. Output streams are first primed with silence, if required. After this call the PA stream is in the Active state. @todo Implement priming via the user callback @param stream Pointer to stream struct @param outputPrimed True if output is already primed (if false, silence will be loaded before starting) @return PortAudio error code */ static PaError PaAsiHpi_StartStream( PaAsiHpiStream *stream, int outputPrimed ) { PaError result = paNoError; if( stream->input ) { PA_ASIHPI_UNLESS_( HPI_InStreamStart( NULL, stream->input->hpiStream ), paUnanticipatedHostError ); } if( stream->output ) { if( !outputPrimed ) { /* Buffer isn't primed, so load stream with silence */ PA_ENSURE_( PaAsiHpi_PrimeOutputWithSilence( stream ) ); } PA_ASIHPI_UNLESS_( HPI_OutStreamStart( NULL, stream->output->hpiStream ), paUnanticipatedHostError ); } stream->state = paAsiHpiActiveState; stream->callbackFinished = 0; /* Report stream info for debugging purposes */ /* PaAsiHpi_StreamDump( stream ); */ error: return result; } /** Start PortAudio stream. If the stream has a callback interface, this starts a helper thread to feed the user callback. The thread will then take care of starting the HPI streams, and this function will block until the streams actually start. In the case of a blocking interface, the HPI streams are simply started. @param s Pointer to PortAudio stream @return PortAudio error code */ static PaError StartStream( PaStream *s ) { PaError result = paNoError; PaAsiHpiStream *stream = (PaAsiHpiStream*)s; assert( stream ); /* Ready the processor */ PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); if( stream->callbackMode ) { /* Create and start callback engine thread */ /* Also waits 1 second for stream to be started by engine thread (otherwise aborts) */ PA_ENSURE_( PaUnixThread_New( &stream->thread, &CallbackThreadFunc, stream, 1., 0 /*rtSched*/ ) ); } else { PA_ENSURE_( PaAsiHpi_StartStream( stream, 0 ) ); } error: return result; } /** Stop HPI streams (input + output), either softly or abruptly. If abort is false, the function blocks until the output stream is drained, otherwise it stops immediately and discards data in the stream hardware buffers. This function is safe to call from the callback engine thread as well as the main thread. @param stream Pointer to stream struct @param abort True if samples in output buffer should be discarded (otherwise blocks until stream is done) @return PortAudio error code */ static PaError PaAsiHpi_StopStream( PaAsiHpiStream *stream, int abort ) { PaError result = paNoError; assert( stream ); /* Input channels */ if( stream->input ) { PA_ASIHPI_UNLESS_( HPI_InStreamReset( NULL, stream->input->hpiStream ), paUnanticipatedHostError ); } /* Output channels */ if( stream->output ) { if( !abort ) { /* Wait until HPI output stream is drained */ while( 1 ) { PaAsiHpiStreamInfo streamInfo; PaTime timeLeft; /* Obtain number of samples waiting to be played */ PA_ENSURE_( PaAsiHpi_GetStreamInfo( stream->output, &streamInfo ) ); /* Check if stream is drained */ if( (streamInfo.state != HPI_STATE_PLAYING) && (streamInfo.dataSize < stream->output->bytesPerFrame * PA_ASIHPI_MIN_FRAMES_) ) break; /* Sleep amount of time represented by remaining samples */ timeLeft = 1000.0 * streamInfo.dataSize / stream->output->bytesPerFrame / stream->baseStreamRep.streamInfo.sampleRate; Pa_Sleep( (long)ceil( timeLeft ) ); } } PA_ASIHPI_UNLESS_( HPI_OutStreamReset( NULL, stream->output->hpiStream ), paUnanticipatedHostError ); } /* Report stream info for debugging purposes */ /* PaAsiHpi_StreamDump( stream ); */ error: return result; } /** Stop or abort PortAudio stream. This function is used to explicitly stop the PortAudio stream (via StopStream/AbortStream), as opposed to the situation when the callback finishes with a result other than paContinue. If a stream is in callback mode we will have to inspect whether the background thread has finished, or we will have to take it out. In either case we join the thread before returning. In blocking mode, we simply tell HPI to stop abruptly (abort) or finish buffers (drain). The PortAudio stream will be in the Stopped state after a call to this function. Don't call this from the callback engine thread! @param stream Pointer to stream struct @param abort True if samples in output buffer should be discarded (otherwise blocks until stream is done) @return PortAudio error code */ static PaError PaAsiHpi_ExplicitStop( PaAsiHpiStream *stream, int abort ) { PaError result = paNoError; /* First deal with the callback thread, cancelling and/or joining it if necessary */ if( stream->callbackMode ) { PaError threadRes; stream->callbackAbort = abort; if( abort ) { PA_DEBUG(( "Aborting callback\n" )); } else { PA_DEBUG(( "Stopping callback\n" )); } PA_ENSURE_( PaUnixThread_Terminate( &stream->thread, !abort, &threadRes ) ); if( threadRes != paNoError ) { PA_DEBUG(( "Callback thread returned: %d\n", threadRes )); } } else { PA_ENSURE_( PaAsiHpi_StopStream( stream, abort ) ); } stream->state = paAsiHpiStoppedState; error: return result; } /** Stop PortAudio stream. This blocks until the output buffers are drained. @param s Pointer to PortAudio stream @return PortAudio error code */ static PaError StopStream( PaStream *s ) { return PaAsiHpi_ExplicitStop( (PaAsiHpiStream *) s, 0 ); } /** Abort PortAudio stream. This discards any existing data in output buffers and stops the stream immediately. @param s Pointer to PortAudio stream @return PortAudio error code */ static PaError AbortStream( PaStream *s ) { return PaAsiHpi_ExplicitStop( (PaAsiHpiStream * ) s, 1 ); } /** Determine whether the stream is stopped. A stream is considered to be stopped prior to a successful call to StartStream and after a successful call to StopStream or AbortStream. If a stream callback returns a value other than paContinue the stream is NOT considered to be stopped (it is in CallbackFinished state). @param s Pointer to PortAudio stream @return Returns one (1) when the stream is stopped, zero (0) when the stream is running, or a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. */ static PaError IsStreamStopped( PaStream *s ) { PaAsiHpiStream *stream = (PaAsiHpiStream*)s; assert( stream ); return stream->state == paAsiHpiStoppedState ? 1 : 0; } /** Determine whether the stream is active. A stream is active after a successful call to StartStream(), until it becomes inactive either as a result of a call to StopStream() or AbortStream(), or as a result of a return value other than paContinue from the stream callback. In the latter case, the stream is considered inactive after the last buffer has finished playing. @param s Pointer to PortAudio stream @return Returns one (1) when the stream is active (i.e. playing or recording audio), zero (0) when not playing, or a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. */ static PaError IsStreamActive( PaStream *s ) { PaAsiHpiStream *stream = (PaAsiHpiStream*)s; assert( stream ); return stream->state == paAsiHpiActiveState ? 1 : 0; } /** Returns current stream time. This corresponds to the system clock. The clock should run continuously while the stream is open, i.e. between calls to OpenStream() and CloseStream(), therefore a frame counter is not good enough. @param s Pointer to PortAudio stream @return Stream time, in seconds */ static PaTime GetStreamTime( PaStream *s ) { return PaUtil_GetTime(); } /** Returns CPU load. @param s Pointer to PortAudio stream @return CPU load (0.0 if blocking interface is used) */ static double GetStreamCpuLoad( PaStream *s ) { PaAsiHpiStream *stream = (PaAsiHpiStream*)s; return stream->callbackMode ? PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ) : 0.0; } /* --------------------------- Callback Interface --------------------------- */ /** Exit routine which is called when callback thread quits. This takes care of stopping the HPI streams (either waiting for output to finish, or abruptly). It also calls the user-supplied StreamFinished callback, and sets the stream state to CallbackFinished if it was reached via a non-paContinue return from the user callback function. @param userData A pointer to an open stream previously created with Pa_OpenStream */ static void PaAsiHpi_OnThreadExit( void *userData ) { PaAsiHpiStream *stream = (PaAsiHpiStream *) userData; assert( stream ); PaUtil_ResetCpuLoadMeasurer( &stream->cpuLoadMeasurer ); PA_DEBUG(( "%s: Stopping HPI streams\n", __FUNCTION__ )); PaAsiHpi_StopStream( stream, stream->callbackAbort ); PA_DEBUG(( "%s: Stoppage\n", __FUNCTION__ )); /* Eventually notify user all buffers have played */ if( stream->baseStreamRep.streamFinishedCallback ) { stream->baseStreamRep.streamFinishedCallback( stream->baseStreamRep.userData ); } /* Unfortunately both explicit calls to Stop/AbortStream (leading to Stopped state) and implicit stops via paComplete/paAbort (leading to CallbackFinished state) end up here - need another flag to remind us which is the case */ if( stream->callbackFinished ) stream->state = paAsiHpiCallbackFinishedState; } /** Wait until there is enough frames to fill a host buffer. The routine attempts to sleep until at least a full host buffer can be retrieved from the input HPI stream and passed to the output HPI stream. It will first sleep until enough output space is available, as this is usually easily achievable. If it is an output-only stream, it will also sleep if the hardware buffer is too full, thereby throttling the filling of the output buffer and reducing output latency. The routine then blocks until enough input samples are available, unless this will cause an output underflow. In the process, input overflows and output underflows are indicated. @param stream Pointer to stream struct @param framesAvail Returns the number of available frames @param cbFlags Overflows and underflows indicated in here @return PortAudio error code (only paUnanticipatedHostError expected) */ static PaError PaAsiHpi_WaitForFrames( PaAsiHpiStream *stream, unsigned long *framesAvail, PaStreamCallbackFlags *cbFlags ) { PaError result = paNoError; double sampleRate; unsigned long framesTarget; uint32_t outputData = 0, outputSpace = 0, inputData = 0, framesLeft = 0; assert( stream ); assert( stream->input || stream->output ); sampleRate = stream->baseStreamRep.streamInfo.sampleRate; /* We have to come up with this much frames on both input and output */ framesTarget = stream->bufferProcessor.framesPerHostBuffer; assert( framesTarget > 0 ); while( 1 ) { PaAsiHpiStreamInfo info; /* Check output first, as this takes priority in the default full-duplex mode */ if( stream->output ) { PA_ENSURE_( PaAsiHpi_GetStreamInfo( stream->output, &info ) ); /* Wait until enough space is available in output buffer to receive a full block */ if( info.availableFrames < framesTarget ) { framesLeft = framesTarget - info.availableFrames; Pa_Sleep( (long)ceil( 1000 * framesLeft / sampleRate ) ); continue; } /* Wait until the data in hardware buffer has dropped to a sensible level. Without this, the hardware buffer quickly fills up in the absence of an input stream to regulate its data rate (if data generation is fast). This leads to large latencies, as the AudioScience hardware buffers are humongous. This is similar to the default "Hardware Buffering=off" option in the AudioScience WAV driver. */ if( !stream->input && (stream->output->outputBufferCap > 0) && ( info.totalBufferedData > stream->output->outputBufferCap / stream->output->bytesPerFrame ) ) { framesLeft = info.totalBufferedData - stream->output->outputBufferCap / stream->output->bytesPerFrame; Pa_Sleep( (long)ceil( 1000 * framesLeft / sampleRate ) ); continue; } outputData = info.totalBufferedData; outputSpace = info.availableFrames; /* Report output underflow to callback */ if( info.underflow ) { *cbFlags |= paOutputUnderflow; } } /* Now check input side */ if( stream->input ) { PA_ENSURE_( PaAsiHpi_GetStreamInfo( stream->input, &info ) ); /* If a full block of samples hasn't been recorded yet, wait for it if possible */ if( info.availableFrames < framesTarget ) { framesLeft = framesTarget - info.availableFrames; /* As long as output is not disrupted in the process, wait for a full block of input samples */ if( !stream->output || (outputData > framesLeft) ) { Pa_Sleep( (long)ceil( 1000 * framesLeft / sampleRate ) ); continue; } } inputData = info.availableFrames; /** @todo The paInputOverflow flag should be set in the callback containing the first input sample following the overflow. That means the block currently sitting at the fore-front of recording, i.e. typically the one containing the newest (last) sample in the HPI buffer system. This is most likely not the same as the current block of data being passed to the callback. The current overflow should ideally be noted in an overflow list of sorts, with an indication of when it should be reported. The trouble starts if there are several separate overflow incidents, given a big input buffer. Oh well, something to try out later... */ if( info.overflow ) { *cbFlags |= paInputOverflow; } } break; } /* Full-duplex stream */ if( stream->input && stream->output ) { if( outputSpace >= framesTarget ) *framesAvail = outputSpace; /* If input didn't make the target, keep the output count instead (input underflow) */ if( (inputData >= framesTarget) && (inputData < outputSpace) ) *framesAvail = inputData; } else { *framesAvail = stream->input ? inputData : outputSpace; } error: return result; } /** Obtain recording, current and playback timestamps of stream. The current time is determined by the system clock. This "now" timestamp occurs at the forefront of recording (and playback in the full-duplex case), which happens later than the input timestamp by an amount equal to the total number of recorded frames in the input buffer. The output timestamp indicates when the next generated sample will actually be played. This happens after all the samples currently in the output buffer are played. The output timestamp therefore follows the current timestamp by an amount equal to the number of frames yet to be played back in the output buffer. If the current timestamp is the present, the input timestamp is in the past and the output timestamp is in the future. @param stream Pointer to stream struct @param timeInfo Pointer to timeInfo struct that will contain timestamps */ static void PaAsiHpi_CalculateTimeInfo( PaAsiHpiStream *stream, PaStreamCallbackTimeInfo *timeInfo ) { PaAsiHpiStreamInfo streamInfo; double sampleRate; assert( stream ); assert( timeInfo ); sampleRate = stream->baseStreamRep.streamInfo.sampleRate; /* The current time ("now") is at the forefront of both recording and playback */ timeInfo->currentTime = GetStreamTime( (PaStream *)stream ); /* The last sample in the input buffer was recorded just now, so the first sample happened (number of recorded samples)/sampleRate ago */ timeInfo->inputBufferAdcTime = timeInfo->currentTime; if( stream->input ) { PaAsiHpi_GetStreamInfo( stream->input, &streamInfo ); timeInfo->inputBufferAdcTime -= streamInfo.totalBufferedData / sampleRate; } /* The first of the outgoing samples will be played after all the samples in the output buffer is done */ timeInfo->outputBufferDacTime = timeInfo->currentTime; if( stream->output ) { PaAsiHpi_GetStreamInfo( stream->output, &streamInfo ); timeInfo->outputBufferDacTime += streamInfo.totalBufferedData / sampleRate; } } /** Read from HPI input stream and register buffers. This reads data from the HPI input stream (if it exists) and registers the temp stream buffers of both input and output streams with the buffer processor. In the process it also handles input underflows in the full-duplex case. @param stream Pointer to stream struct @param numFrames On entrance the number of available frames, on exit the number of received frames @param cbFlags Indicates overflows and underflows @return PortAudio error code */ static PaError PaAsiHpi_BeginProcessing( PaAsiHpiStream *stream, unsigned long *numFrames, PaStreamCallbackFlags *cbFlags ) { PaError result = paNoError; assert( stream ); if( *numFrames > stream->maxFramesPerHostBuffer ) *numFrames = stream->maxFramesPerHostBuffer; if( stream->input ) { PaAsiHpiStreamInfo info; uint32_t framesToGet = *numFrames; /* Check for overflows and underflows yet again */ PA_ENSURE_( PaAsiHpi_GetStreamInfo( stream->input, &info ) ); if( info.overflow ) { *cbFlags |= paInputOverflow; } /* Input underflow if less than expected number of samples pitch up */ if( framesToGet > info.availableFrames ) { PaUtilZeroer *zeroer; PaSampleFormat inputFormat; /* Never call an input-only stream with InputUnderflow set */ if( stream->output ) *cbFlags |= paInputUnderflow; framesToGet = info.availableFrames; /* Fill temp buffer with silence (to make up for missing input samples) */ inputFormat = PaAsiHpi_HpiToPaFormat( stream->input->hpiFormat.wFormat ); zeroer = PaUtil_SelectZeroer( inputFormat ); zeroer(stream->input->tempBuffer, 1, stream->input->tempBufferSize / Pa_GetSampleSize(inputFormat) ); } /* Read block of data into temp buffer */ PA_ASIHPI_UNLESS_( HPI_InStreamReadBuf( NULL, stream->input->hpiStream, stream->input->tempBuffer, framesToGet * stream->input->bytesPerFrame), paUnanticipatedHostError ); /* Register temp buffer with buffer processor (always FULL buffer) */ PaUtil_SetInputFrameCount( &stream->bufferProcessor, *numFrames ); /* HPI interface only allows interleaved channels */ PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, 0, stream->input->tempBuffer, stream->input->hpiFormat.wChannels ); } if( stream->output ) { /* Register temp buffer with buffer processor */ PaUtil_SetOutputFrameCount( &stream->bufferProcessor, *numFrames ); /* HPI interface only allows interleaved channels */ PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, 0, stream->output->tempBuffer, stream->output->hpiFormat.wChannels ); } error: return result; } /** Flush output buffers to HPI output stream. This completes the processing cycle by writing the temp buffer to the HPI interface. Additional output underflows are caught before data is written to the stream, as this action typically remedies the underflow and hides it in the process. @param stream Pointer to stream struct @param numFrames The number of frames to write to the output stream @param cbFlags Indicates overflows and underflows */ static PaError PaAsiHpi_EndProcessing( PaAsiHpiStream *stream, unsigned long numFrames, PaStreamCallbackFlags *cbFlags ) { PaError result = paNoError; assert( stream ); if( stream->output ) { PaAsiHpiStreamInfo info; /* Check for underflows after the (potentially time-consuming) callback */ PA_ENSURE_( PaAsiHpi_GetStreamInfo( stream->output, &info ) ); if( info.underflow ) { *cbFlags |= paOutputUnderflow; } /* Write temp buffer to HPI stream */ PA_ASIHPI_UNLESS_( HPI_OutStreamWriteBuf( NULL, stream->output->hpiStream, stream->output->tempBuffer, numFrames * stream->output->bytesPerFrame, &stream->output->hpiFormat), paUnanticipatedHostError ); } error: return result; } /** Main callback engine. This function runs in a separate thread and does all the work of fetching audio data from the AudioScience card via the HPI interface, feeding it to the user callback via the buffer processor, and delivering the resulting output data back to the card via HPI calls. It is started and terminated when the PortAudio stream is started and stopped, and starts the HPI streams on startup. @param userData A pointer to an open stream previously created with Pa_OpenStream. */ static void *CallbackThreadFunc( void *userData ) { PaError result = paNoError; PaAsiHpiStream *stream = (PaAsiHpiStream *) userData; int callbackResult = paContinue; assert( stream ); /* Cleanup routine stops streams on thread exit */ pthread_cleanup_push( &PaAsiHpi_OnThreadExit, stream ); /* Start HPI streams and notify parent when we're done */ PA_ENSURE_( PaUnixThread_PrepareNotify( &stream->thread ) ); /* Buffer will be primed with silence */ PA_ENSURE_( PaAsiHpi_StartStream( stream, 0 ) ); PA_ENSURE_( PaUnixThread_NotifyParent( &stream->thread ) ); /* MAIN LOOP */ while( 1 ) { PaStreamCallbackFlags cbFlags = 0; unsigned long framesAvail, framesGot; pthread_testcancel(); /** @concern StreamStop if the main thread has requested a stop and the stream has not * been effectively stopped we signal this condition by modifying callbackResult * (we'll want to flush buffered output). */ if( PaUnixThread_StopRequested( &stream->thread ) && (callbackResult == paContinue) ) { PA_DEBUG(( "Setting callbackResult to paComplete\n" )); callbackResult = paComplete; } /* Start winding down thread if requested */ if( callbackResult != paContinue ) { stream->callbackAbort = (callbackResult == paAbort); if( stream->callbackAbort || /** @concern BlockAdaption: Go on if adaption buffers are empty */ PaUtil_IsBufferProcessorOutputEmpty( &stream->bufferProcessor ) ) { goto end; } PA_DEBUG(( "%s: Flushing buffer processor\n", __FUNCTION__ )); /* There is still buffered output that needs to be processed */ } /* SLEEP */ /* Wait for data (or buffer space) to become available. This basically sleeps and polls the HPI interface until a full block of frames can be moved. */ PA_ENSURE_( PaAsiHpi_WaitForFrames( stream, &framesAvail, &cbFlags ) ); /* Consume buffer space. Once we have a number of frames available for consumption we must retrieve the data from the HPI interface and pass it to the PA buffer processor. We should be prepared to process several chunks successively. */ while( framesAvail > 0 ) { PaStreamCallbackTimeInfo timeInfo = {0, 0, 0}; pthread_testcancel(); framesGot = framesAvail; if( stream->bufferProcessor.hostBufferSizeMode == paUtilFixedHostBufferSize ) { /* We've committed to a fixed host buffer size, stick to that */ framesGot = framesGot >= stream->maxFramesPerHostBuffer ? stream->maxFramesPerHostBuffer : 0; } else { /* We've committed to an upper bound on the size of host buffers */ assert( stream->bufferProcessor.hostBufferSizeMode == paUtilBoundedHostBufferSize ); framesGot = PA_MIN( framesGot, stream->maxFramesPerHostBuffer ); } /* Obtain buffer timestamps */ PaAsiHpi_CalculateTimeInfo( stream, &timeInfo ); PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, cbFlags ); /* CPU load measurement should include processing activivity external to the stream callback */ PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); if( framesGot > 0 ) { /* READ FROM HPI INPUT STREAM */ PA_ENSURE_( PaAsiHpi_BeginProcessing( stream, &framesGot, &cbFlags ) ); /* Input overflow in a full-duplex stream makes for interesting times */ if( stream->input && stream->output && (cbFlags & paInputOverflow) ) { /* Special full-duplex paNeverDropInput mode */ if( stream->neverDropInput ) { PaUtil_SetNoOutput( &stream->bufferProcessor ); cbFlags |= paOutputOverflow; } } /* CALL USER CALLBACK WITH INPUT DATA, AND OBTAIN OUTPUT DATA */ PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult ); /* Clear overflow and underflow information (but PaAsiHpi_EndProcessing might still show up output underflow that will carry over to next round) */ cbFlags = 0; /* WRITE TO HPI OUTPUT STREAM */ PA_ENSURE_( PaAsiHpi_EndProcessing( stream, framesGot, &cbFlags ) ); /* Advance frame counter */ framesAvail -= framesGot; } PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesGot ); if( framesGot == 0 ) { /* Go back to polling for more frames */ break; } if( callbackResult != paContinue ) break; } } /* This code is unreachable, but important to include regardless because it * is possibly a macro with a closing brace to match the opening brace in * pthread_cleanup_push() above. The documentation states that they must * always occur in pairs. */ pthread_cleanup_pop( 1 ); end: /* Indicates normal exit of callback, as opposed to the thread getting killed explicitly */ stream->callbackFinished = 1; PA_DEBUG(( "%s: Thread %d exiting (callbackResult = %d)\n ", __FUNCTION__, pthread_self(), callbackResult )); /* Exit from thread and report any PortAudio error in the process */ PaUnixThreading_EXIT( result ); error: goto end; } /* --------------------------- Blocking Interface --------------------------- */ /* As separate stream interfaces are used for blocking and callback streams, the following functions can be guaranteed to only be called for blocking streams. */ /** Read data from input stream. This reads the indicated number of frames into the supplied buffer from an input stream, and blocks until this is done. @param s Pointer to PortAudio stream @param buffer Pointer to buffer that will receive interleaved data (or an array of pointers to a buffer for each non-interleaved channel) @param frames Number of frames to read from stream @return PortAudio error code (also indicates overflow via paInputOverflowed) */ static PaError ReadStream( PaStream *s, void *buffer, unsigned long frames ) { PaError result = paNoError; PaAsiHpiStream *stream = (PaAsiHpiStream*)s; PaAsiHpiStreamInfo info; void *userBuffer; assert( stream ); PA_UNLESS_( stream->input, paCanNotReadFromAnOutputOnlyStream ); /* Check for input overflow since previous call to ReadStream */ PA_ENSURE_( PaAsiHpi_GetStreamInfo( stream->input, &info ) ); if( info.overflow ) { result = paInputOverflowed; } /* NB Make copy of user buffer pointers, since they are advanced by buffer processor */ if( stream->bufferProcessor.userInputIsInterleaved ) { userBuffer = buffer; } else { /* Copy channels into local array */ userBuffer = stream->blockingUserBufferCopy; memcpy( userBuffer, buffer, sizeof (void *) * stream->input->hpiFormat.wChannels ); } while( frames > 0 ) { unsigned long framesGot, framesAvail; PaStreamCallbackFlags cbFlags = 0; PA_ENSURE_( PaAsiHpi_WaitForFrames( stream, &framesAvail, &cbFlags ) ); framesGot = PA_MIN( framesAvail, frames ); PA_ENSURE_( PaAsiHpi_BeginProcessing( stream, &framesGot, &cbFlags ) ); if( framesGot > 0 ) { framesGot = PaUtil_CopyInput( &stream->bufferProcessor, &userBuffer, framesGot ); PA_ENSURE_( PaAsiHpi_EndProcessing( stream, framesGot, &cbFlags ) ); /* Advance frame counter */ frames -= framesGot; } } error: return result; } /** Write data to output stream. This writes the indicated number of frames from the supplied buffer to an output stream, and blocks until this is done. @param s Pointer to PortAudio stream @param buffer Pointer to buffer that provides interleaved data (or an array of pointers to a buffer for each non-interleaved channel) @param frames Number of frames to write to stream @return PortAudio error code (also indicates underflow via paOutputUnderflowed) */ static PaError WriteStream( PaStream *s, const void *buffer, unsigned long frames ) { PaError result = paNoError; PaAsiHpiStream *stream = (PaAsiHpiStream*)s; PaAsiHpiStreamInfo info; const void *userBuffer; assert( stream ); PA_UNLESS_( stream->output, paCanNotWriteToAnInputOnlyStream ); /* Check for output underflow since previous call to WriteStream */ PA_ENSURE_( PaAsiHpi_GetStreamInfo( stream->output, &info ) ); if( info.underflow ) { result = paOutputUnderflowed; } /* NB Make copy of user buffer pointers, since they are advanced by buffer processor */ if( stream->bufferProcessor.userOutputIsInterleaved ) { userBuffer = buffer; } else { /* Copy channels into local array */ userBuffer = stream->blockingUserBufferCopy; memcpy( (void *)userBuffer, buffer, sizeof (void *) * stream->output->hpiFormat.wChannels ); } while( frames > 0 ) { unsigned long framesGot, framesAvail; PaStreamCallbackFlags cbFlags = 0; PA_ENSURE_( PaAsiHpi_WaitForFrames( stream, &framesAvail, &cbFlags ) ); framesGot = PA_MIN( framesAvail, frames ); PA_ENSURE_( PaAsiHpi_BeginProcessing( stream, &framesGot, &cbFlags ) ); if( framesGot > 0 ) { framesGot = PaUtil_CopyOutput( &stream->bufferProcessor, &userBuffer, framesGot ); PA_ENSURE_( PaAsiHpi_EndProcessing( stream, framesGot, &cbFlags ) ); /* Advance frame counter */ frames -= framesGot; } } error: return result; } /** Number of frames that can be read from input stream without blocking. @param s Pointer to PortAudio stream @return Number of frames, or PortAudio error code */ static signed long GetStreamReadAvailable( PaStream *s ) { PaError result = paNoError; PaAsiHpiStream *stream = (PaAsiHpiStream*)s; PaAsiHpiStreamInfo info; assert( stream ); PA_UNLESS_( stream->input, paCanNotReadFromAnOutputOnlyStream ); PA_ENSURE_( PaAsiHpi_GetStreamInfo( stream->input, &info ) ); /* Round down to the nearest host buffer multiple */ result = (info.availableFrames / stream->maxFramesPerHostBuffer) * stream->maxFramesPerHostBuffer; if( info.overflow ) { result = paInputOverflowed; } error: return result; } /** Number of frames that can be written to output stream without blocking. @param s Pointer to PortAudio stream @return Number of frames, or PortAudio error code */ static signed long GetStreamWriteAvailable( PaStream *s ) { PaError result = paNoError; PaAsiHpiStream *stream = (PaAsiHpiStream*)s; PaAsiHpiStreamInfo info; assert( stream ); PA_UNLESS_( stream->output, paCanNotWriteToAnInputOnlyStream ); PA_ENSURE_( PaAsiHpi_GetStreamInfo( stream->output, &info ) ); /* Round down to the nearest host buffer multiple */ result = (info.availableFrames / stream->maxFramesPerHostBuffer) * stream->maxFramesPerHostBuffer; if( info.underflow ) { result = paOutputUnderflowed; } error: return result; } praat-6.0.04/external/portaudio/pa_mac_core.c000066400000000000000000003423741261542461700211610ustar00rootroot00000000000000/* * Implementation of the PortAudio API for Apple AUHAL * * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * * Written by Bjorn Roche of XO Audio LLC, from PA skeleton code. * Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation) * * Dominic's code was based on code by Phil Burk, Darren Gibbs, * Gord Peters, Stephane Letz, and Greg Pfiel. * * The following people also deserve acknowledgements: * * Olivier Tristan for feedback and testing * Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O * interface. * * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file pa_mac_core @ingroup hostapi_src @author Bjorn Roche @brief AUHAL implementation of PortAudio */ /* FIXME: not all error conditions call PaUtil_SetLastHostErrorInfo() * PaMacCore_SetError() will do this. */ #include "pa_mac_core_internal.h" #include /* strlen(), memcmp() etc. */ #include #include "pa_mac_core.h" #include "pa_mac_core_utilities.h" #include "pa_mac_core_blocking.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* This is a reasonable size for a small buffer based on experience. */ #define PA_MAC_SMALL_BUFFER_SIZE (64) /* prototypes for functions declared in this file */ PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); /* * Function declared in pa_mac_core.h. Sets up a PaMacCoreStreamInfoStruct * with the requested flags and initializes channel map. */ void PaMacCore_SetupStreamInfo( PaMacCoreStreamInfo *data, const unsigned long flags ) { bzero( data, sizeof( PaMacCoreStreamInfo ) ); data->size = sizeof( PaMacCoreStreamInfo ); data->hostApiType = paCoreAudio; data->version = 0x01; data->flags = flags; data->channelMap = NULL; data->channelMapSize = 0; } /* * Function declared in pa_mac_core.h. Adds channel mapping to a PaMacCoreStreamInfoStruct */ void PaMacCore_SetupChannelMap( PaMacCoreStreamInfo *data, const SInt32 * const channelMap, const unsigned long channelMapSize ) { data->channelMap = channelMap; data->channelMapSize = channelMapSize; } static char *channelName = NULL; static int channelNameSize = 0; static bool ensureChannelNameSize( int size ) { if( size >= channelNameSize ) { free( channelName ); channelName = (char *) malloc( ( channelNameSize = size ) + 1 ); if( !channelName ) { channelNameSize = 0; return false; } } return true; } /* * Function declared in pa_mac_core.h. retrives channel names. */ const char *PaMacCore_GetChannelName( int device, int channelIndex, bool input ) { struct PaUtilHostApiRepresentation *hostApi; PaError err; OSStatus error; err = PaUtil_GetHostApiRepresentation( &hostApi, paCoreAudio ); assert(err == paNoError); if( err != paNoError ) return NULL; PaMacAUHAL *macCoreHostApi = (PaMacAUHAL*)hostApi; AudioDeviceID hostApiDevice = macCoreHostApi->devIds[device]; UInt32 size = 0; error = AudioDeviceGetPropertyInfo( hostApiDevice, channelIndex + 1, input, kAudioDevicePropertyChannelName, &size, NULL ); if( error ) { //try the CFString CFStringRef name; bool isDeviceName = false; size = sizeof( name ); error = AudioDeviceGetProperty( hostApiDevice, channelIndex + 1, input, kAudioDevicePropertyChannelNameCFString, &size, &name ); if( error ) { //as a last-ditch effort, get the device name. Later we'll append the channel number. size = sizeof( name ); error = AudioDeviceGetProperty( hostApiDevice, channelIndex + 1, input, kAudioDevicePropertyDeviceNameCFString, &size, &name ); if( error ) return NULL; isDeviceName = true; } if( isDeviceName ) { name = CFStringCreateWithFormat( NULL, NULL, CFSTR( "%@: %d"), name, channelIndex + 1 ); } CFIndex length = CFStringGetLength(name); while( ensureChannelNameSize( length * sizeof(UniChar) + 1 ) ) { if( CFStringGetCString( name, channelName, channelNameSize, kCFStringEncodingUTF8 ) ) { if( isDeviceName ) CFRelease( name ); return channelName; } if( length == 0 ) ++length; length *= 2; } if( isDeviceName ) CFRelease( name ); return NULL; } //continue with C string: if( !ensureChannelNameSize( size ) ) return NULL; error = AudioDeviceGetProperty( hostApiDevice, channelIndex + 1, input, kAudioDevicePropertyChannelName, &size, channelName ); if( error ) { ERR( error ); return NULL; } return channelName; } PaError PaMacCore_GetBufferSizeRange( PaDeviceIndex device, long *minBufferSizeFrames, long *maxBufferSizeFrames ) { PaError result; PaUtilHostApiRepresentation *hostApi; result = PaUtil_GetHostApiRepresentation( &hostApi, paCoreAudio ); if( result == paNoError ) { PaDeviceIndex hostApiDeviceIndex; result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDeviceIndex, device, hostApi ); if( result == paNoError ) { PaMacAUHAL *macCoreHostApi = (PaMacAUHAL*)hostApi; AudioDeviceID macCoreDeviceId = macCoreHostApi->devIds[hostApiDeviceIndex]; AudioValueRange audioRange; UInt32 propSize = sizeof( audioRange ); // return the size range for the output scope unless we only have inputs Boolean isInput = 0; if( macCoreHostApi->inheritedHostApiRep.deviceInfos[hostApiDeviceIndex]->maxOutputChannels == 0 ) isInput = 1; result = WARNING(AudioDeviceGetProperty( macCoreDeviceId, 0, isInput, kAudioDevicePropertyBufferFrameSizeRange, &propSize, &audioRange ) ); *minBufferSizeFrames = audioRange.mMinimum; *maxBufferSizeFrames = audioRange.mMaximum; } } return result; } AudioDeviceID PaMacCore_GetStreamInputDevice( PaStream* s ) { PaMacCoreStream *stream = (PaMacCoreStream*)s; VVDBUG(("PaMacCore_GetStreamInputHandle()\n")); return ( stream->inputDevice ); } AudioDeviceID PaMacCore_GetStreamOutputDevice( PaStream* s ) { PaMacCoreStream *stream = (PaMacCoreStream*)s; VVDBUG(("PaMacCore_GetStreamOutputHandle()\n")); return ( stream->outputDevice ); } #ifdef __cplusplus } #endif /* __cplusplus */ #define RING_BUFFER_ADVANCE_DENOMINATOR (4) static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); static PaError CloseStream( PaStream* stream ); static PaError StartStream( PaStream *stream ); static PaError StopStream( PaStream *stream ); static PaError AbortStream( PaStream *stream ); static PaError IsStreamStopped( PaStream *s ); static PaError IsStreamActive( PaStream *stream ); static PaTime GetStreamTime( PaStream *stream ); static OSStatus AudioIOProc( void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData ); static double GetStreamCpuLoad( PaStream* stream ); static PaError GetChannelInfo( PaMacAUHAL *auhalHostApi, PaDeviceInfo *deviceInfo, AudioDeviceID macCoreDeviceId, int isInput); static PaError OpenAndSetupOneAudioUnit( const PaMacCoreStream *stream, const PaStreamParameters *inStreamParams, const PaStreamParameters *outStreamParams, const UInt32 requestedFramesPerBuffer, UInt32 *actualInputFramesPerBuffer, UInt32 *actualOutputFramesPerBuffer, const PaMacAUHAL *auhalHostApi, AudioUnit *audioUnit, AudioConverterRef *srConverter, AudioDeviceID *audioDevice, const double sampleRate, void *refCon ); /* for setting errors. */ #define PA_AUHAL_SET_LAST_HOST_ERROR( errorCode, errorText ) \ PaUtil_SetLastHostErrorInfo( paInDevelopment, errorCode, errorText ) /* * Callback called when starting or stopping a stream. */ static void startStopCallback( void * inRefCon, AudioUnit ci, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement ) { PaMacCoreStream *stream = (PaMacCoreStream *) inRefCon; UInt32 isRunning; UInt32 size = sizeof( isRunning ); OSStatus err; err = AudioUnitGetProperty( ci, kAudioOutputUnitProperty_IsRunning, inScope, inElement, &isRunning, &size ); assert( !err ); if( err ) isRunning = false; //it's very unclear what to do in case of error here. There's no real way to notify the user, and crashing seems unreasonable. if( isRunning ) return; //We are only interested in when we are stopping // -- if we are using 2 I/O units, we only need one notification! if( stream->inputUnit && stream->outputUnit && stream->inputUnit != stream->outputUnit && ci == stream->inputUnit ) return; PaStreamFinishedCallback *sfc = stream->streamRepresentation.streamFinishedCallback; if( stream->state == STOPPING ) stream->state = STOPPED ; if( sfc ) sfc( stream->streamRepresentation.userData ); } /*currently, this is only used in initialization, but it might be modified to be used when the list of devices changes.*/ static PaError gatherDeviceInfo(PaMacAUHAL *auhalHostApi) { UInt32 size; UInt32 propsize; VVDBUG(("gatherDeviceInfo()\n")); /* -- free any previous allocations -- */ if( auhalHostApi->devIds ) PaUtil_GroupFreeMemory(auhalHostApi->allocations, auhalHostApi->devIds); auhalHostApi->devIds = NULL; /* -- figure out how many devices there are -- */ AudioHardwareGetPropertyInfo( kAudioHardwarePropertyDevices, &propsize, NULL ); auhalHostApi->devCount = propsize / sizeof( AudioDeviceID ); VDBUG( ( "Found %ld device(s).\n", auhalHostApi->devCount ) ); /* -- copy the device IDs -- */ auhalHostApi->devIds = (AudioDeviceID *)PaUtil_GroupAllocateMemory( auhalHostApi->allocations, propsize ); if( !auhalHostApi->devIds ) return paInsufficientMemory; AudioHardwareGetProperty( kAudioHardwarePropertyDevices, &propsize, auhalHostApi->devIds ); #ifdef MAC_CORE_VERBOSE_DEBUG { int i; for( i=0; idevCount; ++i ) printf( "Device %d\t: %ld\n", i, auhalHostApi->devIds[i] ); } #endif size = sizeof(AudioDeviceID); auhalHostApi->defaultIn = kAudioDeviceUnknown; auhalHostApi->defaultOut = kAudioDeviceUnknown; /* determine the default device. */ /* I am not sure how these calls to AudioHardwareGetProperty() could fail, but in case they do, we use the first available device as the default. */ if( 0 != AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &size, &auhalHostApi->defaultIn) ) { int i; auhalHostApi->defaultIn = kAudioDeviceUnknown; VDBUG(("Failed to get default input device from OS.")); VDBUG((" I will substitute the first available input Device.")); for( i=0; idevCount; ++i ) { PaDeviceInfo devInfo; if( 0 != GetChannelInfo( auhalHostApi, &devInfo, auhalHostApi->devIds[i], TRUE ) ) if( devInfo.maxInputChannels ) { auhalHostApi->defaultIn = auhalHostApi->devIds[i]; break; } } } if( 0 != AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &size, &auhalHostApi->defaultOut) ) { int i; auhalHostApi->defaultIn = kAudioDeviceUnknown; VDBUG(("Failed to get default output device from OS.")); VDBUG((" I will substitute the first available output Device.")); for( i=0; idevCount; ++i ) { PaDeviceInfo devInfo; if( 0 != GetChannelInfo( auhalHostApi, &devInfo, auhalHostApi->devIds[i], FALSE ) ) if( devInfo.maxOutputChannels ) { auhalHostApi->defaultOut = auhalHostApi->devIds[i]; break; } } } VDBUG( ( "Default in : %ld\n", auhalHostApi->defaultIn ) ); VDBUG( ( "Default out: %ld\n", auhalHostApi->defaultOut ) ); return paNoError; } /* =================================================================================================== */ /** * @internal * @brief Clip the desired size against the allowed IO buffer size range for the device. */ static PaError ClipToDeviceBufferSize( AudioDeviceID macCoreDeviceId, int isInput, UInt32 desiredSize, UInt32 *allowedSize ) { UInt32 resultSize = desiredSize; AudioValueRange audioRange; UInt32 propSize = sizeof( audioRange ); PaError err = WARNING(AudioDeviceGetProperty( macCoreDeviceId, 0, isInput, kAudioDevicePropertyBufferFrameSizeRange, &propSize, &audioRange ) ); resultSize = MAX( resultSize, audioRange.mMinimum ); resultSize = MIN( resultSize, audioRange.mMaximum ); *allowedSize = resultSize; return err; } /* =================================================================================================== */ #if 0 static void DumpDeviceProperties( AudioDeviceID macCoreDeviceId, int isInput ) { PaError err; int i; UInt32 propSize; UInt32 deviceLatency; UInt32 streamLatency; UInt32 bufferFrames; UInt32 safetyOffset; AudioStreamID streamIDs[128]; printf("\n======= latency query : macCoreDeviceId = %d, isInput %d =======\n", (int)macCoreDeviceId, isInput ); propSize = sizeof(UInt32); err = WARNING(AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyBufferFrameSize, &propSize, &bufferFrames)); printf("kAudioDevicePropertyBufferFrameSize: err = %d, propSize = %d, value = %d\n", err, propSize, bufferFrames ); propSize = sizeof(UInt32); err = WARNING(AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertySafetyOffset, &propSize, &safetyOffset)); printf("kAudioDevicePropertySafetyOffset: err = %d, propSize = %d, value = %d\n", err, propSize, safetyOffset ); propSize = sizeof(UInt32); err = WARNING(AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyLatency, &propSize, &deviceLatency)); printf("kAudioDevicePropertyLatency: err = %d, propSize = %d, value = %d\n", err, propSize, deviceLatency ); AudioValueRange audioRange; propSize = sizeof( audioRange ); err = WARNING(AudioDeviceGetProperty( macCoreDeviceId, 0, isInput, kAudioDevicePropertyBufferFrameSizeRange, &propSize, &audioRange ) ); printf("kAudioDevicePropertyBufferFrameSizeRange: err = %d, propSize = %u, minimum = %g\n", err, propSize, audioRange.mMinimum); printf("kAudioDevicePropertyBufferFrameSizeRange: err = %d, propSize = %u, maximum = %g\n", err, propSize, audioRange.mMaximum ); /* Get the streams from the device and query their latency. */ propSize = sizeof(streamIDs); err = WARNING(AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyStreams, &propSize, &streamIDs[0])); int numStreams = propSize / sizeof(AudioStreamID); for( i=0; imNumberBuffers; ++i) numChannels += buflist->mBuffers[i].mNumberChannels; if (isInput) deviceInfo->maxInputChannels = numChannels; else deviceInfo->maxOutputChannels = numChannels; if (numChannels > 0) /* do not try to retrieve the latency if there are no channels. */ { /* Get the latency. Don't fail if we can't get this. */ /* default to something reasonable */ deviceInfo->defaultLowInputLatency = .01; deviceInfo->defaultHighInputLatency = .10; deviceInfo->defaultLowOutputLatency = .01; deviceInfo->defaultHighOutputLatency = .10; UInt32 lowLatencyFrames = 0; UInt32 highLatencyFrames = 0; err = CalculateDefaultDeviceLatencies( macCoreDeviceId, isInput, &lowLatencyFrames, &highLatencyFrames ); if( err == 0 ) { double lowLatencySeconds = lowLatencyFrames / deviceInfo->defaultSampleRate; double highLatencySeconds = highLatencyFrames / deviceInfo->defaultSampleRate; if (isInput) { deviceInfo->defaultLowInputLatency = lowLatencySeconds; deviceInfo->defaultHighInputLatency = highLatencySeconds; } else { deviceInfo->defaultLowOutputLatency = lowLatencySeconds; deviceInfo->defaultHighOutputLatency = highLatencySeconds; } } } PaUtil_FreeMemory( buflist ); return paNoError; error: PaUtil_FreeMemory( buflist ); return err; } /* =================================================================================================== */ static PaError InitializeDeviceInfo( PaMacAUHAL *auhalHostApi, PaDeviceInfo *deviceInfo, AudioDeviceID macCoreDeviceId, PaHostApiIndex hostApiIndex ) { Float64 sampleRate; char *name; PaError err = paNoError; UInt32 propSize; VVDBUG(("InitializeDeviceInfo(): macCoreDeviceId=%ld\n", macCoreDeviceId)); memset(deviceInfo, 0, sizeof(PaDeviceInfo)); deviceInfo->structVersion = 2; deviceInfo->hostApi = hostApiIndex; /* Get the device name. Fail if we can't get it. */ err = ERR(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, NULL)); if (err) return err; name = PaUtil_GroupAllocateMemory(auhalHostApi->allocations,propSize); if ( !name ) return paInsufficientMemory; err = ERR(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, name)); if (err) return err; deviceInfo->name = name; /* Try to get the default sample rate. Don't fail if we can't get this. */ propSize = sizeof(Float64); err = ERR(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyNominalSampleRate, &propSize, &sampleRate)); if (err) deviceInfo->defaultSampleRate = 0.0; else deviceInfo->defaultSampleRate = sampleRate; /* Get the maximum number of input and output channels. Fail if we can't get this. */ err = GetChannelInfo(auhalHostApi, deviceInfo, macCoreDeviceId, 1); if (err) return err; err = GetChannelInfo(auhalHostApi, deviceInfo, macCoreDeviceId, 0); if (err) return err; return paNoError; } PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) { PaError result = paNoError; int i; PaMacAUHAL *auhalHostApi = NULL; PaDeviceInfo *deviceInfoArray; int unixErr; VVDBUG(("PaMacCore_Initialize(): hostApiIndex=%d\n", hostApiIndex)); SInt32 major; SInt32 minor; Gestalt(gestaltSystemVersionMajor, &major); Gestalt(gestaltSystemVersionMinor, &minor); // Starting with 10.6 systems, the HAL notification thread is created internally if (major == 10 && minor >= 6) { CFRunLoopRef theRunLoop = NULL; AudioObjectPropertyAddress theAddress = { kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; OSStatus osErr = AudioObjectSetPropertyData (kAudioObjectSystemObject, &theAddress, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop); if (osErr != noErr) { goto error; } } unixErr = initializeXRunListenerList(); if( 0 != unixErr ) { return UNIX_ERR(unixErr); } auhalHostApi = (PaMacAUHAL*)PaUtil_AllocateMemory( sizeof(PaMacAUHAL) ); if( !auhalHostApi ) { result = paInsufficientMemory; goto error; } auhalHostApi->allocations = PaUtil_CreateAllocationGroup(); if( !auhalHostApi->allocations ) { result = paInsufficientMemory; goto error; } auhalHostApi->devIds = NULL; auhalHostApi->devCount = 0; /* get the info we need about the devices */ result = gatherDeviceInfo( auhalHostApi ); if( result != paNoError ) goto error; *hostApi = &auhalHostApi->inheritedHostApiRep; (*hostApi)->info.structVersion = 1; (*hostApi)->info.type = paCoreAudio; (*hostApi)->info.name = "Core Audio"; (*hostApi)->info.defaultInputDevice = paNoDevice; (*hostApi)->info.defaultOutputDevice = paNoDevice; (*hostApi)->info.deviceCount = 0; if( auhalHostApi->devCount > 0 ) { (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( auhalHostApi->allocations, sizeof(PaDeviceInfo*) * auhalHostApi->devCount); if( !(*hostApi)->deviceInfos ) { result = paInsufficientMemory; goto error; } /* allocate all device info structs in a contiguous block */ deviceInfoArray = (PaDeviceInfo*)PaUtil_GroupAllocateMemory( auhalHostApi->allocations, sizeof(PaDeviceInfo) * auhalHostApi->devCount ); if( !deviceInfoArray ) { result = paInsufficientMemory; goto error; } for( i=0; i < auhalHostApi->devCount; ++i ) { int err; err = InitializeDeviceInfo( auhalHostApi, &deviceInfoArray[i], auhalHostApi->devIds[i], hostApiIndex ); if (err == paNoError) { /* copy some info and set the defaults */ (*hostApi)->deviceInfos[(*hostApi)->info.deviceCount] = &deviceInfoArray[i]; if (auhalHostApi->devIds[i] == auhalHostApi->defaultIn) (*hostApi)->info.defaultInputDevice = (*hostApi)->info.deviceCount; if (auhalHostApi->devIds[i] == auhalHostApi->defaultOut) (*hostApi)->info.defaultOutputDevice = (*hostApi)->info.deviceCount; (*hostApi)->info.deviceCount++; } else { /* there was an error. we need to shift the devices down, so we ignore this one */ int j; auhalHostApi->devCount--; for( j=i; jdevCount; ++j ) auhalHostApi->devIds[j] = auhalHostApi->devIds[j+1]; i--; } } } (*hostApi)->Terminate = Terminate; (*hostApi)->OpenStream = OpenStream; (*hostApi)->IsFormatSupported = IsFormatSupported; PaUtil_InitializeStreamInterface( &auhalHostApi->callbackStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, GetStreamCpuLoad, PaUtil_DummyRead, PaUtil_DummyWrite, PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); PaUtil_InitializeStreamInterface( &auhalHostApi->blockingStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, PaUtil_DummyGetCpuLoad, ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable ); return result; error: if( auhalHostApi ) { if( auhalHostApi->allocations ) { PaUtil_FreeAllAllocations( auhalHostApi->allocations ); PaUtil_DestroyAllocationGroup( auhalHostApi->allocations ); } PaUtil_FreeMemory( auhalHostApi ); } return result; } static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) { int unixErr; PaMacAUHAL *auhalHostApi = (PaMacAUHAL*)hostApi; VVDBUG(("Terminate()\n")); unixErr = destroyXRunListenerList(); if( 0 != unixErr ) UNIX_ERR(unixErr); /* IMPLEMENT ME: - clean up any resources not handled by the allocation group TODO: Double check that everything is handled by alloc group */ if( auhalHostApi->allocations ) { PaUtil_FreeAllAllocations( auhalHostApi->allocations ); PaUtil_DestroyAllocationGroup( auhalHostApi->allocations ); } PaUtil_FreeMemory( auhalHostApi ); } static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { int inputChannelCount, outputChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; VVDBUG(("IsFormatSupported(): in chan=%d, in fmt=%ld, out chan=%d, out fmt=%ld sampleRate=%g\n", inputParameters ? inputParameters->channelCount : -1, inputParameters ? inputParameters->sampleFormat : -1, outputParameters ? outputParameters->channelCount : -1, outputParameters ? outputParameters->sampleFormat : -1, (float) sampleRate )); /** These first checks are standard PA checks. We do some fancier checks later. */ if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( inputSampleFormat & paCustomFormat ) return paSampleFormatNotSupported; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that input device can support inputChannelCount */ if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) return paInvalidChannelCount; } else { inputChannelCount = 0; } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( outputSampleFormat & paCustomFormat ) return paSampleFormatNotSupported; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that output device can support outputChannelCount */ if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) return paInvalidChannelCount; } else { outputChannelCount = 0; } /* FEEDBACK */ /* I think the only way to check a given format SR combo is */ /* to try opening it. This could be disruptive, is that Okay? */ /* The alternative is to just read off available sample rates, */ /* but this will not work %100 of the time (eg, a device that */ /* supports N output at one rate but only N/2 at a higher rate.)*/ /* The following code opens the device with the requested parameters to see if it works. */ { PaError err; PaStream *s; err = OpenStream( hostApi, &s, inputParameters, outputParameters, sampleRate, 1024, 0, (PaStreamCallback *)1, NULL ); if( err != paNoError && err != paInvalidSampleRate ) DBUG( ( "OpenStream @ %g returned: %d: %s\n", (float) sampleRate, err, Pa_GetErrorText( err ) ) ); if( err ) return err; err = CloseStream( s ); if( err ) { /* FEEDBACK: is this more serious? should we assert? */ DBUG( ( "WARNING: could not close Stream. %d: %s\n", err, Pa_GetErrorText( err ) ) ); } } return paFormatIsSupported; } /* ================================================================================= */ static void InitializeDeviceProperties( PaMacCoreDeviceProperties *deviceProperties ) { memset( deviceProperties, 0, sizeof(PaMacCoreDeviceProperties) ); deviceProperties->sampleRate = 1.0; // Better than random. Overwritten by actual values later on. deviceProperties->samplePeriod = 1.0 / deviceProperties->sampleRate; } static Float64 CalculateSoftwareLatencyFromProperties( PaMacCoreStream *stream, PaMacCoreDeviceProperties *deviceProperties ) { UInt32 latencyFrames = deviceProperties->bufferFrameSize + deviceProperties->deviceLatency + deviceProperties->safetyOffset; return latencyFrames * deviceProperties->samplePeriod; // same as dividing by sampleRate but faster } static Float64 CalculateHardwareLatencyFromProperties( PaMacCoreStream *stream, PaMacCoreDeviceProperties *deviceProperties ) { return deviceProperties->deviceLatency * deviceProperties->samplePeriod; // same as dividing by sampleRate but faster } /* Calculate values used to convert Apple timestamps into PA timestamps * from the device properties. The final results of this calculation * will be used in the audio callback function. */ static void UpdateTimeStampOffsets( PaMacCoreStream *stream ) { Float64 inputSoftwareLatency = 0.0; Float64 inputHardwareLatency = 0.0; Float64 outputSoftwareLatency = 0.0; Float64 outputHardwareLatency = 0.0; if( stream->inputUnit != NULL ) { inputSoftwareLatency = CalculateSoftwareLatencyFromProperties( stream, &stream->inputProperties ); inputHardwareLatency = CalculateHardwareLatencyFromProperties( stream, &stream->inputProperties ); } if( stream->outputUnit != NULL ) { outputSoftwareLatency = CalculateSoftwareLatencyFromProperties( stream, &stream->outputProperties ); outputHardwareLatency = CalculateHardwareLatencyFromProperties( stream, &stream->outputProperties ); } /* We only need a mutex around setting these variables as a group. */ pthread_mutex_lock( &stream->timingInformationMutex ); stream->timestampOffsetCombined = inputSoftwareLatency + outputSoftwareLatency; stream->timestampOffsetInputDevice = inputHardwareLatency; stream->timestampOffsetOutputDevice = outputHardwareLatency; pthread_mutex_unlock( &stream->timingInformationMutex ); } /* ================================================================================= */ /* can be used to update from nominal or actual sample rate */ static OSStatus UpdateSampleRateFromDeviceProperty( PaMacCoreStream *stream, AudioDeviceID deviceID, Boolean isInput, AudioDevicePropertyID sampleRatePropertyID ) { PaMacCoreDeviceProperties * deviceProperties = isInput ? &stream->inputProperties : &stream->outputProperties; Float64 sampleRate = 0.0; UInt32 propSize = sizeof(Float64); OSStatus osErr = AudioDeviceGetProperty( deviceID, 0, isInput, sampleRatePropertyID, &propSize, &sampleRate); if( (osErr == noErr) && (sampleRate > 1000.0) ) /* avoid divide by zero if there's an error */ { deviceProperties->sampleRate = sampleRate; deviceProperties->samplePeriod = 1.0 / sampleRate; } return osErr; } static OSStatus AudioDevicePropertyActualSampleRateListenerProc( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void *inClientData ) { PaMacCoreStream *stream = (PaMacCoreStream*)inClientData; // Make sure the callback is operating on a stream that is still valid! assert( stream->streamRepresentation.magic == PA_STREAM_MAGIC ); OSStatus osErr = UpdateSampleRateFromDeviceProperty( stream, inDevice, isInput, kAudioDevicePropertyActualSampleRate ); if( osErr == noErr ) { UpdateTimeStampOffsets( stream ); } return osErr; } /* ================================================================================= */ static OSStatus QueryUInt32DeviceProperty( AudioDeviceID deviceID, Boolean isInput, AudioDevicePropertyID propertyID, UInt32 *outValue ) { UInt32 propertyValue = 0; UInt32 propertySize = sizeof(UInt32); OSStatus osErr = AudioDeviceGetProperty( deviceID, 0, isInput, propertyID, &propertySize, &propertyValue); if( osErr == noErr ) { *outValue = propertyValue; } return osErr; } static OSStatus AudioDevicePropertyGenericListenerProc( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void *inClientData ) { OSStatus osErr = noErr; PaMacCoreStream *stream = (PaMacCoreStream*)inClientData; // Make sure the callback is operating on a stream that is still valid! assert( stream->streamRepresentation.magic == PA_STREAM_MAGIC ); PaMacCoreDeviceProperties *deviceProperties = isInput ? &stream->inputProperties : &stream->outputProperties; UInt32 *valuePtr = NULL; switch( inPropertyID ) { case kAudioDevicePropertySafetyOffset: valuePtr = &deviceProperties->safetyOffset; break; case kAudioDevicePropertyLatency: valuePtr = &deviceProperties->deviceLatency; break; case kAudioDevicePropertyBufferFrameSize: valuePtr = &deviceProperties->bufferFrameSize; break; } if( valuePtr != NULL ) { osErr = QueryUInt32DeviceProperty( inDevice, isInput, inPropertyID, valuePtr ); if( osErr == noErr ) { UpdateTimeStampOffsets( stream ); } } return osErr; } /* ================================================================================= */ /* * Setup listeners in case device properties change during the run. */ static OSStatus SetupDevicePropertyListeners( PaMacCoreStream *stream, AudioDeviceID deviceID, Boolean isInput ) { OSStatus osErr = noErr; PaMacCoreDeviceProperties *deviceProperties = isInput ? &stream->inputProperties : &stream->outputProperties; if( (osErr = QueryUInt32DeviceProperty( deviceID, isInput, kAudioDevicePropertyLatency, &deviceProperties->deviceLatency )) != noErr ) return osErr; if( (osErr = QueryUInt32DeviceProperty( deviceID, isInput, kAudioDevicePropertyBufferFrameSize, &deviceProperties->bufferFrameSize )) != noErr ) return osErr; if( (osErr = QueryUInt32DeviceProperty( deviceID, isInput, kAudioDevicePropertySafetyOffset, &deviceProperties->safetyOffset )) != noErr ) return osErr; AudioDeviceAddPropertyListener( deviceID, 0, isInput, kAudioDevicePropertyActualSampleRate, AudioDevicePropertyActualSampleRateListenerProc, stream ); AudioDeviceAddPropertyListener( deviceID, 0, isInput, kAudioStreamPropertyLatency, AudioDevicePropertyGenericListenerProc, stream ); AudioDeviceAddPropertyListener( deviceID, 0, isInput, kAudioDevicePropertyBufferFrameSize, AudioDevicePropertyGenericListenerProc, stream ); AudioDeviceAddPropertyListener( deviceID, 0, isInput, kAudioDevicePropertySafetyOffset, AudioDevicePropertyGenericListenerProc, stream ); return osErr; } static void CleanupDevicePropertyListeners( PaMacCoreStream *stream, AudioDeviceID deviceID, Boolean isInput ) { AudioDeviceRemovePropertyListener( deviceID, 0, isInput, kAudioDevicePropertyActualSampleRate, AudioDevicePropertyActualSampleRateListenerProc ); AudioDeviceRemovePropertyListener( deviceID, 0, isInput, kAudioDevicePropertyLatency, AudioDevicePropertyGenericListenerProc ); AudioDeviceRemovePropertyListener( deviceID, 0, isInput, kAudioDevicePropertyBufferFrameSize, AudioDevicePropertyGenericListenerProc ); AudioDeviceRemovePropertyListener( deviceID, 0, isInput, kAudioDevicePropertySafetyOffset, AudioDevicePropertyGenericListenerProc ); } /* ================================================================================= */ static PaError OpenAndSetupOneAudioUnit( const PaMacCoreStream *stream, const PaStreamParameters *inStreamParams, const PaStreamParameters *outStreamParams, const UInt32 requestedFramesPerBuffer, UInt32 *actualInputFramesPerBuffer, UInt32 *actualOutputFramesPerBuffer, const PaMacAUHAL *auhalHostApi, AudioUnit *audioUnit, AudioConverterRef *srConverter, AudioDeviceID *audioDevice, const double sampleRate, void *refCon ) { ComponentDescription desc; Component comp; /*An Apple TN suggests using CAStreamBasicDescription, but that is C++*/ AudioStreamBasicDescription desiredFormat; OSStatus result = noErr; PaError paResult = paNoError; int line = 0; UInt32 callbackKey; AURenderCallbackStruct rcbs; unsigned long macInputStreamFlags = paMacCorePlayNice; unsigned long macOutputStreamFlags = paMacCorePlayNice; SInt32 const *inChannelMap = NULL; SInt32 const *outChannelMap = NULL; unsigned long inChannelMapSize = 0; unsigned long outChannelMapSize = 0; VVDBUG(("OpenAndSetupOneAudioUnit(): in chan=%d, in fmt=%ld, out chan=%d, out fmt=%ld, requestedFramesPerBuffer=%ld\n", inStreamParams ? inStreamParams->channelCount : -1, inStreamParams ? inStreamParams->sampleFormat : -1, outStreamParams ? outStreamParams->channelCount : -1, outStreamParams ? outStreamParams->sampleFormat : -1, requestedFramesPerBuffer )); /* -- handle the degenerate case -- */ if( !inStreamParams && !outStreamParams ) { *audioUnit = NULL; *audioDevice = kAudioDeviceUnknown; return paNoError; } /* -- get the user's api specific info, if they set any -- */ if( inStreamParams && inStreamParams->hostApiSpecificStreamInfo ) { macInputStreamFlags= ((PaMacCoreStreamInfo*)inStreamParams->hostApiSpecificStreamInfo) ->flags; inChannelMap = ((PaMacCoreStreamInfo*)inStreamParams->hostApiSpecificStreamInfo) ->channelMap; inChannelMapSize = ((PaMacCoreStreamInfo*)inStreamParams->hostApiSpecificStreamInfo) ->channelMapSize; } if( outStreamParams && outStreamParams->hostApiSpecificStreamInfo ) { macOutputStreamFlags= ((PaMacCoreStreamInfo*)outStreamParams->hostApiSpecificStreamInfo) ->flags; outChannelMap = ((PaMacCoreStreamInfo*)outStreamParams->hostApiSpecificStreamInfo) ->channelMap; outChannelMapSize = ((PaMacCoreStreamInfo*)outStreamParams->hostApiSpecificStreamInfo) ->channelMapSize; } /* Override user's flags here, if desired for testing. */ /* * The HAL AU is a Mac OS style "component". * the first few steps deal with that. * Later steps work on a combination of Mac OS * components and the slightly lower level * HAL. */ /* -- describe the output type AudioUnit -- */ /* Note: for the default AudioUnit, we could use the * componentSubType value kAudioUnitSubType_DefaultOutput; * but I don't think that's relevant here. */ desc.componentType = kAudioUnitType_Output; desc.componentSubType = kAudioUnitSubType_HALOutput; desc.componentManufacturer = kAudioUnitManufacturer_Apple; desc.componentFlags = 0; desc.componentFlagsMask = 0; /* -- find the component -- */ comp = FindNextComponent( NULL, &desc ); if( !comp ) { DBUG( ( "AUHAL component not found." ) ); *audioUnit = NULL; *audioDevice = kAudioDeviceUnknown; return paUnanticipatedHostError; } /* -- open it -- */ result = OpenAComponent( comp, audioUnit ); if( result ) { DBUG( ( "Failed to open AUHAL component." ) ); *audioUnit = NULL; *audioDevice = kAudioDeviceUnknown; return ERR( result ); } /* -- prepare a little error handling logic / hackery -- */ #define ERR_WRAP(mac_err) do { result = mac_err ; line = __LINE__ ; if ( result != noErr ) goto error ; } while(0) /* -- if there is input, we have to explicitly enable input -- */ if( inStreamParams ) { UInt32 enableIO = 1; ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, INPUT_ELEMENT, &enableIO, sizeof(enableIO) ) ); } /* -- if there is no output, we must explicitly disable output -- */ if( !outStreamParams ) { UInt32 enableIO = 0; ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, OUTPUT_ELEMENT, &enableIO, sizeof(enableIO) ) ); } /* -- set the devices -- */ /* make sure input and output are the same device if we are doing input and output. */ if( inStreamParams && outStreamParams ) { assert( outStreamParams->device == inStreamParams->device ); } if( inStreamParams ) { *audioDevice = auhalHostApi->devIds[inStreamParams->device] ; ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, INPUT_ELEMENT, audioDevice, sizeof(AudioDeviceID) ) ); } if( outStreamParams && outStreamParams != inStreamParams ) { *audioDevice = auhalHostApi->devIds[outStreamParams->device] ; ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, OUTPUT_ELEMENT, audioDevice, sizeof(AudioDeviceID) ) ); } /* -- add listener for dropouts -- */ result = AudioDeviceAddPropertyListener( *audioDevice, 0, outStreamParams ? false : true, kAudioDeviceProcessorOverload, xrunCallback, addToXRunListenerList( (void *)stream ) ) ; if( result == kAudioHardwareIllegalOperationError ) { // -- already registered, we're good } else { // -- not already registered, just check for errors ERR_WRAP( result ); } /* -- listen for stream start and stop -- */ ERR_WRAP( AudioUnitAddPropertyListener( *audioUnit, kAudioOutputUnitProperty_IsRunning, startStopCallback, (void *)stream ) ); /* -- set format -- */ bzero( &desiredFormat, sizeof(desiredFormat) ); desiredFormat.mFormatID = kAudioFormatLinearPCM ; desiredFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked; desiredFormat.mFramesPerPacket = 1; desiredFormat.mBitsPerChannel = sizeof( float ) * 8; result = 0; /* set device format first, but only touch the device if the user asked */ if( inStreamParams ) { /*The callback never calls back if we don't set the FPB */ /*This seems wierd, because I would think setting anything on the device would be disruptive.*/ paResult = setBestFramesPerBuffer( *audioDevice, FALSE, requestedFramesPerBuffer, actualInputFramesPerBuffer ); if( paResult ) goto error; if( macInputStreamFlags & paMacCoreChangeDeviceParameters ) { bool requireExact; requireExact=macInputStreamFlags & paMacCoreFailIfConversionRequired; paResult = setBestSampleRateForDevice( *audioDevice, FALSE, requireExact, sampleRate ); if( paResult ) goto error; } if( actualInputFramesPerBuffer && actualOutputFramesPerBuffer ) *actualOutputFramesPerBuffer = *actualInputFramesPerBuffer ; } if( outStreamParams && !inStreamParams ) { /*The callback never calls back if we don't set the FPB */ /*This seems wierd, because I would think setting anything on the device would be disruptive.*/ paResult = setBestFramesPerBuffer( *audioDevice, TRUE, requestedFramesPerBuffer, actualOutputFramesPerBuffer ); if( paResult ) goto error; if( macOutputStreamFlags & paMacCoreChangeDeviceParameters ) { bool requireExact; requireExact=macOutputStreamFlags & paMacCoreFailIfConversionRequired; paResult = setBestSampleRateForDevice( *audioDevice, TRUE, requireExact, sampleRate ); if( paResult ) goto error; } } /* -- set the quality of the output converter -- */ if( outStreamParams ) { UInt32 value = kAudioConverterQuality_Max; switch( macOutputStreamFlags & 0x0700 ) { case 0x0100: /*paMacCore_ConversionQualityMin:*/ value=kRenderQuality_Min; break; case 0x0200: /*paMacCore_ConversionQualityLow:*/ value=kRenderQuality_Low; break; case 0x0300: /*paMacCore_ConversionQualityMedium:*/ value=kRenderQuality_Medium; break; case 0x0400: /*paMacCore_ConversionQualityHigh:*/ value=kRenderQuality_High; break; } ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioUnitProperty_RenderQuality, kAudioUnitScope_Global, OUTPUT_ELEMENT, &value, sizeof(value) ) ); } /* now set the format on the Audio Units. */ if( outStreamParams ) { desiredFormat.mSampleRate =sampleRate; desiredFormat.mBytesPerPacket=sizeof(float)*outStreamParams->channelCount; desiredFormat.mBytesPerFrame =sizeof(float)*outStreamParams->channelCount; desiredFormat.mChannelsPerFrame = outStreamParams->channelCount; ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, OUTPUT_ELEMENT, &desiredFormat, sizeof(AudioStreamBasicDescription) ) ); } if( inStreamParams ) { AudioStreamBasicDescription sourceFormat; UInt32 size = sizeof( AudioStreamBasicDescription ); /* keep the sample rate of the device, or we confuse AUHAL */ ERR_WRAP( AudioUnitGetProperty( *audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, INPUT_ELEMENT, &sourceFormat, &size ) ); desiredFormat.mSampleRate = sourceFormat.mSampleRate; desiredFormat.mBytesPerPacket=sizeof(float)*inStreamParams->channelCount; desiredFormat.mBytesPerFrame =sizeof(float)*inStreamParams->channelCount; desiredFormat.mChannelsPerFrame = inStreamParams->channelCount; ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, INPUT_ELEMENT, &desiredFormat, sizeof(AudioStreamBasicDescription) ) ); } /* set the maximumFramesPerSlice */ /* not doing this causes real problems (eg. the callback might not be called). The idea of setting both this and the frames per buffer on the device is that we'll be most likely to actually get the frame size we requested in the callback with the minimum latency. */ if( outStreamParams ) { UInt32 size = sizeof( *actualOutputFramesPerBuffer ); ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Input, OUTPUT_ELEMENT, actualOutputFramesPerBuffer, sizeof(*actualOutputFramesPerBuffer) ) ); ERR_WRAP( AudioUnitGetProperty( *audioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, OUTPUT_ELEMENT, actualOutputFramesPerBuffer, &size ) ); } if( inStreamParams ) { /*UInt32 size = sizeof( *actualInputFramesPerBuffer );*/ ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Output, INPUT_ELEMENT, actualInputFramesPerBuffer, sizeof(*actualInputFramesPerBuffer) ) ); /* Don't know why this causes problems ERR_WRAP( AudioUnitGetProperty( *audioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, //Output, INPUT_ELEMENT, actualInputFramesPerBuffer, &size ) ); */ } /* -- if we have input, we may need to setup an SR converter -- */ /* even if we got the sample rate we asked for, we need to do the conversion in case another program changes the underlying SR. */ /* FIXME: I think we need to monitor stream and change the converter if the incoming format changes. */ if( inStreamParams ) { AudioStreamBasicDescription desiredFormat; AudioStreamBasicDescription sourceFormat; UInt32 sourceSize = sizeof( sourceFormat ); bzero( &desiredFormat, sizeof(desiredFormat) ); desiredFormat.mSampleRate = sampleRate; desiredFormat.mFormatID = kAudioFormatLinearPCM ; desiredFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked; desiredFormat.mFramesPerPacket = 1; desiredFormat.mBitsPerChannel = sizeof( float ) * 8; desiredFormat.mBytesPerPacket=sizeof(float)*inStreamParams->channelCount; desiredFormat.mBytesPerFrame =sizeof(float)*inStreamParams->channelCount; desiredFormat.mChannelsPerFrame = inStreamParams->channelCount; /* get the source format */ ERR_WRAP( AudioUnitGetProperty( *audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, INPUT_ELEMENT, &sourceFormat, &sourceSize ) ); if( desiredFormat.mSampleRate != sourceFormat.mSampleRate ) { UInt32 value = kAudioConverterQuality_Max; switch( macInputStreamFlags & 0x0700 ) { case 0x0100: /*paMacCore_ConversionQualityMin:*/ value=kAudioConverterQuality_Min; break; case 0x0200: /*paMacCore_ConversionQualityLow:*/ value=kAudioConverterQuality_Low; break; case 0x0300: /*paMacCore_ConversionQualityMedium:*/ value=kAudioConverterQuality_Medium; break; case 0x0400: /*paMacCore_ConversionQualityHigh:*/ value=kAudioConverterQuality_High; break; } VDBUG(( "Creating sample rate converter for input" " to convert from %g to %g\n", (float)sourceFormat.mSampleRate, (float)desiredFormat.mSampleRate ) ); /* create our converter */ ERR_WRAP( AudioConverterNew( &sourceFormat, &desiredFormat, srConverter ) ); /* Set quality */ ERR_WRAP( AudioConverterSetProperty( *srConverter, kAudioConverterSampleRateConverterQuality, sizeof( value ), &value ) ); } } /* -- set IOProc (callback) -- */ callbackKey = outStreamParams ? kAudioUnitProperty_SetRenderCallback : kAudioOutputUnitProperty_SetInputCallback ; rcbs.inputProc = AudioIOProc; rcbs.inputProcRefCon = refCon; ERR_WRAP( AudioUnitSetProperty( *audioUnit, callbackKey, kAudioUnitScope_Output, outStreamParams ? OUTPUT_ELEMENT : INPUT_ELEMENT, &rcbs, sizeof(rcbs)) ); if( inStreamParams && outStreamParams && *srConverter ) ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Output, INPUT_ELEMENT, &rcbs, sizeof(rcbs)) ); /* channel mapping. */ if(inChannelMap) { UInt32 mapSize = inChannelMapSize *sizeof(SInt32); //for each channel of desired input, map the channel from //the device's output channel. ERR_WRAP( AudioUnitSetProperty(*audioUnit, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, INPUT_ELEMENT, inChannelMap, mapSize)); } if(outChannelMap) { UInt32 mapSize = outChannelMapSize *sizeof(SInt32); //for each channel of desired output, map the channel from //the device's output channel. ERR_WRAP(AudioUnitSetProperty(*audioUnit, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, OUTPUT_ELEMENT, outChannelMap, mapSize)); } /* initialize the audio unit */ ERR_WRAP( AudioUnitInitialize(*audioUnit) ); if( inStreamParams && outStreamParams ) { VDBUG( ("Opened device %ld for input and output.\n", *audioDevice ) ); } else if( inStreamParams ) { VDBUG( ("Opened device %ld for input.\n", *audioDevice ) ); } else if( outStreamParams ) { VDBUG( ("Opened device %ld for output.\n", *audioDevice ) ); } return paNoError; #undef ERR_WRAP error: CloseComponent( *audioUnit ); *audioUnit = NULL; if( result ) return PaMacCore_SetError( result, line, 1 ); return paResult; } /* =================================================================================================== */ static UInt32 CalculateOptimalBufferSize( PaMacAUHAL *auhalHostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, UInt32 fixedInputLatency, UInt32 fixedOutputLatency, double sampleRate, UInt32 requestedFramesPerBuffer ) { UInt32 resultBufferSizeFrames = 0; // Use maximum of suggested input and output latencies. if( inputParameters ) { UInt32 suggestedLatencyFrames = inputParameters->suggestedLatency * sampleRate; // Calculate a buffer size assuming we are double buffered. SInt32 variableLatencyFrames = suggestedLatencyFrames - fixedInputLatency; // Prevent negative latency. variableLatencyFrames = MAX( variableLatencyFrames, 0 ); resultBufferSizeFrames = MAX( resultBufferSizeFrames, (UInt32) variableLatencyFrames ); } if( outputParameters ) { UInt32 suggestedLatencyFrames = outputParameters->suggestedLatency * sampleRate; SInt32 variableLatencyFrames = suggestedLatencyFrames - fixedOutputLatency; variableLatencyFrames = MAX( variableLatencyFrames, 0 ); resultBufferSizeFrames = MAX( resultBufferSizeFrames, (UInt32) variableLatencyFrames ); } // can't have zero frames. code to round up to next user buffer requires non-zero resultBufferSizeFrames = MAX( resultBufferSizeFrames, 1 ); if( requestedFramesPerBuffer != paFramesPerBufferUnspecified ) { // make host buffer the next highest integer multiple of user frames per buffer UInt32 n = (resultBufferSizeFrames + requestedFramesPerBuffer - 1) / requestedFramesPerBuffer; resultBufferSizeFrames = n * requestedFramesPerBuffer; // FIXME: really we should be searching for a multiple of requestedFramesPerBuffer // that is >= suggested latency and also fits within device buffer min/max }else{ VDBUG( ("Block Size unspecified. Based on Latency, the user wants a Block Size near: %ld.\n", resultBufferSizeFrames ) ); } // Clip to the capabilities of the device. if( inputParameters ) { ClipToDeviceBufferSize( auhalHostApi->devIds[inputParameters->device], true, // In the old code isInput was false! resultBufferSizeFrames, &resultBufferSizeFrames ); } if( outputParameters ) { ClipToDeviceBufferSize( auhalHostApi->devIds[outputParameters->device], false, resultBufferSizeFrames, &resultBufferSizeFrames ); } VDBUG(("After querying hardware, setting block size to %ld.\n", resultBufferSizeFrames)); return resultBufferSizeFrames; } /* =================================================================================================== */ /* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long requestedFramesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ) { PaError result = paNoError; PaMacAUHAL *auhalHostApi = (PaMacAUHAL*)hostApi; PaMacCoreStream *stream = 0; int inputChannelCount, outputChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat; UInt32 fixedInputLatency = 0; UInt32 fixedOutputLatency = 0; // Accumulate contributions to latency in these variables. UInt32 inputLatencyFrames = 0; UInt32 outputLatencyFrames = 0; UInt32 suggestedLatencyFramesPerBuffer = requestedFramesPerBuffer; VVDBUG(("OpenStream(): in chan=%d, in fmt=%ld, out chan=%d, out fmt=%ld SR=%g, FPB=%ld\n", inputParameters ? inputParameters->channelCount : -1, inputParameters ? inputParameters->sampleFormat : -1, outputParameters ? outputParameters->channelCount : -1, outputParameters ? outputParameters->sampleFormat : -1, (float) sampleRate, requestedFramesPerBuffer )); VDBUG( ("Opening Stream.\n") ); /* These first few bits of code are from paSkeleton with few modifications. */ if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* @todo Blocking read/write on Mac is not yet supported. */ if( !streamCallback && inputSampleFormat & paNonInterleaved ) { return paSampleFormatNotSupported; } /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that input device can support inputChannelCount */ if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) return paInvalidChannelCount; /* Host supports interleaved float32 */ hostInputSampleFormat = paFloat32; } else { inputChannelCount = 0; inputSampleFormat = hostInputSampleFormat = paFloat32; /* Surpress 'uninitialised var' warnings. */ } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* @todo Blocking read/write on Mac is not yet supported. */ if( !streamCallback && outputSampleFormat & paNonInterleaved ) { return paSampleFormatNotSupported; } /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that output device can support inputChannelCount */ if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) return paInvalidChannelCount; /* Host supports interleaved float32 */ hostOutputSampleFormat = paFloat32; } else { outputChannelCount = 0; outputSampleFormat = hostOutputSampleFormat = paFloat32; /* Surpress 'uninitialized var' warnings. */ } /* validate platform specific flags */ if( (streamFlags & paPlatformSpecificFlags) != 0 ) return paInvalidFlag; /* unexpected platform specific flag */ stream = (PaMacCoreStream*)PaUtil_AllocateMemory( sizeof(PaMacCoreStream) ); if( !stream ) { result = paInsufficientMemory; goto error; } /* If we fail after this point, we my be left in a bad state, with some data structures setup and others not. So, first thing we do is initialize everything so that if we fail, we know what hasn't been touched. */ bzero( stream, sizeof( PaMacCoreStream ) ); /* stream->blio.inputRingBuffer.buffer = NULL; stream->blio.outputRingBuffer.buffer = NULL; stream->blio.inputSampleFormat = inputParameters?inputParameters->sampleFormat:0; stream->blio.inputSampleSize = computeSampleSizeFromFormat(stream->blio.inputSampleFormat); stream->blio.outputSampleFormat=outputParameters?outputParameters->sampleFormat:0; stream->blio.outputSampleSize = computeSampleSizeFromFormat(stream->blio.outputSampleFormat); */ /* assert( streamCallback ) ; */ /* only callback mode is implemented */ if( streamCallback ) { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &auhalHostApi->callbackStreamInterface, streamCallback, userData ); } else { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &auhalHostApi->blockingStreamInterface, BlioCallback, &stream->blio ); } PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate ); if( inputParameters ) { CalculateFixedDeviceLatency( auhalHostApi->devIds[inputParameters->device], true, &fixedInputLatency ); inputLatencyFrames += fixedInputLatency; } if( outputParameters ) { CalculateFixedDeviceLatency( auhalHostApi->devIds[outputParameters->device], false, &fixedOutputLatency ); outputLatencyFrames += fixedOutputLatency; } suggestedLatencyFramesPerBuffer = CalculateOptimalBufferSize( auhalHostApi, inputParameters, outputParameters, fixedInputLatency, fixedOutputLatency, sampleRate, requestedFramesPerBuffer ); if( requestedFramesPerBuffer == paFramesPerBufferUnspecified ) { requestedFramesPerBuffer = suggestedLatencyFramesPerBuffer; } /* -- Now we actually open and setup streams. -- */ if( inputParameters && outputParameters && outputParameters->device == inputParameters->device ) { /* full duplex. One device. */ UInt32 inputFramesPerBuffer = (UInt32) stream->inputFramesPerBuffer; UInt32 outputFramesPerBuffer = (UInt32) stream->outputFramesPerBuffer; result = OpenAndSetupOneAudioUnit( stream, inputParameters, outputParameters, suggestedLatencyFramesPerBuffer, &inputFramesPerBuffer, &outputFramesPerBuffer, auhalHostApi, &(stream->inputUnit), &(stream->inputSRConverter), &(stream->inputDevice), sampleRate, stream ); stream->inputFramesPerBuffer = inputFramesPerBuffer; stream->outputFramesPerBuffer = outputFramesPerBuffer; stream->outputUnit = stream->inputUnit; stream->outputDevice = stream->inputDevice; if( result != paNoError ) goto error; } else { /* full duplex, different devices OR simplex */ UInt32 outputFramesPerBuffer = (UInt32) stream->outputFramesPerBuffer; UInt32 inputFramesPerBuffer = (UInt32) stream->inputFramesPerBuffer; result = OpenAndSetupOneAudioUnit( stream, NULL, outputParameters, suggestedLatencyFramesPerBuffer, NULL, &outputFramesPerBuffer, auhalHostApi, &(stream->outputUnit), NULL, &(stream->outputDevice), sampleRate, stream ); if( result != paNoError ) goto error; result = OpenAndSetupOneAudioUnit( stream, inputParameters, NULL, suggestedLatencyFramesPerBuffer, &inputFramesPerBuffer, NULL, auhalHostApi, &(stream->inputUnit), &(stream->inputSRConverter), &(stream->inputDevice), sampleRate, stream ); if( result != paNoError ) goto error; stream->inputFramesPerBuffer = inputFramesPerBuffer; stream->outputFramesPerBuffer = outputFramesPerBuffer; } inputLatencyFrames += stream->inputFramesPerBuffer; outputLatencyFrames += stream->outputFramesPerBuffer; if( stream->inputUnit ) { const size_t szfl = sizeof(float); /* setup the AudioBufferList used for input */ bzero( &stream->inputAudioBufferList, sizeof( AudioBufferList ) ); stream->inputAudioBufferList.mNumberBuffers = 1; stream->inputAudioBufferList.mBuffers[0].mNumberChannels = inputChannelCount; stream->inputAudioBufferList.mBuffers[0].mDataByteSize = stream->inputFramesPerBuffer*inputChannelCount*szfl; stream->inputAudioBufferList.mBuffers[0].mData = (float *) calloc( stream->inputFramesPerBuffer*inputChannelCount, szfl ); if( !stream->inputAudioBufferList.mBuffers[0].mData ) { result = paInsufficientMemory; goto error; } /* * If input and output devs are different or we are doing SR conversion, * we also need a * ring buffer to store inpt data while waiting for output * data. */ if( (stream->outputUnit && (stream->inputUnit != stream->outputUnit)) || stream->inputSRConverter ) { /* May want the ringSize ot initial position in ring buffer to depend somewhat on sample rate change */ void *data; long ringSize; ringSize = computeRingBufferSize( inputParameters, outputParameters, stream->inputFramesPerBuffer, stream->outputFramesPerBuffer, sampleRate ); /*ringSize <<= 4; *//*16x bigger, for testing */ /*now, we need to allocate memory for the ring buffer*/ data = calloc( ringSize, szfl*inputParameters->channelCount ); if( !data ) { result = paInsufficientMemory; goto error; } /* now we can initialize the ring buffer */ PaUtil_InitializeRingBuffer( &stream->inputRingBuffer, szfl*inputParameters->channelCount, ringSize, data ) ; /* advance the read point a little, so we are reading from the middle of the buffer */ if( stream->outputUnit ) PaUtil_AdvanceRingBufferWriteIndex( &stream->inputRingBuffer, ringSize / RING_BUFFER_ADVANCE_DENOMINATOR ); // Just adds to input latency between input device and PA full duplex callback. inputLatencyFrames += ringSize; } } /* -- initialize Blio Buffer Processors -- */ if( !streamCallback ) { long ringSize; ringSize = computeRingBufferSize( inputParameters, outputParameters, stream->inputFramesPerBuffer, stream->outputFramesPerBuffer, sampleRate ); result = initializeBlioRingBuffers( &stream->blio, inputParameters?inputParameters->sampleFormat:0 , outputParameters?outputParameters->sampleFormat:0 , MAX(stream->inputFramesPerBuffer,stream->outputFramesPerBuffer), ringSize, inputParameters?inputChannelCount:0 , outputParameters?outputChannelCount:0 ) ; if( result != paNoError ) goto error; inputLatencyFrames += ringSize; outputLatencyFrames += ringSize; } /* -- initialize Buffer Processor -- */ { unsigned long maxHostFrames = stream->inputFramesPerBuffer; if( stream->outputFramesPerBuffer > maxHostFrames ) maxHostFrames = stream->outputFramesPerBuffer; result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, inputChannelCount, inputSampleFormat, hostInputSampleFormat, outputChannelCount, outputSampleFormat, hostOutputSampleFormat, sampleRate, streamFlags, requestedFramesPerBuffer, /* If sample rate conversion takes place, the buffer size will not be known. */ maxHostFrames, stream->inputSRConverter ? paUtilUnknownHostBufferSize : paUtilBoundedHostBufferSize, streamCallback ? streamCallback : BlioCallback, streamCallback ? userData : &stream->blio ); if( result != paNoError ) goto error; } stream->bufferProcessorIsInitialized = TRUE; // Calculate actual latency from the sum of individual latencies. if( inputParameters ) { inputLatencyFrames += PaUtil_GetBufferProcessorInputLatencyFrames(&stream->bufferProcessor); stream->streamRepresentation.streamInfo.inputLatency = inputLatencyFrames / sampleRate; } else { stream->streamRepresentation.streamInfo.inputLatency = 0.0; } if( outputParameters ) { outputLatencyFrames += PaUtil_GetBufferProcessorOutputLatencyFrames(&stream->bufferProcessor); stream->streamRepresentation.streamInfo.outputLatency = outputLatencyFrames / sampleRate; } else { stream->streamRepresentation.streamInfo.outputLatency = 0.0; } stream->streamRepresentation.streamInfo.sampleRate = sampleRate; stream->sampleRate = sampleRate; stream->userInChan = inputChannelCount; stream->userOutChan = outputChannelCount; // Setup property listeners for timestamp and latency calculations. pthread_mutex_init( &stream->timingInformationMutex, NULL ); stream->timingInformationMutexIsInitialized = 1; InitializeDeviceProperties( &stream->inputProperties ); // zeros the struct. doesn't actually init it to useful values InitializeDeviceProperties( &stream->outputProperties ); // zeros the struct. doesn't actually init it to useful values if( stream->outputUnit ) { Boolean isInput = FALSE; // Start with the current values for the device properties. // Init with nominal sample rate. Use actual sample rate where available result = ERR( UpdateSampleRateFromDeviceProperty( stream, stream->outputDevice, isInput, kAudioDevicePropertyNominalSampleRate ) ); if( result ) goto error; /* fail if we can't even get a nominal device sample rate */ UpdateSampleRateFromDeviceProperty( stream, stream->outputDevice, isInput, kAudioDevicePropertyActualSampleRate ); SetupDevicePropertyListeners( stream, stream->outputDevice, isInput ); } if( stream->inputUnit ) { Boolean isInput = TRUE; // as above result = ERR( UpdateSampleRateFromDeviceProperty( stream, stream->inputDevice, isInput, kAudioDevicePropertyNominalSampleRate ) ); if( result ) goto error; UpdateSampleRateFromDeviceProperty( stream, stream->inputDevice, isInput, kAudioDevicePropertyActualSampleRate ); SetupDevicePropertyListeners( stream, stream->inputDevice, isInput ); } UpdateTimeStampOffsets( stream ); // Setup timestamp copies to be used by audio callback. stream->timestampOffsetCombined_ioProcCopy = stream->timestampOffsetCombined; stream->timestampOffsetInputDevice_ioProcCopy = stream->timestampOffsetInputDevice; stream->timestampOffsetOutputDevice_ioProcCopy = stream->timestampOffsetOutputDevice; stream->state = STOPPED; stream->xrunFlags = 0; *s = (PaStream*)stream; return result; error: CloseStream( stream ); return result; } #define HOST_TIME_TO_PA_TIME( x ) ( AudioConvertHostTimeToNanos( (x) ) * 1.0E-09) /* convert to nanoseconds and then to seconds */ PaTime GetStreamTime( PaStream *s ) { return HOST_TIME_TO_PA_TIME( AudioGetCurrentHostTime() ); } #define RING_BUFFER_EMPTY (1000) static OSStatus ringBufferIOProc( AudioConverterRef inAudioConverter, UInt32*ioDataSize, void** outData, void*inUserData ) { void *dummyData; ring_buffer_size_t dummySize; PaUtilRingBuffer *rb = (PaUtilRingBuffer *) inUserData; VVDBUG(("ringBufferIOProc()\n")); if( PaUtil_GetRingBufferReadAvailable( rb ) == 0 ) { *outData = NULL; *ioDataSize = 0; return RING_BUFFER_EMPTY; } assert(sizeof(UInt32) == sizeof(ring_buffer_size_t)); assert( ( (*ioDataSize) / rb->elementSizeBytes ) * rb->elementSizeBytes == (*ioDataSize) ) ; (*ioDataSize) /= rb->elementSizeBytes ; PaUtil_GetRingBufferReadRegions( rb, *ioDataSize, outData, (ring_buffer_size_t *)ioDataSize, &dummyData, &dummySize ); assert( *ioDataSize ); PaUtil_AdvanceRingBufferReadIndex( rb, *ioDataSize ); (*ioDataSize) *= rb->elementSizeBytes ; return noErr; } /* * Called by the AudioUnit API to process audio from the sound card. * This is where the magic happens. */ /* FEEDBACK: there is a lot of redundant code here because of how all the cases differ. This makes it hard to maintain, so if there are suggestinos for cleaning it up, I'm all ears. */ static OSStatus AudioIOProc( void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData ) { unsigned long framesProcessed = 0; PaStreamCallbackTimeInfo timeInfo = {0,0,0}; PaMacCoreStream *stream = (PaMacCoreStream*)inRefCon; const bool isRender = inBusNumber == OUTPUT_ELEMENT; int callbackResult = paContinue ; double hostTimeStampInPaTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime); VVDBUG(("AudioIOProc()\n")); PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); /* -----------------------------------------------------------------*\ This output may be useful for debugging, But printing durring the callback is a bad enough idea that this is not enabled by enableing the usual debugging calls. \* -----------------------------------------------------------------*/ /* static int renderCount = 0; static int inputCount = 0; printf( "------------------- starting reder/input\n" ); if( isRender ) printf("Render callback (%d):\t", ++renderCount); else printf("Input callback (%d):\t", ++inputCount); printf( "Call totals: %d (input), %d (render)\n", inputCount, renderCount ); printf( "--- inBusNumber: %lu\n", inBusNumber ); printf( "--- inNumberFrames: %lu\n", inNumberFrames ); printf( "--- %x ioData\n", (unsigned) ioData ); if( ioData ) { int i=0; printf( "--- ioData.mNumBuffers %lu: \n", ioData->mNumberBuffers ); for( i=0; imNumberBuffers; ++i ) printf( "--- ioData buffer %d size: %lu.\n", i, ioData->mBuffers[i].mDataByteSize ); } ----------------------------------------------------------------- */ /* compute PaStreamCallbackTimeInfo */ if( pthread_mutex_trylock( &stream->timingInformationMutex ) == 0 ){ /* snapshot the ioproc copy of timing information */ stream->timestampOffsetCombined_ioProcCopy = stream->timestampOffsetCombined; stream->timestampOffsetInputDevice_ioProcCopy = stream->timestampOffsetInputDevice; stream->timestampOffsetOutputDevice_ioProcCopy = stream->timestampOffsetOutputDevice; pthread_mutex_unlock( &stream->timingInformationMutex ); } /* For timeInfo.currentTime we could calculate current time backwards from the HAL audio output time to give a more accurate impression of the current timeslice but it doesn't seem worth it at the moment since other PA host APIs don't do any better. */ timeInfo.currentTime = HOST_TIME_TO_PA_TIME( AudioGetCurrentHostTime() ); /* For an input HAL AU, inTimeStamp is the time the samples are received from the hardware, for an output HAL AU inTimeStamp is the time the samples are sent to the hardware. PA expresses timestamps in terms of when the samples enter the ADC or leave the DAC so we add or subtract kAudioDevicePropertyLatency below. */ /* FIXME: not sure what to do below if the host timestamps aren't valid (kAudioTimeStampHostTimeValid isn't set) Could ask on CA mailing list if it is possible for it not to be set. If so, could probably grab a now timestamp at the top and compute from there (modulo scheduling jitter) or ask on mailing list for other options. */ if( isRender ) { if( stream->inputUnit ) /* full duplex */ { if( stream->inputUnit == stream->outputUnit ) /* full duplex AUHAL IOProc */ { // Ross and Phil agreed that the following calculation is correct based on an email from Jeff Moore: // http://osdir.com/ml/coreaudio-api/2009-07/msg00140.html // Basically the difference between the Apple output timestamp and the PA timestamp is kAudioDevicePropertyLatency. timeInfo.inputBufferAdcTime = hostTimeStampInPaTime - (stream->timestampOffsetCombined_ioProcCopy + stream->timestampOffsetInputDevice_ioProcCopy); timeInfo.outputBufferDacTime = hostTimeStampInPaTime + stream->timestampOffsetOutputDevice_ioProcCopy; } else /* full duplex with ring-buffer from a separate input AUHAL ioproc */ { /* FIXME: take the ring buffer latency into account */ timeInfo.inputBufferAdcTime = hostTimeStampInPaTime - (stream->timestampOffsetCombined_ioProcCopy + stream->timestampOffsetInputDevice_ioProcCopy); timeInfo.outputBufferDacTime = hostTimeStampInPaTime + stream->timestampOffsetOutputDevice_ioProcCopy; } } else /* output only */ { timeInfo.inputBufferAdcTime = 0; timeInfo.outputBufferDacTime = hostTimeStampInPaTime + stream->timestampOffsetOutputDevice_ioProcCopy; } } else /* input only */ { timeInfo.inputBufferAdcTime = hostTimeStampInPaTime - stream->timestampOffsetInputDevice_ioProcCopy; timeInfo.outputBufferDacTime = 0; } //printf( "---%g, %g, %g\n", timeInfo.inputBufferAdcTime, timeInfo.currentTime, timeInfo.outputBufferDacTime ); if( isRender && stream->inputUnit == stream->outputUnit && !stream->inputSRConverter ) { /* --------- Full Duplex, One Device, no SR Conversion ------- * * This is the lowest latency case, and also the simplest. * Input data and output data are available at the same time. * we do not use the input SR converter or the input ring buffer. * */ OSStatus err = 0; unsigned long frames; long bytesPerFrame = sizeof( float ) * ioData->mBuffers[0].mNumberChannels; /* -- start processing -- */ PaUtil_BeginBufferProcessing( &(stream->bufferProcessor), &timeInfo, stream->xrunFlags ); stream->xrunFlags = 0; //FIXME: this flag also gets set outside by a callback, which calls the xrunCallback function. It should be in the same thread as the main audio callback, but the apple docs just use the word "usually" so it may be possible to loose an xrun notification, if that callback happens here. /* -- compute frames. do some checks -- */ assert( ioData->mNumberBuffers == 1 ); assert( ioData->mBuffers[0].mNumberChannels == stream->userOutChan ); frames = ioData->mBuffers[0].mDataByteSize / bytesPerFrame; /* -- copy and process input data -- */ err= AudioUnitRender(stream->inputUnit, ioActionFlags, inTimeStamp, INPUT_ELEMENT, inNumberFrames, &stream->inputAudioBufferList ); /* FEEDBACK: I'm not sure what to do when this call fails. There's nothing in the PA API to * do about failures in the callback system. */ assert( !err ); PaUtil_SetInputFrameCount( &(stream->bufferProcessor), frames ); PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor), 0, stream->inputAudioBufferList.mBuffers[0].mData, stream->inputAudioBufferList.mBuffers[0].mNumberChannels); /* -- Copy and process output data -- */ PaUtil_SetOutputFrameCount( &(stream->bufferProcessor), frames ); PaUtil_SetInterleavedOutputChannels( &(stream->bufferProcessor), 0, ioData->mBuffers[0].mData, ioData->mBuffers[0].mNumberChannels); /* -- complete processing -- */ framesProcessed = PaUtil_EndBufferProcessing( &(stream->bufferProcessor), &callbackResult ); } else if( isRender ) { /* -------- Output Side of Full Duplex (Separate Devices or SR Conversion) * -- OR Simplex Output * * This case handles output data as in the full duplex case, * and, if there is input data, reads it off the ring buffer * and into the PA buffer processor. If sample rate conversion * is required on input, that is done here as well. */ unsigned long frames; long bytesPerFrame = sizeof( float ) * ioData->mBuffers[0].mNumberChannels; /* Sometimes, when stopping a duplex stream we get erroneous xrun flags, so if this is our last run, clear the flags. */ int xrunFlags = stream->xrunFlags; /* if( xrunFlags & paInputUnderflow ) printf( "input underflow.\n" ); if( xrunFlags & paInputOverflow ) printf( "input overflow.\n" ); */ if( stream->state == STOPPING || stream->state == CALLBACK_STOPPED ) xrunFlags = 0; /* -- start processing -- */ PaUtil_BeginBufferProcessing( &(stream->bufferProcessor), &timeInfo, xrunFlags ); stream->xrunFlags = 0; /* FEEDBACK: we only send flags to Buf Proc once */ /* -- Copy and process output data -- */ assert( ioData->mNumberBuffers == 1 ); frames = ioData->mBuffers[0].mDataByteSize / bytesPerFrame; assert( ioData->mBuffers[0].mNumberChannels == stream->userOutChan ); PaUtil_SetOutputFrameCount( &(stream->bufferProcessor), frames ); PaUtil_SetInterleavedOutputChannels( &(stream->bufferProcessor), 0, ioData->mBuffers[0].mData, ioData->mBuffers[0].mNumberChannels); /* -- copy and process input data, and complete processing -- */ if( stream->inputUnit ) { const int flsz = sizeof( float ); /* Here, we read the data out of the ring buffer, through the audio converter. */ int inChan = stream->inputAudioBufferList.mBuffers[0].mNumberChannels; long bytesPerFrame = flsz * inChan; if( stream->inputSRConverter ) { OSStatus err; UInt32 size; float data[ inChan * frames ]; size = sizeof( data ); err = AudioConverterFillBuffer( stream->inputSRConverter, ringBufferIOProc, &stream->inputRingBuffer, &size, (void *)&data ); if( err == RING_BUFFER_EMPTY ) { /*the ring buffer callback underflowed */ err = 0; bzero( ((char *)data) + size, sizeof(data)-size ); /* The ring buffer can underflow normally when the stream is stopping. * So only report an error if the stream is active. */ if( stream->state == ACTIVE ) { stream->xrunFlags |= paInputUnderflow; } } ERR( err ); assert( !err ); PaUtil_SetInputFrameCount( &(stream->bufferProcessor), frames ); PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor), 0, data, inChan ); framesProcessed = PaUtil_EndBufferProcessing( &(stream->bufferProcessor), &callbackResult ); } else { /* Without the AudioConverter is actually a bit more complex because we have to do a little buffer processing that the AudioConverter would otherwise handle for us. */ void *data1, *data2; ring_buffer_size_t size1, size2; ring_buffer_size_t framesReadable = PaUtil_GetRingBufferReadRegions( &stream->inputRingBuffer, frames, &data1, &size1, &data2, &size2 ); if( size1 == frames ) { /* simplest case: all in first buffer */ PaUtil_SetInputFrameCount( &(stream->bufferProcessor), frames ); PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor), 0, data1, inChan ); framesProcessed = PaUtil_EndBufferProcessing( &(stream->bufferProcessor), &callbackResult ); PaUtil_AdvanceRingBufferReadIndex(&stream->inputRingBuffer, size1 ); } else if( framesReadable < frames ) { long sizeBytes1 = size1 * bytesPerFrame; long sizeBytes2 = size2 * bytesPerFrame; /*we underflowed. take what data we can, zero the rest.*/ unsigned char data[ frames * bytesPerFrame ]; if( size1 > 0 ) { memcpy( data, data1, sizeBytes1 ); } if( size2 > 0 ) { memcpy( data+sizeBytes1, data2, sizeBytes2 ); } bzero( data+sizeBytes1+sizeBytes2, (frames*bytesPerFrame) - sizeBytes1 - sizeBytes2 ); PaUtil_SetInputFrameCount( &(stream->bufferProcessor), frames ); PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor), 0, data, inChan ); framesProcessed = PaUtil_EndBufferProcessing( &(stream->bufferProcessor), &callbackResult ); PaUtil_AdvanceRingBufferReadIndex( &stream->inputRingBuffer, framesReadable ); /* flag underflow */ stream->xrunFlags |= paInputUnderflow; } else { /*we got all the data, but split between buffers*/ PaUtil_SetInputFrameCount( &(stream->bufferProcessor), size1 ); PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor), 0, data1, inChan ); PaUtil_Set2ndInputFrameCount( &(stream->bufferProcessor), size2 ); PaUtil_Set2ndInterleavedInputChannels( &(stream->bufferProcessor), 0, data2, inChan ); framesProcessed = PaUtil_EndBufferProcessing( &(stream->bufferProcessor), &callbackResult ); PaUtil_AdvanceRingBufferReadIndex(&stream->inputRingBuffer, framesReadable ); } } } else { framesProcessed = PaUtil_EndBufferProcessing( &(stream->bufferProcessor), &callbackResult ); } } else { /* ------------------ Input * * First, we read off the audio data and put it in the ring buffer. * if this is an input-only stream, we need to process it more, * otherwise, we let the output case deal with it. */ OSStatus err = 0; int chan = stream->inputAudioBufferList.mBuffers[0].mNumberChannels ; /* FIXME: looping here may not actually be necessary, but it was something I tried in testing. */ do { err= AudioUnitRender(stream->inputUnit, ioActionFlags, inTimeStamp, INPUT_ELEMENT, inNumberFrames, &stream->inputAudioBufferList ); if( err == -10874 ) inNumberFrames /= 2; } while( err == -10874 && inNumberFrames > 1 ); /* FEEDBACK: I'm not sure what to do when this call fails */ ERR( err ); assert( !err ); if( stream->inputSRConverter || stream->outputUnit ) { /* If this is duplex or we use a converter, put the data into the ring buffer. */ ring_buffer_size_t framesWritten = PaUtil_WriteRingBuffer( &stream->inputRingBuffer, stream->inputAudioBufferList.mBuffers[0].mData, inNumberFrames ); if( framesWritten != inNumberFrames ) { stream->xrunFlags |= paInputOverflow ; } } else { /* for simplex input w/o SR conversion, just pop the data into the buffer processor.*/ PaUtil_BeginBufferProcessing( &(stream->bufferProcessor), &timeInfo, stream->xrunFlags ); stream->xrunFlags = 0; PaUtil_SetInputFrameCount( &(stream->bufferProcessor), inNumberFrames); PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor), 0, stream->inputAudioBufferList.mBuffers[0].mData, chan ); framesProcessed = PaUtil_EndBufferProcessing( &(stream->bufferProcessor), &callbackResult ); } if( !stream->outputUnit && stream->inputSRConverter ) { /* ------------------ Simplex Input w/ SR Conversion * * if this is a simplex input stream, we need to read off the buffer, * do our sample rate conversion and pass the results to the buffer * processor. * The logic here is complicated somewhat by the fact that we don't * know how much data is available, so we loop on reasonably sized * chunks, and let the BufferProcessor deal with the rest. * */ /*This might be too big or small depending on SR conversion*/ float data[ chan * inNumberFrames ]; OSStatus err; do { /*Run the buffer processor until we are out of data*/ UInt32 size; long f; size = sizeof( data ); err = AudioConverterFillBuffer( stream->inputSRConverter, ringBufferIOProc, &stream->inputRingBuffer, &size, (void *)data ); if( err != RING_BUFFER_EMPTY ) ERR( err ); assert( err == 0 || err == RING_BUFFER_EMPTY ); f = size / ( chan * sizeof(float) ); PaUtil_SetInputFrameCount( &(stream->bufferProcessor), f ); if( f ) { PaUtil_BeginBufferProcessing( &(stream->bufferProcessor), &timeInfo, stream->xrunFlags ); stream->xrunFlags = 0; PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor), 0, data, chan ); framesProcessed = PaUtil_EndBufferProcessing( &(stream->bufferProcessor), &callbackResult ); } } while( callbackResult == paContinue && !err ); } } switch( callbackResult ) { case paContinue: break; case paComplete: case paAbort: stream->state = CALLBACK_STOPPED ; if( stream->outputUnit ) AudioOutputUnitStop(stream->outputUnit); if( stream->inputUnit ) AudioOutputUnitStop(stream->inputUnit); break; } PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed ); return noErr; } /* When CloseStream() is called, the multi-api layer ensures that the stream has already been stopped or aborted. */ static PaError CloseStream( PaStream* s ) { /* This may be called from a failed OpenStream. Therefore, each piece of info is treated seperately. */ PaError result = paNoError; PaMacCoreStream *stream = (PaMacCoreStream*)s; VVDBUG(("CloseStream()\n")); VDBUG( ( "Closing stream.\n" ) ); if( stream ) { if( stream->outputUnit ) { Boolean isInput = FALSE; CleanupDevicePropertyListeners( stream, stream->outputDevice, isInput ); } if( stream->inputUnit ) { Boolean isInput = TRUE; CleanupDevicePropertyListeners( stream, stream->inputDevice, isInput ); } if( stream->outputUnit ) { int count = removeFromXRunListenerList( stream ); if( count == 0 ) AudioDeviceRemovePropertyListener( stream->outputDevice, 0, false, kAudioDeviceProcessorOverload, xrunCallback ); } if( stream->inputUnit && stream->outputUnit != stream->inputUnit ) { int count = removeFromXRunListenerList( stream ); if( count == 0 ) AudioDeviceRemovePropertyListener( stream->inputDevice, 0, true, kAudioDeviceProcessorOverload, xrunCallback ); } if( stream->outputUnit && stream->outputUnit != stream->inputUnit ) { AudioUnitUninitialize( stream->outputUnit ); CloseComponent( stream->outputUnit ); } stream->outputUnit = NULL; if( stream->inputUnit ) { AudioUnitUninitialize( stream->inputUnit ); CloseComponent( stream->inputUnit ); stream->inputUnit = NULL; } if( stream->inputRingBuffer.buffer ) free( (void *) stream->inputRingBuffer.buffer ); stream->inputRingBuffer.buffer = NULL; /*TODO: is there more that needs to be done on error from AudioConverterDispose?*/ if( stream->inputSRConverter ) ERR( AudioConverterDispose( stream->inputSRConverter ) ); stream->inputSRConverter = NULL; if( stream->inputAudioBufferList.mBuffers[0].mData ) free( stream->inputAudioBufferList.mBuffers[0].mData ); stream->inputAudioBufferList.mBuffers[0].mData = NULL; result = destroyBlioRingBuffers( &stream->blio ); if( result ) return result; if( stream->bufferProcessorIsInitialized ) PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); if( stream->timingInformationMutexIsInitialized ) pthread_mutex_destroy( &stream->timingInformationMutex ); PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); PaUtil_FreeMemory( stream ); } return result; } static PaError StartStream( PaStream *s ) { PaMacCoreStream *stream = (PaMacCoreStream*)s; OSStatus result = noErr; VVDBUG(("StartStream()\n")); VDBUG( ( "Starting stream.\n" ) ); #define ERR_WRAP(mac_err) do { result = mac_err ; if ( result != noErr ) return ERR(result) ; } while(0) /*FIXME: maybe want to do this on close/abort for faster start? */ PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); if( stream->inputSRConverter ) ERR_WRAP( AudioConverterReset( stream->inputSRConverter ) ); /* -- start -- */ stream->state = ACTIVE; if( stream->inputUnit ) { ERR_WRAP( AudioOutputUnitStart(stream->inputUnit) ); } if( stream->outputUnit && stream->outputUnit != stream->inputUnit ) { ERR_WRAP( AudioOutputUnitStart(stream->outputUnit) ); } return paNoError; #undef ERR_WRAP } // it's not clear from appl's docs that this really waits // until all data is flushed. static ComponentResult BlockWhileAudioUnitIsRunning( AudioUnit audioUnit, AudioUnitElement element ) { Boolean isRunning = 1; while( isRunning ) { UInt32 s = sizeof( isRunning ); ComponentResult err = AudioUnitGetProperty( audioUnit, kAudioOutputUnitProperty_IsRunning, kAudioUnitScope_Global, element, &isRunning, &s ); if( err ) return err; Pa_Sleep( 100 ); } return noErr; } static PaError StopStream( PaStream *s ) { PaMacCoreStream *stream = (PaMacCoreStream*)s; OSStatus result = noErr; PaError paErr; VVDBUG(("StopStream()\n")); VDBUG( ("Waiting for BLIO.\n") ); waitUntilBlioWriteBufferIsFlushed( &stream->blio ); VDBUG( ( "Stopping stream.\n" ) ); stream->state = STOPPING; #define ERR_WRAP(mac_err) do { result = mac_err ; if ( result != noErr ) return ERR(result) ; } while(0) /* -- stop and reset -- */ if( stream->inputUnit == stream->outputUnit && stream->inputUnit ) { ERR_WRAP( AudioOutputUnitStop(stream->inputUnit) ); ERR_WRAP( BlockWhileAudioUnitIsRunning(stream->inputUnit,0) ); ERR_WRAP( BlockWhileAudioUnitIsRunning(stream->inputUnit,1) ); ERR_WRAP( AudioUnitReset(stream->inputUnit, kAudioUnitScope_Global, 1) ); ERR_WRAP( AudioUnitReset(stream->inputUnit, kAudioUnitScope_Global, 0) ); } else { if( stream->inputUnit ) { ERR_WRAP(AudioOutputUnitStop(stream->inputUnit) ); ERR_WRAP( BlockWhileAudioUnitIsRunning(stream->inputUnit,1) ); ERR_WRAP(AudioUnitReset(stream->inputUnit,kAudioUnitScope_Global,1)); } if( stream->outputUnit ) { ERR_WRAP(AudioOutputUnitStop(stream->outputUnit)); ERR_WRAP( BlockWhileAudioUnitIsRunning(stream->outputUnit,0) ); ERR_WRAP(AudioUnitReset(stream->outputUnit,kAudioUnitScope_Global,0)); } } if( stream->inputRingBuffer.buffer ) { PaUtil_FlushRingBuffer( &stream->inputRingBuffer ); bzero( (void *)stream->inputRingBuffer.buffer, stream->inputRingBuffer.bufferSize ); /* advance the write point a little, so we are reading from the middle of the buffer. We'll need extra at the end because testing has shown that this helps. */ if( stream->outputUnit ) PaUtil_AdvanceRingBufferWriteIndex( &stream->inputRingBuffer, stream->inputRingBuffer.bufferSize / RING_BUFFER_ADVANCE_DENOMINATOR ); } stream->xrunFlags = 0; stream->state = STOPPED; paErr = resetBlioRingBuffers( &stream->blio ); if( paErr ) return paErr; VDBUG( ( "Stream Stopped.\n" ) ); return paNoError; #undef ERR_WRAP } static PaError AbortStream( PaStream *s ) { VVDBUG(("AbortStream()->StopStream()\n")); VDBUG( ( "Aborting stream.\n" ) ); /* We have nothing faster than StopStream. */ return StopStream(s); } static PaError IsStreamStopped( PaStream *s ) { PaMacCoreStream *stream = (PaMacCoreStream*)s; VVDBUG(("IsStreamStopped()\n")); return stream->state == STOPPED ? 1 : 0; } static PaError IsStreamActive( PaStream *s ) { PaMacCoreStream *stream = (PaMacCoreStream*)s; VVDBUG(("IsStreamActive()\n")); return ( stream->state == ACTIVE || stream->state == STOPPING ); } static double GetStreamCpuLoad( PaStream* s ) { PaMacCoreStream *stream = (PaMacCoreStream*)s; VVDBUG(("GetStreamCpuLoad()\n")); return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); } praat-6.0.04/external/portaudio/pa_mac_core.h000066400000000000000000000165771261542461700211710ustar00rootroot00000000000000#ifndef PA_MAC_CORE_H #define PA_MAC_CORE_H /* * PortAudio Portable Real-Time Audio Library * Macintosh Core Audio specific extensions * portaudio.h should be included before this file. * * Copyright (c) 2005-2006 Bjorn Roche * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file * @ingroup public_header * @brief CoreAudio-specific PortAudio API extension header file. */ #include "portaudio.h" #include #include #ifdef __cplusplus extern "C" { #endif /** * A pointer to a paMacCoreStreamInfo may be passed as * the hostApiSpecificStreamInfo in the PaStreamParameters struct * when opening a stream or querying the format. Use NULL, for the * defaults. Note that for duplex streams, flags for input and output * should be the same or behaviour is undefined. */ typedef struct { unsigned long size; /**size of whole structure including this header */ PaHostApiTypeId hostApiType; /**host API for which this data is intended */ unsigned long version; /**structure version */ unsigned long flags; /** flags to modify behaviour */ SInt32 const * channelMap; /** Channel map for HAL channel mapping , if not needed, use NULL;*/ unsigned long channelMapSize; /** Channel map size for HAL channel mapping , if not needed, use 0;*/ } PaMacCoreStreamInfo; /** * Functions */ /** Use this function to initialize a paMacCoreStreamInfo struct * using the requested flags. Note that channel mapping is turned * off after a call to this function. * @param data The datastructure to initialize * @param flags The flags to initialize the datastructure with. */ void PaMacCore_SetupStreamInfo( PaMacCoreStreamInfo *data, unsigned long flags ); /** call this after pa_SetupMacCoreStreamInfo to use channel mapping as described in notes.txt. * @param data The stream info structure to assign a channel mapping to * @param channelMap The channel map array, as described in notes.txt. This array pointer will be used directly (ie the underlying data will not be copied), so the caller should not free the array until after the stream has been opened. * @param channelMapSize The size of the channel map array. */ void PaMacCore_SetupChannelMap( PaMacCoreStreamInfo *data, const SInt32 * const channelMap, unsigned long channelMapSize ); /** * Retrieve the AudioDeviceID of the input device assigned to an open stream * * @param s The stream to query. * * @return A valid AudioDeviceID, or NULL if an error occurred. */ AudioDeviceID PaMacCore_GetStreamInputDevice( PaStream* s ); /** * Retrieve the AudioDeviceID of the output device assigned to an open stream * * @param s The stream to query. * * @return A valid AudioDeviceID, or NULL if an error occurred. */ AudioDeviceID PaMacCore_GetStreamOutputDevice( PaStream* s ); /** * Returns a statically allocated string with the device's name * for the given channel. NULL will be returned on failure. * * This function's implemenation is not complete! * * @param device The PortAudio device index. * @param channel The channel number who's name is requested. * @return a statically allocated string with the name of the device. * Because this string is statically allocated, it must be * coppied if it is to be saved and used by the user after * another call to this function. * */ const char *PaMacCore_GetChannelName( int device, int channelIndex, bool input ); /** Retrieve the range of legal native buffer sizes for the specificed device, in sample frames. @param device The global index of the PortAudio device about which the query is being made. @param minBufferSizeFrames A pointer to the location which will receive the minimum buffer size value. @param maxBufferSizeFrames A pointer to the location which will receive the maximum buffer size value. @see kAudioDevicePropertyBufferFrameSizeRange in the CoreAudio SDK. */ PaError PaMacCore_GetBufferSizeRange( PaDeviceIndex device, long *minBufferSizeFrames, long *maxBufferSizeFrames ); /** * Flags */ /** * The following flags alter the behaviour of PA on the mac platform. * they can be ORed together. These should work both for opening and * checking a device. */ /** Allows PortAudio to change things like the device's frame size, * which allows for much lower latency, but might disrupt the device * if other programs are using it, even when you are just Querying * the device. */ #define paMacCoreChangeDeviceParameters (0x01) /** In combination with the above flag, * causes the stream opening to fail, unless the exact sample rates * are supported by the device. */ #define paMacCoreFailIfConversionRequired (0x02) /** These flags set the SR conversion quality, if required. The wierd ordering * allows Maximum Quality to be the default.*/ #define paMacCoreConversionQualityMin (0x0100) #define paMacCoreConversionQualityMedium (0x0200) #define paMacCoreConversionQualityLow (0x0300) #define paMacCoreConversionQualityHigh (0x0400) #define paMacCoreConversionQualityMax (0x0000) /** * Here are some "preset" combinations of flags (above) to get to some * common configurations. THIS IS OVERKILL, but if more flags are added * it won't be. */ /**This is the default setting: do as much sample rate conversion as possible * and as little mucking with the device as possible. */ #define paMacCorePlayNice (0x00) /**This setting is tuned for pro audio apps. It allows SR conversion on input and output, but it tries to set the appropriate SR on the device.*/ #define paMacCorePro (0x01) /**This is a setting to minimize CPU usage and still play nice.*/ #define paMacCoreMinimizeCPUButPlayNice (0x0100) /**This is a setting to minimize CPU usage, even if that means interrupting the device. */ #define paMacCoreMinimizeCPU (0x0101) #ifdef __cplusplus } #endif /** __cplusplus */ #endif /** PA_MAC_CORE_H */ praat-6.0.04/external/portaudio/pa_mac_core_blocking.c000066400000000000000000000470211261542461700230200ustar00rootroot00000000000000/* * Implementation of the PortAudio API for Apple AUHAL * * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * * Written by Bjorn Roche of XO Audio LLC, from PA skeleton code. * Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation) * * Dominic's code was based on code by Phil Burk, Darren Gibbs, * Gord Peters, Stephane Letz, and Greg Pfiel. * * The following people also deserve acknowledgements: * * Olivier Tristan for feedback and testing * Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O * interface. * * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostapi_src This file contains the implementation required for blocking I/O. It is separated from pa_mac_core.c simply to ease development. */ #include "pa_mac_core_blocking.h" #include "pa_mac_core_internal.h" #include #ifdef MOSX_USE_NON_ATOMIC_FLAG_BITS # define OSAtomicOr32( a, b ) ( (*(b)) |= (a) ) # define OSAtomicAnd32( a, b ) ( (*(b)) &= (a) ) #else # include #endif /* * This function determines the size of a particular sample format. * if the format is not recognized, this returns zero. */ static size_t computeSampleSizeFromFormat( PaSampleFormat format ) { switch( format & (~paNonInterleaved) ) { case paFloat32: return 4; case paInt32: return 4; case paInt24: return 3; case paInt16: return 2; case paInt8: case paUInt8: return 1; default: return 0; } } /* * Same as computeSampleSizeFromFormat, except that if * the size is not a power of two, it returns the next power of two up */ static size_t computeSampleSizeFromFormatPow2( PaSampleFormat format ) { switch( format & (~paNonInterleaved) ) { case paFloat32: return 4; case paInt32: return 4; case paInt24: return 4; case paInt16: return 2; case paInt8: case paUInt8: return 1; default: return 0; } } /* * Functions for initializing, resetting, and destroying BLIO structures. * */ /* This should be called with the relevant info when initializing a stream for callback. */ PaError initializeBlioRingBuffers( PaMacBlio *blio, PaSampleFormat inputSampleFormat, PaSampleFormat outputSampleFormat, size_t framesPerBuffer, long ringBufferSize, int inChan, int outChan ) { void *data; int result; OSStatus err; /* zeroify things */ bzero( blio, sizeof( PaMacBlio ) ); /* this is redundant, but the buffers are used to check if the bufffers have been initialized, so we do it explicitly. */ blio->inputRingBuffer.buffer = NULL; blio->outputRingBuffer.buffer = NULL; /* initialize simple data */ blio->ringBufferFrames = ringBufferSize; blio->inputSampleFormat = inputSampleFormat; blio->inputSampleSizeActual = computeSampleSizeFromFormat(inputSampleFormat); blio->inputSampleSizePow2 = computeSampleSizeFromFormatPow2(inputSampleFormat); blio->outputSampleFormat = outputSampleFormat; blio->outputSampleSizeActual = computeSampleSizeFromFormat(outputSampleFormat); blio->outputSampleSizePow2 = computeSampleSizeFromFormatPow2(outputSampleFormat); blio->framesPerBuffer = framesPerBuffer; blio->inChan = inChan; blio->outChan = outChan; blio->statusFlags = 0; blio->errors = paNoError; #ifdef PA_MAC_BLIO_MUTEX blio->isInputEmpty = false; blio->isOutputFull = false; #endif /* setup ring buffers */ #ifdef PA_MAC_BLIO_MUTEX result = PaMacCore_SetUnixError( pthread_mutex_init(&(blio->inputMutex),NULL), 0 ); if( result ) goto error; result = UNIX_ERR( pthread_cond_init( &(blio->inputCond), NULL ) ); if( result ) goto error; result = UNIX_ERR( pthread_mutex_init(&(blio->outputMutex),NULL) ); if( result ) goto error; result = UNIX_ERR( pthread_cond_init( &(blio->outputCond), NULL ) ); #endif if( inChan ) { data = calloc( ringBufferSize, blio->inputSampleSizePow2*inChan ); if( !data ) { result = paInsufficientMemory; goto error; } err = PaUtil_InitializeRingBuffer( &blio->inputRingBuffer, 1, ringBufferSize*blio->inputSampleSizePow2*inChan, data ); assert( !err ); } if( outChan ) { data = calloc( ringBufferSize, blio->outputSampleSizePow2*outChan ); if( !data ) { result = paInsufficientMemory; goto error; } err = PaUtil_InitializeRingBuffer( &blio->outputRingBuffer, 1, ringBufferSize*blio->outputSampleSizePow2*outChan, data ); assert( !err ); } result = resetBlioRingBuffers( blio ); if( result ) goto error; return 0; error: destroyBlioRingBuffers( blio ); return result; } #ifdef PA_MAC_BLIO_MUTEX PaError blioSetIsInputEmpty( PaMacBlio *blio, bool isEmpty ) { PaError result = paNoError; if( isEmpty == blio->isInputEmpty ) goto done; /* we need to update the value. Here's what we do: * - Lock the mutex, so noone else can write. * - update the value. * - unlock. * - broadcast to all listeners. */ result = UNIX_ERR( pthread_mutex_lock( &blio->inputMutex ) ); if( result ) goto done; blio->isInputEmpty = isEmpty; result = UNIX_ERR( pthread_mutex_unlock( &blio->inputMutex ) ); if( result ) goto done; result = UNIX_ERR( pthread_cond_broadcast( &blio->inputCond ) ); if( result ) goto done; done: return result; } PaError blioSetIsOutputFull( PaMacBlio *blio, bool isFull ) { PaError result = paNoError; if( isFull == blio->isOutputFull ) goto done; /* we need to update the value. Here's what we do: * - Lock the mutex, so noone else can write. * - update the value. * - unlock. * - broadcast to all listeners. */ result = UNIX_ERR( pthread_mutex_lock( &blio->outputMutex ) ); if( result ) goto done; blio->isOutputFull = isFull; result = UNIX_ERR( pthread_mutex_unlock( &blio->outputMutex ) ); if( result ) goto done; result = UNIX_ERR( pthread_cond_broadcast( &blio->outputCond ) ); if( result ) goto done; done: return result; } #endif /* This should be called after stopping or aborting the stream, so that on next start, the buffers will be ready. */ PaError resetBlioRingBuffers( PaMacBlio *blio ) { #ifdef PA_MAC__BLIO_MUTEX int result; #endif blio->statusFlags = 0; if( blio->outputRingBuffer.buffer ) { PaUtil_FlushRingBuffer( &blio->outputRingBuffer ); bzero( blio->outputRingBuffer.buffer, blio->outputRingBuffer.bufferSize ); /* Advance buffer */ PaUtil_AdvanceRingBufferWriteIndex( &blio->outputRingBuffer, blio->ringBufferFrames*blio->outputSampleSizeActual*blio->outChan ); //PaUtil_AdvanceRingBufferWriteIndex( &blio->outputRingBuffer, blio->outputRingBuffer.bufferSize ); /* Update isOutputFull. */ #ifdef PA_MAC__BLIO_MUTEX result = blioSetIsOutputFull( blio, toAdvance == blio->outputRingBuffer.bufferSize ); if( result ) goto error; #endif /* printf( "------%d\n" , blio->framesPerBuffer ); printf( "------%d\n" , blio->outChan ); printf( "------%d\n" , blio->outputSampleSize ); printf( "------%d\n" , blio->framesPerBuffer*blio->outChan*blio->outputSampleSize ); */ } if( blio->inputRingBuffer.buffer ) { PaUtil_FlushRingBuffer( &blio->inputRingBuffer ); bzero( blio->inputRingBuffer.buffer, blio->inputRingBuffer.bufferSize ); /* Update isInputEmpty. */ #ifdef PA_MAC__BLIO_MUTEX result = blioSetIsInputEmpty( blio, true ); if( result ) goto error; #endif } return paNoError; #ifdef PA_MAC__BLIO_MUTEX error: return result; #endif } /*This should be called when you are done with the blio. It can safely be called multiple times if there are no exceptions. */ PaError destroyBlioRingBuffers( PaMacBlio *blio ) { PaError result = paNoError; if( blio->inputRingBuffer.buffer ) { free( blio->inputRingBuffer.buffer ); #ifdef PA_MAC__BLIO_MUTEX result = UNIX_ERR( pthread_mutex_destroy( & blio->inputMutex ) ); if( result ) return result; result = UNIX_ERR( pthread_cond_destroy( & blio->inputCond ) ); if( result ) return result; #endif } blio->inputRingBuffer.buffer = NULL; if( blio->outputRingBuffer.buffer ) { free( blio->outputRingBuffer.buffer ); #ifdef PA_MAC__BLIO_MUTEX result = UNIX_ERR( pthread_mutex_destroy( & blio->outputMutex ) ); if( result ) return result; result = UNIX_ERR( pthread_cond_destroy( & blio->outputCond ) ); if( result ) return result; #endif } blio->outputRingBuffer.buffer = NULL; return result; } /* * this is the BlioCallback function. It expects to recieve a PaMacBlio Object * pointer as userData. * */ int BlioCallback( const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData ) { PaMacBlio *blio = (PaMacBlio*)userData; long avail; long toRead; long toWrite; long read; long written; /* set flags returned by OS: */ OSAtomicOr32( statusFlags, &blio->statusFlags ) ; /* --- Handle Input Buffer --- */ if( blio->inChan ) { avail = PaUtil_GetRingBufferWriteAvailable( &blio->inputRingBuffer ); /* check for underflow */ if( avail < frameCount * blio->inputSampleSizeActual * blio->inChan ) { OSAtomicOr32( paInputOverflow, &blio->statusFlags ); } toRead = MIN( avail, frameCount * blio->inputSampleSizeActual * blio->inChan ); /* copy the data */ /*printf( "reading %d\n", toRead );*/ read = PaUtil_WriteRingBuffer( &blio->inputRingBuffer, input, toRead ); assert( toRead == read ); #ifdef PA_MAC__BLIO_MUTEX /* Priority inversion. See notes below. */ blioSetIsInputEmpty( blio, false ); #endif } /* --- Handle Output Buffer --- */ if( blio->outChan ) { avail = PaUtil_GetRingBufferReadAvailable( &blio->outputRingBuffer ); /* check for underflow */ if( avail < frameCount * blio->outputSampleSizeActual * blio->outChan ) OSAtomicOr32( paOutputUnderflow, &blio->statusFlags ); toWrite = MIN( avail, frameCount * blio->outputSampleSizeActual * blio->outChan ); if( toWrite != frameCount * blio->outputSampleSizeActual * blio->outChan ) bzero( ((char *)output)+toWrite, frameCount * blio->outputSampleSizeActual * blio->outChan - toWrite ); /* copy the data */ /*printf( "writing %d\n", toWrite );*/ written = PaUtil_ReadRingBuffer( &blio->outputRingBuffer, output, toWrite ); assert( toWrite == written ); #ifdef PA_MAC__BLIO_MUTEX /* We have a priority inversion here. However, we will only have to wait if this was true and is now false, which means we've got some room in the buffer. Hopefully problems will be minimized. */ blioSetIsOutputFull( blio, false ); #endif } return paContinue; } PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ) { PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio; char *cbuf = (char *) buffer; PaError ret = paNoError; VVDBUG(("ReadStream()\n")); while( frames > 0 ) { long avail; long toRead; do { avail = PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer ); /* printf( "Read Buffer is %%%g full: %ld of %ld.\n", 100 * (float)avail / (float) blio->inputRingBuffer.bufferSize, avail, blio->inputRingBuffer.bufferSize ); */ if( avail == 0 ) { #ifdef PA_MAC_BLIO_MUTEX /**block when empty*/ ret = UNIX_ERR( pthread_mutex_lock( &blio->inputMutex ) ); if( ret ) return ret; while( blio->isInputEmpty ) { ret = UNIX_ERR( pthread_cond_wait( &blio->inputCond, &blio->inputMutex ) ); if( ret ) return ret; } ret = UNIX_ERR( pthread_mutex_unlock( &blio->inputMutex ) ); if( ret ) return ret; #else Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL ); #endif } } while( avail == 0 ); toRead = MIN( avail, frames * blio->inputSampleSizeActual * blio->inChan ); toRead -= toRead % blio->inputSampleSizeActual * blio->inChan ; PaUtil_ReadRingBuffer( &blio->inputRingBuffer, (void *)cbuf, toRead ); cbuf += toRead; frames -= toRead / ( blio->inputSampleSizeActual * blio->inChan ); if( toRead == avail ) { #ifdef PA_MAC_BLIO_MUTEX /* we just emptied the buffer, so we need to mark it as empty. */ ret = blioSetIsInputEmpty( blio, true ); if( ret ) return ret; /* of course, in the meantime, the callback may have put some sats in, so so check for that, too, to avoid a race condition. */ if( PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer ) ) { blioSetIsInputEmpty( blio, false ); if( ret ) return ret; } #endif } } /* Report either paNoError or paInputOverflowed. */ /* may also want to report other errors, but this is non-standard. */ ret = blio->statusFlags & paInputOverflow; /* report underflow only once: */ if( ret ) { OSAtomicAnd32( (uint32_t)(~paInputOverflow), &blio->statusFlags ); ret = paInputOverflowed; } return ret; } PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ) { PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio; char *cbuf = (char *) buffer; PaError ret = paNoError; VVDBUG(("WriteStream()\n")); while( frames > 0 ) { long avail = 0; long toWrite; do { avail = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ); /* printf( "Write Buffer is %%%g full: %ld of %ld.\n", 100 - 100 * (float)avail / (float) blio->outputRingBuffer.bufferSize, avail, blio->outputRingBuffer.bufferSize ); */ if( avail == 0 ) { #ifdef PA_MAC_BLIO_MUTEX /*block while full*/ ret = UNIX_ERR( pthread_mutex_lock( &blio->outputMutex ) ); if( ret ) return ret; while( blio->isOutputFull ) { ret = UNIX_ERR( pthread_cond_wait( &blio->outputCond, &blio->outputMutex ) ); if( ret ) return ret; } ret = UNIX_ERR( pthread_mutex_unlock( &blio->outputMutex ) ); if( ret ) return ret; #else Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL ); #endif } } while( avail == 0 ); toWrite = MIN( avail, frames * blio->outputSampleSizeActual * blio->outChan ); toWrite -= toWrite % blio->outputSampleSizeActual * blio->outChan ; PaUtil_WriteRingBuffer( &blio->outputRingBuffer, (void *)cbuf, toWrite ); cbuf += toWrite; frames -= toWrite / ( blio->outputSampleSizeActual * blio->outChan ); #ifdef PA_MAC_BLIO_MUTEX if( toWrite == avail ) { /* we just filled up the buffer, so we need to mark it as filled. */ ret = blioSetIsOutputFull( blio, true ); if( ret ) return ret; /* of course, in the meantime, we may have emptied the buffer, so so check for that, too, to avoid a race condition. */ if( PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ) ) { blioSetIsOutputFull( blio, false ); if( ret ) return ret; } } #endif } /* Report either paNoError or paOutputUnderflowed. */ /* may also want to report other errors, but this is non-standard. */ ret = blio->statusFlags & paOutputUnderflow; /* report underflow only once: */ if( ret ) { OSAtomicAnd32( (uint32_t)(~paOutputUnderflow), &blio->statusFlags ); ret = paOutputUnderflowed; } return ret; } /* * */ void waitUntilBlioWriteBufferIsFlushed( PaMacBlio *blio ) { if( blio->outputRingBuffer.buffer ) { long avail = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ); while( avail != blio->outputRingBuffer.bufferSize ) { if( avail == 0 ) Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL ); avail = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ); } } } signed long GetStreamReadAvailable( PaStream* stream ) { PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio; VVDBUG(("GetStreamReadAvailable()\n")); return PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer ) / ( blio->inputSampleSizeActual * blio->inChan ); } signed long GetStreamWriteAvailable( PaStream* stream ) { PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio; VVDBUG(("GetStreamWriteAvailable()\n")); return PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ) / ( blio->outputSampleSizeActual * blio->outChan ); } praat-6.0.04/external/portaudio/pa_mac_core_blocking.h000066400000000000000000000110431261542461700230200ustar00rootroot00000000000000/* * Internal blocking interfaces for PortAudio Apple AUHAL implementation * * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * * Written by Bjorn Roche of XO Audio LLC, from PA skeleton code. * Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation) * * Dominic's code was based on code by Phil Burk, Darren Gibbs, * Gord Peters, Stephane Letz, and Greg Pfiel. * * The following people also deserve acknowledgements: * * Olivier Tristan for feedback and testing * Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O * interface. * * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostapi_src */ #ifndef PA_MAC_CORE_BLOCKING_H_ #define PA_MAC_CORE_BLOCKING_H_ #include "pa_ringbuffer.h" #include "portaudio.h" #include "pa_mac_core_utilities.h" /* * Number of miliseconds to busy wait whil waiting for data in blocking calls. */ #define PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL (5) /* * Define exactly one of these blocking methods * PA_MAC_BLIO_MUTEX is not actively maintained. */ #define PA_MAC_BLIO_BUSY_WAIT /* #define PA_MAC_BLIO_MUTEX */ typedef struct { PaUtilRingBuffer inputRingBuffer; PaUtilRingBuffer outputRingBuffer; size_t ringBufferFrames; PaSampleFormat inputSampleFormat; size_t inputSampleSizeActual; size_t inputSampleSizePow2; PaSampleFormat outputSampleFormat; size_t outputSampleSizeActual; size_t outputSampleSizePow2; size_t framesPerBuffer; int inChan; int outChan; //PaStreamCallbackFlags statusFlags; uint32_t statusFlags; PaError errors; /* Here we handle blocking, using condition variables. */ #ifdef PA_MAC_BLIO_MUTEX volatile bool isInputEmpty; pthread_mutex_t inputMutex; pthread_cond_t inputCond; volatile bool isOutputFull; pthread_mutex_t outputMutex; pthread_cond_t outputCond; #endif } PaMacBlio; /* * These functions operate on condition and related variables. */ PaError initializeBlioRingBuffers( PaMacBlio *blio, PaSampleFormat inputSampleFormat, PaSampleFormat outputSampleFormat, size_t framesPerBuffer, long ringBufferSize, int inChan, int outChan ); PaError destroyBlioRingBuffers( PaMacBlio *blio ); PaError resetBlioRingBuffers( PaMacBlio *blio ); int BlioCallback( const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData ); void waitUntilBlioWriteBufferIsFlushed( PaMacBlio *blio ); #endif /*PA_MAC_CORE_BLOCKING_H_*/ praat-6.0.04/external/portaudio/pa_mac_core_internal.h000066400000000000000000000160031261542461700230450ustar00rootroot00000000000000/* * Internal interfaces for PortAudio Apple AUHAL implementation * * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * * Written by Bjorn Roche of XO Audio LLC, from PA skeleton code. * Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation) * * Dominic's code was based on code by Phil Burk, Darren Gibbs, * Gord Peters, Stephane Letz, and Greg Pfiel. * * The following people also deserve acknowledgements: * * Olivier Tristan for feedback and testing * Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O * interface. * * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file pa_mac_core @ingroup hostapi_src @author Bjorn Roche @brief AUHAL implementation of PortAudio */ #ifndef PA_MAC_CORE_INTERNAL_H__ #define PA_MAC_CORE_INTERNAL_H__ #include #include #include #include #include "portaudio.h" #include "pa_util.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_allocation.h" #include "pa_cpuload.h" #include "pa_process.h" #include "pa_ringbuffer.h" #include "pa_mac_core_blocking.h" /* function prototypes */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); #ifdef __cplusplus } #endif /* __cplusplus */ #define RING_BUFFER_ADVANCE_DENOMINATOR (4) PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ); PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ); signed long GetStreamReadAvailable( PaStream* stream ); signed long GetStreamWriteAvailable( PaStream* stream ); /* PaMacAUHAL - host api datastructure specific to this implementation */ typedef struct { PaUtilHostApiRepresentation inheritedHostApiRep; PaUtilStreamInterface callbackStreamInterface; PaUtilStreamInterface blockingStreamInterface; PaUtilAllocationGroup *allocations; /* implementation specific data goes here */ long devCount; AudioDeviceID *devIds; /*array of all audio devices*/ AudioDeviceID defaultIn; AudioDeviceID defaultOut; } PaMacAUHAL; typedef struct PaMacCoreDeviceProperties { /* Values in Frames from property queries. */ UInt32 safetyOffset; UInt32 bufferFrameSize; // UInt32 streamLatency; // Seems to be the same as deviceLatency!? UInt32 deviceLatency; /* Current device sample rate. May change! These are initialized to the nominal device sample rate, and updated with the actual sample rate, when/where available. Note that these are the *device* sample rates, prior to any required SR conversion. */ Float64 sampleRate; Float64 samplePeriod; // reciprocal } PaMacCoreDeviceProperties; /* stream data structure specifically for this implementation */ typedef struct PaMacCoreStream { PaUtilStreamRepresentation streamRepresentation; PaUtilCpuLoadMeasurer cpuLoadMeasurer; PaUtilBufferProcessor bufferProcessor; /* implementation specific data goes here */ bool bufferProcessorIsInitialized; AudioUnit inputUnit; AudioUnit outputUnit; AudioDeviceID inputDevice; AudioDeviceID outputDevice; size_t userInChan; size_t userOutChan; size_t inputFramesPerBuffer; size_t outputFramesPerBuffer; PaMacBlio blio; /* We use this ring buffer when input and out devs are different. */ PaUtilRingBuffer inputRingBuffer; /* We may need to do SR conversion on input. */ AudioConverterRef inputSRConverter; /* We need to preallocate an inputBuffer for reading data. */ AudioBufferList inputAudioBufferList; AudioTimeStamp startTime; /* FIXME: instead of volatile, these should be properly memory barriered */ volatile uint32_t xrunFlags; /*PaStreamCallbackFlags*/ volatile enum { STOPPED = 0, /* playback is completely stopped, and the user has called StopStream(). */ CALLBACK_STOPPED = 1, /* callback has requested stop, but user has not yet called StopStream(). */ STOPPING = 2, /* The stream is in the process of closing because the user has called StopStream. This state is just used internally; externally it is indistinguishable from ACTIVE.*/ ACTIVE = 3 /* The stream is active and running. */ } state; double sampleRate; PaMacCoreDeviceProperties inputProperties; PaMacCoreDeviceProperties outputProperties; /* data updated by main thread and notifications, protected by timingInformationMutex */ int timingInformationMutexIsInitialized; pthread_mutex_t timingInformationMutex; /* These are written by the PA thread or from CoreAudio callbacks. Protected by the mutex. */ Float64 timestampOffsetCombined; Float64 timestampOffsetInputDevice; Float64 timestampOffsetOutputDevice; /* Offsets in seconds to be applied to Apple timestamps to convert them to PA timestamps. * While the io proc is active, the following values are only accessed and manipulated by the ioproc */ Float64 timestampOffsetCombined_ioProcCopy; Float64 timestampOffsetInputDevice_ioProcCopy; Float64 timestampOffsetOutputDevice_ioProcCopy; } PaMacCoreStream; #endif /* PA_MAC_CORE_INTERNAL_H__ */ praat-6.0.04/external/portaudio/pa_mac_core_utilities.c000066400000000000000000000602551261542461700232470ustar00rootroot00000000000000/* * Helper and utility functions for pa_mac_core.c (Apple AUHAL implementation) * * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * * Written by Bjorn Roche of XO Audio LLC, from PA skeleton code. * Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation) * * Dominic's code was based on code by Phil Burk, Darren Gibbs, * Gord Peters, Stephane Letz, and Greg Pfiel. * * The following people also deserve acknowledgements: * * Olivier Tristan for feedback and testing * Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O * interface. * * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostapi_src */ #include "pa_mac_core_utilities.h" #include "pa_mac_core_internal.h" #include #include #include #include PaError PaMacCore_SetUnixError( int err, int line ) { PaError ret; const char *errorText; if( err == 0 ) { return paNoError; } ret = paNoError; errorText = strerror( err ); /** Map Unix error to PaError. Pretty much the only one that maps is ENOMEM. */ if( err == ENOMEM ) ret = paInsufficientMemory; else ret = paInternalError; DBUG(("%d on line %d: msg='%s'\n", err, line, errorText)); PaUtil_SetLastHostErrorInfo( paCoreAudio, err, errorText ); return ret; } /* * Translates MacOS generated errors into PaErrors */ PaError PaMacCore_SetError(OSStatus error, int line, int isError) { /*FIXME: still need to handle possible ComponentResult values.*/ /* unfortunately, they don't seem to be documented anywhere.*/ PaError result; const char *errorType; const char *errorText; switch (error) { case kAudioHardwareNoError: return paNoError; case kAudioHardwareNotRunningError: errorText = "Audio Hardware Not Running"; result = paInternalError; break; case kAudioHardwareUnspecifiedError: errorText = "Unspecified Audio Hardware Error"; result = paInternalError; break; case kAudioHardwareUnknownPropertyError: errorText = "Audio Hardware: Unknown Property"; result = paInternalError; break; case kAudioHardwareBadPropertySizeError: errorText = "Audio Hardware: Bad Property Size"; result = paInternalError; break; case kAudioHardwareIllegalOperationError: errorText = "Audio Hardware: Illegal Operation"; result = paInternalError; break; case kAudioHardwareBadDeviceError: errorText = "Audio Hardware: Bad Device"; result = paInvalidDevice; break; case kAudioHardwareBadStreamError: errorText = "Audio Hardware: BadStream"; result = paBadStreamPtr; break; case kAudioHardwareUnsupportedOperationError: errorText = "Audio Hardware: Unsupported Operation"; result = paInternalError; break; case kAudioDeviceUnsupportedFormatError: errorText = "Audio Device: Unsupported Format"; result = paSampleFormatNotSupported; break; case kAudioDevicePermissionsError: errorText = "Audio Device: Permissions Error"; result = paDeviceUnavailable; break; /* Audio Unit Errors: http://developer.apple.com/documentation/MusicAudio/Reference/CoreAudio/audio_units/chapter_5_section_3.html */ case kAudioUnitErr_InvalidProperty: errorText = "Audio Unit: Invalid Property"; result = paInternalError; break; case kAudioUnitErr_InvalidParameter: errorText = "Audio Unit: Invalid Parameter"; result = paInternalError; break; case kAudioUnitErr_NoConnection: errorText = "Audio Unit: No Connection"; result = paInternalError; break; case kAudioUnitErr_FailedInitialization: errorText = "Audio Unit: Initialization Failed"; result = paInternalError; break; case kAudioUnitErr_TooManyFramesToProcess: errorText = "Audio Unit: Too Many Frames"; result = paInternalError; break; case kAudioUnitErr_IllegalInstrument: errorText = "Audio Unit: Illegal Instrument"; result = paInternalError; break; case kAudioUnitErr_InstrumentTypeNotFound: errorText = "Audio Unit: Instrument Type Not Found"; result = paInternalError; break; case kAudioUnitErr_InvalidFile: errorText = "Audio Unit: Invalid File"; result = paInternalError; break; case kAudioUnitErr_UnknownFileType: errorText = "Audio Unit: Unknown File Type"; result = paInternalError; break; case kAudioUnitErr_FileNotSpecified: errorText = "Audio Unit: File Not Specified"; result = paInternalError; break; case kAudioUnitErr_FormatNotSupported: errorText = "Audio Unit: Format Not Supported"; result = paInternalError; break; case kAudioUnitErr_Uninitialized: errorText = "Audio Unit: Unitialized"; result = paInternalError; break; case kAudioUnitErr_InvalidScope: errorText = "Audio Unit: Invalid Scope"; result = paInternalError; break; case kAudioUnitErr_PropertyNotWritable: errorText = "Audio Unit: PropertyNotWritable"; result = paInternalError; break; case kAudioUnitErr_InvalidPropertyValue: errorText = "Audio Unit: Invalid Property Value"; result = paInternalError; break; case kAudioUnitErr_PropertyNotInUse: errorText = "Audio Unit: Property Not In Use"; result = paInternalError; break; case kAudioUnitErr_Initialized: errorText = "Audio Unit: Initialized"; result = paInternalError; break; case kAudioUnitErr_InvalidOfflineRender: errorText = "Audio Unit: Invalid Offline Render"; result = paInternalError; break; case kAudioUnitErr_Unauthorized: errorText = "Audio Unit: Unauthorized"; result = paInternalError; break; case kAudioUnitErr_CannotDoInCurrentContext: errorText = "Audio Unit: cannot do in current context"; result = paInternalError; break; default: errorText = "Unknown Error"; result = paInternalError; } if (isError) errorType = "Error"; else errorType = "Warning"; char str[20]; // see if it appears to be a 4-char-code *(UInt32 *)(str + 1) = CFSwapInt32HostToBig(error); if (isprint(str[1]) && isprint(str[2]) && isprint(str[3]) && isprint(str[4])) { str[0] = str[5] = '\''; str[6] = '\0'; } else { // no, format it as an integer sprintf(str, "%d", (int)error); } DBUG(("%s on line %d: err='%s', msg=%s\n", errorType, line, str, errorText)); PaUtil_SetLastHostErrorInfo( paCoreAudio, error, errorText ); return result; } /* * This function computes an appropriate ring buffer size given * a requested latency (in seconds), sample rate and framesPerBuffer. * * The returned ringBufferSize is computed using the following * constraints: * - it must be at least 4. * - it must be at least 3x framesPerBuffer. * - it must be at least 2x the suggestedLatency. * - it must be a power of 2. * This function attempts to compute the minimum such size. * * FEEDBACK: too liberal/conservative/another way? */ long computeRingBufferSize( const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, long inputFramesPerBuffer, long outputFramesPerBuffer, double sampleRate ) { long ringSize; int index; int i; double latency ; long framesPerBuffer ; VVDBUG(( "computeRingBufferSize()\n" )); assert( inputParameters || outputParameters ); if( outputParameters && inputParameters ) { latency = MAX( inputParameters->suggestedLatency, outputParameters->suggestedLatency ); framesPerBuffer = MAX( inputFramesPerBuffer, outputFramesPerBuffer ); } else if( outputParameters ) { latency = outputParameters->suggestedLatency; framesPerBuffer = outputFramesPerBuffer ; } else /* we have inputParameters */ { latency = inputParameters->suggestedLatency; framesPerBuffer = inputFramesPerBuffer ; } ringSize = (long) ( latency * sampleRate * 2 + .5); VDBUG( ( "suggested latency : %d\n", (int) (latency*sampleRate) ) ); if( ringSize < framesPerBuffer * 3 ) ringSize = framesPerBuffer * 3 ; VDBUG(("framesPerBuffer:%d\n",(int)framesPerBuffer)); VDBUG(("Ringbuffer size (1): %d\n", (int)ringSize )); /* make sure it's at least 4 */ ringSize = MAX( ringSize, 4 ); /* round up to the next power of 2 */ index = -1; for( i=0; i> i & 0x01 ) index = i; assert( index > 0 ); if( ringSize <= ( 0x01 << index ) ) ringSize = 0x01 << index ; else ringSize = 0x01 << ( index + 1 ); VDBUG(( "Final Ringbuffer size (2): %d\n", (int)ringSize )); return ringSize; } /* * Durring testing of core audio, I found that serious crashes could occur * if properties such as sample rate were changed multiple times in rapid * succession. The function below could be used to with a condition variable. * to prevent propertychanges from happening until the last property * change is acknowledged. Instead, I implemented a busy-wait, which is simpler * to implement b/c in second round of testing (nov '09) property changes occured * quickly and so there was no real way to test the condition variable implementation. * therefore, this function is not used, but it is aluded to in commented code below, * since it represents a theoretically better implementation. */ OSStatus propertyProc( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData ) { // this is where we would set the condition variable return noErr; } /* sets the value of the given property and waits for the change to be acknowledged, and returns the final value, which is not guaranteed by this function to be the same as the desired value. Obviously, this function can only be used for data whose input and output are the same size and format, and their size and format are known in advance. whether or not the call succeeds, if the data is successfully read, it is returned in outPropertyData. If it is not read successfully, outPropertyData is zeroed, which may or may not be useful in determining if the property was read. */ PaError AudioDeviceSetPropertyNowAndWaitForChange( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, UInt32 inPropertyDataSize, const void *inPropertyData, void *outPropertyData ) { OSStatus macErr; UInt32 outPropertyDataSize = inPropertyDataSize; /* First, see if it already has that value. If so, return. */ macErr = AudioDeviceGetProperty( inDevice, inChannel, isInput, inPropertyID, &outPropertyDataSize, outPropertyData ); if( macErr ) { memset( outPropertyData, 0, inPropertyDataSize ); goto failMac; } if( inPropertyDataSize!=outPropertyDataSize ) return paInternalError; if( 0==memcmp( outPropertyData, inPropertyData, outPropertyDataSize ) ) return paNoError; /* Ideally, we'd use a condition variable to determine changes. we could set that up here. */ /* If we were using a cond variable, we'd do something useful here, but for now, this is just to make 10.6 happy. */ macErr = AudioDeviceAddPropertyListener( inDevice, inChannel, isInput, inPropertyID, propertyProc, NULL ); if( macErr ) /* we couldn't add a listener. */ goto failMac; /* set property */ macErr = AudioDeviceSetProperty( inDevice, NULL, inChannel, isInput, inPropertyID, inPropertyDataSize, inPropertyData ); if( macErr ) goto failMac; /* busy-wait up to 30 seconds for the property to change */ /* busy-wait is justified here only because the correct alternative (condition variable) was hard to test, since most of the waiting ended up being for setting rather than getting in OS X 10.5. This was not the case in earlier OS versions. */ struct timeval tv1, tv2; gettimeofday( &tv1, NULL ); memcpy( &tv2, &tv1, sizeof( struct timeval ) ); while( tv2.tv_sec - tv1.tv_sec < 30 ) { /* now read the property back out */ macErr = AudioDeviceGetProperty( inDevice, inChannel, isInput, inPropertyID, &outPropertyDataSize, outPropertyData ); if( macErr ) { memset( outPropertyData, 0, inPropertyDataSize ); goto failMac; } /* and compare... */ if( 0==memcmp( outPropertyData, inPropertyData, outPropertyDataSize ) ) { AudioDeviceRemovePropertyListener( inDevice, inChannel, isInput, inPropertyID, propertyProc ); return paNoError; } /* No match yet, so let's sleep and try again. */ Pa_Sleep( 100 ); gettimeofday( &tv2, NULL ); } DBUG( ("Timeout waiting for device setting.\n" ) ); AudioDeviceRemovePropertyListener( inDevice, inChannel, isInput, inPropertyID, propertyProc ); return paNoError; failMac: AudioDeviceRemovePropertyListener( inDevice, inChannel, isInput, inPropertyID, propertyProc ); return ERR( macErr ); } /* * Sets the sample rate the HAL device. * if requireExact: set the sample rate or fail. * * otherwise : set the exact sample rate. * If that fails, check for available sample rates, and choose one * higher than the requested rate. If there isn't a higher one, * just use the highest available. */ PaError setBestSampleRateForDevice( const AudioDeviceID device, const bool isOutput, const bool requireExact, const Float64 desiredSrate ) { const bool isInput = isOutput ? 0 : 1; Float64 srate; UInt32 propsize = sizeof( Float64 ); OSErr err; AudioValueRange *ranges; int i=0; Float64 max = -1; /*the maximum rate available*/ Float64 best = -1; /*the lowest sample rate still greater than desired rate*/ VDBUG(("Setting sample rate for device %ld to %g.\n",device,(float)desiredSrate)); /* -- try setting the sample rate -- */ srate = 0; err = AudioDeviceSetPropertyNowAndWaitForChange( device, 0, isInput, kAudioDevicePropertyNominalSampleRate, propsize, &desiredSrate, &srate ); /* -- if the rate agrees, and was changed, we are done -- */ if( srate != 0 && srate == desiredSrate ) return paNoError; /* -- if the rate agrees, and we got no errors, we are done -- */ if( !err && srate == desiredSrate ) return paNoError; /* -- we've failed if the rates disagree and we are setting input -- */ if( requireExact ) return paInvalidSampleRate; /* -- generate a list of available sample rates -- */ err = AudioDeviceGetPropertyInfo( device, 0, isInput, kAudioDevicePropertyAvailableNominalSampleRates, &propsize, NULL ); if( err ) return ERR( err ); ranges = (AudioValueRange *)calloc( 1, propsize ); if( !ranges ) return paInsufficientMemory; err = AudioDeviceGetProperty( device, 0, isInput, kAudioDevicePropertyAvailableNominalSampleRates, &propsize, ranges ); if( err ) { free( ranges ); return ERR( err ); } VDBUG(("Requested sample rate of %g was not available.\n", (float)desiredSrate)); VDBUG(("%lu Available Sample Rates are:\n",propsize/sizeof(AudioValueRange))); #ifdef MAC_CORE_VERBOSE_DEBUG for( i=0; i max ) max = ranges[i].mMaximum; if( ranges[i].mMinimum > desiredSrate ) { if( best < 0 ) best = ranges[i].mMinimum; else if( ranges[i].mMinimum < best ) best = ranges[i].mMinimum; } } if( best < 0 ) best = max; VDBUG( ("Maximum Rate %g. best is %g.\n", max, best ) ); free( ranges ); /* -- set the sample rate -- */ propsize = sizeof( best ); srate = 0; err = AudioDeviceSetPropertyNowAndWaitForChange( device, 0, isInput, kAudioDevicePropertyNominalSampleRate, propsize, &best, &srate ); /* -- if the set rate matches, we are done -- */ if( srate != 0 && srate == best ) return paNoError; if( err ) return ERR( err ); /* -- otherwise, something wierd happened: we didn't set the rate, and we got no errors. Just bail. */ return paInternalError; } /* Attempts to set the requestedFramesPerBuffer. If it can't set the exact value, it settles for something smaller if available. If nothing smaller is available, it uses the smallest available size. actualFramesPerBuffer will be set to the actual value on successful return. OK to pass NULL to actualFramesPerBuffer. The logic is very simmilar too setBestSampleRate only failure here is not usually catastrophic. */ PaError setBestFramesPerBuffer( const AudioDeviceID device, const bool isOutput, UInt32 requestedFramesPerBuffer, UInt32 *actualFramesPerBuffer ) { UInt32 afpb; const bool isInput = !isOutput; UInt32 propsize = sizeof(UInt32); OSErr err; AudioValueRange range; if( actualFramesPerBuffer == NULL ) { actualFramesPerBuffer = &afpb; } /* -- try and set exact FPB -- */ err = AudioDeviceSetProperty( device, NULL, 0, isInput, kAudioDevicePropertyBufferFrameSize, propsize, &requestedFramesPerBuffer); err = AudioDeviceGetProperty( device, 0, isInput, kAudioDevicePropertyBufferFrameSize, &propsize, actualFramesPerBuffer); if( err ) { return ERR( err ); } // Did we get the size we asked for? if( *actualFramesPerBuffer == requestedFramesPerBuffer ) { return paNoError; /* we are done */ } // Clip requested value against legal range for the device. propsize = sizeof(AudioValueRange); err = AudioDeviceGetProperty( device, 0, isInput, kAudioDevicePropertyBufferFrameSizeRange, &propsize, &range ); if( err ) { return ERR( err ); } if( requestedFramesPerBuffer < range.mMinimum ) { requestedFramesPerBuffer = range.mMinimum; } else if( requestedFramesPerBuffer > range.mMaximum ) { requestedFramesPerBuffer = range.mMaximum; } /* --- set the buffer size (ignore errors) -- */ propsize = sizeof( UInt32 ); err = AudioDeviceSetProperty( device, NULL, 0, isInput, kAudioDevicePropertyBufferFrameSize, propsize, &requestedFramesPerBuffer ); /* --- read the property to check that it was set -- */ err = AudioDeviceGetProperty( device, 0, isInput, kAudioDevicePropertyBufferFrameSize, &propsize, actualFramesPerBuffer ); if( err ) return ERR( err ); return paNoError; } /********************** * * XRun stuff * **********************/ struct PaMacXRunListNode_s { PaMacCoreStream *stream; struct PaMacXRunListNode_s *next; } ; typedef struct PaMacXRunListNode_s PaMacXRunListNode; /** Always empty, so that it can always be the one returned by addToXRunListenerList. note that it's not a pointer. */ static PaMacXRunListNode firstXRunListNode; static int xRunListSize; static pthread_mutex_t xrunMutex; OSStatus xrunCallback( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData) { PaMacXRunListNode *node = (PaMacXRunListNode *) inClientData; int ret = pthread_mutex_trylock( &xrunMutex ) ; if( ret == 0 ) { node = node->next ; //skip the first node for( ; node; node=node->next ) { PaMacCoreStream *stream = node->stream; if( stream->state != ACTIVE ) continue; //if the stream isn't active, we don't care if the device is dropping if( isInput ) { if( stream->inputDevice == inDevice ) OSAtomicOr32( paInputOverflow, &stream->xrunFlags ); } else { if( stream->outputDevice == inDevice ) OSAtomicOr32( paOutputUnderflow, &stream->xrunFlags ); } } pthread_mutex_unlock( &xrunMutex ); } return 0; } int initializeXRunListenerList() { xRunListSize = 0; bzero( (void *) &firstXRunListNode, sizeof(firstXRunListNode) ); return pthread_mutex_init( &xrunMutex, NULL ); } int destroyXRunListenerList() { PaMacXRunListNode *node; node = firstXRunListNode.next; while( node ) { PaMacXRunListNode *tmp = node; node = node->next; free( tmp ); } xRunListSize = 0; return pthread_mutex_destroy( &xrunMutex ); } void *addToXRunListenerList( void *stream ) { pthread_mutex_lock( &xrunMutex ); PaMacXRunListNode *newNode; // setup new node: newNode = (PaMacXRunListNode *) malloc( sizeof( PaMacXRunListNode ) ); newNode->stream = (PaMacCoreStream *) stream; newNode->next = firstXRunListNode.next; // insert: firstXRunListNode.next = newNode; pthread_mutex_unlock( &xrunMutex ); return &firstXRunListNode; } int removeFromXRunListenerList( void *stream ) { pthread_mutex_lock( &xrunMutex ); PaMacXRunListNode *node, *prev; prev = &firstXRunListNode; node = firstXRunListNode.next; while( node ) { if( node->stream == stream ) { //found it: --xRunListSize; prev->next = node->next; free( node ); pthread_mutex_unlock( &xrunMutex ); return xRunListSize; } prev = prev->next; node = node->next; } pthread_mutex_unlock( &xrunMutex ); // failure return xRunListSize; } praat-6.0.04/external/portaudio/pa_mac_core_utilities.h000066400000000000000000000164351261542461700232550ustar00rootroot00000000000000/* * Helper and utility functions for pa_mac_core.c (Apple AUHAL implementation) * * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * * Written by Bjorn Roche of XO Audio LLC, from PA skeleton code. * Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation) * * Dominic's code was based on code by Phil Burk, Darren Gibbs, * Gord Peters, Stephane Letz, and Greg Pfiel. * * The following people also deserve acknowledgements: * * Olivier Tristan for feedback and testing * Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O * interface. * * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostapi_src */ #ifndef PA_MAC_CORE_UTILITIES_H__ #define PA_MAC_CORE_UTILITIES_H__ #include #include "portaudio.h" #include "pa_util.h" #include #include #ifndef MIN #define MIN(a, b) (((a)<(b))?(a):(b)) #endif #ifndef MAX #define MAX(a, b) (((a)<(b))?(b):(a)) #endif #define ERR(mac_error) PaMacCore_SetError(mac_error, __LINE__, 1 ) #define WARNING(mac_error) PaMacCore_SetError(mac_error, __LINE__, 0 ) /* Help keep track of AUHAL element numbers */ #define INPUT_ELEMENT (1) #define OUTPUT_ELEMENT (0) /* Normal level of debugging: fine for most apps that don't mind the occational warning being printf'ed */ /* */ #define MAC_CORE_DEBUG #ifdef MAC_CORE_DEBUG # define DBUG(MSG) do { printf("||PaMacCore (AUHAL)|| "); printf MSG ; fflush(stdout); } while(0) #else # define DBUG(MSG) #endif /* Verbose Debugging: useful for developement */ /* #define MAC_CORE_VERBOSE_DEBUG */ #ifdef MAC_CORE_VERBOSE_DEBUG # define VDBUG(MSG) do { printf("||PaMacCore (v )|| "); printf MSG ; fflush(stdout); } while(0) #else # define VDBUG(MSG) #endif /* Very Verbose Debugging: Traces every call. */ /* #define MAC_CORE_VERY_VERBOSE_DEBUG */ #ifdef MAC_CORE_VERY_VERBOSE_DEBUG # define VVDBUG(MSG) do { printf("||PaMacCore (vv)|| "); printf MSG ; fflush(stdout); } while(0) #else # define VVDBUG(MSG) #endif #define UNIX_ERR(err) PaMacCore_SetUnixError( err, __LINE__ ) PaError PaMacCore_SetUnixError( int err, int line ); /* * Translates MacOS generated errors into PaErrors */ PaError PaMacCore_SetError(OSStatus error, int line, int isError); /* * This function computes an appropriate ring buffer size given * a requested latency (in seconds), sample rate and framesPerBuffer. * * The returned ringBufferSize is computed using the following * constraints: * - it must be at least 4. * - it must be at least 3x framesPerBuffer. * - it must be at least 2x the suggestedLatency. * - it must be a power of 2. * This function attempts to compute the minimum such size. * */ long computeRingBufferSize( const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, long inputFramesPerBuffer, long outputFramesPerBuffer, double sampleRate ); OSStatus propertyProc( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData ); /* sets the value of the given property and waits for the change to be acknowledged, and returns the final value, which is not guaranteed by this function to be the same as the desired value. Obviously, this function can only be used for data whose input and output are the same size and format, and their size and format are known in advance.*/ PaError AudioDeviceSetPropertyNowAndWaitForChange( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, UInt32 inPropertyDataSize, const void *inPropertyData, void *outPropertyData ); /* * Sets the sample rate the HAL device. * if requireExact: set the sample rate or fail. * * otherwise : set the exact sample rate. * If that fails, check for available sample rates, and choose one * higher than the requested rate. If there isn't a higher one, * just use the highest available. */ PaError setBestSampleRateForDevice( const AudioDeviceID device, const bool isOutput, const bool requireExact, const Float64 desiredSrate ); /* Attempts to set the requestedFramesPerBuffer. If it can't set the exact value, it settles for something smaller if available. If nothing smaller is available, it uses the smallest available size. actualFramesPerBuffer will be set to the actual value on successful return. OK to pass NULL to actualFramesPerBuffer. The logic is very simmilar too setBestSampleRate only failure here is not usually catastrophic. */ PaError setBestFramesPerBuffer( const AudioDeviceID device, const bool isOutput, UInt32 requestedFramesPerBuffer, UInt32 *actualFramesPerBuffer ); /********************* * * xrun handling * *********************/ OSStatus xrunCallback( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData ) ; /** returns zero on success or a unix style error code. */ int initializeXRunListenerList(); /** returns zero on success or a unix style error code. */ int destroyXRunListenerList(); /**Returns the list, so that it can be passed to CorAudio.*/ void *addToXRunListenerList( void *stream ); /**Returns the number of Listeners in the list remaining.*/ int removeFromXRunListenerList( void *stream ); #endif /* PA_MAC_CORE_UTILITIES_H__*/ praat-6.0.04/external/portaudio/pa_mac_hostapis.c000066400000000000000000000051131261542461700220460ustar00rootroot00000000000000/* * $Id: pa_mac_hostapis.c 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library Macintosh initialization table * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup macosx_src Mac OS host API initialization function table. */ #include "pa_hostapi.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaMacSm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaJack_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaMacAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); #ifdef __cplusplus } #endif /* __cplusplus */ PaUtilHostApiInitializer *paHostApiInitializers[] = { PaMacCore_Initialize, 0 /* NULL terminated array */ }; int paDefaultHostApiIndex = 0; praat-6.0.04/external/portaudio/pa_mac_util.c000066400000000000000000000071571261542461700212030ustar00rootroot00000000000000/* * $Id: pa_unix_util.c 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library * UNIX platform-specific support functions * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2000 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup unix_src */ #include #include #include #include #include #include #include /* For memset */ #include #include #include "pa_util.h" //#include "pa_mac_util.h" /* Track memory allocations to avoid leaks. */ #if PA_TRACK_MEMORY static int numAllocations_ = 0; #endif void *PaUtil_AllocateMemory( long size ) { void *result = malloc( size ); #if PA_TRACK_MEMORY if( result != NULL ) numAllocations_ += 1; #endif return result; } void PaUtil_FreeMemory( void *block ) { if( block != NULL ) { free( block ); #if PA_TRACK_MEMORY numAllocations_ -= 1; #endif } } int PaUtil_CountCurrentlyAllocatedBlocks( void ) { #if PA_TRACK_MEMORY return numAllocations_; #else return 0; #endif } void Pa_Sleep( long msec ) { #ifdef HAVE_NANOSLEEP struct timespec req = {0}, rem = {0}; PaTime time = msec / 1.e3; req.tv_sec = (time_t)time; assert(time - req.tv_sec < 1.0); req.tv_nsec = (long)((time - req.tv_sec) * 1.e9); nanosleep(&req, &rem); /* XXX: Try sleeping the remaining time (contained in rem) if interrupted by a signal? */ #else while( msec > 999 ) /* For OpenBSD and IRIX, argument */ { /* to usleep must be < 1000000. */ usleep( 999000 ); msec -= 999; } usleep( msec * 1000 ); #endif } /* *** NOT USED YET: *** static int usePerformanceCounter_; static double microsecondsPerTick_; */ void PaUtil_InitializeClock( void ) { /* TODO */ } PaTime PaUtil_GetTime( void ) { #ifdef HAVE_CLOCK_GETTIME struct timespec tp; clock_gettime(CLOCK_REALTIME, &tp); return (PaTime)(tp.tv_sec + tp.tv_nsec / 1.e9); #else struct timeval tv; gettimeofday( &tv, NULL ); return (PaTime) tv.tv_usec / 1000000. + tv.tv_sec; #endif } praat-6.0.04/external/portaudio/pa_mac_util.h000066400000000000000000000172611261542461700212050ustar00rootroot00000000000000/* * $Id: pa_unix_util.h 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library * UNIX platform-specific support functions * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2000 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup unix_src */ #ifndef PA_UNIX_UTIL_H #define PA_UNIX_UTIL_H #include "pa_cpuload.h" #include #include #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define PA_MIN(x,y) ( (x) < (y) ? (x) : (y) ) #define PA_MAX(x,y) ( (x) > (y) ? (x) : (y) ) /* Utilize GCC branch prediction for error tests */ #if defined __GNUC__ && __GNUC__ >= 3 #define UNLIKELY(expr) __builtin_expect( (expr), 0 ) #else #define UNLIKELY(expr) (expr) #endif #define STRINGIZE_HELPER(expr) #expr #define STRINGIZE(expr) STRINGIZE_HELPER(expr) #define PA_UNLESS(expr, code) \ do { \ if( UNLIKELY( (expr) == 0 ) ) \ { \ PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \ result = (code); \ goto error; \ } \ } while (0); static PaError paUtilErr_; /* Used with PA_ENSURE */ /* Check PaError */ #define PA_ENSURE(expr) \ do { \ if( UNLIKELY( (paUtilErr_ = (expr)) < paNoError ) ) \ { \ PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \ result = paUtilErr_; \ goto error; \ } \ } while (0); #define PA_ASSERT_CALL(expr, success) \ paUtilErr_ = (expr); \ assert( success == paUtilErr_ ); #define PA_ENSURE_SYSTEM(expr, success) \ do { \ if( UNLIKELY( (paUtilErr_ = (expr)) != success ) ) \ { \ /* PaUtil_SetLastHostErrorInfo should only be used in the main thread */ \ if( pthread_equal(pthread_self(), paUnixMainThread) ) \ { \ PaUtil_SetLastHostErrorInfo( paALSA, paUtilErr_, strerror( paUtilErr_ ) ); \ } \ PaUtil_DebugPrint( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" ); \ result = paUnanticipatedHostError; \ goto error; \ } \ } while( 0 ); typedef struct { pthread_t callbackThread; } PaUtilThreading; PaError PaUtil_InitializeThreading( PaUtilThreading *threading ); void PaUtil_TerminateThreading( PaUtilThreading *threading ); PaError PaUtil_StartThreading( PaUtilThreading *threading, void *(*threadRoutine)(void *), void *data ); PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *exitResult ); /* State accessed by utility functions */ /* void PaUnix_SetRealtimeScheduling( int rt ); void PaUtil_InitializeThreading( PaUtilThreading *th, PaUtilCpuLoadMeasurer *clm ); PaError PaUtil_CreateCallbackThread( PaUtilThreading *th, void *(*CallbackThreadFunc)( void * ), PaStream *s ); PaError PaUtil_KillCallbackThread( PaUtilThreading *th, PaError *exitResult ); void PaUtil_CallbackUpdate( PaUtilThreading *th ); */ extern pthread_t paUnixMainThread; typedef struct { pthread_mutex_t mtx; } PaUnixMutex; PaError PaUnixMutex_Initialize( PaUnixMutex* self ); PaError PaUnixMutex_Terminate( PaUnixMutex* self ); PaError PaUnixMutex_Lock( PaUnixMutex* self ); PaError PaUnixMutex_Unlock( PaUnixMutex* self ); typedef struct { pthread_t thread; int parentWaiting; int stopRequested; int locked; PaUnixMutex mtx; pthread_cond_t cond; volatile sig_atomic_t stopRequest; } PaUnixThread; /** Initialize global threading state. */ PaError PaUnixThreading_Initialize(); /** Perish, passing on eventual error code. * * A thin wrapper around pthread_exit, will automatically pass on any error code to the joining thread. * If the result indicates an error, i.e. it is not equal to paNoError, this function will automatically * allocate a pointer so the error is passed on with pthread_exit. If the result indicates that all is * well however, only a NULL pointer will be handed to pthread_exit. Thus, the joining thread should * check whether a non-NULL result pointer is obtained from pthread_join and make sure to free it. * @param result: The error code to pass on to the joining thread. */ #define PaUnixThreading_EXIT(result) \ do { \ PaError* pres = NULL; \ if( paNoError != (result) ) \ { \ pres = malloc( sizeof (PaError) ); \ *pres = (result); \ } \ pthread_exit( pres ); \ } while (0); /** Spawn a thread. * * Intended for spawning the callback thread from the main thread. This function can even block (for a certain * time or indefinitely) untill notified by the callback thread (using PaUnixThread_NotifyParent), which can be * useful in order to make sure that callback has commenced before returning from Pa_StartStream. * @param threadFunc: The function to be executed in the child thread. * @param waitForChild: If not 0, wait for child thread to call PaUnixThread_NotifyParent. Less than 0 means * wait for ever, greater than 0 wait for the specified time. * @return: If timed out waiting on child, paTimedOut. */ PaError PaUnixThread_New( PaUnixThread* self, void* (*threadFunc)( void* ), void* threadArg, PaTime waitForChild ); /** Terminate thread. * * @param wait: If true, request that background thread stop and wait untill it does, else cancel it. * @param exitResult: If non-null this will upon return contain the exit status of the thread. */ PaError PaUnixThread_Terminate( PaUnixThread* self, int wait, PaError* exitResult ); /** Prepare to notify waiting parent thread. * * An internal lock must be held before the parent is notified in PaUnixThread_NotifyParent, call this to * acquire it beforehand. * @return: If parent is not waiting, paInternalError. */ PaError PaUnixThread_PrepareNotify( PaUnixThread* self ); /** Notify waiting parent thread. * * @return: If parent timed out waiting, paTimedOut. If parent was never waiting, paInternalError. */ PaError PaUnixThread_NotifyParent( PaUnixThread* self ); /** Has the parent thread requested this thread to stop? */ int PaUnixThread_StopRequested( PaUnixThread* self ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif praat-6.0.04/external/portaudio/pa_memorybarrier.h000066400000000000000000000135311261542461700222630ustar00rootroot00000000000000/* * $Id: pa_memorybarrier.h 1240 2007-07-17 13:05:07Z bjornroche $ * Portable Audio I/O Library * Memory barrier utilities * * Author: Bjorn Roche, XO Audio, LLC * * This program uses the PortAudio Portable Audio Library. * For more information see: http://www.portaudio.com * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file pa_memorybarrier.h @ingroup common_src */ /**************** * Some memory barrier primitives based on the system. * right now only OS X, FreeBSD, and Linux are supported. In addition to providing * memory barriers, these functions should ensure that data cached in registers * is written out to cache where it can be snooped by other CPUs. (ie, the volatile * keyword should not be required) * * the primitives that must be defined are: * * PaUtil_FullMemoryBarrier() * PaUtil_ReadMemoryBarrier() * PaUtil_WriteMemoryBarrier() * ****************/ #if defined(__APPLE__) # include /* Here are the memory barrier functions. Mac OS X only provides full memory barriers, so the three types of barriers are the same, however, these barriers are superior to compiler-based ones. */ # define PaUtil_FullMemoryBarrier() OSMemoryBarrier() # define PaUtil_ReadMemoryBarrier() OSMemoryBarrier() # define PaUtil_WriteMemoryBarrier() OSMemoryBarrier() #elif defined(__GNUC__) /* GCC >= 4.1 has built-in intrinsics. We'll use those */ # if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) # define PaUtil_FullMemoryBarrier() __sync_synchronize() # define PaUtil_ReadMemoryBarrier() __sync_synchronize() # define PaUtil_WriteMemoryBarrier() __sync_synchronize() /* as a fallback, GCC understands volatile asm and "memory" to mean it * should not reorder memory read/writes */ /* Note that it is not clear that any compiler actually defines __PPC__, * it can probably removed safely. */ # elif defined( __ppc__ ) || defined( __powerpc__) || defined( __PPC__ ) # define PaUtil_FullMemoryBarrier() asm volatile("sync":::"memory") # define PaUtil_ReadMemoryBarrier() asm volatile("sync":::"memory") # define PaUtil_WriteMemoryBarrier() asm volatile("sync":::"memory") # elif defined( __i386__ ) || defined( __i486__ ) || defined( __i586__ ) || \ defined( __i686__ ) || defined( __x86_64__ ) # define PaUtil_FullMemoryBarrier() asm volatile("mfence":::"memory") # define PaUtil_ReadMemoryBarrier() asm volatile("lfence":::"memory") # define PaUtil_WriteMemoryBarrier() asm volatile("sfence":::"memory") # else # ifdef ALLOW_SMP_DANGERS # warning Memory barriers not defined on this system or system unknown # warning For SMP safety, you should fix this. # define PaUtil_FullMemoryBarrier() # define PaUtil_ReadMemoryBarrier() # define PaUtil_WriteMemoryBarrier() # else # error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed. # endif # endif #elif (_MSC_VER >= 1400) && !defined(_WIN32_WCE) # include # pragma intrinsic(_ReadWriteBarrier) # pragma intrinsic(_ReadBarrier) # pragma intrinsic(_WriteBarrier) /* note that MSVC intrinsics _ReadWriteBarrier(), _ReadBarrier(), _WriteBarrier() are just compiler barriers *not* memory barriers */ # define PaUtil_FullMemoryBarrier() _ReadWriteBarrier() # define PaUtil_ReadMemoryBarrier() _ReadBarrier() # define PaUtil_WriteMemoryBarrier() _WriteBarrier() #elif defined(_WIN32_WCE) # define PaUtil_FullMemoryBarrier() # define PaUtil_ReadMemoryBarrier() # define PaUtil_WriteMemoryBarrier() #elif defined(_MSC_VER) || defined(__BORLANDC__) # define PaUtil_FullMemoryBarrier() _asm { lock add [esp], 0 } # define PaUtil_ReadMemoryBarrier() _asm { lock add [esp], 0 } # define PaUtil_WriteMemoryBarrier() _asm { lock add [esp], 0 } #else # ifdef ALLOW_SMP_DANGERS # warning Memory barriers not defined on this system or system unknown # warning For SMP safety, you should fix this. # define PaUtil_FullMemoryBarrier() # define PaUtil_ReadMemoryBarrier() # define PaUtil_WriteMemoryBarrier() # else # error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed. # endif #endif praat-6.0.04/external/portaudio/pa_process.c000066400000000000000000002050201261542461700210510ustar00rootroot00000000000000/* * $Id: pa_process.c 1913 2013-11-18 11:42:27Z gineera $ * Portable Audio I/O Library * streamCallback <-> host buffer processing adapter * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Buffer Processor implementation. */ #include #include /* memset() */ #include "pa_process.h" #include "pa_util.h" #define PA_FRAMES_PER_TEMP_BUFFER_WHEN_HOST_BUFFER_SIZE_IS_UNKNOWN_ 1024 #define PA_MIN_( a, b ) ( ((a)<(b)) ? (a) : (b) ) /* greatest common divisor - PGCD in French */ static unsigned long GCD( unsigned long a, unsigned long b ) { return (b==0) ? a : GCD( b, a%b); } /* least common multiple - PPCM in French */ static unsigned long LCM( unsigned long a, unsigned long b ) { return (a*b) / GCD(a,b); } #define PA_MAX_( a, b ) (((a) > (b)) ? (a) : (b)) static unsigned long CalculateFrameShift( unsigned long M, unsigned long N ) { unsigned long result = 0; unsigned long i; unsigned long lcm; assert( M > 0 ); assert( N > 0 ); lcm = LCM( M, N ); for( i = M; i < lcm; i += M ) result = PA_MAX_( result, i % N ); return result; } PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bp, int inputChannelCount, PaSampleFormat userInputSampleFormat, PaSampleFormat hostInputSampleFormat, int outputChannelCount, PaSampleFormat userOutputSampleFormat, PaSampleFormat hostOutputSampleFormat, double sampleRate, PaStreamFlags streamFlags, unsigned long framesPerUserBuffer, unsigned long framesPerHostBuffer, PaUtilHostBufferSizeMode hostBufferSizeMode, PaStreamCallback *streamCallback, void *userData ) { PaError result = paNoError; PaError bytesPerSample; unsigned long tempInputBufferSize, tempOutputBufferSize; PaStreamFlags tempInputStreamFlags; if( streamFlags & paNeverDropInput ) { /* paNeverDropInput is only valid for full-duplex callback streams, with an unspecified number of frames per buffer. */ if( !streamCallback || !(inputChannelCount > 0 && outputChannelCount > 0) || framesPerUserBuffer != paFramesPerBufferUnspecified ) return paInvalidFlag; } /* initialize buffer ptrs to zero so they can be freed if necessary in error */ bp->tempInputBuffer = 0; bp->tempInputBufferPtrs = 0; bp->tempOutputBuffer = 0; bp->tempOutputBufferPtrs = 0; bp->framesPerUserBuffer = framesPerUserBuffer; bp->framesPerHostBuffer = framesPerHostBuffer; bp->inputChannelCount = inputChannelCount; bp->outputChannelCount = outputChannelCount; bp->hostBufferSizeMode = hostBufferSizeMode; bp->hostInputChannels[0] = bp->hostInputChannels[1] = 0; bp->hostOutputChannels[0] = bp->hostOutputChannels[1] = 0; if( framesPerUserBuffer == 0 ) /* streamCallback will accept any buffer size */ { bp->useNonAdaptingProcess = 1; bp->initialFramesInTempInputBuffer = 0; bp->initialFramesInTempOutputBuffer = 0; if( hostBufferSizeMode == paUtilFixedHostBufferSize || hostBufferSizeMode == paUtilBoundedHostBufferSize ) { bp->framesPerTempBuffer = framesPerHostBuffer; } else /* unknown host buffer size */ { bp->framesPerTempBuffer = PA_FRAMES_PER_TEMP_BUFFER_WHEN_HOST_BUFFER_SIZE_IS_UNKNOWN_; } } else { bp->framesPerTempBuffer = framesPerUserBuffer; if( hostBufferSizeMode == paUtilFixedHostBufferSize && framesPerHostBuffer % framesPerUserBuffer == 0 ) { bp->useNonAdaptingProcess = 1; bp->initialFramesInTempInputBuffer = 0; bp->initialFramesInTempOutputBuffer = 0; } else { bp->useNonAdaptingProcess = 0; if( inputChannelCount > 0 && outputChannelCount > 0 ) { /* full duplex */ if( hostBufferSizeMode == paUtilFixedHostBufferSize ) { unsigned long frameShift = CalculateFrameShift( framesPerHostBuffer, framesPerUserBuffer ); if( framesPerUserBuffer > framesPerHostBuffer ) { bp->initialFramesInTempInputBuffer = frameShift; bp->initialFramesInTempOutputBuffer = 0; } else { bp->initialFramesInTempInputBuffer = 0; bp->initialFramesInTempOutputBuffer = frameShift; } } else /* variable host buffer size, add framesPerUserBuffer latency */ { bp->initialFramesInTempInputBuffer = 0; bp->initialFramesInTempOutputBuffer = framesPerUserBuffer; } } else { /* half duplex */ bp->initialFramesInTempInputBuffer = 0; bp->initialFramesInTempOutputBuffer = 0; } } } bp->framesInTempInputBuffer = bp->initialFramesInTempInputBuffer; bp->framesInTempOutputBuffer = bp->initialFramesInTempOutputBuffer; if( inputChannelCount > 0 ) { bytesPerSample = Pa_GetSampleSize( hostInputSampleFormat ); if( bytesPerSample > 0 ) { bp->bytesPerHostInputSample = bytesPerSample; } else { result = bytesPerSample; goto error; } bytesPerSample = Pa_GetSampleSize( userInputSampleFormat ); if( bytesPerSample > 0 ) { bp->bytesPerUserInputSample = bytesPerSample; } else { result = bytesPerSample; goto error; } /* Under the assumption that no ADC in existence delivers better than 24bits resolution, we disable dithering when host input format is paInt32 and user format is paInt24, since the host samples will just be padded with zeros anyway. */ tempInputStreamFlags = streamFlags; if( !(tempInputStreamFlags & paDitherOff) /* dither is on */ && (hostInputSampleFormat & paInt32) /* host input format is int32 */ && (userInputSampleFormat & paInt24) /* user requested format is int24 */ ){ tempInputStreamFlags = tempInputStreamFlags | paDitherOff; } bp->inputConverter = PaUtil_SelectConverter( hostInputSampleFormat, userInputSampleFormat, tempInputStreamFlags ); bp->inputZeroer = PaUtil_SelectZeroer( userInputSampleFormat ); bp->userInputIsInterleaved = (userInputSampleFormat & paNonInterleaved)?0:1; bp->hostInputIsInterleaved = (hostInputSampleFormat & paNonInterleaved)?0:1; bp->userInputSampleFormatIsEqualToHost = ((userInputSampleFormat & ~paNonInterleaved) == (hostInputSampleFormat & ~paNonInterleaved)); tempInputBufferSize = bp->framesPerTempBuffer * bp->bytesPerUserInputSample * inputChannelCount; bp->tempInputBuffer = PaUtil_AllocateMemory( tempInputBufferSize ); if( bp->tempInputBuffer == 0 ) { result = paInsufficientMemory; goto error; } if( bp->framesInTempInputBuffer > 0 ) memset( bp->tempInputBuffer, 0, tempInputBufferSize ); if( userInputSampleFormat & paNonInterleaved ) { bp->tempInputBufferPtrs = (void **)PaUtil_AllocateMemory( sizeof(void*)*inputChannelCount ); if( bp->tempInputBufferPtrs == 0 ) { result = paInsufficientMemory; goto error; } } bp->hostInputChannels[0] = (PaUtilChannelDescriptor*) PaUtil_AllocateMemory( sizeof(PaUtilChannelDescriptor) * inputChannelCount * 2); if( bp->hostInputChannels[0] == 0 ) { result = paInsufficientMemory; goto error; } bp->hostInputChannels[1] = &bp->hostInputChannels[0][inputChannelCount]; } if( outputChannelCount > 0 ) { bytesPerSample = Pa_GetSampleSize( hostOutputSampleFormat ); if( bytesPerSample > 0 ) { bp->bytesPerHostOutputSample = bytesPerSample; } else { result = bytesPerSample; goto error; } bytesPerSample = Pa_GetSampleSize( userOutputSampleFormat ); if( bytesPerSample > 0 ) { bp->bytesPerUserOutputSample = bytesPerSample; } else { result = bytesPerSample; goto error; } bp->outputConverter = PaUtil_SelectConverter( userOutputSampleFormat, hostOutputSampleFormat, streamFlags ); bp->outputZeroer = PaUtil_SelectZeroer( hostOutputSampleFormat ); bp->userOutputIsInterleaved = (userOutputSampleFormat & paNonInterleaved)?0:1; bp->hostOutputIsInterleaved = (hostOutputSampleFormat & paNonInterleaved)?0:1; bp->userOutputSampleFormatIsEqualToHost = ((userOutputSampleFormat & ~paNonInterleaved) == (hostOutputSampleFormat & ~paNonInterleaved)); tempOutputBufferSize = bp->framesPerTempBuffer * bp->bytesPerUserOutputSample * outputChannelCount; bp->tempOutputBuffer = PaUtil_AllocateMemory( tempOutputBufferSize ); if( bp->tempOutputBuffer == 0 ) { result = paInsufficientMemory; goto error; } if( bp->framesInTempOutputBuffer > 0 ) memset( bp->tempOutputBuffer, 0, tempOutputBufferSize ); if( userOutputSampleFormat & paNonInterleaved ) { bp->tempOutputBufferPtrs = (void **)PaUtil_AllocateMemory( sizeof(void*)*outputChannelCount ); if( bp->tempOutputBufferPtrs == 0 ) { result = paInsufficientMemory; goto error; } } bp->hostOutputChannels[0] = (PaUtilChannelDescriptor*) PaUtil_AllocateMemory( sizeof(PaUtilChannelDescriptor)*outputChannelCount * 2 ); if( bp->hostOutputChannels[0] == 0 ) { result = paInsufficientMemory; goto error; } bp->hostOutputChannels[1] = &bp->hostOutputChannels[0][outputChannelCount]; } PaUtil_InitializeTriangularDitherState( &bp->ditherGenerator ); bp->samplePeriod = 1. / sampleRate; bp->streamCallback = streamCallback; bp->userData = userData; return result; error: if( bp->tempInputBuffer ) PaUtil_FreeMemory( bp->tempInputBuffer ); if( bp->tempInputBufferPtrs ) PaUtil_FreeMemory( bp->tempInputBufferPtrs ); if( bp->hostInputChannels[0] ) PaUtil_FreeMemory( bp->hostInputChannels[0] ); if( bp->tempOutputBuffer ) PaUtil_FreeMemory( bp->tempOutputBuffer ); if( bp->tempOutputBufferPtrs ) PaUtil_FreeMemory( bp->tempOutputBufferPtrs ); if( bp->hostOutputChannels[0] ) PaUtil_FreeMemory( bp->hostOutputChannels[0] ); return result; } void PaUtil_TerminateBufferProcessor( PaUtilBufferProcessor* bp ) { if( bp->tempInputBuffer ) PaUtil_FreeMemory( bp->tempInputBuffer ); if( bp->tempInputBufferPtrs ) PaUtil_FreeMemory( bp->tempInputBufferPtrs ); if( bp->hostInputChannels[0] ) PaUtil_FreeMemory( bp->hostInputChannels[0] ); if( bp->tempOutputBuffer ) PaUtil_FreeMemory( bp->tempOutputBuffer ); if( bp->tempOutputBufferPtrs ) PaUtil_FreeMemory( bp->tempOutputBufferPtrs ); if( bp->hostOutputChannels[0] ) PaUtil_FreeMemory( bp->hostOutputChannels[0] ); } void PaUtil_ResetBufferProcessor( PaUtilBufferProcessor* bp ) { unsigned long tempInputBufferSize, tempOutputBufferSize; bp->framesInTempInputBuffer = bp->initialFramesInTempInputBuffer; bp->framesInTempOutputBuffer = bp->initialFramesInTempOutputBuffer; if( bp->framesInTempInputBuffer > 0 ) { tempInputBufferSize = bp->framesPerTempBuffer * bp->bytesPerUserInputSample * bp->inputChannelCount; memset( bp->tempInputBuffer, 0, tempInputBufferSize ); } if( bp->framesInTempOutputBuffer > 0 ) { tempOutputBufferSize = bp->framesPerTempBuffer * bp->bytesPerUserOutputSample * bp->outputChannelCount; memset( bp->tempOutputBuffer, 0, tempOutputBufferSize ); } } unsigned long PaUtil_GetBufferProcessorInputLatencyFrames( PaUtilBufferProcessor* bp ) { return bp->initialFramesInTempInputBuffer; } unsigned long PaUtil_GetBufferProcessorOutputLatencyFrames( PaUtilBufferProcessor* bp ) { return bp->initialFramesInTempOutputBuffer; } void PaUtil_SetInputFrameCount( PaUtilBufferProcessor* bp, unsigned long frameCount ) { if( frameCount == 0 ) bp->hostInputFrameCount[0] = bp->framesPerHostBuffer; else bp->hostInputFrameCount[0] = frameCount; } void PaUtil_SetNoInput( PaUtilBufferProcessor* bp ) { assert( bp->inputChannelCount > 0 ); bp->hostInputChannels[0][0].data = 0; } void PaUtil_SetInputChannel( PaUtilBufferProcessor* bp, unsigned int channel, void *data, unsigned int stride ) { assert( channel < bp->inputChannelCount ); bp->hostInputChannels[0][channel].data = data; bp->hostInputChannels[0][channel].stride = stride; } void PaUtil_SetInterleavedInputChannels( PaUtilBufferProcessor* bp, unsigned int firstChannel, void *data, unsigned int channelCount ) { unsigned int i; unsigned int channel = firstChannel; unsigned char *p = (unsigned char*)data; if( channelCount == 0 ) channelCount = bp->inputChannelCount; assert( firstChannel < bp->inputChannelCount ); assert( firstChannel + channelCount <= bp->inputChannelCount ); assert( bp->hostInputIsInterleaved ); for( i=0; i< channelCount; ++i ) { bp->hostInputChannels[0][channel+i].data = p; p += bp->bytesPerHostInputSample; bp->hostInputChannels[0][channel+i].stride = channelCount; } } void PaUtil_SetNonInterleavedInputChannel( PaUtilBufferProcessor* bp, unsigned int channel, void *data ) { assert( channel < bp->inputChannelCount ); assert( !bp->hostInputIsInterleaved ); bp->hostInputChannels[0][channel].data = data; bp->hostInputChannels[0][channel].stride = 1; } void PaUtil_Set2ndInputFrameCount( PaUtilBufferProcessor* bp, unsigned long frameCount ) { bp->hostInputFrameCount[1] = frameCount; } void PaUtil_Set2ndInputChannel( PaUtilBufferProcessor* bp, unsigned int channel, void *data, unsigned int stride ) { assert( channel < bp->inputChannelCount ); bp->hostInputChannels[1][channel].data = data; bp->hostInputChannels[1][channel].stride = stride; } void PaUtil_Set2ndInterleavedInputChannels( PaUtilBufferProcessor* bp, unsigned int firstChannel, void *data, unsigned int channelCount ) { unsigned int i; unsigned int channel = firstChannel; unsigned char *p = (unsigned char*)data; if( channelCount == 0 ) channelCount = bp->inputChannelCount; assert( firstChannel < bp->inputChannelCount ); assert( firstChannel + channelCount <= bp->inputChannelCount ); assert( bp->hostInputIsInterleaved ); for( i=0; i< channelCount; ++i ) { bp->hostInputChannels[1][channel+i].data = p; p += bp->bytesPerHostInputSample; bp->hostInputChannels[1][channel+i].stride = channelCount; } } void PaUtil_Set2ndNonInterleavedInputChannel( PaUtilBufferProcessor* bp, unsigned int channel, void *data ) { assert( channel < bp->inputChannelCount ); assert( !bp->hostInputIsInterleaved ); bp->hostInputChannels[1][channel].data = data; bp->hostInputChannels[1][channel].stride = 1; } void PaUtil_SetOutputFrameCount( PaUtilBufferProcessor* bp, unsigned long frameCount ) { if( frameCount == 0 ) bp->hostOutputFrameCount[0] = bp->framesPerHostBuffer; else bp->hostOutputFrameCount[0] = frameCount; } void PaUtil_SetNoOutput( PaUtilBufferProcessor* bp ) { assert( bp->outputChannelCount > 0 ); bp->hostOutputChannels[0][0].data = 0; /* note that only NonAdaptingProcess is able to deal with no output at this stage. not implemented for AdaptingProcess */ } void PaUtil_SetOutputChannel( PaUtilBufferProcessor* bp, unsigned int channel, void *data, unsigned int stride ) { assert( channel < bp->outputChannelCount ); assert( data != NULL ); bp->hostOutputChannels[0][channel].data = data; bp->hostOutputChannels[0][channel].stride = stride; } void PaUtil_SetInterleavedOutputChannels( PaUtilBufferProcessor* bp, unsigned int firstChannel, void *data, unsigned int channelCount ) { unsigned int i; unsigned int channel = firstChannel; unsigned char *p = (unsigned char*)data; if( channelCount == 0 ) channelCount = bp->outputChannelCount; assert( firstChannel < bp->outputChannelCount ); assert( firstChannel + channelCount <= bp->outputChannelCount ); assert( bp->hostOutputIsInterleaved ); for( i=0; i< channelCount; ++i ) { PaUtil_SetOutputChannel( bp, channel + i, p, channelCount ); p += bp->bytesPerHostOutputSample; } } void PaUtil_SetNonInterleavedOutputChannel( PaUtilBufferProcessor* bp, unsigned int channel, void *data ) { assert( channel < bp->outputChannelCount ); assert( !bp->hostOutputIsInterleaved ); PaUtil_SetOutputChannel( bp, channel, data, 1 ); } void PaUtil_Set2ndOutputFrameCount( PaUtilBufferProcessor* bp, unsigned long frameCount ) { bp->hostOutputFrameCount[1] = frameCount; } void PaUtil_Set2ndOutputChannel( PaUtilBufferProcessor* bp, unsigned int channel, void *data, unsigned int stride ) { assert( channel < bp->outputChannelCount ); assert( data != NULL ); bp->hostOutputChannels[1][channel].data = data; bp->hostOutputChannels[1][channel].stride = stride; } void PaUtil_Set2ndInterleavedOutputChannels( PaUtilBufferProcessor* bp, unsigned int firstChannel, void *data, unsigned int channelCount ) { unsigned int i; unsigned int channel = firstChannel; unsigned char *p = (unsigned char*)data; if( channelCount == 0 ) channelCount = bp->outputChannelCount; assert( firstChannel < bp->outputChannelCount ); assert( firstChannel + channelCount <= bp->outputChannelCount ); assert( bp->hostOutputIsInterleaved ); for( i=0; i< channelCount; ++i ) { PaUtil_Set2ndOutputChannel( bp, channel + i, p, channelCount ); p += bp->bytesPerHostOutputSample; } } void PaUtil_Set2ndNonInterleavedOutputChannel( PaUtilBufferProcessor* bp, unsigned int channel, void *data ) { assert( channel < bp->outputChannelCount ); assert( !bp->hostOutputIsInterleaved ); PaUtil_Set2ndOutputChannel( bp, channel, data, 1 ); } void PaUtil_BeginBufferProcessing( PaUtilBufferProcessor* bp, PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags callbackStatusFlags ) { bp->timeInfo = timeInfo; /* the first streamCallback will be called to process samples which are currently in the input buffer before the ones starting at the timeInfo time */ bp->timeInfo->inputBufferAdcTime -= bp->framesInTempInputBuffer * bp->samplePeriod; /* We just pass through timeInfo->currentTime provided by the caller. This is not strictly conformant to the word of the spec, since the buffer processor might call the callback multiple times, and we never refresh currentTime. */ /* the first streamCallback will be called to generate samples which will be outputted after the frames currently in the output buffer have been outputted. */ bp->timeInfo->outputBufferDacTime += bp->framesInTempOutputBuffer * bp->samplePeriod; bp->callbackStatusFlags = callbackStatusFlags; bp->hostInputFrameCount[1] = 0; bp->hostOutputFrameCount[1] = 0; } /* NonAdaptingProcess() is a simple buffer copying adaptor that can handle both full and half duplex copies. It processes framesToProcess frames, broken into blocks bp->framesPerTempBuffer long. This routine can be used when the streamCallback doesn't care what length the buffers are, or when framesToProcess is an integer multiple of bp->framesPerTempBuffer, in which case streamCallback will always be called with bp->framesPerTempBuffer samples. */ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp, int *streamCallbackResult, PaUtilChannelDescriptor *hostInputChannels, PaUtilChannelDescriptor *hostOutputChannels, unsigned long framesToProcess ) { void *userInput, *userOutput; unsigned char *srcBytePtr, *destBytePtr; unsigned int srcSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */ unsigned int srcChannelStrideBytes; /* stride from one channel to the next, in bytes */ unsigned int destSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */ unsigned int destChannelStrideBytes; /* stride from one channel to the next, in bytes */ unsigned int i; unsigned long frameCount; unsigned long framesToGo = framesToProcess; unsigned long framesProcessed = 0; int skipOutputConvert = 0; int skipInputConvert = 0; if( *streamCallbackResult == paContinue ) { do { frameCount = PA_MIN_( bp->framesPerTempBuffer, framesToGo ); /* configure user input buffer and convert input data (host -> user) */ if( bp->inputChannelCount == 0 ) { /* no input */ userInput = 0; } else /* there are input channels */ { destBytePtr = (unsigned char *)bp->tempInputBuffer; if( bp->userInputIsInterleaved ) { destSampleStrideSamples = bp->inputChannelCount; destChannelStrideBytes = bp->bytesPerUserInputSample; /* process host buffer directly, or use temp buffer if formats differ or host buffer non-interleaved, * or if the number of channels differs between the host (set in stride) and the user */ if( bp->userInputSampleFormatIsEqualToHost && bp->hostInputIsInterleaved && bp->hostInputChannels[0][0].data && bp->inputChannelCount == hostInputChannels[0].stride ) { userInput = hostInputChannels[0].data; destBytePtr = (unsigned char *)hostInputChannels[0].data; skipInputConvert = 1; } else { userInput = bp->tempInputBuffer; } } else /* user input is not interleaved */ { destSampleStrideSamples = 1; destChannelStrideBytes = frameCount * bp->bytesPerUserInputSample; /* setup non-interleaved ptrs */ if( bp->userInputSampleFormatIsEqualToHost && !bp->hostInputIsInterleaved && bp->hostInputChannels[0][0].data ) { for( i=0; iinputChannelCount; ++i ) { bp->tempInputBufferPtrs[i] = hostInputChannels[i].data; } skipInputConvert = 1; } else { for( i=0; iinputChannelCount; ++i ) { bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) + i * bp->bytesPerUserInputSample * frameCount; } } userInput = bp->tempInputBufferPtrs; } if( !bp->hostInputChannels[0][0].data ) { /* no input was supplied (see PaUtil_SetNoInput), so zero the input buffer */ for( i=0; iinputChannelCount; ++i ) { bp->inputZeroer( destBytePtr, destSampleStrideSamples, frameCount ); destBytePtr += destChannelStrideBytes; /* skip to next destination channel */ } } else { if( skipInputConvert ) { for( i=0; iinputChannelCount; ++i ) { /* advance src ptr for next iteration */ hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) + frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample; } } else { for( i=0; iinputChannelCount; ++i ) { bp->inputConverter( destBytePtr, destSampleStrideSamples, hostInputChannels[i].data, hostInputChannels[i].stride, frameCount, &bp->ditherGenerator ); destBytePtr += destChannelStrideBytes; /* skip to next destination channel */ /* advance src ptr for next iteration */ hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) + frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample; } } } } /* configure user output buffer */ if( bp->outputChannelCount == 0 ) { /* no output */ userOutput = 0; } else /* there are output channels */ { if( bp->userOutputIsInterleaved ) { /* process host buffer directly, or use temp buffer if formats differ or host buffer non-interleaved */ if( bp->userOutputSampleFormatIsEqualToHost && bp->hostOutputIsInterleaved ) { userOutput = hostOutputChannels[0].data; skipOutputConvert = 1; } else { userOutput = bp->tempOutputBuffer; } } else /* user output is not interleaved */ { if( bp->userOutputSampleFormatIsEqualToHost && !bp->hostOutputIsInterleaved ) { for( i=0; ioutputChannelCount; ++i ) { bp->tempOutputBufferPtrs[i] = hostOutputChannels[i].data; } skipOutputConvert = 1; } else { for( i=0; ioutputChannelCount; ++i ) { bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) + i * bp->bytesPerUserOutputSample * frameCount; } } userOutput = bp->tempOutputBufferPtrs; } } *streamCallbackResult = bp->streamCallback( userInput, userOutput, frameCount, bp->timeInfo, bp->callbackStatusFlags, bp->userData ); if( *streamCallbackResult == paAbort ) { /* callback returned paAbort, don't advance framesProcessed and framesToGo, they will be handled below */ } else { bp->timeInfo->inputBufferAdcTime += frameCount * bp->samplePeriod; bp->timeInfo->outputBufferDacTime += frameCount * bp->samplePeriod; /* convert output data (user -> host) */ if( bp->outputChannelCount != 0 && bp->hostOutputChannels[0][0].data ) { if( skipOutputConvert ) { for( i=0; ioutputChannelCount; ++i ) { /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } } else { srcBytePtr = (unsigned char *)bp->tempOutputBuffer; if( bp->userOutputIsInterleaved ) { srcSampleStrideSamples = bp->outputChannelCount; srcChannelStrideBytes = bp->bytesPerUserOutputSample; } else /* user output is not interleaved */ { srcSampleStrideSamples = 1; srcChannelStrideBytes = frameCount * bp->bytesPerUserOutputSample; } for( i=0; ioutputChannelCount; ++i ) { bp->outputConverter( hostOutputChannels[i].data, hostOutputChannels[i].stride, srcBytePtr, srcSampleStrideSamples, frameCount, &bp->ditherGenerator ); srcBytePtr += srcChannelStrideBytes; /* skip to next source channel */ /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } } } framesProcessed += frameCount; framesToGo -= frameCount; } } while( framesToGo > 0 && *streamCallbackResult == paContinue ); } if( framesToGo > 0 ) { /* zero any remaining frames output. There will only be remaining frames if the callback has returned paComplete or paAbort */ frameCount = framesToGo; if( bp->outputChannelCount != 0 && bp->hostOutputChannels[0][0].data ) { for( i=0; ioutputChannelCount; ++i ) { bp->outputZeroer( hostOutputChannels[i].data, hostOutputChannels[i].stride, frameCount ); /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } } framesProcessed += frameCount; } return framesProcessed; } /* AdaptingInputOnlyProcess() is a half duplex input buffer processor. It converts data from the input buffers into the temporary input buffer, when the temporary input buffer is full, it calls the streamCallback. */ static unsigned long AdaptingInputOnlyProcess( PaUtilBufferProcessor *bp, int *streamCallbackResult, PaUtilChannelDescriptor *hostInputChannels, unsigned long framesToProcess ) { void *userInput, *userOutput; unsigned char *destBytePtr; unsigned int destSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */ unsigned int destChannelStrideBytes; /* stride from one channel to the next, in bytes */ unsigned int i; unsigned long frameCount; unsigned long framesToGo = framesToProcess; unsigned long framesProcessed = 0; userOutput = 0; do { frameCount = ( bp->framesInTempInputBuffer + framesToGo > bp->framesPerUserBuffer ) ? ( bp->framesPerUserBuffer - bp->framesInTempInputBuffer ) : framesToGo; /* convert frameCount samples into temp buffer */ if( bp->userInputIsInterleaved ) { destBytePtr = ((unsigned char*)bp->tempInputBuffer) + bp->bytesPerUserInputSample * bp->inputChannelCount * bp->framesInTempInputBuffer; destSampleStrideSamples = bp->inputChannelCount; destChannelStrideBytes = bp->bytesPerUserInputSample; userInput = bp->tempInputBuffer; } else /* user input is not interleaved */ { destBytePtr = ((unsigned char*)bp->tempInputBuffer) + bp->bytesPerUserInputSample * bp->framesInTempInputBuffer; destSampleStrideSamples = 1; destChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserInputSample; /* setup non-interleaved ptrs */ for( i=0; iinputChannelCount; ++i ) { bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) + i * bp->bytesPerUserInputSample * bp->framesPerUserBuffer; } userInput = bp->tempInputBufferPtrs; } for( i=0; iinputChannelCount; ++i ) { bp->inputConverter( destBytePtr, destSampleStrideSamples, hostInputChannels[i].data, hostInputChannels[i].stride, frameCount, &bp->ditherGenerator ); destBytePtr += destChannelStrideBytes; /* skip to next destination channel */ /* advance src ptr for next iteration */ hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) + frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample; } bp->framesInTempInputBuffer += frameCount; if( bp->framesInTempInputBuffer == bp->framesPerUserBuffer ) { /** @todo (non-critical optimisation) The conditional below implements the continue/complete/abort mechanism simply by continuing on iterating through the input buffer, but not passing the data to the callback. With care, the outer loop could be terminated earlier, thus some unneeded conversion cycles would be saved. */ if( *streamCallbackResult == paContinue ) { bp->timeInfo->outputBufferDacTime = 0; *streamCallbackResult = bp->streamCallback( userInput, userOutput, bp->framesPerUserBuffer, bp->timeInfo, bp->callbackStatusFlags, bp->userData ); bp->timeInfo->inputBufferAdcTime += bp->framesPerUserBuffer * bp->samplePeriod; } bp->framesInTempInputBuffer = 0; } framesProcessed += frameCount; framesToGo -= frameCount; }while( framesToGo > 0 ); return framesProcessed; } /* AdaptingOutputOnlyProcess() is a half duplex output buffer processor. It converts data from the temporary output buffer, to the output buffers, when the temporary output buffer is empty, it calls the streamCallback. */ static unsigned long AdaptingOutputOnlyProcess( PaUtilBufferProcessor *bp, int *streamCallbackResult, PaUtilChannelDescriptor *hostOutputChannels, unsigned long framesToProcess ) { void *userInput, *userOutput; unsigned char *srcBytePtr; unsigned int srcSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */ unsigned int srcChannelStrideBytes; /* stride from one channel to the next, in bytes */ unsigned int i; unsigned long frameCount; unsigned long framesToGo = framesToProcess; unsigned long framesProcessed = 0; do { if( bp->framesInTempOutputBuffer == 0 && *streamCallbackResult == paContinue ) { userInput = 0; /* setup userOutput */ if( bp->userOutputIsInterleaved ) { userOutput = bp->tempOutputBuffer; } else /* user output is not interleaved */ { for( i = 0; i < bp->outputChannelCount; ++i ) { bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) + i * bp->framesPerUserBuffer * bp->bytesPerUserOutputSample; } userOutput = bp->tempOutputBufferPtrs; } bp->timeInfo->inputBufferAdcTime = 0; *streamCallbackResult = bp->streamCallback( userInput, userOutput, bp->framesPerUserBuffer, bp->timeInfo, bp->callbackStatusFlags, bp->userData ); if( *streamCallbackResult == paAbort ) { /* if the callback returned paAbort, we disregard its output */ } else { bp->timeInfo->outputBufferDacTime += bp->framesPerUserBuffer * bp->samplePeriod; bp->framesInTempOutputBuffer = bp->framesPerUserBuffer; } } if( bp->framesInTempOutputBuffer > 0 ) { /* convert frameCount frames from user buffer to host buffer */ frameCount = PA_MIN_( bp->framesInTempOutputBuffer, framesToGo ); if( bp->userOutputIsInterleaved ) { srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) + bp->bytesPerUserOutputSample * bp->outputChannelCount * (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer); srcSampleStrideSamples = bp->outputChannelCount; srcChannelStrideBytes = bp->bytesPerUserOutputSample; } else /* user output is not interleaved */ { srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) + bp->bytesPerUserOutputSample * (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer); srcSampleStrideSamples = 1; srcChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserOutputSample; } for( i=0; ioutputChannelCount; ++i ) { bp->outputConverter( hostOutputChannels[i].data, hostOutputChannels[i].stride, srcBytePtr, srcSampleStrideSamples, frameCount, &bp->ditherGenerator ); srcBytePtr += srcChannelStrideBytes; /* skip to next source channel */ /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } bp->framesInTempOutputBuffer -= frameCount; } else { /* no more user data is available because the callback has returned paComplete or paAbort. Fill the remainder of the host buffer with zeros. */ frameCount = framesToGo; for( i=0; ioutputChannelCount; ++i ) { bp->outputZeroer( hostOutputChannels[i].data, hostOutputChannels[i].stride, frameCount ); /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } } framesProcessed += frameCount; framesToGo -= frameCount; }while( framesToGo > 0 ); return framesProcessed; } /* CopyTempOutputBuffersToHostOutputBuffers is called from AdaptingProcess to copy frames from tempOutputBuffer to hostOutputChannels. This includes data conversion and interleaving. */ static void CopyTempOutputBuffersToHostOutputBuffers( PaUtilBufferProcessor *bp) { unsigned long maxFramesToCopy; PaUtilChannelDescriptor *hostOutputChannels; unsigned int frameCount; unsigned char *srcBytePtr; unsigned int srcSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */ unsigned int srcChannelStrideBytes; /* stride from one channel to the next, in bytes */ unsigned int i; /* copy frames from user to host output buffers */ while( bp->framesInTempOutputBuffer > 0 && ((bp->hostOutputFrameCount[0] + bp->hostOutputFrameCount[1]) > 0) ) { maxFramesToCopy = bp->framesInTempOutputBuffer; /* select the output buffer set (1st or 2nd) */ if( bp->hostOutputFrameCount[0] > 0 ) { hostOutputChannels = bp->hostOutputChannels[0]; frameCount = PA_MIN_( bp->hostOutputFrameCount[0], maxFramesToCopy ); } else { hostOutputChannels = bp->hostOutputChannels[1]; frameCount = PA_MIN_( bp->hostOutputFrameCount[1], maxFramesToCopy ); } if( bp->userOutputIsInterleaved ) { srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) + bp->bytesPerUserOutputSample * bp->outputChannelCount * (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer); srcSampleStrideSamples = bp->outputChannelCount; srcChannelStrideBytes = bp->bytesPerUserOutputSample; } else /* user output is not interleaved */ { srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) + bp->bytesPerUserOutputSample * (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer); srcSampleStrideSamples = 1; srcChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserOutputSample; } for( i=0; ioutputChannelCount; ++i ) { assert( hostOutputChannels[i].data != NULL ); bp->outputConverter( hostOutputChannels[i].data, hostOutputChannels[i].stride, srcBytePtr, srcSampleStrideSamples, frameCount, &bp->ditherGenerator ); srcBytePtr += srcChannelStrideBytes; /* skip to next source channel */ /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } if( bp->hostOutputFrameCount[0] > 0 ) bp->hostOutputFrameCount[0] -= frameCount; else bp->hostOutputFrameCount[1] -= frameCount; bp->framesInTempOutputBuffer -= frameCount; } } /* AdaptingProcess is a full duplex adapting buffer processor. It converts data from the temporary output buffer into the host output buffers, then from the host input buffers into the temporary input buffers. Calling the streamCallback when necessary. When processPartialUserBuffers is 0, all available input data will be consumed and all available output space will be filled. When processPartialUserBuffers is non-zero, as many full user buffers as possible will be processed, but partial buffers will not be consumed. */ static unsigned long AdaptingProcess( PaUtilBufferProcessor *bp, int *streamCallbackResult, int processPartialUserBuffers ) { void *userInput, *userOutput; unsigned long framesProcessed = 0; unsigned long framesAvailable; unsigned long endProcessingMinFrameCount; unsigned long maxFramesToCopy; PaUtilChannelDescriptor *hostInputChannels, *hostOutputChannels; unsigned int frameCount; unsigned char *destBytePtr; unsigned int destSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */ unsigned int destChannelStrideBytes; /* stride from one channel to the next, in bytes */ unsigned int i, j; framesAvailable = bp->hostInputFrameCount[0] + bp->hostInputFrameCount[1];/* this is assumed to be the same as the output buffer's frame count */ if( processPartialUserBuffers ) endProcessingMinFrameCount = 0; else endProcessingMinFrameCount = (bp->framesPerUserBuffer - 1); /* Fill host output with remaining frames in user output (tempOutputBuffer) */ CopyTempOutputBuffersToHostOutputBuffers( bp ); while( framesAvailable > endProcessingMinFrameCount ) { if( bp->framesInTempOutputBuffer == 0 && *streamCallbackResult != paContinue ) { /* the callback will not be called any more, so zero what remains of the host output buffers */ for( i=0; i<2; ++i ) { frameCount = bp->hostOutputFrameCount[i]; if( frameCount > 0 ) { hostOutputChannels = bp->hostOutputChannels[i]; for( j=0; joutputChannelCount; ++j ) { bp->outputZeroer( hostOutputChannels[j].data, hostOutputChannels[j].stride, frameCount ); /* advance dest ptr for next iteration */ hostOutputChannels[j].data = ((unsigned char*)hostOutputChannels[j].data) + frameCount * hostOutputChannels[j].stride * bp->bytesPerHostOutputSample; } bp->hostOutputFrameCount[i] = 0; } } } /* copy frames from host to user input buffers */ while( bp->framesInTempInputBuffer < bp->framesPerUserBuffer && ((bp->hostInputFrameCount[0] + bp->hostInputFrameCount[1]) > 0) ) { maxFramesToCopy = bp->framesPerUserBuffer - bp->framesInTempInputBuffer; /* select the input buffer set (1st or 2nd) */ if( bp->hostInputFrameCount[0] > 0 ) { hostInputChannels = bp->hostInputChannels[0]; frameCount = PA_MIN_( bp->hostInputFrameCount[0], maxFramesToCopy ); } else { hostInputChannels = bp->hostInputChannels[1]; frameCount = PA_MIN_( bp->hostInputFrameCount[1], maxFramesToCopy ); } /* configure conversion destination pointers */ if( bp->userInputIsInterleaved ) { destBytePtr = ((unsigned char*)bp->tempInputBuffer) + bp->bytesPerUserInputSample * bp->inputChannelCount * bp->framesInTempInputBuffer; destSampleStrideSamples = bp->inputChannelCount; destChannelStrideBytes = bp->bytesPerUserInputSample; } else /* user input is not interleaved */ { destBytePtr = ((unsigned char*)bp->tempInputBuffer) + bp->bytesPerUserInputSample * bp->framesInTempInputBuffer; destSampleStrideSamples = 1; destChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserInputSample; } for( i=0; iinputChannelCount; ++i ) { bp->inputConverter( destBytePtr, destSampleStrideSamples, hostInputChannels[i].data, hostInputChannels[i].stride, frameCount, &bp->ditherGenerator ); destBytePtr += destChannelStrideBytes; /* skip to next destination channel */ /* advance src ptr for next iteration */ hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) + frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample; } if( bp->hostInputFrameCount[0] > 0 ) bp->hostInputFrameCount[0] -= frameCount; else bp->hostInputFrameCount[1] -= frameCount; bp->framesInTempInputBuffer += frameCount; /* update framesAvailable and framesProcessed based on input consumed unless something is very wrong this will also correspond to the amount of output generated */ framesAvailable -= frameCount; framesProcessed += frameCount; } /* call streamCallback */ if( bp->framesInTempInputBuffer == bp->framesPerUserBuffer && bp->framesInTempOutputBuffer == 0 ) { if( *streamCallbackResult == paContinue ) { /* setup userInput */ if( bp->userInputIsInterleaved ) { userInput = bp->tempInputBuffer; } else /* user input is not interleaved */ { for( i = 0; i < bp->inputChannelCount; ++i ) { bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) + i * bp->framesPerUserBuffer * bp->bytesPerUserInputSample; } userInput = bp->tempInputBufferPtrs; } /* setup userOutput */ if( bp->userOutputIsInterleaved ) { userOutput = bp->tempOutputBuffer; } else /* user output is not interleaved */ { for( i = 0; i < bp->outputChannelCount; ++i ) { bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) + i * bp->framesPerUserBuffer * bp->bytesPerUserOutputSample; } userOutput = bp->tempOutputBufferPtrs; } /* call streamCallback */ *streamCallbackResult = bp->streamCallback( userInput, userOutput, bp->framesPerUserBuffer, bp->timeInfo, bp->callbackStatusFlags, bp->userData ); bp->timeInfo->inputBufferAdcTime += bp->framesPerUserBuffer * bp->samplePeriod; bp->timeInfo->outputBufferDacTime += bp->framesPerUserBuffer * bp->samplePeriod; bp->framesInTempInputBuffer = 0; if( *streamCallbackResult == paAbort ) bp->framesInTempOutputBuffer = 0; else bp->framesInTempOutputBuffer = bp->framesPerUserBuffer; } else { /* paComplete or paAbort has already been called. */ bp->framesInTempInputBuffer = 0; } } /* copy frames from user (tempOutputBuffer) to host output buffers (hostOutputChannels) Means to process the user output provided by the callback. Has to be called after each callback. */ CopyTempOutputBuffersToHostOutputBuffers( bp ); } return framesProcessed; } unsigned long PaUtil_EndBufferProcessing( PaUtilBufferProcessor* bp, int *streamCallbackResult ) { unsigned long framesToProcess, framesToGo; unsigned long framesProcessed = 0; if( bp->inputChannelCount != 0 && bp->outputChannelCount != 0 && bp->hostInputChannels[0][0].data /* input was supplied (see PaUtil_SetNoInput) */ && bp->hostOutputChannels[0][0].data /* output was supplied (see PaUtil_SetNoOutput) */ ) { assert( (bp->hostInputFrameCount[0] + bp->hostInputFrameCount[1]) == (bp->hostOutputFrameCount[0] + bp->hostOutputFrameCount[1]) ); } assert( *streamCallbackResult == paContinue || *streamCallbackResult == paComplete || *streamCallbackResult == paAbort ); /* don't forget to pass in a valid callback result value */ if( bp->useNonAdaptingProcess ) { if( bp->inputChannelCount != 0 && bp->outputChannelCount != 0 ) { /* full duplex non-adapting process, splice buffers if they are different lengths */ framesToGo = bp->hostOutputFrameCount[0] + bp->hostOutputFrameCount[1]; /* relies on assert above for input/output equivalence */ do{ unsigned long noInputInputFrameCount; unsigned long *hostInputFrameCount; PaUtilChannelDescriptor *hostInputChannels; unsigned long noOutputOutputFrameCount; unsigned long *hostOutputFrameCount; PaUtilChannelDescriptor *hostOutputChannels; unsigned long framesProcessedThisIteration; if( !bp->hostInputChannels[0][0].data ) { /* no input was supplied (see PaUtil_SetNoInput) NonAdaptingProcess knows how to deal with this */ noInputInputFrameCount = framesToGo; hostInputFrameCount = &noInputInputFrameCount; hostInputChannels = 0; } else if( bp->hostInputFrameCount[0] != 0 ) { hostInputFrameCount = &bp->hostInputFrameCount[0]; hostInputChannels = bp->hostInputChannels[0]; } else { hostInputFrameCount = &bp->hostInputFrameCount[1]; hostInputChannels = bp->hostInputChannels[1]; } if( !bp->hostOutputChannels[0][0].data ) { /* no output was supplied (see PaUtil_SetNoOutput) NonAdaptingProcess knows how to deal with this */ noOutputOutputFrameCount = framesToGo; hostOutputFrameCount = &noOutputOutputFrameCount; hostOutputChannels = 0; } if( bp->hostOutputFrameCount[0] != 0 ) { hostOutputFrameCount = &bp->hostOutputFrameCount[0]; hostOutputChannels = bp->hostOutputChannels[0]; } else { hostOutputFrameCount = &bp->hostOutputFrameCount[1]; hostOutputChannels = bp->hostOutputChannels[1]; } framesToProcess = PA_MIN_( *hostInputFrameCount, *hostOutputFrameCount ); assert( framesToProcess != 0 ); framesProcessedThisIteration = NonAdaptingProcess( bp, streamCallbackResult, hostInputChannels, hostOutputChannels, framesToProcess ); *hostInputFrameCount -= framesProcessedThisIteration; *hostOutputFrameCount -= framesProcessedThisIteration; framesProcessed += framesProcessedThisIteration; framesToGo -= framesProcessedThisIteration; }while( framesToGo > 0 ); } else { /* half duplex non-adapting process, just process 1st and 2nd buffer */ /* process first buffer */ framesToProcess = (bp->inputChannelCount != 0) ? bp->hostInputFrameCount[0] : bp->hostOutputFrameCount[0]; framesProcessed = NonAdaptingProcess( bp, streamCallbackResult, bp->hostInputChannels[0], bp->hostOutputChannels[0], framesToProcess ); /* process second buffer if provided */ framesToProcess = (bp->inputChannelCount != 0) ? bp->hostInputFrameCount[1] : bp->hostOutputFrameCount[1]; if( framesToProcess > 0 ) { framesProcessed += NonAdaptingProcess( bp, streamCallbackResult, bp->hostInputChannels[1], bp->hostOutputChannels[1], framesToProcess ); } } } else /* block adaption necessary*/ { if( bp->inputChannelCount != 0 && bp->outputChannelCount != 0 ) { /* full duplex */ if( bp->hostBufferSizeMode == paUtilVariableHostBufferSizePartialUsageAllowed ) { framesProcessed = AdaptingProcess( bp, streamCallbackResult, 0 /* dont process partial user buffers */ ); } else { framesProcessed = AdaptingProcess( bp, streamCallbackResult, 1 /* process partial user buffers */ ); } } else if( bp->inputChannelCount != 0 ) { /* input only */ framesToProcess = bp->hostInputFrameCount[0]; framesProcessed = AdaptingInputOnlyProcess( bp, streamCallbackResult, bp->hostInputChannels[0], framesToProcess ); framesToProcess = bp->hostInputFrameCount[1]; if( framesToProcess > 0 ) { framesProcessed += AdaptingInputOnlyProcess( bp, streamCallbackResult, bp->hostInputChannels[1], framesToProcess ); } } else { /* output only */ framesToProcess = bp->hostOutputFrameCount[0]; framesProcessed = AdaptingOutputOnlyProcess( bp, streamCallbackResult, bp->hostOutputChannels[0], framesToProcess ); framesToProcess = bp->hostOutputFrameCount[1]; if( framesToProcess > 0 ) { framesProcessed += AdaptingOutputOnlyProcess( bp, streamCallbackResult, bp->hostOutputChannels[1], framesToProcess ); } } } return framesProcessed; } int PaUtil_IsBufferProcessorOutputEmpty( PaUtilBufferProcessor* bp ) { return (bp->framesInTempOutputBuffer) ? 0 : 1; } unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bp, void **buffer, unsigned long frameCount ) { PaUtilChannelDescriptor *hostInputChannels; unsigned int framesToCopy; unsigned char *destBytePtr; void **nonInterleavedDestPtrs; unsigned int destSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */ unsigned int destChannelStrideBytes; /* stride from one channel to the next, in bytes */ unsigned int i; hostInputChannels = bp->hostInputChannels[0]; framesToCopy = PA_MIN_( bp->hostInputFrameCount[0], frameCount ); if( bp->userInputIsInterleaved ) { destBytePtr = (unsigned char*)*buffer; destSampleStrideSamples = bp->inputChannelCount; destChannelStrideBytes = bp->bytesPerUserInputSample; for( i=0; iinputChannelCount; ++i ) { bp->inputConverter( destBytePtr, destSampleStrideSamples, hostInputChannels[i].data, hostInputChannels[i].stride, framesToCopy, &bp->ditherGenerator ); destBytePtr += destChannelStrideBytes; /* skip to next dest channel */ /* advance source ptr for next iteration */ hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) + framesToCopy * hostInputChannels[i].stride * bp->bytesPerHostInputSample; } /* advance callers dest pointer (buffer) */ *buffer = ((unsigned char *)*buffer) + framesToCopy * bp->inputChannelCount * bp->bytesPerUserInputSample; } else { /* user input is not interleaved */ nonInterleavedDestPtrs = (void**)*buffer; destSampleStrideSamples = 1; for( i=0; iinputChannelCount; ++i ) { destBytePtr = (unsigned char*)nonInterleavedDestPtrs[i]; bp->inputConverter( destBytePtr, destSampleStrideSamples, hostInputChannels[i].data, hostInputChannels[i].stride, framesToCopy, &bp->ditherGenerator ); /* advance callers dest pointer (nonInterleavedDestPtrs[i]) */ destBytePtr += bp->bytesPerUserInputSample * framesToCopy; nonInterleavedDestPtrs[i] = destBytePtr; /* advance source ptr for next iteration */ hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) + framesToCopy * hostInputChannels[i].stride * bp->bytesPerHostInputSample; } } bp->hostInputFrameCount[0] -= framesToCopy; return framesToCopy; } unsigned long PaUtil_CopyOutput( PaUtilBufferProcessor* bp, const void ** buffer, unsigned long frameCount ) { PaUtilChannelDescriptor *hostOutputChannels; unsigned int framesToCopy; unsigned char *srcBytePtr; void **nonInterleavedSrcPtrs; unsigned int srcSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */ unsigned int srcChannelStrideBytes; /* stride from one channel to the next, in bytes */ unsigned int i; hostOutputChannels = bp->hostOutputChannels[0]; framesToCopy = PA_MIN_( bp->hostOutputFrameCount[0], frameCount ); if( bp->userOutputIsInterleaved ) { srcBytePtr = (unsigned char*)*buffer; srcSampleStrideSamples = bp->outputChannelCount; srcChannelStrideBytes = bp->bytesPerUserOutputSample; for( i=0; ioutputChannelCount; ++i ) { bp->outputConverter( hostOutputChannels[i].data, hostOutputChannels[i].stride, srcBytePtr, srcSampleStrideSamples, framesToCopy, &bp->ditherGenerator ); srcBytePtr += srcChannelStrideBytes; /* skip to next source channel */ /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + framesToCopy * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } /* advance callers source pointer (buffer) */ *buffer = ((unsigned char *)*buffer) + framesToCopy * bp->outputChannelCount * bp->bytesPerUserOutputSample; } else { /* user output is not interleaved */ nonInterleavedSrcPtrs = (void**)*buffer; srcSampleStrideSamples = 1; for( i=0; ioutputChannelCount; ++i ) { srcBytePtr = (unsigned char*)nonInterleavedSrcPtrs[i]; bp->outputConverter( hostOutputChannels[i].data, hostOutputChannels[i].stride, srcBytePtr, srcSampleStrideSamples, framesToCopy, &bp->ditherGenerator ); /* advance callers source pointer (nonInterleavedSrcPtrs[i]) */ srcBytePtr += bp->bytesPerUserOutputSample * framesToCopy; nonInterleavedSrcPtrs[i] = srcBytePtr; /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + framesToCopy * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } } bp->hostOutputFrameCount[0] += framesToCopy; return framesToCopy; } unsigned long PaUtil_ZeroOutput( PaUtilBufferProcessor* bp, unsigned long frameCount ) { PaUtilChannelDescriptor *hostOutputChannels; unsigned int framesToZero; unsigned int i; hostOutputChannels = bp->hostOutputChannels[0]; framesToZero = PA_MIN_( bp->hostOutputFrameCount[0], frameCount ); for( i=0; ioutputChannelCount; ++i ) { bp->outputZeroer( hostOutputChannels[i].data, hostOutputChannels[i].stride, framesToZero ); /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + framesToZero * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } bp->hostOutputFrameCount[0] += framesToZero; return framesToZero; } praat-6.0.04/external/portaudio/pa_process.h000066400000000000000000000765441261542461700210770ustar00rootroot00000000000000#ifndef PA_PROCESS_H #define PA_PROCESS_H /* * $Id: pa_process.h 1668 2011-05-02 17:07:11Z rossb $ * Portable Audio I/O Library callback buffer processing adapters * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Phil Burk, Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Buffer Processor prototypes. A Buffer Processor performs buffer length adaption, coordinates sample format conversion, and interleaves/deinterleaves channels.

Overview

The "Buffer Processor" (PaUtilBufferProcessor) manages conversion of audio data from host buffers to user buffers and back again. Where required, the buffer processor takes care of converting between host and user sample formats, interleaving and deinterleaving multichannel buffers, and adapting between host and user buffers with different lengths. The buffer processor may be used with full and half duplex streams, for both callback streams and blocking read/write streams. One of the important capabilities provided by the buffer processor is the ability to adapt between user and host buffer sizes of different lengths with minimum latency. Although this task is relatively easy to perform when the host buffer size is an integer multiple of the user buffer size, the problem is more complicated when this is not the case - especially for full-duplex callback streams. Where necessary the adaption is implemented by internally buffering some input and/or output data. The buffer adation algorithm used by the buffer processor was originally implemented by Stephan Letz for the ASIO version of PortAudio, and is described in his Callback_adaption_.pdf which is included in the distribution. The buffer processor performs sample conversion using the functions provided by pa_converters.c. The following sections provide an overview of how to use the buffer processor. Interested readers are advised to consult the host API implementations for examples of buffer processor usage.

Initialization, resetting and termination

When a stream is opened, the buffer processor should be initialized using PaUtil_InitializeBufferProcessor. This function initializes internal state and allocates temporary buffers as neccesary according to the supplied configuration parameters. Some of the parameters correspond to those requested by the user in their call to Pa_OpenStream(), others reflect the requirements of the host API implementation - they indicate host buffer sizes, formats, and the type of buffering which the Host API uses. The buffer processor should be initialized for callback streams and blocking read/write streams. Call PaUtil_ResetBufferProcessor to clear any sample data which is present in the buffer processor before starting to use it (for example when Pa_StartStream is called). When the buffer processor is no longer used call PaUtil_TerminateBufferProcessor.

Using the buffer processor for a callback stream

The buffer processor's role in a callback stream is to take host input buffers process them with the stream callback, and fill host output buffers. For a full duplex stream, the buffer processor handles input and output simultaneously due to the requirements of the minimum-latency buffer adation algorithm. When a host buffer becomes available, the implementation should call the buffer processor to process the buffer. The buffer processor calls the stream callback to consume and/or produce audio data as necessary. The buffer processor will convert sample formats, interleave/deinterleave channels, and slice or chunk the data to the appropriate buffer lengths according to the requirements of the stream callback and the host API. To process a host buffer (or a pair of host buffers for a full-duplex stream) use the following calling sequence: -# Call PaUtil_BeginBufferProcessing -# For a stream which takes input: - Call PaUtil_SetInputFrameCount with the number of frames in the host input buffer. - Call one of the following functions one or more times to tell the buffer processor about the host input buffer(s): PaUtil_SetInputChannel, PaUtil_SetInterleavedInputChannels, PaUtil_SetNonInterleavedInputChannel. Which function you call will depend on whether the host buffer(s) are interleaved or not. - If the available host data is split accross two buffers (for example a data range at the end of a circular buffer and another range at the beginning of the circular buffer), also call PaUtil_Set2ndInputFrameCount, PaUtil_Set2ndInputChannel, PaUtil_Set2ndInterleavedInputChannels, PaUtil_Set2ndNonInterleavedInputChannel as necessary to tell the buffer processor about the second buffer. -# For a stream which generates output: - Call PaUtil_SetOutputFrameCount with the number of frames in the host output buffer. - Call one of the following functions one or more times to tell the buffer processor about the host output buffer(s): PaUtil_SetOutputChannel, PaUtil_SetInterleavedOutputChannels, PaUtil_SetNonInterleavedOutputChannel. Which function you call will depend on whether the host buffer(s) are interleaved or not. - If the available host output buffer space is split accross two buffers (for example a data range at the end of a circular buffer and another range at the beginning of the circular buffer), call PaUtil_Set2ndOutputFrameCount, PaUtil_Set2ndOutputChannel, PaUtil_Set2ndInterleavedOutputChannels, PaUtil_Set2ndNonInterleavedOutputChannel as necessary to tell the buffer processor about the second buffer. -# Call PaUtil_EndBufferProcessing, this function performs the actual data conversion and processing.

Using the buffer processor for a blocking read/write stream

Blocking read/write streams use the buffer processor to convert and copy user output data to a host buffer, and to convert and copy host input data to the user's buffer. The buffer processor does not perform any buffer adaption. When using the buffer processor in a blocking read/write stream the input and output conversion are performed separately by the PaUtil_CopyInput and PaUtil_CopyOutput functions. To copy data from a host input buffer to the buffer(s) which the user supplies to Pa_ReadStream, use the following calling sequence. - Repeat the following three steps until the user buffer(s) have been filled with samples from the host input buffers: -# Call PaUtil_SetInputFrameCount with the number of frames in the host input buffer. -# Call one of the following functions one or more times to tell the buffer processor about the host input buffer(s): PaUtil_SetInputChannel, PaUtil_SetInterleavedInputChannels, PaUtil_SetNonInterleavedInputChannel. Which function you call will depend on whether the host buffer(s) are interleaved or not. -# Call PaUtil_CopyInput with the user buffer pointer (or a copy of the array of buffer pointers for a non-interleaved stream) passed to Pa_ReadStream, along with the number of frames in the user buffer(s). Be careful to pass a copy of the user buffer pointers to PaUtil_CopyInput because PaUtil_CopyInput advances the pointers to the start of the next region to copy. - PaUtil_CopyInput will not copy more data than is available in the host buffer(s), so the above steps need to be repeated until the user buffer(s) are full. To copy data to the host output buffer from the user buffers(s) supplied to Pa_WriteStream use the following calling sequence. - Repeat the following three steps until all frames from the user buffer(s) have been copied to the host API: -# Call PaUtil_SetOutputFrameCount with the number of frames in the host output buffer. -# Call one of the following functions one or more times to tell the buffer processor about the host output buffer(s): PaUtil_SetOutputChannel, PaUtil_SetInterleavedOutputChannels, PaUtil_SetNonInterleavedOutputChannel. Which function you call will depend on whether the host buffer(s) are interleaved or not. -# Call PaUtil_CopyOutput with the user buffer pointer (or a copy of the array of buffer pointers for a non-interleaved stream) passed to Pa_WriteStream, along with the number of frames in the user buffer(s). Be careful to pass a copy of the user buffer pointers to PaUtil_CopyOutput because PaUtil_CopyOutput advances the pointers to the start of the next region to copy. - PaUtil_CopyOutput will not copy more data than fits in the host buffer(s), so the above steps need to be repeated until all user data is copied. */ #include "portaudio.h" #include "pa_converters.h" #include "pa_dither.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** @brief Mode flag passed to PaUtil_InitializeBufferProcessor indicating the type of buffering that the host API uses. The mode used depends on whether the host API or the implementation manages the buffers, and how these buffers are used (scatter gather, circular buffer). */ typedef enum { /** The host buffer size is a fixed known size. */ paUtilFixedHostBufferSize, /** The host buffer size may vary, but has a known maximum size. */ paUtilBoundedHostBufferSize, /** Nothing is known about the host buffer size. */ paUtilUnknownHostBufferSize, /** The host buffer size varies, and the client does not require the buffer processor to consume all of the input and fill all of the output buffer. This is useful when the implementation has access to the host API's circular buffer and only needs to consume/fill some of it, not necessarily all of it, with each call to the buffer processor. This is the only mode where PaUtil_EndBufferProcessing() may not consume the whole buffer. */ paUtilVariableHostBufferSizePartialUsageAllowed }PaUtilHostBufferSizeMode; /** @brief An auxilliary data structure used internally by the buffer processor to represent host input and output buffers. */ typedef struct PaUtilChannelDescriptor{ void *data; unsigned int stride; /**< stride in samples, not bytes */ }PaUtilChannelDescriptor; /** @brief The main buffer processor data structure. Allocate one of these, initialize it with PaUtil_InitializeBufferProcessor and terminate it with PaUtil_TerminateBufferProcessor. */ typedef struct { unsigned long framesPerUserBuffer; unsigned long framesPerHostBuffer; PaUtilHostBufferSizeMode hostBufferSizeMode; int useNonAdaptingProcess; int userOutputSampleFormatIsEqualToHost; int userInputSampleFormatIsEqualToHost; unsigned long framesPerTempBuffer; unsigned int inputChannelCount; unsigned int bytesPerHostInputSample; unsigned int bytesPerUserInputSample; int userInputIsInterleaved; PaUtilConverter *inputConverter; PaUtilZeroer *inputZeroer; unsigned int outputChannelCount; unsigned int bytesPerHostOutputSample; unsigned int bytesPerUserOutputSample; int userOutputIsInterleaved; PaUtilConverter *outputConverter; PaUtilZeroer *outputZeroer; unsigned long initialFramesInTempInputBuffer; unsigned long initialFramesInTempOutputBuffer; void *tempInputBuffer; /**< used for slips, block adaption, and conversion. */ void **tempInputBufferPtrs; /**< storage for non-interleaved buffer pointers, NULL for interleaved user input */ unsigned long framesInTempInputBuffer; /**< frames remaining in input buffer from previous adaption iteration */ void *tempOutputBuffer; /**< used for slips, block adaption, and conversion. */ void **tempOutputBufferPtrs; /**< storage for non-interleaved buffer pointers, NULL for interleaved user output */ unsigned long framesInTempOutputBuffer; /**< frames remaining in input buffer from previous adaption iteration */ PaStreamCallbackTimeInfo *timeInfo; PaStreamCallbackFlags callbackStatusFlags; int hostInputIsInterleaved; unsigned long hostInputFrameCount[2]; PaUtilChannelDescriptor *hostInputChannels[2]; /**< pointers to arrays of channel descriptors. pointers are NULL for half-duplex output processing. hostInputChannels[i].data is NULL when the caller calls PaUtil_SetNoInput() */ int hostOutputIsInterleaved; unsigned long hostOutputFrameCount[2]; PaUtilChannelDescriptor *hostOutputChannels[2]; /**< pointers to arrays of channel descriptors. pointers are NULL for half-duplex input processing. hostOutputChannels[i].data is NULL when the caller calls PaUtil_SetNoOutput() */ PaUtilTriangularDitherGenerator ditherGenerator; double samplePeriod; PaStreamCallback *streamCallback; void *userData; } PaUtilBufferProcessor; /** @name Initialization, termination, resetting and info */ /*@{*/ /** Initialize a buffer processor's representation stored in a PaUtilBufferProcessor structure. Be sure to call PaUtil_TerminateBufferProcessor after finishing with a buffer processor. @param bufferProcessor The buffer processor structure to initialize. @param inputChannelCount The number of input channels as passed to Pa_OpenStream or 0 for an output-only stream. @param userInputSampleFormat Format of user input samples, as passed to Pa_OpenStream. This parameter is ignored for ouput-only streams. @param hostInputSampleFormat Format of host input samples. This parameter is ignored for output-only streams. See note about host buffer interleave below. @param outputChannelCount The number of output channels as passed to Pa_OpenStream or 0 for an input-only stream. @param userOutputSampleFormat Format of user output samples, as passed to Pa_OpenStream. This parameter is ignored for input-only streams. @param hostOutputSampleFormat Format of host output samples. This parameter is ignored for input-only streams. See note about host buffer interleave below. @param sampleRate Sample rate of the stream. The more accurate this is the better - it is used for updating time stamps when adapting buffers. @param streamFlags Stream flags as passed to Pa_OpenStream, this parameter is used for selecting special sample conversion options such as clipping and dithering. @param framesPerUserBuffer Number of frames per user buffer, as requested by the framesPerBuffer parameter to Pa_OpenStream. This parameter may be zero to indicate that the user will accept any (and varying) buffer sizes. @param framesPerHostBuffer Specifies the number of frames per host buffer for the fixed buffer size mode, and the maximum number of frames per host buffer for the bounded host buffer size mode. It is ignored for the other modes. @param hostBufferSizeMode A mode flag indicating the size variability of host buffers that will be passed to the buffer processor. See PaUtilHostBufferSizeMode for further details. @param streamCallback The user stream callback passed to Pa_OpenStream. @param userData The user data field passed to Pa_OpenStream. @note The interleave flag is ignored for host buffer formats. Host interleave is determined by the use of different SetInput and SetOutput functions. @return An error code indicating whether the initialization was successful. If the error code is not PaNoError, the buffer processor was not initialized and should not be used. @see Pa_OpenStream, PaUtilHostBufferSizeMode, PaUtil_TerminateBufferProcessor */ PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bufferProcessor, int inputChannelCount, PaSampleFormat userInputSampleFormat, PaSampleFormat hostInputSampleFormat, int outputChannelCount, PaSampleFormat userOutputSampleFormat, PaSampleFormat hostOutputSampleFormat, double sampleRate, PaStreamFlags streamFlags, unsigned long framesPerUserBuffer, /* 0 indicates don't care */ unsigned long framesPerHostBuffer, PaUtilHostBufferSizeMode hostBufferSizeMode, PaStreamCallback *streamCallback, void *userData ); /** Terminate a buffer processor's representation. Deallocates any temporary buffers allocated by PaUtil_InitializeBufferProcessor. @param bufferProcessor The buffer processor structure to terminate. @see PaUtil_InitializeBufferProcessor. */ void PaUtil_TerminateBufferProcessor( PaUtilBufferProcessor* bufferProcessor ); /** Clear any internally buffered data. If you call PaUtil_InitializeBufferProcessor in your OpenStream routine, make sure you call PaUtil_ResetBufferProcessor in your StartStream call. @param bufferProcessor The buffer processor to reset. */ void PaUtil_ResetBufferProcessor( PaUtilBufferProcessor* bufferProcessor ); /** Retrieve the input latency of a buffer processor, in frames. @param bufferProcessor The buffer processor examine. @return The input latency introduced by the buffer processor, in frames. @see PaUtil_GetBufferProcessorOutputLatencyFrames */ unsigned long PaUtil_GetBufferProcessorInputLatencyFrames( PaUtilBufferProcessor* bufferProcessor ); /** Retrieve the output latency of a buffer processor, in frames. @param bufferProcessor The buffer processor examine. @return The output latency introduced by the buffer processor, in frames. @see PaUtil_GetBufferProcessorInputLatencyFrames */ unsigned long PaUtil_GetBufferProcessorOutputLatencyFrames( PaUtilBufferProcessor* bufferProcessor ); /*@}*/ /** @name Host buffer pointer configuration Functions to set host input and output buffers, used by both callback streams and blocking read/write streams. */ /*@{*/ /** Set the number of frames in the input host buffer(s) specified by the PaUtil_Set*InputChannel functions. @param bufferProcessor The buffer processor. @param frameCount The number of host input frames. A 0 frameCount indicates to use the framesPerHostBuffer value passed to PaUtil_InitializeBufferProcessor. @see PaUtil_SetNoInput, PaUtil_SetInputChannel, PaUtil_SetInterleavedInputChannels, PaUtil_SetNonInterleavedInputChannel */ void PaUtil_SetInputFrameCount( PaUtilBufferProcessor* bufferProcessor, unsigned long frameCount ); /** Indicate that no input is avalable. This function should be used when priming the output of a full-duplex stream opened with the paPrimeOutputBuffersUsingStreamCallback flag. Note that it is not necessary to call this or any othe PaUtil_Set*Input* functions for ouput-only streams. @param bufferProcessor The buffer processor. */ void PaUtil_SetNoInput( PaUtilBufferProcessor* bufferProcessor ); /** Provide the buffer processor with a pointer to a host input channel. @param bufferProcessor The buffer processor. @param channel The channel number. @param data The buffer. @param stride The stride from one sample to the next, in samples. For interleaved host buffers, the stride will usually be the same as the number of channels in the buffer. */ void PaUtil_SetInputChannel( PaUtilBufferProcessor* bufferProcessor, unsigned int channel, void *data, unsigned int stride ); /** Provide the buffer processor with a pointer to an number of interleaved host input channels. @param bufferProcessor The buffer processor. @param firstChannel The first channel number. @param data The buffer. @param channelCount The number of interleaved channels in the buffer. If channelCount is zero, the number of channels specified to PaUtil_InitializeBufferProcessor will be used. */ void PaUtil_SetInterleavedInputChannels( PaUtilBufferProcessor* bufferProcessor, unsigned int firstChannel, void *data, unsigned int channelCount ); /** Provide the buffer processor with a pointer to one non-interleaved host output channel. @param bufferProcessor The buffer processor. @param channel The channel number. @param data The buffer. */ void PaUtil_SetNonInterleavedInputChannel( PaUtilBufferProcessor* bufferProcessor, unsigned int channel, void *data ); /** Use for the second buffer half when the input buffer is split in two halves. @see PaUtil_SetInputFrameCount */ void PaUtil_Set2ndInputFrameCount( PaUtilBufferProcessor* bufferProcessor, unsigned long frameCount ); /** Use for the second buffer half when the input buffer is split in two halves. @see PaUtil_SetInputChannel */ void PaUtil_Set2ndInputChannel( PaUtilBufferProcessor* bufferProcessor, unsigned int channel, void *data, unsigned int stride ); /** Use for the second buffer half when the input buffer is split in two halves. @see PaUtil_SetInterleavedInputChannels */ void PaUtil_Set2ndInterleavedInputChannels( PaUtilBufferProcessor* bufferProcessor, unsigned int firstChannel, void *data, unsigned int channelCount ); /** Use for the second buffer half when the input buffer is split in two halves. @see PaUtil_SetNonInterleavedInputChannel */ void PaUtil_Set2ndNonInterleavedInputChannel( PaUtilBufferProcessor* bufferProcessor, unsigned int channel, void *data ); /** Set the number of frames in the output host buffer(s) specified by the PaUtil_Set*OutputChannel functions. @param bufferProcessor The buffer processor. @param frameCount The number of host output frames. A 0 frameCount indicates to use the framesPerHostBuffer value passed to PaUtil_InitializeBufferProcessor. @see PaUtil_SetOutputChannel, PaUtil_SetInterleavedOutputChannels, PaUtil_SetNonInterleavedOutputChannel */ void PaUtil_SetOutputFrameCount( PaUtilBufferProcessor* bufferProcessor, unsigned long frameCount ); /** Indicate that the output will be discarded. This function should be used when implementing the paNeverDropInput mode for full duplex streams. @param bufferProcessor The buffer processor. */ void PaUtil_SetNoOutput( PaUtilBufferProcessor* bufferProcessor ); /** Provide the buffer processor with a pointer to a host output channel. @param bufferProcessor The buffer processor. @param channel The channel number. @param data The buffer. @param stride The stride from one sample to the next, in samples. For interleaved host buffers, the stride will usually be the same as the number of channels in the buffer. */ void PaUtil_SetOutputChannel( PaUtilBufferProcessor* bufferProcessor, unsigned int channel, void *data, unsigned int stride ); /** Provide the buffer processor with a pointer to a number of interleaved host output channels. @param bufferProcessor The buffer processor. @param firstChannel The first channel number. @param data The buffer. @param channelCount The number of interleaved channels in the buffer. If channelCount is zero, the number of channels specified to PaUtil_InitializeBufferProcessor will be used. */ void PaUtil_SetInterleavedOutputChannels( PaUtilBufferProcessor* bufferProcessor, unsigned int firstChannel, void *data, unsigned int channelCount ); /** Provide the buffer processor with a pointer to one non-interleaved host output channel. @param bufferProcessor The buffer processor. @param channel The channel number. @param data The buffer. */ void PaUtil_SetNonInterleavedOutputChannel( PaUtilBufferProcessor* bufferProcessor, unsigned int channel, void *data ); /** Use for the second buffer half when the output buffer is split in two halves. @see PaUtil_SetOutputFrameCount */ void PaUtil_Set2ndOutputFrameCount( PaUtilBufferProcessor* bufferProcessor, unsigned long frameCount ); /** Use for the second buffer half when the output buffer is split in two halves. @see PaUtil_SetOutputChannel */ void PaUtil_Set2ndOutputChannel( PaUtilBufferProcessor* bufferProcessor, unsigned int channel, void *data, unsigned int stride ); /** Use for the second buffer half when the output buffer is split in two halves. @see PaUtil_SetInterleavedOutputChannels */ void PaUtil_Set2ndInterleavedOutputChannels( PaUtilBufferProcessor* bufferProcessor, unsigned int firstChannel, void *data, unsigned int channelCount ); /** Use for the second buffer half when the output buffer is split in two halves. @see PaUtil_SetNonInterleavedOutputChannel */ void PaUtil_Set2ndNonInterleavedOutputChannel( PaUtilBufferProcessor* bufferProcessor, unsigned int channel, void *data ); /*@}*/ /** @name Buffer processing functions for callback streams */ /*@{*/ /** Commence processing a host buffer (or a pair of host buffers in the full-duplex case) for a callback stream. @param bufferProcessor The buffer processor. @param timeInfo Timing information for the first sample of the host buffer(s). This information may be adjusted when buffer adaption is being performed. @param callbackStatusFlags Flags indicating whether underruns and overruns have occurred since the last time the buffer processor was called. */ void PaUtil_BeginBufferProcessing( PaUtilBufferProcessor* bufferProcessor, PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags callbackStatusFlags ); /** Finish processing a host buffer (or a pair of host buffers in the full-duplex case) for a callback stream. @param bufferProcessor The buffer processor. @param callbackResult On input, indicates a previous callback result, and on exit, the result of the user stream callback, if it is called. On entry callbackResult should contain one of { paContinue, paComplete, or paAbort}. If paComplete is passed, the stream callback will not be called but any audio that was generated by previous stream callbacks will be copied to the output buffer(s). You can check whether the buffer processor's internal buffer is empty by calling PaUtil_IsBufferProcessorOutputEmpty. If the stream callback is called its result is stored in *callbackResult. If the stream callback returns paComplete or paAbort, all output buffers will be full of valid data - some of which may be zeros to acount for data that wasn't generated by the terminating callback. @return The number of frames processed. This usually corresponds to the number of frames specified by the PaUtil_Set*FrameCount functions, exept in the paUtilVariableHostBufferSizePartialUsageAllowed buffer size mode when a smaller value may be returned. */ unsigned long PaUtil_EndBufferProcessing( PaUtilBufferProcessor* bufferProcessor, int *callbackResult ); /** Determine whether any callback generated output remains in the bufffer processor's internal buffers. This method may be used to determine when to continue calling PaUtil_EndBufferProcessing() after the callback has returned a callbackResult of paComplete. @param bufferProcessor The buffer processor. @return Returns non-zero when callback generated output remains in the internal buffer and zero (0) when there internal buffer contains no callback generated data. */ int PaUtil_IsBufferProcessorOutputEmpty( PaUtilBufferProcessor* bufferProcessor ); /*@}*/ /** @name Buffer processing functions for blocking read/write streams */ /*@{*/ /** Copy samples from host input channels set up by the PaUtil_Set*InputChannels functions to a user supplied buffer. This function is intended for use with blocking read/write streams. Copies the minimum of the number of user frames (specified by the frameCount parameter) and the number of available host frames (specified in a previous call to SetInputFrameCount()). @param bufferProcessor The buffer processor. @param buffer A pointer to the user buffer pointer, or a pointer to a pointer to an array of user buffer pointers for a non-interleaved stream. It is important that this parameter points to a copy of the user buffer pointers, not to the actual user buffer pointers, because this function updates the pointers before returning. @param frameCount The number of frames of data in the buffer(s) pointed to by the buffer parameter. @return The number of frames copied. The buffer pointer(s) pointed to by the buffer parameter are advanced to point to the frame(s) following the last one filled. */ unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bufferProcessor, void **buffer, unsigned long frameCount ); /* Copy samples from a user supplied buffer to host output channels set up by the PaUtil_Set*OutputChannels functions. This function is intended for use with blocking read/write streams. Copies the minimum of the number of user frames (specified by the frameCount parameter) and the number of host frames (specified in a previous call to SetOutputFrameCount()). @param bufferProcessor The buffer processor. @param buffer A pointer to the user buffer pointer, or a pointer to a pointer to an array of user buffer pointers for a non-interleaved stream. It is important that this parameter points to a copy of the user buffer pointers, not to the actual user buffer pointers, because this function updates the pointers before returning. @param frameCount The number of frames of data in the buffer(s) pointed to by the buffer parameter. @return The number of frames copied. The buffer pointer(s) pointed to by the buffer parameter are advanced to point to the frame(s) following the last one copied. */ unsigned long PaUtil_CopyOutput( PaUtilBufferProcessor* bufferProcessor, const void ** buffer, unsigned long frameCount ); /* Zero samples in host output channels set up by the PaUtil_Set*OutputChannels functions. This function is useful for flushing streams. Zeros the minimum of frameCount and the number of host frames specified in a previous call to SetOutputFrameCount(). @param bufferProcessor The buffer processor. @param frameCount The maximum number of frames to zero. @return The number of frames zeroed. */ unsigned long PaUtil_ZeroOutput( PaUtilBufferProcessor* bufferProcessor, unsigned long frameCount ); /*@}*/ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_PROCESS_H */ praat-6.0.04/external/portaudio/pa_ringbuffer.c000066400000000000000000000223551261542461700215340ustar00rootroot00000000000000/* * $Id: pa_ringbuffer.c 1738 2011-08-18 11:47:28Z rossb $ * Portable Audio I/O Library * Ring Buffer utility. * * Author: Phil Burk, http://www.softsynth.com * modified for SMP safety on Mac OS X by Bjorn Roche * modified for SMP safety on Linux by Leland Lucius * also, allowed for const where possible * modified for multiple-byte-sized data elements by Sven Fischer * * Note that this is safe only for a single-thread reader and a * single-thread writer. * * This program uses the PortAudio Portable Audio Library. * For more information see: http://www.portaudio.com * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src */ #include #include #include #include "pa_ringbuffer.h" #include #include "pa_memorybarrier.h" /*************************************************************************** * Initialize FIFO. * elementCount must be power of 2, returns -1 if not. */ ring_buffer_size_t PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementSizeBytes, ring_buffer_size_t elementCount, void *dataPtr ) { if( ((elementCount-1) & elementCount) != 0) return -1; /* Not Power of two. */ rbuf->bufferSize = elementCount; rbuf->buffer = (char *)dataPtr; PaUtil_FlushRingBuffer( rbuf ); rbuf->bigMask = (elementCount*2)-1; rbuf->smallMask = (elementCount)-1; rbuf->elementSizeBytes = elementSizeBytes; return 0; } /*************************************************************************** ** Return number of elements available for reading. */ ring_buffer_size_t PaUtil_GetRingBufferReadAvailable( const PaUtilRingBuffer *rbuf ) { return ( (rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask ); } /*************************************************************************** ** Return number of elements available for writing. */ ring_buffer_size_t PaUtil_GetRingBufferWriteAvailable( const PaUtilRingBuffer *rbuf ) { return ( rbuf->bufferSize - PaUtil_GetRingBufferReadAvailable(rbuf)); } /*************************************************************************** ** Clear buffer. Should only be called when buffer is NOT being read or written. */ void PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf ) { rbuf->writeIndex = rbuf->readIndex = 0; } /*************************************************************************** ** Get address of region(s) to which we can write data. ** If the region is contiguous, size2 will be zero. ** If non-contiguous, size2 will be the size of second region. ** Returns room available to be written or elementCount, whichever is smaller. */ ring_buffer_size_t PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount, void **dataPtr1, ring_buffer_size_t *sizePtr1, void **dataPtr2, ring_buffer_size_t *sizePtr2 ) { ring_buffer_size_t index; ring_buffer_size_t available = PaUtil_GetRingBufferWriteAvailable( rbuf ); if( elementCount > available ) elementCount = available; /* Check to see if write is not contiguous. */ index = rbuf->writeIndex & rbuf->smallMask; if( (index + elementCount) > rbuf->bufferSize ) { /* Write data in two blocks that wrap the buffer. */ ring_buffer_size_t firstHalf = rbuf->bufferSize - index; *dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes]; *sizePtr1 = firstHalf; *dataPtr2 = &rbuf->buffer[0]; *sizePtr2 = elementCount - firstHalf; } else { *dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes]; *sizePtr1 = elementCount; *dataPtr2 = NULL; *sizePtr2 = 0; } if( available ) PaUtil_FullMemoryBarrier(); /* (write-after-read) => full barrier */ return elementCount; } /*************************************************************************** */ ring_buffer_size_t PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount ) { /* ensure that previous writes are seen before we update the write index (write after write) */ PaUtil_WriteMemoryBarrier(); return rbuf->writeIndex = (rbuf->writeIndex + elementCount) & rbuf->bigMask; } /*************************************************************************** ** Get address of region(s) from which we can read data. ** If the region is contiguous, size2 will be zero. ** If non-contiguous, size2 will be the size of second region. ** Returns room available to be read or elementCount, whichever is smaller. */ ring_buffer_size_t PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount, void **dataPtr1, ring_buffer_size_t *sizePtr1, void **dataPtr2, ring_buffer_size_t *sizePtr2 ) { ring_buffer_size_t index; ring_buffer_size_t available = PaUtil_GetRingBufferReadAvailable( rbuf ); /* doesn't use memory barrier */ if( elementCount > available ) elementCount = available; /* Check to see if read is not contiguous. */ index = rbuf->readIndex & rbuf->smallMask; if( (index + elementCount) > rbuf->bufferSize ) { /* Write data in two blocks that wrap the buffer. */ ring_buffer_size_t firstHalf = rbuf->bufferSize - index; *dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes]; *sizePtr1 = firstHalf; *dataPtr2 = &rbuf->buffer[0]; *sizePtr2 = elementCount - firstHalf; } else { *dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes]; *sizePtr1 = elementCount; *dataPtr2 = NULL; *sizePtr2 = 0; } if( available ) PaUtil_ReadMemoryBarrier(); /* (read-after-read) => read barrier */ return elementCount; } /*************************************************************************** */ ring_buffer_size_t PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount ) { /* ensure that previous reads (copies out of the ring buffer) are always completed before updating (writing) the read index. (write-after-read) => full barrier */ PaUtil_FullMemoryBarrier(); return rbuf->readIndex = (rbuf->readIndex + elementCount) & rbuf->bigMask; } /*************************************************************************** ** Return elements written. */ ring_buffer_size_t PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, ring_buffer_size_t elementCount ) { ring_buffer_size_t size1, size2, numWritten; void *data1, *data2; numWritten = PaUtil_GetRingBufferWriteRegions( rbuf, elementCount, &data1, &size1, &data2, &size2 ); if( size2 > 0 ) { memcpy( data1, data, size1*rbuf->elementSizeBytes ); data = ((char *)data) + size1*rbuf->elementSizeBytes; memcpy( data2, data, size2*rbuf->elementSizeBytes ); } else { memcpy( data1, data, size1*rbuf->elementSizeBytes ); } PaUtil_AdvanceRingBufferWriteIndex( rbuf, numWritten ); return numWritten; } /*************************************************************************** ** Return elements read. */ ring_buffer_size_t PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, ring_buffer_size_t elementCount ) { ring_buffer_size_t size1, size2, numRead; void *data1, *data2; numRead = PaUtil_GetRingBufferReadRegions( rbuf, elementCount, &data1, &size1, &data2, &size2 ); if( size2 > 0 ) { memcpy( data, data1, size1*rbuf->elementSizeBytes ); data = ((char *)data) + size1*rbuf->elementSizeBytes; memcpy( data, data2, size2*rbuf->elementSizeBytes ); } else { memcpy( data, data1, size1*rbuf->elementSizeBytes ); } PaUtil_AdvanceRingBufferReadIndex( rbuf, numRead ); return numRead; } praat-6.0.04/external/portaudio/pa_ringbuffer.h000066400000000000000000000213051261542461700215330ustar00rootroot00000000000000#ifndef PA_RINGBUFFER_H #define PA_RINGBUFFER_H /* * $Id: pa_ringbuffer.h 1873 2012-10-07 19:00:11Z philburk $ * Portable Audio I/O Library * Ring Buffer utility. * * Author: Phil Burk, http://www.softsynth.com * modified for SMP safety on OS X by Bjorn Roche. * also allowed for const where possible. * modified for multiple-byte-sized data elements by Sven Fischer * * Note that this is safe only for a single-thread reader * and a single-thread writer. * * This program is distributed with the PortAudio Portable Audio Library. * For more information see: http://www.portaudio.com * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Single-reader single-writer lock-free ring buffer PaUtilRingBuffer is a ring buffer used to transport samples between different execution contexts (threads, OS callbacks, interrupt handlers) without requiring the use of any locks. This only works when there is a single reader and a single writer (ie. one thread or callback writes to the ring buffer, another thread or callback reads from it). The PaUtilRingBuffer structure manages a ring buffer containing N elements, where N must be a power of two. An element may be any size (specified in bytes). The memory area used to store the buffer elements must be allocated by the client prior to calling PaUtil_InitializeRingBuffer() and must outlive the use of the ring buffer. @note The ring buffer functions are not normally exposed in the PortAudio libraries. If you want to call them then you will need to add pa_ringbuffer.c to your application source code. */ #if defined(__APPLE__) #include typedef int32_t ring_buffer_size_t; #elif defined( __GNUC__ ) typedef long ring_buffer_size_t; #elif (_MSC_VER >= 1400) typedef long ring_buffer_size_t; #elif defined(_MSC_VER) || defined(__BORLANDC__) typedef long ring_buffer_size_t; #else typedef long ring_buffer_size_t; #endif #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ typedef struct PaUtilRingBuffer { ring_buffer_size_t bufferSize; /**< Number of elements in FIFO. Power of 2. Set by PaUtil_InitRingBuffer. */ volatile ring_buffer_size_t writeIndex; /**< Index of next writable element. Set by PaUtil_AdvanceRingBufferWriteIndex. */ volatile ring_buffer_size_t readIndex; /**< Index of next readable element. Set by PaUtil_AdvanceRingBufferReadIndex. */ ring_buffer_size_t bigMask; /**< Used for wrapping indices with extra bit to distinguish full/empty. */ ring_buffer_size_t smallMask; /**< Used for fitting indices to buffer. */ ring_buffer_size_t elementSizeBytes; /**< Number of bytes per element. */ char *buffer; /**< Pointer to the buffer containing the actual data. */ }PaUtilRingBuffer; /** Initialize Ring Buffer to empty state ready to have elements written to it. @param rbuf The ring buffer. @param elementSizeBytes The size of a single data element in bytes. @param elementCount The number of elements in the buffer (must be a power of 2). @param dataPtr A pointer to a previously allocated area where the data will be maintained. It must be elementCount*elementSizeBytes long. @return -1 if elementCount is not a power of 2, otherwise 0. */ ring_buffer_size_t PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementSizeBytes, ring_buffer_size_t elementCount, void *dataPtr ); /** Reset buffer to empty. Should only be called when buffer is NOT being read or written. @param rbuf The ring buffer. */ void PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf ); /** Retrieve the number of elements available in the ring buffer for writing. @param rbuf The ring buffer. @return The number of elements available for writing. */ ring_buffer_size_t PaUtil_GetRingBufferWriteAvailable( const PaUtilRingBuffer *rbuf ); /** Retrieve the number of elements available in the ring buffer for reading. @param rbuf The ring buffer. @return The number of elements available for reading. */ ring_buffer_size_t PaUtil_GetRingBufferReadAvailable( const PaUtilRingBuffer *rbuf ); /** Write data to the ring buffer. @param rbuf The ring buffer. @param data The address of new data to write to the buffer. @param elementCount The number of elements to be written. @return The number of elements written. */ ring_buffer_size_t PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, ring_buffer_size_t elementCount ); /** Read data from the ring buffer. @param rbuf The ring buffer. @param data The address where the data should be stored. @param elementCount The number of elements to be read. @return The number of elements read. */ ring_buffer_size_t PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, ring_buffer_size_t elementCount ); /** Get address of region(s) to which we can write data. @param rbuf The ring buffer. @param elementCount The number of elements desired. @param dataPtr1 The address where the first (or only) region pointer will be stored. @param sizePtr1 The address where the first (or only) region length will be stored. @param dataPtr2 The address where the second region pointer will be stored if the first region is too small to satisfy elementCount. @param sizePtr2 The address where the second region length will be stored if the first region is too small to satisfy elementCount. @return The room available to be written or elementCount, whichever is smaller. */ ring_buffer_size_t PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount, void **dataPtr1, ring_buffer_size_t *sizePtr1, void **dataPtr2, ring_buffer_size_t *sizePtr2 ); /** Advance the write index to the next location to be written. @param rbuf The ring buffer. @param elementCount The number of elements to advance. @return The new position. */ ring_buffer_size_t PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount ); /** Get address of region(s) from which we can read data. @param rbuf The ring buffer. @param elementCount The number of elements desired. @param dataPtr1 The address where the first (or only) region pointer will be stored. @param sizePtr1 The address where the first (or only) region length will be stored. @param dataPtr2 The address where the second region pointer will be stored if the first region is too small to satisfy elementCount. @param sizePtr2 The address where the second region length will be stored if the first region is too small to satisfy elementCount. @return The number of elements available for reading. */ ring_buffer_size_t PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount, void **dataPtr1, ring_buffer_size_t *sizePtr1, void **dataPtr2, ring_buffer_size_t *sizePtr2 ); /** Advance the read index to the next location to be read. @param rbuf The ring buffer. @param elementCount The number of elements to advance. @return The new position. */ ring_buffer_size_t PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_RINGBUFFER_H */ praat-6.0.04/external/portaudio/pa_skeleton.c000066400000000000000000000667101261542461700212320ustar00rootroot00000000000000/* * $Id: pa_skeleton.c 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library skeleton implementation * demonstrates how to use the common functions to implement support * for a host API * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Skeleton implementation of support for a host API. @note This file is provided as a starting point for implementing support for a new host API. IMPLEMENT ME comments are used to indicate functionality which much be customised for each implementation. */ #include /* strlen() */ #include "pa_util.h" #include "pa_allocation.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_cpuload.h" #include "pa_process.h" /* prototypes for functions declared in this file */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); #ifdef __cplusplus } #endif /* __cplusplus */ static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); static PaError CloseStream( PaStream* stream ); static PaError StartStream( PaStream *stream ); static PaError StopStream( PaStream *stream ); static PaError AbortStream( PaStream *stream ); static PaError IsStreamStopped( PaStream *s ); static PaError IsStreamActive( PaStream *stream ); static PaTime GetStreamTime( PaStream *stream ); static double GetStreamCpuLoad( PaStream* stream ); static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ); static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ); static signed long GetStreamReadAvailable( PaStream* stream ); static signed long GetStreamWriteAvailable( PaStream* stream ); /* IMPLEMENT ME: a macro like the following one should be used for reporting host errors */ #define PA_SKELETON_SET_LAST_HOST_ERROR( errorCode, errorText ) \ PaUtil_SetLastHostErrorInfo( paInDevelopment, errorCode, errorText ) /* PaSkeletonHostApiRepresentation - host api datastructure specific to this implementation */ typedef struct { PaUtilHostApiRepresentation inheritedHostApiRep; PaUtilStreamInterface callbackStreamInterface; PaUtilStreamInterface blockingStreamInterface; PaUtilAllocationGroup *allocations; /* implementation specific data goes here */ } PaSkeletonHostApiRepresentation; /* IMPLEMENT ME: rename this */ PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) { PaError result = paNoError; int i, deviceCount; PaSkeletonHostApiRepresentation *skeletonHostApi; PaDeviceInfo *deviceInfoArray; skeletonHostApi = (PaSkeletonHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaSkeletonHostApiRepresentation) ); if( !skeletonHostApi ) { result = paInsufficientMemory; goto error; } skeletonHostApi->allocations = PaUtil_CreateAllocationGroup(); if( !skeletonHostApi->allocations ) { result = paInsufficientMemory; goto error; } *hostApi = &skeletonHostApi->inheritedHostApiRep; (*hostApi)->info.structVersion = 1; (*hostApi)->info.type = paInDevelopment; /* IMPLEMENT ME: change to correct type id */ (*hostApi)->info.name = "skeleton implementation"; /* IMPLEMENT ME: change to correct name */ (*hostApi)->info.defaultInputDevice = paNoDevice; /* IMPLEMENT ME */ (*hostApi)->info.defaultOutputDevice = paNoDevice; /* IMPLEMENT ME */ (*hostApi)->info.deviceCount = 0; deviceCount = 0; /* IMPLEMENT ME */ if( deviceCount > 0 ) { (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( skeletonHostApi->allocations, sizeof(PaDeviceInfo*) * deviceCount ); if( !(*hostApi)->deviceInfos ) { result = paInsufficientMemory; goto error; } /* allocate all device info structs in a contiguous block */ deviceInfoArray = (PaDeviceInfo*)PaUtil_GroupAllocateMemory( skeletonHostApi->allocations, sizeof(PaDeviceInfo) * deviceCount ); if( !deviceInfoArray ) { result = paInsufficientMemory; goto error; } for( i=0; i < deviceCount; ++i ) { PaDeviceInfo *deviceInfo = &deviceInfoArray[i]; deviceInfo->structVersion = 2; deviceInfo->hostApi = hostApiIndex; deviceInfo->name = 0; /* IMPLEMENT ME: allocate block and copy name eg: deviceName = (char*)PaUtil_GroupAllocateMemory( skeletonHostApi->allocations, strlen(srcName) + 1 ); if( !deviceName ) { result = paInsufficientMemory; goto error; } strcpy( deviceName, srcName ); deviceInfo->name = deviceName; */ deviceInfo->maxInputChannels = 0; /* IMPLEMENT ME */ deviceInfo->maxOutputChannels = 0; /* IMPLEMENT ME */ deviceInfo->defaultLowInputLatency = 0.; /* IMPLEMENT ME */ deviceInfo->defaultLowOutputLatency = 0.; /* IMPLEMENT ME */ deviceInfo->defaultHighInputLatency = 0.; /* IMPLEMENT ME */ deviceInfo->defaultHighOutputLatency = 0.; /* IMPLEMENT ME */ deviceInfo->defaultSampleRate = 0.; /* IMPLEMENT ME */ (*hostApi)->deviceInfos[i] = deviceInfo; ++(*hostApi)->info.deviceCount; } } (*hostApi)->Terminate = Terminate; (*hostApi)->OpenStream = OpenStream; (*hostApi)->IsFormatSupported = IsFormatSupported; PaUtil_InitializeStreamInterface( &skeletonHostApi->callbackStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, GetStreamCpuLoad, PaUtil_DummyRead, PaUtil_DummyWrite, PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); PaUtil_InitializeStreamInterface( &skeletonHostApi->blockingStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, PaUtil_DummyGetCpuLoad, ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable ); return result; error: if( skeletonHostApi ) { if( skeletonHostApi->allocations ) { PaUtil_FreeAllAllocations( skeletonHostApi->allocations ); PaUtil_DestroyAllocationGroup( skeletonHostApi->allocations ); } PaUtil_FreeMemory( skeletonHostApi ); } return result; } static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) { PaSkeletonHostApiRepresentation *skeletonHostApi = (PaSkeletonHostApiRepresentation*)hostApi; /* IMPLEMENT ME: - clean up any resources not handled by the allocation group */ if( skeletonHostApi->allocations ) { PaUtil_FreeAllAllocations( skeletonHostApi->allocations ); PaUtil_DestroyAllocationGroup( skeletonHostApi->allocations ); } PaUtil_FreeMemory( skeletonHostApi ); } static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { int inputChannelCount, outputChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( inputSampleFormat & paCustomFormat ) return paSampleFormatNotSupported; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that input device can support inputChannelCount */ if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) return paInvalidChannelCount; /* validate inputStreamInfo */ if( inputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else { inputChannelCount = 0; } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( outputSampleFormat & paCustomFormat ) return paSampleFormatNotSupported; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that output device can support outputChannelCount */ if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) return paInvalidChannelCount; /* validate outputStreamInfo */ if( outputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else { outputChannelCount = 0; } /* IMPLEMENT ME: - if a full duplex stream is requested, check that the combination of input and output parameters is supported if necessary - check that the device supports sampleRate Because the buffer adapter handles conversion between all standard sample formats, the following checks are only required if paCustomFormat is implemented, or under some other unusual conditions. - check that input device can support inputSampleFormat, or that we have the capability to convert from inputSampleFormat to a native format - check that output device can support outputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format */ /* suppress unused variable warnings */ (void) sampleRate; return paFormatIsSupported; } /* PaSkeletonStream - a stream data structure specifically for this implementation */ typedef struct PaSkeletonStream { /* IMPLEMENT ME: rename this */ PaUtilStreamRepresentation streamRepresentation; PaUtilCpuLoadMeasurer cpuLoadMeasurer; PaUtilBufferProcessor bufferProcessor; /* IMPLEMENT ME: - implementation specific data goes here */ unsigned long framesPerHostCallback; /* just an example */ } PaSkeletonStream; /* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ) { PaError result = paNoError; PaSkeletonHostApiRepresentation *skeletonHostApi = (PaSkeletonHostApiRepresentation*)hostApi; PaSkeletonStream *stream = 0; unsigned long framesPerHostBuffer = framesPerBuffer; /* these may not be equivalent for all implementations */ int inputChannelCount, outputChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat; if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that input device can support inputChannelCount */ if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) return paInvalidChannelCount; /* validate inputStreamInfo */ if( inputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ /* IMPLEMENT ME - establish which host formats are available */ hostInputSampleFormat = PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, inputSampleFormat ); } else { inputChannelCount = 0; inputSampleFormat = hostInputSampleFormat = paInt16; /* Surpress 'uninitialised var' warnings. */ } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that output device can support inputChannelCount */ if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) return paInvalidChannelCount; /* validate outputStreamInfo */ if( outputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ /* IMPLEMENT ME - establish which host formats are available */ hostOutputSampleFormat = PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, outputSampleFormat ); } else { outputChannelCount = 0; outputSampleFormat = hostOutputSampleFormat = paInt16; /* Surpress 'uninitialized var' warnings. */ } /* IMPLEMENT ME: ( the following two checks are taken care of by PaUtil_InitializeBufferProcessor() FIXME - checks needed? ) - check that input device can support inputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format - check that output device can support outputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format - if a full duplex stream is requested, check that the combination of input and output parameters is supported - check that the device supports sampleRate - alter sampleRate to a close allowable rate if possible / necessary - validate suggestedInputLatency and suggestedOutputLatency parameters, use default values where necessary */ /* validate platform specific flags */ if( (streamFlags & paPlatformSpecificFlags) != 0 ) return paInvalidFlag; /* unexpected platform specific flag */ stream = (PaSkeletonStream*)PaUtil_AllocateMemory( sizeof(PaSkeletonStream) ); if( !stream ) { result = paInsufficientMemory; goto error; } if( streamCallback ) { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &skeletonHostApi->callbackStreamInterface, streamCallback, userData ); } else { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &skeletonHostApi->blockingStreamInterface, streamCallback, userData ); } PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate ); /* we assume a fixed host buffer size in this example, but the buffer processor can also support bounded and unknown host buffer sizes by passing paUtilBoundedHostBufferSize or paUtilUnknownHostBufferSize instead of paUtilFixedHostBufferSize below. */ result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, inputChannelCount, inputSampleFormat, hostInputSampleFormat, outputChannelCount, outputSampleFormat, hostOutputSampleFormat, sampleRate, streamFlags, framesPerBuffer, framesPerHostBuffer, paUtilFixedHostBufferSize, streamCallback, userData ); if( result != paNoError ) goto error; /* IMPLEMENT ME: initialise the following fields with estimated or actual values. */ stream->streamRepresentation.streamInfo.inputLatency = PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor); stream->streamRepresentation.streamInfo.outputLatency = PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor); stream->streamRepresentation.streamInfo.sampleRate = sampleRate; /* IMPLEMENT ME: - additional stream setup + opening */ stream->framesPerHostCallback = framesPerHostBuffer; *s = (PaStream*)stream; return result; error: if( stream ) PaUtil_FreeMemory( stream ); return result; } /* ExampleHostProcessingLoop() illustrates the kind of processing which may occur in a host implementation. */ static void ExampleHostProcessingLoop( void *inputBuffer, void *outputBuffer, void *userData ) { PaSkeletonStream *stream = (PaSkeletonStream*)userData; PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /* IMPLEMENT ME */ int callbackResult; unsigned long framesProcessed; PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); /* IMPLEMENT ME: - generate timing information - handle buffer slips */ /* If you need to byte swap or shift inputBuffer to convert it into a portaudio format, do it here. */ PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, 0 /* IMPLEMENT ME: pass underflow/overflow flags when necessary */ ); /* depending on whether the host buffers are interleaved, non-interleaved or a mixture, you will want to call PaUtil_SetInterleaved*Channels(), PaUtil_SetNonInterleaved*Channel() or PaUtil_Set*Channel() here. */ PaUtil_SetInputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ ); PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, 0, /* first channel of inputBuffer is channel 0 */ inputBuffer, 0 ); /* 0 - use inputChannelCount passed to init buffer processor */ PaUtil_SetOutputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ ); PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, 0, /* first channel of outputBuffer is channel 0 */ outputBuffer, 0 ); /* 0 - use outputChannelCount passed to init buffer processor */ /* you must pass a valid value of callback result to PaUtil_EndBufferProcessing() in general you would pass paContinue for normal operation, and paComplete to drain the buffer processor's internal output buffer. You can check whether the buffer processor's output buffer is empty using PaUtil_IsBufferProcessorOuputEmpty( bufferProcessor ) */ callbackResult = paContinue; framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult ); /* If you need to byte swap or shift outputBuffer to convert it to host format, do it here. */ PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed ); if( callbackResult == paContinue ) { /* nothing special to do */ } else if( callbackResult == paAbort ) { /* IMPLEMENT ME - finish playback immediately */ /* once finished, call the finished callback */ if( stream->streamRepresentation.streamFinishedCallback != 0 ) stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); } else { /* User callback has asked us to stop with paComplete or other non-zero value */ /* IMPLEMENT ME - finish playback once currently queued audio has completed */ /* once finished, call the finished callback */ if( stream->streamRepresentation.streamFinishedCallback != 0 ) stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); } } /* When CloseStream() is called, the multi-api layer ensures that the stream has already been stopped or aborted. */ static PaError CloseStream( PaStream* s ) { PaError result = paNoError; PaSkeletonStream *stream = (PaSkeletonStream*)s; /* IMPLEMENT ME: - additional stream closing + cleanup */ PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); PaUtil_FreeMemory( stream ); return result; } static PaError StartStream( PaStream *s ) { PaError result = paNoError; PaSkeletonStream *stream = (PaSkeletonStream*)s; PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); /* IMPLEMENT ME, see portaudio.h for required behavior */ /* suppress unused function warning. the code in ExampleHostProcessingLoop or something similar should be implemented to feed samples to and from the host after StartStream() is called. */ (void) ExampleHostProcessingLoop; return result; } static PaError StopStream( PaStream *s ) { PaError result = paNoError; PaSkeletonStream *stream = (PaSkeletonStream*)s; /* suppress unused variable warnings */ (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior */ return result; } static PaError AbortStream( PaStream *s ) { PaError result = paNoError; PaSkeletonStream *stream = (PaSkeletonStream*)s; /* suppress unused variable warnings */ (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior */ return result; } static PaError IsStreamStopped( PaStream *s ) { PaSkeletonStream *stream = (PaSkeletonStream*)s; /* suppress unused variable warnings */ (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior */ return 0; } static PaError IsStreamActive( PaStream *s ) { PaSkeletonStream *stream = (PaSkeletonStream*)s; /* suppress unused variable warnings */ (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior */ return 0; } static PaTime GetStreamTime( PaStream *s ) { PaSkeletonStream *stream = (PaSkeletonStream*)s; /* suppress unused variable warnings */ (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ return 0; } static double GetStreamCpuLoad( PaStream* s ) { PaSkeletonStream *stream = (PaSkeletonStream*)s; return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); } /* As separate stream interfaces are used for blocking and callback streams, the following functions can be guaranteed to only be called for blocking streams. */ static PaError ReadStream( PaStream* s, void *buffer, unsigned long frames ) { PaSkeletonStream *stream = (PaSkeletonStream*)s; /* suppress unused variable warnings */ (void) buffer; (void) frames; (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ return paNoError; } static PaError WriteStream( PaStream* s, const void *buffer, unsigned long frames ) { PaSkeletonStream *stream = (PaSkeletonStream*)s; /* suppress unused variable warnings */ (void) buffer; (void) frames; (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ return paNoError; } static signed long GetStreamReadAvailable( PaStream* s ) { PaSkeletonStream *stream = (PaSkeletonStream*)s; /* suppress unused variable warnings */ (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ return 0; } static signed long GetStreamWriteAvailable( PaStream* s ) { PaSkeletonStream *stream = (PaSkeletonStream*)s; /* suppress unused variable warnings */ (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ return 0; } praat-6.0.04/external/portaudio/pa_stream.c000066400000000000000000000123601261542461700206710ustar00rootroot00000000000000/* * $Id: pa_stream.c 1339 2008-02-15 07:50:33Z rossb $ * Portable Audio I/O Library * stream interface * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 2008 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Stream interfaces, representation structures and helper functions used to interface between pa_front.c host API implementations. */ #include "pa_stream.h" void PaUtil_InitializeStreamInterface( PaUtilStreamInterface *streamInterface, PaError (*Close)( PaStream* ), PaError (*Start)( PaStream* ), PaError (*Stop)( PaStream* ), PaError (*Abort)( PaStream* ), PaError (*IsStopped)( PaStream* ), PaError (*IsActive)( PaStream* ), PaTime (*GetTime)( PaStream* ), double (*GetCpuLoad)( PaStream* ), PaError (*Read)( PaStream*, void *, unsigned long ), PaError (*Write)( PaStream*, const void *, unsigned long ), signed long (*GetReadAvailable)( PaStream* ), signed long (*GetWriteAvailable)( PaStream* ) ) { streamInterface->Close = Close; streamInterface->Start = Start; streamInterface->Stop = Stop; streamInterface->Abort = Abort; streamInterface->IsStopped = IsStopped; streamInterface->IsActive = IsActive; streamInterface->GetTime = GetTime; streamInterface->GetCpuLoad = GetCpuLoad; streamInterface->Read = Read; streamInterface->Write = Write; streamInterface->GetReadAvailable = GetReadAvailable; streamInterface->GetWriteAvailable = GetWriteAvailable; } void PaUtil_InitializeStreamRepresentation( PaUtilStreamRepresentation *streamRepresentation, PaUtilStreamInterface *streamInterface, PaStreamCallback *streamCallback, void *userData ) { streamRepresentation->magic = PA_STREAM_MAGIC; streamRepresentation->nextOpenStream = 0; streamRepresentation->streamInterface = streamInterface; streamRepresentation->streamCallback = streamCallback; streamRepresentation->streamFinishedCallback = 0; streamRepresentation->userData = userData; streamRepresentation->streamInfo.inputLatency = 0.; streamRepresentation->streamInfo.outputLatency = 0.; streamRepresentation->streamInfo.sampleRate = 0.; } void PaUtil_TerminateStreamRepresentation( PaUtilStreamRepresentation *streamRepresentation ) { streamRepresentation->magic = 0; } PaError PaUtil_DummyRead( PaStream* stream, void *buffer, unsigned long frames ) { (void)stream; /* unused parameter */ (void)buffer; /* unused parameter */ (void)frames; /* unused parameter */ return paCanNotReadFromACallbackStream; } PaError PaUtil_DummyWrite( PaStream* stream, const void *buffer, unsigned long frames ) { (void)stream; /* unused parameter */ (void)buffer; /* unused parameter */ (void)frames; /* unused parameter */ return paCanNotWriteToACallbackStream; } signed long PaUtil_DummyGetReadAvailable( PaStream* stream ) { (void)stream; /* unused parameter */ return paCanNotReadFromACallbackStream; } signed long PaUtil_DummyGetWriteAvailable( PaStream* stream ) { (void)stream; /* unused parameter */ return paCanNotWriteToACallbackStream; } double PaUtil_DummyGetCpuLoad( PaStream* stream ) { (void)stream; /* unused parameter */ return 0.0; } praat-6.0.04/external/portaudio/pa_stream.h000066400000000000000000000161751261542461700207060ustar00rootroot00000000000000#ifndef PA_STREAM_H #define PA_STREAM_H /* * $Id: pa_stream.h 1339 2008-02-15 07:50:33Z rossb $ * Portable Audio I/O Library * stream interface * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2008 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Stream interfaces, representation structures and helper functions used to interface between pa_front.c host API implementations. */ #include "portaudio.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define PA_STREAM_MAGIC (0x18273645) /** A structure representing an (abstract) interface to a host API. Contains pointers to functions which implement the interface. All PaStreamInterface functions are guaranteed to be called with a non-null, valid stream parameter. */ typedef struct { PaError (*Close)( PaStream* stream ); PaError (*Start)( PaStream *stream ); PaError (*Stop)( PaStream *stream ); PaError (*Abort)( PaStream *stream ); PaError (*IsStopped)( PaStream *stream ); PaError (*IsActive)( PaStream *stream ); PaTime (*GetTime)( PaStream *stream ); double (*GetCpuLoad)( PaStream* stream ); PaError (*Read)( PaStream* stream, void *buffer, unsigned long frames ); PaError (*Write)( PaStream* stream, const void *buffer, unsigned long frames ); signed long (*GetReadAvailable)( PaStream* stream ); signed long (*GetWriteAvailable)( PaStream* stream ); } PaUtilStreamInterface; /** Initialize the fields of a PaUtilStreamInterface structure. */ void PaUtil_InitializeStreamInterface( PaUtilStreamInterface *streamInterface, PaError (*Close)( PaStream* ), PaError (*Start)( PaStream* ), PaError (*Stop)( PaStream* ), PaError (*Abort)( PaStream* ), PaError (*IsStopped)( PaStream* ), PaError (*IsActive)( PaStream* ), PaTime (*GetTime)( PaStream* ), double (*GetCpuLoad)( PaStream* ), PaError (*Read)( PaStream* stream, void *buffer, unsigned long frames ), PaError (*Write)( PaStream* stream, const void *buffer, unsigned long frames ), signed long (*GetReadAvailable)( PaStream* stream ), signed long (*GetWriteAvailable)( PaStream* stream ) ); /** Dummy Read function for use in interfaces to a callback based streams. Pass to the Read parameter of PaUtil_InitializeStreamInterface. @return An error code indicating that the function has no effect because the stream is a callback stream. */ PaError PaUtil_DummyRead( PaStream* stream, void *buffer, unsigned long frames ); /** Dummy Write function for use in an interfaces to callback based streams. Pass to the Write parameter of PaUtil_InitializeStreamInterface. @return An error code indicating that the function has no effect because the stream is a callback stream. */ PaError PaUtil_DummyWrite( PaStream* stream, const void *buffer, unsigned long frames ); /** Dummy GetReadAvailable function for use in interfaces to callback based streams. Pass to the GetReadAvailable parameter of PaUtil_InitializeStreamInterface. @return An error code indicating that the function has no effect because the stream is a callback stream. */ signed long PaUtil_DummyGetReadAvailable( PaStream* stream ); /** Dummy GetWriteAvailable function for use in interfaces to callback based streams. Pass to the GetWriteAvailable parameter of PaUtil_InitializeStreamInterface. @return An error code indicating that the function has no effect because the stream is a callback stream. */ signed long PaUtil_DummyGetWriteAvailable( PaStream* stream ); /** Dummy GetCpuLoad function for use in an interface to a read/write stream. Pass to the GetCpuLoad parameter of PaUtil_InitializeStreamInterface. @return Returns 0. */ double PaUtil_DummyGetCpuLoad( PaStream* stream ); /** Non host specific data for a stream. This data is used by pa_front to forward to the appropriate functions in the streamInterface structure. */ typedef struct PaUtilStreamRepresentation { unsigned long magic; /**< set to PA_STREAM_MAGIC */ struct PaUtilStreamRepresentation *nextOpenStream; /**< field used by multi-api code */ PaUtilStreamInterface *streamInterface; PaStreamCallback *streamCallback; PaStreamFinishedCallback *streamFinishedCallback; void *userData; PaStreamInfo streamInfo; } PaUtilStreamRepresentation; /** Initialize a PaUtilStreamRepresentation structure. @see PaUtil_InitializeStreamRepresentation */ void PaUtil_InitializeStreamRepresentation( PaUtilStreamRepresentation *streamRepresentation, PaUtilStreamInterface *streamInterface, PaStreamCallback *streamCallback, void *userData ); /** Clean up a PaUtilStreamRepresentation structure previously initialized by a call to PaUtil_InitializeStreamRepresentation. @see PaUtil_InitializeStreamRepresentation */ void PaUtil_TerminateStreamRepresentation( PaUtilStreamRepresentation *streamRepresentation ); /** Check that the stream pointer is valid. @return Returns paNoError if the stream pointer appears to be OK, otherwise returns an error indicating the cause of failure. */ PaError PaUtil_ValidateStreamPointer( PaStream *stream ); /** Cast an opaque stream pointer into a pointer to a PaUtilStreamRepresentation. @see PaUtilStreamRepresentation */ #define PA_STREAM_REP( stream )\ ((PaUtilStreamRepresentation*) (stream) ) /** Cast an opaque stream pointer into a pointer to a PaUtilStreamInterface. @see PaUtilStreamRepresentation, PaUtilStreamInterface */ #define PA_STREAM_INTERFACE( stream )\ PA_STREAM_REP( (stream) )->streamInterface #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_STREAM_H */ praat-6.0.04/external/portaudio/pa_trace.c000066400000000000000000000161561261542461700205030ustar00rootroot00000000000000/* * $Id: pa_trace.c 1916 2014-01-17 03:45:15Z philburk $ * Portable Audio I/O Library Trace Facility * Store trace information in real-time for later printing. * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2000 Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Real-time safe event trace logging facility for debugging. */ #include #include #include #include #include #include "pa_trace.h" #include "pa_util.h" #include "pa_debugprint.h" #if PA_TRACE_REALTIME_EVENTS static char const *traceTextArray[PA_MAX_TRACE_RECORDS]; static int traceIntArray[PA_MAX_TRACE_RECORDS]; static int traceIndex = 0; static int traceBlock = 0; /*********************************************************************/ void PaUtil_ResetTraceMessages() { traceIndex = 0; } /*********************************************************************/ void PaUtil_DumpTraceMessages() { int i; int messageCount = (traceIndex < PA_MAX_TRACE_RECORDS) ? traceIndex : PA_MAX_TRACE_RECORDS; printf("DumpTraceMessages: traceIndex = %d\n", traceIndex ); for( i=0; idata = (char*)PaUtil_AllocateMemory(maxSizeInBytes); if (pLog->data == 0) { PaUtil_FreeMemory(pLog); return paInsufficientMemory; } pLog->magik = kMagik; pLog->size = maxSizeInBytes; pLog->refTime = PaUtil_GetTime(); return paNoError; } void PaUtil_ResetHighSpeedLogTimeRef( LogHandle hLog ) { PaHighPerformanceLog* pLog = (PaHighPerformanceLog*)hLog; assert(pLog->magik == kMagik); pLog->refTime = PaUtil_GetTime(); } typedef struct __PaLogEntryHeader { int size; double timeStamp; } PaLogEntryHeader; #ifdef __APPLE__ #define _vsnprintf vsnprintf #define min(a,b) ((a)<(b)?(a):(b)) #endif int PaUtil_AddHighSpeedLogMessage( LogHandle hLog, const char* fmt, ... ) { va_list l; int n = 0; PaHighPerformanceLog* pLog = (PaHighPerformanceLog*)hLog; if (pLog != 0) { PaLogEntryHeader* pHeader; char* p; int maxN; assert(pLog->magik == kMagik); pHeader = (PaLogEntryHeader*)( pLog->data + pLog->writePtr ); p = (char*)( pHeader + 1 ); maxN = pLog->size - pLog->writePtr - 2 * sizeof(PaLogEntryHeader); pHeader->timeStamp = PaUtil_GetTime() - pLog->refTime; if (maxN > 0) { if (maxN > 32) { va_start(l, fmt); n = _vsnprintf(p, min(1024, maxN), fmt, l); va_end(l); } else { n = sprintf(p, "End of log..."); } n = ((n + sizeof(unsigned)) & ~(sizeof(unsigned)-1)) + sizeof(PaLogEntryHeader); pHeader->size = n; #if 0 PaUtil_DebugPrint("%05u.%03u: %s\n", pHeader->timeStamp/1000, pHeader->timeStamp%1000, p); #endif pLog->writePtr += n; } } return n; } void PaUtil_DumpHighSpeedLog( LogHandle hLog, const char* fileName ) { FILE* f = (fileName != NULL) ? fopen(fileName, "w") : stdout; unsigned localWritePtr; PaHighPerformanceLog* pLog = (PaHighPerformanceLog*)hLog; assert(pLog->magik == kMagik); localWritePtr = pLog->writePtr; while (pLog->readPtr != localWritePtr) { const PaLogEntryHeader* pHeader = (const PaLogEntryHeader*)( pLog->data + pLog->readPtr ); const char* p = (const char*)( pHeader + 1 ); const PaUint64 ts = (const PaUint64)( pHeader->timeStamp * USEC_PER_SEC ); assert(pHeader->size < (1024+sizeof(unsigned)+sizeof(PaLogEntryHeader))); fprintf(f, "%05u.%03u: %s\n", (unsigned)(ts/1000), (unsigned)(ts%1000), p); pLog->readPtr += pHeader->size; } if (f != stdout) { fclose(f); } } void PaUtil_DiscardHighSpeedLog( LogHandle hLog ) { PaHighPerformanceLog* pLog = (PaHighPerformanceLog*)hLog; assert(pLog->magik == kMagik); PaUtil_FreeMemory(pLog->data); PaUtil_FreeMemory(pLog); } #else /* This stub was added so that this file will generate a symbol. * Otherwise linker/archiver programs will complain. */ int PaUtil_TraceStubToSatisfyLinker(void) { return 0; } #endif /* TRACE_REALTIME_EVENTS */ praat-6.0.04/external/portaudio/pa_trace.h000066400000000000000000000101011261542461700204700ustar00rootroot00000000000000#ifndef PA_TRACE_H #define PA_TRACE_H /* * $Id: pa_trace.h 1812 2012-02-14 09:32:57Z robiwan $ * Portable Audio I/O Library Trace Facility * Store trace information in real-time for later printing. * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2000 Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Real-time safe event trace logging facility for debugging. Allows data to be logged to a fixed size trace buffer in a real-time execution context (such as at interrupt time). Each log entry consists of a message comprising a string pointer and an int. The trace buffer may be dumped to stdout later. This facility is only active if PA_TRACE_REALTIME_EVENTS is set to 1, otherwise the trace functions expand to no-ops. @fn PaUtil_ResetTraceMessages @brief Clear the trace buffer. @fn PaUtil_AddTraceMessage @brief Add a message to the trace buffer. A message consists of string and an int. @param msg The string pointer must remain valid until PaUtil_DumpTraceMessages is called. As a result, usually only string literals should be passed as the msg parameter. @fn PaUtil_DumpTraceMessages @brief Print all messages in the trace buffer to stdout and clear the trace buffer. */ #ifndef PA_TRACE_REALTIME_EVENTS #define PA_TRACE_REALTIME_EVENTS (0) /**< Set to 1 to enable logging using the trace functions defined below */ #endif #ifndef PA_MAX_TRACE_RECORDS #define PA_MAX_TRACE_RECORDS (2048) /**< Maximum number of records stored in trace buffer */ #endif #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #if PA_TRACE_REALTIME_EVENTS void PaUtil_ResetTraceMessages(); void PaUtil_AddTraceMessage( const char *msg, int data ); void PaUtil_DumpTraceMessages(); /* Alternative interface */ typedef void* LogHandle; int PaUtil_InitializeHighSpeedLog(LogHandle* phLog, unsigned maxSizeInBytes); void PaUtil_ResetHighSpeedLogTimeRef(LogHandle hLog); int PaUtil_AddHighSpeedLogMessage(LogHandle hLog, const char* fmt, ...); void PaUtil_DumpHighSpeedLog(LogHandle hLog, const char* fileName); void PaUtil_DiscardHighSpeedLog(LogHandle hLog); #else #define PaUtil_ResetTraceMessages() /* noop */ #define PaUtil_AddTraceMessage(msg,data) /* noop */ #define PaUtil_DumpTraceMessages() /* noop */ #define PaUtil_InitializeHighSpeedLog(phLog, maxSizeInBytes) (0) #define PaUtil_ResetHighSpeedLogTimeRef(hLog) #define PaUtil_AddHighSpeedLogMessage(...) (0) #define PaUtil_DumpHighSpeedLog(hLog, fileName) #define PaUtil_DiscardHighSpeedLog(hLog) #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_TRACE_H */ praat-6.0.04/external/portaudio/pa_types.h000066400000000000000000000063641261542461700205560ustar00rootroot00000000000000#ifndef PA_TYPES_H #define PA_TYPES_H /* * Portable Audio I/O Library * integer type definitions * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2006 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Definition of 16 and 32 bit integer types (PaInt16, PaInt32 etc) SIZEOF_SHORT, SIZEOF_INT and SIZEOF_LONG are set by the configure script when it is used. Otherwise we default to the common 32 bit values, if your platform doesn't use configure, and doesn't use the default values below you will need to explicitly define these symbols in your make file. A PA_VALIDATE_SIZES macro is provided to assert that the values set in this file are correct. Paul Boersma 2013: the sizes should not be handcoded if this header file is to be included in both 32-bit and 64-bit applications; instead, we use int32_t and the like from . */ #include typedef int16_t PaInt16; typedef uint16_t PaUint16; typedef int32_t PaInt32; typedef uint32_t PaUint32; /* PA_VALIDATE_TYPE_SIZES compares the size of the integer types at runtime to ensure that PortAudio was configured correctly, and raises an assertion if they don't match the expected values. must be included in the context in which this macro is used. */ #define PA_VALIDATE_TYPE_SIZES \ { \ assert( "PortAudio: type sizes are not correct in pa_types.h" && sizeof( PaUint16 ) == 2 ); \ assert( "PortAudio: type sizes are not correct in pa_types.h" && sizeof( PaInt16 ) == 2 ); \ assert( "PortAudio: type sizes are not correct in pa_types.h" && sizeof( PaUint32 ) == 4 ); \ assert( "PortAudio: type sizes are not correct in pa_types.h" && sizeof( PaInt32 ) == 4 ); \ } #endif /* PA_TYPES_H */ praat-6.0.04/external/portaudio/pa_unix_hostapis.c000066400000000000000000000055141261542461700222760ustar00rootroot00000000000000#ifdef UNIX /* * $Id: pa_unix_hostapis.c 1740 2011-08-25 07:17:48Z philburk $ * Portable Audio I/O Library UNIX initialization table * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup unix_src */ #include "pa_hostapi.h" PaError PaJack_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaAlsa_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaOSS_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); /* Added for IRIX, Pieter, oct 2, 2003: */ PaError PaSGI_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); /* Linux AudioScience HPI */ PaError PaAsiHpi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); /** Note that on Linux, ALSA is placed before OSS so that the former is preferred over the latter. */ PaUtilHostApiInitializer *paHostApiInitializers[] = { #if defined (linux) && defined (ALSA) PaAlsa_Initialize, // ppgb #endif 0 /* NULL terminated array */ }; int paDefaultHostApiIndex = 0; // ppgb #endif praat-6.0.04/external/portaudio/pa_unix_oss.c000066400000000000000000002134251261542461700212520ustar00rootroot00000000000000/* * $Id: pa_unix_oss.c 1894 2013-06-08 19:30:41Z gineera $ * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * OSS implementation by: * Douglas Repetto * Phil Burk * Dominic Mazzoni * Arve Knudsen * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostapi_src */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_SYS_SOUNDCARD_H # include # ifdef __NetBSD__ # define DEVICE_NAME_BASE "/dev/audio" # else # define DEVICE_NAME_BASE "/dev/dsp" # endif #elif defined(HAVE_LINUX_SOUNDCARD_H) # include # define DEVICE_NAME_BASE "/dev/dsp" #elif defined(HAVE_MACHINE_SOUNDCARD_H) # include /* JH20010905 */ # define DEVICE_NAME_BASE "/dev/audio" #else # error No sound card header file #endif #include "portaudio.h" #include "pa_util.h" #include "pa_allocation.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_cpuload.h" #include "pa_process.h" #include "pa_unix_util.h" #include "pa_debugprint.h" static int sysErr_; static pthread_t mainThread_; /* Check return value of system call, and map it to PaError */ #define ENSURE_(expr, code) \ do { \ if( UNLIKELY( (sysErr_ = (expr)) < 0 ) ) \ { \ /* PaUtil_SetLastHostErrorInfo should only be used in the main thread */ \ if( (code) == paUnanticipatedHostError && pthread_self() == mainThread_ ) \ { \ PaUtil_SetLastHostErrorInfo( paOSS, sysErr_, strerror( errno ) ); \ } \ \ PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \ result = (code); \ goto error; \ } \ } while( 0 ); #ifndef AFMT_S16_NE #define AFMT_S16_NE Get_AFMT_S16_NE() /********************************************************************* * Some versions of OSS do not define AFMT_S16_NE. So check CPU. * PowerPC is Big Endian. X86 is Little Endian. */ static int Get_AFMT_S16_NE( void ) { long testData = 1; char *ptr = (char *) &testData; int isLittle = ( *ptr == 1 ); /* Does address point to least significant byte? */ return isLittle ? AFMT_S16_LE : AFMT_S16_BE; } #endif /* PaOSSHostApiRepresentation - host api datastructure specific to this implementation */ typedef struct { PaUtilHostApiRepresentation inheritedHostApiRep; PaUtilStreamInterface callbackStreamInterface; PaUtilStreamInterface blockingStreamInterface; PaUtilAllocationGroup *allocations; PaHostApiIndex hostApiIndex; } PaOSSHostApiRepresentation; /** Per-direction structure for PaOssStream. * * Aspect StreamChannels: In case the user requests to open the same device for both capture and playback, * but with different number of channels we will have to adapt between the number of user and host * channels for at least one direction, since the configuration space is the same for both directions * of an OSS device. */ typedef struct { int fd; const char *devName; int userChannelCount, hostChannelCount; int userInterleaved; void *buffer; PaSampleFormat userFormat, hostFormat; double latency; unsigned long hostFrames, numBufs; void **userBuffers; /* For non-interleaved blocking */ } PaOssStreamComponent; /** Implementation specific representation of a PaStream. * */ typedef struct PaOssStream { PaUtilStreamRepresentation streamRepresentation; PaUtilCpuLoadMeasurer cpuLoadMeasurer; PaUtilBufferProcessor bufferProcessor; PaUtilThreading threading; int sharedDevice; unsigned long framesPerHostBuffer; int triggered; /* Have the devices been triggered yet (first start) */ int isActive; int isStopped; int lastPosPtr; double lastStreamBytes; int framesProcessed; double sampleRate; int callbackMode; volatile int callbackStop, callbackAbort; PaOssStreamComponent *capture, *playback; unsigned long pollTimeout; sem_t semaphore; } PaOssStream; typedef enum { StreamMode_In, StreamMode_Out } StreamMode; /* prototypes for functions declared in this file */ static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); static PaError CloseStream( PaStream* stream ); static PaError StartStream( PaStream *stream ); static PaError StopStream( PaStream *stream ); static PaError AbortStream( PaStream *stream ); static PaError IsStreamStopped( PaStream *s ); static PaError IsStreamActive( PaStream *stream ); static PaTime GetStreamTime( PaStream *stream ); static double GetStreamCpuLoad( PaStream* stream ); static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ); static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ); static signed long GetStreamReadAvailable( PaStream* stream ); static signed long GetStreamWriteAvailable( PaStream* stream ); static PaError BuildDeviceList( PaOSSHostApiRepresentation *hostApi ); /** Initialize the OSS API implementation. * * This function will initialize host API datastructures and query host devices for information. * * Aspect DeviceCapabilities: Enumeration of host API devices is initiated from here * * Aspect FreeResources: If an error is encountered under way we have to free each resource allocated in this function, * this happens with the usual "error" label. */ PaError PaOSS_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) { PaError result = paNoError; PaOSSHostApiRepresentation *ossHostApi = NULL; PA_UNLESS( ossHostApi = (PaOSSHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaOSSHostApiRepresentation) ), paInsufficientMemory ); PA_UNLESS( ossHostApi->allocations = PaUtil_CreateAllocationGroup(), paInsufficientMemory ); ossHostApi->hostApiIndex = hostApiIndex; /* Initialize host API structure */ *hostApi = &ossHostApi->inheritedHostApiRep; (*hostApi)->info.structVersion = 1; (*hostApi)->info.type = paOSS; (*hostApi)->info.name = "OSS"; (*hostApi)->Terminate = Terminate; (*hostApi)->OpenStream = OpenStream; (*hostApi)->IsFormatSupported = IsFormatSupported; PA_ENSURE( BuildDeviceList( ossHostApi ) ); PaUtil_InitializeStreamInterface( &ossHostApi->callbackStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, GetStreamCpuLoad, PaUtil_DummyRead, PaUtil_DummyWrite, PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); PaUtil_InitializeStreamInterface( &ossHostApi->blockingStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, PaUtil_DummyGetCpuLoad, ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable ); mainThread_ = pthread_self(); return result; error: if( ossHostApi ) { if( ossHostApi->allocations ) { PaUtil_FreeAllAllocations( ossHostApi->allocations ); PaUtil_DestroyAllocationGroup( ossHostApi->allocations ); } PaUtil_FreeMemory( ossHostApi ); } return result; } PaError PaUtil_InitializeDeviceInfo( PaDeviceInfo *deviceInfo, const char *name, PaHostApiIndex hostApiIndex, int maxInputChannels, int maxOutputChannels, PaTime defaultLowInputLatency, PaTime defaultLowOutputLatency, PaTime defaultHighInputLatency, PaTime defaultHighOutputLatency, double defaultSampleRate, PaUtilAllocationGroup *allocations ) { PaError result = paNoError; deviceInfo->structVersion = 2; if( allocations ) { size_t len = strlen( name ) + 1; PA_UNLESS( deviceInfo->name = PaUtil_GroupAllocateMemory( allocations, len ), paInsufficientMemory ); strncpy( (char *)deviceInfo->name, name, len ); } else deviceInfo->name = name; deviceInfo->hostApi = hostApiIndex; deviceInfo->maxInputChannels = maxInputChannels; deviceInfo->maxOutputChannels = maxOutputChannels; deviceInfo->defaultLowInputLatency = defaultLowInputLatency; deviceInfo->defaultLowOutputLatency = defaultLowOutputLatency; deviceInfo->defaultHighInputLatency = defaultHighInputLatency; deviceInfo->defaultHighOutputLatency = defaultHighOutputLatency; deviceInfo->defaultSampleRate = defaultSampleRate; error: return result; } static int CalcHigherLogTwo( int n ) { int log2 = 0; while( (1<= 2 ) break; } else { /* ioctl() worked but bail out if it does not support numChannels. * We don't want to leave gaps in the numChannels supported. */ if( (numChannels > 2) && (temp != numChannels) ) break; if( temp > maxNumChannels ) maxNumChannels = temp; /* Save maximum. */ } } /* A: We're able to open a device for capture if it's busy playing back and vice versa, * but we can't configure anything */ if( 0 == maxNumChannels && busy ) { result = paDeviceUnavailable; goto error; } /* The above negotiation may fail for an old driver so try this older technique. */ if( maxNumChannels < 1 ) { int stereo = 1; if( ioctl( devHandle, SNDCTL_DSP_STEREO, &stereo ) < 0 ) { maxNumChannels = 1; } else { maxNumChannels = (stereo) ? 2 : 1; } PA_DEBUG(( "%s: use SNDCTL_DSP_STEREO, maxNumChannels = %d\n", __FUNCTION__, maxNumChannels )); } /* During channel negotiation, the last ioctl() may have failed. This can * also cause sample rate negotiation to fail. Hence the following, to return * to a supported number of channels. SG20011005 */ { /* use most reasonable default value */ numChannels = PA_MIN( maxNumChannels, 2 ); ENSURE_( ioctl( devHandle, SNDCTL_DSP_CHANNELS, &numChannels ), paUnanticipatedHostError ); } /* Get supported sample rate closest to 44100 Hz */ if( *defaultSampleRate < 0 ) { sr = 44100; ENSURE_( ioctl( devHandle, SNDCTL_DSP_SPEED, &sr ), paUnanticipatedHostError ); *defaultSampleRate = sr; } *maxChannelCount = maxNumChannels; /* Attempt to set low latency with 4 frags-per-buffer, 128 frames-per-frag (total buffer 512 frames) * since the ioctl sets bytes, multiply by numChannels, and base on 2 bytes-per-sample, */ fragFrames = 128; frgmt = (4 << 16) + (CalcHigherLogTwo( fragFrames * numChannels * 2 ) & 0xffff); ENSURE_( ioctl( devHandle, SNDCTL_DSP_SETFRAGMENT, &frgmt ), paUnanticipatedHostError ); /* Use the value set by the ioctl to give the latency achieved */ fragFrames = pow( 2, frgmt & 0xffff ) / (numChannels * 2); *defaultLowLatency = ((frgmt >> 16) - 1) * fragFrames / *defaultSampleRate; /* Cannot now try setting a high latency (device would need closing and opening again). Make * high-latency 4 times the low unless the fragFrames are significantly more than requested 128 */ temp = (fragFrames < 256) ? 4 : (fragFrames < 512) ? 2 : 1; *defaultHighLatency = temp * *defaultLowLatency; error: if( devHandle >= 0 ) close( devHandle ); return result; } /** Query OSS device. * * This is where PaDeviceInfo objects are constructed and filled in with relevant information. * * Aspect DeviceCapabilities: The inferred device capabilities are recorded in a PaDeviceInfo object that is constructed * in place. */ static PaError QueryDevice( char *deviceName, PaOSSHostApiRepresentation *ossApi, PaDeviceInfo **deviceInfo ) { PaError result = paNoError; double sampleRate = -1.; int maxInputChannels, maxOutputChannels; PaTime defaultLowInputLatency, defaultLowOutputLatency, defaultHighInputLatency, defaultHighOutputLatency; PaError tmpRes = paNoError; int busy = 0; *deviceInfo = NULL; /* douglas: we have to do this querying in a slightly different order. apparently some sound cards will give you different info based on their settins. e.g. a card might give you stereo at 22kHz but only mono at 44kHz. the correct order for OSS is: format, channels, sample rate */ /* Aspect StreamChannels: The number of channels supported for a device may depend on the mode it is * opened in, it may have more channels available for capture than playback and vice versa. Therefore * we will open the device in both read- and write-only mode to determine the supported number. */ if( (tmpRes = QueryDirection( deviceName, StreamMode_In, &sampleRate, &maxInputChannels, &defaultLowInputLatency, &defaultHighInputLatency )) != paNoError ) { if( tmpRes != paDeviceUnavailable ) { PA_DEBUG(( "%s: Querying device %s for capture failed!\n", __FUNCTION__, deviceName )); /* PA_ENSURE( tmpRes ); */ } ++busy; } if( (tmpRes = QueryDirection( deviceName, StreamMode_Out, &sampleRate, &maxOutputChannels, &defaultLowOutputLatency, &defaultHighOutputLatency )) != paNoError ) { if( tmpRes != paDeviceUnavailable ) { PA_DEBUG(( "%s: Querying device %s for playback failed!\n", __FUNCTION__, deviceName )); /* PA_ENSURE( tmpRes ); */ } ++busy; } assert( 0 <= busy && busy <= 2 ); if( 2 == busy ) /* Both directions are unavailable to us */ { result = paDeviceUnavailable; goto error; } PA_UNLESS( *deviceInfo = PaUtil_GroupAllocateMemory( ossApi->allocations, sizeof (PaDeviceInfo) ), paInsufficientMemory ); PA_ENSURE( PaUtil_InitializeDeviceInfo( *deviceInfo, deviceName, ossApi->hostApiIndex, maxInputChannels, maxOutputChannels, defaultLowInputLatency, defaultLowOutputLatency, defaultHighInputLatency, defaultHighOutputLatency, sampleRate, ossApi->allocations ) ); error: return result; } /** Query host devices. * * Loop over host devices and query their capabilitiesu * * Aspect DeviceCapabilities: This function calls QueryDevice on each device entry and receives a filled in PaDeviceInfo object * per device, these are placed in the host api representation's deviceInfos array. */ static PaError BuildDeviceList( PaOSSHostApiRepresentation *ossApi ) { PaError result = paNoError; PaUtilHostApiRepresentation *commonApi = &ossApi->inheritedHostApiRep; int i; int numDevices = 0, maxDeviceInfos = 1; PaDeviceInfo **deviceInfos = NULL; /* These two will be set to the first working input and output device, respectively */ commonApi->info.defaultInputDevice = paNoDevice; commonApi->info.defaultOutputDevice = paNoDevice; /* Find devices by calling QueryDevice on each * potential device names. When we find a valid one, * add it to a linked list. * A: Set an arbitrary of 100 devices, should probably be a smarter way. */ for( i = 0; i < 100; i++ ) { char deviceName[32]; PaDeviceInfo *deviceInfo; int testResult; if( i == 0 ) snprintf(deviceName, sizeof (deviceName), "%s", DEVICE_NAME_BASE); else snprintf(deviceName, sizeof (deviceName), "%s%d", DEVICE_NAME_BASE, i); /* PA_DEBUG(("%s: trying device %s\n", __FUNCTION__, deviceName )); */ if( (testResult = QueryDevice( deviceName, ossApi, &deviceInfo )) != paNoError ) { if( testResult != paDeviceUnavailable ) PA_ENSURE( testResult ); continue; } ++numDevices; if( !deviceInfos || numDevices > maxDeviceInfos ) { maxDeviceInfos *= 2; PA_UNLESS( deviceInfos = (PaDeviceInfo **) realloc( deviceInfos, maxDeviceInfos * sizeof (PaDeviceInfo *) ), paInsufficientMemory ); } { int devIdx = numDevices - 1; deviceInfos[devIdx] = deviceInfo; if( commonApi->info.defaultInputDevice == paNoDevice && deviceInfo->maxInputChannels > 0 ) commonApi->info.defaultInputDevice = devIdx; if( commonApi->info.defaultOutputDevice == paNoDevice && deviceInfo->maxOutputChannels > 0 ) commonApi->info.defaultOutputDevice = devIdx; } } /* Make an array of PaDeviceInfo pointers out of the linked list */ PA_DEBUG(("PaOSS %s: Total number of devices found: %d\n", __FUNCTION__, numDevices)); commonApi->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( ossApi->allocations, sizeof(PaDeviceInfo*) * numDevices ); memcpy( commonApi->deviceInfos, deviceInfos, numDevices * sizeof (PaDeviceInfo *) ); commonApi->info.deviceCount = numDevices; error: free( deviceInfos ); return result; } static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) { PaOSSHostApiRepresentation *ossHostApi = (PaOSSHostApiRepresentation*)hostApi; if( ossHostApi->allocations ) { PaUtil_FreeAllAllocations( ossHostApi->allocations ); PaUtil_DestroyAllocationGroup( ossHostApi->allocations ); } PaUtil_FreeMemory( ossHostApi ); } static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { PaError result = paNoError; PaDeviceIndex device; PaDeviceInfo *deviceInfo; char *deviceName; int inputChannelCount, outputChannelCount; int tempDevHandle = -1; int flags; PaSampleFormat inputSampleFormat, outputSampleFormat; if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that input device can support inputChannelCount */ if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) return paInvalidChannelCount; /* validate inputStreamInfo */ if( inputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else { inputChannelCount = 0; } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that output device can support inputChannelCount */ if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) return paInvalidChannelCount; /* validate outputStreamInfo */ if( outputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else { outputChannelCount = 0; } if (inputChannelCount == 0 && outputChannelCount == 0) return paInvalidChannelCount; /* if full duplex, make sure that they're the same device */ if (inputChannelCount > 0 && outputChannelCount > 0 && inputParameters->device != outputParameters->device) return paInvalidDevice; /* if full duplex, also make sure that they're the same number of channels */ if (inputChannelCount > 0 && outputChannelCount > 0 && inputChannelCount != outputChannelCount) return paInvalidChannelCount; /* open the device so we can do more tests */ if( inputChannelCount > 0 ) { result = PaUtil_DeviceIndexToHostApiDeviceIndex(&device, inputParameters->device, hostApi); if (result != paNoError) return result; } else { result = PaUtil_DeviceIndexToHostApiDeviceIndex(&device, outputParameters->device, hostApi); if (result != paNoError) return result; } deviceInfo = hostApi->deviceInfos[device]; deviceName = (char *)deviceInfo->name; flags = O_NONBLOCK; if (inputChannelCount > 0 && outputChannelCount > 0) flags |= O_RDWR; else if (inputChannelCount > 0) flags |= O_RDONLY; else flags |= O_WRONLY; ENSURE_( tempDevHandle = open( deviceInfo->name, flags ), paDeviceUnavailable ); /* PaOssStream_Configure will do the rest of the checking for us */ /* PA_ENSURE( PaOssStream_Configure( tempDevHandle, deviceName, outputChannelCount, &sampleRate ) ); */ /* everything succeeded! */ error: if( tempDevHandle >= 0 ) close( tempDevHandle ); return result; } /** Validate stream parameters. * * Aspect StreamChannels: We verify that the number of channels is within the allowed range for the device */ static PaError ValidateParameters( const PaStreamParameters *parameters, const PaDeviceInfo *deviceInfo, StreamMode mode ) { int maxChans; assert( parameters ); if( parameters->device == paUseHostApiSpecificDeviceSpecification ) { return paInvalidDevice; } maxChans = (mode == StreamMode_In ? deviceInfo->maxInputChannels : deviceInfo->maxOutputChannels); if( parameters->channelCount > maxChans ) { return paInvalidChannelCount; } return paNoError; } static PaError PaOssStreamComponent_Initialize( PaOssStreamComponent *component, const PaStreamParameters *parameters, int callbackMode, int fd, const char *deviceName ) { PaError result = paNoError; assert( component ); memset( component, 0, sizeof (PaOssStreamComponent) ); component->fd = fd; component->devName = deviceName; component->userChannelCount = parameters->channelCount; component->userFormat = parameters->sampleFormat; component->latency = parameters->suggestedLatency; component->userInterleaved = !(parameters->sampleFormat & paNonInterleaved); if( !callbackMode && !component->userInterleaved ) { /* Pre-allocate non-interleaved user provided buffers */ PA_UNLESS( component->userBuffers = PaUtil_AllocateMemory( sizeof (void *) * component->userChannelCount ), paInsufficientMemory ); } error: return result; } static void PaOssStreamComponent_Terminate( PaOssStreamComponent *component ) { assert( component ); if( component->fd >= 0 ) close( component->fd ); if( component->buffer ) PaUtil_FreeMemory( component->buffer ); if( component->userBuffers ) PaUtil_FreeMemory( component->userBuffers ); PaUtil_FreeMemory( component ); } static PaError ModifyBlocking( int fd, int blocking ) { PaError result = paNoError; int fflags; ENSURE_( fflags = fcntl( fd, F_GETFL ), paUnanticipatedHostError ); if( blocking ) fflags &= ~O_NONBLOCK; else fflags |= O_NONBLOCK; ENSURE_( fcntl( fd, F_SETFL, fflags ), paUnanticipatedHostError ); error: return result; } /** Open input and output devices. * * @param idev: Returned input device file descriptor. * @param odev: Returned output device file descriptor. */ static PaError OpenDevices( const char *idevName, const char *odevName, int *idev, int *odev ) { PaError result = paNoError; int flags = O_NONBLOCK, duplex = 0; *idev = *odev = -1; if( idevName && odevName ) { duplex = 1; flags |= O_RDWR; } else if( idevName ) flags |= O_RDONLY; else flags |= O_WRONLY; /* open first in nonblocking mode, in case it's busy... * A: then unset the non-blocking attribute */ assert( flags & O_NONBLOCK ); if( idevName ) { ENSURE_( *idev = open( idevName, flags ), paDeviceUnavailable ); PA_ENSURE( ModifyBlocking( *idev, 1 ) ); /* Blocking */ } if( odevName ) { if( !idevName ) { ENSURE_( *odev = open( odevName, flags ), paDeviceUnavailable ); PA_ENSURE( ModifyBlocking( *odev, 1 ) ); /* Blocking */ } else { ENSURE_( *odev = dup( *idev ), paUnanticipatedHostError ); } } error: return result; } static PaError PaOssStream_Initialize( PaOssStream *stream, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, PaStreamCallback callback, void *userData, PaStreamFlags streamFlags, PaOSSHostApiRepresentation *ossApi ) { PaError result = paNoError; int idev, odev; PaUtilHostApiRepresentation *hostApi = &ossApi->inheritedHostApiRep; const char *idevName = NULL, *odevName = NULL; assert( stream ); memset( stream, 0, sizeof (PaOssStream) ); stream->isStopped = 1; PA_ENSURE( PaUtil_InitializeThreading( &stream->threading ) ); if( inputParameters && outputParameters ) { if( inputParameters->device == outputParameters->device ) stream->sharedDevice = 1; } if( inputParameters ) idevName = hostApi->deviceInfos[inputParameters->device]->name; if( outputParameters ) odevName = hostApi->deviceInfos[outputParameters->device]->name; PA_ENSURE( OpenDevices( idevName, odevName, &idev, &odev ) ); if( inputParameters ) { PA_UNLESS( stream->capture = PaUtil_AllocateMemory( sizeof (PaOssStreamComponent) ), paInsufficientMemory ); PA_ENSURE( PaOssStreamComponent_Initialize( stream->capture, inputParameters, callback != NULL, idev, idevName ) ); } if( outputParameters ) { PA_UNLESS( stream->playback = PaUtil_AllocateMemory( sizeof (PaOssStreamComponent) ), paInsufficientMemory ); PA_ENSURE( PaOssStreamComponent_Initialize( stream->playback, outputParameters, callback != NULL, odev, odevName ) ); } if( callback != NULL ) { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &ossApi->callbackStreamInterface, callback, userData ); stream->callbackMode = 1; } else { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &ossApi->blockingStreamInterface, callback, userData ); } ENSURE_( sem_init( &stream->semaphore, 0, 0 ), paInternalError ); error: return result; } static void PaOssStream_Terminate( PaOssStream *stream ) { assert( stream ); PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); PaUtil_TerminateThreading( &stream->threading ); if( stream->capture ) PaOssStreamComponent_Terminate( stream->capture ); if( stream->playback ) PaOssStreamComponent_Terminate( stream->playback ); sem_destroy( &stream->semaphore ); PaUtil_FreeMemory( stream ); } /** Translate from PA format to OSS native. * */ static PaError Pa2OssFormat( PaSampleFormat paFormat, int *ossFormat ) { switch( paFormat ) { case paUInt8: *ossFormat = AFMT_U8; break; case paInt8: *ossFormat = AFMT_S8; break; case paInt16: *ossFormat = AFMT_S16_NE; break; default: return paInternalError; /* This shouldn't happen */ } return paNoError; } /** Return the PA-compatible formats that this device can support. * */ static PaError GetAvailableFormats( PaOssStreamComponent *component, PaSampleFormat *availableFormats ) { PaError result = paNoError; int mask = 0; PaSampleFormat frmts = 0; ENSURE_( ioctl( component->fd, SNDCTL_DSP_GETFMTS, &mask ), paUnanticipatedHostError ); if( mask & AFMT_U8 ) frmts |= paUInt8; if( mask & AFMT_S8 ) frmts |= paInt8; if( mask & AFMT_S16_NE ) frmts |= paInt16; else result = paSampleFormatNotSupported; *availableFormats = frmts; error: return result; } static unsigned int PaOssStreamComponent_FrameSize( PaOssStreamComponent *component ) { return Pa_GetSampleSize( component->hostFormat ) * component->hostChannelCount; } /** Buffer size in bytes. * */ static unsigned long PaOssStreamComponent_BufferSize( PaOssStreamComponent *component ) { return PaOssStreamComponent_FrameSize( component ) * component->hostFrames * component->numBufs; } /** Configure stream component device parameters. */ static PaError PaOssStreamComponent_Configure( PaOssStreamComponent *component, double sampleRate, unsigned long framesPerBuffer, StreamMode streamMode, PaOssStreamComponent *master ) { PaError result = paNoError; int temp, nativeFormat; int sr = (int)sampleRate; PaSampleFormat availableFormats = 0, hostFormat = 0; int chans = component->userChannelCount; int frgmt; int numBufs; int bytesPerBuf; unsigned long bufSz; unsigned long fragSz; audio_buf_info bufInfo; /* We may have a situation where only one component (the master) is configured, if both point to the same device. * In that case, the second component will copy settings from the other */ if( !master ) { /* Aspect BufferSettings: If framesPerBuffer is unspecified we have to infer a suitable fragment size. * The hardware need not respect the requested fragment size, so we may have to adapt. */ if( framesPerBuffer == paFramesPerBufferUnspecified ) { /* Aim for 4 fragments in the complete buffer; the latency comes from 3 of these */ fragSz = (unsigned long)(component->latency * sampleRate / 3); bufSz = fragSz * 4; } else { fragSz = framesPerBuffer; bufSz = (unsigned long)(component->latency * sampleRate) + fragSz; /* Latency + 1 buffer */ } PA_ENSURE( GetAvailableFormats( component, &availableFormats ) ); hostFormat = PaUtil_SelectClosestAvailableFormat( availableFormats, component->userFormat ); /* OSS demands at least 2 buffers, and 16 bytes per buffer */ numBufs = (int)PA_MAX( bufSz / fragSz, 2 ); bytesPerBuf = PA_MAX( fragSz * Pa_GetSampleSize( hostFormat ) * chans, 16 ); /* The fragment parameters are encoded like this: * Most significant byte: number of fragments * Least significant byte: exponent of fragment size (i.e., for 256, 8) */ frgmt = (numBufs << 16) + (CalcHigherLogTwo( bytesPerBuf ) & 0xffff); ENSURE_( ioctl( component->fd, SNDCTL_DSP_SETFRAGMENT, &frgmt ), paUnanticipatedHostError ); /* A: according to the OSS programmer's guide parameters should be set in this order: * format, channels, rate */ /* This format should be deemed good before we get this far */ PA_ENSURE( Pa2OssFormat( hostFormat, &temp ) ); nativeFormat = temp; ENSURE_( ioctl( component->fd, SNDCTL_DSP_SETFMT, &temp ), paUnanticipatedHostError ); PA_UNLESS( temp == nativeFormat, paInternalError ); /* try to set the number of channels */ ENSURE_( ioctl( component->fd, SNDCTL_DSP_CHANNELS, &chans ), paSampleFormatNotSupported ); /* XXX: Should be paInvalidChannelCount? */ /* It's possible that the minimum number of host channels is greater than what the user requested */ PA_UNLESS( chans >= component->userChannelCount, paInvalidChannelCount ); /* try to set the sample rate */ ENSURE_( ioctl( component->fd, SNDCTL_DSP_SPEED, &sr ), paInvalidSampleRate ); /* reject if there's no sample rate within 1% of the one requested */ if( (fabs( sampleRate - sr ) / sampleRate) > 0.01 ) { PA_DEBUG(("%s: Wanted %f, closest sample rate was %d\n", __FUNCTION__, sampleRate, sr )); PA_ENSURE( paInvalidSampleRate ); } ENSURE_( ioctl( component->fd, streamMode == StreamMode_In ? SNDCTL_DSP_GETISPACE : SNDCTL_DSP_GETOSPACE, &bufInfo ), paUnanticipatedHostError ); component->numBufs = bufInfo.fragstotal; /* This needs to be the last ioctl call before the first read/write, according to the OSS programmer's guide */ ENSURE_( ioctl( component->fd, SNDCTL_DSP_GETBLKSIZE, &bytesPerBuf ), paUnanticipatedHostError ); component->hostFrames = bytesPerBuf / Pa_GetSampleSize( hostFormat ) / chans; component->hostChannelCount = chans; component->hostFormat = hostFormat; } else { component->hostFormat = master->hostFormat; component->hostFrames = master->hostFrames; component->hostChannelCount = master->hostChannelCount; component->numBufs = master->numBufs; } PA_UNLESS( component->buffer = PaUtil_AllocateMemory( PaOssStreamComponent_BufferSize( component ) ), paInsufficientMemory ); error: return result; } static PaError PaOssStreamComponent_Read( PaOssStreamComponent *component, unsigned long *frames ) { PaError result = paNoError; size_t len = *frames * PaOssStreamComponent_FrameSize( component ); ssize_t bytesRead; ENSURE_( bytesRead = read( component->fd, component->buffer, len ), paUnanticipatedHostError ); *frames = bytesRead / PaOssStreamComponent_FrameSize( component ); /* TODO: Handle condition where number of frames read doesn't equal number of frames requested */ error: return result; } static PaError PaOssStreamComponent_Write( PaOssStreamComponent *component, unsigned long *frames ) { PaError result = paNoError; size_t len = *frames * PaOssStreamComponent_FrameSize( component ); ssize_t bytesWritten; ENSURE_( bytesWritten = write( component->fd, component->buffer, len ), paUnanticipatedHostError ); *frames = bytesWritten / PaOssStreamComponent_FrameSize( component ); /* TODO: Handle condition where number of frames written doesn't equal number of frames requested */ error: return result; } /** Configure the stream according to input/output parameters. * * Aspect StreamChannels: The minimum number of channels supported by the device may exceed that requested by * the user, if so we'll record the actual number of host channels and adapt later. */ static PaError PaOssStream_Configure( PaOssStream *stream, double sampleRate, unsigned long framesPerBuffer, double *inputLatency, double *outputLatency ) { PaError result = paNoError; int duplex = stream->capture && stream->playback; unsigned long framesPerHostBuffer = 0; /* We should request full duplex first thing after opening the device */ if( duplex && stream->sharedDevice ) ENSURE_( ioctl( stream->capture->fd, SNDCTL_DSP_SETDUPLEX, 0 ), paUnanticipatedHostError ); if( stream->capture ) { PaOssStreamComponent *component = stream->capture; PA_ENSURE( PaOssStreamComponent_Configure( component, sampleRate, framesPerBuffer, StreamMode_In, NULL ) ); assert( component->hostChannelCount > 0 ); assert( component->hostFrames > 0 ); *inputLatency = (component->hostFrames * (component->numBufs - 1)) / sampleRate; } if( stream->playback ) { PaOssStreamComponent *component = stream->playback, *master = stream->sharedDevice ? stream->capture : NULL; PA_ENSURE( PaOssStreamComponent_Configure( component, sampleRate, framesPerBuffer, StreamMode_Out, master ) ); assert( component->hostChannelCount > 0 ); assert( component->hostFrames > 0 ); *outputLatency = (component->hostFrames * (component->numBufs - 1)) / sampleRate; } if( duplex ) framesPerHostBuffer = PA_MIN( stream->capture->hostFrames, stream->playback->hostFrames ); else if( stream->capture ) framesPerHostBuffer = stream->capture->hostFrames; else if( stream->playback ) framesPerHostBuffer = stream->playback->hostFrames; stream->framesPerHostBuffer = framesPerHostBuffer; stream->pollTimeout = (int) ceil( 1e6 * framesPerHostBuffer / sampleRate ); /* Period in usecs, rounded up */ stream->sampleRate = stream->streamRepresentation.streamInfo.sampleRate = sampleRate; error: return result; } /* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */ /** Open a PA OSS stream. * * Aspect StreamChannels: The number of channels is specified per direction (in/out), and can differ between the * two. However, OSS doesn't support separate configuration spaces for capture and playback so if both * directions are the same device we will demand the same number of channels. The number of channels can range * from 1 to the maximum supported by the device. * * Aspect BufferSettings: If framesPerBuffer != paFramesPerBufferUnspecified the number of frames per callback * must reflect this, in addition the host latency per device should approximate the corresponding * suggestedLatency. Based on these constraints we need to determine a number of frames per host buffer that * both capture and playback can agree on (they can be different devices), the buffer processor can adapt * between host and user buffer size, but the ratio should preferably be integral. */ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ) { PaError result = paNoError; PaOSSHostApiRepresentation *ossHostApi = (PaOSSHostApiRepresentation*)hostApi; PaOssStream *stream = NULL; int inputChannelCount = 0, outputChannelCount = 0; PaSampleFormat inputSampleFormat = 0, outputSampleFormat = 0, inputHostFormat = 0, outputHostFormat = 0; const PaDeviceInfo *inputDeviceInfo = 0, *outputDeviceInfo = 0; int bpInitialized = 0; double inLatency = 0., outLatency = 0.; int i = 0; /* validate platform specific flags */ if( (streamFlags & paPlatformSpecificFlags) != 0 ) return paInvalidFlag; /* unexpected platform specific flag */ if( inputParameters ) { /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ inputDeviceInfo = hostApi->deviceInfos[inputParameters->device]; PA_ENSURE( ValidateParameters( inputParameters, inputDeviceInfo, StreamMode_In ) ); inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; } if( outputParameters ) { outputDeviceInfo = hostApi->deviceInfos[outputParameters->device]; PA_ENSURE( ValidateParameters( outputParameters, outputDeviceInfo, StreamMode_Out ) ); outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; } /* Aspect StreamChannels: We currently demand that number of input and output channels are the same, if the same * device is opened for both directions */ if( inputChannelCount > 0 && outputChannelCount > 0 ) { if( inputParameters->device == outputParameters->device ) { if( inputParameters->channelCount != outputParameters->channelCount ) return paInvalidChannelCount; } } /* Round framesPerBuffer to the next power-of-two to make OSS happy. */ if( framesPerBuffer != paFramesPerBufferUnspecified ) { framesPerBuffer &= INT_MAX; for (i = 1; framesPerBuffer > i; i <<= 1) ; framesPerBuffer = i; } /* allocate and do basic initialization of the stream structure */ PA_UNLESS( stream = (PaOssStream*)PaUtil_AllocateMemory( sizeof(PaOssStream) ), paInsufficientMemory ); PA_ENSURE( PaOssStream_Initialize( stream, inputParameters, outputParameters, streamCallback, userData, streamFlags, ossHostApi ) ); PA_ENSURE( PaOssStream_Configure( stream, sampleRate, framesPerBuffer, &inLatency, &outLatency ) ); PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate ); if( inputParameters ) { inputHostFormat = stream->capture->hostFormat; stream->streamRepresentation.streamInfo.inputLatency = inLatency + PaUtil_GetBufferProcessorInputLatencyFrames( &stream->bufferProcessor ) / sampleRate; } if( outputParameters ) { outputHostFormat = stream->playback->hostFormat; stream->streamRepresentation.streamInfo.outputLatency = outLatency + PaUtil_GetBufferProcessorOutputLatencyFrames( &stream->bufferProcessor ) / sampleRate; } /* Initialize buffer processor with fixed host buffer size. * Aspect StreamSampleFormat: Here we commit the user and host sample formats, PA infrastructure will * convert between the two. */ PA_ENSURE( PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, inputChannelCount, inputSampleFormat, inputHostFormat, outputChannelCount, outputSampleFormat, outputHostFormat, sampleRate, streamFlags, framesPerBuffer, stream->framesPerHostBuffer, paUtilFixedHostBufferSize, streamCallback, userData ) ); bpInitialized = 1; *s = (PaStream*)stream; return result; error: if( bpInitialized ) PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); if( stream ) PaOssStream_Terminate( stream ); return result; } /*! Poll on I/O filedescriptors. Poll till we've determined there's data for read or write. In the full-duplex case, we don't want to hang around forever waiting for either input or output frames, so whenever we have a timed out filedescriptor we check if we're nearing under/overrun for the other direction (critical limit set at one buffer). If so, we exit the waiting state, and go on with what we got. We align the number of frames on a host buffer boundary because it is possible that the buffer size differs for the two directions and the host buffer size is a compromise between the two. */ static PaError PaOssStream_WaitForFrames( PaOssStream *stream, unsigned long *frames ) { PaError result = paNoError; int pollPlayback = 0, pollCapture = 0; int captureAvail = INT_MAX, playbackAvail = INT_MAX, commonAvail; audio_buf_info bufInfo; /* int ofs = 0, nfds = stream->nfds; */ fd_set readFds, writeFds; int nfds = 0; struct timeval selectTimeval = {0, 0}; unsigned long timeout = stream->pollTimeout; /* In usecs */ int captureFd = -1, playbackFd = -1; assert( stream ); assert( frames ); if( stream->capture ) { pollCapture = 1; captureFd = stream->capture->fd; /* stream->capture->pfd->events = POLLIN; */ } if( stream->playback ) { pollPlayback = 1; playbackFd = stream->playback->fd; /* stream->playback->pfd->events = POLLOUT; */ } FD_ZERO( &readFds ); FD_ZERO( &writeFds ); while( pollPlayback || pollCapture ) { #ifdef PTHREAD_CANCELED pthread_testcancel(); #else /* avoid indefinite waiting on thread not supporting cancelation */ if( stream->callbackStop || stream->callbackAbort ) { PA_DEBUG(( "Cancelling PaOssStream_WaitForFrames\n" )); (*frames) = 0; return paNoError; } #endif /* select may modify the timeout parameter */ selectTimeval.tv_usec = timeout; nfds = 0; if( pollCapture ) { FD_SET( captureFd, &readFds ); nfds = captureFd + 1; } if( pollPlayback ) { FD_SET( playbackFd, &writeFds ); nfds = PA_MAX( nfds, playbackFd + 1 ); } ENSURE_( select( nfds, &readFds, &writeFds, NULL, &selectTimeval ), paUnanticipatedHostError ); /* if( poll( stream->pfds + ofs, nfds, stream->pollTimeout ) < 0 ) { ENSURE_( -1, paUnanticipatedHostError ); } */ #ifdef PTHREAD_CANCELED pthread_testcancel(); #else /* avoid indefinite waiting on thread not supporting cancelation */ if( stream->callbackStop || stream->callbackAbort ) { PA_DEBUG(( "Cancelling PaOssStream_WaitForFrames\n" )); (*frames) = 0; return paNoError; } #endif if( pollCapture ) { if( FD_ISSET( captureFd, &readFds ) ) { FD_CLR( captureFd, &readFds ); pollCapture = 0; } /* if( stream->capture->pfd->revents & POLLIN ) { --nfds; ++ofs; pollCapture = 0; } */ else if( stream->playback ) /* Timed out, go on with playback? */ { /*PA_DEBUG(( "%s: Trying to poll again for capture frames, pollTimeout: %d\n", __FUNCTION__, stream->pollTimeout ));*/ } } if( pollPlayback ) { if( FD_ISSET( playbackFd, &writeFds ) ) { FD_CLR( playbackFd, &writeFds ); pollPlayback = 0; } /* if( stream->playback->pfd->revents & POLLOUT ) { --nfds; pollPlayback = 0; } */ else if( stream->capture ) /* Timed out, go on with capture? */ { /*PA_DEBUG(( "%s: Trying to poll again for playback frames, pollTimeout: %d\n\n", __FUNCTION__, stream->pollTimeout ));*/ } } } if( stream->capture ) { ENSURE_( ioctl( captureFd, SNDCTL_DSP_GETISPACE, &bufInfo ), paUnanticipatedHostError ); captureAvail = bufInfo.fragments * stream->capture->hostFrames; if( !captureAvail ) PA_DEBUG(( "%s: captureAvail: 0\n", __FUNCTION__ )); captureAvail = captureAvail == 0 ? INT_MAX : captureAvail; /* Disregard if zero */ } if( stream->playback ) { ENSURE_( ioctl( playbackFd, SNDCTL_DSP_GETOSPACE, &bufInfo ), paUnanticipatedHostError ); playbackAvail = bufInfo.fragments * stream->playback->hostFrames; if( !playbackAvail ) { PA_DEBUG(( "%s: playbackAvail: 0\n", __FUNCTION__ )); } playbackAvail = playbackAvail == 0 ? INT_MAX : playbackAvail; /* Disregard if zero */ } commonAvail = PA_MIN( captureAvail, playbackAvail ); if( commonAvail == INT_MAX ) commonAvail = 0; commonAvail -= commonAvail % stream->framesPerHostBuffer; assert( commonAvail != INT_MAX ); assert( commonAvail >= 0 ); *frames = commonAvail; error: return result; } /** Prepare stream for capture/playback. * * In order to synchronize capture and playback properly we use the SETTRIGGER command. */ static PaError PaOssStream_Prepare( PaOssStream *stream ) { PaError result = paNoError; int enableBits = 0; if( stream->triggered ) return result; /* The OSS reference instructs us to clear direction bits before setting them.*/ if( stream->playback ) ENSURE_( ioctl( stream->playback->fd, SNDCTL_DSP_SETTRIGGER, &enableBits ), paUnanticipatedHostError ); if( stream->capture ) ENSURE_( ioctl( stream->capture->fd, SNDCTL_DSP_SETTRIGGER, &enableBits ), paUnanticipatedHostError ); if( stream->playback ) { size_t bufSz = PaOssStreamComponent_BufferSize( stream->playback ); memset( stream->playback->buffer, 0, bufSz ); /* Looks like we have to turn off blocking before we try this, but if we don't fill the buffer * OSS will complain. */ PA_ENSURE( ModifyBlocking( stream->playback->fd, 0 ) ); while (1) { if( write( stream->playback->fd, stream->playback->buffer, bufSz ) < 0 ) break; } PA_ENSURE( ModifyBlocking( stream->playback->fd, 1 ) ); } if( stream->sharedDevice ) { enableBits = PCM_ENABLE_INPUT | PCM_ENABLE_OUTPUT; ENSURE_( ioctl( stream->capture->fd, SNDCTL_DSP_SETTRIGGER, &enableBits ), paUnanticipatedHostError ); } else { if( stream->capture ) { enableBits = PCM_ENABLE_INPUT; ENSURE_( ioctl( stream->capture->fd, SNDCTL_DSP_SETTRIGGER, &enableBits ), paUnanticipatedHostError ); } if( stream->playback ) { enableBits = PCM_ENABLE_OUTPUT; ENSURE_( ioctl( stream->playback->fd, SNDCTL_DSP_SETTRIGGER, &enableBits ), paUnanticipatedHostError ); } } /* Ok, we have triggered the stream */ stream->triggered = 1; error: return result; } /** Stop audio processing * */ static PaError PaOssStream_Stop( PaOssStream *stream, int abort ) { PaError result = paNoError; /* Looks like the only safe way to stop audio without reopening the device is SNDCTL_DSP_POST. * Also disable capture/playback till the stream is started again. */ int captureErr = 0, playbackErr = 0; if( stream->capture ) { if( (captureErr = ioctl( stream->capture->fd, SNDCTL_DSP_POST, 0 )) < 0 ) { PA_DEBUG(( "%s: Failed to stop capture device, error: %d\n", __FUNCTION__, captureErr )); } } if( stream->playback && !stream->sharedDevice ) { if( (playbackErr = ioctl( stream->playback->fd, SNDCTL_DSP_POST, 0 )) < 0 ) { PA_DEBUG(( "%s: Failed to stop playback device, error: %d\n", __FUNCTION__, playbackErr )); } } if( captureErr || playbackErr ) { result = paUnanticipatedHostError; } return result; } /** Clean up after thread exit. * * Aspect StreamState: If the user has registered a streamFinishedCallback it will be called here */ static void OnExit( void *data ) { PaOssStream *stream = (PaOssStream *) data; assert( data ); PaUtil_ResetCpuLoadMeasurer( &stream->cpuLoadMeasurer ); PaOssStream_Stop( stream, stream->callbackAbort ); PA_DEBUG(( "OnExit: Stoppage\n" )); /* Eventually notify user all buffers have played */ if( stream->streamRepresentation.streamFinishedCallback ) stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); stream->callbackAbort = 0; /* Clear state */ stream->isActive = 0; } static PaError SetUpBuffers( PaOssStream *stream, unsigned long framesAvail ) { PaError result = paNoError; if( stream->capture ) { PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, 0, stream->capture->buffer, stream->capture->hostChannelCount ); PaUtil_SetInputFrameCount( &stream->bufferProcessor, framesAvail ); } if( stream->playback ) { PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, 0, stream->playback->buffer, stream->playback->hostChannelCount ); PaUtil_SetOutputFrameCount( &stream->bufferProcessor, framesAvail ); } return result; } /** Thread procedure for callback processing. * * Aspect StreamState: StartStream will wait on this to initiate audio processing, useful in case the * callback should be used for buffer priming. When the stream is cancelled a separate function will * take care of the transition to the Callback Finished state (the stream isn't considered Stopped * before StopStream() or AbortStream() are called). */ static void *PaOSS_AudioThreadProc( void *userData ) { PaError result = paNoError; PaOssStream *stream = (PaOssStream*)userData; unsigned long framesAvail = 0, framesProcessed = 0; int callbackResult = paContinue; int triggered = stream->triggered; /* See if SNDCTL_DSP_TRIGGER has been issued already */ int initiateProcessing = triggered; /* Already triggered? */ PaStreamCallbackFlags cbFlags = 0; /* We might want to keep state across iterations */ PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /* TODO: IMPLEMENT ME */ /* #if ( SOUND_VERSION > 0x030904 ) audio_errinfo errinfo; #endif */ assert( stream ); pthread_cleanup_push( &OnExit, stream ); /* Execute OnExit when exiting */ /* The first time the stream is started we use SNDCTL_DSP_TRIGGER to accurately start capture and * playback in sync, when the stream is restarted after being stopped we simply start by reading/ * writing. */ PA_ENSURE( PaOssStream_Prepare( stream ) ); /* If we are to initiate processing implicitly by reading/writing data, we start off in blocking mode */ if( initiateProcessing ) { /* Make sure devices are in blocking mode */ if( stream->capture ) ModifyBlocking( stream->capture->fd, 1 ); if( stream->playback ) ModifyBlocking( stream->playback->fd, 1 ); } while( 1 ) { #ifdef PTHREAD_CANCELED pthread_testcancel(); #else if( stream->callbackAbort ) /* avoid indefinite waiting on thread not supporting cancelation */ { PA_DEBUG(( "Aborting callback thread\n" )); break; } #endif if( stream->callbackStop && callbackResult == paContinue ) { PA_DEBUG(( "Setting callbackResult to paComplete\n" )); callbackResult = paComplete; } /* Aspect StreamState: Because of the messy OSS scheme we can't explicitly trigger device start unless * the stream has been recently started, we will have to go right ahead and read/write in blocking * fashion to trigger operation. Therefore we begin with processing one host buffer before we switch * to non-blocking mode. */ if( !initiateProcessing ) { /* Wait on available frames */ PA_ENSURE( PaOssStream_WaitForFrames( stream, &framesAvail ) ); assert( framesAvail % stream->framesPerHostBuffer == 0 ); } else { framesAvail = stream->framesPerHostBuffer; } while( framesAvail > 0 ) { unsigned long frames = framesAvail; #ifdef PTHREAD_CANCELED pthread_testcancel(); #else if( stream->callbackStop ) { PA_DEBUG(( "Setting callbackResult to paComplete\n" )); callbackResult = paComplete; } if( stream->callbackAbort ) /* avoid indefinite waiting on thread not supporting cancelation */ { PA_DEBUG(( "Aborting callback thread\n" )); break; } #endif PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); /* Read data */ if ( stream->capture ) { PA_ENSURE( PaOssStreamComponent_Read( stream->capture, &frames ) ); if( frames < framesAvail ) { PA_DEBUG(( "Read %lu less frames than requested\n", framesAvail - frames )); framesAvail = frames; } } #if ( SOUND_VERSION >= 0x030904 ) /* Check with OSS to see if there have been any under/overruns since last time we checked. */ /* if( ioctl( stream->deviceHandle, SNDCTL_DSP_GETERROR, &errinfo ) >= 0 ) { if( errinfo.play_underruns ) cbFlags |= paOutputUnderflow ; if( errinfo.record_underruns ) cbFlags |= paInputUnderflow ; } else PA_DEBUG(( "SNDCTL_DSP_GETERROR command failed: %s\n", strerror( errno ) )); */ #endif PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, cbFlags ); cbFlags = 0; PA_ENSURE( SetUpBuffers( stream, framesAvail ) ); framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult ); assert( framesProcessed == framesAvail ); PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed ); if ( stream->playback ) { frames = framesAvail; PA_ENSURE( PaOssStreamComponent_Write( stream->playback, &frames ) ); if( frames < framesAvail ) { /* TODO: handle bytesWritten != bytesRequested (slippage?) */ PA_DEBUG(( "Wrote %lu less frames than requested\n", framesAvail - frames )); } } framesAvail -= framesProcessed; stream->framesProcessed += framesProcessed; if( callbackResult != paContinue ) break; } if( initiateProcessing || !triggered ) { /* Non-blocking */ if( stream->capture ) PA_ENSURE( ModifyBlocking( stream->capture->fd, 0 ) ); if( stream->playback && !stream->sharedDevice ) PA_ENSURE( ModifyBlocking( stream->playback->fd, 0 ) ); initiateProcessing = 0; sem_post( &stream->semaphore ); } if( callbackResult != paContinue ) { stream->callbackAbort = callbackResult == paAbort; if( stream->callbackAbort || PaUtil_IsBufferProcessorOutputEmpty( &stream->bufferProcessor ) ) break; } } pthread_cleanup_pop( 1 ); error: pthread_exit( NULL ); } /** Close the stream. * */ static PaError CloseStream( PaStream* s ) { PaError result = paNoError; PaOssStream *stream = (PaOssStream*)s; assert( stream ); PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); PaOssStream_Terminate( stream ); return result; } /** Start the stream. * * Aspect StreamState: After returning, the stream shall be in the Active state, implying that an eventual * callback will be repeatedly called in a separate thread. If a separate thread is started this function * will block untill it has started processing audio, otherwise audio processing is started directly. */ static PaError StartStream( PaStream *s ) { PaError result = paNoError; PaOssStream *stream = (PaOssStream*)s; stream->isActive = 1; stream->isStopped = 0; stream->lastPosPtr = 0; stream->lastStreamBytes = 0; stream->framesProcessed = 0; /* only use the thread for callback streams */ if( stream->bufferProcessor.streamCallback ) { PA_ENSURE( PaUtil_StartThreading( &stream->threading, &PaOSS_AudioThreadProc, stream ) ); sem_wait( &stream->semaphore ); } else PA_ENSURE( PaOssStream_Prepare( stream ) ); error: return result; } static PaError RealStop( PaOssStream *stream, int abort ) { PaError result = paNoError; if( stream->callbackMode ) { if( abort ) stream->callbackAbort = 1; else stream->callbackStop = 1; PA_ENSURE( PaUtil_CancelThreading( &stream->threading, !abort, NULL ) ); stream->callbackStop = stream->callbackAbort = 0; } else PA_ENSURE( PaOssStream_Stop( stream, abort ) ); stream->isStopped = 1; error: return result; } /** Stop the stream. * * Aspect StreamState: This will cause the stream to transition to the Stopped state, playing all enqueued * buffers. */ static PaError StopStream( PaStream *s ) { return RealStop( (PaOssStream *)s, 0 ); } /** Abort the stream. * * Aspect StreamState: This will cause the stream to transition to the Stopped state, discarding all enqueued * buffers. Note that the buffers are not currently correctly discarded, this is difficult without closing * the OSS device. */ static PaError AbortStream( PaStream *s ) { return RealStop( (PaOssStream *)s, 1 ); } /** Is the stream in the Stopped state. * */ static PaError IsStreamStopped( PaStream *s ) { PaOssStream *stream = (PaOssStream*)s; return (stream->isStopped); } /** Is the stream in the Active state. * */ static PaError IsStreamActive( PaStream *s ) { PaOssStream *stream = (PaOssStream*)s; return (stream->isActive); } static PaTime GetStreamTime( PaStream *s ) { PaOssStream *stream = (PaOssStream*)s; count_info info; int delta; if( stream->playback ) { if( ioctl( stream->playback->fd, SNDCTL_DSP_GETOPTR, &info) == 0 ) { delta = ( info.bytes - stream->lastPosPtr ) /* & 0x000FFFFF*/; return (float)(stream->lastStreamBytes + delta) / PaOssStreamComponent_FrameSize( stream->playback ) / stream->sampleRate; } } else { if (ioctl( stream->capture->fd, SNDCTL_DSP_GETIPTR, &info) == 0) { delta = (info.bytes - stream->lastPosPtr) /*& 0x000FFFFF*/; return (float)(stream->lastStreamBytes + delta) / PaOssStreamComponent_FrameSize( stream->capture ) / stream->sampleRate; } } /* the ioctl failed, but we can still give a coarse estimate */ return stream->framesProcessed / stream->sampleRate; } static double GetStreamCpuLoad( PaStream* s ) { PaOssStream *stream = (PaOssStream*)s; return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); } /* As separate stream interfaces are used for blocking and callback streams, the following functions can be guaranteed to only be called for blocking streams. */ static PaError ReadStream( PaStream* s, void *buffer, unsigned long frames ) { PaError result = paNoError; PaOssStream *stream = (PaOssStream*)s; int bytesRequested, bytesRead; unsigned long framesRequested; void *userBuffer; /* If user input is non-interleaved, PaUtil_CopyInput will manipulate the channel pointers, * so we copy the user provided pointers */ if( stream->bufferProcessor.userInputIsInterleaved ) userBuffer = buffer; else /* Copy channels into local array */ { userBuffer = stream->capture->userBuffers; memcpy( (void *)userBuffer, buffer, sizeof (void *) * stream->capture->userChannelCount ); } while( frames ) { framesRequested = PA_MIN( frames, stream->capture->hostFrames ); bytesRequested = framesRequested * PaOssStreamComponent_FrameSize( stream->capture ); ENSURE_( (bytesRead = read( stream->capture->fd, stream->capture->buffer, bytesRequested )), paUnanticipatedHostError ); if ( bytesRequested != bytesRead ) { PA_DEBUG(( "Requested %d bytes, read %d\n", bytesRequested, bytesRead )); return paUnanticipatedHostError; } PaUtil_SetInputFrameCount( &stream->bufferProcessor, stream->capture->hostFrames ); PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, 0, stream->capture->buffer, stream->capture->hostChannelCount ); PaUtil_CopyInput( &stream->bufferProcessor, &userBuffer, framesRequested ); frames -= framesRequested; } error: return result; } static PaError WriteStream( PaStream *s, const void *buffer, unsigned long frames ) { PaError result = paNoError; PaOssStream *stream = (PaOssStream*)s; int bytesRequested, bytesWritten; unsigned long framesConverted; const void *userBuffer; /* If user output is non-interleaved, PaUtil_CopyOutput will manipulate the channel pointers, * so we copy the user provided pointers */ if( stream->bufferProcessor.userOutputIsInterleaved ) userBuffer = buffer; else { /* Copy channels into local array */ userBuffer = stream->playback->userBuffers; memcpy( (void *)userBuffer, buffer, sizeof (void *) * stream->playback->userChannelCount ); } while( frames ) { PaUtil_SetOutputFrameCount( &stream->bufferProcessor, stream->playback->hostFrames ); PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, 0, stream->playback->buffer, stream->playback->hostChannelCount ); framesConverted = PaUtil_CopyOutput( &stream->bufferProcessor, &userBuffer, frames ); frames -= framesConverted; bytesRequested = framesConverted * PaOssStreamComponent_FrameSize( stream->playback ); ENSURE_( (bytesWritten = write( stream->playback->fd, stream->playback->buffer, bytesRequested )), paUnanticipatedHostError ); if ( bytesRequested != bytesWritten ) { PA_DEBUG(( "Requested %d bytes, wrote %d\n", bytesRequested, bytesWritten )); return paUnanticipatedHostError; } } error: return result; } static signed long GetStreamReadAvailable( PaStream* s ) { PaError result = paNoError; PaOssStream *stream = (PaOssStream*)s; audio_buf_info info; ENSURE_( ioctl( stream->capture->fd, SNDCTL_DSP_GETISPACE, &info ), paUnanticipatedHostError ); return info.fragments * stream->capture->hostFrames; error: return result; } /* TODO: Compute number of allocated bytes somewhere else, can we use ODELAY with capture */ static signed long GetStreamWriteAvailable( PaStream* s ) { PaError result = paNoError; PaOssStream *stream = (PaOssStream*)s; int delay = 0; #ifdef SNDCTL_DSP_GETODELAY ENSURE_( ioctl( stream->playback->fd, SNDCTL_DSP_GETODELAY, &delay ), paUnanticipatedHostError ); #endif return (PaOssStreamComponent_BufferSize( stream->playback ) - delay) / PaOssStreamComponent_FrameSize( stream->playback ); /* Conditionally compile this to avoid warning about unused label */ #ifdef SNDCTL_DSP_GETODELAY error: return result; #endif } praat-6.0.04/external/portaudio/pa_unix_util.c000066400000000000000000000503361261542461700214230ustar00rootroot00000000000000#ifdef UNIX /* * $Id: pa_unix_util.c 1510 2010-06-10 08:05:29Z dmitrykos $ * Portable Audio I/O Library * UNIX platform-specific support functions * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2000 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup unix_src */ #include #include #include #include #include #include #include /* For memset */ #include #include #if defined(__APPLE__) && !defined(HAVE_MACH_ABSOLUTE_TIME) #define HAVE_MACH_ABSOLUTE_TIME #endif #ifdef HAVE_MACH_ABSOLUTE_TIME #include #endif #include "pa_util.h" #include "pa_unix_util.h" #include "pa_debugprint.h" /* Track memory allocations to avoid leaks. */ #if PA_TRACK_MEMORY static int numAllocations_ = 0; #endif void *PaUtil_AllocateMemory( long size ) { void *result = malloc( size ); #if PA_TRACK_MEMORY if( result != NULL ) numAllocations_ += 1; #endif return result; } void PaUtil_FreeMemory( void *block ) { if( block != NULL ) { free( block ); #if PA_TRACK_MEMORY numAllocations_ -= 1; #endif } } int PaUtil_CountCurrentlyAllocatedBlocks( void ) { #if PA_TRACK_MEMORY return numAllocations_; #else return 0; #endif } void Pa_Sleep( long msec ) { #ifdef HAVE_NANOSLEEP struct timespec req = {0}, rem = {0}; PaTime time = msec / 1.e3; req.tv_sec = (time_t)time; assert(time - req.tv_sec < 1.0); req.tv_nsec = (long)((time - req.tv_sec) * 1.e9); nanosleep(&req, &rem); /* XXX: Try sleeping the remaining time (contained in rem) if interrupted by a signal? */ #else while( msec > 999 ) /* For OpenBSD and IRIX, argument */ { /* to usleep must be < 1000000. */ usleep( 999000 ); msec -= 999; } usleep( msec * 1000 ); #endif } #ifdef HAVE_MACH_ABSOLUTE_TIME /* Discussion on the CoreAudio mailing list suggests that calling gettimeofday (or anything else in the BSD layer) is not real-time safe, so we use mach_absolute_time on OSX. This implementation is based on these two links: Technical Q&A QA1398 - Mach Absolute Time Units http://developer.apple.com/mac/library/qa/qa2004/qa1398.html Tutorial: Performance and Time. http://www.macresearch.org/tutorial_performance_and_time */ /* Scaler to convert the result of mach_absolute_time to seconds */ static double machSecondsConversionScaler_ = 0.0; #endif void PaUtil_InitializeClock( void ) { #ifdef HAVE_MACH_ABSOLUTE_TIME mach_timebase_info_data_t info; kern_return_t err = mach_timebase_info( &info ); if( err == 0 ) machSecondsConversionScaler_ = 1e-9 * (double) info.numer / (double) info.denom; #endif } PaTime PaUtil_GetTime( void ) { #ifdef HAVE_MACH_ABSOLUTE_TIME return mach_absolute_time() * machSecondsConversionScaler_; #elif defined(HAVE_CLOCK_GETTIME) struct timespec tp; clock_gettime(CLOCK_REALTIME, &tp); return (PaTime)(tp.tv_sec + tp.tv_nsec * 1e-9); #else struct timeval tv; gettimeofday( &tv, NULL ); return (PaTime) tv.tv_usec * 1e-6 + tv.tv_sec; #endif } PaError PaUtil_InitializeThreading( PaUtilThreading *threading ) { (void) paUtilErr_; return paNoError; } void PaUtil_TerminateThreading( PaUtilThreading *threading ) { } PaError PaUtil_StartThreading( PaUtilThreading *threading, void *(*threadRoutine)(void *), void *data ) { pthread_create( &threading->callbackThread, NULL, threadRoutine, data ); return paNoError; } PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *exitResult ) { PaError result = paNoError; void *pret; if( exitResult ) *exitResult = paNoError; /* If pthread_cancel is not supported (Android platform) whole this function can lead to indefinite waiting if working thread (callbackThread) has'n received any stop signals from outside, please keep this in mind when considering using PaUtil_CancelThreading */ #ifdef PTHREAD_CANCELED /* Only kill the thread if it isn't in the process of stopping (flushing adaptation buffers) */ if( !wait ) pthread_cancel( threading->callbackThread ); /* XXX: Safe to call this if the thread has exited on its own? */ #endif pthread_join( threading->callbackThread, &pret ); #ifdef PTHREAD_CANCELED if( pret && PTHREAD_CANCELED != pret ) #else /* !wait means the thread may have been canceled */ if( pret && wait ) #endif { if( exitResult ) *exitResult = *(PaError *) pret; free( pret ); } return result; } /* Threading */ /* paUnixMainThread * We have to be a bit careful with defining this global variable, * as explained below. */ #ifdef __APPLE__ /* apple/gcc has a "problem" with global vars and dynamic libs. Initializing it seems to fix the problem. Described a bit in this thread: http://gcc.gnu.org/ml/gcc/2005-06/msg00179.html */ pthread_t paUnixMainThread = 0; #else /*pthreads are opaque. We don't know that asigning it an int value always makes sense, so we don't initialize it unless we have to.*/ pthread_t paUnixMainThread = 0; #endif PaError PaUnixThreading_Initialize( void ) { paUnixMainThread = pthread_self(); return paNoError; } static PaError BoostPriority( PaUnixThread* self ) { PaError result = paNoError; struct sched_param spm = { 0 }; /* Priority should only matter between contending FIFO threads? */ spm.sched_priority = 1; assert( self ); if( pthread_setschedparam( self->thread, SCHED_FIFO, &spm ) != 0 ) { PA_UNLESS( errno == EPERM, paInternalError ); /* Lack permission to raise priority */ PA_DEBUG(( "Failed bumping priority\n" )); result = 0; } else { result = 1; /* Success */ } error: return result; } PaError PaUnixThread_New( PaUnixThread* self, void* (*threadFunc)( void* ), void* threadArg, PaTime waitForChild, int rtSched ) { PaError result = paNoError; pthread_attr_t attr; int started = 0; memset( self, 0, sizeof (PaUnixThread) ); PaUnixMutex_Initialize( &self->mtx ); PA_ASSERT_CALL( pthread_cond_init( &self->cond, NULL ), 0 ); self->parentWaiting = 0 != waitForChild; /* Spawn thread */ /* Temporarily disabled since we should test during configuration for presence of required mman.h header */ #if 0 #if defined _POSIX_MEMLOCK && (_POSIX_MEMLOCK != -1) if( rtSched ) { if( mlockall( MCL_CURRENT | MCL_FUTURE ) < 0 ) { int savedErrno = errno; /* In case errno gets overwritten */ assert( savedErrno != EINVAL ); /* Most likely a programmer error */ PA_UNLESS( (savedErrno == EPERM), paInternalError ); PA_DEBUG(( "%s: Failed locking memory\n", __FUNCTION__ )); } else PA_DEBUG(( "%s: Successfully locked memory\n", __FUNCTION__ )); } #endif #endif PA_UNLESS( !pthread_attr_init( &attr ), paInternalError ); /* Priority relative to other processes */ PA_UNLESS( !pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ), paInternalError ); PA_UNLESS( !pthread_create( &self->thread, &attr, threadFunc, threadArg ), paInternalError ); started = 1; if( rtSched ) { #if 0 if( self->useWatchdog ) { int err; struct sched_param wdSpm = { 0 }; /* Launch watchdog, watchdog sets callback thread priority */ int prio = PA_MIN( self->rtPrio + 4, sched_get_priority_max( SCHED_FIFO ) ); wdSpm.sched_priority = prio; PA_UNLESS( !pthread_attr_init( &attr ), paInternalError ); PA_UNLESS( !pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED ), paInternalError ); PA_UNLESS( !pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ), paInternalError ); PA_UNLESS( !pthread_attr_setschedpolicy( &attr, SCHED_FIFO ), paInternalError ); PA_UNLESS( !pthread_attr_setschedparam( &attr, &wdSpm ), paInternalError ); if( (err = pthread_create( &self->watchdogThread, &attr, &WatchdogFunc, self )) ) { PA_UNLESS( err == EPERM, paInternalError ); /* Permission error, go on without realtime privileges */ PA_DEBUG(( "Failed bumping priority\n" )); } else { int policy; self->watchdogRunning = 1; PA_ENSURE_SYSTEM( pthread_getschedparam( self->watchdogThread, &policy, &wdSpm ), 0 ); /* Check if priority is right, policy could potentially differ from SCHED_FIFO (but that's alright) */ if( wdSpm.sched_priority != prio ) { PA_DEBUG(( "Watchdog priority not set correctly (%d)\n", wdSpm.sched_priority )); PA_ENSURE( paInternalError ); } } } else #endif PA_ENSURE( BoostPriority( self ) ); { int policy; struct sched_param spm; pthread_getschedparam(self->thread, &policy, &spm); } } if( self->parentWaiting ) { PaTime till; struct timespec ts; int res = 0; PaTime now; PA_ENSURE( PaUnixMutex_Lock( &self->mtx ) ); /* Wait for stream to be started */ now = PaUtil_GetTime(); till = now + waitForChild; while( self->parentWaiting && !res ) { if( waitForChild > 0 ) { ts.tv_sec = (time_t) floor( till ); ts.tv_nsec = (long) ((till - floor( till )) * 1e9); res = pthread_cond_timedwait( &self->cond, &self->mtx.mtx, &ts ); } else { res = pthread_cond_wait( &self->cond, &self->mtx.mtx ); } } PA_ENSURE( PaUnixMutex_Unlock( &self->mtx ) ); PA_UNLESS( !res || ETIMEDOUT == res, paInternalError ); PA_DEBUG(( "%s: Waited for %g seconds for stream to start\n", __FUNCTION__, PaUtil_GetTime() - now )); if( ETIMEDOUT == res ) { PA_ENSURE( paTimedOut ); } } end: return result; error: if( started ) { PaUnixThread_Terminate( self, 0, NULL ); } goto end; } PaError PaUnixThread_Terminate( PaUnixThread* self, int wait, PaError* exitResult ) { PaError result = paNoError; void* pret; if( exitResult ) { *exitResult = paNoError; } #if 0 if( watchdogExitResult ) *watchdogExitResult = paNoError; if( th->watchdogRunning ) { pthread_cancel( th->watchdogThread ); PA_ENSURE_SYSTEM( pthread_join( th->watchdogThread, &pret ), 0 ); if( pret && pret != PTHREAD_CANCELED ) { if( watchdogExitResult ) *watchdogExitResult = *(PaError *) pret; free( pret ); } } #endif /* Only kill the thread if it isn't in the process of stopping (flushing adaptation buffers) */ /* TODO: Make join time out */ self->stopRequested = wait; if( !wait ) { PA_DEBUG(( "%s: Canceling thread %d\n", __FUNCTION__, self->thread )); /* XXX: Safe to call this if the thread has exited on its own? */ #ifdef PTHREAD_CANCELED pthread_cancel( self->thread ); #endif } PA_DEBUG(( "%s: Joining thread %d\n", __FUNCTION__, self->thread )); PA_ENSURE_SYSTEM( pthread_join( self->thread, &pret ), 0 ); #ifdef PTHREAD_CANCELED if( pret && PTHREAD_CANCELED != pret ) #else /* !wait means the thread may have been canceled */ if( pret && wait ) #endif { if( exitResult ) { *exitResult = *(PaError*)pret; } free( pret ); } error: PA_ASSERT_CALL( PaUnixMutex_Terminate( &self->mtx ), paNoError ); PA_ASSERT_CALL( pthread_cond_destroy( &self->cond ), 0 ); return result; } PaError PaUnixThread_PrepareNotify( PaUnixThread* self ) { PaError result = paNoError; PA_UNLESS( self->parentWaiting, paInternalError ); PA_ENSURE( PaUnixMutex_Lock( &self->mtx ) ); self->locked = 1; error: return result; } PaError PaUnixThread_NotifyParent( PaUnixThread* self ) { PaError result = paNoError; PA_UNLESS( self->parentWaiting, paInternalError ); if( !self->locked ) { PA_ENSURE( PaUnixMutex_Lock( &self->mtx ) ); self->locked = 1; } self->parentWaiting = 0; pthread_cond_signal( &self->cond ); PA_ENSURE( PaUnixMutex_Unlock( &self->mtx ) ); self->locked = 0; error: return result; } int PaUnixThread_StopRequested( PaUnixThread* self ) { return self->stopRequested; } PaError PaUnixMutex_Initialize( PaUnixMutex* self ) { PaError result = paNoError; PA_ASSERT_CALL( pthread_mutex_init( &self->mtx, NULL ), 0 ); return result; } PaError PaUnixMutex_Terminate( PaUnixMutex* self ) { PaError result = paNoError; PA_ASSERT_CALL( pthread_mutex_destroy( &self->mtx ), 0 ); return result; } /** Lock mutex. * * We're disabling thread cancellation while the thread is holding a lock, so mutexes are * properly unlocked at termination time. */ PaError PaUnixMutex_Lock( PaUnixMutex* self ) { PaError result = paNoError; #ifdef PTHREAD_CANCEL int oldState; PA_ENSURE_SYSTEM( pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldState ), 0 ); #endif PA_ENSURE_SYSTEM( pthread_mutex_lock( &self->mtx ), 0 ); error: return result; } /** Unlock mutex. * * Thread cancellation is enabled again after the mutex is properly unlocked. */ PaError PaUnixMutex_Unlock( PaUnixMutex* self ) { PaError result = paNoError; PA_ENSURE_SYSTEM( pthread_mutex_unlock( &self->mtx ), 0 ); #ifdef PTHREAD_CANCEL int oldState; PA_ENSURE_SYSTEM( pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, &oldState ), 0 ); #endif error: return result; } #if 0 static void OnWatchdogExit( void *userData ) { PaAlsaThreading *th = (PaAlsaThreading *) userData; struct sched_param spm = { 0 }; assert( th ); PA_ASSERT_CALL( pthread_setschedparam( th->callbackThread, SCHED_OTHER, &spm ), 0 ); /* Lower before exiting */ PA_DEBUG(( "Watchdog exiting\n" )); } static void *WatchdogFunc( void *userData ) { PaError result = paNoError, *pres = NULL; int err; PaAlsaThreading *th = (PaAlsaThreading *) userData; unsigned intervalMsec = 500; const PaTime maxSeconds = 3.; /* Max seconds between callbacks */ PaTime timeThen = PaUtil_GetTime(), timeNow, timeElapsed, cpuTimeThen, cpuTimeNow, cpuTimeElapsed; double cpuLoad, avgCpuLoad = 0.; int throttled = 0; assert( th ); /* Execute OnWatchdogExit when exiting */ pthread_cleanup_push( &OnWatchdogExit, th ); /* Boost priority of callback thread */ PA_ENSURE( result = BoostPriority( th ) ); if( !result ) { /* Boost failed, might as well exit */ pthread_exit( NULL ); } cpuTimeThen = th->callbackCpuTime; { int policy; struct sched_param spm = { 0 }; pthread_getschedparam( pthread_self(), &policy, &spm ); PA_DEBUG(( "%s: Watchdog priority is %d\n", __FUNCTION__, spm.sched_priority )); } while( 1 ) { double lowpassCoeff = 0.9, lowpassCoeff1 = 0.99999 - lowpassCoeff; /* Test before and after in case whatever underlying sleep call isn't interrupted by pthread_cancel */ pthread_testcancel(); Pa_Sleep( intervalMsec ); pthread_testcancel(); if( PaUtil_GetTime() - th->callbackTime > maxSeconds ) { PA_DEBUG(( "Watchdog: Terminating callback thread\n" )); /* Tell thread to terminate */ err = pthread_kill( th->callbackThread, SIGKILL ); pthread_exit( NULL ); } PA_DEBUG(( "%s: PortAudio reports CPU load: %g\n", __FUNCTION__, PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) )); /* Check if we should throttle, or unthrottle :P */ cpuTimeNow = th->callbackCpuTime; cpuTimeElapsed = cpuTimeNow - cpuTimeThen; cpuTimeThen = cpuTimeNow; timeNow = PaUtil_GetTime(); timeElapsed = timeNow - timeThen; timeThen = timeNow; cpuLoad = cpuTimeElapsed / timeElapsed; avgCpuLoad = avgCpuLoad * lowpassCoeff + cpuLoad * lowpassCoeff1; /* if( throttled ) PA_DEBUG(( "Watchdog: CPU load: %g, %g\n", avgCpuLoad, cpuTimeElapsed )); */ if( PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) > .925 ) { static int policy; static struct sched_param spm = { 0 }; static const struct sched_param defaultSpm = { 0 }; PA_DEBUG(( "%s: Throttling audio thread, priority %d\n", __FUNCTION__, spm.sched_priority )); pthread_getschedparam( th->callbackThread, &policy, &spm ); if( !pthread_setschedparam( th->callbackThread, SCHED_OTHER, &defaultSpm ) ) { throttled = 1; } else PA_DEBUG(( "Watchdog: Couldn't lower priority of audio thread: %s\n", strerror( errno ) )); /* Give other processes a go, before raising priority again */ PA_DEBUG(( "%s: Watchdog sleeping for %lu msecs before unthrottling\n", __FUNCTION__, th->throttledSleepTime )); Pa_Sleep( th->throttledSleepTime ); /* Reset callback priority */ if( pthread_setschedparam( th->callbackThread, SCHED_FIFO, &spm ) != 0 ) { PA_DEBUG(( "%s: Couldn't raise priority of audio thread: %s\n", __FUNCTION__, strerror( errno ) )); } if( PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) >= .99 ) intervalMsec = 50; else intervalMsec = 100; /* lowpassCoeff = .97; lowpassCoeff1 = .99999 - lowpassCoeff; */ } else if( throttled && avgCpuLoad < .8 ) { intervalMsec = 500; throttled = 0; /* lowpassCoeff = .9; lowpassCoeff1 = .99999 - lowpassCoeff; */ } } pthread_cleanup_pop( 1 ); /* Execute cleanup on exit */ error: /* Shouldn't get here in the normal case */ /* Pass on error code */ pres = malloc( sizeof (PaError) ); *pres = result; pthread_exit( pres ); } static void CallbackUpdate( PaAlsaThreading *th ) { th->callbackTime = PaUtil_GetTime(); th->callbackCpuTime = PaUtil_GetCpuLoad( th->cpuLoadMeasurer ); } /* static void *CanaryFunc( void *userData ) { const unsigned intervalMsec = 1000; PaUtilThreading *th = (PaUtilThreading *) userData; while( 1 ) { th->canaryTime = PaUtil_GetTime(); pthread_testcancel(); Pa_Sleep( intervalMsec ); } pthread_exit( NULL ); } */ #endif #endif praat-6.0.04/external/portaudio/pa_unix_util.h000066400000000000000000000173761261542461700214370ustar00rootroot00000000000000/* * $Id: pa_unix_util.h 1241 2007-07-23 20:08:31Z aknudsen $ * Portable Audio I/O Library * UNIX platform-specific support functions * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2000 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup unix_src */ #ifndef PA_UNIX_UTIL_H #define PA_UNIX_UTIL_H #include "pa_cpuload.h" #include #include #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define PA_MIN(x,y) ( (x) < (y) ? (x) : (y) ) #define PA_MAX(x,y) ( (x) > (y) ? (x) : (y) ) /* Utilize GCC branch prediction for error tests */ #if defined __GNUC__ && __GNUC__ >= 3 #define UNLIKELY(expr) __builtin_expect( (expr), 0 ) #else #define UNLIKELY(expr) (expr) #endif #define STRINGIZE_HELPER(expr) #expr #define STRINGIZE(expr) STRINGIZE_HELPER(expr) #define PA_UNLESS(expr, code) \ do { \ if( UNLIKELY( (expr) == 0 ) ) \ { \ PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \ result = (code); \ goto error; \ } \ } while (0); static PaError paUtilErr_; /* Used with PA_ENSURE */ /* Check PaError */ #define PA_ENSURE(expr) \ do { \ if( UNLIKELY( (paUtilErr_ = (expr)) < paNoError ) ) \ { \ PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \ result = paUtilErr_; \ goto error; \ } \ } while (0); #define PA_ASSERT_CALL(expr, success) \ paUtilErr_ = (expr); \ assert( success == paUtilErr_ ); #define PA_ENSURE_SYSTEM(expr, success) \ do { \ if( UNLIKELY( (paUtilErr_ = (expr)) != success ) ) \ { \ /* PaUtil_SetLastHostErrorInfo should only be used in the main thread */ \ if( pthread_equal(pthread_self(), paUnixMainThread) ) \ { \ PaUtil_SetLastHostErrorInfo( paALSA, paUtilErr_, strerror( paUtilErr_ ) ); \ } \ PaUtil_DebugPrint( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" ); \ result = paUnanticipatedHostError; \ goto error; \ } \ } while( 0 ); typedef struct { pthread_t callbackThread; } PaUtilThreading; PaError PaUtil_InitializeThreading( PaUtilThreading *threading ); void PaUtil_TerminateThreading( PaUtilThreading *threading ); PaError PaUtil_StartThreading( PaUtilThreading *threading, void *(*threadRoutine)(void *), void *data ); PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *exitResult ); /* State accessed by utility functions */ /* void PaUnix_SetRealtimeScheduling( int rt ); void PaUtil_InitializeThreading( PaUtilThreading *th, PaUtilCpuLoadMeasurer *clm ); PaError PaUtil_CreateCallbackThread( PaUtilThreading *th, void *(*CallbackThreadFunc)( void * ), PaStream *s ); PaError PaUtil_KillCallbackThread( PaUtilThreading *th, PaError *exitResult ); void PaUtil_CallbackUpdate( PaUtilThreading *th ); */ extern pthread_t paUnixMainThread; typedef struct { pthread_mutex_t mtx; } PaUnixMutex; PaError PaUnixMutex_Initialize( PaUnixMutex* self ); PaError PaUnixMutex_Terminate( PaUnixMutex* self ); PaError PaUnixMutex_Lock( PaUnixMutex* self ); PaError PaUnixMutex_Unlock( PaUnixMutex* self ); typedef struct { pthread_t thread; int parentWaiting; int stopRequested; int locked; PaUnixMutex mtx; pthread_cond_t cond; volatile sig_atomic_t stopRequest; } PaUnixThread; /** Initialize global threading state. */ PaError PaUnixThreading_Initialize( void ); /** Perish, passing on eventual error code. * * A thin wrapper around pthread_exit, will automatically pass on any error code to the joining thread. * If the result indicates an error, i.e. it is not equal to paNoError, this function will automatically * allocate a pointer so the error is passed on with pthread_exit. If the result indicates that all is * well however, only a NULL pointer will be handed to pthread_exit. Thus, the joining thread should * check whether a non-NULL result pointer is obtained from pthread_join and make sure to free it. * @param result: The error code to pass on to the joining thread. */ #define PaUnixThreading_EXIT(result) \ do { \ PaError* pres = NULL; \ if( paNoError != (result) ) \ { \ pres = malloc( sizeof (PaError) ); \ *pres = (result); \ } \ pthread_exit( pres ); \ } while (0); /** Spawn a thread. * * Intended for spawning the callback thread from the main thread. This function can even block (for a certain * time or indefinitely) untill notified by the callback thread (using PaUnixThread_NotifyParent), which can be * useful in order to make sure that callback has commenced before returning from Pa_StartStream. * @param threadFunc: The function to be executed in the child thread. * @param waitForChild: If not 0, wait for child thread to call PaUnixThread_NotifyParent. Less than 0 means * wait for ever, greater than 0 wait for the specified time. * @param rtSched: Enable realtime scheduling? * @return: If timed out waiting on child, paTimedOut. */ PaError PaUnixThread_New( PaUnixThread* self, void* (*threadFunc)( void* ), void* threadArg, PaTime waitForChild, int rtSched ); /** Terminate thread. * * @param wait: If true, request that background thread stop and wait untill it does, else cancel it. * @param exitResult: If non-null this will upon return contain the exit status of the thread. */ PaError PaUnixThread_Terminate( PaUnixThread* self, int wait, PaError* exitResult ); /** Prepare to notify waiting parent thread. * * An internal lock must be held before the parent is notified in PaUnixThread_NotifyParent, call this to * acquire it beforehand. * @return: If parent is not waiting, paInternalError. */ PaError PaUnixThread_PrepareNotify( PaUnixThread* self ); /** Notify waiting parent thread. * * @return: If parent timed out waiting, paTimedOut. If parent was never waiting, paInternalError. */ PaError PaUnixThread_NotifyParent( PaUnixThread* self ); /** Has the parent thread requested this thread to stop? */ int PaUnixThread_StopRequested( PaUnixThread* self ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif praat-6.0.04/external/portaudio/pa_util.h000066400000000000000000000126201261542461700203570ustar00rootroot00000000000000#ifndef PA_UTIL_H #define PA_UTIL_H /* * $Id: pa_util.h 1584 2011-02-02 18:58:17Z rossb $ * Portable Audio I/O Library implementation utilities header * common implementation utilities and interfaces * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2008 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Prototypes for utility functions used by PortAudio implementations. Some functions declared here are defined in pa_front.c while others are implemented separately for each platform. */ #include "portaudio.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ struct PaUtilHostApiRepresentation; /** Retrieve a specific host API representation. This function can be used by implementations to retrieve a pointer to their representation in host api specific extension functions which aren't passed a rep pointer by pa_front.c. @param hostApi A pointer to a host API represenation pointer. Apon success this will receive the requested representation pointer. @param type A valid host API type identifier. @returns An error code. If the result is PaNoError then a pointer to the requested host API representation will be stored in *hostApi. If the host API specified by type is not found, this function returns paHostApiNotFound. */ PaError PaUtil_GetHostApiRepresentation( struct PaUtilHostApiRepresentation **hostApi, PaHostApiTypeId type ); /** Convert a PortAudio device index into a host API specific device index. @param hostApiDevice Pointer to a device index, on success this will recieve the converted device index value. @param device The PortAudio device index to convert. @param hostApi The host api which the index should be converted for. @returns On success returns PaNoError and places the converted index in the hostApiDevice parameter. */ PaError PaUtil_DeviceIndexToHostApiDeviceIndex( PaDeviceIndex *hostApiDevice, PaDeviceIndex device, struct PaUtilHostApiRepresentation *hostApi ); /** Set the host error information returned by Pa_GetLastHostErrorInfo. This function and the paUnanticipatedHostError error code should be used as a last resort. Implementors should use existing PA error codes where possible, or nominate new ones. Note that at it is always better to use PaUtil_SetLastHostErrorInfo() and paUnanticipatedHostError than to return an ambiguous or inaccurate PaError code. @param hostApiType The host API which encountered the error (ie of the caller) @param errorCode The error code returned by the native API function. @param errorText A string describing the error. PaUtil_SetLastHostErrorInfo makes a copy of the string, so it is not necessary for the pointer to remain valid after the call to PaUtil_SetLastHostErrorInfo() returns. */ void PaUtil_SetLastHostErrorInfo( PaHostApiTypeId hostApiType, long errorCode, const char *errorText ); /* the following functions are implemented in a platform platform specific .c file */ /** Allocate size bytes, guaranteed to be aligned to a FIXME byte boundary */ void *PaUtil_AllocateMemory( long size ); /** Realease block if non-NULL. block may be NULL */ void PaUtil_FreeMemory( void *block ); /** Return the number of currently allocated blocks. This function can be used for detecting memory leaks. @note Allocations will only be tracked if PA_TRACK_MEMORY is #defined. If it isn't, this function will always return 0. */ int PaUtil_CountCurrentlyAllocatedBlocks( void ); /** Initialize the clock used by PaUtil_GetTime(). Call this before calling PaUtil_GetTime. @see PaUtil_GetTime */ void PaUtil_InitializeClock( void ); /** Return the system time in seconds. Used to implement CPU load functions @see PaUtil_InitializeClock */ double PaUtil_GetTime( void ); /* void Pa_Sleep( long msec ); must also be implemented in per-platform .c file */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_UTIL_H */ praat-6.0.04/external/portaudio/pa_win_coinitialize.c000066400000000000000000000120611261542461700227340ustar00rootroot00000000000000/* * Microsoft COM initialization routines * Copyright (c) 1999-2011 Ross Bencina, Dmitry Kostjuchenko * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2011 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup win_src @brief Microsoft COM initialization routines. */ #include #include #include "portaudio.h" #include "pa_util.h" #include "pa_debugprint.h" #include "pa_win_coinitialize.h" #if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) && !defined(_WIN32_WCE) /* MSC version 6 and above */ #pragma comment( lib, "ole32.lib" ) #endif /* use some special bit patterns here to try to guard against uninitialized memory errors */ #define PAWINUTIL_COM_INITIALIZED (0xb38f) #define PAWINUTIL_COM_NOT_INITIALIZED (0xf1cd) PaError PaWinUtil_CoInitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult ) { HRESULT hr; comInitializationResult->state = PAWINUTIL_COM_NOT_INITIALIZED; /* If COM is already initialized CoInitialize will either return FALSE, or RPC_E_CHANGED_MODE if it was initialised in a different threading mode. In either case we shouldn't consider it an error but we need to be careful to not call CoUninitialize() if RPC_E_CHANGED_MODE was returned. */ hr = CoInitialize(0); /* use legacy-safe equivalent to CoInitializeEx(NULL, COINIT_APARTMENTTHREADED) */ if( FAILED(hr) && hr != RPC_E_CHANGED_MODE ) { PA_DEBUG(("CoInitialize(0) failed. hr=%d\n", hr)); if( hr == E_OUTOFMEMORY ) return paInsufficientMemory; { char *lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); PaUtil_SetLastHostErrorInfo( hostApiType, hr, lpMsgBuf ); LocalFree( lpMsgBuf ); } return paUnanticipatedHostError; } if( hr != RPC_E_CHANGED_MODE ) { comInitializationResult->state = PAWINUTIL_COM_INITIALIZED; /* Memorize calling thread id and report warning on Uninitialize if calling thread is different as CoInitialize must match CoUninitialize in the same thread. */ comInitializationResult->initializingThreadId = GetCurrentThreadId(); } return paNoError; } void PaWinUtil_CoUninitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult ) { if( comInitializationResult->state != PAWINUTIL_COM_NOT_INITIALIZED && comInitializationResult->state != PAWINUTIL_COM_INITIALIZED ){ PA_DEBUG(("ERROR: PaWinUtil_CoUninitialize called without calling PaWinUtil_CoInitialize\n")); } if( comInitializationResult->state == PAWINUTIL_COM_INITIALIZED ) { DWORD currentThreadId = GetCurrentThreadId(); if( comInitializationResult->initializingThreadId != currentThreadId ) { PA_DEBUG(("ERROR: failed PaWinUtil_CoUninitialize calling thread[%d] does not match initializing thread[%d]\n", currentThreadId, comInitializationResult->initializingThreadId)); } else { CoUninitialize(); comInitializationResult->state = PAWINUTIL_COM_NOT_INITIALIZED; } } }praat-6.0.04/external/portaudio/pa_win_coinitialize.h000066400000000000000000000067761261542461700227610ustar00rootroot00000000000000/* * Microsoft COM initialization routines * Copyright (c) 1999-2011 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup win_src @brief Microsoft COM initialization routines. */ #ifndef PA_WIN_COINITIALIZE_H #define PA_WIN_COINITIALIZE_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** @brief Data type used to hold the result of an attempt to initialize COM using PaWinUtil_CoInitialize. Must be retained between a call to PaWinUtil_CoInitialize and a matching call to PaWinUtil_CoUninitialize. */ typedef struct PaWinUtilComInitializationResult{ int state; int initializingThreadId; } PaWinUtilComInitializationResult; /** @brief Initialize Microsoft COM subsystem on the current thread. @param hostApiType the host API type id of the caller. Used for error reporting. @param comInitializationResult An output parameter. The value pointed to by this parameter stores information required by PaWinUtil_CoUninitialize to correctly uninitialize COM. The value should be retained and later passed to PaWinUtil_CoUninitialize. If PaWinUtil_CoInitialize returns paNoError, the caller must later call PaWinUtil_CoUninitialize once. */ PaError PaWinUtil_CoInitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult ); /** @brief Uninitialize the Microsoft COM subsystem on the current thread using the result of a previous call to PaWinUtil_CoInitialize. Must be called on the same thread as PaWinUtil_CoInitialize. @param hostApiType the host API type id of the caller. Used for error reporting. @param comInitializationResult An input parameter. A pointer to a value previously initialized by a call to PaWinUtil_CoInitialize. */ void PaWinUtil_CoUninitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_WIN_COINITIALIZE_H */ praat-6.0.04/external/portaudio/pa_win_ds.c000066400000000000000000003625741261542461700207000ustar00rootroot00000000000000#ifdef _WIN32 /* * $Id: pa_win_ds.c 1877 2012-11-10 02:55:20Z rbencina $ * Portable Audio I/O Library DirectSound implementation * * Authors: Phil Burk, Robert Marsanyi & Ross Bencina * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2007 Ross Bencina, Phil Burk, Robert Marsanyi * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostapi_src */ /* Until May 2011 PA/DS has used a multimedia timer to perform the callback. We're replacing this with a new implementation using a thread and a different timer mechanim. Defining PA_WIN_DS_USE_WMME_TIMER uses the old (pre-May 2011) behavior. */ //#define PA_WIN_DS_USE_WMME_TIMER #include #include #include /* strlen() */ #define _WIN32_WINNT 0x0400 /* required to get waitable timer APIs */ #include /* make sure ds guids get defined */ #include #include /* Use the earliest version of DX required, no need to polute the namespace */ #ifdef PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE #define DIRECTSOUND_VERSION 0x0800 #else #define DIRECTSOUND_VERSION 0x0300 #endif #include #ifdef PAWIN_USE_WDMKS_DEVICE_INFO #include #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ #ifndef PA_WIN_DS_USE_WMME_TIMER #ifndef UNDER_CE #include #endif #endif #include "pa_util.h" #include "pa_allocation.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_cpuload.h" #include "pa_process.h" #include "pa_debugprint.h" #include "pa_win_ds.h" #include "pa_win_ds_dynlink.h" #include "pa_win_waveformat.h" #include "pa_win_wdmks_utils.h" #include "pa_win_coinitialize.h" #if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */ #pragma comment( lib, "dsound.lib" ) #pragma comment( lib, "winmm.lib" ) #pragma comment( lib, "kernel32.lib" ) #endif /* use CreateThread for CYGWIN, _beginthreadex for all others */ #ifndef PA_WIN_DS_USE_WMME_TIMER #if !defined(__CYGWIN__) && !defined(UNDER_CE) #define CREATE_THREAD (HANDLE)_beginthreadex #undef CLOSE_THREAD_HANDLE /* as per documentation we don't call CloseHandle on a thread created with _beginthreadex */ #define PA_THREAD_FUNC static unsigned WINAPI #define PA_THREAD_ID unsigned #else #define CREATE_THREAD CreateThread #define CLOSE_THREAD_HANDLE CloseHandle #define PA_THREAD_FUNC static DWORD WINAPI #define PA_THREAD_ID DWORD #endif #if (defined(UNDER_CE)) #pragma comment(lib, "Coredll.lib") #elif (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */ #pragma comment(lib, "winmm.lib") #endif PA_THREAD_FUNC ProcessingThreadProc( void *pArg ); #if !defined(UNDER_CE) #define PA_WIN_DS_USE_WAITABLE_TIMER_OBJECT /* use waitable timer where possible, otherwise we use a WaitForSingleObject timeout */ #endif #endif /* !PA_WIN_DS_USE_WMME_TIMER */ /* provided in newer platform sdks and x64 */ #ifndef DWORD_PTR #if defined(_WIN64) #define DWORD_PTR unsigned __int64 #else #define DWORD_PTR unsigned long #endif #endif #define PRINT(x) PA_DEBUG(x); #define ERR_RPT(x) PRINT(x) #define DBUG(x) PRINT(x) #define DBUGX(x) PRINT(x) #define PA_USE_HIGH_LATENCY (0) #if PA_USE_HIGH_LATENCY #define PA_DS_WIN_9X_DEFAULT_LATENCY_ (.500) #define PA_DS_WIN_NT_DEFAULT_LATENCY_ (.600) #else #define PA_DS_WIN_9X_DEFAULT_LATENCY_ (.140) #define PA_DS_WIN_NT_DEFAULT_LATENCY_ (.280) #endif #define PA_DS_WIN_WDM_DEFAULT_LATENCY_ (.120) /* we allow the polling period to range between 1 and 100ms. prior to August 2011 we limited the minimum polling period to 10ms. */ #define PA_DS_MINIMUM_POLLING_PERIOD_SECONDS (0.001) /* 1ms */ #define PA_DS_MAXIMUM_POLLING_PERIOD_SECONDS (0.100) /* 100ms */ #define PA_DS_POLLING_JITTER_SECONDS (0.001) /* 1ms */ #define SECONDS_PER_MSEC (0.001) #define MSECS_PER_SECOND (1000) /* prototypes for functions declared in this file */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); #ifdef __cplusplus } #endif /* __cplusplus */ static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); static PaError CloseStream( PaStream* stream ); static PaError StartStream( PaStream *stream ); static PaError StopStream( PaStream *stream ); static PaError AbortStream( PaStream *stream ); static PaError IsStreamStopped( PaStream *s ); static PaError IsStreamActive( PaStream *stream ); static PaTime GetStreamTime( PaStream *stream ); static double GetStreamCpuLoad( PaStream* stream ); static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ); static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ); static signed long GetStreamReadAvailable( PaStream* stream ); static signed long GetStreamWriteAvailable( PaStream* stream ); /* FIXME: should convert hr to a string */ #define PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr ) \ PaUtil_SetLastHostErrorInfo( paDirectSound, hr, "DirectSound error" ) /************************************************* DX Prototypes **********/ static BOOL CALLBACK CollectGUIDsProcA(LPGUID lpGUID, LPCSTR lpszDesc, LPCSTR lpszDrvName, LPVOID lpContext ); /************************************************************************************/ /********************** Structures **************************************************/ /************************************************************************************/ /* PaWinDsHostApiRepresentation - host api datastructure specific to this implementation */ typedef struct PaWinDsDeviceInfo { PaDeviceInfo inheritedDeviceInfo; GUID guid; GUID *lpGUID; double sampleRates[3]; char deviceInputChannelCountIsKnown; /**<< if the system returns 0xFFFF then we don't really know the number of supported channels (1=>known, 0=>unknown)*/ char deviceOutputChannelCountIsKnown; /**<< if the system returns 0xFFFF then we don't really know the number of supported channels (1=>known, 0=>unknown)*/ } PaWinDsDeviceInfo; typedef struct { PaUtilHostApiRepresentation inheritedHostApiRep; PaUtilStreamInterface callbackStreamInterface; PaUtilStreamInterface blockingStreamInterface; PaUtilAllocationGroup *allocations; /* implementation specific data goes here */ PaWinUtilComInitializationResult comInitializationResult; } PaWinDsHostApiRepresentation; /* PaWinDsStream - a stream data structure specifically for this implementation */ typedef struct PaWinDsStream { PaUtilStreamRepresentation streamRepresentation; PaUtilCpuLoadMeasurer cpuLoadMeasurer; PaUtilBufferProcessor bufferProcessor; /* DirectSound specific data. */ #ifdef PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE LPDIRECTSOUNDFULLDUPLEX8 pDirectSoundFullDuplex8; #endif /* Output */ LPDIRECTSOUND pDirectSound; LPDIRECTSOUNDBUFFER pDirectSoundPrimaryBuffer; LPDIRECTSOUNDBUFFER pDirectSoundOutputBuffer; DWORD outputBufferWriteOffsetBytes; /* last write position */ INT outputBufferSizeBytes; INT outputFrameSizeBytes; /* Try to detect play buffer underflows. */ LARGE_INTEGER perfCounterTicksPerBuffer; /* counter ticks it should take to play a full buffer */ LARGE_INTEGER previousPlayTime; DWORD previousPlayCursor; UINT outputUnderflowCount; BOOL outputIsRunning; INT finalZeroBytesWritten; /* used to determine when we've flushed the whole buffer */ /* Input */ LPDIRECTSOUNDCAPTURE pDirectSoundCapture; LPDIRECTSOUNDCAPTUREBUFFER pDirectSoundInputBuffer; INT inputFrameSizeBytes; UINT readOffset; /* last read position */ UINT inputBufferSizeBytes; int hostBufferSizeFrames; /* input and output host ringbuffers have the same number of frames */ double framesWritten; double secondsPerHostByte; /* Used to optimize latency calculation for outTime */ double pollingPeriodSeconds; PaStreamCallbackFlags callbackFlags; PaStreamFlags streamFlags; int callbackResult; HANDLE processingCompleted; /* FIXME - move all below to PaUtilStreamRepresentation */ volatile int isStarted; volatile int isActive; volatile int stopProcessing; /* stop thread once existing buffers have been returned */ volatile int abortProcessing; /* stop thread immediately */ UINT systemTimerResolutionPeriodMs; /* set to 0 if we were unable to set the timer period */ #ifdef PA_WIN_DS_USE_WMME_TIMER MMRESULT timerID; #else #ifdef PA_WIN_DS_USE_WAITABLE_TIMER_OBJECT HANDLE waitableTimer; #endif HANDLE processingThread; PA_THREAD_ID processingThreadId; HANDLE processingThreadCompleted; #endif } PaWinDsStream; /* Set minimal latency based on the current OS version. * NT has higher latency. */ static double PaWinDS_GetMinSystemLatencySeconds( void ) { double minLatencySeconds; /* Set minimal latency based on whether NT or other OS. * NT has higher latency. */ OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof( osvi ); GetVersionEx( &osvi ); DBUG(("PA - PlatformId = 0x%x\n", osvi.dwPlatformId )); DBUG(("PA - MajorVersion = 0x%x\n", osvi.dwMajorVersion )); DBUG(("PA - MinorVersion = 0x%x\n", osvi.dwMinorVersion )); /* Check for NT */ if( (osvi.dwMajorVersion == 4) && (osvi.dwPlatformId == 2) ) { minLatencySeconds = PA_DS_WIN_NT_DEFAULT_LATENCY_; } else if(osvi.dwMajorVersion >= 5) { minLatencySeconds = PA_DS_WIN_WDM_DEFAULT_LATENCY_; } else { minLatencySeconds = PA_DS_WIN_9X_DEFAULT_LATENCY_; } return minLatencySeconds; } /************************************************************************* ** Return minimum workable latency required for this host. This is returned ** As the default stream latency in PaDeviceInfo. ** Latency can be optionally set by user by setting an environment variable. ** For example, to set latency to 200 msec, put: ** ** set PA_MIN_LATENCY_MSEC=200 ** ** in the AUTOEXEC.BAT file and reboot. ** If the environment variable is not set, then the latency will be determined ** based on the OS. Windows NT has higher latency than Win95. */ #define PA_LATENCY_ENV_NAME ("PA_MIN_LATENCY_MSEC") #define PA_ENV_BUF_SIZE (32) static double PaWinDs_GetMinLatencySeconds( double sampleRate ) { char envbuf[PA_ENV_BUF_SIZE]; DWORD hresult; double minLatencySeconds = 0; /* Let user determine minimal latency by setting environment variable. */ hresult = GetEnvironmentVariableA( PA_LATENCY_ENV_NAME, envbuf, PA_ENV_BUF_SIZE ); if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) ) { minLatencySeconds = atoi( envbuf ) * SECONDS_PER_MSEC; } else { minLatencySeconds = PaWinDS_GetMinSystemLatencySeconds(); #if PA_USE_HIGH_LATENCY PRINT(("PA - Minimum Latency set to %f msec!\n", minLatencySeconds * MSECS_PER_SECOND )); #endif } return minLatencySeconds; } /************************************************************************************ ** Duplicate the input string using the allocations allocator. ** A NULL string is converted to a zero length string. ** If memory cannot be allocated, NULL is returned. **/ static char *DuplicateDeviceNameString( PaUtilAllocationGroup *allocations, const char* src ) { char *result = 0; if( src != NULL ) { size_t len = strlen(src); result = (char*)PaUtil_GroupAllocateMemory( allocations, (long)(len + 1) ); if( result ) memcpy( (void *) result, src, len+1 ); } else { result = (char*)PaUtil_GroupAllocateMemory( allocations, 1 ); if( result ) result[0] = '\0'; } return result; } /************************************************************************************ ** DSDeviceNameAndGUID, DSDeviceNameAndGUIDVector used for collecting preliminary ** information during device enumeration. */ typedef struct DSDeviceNameAndGUID{ char *name; // allocated from parent's allocations, never deleted by this structure GUID guid; LPGUID lpGUID; void *pnpInterface; // wchar_t* interface path, allocated using the DS host api's allocation group } DSDeviceNameAndGUID; typedef struct DSDeviceNameAndGUIDVector{ PaUtilAllocationGroup *allocations; PaError enumerationError; int count; int free; DSDeviceNameAndGUID *items; // Allocated using LocalAlloc() } DSDeviceNameAndGUIDVector; typedef struct DSDeviceNamesAndGUIDs{ PaWinDsHostApiRepresentation *winDsHostApi; DSDeviceNameAndGUIDVector inputNamesAndGUIDs; DSDeviceNameAndGUIDVector outputNamesAndGUIDs; } DSDeviceNamesAndGUIDs; static PaError InitializeDSDeviceNameAndGUIDVector( DSDeviceNameAndGUIDVector *guidVector, PaUtilAllocationGroup *allocations ) { PaError result = paNoError; guidVector->allocations = allocations; guidVector->enumerationError = paNoError; guidVector->count = 0; guidVector->free = 8; guidVector->items = (DSDeviceNameAndGUID*)LocalAlloc( LMEM_FIXED, sizeof(DSDeviceNameAndGUID) * guidVector->free ); if( guidVector->items == NULL ) result = paInsufficientMemory; return result; } static PaError ExpandDSDeviceNameAndGUIDVector( DSDeviceNameAndGUIDVector *guidVector ) { PaError result = paNoError; DSDeviceNameAndGUID *newItems; int i; /* double size of vector */ int size = guidVector->count + guidVector->free; guidVector->free += size; newItems = (DSDeviceNameAndGUID*)LocalAlloc( LMEM_FIXED, sizeof(DSDeviceNameAndGUID) * size * 2 ); if( newItems == NULL ) { result = paInsufficientMemory; } else { for( i=0; i < guidVector->count; ++i ) { newItems[i].name = guidVector->items[i].name; if( guidVector->items[i].lpGUID == NULL ) { newItems[i].lpGUID = NULL; } else { newItems[i].lpGUID = &newItems[i].guid; memcpy( &newItems[i].guid, guidVector->items[i].lpGUID, sizeof(GUID) ); } newItems[i].pnpInterface = guidVector->items[i].pnpInterface; } LocalFree( guidVector->items ); guidVector->items = newItems; } return result; } /* it's safe to call DSDeviceNameAndGUIDVector multiple times */ static PaError TerminateDSDeviceNameAndGUIDVector( DSDeviceNameAndGUIDVector *guidVector ) { PaError result = paNoError; if( guidVector->items != NULL ) { if( LocalFree( guidVector->items ) != NULL ) result = paInsufficientMemory; /** @todo this isn't the correct error to return from a deallocation failure */ guidVector->items = NULL; } return result; } /************************************************************************************ ** Collect preliminary device information during DirectSound enumeration */ static BOOL CALLBACK CollectGUIDsProcA(LPGUID lpGUID, LPCSTR lpszDesc, LPCSTR lpszDrvName, LPVOID lpContext ) { DSDeviceNameAndGUIDVector *namesAndGUIDs = (DSDeviceNameAndGUIDVector*)lpContext; PaError error; (void) lpszDrvName; /* unused variable */ if( namesAndGUIDs->free == 0 ) { error = ExpandDSDeviceNameAndGUIDVector( namesAndGUIDs ); if( error != paNoError ) { namesAndGUIDs->enumerationError = error; return FALSE; } } /* Set GUID pointer, copy GUID to storage in DSDeviceNameAndGUIDVector. */ if( lpGUID == NULL ) { namesAndGUIDs->items[namesAndGUIDs->count].lpGUID = NULL; } else { namesAndGUIDs->items[namesAndGUIDs->count].lpGUID = &namesAndGUIDs->items[namesAndGUIDs->count].guid; memcpy( &namesAndGUIDs->items[namesAndGUIDs->count].guid, lpGUID, sizeof(GUID) ); } namesAndGUIDs->items[namesAndGUIDs->count].name = DuplicateDeviceNameString( namesAndGUIDs->allocations, lpszDesc ); if( namesAndGUIDs->items[namesAndGUIDs->count].name == NULL ) { namesAndGUIDs->enumerationError = paInsufficientMemory; return FALSE; } namesAndGUIDs->items[namesAndGUIDs->count].pnpInterface = 0; ++namesAndGUIDs->count; --namesAndGUIDs->free; return TRUE; } #ifdef PAWIN_USE_WDMKS_DEVICE_INFO static void *DuplicateWCharString( PaUtilAllocationGroup *allocations, wchar_t *source ) { size_t len; wchar_t *result; len = wcslen( source ); result = (wchar_t*)PaUtil_GroupAllocateMemory( allocations, (long) ((len+1) * sizeof(wchar_t)) ); wcscpy( result, source ); return result; } static BOOL CALLBACK KsPropertySetEnumerateCallback( PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data, LPVOID context ) { int i; DSDeviceNamesAndGUIDs *deviceNamesAndGUIDs = (DSDeviceNamesAndGUIDs*)context; /* Apparently data->Interface can be NULL in some cases. Possibly virtual devices without hardware. So we check for NULLs now. See mailing list message November 10, 2012: "[Portaudio] portaudio initialization crash in KsPropertySetEnumerateCallback(pa_win_ds.c)" */ if( data->Interface ) { if( data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER ) { for( i=0; i < deviceNamesAndGUIDs->outputNamesAndGUIDs.count; ++i ) { if( deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].lpGUID && memcmp( &data->DeviceId, deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].lpGUID, sizeof(GUID) ) == 0 ) { deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].pnpInterface = (char*)DuplicateWCharString( deviceNamesAndGUIDs->winDsHostApi->allocations, data->Interface ); break; } } } else if( data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE ) { for( i=0; i < deviceNamesAndGUIDs->inputNamesAndGUIDs.count; ++i ) { if( deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].lpGUID && memcmp( &data->DeviceId, deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].lpGUID, sizeof(GUID) ) == 0 ) { deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].pnpInterface = (char*)DuplicateWCharString( deviceNamesAndGUIDs->winDsHostApi->allocations, data->Interface ); break; } } } } return TRUE; } static GUID pawin_CLSID_DirectSoundPrivate = { 0x11ab3ec0, 0x25ec, 0x11d1, 0xa4, 0xd8, 0x00, 0xc0, 0x4f, 0xc2, 0x8a, 0xca }; static GUID pawin_DSPROPSETID_DirectSoundDevice = { 0x84624f82, 0x25ec, 0x11d1, 0xa4, 0xd8, 0x00, 0xc0, 0x4f, 0xc2, 0x8a, 0xca }; static GUID pawin_IID_IKsPropertySet = { 0x31efac30, 0x515c, 0x11d0, 0xa9, 0xaa, 0x00, 0xaa, 0x00, 0x61, 0xbe, 0x93 }; /* FindDevicePnpInterfaces fills in the pnpInterface fields in deviceNamesAndGUIDs with UNICODE file paths to the devices. The DS documentation mentions at least two techniques by which these Interface paths can be found using IKsPropertySet on the DirectSound class object. One is using the DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION property, and the other is using DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE. I tried both methods and only the second worked. I found two postings on the net from people who had the same problem with the first method, so I think the method used here is more common/likely to work. The probem is that IKsPropertySet_Get returns S_OK but the fields of the device description are not filled in. The mechanism we use works by registering an enumeration callback which is called for every DSound device. Our callback searches for a device in our deviceNamesAndGUIDs list with the matching GUID and copies the pointer to the Interface path. Note that we could have used this enumeration callback to perform the original device enumeration, however we choose not to so we can disable this step easily. Apparently the IKsPropertySet mechanism was added in DirectSound 9c 2004 http://www.tech-archive.net/Archive/Development/microsoft.public.win32.programmer.mmedia/2004-12/0099.html -- rossb */ static void FindDevicePnpInterfaces( DSDeviceNamesAndGUIDs *deviceNamesAndGUIDs ) { IClassFactory *pClassFactory; if( paWinDsDSoundEntryPoints.DllGetClassObject(&pawin_CLSID_DirectSoundPrivate, &IID_IClassFactory, (PVOID *) &pClassFactory) == S_OK ){ IKsPropertySet *pPropertySet; if( pClassFactory->lpVtbl->CreateInstance( pClassFactory, NULL, &pawin_IID_IKsPropertySet, (PVOID *) &pPropertySet) == S_OK ){ DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data; ULONG bytesReturned; data.Callback = KsPropertySetEnumerateCallback; data.Context = deviceNamesAndGUIDs; IKsPropertySet_Get( pPropertySet, &pawin_DSPROPSETID_DirectSoundDevice, DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W, NULL, 0, &data, sizeof(data), &bytesReturned ); IKsPropertySet_Release( pPropertySet ); } pClassFactory->lpVtbl->Release( pClassFactory ); } /* The following code fragment, which I chose not to use, queries for the device interface for a device with a specific GUID: ULONG BytesReturned; DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA Property; memset (&Property, 0, sizeof(Property)); Property.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER; Property.DeviceId = *lpGUID; hr = IKsPropertySet_Get( pPropertySet, &pawin_DSPROPSETID_DirectSoundDevice, DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W, NULL, 0, &Property, sizeof(Property), &BytesReturned ); if( hr == S_OK ) { //pnpInterface = Property.Interface; } */ } #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ /* GUIDs for emulated devices which we blacklist below. are there more than two of them?? */ GUID IID_IRolandVSCEmulated1 = {0xc2ad1800, 0xb243, 0x11ce, 0xa8, 0xa4, 0x00, 0xaa, 0x00, 0x6c, 0x45, 0x01}; GUID IID_IRolandVSCEmulated2 = {0xc2ad1800, 0xb243, 0x11ce, 0xa8, 0xa4, 0x00, 0xaa, 0x00, 0x6c, 0x45, 0x02}; #define PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_ (13) /* must match array length below */ static double defaultSampleRateSearchOrder_[] = { 44100.0, 48000.0, 32000.0, 24000.0, 22050.0, 88200.0, 96000.0, 192000.0, 16000.0, 12000.0, 11025.0, 9600.0, 8000.0 }; /************************************************************************************ ** Extract capabilities from an output device, and add it to the device info list ** if successful. This function assumes that there is enough room in the ** device info list to accomodate all entries. ** ** The device will not be added to the device list if any errors are encountered. */ static PaError AddOutputDeviceInfoFromDirectSound( PaWinDsHostApiRepresentation *winDsHostApi, char *name, LPGUID lpGUID, char *pnpInterface ) { PaUtilHostApiRepresentation *hostApi = &winDsHostApi->inheritedHostApiRep; PaWinDsDeviceInfo *winDsDeviceInfo = (PaWinDsDeviceInfo*) hostApi->deviceInfos[hostApi->info.deviceCount]; PaDeviceInfo *deviceInfo = &winDsDeviceInfo->inheritedDeviceInfo; HRESULT hr; LPDIRECTSOUND lpDirectSound; DSCAPS caps; int deviceOK = TRUE; PaError result = paNoError; int i; /* Copy GUID to the device info structure. Set pointer. */ if( lpGUID == NULL ) { winDsDeviceInfo->lpGUID = NULL; } else { memcpy( &winDsDeviceInfo->guid, lpGUID, sizeof(GUID) ); winDsDeviceInfo->lpGUID = &winDsDeviceInfo->guid; } if( lpGUID ) { if (IsEqualGUID (&IID_IRolandVSCEmulated1,lpGUID) || IsEqualGUID (&IID_IRolandVSCEmulated2,lpGUID) ) { PA_DEBUG(("BLACKLISTED: %s \n",name)); return paNoError; } } /* Create a DirectSound object for the specified GUID Note that using CoCreateInstance doesn't work on windows CE. */ hr = paWinDsDSoundEntryPoints.DirectSoundCreate( lpGUID, &lpDirectSound, NULL ); /** try using CoCreateInstance because DirectSoundCreate was hanging under some circumstances - note this was probably related to the #define BOOL short bug which has now been fixed @todo delete this comment and the following code once we've ensured there is no bug. */ /* hr = CoCreateInstance( &CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound, (void**)&lpDirectSound ); if( hr == S_OK ) { hr = IDirectSound_Initialize( lpDirectSound, lpGUID ); } */ if( hr != DS_OK ) { if (hr == DSERR_ALLOCATED) PA_DEBUG(("AddOutputDeviceInfoFromDirectSound %s DSERR_ALLOCATED\n",name)); DBUG(("Cannot create DirectSound for %s. Result = 0x%x\n", name, hr )); if (lpGUID) DBUG(("%s's GUID: {0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x, 0x%x} \n", name, lpGUID->Data1, lpGUID->Data2, lpGUID->Data3, lpGUID->Data4[0], lpGUID->Data4[1], lpGUID->Data4[2], lpGUID->Data4[3], lpGUID->Data4[4], lpGUID->Data4[5], lpGUID->Data4[6], lpGUID->Data4[7])); deviceOK = FALSE; } else { /* Query device characteristics. */ memset( &caps, 0, sizeof(caps) ); caps.dwSize = sizeof(caps); hr = IDirectSound_GetCaps( lpDirectSound, &caps ); if( hr != DS_OK ) { DBUG(("Cannot GetCaps() for DirectSound device %s. Result = 0x%x\n", name, hr )); deviceOK = FALSE; } else { #if PA_USE_WMME if( caps.dwFlags & DSCAPS_EMULDRIVER ) { /* If WMME supported, then reject Emulated drivers because they are lousy. */ deviceOK = FALSE; } #endif if( deviceOK ) { deviceInfo->maxInputChannels = 0; winDsDeviceInfo->deviceInputChannelCountIsKnown = 1; /* DS output capabilities only indicate supported number of channels using two flags which indicate mono and/or stereo. We assume that stereo devices may support more than 2 channels (as is the case with 5.1 devices for example) and so set deviceOutputChannelCountIsKnown to 0 (unknown). In this case OpenStream will try to open the device when the user requests more than 2 channels, rather than returning an error. */ if( caps.dwFlags & DSCAPS_PRIMARYSTEREO ) { deviceInfo->maxOutputChannels = 2; winDsDeviceInfo->deviceOutputChannelCountIsKnown = 0; } else { deviceInfo->maxOutputChannels = 1; winDsDeviceInfo->deviceOutputChannelCountIsKnown = 1; } /* Guess channels count from speaker configuration. We do it only when pnpInterface is NULL or when PAWIN_USE_WDMKS_DEVICE_INFO is undefined. */ #ifdef PAWIN_USE_WDMKS_DEVICE_INFO if( !pnpInterface ) #endif { DWORD spkrcfg; if( SUCCEEDED(IDirectSound_GetSpeakerConfig( lpDirectSound, &spkrcfg )) ) { int count = 0; switch (DSSPEAKER_CONFIG(spkrcfg)) { case DSSPEAKER_HEADPHONE: count = 2; break; case DSSPEAKER_MONO: count = 1; break; case DSSPEAKER_QUAD: count = 4; break; case DSSPEAKER_STEREO: count = 2; break; case DSSPEAKER_SURROUND: count = 4; break; case DSSPEAKER_5POINT1: count = 6; break; case DSSPEAKER_7POINT1: count = 8; break; #ifndef DSSPEAKER_7POINT1_SURROUND #define DSSPEAKER_7POINT1_SURROUND 0x00000008 #endif case DSSPEAKER_7POINT1_SURROUND: count = 8; break; #ifndef DSSPEAKER_5POINT1_SURROUND #define DSSPEAKER_5POINT1_SURROUND 0x00000009 #endif case DSSPEAKER_5POINT1_SURROUND: count = 6; break; } if( count ) { deviceInfo->maxOutputChannels = count; winDsDeviceInfo->deviceOutputChannelCountIsKnown = 1; } } } #ifdef PAWIN_USE_WDMKS_DEVICE_INFO if( pnpInterface ) { int count = PaWin_WDMKS_QueryFilterMaximumChannelCount( pnpInterface, /* isInput= */ 0 ); if( count > 0 ) { deviceInfo->maxOutputChannels = count; winDsDeviceInfo->deviceOutputChannelCountIsKnown = 1; } } #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ /* initialize defaultSampleRate */ if( caps.dwFlags & DSCAPS_CONTINUOUSRATE ) { /* initialize to caps.dwMaxSecondarySampleRate incase none of the standard rates match */ deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate; for( i = 0; i < PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_; ++i ) { if( defaultSampleRateSearchOrder_[i] >= caps.dwMinSecondarySampleRate && defaultSampleRateSearchOrder_[i] <= caps.dwMaxSecondarySampleRate ) { deviceInfo->defaultSampleRate = defaultSampleRateSearchOrder_[i]; break; } } } else if( caps.dwMinSecondarySampleRate == caps.dwMaxSecondarySampleRate ) { if( caps.dwMinSecondarySampleRate == 0 ) { /* ** On my Thinkpad 380Z, DirectSoundV6 returns min-max=0 !! ** But it supports continuous sampling. ** So fake range of rates, and hope it really supports it. */ deviceInfo->defaultSampleRate = 48000.0f; /* assume 48000 as the default */ DBUG(("PA - Reported rates both zero. Setting to fake values for device #%s\n", name )); } else { deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate; } } else if( (caps.dwMinSecondarySampleRate < 1000.0) && (caps.dwMaxSecondarySampleRate > 50000.0) ) { /* The EWS88MT drivers lie, lie, lie. The say they only support two rates, 100 & 100000. ** But we know that they really support a range of rates! ** So when we see a ridiculous set of rates, assume it is a range. */ deviceInfo->defaultSampleRate = 48000.0f; /* assume 48000 as the default */ DBUG(("PA - Sample rate range used instead of two odd values for device #%s\n", name )); } else deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate; //printf( "min %d max %d\n", caps.dwMinSecondarySampleRate, caps.dwMaxSecondarySampleRate ); // dwFlags | DSCAPS_CONTINUOUSRATE deviceInfo->defaultLowInputLatency = 0.; deviceInfo->defaultHighInputLatency = 0.; deviceInfo->defaultLowOutputLatency = PaWinDs_GetMinLatencySeconds( deviceInfo->defaultSampleRate ); deviceInfo->defaultHighOutputLatency = deviceInfo->defaultLowOutputLatency * 2; } } IDirectSound_Release( lpDirectSound ); } if( deviceOK ) { deviceInfo->name = name; if( lpGUID == NULL ) hostApi->info.defaultOutputDevice = hostApi->info.deviceCount; hostApi->info.deviceCount++; } return result; } /************************************************************************************ ** Extract capabilities from an input device, and add it to the device info list ** if successful. This function assumes that there is enough room in the ** device info list to accomodate all entries. ** ** The device will not be added to the device list if any errors are encountered. */ static PaError AddInputDeviceInfoFromDirectSoundCapture( PaWinDsHostApiRepresentation *winDsHostApi, char *name, LPGUID lpGUID, char *pnpInterface ) { PaUtilHostApiRepresentation *hostApi = &winDsHostApi->inheritedHostApiRep; PaWinDsDeviceInfo *winDsDeviceInfo = (PaWinDsDeviceInfo*) hostApi->deviceInfos[hostApi->info.deviceCount]; PaDeviceInfo *deviceInfo = &winDsDeviceInfo->inheritedDeviceInfo; HRESULT hr; LPDIRECTSOUNDCAPTURE lpDirectSoundCapture; DSCCAPS caps; int deviceOK = TRUE; PaError result = paNoError; /* Copy GUID to the device info structure. Set pointer. */ if( lpGUID == NULL ) { winDsDeviceInfo->lpGUID = NULL; } else { winDsDeviceInfo->lpGUID = &winDsDeviceInfo->guid; memcpy( &winDsDeviceInfo->guid, lpGUID, sizeof(GUID) ); } hr = paWinDsDSoundEntryPoints.DirectSoundCaptureCreate( lpGUID, &lpDirectSoundCapture, NULL ); /** try using CoCreateInstance because DirectSoundCreate was hanging under some circumstances - note this was probably related to the #define BOOL short bug which has now been fixed @todo delete this comment and the following code once we've ensured there is no bug. */ /* hr = CoCreateInstance( &CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSoundCapture, (void**)&lpDirectSoundCapture ); */ if( hr != DS_OK ) { DBUG(("Cannot create Capture for %s. Result = 0x%x\n", name, hr )); deviceOK = FALSE; } else { /* Query device characteristics. */ memset( &caps, 0, sizeof(caps) ); caps.dwSize = sizeof(caps); hr = IDirectSoundCapture_GetCaps( lpDirectSoundCapture, &caps ); if( hr != DS_OK ) { DBUG(("Cannot GetCaps() for Capture device %s. Result = 0x%x\n", name, hr )); deviceOK = FALSE; } else { #if PA_USE_WMME if( caps.dwFlags & DSCAPS_EMULDRIVER ) { /* If WMME supported, then reject Emulated drivers because they are lousy. */ deviceOK = FALSE; } #endif if( deviceOK ) { deviceInfo->maxInputChannels = caps.dwChannels; winDsDeviceInfo->deviceInputChannelCountIsKnown = 1; deviceInfo->maxOutputChannels = 0; winDsDeviceInfo->deviceOutputChannelCountIsKnown = 1; #ifdef PAWIN_USE_WDMKS_DEVICE_INFO if( pnpInterface ) { int count = PaWin_WDMKS_QueryFilterMaximumChannelCount( pnpInterface, /* isInput= */ 1 ); if( count > 0 ) { deviceInfo->maxInputChannels = count; winDsDeviceInfo->deviceInputChannelCountIsKnown = 1; } } #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ /* constants from a WINE patch by Francois Gouget, see: http://www.winehq.com/hypermail/wine-patches/2003/01/0290.html --- Date: Fri, 14 May 2004 10:38:12 +0200 (CEST) From: Francois Gouget To: Ross Bencina Subject: Re: Permission to use wine 48/96 wave patch in BSD licensed library [snip] I give you permission to use the patch below under the BSD license. http://www.winehq.com/hypermail/wine-patches/2003/01/0290.html [snip] */ #ifndef WAVE_FORMAT_48M08 #define WAVE_FORMAT_48M08 0x00001000 /* 48 kHz, Mono, 8-bit */ #define WAVE_FORMAT_48S08 0x00002000 /* 48 kHz, Stereo, 8-bit */ #define WAVE_FORMAT_48M16 0x00004000 /* 48 kHz, Mono, 16-bit */ #define WAVE_FORMAT_48S16 0x00008000 /* 48 kHz, Stereo, 16-bit */ #define WAVE_FORMAT_96M08 0x00010000 /* 96 kHz, Mono, 8-bit */ #define WAVE_FORMAT_96S08 0x00020000 /* 96 kHz, Stereo, 8-bit */ #define WAVE_FORMAT_96M16 0x00040000 /* 96 kHz, Mono, 16-bit */ #define WAVE_FORMAT_96S16 0x00080000 /* 96 kHz, Stereo, 16-bit */ #endif /* defaultSampleRate */ if( caps.dwChannels == 2 ) { if( caps.dwFormats & WAVE_FORMAT_4S16 ) deviceInfo->defaultSampleRate = 44100.0; else if( caps.dwFormats & WAVE_FORMAT_48S16 ) deviceInfo->defaultSampleRate = 48000.0; else if( caps.dwFormats & WAVE_FORMAT_2S16 ) deviceInfo->defaultSampleRate = 22050.0; else if( caps.dwFormats & WAVE_FORMAT_1S16 ) deviceInfo->defaultSampleRate = 11025.0; else if( caps.dwFormats & WAVE_FORMAT_96S16 ) deviceInfo->defaultSampleRate = 96000.0; else deviceInfo->defaultSampleRate = 48000.0; /* assume 48000 as the default */ } else if( caps.dwChannels == 1 ) { if( caps.dwFormats & WAVE_FORMAT_4M16 ) deviceInfo->defaultSampleRate = 44100.0; else if( caps.dwFormats & WAVE_FORMAT_48M16 ) deviceInfo->defaultSampleRate = 48000.0; else if( caps.dwFormats & WAVE_FORMAT_2M16 ) deviceInfo->defaultSampleRate = 22050.0; else if( caps.dwFormats & WAVE_FORMAT_1M16 ) deviceInfo->defaultSampleRate = 11025.0; else if( caps.dwFormats & WAVE_FORMAT_96M16 ) deviceInfo->defaultSampleRate = 96000.0; else deviceInfo->defaultSampleRate = 48000.0; /* assume 48000 as the default */ } else deviceInfo->defaultSampleRate = 48000.0; /* assume 48000 as the default */ deviceInfo->defaultLowInputLatency = PaWinDs_GetMinLatencySeconds( deviceInfo->defaultSampleRate ); deviceInfo->defaultHighInputLatency = deviceInfo->defaultLowInputLatency * 2; deviceInfo->defaultLowOutputLatency = 0.; deviceInfo->defaultHighOutputLatency = 0.; } } IDirectSoundCapture_Release( lpDirectSoundCapture ); } if( deviceOK ) { deviceInfo->name = name; if( lpGUID == NULL ) hostApi->info.defaultInputDevice = hostApi->info.deviceCount; hostApi->info.deviceCount++; } return result; } /***********************************************************************************/ PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) { PaError result = paNoError; int i, deviceCount; PaWinDsHostApiRepresentation *winDsHostApi; DSDeviceNamesAndGUIDs deviceNamesAndGUIDs; PaWinDsDeviceInfo *deviceInfoArray; PaWinDs_InitializeDSoundEntryPoints(); /* initialise guid vectors so they can be safely deleted on error */ deviceNamesAndGUIDs.winDsHostApi = NULL; deviceNamesAndGUIDs.inputNamesAndGUIDs.items = NULL; deviceNamesAndGUIDs.outputNamesAndGUIDs.items = NULL; winDsHostApi = (PaWinDsHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaWinDsHostApiRepresentation) ); if( !winDsHostApi ) { result = paInsufficientMemory; goto error; } memset( winDsHostApi, 0, sizeof(PaWinDsHostApiRepresentation) ); /* ensure all fields are zeroed. especially winDsHostApi->allocations */ result = PaWinUtil_CoInitialize( paDirectSound, &winDsHostApi->comInitializationResult ); if( result != paNoError ) { goto error; } winDsHostApi->allocations = PaUtil_CreateAllocationGroup(); if( !winDsHostApi->allocations ) { result = paInsufficientMemory; goto error; } *hostApi = &winDsHostApi->inheritedHostApiRep; (*hostApi)->info.structVersion = 1; (*hostApi)->info.type = paDirectSound; (*hostApi)->info.name = "Windows DirectSound"; (*hostApi)->info.deviceCount = 0; (*hostApi)->info.defaultInputDevice = paNoDevice; (*hostApi)->info.defaultOutputDevice = paNoDevice; /* DSound - enumerate devices to count them and to gather their GUIDs */ result = InitializeDSDeviceNameAndGUIDVector( &deviceNamesAndGUIDs.inputNamesAndGUIDs, winDsHostApi->allocations ); if( result != paNoError ) goto error; result = InitializeDSDeviceNameAndGUIDVector( &deviceNamesAndGUIDs.outputNamesAndGUIDs, winDsHostApi->allocations ); if( result != paNoError ) goto error; paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA( (LPDSENUMCALLBACKA)CollectGUIDsProcA, (void *)&deviceNamesAndGUIDs.inputNamesAndGUIDs ); paWinDsDSoundEntryPoints.DirectSoundEnumerateA( (LPDSENUMCALLBACKA)CollectGUIDsProcA, (void *)&deviceNamesAndGUIDs.outputNamesAndGUIDs ); if( deviceNamesAndGUIDs.inputNamesAndGUIDs.enumerationError != paNoError ) { result = deviceNamesAndGUIDs.inputNamesAndGUIDs.enumerationError; goto error; } if( deviceNamesAndGUIDs.outputNamesAndGUIDs.enumerationError != paNoError ) { result = deviceNamesAndGUIDs.outputNamesAndGUIDs.enumerationError; goto error; } deviceCount = deviceNamesAndGUIDs.inputNamesAndGUIDs.count + deviceNamesAndGUIDs.outputNamesAndGUIDs.count; #ifdef PAWIN_USE_WDMKS_DEVICE_INFO if( deviceCount > 0 ) { deviceNamesAndGUIDs.winDsHostApi = winDsHostApi; FindDevicePnpInterfaces( &deviceNamesAndGUIDs ); } #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ if( deviceCount > 0 ) { /* allocate array for pointers to PaDeviceInfo structs */ (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( winDsHostApi->allocations, sizeof(PaDeviceInfo*) * deviceCount ); if( !(*hostApi)->deviceInfos ) { result = paInsufficientMemory; goto error; } /* allocate all PaDeviceInfo structs in a contiguous block */ deviceInfoArray = (PaWinDsDeviceInfo*)PaUtil_GroupAllocateMemory( winDsHostApi->allocations, sizeof(PaWinDsDeviceInfo) * deviceCount ); if( !deviceInfoArray ) { result = paInsufficientMemory; goto error; } for( i=0; i < deviceCount; ++i ) { PaDeviceInfo *deviceInfo = &deviceInfoArray[i].inheritedDeviceInfo; deviceInfo->structVersion = 2; deviceInfo->hostApi = hostApiIndex; deviceInfo->name = 0; (*hostApi)->deviceInfos[i] = deviceInfo; } for( i=0; i < deviceNamesAndGUIDs.inputNamesAndGUIDs.count; ++i ) { result = AddInputDeviceInfoFromDirectSoundCapture( winDsHostApi, deviceNamesAndGUIDs.inputNamesAndGUIDs.items[i].name, deviceNamesAndGUIDs.inputNamesAndGUIDs.items[i].lpGUID, deviceNamesAndGUIDs.inputNamesAndGUIDs.items[i].pnpInterface ); if( result != paNoError ) goto error; } for( i=0; i < deviceNamesAndGUIDs.outputNamesAndGUIDs.count; ++i ) { result = AddOutputDeviceInfoFromDirectSound( winDsHostApi, deviceNamesAndGUIDs.outputNamesAndGUIDs.items[i].name, deviceNamesAndGUIDs.outputNamesAndGUIDs.items[i].lpGUID, deviceNamesAndGUIDs.outputNamesAndGUIDs.items[i].pnpInterface ); if( result != paNoError ) goto error; } } result = TerminateDSDeviceNameAndGUIDVector( &deviceNamesAndGUIDs.inputNamesAndGUIDs ); if( result != paNoError ) goto error; result = TerminateDSDeviceNameAndGUIDVector( &deviceNamesAndGUIDs.outputNamesAndGUIDs ); if( result != paNoError ) goto error; (*hostApi)->Terminate = Terminate; (*hostApi)->OpenStream = OpenStream; (*hostApi)->IsFormatSupported = IsFormatSupported; PaUtil_InitializeStreamInterface( &winDsHostApi->callbackStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, GetStreamCpuLoad, PaUtil_DummyRead, PaUtil_DummyWrite, PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); PaUtil_InitializeStreamInterface( &winDsHostApi->blockingStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, PaUtil_DummyGetCpuLoad, ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable ); return result; error: TerminateDSDeviceNameAndGUIDVector( &deviceNamesAndGUIDs.inputNamesAndGUIDs ); TerminateDSDeviceNameAndGUIDVector( &deviceNamesAndGUIDs.outputNamesAndGUIDs ); Terminate( (struct PaUtilHostApiRepresentation *)winDsHostApi ); return result; } /***********************************************************************************/ static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) { PaWinDsHostApiRepresentation *winDsHostApi = (PaWinDsHostApiRepresentation*)hostApi; if( winDsHostApi ){ if( winDsHostApi->allocations ) { PaUtil_FreeAllAllocations( winDsHostApi->allocations ); PaUtil_DestroyAllocationGroup( winDsHostApi->allocations ); } PaWinUtil_CoUninitialize( paDirectSound, &winDsHostApi->comInitializationResult ); PaUtil_FreeMemory( winDsHostApi ); } PaWinDs_TerminateDSoundEntryPoints(); } static PaError ValidateWinDirectSoundSpecificStreamInfo( const PaStreamParameters *streamParameters, const PaWinDirectSoundStreamInfo *streamInfo ) { if( streamInfo ) { if( streamInfo->size != sizeof( PaWinDirectSoundStreamInfo ) || streamInfo->version != 2 ) { return paIncompatibleHostApiSpecificStreamInfo; } if( streamInfo->flags & paWinDirectSoundUseLowLevelLatencyParameters ) { if( streamInfo->framesPerBuffer <= 0 ) return paIncompatibleHostApiSpecificStreamInfo; } } return paNoError; } /***********************************************************************************/ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { PaError result; PaWinDsDeviceInfo *inputWinDsDeviceInfo, *outputWinDsDeviceInfo; PaDeviceInfo *inputDeviceInfo, *outputDeviceInfo; int inputChannelCount, outputChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; PaWinDirectSoundStreamInfo *inputStreamInfo, *outputStreamInfo; if( inputParameters ) { inputWinDsDeviceInfo = (PaWinDsDeviceInfo*) hostApi->deviceInfos[ inputParameters->device ]; inputDeviceInfo = &inputWinDsDeviceInfo->inheritedDeviceInfo; inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that input device can support inputChannelCount */ if( inputWinDsDeviceInfo->deviceInputChannelCountIsKnown && inputChannelCount > inputDeviceInfo->maxInputChannels ) return paInvalidChannelCount; /* validate inputStreamInfo */ inputStreamInfo = (PaWinDirectSoundStreamInfo*)inputParameters->hostApiSpecificStreamInfo; result = ValidateWinDirectSoundSpecificStreamInfo( inputParameters, inputStreamInfo ); if( result != paNoError ) return result; } else { inputChannelCount = 0; } if( outputParameters ) { outputWinDsDeviceInfo = (PaWinDsDeviceInfo*) hostApi->deviceInfos[ outputParameters->device ]; outputDeviceInfo = &outputWinDsDeviceInfo->inheritedDeviceInfo; outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that output device can support inputChannelCount */ if( outputWinDsDeviceInfo->deviceOutputChannelCountIsKnown && outputChannelCount > outputDeviceInfo->maxOutputChannels ) return paInvalidChannelCount; /* validate outputStreamInfo */ outputStreamInfo = (PaWinDirectSoundStreamInfo*)outputParameters->hostApiSpecificStreamInfo; result = ValidateWinDirectSoundSpecificStreamInfo( outputParameters, outputStreamInfo ); if( result != paNoError ) return result; } else { outputChannelCount = 0; } /* IMPLEMENT ME: - if a full duplex stream is requested, check that the combination of input and output parameters is supported if necessary - check that the device supports sampleRate Because the buffer adapter handles conversion between all standard sample formats, the following checks are only required if paCustomFormat is implemented, or under some other unusual conditions. - check that input device can support inputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format - check that output device can support outputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format */ return paFormatIsSupported; } #ifdef PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE static HRESULT InitFullDuplexInputOutputBuffers( PaWinDsStream *stream, PaWinDsDeviceInfo *inputDevice, PaSampleFormat hostInputSampleFormat, WORD inputChannelCount, int bytesPerInputBuffer, PaWinWaveFormatChannelMask inputChannelMask, PaWinDsDeviceInfo *outputDevice, PaSampleFormat hostOutputSampleFormat, WORD outputChannelCount, int bytesPerOutputBuffer, PaWinWaveFormatChannelMask outputChannelMask, unsigned long nFrameRate ) { HRESULT hr; DSCBUFFERDESC captureDesc; PaWinWaveFormat captureWaveFormat; DSBUFFERDESC secondaryRenderDesc; PaWinWaveFormat renderWaveFormat; LPDIRECTSOUNDBUFFER8 pRenderBuffer8; LPDIRECTSOUNDCAPTUREBUFFER8 pCaptureBuffer8; // capture buffer description // only try wave format extensible. assume it's available on all ds 8 systems PaWin_InitializeWaveFormatExtensible( &captureWaveFormat, inputChannelCount, hostInputSampleFormat, PaWin_SampleFormatToLinearWaveFormatTag( hostInputSampleFormat ), nFrameRate, inputChannelMask ); ZeroMemory(&captureDesc, sizeof(DSCBUFFERDESC)); captureDesc.dwSize = sizeof(DSCBUFFERDESC); captureDesc.dwFlags = 0; captureDesc.dwBufferBytes = bytesPerInputBuffer; captureDesc.lpwfxFormat = (WAVEFORMATEX*)&captureWaveFormat; // render buffer description PaWin_InitializeWaveFormatExtensible( &renderWaveFormat, outputChannelCount, hostOutputSampleFormat, PaWin_SampleFormatToLinearWaveFormatTag( hostOutputSampleFormat ), nFrameRate, outputChannelMask ); ZeroMemory(&secondaryRenderDesc, sizeof(DSBUFFERDESC)); secondaryRenderDesc.dwSize = sizeof(DSBUFFERDESC); secondaryRenderDesc.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2; secondaryRenderDesc.dwBufferBytes = bytesPerOutputBuffer; secondaryRenderDesc.lpwfxFormat = (WAVEFORMATEX*)&renderWaveFormat; /* note that we don't create a primary buffer here at all */ hr = paWinDsDSoundEntryPoints.DirectSoundFullDuplexCreate8( inputDevice->lpGUID, outputDevice->lpGUID, &captureDesc, &secondaryRenderDesc, GetDesktopWindow(), /* see InitOutputBuffer() for a discussion of whether this is a good idea */ DSSCL_EXCLUSIVE, &stream->pDirectSoundFullDuplex8, &pCaptureBuffer8, &pRenderBuffer8, NULL /* pUnkOuter must be NULL */ ); if( hr == DS_OK ) { PA_DEBUG(("DirectSoundFullDuplexCreate succeeded!\n")); /* retrieve the pre ds 8 buffer interfaces which are used by the rest of the code */ hr = IUnknown_QueryInterface( pCaptureBuffer8, &IID_IDirectSoundCaptureBuffer, (LPVOID *)&stream->pDirectSoundInputBuffer ); if( hr == DS_OK ) hr = IUnknown_QueryInterface( pRenderBuffer8, &IID_IDirectSoundBuffer, (LPVOID *)&stream->pDirectSoundOutputBuffer ); /* release the ds 8 interfaces, we don't need them */ IUnknown_Release( pCaptureBuffer8 ); IUnknown_Release( pRenderBuffer8 ); if( !stream->pDirectSoundInputBuffer || !stream->pDirectSoundOutputBuffer ){ /* couldn't get pre ds 8 interfaces for some reason. clean up. */ if( stream->pDirectSoundInputBuffer ) { IUnknown_Release( stream->pDirectSoundInputBuffer ); stream->pDirectSoundInputBuffer = NULL; } if( stream->pDirectSoundOutputBuffer ) { IUnknown_Release( stream->pDirectSoundOutputBuffer ); stream->pDirectSoundOutputBuffer = NULL; } IUnknown_Release( stream->pDirectSoundFullDuplex8 ); stream->pDirectSoundFullDuplex8 = NULL; } } else { PA_DEBUG(("DirectSoundFullDuplexCreate failed. hr=%d\n", hr)); } return hr; } #endif /* PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE */ static HRESULT InitInputBuffer( PaWinDsStream *stream, PaWinDsDeviceInfo *device, PaSampleFormat sampleFormat, unsigned long nFrameRate, WORD nChannels, int bytesPerBuffer, PaWinWaveFormatChannelMask channelMask ) { DSCBUFFERDESC captureDesc; PaWinWaveFormat waveFormat; HRESULT result; if( (result = paWinDsDSoundEntryPoints.DirectSoundCaptureCreate( device->lpGUID, &stream->pDirectSoundCapture, NULL) ) != DS_OK ){ ERR_RPT(("PortAudio: DirectSoundCaptureCreate() failed!\n")); return result; } // Setup the secondary buffer description ZeroMemory(&captureDesc, sizeof(DSCBUFFERDESC)); captureDesc.dwSize = sizeof(DSCBUFFERDESC); captureDesc.dwFlags = 0; captureDesc.dwBufferBytes = bytesPerBuffer; captureDesc.lpwfxFormat = (WAVEFORMATEX*)&waveFormat; // Create the capture buffer // first try WAVEFORMATEXTENSIBLE. if this fails, fall back to WAVEFORMATEX PaWin_InitializeWaveFormatExtensible( &waveFormat, nChannels, sampleFormat, PaWin_SampleFormatToLinearWaveFormatTag( sampleFormat ), nFrameRate, channelMask ); if( IDirectSoundCapture_CreateCaptureBuffer( stream->pDirectSoundCapture, &captureDesc, &stream->pDirectSoundInputBuffer, NULL) != DS_OK ) { PaWin_InitializeWaveFormatEx( &waveFormat, nChannels, sampleFormat, PaWin_SampleFormatToLinearWaveFormatTag( sampleFormat ), nFrameRate ); if ((result = IDirectSoundCapture_CreateCaptureBuffer( stream->pDirectSoundCapture, &captureDesc, &stream->pDirectSoundInputBuffer, NULL)) != DS_OK) return result; } stream->readOffset = 0; // reset last read position to start of buffer return DS_OK; } static HRESULT InitOutputBuffer( PaWinDsStream *stream, PaWinDsDeviceInfo *device, PaSampleFormat sampleFormat, unsigned long nFrameRate, WORD nChannels, int bytesPerBuffer, PaWinWaveFormatChannelMask channelMask ) { HRESULT result; HWND hWnd; HRESULT hr; PaWinWaveFormat waveFormat; DSBUFFERDESC primaryDesc; DSBUFFERDESC secondaryDesc; if( (hr = paWinDsDSoundEntryPoints.DirectSoundCreate( device->lpGUID, &stream->pDirectSound, NULL )) != DS_OK ){ ERR_RPT(("PortAudio: DirectSoundCreate() failed!\n")); return hr; } // We were using getForegroundWindow() but sometimes the ForegroundWindow may not be the // applications's window. Also if that window is closed before the Buffer is closed // then DirectSound can crash. (Thanks for Scott Patterson for reporting this.) // So we will use GetDesktopWindow() which was suggested by Miller Puckette. // hWnd = GetForegroundWindow(); // // FIXME: The example code I have on the net creates a hidden window that // is managed by our code - I think we should do that - one hidden // window for the whole of Pa_DS // hWnd = GetDesktopWindow(); // Set cooperative level to DSSCL_EXCLUSIVE so that we can get 16 bit output, 44.1 KHz. // exclusive also prevents unexpected sounds from other apps during a performance. if ((hr = IDirectSound_SetCooperativeLevel( stream->pDirectSound, hWnd, DSSCL_EXCLUSIVE)) != DS_OK) { return hr; } // ----------------------------------------------------------------------- // Create primary buffer and set format just so we can specify our custom format. // Otherwise we would be stuck with the default which might be 8 bit or 22050 Hz. // Setup the primary buffer description ZeroMemory(&primaryDesc, sizeof(DSBUFFERDESC)); primaryDesc.dwSize = sizeof(DSBUFFERDESC); primaryDesc.dwFlags = DSBCAPS_PRIMARYBUFFER; // all panning, mixing, etc done by synth primaryDesc.dwBufferBytes = 0; primaryDesc.lpwfxFormat = NULL; // Create the buffer if ((result = IDirectSound_CreateSoundBuffer( stream->pDirectSound, &primaryDesc, &stream->pDirectSoundPrimaryBuffer, NULL)) != DS_OK) goto error; // Set the primary buffer's format // first try WAVEFORMATEXTENSIBLE. if this fails, fall back to WAVEFORMATEX PaWin_InitializeWaveFormatExtensible( &waveFormat, nChannels, sampleFormat, PaWin_SampleFormatToLinearWaveFormatTag( sampleFormat ), nFrameRate, channelMask ); if( IDirectSoundBuffer_SetFormat( stream->pDirectSoundPrimaryBuffer, (WAVEFORMATEX*)&waveFormat) != DS_OK ) { PaWin_InitializeWaveFormatEx( &waveFormat, nChannels, sampleFormat, PaWin_SampleFormatToLinearWaveFormatTag( sampleFormat ), nFrameRate ); if((result = IDirectSoundBuffer_SetFormat( stream->pDirectSoundPrimaryBuffer, (WAVEFORMATEX*)&waveFormat)) != DS_OK) goto error; } // ---------------------------------------------------------------------- // Setup the secondary buffer description ZeroMemory(&secondaryDesc, sizeof(DSBUFFERDESC)); secondaryDesc.dwSize = sizeof(DSBUFFERDESC); secondaryDesc.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2; secondaryDesc.dwBufferBytes = bytesPerBuffer; secondaryDesc.lpwfxFormat = (WAVEFORMATEX*)&waveFormat; /* waveFormat contains whatever format was negotiated for the primary buffer above */ // Create the secondary buffer if ((result = IDirectSound_CreateSoundBuffer( stream->pDirectSound, &secondaryDesc, &stream->pDirectSoundOutputBuffer, NULL)) != DS_OK) goto error; return DS_OK; error: if( stream->pDirectSoundPrimaryBuffer ) { IDirectSoundBuffer_Release( stream->pDirectSoundPrimaryBuffer ); stream->pDirectSoundPrimaryBuffer = NULL; } return result; } static void CalculateBufferSettings( unsigned long *hostBufferSizeFrames, unsigned long *pollingPeriodFrames, int isFullDuplex, unsigned long suggestedInputLatencyFrames, unsigned long suggestedOutputLatencyFrames, double sampleRate, unsigned long userFramesPerBuffer ) { unsigned long minimumPollingPeriodFrames = (unsigned long)(sampleRate * PA_DS_MINIMUM_POLLING_PERIOD_SECONDS); unsigned long maximumPollingPeriodFrames = (unsigned long)(sampleRate * PA_DS_MAXIMUM_POLLING_PERIOD_SECONDS); unsigned long pollingJitterFrames = (unsigned long)(sampleRate * PA_DS_POLLING_JITTER_SECONDS); if( userFramesPerBuffer == paFramesPerBufferUnspecified ) { unsigned long targetBufferingLatencyFrames = max( suggestedInputLatencyFrames, suggestedOutputLatencyFrames ); *pollingPeriodFrames = targetBufferingLatencyFrames / 4; if( *pollingPeriodFrames < minimumPollingPeriodFrames ) { *pollingPeriodFrames = minimumPollingPeriodFrames; } else if( *pollingPeriodFrames > maximumPollingPeriodFrames ) { *pollingPeriodFrames = maximumPollingPeriodFrames; } *hostBufferSizeFrames = *pollingPeriodFrames + max( *pollingPeriodFrames + pollingJitterFrames, targetBufferingLatencyFrames); } else { unsigned long targetBufferingLatencyFrames = suggestedInputLatencyFrames; if( isFullDuplex ) { /* In full duplex streams we know that the buffer adapter adds userFramesPerBuffer extra fixed latency. so we subtract it here as a fixed latency before computing the buffer size. being careful not to produce an unrepresentable negative result. Note: this only works as expected if output latency is greater than input latency. Otherwise we use input latency anyway since we do max(in,out). */ if( userFramesPerBuffer < suggestedOutputLatencyFrames ) { unsigned long adjustedSuggestedOutputLatencyFrames = suggestedOutputLatencyFrames - userFramesPerBuffer; /* maximum of input and adjusted output suggested latency */ if( adjustedSuggestedOutputLatencyFrames > targetBufferingLatencyFrames ) targetBufferingLatencyFrames = adjustedSuggestedOutputLatencyFrames; } } else { /* maximum of input and output suggested latency */ if( suggestedOutputLatencyFrames > suggestedInputLatencyFrames ) targetBufferingLatencyFrames = suggestedOutputLatencyFrames; } *hostBufferSizeFrames = userFramesPerBuffer + max( userFramesPerBuffer + pollingJitterFrames, targetBufferingLatencyFrames); *pollingPeriodFrames = max( max(1, userFramesPerBuffer / 4), targetBufferingLatencyFrames / 16 ); if( *pollingPeriodFrames > maximumPollingPeriodFrames ) { *pollingPeriodFrames = maximumPollingPeriodFrames; } } } static void CalculatePollingPeriodFrames( unsigned long hostBufferSizeFrames, unsigned long *pollingPeriodFrames, double sampleRate, unsigned long userFramesPerBuffer ) { unsigned long minimumPollingPeriodFrames = (unsigned long)(sampleRate * PA_DS_MINIMUM_POLLING_PERIOD_SECONDS); unsigned long maximumPollingPeriodFrames = (unsigned long)(sampleRate * PA_DS_MAXIMUM_POLLING_PERIOD_SECONDS); unsigned long pollingJitterFrames = (unsigned long)(sampleRate * PA_DS_POLLING_JITTER_SECONDS); *pollingPeriodFrames = max( max(1, userFramesPerBuffer / 4), hostBufferSizeFrames / 16 ); if( *pollingPeriodFrames > maximumPollingPeriodFrames ) { *pollingPeriodFrames = maximumPollingPeriodFrames; } } static void SetStreamInfoLatencies( PaWinDsStream *stream, unsigned long userFramesPerBuffer, unsigned long pollingPeriodFrames, double sampleRate ) { /* compute the stream info actual latencies based on framesPerBuffer, polling period, hostBufferSizeFrames, and the configuration of the buffer processor */ unsigned long effectiveFramesPerBuffer = (userFramesPerBuffer == paFramesPerBufferUnspecified) ? pollingPeriodFrames : userFramesPerBuffer; if( stream->bufferProcessor.inputChannelCount > 0 ) { /* stream info input latency is the minimum buffering latency (unlike suggested and default which are *maximums*) */ stream->streamRepresentation.streamInfo.inputLatency = (double)(PaUtil_GetBufferProcessorInputLatencyFrames(&stream->bufferProcessor) + effectiveFramesPerBuffer) / sampleRate; } else { stream->streamRepresentation.streamInfo.inputLatency = 0; } if( stream->bufferProcessor.outputChannelCount > 0 ) { stream->streamRepresentation.streamInfo.outputLatency = (double)(PaUtil_GetBufferProcessorOutputLatencyFrames(&stream->bufferProcessor) + (stream->hostBufferSizeFrames - effectiveFramesPerBuffer)) / sampleRate; } else { stream->streamRepresentation.streamInfo.outputLatency = 0; } } /***********************************************************************************/ /* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ) { PaError result = paNoError; PaWinDsHostApiRepresentation *winDsHostApi = (PaWinDsHostApiRepresentation*)hostApi; PaWinDsStream *stream = 0; int bufferProcessorIsInitialized = 0; int streamRepresentationIsInitialized = 0; PaWinDsDeviceInfo *inputWinDsDeviceInfo, *outputWinDsDeviceInfo; PaDeviceInfo *inputDeviceInfo, *outputDeviceInfo; int inputChannelCount, outputChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat; int userRequestedHostInputBufferSizeFrames = 0; int userRequestedHostOutputBufferSizeFrames = 0; unsigned long suggestedInputLatencyFrames, suggestedOutputLatencyFrames; PaWinDirectSoundStreamInfo *inputStreamInfo, *outputStreamInfo; PaWinWaveFormatChannelMask inputChannelMask, outputChannelMask; unsigned long pollingPeriodFrames = 0; if( inputParameters ) { inputWinDsDeviceInfo = (PaWinDsDeviceInfo*) hostApi->deviceInfos[ inputParameters->device ]; inputDeviceInfo = &inputWinDsDeviceInfo->inheritedDeviceInfo; inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; suggestedInputLatencyFrames = (unsigned long)(inputParameters->suggestedLatency * sampleRate); /* IDEA: the following 3 checks could be performed by default by pa_front unless some flag indicated otherwise */ /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that input device can support inputChannelCount */ if( inputWinDsDeviceInfo->deviceInputChannelCountIsKnown && inputChannelCount > inputDeviceInfo->maxInputChannels ) return paInvalidChannelCount; /* validate hostApiSpecificStreamInfo */ inputStreamInfo = (PaWinDirectSoundStreamInfo*)inputParameters->hostApiSpecificStreamInfo; result = ValidateWinDirectSoundSpecificStreamInfo( inputParameters, inputStreamInfo ); if( result != paNoError ) return result; if( inputStreamInfo && inputStreamInfo->flags & paWinDirectSoundUseLowLevelLatencyParameters ) userRequestedHostInputBufferSizeFrames = inputStreamInfo->framesPerBuffer; if( inputStreamInfo && inputStreamInfo->flags & paWinDirectSoundUseChannelMask ) inputChannelMask = inputStreamInfo->channelMask; else inputChannelMask = PaWin_DefaultChannelMask( inputChannelCount ); } else { inputChannelCount = 0; inputSampleFormat = 0; suggestedInputLatencyFrames = 0; } if( outputParameters ) { outputWinDsDeviceInfo = (PaWinDsDeviceInfo*) hostApi->deviceInfos[ outputParameters->device ]; outputDeviceInfo = &outputWinDsDeviceInfo->inheritedDeviceInfo; outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; suggestedOutputLatencyFrames = (unsigned long)(outputParameters->suggestedLatency * sampleRate); /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that output device can support outputChannelCount */ if( outputWinDsDeviceInfo->deviceOutputChannelCountIsKnown && outputChannelCount > outputDeviceInfo->maxOutputChannels ) return paInvalidChannelCount; /* validate hostApiSpecificStreamInfo */ outputStreamInfo = (PaWinDirectSoundStreamInfo*)outputParameters->hostApiSpecificStreamInfo; result = ValidateWinDirectSoundSpecificStreamInfo( outputParameters, outputStreamInfo ); if( result != paNoError ) return result; if( outputStreamInfo && outputStreamInfo->flags & paWinDirectSoundUseLowLevelLatencyParameters ) userRequestedHostOutputBufferSizeFrames = outputStreamInfo->framesPerBuffer; if( outputStreamInfo && outputStreamInfo->flags & paWinDirectSoundUseChannelMask ) outputChannelMask = outputStreamInfo->channelMask; else outputChannelMask = PaWin_DefaultChannelMask( outputChannelCount ); } else { outputChannelCount = 0; outputSampleFormat = 0; suggestedOutputLatencyFrames = 0; } /* If low level host buffer size is specified for both input and output the current code requires the sizes to match. */ if( (userRequestedHostInputBufferSizeFrames > 0 && userRequestedHostOutputBufferSizeFrames > 0) && userRequestedHostInputBufferSizeFrames != userRequestedHostOutputBufferSizeFrames ) return paIncompatibleHostApiSpecificStreamInfo; /* IMPLEMENT ME: ( the following two checks are taken care of by PaUtil_InitializeBufferProcessor() ) - check that input device can support inputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format - check that output device can support outputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format - if a full duplex stream is requested, check that the combination of input and output parameters is supported - check that the device supports sampleRate - alter sampleRate to a close allowable rate if possible / necessary - validate suggestedInputLatency and suggestedOutputLatency parameters, use default values where necessary */ /* validate platform specific flags */ if( (streamFlags & paPlatformSpecificFlags) != 0 ) return paInvalidFlag; /* unexpected platform specific flag */ stream = (PaWinDsStream*)PaUtil_AllocateMemory( sizeof(PaWinDsStream) ); if( !stream ) { result = paInsufficientMemory; goto error; } memset( stream, 0, sizeof(PaWinDsStream) ); /* initialize all stream variables to 0 */ if( streamCallback ) { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &winDsHostApi->callbackStreamInterface, streamCallback, userData ); } else { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &winDsHostApi->blockingStreamInterface, streamCallback, userData ); } streamRepresentationIsInitialized = 1; stream->streamFlags = streamFlags; PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate ); if( inputParameters ) { /* IMPLEMENT ME - establish which host formats are available */ PaSampleFormat nativeInputFormats = paInt16; /* PaSampleFormat nativeFormats = paUInt8 | paInt16 | paInt24 | paInt32 | paFloat32; */ hostInputSampleFormat = PaUtil_SelectClosestAvailableFormat( nativeInputFormats, inputParameters->sampleFormat ); } else { hostInputSampleFormat = 0; } if( outputParameters ) { /* IMPLEMENT ME - establish which host formats are available */ PaSampleFormat nativeOutputFormats = paInt16; /* PaSampleFormat nativeOutputFormats = paUInt8 | paInt16 | paInt24 | paInt32 | paFloat32; */ hostOutputSampleFormat = PaUtil_SelectClosestAvailableFormat( nativeOutputFormats, outputParameters->sampleFormat ); } else { hostOutputSampleFormat = 0; } result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, inputChannelCount, inputSampleFormat, hostInputSampleFormat, outputChannelCount, outputSampleFormat, hostOutputSampleFormat, sampleRate, streamFlags, framesPerBuffer, 0, /* ignored in paUtilVariableHostBufferSizePartialUsageAllowed mode. */ /* This next mode is required because DS can split the host buffer when it wraps around. */ paUtilVariableHostBufferSizePartialUsageAllowed, streamCallback, userData ); if( result != paNoError ) goto error; bufferProcessorIsInitialized = 1; /* DirectSound specific initialization */ { HRESULT hr; unsigned long integerSampleRate = (unsigned long) (sampleRate + 0.5); stream->processingCompleted = CreateEvent( NULL, /* bManualReset = */ TRUE, /* bInitialState = */ FALSE, NULL ); if( stream->processingCompleted == NULL ) { result = paInsufficientMemory; goto error; } #ifdef PA_WIN_DS_USE_WMME_TIMER stream->timerID = 0; #endif #ifdef PA_WIN_DS_USE_WAITABLE_TIMER_OBJECT stream->waitableTimer = (HANDLE)CreateWaitableTimer( 0, FALSE, NULL ); if( stream->waitableTimer == NULL ) { result = paUnanticipatedHostError; PA_DS_SET_LAST_DIRECTSOUND_ERROR( GetLastError() ); goto error; } #endif #ifndef PA_WIN_DS_USE_WMME_TIMER stream->processingThreadCompleted = CreateEvent( NULL, /* bManualReset = */ TRUE, /* bInitialState = */ FALSE, NULL ); if( stream->processingThreadCompleted == NULL ) { result = paUnanticipatedHostError; PA_DS_SET_LAST_DIRECTSOUND_ERROR( GetLastError() ); goto error; } #endif /* set up i/o parameters */ if( userRequestedHostInputBufferSizeFrames > 0 || userRequestedHostOutputBufferSizeFrames > 0 ) { /* use low level parameters */ /* since we use the same host buffer size for input and output we choose the highest user specified value. */ stream->hostBufferSizeFrames = max( userRequestedHostInputBufferSizeFrames, userRequestedHostOutputBufferSizeFrames ); CalculatePollingPeriodFrames( stream->hostBufferSizeFrames, &pollingPeriodFrames, sampleRate, framesPerBuffer ); } else { CalculateBufferSettings( &stream->hostBufferSizeFrames, &pollingPeriodFrames, /* isFullDuplex = */ (inputParameters && outputParameters), suggestedInputLatencyFrames, suggestedOutputLatencyFrames, sampleRate, framesPerBuffer ); } stream->pollingPeriodSeconds = pollingPeriodFrames / sampleRate; DBUG(("DirectSound host buffer size frames: %d, polling period seconds: %f, @ sr: %f\n", stream->hostBufferSizeFrames, stream->pollingPeriodSeconds, sampleRate )); /* ------------------ OUTPUT */ if( outputParameters ) { LARGE_INTEGER counterFrequency; /* PaDeviceInfo *deviceInfo = hostApi->deviceInfos[ outputParameters->device ]; DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", outputParameters->device)); */ int sampleSizeBytes = Pa_GetSampleSize(hostOutputSampleFormat); stream->outputFrameSizeBytes = outputParameters->channelCount * sampleSizeBytes; stream->outputBufferSizeBytes = stream->hostBufferSizeFrames * stream->outputFrameSizeBytes; if( stream->outputBufferSizeBytes < DSBSIZE_MIN ) { result = paBufferTooSmall; goto error; } else if( stream->outputBufferSizeBytes > DSBSIZE_MAX ) { result = paBufferTooBig; goto error; } /* Calculate value used in latency calculation to avoid real-time divides. */ stream->secondsPerHostByte = 1.0 / (stream->bufferProcessor.bytesPerHostOutputSample * outputChannelCount * sampleRate); stream->outputIsRunning = FALSE; stream->outputUnderflowCount = 0; /* perfCounterTicksPerBuffer is used by QueryOutputSpace for overflow detection */ if( QueryPerformanceFrequency( &counterFrequency ) ) { stream->perfCounterTicksPerBuffer.QuadPart = (counterFrequency.QuadPart * stream->hostBufferSizeFrames) / integerSampleRate; } else { stream->perfCounterTicksPerBuffer.QuadPart = 0; } } /* ------------------ INPUT */ if( inputParameters ) { /* PaDeviceInfo *deviceInfo = hostApi->deviceInfos[ inputParameters->device ]; DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", inputParameters->device)); */ int sampleSizeBytes = Pa_GetSampleSize(hostInputSampleFormat); stream->inputFrameSizeBytes = inputParameters->channelCount * sampleSizeBytes; stream->inputBufferSizeBytes = stream->hostBufferSizeFrames * stream->inputFrameSizeBytes; if( stream->inputBufferSizeBytes < DSBSIZE_MIN ) { result = paBufferTooSmall; goto error; } else if( stream->inputBufferSizeBytes > DSBSIZE_MAX ) { result = paBufferTooBig; goto error; } } /* open/create the DirectSound buffers */ /* interface ptrs should be zeroed when stream is zeroed. */ assert( stream->pDirectSoundCapture == NULL ); assert( stream->pDirectSoundInputBuffer == NULL ); assert( stream->pDirectSound == NULL ); assert( stream->pDirectSoundPrimaryBuffer == NULL ); assert( stream->pDirectSoundOutputBuffer == NULL ); if( inputParameters && outputParameters ) { #ifdef PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE /* try to use the full-duplex DX8 API to create the buffers. if that fails we fall back to the half-duplex API below */ hr = InitFullDuplexInputOutputBuffers( stream, (PaWinDsDeviceInfo*)hostApi->deviceInfos[inputParameters->device], hostInputSampleFormat, (WORD)inputParameters->channelCount, stream->inputBufferSizeBytes, inputChannelMask, (PaWinDsDeviceInfo*)hostApi->deviceInfos[outputParameters->device], hostOutputSampleFormat, (WORD)outputParameters->channelCount, stream->outputBufferSizeBytes, outputChannelMask, integerSampleRate ); DBUG(("InitFullDuplexInputOutputBuffers() returns %x\n", hr)); /* ignore any error returned by InitFullDuplexInputOutputBuffers. we retry opening the buffers below */ #endif /* PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE */ } /* create half duplex buffers. also used for full-duplex streams which didn't succeed when using the full duplex API. that could happen because DX8 or greater isnt installed, the i/o devices aren't the same physical device. etc. */ if( outputParameters && !stream->pDirectSoundOutputBuffer ) { hr = InitOutputBuffer( stream, (PaWinDsDeviceInfo*)hostApi->deviceInfos[outputParameters->device], hostOutputSampleFormat, integerSampleRate, (WORD)outputParameters->channelCount, stream->outputBufferSizeBytes, outputChannelMask ); DBUG(("InitOutputBuffer() returns %x\n", hr)); if( hr != DS_OK ) { result = paUnanticipatedHostError; PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr ); goto error; } } if( inputParameters && !stream->pDirectSoundInputBuffer ) { hr = InitInputBuffer( stream, (PaWinDsDeviceInfo*)hostApi->deviceInfos[inputParameters->device], hostInputSampleFormat, integerSampleRate, (WORD)inputParameters->channelCount, stream->inputBufferSizeBytes, inputChannelMask ); DBUG(("InitInputBuffer() returns %x\n", hr)); if( hr != DS_OK ) { ERR_RPT(("PortAudio: DSW_InitInputBuffer() returns %x\n", hr)); result = paUnanticipatedHostError; PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr ); goto error; } } } SetStreamInfoLatencies( stream, framesPerBuffer, pollingPeriodFrames, sampleRate ); stream->streamRepresentation.streamInfo.sampleRate = sampleRate; *s = (PaStream*)stream; return result; error: if( stream ) { if( stream->processingCompleted != NULL ) CloseHandle( stream->processingCompleted ); #ifdef PA_WIN_DS_USE_WAITABLE_TIMER_OBJECT if( stream->waitableTimer != NULL ) CloseHandle( stream->waitableTimer ); #endif #ifndef PA_WIN_DS_USE_WMME_TIMER if( stream->processingThreadCompleted != NULL ) CloseHandle( stream->processingThreadCompleted ); #endif if( stream->pDirectSoundOutputBuffer ) { IDirectSoundBuffer_Stop( stream->pDirectSoundOutputBuffer ); IDirectSoundBuffer_Release( stream->pDirectSoundOutputBuffer ); stream->pDirectSoundOutputBuffer = NULL; } if( stream->pDirectSoundPrimaryBuffer ) { IDirectSoundBuffer_Release( stream->pDirectSoundPrimaryBuffer ); stream->pDirectSoundPrimaryBuffer = NULL; } if( stream->pDirectSoundInputBuffer ) { IDirectSoundCaptureBuffer_Stop( stream->pDirectSoundInputBuffer ); IDirectSoundCaptureBuffer_Release( stream->pDirectSoundInputBuffer ); stream->pDirectSoundInputBuffer = NULL; } if( stream->pDirectSoundCapture ) { IDirectSoundCapture_Release( stream->pDirectSoundCapture ); stream->pDirectSoundCapture = NULL; } if( stream->pDirectSound ) { IDirectSound_Release( stream->pDirectSound ); stream->pDirectSound = NULL; } #ifdef PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE if( stream->pDirectSoundFullDuplex8 ) { IDirectSoundFullDuplex_Release( stream->pDirectSoundFullDuplex8 ); stream->pDirectSoundFullDuplex8 = NULL; } #endif if( bufferProcessorIsInitialized ) PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); if( streamRepresentationIsInitialized ) PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); PaUtil_FreeMemory( stream ); } return result; } /************************************************************************************ * Determine how much space can be safely written to in DS buffer. * Detect underflows and overflows. * Does not allow writing into safety gap maintained by DirectSound. */ static HRESULT QueryOutputSpace( PaWinDsStream *stream, long *bytesEmpty ) { HRESULT hr; DWORD playCursor; DWORD writeCursor; long numBytesEmpty; long playWriteGap; // Query to see how much room is in buffer. hr = IDirectSoundBuffer_GetCurrentPosition( stream->pDirectSoundOutputBuffer, &playCursor, &writeCursor ); if( hr != DS_OK ) { return hr; } // Determine size of gap between playIndex and WriteIndex that we cannot write into. playWriteGap = writeCursor - playCursor; if( playWriteGap < 0 ) playWriteGap += stream->outputBufferSizeBytes; // unwrap /* DirectSound doesn't have a large enough playCursor so we cannot detect wrap-around. */ /* Attempt to detect playCursor wrap-around and correct it. */ if( stream->outputIsRunning && (stream->perfCounterTicksPerBuffer.QuadPart != 0) ) { /* How much time has elapsed since last check. */ LARGE_INTEGER currentTime; LARGE_INTEGER elapsedTime; long bytesPlayed; long bytesExpected; long buffersWrapped; QueryPerformanceCounter( ¤tTime ); elapsedTime.QuadPart = currentTime.QuadPart - stream->previousPlayTime.QuadPart; stream->previousPlayTime = currentTime; /* How many bytes does DirectSound say have been played. */ bytesPlayed = playCursor - stream->previousPlayCursor; if( bytesPlayed < 0 ) bytesPlayed += stream->outputBufferSizeBytes; // unwrap stream->previousPlayCursor = playCursor; /* Calculate how many bytes we would have expected to been played by now. */ bytesExpected = (long) ((elapsedTime.QuadPart * stream->outputBufferSizeBytes) / stream->perfCounterTicksPerBuffer.QuadPart); buffersWrapped = (bytesExpected - bytesPlayed) / stream->outputBufferSizeBytes; if( buffersWrapped > 0 ) { playCursor += (buffersWrapped * stream->outputBufferSizeBytes); bytesPlayed += (buffersWrapped * stream->outputBufferSizeBytes); } } numBytesEmpty = playCursor - stream->outputBufferWriteOffsetBytes; if( numBytesEmpty < 0 ) numBytesEmpty += stream->outputBufferSizeBytes; // unwrap offset /* Have we underflowed? */ if( numBytesEmpty > (stream->outputBufferSizeBytes - playWriteGap) ) { if( stream->outputIsRunning ) { stream->outputUnderflowCount += 1; } /* From MSDN: The write cursor indicates the position at which it is safe to write new data to the buffer. The write cursor always leads the play cursor, typically by about 15 milliseconds' worth of audio data. It is always safe to change data that is behind the position indicated by the lpdwCurrentPlayCursor parameter. */ stream->outputBufferWriteOffsetBytes = writeCursor; numBytesEmpty = stream->outputBufferSizeBytes - playWriteGap; } *bytesEmpty = numBytesEmpty; return hr; } /***********************************************************************************/ static int TimeSlice( PaWinDsStream *stream ) { long numFrames = 0; long bytesEmpty = 0; long bytesFilled = 0; long bytesToXfer = 0; long framesToXfer = 0; /* the number of frames we'll process this tick */ long numInFramesReady = 0; long numOutFramesReady = 0; long bytesProcessed; HRESULT hresult; double outputLatency = 0; double inputLatency = 0; PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /* Input */ LPBYTE lpInBuf1 = NULL; LPBYTE lpInBuf2 = NULL; DWORD dwInSize1 = 0; DWORD dwInSize2 = 0; /* Output */ LPBYTE lpOutBuf1 = NULL; LPBYTE lpOutBuf2 = NULL; DWORD dwOutSize1 = 0; DWORD dwOutSize2 = 0; /* How much input data is available? */ if( stream->bufferProcessor.inputChannelCount > 0 ) { HRESULT hr; DWORD capturePos; DWORD readPos; long filled = 0; // Query to see how much data is in buffer. // We don't need the capture position but sometimes DirectSound doesn't handle NULLS correctly // so let's pass a pointer just to be safe. hr = IDirectSoundCaptureBuffer_GetCurrentPosition( stream->pDirectSoundInputBuffer, &capturePos, &readPos ); if( hr == DS_OK ) { filled = readPos - stream->readOffset; if( filled < 0 ) filled += stream->inputBufferSizeBytes; // unwrap offset bytesFilled = filled; inputLatency = ((double)bytesFilled) * stream->secondsPerHostByte; } // FIXME: what happens if IDirectSoundCaptureBuffer_GetCurrentPosition fails? framesToXfer = numInFramesReady = bytesFilled / stream->inputFrameSizeBytes; /** @todo Check for overflow */ } /* How much output room is available? */ if( stream->bufferProcessor.outputChannelCount > 0 ) { UINT previousUnderflowCount = stream->outputUnderflowCount; QueryOutputSpace( stream, &bytesEmpty ); framesToXfer = numOutFramesReady = bytesEmpty / stream->outputFrameSizeBytes; /* Check for underflow */ /* FIXME QueryOutputSpace should not adjust underflow count as a side effect. A query function should be a const operator on the stream and return a flag on underflow. */ if( stream->outputUnderflowCount != previousUnderflowCount ) stream->callbackFlags |= paOutputUnderflow; /* We are about to compute audio into the first byte of empty space in the output buffer. This audio will reach the DAC after all of the current (non-empty) audio in the buffer has played. Therefore the output time is the current time plus the time it takes to play the non-empty bytes in the buffer, computed here: */ outputLatency = ((double)(stream->outputBufferSizeBytes - bytesEmpty)) * stream->secondsPerHostByte; } /* if it's a full duplex stream, set framesToXfer to the minimum of input and output frames ready */ if( stream->bufferProcessor.inputChannelCount > 0 && stream->bufferProcessor.outputChannelCount > 0 ) { framesToXfer = (numOutFramesReady < numInFramesReady) ? numOutFramesReady : numInFramesReady; } if( framesToXfer > 0 ) { PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); /* The outputBufferDacTime parameter should indicates the time at which the first sample of the output buffer is heard at the DACs. */ timeInfo.currentTime = PaUtil_GetTime(); PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, stream->callbackFlags ); stream->callbackFlags = 0; /* Input */ if( stream->bufferProcessor.inputChannelCount > 0 ) { timeInfo.inputBufferAdcTime = timeInfo.currentTime - inputLatency; bytesToXfer = framesToXfer * stream->inputFrameSizeBytes; hresult = IDirectSoundCaptureBuffer_Lock ( stream->pDirectSoundInputBuffer, stream->readOffset, bytesToXfer, (void **) &lpInBuf1, &dwInSize1, (void **) &lpInBuf2, &dwInSize2, 0); if (hresult != DS_OK) { ERR_RPT(("DirectSound IDirectSoundCaptureBuffer_Lock failed, hresult = 0x%x\n",hresult)); /* PA_DS_SET_LAST_DIRECTSOUND_ERROR( hresult ); */ PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); /* flush the buffer processor */ stream->callbackResult = paComplete; goto error2; } numFrames = dwInSize1 / stream->inputFrameSizeBytes; PaUtil_SetInputFrameCount( &stream->bufferProcessor, numFrames ); PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, 0, lpInBuf1, 0 ); /* Is input split into two regions. */ if( dwInSize2 > 0 ) { numFrames = dwInSize2 / stream->inputFrameSizeBytes; PaUtil_Set2ndInputFrameCount( &stream->bufferProcessor, numFrames ); PaUtil_Set2ndInterleavedInputChannels( &stream->bufferProcessor, 0, lpInBuf2, 0 ); } } /* Output */ if( stream->bufferProcessor.outputChannelCount > 0 ) { /* We don't currently add outputLatency here because it appears to produce worse results than not adding it. Need to do more testing to verify this. */ /* timeInfo.outputBufferDacTime = timeInfo.currentTime + outputLatency; */ timeInfo.outputBufferDacTime = timeInfo.currentTime; bytesToXfer = framesToXfer * stream->outputFrameSizeBytes; hresult = IDirectSoundBuffer_Lock ( stream->pDirectSoundOutputBuffer, stream->outputBufferWriteOffsetBytes, bytesToXfer, (void **) &lpOutBuf1, &dwOutSize1, (void **) &lpOutBuf2, &dwOutSize2, 0); if (hresult != DS_OK) { ERR_RPT(("DirectSound IDirectSoundBuffer_Lock failed, hresult = 0x%x\n",hresult)); /* PA_DS_SET_LAST_DIRECTSOUND_ERROR( hresult ); */ PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); /* flush the buffer processor */ stream->callbackResult = paComplete; goto error1; } numFrames = dwOutSize1 / stream->outputFrameSizeBytes; PaUtil_SetOutputFrameCount( &stream->bufferProcessor, numFrames ); PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, 0, lpOutBuf1, 0 ); /* Is output split into two regions. */ if( dwOutSize2 > 0 ) { numFrames = dwOutSize2 / stream->outputFrameSizeBytes; PaUtil_Set2ndOutputFrameCount( &stream->bufferProcessor, numFrames ); PaUtil_Set2ndInterleavedOutputChannels( &stream->bufferProcessor, 0, lpOutBuf2, 0 ); } } numFrames = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &stream->callbackResult ); stream->framesWritten += numFrames; if( stream->bufferProcessor.outputChannelCount > 0 ) { /* FIXME: an underflow could happen here */ /* Update our buffer offset and unlock sound buffer */ bytesProcessed = numFrames * stream->outputFrameSizeBytes; stream->outputBufferWriteOffsetBytes = (stream->outputBufferWriteOffsetBytes + bytesProcessed) % stream->outputBufferSizeBytes; IDirectSoundBuffer_Unlock( stream->pDirectSoundOutputBuffer, lpOutBuf1, dwOutSize1, lpOutBuf2, dwOutSize2); } error1: if( stream->bufferProcessor.inputChannelCount > 0 ) { /* FIXME: an overflow could happen here */ /* Update our buffer offset and unlock sound buffer */ bytesProcessed = numFrames * stream->inputFrameSizeBytes; stream->readOffset = (stream->readOffset + bytesProcessed) % stream->inputBufferSizeBytes; IDirectSoundCaptureBuffer_Unlock( stream->pDirectSoundInputBuffer, lpInBuf1, dwInSize1, lpInBuf2, dwInSize2); } error2: PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, numFrames ); } if( stream->callbackResult == paComplete && !PaUtil_IsBufferProcessorOutputEmpty( &stream->bufferProcessor ) ) { /* don't return completed until the buffer processor has been drained */ return paContinue; } else { return stream->callbackResult; } } /*******************************************************************/ static HRESULT ZeroAvailableOutputSpace( PaWinDsStream *stream ) { HRESULT hr; LPBYTE lpbuf1 = NULL; LPBYTE lpbuf2 = NULL; DWORD dwsize1 = 0; DWORD dwsize2 = 0; long bytesEmpty; hr = QueryOutputSpace( stream, &bytesEmpty ); if (hr != DS_OK) return hr; if( bytesEmpty == 0 ) return DS_OK; // Lock free space in the DS hr = IDirectSoundBuffer_Lock( stream->pDirectSoundOutputBuffer, stream->outputBufferWriteOffsetBytes, bytesEmpty, (void **) &lpbuf1, &dwsize1, (void **) &lpbuf2, &dwsize2, 0); if (hr == DS_OK) { // Copy the buffer into the DS ZeroMemory(lpbuf1, dwsize1); if(lpbuf2 != NULL) { ZeroMemory(lpbuf2, dwsize2); } // Update our buffer offset and unlock sound buffer stream->outputBufferWriteOffsetBytes = (stream->outputBufferWriteOffsetBytes + dwsize1 + dwsize2) % stream->outputBufferSizeBytes; IDirectSoundBuffer_Unlock( stream->pDirectSoundOutputBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2); stream->finalZeroBytesWritten += dwsize1 + dwsize2; } return hr; } static void CALLBACK TimerCallback(UINT uID, UINT uMsg, DWORD_PTR dwUser, DWORD dw1, DWORD dw2) { PaWinDsStream *stream; int isFinished = 0; /* suppress unused variable warnings */ (void) uID; (void) uMsg; (void) dw1; (void) dw2; stream = (PaWinDsStream *) dwUser; if( stream == NULL ) return; if( stream->isActive ) { if( stream->abortProcessing ) { isFinished = 1; } else if( stream->stopProcessing ) { if( stream->bufferProcessor.outputChannelCount > 0 ) { ZeroAvailableOutputSpace( stream ); if( stream->finalZeroBytesWritten >= stream->outputBufferSizeBytes ) { /* once we've flushed the whole output buffer with zeros we know all data has been played */ isFinished = 1; } } else { isFinished = 1; } } else { int callbackResult = TimeSlice( stream ); if( callbackResult != paContinue ) { /* FIXME implement handling of paComplete and paAbort if possible At the moment this should behave as if paComplete was called and flush the buffer. */ stream->stopProcessing = 1; } } if( isFinished ) { if( stream->streamRepresentation.streamFinishedCallback != 0 ) stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); stream->isActive = 0; /* don't set this until the stream really is inactive */ SetEvent( stream->processingCompleted ); } } } #ifndef PA_WIN_DS_USE_WMME_TIMER #ifdef PA_WIN_DS_USE_WAITABLE_TIMER_OBJECT static void CALLBACK WaitableTimerAPCProc( LPVOID lpArg, // Data value DWORD dwTimerLowValue, // Timer low value DWORD dwTimerHighValue ) // Timer high value { (void)dwTimerLowValue; (void)dwTimerHighValue; TimerCallback( 0, 0, (DWORD_PTR)lpArg, 0, 0 ); } #endif /* PA_WIN_DS_USE_WAITABLE_TIMER_OBJECT */ PA_THREAD_FUNC ProcessingThreadProc( void *pArg ) { PaWinDsStream *stream = (PaWinDsStream *)pArg; LARGE_INTEGER dueTime; int timerPeriodMs; timerPeriodMs = (int)(stream->pollingPeriodSeconds * MSECS_PER_SECOND); if( timerPeriodMs < 1 ) timerPeriodMs = 1; #ifdef PA_WIN_DS_USE_WAITABLE_TIMER_OBJECT assert( stream->waitableTimer != NULL ); /* invoke first timeout immediately */ dueTime.LowPart = timerPeriodMs * 1000 * 10; dueTime.HighPart = 0; /* tick using waitable timer */ if( SetWaitableTimer( stream->waitableTimer, &dueTime, timerPeriodMs, WaitableTimerAPCProc, pArg, FALSE ) != 0 ) { DWORD wfsoResult = 0; do { /* wait for processingCompleted to be signaled or our timer APC to be called */ wfsoResult = WaitForSingleObjectEx( stream->processingCompleted, timerPeriodMs * 10, /* alertable = */ TRUE ); }while( wfsoResult == WAIT_TIMEOUT || wfsoResult == WAIT_IO_COMPLETION ); } CancelWaitableTimer( stream->waitableTimer ); #else /* tick using WaitForSingleObject timout */ while ( WaitForSingleObject( stream->processingCompleted, timerPeriodMs ) == WAIT_TIMEOUT ) { TimerCallback( 0, 0, (DWORD_PTR)pArg, 0, 0 ); } #endif /* PA_WIN_DS_USE_WAITABLE_TIMER_OBJECT */ SetEvent( stream->processingThreadCompleted ); return 0; } #endif /* !PA_WIN_DS_USE_WMME_TIMER */ /*********************************************************************************** When CloseStream() is called, the multi-api layer ensures that the stream has already been stopped or aborted. */ static PaError CloseStream( PaStream* s ) { PaError result = paNoError; PaWinDsStream *stream = (PaWinDsStream*)s; CloseHandle( stream->processingCompleted ); #ifdef PA_WIN_DS_USE_WAITABLE_TIMER_OBJECT if( stream->waitableTimer != NULL ) CloseHandle( stream->waitableTimer ); #endif #ifndef PA_WIN_DS_USE_WMME_TIMER CloseHandle( stream->processingThreadCompleted ); #endif // Cleanup the sound buffers if( stream->pDirectSoundOutputBuffer ) { IDirectSoundBuffer_Stop( stream->pDirectSoundOutputBuffer ); IDirectSoundBuffer_Release( stream->pDirectSoundOutputBuffer ); stream->pDirectSoundOutputBuffer = NULL; } if( stream->pDirectSoundPrimaryBuffer ) { IDirectSoundBuffer_Release( stream->pDirectSoundPrimaryBuffer ); stream->pDirectSoundPrimaryBuffer = NULL; } if( stream->pDirectSoundInputBuffer ) { IDirectSoundCaptureBuffer_Stop( stream->pDirectSoundInputBuffer ); IDirectSoundCaptureBuffer_Release( stream->pDirectSoundInputBuffer ); stream->pDirectSoundInputBuffer = NULL; } if( stream->pDirectSoundCapture ) { IDirectSoundCapture_Release( stream->pDirectSoundCapture ); stream->pDirectSoundCapture = NULL; } if( stream->pDirectSound ) { IDirectSound_Release( stream->pDirectSound ); stream->pDirectSound = NULL; } #ifdef PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE if( stream->pDirectSoundFullDuplex8 ) { IDirectSoundFullDuplex_Release( stream->pDirectSoundFullDuplex8 ); stream->pDirectSoundFullDuplex8 = NULL; } #endif PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); PaUtil_FreeMemory( stream ); return result; } /***********************************************************************************/ static HRESULT ClearOutputBuffer( PaWinDsStream *stream ) { PaError result = paNoError; unsigned char* pDSBuffData; DWORD dwDataLen; HRESULT hr; hr = IDirectSoundBuffer_SetCurrentPosition( stream->pDirectSoundOutputBuffer, 0 ); DBUG(("PaHost_ClearOutputBuffer: IDirectSoundBuffer_SetCurrentPosition returned = 0x%X.\n", hr)); if( hr != DS_OK ) return hr; // Lock the DS buffer if ((hr = IDirectSoundBuffer_Lock( stream->pDirectSoundOutputBuffer, 0, stream->outputBufferSizeBytes, (LPVOID*)&pDSBuffData, &dwDataLen, NULL, 0, 0)) != DS_OK ) return hr; // Zero the DS buffer ZeroMemory(pDSBuffData, dwDataLen); // Unlock the DS buffer if ((hr = IDirectSoundBuffer_Unlock( stream->pDirectSoundOutputBuffer, pDSBuffData, dwDataLen, NULL, 0)) != DS_OK) return hr; // Let DSound set the starting write position because if we set it to zero, it looks like the // buffer is full to begin with. This causes a long pause before sound starts when using large buffers. if ((hr = IDirectSoundBuffer_GetCurrentPosition( stream->pDirectSoundOutputBuffer, &stream->previousPlayCursor, &stream->outputBufferWriteOffsetBytes )) != DS_OK) return hr; /* printf("DSW_InitOutputBuffer: playCursor = %d, writeCursor = %d\n", playCursor, dsw->dsw_WriteOffset ); */ return DS_OK; } static PaError StartStream( PaStream *s ) { PaError result = paNoError; PaWinDsStream *stream = (PaWinDsStream*)s; HRESULT hr; stream->callbackResult = paContinue; PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); ResetEvent( stream->processingCompleted ); #ifndef PA_WIN_DS_USE_WMME_TIMER ResetEvent( stream->processingThreadCompleted ); #endif if( stream->bufferProcessor.inputChannelCount > 0 ) { // Start the buffer capture if( stream->pDirectSoundInputBuffer != NULL ) // FIXME: not sure this check is necessary { hr = IDirectSoundCaptureBuffer_Start( stream->pDirectSoundInputBuffer, DSCBSTART_LOOPING ); } DBUG(("StartStream: DSW_StartInput returned = 0x%X.\n", hr)); if( hr != DS_OK ) { result = paUnanticipatedHostError; PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr ); goto error; } } stream->framesWritten = 0; stream->callbackFlags = 0; stream->abortProcessing = 0; stream->stopProcessing = 0; if( stream->bufferProcessor.outputChannelCount > 0 ) { QueryPerformanceCounter( &stream->previousPlayTime ); stream->finalZeroBytesWritten = 0; hr = ClearOutputBuffer( stream ); if( hr != DS_OK ) { result = paUnanticipatedHostError; PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr ); goto error; } if( stream->streamRepresentation.streamCallback && (stream->streamFlags & paPrimeOutputBuffersUsingStreamCallback) ) { stream->callbackFlags = paPrimingOutput; TimeSlice( stream ); /* we ignore the return value from TimeSlice here and start the stream as usual. The first timer callback will detect if the callback has completed. */ stream->callbackFlags = 0; } // Start the buffer playback in a loop. if( stream->pDirectSoundOutputBuffer != NULL ) // FIXME: not sure this needs to be checked here { hr = IDirectSoundBuffer_Play( stream->pDirectSoundOutputBuffer, 0, 0, DSBPLAY_LOOPING ); DBUG(("PaHost_StartOutput: IDirectSoundBuffer_Play returned = 0x%X.\n", hr)); if( hr != DS_OK ) { result = paUnanticipatedHostError; PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr ); goto error; } stream->outputIsRunning = TRUE; } } if( stream->streamRepresentation.streamCallback ) { TIMECAPS timecaps; int timerPeriodMs = (int)(stream->pollingPeriodSeconds * MSECS_PER_SECOND); if( timerPeriodMs < 1 ) timerPeriodMs = 1; /* set windows scheduler granularity only as fine as needed, no finer */ /* Although this is not fully documented by MS, it appears that timeBeginPeriod() affects the scheduling granulatity of all timers including Waitable Timer Objects. So we always call timeBeginPeriod, whether we're using an MM timer callback via timeSetEvent or not. */ assert( stream->systemTimerResolutionPeriodMs == 0 ); if( timeGetDevCaps( &timecaps, sizeof(TIMECAPS) ) == MMSYSERR_NOERROR && timecaps.wPeriodMin > 0 ) { /* aim for resolution 4 times higher than polling rate */ stream->systemTimerResolutionPeriodMs = (UINT)((stream->pollingPeriodSeconds * MSECS_PER_SECOND) * .25); if( stream->systemTimerResolutionPeriodMs < timecaps.wPeriodMin ) stream->systemTimerResolutionPeriodMs = timecaps.wPeriodMin; if( stream->systemTimerResolutionPeriodMs > timecaps.wPeriodMax ) stream->systemTimerResolutionPeriodMs = timecaps.wPeriodMax; if( timeBeginPeriod( stream->systemTimerResolutionPeriodMs ) != MMSYSERR_NOERROR ) stream->systemTimerResolutionPeriodMs = 0; /* timeBeginPeriod failed, so we don't need to call timeEndPeriod() later */ } #ifdef PA_WIN_DS_USE_WMME_TIMER /* Create timer that will wake us up so we can fill the DSound buffer. */ /* We have deprecated timeSetEvent because all MM timer callbacks are serialised onto a single thread. Which creates problems with multiple PA streams, or when also using timers for other time critical tasks */ stream->timerID = timeSetEvent( timerPeriodMs, stream->systemTimerResolutionPeriodMs, (LPTIMECALLBACK) TimerCallback, (DWORD_PTR) stream, TIME_PERIODIC | TIME_KILL_SYNCHRONOUS ); if( stream->timerID == 0 ) { stream->isActive = 0; result = paUnanticipatedHostError; PA_DS_SET_LAST_DIRECTSOUND_ERROR( GetLastError() ); goto error; } #else /* Create processing thread which calls TimerCallback */ stream->processingThread = CREATE_THREAD( 0, 0, ProcessingThreadProc, stream, 0, &stream->processingThreadId ); if( !stream->processingThread ) { result = paUnanticipatedHostError; PA_DS_SET_LAST_DIRECTSOUND_ERROR( GetLastError() ); goto error; } if( !SetThreadPriority( stream->processingThread, THREAD_PRIORITY_TIME_CRITICAL ) ) { result = paUnanticipatedHostError; PA_DS_SET_LAST_DIRECTSOUND_ERROR( GetLastError() ); goto error; } #endif } stream->isActive = 1; stream->isStarted = 1; assert( result == paNoError ); return result; error: if( stream->pDirectSoundOutputBuffer != NULL && stream->outputIsRunning ) IDirectSoundBuffer_Stop( stream->pDirectSoundOutputBuffer ); stream->outputIsRunning = FALSE; #ifndef PA_WIN_DS_USE_WMME_TIMER if( stream->processingThread ) { #ifdef CLOSE_THREAD_HANDLE CLOSE_THREAD_HANDLE( stream->processingThread ); /* Delete thread. */ #endif stream->processingThread = NULL; } #endif return result; } /***********************************************************************************/ static PaError StopStream( PaStream *s ) { PaError result = paNoError; PaWinDsStream *stream = (PaWinDsStream*)s; HRESULT hr; int timeoutMsec; if( stream->streamRepresentation.streamCallback ) { stream->stopProcessing = 1; /* Set timeout at 4 times maximum time we might wait. */ timeoutMsec = (int) (4 * MSECS_PER_SECOND * (stream->hostBufferSizeFrames / stream->streamRepresentation.streamInfo.sampleRate)); WaitForSingleObject( stream->processingCompleted, timeoutMsec ); } #ifdef PA_WIN_DS_USE_WMME_TIMER if( stream->timerID != 0 ) { timeKillEvent(stream->timerID); /* Stop callback timer. */ stream->timerID = 0; } #else if( stream->processingThread ) { if( WaitForSingleObject( stream->processingThreadCompleted, 30*100 ) == WAIT_TIMEOUT ) return paUnanticipatedHostError; #ifdef CLOSE_THREAD_HANDLE CloseHandle( stream->processingThread ); /* Delete thread. */ stream->processingThread = NULL; #endif } #endif if( stream->systemTimerResolutionPeriodMs > 0 ){ timeEndPeriod( stream->systemTimerResolutionPeriodMs ); stream->systemTimerResolutionPeriodMs = 0; } if( stream->bufferProcessor.outputChannelCount > 0 ) { // Stop the buffer playback if( stream->pDirectSoundOutputBuffer != NULL ) { stream->outputIsRunning = FALSE; // FIXME: what happens if IDirectSoundBuffer_Stop returns an error? hr = IDirectSoundBuffer_Stop( stream->pDirectSoundOutputBuffer ); if( stream->pDirectSoundPrimaryBuffer ) IDirectSoundBuffer_Stop( stream->pDirectSoundPrimaryBuffer ); /* FIXME we never started the primary buffer so I'm not sure we need to stop it */ } } if( stream->bufferProcessor.inputChannelCount > 0 ) { // Stop the buffer capture if( stream->pDirectSoundInputBuffer != NULL ) { // FIXME: what happens if IDirectSoundCaptureBuffer_Stop returns an error? hr = IDirectSoundCaptureBuffer_Stop( stream->pDirectSoundInputBuffer ); } } stream->isStarted = 0; return result; } /***********************************************************************************/ static PaError AbortStream( PaStream *s ) { PaWinDsStream *stream = (PaWinDsStream*)s; stream->abortProcessing = 1; return StopStream( s ); } /***********************************************************************************/ static PaError IsStreamStopped( PaStream *s ) { PaWinDsStream *stream = (PaWinDsStream*)s; return !stream->isStarted; } /***********************************************************************************/ static PaError IsStreamActive( PaStream *s ) { PaWinDsStream *stream = (PaWinDsStream*)s; return stream->isActive; } /***********************************************************************************/ static PaTime GetStreamTime( PaStream *s ) { /* suppress unused variable warnings */ (void) s; return PaUtil_GetTime(); } /***********************************************************************************/ static double GetStreamCpuLoad( PaStream* s ) { PaWinDsStream *stream = (PaWinDsStream*)s; return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); } /*********************************************************************************** As separate stream interfaces are used for blocking and callback streams, the following functions can be guaranteed to only be called for blocking streams. */ static PaError ReadStream( PaStream* s, void *buffer, unsigned long frames ) { PaWinDsStream *stream = (PaWinDsStream*)s; /* suppress unused variable warnings */ (void) buffer; (void) frames; (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ return paNoError; } /***********************************************************************************/ static PaError WriteStream( PaStream* s, const void *buffer, unsigned long frames ) { PaWinDsStream *stream = (PaWinDsStream*)s; /* suppress unused variable warnings */ (void) buffer; (void) frames; (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ return paNoError; } /***********************************************************************************/ static signed long GetStreamReadAvailable( PaStream* s ) { PaWinDsStream *stream = (PaWinDsStream*)s; /* suppress unused variable warnings */ (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ return 0; } /***********************************************************************************/ static signed long GetStreamWriteAvailable( PaStream* s ) { PaWinDsStream *stream = (PaWinDsStream*)s; /* suppress unused variable warnings */ (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ return 0; } #endif praat-6.0.04/external/portaudio/pa_win_ds.h000066400000000000000000000066751261542461700207020ustar00rootroot00000000000000#ifndef PA_WIN_DS_H #define PA_WIN_DS_H /* * $Id: $ * PortAudio Portable Real-Time Audio Library * DirectSound specific extensions * * Copyright (c) 1999-2007 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup public_header @brief DirectSound-specific PortAudio API extension header file. */ #include "portaudio.h" #include "pa_win_waveformat.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define paWinDirectSoundUseLowLevelLatencyParameters (0x01) #define paWinDirectSoundUseChannelMask (0x04) typedef struct PaWinDirectSoundStreamInfo{ unsigned long size; /**< sizeof(PaWinDirectSoundStreamInfo) */ PaHostApiTypeId hostApiType; /**< paDirectSound */ unsigned long version; /**< 2 */ unsigned long flags; /**< enable other features of this struct */ /** low-level latency setting support Sets the size of the DirectSound host buffer. When flags contains the paWinDirectSoundUseLowLevelLatencyParameters this size will be used instead of interpreting the generic latency parameters to Pa_OpenStream(). If the flag is not set this value is ignored. If the stream is a full duplex stream the implementation requires that the values of framesPerBuffer for input and output match (if both are specified). */ unsigned long framesPerBuffer; /** support for WAVEFORMATEXTENSIBLE channel masks. If flags contains paWinDirectSoundUseChannelMask this allows you to specify which speakers to address in a multichannel stream. Constants for channelMask are specified in pa_win_waveformat.h */ PaWinWaveFormatChannelMask channelMask; }PaWinDirectSoundStreamInfo; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_WIN_DS_H */ praat-6.0.04/external/portaudio/pa_win_ds_dynlink.c000066400000000000000000000234201261542461700224100ustar00rootroot00000000000000/* * Interface for dynamically loading directsound and providing a dummy * implementation if it isn't present. * * Author: Ross Bencina (some portions Phil Burk & Robert Marsanyi) * * For PortAudio Portable Real-Time Audio Library * For more information see: http://www.portaudio.com * Copyright (c) 1999-2006 Phil Burk, Robert Marsanyi and Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostapi_src */ #include "pa_win_ds_dynlink.h" #include "pa_debugprint.h" PaWinDsDSoundEntryPoints paWinDsDSoundEntryPoints = { 0, 0, 0, 0, 0, 0, 0 }; static HRESULT WINAPI DummyDllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { (void)rclsid; /* unused parameter */ (void)riid; /* unused parameter */ (void)ppv; /* unused parameter */ return CLASS_E_CLASSNOTAVAILABLE; } static HRESULT WINAPI DummyDirectSoundCreate(LPGUID lpcGuidDevice, LPDIRECTSOUND *ppDS, LPUNKNOWN pUnkOuter) { (void)lpcGuidDevice; /* unused parameter */ (void)ppDS; /* unused parameter */ (void)pUnkOuter; /* unused parameter */ return E_NOTIMPL; } static HRESULT WINAPI DummyDirectSoundEnumerateW(LPDSENUMCALLBACKW lpDSEnumCallback, LPVOID lpContext) { (void)lpDSEnumCallback; /* unused parameter */ (void)lpContext; /* unused parameter */ return E_NOTIMPL; } static HRESULT WINAPI DummyDirectSoundEnumerateA(LPDSENUMCALLBACKA lpDSEnumCallback, LPVOID lpContext) { (void)lpDSEnumCallback; /* unused parameter */ (void)lpContext; /* unused parameter */ return E_NOTIMPL; } static HRESULT WINAPI DummyDirectSoundCaptureCreate(LPGUID lpcGUID, LPDIRECTSOUNDCAPTURE *lplpDSC, LPUNKNOWN pUnkOuter) { (void)lpcGUID; /* unused parameter */ (void)lplpDSC; /* unused parameter */ (void)pUnkOuter; /* unused parameter */ return E_NOTIMPL; } static HRESULT WINAPI DummyDirectSoundCaptureEnumerateW(LPDSENUMCALLBACKW lpDSCEnumCallback, LPVOID lpContext) { (void)lpDSCEnumCallback; /* unused parameter */ (void)lpContext; /* unused parameter */ return E_NOTIMPL; } static HRESULT WINAPI DummyDirectSoundCaptureEnumerateA(LPDSENUMCALLBACKA lpDSCEnumCallback, LPVOID lpContext) { (void)lpDSCEnumCallback; /* unused parameter */ (void)lpContext; /* unused parameter */ return E_NOTIMPL; } #ifdef PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE static HRESULT WINAPI DummyDirectSoundFullDuplexCreate8( LPCGUID pcGuidCaptureDevice, LPCGUID pcGuidRenderDevice, LPCDSCBUFFERDESC pcDSCBufferDesc, LPCDSBUFFERDESC pcDSBufferDesc, HWND hWnd, DWORD dwLevel, LPDIRECTSOUNDFULLDUPLEX * ppDSFD, LPDIRECTSOUNDCAPTUREBUFFER8 * ppDSCBuffer8, LPDIRECTSOUNDBUFFER8 * ppDSBuffer8, LPUNKNOWN pUnkOuter) { (void)pcGuidCaptureDevice; /* unused parameter */ (void)pcGuidRenderDevice; /* unused parameter */ (void)pcDSCBufferDesc; /* unused parameter */ (void)pcDSBufferDesc; /* unused parameter */ (void)hWnd; /* unused parameter */ (void)dwLevel; /* unused parameter */ (void)ppDSFD; /* unused parameter */ (void)ppDSCBuffer8; /* unused parameter */ (void)ppDSBuffer8; /* unused parameter */ (void)pUnkOuter; /* unused parameter */ return E_NOTIMPL; } #endif /* PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE */ void PaWinDs_InitializeDSoundEntryPoints(void) { paWinDsDSoundEntryPoints.hInstance_ = LoadLibraryA("dsound.dll"); if( paWinDsDSoundEntryPoints.hInstance_ != NULL ) { paWinDsDSoundEntryPoints.DllGetClassObject = (HRESULT (WINAPI *)(REFCLSID, REFIID , LPVOID *)) GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DllGetClassObject" ); if( paWinDsDSoundEntryPoints.DllGetClassObject == NULL ) paWinDsDSoundEntryPoints.DllGetClassObject = DummyDllGetClassObject; paWinDsDSoundEntryPoints.DirectSoundCreate = (HRESULT (WINAPI *)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN)) GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundCreate" ); if( paWinDsDSoundEntryPoints.DirectSoundCreate == NULL ) paWinDsDSoundEntryPoints.DirectSoundCreate = DummyDirectSoundCreate; paWinDsDSoundEntryPoints.DirectSoundEnumerateW = (HRESULT (WINAPI *)(LPDSENUMCALLBACKW, LPVOID)) GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundEnumerateW" ); if( paWinDsDSoundEntryPoints.DirectSoundEnumerateW == NULL ) paWinDsDSoundEntryPoints.DirectSoundEnumerateW = DummyDirectSoundEnumerateW; paWinDsDSoundEntryPoints.DirectSoundEnumerateA = (HRESULT (WINAPI *)(LPDSENUMCALLBACKA, LPVOID)) GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundEnumerateA" ); if( paWinDsDSoundEntryPoints.DirectSoundEnumerateA == NULL ) paWinDsDSoundEntryPoints.DirectSoundEnumerateA = DummyDirectSoundEnumerateA; paWinDsDSoundEntryPoints.DirectSoundCaptureCreate = (HRESULT (WINAPI *)(LPGUID, LPDIRECTSOUNDCAPTURE *, LPUNKNOWN)) GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundCaptureCreate" ); if( paWinDsDSoundEntryPoints.DirectSoundCaptureCreate == NULL ) paWinDsDSoundEntryPoints.DirectSoundCaptureCreate = DummyDirectSoundCaptureCreate; paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW = (HRESULT (WINAPI *)(LPDSENUMCALLBACKW, LPVOID)) GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundCaptureEnumerateW" ); if( paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW == NULL ) paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW = DummyDirectSoundCaptureEnumerateW; paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA = (HRESULT (WINAPI *)(LPDSENUMCALLBACKA, LPVOID)) GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundCaptureEnumerateA" ); if( paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA == NULL ) paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA = DummyDirectSoundCaptureEnumerateA; #ifdef PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE paWinDsDSoundEntryPoints.DirectSoundFullDuplexCreate8 = (HRESULT (WINAPI *)(LPCGUID, LPCGUID, LPCDSCBUFFERDESC, LPCDSBUFFERDESC, HWND, DWORD, LPDIRECTSOUNDFULLDUPLEX *, LPDIRECTSOUNDCAPTUREBUFFER8 *, LPDIRECTSOUNDBUFFER8 *, LPUNKNOWN)) GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundFullDuplexCreate" ); if( paWinDsDSoundEntryPoints.DirectSoundFullDuplexCreate8 == NULL ) paWinDsDSoundEntryPoints.DirectSoundFullDuplexCreate8 = DummyDirectSoundFullDuplexCreate8; #endif } else { DWORD errorCode = GetLastError(); // 126 (0x7E) == ERROR_MOD_NOT_FOUND PA_DEBUG(("Couldn't load dsound.dll error code: %d \n",errorCode)); /* initialize with dummy entry points to make live easy when ds isn't present */ paWinDsDSoundEntryPoints.DirectSoundCreate = DummyDirectSoundCreate; paWinDsDSoundEntryPoints.DirectSoundEnumerateW = DummyDirectSoundEnumerateW; paWinDsDSoundEntryPoints.DirectSoundEnumerateA = DummyDirectSoundEnumerateA; paWinDsDSoundEntryPoints.DirectSoundCaptureCreate = DummyDirectSoundCaptureCreate; paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW = DummyDirectSoundCaptureEnumerateW; paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA = DummyDirectSoundCaptureEnumerateA; #ifdef PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE paWinDsDSoundEntryPoints.DirectSoundFullDuplexCreate8 = DummyDirectSoundFullDuplexCreate8; #endif } } void PaWinDs_TerminateDSoundEntryPoints(void) { if( paWinDsDSoundEntryPoints.hInstance_ != NULL ) { /* ensure that we crash reliably if the entry points arent initialised */ paWinDsDSoundEntryPoints.DirectSoundCreate = 0; paWinDsDSoundEntryPoints.DirectSoundEnumerateW = 0; paWinDsDSoundEntryPoints.DirectSoundEnumerateA = 0; paWinDsDSoundEntryPoints.DirectSoundCaptureCreate = 0; paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW = 0; paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA = 0; FreeLibrary( paWinDsDSoundEntryPoints.hInstance_ ); paWinDsDSoundEntryPoints.hInstance_ = NULL; } }praat-6.0.04/external/portaudio/pa_win_ds_dynlink.h000066400000000000000000000071651261542461700224250ustar00rootroot00000000000000/* * Interface for dynamically loading directsound and providing a dummy * implementation if it isn't present. * * Author: Ross Bencina (some portions Phil Burk & Robert Marsanyi) * * For PortAudio Portable Real-Time Audio Library * For more information see: http://www.portaudio.com * Copyright (c) 1999-2006 Phil Burk, Robert Marsanyi and Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostapi_src */ #ifndef INCLUDED_PA_DSOUND_DYNLINK_H #define INCLUDED_PA_DSOUND_DYNLINK_H /* on Borland compilers, WIN32 doesn't seem to be defined by default, which breaks dsound.h. Adding the define here fixes the problem. - rossb. */ #ifdef __BORLANDC__ #if !defined(WIN32) #define WIN32 #endif #endif /* Use the earliest version of DX required, no need to polute the namespace */ #ifdef PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE #define DIRECTSOUND_VERSION 0x0800 #else #define DIRECTSOUND_VERSION 0x0300 #endif #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ typedef struct { HINSTANCE hInstance_; HRESULT (WINAPI *DllGetClassObject)(REFCLSID , REFIID , LPVOID *); HRESULT (WINAPI *DirectSoundCreate)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN); HRESULT (WINAPI *DirectSoundEnumerateW)(LPDSENUMCALLBACKW, LPVOID); HRESULT (WINAPI *DirectSoundEnumerateA)(LPDSENUMCALLBACKA, LPVOID); HRESULT (WINAPI *DirectSoundCaptureCreate)(LPGUID, LPDIRECTSOUNDCAPTURE *, LPUNKNOWN); HRESULT (WINAPI *DirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW, LPVOID); HRESULT (WINAPI *DirectSoundCaptureEnumerateA)(LPDSENUMCALLBACKA, LPVOID); #ifdef PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE HRESULT (WINAPI *DirectSoundFullDuplexCreate8)( LPCGUID, LPCGUID, LPCDSCBUFFERDESC, LPCDSBUFFERDESC, HWND, DWORD, LPDIRECTSOUNDFULLDUPLEX *, LPDIRECTSOUNDCAPTUREBUFFER8 *, LPDIRECTSOUNDBUFFER8 *, LPUNKNOWN ); #endif }PaWinDsDSoundEntryPoints; extern PaWinDsDSoundEntryPoints paWinDsDSoundEntryPoints; void PaWinDs_InitializeDSoundEntryPoints(void); void PaWinDs_TerminateDSoundEntryPoints(void); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* INCLUDED_PA_DSOUND_DYNLINK_H */ praat-6.0.04/external/portaudio/pa_win_hostapis.c000066400000000000000000000060531261542461700221070ustar00rootroot00000000000000#ifdef _WIN32 /* * $Id: pa_win_hostapis.c 1728 2011-08-18 03:31:51Z rossb $ * Portable Audio I/O Library Windows initialization table * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2008 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup win_src @brief Win32 host API initialization function table. */ /* This is needed to make this source file depend on CMake option changes and at the same time make it transparent for clients not using CMake. */ #ifdef PORTAUDIO_CMAKE_GENERATED #include "options_cmake.h" #endif #include "pa_hostapi.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaWinWdm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); #ifdef __cplusplus } #endif /* __cplusplus */ PaUtilHostApiInitializer *paHostApiInitializers[] = { PaWinMme_Initialize, // 0 ppgb //PaWinDs_Initialize, // 1 ppgb //PaWinWdm_Initialize, // 2 ppgb //PaAsio_Initialize, //PaWinWasapi_Initialize, 0 /* NULL terminated array */ }; int paDefaultHostApiIndex = 0; // ppgb #endif praat-6.0.04/external/portaudio/pa_win_util.c000066400000000000000000000100171261542461700212250ustar00rootroot00000000000000#ifdef _WIN32 /* * $Id: pa_win_util.c 1584 2011-02-02 18:58:17Z rossb $ * Portable Audio I/O Library * Win32 platform-specific support functions * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2008 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup win_src @brief Win32 implementation of platform-specific PaUtil support functions. */ #include #include /* for timeGetTime() */ #include "pa_util.h" #if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) && !defined(_WIN32_WCE) /* MSC version 6 and above */ #pragma comment( lib, "winmm.lib" ) #endif /* Track memory allocations to avoid leaks. */ #if PA_TRACK_MEMORY static int numAllocations_ = 0; #endif void *PaUtil_AllocateMemory( long size ) { void *result = GlobalAlloc( GPTR, size ); #if PA_TRACK_MEMORY if( result != NULL ) numAllocations_ += 1; #endif return result; } void PaUtil_FreeMemory( void *block ) { if( block != NULL ) { GlobalFree( block ); #if PA_TRACK_MEMORY numAllocations_ -= 1; #endif } } int PaUtil_CountCurrentlyAllocatedBlocks( void ) { #if PA_TRACK_MEMORY return numAllocations_; #else return 0; #endif } void Pa_Sleep( long msec ) { Sleep( msec ); } static int usePerformanceCounter_; static double secondsPerTick_; void PaUtil_InitializeClock( void ) { LARGE_INTEGER ticksPerSecond; if( QueryPerformanceFrequency( &ticksPerSecond ) != 0 ) { usePerformanceCounter_ = 1; secondsPerTick_ = 1.0 / (double)ticksPerSecond.QuadPart; } else { usePerformanceCounter_ = 0; } } double PaUtil_GetTime( void ) { LARGE_INTEGER time; if( usePerformanceCounter_ ) { /* Note: QueryPerformanceCounter has a known issue where it can skip forward by a few seconds (!) due to a hardware bug on some PCI-ISA bridge hardware. This is documented here: http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q274323& The work-arounds are not very paletable and involve querying GetTickCount at every time step. Using rdtsc is not a good option on multi-core systems. For now we just use QueryPerformanceCounter(). It's good, most of the time. */ QueryPerformanceCounter( &time ); return time.QuadPart * secondsPerTick_; } else { #ifndef UNDER_CE return timeGetTime() * .001; #else return GetTickCount() * .001; #endif } } #endif praat-6.0.04/external/portaudio/pa_win_wasapi.h000066400000000000000000000347771261542461700215640ustar00rootroot00000000000000#ifndef PA_WIN_WASAPI_H #define PA_WIN_WASAPI_H /* * $Id: $ * PortAudio Portable Real-Time Audio Library * DirectSound specific extensions * * Copyright (c) 1999-2007 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup public_header @brief WASAPI-specific PortAudio API extension header file. */ #include "portaudio.h" #include "pa_win_waveformat.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* Setup flags */ typedef enum PaWasapiFlags { /* puts WASAPI into exclusive mode */ paWinWasapiExclusive = (1 << 0), /* allows to skip internal PA processing completely */ paWinWasapiRedirectHostProcessor = (1 << 1), /* assigns custom channel mask */ paWinWasapiUseChannelMask = (1 << 2), /* selects non-Event driven method of data read/write Note: WASAPI Event driven core is capable of 2ms latency!!!, but Polling method can only provide 15-20ms latency. */ paWinWasapiPolling = (1 << 3), /* forces custom thread priority setting. must be used if PaWasapiStreamInfo::threadPriority is set to custom value. */ paWinWasapiThreadPriority = (1 << 4) } PaWasapiFlags; #define paWinWasapiExclusive (paWinWasapiExclusive) #define paWinWasapiRedirectHostProcessor (paWinWasapiRedirectHostProcessor) #define paWinWasapiUseChannelMask (paWinWasapiUseChannelMask) #define paWinWasapiPolling (paWinWasapiPolling) #define paWinWasapiThreadPriority (paWinWasapiThreadPriority) /* Host processor. Allows to skip internal PA processing completely. You must set paWinWasapiRedirectHostProcessor flag to PaWasapiStreamInfo::flags member in order to have host processor redirected to your callback. Use with caution! inputFrames and outputFrames depend solely on final device setup. To query maximal values of inputFrames/outputFrames use PaWasapi_GetFramesPerHostBuffer. */ typedef void (*PaWasapiHostProcessorCallback) (void *inputBuffer, long inputFrames, void *outputBuffer, long outputFrames, void *userData); /* Device role */ typedef enum PaWasapiDeviceRole { eRoleRemoteNetworkDevice = 0, eRoleSpeakers, eRoleLineLevel, eRoleHeadphones, eRoleMicrophone, eRoleHeadset, eRoleHandset, eRoleUnknownDigitalPassthrough, eRoleSPDIF, eRoleHDMI, eRoleUnknownFormFactor } PaWasapiDeviceRole; /* Jack connection type */ typedef enum PaWasapiJackConnectionType { eJackConnTypeUnknown, eJackConnType3Point5mm, eJackConnTypeQuarter, eJackConnTypeAtapiInternal, eJackConnTypeRCA, eJackConnTypeOptical, eJackConnTypeOtherDigital, eJackConnTypeOtherAnalog, eJackConnTypeMultichannelAnalogDIN, eJackConnTypeXlrProfessional, eJackConnTypeRJ11Modem, eJackConnTypeCombination } PaWasapiJackConnectionType; /* Jack geometric location */ typedef enum PaWasapiJackGeoLocation { eJackGeoLocUnk = 0, eJackGeoLocRear = 0x1, /* matches EPcxGeoLocation::eGeoLocRear */ eJackGeoLocFront, eJackGeoLocLeft, eJackGeoLocRight, eJackGeoLocTop, eJackGeoLocBottom, eJackGeoLocRearPanel, eJackGeoLocRiser, eJackGeoLocInsideMobileLid, eJackGeoLocDrivebay, eJackGeoLocHDMI, eJackGeoLocOutsideMobileLid, eJackGeoLocATAPI, eJackGeoLocReserved5, eJackGeoLocReserved6, } PaWasapiJackGeoLocation; /* Jack general location */ typedef enum PaWasapiJackGenLocation { eJackGenLocPrimaryBox = 0, eJackGenLocInternal, eJackGenLocSeparate, eJackGenLocOther } PaWasapiJackGenLocation; /* Jack's type of port */ typedef enum PaWasapiJackPortConnection { eJackPortConnJack = 0, eJackPortConnIntegratedDevice, eJackPortConnBothIntegratedAndJack, eJackPortConnUnknown } PaWasapiJackPortConnection; /* Thread priority */ typedef enum PaWasapiThreadPriority { eThreadPriorityNone = 0, eThreadPriorityAudio, //!< Default for Shared mode. eThreadPriorityCapture, eThreadPriorityDistribution, eThreadPriorityGames, eThreadPriorityPlayback, eThreadPriorityProAudio, //!< Default for Exclusive mode. eThreadPriorityWindowManager } PaWasapiThreadPriority; /* Stream descriptor. */ typedef struct PaWasapiJackDescription { unsigned long channelMapping; unsigned long color; /* derived from macro: #define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16))) */ PaWasapiJackConnectionType connectionType; PaWasapiJackGeoLocation geoLocation; PaWasapiJackGenLocation genLocation; PaWasapiJackPortConnection portConnection; unsigned int isConnected; } PaWasapiJackDescription; /* Stream descriptor. */ typedef struct PaWasapiStreamInfo { unsigned long size; /**< sizeof(PaWasapiStreamInfo) */ PaHostApiTypeId hostApiType; /**< paWASAPI */ unsigned long version; /**< 1 */ unsigned long flags; /**< collection of PaWasapiFlags */ /* Support for WAVEFORMATEXTENSIBLE channel masks. If flags contains paWinWasapiUseChannelMask this allows you to specify which speakers to address in a multichannel stream. Constants for channelMask are specified in pa_win_waveformat.h. Will be used only if paWinWasapiUseChannelMask flag is specified. */ PaWinWaveFormatChannelMask channelMask; /* Delivers raw data to callback obtained from GetBuffer() methods skipping internal PortAudio processing inventory completely. userData parameter will be the same that was passed to Pa_OpenStream method. Will be used only if paWinWasapiRedirectHostProcessor flag is specified. */ PaWasapiHostProcessorCallback hostProcessorOutput; PaWasapiHostProcessorCallback hostProcessorInput; /* Specifies thread priority explicitly. Will be used only if paWinWasapiThreadPriority flag is specified. Please note, if Input/Output streams are opened simultaniously (Full-Duplex mode) you shall specify same value for threadPriority or othervise one of the values will be used to setup thread priority. */ PaWasapiThreadPriority threadPriority; } PaWasapiStreamInfo; /** Returns default sound format for device. Format is represented by PaWinWaveFormat or WAVEFORMATEXTENSIBLE structure. @param pFormat Pointer to PaWinWaveFormat or WAVEFORMATEXTENSIBLE structure. @param nFormatSize Size of PaWinWaveFormat or WAVEFORMATEXTENSIBLE structure in bytes. @param nDevice Device index. @return Non-negative value indicating the number of bytes copied into format decriptor or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. */ int PaWasapi_GetDeviceDefaultFormat( void *pFormat, unsigned int nFormatSize, PaDeviceIndex nDevice ); /** Returns device role (PaWasapiDeviceRole enum). @param nDevice device index. @return Non-negative value indicating device role or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. */ int/*PaWasapiDeviceRole*/ PaWasapi_GetDeviceRole( PaDeviceIndex nDevice ); /** Boost thread priority of calling thread (MMCSS). Use it for Blocking Interface only for thread which makes calls to Pa_WriteStream/Pa_ReadStream. @param hTask Handle to pointer to priority task. Must be used with PaWasapi_RevertThreadPriority method to revert thread priority to initial state. @param nPriorityClass Id of thread priority of PaWasapiThreadPriority type. Specifying eThreadPriorityNone does nothing. @return Error code indicating success or failure. @see PaWasapi_RevertThreadPriority */ PaError PaWasapi_ThreadPriorityBoost( void **hTask, PaWasapiThreadPriority nPriorityClass ); /** Boost thread priority of calling thread (MMCSS). Use it for Blocking Interface only for thread which makes calls to Pa_WriteStream/Pa_ReadStream. @param hTask Task handle obtained by PaWasapi_BoostThreadPriority method. @return Error code indicating success or failure. @see PaWasapi_BoostThreadPriority */ PaError PaWasapi_ThreadPriorityRevert( void *hTask ); /** Get number of frames per host buffer. This is maximal value of frames of WASAPI buffer which can be locked for operations. Use this method as helper to findout maximal values of inputFrames/outputFrames of PaWasapiHostProcessorCallback. @param pStream Pointer to PaStream to query. @param nInput Pointer to variable to receive number of input frames. Can be NULL. @param nOutput Pointer to variable to receive number of output frames. Can be NULL. @return Error code indicating success or failure. @see PaWasapiHostProcessorCallback */ PaError PaWasapi_GetFramesPerHostBuffer( PaStream *pStream, unsigned int *nInput, unsigned int *nOutput ); /** Get number of jacks associated with a WASAPI device. Use this method to determine if there are any jacks associated with the provided WASAPI device. Not all audio devices will support this capability. This is valid for both input and output devices. @param nDevice device index. @param jcount Number of jacks is returned in this variable @return Error code indicating success or failure @see PaWasapi_GetJackDescription */ PaError PaWasapi_GetJackCount(PaDeviceIndex nDevice, int *jcount); /** Get the jack description associated with a WASAPI device and jack number Before this function is called, use PaWasapi_GetJackCount to determine the number of jacks associated with device. If jcount is greater than zero, then each jack from 0 to jcount can be queried with this function to get the jack description. @param nDevice device index. @param jindex Which jack to return information @param KSJACK_DESCRIPTION This structure filled in on success. @return Error code indicating success or failure @see PaWasapi_GetJackCount */ PaError PaWasapi_GetJackDescription(PaDeviceIndex nDevice, int jindex, PaWasapiJackDescription *pJackDescription); /* IMPORTANT: WASAPI is implemented for Callback and Blocking interfaces. It supports Shared and Exclusive share modes. Exclusive Mode: Exclusive mode allows to deliver audio data directly to hardware bypassing software mixing. Exclusive mode is specified by 'paWinWasapiExclusive' flag. Callback Interface: Provides best audio quality with low latency. Callback interface is implemented in two versions: 1) Event-Driven: This is the most powerful WASAPI implementation which provides glitch-free audio at around 3ms latency in Exclusive mode. Lowest possible latency for this mode is 3 ms for HD Audio class audio chips. For the Shared mode latency can not be lower than 20 ms. 2) Poll-Driven: Polling is another 2-nd method to operate with WASAPI. It is less efficient than Event-Driven and provides latency at around 10-13ms. Polling must be used to overcome a system bug under Windows Vista x64 when application is WOW64(32-bit) and Event-Driven method simply times out (event handle is never signalled on buffer completion). Please note, such WOW64 bug does not exist in Vista x86 or Windows 7. Polling can be setup by speciying 'paWinWasapiPolling' flag. Our WASAPI implementation detects WOW64 bug and sets 'paWinWasapiPolling' automatically. Thread priority: Normally thread priority is set automatically and does not require modification. Although if user wants some tweaking thread priority can be modified by setting 'paWinWasapiThreadPriority' flag and specifying 'PaWasapiStreamInfo::threadPriority' with value from PaWasapiThreadPriority enum. Blocking Interface: Blocking interface is implemented but due to above described Poll-Driven method can not deliver lowest possible latency. Specifying too low latency in Shared mode will result in distorted audio although Exclusive mode adds stability. Pa_IsFormatSupported: To check format with correct Share Mode (Exclusive/Shared) you must supply PaWasapiStreamInfo with flags paWinWasapiExclusive set through member of PaStreamParameters::hostApiSpecificStreamInfo structure. Pa_OpenStream: To set desired Share Mode (Exclusive/Shared) you must supply PaWasapiStreamInfo with flags paWinWasapiExclusive set through member of PaStreamParameters::hostApiSpecificStreamInfo structure. */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_WIN_WASAPI_H */ praat-6.0.04/external/portaudio/pa_win_waveformat.c000066400000000000000000000144571261542461700224370ustar00rootroot00000000000000#ifdef _WIN32 /* * PortAudio Portable Real-Time Audio Library * Windows WAVEFORMAT* data structure utilities * portaudio.h should be included before this file. * * Copyright (c) 2007 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ #include #include #include "portaudio.h" #include "pa_win_waveformat.h" #if !defined(WAVE_FORMAT_EXTENSIBLE) #define WAVE_FORMAT_EXTENSIBLE 0xFFFE #endif static GUID pawin_ksDataFormatSubtypeGuidBase = { (USHORT)(WAVE_FORMAT_PCM), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }; int PaWin_SampleFormatToLinearWaveFormatTag( PaSampleFormat sampleFormat ) { if( sampleFormat == paFloat32 ) return PAWIN_WAVE_FORMAT_IEEE_FLOAT; return PAWIN_WAVE_FORMAT_PCM; } void PaWin_InitializeWaveFormatEx( PaWinWaveFormat *waveFormat, int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate ) { WAVEFORMATEX *waveFormatEx = (WAVEFORMATEX*)waveFormat; int bytesPerSample = Pa_GetSampleSize(sampleFormat); unsigned long bytesPerFrame = numChannels * bytesPerSample; waveFormatEx->wFormatTag = waveFormatTag; waveFormatEx->nChannels = (WORD)numChannels; waveFormatEx->nSamplesPerSec = (DWORD)sampleRate; waveFormatEx->nAvgBytesPerSec = waveFormatEx->nSamplesPerSec * bytesPerFrame; waveFormatEx->nBlockAlign = (WORD)bytesPerFrame; waveFormatEx->wBitsPerSample = bytesPerSample * 8; waveFormatEx->cbSize = 0; } void PaWin_InitializeWaveFormatExtensible( PaWinWaveFormat *waveFormat, int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate, PaWinWaveFormatChannelMask channelMask ) { WAVEFORMATEX *waveFormatEx = (WAVEFORMATEX*)waveFormat; int bytesPerSample = Pa_GetSampleSize(sampleFormat); unsigned long bytesPerFrame = numChannels * bytesPerSample; GUID guid; waveFormatEx->wFormatTag = WAVE_FORMAT_EXTENSIBLE; waveFormatEx->nChannels = (WORD)numChannels; waveFormatEx->nSamplesPerSec = (DWORD)sampleRate; waveFormatEx->nAvgBytesPerSec = waveFormatEx->nSamplesPerSec * bytesPerFrame; waveFormatEx->nBlockAlign = (WORD)bytesPerFrame; waveFormatEx->wBitsPerSample = bytesPerSample * 8; waveFormatEx->cbSize = 22; *((WORD*)&waveFormat->fields[PAWIN_INDEXOF_WVALIDBITSPERSAMPLE]) = waveFormatEx->wBitsPerSample; *((DWORD*)&waveFormat->fields[PAWIN_INDEXOF_DWCHANNELMASK]) = channelMask; guid = pawin_ksDataFormatSubtypeGuidBase; guid.Data1 = (USHORT)waveFormatTag; *((GUID*)&waveFormat->fields[PAWIN_INDEXOF_SUBFORMAT]) = guid; } PaWinWaveFormatChannelMask PaWin_DefaultChannelMask( int numChannels ) { switch( numChannels ){ case 1: return PAWIN_SPEAKER_MONO; case 2: return PAWIN_SPEAKER_STEREO; case 3: return PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_FRONT_RIGHT; case 4: return PAWIN_SPEAKER_QUAD; case 5: return PAWIN_SPEAKER_QUAD | PAWIN_SPEAKER_FRONT_CENTER; case 6: /* The meaning of the PAWIN_SPEAKER_5POINT1 flag has changed over time: http://msdn2.microsoft.com/en-us/library/aa474707.aspx We use PAWIN_SPEAKER_5POINT1 (not PAWIN_SPEAKER_5POINT1_SURROUND) because on some cards (eg Audigy) PAWIN_SPEAKER_5POINT1_SURROUND results in a virtual mixdown placing the rear output in the front _and_ rear speakers. */ return PAWIN_SPEAKER_5POINT1; /* case 7: */ case 8: /* RoBi: PAWIN_SPEAKER_7POINT1_SURROUND fits normal surround sound setups better than PAWIN_SPEAKER_7POINT1, f.i. NVidia HDMI Audio output is silent on channels 5&6 with NVidia drivers, and channel 7&8 with Micrsoft HD Audio driver using PAWIN_SPEAKER_7POINT1. With PAWIN_SPEAKER_7POINT1_SURROUND both setups work OK. */ return PAWIN_SPEAKER_7POINT1_SURROUND; } /* Apparently some Audigy drivers will output silence if the direct-out constant (0) is used. So this is not ideal. RoBi 2012-12-19: Also, NVidia driver seem to output garbage instead. Again not very ideal. */ return PAWIN_SPEAKER_DIRECTOUT; /* Note that Alec Rogers proposed the following as an alternate method to generate the default channel mask, however it doesn't seem to be an improvement over the above, since some drivers will matrix outputs mapping to non-present speakers accross multiple physical speakers. if(nChannels==1) { pwfFormat->dwChannelMask = SPEAKER_FRONT_CENTER; } else { pwfFormat->dwChannelMask = 0; for(i=0; idwChannelMask = (pwfFormat->dwChannelMask << 1) | 0x1; } */ } #endif praat-6.0.04/external/portaudio/pa_win_waveformat.h000066400000000000000000000215141261542461700224340ustar00rootroot00000000000000#ifndef PA_WIN_WAVEFORMAT_H #define PA_WIN_WAVEFORMAT_H /* * PortAudio Portable Real-Time Audio Library * Windows WAVEFORMAT* data structure utilities * portaudio.h should be included before this file. * * Copyright (c) 2007 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup public_header @brief Windows specific PortAudio API extension and utilities header file. */ #ifdef __cplusplus extern "C" { #endif /* The following #defines for speaker channel masks are the same as those in ksmedia.h, except with PAWIN_ prepended, KSAUDIO_ removed in some cases, and casts to PaWinWaveFormatChannelMask added. */ typedef unsigned long PaWinWaveFormatChannelMask; /* Speaker Positions: */ #define PAWIN_SPEAKER_FRONT_LEFT ((PaWinWaveFormatChannelMask)0x1) #define PAWIN_SPEAKER_FRONT_RIGHT ((PaWinWaveFormatChannelMask)0x2) #define PAWIN_SPEAKER_FRONT_CENTER ((PaWinWaveFormatChannelMask)0x4) #define PAWIN_SPEAKER_LOW_FREQUENCY ((PaWinWaveFormatChannelMask)0x8) #define PAWIN_SPEAKER_BACK_LEFT ((PaWinWaveFormatChannelMask)0x10) #define PAWIN_SPEAKER_BACK_RIGHT ((PaWinWaveFormatChannelMask)0x20) #define PAWIN_SPEAKER_FRONT_LEFT_OF_CENTER ((PaWinWaveFormatChannelMask)0x40) #define PAWIN_SPEAKER_FRONT_RIGHT_OF_CENTER ((PaWinWaveFormatChannelMask)0x80) #define PAWIN_SPEAKER_BACK_CENTER ((PaWinWaveFormatChannelMask)0x100) #define PAWIN_SPEAKER_SIDE_LEFT ((PaWinWaveFormatChannelMask)0x200) #define PAWIN_SPEAKER_SIDE_RIGHT ((PaWinWaveFormatChannelMask)0x400) #define PAWIN_SPEAKER_TOP_CENTER ((PaWinWaveFormatChannelMask)0x800) #define PAWIN_SPEAKER_TOP_FRONT_LEFT ((PaWinWaveFormatChannelMask)0x1000) #define PAWIN_SPEAKER_TOP_FRONT_CENTER ((PaWinWaveFormatChannelMask)0x2000) #define PAWIN_SPEAKER_TOP_FRONT_RIGHT ((PaWinWaveFormatChannelMask)0x4000) #define PAWIN_SPEAKER_TOP_BACK_LEFT ((PaWinWaveFormatChannelMask)0x8000) #define PAWIN_SPEAKER_TOP_BACK_CENTER ((PaWinWaveFormatChannelMask)0x10000) #define PAWIN_SPEAKER_TOP_BACK_RIGHT ((PaWinWaveFormatChannelMask)0x20000) /* Bit mask locations reserved for future use */ #define PAWIN_SPEAKER_RESERVED ((PaWinWaveFormatChannelMask)0x7FFC0000) /* Used to specify that any possible permutation of speaker configurations */ #define PAWIN_SPEAKER_ALL ((PaWinWaveFormatChannelMask)0x80000000) /* DirectSound Speaker Config */ #define PAWIN_SPEAKER_DIRECTOUT 0 #define PAWIN_SPEAKER_MONO (PAWIN_SPEAKER_FRONT_CENTER) #define PAWIN_SPEAKER_STEREO (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT) #define PAWIN_SPEAKER_QUAD (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \ PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT) #define PAWIN_SPEAKER_SURROUND (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \ PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_BACK_CENTER) #define PAWIN_SPEAKER_5POINT1 (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \ PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \ PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT) #define PAWIN_SPEAKER_7POINT1 (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \ PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \ PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT | \ PAWIN_SPEAKER_FRONT_LEFT_OF_CENTER | PAWIN_SPEAKER_FRONT_RIGHT_OF_CENTER) #define PAWIN_SPEAKER_5POINT1_SURROUND (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \ PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \ PAWIN_SPEAKER_SIDE_LEFT | PAWIN_SPEAKER_SIDE_RIGHT) #define PAWIN_SPEAKER_7POINT1_SURROUND (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \ PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \ PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT | \ PAWIN_SPEAKER_SIDE_LEFT | PAWIN_SPEAKER_SIDE_RIGHT) /* According to the Microsoft documentation: The following are obsolete 5.1 and 7.1 settings (they lack side speakers). Note this means that the default 5.1 and 7.1 settings (KSAUDIO_SPEAKER_5POINT1 and KSAUDIO_SPEAKER_7POINT1 are similarly obsolete but are unchanged for compatibility reasons). */ #define PAWIN_SPEAKER_5POINT1_BACK PAWIN_SPEAKER_5POINT1 #define PAWIN_SPEAKER_7POINT1_WIDE PAWIN_SPEAKER_7POINT1 /* DVD Speaker Positions */ #define PAWIN_SPEAKER_GROUND_FRONT_LEFT PAWIN_SPEAKER_FRONT_LEFT #define PAWIN_SPEAKER_GROUND_FRONT_CENTER PAWIN_SPEAKER_FRONT_CENTER #define PAWIN_SPEAKER_GROUND_FRONT_RIGHT PAWIN_SPEAKER_FRONT_RIGHT #define PAWIN_SPEAKER_GROUND_REAR_LEFT PAWIN_SPEAKER_BACK_LEFT #define PAWIN_SPEAKER_GROUND_REAR_RIGHT PAWIN_SPEAKER_BACK_RIGHT #define PAWIN_SPEAKER_TOP_MIDDLE PAWIN_SPEAKER_TOP_CENTER #define PAWIN_SPEAKER_SUPER_WOOFER PAWIN_SPEAKER_LOW_FREQUENCY /* PaWinWaveFormat is defined here to provide compatibility with compilation environments which don't have headers defining WAVEFORMATEXTENSIBLE (e.g. older versions of MSVC, Borland C++ etc. The fields for WAVEFORMATEX and WAVEFORMATEXTENSIBLE are declared as an unsigned char array here to avoid clients who include this file having a dependency on windows.h and mmsystem.h, and also to to avoid having to write separate packing pragmas for each compiler. */ #define PAWIN_SIZEOF_WAVEFORMATEX 18 #define PAWIN_SIZEOF_WAVEFORMATEXTENSIBLE (PAWIN_SIZEOF_WAVEFORMATEX + 22) typedef struct{ unsigned char fields[ PAWIN_SIZEOF_WAVEFORMATEXTENSIBLE ]; unsigned long extraLongForAlignment; /* ensure that compiler aligns struct to DWORD */ } PaWinWaveFormat; /* WAVEFORMATEXTENSIBLE fields: union { WORD wValidBitsPerSample; WORD wSamplesPerBlock; WORD wReserved; } Samples; DWORD dwChannelMask; GUID SubFormat; */ #define PAWIN_INDEXOF_WVALIDBITSPERSAMPLE (PAWIN_SIZEOF_WAVEFORMATEX+0) #define PAWIN_INDEXOF_DWCHANNELMASK (PAWIN_SIZEOF_WAVEFORMATEX+2) #define PAWIN_INDEXOF_SUBFORMAT (PAWIN_SIZEOF_WAVEFORMATEX+6) /* Valid values to pass for the waveFormatTag PaWin_InitializeWaveFormatEx and PaWin_InitializeWaveFormatExtensible functions below. These must match the standard Windows WAVE_FORMAT_* values. */ #define PAWIN_WAVE_FORMAT_PCM (1) #define PAWIN_WAVE_FORMAT_IEEE_FLOAT (3) #define PAWIN_WAVE_FORMAT_DOLBY_AC3_SPDIF (0x0092) #define PAWIN_WAVE_FORMAT_WMA_SPDIF (0x0164) /* returns PAWIN_WAVE_FORMAT_PCM or PAWIN_WAVE_FORMAT_IEEE_FLOAT depending on the sampleFormat parameter. */ int PaWin_SampleFormatToLinearWaveFormatTag( PaSampleFormat sampleFormat ); /* Use the following two functions to initialize the waveformat structure. */ void PaWin_InitializeWaveFormatEx( PaWinWaveFormat *waveFormat, int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate ); void PaWin_InitializeWaveFormatExtensible( PaWinWaveFormat *waveFormat, int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate, PaWinWaveFormatChannelMask channelMask ); /* Map a channel count to a speaker channel mask */ PaWinWaveFormatChannelMask PaWin_DefaultChannelMask( int numChannels ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_WIN_WAVEFORMAT_H */praat-6.0.04/external/portaudio/pa_win_wdmks.c000066400000000000000000007121761261542461700214140ustar00rootroot00000000000000/* * $Id: pa_win_wdmks.c 1885 2012-12-28 16:54:25Z robiwan $ * PortAudio Windows WDM-KS interface * * Author: Andrew Baldwin, Robert Bielik (WaveRT) * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2004 Andrew Baldwin, Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostapi_src @brief Portaudio WDM-KS host API. @note This is the implementation of the Portaudio host API using the Windows WDM/Kernel Streaming API in order to enable very low latency playback and recording on all modern Windows platforms (e.g. 2K, XP, Vista, Win7) Note: This API accesses the device drivers below the usual KMIXER component which is normally used to enable multi-client mixing and format conversion. That means that it will lock out all other users of a device for the duration of active stream using those devices */ #include #if (defined(_WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */ #pragma comment( lib, "setupapi.lib" ) #endif /* Debugging/tracing support */ #define PA_LOGE_ #define PA_LOGL_ #ifdef __GNUC__ #include #define _WIN32_WINNT 0x0501 #define WINVER 0x0501 #endif #include /* strlen() */ #include #include /* iswspace() */ #include "pa_util.h" #include "pa_allocation.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_cpuload.h" #include "pa_process.h" #include "portaudio.h" #include "pa_debugprint.h" #include "pa_memorybarrier.h" #include "pa_ringbuffer.h" #include "pa_trace.h" #include "pa_win_waveformat.h" #include "pa_win_wdmks.h" #include #include #include #include #ifdef _MSC_VER #define snprintf _snprintf #define vsnprintf _vsnprintf #endif /* The PA_HP_TRACE macro is used in RT parts, so it can be switched off without affecting the rest of the debug tracing */ #if 1 #define PA_HP_TRACE(x) PaUtil_AddHighSpeedLogMessage x ; #else #define PA_HP_TRACE(x) #endif /* A define that selects whether the resulting pin names are chosen from pin category instead of the available pin names, who sometimes can be quite cheesy, like "Volume control". Default is to use the pin category. */ #ifndef PA_WDMKS_USE_CATEGORY_FOR_PIN_NAMES #define PA_WDMKS_USE_CATEGORY_FOR_PIN_NAMES 1 #endif #ifdef __GNUC__ #undef PA_LOGE_ #define PA_LOGE_ PA_DEBUG(("%s {\n",__FUNCTION__)) #undef PA_LOGL_ #define PA_LOGL_ PA_DEBUG(("} %s\n",__FUNCTION__)) /* These defines are set in order to allow the WIndows DirectX * headers to compile with a GCC compiler such as MinGW * NOTE: The headers may generate a few warning in GCC, but * they should compile */ #define _INC_MMSYSTEM #define _INC_MMREG #define _NTRTL_ /* Turn off default definition of DEFINE_GUIDEX */ #define DEFINE_GUID_THUNK(name,guid) DEFINE_GUID(name,guid) #define DEFINE_GUIDEX(n) DEFINE_GUID_THUNK( n, STATIC_##n ) #if !defined( DEFINE_WAVEFORMATEX_GUID ) #define DEFINE_WAVEFORMATEX_GUID(x) (USHORT)(x), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 #endif #define WAVE_FORMAT_ADPCM 0x0002 #define WAVE_FORMAT_IEEE_FLOAT 0x0003 #define WAVE_FORMAT_ALAW 0x0006 #define WAVE_FORMAT_MULAW 0x0007 #define WAVE_FORMAT_MPEG 0x0050 #define WAVE_FORMAT_DRM 0x0009 #define DYNAMIC_GUID_THUNK(l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} #define DYNAMIC_GUID(data) DYNAMIC_GUID_THUNK(data) #endif /* use CreateThread for CYGWIN/Windows Mobile, _beginthreadex for all others */ #if !defined(__CYGWIN__) && !defined(_WIN32_WCE) #define CREATE_THREAD_FUNCTION (HANDLE)_beginthreadex #define PA_THREAD_FUNC static unsigned WINAPI #else #define CREATE_THREAD_FUNCTION CreateThread #define PA_THREAD_FUNC static DWORD WINAPI #endif #ifdef _MSC_VER #define NOMMIDS #define DYNAMIC_GUID(data) {data} #define _NTRTL_ /* Turn off default definition of DEFINE_GUIDEX */ #undef DEFINE_GUID #define DEFINE_GUID(n,data) EXTERN_C const GUID n = {data} #define DEFINE_GUID_THUNK(n,data) DEFINE_GUID(n,data) #define DEFINE_GUIDEX(n) DEFINE_GUID_THUNK(n, STATIC_##n) #endif #include #ifndef EXTERN_C #define EXTERN_C extern #endif #if defined(__GNUC__) /* For MinGW we reference mingw-include files supplied with WASAPI */ #define WINBOOL BOOL #include "../wasapi/mingw-include/ks.h" #include "../wasapi/mingw-include/ksmedia.h" #else #include #include /* Note that Windows SDK V6.0A or later is needed for WaveRT specific structs to be present in ksmedia.h. Also make sure that the SDK include path is before other include paths (that may contain an "old" ksmedia.h), so the proper ksmedia.h is used */ #include #endif #include #include /* These next definitions allow the use of the KSUSER DLL */ typedef /*KSDDKAPI*/ DWORD WINAPI KSCREATEPIN(HANDLE, PKSPIN_CONNECT, ACCESS_MASK, PHANDLE); extern HMODULE DllKsUser; extern KSCREATEPIN* FunctionKsCreatePin; /* These definitions allows the use of AVRT.DLL on Vista and later OSs */ typedef enum _PA_AVRT_PRIORITY { PA_AVRT_PRIORITY_LOW = -1, PA_AVRT_PRIORITY_NORMAL, PA_AVRT_PRIORITY_HIGH, PA_AVRT_PRIORITY_CRITICAL } PA_AVRT_PRIORITY, *PPA_AVRT_PRIORITY; typedef struct { HINSTANCE hInstance; HANDLE (WINAPI *AvSetMmThreadCharacteristics) (LPCSTR, LPDWORD); BOOL (WINAPI *AvRevertMmThreadCharacteristics) (HANDLE); BOOL (WINAPI *AvSetMmThreadPriority) (HANDLE, PA_AVRT_PRIORITY); } PaWinWDMKSAvRtEntryPoints; static PaWinWDMKSAvRtEntryPoints paWinWDMKSAvRtEntryPoints = {0}; /* An unspecified channel count (-1) is not treated correctly, so we replace it with * an arbitrarily large number */ #define MAXIMUM_NUMBER_OF_CHANNELS 256 /* Forward definition to break circular type reference between pin and filter */ struct __PaWinWdmFilter; typedef struct __PaWinWdmFilter PaWinWdmFilter; struct __PaWinWdmPin; typedef struct __PaWinWdmPin PaWinWdmPin; struct __PaWinWdmStream; typedef struct __PaWinWdmStream PaWinWdmStream; /* Function prototype for getting audio position */ typedef PaError (*FunctionGetPinAudioPosition)(PaWinWdmPin*, unsigned long*); /* Function prototype for memory barrier */ typedef void (*FunctionMemoryBarrier)(void); struct __PaProcessThreadInfo; typedef struct __PaProcessThreadInfo PaProcessThreadInfo; typedef PaError (*FunctionPinHandler)(PaProcessThreadInfo* pInfo, unsigned eventIndex); typedef enum __PaStreamStartEnum { StreamStart_kOk, StreamStart_kFailed, StreamStart_kCnt } PaStreamStartEnum; /* Multiplexed input structure. * Very often several physical inputs are multiplexed through a MUX node (represented in the topology filter) */ typedef struct __PaWinWdmMuxedInput { wchar_t friendlyName[MAX_PATH]; ULONG muxPinId; ULONG muxNodeId; ULONG endpointPinId; } PaWinWdmMuxedInput; /* The Pin structure * A pin is an input or output node, e.g. for audio flow */ struct __PaWinWdmPin { HANDLE handle; PaWinWdmMuxedInput** inputs; unsigned inputCount; wchar_t friendlyName[MAX_PATH]; PaWinWdmFilter* parentFilter; PaWDMKSSubType pinKsSubType; unsigned long pinId; unsigned long endpointPinId; /* For output pins */ KSPIN_CONNECT* pinConnect; unsigned long pinConnectSize; KSDATAFORMAT_WAVEFORMATEX* ksDataFormatWfx; KSPIN_COMMUNICATION communication; KSDATARANGE* dataRanges; KSMULTIPLE_ITEM* dataRangesItem; KSPIN_DATAFLOW dataFlow; KSPIN_CINSTANCES instances; unsigned long frameSize; int maxChannels; unsigned long formats; int defaultSampleRate; ULONG *positionRegister; /* WaveRT */ ULONG hwLatency; /* WaveRT */ FunctionMemoryBarrier fnMemBarrier; /* WaveRT */ FunctionGetPinAudioPosition fnAudioPosition; /* WaveRT */ FunctionPinHandler fnEventHandler; FunctionPinHandler fnSubmitHandler; }; /* The Filter structure * A filter has a number of pins and a "friendly name" */ struct __PaWinWdmFilter { HANDLE handle; PaWinWDMKSDeviceInfo devInfo; /* This will hold information that is exposed in PaDeviceInfo */ DWORD deviceNode; int pinCount; PaWinWdmPin** pins; PaWinWdmFilter* topologyFilter; wchar_t friendlyName[MAX_PATH]; int validPinCount; int usageCount; KSMULTIPLE_ITEM* connections; KSMULTIPLE_ITEM* nodes; int filterRefCount; }; typedef struct __PaWinWdmDeviceInfo { PaDeviceInfo inheritedDeviceInfo; char compositeName[MAX_PATH]; /* Composite name consists of pin name + device name in utf8 */ PaWinWdmFilter* filter; unsigned long pin; int muxPosition; /* Used only for input devices */ int endpointPinId; } PaWinWdmDeviceInfo; /* PaWinWdmHostApiRepresentation - host api datastructure specific to this implementation */ typedef struct __PaWinWdmHostApiRepresentation { PaUtilHostApiRepresentation inheritedHostApiRep; PaUtilStreamInterface callbackStreamInterface; PaUtilStreamInterface blockingStreamInterface; PaUtilAllocationGroup* allocations; int deviceCount; } PaWinWdmHostApiRepresentation; typedef struct __DATAPACKET { KSSTREAM_HEADER Header; OVERLAPPED Signal; } DATAPACKET; typedef struct __PaIOPacket { DATAPACKET* packet; unsigned startByte; unsigned lengthBytes; } PaIOPacket; typedef struct __PaWinWdmIOInfo { PaWinWdmPin* pPin; char* hostBuffer; unsigned hostBufferSize; unsigned framesPerBuffer; unsigned bytesPerFrame; unsigned bytesPerSample; unsigned noOfPackets; /* Only used in WaveCyclic */ HANDLE *events; /* noOfPackets handles (WaveCyclic) 1 (WaveRT) */ DATAPACKET *packets; /* noOfPackets packets (WaveCyclic) 2 (WaveRT) */ /* WaveRT polled mode */ unsigned lastPosition; unsigned pollCntr; } PaWinWdmIOInfo; /* PaWinWdmStream - a stream data structure specifically for this implementation */ struct __PaWinWdmStream { PaUtilStreamRepresentation streamRepresentation; PaWDMKSSpecificStreamInfo hostApiStreamInfo; /* This holds info that is exposed through PaStreamInfo */ PaUtilCpuLoadMeasurer cpuLoadMeasurer; PaUtilBufferProcessor bufferProcessor; #if PA_TRACE_REALTIME_EVENTS LogHandle hLog; #endif PaUtilAllocationGroup* allocGroup; PaWinWdmIOInfo capture; PaWinWdmIOInfo render; int streamStarted; int streamActive; int streamStop; int streamAbort; int oldProcessPriority; HANDLE streamThread; HANDLE eventAbort; HANDLE eventStreamStart[StreamStart_kCnt]; /* 0 = OK, 1 = Failed */ PaError threadResult; PaStreamFlags streamFlags; /* Capture ring buffer */ PaUtilRingBuffer ringBuffer; char* ringBufferData; /* These values handle the case where the user wants to use fewer * channels than the device has */ int userInputChannels; int deviceInputChannels; int userOutputChannels; int deviceOutputChannels; }; /* Gather all processing variables in a struct */ struct __PaProcessThreadInfo { PaWinWdmStream *stream; PaStreamCallbackTimeInfo ti; PaStreamCallbackFlags underover; int cbResult; volatile int pending; volatile int priming; volatile int pinsStarted; unsigned long timeout; unsigned captureHead; unsigned captureTail; unsigned renderHead; unsigned renderTail; PaIOPacket capturePackets[4]; PaIOPacket renderPackets[4]; }; /* Used for transferring device infos during scanning / rescanning */ typedef struct __PaWinWDMScanDeviceInfosResults { PaDeviceInfo **deviceInfos; PaDeviceIndex defaultInputDevice; PaDeviceIndex defaultOutputDevice; } PaWinWDMScanDeviceInfosResults; static const unsigned cPacketsArrayMask = 3; HMODULE DllKsUser = NULL; KSCREATEPIN* FunctionKsCreatePin = NULL; /* prototypes for functions declared in this file */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ PaError PaWinWdm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); #ifdef __cplusplus } #endif /* __cplusplus */ /* Low level I/O functions */ static PaError WdmSyncIoctl(HANDLE handle, unsigned long ioctlNumber, void* inBuffer, unsigned long inBufferCount, void* outBuffer, unsigned long outBufferCount, unsigned long* bytesReturned); static PaError WdmGetPropertySimple(HANDLE handle, const GUID* const guidPropertySet, unsigned long property, void* value, unsigned long valueCount); static PaError WdmSetPropertySimple(HANDLE handle, const GUID* const guidPropertySet, unsigned long property, void* value, unsigned long valueCount, void* instance, unsigned long instanceCount); static PaError WdmGetPinPropertySimple(HANDLE handle, unsigned long pinId, const GUID* const guidPropertySet, unsigned long property, void* value, unsigned long valueCount, unsigned long* byteCount); static PaError WdmGetPinPropertyMulti(HANDLE handle, unsigned long pinId, const GUID* const guidPropertySet, unsigned long property, KSMULTIPLE_ITEM** ksMultipleItem); static PaError WdmGetPropertyMulti(HANDLE handle, const GUID* const guidPropertySet, unsigned long property, KSMULTIPLE_ITEM** ksMultipleItem); static PaError WdmSetMuxNodeProperty(HANDLE handle, ULONG nodeId, ULONG pinId); /** Pin management functions */ static PaWinWdmPin* PinNew(PaWinWdmFilter* parentFilter, unsigned long pinId, PaError* error); static void PinFree(PaWinWdmPin* pin); static void PinClose(PaWinWdmPin* pin); static PaError PinInstantiate(PaWinWdmPin* pin); /*static PaError PinGetState(PaWinWdmPin* pin, KSSTATE* state); NOT USED */ static PaError PinSetState(PaWinWdmPin* pin, KSSTATE state); static PaError PinSetFormat(PaWinWdmPin* pin, const WAVEFORMATEX* format); static PaError PinIsFormatSupported(PaWinWdmPin* pin, const WAVEFORMATEX* format); /* WaveRT support */ static PaError PinQueryNotificationSupport(PaWinWdmPin* pPin, BOOL* pbResult); static PaError PinGetBuffer(PaWinWdmPin* pPin, void** pBuffer, DWORD* pRequestedBufSize, BOOL* pbCallMemBarrier); static PaError PinRegisterPositionRegister(PaWinWdmPin* pPin); static PaError PinRegisterNotificationHandle(PaWinWdmPin* pPin, HANDLE handle); static PaError PinUnregisterNotificationHandle(PaWinWdmPin* pPin, HANDLE handle); static PaError PinGetHwLatency(PaWinWdmPin* pPin, ULONG* pFifoSize, ULONG* pChipsetDelay, ULONG* pCodecDelay); static PaError PinGetAudioPositionDirect(PaWinWdmPin* pPin, ULONG* pPosition); static PaError PinGetAudioPositionViaIOCTL(PaWinWdmPin* pPin, ULONG* pPosition); /* Filter management functions */ static PaWinWdmFilter* FilterNew(PaWDMKSType type, DWORD devNode, const wchar_t* filterName, const wchar_t* friendlyName, PaError* error); static PaError FilterInitializePins(PaWinWdmFilter* filter); static void FilterFree(PaWinWdmFilter* filter); static void FilterAddRef(PaWinWdmFilter* filter); static PaWinWdmPin* FilterCreatePin( PaWinWdmFilter* filter, int pinId, const WAVEFORMATEX* wfex, PaError* error); static PaError FilterUse(PaWinWdmFilter* filter); static void FilterRelease(PaWinWdmFilter* filter); /* Hot plug functions */ static BOOL IsDeviceTheSame(const PaWinWdmDeviceInfo* pDev1, const PaWinWdmDeviceInfo* pDev2); /* Interface functions */ static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); static PaError ScanDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, PaHostApiIndex index, void **newDeviceInfos, int *newDeviceCount ); static PaError CommitDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, PaHostApiIndex index, void *deviceInfos, int deviceCount ); static PaError DisposeDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, void *deviceInfos, int deviceCount ); static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); static PaError CloseStream( PaStream* stream ); static PaError StartStream( PaStream *stream ); static PaError StopStream( PaStream *stream ); static PaError AbortStream( PaStream *stream ); static PaError IsStreamStopped( PaStream *s ); static PaError IsStreamActive( PaStream *stream ); static PaTime GetStreamTime( PaStream *stream ); static double GetStreamCpuLoad( PaStream* stream ); static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ); static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ); static signed long GetStreamReadAvailable( PaStream* stream ); static signed long GetStreamWriteAvailable( PaStream* stream ); /* Utility functions */ static unsigned long GetWfexSize(const WAVEFORMATEX* wfex); static PaWinWdmFilter** BuildFilterList(int* filterCount, int* noOfPaDevices, PaError* result); static BOOL PinWrite(HANDLE h, DATAPACKET* p); static BOOL PinRead(HANDLE h, DATAPACKET* p); static void DuplicateFirstChannelInt16(void* buffer, int channels, int samples); static void DuplicateFirstChannelInt24(void* buffer, int channels, int samples); PA_THREAD_FUNC ProcessingThread(void*); /* Pin handler functions */ static PaError PaPinCaptureEventHandler_WaveCyclic(PaProcessThreadInfo* pInfo, unsigned eventIndex); static PaError PaPinCaptureSubmitHandler_WaveCyclic(PaProcessThreadInfo* pInfo, unsigned eventIndex); static PaError PaPinRenderEventHandler_WaveCyclic(PaProcessThreadInfo* pInfo, unsigned eventIndex); static PaError PaPinRenderSubmitHandler_WaveCyclic(PaProcessThreadInfo* pInfo, unsigned eventIndex); static PaError PaPinCaptureEventHandler_WaveRTEvent(PaProcessThreadInfo* pInfo, unsigned eventIndex); static PaError PaPinCaptureEventHandler_WaveRTPolled(PaProcessThreadInfo* pInfo, unsigned eventIndex); static PaError PaPinCaptureSubmitHandler_WaveRTEvent(PaProcessThreadInfo* pInfo, unsigned eventIndex); static PaError PaPinCaptureSubmitHandler_WaveRTPolled(PaProcessThreadInfo* pInfo, unsigned eventIndex); static PaError PaPinRenderEventHandler_WaveRTEvent(PaProcessThreadInfo* pInfo, unsigned eventIndex); static PaError PaPinRenderEventHandler_WaveRTPolled(PaProcessThreadInfo* pInfo, unsigned eventIndex); static PaError PaPinRenderSubmitHandler_WaveRTEvent(PaProcessThreadInfo* pInfo, unsigned eventIndex); static PaError PaPinRenderSubmitHandler_WaveRTPolled(PaProcessThreadInfo* pInfo, unsigned eventIndex); /* Function bodies */ #if defined(_DEBUG) && defined(PA_ENABLE_DEBUG_OUTPUT) #define PA_WDMKS_SET_TREF static PaTime tRef = 0; static void PaWinWdmDebugPrintf(const char* fmt, ...) { va_list list; char buffer[1024]; PaTime t = PaUtil_GetTime() - tRef; va_start(list, fmt); _vsnprintf(buffer, 1023, fmt, list); va_end(list); PaUtil_DebugPrint("%6.3lf: %s", t, buffer); } #ifdef PA_DEBUG #undef PA_DEBUG #define PA_DEBUG(x) PaWinWdmDebugPrintf x ; #endif #endif static BOOL IsDeviceTheSame(const PaWinWdmDeviceInfo* pDev1, const PaWinWdmDeviceInfo* pDev2) { if (pDev1 == NULL || pDev2 == NULL) return FALSE; if (pDev1 == pDev2) return TRUE; if (strcmp(pDev1->compositeName, pDev2->compositeName) == 0) return TRUE; return FALSE; } static BOOL IsEarlierThanVista() { OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof(osvi); if (GetVersionEx(&osvi) && osvi.dwMajorVersion<6) { return TRUE; } return FALSE; } static void MemoryBarrierDummy(void) { /* Do nothing */ } static void MemoryBarrierRead(void) { PaUtil_ReadMemoryBarrier(); } static void MemoryBarrierWrite(void) { PaUtil_WriteMemoryBarrier(); } static unsigned long GetWfexSize(const WAVEFORMATEX* wfex) { if( wfex->wFormatTag == WAVE_FORMAT_PCM ) { return sizeof( WAVEFORMATEX ); } else { return (sizeof( WAVEFORMATEX ) + wfex->cbSize); } } static void PaWinWDM_SetLastErrorInfo(long errCode, const char* fmt, ...) { va_list list; char buffer[1024]; va_start(list, fmt); _vsnprintf(buffer, 1023, fmt, list); va_end(list); PaUtil_SetLastHostErrorInfo(paWDMKS, errCode, buffer); } /* Low level pin/filter access functions */ static PaError WdmSyncIoctl( HANDLE handle, unsigned long ioctlNumber, void* inBuffer, unsigned long inBufferCount, void* outBuffer, unsigned long outBufferCount, unsigned long* bytesReturned) { PaError result = paNoError; unsigned long dummyBytesReturned = 0; BOOL bRes; if( !bytesReturned ) { /* Use a dummy as the caller hasn't supplied one */ bytesReturned = &dummyBytesReturned; } bRes = DeviceIoControl(handle, ioctlNumber, inBuffer, inBufferCount, outBuffer, outBufferCount, bytesReturned, NULL); if (!bRes) { unsigned long error = GetLastError(); if ( !(((error == ERROR_INSUFFICIENT_BUFFER ) || ( error == ERROR_MORE_DATA )) && ( ioctlNumber == IOCTL_KS_PROPERTY ) && ( outBufferCount == 0 ) ) ) { KSPROPERTY* ksProperty = (KSPROPERTY*)inBuffer; PaWinWDM_SetLastErrorInfo(result, "WdmSyncIoctl: DeviceIoControl GLE = 0x%08X (prop_set = {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}, prop_id = %u)", error, ksProperty->Set.Data1, ksProperty->Set.Data2, ksProperty->Set.Data3, ksProperty->Set.Data4[0], ksProperty->Set.Data4[1], ksProperty->Set.Data4[2], ksProperty->Set.Data4[3], ksProperty->Set.Data4[4], ksProperty->Set.Data4[5], ksProperty->Set.Data4[6], ksProperty->Set.Data4[7], ksProperty->Id ); result = paUnanticipatedHostError; } } return result; } static PaError WdmGetPropertySimple(HANDLE handle, const GUID* const guidPropertySet, unsigned long property, void* value, unsigned long valueCount) { PaError result; KSPROPERTY ksProperty; ksProperty.Set = *guidPropertySet; ksProperty.Id = property; ksProperty.Flags = KSPROPERTY_TYPE_GET; result = WdmSyncIoctl( handle, IOCTL_KS_PROPERTY, &ksProperty, sizeof(KSPROPERTY), value, valueCount, NULL); return result; } static PaError WdmSetPropertySimple( HANDLE handle, const GUID* const guidPropertySet, unsigned long property, void* value, unsigned long valueCount, void* instance, unsigned long instanceCount) { PaError result; KSPROPERTY* ksProperty; unsigned long propertyCount = 0; propertyCount = sizeof(KSPROPERTY) + instanceCount; ksProperty = (KSPROPERTY*)_alloca( propertyCount ); if( !ksProperty ) { return paInsufficientMemory; } ksProperty->Set = *guidPropertySet; ksProperty->Id = property; ksProperty->Flags = KSPROPERTY_TYPE_SET; if( instance ) { memcpy((void*)((char*)ksProperty + sizeof(KSPROPERTY)), instance, instanceCount); } result = WdmSyncIoctl( handle, IOCTL_KS_PROPERTY, ksProperty, propertyCount, value, valueCount, NULL); return result; } static PaError WdmGetPinPropertySimple( HANDLE handle, unsigned long pinId, const GUID* const guidPropertySet, unsigned long property, void* value, unsigned long valueCount, unsigned long *byteCount) { PaError result; KSP_PIN ksPProp; ksPProp.Property.Set = *guidPropertySet; ksPProp.Property.Id = property; ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; ksPProp.PinId = pinId; ksPProp.Reserved = 0; result = WdmSyncIoctl( handle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN), value, valueCount, byteCount); return result; } static PaError WdmGetPinPropertyMulti( HANDLE handle, unsigned long pinId, const GUID* const guidPropertySet, unsigned long property, KSMULTIPLE_ITEM** ksMultipleItem) { PaError result; unsigned long multipleItemSize = 0; KSP_PIN ksPProp; ksPProp.Property.Set = *guidPropertySet; ksPProp.Property.Id = property; ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; ksPProp.PinId = pinId; ksPProp.Reserved = 0; result = WdmSyncIoctl( handle, IOCTL_KS_PROPERTY, &ksPProp.Property, sizeof(KSP_PIN), NULL, 0, &multipleItemSize); if( result != paNoError ) { return result; } *ksMultipleItem = (KSMULTIPLE_ITEM*)PaUtil_AllocateMemory( multipleItemSize ); if( !*ksMultipleItem ) { return paInsufficientMemory; } result = WdmSyncIoctl( handle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN), (void*)*ksMultipleItem, multipleItemSize, NULL); if( result != paNoError ) { PaUtil_FreeMemory( ksMultipleItem ); } return result; } static PaError WdmGetPropertyMulti(HANDLE handle, const GUID* const guidPropertySet, unsigned long property, KSMULTIPLE_ITEM** ksMultipleItem) { PaError result; unsigned long multipleItemSize = 0; KSPROPERTY ksProp; ksProp.Set = *guidPropertySet; ksProp.Id = property; ksProp.Flags = KSPROPERTY_TYPE_GET; result = WdmSyncIoctl( handle, IOCTL_KS_PROPERTY, &ksProp, sizeof(KSPROPERTY), NULL, 0, &multipleItemSize); if( result != paNoError ) { return result; } *ksMultipleItem = (KSMULTIPLE_ITEM*)PaUtil_AllocateMemory( multipleItemSize ); if( !*ksMultipleItem ) { return paInsufficientMemory; } result = WdmSyncIoctl( handle, IOCTL_KS_PROPERTY, &ksProp, sizeof(KSPROPERTY), (void*)*ksMultipleItem, multipleItemSize, NULL); if( result != paNoError ) { PaUtil_FreeMemory( ksMultipleItem ); } return result; } static PaError WdmSetMuxNodeProperty(HANDLE handle, ULONG nodeId, ULONG pinId) { PaError result = paNoError; KSNODEPROPERTY prop; prop.Property.Set = KSPROPSETID_Audio; prop.Property.Id = KSPROPERTY_AUDIO_MUX_SOURCE; prop.Property.Flags = KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_TOPOLOGY; prop.NodeId = nodeId; prop.Reserved = 0; result = WdmSyncIoctl(handle, IOCTL_KS_PROPERTY, &prop, sizeof(KSNODEPROPERTY), &pinId, sizeof(ULONG), NULL); return result; } /* Used when traversing topology for outputs */ static const KSTOPOLOGY_CONNECTION* GetConnectionTo(const KSTOPOLOGY_CONNECTION* pFrom, PaWinWdmFilter* filter, int muxIdx) { unsigned i; const KSTOPOLOGY_CONNECTION* retval = NULL; const KSTOPOLOGY_CONNECTION* connections = (const KSTOPOLOGY_CONNECTION*)(filter->connections + 1); (void)muxIdx; PA_DEBUG(("GetConnectionTo: Checking %u connections... (pFrom = %p)", filter->connections->Count, pFrom)); for (i = 0; i < filter->connections->Count; ++i) { const KSTOPOLOGY_CONNECTION* pConn = connections + i; if (pConn == pFrom) continue; if (pConn->FromNode == pFrom->ToNode) { retval = pConn; break; } } PA_DEBUG(("GetConnectionTo: Returning %p\n", retval)); return retval; } /* Used when traversing topology for inputs */ static const KSTOPOLOGY_CONNECTION* GetConnectionFrom(const KSTOPOLOGY_CONNECTION* pTo, PaWinWdmFilter* filter, int muxIdx) { unsigned i; const KSTOPOLOGY_CONNECTION* retval = NULL; const KSTOPOLOGY_CONNECTION* connections = (const KSTOPOLOGY_CONNECTION*)(filter->connections + 1); int muxCntr = 0; PA_DEBUG(("GetConnectionFrom: Checking %u connections... (pTo = %p)\n", filter->connections->Count, pTo)); for (i = 0; i < filter->connections->Count; ++i) { const KSTOPOLOGY_CONNECTION* pConn = connections + i; if (pConn == pTo) continue; if (pConn->ToNode == pTo->FromNode) { if (muxIdx >= 0) { if (muxCntr < muxIdx) { ++muxCntr; continue; } } retval = pConn; break; } } PA_DEBUG(("GetConnectionFrom: Returning %p\n", retval)); return retval; } static ULONG GetNumberOfConnectionsTo(const KSTOPOLOGY_CONNECTION* pTo, PaWinWdmFilter* filter) { ULONG retval = 0; unsigned i; const KSTOPOLOGY_CONNECTION* connections = (const KSTOPOLOGY_CONNECTION*)(filter->connections + 1); PA_DEBUG(("GetNumberOfConnectionsTo: Checking %u connections...", filter->connections->Count)); for (i = 0; i < filter->connections->Count; ++i) { const KSTOPOLOGY_CONNECTION* pConn = connections + i; if (pConn->ToNode == pTo->FromNode && (pTo->FromNode != KSFILTER_NODE || pConn->ToNodePin == pTo->FromNodePin)) { ++retval; } } return retval; } typedef const KSTOPOLOGY_CONNECTION *(*TFnGetConnection)(const KSTOPOLOGY_CONNECTION*, PaWinWdmFilter*, int); static const KSTOPOLOGY_CONNECTION* FindStartConnectionFrom(ULONG startPin, PaWinWdmFilter* filter) { unsigned i; const KSTOPOLOGY_CONNECTION* connections = (const KSTOPOLOGY_CONNECTION*)(filter->connections + 1); PA_DEBUG(("FindStartConnectionFrom: Checking %u connections...", filter->connections->Count)); for (i = 0; i < filter->connections->Count; ++i) { const KSTOPOLOGY_CONNECTION* pConn = connections + i; if (pConn->ToNode == KSFILTER_NODE && pConn->ToNodePin == startPin) { return pConn; } } assert(FALSE); return 0; } static const KSTOPOLOGY_CONNECTION* FindStartConnectionTo(ULONG startPin, PaWinWdmFilter* filter) { unsigned i; const KSTOPOLOGY_CONNECTION* connections = (const KSTOPOLOGY_CONNECTION*)(filter->connections + 1); PA_DEBUG(("FindStartConnectionTo: Checking %u connections...", filter->connections->Count)); for (i = 0; i < filter->connections->Count; ++i) { const KSTOPOLOGY_CONNECTION* pConn = connections + i; if (pConn->FromNode == KSFILTER_NODE && pConn->FromNodePin == startPin) { return pConn; } } assert(FALSE); return 0; } static ULONG GetConnectedPin(ULONG startPin, BOOL forward, PaWinWdmFilter* filter, int muxPosition, ULONG *muxInputPinId, ULONG *muxNodeId) { const KSTOPOLOGY_CONNECTION *conn = NULL; TFnGetConnection fnGetConnection = forward ? GetConnectionTo : GetConnectionFrom ; while (1) { if (conn == NULL) { conn = forward ? FindStartConnectionTo(startPin, filter) : FindStartConnectionFrom(startPin, filter); } else { conn = fnGetConnection(conn, filter, -1); } /* Handling case of erroneous connection list */ if (conn == NULL) { break; } if (forward ? conn->ToNode == KSFILTER_NODE : conn->FromNode == KSFILTER_NODE) { return forward ? conn->ToNodePin : conn->FromNodePin; } else { PA_DEBUG(("GetConnectedPin: count=%d, forward=%d, muxPosition=%d\n", filter->nodes->Count, forward, muxPosition)); if (filter->nodes->Count > 0 && !forward && muxPosition >= 0) { const GUID* nodes = (const GUID*)(filter->nodes + 1); if (IsEqualGUID(&nodes[conn->FromNode], &KSNODETYPE_MUX)) { ULONG nConn = GetNumberOfConnectionsTo(conn, filter); conn = fnGetConnection(conn, filter, muxPosition); if (conn == NULL) { break; } if (muxInputPinId != 0) { *muxInputPinId = conn->ToNodePin; } if (muxNodeId != 0) { *muxNodeId = conn->ToNode; } } } } } return KSFILTER_NODE; } static void DumpConnectionsAndNodes(PaWinWdmFilter* filter) { unsigned i; const KSTOPOLOGY_CONNECTION* connections = (const KSTOPOLOGY_CONNECTION*)(filter->connections + 1); const GUID* nodes = (const GUID*)(filter->nodes + 1); PA_DEBUG(("DumpConnectionsAndNodes: connections=%d, nodes=%d\n", filter->connections->Count, filter->nodes->Count)); for (i=0; i < filter->connections->Count; ++i) { const KSTOPOLOGY_CONNECTION* pConn = connections + i; PA_DEBUG((" Connection: %u - FromNode=%u,FromPin=%u -> ToNode=%u,ToPin=%u\n", i, pConn->FromNode, pConn->FromNodePin, pConn->ToNode, pConn->ToNodePin )); } for (i=0; i < filter->nodes->Count; ++i) { const GUID* pConn = nodes + i; PA_DEBUG((" Node: %d - {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n", i, pConn->Data1, pConn->Data2, pConn->Data3, pConn->Data4[0], pConn->Data4[1], pConn->Data4[2], pConn->Data4[3], pConn->Data4[4], pConn->Data4[5], pConn->Data4[6], pConn->Data4[7] )); } } typedef struct __PaUsbTerminalGUIDToName { USHORT usbGUID; wchar_t name[64]; } PaUsbTerminalGUIDToName; static const PaUsbTerminalGUIDToName kNames[] = { /* Types copied from: http://msdn.microsoft.com/en-us/library/ff537742(v=vs.85).aspx */ /* Input terminal types */ { 0x0201, L"Microphone" }, { 0x0202, L"Desktop Microphone" }, { 0x0203, L"Personal Microphone" }, { 0x0204, L"Omni Directional Microphone" }, { 0x0205, L"Microphone Array" }, { 0x0206, L"Processing Microphone Array" }, /* Output terminal types */ { 0x0301, L"Speakers" }, { 0x0302, L"Headphones" }, { 0x0303, L"Head Mounted Display Audio" }, { 0x0304, L"Desktop Speaker" }, { 0x0305, L"Room Speaker" }, { 0x0306, L"Communication Speaker" }, { 0x0307, L"LFE Speakers" }, /* External terminal types */ { 0x0601, L"Analog" }, { 0x0602, L"Digital" }, { 0x0603, L"Line" }, { 0x0604, L"Audio" }, { 0x0605, L"SPDIF" }, }; static const unsigned kNamesCnt = sizeof(kNames)/sizeof(PaUsbTerminalGUIDToName); static int PaUsbTerminalGUIDToNameCmp(const void* lhs, const void* rhs) { const PaUsbTerminalGUIDToName* pL = (const PaUsbTerminalGUIDToName*)lhs; const PaUsbTerminalGUIDToName* pR = (const PaUsbTerminalGUIDToName*)rhs; return ((int)(pL->usbGUID) - (int)(pR->usbGUID)); } static PaError GetNameFromCategory(const GUID* pGUID, BOOL input, wchar_t* name, unsigned length) { PaError result = paUnanticipatedHostError; USHORT usbTerminalGUID = (USHORT)(pGUID->Data1 - 0xDFF219E0); if (input && usbTerminalGUID >= 0x301 && usbTerminalGUID < 0x400) { /* Output terminal name for an input !? Set it to Line! */ usbTerminalGUID = 0x603; } if (!input && usbTerminalGUID >= 0x201 && usbTerminalGUID < 0x300) { /* Input terminal name for an output !? Set it to Line! */ usbTerminalGUID = 0x603; } if (usbTerminalGUID >= 0x201 && usbTerminalGUID < 0x713) { PaUsbTerminalGUIDToName s = { usbTerminalGUID }; const PaUsbTerminalGUIDToName* ptr = bsearch( &s, kNames, kNamesCnt, sizeof(PaUsbTerminalGUIDToName), PaUsbTerminalGUIDToNameCmp ); if (ptr != 0) { PA_DEBUG(("GetNameFromCategory: USB GUID %04X -> '%S'\n", usbTerminalGUID, ptr->name)); if (name != NULL && length > 0) { int n = _snwprintf(name, length, L"%s", ptr->name); if (usbTerminalGUID >= 0x601 && usbTerminalGUID < 0x700) { _snwprintf(name + n, length - n, L" %s", (input ? L"In":L"Out")); } } result = paNoError; } } else { PaWinWDM_SetLastErrorInfo(result, "GetNameFromCategory: usbTerminalGUID = %04X ", usbTerminalGUID); } return result; } static BOOL IsFrequencyWithinRange(const KSDATARANGE_AUDIO* range, int frequency) { if (frequency < (int)range->MinimumSampleFrequency) return FALSE; if (frequency > (int)range->MaximumSampleFrequency) return FALSE; return TRUE; } static BOOL IsBitsWithinRange(const KSDATARANGE_AUDIO* range, int noOfBits) { if (noOfBits < (int)range->MinimumBitsPerSample) return FALSE; if (noOfBits > (int)range->MaximumBitsPerSample) return FALSE; return TRUE; } /* Note: Somewhat different order compared to WMME implementation, as we want to focus on fidelity first */ static const int defaultSampleRateSearchOrder[] = { 44100, 48000, 88200, 96000, 192000, 32000, 24000, 22050, 16000, 12000, 11025, 9600, 8000 }; static const int defaultSampleRateSearchOrderCount = sizeof(defaultSampleRateSearchOrder)/sizeof(defaultSampleRateSearchOrder[0]); static int DefaultSampleFrequencyIndex(const KSDATARANGE_AUDIO* range) { int i; for(i=0; i < defaultSampleRateSearchOrderCount; ++i) { int currentFrequency = defaultSampleRateSearchOrder[i]; if (IsFrequencyWithinRange(range, currentFrequency)) { return i; } } return -1; } /* Create a new pin object belonging to a filter The pin object holds all the configuration information about the pin before it is opened, and then the handle of the pin after is opened */ static PaWinWdmPin* PinNew(PaWinWdmFilter* parentFilter, unsigned long pinId, PaError* error) { PaWinWdmPin* pin; PaError result; unsigned long i; KSMULTIPLE_ITEM* item = NULL; KSIDENTIFIER* identifier; KSDATARANGE* dataRange; const ULONG streamingId = (parentFilter->devInfo.streamingType == Type_kWaveRT) ? KSINTERFACE_STANDARD_LOOPED_STREAMING : KSINTERFACE_STANDARD_STREAMING; int defaultSampleRateIndex = defaultSampleRateSearchOrderCount; PA_LOGE_; PA_DEBUG(("PinNew: Creating pin %d:\n",pinId)); /* Allocate the new PIN object */ pin = (PaWinWdmPin*)PaUtil_AllocateMemory( sizeof(PaWinWdmPin) ); if( !pin ) { result = paInsufficientMemory; goto error; } /* Zero the pin object */ /* memset( (void*)pin, 0, sizeof(PaWinWdmPin) ); */ pin->parentFilter = parentFilter; pin->pinId = pinId; /* Allocate a connect structure */ pin->pinConnectSize = sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT_WAVEFORMATEX); pin->pinConnect = (KSPIN_CONNECT*)PaUtil_AllocateMemory( pin->pinConnectSize ); if( !pin->pinConnect ) { result = paInsufficientMemory; goto error; } /* Configure the connect structure with default values */ pin->pinConnect->Interface.Set = KSINTERFACESETID_Standard; pin->pinConnect->Interface.Id = streamingId; pin->pinConnect->Interface.Flags = 0; pin->pinConnect->Medium.Set = KSMEDIUMSETID_Standard; pin->pinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE; pin->pinConnect->Medium.Flags = 0; pin->pinConnect->PinId = pinId; pin->pinConnect->PinToHandle = NULL; pin->pinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL; pin->pinConnect->Priority.PrioritySubClass = 1; pin->ksDataFormatWfx = (KSDATAFORMAT_WAVEFORMATEX*)(pin->pinConnect + 1); pin->ksDataFormatWfx->DataFormat.FormatSize = sizeof(KSDATAFORMAT_WAVEFORMATEX); pin->ksDataFormatWfx->DataFormat.Flags = 0; pin->ksDataFormatWfx->DataFormat.Reserved = 0; pin->ksDataFormatWfx->DataFormat.MajorFormat = KSDATAFORMAT_TYPE_AUDIO; pin->ksDataFormatWfx->DataFormat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; pin->ksDataFormatWfx->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX; pin->frameSize = 0; /* Unknown until we instantiate pin */ /* Get the COMMUNICATION property */ result = WdmGetPinPropertySimple( parentFilter->handle, pinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_COMMUNICATION, &pin->communication, sizeof(KSPIN_COMMUNICATION), NULL); if( result != paNoError ) goto error; if( /*(pin->communication != KSPIN_COMMUNICATION_SOURCE) &&*/ (pin->communication != KSPIN_COMMUNICATION_SINK) && (pin->communication != KSPIN_COMMUNICATION_BOTH) ) { PA_DEBUG(("PinNew: Not source/sink\n")); result = paInvalidDevice; goto error; } /* Get dataflow information */ result = WdmGetPinPropertySimple( parentFilter->handle, pinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_DATAFLOW, &pin->dataFlow, sizeof(KSPIN_DATAFLOW), NULL); if( result != paNoError ) goto error; /* Get the INTERFACE property list */ result = WdmGetPinPropertyMulti( parentFilter->handle, pinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_INTERFACES, &item); if( result != paNoError ) goto error; identifier = (KSIDENTIFIER*)(item+1); /* Check that at least one interface is STANDARD_STREAMING */ result = paUnanticipatedHostError; for( i = 0; i < item->Count; i++ ) { if( IsEqualGUID(&identifier[i].Set, &KSINTERFACESETID_Standard) && ( identifier[i].Id == streamingId ) ) { result = paNoError; break; } } if( result != paNoError ) { PA_DEBUG(("PinNew: No %s streaming\n", streamingId==KSINTERFACE_STANDARD_LOOPED_STREAMING?"looped":"standard")); goto error; } /* Don't need interfaces any more */ PaUtil_FreeMemory( item ); item = NULL; /* Get the MEDIUM properties list */ result = WdmGetPinPropertyMulti( parentFilter->handle, pinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_MEDIUMS, &item); if( result != paNoError ) goto error; identifier = (KSIDENTIFIER*)(item+1); /* Not actually necessary... */ /* Check that at least one medium is STANDARD_DEVIO */ result = paUnanticipatedHostError; for( i = 0; i < item->Count; i++ ) { if( IsEqualGUID(&identifier[i].Set, &KSMEDIUMSETID_Standard) && ( identifier[i].Id == KSMEDIUM_STANDARD_DEVIO ) ) { result = paNoError; break; } } if( result != paNoError ) { PA_DEBUG(("No standard devio\n")); goto error; } /* Don't need mediums any more */ PaUtil_FreeMemory( item ); item = NULL; /* Get DATARANGES */ result = WdmGetPinPropertyMulti( parentFilter->handle, pinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_DATARANGES, &pin->dataRangesItem); if( result != paNoError ) goto error; pin->dataRanges = (KSDATARANGE*)(pin->dataRangesItem +1); /* Check that at least one datarange supports audio */ result = paUnanticipatedHostError; dataRange = pin->dataRanges; pin->maxChannels = 0; pin->defaultSampleRate = 0; pin->formats = 0; PA_DEBUG(("PinNew: Checking %u no of dataranges...\n", pin->dataRangesItem->Count)); for( i = 0; i < pin->dataRangesItem->Count; i++) { PA_DEBUG(("PinNew: DR major format %x\n",*(unsigned long*)(&(dataRange->MajorFormat)))); /* Check that subformat is WAVEFORMATEX, PCM or WILDCARD */ if( IS_VALID_WAVEFORMATEX_GUID(&dataRange->SubFormat) || IsEqualGUID(&dataRange->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM) || IsEqualGUID(&dataRange->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT) || IsEqualGUID(&dataRange->SubFormat, &KSDATAFORMAT_SUBTYPE_WILDCARD) || IsEqualGUID(&dataRange->MajorFormat, &KSDATAFORMAT_TYPE_AUDIO) ) { int defaultIndex; result = paNoError; /* Record the maximum possible channels with this pin */ if( ((KSDATARANGE_AUDIO*)dataRange)->MaximumChannels == (ULONG) -1 ) { pin->maxChannels = MAXIMUM_NUMBER_OF_CHANNELS; } else if( (int) ((KSDATARANGE_AUDIO*)dataRange)->MaximumChannels > pin->maxChannels ) { pin->maxChannels = (int) ((KSDATARANGE_AUDIO*)dataRange)->MaximumChannels; } PA_DEBUG(("PinNew: MaxChannel: %d\n",pin->maxChannels)); /* Record the formats (bit depths) that are supported */ if( IsBitsWithinRange((KSDATARANGE_AUDIO*)dataRange, 8) ) { pin->formats |= paInt8; PA_DEBUG(("PinNew: Format PCM 8 bit supported\n")); } if( IsBitsWithinRange((KSDATARANGE_AUDIO*)dataRange, 16) ) { pin->formats |= paInt16; PA_DEBUG(("PinNew: Format PCM 16 bit supported\n")); } if( IsBitsWithinRange((KSDATARANGE_AUDIO*)dataRange, 24) ) { pin->formats |= paInt24; PA_DEBUG(("PinNew: Format PCM 24 bit supported\n")); } if( IsBitsWithinRange((KSDATARANGE_AUDIO*)dataRange, 32) ) { if (IsEqualGUID(&dataRange->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)) { pin->formats |= paFloat32; PA_DEBUG(("PinNew: Format IEEE float 32 bit supported\n")); } else { pin->formats |= paInt32; PA_DEBUG(("PinNew: Format PCM 32 bit supported\n")); } } defaultIndex = DefaultSampleFrequencyIndex((KSDATARANGE_AUDIO*)dataRange); if (defaultIndex >= 0 && defaultIndex < defaultSampleRateIndex) { defaultSampleRateIndex = defaultIndex; } } dataRange = (KSDATARANGE*)( ((char*)dataRange) + dataRange->FormatSize); } if( result != paNoError ) goto error; /* If none of the frequencies searched for are present, there's something seriously wrong */ if (defaultSampleRateIndex == defaultSampleRateSearchOrderCount) { PA_DEBUG(("PinNew: No default sample rate found, skipping pin!\n")); PaWinWDM_SetLastErrorInfo(paUnanticipatedHostError, "PinNew: No default sample rate found"); result = paUnanticipatedHostError; goto error; } /* Set the default sample rate */ pin->defaultSampleRate = defaultSampleRateSearchOrder[defaultSampleRateIndex]; PA_DEBUG(("PinNew: Default sample rate = %d Hz\n", pin->defaultSampleRate)); /* Get instance information */ result = WdmGetPinPropertySimple( parentFilter->handle, pinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_CINSTANCES, &pin->instances, sizeof(KSPIN_CINSTANCES), NULL); if( result != paNoError ) goto error; /* If WaveRT, check if pin supports notification mode */ if (parentFilter->devInfo.streamingType == Type_kWaveRT) { BOOL bSupportsNotification = FALSE; if (PinQueryNotificationSupport(pin, &bSupportsNotification) == paNoError) { pin->pinKsSubType = bSupportsNotification ? SubType_kNotification : SubType_kPolled; } } /* Query pin name (which means we need to traverse to non IRP pin, via physical connection to topology filter pin, through its nodes to the endpoint pin, and get that ones name... phew...) */ PA_DEBUG(("PinNew: Finding topology pin...\n")); { ULONG topoPinId = GetConnectedPin(pinId, (pin->dataFlow == KSPIN_DATAFLOW_IN), parentFilter, -1, NULL, NULL); const wchar_t kInputName[] = L"Input"; const wchar_t kOutputName[] = L"Output"; if (topoPinId != KSFILTER_NODE) { /* Get physical connection for topo pin */ unsigned long cbBytes = 0; PA_DEBUG(("PinNew: Getting physical connection...\n")); result = WdmGetPinPropertySimple(parentFilter->handle, topoPinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_PHYSICALCONNECTION, 0, 0, &cbBytes ); if (result != paNoError) { /* No physical connection -> there is no topology filter! So we get the name of the pin! */ PA_DEBUG(("PinNew: No physical connection! Getting the pin name\n")); result = WdmGetPinPropertySimple(parentFilter->handle, topoPinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_NAME, pin->friendlyName, MAX_PATH, NULL); if (result != paNoError) { GUID category = {0}; /* Get pin category information */ result = WdmGetPinPropertySimple(parentFilter->handle, topoPinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_CATEGORY, &category, sizeof(GUID), NULL); if (result == paNoError) { result = GetNameFromCategory(&category, (pin->dataFlow == KSPIN_DATAFLOW_OUT), pin->friendlyName, MAX_PATH); } } /* Make sure pin gets a name here... */ if (wcslen(pin->friendlyName) == 0) { wcscpy(pin->friendlyName, (pin->dataFlow == KSPIN_DATAFLOW_IN) ? kOutputName : kInputName); #ifdef UNICODE PA_DEBUG(("PinNew: Setting pin friendly name to '%s'\n", pin->friendlyName)); #else PA_DEBUG(("PinNew: Setting pin friendly name to '%S'\n", pin->friendlyName)); #endif } /* This is then == the endpoint pin */ pin->endpointPinId = (pin->dataFlow == KSPIN_DATAFLOW_IN) ? pinId : topoPinId; } else { KSPIN_PHYSICALCONNECTION* pc = (KSPIN_PHYSICALCONNECTION*)PaUtil_AllocateMemory(cbBytes + 2); PA_DEBUG(("PinNew: Physical connection found!\n")); if (pc == NULL) { result = paInsufficientMemory; goto error; } result = WdmGetPinPropertySimple(parentFilter->handle, topoPinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_PHYSICALCONNECTION, pc, cbBytes, NULL ); if (result == paNoError) { wchar_t symbLinkName[MAX_PATH]; wcsncpy(symbLinkName, pc->SymbolicLinkName, MAX_PATH); if (symbLinkName[1] == TEXT('?')) { symbLinkName[1] = TEXT('\\'); } if (pin->parentFilter->topologyFilter == NULL) { PA_DEBUG(("PinNew: Creating topology filter '%S'\n", symbLinkName)); pin->parentFilter->topologyFilter = FilterNew(Type_kNotUsed, 0, symbLinkName, L"", &result); if (pin->parentFilter->topologyFilter == NULL) { PA_DEBUG(("PinNew: Failed creating topology filter\n")); result = paUnanticipatedHostError; PaWinWDM_SetLastErrorInfo(result, "Failed to create topology filter '%S'", symbLinkName); goto error; } /* Copy info so we have it in device info */ wcsncpy(pin->parentFilter->devInfo.topologyPath, symbLinkName, MAX_PATH); } else { /* Must be the same */ assert(wcscmp(symbLinkName, pin->parentFilter->topologyFilter->devInfo.filterPath) == 0); } PA_DEBUG(("PinNew: Opening topology filter...")); result = FilterUse(pin->parentFilter->topologyFilter); if (result == paNoError) { unsigned long endpointPinId; if (pin->dataFlow == KSPIN_DATAFLOW_IN) { /* The "endpointPinId" is what WASAPI looks at for pin names */ GUID category = {0}; PA_DEBUG(("PinNew: Checking for output endpoint pin id...\n")); endpointPinId = GetConnectedPin(pc->Pin, TRUE, pin->parentFilter->topologyFilter, -1, NULL, NULL); if (endpointPinId == KSFILTER_NODE) { result = paUnanticipatedHostError; PaWinWDM_SetLastErrorInfo(result, "Failed to get endpoint pin ID on topology filter!"); goto error; } PA_DEBUG(("PinNew: Found endpoint pin id %u\n", endpointPinId)); /* Get pin category information */ result = WdmGetPinPropertySimple(pin->parentFilter->topologyFilter->handle, endpointPinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_CATEGORY, &category, sizeof(GUID), NULL); if (result == paNoError) { #if !PA_WDMKS_USE_CATEGORY_FOR_PIN_NAMES wchar_t pinName[MAX_PATH]; PA_DEBUG(("PinNew: Getting pin name property...")); /* Ok, try pin name also, and favor that if available */ result = WdmGetPinPropertySimple(pin->parentFilter->topologyFilter->handle, endpointPinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_NAME, pinName, MAX_PATH, NULL); if (result == paNoError && wcslen(pinName)>0) { wcsncpy(pin->friendlyName, pinName, MAX_PATH); } else #endif { result = GetNameFromCategory(&category, (pin->dataFlow == KSPIN_DATAFLOW_OUT), pin->friendlyName, MAX_PATH); } if (wcslen(pin->friendlyName) == 0) { wcscpy(pin->friendlyName, L"Output"); } #ifdef UNICODE PA_DEBUG(("PinNew: Pin name '%s'\n", pin->friendlyName)); #else PA_DEBUG(("PinNew: Pin name '%S'\n", pin->friendlyName)); #endif } /* Set endpoint pin ID (this is the topology INPUT pin, since portmixer will always traverse the filter in audio streaming direction, see http://msdn.microsoft.com/en-us/library/windows/hardware/ff536331(v=vs.85).aspx for more information) */ pin->endpointPinId = pc->Pin; } else { unsigned muxCount = 0; int muxPos = 0; /* Max 64 multiplexer inputs... sanity check :) */ for (i = 0; i < 64; ++i) { ULONG muxNodeIdTest = (unsigned)-1; PA_DEBUG(("PinNew: Checking for input endpoint pin id (%d)...\n", i)); endpointPinId = GetConnectedPin(pc->Pin, FALSE, pin->parentFilter->topologyFilter, (int)i, NULL, &muxNodeIdTest); if (endpointPinId == KSFILTER_NODE) { /* We're done */ PA_DEBUG(("PinNew: Done with inputs.\n", endpointPinId)); break; } else { /* The "endpointPinId" is what WASAPI looks at for pin names */ GUID category = {0}; PA_DEBUG(("PinNew: Found endpoint pin id %u\n", endpointPinId)); /* Get pin category information */ result = WdmGetPinPropertySimple(pin->parentFilter->topologyFilter->handle, endpointPinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_CATEGORY, &category, sizeof(GUID), NULL); if (result == paNoError) { if (muxNodeIdTest == (unsigned)-1) { /* Ok, try pin name, and favor that if available */ result = WdmGetPinPropertySimple(pin->parentFilter->topologyFilter->handle, endpointPinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_NAME, pin->friendlyName, MAX_PATH, NULL); if (result != paNoError) { result = GetNameFromCategory(&category, TRUE, pin->friendlyName, MAX_PATH); } break; } else { result = GetNameFromCategory(&category, TRUE, NULL, 0); if (result == paNoError) { ++muxCount; } } } else { PA_DEBUG(("PinNew: Failed to get pin category")); } } } if (muxCount == 0) { pin->endpointPinId = endpointPinId; /* Make sure we get a name for the pin */ if (wcslen(pin->friendlyName) == 0) { wcscpy(pin->friendlyName, kInputName); } #ifdef UNICODE PA_DEBUG(("PinNew: Input friendly name '%s'\n", pin->friendlyName)); #else PA_DEBUG(("PinNew: Input friendly name '%S'\n", pin->friendlyName)); #endif } else // muxCount > 0 { PA_DEBUG(("PinNew: Setting up %u inputs\n", muxCount)); /* Now we redo the operation once known how many multiplexer positions there are */ pin->inputs = (PaWinWdmMuxedInput**)PaUtil_AllocateMemory(muxCount * sizeof(PaWinWdmMuxedInput*)); if (pin->inputs == NULL) { FilterRelease(pin->parentFilter->topologyFilter); result = paInsufficientMemory; goto error; } pin->inputCount = muxCount; for (i = 0; i < muxCount; ++muxPos) { PA_DEBUG(("PinNew: Setting up input %u...\n", i)); if (pin->inputs[i] == NULL) { pin->inputs[i] = (PaWinWdmMuxedInput*)PaUtil_AllocateMemory(sizeof(PaWinWdmMuxedInput)); if (pin->inputs[i] == NULL) { FilterRelease(pin->parentFilter->topologyFilter); result = paInsufficientMemory; goto error; } } endpointPinId = GetConnectedPin(pc->Pin, FALSE, pin->parentFilter->topologyFilter, muxPos, &pin->inputs[i]->muxPinId, &pin->inputs[i]->muxNodeId); if (endpointPinId != KSFILTER_NODE) { /* The "endpointPinId" is what WASAPI looks at for pin names */ GUID category = {0}; /* Set input endpoint ID */ pin->inputs[i]->endpointPinId = endpointPinId; /* Get pin category information */ result = WdmGetPinPropertySimple(pin->parentFilter->topologyFilter->handle, endpointPinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_CATEGORY, &category, sizeof(GUID), NULL); if (result == paNoError) { /* Try pin name first, and if that is not defined, use category instead */ result = WdmGetPinPropertySimple(pin->parentFilter->topologyFilter->handle, endpointPinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_NAME, pin->inputs[i]->friendlyName, MAX_PATH, NULL); if (result != paNoError) { result = GetNameFromCategory(&category, TRUE, pin->inputs[i]->friendlyName, MAX_PATH); if (result != paNoError) { /* Only specify name, let name hash in ScanDeviceInfos fix postfix enumerators */ wcscpy(pin->inputs[i]->friendlyName, kInputName); } } #ifdef UNICODE PA_DEBUG(("PinNew: Input (%u) friendly name '%s'\n", i, pin->inputs[i]->friendlyName)); #else PA_DEBUG(("PinNew: Input (%u) friendly name '%S'\n", i, pin->inputs[i]->friendlyName)); #endif ++i; } } else { /* Should never come here! */ assert(FALSE); } } } } } } PaUtil_FreeMemory(pc); } } else { PA_DEBUG(("PinNew: No topology pin id found. Bad...\n")); /* No TOPO pin id ??? This is bad. Ok, so we just say it is an input or output... */ wcscpy(pin->friendlyName, (pin->dataFlow == KSPIN_DATAFLOW_IN) ? kOutputName : kInputName); } } /* Release topology filter if it has been used */ if (pin->parentFilter->topologyFilter && pin->parentFilter->topologyFilter->handle != NULL) { PA_DEBUG(("PinNew: Releasing topology filter...\n")); FilterRelease(pin->parentFilter->topologyFilter); } /* Success */ *error = paNoError; PA_DEBUG(("Pin created successfully\n")); PA_LOGL_; return pin; error: PA_DEBUG(("PinNew: Error %d\n", result)); /* Error cleanup */ PaUtil_FreeMemory( item ); if( pin ) { if (pin->parentFilter->topologyFilter && pin->parentFilter->topologyFilter->handle != NULL) { FilterRelease(pin->parentFilter->topologyFilter); } PaUtil_FreeMemory( pin->pinConnect ); PaUtil_FreeMemory( pin->dataRangesItem ); PaUtil_FreeMemory( pin ); } *error = result; PA_LOGL_; return NULL; } /* Safely free all resources associated with the pin */ static void PinFree(PaWinWdmPin* pin) { unsigned i; PA_LOGE_; if( pin ) { PinClose(pin); if( pin->pinConnect ) { PaUtil_FreeMemory( pin->pinConnect ); } if( pin->dataRangesItem ) { PaUtil_FreeMemory( pin->dataRangesItem ); } if( pin->inputs ) { for (i = 0; i < pin->inputCount; ++i) { PaUtil_FreeMemory( pin->inputs[i] ); } PaUtil_FreeMemory( pin->inputs ); } PaUtil_FreeMemory( pin ); } PA_LOGL_; } /* If the pin handle is open, close it */ static void PinClose(PaWinWdmPin* pin) { PA_LOGE_; if( pin == NULL ) { PA_DEBUG(("Closing NULL pin!")); PA_LOGL_; return; } if( pin->handle != NULL ) { PinSetState( pin, KSSTATE_PAUSE ); PinSetState( pin, KSSTATE_STOP ); CloseHandle( pin->handle ); pin->handle = NULL; FilterRelease(pin->parentFilter); } PA_LOGL_; } /* Set the state of this (instantiated) pin */ static PaError PinSetState(PaWinWdmPin* pin, KSSTATE state) { PaError result = paNoError; KSPROPERTY prop; PA_LOGE_; prop.Set = KSPROPSETID_Connection; prop.Id = KSPROPERTY_CONNECTION_STATE; prop.Flags = KSPROPERTY_TYPE_SET; if( pin == NULL ) return paInternalError; if( pin->handle == NULL ) return paInternalError; result = WdmSyncIoctl(pin->handle, IOCTL_KS_PROPERTY, &prop, sizeof(KSPROPERTY), &state, sizeof(KSSTATE), NULL); PA_LOGL_; return result; } static PaError PinInstantiate(PaWinWdmPin* pin) { PaError result; unsigned long createResult; KSALLOCATOR_FRAMING ksaf; KSALLOCATOR_FRAMING_EX ksafex; PA_LOGE_; if( pin == NULL ) return paInternalError; if(!pin->pinConnect) return paInternalError; FilterUse(pin->parentFilter); createResult = FunctionKsCreatePin( pin->parentFilter->handle, pin->pinConnect, GENERIC_WRITE | GENERIC_READ, &pin->handle ); PA_DEBUG(("Pin create result = 0x%08x\n",createResult)); if( createResult != ERROR_SUCCESS ) { FilterRelease(pin->parentFilter); pin->handle = NULL; switch (createResult) { case ERROR_INVALID_PARAMETER: /* First case when pin actually don't support the format */ return paSampleFormatNotSupported; case ERROR_BAD_COMMAND: /* Case when pin is occupied (by another application) */ return paDeviceUnavailable; default: /* All other cases */ return paInvalidDevice; } } if (pin->parentFilter->devInfo.streamingType == Type_kWaveCyclic) { /* Framing size query only valid for WaveCyclic devices */ result = WdmGetPropertySimple( pin->handle, &KSPROPSETID_Connection, KSPROPERTY_CONNECTION_ALLOCATORFRAMING, &ksaf, sizeof(ksaf)); if( result != paNoError ) { result = WdmGetPropertySimple( pin->handle, &KSPROPSETID_Connection, KSPROPERTY_CONNECTION_ALLOCATORFRAMING_EX, &ksafex, sizeof(ksafex)); if( result == paNoError ) { pin->frameSize = ksafex.FramingItem[0].FramingRange.Range.MinFrameSize; } } else { pin->frameSize = ksaf.FrameSize; } } PA_LOGL_; return paNoError; } static PaError PinSetFormat(PaWinWdmPin* pin, const WAVEFORMATEX* format) { unsigned long size; void* newConnect; PA_LOGE_; if( pin == NULL ) return paInternalError; if( format == NULL ) return paInternalError; size = GetWfexSize(format) + sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT_WAVEFORMATEX) - sizeof(WAVEFORMATEX); if( pin->pinConnectSize != size ) { newConnect = PaUtil_AllocateMemory( size ); if( newConnect == NULL ) return paInsufficientMemory; memcpy( newConnect, (void*)pin->pinConnect, min(pin->pinConnectSize,size) ); PaUtil_FreeMemory( pin->pinConnect ); pin->pinConnect = (KSPIN_CONNECT*)newConnect; pin->pinConnectSize = size; pin->ksDataFormatWfx = (KSDATAFORMAT_WAVEFORMATEX*)((KSPIN_CONNECT*)newConnect + 1); pin->ksDataFormatWfx->DataFormat.FormatSize = size - sizeof(KSPIN_CONNECT); } memcpy( (void*)&(pin->ksDataFormatWfx->WaveFormatEx), format, GetWfexSize(format) ); pin->ksDataFormatWfx->DataFormat.SampleSize = (unsigned short)(format->nChannels * (format->wBitsPerSample / 8)); PA_LOGL_; return paNoError; } static PaError PinIsFormatSupported(PaWinWdmPin* pin, const WAVEFORMATEX* format) { KSDATARANGE_AUDIO* dataRange; unsigned long count; GUID guid = DYNAMIC_GUID( DEFINE_WAVEFORMATEX_GUID(format->wFormatTag) ); PaError result = paInvalidDevice; const WAVEFORMATEXTENSIBLE* pFormatExt = (format->wFormatTag == WAVE_FORMAT_EXTENSIBLE) ? (const WAVEFORMATEXTENSIBLE*)format : 0; PA_LOGE_; if( pFormatExt != 0 ) { guid = pFormatExt->SubFormat; } dataRange = (KSDATARANGE_AUDIO*)pin->dataRanges; for(count = 0; countdataRangesItem->Count; count++, dataRange = (KSDATARANGE_AUDIO*)( ((char*)dataRange) + dataRange->DataRange.FormatSize)) /* Need to update dataRange here, due to 'continue' !! */ { /* Check major format*/ if (!(IsEqualGUID(&(dataRange->DataRange.MajorFormat), &KSDATAFORMAT_TYPE_AUDIO) || IsEqualGUID(&(dataRange->DataRange.MajorFormat), &KSDATAFORMAT_TYPE_WILDCARD))) { continue; } /* This is an audio or wildcard datarange... */ if (! (IsEqualGUID(&(dataRange->DataRange.SubFormat), &KSDATAFORMAT_SUBTYPE_WILDCARD) || IsEqualGUID(&(dataRange->DataRange.SubFormat), &KSDATAFORMAT_SUBTYPE_PCM) || IsEqualGUID(&(dataRange->DataRange.SubFormat), &guid) )) { continue; } /* Check specifier... */ if (! (IsEqualGUID(&(dataRange->DataRange.Specifier), &KSDATAFORMAT_SPECIFIER_WILDCARD) || IsEqualGUID(&(dataRange->DataRange.Specifier), &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)) ) { continue; } PA_DEBUG(("Pin:%x, DataRange:%d\n",(void*)pin,count)); PA_DEBUG(("\tFormatSize:%d, SampleSize:%d\n",dataRange->DataRange.FormatSize,dataRange->DataRange.SampleSize)); PA_DEBUG(("\tMaxChannels:%d\n",dataRange->MaximumChannels)); PA_DEBUG(("\tBits:%d-%d\n",dataRange->MinimumBitsPerSample,dataRange->MaximumBitsPerSample)); PA_DEBUG(("\tSampleRate:%d-%d\n",dataRange->MinimumSampleFrequency,dataRange->MaximumSampleFrequency)); if( dataRange->MaximumChannels != (ULONG)-1 && dataRange->MaximumChannels < format->nChannels ) { result = paInvalidChannelCount; continue; } if (pFormatExt != 0) { if ( dataRange->MinimumBitsPerSample > pFormatExt->Samples.wValidBitsPerSample ) { result = paSampleFormatNotSupported; continue; } if ( dataRange->MaximumBitsPerSample < pFormatExt->Samples.wValidBitsPerSample ) { result = paSampleFormatNotSupported; continue; } } else { if( dataRange->MinimumBitsPerSample > format->wBitsPerSample ) { result = paSampleFormatNotSupported; continue; } if( dataRange->MaximumBitsPerSample < format->wBitsPerSample ) { result = paSampleFormatNotSupported; continue; } } if( dataRange->MinimumSampleFrequency > format->nSamplesPerSec ) { result = paInvalidSampleRate; continue; } if( dataRange->MaximumSampleFrequency < format->nSamplesPerSec ) { result = paInvalidSampleRate; continue; } /* Success! */ result = paNoError; break; } PA_LOGL_; return result; } static PaError PinQueryNotificationSupport(PaWinWdmPin* pPin, BOOL* pbResult) { PaError result = paNoError; KSPROPERTY propIn; propIn.Set = KSPROPSETID_RtAudio; propIn.Id = 8; /* = KSPROPERTY_RTAUDIO_QUERY_NOTIFICATION_SUPPORT */ propIn.Flags = KSPROPERTY_TYPE_GET; result = WdmSyncIoctl(pPin->handle, IOCTL_KS_PROPERTY, &propIn, sizeof(KSPROPERTY), pbResult, sizeof(BOOL), NULL); if (result != paNoError) { PA_DEBUG(("Failed PinQueryNotificationSupport\n")); } return result; } static PaError PinGetBufferWithNotification(PaWinWdmPin* pPin, void** pBuffer, DWORD* pRequestedBufSize, BOOL* pbCallMemBarrier) { PaError result = paNoError; KSRTAUDIO_BUFFER_PROPERTY_WITH_NOTIFICATION propIn; KSRTAUDIO_BUFFER propOut; propIn.BaseAddress = 0; propIn.NotificationCount = 2; propIn.RequestedBufferSize = *pRequestedBufSize; propIn.Property.Set = KSPROPSETID_RtAudio; propIn.Property.Id = KSPROPERTY_RTAUDIO_BUFFER_WITH_NOTIFICATION; propIn.Property.Flags = KSPROPERTY_TYPE_GET; result = WdmSyncIoctl(pPin->handle, IOCTL_KS_PROPERTY, &propIn, sizeof(KSRTAUDIO_BUFFER_PROPERTY_WITH_NOTIFICATION), &propOut, sizeof(KSRTAUDIO_BUFFER), NULL); if (result == paNoError) { *pBuffer = propOut.BufferAddress; *pRequestedBufSize = propOut.ActualBufferSize; *pbCallMemBarrier = propOut.CallMemoryBarrier; } else { PA_DEBUG(("Failed to get buffer with notification\n")); } return result; } static PaError PinGetBufferWithoutNotification(PaWinWdmPin* pPin, void** pBuffer, DWORD* pRequestedBufSize, BOOL* pbCallMemBarrier) { PaError result = paNoError; KSRTAUDIO_BUFFER_PROPERTY propIn; KSRTAUDIO_BUFFER propOut; propIn.BaseAddress = NULL; propIn.RequestedBufferSize = *pRequestedBufSize; propIn.Property.Set = KSPROPSETID_RtAudio; propIn.Property.Id = KSPROPERTY_RTAUDIO_BUFFER; propIn.Property.Flags = KSPROPERTY_TYPE_GET; result = WdmSyncIoctl(pPin->handle, IOCTL_KS_PROPERTY, &propIn, sizeof(KSRTAUDIO_BUFFER_PROPERTY), &propOut, sizeof(KSRTAUDIO_BUFFER), NULL); if (result == paNoError) { *pBuffer = propOut.BufferAddress; *pRequestedBufSize = propOut.ActualBufferSize; *pbCallMemBarrier = propOut.CallMemoryBarrier; } else { PA_DEBUG(("Failed to get buffer without notification\n")); } return result; } /* greatest common divisor - PGCD in French */ static unsigned long PaWinWDMGCD( unsigned long a, unsigned long b ) { return (b==0) ? a : PaWinWDMGCD( b, a%b); } /* This function will handle getting the cyclic buffer from a WaveRT driver. Certain WaveRT drivers needs to have requested buffer size on multiples of 128 bytes: */ static PaError PinGetBuffer(PaWinWdmPin* pPin, void** pBuffer, DWORD* pRequestedBufSize, BOOL* pbCallMemBarrier) { PaError result = paNoError; while (1) { if (pPin->pinKsSubType != SubType_kPolled) { /* In case of unknown (or notification), we try both modes */ result = PinGetBufferWithNotification(pPin, pBuffer, pRequestedBufSize, pbCallMemBarrier); if (result == paNoError) { PA_DEBUG(("PinGetBuffer: SubType_kNotification\n")); pPin->pinKsSubType = SubType_kNotification; break; } } result = PinGetBufferWithoutNotification(pPin, pBuffer, pRequestedBufSize, pbCallMemBarrier); if (result == paNoError) { PA_DEBUG(("PinGetBuffer: SubType_kPolled\n")); pPin->pinKsSubType = SubType_kPolled; break; } /* Check if requested size is on a 128 byte boundary */ if (((*pRequestedBufSize) % 128UL) == 0) { PA_DEBUG(("Buffer size on 128 byte boundary, still fails :(\n")); /* Ok, can't do much more */ break; } else { /* Compute LCM so we know which sizes are on a 128 byte boundary */ const unsigned gcd = PaWinWDMGCD(128UL, pPin->ksDataFormatWfx->WaveFormatEx.nBlockAlign); const unsigned lcm = (128UL * pPin->ksDataFormatWfx->WaveFormatEx.nBlockAlign) / gcd; DWORD dwOldSize = *pRequestedBufSize; /* Align size to (next larger) LCM byte boundary, and then we try again. Note that LCM is not necessarily a power of 2. */ *pRequestedBufSize = ((*pRequestedBufSize + lcm - 1) / lcm) * lcm; PA_DEBUG(("Adjusting buffer size from %u to %u bytes (128 byte boundary, LCM=%u)\n", dwOldSize, *pRequestedBufSize, lcm)); } } return result; } static PaError PinRegisterPositionRegister(PaWinWdmPin* pPin) { PaError result = paNoError; KSRTAUDIO_HWREGISTER_PROPERTY propIn; KSRTAUDIO_HWREGISTER propOut; PA_LOGE_; propIn.BaseAddress = NULL; propIn.Property.Set = KSPROPSETID_RtAudio; propIn.Property.Id = KSPROPERTY_RTAUDIO_POSITIONREGISTER; propIn.Property.Flags = KSPROPERTY_TYPE_GET; result = WdmSyncIoctl(pPin->handle, IOCTL_KS_PROPERTY, &propIn, sizeof(KSRTAUDIO_HWREGISTER_PROPERTY), &propOut, sizeof(KSRTAUDIO_HWREGISTER), NULL); if (result == paNoError) { pPin->positionRegister = (ULONG*)propOut.Register; } else { PA_DEBUG(("Failed to register position register\n")); } PA_LOGL_; return result; } static PaError PinRegisterNotificationHandle(PaWinWdmPin* pPin, HANDLE handle) { PaError result = paNoError; KSRTAUDIO_NOTIFICATION_EVENT_PROPERTY prop; PA_LOGE_; prop.NotificationEvent = handle; prop.Property.Set = KSPROPSETID_RtAudio; prop.Property.Id = KSPROPERTY_RTAUDIO_REGISTER_NOTIFICATION_EVENT; prop.Property.Flags = KSPROPERTY_TYPE_GET; result = WdmSyncIoctl(pPin->handle, IOCTL_KS_PROPERTY, &prop, sizeof(KSRTAUDIO_NOTIFICATION_EVENT_PROPERTY), &prop, sizeof(KSRTAUDIO_NOTIFICATION_EVENT_PROPERTY), NULL); if (result != paNoError) { PA_DEBUG(("Failed to register notification handle 0x%08X\n", handle)); } PA_LOGL_; return result; } static PaError PinUnregisterNotificationHandle(PaWinWdmPin* pPin, HANDLE handle) { PaError result = paNoError; KSRTAUDIO_NOTIFICATION_EVENT_PROPERTY prop; PA_LOGE_; if (handle != NULL) { prop.NotificationEvent = handle; prop.Property.Set = KSPROPSETID_RtAudio; prop.Property.Id = KSPROPERTY_RTAUDIO_UNREGISTER_NOTIFICATION_EVENT; prop.Property.Flags = KSPROPERTY_TYPE_GET; result = WdmSyncIoctl(pPin->handle, IOCTL_KS_PROPERTY, &prop, sizeof(KSRTAUDIO_NOTIFICATION_EVENT_PROPERTY), &prop, sizeof(KSRTAUDIO_NOTIFICATION_EVENT_PROPERTY), NULL); if (result != paNoError) { PA_DEBUG(("Failed to unregister notification handle 0x%08X\n", handle)); } } PA_LOGL_; return result; } static PaError PinGetHwLatency(PaWinWdmPin* pPin, ULONG* pFifoSize, ULONG* pChipsetDelay, ULONG* pCodecDelay) { PaError result = paNoError; KSPROPERTY propIn; KSRTAUDIO_HWLATENCY propOut; PA_LOGE_; propIn.Set = KSPROPSETID_RtAudio; propIn.Id = KSPROPERTY_RTAUDIO_HWLATENCY; propIn.Flags = KSPROPERTY_TYPE_GET; result = WdmSyncIoctl(pPin->handle, IOCTL_KS_PROPERTY, &propIn, sizeof(KSPROPERTY), &propOut, sizeof(KSRTAUDIO_HWLATENCY), NULL); if (result == paNoError) { *pFifoSize = propOut.FifoSize; *pChipsetDelay = propOut.ChipsetDelay; *pCodecDelay = propOut.CodecDelay; } else { PA_DEBUG(("Failed to retrieve hardware FIFO size!\n")); } PA_LOGL_; return result; } /* This one is used for WaveRT */ static PaError PinGetAudioPositionDirect(PaWinWdmPin* pPin, ULONG* pPosition) { *pPosition = (*pPin->positionRegister); return paNoError; } /* This one also, but in case the driver hasn't implemented memory mapped access to the position register */ static PaError PinGetAudioPositionViaIOCTL(PaWinWdmPin* pPin, ULONG* pPosition) { PaError result = paNoError; KSPROPERTY propIn; KSAUDIO_POSITION propOut; PA_LOGE_; propIn.Set = KSPROPSETID_Audio; propIn.Id = KSPROPERTY_AUDIO_POSITION; propIn.Flags = KSPROPERTY_TYPE_GET; result = WdmSyncIoctl(pPin->handle, IOCTL_KS_PROPERTY, &propIn, sizeof(KSPROPERTY), &propOut, sizeof(KSAUDIO_POSITION), NULL); if (result == paNoError) { *pPosition = (ULONG)(propOut.PlayOffset); } else { PA_DEBUG(("Failed to get audio position!\n")); } PA_LOGL_; return result; } /***********************************************************************************************/ /** * Create a new filter object. */ static PaWinWdmFilter* FilterNew( PaWDMKSType type, DWORD devNode, const wchar_t* filterName, const wchar_t* friendlyName, PaError* error ) { PaWinWdmFilter* filter = 0; PaError result; /* Allocate the new filter object */ filter = (PaWinWdmFilter*)PaUtil_AllocateMemory( sizeof(PaWinWdmFilter) ); if( !filter ) { result = paInsufficientMemory; goto error; } PA_DEBUG(("FilterNew: Creating filter '%S'\n", friendlyName)); /* Set type flag */ filter->devInfo.streamingType = type; /* Store device node */ filter->deviceNode = devNode; /* Zero the filter object - done by AllocateMemory */ /* memset( (void*)filter, 0, sizeof(PaWinWdmFilter) ); */ /* Copy the filter name */ wcsncpy(filter->devInfo.filterPath, filterName, MAX_PATH); /* Copy the friendly name */ wcsncpy(filter->friendlyName, friendlyName, MAX_PATH); PA_DEBUG(("FilterNew: Opening filter...\n", friendlyName)); /* Open the filter handle */ result = FilterUse(filter); if( result != paNoError ) { goto error; } /* Get pin count */ result = WdmGetPinPropertySimple ( filter->handle, 0, &KSPROPSETID_Pin, KSPROPERTY_PIN_CTYPES, &filter->pinCount, sizeof(filter->pinCount), NULL); if( result != paNoError) { goto error; } /* Get connections & nodes for filter */ result = WdmGetPropertyMulti( filter->handle, &KSPROPSETID_Topology, KSPROPERTY_TOPOLOGY_CONNECTIONS, &filter->connections); if( result != paNoError) { goto error; } result = WdmGetPropertyMulti( filter->handle, &KSPROPSETID_Topology, KSPROPERTY_TOPOLOGY_NODES, &filter->nodes); if( result != paNoError) { goto error; } /* For debugging purposes */ DumpConnectionsAndNodes(filter); /* Get product GUID (it might not be supported) */ { KSCOMPONENTID compId; if (WdmGetPropertySimple(filter->handle, &KSPROPSETID_General, KSPROPERTY_GENERAL_COMPONENTID, &compId, sizeof(KSCOMPONENTID)) == paNoError) { filter->devInfo.deviceProductGuid = compId.Product; } } /* This section is not executed for topology filters */ if (type != Type_kNotUsed) { /* Initialize the pins */ result = FilterInitializePins(filter); if( result != paNoError) { goto error; } } /* Close the filter handle for now * It will be opened later when needed */ FilterRelease(filter); *error = paNoError; return filter; error: PA_DEBUG(("FilterNew: Error %d\n", result)); /* Error cleanup */ FilterFree(filter); *error = result; return NULL; } /** * Add reference to filter */ static void FilterAddRef( PaWinWdmFilter* filter ) { if (filter != 0) { filter->filterRefCount++; } } /** * Initialize the pins of the filter. This is separated from FilterNew because this might fail if there is another * process using the pin(s). */ PaError FilterInitializePins( PaWinWdmFilter* filter ) { PaError result = paNoError; int pinId; if (filter->devInfo.streamingType == Type_kNotUsed) return paNoError; if (filter->pins != NULL) return paNoError; /* Allocate pointer array to hold the pins */ filter->pins = (PaWinWdmPin**)PaUtil_AllocateMemory( sizeof(PaWinWdmPin*) * filter->pinCount ); if( !filter->pins ) { result = paInsufficientMemory; goto error; } /* Create all the pins we can */ for(pinId = 0; pinId < filter->pinCount; pinId++) { /* Create the pin with this Id */ PaWinWdmPin* newPin; newPin = PinNew(filter, pinId, &result); if( result == paInsufficientMemory ) goto error; if( newPin != NULL ) { filter->pins[pinId] = newPin; ++filter->validPinCount; } } if (filter->validPinCount == 0) { result = paDeviceUnavailable; goto error; } return paNoError; error: if (filter->pins) { for (pinId = 0; pinId < filter->pinCount; ++pinId) { if (filter->pins[pinId]) { PaUtil_FreeMemory(filter->pins[pinId]); filter->pins[pinId] = 0; } } PaUtil_FreeMemory( filter->pins ); filter->pins = 0; } return result; } /** * Free a previously created filter */ static void FilterFree(PaWinWdmFilter* filter) { int pinId; PA_LOGL_; if( filter ) { if (--filter->filterRefCount > 0) { /* Ok, a stream has a ref count to this filter */ return; } if (filter->topologyFilter) { FilterFree(filter->topologyFilter); filter->topologyFilter = 0; } if ( filter->pins ) { for( pinId = 0; pinId < filter->pinCount; pinId++ ) PinFree(filter->pins[pinId]); PaUtil_FreeMemory( filter->pins ); filter->pins = 0; } if( filter->connections ) { PaUtil_FreeMemory(filter->connections); filter->connections = 0; } if( filter->nodes ) { PaUtil_FreeMemory(filter->nodes); filter->nodes = 0; } if( filter->handle ) CloseHandle( filter->handle ); PaUtil_FreeMemory( filter ); } PA_LOGE_; } /** * Reopen the filter handle if necessary so it can be used **/ static PaError FilterUse(PaWinWdmFilter* filter) { assert( filter ); PA_LOGE_; if( filter->handle == NULL ) { /* Open the filter */ filter->handle = CreateFileW( filter->devInfo.filterPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); if( filter->handle == NULL ) { return paDeviceUnavailable; } } filter->usageCount++; PA_LOGL_; return paNoError; } /** * Release the filter handle if nobody is using it **/ static void FilterRelease(PaWinWdmFilter* filter) { assert( filter ); assert( filter->usageCount > 0 ); PA_LOGE_; /* Check first topology filter, if used */ if (filter->topologyFilter != NULL && filter->topologyFilter->handle != NULL) { FilterRelease(filter->topologyFilter); } filter->usageCount--; if( filter->usageCount == 0 ) { if( filter->handle != NULL ) { CloseHandle( filter->handle ); filter->handle = NULL; } } PA_LOGL_; } /** * Create a render or playback pin using the supplied format **/ static PaWinWdmPin* FilterCreatePin(PaWinWdmFilter* filter, int pinId, const WAVEFORMATEX* wfex, PaError* error) { PaError result = paNoError; PaWinWdmPin* pin = NULL; assert( filter ); assert( pinId < filter->pinCount ); pin = filter->pins[pinId]; assert( pin ); result = PinSetFormat(pin,wfex); if( result == paNoError ) { result = PinInstantiate(pin); } *error = result; return result == paNoError ? pin : 0; } static const wchar_t kUsbPrefix[] = L"\\\\?\\USB"; static BOOL IsUSBDevice(const wchar_t* devicePath) { /* Alex Lessard pointed out that different devices might present the device path with lower case letters. */ return (_wcsnicmp(devicePath, kUsbPrefix, sizeof(kUsbPrefix)/sizeof(kUsbPrefix[0]) ) == 0); } /* This should make it more language tolerant, I hope... */ static const wchar_t kUsbNamePrefix[] = L"USB Audio"; static BOOL IsNameUSBAudioDevice(const wchar_t* friendlyName) { return (_wcsnicmp(friendlyName, kUsbNamePrefix, sizeof(kUsbNamePrefix)/sizeof(kUsbNamePrefix[0])) == 0); } typedef enum _tag_EAlias { Alias_kRender = (1<<0), Alias_kCapture = (1<<1), Alias_kRealtime = (1<<2), } EAlias; /* Trim whitespace from string */ static void TrimString(wchar_t* str, size_t length) { wchar_t* s = str; wchar_t* e = 0; /* Find start of string */ while (iswspace(*s)) ++s; e=s+min(length,wcslen(s))-1; /* Find end of string */ while(e>s && iswspace(*e)) --e; ++e; length = e - s; memmove(str, s, length * sizeof(wchar_t)); str[length] = 0; } /** * Build the list of available filters * Use the SetupDi API to enumerate all devices in the KSCATEGORY_AUDIO which * have a KSCATEGORY_RENDER or KSCATEGORY_CAPTURE alias. For each of these * devices initialise a PaWinWdmFilter structure by calling our NewFilter() * function. We enumerate devices twice, once to count how many there are, * and once to initialize the PaWinWdmFilter structures. * * Vista and later: Also check KSCATEGORY_REALTIME for WaveRT devices. */ //PaError BuildFilterList( PaWinWdmHostApiRepresentation* wdmHostApi, int* noOfPaDevices ) PaWinWdmFilter** BuildFilterList( int* pFilterCount, int* pNoOfPaDevices, PaError* pResult ) { PaWinWdmFilter** ppFilters = NULL; HDEVINFO handle = NULL; int device; int invalidDevices; int slot; SP_DEVICE_INTERFACE_DATA interfaceData; SP_DEVICE_INTERFACE_DATA aliasData; SP_DEVINFO_DATA devInfoData; int noError; const int sizeInterface = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + (MAX_PATH * sizeof(WCHAR)); unsigned char interfaceDetailsArray[sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + (MAX_PATH * sizeof(WCHAR))]; SP_DEVICE_INTERFACE_DETAIL_DATA_W* devInterfaceDetails = (SP_DEVICE_INTERFACE_DETAIL_DATA_W*)interfaceDetailsArray; const GUID* category = (const GUID*)&KSCATEGORY_AUDIO; const GUID* alias_render = (const GUID*)&KSCATEGORY_RENDER; const GUID* alias_capture = (const GUID*)&KSCATEGORY_CAPTURE; const GUID* category_realtime = (const GUID*)&KSCATEGORY_REALTIME; DWORD aliasFlags; PaWDMKSType streamingType; int filterCount = 0; int noOfPaDevices = 0; PA_LOGE_; assert(pFilterCount != NULL); assert(pNoOfPaDevices != NULL); assert(pResult != NULL); devInterfaceDetails->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W); *pFilterCount = 0; *pNoOfPaDevices = 0; /* Open a handle to search for devices (filters) */ handle = SetupDiGetClassDevs(category,NULL,NULL,DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if( handle == INVALID_HANDLE_VALUE ) { *pResult = paUnanticipatedHostError; return NULL; } PA_DEBUG(("Setup called\n")); /* First let's count the number of devices so we can allocate a list */ invalidDevices = 0; for( device = 0;;device++ ) { interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); interfaceData.Reserved = 0; aliasData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); aliasData.Reserved = 0; noError = SetupDiEnumDeviceInterfaces(handle,NULL,category,device,&interfaceData); PA_DEBUG(("Enum called\n")); if( !noError ) break; /* No more devices */ /* Check this one has the render or capture alias */ aliasFlags = 0; noError = SetupDiGetDeviceInterfaceAlias(handle,&interfaceData,alias_render,&aliasData); PA_DEBUG(("noError = %d\n",noError)); if(noError) { if(aliasData.Flags && (!(aliasData.Flags & SPINT_REMOVED))) { PA_DEBUG(("Device %d has render alias\n",device)); aliasFlags |= Alias_kRender; /* Has render alias */ } else { PA_DEBUG(("Device %d has no render alias\n",device)); } } noError = SetupDiGetDeviceInterfaceAlias(handle,&interfaceData,alias_capture,&aliasData); if(noError) { if(aliasData.Flags && (!(aliasData.Flags & SPINT_REMOVED))) { PA_DEBUG(("Device %d has capture alias\n",device)); aliasFlags |= Alias_kCapture; /* Has capture alias */ } else { PA_DEBUG(("Device %d has no capture alias\n",device)); } } if(!aliasFlags) invalidDevices++; /* This was not a valid capture or render audio device */ } /* Remember how many there are */ filterCount = device-invalidDevices; PA_DEBUG(("Interfaces found: %d\n",device-invalidDevices)); /* Now allocate the list of pointers to devices */ ppFilters = (PaWinWdmFilter**)PaUtil_AllocateMemory( sizeof(PaWinWdmFilter*) * filterCount); if( ppFilters == 0 ) { if(handle != NULL) SetupDiDestroyDeviceInfoList(handle); *pResult = paInsufficientMemory; return NULL; } /* Now create filter objects for each interface found */ slot = 0; for( device = 0;;device++ ) { interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); interfaceData.Reserved = 0; aliasData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); aliasData.Reserved = 0; devInfoData.cbSize = sizeof(SP_DEVINFO_DATA); devInfoData.Reserved = 0; streamingType = Type_kWaveCyclic; noError = SetupDiEnumDeviceInterfaces(handle,NULL,category,device,&interfaceData); if( !noError ) break; /* No more devices */ /* Check this one has the render or capture alias */ aliasFlags = 0; noError = SetupDiGetDeviceInterfaceAlias(handle,&interfaceData,alias_render,&aliasData); if(noError) { if(aliasData.Flags && (!(aliasData.Flags & SPINT_REMOVED))) { PA_DEBUG(("Device %d has render alias\n",device)); aliasFlags |= Alias_kRender; /* Has render alias */ } } noError = SetupDiGetDeviceInterfaceAlias(handle,&interfaceData,alias_capture,&aliasData); if(noError) { if(aliasData.Flags && (!(aliasData.Flags & SPINT_REMOVED))) { PA_DEBUG(("Device %d has capture alias\n",device)); aliasFlags |= Alias_kCapture; /* Has capture alias */ } } if(!aliasFlags) { continue; /* This was not a valid capture or render audio device */ } else { /* Check if filter is WaveRT, if not it is a WaveCyclic */ noError = SetupDiGetDeviceInterfaceAlias(handle,&interfaceData,category_realtime,&aliasData); if (noError) { PA_DEBUG(("Device %d has realtime alias\n",device)); aliasFlags |= Alias_kRealtime; streamingType = Type_kWaveRT; } } noError = SetupDiGetDeviceInterfaceDetailW(handle,&interfaceData,devInterfaceDetails,sizeInterface,NULL,&devInfoData); if( noError ) { DWORD type; WCHAR friendlyName[MAX_PATH] = {0}; DWORD sizeFriendlyName; PaWinWdmFilter* newFilter = 0; PaError result = paNoError; /* Try to get the "friendly name" for this interface */ sizeFriendlyName = sizeof(friendlyName); if (IsEarlierThanVista() && IsUSBDevice(devInterfaceDetails->DevicePath)) { /* XP and USB audio device needs to look elsewhere, otherwise it'll only be a "USB Audio Device". Not very literate. */ if (!SetupDiGetDeviceRegistryPropertyW(handle, &devInfoData, SPDRP_LOCATION_INFORMATION, &type, (BYTE*)friendlyName, sizeof(friendlyName), NULL)) { friendlyName[0] = 0; } } if (friendlyName[0] == 0 || IsNameUSBAudioDevice(friendlyName)) { /* Fix contributed by Ben Allison * Removed KEY_SET_VALUE from flags on following call * as its causes failure when running without admin rights * and it was not required */ HKEY hkey=SetupDiOpenDeviceInterfaceRegKey(handle,&interfaceData,0,KEY_QUERY_VALUE); if(hkey!=INVALID_HANDLE_VALUE) { noError = RegQueryValueExW(hkey,L"FriendlyName",0,&type,(BYTE*)friendlyName,&sizeFriendlyName); if( noError == ERROR_SUCCESS ) { PA_DEBUG(("Interface %d, Name: %s\n",device,friendlyName)); RegCloseKey(hkey); } else { friendlyName[0] = 0; } } } TrimString(friendlyName, sizeFriendlyName); newFilter = FilterNew(streamingType, devInfoData.DevInst, devInterfaceDetails->DevicePath, friendlyName, &result); if( result == paNoError ) { int pin; unsigned filterIOs = 0; /* Increment number of "devices" */ for (pin = 0; pin < newFilter->pinCount; ++pin) { PaWinWdmPin* pPin = newFilter->pins[pin]; if (pPin == NULL) continue; filterIOs += max(1, pPin->inputCount); } noOfPaDevices += filterIOs; PA_DEBUG(("Filter (%s) created with %d valid pins (total I/Os: %u)\n", ((newFilter->devInfo.streamingType==Type_kWaveRT)?"WaveRT":"WaveCyclic"), newFilter->validPinCount, filterIOs)); assert(slot < filterCount); ppFilters[slot] = newFilter; slot++; } else { PA_DEBUG(("Filter NOT created\n")); /* As there are now less filters than we initially thought * we must reduce the count by one */ filterCount--; } } } /* Clean up */ if(handle != NULL) SetupDiDestroyDeviceInfoList(handle); *pFilterCount = filterCount; *pNoOfPaDevices = noOfPaDevices; return ppFilters; } typedef struct PaNameHashIndex { unsigned index; unsigned count; ULONG hash; struct PaNameHashIndex *next; } PaNameHashIndex; typedef struct PaNameHashObject { PaNameHashIndex* list; PaUtilAllocationGroup* allocGroup; } PaNameHashObject; static ULONG GetNameHash(const wchar_t* str, const BOOL input) { /* This is to make sure that a name that exists as both input & output won't get the same hash value */ const ULONG fnv_prime = (input ? 0x811C9DD7 : 0x811FEB0B); ULONG hash = 0; for(; *str != 0; str++) { hash *= fnv_prime; hash ^= (*str); } assert(hash != 0); return hash; } static PaError CreateHashEntry(PaNameHashObject* obj, const wchar_t* name, const BOOL input) { ULONG hash = GetNameHash(name, input); PaNameHashIndex * pLast = NULL; PaNameHashIndex * p = obj->list; while (p != 0) { if (p->hash == hash) { break; } pLast = p; p = p->next; } if (p == NULL) { p = (PaNameHashIndex*)PaUtil_GroupAllocateMemory(obj->allocGroup, sizeof(PaNameHashIndex)); if (p == NULL) { return paInsufficientMemory; } p->hash = hash; p->count = 1; if (pLast != 0) { assert(pLast->next == 0); pLast->next = p; } if (obj->list == 0) { obj->list = p; } } else { ++p->count; } return paNoError; } static PaError InitNameHashObject(PaNameHashObject* obj, PaWinWdmFilter* pFilter) { int i; obj->allocGroup = PaUtil_CreateAllocationGroup(); if (obj->allocGroup == NULL) { return paInsufficientMemory; } for (i = 0; i < pFilter->pinCount; ++i) { unsigned m; PaWinWdmPin* pin = pFilter->pins[i]; if (pin == NULL) continue; for (m = 0; m < max(1, pin->inputCount); ++m) { const BOOL isInput = (pin->dataFlow == KSPIN_DATAFLOW_OUT); const wchar_t* name = (pin->inputs == NULL) ? pin->friendlyName : pin->inputs[m]->friendlyName; PaError result = CreateHashEntry(obj, name, isInput); if (result != paNoError) { return result; } } } return paNoError; } static void DeinitNameHashObject(PaNameHashObject* obj) { assert(obj != 0); PaUtil_FreeAllAllocations(obj->allocGroup); PaUtil_DestroyAllocationGroup(obj->allocGroup); memset(obj, 0, sizeof(PaNameHashObject)); } static unsigned GetNameIndex(PaNameHashObject* obj, const wchar_t* name, const BOOL input) { ULONG hash = GetNameHash(name, input); PaNameHashIndex* p = obj->list; while (p != NULL) { if (p->hash == hash) { if (p->count > 1) { return (++p->index); } else { return 0; } } p = p->next; } // Should never get here!! assert(FALSE); return 0; } static PaError ScanDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, PaHostApiIndex hostApiIndex, void **scanResults, int *newDeviceCount ) { PaWinWdmHostApiRepresentation *wdmHostApi = (PaWinWdmHostApiRepresentation*)hostApi; PaError result = paNoError; PaWinWdmFilter** ppFilters = 0; PaWinWDMScanDeviceInfosResults *outArgument = 0; int filterCount = 0; int totalDeviceCount = 0; int idxDevice = 0; ppFilters = BuildFilterList( &filterCount, &totalDeviceCount, &result ); if( result != paNoError ) { goto error; } if( totalDeviceCount > 0 ) { PaWinWdmDeviceInfo *deviceInfoArray = 0; int idxFilter; int i; /* Allocate the out param for all the info we need */ outArgument = (PaWinWDMScanDeviceInfosResults *) PaUtil_GroupAllocateMemory( wdmHostApi->allocations, sizeof(PaWinWDMScanDeviceInfosResults) ); if( !outArgument ) { result = paInsufficientMemory; goto error; } outArgument->defaultInputDevice = paNoDevice; outArgument->defaultOutputDevice = paNoDevice; outArgument->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( wdmHostApi->allocations, sizeof(PaDeviceInfo*) * totalDeviceCount ); if( !outArgument->deviceInfos ) { result = paInsufficientMemory; goto error; } /* allocate all device info structs in a contiguous block */ deviceInfoArray = (PaWinWdmDeviceInfo*)PaUtil_GroupAllocateMemory( wdmHostApi->allocations, sizeof(PaWinWdmDeviceInfo) * totalDeviceCount ); if( !deviceInfoArray ) { result = paInsufficientMemory; goto error; } /* Make sure all items in array */ for( i = 0 ; i < totalDeviceCount; ++i ) { PaDeviceInfo *deviceInfo = &deviceInfoArray[i].inheritedDeviceInfo; deviceInfo->structVersion = 2; deviceInfo->hostApi = hostApiIndex; deviceInfo->name = 0; outArgument->deviceInfos[ i ] = deviceInfo; } idxDevice = 0; for (idxFilter = 0; idxFilter < filterCount; ++idxFilter) { PaNameHashObject nameHash = {0}; PaWinWdmFilter* pFilter = ppFilters[idxFilter]; if( pFilter == NULL ) continue; if (InitNameHashObject(&nameHash, pFilter) != paNoError) { DeinitNameHashObject(&nameHash); continue; } for (i = 0; i < pFilter->pinCount; ++i) { unsigned m; ULONG nameIndex = 0; ULONG nameIndexHash = 0; PaWinWdmPin* pin = pFilter->pins[i]; if (pin == NULL) continue; for (m = 0; m < max(1, pin->inputCount); ++m) { PaWinWdmDeviceInfo *wdmDeviceInfo = (PaWinWdmDeviceInfo *)outArgument->deviceInfos[idxDevice]; PaDeviceInfo *deviceInfo = &wdmDeviceInfo->inheritedDeviceInfo; wchar_t localCompositeName[MAX_PATH]; unsigned nameIndex = 0; const BOOL isInput = (pin->dataFlow == KSPIN_DATAFLOW_OUT); wdmDeviceInfo->filter = pFilter; deviceInfo->structVersion = 2; deviceInfo->hostApi = hostApiIndex; deviceInfo->name = wdmDeviceInfo->compositeName; /* deviceInfo->hostApiSpecificDeviceInfo = &pFilter->devInfo; */ wdmDeviceInfo->pin = pin->pinId; /* Get the name of the "device" */ if (pin->inputs == NULL) { wcsncpy(localCompositeName, pin->friendlyName, MAX_PATH); wdmDeviceInfo->muxPosition = -1; wdmDeviceInfo->endpointPinId = pin->endpointPinId; } else { PaWinWdmMuxedInput* input = pin->inputs[m]; wcsncpy(localCompositeName, input->friendlyName, MAX_PATH); wdmDeviceInfo->muxPosition = (int)m; wdmDeviceInfo->endpointPinId = input->endpointPinId; } { /* Get base length */ size_t n = wcslen(localCompositeName); /* Check if there are more entries with same name (which might very well be the case), if there are, the name will be postfixed with an index. */ nameIndex = GetNameIndex(&nameHash, localCompositeName, isInput); if (nameIndex > 0) { /* This name has multiple instances, so we post fix with a number */ n += _snwprintf(localCompositeName + n, MAX_PATH - n, L" %u", nameIndex); } /* Postfix with filter name */ _snwprintf(localCompositeName + n, MAX_PATH - n, L" (%s)", pFilter->friendlyName); } /* Convert wide char string to utf-8 */ WideCharToMultiByte(CP_UTF8, 0, localCompositeName, -1, wdmDeviceInfo->compositeName, MAX_PATH, NULL, NULL); /* NB! WDM/KS has no concept of a full-duplex device, each pin is either an input or and output */ if (isInput) { /* INPUT ! */ deviceInfo->maxInputChannels = pin->maxChannels; deviceInfo->maxOutputChannels = 0; if (outArgument->defaultInputDevice == paNoDevice) { outArgument->defaultInputDevice = idxDevice; } } else { /* OUTPUT ! */ deviceInfo->maxInputChannels = 0; deviceInfo->maxOutputChannels = pin->maxChannels; if (outArgument->defaultOutputDevice == paNoDevice) { outArgument->defaultOutputDevice = idxDevice; } } /* These low values are not very useful because * a) The lowest latency we end up with can depend on many factors such * as the device buffer sizes/granularities, sample rate, channels and format * b) We cannot know the device buffer sizes until we try to open/use it at * a particular setting * So: we give 512x48000Hz frames as the default low input latency **/ switch (pFilter->devInfo.streamingType) { case Type_kWaveCyclic: if (IsEarlierThanVista()) { /* XP doesn't tolerate low latency, unless the Process Priority Class is set to REALTIME_PRIORITY_CLASS through SetPriorityClass, then 10 ms is quite feasible. However, one should then bear in mind that ALL of the process is running in REALTIME_PRIORITY_CLASS, which might not be appropriate for an application with a GUI . In this case it is advisable to separate the audio engine in another process and use IPC to communicate with it. */ deviceInfo->defaultLowInputLatency = 0.02; deviceInfo->defaultLowOutputLatency = 0.02; } else { /* This is a conservative estimate. Most WaveCyclic drivers will limit the available latency, but f.i. my Edirol PCR-A30 can reach 3 ms latency easily... */ deviceInfo->defaultLowInputLatency = 0.01; deviceInfo->defaultLowOutputLatency = 0.01; } deviceInfo->defaultHighInputLatency = (4096.0/48000.0); deviceInfo->defaultHighOutputLatency = (4096.0/48000.0); deviceInfo->defaultSampleRate = (double)(pin->defaultSampleRate); break; case Type_kWaveRT: /* This is also a conservative estimate, based on WaveRT polled mode. In polled mode, the latency will be dictated by the buffer size given by the driver. */ deviceInfo->defaultLowInputLatency = 0.01; deviceInfo->defaultLowOutputLatency = 0.01; deviceInfo->defaultHighInputLatency = 0.04; deviceInfo->defaultHighOutputLatency = 0.04; deviceInfo->defaultSampleRate = (double)(pin->defaultSampleRate); break; default: assert(0); break; } /* Add reference to filter */ FilterAddRef(wdmDeviceInfo->filter); assert(idxDevice < totalDeviceCount); ++idxDevice; } } /* If no one has add ref'd the filter, drop it */ if (pFilter->filterRefCount == 0) { FilterFree(pFilter); } /* Deinitialize name hash object */ DeinitNameHashObject(&nameHash); } } *scanResults = outArgument; *newDeviceCount = idxDevice; return result; error: result = DisposeDeviceInfos(hostApi, outArgument, totalDeviceCount); return result; } static PaError CommitDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, PaHostApiIndex index, void *scanResults, int deviceCount ) { PaWinWdmHostApiRepresentation *wdmHostApi = (PaWinWdmHostApiRepresentation*)hostApi; hostApi->info.deviceCount = 0; hostApi->info.defaultInputDevice = paNoDevice; hostApi->info.defaultOutputDevice = paNoDevice; /* Free any old memory which might be in the device info */ if( hostApi->deviceInfos ) { PaWinWDMScanDeviceInfosResults* localScanResults = (PaWinWDMScanDeviceInfosResults*)PaUtil_GroupAllocateMemory( wdmHostApi->allocations, sizeof(PaWinWDMScanDeviceInfosResults)); localScanResults->deviceInfos = hostApi->deviceInfos; DisposeDeviceInfos(hostApi, &localScanResults, hostApi->info.deviceCount); hostApi->deviceInfos = NULL; } if( scanResults != NULL ) { PaWinWDMScanDeviceInfosResults *scanDeviceInfosResults = ( PaWinWDMScanDeviceInfosResults * ) scanResults; if( deviceCount > 0 ) { /* use the array allocated in ScanDeviceInfos() as our deviceInfos */ hostApi->deviceInfos = scanDeviceInfosResults->deviceInfos; hostApi->info.defaultInputDevice = scanDeviceInfosResults->defaultInputDevice; hostApi->info.defaultOutputDevice = scanDeviceInfosResults->defaultOutputDevice; hostApi->info.deviceCount = deviceCount; } PaUtil_GroupFreeMemory( wdmHostApi->allocations, scanDeviceInfosResults ); } return paNoError; } static PaError DisposeDeviceInfos( struct PaUtilHostApiRepresentation *hostApi, void *scanResults, int deviceCount ) { PaWinWdmHostApiRepresentation *winDsHostApi = (PaWinWdmHostApiRepresentation*)hostApi; if( scanResults != NULL ) { PaWinWDMScanDeviceInfosResults *scanDeviceInfosResults = ( PaWinWDMScanDeviceInfosResults * ) scanResults; if( scanDeviceInfosResults->deviceInfos ) { int i; for (i = 0; i < deviceCount; ++i) { PaWinWdmDeviceInfo* pDevice = (PaWinWdmDeviceInfo*)scanDeviceInfosResults->deviceInfos[i]; if (pDevice->filter != 0) { FilterFree(pDevice->filter); } } PaUtil_GroupFreeMemory( winDsHostApi->allocations, scanDeviceInfosResults->deviceInfos[0] ); /* all device info structs are allocated in a block so we can destroy them here */ PaUtil_GroupFreeMemory( winDsHostApi->allocations, scanDeviceInfosResults->deviceInfos ); } PaUtil_GroupFreeMemory( winDsHostApi->allocations, scanDeviceInfosResults ); } return paNoError; } PaError PaWinWdm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) { PaError result = paNoError; int deviceCount = 0; void *scanResults = 0; PaWinWdmHostApiRepresentation *wdmHostApi = NULL; PA_LOGE_; #ifdef PA_WDMKS_SET_TREF tRef = PaUtil_GetTime(); #endif /* Attempt to load the KSUSER.DLL without which we cannot create pins We will unload this on termination */ if(DllKsUser == NULL) { DllKsUser = LoadLibrary(TEXT("ksuser.dll")); if(DllKsUser == NULL) goto error; } FunctionKsCreatePin = (KSCREATEPIN*)GetProcAddress(DllKsUser, "KsCreatePin"); if(FunctionKsCreatePin == NULL) goto error; /* Attempt to load AVRT.DLL, if we can't, then we'll just use time critical prio instead... */ if(paWinWDMKSAvRtEntryPoints.hInstance == NULL) { paWinWDMKSAvRtEntryPoints.hInstance = LoadLibrary(TEXT("avrt.dll")); if (paWinWDMKSAvRtEntryPoints.hInstance != NULL) { paWinWDMKSAvRtEntryPoints.AvSetMmThreadCharacteristics = (HANDLE(WINAPI*)(LPCSTR,LPDWORD))GetProcAddress(paWinWDMKSAvRtEntryPoints.hInstance,"AvSetMmThreadCharacteristicsA"); paWinWDMKSAvRtEntryPoints.AvRevertMmThreadCharacteristics = (BOOL(WINAPI*)(HANDLE))GetProcAddress(paWinWDMKSAvRtEntryPoints.hInstance, "AvRevertMmThreadCharacteristics"); paWinWDMKSAvRtEntryPoints.AvSetMmThreadPriority = (BOOL(WINAPI*)(HANDLE,PA_AVRT_PRIORITY))GetProcAddress(paWinWDMKSAvRtEntryPoints.hInstance, "AvSetMmThreadPriority"); } } wdmHostApi = (PaWinWdmHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaWinWdmHostApiRepresentation) ); if( !wdmHostApi ) { result = paInsufficientMemory; goto error; } wdmHostApi->allocations = PaUtil_CreateAllocationGroup(); if( !wdmHostApi->allocations ) { result = paInsufficientMemory; goto error; } *hostApi = &wdmHostApi->inheritedHostApiRep; (*hostApi)->info.structVersion = 1; (*hostApi)->info.type = paWDMKS; (*hostApi)->info.name = "Windows WDM-KS"; /* these are all updated by CommitDeviceInfos() */ (*hostApi)->info.deviceCount = 0; (*hostApi)->info.defaultInputDevice = paNoDevice; (*hostApi)->info.defaultOutputDevice = paNoDevice; (*hostApi)->deviceInfos = 0; result = ScanDeviceInfos(&wdmHostApi->inheritedHostApiRep, hostApiIndex, &scanResults, &deviceCount); if (result != paNoError) { goto error; } CommitDeviceInfos(&wdmHostApi->inheritedHostApiRep, hostApiIndex, scanResults, deviceCount); (*hostApi)->Terminate = Terminate; (*hostApi)->OpenStream = OpenStream; (*hostApi)->IsFormatSupported = IsFormatSupported; /* In preparation for hotplug (*hostApi)->ScanDeviceInfos = ScanDeviceInfos; (*hostApi)->CommitDeviceInfos = CommitDeviceInfos; (*hostApi)->DisposeDeviceInfos = DisposeDeviceInfos; */ PaUtil_InitializeStreamInterface( &wdmHostApi->callbackStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, GetStreamCpuLoad, PaUtil_DummyRead, PaUtil_DummyWrite, PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); PaUtil_InitializeStreamInterface( &wdmHostApi->blockingStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, PaUtil_DummyGetCpuLoad, ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable ); PA_LOGL_; return result; error: Terminate( (PaUtilHostApiRepresentation*)wdmHostApi ); PA_LOGL_; return result; } static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) { PaWinWdmHostApiRepresentation *wdmHostApi = (PaWinWdmHostApiRepresentation*)hostApi; PA_LOGE_; /* Do not unload the libraries */ if( DllKsUser != NULL ) { FreeLibrary( DllKsUser ); DllKsUser = NULL; } if( paWinWDMKSAvRtEntryPoints.hInstance != NULL ) { FreeLibrary( paWinWDMKSAvRtEntryPoints.hInstance ); paWinWDMKSAvRtEntryPoints.hInstance = NULL; } if( wdmHostApi) { PaWinWDMScanDeviceInfosResults* localScanResults = (PaWinWDMScanDeviceInfosResults*)PaUtil_GroupAllocateMemory( wdmHostApi->allocations, sizeof(PaWinWDMScanDeviceInfosResults)); localScanResults->deviceInfos = hostApi->deviceInfos; DisposeDeviceInfos(hostApi, localScanResults, hostApi->info.deviceCount); if( wdmHostApi->allocations ) { PaUtil_FreeAllAllocations( wdmHostApi->allocations ); PaUtil_DestroyAllocationGroup( wdmHostApi->allocations ); } PaUtil_FreeMemory( wdmHostApi ); } PA_LOGL_; } static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { int inputChannelCount, outputChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; PaWinWdmHostApiRepresentation *wdmHostApi = (PaWinWdmHostApiRepresentation*)hostApi; PaWinWdmFilter* pFilter; int result = paFormatIsSupported; WAVEFORMATEXTENSIBLE wfx; PaWinWaveFormatChannelMask channelMask; PA_LOGE_; if( inputParameters ) { PaWinWdmDeviceInfo* pDeviceInfo = (PaWinWdmDeviceInfo*)wdmHostApi->inheritedHostApiRep.deviceInfos[inputParameters->device]; PaWinWdmPin* pin; unsigned fmt; unsigned long testFormat = 0; unsigned validBits = 0; inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( inputSampleFormat & paCustomFormat ) { PaWinWDM_SetLastErrorInfo(paSampleFormatNotSupported, "IsFormatSupported: Custom input format not supported"); return paSampleFormatNotSupported; } /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) { PaWinWDM_SetLastErrorInfo(paInvalidDevice, "IsFormatSupported: paUseHostApiSpecificDeviceSpecification not supported"); return paInvalidDevice; } /* check that input device can support inputChannelCount */ if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) { PaWinWDM_SetLastErrorInfo(paInvalidChannelCount, "IsFormatSupported: Invalid input channel count"); return paInvalidChannelCount; } /* validate inputStreamInfo */ if( inputParameters->hostApiSpecificStreamInfo ) { PaWinWDM_SetLastErrorInfo(paIncompatibleHostApiSpecificStreamInfo, "Host API stream info not supported"); return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } pFilter = pDeviceInfo->filter; pin = pFilter->pins[pDeviceInfo->pin]; /* Find out the testing format */ for (fmt = paFloat32; fmt <= paUInt8; fmt <<= 1) { if ((fmt & pin->formats) != 0) { /* Found a matching format! */ testFormat = fmt; break; } } if (testFormat == 0) { PaWinWDM_SetLastErrorInfo(result, "IsFormatSupported(capture) failed: no testformat found!"); return paUnanticipatedHostError; } /* Due to special considerations, WaveRT devices with paInt24 should be tested with paInt32 and valid bits = 24 (instead of 24 bit samples) */ if (pFilter->devInfo.streamingType == Type_kWaveRT && testFormat == paInt24) { PA_DEBUG(("IsFormatSupported (capture): WaveRT overriding testFormat paInt24 with paInt32 (24 valid bits)")); testFormat = paInt32; validBits = 24; } /* Check that the input format is supported */ channelMask = PaWin_DefaultChannelMask(inputChannelCount); PaWin_InitializeWaveFormatExtensible((PaWinWaveFormat*)&wfx, inputChannelCount, testFormat, PaWin_SampleFormatToLinearWaveFormatTag(testFormat), sampleRate, channelMask ); if (validBits != 0) { wfx.Samples.wValidBitsPerSample = validBits; } result = PinIsFormatSupported(pin, (const WAVEFORMATEX*)&wfx); if( result != paNoError ) { /* Try a WAVE_FORMAT_PCM instead */ PaWin_InitializeWaveFormatEx((PaWinWaveFormat*)&wfx, inputChannelCount, testFormat, PaWin_SampleFormatToLinearWaveFormatTag(testFormat), sampleRate); if (validBits != 0) { wfx.Samples.wValidBitsPerSample = validBits; } result = PinIsFormatSupported(pin, (const WAVEFORMATEX*)&wfx); if( result != paNoError ) { PaWinWDM_SetLastErrorInfo(result, "IsFormatSupported(capture) failed: sr=%u,ch=%u,bits=%u", wfx.Format.nSamplesPerSec, wfx.Format.nChannels, wfx.Format.wBitsPerSample); return result; } } } else { inputChannelCount = 0; } if( outputParameters ) { PaWinWdmDeviceInfo* pDeviceInfo = (PaWinWdmDeviceInfo*)wdmHostApi->inheritedHostApiRep.deviceInfos[outputParameters->device]; PaWinWdmPin* pin; unsigned fmt; unsigned long testFormat = 0; unsigned validBits = 0; outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( outputSampleFormat & paCustomFormat ) { PaWinWDM_SetLastErrorInfo(paSampleFormatNotSupported, "IsFormatSupported: Custom output format not supported"); return paSampleFormatNotSupported; } /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) { PaWinWDM_SetLastErrorInfo(paInvalidDevice, "IsFormatSupported: paUseHostApiSpecificDeviceSpecification not supported"); return paInvalidDevice; } /* check that output device can support outputChannelCount */ if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) { PaWinWDM_SetLastErrorInfo(paInvalidChannelCount, "Invalid output channel count"); return paInvalidChannelCount; } /* validate outputStreamInfo */ if( outputParameters->hostApiSpecificStreamInfo ) { PaWinWDM_SetLastErrorInfo(paIncompatibleHostApiSpecificStreamInfo, "Host API stream info not supported"); return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } pFilter = pDeviceInfo->filter; pin = pFilter->pins[pDeviceInfo->pin]; /* Find out the testing format */ for (fmt = paFloat32; fmt <= paUInt8; fmt <<= 1) { if ((fmt & pin->formats) != 0) { /* Found a matching format! */ testFormat = fmt; break; } } if (testFormat == 0) { PaWinWDM_SetLastErrorInfo(result, "IsFormatSupported(render) failed: no testformat found!"); return paUnanticipatedHostError; } /* Due to special considerations, WaveRT devices with paInt24 should be tested with paInt32 and valid bits = 24 (instead of 24 bit samples) */ if (pFilter->devInfo.streamingType == Type_kWaveRT && testFormat == paInt24) { PA_DEBUG(("IsFormatSupported (render): WaveRT overriding testFormat paInt24 with paInt32 (24 valid bits)")); testFormat = paInt32; validBits = 24; } /* Check that the output format is supported */ channelMask = PaWin_DefaultChannelMask(outputChannelCount); PaWin_InitializeWaveFormatExtensible((PaWinWaveFormat*)&wfx, outputChannelCount, testFormat, PaWin_SampleFormatToLinearWaveFormatTag(testFormat), sampleRate, channelMask ); if (validBits != 0) { wfx.Samples.wValidBitsPerSample = validBits; } result = PinIsFormatSupported(pin, (const WAVEFORMATEX*)&wfx); if( result != paNoError ) { /* Try a WAVE_FORMAT_PCM instead */ PaWin_InitializeWaveFormatEx((PaWinWaveFormat*)&wfx, outputChannelCount, testFormat, PaWin_SampleFormatToLinearWaveFormatTag(testFormat), sampleRate); if (validBits != 0) { wfx.Samples.wValidBitsPerSample = validBits; } result = PinIsFormatSupported(pin, (const WAVEFORMATEX*)&wfx); if( result != paNoError ) { PaWinWDM_SetLastErrorInfo(result, "IsFormatSupported(render) failed: %u,%u,%u", wfx.Format.nSamplesPerSec, wfx.Format.nChannels, wfx.Format.wBitsPerSample); return result; } } } else { outputChannelCount = 0; } /* IMPLEMENT ME: - if a full duplex stream is requested, check that the combination of input and output parameters is supported if necessary - check that the device supports sampleRate Because the buffer adapter handles conversion between all standard sample formats, the following checks are only required if paCustomFormat is implemented, or under some other unusual conditions. - check that input device can support inputSampleFormat, or that we have the capability to convert from inputSampleFormat to a native format - check that output device can support outputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format */ if((inputChannelCount == 0)&&(outputChannelCount == 0)) { PaWinWDM_SetLastErrorInfo(paSampleFormatNotSupported, "No input or output channels defined"); result = paSampleFormatNotSupported; /* Not right error */ } PA_LOGL_; return result; } static void ResetStreamEvents(PaWinWdmStream* stream) { unsigned i; ResetEvent(stream->eventAbort); ResetEvent(stream->eventStreamStart[StreamStart_kOk]); ResetEvent(stream->eventStreamStart[StreamStart_kFailed]); for (i=0; icapture.noOfPackets; ++i) { if (stream->capture.events && stream->capture.events[i]) { ResetEvent(stream->capture.events[i]); } } for (i=0; irender.noOfPackets; ++i) { if (stream->render.events && stream->render.events[i]) { ResetEvent(stream->render.events[i]); } } } static void CloseStreamEvents(PaWinWdmStream* stream) { unsigned i; PaWinWdmIOInfo* ios[2] = { &stream->capture, &stream->render }; if (stream->eventAbort) { CloseHandle(stream->eventAbort); stream->eventAbort = 0; } if (stream->eventStreamStart[StreamStart_kOk]) { CloseHandle(stream->eventStreamStart[StreamStart_kOk]); } if (stream->eventStreamStart[StreamStart_kFailed]) { CloseHandle(stream->eventStreamStart[StreamStart_kFailed]); } for (i = 0; i < 2; ++i) { unsigned j; /* Unregister notification handles for WaveRT */ if (ios[i]->pPin && ios[i]->pPin->parentFilter->devInfo.streamingType == Type_kWaveRT && ios[i]->pPin->pinKsSubType == SubType_kNotification && ios[i]->events != 0) { PinUnregisterNotificationHandle(ios[i]->pPin, ios[i]->events[0]); } for (j=0; j < ios[i]->noOfPackets; ++j) { if (ios[i]->events && ios[i]->events[j]) { CloseHandle(ios[i]->events[j]); ios[i]->events[j] = 0; } } } } static unsigned NextPowerOf2(unsigned val) { val--; val = (val >> 1) | val; val = (val >> 2) | val; val = (val >> 4) | val; val = (val >> 8) | val; val = (val >> 16) | val; return ++val; } static PaError ValidateSpecificStreamParameters( const PaStreamParameters *streamParameters, const PaWinWDMKSInfo *streamInfo) { if( streamInfo ) { if( streamInfo->size != sizeof( PaWinWDMKSInfo ) || streamInfo->version != 1 ) { PA_DEBUG(("Stream parameters: size or version not correct")); return paIncompatibleHostApiSpecificStreamInfo; } if (streamInfo->noOfPackets != 0 && (streamInfo->noOfPackets < 2 || streamInfo->noOfPackets > 8)) { PA_DEBUG(("Stream parameters: noOfPackets %u out of range [2,8]", streamInfo->noOfPackets)); return paIncompatibleHostApiSpecificStreamInfo; } } return paNoError; } /* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerUserBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ) { PaError result = paNoError; PaWinWdmHostApiRepresentation *wdmHostApi = (PaWinWdmHostApiRepresentation*)hostApi; PaWinWdmStream *stream = 0; /* unsigned long framesPerHostBuffer; these may not be equivalent for all implementations */ PaSampleFormat inputSampleFormat, outputSampleFormat; PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat; int userInputChannels,userOutputChannels; WAVEFORMATEXTENSIBLE wfx; PA_LOGE_; PA_DEBUG(("OpenStream:sampleRate = %f\n",sampleRate)); PA_DEBUG(("OpenStream:framesPerBuffer = %lu\n",framesPerUserBuffer)); if( inputParameters ) { userInputChannels = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) { PaWinWDM_SetLastErrorInfo(paInvalidDevice, "paUseHostApiSpecificDeviceSpecification(in) not supported"); return paInvalidDevice; } /* check that input device can support stream->userInputChannels */ if( userInputChannels > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) { PaWinWDM_SetLastErrorInfo(paInvalidChannelCount, "Invalid input channel count"); return paInvalidChannelCount; } /* validate inputStreamInfo */ result = ValidateSpecificStreamParameters(inputParameters, inputParameters->hostApiSpecificStreamInfo); if(result != paNoError) { PaWinWDM_SetLastErrorInfo(result, "Host API stream info not supported (in)"); return result; /* this implementation doesn't use custom stream info */ } } else { userInputChannels = 0; inputSampleFormat = hostInputSampleFormat = paInt16; /* Supress 'uninitialised var' warnings. */ } if( outputParameters ) { userOutputChannels = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) { PaWinWDM_SetLastErrorInfo(paInvalidDevice, "paUseHostApiSpecificDeviceSpecification(out) not supported"); return paInvalidDevice; } /* check that output device can support stream->userInputChannels */ if( userOutputChannels > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) { PaWinWDM_SetLastErrorInfo(paInvalidChannelCount, "Invalid output channel count"); return paInvalidChannelCount; } /* validate outputStreamInfo */ result = ValidateSpecificStreamParameters( outputParameters, outputParameters->hostApiSpecificStreamInfo ); if (result != paNoError) { PaWinWDM_SetLastErrorInfo(result, "Host API stream info not supported (out)"); return result; /* this implementation doesn't use custom stream info */ } } else { userOutputChannels = 0; outputSampleFormat = hostOutputSampleFormat = paInt16; /* Supress 'uninitialized var' warnings. */ } /* validate platform specific flags */ if( (streamFlags & paPlatformSpecificFlags) != 0 ) { PaWinWDM_SetLastErrorInfo(paInvalidFlag, "Invalid flag supplied"); return paInvalidFlag; /* unexpected platform specific flag */ } stream = (PaWinWdmStream*)PaUtil_AllocateMemory( sizeof(PaWinWdmStream) ); if( !stream ) { result = paInsufficientMemory; goto error; } /* Create allocation group */ stream->allocGroup = PaUtil_CreateAllocationGroup(); if( !stream->allocGroup ) { result = paInsufficientMemory; goto error; } /* Zero the stream object */ /* memset((void*)stream,0,sizeof(PaWinWdmStream)); */ if( streamCallback ) { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &wdmHostApi->callbackStreamInterface, streamCallback, userData ); } else { /* PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &wdmHostApi->blockingStreamInterface, streamCallback, userData ); */ /* We don't support the blocking API yet */ PA_DEBUG(("Blocking API not supported yet!\n")); PaWinWDM_SetLastErrorInfo(paUnanticipatedHostError, "Blocking API not supported yet"); result = paUnanticipatedHostError; goto error; } PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate ); /* Instantiate the input pin if necessary */ if(userInputChannels > 0) { PaWinWdmFilter* pFilter; PaWinWdmDeviceInfo* pDeviceInfo; PaWinWdmPin* pPin; unsigned validBitsPerSample = 0; PaWinWaveFormatChannelMask channelMask = PaWin_DefaultChannelMask( userInputChannels ); result = paSampleFormatNotSupported; pDeviceInfo = (PaWinWdmDeviceInfo*)wdmHostApi->inheritedHostApiRep.deviceInfos[inputParameters->device]; pFilter = pDeviceInfo->filter; pPin = pFilter->pins[pDeviceInfo->pin]; stream->userInputChannels = userInputChannels; hostInputSampleFormat = PaUtil_SelectClosestAvailableFormat( pPin->formats, inputSampleFormat ); if (hostInputSampleFormat == paSampleFormatNotSupported) { result = paUnanticipatedHostError; PaWinWDM_SetLastErrorInfo(result, "PU_SCAF(%X,%X) failed (input)", pPin->formats, inputSampleFormat); goto error; } else if (pFilter->devInfo.streamingType == Type_kWaveRT && hostInputSampleFormat == paInt24) { /* For WaveRT, we choose 32 bit format instead of paInt24, since we MIGHT need to align buffer on a 128 byte boundary (see PinGetBuffer) */ hostInputSampleFormat = paInt32; /* But we'll tell the driver that it's 24 bit in 32 bit container */ validBitsPerSample = 24; } while (hostInputSampleFormat <= paUInt8) { unsigned channelsToProbe = stream->userInputChannels; /* Some or all KS devices can only handle the exact number of channels * they specify. But PortAudio clients expect to be able to * at least specify mono I/O on a multi-channel device * If this is the case, then we will do the channel mapping internally * The following loop tests this case **/ while (1) { PaWin_InitializeWaveFormatExtensible((PaWinWaveFormat*)&wfx, channelsToProbe, hostInputSampleFormat, PaWin_SampleFormatToLinearWaveFormatTag(hostInputSampleFormat), sampleRate, channelMask ); stream->capture.bytesPerFrame = wfx.Format.nBlockAlign; if (validBitsPerSample != 0) { wfx.Samples.wValidBitsPerSample = validBitsPerSample; } stream->capture.pPin = FilterCreatePin(pFilter, pPin->pinId, (WAVEFORMATEX*)&wfx, &result); stream->deviceInputChannels = channelsToProbe; if( result != paNoError && result != paDeviceUnavailable ) { /* Try a WAVE_FORMAT_PCM instead */ PaWin_InitializeWaveFormatEx((PaWinWaveFormat*)&wfx, channelsToProbe, hostInputSampleFormat, PaWin_SampleFormatToLinearWaveFormatTag(hostInputSampleFormat), sampleRate); if (validBitsPerSample != 0) { wfx.Samples.wValidBitsPerSample = validBitsPerSample; } stream->capture.pPin = FilterCreatePin(pFilter, pPin->pinId, (const WAVEFORMATEX*)&wfx, &result); } if (result == paDeviceUnavailable) goto occupied; if (result == paNoError) { /* We're done */ break; } if (channelsToProbe < (unsigned)pPin->maxChannels) { /* Go to next multiple of 2 */ channelsToProbe = min((((channelsToProbe>>1)+1)<<1), (unsigned)pPin->maxChannels); continue; } break; } if (result == paNoError) { /* We're done */ break; } /* Go to next format in line with lower resolution */ hostInputSampleFormat <<= 1; } if(stream->capture.pPin == NULL) { PaWinWDM_SetLastErrorInfo(result, "Failed to create capture pin: sr=%u,ch=%u,bits=%u,align=%u", wfx.Format.nSamplesPerSec, wfx.Format.nChannels, wfx.Format.wBitsPerSample, wfx.Format.nBlockAlign); goto error; } /* Select correct mux input on MUX node of topology filter */ if (pDeviceInfo->muxPosition >= 0) { assert(pPin->parentFilter->topologyFilter != NULL); result = FilterUse(pPin->parentFilter->topologyFilter); if (result != paNoError) { PaWinWDM_SetLastErrorInfo(result, "Failed to open topology filter"); goto error; } result = WdmSetMuxNodeProperty(pPin->parentFilter->topologyFilter->handle, pPin->inputs[pDeviceInfo->muxPosition]->muxNodeId, pPin->inputs[pDeviceInfo->muxPosition]->muxPinId); FilterRelease(pPin->parentFilter->topologyFilter); if(result != paNoError) { PaWinWDM_SetLastErrorInfo(result, "Failed to set topology mux node"); goto error; } } stream->capture.bytesPerSample = stream->capture.bytesPerFrame / stream->deviceInputChannels; stream->capture.pPin->frameSize /= stream->capture.bytesPerFrame; PA_DEBUG(("Capture pin frames: %d\n",stream->capture.pPin->frameSize)); } else { stream->capture.pPin = NULL; stream->capture.bytesPerFrame = 0; } /* Instantiate the output pin if necessary */ if(userOutputChannels > 0) { PaWinWdmFilter* pFilter; PaWinWdmDeviceInfo* pDeviceInfo; PaWinWdmPin* pPin; unsigned validBitsPerSample = 0; PaWinWaveFormatChannelMask channelMask = PaWin_DefaultChannelMask( userOutputChannels ); result = paSampleFormatNotSupported; pDeviceInfo = (PaWinWdmDeviceInfo*)wdmHostApi->inheritedHostApiRep.deviceInfos[outputParameters->device]; pFilter = pDeviceInfo->filter; pPin = pFilter->pins[pDeviceInfo->pin]; stream->userOutputChannels = userOutputChannels; hostOutputSampleFormat = PaUtil_SelectClosestAvailableFormat( pPin->formats, outputSampleFormat ); if (hostOutputSampleFormat == paSampleFormatNotSupported) { result = paUnanticipatedHostError; PaWinWDM_SetLastErrorInfo(result, "PU_SCAF(%X,%X) failed (output)", pPin->formats, hostOutputSampleFormat); goto error; } else if (pFilter->devInfo.streamingType == Type_kWaveRT && hostOutputSampleFormat == paInt24) { /* For WaveRT, we choose 32 bit format instead of paInt24, since we MIGHT need to align buffer on a 128 byte boundary (see PinGetBuffer) */ hostOutputSampleFormat = paInt32; /* But we'll tell the driver that it's 24 bit in 32 bit container */ validBitsPerSample = 24; } while (hostOutputSampleFormat <= paUInt8) { unsigned channelsToProbe = stream->userOutputChannels; /* Some or all KS devices can only handle the exact number of channels * they specify. But PortAudio clients expect to be able to * at least specify mono I/O on a multi-channel device * If this is the case, then we will do the channel mapping internally * The following loop tests this case **/ while (1) { PaWin_InitializeWaveFormatExtensible((PaWinWaveFormat*)&wfx, channelsToProbe, hostOutputSampleFormat, PaWin_SampleFormatToLinearWaveFormatTag(hostOutputSampleFormat), sampleRate, channelMask ); stream->render.bytesPerFrame = wfx.Format.nBlockAlign; if (validBitsPerSample != 0) { wfx.Samples.wValidBitsPerSample = validBitsPerSample; } stream->render.pPin = FilterCreatePin(pFilter, pPin->pinId, (WAVEFORMATEX*)&wfx, &result); stream->deviceOutputChannels = channelsToProbe; if( result != paNoError && result != paDeviceUnavailable ) { PaWin_InitializeWaveFormatEx((PaWinWaveFormat*)&wfx, channelsToProbe, hostOutputSampleFormat, PaWin_SampleFormatToLinearWaveFormatTag(hostOutputSampleFormat), sampleRate); if (validBitsPerSample != 0) { wfx.Samples.wValidBitsPerSample = validBitsPerSample; } stream->render.pPin = FilterCreatePin(pFilter, pPin->pinId, (const WAVEFORMATEX*)&wfx, &result); } if (result == paDeviceUnavailable) goto occupied; if (result == paNoError) { /* We're done */ break; } if (channelsToProbe < (unsigned)pPin->maxChannels) { /* Go to next multiple of 2 */ channelsToProbe = min((((channelsToProbe>>1)+1)<<1), (unsigned)pPin->maxChannels); continue; } break; }; if (result == paNoError) { /* We're done */ break; } /* Go to next format in line with lower resolution */ hostOutputSampleFormat <<= 1; } if(stream->render.pPin == NULL) { PaWinWDM_SetLastErrorInfo(result, "Failed to create render pin: sr=%u,ch=%u,bits=%u,align=%u", wfx.Format.nSamplesPerSec, wfx.Format.nChannels, wfx.Format.wBitsPerSample, wfx.Format.nBlockAlign); goto error; } stream->render.bytesPerSample = stream->render.bytesPerFrame / stream->deviceOutputChannels; stream->render.pPin->frameSize /= stream->render.bytesPerFrame; PA_DEBUG(("Render pin frames: %d\n",stream->render.pPin->frameSize)); } else { stream->render.pPin = NULL; stream->render.bytesPerFrame = 0; } /* Calculate the framesPerHostXxxxBuffer size based upon the suggested latency values */ /* Record the buffer length */ if(inputParameters) { /* Calculate the frames from the user's value - add a bit to round up */ stream->capture.framesPerBuffer = (unsigned long)((inputParameters->suggestedLatency*sampleRate)+0.0001); if(stream->capture.framesPerBuffer > (unsigned long)sampleRate) { /* Upper limit is 1 second */ stream->capture.framesPerBuffer = (unsigned long)sampleRate; } else if(stream->capture.framesPerBuffer < stream->capture.pPin->frameSize) { stream->capture.framesPerBuffer = stream->capture.pPin->frameSize; } PA_DEBUG(("Input frames chosen:%ld\n",stream->capture.framesPerBuffer)); /* Setup number of packets to use */ stream->capture.noOfPackets = 2; if (inputParameters->hostApiSpecificStreamInfo) { PaWinWDMKSInfo* pInfo = (PaWinWDMKSInfo*)inputParameters->hostApiSpecificStreamInfo; if (stream->capture.pPin->parentFilter->devInfo.streamingType == Type_kWaveCyclic && pInfo->noOfPackets != 0) { stream->capture.noOfPackets = pInfo->noOfPackets; } } } if(outputParameters) { /* Calculate the frames from the user's value - add a bit to round up */ stream->render.framesPerBuffer = (unsigned long)((outputParameters->suggestedLatency*sampleRate)+0.0001); if(stream->render.framesPerBuffer > (unsigned long)sampleRate) { /* Upper limit is 1 second */ stream->render.framesPerBuffer = (unsigned long)sampleRate; } else if(stream->render.framesPerBuffer < stream->render.pPin->frameSize) { stream->render.framesPerBuffer = stream->render.pPin->frameSize; } PA_DEBUG(("Output frames chosen:%ld\n",stream->render.framesPerBuffer)); /* Setup number of packets to use */ stream->render.noOfPackets = 2; if (outputParameters->hostApiSpecificStreamInfo) { PaWinWDMKSInfo* pInfo = (PaWinWDMKSInfo*)outputParameters->hostApiSpecificStreamInfo; if (stream->render.pPin->parentFilter->devInfo.streamingType == Type_kWaveCyclic && pInfo->noOfPackets != 0) { stream->render.noOfPackets = pInfo->noOfPackets; } } } /* Host buffer size is bound to the largest of the input and output frame sizes */ result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, stream->userInputChannels, inputSampleFormat, hostInputSampleFormat, stream->userOutputChannels, outputSampleFormat, hostOutputSampleFormat, sampleRate, streamFlags, framesPerUserBuffer, max(stream->capture.framesPerBuffer, stream->render.framesPerBuffer), paUtilBoundedHostBufferSize, streamCallback, userData ); if( result != paNoError ) { PaWinWDM_SetLastErrorInfo(result, "PaUtil_InitializeBufferProcessor failed: ich=%u, isf=%u, hisf=%u, och=%u, osf=%u, hosf=%u, sr=%lf, flags=0x%X, fpub=%u, fphb=%u", stream->userInputChannels, inputSampleFormat, hostInputSampleFormat, stream->userOutputChannels, outputSampleFormat, hostOutputSampleFormat, sampleRate, streamFlags, framesPerUserBuffer, max(stream->capture.framesPerBuffer, stream->render.framesPerBuffer)); goto error; } /* Allocate/get all the buffers for host I/O */ if (stream->userInputChannels > 0) { stream->streamRepresentation.streamInfo.inputLatency = stream->capture.framesPerBuffer / sampleRate; switch (stream->capture.pPin->parentFilter->devInfo.streamingType) { case Type_kWaveCyclic: { unsigned size = stream->capture.noOfPackets * stream->capture.framesPerBuffer * stream->capture.bytesPerFrame; /* Allocate input host buffer */ stream->capture.hostBuffer = (char*)PaUtil_GroupAllocateMemory(stream->allocGroup, size); PA_DEBUG(("Input buffer allocated (size = %u)\n", size)); if( !stream->capture.hostBuffer ) { PA_DEBUG(("Cannot allocate host input buffer!\n")); PaWinWDM_SetLastErrorInfo(paInsufficientMemory, "Failed to allocate input buffer"); result = paInsufficientMemory; goto error; } stream->capture.hostBufferSize = size; PA_DEBUG(("Input buffer start = %p (size=%u)\n",stream->capture.hostBuffer, stream->capture.hostBufferSize)); stream->capture.pPin->fnEventHandler = PaPinCaptureEventHandler_WaveCyclic; stream->capture.pPin->fnSubmitHandler = PaPinCaptureSubmitHandler_WaveCyclic; } break; case Type_kWaveRT: { const DWORD dwTotalSize = 2 * stream->capture.framesPerBuffer * stream->capture.bytesPerFrame; DWORD dwRequestedSize = dwTotalSize; BOOL bCallMemoryBarrier = FALSE; ULONG hwFifoLatency = 0; ULONG dummy; result = PinGetBuffer(stream->capture.pPin, (void**)&stream->capture.hostBuffer, &dwRequestedSize, &bCallMemoryBarrier); if (!result) { PA_DEBUG(("Input buffer start = %p, size = %u\n", stream->capture.hostBuffer, dwRequestedSize)); if (dwRequestedSize != dwTotalSize) { PA_DEBUG(("Buffer length changed by driver from %u to %u !\n", dwTotalSize, dwRequestedSize)); /* Recalculate to what the driver has given us */ stream->capture.framesPerBuffer = dwRequestedSize / (2 * stream->capture.bytesPerFrame); } stream->capture.hostBufferSize = dwRequestedSize; if (stream->capture.pPin->pinKsSubType == SubType_kPolled) { stream->capture.pPin->fnEventHandler = PaPinCaptureEventHandler_WaveRTPolled; stream->capture.pPin->fnSubmitHandler = PaPinCaptureSubmitHandler_WaveRTPolled; } else { stream->capture.pPin->fnEventHandler = PaPinCaptureEventHandler_WaveRTEvent; stream->capture.pPin->fnSubmitHandler = PaPinCaptureSubmitHandler_WaveRTEvent; } stream->capture.pPin->fnMemBarrier = bCallMemoryBarrier ? MemoryBarrierRead : MemoryBarrierDummy; } else { PA_DEBUG(("Failed to get input buffer (WaveRT)\n")); PaWinWDM_SetLastErrorInfo(paUnanticipatedHostError, "Failed to get input buffer (WaveRT)"); result = paUnanticipatedHostError; goto error; } /* Get latency */ result = PinGetHwLatency(stream->capture.pPin, &hwFifoLatency, &dummy, &dummy); if (result == paNoError) { stream->capture.pPin->hwLatency = hwFifoLatency; /* Add HW latency into total input latency */ stream->streamRepresentation.streamInfo.inputLatency += ((hwFifoLatency / stream->capture.bytesPerFrame) / sampleRate); } else { PA_DEBUG(("Failed to get size of FIFO hardware buffer (is set to zero)\n")); stream->capture.pPin->hwLatency = 0; } } break; default: /* Undefined wave type!! */ assert(0); result = paInternalError; PaWinWDM_SetLastErrorInfo(result, "Wave type %u ??", stream->capture.pPin->parentFilter->devInfo.streamingType); goto error; } } else { stream->capture.hostBuffer = 0; } if (stream->userOutputChannels > 0) { stream->streamRepresentation.streamInfo.outputLatency = stream->render.framesPerBuffer / sampleRate; switch (stream->render.pPin->parentFilter->devInfo.streamingType) { case Type_kWaveCyclic: { unsigned size = stream->render.noOfPackets * stream->render.framesPerBuffer * stream->render.bytesPerFrame; /* Allocate output device buffer */ stream->render.hostBuffer = (char*)PaUtil_GroupAllocateMemory(stream->allocGroup, size); PA_DEBUG(("Output buffer allocated (size = %u)\n", size)); if( !stream->render.hostBuffer ) { PA_DEBUG(("Cannot allocate host output buffer!\n")); PaWinWDM_SetLastErrorInfo(paInsufficientMemory, "Failed to allocate output buffer"); result = paInsufficientMemory; goto error; } stream->render.hostBufferSize = size; PA_DEBUG(("Output buffer start = %p (size=%u)\n",stream->render.hostBuffer, stream->render.hostBufferSize)); stream->render.pPin->fnEventHandler = PaPinRenderEventHandler_WaveCyclic; stream->render.pPin->fnSubmitHandler = PaPinRenderSubmitHandler_WaveCyclic; } break; case Type_kWaveRT: { const DWORD dwTotalSize = 2 * stream->render.framesPerBuffer * stream->render.bytesPerFrame; DWORD dwRequestedSize = dwTotalSize; BOOL bCallMemoryBarrier = FALSE; ULONG hwFifoLatency = 0; ULONG dummy; result = PinGetBuffer(stream->render.pPin, (void**)&stream->render.hostBuffer, &dwRequestedSize, &bCallMemoryBarrier); if (!result) { PA_DEBUG(("Output buffer start = %p, size = %u, membarrier = %u\n", stream->render.hostBuffer, dwRequestedSize, bCallMemoryBarrier)); if (dwRequestedSize != dwTotalSize) { PA_DEBUG(("Buffer length changed by driver from %u to %u !\n", dwTotalSize, dwRequestedSize)); /* Recalculate to what the driver has given us */ stream->render.framesPerBuffer = dwRequestedSize / (2 * stream->render.bytesPerFrame); } stream->render.hostBufferSize = dwRequestedSize; if (stream->render.pPin->pinKsSubType == SubType_kPolled) { stream->render.pPin->fnEventHandler = PaPinRenderEventHandler_WaveRTPolled; stream->render.pPin->fnSubmitHandler = PaPinRenderSubmitHandler_WaveRTPolled; } else { stream->render.pPin->fnEventHandler = PaPinRenderEventHandler_WaveRTEvent; stream->render.pPin->fnSubmitHandler = PaPinRenderSubmitHandler_WaveRTEvent; } stream->render.pPin->fnMemBarrier = bCallMemoryBarrier ? MemoryBarrierWrite : MemoryBarrierDummy; } else { PA_DEBUG(("Failed to get output buffer (with notification)\n")); PaWinWDM_SetLastErrorInfo(paUnanticipatedHostError, "Failed to get output buffer (with notification)"); result = paUnanticipatedHostError; goto error; } /* Get latency */ result = PinGetHwLatency(stream->render.pPin, &hwFifoLatency, &dummy, &dummy); if (result == paNoError) { stream->render.pPin->hwLatency = hwFifoLatency; /* Add HW latency into total output latency */ stream->streamRepresentation.streamInfo.outputLatency += ((hwFifoLatency / stream->render.bytesPerFrame) / sampleRate); } else { PA_DEBUG(("Failed to get size of FIFO hardware buffer (is set to zero)\n")); stream->render.pPin->hwLatency = 0; } } break; default: /* Undefined wave type!! */ assert(0); result = paInternalError; PaWinWDM_SetLastErrorInfo(result, "Wave type %u ??", stream->capture.pPin->parentFilter->devInfo.streamingType); goto error; } } else { stream->render.hostBuffer = 0; } stream->streamRepresentation.streamInfo.sampleRate = sampleRate; PA_DEBUG(("BytesPerInputFrame = %d\n",stream->capture.bytesPerFrame)); PA_DEBUG(("BytesPerOutputFrame = %d\n",stream->render.bytesPerFrame)); /* memset(stream->hostBuffer,0,size); */ /* Abort */ stream->eventAbort = CreateEvent(NULL, TRUE, FALSE, NULL); if (stream->eventAbort == 0) { result = paInsufficientMemory; goto error; } stream->eventStreamStart[0] = CreateEvent(NULL, TRUE, FALSE, NULL); if (stream->eventStreamStart[0] == 0) { result = paInsufficientMemory; goto error; } stream->eventStreamStart[1] = CreateEvent(NULL, TRUE, FALSE, NULL); if (stream->eventStreamStart[1] == 0) { result = paInsufficientMemory; goto error; } if(stream->userInputChannels > 0) { const unsigned bufferSizeInBytes = stream->capture.framesPerBuffer * stream->capture.bytesPerFrame; const unsigned ringBufferFrameSize = NextPowerOf2( 1024 + 2 * max(stream->capture.framesPerBuffer, stream->render.framesPerBuffer) ); stream->capture.events = (HANDLE*)PaUtil_GroupAllocateMemory(stream->allocGroup, stream->capture.noOfPackets * sizeof(HANDLE)); if (stream->capture.events == NULL) { result = paInsufficientMemory; goto error; } stream->capture.packets = (DATAPACKET*)PaUtil_GroupAllocateMemory(stream->allocGroup, stream->capture.noOfPackets * sizeof(DATAPACKET)); if (stream->capture.packets == NULL) { result = paInsufficientMemory; goto error; } switch(stream->capture.pPin->parentFilter->devInfo.streamingType) { case Type_kWaveCyclic: { /* WaveCyclic case */ unsigned i; for (i = 0; i < stream->capture.noOfPackets; ++i) { /* Set up the packets */ DATAPACKET *p = stream->capture.packets + i; /* Record event */ stream->capture.events[i] = CreateEvent(NULL, TRUE, FALSE, NULL); p->Signal.hEvent = stream->capture.events[i]; p->Header.Data = stream->capture.hostBuffer + (i*bufferSizeInBytes); p->Header.FrameExtent = bufferSizeInBytes; p->Header.DataUsed = 0; p->Header.Size = sizeof(p->Header); p->Header.PresentationTime.Numerator = 1; p->Header.PresentationTime.Denominator = 1; } } break; case Type_kWaveRT: { /* Set up the "packets" */ DATAPACKET *p = stream->capture.packets + 0; /* Record event: WaveRT has a single event for 2 notification per buffer */ stream->capture.events[0] = CreateEvent(NULL, FALSE, FALSE, NULL); p->Header.Data = stream->capture.hostBuffer; p->Header.FrameExtent = bufferSizeInBytes; p->Header.DataUsed = 0; p->Header.Size = sizeof(p->Header); p->Header.PresentationTime.Numerator = 1; p->Header.PresentationTime.Denominator = 1; ++p; p->Header.Data = stream->capture.hostBuffer + bufferSizeInBytes; p->Header.FrameExtent = bufferSizeInBytes; p->Header.DataUsed = 0; p->Header.Size = sizeof(p->Header); p->Header.PresentationTime.Numerator = 1; p->Header.PresentationTime.Denominator = 1; if (stream->capture.pPin->pinKsSubType == SubType_kNotification) { result = PinRegisterNotificationHandle(stream->capture.pPin, stream->capture.events[0]); if (result != paNoError) { PA_DEBUG(("Failed to register capture notification handle\n")); PaWinWDM_SetLastErrorInfo(paUnanticipatedHostError, "Failed to register capture notification handle"); result = paUnanticipatedHostError; goto error; } } result = PinRegisterPositionRegister(stream->capture.pPin); if (result != paNoError) { unsigned long pos = 0xdeadc0de; PA_DEBUG(("Failed to register capture position register, using PinGetAudioPositionViaIOCTL\n")); stream->capture.pPin->fnAudioPosition = PinGetAudioPositionViaIOCTL; /* Test position function */ result = (stream->capture.pPin->fnAudioPosition)(stream->capture.pPin, &pos); if (result != paNoError || pos != 0x0) { PA_DEBUG(("Failed to read capture position register (IOCTL)\n")); PaWinWDM_SetLastErrorInfo(paUnanticipatedHostError, "Failed to read capture position register (IOCTL)"); result = paUnanticipatedHostError; goto error; } } else { stream->capture.pPin->fnAudioPosition = PinGetAudioPositionDirect; } } break; default: /* Undefined wave type!! */ assert(0); result = paInternalError; PaWinWDM_SetLastErrorInfo(result, "Wave type %u ??", stream->capture.pPin->parentFilter->devInfo.streamingType); goto error; } /* Setup the input ring buffer here */ stream->ringBufferData = (char*)PaUtil_GroupAllocateMemory(stream->allocGroup, ringBufferFrameSize * stream->capture.bytesPerFrame); if (stream->ringBufferData == NULL) { result = paInsufficientMemory; goto error; } PaUtil_InitializeRingBuffer(&stream->ringBuffer, stream->capture.bytesPerFrame, ringBufferFrameSize, stream->ringBufferData); } if(stream->userOutputChannels > 0) { const unsigned bufferSizeInBytes = stream->render.framesPerBuffer * stream->render.bytesPerFrame; stream->render.events = (HANDLE*)PaUtil_GroupAllocateMemory(stream->allocGroup, stream->render.noOfPackets * sizeof(HANDLE)); if (stream->render.events == NULL) { result = paInsufficientMemory; goto error; } stream->render.packets = (DATAPACKET*)PaUtil_GroupAllocateMemory(stream->allocGroup, stream->render.noOfPackets * sizeof(DATAPACKET)); if (stream->render.packets == NULL) { result = paInsufficientMemory; goto error; } switch(stream->render.pPin->parentFilter->devInfo.streamingType) { case Type_kWaveCyclic: { /* WaveCyclic case */ unsigned i; for (i = 0; i < stream->render.noOfPackets; ++i) { /* Set up the packets */ DATAPACKET *p = stream->render.packets + i; /* Playback event */ stream->render.events[i] = CreateEvent(NULL, TRUE, FALSE, NULL); /* In this case, we just use the packets as ptr to the device buffer */ p->Signal.hEvent = stream->render.events[i]; p->Header.Data = stream->render.hostBuffer + (i*bufferSizeInBytes); p->Header.FrameExtent = bufferSizeInBytes; p->Header.DataUsed = bufferSizeInBytes; p->Header.Size = sizeof(p->Header); p->Header.PresentationTime.Numerator = 1; p->Header.PresentationTime.Denominator = 1; } } break; case Type_kWaveRT: { /* WaveRT case */ /* Set up the "packets" */ DATAPACKET *p = stream->render.packets; /* The only playback event */ stream->render.events[0] = CreateEvent(NULL, FALSE, FALSE, NULL); /* In this case, we just use the packets as ptr to the device buffer */ p->Header.Data = stream->render.hostBuffer; p->Header.FrameExtent = stream->render.framesPerBuffer*stream->render.bytesPerFrame; p->Header.DataUsed = stream->render.framesPerBuffer*stream->render.bytesPerFrame; p->Header.Size = sizeof(p->Header); p->Header.PresentationTime.Numerator = 1; p->Header.PresentationTime.Denominator = 1; ++p; p->Header.Data = stream->render.hostBuffer + stream->render.framesPerBuffer*stream->render.bytesPerFrame; p->Header.FrameExtent = stream->render.framesPerBuffer*stream->render.bytesPerFrame; p->Header.DataUsed = stream->render.framesPerBuffer*stream->render.bytesPerFrame; p->Header.Size = sizeof(p->Header); p->Header.PresentationTime.Numerator = 1; p->Header.PresentationTime.Denominator = 1; if (stream->render.pPin->pinKsSubType == SubType_kNotification) { result = PinRegisterNotificationHandle(stream->render.pPin, stream->render.events[0]); if (result != paNoError) { PA_DEBUG(("Failed to register rendering notification handle\n")); PaWinWDM_SetLastErrorInfo(paUnanticipatedHostError, "Failed to register rendering notification handle"); result = paUnanticipatedHostError; goto error; } } result = PinRegisterPositionRegister(stream->render.pPin); if (result != paNoError) { unsigned long pos = 0xdeadc0de; PA_DEBUG(("Failed to register rendering position register, using PinGetAudioPositionViaIOCTL\n")); stream->render.pPin->fnAudioPosition = PinGetAudioPositionViaIOCTL; /* Test position function */ result = (stream->render.pPin->fnAudioPosition)(stream->render.pPin, &pos); if (result != paNoError || pos != 0x0) { PA_DEBUG(("Failed to read render position register (IOCTL)\n")); PaWinWDM_SetLastErrorInfo(paUnanticipatedHostError, "Failed to read render position register (IOCTL)"); result = paUnanticipatedHostError; goto error; } } else { stream->render.pPin->fnAudioPosition = PinGetAudioPositionDirect; } } break; default: /* Undefined wave type!! */ assert(0); result = paInternalError; PaWinWDM_SetLastErrorInfo(result, "Wave type %u ??", stream->capture.pPin->parentFilter->devInfo.streamingType); goto error; } } stream->streamStarted = 0; stream->streamActive = 0; stream->streamStop = 0; stream->streamAbort = 0; stream->streamFlags = streamFlags; stream->oldProcessPriority = REALTIME_PRIORITY_CLASS; /* Increase ref count on filters in use, so that a CommitDeviceInfos won't delete them */ if (stream->capture.pPin != 0) { FilterAddRef(stream->capture.pPin->parentFilter); } if (stream->render.pPin != 0) { FilterAddRef(stream->render.pPin->parentFilter); } /* Ok, now update our host API specific stream info */ if (stream->userInputChannels) { PaWinWdmDeviceInfo *pDeviceInfo = (PaWinWdmDeviceInfo*)wdmHostApi->inheritedHostApiRep.deviceInfos[inputParameters->device]; stream->hostApiStreamInfo.input.device = Pa_HostApiDeviceIndexToDeviceIndex(Pa_HostApiTypeIdToHostApiIndex(paWDMKS), inputParameters->device); stream->hostApiStreamInfo.input.channels = stream->deviceInputChannels; stream->hostApiStreamInfo.input.muxNodeId = -1; if (stream->capture.pPin->inputs) { stream->hostApiStreamInfo.input.muxNodeId = stream->capture.pPin->inputs[pDeviceInfo->muxPosition]->muxNodeId; } stream->hostApiStreamInfo.input.endpointPinId = pDeviceInfo->endpointPinId; stream->hostApiStreamInfo.input.framesPerHostBuffer = stream->capture.framesPerBuffer; stream->hostApiStreamInfo.input.streamingSubType = stream->capture.pPin->pinKsSubType; } else { stream->hostApiStreamInfo.input.device = paNoDevice; } if (stream->userOutputChannels) { stream->hostApiStreamInfo.output.device = Pa_HostApiDeviceIndexToDeviceIndex(Pa_HostApiTypeIdToHostApiIndex(paWDMKS), outputParameters->device); stream->hostApiStreamInfo.output.channels = stream->deviceOutputChannels; stream->hostApiStreamInfo.output.framesPerHostBuffer = stream->render.framesPerBuffer; stream->hostApiStreamInfo.output.endpointPinId = stream->render.pPin->endpointPinId; stream->hostApiStreamInfo.output.streamingSubType = stream->render.pPin->pinKsSubType; } else { stream->hostApiStreamInfo.output.device = paNoDevice; } /*stream->streamRepresentation.streamInfo.hostApiTypeId = paWDMKS; stream->streamRepresentation.streamInfo.hostApiSpecificStreamInfo = &stream->hostApiStreamInfo;*/ stream->streamRepresentation.streamInfo.structVersion = 2; *s = (PaStream*)stream; PA_LOGL_; return result; occupied: /* Ok, someone else is hogging the pin, bail out */ assert (result == paDeviceUnavailable); PaWinWDM_SetLastErrorInfo(result, "Device is occupied"); error: PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); CloseStreamEvents(stream); if (stream->allocGroup) { PaUtil_FreeAllAllocations(stream->allocGroup); PaUtil_DestroyAllocationGroup(stream->allocGroup); stream->allocGroup = 0; } if(stream->render.pPin) PinClose(stream->render.pPin); if(stream->capture.pPin) PinClose(stream->capture.pPin); PaUtil_FreeMemory( stream ); PA_LOGL_; return result; } /* When CloseStream() is called, the multi-api layer ensures that the stream has already been stopped or aborted. */ static PaError CloseStream( PaStream* s ) { PaError result = paNoError; PaWinWdmStream *stream = (PaWinWdmStream*)s; PA_LOGE_; assert(!stream->streamStarted); assert(!stream->streamActive); PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); CloseStreamEvents(stream); if (stream->allocGroup) { PaUtil_FreeAllAllocations(stream->allocGroup); PaUtil_DestroyAllocationGroup(stream->allocGroup); stream->allocGroup = 0; } if(stream->render.pPin) { PinClose(stream->render.pPin); } if(stream->capture.pPin) { PinClose(stream->capture.pPin); } if (stream->render.pPin) { FilterFree(stream->render.pPin->parentFilter); } if (stream->capture.pPin) { FilterFree(stream->capture.pPin->parentFilter); } PaUtil_FreeMemory( stream ); PA_LOGL_; return result; } /* Write the supplied packet to the pin Asynchronous Should return paNoError on success */ static PaError PinWrite(HANDLE h, DATAPACKET* p) { PaError result = paNoError; unsigned long cbReturned = 0; BOOL fRes = DeviceIoControl(h, IOCTL_KS_WRITE_STREAM, NULL, 0, &p->Header, p->Header.Size, &cbReturned, &p->Signal); if (!fRes) { unsigned long error = GetLastError(); if (error != ERROR_IO_PENDING) { result = paInternalError; } } return result; } /* Read to the supplied packet from the pin Asynchronous Should return paNoError on success */ static PaError PinRead(HANDLE h, DATAPACKET* p) { PaError result = paNoError; unsigned long cbReturned = 0; BOOL fRes = DeviceIoControl(h, IOCTL_KS_READ_STREAM, NULL, 0, &p->Header, p->Header.Size, &cbReturned, &p->Signal); if (!fRes) { unsigned long error = GetLastError(); if (error != ERROR_IO_PENDING) { result = paInternalError; } } return result; } /* Copy the first interleaved channel of 16 bit data to the other channels */ static void DuplicateFirstChannelInt16(void* buffer, int channels, int samples) { unsigned short* data = (unsigned short*)buffer; int channel; unsigned short sourceSample; while( samples-- ) { sourceSample = *data++; channel = channels-1; while( channel-- ) { *data++ = sourceSample; } } } /* Copy the first interleaved channel of 24 bit data to the other channels */ static void DuplicateFirstChannelInt24(void* buffer, int channels, int samples) { unsigned char* data = (unsigned char*)buffer; int channel; unsigned char sourceSample[3]; while( samples-- ) { sourceSample[0] = data[0]; sourceSample[1] = data[1]; sourceSample[2] = data[2]; data += 3; channel = channels-1; while( channel-- ) { data[0] = sourceSample[0]; data[1] = sourceSample[1]; data[2] = sourceSample[2]; data += 3; } } } /* Copy the first interleaved channel of 32 bit data to the other channels */ static void DuplicateFirstChannelInt32(void* buffer, int channels, int samples) { unsigned long* data = (unsigned long*)buffer; int channel; unsigned long sourceSample; while( samples-- ) { sourceSample = *data++; channel = channels-1; while( channel-- ) { *data++ = sourceSample; } } } /* Increase the priority of the calling thread to RT */ static HANDLE BumpThreadPriority() { HANDLE hThread = GetCurrentThread(); DWORD dwTask = 0; HANDLE hAVRT = NULL; /* If we have access to AVRT.DLL (Vista and later), use it */ if (paWinWDMKSAvRtEntryPoints.AvSetMmThreadCharacteristics != NULL) { hAVRT = paWinWDMKSAvRtEntryPoints.AvSetMmThreadCharacteristics("Pro Audio", &dwTask); if (hAVRT != NULL && hAVRT != INVALID_HANDLE_VALUE) { BOOL bret = paWinWDMKSAvRtEntryPoints.AvSetMmThreadPriority(hAVRT, PA_AVRT_PRIORITY_CRITICAL); if (!bret) { PA_DEBUG(("Set mm thread prio to critical failed!\n")); } else { return hAVRT; } } else { PA_DEBUG(("Set mm thread characteristic to 'Pro Audio' failed, reverting to SetThreadPriority\n")); } } /* For XP and earlier, or if AvSetMmThreadCharacteristics fails (MMCSS disabled ?) */ if (timeBeginPeriod(1) != TIMERR_NOERROR) { PA_DEBUG(("timeBeginPeriod(1) failed!\n")); } if (!SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL)) { PA_DEBUG(("SetThreadPriority failed!\n")); } return hAVRT; } /* Decrease the priority of the calling thread to normal */ static void DropThreadPriority(HANDLE hAVRT) { HANDLE hThread = GetCurrentThread(); if (hAVRT != NULL) { paWinWDMKSAvRtEntryPoints.AvSetMmThreadPriority(hAVRT, PA_AVRT_PRIORITY_NORMAL); paWinWDMKSAvRtEntryPoints.AvRevertMmThreadCharacteristics(hAVRT); return; } SetThreadPriority(hThread, THREAD_PRIORITY_NORMAL); timeEndPeriod(1); } static PaError PreparePinForStart(PaWinWdmPin* pin) { PaError result; result = PinSetState(pin, KSSTATE_ACQUIRE); if (result != paNoError) { goto error; } result = PinSetState(pin, KSSTATE_PAUSE); if (result != paNoError) { goto error; } return result; error: PinSetState(pin, KSSTATE_STOP); return result; } static PaError PreparePinsForStart(PaProcessThreadInfo* pInfo) { PaError result = paNoError; /* Submit buffers */ if (pInfo->stream->capture.pPin) { if ((result = PreparePinForStart(pInfo->stream->capture.pPin)) != paNoError) { goto error; } if (pInfo->stream->capture.pPin->parentFilter->devInfo.streamingType == Type_kWaveCyclic) { unsigned i; for(i=0; i < pInfo->stream->capture.noOfPackets; ++i) { if ((result = PinRead(pInfo->stream->capture.pPin->handle, pInfo->stream->capture.packets + i)) != paNoError) { goto error; } ++pInfo->pending; } } else { pInfo->pending = 2; } } if(pInfo->stream->render.pPin) { if ((result = PreparePinForStart(pInfo->stream->render.pPin)) != paNoError) { goto error; } pInfo->priming += pInfo->stream->render.noOfPackets; ++pInfo->pending; SetEvent(pInfo->stream->render.events[0]); if (pInfo->stream->render.pPin->parentFilter->devInfo.streamingType == Type_kWaveCyclic) { unsigned i; for(i=1; i < pInfo->stream->render.noOfPackets; ++i) { SetEvent(pInfo->stream->render.events[i]); ++pInfo->pending; } } } error: PA_DEBUG(("PreparePinsForStart = %d\n", result)); return result; } static PaError StartPin(PaWinWdmPin* pin) { return PinSetState(pin, KSSTATE_RUN); } static PaError StartPins(PaProcessThreadInfo* pInfo) { PaError result = paNoError; /* Start the pins as synced as possible */ if (pInfo->stream->capture.pPin) { result = StartPin(pInfo->stream->capture.pPin); } if(pInfo->stream->render.pPin) { result = StartPin(pInfo->stream->render.pPin); } PA_DEBUG(("StartPins = %d\n", result)); return result; } static PaError StopPin(PaWinWdmPin* pin) { PinSetState(pin, KSSTATE_PAUSE); PinSetState(pin, KSSTATE_STOP); return paNoError; } static PaError StopPins(PaProcessThreadInfo* pInfo) { PaError result = paNoError; if(pInfo->stream->render.pPin) { StopPin(pInfo->stream->render.pPin); } if(pInfo->stream->capture.pPin) { StopPin(pInfo->stream->capture.pPin); } return result; } typedef void (*TSetInputFrameCount)(PaUtilBufferProcessor*, unsigned long); typedef void (*TSetInputChannel)(PaUtilBufferProcessor*, unsigned int, void *, unsigned int); static const TSetInputFrameCount fnSetInputFrameCount[2] = { PaUtil_SetInputFrameCount, PaUtil_Set2ndInputFrameCount }; static const TSetInputChannel fnSetInputChannel[2] = { PaUtil_SetInputChannel, PaUtil_Set2ndInputChannel }; static PaError PaDoProcessing(PaProcessThreadInfo* pInfo) { PaError result = paNoError; int i, framesProcessed = 0, doChannelCopy = 0; ring_buffer_size_t inputFramesAvailable = PaUtil_GetRingBufferReadAvailable(&pInfo->stream->ringBuffer); /* Do necessary buffer processing (which will invoke user callback if necessary) */ if (pInfo->cbResult == paContinue && (pInfo->renderHead != pInfo->renderTail || inputFramesAvailable)) { unsigned processFullDuplex = pInfo->stream->capture.pPin && pInfo->stream->render.pPin && (!pInfo->priming); PA_HP_TRACE((pInfo->stream->hLog, "DoProcessing: InputFrames=%u", inputFramesAvailable)); PaUtil_BeginCpuLoadMeasurement( &pInfo->stream->cpuLoadMeasurer ); pInfo->ti.currentTime = PaUtil_GetTime(); PaUtil_BeginBufferProcessing(&pInfo->stream->bufferProcessor, &pInfo->ti, pInfo->underover); pInfo->underover = 0; /* Reset the (under|over)flow status */ if (pInfo->renderTail != pInfo->renderHead) { DATAPACKET* packet = pInfo->renderPackets[pInfo->renderTail & cPacketsArrayMask].packet; assert(packet != 0); assert(packet->Header.Data != 0); PaUtil_SetOutputFrameCount(&pInfo->stream->bufferProcessor, pInfo->stream->render.framesPerBuffer); for(i=0;istream->userOutputChannels;i++) { /* Only write the user output channels. Leave the rest blank */ PaUtil_SetOutputChannel(&pInfo->stream->bufferProcessor, i, ((unsigned char*)(packet->Header.Data))+(i*pInfo->stream->render.bytesPerSample), pInfo->stream->deviceOutputChannels); } /* We will do a copy to the other channels after the data has been written */ doChannelCopy = ( pInfo->stream->userOutputChannels == 1 ); } if (inputFramesAvailable && (!pInfo->stream->userOutputChannels || inputFramesAvailable >= (int)pInfo->stream->render.framesPerBuffer)) { unsigned wrapCntr = 0; void* data[2] = {0}; ring_buffer_size_t size[2] = {0}; /* If full-duplex, we just extract output buffer number of frames */ if (pInfo->stream->userOutputChannels) { inputFramesAvailable = min(inputFramesAvailable, (int)pInfo->stream->render.framesPerBuffer); } inputFramesAvailable = PaUtil_GetRingBufferReadRegions(&pInfo->stream->ringBuffer, inputFramesAvailable, &data[0], &size[0], &data[1], &size[1]); for (wrapCntr = 0; wrapCntr < 2; ++wrapCntr) { if (size[wrapCntr] == 0) break; fnSetInputFrameCount[wrapCntr](&pInfo->stream->bufferProcessor, size[wrapCntr]); for(i=0;istream->userInputChannels;i++) { /* Only read as many channels as the user wants */ fnSetInputChannel[wrapCntr](&pInfo->stream->bufferProcessor, i, ((unsigned char*)(data[wrapCntr]))+(i*pInfo->stream->capture.bytesPerSample), pInfo->stream->deviceInputChannels); } } } else { /* We haven't consumed anything from the ring buffer... */ inputFramesAvailable = 0; /* If we have full-duplex, this is at startup, so mark no-input! */ if (pInfo->stream->userOutputChannels>0 && pInfo->stream->userInputChannels>0) { PA_HP_TRACE((pInfo->stream->hLog, "Input startup, marking no input.")); PaUtil_SetNoInput(&pInfo->stream->bufferProcessor); } } if (processFullDuplex) /* full duplex */ { /* Only call the EndBufferProcessing function when the total input frames == total output frames */ const unsigned long totalInputFrameCount = pInfo->stream->bufferProcessor.hostInputFrameCount[0] + pInfo->stream->bufferProcessor.hostInputFrameCount[1]; const unsigned long totalOutputFrameCount = pInfo->stream->bufferProcessor.hostOutputFrameCount[0] + pInfo->stream->bufferProcessor.hostOutputFrameCount[1]; if(totalInputFrameCount == totalOutputFrameCount && totalOutputFrameCount != 0) { framesProcessed = PaUtil_EndBufferProcessing(&pInfo->stream->bufferProcessor, &pInfo->cbResult); } else { framesProcessed = 0; } } else { framesProcessed = PaUtil_EndBufferProcessing(&pInfo->stream->bufferProcessor, &pInfo->cbResult); } PA_HP_TRACE((pInfo->stream->hLog, "Frames processed: %u %s", framesProcessed, (pInfo->priming ? "(priming)":""))); if( doChannelCopy ) { DATAPACKET* packet = pInfo->renderPackets[pInfo->renderTail & cPacketsArrayMask].packet; /* Copy the first output channel to the other channels */ switch (pInfo->stream->render.bytesPerSample) { case 2: DuplicateFirstChannelInt16(packet->Header.Data, pInfo->stream->deviceOutputChannels, pInfo->stream->render.framesPerBuffer); break; case 3: DuplicateFirstChannelInt24(packet->Header.Data, pInfo->stream->deviceOutputChannels, pInfo->stream->render.framesPerBuffer); break; case 4: DuplicateFirstChannelInt32(packet->Header.Data, pInfo->stream->deviceOutputChannels, pInfo->stream->render.framesPerBuffer); break; default: assert(0); /* Unsupported format! */ break; } } PaUtil_EndCpuLoadMeasurement( &pInfo->stream->cpuLoadMeasurer, framesProcessed ); if (inputFramesAvailable) { PaUtil_AdvanceRingBufferReadIndex(&pInfo->stream->ringBuffer, inputFramesAvailable); } if (pInfo->renderTail != pInfo->renderHead) { if (!pInfo->stream->streamStop) { result = pInfo->stream->render.pPin->fnSubmitHandler(pInfo, pInfo->renderTail); if (result != paNoError) { PA_HP_TRACE((pInfo->stream->hLog, "Capture submit handler failed with result %d", result)); return result; } } pInfo->renderTail++; if (!pInfo->pinsStarted && pInfo->priming == 0) { /* We start the pins here to allow "prime time" */ if ((result = StartPins(pInfo)) == paNoError) { PA_HP_TRACE((pInfo->stream->hLog, "Starting pins!")); pInfo->pinsStarted = 1; } } } } return result; } static VOID CALLBACK TimerAPCWaveRTPolledMode( LPVOID lpArgToCompletionRoutine, DWORD dwTimerLowValue, DWORD dwTimerHighValue) { HANDLE* pHandles = (HANDLE*)lpArgToCompletionRoutine; if (pHandles[0]) SetEvent(pHandles[0]); if (pHandles[1]) SetEvent(pHandles[1]); } static DWORD GetCurrentTimeInMillisecs() { return timeGetTime(); } PA_THREAD_FUNC ProcessingThread(void* pParam) { PaError result = paNoError; HANDLE hAVRT = NULL; HANDLE hTimer = NULL; HANDLE *handleArray = NULL; HANDLE timerEventHandles[2] = {0}; unsigned noOfHandles = 0; unsigned captureEvents = 0; unsigned renderEvents = 0; unsigned timerPeriod = 0; DWORD timeStamp[2] = {0}; PaProcessThreadInfo info; memset(&info, 0, sizeof(PaProcessThreadInfo)); info.stream = (PaWinWdmStream*)pParam; info.stream->threadResult = paNoError; PA_LOGE_; info.ti.inputBufferAdcTime = 0.0; info.ti.currentTime = 0.0; info.ti.outputBufferDacTime = 0.0; PA_DEBUG(("In buffer len: %.3f ms\n",(2000*info.stream->capture.framesPerBuffer) / info.stream->streamRepresentation.streamInfo.sampleRate)); PA_DEBUG(("Out buffer len: %.3f ms\n",(2000*info.stream->render.framesPerBuffer) / info.stream->streamRepresentation.streamInfo.sampleRate)); info.timeout = (DWORD)max( (2000*info.stream->render.framesPerBuffer/info.stream->streamRepresentation.streamInfo.sampleRate + 0.5), (2000*info.stream->capture.framesPerBuffer/info.stream->streamRepresentation.streamInfo.sampleRate + 0.5)); info.timeout = max(info.timeout*8, 100); timerPeriod = info.timeout; PA_DEBUG(("Timeout = %ld ms\n",info.timeout)); /* Allocate handle array */ handleArray = (HANDLE*)PaUtil_AllocateMemory((info.stream->capture.noOfPackets + info.stream->render.noOfPackets + 1) * sizeof(HANDLE)); /* Setup handle array for WFMO */ if (info.stream->capture.pPin != 0) { handleArray[noOfHandles++] = info.stream->capture.events[0]; if (info.stream->capture.pPin->parentFilter->devInfo.streamingType == Type_kWaveCyclic) { unsigned i; for(i=1; i < info.stream->capture.noOfPackets; ++i) { handleArray[noOfHandles++] = info.stream->capture.events[i]; } } captureEvents = noOfHandles; renderEvents = noOfHandles; } if (info.stream->render.pPin != 0) { handleArray[noOfHandles++] = info.stream->render.events[0]; if (info.stream->render.pPin->parentFilter->devInfo.streamingType == Type_kWaveCyclic) { unsigned i; for(i=1; i < info.stream->render.noOfPackets; ++i) { handleArray[noOfHandles++] = info.stream->render.events[i]; } } renderEvents = noOfHandles; } handleArray[noOfHandles++] = info.stream->eventAbort; assert(noOfHandles <= (info.stream->capture.noOfPackets + info.stream->render.noOfPackets + 1)); /* Prepare render and capture pins */ if ((result = PreparePinsForStart(&info)) != paNoError) { PA_DEBUG(("Failed to prepare device(s)!\n")); goto error; } /* Init high speed logger */ if (PaUtil_InitializeHighSpeedLog(&info.stream->hLog, 1000000) != paNoError) { PA_DEBUG(("Failed to init high speed logger!\n")); goto error; } /* Heighten priority here */ hAVRT = BumpThreadPriority(); /* If input only, we start the pins immediately */ if (info.stream->render.pPin == 0) { if ((result = StartPins(&info)) != paNoError) { PA_DEBUG(("Failed to start device(s)!\n")); goto error; } info.pinsStarted = 1; } /* Handle WaveRT polled mode */ { const unsigned fs = (unsigned)info.stream->streamRepresentation.streamInfo.sampleRate; if (info.stream->capture.pPin != 0 && info.stream->capture.pPin->pinKsSubType == SubType_kPolled) { timerEventHandles[0] = info.stream->capture.events[0]; timerPeriod = min(timerPeriod, (1000*info.stream->capture.framesPerBuffer)/fs); } if (info.stream->render.pPin != 0 && info.stream->render.pPin->pinKsSubType == SubType_kPolled) { timerEventHandles[1] = info.stream->render.events[0]; timerPeriod = min(timerPeriod, (1000*info.stream->render.framesPerBuffer)/fs); } if (timerEventHandles[0] || timerEventHandles[1]) { LARGE_INTEGER dueTime = {0}; timerPeriod=max(timerPeriod/5,1); PA_DEBUG(("Timer event handles=0x%04X,0x%04X period=%u ms", timerEventHandles[0], timerEventHandles[1], timerPeriod)); hTimer = CreateWaitableTimer(0, FALSE, NULL); if (hTimer == NULL) { result = paUnanticipatedHostError; goto error; } /* invoke first timeout immediately */ if (!SetWaitableTimer(hTimer, &dueTime, timerPeriod, TimerAPCWaveRTPolledMode, timerEventHandles, FALSE)) { result = paUnanticipatedHostError; goto error; } PA_DEBUG(("Waitable timer started, period = %u ms\n", timerPeriod)); } } /* Mark stream as active */ info.stream->streamActive = 1; info.stream->threadResult = paNoError; /* Up and running... */ SetEvent(info.stream->eventStreamStart[StreamStart_kOk]); /* Take timestamp here */ timeStamp[0] = timeStamp[1] = GetCurrentTimeInMillisecs(); while(!info.stream->streamAbort) { unsigned doProcessing = 1; unsigned wait = WaitForMultipleObjects(noOfHandles, handleArray, FALSE, 0); unsigned eventSignalled = wait - WAIT_OBJECT_0; DWORD dwCurrentTime = 0; if (wait == WAIT_FAILED) { PA_DEBUG(("Wait failed = %ld! \n",wait)); break; } if (wait == WAIT_TIMEOUT) { wait = WaitForMultipleObjectsEx(noOfHandles, handleArray, FALSE, 50, TRUE); eventSignalled = wait - WAIT_OBJECT_0; } else { if (eventSignalled < captureEvents) { if (PaUtil_GetRingBufferWriteAvailable(&info.stream->ringBuffer) == 0) { PA_HP_TRACE((info.stream->hLog, "!!!!! Input overflow !!!!!")); info.underover |= paInputOverflow; } } else if (eventSignalled < renderEvents) { if (!info.priming && info.renderHead - info.renderTail > 1) { PA_HP_TRACE((info.stream->hLog, "!!!!! Output underflow !!!!!")); info.underover |= paOutputUnderflow; } } } /* Get event time */ dwCurrentTime = GetCurrentTimeInMillisecs(); /* Since we can mix capture/render devices between WaveCyclic, WaveRT polled and WaveRT notification (3x3 combinations), we can't rely on the timeout of WFMO to check for device timeouts, we need to keep tally. */ if (info.stream->capture.pPin && (dwCurrentTime - timeStamp[0]) >= info.timeout) { PA_DEBUG(("Timeout for capture device (%u ms)!", info.timeout, (dwCurrentTime - timeStamp[0]))); result = paTimedOut; break; } if (info.stream->render.pPin && (dwCurrentTime - timeStamp[1]) >= info.timeout) { PA_DEBUG(("Timeout for render device (%u ms)!", info.timeout, (dwCurrentTime - timeStamp[1]))); result = paTimedOut; break; } if (wait == WAIT_IO_COMPLETION) { /* Waitable timer has fired! */ PA_HP_TRACE((info.stream->hLog, "WAIT_IO_COMPLETION")); continue; } if (wait == WAIT_TIMEOUT) { continue; } else { if (eventSignalled < captureEvents) { if (info.stream->capture.pPin->fnEventHandler(&info, eventSignalled) == paNoError) { timeStamp[0] = dwCurrentTime; /* Since we use the ring buffer, we can submit the buffers directly */ if (!info.stream->streamStop) { result = info.stream->capture.pPin->fnSubmitHandler(&info, info.captureTail); if (result != paNoError) { PA_HP_TRACE((info.stream->hLog, "Capture submit handler failed with result %d", result)); break; } } ++info.captureTail; /* If full-duplex, let _only_ render event trigger processing. We still need the stream stop handling working, so let that be processed anyways... */ if (info.stream->userOutputChannels > 0) { doProcessing = 0; } } } else if (eventSignalled < renderEvents) { timeStamp[1] = dwCurrentTime; eventSignalled -= captureEvents; info.stream->render.pPin->fnEventHandler(&info, eventSignalled); } else { assert(info.stream->streamAbort); PA_HP_TRACE((info.stream->hLog, "Stream abort!")); continue; } } /* Handle processing */ if (doProcessing) { result = PaDoProcessing(&info); if (result != paNoError) { PA_HP_TRACE((info.stream->hLog, "PaDoProcessing failed!")); break; } } if(info.stream->streamStop && info.cbResult != paComplete) { PA_HP_TRACE((info.stream->hLog, "Stream stop! pending=%d",info.pending)); info.cbResult = paComplete; /* Stop, but play remaining buffers */ } if(info.pending<=0) { PA_HP_TRACE((info.stream->hLog, "pending==0 finished...")); break; } if((!info.stream->render.pPin)&&(info.cbResult!=paContinue)) { PA_HP_TRACE((info.stream->hLog, "record only cbResult=%d...",info.cbResult)); break; } } PA_DEBUG(("Finished processing loop\n")); info.stream->threadResult = result; goto bailout; error: PA_DEBUG(("Error starting processing thread\n")); /* Set the "error" event together with result */ info.stream->threadResult = result; SetEvent(info.stream->eventStreamStart[StreamStart_kFailed]); bailout: if (hTimer) { PA_DEBUG(("Waitable timer stopped\n", timerPeriod)); CancelWaitableTimer(hTimer); CloseHandle(hTimer); hTimer = 0; } if (info.pinsStarted) { StopPins(&info); } /* Lower prio here */ DropThreadPriority(hAVRT); if (handleArray != NULL) { PaUtil_FreeMemory(handleArray); } #if PA_TRACE_REALTIME_EVENTS if (info.stream->hLog) { PA_DEBUG(("Dumping highspeed trace...\n")); PaUtil_DumpHighSpeedLog(info.stream->hLog, "hp_trace.log"); PaUtil_DiscardHighSpeedLog(info.stream->hLog); info.stream->hLog = 0; } #endif info.stream->streamActive = 0; if((!info.stream->streamStop)&&(!info.stream->streamAbort)) { /* Invoke the user stream finished callback */ /* Only do it from here if not being stopped/aborted by user */ if( info.stream->streamRepresentation.streamFinishedCallback != 0 ) info.stream->streamRepresentation.streamFinishedCallback( info.stream->streamRepresentation.userData ); } info.stream->streamStop = 0; info.stream->streamAbort = 0; PA_LOGL_; return 0; } static PaError StartStream( PaStream *s ) { PaError result = paNoError; PaWinWdmStream *stream = (PaWinWdmStream*)s; PA_LOGE_; if (stream->streamThread != NULL) { return paStreamIsNotStopped; } stream->streamStop = 0; stream->streamAbort = 0; ResetStreamEvents(stream); PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); stream->oldProcessPriority = GetPriorityClass(GetCurrentProcess()); /* Uncomment the following line to enable dynamic boosting of the process * priority to real time for best low latency support * Disabled by default because RT processes can easily block the OS */ /*ret = SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS); PA_DEBUG(("Class ret = %d;",ret));*/ stream->streamThread = CREATE_THREAD_FUNCTION (NULL, 0, ProcessingThread, stream, CREATE_SUSPENDED, NULL); if(stream->streamThread == NULL) { result = paInsufficientMemory; goto end; } ResumeThread(stream->streamThread); switch (WaitForMultipleObjects(2, stream->eventStreamStart, FALSE, 5000)) { case WAIT_OBJECT_0 + StreamStart_kOk: PA_DEBUG(("Processing thread started!\n")); result = paNoError; /* streamActive is set in processing thread */ stream->streamStarted = 1; break; case WAIT_OBJECT_0 + StreamStart_kFailed: PA_DEBUG(("Processing thread start failed! (result=%d)\n", stream->threadResult)); result = stream->threadResult; /* Wait for the stream to really exit */ WaitForSingleObject(stream->streamThread, 200); CloseHandle(stream->streamThread); stream->streamThread = 0; break; case WAIT_TIMEOUT: default: result = paTimedOut; PaWinWDM_SetLastErrorInfo(result, "Failed to start processing thread (timeout)!"); break; } end: PA_LOGL_; return result; } static PaError StopStream( PaStream *s ) { PaError result = paNoError; PaWinWdmStream *stream = (PaWinWdmStream*)s; BOOL doCb = FALSE; PA_LOGE_; if(stream->streamActive) { DWORD dwExitCode; doCb = TRUE; stream->streamStop = 1; if (GetExitCodeThread(stream->streamThread, &dwExitCode) && dwExitCode == STILL_ACTIVE) { if (WaitForSingleObject(stream->streamThread, INFINITE) != WAIT_OBJECT_0) { PA_DEBUG(("StopStream: stream thread terminated\n")); TerminateThread(stream->streamThread, -1); result = paTimedOut; } } else { PA_DEBUG(("StopStream: GECT says not active, but streamActive is not false ??")); result = paUnanticipatedHostError; PaWinWDM_SetLastErrorInfo(result, "StopStream: GECT says not active, but streamActive = %d", stream->streamActive); } } else { if (stream->threadResult != paNoError) { PA_DEBUG(("StopStream: Stream not active (%d)\n", stream->threadResult)); result = stream->threadResult; stream->threadResult = paNoError; } } if (stream->streamThread != NULL) { CloseHandle(stream->streamThread); stream->streamThread = 0; } stream->streamStarted = 0; stream->streamActive = 0; if(doCb) { /* Do user callback now after all state has been reset */ /* This means it should be safe for the called function */ /* to invoke e.g. StartStream */ if( stream->streamRepresentation.streamFinishedCallback != 0 ) stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); } PA_LOGL_; return result; } static PaError AbortStream( PaStream *s ) { PaError result = paNoError; PaWinWdmStream *stream = (PaWinWdmStream*)s; int doCb = 0; PA_LOGE_; if(stream->streamActive) { doCb = 1; stream->streamAbort = 1; SetEvent(stream->eventAbort); /* Signal immediately */ if (WaitForSingleObject(stream->streamThread, 10000) != WAIT_OBJECT_0) { TerminateThread(stream->streamThread, -1); result = paTimedOut; PA_DEBUG(("AbortStream: stream thread terminated\n")); } assert(!stream->streamActive); } CloseHandle(stream->streamThread); stream->streamThread = NULL; stream->streamStarted = 0; if(doCb) { /* Do user callback now after all state has been reset */ /* This means it should be safe for the called function */ /* to invoke e.g. StartStream */ if( stream->streamRepresentation.streamFinishedCallback != 0 ) stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); } stream->streamActive = 0; stream->streamStarted = 0; PA_LOGL_; return result; } static PaError IsStreamStopped( PaStream *s ) { PaWinWdmStream *stream = (PaWinWdmStream*)s; int result = 0; PA_LOGE_; if(!stream->streamStarted) result = 1; PA_LOGL_; return result; } static PaError IsStreamActive( PaStream *s ) { PaWinWdmStream *stream = (PaWinWdmStream*)s; int result = 0; PA_LOGE_; if(stream->streamActive) result = 1; PA_LOGL_; return result; } static PaTime GetStreamTime( PaStream* s ) { PA_LOGE_; PA_LOGL_; (void)s; return PaUtil_GetTime(); } static double GetStreamCpuLoad( PaStream* s ) { PaWinWdmStream *stream = (PaWinWdmStream*)s; double result; PA_LOGE_; result = PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); PA_LOGL_; return result; } /* As separate stream interfaces are used for blocking and callback streams, the following functions can be guaranteed to only be called for blocking streams. */ static PaError ReadStream( PaStream* s, void *buffer, unsigned long frames ) { PaWinWdmStream *stream = (PaWinWdmStream*)s; PA_LOGE_; /* suppress unused variable warnings */ (void) buffer; (void) frames; (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ PA_LOGL_; return paInternalError; } static PaError WriteStream( PaStream* s, const void *buffer, unsigned long frames ) { PaWinWdmStream *stream = (PaWinWdmStream*)s; PA_LOGE_; /* suppress unused variable warnings */ (void) buffer; (void) frames; (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ PA_LOGL_; return paInternalError; } static signed long GetStreamReadAvailable( PaStream* s ) { PaWinWdmStream *stream = (PaWinWdmStream*)s; PA_LOGE_; /* suppress unused variable warnings */ (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ PA_LOGL_; return 0; } static signed long GetStreamWriteAvailable( PaStream* s ) { PaWinWdmStream *stream = (PaWinWdmStream*)s; PA_LOGE_; /* suppress unused variable warnings */ (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ PA_LOGL_; return 0; } /***************************************************************************************/ /* Event and submit handlers for WaveCyclic */ /***************************************************************************************/ static PaError PaPinCaptureEventHandler_WaveCyclic(PaProcessThreadInfo* pInfo, unsigned eventIndex) { PaError result = paNoError; ring_buffer_size_t frameCount; DATAPACKET* packet = pInfo->stream->capture.packets + eventIndex; assert( eventIndex < pInfo->stream->capture.noOfPackets ); if (packet->Header.DataUsed == 0) { PA_HP_TRACE((pInfo->stream->hLog, ">>> Capture bogus event (no data): idx=%u", eventIndex)); /* Bogus event, reset! This is to handle the behavior of this USB mic: http://shop.xtz.se/measurement-system/microphone-to-dirac-live-room-correction-suite on startup of streaming, where it erroneously sets the event without the corresponding buffer being filled (DataUsed == 0) */ ResetEvent(packet->Signal.hEvent); result = -1; /* Only need this to be NOT paNoError */ } else { pInfo->capturePackets[pInfo->captureHead & cPacketsArrayMask].packet = packet; frameCount = PaUtil_WriteRingBuffer(&pInfo->stream->ringBuffer, packet->Header.Data, pInfo->stream->capture.framesPerBuffer); PA_HP_TRACE((pInfo->stream->hLog, ">>> Capture event: idx=%u (frames=%u)", eventIndex, frameCount)); ++pInfo->captureHead; } --pInfo->pending; /* This needs to be done in either case */ return result; } static PaError PaPinCaptureSubmitHandler_WaveCyclic(PaProcessThreadInfo* pInfo, unsigned eventIndex) { PaError result = paNoError; DATAPACKET* packet = pInfo->capturePackets[pInfo->captureTail & cPacketsArrayMask].packet; pInfo->capturePackets[pInfo->captureTail & cPacketsArrayMask].packet = 0; assert(packet != 0); PA_HP_TRACE((pInfo->stream->hLog, "Capture submit: %u", eventIndex)); packet->Header.DataUsed = 0; /* Reset for reuse */ ResetEvent(packet->Signal.hEvent); result = PinRead(pInfo->stream->capture.pPin->handle, packet); ++pInfo->pending; return result; } static PaError PaPinRenderEventHandler_WaveCyclic(PaProcessThreadInfo* pInfo, unsigned eventIndex) { assert( eventIndex < pInfo->stream->render.noOfPackets ); pInfo->renderPackets[pInfo->renderHead & cPacketsArrayMask].packet = pInfo->stream->render.packets + eventIndex; PA_HP_TRACE((pInfo->stream->hLog, "<<< Render event : idx=%u head=%u", eventIndex, pInfo->renderHead)); ++pInfo->renderHead; --pInfo->pending; return paNoError; } static PaError PaPinRenderSubmitHandler_WaveCyclic(PaProcessThreadInfo* pInfo, unsigned eventIndex) { PaError result = paNoError; DATAPACKET* packet = pInfo->renderPackets[pInfo->renderTail & cPacketsArrayMask].packet; pInfo->renderPackets[pInfo->renderTail & cPacketsArrayMask].packet = 0; assert(packet != 0); PA_HP_TRACE((pInfo->stream->hLog, "Render submit : %u idx=%u", pInfo->renderTail, (unsigned)(packet - pInfo->stream->render.packets))); ResetEvent(packet->Signal.hEvent); result = PinWrite(pInfo->stream->render.pPin->handle, packet); /* Reset event, just in case we have an analogous situation to capture (see PaPinCaptureSubmitHandler_WaveCyclic) */ ++pInfo->pending; if (pInfo->priming) { --pInfo->priming; } return result; } /***************************************************************************************/ /* Event and submit handlers for WaveRT */ /***************************************************************************************/ static PaError PaPinCaptureEventHandler_WaveRTEvent(PaProcessThreadInfo* pInfo, unsigned eventIndex) { unsigned long pos; unsigned realInBuf; unsigned frameCount; PaWinWdmIOInfo* pCapture = &pInfo->stream->capture; const unsigned halfInputBuffer = pCapture->hostBufferSize >> 1; PaWinWdmPin* pin = pCapture->pPin; DATAPACKET* packet = 0; /* Get hold of current ADC position */ pin->fnAudioPosition(pin, &pos); /* Wrap it (robi: why not use hw latency compensation here ?? because pos then gets _way_ off from where it should be, i.e. at beginning or half buffer position. Why? No idea.) */ pos %= pCapture->hostBufferSize; /* Then realInBuf will point to "other" half of double buffer */ realInBuf = pos < halfInputBuffer ? 1U : 0U; packet = pInfo->stream->capture.packets + realInBuf; /* Call barrier (or dummy) */ pin->fnMemBarrier(); /* Put it in queue */ frameCount = PaUtil_WriteRingBuffer(&pInfo->stream->ringBuffer, packet->Header.Data, pCapture->framesPerBuffer); pInfo->capturePackets[pInfo->captureHead & cPacketsArrayMask].packet = packet; PA_HP_TRACE((pInfo->stream->hLog, "Capture event (WaveRT): idx=%u head=%u (pos = %4.1lf%%, frames=%u)", realInBuf, pInfo->captureHead, (pos * 100.0 / pCapture->hostBufferSize), frameCount)); ++pInfo->captureHead; --pInfo->pending; return paNoError; } static PaError PaPinCaptureEventHandler_WaveRTPolled(PaProcessThreadInfo* pInfo, unsigned eventIndex) { unsigned long pos; unsigned bytesToRead; PaWinWdmIOInfo* pCapture = &pInfo->stream->capture; const unsigned halfInputBuffer = pCapture->hostBufferSize>>1; PaWinWdmPin* pin = pInfo->stream->capture.pPin; /* Get hold of current ADC position */ pin->fnAudioPosition(pin, &pos); /* Wrap it (robi: why not use hw latency compensation here ?? because pos then gets _way_ off from where it should be, i.e. at beginning or half buffer position. Why? No idea.) */ /* Compensate for HW FIFO to get to last read buffer position */ pos += pin->hwLatency; pos %= pCapture->hostBufferSize; /* Need to align position on frame boundary */ pos &= ~(pCapture->bytesPerFrame - 1); /* Call barrier (or dummy) */ pin->fnMemBarrier(); /* Put it in "queue" */ bytesToRead = (pCapture->hostBufferSize + pos - pCapture->lastPosition) % pCapture->hostBufferSize; if (bytesToRead > 0) { unsigned frameCount = PaUtil_WriteRingBuffer(&pInfo->stream->ringBuffer, pCapture->hostBuffer + pCapture->lastPosition, bytesToRead / pCapture->bytesPerFrame); pCapture->lastPosition = (pCapture->lastPosition + frameCount * pCapture->bytesPerFrame) % pCapture->hostBufferSize; PA_HP_TRACE((pInfo->stream->hLog, "Capture event (WaveRTPolled): pos = %4.1lf%%, framesRead=%u", (pos * 100.0 / pCapture->hostBufferSize), frameCount)); ++pInfo->captureHead; --pInfo->pending; } return paNoError; } static PaError PaPinCaptureSubmitHandler_WaveRTEvent(PaProcessThreadInfo* pInfo, unsigned eventIndex) { pInfo->capturePackets[pInfo->captureTail & cPacketsArrayMask].packet = 0; ++pInfo->pending; return paNoError; } static PaError PaPinCaptureSubmitHandler_WaveRTPolled(PaProcessThreadInfo* pInfo, unsigned eventIndex) { pInfo->capturePackets[pInfo->captureTail & cPacketsArrayMask].packet = 0; ++pInfo->pending; return paNoError; } static PaError PaPinRenderEventHandler_WaveRTEvent(PaProcessThreadInfo* pInfo, unsigned eventIndex) { unsigned long pos; unsigned realOutBuf; PaWinWdmIOInfo* pRender = &pInfo->stream->render; const unsigned halfOutputBuffer = pRender->hostBufferSize >> 1; PaWinWdmPin* pin = pInfo->stream->render.pPin; PaIOPacket* ioPacket = &pInfo->renderPackets[pInfo->renderHead & cPacketsArrayMask]; /* Get hold of current DAC position */ pin->fnAudioPosition(pin, &pos); /* Compensate for HW FIFO to get to last read buffer position */ pos += pin->hwLatency; /* Wrap it */ pos %= pRender->hostBufferSize; /* And align it, not sure its really needed though */ pos &= ~(pRender->bytesPerFrame - 1); /* Then realOutBuf will point to "other" half of double buffer */ realOutBuf = pos < halfOutputBuffer ? 1U : 0U; if (pInfo->priming) { realOutBuf = pInfo->renderHead & 0x1; } ioPacket->packet = pInfo->stream->render.packets + realOutBuf; ioPacket->startByte = realOutBuf * halfOutputBuffer; ioPacket->lengthBytes = halfOutputBuffer; PA_HP_TRACE((pInfo->stream->hLog, "Render event (WaveRT) : idx=%u head=%u (pos = %4.1lf%%)", realOutBuf, pInfo->renderHead, (pos * 100.0 / pRender->hostBufferSize) )); ++pInfo->renderHead; --pInfo->pending; return paNoError; } static PaError PaPinRenderEventHandler_WaveRTPolled(PaProcessThreadInfo* pInfo, unsigned eventIndex) { unsigned long pos; unsigned realOutBuf; unsigned bytesToWrite; PaWinWdmIOInfo* pRender = &pInfo->stream->render; const unsigned halfOutputBuffer = pRender->hostBufferSize >> 1; PaWinWdmPin* pin = pInfo->stream->render.pPin; PaIOPacket* ioPacket = &pInfo->renderPackets[pInfo->renderHead & cPacketsArrayMask]; /* Get hold of current DAC position */ pin->fnAudioPosition(pin, &pos); /* Compensate for HW FIFO to get to last read buffer position */ pos += pin->hwLatency; /* Wrap it */ pos %= pRender->hostBufferSize; /* And align it, not sure its really needed though */ pos &= ~(pRender->bytesPerFrame - 1); if (pInfo->priming) { realOutBuf = pInfo->renderHead & 0x1; ioPacket->packet = pInfo->stream->render.packets + realOutBuf; ioPacket->startByte = realOutBuf * halfOutputBuffer; ioPacket->lengthBytes = halfOutputBuffer; ++pInfo->renderHead; --pInfo->pending; } else { bytesToWrite = (pRender->hostBufferSize + pos - pRender->lastPosition) % pRender->hostBufferSize; ++pRender->pollCntr; if (bytesToWrite >= halfOutputBuffer) { realOutBuf = (pos < halfOutputBuffer) ? 1U : 0U; ioPacket->packet = pInfo->stream->render.packets + realOutBuf; pRender->lastPosition = realOutBuf ? 0U : halfOutputBuffer; ioPacket->startByte = realOutBuf * halfOutputBuffer; ioPacket->lengthBytes = halfOutputBuffer; ++pInfo->renderHead; --pInfo->pending; PA_HP_TRACE((pInfo->stream->hLog, "Render event (WaveRTPolled) : idx=%u head=%u (pos = %4.1lf%%, cnt=%u)", realOutBuf, pInfo->renderHead, (pos * 100.0 / pRender->hostBufferSize), pRender->pollCntr)); pRender->pollCntr = 0; } } return paNoError; } static PaError PaPinRenderSubmitHandler_WaveRTEvent(PaProcessThreadInfo* pInfo, unsigned eventIndex) { PaWinWdmPin* pin = pInfo->stream->render.pPin; pInfo->renderPackets[pInfo->renderTail & cPacketsArrayMask].packet = 0; /* Call barrier (if needed) */ pin->fnMemBarrier(); PA_HP_TRACE((pInfo->stream->hLog, "Render submit (WaveRT) : submit=%u", pInfo->renderTail)); ++pInfo->pending; if (pInfo->priming) { --pInfo->priming; if (pInfo->priming) { PA_HP_TRACE((pInfo->stream->hLog, "Setting WaveRT event for priming (2)")); SetEvent(pInfo->stream->render.events[0]); } } return paNoError; } static PaError PaPinRenderSubmitHandler_WaveRTPolled(PaProcessThreadInfo* pInfo, unsigned eventIndex) { PaWinWdmPin* pin = pInfo->stream->render.pPin; pInfo->renderPackets[pInfo->renderTail & cPacketsArrayMask].packet = 0; /* Call barrier (if needed) */ pin->fnMemBarrier(); PA_HP_TRACE((pInfo->stream->hLog, "Render submit (WaveRTPolled) : submit=%u", pInfo->renderTail)); ++pInfo->pending; if (pInfo->priming) { --pInfo->priming; if (pInfo->priming) { PA_HP_TRACE((pInfo->stream->hLog, "Setting WaveRT event for priming (2)")); SetEvent(pInfo->stream->render.events[0]); } } return paNoError; } praat-6.0.04/external/portaudio/pa_win_wdmks.h000066400000000000000000000075541261542461700214160ustar00rootroot00000000000000#ifndef PA_WIN_WDMKS_H #define PA_WIN_WDMKS_H /* * $Id: pa_win_wdmks.h 1812 2012-02-14 09:32:57Z robiwan $ * PortAudio Portable Real-Time Audio Library * WDM/KS specific extensions * * Copyright (c) 1999-2007 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup public_header @brief WDM Kernel Streaming-specific PortAudio API extension header file. */ #include "portaudio.h" #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ typedef struct PaWinWDMKSInfo{ unsigned long size; /**< sizeof(PaWinWDMKSInfo) */ PaHostApiTypeId hostApiType; /**< paWDMKS */ unsigned long version; /**< 1 */ /* The number of packets to use for WaveCyclic devices, range is [2, 8]. Set to zero for default value of 2. */ unsigned noOfPackets; } PaWinWDMKSInfo; typedef enum PaWDMKSType { Type_kNotUsed, Type_kWaveCyclic, Type_kWaveRT, Type_kCnt, } PaWDMKSType; typedef enum PaWDMKSSubType { SubType_kUnknown, SubType_kNotification, SubType_kPolled, SubType_kCnt, } PaWDMKSSubType; typedef struct PaWinWDMKSDeviceInfo { wchar_t filterPath[MAX_PATH]; /**< KS filter path in Unicode! */ wchar_t topologyPath[MAX_PATH]; /**< Topology filter path in Unicode! */ PaWDMKSType streamingType; GUID deviceProductGuid; /**< The product GUID of the device (if supported) */ } PaWinWDMKSDeviceInfo; typedef struct PaWDMKSDirectionSpecificStreamInfo { PaDeviceIndex device; unsigned channels; /**< No of channels the device is opened with */ unsigned framesPerHostBuffer; /**< No of frames of the device buffer */ int endpointPinId; /**< Endpoint pin ID (on topology filter if topologyName is not empty) */ int muxNodeId; /**< Only valid for input */ PaWDMKSSubType streamingSubType; /**< Not known until device is opened for streaming */ } PaWDMKSDirectionSpecificStreamInfo; typedef struct PaWDMKSSpecificStreamInfo { PaWDMKSDirectionSpecificStreamInfo input; PaWDMKSDirectionSpecificStreamInfo output; } PaWDMKSSpecificStreamInfo; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_WIN_DS_H */ praat-6.0.04/external/portaudio/pa_win_wdmks_utils.c000066400000000000000000000302061261542461700226170ustar00rootroot00000000000000/* * PortAudio Portable Real-Time Audio Library * Windows WDM KS utilities * * Copyright (c) 1999 - 2007 Andrew Baldwin, Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ #include #include #ifndef WAVE_FORMAT_IEEE_FLOAT #define WAVE_FORMAT_IEEE_FLOAT 0x0003 // MinGW32 does not define this #endif #ifndef _WAVEFORMATEXTENSIBLE_ #define _WAVEFORMATEXTENSIBLE_ // MinGW32 does not define this #endif #ifndef _INC_MMREG #define _INC_MMREG // for STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT #endif #include // MinGW32 does not define this automatically #if defined(__GNUC__) #include "../../hostapi/wasapi/mingw-include/ks.h" #include "../../hostapi/wasapi/mingw-include/ksmedia.h" #else #include #include #endif #include // just for some development printfs #include "portaudio.h" #include "pa_util.h" #include "pa_win_wdmks_utils.h" #if !defined(PA_WDMKS_NO_KSGUID_LIB) && !defined(PAWIN_WDMKS_NO_KSGUID_LIB) && !defined(__GNUC__) #if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */ #pragma comment( lib, "ksguid.lib" ) #endif #define pa_KSDATAFORMAT_TYPE_AUDIO KSDATAFORMAT_TYPE_AUDIO #define pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT KSDATAFORMAT_SUBTYPE_IEEE_FLOAT #define pa_KSDATAFORMAT_SUBTYPE_PCM KSDATAFORMAT_SUBTYPE_PCM #define pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX KSDATAFORMAT_SUBTYPE_WAVEFORMATEX #define pa_KSMEDIUMSETID_Standard KSMEDIUMSETID_Standard #define pa_KSINTERFACESETID_Standard KSINTERFACESETID_Standard #define pa_KSPROPSETID_Pin KSPROPSETID_Pin #else static const GUID pa_KSDATAFORMAT_TYPE_AUDIO = { STATIC_KSDATAFORMAT_TYPE_AUDIO }; static const GUID pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT }; static const GUID pa_KSDATAFORMAT_SUBTYPE_PCM = { STATIC_KSDATAFORMAT_SUBTYPE_PCM }; static const GUID pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX = { STATIC_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX }; static const GUID pa_KSMEDIUMSETID_Standard = { STATIC_KSMEDIUMSETID_Standard }; static const GUID pa_KSINTERFACESETID_Standard = { STATIC_KSINTERFACESETID_Standard }; static const GUID pa_KSPROPSETID_Pin = { STATIC_KSPROPSETID_Pin }; #endif #define pa_IS_VALID_WAVEFORMATEX_GUID(Guid)\ (!memcmp(((PUSHORT)&pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX) + 1, ((PUSHORT)(Guid)) + 1, sizeof(GUID) - sizeof(USHORT))) static PaError WdmGetPinPropertySimple( HANDLE handle, unsigned long pinId, unsigned long property, void* value, unsigned long valueSize ) { DWORD bytesReturned; KSP_PIN ksPProp; ksPProp.Property.Set = pa_KSPROPSETID_Pin; ksPProp.Property.Id = property; ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; ksPProp.PinId = pinId; ksPProp.Reserved = 0; if( DeviceIoControl( handle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN), value, valueSize, &bytesReturned, NULL ) == 0 || bytesReturned != valueSize ) { return paUnanticipatedHostError; } else { return paNoError; } } static PaError WdmGetPinPropertyMulti( HANDLE handle, unsigned long pinId, unsigned long property, KSMULTIPLE_ITEM** ksMultipleItem) { unsigned long multipleItemSize = 0; KSP_PIN ksPProp; DWORD bytesReturned; *ksMultipleItem = 0; ksPProp.Property.Set = pa_KSPROPSETID_Pin; ksPProp.Property.Id = property; ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; ksPProp.PinId = pinId; ksPProp.Reserved = 0; if( DeviceIoControl( handle, IOCTL_KS_PROPERTY, &ksPProp.Property, sizeof(KSP_PIN), NULL, 0, &multipleItemSize, NULL ) == 0 && GetLastError() != ERROR_MORE_DATA ) { return paUnanticipatedHostError; } *ksMultipleItem = (KSMULTIPLE_ITEM*)PaUtil_AllocateMemory( multipleItemSize ); if( !*ksMultipleItem ) { return paInsufficientMemory; } if( DeviceIoControl( handle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN), (void*)*ksMultipleItem, multipleItemSize, &bytesReturned, NULL ) == 0 || bytesReturned != multipleItemSize ) { PaUtil_FreeMemory( ksMultipleItem ); return paUnanticipatedHostError; } return paNoError; } static int GetKSFilterPinCount( HANDLE deviceHandle ) { DWORD result; if( WdmGetPinPropertySimple( deviceHandle, 0, KSPROPERTY_PIN_CTYPES, &result, sizeof(result) ) == paNoError ){ return result; }else{ return 0; } } static KSPIN_COMMUNICATION GetKSFilterPinPropertyCommunication( HANDLE deviceHandle, int pinId ) { KSPIN_COMMUNICATION result; if( WdmGetPinPropertySimple( deviceHandle, pinId, KSPROPERTY_PIN_COMMUNICATION, &result, sizeof(result) ) == paNoError ){ return result; }else{ return KSPIN_COMMUNICATION_NONE; } } static KSPIN_DATAFLOW GetKSFilterPinPropertyDataflow( HANDLE deviceHandle, int pinId ) { KSPIN_DATAFLOW result; if( WdmGetPinPropertySimple( deviceHandle, pinId, KSPROPERTY_PIN_DATAFLOW, &result, sizeof(result) ) == paNoError ){ return result; }else{ return (KSPIN_DATAFLOW)0; } } static int KSFilterPinPropertyIdentifiersInclude( HANDLE deviceHandle, int pinId, unsigned long property, const GUID *identifierSet, unsigned long identifierId ) { KSMULTIPLE_ITEM* item = NULL; KSIDENTIFIER* identifier; int i; int result = 0; if( WdmGetPinPropertyMulti( deviceHandle, pinId, property, &item) != paNoError ) return 0; identifier = (KSIDENTIFIER*)(item+1); for( i = 0; i < (int)item->Count; i++ ) { if( !memcmp( (void*)&identifier[i].Set, (void*)identifierSet, sizeof( GUID ) ) && ( identifier[i].Id == identifierId ) ) { result = 1; break; } } PaUtil_FreeMemory( item ); return result; } /* return the maximum channel count supported by any pin on the device. if isInput is non-zero we query input pins, otherwise output pins. */ int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInput ) { HANDLE deviceHandle; ULONG i; int pinCount, pinId; int result = 0; KSPIN_DATAFLOW requiredDataflowDirection = (isInput ? KSPIN_DATAFLOW_OUT : KSPIN_DATAFLOW_IN ); if( !wcharDevicePath ) return 0; deviceHandle = CreateFileW( (LPCWSTR)wcharDevicePath, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL ); if( deviceHandle == INVALID_HANDLE_VALUE ) return 0; pinCount = GetKSFilterPinCount( deviceHandle ); for( pinId = 0; pinId < pinCount; ++pinId ) { KSPIN_COMMUNICATION communication = GetKSFilterPinPropertyCommunication( deviceHandle, pinId ); KSPIN_DATAFLOW dataflow = GetKSFilterPinPropertyDataflow( deviceHandle, pinId ); if( ( dataflow == requiredDataflowDirection ) && (( communication == KSPIN_COMMUNICATION_SINK) || ( communication == KSPIN_COMMUNICATION_BOTH)) && ( KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId, KSPROPERTY_PIN_INTERFACES, &pa_KSINTERFACESETID_Standard, KSINTERFACE_STANDARD_STREAMING ) || KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId, KSPROPERTY_PIN_INTERFACES, &pa_KSINTERFACESETID_Standard, KSINTERFACE_STANDARD_LOOPED_STREAMING ) ) && KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId, KSPROPERTY_PIN_MEDIUMS, &pa_KSMEDIUMSETID_Standard, KSMEDIUM_STANDARD_DEVIO ) ) { KSMULTIPLE_ITEM* item = NULL; if( WdmGetPinPropertyMulti( deviceHandle, pinId, KSPROPERTY_PIN_DATARANGES, &item ) == paNoError ) { KSDATARANGE *dataRange = (KSDATARANGE*)(item+1); for( i=0; i < item->Count; ++i ){ if( pa_IS_VALID_WAVEFORMATEX_GUID(&dataRange->SubFormat) || memcmp( (void*)&dataRange->SubFormat, (void*)&pa_KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID) ) == 0 || memcmp( (void*)&dataRange->SubFormat, (void*)&pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof(GUID) ) == 0 || ( ( memcmp( (void*)&dataRange->MajorFormat, (void*)&pa_KSDATAFORMAT_TYPE_AUDIO, sizeof(GUID) ) == 0 ) && ( memcmp( (void*)&dataRange->SubFormat, (void*)&KSDATAFORMAT_SUBTYPE_WILDCARD, sizeof(GUID) ) == 0 ) ) ) { KSDATARANGE_AUDIO *dataRangeAudio = (KSDATARANGE_AUDIO*)dataRange; /* printf( ">>> %d %d %d %d %S\n", isInput, dataflow, communication, dataRangeAudio->MaximumChannels, devicePath ); if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_WAVEFORMATEX, sizeof(GUID) ) == 0 ) printf( "\tspecifier: KSDATAFORMAT_SPECIFIER_WAVEFORMATEX\n" ); else if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_DSOUND, sizeof(GUID) ) == 0 ) printf( "\tspecifier: KSDATAFORMAT_SPECIFIER_DSOUND\n" ); else if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_WILDCARD, sizeof(GUID) ) == 0 ) printf( "\tspecifier: KSDATAFORMAT_SPECIFIER_WILDCARD\n" ); else printf( "\tspecifier: ?\n" ); */ /* We assume that very high values for MaximumChannels are not useful and indicate that the driver isn't prepared to tell us the real number of channels which it supports. */ if( dataRangeAudio->MaximumChannels < 0xFFFFUL && (int)dataRangeAudio->MaximumChannels > result ) result = (int)dataRangeAudio->MaximumChannels; } dataRange = (KSDATARANGE*)( ((char*)dataRange) + dataRange->FormatSize); } PaUtil_FreeMemory( item ); } } } CloseHandle( deviceHandle ); return result; } praat-6.0.04/external/portaudio/pa_win_wdmks_utils.h000066400000000000000000000047051261542461700226310ustar00rootroot00000000000000#ifndef PA_WIN_WDMKS_UTILS_H #define PA_WIN_WDMKS_UTILS_H /* * PortAudio Portable Real-Time Audio Library * Windows WDM KS utilities * * Copyright (c) 1999 - 2007 Ross Bencina, Andrew Baldwin * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @brief Utilities for working with the Windows WDM KS API */ #ifdef __cplusplus extern "C" { #endif /** Query for the maximum number of channels supported by any pin of the specified device. Returns 0 if the query fails for any reason. @param wcharDevicePath A system level PnP interface path, supplied as a WCHAR unicode string. Declard as void* to avoid introducing a dependency on wchar_t here. @param isInput A flag specifying whether to query for input (non-zero) or output (zero) channels. */ int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInput ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_WIN_WDMKS_UTILS_H */praat-6.0.04/external/portaudio/pa_win_wmme.c000066400000000000000000004562671261542461700212420ustar00rootroot00000000000000#ifdef _WIN32 /* * $Id: pa_win_wmme.c 1874 2012-10-31 06:20:59Z rbencina $ * pa_win_wmme.c * Implementation of PortAudio for Windows MultiMedia Extensions (WMME) * * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * * Authors: Ross Bencina and Phil Burk * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /* Modification History: PLB = Phil Burk JM = Julien Maillard RDB = Ross Bencina PLB20010402 - sDevicePtrs now allocates based on sizeof(pointer) PLB20010413 - check for excessive numbers of channels PLB20010422 - apply Mike Berry's changes for CodeWarrior on PC including conditional inclusion of memory.h, and explicit typecasting on memory allocation PLB20010802 - use GlobalAlloc for sDevicesPtr instead of PaHost_AllocFastMemory PLB20010816 - pass process instead of thread to SetPriorityClass() PLB20010927 - use number of frames instead of real-time for CPULoad calculation. JM20020118 - prevent hung thread when buffers underflow. PLB20020321 - detect Win XP versus NT, 9x; fix DBUG typo; removed init of CurrentCount RDB20020411 - various renaming cleanups, factored streamData alloc and cpu usage init RDB20020417 - stopped counting WAVE_MAPPER when there were no real devices refactoring, renaming and fixed a few edge case bugs RDB20020531 - converted to V19 framework ** NOTE maintanance history is now stored in CVS ** */ /** @file @ingroup hostapi_src @brief Win32 host API implementation for the Windows MultiMedia Extensions (WMME) audio API. */ /* How it works: For both callback and blocking read/write streams we open the MME devices in CALLBACK_EVENT mode. In this mode, MME signals an Event object whenever it has finished with a buffer (either filled it for input, or played it for output). Where necessary, we block waiting for Event objects using WaitMultipleObjects(). When implementing a PA callback stream, we set up a high priority thread which waits on the MME buffer Events and drains/fills the buffers when they are ready. When implementing a PA blocking read/write stream, we simply wait on these Events (when necessary) inside the ReadStream() and WriteStream() functions. */ #include #include #include #include #include #ifndef UNDER_CE #include #endif #include /* PLB20010422 - "memory.h" doesn't work on CodeWarrior for PC. Thanks Mike Berry for the mod. */ #ifndef __MWERKS__ #include #include #endif /* __MWERKS__ */ #include "portaudio.h" #include "pa_trace.h" #include "pa_util.h" #include "pa_allocation.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_cpuload.h" #include "pa_process.h" #include "pa_debugprint.h" #include "pa_win_wmme.h" #include "pa_win_waveformat.h" #ifdef PAWIN_USE_WDMKS_DEVICE_INFO #include "pa_win_wdmks_utils.h" #ifndef DRV_QUERYDEVICEINTERFACE #define DRV_QUERYDEVICEINTERFACE (DRV_RESERVED + 12) #endif #ifndef DRV_QUERYDEVICEINTERFACESIZE #define DRV_QUERYDEVICEINTERFACESIZE (DRV_RESERVED + 13) #endif #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ /* use CreateThread for CYGWIN, _beginthreadex for all others */ #if !defined(__CYGWIN__) && !defined(_WIN32_WCE) #define CREATE_THREAD (HANDLE)_beginthreadex( 0, 0, ProcessingThreadProc, stream, 0, &stream->processingThreadId ) #define PA_THREAD_FUNC static unsigned WINAPI #define PA_THREAD_ID unsigned #else #define CREATE_THREAD CreateThread( 0, 0, ProcessingThreadProc, stream, 0, &stream->processingThreadId ) #define PA_THREAD_FUNC static DWORD WINAPI #define PA_THREAD_ID DWORD #endif #if (defined(_WIN32_WCE)) #pragma comment(lib, "Coredll.lib") #elif (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */ #pragma comment(lib, "winmm.lib") #endif /* provided in newer platform sdks */ #ifndef DWORD_PTR #if defined(_WIN64) #define DWORD_PTR unsigned __int64 #else #define DWORD_PTR unsigned long #endif #endif /************************************************* Constants ********/ #define PA_MME_USE_HIGH_DEFAULT_LATENCY_ (0) /* For debugging glitches. */ #if PA_MME_USE_HIGH_DEFAULT_LATENCY_ #define PA_MME_WIN_9X_DEFAULT_LATENCY_ (0.4) #define PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_ (4) #define PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_ (4) #define PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_HALF_DUPLEX_ (4) #define PA_MME_HOST_BUFFER_GRANULARITY_FRAMES_WHEN_UNSPECIFIED_ (16) #define PA_MME_MAX_HOST_BUFFER_SECS_ (0.3) /* Do not exceed unless user buffer exceeds */ #define PA_MME_MAX_HOST_BUFFER_BYTES_ (32 * 1024) /* Has precedence over PA_MME_MAX_HOST_BUFFER_SECS_, some drivers are known to crash with buffer sizes > 32k */ #else #define PA_MME_WIN_9X_DEFAULT_LATENCY_ (0.2) #define PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_ (2) #define PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_ (3) /* always use at least 3 input buffers for full duplex */ #define PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_HALF_DUPLEX_ (2) #define PA_MME_HOST_BUFFER_GRANULARITY_FRAMES_WHEN_UNSPECIFIED_ (16) #define PA_MME_MAX_HOST_BUFFER_SECS_ (0.1) /* Do not exceed unless user buffer exceeds */ #define PA_MME_MAX_HOST_BUFFER_BYTES_ (32 * 1024) /* Has precedence over PA_MME_MAX_HOST_BUFFER_SECS_, some drivers are known to crash with buffer sizes > 32k */ #endif /* Use higher latency for NT because it is even worse at real-time operation than Win9x. */ #define PA_MME_WIN_NT_DEFAULT_LATENCY_ (0.4) /* Default low latency for WDM based systems. This is based on a rough survey of workable latency settings using patest_wmme_find_best_latency_params.c. See pdf attached to ticket 185 for a graph of the survey results: http://www.portaudio.com/trac/ticket/185 Workable latencies varied between 40ms and ~80ms on different systems (different combinations of hardware, 32 and 64 bit, WinXP, Vista and Win7. We didn't get enough Vista results to know if Vista has systemically worse latency. For now we choose a safe value across all Windows versions here. */ #define PA_MME_WIN_WDM_DEFAULT_LATENCY_ (0.090) /* When client suggestedLatency could result in many host buffers, we aim to have around 8, based off Windows documentation that suggests that the kmixer uses 8 buffers. This choice is somewhat arbitrary here, since we havn't observed significant stability degredation with using either more, or less buffers. */ #define PA_MME_TARGET_HOST_BUFFER_COUNT_ 8 #define PA_MME_MIN_TIMEOUT_MSEC_ (1000) static const char constInputMapperSuffix_[] = " - Input"; static const char constOutputMapperSuffix_[] = " - Output"; /* copies TCHAR string to explicit char string */ char *StrTCpyToC(char *to, const TCHAR *from) { #if !defined(_UNICODE) && !defined(UNICODE) return strcpy(to, from); #else int count = wcslen(from); if (count != 0) if (WideCharToMultiByte(CP_ACP, 0, from, count, to, count, NULL, NULL) == 0) return NULL; return to; #endif } /* returns length of TCHAR string */ size_t StrTLen(const TCHAR *str) { #if !defined(_UNICODE) && !defined(UNICODE) return strlen(str); #else return wcslen(str); #endif } /********************************************************************/ typedef struct PaWinMmeStream PaWinMmeStream; /* forward declaration */ /* prototypes for functions declared in this file */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); #ifdef __cplusplus } #endif /* __cplusplus */ static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** stream, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); static PaError CloseStream( PaStream* stream ); static PaError StartStream( PaStream *stream ); static PaError StopStream( PaStream *stream ); static PaError AbortStream( PaStream *stream ); static PaError IsStreamStopped( PaStream *s ); static PaError IsStreamActive( PaStream *stream ); static PaTime GetStreamTime( PaStream *stream ); static double GetStreamCpuLoad( PaStream* stream ); static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ); static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ); static signed long GetStreamReadAvailable( PaStream* stream ); static signed long GetStreamWriteAvailable( PaStream* stream ); /* macros for setting last host error information */ #ifdef UNICODE #define PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ) \ { \ wchar_t mmeErrorTextWide[ MAXERRORLENGTH ]; \ char mmeErrorText[ MAXERRORLENGTH ]; \ waveInGetErrorText( mmresult, mmeErrorTextWide, MAXERRORLENGTH ); \ WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR,\ mmeErrorTextWide, -1, mmeErrorText, MAXERRORLENGTH, NULL, NULL ); \ PaUtil_SetLastHostErrorInfo( paMME, mmresult, mmeErrorText ); \ } #define PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ) \ { \ wchar_t mmeErrorTextWide[ MAXERRORLENGTH ]; \ char mmeErrorText[ MAXERRORLENGTH ]; \ waveOutGetErrorText( mmresult, mmeErrorTextWide, MAXERRORLENGTH ); \ WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR,\ mmeErrorTextWide, -1, mmeErrorText, MAXERRORLENGTH, NULL, NULL ); \ PaUtil_SetLastHostErrorInfo( paMME, mmresult, mmeErrorText ); \ } #else /* !UNICODE */ #define PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ) \ { \ char mmeErrorText[ MAXERRORLENGTH ]; \ waveInGetErrorText( mmresult, mmeErrorText, MAXERRORLENGTH ); \ PaUtil_SetLastHostErrorInfo( paMME, mmresult, mmeErrorText ); \ } #define PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ) \ { \ char mmeErrorText[ MAXERRORLENGTH ]; \ waveOutGetErrorText( mmresult, mmeErrorText, MAXERRORLENGTH ); \ PaUtil_SetLastHostErrorInfo( paMME, mmresult, mmeErrorText ); \ } #endif /* UNICODE */ static void PaMme_SetLastSystemError( DWORD errorCode ) { char *lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); PaUtil_SetLastHostErrorInfo( paMME, errorCode, lpMsgBuf ); LocalFree( lpMsgBuf ); } #define PA_MME_SET_LAST_SYSTEM_ERROR( errorCode ) \ PaMme_SetLastSystemError( errorCode ) /* PaError returning wrappers for some commonly used win32 functions note that we allow passing a null ptr to have no effect. */ static PaError CreateEventWithPaError( HANDLE *handle, LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCTSTR lpName ) { PaError result = paNoError; *handle = NULL; *handle = CreateEvent( lpEventAttributes, bManualReset, bInitialState, lpName ); if( *handle == NULL ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() ); } return result; } static PaError ResetEventWithPaError( HANDLE handle ) { PaError result = paNoError; if( handle ) { if( ResetEvent( handle ) == 0 ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() ); } } return result; } static PaError CloseHandleWithPaError( HANDLE handle ) { PaError result = paNoError; if( handle ) { if( CloseHandle( handle ) == 0 ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() ); } } return result; } /* PaWinMmeHostApiRepresentation - host api datastructure specific to this implementation */ typedef struct { PaUtilHostApiRepresentation inheritedHostApiRep; PaUtilStreamInterface callbackStreamInterface; PaUtilStreamInterface blockingStreamInterface; PaUtilAllocationGroup *allocations; int inputDeviceCount, outputDeviceCount; /** winMmeDeviceIds is an array of WinMme device ids. fields in the range [0, inputDeviceCount) are input device ids, and [inputDeviceCount, inputDeviceCount + outputDeviceCount) are output device ids. */ UINT *winMmeDeviceIds; } PaWinMmeHostApiRepresentation; typedef struct { PaDeviceInfo inheritedDeviceInfo; DWORD dwFormats; /**<< standard formats bitmask from the WAVEINCAPS and WAVEOUTCAPS structures */ char deviceInputChannelCountIsKnown; /**<< if the system returns 0xFFFF then we don't really know the number of supported channels (1=>known, 0=>unknown)*/ char deviceOutputChannelCountIsKnown; /**<< if the system returns 0xFFFF then we don't really know the number of supported channels (1=>known, 0=>unknown)*/ } PaWinMmeDeviceInfo; /************************************************************************* * Returns recommended device ID. * On the PC, the recommended device can be specified by the user by * setting an environment variable. For example, to use device #1. * * set PA_RECOMMENDED_OUTPUT_DEVICE=1 * * The user should first determine the available device ID by using * the supplied application "pa_devs". */ #define PA_ENV_BUF_SIZE_ (32) #define PA_REC_IN_DEV_ENV_NAME_ ("PA_RECOMMENDED_INPUT_DEVICE") #define PA_REC_OUT_DEV_ENV_NAME_ ("PA_RECOMMENDED_OUTPUT_DEVICE") static PaDeviceIndex GetEnvDefaultDeviceID( char *envName ) { PaDeviceIndex recommendedIndex = paNoDevice; DWORD hresult; char envbuf[PA_ENV_BUF_SIZE_]; #ifndef WIN32_PLATFORM_PSPC /* no GetEnvironmentVariable on PocketPC */ /* Let user determine default device by setting environment variable. */ hresult = GetEnvironmentVariableA( envName, envbuf, PA_ENV_BUF_SIZE_ ); if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE_) ) { recommendedIndex = atoi( envbuf ); } #endif return recommendedIndex; } static void InitializeDefaultDeviceIdsFromEnv( PaWinMmeHostApiRepresentation *hostApi ) { PaDeviceIndex device; /* input */ device = GetEnvDefaultDeviceID( PA_REC_IN_DEV_ENV_NAME_ ); if( device != paNoDevice && ( device >= 0 && device < hostApi->inheritedHostApiRep.info.deviceCount ) && hostApi->inheritedHostApiRep.deviceInfos[ device ]->maxInputChannels > 0 ) { hostApi->inheritedHostApiRep.info.defaultInputDevice = device; } /* output */ device = GetEnvDefaultDeviceID( PA_REC_OUT_DEV_ENV_NAME_ ); if( device != paNoDevice && ( device >= 0 && device < hostApi->inheritedHostApiRep.info.deviceCount ) && hostApi->inheritedHostApiRep.deviceInfos[ device ]->maxOutputChannels > 0 ) { hostApi->inheritedHostApiRep.info.defaultOutputDevice = device; } } /** Convert external PA ID to a windows multimedia device ID */ static UINT LocalDeviceIndexToWinMmeDeviceId( PaWinMmeHostApiRepresentation *hostApi, PaDeviceIndex device ) { assert( device >= 0 && device < hostApi->inputDeviceCount + hostApi->outputDeviceCount ); return hostApi->winMmeDeviceIds[ device ]; } static int SampleFormatAndWinWmmeSpecificFlagsToLinearWaveFormatTag( PaSampleFormat sampleFormat, unsigned long winMmeSpecificFlags ) { int waveFormatTag = 0; if( winMmeSpecificFlags & paWinMmeWaveFormatDolbyAc3Spdif ) waveFormatTag = PAWIN_WAVE_FORMAT_DOLBY_AC3_SPDIF; else if( winMmeSpecificFlags & paWinMmeWaveFormatWmaSpdif ) waveFormatTag = PAWIN_WAVE_FORMAT_WMA_SPDIF; else waveFormatTag = PaWin_SampleFormatToLinearWaveFormatTag( sampleFormat ); return waveFormatTag; } static PaError QueryInputWaveFormatEx( int deviceId, WAVEFORMATEX *waveFormatEx ) { MMRESULT mmresult; switch( mmresult = waveInOpen( NULL, deviceId, waveFormatEx, 0, 0, WAVE_FORMAT_QUERY ) ) { case MMSYSERR_NOERROR: return paNoError; case MMSYSERR_ALLOCATED: /* Specified resource is already allocated. */ return paDeviceUnavailable; case MMSYSERR_NODRIVER: /* No device driver is present. */ return paDeviceUnavailable; case MMSYSERR_NOMEM: /* Unable to allocate or lock memory. */ return paInsufficientMemory; case WAVERR_BADFORMAT: /* Attempted to open with an unsupported waveform-audio format. */ return paSampleFormatNotSupported; case MMSYSERR_BADDEVICEID: /* Specified device identifier is out of range. */ /* falls through */ default: PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); return paUnanticipatedHostError; } } static PaError QueryOutputWaveFormatEx( int deviceId, WAVEFORMATEX *waveFormatEx ) { MMRESULT mmresult; switch( mmresult = waveOutOpen( NULL, deviceId, waveFormatEx, 0, 0, WAVE_FORMAT_QUERY ) ) { case MMSYSERR_NOERROR: return paNoError; case MMSYSERR_ALLOCATED: /* Specified resource is already allocated. */ return paDeviceUnavailable; case MMSYSERR_NODRIVER: /* No device driver is present. */ return paDeviceUnavailable; case MMSYSERR_NOMEM: /* Unable to allocate or lock memory. */ return paInsufficientMemory; case WAVERR_BADFORMAT: /* Attempted to open with an unsupported waveform-audio format. */ return paSampleFormatNotSupported; case MMSYSERR_BADDEVICEID: /* Specified device identifier is out of range. */ /* falls through */ default: PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); return paUnanticipatedHostError; } } static PaError QueryFormatSupported( PaDeviceInfo *deviceInfo, PaError (*waveFormatExQueryFunction)(int, WAVEFORMATEX*), int winMmeDeviceId, int channels, double sampleRate, unsigned long winMmeSpecificFlags ) { PaWinMmeDeviceInfo *winMmeDeviceInfo = (PaWinMmeDeviceInfo*)deviceInfo; PaWinWaveFormat waveFormat; PaSampleFormat sampleFormat; int waveFormatTag; /* @todo at the moment we only query with 16 bit sample format and directout speaker config*/ sampleFormat = paInt16; waveFormatTag = SampleFormatAndWinWmmeSpecificFlagsToLinearWaveFormatTag( sampleFormat, winMmeSpecificFlags ); if( waveFormatTag == PaWin_SampleFormatToLinearWaveFormatTag( paInt16 ) ){ /* attempt bypass querying the device for linear formats */ if( sampleRate == 11025.0 && ( (channels == 1 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_1M16)) || (channels == 2 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_1S16)) ) ){ return paNoError; } if( sampleRate == 22050.0 && ( (channels == 1 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_2M16)) || (channels == 2 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_2S16)) ) ){ return paNoError; } if( sampleRate == 44100.0 && ( (channels == 1 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_4M16)) || (channels == 2 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_4S16)) ) ){ return paNoError; } } /* first, attempt to query the device using WAVEFORMATEXTENSIBLE, if this fails we fall back to WAVEFORMATEX */ PaWin_InitializeWaveFormatExtensible( &waveFormat, channels, sampleFormat, waveFormatTag, sampleRate, PAWIN_SPEAKER_DIRECTOUT ); if( waveFormatExQueryFunction( winMmeDeviceId, (WAVEFORMATEX*)&waveFormat ) == paNoError ) return paNoError; PaWin_InitializeWaveFormatEx( &waveFormat, channels, sampleFormat, waveFormatTag, sampleRate ); return waveFormatExQueryFunction( winMmeDeviceId, (WAVEFORMATEX*)&waveFormat ); } #define PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_ (13) /* must match array length below */ static double defaultSampleRateSearchOrder_[] = { 44100.0, 48000.0, 32000.0, 24000.0, 22050.0, 88200.0, 96000.0, 192000.0, 16000.0, 12000.0, 11025.0, 9600.0, 8000.0 }; static void DetectDefaultSampleRate( PaWinMmeDeviceInfo *winMmeDeviceInfo, int winMmeDeviceId, PaError (*waveFormatExQueryFunction)(int, WAVEFORMATEX*), int maxChannels ) { PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo; int i; deviceInfo->defaultSampleRate = 0.; for( i=0; i < PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_; ++i ) { double sampleRate = defaultSampleRateSearchOrder_[ i ]; PaError paerror = QueryFormatSupported( deviceInfo, waveFormatExQueryFunction, winMmeDeviceId, maxChannels, sampleRate, 0 ); if( paerror == paNoError ) { deviceInfo->defaultSampleRate = sampleRate; break; } } } #ifdef PAWIN_USE_WDMKS_DEVICE_INFO static int QueryWaveInKSFilterMaxChannels( int waveInDeviceId, int *maxChannels ) { void *devicePath; DWORD devicePathSize; int result = 0; if( waveInMessage((HWAVEIN)waveInDeviceId, DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&devicePathSize, 0 ) != MMSYSERR_NOERROR ) return 0; devicePath = PaUtil_AllocateMemory( devicePathSize ); if( !devicePath ) return 0; /* apparently DRV_QUERYDEVICEINTERFACE returns a unicode interface path, although this is undocumented */ if( waveInMessage((HWAVEIN)waveInDeviceId, DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)devicePath, devicePathSize ) == MMSYSERR_NOERROR ) { int count = PaWin_WDMKS_QueryFilterMaximumChannelCount( devicePath, /* isInput= */ 1 ); if( count > 0 ) { *maxChannels = count; result = 1; } } PaUtil_FreeMemory( devicePath ); return result; } #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ static PaError InitializeInputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeHostApi, PaWinMmeDeviceInfo *winMmeDeviceInfo, UINT winMmeInputDeviceId, int *success ) { PaError result = paNoError; char *deviceName; /* non-const ptr */ MMRESULT mmresult; WAVEINCAPS wic; PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo; *success = 0; mmresult = waveInGetDevCaps( winMmeInputDeviceId, &wic, sizeof( WAVEINCAPS ) ); if( mmresult == MMSYSERR_NOMEM ) { result = paInsufficientMemory; goto error; } else if( mmresult != MMSYSERR_NOERROR ) { /* instead of returning paUnanticipatedHostError we return paNoError, but leave success set as 0. This allows Pa_Initialize to just ignore this device, without failing the entire initialisation process. */ return paNoError; } if( winMmeInputDeviceId == WAVE_MAPPER ) { /* Append I/O suffix to WAVE_MAPPER device. */ deviceName = (char *)PaUtil_GroupAllocateMemory( winMmeHostApi->allocations, (long) (StrTLen( wic.szPname ) + 1 + sizeof(constInputMapperSuffix_)) ); if( !deviceName ) { result = paInsufficientMemory; goto error; } StrTCpyToC( deviceName, wic.szPname ); strcat( deviceName, constInputMapperSuffix_ ); } else { deviceName = (char*)PaUtil_GroupAllocateMemory( winMmeHostApi->allocations, (long) (StrTLen( wic.szPname ) + 1) ); if( !deviceName ) { result = paInsufficientMemory; goto error; } StrTCpyToC( deviceName, wic.szPname ); } deviceInfo->name = deviceName; if( wic.wChannels == 0xFFFF || wic.wChannels < 1 || wic.wChannels > 255 ){ /* For Windows versions using WDM (possibly Windows 98 ME and later) * the kernel mixer sits between the application and the driver. As a result, * wave*GetDevCaps often kernel mixer channel counts, which are unlimited. * When this happens we assume the device is stereo and set a flag * so that other channel counts can be tried with OpenStream -- i.e. when * device*ChannelCountIsKnown is false, OpenStream will try whatever * channel count you supply. * see also InitializeOutputDeviceInfo() below. */ PA_DEBUG(("Pa_GetDeviceInfo: Num input channels reported as %d! Changed to 2.\n", wic.wChannels )); deviceInfo->maxInputChannels = 2; winMmeDeviceInfo->deviceInputChannelCountIsKnown = 0; }else{ deviceInfo->maxInputChannels = wic.wChannels; winMmeDeviceInfo->deviceInputChannelCountIsKnown = 1; } #ifdef PAWIN_USE_WDMKS_DEVICE_INFO winMmeDeviceInfo->deviceInputChannelCountIsKnown = QueryWaveInKSFilterMaxChannels( winMmeInputDeviceId, &deviceInfo->maxInputChannels ); #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ winMmeDeviceInfo->dwFormats = wic.dwFormats; DetectDefaultSampleRate( winMmeDeviceInfo, winMmeInputDeviceId, QueryInputWaveFormatEx, deviceInfo->maxInputChannels ); *success = 1; error: return result; } #ifdef PAWIN_USE_WDMKS_DEVICE_INFO static int QueryWaveOutKSFilterMaxChannels( int waveOutDeviceId, int *maxChannels ) { void *devicePath; DWORD devicePathSize; int result = 0; if( waveOutMessage((HWAVEOUT)waveOutDeviceId, DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&devicePathSize, 0 ) != MMSYSERR_NOERROR ) return 0; devicePath = PaUtil_AllocateMemory( devicePathSize ); if( !devicePath ) return 0; /* apparently DRV_QUERYDEVICEINTERFACE returns a unicode interface path, although this is undocumented */ if( waveOutMessage((HWAVEOUT)waveOutDeviceId, DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)devicePath, devicePathSize ) == MMSYSERR_NOERROR ) { int count = PaWin_WDMKS_QueryFilterMaximumChannelCount( devicePath, /* isInput= */ 0 ); if( count > 0 ) { *maxChannels = count; result = 1; } } PaUtil_FreeMemory( devicePath ); return result; } #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeHostApi, PaWinMmeDeviceInfo *winMmeDeviceInfo, UINT winMmeOutputDeviceId, int *success ) { PaError result = paNoError; char *deviceName; /* non-const ptr */ MMRESULT mmresult; WAVEOUTCAPS woc; PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo; #ifdef PAWIN_USE_WDMKS_DEVICE_INFO int wdmksDeviceOutputChannelCountIsKnown; #endif *success = 0; mmresult = waveOutGetDevCaps( winMmeOutputDeviceId, &woc, sizeof( WAVEOUTCAPS ) ); if( mmresult == MMSYSERR_NOMEM ) { result = paInsufficientMemory; goto error; } else if( mmresult != MMSYSERR_NOERROR ) { /* instead of returning paUnanticipatedHostError we return paNoError, but leave success set as 0. This allows Pa_Initialize to just ignore this device, without failing the entire initialisation process. */ return paNoError; } if( winMmeOutputDeviceId == WAVE_MAPPER ) { /* Append I/O suffix to WAVE_MAPPER device. */ deviceName = (char *)PaUtil_GroupAllocateMemory( winMmeHostApi->allocations, (long) (StrTLen( woc.szPname ) + 1 + sizeof(constOutputMapperSuffix_)) ); if( !deviceName ) { result = paInsufficientMemory; goto error; } StrTCpyToC( deviceName, woc.szPname ); strcat( deviceName, constOutputMapperSuffix_ ); } else { deviceName = (char*)PaUtil_GroupAllocateMemory( winMmeHostApi->allocations, (long) (StrTLen( woc.szPname ) + 1) ); if( !deviceName ) { result = paInsufficientMemory; goto error; } StrTCpyToC( deviceName, woc.szPname ); } deviceInfo->name = deviceName; if( woc.wChannels == 0xFFFF || woc.wChannels < 1 || woc.wChannels > 255 ){ /* For Windows versions using WDM (possibly Windows 98 ME and later) * the kernel mixer sits between the application and the driver. As a result, * wave*GetDevCaps often kernel mixer channel counts, which are unlimited. * When this happens we assume the device is stereo and set a flag * so that other channel counts can be tried with OpenStream -- i.e. when * device*ChannelCountIsKnown is false, OpenStream will try whatever * channel count you supply. * see also InitializeInputDeviceInfo() above. */ PA_DEBUG(("Pa_GetDeviceInfo: Num output channels reported as %d! Changed to 2.\n", woc.wChannels )); deviceInfo->maxOutputChannels = 2; winMmeDeviceInfo->deviceOutputChannelCountIsKnown = 0; }else{ deviceInfo->maxOutputChannels = woc.wChannels; winMmeDeviceInfo->deviceOutputChannelCountIsKnown = 1; } #ifdef PAWIN_USE_WDMKS_DEVICE_INFO wdmksDeviceOutputChannelCountIsKnown = QueryWaveOutKSFilterMaxChannels( winMmeOutputDeviceId, &deviceInfo->maxOutputChannels ); if( wdmksDeviceOutputChannelCountIsKnown && !winMmeDeviceInfo->deviceOutputChannelCountIsKnown ) winMmeDeviceInfo->deviceOutputChannelCountIsKnown = 1; #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ winMmeDeviceInfo->dwFormats = woc.dwFormats; DetectDefaultSampleRate( winMmeDeviceInfo, winMmeOutputDeviceId, QueryOutputWaveFormatEx, deviceInfo->maxOutputChannels ); *success = 1; error: return result; } static void GetDefaultLatencies( PaTime *defaultLowLatency, PaTime *defaultHighLatency ) { OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof( osvi ); GetVersionEx( &osvi ); /* Check for NT */ if( (osvi.dwMajorVersion == 4) && (osvi.dwPlatformId == 2) ) { *defaultLowLatency = PA_MME_WIN_NT_DEFAULT_LATENCY_; } else if(osvi.dwMajorVersion >= 5) { *defaultLowLatency = PA_MME_WIN_WDM_DEFAULT_LATENCY_; } else { *defaultLowLatency = PA_MME_WIN_9X_DEFAULT_LATENCY_; } *defaultHighLatency = *defaultLowLatency * 2; } PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) { PaError result = paNoError; int i; PaWinMmeHostApiRepresentation *winMmeHostApi; int inputDeviceCount, outputDeviceCount, maximumPossibleDeviceCount; PaWinMmeDeviceInfo *deviceInfoArray; int deviceInfoInitializationSucceeded; PaTime defaultLowLatency, defaultHighLatency; DWORD waveInPreferredDevice, waveOutPreferredDevice; DWORD preferredDeviceStatusFlags; winMmeHostApi = (PaWinMmeHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaWinMmeHostApiRepresentation) ); if( !winMmeHostApi ) { result = paInsufficientMemory; goto error; } winMmeHostApi->allocations = PaUtil_CreateAllocationGroup(); if( !winMmeHostApi->allocations ) { result = paInsufficientMemory; goto error; } *hostApi = &winMmeHostApi->inheritedHostApiRep; (*hostApi)->info.structVersion = 1; (*hostApi)->info.type = paMME; (*hostApi)->info.name = "MME"; /* initialise device counts and default devices under the assumption that there are no devices. These values are incremented below if and when devices are successfully initialized. */ (*hostApi)->info.deviceCount = 0; (*hostApi)->info.defaultInputDevice = paNoDevice; (*hostApi)->info.defaultOutputDevice = paNoDevice; winMmeHostApi->inputDeviceCount = 0; winMmeHostApi->outputDeviceCount = 0; #if !defined(DRVM_MAPPER_PREFERRED_GET) /* DRVM_MAPPER_PREFERRED_GET is defined in mmddk.h but we avoid a dependency on the DDK by defining it here */ #define DRVM_MAPPER_PREFERRED_GET (0x2000+21) #endif /* the following calls assume that if wave*Message fails the preferred device parameter won't be modified */ preferredDeviceStatusFlags = 0; waveInPreferredDevice = -1; waveInMessage( (HWAVEIN)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&waveInPreferredDevice, (DWORD_PTR)&preferredDeviceStatusFlags ); preferredDeviceStatusFlags = 0; waveOutPreferredDevice = -1; waveOutMessage( (HWAVEOUT)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&waveOutPreferredDevice, (DWORD_PTR)&preferredDeviceStatusFlags ); maximumPossibleDeviceCount = 0; inputDeviceCount = waveInGetNumDevs(); if( inputDeviceCount > 0 ) maximumPossibleDeviceCount += inputDeviceCount + 1; /* assume there is a WAVE_MAPPER */ outputDeviceCount = waveOutGetNumDevs(); if( outputDeviceCount > 0 ) maximumPossibleDeviceCount += outputDeviceCount + 1; /* assume there is a WAVE_MAPPER */ if( maximumPossibleDeviceCount > 0 ){ (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( winMmeHostApi->allocations, sizeof(PaDeviceInfo*) * maximumPossibleDeviceCount ); if( !(*hostApi)->deviceInfos ) { result = paInsufficientMemory; goto error; } /* allocate all device info structs in a contiguous block */ deviceInfoArray = (PaWinMmeDeviceInfo*)PaUtil_GroupAllocateMemory( winMmeHostApi->allocations, sizeof(PaWinMmeDeviceInfo) * maximumPossibleDeviceCount ); if( !deviceInfoArray ) { result = paInsufficientMemory; goto error; } winMmeHostApi->winMmeDeviceIds = (UINT*)PaUtil_GroupAllocateMemory( winMmeHostApi->allocations, sizeof(int) * maximumPossibleDeviceCount ); if( !winMmeHostApi->winMmeDeviceIds ) { result = paInsufficientMemory; goto error; } GetDefaultLatencies( &defaultLowLatency, &defaultHighLatency ); if( inputDeviceCount > 0 ){ /* -1 is the WAVE_MAPPER */ for( i = -1; i < inputDeviceCount; ++i ){ UINT winMmeDeviceId = (UINT)((i==-1) ? WAVE_MAPPER : i); PaWinMmeDeviceInfo *wmmeDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ]; PaDeviceInfo *deviceInfo = &wmmeDeviceInfo->inheritedDeviceInfo; deviceInfo->structVersion = 2; deviceInfo->hostApi = hostApiIndex; deviceInfo->maxInputChannels = 0; wmmeDeviceInfo->deviceInputChannelCountIsKnown = 1; deviceInfo->maxOutputChannels = 0; wmmeDeviceInfo->deviceOutputChannelCountIsKnown = 1; deviceInfo->defaultLowInputLatency = defaultLowLatency; deviceInfo->defaultLowOutputLatency = defaultLowLatency; deviceInfo->defaultHighInputLatency = defaultHighLatency; deviceInfo->defaultHighOutputLatency = defaultHighLatency; result = InitializeInputDeviceInfo( winMmeHostApi, wmmeDeviceInfo, winMmeDeviceId, &deviceInfoInitializationSucceeded ); if( result != paNoError ) goto error; if( deviceInfoInitializationSucceeded ){ if( (*hostApi)->info.defaultInputDevice == paNoDevice ){ /* if there is currently no default device, use the first one available */ (*hostApi)->info.defaultInputDevice = (*hostApi)->info.deviceCount; }else if( winMmeDeviceId == waveInPreferredDevice ){ /* set the default device to the system preferred device */ (*hostApi)->info.defaultInputDevice = (*hostApi)->info.deviceCount; } winMmeHostApi->winMmeDeviceIds[ (*hostApi)->info.deviceCount ] = winMmeDeviceId; (*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo; winMmeHostApi->inputDeviceCount++; (*hostApi)->info.deviceCount++; } } } if( outputDeviceCount > 0 ){ /* -1 is the WAVE_MAPPER */ for( i = -1; i < outputDeviceCount; ++i ){ UINT winMmeDeviceId = (UINT)((i==-1) ? WAVE_MAPPER : i); PaWinMmeDeviceInfo *wmmeDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ]; PaDeviceInfo *deviceInfo = &wmmeDeviceInfo->inheritedDeviceInfo; deviceInfo->structVersion = 2; deviceInfo->hostApi = hostApiIndex; deviceInfo->maxInputChannels = 0; wmmeDeviceInfo->deviceInputChannelCountIsKnown = 1; deviceInfo->maxOutputChannels = 0; wmmeDeviceInfo->deviceOutputChannelCountIsKnown = 1; deviceInfo->defaultLowInputLatency = defaultLowLatency; deviceInfo->defaultLowOutputLatency = defaultLowLatency; deviceInfo->defaultHighInputLatency = defaultHighLatency; deviceInfo->defaultHighOutputLatency = defaultHighLatency; result = InitializeOutputDeviceInfo( winMmeHostApi, wmmeDeviceInfo, winMmeDeviceId, &deviceInfoInitializationSucceeded ); if( result != paNoError ) goto error; if( deviceInfoInitializationSucceeded ){ if( (*hostApi)->info.defaultOutputDevice == paNoDevice ){ /* if there is currently no default device, use the first one available */ (*hostApi)->info.defaultOutputDevice = (*hostApi)->info.deviceCount; }else if( winMmeDeviceId == waveOutPreferredDevice ){ /* set the default device to the system preferred device */ (*hostApi)->info.defaultOutputDevice = (*hostApi)->info.deviceCount; } winMmeHostApi->winMmeDeviceIds[ (*hostApi)->info.deviceCount ] = winMmeDeviceId; (*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo; winMmeHostApi->outputDeviceCount++; (*hostApi)->info.deviceCount++; } } } } InitializeDefaultDeviceIdsFromEnv( winMmeHostApi ); (*hostApi)->Terminate = Terminate; (*hostApi)->OpenStream = OpenStream; (*hostApi)->IsFormatSupported = IsFormatSupported; PaUtil_InitializeStreamInterface( &winMmeHostApi->callbackStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, GetStreamCpuLoad, PaUtil_DummyRead, PaUtil_DummyWrite, PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); PaUtil_InitializeStreamInterface( &winMmeHostApi->blockingStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, PaUtil_DummyGetCpuLoad, ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable ); return result; error: if( winMmeHostApi ) { if( winMmeHostApi->allocations ) { PaUtil_FreeAllAllocations( winMmeHostApi->allocations ); PaUtil_DestroyAllocationGroup( winMmeHostApi->allocations ); } PaUtil_FreeMemory( winMmeHostApi ); } return result; } static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) { PaWinMmeHostApiRepresentation *winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi; if( winMmeHostApi->allocations ) { PaUtil_FreeAllAllocations( winMmeHostApi->allocations ); PaUtil_DestroyAllocationGroup( winMmeHostApi->allocations ); } PaUtil_FreeMemory( winMmeHostApi ); } static PaError IsInputChannelCountSupported( PaWinMmeDeviceInfo* deviceInfo, int channelCount ) { PaError result = paNoError; if( channelCount > 0 && deviceInfo->deviceInputChannelCountIsKnown && channelCount > deviceInfo->inheritedDeviceInfo.maxInputChannels ){ result = paInvalidChannelCount; } return result; } static PaError IsOutputChannelCountSupported( PaWinMmeDeviceInfo* deviceInfo, int channelCount ) { PaError result = paNoError; if( channelCount > 0 && deviceInfo->deviceOutputChannelCountIsKnown && channelCount > deviceInfo->inheritedDeviceInfo.maxOutputChannels ){ result = paInvalidChannelCount; } return result; } static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { PaWinMmeHostApiRepresentation *winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi; PaDeviceInfo *inputDeviceInfo, *outputDeviceInfo; int inputChannelCount, outputChannelCount; int inputMultipleDeviceChannelCount, outputMultipleDeviceChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; PaWinMmeStreamInfo *inputStreamInfo, *outputStreamInfo; UINT winMmeInputDeviceId, winMmeOutputDeviceId; unsigned int i; PaError paerror; /* The calls to QueryFormatSupported below are intended to detect invalid sample rates. If we assume that the channel count and format are OK, then the only thing that could fail is the sample rate. This isn't strictly true, but I can't think of a better way to test that the sample rate is valid. */ if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; inputStreamInfo = inputParameters->hostApiSpecificStreamInfo; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( inputSampleFormat & paCustomFormat ) return paSampleFormatNotSupported; if( inputParameters->device == paUseHostApiSpecificDeviceSpecification && inputStreamInfo && (inputStreamInfo->flags & paWinMmeUseMultipleDevices) ) { inputMultipleDeviceChannelCount = 0; for( i=0; i< inputStreamInfo->deviceCount; ++i ) { inputMultipleDeviceChannelCount += inputStreamInfo->devices[i].channelCount; inputDeviceInfo = hostApi->deviceInfos[ inputStreamInfo->devices[i].device ]; /* check that input device can support inputChannelCount */ if( inputStreamInfo->devices[i].channelCount < 1 ) return paInvalidChannelCount; paerror = IsInputChannelCountSupported( (PaWinMmeDeviceInfo*)inputDeviceInfo, inputStreamInfo->devices[i].channelCount ); if( paerror != paNoError ) return paerror; /* test for valid sample rate, see comment above */ winMmeInputDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, inputStreamInfo->devices[i].device ); paerror = QueryFormatSupported( inputDeviceInfo, QueryInputWaveFormatEx, winMmeInputDeviceId, inputStreamInfo->devices[i].channelCount, sampleRate, ((inputStreamInfo) ? inputStreamInfo->flags : 0) ); if( paerror != paNoError ) return paInvalidSampleRate; } if( inputMultipleDeviceChannelCount != inputChannelCount ) return paIncompatibleHostApiSpecificStreamInfo; } else { if( inputStreamInfo && (inputStreamInfo->flags & paWinMmeUseMultipleDevices) ) return paIncompatibleHostApiSpecificStreamInfo; /* paUseHostApiSpecificDeviceSpecification was not supplied as the input device */ inputDeviceInfo = hostApi->deviceInfos[ inputParameters->device ]; /* check that input device can support inputChannelCount */ paerror = IsInputChannelCountSupported( (PaWinMmeDeviceInfo*)inputDeviceInfo, inputChannelCount ); if( paerror != paNoError ) return paerror; /* test for valid sample rate, see comment above */ winMmeInputDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, inputParameters->device ); paerror = QueryFormatSupported( inputDeviceInfo, QueryInputWaveFormatEx, winMmeInputDeviceId, inputChannelCount, sampleRate, ((inputStreamInfo) ? inputStreamInfo->flags : 0) ); if( paerror != paNoError ) return paInvalidSampleRate; } } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; outputStreamInfo = outputParameters->hostApiSpecificStreamInfo; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( outputSampleFormat & paCustomFormat ) return paSampleFormatNotSupported; if( outputParameters->device == paUseHostApiSpecificDeviceSpecification && outputStreamInfo && (outputStreamInfo->flags & paWinMmeUseMultipleDevices) ) { outputMultipleDeviceChannelCount = 0; for( i=0; i< outputStreamInfo->deviceCount; ++i ) { outputMultipleDeviceChannelCount += outputStreamInfo->devices[i].channelCount; outputDeviceInfo = hostApi->deviceInfos[ outputStreamInfo->devices[i].device ]; /* check that output device can support outputChannelCount */ if( outputStreamInfo->devices[i].channelCount < 1 ) return paInvalidChannelCount; paerror = IsOutputChannelCountSupported( (PaWinMmeDeviceInfo*)outputDeviceInfo, outputStreamInfo->devices[i].channelCount ); if( paerror != paNoError ) return paerror; /* test for valid sample rate, see comment above */ winMmeOutputDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, outputStreamInfo->devices[i].device ); paerror = QueryFormatSupported( outputDeviceInfo, QueryOutputWaveFormatEx, winMmeOutputDeviceId, outputStreamInfo->devices[i].channelCount, sampleRate, ((outputStreamInfo) ? outputStreamInfo->flags : 0) ); if( paerror != paNoError ) return paInvalidSampleRate; } if( outputMultipleDeviceChannelCount != outputChannelCount ) return paIncompatibleHostApiSpecificStreamInfo; } else { if( outputStreamInfo && (outputStreamInfo->flags & paWinMmeUseMultipleDevices) ) return paIncompatibleHostApiSpecificStreamInfo; /* paUseHostApiSpecificDeviceSpecification was not supplied as the output device */ outputDeviceInfo = hostApi->deviceInfos[ outputParameters->device ]; /* check that output device can support outputChannelCount */ paerror = IsOutputChannelCountSupported( (PaWinMmeDeviceInfo*)outputDeviceInfo, outputChannelCount ); if( paerror != paNoError ) return paerror; /* test for valid sample rate, see comment above */ winMmeOutputDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, outputParameters->device ); paerror = QueryFormatSupported( outputDeviceInfo, QueryOutputWaveFormatEx, winMmeOutputDeviceId, outputChannelCount, sampleRate, ((outputStreamInfo) ? outputStreamInfo->flags : 0) ); if( paerror != paNoError ) return paInvalidSampleRate; } } /* - if a full duplex stream is requested, check that the combination of input and output parameters is supported - check that the device supports sampleRate for mme all we can do is test that the input and output devices support the requested sample rate and number of channels. we cannot test for full duplex compatibility. */ return paFormatIsSupported; } static unsigned long ComputeHostBufferCountForFixedBufferSizeFrames( unsigned long suggestedLatencyFrames, unsigned long hostBufferSizeFrames, unsigned long minimumBufferCount ) { /* Calculate the number of buffers of length hostFramesPerBuffer that fit in suggestedLatencyFrames, rounding up to the next integer. The value (hostBufferSizeFrames - 1) below is to ensure the buffer count is rounded up. */ unsigned long resultBufferCount = ((suggestedLatencyFrames + (hostBufferSizeFrames - 1)) / hostBufferSizeFrames); /* We always need one extra buffer for processing while the rest are queued/playing. i.e. latency is framesPerBuffer * (bufferCount - 1) */ resultBufferCount += 1; if( resultBufferCount < minimumBufferCount ) /* clamp to minimum buffer count */ resultBufferCount = minimumBufferCount; return resultBufferCount; } static unsigned long ComputeHostBufferSizeGivenHardUpperLimit( unsigned long userFramesPerBuffer, unsigned long absoluteMaximumBufferSizeFrames ) { static unsigned long primes_[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 0 }; /* zero terminated */ unsigned long result = userFramesPerBuffer; int i; assert( absoluteMaximumBufferSizeFrames > 67 ); /* assume maximum is large and we're only factoring by small primes */ /* search for the largest integer factor of userFramesPerBuffer less than or equal to absoluteMaximumBufferSizeFrames */ /* repeatedly divide by smallest prime factors until a buffer size smaller than absoluteMaximumBufferSizeFrames is found */ while( result > absoluteMaximumBufferSizeFrames ){ /* search for the smallest prime factor of result */ for( i=0; primes_[i] != 0; ++i ) { unsigned long p = primes_[i]; unsigned long divided = result / p; if( divided*p == result ) { result = divided; break; /* continue with outer while loop */ } } if( primes_[i] == 0 ) { /* loop failed to find a prime factor, return an approximate result */ unsigned long d = (userFramesPerBuffer + (absoluteMaximumBufferSizeFrames-1)) / absoluteMaximumBufferSizeFrames; return userFramesPerBuffer / d; } } return result; } static PaError SelectHostBufferSizeFramesAndHostBufferCount( unsigned long suggestedLatencyFrames, unsigned long userFramesPerBuffer, unsigned long minimumBufferCount, unsigned long preferredMaximumBufferSizeFrames, /* try not to exceed this. for example, don't exceed when coalescing buffers */ unsigned long absoluteMaximumBufferSizeFrames, /* never exceed this, a hard limit */ unsigned long *hostBufferSizeFrames, unsigned long *hostBufferCount ) { unsigned long effectiveUserFramesPerBuffer; unsigned long numberOfUserBuffersPerHostBuffer; if( userFramesPerBuffer == paFramesPerBufferUnspecified ){ effectiveUserFramesPerBuffer = PA_MME_HOST_BUFFER_GRANULARITY_FRAMES_WHEN_UNSPECIFIED_; }else{ if( userFramesPerBuffer > absoluteMaximumBufferSizeFrames ){ /* user has requested a user buffer that's larger than absoluteMaximumBufferSizeFrames. try to choose a buffer size that is equal or smaller than absoluteMaximumBufferSizeFrames but is also an integer factor of userFramesPerBuffer, so as to distribute computation evenly. the buffer processor will handle the block adaption between host and user buffer sizes. see http://www.portaudio.com/trac/ticket/189 for discussion. */ effectiveUserFramesPerBuffer = ComputeHostBufferSizeGivenHardUpperLimit( userFramesPerBuffer, absoluteMaximumBufferSizeFrames ); assert( effectiveUserFramesPerBuffer <= absoluteMaximumBufferSizeFrames ); /* try to ensure that duration of host buffering is at least as large as duration of user buffer. */ if( suggestedLatencyFrames < userFramesPerBuffer ) suggestedLatencyFrames = userFramesPerBuffer; }else{ effectiveUserFramesPerBuffer = userFramesPerBuffer; } } /* compute a host buffer count based on suggestedLatencyFrames and our granularity */ *hostBufferSizeFrames = effectiveUserFramesPerBuffer; *hostBufferCount = ComputeHostBufferCountForFixedBufferSizeFrames( suggestedLatencyFrames, *hostBufferSizeFrames, minimumBufferCount ); if( *hostBufferSizeFrames >= userFramesPerBuffer ) { /* If there are too many host buffers we would like to coalesce them by packing an integer number of user buffers into each host buffer. We try to coalesce such that hostBufferCount will lie between PA_MME_TARGET_HOST_BUFFER_COUNT_ and (PA_MME_TARGET_HOST_BUFFER_COUNT_*2)-1. We limit coalescing to avoid exceeding either absoluteMaximumBufferSizeFrames and preferredMaximumBufferSizeFrames. First, compute a coalescing factor: the number of user buffers per host buffer. The goal is to achieve PA_MME_TARGET_HOST_BUFFER_COUNT_ total buffer count. Since our latency is computed based on (*hostBufferCount - 1) we compute a coalescing factor based on (*hostBufferCount - 1) and (PA_MME_TARGET_HOST_BUFFER_COUNT_-1). The + (PA_MME_TARGET_HOST_BUFFER_COUNT_-2) term below is intended to round up. */ numberOfUserBuffersPerHostBuffer = ((*hostBufferCount - 1) + (PA_MME_TARGET_HOST_BUFFER_COUNT_-2)) / (PA_MME_TARGET_HOST_BUFFER_COUNT_ - 1); if( numberOfUserBuffersPerHostBuffer > 1 ) { unsigned long maxCoalescedBufferSizeFrames = (absoluteMaximumBufferSizeFrames < preferredMaximumBufferSizeFrames) /* minimum of our limits */ ? absoluteMaximumBufferSizeFrames : preferredMaximumBufferSizeFrames; unsigned long maxUserBuffersPerHostBuffer = maxCoalescedBufferSizeFrames / effectiveUserFramesPerBuffer; /* don't coalesce more than this */ if( numberOfUserBuffersPerHostBuffer > maxUserBuffersPerHostBuffer ) numberOfUserBuffersPerHostBuffer = maxUserBuffersPerHostBuffer; *hostBufferSizeFrames = effectiveUserFramesPerBuffer * numberOfUserBuffersPerHostBuffer; /* recompute hostBufferCount to approximate suggestedLatencyFrames now that hostBufferSizeFrames is larger */ *hostBufferCount = ComputeHostBufferCountForFixedBufferSizeFrames( suggestedLatencyFrames, *hostBufferSizeFrames, minimumBufferCount ); } } return paNoError; } static PaError CalculateMaxHostSampleFrameSizeBytes( int channelCount, PaSampleFormat hostSampleFormat, const PaWinMmeStreamInfo *streamInfo, int *hostSampleFrameSizeBytes ) { unsigned int i; /* PA WMME streams may aggregate multiple WMME devices. When the stream addresses more than one device in a single direction, maxDeviceChannelCount is the maximum number of channels used by a single device. */ int maxDeviceChannelCount = channelCount; int hostSampleSizeBytes = Pa_GetSampleSize( hostSampleFormat ); if( hostSampleSizeBytes < 0 ) { return hostSampleSizeBytes; /* the value of hostSampleSize here is an error code, not a sample size */ } if( streamInfo && ( streamInfo->flags & paWinMmeUseMultipleDevices ) ) { maxDeviceChannelCount = streamInfo->devices[0].channelCount; for( i=1; i< streamInfo->deviceCount; ++i ) { if( streamInfo->devices[i].channelCount > maxDeviceChannelCount ) maxDeviceChannelCount = streamInfo->devices[i].channelCount; } } *hostSampleFrameSizeBytes = hostSampleSizeBytes * maxDeviceChannelCount; return paNoError; } /* CalculateBufferSettings() fills the framesPerHostInputBuffer, hostInputBufferCount, framesPerHostOutputBuffer and hostOutputBufferCount parameters based on the values of the other parameters. */ static PaError CalculateBufferSettings( unsigned long *hostFramesPerInputBuffer, unsigned long *hostInputBufferCount, unsigned long *hostFramesPerOutputBuffer, unsigned long *hostOutputBufferCount, int inputChannelCount, PaSampleFormat hostInputSampleFormat, PaTime suggestedInputLatency, const PaWinMmeStreamInfo *inputStreamInfo, int outputChannelCount, PaSampleFormat hostOutputSampleFormat, PaTime suggestedOutputLatency, const PaWinMmeStreamInfo *outputStreamInfo, double sampleRate, unsigned long userFramesPerBuffer ) { PaError result = paNoError; if( inputChannelCount > 0 ) /* stream has input */ { int hostInputFrameSizeBytes; result = CalculateMaxHostSampleFrameSizeBytes( inputChannelCount, hostInputSampleFormat, inputStreamInfo, &hostInputFrameSizeBytes ); if( result != paNoError ) goto error; if( inputStreamInfo && ( inputStreamInfo->flags & paWinMmeUseLowLevelLatencyParameters ) ) { /* input - using low level latency parameters if provided */ if( inputStreamInfo->bufferCount <= 0 || inputStreamInfo->framesPerBuffer <= 0 ) { result = paIncompatibleHostApiSpecificStreamInfo; goto error; } *hostFramesPerInputBuffer = inputStreamInfo->framesPerBuffer; *hostInputBufferCount = inputStreamInfo->bufferCount; } else { /* input - not using low level latency parameters, so compute hostFramesPerInputBuffer and hostInputBufferCount based on userFramesPerBuffer and suggestedInputLatency. */ unsigned long minimumBufferCount = (outputChannelCount > 0) ? PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_ : PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_HALF_DUPLEX_; result = SelectHostBufferSizeFramesAndHostBufferCount( (unsigned long)(suggestedInputLatency * sampleRate), /* (truncate) */ userFramesPerBuffer, minimumBufferCount, (unsigned long)(PA_MME_MAX_HOST_BUFFER_SECS_ * sampleRate), /* in frames. preferred maximum */ (PA_MME_MAX_HOST_BUFFER_BYTES_ / hostInputFrameSizeBytes), /* in frames. a hard limit. note truncation due to division is intentional here to limit max bytes */ hostFramesPerInputBuffer, hostInputBufferCount ); if( result != paNoError ) goto error; } } else { *hostFramesPerInputBuffer = 0; *hostInputBufferCount = 0; } if( outputChannelCount > 0 ) /* stream has output */ { if( outputStreamInfo && ( outputStreamInfo->flags & paWinMmeUseLowLevelLatencyParameters ) ) { /* output - using low level latency parameters */ if( outputStreamInfo->bufferCount <= 0 || outputStreamInfo->framesPerBuffer <= 0 ) { result = paIncompatibleHostApiSpecificStreamInfo; goto error; } *hostFramesPerOutputBuffer = outputStreamInfo->framesPerBuffer; *hostOutputBufferCount = outputStreamInfo->bufferCount; if( inputChannelCount > 0 ) /* full duplex */ { /* harmonize hostFramesPerInputBuffer and hostFramesPerOutputBuffer */ if( *hostFramesPerInputBuffer != *hostFramesPerOutputBuffer ) { if( inputStreamInfo && ( inputStreamInfo->flags & paWinMmeUseLowLevelLatencyParameters ) ) { /* a custom StreamInfo was used for specifying both input and output buffer sizes. We require that the larger buffer size must be a multiple of the smaller buffer size */ if( *hostFramesPerInputBuffer < *hostFramesPerOutputBuffer ) { if( *hostFramesPerOutputBuffer % *hostFramesPerInputBuffer != 0 ) { result = paIncompatibleHostApiSpecificStreamInfo; goto error; } } else { assert( *hostFramesPerInputBuffer > *hostFramesPerOutputBuffer ); if( *hostFramesPerInputBuffer % *hostFramesPerOutputBuffer != 0 ) { result = paIncompatibleHostApiSpecificStreamInfo; goto error; } } } else { /* a custom StreamInfo was not used for specifying the input buffer size, so use the output buffer size, and approximately the suggested input latency. */ *hostFramesPerInputBuffer = *hostFramesPerOutputBuffer; *hostInputBufferCount = ComputeHostBufferCountForFixedBufferSizeFrames( (unsigned long)(suggestedInputLatency * sampleRate), *hostFramesPerInputBuffer, PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_ ); } } } } else { /* output - no low level latency parameters, so compute hostFramesPerOutputBuffer and hostOutputBufferCount based on userFramesPerBuffer and suggestedOutputLatency. */ int hostOutputFrameSizeBytes; result = CalculateMaxHostSampleFrameSizeBytes( outputChannelCount, hostOutputSampleFormat, outputStreamInfo, &hostOutputFrameSizeBytes ); if( result != paNoError ) goto error; /* compute the output buffer size and count */ result = SelectHostBufferSizeFramesAndHostBufferCount( (unsigned long)(suggestedOutputLatency * sampleRate), /* (truncate) */ userFramesPerBuffer, PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_, (unsigned long)(PA_MME_MAX_HOST_BUFFER_SECS_ * sampleRate), /* in frames. preferred maximum */ (PA_MME_MAX_HOST_BUFFER_BYTES_ / hostOutputFrameSizeBytes), /* in frames. a hard limit. note truncation due to division is intentional here to limit max bytes */ hostFramesPerOutputBuffer, hostOutputBufferCount ); if( result != paNoError ) goto error; if( inputChannelCount > 0 ) /* full duplex */ { /* harmonize hostFramesPerInputBuffer and hostFramesPerOutputBuffer */ /* ensure that both input and output buffer sizes are the same. if they don't match at this stage, choose the smallest one and use that for input and output and recompute the corresponding buffer count accordingly. */ if( *hostFramesPerOutputBuffer != *hostFramesPerInputBuffer ) { if( hostFramesPerInputBuffer < hostFramesPerOutputBuffer ) { *hostFramesPerOutputBuffer = *hostFramesPerInputBuffer; *hostOutputBufferCount = ComputeHostBufferCountForFixedBufferSizeFrames( (unsigned long)(suggestedOutputLatency * sampleRate), *hostOutputBufferCount, PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_ ); } else { *hostFramesPerInputBuffer = *hostFramesPerOutputBuffer; *hostInputBufferCount = ComputeHostBufferCountForFixedBufferSizeFrames( (unsigned long)(suggestedInputLatency * sampleRate), *hostFramesPerInputBuffer, PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_ ); } } } } } else { *hostFramesPerOutputBuffer = 0; *hostOutputBufferCount = 0; } error: return result; } typedef struct { HANDLE bufferEvent; void *waveHandles; unsigned int deviceCount; /* unsigned int channelCount; */ WAVEHDR **waveHeaders; /* waveHeaders[device][buffer] */ unsigned int bufferCount; unsigned int currentBufferIndex; unsigned int framesPerBuffer; unsigned int framesUsedInCurrentBuffer; }PaWinMmeSingleDirectionHandlesAndBuffers; /* prototypes for functions operating on PaWinMmeSingleDirectionHandlesAndBuffers */ static void InitializeSingleDirectionHandlesAndBuffers( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers ); static PaError InitializeWaveHandles( PaWinMmeHostApiRepresentation *winMmeHostApi, PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, unsigned long winMmeSpecificFlags, unsigned long bytesPerHostSample, double sampleRate, PaWinMmeDeviceAndChannelCount *devices, unsigned int deviceCount, PaWinWaveFormatChannelMask channelMask, int isInput ); static PaError TerminateWaveHandles( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, int isInput, int currentlyProcessingAnError ); static PaError InitializeWaveHeaders( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, unsigned long hostBufferCount, PaSampleFormat hostSampleFormat, unsigned long framesPerHostBuffer, PaWinMmeDeviceAndChannelCount *devices, int isInput ); static void TerminateWaveHeaders( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, int isInput ); static void InitializeSingleDirectionHandlesAndBuffers( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers ) { handlesAndBuffers->bufferEvent = 0; handlesAndBuffers->waveHandles = 0; handlesAndBuffers->deviceCount = 0; handlesAndBuffers->waveHeaders = 0; handlesAndBuffers->bufferCount = 0; } static PaError InitializeWaveHandles( PaWinMmeHostApiRepresentation *winMmeHostApi, PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, unsigned long winMmeSpecificFlags, unsigned long bytesPerHostSample, double sampleRate, PaWinMmeDeviceAndChannelCount *devices, unsigned int deviceCount, PaWinWaveFormatChannelMask channelMask, int isInput ) { PaError result; MMRESULT mmresult; signed int i, j; PaSampleFormat sampleFormat; int waveFormatTag; /* for error cleanup we expect that InitializeSingleDirectionHandlesAndBuffers() has already been called to zero some fields */ result = CreateEventWithPaError( &handlesAndBuffers->bufferEvent, NULL, FALSE, FALSE, NULL ); if( result != paNoError ) goto error; if( isInput ) handlesAndBuffers->waveHandles = (void*)PaUtil_AllocateMemory( sizeof(HWAVEIN) * deviceCount ); else handlesAndBuffers->waveHandles = (void*)PaUtil_AllocateMemory( sizeof(HWAVEOUT) * deviceCount ); if( !handlesAndBuffers->waveHandles ) { result = paInsufficientMemory; goto error; } handlesAndBuffers->deviceCount = deviceCount; for( i = 0; i < (signed int)deviceCount; ++i ) { if( isInput ) ((HWAVEIN*)handlesAndBuffers->waveHandles)[i] = 0; else ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i] = 0; } /* @todo at the moment we only use 16 bit sample format */ sampleFormat = paInt16; waveFormatTag = SampleFormatAndWinWmmeSpecificFlagsToLinearWaveFormatTag( sampleFormat, winMmeSpecificFlags ); for( i = 0; i < (signed int)deviceCount; ++i ) { PaWinWaveFormat waveFormat; UINT winMmeDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, devices[i].device ); /* @todo: consider providing a flag or #define to not try waveformat extensible this could just initialize j to 1 the first time round. */ for( j = 0; j < 2; ++j ) { switch(j){ case 0: /* first, attempt to open the device using WAVEFORMATEXTENSIBLE, if this fails we fall back to WAVEFORMATEX */ PaWin_InitializeWaveFormatExtensible( &waveFormat, devices[i].channelCount, sampleFormat, waveFormatTag, sampleRate, channelMask ); break; case 1: /* retry with WAVEFORMATEX */ PaWin_InitializeWaveFormatEx( &waveFormat, devices[i].channelCount, sampleFormat, waveFormatTag, sampleRate ); break; } /* REVIEW: consider not firing an event for input when a full duplex stream is being used. this would probably depend on the neverDropInput flag. */ if( isInput ) { mmresult = waveInOpen( &((HWAVEIN*)handlesAndBuffers->waveHandles)[i], winMmeDeviceId, (WAVEFORMATEX*)&waveFormat, (DWORD_PTR)handlesAndBuffers->bufferEvent, (DWORD_PTR)0, CALLBACK_EVENT ); } else { mmresult = waveOutOpen( &((HWAVEOUT*)handlesAndBuffers->waveHandles)[i], winMmeDeviceId, (WAVEFORMATEX*)&waveFormat, (DWORD_PTR)handlesAndBuffers->bufferEvent, (DWORD_PTR)0, CALLBACK_EVENT ); } if( mmresult == MMSYSERR_NOERROR ) { break; /* success */ } else if( j == 0 ) { continue; /* try again with WAVEFORMATEX */ } else { switch( mmresult ) { case MMSYSERR_ALLOCATED: /* Specified resource is already allocated. */ result = paDeviceUnavailable; break; case MMSYSERR_NODRIVER: /* No device driver is present. */ result = paDeviceUnavailable; break; case MMSYSERR_NOMEM: /* Unable to allocate or lock memory. */ result = paInsufficientMemory; break; case MMSYSERR_BADDEVICEID: /* Specified device identifier is out of range. */ /* falls through */ case WAVERR_BADFORMAT: /* Attempted to open with an unsupported waveform-audio format. */ /* This can also occur if we try to open the device with an unsupported * number of channels. This is attempted when device*ChannelCountIsKnown is * set to 0. */ /* falls through */ default: result = paUnanticipatedHostError; if( isInput ) { PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); } else { PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); } } goto error; } } } return result; error: TerminateWaveHandles( handlesAndBuffers, isInput, 1 /* currentlyProcessingAnError */ ); return result; } static PaError TerminateWaveHandles( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, int isInput, int currentlyProcessingAnError ) { PaError result = paNoError; MMRESULT mmresult; signed int i; if( handlesAndBuffers->waveHandles ) { for( i = handlesAndBuffers->deviceCount-1; i >= 0; --i ) { if( isInput ) { if( ((HWAVEIN*)handlesAndBuffers->waveHandles)[i] ) mmresult = waveInClose( ((HWAVEIN*)handlesAndBuffers->waveHandles)[i] ); else mmresult = MMSYSERR_NOERROR; } else { if( ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i] ) mmresult = waveOutClose( ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i] ); else mmresult = MMSYSERR_NOERROR; } if( mmresult != MMSYSERR_NOERROR && !currentlyProcessingAnError ) /* don't update the error state if we're already processing an error */ { result = paUnanticipatedHostError; if( isInput ) { PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); } else { PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); } /* note that we don't break here, we try to continue closing devices */ } } PaUtil_FreeMemory( handlesAndBuffers->waveHandles ); handlesAndBuffers->waveHandles = 0; } if( handlesAndBuffers->bufferEvent ) { result = CloseHandleWithPaError( handlesAndBuffers->bufferEvent ); handlesAndBuffers->bufferEvent = 0; } return result; } static PaError InitializeWaveHeaders( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, unsigned long hostBufferCount, PaSampleFormat hostSampleFormat, unsigned long framesPerHostBuffer, PaWinMmeDeviceAndChannelCount *devices, int isInput ) { PaError result = paNoError; MMRESULT mmresult; WAVEHDR *deviceWaveHeaders; signed int i, j; /* for error cleanup we expect that InitializeSingleDirectionHandlesAndBuffers() has already been called to zero some fields */ /* allocate an array of pointers to arrays of wave headers, one array of wave headers per device */ handlesAndBuffers->waveHeaders = (WAVEHDR**)PaUtil_AllocateMemory( sizeof(WAVEHDR*) * handlesAndBuffers->deviceCount ); if( !handlesAndBuffers->waveHeaders ) { result = paInsufficientMemory; goto error; } for( i = 0; i < (signed int)handlesAndBuffers->deviceCount; ++i ) handlesAndBuffers->waveHeaders[i] = 0; handlesAndBuffers->bufferCount = hostBufferCount; for( i = 0; i < (signed int)handlesAndBuffers->deviceCount; ++i ) { int bufferBytes = Pa_GetSampleSize( hostSampleFormat ) * framesPerHostBuffer * devices[i].channelCount; if( bufferBytes < 0 ) { result = paInternalError; goto error; } /* Allocate an array of wave headers for device i */ deviceWaveHeaders = (WAVEHDR *) PaUtil_AllocateMemory( sizeof(WAVEHDR)*hostBufferCount ); if( !deviceWaveHeaders ) { result = paInsufficientMemory; goto error; } for( j=0; j < (signed int)hostBufferCount; ++j ) deviceWaveHeaders[j].lpData = 0; handlesAndBuffers->waveHeaders[i] = deviceWaveHeaders; /* Allocate a buffer for each wave header */ for( j=0; j < (signed int)hostBufferCount; ++j ) { deviceWaveHeaders[j].lpData = (char *)PaUtil_AllocateMemory( bufferBytes ); if( !deviceWaveHeaders[j].lpData ) { result = paInsufficientMemory; goto error; } deviceWaveHeaders[j].dwBufferLength = bufferBytes; deviceWaveHeaders[j].dwUser = 0xFFFFFFFF; /* indicates that *PrepareHeader() has not yet been called, for error clean up code */ if( isInput ) { mmresult = waveInPrepareHeader( ((HWAVEIN*)handlesAndBuffers->waveHandles)[i], &deviceWaveHeaders[j], sizeof(WAVEHDR) ); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); goto error; } } else /* output */ { mmresult = waveOutPrepareHeader( ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i], &deviceWaveHeaders[j], sizeof(WAVEHDR) ); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); goto error; } } deviceWaveHeaders[j].dwUser = devices[i].channelCount; } } return result; error: TerminateWaveHeaders( handlesAndBuffers, isInput ); return result; } static void TerminateWaveHeaders( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, int isInput ) { signed int i, j; WAVEHDR *deviceWaveHeaders; if( handlesAndBuffers->waveHeaders ) { for( i = handlesAndBuffers->deviceCount-1; i >= 0 ; --i ) { deviceWaveHeaders = handlesAndBuffers->waveHeaders[i]; /* wave headers for device i */ if( deviceWaveHeaders ) { for( j = handlesAndBuffers->bufferCount-1; j >= 0; --j ) { if( deviceWaveHeaders[j].lpData ) { if( deviceWaveHeaders[j].dwUser != 0xFFFFFFFF ) { if( isInput ) waveInUnprepareHeader( ((HWAVEIN*)handlesAndBuffers->waveHandles)[i], &deviceWaveHeaders[j], sizeof(WAVEHDR) ); else waveOutUnprepareHeader( ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i], &deviceWaveHeaders[j], sizeof(WAVEHDR) ); } PaUtil_FreeMemory( deviceWaveHeaders[j].lpData ); } } PaUtil_FreeMemory( deviceWaveHeaders ); } } PaUtil_FreeMemory( handlesAndBuffers->waveHeaders ); handlesAndBuffers->waveHeaders = 0; } } /* PaWinMmeStream - a stream data structure specifically for this implementation */ /* note that struct PaWinMmeStream is typedeffed to PaWinMmeStream above. */ struct PaWinMmeStream { PaUtilStreamRepresentation streamRepresentation; PaUtilCpuLoadMeasurer cpuLoadMeasurer; PaUtilBufferProcessor bufferProcessor; int primeStreamUsingCallback; PaWinMmeSingleDirectionHandlesAndBuffers input; PaWinMmeSingleDirectionHandlesAndBuffers output; /* Processing thread management -------------- */ HANDLE abortEvent; HANDLE processingThread; PA_THREAD_ID processingThreadId; char throttleProcessingThreadOnOverload; /* 0 -> don't throtte, non-0 -> throttle */ int processingThreadPriority; int highThreadPriority; int throttledThreadPriority; unsigned long throttledSleepMsecs; int isStopped; volatile int isActive; volatile int stopProcessing; /* stop thread once existing buffers have been returned */ volatile int abortProcessing; /* stop thread immediately */ DWORD allBuffersDurationMs; /* used to calculate timeouts */ }; /* updates deviceCount if PaWinMmeUseMultipleDevices is used */ static PaError ValidateWinMmeSpecificStreamInfo( const PaStreamParameters *streamParameters, const PaWinMmeStreamInfo *streamInfo, unsigned long *winMmeSpecificFlags, char *throttleProcessingThreadOnOverload, unsigned long *deviceCount ) { if( streamInfo ) { if( streamInfo->size != sizeof( PaWinMmeStreamInfo ) || streamInfo->version != 1 ) { return paIncompatibleHostApiSpecificStreamInfo; } *winMmeSpecificFlags = streamInfo->flags; if( streamInfo->flags & paWinMmeDontThrottleOverloadedProcessingThread ) *throttleProcessingThreadOnOverload = 0; if( streamInfo->flags & paWinMmeUseMultipleDevices ) { if( streamParameters->device != paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; *deviceCount = streamInfo->deviceCount; } } return paNoError; } static PaError RetrieveDevicesFromStreamParameters( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *streamParameters, const PaWinMmeStreamInfo *streamInfo, PaWinMmeDeviceAndChannelCount *devices, unsigned long deviceCount ) { PaError result = paNoError; unsigned int i; int totalChannelCount; PaDeviceIndex hostApiDevice; if( streamInfo && streamInfo->flags & paWinMmeUseMultipleDevices ) { totalChannelCount = 0; for( i=0; i < deviceCount; ++i ) { /* validate that the device number is within range */ result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, streamInfo->devices[i].device, hostApi ); if( result != paNoError ) return result; devices[i].device = hostApiDevice; devices[i].channelCount = streamInfo->devices[i].channelCount; totalChannelCount += devices[i].channelCount; } if( totalChannelCount != streamParameters->channelCount ) { /* channelCount must match total channels specified by multiple devices */ return paInvalidChannelCount; /* REVIEW use of this error code */ } } else { devices[0].device = streamParameters->device; devices[0].channelCount = streamParameters->channelCount; } return result; } static PaError ValidateInputChannelCounts( struct PaUtilHostApiRepresentation *hostApi, PaWinMmeDeviceAndChannelCount *devices, unsigned long deviceCount ) { unsigned int i; PaWinMmeDeviceInfo *inputDeviceInfo; PaError paerror; for( i=0; i < deviceCount; ++i ) { if( devices[i].channelCount < 1 ) return paInvalidChannelCount; inputDeviceInfo = (PaWinMmeDeviceInfo*)hostApi->deviceInfos[ devices[i].device ]; paerror = IsInputChannelCountSupported( inputDeviceInfo, devices[i].channelCount ); if( paerror != paNoError ) return paerror; } return paNoError; } static PaError ValidateOutputChannelCounts( struct PaUtilHostApiRepresentation *hostApi, PaWinMmeDeviceAndChannelCount *devices, unsigned long deviceCount ) { unsigned int i; PaWinMmeDeviceInfo *outputDeviceInfo; PaError paerror; for( i=0; i < deviceCount; ++i ) { if( devices[i].channelCount < 1 ) return paInvalidChannelCount; outputDeviceInfo = (PaWinMmeDeviceInfo*)hostApi->deviceInfos[ devices[i].device ]; paerror = IsOutputChannelCountSupported( outputDeviceInfo, devices[i].channelCount ); if( paerror != paNoError ) return paerror; } return paNoError; } /* the following macros are intended to improve the readability of the following code */ #define PA_IS_INPUT_STREAM_( stream ) ( stream ->input.waveHandles ) #define PA_IS_OUTPUT_STREAM_( stream ) ( stream ->output.waveHandles ) #define PA_IS_FULL_DUPLEX_STREAM_( stream ) ( stream ->input.waveHandles && stream ->output.waveHandles ) #define PA_IS_HALF_DUPLEX_STREAM_( stream ) ( !(stream ->input.waveHandles && stream ->output.waveHandles) ) static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ) { PaError result; PaWinMmeHostApiRepresentation *winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi; PaWinMmeStream *stream = 0; int bufferProcessorIsInitialized = 0; int streamRepresentationIsInitialized = 0; PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat; int inputChannelCount, outputChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; double suggestedInputLatency, suggestedOutputLatency; PaWinMmeStreamInfo *inputStreamInfo, *outputStreamInfo; PaWinWaveFormatChannelMask inputChannelMask, outputChannelMask; unsigned long framesPerHostInputBuffer; unsigned long hostInputBufferCount; unsigned long framesPerHostOutputBuffer; unsigned long hostOutputBufferCount; unsigned long framesPerBufferProcessorCall; PaWinMmeDeviceAndChannelCount *inputDevices = 0; /* contains all devices and channel counts as local host api ids, even when PaWinMmeUseMultipleDevices is not used */ unsigned long winMmeSpecificInputFlags = 0; unsigned long inputDeviceCount = 0; PaWinMmeDeviceAndChannelCount *outputDevices = 0; unsigned long winMmeSpecificOutputFlags = 0; unsigned long outputDeviceCount = 0; /* contains all devices and channel counts as local host api ids, even when PaWinMmeUseMultipleDevices is not used */ char throttleProcessingThreadOnOverload = 1; if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; suggestedInputLatency = inputParameters->suggestedLatency; inputDeviceCount = 1; /* validate input hostApiSpecificStreamInfo */ inputStreamInfo = (PaWinMmeStreamInfo*)inputParameters->hostApiSpecificStreamInfo; result = ValidateWinMmeSpecificStreamInfo( inputParameters, inputStreamInfo, &winMmeSpecificInputFlags, &throttleProcessingThreadOnOverload, &inputDeviceCount ); if( result != paNoError ) return result; inputDevices = (PaWinMmeDeviceAndChannelCount*)alloca( sizeof(PaWinMmeDeviceAndChannelCount) * inputDeviceCount ); if( !inputDevices ) return paInsufficientMemory; result = RetrieveDevicesFromStreamParameters( hostApi, inputParameters, inputStreamInfo, inputDevices, inputDeviceCount ); if( result != paNoError ) return result; result = ValidateInputChannelCounts( hostApi, inputDevices, inputDeviceCount ); if( result != paNoError ) return result; hostInputSampleFormat = PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, inputSampleFormat ); if( inputDeviceCount != 1 ){ /* always use direct speakers when using multi-device multichannel mode */ inputChannelMask = PAWIN_SPEAKER_DIRECTOUT; } else { if( inputStreamInfo && inputStreamInfo->flags & paWinMmeUseChannelMask ) inputChannelMask = inputStreamInfo->channelMask; else inputChannelMask = PaWin_DefaultChannelMask( inputDevices[0].channelCount ); } } else { inputChannelCount = 0; inputSampleFormat = 0; suggestedInputLatency = 0.; inputStreamInfo = 0; hostInputSampleFormat = 0; } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; suggestedOutputLatency = outputParameters->suggestedLatency; outputDeviceCount = 1; /* validate output hostApiSpecificStreamInfo */ outputStreamInfo = (PaWinMmeStreamInfo*)outputParameters->hostApiSpecificStreamInfo; result = ValidateWinMmeSpecificStreamInfo( outputParameters, outputStreamInfo, &winMmeSpecificOutputFlags, &throttleProcessingThreadOnOverload, &outputDeviceCount ); if( result != paNoError ) return result; outputDevices = (PaWinMmeDeviceAndChannelCount*)alloca( sizeof(PaWinMmeDeviceAndChannelCount) * outputDeviceCount ); if( !outputDevices ) return paInsufficientMemory; result = RetrieveDevicesFromStreamParameters( hostApi, outputParameters, outputStreamInfo, outputDevices, outputDeviceCount ); if( result != paNoError ) return result; result = ValidateOutputChannelCounts( hostApi, outputDevices, outputDeviceCount ); if( result != paNoError ) return result; hostOutputSampleFormat = PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, outputSampleFormat ); if( outputDeviceCount != 1 ){ /* always use direct speakers when using multi-device multichannel mode */ outputChannelMask = PAWIN_SPEAKER_DIRECTOUT; } else { if( outputStreamInfo && outputStreamInfo->flags & paWinMmeUseChannelMask ) outputChannelMask = outputStreamInfo->channelMask; else outputChannelMask = PaWin_DefaultChannelMask( outputDevices[0].channelCount ); } } else { outputChannelCount = 0; outputSampleFormat = 0; outputStreamInfo = 0; hostOutputSampleFormat = 0; suggestedOutputLatency = 0.; } /* IMPLEMENT ME: - alter sampleRate to a close allowable rate if possible / necessary */ /* validate platform specific flags */ if( (streamFlags & paPlatformSpecificFlags) != 0 ) return paInvalidFlag; /* unexpected platform specific flag */ /* always disable clipping and dithering if we are outputting a raw spdif stream */ if( (winMmeSpecificOutputFlags & paWinMmeWaveFormatDolbyAc3Spdif) || (winMmeSpecificOutputFlags & paWinMmeWaveFormatWmaSpdif) ){ streamFlags = streamFlags | paClipOff | paDitherOff; } result = CalculateBufferSettings( &framesPerHostInputBuffer, &hostInputBufferCount, &framesPerHostOutputBuffer, &hostOutputBufferCount, inputChannelCount, hostInputSampleFormat, suggestedInputLatency, inputStreamInfo, outputChannelCount, hostOutputSampleFormat, suggestedOutputLatency, outputStreamInfo, sampleRate, framesPerBuffer ); if( result != paNoError ) goto error; stream = (PaWinMmeStream*)PaUtil_AllocateMemory( sizeof(PaWinMmeStream) ); if( !stream ) { result = paInsufficientMemory; goto error; } InitializeSingleDirectionHandlesAndBuffers( &stream->input ); InitializeSingleDirectionHandlesAndBuffers( &stream->output ); stream->abortEvent = 0; stream->processingThread = 0; stream->throttleProcessingThreadOnOverload = throttleProcessingThreadOnOverload; PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, ( (streamCallback) ? &winMmeHostApi->callbackStreamInterface : &winMmeHostApi->blockingStreamInterface ), streamCallback, userData ); streamRepresentationIsInitialized = 1; PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate ); if( inputParameters && outputParameters ) /* full duplex */ { if( framesPerHostInputBuffer < framesPerHostOutputBuffer ) { assert( (framesPerHostOutputBuffer % framesPerHostInputBuffer) == 0 ); /* CalculateBufferSettings() should guarantee this condition */ framesPerBufferProcessorCall = framesPerHostInputBuffer; } else { assert( (framesPerHostInputBuffer % framesPerHostOutputBuffer) == 0 ); /* CalculateBufferSettings() should guarantee this condition */ framesPerBufferProcessorCall = framesPerHostOutputBuffer; } } else if( inputParameters ) { framesPerBufferProcessorCall = framesPerHostInputBuffer; } else if( outputParameters ) { framesPerBufferProcessorCall = framesPerHostOutputBuffer; } stream->input.framesPerBuffer = framesPerHostInputBuffer; stream->output.framesPerBuffer = framesPerHostOutputBuffer; result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, inputChannelCount, inputSampleFormat, hostInputSampleFormat, outputChannelCount, outputSampleFormat, hostOutputSampleFormat, sampleRate, streamFlags, framesPerBuffer, framesPerBufferProcessorCall, paUtilFixedHostBufferSize, streamCallback, userData ); if( result != paNoError ) goto error; bufferProcessorIsInitialized = 1; /* stream info input latency is the minimum buffering latency (unlike suggested and default which are *maximums*) */ stream->streamRepresentation.streamInfo.inputLatency = (double)(PaUtil_GetBufferProcessorInputLatencyFrames(&stream->bufferProcessor) + framesPerHostInputBuffer) / sampleRate; stream->streamRepresentation.streamInfo.outputLatency = (double)(PaUtil_GetBufferProcessorOutputLatencyFrames(&stream->bufferProcessor) + (framesPerHostOutputBuffer * (hostOutputBufferCount-1))) / sampleRate; stream->streamRepresentation.streamInfo.sampleRate = sampleRate; stream->primeStreamUsingCallback = ( (streamFlags&paPrimeOutputBuffersUsingStreamCallback) && streamCallback ) ? 1 : 0; /* time to sleep when throttling due to >100% cpu usage. -a quater of a buffer's duration */ stream->throttledSleepMsecs = (unsigned long)(stream->bufferProcessor.framesPerHostBuffer * stream->bufferProcessor.samplePeriod * .25 * 1000); stream->isStopped = 1; stream->isActive = 0; /* for maximum compatibility with multi-device multichannel drivers, we first open all devices, then we prepare all buffers, finally we start all devices ( in StartStream() ). teardown in reverse order. */ if( inputParameters ) { result = InitializeWaveHandles( winMmeHostApi, &stream->input, winMmeSpecificInputFlags, stream->bufferProcessor.bytesPerHostInputSample, sampleRate, inputDevices, inputDeviceCount, inputChannelMask, 1 /* isInput */ ); if( result != paNoError ) goto error; } if( outputParameters ) { result = InitializeWaveHandles( winMmeHostApi, &stream->output, winMmeSpecificOutputFlags, stream->bufferProcessor.bytesPerHostOutputSample, sampleRate, outputDevices, outputDeviceCount, outputChannelMask, 0 /* isInput */ ); if( result != paNoError ) goto error; } if( inputParameters ) { result = InitializeWaveHeaders( &stream->input, hostInputBufferCount, hostInputSampleFormat, framesPerHostInputBuffer, inputDevices, 1 /* isInput */ ); if( result != paNoError ) goto error; } if( outputParameters ) { result = InitializeWaveHeaders( &stream->output, hostOutputBufferCount, hostOutputSampleFormat, framesPerHostOutputBuffer, outputDevices, 0 /* not isInput */ ); if( result != paNoError ) goto error; stream->allBuffersDurationMs = (DWORD) (1000.0 * (framesPerHostOutputBuffer * stream->output.bufferCount) / sampleRate); } else { stream->allBuffersDurationMs = (DWORD) (1000.0 * (framesPerHostInputBuffer * stream->input.bufferCount) / sampleRate); } if( streamCallback ) { /* abort event is only needed for callback streams */ result = CreateEventWithPaError( &stream->abortEvent, NULL, TRUE, FALSE, NULL ); if( result != paNoError ) goto error; } *s = (PaStream*)stream; return result; error: if( stream ) { if( stream->abortEvent ) CloseHandle( stream->abortEvent ); TerminateWaveHeaders( &stream->output, 0 /* not isInput */ ); TerminateWaveHeaders( &stream->input, 1 /* isInput */ ); TerminateWaveHandles( &stream->output, 0 /* not isInput */, 1 /* currentlyProcessingAnError */ ); TerminateWaveHandles( &stream->input, 1 /* isInput */, 1 /* currentlyProcessingAnError */ ); if( bufferProcessorIsInitialized ) PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); if( streamRepresentationIsInitialized ) PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); PaUtil_FreeMemory( stream ); } return result; } /* return non-zero if all current buffers are done */ static int BuffersAreDone( WAVEHDR **waveHeaders, unsigned int deviceCount, int bufferIndex ) { unsigned int i; for( i=0; i < deviceCount; ++i ) { if( !(waveHeaders[i][ bufferIndex ].dwFlags & WHDR_DONE) ) { return 0; } } return 1; } static int CurrentInputBuffersAreDone( PaWinMmeStream *stream ) { return BuffersAreDone( stream->input.waveHeaders, stream->input.deviceCount, stream->input.currentBufferIndex ); } static int CurrentOutputBuffersAreDone( PaWinMmeStream *stream ) { return BuffersAreDone( stream->output.waveHeaders, stream->output.deviceCount, stream->output.currentBufferIndex ); } /* return non-zero if any buffers are queued */ static int NoBuffersAreQueued( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers ) { unsigned int i, j; if( handlesAndBuffers->waveHandles ) { for( i=0; i < handlesAndBuffers->bufferCount; ++i ) { for( j=0; j < handlesAndBuffers->deviceCount; ++j ) { if( !( handlesAndBuffers->waveHeaders[ j ][ i ].dwFlags & WHDR_DONE) ) { return 0; } } } } return 1; } #define PA_CIRCULAR_INCREMENT_( current, max )\ ( (((current) + 1) >= (max)) ? (0) : (current+1) ) #define PA_CIRCULAR_DECREMENT_( current, max )\ ( ((current) == 0) ? ((max)-1) : (current-1) ) static signed long GetAvailableFrames( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers ) { signed long result = 0; unsigned int i; if( BuffersAreDone( handlesAndBuffers->waveHeaders, handlesAndBuffers->deviceCount, handlesAndBuffers->currentBufferIndex ) ) { /* we could calculate the following in O(1) if we kept track of the last done buffer */ result = handlesAndBuffers->framesPerBuffer - handlesAndBuffers->framesUsedInCurrentBuffer; i = PA_CIRCULAR_INCREMENT_( handlesAndBuffers->currentBufferIndex, handlesAndBuffers->bufferCount ); while( i != handlesAndBuffers->currentBufferIndex ) { if( BuffersAreDone( handlesAndBuffers->waveHeaders, handlesAndBuffers->deviceCount, i ) ) { result += handlesAndBuffers->framesPerBuffer; i = PA_CIRCULAR_INCREMENT_( i, handlesAndBuffers->bufferCount ); } else break; } } return result; } static PaError AdvanceToNextInputBuffer( PaWinMmeStream *stream ) { PaError result = paNoError; MMRESULT mmresult; unsigned int i; for( i=0; i < stream->input.deviceCount; ++i ) { stream->input.waveHeaders[i][ stream->input.currentBufferIndex ].dwFlags &= ~WHDR_DONE; mmresult = waveInAddBuffer( ((HWAVEIN*)stream->input.waveHandles)[i], &stream->input.waveHeaders[i][ stream->input.currentBufferIndex ], sizeof(WAVEHDR) ); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); } } stream->input.currentBufferIndex = PA_CIRCULAR_INCREMENT_( stream->input.currentBufferIndex, stream->input.bufferCount ); stream->input.framesUsedInCurrentBuffer = 0; return result; } static PaError AdvanceToNextOutputBuffer( PaWinMmeStream *stream ) { PaError result = paNoError; MMRESULT mmresult; unsigned int i; for( i=0; i < stream->output.deviceCount; ++i ) { mmresult = waveOutWrite( ((HWAVEOUT*)stream->output.waveHandles)[i], &stream->output.waveHeaders[i][ stream->output.currentBufferIndex ], sizeof(WAVEHDR) ); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); } } stream->output.currentBufferIndex = PA_CIRCULAR_INCREMENT_( stream->output.currentBufferIndex, stream->output.bufferCount ); stream->output.framesUsedInCurrentBuffer = 0; return result; } /* requeue all but the most recent input with the driver. Used for catching up after a total input buffer underrun */ static PaError CatchUpInputBuffers( PaWinMmeStream *stream ) { PaError result = paNoError; unsigned int i; for( i=0; i < stream->input.bufferCount - 1; ++i ) { result = AdvanceToNextInputBuffer( stream ); if( result != paNoError ) break; } return result; } /* take the most recent output and duplicate it to all other output buffers and requeue them. Used for catching up after a total output buffer underrun. */ static PaError CatchUpOutputBuffers( PaWinMmeStream *stream ) { PaError result = paNoError; unsigned int i, j; unsigned int previousBufferIndex = PA_CIRCULAR_DECREMENT_( stream->output.currentBufferIndex, stream->output.bufferCount ); for( i=0; i < stream->output.bufferCount - 1; ++i ) { for( j=0; j < stream->output.deviceCount; ++j ) { if( stream->output.waveHeaders[j][ stream->output.currentBufferIndex ].lpData != stream->output.waveHeaders[j][ previousBufferIndex ].lpData ) { CopyMemory( stream->output.waveHeaders[j][ stream->output.currentBufferIndex ].lpData, stream->output.waveHeaders[j][ previousBufferIndex ].lpData, stream->output.waveHeaders[j][ stream->output.currentBufferIndex ].dwBufferLength ); } } result = AdvanceToNextOutputBuffer( stream ); if( result != paNoError ) break; } return result; } PA_THREAD_FUNC ProcessingThreadProc( void *pArg ) { PaWinMmeStream *stream = (PaWinMmeStream *)pArg; HANDLE events[3]; int eventCount = 0; DWORD result = paNoError; DWORD waitResult; DWORD timeout = (unsigned long)(stream->allBuffersDurationMs * 0.5); int hostBuffersAvailable; signed int hostInputBufferIndex, hostOutputBufferIndex; PaStreamCallbackFlags statusFlags; int callbackResult; int done = 0; unsigned int channel, i; unsigned long framesProcessed; /* prepare event array for call to WaitForMultipleObjects() */ if( stream->input.bufferEvent ) events[eventCount++] = stream->input.bufferEvent; if( stream->output.bufferEvent ) events[eventCount++] = stream->output.bufferEvent; events[eventCount++] = stream->abortEvent; statusFlags = 0; /** @todo support paInputUnderflow, paOutputOverflow and paNeverDropInput */ /* loop until something causes us to stop */ do{ /* wait for MME to signal that a buffer is available, or for the PA abort event to be signaled. When this indicates that one or more buffers are available NoBuffersAreQueued() and Current*BuffersAreDone are used below to poll for additional done buffers. NoBuffersAreQueued() will fail to identify an underrun/overflow if the driver doesn't mark all done buffers prior to signalling the event. Some drivers do this (eg RME Digi96, and others don't eg VIA PC 97 input). This isn't a huge problem, it just means that we won't always be able to detect underflow/overflow. */ waitResult = WaitForMultipleObjects( eventCount, events, FALSE /* wait all = FALSE */, timeout ); if( waitResult == WAIT_FAILED ) { result = paUnanticipatedHostError; /** @todo FIXME/REVIEW: can't return host error info from an asyncronous thread. see http://www.portaudio.com/trac/ticket/143 */ done = 1; } else if( waitResult == WAIT_TIMEOUT ) { /* if a timeout is encountered, continue */ } if( stream->abortProcessing ) { /* Pa_AbortStream() has been called, stop processing immediately */ done = 1; } else if( stream->stopProcessing ) { /* Pa_StopStream() has been called or the user callback returned non-zero, processing will continue until all output buffers are marked as done. The stream will stop immediately if it is input-only. */ if( PA_IS_OUTPUT_STREAM_(stream) ) { if( NoBuffersAreQueued( &stream->output ) ) done = 1; /* Will cause thread to return. */ } else { /* input only stream */ done = 1; /* Will cause thread to return. */ } } else { hostBuffersAvailable = 1; /* process all available host buffers */ do { hostInputBufferIndex = -1; hostOutputBufferIndex = -1; if( PA_IS_INPUT_STREAM_(stream) ) { if( CurrentInputBuffersAreDone( stream ) ) { if( NoBuffersAreQueued( &stream->input ) ) { /** @todo if all of the other buffers are also ready then we discard all but the most recent. This is an input buffer overflow. FIXME: these buffers should be passed to the callback in a paNeverDropInput stream. http://www.portaudio.com/trac/ticket/142 note that it is also possible for an input overflow to happen while the callback is processing a buffer. that is handled further down. */ result = CatchUpInputBuffers( stream ); if( result != paNoError ) done = 1; statusFlags |= paInputOverflow; } hostInputBufferIndex = stream->input.currentBufferIndex; } } if( PA_IS_OUTPUT_STREAM_(stream) ) { if( CurrentOutputBuffersAreDone( stream ) ) { /* ok, we have an output buffer */ if( NoBuffersAreQueued( &stream->output ) ) { /* if all of the other buffers are also ready, catch up by copying the most recently generated buffer into all but one of the output buffers. note that this catch up code only handles the case where all buffers have been played out due to this thread not having woken up at all. a more common case occurs when this thread is woken up, processes one buffer, but takes too long, and as a result all the other buffers have become un-queued. that case is handled further down. */ result = CatchUpOutputBuffers( stream ); if( result != paNoError ) done = 1; statusFlags |= paOutputUnderflow; } hostOutputBufferIndex = stream->output.currentBufferIndex; } } if( (PA_IS_FULL_DUPLEX_STREAM_(stream) && hostInputBufferIndex != -1 && hostOutputBufferIndex != -1) || (PA_IS_HALF_DUPLEX_STREAM_(stream) && ( hostInputBufferIndex != -1 || hostOutputBufferIndex != -1 ) ) ) { PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /** @todo implement inputBufferAdcTime */ if( PA_IS_OUTPUT_STREAM_(stream) ) { /* set timeInfo.currentTime and calculate timeInfo.outputBufferDacTime from the current wave out position */ MMTIME mmtime; double timeBeforeGetPosition, timeAfterGetPosition; double time; long framesInBufferRing; long writePosition; long playbackPosition; HWAVEOUT firstWaveOutDevice = ((HWAVEOUT*)stream->output.waveHandles)[0]; mmtime.wType = TIME_SAMPLES; timeBeforeGetPosition = PaUtil_GetTime(); waveOutGetPosition( firstWaveOutDevice, &mmtime, sizeof(MMTIME) ); timeAfterGetPosition = PaUtil_GetTime(); timeInfo.currentTime = timeAfterGetPosition; /* approximate time at which wave out position was measured as half way between timeBeforeGetPosition and timeAfterGetPosition */ time = timeBeforeGetPosition + (timeAfterGetPosition - timeBeforeGetPosition) * .5; framesInBufferRing = stream->output.bufferCount * stream->bufferProcessor.framesPerHostBuffer; playbackPosition = mmtime.u.sample % framesInBufferRing; writePosition = stream->output.currentBufferIndex * stream->bufferProcessor.framesPerHostBuffer + stream->output.framesUsedInCurrentBuffer; if( playbackPosition >= writePosition ){ timeInfo.outputBufferDacTime = time + ((double)( writePosition + (framesInBufferRing - playbackPosition) ) * stream->bufferProcessor.samplePeriod ); }else{ timeInfo.outputBufferDacTime = time + ((double)( writePosition - playbackPosition ) * stream->bufferProcessor.samplePeriod ); } } PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, statusFlags ); /* reset status flags once they have been passed to the buffer processor */ statusFlags = 0; if( PA_IS_INPUT_STREAM_(stream) ) { PaUtil_SetInputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ ); channel = 0; for( i=0; iinput.deviceCount; ++i ) { /* we have stored the number of channels in the buffer in dwUser */ int channelCount = (int)stream->input.waveHeaders[i][ hostInputBufferIndex ].dwUser; PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, channel, stream->input.waveHeaders[i][ hostInputBufferIndex ].lpData + stream->input.framesUsedInCurrentBuffer * channelCount * stream->bufferProcessor.bytesPerHostInputSample, channelCount ); channel += channelCount; } } if( PA_IS_OUTPUT_STREAM_(stream) ) { PaUtil_SetOutputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ ); channel = 0; for( i=0; ioutput.deviceCount; ++i ) { /* we have stored the number of channels in the buffer in dwUser */ int channelCount = (int)stream->output.waveHeaders[i][ hostOutputBufferIndex ].dwUser; PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, channel, stream->output.waveHeaders[i][ hostOutputBufferIndex ].lpData + stream->output.framesUsedInCurrentBuffer * channelCount * stream->bufferProcessor.bytesPerHostOutputSample, channelCount ); channel += channelCount; } } callbackResult = paContinue; framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult ); stream->input.framesUsedInCurrentBuffer += framesProcessed; stream->output.framesUsedInCurrentBuffer += framesProcessed; PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed ); if( callbackResult == paContinue ) { /* nothing special to do */ } else if( callbackResult == paAbort ) { stream->abortProcessing = 1; done = 1; /** @todo FIXME: should probably reset the output device immediately once the callback returns paAbort see: http://www.portaudio.com/trac/ticket/141 */ result = paNoError; } else { /* User callback has asked us to stop with paComplete or other non-zero value */ stream->stopProcessing = 1; /* stop once currently queued audio has finished */ result = paNoError; } if( PA_IS_INPUT_STREAM_(stream) && stream->stopProcessing == 0 && stream->abortProcessing == 0 && stream->input.framesUsedInCurrentBuffer == stream->input.framesPerBuffer ) { if( NoBuffersAreQueued( &stream->input ) ) { /** @todo need to handle PaNeverDropInput here where necessary */ result = CatchUpInputBuffers( stream ); if( result != paNoError ) done = 1; statusFlags |= paInputOverflow; } result = AdvanceToNextInputBuffer( stream ); if( result != paNoError ) done = 1; } if( PA_IS_OUTPUT_STREAM_(stream) && !stream->abortProcessing ) { if( stream->stopProcessing && stream->output.framesUsedInCurrentBuffer < stream->output.framesPerBuffer ) { /* zero remaining samples in output output buffer and flush */ stream->output.framesUsedInCurrentBuffer += PaUtil_ZeroOutput( &stream->bufferProcessor, stream->output.framesPerBuffer - stream->output.framesUsedInCurrentBuffer ); /* we send the entire buffer to the output devices, but we could just send a partial buffer, rather than zeroing the unused samples. */ } if( stream->output.framesUsedInCurrentBuffer == stream->output.framesPerBuffer ) { /* check for underflow before enquing the just-generated buffer, but recover from underflow after enquing it. This ensures that the most recent audio segment is repeated */ int outputUnderflow = NoBuffersAreQueued( &stream->output ); result = AdvanceToNextOutputBuffer( stream ); if( result != paNoError ) done = 1; if( outputUnderflow && !done && !stream->stopProcessing ) { /* Recover from underflow in the case where the underflow occured while processing the buffer we just finished */ result = CatchUpOutputBuffers( stream ); if( result != paNoError ) done = 1; statusFlags |= paOutputUnderflow; } } } if( stream->throttleProcessingThreadOnOverload != 0 ) { if( stream->stopProcessing || stream->abortProcessing ) { if( stream->processingThreadPriority != stream->highThreadPriority ) { SetThreadPriority( stream->processingThread, stream->highThreadPriority ); stream->processingThreadPriority = stream->highThreadPriority; } } else if( PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ) > 1. ) { if( stream->processingThreadPriority != stream->throttledThreadPriority ) { SetThreadPriority( stream->processingThread, stream->throttledThreadPriority ); stream->processingThreadPriority = stream->throttledThreadPriority; } /* sleep to give other processes a go */ Sleep( stream->throttledSleepMsecs ); } else { if( stream->processingThreadPriority != stream->highThreadPriority ) { SetThreadPriority( stream->processingThread, stream->highThreadPriority ); stream->processingThreadPriority = stream->highThreadPriority; } } } } else { hostBuffersAvailable = 0; } } while( hostBuffersAvailable && stream->stopProcessing == 0 && stream->abortProcessing == 0 && !done ); } } while( !done ); stream->isActive = 0; if( stream->streamRepresentation.streamFinishedCallback != 0 ) stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); PaUtil_ResetCpuLoadMeasurer( &stream->cpuLoadMeasurer ); return result; } /* When CloseStream() is called, the multi-api layer ensures that the stream has already been stopped or aborted. */ static PaError CloseStream( PaStream* s ) { PaError result; PaWinMmeStream *stream = (PaWinMmeStream*)s; result = CloseHandleWithPaError( stream->abortEvent ); if( result != paNoError ) goto error; TerminateWaveHeaders( &stream->output, 0 /* not isInput */ ); TerminateWaveHeaders( &stream->input, 1 /* isInput */ ); TerminateWaveHandles( &stream->output, 0 /* not isInput */, 0 /* not currentlyProcessingAnError */ ); TerminateWaveHandles( &stream->input, 1 /* isInput */, 0 /* not currentlyProcessingAnError */ ); PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); PaUtil_FreeMemory( stream ); error: /** @todo REVIEW: what is the best way to clean up a stream if an error is detected? */ return result; } static PaError StartStream( PaStream *s ) { PaError result; PaWinMmeStream *stream = (PaWinMmeStream*)s; MMRESULT mmresult; unsigned int i, j; int callbackResult; unsigned int channel; unsigned long framesProcessed; PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /** @todo implement this for stream priming */ PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); if( PA_IS_INPUT_STREAM_(stream) ) { for( i=0; iinput.bufferCount; ++i ) { for( j=0; jinput.deviceCount; ++j ) { stream->input.waveHeaders[j][i].dwFlags &= ~WHDR_DONE; mmresult = waveInAddBuffer( ((HWAVEIN*)stream->input.waveHandles)[j], &stream->input.waveHeaders[j][i], sizeof(WAVEHDR) ); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); goto error; } } } stream->input.currentBufferIndex = 0; stream->input.framesUsedInCurrentBuffer = 0; } if( PA_IS_OUTPUT_STREAM_(stream) ) { for( i=0; ioutput.deviceCount; ++i ) { if( (mmresult = waveOutPause( ((HWAVEOUT*)stream->output.waveHandles)[i] )) != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); goto error; } } for( i=0; ioutput.bufferCount; ++i ) { if( stream->primeStreamUsingCallback ) { stream->output.framesUsedInCurrentBuffer = 0; do{ PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, paPrimingOutput | ((stream->input.bufferCount > 0 ) ? paInputUnderflow : 0)); if( stream->input.bufferCount > 0 ) PaUtil_SetNoInput( &stream->bufferProcessor ); PaUtil_SetOutputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ ); channel = 0; for( j=0; joutput.deviceCount; ++j ) { /* we have stored the number of channels in the buffer in dwUser */ int channelCount = (int)stream->output.waveHeaders[j][i].dwUser; PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, channel, stream->output.waveHeaders[j][i].lpData + stream->output.framesUsedInCurrentBuffer * channelCount * stream->bufferProcessor.bytesPerHostOutputSample, channelCount ); /* we have stored the number of channels in the buffer in dwUser */ channel += channelCount; } callbackResult = paContinue; framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult ); stream->output.framesUsedInCurrentBuffer += framesProcessed; if( callbackResult != paContinue ) { /** @todo fix this, what do we do if callback result is non-zero during stream priming? for complete: play out primed waveHeaders as usual for abort: clean up immediately. */ } }while( stream->output.framesUsedInCurrentBuffer != stream->output.framesPerBuffer ); } else { for( j=0; joutput.deviceCount; ++j ) { ZeroMemory( stream->output.waveHeaders[j][i].lpData, stream->output.waveHeaders[j][i].dwBufferLength ); } } /* we queue all channels of a single buffer frame (accross all devices, because some multidevice multichannel drivers work better this way */ for( j=0; joutput.deviceCount; ++j ) { mmresult = waveOutWrite( ((HWAVEOUT*)stream->output.waveHandles)[j], &stream->output.waveHeaders[j][i], sizeof(WAVEHDR) ); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); goto error; } } } stream->output.currentBufferIndex = 0; stream->output.framesUsedInCurrentBuffer = 0; } stream->isStopped = 0; stream->isActive = 1; stream->stopProcessing = 0; stream->abortProcessing = 0; result = ResetEventWithPaError( stream->input.bufferEvent ); if( result != paNoError ) goto error; result = ResetEventWithPaError( stream->output.bufferEvent ); if( result != paNoError ) goto error; if( stream->streamRepresentation.streamCallback ) { /* callback stream */ result = ResetEventWithPaError( stream->abortEvent ); if( result != paNoError ) goto error; /* Create thread that waits for audio buffers to be ready for processing. */ stream->processingThread = CREATE_THREAD; if( !stream->processingThread ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() ); goto error; } /** @todo could have mme specific stream parameters to allow the user to set the callback thread priorities */ stream->highThreadPriority = THREAD_PRIORITY_TIME_CRITICAL; stream->throttledThreadPriority = THREAD_PRIORITY_NORMAL; if( !SetThreadPriority( stream->processingThread, stream->highThreadPriority ) ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() ); goto error; } stream->processingThreadPriority = stream->highThreadPriority; } else { /* blocking read/write stream */ } if( PA_IS_INPUT_STREAM_(stream) ) { for( i=0; i < stream->input.deviceCount; ++i ) { mmresult = waveInStart( ((HWAVEIN*)stream->input.waveHandles)[i] ); PA_DEBUG(("Pa_StartStream: waveInStart returned = 0x%X.\n", mmresult)); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); goto error; } } } if( PA_IS_OUTPUT_STREAM_(stream) ) { for( i=0; i < stream->output.deviceCount; ++i ) { if( (mmresult = waveOutRestart( ((HWAVEOUT*)stream->output.waveHandles)[i] )) != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); goto error; } } } return result; error: /** @todo FIXME: implement recovery as best we can This should involve rolling back to a state as-if this function had never been called */ return result; } static PaError StopStream( PaStream *s ) { PaError result = paNoError; PaWinMmeStream *stream = (PaWinMmeStream*)s; int timeout; DWORD waitResult; MMRESULT mmresult; signed int hostOutputBufferIndex; unsigned int channel, waitCount, i; /** @todo REVIEW: the error checking in this function needs review. the basic idea is to return from this function in a known state - for example there is no point avoiding calling waveInReset just because the thread times out. */ if( stream->processingThread ) { /* callback stream */ /* Tell processing thread to stop generating more data and to let current data play out. */ stream->stopProcessing = 1; /* Calculate timeOut longer than longest time it could take to return all buffers. */ timeout = (int)(stream->allBuffersDurationMs * 1.5); if( timeout < PA_MME_MIN_TIMEOUT_MSEC_ ) timeout = PA_MME_MIN_TIMEOUT_MSEC_; PA_DEBUG(("WinMME StopStream: waiting for background thread.\n")); waitResult = WaitForSingleObject( stream->processingThread, timeout ); if( waitResult == WAIT_TIMEOUT ) { /* try to abort */ stream->abortProcessing = 1; SetEvent( stream->abortEvent ); waitResult = WaitForSingleObject( stream->processingThread, timeout ); if( waitResult == WAIT_TIMEOUT ) { PA_DEBUG(("WinMME StopStream: timed out while waiting for background thread to finish.\n")); result = paTimedOut; } } CloseHandle( stream->processingThread ); stream->processingThread = NULL; } else { /* blocking read / write stream */ if( PA_IS_OUTPUT_STREAM_(stream) ) { if( stream->output.framesUsedInCurrentBuffer > 0 ) { /* there are still unqueued frames in the current buffer, so flush them */ hostOutputBufferIndex = stream->output.currentBufferIndex; PaUtil_SetOutputFrameCount( &stream->bufferProcessor, stream->output.framesPerBuffer - stream->output.framesUsedInCurrentBuffer ); channel = 0; for( i=0; ioutput.deviceCount; ++i ) { /* we have stored the number of channels in the buffer in dwUser */ int channelCount = (int)stream->output.waveHeaders[i][ hostOutputBufferIndex ].dwUser; PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, channel, stream->output.waveHeaders[i][ hostOutputBufferIndex ].lpData + stream->output.framesUsedInCurrentBuffer * channelCount * stream->bufferProcessor.bytesPerHostOutputSample, channelCount ); channel += channelCount; } PaUtil_ZeroOutput( &stream->bufferProcessor, stream->output.framesPerBuffer - stream->output.framesUsedInCurrentBuffer ); /* we send the entire buffer to the output devices, but we could just send a partial buffer, rather than zeroing the unused samples. */ AdvanceToNextOutputBuffer( stream ); } timeout = (stream->allBuffersDurationMs / stream->output.bufferCount) + 1; if( timeout < PA_MME_MIN_TIMEOUT_MSEC_ ) timeout = PA_MME_MIN_TIMEOUT_MSEC_; waitCount = 0; while( !NoBuffersAreQueued( &stream->output ) && waitCount <= stream->output.bufferCount ) { /* wait for MME to signal that a buffer is available */ waitResult = WaitForSingleObject( stream->output.bufferEvent, timeout ); if( waitResult == WAIT_FAILED ) { break; } else if( waitResult == WAIT_TIMEOUT ) { /* keep waiting */ } ++waitCount; } } } if( PA_IS_OUTPUT_STREAM_(stream) ) { for( i =0; i < stream->output.deviceCount; ++i ) { mmresult = waveOutReset( ((HWAVEOUT*)stream->output.waveHandles)[i] ); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); } } } if( PA_IS_INPUT_STREAM_(stream) ) { for( i=0; i < stream->input.deviceCount; ++i ) { mmresult = waveInReset( ((HWAVEIN*)stream->input.waveHandles)[i] ); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); } } } stream->isStopped = 1; stream->isActive = 0; return result; } static PaError AbortStream( PaStream *s ) { PaError result = paNoError; PaWinMmeStream *stream = (PaWinMmeStream*)s; int timeout; DWORD waitResult; MMRESULT mmresult; unsigned int i; /** @todo REVIEW: the error checking in this function needs review. the basic idea is to return from this function in a known state - for example there is no point avoiding calling waveInReset just because the thread times out. */ if( stream->processingThread ) { /* callback stream */ /* Tell processing thread to abort immediately */ stream->abortProcessing = 1; SetEvent( stream->abortEvent ); } if( PA_IS_OUTPUT_STREAM_(stream) ) { for( i =0; i < stream->output.deviceCount; ++i ) { mmresult = waveOutReset( ((HWAVEOUT*)stream->output.waveHandles)[i] ); if( mmresult != MMSYSERR_NOERROR ) { PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); return paUnanticipatedHostError; } } } if( PA_IS_INPUT_STREAM_(stream) ) { for( i=0; i < stream->input.deviceCount; ++i ) { mmresult = waveInReset( ((HWAVEIN*)stream->input.waveHandles)[i] ); if( mmresult != MMSYSERR_NOERROR ) { PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); return paUnanticipatedHostError; } } } if( stream->processingThread ) { /* callback stream */ PA_DEBUG(("WinMME AbortStream: waiting for background thread.\n")); /* Calculate timeOut longer than longest time it could take to return all buffers. */ timeout = (int)(stream->allBuffersDurationMs * 1.5); if( timeout < PA_MME_MIN_TIMEOUT_MSEC_ ) timeout = PA_MME_MIN_TIMEOUT_MSEC_; waitResult = WaitForSingleObject( stream->processingThread, timeout ); if( waitResult == WAIT_TIMEOUT ) { PA_DEBUG(("WinMME AbortStream: timed out while waiting for background thread to finish.\n")); return paTimedOut; } CloseHandle( stream->processingThread ); stream->processingThread = NULL; } stream->isStopped = 1; stream->isActive = 0; return result; } static PaError IsStreamStopped( PaStream *s ) { PaWinMmeStream *stream = (PaWinMmeStream*)s; return stream->isStopped; } static PaError IsStreamActive( PaStream *s ) { PaWinMmeStream *stream = (PaWinMmeStream*)s; return stream->isActive; } static PaTime GetStreamTime( PaStream *s ) { (void) s; /* unused parameter */ return PaUtil_GetTime(); } static double GetStreamCpuLoad( PaStream* s ) { PaWinMmeStream *stream = (PaWinMmeStream*)s; return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); } /* As separate stream interfaces are used for blocking and callback streams, the following functions can be guaranteed to only be called for blocking streams. */ static PaError ReadStream( PaStream* s, void *buffer, unsigned long frames ) { PaError result = paNoError; PaWinMmeStream *stream = (PaWinMmeStream*)s; void *userBuffer; unsigned long framesRead = 0; unsigned long framesProcessed; signed int hostInputBufferIndex; DWORD waitResult; DWORD timeout = (unsigned long)(stream->allBuffersDurationMs * 0.5); unsigned int channel, i; if( PA_IS_INPUT_STREAM_(stream) ) { /* make a local copy of the user buffer pointer(s). this is necessary because PaUtil_CopyInput() advances these pointers every time it is called. */ if( stream->bufferProcessor.userInputIsInterleaved ) { userBuffer = buffer; } else { userBuffer = (void*)alloca( sizeof(void*) * stream->bufferProcessor.inputChannelCount ); if( !userBuffer ) return paInsufficientMemory; for( i = 0; ibufferProcessor.inputChannelCount; ++i ) ((void**)userBuffer)[i] = ((void**)buffer)[i]; } do{ if( CurrentInputBuffersAreDone( stream ) ) { if( NoBuffersAreQueued( &stream->input ) ) { /** @todo REVIEW: consider what to do if the input overflows. do we requeue all of the buffers? should we be running a thread to make sure they are always queued? see: http://www.portaudio.com/trac/ticket/117 */ result = paInputOverflowed; } hostInputBufferIndex = stream->input.currentBufferIndex; PaUtil_SetInputFrameCount( &stream->bufferProcessor, stream->input.framesPerBuffer - stream->input.framesUsedInCurrentBuffer ); channel = 0; for( i=0; iinput.deviceCount; ++i ) { /* we have stored the number of channels in the buffer in dwUser */ int channelCount = (int)stream->input.waveHeaders[i][ hostInputBufferIndex ].dwUser; PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, channel, stream->input.waveHeaders[i][ hostInputBufferIndex ].lpData + stream->input.framesUsedInCurrentBuffer * channelCount * stream->bufferProcessor.bytesPerHostInputSample, channelCount ); channel += channelCount; } framesProcessed = PaUtil_CopyInput( &stream->bufferProcessor, &userBuffer, frames - framesRead ); stream->input.framesUsedInCurrentBuffer += framesProcessed; if( stream->input.framesUsedInCurrentBuffer == stream->input.framesPerBuffer ) { result = AdvanceToNextInputBuffer( stream ); if( result != paNoError ) break; } framesRead += framesProcessed; }else{ /* wait for MME to signal that a buffer is available */ waitResult = WaitForSingleObject( stream->input.bufferEvent, timeout ); if( waitResult == WAIT_FAILED ) { result = paUnanticipatedHostError; break; } else if( waitResult == WAIT_TIMEOUT ) { /* if a timeout is encountered, continue, perhaps we should give up eventually */ } } }while( framesRead < frames ); } else { result = paCanNotReadFromAnOutputOnlyStream; } return result; } static PaError WriteStream( PaStream* s, const void *buffer, unsigned long frames ) { PaError result = paNoError; PaWinMmeStream *stream = (PaWinMmeStream*)s; const void *userBuffer; unsigned long framesWritten = 0; unsigned long framesProcessed; signed int hostOutputBufferIndex; DWORD waitResult; DWORD timeout = (unsigned long)(stream->allBuffersDurationMs * 0.5); unsigned int channel, i; if( PA_IS_OUTPUT_STREAM_(stream) ) { /* make a local copy of the user buffer pointer(s). this is necessary because PaUtil_CopyOutput() advances these pointers every time it is called. */ if( stream->bufferProcessor.userOutputIsInterleaved ) { userBuffer = buffer; } else { userBuffer = (const void*)alloca( sizeof(void*) * stream->bufferProcessor.outputChannelCount ); if( !userBuffer ) return paInsufficientMemory; for( i = 0; ibufferProcessor.outputChannelCount; ++i ) ((const void**)userBuffer)[i] = ((const void**)buffer)[i]; } do{ if( CurrentOutputBuffersAreDone( stream ) ) { if( NoBuffersAreQueued( &stream->output ) ) { /** @todo REVIEW: consider what to do if the output underflows. do we requeue all the existing buffers with zeros? should we run a separate thread to keep the buffers enqueued at all times? see: http://www.portaudio.com/trac/ticket/117 */ result = paOutputUnderflowed; } hostOutputBufferIndex = stream->output.currentBufferIndex; PaUtil_SetOutputFrameCount( &stream->bufferProcessor, stream->output.framesPerBuffer - stream->output.framesUsedInCurrentBuffer ); channel = 0; for( i=0; ioutput.deviceCount; ++i ) { /* we have stored the number of channels in the buffer in dwUser */ int channelCount = (int)stream->output.waveHeaders[i][ hostOutputBufferIndex ].dwUser; PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, channel, stream->output.waveHeaders[i][ hostOutputBufferIndex ].lpData + stream->output.framesUsedInCurrentBuffer * channelCount * stream->bufferProcessor.bytesPerHostOutputSample, channelCount ); channel += channelCount; } framesProcessed = PaUtil_CopyOutput( &stream->bufferProcessor, &userBuffer, frames - framesWritten ); stream->output.framesUsedInCurrentBuffer += framesProcessed; if( stream->output.framesUsedInCurrentBuffer == stream->output.framesPerBuffer ) { result = AdvanceToNextOutputBuffer( stream ); if( result != paNoError ) break; } framesWritten += framesProcessed; } else { /* wait for MME to signal that a buffer is available */ waitResult = WaitForSingleObject( stream->output.bufferEvent, timeout ); if( waitResult == WAIT_FAILED ) { result = paUnanticipatedHostError; break; } else if( waitResult == WAIT_TIMEOUT ) { /* if a timeout is encountered, continue, perhaps we should give up eventually */ } } }while( framesWritten < frames ); } else { result = paCanNotWriteToAnInputOnlyStream; } return result; } static signed long GetStreamReadAvailable( PaStream* s ) { PaWinMmeStream *stream = (PaWinMmeStream*)s; if( PA_IS_INPUT_STREAM_(stream) ) return GetAvailableFrames( &stream->input ); else return paCanNotReadFromAnOutputOnlyStream; } static signed long GetStreamWriteAvailable( PaStream* s ) { PaWinMmeStream *stream = (PaWinMmeStream*)s; if( PA_IS_OUTPUT_STREAM_(stream) ) return GetAvailableFrames( &stream->output ); else return paCanNotWriteToAnInputOnlyStream; } /* NOTE: the following functions are MME-stream specific, and are called directly by client code. We need to check for many more error conditions here because we don't have the benefit of pa_front.c's parameter checking. */ static PaError GetWinMMEStreamPointer( PaWinMmeStream **stream, PaStream *s ) { PaError result; PaUtilHostApiRepresentation *hostApi; PaWinMmeHostApiRepresentation *winMmeHostApi; result = PaUtil_ValidateStreamPointer( s ); if( result != paNoError ) return result; result = PaUtil_GetHostApiRepresentation( &hostApi, paMME ); if( result != paNoError ) return result; winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi; /* note, the following would be easier if there was a generic way of testing that a stream belongs to a specific host API */ if( PA_STREAM_REP( s )->streamInterface == &winMmeHostApi->callbackStreamInterface || PA_STREAM_REP( s )->streamInterface == &winMmeHostApi->blockingStreamInterface ) { /* s is a WinMME stream */ *stream = (PaWinMmeStream *)s; return paNoError; } else { return paIncompatibleStreamHostApi; } } int PaWinMME_GetStreamInputHandleCount( PaStream* s ) { PaWinMmeStream *stream; PaError result = GetWinMMEStreamPointer( &stream, s ); if( result == paNoError ) return (PA_IS_INPUT_STREAM_(stream)) ? stream->input.deviceCount : 0; else return result; } HWAVEIN PaWinMME_GetStreamInputHandle( PaStream* s, int handleIndex ) { PaWinMmeStream *stream; PaError result = GetWinMMEStreamPointer( &stream, s ); if( result == paNoError && PA_IS_INPUT_STREAM_(stream) && handleIndex >= 0 && (unsigned int)handleIndex < stream->input.deviceCount ) return ((HWAVEIN*)stream->input.waveHandles)[handleIndex]; else return 0; } int PaWinMME_GetStreamOutputHandleCount( PaStream* s) { PaWinMmeStream *stream; PaError result = GetWinMMEStreamPointer( &stream, s ); if( result == paNoError ) return (PA_IS_OUTPUT_STREAM_(stream)) ? stream->output.deviceCount : 0; else return result; } HWAVEOUT PaWinMME_GetStreamOutputHandle( PaStream* s, int handleIndex ) { PaWinMmeStream *stream; PaError result = GetWinMMEStreamPointer( &stream, s ); if( result == paNoError && PA_IS_OUTPUT_STREAM_(stream) && handleIndex >= 0 && (unsigned int)handleIndex < stream->output.deviceCount ) return ((HWAVEOUT*)stream->output.waveHandles)[handleIndex]; else return 0; } #endif praat-6.0.04/external/portaudio/pa_win_wmme.h000066400000000000000000000153541261542461700212330ustar00rootroot00000000000000#ifndef PA_WIN_WMME_H #define PA_WIN_WMME_H /* * $Id: pa_win_wmme.h 1592 2011-02-04 10:41:58Z rossb $ * PortAudio Portable Real-Time Audio Library * MME specific extensions * * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup public_header @brief WMME-specific PortAudio API extension header file. */ #include "portaudio.h" #include "pa_win_waveformat.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* The following are flags which can be set in PaWinMmeStreamInfo's flags field. */ #define paWinMmeUseLowLevelLatencyParameters (0x01) #define paWinMmeUseMultipleDevices (0x02) /* use mme specific multiple device feature */ #define paWinMmeUseChannelMask (0x04) /* By default, the mme implementation drops the processing thread's priority to THREAD_PRIORITY_NORMAL and sleeps the thread if the CPU load exceeds 100% This flag disables any priority throttling. The processing thread will always run at THREAD_PRIORITY_TIME_CRITICAL. */ #define paWinMmeDontThrottleOverloadedProcessingThread (0x08) /* Flags for non-PCM spdif passthrough. */ #define paWinMmeWaveFormatDolbyAc3Spdif (0x10) #define paWinMmeWaveFormatWmaSpdif (0x20) typedef struct PaWinMmeDeviceAndChannelCount{ PaDeviceIndex device; int channelCount; }PaWinMmeDeviceAndChannelCount; typedef struct PaWinMmeStreamInfo{ unsigned long size; /**< sizeof(PaWinMmeStreamInfo) */ PaHostApiTypeId hostApiType; /**< paMME */ unsigned long version; /**< 1 */ unsigned long flags; /* low-level latency setting support These settings control the number and size of host buffers in order to set latency. They will be used instead of the generic parameters to Pa_OpenStream() if flags contains the PaWinMmeUseLowLevelLatencyParameters flag. If PaWinMmeStreamInfo structures with PaWinMmeUseLowLevelLatencyParameters are supplied for both input and output in a full duplex stream, then the input and output framesPerBuffer must be the same, or the larger of the two must be a multiple of the smaller, otherwise a paIncompatibleHostApiSpecificStreamInfo error will be returned from Pa_OpenStream(). */ unsigned long framesPerBuffer; unsigned long bufferCount; /* formerly numBuffers */ /* multiple devices per direction support If flags contains the PaWinMmeUseMultipleDevices flag, this functionality will be used, otherwise the device parameter to Pa_OpenStream() will be used instead. If devices are specified here, the corresponding device parameter to Pa_OpenStream() should be set to paUseHostApiSpecificDeviceSpecification, otherwise an paInvalidDevice error will result. The total number of channels accross all specified devices must agree with the corresponding channelCount parameter to Pa_OpenStream() otherwise a paInvalidChannelCount error will result. */ PaWinMmeDeviceAndChannelCount *devices; unsigned long deviceCount; /* support for WAVEFORMATEXTENSIBLE channel masks. If flags contains paWinMmeUseChannelMask this allows you to specify which speakers to address in a multichannel stream. Constants for channelMask are specified in pa_win_waveformat.h */ PaWinWaveFormatChannelMask channelMask; }PaWinMmeStreamInfo; /** Retrieve the number of wave in handles used by a PortAudio WinMME stream. Returns zero if the stream is output only. @return A non-negative value indicating the number of wave in handles or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. @see PaWinMME_GetStreamInputHandle */ int PaWinMME_GetStreamInputHandleCount( PaStream* stream ); /** Retrieve a wave in handle used by a PortAudio WinMME stream. @param stream The stream to query. @param handleIndex The zero based index of the wave in handle to retrieve. This should be in the range [0, PaWinMME_GetStreamInputHandleCount(stream)-1]. @return A valid wave in handle, or NULL if an error occurred. @see PaWinMME_GetStreamInputHandle */ HWAVEIN PaWinMME_GetStreamInputHandle( PaStream* stream, int handleIndex ); /** Retrieve the number of wave out handles used by a PortAudio WinMME stream. Returns zero if the stream is input only. @return A non-negative value indicating the number of wave out handles or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. @see PaWinMME_GetStreamOutputHandle */ int PaWinMME_GetStreamOutputHandleCount( PaStream* stream ); /** Retrieve a wave out handle used by a PortAudio WinMME stream. @param stream The stream to query. @param handleIndex The zero based index of the wave out handle to retrieve. This should be in the range [0, PaWinMME_GetStreamOutputHandleCount(stream)-1]. @return A valid wave out handle, or NULL if an error occurred. @see PaWinMME_GetStreamOutputHandleCount */ HWAVEOUT PaWinMME_GetStreamOutputHandle( PaStream* stream, int handleIndex ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_WIN_WMME_H */ praat-6.0.04/external/portaudio/pa_x86_plain_converters.c000066400000000000000000001162171261542461700234660ustar00rootroot00000000000000/* * Plain Intel IA32 assembly implementations of PortAudio sample converter functions. * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup win_src */ #include "pa_x86_plain_converters.h" #include "pa_converters.h" #include "pa_dither.h" /* the main reason these versions are faster than the equivalent C versions is that float -> int casting is expensive in C on x86 because the rounding mode needs to be changed for every cast. these versions only set the rounding mode once outside the loop. small additional speed gains are made by the way that clamping is implemented. TODO: o- inline dither code o- implement Dither only (no-clip) versions o- implement int8 and uint8 versions o- test thouroughly o- the packed 24 bit functions could benefit from unrolling and avoiding byte and word sized register access. */ /* -------------------------------------------------------------------------- */ /* #define PA_CLIP_( val, min, max )\ { val = ((val) < (min)) ? (min) : (((val) > (max)) ? (max) : (val)); } */ /* the following notes were used to determine whether a floating point value should be saturated (ie >1 or <-1) by loading it into an integer register. these should be rewritten so that they make sense. an ieee floating point value 1.xxxxxxxxxxxxxxxxxxxx? is less than or equal to 1 and greater than or equal to -1 either: if the mantissa is 0 and the unbiased exponent is 0 OR if the unbiased exponent < 0 this translates to: if the mantissa is 0 and the biased exponent is 7F or if the biased exponent is less than 7F therefore the value is greater than 1 or less than -1 if the mantissa is not 0 and the biased exponent is 7F or if the biased exponent is greater than 7F in other words, if we mask out the sign bit, the value is greater than 1 or less than -1 if its integer representation is greater than: 0 01111111 0000 0000 0000 0000 0000 000 0011 1111 1000 0000 0000 0000 0000 0000 => 0x3F800000 */ #if defined(_WIN64) || defined(_WIN32_WCE) /* -EMT64/AMD64 uses different asm -VC2005 doesnt allow _WIN64 with inline assembly either! */ void PaUtil_InitializeX86PlainConverters( void ) { } #else /* -------------------------------------------------------------------------- */ static const short fpuControlWord_ = 0x033F; /*round to nearest, 64 bit precision, all exceptions masked*/ static const double int32Scaler_ = 0x7FFFFFFF; static const double ditheredInt32Scaler_ = 0x7FFFFFFE; static const double int24Scaler_ = 0x7FFFFF; static const double ditheredInt24Scaler_ = 0x7FFFFE; static const double int16Scaler_ = 0x7FFF; static const double ditheredInt16Scaler_ = 0x7FFE; #define PA_DITHER_BITS_ (15) /* Multiply by PA_FLOAT_DITHER_SCALE_ to get a float between -2.0 and +1.99999 */ #define PA_FLOAT_DITHER_SCALE_ (1.0F / ((1< source ptr // eax -> source byte stride // edi -> destination ptr // ebx -> destination byte stride // ecx -> source end ptr // edx -> temp mov esi, sourceBuffer mov edx, 4 // sizeof float32 and int32 mov eax, sourceStride imul eax, edx mov ecx, count imul ecx, eax add ecx, esi mov edi, destinationBuffer mov ebx, destinationStride imul ebx, edx fwait fstcw savedFpuControlWord fldcw fpuControlWord_ fld int32Scaler_ // stack: (int)0x7FFFFFFF Float32_To_Int32_loop: // load unscaled value into st(0) fld dword ptr [esi] // stack: value, (int)0x7FFFFFFF add esi, eax // increment source ptr //lea esi, [esi+eax] fmul st(0), st(1) // st(0) *= st(1), stack: value*0x7FFFFFFF, (int)0x7FFFFFFF /* note: we could store to a temporary qword here which would cause wraparound distortion instead of int indefinite 0x10. that would be more work, and given that not enabling clipping is only advisable when you know that your signal isn't going to clip it isn't worth it. */ fistp dword ptr [edi] // pop st(0) into dest, stack: (int)0x7FFFFFFF add edi, ebx // increment destination ptr //lea edi, [edi+ebx] cmp esi, ecx // has src ptr reached end? jne Float32_To_Int32_loop ffree st(0) fincstp fwait fnclex fldcw savedFpuControlWord } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int32_Clip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ) { /* float *src = (float*)sourceBuffer; signed long *dest = (signed long*)destinationBuffer; (void) ditherGenerator; // unused parameter while( count-- ) { // REVIEW double scaled = *src * 0x7FFFFFFF; PA_CLIP_( scaled, -2147483648., 2147483647. ); *dest = (signed long) scaled; src += sourceStride; dest += destinationStride; } */ short savedFpuControlWord; (void) ditherGenerator; /* unused parameter */ __asm{ // esi -> source ptr // eax -> source byte stride // edi -> destination ptr // ebx -> destination byte stride // ecx -> source end ptr // edx -> temp mov esi, sourceBuffer mov edx, 4 // sizeof float32 and int32 mov eax, sourceStride imul eax, edx mov ecx, count imul ecx, eax add ecx, esi mov edi, destinationBuffer mov ebx, destinationStride imul ebx, edx fwait fstcw savedFpuControlWord fldcw fpuControlWord_ fld int32Scaler_ // stack: (int)0x7FFFFFFF Float32_To_Int32_Clip_loop: mov edx, dword ptr [esi] // load floating point value into integer register and edx, 0x7FFFFFFF // mask off sign cmp edx, 0x3F800000 // greater than 1.0 or less than -1.0 jg Float32_To_Int32_Clip_clamp // load unscaled value into st(0) fld dword ptr [esi] // stack: value, (int)0x7FFFFFFF add esi, eax // increment source ptr //lea esi, [esi+eax] fmul st(0), st(1) // st(0) *= st(1), stack: value*0x7FFFFFFF, (int)0x7FFFFFFF fistp dword ptr [edi] // pop st(0) into dest, stack: (int)0x7FFFFFFF jmp Float32_To_Int32_Clip_stored Float32_To_Int32_Clip_clamp: mov edx, dword ptr [esi] // load floating point value into integer register shr edx, 31 // move sign bit into bit 0 add esi, eax // increment source ptr //lea esi, [esi+eax] add edx, 0x7FFFFFFF // convert to maximum range integers mov dword ptr [edi], edx Float32_To_Int32_Clip_stored: //add edi, ebx // increment destination ptr lea edi, [edi+ebx] cmp esi, ecx // has src ptr reached end? jne Float32_To_Int32_Clip_loop ffree st(0) fincstp fwait fnclex fldcw savedFpuControlWord } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int32_DitherClip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ) { /* float *src = (float*)sourceBuffer; signed long *dest = (signed long*)destinationBuffer; while( count-- ) { // REVIEW double dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); // use smaller scaler to prevent overflow when we add the dither double dithered = ((double)*src * (2147483646.0)) + dither; PA_CLIP_( dithered, -2147483648., 2147483647. ); *dest = (signed long) dithered; src += sourceStride; dest += destinationStride; } */ short savedFpuControlWord; // spill storage: signed long sourceByteStride; signed long highpassedDither; // dither state: unsigned long ditherPrevious = ditherGenerator->previous; unsigned long ditherRandSeed1 = ditherGenerator->randSeed1; unsigned long ditherRandSeed2 = ditherGenerator->randSeed2; __asm{ // esi -> source ptr // eax -> source byte stride // edi -> destination ptr // ebx -> destination byte stride // ecx -> source end ptr // edx -> temp mov esi, sourceBuffer mov edx, 4 // sizeof float32 and int32 mov eax, sourceStride imul eax, edx mov ecx, count imul ecx, eax add ecx, esi mov edi, destinationBuffer mov ebx, destinationStride imul ebx, edx fwait fstcw savedFpuControlWord fldcw fpuControlWord_ fld ditheredInt32Scaler_ // stack: int scaler Float32_To_Int32_DitherClip_loop: mov edx, dword ptr [esi] // load floating point value into integer register and edx, 0x7FFFFFFF // mask off sign cmp edx, 0x3F800000 // greater than 1.0 or less than -1.0 jg Float32_To_Int32_DitherClip_clamp // load unscaled value into st(0) fld dword ptr [esi] // stack: value, int scaler add esi, eax // increment source ptr //lea esi, [esi+eax] fmul st(0), st(1) // st(0) *= st(1), stack: value*(int scaler), int scaler /* // call PaUtil_GenerateFloatTriangularDither with C calling convention mov sourceByteStride, eax // save eax mov sourceEnd, ecx // save ecx push ditherGenerator // pass ditherGenerator parameter on stack call PaUtil_GenerateFloatTriangularDither // stack: dither, value*(int scaler), int scaler pop edx // clear parameter off stack mov ecx, sourceEnd // restore ecx mov eax, sourceByteStride // restore eax */ // generate dither mov sourceByteStride, eax // save eax mov edx, 196314165 mov eax, ditherRandSeed1 mul edx // eax:edx = eax * 196314165 //add eax, 907633515 lea eax, [eax+907633515] mov ditherRandSeed1, eax mov edx, 196314165 mov eax, ditherRandSeed2 mul edx // eax:edx = eax * 196314165 //add eax, 907633515 lea eax, [eax+907633515] mov edx, ditherRandSeed1 shr edx, PA_DITHER_SHIFT_ mov ditherRandSeed2, eax shr eax, PA_DITHER_SHIFT_ //add eax, edx // eax -> current lea eax, [eax+edx] mov edx, ditherPrevious neg edx lea edx, [eax+edx] // highpass = current - previous mov highpassedDither, edx mov ditherPrevious, eax // previous = current mov eax, sourceByteStride // restore eax fild highpassedDither fmul const_float_dither_scale_ // end generate dither, dither signal in st(0) faddp st(1), st(0) // stack: dither + value*(int scaler), int scaler fistp dword ptr [edi] // pop st(0) into dest, stack: int scaler jmp Float32_To_Int32_DitherClip_stored Float32_To_Int32_DitherClip_clamp: mov edx, dword ptr [esi] // load floating point value into integer register shr edx, 31 // move sign bit into bit 0 add esi, eax // increment source ptr //lea esi, [esi+eax] add edx, 0x7FFFFFFF // convert to maximum range integers mov dword ptr [edi], edx Float32_To_Int32_DitherClip_stored: //add edi, ebx // increment destination ptr lea edi, [edi+ebx] cmp esi, ecx // has src ptr reached end? jne Float32_To_Int32_DitherClip_loop ffree st(0) fincstp fwait fnclex fldcw savedFpuControlWord } ditherGenerator->previous = ditherPrevious; ditherGenerator->randSeed1 = ditherRandSeed1; ditherGenerator->randSeed2 = ditherRandSeed2; } /* -------------------------------------------------------------------------- */ static void Float32_To_Int24( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ) { /* float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; signed long temp; (void) ditherGenerator; // unused parameter while( count-- ) { // convert to 32 bit and drop the low 8 bits double scaled = *src * 0x7FFFFFFF; temp = (signed long) scaled; dest[0] = (unsigned char)(temp >> 8); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 24); src += sourceStride; dest += destinationStride * 3; } */ short savedFpuControlWord; signed long tempInt32; (void) ditherGenerator; /* unused parameter */ __asm{ // esi -> source ptr // eax -> source byte stride // edi -> destination ptr // ebx -> destination byte stride // ecx -> source end ptr // edx -> temp mov esi, sourceBuffer mov edx, 4 // sizeof float32 mov eax, sourceStride imul eax, edx mov ecx, count imul ecx, eax add ecx, esi mov edi, destinationBuffer mov edx, 3 // sizeof int24 mov ebx, destinationStride imul ebx, edx fwait fstcw savedFpuControlWord fldcw fpuControlWord_ fld int24Scaler_ // stack: (int)0x7FFFFF Float32_To_Int24_loop: // load unscaled value into st(0) fld dword ptr [esi] // stack: value, (int)0x7FFFFF add esi, eax // increment source ptr //lea esi, [esi+eax] fmul st(0), st(1) // st(0) *= st(1), stack: value*0x7FFFFF, (int)0x7FFFFF fistp tempInt32 // pop st(0) into tempInt32, stack: (int)0x7FFFFF mov edx, tempInt32 mov byte ptr [edi], DL shr edx, 8 //mov byte ptr [edi+1], DL //mov byte ptr [edi+2], DH mov word ptr [edi+1], DX //add edi, ebx // increment destination ptr lea edi, [edi+ebx] cmp esi, ecx // has src ptr reached end? jne Float32_To_Int24_loop ffree st(0) fincstp fwait fnclex fldcw savedFpuControlWord } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int24_Clip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ) { /* float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; signed long temp; (void) ditherGenerator; // unused parameter while( count-- ) { // convert to 32 bit and drop the low 8 bits double scaled = *src * 0x7FFFFFFF; PA_CLIP_( scaled, -2147483648., 2147483647. ); temp = (signed long) scaled; dest[0] = (unsigned char)(temp >> 8); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 24); src += sourceStride; dest += destinationStride * 3; } */ short savedFpuControlWord; signed long tempInt32; (void) ditherGenerator; /* unused parameter */ __asm{ // esi -> source ptr // eax -> source byte stride // edi -> destination ptr // ebx -> destination byte stride // ecx -> source end ptr // edx -> temp mov esi, sourceBuffer mov edx, 4 // sizeof float32 mov eax, sourceStride imul eax, edx mov ecx, count imul ecx, eax add ecx, esi mov edi, destinationBuffer mov edx, 3 // sizeof int24 mov ebx, destinationStride imul ebx, edx fwait fstcw savedFpuControlWord fldcw fpuControlWord_ fld int24Scaler_ // stack: (int)0x7FFFFF Float32_To_Int24_Clip_loop: mov edx, dword ptr [esi] // load floating point value into integer register and edx, 0x7FFFFFFF // mask off sign cmp edx, 0x3F800000 // greater than 1.0 or less than -1.0 jg Float32_To_Int24_Clip_clamp // load unscaled value into st(0) fld dword ptr [esi] // stack: value, (int)0x7FFFFF add esi, eax // increment source ptr //lea esi, [esi+eax] fmul st(0), st(1) // st(0) *= st(1), stack: value*0x7FFFFF, (int)0x7FFFFF fistp tempInt32 // pop st(0) into tempInt32, stack: (int)0x7FFFFF mov edx, tempInt32 jmp Float32_To_Int24_Clip_store Float32_To_Int24_Clip_clamp: mov edx, dword ptr [esi] // load floating point value into integer register shr edx, 31 // move sign bit into bit 0 add esi, eax // increment source ptr //lea esi, [esi+eax] add edx, 0x7FFFFF // convert to maximum range integers Float32_To_Int24_Clip_store: mov byte ptr [edi], DL shr edx, 8 //mov byte ptr [edi+1], DL //mov byte ptr [edi+2], DH mov word ptr [edi+1], DX //add edi, ebx // increment destination ptr lea edi, [edi+ebx] cmp esi, ecx // has src ptr reached end? jne Float32_To_Int24_Clip_loop ffree st(0) fincstp fwait fnclex fldcw savedFpuControlWord } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int24_DitherClip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ) { /* float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; signed long temp; while( count-- ) { // convert to 32 bit and drop the low 8 bits // FIXME: the dither amplitude here appears to be too small by 8 bits double dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); // use smaller scaler to prevent overflow when we add the dither double dithered = ((double)*src * (2147483646.0)) + dither; PA_CLIP_( dithered, -2147483648., 2147483647. ); temp = (signed long) dithered; dest[0] = (unsigned char)(temp >> 8); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 24); src += sourceStride; dest += destinationStride * 3; } */ short savedFpuControlWord; // spill storage: signed long sourceByteStride; signed long highpassedDither; // dither state: unsigned long ditherPrevious = ditherGenerator->previous; unsigned long ditherRandSeed1 = ditherGenerator->randSeed1; unsigned long ditherRandSeed2 = ditherGenerator->randSeed2; signed long tempInt32; __asm{ // esi -> source ptr // eax -> source byte stride // edi -> destination ptr // ebx -> destination byte stride // ecx -> source end ptr // edx -> temp mov esi, sourceBuffer mov edx, 4 // sizeof float32 mov eax, sourceStride imul eax, edx mov ecx, count imul ecx, eax add ecx, esi mov edi, destinationBuffer mov edx, 3 // sizeof int24 mov ebx, destinationStride imul ebx, edx fwait fstcw savedFpuControlWord fldcw fpuControlWord_ fld ditheredInt24Scaler_ // stack: int scaler Float32_To_Int24_DitherClip_loop: mov edx, dword ptr [esi] // load floating point value into integer register and edx, 0x7FFFFFFF // mask off sign cmp edx, 0x3F800000 // greater than 1.0 or less than -1.0 jg Float32_To_Int24_DitherClip_clamp // load unscaled value into st(0) fld dword ptr [esi] // stack: value, int scaler add esi, eax // increment source ptr //lea esi, [esi+eax] fmul st(0), st(1) // st(0) *= st(1), stack: value*(int scaler), int scaler /* // call PaUtil_GenerateFloatTriangularDither with C calling convention mov sourceByteStride, eax // save eax mov sourceEnd, ecx // save ecx push ditherGenerator // pass ditherGenerator parameter on stack call PaUtil_GenerateFloatTriangularDither // stack: dither, value*(int scaler), int scaler pop edx // clear parameter off stack mov ecx, sourceEnd // restore ecx mov eax, sourceByteStride // restore eax */ // generate dither mov sourceByteStride, eax // save eax mov edx, 196314165 mov eax, ditherRandSeed1 mul edx // eax:edx = eax * 196314165 //add eax, 907633515 lea eax, [eax+907633515] mov ditherRandSeed1, eax mov edx, 196314165 mov eax, ditherRandSeed2 mul edx // eax:edx = eax * 196314165 //add eax, 907633515 lea eax, [eax+907633515] mov edx, ditherRandSeed1 shr edx, PA_DITHER_SHIFT_ mov ditherRandSeed2, eax shr eax, PA_DITHER_SHIFT_ //add eax, edx // eax -> current lea eax, [eax+edx] mov edx, ditherPrevious neg edx lea edx, [eax+edx] // highpass = current - previous mov highpassedDither, edx mov ditherPrevious, eax // previous = current mov eax, sourceByteStride // restore eax fild highpassedDither fmul const_float_dither_scale_ // end generate dither, dither signal in st(0) faddp st(1), st(0) // stack: dither * value*(int scaler), int scaler fistp tempInt32 // pop st(0) into tempInt32, stack: int scaler mov edx, tempInt32 jmp Float32_To_Int24_DitherClip_store Float32_To_Int24_DitherClip_clamp: mov edx, dword ptr [esi] // load floating point value into integer register shr edx, 31 // move sign bit into bit 0 add esi, eax // increment source ptr //lea esi, [esi+eax] add edx, 0x7FFFFF // convert to maximum range integers Float32_To_Int24_DitherClip_store: mov byte ptr [edi], DL shr edx, 8 //mov byte ptr [edi+1], DL //mov byte ptr [edi+2], DH mov word ptr [edi+1], DX //add edi, ebx // increment destination ptr lea edi, [edi+ebx] cmp esi, ecx // has src ptr reached end? jne Float32_To_Int24_DitherClip_loop ffree st(0) fincstp fwait fnclex fldcw savedFpuControlWord } ditherGenerator->previous = ditherPrevious; ditherGenerator->randSeed1 = ditherRandSeed1; ditherGenerator->randSeed2 = ditherRandSeed2; } /* -------------------------------------------------------------------------- */ static void Float32_To_Int16( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ) { /* float *src = (float*)sourceBuffer; signed short *dest = (signed short*)destinationBuffer; (void)ditherGenerator; // unused parameter while( count-- ) { short samp = (short) (*src * (32767.0f)); *dest = samp; src += sourceStride; dest += destinationStride; } */ short savedFpuControlWord; (void) ditherGenerator; /* unused parameter */ __asm{ // esi -> source ptr // eax -> source byte stride // edi -> destination ptr // ebx -> destination byte stride // ecx -> source end ptr // edx -> temp mov esi, sourceBuffer mov edx, 4 // sizeof float32 mov eax, sourceStride imul eax, edx // source byte stride mov ecx, count imul ecx, eax add ecx, esi // source end ptr = count * source byte stride + source ptr mov edi, destinationBuffer mov edx, 2 // sizeof int16 mov ebx, destinationStride imul ebx, edx // destination byte stride fwait fstcw savedFpuControlWord fldcw fpuControlWord_ fld int16Scaler_ // stack: (int)0x7FFF Float32_To_Int16_loop: // load unscaled value into st(0) fld dword ptr [esi] // stack: value, (int)0x7FFF add esi, eax // increment source ptr //lea esi, [esi+eax] fmul st(0), st(1) // st(0) *= st(1), stack: value*0x7FFF, (int)0x7FFF fistp word ptr [edi] // store scaled int into dest, stack: (int)0x7FFF add edi, ebx // increment destination ptr //lea edi, [edi+ebx] cmp esi, ecx // has src ptr reached end? jne Float32_To_Int16_loop ffree st(0) fincstp fwait fnclex fldcw savedFpuControlWord } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int16_Clip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ) { /* float *src = (float*)sourceBuffer; signed short *dest = (signed short*)destinationBuffer; (void)ditherGenerator; // unused parameter while( count-- ) { long samp = (signed long) (*src * (32767.0f)); PA_CLIP_( samp, -0x8000, 0x7FFF ); *dest = (signed short) samp; src += sourceStride; dest += destinationStride; } */ short savedFpuControlWord; (void) ditherGenerator; /* unused parameter */ __asm{ // esi -> source ptr // eax -> source byte stride // edi -> destination ptr // ebx -> destination byte stride // ecx -> source end ptr // edx -> temp mov esi, sourceBuffer mov edx, 4 // sizeof float32 mov eax, sourceStride imul eax, edx // source byte stride mov ecx, count imul ecx, eax add ecx, esi // source end ptr = count * source byte stride + source ptr mov edi, destinationBuffer mov edx, 2 // sizeof int16 mov ebx, destinationStride imul ebx, edx // destination byte stride fwait fstcw savedFpuControlWord fldcw fpuControlWord_ fld int16Scaler_ // stack: (int)0x7FFF Float32_To_Int16_Clip_loop: mov edx, dword ptr [esi] // load floating point value into integer register and edx, 0x7FFFFFFF // mask off sign cmp edx, 0x3F800000 // greater than 1.0 or less than -1.0 jg Float32_To_Int16_Clip_clamp // load unscaled value into st(0) fld dword ptr [esi] // stack: value, (int)0x7FFF add esi, eax // increment source ptr //lea esi, [esi+eax] fmul st(0), st(1) // st(0) *= st(1), stack: value*0x7FFF, (int)0x7FFF fistp word ptr [edi] // store scaled int into dest, stack: (int)0x7FFF jmp Float32_To_Int16_Clip_stored Float32_To_Int16_Clip_clamp: mov edx, dword ptr [esi] // load floating point value into integer register shr edx, 31 // move sign bit into bit 0 add esi, eax // increment source ptr //lea esi, [esi+eax] add dx, 0x7FFF // convert to maximum range integers mov word ptr [edi], dx // store clamped into into dest Float32_To_Int16_Clip_stored: add edi, ebx // increment destination ptr //lea edi, [edi+ebx] cmp esi, ecx // has src ptr reached end? jne Float32_To_Int16_Clip_loop ffree st(0) fincstp fwait fnclex fldcw savedFpuControlWord } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int16_DitherClip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ) { /* float *src = (float*)sourceBuffer; signed short *dest = (signed short*)destinationBuffer; (void)ditherGenerator; // unused parameter while( count-- ) { float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); // use smaller scaler to prevent overflow when we add the dither float dithered = (*src * (32766.0f)) + dither; signed long samp = (signed long) dithered; PA_CLIP_( samp, -0x8000, 0x7FFF ); *dest = (signed short) samp; src += sourceStride; dest += destinationStride; } */ short savedFpuControlWord; // spill storage: signed long sourceByteStride; signed long highpassedDither; // dither state: unsigned long ditherPrevious = ditherGenerator->previous; unsigned long ditherRandSeed1 = ditherGenerator->randSeed1; unsigned long ditherRandSeed2 = ditherGenerator->randSeed2; __asm{ // esi -> source ptr // eax -> source byte stride // edi -> destination ptr // ebx -> destination byte stride // ecx -> source end ptr // edx -> temp mov esi, sourceBuffer mov edx, 4 // sizeof float32 mov eax, sourceStride imul eax, edx // source byte stride mov ecx, count imul ecx, eax add ecx, esi // source end ptr = count * source byte stride + source ptr mov edi, destinationBuffer mov edx, 2 // sizeof int16 mov ebx, destinationStride imul ebx, edx // destination byte stride fwait fstcw savedFpuControlWord fldcw fpuControlWord_ fld ditheredInt16Scaler_ // stack: int scaler Float32_To_Int16_DitherClip_loop: mov edx, dword ptr [esi] // load floating point value into integer register and edx, 0x7FFFFFFF // mask off sign cmp edx, 0x3F800000 // greater than 1.0 or less than -1.0 jg Float32_To_Int16_DitherClip_clamp // load unscaled value into st(0) fld dword ptr [esi] // stack: value, int scaler add esi, eax // increment source ptr //lea esi, [esi+eax] fmul st(0), st(1) // st(0) *= st(1), stack: value*(int scaler), int scaler /* // call PaUtil_GenerateFloatTriangularDither with C calling convention mov sourceByteStride, eax // save eax mov sourceEnd, ecx // save ecx push ditherGenerator // pass ditherGenerator parameter on stack call PaUtil_GenerateFloatTriangularDither // stack: dither, value*(int scaler), int scaler pop edx // clear parameter off stack mov ecx, sourceEnd // restore ecx mov eax, sourceByteStride // restore eax */ // generate dither mov sourceByteStride, eax // save eax mov edx, 196314165 mov eax, ditherRandSeed1 mul edx // eax:edx = eax * 196314165 //add eax, 907633515 lea eax, [eax+907633515] mov ditherRandSeed1, eax mov edx, 196314165 mov eax, ditherRandSeed2 mul edx // eax:edx = eax * 196314165 //add eax, 907633515 lea eax, [eax+907633515] mov edx, ditherRandSeed1 shr edx, PA_DITHER_SHIFT_ mov ditherRandSeed2, eax shr eax, PA_DITHER_SHIFT_ //add eax, edx // eax -> current lea eax, [eax+edx] // current = randSeed1>>x + randSeed2>>x mov edx, ditherPrevious neg edx lea edx, [eax+edx] // highpass = current - previous mov highpassedDither, edx mov ditherPrevious, eax // previous = current mov eax, sourceByteStride // restore eax fild highpassedDither fmul const_float_dither_scale_ // end generate dither, dither signal in st(0) faddp st(1), st(0) // stack: dither * value*(int scaler), int scaler fistp word ptr [edi] // store scaled int into dest, stack: int scaler jmp Float32_To_Int16_DitherClip_stored Float32_To_Int16_DitherClip_clamp: mov edx, dword ptr [esi] // load floating point value into integer register shr edx, 31 // move sign bit into bit 0 add esi, eax // increment source ptr //lea esi, [esi+eax] add dx, 0x7FFF // convert to maximum range integers mov word ptr [edi], dx // store clamped into into dest Float32_To_Int16_DitherClip_stored: add edi, ebx // increment destination ptr //lea edi, [edi+ebx] cmp esi, ecx // has src ptr reached end? jne Float32_To_Int16_DitherClip_loop ffree st(0) fincstp fwait fnclex fldcw savedFpuControlWord } ditherGenerator->previous = ditherPrevious; ditherGenerator->randSeed1 = ditherRandSeed1; ditherGenerator->randSeed2 = ditherRandSeed2; } /* -------------------------------------------------------------------------- */ void PaUtil_InitializeX86PlainConverters( void ) { paConverters.Float32_To_Int32 = Float32_To_Int32; paConverters.Float32_To_Int32_Clip = Float32_To_Int32_Clip; paConverters.Float32_To_Int32_DitherClip = Float32_To_Int32_DitherClip; paConverters.Float32_To_Int24 = Float32_To_Int24; paConverters.Float32_To_Int24_Clip = Float32_To_Int24_Clip; paConverters.Float32_To_Int24_DitherClip = Float32_To_Int24_DitherClip; paConverters.Float32_To_Int16 = Float32_To_Int16; paConverters.Float32_To_Int16_Clip = Float32_To_Int16_Clip; paConverters.Float32_To_Int16_DitherClip = Float32_To_Int16_DitherClip; } #endif /* -------------------------------------------------------------------------- */ praat-6.0.04/external/portaudio/pa_x86_plain_converters.h000066400000000000000000000041551261542461700234700ustar00rootroot00000000000000/* * Plain Intel IA32 assembly implementations of PortAudio sample converter functions. * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup win_src */ #ifndef PA_X86_PLAIN_CONVERTERS_H #define PA_X86_PLAIN_CONVERTERS_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** @brief Install optimized converter functions suitable for all IA32 processors It is recommended to call PaUtil_InitializeX86PlainConverters prior to calling Pa_Initialize */ void PaUtil_InitializeX86PlainConverters( void ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_X86_PLAIN_CONVERTERS_H */ praat-6.0.04/external/portaudio/portaudio.h000066400000000000000000001314171261542461700207360ustar00rootroot00000000000000#ifndef PORTAUDIO_H #define PORTAUDIO_H /* * $Id: portaudio.h 1859 2012-09-01 00:10:13Z philburk $ * PortAudio Portable Real-Time Audio Library * PortAudio API Header File * Latest version available at: http://www.portaudio.com/ * * Copyright (c) 1999-2002 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup public_header @brief The portable PortAudio API. */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** Retrieve the release number of the currently running PortAudio build, eg 1900. */ int Pa_GetVersion( void ); /** Retrieve a textual description of the current PortAudio build, eg "PortAudio V19-devel 13 October 2002". */ const char* Pa_GetVersionText( void ); /** Error codes returned by PortAudio functions. Note that with the exception of paNoError, all PaErrorCodes are negative. */ typedef int PaError; typedef enum PaErrorCode { paNoError = 0, paNotInitialized = -10000, paUnanticipatedHostError, paInvalidChannelCount, paInvalidSampleRate, paInvalidDevice, paInvalidFlag, paSampleFormatNotSupported, paBadIODeviceCombination, paInsufficientMemory, paBufferTooBig, paBufferTooSmall, paNullCallback, paBadStreamPtr, paTimedOut, paInternalError, paDeviceUnavailable, paIncompatibleHostApiSpecificStreamInfo, paStreamIsStopped, paStreamIsNotStopped, paInputOverflowed, paOutputUnderflowed, paHostApiNotFound, paInvalidHostApi, paCanNotReadFromACallbackStream, paCanNotWriteToACallbackStream, paCanNotReadFromAnOutputOnlyStream, paCanNotWriteToAnInputOnlyStream, paIncompatibleStreamHostApi, paBadBufferPtr } PaErrorCode; /** Translate the supplied PortAudio error code into a human readable message. */ const char *Pa_GetErrorText( PaError errorCode ); /** Library initialization function - call this before using PortAudio. This function initializes internal data structures and prepares underlying host APIs for use. With the exception of Pa_GetVersion(), Pa_GetVersionText(), and Pa_GetErrorText(), this function MUST be called before using any other PortAudio API functions. If Pa_Initialize() is called multiple times, each successful call must be matched with a corresponding call to Pa_Terminate(). Pairs of calls to Pa_Initialize()/Pa_Terminate() may overlap, and are not required to be fully nested. Note that if Pa_Initialize() returns an error code, Pa_Terminate() should NOT be called. @return paNoError if successful, otherwise an error code indicating the cause of failure. @see Pa_Terminate */ PaError Pa_Initialize( void ); /** Library termination function - call this when finished using PortAudio. This function deallocates all resources allocated by PortAudio since it was initialized by a call to Pa_Initialize(). In cases where Pa_Initialise() has been called multiple times, each call must be matched with a corresponding call to Pa_Terminate(). The final matching call to Pa_Terminate() will automatically close any PortAudio streams that are still open. Pa_Terminate() MUST be called before exiting a program which uses PortAudio. Failure to do so may result in serious resource leaks, such as audio devices not being available until the next reboot. @return paNoError if successful, otherwise an error code indicating the cause of failure. @see Pa_Initialize */ PaError Pa_Terminate( void ); /** The type used to refer to audio devices. Values of this type usually range from 0 to (Pa_GetDeviceCount()-1), and may also take on the PaNoDevice and paUseHostApiSpecificDeviceSpecification values. @see Pa_GetDeviceCount, paNoDevice, paUseHostApiSpecificDeviceSpecification */ typedef int PaDeviceIndex; /** A special PaDeviceIndex value indicating that no device is available, or should be used. @see PaDeviceIndex */ #define paNoDevice ((PaDeviceIndex)-1) /** A special PaDeviceIndex value indicating that the device(s) to be used are specified in the host api specific stream info structure. @see PaDeviceIndex */ #define paUseHostApiSpecificDeviceSpecification ((PaDeviceIndex)-2) /* Host API enumeration mechanism */ /** The type used to enumerate to host APIs at runtime. Values of this type range from 0 to (Pa_GetHostApiCount()-1). @see Pa_GetHostApiCount */ typedef int PaHostApiIndex; /** Retrieve the number of available host APIs. Even if a host API is available it may have no devices available. @return A non-negative value indicating the number of available host APIs or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. @see PaHostApiIndex */ PaHostApiIndex Pa_GetHostApiCount( void ); /** Retrieve the index of the default host API. The default host API will be the lowest common denominator host API on the current platform and is unlikely to provide the best performance. @return A non-negative value ranging from 0 to (Pa_GetHostApiCount()-1) indicating the default host API index or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. */ PaHostApiIndex Pa_GetDefaultHostApi( void ); /** Unchanging unique identifiers for each supported host API. This type is used in the PaHostApiInfo structure. The values are guaranteed to be unique and to never change, thus allowing code to be written that conditionally uses host API specific extensions. New type ids will be allocated when support for a host API reaches "public alpha" status, prior to that developers should use the paInDevelopment type id. @see PaHostApiInfo */ typedef enum PaHostApiTypeId { paInDevelopment=0, /* use while developing support for a new host API */ paDirectSound=1, paMME=2, paASIO=3, paSoundManager=4, paCoreAudio=5, paOSS=7, paALSA=8, paAL=9, paBeOS=10, paWDMKS=11, paJACK=12, paWASAPI=13, paAudioScienceHPI=14 } PaHostApiTypeId; /** A structure containing information about a particular host API. */ typedef struct PaHostApiInfo { /** this is struct version 1 */ int structVersion; /** The well known unique identifier of this host API @see PaHostApiTypeId */ PaHostApiTypeId type; /** A textual description of the host API for display on user interfaces. */ const char *name; /** The number of devices belonging to this host API. This field may be used in conjunction with Pa_HostApiDeviceIndexToDeviceIndex() to enumerate all devices for this host API. @see Pa_HostApiDeviceIndexToDeviceIndex */ int deviceCount; /** The default input device for this host API. The value will be a device index ranging from 0 to (Pa_GetDeviceCount()-1), or paNoDevice if no default input device is available. */ PaDeviceIndex defaultInputDevice; /** The default output device for this host API. The value will be a device index ranging from 0 to (Pa_GetDeviceCount()-1), or paNoDevice if no default output device is available. */ PaDeviceIndex defaultOutputDevice; } PaHostApiInfo; /** Retrieve a pointer to a structure containing information about a specific host Api. @param hostApi A valid host API index ranging from 0 to (Pa_GetHostApiCount()-1) @return A pointer to an immutable PaHostApiInfo structure describing a specific host API. If the hostApi parameter is out of range or an error is encountered, the function returns NULL. The returned structure is owned by the PortAudio implementation and must not be manipulated or freed. The pointer is only guaranteed to be valid between calls to Pa_Initialize() and Pa_Terminate(). */ const PaHostApiInfo * Pa_GetHostApiInfo( PaHostApiIndex hostApi ); /** Convert a static host API unique identifier, into a runtime host API index. @param type A unique host API identifier belonging to the PaHostApiTypeId enumeration. @return A valid PaHostApiIndex ranging from 0 to (Pa_GetHostApiCount()-1) or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. The paHostApiNotFound error code indicates that the host API specified by the type parameter is not available. @see PaHostApiTypeId */ PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type ); /** Convert a host-API-specific device index to standard PortAudio device index. This function may be used in conjunction with the deviceCount field of PaHostApiInfo to enumerate all devices for the specified host API. @param hostApi A valid host API index ranging from 0 to (Pa_GetHostApiCount()-1) @param hostApiDeviceIndex A valid per-host device index in the range 0 to (Pa_GetHostApiInfo(hostApi)->deviceCount-1) @return A non-negative PaDeviceIndex ranging from 0 to (Pa_GetDeviceCount()-1) or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. A paInvalidHostApi error code indicates that the host API index specified by the hostApi parameter is out of range. A paInvalidDevice error code indicates that the hostApiDeviceIndex parameter is out of range. @see PaHostApiInfo */ PaDeviceIndex Pa_HostApiDeviceIndexToDeviceIndex( PaHostApiIndex hostApi, int hostApiDeviceIndex ); /** Structure used to return information about a host error condition. */ typedef struct PaHostErrorInfo{ PaHostApiTypeId hostApiType; /**< the host API which returned the error code */ long errorCode; /**< the error code returned */ const char *errorText; /**< a textual description of the error if available, otherwise a zero-length string */ }PaHostErrorInfo; /** Return information about the last host error encountered. The error information returned by Pa_GetLastHostErrorInfo() will never be modified asynchronously by errors occurring in other PortAudio owned threads (such as the thread that manages the stream callback.) This function is provided as a last resort, primarily to enhance debugging by providing clients with access to all available error information. @return A pointer to an immutable structure constraining information about the host error. The values in this structure will only be valid if a PortAudio function has previously returned the paUnanticipatedHostError error code. */ const PaHostErrorInfo* Pa_GetLastHostErrorInfo( void ); /* Device enumeration and capabilities */ /** Retrieve the number of available devices. The number of available devices may be zero. @return A non-negative value indicating the number of available devices or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. */ PaDeviceIndex Pa_GetDeviceCount( void ); /** Retrieve the index of the default input device. The result can be used in the inputDevice parameter to Pa_OpenStream(). @return The default input device index for the default host API, or paNoDevice if no default input device is available or an error was encountered. */ PaDeviceIndex Pa_GetDefaultInputDevice( void ); /** Retrieve the index of the default output device. The result can be used in the outputDevice parameter to Pa_OpenStream(). @return The default output device index for the default host API, or paNoDevice if no default output device is available or an error was encountered. @note On the PC, the user can specify a default device by setting an environment variable. For example, to use device #1.
 set PA_RECOMMENDED_OUTPUT_DEVICE=1
The user should first determine the available device ids by using the supplied application "pa_devs". */ PaDeviceIndex Pa_GetDefaultOutputDevice( void ); /** The type used to represent monotonic time in seconds. PaTime is used for the fields of the PaStreamCallbackTimeInfo argument to the PaStreamCallback and as the result of Pa_GetStreamTime(). PaTime values have unspecified origin. @see PaStreamCallback, PaStreamCallbackTimeInfo, Pa_GetStreamTime */ typedef double PaTime; /** A type used to specify one or more sample formats. Each value indicates a possible format for sound data passed to and from the stream callback, Pa_ReadStream and Pa_WriteStream. The standard formats paFloat32, paInt16, paInt32, paInt24, paInt8 and aUInt8 are usually implemented by all implementations. The floating point representation (paFloat32) uses +1.0 and -1.0 as the maximum and minimum respectively. paUInt8 is an unsigned 8 bit format where 128 is considered "ground" The paNonInterleaved flag indicates that audio data is passed as an array of pointers to separate buffers, one buffer for each channel. Usually, when this flag is not used, audio data is passed as a single buffer with all channels interleaved. @see Pa_OpenStream, Pa_OpenDefaultStream, PaDeviceInfo @see paFloat32, paInt16, paInt32, paInt24, paInt8 @see paUInt8, paCustomFormat, paNonInterleaved */ typedef unsigned long PaSampleFormat; #define paFloat32 ((PaSampleFormat) 0x00000001) /**< @see PaSampleFormat */ #define paInt32 ((PaSampleFormat) 0x00000002) /**< @see PaSampleFormat */ #define paInt24 ((PaSampleFormat) 0x00000004) /**< Packed 24 bit format. @see PaSampleFormat */ #define paInt16 ((PaSampleFormat) 0x00000008) /**< @see PaSampleFormat */ #define paInt8 ((PaSampleFormat) 0x00000010) /**< @see PaSampleFormat */ #define paUInt8 ((PaSampleFormat) 0x00000020) /**< @see PaSampleFormat */ #define paCustomFormat ((PaSampleFormat) 0x00010000) /**< @see PaSampleFormat */ #define paNonInterleaved ((PaSampleFormat) 0x80000000) /**< @see PaSampleFormat */ /** A structure providing information and capabilities of PortAudio devices. Devices may support input, output or both input and output. */ typedef struct PaDeviceInfo { int structVersion; /* this is struct version 2 */ const char *name; PaHostApiIndex hostApi; /**< note this is a host API index, not a type id*/ int maxInputChannels; int maxOutputChannels; /** Default latency values for interactive performance. */ PaTime defaultLowInputLatency; PaTime defaultLowOutputLatency; /** Default latency values for robust non-interactive applications (eg. playing sound files). */ PaTime defaultHighInputLatency; PaTime defaultHighOutputLatency; double defaultSampleRate; } PaDeviceInfo; /** Retrieve a pointer to a PaDeviceInfo structure containing information about the specified device. @return A pointer to an immutable PaDeviceInfo structure. If the device parameter is out of range the function returns NULL. @param device A valid device index in the range 0 to (Pa_GetDeviceCount()-1) @note PortAudio manages the memory referenced by the returned pointer, the client must not manipulate or free the memory. The pointer is only guaranteed to be valid between calls to Pa_Initialize() and Pa_Terminate(). @see PaDeviceInfo, PaDeviceIndex */ const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceIndex device ); /** Parameters for one direction (input or output) of a stream. */ typedef struct PaStreamParameters { /** A valid device index in the range 0 to (Pa_GetDeviceCount()-1) specifying the device to be used or the special constant paUseHostApiSpecificDeviceSpecification which indicates that the actual device(s) to use are specified in hostApiSpecificStreamInfo. This field must not be set to paNoDevice. */ PaDeviceIndex device; /** The number of channels of sound to be delivered to the stream callback or accessed by Pa_ReadStream() or Pa_WriteStream(). It can range from 1 to the value of maxInputChannels in the PaDeviceInfo record for the device specified by the device parameter. */ int channelCount; /** The sample format of the buffer provided to the stream callback, a_ReadStream() or Pa_WriteStream(). It may be any of the formats described by the PaSampleFormat enumeration. */ PaSampleFormat sampleFormat; /** The desired latency in seconds. Where practical, implementations should configure their latency based on these parameters, otherwise they may choose the closest viable latency instead. Unless the suggested latency is greater than the absolute upper limit for the device implementations should round the suggestedLatency up to the next practical value - ie to provide an equal or higher latency than suggestedLatency wherever possible. Actual latency values for an open stream may be retrieved using the inputLatency and outputLatency fields of the PaStreamInfo structure returned by Pa_GetStreamInfo(). @see default*Latency in PaDeviceInfo, *Latency in PaStreamInfo */ PaTime suggestedLatency; /** An optional pointer to a host api specific data structure containing additional information for device setup and/or stream processing. hostApiSpecificStreamInfo is never required for correct operation, if not used it should be set to NULL. */ void *hostApiSpecificStreamInfo; } PaStreamParameters; /** Return code for Pa_IsFormatSupported indicating success. */ #define paFormatIsSupported (0) /** Determine whether it would be possible to open a stream with the specified parameters. @param inputParameters A structure that describes the input parameters used to open a stream. The suggestedLatency field is ignored. See PaStreamParameters for a description of these parameters. inputParameters must be NULL for output-only streams. @param outputParameters A structure that describes the output parameters used to open a stream. The suggestedLatency field is ignored. See PaStreamParameters for a description of these parameters. outputParameters must be NULL for input-only streams. @param sampleRate The required sampleRate. For full-duplex streams it is the sample rate for both input and output @return Returns 0 if the format is supported, and an error code indicating why the format is not supported otherwise. The constant paFormatIsSupported is provided to compare with the return value for success. @see paFormatIsSupported, PaStreamParameters */ PaError Pa_IsFormatSupported( const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); /* Streaming types and functions */ /** A single PaStream can provide multiple channels of real-time streaming audio input and output to a client application. A stream provides access to audio hardware represented by one or more PaDevices. Depending on the underlying Host API, it may be possible to open multiple streams using the same device, however this behavior is implementation defined. Portable applications should assume that a PaDevice may be simultaneously used by at most one PaStream. Pointers to PaStream objects are passed between PortAudio functions that operate on streams. @see Pa_OpenStream, Pa_OpenDefaultStream, Pa_OpenDefaultStream, Pa_CloseStream, Pa_StartStream, Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive, Pa_GetStreamTime, Pa_GetStreamCpuLoad */ typedef void PaStream; /** Can be passed as the framesPerBuffer parameter to Pa_OpenStream() or Pa_OpenDefaultStream() to indicate that the stream callback will accept buffers of any size. */ #define paFramesPerBufferUnspecified (0) /** Flags used to control the behavior of a stream. They are passed as parameters to Pa_OpenStream or Pa_OpenDefaultStream. Multiple flags may be ORed together. @see Pa_OpenStream, Pa_OpenDefaultStream @see paNoFlag, paClipOff, paDitherOff, paNeverDropInput, paPrimeOutputBuffersUsingStreamCallback, paPlatformSpecificFlags */ typedef unsigned long PaStreamFlags; /** @see PaStreamFlags */ #define paNoFlag ((PaStreamFlags) 0) /** Disable default clipping of out of range samples. @see PaStreamFlags */ #define paClipOff ((PaStreamFlags) 0x00000001) /** Disable default dithering. @see PaStreamFlags */ #define paDitherOff ((PaStreamFlags) 0x00000002) /** Flag requests that where possible a full duplex stream will not discard overflowed input samples without calling the stream callback. This flag is only valid for full duplex callback streams and only when used in combination with the paFramesPerBufferUnspecified (0) framesPerBuffer parameter. Using this flag incorrectly results in a paInvalidFlag error being returned from Pa_OpenStream and Pa_OpenDefaultStream. @see PaStreamFlags, paFramesPerBufferUnspecified */ #define paNeverDropInput ((PaStreamFlags) 0x00000004) /** Call the stream callback to fill initial output buffers, rather than the default behavior of priming the buffers with zeros (silence). This flag has no effect for input-only and blocking read/write streams. @see PaStreamFlags */ #define paPrimeOutputBuffersUsingStreamCallback ((PaStreamFlags) 0x00000008) /** A mask specifying the platform specific bits. @see PaStreamFlags */ #define paPlatformSpecificFlags ((PaStreamFlags)0xFFFF0000) /** Timing information for the buffers passed to the stream callback. Time values are expressed in seconds and are synchronised with the time base used by Pa_GetStreamTime() for the associated stream. @see PaStreamCallback, Pa_GetStreamTime */ typedef struct PaStreamCallbackTimeInfo{ PaTime inputBufferAdcTime; /**< The time when the first sample of the input buffer was captured at the ADC input */ PaTime currentTime; /**< The time when the stream callback was invoked */ PaTime outputBufferDacTime; /**< The time when the first sample of the output buffer will output the DAC */ } PaStreamCallbackTimeInfo; /** Flag bit constants for the statusFlags to PaStreamCallback. @see paInputUnderflow, paInputOverflow, paOutputUnderflow, paOutputOverflow, paPrimingOutput */ typedef unsigned long PaStreamCallbackFlags; /** In a stream opened with paFramesPerBufferUnspecified, indicates that input data is all silence (zeros) because no real data is available. In a stream opened without paFramesPerBufferUnspecified, it indicates that one or more zero samples have been inserted into the input buffer to compensate for an input underflow. @see PaStreamCallbackFlags */ #define paInputUnderflow ((PaStreamCallbackFlags) 0x00000001) /** In a stream opened with paFramesPerBufferUnspecified, indicates that data prior to the first sample of the input buffer was discarded due to an overflow, possibly because the stream callback is using too much CPU time. Otherwise indicates that data prior to one or more samples in the input buffer was discarded. @see PaStreamCallbackFlags */ #define paInputOverflow ((PaStreamCallbackFlags) 0x00000002) /** Indicates that output data (or a gap) was inserted, possibly because the stream callback is using too much CPU time. @see PaStreamCallbackFlags */ #define paOutputUnderflow ((PaStreamCallbackFlags) 0x00000004) /** Indicates that output data will be discarded because no room is available. @see PaStreamCallbackFlags */ #define paOutputOverflow ((PaStreamCallbackFlags) 0x00000008) /** Some of all of the output data will be used to prime the stream, input data may be zero. @see PaStreamCallbackFlags */ #define paPrimingOutput ((PaStreamCallbackFlags) 0x00000010) /** Allowable return values for the PaStreamCallback. @see PaStreamCallback */ typedef enum PaStreamCallbackResult { paContinue=0, /**< Signal that the stream should continue invoking the callback and processing audio. */ paComplete=1, /**< Signal that the stream should stop invoking the callback and finish once all output samples have played. */ paAbort=2 /**< Signal that the stream should stop invoking the callback and finish as soon as possible. */ } PaStreamCallbackResult; /** Functions of type PaStreamCallback are implemented by PortAudio clients. They consume, process or generate audio in response to requests from an active PortAudio stream. When a stream is running, PortAudio calls the stream callback periodically. The callback function is responsible for processing buffers of audio samples passed via the input and output parameters. The PortAudio stream callback runs at very high or real-time priority. It is required to consistently meet its time deadlines. Do not allocate memory, access the file system, call library functions or call other functions from the stream callback that may block or take an unpredictable amount of time to complete. In order for a stream to maintain glitch-free operation the callback must consume and return audio data faster than it is recorded and/or played. PortAudio anticipates that each callback invocation may execute for a duration approaching the duration of frameCount audio frames at the stream sample rate. It is reasonable to expect to be able to utilise 70% or more of the available CPU time in the PortAudio callback. However, due to buffer size adaption and other factors, not all host APIs are able to guarantee audio stability under heavy CPU load with arbitrary fixed callback buffer sizes. When high callback CPU utilisation is required the most robust behavior can be achieved by using paFramesPerBufferUnspecified as the Pa_OpenStream() framesPerBuffer parameter. @param input and @param output are either arrays of interleaved samples or; if non-interleaved samples were requested using the paNonInterleaved sample format flag, an array of buffer pointers, one non-interleaved buffer for each channel. The format, packing and number of channels used by the buffers are determined by parameters to Pa_OpenStream(). @param frameCount The number of sample frames to be processed by the stream callback. @param timeInfo Timestamps indicating the ADC capture time of the first sample in the input buffer, the DAC output time of the first sample in the output buffer and the time the callback was invoked. See PaStreamCallbackTimeInfo and Pa_GetStreamTime() @param statusFlags Flags indicating whether input and/or output buffers have been inserted or will be dropped to overcome underflow or overflow conditions. @param userData The value of a user supplied pointer passed to Pa_OpenStream() intended for storing synthesis data etc. @return The stream callback should return one of the values in the ::PaStreamCallbackResult enumeration. To ensure that the callback continues to be called, it should return paContinue (0). Either paComplete or paAbort can be returned to finish stream processing, after either of these values is returned the callback will not be called again. If paAbort is returned the stream will finish as soon as possible. If paComplete is returned, the stream will continue until all buffers generated by the callback have been played. This may be useful in applications such as soundfile players where a specific duration of output is required. However, it is not necessary to utilize this mechanism as Pa_StopStream(), Pa_AbortStream() or Pa_CloseStream() can also be used to stop the stream. The callback must always fill the entire output buffer irrespective of its return value. @see Pa_OpenStream, Pa_OpenDefaultStream @note With the exception of Pa_GetStreamCpuLoad() it is not permissible to call PortAudio API functions from within the stream callback. */ typedef int PaStreamCallback( const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData ); /** Opens a stream for either input, output or both. @param stream The address of a PaStream pointer which will receive a pointer to the newly opened stream. @param inputParameters A structure that describes the input parameters used by the opened stream. See PaStreamParameters for a description of these parameters. inputParameters must be NULL for output-only streams. @param outputParameters A structure that describes the output parameters used by the opened stream. See PaStreamParameters for a description of these parameters. outputParameters must be NULL for input-only streams. @param sampleRate The desired sampleRate. For full-duplex streams it is the sample rate for both input and output @param framesPerBuffer The number of frames passed to the stream callback function, or the preferred block granularity for a blocking read/write stream. The special value paFramesPerBufferUnspecified (0) may be used to request that the stream callback will receive an optimal (and possibly varying) number of frames based on host requirements and the requested latency settings. Note: With some host APIs, the use of non-zero framesPerBuffer for a callback stream may introduce an additional layer of buffering which could introduce additional latency. PortAudio guarantees that the additional latency will be kept to the theoretical minimum however, it is strongly recommended that a non-zero framesPerBuffer value only be used when your algorithm requires a fixed number of frames per stream callback. @param streamFlags Flags which modify the behavior of the streaming process. This parameter may contain a combination of flags ORed together. Some flags may only be relevant to certain buffer formats. @param streamCallback A pointer to a client supplied function that is responsible for processing and filling input and output buffers. If this parameter is NULL the stream will be opened in 'blocking read/write' mode. In blocking mode, the client can receive sample data using Pa_ReadStream and write sample data using Pa_WriteStream, the number of samples that may be read or written without blocking is returned by Pa_GetStreamReadAvailable and Pa_GetStreamWriteAvailable respectively. @param userData A client supplied pointer which is passed to the stream callback function. It could for example, contain a pointer to instance data necessary for processing the audio buffers. This parameter is ignored if streamCallback is NULL. @return Upon success Pa_OpenStream() returns paNoError and places a pointer to a valid PaStream in the stream argument. The stream is inactive (stopped). If a call to Pa_OpenStream() fails, a non-zero error code is returned (see PaError for possible error codes) and the value of stream is invalid. @see PaStreamParameters, PaStreamCallback, Pa_ReadStream, Pa_WriteStream, Pa_GetStreamReadAvailable, Pa_GetStreamWriteAvailable */ PaError Pa_OpenStream( PaStream** stream, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); /** A simplified version of Pa_OpenStream() that opens the default input and/or output devices. @param stream The address of a PaStream pointer which will receive a pointer to the newly opened stream. @param numInputChannels The number of channels of sound that will be supplied to the stream callback or returned by Pa_ReadStream. It can range from 1 to the value of maxInputChannels in the PaDeviceInfo record for the default input device. If 0 the stream is opened as an output-only stream. @param numOutputChannels The number of channels of sound to be delivered to the stream callback or passed to Pa_WriteStream. It can range from 1 to the value of maxOutputChannels in the PaDeviceInfo record for the default output device. If 0 the stream is opened as an output-only stream. @param sampleFormat The sample format of both the input and output buffers provided to the callback or passed to and from Pa_ReadStream and Pa_WriteStream. sampleFormat may be any of the formats described by the PaSampleFormat enumeration. @param sampleRate Same as Pa_OpenStream parameter of the same name. @param framesPerBuffer Same as Pa_OpenStream parameter of the same name. @param streamCallback Same as Pa_OpenStream parameter of the same name. @param userData Same as Pa_OpenStream parameter of the same name. @return As for Pa_OpenStream @see Pa_OpenStream, PaStreamCallback */ PaError Pa_OpenDefaultStream( PaStream** stream, int numInputChannels, int numOutputChannels, PaSampleFormat sampleFormat, double sampleRate, unsigned long framesPerBuffer, PaStreamCallback *streamCallback, void *userData ); /** Closes an audio stream. If the audio stream is active it discards any pending buffers as if Pa_AbortStream() had been called. */ PaError Pa_CloseStream( PaStream *stream ); /** Functions of type PaStreamFinishedCallback are implemented by PortAudio clients. They can be registered with a stream using the Pa_SetStreamFinishedCallback function. Once registered they are called when the stream becomes inactive (ie once a call to Pa_StopStream() will not block). A stream will become inactive after the stream callback returns non-zero, or when Pa_StopStream or Pa_AbortStream is called. For a stream providing audio output, if the stream callback returns paComplete, or Pa_StopStream is called, the stream finished callback will not be called until all generated sample data has been played. @param userData The userData parameter supplied to Pa_OpenStream() @see Pa_SetStreamFinishedCallback */ typedef void PaStreamFinishedCallback( void *userData ); /** Register a stream finished callback function which will be called when the stream becomes inactive. See the description of PaStreamFinishedCallback for further details about when the callback will be called. @param stream a pointer to a PaStream that is in the stopped state - if the stream is not stopped, the stream's finished callback will remain unchanged and an error code will be returned. @param streamFinishedCallback a pointer to a function with the same signature as PaStreamFinishedCallback, that will be called when the stream becomes inactive. Passing NULL for this parameter will un-register a previously registered stream finished callback function. @return on success returns paNoError, otherwise an error code indicating the cause of the error. @see PaStreamFinishedCallback */ PaError Pa_SetStreamFinishedCallback( PaStream *stream, PaStreamFinishedCallback* streamFinishedCallback ); /** Commences audio processing. */ PaError Pa_StartStream( PaStream *stream ); /** Terminates audio processing. It waits until all pending audio buffers have been played before it returns. */ PaError Pa_StopStream( PaStream *stream ); /** Terminates audio processing immediately without waiting for pending buffers to complete. */ PaError Pa_AbortStream( PaStream *stream ); /** Determine whether the stream is stopped. A stream is considered to be stopped prior to a successful call to Pa_StartStream and after a successful call to Pa_StopStream or Pa_AbortStream. If a stream callback returns a value other than paContinue the stream is NOT considered to be stopped. @return Returns one (1) when the stream is stopped, zero (0) when the stream is running or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive */ PaError Pa_IsStreamStopped( PaStream *stream ); /** Determine whether the stream is active. A stream is active after a successful call to Pa_StartStream(), until it becomes inactive either as a result of a call to Pa_StopStream() or Pa_AbortStream(), or as a result of a return value other than paContinue from the stream callback. In the latter case, the stream is considered inactive after the last buffer has finished playing. @return Returns one (1) when the stream is active (ie playing or recording audio), zero (0) when not playing or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamStopped */ PaError Pa_IsStreamActive( PaStream *stream ); /** A structure containing unchanging information about an open stream. @see Pa_GetStreamInfo */ typedef struct PaStreamInfo { /** this is struct version 1 */ int structVersion; /** The input latency of the stream in seconds. This value provides the most accurate estimate of input latency available to the implementation. It may differ significantly from the suggestedLatency value passed to Pa_OpenStream(). The value of this field will be zero (0.) for output-only streams. @see PaTime */ PaTime inputLatency; /** The output latency of the stream in seconds. This value provides the most accurate estimate of output latency available to the implementation. It may differ significantly from the suggestedLatency value passed to Pa_OpenStream(). The value of this field will be zero (0.) for input-only streams. @see PaTime */ PaTime outputLatency; /** The sample rate of the stream in Hertz (samples per second). In cases where the hardware sample rate is inaccurate and PortAudio is aware of it, the value of this field may be different from the sampleRate parameter passed to Pa_OpenStream(). If information about the actual hardware sample rate is not available, this field will have the same value as the sampleRate parameter passed to Pa_OpenStream(). */ double sampleRate; } PaStreamInfo; /** Retrieve a pointer to a PaStreamInfo structure containing information about the specified stream. @return A pointer to an immutable PaStreamInfo structure. If the stream parameter is invalid, or an error is encountered, the function returns NULL. @param stream A pointer to an open stream previously created with Pa_OpenStream. @note PortAudio manages the memory referenced by the returned pointer, the client must not manipulate or free the memory. The pointer is only guaranteed to be valid until the specified stream is closed. @see PaStreamInfo */ const PaStreamInfo* Pa_GetStreamInfo( PaStream *stream ); /** Returns the current time in seconds for a stream according to the same clock used to generate callback PaStreamCallbackTimeInfo timestamps. The time values are monotonically increasing and have unspecified origin. Pa_GetStreamTime returns valid time values for the entire life of the stream, from when the stream is opened until it is closed. Starting and stopping the stream does not affect the passage of time returned by Pa_GetStreamTime. This time may be used for synchronizing other events to the audio stream, for example synchronizing audio to MIDI. @return The stream's current time in seconds, or 0 if an error occurred. @see PaTime, PaStreamCallback, PaStreamCallbackTimeInfo */ PaTime Pa_GetStreamTime( PaStream *stream ); /** Retrieve CPU usage information for the specified stream. The "CPU Load" is a fraction of total CPU time consumed by a callback stream's audio processing routines including, but not limited to the client supplied stream callback. This function does not work with blocking read/write streams. This function may be called from the stream callback function or the application. @return A floating point value, typically between 0.0 and 1.0, where 1.0 indicates that the stream callback is consuming the maximum number of CPU cycles possible to maintain real-time operation. A value of 0.5 would imply that PortAudio and the stream callback was consuming roughly 50% of the available CPU time. The return value may exceed 1.0. A value of 0.0 will always be returned for a blocking read/write stream, or if an error occurs. */ double Pa_GetStreamCpuLoad( PaStream* stream ); /** Read samples from an input stream. The function doesn't return until the entire buffer has been filled - this may involve waiting for the operating system to supply the data. @param stream A pointer to an open stream previously created with Pa_OpenStream. @param buffer A pointer to a buffer of sample frames. The buffer contains samples in the format specified by the inputParameters->sampleFormat field used to open the stream, and the number of channels specified by inputParameters->numChannels. If non-interleaved samples were requested using the paNonInterleaved sample format flag, buffer is a pointer to the first element of an array of buffer pointers, one non-interleaved buffer for each channel. @param frames The number of frames to be read into buffer. This parameter is not constrained to a specific range, however high performance applications will want to match this parameter to the framesPerBuffer parameter used when opening the stream. @return On success PaNoError will be returned, or PaInputOverflowed if input data was discarded by PortAudio after the previous call and before this call. */ PaError Pa_ReadStream( PaStream* stream, void *buffer, unsigned long frames ); /** Write samples to an output stream. This function doesn't return until the entire buffer has been consumed - this may involve waiting for the operating system to consume the data. @param stream A pointer to an open stream previously created with Pa_OpenStream. @param buffer A pointer to a buffer of sample frames. The buffer contains samples in the format specified by the outputParameters->sampleFormat field used to open the stream, and the number of channels specified by outputParameters->numChannels. If non-interleaved samples were requested using the paNonInterleaved sample format flag, buffer is a pointer to the first element of an array of buffer pointers, one non-interleaved buffer for each channel. @param frames The number of frames to be written from buffer. This parameter is not constrained to a specific range, however high performance applications will want to match this parameter to the framesPerBuffer parameter used when opening the stream. @return On success PaNoError will be returned, or paOutputUnderflowed if additional output data was inserted after the previous call and before this call. */ PaError Pa_WriteStream( PaStream* stream, const void *buffer, unsigned long frames ); /** Retrieve the number of frames that can be read from the stream without waiting. @return Returns a non-negative value representing the maximum number of frames that can be read from the stream without blocking or busy waiting or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. */ signed long Pa_GetStreamReadAvailable( PaStream* stream ); /** Retrieve the number of frames that can be written to the stream without waiting. @return Returns a non-negative value representing the maximum number of frames that can be written to the stream without blocking or busy waiting or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. */ signed long Pa_GetStreamWriteAvailable( PaStream* stream ); /* Miscellaneous utilities */ /** Retrieve the size of a given sample format in bytes. @return The size in bytes of a single sample in the specified format, or paSampleFormatNotSupported if the format is not supported. */ PaError Pa_GetSampleSize( PaSampleFormat format ); /** Put the caller to sleep for at least 'msec' milliseconds. This function is provided only as a convenience for authors of portable code (such as the tests and examples in the PortAudio distribution.) The function may sleep longer than requested so don't rely on this for accurate musical timing. */ void Pa_Sleep( long msec ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PORTAUDIO_H */ praat-6.0.04/external/portaudio2007/000077500000000000000000000000001261542461700170615ustar00rootroot00000000000000praat-6.0.04/external/portaudio2007/Makefile000066400000000000000000000011361261542461700205220ustar00rootroot00000000000000# Makefile of the library "external/portaudio" # Paul Boersma, 14 January 2012 include ../../makefile.defs OBJECTS = pa_skeleton.o \ pa_unix_hostapis.o pa_unix_util.o pa_linux_alsa.o \ pa_win_hostapis.o pa_win_util.o pa_win_wmme.o pa_win_waveformat.o \ pa_front.o pa_debugprint.o pa_cpuload.o \ pa_allocation.o pa_process.o pa_converters.o pa_dither.o \ pa_stream.o .PHONY: all clean all: libportaudio.a clean: $(RM) $(OBJECTS) $(RM) libportaudio.a libportaudio.a: $(OBJECTS) touch libportaudio.a rm libportaudio.a ar cq libportaudio.a $(OBJECTS) $(RANLIB) libportaudio.a $(OBJECTS): *.h praat-6.0.04/external/portaudio2007/READ_ME.TXT000066400000000000000000000013361261542461700205610ustar00rootroot00000000000000Praats/external/portaudio/READ_ME.TXT Paul Boersma, 1 September 2013 This file describes the adaptations to the PortAudio v19 sources (2007/11) that are needed to make them compatible with Praat. Deleted lines in pa_***_hostapis.c. At the top of pa_win_*.c: #undef UNICODE In pa_win_mme.c, remove the #ifndef/endif from: #ifndef __MWERKS__ #include #include #endif /* __MWERKS__ */ In pa_mac_core.c: #include Duplicate pa_unix_util.c to pa_mac_util.c, but only for allocation and time routines. Remove the hard-coded definition of SIZEOF_LONG from pa_types.h and instead use to define PaInt32 and the like. Correct the associated error in pa_dither.c: SIZEOF_LONG -> sizeof(long).praat-6.0.04/external/portaudio2007/pa_allocation.c000066400000000000000000000154051261542461700220370ustar00rootroot00000000000000/* * $Id: pa_allocation.c 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library allocation group implementation * memory allocation group for tracking allocation groups * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Allocation Group implementation. */ #include "pa_allocation.h" #include "pa_util.h" /* Maintain 3 singly linked lists... linkBlocks: the buffers used to allocate the links spareLinks: links available for use in the allocations list allocations: the buffers currently allocated using PaUtil_ContextAllocateMemory() Link block size is doubled every time new links are allocated. */ #define PA_INITIAL_LINK_COUNT_ 16 struct PaUtilAllocationGroupLink { struct PaUtilAllocationGroupLink *next; void *buffer; }; /* Allocate a block of links. The first link will have it's buffer member pointing to the block, and it's next member set to . The remaining links will have NULL buffer members, and each link will point to the next link except the last, which will point to */ static struct PaUtilAllocationGroupLink *AllocateLinks( long count, struct PaUtilAllocationGroupLink *nextBlock, struct PaUtilAllocationGroupLink *nextSpare ) { struct PaUtilAllocationGroupLink *result; int i; result = (struct PaUtilAllocationGroupLink *)PaUtil_AllocateMemory( sizeof(struct PaUtilAllocationGroupLink) * count ); if( result ) { /* the block link */ result[0].buffer = result; result[0].next = nextBlock; /* the spare links */ for( i=1; ilinkCount = PA_INITIAL_LINK_COUNT_; result->linkBlocks = &links[0]; result->spareLinks = &links[1]; result->allocations = 0; } else { PaUtil_FreeMemory( links ); } } return result; } void PaUtil_DestroyAllocationGroup( PaUtilAllocationGroup* group ) { struct PaUtilAllocationGroupLink *current = group->linkBlocks; struct PaUtilAllocationGroupLink *next; while( current ) { next = current->next; PaUtil_FreeMemory( current->buffer ); current = next; } PaUtil_FreeMemory( group ); } void* PaUtil_GroupAllocateMemory( PaUtilAllocationGroup* group, long size ) { struct PaUtilAllocationGroupLink *links, *link; void *result = 0; /* allocate more links if necessary */ if( !group->spareLinks ) { /* double the link count on each block allocation */ links = AllocateLinks( group->linkCount, group->linkBlocks, group->spareLinks ); if( links ) { group->linkCount += group->linkCount; group->linkBlocks = &links[0]; group->spareLinks = &links[1]; } } if( group->spareLinks ) { result = PaUtil_AllocateMemory( size ); if( result ) { link = group->spareLinks; group->spareLinks = link->next; link->buffer = result; link->next = group->allocations; group->allocations = link; } } return result; } void PaUtil_GroupFreeMemory( PaUtilAllocationGroup* group, void *buffer ) { struct PaUtilAllocationGroupLink *current = group->allocations; struct PaUtilAllocationGroupLink *previous = 0; if( buffer == 0 ) return; /* find the right link and remove it */ while( current ) { if( current->buffer == buffer ) { if( previous ) { previous->next = current->next; } else { group->allocations = current->next; } current->buffer = 0; current->next = group->spareLinks; group->spareLinks = current; break; } previous = current; current = current->next; } PaUtil_FreeMemory( buffer ); /* free the memory whether we found it in the list or not */ } void PaUtil_FreeAllAllocations( PaUtilAllocationGroup* group ) { struct PaUtilAllocationGroupLink *current = group->allocations; struct PaUtilAllocationGroupLink *previous = 0; /* free all buffers in the allocations list */ while( current ) { PaUtil_FreeMemory( current->buffer ); current->buffer = 0; previous = current; current = current->next; } /* link the former allocations list onto the front of the spareLinks list */ if( previous ) { previous->next = group->spareLinks; group->spareLinks = group->allocations; group->allocations = 0; } } praat-6.0.04/external/portaudio2007/pa_allocation.h000066400000000000000000000074441261542461700220500ustar00rootroot00000000000000#ifndef PA_ALLOCATION_H #define PA_ALLOCATION_H /* * $Id: pa_allocation.h 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library allocation context header * memory allocation context for tracking allocation groups * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Allocation Group prototypes. An Allocation Group makes it easy to allocate multiple blocks of memory and free them all simultanously. An allocation group is useful for keeping track of multiple blocks of memory which are allocated at the same time (such as during initialization) and need to be deallocated at the same time. The allocation group maintains a list of allocated blocks, and can deallocate them all simultaneously which can be usefull for cleaning up after a partially initialized object fails. The allocation group implementation is built on top of the lower level allocation functions defined in pa_util.h */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ typedef struct { long linkCount; struct PaUtilAllocationGroupLink *linkBlocks; struct PaUtilAllocationGroupLink *spareLinks; struct PaUtilAllocationGroupLink *allocations; }PaUtilAllocationGroup; /** Create an allocation group. */ PaUtilAllocationGroup* PaUtil_CreateAllocationGroup( void ); /** Destroy an allocation group, but not the memory allocated through the group. */ void PaUtil_DestroyAllocationGroup( PaUtilAllocationGroup* group ); /** Allocate a block of memory though an allocation group. */ void* PaUtil_GroupAllocateMemory( PaUtilAllocationGroup* group, long size ); /** Free a block of memory that was previously allocated though an allocation group. Calling this function is a relatively time consuming operation. Under normal circumstances clients should call PaUtil_FreeAllAllocations to free all allocated blocks simultaneously. @see PaUtil_FreeAllAllocations */ void PaUtil_GroupFreeMemory( PaUtilAllocationGroup* group, void *buffer ); /** Free all blocks of memory which have been allocated through the allocation group. This function doesn't destroy the group itself. */ void PaUtil_FreeAllAllocations( PaUtilAllocationGroup* group ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_ALLOCATION_H */ praat-6.0.04/external/portaudio2007/pa_converters.c000066400000000000000000002036651261542461700221130ustar00rootroot00000000000000/* * $Id: pa_converters.c 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library sample conversion mechanism * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Phil Burk, Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Conversion functions implementations. If the C9x function lrintf() is available, define PA_USE_C99_LRINTF to use it @todo Consider whether functions which dither but don't clip should exist, V18 automatically enabled clipping whenever dithering was selected. Perhaps we should do the same. @todo implement the converters marked IMPLEMENT ME: Float32_To_UInt8_Dither, Float32_To_UInt8_Clip, Float32_To_UInt8_DitherClip, Int32_To_Int24_Dither, Int32_To_UInt8_Dither, Int24_To_Int16_Dither, Int24_To_Int8_Dither, Int24_To_UInt8_Dither, Int16_To_Int8_Dither, Int16_To_UInt8_Dither, @todo review the converters marked REVIEW: Float32_To_Int32, Float32_To_Int32_Dither, Float32_To_Int32_Clip, Float32_To_Int32_DitherClip, Int32_To_Int16_Dither, Int32_To_Int8_Dither, Int16_To_Int32 */ #include "pa_converters.h" #include "pa_dither.h" #include "pa_endianness.h" #include "pa_types.h" PaSampleFormat PaUtil_SelectClosestAvailableFormat( PaSampleFormat availableFormats, PaSampleFormat format ) { PaSampleFormat result; format &= ~paNonInterleaved; availableFormats &= ~paNonInterleaved; if( (format & availableFormats) == 0 ) { /* NOTE: this code depends on the sample format constants being in descending order of quality - ie best quality is 0 FIXME: should write an assert which checks that all of the known constants conform to that requirement. */ if( format != 0x01 ) { /* scan for better formats */ result = format; do { result >>= 1; } while( (result & availableFormats) == 0 && result != 0 ); } else { result = 0; } if( result == 0 ){ /* scan for worse formats */ result = format; do { result <<= 1; } while( (result & availableFormats) == 0 && result != paCustomFormat ); if( (result & availableFormats) == 0 ) result = paSampleFormatNotSupported; } }else{ result = format; } return result; } /* -------------------------------------------------------------------------- */ #define PA_SELECT_FORMAT_( format, float32, int32, int24, int16, int8, uint8 ) \ switch( format & ~paNonInterleaved ){ \ case paFloat32: \ float32 \ case paInt32: \ int32 \ case paInt24: \ int24 \ case paInt16: \ int16 \ case paInt8: \ int8 \ case paUInt8: \ uint8 \ default: return 0; \ } /* -------------------------------------------------------------------------- */ #define PA_SELECT_CONVERTER_DITHER_CLIP_( flags, source, destination ) \ if( flags & paClipOff ){ /* no clip */ \ if( flags & paDitherOff ){ /* no dither */ \ return paConverters. source ## _To_ ## destination; \ }else{ /* dither */ \ return paConverters. source ## _To_ ## destination ## _Dither; \ } \ }else{ /* clip */ \ if( flags & paDitherOff ){ /* no dither */ \ return paConverters. source ## _To_ ## destination ## _Clip; \ }else{ /* dither */ \ return paConverters. source ## _To_ ## destination ## _DitherClip; \ } \ } /* -------------------------------------------------------------------------- */ #define PA_SELECT_CONVERTER_DITHER_( flags, source, destination ) \ if( flags & paDitherOff ){ /* no dither */ \ return paConverters. source ## _To_ ## destination; \ }else{ /* dither */ \ return paConverters. source ## _To_ ## destination ## _Dither; \ } /* -------------------------------------------------------------------------- */ #define PA_USE_CONVERTER_( source, destination )\ return paConverters. source ## _To_ ## destination; /* -------------------------------------------------------------------------- */ #define PA_UNITY_CONVERSION_( wordlength )\ return paConverters. Copy_ ## wordlength ## _To_ ## wordlength; /* -------------------------------------------------------------------------- */ PaUtilConverter* PaUtil_SelectConverter( PaSampleFormat sourceFormat, PaSampleFormat destinationFormat, PaStreamFlags flags ) { PA_SELECT_FORMAT_( sourceFormat, /* paFloat32: */ PA_SELECT_FORMAT_( destinationFormat, /* paFloat32: */ PA_UNITY_CONVERSION_( 32 ), /* paInt32: */ PA_SELECT_CONVERTER_DITHER_CLIP_( flags, Float32, Int32 ), /* paInt24: */ PA_SELECT_CONVERTER_DITHER_CLIP_( flags, Float32, Int24 ), /* paInt16: */ PA_SELECT_CONVERTER_DITHER_CLIP_( flags, Float32, Int16 ), /* paInt8: */ PA_SELECT_CONVERTER_DITHER_CLIP_( flags, Float32, Int8 ), /* paUInt8: */ PA_SELECT_CONVERTER_DITHER_CLIP_( flags, Float32, UInt8 ) ), /* paInt32: */ PA_SELECT_FORMAT_( destinationFormat, /* paFloat32: */ PA_USE_CONVERTER_( Int32, Float32 ), /* paInt32: */ PA_UNITY_CONVERSION_( 32 ), /* paInt24: */ PA_SELECT_CONVERTER_DITHER_( flags, Int32, Int24 ), /* paInt16: */ PA_SELECT_CONVERTER_DITHER_( flags, Int32, Int16 ), /* paInt8: */ PA_SELECT_CONVERTER_DITHER_( flags, Int32, Int8 ), /* paUInt8: */ PA_SELECT_CONVERTER_DITHER_( flags, Int32, UInt8 ) ), /* paInt24: */ PA_SELECT_FORMAT_( destinationFormat, /* paFloat32: */ PA_USE_CONVERTER_( Int24, Float32 ), /* paInt32: */ PA_USE_CONVERTER_( Int24, Int32 ), /* paInt24: */ PA_UNITY_CONVERSION_( 24 ), /* paInt16: */ PA_SELECT_CONVERTER_DITHER_( flags, Int24, Int16 ), /* paInt8: */ PA_SELECT_CONVERTER_DITHER_( flags, Int24, Int8 ), /* paUInt8: */ PA_SELECT_CONVERTER_DITHER_( flags, Int24, UInt8 ) ), /* paInt16: */ PA_SELECT_FORMAT_( destinationFormat, /* paFloat32: */ PA_USE_CONVERTER_( Int16, Float32 ), /* paInt32: */ PA_USE_CONVERTER_( Int16, Int32 ), /* paInt24: */ PA_USE_CONVERTER_( Int16, Int24 ), /* paInt16: */ PA_UNITY_CONVERSION_( 16 ), /* paInt8: */ PA_SELECT_CONVERTER_DITHER_( flags, Int16, Int8 ), /* paUInt8: */ PA_SELECT_CONVERTER_DITHER_( flags, Int16, UInt8 ) ), /* paInt8: */ PA_SELECT_FORMAT_( destinationFormat, /* paFloat32: */ PA_USE_CONVERTER_( Int8, Float32 ), /* paInt32: */ PA_USE_CONVERTER_( Int8, Int32 ), /* paInt24: */ PA_USE_CONVERTER_( Int8, Int24 ), /* paInt16: */ PA_USE_CONVERTER_( Int8, Int16 ), /* paInt8: */ PA_UNITY_CONVERSION_( 8 ), /* paUInt8: */ PA_USE_CONVERTER_( Int8, UInt8 ) ), /* paUInt8: */ PA_SELECT_FORMAT_( destinationFormat, /* paFloat32: */ PA_USE_CONVERTER_( UInt8, Float32 ), /* paInt32: */ PA_USE_CONVERTER_( UInt8, Int32 ), /* paInt24: */ PA_USE_CONVERTER_( UInt8, Int24 ), /* paInt16: */ PA_USE_CONVERTER_( UInt8, Int16 ), /* paInt8: */ PA_USE_CONVERTER_( UInt8, Int8 ), /* paUInt8: */ PA_UNITY_CONVERSION_( 8 ) ) ) } /* -------------------------------------------------------------------------- */ #ifdef PA_NO_STANDARD_CONVERTERS /* -------------------------------------------------------------------------- */ PaUtilConverterTable paConverters = { 0, /* PaUtilConverter *Float32_To_Int32; */ 0, /* PaUtilConverter *Float32_To_Int32_Dither; */ 0, /* PaUtilConverter *Float32_To_Int32_Clip; */ 0, /* PaUtilConverter *Float32_To_Int32_DitherClip; */ 0, /* PaUtilConverter *Float32_To_Int24; */ 0, /* PaUtilConverter *Float32_To_Int24_Dither; */ 0, /* PaUtilConverter *Float32_To_Int24_Clip; */ 0, /* PaUtilConverter *Float32_To_Int24_DitherClip; */ 0, /* PaUtilConverter *Float32_To_Int16; */ 0, /* PaUtilConverter *Float32_To_Int16_Dither; */ 0, /* PaUtilConverter *Float32_To_Int16_Clip; */ 0, /* PaUtilConverter *Float32_To_Int16_DitherClip; */ 0, /* PaUtilConverter *Float32_To_Int8; */ 0, /* PaUtilConverter *Float32_To_Int8_Dither; */ 0, /* PaUtilConverter *Float32_To_Int8_Clip; */ 0, /* PaUtilConverter *Float32_To_Int8_DitherClip; */ 0, /* PaUtilConverter *Float32_To_UInt8; */ 0, /* PaUtilConverter *Float32_To_UInt8_Dither; */ 0, /* PaUtilConverter *Float32_To_UInt8_Clip; */ 0, /* PaUtilConverter *Float32_To_UInt8_DitherClip; */ 0, /* PaUtilConverter *Int32_To_Float32; */ 0, /* PaUtilConverter *Int32_To_Int24; */ 0, /* PaUtilConverter *Int32_To_Int24_Dither; */ 0, /* PaUtilConverter *Int32_To_Int16; */ 0, /* PaUtilConverter *Int32_To_Int16_Dither; */ 0, /* PaUtilConverter *Int32_To_Int8; */ 0, /* PaUtilConverter *Int32_To_Int8_Dither; */ 0, /* PaUtilConverter *Int32_To_UInt8; */ 0, /* PaUtilConverter *Int32_To_UInt8_Dither; */ 0, /* PaUtilConverter *Int24_To_Float32; */ 0, /* PaUtilConverter *Int24_To_Int32; */ 0, /* PaUtilConverter *Int24_To_Int16; */ 0, /* PaUtilConverter *Int24_To_Int16_Dither; */ 0, /* PaUtilConverter *Int24_To_Int8; */ 0, /* PaUtilConverter *Int24_To_Int8_Dither; */ 0, /* PaUtilConverter *Int24_To_UInt8; */ 0, /* PaUtilConverter *Int24_To_UInt8_Dither; */ 0, /* PaUtilConverter *Int16_To_Float32; */ 0, /* PaUtilConverter *Int16_To_Int32; */ 0, /* PaUtilConverter *Int16_To_Int24; */ 0, /* PaUtilConverter *Int16_To_Int8; */ 0, /* PaUtilConverter *Int16_To_Int8_Dither; */ 0, /* PaUtilConverter *Int16_To_UInt8; */ 0, /* PaUtilConverter *Int16_To_UInt8_Dither; */ 0, /* PaUtilConverter *Int8_To_Float32; */ 0, /* PaUtilConverter *Int8_To_Int32; */ 0, /* PaUtilConverter *Int8_To_Int24 */ 0, /* PaUtilConverter *Int8_To_Int16; */ 0, /* PaUtilConverter *Int8_To_UInt8; */ 0, /* PaUtilConverter *UInt8_To_Float32; */ 0, /* PaUtilConverter *UInt8_To_Int32; */ 0, /* PaUtilConverter *UInt8_To_Int24; */ 0, /* PaUtilConverter *UInt8_To_Int16; */ 0, /* PaUtilConverter *UInt8_To_Int8; */ 0, /* PaUtilConverter *Copy_8_To_8; */ 0, /* PaUtilConverter *Copy_16_To_16; */ 0, /* PaUtilConverter *Copy_24_To_24; */ 0 /* PaUtilConverter *Copy_32_To_32; */ }; /* -------------------------------------------------------------------------- */ #else /* PA_NO_STANDARD_CONVERTERS is not defined */ /* -------------------------------------------------------------------------- */ #define PA_CLIP_( val, min, max )\ { val = ((val) < (min)) ? (min) : (((val) > (max)) ? (max) : (val)); } static const float const_1_div_128_ = 1.0f / 128.0f; /* 8 bit multiplier */ static const float const_1_div_32768_ = 1.0f / 32768.f; /* 16 bit multiplier */ static const double const_1_div_2147483648_ = 1.0 / 2147483648.0; /* 32 bit multiplier */ /* -------------------------------------------------------------------------- */ static void Float32_To_Int32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; PaInt32 *dest = (PaInt32*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { /* REVIEW */ #ifdef PA_USE_C99_LRINTF float scaled = *src * 0x7FFFFFFF; *dest = lrintf(scaled-0.5f); #else double scaled = *src * 0x7FFFFFFF; *dest = (PaInt32) scaled; #endif src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int32_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; PaInt32 *dest = (PaInt32*)destinationBuffer; while( count-- ) { /* REVIEW */ #ifdef PA_USE_C99_LRINTF float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ float dithered = ((float)*src * (2147483646.0f)) + dither; *dest = lrintf(dithered - 0.5f); #else double dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ double dithered = ((double)*src * (2147483646.0)) + dither; *dest = (PaInt32) dithered; #endif src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int32_Clip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; PaInt32 *dest = (PaInt32*)destinationBuffer; (void) ditherGenerator; /* unused parameter */ while( count-- ) { /* REVIEW */ #ifdef PA_USE_C99_LRINTF float scaled = *src * 0x7FFFFFFF; PA_CLIP_( scaled, -2147483648.f, 2147483647.f ); *dest = lrintf(scaled-0.5f); #else double scaled = *src * 0x7FFFFFFF; PA_CLIP_( scaled, -2147483648., 2147483647. ); *dest = (PaInt32) scaled; #endif src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int32_DitherClip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; PaInt32 *dest = (PaInt32*)destinationBuffer; while( count-- ) { /* REVIEW */ #ifdef PA_USE_C99_LRINTF float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ float dithered = ((float)*src * (2147483646.0f)) + dither; PA_CLIP_( dithered, -2147483648.f, 2147483647.f ); *dest = lrintf(dithered-0.5f); #else double dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ double dithered = ((double)*src * (2147483646.0)) + dither; PA_CLIP_( dithered, -2147483648., 2147483647. ); *dest = (PaInt32) dithered; #endif src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int24( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; PaInt32 temp; (void) ditherGenerator; /* unused parameter */ while( count-- ) { /* convert to 32 bit and drop the low 8 bits */ double scaled = *src * 0x7FFFFFFF; temp = (PaInt32) scaled; #if defined(PA_LITTLE_ENDIAN) dest[0] = (unsigned char)(temp >> 8); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 24); #elif defined(PA_BIG_ENDIAN) dest[0] = (unsigned char)(temp >> 24); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 8); #endif src += sourceStride; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int24_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; PaInt32 temp; while( count-- ) { /* convert to 32 bit and drop the low 8 bits */ double dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ double dithered = ((double)*src * (2147483646.0)) + dither; temp = (PaInt32) dithered; #if defined(PA_LITTLE_ENDIAN) dest[0] = (unsigned char)(temp >> 8); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 24); #elif defined(PA_BIG_ENDIAN) dest[0] = (unsigned char)(temp >> 24); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 8); #endif src += sourceStride; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int24_Clip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; PaInt32 temp; (void) ditherGenerator; /* unused parameter */ while( count-- ) { /* convert to 32 bit and drop the low 8 bits */ double scaled = *src * 0x7FFFFFFF; PA_CLIP_( scaled, -2147483648., 2147483647. ); temp = (PaInt32) scaled; #if defined(PA_LITTLE_ENDIAN) dest[0] = (unsigned char)(temp >> 8); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 24); #elif defined(PA_BIG_ENDIAN) dest[0] = (unsigned char)(temp >> 24); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 8); #endif src += sourceStride; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int24_DitherClip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; PaInt32 temp; while( count-- ) { /* convert to 32 bit and drop the low 8 bits */ double dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ double dithered = ((double)*src * (2147483646.0)) + dither; PA_CLIP_( dithered, -2147483648., 2147483647. ); temp = (PaInt32) dithered; #if defined(PA_LITTLE_ENDIAN) dest[0] = (unsigned char)(temp >> 8); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 24); #elif defined(PA_BIG_ENDIAN) dest[0] = (unsigned char)(temp >> 24); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 8); #endif src += sourceStride; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int16( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { #ifdef PA_USE_C99_LRINTF float tempf = (*src * (32767.0f)) ; *dest = lrintf(tempf-0.5f); #else short samp = (short) (*src * (32767.0f)); *dest = samp; #endif src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int16_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; while( count-- ) { float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ float dithered = (*src * (32766.0f)) + dither; #ifdef PA_USE_C99_LRINTF *dest = lrintf(dithered-0.5f); #else *dest = (PaInt16) dithered; #endif src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int16_Clip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { #ifdef PA_USE_C99_LRINTF long samp = lrintf((*src * (32767.0f)) -0.5f); #else long samp = (PaInt32) (*src * (32767.0f)); #endif PA_CLIP_( samp, -0x8000, 0x7FFF ); *dest = (PaInt16) samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int16_DitherClip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ float dithered = (*src * (32766.0f)) + dither; PaInt32 samp = (PaInt32) dithered; PA_CLIP_( samp, -0x8000, 0x7FFF ); #ifdef PA_USE_C99_LRINTF *dest = lrintf(samp-0.5f); #else *dest = (PaInt16) samp; #endif src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { signed char samp = (signed char) (*src * (127.0f)); *dest = samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int8_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ float dithered = (*src * (126.0f)) + dither; PaInt32 samp = (PaInt32) dithered; *dest = (signed char) samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int8_Clip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { PaInt32 samp = (PaInt32)(*src * (127.0f)); PA_CLIP_( samp, -0x80, 0x7F ); *dest = (signed char) samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int8_DitherClip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ float dithered = (*src * (126.0f)) + dither; PaInt32 samp = (PaInt32) dithered; PA_CLIP_( samp, -0x80, 0x7F ); *dest = (signed char) samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_UInt8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { unsigned char samp = (unsigned char)(128 + ((unsigned char) (*src * (127.0f)))); *dest = samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_UInt8_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { /* IMPLEMENT ME */ src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_UInt8_Clip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { /* IMPLEMENT ME */ src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_UInt8_DitherClip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { /* IMPLEMENT ME */ src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int32_To_Float32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt32 *src = (PaInt32*)sourceBuffer; float *dest = (float*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { *dest = (float) ((double)*src * const_1_div_2147483648_); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int32_To_Int24( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt32 *src = (PaInt32*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void) ditherGenerator; /* unused parameter */ while( count-- ) { /* REVIEW */ #if defined(PA_LITTLE_ENDIAN) dest[0] = (unsigned char)(*src >> 8); dest[1] = (unsigned char)(*src >> 16); dest[2] = (unsigned char)(*src >> 24); #elif defined(PA_BIG_ENDIAN) dest[0] = (unsigned char)(*src >> 24); dest[1] = (unsigned char)(*src >> 16); dest[2] = (unsigned char)(*src >> 8); #endif src += sourceStride; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Int32_To_Int24_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { (void) destinationBuffer; /* unused parameters */ (void) destinationStride; /* unused parameters */ (void) sourceBuffer; /* unused parameters */ (void) sourceStride; /* unused parameters */ (void) count; /* unused parameters */ (void) ditherGenerator; /* unused parameters */ /* IMPLEMENT ME */ } /* -------------------------------------------------------------------------- */ static void Int32_To_Int16( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt32 *src = (PaInt32*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { *dest = (PaInt16) ((*src) >> 16); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int32_To_Int16_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt32 *src = (PaInt32*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; PaInt32 dither; while( count-- ) { /* REVIEW */ dither = PaUtil_Generate16BitTriangularDither( ditherGenerator ); *dest = (PaInt16) ((((*src)>>1) + dither) >> 15); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int32_To_Int8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt32 *src = (PaInt32*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { *dest = (signed char) ((*src) >> 24); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int32_To_Int8_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt32 *src = (PaInt32*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; PaInt32 dither; while( count-- ) { /* REVIEW */ dither = PaUtil_Generate16BitTriangularDither( ditherGenerator ); *dest = (signed char) ((((*src)>>1) + dither) >> 23); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int32_To_UInt8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt32 *src = (PaInt32*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (unsigned char)(((*src) >> 24) + 128); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int32_To_UInt8_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt32 *src = (PaInt32*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { /* IMPLEMENT ME */ src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int24_To_Float32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; float *dest = (float*)destinationBuffer; PaInt32 temp; (void) ditherGenerator; /* unused parameter */ while( count-- ) { #if defined(PA_LITTLE_ENDIAN) temp = (((long)src[0]) << 8); temp = temp | (((long)src[1]) << 16); temp = temp | (((long)src[2]) << 24); #elif defined(PA_BIG_ENDIAN) temp = (((long)src[0]) << 24); temp = temp | (((long)src[1]) << 16); temp = temp | (((long)src[2]) << 8); #endif *dest = (float) ((double)temp * const_1_div_2147483648_); src += sourceStride * 3; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int24_To_Int32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; PaInt32 *dest = (PaInt32*) destinationBuffer; PaInt32 temp; (void) ditherGenerator; /* unused parameter */ while( count-- ) { #if defined(PA_LITTLE_ENDIAN) temp = (((long)src[0]) << 8); temp = temp | (((long)src[1]) << 16); temp = temp | (((long)src[2]) << 24); #elif defined(PA_BIG_ENDIAN) temp = (((long)src[0]) << 24); temp = temp | (((long)src[1]) << 16); temp = temp | (((long)src[2]) << 8); #endif *dest = temp; src += sourceStride * 3; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int24_To_Int16( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; PaInt16 temp; (void) ditherGenerator; /* unused parameter */ while( count-- ) { #if defined(PA_LITTLE_ENDIAN) /* src[0] is discarded */ temp = (((PaInt16)src[1])); temp = temp | (PaInt16)(((PaInt16)src[2]) << 8); #elif defined(PA_BIG_ENDIAN) /* src[2] is discarded */ temp = (PaInt16)(((PaInt16)src[0]) << 8); temp = temp | (((PaInt16)src[1])); #endif *dest = temp; src += sourceStride * 3; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int24_To_Int16_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { (void) destinationBuffer; /* unused parameters */ (void) destinationStride; /* unused parameters */ (void) sourceBuffer; /* unused parameters */ (void) sourceStride; /* unused parameters */ (void) count; /* unused parameters */ (void) ditherGenerator; /* unused parameters */ /* IMPLEMENT ME */ } /* -------------------------------------------------------------------------- */ static void Int24_To_Int8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; (void) ditherGenerator; /* unused parameter */ while( count-- ) { #if defined(PA_LITTLE_ENDIAN) /* src[0] is discarded */ /* src[1] is discarded */ *dest = src[2]; #elif defined(PA_BIG_ENDIAN) /* src[2] is discarded */ /* src[1] is discarded */ *dest = src[0]; #endif src += sourceStride * 3; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int24_To_Int8_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { (void) destinationBuffer; /* unused parameters */ (void) destinationStride; /* unused parameters */ (void) sourceBuffer; /* unused parameters */ (void) sourceStride; /* unused parameters */ (void) count; /* unused parameters */ (void) ditherGenerator; /* unused parameters */ /* IMPLEMENT ME */ } /* -------------------------------------------------------------------------- */ static void Int24_To_UInt8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void) ditherGenerator; /* unused parameter */ while( count-- ) { #if defined(PA_LITTLE_ENDIAN) /* src[0] is discarded */ /* src[1] is discarded */ *dest = (unsigned char)(src[2] + 128); #elif defined(PA_BIG_ENDIAN) *dest = (unsigned char)(src[0] + 128); /* src[1] is discarded */ /* src[2] is discarded */ #endif src += sourceStride * 3; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int24_To_UInt8_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { (void) destinationBuffer; /* unused parameters */ (void) destinationStride; /* unused parameters */ (void) sourceBuffer; /* unused parameters */ (void) sourceStride; /* unused parameters */ (void) count; /* unused parameters */ (void) ditherGenerator; /* unused parameters */ /* IMPLEMENT ME */ } /* -------------------------------------------------------------------------- */ static void Int16_To_Float32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt16 *src = (PaInt16*)sourceBuffer; float *dest = (float*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { float samp = *src * const_1_div_32768_; /* FIXME: i'm concerned about this being asymetrical with float->int16 -rb */ *dest = samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int16_To_Int32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt16 *src = (PaInt16*)sourceBuffer; PaInt32 *dest = (PaInt32*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { /* REVIEW: we should consider something like (*src << 16) | (*src & 0xFFFF) */ *dest = *src << 16; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int16_To_Int24( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt16 *src = (PaInt16*) sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; PaInt16 temp; (void) ditherGenerator; /* unused parameter */ while( count-- ) { temp = *src; #if defined(PA_LITTLE_ENDIAN) dest[0] = 0; dest[1] = (unsigned char)(temp); dest[2] = (unsigned char)(temp >> 8); #elif defined(PA_BIG_ENDIAN) dest[0] = (unsigned char)(temp >> 8); dest[1] = (unsigned char)(temp); dest[2] = 0; #endif src += sourceStride; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Int16_To_Int8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt16 *src = (PaInt16*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (signed char)((*src) >> 8); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int16_To_Int8_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt16 *src = (PaInt16*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { /* IMPLEMENT ME */ src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int16_To_UInt8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt16 *src = (PaInt16*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (unsigned char)(((*src) >> 8) + 128); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int16_To_UInt8_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt16 *src = (PaInt16*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { /* IMPLEMENT ME */ src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int8_To_Float32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { signed char *src = (signed char*)sourceBuffer; float *dest = (float*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { float samp = *src * const_1_div_128_; *dest = samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int8_To_Int32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { signed char *src = (signed char*)sourceBuffer; PaInt32 *dest = (PaInt32*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (*src) << 24; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int8_To_Int24( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { signed char *src = (signed char*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { #if defined(PA_LITTLE_ENDIAN) dest[0] = 0; dest[1] = 0; dest[2] = (*src); #elif defined(PA_BIG_ENDIAN) dest[0] = (*src); dest[1] = 0; dest[2] = 0; #endif src += sourceStride; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Int8_To_Int16( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { signed char *src = (signed char*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (PaInt16)((*src) << 8); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int8_To_UInt8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { signed char *src = (signed char*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (unsigned char)(*src + 128); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void UInt8_To_Float32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; float *dest = (float*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { float samp = (*src - 128) * const_1_div_128_; *dest = samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void UInt8_To_Int32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; PaInt32 *dest = (PaInt32*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (*src - 128) << 24; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void UInt8_To_Int24( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void) ditherGenerator; /* unused parameters */ while( count-- ) { #if defined(PA_LITTLE_ENDIAN) dest[0] = 0; dest[1] = 0; dest[2] = (unsigned char)(*src - 128); #elif defined(PA_BIG_ENDIAN) dest[0] = (unsigned char)(*src - 128); dest[1] = 0; dest[2] = 0; #endif src += sourceStride; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void UInt8_To_Int16( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (PaInt16)((*src - 128) << 8); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void UInt8_To_Int8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (signed char)(*src - 128); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Copy_8_To_8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void) ditherGenerator; /* unused parameter */ while( count-- ) { *dest = *src; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Copy_16_To_16( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaUint16 *src = (PaUint16 *)sourceBuffer; PaUint16 *dest = (PaUint16 *)destinationBuffer; (void) ditherGenerator; /* unused parameter */ while( count-- ) { *dest = *src; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Copy_24_To_24( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void) ditherGenerator; /* unused parameter */ while( count-- ) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; src += sourceStride * 3; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Copy_32_To_32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaUint32 *dest = (PaUint32 *)destinationBuffer; PaUint32 *src = (PaUint32 *)sourceBuffer; (void) ditherGenerator; /* unused parameter */ while( count-- ) { *dest = *src; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ PaUtilConverterTable paConverters = { Float32_To_Int32, /* PaUtilConverter *Float32_To_Int32; */ Float32_To_Int32_Dither, /* PaUtilConverter *Float32_To_Int32_Dither; */ Float32_To_Int32_Clip, /* PaUtilConverter *Float32_To_Int32_Clip; */ Float32_To_Int32_DitherClip, /* PaUtilConverter *Float32_To_Int32_DitherClip; */ Float32_To_Int24, /* PaUtilConverter *Float32_To_Int24; */ Float32_To_Int24_Dither, /* PaUtilConverter *Float32_To_Int24_Dither; */ Float32_To_Int24_Clip, /* PaUtilConverter *Float32_To_Int24_Clip; */ Float32_To_Int24_DitherClip, /* PaUtilConverter *Float32_To_Int24_DitherClip; */ Float32_To_Int16, /* PaUtilConverter *Float32_To_Int16; */ Float32_To_Int16_Dither, /* PaUtilConverter *Float32_To_Int16_Dither; */ Float32_To_Int16_Clip, /* PaUtilConverter *Float32_To_Int16_Clip; */ Float32_To_Int16_DitherClip, /* PaUtilConverter *Float32_To_Int16_DitherClip; */ Float32_To_Int8, /* PaUtilConverter *Float32_To_Int8; */ Float32_To_Int8_Dither, /* PaUtilConverter *Float32_To_Int8_Dither; */ Float32_To_Int8_Clip, /* PaUtilConverter *Float32_To_Int8_Clip; */ Float32_To_Int8_DitherClip, /* PaUtilConverter *Float32_To_Int8_DitherClip; */ Float32_To_UInt8, /* PaUtilConverter *Float32_To_UInt8; */ Float32_To_UInt8_Dither, /* PaUtilConverter *Float32_To_UInt8_Dither; */ Float32_To_UInt8_Clip, /* PaUtilConverter *Float32_To_UInt8_Clip; */ Float32_To_UInt8_DitherClip, /* PaUtilConverter *Float32_To_UInt8_DitherClip; */ Int32_To_Float32, /* PaUtilConverter *Int32_To_Float32; */ Int32_To_Int24, /* PaUtilConverter *Int32_To_Int24; */ Int32_To_Int24_Dither, /* PaUtilConverter *Int32_To_Int24_Dither; */ Int32_To_Int16, /* PaUtilConverter *Int32_To_Int16; */ Int32_To_Int16_Dither, /* PaUtilConverter *Int32_To_Int16_Dither; */ Int32_To_Int8, /* PaUtilConverter *Int32_To_Int8; */ Int32_To_Int8_Dither, /* PaUtilConverter *Int32_To_Int8_Dither; */ Int32_To_UInt8, /* PaUtilConverter *Int32_To_UInt8; */ Int32_To_UInt8_Dither, /* PaUtilConverter *Int32_To_UInt8_Dither; */ Int24_To_Float32, /* PaUtilConverter *Int24_To_Float32; */ Int24_To_Int32, /* PaUtilConverter *Int24_To_Int32; */ Int24_To_Int16, /* PaUtilConverter *Int24_To_Int16; */ Int24_To_Int16_Dither, /* PaUtilConverter *Int24_To_Int16_Dither; */ Int24_To_Int8, /* PaUtilConverter *Int24_To_Int8; */ Int24_To_Int8_Dither, /* PaUtilConverter *Int24_To_Int8_Dither; */ Int24_To_UInt8, /* PaUtilConverter *Int24_To_UInt8; */ Int24_To_UInt8_Dither, /* PaUtilConverter *Int24_To_UInt8_Dither; */ Int16_To_Float32, /* PaUtilConverter *Int16_To_Float32; */ Int16_To_Int32, /* PaUtilConverter *Int16_To_Int32; */ Int16_To_Int24, /* PaUtilConverter *Int16_To_Int24; */ Int16_To_Int8, /* PaUtilConverter *Int16_To_Int8; */ Int16_To_Int8_Dither, /* PaUtilConverter *Int16_To_Int8_Dither; */ Int16_To_UInt8, /* PaUtilConverter *Int16_To_UInt8; */ Int16_To_UInt8_Dither, /* PaUtilConverter *Int16_To_UInt8_Dither; */ Int8_To_Float32, /* PaUtilConverter *Int8_To_Float32; */ Int8_To_Int32, /* PaUtilConverter *Int8_To_Int32; */ Int8_To_Int24, /* PaUtilConverter *Int8_To_Int24 */ Int8_To_Int16, /* PaUtilConverter *Int8_To_Int16; */ Int8_To_UInt8, /* PaUtilConverter *Int8_To_UInt8; */ UInt8_To_Float32, /* PaUtilConverter *UInt8_To_Float32; */ UInt8_To_Int32, /* PaUtilConverter *UInt8_To_Int32; */ UInt8_To_Int24, /* PaUtilConverter *UInt8_To_Int24; */ UInt8_To_Int16, /* PaUtilConverter *UInt8_To_Int16; */ UInt8_To_Int8, /* PaUtilConverter *UInt8_To_Int8; */ Copy_8_To_8, /* PaUtilConverter *Copy_8_To_8; */ Copy_16_To_16, /* PaUtilConverter *Copy_16_To_16; */ Copy_24_To_24, /* PaUtilConverter *Copy_24_To_24; */ Copy_32_To_32 /* PaUtilConverter *Copy_32_To_32; */ }; /* -------------------------------------------------------------------------- */ #endif /* PA_NO_STANDARD_CONVERTERS */ /* -------------------------------------------------------------------------- */ PaUtilZeroer* PaUtil_SelectZeroer( PaSampleFormat destinationFormat ) { switch( destinationFormat & ~paNonInterleaved ){ case paFloat32: return paZeroers.Zero32; case paInt32: return paZeroers.Zero32; case paInt24: return paZeroers.Zero24; case paInt16: return paZeroers.Zero16; case paInt8: return paZeroers.Zero8; case paUInt8: return paZeroers.ZeroU8; default: return 0; } } /* -------------------------------------------------------------------------- */ #ifdef PA_NO_STANDARD_ZEROERS /* -------------------------------------------------------------------------- */ PaUtilZeroerTable paZeroers = { 0, /* PaUtilZeroer *ZeroU8; */ 0, /* PaUtilZeroer *Zero8; */ 0, /* PaUtilZeroer *Zero16; */ 0, /* PaUtilZeroer *Zero24; */ 0, /* PaUtilZeroer *Zero32; */ }; /* -------------------------------------------------------------------------- */ #else /* PA_NO_STANDARD_ZEROERS is not defined */ /* -------------------------------------------------------------------------- */ static void ZeroU8( void *destinationBuffer, signed int destinationStride, unsigned int count ) { unsigned char *dest = (unsigned char*)destinationBuffer; while( count-- ) { *dest = 128; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Zero8( void *destinationBuffer, signed int destinationStride, unsigned int count ) { unsigned char *dest = (unsigned char*)destinationBuffer; while( count-- ) { *dest = 0; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Zero16( void *destinationBuffer, signed int destinationStride, unsigned int count ) { PaUint16 *dest = (PaUint16 *)destinationBuffer; while( count-- ) { *dest = 0; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Zero24( void *destinationBuffer, signed int destinationStride, unsigned int count ) { unsigned char *dest = (unsigned char*)destinationBuffer; while( count-- ) { dest[0] = 0; dest[1] = 0; dest[2] = 0; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Zero32( void *destinationBuffer, signed int destinationStride, unsigned int count ) { PaUint32 *dest = (PaUint32 *)destinationBuffer; while( count-- ) { *dest = 0; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ PaUtilZeroerTable paZeroers = { ZeroU8, /* PaUtilZeroer *ZeroU8; */ Zero8, /* PaUtilZeroer *Zero8; */ Zero16, /* PaUtilZeroer *Zero16; */ Zero24, /* PaUtilZeroer *Zero24; */ Zero32, /* PaUtilZeroer *Zero32; */ }; /* -------------------------------------------------------------------------- */ #endif /* PA_NO_STANDARD_ZEROERS */ praat-6.0.04/external/portaudio2007/pa_converters.h000066400000000000000000000237601261542461700221140ustar00rootroot00000000000000#ifndef PA_CONVERTERS_H #define PA_CONVERTERS_H /* * $Id: pa_converters.h 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library sample conversion mechanism * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Phil Burk, Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Conversion functions used to convert buffers of samples from one format to another. */ #include "portaudio.h" /* for PaSampleFormat */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ struct PaUtilTriangularDitherGenerator; /** Choose an available sample format which is most appropriate for representing the requested format. If the requested format is not available higher quality formats are considered before lower quality formates. @param availableFormats A variable containing the logical OR of all available formats. @param format The desired format. @return The most appropriate available format for representing the requested format. */ PaSampleFormat PaUtil_SelectClosestAvailableFormat( PaSampleFormat availableFormats, PaSampleFormat format ); /* high level conversions functions for use by implementations */ /** The generic sample converter prototype. Sample converters convert count samples from sourceBuffer to destinationBuffer. The actual type of the data pointed to by these parameters varys for different converter functions. @param destinationBuffer A pointer to the first sample of the destination. @param destinationStride An offset between successive destination samples expressed in samples (not bytes.) It may be negative. @param sourceBuffer A pointer to the first sample of the source. @param sourceStride An offset between successive source samples expressed in samples (not bytes.) It may be negative. @param count The number of samples to convert. @param ditherState State information used to calculate dither. Converters that do not perform dithering will ignore this parameter, in which case NULL or invalid dither state may be passed. */ typedef void PaUtilConverter( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ); /** Find a sample converter function for the given source and destinations formats and flags (clip and dither.) @return A pointer to a PaUtilConverter which will perform the requested conversion, or NULL if the given format conversion is not supported. For conversions where clipping or dithering is not necessary, the clip and dither flags are ignored and a non-clipping or dithering version is returned. If the source and destination formats are the same, a function which copies data of the appropriate size will be returned. */ PaUtilConverter* PaUtil_SelectConverter( PaSampleFormat sourceFormat, PaSampleFormat destinationFormat, PaStreamFlags flags ); /** The generic buffer zeroer prototype. Buffer zeroers copy count zeros to destinationBuffer. The actual type of the data pointed to varys for different zeroer functions. @param destinationBuffer A pointer to the first sample of the destination. @param destinationStride An offset between successive destination samples expressed in samples (not bytes.) It may be negative. @param count The number of samples to zero. */ typedef void PaUtilZeroer( void *destinationBuffer, signed int destinationStride, unsigned int count ); /** Find a buffer zeroer function for the given destination format. @return A pointer to a PaUtilZeroer which will perform the requested zeroing. */ PaUtilZeroer* PaUtil_SelectZeroer( PaSampleFormat destinationFormat ); /*----------------------------------------------------------------------------*/ /* low level functions and data structures which may be used for substituting conversion functions */ /** The type used to store all sample conversion functions. @see paConverters; */ typedef struct{ PaUtilConverter *Float32_To_Int32; PaUtilConverter *Float32_To_Int32_Dither; PaUtilConverter *Float32_To_Int32_Clip; PaUtilConverter *Float32_To_Int32_DitherClip; PaUtilConverter *Float32_To_Int24; PaUtilConverter *Float32_To_Int24_Dither; PaUtilConverter *Float32_To_Int24_Clip; PaUtilConverter *Float32_To_Int24_DitherClip; PaUtilConverter *Float32_To_Int16; PaUtilConverter *Float32_To_Int16_Dither; PaUtilConverter *Float32_To_Int16_Clip; PaUtilConverter *Float32_To_Int16_DitherClip; PaUtilConverter *Float32_To_Int8; PaUtilConverter *Float32_To_Int8_Dither; PaUtilConverter *Float32_To_Int8_Clip; PaUtilConverter *Float32_To_Int8_DitherClip; PaUtilConverter *Float32_To_UInt8; PaUtilConverter *Float32_To_UInt8_Dither; PaUtilConverter *Float32_To_UInt8_Clip; PaUtilConverter *Float32_To_UInt8_DitherClip; PaUtilConverter *Int32_To_Float32; PaUtilConverter *Int32_To_Int24; PaUtilConverter *Int32_To_Int24_Dither; PaUtilConverter *Int32_To_Int16; PaUtilConverter *Int32_To_Int16_Dither; PaUtilConverter *Int32_To_Int8; PaUtilConverter *Int32_To_Int8_Dither; PaUtilConverter *Int32_To_UInt8; PaUtilConverter *Int32_To_UInt8_Dither; PaUtilConverter *Int24_To_Float32; PaUtilConverter *Int24_To_Int32; PaUtilConverter *Int24_To_Int16; PaUtilConverter *Int24_To_Int16_Dither; PaUtilConverter *Int24_To_Int8; PaUtilConverter *Int24_To_Int8_Dither; PaUtilConverter *Int24_To_UInt8; PaUtilConverter *Int24_To_UInt8_Dither; PaUtilConverter *Int16_To_Float32; PaUtilConverter *Int16_To_Int32; PaUtilConverter *Int16_To_Int24; PaUtilConverter *Int16_To_Int8; PaUtilConverter *Int16_To_Int8_Dither; PaUtilConverter *Int16_To_UInt8; PaUtilConverter *Int16_To_UInt8_Dither; PaUtilConverter *Int8_To_Float32; PaUtilConverter *Int8_To_Int32; PaUtilConverter *Int8_To_Int24; PaUtilConverter *Int8_To_Int16; PaUtilConverter *Int8_To_UInt8; PaUtilConverter *UInt8_To_Float32; PaUtilConverter *UInt8_To_Int32; PaUtilConverter *UInt8_To_Int24; PaUtilConverter *UInt8_To_Int16; PaUtilConverter *UInt8_To_Int8; PaUtilConverter *Copy_8_To_8; /* copy without any conversion */ PaUtilConverter *Copy_16_To_16; /* copy without any conversion */ PaUtilConverter *Copy_24_To_24; /* copy without any conversion */ PaUtilConverter *Copy_32_To_32; /* copy without any conversion */ } PaUtilConverterTable; /** A table of pointers to all required converter functions. PaUtil_SelectConverter() uses this table to lookup the appropriate conversion functions. The fields of this structure are initialized with default conversion functions. Fields may be NULL, indicating that no conversion function is available. User code may substitue optimised conversion functions by assigning different function pointers to these fields. @note If the PA_NO_STANDARD_CONVERTERS preprocessor variable is defined, PortAudio's standard converters will not be compiled, and all fields of this structure will be initialized to NULL. In such cases, users should supply their own conversion functions if the require PortAudio to open a stream that requires sample conversion. @see PaUtilConverterTable, PaUtilConverter, PaUtil_SelectConverter */ extern PaUtilConverterTable paConverters; /** The type used to store all buffer zeroing functions. @see paZeroers; */ typedef struct{ PaUtilZeroer *ZeroU8; /* unsigned 8 bit, zero == 128 */ PaUtilZeroer *Zero8; PaUtilZeroer *Zero16; PaUtilZeroer *Zero24; PaUtilZeroer *Zero32; } PaUtilZeroerTable; /** A table of pointers to all required zeroer functions. PaUtil_SelectZeroer() uses this table to lookup the appropriate conversion functions. The fields of this structure are initialized with default conversion functions. User code may substitue optimised conversion functions by assigning different function pointers to these fields. @note If the PA_NO_STANDARD_ZEROERS preprocessor variable is defined, PortAudio's standard zeroers will not be compiled, and all fields of this structure will be initialized to NULL. In such cases, users should supply their own zeroing functions for the sample sizes which they intend to use. @see PaUtilZeroerTable, PaUtilZeroer, PaUtil_SelectZeroer */ extern PaUtilZeroerTable paZeroers; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_CONVERTERS_H */ praat-6.0.04/external/portaudio2007/pa_cpuload.c000066400000000000000000000073001261542461700213340ustar00rootroot00000000000000/* * $Id: pa_cpuload.c 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library CPU Load measurement functions * Portable CPU load measurement facility. * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 2002 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Functions to assist in measuring the CPU utilization of a callback stream. Used to implement the Pa_GetStreamCpuLoad() function. @todo Dynamically calculate the coefficients used to smooth the CPU Load Measurements over time to provide a uniform characterisation of CPU Load independent of rate at which PaUtil_BeginCpuLoadMeasurement / PaUtil_EndCpuLoadMeasurement are called. */ #include "pa_cpuload.h" #include #include "pa_util.h" /* for PaUtil_GetTime() */ void PaUtil_InitializeCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer, double sampleRate ) { assert( sampleRate > 0 ); measurer->samplingPeriod = 1. / sampleRate; measurer->averageLoad = 0.; } void PaUtil_ResetCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer ) { measurer->averageLoad = 0.; } void PaUtil_BeginCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer ) { measurer->measurementStartTime = PaUtil_GetTime(); } void PaUtil_EndCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer, unsigned long framesProcessed ) { double measurementEndTime, secondsFor100Percent, measuredLoad; if( framesProcessed > 0 ){ measurementEndTime = PaUtil_GetTime(); assert( framesProcessed > 0 ); secondsFor100Percent = framesProcessed * measurer->samplingPeriod; measuredLoad = (measurementEndTime - measurer->measurementStartTime) / secondsFor100Percent; /* Low pass filter the calculated CPU load to reduce jitter using a simple IIR low pass filter. */ /** FIXME @todo these coefficients shouldn't be hardwired */ #define LOWPASS_COEFFICIENT_0 (0.9) #define LOWPASS_COEFFICIENT_1 (0.99999 - LOWPASS_COEFFICIENT_0) measurer->averageLoad = (LOWPASS_COEFFICIENT_0 * measurer->averageLoad) + (LOWPASS_COEFFICIENT_1 * measuredLoad); } } double PaUtil_GetCpuLoad( PaUtilCpuLoadMeasurer* measurer ) { return measurer->averageLoad; } praat-6.0.04/external/portaudio2007/pa_cpuload.h000066400000000000000000000052371261542461700213500ustar00rootroot00000000000000#ifndef PA_CPULOAD_H #define PA_CPULOAD_H /* * $Id: pa_cpuload.h 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library CPU Load measurement functions * Portable CPU load measurement facility. * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 2002 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Functions to assist in measuring the CPU utilization of a callback stream. Used to implement the Pa_GetStreamCpuLoad() function. */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ typedef struct { double samplingPeriod; double measurementStartTime; double averageLoad; } PaUtilCpuLoadMeasurer; /**< @todo need better name than measurer */ void PaUtil_InitializeCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer, double sampleRate ); void PaUtil_BeginCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer ); void PaUtil_EndCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer, unsigned long framesProcessed ); void PaUtil_ResetCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer ); double PaUtil_GetCpuLoad( PaUtilCpuLoadMeasurer* measurer ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_CPULOAD_H */ praat-6.0.04/external/portaudio2007/pa_debugprint.c000066400000000000000000000063731261542461700220610ustar00rootroot00000000000000/* * $Id: pa_log.c $ * Portable Audio I/O Library Multi-Host API front end * Validate function parameters and manage multiple host APIs. * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2006 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Implements log function. PaUtil_SetLogPrintFunction can be user called to replace the provided DefaultLogPrint function, which writes to stderr. One can NOT pass var_args across compiler/dll boundaries as it is not "byte code/abi portable". So the technique used here is to allocate a local a static array, write in it, then callback the user with a pointer to its start. @todo Consider allocating strdump using dynamic allocation. @todo Consider reentrancy and possibly corrupted strdump buffer. */ #include #include #include "pa_debugprint.h" static PaUtilLogCallback userCB=0; void PaUtil_SetDebugPrintFunction(PaUtilLogCallback cb) { userCB = cb; } /* If your platform doesnt have vsnprintf, you are stuck with a VERY dangerous alternative, vsprintf (with no n) */ #if (_MSC_VER) && (_MSC_VER <= 1400) #define VSNPRINTF _vsnprintf #else #define VSNPRINTF vsnprintf #endif #define SIZEDUMP 1024 static char strdump[SIZEDUMP]; void PaUtil_DebugPrint( const char *format, ... ) { if (userCB) { va_list ap; va_start( ap, format ); VSNPRINTF( strdump, SIZEDUMP, format, ap ); userCB(strdump); va_end( ap ); } else { va_list ap; va_start( ap, format ); vfprintf( stderr, format, ap ); va_end( ap ); fflush( stderr ); } } praat-6.0.04/external/portaudio2007/pa_debugprint.h000066400000000000000000000116611261542461700220620ustar00rootroot00000000000000#ifndef PA_LOG_H #define PA_LOG_H /* * Log file redirector function * Copyright (c) 1999-2006 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ void PaUtil_DebugPrint( const char *format, ... ); /* The basic format for log messages is described below. If you need to add any log messages, please follow this format. Function entry (void function): "FunctionName called.\n" Function entry (non void function): "FunctionName called:\n" "\tParam1Type param1: param1Value\n" "\tParam2Type param2: param2Value\n" (etc...) Function exit (no return value): "FunctionName returned.\n" Function exit (simple return value): "FunctionName returned:\n" "\tReturnType: returnValue\n" If the return type is an error code, the error text is displayed in () If the return type is not an error code, but has taken a special value because an error occurred, then the reason for the error is shown in [] If the return type is a struct ptr, the struct is dumped. See the code below for examples */ /** PA_DEBUG() provides a simple debug message printing facility. The macro passes it's argument to a printf-like function called PaUtil_DebugPrint() which prints to stderr and always flushes the stream after printing. Because preprocessor macros cannot directly accept variable length argument lists, calls to the macro must include an additional set of parenthesis, eg: PA_DEBUG(("errorno: %d", 1001 )); */ #ifdef PA_ENABLE_DEBUG_OUTPUT #define PA_DEBUG(x) PaUtil_DebugPrint x ; #else #define PA_DEBUG(x) #endif #ifdef PA_LOG_API_CALLS #define PA_LOGAPI(x) PaUtil_DebugPrint x #define PA_LOGAPI_ENTER(functionName) PaUtil_DebugPrint( functionName " called.\n" ) #define PA_LOGAPI_ENTER_PARAMS(functionName) PaUtil_DebugPrint( functionName " called:\n" ) #define PA_LOGAPI_EXIT(functionName) PaUtil_DebugPrint( functionName " returned.\n" ) #define PA_LOGAPI_EXIT_PAERROR( functionName, result ) \ PaUtil_DebugPrint( functionName " returned:\n" ); \ PaUtil_DebugPrint("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ) #define PA_LOGAPI_EXIT_T( functionName, resultFormatString, result ) \ PaUtil_DebugPrint( functionName " returned:\n" ); \ PaUtil_DebugPrint("\t" resultFormatString "\n", result ) #define PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( functionName, positiveResultFormatString, result ) \ PaUtil_DebugPrint( functionName " returned:\n" ); \ if( result > 0 ) \ PaUtil_DebugPrint("\t" positiveResultFormatString "\n", result ); \ else \ PaUtil_DebugPrint("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ) #else #define PA_LOGAPI(x) #define PA_LOGAPI_ENTER(functionName) #define PA_LOGAPI_ENTER_PARAMS(functionName) #define PA_LOGAPI_EXIT(functionName) #define PA_LOGAPI_EXIT_PAERROR( functionName, result ) #define PA_LOGAPI_EXIT_T( functionName, resultFormatString, result ) #define PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( functionName, positiveResultFormatString, result ) #endif typedef void (*PaUtilLogCallback ) (const char *log); /** Install user provided log function */ void PaUtil_SetDebugPrintFunction(PaUtilLogCallback cb); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_LOG_H */ praat-6.0.04/external/portaudio2007/pa_dither.c000066400000000000000000000157121261542461700211720ustar00rootroot00000000000000/* * $Id: pa_dither.c 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library triangular dither generator * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Phil Burk, Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Functions for generating dither noise Paul Boersma 2013: corrected for sizeof(long) */ #include "pa_dither.h" #include "pa_types.h" #define PA_DITHER_BITS_ (15) void PaUtil_InitializeTriangularDitherState( PaUtilTriangularDitherGenerator *state ) { state->previous = 0; state->randSeed1 = 22222; state->randSeed2 = 5555555; } signed long PaUtil_Generate16BitTriangularDither( PaUtilTriangularDitherGenerator *state ) { signed long current, highPass; /* Generate two random numbers. */ state->randSeed1 = (state->randSeed1 * 196314165) + 907633515; state->randSeed2 = (state->randSeed2 * 196314165) + 907633515; /* Generate triangular distribution about 0. * Shift before adding to prevent overflow which would skew the distribution. * Also shift an extra bit for the high pass filter. */ #define DITHER_SHIFT_ ((sizeof(long)*8 - PA_DITHER_BITS_) + 1) current = (((signed long)state->randSeed1)>>DITHER_SHIFT_) + (((signed long)state->randSeed2)>>DITHER_SHIFT_); /* High pass filter to reduce audibility. */ highPass = current - state->previous; state->previous = current; return highPass; } /* Multiply by PA_FLOAT_DITHER_SCALE_ to get a float between -2.0 and +1.99999 */ #define PA_FLOAT_DITHER_SCALE_ (1.0f / ((1<randSeed1 = (state->randSeed1 * 196314165) + 907633515; state->randSeed2 = (state->randSeed2 * 196314165) + 907633515; /* Generate triangular distribution about 0. * Shift before adding to prevent overflow which would skew the distribution. * Also shift an extra bit for the high pass filter. */ #define DITHER_SHIFT_ ((sizeof(long)*8 - PA_DITHER_BITS_) + 1) current = (((signed long)state->randSeed1)>>DITHER_SHIFT_) + (((signed long)state->randSeed2)>>DITHER_SHIFT_); /* High pass filter to reduce audibility. */ highPass = current - state->previous; state->previous = current; return ((float)highPass) * const_float_dither_scale_; } /* The following alternate dither algorithms (from musicdsp.org) could be considered */ /*Noise shaped dither (March 2000) ------------------- This is a simple implementation of highpass triangular-PDF dither with 2nd-order noise shaping, for use when truncating floating point audio data to fixed point. The noise shaping lowers the noise floor by 11dB below 5kHz (@ 44100Hz sample rate) compared to triangular-PDF dither. The code below assumes input data is in the range +1 to -1 and doesn't check for overloads! To save time when generating dither for multiple channels you can do things like this: r3=(r1 & 0x7F)<<8; instead of calling rand() again. int r1, r2; //rectangular-PDF random numbers float s1, s2; //error feedback buffers float s = 0.5f; //set to 0.0f for no noise shaping float w = pow(2.0,bits-1); //word length (usually bits=16) float wi= 1.0f/w; float d = wi / RAND_MAX; //dither amplitude (2 lsb) float o = wi * 0.5f; //remove dc offset float in, tmp; int out; //for each sample... r2=r1; //can make HP-TRI dither by r1=rand(); //subtracting previous rand() in += s * (s1 + s1 - s2); //error feedback tmp = in + o + d * (float)(r1 - r2); //dc offset and dither out = (int)(w * tmp); //truncate downwards if(tmp<0.0f) out--; //this is faster than floor() s2 = s1; s1 = in - wi * (float)out; //error -- paul.kellett@maxim.abel.co.uk http://www.maxim.abel.co.uk */ /* 16-to-8-bit first-order dither Type : First order error feedforward dithering code References : Posted by Jon Watte Notes : This is about as simple a dithering algorithm as you can implement, but it's likely to sound better than just truncating to N bits. Note that you might not want to carry forward the full difference for infinity. It's probably likely that the worst performance hit comes from the saturation conditionals, which can be avoided with appropriate instructions on many DSPs and integer SIMD type instructions, or CMOV. Last, if sound quality is paramount (such as when going from > 16 bits to 16 bits) you probably want to use a higher-order dither function found elsewhere on this site. Code : // This code will down-convert and dither a 16-bit signed short // mono signal into an 8-bit unsigned char signal, using a first // order forward-feeding error term dither. #define uchar unsigned char void dither_one_channel_16_to_8( short * input, uchar * output, int count, int * memory ) { int m = *memory; while( count-- > 0 ) { int i = *input++; i += m; int j = i + 32768 - 128; uchar o; if( j < 0 ) { o = 0; } else if( j > 65535 ) { o = 255; } else { o = (uchar)((j>>8)&0xff); } m = ((j-32768+128)-i); *output++ = o; } *memory = m; } */ praat-6.0.04/external/portaudio2007/pa_dither.h000066400000000000000000000064521261542461700212000ustar00rootroot00000000000000#ifndef PA_DITHER_H #define PA_DITHER_H /* * $Id: pa_dither.h 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library triangular dither generator * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Phil Burk, Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Functions for generating dither noise */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** @brief State needed to generate a dither signal */ typedef struct PaUtilTriangularDitherGenerator{ unsigned long previous; unsigned long randSeed1; unsigned long randSeed2; } PaUtilTriangularDitherGenerator; /** @brief Initialize dither state */ void PaUtil_InitializeTriangularDitherState( PaUtilTriangularDitherGenerator *ditherState ); /** @brief Calculate 2 LSB dither signal with a triangular distribution. Ranged for adding to a 1 bit right-shifted 32 bit integer prior to >>15. eg:
    signed long in = *
    signed long dither = PaUtil_Generate16BitTriangularDither( ditherState );
    signed short out = (signed short)(((in>>1) + dither) >> 15);
@return A signed long with a range of +32767 to -32768 */ signed long PaUtil_Generate16BitTriangularDither( PaUtilTriangularDitherGenerator *ditherState ); /** @brief Calculate 2 LSB dither signal with a triangular distribution. Ranged for adding to a pre-scaled float.
    float in = *
    float dither = PaUtil_GenerateFloatTriangularDither( ditherState );
    // use smaller scaler to prevent overflow when we add the dither
    signed short out = (signed short)(in*(32766.0f) + dither );
@return A float with a range of -2.0 to +1.99999. */ float PaUtil_GenerateFloatTriangularDither( PaUtilTriangularDitherGenerator *ditherState ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_DITHER_H */ praat-6.0.04/external/portaudio2007/pa_endianness.h000066400000000000000000000124261261542461700220460ustar00rootroot00000000000000#ifndef PA_ENDIANNESS_H #define PA_ENDIANNESS_H /* * $Id: pa_endianness.h 1216 2007-06-10 09:26:00Z aknudsen $ * Portable Audio I/O Library current platform endianness macros * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Phil Burk, Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Configure endianness symbols for the target processor. Arrange for either the PA_LITTLE_ENDIAN or PA_BIG_ENDIAN preprocessor symbols to be defined. The one that is defined reflects the endianness of the target platform and may be used to implement conditional compilation of byte-order dependent code. If either PA_LITTLE_ENDIAN or PA_BIG_ENDIAN is defined already, then no attempt is made to override that setting. This may be useful if you have a better way of determining the platform's endianness. The autoconf mechanism uses this for example. A PA_VALIDATE_ENDIANNESS macro is provided to compare the compile time and runtime endiannes and raise an assertion if they don't match. */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* If this is an apple, we need to do detect endianness this way */ #if defined(__APPLE__) /* we need to do some endian detection that is sensitive to harware arch */ #if defined(__LITTLE_ENDIAN__) #if !defined( PA_LITTLE_ENDIAN ) #define PA_LITTLE_ENDIAN #endif #if defined( PA_BIG_ENDIAN ) #undef PA_BIG_ENDIAN #endif #else #if !defined( PA_BIG_ENDIAN ) #define PA_BIG_ENDIAN #endif #if defined( PA_LITTLE_ENDIAN ) #undef PA_LITTLE_ENDIAN #endif #endif #else /* this is not an apple, so first check the existing defines, and, failing that, detect well-known architechtures. */ #if defined(PA_LITTLE_ENDIAN) || defined(PA_BIG_ENDIAN) /* endianness define has been set externally, such as by autoconf */ #if defined(PA_LITTLE_ENDIAN) && defined(PA_BIG_ENDIAN) #error both PA_LITTLE_ENDIAN and PA_BIG_ENDIAN have been defined externally to pa_endianness.h - only one endianness at a time please #endif #else /* endianness define has not been set externally */ /* set PA_LITTLE_ENDIAN or PA_BIG_ENDIAN by testing well known platform specific defines */ #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(LITTLE_ENDIAN) || defined(__i386) || defined(_M_IX86) || defined(__x86_64__) #define PA_LITTLE_ENDIAN /* win32, assume intel byte order */ #else #define PA_BIG_ENDIAN #endif #endif #if !defined(PA_LITTLE_ENDIAN) && !defined(PA_BIG_ENDIAN) /* If the following error is raised, you either need to modify the code above to automatically determine the endianness from other symbols defined on your platform, or define either PA_LITTLE_ENDIAN or PA_BIG_ENDIAN externally. */ #error pa_endianness.h was unable to automatically determine the endianness of the target platform #endif #endif /* PA_VALIDATE_ENDIANNESS compares the compile time and runtime endianness, and raises an assertion if they don't match. must be included in the context in which this macro is used. */ #if defined(PA_LITTLE_ENDIAN) #define PA_VALIDATE_ENDIANNESS \ { \ const long nativeOne = 1; \ assert( "PortAudio: compile time and runtime endianness don't match" && (((char *)&nativeOne)[0]) == 1 ); \ } #elif defined(PA_BIG_ENDIAN) #define PA_VALIDATE_ENDIANNESS \ { \ const long nativeOne = 1; \ assert( "PortAudio: compile time and runtime endianness don't match" && (((char *)&nativeOne)[0]) == 0 ); \ } #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_ENDIANNESS_H */ praat-6.0.04/external/portaudio2007/pa_front.c000066400000000000000000001520331261542461700210410ustar00rootroot00000000000000/* * $Id: pa_front.c 1229 2007-06-15 16:11:11Z rossb $ * Portable Audio I/O Library Multi-Host API front end * Validate function parameters and manage multiple host APIs. * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Implements public PortAudio API, checks some errors, forwards to host API implementations. Implements the functions defined in the PortAudio API, checks for some parameter and state inconsistencies and forwards API requests to specific Host API implementations (via the interface declared in pa_hostapi.h), and Streams (via the interface declared in pa_stream.h). This file handles initialization and termination of Host API implementations via initializers stored in the paHostApiInitializers global variable. Some utility functions declared in pa_util.h are implemented in this file. All PortAudio API functions can be conditionally compiled with logging code. To compile with logging, define the PA_LOG_API_CALLS precompiler symbol. @todo Consider adding host API specific error text in Pa_GetErrorText() for paUnanticipatedHostError @todo Consider adding a new error code for when (inputParameters == NULL) && (outputParameters == NULL) @todo review whether Pa_CloseStream() should call the interface's CloseStream function if aborting the stream returns an error code. @todo Create new error codes if a NULL buffer pointer, or a zero frame count is passed to Pa_ReadStream or Pa_WriteStream. */ #include #include #include #include /* needed by PA_VALIDATE_ENDIANNESS */ #include "portaudio.h" #include "pa_util.h" #include "pa_endianness.h" #include "pa_types.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_trace.h" /* still usefull?*/ #include "pa_debugprint.h" #define PA_VERSION_ 1899 #define PA_VERSION_TEXT_ "PortAudio V19-devel (built " __DATE__ ")" int Pa_GetVersion( void ) { return PA_VERSION_; } const char* Pa_GetVersionText( void ) { return PA_VERSION_TEXT_; } #define PA_LAST_HOST_ERROR_TEXT_LENGTH_ 1024 static char lastHostErrorText_[ PA_LAST_HOST_ERROR_TEXT_LENGTH_ + 1 ] = {0}; static PaHostErrorInfo lastHostErrorInfo_ = { (PaHostApiTypeId)-1, 0, lastHostErrorText_ }; void PaUtil_SetLastHostErrorInfo( PaHostApiTypeId hostApiType, long errorCode, const char *errorText ) { lastHostErrorInfo_.hostApiType = hostApiType; lastHostErrorInfo_.errorCode = errorCode; strncpy( lastHostErrorText_, errorText, PA_LAST_HOST_ERROR_TEXT_LENGTH_ ); } static PaUtilHostApiRepresentation **hostApis_ = 0; static int hostApisCount_ = 0; static int initializationCount_ = 0; static int deviceCount_ = 0; PaUtilStreamRepresentation *firstOpenStream_ = NULL; #define PA_IS_INITIALISED_ (initializationCount_ != 0) static int CountHostApiInitializers( void ) { int result = 0; while( paHostApiInitializers[ result ] != 0 ) ++result; return result; } static void TerminateHostApis( void ) { /* terminate in reverse order from initialization */ PA_DEBUG(("TerminateHostApis in \n")); while( hostApisCount_ > 0 ) { --hostApisCount_; hostApis_[hostApisCount_]->Terminate( hostApis_[hostApisCount_] ); } hostApisCount_ = 0; deviceCount_ = 0; if( hostApis_ != 0 ) PaUtil_FreeMemory( hostApis_ ); hostApis_ = 0; PA_DEBUG(("TerminateHostApis out\n")); } static PaError InitializeHostApis( void ) { PaError result = paNoError; int i, initializerCount, baseDeviceIndex; initializerCount = CountHostApiInitializers(); hostApis_ = (PaUtilHostApiRepresentation**)PaUtil_AllocateMemory( sizeof(PaUtilHostApiRepresentation*) * initializerCount ); if( !hostApis_ ) { result = paInsufficientMemory; goto error; } hostApisCount_ = 0; deviceCount_ = 0; baseDeviceIndex = 0; for( i=0; i< initializerCount; ++i ) { hostApis_[hostApisCount_] = NULL; PA_DEBUG(( "before paHostApiInitializers[%d].\n",i)); result = paHostApiInitializers[i]( &hostApis_[hostApisCount_], hostApisCount_ ); if( result != paNoError ) goto error; PA_DEBUG(( "after paHostApiInitializers[%d].\n",i)); if( hostApis_[hostApisCount_] ) { PaUtilHostApiRepresentation* hostApi = hostApis_[hostApisCount_]; assert( hostApi->info.defaultInputDevice < hostApi->info.deviceCount ); assert( hostApi->info.defaultOutputDevice < hostApi->info.deviceCount ); hostApi->privatePaFrontInfo.baseDeviceIndex = baseDeviceIndex; if( hostApi->info.defaultInputDevice != paNoDevice ) hostApi->info.defaultInputDevice += baseDeviceIndex; if( hostApi->info.defaultOutputDevice != paNoDevice ) hostApi->info.defaultOutputDevice += baseDeviceIndex; baseDeviceIndex += hostApi->info.deviceCount; deviceCount_ += hostApi->info.deviceCount; ++hostApisCount_; } } return result; error: TerminateHostApis(); return result; } /* FindHostApi() finds the index of the host api to which belongs and returns it. if is non-null, the host specific device index is returned in it. returns -1 if is out of range. */ static int FindHostApi( PaDeviceIndex device, int *hostSpecificDeviceIndex ) { int i=0; if( !PA_IS_INITIALISED_ ) return -1; if( device < 0 ) return -1; while( i < hostApisCount_ && device >= hostApis_[i]->info.deviceCount ) { device -= hostApis_[i]->info.deviceCount; ++i; } if( i >= hostApisCount_ ) return -1; if( hostSpecificDeviceIndex ) *hostSpecificDeviceIndex = device; return i; } static void AddOpenStream( PaStream* stream ) { ((PaUtilStreamRepresentation*)stream)->nextOpenStream = firstOpenStream_; firstOpenStream_ = (PaUtilStreamRepresentation*)stream; } static void RemoveOpenStream( PaStream* stream ) { PaUtilStreamRepresentation *previous = NULL; PaUtilStreamRepresentation *current = firstOpenStream_; while( current != NULL ) { if( ((PaStream*)current) == stream ) { if( previous == NULL ) { firstOpenStream_ = current->nextOpenStream; } else { previous->nextOpenStream = current->nextOpenStream; } return; } else { previous = current; current = current->nextOpenStream; } } } static void CloseOpenStreams( void ) { /* we call Pa_CloseStream() here to ensure that the same destruction logic is used for automatically closed streams */ while( firstOpenStream_ != NULL ) Pa_CloseStream( firstOpenStream_ ); } PaError Pa_Initialize( void ) { PaError result; PA_LOGAPI_ENTER( "Pa_Initialize" ); if( PA_IS_INITIALISED_ ) { ++initializationCount_; result = paNoError; } else { PA_VALIDATE_TYPE_SIZES; PA_VALIDATE_ENDIANNESS; PaUtil_InitializeClock(); PaUtil_ResetTraceMessages(); result = InitializeHostApis(); if( result == paNoError ) ++initializationCount_; } PA_LOGAPI_EXIT_PAERROR( "Pa_Initialize", result ); return result; } PaError Pa_Terminate( void ) { PaError result; PA_LOGAPI_ENTER( "Pa_Terminate" ); if( PA_IS_INITIALISED_ ) { if( --initializationCount_ == 0 ) { CloseOpenStreams(); TerminateHostApis(); PaUtil_DumpTraceMessages(); } result = paNoError; } else { result= paNotInitialized; } PA_LOGAPI_EXIT_PAERROR( "Pa_Terminate", result ); return result; } const PaHostErrorInfo* Pa_GetLastHostErrorInfo( void ) { return &lastHostErrorInfo_; } const char *Pa_GetErrorText( PaError errorCode ) { const char *result; switch( errorCode ) { case paNoError: result = "Success"; break; case paNotInitialized: result = "PortAudio not initialized"; break; /** @todo could catenate the last host error text to result in the case of paUnanticipatedHostError */ case paUnanticipatedHostError: result = "Unanticipated host error"; break; case paInvalidChannelCount: result = "Invalid number of channels"; break; case paInvalidSampleRate: result = "Invalid sample rate"; break; case paInvalidDevice: result = "Invalid device"; break; case paInvalidFlag: result = "Invalid flag"; break; case paSampleFormatNotSupported: result = "Sample format not supported"; break; case paBadIODeviceCombination: result = "Illegal combination of I/O devices"; break; case paInsufficientMemory: result = "Insufficient memory"; break; case paBufferTooBig: result = "Buffer too big"; break; case paBufferTooSmall: result = "Buffer too small"; break; case paNullCallback: result = "No callback routine specified"; break; case paBadStreamPtr: result = "Invalid stream pointer"; break; case paTimedOut: result = "Wait timed out"; break; case paInternalError: result = "Internal PortAudio error"; break; case paDeviceUnavailable: result = "Device unavailable"; break; case paIncompatibleHostApiSpecificStreamInfo: result = "Incompatible host API specific stream info"; break; case paStreamIsStopped: result = "Stream is stopped"; break; case paStreamIsNotStopped: result = "Stream is not stopped"; break; case paInputOverflowed: result = "Input overflowed"; break; case paOutputUnderflowed: result = "Output underflowed"; break; case paHostApiNotFound: result = "Host API not found"; break; case paInvalidHostApi: result = "Invalid host API"; break; case paCanNotReadFromACallbackStream: result = "Can't read from a callback stream"; break; case paCanNotWriteToACallbackStream: result = "Can't write to a callback stream"; break; case paCanNotReadFromAnOutputOnlyStream: result = "Can't read from an output only stream"; break; case paCanNotWriteToAnInputOnlyStream: result = "Can't write to an input only stream"; break; default: if( errorCode > 0 ) result = "Invalid error code (value greater than zero)"; else result = "Invalid error code"; break; } return result; } PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type ) { PaHostApiIndex result; int i; PA_LOGAPI_ENTER_PARAMS( "Pa_HostApiTypeIdToHostApiIndex" ); PA_LOGAPI(("\tPaHostApiTypeId type: %d\n", type )); if( !PA_IS_INITIALISED_ ) { result = paNotInitialized; } else { result = paHostApiNotFound; for( i=0; i < hostApisCount_; ++i ) { if( hostApis_[i]->info.type == type ) { result = i; break; } } } PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_HostApiTypeIdToHostApiIndex", "PaHostApiIndex: %d", result ); return result; } PaError PaUtil_GetHostApiRepresentation( struct PaUtilHostApiRepresentation **hostApi, PaHostApiTypeId type ) { PaError result; int i; if( !PA_IS_INITIALISED_ ) { result = paNotInitialized; } else { result = paHostApiNotFound; for( i=0; i < hostApisCount_; ++i ) { if( hostApis_[i]->info.type == type ) { *hostApi = hostApis_[i]; result = paNoError; break; } } } return result; } PaError PaUtil_DeviceIndexToHostApiDeviceIndex( PaDeviceIndex *hostApiDevice, PaDeviceIndex device, struct PaUtilHostApiRepresentation *hostApi ) { PaError result; PaDeviceIndex x; x = device - hostApi->privatePaFrontInfo.baseDeviceIndex; if( x < 0 || x >= hostApi->info.deviceCount ) { result = paInvalidDevice; } else { *hostApiDevice = x; result = paNoError; } return result; } PaHostApiIndex Pa_GetHostApiCount( void ) { int result; PA_LOGAPI_ENTER( "Pa_GetHostApiCount" ); if( !PA_IS_INITIALISED_ ) { result = paNotInitialized; } else { result = hostApisCount_; } PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetHostApiCount", "PaHostApiIndex: %d", result ); return result; } PaHostApiIndex Pa_GetDefaultHostApi( void ) { int result; PA_LOGAPI_ENTER( "Pa_GetDefaultHostApi" ); if( !PA_IS_INITIALISED_ ) { result = paNotInitialized; } else { result = paDefaultHostApiIndex; /* internal consistency check: make sure that the default host api index is within range */ if( result < 0 || result >= hostApisCount_ ) { result = paInternalError; } } PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetDefaultHostApi", "PaHostApiIndex: %d", result ); return result; } const PaHostApiInfo* Pa_GetHostApiInfo( PaHostApiIndex hostApi ) { PaHostApiInfo *info; PA_LOGAPI_ENTER_PARAMS( "Pa_GetHostApiInfo" ); PA_LOGAPI(("\tPaHostApiIndex hostApi: %d\n", hostApi )); if( !PA_IS_INITIALISED_ ) { info = NULL; PA_LOGAPI(("Pa_GetHostApiInfo returned:\n" )); PA_LOGAPI(("\tPaHostApiInfo*: NULL [ PortAudio not initialized ]\n" )); } else if( hostApi < 0 || hostApi >= hostApisCount_ ) { info = NULL; PA_LOGAPI(("Pa_GetHostApiInfo returned:\n" )); PA_LOGAPI(("\tPaHostApiInfo*: NULL [ hostApi out of range ]\n" )); } else { info = &hostApis_[hostApi]->info; PA_LOGAPI(("Pa_GetHostApiInfo returned:\n" )); PA_LOGAPI(("\tPaHostApiInfo*: 0x%p\n", info )); PA_LOGAPI(("\t{\n" )); PA_LOGAPI(("\t\tint structVersion: %d\n", info->structVersion )); PA_LOGAPI(("\t\tPaHostApiTypeId type: %d\n", info->type )); PA_LOGAPI(("\t\tconst char *name: %s\n", info->name )); PA_LOGAPI(("\t}\n" )); } return info; } PaDeviceIndex Pa_HostApiDeviceIndexToDeviceIndex( PaHostApiIndex hostApi, int hostApiDeviceIndex ) { PaDeviceIndex result; PA_LOGAPI_ENTER_PARAMS( "Pa_HostApiDeviceIndexToPaDeviceIndex" ); PA_LOGAPI(("\tPaHostApiIndex hostApi: %d\n", hostApi )); PA_LOGAPI(("\tint hostApiDeviceIndex: %d\n", hostApiDeviceIndex )); if( !PA_IS_INITIALISED_ ) { result = paNotInitialized; } else { if( hostApi < 0 || hostApi >= hostApisCount_ ) { result = paInvalidHostApi; } else { if( hostApiDeviceIndex < 0 || hostApiDeviceIndex >= hostApis_[hostApi]->info.deviceCount ) { result = paInvalidDevice; } else { result = hostApis_[hostApi]->privatePaFrontInfo.baseDeviceIndex + hostApiDeviceIndex; } } } PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_HostApiDeviceIndexToPaDeviceIndex", "PaDeviceIndex: %d", result ); return result; } PaDeviceIndex Pa_GetDeviceCount( void ) { PaDeviceIndex result; PA_LOGAPI_ENTER( "Pa_GetDeviceCount" ); if( !PA_IS_INITIALISED_ ) { result = paNotInitialized; } else { result = deviceCount_; } PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetDeviceCount", "PaDeviceIndex: %d", result ); return result; } PaDeviceIndex Pa_GetDefaultInputDevice( void ) { PaHostApiIndex hostApi; PaDeviceIndex result; PA_LOGAPI_ENTER( "Pa_GetDefaultInputDevice" ); hostApi = Pa_GetDefaultHostApi(); if( hostApi < 0 ) { result = paNoDevice; } else { result = hostApis_[hostApi]->info.defaultInputDevice; } PA_LOGAPI_EXIT_T( "Pa_GetDefaultInputDevice", "PaDeviceIndex: %d", result ); return result; } PaDeviceIndex Pa_GetDefaultOutputDevice( void ) { PaHostApiIndex hostApi; PaDeviceIndex result; PA_LOGAPI_ENTER( "Pa_GetDefaultOutputDevice" ); hostApi = Pa_GetDefaultHostApi(); if( hostApi < 0 ) { result = paNoDevice; } else { result = hostApis_[hostApi]->info.defaultOutputDevice; } PA_LOGAPI_EXIT_T( "Pa_GetDefaultOutputDevice", "PaDeviceIndex: %d", result ); return result; } const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceIndex device ) { int hostSpecificDeviceIndex; int hostApiIndex = FindHostApi( device, &hostSpecificDeviceIndex ); PaDeviceInfo *result; PA_LOGAPI_ENTER_PARAMS( "Pa_GetDeviceInfo" ); PA_LOGAPI(("\tPaDeviceIndex device: %d\n", device )); if( hostApiIndex < 0 ) { result = NULL; PA_LOGAPI(("Pa_GetDeviceInfo returned:\n" )); PA_LOGAPI(("\tPaDeviceInfo* NULL [ invalid device index ]\n" )); } else { result = hostApis_[hostApiIndex]->deviceInfos[ hostSpecificDeviceIndex ]; PA_LOGAPI(("Pa_GetDeviceInfo returned:\n" )); PA_LOGAPI(("\tPaDeviceInfo*: 0x%p:\n", result )); PA_LOGAPI(("\t{\n" )); PA_LOGAPI(("\t\tint structVersion: %d\n", result->structVersion )); PA_LOGAPI(("\t\tconst char *name: %s\n", result->name )); PA_LOGAPI(("\t\tPaHostApiIndex hostApi: %d\n", result->hostApi )); PA_LOGAPI(("\t\tint maxInputChannels: %d\n", result->maxInputChannels )); PA_LOGAPI(("\t\tint maxOutputChannels: %d\n", result->maxOutputChannels )); PA_LOGAPI(("\t}\n" )); } return result; } /* SampleFormatIsValid() returns 1 if sampleFormat is a sample format defined in portaudio.h, or 0 otherwise. */ static int SampleFormatIsValid( PaSampleFormat format ) { switch( format & ~paNonInterleaved ) { case paFloat32: return 1; case paInt16: return 1; case paInt32: return 1; case paInt24: return 1; case paInt8: return 1; case paUInt8: return 1; case paCustomFormat: return 1; default: return 0; } } /* NOTE: make sure this validation list is kept syncronised with the one in pa_hostapi.h ValidateOpenStreamParameters() checks that parameters to Pa_OpenStream() conform to the expected values as described below. This function is also designed to be used with the proposed Pa_IsFormatSupported() function. There are basically two types of validation that could be performed: Generic conformance validation, and device capability mismatch validation. This function performs only generic conformance validation. Validation that would require knowledge of device capabilities is not performed because of potentially complex relationships between combinations of parameters - for example, even if the sampleRate seems ok, it might not be for a duplex stream - we have no way of checking this in an API-neutral way, so we don't try. On success the function returns PaNoError and fills in hostApi, hostApiInputDeviceID, and hostApiOutputDeviceID fields. On failure the function returns an error code indicating the first encountered parameter error. If ValidateOpenStreamParameters() returns paNoError, the following assertions are guaranteed to be true. - at least one of inputParameters & outputParmeters is valid (not NULL) - if inputParameters & outputParameters are both valid, that inputParameters->device & outputParameters->device both use the same host api PaDeviceIndex inputParameters->device - is within range (0 to Pa_GetDeviceCount-1) Or: - is paUseHostApiSpecificDeviceSpecification and inputParameters->hostApiSpecificStreamInfo is non-NULL and refers to a valid host api int inputParameters->channelCount - if inputParameters->device is not paUseHostApiSpecificDeviceSpecification, channelCount is > 0 - upper bound is NOT validated against device capabilities PaSampleFormat inputParameters->sampleFormat - is one of the sample formats defined in portaudio.h void *inputParameters->hostApiSpecificStreamInfo - if supplied its hostApi field matches the input device's host Api PaDeviceIndex outputParmeters->device - is within range (0 to Pa_GetDeviceCount-1) int outputParmeters->channelCount - if inputDevice is valid, channelCount is > 0 - upper bound is NOT validated against device capabilities PaSampleFormat outputParmeters->sampleFormat - is one of the sample formats defined in portaudio.h void *outputParmeters->hostApiSpecificStreamInfo - if supplied its hostApi field matches the output device's host Api double sampleRate - is not an 'absurd' rate (less than 1000. or greater than 200000.) - sampleRate is NOT validated against device capabilities PaStreamFlags streamFlags - unused platform neutral flags are zero - paNeverDropInput is only used for full-duplex callback streams with variable buffer size (paFramesPerBufferUnspecified) */ static PaError ValidateOpenStreamParameters( const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, PaUtilHostApiRepresentation **hostApi, PaDeviceIndex *hostApiInputDevice, PaDeviceIndex *hostApiOutputDevice ) { int inputHostApiIndex = -1, /* Surpress uninitialised var warnings: compiler does */ outputHostApiIndex = -1; /* not see that if inputParameters and outputParame- */ /* ters are both nonzero, these indices are set. */ if( (inputParameters == NULL) && (outputParameters == NULL) ) { return paInvalidDevice; /** @todo should be a new error code "invalid device parameters" or something */ } else { if( inputParameters == NULL ) { *hostApiInputDevice = paNoDevice; } else if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) { if( inputParameters->hostApiSpecificStreamInfo ) { inputHostApiIndex = Pa_HostApiTypeIdToHostApiIndex( ((PaUtilHostApiSpecificStreamInfoHeader*)inputParameters->hostApiSpecificStreamInfo)->hostApiType ); if( inputHostApiIndex != -1 ) { *hostApiInputDevice = paUseHostApiSpecificDeviceSpecification; *hostApi = hostApis_[inputHostApiIndex]; } else { return paInvalidDevice; } } else { return paInvalidDevice; } } else { if( inputParameters->device < 0 || inputParameters->device >= deviceCount_ ) return paInvalidDevice; inputHostApiIndex = FindHostApi( inputParameters->device, hostApiInputDevice ); if( inputHostApiIndex < 0 ) return paInternalError; *hostApi = hostApis_[inputHostApiIndex]; if( inputParameters->channelCount <= 0 ) return paInvalidChannelCount; if( !SampleFormatIsValid( inputParameters->sampleFormat ) ) return paSampleFormatNotSupported; if( inputParameters->hostApiSpecificStreamInfo != NULL ) { if( ((PaUtilHostApiSpecificStreamInfoHeader*)inputParameters->hostApiSpecificStreamInfo)->hostApiType != (*hostApi)->info.type ) return paIncompatibleHostApiSpecificStreamInfo; } } if( outputParameters == NULL ) { *hostApiOutputDevice = paNoDevice; } else if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) { if( outputParameters->hostApiSpecificStreamInfo ) { outputHostApiIndex = Pa_HostApiTypeIdToHostApiIndex( ((PaUtilHostApiSpecificStreamInfoHeader*)outputParameters->hostApiSpecificStreamInfo)->hostApiType ); if( outputHostApiIndex != -1 ) { *hostApiOutputDevice = paUseHostApiSpecificDeviceSpecification; *hostApi = hostApis_[outputHostApiIndex]; } else { return paInvalidDevice; } } else { return paInvalidDevice; } } else { if( outputParameters->device < 0 || outputParameters->device >= deviceCount_ ) return paInvalidDevice; outputHostApiIndex = FindHostApi( outputParameters->device, hostApiOutputDevice ); if( outputHostApiIndex < 0 ) return paInternalError; *hostApi = hostApis_[outputHostApiIndex]; if( outputParameters->channelCount <= 0 ) return paInvalidChannelCount; if( !SampleFormatIsValid( outputParameters->sampleFormat ) ) return paSampleFormatNotSupported; if( outputParameters->hostApiSpecificStreamInfo != NULL ) { if( ((PaUtilHostApiSpecificStreamInfoHeader*)outputParameters->hostApiSpecificStreamInfo)->hostApiType != (*hostApi)->info.type ) return paIncompatibleHostApiSpecificStreamInfo; } } if( (inputParameters != NULL) && (outputParameters != NULL) ) { /* ensure that both devices use the same API */ if( inputHostApiIndex != outputHostApiIndex ) return paBadIODeviceCombination; } } /* Check for absurd sample rates. */ if( (sampleRate < 1000.0) || (sampleRate > 200000.0) ) return paInvalidSampleRate; if( ((streamFlags & ~paPlatformSpecificFlags) & ~(paClipOff | paDitherOff | paNeverDropInput | paPrimeOutputBuffersUsingStreamCallback ) ) != 0 ) return paInvalidFlag; if( streamFlags & paNeverDropInput ) { /* must be a callback stream */ if( !streamCallback ) return paInvalidFlag; /* must be a full duplex stream */ if( (inputParameters == NULL) || (outputParameters == NULL) ) return paInvalidFlag; /* must use paFramesPerBufferUnspecified */ if( framesPerBuffer != paFramesPerBufferUnspecified ) return paInvalidFlag; } return paNoError; } PaError Pa_IsFormatSupported( const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { PaError result; PaUtilHostApiRepresentation *hostApi = 0; PaDeviceIndex hostApiInputDevice = paNoDevice, hostApiOutputDevice = paNoDevice; PaStreamParameters hostApiInputParameters, hostApiOutputParameters; PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr; #ifdef PA_LOG_API_CALLS PA_LOGAPI_ENTER_PARAMS( "Pa_IsFormatSupported" ); if( inputParameters == NULL ){ PA_LOGAPI(("\tPaStreamParameters *inputParameters: NULL\n" )); }else{ PA_LOGAPI(("\tPaStreamParameters *inputParameters: 0x%p\n", inputParameters )); PA_LOGAPI(("\tPaDeviceIndex inputParameters->device: %d\n", inputParameters->device )); PA_LOGAPI(("\tint inputParameters->channelCount: %d\n", inputParameters->channelCount )); PA_LOGAPI(("\tPaSampleFormat inputParameters->sampleFormat: %d\n", inputParameters->sampleFormat )); PA_LOGAPI(("\tPaTime inputParameters->suggestedLatency: %f\n", inputParameters->suggestedLatency )); PA_LOGAPI(("\tvoid *inputParameters->hostApiSpecificStreamInfo: 0x%p\n", inputParameters->hostApiSpecificStreamInfo )); } if( outputParameters == NULL ){ PA_LOGAPI(("\tPaStreamParameters *outputParameters: NULL\n" )); }else{ PA_LOGAPI(("\tPaStreamParameters *outputParameters: 0x%p\n", outputParameters )); PA_LOGAPI(("\tPaDeviceIndex outputParameters->device: %d\n", outputParameters->device )); PA_LOGAPI(("\tint outputParameters->channelCount: %d\n", outputParameters->channelCount )); PA_LOGAPI(("\tPaSampleFormat outputParameters->sampleFormat: %d\n", outputParameters->sampleFormat )); PA_LOGAPI(("\tPaTime outputParameters->suggestedLatency: %f\n", outputParameters->suggestedLatency )); PA_LOGAPI(("\tvoid *outputParameters->hostApiSpecificStreamInfo: 0x%p\n", outputParameters->hostApiSpecificStreamInfo )); } PA_LOGAPI(("\tdouble sampleRate: %g\n", sampleRate )); #endif if( !PA_IS_INITIALISED_ ) { result = paNotInitialized; PA_LOGAPI_EXIT_PAERROR( "Pa_IsFormatSupported", result ); return result; } result = ValidateOpenStreamParameters( inputParameters, outputParameters, sampleRate, 0, paNoFlag, 0, &hostApi, &hostApiInputDevice, &hostApiOutputDevice ); if( result != paNoError ) { PA_LOGAPI_EXIT_PAERROR( "Pa_IsFormatSupported", result ); return result; } if( inputParameters ) { hostApiInputParameters.device = hostApiInputDevice; hostApiInputParameters.channelCount = inputParameters->channelCount; hostApiInputParameters.sampleFormat = inputParameters->sampleFormat; hostApiInputParameters.suggestedLatency = inputParameters->suggestedLatency; hostApiInputParameters.hostApiSpecificStreamInfo = inputParameters->hostApiSpecificStreamInfo; hostApiInputParametersPtr = &hostApiInputParameters; } else { hostApiInputParametersPtr = NULL; } if( outputParameters ) { hostApiOutputParameters.device = hostApiOutputDevice; hostApiOutputParameters.channelCount = outputParameters->channelCount; hostApiOutputParameters.sampleFormat = outputParameters->sampleFormat; hostApiOutputParameters.suggestedLatency = outputParameters->suggestedLatency; hostApiOutputParameters.hostApiSpecificStreamInfo = outputParameters->hostApiSpecificStreamInfo; hostApiOutputParametersPtr = &hostApiOutputParameters; } else { hostApiOutputParametersPtr = NULL; } result = hostApi->IsFormatSupported( hostApi, hostApiInputParametersPtr, hostApiOutputParametersPtr, sampleRate ); #ifdef PA_LOG_API_CALLS PA_LOGAPI(("Pa_OpenStream returned:\n" )); if( result == paFormatIsSupported ) PA_LOGAPI(("\tPaError: 0 [ paFormatIsSupported ]\n" )); else PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); #endif return result; } PaError Pa_OpenStream( PaStream** stream, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ) { PaError result; PaUtilHostApiRepresentation *hostApi = 0; PaDeviceIndex hostApiInputDevice = paNoDevice, hostApiOutputDevice = paNoDevice; PaStreamParameters hostApiInputParameters, hostApiOutputParameters; PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr; #ifdef PA_LOG_API_CALLS PA_LOGAPI_ENTER_PARAMS( "Pa_OpenStream" ); PA_LOGAPI(("\tPaStream** stream: 0x%p\n", stream )); if( inputParameters == NULL ){ PA_LOGAPI(("\tPaStreamParameters *inputParameters: NULL\n" )); }else{ PA_LOGAPI(("\tPaStreamParameters *inputParameters: 0x%p\n", inputParameters )); PA_LOGAPI(("\tPaDeviceIndex inputParameters->device: %d\n", inputParameters->device )); PA_LOGAPI(("\tint inputParameters->channelCount: %d\n", inputParameters->channelCount )); PA_LOGAPI(("\tPaSampleFormat inputParameters->sampleFormat: %d\n", inputParameters->sampleFormat )); PA_LOGAPI(("\tPaTime inputParameters->suggestedLatency: %f\n", inputParameters->suggestedLatency )); PA_LOGAPI(("\tvoid *inputParameters->hostApiSpecificStreamInfo: 0x%p\n", inputParameters->hostApiSpecificStreamInfo )); } if( outputParameters == NULL ){ PA_LOGAPI(("\tPaStreamParameters *outputParameters: NULL\n" )); }else{ PA_LOGAPI(("\tPaStreamParameters *outputParameters: 0x%p\n", outputParameters )); PA_LOGAPI(("\tPaDeviceIndex outputParameters->device: %d\n", outputParameters->device )); PA_LOGAPI(("\tint outputParameters->channelCount: %d\n", outputParameters->channelCount )); PA_LOGAPI(("\tPaSampleFormat outputParameters->sampleFormat: %d\n", outputParameters->sampleFormat )); PA_LOGAPI(("\tPaTime outputParameters->suggestedLatency: %f\n", outputParameters->suggestedLatency )); PA_LOGAPI(("\tvoid *outputParameters->hostApiSpecificStreamInfo: 0x%p\n", outputParameters->hostApiSpecificStreamInfo )); } PA_LOGAPI(("\tdouble sampleRate: %g\n", sampleRate )); PA_LOGAPI(("\tunsigned long framesPerBuffer: %d\n", framesPerBuffer )); PA_LOGAPI(("\tPaStreamFlags streamFlags: 0x%x\n", streamFlags )); PA_LOGAPI(("\tPaStreamCallback *streamCallback: 0x%p\n", streamCallback )); PA_LOGAPI(("\tvoid *userData: 0x%p\n", userData )); #endif if( !PA_IS_INITIALISED_ ) { result = paNotInitialized; PA_LOGAPI(("Pa_OpenStream returned:\n" )); PA_LOGAPI(("\t*(PaStream** stream): undefined\n" )); PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); return result; } /* Check for parameter errors. NOTE: make sure this validation list is kept syncronised with the one in pa_hostapi.h */ if( stream == NULL ) { result = paBadStreamPtr; PA_LOGAPI(("Pa_OpenStream returned:\n" )); PA_LOGAPI(("\t*(PaStream** stream): undefined\n" )); PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); return result; } result = ValidateOpenStreamParameters( inputParameters, outputParameters, sampleRate, framesPerBuffer, streamFlags, streamCallback, &hostApi, &hostApiInputDevice, &hostApiOutputDevice ); if( result != paNoError ) { PA_LOGAPI(("Pa_OpenStream returned:\n" )); PA_LOGAPI(("\t*(PaStream** stream): undefined\n" )); PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); return result; } if( inputParameters ) { hostApiInputParameters.device = hostApiInputDevice; hostApiInputParameters.channelCount = inputParameters->channelCount; hostApiInputParameters.sampleFormat = inputParameters->sampleFormat; hostApiInputParameters.suggestedLatency = inputParameters->suggestedLatency; hostApiInputParameters.hostApiSpecificStreamInfo = inputParameters->hostApiSpecificStreamInfo; hostApiInputParametersPtr = &hostApiInputParameters; } else { hostApiInputParametersPtr = NULL; } if( outputParameters ) { hostApiOutputParameters.device = hostApiOutputDevice; hostApiOutputParameters.channelCount = outputParameters->channelCount; hostApiOutputParameters.sampleFormat = outputParameters->sampleFormat; hostApiOutputParameters.suggestedLatency = outputParameters->suggestedLatency; hostApiOutputParameters.hostApiSpecificStreamInfo = outputParameters->hostApiSpecificStreamInfo; hostApiOutputParametersPtr = &hostApiOutputParameters; } else { hostApiOutputParametersPtr = NULL; } result = hostApi->OpenStream( hostApi, stream, hostApiInputParametersPtr, hostApiOutputParametersPtr, sampleRate, framesPerBuffer, streamFlags, streamCallback, userData ); if( result == paNoError ) AddOpenStream( *stream ); PA_LOGAPI(("Pa_OpenStream returned:\n" )); PA_LOGAPI(("\t*(PaStream** stream): 0x%p\n", *stream )); PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); return result; } PaError Pa_OpenDefaultStream( PaStream** stream, int inputChannelCount, int outputChannelCount, PaSampleFormat sampleFormat, double sampleRate, unsigned long framesPerBuffer, PaStreamCallback *streamCallback, void *userData ) { PaError result; PaStreamParameters hostApiInputParameters, hostApiOutputParameters; PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr; PA_LOGAPI_ENTER_PARAMS( "Pa_OpenDefaultStream" ); PA_LOGAPI(("\tPaStream** stream: 0x%p\n", stream )); PA_LOGAPI(("\tint inputChannelCount: %d\n", inputChannelCount )); PA_LOGAPI(("\tint outputChannelCount: %d\n", outputChannelCount )); PA_LOGAPI(("\tPaSampleFormat sampleFormat: %d\n", sampleFormat )); PA_LOGAPI(("\tdouble sampleRate: %g\n", sampleRate )); PA_LOGAPI(("\tunsigned long framesPerBuffer: %d\n", framesPerBuffer )); PA_LOGAPI(("\tPaStreamCallback *streamCallback: 0x%p\n", streamCallback )); PA_LOGAPI(("\tvoid *userData: 0x%p\n", userData )); if( inputChannelCount > 0 ) { hostApiInputParameters.device = Pa_GetDefaultInputDevice(); if( hostApiInputParameters.device == paNoDevice ) return paDeviceUnavailable; hostApiInputParameters.channelCount = inputChannelCount; hostApiInputParameters.sampleFormat = sampleFormat; /* defaultHighInputLatency is used below instead of defaultLowInputLatency because it is more important for the default stream to work reliably than it is for it to work with the lowest latency. */ hostApiInputParameters.suggestedLatency = Pa_GetDeviceInfo( hostApiInputParameters.device )->defaultHighInputLatency; hostApiInputParameters.hostApiSpecificStreamInfo = NULL; hostApiInputParametersPtr = &hostApiInputParameters; } else { hostApiInputParametersPtr = NULL; } if( outputChannelCount > 0 ) { hostApiOutputParameters.device = Pa_GetDefaultOutputDevice(); if( hostApiOutputParameters.device == paNoDevice ) return paDeviceUnavailable; hostApiOutputParameters.channelCount = outputChannelCount; hostApiOutputParameters.sampleFormat = sampleFormat; /* defaultHighOutputLatency is used below instead of defaultLowOutputLatency because it is more important for the default stream to work reliably than it is for it to work with the lowest latency. */ hostApiOutputParameters.suggestedLatency = Pa_GetDeviceInfo( hostApiOutputParameters.device )->defaultHighOutputLatency; hostApiOutputParameters.hostApiSpecificStreamInfo = NULL; hostApiOutputParametersPtr = &hostApiOutputParameters; } else { hostApiOutputParametersPtr = NULL; } result = Pa_OpenStream( stream, hostApiInputParametersPtr, hostApiOutputParametersPtr, sampleRate, framesPerBuffer, paNoFlag, streamCallback, userData ); PA_LOGAPI(("Pa_OpenDefaultStream returned:\n" )); PA_LOGAPI(("\t*(PaStream** stream): 0x%p", *stream )); PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); return result; } PaError PaUtil_ValidateStreamPointer( PaStream* stream ) { if( !PA_IS_INITIALISED_ ) return paNotInitialized; if( stream == NULL ) return paBadStreamPtr; if( ((PaUtilStreamRepresentation*)stream)->magic != PA_STREAM_MAGIC ) return paBadStreamPtr; return paNoError; } PaError Pa_CloseStream( PaStream* stream ) { PaUtilStreamInterface *interface; PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_CloseStream" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); /* always remove the open stream from our list, even if this function eventually returns an error. Otherwise CloseOpenStreams() will get stuck in an infinite loop */ RemoveOpenStream( stream ); /* be sure to call this _before_ closing the stream */ if( result == paNoError ) { interface = PA_STREAM_INTERFACE(stream); /* abort the stream if it isn't stopped */ result = interface->IsStopped( stream ); if( result == 1 ) result = paNoError; else if( result == 0 ) result = interface->Abort( stream ); if( result == paNoError ) /** @todo REVIEW: shouldn't we close anyway? */ result = interface->Close( stream ); } PA_LOGAPI_EXIT_PAERROR( "Pa_CloseStream", result ); return result; } PaError Pa_SetStreamFinishedCallback( PaStream *stream, PaStreamFinishedCallback* streamFinishedCallback ) { PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_SetStreamFinishedCallback" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); PA_LOGAPI(("\tPaStreamFinishedCallback* streamFinishedCallback: 0x%p\n", streamFinishedCallback )); if( result == paNoError ) { result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); if( result == 0 ) { result = paStreamIsNotStopped ; } if( result == 1 ) { PA_STREAM_REP( stream )->streamFinishedCallback = streamFinishedCallback; result = paNoError; } } PA_LOGAPI_EXIT_PAERROR( "Pa_SetStreamFinishedCallback", result ); return result; } PaError Pa_StartStream( PaStream *stream ) { PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_StartStream" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( result == paNoError ) { result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); if( result == 0 ) { result = paStreamIsNotStopped ; } else if( result == 1 ) { result = PA_STREAM_INTERFACE(stream)->Start( stream ); } } PA_LOGAPI_EXIT_PAERROR( "Pa_StartStream", result ); return result; } PaError Pa_StopStream( PaStream *stream ) { PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_StopStream" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( result == paNoError ) { result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); if( result == 0 ) { result = PA_STREAM_INTERFACE(stream)->Stop( stream ); } else if( result == 1 ) { result = paStreamIsStopped; } } PA_LOGAPI_EXIT_PAERROR( "Pa_StopStream", result ); return result; } PaError Pa_AbortStream( PaStream *stream ) { PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_AbortStream" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( result == paNoError ) { result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); if( result == 0 ) { result = PA_STREAM_INTERFACE(stream)->Abort( stream ); } else if( result == 1 ) { result = paStreamIsStopped; } } PA_LOGAPI_EXIT_PAERROR( "Pa_AbortStream", result ); return result; } PaError Pa_IsStreamStopped( PaStream *stream ) { PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_IsStreamStopped" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( result == paNoError ) result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); PA_LOGAPI_EXIT_PAERROR( "Pa_IsStreamStopped", result ); return result; } PaError Pa_IsStreamActive( PaStream *stream ) { PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_IsStreamActive" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( result == paNoError ) result = PA_STREAM_INTERFACE(stream)->IsActive( stream ); PA_LOGAPI_EXIT_PAERROR( "Pa_IsStreamActive", result ); return result; } const PaStreamInfo* Pa_GetStreamInfo( PaStream *stream ) { PaError error = PaUtil_ValidateStreamPointer( stream ); const PaStreamInfo *result; PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamInfo" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( error != paNoError ) { result = 0; PA_LOGAPI(("Pa_GetStreamInfo returned:\n" )); PA_LOGAPI(("\tconst PaStreamInfo*: 0 [PaError error:%d ( %s )]\n", result, error, Pa_GetErrorText( error ) )); } else { result = &PA_STREAM_REP( stream )->streamInfo; PA_LOGAPI(("Pa_GetStreamInfo returned:\n" )); PA_LOGAPI(("\tconst PaStreamInfo*: 0x%p:\n", result )); PA_LOGAPI(("\t{" )); PA_LOGAPI(("\t\tint structVersion: %d\n", result->structVersion )); PA_LOGAPI(("\t\tPaTime inputLatency: %f\n", result->inputLatency )); PA_LOGAPI(("\t\tPaTime outputLatency: %f\n", result->outputLatency )); PA_LOGAPI(("\t\tdouble sampleRate: %f\n", result->sampleRate )); PA_LOGAPI(("\t}\n" )); } return result; } PaTime Pa_GetStreamTime( PaStream *stream ) { PaError error = PaUtil_ValidateStreamPointer( stream ); PaTime result; PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamTime" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( error != paNoError ) { result = 0; PA_LOGAPI(("Pa_GetStreamTime returned:\n" )); PA_LOGAPI(("\tPaTime: 0 [PaError error:%d ( %s )]\n", result, error, Pa_GetErrorText( error ) )); } else { result = PA_STREAM_INTERFACE(stream)->GetTime( stream ); PA_LOGAPI(("Pa_GetStreamTime returned:\n" )); PA_LOGAPI(("\tPaTime: %g\n", result )); } return result; } double Pa_GetStreamCpuLoad( PaStream* stream ) { PaError error = PaUtil_ValidateStreamPointer( stream ); double result; PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamCpuLoad" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( error != paNoError ) { result = 0.0; PA_LOGAPI(("Pa_GetStreamCpuLoad returned:\n" )); PA_LOGAPI(("\tdouble: 0.0 [PaError error: %d ( %s )]\n", error, Pa_GetErrorText( error ) )); } else { result = PA_STREAM_INTERFACE(stream)->GetCpuLoad( stream ); PA_LOGAPI(("Pa_GetStreamCpuLoad returned:\n" )); PA_LOGAPI(("\tdouble: %g\n", result )); } return result; } PaError Pa_ReadStream( PaStream* stream, void *buffer, unsigned long frames ) { PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_ReadStream" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( result == paNoError ) { if( frames == 0 ) { /* XXX: Should we not allow the implementation to signal any overflow condition? */ result = paNoError; } else if( buffer == 0 ) { result = paBadBufferPtr; } else { result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); if( result == 0 ) { result = PA_STREAM_INTERFACE(stream)->Read( stream, buffer, frames ); } else if( result == 1 ) { result = paStreamIsStopped; } } } PA_LOGAPI_EXIT_PAERROR( "Pa_ReadStream", result ); return result; } PaError Pa_WriteStream( PaStream* stream, const void *buffer, unsigned long frames ) { PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_WriteStream" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( result == paNoError ) { if( frames == 0 ) { /* XXX: Should we not allow the implementation to signal any underflow condition? */ result = paNoError; } else if( buffer == 0 ) { result = paBadBufferPtr; } else { result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); if( result == 0 ) { result = PA_STREAM_INTERFACE(stream)->Write( stream, buffer, frames ); } else if( result == 1 ) { result = paStreamIsStopped; } } } PA_LOGAPI_EXIT_PAERROR( "Pa_WriteStream", result ); return result; } signed long Pa_GetStreamReadAvailable( PaStream* stream ) { PaError error = PaUtil_ValidateStreamPointer( stream ); signed long result; PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamReadAvailable" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( error != paNoError ) { result = 0; PA_LOGAPI(("Pa_GetStreamReadAvailable returned:\n" )); PA_LOGAPI(("\tunsigned long: 0 [ PaError error: %d ( %s ) ]\n", error, Pa_GetErrorText( error ) )); } else { result = PA_STREAM_INTERFACE(stream)->GetReadAvailable( stream ); PA_LOGAPI(("Pa_GetStreamReadAvailable returned:\n" )); PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); } return result; } signed long Pa_GetStreamWriteAvailable( PaStream* stream ) { PaError error = PaUtil_ValidateStreamPointer( stream ); signed long result; PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamWriteAvailable" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( error != paNoError ) { result = 0; PA_LOGAPI(("Pa_GetStreamWriteAvailable returned:\n" )); PA_LOGAPI(("\tunsigned long: 0 [ PaError error: %d ( %s ) ]\n", error, Pa_GetErrorText( error ) )); } else { result = PA_STREAM_INTERFACE(stream)->GetWriteAvailable( stream ); PA_LOGAPI(("Pa_GetStreamWriteAvailable returned:\n" )); PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); } return result; } PaError Pa_GetSampleSize( PaSampleFormat format ) { int result; PA_LOGAPI_ENTER_PARAMS( "Pa_GetSampleSize" ); PA_LOGAPI(("\tPaSampleFormat format: %d\n", format )); switch( format & ~paNonInterleaved ) { case paUInt8: case paInt8: result = 1; break; case paInt16: result = 2; break; case paInt24: result = 3; break; case paFloat32: case paInt32: result = 4; break; default: result = paSampleFormatNotSupported; break; } PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetSampleSize", "int: %d", result ); return (PaError) result; } praat-6.0.04/external/portaudio2007/pa_hostapi.h000066400000000000000000000234411261542461700213650ustar00rootroot00000000000000#ifndef PA_HOSTAPI_H #define PA_HOSTAPI_H /* * $Id: pa_hostapi.h 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library * host api representation * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Interface used by pa_front to virtualize functions which operate on host APIs. */ #include "portaudio.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** **FOR THE USE OF pa_front.c ONLY** Do NOT use fields in this structure, they my change at any time. Use functions defined in pa_util.h if you think you need functionality which can be derived from here. */ typedef struct PaUtilPrivatePaFrontHostApiInfo { unsigned long baseDeviceIndex; }PaUtilPrivatePaFrontHostApiInfo; /** The common header for all data structures whose pointers are passed through the hostApiSpecificStreamInfo field of the PaStreamParameters structure. Note that in order to keep the public PortAudio interface clean, this structure is not used explicitly when declaring hostApiSpecificStreamInfo data structures. However, some code in pa_front depends on the first 3 members being equivalent with this structure. @see PaStreamParameters */ typedef struct PaUtilHostApiSpecificStreamInfoHeader { unsigned long size; /**< size of whole structure including this header */ PaHostApiTypeId hostApiType; /**< host API for which this data is intended */ unsigned long version; /**< structure version */ } PaUtilHostApiSpecificStreamInfoHeader; /** A structure representing the interface to a host API. Contains both concrete data and pointers to functions which implement the interface. */ typedef struct PaUtilHostApiRepresentation { PaUtilPrivatePaFrontHostApiInfo privatePaFrontInfo; /** The host api implementation should populate the info field. In the case of info.defaultInputDevice and info.defaultOutputDevice the values stored should be 0 based indices within the host api's own device index range (0 to deviceCount). These values will be converted to global device indices by pa_front after PaUtilHostApiInitializer() returns. */ PaHostApiInfo info; PaDeviceInfo** deviceInfos; /** (*Terminate)() is guaranteed to be called with a valid parameter, which was previously returned from the same implementation's initializer. */ void (*Terminate)( struct PaUtilHostApiRepresentation *hostApi ); /** The inputParameters and outputParameters pointers should not be saved as they will not remain valid after OpenStream is called. The following guarantees are made about parameters to (*OpenStream)(): [NOTE: the following list up to *END PA FRONT VALIDATIONS* should be kept in sync with the one for ValidateOpenStreamParameters and Pa_OpenStream in pa_front.c] PaHostApiRepresentation *hostApi - is valid for this implementation PaStream** stream - is non-null - at least one of inputParameters & outputParmeters is valid (not NULL) - if inputParameters & outputParmeters are both valid, that inputParameters->device & outputParmeters->device both use the same host api PaDeviceIndex inputParameters->device - is within range (0 to Pa_CountDevices-1) Or: - is paUseHostApiSpecificDeviceSpecification and inputParameters->hostApiSpecificStreamInfo is non-NULL and refers to a valid host api int inputParameters->numChannels - if inputParameters->device is not paUseHostApiSpecificDeviceSpecification, numInputChannels is > 0 - upper bound is NOT validated against device capabilities PaSampleFormat inputParameters->sampleFormat - is one of the sample formats defined in portaudio.h void *inputParameters->hostApiSpecificStreamInfo - if supplied its hostApi field matches the input device's host Api PaDeviceIndex outputParmeters->device - is within range (0 to Pa_CountDevices-1) int outputParmeters->numChannels - if inputDevice is valid, numInputChannels is > 0 - upper bound is NOT validated against device capabilities PaSampleFormat outputParmeters->sampleFormat - is one of the sample formats defined in portaudio.h void *outputParmeters->hostApiSpecificStreamInfo - if supplied its hostApi field matches the output device's host Api double sampleRate - is not an 'absurd' rate (less than 1000. or greater than 200000.) - sampleRate is NOT validated against device capabilities PaStreamFlags streamFlags - unused platform neutral flags are zero - paNeverDropInput is only used for full-duplex callback streams with variable buffer size (paFramesPerBufferUnspecified) [*END PA FRONT VALIDATIONS*] The following validations MUST be performed by (*OpenStream)(): - check that input device can support numInputChannels - check that input device can support inputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format - if inputStreamInfo is supplied, validate its contents, or return an error if no inputStreamInfo is expected - check that output device can support numOutputChannels - check that output device can support outputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format - if outputStreamInfo is supplied, validate its contents, or return an error if no outputStreamInfo is expected - if a full duplex stream is requested, check that the combination of input and output parameters is supported - check that the device supports sampleRate - alter sampleRate to a close allowable rate if necessary - validate inputLatency and outputLatency - validate any platform specific flags, if flags are supplied they must be valid. */ PaError (*OpenStream)( struct PaUtilHostApiRepresentation *hostApi, PaStream** stream, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerCallback, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); PaError (*IsFormatSupported)( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); } PaUtilHostApiRepresentation; /** Prototype for the initialization function which must be implemented by every host API. @see paHostApiInitializers */ typedef PaError PaUtilHostApiInitializer( PaUtilHostApiRepresentation**, PaHostApiIndex ); /** paHostApiInitializers is a NULL-terminated array of host API initialization functions. These functions are called by pa_front to initialize the host APIs when the client calls Pa_Initialize(). There is a platform specific file which defines paHostApiInitializers for that platform, pa_win/pa_win_hostapis.c contains the Win32 definitions for example. */ extern PaUtilHostApiInitializer *paHostApiInitializers[]; /** The index of the default host API in the paHostApiInitializers array. There is a platform specific file which defines paDefaultHostApiIndex for that platform, see pa_win/pa_win_hostapis.c for example. */ extern int paDefaultHostApiIndex; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_HOSTAPI_H */ praat-6.0.04/external/portaudio2007/pa_linux_alsa.c000066400000000000000000003677171261542461700220710ustar00rootroot00000000000000#if defined (UNIX) && defined (ALSA) /* * $Id: pa_linux_alsa.c 1278 2007-09-12 17:39:48Z aknudsen $ * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * ALSA implementation by Joshua Haberman and Arve Knudsen * * Copyright (c) 2002 Joshua Haberman * Copyright (c) 2005-2007 Arve Knudsen * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostapi_src */ #define ALSA_PCM_NEW_HW_PARAMS_API #define ALSA_PCM_NEW_SW_PARAMS_API #include #undef ALSA_PCM_NEW_HW_PARAMS_API #undef ALSA_PCM_NEW_SW_PARAMS_API #include #include /* strlen() */ #include #include #include #include #include #include #include /* For sig_atomic_t */ #include "portaudio.h" #include "pa_util.h" #include "pa_unix_util.h" #include "pa_allocation.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_cpuload.h" #include "pa_process.h" #include "pa_endianness.h" #include "pa_debugprint.h" #include "pa_linux_alsa.h" /* Check return value of ALSA function, and map it to PaError */ #define ENSURE_(expr, code) \ do { \ if( UNLIKELY( (aErr_ = (expr)) < 0 ) ) \ { \ /* PaUtil_SetLastHostErrorInfo should only be used in the main thread */ \ if( (code) == paUnanticipatedHostError && pthread_equal( pthread_self(), paUnixMainThread) ) \ { \ PaUtil_SetLastHostErrorInfo( paALSA, aErr_, snd_strerror( aErr_ ) ); \ } \ PaUtil_DebugPrint( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" ); \ if( (code) == paUnanticipatedHostError ) \ PA_DEBUG(( "Host error description: %s\n", snd_strerror( aErr_ ) )); \ result = (code); \ goto error; \ } \ } while( 0 ); #define ASSERT_CALL_(expr, success) \ aErr_ = (expr); \ assert( success == aErr_ ); static int aErr_; /* Used with ENSURE_ */ static int numPeriods_ = 4; int PaAlsa_SetNumPeriods( int numPeriods ) { numPeriods_ = numPeriods; return paNoError; } typedef enum { StreamDirection_In, StreamDirection_Out } StreamDirection; typedef struct { PaSampleFormat hostSampleFormat; unsigned long framesPerBuffer; int numUserChannels, numHostChannels; int userInterleaved, hostInterleaved; PaDeviceIndex device; /* Keep the device index */ snd_pcm_t *pcm; snd_pcm_uframes_t bufferSize; snd_pcm_format_t nativeFormat; unsigned int nfds; int ready; /* Marked ready from poll */ void **userBuffers; snd_pcm_uframes_t offset; StreamDirection streamDir; snd_pcm_channel_area_t *channelAreas; /* Needed for channel adaption */ } PaAlsaStreamComponent; /* Implementation specific stream structure */ typedef struct PaAlsaStream { PaUtilStreamRepresentation streamRepresentation; PaUtilCpuLoadMeasurer cpuLoadMeasurer; PaUtilBufferProcessor bufferProcessor; PaUnixThread thread; unsigned long framesPerUserBuffer, maxFramesPerHostBuffer; int primeBuffers; int callbackMode; /* bool: are we running in callback mode? */ int pcmsSynced; /* Have we successfully synced pcms */ int rtSched; /* the callback thread uses these to poll the sound device(s), waiting * for data to be ready/available */ struct pollfd* pfds; int pollTimeout; /* Used in communication between threads */ volatile sig_atomic_t callback_finished; /* bool: are we in the "callback finished" state? */ volatile sig_atomic_t callbackAbort; /* Drop frames? */ volatile sig_atomic_t isActive; /* Is stream in active state? (Between StartStream and StopStream || !paContinue) */ PaUnixMutex stateMtx; /* Used to synchronize access to stream state */ int neverDropInput; PaTime underrun; PaTime overrun; PaAlsaStreamComponent capture, playback; } PaAlsaStream; /* PaAlsaHostApiRepresentation - host api datastructure specific to this implementation */ typedef struct PaAlsaHostApiRepresentation { PaUtilHostApiRepresentation baseHostApiRep; PaUtilStreamInterface callbackStreamInterface; PaUtilStreamInterface blockingStreamInterface; PaUtilAllocationGroup *allocations; PaHostApiIndex hostApiIndex; } PaAlsaHostApiRepresentation; typedef struct PaAlsaDeviceInfo { PaDeviceInfo baseDeviceInfo; char *alsaName; int isPlug; int minInputChannels; int minOutputChannels; } PaAlsaDeviceInfo; /* prototypes for functions declared in this file */ static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *callback, void *userData ); static PaError CloseStream( PaStream* stream ); static PaError StartStream( PaStream *stream ); static PaError StopStream( PaStream *stream ); static PaError AbortStream( PaStream *stream ); static PaError IsStreamStopped( PaStream *s ); static PaError IsStreamActive( PaStream *stream ); static PaTime GetStreamTime( PaStream *stream ); static double GetStreamCpuLoad( PaStream* stream ); static PaError BuildDeviceList( PaAlsaHostApiRepresentation *hostApi ); static int SetApproximateSampleRate( snd_pcm_t *pcm, snd_pcm_hw_params_t *hwParams, double sampleRate ); static int GetExactSampleRate( snd_pcm_hw_params_t *hwParams, double *sampleRate ); /* Callback prototypes */ static void *CallbackThreadFunc( void *userData ); /* Blocking prototypes */ static signed long GetStreamReadAvailable( PaStream* s ); static signed long GetStreamWriteAvailable( PaStream* s ); static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ); static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ); static const PaAlsaDeviceInfo *GetDeviceInfo( const PaUtilHostApiRepresentation *hostApi, int device ) { return (const PaAlsaDeviceInfo *)hostApi->deviceInfos[device]; } static void AlsaErrorHandler(const char *file, int line, const char *function, int err, const char *fmt, ...) { } PaError PaAlsa_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) { PaError result = paNoError; PaAlsaHostApiRepresentation *alsaHostApi = NULL; PA_UNLESS( alsaHostApi = (PaAlsaHostApiRepresentation*) PaUtil_AllocateMemory( sizeof(PaAlsaHostApiRepresentation) ), paInsufficientMemory ); PA_UNLESS( alsaHostApi->allocations = PaUtil_CreateAllocationGroup(), paInsufficientMemory ); alsaHostApi->hostApiIndex = hostApiIndex; *hostApi = (PaUtilHostApiRepresentation*)alsaHostApi; (*hostApi)->info.structVersion = 1; (*hostApi)->info.type = paALSA; (*hostApi)->info.name = "ALSA"; (*hostApi)->Terminate = Terminate; (*hostApi)->OpenStream = OpenStream; (*hostApi)->IsFormatSupported = IsFormatSupported; ENSURE_( snd_lib_error_set_handler(AlsaErrorHandler), paUnanticipatedHostError ); PA_ENSURE( BuildDeviceList( alsaHostApi ) ); PaUtil_InitializeStreamInterface( &alsaHostApi->callbackStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, GetStreamCpuLoad, PaUtil_DummyRead, PaUtil_DummyWrite, PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); PaUtil_InitializeStreamInterface( &alsaHostApi->blockingStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, PaUtil_DummyGetCpuLoad, ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable ); PA_ENSURE( PaUnixThreading_Initialize() ); return result; error: if( alsaHostApi ) { if( alsaHostApi->allocations ) { PaUtil_FreeAllAllocations( alsaHostApi->allocations ); PaUtil_DestroyAllocationGroup( alsaHostApi->allocations ); } PaUtil_FreeMemory( alsaHostApi ); } return result; } static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) { PaAlsaHostApiRepresentation *alsaHostApi = (PaAlsaHostApiRepresentation*)hostApi; assert( hostApi ); if( alsaHostApi->allocations ) { PaUtil_FreeAllAllocations( alsaHostApi->allocations ); PaUtil_DestroyAllocationGroup( alsaHostApi->allocations ); } PaUtil_FreeMemory( alsaHostApi ); snd_config_update_free_global(); } /** Determine max channels and default latencies. * * This function provides functionality to grope an opened (might be opened for capture or playback) pcm device for * traits like max channels, suitable default latencies and default sample rate. Upon error, max channels is set to zero, * and a suitable result returned. The device is closed before returning. */ static PaError GropeDevice( snd_pcm_t* pcm, int isPlug, StreamDirection mode, int openBlocking, PaAlsaDeviceInfo* devInfo, int* canMmap ) { PaError result = paNoError; snd_pcm_hw_params_t *hwParams; snd_pcm_uframes_t lowLatency = 512, highLatency = 2048; unsigned int minChans, maxChans; int* minChannels, * maxChannels; double * defaultLowLatency, * defaultHighLatency, * defaultSampleRate = &devInfo->baseDeviceInfo.defaultSampleRate; double defaultSr = *defaultSampleRate; assert( pcm ); if( StreamDirection_In == mode ) { minChannels = &devInfo->minInputChannels; maxChannels = &devInfo->baseDeviceInfo.maxInputChannels; defaultLowLatency = &devInfo->baseDeviceInfo.defaultLowInputLatency; defaultHighLatency = &devInfo->baseDeviceInfo.defaultHighInputLatency; } else { minChannels = &devInfo->minOutputChannels; maxChannels = &devInfo->baseDeviceInfo.maxOutputChannels; defaultLowLatency = &devInfo->baseDeviceInfo.defaultLowOutputLatency; defaultHighLatency = &devInfo->baseDeviceInfo.defaultHighOutputLatency; } ENSURE_( snd_pcm_nonblock( pcm, 0 ), paUnanticipatedHostError ); snd_pcm_hw_params_alloca( &hwParams ); snd_pcm_hw_params_any( pcm, hwParams ); *canMmap = snd_pcm_hw_params_test_access( pcm, hwParams, SND_PCM_ACCESS_MMAP_INTERLEAVED ) >= 0 || snd_pcm_hw_params_test_access( pcm, hwParams, SND_PCM_ACCESS_MMAP_NONINTERLEAVED ) >= 0; if( defaultSr >= 0 ) { /* Could be that the device opened in one mode supports samplerates that the other mode wont have, * so try again .. */ if( SetApproximateSampleRate( pcm, hwParams, defaultSr ) < 0 ) { defaultSr = -1.; PA_DEBUG(( "%s: Original default samplerate failed, trying again ..\n", __FUNCTION__ )); } } if( defaultSr < 0. ) /* Default sample rate not set */ { unsigned int sampleRate = 44100; /* Will contain approximate rate returned by alsa-lib */ if( snd_pcm_hw_params_set_rate_near( pcm, hwParams, &sampleRate, NULL ) < 0) { result = paUnanticipatedHostError; goto error; } ENSURE_( GetExactSampleRate( hwParams, &defaultSr ), paUnanticipatedHostError ); } ENSURE_( snd_pcm_hw_params_get_channels_min( hwParams, &minChans ), paUnanticipatedHostError ); ENSURE_( snd_pcm_hw_params_get_channels_max( hwParams, &maxChans ), paUnanticipatedHostError ); assert( maxChans <= INT_MAX ); assert( maxChans > 0 ); /* Weird linking issue could cause wrong version of ALSA symbols to be called, resulting in zeroed values */ /* XXX: Limit to sensible number (ALSA plugins accept a crazy amount of channels)? */ if( isPlug && maxChans > 128 ) { maxChans = 128; PA_DEBUG(( "%s: Limiting number of plugin channels to %u\n", __FUNCTION__, maxChans )); } /* TWEAKME: * * Giving values for default min and max latency is not * straightforward. Here are our objectives: * * * for low latency, we want to give the lowest value * that will work reliably. This varies based on the * sound card, kernel, CPU, etc. I think it is better * to give sub-optimal latency than to give a number * too low and cause dropouts. My conservative * estimate at this point is to base it on 4096-sample * latency at 44.1 kHz, which gives a latency of 23ms. * * for high latency we want to give a large enough * value that dropouts are basically impossible. This * doesn't really require as much tweaking, since * providing too large a number will just cause us to * select the nearest setting that will work at stream * config time. */ ENSURE_( snd_pcm_hw_params_set_buffer_size_near( pcm, hwParams, &lowLatency ), paUnanticipatedHostError ); /* Have to reset hwParams, to set new buffer size */ ENSURE_( snd_pcm_hw_params_any( pcm, hwParams ), paUnanticipatedHostError ); ENSURE_( snd_pcm_hw_params_set_buffer_size_near( pcm, hwParams, &highLatency ), paUnanticipatedHostError ); *minChannels = (int)minChans; *maxChannels = (int)maxChans; *defaultSampleRate = defaultSr; *defaultLowLatency = (double) lowLatency / *defaultSampleRate; *defaultHighLatency = (double) highLatency / *defaultSampleRate; end: snd_pcm_close( pcm ); return result; error: goto end; } /* Initialize device info with invalid values (maxInputChannels and maxOutputChannels are set to zero since these indicate * wether input/output is available) */ static void InitializeDeviceInfo( PaDeviceInfo *deviceInfo ) { deviceInfo->structVersion = -1; deviceInfo->name = NULL; deviceInfo->hostApi = -1; deviceInfo->maxInputChannels = 0; deviceInfo->maxOutputChannels = 0; deviceInfo->defaultLowInputLatency = -1.; deviceInfo->defaultLowOutputLatency = -1.; deviceInfo->defaultHighInputLatency = -1.; deviceInfo->defaultHighOutputLatency = -1.; deviceInfo->defaultSampleRate = -1.; } /* Helper struct */ typedef struct { char *alsaName; char *name; int isPlug; int hasPlayback; int hasCapture; } HwDevInfo; HwDevInfo predefinedNames[] = { { "center_lfe", NULL, 0, 1, 0 }, /* { "default", NULL, 0, 1, 0 }, */ /* { "dmix", NULL, 0, 1, 0 }, */ /* { "dpl", NULL, 0, 1, 0 }, */ /* { "dsnoop", NULL, 0, 1, 0 }, */ { "front", NULL, 0, 1, 0 }, { "iec958", NULL, 0, 1, 0 }, /* { "modem", NULL, 0, 1, 0 }, */ { "rear", NULL, 0, 1, 0 }, { "side", NULL, 0, 1, 0 }, /* { "spdif", NULL, 0, 0, 0 }, */ { "surround40", NULL, 0, 1, 0 }, { "surround41", NULL, 0, 1, 0 }, { "surround50", NULL, 0, 1, 0 }, { "surround51", NULL, 0, 1, 0 }, { "surround71", NULL, 0, 1, 0 }, { NULL, NULL, 0, 1, 0 } }; static const HwDevInfo *FindDeviceName( const char *name ) { int i; for( i = 0; predefinedNames[i].alsaName; i++ ) { if( strcmp( name, predefinedNames[i].alsaName ) == 0 ) { return &predefinedNames[i]; } } return NULL; } static PaError PaAlsa_StrDup( PaAlsaHostApiRepresentation *alsaApi, char **dst, const char *src) { PaError result = paNoError; int len = strlen( src ) + 1; /* PA_DEBUG(("PaStrDup %s %d\n", src, len)); */ PA_UNLESS( *dst = (char *)PaUtil_GroupAllocateMemory( alsaApi->allocations, len ), paInsufficientMemory ); strncpy( *dst, src, len ); error: return result; } /* Disregard some standard plugins */ static int IgnorePlugin( const char *pluginId ) { static const char *ignoredPlugins[] = {"hw", "plughw", "plug", "dsnoop", "tee", "file", "null", "shm", "cards", "rate_convert", NULL}; int i = 0; while( ignoredPlugins[i] ) { if( !strcmp( pluginId, ignoredPlugins[i] ) ) { return 1; } ++i; } return 0; } /** Open PCM device. * * Wrapper around snd_pcm_open which may repeatedly retry opening a device if it is busy, for * a certain time. This is because dmix may temporarily hold on to a device after it (dmix) * has been opened and closed. * @param mode: Open mode (e.g., SND_PCM_BLOCKING). * @param waitOnBusy: Retry opening busy device for up to one second? **/ static int OpenPcm( snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t stream, int mode, int waitOnBusy ) { int tries = 0, maxTries = waitOnBusy ? 100 : 0; int ret = snd_pcm_open( pcmp, name, stream, mode ); for( tries = 0; tries < maxTries && -EBUSY == ret; ++tries ) { Pa_Sleep( 10 ); ret = snd_pcm_open( pcmp, name, stream, mode ); if( -EBUSY != ret ) { PA_DEBUG(( "%s: Successfully opened initially busy device after %d tries\n", __FUNCTION__, tries )); } } if( -EBUSY == ret ) { PA_DEBUG(( "%s: Failed to open busy device '%s'\n", __FUNCTION__, name )); } return ret; } static PaError FillInDevInfo( PaAlsaHostApiRepresentation *alsaApi, HwDevInfo* deviceName, int blocking, PaAlsaDeviceInfo* devInfo, int* devIdx ) { PaError result = 0; PaDeviceInfo *baseDeviceInfo = &devInfo->baseDeviceInfo; snd_pcm_t *pcm; int canMmap = -1; PaUtilHostApiRepresentation *baseApi = &alsaApi->baseHostApiRep; /* Zero fields */ InitializeDeviceInfo( baseDeviceInfo ); /* to determine device capabilities, we must open the device and query the * hardware parameter configuration space */ /* Query capture */ if( deviceName->hasCapture && OpenPcm( &pcm, deviceName->alsaName, SND_PCM_STREAM_CAPTURE, blocking, 0 ) >= 0 ) { if( GropeDevice( pcm, deviceName->isPlug, StreamDirection_In, blocking, devInfo, &canMmap ) != paNoError ) { /* Error */ PA_DEBUG(("%s: Failed groping %s for capture\n", __FUNCTION__, deviceName->alsaName)); goto end; } } /* Query playback */ if( deviceName->hasPlayback && OpenPcm( &pcm, deviceName->alsaName, SND_PCM_STREAM_PLAYBACK, blocking, 0 ) >= 0 ) { if( GropeDevice( pcm, deviceName->isPlug, StreamDirection_Out, blocking, devInfo, &canMmap ) != paNoError ) { /* Error */ PA_DEBUG(("%s: Failed groping %s for playback\n", __FUNCTION__, deviceName->alsaName)); goto end; } } if( 0 == canMmap ) { PA_DEBUG(("%s: Device %s doesn't support mmap\n", __FUNCTION__, deviceName->alsaName)); goto end; } baseDeviceInfo->structVersion = 2; baseDeviceInfo->hostApi = alsaApi->hostApiIndex; baseDeviceInfo->name = deviceName->name; devInfo->alsaName = deviceName->alsaName; devInfo->isPlug = deviceName->isPlug; /* A: Storing pointer to PaAlsaDeviceInfo object as pointer to PaDeviceInfo object. * Should now be safe to add device info, unless the device supports neither capture nor playback */ if( baseDeviceInfo->maxInputChannels > 0 || baseDeviceInfo->maxOutputChannels > 0 ) { /* Make device default if there isn't already one or it is the ALSA "default" device */ if( (baseApi->info.defaultInputDevice == paNoDevice || !strcmp(deviceName->alsaName, "default" )) && baseDeviceInfo->maxInputChannels > 0 ) { baseApi->info.defaultInputDevice = *devIdx; PA_DEBUG(("Default input device: %s\n", deviceName->name)); } if( (baseApi->info.defaultOutputDevice == paNoDevice || !strcmp(deviceName->alsaName, "default" )) && baseDeviceInfo->maxOutputChannels > 0 ) { baseApi->info.defaultOutputDevice = *devIdx; PA_DEBUG(("Default output device: %s\n", deviceName->name)); } PA_DEBUG(("%s: Adding device %s: %d\n", __FUNCTION__, deviceName->name, *devIdx)); baseApi->deviceInfos[*devIdx] = (PaDeviceInfo *) devInfo; (*devIdx) += 1; } end: return result; } /* Build PaDeviceInfo list, ignore devices for which we cannot determine capabilities (possibly busy, sigh) */ static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi ) { PaUtilHostApiRepresentation *baseApi = &alsaApi->baseHostApiRep; PaAlsaDeviceInfo *deviceInfoArray; int cardIdx = -1, devIdx = 0; snd_ctl_card_info_t *cardInfo; PaError result = paNoError; size_t numDeviceNames = 0, maxDeviceNames = 1, i; HwDevInfo *hwDevInfos = NULL; snd_config_t *topNode = NULL; snd_pcm_info_t *pcmInfo; int res; int blocking = SND_PCM_NONBLOCK; char alsaCardName[50]; #ifdef PA_ENABLE_DEBUG_OUTPUT PaTime startTime = PaUtil_GetTime(); #endif if( getenv( "PA_ALSA_INITIALIZE_BLOCK" ) && atoi( getenv( "PA_ALSA_INITIALIZE_BLOCK" ) ) ) blocking = 0; /* These two will be set to the first working input and output device, respectively */ baseApi->info.defaultInputDevice = paNoDevice; baseApi->info.defaultOutputDevice = paNoDevice; /* Gather info about hw devices * snd_card_next() modifies the integer passed to it to be: * the index of the first card if the parameter is -1 * the index of the next card if the parameter is the index of a card * -1 if there are no more cards * * The function itself returns 0 if it succeeded. */ cardIdx = -1; snd_ctl_card_info_alloca( &cardInfo ); snd_pcm_info_alloca( &pcmInfo ); while( snd_card_next( &cardIdx ) == 0 && cardIdx >= 0 ) { char *cardName; int devIdx = -1; snd_ctl_t *ctl; char buf[50]; snprintf( alsaCardName, sizeof (alsaCardName), "hw:%d", cardIdx ); /* Acquire name of card */ if( snd_ctl_open( &ctl, alsaCardName, 0 ) < 0 ) { /* Unable to open card :( */ PA_DEBUG(( "%s: Unable to open device %s\n", __FUNCTION__, alsaCardName )); continue; } snd_ctl_card_info( ctl, cardInfo ); PA_ENSURE( PaAlsa_StrDup( alsaApi, &cardName, snd_ctl_card_info_get_name( cardInfo )) ); while( snd_ctl_pcm_next_device( ctl, &devIdx ) == 0 && devIdx >= 0 ) { char *alsaDeviceName, *deviceName; size_t len; int hasPlayback = 0, hasCapture = 0; snprintf( buf, sizeof (buf), "hw:%d,%d", cardIdx, devIdx ); /* Obtain info about this particular device */ snd_pcm_info_set_device( pcmInfo, devIdx ); snd_pcm_info_set_subdevice( pcmInfo, 0 ); snd_pcm_info_set_stream( pcmInfo, SND_PCM_STREAM_CAPTURE ); if( snd_ctl_pcm_info( ctl, pcmInfo ) >= 0 ) { hasCapture = 1; } snd_pcm_info_set_stream( pcmInfo, SND_PCM_STREAM_PLAYBACK ); if( snd_ctl_pcm_info( ctl, pcmInfo ) >= 0 ) { hasPlayback = 1; } if( !hasPlayback && !hasCapture ) { /* Error */ continue; } /* The length of the string written by snprintf plus terminating 0 */ len = snprintf( NULL, 0, "%s: %s (%s)", cardName, snd_pcm_info_get_name( pcmInfo ), buf ) + 1; PA_UNLESS( deviceName = (char *)PaUtil_GroupAllocateMemory( alsaApi->allocations, len ), paInsufficientMemory ); snprintf( deviceName, len, "%s: %s (%s)", cardName, snd_pcm_info_get_name( pcmInfo ), buf ); ++numDeviceNames; if( !hwDevInfos || numDeviceNames > maxDeviceNames ) { maxDeviceNames *= 2; PA_UNLESS( hwDevInfos = (HwDevInfo *) realloc( hwDevInfos, maxDeviceNames * sizeof (HwDevInfo) ), paInsufficientMemory ); } PA_ENSURE( PaAlsa_StrDup( alsaApi, &alsaDeviceName, buf ) ); hwDevInfos[ numDeviceNames - 1 ].alsaName = alsaDeviceName; hwDevInfos[ numDeviceNames - 1 ].name = deviceName; hwDevInfos[ numDeviceNames - 1 ].isPlug = 0; hwDevInfos[ numDeviceNames - 1 ].hasPlayback = hasPlayback; hwDevInfos[ numDeviceNames - 1 ].hasCapture = hasCapture; } snd_ctl_close( ctl ); } /* Iterate over plugin devices */ if( NULL == snd_config ) { /* snd_config_update is called implicitly by some functions, if this hasn't happened snd_config will be NULL (bleh) */ ENSURE_( snd_config_update(), paUnanticipatedHostError ); PA_DEBUG(( "Updating snd_config\n" )); } assert( snd_config ); if( (res = snd_config_search( snd_config, "pcm", &topNode )) >= 0 ) { snd_config_iterator_t i, next; snd_config_for_each( i, next, topNode ) { const char *tpStr = "unknown", *idStr = NULL; int err = 0; char *alsaDeviceName, *deviceName; const HwDevInfo *predefined = NULL; snd_config_t *n = snd_config_iterator_entry( i ), * tp = NULL;; if( (err = snd_config_search( n, "type", &tp )) < 0 ) { if( -ENOENT != err ) { ENSURE_(err, paUnanticipatedHostError); } } else { ENSURE_( snd_config_get_string( tp, &tpStr ), paUnanticipatedHostError ); } ENSURE_( snd_config_get_id( n, &idStr ), paUnanticipatedHostError ); if( IgnorePlugin( idStr ) ) { PA_DEBUG(( "%s: Ignoring ALSA plugin device %s of type %s\n", __FUNCTION__, idStr, tpStr )); continue; } PA_DEBUG(( "%s: Found plugin %s of type %s\n", __FUNCTION__, idStr, tpStr )); PA_UNLESS( alsaDeviceName = (char*)PaUtil_GroupAllocateMemory( alsaApi->allocations, strlen(idStr) + 6 ), paInsufficientMemory ); strcpy( alsaDeviceName, idStr ); PA_UNLESS( deviceName = (char*)PaUtil_GroupAllocateMemory( alsaApi->allocations, strlen(idStr) + 1 ), paInsufficientMemory ); strcpy( deviceName, idStr ); ++numDeviceNames; if( !hwDevInfos || numDeviceNames > maxDeviceNames ) { maxDeviceNames *= 2; PA_UNLESS( hwDevInfos = (HwDevInfo *) realloc( hwDevInfos, maxDeviceNames * sizeof (HwDevInfo) ), paInsufficientMemory ); } predefined = FindDeviceName( alsaDeviceName ); hwDevInfos[numDeviceNames - 1].alsaName = alsaDeviceName; hwDevInfos[numDeviceNames - 1].name = deviceName; hwDevInfos[numDeviceNames - 1].isPlug = 1; if( predefined ) { hwDevInfos[numDeviceNames - 1].hasPlayback = predefined->hasPlayback; hwDevInfos[numDeviceNames - 1].hasCapture = predefined->hasCapture; } else { hwDevInfos[numDeviceNames - 1].hasPlayback = 1; hwDevInfos[numDeviceNames - 1].hasCapture = 1; } } } else PA_DEBUG(( "%s: Iterating over ALSA plugins failed: %s\n", __FUNCTION__, snd_strerror( res ) )); /* allocate deviceInfo memory based on the number of devices */ PA_UNLESS( baseApi->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( alsaApi->allocations, sizeof(PaDeviceInfo*) * (numDeviceNames) ), paInsufficientMemory ); /* allocate all device info structs in a contiguous block */ PA_UNLESS( deviceInfoArray = (PaAlsaDeviceInfo*)PaUtil_GroupAllocateMemory( alsaApi->allocations, sizeof(PaAlsaDeviceInfo) * numDeviceNames ), paInsufficientMemory ); /* Loop over list of cards, filling in info. If a device is deemed unavailable (can't get name), * it's ignored. * * Note that we do this in two stages. This is a workaround owing to the fact that the 'dmix' * plugin may cause the underlying hardware device to be busy for a short while even after it * (dmix) is closed. The 'default' plugin may also point to the dmix plugin, so the same goes * for this. */ for( i = 0, devIdx = 0; i < numDeviceNames; ++i ) { PaAlsaDeviceInfo* devInfo = &deviceInfoArray[i]; HwDevInfo* hwInfo = &hwDevInfos[i]; if( !strcmp( hwInfo->name, "dmix" ) || !strcmp( hwInfo->name, "default" ) ) { continue; } PA_ENSURE( FillInDevInfo( alsaApi, hwInfo, blocking, devInfo, &devIdx ) ); } assert( devIdx < numDeviceNames ); /* Now inspect 'dmix' and 'default' plugins */ for( i = 0; i < numDeviceNames; ++i ) { PaAlsaDeviceInfo* devInfo = &deviceInfoArray[i]; HwDevInfo* hwInfo = &hwDevInfos[i]; if( strcmp( hwInfo->name, "dmix" ) && strcmp( hwInfo->name, "default" ) ) { continue; } PA_ENSURE( FillInDevInfo( alsaApi, hwInfo, blocking, devInfo, &devIdx ) ); } free( hwDevInfos ); baseApi->info.deviceCount = devIdx; /* Number of successfully queried devices */ #ifdef PA_ENABLE_DEBUG_OUTPUT PA_DEBUG(( "%s: Building device list took %f seconds\n", __FUNCTION__, PaUtil_GetTime() - startTime )); #endif end: return result; error: /* No particular action */ goto end; } /* Check against known device capabilities */ static PaError ValidateParameters( const PaStreamParameters *parameters, PaUtilHostApiRepresentation *hostApi, StreamDirection mode ) { PaError result = paNoError; int maxChans; const PaAlsaDeviceInfo *deviceInfo = NULL; assert( parameters ); if( parameters->device != paUseHostApiSpecificDeviceSpecification ) { assert( parameters->device < hostApi->info.deviceCount ); PA_UNLESS( parameters->hostApiSpecificStreamInfo == NULL, paBadIODeviceCombination ); deviceInfo = GetDeviceInfo( hostApi, parameters->device ); } else { const PaAlsaStreamInfo *streamInfo = parameters->hostApiSpecificStreamInfo; PA_UNLESS( parameters->device == paUseHostApiSpecificDeviceSpecification, paInvalidDevice ); PA_UNLESS( streamInfo->size == sizeof (PaAlsaStreamInfo) && streamInfo->version == 1, paIncompatibleHostApiSpecificStreamInfo ); PA_UNLESS( streamInfo->deviceString != NULL, paInvalidDevice ); /* Skip further checking */ return paNoError; } assert( deviceInfo ); assert( parameters->hostApiSpecificStreamInfo == NULL ); maxChans = (StreamDirection_In == mode ? deviceInfo->baseDeviceInfo.maxInputChannels : deviceInfo->baseDeviceInfo.maxOutputChannels); PA_UNLESS( parameters->channelCount <= maxChans, paInvalidChannelCount ); error: return result; } /* Given an open stream, what sample formats are available? */ static PaSampleFormat GetAvailableFormats( snd_pcm_t *pcm ) { PaSampleFormat available = 0; snd_pcm_hw_params_t *hwParams; snd_pcm_hw_params_alloca( &hwParams ); snd_pcm_hw_params_any( pcm, hwParams ); if( snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_FLOAT ) >= 0) available |= paFloat32; if( snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S32 ) >= 0) available |= paInt32; #ifdef PA_LITTLE_ENDIAN if( snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3LE ) >= 0) available |= paInt24; #elif defined PA_BIG_ENDIAN if( snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3BE ) >= 0) available |= paInt24; #endif if( snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S16 ) >= 0) available |= paInt16; if( snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U8 ) >= 0) available |= paUInt8; if( snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S8 ) >= 0) available |= paInt8; return available; } static snd_pcm_format_t Pa2AlsaFormat( PaSampleFormat paFormat ) { switch( paFormat ) { case paFloat32: return SND_PCM_FORMAT_FLOAT; case paInt16: return SND_PCM_FORMAT_S16; case paInt24: #ifdef PA_LITTLE_ENDIAN return SND_PCM_FORMAT_S24_3LE; #elif defined PA_BIG_ENDIAN return SND_PCM_FORMAT_S24_3BE; #endif case paInt32: return SND_PCM_FORMAT_S32; case paInt8: return SND_PCM_FORMAT_S8; case paUInt8: return SND_PCM_FORMAT_U8; default: return SND_PCM_FORMAT_UNKNOWN; } } /** Open an ALSA pcm handle. * * The device to be open can be specified in a custom PaAlsaStreamInfo struct, or it will be a device number. In case of a * device number, it maybe specified through an env variable (PA_ALSA_PLUGHW) that we should open the corresponding plugin * device. */ static PaError AlsaOpen( const PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *params, StreamDirection streamDir, snd_pcm_t **pcm ) { PaError result = paNoError; int ret; char dnameArray[50]; const char* deviceName = dnameArray; const PaAlsaDeviceInfo *deviceInfo = NULL; PaAlsaStreamInfo *streamInfo = (PaAlsaStreamInfo *)params->hostApiSpecificStreamInfo; if( !streamInfo ) { int usePlug = 0; deviceInfo = GetDeviceInfo( hostApi, params->device ); /* If device name starts with hw: and PA_ALSA_PLUGHW is 1, we open the plughw device instead */ if( !strncmp( "hw:", deviceInfo->alsaName, 3 ) && getenv( "PA_ALSA_PLUGHW" ) ) usePlug = atoi( getenv( "PA_ALSA_PLUGHW" ) ); if( usePlug ) snprintf( dnameArray, 50, "plug%s", deviceInfo->alsaName ); else deviceName = deviceInfo->alsaName; } else deviceName = streamInfo->deviceString; PA_DEBUG(( "%s: Opening device %s\n", __FUNCTION__, deviceName )); if( (ret = OpenPcm( pcm, deviceName, streamDir == StreamDirection_In ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK, 1 )) < 0 ) { /* Not to be closed */ *pcm = NULL; ENSURE_( ret, -EBUSY == ret ? paDeviceUnavailable : paBadIODeviceCombination ); } ENSURE_( snd_pcm_nonblock( *pcm, 0 ), paUnanticipatedHostError ); end: return result; error: goto end; } static PaError TestParameters( const PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *parameters, double sampleRate, StreamDirection streamDir ) { PaError result = paNoError; snd_pcm_t *pcm = NULL; PaSampleFormat availableFormats; /* We are able to adapt to a number of channels less than what the device supports */ unsigned int numHostChannels; PaSampleFormat hostFormat; snd_pcm_hw_params_t *hwParams; snd_pcm_hw_params_alloca( &hwParams ); if( !parameters->hostApiSpecificStreamInfo ) { const PaAlsaDeviceInfo *devInfo = GetDeviceInfo( hostApi, parameters->device ); numHostChannels = PA_MAX( parameters->channelCount, StreamDirection_In == streamDir ? devInfo->minInputChannels : devInfo->minOutputChannels ); } else numHostChannels = parameters->channelCount; PA_ENSURE( AlsaOpen( hostApi, parameters, streamDir, &pcm ) ); snd_pcm_hw_params_any( pcm, hwParams ); if( SetApproximateSampleRate( pcm, hwParams, sampleRate ) < 0 ) { result = paInvalidSampleRate; goto error; } if( snd_pcm_hw_params_set_channels( pcm, hwParams, numHostChannels ) < 0 ) { result = paInvalidChannelCount; goto error; } /* See if we can find a best possible match */ availableFormats = GetAvailableFormats( pcm ); PA_ENSURE( hostFormat = PaUtil_SelectClosestAvailableFormat( availableFormats, parameters->sampleFormat ) ); ENSURE_( snd_pcm_hw_params_set_format( pcm, hwParams, Pa2AlsaFormat( hostFormat ) ), paUnanticipatedHostError ); { /* It happens that this call fails because the device is busy */ int ret = 0; if( (ret = snd_pcm_hw_params( pcm, hwParams )) < 0) { if( -EINVAL == ret ) { /* Don't know what to return here */ result = paBadIODeviceCombination; goto error; } else if( -EBUSY == ret ) { result = paDeviceUnavailable; PA_DEBUG(( "%s: Device is busy\n", __FUNCTION__ )); } else { result = paUnanticipatedHostError; } ENSURE_( ret, result ); } } end: if( pcm ) { snd_pcm_close( pcm ); } return result; error: goto end; } static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { int inputChannelCount = 0, outputChannelCount = 0; PaSampleFormat inputSampleFormat, outputSampleFormat; PaError result = paFormatIsSupported; if( inputParameters ) { PA_ENSURE( ValidateParameters( inputParameters, hostApi, StreamDirection_In ) ); inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; } if( outputParameters ) { PA_ENSURE( ValidateParameters( outputParameters, hostApi, StreamDirection_Out ) ); outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; } if( inputChannelCount ) { if( (result = TestParameters( hostApi, inputParameters, sampleRate, StreamDirection_In )) != paNoError ) goto error; } if ( outputChannelCount ) { if( (result = TestParameters( hostApi, outputParameters, sampleRate, StreamDirection_Out )) != paNoError ) goto error; } return paFormatIsSupported; error: return result; } static PaError PaAlsaStreamComponent_Initialize( PaAlsaStreamComponent *self, PaAlsaHostApiRepresentation *alsaApi, const PaStreamParameters *params, StreamDirection streamDir, int callbackMode ) { PaError result = paNoError; PaSampleFormat userSampleFormat = params->sampleFormat, hostSampleFormat; assert( params->channelCount > 0 ); /* Make sure things have an initial value */ memset( self, 0, sizeof (PaAlsaStreamComponent) ); if( NULL == params->hostApiSpecificStreamInfo ) { const PaAlsaDeviceInfo *devInfo = GetDeviceInfo( &alsaApi->baseHostApiRep, params->device ); self->numHostChannels = PA_MAX( params->channelCount, StreamDirection_In == streamDir ? devInfo->minInputChannels : devInfo->minOutputChannels ); } else { /* We're blissfully unaware of the minimum channelCount */ self->numHostChannels = params->channelCount; } self->device = params->device; PA_ENSURE( AlsaOpen( &alsaApi->baseHostApiRep, params, streamDir, &self->pcm ) ); self->nfds = snd_pcm_poll_descriptors_count( self->pcm ); hostSampleFormat = PaUtil_SelectClosestAvailableFormat( GetAvailableFormats( self->pcm ), userSampleFormat ); self->hostSampleFormat = hostSampleFormat; self->nativeFormat = Pa2AlsaFormat( hostSampleFormat ); self->hostInterleaved = self->userInterleaved = !(userSampleFormat & paNonInterleaved); self->numUserChannels = params->channelCount; self->streamDir = streamDir; if( !callbackMode && !self->userInterleaved ) { /* Pre-allocate non-interleaved user provided buffers */ PA_UNLESS( self->userBuffers = PaUtil_AllocateMemory( sizeof (void *) * self->numUserChannels ), paInsufficientMemory ); } error: return result; } static void PaAlsaStreamComponent_Terminate( PaAlsaStreamComponent *self ) { snd_pcm_close( self->pcm ); if( self->userBuffers ) PaUtil_FreeMemory( self->userBuffers ); } /* static int nearbyint_(float value) { if( value - (int)value > .5 ) return (int)ceil( value ); return (int)floor( value ); } */ /** Initiate configuration, preparing for determining a period size suitable for both capture and playback components. * */ static PaError PaAlsaStreamComponent_InitialConfigure( PaAlsaStreamComponent *self, const PaStreamParameters *params, int primeBuffers, snd_pcm_hw_params_t *hwParams, double *sampleRate ) { /* Configuration consists of setting all of ALSA's parameters. * These parameters come in two flavors: hardware parameters * and software paramters. Hardware parameters will affect * the way the device is initialized, software parameters * affect the way ALSA interacts with me, the user-level client. */ PaError result = paNoError; snd_pcm_access_t accessMode, alternateAccessMode; int dir = 0; snd_pcm_t *pcm = self->pcm; double sr = *sampleRate; unsigned int minPeriods = 2; /* self->framesPerBuffer = framesPerHostBuffer; */ /* ... fill up the configuration space with all possibile * combinations of parameters this device will accept */ ENSURE_( snd_pcm_hw_params_any( pcm, hwParams ), paUnanticipatedHostError ); ENSURE_( snd_pcm_hw_params_set_periods_integer( pcm, hwParams ), paUnanticipatedHostError ); /* I think there should be at least 2 periods (even though ALSA doesn't appear to enforce this) */ dir = 0; ENSURE_( snd_pcm_hw_params_set_periods_min( pcm, hwParams, &minPeriods, &dir ), paUnanticipatedHostError ); if( self->userInterleaved ) { accessMode = SND_PCM_ACCESS_MMAP_INTERLEAVED; alternateAccessMode = SND_PCM_ACCESS_MMAP_NONINTERLEAVED; } else { accessMode = SND_PCM_ACCESS_MMAP_NONINTERLEAVED; alternateAccessMode = SND_PCM_ACCESS_MMAP_INTERLEAVED; } /* If requested access mode fails, try alternate mode */ if( snd_pcm_hw_params_set_access( pcm, hwParams, accessMode ) < 0 ) { int err = 0; if( (err = snd_pcm_hw_params_set_access( pcm, hwParams, alternateAccessMode )) < 0) { result = paUnanticipatedHostError; if( -EINVAL == err ) { PaUtil_SetLastHostErrorInfo( paALSA, err, "PA ALSA requires that a device supports mmap access" ); } else { PaUtil_SetLastHostErrorInfo( paALSA, err, snd_strerror( err ) ); } goto error; } /* Flip mode */ self->hostInterleaved = !self->userInterleaved; } ENSURE_( snd_pcm_hw_params_set_format( pcm, hwParams, self->nativeFormat ), paUnanticipatedHostError ); ENSURE_( SetApproximateSampleRate( pcm, hwParams, sr ), paInvalidSampleRate ); ENSURE_( GetExactSampleRate( hwParams, &sr ), paUnanticipatedHostError ); /* reject if there's no sample rate within 1% of the one requested */ if( (fabs( *sampleRate - sr ) / *sampleRate) > 0.01 ) { PA_DEBUG(("%s: Wanted %f, closest sample rate was %d\n", __FUNCTION__, sampleRate, sr )); PA_ENSURE( paInvalidSampleRate ); } ENSURE_( snd_pcm_hw_params_set_channels( pcm, hwParams, self->numHostChannels ), paInvalidChannelCount ); *sampleRate = sr; end: return result; error: /* No particular action */ goto end; } /** Finish the configuration of the component's ALSA device. * * As part of this method, the component's bufferSize attribute will be set. * @param latency: The latency for this component. */ static PaError PaAlsaStreamComponent_FinishConfigure( PaAlsaStreamComponent *self, snd_pcm_hw_params_t* hwParams, const PaStreamParameters *params, int primeBuffers, double sampleRate, PaTime* latency ) { PaError result = paNoError; snd_pcm_sw_params_t* swParams; snd_pcm_uframes_t bufSz = 0; *latency = -1.; snd_pcm_sw_params_alloca( &swParams ); bufSz = params->suggestedLatency * sampleRate; ENSURE_( snd_pcm_hw_params_set_buffer_size_near( self->pcm, hwParams, &bufSz ), paUnanticipatedHostError ); /* Set the parameters! */ { int r = snd_pcm_hw_params( self->pcm, hwParams ); #ifdef PA_ENABLE_DEBUG_OUTPUT if( r < 0 ) { snd_output_t *output = NULL; snd_output_stdio_attach( &output, stderr, 0 ); snd_pcm_hw_params_dump( hwParams, output ); } #endif ENSURE_(r, paUnanticipatedHostError ); } ENSURE_( snd_pcm_hw_params_get_buffer_size( hwParams, &self->bufferSize ), paUnanticipatedHostError ); /* Latency in seconds */ *latency = self->bufferSize / sampleRate; /* Now software parameters... */ ENSURE_( snd_pcm_sw_params_current( self->pcm, swParams ), paUnanticipatedHostError ); ENSURE_( snd_pcm_sw_params_set_start_threshold( self->pcm, swParams, self->framesPerBuffer ), paUnanticipatedHostError ); ENSURE_( snd_pcm_sw_params_set_stop_threshold( self->pcm, swParams, self->bufferSize ), paUnanticipatedHostError ); /* Silence buffer in the case of underrun */ if( !primeBuffers ) /* XXX: Make sense? */ { snd_pcm_uframes_t boundary; ENSURE_( snd_pcm_sw_params_get_boundary( swParams, &boundary ), paUnanticipatedHostError ); ENSURE_( snd_pcm_sw_params_set_silence_threshold( self->pcm, swParams, 0 ), paUnanticipatedHostError ); ENSURE_( snd_pcm_sw_params_set_silence_size( self->pcm, swParams, boundary ), paUnanticipatedHostError ); } ENSURE_( snd_pcm_sw_params_set_avail_min( self->pcm, swParams, self->framesPerBuffer ), paUnanticipatedHostError ); ENSURE_( snd_pcm_sw_params_set_xfer_align( self->pcm, swParams, 1 ), paUnanticipatedHostError ); ENSURE_( snd_pcm_sw_params_set_tstamp_mode( self->pcm, swParams, SND_PCM_TSTAMP_MMAP ), paUnanticipatedHostError ); /* Set the parameters! */ ENSURE_( snd_pcm_sw_params( self->pcm, swParams ), paUnanticipatedHostError ); error: return result; } static PaError PaAlsaStream_Initialize( PaAlsaStream *self, PaAlsaHostApiRepresentation *alsaApi, const PaStreamParameters *inParams, const PaStreamParameters *outParams, double sampleRate, unsigned long framesPerUserBuffer, PaStreamCallback callback, PaStreamFlags streamFlags, void *userData ) { PaError result = paNoError; assert( self ); memset( self, 0, sizeof (PaAlsaStream) ); if( NULL != callback ) { PaUtil_InitializeStreamRepresentation( &self->streamRepresentation, &alsaApi->callbackStreamInterface, callback, userData ); self->callbackMode = 1; } else { PaUtil_InitializeStreamRepresentation( &self->streamRepresentation, &alsaApi->blockingStreamInterface, NULL, userData ); } self->framesPerUserBuffer = framesPerUserBuffer; self->neverDropInput = streamFlags & paNeverDropInput; /* XXX: Ignore paPrimeOutputBuffersUsingStreamCallback untill buffer priming is fully supported in pa_process.c */ /* if( outParams & streamFlags & paPrimeOutputBuffersUsingStreamCallback ) self->primeBuffers = 1; */ memset( &self->capture, 0, sizeof (PaAlsaStreamComponent) ); memset( &self->playback, 0, sizeof (PaAlsaStreamComponent) ); if( inParams ) { PA_ENSURE( PaAlsaStreamComponent_Initialize( &self->capture, alsaApi, inParams, StreamDirection_In, NULL != callback ) ); } if( outParams ) { PA_ENSURE( PaAlsaStreamComponent_Initialize( &self->playback, alsaApi, outParams, StreamDirection_Out, NULL != callback ) ); } assert( self->capture.nfds || self->playback.nfds ); PA_UNLESS( self->pfds = (struct pollfd*)PaUtil_AllocateMemory( (self->capture.nfds + self->playback.nfds) * sizeof (struct pollfd) ), paInsufficientMemory ); PaUtil_InitializeCpuLoadMeasurer( &self->cpuLoadMeasurer, sampleRate ); ASSERT_CALL_( PaUnixMutex_Initialize( &self->stateMtx ), paNoError ); error: return result; } /** Free resources associated with stream, and eventually stream itself. * * Frees allocated memory, and terminates individual StreamComponents. */ static void PaAlsaStream_Terminate( PaAlsaStream *self ) { assert( self ); if( self->capture.pcm ) { PaAlsaStreamComponent_Terminate( &self->capture ); } if( self->playback.pcm ) { PaAlsaStreamComponent_Terminate( &self->playback ); } PaUtil_FreeMemory( self->pfds ); ASSERT_CALL_( PaUnixMutex_Terminate( &self->stateMtx ), paNoError ); PaUtil_FreeMemory( self ); } /** Calculate polling timeout * * @param frames Time to wait * @return Polling timeout in milliseconds */ static int CalculatePollTimeout( const PaAlsaStream *stream, unsigned long frames ) { assert( stream->streamRepresentation.streamInfo.sampleRate > 0.0 ); /* Period in msecs, rounded up */ return (int)ceil( 1000 * frames / stream->streamRepresentation.streamInfo.sampleRate ); } /** Determine size per host buffer. * * During this method call, the component's framesPerBuffer attribute gets computed, and the corresponding period size * gets configured for the device. * @param accurate: If the configured period size is non-integer, this will be set to 0. */ static PaError PaAlsaStreamComponent_DetermineFramesPerBuffer( PaAlsaStreamComponent* self, const PaStreamParameters* params, unsigned long framesPerUserBuffer, double sampleRate, snd_pcm_hw_params_t* hwParams, int* accurate ) { PaError result = paNoError; unsigned long bufferSize = params->suggestedLatency * sampleRate, framesPerHostBuffer; int dir = 0; { snd_pcm_uframes_t tmp; snd_pcm_hw_params_get_buffer_size_min( hwParams, &tmp ); bufferSize = PA_MAX( bufferSize, tmp ); snd_pcm_hw_params_get_buffer_size_max( hwParams, &tmp ); bufferSize = PA_MIN( bufferSize, tmp ); } assert( bufferSize > 0 ); if( framesPerUserBuffer != paFramesPerBufferUnspecified ) { /* Preferably the host buffer size should be a multiple of the user buffer size */ if( bufferSize > framesPerUserBuffer ) { snd_pcm_uframes_t remainder = bufferSize % framesPerUserBuffer; if( remainder > framesPerUserBuffer / 2. ) bufferSize += framesPerUserBuffer - remainder; else bufferSize -= remainder; assert( bufferSize % framesPerUserBuffer == 0 ); } else if( framesPerUserBuffer % bufferSize != 0 ) { /* Find a good compromise between user specified latency and buffer size */ if( bufferSize > framesPerUserBuffer * .75 ) { bufferSize = framesPerUserBuffer; } else { snd_pcm_uframes_t newSz = framesPerUserBuffer; while( newSz / 2 >= bufferSize ) { if( framesPerUserBuffer % (newSz / 2) != 0 ) { /* No use dividing any further */ break; } newSz /= 2; } bufferSize = newSz; } assert( framesPerUserBuffer % bufferSize == 0 ); } } /* Using the base number of periods, we try to approximate the suggested latency (+1 period), finding a combination of period/buffer size which best fits these constraints */ { unsigned numPeriods = numPeriods_, maxPeriods = 0; /* It may be that the device only supports 2 periods for instance */ dir = 0; ENSURE_( snd_pcm_hw_params_get_periods_max( hwParams, &maxPeriods, &dir ), paUnanticipatedHostError ); assert( maxPeriods > 1 ); numPeriods = PA_MIN( maxPeriods, numPeriods ); if( framesPerUserBuffer != paFramesPerBufferUnspecified ) { /* Try to get a power-of-two of the user buffer size. */ framesPerHostBuffer = framesPerUserBuffer; if( framesPerHostBuffer < bufferSize ) { while( bufferSize / framesPerHostBuffer > numPeriods ) { framesPerHostBuffer *= 2; } /* One extra period is preferrable to one less (should be more robust) */ if( bufferSize / framesPerHostBuffer < numPeriods ) { framesPerHostBuffer /= 2; } } else { while( bufferSize / framesPerHostBuffer < numPeriods ) { if( framesPerUserBuffer % (framesPerHostBuffer / 2) != 0 ) { /* Can't be divided any further */ break; } framesPerHostBuffer /= 2; } } if( framesPerHostBuffer < framesPerUserBuffer ) { assert( framesPerUserBuffer % framesPerHostBuffer == 0 ); if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer, 0 ) < 0 ) { if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer * 2, 0 ) == 0 ) framesPerHostBuffer *= 2; else if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer / 2, 0 ) == 0 ) framesPerHostBuffer /= 2; } } else { assert( framesPerHostBuffer % framesPerUserBuffer == 0 ); if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer, 0 ) < 0 ) { if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer + framesPerUserBuffer, 0 ) == 0 ) framesPerHostBuffer += framesPerUserBuffer; else if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer - framesPerUserBuffer, 0 ) == 0 ) framesPerHostBuffer -= framesPerUserBuffer; } } } else { framesPerHostBuffer = bufferSize / numPeriods; } } assert( framesPerHostBuffer > 0 ); { snd_pcm_uframes_t min = 0, max = 0; ENSURE_( snd_pcm_hw_params_get_period_size_min( hwParams, &min, NULL ), paUnanticipatedHostError ); ENSURE_( snd_pcm_hw_params_get_period_size_max( hwParams, &max, NULL ), paUnanticipatedHostError ); if( framesPerHostBuffer < min ) { PA_DEBUG(( "%s: The determined period size (%lu) is less than minimum (%lu)\n", __FUNCTION__, framesPerHostBuffer, min )); framesPerHostBuffer = min; } else if( framesPerHostBuffer > max ) { PA_DEBUG(( "%s: The determined period size (%lu) is greater than maximum (%lu)\n", __FUNCTION__, framesPerHostBuffer, max )); framesPerHostBuffer = max; } assert( framesPerHostBuffer >= min && framesPerHostBuffer <= max ); dir = 0; ENSURE_( snd_pcm_hw_params_set_period_size_near( self->pcm, hwParams, &framesPerHostBuffer, &dir ), paUnanticipatedHostError ); if( dir != 0 ) { PA_DEBUG(( "%s: The configured period size is non-integer.\n", __FUNCTION__, dir )); *accurate = 0; } } self->framesPerBuffer = framesPerHostBuffer; error: return result; } /* We need to determine how many frames per host buffer (period) to use. Our * goals are to provide the best possible performance, but also to * honor the requested latency settings as closely as we can. Therefore this * decision is based on: * * - the period sizes that playback and/or capture support. The * host buffer size has to be one of these. * - the number of periods that playback and/or capture support. * * We want to make period_size*(num_periods-1) to be as close as possible * to latency*rate for both playback and capture. * * This method will determine suitable period sizes for capture and playback handles, and report the maximum number of * frames per host buffer. The latter is relevant, in case we should be so unfortunate that the period size differs * between capture and playback. If this should happen, the stream's hostBufferSizeMode attribute will be set to * paUtilBoundedHostBufferSize, because the best we can do is limit the size of individual host buffers to the upper * bound. The size of host buffers scheduled for processing should only matter if the user has specified a buffer size, * but when he/she does we must strive for an optimal configuration. By default we'll opt for a fixed host buffer size, * which should be fine if the period size is the same for capture and playback. In general, if there is a specified user * buffer size, this method tries it best to determine a period size which is a multiple of the user buffer size. * * The framesPerBuffer attributes of the individual capture and playback components of the stream are set to corresponding * values determined here. Since these should be reported as * * This is one of those blocks of code that will just take a lot of * refinement to be any good. * * In the full-duplex case it is possible that the routine was unable * to find a number of frames per buffer acceptable to both devices * TODO: Implement an algorithm to find the value closest to acceptance * by both devices, to minimize difference between period sizes? * * @param determinedFramesPerHostBuffer: The determined host buffer size. */ static PaError PaAlsaStream_DetermineFramesPerBuffer( PaAlsaStream* self, double sampleRate, const PaStreamParameters* inputParameters, const PaStreamParameters* outputParameters, unsigned long framesPerUserBuffer, snd_pcm_hw_params_t* hwParamsCapture, snd_pcm_hw_params_t* hwParamsPlayback, PaUtilHostBufferSizeMode* hostBufferSizeMode ) { PaError result = paNoError; unsigned long framesPerHostBuffer = 0; int dir = 0; int accurate = 1; unsigned numPeriods = numPeriods_; if( self->capture.pcm && self->playback.pcm ) { if( framesPerUserBuffer == paFramesPerBufferUnspecified ) { /* Come up with a common desired latency */ snd_pcm_uframes_t desiredBufSz, e, minPeriodSize, maxPeriodSize, optimalPeriodSize, periodSize, minCapture, minPlayback, maxCapture, maxPlayback; dir = 0; ENSURE_( snd_pcm_hw_params_get_period_size_min( hwParamsCapture, &minCapture, &dir ), paUnanticipatedHostError ); dir = 0; ENSURE_( snd_pcm_hw_params_get_period_size_min( hwParamsPlayback, &minPlayback, &dir ), paUnanticipatedHostError ); dir = 0; ENSURE_( snd_pcm_hw_params_get_period_size_max( hwParamsCapture, &maxCapture, &dir ), paUnanticipatedHostError ); dir = 0; ENSURE_( snd_pcm_hw_params_get_period_size_max( hwParamsPlayback, &maxPlayback, &dir ), paUnanticipatedHostError ); minPeriodSize = PA_MAX( minPlayback, minCapture ); maxPeriodSize = PA_MIN( maxPlayback, maxCapture ); PA_UNLESS( minPeriodSize <= maxPeriodSize, paBadIODeviceCombination ); desiredBufSz = (snd_pcm_uframes_t)(PA_MIN( outputParameters->suggestedLatency, inputParameters->suggestedLatency ) * sampleRate); /* Clamp desiredBufSz */ { snd_pcm_uframes_t maxBufferSize; snd_pcm_uframes_t maxBufferSizeCapture, maxBufferSizePlayback; ENSURE_( snd_pcm_hw_params_get_buffer_size_max( hwParamsCapture, &maxBufferSizeCapture ), paUnanticipatedHostError ); ENSURE_( snd_pcm_hw_params_get_buffer_size_max( hwParamsPlayback, &maxBufferSizePlayback ), paUnanticipatedHostError ); maxBufferSize = PA_MIN( maxBufferSizeCapture, maxBufferSizePlayback ); desiredBufSz = PA_MIN( desiredBufSz, maxBufferSize ); } /* Find the closest power of 2 */ e = ilogb( minPeriodSize ); if( minPeriodSize & (minPeriodSize - 1) ) e += 1; periodSize = (snd_pcm_uframes_t)pow( 2, e ); while( periodSize <= maxPeriodSize ) { if( snd_pcm_hw_params_test_period_size( self->playback.pcm, hwParamsPlayback, periodSize, 0 ) >= 0 && snd_pcm_hw_params_test_period_size( self->capture.pcm, hwParamsCapture, periodSize, 0 ) >= 0 ) { /* OK! */ break; } periodSize *= 2; } optimalPeriodSize = PA_MAX( desiredBufSz / numPeriods, minPeriodSize ); optimalPeriodSize = PA_MIN( optimalPeriodSize, maxPeriodSize ); /* Find the closest power of 2 */ e = ilogb( optimalPeriodSize ); if( optimalPeriodSize & (optimalPeriodSize - 1) ) e += 1; optimalPeriodSize = (snd_pcm_uframes_t)pow( 2, e ); while( optimalPeriodSize >= periodSize ) { if( snd_pcm_hw_params_test_period_size( self->capture.pcm, hwParamsCapture, optimalPeriodSize, 0 ) >= 0 && snd_pcm_hw_params_test_period_size( self->playback.pcm, hwParamsPlayback, optimalPeriodSize, 0 ) >= 0 ) { break; } optimalPeriodSize /= 2; } if( optimalPeriodSize > periodSize ) periodSize = optimalPeriodSize; if( periodSize <= maxPeriodSize ) { /* Looks good, the periodSize _should_ be acceptable by both devices */ ENSURE_( snd_pcm_hw_params_set_period_size( self->capture.pcm, hwParamsCapture, periodSize, 0 ), paUnanticipatedHostError ); ENSURE_( snd_pcm_hw_params_set_period_size( self->playback.pcm, hwParamsPlayback, periodSize, 0 ), paUnanticipatedHostError ); self->capture.framesPerBuffer = self->playback.framesPerBuffer = periodSize; framesPerHostBuffer = periodSize; } else { /* Unable to find a common period size, oh well */ optimalPeriodSize = PA_MAX( desiredBufSz / numPeriods, minPeriodSize ); optimalPeriodSize = PA_MIN( optimalPeriodSize, maxPeriodSize ); self->capture.framesPerBuffer = optimalPeriodSize; dir = 0; ENSURE_( snd_pcm_hw_params_set_period_size_near( self->capture.pcm, hwParamsCapture, &self->capture.framesPerBuffer, &dir ), paUnanticipatedHostError ); self->playback.framesPerBuffer = optimalPeriodSize; dir = 0; ENSURE_( snd_pcm_hw_params_set_period_size_near( self->playback.pcm, hwParamsPlayback, &self->playback.framesPerBuffer, &dir ), paUnanticipatedHostError ); framesPerHostBuffer = PA_MAX( self->capture.framesPerBuffer, self->playback.framesPerBuffer ); *hostBufferSizeMode = paUtilBoundedHostBufferSize; } } else { /* We choose the simple route and determine a suitable number of frames per buffer for one component of * the stream, then we hope that this will work for the other component too (it should!). */ unsigned maxPeriods = 0; PaAlsaStreamComponent* first = &self->capture, * second = &self->playback; const PaStreamParameters* firstStreamParams = inputParameters; snd_pcm_hw_params_t* firstHwParams = hwParamsCapture, * secondHwParams = hwParamsPlayback; dir = 0; ENSURE_( snd_pcm_hw_params_get_periods_max( hwParamsPlayback, &maxPeriods, &dir ), paUnanticipatedHostError ); if( maxPeriods < numPeriods ) { /* The playback component is trickier to get right, try that first */ first = &self->playback; second = &self->capture; firstStreamParams = outputParameters; firstHwParams = hwParamsPlayback; secondHwParams = hwParamsCapture; } PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( first, firstStreamParams, framesPerUserBuffer, sampleRate, firstHwParams, &accurate ) ); second->framesPerBuffer = first->framesPerBuffer; dir = 0; ENSURE_( snd_pcm_hw_params_set_period_size_near( second->pcm, secondHwParams, &second->framesPerBuffer, &dir ), paUnanticipatedHostError ); if( self->capture.framesPerBuffer == self->playback.framesPerBuffer ) { framesPerHostBuffer = self->capture.framesPerBuffer; } else { framesPerHostBuffer = PA_MAX( self->capture.framesPerBuffer, self->playback.framesPerBuffer ); *hostBufferSizeMode = paUtilBoundedHostBufferSize; } } } else /* half-duplex is a slightly simpler case */ { if( self->capture.pcm ) { PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( &self->capture, inputParameters, framesPerUserBuffer, sampleRate, hwParamsCapture, &accurate) ); framesPerHostBuffer = self->capture.framesPerBuffer; } else { assert( self->playback.pcm ); PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( &self->playback, outputParameters, framesPerUserBuffer, sampleRate, hwParamsPlayback, &accurate ) ); framesPerHostBuffer = self->playback.framesPerBuffer; } } PA_UNLESS( framesPerHostBuffer != 0, paInternalError ); self->maxFramesPerHostBuffer = framesPerHostBuffer; if( !accurate ) { /* Don't know the exact size per host buffer */ *hostBufferSizeMode = paUtilBoundedHostBufferSize; /* Raise upper bound */ ++self->maxFramesPerHostBuffer; } error: return result; } /** Set up ALSA stream parameters. * */ static PaError PaAlsaStream_Configure( PaAlsaStream *self, const PaStreamParameters *inParams, const PaStreamParameters* outParams, double sampleRate, unsigned long framesPerUserBuffer, double* inputLatency, double* outputLatency, PaUtilHostBufferSizeMode* hostBufferSizeMode ) { PaError result = paNoError; double realSr = sampleRate; snd_pcm_hw_params_t* hwParamsCapture, * hwParamsPlayback; snd_pcm_hw_params_alloca( &hwParamsCapture ); snd_pcm_hw_params_alloca( &hwParamsPlayback ); if( self->capture.pcm ) PA_ENSURE( PaAlsaStreamComponent_InitialConfigure( &self->capture, inParams, self->primeBuffers, hwParamsCapture, &realSr ) ); if( self->playback.pcm ) PA_ENSURE( PaAlsaStreamComponent_InitialConfigure( &self->playback, outParams, self->primeBuffers, hwParamsPlayback, &realSr ) ); PA_ENSURE( PaAlsaStream_DetermineFramesPerBuffer( self, realSr, inParams, outParams, framesPerUserBuffer, hwParamsCapture, hwParamsPlayback, hostBufferSizeMode ) ); if( self->capture.pcm ) { assert( self->capture.framesPerBuffer != 0 ); PA_ENSURE( PaAlsaStreamComponent_FinishConfigure( &self->capture, hwParamsCapture, inParams, self->primeBuffers, realSr, inputLatency ) ); PA_DEBUG(( "%s: Capture period size: %lu, latency: %f\n", __FUNCTION__, self->capture.framesPerBuffer, *inputLatency )); } if( self->playback.pcm ) { assert( self->playback.framesPerBuffer != 0 ); PA_ENSURE( PaAlsaStreamComponent_FinishConfigure( &self->playback, hwParamsPlayback, outParams, self->primeBuffers, realSr, outputLatency ) ); PA_DEBUG(( "%s: Playback period size: %lu, latency: %f\n", __FUNCTION__, self->playback.framesPerBuffer, *outputLatency )); } /* Should be exact now */ self->streamRepresentation.streamInfo.sampleRate = realSr; /* this will cause the two streams to automatically start/stop/prepare in sync. * We only need to execute these operations on one of the pair. * A: We don't want to do this on a blocking stream. */ if( self->callbackMode && self->capture.pcm && self->playback.pcm ) { int err = snd_pcm_link( self->capture.pcm, self->playback.pcm ); if( err == 0 ) self->pcmsSynced = 1; else PA_DEBUG(( "%s: Unable to sync pcms: %s\n", __FUNCTION__, snd_strerror( err ) )); } { unsigned long minFramesPerHostBuffer = PA_MIN( self->capture.pcm ? self->capture.framesPerBuffer : ULONG_MAX, self->playback.pcm ? self->playback.framesPerBuffer : ULONG_MAX ); self->pollTimeout = CalculatePollTimeout( self, minFramesPerHostBuffer ); /* Period in msecs, rounded up */ /* Time before watchdog unthrottles realtime thread == 1/4 of period time in msecs */ /* self->threading.throttledSleepTime = (unsigned long) (minFramesPerHostBuffer / sampleRate / 4 * 1000); */ } if( self->callbackMode ) { /* If the user expects a certain number of frames per callback we will either have to rely on block adaption * (framesPerHostBuffer is not an integer multiple of framesPerBuffer) or we can simply align the number * of host buffer frames with what the user specified */ if( self->framesPerUserBuffer != paFramesPerBufferUnspecified ) { /* self->alignFrames = 1; */ /* Unless the ratio between number of host and user buffer frames is an integer we will have to rely * on block adaption */ /* if( framesPerHostBuffer % framesPerBuffer != 0 || (self->capture.pcm && self->playback.pcm && self->capture.framesPerBuffer != self->playback.framesPerBuffer) ) self->useBlockAdaption = 1; else self->alignFrames = 1; */ } } error: return result; } static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback* callback, void *userData ) { PaError result = paNoError; PaAlsaHostApiRepresentation *alsaHostApi = (PaAlsaHostApiRepresentation*)hostApi; PaAlsaStream *stream = NULL; PaSampleFormat hostInputSampleFormat = 0, hostOutputSampleFormat = 0; PaSampleFormat inputSampleFormat = 0, outputSampleFormat = 0; int numInputChannels = 0, numOutputChannels = 0; PaTime inputLatency, outputLatency; /* Operate with fixed host buffer size by default, since other modes will invariably lead to block adaption */ /* XXX: Use Bounded by default? Output tends to get stuttery with Fixed ... */ PaUtilHostBufferSizeMode hostBufferSizeMode = paUtilFixedHostBufferSize; if( (streamFlags & paPlatformSpecificFlags) != 0 ) return paInvalidFlag; if( inputParameters ) { PA_ENSURE( ValidateParameters( inputParameters, hostApi, StreamDirection_In ) ); numInputChannels = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; } if( outputParameters ) { PA_ENSURE( ValidateParameters( outputParameters, hostApi, StreamDirection_Out ) ); numOutputChannels = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; } /* XXX: Why do we support this anyway? */ if( framesPerBuffer == paFramesPerBufferUnspecified && getenv( "PA_ALSA_PERIODSIZE" ) != NULL ) { PA_DEBUG(( "%s: Getting framesPerBuffer from environment\n", __FUNCTION__ )); framesPerBuffer = atoi( getenv("PA_ALSA_PERIODSIZE") ); } PA_UNLESS( stream = (PaAlsaStream*)PaUtil_AllocateMemory( sizeof(PaAlsaStream) ), paInsufficientMemory ); PA_ENSURE( PaAlsaStream_Initialize( stream, alsaHostApi, inputParameters, outputParameters, sampleRate, framesPerBuffer, callback, streamFlags, userData ) ); PA_ENSURE( PaAlsaStream_Configure( stream, inputParameters, outputParameters, sampleRate, framesPerBuffer, &inputLatency, &outputLatency, &hostBufferSizeMode ) ); hostInputSampleFormat = stream->capture.hostSampleFormat; hostOutputSampleFormat = stream->playback.hostSampleFormat; PA_ENSURE( PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, numInputChannels, inputSampleFormat, hostInputSampleFormat, numOutputChannels, outputSampleFormat, hostOutputSampleFormat, sampleRate, streamFlags, framesPerBuffer, stream->maxFramesPerHostBuffer, hostBufferSizeMode, callback, userData ) ); /* Ok, buffer processor is initialized, now we can deduce it's latency */ if( numInputChannels > 0 ) stream->streamRepresentation.streamInfo.inputLatency = inputLatency + PaUtil_GetBufferProcessorInputLatency( &stream->bufferProcessor ); if( numOutputChannels > 0 ) stream->streamRepresentation.streamInfo.outputLatency = outputLatency + PaUtil_GetBufferProcessorOutputLatency( &stream->bufferProcessor ); *s = (PaStream*)stream; return result; error: if( stream ) { PA_DEBUG(( "%s: Stream in error, terminating\n", __FUNCTION__ )); PaAlsaStream_Terminate( stream ); } return result; } static PaError CloseStream( PaStream* s ) { PaError result = paNoError; PaAlsaStream *stream = (PaAlsaStream*)s; PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); PaAlsaStream_Terminate( stream ); return result; } static void SilenceBuffer( PaAlsaStream *stream ) { const snd_pcm_channel_area_t *areas; snd_pcm_uframes_t frames = (snd_pcm_uframes_t)snd_pcm_avail_update( stream->playback.pcm ), offset; snd_pcm_mmap_begin( stream->playback.pcm, &areas, &offset, &frames ); snd_pcm_areas_silence( areas, offset, stream->playback.numHostChannels, frames, stream->playback.nativeFormat ); snd_pcm_mmap_commit( stream->playback.pcm, offset, frames ); } /** Start/prepare pcm(s) for streaming. * * Depending on wether the stream is in callback or blocking mode, we will respectively start or simply * prepare the playback pcm. If the buffer has _not_ been primed, we will in callback mode prepare and * silence the buffer before starting playback. In blocking mode we simply prepare, as the playback will * be started automatically as the user writes to output. * * The capture pcm, however, will simply be prepared and started. */ static PaError AlsaStart( PaAlsaStream *stream, int priming ) { PaError result = paNoError; if( stream->playback.pcm ) { if( stream->callbackMode ) { if( !priming ) { /* Buffer isn't primed, so prepare and silence */ ENSURE_( snd_pcm_prepare( stream->playback.pcm ), paUnanticipatedHostError ); SilenceBuffer( stream ); } ENSURE_( snd_pcm_start( stream->playback.pcm ), paUnanticipatedHostError ); } else ENSURE_( snd_pcm_prepare( stream->playback.pcm ), paUnanticipatedHostError ); } if( stream->capture.pcm && !stream->pcmsSynced ) { ENSURE_( snd_pcm_prepare( stream->capture.pcm ), paUnanticipatedHostError ); /* For a blocking stream we want to start capture as well, since nothing will happen otherwise */ ENSURE_( snd_pcm_start( stream->capture.pcm ), paUnanticipatedHostError ); } end: return result; error: goto end; } /** Utility function for determining if pcms are in running state. * */ #if 0 static int IsRunning( PaAlsaStream *stream ) { int result = 0; PA_ENSURE( PaUnixMutex_Lock( &stream->stateMtx ) ); if( stream->capture.pcm ) { snd_pcm_state_t capture_state = snd_pcm_state( stream->capture.pcm ); if( capture_state == SND_PCM_STATE_RUNNING || capture_state == SND_PCM_STATE_XRUN || capture_state == SND_PCM_STATE_DRAINING ) { result = 1; goto end; } } if( stream->playback.pcm ) { snd_pcm_state_t playback_state = snd_pcm_state( stream->playback.pcm ); if( playback_state == SND_PCM_STATE_RUNNING || playback_state == SND_PCM_STATE_XRUN || playback_state == SND_PCM_STATE_DRAINING ) { result = 1; goto end; } } end: ASSERT_CALL_( PaUnixMutex_Unlock( &stream->stateMtx ), paNoError ); return result; error: goto error; } #endif static PaError StartStream( PaStream *s ) { PaError result = paNoError; PaAlsaStream* stream = (PaAlsaStream*)s; int streamStarted = 0; /* So we can know wether we need to take the stream down */ /* Ready the processor */ PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); /* Set now, so we can test for activity further down */ stream->isActive = 1; if( stream->callbackMode ) { PA_ENSURE( PaUnixThread_New( &stream->thread, &CallbackThreadFunc, stream, 1., stream->rtSched ) ); } else { PA_ENSURE( AlsaStart( stream, 0 ) ); streamStarted = 1; } end: return result; error: if( streamStarted ) { AbortStream( stream ); } stream->isActive = 0; goto end; } /** Stop PCM handle, either softly or abruptly. */ static PaError AlsaStop( PaAlsaStream *stream, int abort ) { PaError result = paNoError; /* XXX: snd_pcm_drain tends to lock up, avoid it until we find out more */ abort = 1; /* if( stream->capture.pcm && !strcmp( Pa_GetDeviceInfo( stream->capture.device )->name, "dmix" ) ) { abort = 1; } else if( stream->playback.pcm && !strcmp( Pa_GetDeviceInfo( stream->playback.device )->name, "dmix" ) ) { abort = 1; } */ if( abort ) { if( stream->playback.pcm ) { ENSURE_( snd_pcm_drop( stream->playback.pcm ), paUnanticipatedHostError ); } if( stream->capture.pcm && !stream->pcmsSynced ) { ENSURE_( snd_pcm_drop( stream->capture.pcm ), paUnanticipatedHostError ); } PA_DEBUG(( "%s: Dropped frames\n", __FUNCTION__ )); } else { if( stream->playback.pcm ) { ENSURE_( snd_pcm_nonblock( stream->playback.pcm, 0 ), paUnanticipatedHostError ); if( snd_pcm_drain( stream->playback.pcm ) < 0 ) { PA_DEBUG(( "%s: Draining playback handle failed!\n", __FUNCTION__ )); } } if( stream->capture.pcm && !stream->pcmsSynced ) { /* We don't need to retrieve any remaining frames */ if( snd_pcm_drain( stream->capture.pcm ) < 0 ) { PA_DEBUG(( "%s: Draining capture handle failed!\n", __FUNCTION__ )); } } } end: return result; error: goto end; } /** Stop or abort stream. * * If a stream is in callback mode we will have to inspect wether the background thread has * finished, or we will have to take it out. In either case we join the thread before * returning. In blocking mode, we simply tell ALSA to stop abruptly (abort) or finish * buffers (drain) * * Stream will be considered inactive (!PaAlsaStream::isActive) after a call to this function */ static PaError RealStop( PaAlsaStream *stream, int abort ) { PaError result = paNoError; /* First deal with the callback thread, cancelling and/or joining * it if necessary */ if( stream->callbackMode ) { PaError threadRes; stream->callbackAbort = abort; if( !abort ) { PA_DEBUG(( "Stopping callback\n" )); } PA_ENSURE( PaUnixThread_Terminate( &stream->thread, !abort, &threadRes ) ); if( threadRes != paNoError ) { PA_DEBUG(( "Callback thread returned: %d\n", threadRes )); } #if 0 if( watchdogRes != paNoError ) PA_DEBUG(( "Watchdog thread returned: %d\n", watchdogRes )); #endif stream->callback_finished = 0; } else { PA_ENSURE( AlsaStop( stream, abort ) ); } stream->isActive = 0; end: return result; error: goto end; } static PaError StopStream( PaStream *s ) { return RealStop( (PaAlsaStream *) s, 0 ); } static PaError AbortStream( PaStream *s ) { return RealStop( (PaAlsaStream * ) s, 1 ); } /** The stream is considered stopped before StartStream, or AFTER a call to Abort/StopStream (callback * returning !paContinue is not considered) * */ static PaError IsStreamStopped( PaStream *s ) { PaAlsaStream *stream = (PaAlsaStream *)s; /* callback_finished indicates we need to join callback thread (ie. in Abort/StopStream) */ return !IsStreamActive( s ) && !stream->callback_finished; } static PaError IsStreamActive( PaStream *s ) { PaAlsaStream *stream = (PaAlsaStream*)s; return stream->isActive; } static PaTime GetStreamTime( PaStream *s ) { PaAlsaStream *stream = (PaAlsaStream*)s; snd_timestamp_t timestamp; snd_pcm_status_t* status; snd_pcm_status_alloca( &status ); /* TODO: what if we have both? does it really matter? */ /* TODO: if running in callback mode, this will mean * libasound routines are being called from multiple threads. * need to verify that libasound is thread-safe. */ if( stream->capture.pcm ) { snd_pcm_status( stream->capture.pcm, status ); } else if( stream->playback.pcm ) { snd_pcm_status( stream->playback.pcm, status ); } snd_pcm_status_get_tstamp( status, ×tamp ); return timestamp.tv_sec + (PaTime)timestamp.tv_usec / 1e6; } static double GetStreamCpuLoad( PaStream* s ) { PaAlsaStream *stream = (PaAlsaStream*)s; return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); } static int SetApproximateSampleRate( snd_pcm_t *pcm, snd_pcm_hw_params_t *hwParams, double sampleRate ) { unsigned long approx = (unsigned long) sampleRate; int dir = 0; double fraction = sampleRate - approx; assert( pcm && hwParams ); if( fraction > 0.0 ) { if( fraction > 0.5 ) { ++approx; dir = -1; } else dir = 1; } return snd_pcm_hw_params_set_rate( pcm, hwParams, approx, dir ); } /* Return exact sample rate in param sampleRate */ static int GetExactSampleRate( snd_pcm_hw_params_t *hwParams, double *sampleRate ) { unsigned int num, den; int err; assert( hwParams ); err = snd_pcm_hw_params_get_rate_numden( hwParams, &num, &den ); *sampleRate = (double) num / den; return err; } /* Utility functions for blocking/callback interfaces */ /* Atomic restart of stream (we don't want the intermediate state visible) */ static PaError AlsaRestart( PaAlsaStream *stream ) { PaError result = paNoError; PA_ENSURE( PaUnixMutex_Lock( &stream->stateMtx ) ); PA_ENSURE( AlsaStop( stream, 0 ) ); PA_ENSURE( AlsaStart( stream, 0 ) ); PA_DEBUG(( "%s: Restarted audio\n", __FUNCTION__ )); error: PA_ENSURE( PaUnixMutex_Unlock( &stream->stateMtx ) ); return result; } /** Recover from xrun state. * */ static PaError PaAlsaStream_HandleXrun( PaAlsaStream *self ) { PaError result = paNoError; snd_pcm_status_t *st; PaTime now = PaUtil_GetTime(); snd_timestamp_t t; snd_pcm_status_alloca( &st ); if( self->playback.pcm ) { snd_pcm_status( self->playback.pcm, st ); if( snd_pcm_status_get_state( st ) == SND_PCM_STATE_XRUN ) { snd_pcm_status_get_trigger_tstamp( st, &t ); self->underrun = now * 1000 - ((PaTime) t.tv_sec * 1000 + (PaTime) t.tv_usec / 1000); } } if( self->capture.pcm ) { snd_pcm_status( self->capture.pcm, st ); if( snd_pcm_status_get_state( st ) == SND_PCM_STATE_XRUN ) { snd_pcm_status_get_trigger_tstamp( st, &t ); self->overrun = now * 1000 - ((PaTime) t.tv_sec * 1000 + (PaTime) t.tv_usec / 1000); } } PA_ENSURE( AlsaRestart( self ) ); end: return result; error: goto end; } /** Decide if we should continue polling for specified direction, eventually adjust the poll timeout. * */ static PaError ContinuePoll( const PaAlsaStream *stream, StreamDirection streamDir, int *pollTimeout, int *continuePoll ) { PaError result = paNoError; snd_pcm_sframes_t delay, margin; int err; const PaAlsaStreamComponent *component = NULL, *otherComponent = NULL; *continuePoll = 1; if( StreamDirection_In == streamDir ) { component = &stream->capture; otherComponent = &stream->playback; } else { component = &stream->playback; otherComponent = &stream->capture; } /* ALSA docs say that negative delay should indicate xrun, but in my experience snd_pcm_delay returns -EPIPE */ if( (err = snd_pcm_delay( otherComponent->pcm, &delay )) < 0 ) { if( err == -EPIPE ) { /* Xrun */ *continuePoll = 0; goto error; } ENSURE_( err, paUnanticipatedHostError ); } if( StreamDirection_Out == streamDir ) { /* Number of eligible frames before capture overrun */ delay = otherComponent->bufferSize - delay; } margin = delay - otherComponent->framesPerBuffer / 2; if( margin < 0 ) { PA_DEBUG(( "%s: Stopping poll for %s\n", __FUNCTION__, StreamDirection_In == streamDir ? "capture" : "playback" )); *continuePoll = 0; } else if( margin < otherComponent->framesPerBuffer ) { *pollTimeout = CalculatePollTimeout( stream, margin ); PA_DEBUG(( "%s: Trying to poll again for %s frames, pollTimeout: %d\n", __FUNCTION__, StreamDirection_In == streamDir ? "capture" : "playback", *pollTimeout )); } error: return result; } /* Callback interface */ static void OnExit( void *data ) { PaAlsaStream *stream = (PaAlsaStream *) data; assert( data ); PaUtil_ResetCpuLoadMeasurer( &stream->cpuLoadMeasurer ); stream->callback_finished = 1; /* Let the outside world know stream was stopped in callback */ PA_DEBUG(( "%s: Stopping ALSA handles\n", __FUNCTION__ )); AlsaStop( stream, stream->callbackAbort ); PA_DEBUG(( "%s: Stoppage\n", __FUNCTION__ )); /* Eventually notify user all buffers have played */ if( stream->streamRepresentation.streamFinishedCallback ) { stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); } stream->isActive = 0; } static void CalculateTimeInfo( PaAlsaStream *stream, PaStreamCallbackTimeInfo *timeInfo ) { snd_pcm_status_t *capture_status, *playback_status; snd_timestamp_t capture_timestamp, playback_timestamp; PaTime capture_time = 0., playback_time = 0.; snd_pcm_status_alloca( &capture_status ); snd_pcm_status_alloca( &playback_status ); if( stream->capture.pcm ) { snd_pcm_sframes_t capture_delay; snd_pcm_status( stream->capture.pcm, capture_status ); snd_pcm_status_get_tstamp( capture_status, &capture_timestamp ); capture_time = capture_timestamp.tv_sec + ((PaTime)capture_timestamp.tv_usec / 1000000.0); timeInfo->currentTime = capture_time; capture_delay = snd_pcm_status_get_delay( capture_status ); timeInfo->inputBufferAdcTime = timeInfo->currentTime - (PaTime)capture_delay / stream->streamRepresentation.streamInfo.sampleRate; } if( stream->playback.pcm ) { snd_pcm_sframes_t playback_delay; snd_pcm_status( stream->playback.pcm, playback_status ); snd_pcm_status_get_tstamp( playback_status, &playback_timestamp ); playback_time = playback_timestamp.tv_sec + ((PaTime)playback_timestamp.tv_usec / 1000000.0); if( stream->capture.pcm ) /* Full duplex */ { /* Hmm, we have both a playback and a capture timestamp. * Hopefully they are the same... */ if( fabs( capture_time - playback_time ) > 0.01 ) PA_DEBUG(("Capture time and playback time differ by %f\n", fabs(capture_time-playback_time))); } else timeInfo->currentTime = playback_time; playback_delay = snd_pcm_status_get_delay( playback_status ); timeInfo->outputBufferDacTime = timeInfo->currentTime + (PaTime)playback_delay / stream->streamRepresentation.streamInfo.sampleRate; } } /** Called after buffer processing is finished. * * A number of mmapped frames is committed, it is possible that an xrun has occurred in the meantime. * * @param numFrames The number of frames that has been processed * @param xrun Return whether an xrun has occurred */ static PaError PaAlsaStreamComponent_EndProcessing( PaAlsaStreamComponent *self, unsigned long numFrames, int *xrun ) { PaError result = paNoError; int res; /* @concern FullDuplex It is possible that only one direction is marked ready after polling, and processed * afterwards */ if( !self->ready ) goto end; res = snd_pcm_mmap_commit( self->pcm, self->offset, numFrames ); if( res == -EPIPE || res == -ESTRPIPE ) { *xrun = 1; } else { ENSURE_( res, paUnanticipatedHostError ); } end: error: return result; } /* Extract buffer from channel area */ static unsigned char *ExtractAddress( const snd_pcm_channel_area_t *area, snd_pcm_uframes_t offset ) { return (unsigned char *) area->addr + (area->first + offset * area->step) / 8; } /** Do necessary adaption between user and host channels. * @concern ChannelAdaption Adapting between user and host channels can involve silencing unused channels and duplicating mono information if host outputs come in pairs. */ static PaError PaAlsaStreamComponent_DoChannelAdaption( PaAlsaStreamComponent *self, PaUtilBufferProcessor *bp, int numFrames ) { PaError result = paNoError; unsigned char *p; int i; int unusedChans = self->numHostChannels - self->numUserChannels; unsigned char *src, *dst; int convertMono = (self->numHostChannels % 2) == 0 && (self->numUserChannels % 2) != 0; assert( StreamDirection_Out == self->streamDir ); if( self->hostInterleaved ) { int swidth = snd_pcm_format_size( self->nativeFormat, 1 ); unsigned char *buffer = ExtractAddress( self->channelAreas, self->offset ); /* Start after the last user channel */ p = buffer + self->numUserChannels * swidth; if( convertMono ) { /* Convert the last user channel into stereo pair */ src = buffer + (self->numUserChannels - 1) * swidth; for( i = 0; i < numFrames; ++i ) { dst = src + swidth; memcpy( dst, src, swidth ); src += self->numHostChannels * swidth; } /* Don't touch the channel we just wrote to */ p += swidth; --unusedChans; } if( unusedChans > 0 ) { /* Silence unused output channels */ for( i = 0; i < numFrames; ++i ) { memset( p, 0, swidth * unusedChans ); p += self->numHostChannels * swidth; } } } else { /* We extract the last user channel */ if( convertMono ) { ENSURE_( snd_pcm_area_copy( self->channelAreas + self->numUserChannels, self->offset, self->channelAreas + (self->numUserChannels - 1), self->offset, numFrames, self->nativeFormat ), paUnanticipatedHostError ); --unusedChans; } if( unusedChans > 0 ) { snd_pcm_areas_silence( self->channelAreas + (self->numHostChannels - unusedChans), self->offset, unusedChans, numFrames, self->nativeFormat ); } } error: return result; } static PaError PaAlsaStream_EndProcessing( PaAlsaStream *self, unsigned long numFrames, int *xrunOccurred ) { PaError result = paNoError; int xrun = 0; if( self->capture.pcm ) { PA_ENSURE( PaAlsaStreamComponent_EndProcessing( &self->capture, numFrames, &xrun ) ); } if( self->playback.pcm ) { if( self->playback.numHostChannels > self->playback.numUserChannels ) { PA_ENSURE( PaAlsaStreamComponent_DoChannelAdaption( &self->playback, &self->bufferProcessor, numFrames ) ); } PA_ENSURE( PaAlsaStreamComponent_EndProcessing( &self->playback, numFrames, &xrun ) ); } error: *xrunOccurred = xrun; return result; } /** Update the number of available frames. * */ static PaError PaAlsaStreamComponent_GetAvailableFrames( PaAlsaStreamComponent *self, unsigned long *numFrames, int *xrunOccurred ) { PaError result = paNoError; snd_pcm_sframes_t framesAvail = snd_pcm_avail_update( self->pcm ); *xrunOccurred = 0; if( -EPIPE == framesAvail ) { *xrunOccurred = 1; framesAvail = 0; } else { ENSURE_( framesAvail, paUnanticipatedHostError ); } *numFrames = framesAvail; error: return result; } /** Fill in pollfd objects. */ static PaError PaAlsaStreamComponent_BeginPolling( PaAlsaStreamComponent* self, struct pollfd* pfds ) { PaError result = paNoError; int ret = snd_pcm_poll_descriptors( self->pcm, pfds, self->nfds ); (void)ret; /* Prevent unused variable warning if asserts are turned off */ assert( ret == self->nfds ); self->ready = 0; return result; } /** Examine results from poll(). * * @param pfds pollfds to inspect * @param shouldPoll Should we continue to poll * @param xrun Has an xrun occurred */ static PaError PaAlsaStreamComponent_EndPolling( PaAlsaStreamComponent* self, struct pollfd* pfds, int* shouldPoll, int* xrun ) { PaError result = paNoError; unsigned short revents; ENSURE_( snd_pcm_poll_descriptors_revents( self->pcm, pfds, self->nfds, &revents ), paUnanticipatedHostError ); if( revents != 0 ) { if( revents & POLLERR ) { *xrun = 1; } else self->ready = 1; *shouldPoll = 0; } error: return result; } /** Return the number of available frames for this stream. * * @concern FullDuplex The minimum available for the two directions is calculated, it might be desirable to ignore * one direction however (not marked ready from poll), so this is controlled by queryCapture and queryPlayback. * * @param queryCapture Check available for capture * @param queryPlayback Check available for playback * @param available The returned number of frames * @param xrunOccurred Return whether an xrun has occurred */ static PaError PaAlsaStream_GetAvailableFrames( PaAlsaStream *self, int queryCapture, int queryPlayback, unsigned long *available, int *xrunOccurred ) { PaError result = paNoError; unsigned long captureFrames, playbackFrames; *xrunOccurred = 0; assert( queryCapture || queryPlayback ); if( queryCapture ) { assert( self->capture.pcm ); PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &self->capture, &captureFrames, xrunOccurred ) ); if( *xrunOccurred ) { goto end; } } if( queryPlayback ) { assert( self->playback.pcm ); PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &self->playback, &playbackFrames, xrunOccurred ) ); if( *xrunOccurred ) { goto end; } } if( queryCapture && queryPlayback ) { *available = PA_MIN( captureFrames, playbackFrames ); /*PA_DEBUG(("capture: %lu, playback: %lu, combined: %lu\n", captureFrames, playbackFrames, *available));*/ } else if( queryCapture ) { *available = captureFrames; } else { *available = playbackFrames; } end: error: return result; } /** Wait for and report available buffer space from ALSA. * * Unless ALSA reports a minimum of frames available for I/O, we poll the ALSA filedescriptors for more. * Both of these operations can uncover xrun conditions. * * @concern Xruns Both polling and querying available frames can report an xrun condition. * * @param framesAvail Return the number of available frames * @param xrunOccurred Return whether an xrun has occurred */ static PaError PaAlsaStream_WaitForFrames( PaAlsaStream *self, unsigned long *framesAvail, int *xrunOccurred ) { PaError result = paNoError; int pollPlayback = self->playback.pcm != NULL, pollCapture = self->capture.pcm != NULL; int pollTimeout = self->pollTimeout; int xrun = 0; assert( self ); assert( framesAvail ); if( !self->callbackMode ) { /* In blocking mode we will only wait if necessary */ PA_ENSURE( PaAlsaStream_GetAvailableFrames( self, self->capture.pcm != NULL, self->playback.pcm != NULL, framesAvail, &xrun ) ); if( xrun ) { goto end; } if( *framesAvail > 0 ) { /* Mark pcms ready from poll */ if( self->capture.pcm ) self->capture.ready = 1; if( self->playback.pcm ) self->playback.ready = 1; goto end; } } while( pollPlayback || pollCapture ) { int totalFds = 0; struct pollfd *capturePfds = NULL, *playbackPfds = NULL; pthread_testcancel(); if( pollCapture ) { capturePfds = self->pfds; PA_ENSURE( PaAlsaStreamComponent_BeginPolling( &self->capture, capturePfds ) ); totalFds += self->capture.nfds; } if( pollPlayback ) { playbackPfds = self->pfds + (self->capture.pcm ? self->capture.nfds : 0); PA_ENSURE( PaAlsaStreamComponent_BeginPolling( &self->playback, playbackPfds ) ); totalFds += self->playback.nfds; } if( poll( self->pfds, totalFds, pollTimeout ) < 0 ) { /* XXX: Depend on preprocessor condition? */ if( errno == EINTR ) { /* gdb */ continue; } /* TODO: Add macro for checking system calls */ PA_ENSURE( paInternalError ); } /* check the return status of our pfds */ if( pollCapture ) { PA_ENSURE( PaAlsaStreamComponent_EndPolling( &self->capture, capturePfds, &pollCapture, &xrun ) ); } if( pollPlayback ) { PA_ENSURE( PaAlsaStreamComponent_EndPolling( &self->playback, playbackPfds, &pollPlayback, &xrun ) ); } if( xrun ) { break; } /* @concern FullDuplex If only one of two pcms is ready we may want to compromise between the two. * If there is less than half a period's worth of samples left of frames in the other pcm's buffer we will * stop polling. */ if( self->capture.pcm && self->playback.pcm ) { if( pollCapture && !pollPlayback ) { PA_ENSURE( ContinuePoll( self, StreamDirection_In, &pollTimeout, &pollCapture ) ); } else if( pollPlayback && !pollCapture ) { PA_ENSURE( ContinuePoll( self, StreamDirection_Out, &pollTimeout, &pollPlayback ) ); } } } if( !xrun ) { /* Get the number of available frames for the pcms that are marked ready. * @concern FullDuplex If only one direction is marked ready (from poll), the number of frames available for * the other direction is returned. Output is normally preferred over capture however, so capture frames may be * discarded to avoid overrun unless paNeverDropInput is specified. */ int captureReady = self->capture.pcm ? self->capture.ready : 0, playbackReady = self->playback.pcm ? self->playback.ready : 0; PA_ENSURE( PaAlsaStream_GetAvailableFrames( self, captureReady, playbackReady, framesAvail, &xrun ) ); if( self->capture.pcm && self->playback.pcm ) { if( !self->playback.ready && !self->neverDropInput ) { /* Drop input, a period's worth */ assert( self->capture.ready ); PaAlsaStreamComponent_EndProcessing( &self->capture, PA_MIN( self->capture.framesPerBuffer, *framesAvail ), &xrun ); *framesAvail = 0; self->capture.ready = 0; } } else if( self->capture.pcm ) assert( self->capture.ready ); else assert( self->playback.ready ); } end: error: if( xrun ) { /* Recover from the xrun state */ PA_ENSURE( PaAlsaStream_HandleXrun( self ) ); *framesAvail = 0; } else { if( 0 != *framesAvail ) { /* If we're reporting frames eligible for processing, one of the handles better be ready */ PA_UNLESS( self->capture.ready || self->playback.ready, paInternalError ); } } *xrunOccurred = xrun; return result; } /** Register per-channel ALSA buffer information with buffer processor. * * Mmapped buffer space is acquired from ALSA, and registered with the buffer processor. Differences between the * number of host and user channels is taken into account. * * @param numFrames On entrance the number of requested frames, on exit the number of contiguously accessible frames. */ static PaError PaAlsaStreamComponent_RegisterChannels( PaAlsaStreamComponent* self, PaUtilBufferProcessor* bp, unsigned long* numFrames, int* xrun ) { PaError result = paNoError; const snd_pcm_channel_area_t *areas, *area; void (*setChannel)(PaUtilBufferProcessor *, unsigned int, void *, unsigned int) = StreamDirection_In == self->streamDir ? PaUtil_SetInputChannel : PaUtil_SetOutputChannel; unsigned char *buffer, *p; int i; unsigned long framesAvail; /* This _must_ be called before mmap_begin */ PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( self, &framesAvail, xrun ) ); if( *xrun ) { *numFrames = 0; goto end; } ENSURE_( snd_pcm_mmap_begin( self->pcm, &areas, &self->offset, numFrames ), paUnanticipatedHostError ); if( self->hostInterleaved ) { int swidth = snd_pcm_format_size( self->nativeFormat, 1 ); p = buffer = ExtractAddress( areas, self->offset ); for( i = 0; i < self->numUserChannels; ++i ) { /* We're setting the channels up to userChannels, but the stride will be hostChannels samples */ setChannel( bp, i, p, self->numHostChannels ); p += swidth; } } else { for( i = 0; i < self->numUserChannels; ++i ) { area = areas + i; buffer = ExtractAddress( area, self->offset ); setChannel( bp, i, buffer, 1 ); } } /* @concern ChannelAdaption Buffer address is recorded so we can do some channel adaption later */ self->channelAreas = (snd_pcm_channel_area_t *)areas; end: error: return result; } /** Initiate buffer processing. * * ALSA buffers are registered with the PA buffer processor and the buffer size (in frames) set. * * @concern FullDuplex If both directions are being processed, the minimum amount of frames for the two directions is * calculated. * * @param numFrames On entrance the number of available frames, on exit the number of received frames * @param xrunOccurred Return whether an xrun has occurred */ static PaError PaAlsaStream_SetUpBuffers( PaAlsaStream* self, unsigned long* numFrames, int* xrunOccurred ) { PaError result = paNoError; unsigned long captureFrames = ULONG_MAX, playbackFrames = ULONG_MAX, commonFrames = 0; int xrun = 0; if( *xrunOccurred ) { *numFrames = 0; return result; } /* If we got here at least one of the pcm's should be marked ready */ PA_UNLESS( self->capture.ready || self->playback.ready, paInternalError ); /* Extract per-channel ALSA buffer pointers and register them with the buffer processor. * It is possible that a direction is not marked ready however, because it is out of sync with the other. */ if( self->capture.pcm && self->capture.ready ) { captureFrames = *numFrames; PA_ENSURE( PaAlsaStreamComponent_RegisterChannels( &self->capture, &self->bufferProcessor, &captureFrames, &xrun ) ); } if( self->playback.pcm && self->playback.ready ) { playbackFrames = *numFrames; PA_ENSURE( PaAlsaStreamComponent_RegisterChannels( &self->playback, &self->bufferProcessor, &playbackFrames, &xrun ) ); } if( xrun ) { /* Nothing more to do */ assert( 0 == commonFrames ); goto end; } commonFrames = PA_MIN( captureFrames, playbackFrames ); /* assert( commonFrames <= *numFrames ); */ if( commonFrames > *numFrames ) { /* Hmmm ... how come there are more frames available than we requested!? Blah. */ PA_DEBUG(( "%s: Common available frames are reported to be more than number requested: %lu, %lu, callbackMode: %d\n", __FUNCTION__, commonFrames, *numFrames, self->callbackMode )); if( self->capture.pcm ) { PA_DEBUG(( "%s: captureFrames: %lu, capture.ready: %d\n", __FUNCTION__, captureFrames, self->capture.ready )); } if( self->playback.pcm ) { PA_DEBUG(( "%s: playbackFrames: %lu, playback.ready: %d\n", __FUNCTION__, playbackFrames, self->playback.ready )); } commonFrames = 0; goto end; } /* Inform PortAudio of the number of frames we got. * @concern FullDuplex We might be experiencing underflow in either end; if its an input underflow, we go on * with output. If its output underflow however, depending on the paNeverDropInput flag, we may want to simply * discard the excess input or call the callback with paOutputOverflow flagged. */ if( self->capture.pcm ) { if( self->capture.ready ) { PaUtil_SetInputFrameCount( &self->bufferProcessor, commonFrames ); } else { /* We have input underflow */ PaUtil_SetNoInput( &self->bufferProcessor ); } } if( self->playback.pcm ) { if( self->playback.ready ) { PaUtil_SetOutputFrameCount( &self->bufferProcessor, commonFrames ); } else { /* We have output underflow, but keeping input data (paNeverDropInput) */ assert( self->neverDropInput ); assert( self->capture.pcm != NULL ); PA_DEBUG(( "%s: Setting output buffers to NULL\n", __FUNCTION__ )); PaUtil_SetNoOutput( &self->bufferProcessor ); } } end: *numFrames = commonFrames; error: if( xrun ) { PA_ENSURE( PaAlsaStream_HandleXrun( self ) ); *numFrames = 0; } *xrunOccurred = xrun; return result; } /** Callback thread's function. * * Roughly, the workflow can be described in the following way: The number of available frames that can be processed * directly is obtained from ALSA, we then request as much directly accessible memory as possible within this amount * from ALSA. The buffer memory is registered with the PA buffer processor and processing is carried out with * PaUtil_EndBufferProcessing. Finally, the number of processed frames is reported to ALSA. The processing can * happen in several iterations untill we have consumed the known number of available frames (or an xrun is detected). */ static void *CallbackThreadFunc( void *userData ) { PaError result = paNoError; PaAlsaStream *stream = (PaAlsaStream*) userData; PaStreamCallbackTimeInfo timeInfo = {0, 0, 0}; snd_pcm_sframes_t startThreshold = 0; int callbackResult = paContinue; PaStreamCallbackFlags cbFlags = 0; /* We might want to keep state across iterations */ int streamStarted = 0; assert( stream ); /* Execute OnExit when exiting */ pthread_cleanup_push( &OnExit, stream ); /* Not implemented */ assert( !stream->primeBuffers ); /* @concern StreamStart If the output is being primed the output pcm needs to be prepared, otherwise the * stream is started immediately. The latter involves signaling the waiting main thread. */ if( stream->primeBuffers ) { snd_pcm_sframes_t avail; if( stream->playback.pcm ) ENSURE_( snd_pcm_prepare( stream->playback.pcm ), paUnanticipatedHostError ); if( stream->capture.pcm && !stream->pcmsSynced ) ENSURE_( snd_pcm_prepare( stream->capture.pcm ), paUnanticipatedHostError ); /* We can't be certain that the whole ring buffer is available for priming, but there should be * at least one period */ avail = snd_pcm_avail_update( stream->playback.pcm ); startThreshold = avail - (avail % stream->playback.framesPerBuffer); assert( startThreshold >= stream->playback.framesPerBuffer ); } else { PA_ENSURE( PaUnixThread_PrepareNotify( &stream->thread ) ); /* Buffer will be zeroed */ PA_ENSURE( AlsaStart( stream, 0 ) ); PA_ENSURE( PaUnixThread_NotifyParent( &stream->thread ) ); streamStarted = 1; } while( 1 ) { unsigned long framesAvail, framesGot; int xrun = 0; pthread_testcancel(); /* @concern StreamStop if the main thread has requested a stop and the stream has not been effectively * stopped we signal this condition by modifying callbackResult (we'll want to flush buffered output). */ if( PaUnixThread_StopRequested( &stream->thread ) && paContinue == callbackResult ) { PA_DEBUG(( "Setting callbackResult to paComplete\n" )); callbackResult = paComplete; } if( paContinue != callbackResult ) { stream->callbackAbort = (paAbort == callbackResult); if( stream->callbackAbort || /** @concern BlockAdaption: Go on if adaption buffers are empty */ PaUtil_IsBufferProcessorOutputEmpty( &stream->bufferProcessor ) ) { goto end; } PA_DEBUG(( "%s: Flushing buffer processor\n", __FUNCTION__ )); /* There is still buffered output that needs to be processed */ } /* Wait for data to become available, this comes down to polling the ALSA file descriptors untill we have * a number of available frames. */ PA_ENSURE( PaAlsaStream_WaitForFrames( stream, &framesAvail, &xrun ) ); if( xrun ) { assert( 0 == framesAvail ); continue; /* XXX: Report xruns to the user? A situation is conceivable where the callback is never invoked due * to constant xruns, it might be desirable to notify the user of this. */ } /* Consume buffer space. Once we have a number of frames available for consumption we must retrieve the * mmapped buffers from ALSA, this is contiguously accessible memory however, so we may receive smaller * portions at a time than is available as a whole. Therefore we should be prepared to process several * chunks successively. The buffers are passed to the PA buffer processor. */ while( framesAvail > 0 ) { xrun = 0; pthread_testcancel(); /** @concern Xruns Under/overflows are to be reported to the callback */ if( stream->underrun > 0.0 ) { cbFlags |= paOutputUnderflow; stream->underrun = 0.0; } if( stream->overrun > 0.0 ) { cbFlags |= paInputOverflow; stream->overrun = 0.0; } if( stream->capture.pcm && stream->playback.pcm ) { /** @concern FullDuplex It's possible that only one direction is being processed to avoid an * under- or overflow, this should be reported correspondingly */ if( !stream->capture.ready ) { cbFlags |= paInputUnderflow; PA_DEBUG(( "%s: Input underflow\n", __FUNCTION__ )); } else if( !stream->playback.ready ) { cbFlags |= paOutputOverflow; PA_DEBUG(( "%s: Output overflow\n", __FUNCTION__ )); } } #if 0 CallbackUpdate( &stream->threading ); #endif CalculateTimeInfo( stream, &timeInfo ); PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, cbFlags ); cbFlags = 0; /* CPU load measurement should include processing activivity external to the stream callback */ PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); framesGot = framesAvail; if( paUtilFixedHostBufferSize == stream->bufferProcessor.hostBufferSizeMode ) { /* We've committed to a fixed host buffer size, stick to that */ framesGot = framesGot >= stream->maxFramesPerHostBuffer ? stream->maxFramesPerHostBuffer : 0; } else { /* We've committed to an upper bound on the size of host buffers */ assert( paUtilBoundedHostBufferSize == stream->bufferProcessor.hostBufferSizeMode ); framesGot = PA_MIN( framesGot, stream->maxFramesPerHostBuffer ); } PA_ENSURE( PaAlsaStream_SetUpBuffers( stream, &framesGot, &xrun ) ); /* Check the host buffer size against the buffer processor configuration */ framesAvail -= framesGot; if( framesGot > 0 ) { assert( !xrun ); PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult ); PA_ENSURE( PaAlsaStream_EndProcessing( stream, framesGot, &xrun ) ); } PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesGot ); if( 0 == framesGot ) { /* Go back to polling for more frames */ break; } if( paContinue != callbackResult ) break; } } /* Match pthread_cleanup_push */ pthread_cleanup_pop( 1 ); end: PA_DEBUG(( "%s: Thread %d exiting\n ", __FUNCTION__, pthread_self() )); PaUnixThreading_EXIT( result ); error: goto end; } /* Blocking interface */ static PaError ReadStream( PaStream* s, void *buffer, unsigned long frames ) { PaError result = paNoError; PaAlsaStream *stream = (PaAlsaStream*)s; unsigned long framesGot, framesAvail; void *userBuffer; snd_pcm_t *save = stream->playback.pcm; assert( stream ); PA_UNLESS( stream->capture.pcm, paCanNotReadFromAnOutputOnlyStream ); /* Disregard playback */ stream->playback.pcm = NULL; if( stream->overrun > 0. ) { result = paInputOverflowed; stream->overrun = 0.0; } if( stream->capture.userInterleaved ) { userBuffer = buffer; } else { /* Copy channels into local array */ userBuffer = stream->capture.userBuffers; memcpy( userBuffer, buffer, sizeof (void *) * stream->capture.numUserChannels ); } /* Start stream if in prepared state */ if( snd_pcm_state( stream->capture.pcm ) == SND_PCM_STATE_PREPARED ) { ENSURE_( snd_pcm_start( stream->capture.pcm ), paUnanticipatedHostError ); } while( frames > 0 ) { int xrun = 0; PA_ENSURE( PaAlsaStream_WaitForFrames( stream, &framesAvail, &xrun ) ); framesGot = PA_MIN( framesAvail, frames ); PA_ENSURE( PaAlsaStream_SetUpBuffers( stream, &framesGot, &xrun ) ); if( framesGot > 0 ) { framesGot = PaUtil_CopyInput( &stream->bufferProcessor, &userBuffer, framesGot ); PA_ENSURE( PaAlsaStream_EndProcessing( stream, framesGot, &xrun ) ); frames -= framesGot; } } end: stream->playback.pcm = save; return result; error: goto end; } static PaError WriteStream( PaStream* s, const void *buffer, unsigned long frames ) { PaError result = paNoError; signed long err; PaAlsaStream *stream = (PaAlsaStream*)s; snd_pcm_uframes_t framesGot, framesAvail; const void *userBuffer; snd_pcm_t *save = stream->capture.pcm; assert( stream ); PA_UNLESS( stream->playback.pcm, paCanNotWriteToAnInputOnlyStream ); /* Disregard capture */ stream->capture.pcm = NULL; if( stream->underrun > 0. ) { result = paOutputUnderflowed; stream->underrun = 0.0; } if( stream->playback.userInterleaved ) userBuffer = buffer; else /* Copy channels into local array */ { userBuffer = stream->playback.userBuffers; memcpy( (void *)userBuffer, buffer, sizeof (void *) * stream->playback.numUserChannels ); } while( frames > 0 ) { int xrun = 0; snd_pcm_uframes_t hwAvail; PA_ENSURE( PaAlsaStream_WaitForFrames( stream, &framesAvail, &xrun ) ); framesGot = PA_MIN( framesAvail, frames ); PA_ENSURE( PaAlsaStream_SetUpBuffers( stream, &framesGot, &xrun ) ); if( framesGot > 0 ) { framesGot = PaUtil_CopyOutput( &stream->bufferProcessor, &userBuffer, framesGot ); PA_ENSURE( PaAlsaStream_EndProcessing( stream, framesGot, &xrun ) ); frames -= framesGot; } /* Start stream after one period of samples worth */ /* Frames residing in buffer */ PA_ENSURE( err = GetStreamWriteAvailable( stream ) ); framesAvail = err; hwAvail = stream->playback.bufferSize - framesAvail; if( snd_pcm_state( stream->playback.pcm ) == SND_PCM_STATE_PREPARED && hwAvail >= stream->playback.framesPerBuffer ) { ENSURE_( snd_pcm_start( stream->playback.pcm ), paUnanticipatedHostError ); } } end: stream->capture.pcm = save; return result; error: goto end; } /* Return frames available for reading. In the event of an overflow, the capture pcm will be restarted */ static signed long GetStreamReadAvailable( PaStream* s ) { PaError result = paNoError; PaAlsaStream *stream = (PaAlsaStream*)s; unsigned long avail; int xrun; PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &stream->capture, &avail, &xrun ) ); if( xrun ) { PA_ENSURE( PaAlsaStream_HandleXrun( stream ) ); PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &stream->capture, &avail, &xrun ) ); if( xrun ) PA_ENSURE( paInputOverflowed ); } return (signed long)avail; error: return result; } static signed long GetStreamWriteAvailable( PaStream* s ) { PaError result = paNoError; PaAlsaStream *stream = (PaAlsaStream*)s; unsigned long avail; int xrun; PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &stream->playback, &avail, &xrun ) ); if( xrun ) { snd_pcm_sframes_t savail; PA_ENSURE( PaAlsaStream_HandleXrun( stream ) ); savail = snd_pcm_avail_update( stream->playback.pcm ); /* savail should not contain -EPIPE now, since PaAlsaStream_HandleXrun will only prepare the pcm */ ENSURE_( savail, paUnanticipatedHostError ); avail = (unsigned long) savail; } return (signed long)avail; error: return result; } /* Extensions */ void PaAlsa_InitializeStreamInfo( PaAlsaStreamInfo *info ) { info->size = sizeof (PaAlsaStreamInfo); info->hostApiType = paALSA; info->version = 1; info->deviceString = NULL; } void PaAlsa_EnableRealtimeScheduling( PaStream *s, int enable ) { PaAlsaStream *stream = (PaAlsaStream *) s; stream->rtSched = enable; } #if 0 void PaAlsa_EnableWatchdog( PaStream *s, int enable ) { PaAlsaStream *stream = (PaAlsaStream *) s; stream->thread.useWatchdog = enable; } #endif PaError PaAlsa_GetStreamInputCard(PaStream* s, int* card) { PaAlsaStream *stream = (PaAlsaStream *) s; snd_pcm_info_t* pcmInfo; PaError result = paNoError; /* XXX: More descriptive error? */ PA_UNLESS( stream->capture.pcm, paDeviceUnavailable ); snd_pcm_info_alloca( &pcmInfo ); PA_ENSURE( snd_pcm_info( stream->capture.pcm, pcmInfo ) ); *card = snd_pcm_info_get_card( pcmInfo ); error: return result; } PaError PaAlsa_GetStreamOutputCard(PaStream* s, int* card) { PaAlsaStream *stream = (PaAlsaStream *) s; snd_pcm_info_t* pcmInfo; PaError result = paNoError; /* XXX: More descriptive error? */ PA_UNLESS( stream->playback.pcm, paDeviceUnavailable ); snd_pcm_info_alloca( &pcmInfo ); PA_ENSURE( snd_pcm_info( stream->playback.pcm, pcmInfo ) ); *card = snd_pcm_info_get_card( pcmInfo ); error: return result; } #endifpraat-6.0.04/external/portaudio2007/pa_linux_alsa.h000066400000000000000000000063771261542461700220660ustar00rootroot00000000000000#ifndef PA_LINUX_ALSA_H #define PA_LINUX_ALSA_H /* * $Id: pa_linux_alsa.h 1236 2007-06-24 20:39:26Z aknudsen $ * PortAudio Portable Real-Time Audio Library * ALSA-specific extensions * * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file * ALSA-specific PortAudio API extension header file. */ #include "portaudio.h" #ifdef __cplusplus extern "C" { #endif typedef struct PaAlsaStreamInfo { unsigned long size; PaHostApiTypeId hostApiType; unsigned long version; const char *deviceString; } PaAlsaStreamInfo; /** Initialize host API specific structure, call this before setting relevant attributes. */ void PaAlsa_InitializeStreamInfo( PaAlsaStreamInfo *info ); /** Instruct whether to enable real-time priority when starting the audio thread. * * If this is turned on by the stream is started, the audio callback thread will be created * with the FIFO scheduling policy, which is suitable for realtime operation. **/ void PaAlsa_EnableRealtimeScheduling( PaStream *s, int enable ); #if 0 void PaAlsa_EnableWatchdog( PaStream *s, int enable ); #endif /** Get the ALSA-lib card index of this stream's input device. */ PaError PaAlsa_GetStreamInputCard( PaStream *s, int *card ); /** Get the ALSA-lib card index of this stream's output device. */ PaError PaAlsa_GetStreamOutputCard( PaStream *s, int *card ); /** Set the number of periods (buffer fragments) to configure devices with. * * By default the number of periods is 4, this is the lowest number of periods that works well on * the author's soundcard. * @param numPeriods The number of periods. */ PaError PaAlsa_SetNumPeriods( int numPeriods ); PaError PaAlsa_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ); #ifdef __cplusplus } #endif #endif praat-6.0.04/external/portaudio2007/pa_mac_core.c000066400000000000000000002705371261542461700214730ustar00rootroot00000000000000/* * Implementation of the PortAudio API for Apple AUHAL * * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * * Written by Bjorn Roche of XO Audio LLC, from PA skeleton code. * Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation) * * Dominic's code was based on code by Phil Burk, Darren Gibbs, * Gord Peters, Stephane Letz, and Greg Pfiel. * * The following people also deserve acknowledgements: * * Olivier Tristan for feedback and testing * Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O * interface. * * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file pa_mac_core @ingroup hostapi_src @author Bjorn Roche @brief AUHAL implementation of PortAudio */ /* FIXME: not all error conditions call PaUtil_SetLastHostErrorInfo() * PaMacCore_SetError() will do this. */ #include "pa_mac_core_internal.h" #include /* strlen(), memcmp() etc. */ #include #include #include "pa_mac_core.h" #include "pa_mac_core_utilities.h" #include "pa_mac_core_blocking.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* prototypes for functions declared in this file */ PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); /* * Function declared in pa_mac_core.h. Sets up a PaMacCoreStreamInfoStruct * with the requested flags and initializes channel map. */ void PaMacCore_SetupStreamInfo( PaMacCoreStreamInfo *data, const unsigned long flags ) { bzero( data, sizeof( PaMacCoreStreamInfo ) ); data->size = sizeof( PaMacCoreStreamInfo ); data->hostApiType = paCoreAudio; data->version = 0x01; data->flags = flags; data->channelMap = NULL; data->channelMapSize = 0; } /* * Function declared in pa_mac_core.h. Adds channel mapping to a PaMacCoreStreamInfoStruct */ void PaMacCore_SetupChannelMap( PaMacCoreStreamInfo *data, const SInt32 * const channelMap, const unsigned long channelMapSize ) { data->channelMap = channelMap; data->channelMapSize = channelMapSize; } static char *channelName = NULL; static int channelNameSize = 0; static bool ensureChannelNameSize( int size ) { if( size >= channelNameSize ) { free( channelName ); channelName = (char *) malloc( ( channelNameSize = size ) + 1 ); if( !channelName ) { channelNameSize = 0; return false; } } return true; } /* * Function declared in pa_mac_core.h. retrives channel names. */ const char *PaMacCore_GetChannelName( int device, int channelIndex, bool input ) { struct PaUtilHostApiRepresentation *hostApi; PaError err; OSStatus error; err = PaUtil_GetHostApiRepresentation( &hostApi, paCoreAudio ); assert(err == paNoError); PaMacAUHAL *macCoreHostApi = (PaMacAUHAL*)hostApi; AudioDeviceID hostApiDevice = macCoreHostApi->devIds[device]; UInt32 size = 0; error = AudioDeviceGetPropertyInfo( hostApiDevice, channelIndex + 1, input, kAudioDevicePropertyChannelName, &size, NULL ); if( error ) { //try the CFString CFStringRef name; bool isDeviceName = false; size = sizeof( name ); error = AudioDeviceGetProperty( hostApiDevice, channelIndex + 1, input, kAudioDevicePropertyChannelNameCFString, &size, &name ); if( error ) { //as a last-ditch effort, get the device name. Later we'll append the channel number. size = sizeof( name ); error = AudioDeviceGetProperty( hostApiDevice, channelIndex + 1, input, kAudioDevicePropertyDeviceNameCFString, &size, &name ); if( error ) return NULL; isDeviceName = true; } if( isDeviceName ) { name = CFStringCreateWithFormat( NULL, NULL, CFSTR( "%@: %d"), name, channelIndex + 1 ); } CFIndex length = CFStringGetLength(name); while( ensureChannelNameSize( length * sizeof(UniChar) + 1 ) ) { if( CFStringGetCString( name, channelName, channelNameSize, kCFStringEncodingUTF8 ) ) { if( isDeviceName ) CFRelease( name ); return channelName; } if( length == 0 ) ++length; length *= 2; } if( isDeviceName ) CFRelease( name ); return NULL; } //continue with C string: if( !ensureChannelNameSize( size ) ) return NULL; error = AudioDeviceGetProperty( hostApiDevice, channelIndex + 1, input, kAudioDevicePropertyChannelName, &size, channelName ); if( error ) { ERR( error ); return NULL; } return channelName; } AudioDeviceID PaMacCore_GetStreamInputDevice( PaStream* s ) { PaMacCoreStream *stream = (PaMacCoreStream*)s; VVDBUG(("PaMacCore_GetStreamInputHandle()\n")); return ( stream->inputDevice ); } AudioDeviceID PaMacCore_GetStreamOutputDevice( PaStream* s ) { PaMacCoreStream *stream = (PaMacCoreStream*)s; VVDBUG(("PaMacCore_GetStreamOutputHandle()\n")); return ( stream->outputDevice ); } #ifdef __cplusplus } #endif /* __cplusplus */ #define RING_BUFFER_ADVANCE_DENOMINATOR (4) static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); static PaError CloseStream( PaStream* stream ); static PaError StartStream( PaStream *stream ); static PaError StopStream( PaStream *stream ); static PaError AbortStream( PaStream *stream ); static PaError IsStreamStopped( PaStream *s ); static PaError IsStreamActive( PaStream *stream ); static PaTime GetStreamTime( PaStream *stream ); static void setStreamStartTime( PaStream *stream ); static OSStatus AudioIOProc( void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData ); static double GetStreamCpuLoad( PaStream* stream ); static PaError GetChannelInfo( PaMacAUHAL *auhalHostApi, PaDeviceInfo *deviceInfo, AudioDeviceID macCoreDeviceId, int isInput); static PaError OpenAndSetupOneAudioUnit( const PaMacCoreStream *stream, const PaStreamParameters *inStreamParams, const PaStreamParameters *outStreamParams, const UInt32 requestedFramesPerBuffer, UInt32 *actualInputFramesPerBuffer, UInt32 *actualOutputFramesPerBuffer, const PaMacAUHAL *auhalHostApi, AudioUnit *audioUnit, AudioConverterRef *srConverter, AudioDeviceID *audioDevice, const double sampleRate, void *refCon ); /* for setting errors. */ #define PA_AUHAL_SET_LAST_HOST_ERROR( errorCode, errorText ) \ PaUtil_SetLastHostErrorInfo( paInDevelopment, errorCode, errorText ) /* * Callback for setting over/underrun flags. * */ static OSStatus xrunCallback( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData) { PaMacCoreStream *stream = (PaMacCoreStream *) inClientData; if( stream->state != ACTIVE ) return 0; //if the stream isn't active, we don't care if the device is dropping if( isInput ) OSAtomicOr32( paInputUnderflow, (uint32_t *)&(stream->xrunFlags) ); else OSAtomicOr32( paOutputOverflow, (uint32_t *)&(stream->xrunFlags) ); return 0; } /* * Callback called when starting or stopping a stream. */ static void startStopCallback( void * inRefCon, AudioUnit ci, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement ) { PaMacCoreStream *stream = (PaMacCoreStream *) inRefCon; UInt32 isRunning; UInt32 size = sizeof( isRunning ); assert( !AudioUnitGetProperty( ci, kAudioOutputUnitProperty_IsRunning, inScope, inElement, &isRunning, &size ) ); if( isRunning ) return; //We are only interested in when we are stopping // -- if we are using 2 I/O units, we only need one notification! if( stream->inputUnit && stream->outputUnit && stream->inputUnit != stream->outputUnit && ci == stream->inputUnit ) return; PaStreamFinishedCallback *sfc = stream->streamRepresentation.streamFinishedCallback; if( stream->state == STOPPING ) stream->state = STOPPED ; if( sfc ) sfc( stream->streamRepresentation.userData ); } /*currently, this is only used in initialization, but it might be modified to be used when the list of devices changes.*/ static PaError gatherDeviceInfo(PaMacAUHAL *auhalHostApi) { UInt32 size; UInt32 propsize; VVDBUG(("gatherDeviceInfo()\n")); /* -- free any previous allocations -- */ if( auhalHostApi->devIds ) PaUtil_GroupFreeMemory(auhalHostApi->allocations, auhalHostApi->devIds); auhalHostApi->devIds = NULL; /* -- figure out how many devices there are -- */ AudioHardwareGetPropertyInfo( kAudioHardwarePropertyDevices, &propsize, NULL ); auhalHostApi->devCount = propsize / sizeof( AudioDeviceID ); VDBUG( ( "Found %ld device(s).\n", auhalHostApi->devCount ) ); /* -- copy the device IDs -- */ auhalHostApi->devIds = (AudioDeviceID *)PaUtil_GroupAllocateMemory( auhalHostApi->allocations, propsize ); if( !auhalHostApi->devIds ) return paInsufficientMemory; AudioHardwareGetProperty( kAudioHardwarePropertyDevices, &propsize, auhalHostApi->devIds ); #ifdef MAC_CORE_VERBOSE_DEBUG { int i; for( i=0; idevCount; ++i ) printf( "Device %d\t: %ld\n", i, auhalHostApi->devIds[i] ); } #endif size = sizeof(AudioDeviceID); auhalHostApi->defaultIn = kAudioDeviceUnknown; auhalHostApi->defaultOut = kAudioDeviceUnknown; /* determine the default device. */ /* I am not sure how these calls to AudioHardwareGetProperty() could fail, but in case they do, we use the first available device as the default. */ if( 0 != AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &size, &auhalHostApi->defaultIn) ) { int i; auhalHostApi->defaultIn = kAudioDeviceUnknown; VDBUG(("Failed to get default input device from OS.")); VDBUG((" I will substitute the first available input Device.")); for( i=0; idevCount; ++i ) { PaDeviceInfo devInfo; if( 0 != GetChannelInfo( auhalHostApi, &devInfo, auhalHostApi->devIds[i], TRUE ) ) if( devInfo.maxInputChannels ) { auhalHostApi->defaultIn = auhalHostApi->devIds[i]; break; } } } if( 0 != AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &size, &auhalHostApi->defaultOut) ) { int i; auhalHostApi->defaultIn = kAudioDeviceUnknown; VDBUG(("Failed to get default output device from OS.")); VDBUG((" I will substitute the first available output Device.")); for( i=0; idevCount; ++i ) { PaDeviceInfo devInfo; if( 0 != GetChannelInfo( auhalHostApi, &devInfo, auhalHostApi->devIds[i], FALSE ) ) if( devInfo.maxOutputChannels ) { auhalHostApi->defaultOut = auhalHostApi->devIds[i]; break; } } } VDBUG( ( "Default in : %ld\n", auhalHostApi->defaultIn ) ); VDBUG( ( "Default out: %ld\n", auhalHostApi->defaultOut ) ); return paNoError; } static PaError GetChannelInfo( PaMacAUHAL *auhalHostApi, PaDeviceInfo *deviceInfo, AudioDeviceID macCoreDeviceId, int isInput) { UInt32 propSize; PaError err = paNoError; UInt32 i; int numChannels = 0; AudioBufferList *buflist = NULL; UInt32 frameLatency; VVDBUG(("GetChannelInfo()\n")); /* Get the number of channels from the stream configuration. Fail if we can't get this. */ err = ERR(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, isInput, kAudioDevicePropertyStreamConfiguration, &propSize, NULL)); if (err) return err; buflist = PaUtil_AllocateMemory(propSize); if( !buflist ) return paInsufficientMemory; err = ERR(AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyStreamConfiguration, &propSize, buflist)); if (err) goto error; for (i = 0; i < buflist->mNumberBuffers; ++i) numChannels += buflist->mBuffers[i].mNumberChannels; if (isInput) deviceInfo->maxInputChannels = numChannels; else deviceInfo->maxOutputChannels = numChannels; if (numChannels > 0) /* do not try to retrieve the latency if there is no channels. */ { /* Get the latency. Don't fail if we can't get this. */ /* default to something reasonable */ deviceInfo->defaultLowInputLatency = .01; deviceInfo->defaultHighInputLatency = .10; deviceInfo->defaultLowOutputLatency = .01; deviceInfo->defaultHighOutputLatency = .10; propSize = sizeof(UInt32); err = WARNING(AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyLatency, &propSize, &frameLatency)); if (!err) { /** FEEDBACK: * This code was arrived at by trial and error, and some extentive, but not exhaustive * testing. Sebastien Beaulieu has suggested using * kAudioDevicePropertyLatency + kAudioDevicePropertySafetyOffset + buffer size instead. * At the time this code was written, many users were reporting dropouts with audio * programs that probably used this formula. This was probably * around 10.4.4, and the problem is probably fixed now. So perhaps * his formula should be reviewed and used. * */ double secondLatency = frameLatency / deviceInfo->defaultSampleRate; if (isInput) { deviceInfo->defaultLowInputLatency = 3 * secondLatency; deviceInfo->defaultHighInputLatency = 3 * 10 * secondLatency; } else { deviceInfo->defaultLowOutputLatency = 3 * secondLatency; deviceInfo->defaultHighOutputLatency = 3 * 10 * secondLatency; } } } PaUtil_FreeMemory( buflist ); return paNoError; error: PaUtil_FreeMemory( buflist ); return err; } static PaError InitializeDeviceInfo( PaMacAUHAL *auhalHostApi, PaDeviceInfo *deviceInfo, AudioDeviceID macCoreDeviceId, PaHostApiIndex hostApiIndex ) { Float64 sampleRate; char *name; PaError err = paNoError; UInt32 propSize; VVDBUG(("InitializeDeviceInfo(): macCoreDeviceId=%ld\n", macCoreDeviceId)); memset(deviceInfo, 0, sizeof(deviceInfo)); deviceInfo->structVersion = 2; deviceInfo->hostApi = hostApiIndex; /* Get the device name. Fail if we can't get it. */ err = ERR(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, NULL)); if (err) return err; name = PaUtil_GroupAllocateMemory(auhalHostApi->allocations,propSize); if ( !name ) return paInsufficientMemory; err = ERR(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, name)); if (err) return err; deviceInfo->name = name; /* Try to get the default sample rate. Don't fail if we can't get this. */ propSize = sizeof(Float64); err = ERR(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyNominalSampleRate, &propSize, &sampleRate)); if (err) deviceInfo->defaultSampleRate = 0.0; else deviceInfo->defaultSampleRate = sampleRate; /* Get the maximum number of input and output channels. Fail if we can't get this. */ err = GetChannelInfo(auhalHostApi, deviceInfo, macCoreDeviceId, 1); if (err) return err; err = GetChannelInfo(auhalHostApi, deviceInfo, macCoreDeviceId, 0); if (err) return err; return paNoError; } PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) { PaError result = paNoError; int i; PaMacAUHAL *auhalHostApi; PaDeviceInfo *deviceInfoArray; VVDBUG(("PaMacCore_Initialize(): hostApiIndex=%d\n", hostApiIndex)); auhalHostApi = (PaMacAUHAL*)PaUtil_AllocateMemory( sizeof(PaMacAUHAL) ); if( !auhalHostApi ) { result = paInsufficientMemory; goto error; } auhalHostApi->allocations = PaUtil_CreateAllocationGroup(); if( !auhalHostApi->allocations ) { result = paInsufficientMemory; goto error; } auhalHostApi->devIds = NULL; auhalHostApi->devCount = 0; /* get the info we need about the devices */ result = gatherDeviceInfo( auhalHostApi ); if( result != paNoError ) goto error; *hostApi = &auhalHostApi->inheritedHostApiRep; (*hostApi)->info.structVersion = 1; (*hostApi)->info.type = paCoreAudio; (*hostApi)->info.name = "Core Audio"; (*hostApi)->info.defaultInputDevice = paNoDevice; (*hostApi)->info.defaultOutputDevice = paNoDevice; (*hostApi)->info.deviceCount = 0; if( auhalHostApi->devCount > 0 ) { (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( auhalHostApi->allocations, sizeof(PaDeviceInfo*) * auhalHostApi->devCount); if( !(*hostApi)->deviceInfos ) { result = paInsufficientMemory; goto error; } /* allocate all device info structs in a contiguous block */ deviceInfoArray = (PaDeviceInfo*)PaUtil_GroupAllocateMemory( auhalHostApi->allocations, sizeof(PaDeviceInfo) * auhalHostApi->devCount ); if( !deviceInfoArray ) { result = paInsufficientMemory; goto error; } for( i=0; i < auhalHostApi->devCount; ++i ) { int err; err = InitializeDeviceInfo( auhalHostApi, &deviceInfoArray[i], auhalHostApi->devIds[i], hostApiIndex ); if (err == paNoError) { /* copy some info and set the defaults */ (*hostApi)->deviceInfos[(*hostApi)->info.deviceCount] = &deviceInfoArray[i]; if (auhalHostApi->devIds[i] == auhalHostApi->defaultIn) (*hostApi)->info.defaultInputDevice = (*hostApi)->info.deviceCount; if (auhalHostApi->devIds[i] == auhalHostApi->defaultOut) (*hostApi)->info.defaultOutputDevice = (*hostApi)->info.deviceCount; (*hostApi)->info.deviceCount++; } else { /* there was an error. we need to shift the devices down, so we ignore this one */ int j; auhalHostApi->devCount--; for( j=i; jdevCount; ++j ) auhalHostApi->devIds[j] = auhalHostApi->devIds[j+1]; i--; } } } (*hostApi)->Terminate = Terminate; (*hostApi)->OpenStream = OpenStream; (*hostApi)->IsFormatSupported = IsFormatSupported; PaUtil_InitializeStreamInterface( &auhalHostApi->callbackStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, GetStreamCpuLoad, PaUtil_DummyRead, PaUtil_DummyWrite, PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); PaUtil_InitializeStreamInterface( &auhalHostApi->blockingStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, PaUtil_DummyGetCpuLoad, ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable ); return result; error: if( auhalHostApi ) { if( auhalHostApi->allocations ) { PaUtil_FreeAllAllocations( auhalHostApi->allocations ); PaUtil_DestroyAllocationGroup( auhalHostApi->allocations ); } PaUtil_FreeMemory( auhalHostApi ); } return result; } static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) { PaMacAUHAL *auhalHostApi = (PaMacAUHAL*)hostApi; VVDBUG(("Terminate()\n")); /* IMPLEMENT ME: - clean up any resources not handled by the allocation group TODO: Double check that everything is handled by alloc group */ if( auhalHostApi->allocations ) { PaUtil_FreeAllAllocations( auhalHostApi->allocations ); PaUtil_DestroyAllocationGroup( auhalHostApi->allocations ); } PaUtil_FreeMemory( auhalHostApi ); } static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { int inputChannelCount, outputChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; VVDBUG(("IsFormatSupported(): in chan=%d, in fmt=%ld, out chan=%d, out fmt=%ld sampleRate=%g\n", inputParameters ? inputParameters->channelCount : -1, inputParameters ? inputParameters->sampleFormat : -1, outputParameters ? outputParameters->channelCount : -1, outputParameters ? outputParameters->sampleFormat : -1, (float) sampleRate )); /** These first checks are standard PA checks. We do some fancier checks later. */ if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( inputSampleFormat & paCustomFormat ) return paSampleFormatNotSupported; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that input device can support inputChannelCount */ if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) return paInvalidChannelCount; } else { inputChannelCount = 0; } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( outputSampleFormat & paCustomFormat ) return paSampleFormatNotSupported; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that output device can support outputChannelCount */ if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) return paInvalidChannelCount; } else { outputChannelCount = 0; } /* FEEDBACK */ /* I think the only way to check a given format SR combo is */ /* to try opening it. This could be disruptive, is that Okay? */ /* The alternative is to just read off available sample rates, */ /* but this will not work %100 of the time (eg, a device that */ /* supports N output at one rate but only N/2 at a higher rate.)*/ /* The following code opens the device with the requested parameters to see if it works. */ { PaError err; PaStream *s; err = OpenStream( hostApi, &s, inputParameters, outputParameters, sampleRate, 1024, 0, (PaStreamCallback *)1, NULL ); if( err != paNoError && err != paInvalidSampleRate ) DBUG( ( "OpenStream @ %g returned: %d: %s\n", (float) sampleRate, err, Pa_GetErrorText( err ) ) ); if( err ) return err; err = CloseStream( s ); if( err ) { /* FEEDBACK: is this more serious? should we assert? */ DBUG( ( "WARNING: could not close Stream. %d: %s\n", err, Pa_GetErrorText( err ) ) ); } } return paFormatIsSupported; } static PaError OpenAndSetupOneAudioUnit( const PaMacCoreStream *stream, const PaStreamParameters *inStreamParams, const PaStreamParameters *outStreamParams, const UInt32 requestedFramesPerBuffer, UInt32 *actualInputFramesPerBuffer, UInt32 *actualOutputFramesPerBuffer, const PaMacAUHAL *auhalHostApi, AudioUnit *audioUnit, AudioConverterRef *srConverter, AudioDeviceID *audioDevice, const double sampleRate, void *refCon ) { ComponentDescription desc; Component comp; /*An Apple TN suggests using CAStreamBasicDescription, but that is C++*/ AudioStreamBasicDescription desiredFormat; OSStatus result = noErr; PaError paResult = paNoError; int line = 0; UInt32 callbackKey; AURenderCallbackStruct rcbs; unsigned long macInputStreamFlags = paMacCorePlayNice; unsigned long macOutputStreamFlags = paMacCorePlayNice; SInt32 const *inChannelMap = NULL; SInt32 const *outChannelMap = NULL; unsigned long inChannelMapSize = 0; unsigned long outChannelMapSize = 0; VVDBUG(("OpenAndSetupOneAudioUnit(): in chan=%d, in fmt=%ld, out chan=%d, out fmt=%ld, requestedFramesPerBuffer=%ld\n", inStreamParams ? inStreamParams->channelCount : -1, inStreamParams ? inStreamParams->sampleFormat : -1, outStreamParams ? outStreamParams->channelCount : -1, outStreamParams ? outStreamParams->sampleFormat : -1, requestedFramesPerBuffer )); /* -- handle the degenerate case -- */ if( !inStreamParams && !outStreamParams ) { *audioUnit = NULL; *audioDevice = kAudioDeviceUnknown; return paNoError; } /* -- get the user's api specific info, if they set any -- */ if( inStreamParams && inStreamParams->hostApiSpecificStreamInfo ) { macInputStreamFlags= ((PaMacCoreStreamInfo*)inStreamParams->hostApiSpecificStreamInfo) ->flags; inChannelMap = ((PaMacCoreStreamInfo*)inStreamParams->hostApiSpecificStreamInfo) ->channelMap; inChannelMapSize = ((PaMacCoreStreamInfo*)inStreamParams->hostApiSpecificStreamInfo) ->channelMapSize; } if( outStreamParams && outStreamParams->hostApiSpecificStreamInfo ) { macOutputStreamFlags= ((PaMacCoreStreamInfo*)outStreamParams->hostApiSpecificStreamInfo) ->flags; outChannelMap = ((PaMacCoreStreamInfo*)outStreamParams->hostApiSpecificStreamInfo) ->channelMap; outChannelMapSize = ((PaMacCoreStreamInfo*)outStreamParams->hostApiSpecificStreamInfo) ->channelMapSize; } /* Override user's flags here, if desired for testing. */ /* * The HAL AU is a Mac OS style "component". * the first few steps deal with that. * Later steps work on a combination of Mac OS * components and the slightly lower level * HAL. */ /* -- describe the output type AudioUnit -- */ /* Note: for the default AudioUnit, we could use the * componentSubType value kAudioUnitSubType_DefaultOutput; * but I don't think that's relevant here. */ desc.componentType = kAudioUnitType_Output; desc.componentSubType = kAudioUnitSubType_HALOutput; desc.componentManufacturer = kAudioUnitManufacturer_Apple; desc.componentFlags = 0; desc.componentFlagsMask = 0; /* -- find the component -- */ comp = FindNextComponent( NULL, &desc ); if( !comp ) { DBUG( ( "AUHAL component not found." ) ); *audioUnit = NULL; *audioDevice = kAudioDeviceUnknown; return paUnanticipatedHostError; } /* -- open it -- */ result = OpenAComponent( comp, audioUnit ); if( result ) { DBUG( ( "Failed to open AUHAL component." ) ); *audioUnit = NULL; *audioDevice = kAudioDeviceUnknown; return ERR( result ); } /* -- prepare a little error handling logic / hackery -- */ #define ERR_WRAP(mac_err) do { result = mac_err ; line = __LINE__ ; if ( result != noErr ) goto error ; } while(0) /* -- if there is input, we have to explicitly enable input -- */ if( inStreamParams ) { UInt32 enableIO = 1; ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, INPUT_ELEMENT, &enableIO, sizeof(enableIO) ) ); } /* -- if there is no output, we must explicitly disable output -- */ if( !outStreamParams ) { UInt32 enableIO = 0; ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, OUTPUT_ELEMENT, &enableIO, sizeof(enableIO) ) ); } /* -- set the devices -- */ /* make sure input and output are the same device if we are doing input and output. */ if( inStreamParams && outStreamParams ) { assert( outStreamParams->device == inStreamParams->device ); } if( inStreamParams ) { *audioDevice = auhalHostApi->devIds[inStreamParams->device] ; ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, INPUT_ELEMENT, audioDevice, sizeof(AudioDeviceID) ) ); } if( outStreamParams && outStreamParams != inStreamParams ) { *audioDevice = auhalHostApi->devIds[outStreamParams->device] ; ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, OUTPUT_ELEMENT, audioDevice, sizeof(AudioDeviceID) ) ); } /* -- add listener for dropouts -- */ ERR_WRAP( AudioDeviceAddPropertyListener( *audioDevice, 0, outStreamParams ? false : true, kAudioDeviceProcessorOverload, xrunCallback, (void *)stream) ); /* -- listen for stream start and stop -- */ ERR_WRAP( AudioUnitAddPropertyListener( *audioUnit, kAudioOutputUnitProperty_IsRunning, startStopCallback, (void *)stream ) ); /* -- set format -- */ bzero( &desiredFormat, sizeof(desiredFormat) ); desiredFormat.mFormatID = kAudioFormatLinearPCM ; desiredFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked; desiredFormat.mFramesPerPacket = 1; desiredFormat.mBitsPerChannel = sizeof( float ) * 8; result = 0; /* set device format first, but only touch the device if the user asked */ if( inStreamParams ) { /*The callback never calls back if we don't set the FPB */ /*This seems wierd, because I would think setting anything on the device would be disruptive.*/ paResult = setBestFramesPerBuffer( *audioDevice, FALSE, requestedFramesPerBuffer, actualInputFramesPerBuffer ); if( paResult ) goto error; if( macInputStreamFlags & paMacCoreChangeDeviceParameters ) { bool requireExact; requireExact=macInputStreamFlags & paMacCoreFailIfConversionRequired; paResult = setBestSampleRateForDevice( *audioDevice, FALSE, requireExact, sampleRate ); if( paResult ) goto error; } if( actualInputFramesPerBuffer && actualOutputFramesPerBuffer ) *actualOutputFramesPerBuffer = *actualInputFramesPerBuffer ; } if( outStreamParams && !inStreamParams ) { /*The callback never calls back if we don't set the FPB */ /*This seems wierd, because I would think setting anything on the device would be disruptive.*/ paResult = setBestFramesPerBuffer( *audioDevice, TRUE, requestedFramesPerBuffer, actualOutputFramesPerBuffer ); if( paResult ) goto error; if( macOutputStreamFlags & paMacCoreChangeDeviceParameters ) { bool requireExact; requireExact=macOutputStreamFlags & paMacCoreFailIfConversionRequired; paResult = setBestSampleRateForDevice( *audioDevice, TRUE, requireExact, sampleRate ); if( paResult ) goto error; } } /* -- set the quality of the output converter -- */ if( outStreamParams ) { UInt32 value = kAudioConverterQuality_Max; switch( macOutputStreamFlags & 0x0700 ) { case 0x0100: /*paMacCore_ConversionQualityMin:*/ value=kRenderQuality_Min; break; case 0x0200: /*paMacCore_ConversionQualityLow:*/ value=kRenderQuality_Low; break; case 0x0300: /*paMacCore_ConversionQualityMedium:*/ value=kRenderQuality_Medium; break; case 0x0400: /*paMacCore_ConversionQualityHigh:*/ value=kRenderQuality_High; break; } ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioUnitProperty_RenderQuality, kAudioUnitScope_Global, OUTPUT_ELEMENT, &value, sizeof(value) ) ); } /* now set the format on the Audio Units. */ if( outStreamParams ) { desiredFormat.mSampleRate =sampleRate; desiredFormat.mBytesPerPacket=sizeof(float)*outStreamParams->channelCount; desiredFormat.mBytesPerFrame =sizeof(float)*outStreamParams->channelCount; desiredFormat.mChannelsPerFrame = outStreamParams->channelCount; ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, OUTPUT_ELEMENT, &desiredFormat, sizeof(AudioStreamBasicDescription) ) ); } if( inStreamParams ) { AudioStreamBasicDescription sourceFormat; UInt32 size = sizeof( AudioStreamBasicDescription ); /* keep the sample rate of the device, or we confuse AUHAL */ ERR_WRAP( AudioUnitGetProperty( *audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, INPUT_ELEMENT, &sourceFormat, &size ) ); desiredFormat.mSampleRate = sourceFormat.mSampleRate; desiredFormat.mBytesPerPacket=sizeof(float)*inStreamParams->channelCount; desiredFormat.mBytesPerFrame =sizeof(float)*inStreamParams->channelCount; desiredFormat.mChannelsPerFrame = inStreamParams->channelCount; ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, INPUT_ELEMENT, &desiredFormat, sizeof(AudioStreamBasicDescription) ) ); } /* set the maximumFramesPerSlice */ /* not doing this causes real problems (eg. the callback might not be called). The idea of setting both this and the frames per buffer on the device is that we'll be most likely to actually get the frame size we requested in the callback with the minimum latency. */ if( outStreamParams ) { UInt32 size = sizeof( *actualOutputFramesPerBuffer ); ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Input, OUTPUT_ELEMENT, actualOutputFramesPerBuffer, sizeof(*actualOutputFramesPerBuffer) ) ); ERR_WRAP( AudioUnitGetProperty( *audioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, OUTPUT_ELEMENT, actualOutputFramesPerBuffer, &size ) ); } if( inStreamParams ) { /*UInt32 size = sizeof( *actualInputFramesPerBuffer );*/ ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Output, INPUT_ELEMENT, actualInputFramesPerBuffer, sizeof(*actualInputFramesPerBuffer) ) ); /* Don't know why this causes problems ERR_WRAP( AudioUnitGetProperty( *audioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, //Output, INPUT_ELEMENT, actualInputFramesPerBuffer, &size ) ); */ } /* -- if we have input, we may need to setup an SR converter -- */ /* even if we got the sample rate we asked for, we need to do the conversion in case another program changes the underlying SR. */ /* FIXME: I think we need to monitor stream and change the converter if the incoming format changes. */ if( inStreamParams ) { AudioStreamBasicDescription desiredFormat; AudioStreamBasicDescription sourceFormat; UInt32 sourceSize = sizeof( sourceFormat ); bzero( &desiredFormat, sizeof(desiredFormat) ); desiredFormat.mSampleRate = sampleRate; desiredFormat.mFormatID = kAudioFormatLinearPCM ; desiredFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked; desiredFormat.mFramesPerPacket = 1; desiredFormat.mBitsPerChannel = sizeof( float ) * 8; desiredFormat.mBytesPerPacket=sizeof(float)*inStreamParams->channelCount; desiredFormat.mBytesPerFrame =sizeof(float)*inStreamParams->channelCount; desiredFormat.mChannelsPerFrame = inStreamParams->channelCount; /* get the source format */ ERR_WRAP( AudioUnitGetProperty( *audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, INPUT_ELEMENT, &sourceFormat, &sourceSize ) ); if( desiredFormat.mSampleRate != sourceFormat.mSampleRate ) { UInt32 value = kAudioConverterQuality_Max; switch( macInputStreamFlags & 0x0700 ) { case 0x0100: /*paMacCore_ConversionQualityMin:*/ value=kAudioConverterQuality_Min; break; case 0x0200: /*paMacCore_ConversionQualityLow:*/ value=kAudioConverterQuality_Low; break; case 0x0300: /*paMacCore_ConversionQualityMedium:*/ value=kAudioConverterQuality_Medium; break; case 0x0400: /*paMacCore_ConversionQualityHigh:*/ value=kAudioConverterQuality_High; break; } VDBUG(( "Creating sample rate converter for input" " to convert from %g to %g\n", (float)sourceFormat.mSampleRate, (float)desiredFormat.mSampleRate ) ); /* create our converter */ ERR_WRAP( AudioConverterNew( &sourceFormat, &desiredFormat, srConverter ) ); /* Set quality */ ERR_WRAP( AudioConverterSetProperty( *srConverter, kAudioConverterSampleRateConverterQuality, sizeof( value ), &value ) ); } } /* -- set IOProc (callback) -- */ callbackKey = outStreamParams ? kAudioUnitProperty_SetRenderCallback : kAudioOutputUnitProperty_SetInputCallback ; rcbs.inputProc = AudioIOProc; rcbs.inputProcRefCon = refCon; ERR_WRAP( AudioUnitSetProperty( *audioUnit, callbackKey, kAudioUnitScope_Output, outStreamParams ? OUTPUT_ELEMENT : INPUT_ELEMENT, &rcbs, sizeof(rcbs)) ); if( inStreamParams && outStreamParams && *srConverter ) ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Output, INPUT_ELEMENT, &rcbs, sizeof(rcbs)) ); /* channel mapping. */ if(inChannelMap) { UInt32 mapSize = inChannelMapSize *sizeof(SInt32); //for each channel of desired input, map the channel from //the device's output channel. ERR_WRAP( AudioUnitSetProperty(*audioUnit, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, INPUT_ELEMENT, inChannelMap, mapSize)); } if(outChannelMap) { UInt32 mapSize = outChannelMapSize *sizeof(SInt32); //for each channel of desired output, map the channel from //the device's output channel. ERR_WRAP(AudioUnitSetProperty(*audioUnit, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, OUTPUT_ELEMENT, outChannelMap, mapSize)); } /* initialize the audio unit */ ERR_WRAP( AudioUnitInitialize(*audioUnit) ); if( inStreamParams && outStreamParams ) VDBUG( ("Opened device %ld for input and output.\n", *audioDevice ) ); else if( inStreamParams ) VDBUG( ("Opened device %ld for input.\n", *audioDevice ) ); else if( outStreamParams ) VDBUG( ("Opened device %ld for output.\n", *audioDevice ) ); return paNoError; #undef ERR_WRAP error: CloseComponent( *audioUnit ); *audioUnit = NULL; if( result ) return PaMacCore_SetError( result, line, 1 ); return paResult; } /* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ) { PaError result = paNoError; PaMacAUHAL *auhalHostApi = (PaMacAUHAL*)hostApi; PaMacCoreStream *stream = 0; int inputChannelCount, outputChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat; VVDBUG(("OpenStream(): in chan=%d, in fmt=%ld, out chan=%d, out fmt=%ld SR=%g, FPB=%ld\n", inputParameters ? inputParameters->channelCount : -1, inputParameters ? inputParameters->sampleFormat : -1, outputParameters ? outputParameters->channelCount : -1, outputParameters ? outputParameters->sampleFormat : -1, (float) sampleRate, framesPerBuffer )); VDBUG( ("Opening Stream.\n") ); /*These first few bits of code are from paSkeleton with few modifications.*/ if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that input device can support inputChannelCount */ if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) return paInvalidChannelCount; /* Host supports interleaved float32 */ hostInputSampleFormat = paFloat32; } else { inputChannelCount = 0; inputSampleFormat = hostInputSampleFormat = paFloat32; /* Surpress 'uninitialised var' warnings. */ } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that output device can support inputChannelCount */ if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) return paInvalidChannelCount; /* Host supports interleaved float32 */ hostOutputSampleFormat = paFloat32; } else { outputChannelCount = 0; outputSampleFormat = hostOutputSampleFormat = paFloat32; /* Surpress 'uninitialized var' warnings. */ } /* validate platform specific flags */ if( (streamFlags & paPlatformSpecificFlags) != 0 ) return paInvalidFlag; /* unexpected platform specific flag */ stream = (PaMacCoreStream*)PaUtil_AllocateMemory( sizeof(PaMacCoreStream) ); if( !stream ) { result = paInsufficientMemory; goto error; } /* If we fail after this point, we my be left in a bad state, with some data structures setup and others not. So, first thing we do is initialize everything so that if we fail, we know what hasn't been touched. */ stream->inputAudioBufferList.mBuffers[0].mData = NULL; stream->inputRingBuffer.buffer = NULL; bzero( &stream->blio, sizeof( PaMacBlio ) ); /* stream->blio.inputRingBuffer.buffer = NULL; stream->blio.outputRingBuffer.buffer = NULL; stream->blio.inputSampleFormat = inputParameters?inputParameters->sampleFormat:0; stream->blio.inputSampleSize = computeSampleSizeFromFormat(stream->blio.inputSampleFormat); stream->blio.outputSampleFormat=outputParameters?outputParameters->sampleFormat:0; stream->blio.outputSampleSize = computeSampleSizeFromFormat(stream->blio.outputSampleFormat); */ stream->inputSRConverter = NULL; stream->inputUnit = NULL; stream->outputUnit = NULL; stream->inputFramesPerBuffer = 0; stream->outputFramesPerBuffer = 0; stream->bufferProcessorIsInitialized = FALSE; /* assert( streamCallback ) ; */ /* only callback mode is implemented */ if( streamCallback ) { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &auhalHostApi->callbackStreamInterface, streamCallback, userData ); } else { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &auhalHostApi->blockingStreamInterface, BlioCallback, &stream->blio ); } PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate ); /* -- handle paFramesPerBufferUnspecified -- */ if( framesPerBuffer == paFramesPerBufferUnspecified ) { long requested = 64; if( inputParameters ) requested = MAX( requested, inputParameters->suggestedLatency * sampleRate / 2 ); if( outputParameters ) requested = MAX( requested, outputParameters->suggestedLatency *sampleRate / 2 ); VDBUG( ("Block Size unspecified. Based on Latency, the user wants a Block Size near: %ld.\n", requested ) ); if( requested <= 64 ) { /*requested a realtively low latency. make sure this is in range of devices */ /*try to get the device's min natural buffer size and use that (but no smaller than 64).*/ AudioValueRange audioRange; UInt32 size = sizeof( audioRange ); if( inputParameters ) { WARNING( result = AudioDeviceGetProperty( auhalHostApi->devIds[inputParameters->device], 0, false, kAudioDevicePropertyBufferFrameSizeRange, &size, &audioRange ) ); if( result ) requested = MAX( requested, audioRange.mMinimum ); } size = sizeof( audioRange ); if( outputParameters ) { WARNING( result = AudioDeviceGetProperty( auhalHostApi->devIds[outputParameters->device], 0, false, kAudioDevicePropertyBufferFrameSizeRange, &size, &audioRange ) ); if( result ) requested = MAX( requested, audioRange.mMinimum ); } } else { /* requested a realtively high latency. make sure this is in range of devices */ /*try to get the device's max natural buffer size and use that (but no larger than 1024).*/ AudioValueRange audioRange; UInt32 size = sizeof( audioRange ); requested = MIN( requested, 1024 ); if( inputParameters ) { WARNING( result = AudioDeviceGetProperty( auhalHostApi->devIds[inputParameters->device], 0, false, kAudioDevicePropertyBufferFrameSizeRange, &size, &audioRange ) ); if( result ) requested = MIN( requested, audioRange.mMaximum ); } size = sizeof( audioRange ); if( outputParameters ) { WARNING( result = AudioDeviceGetProperty( auhalHostApi->devIds[outputParameters->device], 0, false, kAudioDevicePropertyBufferFrameSizeRange, &size, &audioRange ) ); if( result ) requested = MIN( requested, audioRange.mMaximum ); } } /* -- double check ranges -- */ if( requested > 1024 ) requested = 1024; if( requested < 64 ) requested = 64; VDBUG(("After querying hardware, setting block size to %ld.\n", requested)); framesPerBuffer = requested; } /* -- Now we actually open and setup streams. -- */ if( inputParameters && outputParameters && outputParameters->device == inputParameters->device ) { /* full duplex. One device. */ UInt32 inputFramesPerBuffer = (UInt32) stream->inputFramesPerBuffer; UInt32 outputFramesPerBuffer = (UInt32) stream->outputFramesPerBuffer; result = OpenAndSetupOneAudioUnit( stream, inputParameters, outputParameters, framesPerBuffer, &inputFramesPerBuffer, &outputFramesPerBuffer, auhalHostApi, &(stream->inputUnit), &(stream->inputSRConverter), &(stream->inputDevice), sampleRate, stream ); stream->inputFramesPerBuffer = inputFramesPerBuffer; stream->outputFramesPerBuffer = outputFramesPerBuffer; stream->outputUnit = stream->inputUnit; stream->outputDevice = stream->inputDevice; if( result != paNoError ) goto error; } else { /* full duplex, different devices OR simplex */ UInt32 outputFramesPerBuffer = (UInt32) stream->outputFramesPerBuffer; UInt32 inputFramesPerBuffer = (UInt32) stream->inputFramesPerBuffer; result = OpenAndSetupOneAudioUnit( stream, NULL, outputParameters, framesPerBuffer, NULL, &outputFramesPerBuffer, auhalHostApi, &(stream->outputUnit), NULL, &(stream->outputDevice), sampleRate, stream ); if( result != paNoError ) goto error; result = OpenAndSetupOneAudioUnit( stream, inputParameters, NULL, framesPerBuffer, &inputFramesPerBuffer, NULL, auhalHostApi, &(stream->inputUnit), &(stream->inputSRConverter), &(stream->inputDevice), sampleRate, stream ); if( result != paNoError ) goto error; stream->inputFramesPerBuffer = inputFramesPerBuffer; stream->outputFramesPerBuffer = outputFramesPerBuffer; } if( stream->inputUnit ) { const size_t szfl = sizeof(float); /* setup the AudioBufferList used for input */ bzero( &stream->inputAudioBufferList, sizeof( AudioBufferList ) ); stream->inputAudioBufferList.mNumberBuffers = 1; stream->inputAudioBufferList.mBuffers[0].mNumberChannels = inputChannelCount; stream->inputAudioBufferList.mBuffers[0].mDataByteSize = stream->inputFramesPerBuffer*inputChannelCount*szfl; stream->inputAudioBufferList.mBuffers[0].mData = (float *) calloc( stream->inputFramesPerBuffer*inputChannelCount, szfl ); if( !stream->inputAudioBufferList.mBuffers[0].mData ) { result = paInsufficientMemory; goto error; } /* * If input and output devs are different or we are doing SR conversion, * we also need a * ring buffer to store inpt data while waiting for output * data. */ if( (stream->outputUnit && stream->inputUnit != stream->outputUnit) || stream->inputSRConverter ) { /* May want the ringSize ot initial position in ring buffer to depend somewhat on sample rate change */ void *data; long ringSize; ringSize = computeRingBufferSize( inputParameters, outputParameters, stream->inputFramesPerBuffer, stream->outputFramesPerBuffer, sampleRate ); /*ringSize <<= 4; *//*16x bigger, for testing */ /*now, we need to allocate memory for the ring buffer*/ data = calloc( ringSize, szfl ); if( !data ) { result = paInsufficientMemory; goto error; } /* now we can initialize the ring buffer */ PaUtil_InitializeRingBuffer( &stream->inputRingBuffer, ringSize*szfl, data ) ; /* advance the read point a little, so we are reading from the middle of the buffer */ if( stream->outputUnit ) PaUtil_AdvanceRingBufferWriteIndex( &stream->inputRingBuffer, ringSize*szfl / RING_BUFFER_ADVANCE_DENOMINATOR ); } } /* -- initialize Blio Buffer Processors -- */ if( !streamCallback ) { long ringSize; ringSize = computeRingBufferSize( inputParameters, outputParameters, stream->inputFramesPerBuffer, stream->outputFramesPerBuffer, sampleRate ); result = initializeBlioRingBuffers( &stream->blio, inputParameters?inputParameters->sampleFormat:0 , outputParameters?outputParameters->sampleFormat:0 , MAX(stream->inputFramesPerBuffer,stream->outputFramesPerBuffer), ringSize, inputParameters?inputChannelCount:0 , outputParameters?outputChannelCount:0 ) ; if( result != paNoError ) goto error; } /* -- initialize Buffer Processor -- */ { unsigned long maxHostFrames = stream->inputFramesPerBuffer; if( stream->outputFramesPerBuffer > maxHostFrames ) maxHostFrames = stream->outputFramesPerBuffer; result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, inputChannelCount, inputSampleFormat, hostInputSampleFormat, outputChannelCount, outputSampleFormat, hostOutputSampleFormat, sampleRate, streamFlags, framesPerBuffer, /* If sample rate conversion takes place, the buffer size will not be known. */ maxHostFrames, stream->inputSRConverter ? paUtilUnknownHostBufferSize : paUtilBoundedHostBufferSize, streamCallback ? streamCallback : BlioCallback, streamCallback ? userData : &stream->blio ); if( result != paNoError ) goto error; } stream->bufferProcessorIsInitialized = TRUE; /* IMPLEMENT ME: initialise the following fields with estimated or actual values. I think this is okay the way it is br 12/1/05 maybe need to change input latency estimate if IO devs differ */ stream->streamRepresentation.streamInfo.inputLatency = PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor)/sampleRate; stream->streamRepresentation.streamInfo.outputLatency = PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor)/sampleRate; stream->streamRepresentation.streamInfo.sampleRate = sampleRate; stream->sampleRate = sampleRate; stream->outDeviceSampleRate = 0; if( stream->outputUnit ) { Float64 rate; UInt32 size = sizeof( rate ); result = ERR( AudioDeviceGetProperty( stream->outputDevice, 0, FALSE, kAudioDevicePropertyNominalSampleRate, &size, &rate ) ); if( result ) goto error; stream->outDeviceSampleRate = rate; } stream->inDeviceSampleRate = 0; if( stream->inputUnit ) { Float64 rate; UInt32 size = sizeof( rate ); result = ERR( AudioDeviceGetProperty( stream->inputDevice, 0, TRUE, kAudioDevicePropertyNominalSampleRate, &size, &rate ) ); if( result ) goto error; stream->inDeviceSampleRate = rate; } stream->userInChan = inputChannelCount; stream->userOutChan = outputChannelCount; stream->isTimeSet = FALSE; stream->state = STOPPED; stream->xrunFlags = 0; *s = (PaStream*)stream; return result; error: CloseStream( stream ); return result; } PaTime GetStreamTime( PaStream *s ) { /* FIXME: I am not at all sure this timing info stuff is right. patest_sine_time reports negative latencies, which is wierd.*/ PaMacCoreStream *stream = (PaMacCoreStream*)s; AudioTimeStamp timeStamp; VVDBUG(("GetStreamTime()\n")); if ( !stream->isTimeSet ) return (PaTime)0; if ( stream->outputDevice ) { AudioDeviceGetCurrentTime( stream->outputDevice, &timeStamp); return (PaTime)(timeStamp.mSampleTime - stream->startTime.mSampleTime)/stream->outDeviceSampleRate; } else if ( stream->inputDevice ) { AudioDeviceGetCurrentTime( stream->inputDevice, &timeStamp); return (PaTime)(timeStamp.mSampleTime - stream->startTime.mSampleTime)/stream->inDeviceSampleRate; } else { return (PaTime)0; } } static void setStreamStartTime( PaStream *stream ) { /* FIXME: I am not at all sure this timing info stuff is right. patest_sine_time reports negative latencies, which is wierd.*/ PaMacCoreStream *s = (PaMacCoreStream *) stream; VVDBUG(("setStreamStartTime()\n")); if( s->outputDevice ) AudioDeviceGetCurrentTime( s->outputDevice, &s->startTime); else if( s->inputDevice ) AudioDeviceGetCurrentTime( s->inputDevice, &s->startTime); else bzero( &s->startTime, sizeof( s->startTime ) ); //FIXME: we need a memory barier here s->isTimeSet = TRUE; } static PaTime TimeStampToSecs(PaMacCoreStream *stream, const AudioTimeStamp* timeStamp) { VVDBUG(("TimeStampToSecs()\n")); //printf( "ATS: %lu, %g, %g\n", timeStamp->mFlags, timeStamp->mSampleTime, timeStamp->mRateScalar ); if (timeStamp->mFlags & kAudioTimeStampSampleTimeValid) return (timeStamp->mSampleTime / stream->sampleRate); else return 0; } #define RING_BUFFER_EMPTY (1000) static OSStatus ringBufferIOProc( AudioConverterRef inAudioConverter, UInt32*ioDataSize, void** outData, void*inUserData ) { void *dummyData; long dummySize; PaUtilRingBuffer *rb = (PaUtilRingBuffer *) inUserData; VVDBUG(("ringBufferIOProc()\n")); assert( sizeof( UInt32 ) == sizeof( long ) ); if( PaUtil_GetRingBufferReadAvailable( rb ) == 0 ) { *outData = NULL; *ioDataSize = 0; return RING_BUFFER_EMPTY; } PaUtil_GetRingBufferReadRegions( rb, *ioDataSize, outData, (long *)ioDataSize, &dummyData, &dummySize ); assert( *ioDataSize ); PaUtil_AdvanceRingBufferReadIndex( rb, *ioDataSize ); return noErr; } /* * Called by the AudioUnit API to process audio from the sound card. * This is where the magic happens. */ /* FEEDBACK: there is a lot of redundant code here because of how all the cases differ. This makes it hard to maintain, so if there are suggestinos for cleaning it up, I'm all ears. */ static OSStatus AudioIOProc( void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData ) { unsigned long framesProcessed = 0; PaStreamCallbackTimeInfo timeInfo = {0,0,0}; PaMacCoreStream *stream = (PaMacCoreStream*)inRefCon; const bool isRender = inBusNumber == OUTPUT_ELEMENT; int callbackResult = paContinue ; VVDBUG(("AudioIOProc()\n")); PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); /* -----------------------------------------------------------------*\ This output may be useful for debugging, But printing durring the callback is a bad enough idea that this is not enabled by enableing the usual debugging calls. \* -----------------------------------------------------------------*/ /* static int renderCount = 0; static int inputCount = 0; printf( "------------------- starting reder/input\n" ); if( isRender ) printf("Render callback (%d):\t", ++renderCount); else printf("Input callback (%d):\t", ++inputCount); printf( "Call totals: %d (input), %d (render)\n", inputCount, renderCount ); printf( "--- inBusNumber: %lu\n", inBusNumber ); printf( "--- inNumberFrames: %lu\n", inNumberFrames ); printf( "--- %x ioData\n", (unsigned) ioData ); if( ioData ) { int i=0; printf( "--- ioData.mNumBuffers %lu: \n", ioData->mNumberBuffers ); for( i=0; imNumberBuffers; ++i ) printf( "--- ioData buffer %d size: %lu.\n", i, ioData->mBuffers[i].mDataByteSize ); } ----------------------------------------------------------------- */ if( !stream->isTimeSet ) setStreamStartTime( stream ); if( isRender ) { AudioTimeStamp currentTime; timeInfo.outputBufferDacTime = TimeStampToSecs(stream, inTimeStamp); AudioDeviceGetCurrentTime(stream->outputDevice, ¤tTime); timeInfo.currentTime = TimeStampToSecs(stream, ¤tTime); } if( isRender && stream->inputUnit == stream->outputUnit ) timeInfo.inputBufferAdcTime = TimeStampToSecs(stream, inTimeStamp); if( !isRender ) { AudioTimeStamp currentTime; timeInfo.inputBufferAdcTime = TimeStampToSecs(stream, inTimeStamp); AudioDeviceGetCurrentTime(stream->inputDevice, ¤tTime); timeInfo.currentTime = TimeStampToSecs(stream, ¤tTime); } //printf( "---%g, %g, %g\n", timeInfo.inputBufferAdcTime, timeInfo.currentTime, timeInfo.outputBufferDacTime ); if( isRender && stream->inputUnit == stream->outputUnit && !stream->inputSRConverter ) { /* --------- Full Duplex, One Device, no SR Conversion ------- * * This is the lowest latency case, and also the simplest. * Input data and output data are available at the same time. * we do not use the input SR converter or the input ring buffer. * */ OSStatus err = 0; unsigned long frames; /* -- start processing -- */ PaUtil_BeginBufferProcessing( &(stream->bufferProcessor), &timeInfo, stream->xrunFlags ); stream->xrunFlags = 0; //FIXME: this flag also gets set outside by a callback, which calls the xrunCallback function. It should be in the same thread as the main audio callback, but the apple docs just use the word "usually" so it may be possible to loose an xrun notification, if that callback happens here. /* -- compute frames. do some checks -- */ assert( ioData->mNumberBuffers == 1 ); assert( ioData->mBuffers[0].mNumberChannels == stream->userOutChan ); frames = ioData->mBuffers[0].mDataByteSize; frames /= sizeof( float ) * ioData->mBuffers[0].mNumberChannels; /* -- copy and process input data -- */ err= AudioUnitRender(stream->inputUnit, ioActionFlags, inTimeStamp, INPUT_ELEMENT, inNumberFrames, &stream->inputAudioBufferList ); /* FEEDBACK: I'm not sure what to do when this call fails */ assert( !err ); PaUtil_SetInputFrameCount( &(stream->bufferProcessor), frames ); PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor), 0, stream->inputAudioBufferList.mBuffers[0].mData, stream->inputAudioBufferList.mBuffers[0].mNumberChannels); /* -- Copy and process output data -- */ PaUtil_SetOutputFrameCount( &(stream->bufferProcessor), frames ); PaUtil_SetInterleavedOutputChannels( &(stream->bufferProcessor), 0, ioData->mBuffers[0].mData, ioData->mBuffers[0].mNumberChannels); /* -- complete processing -- */ framesProcessed = PaUtil_EndBufferProcessing( &(stream->bufferProcessor), &callbackResult ); } else if( isRender ) { /* -------- Output Side of Full Duplex (Separate Devices or SR Conversion) * -- OR Simplex Output * * This case handles output data as in the full duplex case, * and, if there is input data, reads it off the ring buffer * and into the PA buffer processor. If sample rate conversion * is required on input, that is done here as well. */ unsigned long frames; /* Sometimes, when stopping a duplex stream we get erroneous xrun flags, so if this is our last run, clear the flags. */ int xrunFlags = stream->xrunFlags; /* if( xrunFlags & paInputUnderflow ) printf( "input underflow.\n" ); if( xrunFlags & paInputOverflow ) printf( "input overflow.\n" ); */ if( stream->state == STOPPING || stream->state == CALLBACK_STOPPED ) xrunFlags = 0; /* -- start processing -- */ PaUtil_BeginBufferProcessing( &(stream->bufferProcessor), &timeInfo, xrunFlags ); stream->xrunFlags = 0; /* FEEDBACK: we only send flags to Buf Proc once */ /* -- Copy and process output data -- */ assert( ioData->mNumberBuffers == 1 ); frames = ioData->mBuffers[0].mDataByteSize; frames /= sizeof( float ) * ioData->mBuffers[0].mNumberChannels; assert( ioData->mBuffers[0].mNumberChannels == stream->userOutChan ); PaUtil_SetOutputFrameCount( &(stream->bufferProcessor), frames ); PaUtil_SetInterleavedOutputChannels( &(stream->bufferProcessor), 0, ioData->mBuffers[0].mData, ioData->mBuffers[0].mNumberChannels); /* -- copy and process input data, and complete processing -- */ if( stream->inputUnit ) { const int flsz = sizeof( float ); /* Here, we read the data out of the ring buffer, through the audio converter. */ int inChan = stream->inputAudioBufferList.mBuffers[0].mNumberChannels; if( stream->inputSRConverter ) { OSStatus err; UInt32 size; float data[ inChan * frames ]; size = sizeof( data ); err = AudioConverterFillBuffer( stream->inputSRConverter, ringBufferIOProc, &stream->inputRingBuffer, &size, (void *)&data ); if( err == RING_BUFFER_EMPTY ) { /*the ring buffer callback underflowed */ err = 0; bzero( ((char *)data) + size, sizeof(data)-size ); stream->xrunFlags |= paInputUnderflow; } ERR( err ); assert( !err ); PaUtil_SetInputFrameCount( &(stream->bufferProcessor), frames ); PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor), 0, data, inChan ); framesProcessed = PaUtil_EndBufferProcessing( &(stream->bufferProcessor), &callbackResult ); } else { /* Without the AudioConverter is actually a bit more complex because we have to do a little buffer processing that the AudioConverter would otherwise handle for us. */ void *data1, *data2; long size1, size2; PaUtil_GetRingBufferReadRegions( &stream->inputRingBuffer, inChan*frames*flsz, &data1, &size1, &data2, &size2 ); if( size1 / ( flsz * inChan ) == frames ) { /* simplest case: all in first buffer */ PaUtil_SetInputFrameCount( &(stream->bufferProcessor), frames ); PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor), 0, data1, inChan ); framesProcessed = PaUtil_EndBufferProcessing( &(stream->bufferProcessor), &callbackResult ); PaUtil_AdvanceRingBufferReadIndex(&stream->inputRingBuffer, size1 ); } else if( ( size1 + size2 ) / ( flsz * inChan ) < frames ) { /*we underflowed. take what data we can, zero the rest.*/ unsigned char data[frames*inChan*flsz]; if( size1 ) memcpy( data, data1, size1 ); if( size2 ) memcpy( data+size1, data2, size2 ); bzero( data+size1+size2, frames*flsz*inChan - size1 - size2 ); PaUtil_SetInputFrameCount( &(stream->bufferProcessor), frames ); PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor), 0, data, inChan ); framesProcessed = PaUtil_EndBufferProcessing( &(stream->bufferProcessor), &callbackResult ); PaUtil_AdvanceRingBufferReadIndex( &stream->inputRingBuffer, size1+size2 ); /* flag underflow */ stream->xrunFlags |= paInputUnderflow; } else { /*we got all the data, but split between buffers*/ PaUtil_SetInputFrameCount( &(stream->bufferProcessor), size1 / ( flsz * inChan ) ); PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor), 0, data1, inChan ); PaUtil_Set2ndInputFrameCount( &(stream->bufferProcessor), size2 / ( flsz * inChan ) ); PaUtil_Set2ndInterleavedInputChannels( &(stream->bufferProcessor), 0, data2, inChan ); framesProcessed = PaUtil_EndBufferProcessing( &(stream->bufferProcessor), &callbackResult ); PaUtil_AdvanceRingBufferReadIndex(&stream->inputRingBuffer, size1+size2 ); } } } else { framesProcessed = PaUtil_EndBufferProcessing( &(stream->bufferProcessor), &callbackResult ); } } else { /* ------------------ Input * * First, we read off the audio data and put it in the ring buffer. * if this is an input-only stream, we need to process it more, * otherwise, we let the output case deal with it. */ OSStatus err = 0; int chan = stream->inputAudioBufferList.mBuffers[0].mNumberChannels ; /* FIXME: looping here may not actually be necessary, but it was something I tried in testing. */ do { err= AudioUnitRender(stream->inputUnit, ioActionFlags, inTimeStamp, INPUT_ELEMENT, inNumberFrames, &stream->inputAudioBufferList ); if( err == -10874 ) inNumberFrames /= 2; } while( err == -10874 && inNumberFrames > 1 ); /* FEEDBACK: I'm not sure what to do when this call fails */ ERR( err ); assert( !err ); if( stream->inputSRConverter || stream->outputUnit ) { /* If this is duplex or we use a converter, put the data into the ring buffer. */ long bytesIn, bytesOut; bytesIn = sizeof( float ) * inNumberFrames * chan; bytesOut = PaUtil_WriteRingBuffer( &stream->inputRingBuffer, stream->inputAudioBufferList.mBuffers[0].mData, bytesIn ); if( bytesIn != bytesOut ) stream->xrunFlags |= paInputOverflow ; } else { /* for simplex input w/o SR conversion, just pop the data into the buffer processor.*/ PaUtil_BeginBufferProcessing( &(stream->bufferProcessor), &timeInfo, stream->xrunFlags ); stream->xrunFlags = 0; PaUtil_SetInputFrameCount( &(stream->bufferProcessor), inNumberFrames); PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor), 0, stream->inputAudioBufferList.mBuffers[0].mData, chan ); framesProcessed = PaUtil_EndBufferProcessing( &(stream->bufferProcessor), &callbackResult ); } if( !stream->outputUnit && stream->inputSRConverter ) { /* ------------------ Simplex Input w/ SR Conversion * * if this is a simplex input stream, we need to read off the buffer, * do our sample rate conversion and pass the results to the buffer * processor. * The logic here is complicated somewhat by the fact that we don't * know how much data is available, so we loop on reasonably sized * chunks, and let the BufferProcessor deal with the rest. * */ /*This might be too big or small depending on SR conversion*/ float data[ chan * inNumberFrames ]; OSStatus err; do { /*Run the buffer processor until we are out of data*/ UInt32 size; long f; size = sizeof( data ); err = AudioConverterFillBuffer( stream->inputSRConverter, ringBufferIOProc, &stream->inputRingBuffer, &size, (void *)data ); if( err != RING_BUFFER_EMPTY ) ERR( err ); assert( err == 0 || err == RING_BUFFER_EMPTY ); f = size / ( chan * sizeof(float) ); PaUtil_SetInputFrameCount( &(stream->bufferProcessor), f ); if( f ) { PaUtil_BeginBufferProcessing( &(stream->bufferProcessor), &timeInfo, stream->xrunFlags ); stream->xrunFlags = 0; PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor), 0, data, chan ); framesProcessed = PaUtil_EndBufferProcessing( &(stream->bufferProcessor), &callbackResult ); } } while( callbackResult == paContinue && !err ); } } switch( callbackResult ) { case paContinue: break; case paComplete: case paAbort: stream->isTimeSet = FALSE; stream->state = CALLBACK_STOPPED ; if( stream->outputUnit ) AudioOutputUnitStop(stream->outputUnit); if( stream->inputUnit ) AudioOutputUnitStop(stream->inputUnit); break; } PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed ); return noErr; } /* When CloseStream() is called, the multi-api layer ensures that the stream has already been stopped or aborted. */ static PaError CloseStream( PaStream* s ) { /* This may be called from a failed OpenStream. Therefore, each piece of info is treated seperately. */ PaError result = paNoError; PaMacCoreStream *stream = (PaMacCoreStream*)s; VVDBUG(("CloseStream()\n")); VDBUG( ( "Closing stream.\n" ) ); if( stream ) { if( stream->outputUnit ) AudioDeviceRemovePropertyListener( stream->outputDevice, 0, false, kAudioDeviceProcessorOverload, xrunCallback ); if( stream->inputUnit && stream->outputUnit != stream->inputUnit ) AudioDeviceRemovePropertyListener( stream->inputDevice, 0, true, kAudioDeviceProcessorOverload, xrunCallback ); if( stream->outputUnit && stream->outputUnit != stream->inputUnit ) { AudioUnitUninitialize( stream->outputUnit ); CloseComponent( stream->outputUnit ); } stream->outputUnit = NULL; if( stream->inputUnit ) { AudioUnitUninitialize( stream->inputUnit ); CloseComponent( stream->inputUnit ); stream->inputUnit = NULL; } if( stream->inputRingBuffer.buffer ) free( (void *) stream->inputRingBuffer.buffer ); stream->inputRingBuffer.buffer = NULL; /*TODO: is there more that needs to be done on error from AudioConverterDispose?*/ if( stream->inputSRConverter ) ERR( AudioConverterDispose( stream->inputSRConverter ) ); stream->inputSRConverter = NULL; if( stream->inputAudioBufferList.mBuffers[0].mData ) free( stream->inputAudioBufferList.mBuffers[0].mData ); stream->inputAudioBufferList.mBuffers[0].mData = NULL; result = destroyBlioRingBuffers( &stream->blio ); if( result ) return result; if( stream->bufferProcessorIsInitialized ) PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); PaUtil_FreeMemory( stream ); } return result; } static PaError StartStream( PaStream *s ) { PaMacCoreStream *stream = (PaMacCoreStream*)s; OSStatus result = noErr; VVDBUG(("StartStream()\n")); VDBUG( ( "Starting stream.\n" ) ); #define ERR_WRAP(mac_err) do { result = mac_err ; if ( result != noErr ) return ERR(result) ; } while(0) /*FIXME: maybe want to do this on close/abort for faster start? */ PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); if( stream->inputSRConverter ) ERR_WRAP( AudioConverterReset( stream->inputSRConverter ) ); /* -- start -- */ stream->state = ACTIVE; if( stream->inputUnit ) { ERR_WRAP( AudioOutputUnitStart(stream->inputUnit) ); } if( stream->outputUnit && stream->outputUnit != stream->inputUnit ) { ERR_WRAP( AudioOutputUnitStart(stream->outputUnit) ); } //setStreamStartTime( stream ); //stream->isTimeSet = TRUE; return paNoError; #undef ERR_WRAP } // it's not clear from appl's docs that this really waits // until all data is flushed. static ComponentResult BlockWhileAudioUnitIsRunning( AudioUnit audioUnit, AudioUnitElement element ) { Boolean isRunning = 1; while( isRunning ) { UInt32 s = sizeof( isRunning ); ComponentResult err = AudioUnitGetProperty( audioUnit, kAudioOutputUnitProperty_IsRunning, kAudioUnitScope_Global, element, &isRunning, &s ); if( err ) return err; Pa_Sleep( 100 ); } return noErr; } static PaError StopStream( PaStream *s ) { PaMacCoreStream *stream = (PaMacCoreStream*)s; OSStatus result = noErr; PaError paErr; VVDBUG(("StopStream()\n")); VDBUG( ("Waiting for BLIO.\n") ); waitUntilBlioWriteBufferIsFlushed( &stream->blio ); VDBUG( ( "Stopping stream.\n" ) ); stream->isTimeSet = FALSE; stream->state = STOPPING; #define ERR_WRAP(mac_err) do { result = mac_err ; if ( result != noErr ) return ERR(result) ; } while(0) /* -- stop and reset -- */ if( stream->inputUnit == stream->outputUnit && stream->inputUnit ) { ERR_WRAP( AudioOutputUnitStop(stream->inputUnit) ); ERR_WRAP( BlockWhileAudioUnitIsRunning(stream->inputUnit,0) ); ERR_WRAP( BlockWhileAudioUnitIsRunning(stream->inputUnit,1) ); ERR_WRAP( AudioUnitReset(stream->inputUnit, kAudioUnitScope_Global, 1) ); ERR_WRAP( AudioUnitReset(stream->inputUnit, kAudioUnitScope_Global, 0) ); } else { if( stream->inputUnit ) { ERR_WRAP(AudioOutputUnitStop(stream->inputUnit) ); ERR_WRAP( BlockWhileAudioUnitIsRunning(stream->inputUnit,1) ); ERR_WRAP(AudioUnitReset(stream->inputUnit,kAudioUnitScope_Global,1)); } if( stream->outputUnit ) { ERR_WRAP(AudioOutputUnitStop(stream->outputUnit)); ERR_WRAP( BlockWhileAudioUnitIsRunning(stream->outputUnit,0) ); ERR_WRAP(AudioUnitReset(stream->outputUnit,kAudioUnitScope_Global,0)); } } if( stream->inputRingBuffer.buffer ) { PaUtil_FlushRingBuffer( &stream->inputRingBuffer ); bzero( (void *)stream->inputRingBuffer.buffer, stream->inputRingBuffer.bufferSize ); /* advance the write point a little, so we are reading from the middle of the buffer. We'll need extra at the end because testing has shown that this helps. */ if( stream->outputUnit ) PaUtil_AdvanceRingBufferWriteIndex( &stream->inputRingBuffer, stream->inputRingBuffer.bufferSize / RING_BUFFER_ADVANCE_DENOMINATOR ); } stream->xrunFlags = 0; stream->state = STOPPED; paErr = resetBlioRingBuffers( &stream->blio ); if( paErr ) return paErr; /* //stream->isTimeSet = FALSE; */ VDBUG( ( "Stream Stopped.\n" ) ); return paNoError; #undef ERR_WRAP } static PaError AbortStream( PaStream *s ) { VVDBUG(("AbortStream()->StopStream()\n")); VDBUG( ( "Aborting stream.\n" ) ); /* We have nothing faster than StopStream. */ return StopStream(s); } static PaError IsStreamStopped( PaStream *s ) { PaMacCoreStream *stream = (PaMacCoreStream*)s; VVDBUG(("IsStreamStopped()\n")); return stream->state == STOPPED ? 1 : 0; } static PaError IsStreamActive( PaStream *s ) { PaMacCoreStream *stream = (PaMacCoreStream*)s; VVDBUG(("IsStreamActive()\n")); return ( stream->state == ACTIVE || stream->state == STOPPING ); } static double GetStreamCpuLoad( PaStream* s ) { PaMacCoreStream *stream = (PaMacCoreStream*)s; VVDBUG(("GetStreamCpuLoad()\n")); return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); } praat-6.0.04/external/portaudio2007/pa_mac_core.h000066400000000000000000000151471261542461700214720ustar00rootroot00000000000000#ifndef PA_MAC_CORE_H #define PA_MAC_CORE_H /* * PortAudio Portable Real-Time Audio Library * Macintosh Core Audio specific extensions * portaudio.h should be included before this file. * * Copyright (c) 2005-2006 Bjorn Roche * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ #include #include #ifdef __cplusplus extern "C" { #endif /* * A pointer to a paMacCoreStreamInfo may be passed as * the hostApiSpecificStreamInfo in the PaStreamParameters struct * when opening a stream or querying the format. Use NULL, for the * defaults. Note that for duplex streams, flags for input and output * should be the same or behaviour is undefined. */ typedef struct { unsigned long size; /**size of whole structure including this header */ PaHostApiTypeId hostApiType; /**host API for which this data is intended */ unsigned long version; /**structure version */ unsigned long flags; /* flags to modify behaviour */ SInt32 const * channelMap; /* Channel map for HAL channel mapping , if not needed, use NULL;*/ unsigned long channelMapSize; /* Channel map size for HAL channel mapping , if not needed, use 0;*/ } PaMacCoreStreamInfo; /* * Functions */ /* Use this function to initialize a paMacCoreStreamInfo struct * using the requested flags. Note that channel mapping is turned * off after a call to this function. * @param data The datastructure to initialize * @param flags The flags to initialize the datastructure with. */ void PaMacCore_SetupStreamInfo( PaMacCoreStreamInfo *data, unsigned long flags ); /* call this after pa_SetupMacCoreStreamInfo to use channel mapping as described in notes.txt. * @param data The stream info structure to assign a channel mapping to * @param channelMap The channel map array, as described in notes.txt. This array pointer will be used directly (ie the underlying data will not be copied), so the caller should not free the array until after the stream has been opened. * @param channelMapSize The size of the channel map array. */ void PaMacCore_SetupChannelMap( PaMacCoreStreamInfo *data, const SInt32 * const channelMap, unsigned long channelMapSize ); /* * Retrieve the AudioDeviceID of the input device assigned to an open stream * * @param s The stream to query. * * @return A valid AudioDeviceID, or NULL if an error occurred. */ AudioDeviceID PaMacCore_GetStreamInputDevice( PaStream* s ); /* * Retrieve the AudioDeviceID of the output device assigned to an open stream * * @param s The stream to query. * * @return A valid AudioDeviceID, or NULL if an error occurred. */ AudioDeviceID PaMacCore_GetStreamOutputDevice( PaStream* s ); /* * Returns a statically allocated string with the device's name * for the given channel. NULL will be returned on failure. * * This function's implemenation is not complete! * * @param device The PortAudio device index. * @param channel The channel number who's name is requested. * @return a statically allocated string with the name of the device. * Because this string is statically allocated, it must be * coppied if it is to be saved and used by the user after * another call to this function. * */ const char *PaMacCore_GetChannelName( int device, int channelIndex, bool input ); /* * Flags */ /* * The following flags alter the behaviour of PA on the mac platform. * they can be ORed together. These should work both for opening and * checking a device. */ /* Allows PortAudio to change things like the device's frame size, * which allows for much lower latency, but might disrupt the device * if other programs are using it, even when you are just Querying * the device. */ #define paMacCoreChangeDeviceParameters (0x01) /* In combination with the above flag, * causes the stream opening to fail, unless the exact sample rates * are supported by the device. */ #define paMacCoreFailIfConversionRequired (0x02) /* These flags set the SR conversion quality, if required. The wierd ordering * allows Maximum Quality to be the default.*/ #define paMacCoreConversionQualityMin (0x0100) #define paMacCoreConversionQualityMedium (0x0200) #define paMacCoreConversionQualityLow (0x0300) #define paMacCoreConversionQualityHigh (0x0400) #define paMacCoreConversionQualityMax (0x0000) /* * Here are some "preset" combinations of flags (above) to get to some * common configurations. THIS IS OVERKILL, but if more flags are added * it won't be. */ /*This is the default setting: do as much sample rate conversion as possible * and as little mucking with the device as possible. */ #define paMacCorePlayNice (0x00) /*This setting is tuned for pro audio apps. It allows SR conversion on input and output, but it tries to set the appropriate SR on the device.*/ #define paMacCorePro (0x01) /*This is a setting to minimize CPU usage and still play nice.*/ #define paMacCoreMinimizeCPUButPlayNice (0x0100) /*This is a setting to minimize CPU usage, even if that means interrupting the device. */ #define paMacCoreMinimizeCPU (0x0101) #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_MAC_CORE_H */ praat-6.0.04/external/portaudio2007/pa_mac_core_blocking.c000066400000000000000000000465241261542461700233400ustar00rootroot00000000000000/* * Implementation of the PortAudio API for Apple AUHAL * * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * * Written by Bjorn Roche of XO Audio LLC, from PA skeleton code. * Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation) * * Dominic's code was based on code by Phil Burk, Darren Gibbs, * Gord Peters, Stephane Letz, and Greg Pfiel. * * The following people also deserve acknowledgements: * * Olivier Tristan for feedback and testing * Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O * interface. * * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostaip_src This file contains the implementation required for blocking I/O. It is separated from pa_mac_core.c simply to ease development. */ #include "pa_mac_core_blocking.h" #include "pa_mac_core_internal.h" #include #ifdef MOSX_USE_NON_ATOMIC_FLAG_BITS # define OSAtomicOr32( a, b ) ( (*(b)) |= (a) ) # define OSAtomicAnd32( a, b ) ( (*(b)) &= (a) ) #else # include #endif /* * This fnuction determines the size of a particular sample format. * if the format is not recognized, this returns zero. */ static size_t computeSampleSizeFromFormat( PaSampleFormat format ) { switch( format ) { case paFloat32: return 4; case paInt32: return 4; case paInt24: return 3; case paInt16: return 2; case paInt8: case paUInt8: return 1; default: return 0; } } /* * Same as computeSampleSizeFromFormat, except that if * the size is not a power of two, it returns the next power of two up */ static size_t computeSampleSizeFromFormatPow2( PaSampleFormat format ) { switch( format ) { case paFloat32: return 4; case paInt32: return 4; case paInt24: return 4; case paInt16: return 2; case paInt8: case paUInt8: return 1; default: return 0; } } /* * Functions for initializing, resetting, and destroying BLIO structures. * */ /* This should be called with the relevant info when initializing a stream for callback. */ PaError initializeBlioRingBuffers( PaMacBlio *blio, PaSampleFormat inputSampleFormat, PaSampleFormat outputSampleFormat, size_t framesPerBuffer, long ringBufferSize, int inChan, int outChan ) { void *data; int result; /* zeroify things */ bzero( blio, sizeof( PaMacBlio ) ); /* this is redundant, but the buffers are used to check if the bufffers have been initialized, so we do it explicitly. */ blio->inputRingBuffer.buffer = NULL; blio->outputRingBuffer.buffer = NULL; /* initialize simple data */ blio->ringBufferFrames = ringBufferSize; blio->inputSampleFormat = inputSampleFormat; blio->inputSampleSizeActual = computeSampleSizeFromFormat(inputSampleFormat); blio->inputSampleSizePow2 = computeSampleSizeFromFormatPow2(inputSampleFormat); blio->outputSampleFormat = outputSampleFormat; blio->outputSampleSizeActual = computeSampleSizeFromFormat(outputSampleFormat); blio->outputSampleSizePow2 = computeSampleSizeFromFormatPow2(outputSampleFormat); blio->framesPerBuffer = framesPerBuffer; blio->inChan = inChan; blio->outChan = outChan; blio->statusFlags = 0; blio->errors = paNoError; #ifdef PA_MAC_BLIO_MUTEX blio->isInputEmpty = false; blio->isOutputFull = false; #endif /* setup ring buffers */ #ifdef PA_MAC_BLIO_MUTEX result = PaMacCore_SetUnixError( pthread_mutex_init(&(blio->inputMutex),NULL), 0 ); if( result ) goto error; result = UNIX_ERR( pthread_cond_init( &(blio->inputCond), NULL ) ); if( result ) goto error; result = UNIX_ERR( pthread_mutex_init(&(blio->outputMutex),NULL) ); if( result ) goto error; result = UNIX_ERR( pthread_cond_init( &(blio->outputCond), NULL ) ); #endif if( inChan ) { data = calloc( ringBufferSize, blio->inputSampleSizePow2*inChan ); if( !data ) { result = paInsufficientMemory; goto error; } assert( 0 == PaUtil_InitializeRingBuffer( &blio->inputRingBuffer, ringBufferSize*blio->inputSampleSizePow2*inChan, data ) ); } if( outChan ) { data = calloc( ringBufferSize, blio->outputSampleSizePow2*outChan ); if( !data ) { result = paInsufficientMemory; goto error; } assert( 0 == PaUtil_InitializeRingBuffer( &blio->outputRingBuffer, ringBufferSize*blio->outputSampleSizePow2*outChan, data ) ); } result = resetBlioRingBuffers( blio ); if( result ) goto error; return 0; error: destroyBlioRingBuffers( blio ); return result; } #ifdef PA_MAC_BLIO_MUTEX PaError blioSetIsInputEmpty( PaMacBlio *blio, bool isEmpty ) { PaError result = paNoError; if( isEmpty == blio->isInputEmpty ) goto done; /* we need to update the value. Here's what we do: * - Lock the mutex, so noone else can write. * - update the value. * - unlock. * - broadcast to all listeners. */ result = UNIX_ERR( pthread_mutex_lock( &blio->inputMutex ) ); if( result ) goto done; blio->isInputEmpty = isEmpty; result = UNIX_ERR( pthread_mutex_unlock( &blio->inputMutex ) ); if( result ) goto done; result = UNIX_ERR( pthread_cond_broadcast( &blio->inputCond ) ); if( result ) goto done; done: return result; } PaError blioSetIsOutputFull( PaMacBlio *blio, bool isFull ) { PaError result = paNoError; if( isFull == blio->isOutputFull ) goto done; /* we need to update the value. Here's what we do: * - Lock the mutex, so noone else can write. * - update the value. * - unlock. * - broadcast to all listeners. */ result = UNIX_ERR( pthread_mutex_lock( &blio->outputMutex ) ); if( result ) goto done; blio->isOutputFull = isFull; result = UNIX_ERR( pthread_mutex_unlock( &blio->outputMutex ) ); if( result ) goto done; result = UNIX_ERR( pthread_cond_broadcast( &blio->outputCond ) ); if( result ) goto done; done: return result; } #endif /* This should be called after stopping or aborting the stream, so that on next start, the buffers will be ready. */ PaError resetBlioRingBuffers( PaMacBlio *blio ) { #ifdef PA_MAC__BLIO_MUTEX int result; #endif blio->statusFlags = 0; if( blio->outputRingBuffer.buffer ) { PaUtil_FlushRingBuffer( &blio->outputRingBuffer ); bzero( blio->outputRingBuffer.buffer, blio->outputRingBuffer.bufferSize ); /* Advance buffer */ PaUtil_AdvanceRingBufferWriteIndex( &blio->outputRingBuffer, blio->ringBufferFrames*blio->outputSampleSizeActual*blio->outChan ); //PaUtil_AdvanceRingBufferWriteIndex( &blio->outputRingBuffer, blio->outputRingBuffer.bufferSize ); /* Update isOutputFull. */ #ifdef PA_MAC__BLIO_MUTEX result = blioSetIsOutputFull( blio, toAdvance == blio->outputRingBuffer.bufferSize ); if( result ) goto error; #endif /* printf( "------%d\n" , blio->framesPerBuffer ); printf( "------%d\n" , blio->outChan ); printf( "------%d\n" , blio->outputSampleSize ); printf( "------%d\n" , blio->framesPerBuffer*blio->outChan*blio->outputSampleSize ); */ } if( blio->inputRingBuffer.buffer ) { PaUtil_FlushRingBuffer( &blio->inputRingBuffer ); bzero( blio->inputRingBuffer.buffer, blio->inputRingBuffer.bufferSize ); /* Update isInputEmpty. */ #ifdef PA_MAC__BLIO_MUTEX result = blioSetIsInputEmpty( blio, true ); if( result ) goto error; #endif } return paNoError; #ifdef PA_MAC__BLIO_MUTEX error: return result; #endif } /*This should be called when you are done with the blio. It can safely be called multiple times if there are no exceptions. */ PaError destroyBlioRingBuffers( PaMacBlio *blio ) { PaError result = paNoError; if( blio->inputRingBuffer.buffer ) { free( blio->inputRingBuffer.buffer ); #ifdef PA_MAC__BLIO_MUTEX result = UNIX_ERR( pthread_mutex_destroy( & blio->inputMutex ) ); if( result ) return result; result = UNIX_ERR( pthread_cond_destroy( & blio->inputCond ) ); if( result ) return result; #endif } blio->inputRingBuffer.buffer = NULL; if( blio->outputRingBuffer.buffer ) { free( blio->outputRingBuffer.buffer ); #ifdef PA_MAC__BLIO_MUTEX result = UNIX_ERR( pthread_mutex_destroy( & blio->outputMutex ) ); if( result ) return result; result = UNIX_ERR( pthread_cond_destroy( & blio->outputCond ) ); if( result ) return result; #endif } blio->outputRingBuffer.buffer = NULL; return result; } /* * this is the BlioCallback function. It expects to recieve a PaMacBlio Object * pointer as userData. * */ int BlioCallback( const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData ) { PaMacBlio *blio = (PaMacBlio*)userData; long avail; long toRead; long toWrite; /* set flags returned by OS: */ OSAtomicOr32( statusFlags, &blio->statusFlags ) ; /* --- Handle Input Buffer --- */ if( blio->inChan ) { avail = PaUtil_GetRingBufferWriteAvailable( &blio->inputRingBuffer ); /* check for underflow */ if( avail < frameCount * blio->inputSampleSizeActual * blio->inChan ) OSAtomicOr32( paInputOverflow, &blio->statusFlags ); toRead = MIN( avail, frameCount * blio->inputSampleSizeActual * blio->inChan ); /* copy the data */ /*printf( "reading %d\n", toRead );*/ assert( toRead == PaUtil_WriteRingBuffer( &blio->inputRingBuffer, input, toRead ) ); #ifdef PA_MAC__BLIO_MUTEX /* Priority inversion. See notes below. */ blioSetIsInputEmpty( blio, false ); #endif } /* --- Handle Output Buffer --- */ if( blio->outChan ) { avail = PaUtil_GetRingBufferReadAvailable( &blio->outputRingBuffer ); /* check for underflow */ if( avail < frameCount * blio->outputSampleSizeActual * blio->outChan ) OSAtomicOr32( paOutputUnderflow, &blio->statusFlags ); toWrite = MIN( avail, frameCount * blio->outputSampleSizeActual * blio->outChan ); if( toWrite != frameCount * blio->outputSampleSizeActual * blio->outChan ) bzero( ((char *)output)+toWrite, frameCount * blio->outputSampleSizeActual * blio->outChan - toWrite ); /* copy the data */ /*printf( "writing %d\n", toWrite );*/ assert( toWrite == PaUtil_ReadRingBuffer( &blio->outputRingBuffer, output, toWrite ) ); #ifdef PA_MAC__BLIO_MUTEX /* We have a priority inversion here. However, we will only have to wait if this was true and is now false, which means we've got some room in the buffer. Hopefully problems will be minimized. */ blioSetIsOutputFull( blio, false ); #endif } return paContinue; } PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ) { PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio; char *cbuf = (char *) buffer; PaError ret = paNoError; VVDBUG(("ReadStream()\n")); while( frames > 0 ) { long avail; long toRead; do { avail = PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer ); /* printf( "Read Buffer is %%%g full: %ld of %ld.\n", 100 * (float)avail / (float) blio->inputRingBuffer.bufferSize, avail, blio->inputRingBuffer.bufferSize ); */ if( avail == 0 ) { #ifdef PA_MAC_BLIO_MUTEX /**block when empty*/ ret = UNIX_ERR( pthread_mutex_lock( &blio->inputMutex ) ); if( ret ) return ret; while( blio->isInputEmpty ) { ret = UNIX_ERR( pthread_cond_wait( &blio->inputCond, &blio->inputMutex ) ); if( ret ) return ret; } ret = UNIX_ERR( pthread_mutex_unlock( &blio->inputMutex ) ); if( ret ) return ret; #else Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL ); #endif } } while( avail == 0 ); toRead = MIN( avail, frames * blio->inputSampleSizeActual * blio->inChan ); toRead -= toRead % blio->inputSampleSizeActual * blio->inChan ; PaUtil_ReadRingBuffer( &blio->inputRingBuffer, (void *)cbuf, toRead ); cbuf += toRead; frames -= toRead / ( blio->inputSampleSizeActual * blio->inChan ); if( toRead == avail ) { #ifdef PA_MAC_BLIO_MUTEX /* we just emptied the buffer, so we need to mark it as empty. */ ret = blioSetIsInputEmpty( blio, true ); if( ret ) return ret; /* of course, in the meantime, the callback may have put some sats in, so so check for that, too, to avoid a race condition. */ if( PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer ) ) { blioSetIsInputEmpty( blio, false ); if( ret ) return ret; } #endif } } /* Report either paNoError or paInputOverflowed. */ /* may also want to report other errors, but this is non-standard. */ ret = blio->statusFlags & paInputOverflow; /* report underflow only once: */ if( ret ) { OSAtomicAnd32( (uint32_t)(~paInputOverflow), &blio->statusFlags ); ret = paInputOverflowed; } return ret; } PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ) { PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio; char *cbuf = (char *) buffer; PaError ret = paNoError; VVDBUG(("WriteStream()\n")); while( frames > 0 ) { long avail = 0; long toWrite; do { avail = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ); /* printf( "Write Buffer is %%%g full: %ld of %ld.\n", 100 - 100 * (float)avail / (float) blio->outputRingBuffer.bufferSize, avail, blio->outputRingBuffer.bufferSize ); */ if( avail == 0 ) { #ifdef PA_MAC_BLIO_MUTEX /*block while full*/ ret = UNIX_ERR( pthread_mutex_lock( &blio->outputMutex ) ); if( ret ) return ret; while( blio->isOutputFull ) { ret = UNIX_ERR( pthread_cond_wait( &blio->outputCond, &blio->outputMutex ) ); if( ret ) return ret; } ret = UNIX_ERR( pthread_mutex_unlock( &blio->outputMutex ) ); if( ret ) return ret; #else Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL ); #endif } } while( avail == 0 ); toWrite = MIN( avail, frames * blio->outputSampleSizeActual * blio->outChan ); toWrite -= toWrite % blio->outputSampleSizeActual * blio->outChan ; PaUtil_WriteRingBuffer( &blio->outputRingBuffer, (void *)cbuf, toWrite ); cbuf += toWrite; frames -= toWrite / ( blio->outputSampleSizeActual * blio->outChan ); #ifdef PA_MAC_BLIO_MUTEX if( toWrite == avail ) { /* we just filled up the buffer, so we need to mark it as filled. */ ret = blioSetIsOutputFull( blio, true ); if( ret ) return ret; /* of course, in the meantime, we may have emptied the buffer, so so check for that, too, to avoid a race condition. */ if( PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ) ) { blioSetIsOutputFull( blio, false ); if( ret ) return ret; } } #endif } /* Report either paNoError or paOutputUnderflowed. */ /* may also want to report other errors, but this is non-standard. */ ret = blio->statusFlags & paOutputUnderflow; /* report underflow only once: */ if( ret ) { OSAtomicAnd32( (uint32_t)(~paOutputUnderflow), &blio->statusFlags ); ret = paOutputUnderflowed; } return ret; } /* * */ void waitUntilBlioWriteBufferIsFlushed( PaMacBlio *blio ) { if( blio->outputRingBuffer.buffer ) { long avail = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ); while( avail != blio->outputRingBuffer.bufferSize ) { if( avail == 0 ) Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL ); avail = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ); } } } signed long GetStreamReadAvailable( PaStream* stream ) { PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio; VVDBUG(("GetStreamReadAvailable()\n")); return PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer ) / ( blio->outputSampleSizeActual * blio->outChan ); } signed long GetStreamWriteAvailable( PaStream* stream ) { PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio; VVDBUG(("GetStreamWriteAvailable()\n")); return PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ) / ( blio->outputSampleSizeActual * blio->outChan ); } praat-6.0.04/external/portaudio2007/pa_mac_core_blocking.h000066400000000000000000000110431261542461700233310ustar00rootroot00000000000000/* * Internal blocking interfaces for PortAudio Apple AUHAL implementation * * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * * Written by Bjorn Roche of XO Audio LLC, from PA skeleton code. * Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation) * * Dominic's code was based on code by Phil Burk, Darren Gibbs, * Gord Peters, Stephane Letz, and Greg Pfiel. * * The following people also deserve acknowledgements: * * Olivier Tristan for feedback and testing * Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O * interface. * * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostaip_src */ #ifndef PA_MAC_CORE_BLOCKING_H_ #define PA_MAC_CORE_BLOCKING_H_ #include "pa_ringbuffer.h" #include "portaudio.h" #include "pa_mac_core_utilities.h" /* * Number of miliseconds to busy wait whil waiting for data in blocking calls. */ #define PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL (5) /* * Define exactly one of these blocking methods * PA_MAC_BLIO_MUTEX is not actively maintained. */ #define PA_MAC_BLIO_BUSY_WAIT /* #define PA_MAC_BLIO_MUTEX */ typedef struct { PaUtilRingBuffer inputRingBuffer; PaUtilRingBuffer outputRingBuffer; size_t ringBufferFrames; PaSampleFormat inputSampleFormat; size_t inputSampleSizeActual; size_t inputSampleSizePow2; PaSampleFormat outputSampleFormat; size_t outputSampleSizeActual; size_t outputSampleSizePow2; size_t framesPerBuffer; int inChan; int outChan; //PaStreamCallbackFlags statusFlags; uint32_t statusFlags; PaError errors; /* Here we handle blocking, using condition variables. */ #ifdef PA_MAC_BLIO_MUTEX volatile bool isInputEmpty; pthread_mutex_t inputMutex; pthread_cond_t inputCond; volatile bool isOutputFull; pthread_mutex_t outputMutex; pthread_cond_t outputCond; #endif } PaMacBlio; /* * These functions operate on condition and related variables. */ PaError initializeBlioRingBuffers( PaMacBlio *blio, PaSampleFormat inputSampleFormat, PaSampleFormat outputSampleFormat, size_t framesPerBuffer, long ringBufferSize, int inChan, int outChan ); PaError destroyBlioRingBuffers( PaMacBlio *blio ); PaError resetBlioRingBuffers( PaMacBlio *blio ); int BlioCallback( const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData ); void waitUntilBlioWriteBufferIsFlushed( PaMacBlio *blio ); #endif /*PA_MAC_CORE_BLOCKING_H_*/ praat-6.0.04/external/portaudio2007/pa_mac_core_internal.h000066400000000000000000000132331261542461700233600ustar00rootroot00000000000000/* * Internal interfaces for PortAudio Apple AUHAL implementation * * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * * Written by Bjorn Roche of XO Audio LLC, from PA skeleton code. * Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation) * * Dominic's code was based on code by Phil Burk, Darren Gibbs, * Gord Peters, Stephane Letz, and Greg Pfiel. * * The following people also deserve acknowledgements: * * Olivier Tristan for feedback and testing * Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O * interface. * * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file pa_mac_core @ingroup hostapi_src @author Bjorn Roche @brief AUHAL implementation of PortAudio */ #ifndef PA_MAC_CORE_INTERNAL_H__ #define PA_MAC_CORE_INTERNAL_H__ #include #include #include "portaudio.h" #include "pa_util.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_allocation.h" #include "pa_cpuload.h" #include "pa_process.h" #include "pa_ringbuffer.h" #include "pa_mac_core_blocking.h" /* function prototypes */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); #ifdef __cplusplus } #endif /* __cplusplus */ #define RING_BUFFER_ADVANCE_DENOMINATOR (4) PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ); PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ); signed long GetStreamReadAvailable( PaStream* stream ); signed long GetStreamWriteAvailable( PaStream* stream ); /* PaMacAUHAL - host api datastructure specific to this implementation */ typedef struct { PaUtilHostApiRepresentation inheritedHostApiRep; PaUtilStreamInterface callbackStreamInterface; PaUtilStreamInterface blockingStreamInterface; PaUtilAllocationGroup *allocations; /* implementation specific data goes here */ long devCount; AudioDeviceID *devIds; /*array of all audio devices*/ AudioDeviceID defaultIn; AudioDeviceID defaultOut; } PaMacAUHAL; /* stream data structure specifically for this implementation */ typedef struct PaMacCoreStream { PaUtilStreamRepresentation streamRepresentation; PaUtilCpuLoadMeasurer cpuLoadMeasurer; PaUtilBufferProcessor bufferProcessor; /* implementation specific data goes here */ bool bufferProcessorIsInitialized; AudioUnit inputUnit; AudioUnit outputUnit; AudioDeviceID inputDevice; AudioDeviceID outputDevice; size_t userInChan; size_t userOutChan; size_t inputFramesPerBuffer; size_t outputFramesPerBuffer; PaMacBlio blio; /* We use this ring buffer when input and out devs are different. */ PaUtilRingBuffer inputRingBuffer; /* We may need to do SR conversion on input. */ AudioConverterRef inputSRConverter; /* We need to preallocate an inputBuffer for reading data. */ AudioBufferList inputAudioBufferList; AudioTimeStamp startTime; /* FIXME: instead of volatile, these should be properly memory barriered */ volatile PaStreamCallbackFlags xrunFlags; volatile bool isTimeSet; volatile enum { STOPPED = 0, /* playback is completely stopped, and the user has called StopStream(). */ CALLBACK_STOPPED = 1, /* callback has requested stop, but user has not yet called StopStream(). */ STOPPING = 2, /* The stream is in the process of closing because the user has called StopStream. This state is just used internally; externally it is indistinguishable from ACTIVE.*/ ACTIVE = 3 /* The stream is active and running. */ } state; double sampleRate; //these may be different from the stream sample rate due to SR conversion: double outDeviceSampleRate; double inDeviceSampleRate; } PaMacCoreStream; #endif /* PA_MAC_CORE_INTERNAL_H__ */ praat-6.0.04/external/portaudio2007/pa_mac_core_utilities.c000066400000000000000000000546551261542461700235670ustar00rootroot00000000000000/* * Helper and utility functions for pa_mac_core.c (Apple AUHAL implementation) * * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * * Written by Bjorn Roche of XO Audio LLC, from PA skeleton code. * Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation) * * Dominic's code was based on code by Phil Burk, Darren Gibbs, * Gord Peters, Stephane Letz, and Greg Pfiel. * * The following people also deserve acknowledgements: * * Olivier Tristan for feedback and testing * Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O * interface. * * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostapi_src */ #include "pa_mac_core_utilities.h" PaError PaMacCore_SetUnixError( int err, int line ) { PaError ret; const char *errorText; if( err == 0 ) { return paNoError; } ret = paNoError; errorText = strerror( err ); /** Map Unix error to PaError. Pretty much the only one that maps is ENOMEM. */ if( err == ENOMEM ) ret = paInsufficientMemory; else ret = paInternalError; DBUG(("%d on line %d: msg='%s'\n", err, line, errorText)); PaUtil_SetLastHostErrorInfo( paCoreAudio, err, errorText ); return ret; } /* * Translates MacOS generated errors into PaErrors */ PaError PaMacCore_SetError(OSStatus error, int line, int isError) { /*FIXME: still need to handle possible ComponentResult values.*/ /* unfortunately, they don't seem to be documented anywhere.*/ PaError result; const char *errorType; const char *errorText; switch (error) { case kAudioHardwareNoError: return paNoError; case kAudioHardwareNotRunningError: errorText = "Audio Hardware Not Running"; result = paInternalError; break; case kAudioHardwareUnspecifiedError: errorText = "Unspecified Audio Hardware Error"; result = paInternalError; break; case kAudioHardwareUnknownPropertyError: errorText = "Audio Hardware: Unknown Property"; result = paInternalError; break; case kAudioHardwareBadPropertySizeError: errorText = "Audio Hardware: Bad Property Size"; result = paInternalError; break; case kAudioHardwareIllegalOperationError: errorText = "Audio Hardware: Illegal Operation"; result = paInternalError; break; case kAudioHardwareBadDeviceError: errorText = "Audio Hardware: Bad Device"; result = paInvalidDevice; break; case kAudioHardwareBadStreamError: errorText = "Audio Hardware: BadStream"; result = paBadStreamPtr; break; case kAudioHardwareUnsupportedOperationError: errorText = "Audio Hardware: Unsupported Operation"; result = paInternalError; break; case kAudioDeviceUnsupportedFormatError: errorText = "Audio Device: Unsupported Format"; result = paSampleFormatNotSupported; break; case kAudioDevicePermissionsError: errorText = "Audio Device: Permissions Error"; result = paDeviceUnavailable; break; /* Audio Unit Errors: http://developer.apple.com/documentation/MusicAudio/Reference/CoreAudio/audio_units/chapter_5_section_3.html */ case kAudioUnitErr_InvalidProperty: errorText = "Audio Unit: Invalid Property"; result = paInternalError; break; case kAudioUnitErr_InvalidParameter: errorText = "Audio Unit: Invalid Parameter"; result = paInternalError; break; case kAudioUnitErr_NoConnection: errorText = "Audio Unit: No Connection"; result = paInternalError; break; case kAudioUnitErr_FailedInitialization: errorText = "Audio Unit: Initialization Failed"; result = paInternalError; break; case kAudioUnitErr_TooManyFramesToProcess: errorText = "Audio Unit: Too Many Frames"; result = paInternalError; break; case kAudioUnitErr_IllegalInstrument: errorText = "Audio Unit: Illegal Instrument"; result = paInternalError; break; case kAudioUnitErr_InstrumentTypeNotFound: errorText = "Audio Unit: Instrument Type Not Found"; result = paInternalError; break; case kAudioUnitErr_InvalidFile: errorText = "Audio Unit: Invalid File"; result = paInternalError; break; case kAudioUnitErr_UnknownFileType: errorText = "Audio Unit: Unknown File Type"; result = paInternalError; break; case kAudioUnitErr_FileNotSpecified: errorText = "Audio Unit: File Not Specified"; result = paInternalError; break; case kAudioUnitErr_FormatNotSupported: errorText = "Audio Unit: Format Not Supported"; result = paInternalError; break; case kAudioUnitErr_Uninitialized: errorText = "Audio Unit: Unitialized"; result = paInternalError; break; case kAudioUnitErr_InvalidScope: errorText = "Audio Unit: Invalid Scope"; result = paInternalError; break; case kAudioUnitErr_PropertyNotWritable: errorText = "Audio Unit: PropertyNotWritable"; result = paInternalError; break; case kAudioUnitErr_InvalidPropertyValue: errorText = "Audio Unit: Invalid Property Value"; result = paInternalError; break; case kAudioUnitErr_PropertyNotInUse: errorText = "Audio Unit: Property Not In Use"; result = paInternalError; break; case kAudioUnitErr_Initialized: errorText = "Audio Unit: Initialized"; result = paInternalError; break; case kAudioUnitErr_InvalidOfflineRender: errorText = "Audio Unit: Invalid Offline Render"; result = paInternalError; break; case kAudioUnitErr_Unauthorized: errorText = "Audio Unit: Unauthorized"; result = paInternalError; break; case kAudioUnitErr_CannotDoInCurrentContext: errorText = "Audio Unit: cannot do in current context"; result = paInternalError; break; default: errorText = "Unknown Error"; result = paInternalError; } if (isError) errorType = "Error"; else errorType = "Warning"; char str[20]; // see if it appears to be a 4-char-code *(UInt32 *)(str + 1) = CFSwapInt32HostToBig(error); if (isprint(str[1]) && isprint(str[2]) && isprint(str[3]) && isprint(str[4])) { str[0] = str[5] = '\''; str[6] = '\0'; } else { // no, format it as an integer sprintf(str, "%d", (int)error); } DBUG(("%s on line %d: err='%s', msg=%s\n", errorType, line, str, errorText)); PaUtil_SetLastHostErrorInfo( paCoreAudio, error, errorText ); return result; } /* * This function computes an appropriate ring buffer size given * a requested latency (in seconds), sample rate and framesPerBuffer. * * The returned ringBufferSize is computed using the following * constraints: * - it must be at least 4. * - it must be at least 3x framesPerBuffer. * - it must be at least 2x the suggestedLatency. * - it must be a power of 2. * This function attempts to compute the minimum such size. * * FEEDBACK: too liberal/conservative/another way? */ long computeRingBufferSize( const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, long inputFramesPerBuffer, long outputFramesPerBuffer, double sampleRate ) { long ringSize; int index; int i; double latencyTimesChannelCount ; long framesPerBufferTimesChannelCount ; VVDBUG(( "computeRingBufferSize()\n" )); assert( inputParameters || outputParameters ); if( outputParameters && inputParameters ) { latencyTimesChannelCount = MAX( inputParameters->suggestedLatency * inputParameters->channelCount, outputParameters->suggestedLatency * outputParameters->channelCount ); framesPerBufferTimesChannelCount = MAX( inputFramesPerBuffer * inputParameters->channelCount, outputFramesPerBuffer * outputParameters->channelCount ); } else if( outputParameters ) { latencyTimesChannelCount = outputParameters->suggestedLatency * outputParameters->channelCount; framesPerBufferTimesChannelCount = outputFramesPerBuffer * outputParameters->channelCount; } else /* we have inputParameters */ { latencyTimesChannelCount = inputParameters->suggestedLatency * inputParameters->channelCount; framesPerBufferTimesChannelCount = inputFramesPerBuffer * inputParameters->channelCount; } ringSize = (long) ( latencyTimesChannelCount * sampleRate * 2 + .5); VDBUG( ( "suggested latency * channelCount: %d\n", (int) (latencyTimesChannelCount*sampleRate) ) ); if( ringSize < framesPerBufferTimesChannelCount * 3 ) ringSize = framesPerBufferTimesChannelCount * 3 ; VDBUG(("framesPerBuffer*channelCount:%d\n",(int)framesPerBufferTimesChannelCount)); VDBUG(("Ringbuffer size (1): %d\n", (int)ringSize )); /* make sure it's at least 4 */ ringSize = MAX( ringSize, 4 ); /* round up to the next power of 2 */ index = -1; for( i=0; i> i & 0x01 ) index = i; assert( index > 0 ); if( ringSize <= ( 0x01 << index ) ) ringSize = 0x01 << index ; else ringSize = 0x01 << ( index + 1 ); VDBUG(( "Final Ringbuffer size (2): %d\n", (int)ringSize )); return ringSize; } /* * Durring testing of core audio, I found that serious crashes could occur * if properties such as sample rate were changed multiple times in rapid * succession. The function below has some fancy logic to make sure that changes * are acknowledged before another is requested. That seems to help a lot. */ OSStatus propertyProc( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData ) { MutexAndBool *mab = (MutexAndBool *) inClientData; mab->once = TRUE; pthread_mutex_unlock( &(mab->mutex) ); return noErr; } /* sets the value of the given property and waits for the change to be acknowledged, and returns the final value, which is not guaranteed by this function to be the same as the desired value. Obviously, this function can only be used for data whose input and output are the same size and format, and their size and format are known in advance.*/ PaError AudioDeviceSetPropertyNowAndWaitForChange( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, UInt32 inPropertyDataSize, const void *inPropertyData, void *outPropertyData ) { OSStatus macErr; int unixErr; MutexAndBool mab; UInt32 outPropertyDataSize = inPropertyDataSize; /* First, see if it already has that value. If so, return. */ macErr = AudioDeviceGetProperty( inDevice, inChannel, isInput, inPropertyID, &outPropertyDataSize, outPropertyData ); if( macErr ) goto failMac2; if( inPropertyDataSize!=outPropertyDataSize ) return paInternalError; if( 0==memcmp( outPropertyData, inPropertyData, outPropertyDataSize ) ) return paNoError; /* setup and lock mutex */ mab.once = FALSE; unixErr = pthread_mutex_init( &mab.mutex, NULL ); if( unixErr ) goto failUnix2; unixErr = pthread_mutex_lock( &mab.mutex ); if( unixErr ) goto failUnix; /* add property listener */ macErr = AudioDeviceAddPropertyListener( inDevice, inChannel, isInput, inPropertyID, propertyProc, &mab ); if( macErr ) goto failMac; /* set property */ macErr = AudioDeviceSetProperty( inDevice, NULL, inChannel, isInput, inPropertyID, inPropertyDataSize, inPropertyData ); if( macErr ) { /* we couldn't set the property, so we'll just unlock the mutex and move on. */ pthread_mutex_unlock( &mab.mutex ); } /* wait for property to change */ unixErr = pthread_mutex_lock( &mab.mutex ); if( unixErr ) goto failUnix; /* now read the property back out */ macErr = AudioDeviceGetProperty( inDevice, inChannel, isInput, inPropertyID, &outPropertyDataSize, outPropertyData ); if( macErr ) goto failMac; /* cleanup */ AudioDeviceRemovePropertyListener( inDevice, inChannel, isInput, inPropertyID, propertyProc ); unixErr = pthread_mutex_unlock( &mab.mutex ); if( unixErr ) goto failUnix2; unixErr = pthread_mutex_destroy( &mab.mutex ); if( unixErr ) goto failUnix2; return paNoError; failUnix: pthread_mutex_destroy( &mab.mutex ); AudioDeviceRemovePropertyListener( inDevice, inChannel, isInput, inPropertyID, propertyProc ); failUnix2: DBUG( ("Error #%d while setting a device property: %s\n", unixErr, strerror( unixErr ) ) ); return paUnanticipatedHostError; failMac: pthread_mutex_destroy( &mab.mutex ); AudioDeviceRemovePropertyListener( inDevice, inChannel, isInput, inPropertyID, propertyProc ); failMac2: return ERR( macErr ); } /* * Sets the sample rate the HAL device. * if requireExact: set the sample rate or fail. * * otherwise : set the exact sample rate. * If that fails, check for available sample rates, and choose one * higher than the requested rate. If there isn't a higher one, * just use the highest available. */ PaError setBestSampleRateForDevice( const AudioDeviceID device, const bool isOutput, const bool requireExact, const Float64 desiredSrate ) { /*FIXME: changing the sample rate is disruptive to other programs using the device, so it might be good to offer a custom flag to not change the sample rate and just do conversion. (in my casual tests, there is no disruption unless the sample rate really does need to change) */ const bool isInput = isOutput ? 0 : 1; Float64 srate; UInt32 propsize = sizeof( Float64 ); OSErr err; AudioValueRange *ranges; int i=0; Float64 max = -1; /*the maximum rate available*/ Float64 best = -1; /*the lowest sample rate still greater than desired rate*/ VDBUG(("Setting sample rate for device %ld to %g.\n",device,(float)desiredSrate)); /* -- try setting the sample rate -- */ err = AudioDeviceSetPropertyNowAndWaitForChange( device, 0, isInput, kAudioDevicePropertyNominalSampleRate, propsize, &desiredSrate, &srate ); if( err ) return err; /* -- if the rate agrees, and we got no errors, we are done -- */ if( !err && srate == desiredSrate ) return paNoError; /* -- we've failed if the rates disagree and we are setting input -- */ if( requireExact ) return paInvalidSampleRate; /* -- generate a list of available sample rates -- */ err = AudioDeviceGetPropertyInfo( device, 0, isInput, kAudioDevicePropertyAvailableNominalSampleRates, &propsize, NULL ); if( err ) return ERR( err ); ranges = (AudioValueRange *)calloc( 1, propsize ); if( !ranges ) return paInsufficientMemory; err = AudioDeviceGetProperty( device, 0, isInput, kAudioDevicePropertyAvailableNominalSampleRates, &propsize, ranges ); if( err ) { free( ranges ); return ERR( err ); } VDBUG(("Requested sample rate of %g was not available.\n", (float)desiredSrate)); VDBUG(("%lu Available Sample Rates are:\n",propsize/sizeof(AudioValueRange))); #ifdef MAC_CORE_VERBOSE_DEBUG for( i=0; i max ) max = ranges[i].mMaximum; if( ranges[i].mMinimum > desiredSrate ) { if( best < 0 ) best = ranges[i].mMinimum; else if( ranges[i].mMinimum < best ) best = ranges[i].mMinimum; } } if( best < 0 ) best = max; VDBUG( ("Maximum Rate %g. best is %g.\n", max, best ) ); free( ranges ); /* -- set the sample rate -- */ propsize = sizeof( best ); err = AudioDeviceSetPropertyNowAndWaitForChange( device, 0, isInput, kAudioDevicePropertyNominalSampleRate, propsize, &best, &srate ); if( err ) return err; if( err ) return ERR( err ); /* -- if the set rate matches, we are done -- */ if( srate == best ) return paNoError; /* -- otherwise, something wierd happened: we didn't set the rate, and we got no errors. Just bail. */ return paInternalError; } /* Attempts to set the requestedFramesPerBuffer. If it can't set the exact value, it settles for something smaller if available. If nothing smaller is available, it uses the smallest available size. actualFramesPerBuffer will be set to the actual value on successful return. OK to pass NULL to actualFramesPerBuffer. The logic is very simmilar too setBestSampleRate only failure here is not usually catastrophic. */ PaError setBestFramesPerBuffer( const AudioDeviceID device, const bool isOutput, UInt32 requestedFramesPerBuffer, UInt32 *actualFramesPerBuffer ) { UInt32 afpb; const bool isInput = !isOutput; UInt32 propsize = sizeof(UInt32); OSErr err; Float64 min = -1; /*the min blocksize*/ Float64 best = -1; /*the best blocksize*/ int i=0; AudioValueRange *ranges; if( actualFramesPerBuffer == NULL ) actualFramesPerBuffer = &afpb; /* -- try and set exact FPB -- */ err = AudioDeviceSetProperty( device, NULL, 0, isInput, kAudioDevicePropertyBufferFrameSize, propsize, &requestedFramesPerBuffer); err = AudioDeviceGetProperty( device, 0, isInput, kAudioDevicePropertyBufferFrameSize, &propsize, actualFramesPerBuffer); if( err ) return ERR( err ); if( *actualFramesPerBuffer == requestedFramesPerBuffer ) return paNoError; /* we are done */ /* -- fetch available block sizes -- */ err = AudioDeviceGetPropertyInfo( device, 0, isInput, kAudioDevicePropertyBufferSizeRange, &propsize, NULL ); if( err ) return ERR( err ); ranges = (AudioValueRange *)calloc( 1, propsize ); if( !ranges ) return paInsufficientMemory; err = AudioDeviceGetProperty( device, 0, isInput, kAudioDevicePropertyBufferSizeRange, &propsize, ranges ); if( err ) { free( ranges ); return ERR( err ); } VDBUG(("Requested block size of %lu was not available.\n", requestedFramesPerBuffer )); VDBUG(("%lu Available block sizes are:\n",propsize/sizeof(AudioValueRange))); #ifdef MAC_CORE_VERBOSE_DEBUG for( i=0; i best ) best = ranges[i].mMaximum; } } if( best == -1 ) best = min; VDBUG( ("Minimum FPB %g. best is %g.\n", min, best ) ); free( ranges ); /* --- set the buffer size (ignore errors) -- */ requestedFramesPerBuffer = (UInt32) best ; propsize = sizeof( UInt32 ); err = AudioDeviceSetProperty( device, NULL, 0, isInput, kAudioDevicePropertyBufferSize, propsize, &requestedFramesPerBuffer ); /* --- read the property to check that it was set -- */ err = AudioDeviceGetProperty( device, 0, isInput, kAudioDevicePropertyBufferSize, &propsize, actualFramesPerBuffer ); if( err ) return ERR( err ); return paNoError; } praat-6.0.04/external/portaudio2007/pa_mac_core_utilities.h000066400000000000000000000161101261542461700235540ustar00rootroot00000000000000/* * Helper and utility functions for pa_mac_core.c (Apple AUHAL implementation) * * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * * Written by Bjorn Roche of XO Audio LLC, from PA skeleton code. * Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation) * * Dominic's code was based on code by Phil Burk, Darren Gibbs, * Gord Peters, Stephane Letz, and Greg Pfiel. * * The following people also deserve acknowledgements: * * Olivier Tristan for feedback and testing * Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O * interface. * * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostapi_src */ #ifndef PA_MAC_CORE_UTILITIES_H__ #define PA_MAC_CORE_UTILITIES_H__ #include #include "portaudio.h" #include "pa_util.h" #include #include #ifndef MIN #define MIN(a, b) (((a)<(b))?(a):(b)) #endif #ifndef MAX #define MAX(a, b) (((a)<(b))?(b):(a)) #endif #define ERR(mac_error) PaMacCore_SetError(mac_error, __LINE__, 1 ) #define WARNING(mac_error) PaMacCore_SetError(mac_error, __LINE__, 0 ) /* Help keep track of AUHAL element numbers */ #define INPUT_ELEMENT (1) #define OUTPUT_ELEMENT (0) /* Normal level of debugging: fine for most apps that don't mind the occational warning being printf'ed */ /* */ #define MAC_CORE_DEBUG #ifdef MAC_CORE_DEBUG # define DBUG(MSG) do { printf("||PaMacCore (AUHAL)|| "); printf MSG ; fflush(stdout); } while(0) #else # define DBUG(MSG) #endif /* Verbose Debugging: useful for developement */ /* #define MAC_CORE_VERBOSE_DEBUG */ #ifdef MAC_CORE_VERBOSE_DEBUG # define VDBUG(MSG) do { printf("||PaMacCore (v )|| "); printf MSG ; fflush(stdout); } while(0) #else # define VDBUG(MSG) #endif /* Very Verbose Debugging: Traces every call. */ /* #define MAC_CORE_VERY_VERBOSE_DEBUG */ #ifdef MAC_CORE_VERY_VERBOSE_DEBUG # define VVDBUG(MSG) do { printf("||PaMacCore (vv)|| "); printf MSG ; fflush(stdout); } while(0) #else # define VVDBUG(MSG) #endif #define UNIX_ERR(err) PaMacCore_SetUnixError( err, __LINE__ ) PaError PaMacCore_SetUnixError( int err, int line ); /* * Translates MacOS generated errors into PaErrors */ PaError PaMacCore_SetError(OSStatus error, int line, int isError); /* * This function computes an appropriate ring buffer size given * a requested latency (in seconds), sample rate and framesPerBuffer. * * The returned ringBufferSize is computed using the following * constraints: * - it must be at least 4. * - it must be at least 3x framesPerBuffer. * - it must be at least 2x the suggestedLatency. * - it must be a power of 2. * This function attempts to compute the minimum such size. * */ long computeRingBufferSize( const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, long inputFramesPerBuffer, long outputFramesPerBuffer, double sampleRate ); /* * Durring testing of core audio, I found that serious crashes could occur * if properties such as sample rate were changed multiple times in rapid * succession. The function below has some fancy logic to make sure that changes * are acknowledged before another is requested. That seems to help a lot. */ typedef struct { bool once; /* I didn't end up using this. bdr */ pthread_mutex_t mutex; } MutexAndBool ; OSStatus propertyProc( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData ); /* sets the value of the given property and waits for the change to be acknowledged, and returns the final value, which is not guaranteed by this function to be the same as the desired value. Obviously, this function can only be used for data whose input and output are the same size and format, and their size and format are known in advance.*/ PaError AudioDeviceSetPropertyNowAndWaitForChange( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, UInt32 inPropertyDataSize, const void *inPropertyData, void *outPropertyData ); /* * Sets the sample rate the HAL device. * if requireExact: set the sample rate or fail. * * otherwise : set the exact sample rate. * If that fails, check for available sample rates, and choose one * higher than the requested rate. If there isn't a higher one, * just use the highest available. */ PaError setBestSampleRateForDevice( const AudioDeviceID device, const bool isOutput, const bool requireExact, const Float64 desiredSrate ); /* Attempts to set the requestedFramesPerBuffer. If it can't set the exact value, it settles for something smaller if available. If nothing smaller is available, it uses the smallest available size. actualFramesPerBuffer will be set to the actual value on successful return. OK to pass NULL to actualFramesPerBuffer. The logic is very simmilar too setBestSampleRate only failure here is not usually catastrophic. */ PaError setBestFramesPerBuffer( const AudioDeviceID device, const bool isOutput, UInt32 requestedFramesPerBuffer, UInt32 *actualFramesPerBuffer ); #endif /* PA_MAC_CORE_UTILITIES_H__*/ praat-6.0.04/external/portaudio2007/pa_mac_hostapis.c000066400000000000000000000051131261542461700223570ustar00rootroot00000000000000/* * $Id: pa_mac_hostapis.c 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library Macintosh initialization table * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup macosx_src Mac OS host API initialization function table. */ #include "pa_hostapi.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaMacSm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaJack_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaMacAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); #ifdef __cplusplus } #endif /* __cplusplus */ PaUtilHostApiInitializer *paHostApiInitializers[] = { PaMacCore_Initialize, 0 /* NULL terminated array */ }; int paDefaultHostApiIndex = 0; praat-6.0.04/external/portaudio2007/pa_mac_util.c000066400000000000000000000071571261542461700215140ustar00rootroot00000000000000/* * $Id: pa_unix_util.c 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library * UNIX platform-specific support functions * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2000 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup unix_src */ #include #include #include #include #include #include #include /* For memset */ #include #include #include "pa_util.h" //#include "pa_mac_util.h" /* Track memory allocations to avoid leaks. */ #if PA_TRACK_MEMORY static int numAllocations_ = 0; #endif void *PaUtil_AllocateMemory( long size ) { void *result = malloc( size ); #if PA_TRACK_MEMORY if( result != NULL ) numAllocations_ += 1; #endif return result; } void PaUtil_FreeMemory( void *block ) { if( block != NULL ) { free( block ); #if PA_TRACK_MEMORY numAllocations_ -= 1; #endif } } int PaUtil_CountCurrentlyAllocatedBlocks( void ) { #if PA_TRACK_MEMORY return numAllocations_; #else return 0; #endif } void Pa_Sleep( long msec ) { #ifdef HAVE_NANOSLEEP struct timespec req = {0}, rem = {0}; PaTime time = msec / 1.e3; req.tv_sec = (time_t)time; assert(time - req.tv_sec < 1.0); req.tv_nsec = (long)((time - req.tv_sec) * 1.e9); nanosleep(&req, &rem); /* XXX: Try sleeping the remaining time (contained in rem) if interrupted by a signal? */ #else while( msec > 999 ) /* For OpenBSD and IRIX, argument */ { /* to usleep must be < 1000000. */ usleep( 999000 ); msec -= 999; } usleep( msec * 1000 ); #endif } /* *** NOT USED YET: *** static int usePerformanceCounter_; static double microsecondsPerTick_; */ void PaUtil_InitializeClock( void ) { /* TODO */ } PaTime PaUtil_GetTime( void ) { #ifdef HAVE_CLOCK_GETTIME struct timespec tp; clock_gettime(CLOCK_REALTIME, &tp); return (PaTime)(tp.tv_sec + tp.tv_nsec / 1.e9); #else struct timeval tv; gettimeofday( &tv, NULL ); return (PaTime) tv.tv_usec / 1000000. + tv.tv_sec; #endif } praat-6.0.04/external/portaudio2007/pa_mac_util.h000066400000000000000000000172611261542461700215160ustar00rootroot00000000000000/* * $Id: pa_unix_util.h 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library * UNIX platform-specific support functions * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2000 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup unix_src */ #ifndef PA_UNIX_UTIL_H #define PA_UNIX_UTIL_H #include "pa_cpuload.h" #include #include #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define PA_MIN(x,y) ( (x) < (y) ? (x) : (y) ) #define PA_MAX(x,y) ( (x) > (y) ? (x) : (y) ) /* Utilize GCC branch prediction for error tests */ #if defined __GNUC__ && __GNUC__ >= 3 #define UNLIKELY(expr) __builtin_expect( (expr), 0 ) #else #define UNLIKELY(expr) (expr) #endif #define STRINGIZE_HELPER(expr) #expr #define STRINGIZE(expr) STRINGIZE_HELPER(expr) #define PA_UNLESS(expr, code) \ do { \ if( UNLIKELY( (expr) == 0 ) ) \ { \ PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \ result = (code); \ goto error; \ } \ } while (0); static PaError paUtilErr_; /* Used with PA_ENSURE */ /* Check PaError */ #define PA_ENSURE(expr) \ do { \ if( UNLIKELY( (paUtilErr_ = (expr)) < paNoError ) ) \ { \ PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \ result = paUtilErr_; \ goto error; \ } \ } while (0); #define PA_ASSERT_CALL(expr, success) \ paUtilErr_ = (expr); \ assert( success == paUtilErr_ ); #define PA_ENSURE_SYSTEM(expr, success) \ do { \ if( UNLIKELY( (paUtilErr_ = (expr)) != success ) ) \ { \ /* PaUtil_SetLastHostErrorInfo should only be used in the main thread */ \ if( pthread_equal(pthread_self(), paUnixMainThread) ) \ { \ PaUtil_SetLastHostErrorInfo( paALSA, paUtilErr_, strerror( paUtilErr_ ) ); \ } \ PaUtil_DebugPrint( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" ); \ result = paUnanticipatedHostError; \ goto error; \ } \ } while( 0 ); typedef struct { pthread_t callbackThread; } PaUtilThreading; PaError PaUtil_InitializeThreading( PaUtilThreading *threading ); void PaUtil_TerminateThreading( PaUtilThreading *threading ); PaError PaUtil_StartThreading( PaUtilThreading *threading, void *(*threadRoutine)(void *), void *data ); PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *exitResult ); /* State accessed by utility functions */ /* void PaUnix_SetRealtimeScheduling( int rt ); void PaUtil_InitializeThreading( PaUtilThreading *th, PaUtilCpuLoadMeasurer *clm ); PaError PaUtil_CreateCallbackThread( PaUtilThreading *th, void *(*CallbackThreadFunc)( void * ), PaStream *s ); PaError PaUtil_KillCallbackThread( PaUtilThreading *th, PaError *exitResult ); void PaUtil_CallbackUpdate( PaUtilThreading *th ); */ extern pthread_t paUnixMainThread; typedef struct { pthread_mutex_t mtx; } PaUnixMutex; PaError PaUnixMutex_Initialize( PaUnixMutex* self ); PaError PaUnixMutex_Terminate( PaUnixMutex* self ); PaError PaUnixMutex_Lock( PaUnixMutex* self ); PaError PaUnixMutex_Unlock( PaUnixMutex* self ); typedef struct { pthread_t thread; int parentWaiting; int stopRequested; int locked; PaUnixMutex mtx; pthread_cond_t cond; volatile sig_atomic_t stopRequest; } PaUnixThread; /** Initialize global threading state. */ PaError PaUnixThreading_Initialize(); /** Perish, passing on eventual error code. * * A thin wrapper around pthread_exit, will automatically pass on any error code to the joining thread. * If the result indicates an error, i.e. it is not equal to paNoError, this function will automatically * allocate a pointer so the error is passed on with pthread_exit. If the result indicates that all is * well however, only a NULL pointer will be handed to pthread_exit. Thus, the joining thread should * check whether a non-NULL result pointer is obtained from pthread_join and make sure to free it. * @param result: The error code to pass on to the joining thread. */ #define PaUnixThreading_EXIT(result) \ do { \ PaError* pres = NULL; \ if( paNoError != (result) ) \ { \ pres = malloc( sizeof (PaError) ); \ *pres = (result); \ } \ pthread_exit( pres ); \ } while (0); /** Spawn a thread. * * Intended for spawning the callback thread from the main thread. This function can even block (for a certain * time or indefinitely) untill notified by the callback thread (using PaUnixThread_NotifyParent), which can be * useful in order to make sure that callback has commenced before returning from Pa_StartStream. * @param threadFunc: The function to be executed in the child thread. * @param waitForChild: If not 0, wait for child thread to call PaUnixThread_NotifyParent. Less than 0 means * wait for ever, greater than 0 wait for the specified time. * @return: If timed out waiting on child, paTimedOut. */ PaError PaUnixThread_New( PaUnixThread* self, void* (*threadFunc)( void* ), void* threadArg, PaTime waitForChild ); /** Terminate thread. * * @param wait: If true, request that background thread stop and wait untill it does, else cancel it. * @param exitResult: If non-null this will upon return contain the exit status of the thread. */ PaError PaUnixThread_Terminate( PaUnixThread* self, int wait, PaError* exitResult ); /** Prepare to notify waiting parent thread. * * An internal lock must be held before the parent is notified in PaUnixThread_NotifyParent, call this to * acquire it beforehand. * @return: If parent is not waiting, paInternalError. */ PaError PaUnixThread_PrepareNotify( PaUnixThread* self ); /** Notify waiting parent thread. * * @return: If parent timed out waiting, paTimedOut. If parent was never waiting, paInternalError. */ PaError PaUnixThread_NotifyParent( PaUnixThread* self ); /** Has the parent thread requested this thread to stop? */ int PaUnixThread_StopRequested( PaUnixThread* self ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif praat-6.0.04/external/portaudio2007/pa_process.c000066400000000000000000001771621261542461700214010ustar00rootroot00000000000000/* * $Id: pa_process.c 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library * streamCallback <-> host buffer processing adapter * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Buffer Processor implementation. The code in this file is not optimised yet - although it's not clear that it needs to be. there may appear to be redundancies that could be factored into common functions, but the redundanceis are left intentionally as each appearance may have different optimisation possibilities. The optimisations which are planned involve only converting data in-place where possible, rather than copying to the temp buffer(s). Note that in the extreme case of being able to convert in-place, and there being no conversion necessary there should be some code which short-circuits the operation. @todo Consider cache tilings for intereave<->deinterleave. @todo implement timeInfo->currentTime int PaUtil_BeginBufferProcessing() @todo specify and implement some kind of logical policy for handling the underflow and overflow stream flags when the underflow/overflow overlaps multiple user buffers/callbacks. @todo provide support for priming the buffers with data from the callback. The client interface is now implemented through PaUtil_SetNoInput() which sets bp->hostInputChannels[0][0].data to zero. However this is currently only implemented in NonAdaptingProcess(). It shouldn't be needed for AdaptingInputOnlyProcess() (no priming should ever be requested for AdaptingInputOnlyProcess()). Not sure if additional work should be required to make it work with AdaptingOutputOnlyProcess, but it definitely is required for AdaptingProcess. @todo implement PaUtil_SetNoOutput for AdaptingProcess @todo don't allocate temp buffers for blocking streams unless they are needed. At the moment they are needed, but perhaps for host APIs where the implementation passes a buffer to the host they could be used. */ #include #include /* memset() */ #include "pa_process.h" #include "pa_util.h" #define PA_FRAMES_PER_TEMP_BUFFER_WHEN_HOST_BUFFER_SIZE_IS_UNKNOWN_ 1024 #define PA_MIN_( a, b ) ( ((a)<(b)) ? (a) : (b) ) /* greatest common divisor - PGCD in French */ static unsigned long GCD( unsigned long a, unsigned long b ) { return (b==0) ? a : GCD( b, a%b); } /* least common multiple - PPCM in French */ static unsigned long LCM( unsigned long a, unsigned long b ) { return (a*b) / GCD(a,b); } #define PA_MAX_( a, b ) (((a) > (b)) ? (a) : (b)) static unsigned long CalculateFrameShift( unsigned long M, unsigned long N ) { unsigned long result = 0; unsigned long i; unsigned long lcm; assert( M > 0 ); assert( N > 0 ); lcm = LCM( M, N ); for( i = M; i < lcm; i += M ) result = PA_MAX_( result, i % N ); return result; } PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bp, int inputChannelCount, PaSampleFormat userInputSampleFormat, PaSampleFormat hostInputSampleFormat, int outputChannelCount, PaSampleFormat userOutputSampleFormat, PaSampleFormat hostOutputSampleFormat, double sampleRate, PaStreamFlags streamFlags, unsigned long framesPerUserBuffer, unsigned long framesPerHostBuffer, PaUtilHostBufferSizeMode hostBufferSizeMode, PaStreamCallback *streamCallback, void *userData ) { PaError result = paNoError; PaError bytesPerSample; unsigned long tempInputBufferSize, tempOutputBufferSize; if( streamFlags & paNeverDropInput ) { /* paNeverDropInput is only valid for full-duplex callback streams, with an unspecified number of frames per buffer. */ if( !streamCallback || !(inputChannelCount > 0 && outputChannelCount > 0) || framesPerUserBuffer != paFramesPerBufferUnspecified ) return paInvalidFlag; } /* initialize buffer ptrs to zero so they can be freed if necessary in error */ bp->tempInputBuffer = 0; bp->tempInputBufferPtrs = 0; bp->tempOutputBuffer = 0; bp->tempOutputBufferPtrs = 0; bp->framesPerUserBuffer = framesPerUserBuffer; bp->framesPerHostBuffer = framesPerHostBuffer; bp->inputChannelCount = inputChannelCount; bp->outputChannelCount = outputChannelCount; bp->hostBufferSizeMode = hostBufferSizeMode; bp->hostInputChannels[0] = bp->hostInputChannels[1] = 0; bp->hostOutputChannels[0] = bp->hostOutputChannels[1] = 0; if( framesPerUserBuffer == 0 ) /* streamCallback will accept any buffer size */ { bp->useNonAdaptingProcess = 1; bp->initialFramesInTempInputBuffer = 0; bp->initialFramesInTempOutputBuffer = 0; if( hostBufferSizeMode == paUtilFixedHostBufferSize || hostBufferSizeMode == paUtilBoundedHostBufferSize ) { bp->framesPerTempBuffer = framesPerHostBuffer; } else /* unknown host buffer size */ { bp->framesPerTempBuffer = PA_FRAMES_PER_TEMP_BUFFER_WHEN_HOST_BUFFER_SIZE_IS_UNKNOWN_; } } else { bp->framesPerTempBuffer = framesPerUserBuffer; if( hostBufferSizeMode == paUtilFixedHostBufferSize && framesPerHostBuffer % framesPerUserBuffer == 0 ) { bp->useNonAdaptingProcess = 1; bp->initialFramesInTempInputBuffer = 0; bp->initialFramesInTempOutputBuffer = 0; } else { bp->useNonAdaptingProcess = 0; if( inputChannelCount > 0 && outputChannelCount > 0 ) { /* full duplex */ if( hostBufferSizeMode == paUtilFixedHostBufferSize ) { unsigned long frameShift = CalculateFrameShift( framesPerHostBuffer, framesPerUserBuffer ); if( framesPerUserBuffer > framesPerHostBuffer ) { bp->initialFramesInTempInputBuffer = frameShift; bp->initialFramesInTempOutputBuffer = 0; } else { bp->initialFramesInTempInputBuffer = 0; bp->initialFramesInTempOutputBuffer = frameShift; } } else /* variable host buffer size, add framesPerUserBuffer latency */ { bp->initialFramesInTempInputBuffer = 0; bp->initialFramesInTempOutputBuffer = framesPerUserBuffer; } } else { /* half duplex */ bp->initialFramesInTempInputBuffer = 0; bp->initialFramesInTempOutputBuffer = 0; } } } bp->framesInTempInputBuffer = bp->initialFramesInTempInputBuffer; bp->framesInTempOutputBuffer = bp->initialFramesInTempOutputBuffer; if( inputChannelCount > 0 ) { bytesPerSample = Pa_GetSampleSize( hostInputSampleFormat ); if( bytesPerSample > 0 ) { bp->bytesPerHostInputSample = bytesPerSample; } else { result = bytesPerSample; goto error; } bytesPerSample = Pa_GetSampleSize( userInputSampleFormat ); if( bytesPerSample > 0 ) { bp->bytesPerUserInputSample = bytesPerSample; } else { result = bytesPerSample; goto error; } bp->inputConverter = PaUtil_SelectConverter( hostInputSampleFormat, userInputSampleFormat, streamFlags ); bp->inputZeroer = PaUtil_SelectZeroer( hostInputSampleFormat ); bp->userInputIsInterleaved = (userInputSampleFormat & paNonInterleaved)?0:1; tempInputBufferSize = bp->framesPerTempBuffer * bp->bytesPerUserInputSample * inputChannelCount; bp->tempInputBuffer = PaUtil_AllocateMemory( tempInputBufferSize ); if( bp->tempInputBuffer == 0 ) { result = paInsufficientMemory; goto error; } if( bp->framesInTempInputBuffer > 0 ) memset( bp->tempInputBuffer, 0, tempInputBufferSize ); if( userInputSampleFormat & paNonInterleaved ) { bp->tempInputBufferPtrs = (void **)PaUtil_AllocateMemory( sizeof(void*)*inputChannelCount ); if( bp->tempInputBufferPtrs == 0 ) { result = paInsufficientMemory; goto error; } } bp->hostInputChannels[0] = (PaUtilChannelDescriptor*) PaUtil_AllocateMemory( sizeof(PaUtilChannelDescriptor) * inputChannelCount * 2); if( bp->hostInputChannels[0] == 0 ) { result = paInsufficientMemory; goto error; } bp->hostInputChannels[1] = &bp->hostInputChannels[0][inputChannelCount]; } if( outputChannelCount > 0 ) { bytesPerSample = Pa_GetSampleSize( hostOutputSampleFormat ); if( bytesPerSample > 0 ) { bp->bytesPerHostOutputSample = bytesPerSample; } else { result = bytesPerSample; goto error; } bytesPerSample = Pa_GetSampleSize( userOutputSampleFormat ); if( bytesPerSample > 0 ) { bp->bytesPerUserOutputSample = bytesPerSample; } else { result = bytesPerSample; goto error; } bp->outputConverter = PaUtil_SelectConverter( userOutputSampleFormat, hostOutputSampleFormat, streamFlags ); bp->outputZeroer = PaUtil_SelectZeroer( hostOutputSampleFormat ); bp->userOutputIsInterleaved = (userOutputSampleFormat & paNonInterleaved)?0:1; tempOutputBufferSize = bp->framesPerTempBuffer * bp->bytesPerUserOutputSample * outputChannelCount; bp->tempOutputBuffer = PaUtil_AllocateMemory( tempOutputBufferSize ); if( bp->tempOutputBuffer == 0 ) { result = paInsufficientMemory; goto error; } if( bp->framesInTempOutputBuffer > 0 ) memset( bp->tempOutputBuffer, 0, tempOutputBufferSize ); if( userOutputSampleFormat & paNonInterleaved ) { bp->tempOutputBufferPtrs = (void **)PaUtil_AllocateMemory( sizeof(void*)*outputChannelCount ); if( bp->tempOutputBufferPtrs == 0 ) { result = paInsufficientMemory; goto error; } } bp->hostOutputChannels[0] = (PaUtilChannelDescriptor*) PaUtil_AllocateMemory( sizeof(PaUtilChannelDescriptor)*outputChannelCount * 2 ); if( bp->hostOutputChannels[0] == 0 ) { result = paInsufficientMemory; goto error; } bp->hostOutputChannels[1] = &bp->hostOutputChannels[0][outputChannelCount]; } PaUtil_InitializeTriangularDitherState( &bp->ditherGenerator ); bp->samplePeriod = 1. / sampleRate; bp->streamCallback = streamCallback; bp->userData = userData; return result; error: if( bp->tempInputBuffer ) PaUtil_FreeMemory( bp->tempInputBuffer ); if( bp->tempInputBufferPtrs ) PaUtil_FreeMemory( bp->tempInputBufferPtrs ); if( bp->hostInputChannels[0] ) PaUtil_FreeMemory( bp->hostInputChannels[0] ); if( bp->tempOutputBuffer ) PaUtil_FreeMemory( bp->tempOutputBuffer ); if( bp->tempOutputBufferPtrs ) PaUtil_FreeMemory( bp->tempOutputBufferPtrs ); if( bp->hostOutputChannels[0] ) PaUtil_FreeMemory( bp->hostOutputChannels[0] ); return result; } void PaUtil_TerminateBufferProcessor( PaUtilBufferProcessor* bp ) { if( bp->tempInputBuffer ) PaUtil_FreeMemory( bp->tempInputBuffer ); if( bp->tempInputBufferPtrs ) PaUtil_FreeMemory( bp->tempInputBufferPtrs ); if( bp->hostInputChannels[0] ) PaUtil_FreeMemory( bp->hostInputChannels[0] ); if( bp->tempOutputBuffer ) PaUtil_FreeMemory( bp->tempOutputBuffer ); if( bp->tempOutputBufferPtrs ) PaUtil_FreeMemory( bp->tempOutputBufferPtrs ); if( bp->hostOutputChannels[0] ) PaUtil_FreeMemory( bp->hostOutputChannels[0] ); } void PaUtil_ResetBufferProcessor( PaUtilBufferProcessor* bp ) { unsigned long tempInputBufferSize, tempOutputBufferSize; bp->framesInTempInputBuffer = bp->initialFramesInTempInputBuffer; bp->framesInTempOutputBuffer = bp->initialFramesInTempOutputBuffer; if( bp->framesInTempInputBuffer > 0 ) { tempInputBufferSize = bp->framesPerTempBuffer * bp->bytesPerUserInputSample * bp->inputChannelCount; memset( bp->tempInputBuffer, 0, tempInputBufferSize ); } if( bp->framesInTempOutputBuffer > 0 ) { tempOutputBufferSize = bp->framesPerTempBuffer * bp->bytesPerUserOutputSample * bp->outputChannelCount; memset( bp->tempOutputBuffer, 0, tempOutputBufferSize ); } } unsigned long PaUtil_GetBufferProcessorInputLatency( PaUtilBufferProcessor* bp ) { return bp->initialFramesInTempInputBuffer; } unsigned long PaUtil_GetBufferProcessorOutputLatency( PaUtilBufferProcessor* bp ) { return bp->initialFramesInTempOutputBuffer; } void PaUtil_SetInputFrameCount( PaUtilBufferProcessor* bp, unsigned long frameCount ) { if( frameCount == 0 ) bp->hostInputFrameCount[0] = bp->framesPerHostBuffer; else bp->hostInputFrameCount[0] = frameCount; } void PaUtil_SetNoInput( PaUtilBufferProcessor* bp ) { assert( bp->inputChannelCount > 0 ); bp->hostInputChannels[0][0].data = 0; } void PaUtil_SetInputChannel( PaUtilBufferProcessor* bp, unsigned int channel, void *data, unsigned int stride ) { assert( channel < bp->inputChannelCount ); bp->hostInputChannels[0][channel].data = data; bp->hostInputChannels[0][channel].stride = stride; } void PaUtil_SetInterleavedInputChannels( PaUtilBufferProcessor* bp, unsigned int firstChannel, void *data, unsigned int channelCount ) { unsigned int i; unsigned int channel = firstChannel; unsigned char *p = (unsigned char*)data; if( channelCount == 0 ) channelCount = bp->inputChannelCount; assert( firstChannel < bp->inputChannelCount ); assert( firstChannel + channelCount <= bp->inputChannelCount ); for( i=0; i< channelCount; ++i ) { bp->hostInputChannels[0][channel+i].data = p; p += bp->bytesPerHostInputSample; bp->hostInputChannels[0][channel+i].stride = channelCount; } } void PaUtil_SetNonInterleavedInputChannel( PaUtilBufferProcessor* bp, unsigned int channel, void *data ) { assert( channel < bp->inputChannelCount ); bp->hostInputChannels[0][channel].data = data; bp->hostInputChannels[0][channel].stride = 1; } void PaUtil_Set2ndInputFrameCount( PaUtilBufferProcessor* bp, unsigned long frameCount ) { bp->hostInputFrameCount[1] = frameCount; } void PaUtil_Set2ndInputChannel( PaUtilBufferProcessor* bp, unsigned int channel, void *data, unsigned int stride ) { assert( channel < bp->inputChannelCount ); bp->hostInputChannels[1][channel].data = data; bp->hostInputChannels[1][channel].stride = stride; } void PaUtil_Set2ndInterleavedInputChannels( PaUtilBufferProcessor* bp, unsigned int firstChannel, void *data, unsigned int channelCount ) { unsigned int i; unsigned int channel = firstChannel; unsigned char *p = (unsigned char*)data; if( channelCount == 0 ) channelCount = bp->inputChannelCount; assert( firstChannel < bp->inputChannelCount ); assert( firstChannel + channelCount <= bp->inputChannelCount ); for( i=0; i< channelCount; ++i ) { bp->hostInputChannels[1][channel+i].data = p; p += bp->bytesPerHostInputSample; bp->hostInputChannels[1][channel+i].stride = channelCount; } } void PaUtil_Set2ndNonInterleavedInputChannel( PaUtilBufferProcessor* bp, unsigned int channel, void *data ) { assert( channel < bp->inputChannelCount ); bp->hostInputChannels[1][channel].data = data; bp->hostInputChannels[1][channel].stride = 1; } void PaUtil_SetOutputFrameCount( PaUtilBufferProcessor* bp, unsigned long frameCount ) { if( frameCount == 0 ) bp->hostOutputFrameCount[0] = bp->framesPerHostBuffer; else bp->hostOutputFrameCount[0] = frameCount; } void PaUtil_SetNoOutput( PaUtilBufferProcessor* bp ) { assert( bp->outputChannelCount > 0 ); bp->hostOutputChannels[0][0].data = 0; } void PaUtil_SetOutputChannel( PaUtilBufferProcessor* bp, unsigned int channel, void *data, unsigned int stride ) { assert( channel < bp->outputChannelCount ); assert( data != NULL ); bp->hostOutputChannels[0][channel].data = data; bp->hostOutputChannels[0][channel].stride = stride; } void PaUtil_SetInterleavedOutputChannels( PaUtilBufferProcessor* bp, unsigned int firstChannel, void *data, unsigned int channelCount ) { unsigned int i; unsigned int channel = firstChannel; unsigned char *p = (unsigned char*)data; if( channelCount == 0 ) channelCount = bp->outputChannelCount; assert( firstChannel < bp->outputChannelCount ); assert( firstChannel + channelCount <= bp->outputChannelCount ); for( i=0; i< channelCount; ++i ) { PaUtil_SetOutputChannel( bp, channel + i, p, channelCount ); p += bp->bytesPerHostOutputSample; } } void PaUtil_SetNonInterleavedOutputChannel( PaUtilBufferProcessor* bp, unsigned int channel, void *data ) { assert( channel < bp->outputChannelCount ); PaUtil_SetOutputChannel( bp, channel, data, 1 ); } void PaUtil_Set2ndOutputFrameCount( PaUtilBufferProcessor* bp, unsigned long frameCount ) { bp->hostOutputFrameCount[1] = frameCount; } void PaUtil_Set2ndOutputChannel( PaUtilBufferProcessor* bp, unsigned int channel, void *data, unsigned int stride ) { assert( channel < bp->outputChannelCount ); assert( data != NULL ); bp->hostOutputChannels[1][channel].data = data; bp->hostOutputChannels[1][channel].stride = stride; } void PaUtil_Set2ndInterleavedOutputChannels( PaUtilBufferProcessor* bp, unsigned int firstChannel, void *data, unsigned int channelCount ) { unsigned int i; unsigned int channel = firstChannel; unsigned char *p = (unsigned char*)data; if( channelCount == 0 ) channelCount = bp->outputChannelCount; assert( firstChannel < bp->outputChannelCount ); assert( firstChannel + channelCount <= bp->outputChannelCount ); for( i=0; i< channelCount; ++i ) { PaUtil_Set2ndOutputChannel( bp, channel + i, p, channelCount ); p += bp->bytesPerHostOutputSample; } } void PaUtil_Set2ndNonInterleavedOutputChannel( PaUtilBufferProcessor* bp, unsigned int channel, void *data ) { assert( channel < bp->outputChannelCount ); PaUtil_Set2ndOutputChannel( bp, channel, data, 1 ); } void PaUtil_BeginBufferProcessing( PaUtilBufferProcessor* bp, PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags callbackStatusFlags ) { bp->timeInfo = timeInfo; /* the first streamCallback will be called to process samples which are currently in the input buffer before the ones starting at the timeInfo time */ bp->timeInfo->inputBufferAdcTime -= bp->framesInTempInputBuffer * bp->samplePeriod; bp->timeInfo->currentTime = 0; /** FIXME: @todo time info currentTime not implemented */ /* the first streamCallback will be called to generate samples which will be outputted after the frames currently in the output buffer have been outputted. */ bp->timeInfo->outputBufferDacTime += bp->framesInTempOutputBuffer * bp->samplePeriod; bp->callbackStatusFlags = callbackStatusFlags; bp->hostInputFrameCount[1] = 0; bp->hostOutputFrameCount[1] = 0; } /* NonAdaptingProcess() is a simple buffer copying adaptor that can handle both full and half duplex copies. It processes framesToProcess frames, broken into blocks bp->framesPerTempBuffer long. This routine can be used when the streamCallback doesn't care what length the buffers are, or when framesToProcess is an integer multiple of bp->framesPerTempBuffer, in which case streamCallback will always be called with bp->framesPerTempBuffer samples. */ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp, int *streamCallbackResult, PaUtilChannelDescriptor *hostInputChannels, PaUtilChannelDescriptor *hostOutputChannels, unsigned long framesToProcess ) { void *userInput, *userOutput; unsigned char *srcBytePtr, *destBytePtr; unsigned int srcSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */ unsigned int srcChannelStrideBytes; /* stride from one channel to the next, in bytes */ unsigned int destSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */ unsigned int destChannelStrideBytes; /* stride from one channel to the next, in bytes */ unsigned int i; unsigned long frameCount; unsigned long framesToGo = framesToProcess; unsigned long framesProcessed = 0; if( *streamCallbackResult == paContinue ) { do { frameCount = PA_MIN_( bp->framesPerTempBuffer, framesToGo ); /* configure user input buffer and convert input data (host -> user) */ if( bp->inputChannelCount == 0 ) { /* no input */ userInput = 0; } else /* there are input channels */ { /* could use more elaborate logic here and sometimes process buffers in-place. */ destBytePtr = (unsigned char *)bp->tempInputBuffer; if( bp->userInputIsInterleaved ) { destSampleStrideSamples = bp->inputChannelCount; destChannelStrideBytes = bp->bytesPerUserInputSample; userInput = bp->tempInputBuffer; } else /* user input is not interleaved */ { destSampleStrideSamples = 1; destChannelStrideBytes = frameCount * bp->bytesPerUserInputSample; /* setup non-interleaved ptrs */ for( i=0; iinputChannelCount; ++i ) { bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) + i * bp->bytesPerUserInputSample * frameCount; } userInput = bp->tempInputBufferPtrs; } if( !bp->hostInputChannels[0][0].data ) { /* no input was supplied (see PaUtil_SetNoInput), so zero the input buffer */ for( i=0; iinputChannelCount; ++i ) { bp->inputZeroer( destBytePtr, destSampleStrideSamples, frameCount ); destBytePtr += destChannelStrideBytes; /* skip to next destination channel */ } } else { for( i=0; iinputChannelCount; ++i ) { bp->inputConverter( destBytePtr, destSampleStrideSamples, hostInputChannels[i].data, hostInputChannels[i].stride, frameCount, &bp->ditherGenerator ); destBytePtr += destChannelStrideBytes; /* skip to next destination channel */ /* advance src ptr for next iteration */ hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) + frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample; } } } /* configure user output buffer */ if( bp->outputChannelCount == 0 ) { /* no output */ userOutput = 0; } else /* there are output channels */ { if( bp->userOutputIsInterleaved ) { userOutput = bp->tempOutputBuffer; } else /* user output is not interleaved */ { for( i = 0; i < bp->outputChannelCount; ++i ) { bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) + i * bp->bytesPerUserOutputSample * frameCount; } userOutput = bp->tempOutputBufferPtrs; } } *streamCallbackResult = bp->streamCallback( userInput, userOutput, frameCount, bp->timeInfo, bp->callbackStatusFlags, bp->userData ); if( *streamCallbackResult == paAbort ) { /* callback returned paAbort, don't advance framesProcessed and framesToGo, they will be handled below */ } else { bp->timeInfo->inputBufferAdcTime += frameCount * bp->samplePeriod; bp->timeInfo->outputBufferDacTime += frameCount * bp->samplePeriod; /* convert output data (user -> host) */ if( bp->outputChannelCount != 0 && bp->hostOutputChannels[0][0].data ) { /* could use more elaborate logic here and sometimes process buffers in-place. */ srcBytePtr = (unsigned char *)bp->tempOutputBuffer; if( bp->userOutputIsInterleaved ) { srcSampleStrideSamples = bp->outputChannelCount; srcChannelStrideBytes = bp->bytesPerUserOutputSample; } else /* user output is not interleaved */ { srcSampleStrideSamples = 1; srcChannelStrideBytes = frameCount * bp->bytesPerUserOutputSample; } for( i=0; ioutputChannelCount; ++i ) { bp->outputConverter( hostOutputChannels[i].data, hostOutputChannels[i].stride, srcBytePtr, srcSampleStrideSamples, frameCount, &bp->ditherGenerator ); srcBytePtr += srcChannelStrideBytes; /* skip to next source channel */ /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } } framesProcessed += frameCount; framesToGo -= frameCount; } } while( framesToGo > 0 && *streamCallbackResult == paContinue ); } if( framesToGo > 0 ) { /* zero any remaining frames output. There will only be remaining frames if the callback has returned paComplete or paAbort */ frameCount = framesToGo; if( bp->outputChannelCount != 0 && bp->hostOutputChannels[0][0].data ) { for( i=0; ioutputChannelCount; ++i ) { bp->outputZeroer( hostOutputChannels[i].data, hostOutputChannels[i].stride, frameCount ); /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } } framesProcessed += frameCount; } return framesProcessed; } /* AdaptingInputOnlyProcess() is a half duplex input buffer processor. It converts data from the input buffers into the temporary input buffer, when the temporary input buffer is full, it calls the streamCallback. */ static unsigned long AdaptingInputOnlyProcess( PaUtilBufferProcessor *bp, int *streamCallbackResult, PaUtilChannelDescriptor *hostInputChannels, unsigned long framesToProcess ) { void *userInput, *userOutput; unsigned char *destBytePtr; unsigned int destSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */ unsigned int destChannelStrideBytes; /* stride from one channel to the next, in bytes */ unsigned int i; unsigned long frameCount; unsigned long framesToGo = framesToProcess; unsigned long framesProcessed = 0; userOutput = 0; do { frameCount = ( bp->framesInTempInputBuffer + framesToGo > bp->framesPerUserBuffer ) ? ( bp->framesPerUserBuffer - bp->framesInTempInputBuffer ) : framesToGo; /* convert frameCount samples into temp buffer */ if( bp->userInputIsInterleaved ) { destBytePtr = ((unsigned char*)bp->tempInputBuffer) + bp->bytesPerUserInputSample * bp->inputChannelCount * bp->framesInTempInputBuffer; destSampleStrideSamples = bp->inputChannelCount; destChannelStrideBytes = bp->bytesPerUserInputSample; userInput = bp->tempInputBuffer; } else /* user input is not interleaved */ { destBytePtr = ((unsigned char*)bp->tempInputBuffer) + bp->bytesPerUserInputSample * bp->framesInTempInputBuffer; destSampleStrideSamples = 1; destChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserInputSample; /* setup non-interleaved ptrs */ for( i=0; iinputChannelCount; ++i ) { bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) + i * bp->bytesPerUserInputSample * bp->framesPerUserBuffer; } userInput = bp->tempInputBufferPtrs; } for( i=0; iinputChannelCount; ++i ) { bp->inputConverter( destBytePtr, destSampleStrideSamples, hostInputChannels[i].data, hostInputChannels[i].stride, frameCount, &bp->ditherGenerator ); destBytePtr += destChannelStrideBytes; /* skip to next destination channel */ /* advance src ptr for next iteration */ hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) + frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample; } bp->framesInTempInputBuffer += frameCount; if( bp->framesInTempInputBuffer == bp->framesPerUserBuffer ) { /** @todo (non-critical optimisation) The conditional below implements the continue/complete/abort mechanism simply by continuing on iterating through the input buffer, but not passing the data to the callback. With care, the outer loop could be terminated earlier, thus some unneeded conversion cycles would be saved. */ if( *streamCallbackResult == paContinue ) { bp->timeInfo->outputBufferDacTime = 0; *streamCallbackResult = bp->streamCallback( userInput, userOutput, bp->framesPerUserBuffer, bp->timeInfo, bp->callbackStatusFlags, bp->userData ); bp->timeInfo->inputBufferAdcTime += frameCount * bp->samplePeriod; } bp->framesInTempInputBuffer = 0; } framesProcessed += frameCount; framesToGo -= frameCount; }while( framesToGo > 0 ); return framesProcessed; } /* AdaptingOutputOnlyProcess() is a half duplex output buffer processor. It converts data from the temporary output buffer, to the output buffers, when the temporary output buffer is empty, it calls the streamCallback. */ static unsigned long AdaptingOutputOnlyProcess( PaUtilBufferProcessor *bp, int *streamCallbackResult, PaUtilChannelDescriptor *hostOutputChannels, unsigned long framesToProcess ) { void *userInput, *userOutput; unsigned char *srcBytePtr; unsigned int srcSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */ unsigned int srcChannelStrideBytes; /* stride from one channel to the next, in bytes */ unsigned int i; unsigned long frameCount; unsigned long framesToGo = framesToProcess; unsigned long framesProcessed = 0; do { if( bp->framesInTempOutputBuffer == 0 && *streamCallbackResult == paContinue ) { userInput = 0; /* setup userOutput */ if( bp->userOutputIsInterleaved ) { userOutput = bp->tempOutputBuffer; } else /* user output is not interleaved */ { for( i = 0; i < bp->outputChannelCount; ++i ) { bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) + i * bp->framesPerUserBuffer * bp->bytesPerUserOutputSample; } userOutput = bp->tempOutputBufferPtrs; } bp->timeInfo->inputBufferAdcTime = 0; *streamCallbackResult = bp->streamCallback( userInput, userOutput, bp->framesPerUserBuffer, bp->timeInfo, bp->callbackStatusFlags, bp->userData ); if( *streamCallbackResult == paAbort ) { /* if the callback returned paAbort, we disregard its output */ } else { bp->timeInfo->outputBufferDacTime += bp->framesPerUserBuffer * bp->samplePeriod; bp->framesInTempOutputBuffer = bp->framesPerUserBuffer; } } if( bp->framesInTempOutputBuffer > 0 ) { /* convert frameCount frames from user buffer to host buffer */ frameCount = PA_MIN_( bp->framesInTempOutputBuffer, framesToGo ); if( bp->userOutputIsInterleaved ) { srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) + bp->bytesPerUserOutputSample * bp->outputChannelCount * (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer); srcSampleStrideSamples = bp->outputChannelCount; srcChannelStrideBytes = bp->bytesPerUserOutputSample; } else /* user output is not interleaved */ { srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) + bp->bytesPerUserOutputSample * (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer); srcSampleStrideSamples = 1; srcChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserOutputSample; } for( i=0; ioutputChannelCount; ++i ) { bp->outputConverter( hostOutputChannels[i].data, hostOutputChannels[i].stride, srcBytePtr, srcSampleStrideSamples, frameCount, &bp->ditherGenerator ); srcBytePtr += srcChannelStrideBytes; /* skip to next source channel */ /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } bp->framesInTempOutputBuffer -= frameCount; } else { /* no more user data is available because the callback has returned paComplete or paAbort. Fill the remainder of the host buffer with zeros. */ frameCount = framesToGo; for( i=0; ioutputChannelCount; ++i ) { bp->outputZeroer( hostOutputChannels[i].data, hostOutputChannels[i].stride, frameCount ); /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } } framesProcessed += frameCount; framesToGo -= frameCount; }while( framesToGo > 0 ); return framesProcessed; } /* CopyTempOutputBuffersToHostOutputBuffers is called from AdaptingProcess to copy frames from tempOutputBuffer to hostOutputChannels. This includes data conversion and interleaving. */ static void CopyTempOutputBuffersToHostOutputBuffers( PaUtilBufferProcessor *bp) { unsigned long maxFramesToCopy; PaUtilChannelDescriptor *hostOutputChannels; unsigned int frameCount; unsigned char *srcBytePtr; unsigned int srcSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */ unsigned int srcChannelStrideBytes; /* stride from one channel to the next, in bytes */ unsigned int i; /* copy frames from user to host output buffers */ while( bp->framesInTempOutputBuffer > 0 && ((bp->hostOutputFrameCount[0] + bp->hostOutputFrameCount[1]) > 0) ) { maxFramesToCopy = bp->framesInTempOutputBuffer; /* select the output buffer set (1st or 2nd) */ if( bp->hostOutputFrameCount[0] > 0 ) { hostOutputChannels = bp->hostOutputChannels[0]; frameCount = PA_MIN_( bp->hostOutputFrameCount[0], maxFramesToCopy ); } else { hostOutputChannels = bp->hostOutputChannels[1]; frameCount = PA_MIN_( bp->hostOutputFrameCount[1], maxFramesToCopy ); } if( bp->userOutputIsInterleaved ) { srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) + bp->bytesPerUserOutputSample * bp->outputChannelCount * (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer); srcSampleStrideSamples = bp->outputChannelCount; srcChannelStrideBytes = bp->bytesPerUserOutputSample; } else /* user output is not interleaved */ { srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) + bp->bytesPerUserOutputSample * (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer); srcSampleStrideSamples = 1; srcChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserOutputSample; } for( i=0; ioutputChannelCount; ++i ) { assert( hostOutputChannels[i].data != NULL ); bp->outputConverter( hostOutputChannels[i].data, hostOutputChannels[i].stride, srcBytePtr, srcSampleStrideSamples, frameCount, &bp->ditherGenerator ); srcBytePtr += srcChannelStrideBytes; /* skip to next source channel */ /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } if( bp->hostOutputFrameCount[0] > 0 ) bp->hostOutputFrameCount[0] -= frameCount; else bp->hostOutputFrameCount[1] -= frameCount; bp->framesInTempOutputBuffer -= frameCount; } } /* AdaptingProcess is a full duplex adapting buffer processor. It converts data from the temporary output buffer into the host output buffers, then from the host input buffers into the temporary input buffers. Calling the streamCallback when necessary. When processPartialUserBuffers is 0, all available input data will be consumed and all available output space will be filled. When processPartialUserBuffers is non-zero, as many full user buffers as possible will be processed, but partial buffers will not be consumed. */ static unsigned long AdaptingProcess( PaUtilBufferProcessor *bp, int *streamCallbackResult, int processPartialUserBuffers ) { void *userInput, *userOutput; unsigned long framesProcessed = 0; unsigned long framesAvailable; unsigned long endProcessingMinFrameCount; unsigned long maxFramesToCopy; PaUtilChannelDescriptor *hostInputChannels, *hostOutputChannels; unsigned int frameCount; unsigned char *destBytePtr; unsigned int destSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */ unsigned int destChannelStrideBytes; /* stride from one channel to the next, in bytes */ unsigned int i, j; framesAvailable = bp->hostInputFrameCount[0] + bp->hostInputFrameCount[1];/* this is assumed to be the same as the output buffer's frame count */ if( processPartialUserBuffers ) endProcessingMinFrameCount = 0; else endProcessingMinFrameCount = (bp->framesPerUserBuffer - 1); /* Fill host output with remaining frames in user output (tempOutputBuffer) */ CopyTempOutputBuffersToHostOutputBuffers( bp ); while( framesAvailable > endProcessingMinFrameCount ) { if( bp->framesInTempOutputBuffer == 0 && *streamCallbackResult != paContinue ) { /* the callback will not be called any more, so zero what remains of the host output buffers */ for( i=0; i<2; ++i ) { frameCount = bp->hostOutputFrameCount[i]; if( frameCount > 0 ) { hostOutputChannels = bp->hostOutputChannels[i]; for( j=0; joutputChannelCount; ++j ) { bp->outputZeroer( hostOutputChannels[j].data, hostOutputChannels[j].stride, frameCount ); /* advance dest ptr for next iteration */ hostOutputChannels[j].data = ((unsigned char*)hostOutputChannels[j].data) + frameCount * hostOutputChannels[j].stride * bp->bytesPerHostOutputSample; } bp->hostOutputFrameCount[i] = 0; } } } /* copy frames from host to user input buffers */ while( bp->framesInTempInputBuffer < bp->framesPerUserBuffer && ((bp->hostInputFrameCount[0] + bp->hostInputFrameCount[1]) > 0) ) { maxFramesToCopy = bp->framesPerUserBuffer - bp->framesInTempInputBuffer; /* select the input buffer set (1st or 2nd) */ if( bp->hostInputFrameCount[0] > 0 ) { hostInputChannels = bp->hostInputChannels[0]; frameCount = PA_MIN_( bp->hostInputFrameCount[0], maxFramesToCopy ); } else { hostInputChannels = bp->hostInputChannels[1]; frameCount = PA_MIN_( bp->hostInputFrameCount[1], maxFramesToCopy ); } /* configure conversion destination pointers */ if( bp->userInputIsInterleaved ) { destBytePtr = ((unsigned char*)bp->tempInputBuffer) + bp->bytesPerUserInputSample * bp->inputChannelCount * bp->framesInTempInputBuffer; destSampleStrideSamples = bp->inputChannelCount; destChannelStrideBytes = bp->bytesPerUserInputSample; } else /* user input is not interleaved */ { destBytePtr = ((unsigned char*)bp->tempInputBuffer) + bp->bytesPerUserInputSample * bp->framesInTempInputBuffer; destSampleStrideSamples = 1; destChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserInputSample; } for( i=0; iinputChannelCount; ++i ) { bp->inputConverter( destBytePtr, destSampleStrideSamples, hostInputChannels[i].data, hostInputChannels[i].stride, frameCount, &bp->ditherGenerator ); destBytePtr += destChannelStrideBytes; /* skip to next destination channel */ /* advance src ptr for next iteration */ hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) + frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample; } if( bp->hostInputFrameCount[0] > 0 ) bp->hostInputFrameCount[0] -= frameCount; else bp->hostInputFrameCount[1] -= frameCount; bp->framesInTempInputBuffer += frameCount; /* update framesAvailable and framesProcessed based on input consumed unless something is very wrong this will also correspond to the amount of output generated */ framesAvailable -= frameCount; framesProcessed += frameCount; } /* call streamCallback */ if( bp->framesInTempInputBuffer == bp->framesPerUserBuffer && bp->framesInTempOutputBuffer == 0 ) { if( *streamCallbackResult == paContinue ) { /* setup userInput */ if( bp->userInputIsInterleaved ) { userInput = bp->tempInputBuffer; } else /* user input is not interleaved */ { for( i = 0; i < bp->inputChannelCount; ++i ) { bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) + i * bp->framesPerUserBuffer * bp->bytesPerUserInputSample; } userInput = bp->tempInputBufferPtrs; } /* setup userOutput */ if( bp->userOutputIsInterleaved ) { userOutput = bp->tempOutputBuffer; } else /* user output is not interleaved */ { for( i = 0; i < bp->outputChannelCount; ++i ) { bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) + i * bp->framesPerUserBuffer * bp->bytesPerUserOutputSample; } userOutput = bp->tempOutputBufferPtrs; } /* call streamCallback */ *streamCallbackResult = bp->streamCallback( userInput, userOutput, bp->framesPerUserBuffer, bp->timeInfo, bp->callbackStatusFlags, bp->userData ); bp->timeInfo->inputBufferAdcTime += bp->framesPerUserBuffer * bp->samplePeriod; bp->timeInfo->outputBufferDacTime += bp->framesPerUserBuffer * bp->samplePeriod; bp->framesInTempInputBuffer = 0; if( *streamCallbackResult == paAbort ) bp->framesInTempOutputBuffer = 0; else bp->framesInTempOutputBuffer = bp->framesPerUserBuffer; } else { /* paComplete or paAbort has already been called. */ bp->framesInTempInputBuffer = 0; } } /* copy frames from user (tempOutputBuffer) to host output buffers (hostOutputChannels) Means to process the user output provided by the callback. Has to be called after each callback. */ CopyTempOutputBuffersToHostOutputBuffers( bp ); } return framesProcessed; } unsigned long PaUtil_EndBufferProcessing( PaUtilBufferProcessor* bp, int *streamCallbackResult ) { unsigned long framesToProcess, framesToGo; unsigned long framesProcessed = 0; if( bp->inputChannelCount != 0 && bp->outputChannelCount != 0 && bp->hostInputChannels[0][0].data /* input was supplied (see PaUtil_SetNoInput) */ && bp->hostOutputChannels[0][0].data /* output was supplied (see PaUtil_SetNoOutput) */ ) { assert( (bp->hostInputFrameCount[0] + bp->hostInputFrameCount[1]) == (bp->hostOutputFrameCount[0] + bp->hostOutputFrameCount[1]) ); } assert( *streamCallbackResult == paContinue || *streamCallbackResult == paComplete || *streamCallbackResult == paAbort ); /* don't forget to pass in a valid callback result value */ if( bp->useNonAdaptingProcess ) { if( bp->inputChannelCount != 0 && bp->outputChannelCount != 0 ) { /* full duplex non-adapting process, splice buffers if they are different lengths */ framesToGo = bp->hostOutputFrameCount[0] + bp->hostOutputFrameCount[1]; /* relies on assert above for input/output equivalence */ do{ unsigned long noInputInputFrameCount; unsigned long *hostInputFrameCount; PaUtilChannelDescriptor *hostInputChannels; unsigned long noOutputOutputFrameCount; unsigned long *hostOutputFrameCount; PaUtilChannelDescriptor *hostOutputChannels; unsigned long framesProcessedThisIteration; if( !bp->hostInputChannels[0][0].data ) { /* no input was supplied (see PaUtil_SetNoInput) NonAdaptingProcess knows how to deal with this */ noInputInputFrameCount = framesToGo; hostInputFrameCount = &noInputInputFrameCount; hostInputChannels = 0; } else if( bp->hostInputFrameCount[0] != 0 ) { hostInputFrameCount = &bp->hostInputFrameCount[0]; hostInputChannels = bp->hostInputChannels[0]; } else { hostInputFrameCount = &bp->hostInputFrameCount[1]; hostInputChannels = bp->hostInputChannels[1]; } if( !bp->hostOutputChannels[0][0].data ) { /* no output was supplied (see PaUtil_SetNoOutput) NonAdaptingProcess knows how to deal with this */ noOutputOutputFrameCount = framesToGo; hostOutputFrameCount = &noOutputOutputFrameCount; hostOutputChannels = 0; } if( bp->hostOutputFrameCount[0] != 0 ) { hostOutputFrameCount = &bp->hostOutputFrameCount[0]; hostOutputChannels = bp->hostOutputChannels[0]; } else { hostOutputFrameCount = &bp->hostOutputFrameCount[1]; hostOutputChannels = bp->hostOutputChannels[1]; } framesToProcess = PA_MIN_( *hostInputFrameCount, *hostOutputFrameCount ); assert( framesToProcess != 0 ); framesProcessedThisIteration = NonAdaptingProcess( bp, streamCallbackResult, hostInputChannels, hostOutputChannels, framesToProcess ); *hostInputFrameCount -= framesProcessedThisIteration; *hostOutputFrameCount -= framesProcessedThisIteration; framesProcessed += framesProcessedThisIteration; framesToGo -= framesProcessedThisIteration; }while( framesToGo > 0 ); } else { /* half duplex non-adapting process, just process 1st and 2nd buffer */ /* process first buffer */ framesToProcess = (bp->inputChannelCount != 0) ? bp->hostInputFrameCount[0] : bp->hostOutputFrameCount[0]; framesProcessed = NonAdaptingProcess( bp, streamCallbackResult, bp->hostInputChannels[0], bp->hostOutputChannels[0], framesToProcess ); /* process second buffer if provided */ framesToProcess = (bp->inputChannelCount != 0) ? bp->hostInputFrameCount[1] : bp->hostOutputFrameCount[1]; if( framesToProcess > 0 ) { framesProcessed += NonAdaptingProcess( bp, streamCallbackResult, bp->hostInputChannels[1], bp->hostOutputChannels[1], framesToProcess ); } } } else /* block adaption necessary*/ { if( bp->inputChannelCount != 0 && bp->outputChannelCount != 0 ) { /* full duplex */ if( bp->hostBufferSizeMode == paUtilVariableHostBufferSizePartialUsageAllowed ) { framesProcessed = AdaptingProcess( bp, streamCallbackResult, 0 /* dont process partial user buffers */ ); } else { framesProcessed = AdaptingProcess( bp, streamCallbackResult, 1 /* process partial user buffers */ ); } } else if( bp->inputChannelCount != 0 ) { /* input only */ framesToProcess = bp->hostInputFrameCount[0]; framesProcessed = AdaptingInputOnlyProcess( bp, streamCallbackResult, bp->hostInputChannels[0], framesToProcess ); framesToProcess = bp->hostInputFrameCount[1]; if( framesToProcess > 0 ) { framesProcessed += AdaptingInputOnlyProcess( bp, streamCallbackResult, bp->hostInputChannels[1], framesToProcess ); } } else { /* output only */ framesToProcess = bp->hostOutputFrameCount[0]; framesProcessed = AdaptingOutputOnlyProcess( bp, streamCallbackResult, bp->hostOutputChannels[0], framesToProcess ); framesToProcess = bp->hostOutputFrameCount[1]; if( framesToProcess > 0 ) { framesProcessed += AdaptingOutputOnlyProcess( bp, streamCallbackResult, bp->hostOutputChannels[1], framesToProcess ); } } } return framesProcessed; } int PaUtil_IsBufferProcessorOutputEmpty( PaUtilBufferProcessor* bp ) { return (bp->framesInTempOutputBuffer) ? 0 : 1; } unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bp, void **buffer, unsigned long frameCount ) { PaUtilChannelDescriptor *hostInputChannels; unsigned int framesToCopy; unsigned char *destBytePtr; void **nonInterleavedDestPtrs; unsigned int destSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */ unsigned int destChannelStrideBytes; /* stride from one channel to the next, in bytes */ unsigned int i; hostInputChannels = bp->hostInputChannels[0]; framesToCopy = PA_MIN_( bp->hostInputFrameCount[0], frameCount ); if( bp->userInputIsInterleaved ) { destBytePtr = (unsigned char*)*buffer; destSampleStrideSamples = bp->inputChannelCount; destChannelStrideBytes = bp->bytesPerUserInputSample; for( i=0; iinputChannelCount; ++i ) { bp->inputConverter( destBytePtr, destSampleStrideSamples, hostInputChannels[i].data, hostInputChannels[i].stride, framesToCopy, &bp->ditherGenerator ); destBytePtr += destChannelStrideBytes; /* skip to next source channel */ /* advance dest ptr for next iteration */ hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) + framesToCopy * hostInputChannels[i].stride * bp->bytesPerHostInputSample; } /* advance callers dest pointer (buffer) */ *buffer = ((unsigned char *)*buffer) + framesToCopy * bp->inputChannelCount * bp->bytesPerUserInputSample; } else { /* user input is not interleaved */ nonInterleavedDestPtrs = (void**)*buffer; destSampleStrideSamples = 1; for( i=0; iinputChannelCount; ++i ) { destBytePtr = (unsigned char*)nonInterleavedDestPtrs[i]; bp->inputConverter( destBytePtr, destSampleStrideSamples, hostInputChannels[i].data, hostInputChannels[i].stride, framesToCopy, &bp->ditherGenerator ); /* advance callers dest pointer (nonInterleavedDestPtrs[i]) */ destBytePtr += bp->bytesPerUserInputSample * framesToCopy; nonInterleavedDestPtrs[i] = destBytePtr; /* advance dest ptr for next iteration */ hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) + framesToCopy * hostInputChannels[i].stride * bp->bytesPerHostInputSample; } } bp->hostInputFrameCount[0] -= framesToCopy; return framesToCopy; } unsigned long PaUtil_CopyOutput( PaUtilBufferProcessor* bp, const void ** buffer, unsigned long frameCount ) { PaUtilChannelDescriptor *hostOutputChannels; unsigned int framesToCopy; unsigned char *srcBytePtr; void **nonInterleavedSrcPtrs; unsigned int srcSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */ unsigned int srcChannelStrideBytes; /* stride from one channel to the next, in bytes */ unsigned int i; hostOutputChannels = bp->hostOutputChannels[0]; framesToCopy = PA_MIN_( bp->hostOutputFrameCount[0], frameCount ); if( bp->userOutputIsInterleaved ) { srcBytePtr = (unsigned char*)*buffer; srcSampleStrideSamples = bp->outputChannelCount; srcChannelStrideBytes = bp->bytesPerUserOutputSample; for( i=0; ioutputChannelCount; ++i ) { bp->outputConverter( hostOutputChannels[i].data, hostOutputChannels[i].stride, srcBytePtr, srcSampleStrideSamples, framesToCopy, &bp->ditherGenerator ); srcBytePtr += srcChannelStrideBytes; /* skip to next source channel */ /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + framesToCopy * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } /* advance callers source pointer (buffer) */ *buffer = ((unsigned char *)*buffer) + framesToCopy * bp->outputChannelCount * bp->bytesPerUserOutputSample; } else { /* user output is not interleaved */ nonInterleavedSrcPtrs = (void**)*buffer; srcSampleStrideSamples = 1; for( i=0; ioutputChannelCount; ++i ) { srcBytePtr = (unsigned char*)nonInterleavedSrcPtrs[i]; bp->outputConverter( hostOutputChannels[i].data, hostOutputChannels[i].stride, srcBytePtr, srcSampleStrideSamples, framesToCopy, &bp->ditherGenerator ); /* advance callers source pointer (nonInterleavedSrcPtrs[i]) */ srcBytePtr += bp->bytesPerUserOutputSample * framesToCopy; nonInterleavedSrcPtrs[i] = srcBytePtr; /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + framesToCopy * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } } bp->hostOutputFrameCount[0] += framesToCopy; return framesToCopy; } unsigned long PaUtil_ZeroOutput( PaUtilBufferProcessor* bp, unsigned long frameCount ) { PaUtilChannelDescriptor *hostOutputChannels; unsigned int framesToZero; unsigned int i; hostOutputChannels = bp->hostOutputChannels[0]; framesToZero = PA_MIN_( bp->hostOutputFrameCount[0], frameCount ); for( i=0; ioutputChannelCount; ++i ) { bp->outputZeroer( hostOutputChannels[i].data, hostOutputChannels[i].stride, framesToZero ); /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + framesToZero * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } bp->hostOutputFrameCount[0] += framesToZero; return framesToZero; } praat-6.0.04/external/portaudio2007/pa_process.h000066400000000000000000000762341261542461700214040ustar00rootroot00000000000000#ifndef PA_PROCESS_H #define PA_PROCESS_H /* * $Id: pa_process.h 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library callback buffer processing adapters * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Phil Burk, Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Buffer Processor prototypes. A Buffer Processor performs buffer length adaption, coordinates sample format conversion, and interleaves/deinterleaves channels.

Overview

The "Buffer Processor" (PaUtilBufferProcessor) manages conversion of audio data from host buffers to user buffers and back again. Where required, the buffer processor takes care of converting between host and user sample formats, interleaving and deinterleaving multichannel buffers, and adapting between host and user buffers with different lengths. The buffer processor may be used with full and half duplex streams, for both callback streams and blocking read/write streams. One of the important capabilities provided by the buffer processor is the ability to adapt between user and host buffer sizes of different lengths with minimum latency. Although this task is relatively easy to perform when the host buffer size is an integer multiple of the user buffer size, the problem is more complicated when this is not the case - especially for full-duplex callback streams. Where necessary the adaption is implemented by internally buffering some input and/or output data. The buffer adation algorithm used by the buffer processor was originally implemented by Stephan Letz for the ASIO version of PortAudio, and is described in his Callback_adaption_.pdf which is included in the distribution. The buffer processor performs sample conversion using the functions provided by pa_converters.c. The following sections provide an overview of how to use the buffer processor. Interested readers are advised to consult the host API implementations for examples of buffer processor usage.

Initialization, resetting and termination

When a stream is opened, the buffer processor should be initialized using PaUtil_InitializeBufferProcessor. This function initializes internal state and allocates temporary buffers as neccesary according to the supplied configuration parameters. Some of the parameters correspond to those requested by the user in their call to Pa_OpenStream(), others reflect the requirements of the host API implementation - they indicate host buffer sizes, formats, and the type of buffering which the Host API uses. The buffer processor should be initialized for callback streams and blocking read/write streams. Call PaUtil_ResetBufferProcessor to clear any sample data which is present in the buffer processor before starting to use it (for example when Pa_StartStream is called). When the buffer processor is no longer used call PaUtil_TerminateBufferProcessor.

Using the buffer processor for a callback stream

The buffer processor's role in a callback stream is to take host input buffers process them with the stream callback, and fill host output buffers. For a full duplex stream, the buffer processor handles input and output simultaneously due to the requirements of the minimum-latency buffer adation algorithm. When a host buffer becomes available, the implementation should call the buffer processor to process the buffer. The buffer processor calls the stream callback to consume and/or produce audio data as necessary. The buffer processor will convert sample formats, interleave/deinterleave channels, and slice or chunk the data to the appropriate buffer lengths according to the requirements of the stream callback and the host API. To process a host buffer (or a pair of host buffers for a full-duplex stream) use the following calling sequence: -# Call PaUtil_BeginBufferProcessing -# For a stream which takes input: - Call PaUtil_SetInputFrameCount with the number of frames in the host input buffer. - Call one of the following functions one or more times to tell the buffer processor about the host input buffer(s): PaUtil_SetInputChannel, PaUtil_SetInterleavedInputChannels, PaUtil_SetNonInterleavedInputChannel. Which function you call will depend on whether the host buffer(s) are interleaved or not. - If the available host data is split accross two buffers (for example a data range at the end of a circular buffer and another range at the beginning of the circular buffer), also call PaUtil_Set2ndInputFrameCount, PaUtil_Set2ndInputChannel, PaUtil_Set2ndInterleavedInputChannels, PaUtil_Set2ndNonInterleavedInputChannel as necessary to tell the buffer processor about the second buffer. -# For a stream which generates output: - Call PaUtil_SetOutputFrameCount with the number of frames in the host output buffer. - Call one of the following functions one or more times to tell the buffer processor about the host output buffer(s): PaUtil_SetOutputChannel, PaUtil_SetInterleavedOutputChannels, PaUtil_SetNonInterleavedOutputChannel. Which function you call will depend on whether the host buffer(s) are interleaved or not. - If the available host output buffer space is split accross two buffers (for example a data range at the end of a circular buffer and another range at the beginning of the circular buffer), call PaUtil_Set2ndOutputFrameCount, PaUtil_Set2ndOutputChannel, PaUtil_Set2ndInterleavedOutputChannels, PaUtil_Set2ndNonInterleavedOutputChannel as necessary to tell the buffer processor about the second buffer. -# Call PaUtil_EndBufferProcessing, this function performs the actual data conversion and processing.

Using the buffer processor for a blocking read/write stream

Blocking read/write streams use the buffer processor to convert and copy user output data to a host buffer, and to convert and copy host input data to the user's buffer. The buffer processor does not perform any buffer adaption. When using the buffer processor in a blocking read/write stream the input and output conversion are performed separately by the PaUtil_CopyInput and PaUtil_CopyOutput functions. To copy data from a host input buffer to the buffer(s) which the user supplies to Pa_ReadStream, use the following calling sequence. - Repeat the following three steps until the user buffer(s) have been filled with samples from the host input buffers: -# Call PaUtil_SetInputFrameCount with the number of frames in the host input buffer. -# Call one of the following functions one or more times to tell the buffer processor about the host input buffer(s): PaUtil_SetInputChannel, PaUtil_SetInterleavedInputChannels, PaUtil_SetNonInterleavedInputChannel. Which function you call will depend on whether the host buffer(s) are interleaved or not. -# Call PaUtil_CopyInput with the user buffer pointer (or a copy of the array of buffer pointers for a non-interleaved stream) passed to Pa_ReadStream, along with the number of frames in the user buffer(s). Be careful to pass a copy of the user buffer pointers to PaUtil_CopyInput because PaUtil_CopyInput advances the pointers to the start of the next region to copy. - PaUtil_CopyInput will not copy more data than is available in the host buffer(s), so the above steps need to be repeated until the user buffer(s) are full. To copy data to the host output buffer from the user buffers(s) supplied to Pa_WriteStream use the following calling sequence. - Repeat the following three steps until all frames from the user buffer(s) have been copied to the host API: -# Call PaUtil_SetOutputFrameCount with the number of frames in the host output buffer. -# Call one of the following functions one or more times to tell the buffer processor about the host output buffer(s): PaUtil_SetOutputChannel, PaUtil_SetInterleavedOutputChannels, PaUtil_SetNonInterleavedOutputChannel. Which function you call will depend on whether the host buffer(s) are interleaved or not. -# Call PaUtil_CopyOutput with the user buffer pointer (or a copy of the array of buffer pointers for a non-interleaved stream) passed to Pa_WriteStream, along with the number of frames in the user buffer(s). Be careful to pass a copy of the user buffer pointers to PaUtil_CopyOutput because PaUtil_CopyOutput advances the pointers to the start of the next region to copy. - PaUtil_CopyOutput will not copy more data than fits in the host buffer(s), so the above steps need to be repeated until all user data is copied. */ #include "portaudio.h" #include "pa_converters.h" #include "pa_dither.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** @brief Mode flag passed to PaUtil_InitializeBufferProcessor indicating the type of buffering that the host API uses. The mode used depends on whether the host API or the implementation manages the buffers, and how these buffers are used (scatter gather, circular buffer). */ typedef enum { /** The host buffer size is a fixed known size. */ paUtilFixedHostBufferSize, /** The host buffer size may vary, but has a known maximum size. */ paUtilBoundedHostBufferSize, /** Nothing is known about the host buffer size. */ paUtilUnknownHostBufferSize, /** The host buffer size varies, and the client does not require the buffer processor to consume all of the input and fill all of the output buffer. This is useful when the implementation has access to the host API's circular buffer and only needs to consume/fill some of it, not necessarily all of it, with each call to the buffer processor. This is the only mode where PaUtil_EndBufferProcessing() may not consume the whole buffer. */ paUtilVariableHostBufferSizePartialUsageAllowed }PaUtilHostBufferSizeMode; /** @brief An auxilliary data structure used internally by the buffer processor to represent host input and output buffers. */ typedef struct PaUtilChannelDescriptor{ void *data; unsigned int stride; /**< stride in samples, not bytes */ }PaUtilChannelDescriptor; /** @brief The main buffer processor data structure. Allocate one of these, initialize it with PaUtil_InitializeBufferProcessor and terminate it with PaUtil_TerminateBufferProcessor. */ typedef struct { unsigned long framesPerUserBuffer; unsigned long framesPerHostBuffer; PaUtilHostBufferSizeMode hostBufferSizeMode; int useNonAdaptingProcess; unsigned long framesPerTempBuffer; unsigned int inputChannelCount; unsigned int bytesPerHostInputSample; unsigned int bytesPerUserInputSample; int userInputIsInterleaved; PaUtilConverter *inputConverter; PaUtilZeroer *inputZeroer; unsigned int outputChannelCount; unsigned int bytesPerHostOutputSample; unsigned int bytesPerUserOutputSample; int userOutputIsInterleaved; PaUtilConverter *outputConverter; PaUtilZeroer *outputZeroer; unsigned long initialFramesInTempInputBuffer; unsigned long initialFramesInTempOutputBuffer; void *tempInputBuffer; /**< used for slips, block adaption, and conversion. */ void **tempInputBufferPtrs; /**< storage for non-interleaved buffer pointers, NULL for interleaved user input */ unsigned long framesInTempInputBuffer; /**< frames remaining in input buffer from previous adaption iteration */ void *tempOutputBuffer; /**< used for slips, block adaption, and conversion. */ void **tempOutputBufferPtrs; /**< storage for non-interleaved buffer pointers, NULL for interleaved user output */ unsigned long framesInTempOutputBuffer; /**< frames remaining in input buffer from previous adaption iteration */ PaStreamCallbackTimeInfo *timeInfo; PaStreamCallbackFlags callbackStatusFlags; unsigned long hostInputFrameCount[2]; PaUtilChannelDescriptor *hostInputChannels[2]; /**< pointers to arrays of channel descriptors. pointers are NULL for half-duplex output processing. hostInputChannels[i].data is NULL when the caller calls PaUtil_SetNoInput() */ unsigned long hostOutputFrameCount[2]; PaUtilChannelDescriptor *hostOutputChannels[2]; /**< pointers to arrays of channel descriptors. pointers are NULL for half-duplex input processing. hostOutputChannels[i].data is NULL when the caller calls PaUtil_SetNoOutput() */ PaUtilTriangularDitherGenerator ditherGenerator; double samplePeriod; PaStreamCallback *streamCallback; void *userData; } PaUtilBufferProcessor; /** @name Initialization, termination, resetting and info */ /*@{*/ /** Initialize a buffer processor's representation stored in a PaUtilBufferProcessor structure. Be sure to call PaUtil_TerminateBufferProcessor after finishing with a buffer processor. @param bufferProcessor The buffer processor structure to initialize. @param inputChannelCount The number of input channels as passed to Pa_OpenStream or 0 for an output-only stream. @param userInputSampleFormat Format of user input samples, as passed to Pa_OpenStream. This parameter is ignored for ouput-only streams. @param hostInputSampleFormat Format of host input samples. This parameter is ignored for output-only streams. See note about host buffer interleave below. @param outputChannelCount The number of output channels as passed to Pa_OpenStream or 0 for an input-only stream. @param userOutputSampleFormat Format of user output samples, as passed to Pa_OpenStream. This parameter is ignored for input-only streams. @param hostOutputSampleFormat Format of host output samples. This parameter is ignored for input-only streams. See note about host buffer interleave below. @param sampleRate Sample rate of the stream. The more accurate this is the better - it is used for updating time stamps when adapting buffers. @param streamFlags Stream flags as passed to Pa_OpenStream, this parameter is used for selecting special sample conversion options such as clipping and dithering. @param framesPerUserBuffer Number of frames per user buffer, as requested by the framesPerBuffer parameter to Pa_OpenStream. This parameter may be zero to indicate that the user will accept any (and varying) buffer sizes. @param framesPerHostBuffer Specifies the number of frames per host buffer for the fixed buffer size mode, and the maximum number of frames per host buffer for the bounded host buffer size mode. It is ignored for the other modes. @param hostBufferSizeMode A mode flag indicating the size variability of host buffers that will be passed to the buffer processor. See PaUtilHostBufferSizeMode for further details. @param streamCallback The user stream callback passed to Pa_OpenStream. @param userData The user data field passed to Pa_OpenStream. @note The interleave flag is ignored for host buffer formats. Host interleave is determined by the use of different SetInput and SetOutput functions. @return An error code indicating whether the initialization was successful. If the error code is not PaNoError, the buffer processor was not initialized and should not be used. @see Pa_OpenStream, PaUtilHostBufferSizeMode, PaUtil_TerminateBufferProcessor */ PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bufferProcessor, int inputChannelCount, PaSampleFormat userInputSampleFormat, PaSampleFormat hostInputSampleFormat, int outputChannelCount, PaSampleFormat userOutputSampleFormat, PaSampleFormat hostOutputSampleFormat, double sampleRate, PaStreamFlags streamFlags, unsigned long framesPerUserBuffer, /* 0 indicates don't care */ unsigned long framesPerHostBuffer, PaUtilHostBufferSizeMode hostBufferSizeMode, PaStreamCallback *streamCallback, void *userData ); /** Terminate a buffer processor's representation. Deallocates any temporary buffers allocated by PaUtil_InitializeBufferProcessor. @param bufferProcessor The buffer processor structure to terminate. @see PaUtil_InitializeBufferProcessor. */ void PaUtil_TerminateBufferProcessor( PaUtilBufferProcessor* bufferProcessor ); /** Clear any internally buffered data. If you call PaUtil_InitializeBufferProcessor in your OpenStream routine, make sure you call PaUtil_ResetBufferProcessor in your StartStream call. @param bufferProcessor The buffer processor to reset. */ void PaUtil_ResetBufferProcessor( PaUtilBufferProcessor* bufferProcessor ); /** Retrieve the input latency of a buffer processor. @param bufferProcessor The buffer processor examine. @return The input latency introduced by the buffer processor, in frames. @see PaUtil_GetBufferProcessorOutputLatency */ unsigned long PaUtil_GetBufferProcessorInputLatency( PaUtilBufferProcessor* bufferProcessor ); /** Retrieve the output latency of a buffer processor. @param bufferProcessor The buffer processor examine. @return The output latency introduced by the buffer processor, in frames. @see PaUtil_GetBufferProcessorInputLatency */ unsigned long PaUtil_GetBufferProcessorOutputLatency( PaUtilBufferProcessor* bufferProcessor ); /*@}*/ /** @name Host buffer pointer configuration Functions to set host input and output buffers, used by both callback streams and blocking read/write streams. */ /*@{*/ /** Set the number of frames in the input host buffer(s) specified by the PaUtil_Set*InputChannel functions. @param bufferProcessor The buffer processor. @param frameCount The number of host input frames. A 0 frameCount indicates to use the framesPerHostBuffer value passed to PaUtil_InitializeBufferProcessor. @see PaUtil_SetNoInput, PaUtil_SetInputChannel, PaUtil_SetInterleavedInputChannels, PaUtil_SetNonInterleavedInputChannel */ void PaUtil_SetInputFrameCount( PaUtilBufferProcessor* bufferProcessor, unsigned long frameCount ); /** Indicate that no input is avalable. This function should be used when priming the output of a full-duplex stream opened with the paPrimeOutputBuffersUsingStreamCallback flag. Note that it is not necessary to call this or any othe PaUtil_Set*Input* functions for ouput-only streams. @param bufferProcessor The buffer processor. */ void PaUtil_SetNoInput( PaUtilBufferProcessor* bufferProcessor ); /** Provide the buffer processor with a pointer to a host input channel. @param bufferProcessor The buffer processor. @param channel The channel number. @param data The buffer. @param stride The stride from one sample to the next, in samples. For interleaved host buffers, the stride will usually be the same as the number of channels in the buffer. */ void PaUtil_SetInputChannel( PaUtilBufferProcessor* bufferProcessor, unsigned int channel, void *data, unsigned int stride ); /** Provide the buffer processor with a pointer to an number of interleaved host input channels. @param bufferProcessor The buffer processor. @param firstChannel The first channel number. @param data The buffer. @param channelCount The number of interleaved channels in the buffer. If channelCount is zero, the number of channels specified to PaUtil_InitializeBufferProcessor will be used. */ void PaUtil_SetInterleavedInputChannels( PaUtilBufferProcessor* bufferProcessor, unsigned int firstChannel, void *data, unsigned int channelCount ); /** Provide the buffer processor with a pointer to one non-interleaved host output channel. @param bufferProcessor The buffer processor. @param channel The channel number. @param data The buffer. */ void PaUtil_SetNonInterleavedInputChannel( PaUtilBufferProcessor* bufferProcessor, unsigned int channel, void *data ); /** Use for the second buffer half when the input buffer is split in two halves. @see PaUtil_SetInputFrameCount */ void PaUtil_Set2ndInputFrameCount( PaUtilBufferProcessor* bufferProcessor, unsigned long frameCount ); /** Use for the second buffer half when the input buffer is split in two halves. @see PaUtil_SetInputChannel */ void PaUtil_Set2ndInputChannel( PaUtilBufferProcessor* bufferProcessor, unsigned int channel, void *data, unsigned int stride ); /** Use for the second buffer half when the input buffer is split in two halves. @see PaUtil_SetInterleavedInputChannels */ void PaUtil_Set2ndInterleavedInputChannels( PaUtilBufferProcessor* bufferProcessor, unsigned int firstChannel, void *data, unsigned int channelCount ); /** Use for the second buffer half when the input buffer is split in two halves. @see PaUtil_SetNonInterleavedInputChannel */ void PaUtil_Set2ndNonInterleavedInputChannel( PaUtilBufferProcessor* bufferProcessor, unsigned int channel, void *data ); /** Set the number of frames in the output host buffer(s) specified by the PaUtil_Set*OutputChannel functions. @param bufferProcessor The buffer processor. @param frameCount The number of host output frames. A 0 frameCount indicates to use the framesPerHostBuffer value passed to PaUtil_InitializeBufferProcessor. @see PaUtil_SetOutputChannel, PaUtil_SetInterleavedOutputChannels, PaUtil_SetNonInterleavedOutputChannel */ void PaUtil_SetOutputFrameCount( PaUtilBufferProcessor* bufferProcessor, unsigned long frameCount ); /** Indicate that the output will be discarded. This function should be used when implementing the paNeverDropInput mode for full duplex streams. @param bufferProcessor The buffer processor. */ void PaUtil_SetNoOutput( PaUtilBufferProcessor* bufferProcessor ); /** Provide the buffer processor with a pointer to a host output channel. @param bufferProcessor The buffer processor. @param channel The channel number. @param data The buffer. @param stride The stride from one sample to the next, in samples. For interleaved host buffers, the stride will usually be the same as the number of channels in the buffer. */ void PaUtil_SetOutputChannel( PaUtilBufferProcessor* bufferProcessor, unsigned int channel, void *data, unsigned int stride ); /** Provide the buffer processor with a pointer to a number of interleaved host output channels. @param bufferProcessor The buffer processor. @param firstChannel The first channel number. @param data The buffer. @param channelCount The number of interleaved channels in the buffer. If channelCount is zero, the number of channels specified to PaUtil_InitializeBufferProcessor will be used. */ void PaUtil_SetInterleavedOutputChannels( PaUtilBufferProcessor* bufferProcessor, unsigned int firstChannel, void *data, unsigned int channelCount ); /** Provide the buffer processor with a pointer to one non-interleaved host output channel. @param bufferProcessor The buffer processor. @param channel The channel number. @param data The buffer. */ void PaUtil_SetNonInterleavedOutputChannel( PaUtilBufferProcessor* bufferProcessor, unsigned int channel, void *data ); /** Use for the second buffer half when the output buffer is split in two halves. @see PaUtil_SetOutputFrameCount */ void PaUtil_Set2ndOutputFrameCount( PaUtilBufferProcessor* bufferProcessor, unsigned long frameCount ); /** Use for the second buffer half when the output buffer is split in two halves. @see PaUtil_SetOutputChannel */ void PaUtil_Set2ndOutputChannel( PaUtilBufferProcessor* bufferProcessor, unsigned int channel, void *data, unsigned int stride ); /** Use for the second buffer half when the output buffer is split in two halves. @see PaUtil_SetInterleavedOutputChannels */ void PaUtil_Set2ndInterleavedOutputChannels( PaUtilBufferProcessor* bufferProcessor, unsigned int firstChannel, void *data, unsigned int channelCount ); /** Use for the second buffer half when the output buffer is split in two halves. @see PaUtil_SetNonInterleavedOutputChannel */ void PaUtil_Set2ndNonInterleavedOutputChannel( PaUtilBufferProcessor* bufferProcessor, unsigned int channel, void *data ); /*@}*/ /** @name Buffer processing functions for callback streams */ /*@{*/ /** Commence processing a host buffer (or a pair of host buffers in the full-duplex case) for a callback stream. @param bufferProcessor The buffer processor. @param timeInfo Timing information for the first sample of the host buffer(s). This information may be adjusted when buffer adaption is being performed. @param callbackStatusFlags Flags indicating whether underruns and overruns have occurred since the last time the buffer processor was called. */ void PaUtil_BeginBufferProcessing( PaUtilBufferProcessor* bufferProcessor, PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags callbackStatusFlags ); /** Finish processing a host buffer (or a pair of host buffers in the full-duplex case) for a callback stream. @param bufferProcessor The buffer processor. @param callbackResult On input, indicates a previous callback result, and on exit, the result of the user stream callback, if it is called. On entry callbackResult should contain one of { paContinue, paComplete, or paAbort}. If paComplete is passed, the stream callback will not be called but any audio that was generated by previous stream callbacks will be copied to the output buffer(s). You can check whether the buffer processor's internal buffer is empty by calling PaUtil_IsBufferProcessorOutputEmpty. If the stream callback is called its result is stored in *callbackResult. If the stream callback returns paComplete or paAbort, all output buffers will be full of valid data - some of which may be zeros to acount for data that wasn't generated by the terminating callback. @return The number of frames processed. This usually corresponds to the number of frames specified by the PaUtil_Set*FrameCount functions, exept in the paUtilVariableHostBufferSizePartialUsageAllowed buffer size mode when a smaller value may be returned. */ unsigned long PaUtil_EndBufferProcessing( PaUtilBufferProcessor* bufferProcessor, int *callbackResult ); /** Determine whether any callback generated output remains in the bufffer processor's internal buffers. This method may be used to determine when to continue calling PaUtil_EndBufferProcessing() after the callback has returned a callbackResult of paComplete. @param bufferProcessor The buffer processor. @return Returns non-zero when callback generated output remains in the internal buffer and zero (0) when there internal buffer contains no callback generated data. */ int PaUtil_IsBufferProcessorOutputEmpty( PaUtilBufferProcessor* bufferProcessor ); /*@}*/ /** @name Buffer processing functions for blocking read/write streams */ /*@{*/ /** Copy samples from host input channels set up by the PaUtil_Set*InputChannels functions to a user supplied buffer. This function is intended for use with blocking read/write streams. Copies the minimum of the number of user frames (specified by the frameCount parameter) and the number of available host frames (specified in a previous call to SetInputFrameCount()). @param bufferProcessor The buffer processor. @param buffer A pointer to the user buffer pointer, or a pointer to a pointer to an array of user buffer pointers for a non-interleaved stream. It is important that this parameter points to a copy of the user buffer pointers, not to the actual user buffer pointers, because this function updates the pointers before returning. @param frameCount The number of frames of data in the buffer(s) pointed to by the buffer parameter. @return The number of frames copied. The buffer pointer(s) pointed to by the buffer parameter are advanced to point to the frame(s) following the last one filled. */ unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bufferProcessor, void **buffer, unsigned long frameCount ); /* Copy samples from a user supplied buffer to host output channels set up by the PaUtil_Set*OutputChannels functions. This function is intended for use with blocking read/write streams. Copies the minimum of the number of user frames (specified by the frameCount parameter) and the number of host frames (specified in a previous call to SetOutputFrameCount()). @param bufferProcessor The buffer processor. @param buffer A pointer to the user buffer pointer, or a pointer to a pointer to an array of user buffer pointers for a non-interleaved stream. It is important that this parameter points to a copy of the user buffer pointers, not to the actual user buffer pointers, because this function updates the pointers before returning. @param frameCount The number of frames of data in the buffer(s) pointed to by the buffer parameter. @return The number of frames copied. The buffer pointer(s) pointed to by the buffer parameter are advanced to point to the frame(s) following the last one copied. */ unsigned long PaUtil_CopyOutput( PaUtilBufferProcessor* bufferProcessor, const void ** buffer, unsigned long frameCount ); /* Zero samples in host output channels set up by the PaUtil_Set*OutputChannels functions. This function is useful for flushing streams. Zeros the minimum of frameCount and the number of host frames specified in a previous call to SetOutputFrameCount(). @param bufferProcessor The buffer processor. @param frameCount The maximum number of frames to zero. @return The number of frames zeroed. */ unsigned long PaUtil_ZeroOutput( PaUtilBufferProcessor* bufferProcessor, unsigned long frameCount ); /*@}*/ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_PROCESS_H */ praat-6.0.04/external/portaudio2007/pa_ringbuffer.c000066400000000000000000000257541261542461700220530ustar00rootroot00000000000000/* * $Id: pa_ringbuffer.c 1240 2007-07-17 13:05:07Z bjornroche $ * Portable Audio I/O Library * Ring Buffer utility. * * Author: Phil Burk, http://www.softsynth.com * modified for SMP safety on Mac OS X by Bjorn Roche * modified for SMP safety on Linux by Leland Lucius * also, allowed for const where possible * Note that this is safe only for a single-thread reader and a * single-thread writer. * * This program uses the PortAudio Portable Audio Library. * For more information see: http://www.portaudio.com * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src */ #include #include #include #include "pa_ringbuffer.h" #include /**************** * First, we'll define some memory barrier primitives based on the system. * right now only OS X, FreeBSD, and Linux are supported. In addition to providing * memory barriers, these functions should ensure that data cached in registers * is written out to cache where it can be snooped by other CPUs. (ie, the volatile * keyword should not be required) * * the primitives that must be defined are: * * PaUtil_FullMemoryBarrier() * PaUtil_ReadMemoryBarrier() * PaUtil_WriteMemoryBarrier() * ****************/ #if defined(__APPLE__) # include /* Here are the memory barrier functions. Mac OS X only provides full memory barriers, so the three types of barriers are the same, however, these barriers are superior to compiler-based ones. */ # define PaUtil_FullMemoryBarrier() OSMemoryBarrier() # define PaUtil_ReadMemoryBarrier() OSMemoryBarrier() # define PaUtil_WriteMemoryBarrier() OSMemoryBarrier() #elif defined(__GNUC__) /* GCC >= 4.1 has built-in intrinsics. We'll use those */ # if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) # define PaUtil_FullMemoryBarrier() __sync_synchronize() # define PaUtil_ReadMemoryBarrier() __sync_synchronize() # define PaUtil_WriteMemoryBarrier() __sync_synchronize() /* as a fallback, GCC understands volatile asm and "memory" to mean it * should not reorder memory read/writes */ # elif defined( __PPC__ ) # define PaUtil_FullMemoryBarrier() asm volatile("sync":::"memory") # define PaUtil_ReadMemoryBarrier() asm volatile("sync":::"memory") # define PaUtil_WriteMemoryBarrier() asm volatile("sync":::"memory") # elif defined( __i386__ ) || defined( __i486__ ) || defined( __i586__ ) || defined( __i686__ ) || defined( __x86_64__ ) # define PaUtil_FullMemoryBarrier() asm volatile("mfence":::"memory") # define PaUtil_ReadMemoryBarrier() asm volatile("lfence":::"memory") # define PaUtil_WriteMemoryBarrier() asm volatile("sfence":::"memory") # else # ifdef ALLOW_SMP_DANGERS # warning Memory barriers not defined on this system or system unknown # warning For SMP safety, you should fix this. # define PaUtil_FullMemoryBarrier() # define PaUtil_ReadMemoryBarrier() # define PaUtil_WriteMemoryBarrier() # else # error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed. # endif # endif #else # ifdef ALLOW_SMP_DANGERS # warning Memory barriers not defined on this system or system unknown # warning For SMP safety, you should fix this. # define PaUtil_FullMemoryBarrier() # define PaUtil_ReadMemoryBarrier() # define PaUtil_WriteMemoryBarrier() # else # error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed. # endif #endif /*************************************************************************** * Initialize FIFO. * numBytes must be power of 2, returns -1 if not. */ long PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, long numBytes, void *dataPtr ) { if( ((numBytes-1) & numBytes) != 0) return -1; /* Not Power of two. */ rbuf->bufferSize = numBytes; rbuf->buffer = (char *)dataPtr; PaUtil_FlushRingBuffer( rbuf ); rbuf->bigMask = (numBytes*2)-1; rbuf->smallMask = (numBytes)-1; return 0; } /*************************************************************************** ** Return number of bytes available for reading. */ long PaUtil_GetRingBufferReadAvailable( PaUtilRingBuffer *rbuf ) { PaUtil_ReadMemoryBarrier(); return ( (rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask ); } /*************************************************************************** ** Return number of bytes available for writing. */ long PaUtil_GetRingBufferWriteAvailable( PaUtilRingBuffer *rbuf ) { /* Since we are calling PaUtil_GetRingBufferReadAvailable, we don't need an aditional MB */ return ( rbuf->bufferSize - PaUtil_GetRingBufferReadAvailable(rbuf)); } /*************************************************************************** ** Clear buffer. Should only be called when buffer is NOT being read. */ void PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf ) { rbuf->writeIndex = rbuf->readIndex = 0; } /*************************************************************************** ** Get address of region(s) to which we can write data. ** If the region is contiguous, size2 will be zero. ** If non-contiguous, size2 will be the size of second region. ** Returns room available to be written or numBytes, whichever is smaller. */ long PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, long numBytes, void **dataPtr1, long *sizePtr1, void **dataPtr2, long *sizePtr2 ) { long index; long available = PaUtil_GetRingBufferWriteAvailable( rbuf ); if( numBytes > available ) numBytes = available; /* Check to see if write is not contiguous. */ index = rbuf->writeIndex & rbuf->smallMask; if( (index + numBytes) > rbuf->bufferSize ) { /* Write data in two blocks that wrap the buffer. */ long firstHalf = rbuf->bufferSize - index; *dataPtr1 = &rbuf->buffer[index]; *sizePtr1 = firstHalf; *dataPtr2 = &rbuf->buffer[0]; *sizePtr2 = numBytes - firstHalf; } else { *dataPtr1 = &rbuf->buffer[index]; *sizePtr1 = numBytes; *dataPtr2 = NULL; *sizePtr2 = 0; } return numBytes; } /*************************************************************************** */ long PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, long numBytes ) { /* we need to ensure that previous writes are seen before we update the write index */ PaUtil_WriteMemoryBarrier(); return rbuf->writeIndex = (rbuf->writeIndex + numBytes) & rbuf->bigMask; } /*************************************************************************** ** Get address of region(s) from which we can read data. ** If the region is contiguous, size2 will be zero. ** If non-contiguous, size2 will be the size of second region. ** Returns room available to be written or numBytes, whichever is smaller. */ long PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, long numBytes, void **dataPtr1, long *sizePtr1, void **dataPtr2, long *sizePtr2 ) { long index; long available = PaUtil_GetRingBufferReadAvailable( rbuf ); if( numBytes > available ) numBytes = available; /* Check to see if read is not contiguous. */ index = rbuf->readIndex & rbuf->smallMask; if( (index + numBytes) > rbuf->bufferSize ) { /* Write data in two blocks that wrap the buffer. */ long firstHalf = rbuf->bufferSize - index; *dataPtr1 = &rbuf->buffer[index]; *sizePtr1 = firstHalf; *dataPtr2 = &rbuf->buffer[0]; *sizePtr2 = numBytes - firstHalf; } else { *dataPtr1 = &rbuf->buffer[index]; *sizePtr1 = numBytes; *dataPtr2 = NULL; *sizePtr2 = 0; } return numBytes; } /*************************************************************************** */ long PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, long numBytes ) { /* we need to ensure that previous writes are always seen before updating the index. */ PaUtil_WriteMemoryBarrier(); return rbuf->readIndex = (rbuf->readIndex + numBytes) & rbuf->bigMask; } /*************************************************************************** ** Return bytes written. */ long PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, long numBytes ) { long size1, size2, numWritten; void *data1, *data2; numWritten = PaUtil_GetRingBufferWriteRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 ); if( size2 > 0 ) { memcpy( data1, data, size1 ); data = ((char *)data) + size1; memcpy( data2, data, size2 ); } else { memcpy( data1, data, size1 ); } PaUtil_AdvanceRingBufferWriteIndex( rbuf, numWritten ); return numWritten; } /*************************************************************************** ** Return bytes read. */ long PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, long numBytes ) { long size1, size2, numRead; void *data1, *data2; numRead = PaUtil_GetRingBufferReadRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 ); if( size2 > 0 ) { memcpy( data, data1, size1 ); data = ((char *)data) + size1; memcpy( data, data2, size2 ); } else { memcpy( data, data1, size1 ); } PaUtil_AdvanceRingBufferReadIndex( rbuf, numRead ); return numRead; } praat-6.0.04/external/portaudio2007/pa_ringbuffer.h000066400000000000000000000150661261542461700220530ustar00rootroot00000000000000#ifndef PA_RINGBUFFER_H #define PA_RINGBUFFER_H /* * $Id: pa_ringbuffer.h 1151 2006-11-29 02:11:16Z leland_lucius $ * Portable Audio I/O Library * Ring Buffer utility. * * Author: Phil Burk, http://www.softsynth.com * modified for SMP safety on OS X by Bjorn Roche. * also allowed for const where possible. * Note that this is safe only for a single-thread reader * and a single-thread writer. * * This program is distributed with the PortAudio Portable Audio Library. * For more information see: http://www.portaudio.com * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ typedef struct PaUtilRingBuffer { long bufferSize; /* Number of bytes in FIFO. Power of 2. Set by PaUtil_InitRingBuffer. */ long writeIndex; /* Index of next writable byte. Set by PaUtil_AdvanceRingBufferWriteIndex. */ long readIndex; /* Index of next readable byte. Set by PaUtil_AdvanceRingBufferReadIndex. */ long bigMask; /* Used for wrapping indices with extra bit to distinguish full/empty. */ long smallMask; /* Used for fitting indices to buffer. */ char *buffer; }PaUtilRingBuffer; /** Initialize Ring Buffer. @param rbuf The ring buffer. @param numBytes The number of bytes in the buffer and must be power of 2. @param dataPtr A pointer to a previously allocated area where the data will be maintained. It must be numBytes long. @return -1 if numBytes is not a power of 2, otherwise 0. */ long PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, long numBytes, void *dataPtr ); /** Clear buffer. Should only be called when buffer is NOT being read. @param rbuf The ring buffer. */ void PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf ); /** Retrieve the number of bytes available in the ring buffer for writing. @param rbuf The ring buffer. @return The number of bytes available for writing. */ long PaUtil_GetRingBufferWriteAvailable( PaUtilRingBuffer *rbuf ); /** Retrieve the number of bytes available in the ring buffer for reading. @param rbuf The ring buffer. @return The number of bytes available for reading. */ long PaUtil_GetRingBufferReadAvailable( PaUtilRingBuffer *rbuf ); /** Write data to the ring buffer. @param rbuf The ring buffer. @param data The address of new data to write to the buffer. @param numBytes The number of bytes to be written. @return The number of bytes written. */ long PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, long numBytes ); /** Read data from the ring buffer. @param rbuf The ring buffer. @param data The address where the data should be stored. @param numBytes The number of bytes to be read. @return The number of bytes read. */ long PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, long numBytes ); /** Get address of region(s) to which we can write data. @param rbuf The ring buffer. @param numBytes The number of bytes desired. @param dataPtr1 The address where the first (or only) region pointer will be stored. @param sizePtr1 The address where the first (or only) region length will be stored. @param dataPtr2 The address where the second region pointer will be stored if the first region is too small to satisfy numBytes. @param sizePtr2 The address where the second region length will be stored if the first region is too small to satisfy numBytes. @return The room available to be written or numBytes, whichever is smaller. */ long PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, long numBytes, void **dataPtr1, long *sizePtr1, void **dataPtr2, long *sizePtr2 ); /** Advance the write index to the next location to be written. @param rbuf The ring buffer. @param numBytes The number of bytes to advance. @return The new position. */ long PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, long numBytes ); /** Get address of region(s) from which we can write data. @param rbuf The ring buffer. @param numBytes The number of bytes desired. @param dataPtr1 The address where the first (or only) region pointer will be stored. @param sizePtr1 The address where the first (or only) region length will be stored. @param dataPtr2 The address where the second region pointer will be stored if the first region is too small to satisfy numBytes. @param sizePtr2 The address where the second region length will be stored if the first region is too small to satisfy numBytes. @return The number of bytes available for reading. */ long PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, long numBytes, void **dataPtr1, long *sizePtr1, void **dataPtr2, long *sizePtr2 ); /** Advance the read index to the next location to be read. @param rbuf The ring buffer. @param numBytes The number of bytes to advance. @return The new position. */ long PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, long numBytes ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_RINGBUFFER_H */ praat-6.0.04/external/portaudio2007/pa_skeleton.c000066400000000000000000000667101261542461700215430ustar00rootroot00000000000000/* * $Id: pa_skeleton.c 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library skeleton implementation * demonstrates how to use the common functions to implement support * for a host API * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Skeleton implementation of support for a host API. @note This file is provided as a starting point for implementing support for a new host API. IMPLEMENT ME comments are used to indicate functionality which much be customised for each implementation. */ #include /* strlen() */ #include "pa_util.h" #include "pa_allocation.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_cpuload.h" #include "pa_process.h" /* prototypes for functions declared in this file */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); #ifdef __cplusplus } #endif /* __cplusplus */ static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); static PaError CloseStream( PaStream* stream ); static PaError StartStream( PaStream *stream ); static PaError StopStream( PaStream *stream ); static PaError AbortStream( PaStream *stream ); static PaError IsStreamStopped( PaStream *s ); static PaError IsStreamActive( PaStream *stream ); static PaTime GetStreamTime( PaStream *stream ); static double GetStreamCpuLoad( PaStream* stream ); static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ); static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ); static signed long GetStreamReadAvailable( PaStream* stream ); static signed long GetStreamWriteAvailable( PaStream* stream ); /* IMPLEMENT ME: a macro like the following one should be used for reporting host errors */ #define PA_SKELETON_SET_LAST_HOST_ERROR( errorCode, errorText ) \ PaUtil_SetLastHostErrorInfo( paInDevelopment, errorCode, errorText ) /* PaSkeletonHostApiRepresentation - host api datastructure specific to this implementation */ typedef struct { PaUtilHostApiRepresentation inheritedHostApiRep; PaUtilStreamInterface callbackStreamInterface; PaUtilStreamInterface blockingStreamInterface; PaUtilAllocationGroup *allocations; /* implementation specific data goes here */ } PaSkeletonHostApiRepresentation; /* IMPLEMENT ME: rename this */ PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) { PaError result = paNoError; int i, deviceCount; PaSkeletonHostApiRepresentation *skeletonHostApi; PaDeviceInfo *deviceInfoArray; skeletonHostApi = (PaSkeletonHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaSkeletonHostApiRepresentation) ); if( !skeletonHostApi ) { result = paInsufficientMemory; goto error; } skeletonHostApi->allocations = PaUtil_CreateAllocationGroup(); if( !skeletonHostApi->allocations ) { result = paInsufficientMemory; goto error; } *hostApi = &skeletonHostApi->inheritedHostApiRep; (*hostApi)->info.structVersion = 1; (*hostApi)->info.type = paInDevelopment; /* IMPLEMENT ME: change to correct type id */ (*hostApi)->info.name = "skeleton implementation"; /* IMPLEMENT ME: change to correct name */ (*hostApi)->info.defaultInputDevice = paNoDevice; /* IMPLEMENT ME */ (*hostApi)->info.defaultOutputDevice = paNoDevice; /* IMPLEMENT ME */ (*hostApi)->info.deviceCount = 0; deviceCount = 0; /* IMPLEMENT ME */ if( deviceCount > 0 ) { (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( skeletonHostApi->allocations, sizeof(PaDeviceInfo*) * deviceCount ); if( !(*hostApi)->deviceInfos ) { result = paInsufficientMemory; goto error; } /* allocate all device info structs in a contiguous block */ deviceInfoArray = (PaDeviceInfo*)PaUtil_GroupAllocateMemory( skeletonHostApi->allocations, sizeof(PaDeviceInfo) * deviceCount ); if( !deviceInfoArray ) { result = paInsufficientMemory; goto error; } for( i=0; i < deviceCount; ++i ) { PaDeviceInfo *deviceInfo = &deviceInfoArray[i]; deviceInfo->structVersion = 2; deviceInfo->hostApi = hostApiIndex; deviceInfo->name = 0; /* IMPLEMENT ME: allocate block and copy name eg: deviceName = (char*)PaUtil_GroupAllocateMemory( skeletonHostApi->allocations, strlen(srcName) + 1 ); if( !deviceName ) { result = paInsufficientMemory; goto error; } strcpy( deviceName, srcName ); deviceInfo->name = deviceName; */ deviceInfo->maxInputChannels = 0; /* IMPLEMENT ME */ deviceInfo->maxOutputChannels = 0; /* IMPLEMENT ME */ deviceInfo->defaultLowInputLatency = 0.; /* IMPLEMENT ME */ deviceInfo->defaultLowOutputLatency = 0.; /* IMPLEMENT ME */ deviceInfo->defaultHighInputLatency = 0.; /* IMPLEMENT ME */ deviceInfo->defaultHighOutputLatency = 0.; /* IMPLEMENT ME */ deviceInfo->defaultSampleRate = 0.; /* IMPLEMENT ME */ (*hostApi)->deviceInfos[i] = deviceInfo; ++(*hostApi)->info.deviceCount; } } (*hostApi)->Terminate = Terminate; (*hostApi)->OpenStream = OpenStream; (*hostApi)->IsFormatSupported = IsFormatSupported; PaUtil_InitializeStreamInterface( &skeletonHostApi->callbackStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, GetStreamCpuLoad, PaUtil_DummyRead, PaUtil_DummyWrite, PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); PaUtil_InitializeStreamInterface( &skeletonHostApi->blockingStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, PaUtil_DummyGetCpuLoad, ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable ); return result; error: if( skeletonHostApi ) { if( skeletonHostApi->allocations ) { PaUtil_FreeAllAllocations( skeletonHostApi->allocations ); PaUtil_DestroyAllocationGroup( skeletonHostApi->allocations ); } PaUtil_FreeMemory( skeletonHostApi ); } return result; } static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) { PaSkeletonHostApiRepresentation *skeletonHostApi = (PaSkeletonHostApiRepresentation*)hostApi; /* IMPLEMENT ME: - clean up any resources not handled by the allocation group */ if( skeletonHostApi->allocations ) { PaUtil_FreeAllAllocations( skeletonHostApi->allocations ); PaUtil_DestroyAllocationGroup( skeletonHostApi->allocations ); } PaUtil_FreeMemory( skeletonHostApi ); } static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { int inputChannelCount, outputChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( inputSampleFormat & paCustomFormat ) return paSampleFormatNotSupported; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that input device can support inputChannelCount */ if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) return paInvalidChannelCount; /* validate inputStreamInfo */ if( inputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else { inputChannelCount = 0; } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( outputSampleFormat & paCustomFormat ) return paSampleFormatNotSupported; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that output device can support outputChannelCount */ if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) return paInvalidChannelCount; /* validate outputStreamInfo */ if( outputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else { outputChannelCount = 0; } /* IMPLEMENT ME: - if a full duplex stream is requested, check that the combination of input and output parameters is supported if necessary - check that the device supports sampleRate Because the buffer adapter handles conversion between all standard sample formats, the following checks are only required if paCustomFormat is implemented, or under some other unusual conditions. - check that input device can support inputSampleFormat, or that we have the capability to convert from inputSampleFormat to a native format - check that output device can support outputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format */ /* suppress unused variable warnings */ (void) sampleRate; return paFormatIsSupported; } /* PaSkeletonStream - a stream data structure specifically for this implementation */ typedef struct PaSkeletonStream { /* IMPLEMENT ME: rename this */ PaUtilStreamRepresentation streamRepresentation; PaUtilCpuLoadMeasurer cpuLoadMeasurer; PaUtilBufferProcessor bufferProcessor; /* IMPLEMENT ME: - implementation specific data goes here */ unsigned long framesPerHostCallback; /* just an example */ } PaSkeletonStream; /* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ) { PaError result = paNoError; PaSkeletonHostApiRepresentation *skeletonHostApi = (PaSkeletonHostApiRepresentation*)hostApi; PaSkeletonStream *stream = 0; unsigned long framesPerHostBuffer = framesPerBuffer; /* these may not be equivalent for all implementations */ int inputChannelCount, outputChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat; if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that input device can support inputChannelCount */ if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) return paInvalidChannelCount; /* validate inputStreamInfo */ if( inputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ /* IMPLEMENT ME - establish which host formats are available */ hostInputSampleFormat = PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, inputSampleFormat ); } else { inputChannelCount = 0; inputSampleFormat = hostInputSampleFormat = paInt16; /* Surpress 'uninitialised var' warnings. */ } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that output device can support inputChannelCount */ if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) return paInvalidChannelCount; /* validate outputStreamInfo */ if( outputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ /* IMPLEMENT ME - establish which host formats are available */ hostOutputSampleFormat = PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, outputSampleFormat ); } else { outputChannelCount = 0; outputSampleFormat = hostOutputSampleFormat = paInt16; /* Surpress 'uninitialized var' warnings. */ } /* IMPLEMENT ME: ( the following two checks are taken care of by PaUtil_InitializeBufferProcessor() FIXME - checks needed? ) - check that input device can support inputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format - check that output device can support outputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format - if a full duplex stream is requested, check that the combination of input and output parameters is supported - check that the device supports sampleRate - alter sampleRate to a close allowable rate if possible / necessary - validate suggestedInputLatency and suggestedOutputLatency parameters, use default values where necessary */ /* validate platform specific flags */ if( (streamFlags & paPlatformSpecificFlags) != 0 ) return paInvalidFlag; /* unexpected platform specific flag */ stream = (PaSkeletonStream*)PaUtil_AllocateMemory( sizeof(PaSkeletonStream) ); if( !stream ) { result = paInsufficientMemory; goto error; } if( streamCallback ) { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &skeletonHostApi->callbackStreamInterface, streamCallback, userData ); } else { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &skeletonHostApi->blockingStreamInterface, streamCallback, userData ); } PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate ); /* we assume a fixed host buffer size in this example, but the buffer processor can also support bounded and unknown host buffer sizes by passing paUtilBoundedHostBufferSize or paUtilUnknownHostBufferSize instead of paUtilFixedHostBufferSize below. */ result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, inputChannelCount, inputSampleFormat, hostInputSampleFormat, outputChannelCount, outputSampleFormat, hostOutputSampleFormat, sampleRate, streamFlags, framesPerBuffer, framesPerHostBuffer, paUtilFixedHostBufferSize, streamCallback, userData ); if( result != paNoError ) goto error; /* IMPLEMENT ME: initialise the following fields with estimated or actual values. */ stream->streamRepresentation.streamInfo.inputLatency = PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor); stream->streamRepresentation.streamInfo.outputLatency = PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor); stream->streamRepresentation.streamInfo.sampleRate = sampleRate; /* IMPLEMENT ME: - additional stream setup + opening */ stream->framesPerHostCallback = framesPerHostBuffer; *s = (PaStream*)stream; return result; error: if( stream ) PaUtil_FreeMemory( stream ); return result; } /* ExampleHostProcessingLoop() illustrates the kind of processing which may occur in a host implementation. */ static void ExampleHostProcessingLoop( void *inputBuffer, void *outputBuffer, void *userData ) { PaSkeletonStream *stream = (PaSkeletonStream*)userData; PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /* IMPLEMENT ME */ int callbackResult; unsigned long framesProcessed; PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); /* IMPLEMENT ME: - generate timing information - handle buffer slips */ /* If you need to byte swap or shift inputBuffer to convert it into a portaudio format, do it here. */ PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, 0 /* IMPLEMENT ME: pass underflow/overflow flags when necessary */ ); /* depending on whether the host buffers are interleaved, non-interleaved or a mixture, you will want to call PaUtil_SetInterleaved*Channels(), PaUtil_SetNonInterleaved*Channel() or PaUtil_Set*Channel() here. */ PaUtil_SetInputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ ); PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, 0, /* first channel of inputBuffer is channel 0 */ inputBuffer, 0 ); /* 0 - use inputChannelCount passed to init buffer processor */ PaUtil_SetOutputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ ); PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, 0, /* first channel of outputBuffer is channel 0 */ outputBuffer, 0 ); /* 0 - use outputChannelCount passed to init buffer processor */ /* you must pass a valid value of callback result to PaUtil_EndBufferProcessing() in general you would pass paContinue for normal operation, and paComplete to drain the buffer processor's internal output buffer. You can check whether the buffer processor's output buffer is empty using PaUtil_IsBufferProcessorOuputEmpty( bufferProcessor ) */ callbackResult = paContinue; framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult ); /* If you need to byte swap or shift outputBuffer to convert it to host format, do it here. */ PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed ); if( callbackResult == paContinue ) { /* nothing special to do */ } else if( callbackResult == paAbort ) { /* IMPLEMENT ME - finish playback immediately */ /* once finished, call the finished callback */ if( stream->streamRepresentation.streamFinishedCallback != 0 ) stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); } else { /* User callback has asked us to stop with paComplete or other non-zero value */ /* IMPLEMENT ME - finish playback once currently queued audio has completed */ /* once finished, call the finished callback */ if( stream->streamRepresentation.streamFinishedCallback != 0 ) stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); } } /* When CloseStream() is called, the multi-api layer ensures that the stream has already been stopped or aborted. */ static PaError CloseStream( PaStream* s ) { PaError result = paNoError; PaSkeletonStream *stream = (PaSkeletonStream*)s; /* IMPLEMENT ME: - additional stream closing + cleanup */ PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); PaUtil_FreeMemory( stream ); return result; } static PaError StartStream( PaStream *s ) { PaError result = paNoError; PaSkeletonStream *stream = (PaSkeletonStream*)s; PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); /* IMPLEMENT ME, see portaudio.h for required behavior */ /* suppress unused function warning. the code in ExampleHostProcessingLoop or something similar should be implemented to feed samples to and from the host after StartStream() is called. */ (void) ExampleHostProcessingLoop; return result; } static PaError StopStream( PaStream *s ) { PaError result = paNoError; PaSkeletonStream *stream = (PaSkeletonStream*)s; /* suppress unused variable warnings */ (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior */ return result; } static PaError AbortStream( PaStream *s ) { PaError result = paNoError; PaSkeletonStream *stream = (PaSkeletonStream*)s; /* suppress unused variable warnings */ (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior */ return result; } static PaError IsStreamStopped( PaStream *s ) { PaSkeletonStream *stream = (PaSkeletonStream*)s; /* suppress unused variable warnings */ (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior */ return 0; } static PaError IsStreamActive( PaStream *s ) { PaSkeletonStream *stream = (PaSkeletonStream*)s; /* suppress unused variable warnings */ (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior */ return 0; } static PaTime GetStreamTime( PaStream *s ) { PaSkeletonStream *stream = (PaSkeletonStream*)s; /* suppress unused variable warnings */ (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ return 0; } static double GetStreamCpuLoad( PaStream* s ) { PaSkeletonStream *stream = (PaSkeletonStream*)s; return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); } /* As separate stream interfaces are used for blocking and callback streams, the following functions can be guaranteed to only be called for blocking streams. */ static PaError ReadStream( PaStream* s, void *buffer, unsigned long frames ) { PaSkeletonStream *stream = (PaSkeletonStream*)s; /* suppress unused variable warnings */ (void) buffer; (void) frames; (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ return paNoError; } static PaError WriteStream( PaStream* s, const void *buffer, unsigned long frames ) { PaSkeletonStream *stream = (PaSkeletonStream*)s; /* suppress unused variable warnings */ (void) buffer; (void) frames; (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ return paNoError; } static signed long GetStreamReadAvailable( PaStream* s ) { PaSkeletonStream *stream = (PaSkeletonStream*)s; /* suppress unused variable warnings */ (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ return 0; } static signed long GetStreamWriteAvailable( PaStream* s ) { PaSkeletonStream *stream = (PaSkeletonStream*)s; /* suppress unused variable warnings */ (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ return 0; } praat-6.0.04/external/portaudio2007/pa_stream.c000066400000000000000000000122541261542461700212040ustar00rootroot00000000000000/* * $Id: pa_stream.c 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library * * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 2002 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Interface used by pa_front to virtualize functions which operate on streams. */ #include "pa_stream.h" void PaUtil_InitializeStreamInterface( PaUtilStreamInterface *streamInterface, PaError (*Close)( PaStream* ), PaError (*Start)( PaStream* ), PaError (*Stop)( PaStream* ), PaError (*Abort)( PaStream* ), PaError (*IsStopped)( PaStream* ), PaError (*IsActive)( PaStream* ), PaTime (*GetTime)( PaStream* ), double (*GetCpuLoad)( PaStream* ), PaError (*Read)( PaStream*, void *, unsigned long ), PaError (*Write)( PaStream*, const void *, unsigned long ), signed long (*GetReadAvailable)( PaStream* ), signed long (*GetWriteAvailable)( PaStream* ) ) { streamInterface->Close = Close; streamInterface->Start = Start; streamInterface->Stop = Stop; streamInterface->Abort = Abort; streamInterface->IsStopped = IsStopped; streamInterface->IsActive = IsActive; streamInterface->GetTime = GetTime; streamInterface->GetCpuLoad = GetCpuLoad; streamInterface->Read = Read; streamInterface->Write = Write; streamInterface->GetReadAvailable = GetReadAvailable; streamInterface->GetWriteAvailable = GetWriteAvailable; } void PaUtil_InitializeStreamRepresentation( PaUtilStreamRepresentation *streamRepresentation, PaUtilStreamInterface *streamInterface, PaStreamCallback *streamCallback, void *userData ) { streamRepresentation->magic = PA_STREAM_MAGIC; streamRepresentation->nextOpenStream = 0; streamRepresentation->streamInterface = streamInterface; streamRepresentation->streamCallback = streamCallback; streamRepresentation->streamFinishedCallback = 0; streamRepresentation->userData = userData; streamRepresentation->streamInfo.inputLatency = 0.; streamRepresentation->streamInfo.outputLatency = 0.; streamRepresentation->streamInfo.sampleRate = 0.; } void PaUtil_TerminateStreamRepresentation( PaUtilStreamRepresentation *streamRepresentation ) { streamRepresentation->magic = 0; } PaError PaUtil_DummyRead( PaStream* stream, void *buffer, unsigned long frames ) { (void)stream; /* unused parameter */ (void)buffer; /* unused parameter */ (void)frames; /* unused parameter */ return paCanNotReadFromACallbackStream; } PaError PaUtil_DummyWrite( PaStream* stream, const void *buffer, unsigned long frames ) { (void)stream; /* unused parameter */ (void)buffer; /* unused parameter */ (void)frames; /* unused parameter */ return paCanNotWriteToACallbackStream; } signed long PaUtil_DummyGetReadAvailable( PaStream* stream ) { (void)stream; /* unused parameter */ return paCanNotReadFromACallbackStream; } signed long PaUtil_DummyGetWriteAvailable( PaStream* stream ) { (void)stream; /* unused parameter */ return paCanNotWriteToACallbackStream; } double PaUtil_DummyGetCpuLoad( PaStream* stream ) { (void)stream; /* unused parameter */ return 0.0; } praat-6.0.04/external/portaudio2007/pa_stream.h000066400000000000000000000161111261542461700212050ustar00rootroot00000000000000#ifndef PA_STREAM_H #define PA_STREAM_H /* * $Id: pa_stream.h 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library * stream interface * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Interface used by pa_front to virtualize functions which operate on streams. */ #include "portaudio.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define PA_STREAM_MAGIC (0x18273645) /** A structure representing an (abstract) interface to a host API. Contains pointers to functions which implement the interface. All PaStreamInterface functions are guaranteed to be called with a non-null, valid stream parameter. */ typedef struct { PaError (*Close)( PaStream* stream ); PaError (*Start)( PaStream *stream ); PaError (*Stop)( PaStream *stream ); PaError (*Abort)( PaStream *stream ); PaError (*IsStopped)( PaStream *stream ); PaError (*IsActive)( PaStream *stream ); PaTime (*GetTime)( PaStream *stream ); double (*GetCpuLoad)( PaStream* stream ); PaError (*Read)( PaStream* stream, void *buffer, unsigned long frames ); PaError (*Write)( PaStream* stream, const void *buffer, unsigned long frames ); signed long (*GetReadAvailable)( PaStream* stream ); signed long (*GetWriteAvailable)( PaStream* stream ); } PaUtilStreamInterface; /** Initialize the fields of a PaUtilStreamInterface structure. */ void PaUtil_InitializeStreamInterface( PaUtilStreamInterface *streamInterface, PaError (*Close)( PaStream* ), PaError (*Start)( PaStream* ), PaError (*Stop)( PaStream* ), PaError (*Abort)( PaStream* ), PaError (*IsStopped)( PaStream* ), PaError (*IsActive)( PaStream* ), PaTime (*GetTime)( PaStream* ), double (*GetCpuLoad)( PaStream* ), PaError (*Read)( PaStream* stream, void *buffer, unsigned long frames ), PaError (*Write)( PaStream* stream, const void *buffer, unsigned long frames ), signed long (*GetReadAvailable)( PaStream* stream ), signed long (*GetWriteAvailable)( PaStream* stream ) ); /** Dummy Read function for use in interfaces to a callback based streams. Pass to the Read parameter of PaUtil_InitializeStreamInterface. @return An error code indicating that the function has no effect because the stream is a callback stream. */ PaError PaUtil_DummyRead( PaStream* stream, void *buffer, unsigned long frames ); /** Dummy Write function for use in an interfaces to callback based streams. Pass to the Write parameter of PaUtil_InitializeStreamInterface. @return An error code indicating that the function has no effect because the stream is a callback stream. */ PaError PaUtil_DummyWrite( PaStream* stream, const void *buffer, unsigned long frames ); /** Dummy GetReadAvailable function for use in interfaces to callback based streams. Pass to the GetReadAvailable parameter of PaUtil_InitializeStreamInterface. @return An error code indicating that the function has no effect because the stream is a callback stream. */ signed long PaUtil_DummyGetReadAvailable( PaStream* stream ); /** Dummy GetWriteAvailable function for use in interfaces to callback based streams. Pass to the GetWriteAvailable parameter of PaUtil_InitializeStreamInterface. @return An error code indicating that the function has no effect because the stream is a callback stream. */ signed long PaUtil_DummyGetWriteAvailable( PaStream* stream ); /** Dummy GetCpuLoad function for use in an interface to a read/write stream. Pass to the GetCpuLoad parameter of PaUtil_InitializeStreamInterface. @return Returns 0. */ double PaUtil_DummyGetCpuLoad( PaStream* stream ); /** Non host specific data for a stream. This data is used by pa_front to forward to the appropriate functions in the streamInterface structure. */ typedef struct PaUtilStreamRepresentation { unsigned long magic; /**< set to PA_STREAM_MAGIC */ struct PaUtilStreamRepresentation *nextOpenStream; /**< field used by multi-api code */ PaUtilStreamInterface *streamInterface; PaStreamCallback *streamCallback; PaStreamFinishedCallback *streamFinishedCallback; void *userData; PaStreamInfo streamInfo; } PaUtilStreamRepresentation; /** Initialize a PaUtilStreamRepresentation structure. @see PaUtil_InitializeStreamRepresentation */ void PaUtil_InitializeStreamRepresentation( PaUtilStreamRepresentation *streamRepresentation, PaUtilStreamInterface *streamInterface, PaStreamCallback *streamCallback, void *userData ); /** Clean up a PaUtilStreamRepresentation structure previously initialized by a call to PaUtil_InitializeStreamRepresentation. @see PaUtil_InitializeStreamRepresentation */ void PaUtil_TerminateStreamRepresentation( PaUtilStreamRepresentation *streamRepresentation ); /** Check that the stream pointer is valid. @return Returns paNoError if the stream pointer appears to be OK, otherwise returns an error indicating the cause of failure. */ PaError PaUtil_ValidateStreamPointer( PaStream *stream ); /** Cast an opaque stream pointer into a pointer to a PaUtilStreamRepresentation. @see PaUtilStreamRepresentation */ #define PA_STREAM_REP( stream )\ ((PaUtilStreamRepresentation*) (stream) ) /** Cast an opaque stream pointer into a pointer to a PaUtilStreamInterface. @see PaUtilStreamRepresentation, PaUtilStreamInterface */ #define PA_STREAM_INTERFACE( stream )\ PA_STREAM_REP( (stream) )->streamInterface #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_STREAM_H */ praat-6.0.04/external/portaudio2007/pa_trace.c000066400000000000000000000062431261542461700210100ustar00rootroot00000000000000/* * $Id: pa_trace.c 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library Trace Facility * Store trace information in real-time for later printing. * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2000 Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Event trace mechanism for debugging. */ #include #include #include #include "pa_trace.h" #if PA_TRACE_REALTIME_EVENTS static char *traceTextArray[PA_MAX_TRACE_RECORDS]; static int traceIntArray[PA_MAX_TRACE_RECORDS]; static int traceIndex = 0; static int traceBlock = 0; /*********************************************************************/ void PaUtil_ResetTraceMessages() { traceIndex = 0; } /*********************************************************************/ void PaUtil_DumpTraceMessages() { int i; int messageCount = (traceIndex < PA_MAX_TRACE_RECORDS) ? traceIndex : PA_MAX_TRACE_RECORDS; printf("DumpTraceMessages: traceIndex = %d\n", traceIndex ); for( i=0; i. */ #include typedef int16_t PaInt16; typedef uint16_t PaUint16; typedef int32_t PaInt32; typedef uint32_t PaUint32; /* PA_VALIDATE_TYPE_SIZES compares the size of the integer types at runtime to ensure that PortAudio was configured correctly, and raises an assertion if they don't match the expected values. must be included in the context in which this macro is used. */ #define PA_VALIDATE_TYPE_SIZES \ { \ assert( "PortAudio: type sizes are not correct in pa_types.h" && sizeof( PaUint16 ) == 2 ); \ assert( "PortAudio: type sizes are not correct in pa_types.h" && sizeof( PaInt16 ) == 2 ); \ assert( "PortAudio: type sizes are not correct in pa_types.h" && sizeof( PaUint32 ) == 4 ); \ assert( "PortAudio: type sizes are not correct in pa_types.h" && sizeof( PaInt32 ) == 4 ); \ } #endif /* PA_TYPES_H */ praat-6.0.04/external/portaudio2007/pa_unix_hostapis.c000066400000000000000000000051351261542461700226060ustar00rootroot00000000000000#ifdef UNIX /* * $Id: pa_unix_hostapis.c 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library UNIX initialization table * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup unix_src */ #include "pa_hostapi.h" PaError PaJack_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaAlsa_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaOSS_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); /* Added for IRIX, Pieter, oct 2, 2003: */ PaError PaSGI_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); /* Linux AudioScience HPI */ PaError PaAsiHpi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaUtilHostApiInitializer *paHostApiInitializers[] = { #if defined (linux) && defined (ALSA) PaAlsa_Initialize, #elif defined (sgi) PaSGI_Initialize, #else //PaOSS_Initialize, #endif 0 /* NULL terminated array */ }; int paDefaultHostApiIndex = 0; #endif praat-6.0.04/external/portaudio2007/pa_unix_oss.c000066400000000000000000002047561261542461700215720ustar00rootroot00000000000000/* * $Id: pa_unix_oss.c 1296 2007-10-28 22:43:50Z aknudsen $ * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * OSS implementation by: * Douglas Repetto * Phil Burk * Dominic Mazzoni * Arve Knudsen * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostapi_src */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_SYS_SOUNDCARD_H # include # define DEVICE_NAME_BASE "/dev/dsp" #elif defined(HAVE_LINUX_SOUNDCARD_H) # include # define DEVICE_NAME_BASE "/dev/dsp" #elif defined(HAVE_MACHINE_SOUNDCARD_H) # include /* JH20010905 */ # define DEVICE_NAME_BASE "/dev/audio" #else # error No sound card header file #endif #include "portaudio.h" #include "pa_util.h" #include "pa_allocation.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_cpuload.h" #include "pa_process.h" #include "pa_unix_util.h" #include "pa_debugprint.h" static int sysErr_; static pthread_t mainThread_; /* Check return value of system call, and map it to PaError */ #define ENSURE_(expr, code) \ do { \ if( UNLIKELY( (sysErr_ = (expr)) < 0 ) ) \ { \ /* PaUtil_SetLastHostErrorInfo should only be used in the main thread */ \ if( (code) == paUnanticipatedHostError && pthread_self() == mainThread_ ) \ { \ PaUtil_SetLastHostErrorInfo( paALSA, sysErr_, strerror( errno ) ); \ } \ \ PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \ result = (code); \ goto error; \ } \ } while( 0 ); #ifndef AFMT_S16_NE #define AFMT_S16_NE Get_AFMT_S16_NE() /********************************************************************* * Some versions of OSS do not define AFMT_S16_NE. So check CPU. * PowerPC is Big Endian. X86 is Little Endian. */ static int Get_AFMT_S16_NE( void ) { long testData = 1; char *ptr = (char *) &testData; int isLittle = ( *ptr == 1 ); /* Does address point to least significant byte? */ return isLittle ? AFMT_S16_LE : AFMT_S16_BE; } #endif /* PaOSSHostApiRepresentation - host api datastructure specific to this implementation */ typedef struct { PaUtilHostApiRepresentation inheritedHostApiRep; PaUtilStreamInterface callbackStreamInterface; PaUtilStreamInterface blockingStreamInterface; PaUtilAllocationGroup *allocations; PaHostApiIndex hostApiIndex; } PaOSSHostApiRepresentation; /** Per-direction structure for PaOssStream. * * Aspect StreamChannels: In case the user requests to open the same device for both capture and playback, * but with different number of channels we will have to adapt between the number of user and host * channels for at least one direction, since the configuration space is the same for both directions * of an OSS device. */ typedef struct { int fd; const char *devName; int userChannelCount, hostChannelCount; int userInterleaved; void *buffer; PaSampleFormat userFormat, hostFormat; double latency; unsigned long hostFrames, numBufs; void **userBuffers; /* For non-interleaved blocking */ } PaOssStreamComponent; /** Implementation specific representation of a PaStream. * */ typedef struct PaOssStream { PaUtilStreamRepresentation streamRepresentation; PaUtilCpuLoadMeasurer cpuLoadMeasurer; PaUtilBufferProcessor bufferProcessor; PaUtilThreading threading; int sharedDevice; unsigned long framesPerHostBuffer; int triggered; /* Have the devices been triggered yet (first start) */ int isActive; int isStopped; int lastPosPtr; double lastStreamBytes; int framesProcessed; double sampleRate; int callbackMode; int callbackStop, callbackAbort; PaOssStreamComponent *capture, *playback; unsigned long pollTimeout; sem_t semaphore; } PaOssStream; typedef enum { StreamMode_In, StreamMode_Out } StreamMode; /* prototypes for functions declared in this file */ static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); static PaError CloseStream( PaStream* stream ); static PaError StartStream( PaStream *stream ); static PaError StopStream( PaStream *stream ); static PaError AbortStream( PaStream *stream ); static PaError IsStreamStopped( PaStream *s ); static PaError IsStreamActive( PaStream *stream ); static PaTime GetStreamTime( PaStream *stream ); static double GetStreamCpuLoad( PaStream* stream ); static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ); static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ); static signed long GetStreamReadAvailable( PaStream* stream ); static signed long GetStreamWriteAvailable( PaStream* stream ); static PaError BuildDeviceList( PaOSSHostApiRepresentation *hostApi ); /** Initialize the OSS API implementation. * * This function will initialize host API datastructures and query host devices for information. * * Aspect DeviceCapabilities: Enumeration of host API devices is initiated from here * * Aspect FreeResources: If an error is encountered under way we have to free each resource allocated in this function, * this happens with the usual "error" label. */ PaError PaOSS_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) { PaError result = paNoError; PaOSSHostApiRepresentation *ossHostApi = NULL; PA_UNLESS( ossHostApi = (PaOSSHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaOSSHostApiRepresentation) ), paInsufficientMemory ); PA_UNLESS( ossHostApi->allocations = PaUtil_CreateAllocationGroup(), paInsufficientMemory ); ossHostApi->hostApiIndex = hostApiIndex; /* Initialize host API structure */ *hostApi = &ossHostApi->inheritedHostApiRep; (*hostApi)->info.structVersion = 1; (*hostApi)->info.type = paOSS; (*hostApi)->info.name = "OSS"; (*hostApi)->Terminate = Terminate; (*hostApi)->OpenStream = OpenStream; (*hostApi)->IsFormatSupported = IsFormatSupported; PA_ENSURE( BuildDeviceList( ossHostApi ) ); PaUtil_InitializeStreamInterface( &ossHostApi->callbackStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, GetStreamCpuLoad, PaUtil_DummyRead, PaUtil_DummyWrite, PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); PaUtil_InitializeStreamInterface( &ossHostApi->blockingStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, PaUtil_DummyGetCpuLoad, ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable ); mainThread_ = pthread_self(); return result; error: if( ossHostApi ) { if( ossHostApi->allocations ) { PaUtil_FreeAllAllocations( ossHostApi->allocations ); PaUtil_DestroyAllocationGroup( ossHostApi->allocations ); } PaUtil_FreeMemory( ossHostApi ); } return result; } PaError PaUtil_InitializeDeviceInfo( PaDeviceInfo *deviceInfo, const char *name, PaHostApiIndex hostApiIndex, int maxInputChannels, int maxOutputChannels, PaTime defaultLowInputLatency, PaTime defaultLowOutputLatency, PaTime defaultHighInputLatency, PaTime defaultHighOutputLatency, double defaultSampleRate, PaUtilAllocationGroup *allocations ) { PaError result = paNoError; deviceInfo->structVersion = 2; if( allocations ) { size_t len = strlen( name ) + 1; PA_UNLESS( deviceInfo->name = PaUtil_GroupAllocateMemory( allocations, len ), paInsufficientMemory ); strncpy( (char *)deviceInfo->name, name, len ); } else deviceInfo->name = name; deviceInfo->hostApi = hostApiIndex; deviceInfo->maxInputChannels = maxInputChannels; deviceInfo->maxOutputChannels = maxOutputChannels; deviceInfo->defaultLowInputLatency = defaultLowInputLatency; deviceInfo->defaultLowOutputLatency = defaultLowOutputLatency; deviceInfo->defaultHighInputLatency = defaultHighInputLatency; deviceInfo->defaultHighOutputLatency = defaultHighOutputLatency; deviceInfo->defaultSampleRate = defaultSampleRate; error: return result; } static PaError QueryDirection( const char *deviceName, StreamMode mode, double *defaultSampleRate, int *maxChannelCount, double *defaultLowLatency, double *defaultHighLatency ) { PaError result = paNoError; int numChannels, maxNumChannels; int busy = 0; int devHandle = -1; int sr; *maxChannelCount = 0; /* Default value in case this fails */ if ( (devHandle = open( deviceName, (mode == StreamMode_In ? O_RDONLY : O_WRONLY) | O_NONBLOCK )) < 0 ) { if( errno == EBUSY || errno == EAGAIN ) { PA_DEBUG(( "%s: Device %s busy\n", __FUNCTION__, deviceName )); } else { PA_DEBUG(( "%s: Can't access device: %s\n", __FUNCTION__, strerror( errno ) )); } return paDeviceUnavailable; } /* Negotiate for the maximum number of channels for this device. PLB20010927 * Consider up to 16 as the upper number of channels. * Variable maxNumChannels should contain the actual upper limit after the call. * Thanks to John Lazzaro and Heiko Purnhagen for suggestions. */ maxNumChannels = 0; for( numChannels = 1; numChannels <= 16; numChannels++ ) { int temp = numChannels; if( ioctl( devHandle, SNDCTL_DSP_CHANNELS, &temp ) < 0 ) { busy = EAGAIN == errno || EBUSY == errno; /* ioctl() failed so bail out if we already have stereo */ if( maxNumChannels >= 2 ) break; } else { /* ioctl() worked but bail out if it does not support numChannels. * We don't want to leave gaps in the numChannels supported. */ if( (numChannels > 2) && (temp != numChannels) ) break; if( temp > maxNumChannels ) maxNumChannels = temp; /* Save maximum. */ } } /* A: We're able to open a device for capture if it's busy playing back and vice versa, * but we can't configure anything */ if( 0 == maxNumChannels && busy ) { result = paDeviceUnavailable; goto error; } /* The above negotiation may fail for an old driver so try this older technique. */ if( maxNumChannels < 1 ) { int stereo = 1; if( ioctl( devHandle, SNDCTL_DSP_STEREO, &stereo ) < 0 ) { maxNumChannels = 1; } else { maxNumChannels = (stereo) ? 2 : 1; } PA_DEBUG(( "%s: use SNDCTL_DSP_STEREO, maxNumChannels = %d\n", __FUNCTION__, maxNumChannels )); } /* During channel negotiation, the last ioctl() may have failed. This can * also cause sample rate negotiation to fail. Hence the following, to return * to a supported number of channels. SG20011005 */ { /* use most reasonable default value */ int temp = PA_MIN( maxNumChannels, 2 ); ENSURE_( ioctl( devHandle, SNDCTL_DSP_CHANNELS, &temp ), paUnanticipatedHostError ); } /* Get supported sample rate closest to 44100 Hz */ if( *defaultSampleRate < 0 ) { sr = 44100; if( ioctl( devHandle, SNDCTL_DSP_SPEED, &sr ) < 0 ) { result = paUnanticipatedHostError; goto error; } *defaultSampleRate = sr; } *maxChannelCount = maxNumChannels; /* TODO */ *defaultLowLatency = 512. / *defaultSampleRate; *defaultHighLatency = 2048. / *defaultSampleRate; error: if( devHandle >= 0 ) close( devHandle ); return result; } /** Query OSS device. * * This is where PaDeviceInfo objects are constructed and filled in with relevant information. * * Aspect DeviceCapabilities: The inferred device capabilities are recorded in a PaDeviceInfo object that is constructed * in place. */ static PaError QueryDevice( char *deviceName, PaOSSHostApiRepresentation *ossApi, PaDeviceInfo **deviceInfo ) { PaError result = paNoError; double sampleRate = -1.; int maxInputChannels, maxOutputChannels; PaTime defaultLowInputLatency, defaultLowOutputLatency, defaultHighInputLatency, defaultHighOutputLatency; PaError tmpRes = paNoError; int busy = 0; *deviceInfo = NULL; /* douglas: we have to do this querying in a slightly different order. apparently some sound cards will give you different info based on their settins. e.g. a card might give you stereo at 22kHz but only mono at 44kHz. the correct order for OSS is: format, channels, sample rate */ /* Aspect StreamChannels: The number of channels supported for a device may depend on the mode it is * opened in, it may have more channels available for capture than playback and vice versa. Therefore * we will open the device in both read- and write-only mode to determine the supported number. */ if( (tmpRes = QueryDirection( deviceName, StreamMode_In, &sampleRate, &maxInputChannels, &defaultLowInputLatency, &defaultHighInputLatency )) != paNoError ) { if( tmpRes != paDeviceUnavailable ) { PA_DEBUG(( "%s: Querying device %s for capture failed!\n", __FUNCTION__, deviceName )); /* PA_ENSURE( tmpRes ); */ } ++busy; } if( (tmpRes = QueryDirection( deviceName, StreamMode_Out, &sampleRate, &maxOutputChannels, &defaultLowOutputLatency, &defaultHighOutputLatency )) != paNoError ) { if( tmpRes != paDeviceUnavailable ) { PA_DEBUG(( "%s: Querying device %s for playback failed!\n", __FUNCTION__, deviceName )); /* PA_ENSURE( tmpRes ); */ } ++busy; } assert( 0 <= busy && busy <= 2 ); if( 2 == busy ) /* Both directions are unavailable to us */ { result = paDeviceUnavailable; goto error; } PA_UNLESS( *deviceInfo = PaUtil_GroupAllocateMemory( ossApi->allocations, sizeof (PaDeviceInfo) ), paInsufficientMemory ); PA_ENSURE( PaUtil_InitializeDeviceInfo( *deviceInfo, deviceName, ossApi->hostApiIndex, maxInputChannels, maxOutputChannels, defaultLowInputLatency, defaultLowOutputLatency, defaultHighInputLatency, defaultHighOutputLatency, sampleRate, ossApi->allocations ) ); error: return result; } /** Query host devices. * * Loop over host devices and query their capabilitiesu * * Aspect DeviceCapabilities: This function calls QueryDevice on each device entry and receives a filled in PaDeviceInfo object * per device, these are placed in the host api representation's deviceInfos array. */ static PaError BuildDeviceList( PaOSSHostApiRepresentation *ossApi ) { PaError result = paNoError; PaUtilHostApiRepresentation *commonApi = &ossApi->inheritedHostApiRep; int i; int numDevices = 0, maxDeviceInfos = 1; PaDeviceInfo **deviceInfos = NULL; /* These two will be set to the first working input and output device, respectively */ commonApi->info.defaultInputDevice = paNoDevice; commonApi->info.defaultOutputDevice = paNoDevice; /* Find devices by calling QueryDevice on each * potential device names. When we find a valid one, * add it to a linked list. * A: Set an arbitrary of 100 devices, should probably be a smarter way. */ for( i = 0; i < 100; i++ ) { char deviceName[32]; PaDeviceInfo *deviceInfo; int testResult; struct stat stbuf; if( i == 0 ) snprintf(deviceName, sizeof (deviceName), "%s", DEVICE_NAME_BASE); else snprintf(deviceName, sizeof (deviceName), "%s%d", DEVICE_NAME_BASE, i); /* PA_DEBUG(("PaOSS BuildDeviceList: trying device %s\n", deviceName )); */ if( stat( deviceName, &stbuf ) < 0 ) { if( ENOENT != errno ) PA_DEBUG(( "%s: Error stat'ing %s: %s\n", __FUNCTION__, deviceName, strerror( errno ) )); continue; } if( (testResult = QueryDevice( deviceName, ossApi, &deviceInfo )) != paNoError ) { if( testResult != paDeviceUnavailable ) PA_ENSURE( testResult ); continue; } ++numDevices; if( !deviceInfos || numDevices > maxDeviceInfos ) { maxDeviceInfos *= 2; PA_UNLESS( deviceInfos = (PaDeviceInfo **) realloc( deviceInfos, maxDeviceInfos * sizeof (PaDeviceInfo *) ), paInsufficientMemory ); } { int devIdx = numDevices - 1; deviceInfos[devIdx] = deviceInfo; if( commonApi->info.defaultInputDevice == paNoDevice && deviceInfo->maxInputChannels > 0 ) commonApi->info.defaultInputDevice = devIdx; if( commonApi->info.defaultOutputDevice == paNoDevice && deviceInfo->maxOutputChannels > 0 ) commonApi->info.defaultOutputDevice = devIdx; } } /* Make an array of PaDeviceInfo pointers out of the linked list */ PA_DEBUG(("PaOSS %s: Total number of devices found: %d\n", __FUNCTION__, numDevices)); commonApi->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( ossApi->allocations, sizeof(PaDeviceInfo*) * numDevices ); memcpy( commonApi->deviceInfos, deviceInfos, numDevices * sizeof (PaDeviceInfo *) ); commonApi->info.deviceCount = numDevices; error: free( deviceInfos ); return result; } static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) { PaOSSHostApiRepresentation *ossHostApi = (PaOSSHostApiRepresentation*)hostApi; if( ossHostApi->allocations ) { PaUtil_FreeAllAllocations( ossHostApi->allocations ); PaUtil_DestroyAllocationGroup( ossHostApi->allocations ); } PaUtil_FreeMemory( ossHostApi ); } static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { PaError result = paNoError; PaDeviceIndex device; PaDeviceInfo *deviceInfo; char *deviceName; int inputChannelCount, outputChannelCount; int tempDevHandle = -1; int flags; PaSampleFormat inputSampleFormat, outputSampleFormat; if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that input device can support inputChannelCount */ if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) return paInvalidChannelCount; /* validate inputStreamInfo */ if( inputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else { inputChannelCount = 0; } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that output device can support inputChannelCount */ if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) return paInvalidChannelCount; /* validate outputStreamInfo */ if( outputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else { outputChannelCount = 0; } if (inputChannelCount == 0 && outputChannelCount == 0) return paInvalidChannelCount; /* if full duplex, make sure that they're the same device */ if (inputChannelCount > 0 && outputChannelCount > 0 && inputParameters->device != outputParameters->device) return paInvalidDevice; /* if full duplex, also make sure that they're the same number of channels */ if (inputChannelCount > 0 && outputChannelCount > 0 && inputChannelCount != outputChannelCount) return paInvalidChannelCount; /* open the device so we can do more tests */ if( inputChannelCount > 0 ) { result = PaUtil_DeviceIndexToHostApiDeviceIndex(&device, inputParameters->device, hostApi); if (result != paNoError) return result; } else { result = PaUtil_DeviceIndexToHostApiDeviceIndex(&device, outputParameters->device, hostApi); if (result != paNoError) return result; } deviceInfo = hostApi->deviceInfos[device]; deviceName = (char *)deviceInfo->name; flags = O_NONBLOCK; if (inputChannelCount > 0 && outputChannelCount > 0) flags |= O_RDWR; else if (inputChannelCount > 0) flags |= O_RDONLY; else flags |= O_WRONLY; ENSURE_( tempDevHandle = open( deviceInfo->name, flags ), paDeviceUnavailable ); /* PaOssStream_Configure will do the rest of the checking for us */ /* PA_ENSURE( PaOssStream_Configure( tempDevHandle, deviceName, outputChannelCount, &sampleRate ) ); */ /* everything succeeded! */ error: if( tempDevHandle >= 0 ) close( tempDevHandle ); return result; } /** Validate stream parameters. * * Aspect StreamChannels: We verify that the number of channels is within the allowed range for the device */ static PaError ValidateParameters( const PaStreamParameters *parameters, const PaDeviceInfo *deviceInfo, StreamMode mode ) { int maxChans; assert( parameters ); if( parameters->device == paUseHostApiSpecificDeviceSpecification ) { return paInvalidDevice; } maxChans = (mode == StreamMode_In ? deviceInfo->maxInputChannels : deviceInfo->maxOutputChannels); if( parameters->channelCount > maxChans ) { return paInvalidChannelCount; } return paNoError; } static PaError PaOssStreamComponent_Initialize( PaOssStreamComponent *component, const PaStreamParameters *parameters, int callbackMode, int fd, const char *deviceName ) { PaError result = paNoError; assert( component ); memset( component, 0, sizeof (PaOssStreamComponent) ); component->fd = fd; component->devName = deviceName; component->userChannelCount = parameters->channelCount; component->userFormat = parameters->sampleFormat; component->latency = parameters->suggestedLatency; component->userInterleaved = !(parameters->sampleFormat & paNonInterleaved); if( !callbackMode && !component->userInterleaved ) { /* Pre-allocate non-interleaved user provided buffers */ PA_UNLESS( component->userBuffers = PaUtil_AllocateMemory( sizeof (void *) * component->userChannelCount ), paInsufficientMemory ); } error: return result; } static void PaOssStreamComponent_Terminate( PaOssStreamComponent *component ) { assert( component ); if( component->fd >= 0 ) close( component->fd ); if( component->buffer ) PaUtil_FreeMemory( component->buffer ); if( component->userBuffers ) PaUtil_FreeMemory( component->userBuffers ); PaUtil_FreeMemory( component ); } static PaError ModifyBlocking( int fd, int blocking ) { PaError result = paNoError; int fflags; ENSURE_( fflags = fcntl( fd, F_GETFL ), paUnanticipatedHostError ); if( blocking ) fflags &= ~O_NONBLOCK; else fflags |= O_NONBLOCK; ENSURE_( fcntl( fd, F_SETFL, fflags ), paUnanticipatedHostError ); error: return result; } static PaError OpenDevices( const char *idevName, const char *odevName, int *idev, int *odev ) { PaError result = paNoError; int flags = O_NONBLOCK, duplex = 0; int enableBits = 0; *idev = *odev = -1; if( idevName && odevName ) { duplex = 1; flags |= O_RDWR; } else if( idevName ) flags |= O_RDONLY; else flags |= O_WRONLY; /* open first in nonblocking mode, in case it's busy... * A: then unset the non-blocking attribute */ assert( flags & O_NONBLOCK ); if( idevName ) { ENSURE_( *idev = open( idevName, flags ), paDeviceUnavailable ); PA_ENSURE( ModifyBlocking( *idev, 1 ) ); /* Blocking */ /* Initially disable */ enableBits = ~PCM_ENABLE_INPUT; ENSURE_( ioctl( *idev, SNDCTL_DSP_SETTRIGGER, &enableBits ), paUnanticipatedHostError ); } if( odevName ) { if( !idevName ) { ENSURE_( *odev = open( odevName, flags ), paDeviceUnavailable ); PA_ENSURE( ModifyBlocking( *odev, 1 ) ); /* Blocking */ /* Initially disable */ enableBits = ~PCM_ENABLE_OUTPUT; ENSURE_( ioctl( *odev, SNDCTL_DSP_SETTRIGGER, &enableBits ), paUnanticipatedHostError ); } else { ENSURE_( *odev = dup( *idev ), paUnanticipatedHostError ); } } error: return result; } static PaError PaOssStream_Initialize( PaOssStream *stream, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, PaStreamCallback callback, void *userData, PaStreamFlags streamFlags, PaOSSHostApiRepresentation *ossApi ) { PaError result = paNoError; int idev, odev; PaUtilHostApiRepresentation *hostApi = &ossApi->inheritedHostApiRep; const char *idevName = NULL, *odevName = NULL; assert( stream ); memset( stream, 0, sizeof (PaOssStream) ); stream->isStopped = 1; PA_ENSURE( PaUtil_InitializeThreading( &stream->threading ) ); if( inputParameters && outputParameters ) { if( inputParameters->device == outputParameters->device ) stream->sharedDevice = 1; } if( inputParameters ) idevName = hostApi->deviceInfos[inputParameters->device]->name; if( outputParameters ) odevName = hostApi->deviceInfos[outputParameters->device]->name; PA_ENSURE( OpenDevices( idevName, odevName, &idev, &odev ) ); if( inputParameters ) { PA_UNLESS( stream->capture = PaUtil_AllocateMemory( sizeof (PaOssStreamComponent) ), paInsufficientMemory ); PA_ENSURE( PaOssStreamComponent_Initialize( stream->capture, inputParameters, callback != NULL, idev, idevName ) ); } if( outputParameters ) { PA_UNLESS( stream->playback = PaUtil_AllocateMemory( sizeof (PaOssStreamComponent) ), paInsufficientMemory ); PA_ENSURE( PaOssStreamComponent_Initialize( stream->playback, outputParameters, callback != NULL, odev, odevName ) ); } if( callback != NULL ) { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &ossApi->callbackStreamInterface, callback, userData ); stream->callbackMode = 1; } else { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &ossApi->blockingStreamInterface, callback, userData ); } ENSURE_( sem_init( &stream->semaphore, 0, 0 ), paInternalError ); error: return result; } static void PaOssStream_Terminate( PaOssStream *stream ) { assert( stream ); PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); PaUtil_TerminateThreading( &stream->threading ); if( stream->capture ) PaOssStreamComponent_Terminate( stream->capture ); if( stream->playback ) PaOssStreamComponent_Terminate( stream->playback ); sem_destroy( &stream->semaphore ); PaUtil_FreeMemory( stream ); } /** Translate from PA format to OSS native. * */ static PaError Pa2OssFormat( PaSampleFormat paFormat, int *ossFormat ) { switch( paFormat ) { case paUInt8: *ossFormat = AFMT_U8; break; case paInt8: *ossFormat = AFMT_S8; break; case paInt16: *ossFormat = AFMT_S16_NE; break; default: return paInternalError; /* This shouldn't happen */ } return paNoError; } /** Return the PA-compatible formats that this device can support. * */ static PaError GetAvailableFormats( PaOssStreamComponent *component, PaSampleFormat *availableFormats ) { PaError result = paNoError; int mask = 0; PaSampleFormat frmts = 0; ENSURE_( ioctl( component->fd, SNDCTL_DSP_GETFMTS, &mask ), paUnanticipatedHostError ); if( mask & AFMT_U8 ) frmts |= paUInt8; if( mask & AFMT_S8 ) frmts |= paInt8; if( mask & AFMT_S16_NE ) frmts |= paInt16; else result = paSampleFormatNotSupported; *availableFormats = frmts; error: return result; } static unsigned int PaOssStreamComponent_FrameSize( PaOssStreamComponent *component ) { return Pa_GetSampleSize( component->hostFormat ) * component->hostChannelCount; } /** Buffer size in bytes. * */ static unsigned long PaOssStreamComponent_BufferSize( PaOssStreamComponent *component ) { return PaOssStreamComponent_FrameSize( component ) * component->hostFrames * component->numBufs; } static int CalcHigherLogTwo( int n ) { int log2 = 0; while( (1<userChannelCount; int frgmt; int numBufs; int bytesPerBuf; unsigned long bufSz; unsigned long fragSz; audio_buf_info bufInfo; /* We may have a situation where only one component (the master) is configured, if both point to the same device. * In that case, the second component will copy settings from the other */ if( !master ) { /* Aspect BufferSettings: If framesPerBuffer is unspecified we have to infer a suitable fragment size. * The hardware need not respect the requested fragment size, so we may have to adapt. */ if( framesPerBuffer == paFramesPerBufferUnspecified ) { bufSz = (unsigned long)(component->latency * sampleRate); fragSz = bufSz / 4; } else { fragSz = framesPerBuffer; bufSz = (unsigned long)(component->latency * sampleRate) + fragSz; /* Latency + 1 buffer */ } PA_ENSURE( GetAvailableFormats( component, &availableFormats ) ); hostFormat = PaUtil_SelectClosestAvailableFormat( availableFormats, component->userFormat ); /* OSS demands at least 2 buffers, and 16 bytes per buffer */ numBufs = (int)PA_MAX( bufSz / fragSz, 2 ); bytesPerBuf = PA_MAX( fragSz * Pa_GetSampleSize( hostFormat ) * chans, 16 ); /* The fragment parameters are encoded like this: * Most significant byte: number of fragments * Least significant byte: exponent of fragment size (i.e., for 256, 8) */ frgmt = (numBufs << 16) + (CalcHigherLogTwo( bytesPerBuf ) & 0xffff); ENSURE_( ioctl( component->fd, SNDCTL_DSP_SETFRAGMENT, &frgmt ), paUnanticipatedHostError ); /* A: according to the OSS programmer's guide parameters should be set in this order: * format, channels, rate */ /* This format should be deemed good before we get this far */ PA_ENSURE( Pa2OssFormat( hostFormat, &temp ) ); nativeFormat = temp; ENSURE_( ioctl( component->fd, SNDCTL_DSP_SETFMT, &temp ), paUnanticipatedHostError ); PA_UNLESS( temp == nativeFormat, paInternalError ); /* try to set the number of channels */ ENSURE_( ioctl( component->fd, SNDCTL_DSP_CHANNELS, &chans ), paSampleFormatNotSupported ); /* XXX: Should be paInvalidChannelCount? */ /* It's possible that the minimum number of host channels is greater than what the user requested */ PA_UNLESS( chans >= component->userChannelCount, paInvalidChannelCount ); /* try to set the sample rate */ ENSURE_( ioctl( component->fd, SNDCTL_DSP_SPEED, &sr ), paInvalidSampleRate ); /* reject if there's no sample rate within 1% of the one requested */ if( (fabs( sampleRate - sr ) / sampleRate) > 0.01 ) { PA_DEBUG(("%s: Wanted %f, closest sample rate was %d\n", __FUNCTION__, sampleRate, sr )); PA_ENSURE( paInvalidSampleRate ); } ENSURE_( ioctl( component->fd, streamMode == StreamMode_In ? SNDCTL_DSP_GETISPACE : SNDCTL_DSP_GETOSPACE, &bufInfo ), paUnanticipatedHostError ); component->numBufs = bufInfo.fragstotal; /* This needs to be the last ioctl call before the first read/write, according to the OSS programmer's guide */ ENSURE_( ioctl( component->fd, SNDCTL_DSP_GETBLKSIZE, &bytesPerBuf ), paUnanticipatedHostError ); component->hostFrames = bytesPerBuf / Pa_GetSampleSize( hostFormat ) / chans; component->hostChannelCount = chans; component->hostFormat = hostFormat; } else { component->hostFormat = master->hostFormat; component->hostFrames = master->hostFrames; component->hostChannelCount = master->hostChannelCount; component->numBufs = master->numBufs; } PA_UNLESS( component->buffer = PaUtil_AllocateMemory( PaOssStreamComponent_BufferSize( component ) ), paInsufficientMemory ); error: return result; } static PaError PaOssStreamComponent_Read( PaOssStreamComponent *component, unsigned long *frames ) { PaError result = paNoError; size_t len = *frames * PaOssStreamComponent_FrameSize( component ); ssize_t bytesRead; ENSURE_( bytesRead = read( component->fd, component->buffer, len ), paUnanticipatedHostError ); *frames = bytesRead / PaOssStreamComponent_FrameSize( component ); /* TODO: Handle condition where number of frames read doesn't equal number of frames requested */ error: return result; } static PaError PaOssStreamComponent_Write( PaOssStreamComponent *component, unsigned long *frames ) { PaError result = paNoError; size_t len = *frames * PaOssStreamComponent_FrameSize( component ); ssize_t bytesWritten; ENSURE_( bytesWritten = write( component->fd, component->buffer, len ), paUnanticipatedHostError ); *frames = bytesWritten / PaOssStreamComponent_FrameSize( component ); /* TODO: Handle condition where number of frames written doesn't equal number of frames requested */ error: return result; } /** Configure the stream according to input/output parameters. * * Aspect StreamChannels: The minimum number of channels supported by the device may exceed that requested by * the user, if so we'll record the actual number of host channels and adapt later. */ static PaError PaOssStream_Configure( PaOssStream *stream, double sampleRate, unsigned long framesPerBuffer, double *inputLatency, double *outputLatency ) { PaError result = paNoError; int duplex = stream->capture && stream->playback; unsigned long framesPerHostBuffer = 0; /* We should request full duplex first thing after opening the device */ if( duplex && stream->sharedDevice ) ENSURE_( ioctl( stream->capture->fd, SNDCTL_DSP_SETDUPLEX, 0 ), paUnanticipatedHostError ); if( stream->capture ) { PaOssStreamComponent *component = stream->capture; PA_ENSURE( PaOssStreamComponent_Configure( component, sampleRate, framesPerBuffer, StreamMode_In, NULL ) ); assert( component->hostChannelCount > 0 ); assert( component->hostFrames > 0 ); *inputLatency = component->hostFrames * (component->numBufs - 1) / sampleRate; } if( stream->playback ) { PaOssStreamComponent *component = stream->playback, *master = stream->sharedDevice ? stream->capture : NULL; PA_ENSURE( PaOssStreamComponent_Configure( component, sampleRate, framesPerBuffer, StreamMode_Out, master ) ); assert( component->hostChannelCount > 0 ); assert( component->hostFrames > 0 ); *outputLatency = component->hostFrames * (component->numBufs - 1) / sampleRate; } if( duplex ) framesPerHostBuffer = PA_MIN( stream->capture->hostFrames, stream->playback->hostFrames ); else if( stream->capture ) framesPerHostBuffer = stream->capture->hostFrames; else if( stream->playback ) framesPerHostBuffer = stream->playback->hostFrames; stream->framesPerHostBuffer = framesPerHostBuffer; stream->pollTimeout = (int) ceil( 1e6 * framesPerHostBuffer / sampleRate ); /* Period in usecs, rounded up */ stream->sampleRate = stream->streamRepresentation.streamInfo.sampleRate = sampleRate; error: return result; } /* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */ /** Open a PA OSS stream. * * Aspect StreamChannels: The number of channels is specified per direction (in/out), and can differ between the * two. However, OSS doesn't support separate configuration spaces for capture and playback so if both * directions are the same device we will demand the same number of channels. The number of channels can range * from 1 to the maximum supported by the device. * * Aspect BufferSettings: If framesPerBuffer != paFramesPerBufferUnspecified the number of frames per callback * must reflect this, in addition the host latency per device should approximate the corresponding * suggestedLatency. Based on these constraints we need to determine a number of frames per host buffer that * both capture and playback can agree on (they can be different devices), the buffer processor can adapt * between host and user buffer size, but the ratio should preferably be integral. */ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ) { PaError result = paNoError; PaOSSHostApiRepresentation *ossHostApi = (PaOSSHostApiRepresentation*)hostApi; PaOssStream *stream = NULL; int inputChannelCount = 0, outputChannelCount = 0; PaSampleFormat inputSampleFormat = 0, outputSampleFormat = 0, inputHostFormat = 0, outputHostFormat = 0; const PaDeviceInfo *inputDeviceInfo = 0, *outputDeviceInfo = 0; int bpInitialized = 0; double inLatency = 0., outLatency = 0.; int i = 0; /* validate platform specific flags */ if( (streamFlags & paPlatformSpecificFlags) != 0 ) return paInvalidFlag; /* unexpected platform specific flag */ if( inputParameters ) { /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ inputDeviceInfo = hostApi->deviceInfos[inputParameters->device]; PA_ENSURE( ValidateParameters( inputParameters, inputDeviceInfo, StreamMode_In ) ); inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; } if( outputParameters ) { outputDeviceInfo = hostApi->deviceInfos[outputParameters->device]; PA_ENSURE( ValidateParameters( outputParameters, outputDeviceInfo, StreamMode_Out ) ); outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; } /* Aspect StreamChannels: We currently demand that number of input and output channels are the same, if the same * device is opened for both directions */ if( inputChannelCount > 0 && outputChannelCount > 0 ) { if( inputParameters->device == outputParameters->device ) { if( inputParameters->channelCount != outputParameters->channelCount ) return paInvalidChannelCount; } } /* Round framesPerBuffer to the next power-of-two to make OSS happy. */ if( framesPerBuffer != paFramesPerBufferUnspecified ) { framesPerBuffer &= INT_MAX; for (i = 1; framesPerBuffer > i; i <<= 1) ; framesPerBuffer = i; } /* allocate and do basic initialization of the stream structure */ PA_UNLESS( stream = (PaOssStream*)PaUtil_AllocateMemory( sizeof(PaOssStream) ), paInsufficientMemory ); PA_ENSURE( PaOssStream_Initialize( stream, inputParameters, outputParameters, streamCallback, userData, streamFlags, ossHostApi ) ); PA_ENSURE( PaOssStream_Configure( stream, sampleRate, framesPerBuffer, &inLatency, &outLatency ) ); PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate ); if( inputParameters ) { inputHostFormat = stream->capture->hostFormat; stream->streamRepresentation.streamInfo.inputLatency = inLatency + PaUtil_GetBufferProcessorInputLatency( &stream->bufferProcessor ) / sampleRate; } if( outputParameters ) { outputHostFormat = stream->playback->hostFormat; stream->streamRepresentation.streamInfo.outputLatency = outLatency + PaUtil_GetBufferProcessorOutputLatency( &stream->bufferProcessor ) / sampleRate; } /* Initialize buffer processor with fixed host buffer size. * Aspect StreamSampleFormat: Here we commit the user and host sample formats, PA infrastructure will * convert between the two. */ PA_ENSURE( PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, inputChannelCount, inputSampleFormat, inputHostFormat, outputChannelCount, outputSampleFormat, outputHostFormat, sampleRate, streamFlags, framesPerBuffer, stream->framesPerHostBuffer, paUtilFixedHostBufferSize, streamCallback, userData ) ); bpInitialized = 1; *s = (PaStream*)stream; return result; error: if( bpInitialized ) PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); if( stream ) PaOssStream_Terminate( stream ); return result; } /*! Poll on I/O filedescriptors. Poll till we've determined there's data for read or write. In the full-duplex case, we don't want to hang around forever waiting for either input or output frames, so whenever we have a timed out filedescriptor we check if we're nearing under/overrun for the other direction (critical limit set at one buffer). If so, we exit the waiting state, and go on with what we got. We align the number of frames on a host buffer boundary because it is possible that the buffer size differs for the two directions and the host buffer size is a compromise between the two. */ static PaError PaOssStream_WaitForFrames( PaOssStream *stream, unsigned long *frames ) { PaError result = paNoError; int pollPlayback = 0, pollCapture = 0; int captureAvail = INT_MAX, playbackAvail = INT_MAX, commonAvail; audio_buf_info bufInfo; /* int ofs = 0, nfds = stream->nfds; */ fd_set readFds, writeFds; int nfds = 0; struct timeval selectTimeval = {0, 0}; unsigned long timeout = stream->pollTimeout; /* In usecs */ int captureFd = -1, playbackFd = -1; assert( stream ); assert( frames ); if( stream->capture ) { pollCapture = 1; captureFd = stream->capture->fd; /* stream->capture->pfd->events = POLLIN; */ } if( stream->playback ) { pollPlayback = 1; playbackFd = stream->playback->fd; /* stream->playback->pfd->events = POLLOUT; */ } FD_ZERO( &readFds ); FD_ZERO( &writeFds ); while( pollPlayback || pollCapture ) { pthread_testcancel(); /* select may modify the timeout parameter */ selectTimeval.tv_usec = timeout; nfds = 0; if( pollCapture ) { FD_SET( captureFd, &readFds ); nfds = captureFd + 1; } if( pollPlayback ) { FD_SET( playbackFd, &writeFds ); nfds = PA_MAX( nfds, playbackFd + 1 ); } ENSURE_( select( nfds, &readFds, &writeFds, NULL, &selectTimeval ), paUnanticipatedHostError ); /* if( poll( stream->pfds + ofs, nfds, stream->pollTimeout ) < 0 ) { ENSURE_( -1, paUnanticipatedHostError ); } */ pthread_testcancel(); if( pollCapture ) { if( FD_ISSET( captureFd, &readFds ) ) { FD_CLR( captureFd, &readFds ); pollCapture = 0; } /* if( stream->capture->pfd->revents & POLLIN ) { --nfds; ++ofs; pollCapture = 0; } */ else if( stream->playback ) /* Timed out, go on with playback? */ { /*PA_DEBUG(( "%s: Trying to poll again for capture frames, pollTimeout: %d\n", __FUNCTION__, stream->pollTimeout ));*/ } } if( pollPlayback ) { if( FD_ISSET( playbackFd, &writeFds ) ) { FD_CLR( playbackFd, &writeFds ); pollPlayback = 0; } /* if( stream->playback->pfd->revents & POLLOUT ) { --nfds; pollPlayback = 0; } */ else if( stream->capture ) /* Timed out, go on with capture? */ { /*PA_DEBUG(( "%s: Trying to poll again for playback frames, pollTimeout: %d\n\n", __FUNCTION__, stream->pollTimeout ));*/ } } } if( stream->capture ) { ENSURE_( ioctl( captureFd, SNDCTL_DSP_GETISPACE, &bufInfo ), paUnanticipatedHostError ); captureAvail = bufInfo.fragments * stream->capture->hostFrames; if( !captureAvail ) PA_DEBUG(( "%s: captureAvail: 0\n", __FUNCTION__ )); captureAvail = captureAvail == 0 ? INT_MAX : captureAvail; /* Disregard if zero */ } if( stream->playback ) { ENSURE_( ioctl( playbackFd, SNDCTL_DSP_GETOSPACE, &bufInfo ), paUnanticipatedHostError ); playbackAvail = bufInfo.fragments * stream->playback->hostFrames; if( !playbackAvail ) { PA_DEBUG(( "%s: playbackAvail: 0\n", __FUNCTION__ )); } playbackAvail = playbackAvail == 0 ? INT_MAX : playbackAvail; /* Disregard if zero */ } commonAvail = PA_MIN( captureAvail, playbackAvail ); if( commonAvail == INT_MAX ) commonAvail = 0; commonAvail -= commonAvail % stream->framesPerHostBuffer; assert( commonAvail != INT_MAX ); assert( commonAvail >= 0 ); *frames = commonAvail; error: return result; } /** Prepare stream for capture/playback. * * In order to synchronize capture and playback properly we use the SETTRIGGER command. */ static PaError PaOssStream_Prepare( PaOssStream *stream ) { PaError result = paNoError; int enableBits = 0; if( stream->triggered ) return result; if( stream->playback ) { size_t bufSz = PaOssStreamComponent_BufferSize( stream->playback ); memset( stream->playback->buffer, 0, bufSz ); /* Looks like we have to turn off blocking before we try this, but if we don't fill the buffer * OSS will complain. */ PA_ENSURE( ModifyBlocking( stream->playback->fd, 0 ) ); while (1) { if( write( stream->playback->fd, stream->playback->buffer, bufSz ) < 0 ) break; } PA_ENSURE( ModifyBlocking( stream->playback->fd, 1 ) ); } if( stream->sharedDevice ) { enableBits = PCM_ENABLE_INPUT | PCM_ENABLE_OUTPUT; ENSURE_( ioctl( stream->capture->fd, SNDCTL_DSP_SETTRIGGER, &enableBits ), paUnanticipatedHostError ); } else { if( stream->capture ) { enableBits = PCM_ENABLE_INPUT; ENSURE_( ioctl( stream->capture->fd, SNDCTL_DSP_SETTRIGGER, &enableBits ), paUnanticipatedHostError ); } if( stream->playback ) { enableBits = PCM_ENABLE_OUTPUT; ENSURE_( ioctl( stream->playback->fd, SNDCTL_DSP_SETTRIGGER, &enableBits ), paUnanticipatedHostError ); } } /* Ok, we have triggered the stream */ stream->triggered = 1; error: return result; } /** Stop audio processing * */ static PaError PaOssStream_Stop( PaOssStream *stream, int abort ) { PaError result = paNoError; /* Looks like the only safe way to stop audio without reopening the device is SNDCTL_DSP_POST. * Also disable capture/playback till the stream is started again */ if( stream->capture ) { ENSURE_( ioctl( stream->capture->fd, SNDCTL_DSP_POST, 0 ), paUnanticipatedHostError ); } if( stream->playback && !stream->sharedDevice ) { ENSURE_( ioctl( stream->playback->fd, SNDCTL_DSP_POST, 0 ), paUnanticipatedHostError ); } error: return result; } /** Clean up after thread exit. * * Aspect StreamState: If the user has registered a streamFinishedCallback it will be called here */ static void OnExit( void *data ) { PaOssStream *stream = (PaOssStream *) data; assert( data ); PaUtil_ResetCpuLoadMeasurer( &stream->cpuLoadMeasurer ); PaOssStream_Stop( stream, stream->callbackAbort ); PA_DEBUG(( "OnExit: Stoppage\n" )); /* Eventually notify user all buffers have played */ if( stream->streamRepresentation.streamFinishedCallback ) stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); stream->callbackAbort = 0; /* Clear state */ stream->isActive = 0; } static PaError SetUpBuffers( PaOssStream *stream, unsigned long framesAvail ) { PaError result = paNoError; if( stream->capture ) { PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, 0, stream->capture->buffer, stream->capture->hostChannelCount ); PaUtil_SetInputFrameCount( &stream->bufferProcessor, framesAvail ); } if( stream->playback ) { PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, 0, stream->playback->buffer, stream->playback->hostChannelCount ); PaUtil_SetOutputFrameCount( &stream->bufferProcessor, framesAvail ); } return result; } /** Thread procedure for callback processing. * * Aspect StreamState: StartStream will wait on this to initiate audio processing, useful in case the * callback should be used for buffer priming. When the stream is cancelled a separate function will * take care of the transition to the Callback Finished state (the stream isn't considered Stopped * before StopStream() or AbortStream() are called). */ static void *PaOSS_AudioThreadProc( void *userData ) { PaError result = paNoError; PaOssStream *stream = (PaOssStream*)userData; unsigned long framesAvail = 0, framesProcessed = 0; int callbackResult = paContinue; int triggered = stream->triggered; /* See if SNDCTL_DSP_TRIGGER has been issued already */ int initiateProcessing = triggered; /* Already triggered? */ PaStreamCallbackFlags cbFlags = 0; /* We might want to keep state across iterations */ PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /* TODO: IMPLEMENT ME */ /* #if ( SOUND_VERSION > 0x030904 ) audio_errinfo errinfo; #endif */ assert( stream ); pthread_cleanup_push( &OnExit, stream ); /* Execute OnExit when exiting */ /* The first time the stream is started we use SNDCTL_DSP_TRIGGER to accurately start capture and * playback in sync, when the stream is restarted after being stopped we simply start by reading/ * writing. */ PA_ENSURE( PaOssStream_Prepare( stream ) ); /* If we are to initiate processing implicitly by reading/writing data, we start off in blocking mode */ if( initiateProcessing ) { /* Make sure devices are in blocking mode */ if( stream->capture ) ModifyBlocking( stream->capture->fd, 1 ); if( stream->playback ) ModifyBlocking( stream->playback->fd, 1 ); } while( 1 ) { pthread_testcancel(); if( stream->callbackStop && callbackResult == paContinue ) { PA_DEBUG(( "Setting callbackResult to paComplete\n" )); callbackResult = paComplete; } /* Aspect StreamState: Because of the messy OSS scheme we can't explicitly trigger device start unless * the stream has been recently started, we will have to go right ahead and read/write in blocking * fashion to trigger operation. Therefore we begin with processing one host buffer before we switch * to non-blocking mode. */ if( !initiateProcessing ) { /* Wait on available frames */ PA_ENSURE( PaOssStream_WaitForFrames( stream, &framesAvail ) ); assert( framesAvail % stream->framesPerHostBuffer == 0 ); } else { framesAvail = stream->framesPerHostBuffer; } while( framesAvail > 0 ) { unsigned long frames = framesAvail; pthread_testcancel(); PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); /* Read data */ if ( stream->capture ) { PA_ENSURE( PaOssStreamComponent_Read( stream->capture, &frames ) ); if( frames < framesAvail ) { PA_DEBUG(( "Read %lu less frames than requested\n", framesAvail - frames )); framesAvail = frames; } } #if ( SOUND_VERSION >= 0x030904 ) /* Check with OSS to see if there have been any under/overruns since last time we checked. */ /* if( ioctl( stream->deviceHandle, SNDCTL_DSP_GETERROR, &errinfo ) >= 0 ) { if( errinfo.play_underruns ) cbFlags |= paOutputUnderflow ; if( errinfo.record_underruns ) cbFlags |= paInputUnderflow ; } else PA_DEBUG(( "SNDCTL_DSP_GETERROR command failed: %s\n", strerror( errno ) )); */ #endif PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, cbFlags ); cbFlags = 0; PA_ENSURE( SetUpBuffers( stream, framesAvail ) ); framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult ); assert( framesProcessed == framesAvail ); PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed ); if ( stream->playback ) { frames = framesAvail; PA_ENSURE( PaOssStreamComponent_Write( stream->playback, &frames ) ); if( frames < framesAvail ) { /* TODO: handle bytesWritten != bytesRequested (slippage?) */ PA_DEBUG(( "Wrote %lu less frames than requested\n", framesAvail - frames )); } } framesAvail -= framesProcessed; stream->framesProcessed += framesProcessed; if( callbackResult != paContinue ) break; } if( initiateProcessing || !triggered ) { /* Non-blocking */ if( stream->capture ) PA_ENSURE( ModifyBlocking( stream->capture->fd, 0 ) ); if( stream->playback && !stream->sharedDevice ) PA_ENSURE( ModifyBlocking( stream->playback->fd, 0 ) ); initiateProcessing = 0; sem_post( &stream->semaphore ); } if( callbackResult != paContinue ) { stream->callbackAbort = callbackResult == paAbort; if( stream->callbackAbort || PaUtil_IsBufferProcessorOutputEmpty( &stream->bufferProcessor ) ) break; } } pthread_cleanup_pop( 1 ); error: pthread_exit( NULL ); } /** Close the stream. * */ static PaError CloseStream( PaStream* s ) { PaError result = paNoError; PaOssStream *stream = (PaOssStream*)s; assert( stream ); PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); PaOssStream_Terminate( stream ); return result; } /** Start the stream. * * Aspect StreamState: After returning, the stream shall be in the Active state, implying that an eventual * callback will be repeatedly called in a separate thread. If a separate thread is started this function * will block untill it has started processing audio, otherwise audio processing is started directly. */ static PaError StartStream( PaStream *s ) { PaError result = paNoError; PaOssStream *stream = (PaOssStream*)s; stream->isActive = 1; stream->isStopped = 0; stream->lastPosPtr = 0; stream->lastStreamBytes = 0; stream->framesProcessed = 0; /* only use the thread for callback streams */ if( stream->bufferProcessor.streamCallback ) { PA_ENSURE( PaUtil_StartThreading( &stream->threading, &PaOSS_AudioThreadProc, stream ) ); sem_wait( &stream->semaphore ); } else PA_ENSURE( PaOssStream_Prepare( stream ) ); error: return result; } static PaError RealStop( PaOssStream *stream, int abort ) { PaError result = paNoError; if( stream->callbackMode ) { if( abort ) stream->callbackAbort = 1; else stream->callbackStop = 1; PA_ENSURE( PaUtil_CancelThreading( &stream->threading, !abort, NULL ) ); stream->callbackStop = stream->callbackAbort = 0; } else PA_ENSURE( PaOssStream_Stop( stream, abort ) ); stream->isStopped = 1; error: return result; } /** Stop the stream. * * Aspect StreamState: This will cause the stream to transition to the Stopped state, playing all enqueued * buffers. */ static PaError StopStream( PaStream *s ) { return RealStop( (PaOssStream *)s, 0 ); } /** Abort the stream. * * Aspect StreamState: This will cause the stream to transition to the Stopped state, discarding all enqueued * buffers. Note that the buffers are not currently correctly discarded, this is difficult without closing * the OSS device. */ static PaError AbortStream( PaStream *s ) { return RealStop( (PaOssStream *)s, 1 ); } /** Is the stream in the Stopped state. * */ static PaError IsStreamStopped( PaStream *s ) { PaOssStream *stream = (PaOssStream*)s; return (stream->isStopped); } /** Is the stream in the Active state. * */ static PaError IsStreamActive( PaStream *s ) { PaOssStream *stream = (PaOssStream*)s; return (stream->isActive); } static PaTime GetStreamTime( PaStream *s ) { PaOssStream *stream = (PaOssStream*)s; count_info info; int delta; if( stream->playback ) { if( ioctl( stream->playback->fd, SNDCTL_DSP_GETOPTR, &info) == 0 ) { delta = ( info.bytes - stream->lastPosPtr ) /* & 0x000FFFFF*/; return (float)(stream->lastStreamBytes + delta) / PaOssStreamComponent_FrameSize( stream->playback ) / stream->sampleRate; } } else { if (ioctl( stream->capture->fd, SNDCTL_DSP_GETIPTR, &info) == 0) { delta = (info.bytes - stream->lastPosPtr) /*& 0x000FFFFF*/; return (float)(stream->lastStreamBytes + delta) / PaOssStreamComponent_FrameSize( stream->capture ) / stream->sampleRate; } } /* the ioctl failed, but we can still give a coarse estimate */ return stream->framesProcessed / stream->sampleRate; } static double GetStreamCpuLoad( PaStream* s ) { PaOssStream *stream = (PaOssStream*)s; return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); } /* As separate stream interfaces are used for blocking and callback streams, the following functions can be guaranteed to only be called for blocking streams. */ static PaError ReadStream( PaStream* s, void *buffer, unsigned long frames ) { PaOssStream *stream = (PaOssStream*)s; int bytesRequested, bytesRead; unsigned long framesRequested; void *userBuffer; /* If user input is non-interleaved, PaUtil_CopyInput will manipulate the channel pointers, * so we copy the user provided pointers */ if( stream->bufferProcessor.userInputIsInterleaved ) userBuffer = buffer; else /* Copy channels into local array */ { userBuffer = stream->capture->userBuffers; memcpy( (void *)userBuffer, buffer, sizeof (void *) * stream->capture->userChannelCount ); } while( frames ) { framesRequested = PA_MIN( frames, stream->capture->hostFrames ); bytesRequested = framesRequested * PaOssStreamComponent_FrameSize( stream->capture ); bytesRead = read( stream->capture->fd, stream->capture->buffer, bytesRequested ); if ( bytesRequested != bytesRead ) return paUnanticipatedHostError; PaUtil_SetInputFrameCount( &stream->bufferProcessor, stream->capture->hostFrames ); PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, 0, stream->capture->buffer, stream->capture->hostChannelCount ); PaUtil_CopyInput( &stream->bufferProcessor, &userBuffer, framesRequested ); frames -= framesRequested; } return paNoError; } static PaError WriteStream( PaStream *s, const void *buffer, unsigned long frames ) { PaOssStream *stream = (PaOssStream*)s; int bytesRequested, bytesWritten; unsigned long framesConverted; const void *userBuffer; /* If user output is non-interleaved, PaUtil_CopyOutput will manipulate the channel pointers, * so we copy the user provided pointers */ if( stream->bufferProcessor.userOutputIsInterleaved ) userBuffer = buffer; else { /* Copy channels into local array */ userBuffer = stream->playback->userBuffers; memcpy( (void *)userBuffer, buffer, sizeof (void *) * stream->playback->userChannelCount ); } while( frames ) { PaUtil_SetOutputFrameCount( &stream->bufferProcessor, stream->playback->hostFrames ); PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, 0, stream->playback->buffer, stream->playback->hostChannelCount ); framesConverted = PaUtil_CopyOutput( &stream->bufferProcessor, &userBuffer, frames ); frames -= framesConverted; bytesRequested = framesConverted * PaOssStreamComponent_FrameSize( stream->playback ); bytesWritten = write( stream->playback->fd, stream->playback->buffer, bytesRequested ); if ( bytesRequested != bytesWritten ) return paUnanticipatedHostError; } return paNoError; } static signed long GetStreamReadAvailable( PaStream* s ) { PaOssStream *stream = (PaOssStream*)s; audio_buf_info info; if( ioctl( stream->capture->fd, SNDCTL_DSP_GETISPACE, &info ) < 0 ) return paUnanticipatedHostError; return info.fragments * stream->capture->hostFrames; } /* TODO: Compute number of allocated bytes somewhere else, can we use ODELAY with capture */ static signed long GetStreamWriteAvailable( PaStream* s ) { PaOssStream *stream = (PaOssStream*)s; int delay = 0; if( ioctl( stream->playback->fd, SNDCTL_DSP_GETODELAY, &delay ) < 0 ) return paUnanticipatedHostError; return (PaOssStreamComponent_BufferSize( stream->playback ) - delay) / PaOssStreamComponent_FrameSize( stream->playback ); } praat-6.0.04/external/portaudio2007/pa_unix_util.c000066400000000000000000000453541261542461700217400ustar00rootroot00000000000000#ifdef UNIX /* * $Id: pa_unix_util.c 1232 2007-06-16 14:49:43Z rossb $ * Portable Audio I/O Library * UNIX platform-specific support functions * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2000 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup unix_src */ #include #include #include #include #include #include #include /* For memset */ #include #include #include "pa_util.h" #include "pa_unix_util.h" #include "pa_debugprint.h" /* Track memory allocations to avoid leaks. */ #if PA_TRACK_MEMORY static int numAllocations_ = 0; #endif void *PaUtil_AllocateMemory( long size ) { void *result = malloc( size ); #if PA_TRACK_MEMORY if( result != NULL ) numAllocations_ += 1; #endif return result; } void PaUtil_FreeMemory( void *block ) { if( block != NULL ) { free( block ); #if PA_TRACK_MEMORY numAllocations_ -= 1; #endif } } int PaUtil_CountCurrentlyAllocatedBlocks( void ) { #if PA_TRACK_MEMORY return numAllocations_; #else return 0; #endif } void Pa_Sleep( long msec ) { #ifdef HAVE_NANOSLEEP struct timespec req = {0}, rem = {0}; PaTime time = msec / 1.e3; req.tv_sec = (time_t)time; assert(time - req.tv_sec < 1.0); req.tv_nsec = (long)((time - req.tv_sec) * 1.e9); nanosleep(&req, &rem); /* XXX: Try sleeping the remaining time (contained in rem) if interrupted by a signal? */ #else while( msec > 999 ) /* For OpenBSD and IRIX, argument */ { /* to usleep must be < 1000000. */ usleep( 999000 ); msec -= 999; } usleep( msec * 1000 ); #endif } /* *** NOT USED YET: *** static int usePerformanceCounter_; static double microsecondsPerTick_; */ void PaUtil_InitializeClock( void ) { /* TODO */ } PaTime PaUtil_GetTime( void ) { #ifdef HAVE_CLOCK_GETTIME struct timespec tp; clock_gettime(CLOCK_REALTIME, &tp); return (PaTime)(tp.tv_sec + tp.tv_nsec / 1.e9); #else struct timeval tv; gettimeofday( &tv, NULL ); return (PaTime) tv.tv_usec / 1000000. + tv.tv_sec; #endif } PaError PaUtil_InitializeThreading( PaUtilThreading *threading ) { (void) paUtilErr_; return paNoError; } void PaUtil_TerminateThreading( PaUtilThreading *threading ) { } PaError PaUtil_StartThreading( PaUtilThreading *threading, void *(*threadRoutine)(void *), void *data ) { pthread_create( &threading->callbackThread, NULL, threadRoutine, data ); return paNoError; } PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *exitResult ) { PaError result = paNoError; void *pret; if( exitResult ) *exitResult = paNoError; /* Only kill the thread if it isn't in the process of stopping (flushing adaptation buffers) */ if( !wait ) pthread_cancel( threading->callbackThread ); /* XXX: Safe to call this if the thread has exited on its own? */ pthread_join( threading->callbackThread, &pret ); #ifdef PTHREAD_CANCELED if( pret && PTHREAD_CANCELED != pret ) #else /* !wait means the thread may have been canceled */ if( pret && wait ) #endif { if( exitResult ) *exitResult = *(PaError *) pret; free( pret ); } return result; } /* Threading */ /* paUnixMainThread * We have to be a bit careful with defining this global variable, * as explained below. */ #ifdef __apple__ /* apple/gcc has a "problem" with global vars and dynamic libs. Initializing it seems to fix the problem. Described a bit in this thread: http://gcc.gnu.org/ml/gcc/2005-06/msg00179.html */ pthread_t paUnixMainThread = 0; #else /*pthreads are opaque. We don't know that asigning it an int value always makes sense, so we don't initialize it unless we have to.*/ pthread_t paUnixMainThread = 0; #endif PaError PaUnixThreading_Initialize() { paUnixMainThread = pthread_self(); return paNoError; } static PaError BoostPriority( PaUnixThread* self ) { PaError result = paNoError; struct sched_param spm = { 0 }; /* Priority should only matter between contending FIFO threads? */ spm.sched_priority = 1; assert( self ); if( pthread_setschedparam( self->thread, SCHED_FIFO, &spm ) != 0 ) { PA_UNLESS( errno == EPERM, paInternalError ); /* Lack permission to raise priority */ PA_DEBUG(( "Failed bumping priority\n" )); result = 0; } else { result = 1; /* Success */ } error: return result; } PaError PaUnixThread_New( PaUnixThread* self, void* (*threadFunc)( void* ), void* threadArg, PaTime waitForChild, int rtSched ) { PaError result = paNoError; pthread_attr_t attr; int started = 0; memset( self, 0, sizeof (PaUnixThread) ); PaUnixMutex_Initialize( &self->mtx ); PA_ASSERT_CALL( pthread_cond_init( &self->cond, NULL ), 0 ); self->parentWaiting = 0 != waitForChild; /* Spawn thread */ /* Temporarily disabled since we should test during configuration for presence of required mman.h header */ #if 0 #if defined _POSIX_MEMLOCK && (_POSIX_MEMLOCK != -1) if( rtSched ) { if( mlockall( MCL_CURRENT | MCL_FUTURE ) < 0 ) { int savedErrno = errno; /* In case errno gets overwritten */ assert( savedErrno != EINVAL ); /* Most likely a programmer error */ PA_UNLESS( (savedErrno == EPERM), paInternalError ); PA_DEBUG(( "%s: Failed locking memory\n", __FUNCTION__ )); } else PA_DEBUG(( "%s: Successfully locked memory\n", __FUNCTION__ )); } #endif #endif PA_UNLESS( !pthread_attr_init( &attr ), paInternalError ); /* Priority relative to other processes */ PA_UNLESS( !pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ), paInternalError ); PA_UNLESS( !pthread_create( &self->thread, &attr, threadFunc, threadArg ), paInternalError ); started = 1; if( rtSched ) { #if 0 if( self->useWatchdog ) { int err; struct sched_param wdSpm = { 0 }; /* Launch watchdog, watchdog sets callback thread priority */ int prio = PA_MIN( self->rtPrio + 4, sched_get_priority_max( SCHED_FIFO ) ); wdSpm.sched_priority = prio; PA_UNLESS( !pthread_attr_init( &attr ), paInternalError ); PA_UNLESS( !pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED ), paInternalError ); PA_UNLESS( !pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ), paInternalError ); PA_UNLESS( !pthread_attr_setschedpolicy( &attr, SCHED_FIFO ), paInternalError ); PA_UNLESS( !pthread_attr_setschedparam( &attr, &wdSpm ), paInternalError ); if( (err = pthread_create( &self->watchdogThread, &attr, &WatchdogFunc, self )) ) { PA_UNLESS( err == EPERM, paInternalError ); /* Permission error, go on without realtime privileges */ PA_DEBUG(( "Failed bumping priority\n" )); } else { int policy; self->watchdogRunning = 1; PA_ENSURE_SYSTEM( pthread_getschedparam( self->watchdogThread, &policy, &wdSpm ), 0 ); /* Check if priority is right, policy could potentially differ from SCHED_FIFO (but that's alright) */ if( wdSpm.sched_priority != prio ) { PA_DEBUG(( "Watchdog priority not set correctly (%d)\n", wdSpm.sched_priority )); PA_ENSURE( paInternalError ); } } } else #endif PA_ENSURE( BoostPriority( self ) ); { int policy; struct sched_param spm; pthread_getschedparam(self->thread, &policy, &spm); } } if( self->parentWaiting ) { PaTime till; struct timespec ts; int res = 0; PaTime now; PA_ENSURE( PaUnixMutex_Lock( &self->mtx ) ); /* Wait for stream to be started */ now = PaUtil_GetTime(); till = now + waitForChild; while( self->parentWaiting && !res ) { if( waitForChild > 0 ) { ts.tv_sec = (time_t) floor( till ); ts.tv_nsec = (long) ((till - floor( till )) * 1e9); res = pthread_cond_timedwait( &self->cond, &self->mtx.mtx, &ts ); } else { res = pthread_cond_wait( &self->cond, &self->mtx.mtx ); } } PA_ENSURE( PaUnixMutex_Unlock( &self->mtx ) ); PA_UNLESS( !res || ETIMEDOUT == res, paInternalError ); PA_DEBUG(( "%s: Waited for %g seconds for stream to start\n", __FUNCTION__, PaUtil_GetTime() - now )); if( ETIMEDOUT == res ) { PA_ENSURE( paTimedOut ); } } end: return result; error: if( started ) { PaUnixThread_Terminate( self, 0, NULL ); } goto end; } PaError PaUnixThread_Terminate( PaUnixThread* self, int wait, PaError* exitResult ) { PaError result = paNoError; void* pret; if( exitResult ) { *exitResult = paNoError; } #if 0 if( watchdogExitResult ) *watchdogExitResult = paNoError; if( th->watchdogRunning ) { pthread_cancel( th->watchdogThread ); PA_ENSURE_SYSTEM( pthread_join( th->watchdogThread, &pret ), 0 ); if( pret && pret != PTHREAD_CANCELED ) { if( watchdogExitResult ) *watchdogExitResult = *(PaError *) pret; free( pret ); } } #endif /* Only kill the thread if it isn't in the process of stopping (flushing adaptation buffers) */ /* TODO: Make join time out */ self->stopRequested = wait; if( !wait ) { PA_DEBUG(( "%s: Canceling thread %d\n", __FUNCTION__, self->thread )); /* XXX: Safe to call this if the thread has exited on its own? */ pthread_cancel( self->thread ); } PA_DEBUG(( "%s: Joining thread %d\n", __FUNCTION__, self->thread )); PA_ENSURE_SYSTEM( pthread_join( self->thread, &pret ), 0 ); if( pret && PTHREAD_CANCELED != pret ) { if( exitResult ) { *exitResult = *(PaError*)pret; } free( pret ); } error: PA_ASSERT_CALL( PaUnixMutex_Terminate( &self->mtx ), paNoError ); PA_ASSERT_CALL( pthread_cond_destroy( &self->cond ), 0 ); return result; } PaError PaUnixThread_PrepareNotify( PaUnixThread* self ) { PaError result = paNoError; PA_UNLESS( self->parentWaiting, paInternalError ); PA_ENSURE( PaUnixMutex_Lock( &self->mtx ) ); self->locked = 1; error: return result; } PaError PaUnixThread_NotifyParent( PaUnixThread* self ) { PaError result = paNoError; PA_UNLESS( self->parentWaiting, paInternalError ); if( !self->locked ) { PA_ENSURE( PaUnixMutex_Lock( &self->mtx ) ); self->locked = 1; } self->parentWaiting = 0; pthread_cond_signal( &self->cond ); PA_ENSURE( PaUnixMutex_Unlock( &self->mtx ) ); self->locked = 0; error: return result; } int PaUnixThread_StopRequested( PaUnixThread* self ) { return self->stopRequested; } PaError PaUnixMutex_Initialize( PaUnixMutex* self ) { PaError result = paNoError; PA_ASSERT_CALL( pthread_mutex_init( &self->mtx, NULL ), 0 ); return result; } PaError PaUnixMutex_Terminate( PaUnixMutex* self ) { PaError result = paNoError; PA_ASSERT_CALL( pthread_mutex_destroy( &self->mtx ), 0 ); return result; } /** Lock mutex. * * We're disabling thread cancellation while the thread is holding a lock, so mutexes are * properly unlocked at termination time. */ PaError PaUnixMutex_Lock( PaUnixMutex* self ) { PaError result = paNoError; int oldState; PA_ENSURE_SYSTEM( pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldState ), 0 ); PA_ENSURE_SYSTEM( pthread_mutex_lock( &self->mtx ), 0 ); error: return result; } /** Unlock mutex. * * Thread cancellation is enabled again after the mutex is properly unlocked. */ PaError PaUnixMutex_Unlock( PaUnixMutex* self ) { PaError result = paNoError; int oldState; PA_ENSURE_SYSTEM( pthread_mutex_unlock( &self->mtx ), 0 ); PA_ENSURE_SYSTEM( pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, &oldState ), 0 ); error: return result; } #if 0 static void OnWatchdogExit( void *userData ) { PaAlsaThreading *th = (PaAlsaThreading *) userData; struct sched_param spm = { 0 }; assert( th ); PA_ASSERT_CALL( pthread_setschedparam( th->callbackThread, SCHED_OTHER, &spm ), 0 ); /* Lower before exiting */ PA_DEBUG(( "Watchdog exiting\n" )); } static void *WatchdogFunc( void *userData ) { PaError result = paNoError, *pres = NULL; int err; PaAlsaThreading *th = (PaAlsaThreading *) userData; unsigned intervalMsec = 500; const PaTime maxSeconds = 3.; /* Max seconds between callbacks */ PaTime timeThen = PaUtil_GetTime(), timeNow, timeElapsed, cpuTimeThen, cpuTimeNow, cpuTimeElapsed; double cpuLoad, avgCpuLoad = 0.; int throttled = 0; assert( th ); /* Execute OnWatchdogExit when exiting */ pthread_cleanup_push( &OnWatchdogExit, th ); /* Boost priority of callback thread */ PA_ENSURE( result = BoostPriority( th ) ); if( !result ) { /* Boost failed, might as well exit */ pthread_exit( NULL ); } cpuTimeThen = th->callbackCpuTime; { int policy; struct sched_param spm = { 0 }; pthread_getschedparam( pthread_self(), &policy, &spm ); PA_DEBUG(( "%s: Watchdog priority is %d\n", __FUNCTION__, spm.sched_priority )); } while( 1 ) { double lowpassCoeff = 0.9, lowpassCoeff1 = 0.99999 - lowpassCoeff; /* Test before and after in case whatever underlying sleep call isn't interrupted by pthread_cancel */ pthread_testcancel(); Pa_Sleep( intervalMsec ); pthread_testcancel(); if( PaUtil_GetTime() - th->callbackTime > maxSeconds ) { PA_DEBUG(( "Watchdog: Terminating callback thread\n" )); /* Tell thread to terminate */ err = pthread_kill( th->callbackThread, SIGKILL ); pthread_exit( NULL ); } PA_DEBUG(( "%s: PortAudio reports CPU load: %g\n", __FUNCTION__, PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) )); /* Check if we should throttle, or unthrottle :P */ cpuTimeNow = th->callbackCpuTime; cpuTimeElapsed = cpuTimeNow - cpuTimeThen; cpuTimeThen = cpuTimeNow; timeNow = PaUtil_GetTime(); timeElapsed = timeNow - timeThen; timeThen = timeNow; cpuLoad = cpuTimeElapsed / timeElapsed; avgCpuLoad = avgCpuLoad * lowpassCoeff + cpuLoad * lowpassCoeff1; /* if( throttled ) PA_DEBUG(( "Watchdog: CPU load: %g, %g\n", avgCpuLoad, cpuTimeElapsed )); */ if( PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) > .925 ) { static int policy; static struct sched_param spm = { 0 }; static const struct sched_param defaultSpm = { 0 }; PA_DEBUG(( "%s: Throttling audio thread, priority %d\n", __FUNCTION__, spm.sched_priority )); pthread_getschedparam( th->callbackThread, &policy, &spm ); if( !pthread_setschedparam( th->callbackThread, SCHED_OTHER, &defaultSpm ) ) { throttled = 1; } else PA_DEBUG(( "Watchdog: Couldn't lower priority of audio thread: %s\n", strerror( errno ) )); /* Give other processes a go, before raising priority again */ PA_DEBUG(( "%s: Watchdog sleeping for %lu msecs before unthrottling\n", __FUNCTION__, th->throttledSleepTime )); Pa_Sleep( th->throttledSleepTime ); /* Reset callback priority */ if( pthread_setschedparam( th->callbackThread, SCHED_FIFO, &spm ) != 0 ) { PA_DEBUG(( "%s: Couldn't raise priority of audio thread: %s\n", __FUNCTION__, strerror( errno ) )); } if( PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) >= .99 ) intervalMsec = 50; else intervalMsec = 100; /* lowpassCoeff = .97; lowpassCoeff1 = .99999 - lowpassCoeff; */ } else if( throttled && avgCpuLoad < .8 ) { intervalMsec = 500; throttled = 0; /* lowpassCoeff = .9; lowpassCoeff1 = .99999 - lowpassCoeff; */ } } pthread_cleanup_pop( 1 ); /* Execute cleanup on exit */ error: /* Shouldn't get here in the normal case */ /* Pass on error code */ pres = malloc( sizeof (PaError) ); *pres = result; pthread_exit( pres ); } static void CallbackUpdate( PaAlsaThreading *th ) { th->callbackTime = PaUtil_GetTime(); th->callbackCpuTime = PaUtil_GetCpuLoad( th->cpuLoadMeasurer ); } /* static void *CanaryFunc( void *userData ) { const unsigned intervalMsec = 1000; PaUtilThreading *th = (PaUtilThreading *) userData; while( 1 ) { th->canaryTime = PaUtil_GetTime(); pthread_testcancel(); Pa_Sleep( intervalMsec ); } pthread_exit( NULL ); } */ #endif #endifpraat-6.0.04/external/portaudio2007/pa_unix_util.h000066400000000000000000000173761261542461700217500ustar00rootroot00000000000000/* * $Id: pa_unix_util.h 1241 2007-07-23 20:08:31Z aknudsen $ * Portable Audio I/O Library * UNIX platform-specific support functions * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2000 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup unix_src */ #ifndef PA_UNIX_UTIL_H #define PA_UNIX_UTIL_H #include "pa_cpuload.h" #include #include #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define PA_MIN(x,y) ( (x) < (y) ? (x) : (y) ) #define PA_MAX(x,y) ( (x) > (y) ? (x) : (y) ) /* Utilize GCC branch prediction for error tests */ #if defined __GNUC__ && __GNUC__ >= 3 #define UNLIKELY(expr) __builtin_expect( (expr), 0 ) #else #define UNLIKELY(expr) (expr) #endif #define STRINGIZE_HELPER(expr) #expr #define STRINGIZE(expr) STRINGIZE_HELPER(expr) #define PA_UNLESS(expr, code) \ do { \ if( UNLIKELY( (expr) == 0 ) ) \ { \ PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \ result = (code); \ goto error; \ } \ } while (0); static PaError paUtilErr_; /* Used with PA_ENSURE */ /* Check PaError */ #define PA_ENSURE(expr) \ do { \ if( UNLIKELY( (paUtilErr_ = (expr)) < paNoError ) ) \ { \ PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \ result = paUtilErr_; \ goto error; \ } \ } while (0); #define PA_ASSERT_CALL(expr, success) \ paUtilErr_ = (expr); \ assert( success == paUtilErr_ ); #define PA_ENSURE_SYSTEM(expr, success) \ do { \ if( UNLIKELY( (paUtilErr_ = (expr)) != success ) ) \ { \ /* PaUtil_SetLastHostErrorInfo should only be used in the main thread */ \ if( pthread_equal(pthread_self(), paUnixMainThread) ) \ { \ PaUtil_SetLastHostErrorInfo( paALSA, paUtilErr_, strerror( paUtilErr_ ) ); \ } \ PaUtil_DebugPrint( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" ); \ result = paUnanticipatedHostError; \ goto error; \ } \ } while( 0 ); typedef struct { pthread_t callbackThread; } PaUtilThreading; PaError PaUtil_InitializeThreading( PaUtilThreading *threading ); void PaUtil_TerminateThreading( PaUtilThreading *threading ); PaError PaUtil_StartThreading( PaUtilThreading *threading, void *(*threadRoutine)(void *), void *data ); PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *exitResult ); /* State accessed by utility functions */ /* void PaUnix_SetRealtimeScheduling( int rt ); void PaUtil_InitializeThreading( PaUtilThreading *th, PaUtilCpuLoadMeasurer *clm ); PaError PaUtil_CreateCallbackThread( PaUtilThreading *th, void *(*CallbackThreadFunc)( void * ), PaStream *s ); PaError PaUtil_KillCallbackThread( PaUtilThreading *th, PaError *exitResult ); void PaUtil_CallbackUpdate( PaUtilThreading *th ); */ extern pthread_t paUnixMainThread; typedef struct { pthread_mutex_t mtx; } PaUnixMutex; PaError PaUnixMutex_Initialize( PaUnixMutex* self ); PaError PaUnixMutex_Terminate( PaUnixMutex* self ); PaError PaUnixMutex_Lock( PaUnixMutex* self ); PaError PaUnixMutex_Unlock( PaUnixMutex* self ); typedef struct { pthread_t thread; int parentWaiting; int stopRequested; int locked; PaUnixMutex mtx; pthread_cond_t cond; volatile sig_atomic_t stopRequest; } PaUnixThread; /** Initialize global threading state. */ PaError PaUnixThreading_Initialize( void ); /** Perish, passing on eventual error code. * * A thin wrapper around pthread_exit, will automatically pass on any error code to the joining thread. * If the result indicates an error, i.e. it is not equal to paNoError, this function will automatically * allocate a pointer so the error is passed on with pthread_exit. If the result indicates that all is * well however, only a NULL pointer will be handed to pthread_exit. Thus, the joining thread should * check whether a non-NULL result pointer is obtained from pthread_join and make sure to free it. * @param result: The error code to pass on to the joining thread. */ #define PaUnixThreading_EXIT(result) \ do { \ PaError* pres = NULL; \ if( paNoError != (result) ) \ { \ pres = malloc( sizeof (PaError) ); \ *pres = (result); \ } \ pthread_exit( pres ); \ } while (0); /** Spawn a thread. * * Intended for spawning the callback thread from the main thread. This function can even block (for a certain * time or indefinitely) untill notified by the callback thread (using PaUnixThread_NotifyParent), which can be * useful in order to make sure that callback has commenced before returning from Pa_StartStream. * @param threadFunc: The function to be executed in the child thread. * @param waitForChild: If not 0, wait for child thread to call PaUnixThread_NotifyParent. Less than 0 means * wait for ever, greater than 0 wait for the specified time. * @param rtSched: Enable realtime scheduling? * @return: If timed out waiting on child, paTimedOut. */ PaError PaUnixThread_New( PaUnixThread* self, void* (*threadFunc)( void* ), void* threadArg, PaTime waitForChild, int rtSched ); /** Terminate thread. * * @param wait: If true, request that background thread stop and wait untill it does, else cancel it. * @param exitResult: If non-null this will upon return contain the exit status of the thread. */ PaError PaUnixThread_Terminate( PaUnixThread* self, int wait, PaError* exitResult ); /** Prepare to notify waiting parent thread. * * An internal lock must be held before the parent is notified in PaUnixThread_NotifyParent, call this to * acquire it beforehand. * @return: If parent is not waiting, paInternalError. */ PaError PaUnixThread_PrepareNotify( PaUnixThread* self ); /** Notify waiting parent thread. * * @return: If parent timed out waiting, paTimedOut. If parent was never waiting, paInternalError. */ PaError PaUnixThread_NotifyParent( PaUnixThread* self ); /** Has the parent thread requested this thread to stop? */ int PaUnixThread_StopRequested( PaUnixThread* self ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif praat-6.0.04/external/portaudio2007/pa_util.h000066400000000000000000000125711261542461700206750ustar00rootroot00000000000000#ifndef PA_UTIL_H #define PA_UTIL_H /* * $Id: pa_util.h 1229 2007-06-15 16:11:11Z rossb $ * Portable Audio I/O Library implementation utilities header * common implementation utilities and interfaces * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Prototypes for utility functions used by PortAudio implementations. @todo Document and adhere to the alignment guarantees provided by PaUtil_AllocateMemory(). */ #include "portaudio.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ struct PaUtilHostApiRepresentation; /** Retrieve a specific host API representation. This function can be used by implementations to retrieve a pointer to their representation in host api specific extension functions which aren't passed a rep pointer by pa_front.c. @param hostApi A pointer to a host API represenation pointer. Apon success this will receive the requested representation pointer. @param type A valid host API type identifier. @returns An error code. If the result is PaNoError then a pointer to the requested host API representation will be stored in *hostApi. If the host API specified by type is not found, this function returns paHostApiNotFound. */ PaError PaUtil_GetHostApiRepresentation( struct PaUtilHostApiRepresentation **hostApi, PaHostApiTypeId type ); /** Convert a PortAudio device index into a host API specific device index. @param hostApiDevice Pointer to a device index, on success this will recieve the converted device index value. @param device The PortAudio device index to convert. @param hostApi The host api which the index should be converted for. @returns On success returns PaNoError and places the converted index in the hostApiDevice parameter. */ PaError PaUtil_DeviceIndexToHostApiDeviceIndex( PaDeviceIndex *hostApiDevice, PaDeviceIndex device, struct PaUtilHostApiRepresentation *hostApi ); /** Set the host error information returned by Pa_GetLastHostErrorInfo. This function and the paUnanticipatedHostError error code should be used as a last resort. Implementors should use existing PA error codes where possible, or nominate new ones. Note that at it is always better to use PaUtil_SetLastHostErrorInfo() and paUnanticipatedHostError than to return an ambiguous or inaccurate PaError code. @param hostApiType The host API which encountered the error (ie of the caller) @param errorCode The error code returned by the native API function. @param errorText A string describing the error. PaUtil_SetLastHostErrorInfo makes a copy of the string, so it is not necessary for the pointer to remain valid after the call to PaUtil_SetLastHostErrorInfo() returns. */ void PaUtil_SetLastHostErrorInfo( PaHostApiTypeId hostApiType, long errorCode, const char *errorText ); /* the following functions are implemented in a platform platform specific .c file */ /** Allocate size bytes, guaranteed to be aligned to a FIXME byte boundary */ void *PaUtil_AllocateMemory( long size ); /** Realease block if non-NULL. block may be NULL */ void PaUtil_FreeMemory( void *block ); /** Return the number of currently allocated blocks. This function can be used for detecting memory leaks. @note Allocations will only be tracked if PA_TRACK_MEMORY is #defined. If it isn't, this function will always return 0. */ int PaUtil_CountCurrentlyAllocatedBlocks( void ); /** Initialize the clock used by PaUtil_GetTime(). Call this before calling PaUtil_GetTime. @see PaUtil_GetTime */ void PaUtil_InitializeClock( void ); /** Return the system time in seconds. Used to implement CPU load functions @see PaUtil_InitializeClock */ double PaUtil_GetTime( void ); /* void Pa_Sleep( long msec ); must also be implemented in per-platform .c file */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_UTIL_H */ praat-6.0.04/external/portaudio2007/pa_win_ds.c000066400000000000000000002727311261542461700212040ustar00rootroot00000000000000#ifdef _WIN32 /* * $Id: pa_win_ds.c 1286 2007-09-26 21:34:23Z rossb $ * Portable Audio I/O Library DirectSound implementation * * Authors: Phil Burk, Robert Marsanyi & Ross Bencina * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2007 Ross Bencina, Phil Burk, Robert Marsanyi * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostaip_src @todo implement paInputOverflow callback status flag @todo implement paNeverDropInput. @todo implement host api specific extension to set i/o buffer sizes in frames @todo implement initialisation of PaDeviceInfo default*Latency fields (currently set to 0.) @todo implement ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable @todo audit handling of DirectSound result codes - in many cases we could convert a HRESULT into a native portaudio error code. Standard DirectSound result codes are documented at msdn. @todo implement IsFormatSupported @todo call PaUtil_SetLastHostErrorInfo with a specific error string (currently just "DSound error"). @todo make sure all buffers have been played before stopping the stream when the stream callback returns paComplete @todo retrieve default devices using the DRVM_MAPPER_PREFERRED_GET functions used in the wmme api these wave device ids can be aligned with the directsound devices either by retrieving the system interface device name using DRV_QUERYDEVICEINTERFACE or by using the wave device id retrieved in KsPropertySetEnumerateCallback. old TODOs from phil, need to work out if these have been done: O- fix "patest_stop.c" */ #undef UNICODE #include #include /* strlen() */ #include #include /* We are only using DX3 in here, no need to polute the namespace - davidv */ #define DIRECTSOUND_VERSION 0x0300 #include #ifdef PAWIN_USE_WDMKS_DEVICE_INFO #include #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ #include "pa_util.h" #include "pa_allocation.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_cpuload.h" #include "pa_process.h" #include "pa_debugprint.h" #include "pa_win_ds.h" #include "pa_win_ds_dynlink.h" #include "pa_win_waveformat.h" #include "pa_win_wdmks_utils.h" #if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */ #pragma comment( lib, "dsound.lib" ) #pragma comment( lib, "winmm.lib" ) #endif /* provided in newer platform sdks and x64 */ #ifndef DWORD_PTR #define DWORD_PTR DWORD #endif #define PRINT(x) PA_DEBUG(x); #define ERR_RPT(x) PRINT(x) #define DBUG(x) PRINT(x) #define DBUGX(x) PRINT(x) #define PA_USE_HIGH_LATENCY (0) #if PA_USE_HIGH_LATENCY #define PA_WIN_9X_LATENCY (500) #define PA_WIN_NT_LATENCY (600) #else #define PA_WIN_9X_LATENCY (140) #define PA_WIN_NT_LATENCY (280) #endif #define PA_WIN_WDM_LATENCY (120) #define SECONDS_PER_MSEC (0.001) #define MSEC_PER_SECOND (1000) /* prototypes for functions declared in this file */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); #ifdef __cplusplus } #endif /* __cplusplus */ static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); static PaError CloseStream( PaStream* stream ); static PaError StartStream( PaStream *stream ); static PaError StopStream( PaStream *stream ); static PaError AbortStream( PaStream *stream ); static PaError IsStreamStopped( PaStream *s ); static PaError IsStreamActive( PaStream *stream ); static PaTime GetStreamTime( PaStream *stream ); static double GetStreamCpuLoad( PaStream* stream ); static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ); static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ); static signed long GetStreamReadAvailable( PaStream* stream ); static signed long GetStreamWriteAvailable( PaStream* stream ); /* FIXME: should convert hr to a string */ #define PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr ) \ PaUtil_SetLastHostErrorInfo( paDirectSound, hr, "DirectSound error" ) /************************************************* DX Prototypes **********/ static BOOL CALLBACK CollectGUIDsProc(LPGUID lpGUID, LPCTSTR lpszDesc, LPCTSTR lpszDrvName, LPVOID lpContext ); /************************************************************************************/ /********************** Structures **************************************************/ /************************************************************************************/ /* PaWinDsHostApiRepresentation - host api datastructure specific to this implementation */ typedef struct PaWinDsDeviceInfo { PaDeviceInfo inheritedDeviceInfo; GUID guid; GUID *lpGUID; double sampleRates[3]; char deviceInputChannelCountIsKnown; /**<< if the system returns 0xFFFF then we don't really know the number of supported channels (1=>known, 0=>unknown)*/ char deviceOutputChannelCountIsKnown; /**<< if the system returns 0xFFFF then we don't really know the number of supported channels (1=>known, 0=>unknown)*/ } PaWinDsDeviceInfo; typedef struct { PaUtilHostApiRepresentation inheritedHostApiRep; PaUtilStreamInterface callbackStreamInterface; PaUtilStreamInterface blockingStreamInterface; PaUtilAllocationGroup *allocations; /* implementation specific data goes here */ char comWasInitialized; } PaWinDsHostApiRepresentation; /* PaWinDsStream - a stream data structure specifically for this implementation */ typedef struct PaWinDsStream { PaUtilStreamRepresentation streamRepresentation; PaUtilCpuLoadMeasurer cpuLoadMeasurer; PaUtilBufferProcessor bufferProcessor; /* DirectSound specific data. */ /* Output */ LPDIRECTSOUND pDirectSound; LPDIRECTSOUNDBUFFER pDirectSoundOutputBuffer; DWORD outputBufferWriteOffsetBytes; /* last write position */ INT outputBufferSizeBytes; INT bytesPerOutputFrame; /* Try to detect play buffer underflows. */ LARGE_INTEGER perfCounterTicksPerBuffer; /* counter ticks it should take to play a full buffer */ LARGE_INTEGER previousPlayTime; UINT previousPlayCursor; UINT outputUnderflowCount; BOOL outputIsRunning; /* use double which lets us can play for several thousand years with enough precision */ double dsw_framesWritten; double framesPlayed; /* Input */ LPDIRECTSOUNDCAPTURE pDirectSoundCapture; LPDIRECTSOUNDCAPTUREBUFFER pDirectSoundInputBuffer; INT bytesPerInputFrame; UINT readOffset; /* last read position */ UINT inputSize; MMRESULT timerID; int framesPerDSBuffer; double framesWritten; double secondsPerHostByte; /* Used to optimize latency calculation for outTime */ PaStreamCallbackFlags callbackFlags; /* FIXME - move all below to PaUtilStreamRepresentation */ volatile int isStarted; volatile int isActive; volatile int stopProcessing; /* stop thread once existing buffers have been returned */ volatile int abortProcessing; /* stop thread immediately */ } PaWinDsStream; /************************************************************************************ ** Duplicate the input string using the allocations allocator. ** A NULL string is converted to a zero length string. ** If memory cannot be allocated, NULL is returned. **/ static char *DuplicateDeviceNameString( PaUtilAllocationGroup *allocations, const char* src ) { char *result = 0; if( src != NULL ) { size_t len = strlen(src); result = (char*)PaUtil_GroupAllocateMemory( allocations, (long)(len + 1) ); if( result ) memcpy( (void *) result, src, len+1 ); } else { result = (char*)PaUtil_GroupAllocateMemory( allocations, 1 ); if( result ) result[0] = '\0'; } return result; } /************************************************************************************ ** DSDeviceNameAndGUID, DSDeviceNameAndGUIDVector used for collecting preliminary ** information during device enumeration. */ typedef struct DSDeviceNameAndGUID{ char *name; // allocated from parent's allocations, never deleted by this structure GUID guid; LPGUID lpGUID; void *pnpInterface; // wchar_t* interface path, allocated using the DS host api's allocation group } DSDeviceNameAndGUID; typedef struct DSDeviceNameAndGUIDVector{ PaUtilAllocationGroup *allocations; PaError enumerationError; int count; int free; DSDeviceNameAndGUID *items; // Allocated using LocalAlloc() } DSDeviceNameAndGUIDVector; typedef struct DSDeviceNamesAndGUIDs{ PaWinDsHostApiRepresentation *winDsHostApi; DSDeviceNameAndGUIDVector inputNamesAndGUIDs; DSDeviceNameAndGUIDVector outputNamesAndGUIDs; } DSDeviceNamesAndGUIDs; static PaError InitializeDSDeviceNameAndGUIDVector( DSDeviceNameAndGUIDVector *guidVector, PaUtilAllocationGroup *allocations ) { PaError result = paNoError; guidVector->allocations = allocations; guidVector->enumerationError = paNoError; guidVector->count = 0; guidVector->free = 8; guidVector->items = (DSDeviceNameAndGUID*)LocalAlloc( LMEM_FIXED, sizeof(DSDeviceNameAndGUID) * guidVector->free ); if( guidVector->items == NULL ) result = paInsufficientMemory; return result; } static PaError ExpandDSDeviceNameAndGUIDVector( DSDeviceNameAndGUIDVector *guidVector ) { PaError result = paNoError; DSDeviceNameAndGUID *newItems; int i; /* double size of vector */ int size = guidVector->count + guidVector->free; guidVector->free += size; newItems = (DSDeviceNameAndGUID*)LocalAlloc( LMEM_FIXED, sizeof(DSDeviceNameAndGUID) * size * 2 ); if( newItems == NULL ) { result = paInsufficientMemory; } else { for( i=0; i < guidVector->count; ++i ) { newItems[i].name = guidVector->items[i].name; if( guidVector->items[i].lpGUID == NULL ) { newItems[i].lpGUID = NULL; } else { newItems[i].lpGUID = &newItems[i].guid; memcpy( &newItems[i].guid, guidVector->items[i].lpGUID, sizeof(GUID) );; } newItems[i].pnpInterface = guidVector->items[i].pnpInterface; } LocalFree( guidVector->items ); guidVector->items = newItems; } return result; } /* it's safe to call DSDeviceNameAndGUIDVector multiple times */ static PaError TerminateDSDeviceNameAndGUIDVector( DSDeviceNameAndGUIDVector *guidVector ) { PaError result = paNoError; if( guidVector->items != NULL ) { if( LocalFree( guidVector->items ) != NULL ) result = paInsufficientMemory; /** @todo this isn't the correct error to return from a deallocation failure */ guidVector->items = NULL; } return result; } /************************************************************************************ ** Collect preliminary device information during DirectSound enumeration */ static BOOL CALLBACK CollectGUIDsProc(LPGUID lpGUID, LPCTSTR lpszDesc, LPCTSTR lpszDrvName, LPVOID lpContext ) { DSDeviceNameAndGUIDVector *namesAndGUIDs = (DSDeviceNameAndGUIDVector*)lpContext; PaError error; (void) lpszDrvName; /* unused variable */ if( namesAndGUIDs->free == 0 ) { error = ExpandDSDeviceNameAndGUIDVector( namesAndGUIDs ); if( error != paNoError ) { namesAndGUIDs->enumerationError = error; return FALSE; } } /* Set GUID pointer, copy GUID to storage in DSDeviceNameAndGUIDVector. */ if( lpGUID == NULL ) { namesAndGUIDs->items[namesAndGUIDs->count].lpGUID = NULL; } else { namesAndGUIDs->items[namesAndGUIDs->count].lpGUID = &namesAndGUIDs->items[namesAndGUIDs->count].guid; memcpy( &namesAndGUIDs->items[namesAndGUIDs->count].guid, lpGUID, sizeof(GUID) ); } namesAndGUIDs->items[namesAndGUIDs->count].name = DuplicateDeviceNameString( namesAndGUIDs->allocations, lpszDesc ); if( namesAndGUIDs->items[namesAndGUIDs->count].name == NULL ) { namesAndGUIDs->enumerationError = paInsufficientMemory; return FALSE; } namesAndGUIDs->items[namesAndGUIDs->count].pnpInterface = 0; ++namesAndGUIDs->count; --namesAndGUIDs->free; return TRUE; } #ifdef PAWIN_USE_WDMKS_DEVICE_INFO static void *DuplicateWCharString( PaUtilAllocationGroup *allocations, wchar_t *source ) { size_t len; wchar_t *result; len = wcslen( source ); result = (wchar_t*)PaUtil_GroupAllocateMemory( allocations, (long) ((len+1) * sizeof(wchar_t)) ); wcscpy( result, source ); return result; } static BOOL CALLBACK KsPropertySetEnumerateCallback( PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data, LPVOID context ) { int i; DSDeviceNamesAndGUIDs *deviceNamesAndGUIDs = (DSDeviceNamesAndGUIDs*)context; if( data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER ) { for( i=0; i < deviceNamesAndGUIDs->outputNamesAndGUIDs.count; ++i ) { if( deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].lpGUID && memcmp( &data->DeviceId, deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].lpGUID, sizeof(GUID) ) == 0 ) { deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].pnpInterface = (char*)DuplicateWCharString( deviceNamesAndGUIDs->winDsHostApi->allocations, data->Interface ); break; } } } else if( data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE ) { for( i=0; i < deviceNamesAndGUIDs->inputNamesAndGUIDs.count; ++i ) { if( deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].lpGUID && memcmp( &data->DeviceId, deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].lpGUID, sizeof(GUID) ) == 0 ) { deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].pnpInterface = (char*)DuplicateWCharString( deviceNamesAndGUIDs->winDsHostApi->allocations, data->Interface ); break; } } } return TRUE; } static GUID pawin_CLSID_DirectSoundPrivate = { 0x11ab3ec0, 0x25ec, 0x11d1, 0xa4, 0xd8, 0x00, 0xc0, 0x4f, 0xc2, 0x8a, 0xca }; static GUID pawin_DSPROPSETID_DirectSoundDevice = { 0x84624f82, 0x25ec, 0x11d1, 0xa4, 0xd8, 0x00, 0xc0, 0x4f, 0xc2, 0x8a, 0xca }; static GUID pawin_IID_IKsPropertySet = { 0x31efac30, 0x515c, 0x11d0, 0xa9, 0xaa, 0x00, 0xaa, 0x00, 0x61, 0xbe, 0x93 }; /* FindDevicePnpInterfaces fills in the pnpInterface fields in deviceNamesAndGUIDs with UNICODE file paths to the devices. The DS documentation mentions at least two techniques by which these Interface paths can be found using IKsPropertySet on the DirectSound class object. One is using the DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION property, and the other is using DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE. I tried both methods and only the second worked. I found two postings on the net from people who had the same problem with the first method, so I think the method used here is more common/likely to work. The probem is that IKsPropertySet_Get returns S_OK but the fields of the device description are not filled in. The mechanism we use works by registering an enumeration callback which is called for every DSound device. Our callback searches for a device in our deviceNamesAndGUIDs list with the matching GUID and copies the pointer to the Interface path. Note that we could have used this enumeration callback to perform the original device enumeration, however we choose not to so we can disable this step easily. Apparently the IKsPropertySet mechanism was added in DirectSound 9c 2004 http://www.tech-archive.net/Archive/Development/microsoft.public.win32.programmer.mmedia/2004-12/0099.html -- rossb */ static void FindDevicePnpInterfaces( DSDeviceNamesAndGUIDs *deviceNamesAndGUIDs ) { IClassFactory *pClassFactory; if( paWinDsDSoundEntryPoints.DllGetClassObject(&pawin_CLSID_DirectSoundPrivate, &IID_IClassFactory, (PVOID *) &pClassFactory) == S_OK ){ IKsPropertySet *pPropertySet; if( pClassFactory->lpVtbl->CreateInstance( pClassFactory, NULL, &pawin_IID_IKsPropertySet, (PVOID *) &pPropertySet) == S_OK ){ DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data; ULONG bytesReturned; data.Callback = KsPropertySetEnumerateCallback; data.Context = deviceNamesAndGUIDs; IKsPropertySet_Get( pPropertySet, &pawin_DSPROPSETID_DirectSoundDevice, DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W, NULL, 0, &data, sizeof(data), &bytesReturned ); IKsPropertySet_Release( pPropertySet ); } pClassFactory->lpVtbl->Release( pClassFactory ); } /* The following code fragment, which I chose not to use, queries for the device interface for a device with a specific GUID: ULONG BytesReturned; DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA Property; memset (&Property, 0, sizeof(Property)); Property.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER; Property.DeviceId = *lpGUID; hr = IKsPropertySet_Get( pPropertySet, &pawin_DSPROPSETID_DirectSoundDevice, DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W, NULL, 0, &Property, sizeof(Property), &BytesReturned ); if( hr == S_OK ) { //pnpInterface = Property.Interface; } */ } #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ /* GUIDs for emulated devices which we blacklist below. are there more than two of them?? */ GUID IID_IRolandVSCEmulated1 = {0xc2ad1800, 0xb243, 0x11ce, 0xa8, 0xa4, 0x00, 0xaa, 0x00, 0x6c, 0x45, 0x01}; GUID IID_IRolandVSCEmulated2 = {0xc2ad1800, 0xb243, 0x11ce, 0xa8, 0xa4, 0x00, 0xaa, 0x00, 0x6c, 0x45, 0x02}; #define PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_ (13) /* must match array length below */ static double defaultSampleRateSearchOrder_[] = { 44100.0, 48000.0, 32000.0, 24000.0, 22050.0, 88200.0, 96000.0, 192000.0, 16000.0, 12000.0, 11025.0, 9600.0, 8000.0 }; /************************************************************************************ ** Extract capabilities from an output device, and add it to the device info list ** if successful. This function assumes that there is enough room in the ** device info list to accomodate all entries. ** ** The device will not be added to the device list if any errors are encountered. */ static PaError AddOutputDeviceInfoFromDirectSound( PaWinDsHostApiRepresentation *winDsHostApi, char *name, LPGUID lpGUID, char *pnpInterface ) { PaUtilHostApiRepresentation *hostApi = &winDsHostApi->inheritedHostApiRep; PaWinDsDeviceInfo *winDsDeviceInfo = (PaWinDsDeviceInfo*) hostApi->deviceInfos[hostApi->info.deviceCount]; PaDeviceInfo *deviceInfo = &winDsDeviceInfo->inheritedDeviceInfo; HRESULT hr; LPDIRECTSOUND lpDirectSound; DSCAPS caps; int deviceOK = TRUE; PaError result = paNoError; int i; /* Copy GUID to the device info structure. Set pointer. */ if( lpGUID == NULL ) { winDsDeviceInfo->lpGUID = NULL; } else { memcpy( &winDsDeviceInfo->guid, lpGUID, sizeof(GUID) ); winDsDeviceInfo->lpGUID = &winDsDeviceInfo->guid; } if( lpGUID ) { if (IsEqualGUID (&IID_IRolandVSCEmulated1,lpGUID) || IsEqualGUID (&IID_IRolandVSCEmulated2,lpGUID) ) { PA_DEBUG(("BLACKLISTED: %s \n",name)); return paNoError; } } /* Create a DirectSound object for the specified GUID Note that using CoCreateInstance doesn't work on windows CE. */ hr = paWinDsDSoundEntryPoints.DirectSoundCreate( lpGUID, &lpDirectSound, NULL ); /** try using CoCreateInstance because DirectSoundCreate was hanging under some circumstances - note this was probably related to the #define BOOL short bug which has now been fixed @todo delete this comment and the following code once we've ensured there is no bug. */ /* hr = CoCreateInstance( &CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound, (void**)&lpDirectSound ); if( hr == S_OK ) { hr = IDirectSound_Initialize( lpDirectSound, lpGUID ); } */ if( hr != DS_OK ) { if (hr == DSERR_ALLOCATED) PA_DEBUG(("AddOutputDeviceInfoFromDirectSound %s DSERR_ALLOCATED\n",name)); DBUG(("Cannot create DirectSound for %s. Result = 0x%x\n", name, hr )); if (lpGUID) DBUG(("%s's GUID: {0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x, 0x%x} \n", name, lpGUID->Data1, lpGUID->Data2, lpGUID->Data3, lpGUID->Data4[0], lpGUID->Data4[1], lpGUID->Data4[2], lpGUID->Data4[3], lpGUID->Data4[4], lpGUID->Data4[5], lpGUID->Data4[6], lpGUID->Data4[7])); deviceOK = FALSE; } else { /* Query device characteristics. */ memset( &caps, 0, sizeof(caps) ); caps.dwSize = sizeof(caps); hr = IDirectSound_GetCaps( lpDirectSound, &caps ); if( hr != DS_OK ) { DBUG(("Cannot GetCaps() for DirectSound device %s. Result = 0x%x\n", name, hr )); deviceOK = FALSE; } else { #ifndef PA_NO_WMME if( caps.dwFlags & DSCAPS_EMULDRIVER ) { /* If WMME supported, then reject Emulated drivers because they are lousy. */ deviceOK = FALSE; } #endif if( deviceOK ) { deviceInfo->maxInputChannels = 0; winDsDeviceInfo->deviceInputChannelCountIsKnown = 1; /* DS output capabilities only indicate supported number of channels using two flags which indicate mono and/or stereo. We assume that stereo devices may support more than 2 channels (as is the case with 5.1 devices for example) and so set deviceOutputChannelCountIsKnown to 0 (unknown). In this case OpenStream will try to open the device when the user requests more than 2 channels, rather than returning an error. */ if( caps.dwFlags & DSCAPS_PRIMARYSTEREO ) { deviceInfo->maxOutputChannels = 2; winDsDeviceInfo->deviceOutputChannelCountIsKnown = 0; } else { deviceInfo->maxOutputChannels = 1; winDsDeviceInfo->deviceOutputChannelCountIsKnown = 1; } #ifdef PAWIN_USE_WDMKS_DEVICE_INFO if( pnpInterface ) { int count = PaWin_WDMKS_QueryFilterMaximumChannelCount( pnpInterface, /* isInput= */ 0 ); if( count > 0 ) { deviceInfo->maxOutputChannels = count; winDsDeviceInfo->deviceOutputChannelCountIsKnown = 1; } } #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ deviceInfo->defaultLowInputLatency = 0.; /** @todo IMPLEMENT ME */ deviceInfo->defaultLowOutputLatency = 0.; /** @todo IMPLEMENT ME */ deviceInfo->defaultHighInputLatency = 0.; /** @todo IMPLEMENT ME */ deviceInfo->defaultHighOutputLatency = 0.; /** @todo IMPLEMENT ME */ /* initialize defaultSampleRate */ if( caps.dwFlags & DSCAPS_CONTINUOUSRATE ) { /* initialize to caps.dwMaxSecondarySampleRate incase none of the standard rates match */ deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate; for( i = 0; i < PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_; ++i ) { if( defaultSampleRateSearchOrder_[i] >= caps.dwMinSecondarySampleRate && defaultSampleRateSearchOrder_[i] <= caps.dwMaxSecondarySampleRate ) { deviceInfo->defaultSampleRate = defaultSampleRateSearchOrder_[i]; break; } } } else if( caps.dwMinSecondarySampleRate == caps.dwMaxSecondarySampleRate ) { if( caps.dwMinSecondarySampleRate == 0 ) { /* ** On my Thinkpad 380Z, DirectSoundV6 returns min-max=0 !! ** But it supports continuous sampling. ** So fake range of rates, and hope it really supports it. */ deviceInfo->defaultSampleRate = 44100.0f; DBUG(("PA - Reported rates both zero. Setting to fake values for device #%s\n", name )); } else { deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate; } } else if( (caps.dwMinSecondarySampleRate < 1000.0) && (caps.dwMaxSecondarySampleRate > 50000.0) ) { /* The EWS88MT drivers lie, lie, lie. The say they only support two rates, 100 & 100000. ** But we know that they really support a range of rates! ** So when we see a ridiculous set of rates, assume it is a range. */ deviceInfo->defaultSampleRate = 44100.0f; DBUG(("PA - Sample rate range used instead of two odd values for device #%s\n", name )); } else deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate; //printf( "min %d max %d\n", caps.dwMinSecondarySampleRate, caps.dwMaxSecondarySampleRate ); // dwFlags | DSCAPS_CONTINUOUSRATE } } IDirectSound_Release( lpDirectSound ); } if( deviceOK ) { deviceInfo->name = name; if( lpGUID == NULL ) hostApi->info.defaultOutputDevice = hostApi->info.deviceCount; hostApi->info.deviceCount++; } return result; } /************************************************************************************ ** Extract capabilities from an input device, and add it to the device info list ** if successful. This function assumes that there is enough room in the ** device info list to accomodate all entries. ** ** The device will not be added to the device list if any errors are encountered. */ static PaError AddInputDeviceInfoFromDirectSoundCapture( PaWinDsHostApiRepresentation *winDsHostApi, char *name, LPGUID lpGUID, char *pnpInterface ) { PaUtilHostApiRepresentation *hostApi = &winDsHostApi->inheritedHostApiRep; PaWinDsDeviceInfo *winDsDeviceInfo = (PaWinDsDeviceInfo*) hostApi->deviceInfos[hostApi->info.deviceCount]; PaDeviceInfo *deviceInfo = &winDsDeviceInfo->inheritedDeviceInfo; HRESULT hr; LPDIRECTSOUNDCAPTURE lpDirectSoundCapture; DSCCAPS caps; int deviceOK = TRUE; PaError result = paNoError; /* Copy GUID to the device info structure. Set pointer. */ if( lpGUID == NULL ) { winDsDeviceInfo->lpGUID = NULL; } else { winDsDeviceInfo->lpGUID = &winDsDeviceInfo->guid; memcpy( &winDsDeviceInfo->guid, lpGUID, sizeof(GUID) ); } hr = paWinDsDSoundEntryPoints.DirectSoundCaptureCreate( lpGUID, &lpDirectSoundCapture, NULL ); /** try using CoCreateInstance because DirectSoundCreate was hanging under some circumstances - note this was probably related to the #define BOOL short bug which has now been fixed @todo delete this comment and the following code once we've ensured there is no bug. */ /* hr = CoCreateInstance( &CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSoundCapture, (void**)&lpDirectSoundCapture ); */ if( hr != DS_OK ) { DBUG(("Cannot create Capture for %s. Result = 0x%x\n", name, hr )); deviceOK = FALSE; } else { /* Query device characteristics. */ memset( &caps, 0, sizeof(caps) ); caps.dwSize = sizeof(caps); hr = IDirectSoundCapture_GetCaps( lpDirectSoundCapture, &caps ); if( hr != DS_OK ) { DBUG(("Cannot GetCaps() for Capture device %s. Result = 0x%x\n", name, hr )); deviceOK = FALSE; } else { #ifndef PA_NO_WMME if( caps.dwFlags & DSCAPS_EMULDRIVER ) { /* If WMME supported, then reject Emulated drivers because they are lousy. */ deviceOK = FALSE; } #endif if( deviceOK ) { deviceInfo->maxInputChannels = caps.dwChannels; winDsDeviceInfo->deviceInputChannelCountIsKnown = 1; deviceInfo->maxOutputChannels = 0; winDsDeviceInfo->deviceOutputChannelCountIsKnown = 1; #ifdef PAWIN_USE_WDMKS_DEVICE_INFO if( pnpInterface ) { int count = PaWin_WDMKS_QueryFilterMaximumChannelCount( pnpInterface, /* isInput= */ 1 ); if( count > 0 ) { deviceInfo->maxInputChannels = count; winDsDeviceInfo->deviceInputChannelCountIsKnown = 1; } } #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ deviceInfo->defaultLowInputLatency = 0.; /** @todo IMPLEMENT ME */ deviceInfo->defaultLowOutputLatency = 0.; /** @todo IMPLEMENT ME */ deviceInfo->defaultHighInputLatency = 0.; /** @todo IMPLEMENT ME */ deviceInfo->defaultHighOutputLatency = 0.; /** @todo IMPLEMENT ME */ /* constants from a WINE patch by Francois Gouget, see: http://www.winehq.com/hypermail/wine-patches/2003/01/0290.html --- Date: Fri, 14 May 2004 10:38:12 +0200 (CEST) From: Francois Gouget To: Ross Bencina Subject: Re: Permission to use wine 48/96 wave patch in BSD licensed library [snip] I give you permission to use the patch below under the BSD license. http://www.winehq.com/hypermail/wine-patches/2003/01/0290.html [snip] */ #ifndef WAVE_FORMAT_48M08 #define WAVE_FORMAT_48M08 0x00001000 /* 48 kHz, Mono, 8-bit */ #define WAVE_FORMAT_48S08 0x00002000 /* 48 kHz, Stereo, 8-bit */ #define WAVE_FORMAT_48M16 0x00004000 /* 48 kHz, Mono, 16-bit */ #define WAVE_FORMAT_48S16 0x00008000 /* 48 kHz, Stereo, 16-bit */ #define WAVE_FORMAT_96M08 0x00010000 /* 96 kHz, Mono, 8-bit */ #define WAVE_FORMAT_96S08 0x00020000 /* 96 kHz, Stereo, 8-bit */ #define WAVE_FORMAT_96M16 0x00040000 /* 96 kHz, Mono, 16-bit */ #define WAVE_FORMAT_96S16 0x00080000 /* 96 kHz, Stereo, 16-bit */ #endif /* defaultSampleRate */ if( caps.dwChannels == 2 ) { if( caps.dwFormats & WAVE_FORMAT_4S16 ) deviceInfo->defaultSampleRate = 44100.0; else if( caps.dwFormats & WAVE_FORMAT_48S16 ) deviceInfo->defaultSampleRate = 48000.0; else if( caps.dwFormats & WAVE_FORMAT_2S16 ) deviceInfo->defaultSampleRate = 22050.0; else if( caps.dwFormats & WAVE_FORMAT_1S16 ) deviceInfo->defaultSampleRate = 11025.0; else if( caps.dwFormats & WAVE_FORMAT_96S16 ) deviceInfo->defaultSampleRate = 96000.0; else deviceInfo->defaultSampleRate = 0.; } else if( caps.dwChannels == 1 ) { if( caps.dwFormats & WAVE_FORMAT_4M16 ) deviceInfo->defaultSampleRate = 44100.0; else if( caps.dwFormats & WAVE_FORMAT_48M16 ) deviceInfo->defaultSampleRate = 48000.0; else if( caps.dwFormats & WAVE_FORMAT_2M16 ) deviceInfo->defaultSampleRate = 22050.0; else if( caps.dwFormats & WAVE_FORMAT_1M16 ) deviceInfo->defaultSampleRate = 11025.0; else if( caps.dwFormats & WAVE_FORMAT_96M16 ) deviceInfo->defaultSampleRate = 96000.0; else deviceInfo->defaultSampleRate = 0.; } else deviceInfo->defaultSampleRate = 0.; } } IDirectSoundCapture_Release( lpDirectSoundCapture ); } if( deviceOK ) { deviceInfo->name = name; if( lpGUID == NULL ) hostApi->info.defaultInputDevice = hostApi->info.deviceCount; hostApi->info.deviceCount++; } return result; } /***********************************************************************************/ PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) { PaError result = paNoError; int i, deviceCount; PaWinDsHostApiRepresentation *winDsHostApi; DSDeviceNamesAndGUIDs deviceNamesAndGUIDs; PaWinDsDeviceInfo *deviceInfoArray; char comWasInitialized = 0; /* If COM is already initialized CoInitialize will either return FALSE, or RPC_E_CHANGED_MODE if it was initialised in a different threading mode. In either case we shouldn't consider it an error but we need to be careful to not call CoUninitialize() if RPC_E_CHANGED_MODE was returned. */ HRESULT hr = CoInitialize(NULL); if( FAILED(hr) && hr != RPC_E_CHANGED_MODE ) return paUnanticipatedHostError; if( hr != RPC_E_CHANGED_MODE ) comWasInitialized = 1; /* initialise guid vectors so they can be safely deleted on error */ deviceNamesAndGUIDs.winDsHostApi = NULL; deviceNamesAndGUIDs.inputNamesAndGUIDs.items = NULL; deviceNamesAndGUIDs.outputNamesAndGUIDs.items = NULL; PaWinDs_InitializeDSoundEntryPoints(); winDsHostApi = (PaWinDsHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaWinDsHostApiRepresentation) ); if( !winDsHostApi ) { result = paInsufficientMemory; goto error; } winDsHostApi->comWasInitialized = comWasInitialized; winDsHostApi->allocations = PaUtil_CreateAllocationGroup(); if( !winDsHostApi->allocations ) { result = paInsufficientMemory; goto error; } *hostApi = &winDsHostApi->inheritedHostApiRep; (*hostApi)->info.structVersion = 1; (*hostApi)->info.type = paDirectSound; (*hostApi)->info.name = "Windows DirectSound"; (*hostApi)->info.deviceCount = 0; (*hostApi)->info.defaultInputDevice = paNoDevice; (*hostApi)->info.defaultOutputDevice = paNoDevice; /* DSound - enumerate devices to count them and to gather their GUIDs */ result = InitializeDSDeviceNameAndGUIDVector( &deviceNamesAndGUIDs.inputNamesAndGUIDs, winDsHostApi->allocations ); if( result != paNoError ) goto error; result = InitializeDSDeviceNameAndGUIDVector( &deviceNamesAndGUIDs.outputNamesAndGUIDs, winDsHostApi->allocations ); if( result != paNoError ) goto error; paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK)CollectGUIDsProc, (void *)&deviceNamesAndGUIDs.inputNamesAndGUIDs ); paWinDsDSoundEntryPoints.DirectSoundEnumerate( (LPDSENUMCALLBACK)CollectGUIDsProc, (void *)&deviceNamesAndGUIDs.outputNamesAndGUIDs ); if( deviceNamesAndGUIDs.inputNamesAndGUIDs.enumerationError != paNoError ) { result = deviceNamesAndGUIDs.inputNamesAndGUIDs.enumerationError; goto error; } if( deviceNamesAndGUIDs.outputNamesAndGUIDs.enumerationError != paNoError ) { result = deviceNamesAndGUIDs.outputNamesAndGUIDs.enumerationError; goto error; } deviceCount = deviceNamesAndGUIDs.inputNamesAndGUIDs.count + deviceNamesAndGUIDs.outputNamesAndGUIDs.count; #ifdef PAWIN_USE_WDMKS_DEVICE_INFO if( deviceCount > 0 ) { deviceNamesAndGUIDs.winDsHostApi = winDsHostApi; FindDevicePnpInterfaces( &deviceNamesAndGUIDs ); } #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ if( deviceCount > 0 ) { /* allocate array for pointers to PaDeviceInfo structs */ (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( winDsHostApi->allocations, sizeof(PaDeviceInfo*) * deviceCount ); if( !(*hostApi)->deviceInfos ) { result = paInsufficientMemory; goto error; } /* allocate all PaDeviceInfo structs in a contiguous block */ deviceInfoArray = (PaWinDsDeviceInfo*)PaUtil_GroupAllocateMemory( winDsHostApi->allocations, sizeof(PaWinDsDeviceInfo) * deviceCount ); if( !deviceInfoArray ) { result = paInsufficientMemory; goto error; } for( i=0; i < deviceCount; ++i ) { PaDeviceInfo *deviceInfo = &deviceInfoArray[i].inheritedDeviceInfo; deviceInfo->structVersion = 2; deviceInfo->hostApi = hostApiIndex; deviceInfo->name = 0; (*hostApi)->deviceInfos[i] = deviceInfo; } for( i=0; i < deviceNamesAndGUIDs.inputNamesAndGUIDs.count; ++i ) { result = AddInputDeviceInfoFromDirectSoundCapture( winDsHostApi, deviceNamesAndGUIDs.inputNamesAndGUIDs.items[i].name, deviceNamesAndGUIDs.inputNamesAndGUIDs.items[i].lpGUID, deviceNamesAndGUIDs.inputNamesAndGUIDs.items[i].pnpInterface ); if( result != paNoError ) goto error; } for( i=0; i < deviceNamesAndGUIDs.outputNamesAndGUIDs.count; ++i ) { result = AddOutputDeviceInfoFromDirectSound( winDsHostApi, deviceNamesAndGUIDs.outputNamesAndGUIDs.items[i].name, deviceNamesAndGUIDs.outputNamesAndGUIDs.items[i].lpGUID, deviceNamesAndGUIDs.outputNamesAndGUIDs.items[i].pnpInterface ); if( result != paNoError ) goto error; } } result = TerminateDSDeviceNameAndGUIDVector( &deviceNamesAndGUIDs.inputNamesAndGUIDs ); if( result != paNoError ) goto error; result = TerminateDSDeviceNameAndGUIDVector( &deviceNamesAndGUIDs.outputNamesAndGUIDs ); if( result != paNoError ) goto error; (*hostApi)->Terminate = Terminate; (*hostApi)->OpenStream = OpenStream; (*hostApi)->IsFormatSupported = IsFormatSupported; PaUtil_InitializeStreamInterface( &winDsHostApi->callbackStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, GetStreamCpuLoad, PaUtil_DummyRead, PaUtil_DummyWrite, PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); PaUtil_InitializeStreamInterface( &winDsHostApi->blockingStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, PaUtil_DummyGetCpuLoad, ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable ); return result; error: if( winDsHostApi ) { if( winDsHostApi->allocations ) { PaUtil_FreeAllAllocations( winDsHostApi->allocations ); PaUtil_DestroyAllocationGroup( winDsHostApi->allocations ); } PaUtil_FreeMemory( winDsHostApi ); } TerminateDSDeviceNameAndGUIDVector( &deviceNamesAndGUIDs.inputNamesAndGUIDs ); TerminateDSDeviceNameAndGUIDVector( &deviceNamesAndGUIDs.outputNamesAndGUIDs ); if( comWasInitialized ) CoUninitialize(); return result; } /***********************************************************************************/ static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) { PaWinDsHostApiRepresentation *winDsHostApi = (PaWinDsHostApiRepresentation*)hostApi; char comWasInitialized = winDsHostApi->comWasInitialized; /* IMPLEMENT ME: - clean up any resources not handled by the allocation group */ if( winDsHostApi->allocations ) { PaUtil_FreeAllAllocations( winDsHostApi->allocations ); PaUtil_DestroyAllocationGroup( winDsHostApi->allocations ); } PaUtil_FreeMemory( winDsHostApi ); PaWinDs_TerminateDSoundEntryPoints(); if( comWasInitialized ) CoUninitialize(); } /* Set minimal latency based on whether NT or Win95. * NT has higher latency. */ static int PaWinDS_GetMinSystemLatency( void ) { int minLatencyMsec; /* Set minimal latency based on whether NT or other OS. * NT has higher latency. */ OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof( osvi ); GetVersionEx( &osvi ); DBUG(("PA - PlatformId = 0x%x\n", osvi.dwPlatformId )); DBUG(("PA - MajorVersion = 0x%x\n", osvi.dwMajorVersion )); DBUG(("PA - MinorVersion = 0x%x\n", osvi.dwMinorVersion )); /* Check for NT */ if( (osvi.dwMajorVersion == 4) && (osvi.dwPlatformId == 2) ) { minLatencyMsec = PA_WIN_NT_LATENCY; } else if(osvi.dwMajorVersion >= 5) { minLatencyMsec = PA_WIN_WDM_LATENCY; } else { minLatencyMsec = PA_WIN_9X_LATENCY; } return minLatencyMsec; } static PaError ValidateWinDirectSoundSpecificStreamInfo( const PaStreamParameters *streamParameters, const PaWinDirectSoundStreamInfo *streamInfo ) { if( streamInfo ) { if( streamInfo->size != sizeof( PaWinDirectSoundStreamInfo ) || streamInfo->version != 1 ) { return paIncompatibleHostApiSpecificStreamInfo; } } return paNoError; } /***********************************************************************************/ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { PaError result; PaWinDsDeviceInfo *inputWinDsDeviceInfo, *outputWinDsDeviceInfo; PaDeviceInfo *inputDeviceInfo, *outputDeviceInfo; int inputChannelCount, outputChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; PaWinDirectSoundStreamInfo *inputStreamInfo, *outputStreamInfo; if( inputParameters ) { inputWinDsDeviceInfo = (PaWinDsDeviceInfo*) hostApi->deviceInfos[ inputParameters->device ]; inputDeviceInfo = &inputWinDsDeviceInfo->inheritedDeviceInfo; inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that input device can support inputChannelCount */ if( inputWinDsDeviceInfo->deviceInputChannelCountIsKnown && inputChannelCount > inputDeviceInfo->maxInputChannels ) return paInvalidChannelCount; /* validate inputStreamInfo */ inputStreamInfo = (PaWinDirectSoundStreamInfo*)inputParameters->hostApiSpecificStreamInfo; result = ValidateWinDirectSoundSpecificStreamInfo( inputParameters, inputStreamInfo ); if( result != paNoError ) return result; } else { inputChannelCount = 0; } if( outputParameters ) { outputWinDsDeviceInfo = (PaWinDsDeviceInfo*) hostApi->deviceInfos[ outputParameters->device ]; outputDeviceInfo = &outputWinDsDeviceInfo->inheritedDeviceInfo; outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that output device can support inputChannelCount */ if( outputWinDsDeviceInfo->deviceOutputChannelCountIsKnown && outputChannelCount > outputDeviceInfo->maxOutputChannels ) return paInvalidChannelCount; /* validate outputStreamInfo */ outputStreamInfo = (PaWinDirectSoundStreamInfo*)outputParameters->hostApiSpecificStreamInfo; result = ValidateWinDirectSoundSpecificStreamInfo( outputParameters, outputStreamInfo ); if( result != paNoError ) return result; } else { outputChannelCount = 0; } /* IMPLEMENT ME: - if a full duplex stream is requested, check that the combination of input and output parameters is supported if necessary - check that the device supports sampleRate Because the buffer adapter handles conversion between all standard sample formats, the following checks are only required if paCustomFormat is implemented, or under some other unusual conditions. - check that input device can support inputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format - check that output device can support outputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format */ return paFormatIsSupported; } /************************************************************************* ** Determine minimum number of buffers required for this host based ** on minimum latency. Latency can be optionally set by user by setting ** an environment variable. For example, to set latency to 200 msec, put: ** ** set PA_MIN_LATENCY_MSEC=200 ** ** in the AUTOEXEC.BAT file and reboot. ** If the environment variable is not set, then the latency will be determined ** based on the OS. Windows NT has higher latency than Win95. */ #define PA_LATENCY_ENV_NAME ("PA_MIN_LATENCY_MSEC") #define PA_ENV_BUF_SIZE (32) static int PaWinDs_GetMinLatencyFrames( double sampleRate ) { char envbuf[PA_ENV_BUF_SIZE]; DWORD hresult; int minLatencyMsec = 0; /* Let user determine minimal latency by setting environment variable. */ hresult = GetEnvironmentVariableA( PA_LATENCY_ENV_NAME, envbuf, PA_ENV_BUF_SIZE ); if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) ) { minLatencyMsec = atoi( envbuf ); } else { minLatencyMsec = PaWinDS_GetMinSystemLatency(); #if PA_USE_HIGH_LATENCY PRINT(("PA - Minimum Latency set to %d msec!\n", minLatencyMsec )); #endif } return (int) (minLatencyMsec * sampleRate * SECONDS_PER_MSEC); } static HRESULT InitInputBuffer( PaWinDsStream *stream, PaSampleFormat sampleFormat, unsigned long nFrameRate, WORD nChannels, int bytesPerBuffer, PaWinWaveFormatChannelMask channelMask ) { DSCBUFFERDESC captureDesc; PaWinWaveFormat waveFormat; HRESULT result; stream->bytesPerInputFrame = nChannels * Pa_GetSampleSize(sampleFormat); stream->inputSize = bytesPerBuffer; // ---------------------------------------------------------------------- // Setup the secondary buffer description ZeroMemory(&captureDesc, sizeof(DSCBUFFERDESC)); captureDesc.dwSize = sizeof(DSCBUFFERDESC); captureDesc.dwFlags = 0; captureDesc.dwBufferBytes = bytesPerBuffer; captureDesc.lpwfxFormat = (WAVEFORMATEX*)&waveFormat; // Create the capture buffer // first try WAVEFORMATEXTENSIBLE. if this fails, fall back to WAVEFORMATEX PaWin_InitializeWaveFormatExtensible( &waveFormat, nChannels, sampleFormat, nFrameRate, channelMask ); if( IDirectSoundCapture_CreateCaptureBuffer( stream->pDirectSoundCapture, &captureDesc, &stream->pDirectSoundInputBuffer, NULL) != DS_OK ) { PaWin_InitializeWaveFormatEx( &waveFormat, nChannels, sampleFormat, nFrameRate ); if ((result = IDirectSoundCapture_CreateCaptureBuffer( stream->pDirectSoundCapture, &captureDesc, &stream->pDirectSoundInputBuffer, NULL)) != DS_OK) return result; } stream->readOffset = 0; // reset last read position to start of buffer return DS_OK; } static HRESULT InitOutputBuffer( PaWinDsStream *stream, PaSampleFormat sampleFormat, unsigned long nFrameRate, WORD nChannels, int bytesPerBuffer, PaWinWaveFormatChannelMask channelMask ) { /** @todo FIXME: if InitOutputBuffer returns an error I'm not sure it frees all resources cleanly */ DWORD dwDataLen; DWORD playCursor; HRESULT result; LPDIRECTSOUNDBUFFER pPrimaryBuffer; HWND hWnd; HRESULT hr; PaWinWaveFormat waveFormat; DSBUFFERDESC primaryDesc; DSBUFFERDESC secondaryDesc; unsigned char* pDSBuffData; LARGE_INTEGER counterFrequency; int bytesPerSample = Pa_GetSampleSize(sampleFormat); stream->outputBufferSizeBytes = bytesPerBuffer; stream->outputIsRunning = FALSE; stream->outputUnderflowCount = 0; stream->dsw_framesWritten = 0; stream->bytesPerOutputFrame = nChannels * bytesPerSample; // We were using getForegroundWindow() but sometimes the ForegroundWindow may not be the // applications's window. Also if that window is closed before the Buffer is closed // then DirectSound can crash. (Thanks for Scott Patterson for reporting this.) // So we will use GetDesktopWindow() which was suggested by Miller Puckette. // hWnd = GetForegroundWindow(); // // FIXME: The example code I have on the net creates a hidden window that // is managed by our code - I think we should do that - one hidden // window for the whole of Pa_DS // hWnd = GetDesktopWindow(); // Set cooperative level to DSSCL_EXCLUSIVE so that we can get 16 bit output, 44.1 KHz. // Exclusize also prevents unexpected sounds from other apps during a performance. if ((hr = IDirectSound_SetCooperativeLevel( stream->pDirectSound, hWnd, DSSCL_EXCLUSIVE)) != DS_OK) { return hr; } // ----------------------------------------------------------------------- // Create primary buffer and set format just so we can specify our custom format. // Otherwise we would be stuck with the default which might be 8 bit or 22050 Hz. // Setup the primary buffer description ZeroMemory(&primaryDesc, sizeof(DSBUFFERDESC)); primaryDesc.dwSize = sizeof(DSBUFFERDESC); primaryDesc.dwFlags = DSBCAPS_PRIMARYBUFFER; // all panning, mixing, etc done by synth primaryDesc.dwBufferBytes = 0; primaryDesc.lpwfxFormat = NULL; // Create the buffer if ((result = IDirectSound_CreateSoundBuffer( stream->pDirectSound, &primaryDesc, &pPrimaryBuffer, NULL)) != DS_OK) return result; // Set the primary buffer's format // first try WAVEFORMATEXTENSIBLE. if this fails, fall back to WAVEFORMATEX PaWin_InitializeWaveFormatExtensible( &waveFormat, nChannels, sampleFormat, nFrameRate, channelMask ); if( IDirectSoundBuffer_SetFormat( pPrimaryBuffer, (WAVEFORMATEX*)&waveFormat) != DS_OK ) { PaWin_InitializeWaveFormatEx( &waveFormat, nChannels, sampleFormat, nFrameRate ); if((result = IDirectSoundBuffer_SetFormat( pPrimaryBuffer, (WAVEFORMATEX*)&waveFormat)) != DS_OK) return result; } // ---------------------------------------------------------------------- // Setup the secondary buffer description ZeroMemory(&secondaryDesc, sizeof(DSBUFFERDESC)); secondaryDesc.dwSize = sizeof(DSBUFFERDESC); secondaryDesc.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2; secondaryDesc.dwBufferBytes = bytesPerBuffer; secondaryDesc.lpwfxFormat = (WAVEFORMATEX*)&waveFormat; // Create the secondary buffer if ((result = IDirectSound_CreateSoundBuffer( stream->pDirectSound, &secondaryDesc, &stream->pDirectSoundOutputBuffer, NULL)) != DS_OK) return result; // Lock the DS buffer if ((result = IDirectSoundBuffer_Lock( stream->pDirectSoundOutputBuffer, 0, stream->outputBufferSizeBytes, (LPVOID*)&pDSBuffData, &dwDataLen, NULL, 0, 0)) != DS_OK) return result; // Zero the DS buffer ZeroMemory(pDSBuffData, dwDataLen); // Unlock the DS buffer if ((result = IDirectSoundBuffer_Unlock( stream->pDirectSoundOutputBuffer, pDSBuffData, dwDataLen, NULL, 0)) != DS_OK) return result; if( QueryPerformanceFrequency( &counterFrequency ) ) { int framesInBuffer = bytesPerBuffer / (nChannels * bytesPerSample); stream->perfCounterTicksPerBuffer.QuadPart = (counterFrequency.QuadPart * framesInBuffer) / nFrameRate; } else { stream->perfCounterTicksPerBuffer.QuadPart = 0; } // Let DSound set the starting write position because if we set it to zero, it looks like the // buffer is full to begin with. This causes a long pause before sound starts when using large buffers. hr = IDirectSoundBuffer_GetCurrentPosition( stream->pDirectSoundOutputBuffer, &playCursor, &stream->outputBufferWriteOffsetBytes ); if( hr != DS_OK ) { return hr; } stream->dsw_framesWritten = stream->outputBufferWriteOffsetBytes / stream->bytesPerOutputFrame; /* printf("DSW_InitOutputBuffer: playCursor = %d, writeCursor = %d\n", playCursor, dsw->dsw_WriteOffset ); */ return DS_OK; } /***********************************************************************************/ /* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ) { PaError result = paNoError; PaWinDsHostApiRepresentation *winDsHostApi = (PaWinDsHostApiRepresentation*)hostApi; PaWinDsStream *stream = 0; PaWinDsDeviceInfo *inputWinDsDeviceInfo, *outputWinDsDeviceInfo; PaDeviceInfo *inputDeviceInfo, *outputDeviceInfo; int inputChannelCount, outputChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat; unsigned long suggestedInputLatencyFrames, suggestedOutputLatencyFrames; PaWinDirectSoundStreamInfo *inputStreamInfo, *outputStreamInfo; PaWinWaveFormatChannelMask inputChannelMask, outputChannelMask; if( inputParameters ) { inputWinDsDeviceInfo = (PaWinDsDeviceInfo*) hostApi->deviceInfos[ inputParameters->device ]; inputDeviceInfo = &inputWinDsDeviceInfo->inheritedDeviceInfo; inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; suggestedInputLatencyFrames = (unsigned long)(inputParameters->suggestedLatency * sampleRate); /* IDEA: the following 3 checks could be performed by default by pa_front unless some flag indicated otherwise */ /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that input device can support inputChannelCount */ if( inputWinDsDeviceInfo->deviceInputChannelCountIsKnown && inputChannelCount > inputDeviceInfo->maxInputChannels ) return paInvalidChannelCount; /* validate hostApiSpecificStreamInfo */ inputStreamInfo = (PaWinDirectSoundStreamInfo*)inputParameters->hostApiSpecificStreamInfo; result = ValidateWinDirectSoundSpecificStreamInfo( inputParameters, inputStreamInfo ); if( result != paNoError ) return result; if( inputStreamInfo && inputStreamInfo->flags & paWinDirectSoundUseChannelMask ) inputChannelMask = inputStreamInfo->channelMask; else inputChannelMask = PaWin_DefaultChannelMask( inputChannelCount ); } else { inputChannelCount = 0; inputSampleFormat = 0; suggestedInputLatencyFrames = 0; } if( outputParameters ) { outputWinDsDeviceInfo = (PaWinDsDeviceInfo*) hostApi->deviceInfos[ outputParameters->device ]; outputDeviceInfo = &outputWinDsDeviceInfo->inheritedDeviceInfo; outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; suggestedOutputLatencyFrames = (unsigned long)(outputParameters->suggestedLatency * sampleRate); /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that output device can support outputChannelCount */ if( outputWinDsDeviceInfo->deviceOutputChannelCountIsKnown && outputChannelCount > outputDeviceInfo->maxOutputChannels ) return paInvalidChannelCount; /* validate hostApiSpecificStreamInfo */ outputStreamInfo = (PaWinDirectSoundStreamInfo*)outputParameters->hostApiSpecificStreamInfo; result = ValidateWinDirectSoundSpecificStreamInfo( outputParameters, outputStreamInfo ); if( result != paNoError ) return result; if( outputStreamInfo && outputStreamInfo->flags & paWinDirectSoundUseChannelMask ) outputChannelMask = outputStreamInfo->channelMask; else outputChannelMask = PaWin_DefaultChannelMask( outputChannelCount ); } else { outputChannelCount = 0; outputSampleFormat = 0; suggestedOutputLatencyFrames = 0; } /* IMPLEMENT ME: ( the following two checks are taken care of by PaUtil_InitializeBufferProcessor() ) - check that input device can support inputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format - check that output device can support outputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format - if a full duplex stream is requested, check that the combination of input and output parameters is supported - check that the device supports sampleRate - alter sampleRate to a close allowable rate if possible / necessary - validate suggestedInputLatency and suggestedOutputLatency parameters, use default values where necessary */ /* validate platform specific flags */ if( (streamFlags & paPlatformSpecificFlags) != 0 ) return paInvalidFlag; /* unexpected platform specific flag */ stream = (PaWinDsStream*)PaUtil_AllocateMemory( sizeof(PaWinDsStream) ); if( !stream ) { result = paInsufficientMemory; goto error; } memset( stream, 0, sizeof(PaWinDsStream) ); /* initialize all stream variables to 0 */ if( streamCallback ) { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &winDsHostApi->callbackStreamInterface, streamCallback, userData ); } else { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &winDsHostApi->blockingStreamInterface, streamCallback, userData ); } PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate ); if( inputParameters ) { /* IMPLEMENT ME - establish which host formats are available */ PaSampleFormat nativeInputFormats = paInt16; //PaSampleFormat nativeFormats = paUInt8 | paInt16 | paInt24 | paInt32 | paFloat32; hostInputSampleFormat = PaUtil_SelectClosestAvailableFormat( nativeInputFormats, inputParameters->sampleFormat ); } else { hostInputSampleFormat = 0; } if( outputParameters ) { /* IMPLEMENT ME - establish which host formats are available */ PaSampleFormat nativeOutputFormats = paInt16; //PaSampleFormat nativeOutputFormats = paUInt8 | paInt16 | paInt24 | paInt32 | paFloat32; hostOutputSampleFormat = PaUtil_SelectClosestAvailableFormat( nativeOutputFormats, outputParameters->sampleFormat ); } else { hostOutputSampleFormat = 0; } result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, inputChannelCount, inputSampleFormat, hostInputSampleFormat, outputChannelCount, outputSampleFormat, hostOutputSampleFormat, sampleRate, streamFlags, framesPerBuffer, framesPerBuffer, /* ignored in paUtilVariableHostBufferSizePartialUsageAllowed mode. */ /* This next mode is required because DS can split the host buffer when it wraps around. */ paUtilVariableHostBufferSizePartialUsageAllowed, streamCallback, userData ); if( result != paNoError ) goto error; stream->streamRepresentation.streamInfo.inputLatency = PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor); /* FIXME: not initialised anywhere else */ stream->streamRepresentation.streamInfo.outputLatency = PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor); /* FIXME: not initialised anywhere else */ stream->streamRepresentation.streamInfo.sampleRate = sampleRate; /* DirectSound specific initialization */ { HRESULT hr; int bytesPerDirectSoundBuffer; int userLatencyFrames; int minLatencyFrames; stream->timerID = 0; /* Get system minimum latency. */ minLatencyFrames = PaWinDs_GetMinLatencyFrames( sampleRate ); /* Let user override latency by passing latency parameter. */ userLatencyFrames = (suggestedInputLatencyFrames > suggestedOutputLatencyFrames) ? suggestedInputLatencyFrames : suggestedOutputLatencyFrames; if( userLatencyFrames > 0 ) minLatencyFrames = userLatencyFrames; /* Calculate stream->framesPerDSBuffer depending on framesPerBuffer */ if( framesPerBuffer == paFramesPerBufferUnspecified ) { /* App support variable framesPerBuffer */ stream->framesPerDSBuffer = minLatencyFrames; stream->streamRepresentation.streamInfo.outputLatency = (double)(minLatencyFrames - 1) / sampleRate; } else { /* Round up to number of buffers needed to guarantee that latency. */ int numUserBuffers = (minLatencyFrames + framesPerBuffer - 1) / framesPerBuffer; if( numUserBuffers < 1 ) numUserBuffers = 1; numUserBuffers += 1; /* So we have latency worth of buffers ahead of current buffer. */ stream->framesPerDSBuffer = framesPerBuffer * numUserBuffers; stream->streamRepresentation.streamInfo.outputLatency = (double)(framesPerBuffer * (numUserBuffers-1)) / sampleRate; } { /** @todo REVIEW: this calculation seems incorrect to me - rossb. */ int msecLatency = (int) ((stream->framesPerDSBuffer * MSEC_PER_SECOND) / sampleRate); PRINT(("PortAudio on DirectSound - Latency = %d frames, %d msec\n", stream->framesPerDSBuffer, msecLatency )); } /* ------------------ OUTPUT */ if( outputParameters ) { /* PaDeviceInfo *deviceInfo = hostApi->deviceInfos[ outputParameters->device ]; DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", outputParameters->device)); */ int bytesPerSample = Pa_GetSampleSize(hostOutputSampleFormat); bytesPerDirectSoundBuffer = stream->framesPerDSBuffer * outputParameters->channelCount * bytesPerSample; if( bytesPerDirectSoundBuffer < DSBSIZE_MIN ) { result = paBufferTooSmall; goto error; } else if( bytesPerDirectSoundBuffer > DSBSIZE_MAX ) { result = paBufferTooBig; goto error; } hr = paWinDsDSoundEntryPoints.DirectSoundCreate( ((PaWinDsDeviceInfo*)hostApi->deviceInfos[outputParameters->device])->lpGUID, &stream->pDirectSound, NULL ); if( hr != DS_OK ) { ERR_RPT(("PortAudio: DirectSoundCreate() failed!\n")); result = paUnanticipatedHostError; PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr ); goto error; } hr = InitOutputBuffer( stream, hostOutputSampleFormat, (unsigned long) (sampleRate + 0.5), (WORD)outputParameters->channelCount, bytesPerDirectSoundBuffer, outputChannelMask ); DBUG(("InitOutputBuffer() returns %x\n", hr)); if( hr != DS_OK ) { result = paUnanticipatedHostError; PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr ); goto error; } /* Calculate value used in latency calculation to avoid real-time divides. */ stream->secondsPerHostByte = 1.0 / (stream->bufferProcessor.bytesPerHostOutputSample * outputChannelCount * sampleRate); } /* ------------------ INPUT */ if( inputParameters ) { /* PaDeviceInfo *deviceInfo = hostApi->deviceInfos[ inputParameters->device ]; DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", inputParameters->device)); */ int bytesPerSample = Pa_GetSampleSize(hostInputSampleFormat); bytesPerDirectSoundBuffer = stream->framesPerDSBuffer * inputParameters->channelCount * bytesPerSample; if( bytesPerDirectSoundBuffer < DSBSIZE_MIN ) { result = paBufferTooSmall; goto error; } else if( bytesPerDirectSoundBuffer > DSBSIZE_MAX ) { result = paBufferTooBig; goto error; } hr = paWinDsDSoundEntryPoints.DirectSoundCaptureCreate( ((PaWinDsDeviceInfo*)hostApi->deviceInfos[inputParameters->device])->lpGUID, &stream->pDirectSoundCapture, NULL ); if( hr != DS_OK ) { ERR_RPT(("PortAudio: DirectSoundCaptureCreate() failed!\n")); result = paUnanticipatedHostError; PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr ); goto error; } hr = InitInputBuffer( stream, hostInputSampleFormat, (unsigned long) (sampleRate + 0.5), (WORD)inputParameters->channelCount, bytesPerDirectSoundBuffer, inputChannelMask ); DBUG(("InitInputBuffer() returns %x\n", hr)); if( hr != DS_OK ) { ERR_RPT(("PortAudio: DSW_InitInputBuffer() returns %x\n", hr)); result = paUnanticipatedHostError; PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr ); goto error; } } } *s = (PaStream*)stream; return result; error: if( stream ) PaUtil_FreeMemory( stream ); return result; } /************************************************************************************ * Determine how much space can be safely written to in DS buffer. * Detect underflows and overflows. * Does not allow writing into safety gap maintained by DirectSound. */ static HRESULT QueryOutputSpace( PaWinDsStream *stream, long *bytesEmpty ) { HRESULT hr; DWORD playCursor; DWORD writeCursor; long numBytesEmpty; long playWriteGap; // Query to see how much room is in buffer. hr = IDirectSoundBuffer_GetCurrentPosition( stream->pDirectSoundOutputBuffer, &playCursor, &writeCursor ); if( hr != DS_OK ) { return hr; } // Determine size of gap between playIndex and WriteIndex that we cannot write into. playWriteGap = writeCursor - playCursor; if( playWriteGap < 0 ) playWriteGap += stream->outputBufferSizeBytes; // unwrap /* DirectSound doesn't have a large enough playCursor so we cannot detect wrap-around. */ /* Attempt to detect playCursor wrap-around and correct it. */ if( stream->outputIsRunning && (stream->perfCounterTicksPerBuffer.QuadPart != 0) ) { /* How much time has elapsed since last check. */ LARGE_INTEGER currentTime; LARGE_INTEGER elapsedTime; long bytesPlayed; long bytesExpected; long buffersWrapped; QueryPerformanceCounter( ¤tTime ); elapsedTime.QuadPart = currentTime.QuadPart - stream->previousPlayTime.QuadPart; stream->previousPlayTime = currentTime; /* How many bytes does DirectSound say have been played. */ bytesPlayed = playCursor - stream->previousPlayCursor; if( bytesPlayed < 0 ) bytesPlayed += stream->outputBufferSizeBytes; // unwrap stream->previousPlayCursor = playCursor; /* Calculate how many bytes we would have expected to been played by now. */ bytesExpected = (long) ((elapsedTime.QuadPart * stream->outputBufferSizeBytes) / stream->perfCounterTicksPerBuffer.QuadPart); buffersWrapped = (bytesExpected - bytesPlayed) / stream->outputBufferSizeBytes; if( buffersWrapped > 0 ) { playCursor += (buffersWrapped * stream->outputBufferSizeBytes); bytesPlayed += (buffersWrapped * stream->outputBufferSizeBytes); } /* Maintain frame output cursor. */ stream->framesPlayed += (bytesPlayed / stream->bytesPerOutputFrame); } numBytesEmpty = playCursor - stream->outputBufferWriteOffsetBytes; if( numBytesEmpty < 0 ) numBytesEmpty += stream->outputBufferSizeBytes; // unwrap offset /* Have we underflowed? */ if( numBytesEmpty > (stream->outputBufferSizeBytes - playWriteGap) ) { if( stream->outputIsRunning ) { stream->outputUnderflowCount += 1; } stream->outputBufferWriteOffsetBytes = writeCursor; numBytesEmpty = stream->outputBufferSizeBytes - playWriteGap; } *bytesEmpty = numBytesEmpty; return hr; } /***********************************************************************************/ static PaError Pa_TimeSlice( PaWinDsStream *stream ) { PaError result = 0; /* FIXME: this should be declared int and this function should also return that type (same as stream callback return type)*/ long numFrames = 0; long bytesEmpty = 0; long bytesFilled = 0; long bytesToXfer = 0; long framesToXfer = 0; long numInFramesReady = 0; long numOutFramesReady = 0; long bytesProcessed; HRESULT hresult; double outputLatency = 0; PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /** @todo implement inputBufferAdcTime */ /* Input */ LPBYTE lpInBuf1 = NULL; LPBYTE lpInBuf2 = NULL; DWORD dwInSize1 = 0; DWORD dwInSize2 = 0; /* Output */ LPBYTE lpOutBuf1 = NULL; LPBYTE lpOutBuf2 = NULL; DWORD dwOutSize1 = 0; DWORD dwOutSize2 = 0; /* How much input data is available? */ if( stream->bufferProcessor.inputChannelCount > 0 ) { HRESULT hr; DWORD capturePos; DWORD readPos; long filled = 0; // Query to see how much data is in buffer. // We don't need the capture position but sometimes DirectSound doesn't handle NULLS correctly // so let's pass a pointer just to be safe. hr = IDirectSoundCaptureBuffer_GetCurrentPosition( stream->pDirectSoundInputBuffer, &capturePos, &readPos ); if( hr == DS_OK ) { filled = readPos - stream->readOffset; if( filled < 0 ) filled += stream->inputSize; // unwrap offset bytesFilled = filled; } // FIXME: what happens if IDirectSoundCaptureBuffer_GetCurrentPosition fails? framesToXfer = numInFramesReady = bytesFilled / stream->bytesPerInputFrame; outputLatency = ((double)bytesFilled) * stream->secondsPerHostByte; /** @todo Check for overflow */ } /* How much output room is available? */ if( stream->bufferProcessor.outputChannelCount > 0 ) { UINT previousUnderflowCount = stream->outputUnderflowCount; QueryOutputSpace( stream, &bytesEmpty ); framesToXfer = numOutFramesReady = bytesEmpty / stream->bytesPerOutputFrame; /* Check for underflow */ if( stream->outputUnderflowCount != previousUnderflowCount ) stream->callbackFlags |= paOutputUnderflow; } if( (numInFramesReady > 0) && (numOutFramesReady > 0) ) { framesToXfer = (numOutFramesReady < numInFramesReady) ? numOutFramesReady : numInFramesReady; } if( framesToXfer > 0 ) { PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); /* The outputBufferDacTime parameter should indicates the time at which the first sample of the output buffer is heard at the DACs. */ timeInfo.currentTime = PaUtil_GetTime(); timeInfo.outputBufferDacTime = timeInfo.currentTime + outputLatency; PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, stream->callbackFlags ); stream->callbackFlags = 0; /* Input */ if( stream->bufferProcessor.inputChannelCount > 0 ) { bytesToXfer = framesToXfer * stream->bytesPerInputFrame; hresult = IDirectSoundCaptureBuffer_Lock ( stream->pDirectSoundInputBuffer, stream->readOffset, bytesToXfer, (void **) &lpInBuf1, &dwInSize1, (void **) &lpInBuf2, &dwInSize2, 0); if (hresult != DS_OK) { ERR_RPT(("DirectSound IDirectSoundCaptureBuffer_Lock failed, hresult = 0x%x\n",hresult)); result = paUnanticipatedHostError; PA_DS_SET_LAST_DIRECTSOUND_ERROR( hresult ); goto error2; } numFrames = dwInSize1 / stream->bytesPerInputFrame; PaUtil_SetInputFrameCount( &stream->bufferProcessor, numFrames ); PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, 0, lpInBuf1, 0 ); /* Is input split into two regions. */ if( dwInSize2 > 0 ) { numFrames = dwInSize2 / stream->bytesPerInputFrame; PaUtil_Set2ndInputFrameCount( &stream->bufferProcessor, numFrames ); PaUtil_Set2ndInterleavedInputChannels( &stream->bufferProcessor, 0, lpInBuf2, 0 ); } } /* Output */ if( stream->bufferProcessor.outputChannelCount > 0 ) { bytesToXfer = framesToXfer * stream->bytesPerOutputFrame; hresult = IDirectSoundBuffer_Lock ( stream->pDirectSoundOutputBuffer, stream->outputBufferWriteOffsetBytes, bytesToXfer, (void **) &lpOutBuf1, &dwOutSize1, (void **) &lpOutBuf2, &dwOutSize2, 0); if (hresult != DS_OK) { ERR_RPT(("DirectSound IDirectSoundBuffer_Lock failed, hresult = 0x%x\n",hresult)); result = paUnanticipatedHostError; PA_DS_SET_LAST_DIRECTSOUND_ERROR( hresult ); goto error1; } numFrames = dwOutSize1 / stream->bytesPerOutputFrame; PaUtil_SetOutputFrameCount( &stream->bufferProcessor, numFrames ); PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, 0, lpOutBuf1, 0 ); /* Is output split into two regions. */ if( dwOutSize2 > 0 ) { numFrames = dwOutSize2 / stream->bytesPerOutputFrame; PaUtil_Set2ndOutputFrameCount( &stream->bufferProcessor, numFrames ); PaUtil_Set2ndInterleavedOutputChannels( &stream->bufferProcessor, 0, lpOutBuf2, 0 ); } } result = paContinue; numFrames = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &result ); stream->framesWritten += numFrames; if( stream->bufferProcessor.outputChannelCount > 0 ) { /* FIXME: an underflow could happen here */ /* Update our buffer offset and unlock sound buffer */ bytesProcessed = numFrames * stream->bytesPerOutputFrame; stream->outputBufferWriteOffsetBytes = (stream->outputBufferWriteOffsetBytes + bytesProcessed) % stream->outputBufferSizeBytes; IDirectSoundBuffer_Unlock( stream->pDirectSoundOutputBuffer, lpOutBuf1, dwOutSize1, lpOutBuf2, dwOutSize2); stream->dsw_framesWritten += numFrames; } error1: if( stream->bufferProcessor.inputChannelCount > 0 ) { /* FIXME: an overflow could happen here */ /* Update our buffer offset and unlock sound buffer */ bytesProcessed = numFrames * stream->bytesPerInputFrame; stream->readOffset = (stream->readOffset + bytesProcessed) % stream->inputSize; IDirectSoundCaptureBuffer_Unlock( stream->pDirectSoundInputBuffer, lpInBuf1, dwInSize1, lpInBuf2, dwInSize2); } error2: PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, numFrames ); } return result; } /*******************************************************************/ static HRESULT ZeroAvailableOutputSpace( PaWinDsStream *stream ) { HRESULT hr; LPBYTE lpbuf1 = NULL; LPBYTE lpbuf2 = NULL; DWORD dwsize1 = 0; DWORD dwsize2 = 0; long bytesEmpty; hr = QueryOutputSpace( stream, &bytesEmpty ); // updates framesPlayed if (hr != DS_OK) return hr; if( bytesEmpty == 0 ) return DS_OK; // Lock free space in the DS hr = IDirectSoundBuffer_Lock( stream->pDirectSoundOutputBuffer, stream->outputBufferWriteOffsetBytes, bytesEmpty, (void **) &lpbuf1, &dwsize1, (void **) &lpbuf2, &dwsize2, 0); if (hr == DS_OK) { // Copy the buffer into the DS ZeroMemory(lpbuf1, dwsize1); if(lpbuf2 != NULL) { ZeroMemory(lpbuf2, dwsize2); } // Update our buffer offset and unlock sound buffer stream->outputBufferWriteOffsetBytes = (stream->outputBufferWriteOffsetBytes + dwsize1 + dwsize2) % stream->outputBufferSizeBytes; IDirectSoundBuffer_Unlock( stream->pDirectSoundOutputBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2); stream->dsw_framesWritten += bytesEmpty / stream->bytesPerOutputFrame; } return hr; } static void CALLBACK Pa_TimerCallback(UINT uID, UINT uMsg, DWORD_PTR dwUser, DWORD dw1, DWORD dw2) { PaWinDsStream *stream; /* suppress unused variable warnings */ (void) uID; (void) uMsg; (void) dw1; (void) dw2; stream = (PaWinDsStream *) dwUser; if( stream == NULL ) return; if( stream->isActive ) { if( stream->abortProcessing ) { stream->isActive = 0; } else if( stream->stopProcessing ) { if( stream->bufferProcessor.outputChannelCount > 0 ) { ZeroAvailableOutputSpace( stream ); /* clear isActive when all sound played */ if( stream->framesPlayed >= stream->framesWritten ) { stream->isActive = 0; } } else { stream->isActive = 0; } } else { if( Pa_TimeSlice( stream ) != 0) /* Call time slice independant of timing method. */ { /* FIXME implement handling of paComplete and paAbort if possible */ stream->stopProcessing = 1; } } if( !stream->isActive ) { if( stream->streamRepresentation.streamFinishedCallback != 0 ) stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); } } } /*********************************************************************************** When CloseStream() is called, the multi-api layer ensures that the stream has already been stopped or aborted. */ static PaError CloseStream( PaStream* s ) { PaError result = paNoError; PaWinDsStream *stream = (PaWinDsStream*)s; // Cleanup the sound buffers if( stream->pDirectSoundOutputBuffer ) { IDirectSoundBuffer_Stop( stream->pDirectSoundOutputBuffer ); IDirectSoundBuffer_Release( stream->pDirectSoundOutputBuffer ); stream->pDirectSoundOutputBuffer = NULL; } if( stream->pDirectSoundInputBuffer ) { IDirectSoundCaptureBuffer_Stop( stream->pDirectSoundInputBuffer ); IDirectSoundCaptureBuffer_Release( stream->pDirectSoundInputBuffer ); stream->pDirectSoundInputBuffer = NULL; } if( stream->pDirectSoundCapture ) { IDirectSoundCapture_Release( stream->pDirectSoundCapture ); stream->pDirectSoundCapture = NULL; } if( stream->pDirectSound ) { IDirectSound_Release( stream->pDirectSound ); stream->pDirectSound = NULL; } PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); PaUtil_FreeMemory( stream ); return result; } /***********************************************************************************/ static PaError StartStream( PaStream *s ) { PaError result = paNoError; PaWinDsStream *stream = (PaWinDsStream*)s; HRESULT hr; PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); if( stream->bufferProcessor.inputChannelCount > 0 ) { // Start the buffer playback if( stream->pDirectSoundInputBuffer != NULL ) // FIXME: not sure this check is necessary { hr = IDirectSoundCaptureBuffer_Start( stream->pDirectSoundInputBuffer, DSCBSTART_LOOPING ); } DBUG(("StartStream: DSW_StartInput returned = 0x%X.\n", hr)); if( hr != DS_OK ) { result = paUnanticipatedHostError; PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr ); goto error; } } stream->framesWritten = 0; stream->callbackFlags = 0; stream->abortProcessing = 0; stream->stopProcessing = 0; stream->isActive = 1; if( stream->bufferProcessor.outputChannelCount > 0 ) { /* Give user callback a chance to pre-fill buffer. REVIEW - i thought we weren't pre-filling, rb. */ result = Pa_TimeSlice( stream ); if( result != paNoError ) return result; // FIXME - what if finished? QueryPerformanceCounter( &stream->previousPlayTime ); stream->previousPlayCursor = 0; stream->framesPlayed = 0; hr = IDirectSoundBuffer_SetCurrentPosition( stream->pDirectSoundOutputBuffer, 0 ); DBUG(("PaHost_StartOutput: IDirectSoundBuffer_SetCurrentPosition returned = 0x%X.\n", hr)); if( hr != DS_OK ) { result = paUnanticipatedHostError; PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr ); goto error; } // Start the buffer playback in a loop. if( stream->pDirectSoundOutputBuffer != NULL ) // FIXME: not sure this needs to be checked here { hr = IDirectSoundBuffer_Play( stream->pDirectSoundOutputBuffer, 0, 0, DSBPLAY_LOOPING ); DBUG(("PaHost_StartOutput: IDirectSoundBuffer_Play returned = 0x%X.\n", hr)); if( hr != DS_OK ) { result = paUnanticipatedHostError; PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr ); goto error; } stream->outputIsRunning = TRUE; } } /* Create timer that will wake us up so we can fill the DSound buffer. */ { int resolution; int framesPerWakeup = stream->framesPerDSBuffer / 4; int msecPerWakeup = MSEC_PER_SECOND * framesPerWakeup / (int) stream->streamRepresentation.streamInfo.sampleRate; if( msecPerWakeup < 10 ) msecPerWakeup = 10; else if( msecPerWakeup > 100 ) msecPerWakeup = 100; resolution = msecPerWakeup/4; stream->timerID = timeSetEvent( msecPerWakeup, resolution, (LPTIMECALLBACK) Pa_TimerCallback, (DWORD_PTR) stream, TIME_PERIODIC ); } if( stream->timerID == 0 ) { stream->isActive = 0; result = paUnanticipatedHostError; PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr ); goto error; } stream->isStarted = TRUE; error: return result; } /***********************************************************************************/ static PaError StopStream( PaStream *s ) { PaError result = paNoError; PaWinDsStream *stream = (PaWinDsStream*)s; HRESULT hr; int timeoutMsec; stream->stopProcessing = 1; /* Set timeout at 20% beyond maximum time we might wait. */ timeoutMsec = (int) (1200.0 * stream->framesPerDSBuffer / stream->streamRepresentation.streamInfo.sampleRate); while( stream->isActive && (timeoutMsec > 0) ) { Sleep(10); timeoutMsec -= 10; } if( stream->timerID != 0 ) { timeKillEvent(stream->timerID); /* Stop callback timer. */ stream->timerID = 0; } if( stream->bufferProcessor.outputChannelCount > 0 ) { // Stop the buffer playback if( stream->pDirectSoundOutputBuffer != NULL ) { stream->outputIsRunning = FALSE; // FIXME: what happens if IDirectSoundBuffer_Stop returns an error? hr = IDirectSoundBuffer_Stop( stream->pDirectSoundOutputBuffer ); } } if( stream->bufferProcessor.inputChannelCount > 0 ) { // Stop the buffer capture if( stream->pDirectSoundInputBuffer != NULL ) { // FIXME: what happens if IDirectSoundCaptureBuffer_Stop returns an error? hr = IDirectSoundCaptureBuffer_Stop( stream->pDirectSoundInputBuffer ); } } stream->isStarted = FALSE; return result; } /***********************************************************************************/ static PaError AbortStream( PaStream *s ) { PaWinDsStream *stream = (PaWinDsStream*)s; stream->abortProcessing = 1; return StopStream( s ); } /***********************************************************************************/ static PaError IsStreamStopped( PaStream *s ) { PaWinDsStream *stream = (PaWinDsStream*)s; return !stream->isStarted; } /***********************************************************************************/ static PaError IsStreamActive( PaStream *s ) { PaWinDsStream *stream = (PaWinDsStream*)s; return stream->isActive; } /***********************************************************************************/ static PaTime GetStreamTime( PaStream *s ) { /* suppress unused variable warnings */ (void) s; return PaUtil_GetTime(); } /***********************************************************************************/ static double GetStreamCpuLoad( PaStream* s ) { PaWinDsStream *stream = (PaWinDsStream*)s; return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); } /*********************************************************************************** As separate stream interfaces are used for blocking and callback streams, the following functions can be guaranteed to only be called for blocking streams. */ static PaError ReadStream( PaStream* s, void *buffer, unsigned long frames ) { PaWinDsStream *stream = (PaWinDsStream*)s; /* suppress unused variable warnings */ (void) buffer; (void) frames; (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ return paNoError; } /***********************************************************************************/ static PaError WriteStream( PaStream* s, const void *buffer, unsigned long frames ) { PaWinDsStream *stream = (PaWinDsStream*)s; /* suppress unused variable warnings */ (void) buffer; (void) frames; (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ return paNoError; } /***********************************************************************************/ static signed long GetStreamReadAvailable( PaStream* s ) { PaWinDsStream *stream = (PaWinDsStream*)s; /* suppress unused variable warnings */ (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ return 0; } /***********************************************************************************/ static signed long GetStreamWriteAvailable( PaStream* s ) { PaWinDsStream *stream = (PaWinDsStream*)s; /* suppress unused variable warnings */ (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ return 0; } #endif praat-6.0.04/external/portaudio2007/pa_win_ds.h000066400000000000000000000071561261542461700212060ustar00rootroot00000000000000#ifndef PA_WIN_DS_H #define PA_WIN_DS_H /* * $Id: $ * PortAudio Portable Real-Time Audio Library * DirectSound specific extensions * * Copyright (c) 1999-2007 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @brief DirectSound-specific PortAudio API extension header file. */ #include "portaudio.h" #include "pa_win_waveformat.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define paWinDirectSoundUseLowLevelLatencyParameters (0x01) #define paWinDirectSoundUseChannelMask (0x04) typedef struct PaWinDirectSoundStreamInfo{ unsigned long size; /**< sizeof(PaWinDirectSoundStreamInfo) */ PaHostApiTypeId hostApiType; /**< paDirectSound */ unsigned long version; /**< 1 */ unsigned long flags; /* low-level latency setting support TODO ** NOT IMPLEMENTED ** These settings control the number and size of host buffers in order to set latency. They will be used instead of the generic parameters to Pa_OpenStream() if flags contains the paWinDirectSoundUseLowLevelLatencyParameters flag. If PaWinDirectSoundStreamInfo structures with paWinDirectSoundUseLowLevelLatencyParameters are supplied for both input and output in a full duplex stream, then the input and output framesPerBuffer must be the same, or the larger of the two must be a multiple of the smaller, otherwise a paIncompatibleHostApiSpecificStreamInfo error will be returned from Pa_OpenStream(). unsigned long framesPerBuffer; */ /* support for WAVEFORMATEXTENSIBLE channel masks. If flags contains paWinDirectSoundUseChannelMask this allows you to specify which speakers to address in a multichannel stream. Constants for channelMask are specified in pa_win_waveformat.h */ PaWinWaveFormatChannelMask channelMask; }PaWinDirectSoundStreamInfo; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_WIN_DS_H */ praat-6.0.04/external/portaudio2007/pa_win_ds_dynlink.c000066400000000000000000000174731261542461700227340ustar00rootroot00000000000000/* * Interface for dynamically loading directsound and providing a dummy * implementation if it isn't present. * * Author: Ross Bencina (some portions Phil Burk & Robert Marsanyi) * * For PortAudio Portable Real-Time Audio Library * For more information see: http://www.portaudio.com * Copyright (c) 1999-2006 Phil Burk, Robert Marsanyi and Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostaip_src */ #undef UNICODE #include "pa_win_ds_dynlink.h" PaWinDsDSoundEntryPoints paWinDsDSoundEntryPoints = { 0, 0, 0, 0, 0, 0, 0 }; static HRESULT WINAPI DummyDllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { (void)rclsid; /* unused parameter */ (void)riid; /* unused parameter */ (void)ppv; /* unused parameter */ return CLASS_E_CLASSNOTAVAILABLE; } static HRESULT WINAPI DummyDirectSoundCreate(LPGUID lpcGuidDevice, LPDIRECTSOUND *ppDS, LPUNKNOWN pUnkOuter) { (void)lpcGuidDevice; /* unused parameter */ (void)ppDS; /* unused parameter */ (void)pUnkOuter; /* unused parameter */ return E_NOTIMPL; } static HRESULT WINAPI DummyDirectSoundEnumerateW(LPDSENUMCALLBACKW lpDSEnumCallback, LPVOID lpContext) { (void)lpDSEnumCallback; /* unused parameter */ (void)lpContext; /* unused parameter */ return E_NOTIMPL; } static HRESULT WINAPI DummyDirectSoundEnumerateA(LPDSENUMCALLBACKA lpDSEnumCallback, LPVOID lpContext) { (void)lpDSEnumCallback; /* unused parameter */ (void)lpContext; /* unused parameter */ return E_NOTIMPL; } static HRESULT WINAPI DummyDirectSoundCaptureCreate(LPGUID lpcGUID, LPDIRECTSOUNDCAPTURE *lplpDSC, LPUNKNOWN pUnkOuter) { (void)lpcGUID; /* unused parameter */ (void)lplpDSC; /* unused parameter */ (void)pUnkOuter; /* unused parameter */ return E_NOTIMPL; } static HRESULT WINAPI DummyDirectSoundCaptureEnumerateW(LPDSENUMCALLBACKW lpDSCEnumCallback, LPVOID lpContext) { (void)lpDSCEnumCallback; /* unused parameter */ (void)lpContext; /* unused parameter */ return E_NOTIMPL; } static HRESULT WINAPI DummyDirectSoundCaptureEnumerateA(LPDSENUMCALLBACKA lpDSCEnumCallback, LPVOID lpContext) { (void)lpDSCEnumCallback; /* unused parameter */ (void)lpContext; /* unused parameter */ return E_NOTIMPL; } void PaWinDs_InitializeDSoundEntryPoints(void) { paWinDsDSoundEntryPoints.hInstance_ = LoadLibraryA("dsound.dll"); if( paWinDsDSoundEntryPoints.hInstance_ != NULL ) { paWinDsDSoundEntryPoints.DllGetClassObject = (HRESULT (WINAPI *)(REFCLSID, REFIID , LPVOID *)) GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DllGetClassObject" ); if( paWinDsDSoundEntryPoints.DllGetClassObject == NULL ) paWinDsDSoundEntryPoints.DllGetClassObject = DummyDllGetClassObject; paWinDsDSoundEntryPoints.DirectSoundCreate = (HRESULT (WINAPI *)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN)) GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundCreate" ); if( paWinDsDSoundEntryPoints.DirectSoundCreate == NULL ) paWinDsDSoundEntryPoints.DirectSoundCreate = DummyDirectSoundCreate; paWinDsDSoundEntryPoints.DirectSoundEnumerateW = (HRESULT (WINAPI *)(LPDSENUMCALLBACKW, LPVOID)) GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundEnumerateW" ); if( paWinDsDSoundEntryPoints.DirectSoundEnumerateW == NULL ) paWinDsDSoundEntryPoints.DirectSoundEnumerateW = DummyDirectSoundEnumerateW; paWinDsDSoundEntryPoints.DirectSoundEnumerateA = (HRESULT (WINAPI *)(LPDSENUMCALLBACKA, LPVOID)) GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundEnumerateA" ); if( paWinDsDSoundEntryPoints.DirectSoundEnumerateA == NULL ) paWinDsDSoundEntryPoints.DirectSoundEnumerateA = DummyDirectSoundEnumerateA; paWinDsDSoundEntryPoints.DirectSoundCaptureCreate = (HRESULT (WINAPI *)(LPGUID, LPDIRECTSOUNDCAPTURE *, LPUNKNOWN)) GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundCaptureCreate" ); if( paWinDsDSoundEntryPoints.DirectSoundCaptureCreate == NULL ) paWinDsDSoundEntryPoints.DirectSoundCaptureCreate = DummyDirectSoundCaptureCreate; paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW = (HRESULT (WINAPI *)(LPDSENUMCALLBACKW, LPVOID)) GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundCaptureEnumerateW" ); if( paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW == NULL ) paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW = DummyDirectSoundCaptureEnumerateW; paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA = (HRESULT (WINAPI *)(LPDSENUMCALLBACKA, LPVOID)) GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundCaptureEnumerateA" ); if( paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA == NULL ) paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA = DummyDirectSoundCaptureEnumerateA; } else { /* initialize with dummy entry points to make live easy when ds isn't present */ paWinDsDSoundEntryPoints.DirectSoundCreate = DummyDirectSoundCreate; paWinDsDSoundEntryPoints.DirectSoundEnumerateW = DummyDirectSoundEnumerateW; paWinDsDSoundEntryPoints.DirectSoundEnumerateA = DummyDirectSoundEnumerateA; paWinDsDSoundEntryPoints.DirectSoundCaptureCreate = DummyDirectSoundCaptureCreate; paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW = DummyDirectSoundCaptureEnumerateW; paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA = DummyDirectSoundCaptureEnumerateA; } } void PaWinDs_TerminateDSoundEntryPoints(void) { if( paWinDsDSoundEntryPoints.hInstance_ != NULL ) { /* ensure that we crash reliably if the entry points arent initialised */ paWinDsDSoundEntryPoints.DirectSoundCreate = 0; paWinDsDSoundEntryPoints.DirectSoundEnumerateW = 0; paWinDsDSoundEntryPoints.DirectSoundEnumerateA = 0; paWinDsDSoundEntryPoints.DirectSoundCaptureCreate = 0; paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW = 0; paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA = 0; FreeLibrary( paWinDsDSoundEntryPoints.hInstance_ ); paWinDsDSoundEntryPoints.hInstance_ = NULL; } }praat-6.0.04/external/portaudio2007/pa_win_ds_dynlink.h000066400000000000000000000063341261542461700227330ustar00rootroot00000000000000/* * Interface for dynamically loading directsound and providing a dummy * implementation if it isn't present. * * Author: Ross Bencina (some portions Phil Burk & Robert Marsanyi) * * For PortAudio Portable Real-Time Audio Library * For more information see: http://www.portaudio.com * Copyright (c) 1999-2006 Phil Burk, Robert Marsanyi and Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostaip_src */ #ifndef INCLUDED_PA_DSOUND_DYNLINK_H #define INCLUDED_PA_DSOUND_DYNLINK_H /* on Borland compilers, WIN32 doesn't seem to be defined by default, which breaks dsound.h. Adding the define here fixes the problem. - rossb. */ #ifdef __BORLANDC__ #if !defined(WIN32) #define WIN32 #endif #endif /* We are only using DX3 in here, no need to polute the namespace - davidv */ #define DIRECTSOUND_VERSION 0x0300 #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ typedef struct { HINSTANCE hInstance_; HRESULT (WINAPI *DllGetClassObject)(REFCLSID , REFIID , LPVOID *); HRESULT (WINAPI *DirectSoundCreate)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN); HRESULT (WINAPI *DirectSoundEnumerateW)(LPDSENUMCALLBACKW, LPVOID); HRESULT (WINAPI *DirectSoundEnumerateA)(LPDSENUMCALLBACKA, LPVOID); HRESULT (WINAPI *DirectSoundCaptureCreate)(LPGUID, LPDIRECTSOUNDCAPTURE *, LPUNKNOWN); HRESULT (WINAPI *DirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW, LPVOID); HRESULT (WINAPI *DirectSoundCaptureEnumerateA)(LPDSENUMCALLBACKA, LPVOID); }PaWinDsDSoundEntryPoints; extern PaWinDsDSoundEntryPoints paWinDsDSoundEntryPoints; void PaWinDs_InitializeDSoundEntryPoints(void); void PaWinDs_TerminateDSoundEntryPoints(void); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* INCLUDED_PA_DSOUND_DYNLINK_H */ praat-6.0.04/external/portaudio2007/pa_win_hostapis.c000066400000000000000000000057721261542461700224270ustar00rootroot00000000000000#ifdef _WIN32 /* * $Id: pa_win_hostapis.c 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library Windows initialization table * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup win_src Win32 host API initialization function table. @todo Consider using PA_USE_WMME etc instead of PA_NO_WMME. This is what the Unix version does, we should consider being consistent. */ #include "pa_hostapi.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaWinWdm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaWinWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); #ifdef __cplusplus } #endif /* __cplusplus */ PaUtilHostApiInitializer *paHostApiInitializers[] = { PaSkeleton_Initialize, // 0; just for testing PaWinMme_Initialize, // 1 //PaWinDs_Initialize, // 2 //PaWinWdm_Initialize, // 3 //PaAsio_Initialize, //PaWinWasapi_Initialize, 0 /* NULL terminated array */ }; int paDefaultHostApiIndex = 1; #endif praat-6.0.04/external/portaudio2007/pa_win_util.c000066400000000000000000000074021261542461700215420ustar00rootroot00000000000000#ifdef _WIN32 /* * $Id: pa_win_util.c 1197 2007-05-04 13:07:10Z gordon_gidluck $ * Portable Audio I/O Library * Win32 platform-specific support functions * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2000 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup win_src Win32 platform-specific support functions. @todo Implement workaround for QueryPerformanceCounter() skipping forward bug. (see msdn kb Q274323). */ #undef UNICODE #include #include /* for timeGetTime() */ #include "pa_util.h" /* Track memory allocations to avoid leaks. */ #if PA_TRACK_MEMORY static int numAllocations_ = 0; #endif void *PaUtil_AllocateMemory( long size ) { void *result = GlobalAlloc( GPTR, size ); #if PA_TRACK_MEMORY if( result != NULL ) numAllocations_ += 1; #endif return result; } void PaUtil_FreeMemory( void *block ) { if( block != NULL ) { GlobalFree( block ); #if PA_TRACK_MEMORY numAllocations_ -= 1; #endif } } int PaUtil_CountCurrentlyAllocatedBlocks( void ) { #if PA_TRACK_MEMORY return numAllocations_; #else return 0; #endif } void Pa_Sleep( long msec ) { Sleep( msec ); } static int usePerformanceCounter_; static double secondsPerTick_; void PaUtil_InitializeClock( void ) { LARGE_INTEGER ticksPerSecond; if( QueryPerformanceFrequency( &ticksPerSecond ) != 0 ) { usePerformanceCounter_ = 1; secondsPerTick_ = 1.0 / (double)ticksPerSecond.QuadPart; } else { usePerformanceCounter_ = 0; } } double PaUtil_GetTime( void ) { LARGE_INTEGER time; if( usePerformanceCounter_ ) { /* FIXME: according to this knowledge-base article, QueryPerformanceCounter can skip forward by seconds! http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q274323& it may be better to use the rtdsc instruction using inline asm, however then a method is needed to calculate a ticks/seconds ratio. */ QueryPerformanceCounter( &time ); return time.QuadPart * secondsPerTick_; } else { #ifndef UNDER_CE return timeGetTime() * .001; #else return GetTickCount() * .001; #endif } } #endif praat-6.0.04/external/portaudio2007/pa_win_waveformat.c000066400000000000000000000140731261542461700227420ustar00rootroot00000000000000#ifdef _WIN32 /* * PortAudio Portable Real-Time Audio Library * Windows WAVEFORMAT* data structure utilities * portaudio.h should be included before this file. * * Copyright (c) 2007 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ #undef UNICODE #include #include #include "portaudio.h" #include "pa_win_waveformat.h" #if !defined(WAVE_FORMAT_EXTENSIBLE) #define WAVE_FORMAT_EXTENSIBLE 0xFFFE #endif #if !defined(WAVE_FORMAT_IEEE_FLOAT) #define WAVE_FORMAT_IEEE_FLOAT 0x0003 #endif static GUID pawin_ksDataFormatSubtypePcm = { (USHORT)(WAVE_FORMAT_PCM), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }; static GUID pawin_ksDataFormatSubtypeIeeeFloat = { (USHORT)(WAVE_FORMAT_IEEE_FLOAT), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }; void PaWin_InitializeWaveFormatEx( PaWinWaveFormat *waveFormat, int numChannels, PaSampleFormat sampleFormat, double sampleRate ) { WAVEFORMATEX *waveFormatEx = (WAVEFORMATEX*)waveFormat; int bytesPerSample = Pa_GetSampleSize(sampleFormat); unsigned long bytesPerFrame = numChannels * bytesPerSample; if( sampleFormat == paFloat32 ) waveFormatEx->wFormatTag = WAVE_FORMAT_IEEE_FLOAT; else waveFormatEx->wFormatTag = WAVE_FORMAT_PCM; waveFormatEx->nChannels = (WORD)numChannels; waveFormatEx->nSamplesPerSec = (DWORD)sampleRate; waveFormatEx->nAvgBytesPerSec = waveFormatEx->nSamplesPerSec * bytesPerFrame; waveFormatEx->nBlockAlign = (WORD)bytesPerFrame; waveFormatEx->wBitsPerSample = bytesPerSample * 8; waveFormatEx->cbSize = 0; } void PaWin_InitializeWaveFormatExtensible( PaWinWaveFormat *waveFormat, int numChannels, PaSampleFormat sampleFormat, double sampleRate, PaWinWaveFormatChannelMask channelMask ) { WAVEFORMATEX *waveFormatEx = (WAVEFORMATEX*)waveFormat; int bytesPerSample = Pa_GetSampleSize(sampleFormat); unsigned long bytesPerFrame = numChannels * bytesPerSample; waveFormatEx->wFormatTag = WAVE_FORMAT_EXTENSIBLE; waveFormatEx->nChannels = (WORD)numChannels; waveFormatEx->nSamplesPerSec = (DWORD)sampleRate; waveFormatEx->nAvgBytesPerSec = waveFormatEx->nSamplesPerSec * bytesPerFrame; waveFormatEx->nBlockAlign = (WORD)bytesPerFrame; waveFormatEx->wBitsPerSample = bytesPerSample * 8; waveFormatEx->cbSize = 22; *((WORD*)&waveFormat->fields[PAWIN_INDEXOF_WVALIDBITSPERSAMPLE]) = waveFormatEx->wBitsPerSample; *((DWORD*)&waveFormat->fields[PAWIN_INDEXOF_DWCHANNELMASK]) = channelMask; if( sampleFormat == paFloat32 ) *((GUID*)&waveFormat->fields[PAWIN_INDEXOF_SUBFORMAT]) = pawin_ksDataFormatSubtypeIeeeFloat; else *((GUID*)&waveFormat->fields[PAWIN_INDEXOF_SUBFORMAT]) = pawin_ksDataFormatSubtypePcm; } PaWinWaveFormatChannelMask PaWin_DefaultChannelMask( int numChannels ) { switch( numChannels ){ case 1: return PAWIN_SPEAKER_MONO; case 2: return PAWIN_SPEAKER_STEREO; case 3: return PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_FRONT_RIGHT; case 4: return PAWIN_SPEAKER_QUAD; case 5: return PAWIN_SPEAKER_QUAD | PAWIN_SPEAKER_FRONT_CENTER; case 6: /* The meaning of the PAWIN_SPEAKER_5POINT1 flag has changed over time: http://msdn2.microsoft.com/en-us/library/aa474707.aspx We use PAWIN_SPEAKER_5POINT1 (not PAWIN_SPEAKER_5POINT1_SURROUND) because on some cards (eg Audigy) PAWIN_SPEAKER_5POINT1_SURROUND results in a virtual mixdown placing the rear output in the front _and_ rear speakers. */ return PAWIN_SPEAKER_5POINT1; /* case 7: */ case 8: return PAWIN_SPEAKER_7POINT1; } /* Apparently some Audigy drivers will output silence if the direct-out constant (0) is used. So this is not ideal. */ return PAWIN_SPEAKER_DIRECTOUT; /* Note that Alec Rogers proposed the following as an alternate method to generate the default channel mask, however it doesn't seem to be an improvement over the above, since some drivers will matrix outputs mapping to non-present speakers accross multiple physical speakers. if(nChannels==1) { pwfFormat->dwChannelMask = SPEAKER_FRONT_CENTER; } else { pwfFormat->dwChannelMask = 0; for(i=0; idwChannelMask = (pwfFormat->dwChannelMask << 1) | 0x1; } */ } #endif praat-6.0.04/external/portaudio2007/pa_win_waveformat.h000066400000000000000000000202341261542461700227430ustar00rootroot00000000000000#ifndef PA_WIN_WAVEFORMAT_H #define PA_WIN_WAVEFORMAT_H /* * PortAudio Portable Real-Time Audio Library * Windows WAVEFORMAT* data structure utilities * portaudio.h should be included before this file. * * Copyright (c) 2007 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @brief Windows specific PortAudio API extension and utilities header file. */ #ifdef __cplusplus extern "C" { #endif /* The following #defines for speaker channel masks are the same as those in ksmedia.h, except with PAWIN_ prepended, KSAUDIO_ removed in some cases, and casts to PaWinWaveFormatChannelMask added. */ typedef unsigned long PaWinWaveFormatChannelMask; /* Speaker Positions: */ #define PAWIN_SPEAKER_FRONT_LEFT ((PaWinWaveFormatChannelMask)0x1) #define PAWIN_SPEAKER_FRONT_RIGHT ((PaWinWaveFormatChannelMask)0x2) #define PAWIN_SPEAKER_FRONT_CENTER ((PaWinWaveFormatChannelMask)0x4) #define PAWIN_SPEAKER_LOW_FREQUENCY ((PaWinWaveFormatChannelMask)0x8) #define PAWIN_SPEAKER_BACK_LEFT ((PaWinWaveFormatChannelMask)0x10) #define PAWIN_SPEAKER_BACK_RIGHT ((PaWinWaveFormatChannelMask)0x20) #define PAWIN_SPEAKER_FRONT_LEFT_OF_CENTER ((PaWinWaveFormatChannelMask)0x40) #define PAWIN_SPEAKER_FRONT_RIGHT_OF_CENTER ((PaWinWaveFormatChannelMask)0x80) #define PAWIN_SPEAKER_BACK_CENTER ((PaWinWaveFormatChannelMask)0x100) #define PAWIN_SPEAKER_SIDE_LEFT ((PaWinWaveFormatChannelMask)0x200) #define PAWIN_SPEAKER_SIDE_RIGHT ((PaWinWaveFormatChannelMask)0x400) #define PAWIN_SPEAKER_TOP_CENTER ((PaWinWaveFormatChannelMask)0x800) #define PAWIN_SPEAKER_TOP_FRONT_LEFT ((PaWinWaveFormatChannelMask)0x1000) #define PAWIN_SPEAKER_TOP_FRONT_CENTER ((PaWinWaveFormatChannelMask)0x2000) #define PAWIN_SPEAKER_TOP_FRONT_RIGHT ((PaWinWaveFormatChannelMask)0x4000) #define PAWIN_SPEAKER_TOP_BACK_LEFT ((PaWinWaveFormatChannelMask)0x8000) #define PAWIN_SPEAKER_TOP_BACK_CENTER ((PaWinWaveFormatChannelMask)0x10000) #define PAWIN_SPEAKER_TOP_BACK_RIGHT ((PaWinWaveFormatChannelMask)0x20000) /* Bit mask locations reserved for future use */ #define PAWIN_SPEAKER_RESERVED ((PaWinWaveFormatChannelMask)0x7FFC0000) /* Used to specify that any possible permutation of speaker configurations */ #define PAWIN_SPEAKER_ALL ((PaWinWaveFormatChannelMask)0x80000000) /* DirectSound Speaker Config */ #define PAWIN_SPEAKER_DIRECTOUT 0 #define PAWIN_SPEAKER_MONO (PAWIN_SPEAKER_FRONT_CENTER) #define PAWIN_SPEAKER_STEREO (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT) #define PAWIN_SPEAKER_QUAD (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \ PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT) #define PAWIN_SPEAKER_SURROUND (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \ PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_BACK_CENTER) #define PAWIN_SPEAKER_5POINT1 (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \ PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \ PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT) #define PAWIN_SPEAKER_7POINT1 (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \ PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \ PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT | \ PAWIN_SPEAKER_FRONT_LEFT_OF_CENTER | PAWIN_SPEAKER_FRONT_RIGHT_OF_CENTER) #define PAWIN_SPEAKER_5POINT1_SURROUND (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \ PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \ PAWIN_SPEAKER_SIDE_LEFT | PAWIN_SPEAKER_SIDE_RIGHT) #define PAWIN_SPEAKER_7POINT1_SURROUND (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \ PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \ PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT | \ PAWIN_SPEAKER_SIDE_LEFT | PAWIN_SPEAKER_SIDE_RIGHT) /* According to the Microsoft documentation: The following are obsolete 5.1 and 7.1 settings (they lack side speakers). Note this means that the default 5.1 and 7.1 settings (KSAUDIO_SPEAKER_5POINT1 and KSAUDIO_SPEAKER_7POINT1 are similarly obsolete but are unchanged for compatibility reasons). */ #define PAWIN_SPEAKER_5POINT1_BACK PAWIN_SPEAKER_5POINT1 #define PAWIN_SPEAKER_7POINT1_WIDE PAWIN_SPEAKER_7POINT1 /* DVD Speaker Positions */ #define PAWIN_SPEAKER_GROUND_FRONT_LEFT PAWIN_SPEAKER_FRONT_LEFT #define PAWIN_SPEAKER_GROUND_FRONT_CENTER PAWIN_SPEAKER_FRONT_CENTER #define PAWIN_SPEAKER_GROUND_FRONT_RIGHT PAWIN_SPEAKER_FRONT_RIGHT #define PAWIN_SPEAKER_GROUND_REAR_LEFT PAWIN_SPEAKER_BACK_LEFT #define PAWIN_SPEAKER_GROUND_REAR_RIGHT PAWIN_SPEAKER_BACK_RIGHT #define PAWIN_SPEAKER_TOP_MIDDLE PAWIN_SPEAKER_TOP_CENTER #define PAWIN_SPEAKER_SUPER_WOOFER PAWIN_SPEAKER_LOW_FREQUENCY /* PaWinWaveFormat is defined here to provide compatibility with compilation environments which don't have headers defining WAVEFORMATEXTENSIBLE (e.g. older versions of MSVC, Borland C++ etc. The fields for WAVEFORMATEX and WAVEFORMATEXTENSIBLE are declared as an unsigned char array here to avoid clients who include this file having a dependency on windows.h and mmsystem.h, and also to to avoid having to write separate packing pragmas for each compiler. */ #define PAWIN_SIZEOF_WAVEFORMATEX 18 #define PAWIN_SIZEOF_WAVEFORMATEXTENSIBLE (PAWIN_SIZEOF_WAVEFORMATEX + 22) typedef struct{ unsigned char fields[ PAWIN_SIZEOF_WAVEFORMATEXTENSIBLE ]; unsigned long extraLongForAlignment; /* ensure that compiler aligns struct to DWORD */ } PaWinWaveFormat; /* WAVEFORMATEXTENSIBLE fields: union { WORD wValidBitsPerSample; WORD wSamplesPerBlock; WORD wReserved; } Samples; DWORD dwChannelMask; GUID SubFormat; */ #define PAWIN_INDEXOF_WVALIDBITSPERSAMPLE (PAWIN_SIZEOF_WAVEFORMATEX+0) #define PAWIN_INDEXOF_DWCHANNELMASK (PAWIN_SIZEOF_WAVEFORMATEX+2) #define PAWIN_INDEXOF_SUBFORMAT (PAWIN_SIZEOF_WAVEFORMATEX+6) /* Use the following two functions to initialize the waveformat structure. */ void PaWin_InitializeWaveFormatEx( PaWinWaveFormat *waveFormat, int numChannels, PaSampleFormat sampleFormat, double sampleRate ); void PaWin_InitializeWaveFormatExtensible( PaWinWaveFormat *waveFormat, int numChannels, PaSampleFormat sampleFormat, double sampleRate, PaWinWaveFormatChannelMask channelMask ); /* Map a channel count to a speaker channel mask */ PaWinWaveFormatChannelMask PaWin_DefaultChannelMask( int numChannels ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_WIN_WAVEFORMAT_H */praat-6.0.04/external/portaudio2007/pa_win_wdmks.c000066400000000000000000003223001261542461700217070ustar00rootroot00000000000000/* * $Id: pa_win_wdmks.c 1263 2007-08-27 22:59:09Z rossb $ * PortAudio Windows WDM-KS interface * * Author: Andrew Baldwin * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2004 Andrew Baldwin, Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostaip_src @brief Portaudio WDM-KS host API. @note This is the implementation of the Portaudio host API using the Windows WDM/Kernel Streaming API in order to enable very low latency playback and recording on all modern Windows platforms (e.g. 2K, XP) Note: This API accesses the device drivers below the usual KMIXER component which is normally used to enable multi-client mixing and format conversion. That means that it will lock out all other users of a device for the duration of active stream using those devices */ #include /* Debugging/tracing support */ #define PA_LOGE_ #define PA_LOGL_ #ifdef __GNUC__ #include #define _WIN32_WINNT 0x0501 #define WINVER 0x0501 #endif #include /* strlen() */ #include #include "pa_util.h" #include "pa_allocation.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_cpuload.h" #include "pa_process.h" #include "portaudio.h" #include "pa_debugprint.h" #include #include // ppgb 20080707: #define _INC_MMSYSTEM #define _INC_MMREG #define DYNAMIC_GUID_THUNK(l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} #define DYNAMIC_GUID(data) DYNAMIC_GUID_THUNK(data) #define _NTRTL_ /* Turn off default definition of DEFINE_GUIDEX */ #define DEFINE_GUID_THUNK(name,guid) DEFINE_GUID(name,guid) #define DEFINE_GUIDEX(n) DEFINE_GUID_THUNK( n, STATIC_##n ) #if !defined( DEFINE_WAVEFORMATEX_GUID ) #define DEFINE_WAVEFORMATEX_GUID(x) (USHORT)(x), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 #endif #define WAVE_FORMAT_ADPCM 0x0002 #define WAVE_FORMAT_IEEE_FLOAT 0x0003 #define WAVE_FORMAT_ALAW 0x0006 #define WAVE_FORMAT_MULAW 0x0007 #define WAVE_FORMAT_MPEG 0x0050 #define WAVE_FORMAT_DRM 0x0009 #ifdef __GNUC__ #undef PA_LOGE_ #define PA_LOGE_ PA_DEBUG(("%s {\n",__FUNCTION__)) #undef PA_LOGL_ #define PA_LOGL_ PA_DEBUG(("} %s\n",__FUNCTION__)) /* These defines are set in order to allow the WIndows DirectX * headers to compile with a GCC compiler such as MinGW * NOTE: The headers may generate a few warning in GCC, but * they should compile */ #define _INC_MMSYSTEM #define _INC_MMREG #define _NTRTL_ /* Turn off default definition of DEFINE_GUIDEX */ #define DEFINE_GUID_THUNK(name,guid) DEFINE_GUID(name,guid) #define DEFINE_GUIDEX(n) DEFINE_GUID_THUNK( n, STATIC_##n ) #if !defined( DEFINE_WAVEFORMATEX_GUID ) #define DEFINE_WAVEFORMATEX_GUID(x) (USHORT)(x), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 #endif #define WAVE_FORMAT_ADPCM 0x0002 #define WAVE_FORMAT_IEEE_FLOAT 0x0003 #define WAVE_FORMAT_ALAW 0x0006 #define WAVE_FORMAT_MULAW 0x0007 #define WAVE_FORMAT_MPEG 0x0050 #define WAVE_FORMAT_DRM 0x0009 #define DYNAMIC_GUID_THUNK(l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} #define DYNAMIC_GUID(data) DYNAMIC_GUID_THUNK(data) #endif #ifdef _MSC_VER #define DYNAMIC_GUID(data) {data} #define _INC_MMREG #define _NTRTL_ /* Turn off default definition of DEFINE_GUIDEX */ #undef DEFINE_GUID #define DEFINE_GUID(n,data) EXTERN_C const GUID n = {data} #define DEFINE_GUID_THUNK(n,data) DEFINE_GUID(n,data) #define DEFINE_GUIDEX(n) DEFINE_GUID_THUNK(n, STATIC_##n) #if !defined( DEFINE_WAVEFORMATEX_GUID ) #define DEFINE_WAVEFORMATEX_GUID(x) (USHORT)(x), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 #endif #define WAVE_FORMAT_ADPCM 0x0002 #define WAVE_FORMAT_IEEE_FLOAT 0x0003 #define WAVE_FORMAT_ALAW 0x0006 #define WAVE_FORMAT_MULAW 0x0007 #define WAVE_FORMAT_MPEG 0x0050 #define WAVE_FORMAT_DRM 0x0009 #endif #include #include #include #include #include /* These next definitions allow the use of the KSUSER DLL */ typedef /*KSDDKAPI ppgb 20080707*/ DWORD WINAPI KSCREATEPIN(HANDLE, PKSPIN_CONNECT, ACCESS_MASK, PHANDLE); extern HMODULE DllKsUser; extern KSCREATEPIN* FunctionKsCreatePin; /* Forward definition to break circular type reference between pin and filter */ struct __PaWinWdmFilter; typedef struct __PaWinWdmFilter PaWinWdmFilter; /* The Pin structure * A pin is an input or output node, e.g. for audio flow */ typedef struct __PaWinWdmPin { HANDLE handle; PaWinWdmFilter* parentFilter; unsigned long pinId; KSPIN_CONNECT* pinConnect; unsigned long pinConnectSize; KSDATAFORMAT_WAVEFORMATEX* ksDataFormatWfx; KSPIN_COMMUNICATION communication; KSDATARANGE* dataRanges; KSMULTIPLE_ITEM* dataRangesItem; KSPIN_DATAFLOW dataFlow; KSPIN_CINSTANCES instances; unsigned long frameSize; int maxChannels; unsigned long formats; int bestSampleRate; } PaWinWdmPin; /* The Filter structure * A filter has a number of pins and a "friendly name" */ struct __PaWinWdmFilter { HANDLE handle; int pinCount; PaWinWdmPin** pins; TCHAR filterName[MAX_PATH]; TCHAR friendlyName[MAX_PATH]; int maxInputChannels; int maxOutputChannels; unsigned long formats; int usageCount; int bestSampleRate; }; /* PaWinWdmHostApiRepresentation - host api datastructure specific to this implementation */ typedef struct __PaWinWdmHostApiRepresentation { PaUtilHostApiRepresentation inheritedHostApiRep; PaUtilStreamInterface callbackStreamInterface; PaUtilStreamInterface blockingStreamInterface; PaUtilAllocationGroup* allocations; PaWinWdmFilter** filters; int filterCount; } PaWinWdmHostApiRepresentation; typedef struct __PaWinWdmDeviceInfo { PaDeviceInfo inheritedDeviceInfo; PaWinWdmFilter* filter; } PaWinWdmDeviceInfo; typedef struct __DATAPACKET { KSSTREAM_HEADER Header; OVERLAPPED Signal; } DATAPACKET; /* PaWinWdmStream - a stream data structure specifically for this implementation */ typedef struct __PaWinWdmStream { PaUtilStreamRepresentation streamRepresentation; PaUtilCpuLoadMeasurer cpuLoadMeasurer; PaUtilBufferProcessor bufferProcessor; PaWinWdmPin* recordingPin; PaWinWdmPin* playbackPin; char* hostBuffer; unsigned long framesPerHostIBuffer; unsigned long framesPerHostOBuffer; int bytesPerInputFrame; int bytesPerOutputFrame; int streamStarted; int streamActive; int streamStop; int streamAbort; int oldProcessPriority; HANDLE streamThread; HANDLE events[5]; /* 2 play + 2 record packets + abort events */ DATAPACKET packets[4]; /* 2 play + 2 record */ PaStreamFlags streamFlags; /* These values handle the case where the user wants to use fewer * channels than the device has */ int userInputChannels; int deviceInputChannels; int userOutputChannels; int deviceOutputChannels; int inputSampleSize; int outputSampleSize; } PaWinWdmStream; #include HMODULE DllKsUser = NULL; KSCREATEPIN* FunctionKsCreatePin = NULL; /* prototypes for functions declared in this file */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ PaError PaWinWdm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); #ifdef __cplusplus } #endif /* __cplusplus */ /* Low level I/O functions */ static PaError WdmSyncIoctl(HANDLE handle, unsigned long ioctlNumber, void* inBuffer, unsigned long inBufferCount, void* outBuffer, unsigned long outBufferCount, unsigned long* bytesReturned); static PaError WdmGetPropertySimple(HANDLE handle, const GUID* const guidPropertySet, unsigned long property, void* value, unsigned long valueCount, void* instance, unsigned long instanceCount); static PaError WdmSetPropertySimple(HANDLE handle, const GUID* const guidPropertySet, unsigned long property, void* value, unsigned long valueCount, void* instance, unsigned long instanceCount); static PaError WdmGetPinPropertySimple(HANDLE handle, unsigned long pinId, const GUID* const guidPropertySet, unsigned long property, void* value, unsigned long valueCount); static PaError WdmGetPinPropertyMulti(HANDLE handle, unsigned long pinId, const GUID* const guidPropertySet, unsigned long property, KSMULTIPLE_ITEM** ksMultipleItem); /** Pin management functions */ static PaWinWdmPin* PinNew(PaWinWdmFilter* parentFilter, unsigned long pinId, PaError* error); static void PinFree(PaWinWdmPin* pin); static void PinClose(PaWinWdmPin* pin); static PaError PinInstantiate(PaWinWdmPin* pin); /*static PaError PinGetState(PaWinWdmPin* pin, KSSTATE* state); NOT USED */ static PaError PinSetState(PaWinWdmPin* pin, KSSTATE state); static PaError PinSetFormat(PaWinWdmPin* pin, const WAVEFORMATEX* format); static PaError PinIsFormatSupported(PaWinWdmPin* pin, const WAVEFORMATEX* format); /* Filter management functions */ static PaWinWdmFilter* FilterNew( TCHAR* filterName, TCHAR* friendlyName, PaError* error); static void FilterFree(PaWinWdmFilter* filter); static PaWinWdmPin* FilterCreateRenderPin( PaWinWdmFilter* filter, const WAVEFORMATEX* wfex, PaError* error); static PaWinWdmPin* FilterFindViableRenderPin( PaWinWdmFilter* filter, const WAVEFORMATEX* wfex, PaError* error); static PaError FilterCanCreateRenderPin( PaWinWdmFilter* filter, const WAVEFORMATEX* wfex); static PaWinWdmPin* FilterCreateCapturePin( PaWinWdmFilter* filter, const WAVEFORMATEX* wfex, PaError* error); static PaWinWdmPin* FilterFindViableCapturePin( PaWinWdmFilter* filter, const WAVEFORMATEX* wfex, PaError* error); static PaError FilterCanCreateCapturePin( PaWinWdmFilter* filter, const WAVEFORMATEX* pwfx); static PaError FilterUse( PaWinWdmFilter* filter); static void FilterRelease( PaWinWdmFilter* filter); /* Interface functions */ static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); static PaError CloseStream( PaStream* stream ); static PaError StartStream( PaStream *stream ); static PaError StopStream( PaStream *stream ); static PaError AbortStream( PaStream *stream ); static PaError IsStreamStopped( PaStream *s ); static PaError IsStreamActive( PaStream *stream ); static PaTime GetStreamTime( PaStream *stream ); static double GetStreamCpuLoad( PaStream* stream ); static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ); static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ); static signed long GetStreamReadAvailable( PaStream* stream ); static signed long GetStreamWriteAvailable( PaStream* stream ); /* Utility functions */ static unsigned long GetWfexSize(const WAVEFORMATEX* wfex); static PaError BuildFilterList(PaWinWdmHostApiRepresentation* wdmHostApi); static BOOL PinWrite(HANDLE h, DATAPACKET* p); static BOOL PinRead(HANDLE h, DATAPACKET* p); static void DuplicateFirstChannelInt16(void* buffer, int channels, int samples); static void DuplicateFirstChannelInt24(void* buffer, int channels, int samples); static DWORD WINAPI ProcessingThread(LPVOID pParam); /* Function bodies */ static unsigned long GetWfexSize(const WAVEFORMATEX* wfex) { if( wfex->wFormatTag == WAVE_FORMAT_PCM ) { return sizeof( WAVEFORMATEX ); } else { return (sizeof( WAVEFORMATEX ) + wfex->cbSize); } } /* Low level pin/filter access functions */ static PaError WdmSyncIoctl( HANDLE handle, unsigned long ioctlNumber, void* inBuffer, unsigned long inBufferCount, void* outBuffer, unsigned long outBufferCount, unsigned long* bytesReturned) { PaError result = paNoError; OVERLAPPED overlapped; int boolResult; unsigned long dummyBytesReturned; unsigned long error; if( !bytesReturned ) { /* User a dummy as the caller hasn't supplied one */ bytesReturned = &dummyBytesReturned; } FillMemory((void *)&overlapped,sizeof(overlapped),0); overlapped.hEvent = CreateEvent(NULL,FALSE,FALSE,NULL); if( !overlapped.hEvent ) { result = paInsufficientMemory; goto error; } overlapped.hEvent = (HANDLE)((DWORD_PTR)overlapped.hEvent | 0x1); boolResult = DeviceIoControl(handle, ioctlNumber, inBuffer, inBufferCount, outBuffer, outBufferCount, bytesReturned, &overlapped); if( !boolResult ) { error = GetLastError(); if( error == ERROR_IO_PENDING ) { error = WaitForSingleObject(overlapped.hEvent,INFINITE); if( error != WAIT_OBJECT_0 ) { result = paUnanticipatedHostError; goto error; } } else if((( error == ERROR_INSUFFICIENT_BUFFER ) || ( error == ERROR_MORE_DATA )) && ( ioctlNumber == IOCTL_KS_PROPERTY ) && ( outBufferCount == 0 )) { boolResult = TRUE; } else { result = paUnanticipatedHostError; } } if( !boolResult ) *bytesReturned = 0; error: if( overlapped.hEvent ) { CloseHandle( overlapped.hEvent ); } return result; } static PaError WdmGetPropertySimple(HANDLE handle, const GUID* const guidPropertySet, unsigned long property, void* value, unsigned long valueCount, void* instance, unsigned long instanceCount) { PaError result; KSPROPERTY* ksProperty; unsigned long propertyCount; propertyCount = sizeof(KSPROPERTY) + instanceCount; ksProperty = (KSPROPERTY*)PaUtil_AllocateMemory( propertyCount ); if( !ksProperty ) { return paInsufficientMemory; } FillMemory((void*)ksProperty,sizeof(ksProperty),0); ksProperty->Set = *guidPropertySet; ksProperty->Id = property; ksProperty->Flags = KSPROPERTY_TYPE_GET; if( instance ) { memcpy( (void*)(((char*)ksProperty)+sizeof(KSPROPERTY)), instance, instanceCount ); } result = WdmSyncIoctl( handle, IOCTL_KS_PROPERTY, ksProperty, propertyCount, value, valueCount, NULL); PaUtil_FreeMemory( ksProperty ); return result; } static PaError WdmSetPropertySimple( HANDLE handle, const GUID* const guidPropertySet, unsigned long property, void* value, unsigned long valueCount, void* instance, unsigned long instanceCount) { PaError result; KSPROPERTY* ksProperty; unsigned long propertyCount = 0; propertyCount = sizeof(KSPROPERTY) + instanceCount; ksProperty = (KSPROPERTY*)PaUtil_AllocateMemory( propertyCount ); if( !ksProperty ) { return paInsufficientMemory; } ksProperty->Set = *guidPropertySet; ksProperty->Id = property; ksProperty->Flags = KSPROPERTY_TYPE_SET; if( instance ) { memcpy((void*)((char*)ksProperty + sizeof(KSPROPERTY)), instance, instanceCount); } result = WdmSyncIoctl( handle, IOCTL_KS_PROPERTY, ksProperty, propertyCount, value, valueCount, NULL); PaUtil_FreeMemory( ksProperty ); return result; } static PaError WdmGetPinPropertySimple( HANDLE handle, unsigned long pinId, const GUID* const guidPropertySet, unsigned long property, void* value, unsigned long valueCount) { PaError result; KSP_PIN ksPProp; ksPProp.Property.Set = *guidPropertySet; ksPProp.Property.Id = property; ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; ksPProp.PinId = pinId; ksPProp.Reserved = 0; result = WdmSyncIoctl( handle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN), value, valueCount, NULL); return result; } static PaError WdmGetPinPropertyMulti( HANDLE handle, unsigned long pinId, const GUID* const guidPropertySet, unsigned long property, KSMULTIPLE_ITEM** ksMultipleItem) { PaError result; unsigned long multipleItemSize = 0; KSP_PIN ksPProp; ksPProp.Property.Set = *guidPropertySet; ksPProp.Property.Id = property; ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; ksPProp.PinId = pinId; ksPProp.Reserved = 0; result = WdmSyncIoctl( handle, IOCTL_KS_PROPERTY, &ksPProp.Property, sizeof(KSP_PIN), NULL, 0, &multipleItemSize); if( result != paNoError ) { return result; } *ksMultipleItem = (KSMULTIPLE_ITEM*)PaUtil_AllocateMemory( multipleItemSize ); if( !*ksMultipleItem ) { return paInsufficientMemory; } result = WdmSyncIoctl( handle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN), (void*)*ksMultipleItem, multipleItemSize, NULL); if( result != paNoError ) { PaUtil_FreeMemory( ksMultipleItem ); } return result; } /* Create a new pin object belonging to a filter The pin object holds all the configuration information about the pin before it is opened, and then the handle of the pin after is opened */ static PaWinWdmPin* PinNew(PaWinWdmFilter* parentFilter, unsigned long pinId, PaError* error) { PaWinWdmPin* pin; PaError result; unsigned long i; KSMULTIPLE_ITEM* item = NULL; KSIDENTIFIER* identifier; KSDATARANGE* dataRange; PA_LOGE_; PA_DEBUG(("Creating pin %d:\n",pinId)); /* Allocate the new PIN object */ pin = (PaWinWdmPin*)PaUtil_AllocateMemory( sizeof(PaWinWdmPin) ); if( !pin ) { result = paInsufficientMemory; goto error; } /* Zero the pin object */ /* memset( (void*)pin, 0, sizeof(PaWinWdmPin) ); */ pin->parentFilter = parentFilter; pin->pinId = pinId; /* Allocate a connect structure */ pin->pinConnectSize = sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT_WAVEFORMATEX); pin->pinConnect = (KSPIN_CONNECT*)PaUtil_AllocateMemory( pin->pinConnectSize ); if( !pin->pinConnect ) { result = paInsufficientMemory; goto error; } /* Configure the connect structure with default values */ pin->pinConnect->Interface.Set = KSINTERFACESETID_Standard; pin->pinConnect->Interface.Id = KSINTERFACE_STANDARD_STREAMING; pin->pinConnect->Interface.Flags = 0; pin->pinConnect->Medium.Set = KSMEDIUMSETID_Standard; pin->pinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE; pin->pinConnect->Medium.Flags = 0; pin->pinConnect->PinId = pinId; pin->pinConnect->PinToHandle = NULL; pin->pinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL; pin->pinConnect->Priority.PrioritySubClass = 1; pin->ksDataFormatWfx = (KSDATAFORMAT_WAVEFORMATEX*)(pin->pinConnect + 1); pin->ksDataFormatWfx->DataFormat.FormatSize = sizeof(KSDATAFORMAT_WAVEFORMATEX); pin->ksDataFormatWfx->DataFormat.Flags = 0; pin->ksDataFormatWfx->DataFormat.Reserved = 0; pin->ksDataFormatWfx->DataFormat.MajorFormat = KSDATAFORMAT_TYPE_AUDIO; pin->ksDataFormatWfx->DataFormat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; pin->ksDataFormatWfx->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX; pin->frameSize = 0; /* Unknown until we instantiate pin */ /* Get the COMMUNICATION property */ result = WdmGetPinPropertySimple( parentFilter->handle, pinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_COMMUNICATION, &pin->communication, sizeof(KSPIN_COMMUNICATION)); if( result != paNoError ) goto error; if( /*(pin->communication != KSPIN_COMMUNICATION_SOURCE) &&*/ (pin->communication != KSPIN_COMMUNICATION_SINK) && (pin->communication != KSPIN_COMMUNICATION_BOTH) ) { PA_DEBUG(("Not source/sink\n")); result = paInvalidDevice; goto error; } /* Get dataflow information */ result = WdmGetPinPropertySimple( parentFilter->handle, pinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_DATAFLOW, &pin->dataFlow, sizeof(KSPIN_DATAFLOW)); if( result != paNoError ) goto error; /* Get the INTERFACE property list */ result = WdmGetPinPropertyMulti( parentFilter->handle, pinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_INTERFACES, &item); if( result != paNoError ) goto error; identifier = (KSIDENTIFIER*)(item+1); /* Check that at least one interface is STANDARD_STREAMING */ result = paUnanticipatedHostError; for( i = 0; i < item->Count; i++ ) { if( !memcmp( (void*)&identifier[i].Set, (void*)&KSINTERFACESETID_Standard, sizeof( GUID ) ) && ( identifier[i].Id == KSINTERFACE_STANDARD_STREAMING ) ) { result = paNoError; break; } } if( result != paNoError ) { PA_DEBUG(("No standard streaming\n")); goto error; } /* Don't need interfaces any more */ PaUtil_FreeMemory( item ); item = NULL; /* Get the MEDIUM properties list */ result = WdmGetPinPropertyMulti( parentFilter->handle, pinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_MEDIUMS, &item); if( result != paNoError ) goto error; identifier = (KSIDENTIFIER*)(item+1); /* Not actually necessary... */ /* Check that at least one medium is STANDARD_DEVIO */ result = paUnanticipatedHostError; for( i = 0; i < item->Count; i++ ) { if( !memcmp( (void*)&identifier[i].Set, (void*)&KSMEDIUMSETID_Standard, sizeof( GUID ) ) && ( identifier[i].Id == KSMEDIUM_STANDARD_DEVIO ) ) { result = paNoError; break; } } if( result != paNoError ) { PA_DEBUG(("No standard devio\n")); goto error; } /* Don't need mediums any more */ PaUtil_FreeMemory( item ); item = NULL; /* Get DATARANGES */ result = WdmGetPinPropertyMulti( parentFilter->handle, pinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_DATARANGES, &pin->dataRangesItem); if( result != paNoError ) goto error; pin->dataRanges = (KSDATARANGE*)(pin->dataRangesItem +1); /* Check that at least one datarange supports audio */ result = paUnanticipatedHostError; dataRange = pin->dataRanges; pin->maxChannels = 0; pin->bestSampleRate = 0; pin->formats = 0; for( i = 0; i dataRangesItem->Count; i++) { PA_DEBUG(("DR major format %x\n",*(unsigned long*)(&(dataRange->MajorFormat)))); /* Check that subformat is WAVEFORMATEX, PCM or WILDCARD */ if( IS_VALID_WAVEFORMATEX_GUID(&dataRange->SubFormat) || !memcmp((void*)&dataRange->SubFormat, (void*)&KSDATAFORMAT_SUBTYPE_PCM, sizeof ( GUID ) ) || ( !memcmp((void*)&dataRange->SubFormat, (void*)&KSDATAFORMAT_SUBTYPE_WILDCARD, sizeof ( GUID ) ) && ( !memcmp((void*)&dataRange->MajorFormat, (void*)&KSDATAFORMAT_TYPE_AUDIO, sizeof ( GUID ) ) ) ) ) { result = paNoError; /* Record the maximum possible channels with this pin */ PA_DEBUG(("MaxChannel: %d\n",pin->maxChannels)); if( (int)((KSDATARANGE_AUDIO*)dataRange)->MaximumChannels > pin->maxChannels ) { pin->maxChannels = ((KSDATARANGE_AUDIO*)dataRange)->MaximumChannels; /*PA_DEBUG(("MaxChannel: %d\n",pin->maxChannels));*/ } /* Record the formats (bit depths) that are supported */ if( ((KSDATARANGE_AUDIO*)dataRange)->MinimumBitsPerSample <= 16 ) { pin->formats |= paInt16; PA_DEBUG(("Format 16 bit supported\n")); } if( ((KSDATARANGE_AUDIO*)dataRange)->MaximumBitsPerSample >= 24 ) { pin->formats |= paInt24; PA_DEBUG(("Format 24 bit supported\n")); } if( ( pin->bestSampleRate != 48000) && (((KSDATARANGE_AUDIO*)dataRange)->MaximumSampleFrequency >= 48000) && (((KSDATARANGE_AUDIO*)dataRange)->MinimumSampleFrequency <= 48000) ) { pin->bestSampleRate = 48000; PA_DEBUG(("48kHz supported\n")); } else if(( pin->bestSampleRate != 48000) && ( pin->bestSampleRate != 44100 ) && (((KSDATARANGE_AUDIO*)dataRange)->MaximumSampleFrequency >= 44100) && (((KSDATARANGE_AUDIO*)dataRange)->MinimumSampleFrequency <= 44100) ) { pin->bestSampleRate = 44100; PA_DEBUG(("44.1kHz supported\n")); } else { pin->bestSampleRate = ((KSDATARANGE_AUDIO*)dataRange)->MaximumSampleFrequency; } } dataRange = (KSDATARANGE*)( ((char*)dataRange) + dataRange->FormatSize); } if( result != paNoError ) goto error; /* Get instance information */ result = WdmGetPinPropertySimple( parentFilter->handle, pinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_CINSTANCES, &pin->instances, sizeof(KSPIN_CINSTANCES)); if( result != paNoError ) goto error; /* Success */ *error = paNoError; PA_DEBUG(("Pin created successfully\n")); PA_LOGL_; return pin; error: /* Error cleanup */ PaUtil_FreeMemory( item ); if( pin ) { PaUtil_FreeMemory( pin->pinConnect ); PaUtil_FreeMemory( pin->dataRangesItem ); PaUtil_FreeMemory( pin ); } *error = result; PA_LOGL_; return NULL; } /* Safely free all resources associated with the pin */ static void PinFree(PaWinWdmPin* pin) { PA_LOGE_; if( pin ) { PinClose(pin); if( pin->pinConnect ) { PaUtil_FreeMemory( pin->pinConnect ); } if( pin->dataRangesItem ) { PaUtil_FreeMemory( pin->dataRangesItem ); } PaUtil_FreeMemory( pin ); } PA_LOGL_; } /* If the pin handle is open, close it */ static void PinClose(PaWinWdmPin* pin) { PA_LOGE_; if( pin == NULL ) { PA_DEBUG(("Closing NULL pin!")); PA_LOGL_; return; } if( pin->handle != NULL ) { PinSetState( pin, KSSTATE_PAUSE ); PinSetState( pin, KSSTATE_STOP ); CloseHandle( pin->handle ); pin->handle = NULL; FilterRelease(pin->parentFilter); } PA_LOGL_; } /* Set the state of this (instantiated) pin */ static PaError PinSetState(PaWinWdmPin* pin, KSSTATE state) { PaError result; PA_LOGE_; if( pin == NULL ) return paInternalError; if( pin->handle == NULL ) return paInternalError; result = WdmSetPropertySimple( pin->handle, &KSPROPSETID_Connection, KSPROPERTY_CONNECTION_STATE, &state, sizeof(state), NULL, 0); PA_LOGL_; return result; } static PaError PinInstantiate(PaWinWdmPin* pin) { PaError result; unsigned long createResult; KSALLOCATOR_FRAMING ksaf; KSALLOCATOR_FRAMING_EX ksafex; PA_LOGE_; if( pin == NULL ) return paInternalError; if(!pin->pinConnect) return paInternalError; FilterUse(pin->parentFilter); createResult = FunctionKsCreatePin( pin->parentFilter->handle, pin->pinConnect, GENERIC_WRITE | GENERIC_READ, &pin->handle ); PA_DEBUG(("Pin create result = %x\n",createResult)); if( createResult != ERROR_SUCCESS ) { FilterRelease(pin->parentFilter); pin->handle = NULL; return paInvalidDevice; } result = WdmGetPropertySimple( pin->handle, &KSPROPSETID_Connection, KSPROPERTY_CONNECTION_ALLOCATORFRAMING, &ksaf, sizeof(ksaf), NULL, 0); if( result != paNoError ) { result = WdmGetPropertySimple( pin->handle, &KSPROPSETID_Connection, KSPROPERTY_CONNECTION_ALLOCATORFRAMING_EX, &ksafex, sizeof(ksafex), NULL, 0); if( result == paNoError ) { pin->frameSize = ksafex.FramingItem[0].FramingRange.Range.MinFrameSize; } } else { pin->frameSize = ksaf.FrameSize; } PA_LOGL_; return paNoError; } /* NOT USED static PaError PinGetState(PaWinWdmPin* pin, KSSTATE* state) { PaError result; if( state == NULL ) return paInternalError; if( pin == NULL ) return paInternalError; if( pin->handle == NULL ) return paInternalError; result = WdmGetPropertySimple( pin->handle, KSPROPSETID_Connection, KSPROPERTY_CONNECTION_STATE, state, sizeof(KSSTATE), NULL, 0); return result; } */ static PaError PinSetFormat(PaWinWdmPin* pin, const WAVEFORMATEX* format) { unsigned long size; void* newConnect; PA_LOGE_; if( pin == NULL ) return paInternalError; if( format == NULL ) return paInternalError; size = GetWfexSize(format) + sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT_WAVEFORMATEX) - sizeof(WAVEFORMATEX); if( pin->pinConnectSize != size ) { newConnect = PaUtil_AllocateMemory( size ); if( newConnect == NULL ) return paInsufficientMemory; memcpy( newConnect, (void*)pin->pinConnect, min(pin->pinConnectSize,size) ); PaUtil_FreeMemory( pin->pinConnect ); pin->pinConnect = (KSPIN_CONNECT*)newConnect; pin->pinConnectSize = size; pin->ksDataFormatWfx = (KSDATAFORMAT_WAVEFORMATEX*)((KSPIN_CONNECT*)newConnect + 1); pin->ksDataFormatWfx->DataFormat.FormatSize = size - sizeof(KSPIN_CONNECT); } memcpy( (void*)&(pin->ksDataFormatWfx->WaveFormatEx), format, GetWfexSize(format) ); pin->ksDataFormatWfx->DataFormat.SampleSize = (unsigned short)(format->nChannels * (format->wBitsPerSample / 8)); PA_LOGL_; return paNoError; } static PaError PinIsFormatSupported(PaWinWdmPin* pin, const WAVEFORMATEX* format) { KSDATARANGE_AUDIO* dataRange; unsigned long count; GUID guid = DYNAMIC_GUID( DEFINE_WAVEFORMATEX_GUID(format->wFormatTag) ); PaError result = paInvalidDevice; PA_LOGE_; if( format->wFormatTag == WAVE_FORMAT_EXTENSIBLE ) { guid = ((WAVEFORMATEXTENSIBLE*)format)->SubFormat; } dataRange = (KSDATARANGE_AUDIO*)pin->dataRanges; for(count = 0; countdataRangesItem->Count; count++) { if(( !memcmp(&(dataRange->DataRange.MajorFormat),&KSDATAFORMAT_TYPE_AUDIO,sizeof(GUID)) ) || ( !memcmp(&(dataRange->DataRange.MajorFormat),&KSDATAFORMAT_TYPE_WILDCARD,sizeof(GUID)) )) { /* This is an audio or wildcard datarange... */ if(( !memcmp(&(dataRange->DataRange.SubFormat),&KSDATAFORMAT_SUBTYPE_WILDCARD,sizeof(GUID)) ) || ( !memcmp(&(dataRange->DataRange.SubFormat),&guid,sizeof(GUID)) )) { if(( !memcmp(&(dataRange->DataRange.Specifier),&KSDATAFORMAT_SPECIFIER_WILDCARD,sizeof(GUID)) ) || ( !memcmp(&(dataRange->DataRange.Specifier),&KSDATAFORMAT_SPECIFIER_WAVEFORMATEX,sizeof(GUID) ))) { PA_DEBUG(("Pin:%x, DataRange:%d\n",(void*)pin,count)); PA_DEBUG(("\tFormatSize:%d, SampleSize:%d\n",dataRange->DataRange.FormatSize,dataRange->DataRange.SampleSize)); PA_DEBUG(("\tMaxChannels:%d\n",dataRange->MaximumChannels)); PA_DEBUG(("\tBits:%d-%d\n",dataRange->MinimumBitsPerSample,dataRange->MaximumBitsPerSample)); PA_DEBUG(("\tSampleRate:%d-%d\n",dataRange->MinimumSampleFrequency,dataRange->MaximumSampleFrequency)); if( dataRange->MaximumChannels < format->nChannels ) { result = paInvalidChannelCount; continue; } if( dataRange->MinimumBitsPerSample > format->wBitsPerSample ) { result = paSampleFormatNotSupported; continue; } if( dataRange->MaximumBitsPerSample < format->wBitsPerSample ) { result = paSampleFormatNotSupported; continue; } if( dataRange->MinimumSampleFrequency > format->nSamplesPerSec ) { result = paInvalidSampleRate; continue; } if( dataRange->MaximumSampleFrequency < format->nSamplesPerSec ) { result = paInvalidSampleRate; continue; } /* Success! */ PA_LOGL_; return paNoError; } } } dataRange = (KSDATARANGE_AUDIO*)( ((char*)dataRange) + dataRange->DataRange.FormatSize); } PA_LOGL_; return result; } /** * Create a new filter object */ static PaWinWdmFilter* FilterNew(TCHAR* filterName, TCHAR* friendlyName, PaError* error) { PaWinWdmFilter* filter; PaError result; int pinId; int valid; /* Allocate the new filter object */ filter = (PaWinWdmFilter*)PaUtil_AllocateMemory( sizeof(PaWinWdmFilter) ); if( !filter ) { result = paInsufficientMemory; goto error; } /* Zero the filter object - done by AllocateMemory */ /* memset( (void*)filter, 0, sizeof(PaWinWdmFilter) ); */ /* Copy the filter name */ _tcsncpy(filter->filterName, filterName, MAX_PATH); /* Copy the friendly name */ _tcsncpy(filter->friendlyName, friendlyName, MAX_PATH); /* Open the filter handle */ result = FilterUse(filter); if( result != paNoError ) { goto error; } /* Get pin count */ result = WdmGetPinPropertySimple ( filter->handle, 0, &KSPROPSETID_Pin, KSPROPERTY_PIN_CTYPES, &filter->pinCount, sizeof(filter->pinCount) ); if( result != paNoError) { goto error; } /* Allocate pointer array to hold the pins */ filter->pins = (PaWinWdmPin**)PaUtil_AllocateMemory( sizeof(PaWinWdmPin*) * filter->pinCount ); if( !filter->pins ) { result = paInsufficientMemory; goto error; } /* Create all the pins we can */ filter->maxInputChannels = 0; filter->maxOutputChannels = 0; filter->bestSampleRate = 0; valid = 0; for(pinId = 0; pinId < filter->pinCount; pinId++) { /* Create the pin with this Id */ PaWinWdmPin* newPin; newPin = PinNew(filter, pinId, &result); if( result == paInsufficientMemory ) goto error; if( newPin != NULL ) { filter->pins[pinId] = newPin; valid = 1; /* Get the max output channel count */ if(( newPin->dataFlow == KSPIN_DATAFLOW_IN ) && (( newPin->communication == KSPIN_COMMUNICATION_SINK) || ( newPin->communication == KSPIN_COMMUNICATION_BOTH))) { if(newPin->maxChannels > filter->maxOutputChannels) filter->maxOutputChannels = newPin->maxChannels; filter->formats |= newPin->formats; } /* Get the max input channel count */ if(( newPin->dataFlow == KSPIN_DATAFLOW_OUT ) && (( newPin->communication == KSPIN_COMMUNICATION_SINK) || ( newPin->communication == KSPIN_COMMUNICATION_BOTH))) { if(newPin->maxChannels > filter->maxInputChannels) filter->maxInputChannels = newPin->maxChannels; filter->formats |= newPin->formats; } if(newPin->bestSampleRate > filter->bestSampleRate) { filter->bestSampleRate = newPin->bestSampleRate; } } } if(( filter->maxInputChannels == 0) && ( filter->maxOutputChannels == 0)) { /* No input or output... not valid */ valid = 0; } if( !valid ) { /* No valid pin was found on this filter so we destroy it */ result = paDeviceUnavailable; goto error; } /* Close the filter handle for now * It will be opened later when needed */ FilterRelease(filter); *error = paNoError; return filter; error: /* Error cleanup */ if( filter ) { for( pinId = 0; pinId < filter->pinCount; pinId++ ) PinFree(filter->pins[pinId]); PaUtil_FreeMemory( filter->pins ); if( filter->handle ) CloseHandle( filter->handle ); PaUtil_FreeMemory( filter ); } *error = result; return NULL; } /** * Free a previously created filter */ static void FilterFree(PaWinWdmFilter* filter) { int pinId; PA_LOGL_; if( filter ) { for( pinId = 0; pinId < filter->pinCount; pinId++ ) PinFree(filter->pins[pinId]); PaUtil_FreeMemory( filter->pins ); if( filter->handle ) CloseHandle( filter->handle ); PaUtil_FreeMemory( filter ); } PA_LOGE_; } /** * Reopen the filter handle if necessary so it can be used **/ static PaError FilterUse(PaWinWdmFilter* filter) { assert( filter ); PA_LOGE_; if( filter->handle == NULL ) { /* Open the filter */ filter->handle = CreateFile( filter->filterName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); if( filter->handle == NULL ) { return paDeviceUnavailable; } } filter->usageCount++; PA_LOGL_; return paNoError; } /** * Release the filter handle if nobody is using it **/ static void FilterRelease(PaWinWdmFilter* filter) { assert( filter ); assert( filter->usageCount > 0 ); PA_LOGE_; filter->usageCount--; if( filter->usageCount == 0 ) { if( filter->handle != NULL ) { CloseHandle( filter->handle ); filter->handle = NULL; } } PA_LOGL_; } /** * Create a render (playback) Pin using the supplied format **/ static PaWinWdmPin* FilterCreateRenderPin(PaWinWdmFilter* filter, const WAVEFORMATEX* wfex, PaError* error) { PaError result; PaWinWdmPin* pin; assert( filter ); pin = FilterFindViableRenderPin(filter,wfex,&result); if(!pin) { goto error; } result = PinSetFormat(pin,wfex); if( result != paNoError ) { goto error; } result = PinInstantiate(pin); if( result != paNoError ) { goto error; } *error = paNoError; return pin; error: *error = result; return NULL; } /** * Find a pin that supports the given format **/ static PaWinWdmPin* FilterFindViableRenderPin(PaWinWdmFilter* filter, const WAVEFORMATEX* wfex, PaError* error) { int pinId; PaWinWdmPin* pin; PaError result = paDeviceUnavailable; *error = paNoError; assert( filter ); for( pinId = 0; pinIdpinCount; pinId++ ) { pin = filter->pins[pinId]; if( pin != NULL ) { if(( pin->dataFlow == KSPIN_DATAFLOW_IN ) && (( pin->communication == KSPIN_COMMUNICATION_SINK) || ( pin->communication == KSPIN_COMMUNICATION_BOTH))) { result = PinIsFormatSupported( pin, wfex ); if( result == paNoError ) { return pin; } } } } *error = result; return NULL; } /** * Check if there is a pin that should playback * with the supplied format **/ static PaError FilterCanCreateRenderPin(PaWinWdmFilter* filter, const WAVEFORMATEX* wfex) { PaWinWdmPin* pin; PaError result; assert ( filter ); pin = FilterFindViableRenderPin(filter,wfex,&result); /* result will be paNoError if pin found * or else an error code indicating what is wrong with the format **/ return result; } /** * Create a capture (record) Pin using the supplied format **/ static PaWinWdmPin* FilterCreateCapturePin(PaWinWdmFilter* filter, const WAVEFORMATEX* wfex, PaError* error) { PaError result; PaWinWdmPin* pin; assert( filter ); pin = FilterFindViableCapturePin(filter,wfex,&result); if(!pin) { goto error; } result = PinSetFormat(pin,wfex); if( result != paNoError ) { goto error; } result = PinInstantiate(pin); if( result != paNoError ) { goto error; } *error = paNoError; return pin; error: *error = result; return NULL; } /** * Find a capture pin that supports the given format **/ static PaWinWdmPin* FilterFindViableCapturePin(PaWinWdmFilter* filter, const WAVEFORMATEX* wfex, PaError* error) { int pinId; PaWinWdmPin* pin; PaError result = paDeviceUnavailable; *error = paNoError; assert( filter ); for( pinId = 0; pinIdpinCount; pinId++ ) { pin = filter->pins[pinId]; if( pin != NULL ) { if(( pin->dataFlow == KSPIN_DATAFLOW_OUT ) && (( pin->communication == KSPIN_COMMUNICATION_SINK) || ( pin->communication == KSPIN_COMMUNICATION_BOTH))) { result = PinIsFormatSupported( pin, wfex ); if( result == paNoError ) { return pin; } } } } *error = result; return NULL; } /** * Check if there is a pin that should playback * with the supplied format **/ static PaError FilterCanCreateCapturePin(PaWinWdmFilter* filter, const WAVEFORMATEX* wfex) { PaWinWdmPin* pin; PaError result; assert ( filter ); pin = FilterFindViableCapturePin(filter,wfex,&result); /* result will be paNoError if pin found * or else an error code indicating what is wrong with the format **/ return result; } /** * Build the list of available filters * Use the SetupDi API to enumerate all devices in the KSCATEGORY_AUDIO which * have a KSCATEGORY_RENDER or KSCATEGORY_CAPTURE alias. For each of these * devices initialise a PaWinWdmFilter structure by calling our NewFilter() * function. We enumerate devices twice, once to count how many there are, * and once to initialize the PaWinWdmFilter structures. */ static PaError BuildFilterList(PaWinWdmHostApiRepresentation* wdmHostApi) { PaError result = paNoError; HDEVINFO handle = NULL; int device; int invalidDevices; int slot; SP_DEVICE_INTERFACE_DATA interfaceData; SP_DEVICE_INTERFACE_DATA aliasData; SP_DEVINFO_DATA devInfoData; int noError; const int sizeInterface = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + (MAX_PATH * sizeof(WCHAR)); unsigned char interfaceDetailsArray[sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + (MAX_PATH * sizeof(WCHAR))]; SP_DEVICE_INTERFACE_DETAIL_DATA* devInterfaceDetails = (SP_DEVICE_INTERFACE_DETAIL_DATA*)interfaceDetailsArray; TCHAR friendlyName[MAX_PATH]; HKEY hkey; DWORD sizeFriendlyName; DWORD type; PaWinWdmFilter* newFilter; GUID* category = (GUID*)&KSCATEGORY_AUDIO; GUID* alias_render = (GUID*)&KSCATEGORY_RENDER; GUID* alias_capture = (GUID*)&KSCATEGORY_CAPTURE; DWORD hasAlias; PA_LOGE_; devInterfaceDetails->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); /* Open a handle to search for devices (filters) */ handle = SetupDiGetClassDevs(category,NULL,NULL,DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if( handle == NULL ) { return paUnanticipatedHostError; } PA_DEBUG(("Setup called\n")); /* First let's count the number of devices so we can allocate a list */ invalidDevices = 0; for( device = 0;;device++ ) { interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); interfaceData.Reserved = 0; aliasData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); aliasData.Reserved = 0; noError = SetupDiEnumDeviceInterfaces(handle,NULL,category,device,&interfaceData); PA_DEBUG(("Enum called\n")); if( !noError ) break; /* No more devices */ /* Check this one has the render or capture alias */ hasAlias = 0; noError = SetupDiGetDeviceInterfaceAlias(handle,&interfaceData,alias_render,&aliasData); PA_DEBUG(("noError = %d\n",noError)); if(noError) { if(aliasData.Flags && (!(aliasData.Flags & SPINT_REMOVED))) { PA_DEBUG(("Device %d has render alias\n",device)); hasAlias |= 1; /* Has render alias */ } else { PA_DEBUG(("Device %d has no render alias\n",device)); } } noError = SetupDiGetDeviceInterfaceAlias(handle,&interfaceData,alias_capture,&aliasData); if(noError) { if(aliasData.Flags && (!(aliasData.Flags & SPINT_REMOVED))) { PA_DEBUG(("Device %d has capture alias\n",device)); hasAlias |= 2; /* Has capture alias */ } else { PA_DEBUG(("Device %d has no capture alias\n",device)); } } if(!hasAlias) invalidDevices++; /* This was not a valid capture or render audio device */ } /* Remember how many there are */ wdmHostApi->filterCount = device-invalidDevices; PA_DEBUG(("Interfaces found: %d\n",device-invalidDevices)); /* Now allocate the list of pointers to devices */ wdmHostApi->filters = (PaWinWdmFilter**)PaUtil_AllocateMemory( sizeof(PaWinWdmFilter*) * device ); if( !wdmHostApi->filters ) { if(handle != NULL) SetupDiDestroyDeviceInfoList(handle); return paInsufficientMemory; } /* Now create filter objects for each interface found */ slot = 0; for( device = 0;;device++ ) { interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); interfaceData.Reserved = 0; aliasData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); aliasData.Reserved = 0; devInfoData.cbSize = sizeof(SP_DEVINFO_DATA); devInfoData.Reserved = 0; noError = SetupDiEnumDeviceInterfaces(handle,NULL,category,device,&interfaceData); if( !noError ) break; /* No more devices */ /* Check this one has the render or capture alias */ hasAlias = 0; noError = SetupDiGetDeviceInterfaceAlias(handle,&interfaceData,alias_render,&aliasData); if(noError) { if(aliasData.Flags && (!(aliasData.Flags & SPINT_REMOVED))) { PA_DEBUG(("Device %d has render alias\n",device)); hasAlias |= 1; /* Has render alias */ } } noError = SetupDiGetDeviceInterfaceAlias(handle,&interfaceData,alias_capture,&aliasData); if(noError) { if(aliasData.Flags && (!(aliasData.Flags & SPINT_REMOVED))) { PA_DEBUG(("Device %d has capture alias\n",device)); hasAlias |= 2; /* Has capture alias */ } } if(!hasAlias) continue; /* This was not a valid capture or render audio device */ noError = SetupDiGetDeviceInterfaceDetail(handle,&interfaceData,devInterfaceDetails,sizeInterface,NULL,&devInfoData); if( noError ) { /* Try to get the "friendly name" for this interface */ sizeFriendlyName = sizeof(friendlyName); /* Fix contributed by Ben Allison * Removed KEY_SET_VALUE from flags on following call * as its causes failure when running without admin rights * and it was not required */ hkey=SetupDiOpenDeviceInterfaceRegKey(handle,&interfaceData,0,KEY_QUERY_VALUE); if(hkey!=INVALID_HANDLE_VALUE) { noError = RegQueryValueEx(hkey,TEXT("FriendlyName"),0,&type,(BYTE*)friendlyName,&sizeFriendlyName); if( noError == ERROR_SUCCESS ) { PA_DEBUG(("Interface %d, Name: %s\n",device,friendlyName)); RegCloseKey(hkey); } else { friendlyName[0] = 0; } } newFilter = FilterNew(devInterfaceDetails->DevicePath,friendlyName,&result); if( result == paNoError ) { PA_DEBUG(("Filter created\n")); wdmHostApi->filters[slot] = newFilter; slot++; } else { PA_DEBUG(("Filter NOT created\n")); /* As there are now less filters than we initially thought * we must reduce the count by one */ wdmHostApi->filterCount--; } } } /* Clean up */ if(handle != NULL) SetupDiDestroyDeviceInfoList(handle); return paNoError; } PaError PaWinWdm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) { PaError result = paNoError; int i, deviceCount; PaWinWdmHostApiRepresentation *wdmHostApi; PaWinWdmDeviceInfo *deviceInfoArray; PaWinWdmFilter* pFilter; PaWinWdmDeviceInfo *wdmDeviceInfo; PaDeviceInfo *deviceInfo; PA_LOGE_; /* Attempt to load the KSUSER.DLL without which we cannot create pins We will unload this on termination */ if(DllKsUser == NULL) { DllKsUser = LoadLibrary(TEXT("ksuser.dll")); if(DllKsUser == NULL) goto error; } FunctionKsCreatePin = (KSCREATEPIN*)GetProcAddress(DllKsUser, "KsCreatePin"); if(FunctionKsCreatePin == NULL) goto error; wdmHostApi = (PaWinWdmHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaWinWdmHostApiRepresentation) ); if( !wdmHostApi ) { result = paInsufficientMemory; goto error; } wdmHostApi->allocations = PaUtil_CreateAllocationGroup(); if( !wdmHostApi->allocations ) { result = paInsufficientMemory; goto error; } result = BuildFilterList( wdmHostApi ); if( result != paNoError ) { goto error; } deviceCount = wdmHostApi->filterCount; *hostApi = &wdmHostApi->inheritedHostApiRep; (*hostApi)->info.structVersion = 1; (*hostApi)->info.type = paWDMKS; (*hostApi)->info.name = "Windows WDM-KS"; (*hostApi)->info.defaultInputDevice = paNoDevice; (*hostApi)->info.defaultOutputDevice = paNoDevice; if( deviceCount > 0 ) { (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( wdmHostApi->allocations, sizeof(PaWinWdmDeviceInfo*) * deviceCount ); if( !(*hostApi)->deviceInfos ) { result = paInsufficientMemory; goto error; } /* allocate all device info structs in a contiguous block */ deviceInfoArray = (PaWinWdmDeviceInfo*)PaUtil_GroupAllocateMemory( wdmHostApi->allocations, sizeof(PaWinWdmDeviceInfo) * deviceCount ); if( !deviceInfoArray ) { result = paInsufficientMemory; goto error; } for( i=0; i < deviceCount; ++i ) { wdmDeviceInfo = &deviceInfoArray[i]; deviceInfo = &wdmDeviceInfo->inheritedDeviceInfo; pFilter = wdmHostApi->filters[i]; if( pFilter == NULL ) continue; wdmDeviceInfo->filter = pFilter; deviceInfo->structVersion = 2; deviceInfo->hostApi = hostApiIndex; deviceInfo->name = (char*)pFilter->friendlyName; PA_DEBUG(("Device found name: %s\n",(char*)pFilter->friendlyName)); deviceInfo->maxInputChannels = pFilter->maxInputChannels; if(deviceInfo->maxInputChannels > 0) { /* Set the default input device to the first device we find with * more than zero input channels **/ if((*hostApi)->info.defaultInputDevice == paNoDevice) { (*hostApi)->info.defaultInputDevice = i; } } deviceInfo->maxOutputChannels = pFilter->maxOutputChannels; if(deviceInfo->maxOutputChannels > 0) { /* Set the default output device to the first device we find with * more than zero output channels **/ if((*hostApi)->info.defaultOutputDevice == paNoDevice) { (*hostApi)->info.defaultOutputDevice = i; } } /* These low values are not very useful because * a) The lowest latency we end up with can depend on many factors such * as the device buffer sizes/granularities, sample rate, channels and format * b) We cannot know the device buffer sizes until we try to open/use it at * a particular setting * So: we give 512x48000Hz frames as the default low input latency **/ deviceInfo->defaultLowInputLatency = (512.0/48000.0); deviceInfo->defaultLowOutputLatency = (512.0/48000.0); deviceInfo->defaultHighInputLatency = (4096.0/48000.0); deviceInfo->defaultHighOutputLatency = (4096.0/48000.0); deviceInfo->defaultSampleRate = (double)(pFilter->bestSampleRate); (*hostApi)->deviceInfos[i] = deviceInfo; } } (*hostApi)->info.deviceCount = deviceCount; (*hostApi)->Terminate = Terminate; (*hostApi)->OpenStream = OpenStream; (*hostApi)->IsFormatSupported = IsFormatSupported; PaUtil_InitializeStreamInterface( &wdmHostApi->callbackStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, GetStreamCpuLoad, PaUtil_DummyRead, PaUtil_DummyWrite, PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); PaUtil_InitializeStreamInterface( &wdmHostApi->blockingStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, PaUtil_DummyGetCpuLoad, ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable ); PA_LOGL_; return result; error: if( DllKsUser != NULL ) { FreeLibrary( DllKsUser ); DllKsUser = NULL; } if( wdmHostApi ) { PaUtil_FreeMemory( wdmHostApi->filters ); if( wdmHostApi->allocations ) { PaUtil_FreeAllAllocations( wdmHostApi->allocations ); PaUtil_DestroyAllocationGroup( wdmHostApi->allocations ); } PaUtil_FreeMemory( wdmHostApi ); } PA_LOGL_; return result; } static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) { PaWinWdmHostApiRepresentation *wdmHostApi = (PaWinWdmHostApiRepresentation*)hostApi; int i; PA_LOGE_; if( wdmHostApi->filters ) { for( i=0; ifilterCount; i++) { if( wdmHostApi->filters[i] != NULL ) { FilterFree( wdmHostApi->filters[i] ); wdmHostApi->filters[i] = NULL; } } } PaUtil_FreeMemory( wdmHostApi->filters ); if( wdmHostApi->allocations ) { PaUtil_FreeAllAllocations( wdmHostApi->allocations ); PaUtil_DestroyAllocationGroup( wdmHostApi->allocations ); } PaUtil_FreeMemory( wdmHostApi ); PA_LOGL_; } static void FillWFEXT( WAVEFORMATEXTENSIBLE* pwfext, PaSampleFormat sampleFormat, double sampleRate, int channelCount) { PA_LOGE_; PA_DEBUG(( "sampleFormat = %lx\n" , sampleFormat )); PA_DEBUG(( "sampleRate = %f\n" , sampleRate )); PA_DEBUG(( "chanelCount = %d\n", channelCount )); pwfext->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; pwfext->Format.nChannels = channelCount; pwfext->Format.nSamplesPerSec = (int)sampleRate; if(channelCount == 1) pwfext->dwChannelMask = KSAUDIO_SPEAKER_DIRECTOUT; else pwfext->dwChannelMask = KSAUDIO_SPEAKER_STEREO; if(sampleFormat == paFloat32) { pwfext->Format.nBlockAlign = channelCount * 4; pwfext->Format.wBitsPerSample = 32; pwfext->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX); pwfext->Samples.wValidBitsPerSample = 32; pwfext->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; } else if(sampleFormat == paInt32) { pwfext->Format.nBlockAlign = channelCount * 4; pwfext->Format.wBitsPerSample = 32; pwfext->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX); pwfext->Samples.wValidBitsPerSample = 32; pwfext->SubFormat = KSDATAFORMAT_SUBTYPE_PCM; } else if(sampleFormat == paInt24) { pwfext->Format.nBlockAlign = channelCount * 3; pwfext->Format.wBitsPerSample = 24; pwfext->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX); pwfext->Samples.wValidBitsPerSample = 24; pwfext->SubFormat = KSDATAFORMAT_SUBTYPE_PCM; } else if(sampleFormat == paInt16) { pwfext->Format.nBlockAlign = channelCount * 2; pwfext->Format.wBitsPerSample = 16; pwfext->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX); pwfext->Samples.wValidBitsPerSample = 16; pwfext->SubFormat = KSDATAFORMAT_SUBTYPE_PCM; } pwfext->Format.nAvgBytesPerSec = pwfext->Format.nSamplesPerSec * pwfext->Format.nBlockAlign; PA_LOGL_; } static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { int inputChannelCount, outputChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; PaWinWdmHostApiRepresentation *wdmHostApi = (PaWinWdmHostApiRepresentation*)hostApi; PaWinWdmFilter* pFilter; int result = paFormatIsSupported; WAVEFORMATEXTENSIBLE wfx; PA_LOGE_; if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( inputSampleFormat & paCustomFormat ) return paSampleFormatNotSupported; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that input device can support inputChannelCount */ if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) return paInvalidChannelCount; /* validate inputStreamInfo */ if( inputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ /* Check that the input format is supported */ FillWFEXT(&wfx,paInt16,sampleRate,inputChannelCount); pFilter = wdmHostApi->filters[inputParameters->device]; result = FilterCanCreateCapturePin(pFilter,(const WAVEFORMATEX*)&wfx); if( result != paNoError ) { /* Try a WAVE_FORMAT_PCM instead */ wfx.Format.wFormatTag = WAVE_FORMAT_PCM; wfx.Format.cbSize = 0; wfx.Samples.wValidBitsPerSample = 0; wfx.dwChannelMask = 0; wfx.SubFormat = GUID_NULL; result = FilterCanCreateCapturePin(pFilter,(const WAVEFORMATEX*)&wfx); if( result != paNoError ) return result; } } else { inputChannelCount = 0; } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( outputSampleFormat & paCustomFormat ) return paSampleFormatNotSupported; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that output device can support outputChannelCount */ if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) return paInvalidChannelCount; /* validate outputStreamInfo */ if( outputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ /* Check that the output format is supported */ FillWFEXT(&wfx,paInt16,sampleRate,outputChannelCount); pFilter = wdmHostApi->filters[outputParameters->device]; result = FilterCanCreateRenderPin(pFilter,(const WAVEFORMATEX*)&wfx); if( result != paNoError ) { /* Try a WAVE_FORMAT_PCM instead */ wfx.Format.wFormatTag = WAVE_FORMAT_PCM; wfx.Format.cbSize = 0; wfx.Samples.wValidBitsPerSample = 0; wfx.dwChannelMask = 0; wfx.SubFormat = GUID_NULL; result = FilterCanCreateRenderPin(pFilter,(const WAVEFORMATEX*)&wfx); if( result != paNoError ) return result; } } else { outputChannelCount = 0; } /* IMPLEMENT ME: - if a full duplex stream is requested, check that the combination of input and output parameters is supported if necessary - check that the device supports sampleRate Because the buffer adapter handles conversion between all standard sample formats, the following checks are only required if paCustomFormat is implemented, or under some other unusual conditions. - check that input device can support inputSampleFormat, or that we have the capability to convert from inputSampleFormat to a native format - check that output device can support outputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format */ if((inputChannelCount == 0)&&(outputChannelCount == 0)) result = paSampleFormatNotSupported; /* Not right error */ PA_LOGL_; return result; } /* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ) { PaError result = paNoError; PaWinWdmHostApiRepresentation *wdmHostApi = (PaWinWdmHostApiRepresentation*)hostApi; PaWinWdmStream *stream = 0; /* unsigned long framesPerHostBuffer; these may not be equivalent for all implementations */ PaSampleFormat inputSampleFormat, outputSampleFormat; PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat; int userInputChannels,userOutputChannels; int size; PaWinWdmFilter* pFilter; WAVEFORMATEXTENSIBLE wfx; PA_LOGE_; PA_DEBUG(("OpenStream:sampleRate = %f\n",sampleRate)); PA_DEBUG(("OpenStream:framesPerBuffer = %lu\n",framesPerBuffer)); if( inputParameters ) { userInputChannels = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that input device can support stream->userInputChannels */ if( userInputChannels > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) return paInvalidChannelCount; /* validate inputStreamInfo */ if( inputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else { userInputChannels = 0; inputSampleFormat = hostInputSampleFormat = paInt16; /* Surpress 'uninitialised var' warnings. */ } if( outputParameters ) { userOutputChannels = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that output device can support stream->userInputChannels */ if( userOutputChannels > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) return paInvalidChannelCount; /* validate outputStreamInfo */ if( outputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else { userOutputChannels = 0; outputSampleFormat = hostOutputSampleFormat = paInt16; /* Surpress 'uninitialized var' warnings. */ } /* validate platform specific flags */ if( (streamFlags & paPlatformSpecificFlags) != 0 ) return paInvalidFlag; /* unexpected platform specific flag */ stream = (PaWinWdmStream*)PaUtil_AllocateMemory( sizeof(PaWinWdmStream) ); if( !stream ) { result = paInsufficientMemory; goto error; } /* Zero the stream object */ /* memset((void*)stream,0,sizeof(PaWinWdmStream)); */ if( streamCallback ) { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &wdmHostApi->callbackStreamInterface, streamCallback, userData ); } else { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &wdmHostApi->blockingStreamInterface, streamCallback, userData ); } PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate ); /* Instantiate the input pin if necessary */ if(userInputChannels > 0) { result = paSampleFormatNotSupported; pFilter = wdmHostApi->filters[inputParameters->device]; stream->userInputChannels = userInputChannels; if(((inputSampleFormat & ~paNonInterleaved) & pFilter->formats) != 0) { /* inputSampleFormat is supported, so try to use it */ hostInputSampleFormat = inputSampleFormat; FillWFEXT(&wfx, hostInputSampleFormat, sampleRate, stream->userInputChannels); stream->bytesPerInputFrame = wfx.Format.nBlockAlign; stream->recordingPin = FilterCreateCapturePin(pFilter, (const WAVEFORMATEX*)&wfx, &result); stream->deviceInputChannels = stream->userInputChannels; } if(result != paNoError) { /* Search through all PaSampleFormats to find one that works */ hostInputSampleFormat = paFloat32; do { FillWFEXT(&wfx, hostInputSampleFormat, sampleRate, stream->userInputChannels); stream->bytesPerInputFrame = wfx.Format.nBlockAlign; stream->recordingPin = FilterCreateCapturePin(pFilter, (const WAVEFORMATEX*)&wfx, &result); stream->deviceInputChannels = stream->userInputChannels; if(stream->recordingPin == NULL) result = paSampleFormatNotSupported; if(result != paNoError) hostInputSampleFormat <<= 1; } while(result != paNoError && hostInputSampleFormat <= paUInt8); } if(result != paNoError) { /* None of the PaSampleFormats worked. Set the hostInputSampleFormat to the best fit * and try a PCM format. **/ hostInputSampleFormat = PaUtil_SelectClosestAvailableFormat( pFilter->formats, inputSampleFormat ); /* Try a WAVE_FORMAT_PCM instead */ wfx.Format.wFormatTag = WAVE_FORMAT_PCM; wfx.Format.cbSize = 0; wfx.Samples.wValidBitsPerSample = 0; wfx.dwChannelMask = 0; wfx.SubFormat = GUID_NULL; stream->recordingPin = FilterCreateCapturePin(pFilter,(const WAVEFORMATEX*)&wfx,&result); if(stream->recordingPin == NULL) result = paSampleFormatNotSupported; } if( result != paNoError ) { /* Some or all KS devices can only handle the exact number of channels * they specify. But PortAudio clients expect to be able to * at least specify mono I/O on a multi-channel device * If this is the case, then we will do the channel mapping internally **/ if( stream->userInputChannels < pFilter->maxInputChannels ) { FillWFEXT(&wfx,hostInputSampleFormat,sampleRate,pFilter->maxInputChannels); stream->bytesPerInputFrame = wfx.Format.nBlockAlign; stream->recordingPin = FilterCreateCapturePin(pFilter,(const WAVEFORMATEX*)&wfx,&result); stream->deviceInputChannels = pFilter->maxInputChannels; if( result != paNoError ) { /* Try a WAVE_FORMAT_PCM instead */ wfx.Format.wFormatTag = WAVE_FORMAT_PCM; wfx.Format.cbSize = 0; wfx.Samples.wValidBitsPerSample = 0; wfx.dwChannelMask = 0; wfx.SubFormat = GUID_NULL; stream->recordingPin = FilterCreateCapturePin(pFilter,(const WAVEFORMATEX*)&wfx,&result); } } } if(stream->recordingPin == NULL) { goto error; } switch(hostInputSampleFormat) { case paInt16: stream->inputSampleSize = 2; break; case paInt24: stream->inputSampleSize = 3; break; case paInt32: case paFloat32: stream->inputSampleSize = 4; break; } stream->recordingPin->frameSize /= stream->bytesPerInputFrame; PA_DEBUG(("Pin output frames: %d\n",stream->recordingPin->frameSize)); } else { stream->recordingPin = NULL; stream->bytesPerInputFrame = 0; } /* Instantiate the output pin if necessary */ if(userOutputChannels > 0) { result = paSampleFormatNotSupported; pFilter = wdmHostApi->filters[outputParameters->device]; stream->userOutputChannels = userOutputChannels; if(((outputSampleFormat & ~paNonInterleaved) & pFilter->formats) != 0) { hostOutputSampleFormat = outputSampleFormat; FillWFEXT(&wfx,hostOutputSampleFormat,sampleRate,stream->userOutputChannels); stream->bytesPerOutputFrame = wfx.Format.nBlockAlign; stream->playbackPin = FilterCreateRenderPin(pFilter,(WAVEFORMATEX*)&wfx,&result); stream->deviceOutputChannels = stream->userOutputChannels; } if(result != paNoError) { hostOutputSampleFormat = paFloat32; do { FillWFEXT(&wfx,hostOutputSampleFormat,sampleRate,stream->userOutputChannels); stream->bytesPerOutputFrame = wfx.Format.nBlockAlign; stream->playbackPin = FilterCreateRenderPin(pFilter,(WAVEFORMATEX*)&wfx,&result); stream->deviceOutputChannels = stream->userOutputChannels; if(stream->playbackPin == NULL) result = paSampleFormatNotSupported; if(result != paNoError) hostOutputSampleFormat <<= 1; } while(result != paNoError && hostOutputSampleFormat <= paUInt8); } if(result != paNoError) { hostOutputSampleFormat = PaUtil_SelectClosestAvailableFormat( pFilter->formats, outputSampleFormat ); /* Try a WAVE_FORMAT_PCM instead */ wfx.Format.wFormatTag = WAVE_FORMAT_PCM; wfx.Format.cbSize = 0; wfx.Samples.wValidBitsPerSample = 0; wfx.dwChannelMask = 0; wfx.SubFormat = GUID_NULL; stream->playbackPin = FilterCreateRenderPin(pFilter,(WAVEFORMATEX*)&wfx,&result); if(stream->playbackPin == NULL) result = paSampleFormatNotSupported; } if( result != paNoError ) { /* Some or all KS devices can only handle the exact number of channels * they specify. But PortAudio clients expect to be able to * at least specify mono I/O on a multi-channel device * If this is the case, then we will do the channel mapping internally **/ if( stream->userOutputChannels < pFilter->maxOutputChannels ) { FillWFEXT(&wfx,hostOutputSampleFormat,sampleRate,pFilter->maxOutputChannels); stream->bytesPerOutputFrame = wfx.Format.nBlockAlign; stream->playbackPin = FilterCreateRenderPin(pFilter,(const WAVEFORMATEX*)&wfx,&result); stream->deviceOutputChannels = pFilter->maxOutputChannels; if( result != paNoError ) { /* Try a WAVE_FORMAT_PCM instead */ wfx.Format.wFormatTag = WAVE_FORMAT_PCM; wfx.Format.cbSize = 0; wfx.Samples.wValidBitsPerSample = 0; wfx.dwChannelMask = 0; wfx.SubFormat = GUID_NULL; stream->playbackPin = FilterCreateRenderPin(pFilter,(const WAVEFORMATEX*)&wfx,&result); } } } if(stream->playbackPin == NULL) { goto error; } switch(hostOutputSampleFormat) { case paInt16: stream->outputSampleSize = 2; break; case paInt24: stream->outputSampleSize = 3; break; case paInt32: case paFloat32: stream->outputSampleSize = 4; break; } stream->playbackPin->frameSize /= stream->bytesPerOutputFrame; PA_DEBUG(("Pin output frames: %d\n",stream->playbackPin->frameSize)); } else { stream->playbackPin = NULL; stream->bytesPerOutputFrame = 0; } /* Calculate the framesPerHostXxxxBuffer size based upon the suggested latency values */ /* Record the buffer length */ if(inputParameters) { /* Calculate the frames from the user's value - add a bit to round up */ stream->framesPerHostIBuffer = (unsigned long)((inputParameters->suggestedLatency*sampleRate)+0.0001); if(stream->framesPerHostIBuffer > (unsigned long)sampleRate) { /* Upper limit is 1 second */ stream->framesPerHostIBuffer = (unsigned long)sampleRate; } else if(stream->framesPerHostIBuffer < stream->recordingPin->frameSize) { stream->framesPerHostIBuffer = stream->recordingPin->frameSize; } PA_DEBUG(("Input frames chosen:%ld\n",stream->framesPerHostIBuffer)); } if(outputParameters) { /* Calculate the frames from the user's value - add a bit to round up */ stream->framesPerHostOBuffer = (unsigned long)((outputParameters->suggestedLatency*sampleRate)+0.0001); if(stream->framesPerHostOBuffer > (unsigned long)sampleRate) { /* Upper limit is 1 second */ stream->framesPerHostOBuffer = (unsigned long)sampleRate; } else if(stream->framesPerHostOBuffer < stream->playbackPin->frameSize) { stream->framesPerHostOBuffer = stream->playbackPin->frameSize; } PA_DEBUG(("Output frames chosen:%ld\n",stream->framesPerHostOBuffer)); } /* Host buffer size is bounded to the largest of the input and output frame sizes */ result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, stream->userInputChannels, inputSampleFormat, hostInputSampleFormat, stream->userOutputChannels, outputSampleFormat, hostOutputSampleFormat, sampleRate, streamFlags, framesPerBuffer, max(stream->framesPerHostOBuffer,stream->framesPerHostIBuffer), paUtilBoundedHostBufferSize, streamCallback, userData ); if( result != paNoError ) goto error; stream->streamRepresentation.streamInfo.inputLatency = ((double)stream->framesPerHostIBuffer) / sampleRate; stream->streamRepresentation.streamInfo.outputLatency = ((double)stream->framesPerHostOBuffer) / sampleRate; stream->streamRepresentation.streamInfo.sampleRate = sampleRate; PA_DEBUG(("BytesPerInputFrame = %d\n",stream->bytesPerInputFrame)); PA_DEBUG(("BytesPerOutputFrame = %d\n",stream->bytesPerOutputFrame)); /* Allocate all the buffers for host I/O */ size = 2 * (stream->framesPerHostIBuffer*stream->bytesPerInputFrame + stream->framesPerHostOBuffer*stream->bytesPerOutputFrame); PA_DEBUG(("Buffer size = %d\n",size)); stream->hostBuffer = (char*)PaUtil_AllocateMemory(size); PA_DEBUG(("Buffer allocated\n")); if( !stream->hostBuffer ) { PA_DEBUG(("Cannot allocate host buffer!\n")); result = paInsufficientMemory; goto error; } PA_DEBUG(("Buffer start = %p\n",stream->hostBuffer)); /* memset(stream->hostBuffer,0,size); */ /* Set up the packets */ stream->events[0] = CreateEvent(NULL, FALSE, FALSE, NULL); ResetEvent(stream->events[0]); /* Record buffer 1 */ stream->events[1] = CreateEvent(NULL, FALSE, FALSE, NULL); ResetEvent(stream->events[1]); /* Record buffer 2 */ stream->events[2] = CreateEvent(NULL, FALSE, FALSE, NULL); ResetEvent(stream->events[2]); /* Play buffer 1 */ stream->events[3] = CreateEvent(NULL, FALSE, FALSE, NULL); ResetEvent(stream->events[3]); /* Play buffer 2 */ stream->events[4] = CreateEvent(NULL, FALSE, FALSE, NULL); ResetEvent(stream->events[4]); /* Abort event */ if(stream->userInputChannels > 0) { DATAPACKET *p = &(stream->packets[0]); p->Signal.hEvent = stream->events[0]; p->Header.Data = stream->hostBuffer; p->Header.FrameExtent = stream->framesPerHostIBuffer*stream->bytesPerInputFrame; p->Header.DataUsed = 0; p->Header.Size = sizeof(p->Header); p->Header.PresentationTime.Numerator = 1; p->Header.PresentationTime.Denominator = 1; p = &(stream->packets[1]); p->Signal.hEvent = stream->events[1]; p->Header.Data = stream->hostBuffer + stream->framesPerHostIBuffer*stream->bytesPerInputFrame; p->Header.FrameExtent = stream->framesPerHostIBuffer*stream->bytesPerInputFrame; p->Header.DataUsed = 0; p->Header.Size = sizeof(p->Header); p->Header.PresentationTime.Numerator = 1; p->Header.PresentationTime.Denominator = 1; } if(stream->userOutputChannels > 0) { DATAPACKET *p = &(stream->packets[2]); p->Signal.hEvent = stream->events[2]; p->Header.Data = stream->hostBuffer + 2*stream->framesPerHostIBuffer*stream->bytesPerInputFrame; p->Header.FrameExtent = stream->framesPerHostOBuffer*stream->bytesPerOutputFrame; p->Header.DataUsed = stream->framesPerHostOBuffer*stream->bytesPerOutputFrame; p->Header.Size = sizeof(p->Header); p->Header.PresentationTime.Numerator = 1; p->Header.PresentationTime.Denominator = 1; p = &(stream->packets[3]); p->Signal.hEvent = stream->events[3]; p->Header.Data = stream->hostBuffer + 2*stream->framesPerHostIBuffer*stream->bytesPerInputFrame + stream->framesPerHostOBuffer*stream->bytesPerOutputFrame; p->Header.FrameExtent = stream->framesPerHostOBuffer*stream->bytesPerOutputFrame; p->Header.DataUsed = stream->framesPerHostOBuffer*stream->bytesPerOutputFrame; p->Header.Size = sizeof(p->Header); p->Header.PresentationTime.Numerator = 1; p->Header.PresentationTime.Denominator = 1; } stream->streamStarted = 0; stream->streamActive = 0; stream->streamStop = 0; stream->streamAbort = 0; stream->streamFlags = streamFlags; stream->oldProcessPriority = REALTIME_PRIORITY_CLASS; *s = (PaStream*)stream; PA_LOGL_; return result; error: size = 5; while(size--) { if(stream->events[size] != NULL) { CloseHandle(stream->events[size]); stream->events[size] = NULL; } } if(stream->hostBuffer) PaUtil_FreeMemory( stream->hostBuffer ); if(stream->playbackPin) PinClose(stream->playbackPin); if(stream->recordingPin) PinClose(stream->recordingPin); if( stream ) PaUtil_FreeMemory( stream ); PA_LOGL_; return result; } /* When CloseStream() is called, the multi-api layer ensures that the stream has already been stopped or aborted. */ static PaError CloseStream( PaStream* s ) { PaError result = paNoError; PaWinWdmStream *stream = (PaWinWdmStream*)s; int size; PA_LOGE_; assert(!stream->streamStarted); assert(!stream->streamActive); PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); size = 5; while(size--) { if(stream->events[size] != NULL) { CloseHandle(stream->events[size]); stream->events[size] = NULL; } } if(stream->hostBuffer) PaUtil_FreeMemory( stream->hostBuffer ); if(stream->playbackPin) PinClose(stream->playbackPin); if(stream->recordingPin) PinClose(stream->recordingPin); PaUtil_FreeMemory( stream ); PA_LOGL_; return result; } /* Write the supplied packet to the pin Asynchronous Should return false on success */ static BOOL PinWrite(HANDLE h, DATAPACKET* p) { unsigned long cbReturned = 0; return DeviceIoControl(h,IOCTL_KS_WRITE_STREAM,NULL,0, &p->Header,p->Header.Size,&cbReturned,&p->Signal); } /* Read to the supplied packet from the pin Asynchronous Should return false on success */ static BOOL PinRead(HANDLE h, DATAPACKET* p) { unsigned long cbReturned = 0; return DeviceIoControl(h,IOCTL_KS_READ_STREAM,NULL,0, &p->Header,p->Header.Size,&cbReturned,&p->Signal); } /* Copy the first interleaved channel of 16 bit data to the other channels */ static void DuplicateFirstChannelInt16(void* buffer, int channels, int samples) { unsigned short* data = (unsigned short*)buffer; int channel; unsigned short sourceSample; while( samples-- ) { sourceSample = *data++; channel = channels-1; while( channel-- ) { *data++ = sourceSample; } } } /* Copy the first interleaved channel of 24 bit data to the other channels */ static void DuplicateFirstChannelInt24(void* buffer, int channels, int samples) { unsigned char* data = (unsigned char*)buffer; int channel; unsigned char sourceSample[3]; while( samples-- ) { sourceSample[0] = data[0]; sourceSample[1] = data[1]; sourceSample[2] = data[2]; data += 3; channel = channels-1; while( channel-- ) { data[0] = sourceSample[0]; data[1] = sourceSample[1]; data[2] = sourceSample[2]; data += 3; } } } /* Copy the first interleaved channel of 32 bit data to the other channels */ static void DuplicateFirstChannelInt32(void* buffer, int channels, int samples) { unsigned long* data = (unsigned long*)buffer; int channel; unsigned long sourceSample; while( samples-- ) { sourceSample = *data++; channel = channels-1; while( channel-- ) { *data++ = sourceSample; } } } static DWORD WINAPI ProcessingThread(LPVOID pParam) { PaWinWdmStream *stream = (PaWinWdmStream*)pParam; PaStreamCallbackTimeInfo ti; int cbResult = paContinue; int inbuf = 0; int outbuf = 0; int pending = 0; PaError result; unsigned long wait; unsigned long eventSignaled; int fillPlaybuf = 0; int emptyRecordbuf = 0; int framesProcessed; unsigned long timeout; int i; int doChannelCopy; int priming = 0; PaStreamCallbackFlags underover = 0; PA_LOGE_; ti.inputBufferAdcTime = 0.0; ti.currentTime = 0.0; ti.outputBufferDacTime = 0.0; /* Get double buffering going */ /* Submit buffers */ if(stream->playbackPin) { result = PinSetState(stream->playbackPin, KSSTATE_RUN); PA_DEBUG(("play state run = %d;",(int)result)); SetEvent(stream->events[outbuf+2]); outbuf = (outbuf+1)&1; SetEvent(stream->events[outbuf+2]); outbuf = (outbuf+1)&1; pending += 2; priming += 4; } if(stream->recordingPin) { result = PinSetState(stream->recordingPin, KSSTATE_RUN); PA_DEBUG(("recording state run = %d;",(int)result)); PinRead(stream->recordingPin->handle,&stream->packets[inbuf]); inbuf = (inbuf+1)&1; /* Increment and wrap */ PinRead(stream->recordingPin->handle,&stream->packets[inbuf]); inbuf = (inbuf+1)&1; /* Increment and wrap */ /* FIXME - do error checking */ pending += 2; } PA_DEBUG(("Out buffer len:%f\n",(2000*stream->framesPerHostOBuffer) / stream->streamRepresentation.streamInfo.sampleRate)); PA_DEBUG(("In buffer len:%f\n",(2000*stream->framesPerHostIBuffer) / stream->streamRepresentation.streamInfo.sampleRate)); timeout = max( ((2000*(DWORD)stream->framesPerHostOBuffer) / (DWORD)stream->streamRepresentation.streamInfo.sampleRate), ((2000*(DWORD)stream->framesPerHostIBuffer) / (DWORD)stream->streamRepresentation.streamInfo.sampleRate)); timeout = max(timeout,1); PA_DEBUG(("Timeout = %ld\n",timeout)); while(!stream->streamAbort) { fillPlaybuf = 0; emptyRecordbuf = 0; /* Wait for next input or output buffer to be finished with*/ assert(pending>0); if(stream->streamStop) { PA_DEBUG(("ss1:pending=%d ",pending)); } wait = WaitForMultipleObjects(5, stream->events, FALSE, 0); if( wait == WAIT_TIMEOUT ) { /* No (under|over)flow has ocurred */ wait = WaitForMultipleObjects(5, stream->events, FALSE, timeout); eventSignaled = wait - WAIT_OBJECT_0; } else { eventSignaled = wait - WAIT_OBJECT_0; if( eventSignaled < 2 ) { underover |= paInputOverflow; PA_DEBUG(("Input overflow\n")); } else if(( eventSignaled < 4 )&&(!priming)) { underover |= paOutputUnderflow; PA_DEBUG(("Output underflow\n")); } } if(stream->streamStop) { PA_DEBUG(("ss2:wait=%ld",wait)); } if(wait == WAIT_FAILED) { PA_DEBUG(("Wait fail = %ld! ",wait)); break; } if(wait == WAIT_TIMEOUT) { continue; } if(eventSignaled < 2) { /* Recording input buffer has been filled */ if(stream->playbackPin) { /* First check if also the next playback buffer has been signaled */ wait = WaitForSingleObject(stream->events[outbuf+2],0); if(wait == WAIT_OBJECT_0) { /* Yes, so do both buffers at same time */ fillPlaybuf = 1; pending--; /* Was this an underflow situation? */ if( underover ) underover |= paOutputUnderflow; /* Yes! */ } } emptyRecordbuf = 1; pending--; } else if(eventSignaled < 4) { /* Playback output buffer has been emptied */ if(stream->recordingPin) { /* First check if also the next recording buffer has been signaled */ wait = WaitForSingleObject(stream->events[inbuf],0); if(wait == WAIT_OBJECT_0) { /* Yes, so do both buffers at same time */ emptyRecordbuf = 1; pending--; /* Was this an overflow situation? */ if( underover ) underover |= paInputOverflow; /* Yes! */ } } fillPlaybuf = 1; pending--; } else { /* Abort event! */ assert(stream->streamAbort); /* Should have been set */ PA_DEBUG(("ABORTING ")); break; } ResetEvent(stream->events[eventSignaled]); if(stream->streamStop) { PA_DEBUG(("Stream stop! pending=%d",pending)); cbResult = paComplete; /* Stop, but play remaining buffers */ } /* Do necessary buffer processing (which will invoke user callback if necessary */ doChannelCopy = 0; if(cbResult==paContinue) { PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); if((stream->bufferProcessor.hostInputFrameCount[0] + stream->bufferProcessor.hostInputFrameCount[1]) == (stream->bufferProcessor.hostOutputFrameCount[0] + stream->bufferProcessor.hostOutputFrameCount[1]) ) PaUtil_BeginBufferProcessing(&stream->bufferProcessor,&ti,underover); underover = 0; /* Reset the (under|over)flow status */ if(fillPlaybuf) { PaUtil_SetOutputFrameCount(&stream->bufferProcessor,0); if( stream->userOutputChannels == 1 ) { /* Write the single user channel to the first interleaved block */ PaUtil_SetOutputChannel(&stream->bufferProcessor,0,stream->packets[outbuf+2].Header.Data,stream->deviceOutputChannels); /* We will do a copy to the other channels after the data has been written */ doChannelCopy = 1; } else { for(i=0;iuserOutputChannels;i++) { /* Only write the user output channels. Leave the rest blank */ PaUtil_SetOutputChannel(&stream->bufferProcessor,i,((unsigned char*)(stream->packets[outbuf+2].Header.Data))+(i*stream->outputSampleSize),stream->deviceOutputChannels); } } } if(emptyRecordbuf) { PaUtil_SetInputFrameCount(&stream->bufferProcessor,stream->packets[inbuf].Header.DataUsed/stream->bytesPerInputFrame); for(i=0;iuserInputChannels;i++) { /* Only read as many channels as the user wants */ PaUtil_SetInputChannel(&stream->bufferProcessor,i,((unsigned char*)(stream->packets[inbuf].Header.Data))+(i*stream->inputSampleSize),stream->deviceInputChannels); } } /* Only call the EndBufferProcessing function is the total input frames == total output frames */ if((stream->bufferProcessor.hostInputFrameCount[0] + stream->bufferProcessor.hostInputFrameCount[1]) == (stream->bufferProcessor.hostOutputFrameCount[0] + stream->bufferProcessor.hostOutputFrameCount[1]) ) framesProcessed = PaUtil_EndBufferProcessing(&stream->bufferProcessor,&cbResult); else framesProcessed = 0; if( doChannelCopy ) { /* Copy the first output channel to the other channels */ switch(stream->outputSampleSize) { case 2: DuplicateFirstChannelInt16(stream->packets[outbuf+2].Header.Data,stream->deviceOutputChannels,stream->framesPerHostOBuffer); break; case 3: DuplicateFirstChannelInt24(stream->packets[outbuf+2].Header.Data,stream->deviceOutputChannels,stream->framesPerHostOBuffer); break; case 4: DuplicateFirstChannelInt32(stream->packets[outbuf+2].Header.Data,stream->deviceOutputChannels,stream->framesPerHostOBuffer); break; default: assert(0); /* Unsupported format! */ break; } } PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed ); } else { fillPlaybuf = 0; emptyRecordbuf = 0; } /* if(cbResult != paContinue) { PA_DEBUG(("cbResult=%d, pending=%d:",cbResult,pending)); } */ /* Submit buffers */ if((fillPlaybuf)&&(cbResult!=paAbort)) { if(!PinWrite(stream->playbackPin->handle,&stream->packets[outbuf+2])) outbuf = (outbuf+1)&1; /* Increment and wrap */ pending++; if( priming ) priming--; /* Have to prime twice */ } if((emptyRecordbuf)&&(cbResult==paContinue)) { stream->packets[inbuf].Header.DataUsed = 0; /* Reset for reuse */ PinRead(stream->recordingPin->handle,&stream->packets[inbuf]); inbuf = (inbuf+1)&1; /* Increment and wrap */ pending++; } if(pending==0) { PA_DEBUG(("pending==0 finished...;")); break; } if((!stream->playbackPin)&&(cbResult!=paContinue)) { PA_DEBUG(("record only cbResult=%d...;",cbResult)); break; } } PA_DEBUG(("Finished thread")); /* Finished, either normally or aborted */ if(stream->playbackPin) { result = PinSetState(stream->playbackPin, KSSTATE_PAUSE); result = PinSetState(stream->playbackPin, KSSTATE_STOP); } if(stream->recordingPin) { result = PinSetState(stream->recordingPin, KSSTATE_PAUSE); result = PinSetState(stream->recordingPin, KSSTATE_STOP); } stream->streamActive = 0; if((!stream->streamStop)&&(!stream->streamAbort)) { /* Invoke the user stream finished callback */ /* Only do it from here if not being stopped/aborted by user */ if( stream->streamRepresentation.streamFinishedCallback != 0 ) stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); } stream->streamStop = 0; stream->streamAbort = 0; /* Reset process priority if necessary */ if(stream->oldProcessPriority != REALTIME_PRIORITY_CLASS) { SetPriorityClass(GetCurrentProcess(),stream->oldProcessPriority); stream->oldProcessPriority = REALTIME_PRIORITY_CLASS; } PA_LOGL_; ExitThread(0); return 0; } static PaError StartStream( PaStream *s ) { PaError result = paNoError; PaWinWdmStream *stream = (PaWinWdmStream*)s; DWORD dwID; BOOL ret; int size; PA_LOGE_; stream->streamStop = 0; stream->streamAbort = 0; size = 5; while(size--) { if(stream->events[size] != NULL) { ResetEvent(stream->events[size]); } } PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); stream->oldProcessPriority = GetPriorityClass(GetCurrentProcess()); /* Uncomment the following line to enable dynamic boosting of the process * priority to real time for best low latency support * Disabled by default because RT processes can easily block the OS */ /*ret = SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS); PA_DEBUG(("Class ret = %d;",ret));*/ stream->streamStarted = 1; stream->streamThread = CreateThread(NULL, 0, ProcessingThread, stream, 0, &dwID); if(stream->streamThread == NULL) { stream->streamStarted = 0; result = paInsufficientMemory; goto end; } ret = SetThreadPriority(stream->streamThread,THREAD_PRIORITY_TIME_CRITICAL); PA_DEBUG(("Priority ret = %d;",ret)); /* Make the stream active */ stream->streamActive = 1; end: PA_LOGL_; return result; } static PaError StopStream( PaStream *s ) { PaError result = paNoError; PaWinWdmStream *stream = (PaWinWdmStream*)s; int doCb = 0; PA_LOGE_; if(stream->streamActive) { doCb = 1; stream->streamStop = 1; while(stream->streamActive) { PA_DEBUG(("W.")); Sleep(10); /* Let thread sleep for 10 msec */ } } PA_DEBUG(("Terminating thread")); if(stream->streamStarted && stream->streamThread) { TerminateThread(stream->streamThread,0); stream->streamThread = NULL; } stream->streamStarted = 0; if(stream->oldProcessPriority != REALTIME_PRIORITY_CLASS) { SetPriorityClass(GetCurrentProcess(),stream->oldProcessPriority); stream->oldProcessPriority = REALTIME_PRIORITY_CLASS; } if(doCb) { /* Do user callback now after all state has been reset */ /* This means it should be safe for the called function */ /* to invoke e.g. StartStream */ if( stream->streamRepresentation.streamFinishedCallback != 0 ) stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); } PA_LOGL_; return result; } static PaError AbortStream( PaStream *s ) { PaError result = paNoError; PaWinWdmStream *stream = (PaWinWdmStream*)s; int doCb = 0; PA_LOGE_; if(stream->streamActive) { doCb = 1; stream->streamAbort = 1; SetEvent(stream->events[4]); /* Signal immediately */ while(stream->streamActive) { Sleep(10); } } if(stream->streamStarted && stream->streamThread) { TerminateThread(stream->streamThread,0); stream->streamThread = NULL; } stream->streamStarted = 0; if(stream->oldProcessPriority != REALTIME_PRIORITY_CLASS) { SetPriorityClass(GetCurrentProcess(),stream->oldProcessPriority); stream->oldProcessPriority = REALTIME_PRIORITY_CLASS; } if(doCb) { /* Do user callback now after all state has been reset */ /* This means it should be safe for the called function */ /* to invoke e.g. StartStream */ if( stream->streamRepresentation.streamFinishedCallback != 0 ) stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); } stream->streamActive = 0; stream->streamStarted = 0; PA_LOGL_; return result; } static PaError IsStreamStopped( PaStream *s ) { PaWinWdmStream *stream = (PaWinWdmStream*)s; int result = 0; PA_LOGE_; if(!stream->streamStarted) result = 1; PA_LOGL_; return result; } static PaError IsStreamActive( PaStream *s ) { PaWinWdmStream *stream = (PaWinWdmStream*)s; int result = 0; PA_LOGE_; if(stream->streamActive) result = 1; PA_LOGL_; return result; } static PaTime GetStreamTime( PaStream* s ) { PA_LOGE_; PA_LOGL_; (void)s; return PaUtil_GetTime(); } static double GetStreamCpuLoad( PaStream* s ) { PaWinWdmStream *stream = (PaWinWdmStream*)s; double result; PA_LOGE_; result = PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); PA_LOGL_; return result; } /* As separate stream interfaces are used for blocking and callback streams, the following functions can be guaranteed to only be called for blocking streams. */ static PaError ReadStream( PaStream* s, void *buffer, unsigned long frames ) { PaWinWdmStream *stream = (PaWinWdmStream*)s; PA_LOGE_; /* suppress unused variable warnings */ (void) buffer; (void) frames; (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ PA_LOGL_; return paNoError; } static PaError WriteStream( PaStream* s, const void *buffer, unsigned long frames ) { PaWinWdmStream *stream = (PaWinWdmStream*)s; PA_LOGE_; /* suppress unused variable warnings */ (void) buffer; (void) frames; (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ PA_LOGL_; return paNoError; } static signed long GetStreamReadAvailable( PaStream* s ) { PaWinWdmStream *stream = (PaWinWdmStream*)s; PA_LOGE_; /* suppress unused variable warnings */ (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ PA_LOGL_; return 0; } static signed long GetStreamWriteAvailable( PaStream* s ) { PaWinWdmStream *stream = (PaWinWdmStream*)s; PA_LOGE_; /* suppress unused variable warnings */ (void) stream; /* IMPLEMENT ME, see portaudio.h for required behavior*/ PA_LOGL_; return 0; }praat-6.0.04/external/portaudio2007/pa_win_wdmks_utils.h000066400000000000000000000047051261542461700231420ustar00rootroot00000000000000#ifndef PA_WIN_WDMKS_UTILS_H #define PA_WIN_WDMKS_UTILS_H /* * PortAudio Portable Real-Time Audio Library * Windows WDM KS utilities * * Copyright (c) 1999 - 2007 Ross Bencina, Andrew Baldwin * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @brief Utilities for working with the Windows WDM KS API */ #ifdef __cplusplus extern "C" { #endif /** Query for the maximum number of channels supported by any pin of the specified device. Returns 0 if the query fails for any reason. @param wcharDevicePath A system level PnP interface path, supplied as a WCHAR unicode string. Declard as void* to avoid introducing a dependency on wchar_t here. @param isInput A flag specifying whether to query for input (non-zero) or output (zero) channels. */ int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInput ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_WIN_WDMKS_UTILS_H */praat-6.0.04/external/portaudio2007/pa_win_wmme.c000066400000000000000000004416051261542461700215410ustar00rootroot00000000000000#ifdef _WIN32 /* * $Id: pa_win_wmme.c 1286 2007-09-26 21:34:23Z rossb $ * pa_win_wmme.c * Implementation of PortAudio for Windows MultiMedia Extensions (WMME) * * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * * Authors: Ross Bencina and Phil Burk * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /* Modification History: PLB = Phil Burk JM = Julien Maillard RDB = Ross Bencina PLB20010402 - sDevicePtrs now allocates based on sizeof(pointer) PLB20010413 - check for excessive numbers of channels PLB20010422 - apply Mike Berry's changes for CodeWarrior on PC including conditional inclusion of memory.h, and explicit typecasting on memory allocation PLB20010802 - use GlobalAlloc for sDevicesPtr instead of PaHost_AllocFastMemory PLB20010816 - pass process instead of thread to SetPriorityClass() PLB20010927 - use number of frames instead of real-time for CPULoad calculation. JM20020118 - prevent hung thread when buffers underflow. PLB20020321 - detect Win XP versus NT, 9x; fix DBUG typo; removed init of CurrentCount RDB20020411 - various renaming cleanups, factored streamData alloc and cpu usage init RDB20020417 - stopped counting WAVE_MAPPER when there were no real devices refactoring, renaming and fixed a few edge case bugs RDB20020531 - converted to V19 framework ** NOTE maintanance history is now stored in CVS ** */ /** @file @ingroup hostaip_src @todo Fix buffer catch up code, can sometimes get stuck (perhaps fixed now, needs to be reviewed and tested.) @todo implement paInputUnderflow, paOutputOverflow streamCallback statusFlags, paNeverDropInput. @todo BUG: PA_MME_SET_LAST_WAVEIN/OUT_ERROR is used in functions which may be called asynchronously from the callback thread. this is bad. @todo implement inputBufferAdcTime in callback thread @todo review/fix error recovery and cleanup in marked functions @todo implement timeInfo for stream priming @todo handle the case where the callback returns paAbort or paComplete during stream priming. @todo review input overflow and output underflow handling in ReadStream and WriteStream Non-critical stuff for the future: @todo Investigate supporting host buffer formats > 16 bits @todo define UNICODE and _UNICODE in the project settings and see what breaks @todo refactor conversion of MMSYSTEM errors into PA arrors into a single function. @todo cleanup WAVEFORMATEXTENSIBLE retry in InitializeWaveHandles to not use a for loop */ /* How it works: For both callback and blocking read/write streams we open the MME devices in CALLBACK_EVENT mode. In this mode, MME signals an Event object whenever it has finished with a buffer (either filled it for input, or played it for output). Where necessary we block waiting for Event objects using WaitMultipleObjects(). When implementing a PA callback stream, we set up a high priority thread which waits on the MME buffer Events and drains/fills the buffers when they are ready. When implementing a PA blocking read/write stream, we simply wait on these Events (when necessary) inside the ReadStream() and WriteStream() functions. */ #undef UNICODE #include #include #include #include #include #ifndef UNDER_CE #include #endif #include /* PLB20010422 - "memory.h" doesn't work on CodeWarrior for PC. Thanks Mike Berry for the mod. */ #ifndef __MWERKS__XXX #include #include #endif /* __MWERKS__ */ #include "portaudio.h" #include "pa_trace.h" #include "pa_util.h" #include "pa_allocation.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_cpuload.h" #include "pa_process.h" #include "pa_debugprint.h" #include "pa_win_wmme.h" #include "pa_win_waveformat.h" #ifdef PAWIN_USE_WDMKS_DEVICE_INFO #include "pa_win_wdmks_utils.h" #ifndef DRV_QUERYDEVICEINTERFACE #define DRV_QUERYDEVICEINTERFACE (DRV_RESERVED + 12) #endif #ifndef DRV_QUERYDEVICEINTERFACESIZE #define DRV_QUERYDEVICEINTERFACESIZE (DRV_RESERVED + 13) #endif #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ #if (defined(UNDER_CE)) #pragma comment(lib, "Coredll.lib") #elif (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */ #pragma comment(lib, "winmm.lib") #endif /* provided in newer platform sdks */ #ifndef DWORD_PTR #define DWORD_PTR DWORD #endif /************************************************* Constants ********/ #define PA_MME_USE_HIGH_DEFAULT_LATENCY_ (0) /* For debugging glitches. */ #if PA_MME_USE_HIGH_DEFAULT_LATENCY_ #define PA_MME_WIN_9X_DEFAULT_LATENCY_ (0.4) #define PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_ (4) #define PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_ (4) #define PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_HALF_DUPLEX_ (4) #define PA_MME_MIN_HOST_BUFFER_FRAMES_WHEN_UNSPECIFIED_ (16) #define PA_MME_MAX_HOST_BUFFER_SECS_ (0.3) /* Do not exceed unless user buffer exceeds */ #define PA_MME_MAX_HOST_BUFFER_BYTES_ (32 * 1024) /* Has precedence over PA_MME_MAX_HOST_BUFFER_SECS_, some drivers are known to crash with buffer sizes > 32k */ #else #define PA_MME_WIN_9X_DEFAULT_LATENCY_ (0.2) #define PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_ (2) #define PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_ (3) #define PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_HALF_DUPLEX_ (2) #define PA_MME_MIN_HOST_BUFFER_FRAMES_WHEN_UNSPECIFIED_ (16) #define PA_MME_MAX_HOST_BUFFER_SECS_ (0.1) /* Do not exceed unless user buffer exceeds */ #define PA_MME_MAX_HOST_BUFFER_BYTES_ (32 * 1024) /* Has precedence over PA_MME_MAX_HOST_BUFFER_SECS_, some drivers are known to crash with buffer sizes > 32k */ #endif /* Use higher latency for NT because it is even worse at real-time operation than Win9x. */ #define PA_MME_WIN_NT_DEFAULT_LATENCY_ (PA_MME_WIN_9X_DEFAULT_LATENCY_ * 2) #define PA_MME_WIN_WDM_DEFAULT_LATENCY_ (PA_MME_WIN_9X_DEFAULT_LATENCY_) #define PA_MME_MIN_TIMEOUT_MSEC_ (1000) static const char constInputMapperSuffix_[] = " - Input"; static const char constOutputMapperSuffix_[] = " - Output"; /********************************************************************/ typedef struct PaWinMmeStream PaWinMmeStream; /* forward declaration */ /* prototypes for functions declared in this file */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); #ifdef __cplusplus } #endif /* __cplusplus */ static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** stream, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); static PaError CloseStream( PaStream* stream ); static PaError StartStream( PaStream *stream ); static PaError StopStream( PaStream *stream ); static PaError AbortStream( PaStream *stream ); static PaError IsStreamStopped( PaStream *s ); static PaError IsStreamActive( PaStream *stream ); static PaTime GetStreamTime( PaStream *stream ); static double GetStreamCpuLoad( PaStream* stream ); static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ); static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ); static signed long GetStreamReadAvailable( PaStream* stream ); static signed long GetStreamWriteAvailable( PaStream* stream ); /* macros for setting last host error information */ #ifdef UNICODE #define PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ) \ { \ wchar_t mmeErrorTextWide[ MAXERRORLENGTH ]; \ char mmeErrorText[ MAXERRORLENGTH ]; \ waveInGetErrorText( mmresult, mmeErrorTextWide, MAXERRORLENGTH ); \ WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR,\ mmeErrorTextWide, -1, mmeErrorText, MAXERRORLENGTH, NULL, NULL ); \ PaUtil_SetLastHostErrorInfo( paMME, mmresult, mmeErrorText ); \ } #define PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ) \ { \ wchar_t mmeErrorTextWide[ MAXERRORLENGTH ]; \ char mmeErrorText[ MAXERRORLENGTH ]; \ waveOutGetErrorText( mmresult, mmeErrorTextWide, MAXERRORLENGTH ); \ WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR,\ mmeErrorTextWide, -1, mmeErrorText, MAXERRORLENGTH, NULL, NULL ); \ PaUtil_SetLastHostErrorInfo( paMME, mmresult, mmeErrorText ); \ } #else /* !UNICODE */ #define PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ) \ { \ char mmeErrorText[ MAXERRORLENGTH ]; \ waveInGetErrorText( mmresult, mmeErrorText, MAXERRORLENGTH ); \ PaUtil_SetLastHostErrorInfo( paMME, mmresult, mmeErrorText ); \ } #define PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ) \ { \ char mmeErrorText[ MAXERRORLENGTH ]; \ waveOutGetErrorText( mmresult, mmeErrorText, MAXERRORLENGTH ); \ PaUtil_SetLastHostErrorInfo( paMME, mmresult, mmeErrorText ); \ } #endif /* UNICODE */ static void PaMme_SetLastSystemError( DWORD errorCode ) { char *lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); PaUtil_SetLastHostErrorInfo( paMME, errorCode, lpMsgBuf ); LocalFree( lpMsgBuf ); } #define PA_MME_SET_LAST_SYSTEM_ERROR( errorCode ) \ PaMme_SetLastSystemError( errorCode ) /* PaError returning wrappers for some commonly used win32 functions note that we allow passing a null ptr to have no effect. */ static PaError CreateEventWithPaError( HANDLE *handle, LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCTSTR lpName ) { PaError result = paNoError; *handle = NULL; *handle = CreateEvent( lpEventAttributes, bManualReset, bInitialState, lpName ); if( *handle == NULL ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() ); } return result; } static PaError ResetEventWithPaError( HANDLE handle ) { PaError result = paNoError; if( handle ) { if( ResetEvent( handle ) == 0 ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() ); } } return result; } static PaError CloseHandleWithPaError( HANDLE handle ) { PaError result = paNoError; if( handle ) { if( CloseHandle( handle ) == 0 ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() ); } } return result; } /* PaWinMmeHostApiRepresentation - host api datastructure specific to this implementation */ typedef struct { PaUtilHostApiRepresentation inheritedHostApiRep; PaUtilStreamInterface callbackStreamInterface; PaUtilStreamInterface blockingStreamInterface; PaUtilAllocationGroup *allocations; int inputDeviceCount, outputDeviceCount; /** winMmeDeviceIds is an array of WinMme device ids. fields in the range [0, inputDeviceCount) are input device ids, and [inputDeviceCount, inputDeviceCount + outputDeviceCount) are output device ids. */ UINT *winMmeDeviceIds; } PaWinMmeHostApiRepresentation; typedef struct { PaDeviceInfo inheritedDeviceInfo; DWORD dwFormats; /**<< standard formats bitmask from the WAVEINCAPS and WAVEOUTCAPS structures */ char deviceInputChannelCountIsKnown; /**<< if the system returns 0xFFFF then we don't really know the number of supported channels (1=>known, 0=>unknown)*/ char deviceOutputChannelCountIsKnown; /**<< if the system returns 0xFFFF then we don't really know the number of supported channels (1=>known, 0=>unknown)*/ } PaWinMmeDeviceInfo; /************************************************************************* * Returns recommended device ID. * On the PC, the recommended device can be specified by the user by * setting an environment variable. For example, to use device #1. * * set PA_RECOMMENDED_OUTPUT_DEVICE=1 * * The user should first determine the available device ID by using * the supplied application "pa_devs". */ #define PA_ENV_BUF_SIZE_ (32) #define PA_REC_IN_DEV_ENV_NAME_ ("PA_RECOMMENDED_INPUT_DEVICE") #define PA_REC_OUT_DEV_ENV_NAME_ ("PA_RECOMMENDED_OUTPUT_DEVICE") static PaDeviceIndex GetEnvDefaultDeviceID( char *envName ) { PaDeviceIndex recommendedIndex = paNoDevice; DWORD hresult; char envbuf[PA_ENV_BUF_SIZE_]; #ifndef WIN32_PLATFORM_PSPC /* no GetEnvironmentVariable on PocketPC */ /* Let user determine default device by setting environment variable. */ hresult = GetEnvironmentVariableA( envName, envbuf, PA_ENV_BUF_SIZE_ ); if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE_) ) { recommendedIndex = atoi( envbuf ); } #endif return recommendedIndex; } static void InitializeDefaultDeviceIdsFromEnv( PaWinMmeHostApiRepresentation *hostApi ) { PaDeviceIndex device; /* input */ device = GetEnvDefaultDeviceID( PA_REC_IN_DEV_ENV_NAME_ ); if( device != paNoDevice && ( device >= 0 && device < hostApi->inheritedHostApiRep.info.deviceCount ) && hostApi->inheritedHostApiRep.deviceInfos[ device ]->maxInputChannels > 0 ) { hostApi->inheritedHostApiRep.info.defaultInputDevice = device; } /* output */ device = GetEnvDefaultDeviceID( PA_REC_OUT_DEV_ENV_NAME_ ); if( device != paNoDevice && ( device >= 0 && device < hostApi->inheritedHostApiRep.info.deviceCount ) && hostApi->inheritedHostApiRep.deviceInfos[ device ]->maxOutputChannels > 0 ) { hostApi->inheritedHostApiRep.info.defaultOutputDevice = device; } } /** Convert external PA ID to a windows multimedia device ID */ static UINT LocalDeviceIndexToWinMmeDeviceId( PaWinMmeHostApiRepresentation *hostApi, PaDeviceIndex device ) { assert( device >= 0 && device < hostApi->inputDeviceCount + hostApi->outputDeviceCount ); return hostApi->winMmeDeviceIds[ device ]; } static PaError QueryInputWaveFormatEx( int deviceId, WAVEFORMATEX *waveFormatEx ) { MMRESULT mmresult; switch( mmresult = waveInOpen( NULL, deviceId, waveFormatEx, 0, 0, WAVE_FORMAT_QUERY ) ) { case MMSYSERR_NOERROR: return paNoError; case MMSYSERR_ALLOCATED: /* Specified resource is already allocated. */ return paDeviceUnavailable; case MMSYSERR_NODRIVER: /* No device driver is present. */ return paDeviceUnavailable; case MMSYSERR_NOMEM: /* Unable to allocate or lock memory. */ return paInsufficientMemory; case WAVERR_BADFORMAT: /* Attempted to open with an unsupported waveform-audio format. */ return paSampleFormatNotSupported; case MMSYSERR_BADDEVICEID: /* Specified device identifier is out of range. */ /* falls through */ default: PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); return paUnanticipatedHostError; } } static PaError QueryOutputWaveFormatEx( int deviceId, WAVEFORMATEX *waveFormatEx ) { MMRESULT mmresult; switch( mmresult = waveOutOpen( NULL, deviceId, waveFormatEx, 0, 0, WAVE_FORMAT_QUERY ) ) { case MMSYSERR_NOERROR: return paNoError; case MMSYSERR_ALLOCATED: /* Specified resource is already allocated. */ return paDeviceUnavailable; case MMSYSERR_NODRIVER: /* No device driver is present. */ return paDeviceUnavailable; case MMSYSERR_NOMEM: /* Unable to allocate or lock memory. */ return paInsufficientMemory; case WAVERR_BADFORMAT: /* Attempted to open with an unsupported waveform-audio format. */ return paSampleFormatNotSupported; case MMSYSERR_BADDEVICEID: /* Specified device identifier is out of range. */ /* falls through */ default: PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); return paUnanticipatedHostError; } } static PaError QueryFormatSupported( PaDeviceInfo *deviceInfo, PaError (*waveFormatExQueryFunction)(int, WAVEFORMATEX*), int winMmeDeviceId, int channels, double sampleRate ) { PaWinMmeDeviceInfo *winMmeDeviceInfo = (PaWinMmeDeviceInfo*)deviceInfo; PaWinWaveFormat waveFormat; if( sampleRate == 11025.0 && ( (channels == 1 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_1M16)) || (channels == 2 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_1S16)) ) ){ return paNoError; } if( sampleRate == 22050.0 && ( (channels == 1 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_2M16)) || (channels == 2 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_2S16)) ) ){ return paNoError; } if( sampleRate == 44100.0 && ( (channels == 1 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_4M16)) || (channels == 2 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_4S16)) ) ){ return paNoError; } /* first, attempt to query the device using WAVEFORMATEXTENSIBLE, if this fails we fall back to WAVEFORMATEX */ /* @todo at the moment we only query with 16 bit sample format and directout speaker config*/ PaWin_InitializeWaveFormatExtensible( &waveFormat, channels, paInt16, sampleRate, PAWIN_SPEAKER_DIRECTOUT ); if( waveFormatExQueryFunction( winMmeDeviceId, (WAVEFORMATEX*)&waveFormat ) == paNoError ) return paNoError; PaWin_InitializeWaveFormatEx( &waveFormat, channels, paInt16, sampleRate ); return waveFormatExQueryFunction( winMmeDeviceId, (WAVEFORMATEX*)&waveFormat ); } #define PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_ (13) /* must match array length below */ static double defaultSampleRateSearchOrder_[] = { 44100.0, 48000.0, 32000.0, 24000.0, 22050.0, 88200.0, 96000.0, 192000.0, 16000.0, 12000.0, 11025.0, 9600.0, 8000.0 }; static void DetectDefaultSampleRate( PaWinMmeDeviceInfo *winMmeDeviceInfo, int winMmeDeviceId, PaError (*waveFormatExQueryFunction)(int, WAVEFORMATEX*), int maxChannels ) { PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo; int i; deviceInfo->defaultSampleRate = 0.; for( i=0; i < PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_; ++i ) { double sampleRate = defaultSampleRateSearchOrder_[ i ]; PaError paerror = QueryFormatSupported( deviceInfo, waveFormatExQueryFunction, winMmeDeviceId, maxChannels, sampleRate ); if( paerror == paNoError ) { deviceInfo->defaultSampleRate = sampleRate; break; } } } #ifdef PAWIN_USE_WDMKS_DEVICE_INFO static int QueryWaveInKSFilterMaxChannels( int waveInDeviceId, int *maxChannels ) { void *devicePath; DWORD devicePathSize; int result = 0; if( waveInMessage((HWAVEIN)waveInDeviceId, DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&devicePathSize, 0 ) != MMSYSERR_NOERROR ) return 0; devicePath = PaUtil_AllocateMemory( devicePathSize ); if( !devicePath ) return 0; /* apparently DRV_QUERYDEVICEINTERFACE returns a unicode interface path, although this is undocumented */ if( waveInMessage((HWAVEIN)waveInDeviceId, DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)devicePath, devicePathSize ) == MMSYSERR_NOERROR ) { int count = PaWin_WDMKS_QueryFilterMaximumChannelCount( devicePath, /* isInput= */ 1 ); if( count > 0 ) { *maxChannels = count; result = 1; } } PaUtil_FreeMemory( devicePath ); return result; } #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ static PaError InitializeInputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeHostApi, PaWinMmeDeviceInfo *winMmeDeviceInfo, UINT winMmeInputDeviceId, int *success ) { PaError result = paNoError; char *deviceName; /* non-const ptr */ MMRESULT mmresult; WAVEINCAPSA wic; PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo; *success = 0; mmresult = waveInGetDevCapsA( winMmeInputDeviceId, &wic, sizeof( WAVEINCAPSA ) ); if( mmresult == MMSYSERR_NOMEM ) { result = paInsufficientMemory; goto error; } else if( mmresult != MMSYSERR_NOERROR ) { /* instead of returning paUnanticipatedHostError we return paNoError, but leave success set as 0. This allows Pa_Initialize to just ignore this device, without failing the entire initialisation process. */ return paNoError; } if( winMmeInputDeviceId == WAVE_MAPPER ) { /* Append I/O suffix to WAVE_MAPPER device. */ deviceName = (char *)PaUtil_GroupAllocateMemory( winMmeHostApi->allocations, strlen( wic.szPname ) + 1 + sizeof(constInputMapperSuffix_) ); if( !deviceName ) { result = paInsufficientMemory; goto error; } strcpy( deviceName, wic.szPname ); strcat( deviceName, constInputMapperSuffix_ ); } else { deviceName = (char*)PaUtil_GroupAllocateMemory( winMmeHostApi->allocations, strlen( wic.szPname ) + 1 ); if( !deviceName ) { result = paInsufficientMemory; goto error; } strcpy( deviceName, wic.szPname ); } deviceInfo->name = deviceName; if( wic.wChannels == 0xFFFF || wic.wChannels < 1 || wic.wChannels > 255 ){ /* For Windows versions using WDM (possibly Windows 98 ME and later) * the kernel mixer sits between the application and the driver. As a result, * wave*GetDevCaps often kernel mixer channel counts, which are unlimited. * When this happens we assume the device is stereo and set a flag * so that other channel counts can be tried with OpenStream -- i.e. when * device*ChannelCountIsKnown is false, OpenStream will try whatever * channel count you supply. * see also InitializeOutputDeviceInfo() below. */ PA_DEBUG(("Pa_GetDeviceInfo: Num input channels reported as %d! Changed to 2.\n", wic.wChannels )); deviceInfo->maxInputChannels = 2; winMmeDeviceInfo->deviceInputChannelCountIsKnown = 0; }else{ deviceInfo->maxInputChannels = wic.wChannels; winMmeDeviceInfo->deviceInputChannelCountIsKnown = 1; } #ifdef PAWIN_USE_WDMKS_DEVICE_INFO winMmeDeviceInfo->deviceInputChannelCountIsKnown = QueryWaveInKSFilterMaxChannels( winMmeInputDeviceId, &deviceInfo->maxInputChannels ); #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ winMmeDeviceInfo->dwFormats = wic.dwFormats; DetectDefaultSampleRate( winMmeDeviceInfo, winMmeInputDeviceId, QueryInputWaveFormatEx, deviceInfo->maxInputChannels ); *success = 1; error: return result; } #ifdef PAWIN_USE_WDMKS_DEVICE_INFO static int QueryWaveOutKSFilterMaxChannels( int waveOutDeviceId, int *maxChannels ) { void *devicePath; DWORD devicePathSize; int result = 0; if( waveOutMessage((HWAVEOUT)waveOutDeviceId, DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&devicePathSize, 0 ) != MMSYSERR_NOERROR ) return 0; devicePath = PaUtil_AllocateMemory( devicePathSize ); if( !devicePath ) return 0; /* apparently DRV_QUERYDEVICEINTERFACE returns a unicode interface path, although this is undocumented */ if( waveOutMessage((HWAVEOUT)waveOutDeviceId, DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)devicePath, devicePathSize ) == MMSYSERR_NOERROR ) { int count = PaWin_WDMKS_QueryFilterMaximumChannelCount( devicePath, /* isInput= */ 0 ); if( count > 0 ) { *maxChannels = count; result = 1; } } PaUtil_FreeMemory( devicePath ); return result; } #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeHostApi, PaWinMmeDeviceInfo *winMmeDeviceInfo, UINT winMmeOutputDeviceId, int *success ) { PaError result = paNoError; char *deviceName; /* non-const ptr */ MMRESULT mmresult; WAVEOUTCAPSA woc; PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo; *success = 0; mmresult = waveOutGetDevCapsA( winMmeOutputDeviceId, &woc, sizeof( WAVEOUTCAPSA ) ); if( mmresult == MMSYSERR_NOMEM ) { result = paInsufficientMemory; goto error; } else if( mmresult != MMSYSERR_NOERROR ) { /* instead of returning paUnanticipatedHostError we return paNoError, but leave success set as 0. This allows Pa_Initialize to just ignore this device, without failing the entire initialisation process. */ return paNoError; } if( winMmeOutputDeviceId == WAVE_MAPPER ) { /* Append I/O suffix to WAVE_MAPPER device. */ deviceName = (char *)PaUtil_GroupAllocateMemory( winMmeHostApi->allocations, strlen( woc.szPname ) + 1 + sizeof(constOutputMapperSuffix_) ); if( !deviceName ) { result = paInsufficientMemory; goto error; } strcpy( deviceName, woc.szPname ); strcat( deviceName, constOutputMapperSuffix_ ); } else { deviceName = (char*)PaUtil_GroupAllocateMemory( winMmeHostApi->allocations, strlen( woc.szPname ) + 1 ); if( !deviceName ) { result = paInsufficientMemory; goto error; } strcpy( deviceName, woc.szPname ); } deviceInfo->name = deviceName; if( woc.wChannels == 0xFFFF || woc.wChannels < 1 || woc.wChannels > 255 ){ /* For Windows versions using WDM (possibly Windows 98 ME and later) * the kernel mixer sits between the application and the driver. As a result, * wave*GetDevCaps often kernel mixer channel counts, which are unlimited. * When this happens we assume the device is stereo and set a flag * so that other channel counts can be tried with OpenStream -- i.e. when * device*ChannelCountIsKnown is false, OpenStream will try whatever * channel count you supply. * see also InitializeInputDeviceInfo() above. */ PA_DEBUG(("Pa_GetDeviceInfo: Num output channels reported as %d! Changed to 2.\n", woc.wChannels )); deviceInfo->maxOutputChannels = 2; winMmeDeviceInfo->deviceOutputChannelCountIsKnown = 0; }else{ deviceInfo->maxOutputChannels = woc.wChannels; winMmeDeviceInfo->deviceOutputChannelCountIsKnown = 1; } #ifdef PAWIN_USE_WDMKS_DEVICE_INFO winMmeDeviceInfo->deviceOutputChannelCountIsKnown = QueryWaveOutKSFilterMaxChannels( winMmeOutputDeviceId, &deviceInfo->maxOutputChannels ); #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ winMmeDeviceInfo->dwFormats = woc.dwFormats; DetectDefaultSampleRate( winMmeDeviceInfo, winMmeOutputDeviceId, QueryOutputWaveFormatEx, deviceInfo->maxOutputChannels ); *success = 1; error: return result; } static void GetDefaultLatencies( PaTime *defaultLowLatency, PaTime *defaultHighLatency ) { OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof( osvi ); GetVersionEx( &osvi ); /* Check for NT */ if( (osvi.dwMajorVersion == 4) && (osvi.dwPlatformId == 2) ) { *defaultLowLatency = PA_MME_WIN_NT_DEFAULT_LATENCY_; } else if(osvi.dwMajorVersion >= 5) { *defaultLowLatency = PA_MME_WIN_WDM_DEFAULT_LATENCY_; } else { *defaultLowLatency = PA_MME_WIN_9X_DEFAULT_LATENCY_; } *defaultHighLatency = *defaultLowLatency * 2; } PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) { PaError result = paNoError; int i; PaWinMmeHostApiRepresentation *winMmeHostApi; int inputDeviceCount, outputDeviceCount, maximumPossibleDeviceCount; PaWinMmeDeviceInfo *deviceInfoArray; int deviceInfoInitializationSucceeded; PaTime defaultLowLatency, defaultHighLatency; DWORD waveInPreferredDevice, waveOutPreferredDevice; DWORD preferredDeviceStatusFlags; winMmeHostApi = (PaWinMmeHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaWinMmeHostApiRepresentation) ); if( !winMmeHostApi ) { result = paInsufficientMemory; goto error; } winMmeHostApi->allocations = PaUtil_CreateAllocationGroup(); if( !winMmeHostApi->allocations ) { result = paInsufficientMemory; goto error; } *hostApi = &winMmeHostApi->inheritedHostApiRep; (*hostApi)->info.structVersion = 1; (*hostApi)->info.type = paMME; (*hostApi)->info.name = "MME"; /* initialise device counts and default devices under the assumption that there are no devices. These values are incremented below if and when devices are successfully initialized. */ (*hostApi)->info.deviceCount = 0; (*hostApi)->info.defaultInputDevice = paNoDevice; (*hostApi)->info.defaultOutputDevice = paNoDevice; winMmeHostApi->inputDeviceCount = 0; winMmeHostApi->outputDeviceCount = 0; #if !defined(DRVM_MAPPER_PREFERRED_GET) /* DRVM_MAPPER_PREFERRED_GET is defined in mmddk.h but we avoid a dependency on the DDK by defining it here */ #define DRVM_MAPPER_PREFERRED_GET (0x2000+21) #endif /* the following calls assume that if wave*Message fails the preferred device parameter won't be modified */ preferredDeviceStatusFlags = 0; waveInPreferredDevice = -1; waveInMessage( (HWAVEIN)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD)&waveInPreferredDevice, (DWORD)&preferredDeviceStatusFlags ); preferredDeviceStatusFlags = 0; waveOutPreferredDevice = -1; waveOutMessage( (HWAVEOUT)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD)&waveOutPreferredDevice, (DWORD)&preferredDeviceStatusFlags ); maximumPossibleDeviceCount = 0; inputDeviceCount = waveInGetNumDevs(); if( inputDeviceCount > 0 ) maximumPossibleDeviceCount += inputDeviceCount + 1; /* assume there is a WAVE_MAPPER */ outputDeviceCount = waveOutGetNumDevs(); if( outputDeviceCount > 0 ) maximumPossibleDeviceCount += outputDeviceCount + 1; /* assume there is a WAVE_MAPPER */ if( maximumPossibleDeviceCount > 0 ){ (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( winMmeHostApi->allocations, sizeof(PaDeviceInfo*) * maximumPossibleDeviceCount ); if( !(*hostApi)->deviceInfos ) { result = paInsufficientMemory; goto error; } /* allocate all device info structs in a contiguous block */ deviceInfoArray = (PaWinMmeDeviceInfo*)PaUtil_GroupAllocateMemory( winMmeHostApi->allocations, sizeof(PaWinMmeDeviceInfo) * maximumPossibleDeviceCount ); if( !deviceInfoArray ) { result = paInsufficientMemory; goto error; } winMmeHostApi->winMmeDeviceIds = (UINT*)PaUtil_GroupAllocateMemory( winMmeHostApi->allocations, sizeof(int) * maximumPossibleDeviceCount ); if( !winMmeHostApi->winMmeDeviceIds ) { result = paInsufficientMemory; goto error; } GetDefaultLatencies( &defaultLowLatency, &defaultHighLatency ); if( inputDeviceCount > 0 ){ /* -1 is the WAVE_MAPPER */ for( i = -1; i < inputDeviceCount; ++i ){ UINT winMmeDeviceId = (UINT)((i==-1) ? WAVE_MAPPER : i); PaWinMmeDeviceInfo *wmmeDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ]; PaDeviceInfo *deviceInfo = &wmmeDeviceInfo->inheritedDeviceInfo; deviceInfo->structVersion = 2; deviceInfo->hostApi = hostApiIndex; deviceInfo->maxInputChannels = 0; wmmeDeviceInfo->deviceInputChannelCountIsKnown = 1; deviceInfo->maxOutputChannels = 0; wmmeDeviceInfo->deviceOutputChannelCountIsKnown = 1; deviceInfo->defaultLowInputLatency = defaultLowLatency; deviceInfo->defaultLowOutputLatency = defaultLowLatency; deviceInfo->defaultHighInputLatency = defaultHighLatency; deviceInfo->defaultHighOutputLatency = defaultHighLatency; result = InitializeInputDeviceInfo( winMmeHostApi, wmmeDeviceInfo, winMmeDeviceId, &deviceInfoInitializationSucceeded ); if( result != paNoError ) goto error; if( deviceInfoInitializationSucceeded ){ if( (*hostApi)->info.defaultInputDevice == paNoDevice ){ /* if there is currently no default device, use the first one available */ (*hostApi)->info.defaultInputDevice = (*hostApi)->info.deviceCount; }else if( winMmeDeviceId == waveInPreferredDevice ){ /* set the default device to the system preferred device */ (*hostApi)->info.defaultInputDevice = (*hostApi)->info.deviceCount; } winMmeHostApi->winMmeDeviceIds[ (*hostApi)->info.deviceCount ] = winMmeDeviceId; (*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo; winMmeHostApi->inputDeviceCount++; (*hostApi)->info.deviceCount++; } } } if( outputDeviceCount > 0 ){ /* -1 is the WAVE_MAPPER */ for( i = -1; i < outputDeviceCount; ++i ){ UINT winMmeDeviceId = (UINT)((i==-1) ? WAVE_MAPPER : i); PaWinMmeDeviceInfo *wmmeDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ]; PaDeviceInfo *deviceInfo = &wmmeDeviceInfo->inheritedDeviceInfo; deviceInfo->structVersion = 2; deviceInfo->hostApi = hostApiIndex; deviceInfo->maxInputChannels = 0; wmmeDeviceInfo->deviceInputChannelCountIsKnown = 1; deviceInfo->maxOutputChannels = 0; wmmeDeviceInfo->deviceOutputChannelCountIsKnown = 1; deviceInfo->defaultLowInputLatency = defaultLowLatency; deviceInfo->defaultLowOutputLatency = defaultLowLatency; deviceInfo->defaultHighInputLatency = defaultHighLatency; deviceInfo->defaultHighOutputLatency = defaultHighLatency; result = InitializeOutputDeviceInfo( winMmeHostApi, wmmeDeviceInfo, winMmeDeviceId, &deviceInfoInitializationSucceeded ); if( result != paNoError ) goto error; if( deviceInfoInitializationSucceeded ){ if( (*hostApi)->info.defaultOutputDevice == paNoDevice ){ /* if there is currently no default device, use the first one available */ (*hostApi)->info.defaultOutputDevice = (*hostApi)->info.deviceCount; }else if( winMmeDeviceId == waveOutPreferredDevice ){ /* set the default device to the system preferred device */ (*hostApi)->info.defaultOutputDevice = (*hostApi)->info.deviceCount; } winMmeHostApi->winMmeDeviceIds[ (*hostApi)->info.deviceCount ] = winMmeDeviceId; (*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo; winMmeHostApi->outputDeviceCount++; (*hostApi)->info.deviceCount++; } } } } InitializeDefaultDeviceIdsFromEnv( winMmeHostApi ); (*hostApi)->Terminate = Terminate; (*hostApi)->OpenStream = OpenStream; (*hostApi)->IsFormatSupported = IsFormatSupported; PaUtil_InitializeStreamInterface( &winMmeHostApi->callbackStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, GetStreamCpuLoad, PaUtil_DummyRead, PaUtil_DummyWrite, PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); PaUtil_InitializeStreamInterface( &winMmeHostApi->blockingStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, PaUtil_DummyGetCpuLoad, ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable ); return result; error: if( winMmeHostApi ) { if( winMmeHostApi->allocations ) { PaUtil_FreeAllAllocations( winMmeHostApi->allocations ); PaUtil_DestroyAllocationGroup( winMmeHostApi->allocations ); } PaUtil_FreeMemory( winMmeHostApi ); } return result; } static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) { PaWinMmeHostApiRepresentation *winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi; if( winMmeHostApi->allocations ) { PaUtil_FreeAllAllocations( winMmeHostApi->allocations ); PaUtil_DestroyAllocationGroup( winMmeHostApi->allocations ); } PaUtil_FreeMemory( winMmeHostApi ); } static PaError IsInputChannelCountSupported( PaWinMmeDeviceInfo* deviceInfo, int channelCount ) { PaError result = paNoError; if( channelCount > 0 && deviceInfo->deviceInputChannelCountIsKnown && channelCount > deviceInfo->inheritedDeviceInfo.maxInputChannels ){ result = paInvalidChannelCount; } return result; } static PaError IsOutputChannelCountSupported( PaWinMmeDeviceInfo* deviceInfo, int channelCount ) { PaError result = paNoError; if( channelCount > 0 && deviceInfo->deviceOutputChannelCountIsKnown && channelCount > deviceInfo->inheritedDeviceInfo.maxOutputChannels ){ result = paInvalidChannelCount; } return result; } static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { PaWinMmeHostApiRepresentation *winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi; PaDeviceInfo *inputDeviceInfo, *outputDeviceInfo; int inputChannelCount, outputChannelCount; int inputMultipleDeviceChannelCount, outputMultipleDeviceChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; PaWinMmeStreamInfo *inputStreamInfo, *outputStreamInfo; UINT winMmeInputDeviceId, winMmeOutputDeviceId; unsigned int i; PaError paerror; /* The calls to QueryFormatSupported below are intended to detect invalid sample rates. If we assume that the channel count and format are OK, then the only thing that could fail is the sample rate. This isn't strictly true, but I can't think of a better way to test that the sample rate is valid. */ if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; inputStreamInfo = inputParameters->hostApiSpecificStreamInfo; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( inputSampleFormat & paCustomFormat ) return paSampleFormatNotSupported; if( inputParameters->device == paUseHostApiSpecificDeviceSpecification && inputStreamInfo && (inputStreamInfo->flags & paWinMmeUseMultipleDevices) ) { inputMultipleDeviceChannelCount = 0; for( i=0; i< inputStreamInfo->deviceCount; ++i ) { inputMultipleDeviceChannelCount += inputStreamInfo->devices[i].channelCount; inputDeviceInfo = hostApi->deviceInfos[ inputStreamInfo->devices[i].device ]; /* check that input device can support inputChannelCount */ if( inputStreamInfo->devices[i].channelCount < 1 ) return paInvalidChannelCount; paerror = IsInputChannelCountSupported( (PaWinMmeDeviceInfo*)inputDeviceInfo, inputStreamInfo->devices[i].channelCount ); if( paerror != paNoError ) return paerror; /* test for valid sample rate, see comment above */ winMmeInputDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, inputStreamInfo->devices[i].device ); paerror = QueryFormatSupported( inputDeviceInfo, QueryInputWaveFormatEx, winMmeInputDeviceId, inputStreamInfo->devices[i].channelCount, sampleRate ); if( paerror != paNoError ) return paInvalidSampleRate; } if( inputMultipleDeviceChannelCount != inputChannelCount ) return paIncompatibleHostApiSpecificStreamInfo; } else { if( inputStreamInfo && (inputStreamInfo->flags & paWinMmeUseMultipleDevices) ) return paIncompatibleHostApiSpecificStreamInfo; /* paUseHostApiSpecificDeviceSpecification was not supplied as the input device */ inputDeviceInfo = hostApi->deviceInfos[ inputParameters->device ]; /* check that input device can support inputChannelCount */ paerror = IsInputChannelCountSupported( (PaWinMmeDeviceInfo*)inputDeviceInfo, inputChannelCount ); if( paerror != paNoError ) return paerror; /* test for valid sample rate, see comment above */ winMmeInputDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, inputParameters->device ); paerror = QueryFormatSupported( inputDeviceInfo, QueryInputWaveFormatEx, winMmeInputDeviceId, inputChannelCount, sampleRate ); if( paerror != paNoError ) return paInvalidSampleRate; } } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; outputStreamInfo = outputParameters->hostApiSpecificStreamInfo; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( outputSampleFormat & paCustomFormat ) return paSampleFormatNotSupported; if( outputParameters->device == paUseHostApiSpecificDeviceSpecification && outputStreamInfo && (outputStreamInfo->flags & paWinMmeUseMultipleDevices) ) { outputMultipleDeviceChannelCount = 0; for( i=0; i< outputStreamInfo->deviceCount; ++i ) { outputMultipleDeviceChannelCount += outputStreamInfo->devices[i].channelCount; outputDeviceInfo = hostApi->deviceInfos[ outputStreamInfo->devices[i].device ]; /* check that output device can support outputChannelCount */ if( outputStreamInfo->devices[i].channelCount < 1 ) return paInvalidChannelCount; paerror = IsOutputChannelCountSupported( (PaWinMmeDeviceInfo*)outputDeviceInfo, outputStreamInfo->devices[i].channelCount ); if( paerror != paNoError ) return paerror; /* test for valid sample rate, see comment above */ winMmeOutputDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, outputStreamInfo->devices[i].device ); paerror = QueryFormatSupported( outputDeviceInfo, QueryOutputWaveFormatEx, winMmeOutputDeviceId, outputStreamInfo->devices[i].channelCount, sampleRate ); if( paerror != paNoError ) return paInvalidSampleRate; } if( outputMultipleDeviceChannelCount != outputChannelCount ) return paIncompatibleHostApiSpecificStreamInfo; } else { if( outputStreamInfo && (outputStreamInfo->flags & paWinMmeUseMultipleDevices) ) return paIncompatibleHostApiSpecificStreamInfo; /* paUseHostApiSpecificDeviceSpecification was not supplied as the output device */ outputDeviceInfo = hostApi->deviceInfos[ outputParameters->device ]; /* check that output device can support outputChannelCount */ paerror = IsOutputChannelCountSupported( (PaWinMmeDeviceInfo*)outputDeviceInfo, outputChannelCount ); if( paerror != paNoError ) return paerror; /* test for valid sample rate, see comment above */ winMmeOutputDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, outputParameters->device ); paerror = QueryFormatSupported( outputDeviceInfo, QueryOutputWaveFormatEx, winMmeOutputDeviceId, outputChannelCount, sampleRate ); if( paerror != paNoError ) return paInvalidSampleRate; } } /* - if a full duplex stream is requested, check that the combination of input and output parameters is supported - check that the device supports sampleRate for mme all we can do is test that the input and output devices support the requested sample rate and number of channels. we cannot test for full duplex compatibility. */ return paFormatIsSupported; } static void SelectBufferSizeAndCount( unsigned long baseBufferSize, unsigned long requestedLatency, unsigned long baseBufferCount, unsigned long minimumBufferCount, unsigned long maximumBufferSize, unsigned long *hostBufferSize, unsigned long *hostBufferCount ) { unsigned long sizeMultiplier, bufferCount, latency; unsigned long nextLatency, nextBufferSize; int baseBufferSizeIsPowerOfTwo; sizeMultiplier = 1; bufferCount = baseBufferCount; /* count-1 below because latency is always determined by one less than the total number of buffers. */ latency = (baseBufferSize * sizeMultiplier) * (bufferCount-1); if( latency > requestedLatency ) { /* reduce number of buffers without falling below suggested latency */ nextLatency = (baseBufferSize * sizeMultiplier) * (bufferCount-2); while( bufferCount > minimumBufferCount && nextLatency >= requestedLatency ) { --bufferCount; nextLatency = (baseBufferSize * sizeMultiplier) * (bufferCount-2); } }else if( latency < requestedLatency ){ baseBufferSizeIsPowerOfTwo = (! (baseBufferSize & (baseBufferSize - 1))); if( baseBufferSizeIsPowerOfTwo ){ /* double size of buffers without exceeding requestedLatency */ nextBufferSize = (baseBufferSize * (sizeMultiplier*2)); nextLatency = nextBufferSize * (bufferCount-1); while( nextBufferSize <= maximumBufferSize && nextLatency < requestedLatency ) { sizeMultiplier *= 2; nextBufferSize = (baseBufferSize * (sizeMultiplier*2)); nextLatency = nextBufferSize * (bufferCount-1); } }else{ /* increase size of buffers upto first excess of requestedLatency */ nextBufferSize = (baseBufferSize * (sizeMultiplier+1)); nextLatency = nextBufferSize * (bufferCount-1); while( nextBufferSize <= maximumBufferSize && nextLatency < requestedLatency ) { ++sizeMultiplier; nextBufferSize = (baseBufferSize * (sizeMultiplier+1)); nextLatency = nextBufferSize * (bufferCount-1); } if( nextLatency < requestedLatency ) ++sizeMultiplier; } /* increase number of buffers until requestedLatency is reached */ latency = (baseBufferSize * sizeMultiplier) * (bufferCount-1); while( latency < requestedLatency ) { ++bufferCount; latency = (baseBufferSize * sizeMultiplier) * (bufferCount-1); } } *hostBufferSize = baseBufferSize * sizeMultiplier; *hostBufferCount = bufferCount; } static void ReselectBufferCount( unsigned long bufferSize, unsigned long requestedLatency, unsigned long baseBufferCount, unsigned long minimumBufferCount, unsigned long *hostBufferCount ) { unsigned long bufferCount, latency; unsigned long nextLatency; bufferCount = baseBufferCount; /* count-1 below because latency is always determined by one less than the total number of buffers. */ latency = bufferSize * (bufferCount-1); if( latency > requestedLatency ) { /* reduce number of buffers without falling below suggested latency */ nextLatency = bufferSize * (bufferCount-2); while( bufferCount > minimumBufferCount && nextLatency >= requestedLatency ) { --bufferCount; nextLatency = bufferSize * (bufferCount-2); } }else if( latency < requestedLatency ){ /* increase number of buffers until requestedLatency is reached */ latency = bufferSize * (bufferCount-1); while( latency < requestedLatency ) { ++bufferCount; latency = bufferSize * (bufferCount-1); } } *hostBufferCount = bufferCount; } /* CalculateBufferSettings() fills the framesPerHostInputBuffer, hostInputBufferCount, framesPerHostOutputBuffer and hostOutputBufferCount parameters based on the values of the other parameters. */ static PaError CalculateBufferSettings( unsigned long *framesPerHostInputBuffer, unsigned long *hostInputBufferCount, unsigned long *framesPerHostOutputBuffer, unsigned long *hostOutputBufferCount, int inputChannelCount, PaSampleFormat hostInputSampleFormat, PaTime suggestedInputLatency, PaWinMmeStreamInfo *inputStreamInfo, int outputChannelCount, PaSampleFormat hostOutputSampleFormat, PaTime suggestedOutputLatency, PaWinMmeStreamInfo *outputStreamInfo, double sampleRate, unsigned long framesPerBuffer ) { PaError result = paNoError; int effectiveInputChannelCount, effectiveOutputChannelCount; int hostInputFrameSize = 0; unsigned int i; if( inputChannelCount > 0 ) { int hostInputSampleSize = Pa_GetSampleSize( hostInputSampleFormat ); if( hostInputSampleSize < 0 ) { result = hostInputSampleSize; goto error; } if( inputStreamInfo && ( inputStreamInfo->flags & paWinMmeUseMultipleDevices ) ) { /* set effectiveInputChannelCount to the largest number of channels on any one device. */ effectiveInputChannelCount = 0; for( i=0; i< inputStreamInfo->deviceCount; ++i ) { if( inputStreamInfo->devices[i].channelCount > effectiveInputChannelCount ) effectiveInputChannelCount = inputStreamInfo->devices[i].channelCount; } } else { effectiveInputChannelCount = inputChannelCount; } hostInputFrameSize = hostInputSampleSize * effectiveInputChannelCount; if( inputStreamInfo && ( inputStreamInfo->flags & paWinMmeUseLowLevelLatencyParameters ) ) { if( inputStreamInfo->bufferCount <= 0 || inputStreamInfo->framesPerBuffer <= 0 ) { result = paIncompatibleHostApiSpecificStreamInfo; goto error; } *framesPerHostInputBuffer = inputStreamInfo->framesPerBuffer; *hostInputBufferCount = inputStreamInfo->bufferCount; } else { unsigned long hostBufferSizeBytes, hostBufferCount; unsigned long minimumBufferCount = (outputChannelCount > 0) ? PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_ : PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_HALF_DUPLEX_; unsigned long maximumBufferSize = (long) ((PA_MME_MAX_HOST_BUFFER_SECS_ * sampleRate) * hostInputFrameSize); if( maximumBufferSize > PA_MME_MAX_HOST_BUFFER_BYTES_ ) maximumBufferSize = PA_MME_MAX_HOST_BUFFER_BYTES_; /* compute the following in bytes, then convert back to frames */ SelectBufferSizeAndCount( ((framesPerBuffer == paFramesPerBufferUnspecified) ? PA_MME_MIN_HOST_BUFFER_FRAMES_WHEN_UNSPECIFIED_ : framesPerBuffer ) * hostInputFrameSize, /* baseBufferSize */ ((unsigned long)(suggestedInputLatency * sampleRate)) * hostInputFrameSize, /* suggestedLatency */ 4, /* baseBufferCount */ minimumBufferCount, maximumBufferSize, &hostBufferSizeBytes, &hostBufferCount ); *framesPerHostInputBuffer = hostBufferSizeBytes / hostInputFrameSize; *hostInputBufferCount = hostBufferCount; } } else { *framesPerHostInputBuffer = 0; *hostInputBufferCount = 0; } if( outputChannelCount > 0 ) { if( outputStreamInfo && ( outputStreamInfo->flags & paWinMmeUseLowLevelLatencyParameters ) ) { if( outputStreamInfo->bufferCount <= 0 || outputStreamInfo->framesPerBuffer <= 0 ) { result = paIncompatibleHostApiSpecificStreamInfo; goto error; } *framesPerHostOutputBuffer = outputStreamInfo->framesPerBuffer; *hostOutputBufferCount = outputStreamInfo->bufferCount; if( inputChannelCount > 0 ) /* full duplex */ { if( *framesPerHostInputBuffer != *framesPerHostOutputBuffer ) { if( inputStreamInfo && ( inputStreamInfo->flags & paWinMmeUseLowLevelLatencyParameters ) ) { /* a custom StreamInfo was used for specifying both input and output buffer sizes, the larger buffer size must be a multiple of the smaller buffer size */ if( *framesPerHostInputBuffer < *framesPerHostOutputBuffer ) { if( *framesPerHostOutputBuffer % *framesPerHostInputBuffer != 0 ) { result = paIncompatibleHostApiSpecificStreamInfo; goto error; } } else { assert( *framesPerHostInputBuffer > *framesPerHostOutputBuffer ); if( *framesPerHostInputBuffer % *framesPerHostOutputBuffer != 0 ) { result = paIncompatibleHostApiSpecificStreamInfo; goto error; } } } else { /* a custom StreamInfo was not used for specifying the input buffer size, so use the output buffer size, and approximately the same latency. */ *framesPerHostInputBuffer = *framesPerHostOutputBuffer; *hostInputBufferCount = (((unsigned long)(suggestedInputLatency * sampleRate)) / *framesPerHostInputBuffer) + 1; if( *hostInputBufferCount < PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_ ) *hostInputBufferCount = PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_; } } } } else { unsigned long hostBufferSizeBytes, hostBufferCount; unsigned long minimumBufferCount = PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_; unsigned long maximumBufferSize; int hostOutputFrameSize; int hostOutputSampleSize; hostOutputSampleSize = Pa_GetSampleSize( hostOutputSampleFormat ); if( hostOutputSampleSize < 0 ) { result = hostOutputSampleSize; goto error; } if( outputStreamInfo && ( outputStreamInfo->flags & paWinMmeUseMultipleDevices ) ) { /* set effectiveOutputChannelCount to the largest number of channels on any one device. */ effectiveOutputChannelCount = 0; for( i=0; i< outputStreamInfo->deviceCount; ++i ) { if( outputStreamInfo->devices[i].channelCount > effectiveOutputChannelCount ) effectiveOutputChannelCount = outputStreamInfo->devices[i].channelCount; } } else { effectiveOutputChannelCount = outputChannelCount; } hostOutputFrameSize = hostOutputSampleSize * effectiveOutputChannelCount; maximumBufferSize = (long) ((PA_MME_MAX_HOST_BUFFER_SECS_ * sampleRate) * hostOutputFrameSize); if( maximumBufferSize > PA_MME_MAX_HOST_BUFFER_BYTES_ ) maximumBufferSize = PA_MME_MAX_HOST_BUFFER_BYTES_; /* compute the following in bytes, then convert back to frames */ SelectBufferSizeAndCount( ((framesPerBuffer == paFramesPerBufferUnspecified) ? PA_MME_MIN_HOST_BUFFER_FRAMES_WHEN_UNSPECIFIED_ : framesPerBuffer ) * hostOutputFrameSize, /* baseBufferSize */ ((unsigned long)(suggestedOutputLatency * sampleRate)) * hostOutputFrameSize, /* suggestedLatency */ 4, /* baseBufferCount */ minimumBufferCount, maximumBufferSize, &hostBufferSizeBytes, &hostBufferCount ); *framesPerHostOutputBuffer = hostBufferSizeBytes / hostOutputFrameSize; *hostOutputBufferCount = hostBufferCount; if( inputChannelCount > 0 ) { /* ensure that both input and output buffer sizes are the same. if they don't match at this stage, choose the smallest one and use that for input and output */ if( *framesPerHostOutputBuffer != *framesPerHostInputBuffer ) { if( framesPerHostInputBuffer < framesPerHostOutputBuffer ) { unsigned long framesPerHostBuffer = *framesPerHostInputBuffer; minimumBufferCount = PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_; ReselectBufferCount( framesPerHostBuffer * hostOutputFrameSize, /* bufferSize */ ((unsigned long)(suggestedOutputLatency * sampleRate)) * hostOutputFrameSize, /* suggestedLatency */ 4, /* baseBufferCount */ minimumBufferCount, &hostBufferCount ); *framesPerHostOutputBuffer = framesPerHostBuffer; *hostOutputBufferCount = hostBufferCount; } else { unsigned long framesPerHostBuffer = *framesPerHostOutputBuffer; minimumBufferCount = PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_; ReselectBufferCount( framesPerHostBuffer * hostInputFrameSize, /* bufferSize */ ((unsigned long)(suggestedInputLatency * sampleRate)) * hostInputFrameSize, /* suggestedLatency */ 4, /* baseBufferCount */ minimumBufferCount, &hostBufferCount ); *framesPerHostInputBuffer = framesPerHostBuffer; *hostInputBufferCount = hostBufferCount; } } } } } else { *framesPerHostOutputBuffer = 0; *hostOutputBufferCount = 0; } error: return result; } typedef struct { HANDLE bufferEvent; void *waveHandles; unsigned int deviceCount; /* unsigned int channelCount; */ WAVEHDR **waveHeaders; /* waveHeaders[device][buffer] */ unsigned int bufferCount; unsigned int currentBufferIndex; unsigned int framesPerBuffer; unsigned int framesUsedInCurrentBuffer; }PaWinMmeSingleDirectionHandlesAndBuffers; /* prototypes for functions operating on PaWinMmeSingleDirectionHandlesAndBuffers */ static void InitializeSingleDirectionHandlesAndBuffers( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers ); static PaError InitializeWaveHandles( PaWinMmeHostApiRepresentation *winMmeHostApi, PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, unsigned long bytesPerHostSample, double sampleRate, PaWinMmeDeviceAndChannelCount *devices, unsigned int deviceCount, PaWinWaveFormatChannelMask channelMask, int isInput ); static PaError TerminateWaveHandles( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, int isInput, int currentlyProcessingAnError ); static PaError InitializeWaveHeaders( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, unsigned long hostBufferCount, PaSampleFormat hostSampleFormat, unsigned long framesPerHostBuffer, PaWinMmeDeviceAndChannelCount *devices, int isInput ); static void TerminateWaveHeaders( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, int isInput ); static void InitializeSingleDirectionHandlesAndBuffers( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers ) { handlesAndBuffers->bufferEvent = 0; handlesAndBuffers->waveHandles = 0; handlesAndBuffers->deviceCount = 0; handlesAndBuffers->waveHeaders = 0; handlesAndBuffers->bufferCount = 0; } static PaError InitializeWaveHandles( PaWinMmeHostApiRepresentation *winMmeHostApi, PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, unsigned long bytesPerHostSample, double sampleRate, PaWinMmeDeviceAndChannelCount *devices, unsigned int deviceCount, PaWinWaveFormatChannelMask channelMask, int isInput ) { PaError result; MMRESULT mmresult; signed int i, j; /* for error cleanup we expect that InitializeSingleDirectionHandlesAndBuffers() has already been called to zero some fields */ result = CreateEventWithPaError( &handlesAndBuffers->bufferEvent, NULL, FALSE, FALSE, NULL ); if( result != paNoError ) goto error; if( isInput ) handlesAndBuffers->waveHandles = (void*)PaUtil_AllocateMemory( sizeof(HWAVEIN) * deviceCount ); else handlesAndBuffers->waveHandles = (void*)PaUtil_AllocateMemory( sizeof(HWAVEOUT) * deviceCount ); if( !handlesAndBuffers->waveHandles ) { result = paInsufficientMemory; goto error; } handlesAndBuffers->deviceCount = deviceCount; for( i = 0; i < (signed int)deviceCount; ++i ) { if( isInput ) ((HWAVEIN*)handlesAndBuffers->waveHandles)[i] = 0; else ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i] = 0; } for( i = 0; i < (signed int)deviceCount; ++i ) { PaWinWaveFormat waveFormat; UINT winMmeDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, devices[i].device ); /* @todo: consider providing a flag or #define to not try waveformat extensible this could just initialize j to 1 the first time round. */ for( j = 0; j < 2; ++j ) { if( j == 0 ) { /* first, attempt to open the device using WAVEFORMATEXTENSIBLE, if this fails we fall back to WAVEFORMATEX */ /* @todo at the moment we only use 16 bit sample format */ PaWin_InitializeWaveFormatExtensible( &waveFormat, devices[i].channelCount, paInt16, sampleRate, channelMask ); } else { /* retry with WAVEFORMATEX */ PaWin_InitializeWaveFormatEx( &waveFormat, devices[i].channelCount, paInt16, sampleRate ); } /* REVIEW: consider not firing an event for input when a full duplex stream is being used. this would probably depend on the neverDropInput flag. */ if( isInput ) { mmresult = waveInOpen( &((HWAVEIN*)handlesAndBuffers->waveHandles)[i], winMmeDeviceId, (WAVEFORMATEX*)&waveFormat, (DWORD_PTR)handlesAndBuffers->bufferEvent, (DWORD_PTR)0, CALLBACK_EVENT ); } else { mmresult = waveOutOpen( &((HWAVEOUT*)handlesAndBuffers->waveHandles)[i], winMmeDeviceId, (WAVEFORMATEX*)&waveFormat, (DWORD_PTR)handlesAndBuffers->bufferEvent, (DWORD_PTR)0, CALLBACK_EVENT ); } if( mmresult == MMSYSERR_NOERROR ) { break; /* success */ } else if( j == 0 ) { continue; /* try again with WAVEFORMATEX */ } else { switch( mmresult ) { case MMSYSERR_ALLOCATED: /* Specified resource is already allocated. */ result = paDeviceUnavailable; break; case MMSYSERR_NODRIVER: /* No device driver is present. */ result = paDeviceUnavailable; break; case MMSYSERR_NOMEM: /* Unable to allocate or lock memory. */ result = paInsufficientMemory; break; case MMSYSERR_BADDEVICEID: /* Specified device identifier is out of range. */ /* falls through */ case WAVERR_BADFORMAT: /* Attempted to open with an unsupported waveform-audio format. */ /* This can also occur if we try to open the device with an unsupported * number of channels. This is attempted when device*ChannelCountIsKnown is * set to 0. */ /* falls through */ default: result = paUnanticipatedHostError; if( isInput ) { PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); } else { PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); } } goto error; } } } return result; error: TerminateWaveHandles( handlesAndBuffers, isInput, 1 /* currentlyProcessingAnError */ ); return result; } static PaError TerminateWaveHandles( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, int isInput, int currentlyProcessingAnError ) { PaError result = paNoError; MMRESULT mmresult; signed int i; if( handlesAndBuffers->waveHandles ) { for( i = handlesAndBuffers->deviceCount-1; i >= 0; --i ) { if( isInput ) { if( ((HWAVEIN*)handlesAndBuffers->waveHandles)[i] ) mmresult = waveInClose( ((HWAVEIN*)handlesAndBuffers->waveHandles)[i] ); else mmresult = MMSYSERR_NOERROR; } else { if( ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i] ) mmresult = waveOutClose( ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i] ); else mmresult = MMSYSERR_NOERROR; } if( mmresult != MMSYSERR_NOERROR && !currentlyProcessingAnError ) /* don't update the error state if we're already processing an error */ { result = paUnanticipatedHostError; if( isInput ) { PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); } else { PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); } /* note that we don't break here, we try to continue closing devices */ } } PaUtil_FreeMemory( handlesAndBuffers->waveHandles ); handlesAndBuffers->waveHandles = 0; } if( handlesAndBuffers->bufferEvent ) { result = CloseHandleWithPaError( handlesAndBuffers->bufferEvent ); handlesAndBuffers->bufferEvent = 0; } return result; } static PaError InitializeWaveHeaders( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, unsigned long hostBufferCount, PaSampleFormat hostSampleFormat, unsigned long framesPerHostBuffer, PaWinMmeDeviceAndChannelCount *devices, int isInput ) { PaError result = paNoError; MMRESULT mmresult; WAVEHDR *deviceWaveHeaders; signed int i, j; /* for error cleanup we expect that InitializeSingleDirectionHandlesAndBuffers() has already been called to zero some fields */ /* allocate an array of pointers to arrays of wave headers, one array of wave headers per device */ handlesAndBuffers->waveHeaders = (WAVEHDR**)PaUtil_AllocateMemory( sizeof(WAVEHDR*) * handlesAndBuffers->deviceCount ); if( !handlesAndBuffers->waveHeaders ) { result = paInsufficientMemory; goto error; } for( i = 0; i < (signed int)handlesAndBuffers->deviceCount; ++i ) handlesAndBuffers->waveHeaders[i] = 0; handlesAndBuffers->bufferCount = hostBufferCount; for( i = 0; i < (signed int)handlesAndBuffers->deviceCount; ++i ) { int bufferBytes = Pa_GetSampleSize( hostSampleFormat ) * framesPerHostBuffer * devices[i].channelCount; if( bufferBytes < 0 ) { result = paInternalError; goto error; } /* Allocate an array of wave headers for device i */ deviceWaveHeaders = (WAVEHDR *) PaUtil_AllocateMemory( sizeof(WAVEHDR)*hostBufferCount ); if( !deviceWaveHeaders ) { result = paInsufficientMemory; goto error; } for( j=0; j < (signed int)hostBufferCount; ++j ) deviceWaveHeaders[j].lpData = 0; handlesAndBuffers->waveHeaders[i] = deviceWaveHeaders; /* Allocate a buffer for each wave header */ for( j=0; j < (signed int)hostBufferCount; ++j ) { deviceWaveHeaders[j].lpData = (char *)PaUtil_AllocateMemory( bufferBytes ); if( !deviceWaveHeaders[j].lpData ) { result = paInsufficientMemory; goto error; } deviceWaveHeaders[j].dwBufferLength = bufferBytes; deviceWaveHeaders[j].dwUser = 0xFFFFFFFF; /* indicates that *PrepareHeader() has not yet been called, for error clean up code */ if( isInput ) { mmresult = waveInPrepareHeader( ((HWAVEIN*)handlesAndBuffers->waveHandles)[i], &deviceWaveHeaders[j], sizeof(WAVEHDR) ); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); goto error; } } else /* output */ { mmresult = waveOutPrepareHeader( ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i], &deviceWaveHeaders[j], sizeof(WAVEHDR) ); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); goto error; } } deviceWaveHeaders[j].dwUser = devices[i].channelCount; } } return result; error: TerminateWaveHeaders( handlesAndBuffers, isInput ); return result; } static void TerminateWaveHeaders( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, int isInput ) { signed int i, j; WAVEHDR *deviceWaveHeaders; if( handlesAndBuffers->waveHeaders ) { for( i = handlesAndBuffers->deviceCount-1; i >= 0 ; --i ) { deviceWaveHeaders = handlesAndBuffers->waveHeaders[i]; /* wave headers for device i */ if( deviceWaveHeaders ) { for( j = handlesAndBuffers->bufferCount-1; j >= 0; --j ) { if( deviceWaveHeaders[j].lpData ) { if( deviceWaveHeaders[j].dwUser != 0xFFFFFFFF ) { if( isInput ) waveInUnprepareHeader( ((HWAVEIN*)handlesAndBuffers->waveHandles)[i], &deviceWaveHeaders[j], sizeof(WAVEHDR) ); else waveOutUnprepareHeader( ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i], &deviceWaveHeaders[j], sizeof(WAVEHDR) ); } PaUtil_FreeMemory( deviceWaveHeaders[j].lpData ); } } PaUtil_FreeMemory( deviceWaveHeaders ); } } PaUtil_FreeMemory( handlesAndBuffers->waveHeaders ); handlesAndBuffers->waveHeaders = 0; } } /* PaWinMmeStream - a stream data structure specifically for this implementation */ /* note that struct PaWinMmeStream is typedeffed to PaWinMmeStream above. */ struct PaWinMmeStream { PaUtilStreamRepresentation streamRepresentation; PaUtilCpuLoadMeasurer cpuLoadMeasurer; PaUtilBufferProcessor bufferProcessor; int primeStreamUsingCallback; PaWinMmeSingleDirectionHandlesAndBuffers input; PaWinMmeSingleDirectionHandlesAndBuffers output; /* Processing thread management -------------- */ HANDLE abortEvent; HANDLE processingThread; DWORD processingThreadId; char throttleProcessingThreadOnOverload; /* 0 -> don't throtte, non-0 -> throttle */ int processingThreadPriority; int highThreadPriority; int throttledThreadPriority; unsigned long throttledSleepMsecs; int isStopped; volatile int isActive; volatile int stopProcessing; /* stop thread once existing buffers have been returned */ volatile int abortProcessing; /* stop thread immediately */ DWORD allBuffersDurationMs; /* used to calculate timeouts */ }; /* updates deviceCount if PaWinMmeUseMultipleDevices is used */ static PaError ValidateWinMmeSpecificStreamInfo( const PaStreamParameters *streamParameters, const PaWinMmeStreamInfo *streamInfo, char *throttleProcessingThreadOnOverload, unsigned long *deviceCount ) { if( streamInfo ) { if( streamInfo->size != sizeof( PaWinMmeStreamInfo ) || streamInfo->version != 1 ) { return paIncompatibleHostApiSpecificStreamInfo; } if( streamInfo->flags & paWinMmeDontThrottleOverloadedProcessingThread ) *throttleProcessingThreadOnOverload = 0; if( streamInfo->flags & paWinMmeUseMultipleDevices ) { if( streamParameters->device != paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; *deviceCount = streamInfo->deviceCount; } } return paNoError; } static PaError RetrieveDevicesFromStreamParameters( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *streamParameters, const PaWinMmeStreamInfo *streamInfo, PaWinMmeDeviceAndChannelCount *devices, unsigned long deviceCount ) { PaError result = paNoError; unsigned int i; int totalChannelCount; PaDeviceIndex hostApiDevice; if( streamInfo && streamInfo->flags & paWinMmeUseMultipleDevices ) { totalChannelCount = 0; for( i=0; i < deviceCount; ++i ) { /* validate that the device number is within range */ result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, streamInfo->devices[i].device, hostApi ); if( result != paNoError ) return result; devices[i].device = hostApiDevice; devices[i].channelCount = streamInfo->devices[i].channelCount; totalChannelCount += devices[i].channelCount; } if( totalChannelCount != streamParameters->channelCount ) { /* channelCount must match total channels specified by multiple devices */ return paInvalidChannelCount; /* REVIEW use of this error code */ } } else { devices[0].device = streamParameters->device; devices[0].channelCount = streamParameters->channelCount; } return result; } static PaError ValidateInputChannelCounts( struct PaUtilHostApiRepresentation *hostApi, PaWinMmeDeviceAndChannelCount *devices, unsigned long deviceCount ) { unsigned int i; PaWinMmeDeviceInfo *inputDeviceInfo; PaError paerror; for( i=0; i < deviceCount; ++i ) { if( devices[i].channelCount < 1 ) return paInvalidChannelCount; inputDeviceInfo = (PaWinMmeDeviceInfo*)hostApi->deviceInfos[ devices[i].device ]; paerror = IsInputChannelCountSupported( inputDeviceInfo, devices[i].channelCount ); if( paerror != paNoError ) return paerror; } return paNoError; } static PaError ValidateOutputChannelCounts( struct PaUtilHostApiRepresentation *hostApi, PaWinMmeDeviceAndChannelCount *devices, unsigned long deviceCount ) { unsigned int i; PaWinMmeDeviceInfo *outputDeviceInfo; PaError paerror; for( i=0; i < deviceCount; ++i ) { if( devices[i].channelCount < 1 ) return paInvalidChannelCount; outputDeviceInfo = (PaWinMmeDeviceInfo*)hostApi->deviceInfos[ devices[i].device ]; paerror = IsOutputChannelCountSupported( outputDeviceInfo, devices[i].channelCount ); if( paerror != paNoError ) return paerror; } return paNoError; } /* the following macros are intended to improve the readability of the following code */ #define PA_IS_INPUT_STREAM_( stream ) ( stream ->input.waveHandles ) #define PA_IS_OUTPUT_STREAM_( stream ) ( stream ->output.waveHandles ) #define PA_IS_FULL_DUPLEX_STREAM_( stream ) ( stream ->input.waveHandles && stream ->output.waveHandles ) #define PA_IS_HALF_DUPLEX_STREAM_( stream ) ( !(stream ->input.waveHandles && stream ->output.waveHandles) ) static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ) { PaError result; PaWinMmeHostApiRepresentation *winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi; PaWinMmeStream *stream = 0; int bufferProcessorIsInitialized = 0; int streamRepresentationIsInitialized = 0; PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat; int inputChannelCount, outputChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; double suggestedInputLatency, suggestedOutputLatency; PaWinMmeStreamInfo *inputStreamInfo, *outputStreamInfo; PaWinWaveFormatChannelMask inputChannelMask, outputChannelMask; unsigned long framesPerHostInputBuffer; unsigned long hostInputBufferCount; unsigned long framesPerHostOutputBuffer; unsigned long hostOutputBufferCount; unsigned long framesPerBufferProcessorCall; PaWinMmeDeviceAndChannelCount *inputDevices = 0; /* contains all devices and channel counts as local host api ids, even when PaWinMmeUseMultipleDevices is not used */ unsigned long inputDeviceCount = 0; PaWinMmeDeviceAndChannelCount *outputDevices = 0; unsigned long outputDeviceCount = 0; /* contains all devices and channel counts as local host api ids, even when PaWinMmeUseMultipleDevices is not used */ char throttleProcessingThreadOnOverload = 1; if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; suggestedInputLatency = inputParameters->suggestedLatency; inputDeviceCount = 1; /* validate input hostApiSpecificStreamInfo */ inputStreamInfo = (PaWinMmeStreamInfo*)inputParameters->hostApiSpecificStreamInfo; result = ValidateWinMmeSpecificStreamInfo( inputParameters, inputStreamInfo, &throttleProcessingThreadOnOverload, &inputDeviceCount ); if( result != paNoError ) return result; inputDevices = (PaWinMmeDeviceAndChannelCount*)alloca( sizeof(PaWinMmeDeviceAndChannelCount) * inputDeviceCount ); if( !inputDevices ) return paInsufficientMemory; result = RetrieveDevicesFromStreamParameters( hostApi, inputParameters, inputStreamInfo, inputDevices, inputDeviceCount ); if( result != paNoError ) return result; result = ValidateInputChannelCounts( hostApi, inputDevices, inputDeviceCount ); if( result != paNoError ) return result; hostInputSampleFormat = PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, inputSampleFormat ); if( inputDeviceCount != 1 ){ /* always use direct speakers when using multi-device multichannel mode */ inputChannelMask = PAWIN_SPEAKER_DIRECTOUT; } else { if( inputStreamInfo && inputStreamInfo->flags & paWinMmeUseChannelMask ) inputChannelMask = inputStreamInfo->channelMask; else inputChannelMask = PaWin_DefaultChannelMask( inputDevices[0].channelCount ); } } else { inputChannelCount = 0; inputSampleFormat = 0; suggestedInputLatency = 0.; inputStreamInfo = 0; hostInputSampleFormat = 0; } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; suggestedOutputLatency = outputParameters->suggestedLatency; outputDeviceCount = 1; /* validate output hostApiSpecificStreamInfo */ outputStreamInfo = (PaWinMmeStreamInfo*)outputParameters->hostApiSpecificStreamInfo; result = ValidateWinMmeSpecificStreamInfo( outputParameters, outputStreamInfo, &throttleProcessingThreadOnOverload, &outputDeviceCount ); if( result != paNoError ) return result; outputDevices = (PaWinMmeDeviceAndChannelCount*)alloca( sizeof(PaWinMmeDeviceAndChannelCount) * outputDeviceCount ); if( !outputDevices ) return paInsufficientMemory; result = RetrieveDevicesFromStreamParameters( hostApi, outputParameters, outputStreamInfo, outputDevices, outputDeviceCount ); if( result != paNoError ) return result; result = ValidateOutputChannelCounts( hostApi, outputDevices, outputDeviceCount ); if( result != paNoError ) return result; hostOutputSampleFormat = PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, outputSampleFormat ); if( outputDeviceCount != 1 ){ /* always use direct speakers when using multi-device multichannel mode */ outputChannelMask = PAWIN_SPEAKER_DIRECTOUT; } else { if( outputStreamInfo && outputStreamInfo->flags & paWinMmeUseChannelMask ) outputChannelMask = outputStreamInfo->channelMask; else outputChannelMask = PaWin_DefaultChannelMask( outputDevices[0].channelCount ); } } else { outputChannelCount = 0; outputSampleFormat = 0; outputStreamInfo = 0; hostOutputSampleFormat = 0; suggestedOutputLatency = 0.; } /* IMPLEMENT ME: - alter sampleRate to a close allowable rate if possible / necessary */ /* validate platform specific flags */ if( (streamFlags & paPlatformSpecificFlags) != 0 ) return paInvalidFlag; /* unexpected platform specific flag */ result = CalculateBufferSettings( &framesPerHostInputBuffer, &hostInputBufferCount, &framesPerHostOutputBuffer, &hostOutputBufferCount, inputChannelCount, hostInputSampleFormat, suggestedInputLatency, inputStreamInfo, outputChannelCount, hostOutputSampleFormat, suggestedOutputLatency, outputStreamInfo, sampleRate, framesPerBuffer ); if( result != paNoError ) goto error; stream = (PaWinMmeStream*)PaUtil_AllocateMemory( sizeof(PaWinMmeStream) ); if( !stream ) { result = paInsufficientMemory; goto error; } InitializeSingleDirectionHandlesAndBuffers( &stream->input ); InitializeSingleDirectionHandlesAndBuffers( &stream->output ); stream->abortEvent = 0; stream->processingThread = 0; stream->throttleProcessingThreadOnOverload = throttleProcessingThreadOnOverload; PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, ( (streamCallback) ? &winMmeHostApi->callbackStreamInterface : &winMmeHostApi->blockingStreamInterface ), streamCallback, userData ); streamRepresentationIsInitialized = 1; PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate ); if( inputParameters && outputParameters ) /* full duplex */ { if( framesPerHostInputBuffer < framesPerHostOutputBuffer ) { assert( (framesPerHostOutputBuffer % framesPerHostInputBuffer) == 0 ); /* CalculateBufferSettings() should guarantee this condition */ framesPerBufferProcessorCall = framesPerHostInputBuffer; } else { assert( (framesPerHostInputBuffer % framesPerHostOutputBuffer) == 0 ); /* CalculateBufferSettings() should guarantee this condition */ framesPerBufferProcessorCall = framesPerHostOutputBuffer; } } else if( inputParameters ) { framesPerBufferProcessorCall = framesPerHostInputBuffer; } else if( outputParameters ) { framesPerBufferProcessorCall = framesPerHostOutputBuffer; } stream->input.framesPerBuffer = framesPerHostInputBuffer; stream->output.framesPerBuffer = framesPerHostOutputBuffer; result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, inputChannelCount, inputSampleFormat, hostInputSampleFormat, outputChannelCount, outputSampleFormat, hostOutputSampleFormat, sampleRate, streamFlags, framesPerBuffer, framesPerBufferProcessorCall, paUtilFixedHostBufferSize, streamCallback, userData ); if( result != paNoError ) goto error; bufferProcessorIsInitialized = 1; stream->streamRepresentation.streamInfo.inputLatency = (double)(PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor) +(framesPerHostInputBuffer * (hostInputBufferCount-1))) / sampleRate; stream->streamRepresentation.streamInfo.outputLatency = (double)(PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor) +(framesPerHostOutputBuffer * (hostOutputBufferCount-1))) / sampleRate; stream->streamRepresentation.streamInfo.sampleRate = sampleRate; stream->primeStreamUsingCallback = ( (streamFlags&paPrimeOutputBuffersUsingStreamCallback) && streamCallback ) ? 1 : 0; /* time to sleep when throttling due to >100% cpu usage. -a quater of a buffer's duration */ stream->throttledSleepMsecs = (unsigned long)(stream->bufferProcessor.framesPerHostBuffer * stream->bufferProcessor.samplePeriod * .25 * 1000); stream->isStopped = 1; stream->isActive = 0; /* for maximum compatibility with multi-device multichannel drivers, we first open all devices, then we prepare all buffers, finally we start all devices ( in StartStream() ). teardown in reverse order. */ if( inputParameters ) { result = InitializeWaveHandles( winMmeHostApi, &stream->input, stream->bufferProcessor.bytesPerHostInputSample, sampleRate, inputDevices, inputDeviceCount, inputChannelMask, 1 /* isInput */ ); if( result != paNoError ) goto error; } if( outputParameters ) { result = InitializeWaveHandles( winMmeHostApi, &stream->output, stream->bufferProcessor.bytesPerHostOutputSample, sampleRate, outputDevices, outputDeviceCount, outputChannelMask, 0 /* isInput */ ); if( result != paNoError ) goto error; } if( inputParameters ) { result = InitializeWaveHeaders( &stream->input, hostInputBufferCount, hostInputSampleFormat, framesPerHostInputBuffer, inputDevices, 1 /* isInput */ ); if( result != paNoError ) goto error; } if( outputParameters ) { result = InitializeWaveHeaders( &stream->output, hostOutputBufferCount, hostOutputSampleFormat, framesPerHostOutputBuffer, outputDevices, 0 /* not isInput */ ); if( result != paNoError ) goto error; stream->allBuffersDurationMs = (DWORD) (1000.0 * (framesPerHostOutputBuffer * stream->output.bufferCount) / sampleRate); } else { stream->allBuffersDurationMs = (DWORD) (1000.0 * (framesPerHostInputBuffer * stream->input.bufferCount) / sampleRate); } if( streamCallback ) { /* abort event is only needed for callback streams */ result = CreateEventWithPaError( &stream->abortEvent, NULL, TRUE, FALSE, NULL ); if( result != paNoError ) goto error; } *s = (PaStream*)stream; return result; error: if( stream ) { if( stream->abortEvent ) CloseHandle( stream->abortEvent ); TerminateWaveHeaders( &stream->output, 0 /* not isInput */ ); TerminateWaveHeaders( &stream->input, 1 /* isInput */ ); TerminateWaveHandles( &stream->output, 0 /* not isInput */, 1 /* currentlyProcessingAnError */ ); TerminateWaveHandles( &stream->input, 1 /* isInput */, 1 /* currentlyProcessingAnError */ ); if( bufferProcessorIsInitialized ) PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); if( streamRepresentationIsInitialized ) PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); PaUtil_FreeMemory( stream ); } return result; } /* return non-zero if all current buffers are done */ static int BuffersAreDone( WAVEHDR **waveHeaders, unsigned int deviceCount, int bufferIndex ) { unsigned int i; for( i=0; i < deviceCount; ++i ) { if( !(waveHeaders[i][ bufferIndex ].dwFlags & WHDR_DONE) ) { return 0; } } return 1; } static int CurrentInputBuffersAreDone( PaWinMmeStream *stream ) { return BuffersAreDone( stream->input.waveHeaders, stream->input.deviceCount, stream->input.currentBufferIndex ); } static int CurrentOutputBuffersAreDone( PaWinMmeStream *stream ) { return BuffersAreDone( stream->output.waveHeaders, stream->output.deviceCount, stream->output.currentBufferIndex ); } /* return non-zero if any buffers are queued */ static int NoBuffersAreQueued( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers ) { unsigned int i, j; if( handlesAndBuffers->waveHandles ) { for( i=0; i < handlesAndBuffers->bufferCount; ++i ) { for( j=0; j < handlesAndBuffers->deviceCount; ++j ) { if( !( handlesAndBuffers->waveHeaders[ j ][ i ].dwFlags & WHDR_DONE) ) { return 0; } } } } return 1; } #define PA_CIRCULAR_INCREMENT_( current, max )\ ( (((current) + 1) >= (max)) ? (0) : (current+1) ) #define PA_CIRCULAR_DECREMENT_( current, max )\ ( ((current) == 0) ? ((max)-1) : (current-1) ) static signed long GetAvailableFrames( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers ) { signed long result = 0; unsigned int i; if( BuffersAreDone( handlesAndBuffers->waveHeaders, handlesAndBuffers->deviceCount, handlesAndBuffers->currentBufferIndex ) ) { /* we could calculate the following in O(1) if we kept track of the last done buffer */ result = handlesAndBuffers->framesPerBuffer - handlesAndBuffers->framesUsedInCurrentBuffer; i = PA_CIRCULAR_INCREMENT_( handlesAndBuffers->currentBufferIndex, handlesAndBuffers->bufferCount ); while( i != handlesAndBuffers->currentBufferIndex ) { if( BuffersAreDone( handlesAndBuffers->waveHeaders, handlesAndBuffers->deviceCount, i ) ) { result += handlesAndBuffers->framesPerBuffer; i = PA_CIRCULAR_INCREMENT_( i, handlesAndBuffers->bufferCount ); } else break; } } return result; } static PaError AdvanceToNextInputBuffer( PaWinMmeStream *stream ) { PaError result = paNoError; MMRESULT mmresult; unsigned int i; for( i=0; i < stream->input.deviceCount; ++i ) { stream->input.waveHeaders[i][ stream->input.currentBufferIndex ].dwFlags &= ~WHDR_DONE; mmresult = waveInAddBuffer( ((HWAVEIN*)stream->input.waveHandles)[i], &stream->input.waveHeaders[i][ stream->input.currentBufferIndex ], sizeof(WAVEHDR) ); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); } } stream->input.currentBufferIndex = PA_CIRCULAR_INCREMENT_( stream->input.currentBufferIndex, stream->input.bufferCount ); stream->input.framesUsedInCurrentBuffer = 0; return result; } static PaError AdvanceToNextOutputBuffer( PaWinMmeStream *stream ) { PaError result = paNoError; MMRESULT mmresult; unsigned int i; for( i=0; i < stream->output.deviceCount; ++i ) { mmresult = waveOutWrite( ((HWAVEOUT*)stream->output.waveHandles)[i], &stream->output.waveHeaders[i][ stream->output.currentBufferIndex ], sizeof(WAVEHDR) ); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); } } stream->output.currentBufferIndex = PA_CIRCULAR_INCREMENT_( stream->output.currentBufferIndex, stream->output.bufferCount ); stream->output.framesUsedInCurrentBuffer = 0; return result; } /* requeue all but the most recent input with the driver. Used for catching up after a total input buffer underrun */ static PaError CatchUpInputBuffers( PaWinMmeStream *stream ) { PaError result = paNoError; unsigned int i; for( i=0; i < stream->input.bufferCount - 1; ++i ) { result = AdvanceToNextInputBuffer( stream ); if( result != paNoError ) break; } return result; } /* take the most recent output and duplicate it to all other output buffers and requeue them. Used for catching up after a total output buffer underrun. */ static PaError CatchUpOutputBuffers( PaWinMmeStream *stream ) { PaError result = paNoError; unsigned int i, j; unsigned int previousBufferIndex = PA_CIRCULAR_DECREMENT_( stream->output.currentBufferIndex, stream->output.bufferCount ); for( i=0; i < stream->output.bufferCount - 1; ++i ) { for( j=0; j < stream->output.deviceCount; ++j ) { if( stream->output.waveHeaders[j][ stream->output.currentBufferIndex ].lpData != stream->output.waveHeaders[j][ previousBufferIndex ].lpData ) { CopyMemory( stream->output.waveHeaders[j][ stream->output.currentBufferIndex ].lpData, stream->output.waveHeaders[j][ previousBufferIndex ].lpData, stream->output.waveHeaders[j][ stream->output.currentBufferIndex ].dwBufferLength ); } } result = AdvanceToNextOutputBuffer( stream ); if( result != paNoError ) break; } return result; } static DWORD WINAPI ProcessingThreadProc( void *pArg ) { PaWinMmeStream *stream = (PaWinMmeStream *)pArg; HANDLE events[3]; int eventCount = 0; DWORD result = paNoError; DWORD waitResult; DWORD timeout = (unsigned long)(stream->allBuffersDurationMs * 0.5); int hostBuffersAvailable; signed int hostInputBufferIndex, hostOutputBufferIndex; PaStreamCallbackFlags statusFlags; int callbackResult; int done = 0; unsigned int channel, i; unsigned long framesProcessed; /* prepare event array for call to WaitForMultipleObjects() */ if( stream->input.bufferEvent ) events[eventCount++] = stream->input.bufferEvent; if( stream->output.bufferEvent ) events[eventCount++] = stream->output.bufferEvent; events[eventCount++] = stream->abortEvent; statusFlags = 0; /** @todo support paInputUnderflow, paOutputOverflow and paNeverDropInput */ /* loop until something causes us to stop */ do{ /* wait for MME to signal that a buffer is available, or for the PA abort event to be signaled. When this indicates that one or more buffers are available NoBuffersAreQueued() and Current*BuffersAreDone are used below to poll for additional done buffers. NoBuffersAreQueued() will fail to identify an underrun/overflow if the driver doesn't mark all done buffers prior to signalling the event. Some drivers do this (eg RME Digi96, and others don't eg VIA PC 97 input). This isn't a huge problem, it just means that we won't always be able to detect underflow/overflow. */ waitResult = WaitForMultipleObjects( eventCount, events, FALSE /* wait all = FALSE */, timeout ); if( waitResult == WAIT_FAILED ) { result = paUnanticipatedHostError; /** @todo FIXME/REVIEW: can't return host error info from an asyncronous thread */ done = 1; } else if( waitResult == WAIT_TIMEOUT ) { /* if a timeout is encountered, continue */ } if( stream->abortProcessing ) { /* Pa_AbortStream() has been called, stop processing immediately */ done = 1; } else if( stream->stopProcessing ) { /* Pa_StopStream() has been called or the user callback returned non-zero, processing will continue until all output buffers are marked as done. The stream will stop immediately if it is input-only. */ if( PA_IS_OUTPUT_STREAM_(stream) ) { if( NoBuffersAreQueued( &stream->output ) ) done = 1; /* Will cause thread to return. */ } else { /* input only stream */ done = 1; /* Will cause thread to return. */ } } else { hostBuffersAvailable = 1; /* process all available host buffers */ do { hostInputBufferIndex = -1; hostOutputBufferIndex = -1; if( PA_IS_INPUT_STREAM_(stream) ) { if( CurrentInputBuffersAreDone( stream ) ) { if( NoBuffersAreQueued( &stream->input ) ) { /** @todo if all of the other buffers are also ready then we discard all but the most recent. This is an input buffer overflow. FIXME: these buffers should be passed to the callback in a paNeverDropInput stream. note that it is also possible for an input overflow to happen while the callback is processing a buffer. that is handled further down. */ result = CatchUpInputBuffers( stream ); if( result != paNoError ) done = 1; statusFlags |= paInputOverflow; } hostInputBufferIndex = stream->input.currentBufferIndex; } } if( PA_IS_OUTPUT_STREAM_(stream) ) { if( CurrentOutputBuffersAreDone( stream ) ) { /* ok, we have an output buffer */ if( NoBuffersAreQueued( &stream->output ) ) { /* if all of the other buffers are also ready, catch up by copying the most recently generated buffer into all but one of the output buffers. note that this catch up code only handles the case where all buffers have been played out due to this thread not having woken up at all. a more common case occurs when this thread is woken up, processes one buffer, but takes too long, and as a result all the other buffers have become un-queued. that case is handled further down. */ result = CatchUpOutputBuffers( stream ); if( result != paNoError ) done = 1; statusFlags |= paOutputUnderflow; } hostOutputBufferIndex = stream->output.currentBufferIndex; } } if( (PA_IS_FULL_DUPLEX_STREAM_(stream) && hostInputBufferIndex != -1 && hostOutputBufferIndex != -1) || (PA_IS_HALF_DUPLEX_STREAM_(stream) && ( hostInputBufferIndex != -1 || hostOutputBufferIndex != -1 ) ) ) { PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /** @todo implement inputBufferAdcTime */ if( PA_IS_OUTPUT_STREAM_(stream) ) { /* set timeInfo.currentTime and calculate timeInfo.outputBufferDacTime from the current wave out position */ MMTIME mmtime; double timeBeforeGetPosition, timeAfterGetPosition; double time; long framesInBufferRing; long writePosition; long playbackPosition; HWAVEOUT firstWaveOutDevice = ((HWAVEOUT*)stream->output.waveHandles)[0]; mmtime.wType = TIME_SAMPLES; timeBeforeGetPosition = PaUtil_GetTime(); waveOutGetPosition( firstWaveOutDevice, &mmtime, sizeof(MMTIME) ); timeAfterGetPosition = PaUtil_GetTime(); timeInfo.currentTime = timeAfterGetPosition; /* approximate time at which wave out position was measured as half way between timeBeforeGetPosition and timeAfterGetPosition */ time = timeBeforeGetPosition + (timeAfterGetPosition - timeBeforeGetPosition) * .5; framesInBufferRing = stream->output.bufferCount * stream->bufferProcessor.framesPerHostBuffer; playbackPosition = mmtime.u.sample % framesInBufferRing; writePosition = stream->output.currentBufferIndex * stream->bufferProcessor.framesPerHostBuffer + stream->output.framesUsedInCurrentBuffer; if( playbackPosition >= writePosition ){ timeInfo.outputBufferDacTime = time + ((double)( writePosition + (framesInBufferRing - playbackPosition) ) * stream->bufferProcessor.samplePeriod ); }else{ timeInfo.outputBufferDacTime = time + ((double)( writePosition - playbackPosition ) * stream->bufferProcessor.samplePeriod ); } } PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, statusFlags ); /* reset status flags once they have been passed to the buffer processor */ statusFlags = 0; if( PA_IS_INPUT_STREAM_(stream) ) { PaUtil_SetInputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ ); channel = 0; for( i=0; iinput.deviceCount; ++i ) { /* we have stored the number of channels in the buffer in dwUser */ int channelCount = (int)stream->input.waveHeaders[i][ hostInputBufferIndex ].dwUser; PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, channel, stream->input.waveHeaders[i][ hostInputBufferIndex ].lpData + stream->input.framesUsedInCurrentBuffer * channelCount * stream->bufferProcessor.bytesPerHostInputSample, channelCount ); channel += channelCount; } } if( PA_IS_OUTPUT_STREAM_(stream) ) { PaUtil_SetOutputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ ); channel = 0; for( i=0; ioutput.deviceCount; ++i ) { /* we have stored the number of channels in the buffer in dwUser */ int channelCount = (int)stream->output.waveHeaders[i][ hostOutputBufferIndex ].dwUser; PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, channel, stream->output.waveHeaders[i][ hostOutputBufferIndex ].lpData + stream->output.framesUsedInCurrentBuffer * channelCount * stream->bufferProcessor.bytesPerHostOutputSample, channelCount ); channel += channelCount; } } callbackResult = paContinue; framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult ); stream->input.framesUsedInCurrentBuffer += framesProcessed; stream->output.framesUsedInCurrentBuffer += framesProcessed; PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed ); if( callbackResult == paContinue ) { /* nothing special to do */ } else if( callbackResult == paAbort ) { stream->abortProcessing = 1; done = 1; /** @todo FIXME: should probably reset the output device immediately once the callback returns paAbort */ result = paNoError; } else { /* User callback has asked us to stop with paComplete or other non-zero value */ stream->stopProcessing = 1; /* stop once currently queued audio has finished */ result = paNoError; } if( PA_IS_INPUT_STREAM_(stream) && stream->stopProcessing == 0 && stream->abortProcessing == 0 && stream->input.framesUsedInCurrentBuffer == stream->input.framesPerBuffer ) { if( NoBuffersAreQueued( &stream->input ) ) { /** @todo need to handle PaNeverDropInput here where necessary */ result = CatchUpInputBuffers( stream ); if( result != paNoError ) done = 1; statusFlags |= paInputOverflow; } result = AdvanceToNextInputBuffer( stream ); if( result != paNoError ) done = 1; } if( PA_IS_OUTPUT_STREAM_(stream) && !stream->abortProcessing ) { if( stream->stopProcessing && stream->output.framesUsedInCurrentBuffer < stream->output.framesPerBuffer ) { /* zero remaining samples in output output buffer and flush */ stream->output.framesUsedInCurrentBuffer += PaUtil_ZeroOutput( &stream->bufferProcessor, stream->output.framesPerBuffer - stream->output.framesUsedInCurrentBuffer ); /* we send the entire buffer to the output devices, but we could just send a partial buffer, rather than zeroing the unused samples. */ } if( stream->output.framesUsedInCurrentBuffer == stream->output.framesPerBuffer ) { /* check for underflow before enquing the just-generated buffer, but recover from underflow after enquing it. This ensures that the most recent audio segment is repeated */ int outputUnderflow = NoBuffersAreQueued( &stream->output ); result = AdvanceToNextOutputBuffer( stream ); if( result != paNoError ) done = 1; if( outputUnderflow && !done && !stream->stopProcessing ) { /* Recover from underflow in the case where the underflow occured while processing the buffer we just finished */ result = CatchUpOutputBuffers( stream ); if( result != paNoError ) done = 1; statusFlags |= paOutputUnderflow; } } } if( stream->throttleProcessingThreadOnOverload != 0 ) { if( stream->stopProcessing || stream->abortProcessing ) { if( stream->processingThreadPriority != stream->highThreadPriority ) { SetThreadPriority( stream->processingThread, stream->highThreadPriority ); stream->processingThreadPriority = stream->highThreadPriority; } } else if( PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ) > 1. ) { if( stream->processingThreadPriority != stream->throttledThreadPriority ) { SetThreadPriority( stream->processingThread, stream->throttledThreadPriority ); stream->processingThreadPriority = stream->throttledThreadPriority; } /* sleep to give other processes a go */ Sleep( stream->throttledSleepMsecs ); } else { if( stream->processingThreadPriority != stream->highThreadPriority ) { SetThreadPriority( stream->processingThread, stream->highThreadPriority ); stream->processingThreadPriority = stream->highThreadPriority; } } } } else { hostBuffersAvailable = 0; } } while( hostBuffersAvailable && stream->stopProcessing == 0 && stream->abortProcessing == 0 && !done ); } } while( !done ); stream->isActive = 0; if( stream->streamRepresentation.streamFinishedCallback != 0 ) stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); PaUtil_ResetCpuLoadMeasurer( &stream->cpuLoadMeasurer ); return result; } /* When CloseStream() is called, the multi-api layer ensures that the stream has already been stopped or aborted. */ static PaError CloseStream( PaStream* s ) { PaError result; PaWinMmeStream *stream = (PaWinMmeStream*)s; result = CloseHandleWithPaError( stream->abortEvent ); if( result != paNoError ) goto error; TerminateWaveHeaders( &stream->output, 0 /* not isInput */ ); TerminateWaveHeaders( &stream->input, 1 /* isInput */ ); TerminateWaveHandles( &stream->output, 0 /* not isInput */, 0 /* not currentlyProcessingAnError */ ); TerminateWaveHandles( &stream->input, 1 /* isInput */, 0 /* not currentlyProcessingAnError */ ); PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); PaUtil_FreeMemory( stream ); error: /** @todo REVIEW: what is the best way to clean up a stream if an error is detected? */ return result; } static PaError StartStream( PaStream *s ) { PaError result; PaWinMmeStream *stream = (PaWinMmeStream*)s; MMRESULT mmresult; unsigned int i, j; int callbackResult; unsigned int channel; unsigned long framesProcessed; PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /** @todo implement this for stream priming */ PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); if( PA_IS_INPUT_STREAM_(stream) ) { for( i=0; iinput.bufferCount; ++i ) { for( j=0; jinput.deviceCount; ++j ) { stream->input.waveHeaders[j][i].dwFlags &= ~WHDR_DONE; mmresult = waveInAddBuffer( ((HWAVEIN*)stream->input.waveHandles)[j], &stream->input.waveHeaders[j][i], sizeof(WAVEHDR) ); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); goto error; } } } stream->input.currentBufferIndex = 0; stream->input.framesUsedInCurrentBuffer = 0; } if( PA_IS_OUTPUT_STREAM_(stream) ) { for( i=0; ioutput.deviceCount; ++i ) { if( (mmresult = waveOutPause( ((HWAVEOUT*)stream->output.waveHandles)[i] )) != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); goto error; } } for( i=0; ioutput.bufferCount; ++i ) { if( stream->primeStreamUsingCallback ) { stream->output.framesUsedInCurrentBuffer = 0; do{ PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, paPrimingOutput | ((stream->input.bufferCount > 0 ) ? paInputUnderflow : 0)); if( stream->input.bufferCount > 0 ) PaUtil_SetNoInput( &stream->bufferProcessor ); PaUtil_SetOutputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ ); channel = 0; for( j=0; joutput.deviceCount; ++j ) { /* we have stored the number of channels in the buffer in dwUser */ int channelCount = (int)stream->output.waveHeaders[j][i].dwUser; PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, channel, stream->output.waveHeaders[j][i].lpData + stream->output.framesUsedInCurrentBuffer * channelCount * stream->bufferProcessor.bytesPerHostOutputSample, channelCount ); /* we have stored the number of channels in the buffer in dwUser */ channel += channelCount; } callbackResult = paContinue; framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult ); stream->output.framesUsedInCurrentBuffer += framesProcessed; if( callbackResult != paContinue ) { /** @todo fix this, what do we do if callback result is non-zero during stream priming? for complete: play out primed waveHeaders as usual for abort: clean up immediately. */ } }while( stream->output.framesUsedInCurrentBuffer != stream->output.framesPerBuffer ); } else { for( j=0; joutput.deviceCount; ++j ) { ZeroMemory( stream->output.waveHeaders[j][i].lpData, stream->output.waveHeaders[j][i].dwBufferLength ); } } /* we queue all channels of a single buffer frame (accross all devices, because some multidevice multichannel drivers work better this way */ for( j=0; joutput.deviceCount; ++j ) { mmresult = waveOutWrite( ((HWAVEOUT*)stream->output.waveHandles)[j], &stream->output.waveHeaders[j][i], sizeof(WAVEHDR) ); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); goto error; } } } stream->output.currentBufferIndex = 0; stream->output.framesUsedInCurrentBuffer = 0; } stream->isStopped = 0; stream->isActive = 1; stream->stopProcessing = 0; stream->abortProcessing = 0; result = ResetEventWithPaError( stream->input.bufferEvent ); if( result != paNoError ) goto error; result = ResetEventWithPaError( stream->output.bufferEvent ); if( result != paNoError ) goto error; if( stream->streamRepresentation.streamCallback ) { /* callback stream */ result = ResetEventWithPaError( stream->abortEvent ); if( result != paNoError ) goto error; /* Create thread that waits for audio buffers to be ready for processing. */ stream->processingThread = CreateThread( 0, 0, ProcessingThreadProc, stream, 0, &stream->processingThreadId ); if( !stream->processingThread ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() ); goto error; } /** @todo could have mme specific stream parameters to allow the user to set the callback thread priorities */ stream->highThreadPriority = THREAD_PRIORITY_TIME_CRITICAL; stream->throttledThreadPriority = THREAD_PRIORITY_NORMAL; if( !SetThreadPriority( stream->processingThread, stream->highThreadPriority ) ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() ); goto error; } stream->processingThreadPriority = stream->highThreadPriority; } else { /* blocking read/write stream */ } if( PA_IS_INPUT_STREAM_(stream) ) { for( i=0; i < stream->input.deviceCount; ++i ) { mmresult = waveInStart( ((HWAVEIN*)stream->input.waveHandles)[i] ); PA_DEBUG(("Pa_StartStream: waveInStart returned = 0x%X.\n", mmresult)); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); goto error; } } } if( PA_IS_OUTPUT_STREAM_(stream) ) { for( i=0; i < stream->output.deviceCount; ++i ) { if( (mmresult = waveOutRestart( ((HWAVEOUT*)stream->output.waveHandles)[i] )) != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); goto error; } } } return result; error: /** @todo FIXME: implement recovery as best we can This should involve rolling back to a state as-if this function had never been called */ return result; } static PaError StopStream( PaStream *s ) { PaError result = paNoError; PaWinMmeStream *stream = (PaWinMmeStream*)s; int timeout; DWORD waitResult; MMRESULT mmresult; signed int hostOutputBufferIndex; unsigned int channel, waitCount, i; /** @todo REVIEW: the error checking in this function needs review. the basic idea is to return from this function in a known state - for example there is no point avoiding calling waveInReset just because the thread times out. */ if( stream->processingThread ) { /* callback stream */ /* Tell processing thread to stop generating more data and to let current data play out. */ stream->stopProcessing = 1; /* Calculate timeOut longer than longest time it could take to return all buffers. */ timeout = (int)(stream->allBuffersDurationMs * 1.5); if( timeout < PA_MME_MIN_TIMEOUT_MSEC_ ) timeout = PA_MME_MIN_TIMEOUT_MSEC_; PA_DEBUG(("WinMME StopStream: waiting for background thread.\n")); waitResult = WaitForSingleObject( stream->processingThread, timeout ); if( waitResult == WAIT_TIMEOUT ) { /* try to abort */ stream->abortProcessing = 1; SetEvent( stream->abortEvent ); waitResult = WaitForSingleObject( stream->processingThread, timeout ); if( waitResult == WAIT_TIMEOUT ) { PA_DEBUG(("WinMME StopStream: timed out while waiting for background thread to finish.\n")); result = paTimedOut; } } CloseHandle( stream->processingThread ); stream->processingThread = NULL; } else { /* blocking read / write stream */ if( PA_IS_OUTPUT_STREAM_(stream) ) { if( stream->output.framesUsedInCurrentBuffer > 0 ) { /* there are still unqueued frames in the current buffer, so flush them */ hostOutputBufferIndex = stream->output.currentBufferIndex; PaUtil_SetOutputFrameCount( &stream->bufferProcessor, stream->output.framesPerBuffer - stream->output.framesUsedInCurrentBuffer ); channel = 0; for( i=0; ioutput.deviceCount; ++i ) { /* we have stored the number of channels in the buffer in dwUser */ int channelCount = (int)stream->output.waveHeaders[i][ hostOutputBufferIndex ].dwUser; PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, channel, stream->output.waveHeaders[i][ hostOutputBufferIndex ].lpData + stream->output.framesUsedInCurrentBuffer * channelCount * stream->bufferProcessor.bytesPerHostOutputSample, channelCount ); channel += channelCount; } PaUtil_ZeroOutput( &stream->bufferProcessor, stream->output.framesPerBuffer - stream->output.framesUsedInCurrentBuffer ); /* we send the entire buffer to the output devices, but we could just send a partial buffer, rather than zeroing the unused samples. */ AdvanceToNextOutputBuffer( stream ); } timeout = (stream->allBuffersDurationMs / stream->output.bufferCount) + 1; if( timeout < PA_MME_MIN_TIMEOUT_MSEC_ ) timeout = PA_MME_MIN_TIMEOUT_MSEC_; waitCount = 0; while( !NoBuffersAreQueued( &stream->output ) && waitCount <= stream->output.bufferCount ) { /* wait for MME to signal that a buffer is available */ waitResult = WaitForSingleObject( stream->output.bufferEvent, timeout ); if( waitResult == WAIT_FAILED ) { break; } else if( waitResult == WAIT_TIMEOUT ) { /* keep waiting */ } ++waitCount; } } } if( PA_IS_OUTPUT_STREAM_(stream) ) { for( i =0; i < stream->output.deviceCount; ++i ) { mmresult = waveOutReset( ((HWAVEOUT*)stream->output.waveHandles)[i] ); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); } } } if( PA_IS_INPUT_STREAM_(stream) ) { for( i=0; i < stream->input.deviceCount; ++i ) { mmresult = waveInReset( ((HWAVEIN*)stream->input.waveHandles)[i] ); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); } } } stream->isStopped = 1; stream->isActive = 0; return result; } static PaError AbortStream( PaStream *s ) { PaError result = paNoError; PaWinMmeStream *stream = (PaWinMmeStream*)s; int timeout; DWORD waitResult; MMRESULT mmresult; unsigned int i; /** @todo REVIEW: the error checking in this function needs review. the basic idea is to return from this function in a known state - for example there is no point avoiding calling waveInReset just because the thread times out. */ if( stream->processingThread ) { /* callback stream */ /* Tell processing thread to abort immediately */ stream->abortProcessing = 1; SetEvent( stream->abortEvent ); } if( PA_IS_OUTPUT_STREAM_(stream) ) { for( i =0; i < stream->output.deviceCount; ++i ) { mmresult = waveOutReset( ((HWAVEOUT*)stream->output.waveHandles)[i] ); if( mmresult != MMSYSERR_NOERROR ) { PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); return paUnanticipatedHostError; } } } if( PA_IS_INPUT_STREAM_(stream) ) { for( i=0; i < stream->input.deviceCount; ++i ) { mmresult = waveInReset( ((HWAVEIN*)stream->input.waveHandles)[i] ); if( mmresult != MMSYSERR_NOERROR ) { PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); return paUnanticipatedHostError; } } } if( stream->processingThread ) { /* callback stream */ PA_DEBUG(("WinMME AbortStream: waiting for background thread.\n")); /* Calculate timeOut longer than longest time it could take to return all buffers. */ timeout = (int)(stream->allBuffersDurationMs * 1.5); if( timeout < PA_MME_MIN_TIMEOUT_MSEC_ ) timeout = PA_MME_MIN_TIMEOUT_MSEC_; waitResult = WaitForSingleObject( stream->processingThread, timeout ); if( waitResult == WAIT_TIMEOUT ) { PA_DEBUG(("WinMME AbortStream: timed out while waiting for background thread to finish.\n")); return paTimedOut; } CloseHandle( stream->processingThread ); stream->processingThread = NULL; } stream->isStopped = 1; stream->isActive = 0; return result; } static PaError IsStreamStopped( PaStream *s ) { PaWinMmeStream *stream = (PaWinMmeStream*)s; return stream->isStopped; } static PaError IsStreamActive( PaStream *s ) { PaWinMmeStream *stream = (PaWinMmeStream*)s; return stream->isActive; } static PaTime GetStreamTime( PaStream *s ) { (void) s; /* unused parameter */ return PaUtil_GetTime(); } static double GetStreamCpuLoad( PaStream* s ) { PaWinMmeStream *stream = (PaWinMmeStream*)s; return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); } /* As separate stream interfaces are used for blocking and callback streams, the following functions can be guaranteed to only be called for blocking streams. */ static PaError ReadStream( PaStream* s, void *buffer, unsigned long frames ) { PaError result = paNoError; PaWinMmeStream *stream = (PaWinMmeStream*)s; void *userBuffer; unsigned long framesRead = 0; unsigned long framesProcessed; signed int hostInputBufferIndex; DWORD waitResult; DWORD timeout = (unsigned long)(stream->allBuffersDurationMs * 0.5); unsigned int channel, i; if( PA_IS_INPUT_STREAM_(stream) ) { /* make a local copy of the user buffer pointer(s). this is necessary because PaUtil_CopyInput() advances these pointers every time it is called. */ if( stream->bufferProcessor.userInputIsInterleaved ) { userBuffer = buffer; } else { userBuffer = alloca( sizeof(void*) * stream->bufferProcessor.inputChannelCount ); if( !userBuffer ) return paInsufficientMemory; for( i = 0; ibufferProcessor.inputChannelCount; ++i ) ((void**)userBuffer)[i] = ((void**)buffer)[i]; } do{ if( CurrentInputBuffersAreDone( stream ) ) { if( NoBuffersAreQueued( &stream->input ) ) { /** @todo REVIEW: consider what to do if the input overflows. do we requeue all of the buffers? should we be running a thread to make sure they are always queued? */ result = paInputOverflowed; } hostInputBufferIndex = stream->input.currentBufferIndex; PaUtil_SetInputFrameCount( &stream->bufferProcessor, stream->input.framesPerBuffer - stream->input.framesUsedInCurrentBuffer ); channel = 0; for( i=0; iinput.deviceCount; ++i ) { /* we have stored the number of channels in the buffer in dwUser */ int channelCount = (int)stream->input.waveHeaders[i][ hostInputBufferIndex ].dwUser; PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, channel, stream->input.waveHeaders[i][ hostInputBufferIndex ].lpData + stream->input.framesUsedInCurrentBuffer * channelCount * stream->bufferProcessor.bytesPerHostInputSample, channelCount ); channel += channelCount; } framesProcessed = PaUtil_CopyInput( &stream->bufferProcessor, &userBuffer, frames - framesRead ); stream->input.framesUsedInCurrentBuffer += framesProcessed; if( stream->input.framesUsedInCurrentBuffer == stream->input.framesPerBuffer ) { result = AdvanceToNextInputBuffer( stream ); if( result != paNoError ) break; } framesRead += framesProcessed; }else{ /* wait for MME to signal that a buffer is available */ waitResult = WaitForSingleObject( stream->input.bufferEvent, timeout ); if( waitResult == WAIT_FAILED ) { result = paUnanticipatedHostError; break; } else if( waitResult == WAIT_TIMEOUT ) { /* if a timeout is encountered, continue, perhaps we should give up eventually */ } } }while( framesRead < frames ); } else { result = paCanNotReadFromAnOutputOnlyStream; } return result; } static PaError WriteStream( PaStream* s, const void *buffer, unsigned long frames ) { PaError result = paNoError; PaWinMmeStream *stream = (PaWinMmeStream*)s; const void *userBuffer; unsigned long framesWritten = 0; unsigned long framesProcessed; signed int hostOutputBufferIndex; DWORD waitResult; DWORD timeout = (unsigned long)(stream->allBuffersDurationMs * 0.5); unsigned int channel, i; if( PA_IS_OUTPUT_STREAM_(stream) ) { /* make a local copy of the user buffer pointer(s). this is necessary because PaUtil_CopyOutput() advances these pointers every time it is called. */ if( stream->bufferProcessor.userOutputIsInterleaved ) { userBuffer = buffer; } else { userBuffer = alloca( sizeof(void*) * stream->bufferProcessor.outputChannelCount ); if( !userBuffer ) return paInsufficientMemory; for( i = 0; ibufferProcessor.outputChannelCount; ++i ) ((const void**)userBuffer)[i] = ((const void**)buffer)[i]; } do{ if( CurrentOutputBuffersAreDone( stream ) ) { if( NoBuffersAreQueued( &stream->output ) ) { /** @todo REVIEW: consider what to do if the output underflows. do we requeue all the existing buffers with zeros? should we run a separate thread to keep the buffers enqueued at all times? */ result = paOutputUnderflowed; } hostOutputBufferIndex = stream->output.currentBufferIndex; PaUtil_SetOutputFrameCount( &stream->bufferProcessor, stream->output.framesPerBuffer - stream->output.framesUsedInCurrentBuffer ); channel = 0; for( i=0; ioutput.deviceCount; ++i ) { /* we have stored the number of channels in the buffer in dwUser */ int channelCount = (int)stream->output.waveHeaders[i][ hostOutputBufferIndex ].dwUser; PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, channel, stream->output.waveHeaders[i][ hostOutputBufferIndex ].lpData + stream->output.framesUsedInCurrentBuffer * channelCount * stream->bufferProcessor.bytesPerHostOutputSample, channelCount ); channel += channelCount; } framesProcessed = PaUtil_CopyOutput( &stream->bufferProcessor, &userBuffer, frames - framesWritten ); stream->output.framesUsedInCurrentBuffer += framesProcessed; if( stream->output.framesUsedInCurrentBuffer == stream->output.framesPerBuffer ) { result = AdvanceToNextOutputBuffer( stream ); if( result != paNoError ) break; } framesWritten += framesProcessed; } else { /* wait for MME to signal that a buffer is available */ waitResult = WaitForSingleObject( stream->output.bufferEvent, timeout ); if( waitResult == WAIT_FAILED ) { result = paUnanticipatedHostError; break; } else if( waitResult == WAIT_TIMEOUT ) { /* if a timeout is encountered, continue, perhaps we should give up eventually */ } } }while( framesWritten < frames ); } else { result = paCanNotWriteToAnInputOnlyStream; } return result; } static signed long GetStreamReadAvailable( PaStream* s ) { PaWinMmeStream *stream = (PaWinMmeStream*)s; if( PA_IS_INPUT_STREAM_(stream) ) return GetAvailableFrames( &stream->input ); else return paCanNotReadFromAnOutputOnlyStream; } static signed long GetStreamWriteAvailable( PaStream* s ) { PaWinMmeStream *stream = (PaWinMmeStream*)s; if( PA_IS_OUTPUT_STREAM_(stream) ) return GetAvailableFrames( &stream->output ); else return paCanNotWriteToAnInputOnlyStream; } /* NOTE: the following functions are MME-stream specific, and are called directly by client code. We need to check for many more error conditions here because we don't have the benefit of pa_front.c's parameter checking. */ static PaError GetWinMMEStreamPointer( PaWinMmeStream **stream, PaStream *s ) { PaError result; PaUtilHostApiRepresentation *hostApi; PaWinMmeHostApiRepresentation *winMmeHostApi; result = PaUtil_ValidateStreamPointer( s ); if( result != paNoError ) return result; result = PaUtil_GetHostApiRepresentation( &hostApi, paMME ); if( result != paNoError ) return result; winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi; /* note, the following would be easier if there was a generic way of testing that a stream belongs to a specific host API */ if( PA_STREAM_REP( s )->streamInterface == &winMmeHostApi->callbackStreamInterface || PA_STREAM_REP( s )->streamInterface == &winMmeHostApi->blockingStreamInterface ) { /* s is a WinMME stream */ *stream = (PaWinMmeStream *)s; return paNoError; } else { return paIncompatibleStreamHostApi; } } int PaWinMME_GetStreamInputHandleCount( PaStream* s ) { PaWinMmeStream *stream; PaError result = GetWinMMEStreamPointer( &stream, s ); if( result == paNoError ) return (PA_IS_INPUT_STREAM_(stream)) ? stream->input.deviceCount : 0; else return result; } HWAVEIN PaWinMME_GetStreamInputHandle( PaStream* s, int handleIndex ) { PaWinMmeStream *stream; PaError result = GetWinMMEStreamPointer( &stream, s ); if( result == paNoError && PA_IS_INPUT_STREAM_(stream) && handleIndex >= 0 && (unsigned int)handleIndex < stream->input.deviceCount ) return ((HWAVEIN*)stream->input.waveHandles)[handleIndex]; else return 0; } int PaWinMME_GetStreamOutputHandleCount( PaStream* s) { PaWinMmeStream *stream; PaError result = GetWinMMEStreamPointer( &stream, s ); if( result == paNoError ) return (PA_IS_OUTPUT_STREAM_(stream)) ? stream->output.deviceCount : 0; else return result; } HWAVEOUT PaWinMME_GetStreamOutputHandle( PaStream* s, int handleIndex ) { PaWinMmeStream *stream; PaError result = GetWinMMEStreamPointer( &stream, s ); if( result == paNoError && PA_IS_OUTPUT_STREAM_(stream) && handleIndex >= 0 && (unsigned int)handleIndex < stream->output.deviceCount ) return ((HWAVEOUT*)stream->output.waveHandles)[handleIndex]; else return 0; } #endif praat-6.0.04/external/portaudio2007/pa_win_wmme.h000066400000000000000000000147221261542461700215420ustar00rootroot00000000000000#ifndef PA_WIN_WMME_H #define PA_WIN_WMME_H /* * $Id: pa_win_wmme.h 1247 2007-08-11 16:29:09Z rossb $ * PortAudio Portable Real-Time Audio Library * MME specific extensions * * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @brief WMME-specific PortAudio API extension header file. */ #include "portaudio.h" #include "pa_win_waveformat.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define paWinMmeUseLowLevelLatencyParameters (0x01) #define paWinMmeUseMultipleDevices (0x02) /* use mme specific multiple device feature */ #define paWinMmeUseChannelMask (0x04) /* By default, the mme implementation drops the processing thread's priority to THREAD_PRIORITY_NORMAL and sleeps the thread if the CPU load exceeds 100% This flag disables any priority throttling. The processing thread will always run at THREAD_PRIORITY_TIME_CRITICAL. */ #define paWinMmeDontThrottleOverloadedProcessingThread (0x08) typedef struct PaWinMmeDeviceAndChannelCount{ PaDeviceIndex device; int channelCount; }PaWinMmeDeviceAndChannelCount; typedef struct PaWinMmeStreamInfo{ unsigned long size; /**< sizeof(PaWinMmeStreamInfo) */ PaHostApiTypeId hostApiType; /**< paMME */ unsigned long version; /**< 1 */ unsigned long flags; /* low-level latency setting support These settings control the number and size of host buffers in order to set latency. They will be used instead of the generic parameters to Pa_OpenStream() if flags contains the PaWinMmeUseLowLevelLatencyParameters flag. If PaWinMmeStreamInfo structures with PaWinMmeUseLowLevelLatencyParameters are supplied for both input and output in a full duplex stream, then the input and output framesPerBuffer must be the same, or the larger of the two must be a multiple of the smaller, otherwise a paIncompatibleHostApiSpecificStreamInfo error will be returned from Pa_OpenStream(). */ unsigned long framesPerBuffer; unsigned long bufferCount; /* formerly numBuffers */ /* multiple devices per direction support If flags contains the PaWinMmeUseMultipleDevices flag, this functionality will be used, otherwise the device parameter to Pa_OpenStream() will be used instead. If devices are specified here, the corresponding device parameter to Pa_OpenStream() should be set to paUseHostApiSpecificDeviceSpecification, otherwise an paInvalidDevice error will result. The total number of channels accross all specified devices must agree with the corresponding channelCount parameter to Pa_OpenStream() otherwise a paInvalidChannelCount error will result. */ PaWinMmeDeviceAndChannelCount *devices; unsigned long deviceCount; /* support for WAVEFORMATEXTENSIBLE channel masks. If flags contains paWinMmeUseChannelMask this allows you to specify which speakers to address in a multichannel stream. Constants for channelMask are specified in pa_win_waveformat.h */ PaWinWaveFormatChannelMask channelMask; }PaWinMmeStreamInfo; /** Retrieve the number of wave in handles used by a PortAudio WinMME stream. Returns zero if the stream is output only. @return A non-negative value indicating the number of wave in handles or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. @see PaWinMME_GetStreamInputHandle */ int PaWinMME_GetStreamInputHandleCount( PaStream* stream ); /** Retrieve a wave in handle used by a PortAudio WinMME stream. @param stream The stream to query. @param handleIndex The zero based index of the wave in handle to retrieve. This should be in the range [0, PaWinMME_GetStreamInputHandleCount(stream)-1]. @return A valid wave in handle, or NULL if an error occurred. @see PaWinMME_GetStreamInputHandle */ HWAVEIN PaWinMME_GetStreamInputHandle( PaStream* stream, int handleIndex ); /** Retrieve the number of wave out handles used by a PortAudio WinMME stream. Returns zero if the stream is input only. @return A non-negative value indicating the number of wave out handles or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. @see PaWinMME_GetStreamOutputHandle */ int PaWinMME_GetStreamOutputHandleCount( PaStream* stream ); /** Retrieve a wave out handle used by a PortAudio WinMME stream. @param stream The stream to query. @param handleIndex The zero based index of the wave out handle to retrieve. This should be in the range [0, PaWinMME_GetStreamOutputHandleCount(stream)-1]. @return A valid wave out handle, or NULL if an error occurred. @see PaWinMME_GetStreamOutputHandleCount */ HWAVEOUT PaWinMME_GetStreamOutputHandle( PaStream* stream, int handleIndex ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_WIN_WMME_H */ praat-6.0.04/external/portaudio2007/portaudio.h000066400000000000000000001241241261542461700212440ustar00rootroot00000000000000#ifndef PORTAUDIO_H #define PORTAUDIO_H /* * $Id: portaudio.h 1247 2007-08-11 16:29:09Z rossb $ * PortAudio Portable Real-Time Audio Library * PortAudio API Header File * Latest version available at: http://www.portaudio.com/ * * Copyright (c) 1999-2002 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @brief The PortAudio API. */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** Retrieve the release number of the currently running PortAudio build, eg 1900. */ int Pa_GetVersion( void ); /** Retrieve a textual description of the current PortAudio build, eg "PortAudio V19-devel 13 October 2002". */ const char* Pa_GetVersionText( void ); /** Error codes returned by PortAudio functions. Note that with the exception of paNoError, all PaErrorCodes are negative. */ typedef int PaError; typedef enum PaErrorCode { paNoError = 0, paNotInitialized = -10000, paUnanticipatedHostError, paInvalidChannelCount, paInvalidSampleRate, paInvalidDevice, paInvalidFlag, paSampleFormatNotSupported, paBadIODeviceCombination, paInsufficientMemory, paBufferTooBig, paBufferTooSmall, paNullCallback, paBadStreamPtr, paTimedOut, paInternalError, paDeviceUnavailable, paIncompatibleHostApiSpecificStreamInfo, paStreamIsStopped, paStreamIsNotStopped, paInputOverflowed, paOutputUnderflowed, paHostApiNotFound, paInvalidHostApi, paCanNotReadFromACallbackStream, /**< @todo review error code name */ paCanNotWriteToACallbackStream, /**< @todo review error code name */ paCanNotReadFromAnOutputOnlyStream, /**< @todo review error code name */ paCanNotWriteToAnInputOnlyStream, /**< @todo review error code name */ paIncompatibleStreamHostApi, paBadBufferPtr } PaErrorCode; /** Translate the supplied PortAudio error code into a human readable message. */ const char *Pa_GetErrorText( PaError errorCode ); /** Library initialization function - call this before using PortAudio. This function initialises internal data structures and prepares underlying host APIs for use. With the exception of Pa_GetVersion(), Pa_GetVersionText(), and Pa_GetErrorText(), this function MUST be called before using any other PortAudio API functions. If Pa_Initialize() is called multiple times, each successful call must be matched with a corresponding call to Pa_Terminate(). Pairs of calls to Pa_Initialize()/Pa_Terminate() may overlap, and are not required to be fully nested. Note that if Pa_Initialize() returns an error code, Pa_Terminate() should NOT be called. @return paNoError if successful, otherwise an error code indicating the cause of failure. @see Pa_Terminate */ PaError Pa_Initialize( void ); /** Library termination function - call this when finished using PortAudio. This function deallocates all resources allocated by PortAudio since it was initializied by a call to Pa_Initialize(). In cases where Pa_Initialise() has been called multiple times, each call must be matched with a corresponding call to Pa_Terminate(). The final matching call to Pa_Terminate() will automatically close any PortAudio streams that are still open. Pa_Terminate() MUST be called before exiting a program which uses PortAudio. Failure to do so may result in serious resource leaks, such as audio devices not being available until the next reboot. @return paNoError if successful, otherwise an error code indicating the cause of failure. @see Pa_Initialize */ PaError Pa_Terminate( void ); /** The type used to refer to audio devices. Values of this type usually range from 0 to (Pa_GetDeviceCount()-1), and may also take on the PaNoDevice and paUseHostApiSpecificDeviceSpecification values. @see Pa_GetDeviceCount, paNoDevice, paUseHostApiSpecificDeviceSpecification */ typedef int PaDeviceIndex; /** A special PaDeviceIndex value indicating that no device is available, or should be used. @see PaDeviceIndex */ #define paNoDevice ((PaDeviceIndex)-1) /** A special PaDeviceIndex value indicating that the device(s) to be used are specified in the host api specific stream info structure. @see PaDeviceIndex */ #define paUseHostApiSpecificDeviceSpecification ((PaDeviceIndex)-2) /* Host API enumeration mechanism */ /** The type used to enumerate to host APIs at runtime. Values of this type range from 0 to (Pa_GetHostApiCount()-1). @see Pa_GetHostApiCount */ typedef int PaHostApiIndex; /** Retrieve the number of available host APIs. Even if a host API is available it may have no devices available. @return A non-negative value indicating the number of available host APIs or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. @see PaHostApiIndex */ PaHostApiIndex Pa_GetHostApiCount( void ); /** Retrieve the index of the default host API. The default host API will be the lowest common denominator host API on the current platform and is unlikely to provide the best performance. @return A non-negative value ranging from 0 to (Pa_GetHostApiCount()-1) indicating the default host API index or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. */ PaHostApiIndex Pa_GetDefaultHostApi( void ); /** Unchanging unique identifiers for each supported host API. This type is used in the PaHostApiInfo structure. The values are guaranteed to be unique and to never change, thus allowing code to be written that conditionally uses host API specific extensions. New type ids will be allocated when support for a host API reaches "public alpha" status, prior to that developers should use the paInDevelopment type id. @see PaHostApiInfo */ typedef enum PaHostApiTypeId { paInDevelopment=0, /* use while developing support for a new host API */ paDirectSound=1, paMME=2, paASIO=3, paSoundManager=4, paCoreAudio=5, paOSS=7, paALSA=8, paAL=9, paBeOS=10, paWDMKS=11, paJACK=12, paWASAPI=13, paAudioScienceHPI=14 } PaHostApiTypeId; /** A structure containing information about a particular host API. */ typedef struct PaHostApiInfo { /** this is struct version 1 */ int structVersion; /** The well known unique identifier of this host API @see PaHostApiTypeId */ PaHostApiTypeId type; /** A textual description of the host API for display on user interfaces. */ const char *name; /** The number of devices belonging to this host API. This field may be used in conjunction with Pa_HostApiDeviceIndexToDeviceIndex() to enumerate all devices for this host API. @see Pa_HostApiDeviceIndexToDeviceIndex */ int deviceCount; /** The default input device for this host API. The value will be a device index ranging from 0 to (Pa_GetDeviceCount()-1), or paNoDevice if no default input device is available. */ PaDeviceIndex defaultInputDevice; /** The default output device for this host API. The value will be a device index ranging from 0 to (Pa_GetDeviceCount()-1), or paNoDevice if no default output device is available. */ PaDeviceIndex defaultOutputDevice; } PaHostApiInfo; /** Retrieve a pointer to a structure containing information about a specific host Api. @param hostApi A valid host API index ranging from 0 to (Pa_GetHostApiCount()-1) @return A pointer to an immutable PaHostApiInfo structure describing a specific host API. If the hostApi parameter is out of range or an error is encountered, the function returns NULL. The returned structure is owned by the PortAudio implementation and must not be manipulated or freed. The pointer is only guaranteed to be valid between calls to Pa_Initialize() and Pa_Terminate(). */ const PaHostApiInfo * Pa_GetHostApiInfo( PaHostApiIndex hostApi ); /** Convert a static host API unique identifier, into a runtime host API index. @param type A unique host API identifier belonging to the PaHostApiTypeId enumeration. @return A valid PaHostApiIndex ranging from 0 to (Pa_GetHostApiCount()-1) or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. The paHostApiNotFound error code indicates that the host API specified by the type parameter is not available. @see PaHostApiTypeId */ PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type ); /** Convert a host-API-specific device index to standard PortAudio device index. This function may be used in conjunction with the deviceCount field of PaHostApiInfo to enumerate all devices for the specified host API. @param hostApi A valid host API index ranging from 0 to (Pa_GetHostApiCount()-1) @param hostApiDeviceIndex A valid per-host device index in the range 0 to (Pa_GetHostApiInfo(hostApi)->deviceCount-1) @return A non-negative PaDeviceIndex ranging from 0 to (Pa_GetDeviceCount()-1) or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. A paInvalidHostApi error code indicates that the host API index specified by the hostApi parameter is out of range. A paInvalidDevice error code indicates that the hostApiDeviceIndex parameter is out of range. @see PaHostApiInfo */ PaDeviceIndex Pa_HostApiDeviceIndexToDeviceIndex( PaHostApiIndex hostApi, int hostApiDeviceIndex ); /** Structure used to return information about a host error condition. */ typedef struct PaHostErrorInfo{ PaHostApiTypeId hostApiType; /**< the host API which returned the error code */ long errorCode; /**< the error code returned */ const char *errorText; /**< a textual description of the error if available, otherwise a zero-length string */ }PaHostErrorInfo; /** Return information about the last host error encountered. The error information returned by Pa_GetLastHostErrorInfo() will never be modified asyncronously by errors occurring in other PortAudio owned threads (such as the thread that manages the stream callback.) This function is provided as a last resort, primarily to enhance debugging by providing clients with access to all available error information. @return A pointer to an immutable structure constaining information about the host error. The values in this structure will only be valid if a PortAudio function has previously returned the paUnanticipatedHostError error code. */ const PaHostErrorInfo* Pa_GetLastHostErrorInfo( void ); /* Device enumeration and capabilities */ /** Retrieve the number of available devices. The number of available devices may be zero. @return A non-negative value indicating the number of available devices or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. */ PaDeviceIndex Pa_GetDeviceCount( void ); /** Retrieve the index of the default input device. The result can be used in the inputDevice parameter to Pa_OpenStream(). @return The default input device index for the default host API, or paNoDevice if no default input device is available or an error was encountered. */ PaDeviceIndex Pa_GetDefaultInputDevice( void ); /** Retrieve the index of the default output device. The result can be used in the outputDevice parameter to Pa_OpenStream(). @return The default output device index for the default host API, or paNoDevice if no default output device is available or an error was encountered. @note On the PC, the user can specify a default device by setting an environment variable. For example, to use device #1.
 set PA_RECOMMENDED_OUTPUT_DEVICE=1
The user should first determine the available device ids by using the supplied application "pa_devs". */ PaDeviceIndex Pa_GetDefaultOutputDevice( void ); /** The type used to represent monotonic time in seconds that can be used for syncronisation. The type is used for the outTime argument to the PaStreamCallback and as the result of Pa_GetStreamTime(). @see PaStreamCallback, Pa_GetStreamTime */ typedef double PaTime; /** A type used to specify one or more sample formats. Each value indicates a possible format for sound data passed to and from the stream callback, Pa_ReadStream and Pa_WriteStream. The standard formats paFloat32, paInt16, paInt32, paInt24, paInt8 and aUInt8 are usually implemented by all implementations. The floating point representation (paFloat32) uses +1.0 and -1.0 as the maximum and minimum respectively. paUInt8 is an unsigned 8 bit format where 128 is considered "ground" The paNonInterleaved flag indicates that a multichannel buffer is passed as a set of non-interleaved pointers. @see Pa_OpenStream, Pa_OpenDefaultStream, PaDeviceInfo @see paFloat32, paInt16, paInt32, paInt24, paInt8 @see paUInt8, paCustomFormat, paNonInterleaved */ typedef unsigned long PaSampleFormat; #define paFloat32 ((PaSampleFormat) 0x00000001) /**< @see PaSampleFormat */ #define paInt32 ((PaSampleFormat) 0x00000002) /**< @see PaSampleFormat */ #define paInt24 ((PaSampleFormat) 0x00000004) /**< Packed 24 bit format. @see PaSampleFormat */ #define paInt16 ((PaSampleFormat) 0x00000008) /**< @see PaSampleFormat */ #define paInt8 ((PaSampleFormat) 0x00000010) /**< @see PaSampleFormat */ #define paUInt8 ((PaSampleFormat) 0x00000020) /**< @see PaSampleFormat */ #define paCustomFormat ((PaSampleFormat) 0x00010000)/**< @see PaSampleFormat */ #define paNonInterleaved ((PaSampleFormat) 0x80000000) /** A structure providing information and capabilities of PortAudio devices. Devices may support input, output or both input and output. */ typedef struct PaDeviceInfo { int structVersion; /* this is struct version 2 */ const char *name; PaHostApiIndex hostApi; /* note this is a host API index, not a type id*/ int maxInputChannels; int maxOutputChannels; /* Default latency values for interactive performance. */ PaTime defaultLowInputLatency; PaTime defaultLowOutputLatency; /* Default latency values for robust non-interactive applications (eg. playing sound files). */ PaTime defaultHighInputLatency; PaTime defaultHighOutputLatency; double defaultSampleRate; } PaDeviceInfo; /** Retrieve a pointer to a PaDeviceInfo structure containing information about the specified device. @return A pointer to an immutable PaDeviceInfo structure. If the device parameter is out of range the function returns NULL. @param device A valid device index in the range 0 to (Pa_GetDeviceCount()-1) @note PortAudio manages the memory referenced by the returned pointer, the client must not manipulate or free the memory. The pointer is only guaranteed to be valid between calls to Pa_Initialize() and Pa_Terminate(). @see PaDeviceInfo, PaDeviceIndex */ const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceIndex device ); /** Parameters for one direction (input or output) of a stream. */ typedef struct PaStreamParameters { /** A valid device index in the range 0 to (Pa_GetDeviceCount()-1) specifying the device to be used or the special constant paUseHostApiSpecificDeviceSpecification which indicates that the actual device(s) to use are specified in hostApiSpecificStreamInfo. This field must not be set to paNoDevice. */ PaDeviceIndex device; /** The number of channels of sound to be delivered to the stream callback or accessed by Pa_ReadStream() or Pa_WriteStream(). It can range from 1 to the value of maxInputChannels in the PaDeviceInfo record for the device specified by the device parameter. */ int channelCount; /** The sample format of the buffer provided to the stream callback, a_ReadStream() or Pa_WriteStream(). It may be any of the formats described by the PaSampleFormat enumeration. */ PaSampleFormat sampleFormat; /** The desired latency in seconds. Where practical, implementations should configure their latency based on these parameters, otherwise they may choose the closest viable latency instead. Unless the suggested latency is greater than the absolute upper limit for the device implementations should round the suggestedLatency up to the next practial value - ie to provide an equal or higher latency than suggestedLatency wherever possibe. Actual latency values for an open stream may be retrieved using the inputLatency and outputLatency fields of the PaStreamInfo structure returned by Pa_GetStreamInfo(). @see default*Latency in PaDeviceInfo, *Latency in PaStreamInfo */ PaTime suggestedLatency; /** An optional pointer to a host api specific data structure containing additional information for device setup and/or stream processing. hostApiSpecificStreamInfo is never required for correct operation, if not used it should be set to NULL. */ void *hostApiSpecificStreamInfo; } PaStreamParameters; /** Return code for Pa_IsFormatSupported indicating success. */ #define paFormatIsSupported (0) /** Determine whether it would be possible to open a stream with the specified parameters. @param inputParameters A structure that describes the input parameters used to open a stream. The suggestedLatency field is ignored. See PaStreamParameters for a description of these parameters. inputParameters must be NULL for output-only streams. @param outputParameters A structure that describes the output parameters used to open a stream. The suggestedLatency field is ignored. See PaStreamParameters for a description of these parameters. outputParameters must be NULL for input-only streams. @param sampleRate The required sampleRate. For full-duplex streams it is the sample rate for both input and output @return Returns 0 if the format is supported, and an error code indicating why the format is not supported otherwise. The constant paFormatIsSupported is provided to compare with the return value for success. @see paFormatIsSupported, PaStreamParameters */ PaError Pa_IsFormatSupported( const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); /* Streaming types and functions */ /** A single PaStream can provide multiple channels of real-time streaming audio input and output to a client application. A stream provides access to audio hardware represented by one or more PaDevices. Depending on the underlying Host API, it may be possible to open multiple streams using the same device, however this behavior is implementation defined. Portable applications should assume that a PaDevice may be simultaneously used by at most one PaStream. Pointers to PaStream objects are passed between PortAudio functions that operate on streams. @see Pa_OpenStream, Pa_OpenDefaultStream, Pa_OpenDefaultStream, Pa_CloseStream, Pa_StartStream, Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive, Pa_GetStreamTime, Pa_GetStreamCpuLoad */ typedef void PaStream; /** Can be passed as the framesPerBuffer parameter to Pa_OpenStream() or Pa_OpenDefaultStream() to indicate that the stream callback will accept buffers of any size. */ #define paFramesPerBufferUnspecified (0) /** Flags used to control the behavior of a stream. They are passed as parameters to Pa_OpenStream or Pa_OpenDefaultStream. Multiple flags may be ORed together. @see Pa_OpenStream, Pa_OpenDefaultStream @see paNoFlag, paClipOff, paDitherOff, paNeverDropInput, paPrimeOutputBuffersUsingStreamCallback, paPlatformSpecificFlags */ typedef unsigned long PaStreamFlags; /** @see PaStreamFlags */ #define paNoFlag ((PaStreamFlags) 0) /** Disable default clipping of out of range samples. @see PaStreamFlags */ #define paClipOff ((PaStreamFlags) 0x00000001) /** Disable default dithering. @see PaStreamFlags */ #define paDitherOff ((PaStreamFlags) 0x00000002) /** Flag requests that where possible a full duplex stream will not discard overflowed input samples without calling the stream callback. This flag is only valid for full duplex callback streams and only when used in combination with the paFramesPerBufferUnspecified (0) framesPerBuffer parameter. Using this flag incorrectly results in a paInvalidFlag error being returned from Pa_OpenStream and Pa_OpenDefaultStream. @see PaStreamFlags, paFramesPerBufferUnspecified */ #define paNeverDropInput ((PaStreamFlags) 0x00000004) /** Call the stream callback to fill initial output buffers, rather than the default behavior of priming the buffers with zeros (silence). This flag has no effect for input-only and blocking read/write streams. @see PaStreamFlags */ #define paPrimeOutputBuffersUsingStreamCallback ((PaStreamFlags) 0x00000008) /** A mask specifying the platform specific bits. @see PaStreamFlags */ #define paPlatformSpecificFlags ((PaStreamFlags)0xFFFF0000) /** Timing information for the buffers passed to the stream callback. */ typedef struct PaStreamCallbackTimeInfo{ PaTime inputBufferAdcTime; PaTime currentTime; PaTime outputBufferDacTime; } PaStreamCallbackTimeInfo; /** Flag bit constants for the statusFlags to PaStreamCallback. @see paInputUnderflow, paInputOverflow, paOutputUnderflow, paOutputOverflow, paPrimingOutput */ typedef unsigned long PaStreamCallbackFlags; /** In a stream opened with paFramesPerBufferUnspecified, indicates that input data is all silence (zeros) because no real data is available. In a stream opened without paFramesPerBufferUnspecified, it indicates that one or more zero samples have been inserted into the input buffer to compensate for an input underflow. @see PaStreamCallbackFlags */ #define paInputUnderflow ((PaStreamCallbackFlags) 0x00000001) /** In a stream opened with paFramesPerBufferUnspecified, indicates that data prior to the first sample of the input buffer was discarded due to an overflow, possibly because the stream callback is using too much CPU time. Otherwise indicates that data prior to one or more samples in the input buffer was discarded. @see PaStreamCallbackFlags */ #define paInputOverflow ((PaStreamCallbackFlags) 0x00000002) /** Indicates that output data (or a gap) was inserted, possibly because the stream callback is using too much CPU time. @see PaStreamCallbackFlags */ #define paOutputUnderflow ((PaStreamCallbackFlags) 0x00000004) /** Indicates that output data will be discarded because no room is available. @see PaStreamCallbackFlags */ #define paOutputOverflow ((PaStreamCallbackFlags) 0x00000008) /** Some of all of the output data will be used to prime the stream, input data may be zero. @see PaStreamCallbackFlags */ #define paPrimingOutput ((PaStreamCallbackFlags) 0x00000010) /** Allowable return values for the PaStreamCallback. @see PaStreamCallback */ typedef enum PaStreamCallbackResult { paContinue=0, paComplete=1, paAbort=2 } PaStreamCallbackResult; /** Functions of type PaStreamCallback are implemented by PortAudio clients. They consume, process or generate audio in response to requests from an active PortAudio stream. @param input and @param output are arrays of interleaved samples, the format, packing and number of channels used by the buffers are determined by parameters to Pa_OpenStream(). @param frameCount The number of sample frames to be processed by the stream callback. @param timeInfo The time in seconds when the first sample of the input buffer was received at the audio input, the time in seconds when the first sample of the output buffer will begin being played at the audio output, and the time in seconds when the stream callback was called. See also Pa_GetStreamTime() @param statusFlags Flags indicating whether input and/or output buffers have been inserted or will be dropped to overcome underflow or overflow conditions. @param userData The value of a user supplied pointer passed to Pa_OpenStream() intended for storing synthesis data etc. @return The stream callback should return one of the values in the PaStreamCallbackResult enumeration. To ensure that the callback continues to be called, it should return paContinue (0). Either paComplete or paAbort can be returned to finish stream processing, after either of these values is returned the callback will not be called again. If paAbort is returned the stream will finish as soon as possible. If paComplete is returned, the stream will continue until all buffers generated by the callback have been played. This may be useful in applications such as soundfile players where a specific duration of output is required. However, it is not necessary to utilise this mechanism as Pa_StopStream(), Pa_AbortStream() or Pa_CloseStream() can also be used to stop the stream. The callback must always fill the entire output buffer irrespective of its return value. @see Pa_OpenStream, Pa_OpenDefaultStream @note With the exception of Pa_GetStreamCpuLoad() it is not permissable to call PortAudio API functions from within the stream callback. */ typedef int PaStreamCallback( const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData ); /** Opens a stream for either input, output or both. @param stream The address of a PaStream pointer which will receive a pointer to the newly opened stream. @param inputParameters A structure that describes the input parameters used by the opened stream. See PaStreamParameters for a description of these parameters. inputParameters must be NULL for output-only streams. @param outputParameters A structure that describes the output parameters used by the opened stream. See PaStreamParameters for a description of these parameters. outputParameters must be NULL for input-only streams. @param sampleRate The desired sampleRate. For full-duplex streams it is the sample rate for both input and output @param framesPerBuffer The number of frames passed to the stream callback function, or the preferred block granularity for a blocking read/write stream. The special value paFramesPerBufferUnspecified (0) may be used to request that the stream callback will recieve an optimal (and possibly varying) number of frames based on host requirements and the requested latency settings. Note: With some host APIs, the use of non-zero framesPerBuffer for a callback stream may introduce an additional layer of buffering which could introduce additional latency. PortAudio guarantees that the additional latency will be kept to the theoretical minimum however, it is strongly recommended that a non-zero framesPerBuffer value only be used when your algorithm requires a fixed number of frames per stream callback. @param streamFlags Flags which modify the behaviour of the streaming process. This parameter may contain a combination of flags ORed together. Some flags may only be relevant to certain buffer formats. @param streamCallback A pointer to a client supplied function that is responsible for processing and filling input and output buffers. If this parameter is NULL the stream will be opened in 'blocking read/write' mode. In blocking mode, the client can receive sample data using Pa_ReadStream and write sample data using Pa_WriteStream, the number of samples that may be read or written without blocking is returned by Pa_GetStreamReadAvailable and Pa_GetStreamWriteAvailable respectively. @param userData A client supplied pointer which is passed to the stream callback function. It could for example, contain a pointer to instance data necessary for processing the audio buffers. This parameter is ignored if streamCallback is NULL. @return Upon success Pa_OpenStream() returns paNoError and places a pointer to a valid PaStream in the stream argument. The stream is inactive (stopped). If a call to Pa_OpenStream() fails, a non-zero error code is returned (see PaError for possible error codes) and the value of stream is invalid. @see PaStreamParameters, PaStreamCallback, Pa_ReadStream, Pa_WriteStream, Pa_GetStreamReadAvailable, Pa_GetStreamWriteAvailable */ PaError Pa_OpenStream( PaStream** stream, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); /** A simplified version of Pa_OpenStream() that opens the default input and/or output devices. @param stream The address of a PaStream pointer which will receive a pointer to the newly opened stream. @param numInputChannels The number of channels of sound that will be supplied to the stream callback or returned by Pa_ReadStream. It can range from 1 to the value of maxInputChannels in the PaDeviceInfo record for the default input device. If 0 the stream is opened as an output-only stream. @param numOutputChannels The number of channels of sound to be delivered to the stream callback or passed to Pa_WriteStream. It can range from 1 to the value of maxOutputChannels in the PaDeviceInfo record for the default output dvice. If 0 the stream is opened as an output-only stream. @param sampleFormat The sample format of both the input and output buffers provided to the callback or passed to and from Pa_ReadStream and Pa_WriteStream. sampleFormat may be any of the formats described by the PaSampleFormat enumeration. @param sampleRate Same as Pa_OpenStream parameter of the same name. @param framesPerBuffer Same as Pa_OpenStream parameter of the same name. @param streamCallback Same as Pa_OpenStream parameter of the same name. @param userData Same as Pa_OpenStream parameter of the same name. @return As for Pa_OpenStream @see Pa_OpenStream, PaStreamCallback */ PaError Pa_OpenDefaultStream( PaStream** stream, int numInputChannels, int numOutputChannels, PaSampleFormat sampleFormat, double sampleRate, unsigned long framesPerBuffer, PaStreamCallback *streamCallback, void *userData ); /** Closes an audio stream. If the audio stream is active it discards any pending buffers as if Pa_AbortStream() had been called. */ PaError Pa_CloseStream( PaStream *stream ); /** Functions of type PaStreamFinishedCallback are implemented by PortAudio clients. They can be registered with a stream using the Pa_SetStreamFinishedCallback function. Once registered they are called when the stream becomes inactive (ie once a call to Pa_StopStream() will not block). A stream will become inactive after the stream callback returns non-zero, or when Pa_StopStream or Pa_AbortStream is called. For a stream providing audio output, if the stream callback returns paComplete, or Pa_StopStream is called, the stream finished callback will not be called until all generated sample data has been played. @param userData The userData parameter supplied to Pa_OpenStream() @see Pa_SetStreamFinishedCallback */ typedef void PaStreamFinishedCallback( void *userData ); /** Register a stream finished callback function which will be called when the stream becomes inactive. See the description of PaStreamFinishedCallback for further details about when the callback will be called. @param stream a pointer to a PaStream that is in the stopped state - if the stream is not stopped, the stream's finished callback will remain unchanged and an error code will be returned. @param streamFinishedCallback a pointer to a function with the same signature as PaStreamFinishedCallback, that will be called when the stream becomes inactive. Passing NULL for this parameter will un-register a previously registered stream finished callback function. @return on success returns paNoError, otherwise an error code indicating the cause of the error. @see PaStreamFinishedCallback */ PaError Pa_SetStreamFinishedCallback( PaStream *stream, PaStreamFinishedCallback* streamFinishedCallback ); /** Commences audio processing. */ PaError Pa_StartStream( PaStream *stream ); /** Terminates audio processing. It waits until all pending audio buffers have been played before it returns. */ PaError Pa_StopStream( PaStream *stream ); /** Terminates audio processing immediately without waiting for pending buffers to complete. */ PaError Pa_AbortStream( PaStream *stream ); /** Determine whether the stream is stopped. A stream is considered to be stopped prior to a successful call to Pa_StartStream and after a successful call to Pa_StopStream or Pa_AbortStream. If a stream callback returns a value other than paContinue the stream is NOT considered to be stopped. @return Returns one (1) when the stream is stopped, zero (0) when the stream is running or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive */ PaError Pa_IsStreamStopped( PaStream *stream ); /** Determine whether the stream is active. A stream is active after a successful call to Pa_StartStream(), until it becomes inactive either as a result of a call to Pa_StopStream() or Pa_AbortStream(), or as a result of a return value other than paContinue from the stream callback. In the latter case, the stream is considered inactive after the last buffer has finished playing. @return Returns one (1) when the stream is active (ie playing or recording audio), zero (0) when not playing or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamStopped */ PaError Pa_IsStreamActive( PaStream *stream ); /** A structure containing unchanging information about an open stream. @see Pa_GetStreamInfo */ typedef struct PaStreamInfo { /** this is struct version 1 */ int structVersion; /** The input latency of the stream in seconds. This value provides the most accurate estimate of input latency available to the implementation. It may differ significantly from the suggestedLatency value passed to Pa_OpenStream(). The value of this field will be zero (0.) for output-only streams. @see PaTime */ PaTime inputLatency; /** The output latency of the stream in seconds. This value provides the most accurate estimate of output latency available to the implementation. It may differ significantly from the suggestedLatency value passed to Pa_OpenStream(). The value of this field will be zero (0.) for input-only streams. @see PaTime */ PaTime outputLatency; /** The sample rate of the stream in Hertz (samples per second). In cases where the hardware sample rate is inaccurate and PortAudio is aware of it, the value of this field may be different from the sampleRate parameter passed to Pa_OpenStream(). If information about the actual hardware sample rate is not available, this field will have the same value as the sampleRate parameter passed to Pa_OpenStream(). */ double sampleRate; } PaStreamInfo; /** Retrieve a pointer to a PaStreamInfo structure containing information about the specified stream. @return A pointer to an immutable PaStreamInfo structure. If the stream parameter invalid, or an error is encountered, the function returns NULL. @param stream A pointer to an open stream previously created with Pa_OpenStream. @note PortAudio manages the memory referenced by the returned pointer, the client must not manipulate or free the memory. The pointer is only guaranteed to be valid until the specified stream is closed. @see PaStreamInfo */ const PaStreamInfo* Pa_GetStreamInfo( PaStream *stream ); /** Determine the current time for the stream according to the same clock used to generate buffer timestamps. This time may be used for syncronising other events to the audio stream, for example synchronizing audio to MIDI. @return The stream's current time in seconds, or 0 if an error occurred. @see PaTime, PaStreamCallback */ PaTime Pa_GetStreamTime( PaStream *stream ); /** Retrieve CPU usage information for the specified stream. The "CPU Load" is a fraction of total CPU time consumed by a callback stream's audio processing routines including, but not limited to the client supplied stream callback. This function does not work with blocking read/write streams. This function may be called from the stream callback function or the application. @return A floating point value, typically between 0.0 and 1.0, where 1.0 indicates that the stream callback is consuming the maximum number of CPU cycles possible to maintain real-time operation. A value of 0.5 would imply that PortAudio and the stream callback was consuming roughly 50% of the available CPU time. The return value may exceed 1.0. A value of 0.0 will always be returned for a blocking read/write stream, or if an error occurrs. */ double Pa_GetStreamCpuLoad( PaStream* stream ); /** Read samples from an input stream. The function doesn't return until the entire buffer has been filled - this may involve waiting for the operating system to supply the data. @param stream A pointer to an open stream previously created with Pa_OpenStream. @param buffer A pointer to a buffer of sample frames. The buffer contains samples in the format specified by the inputParameters->sampleFormat field used to open the stream, and the number of channels specified by inputParameters->numChannels. If non-interleaved samples were requested, buffer is a pointer to the first element of an array of non-interleaved buffer pointers, one for each channel. @param frames The number of frames to be read into buffer. This parameter is not constrained to a specific range, however high performance applications will want to match this parameter to the framesPerBuffer parameter used when opening the stream. @return On success PaNoError will be returned, or PaInputOverflowed if input data was discarded by PortAudio after the previous call and before this call. */ PaError Pa_ReadStream( PaStream* stream, void *buffer, unsigned long frames ); /** Write samples to an output stream. This function doesn't return until the entire buffer has been consumed - this may involve waiting for the operating system to consume the data. @param stream A pointer to an open stream previously created with Pa_OpenStream. @param buffer A pointer to a buffer of sample frames. The buffer contains samples in the format specified by the outputParameters->sampleFormat field used to open the stream, and the number of channels specified by outputParameters->numChannels. If non-interleaved samples were requested, buffer is a pointer to the first element of an array of non-interleaved buffer pointers, one for each channel. @param frames The number of frames to be written from buffer. This parameter is not constrained to a specific range, however high performance applications will want to match this parameter to the framesPerBuffer parameter used when opening the stream. @return On success PaNoError will be returned, or paOutputUnderflowed if additional output data was inserted after the previous call and before this call. */ PaError Pa_WriteStream( PaStream* stream, const void *buffer, unsigned long frames ); /** Retrieve the number of frames that can be read from the stream without waiting. @return Returns a non-negative value representing the maximum number of frames that can be read from the stream without blocking or busy waiting or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. */ signed long Pa_GetStreamReadAvailable( PaStream* stream ); /** Retrieve the number of frames that can be written to the stream without waiting. @return Returns a non-negative value representing the maximum number of frames that can be written to the stream without blocking or busy waiting or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. */ signed long Pa_GetStreamWriteAvailable( PaStream* stream ); /* Miscellaneous utilities */ /** Retrieve the size of a given sample format in bytes. @return The size in bytes of a single sample in the specified format, or paSampleFormatNotSupported if the format is not supported. */ PaError Pa_GetSampleSize( PaSampleFormat format ); /** Put the caller to sleep for at least 'msec' milliseconds. This function is provided only as a convenience for authors of portable code (such as the tests and examples in the PortAudio distribution.) The function may sleep longer than requested so don't rely on this for accurate musical timing. */ void Pa_Sleep( long msec ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PORTAUDIO_H */ praat-6.0.04/fon/000077500000000000000000000000001261542461700135025ustar00rootroot00000000000000praat-6.0.04/fon/AmplitudeTier.cpp000066400000000000000000000374171261542461700167720ustar00rootroot00000000000000/* AmplitudeTier.cpp * * Copyright (C) 2003-2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "AmplitudeTier.h" Thing_implement (AmplitudeTier, RealTier, 0); autoAmplitudeTier AmplitudeTier_create (double tmin, double tmax) { try { autoAmplitudeTier me = Thing_new (AmplitudeTier); RealTier_init (me.peek(), tmin, tmax); return me; } catch (MelderError) { Melder_throw (U"AmplitudeTier not created."); } } void AmplitudeTier_draw (AmplitudeTier me, Graphics g, double tmin, double tmax, double ymin, double ymax, const char32 *method, int garnish) { RealTier_draw (me, g, tmin, tmax, ymin, ymax, garnish, method, U"Sound pressure (Pa)"); } autoAmplitudeTier PointProcess_upto_AmplitudeTier (PointProcess me, double soundPressure) { try { autoAmplitudeTier thee = PointProcess_upto_RealTier (me, soundPressure, classAmplitudeTier).static_cast_move(); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to AmplitudeTier."); } } autoAmplitudeTier IntensityTier_to_AmplitudeTier (IntensityTier me) { try { autoAmplitudeTier thee = Thing_new (AmplitudeTier); my structRealTier :: v_copy (thee.peek()); for (long i = 1; i <= thy numberOfPoints(); i ++) { RealPoint point = thy point (i); point -> value = pow (10.0, point -> value / 20.0) * 2.0e-5; } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to AmplitudeTier."); } } autoIntensityTier AmplitudeTier_to_IntensityTier (AmplitudeTier me, double threshold_dB) { try { double threshold_Pa = pow (10.0, threshold_dB / 20.0) * 2.0e-5; // often zero! autoIntensityTier thee = Thing_new (IntensityTier); my structRealTier :: v_copy (thee.peek()); for (long i = 1; i <= thy numberOfPoints(); i ++) { RealPoint point = thy point (i); double absoluteValue = fabs (point -> value); point -> value = absoluteValue <= threshold_Pa ? threshold_dB : 20.0 * log10 (absoluteValue / 2.0e-5); } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to IntensityTier."); } } autoTableOfReal AmplitudeTier_downto_TableOfReal (AmplitudeTier me) { return RealTier_downto_TableOfReal (me, U"Time (s)", U"Sound pressure (Pa)"); } void Sound_AmplitudeTier_multiply_inline (Sound me, AmplitudeTier amplitude) { if (amplitude -> numberOfPoints() == 0) return; for (long isamp = 1; isamp <= my nx; isamp ++) { double t = my x1 + (isamp - 1) * my dx; double factor = RealTier_getValueAtTime (amplitude, t); for (long channel = 1; channel <= my ny; channel ++) { my z [channel] [isamp] *= factor; } } } autoSound Sound_AmplitudeTier_multiply (Sound me, AmplitudeTier amplitude) { try { autoSound thee = Data_copy (me); Sound_AmplitudeTier_multiply_inline (thee.peek(), amplitude); Vector_scale (thee.peek(), 0.9); return thee; } catch (MelderError) { Melder_throw (me, U": not multiplied by ", amplitude, U"."); } } autoAmplitudeTier PointProcess_Sound_to_AmplitudeTier_point (PointProcess me, Sound thee) { try { long imin, imax, numberOfPeaks = PointProcess_getWindowPoints (me, my xmin, my xmax, & imin, & imax); if (numberOfPeaks < 3) return nullptr; autoAmplitudeTier him = AmplitudeTier_create (my xmin, my xmax); for (long i = imin; i <= imax; i ++) { double value = Vector_getValueAtX (thee, my t [i], Vector_CHANNEL_AVERAGE, Vector_VALUE_INTERPOLATION_SINC700); if (NUMdefined (value)) RealTier_addPoint (him.peek(), my t [i], value); } return him; } catch (MelderError) { Melder_throw (me, U" & ", thee, U": not converted to AmplitudeTier."); } } /* static double Sound_getPeak (Sound me, double tmin, double tmax, long channel) { double minimum, timeOfMinimum, maximum, timeOfMaximum; double *y = my z [channel]; long i, imin, imax, sampleOfMinimum, sampleOfMaximum; if (Sampled_getWindowSamples (me, tmin, tmax, & imin, & imax) < 3) return NUMundefined; maximum = minimum = y [imin]; sampleOfMaximum = sampleOfMinimum = imin; for (i = imin + 1; i <= imax; i ++) { if (y [i] < minimum) { minimum = y [i]; sampleOfMinimum = i; } if (y [i] > maximum) { maximum = y [i]; sampleOfMaximum = i; } } timeOfMinimum = my x1 + (sampleOfMinimum - 1) * my dx; timeOfMaximum = my x1 + (sampleOfMaximum - 1) * my dx; Vector_getMinimumAndX (me, timeOfMinimum - my dx, timeOfMinimum + my dx, NUM_PEAK_INTERPOLATE_SINC70, & minimum, & timeOfMinimum); Vector_getMaximumAndX (me, timeOfMaximum - my dx, timeOfMaximum + my dx, NUM_PEAK_INTERPOLATE_SINC70, & maximum, & timeOfMaximum); return maximum - minimum; } */ static double Sound_getHannWindowedRms (Sound me, double tmid, double widthLeft, double widthRight) { double sumOfSquares = 0.0, windowSumOfSquares = 0.0; long imin, imax; if (Sampled_getWindowSamples (me, tmid - widthLeft, tmid + widthRight, & imin, & imax) < 3) return NUMundefined; for (long i = imin; i <= imax; i ++) { double t = my x1 + (i - 1) * my dx; double width = t < tmid ? widthLeft : widthRight; double windowPhase = (t - tmid) / width; /* in [-1 .. 1] */ double window = 0.5 + 0.5 * cos (NUMpi * windowPhase); /* Hann */ double windowedValue = ( my ny == 1 ? my z [1] [i] : 0.5 * (my z [1] [i] + my z [2] [i]) ) * window; sumOfSquares += windowedValue * windowedValue; windowSumOfSquares += window * window; } return sqrt (sumOfSquares / windowSumOfSquares); } autoAmplitudeTier PointProcess_Sound_to_AmplitudeTier_period (PointProcess me, Sound thee, double tmin, double tmax, double pmin, double pmax, double maximumPeriodFactor) { try { if (tmax <= tmin) tmin = my xmin, tmax = my xmax; long imin, imax; long numberOfPeaks = PointProcess_getWindowPoints (me, tmin, tmax, & imin, & imax); if (numberOfPeaks < 3) Melder_throw (U"Too few pulses between ", tmin, U" and ", tmax, U" seconds."); autoAmplitudeTier him = AmplitudeTier_create (tmin, tmax); for (long i = imin + 1; i < imax; i ++) { double p1 = my t [i] - my t [i - 1], p2 = my t [i + 1] - my t [i]; double intervalFactor = p1 > p2 ? p1 / p2 : p2 / p1; if (pmin == pmax || (p1 >= pmin && p1 <= pmax && p2 >= pmin && p2 <= pmax && intervalFactor <= maximumPeriodFactor)) { double peak = Sound_getHannWindowedRms (thee, my t [i], 0.2 * p1, 0.2 * p2); if (NUMdefined (peak) && peak > 0.0) RealTier_addPoint (him.peek(), my t [i], peak); } } return him; } catch (MelderError) { Melder_throw (me, U" & ", thee, U": not converted to AmplitudeTier."); } } double AmplitudeTier_getShimmer_local (AmplitudeTier me, double pmin, double pmax, double maximumAmplitudeFactor) { long numberOfPeaks = 0; double numerator = 0.0, denominator = 0.0; RealPoint *points = (RealPoint *) my points -> item; for (long i = 2; i <= my points -> size; i ++) { double p = points [i] -> number - points [i - 1] -> number; if (pmin == pmax || (p >= pmin && p <= pmax)) { double a1 = points [i - 1] -> value, a2 = points [i] -> value; double amplitudeFactor = a1 > a2 ? a1 / a2 : a2 / a1; if (amplitudeFactor <= maximumAmplitudeFactor) { numerator += fabs (a1 - a2); numberOfPeaks ++; } } } if (numberOfPeaks < 1) return NUMundefined; numerator /= numberOfPeaks; numberOfPeaks = 0; for (long i = 1; i < my points -> size; i ++) { denominator += points [i] -> value; numberOfPeaks ++; } denominator /= numberOfPeaks; if (denominator == 0.0) return NUMundefined; return numerator / denominator; } double AmplitudeTier_getShimmer_local_dB (AmplitudeTier me, double pmin, double pmax, double maximumAmplitudeFactor) { long numberOfPeaks = 0; double result = 0.0; RealPoint *points = (RealPoint *) my points -> item; for (long i = 2; i <= my points -> size; i ++) { double p = points [i] -> number - points [i - 1] -> number; if (pmin == pmax || (p >= pmin && p <= pmax)) { double a1 = points [i - 1] -> value, a2 = points [i] -> value; double amplitudeFactor = a1 > a2 ? a1 / a2 : a2 / a1; if (amplitudeFactor <= maximumAmplitudeFactor) { result += fabs (log10 (a1 / a2)); numberOfPeaks ++; } } } if (numberOfPeaks < 1) return NUMundefined; result /= numberOfPeaks; return 20.0 * result; } double AmplitudeTier_getShimmer_apq3 (AmplitudeTier me, double pmin, double pmax, double maximumAmplitudeFactor) { long numberOfPeaks = 0; double numerator = 0.0, denominator = 0.0; RealPoint *points = (RealPoint *) my points -> item; for (long i = 2; i <= my points -> size - 1; i ++) { double p1 = points [i] -> number - points [i - 1] -> number, p2 = points [i + 1] -> number - points [i] -> number; if (pmin == pmax || (p1 >= pmin && p1 <= pmax && p2 >= pmin && p2 <= pmax)) { double a1 = points [i - 1] -> value, a2 = points [i] -> value, a3 = points [i + 1] -> value; double f1 = a1 > a2 ? a1 / a2 : a2 / a1, f2 = a2 > a3 ? a2 / a3 : a3 / a2; if (f1 <= maximumAmplitudeFactor && f2 <= maximumAmplitudeFactor) { double threePointAverage = (a1 + a2 + a3) / 3.0; numerator += fabs (a2 - threePointAverage); numberOfPeaks ++; } } } if (numberOfPeaks < 1) return NUMundefined; numerator /= numberOfPeaks; numberOfPeaks = 0; for (long i = 1; i < my points -> size; i ++) { denominator += points [i] -> value; numberOfPeaks ++; } denominator /= numberOfPeaks; if (denominator == 0.0) return NUMundefined; return numerator / denominator; } double AmplitudeTier_getShimmer_apq5 (AmplitudeTier me, double pmin, double pmax, double maximumAmplitudeFactor) { long numberOfPeaks = 0; double numerator = 0.0, denominator = 0.0; RealPoint *points = (RealPoint *) my points -> item; for (long i = 3; i <= my points -> size - 2; i ++) { double p1 = points [i - 1] -> number - points [i - 2] -> number, p2 = points [i] -> number - points [i - 1] -> number, p3 = points [i + 1] -> number - points [i] -> number, p4 = points [i + 2] -> number - points [i + 1] -> number; if (pmin == pmax || (p1 >= pmin && p1 <= pmax && p2 >= pmin && p2 <= pmax && p3 >= pmin && p3 <= pmax && p4 >= pmin && p4 <= pmax)) { double a1 = points [i - 2] -> value, a2 = points [i - 1] -> value, a3 = points [i] -> value, a4 = points [i + 1] -> value, a5 = points [i + 2] -> value; double f1 = a1 > a2 ? a1 / a2 : a2 / a1, f2 = a2 > a3 ? a2 / a3 : a3 / a2, f3 = a3 > a4 ? a3 / a4 : a4 / a3, f4 = a4 > a5 ? a4 / a5 : a5 / a4; if (f1 <= maximumAmplitudeFactor && f2 <= maximumAmplitudeFactor && f3 <= maximumAmplitudeFactor && f4 <= maximumAmplitudeFactor) { double fivePointAverage = (a1 + a2 + a3 + a4 + a5) / 5.0; numerator += fabs (a3 - fivePointAverage); numberOfPeaks ++; } } } if (numberOfPeaks < 1) return NUMundefined; numerator /= numberOfPeaks; numberOfPeaks = 0; for (long i = 1; i < my points -> size; i ++) { denominator += points [i] -> value; numberOfPeaks ++; } denominator /= numberOfPeaks; if (denominator == 0.0) return NUMundefined; return numerator / denominator; } double AmplitudeTier_getShimmer_apq11 (AmplitudeTier me, double pmin, double pmax, double maximumAmplitudeFactor) { long numberOfPeaks = 0; double numerator = 0.0, denominator = 0.0; RealPoint *points = (RealPoint *) my points -> item; for (long i = 6; i <= my points -> size - 5; i ++) { double p1 = points [i - 4] -> number - points [i - 5] -> number, p2 = points [i - 3] -> number - points [i - 4] -> number, p3 = points [i - 2] -> number - points [i - 3] -> number, p4 = points [i - 1] -> number - points [i - 2] -> number, p5 = points [i] -> number - points [i - 1] -> number, p6 = points [i + 1] -> number - points [i] -> number, p7 = points [i + 2] -> number - points [i + 1] -> number, p8 = points [i + 3] -> number - points [i + 2] -> number, p9 = points [i + 4] -> number - points [i + 3] -> number, p10 = points [i + 5] -> number - points [i + 4] -> number; if (pmin == pmax || (p1 >= pmin && p1 <= pmax && p2 >= pmin && p2 <= pmax && p3 >= pmin && p3 <= pmax && p4 >= pmin && p4 <= pmax && p5 >= pmin && p5 <= pmax && p6 >= pmin && p6 <= pmax && p7 >= pmin && p7 <= pmax && p8 >= pmin && p8 <= pmax && p9 >= pmin && p9 <= pmax && p10 >= pmin && p10 <= pmax)) { double a1 = points [i - 5] -> value, a2 = points [i - 4] -> value, a3 = points [i - 3] -> value, a4 = points [i - 2] -> value, a5 = points [i - 1] -> value, a6 = points [i] -> value, a7 = points [i + 1] -> value, a8 = points [i + 2] -> value, a9 = points [i + 3] -> value, a10 = points [i + 4] -> value, a11 = points [i + 5] -> value; double f1 = a1 > a2 ? a1 / a2 : a2 / a1, f2 = a2 > a3 ? a2 / a3 : a3 / a2, f3 = a3 > a4 ? a3 / a4 : a4 / a3, f4 = a4 > a5 ? a4 / a5 : a5 / a4, f5 = a5 > a6 ? a5 / a6 : a6 / a5, f6 = a6 > a7 ? a6 / a7 : a7 / a6, f7 = a7 > a8 ? a7 / a8 : a8 / a7, f8 = a8 > a9 ? a8 / a9 : a9 / a8, f9 = a9 > a10 ? a9 / a10 : a10 / a9, f10 = a10 > a11 ? a10 / a11 : a11 / a10; if (f1 <= maximumAmplitudeFactor && f2 <= maximumAmplitudeFactor && f3 <= maximumAmplitudeFactor && f4 <= maximumAmplitudeFactor && f5 <= maximumAmplitudeFactor && f6 <= maximumAmplitudeFactor && f7 <= maximumAmplitudeFactor && f8 <= maximumAmplitudeFactor && f9 <= maximumAmplitudeFactor && f10 <= maximumAmplitudeFactor) { double elevenPointAverage = (a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11) / 11.0; numerator += fabs (a6 - elevenPointAverage); numberOfPeaks ++; } } } if (numberOfPeaks < 1) return NUMundefined; numerator /= numberOfPeaks; numberOfPeaks = 0; for (long i = 1; i < my points -> size; i ++) { denominator += points [i] -> value; numberOfPeaks ++; } denominator /= numberOfPeaks; if (denominator == 0.0) return NUMundefined; return numerator / denominator; } double AmplitudeTier_getShimmer_dda (AmplitudeTier me, double pmin, double pmax, double maximumAmplitudeFactor) { double apq3 = AmplitudeTier_getShimmer_apq3 (me, pmin, pmax, maximumAmplitudeFactor); return NUMdefined (apq3) ? 3.0 * apq3 : NUMundefined; } autoSound AmplitudeTier_to_Sound (AmplitudeTier me, double samplingFrequency, long interpolationDepth) { try { long sound_nt = 1 + (long) floor ((my xmax - my xmin) * samplingFrequency); // >= 1 double dt = 1.0 / samplingFrequency; double tmid = (my xmin + my xmax) / 2; double t1 = tmid - 0.5 * (sound_nt - 1) * dt; double *sound; autoSound thee = Sound_create (1, my xmin, my xmax, sound_nt, dt, t1); sound = thy z [1]; for (long it = 1; it <= my points -> size; it ++) { RealPoint point = (RealPoint) my points -> item [it]; double t = point -> number, amplitude = point -> value, angle, halfampsinangle; long mid = Sampled_xToNearestIndex (thee.peek(), t), j; long begin = mid - interpolationDepth, end = mid + interpolationDepth; if (begin < 1) begin = 1; if (end > thy nx) end = thy nx; angle = NUMpi * (Sampled_indexToX (thee.peek(), begin) - t) / thy dx; halfampsinangle = 0.5 * amplitude * sin (angle); for (j = begin; j <= end; j ++) { if (fabs (angle) < 1e-6) sound [j] += amplitude; else if (angle < 0.0) sound [j] += halfampsinangle * (1 + cos (angle / (mid - begin + 1))) / angle; else sound [j] += halfampsinangle * (1 + cos (angle / (end - mid + 1))) / angle; angle += NUMpi; halfampsinangle = - halfampsinangle; } } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Sound."); } } /* End of file AmplitudeTier.cpp */ praat-6.0.04/fon/AmplitudeTier.h000066400000000000000000000056451261542461700164350ustar00rootroot00000000000000#ifndef _AmplitudeTier_h_ #define _AmplitudeTier_h_ /* AmplitudeTier.h * * Copyright (C) 2003-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "IntensityTier.h" #include "TableOfReal.h" #include "Sound.h" /********** class AmplitudeTier **********/ Thing_define (AmplitudeTier, RealTier) { int v_domainQuantity () override { return MelderQuantity_TIME_SECONDS; } }; autoAmplitudeTier AmplitudeTier_create (double tmin, double tmax); void AmplitudeTier_draw (AmplitudeTier me, Graphics g, double tmin, double tmax, double ymin, double ymax, const char32 *method, int garnish); autoAmplitudeTier PointProcess_upto_AmplitudeTier (PointProcess me, double soundPressure); autoAmplitudeTier IntensityTier_to_AmplitudeTier (IntensityTier me); autoIntensityTier AmplitudeTier_to_IntensityTier (AmplitudeTier me, double threshold_dB); autoTableOfReal AmplitudeTier_downto_TableOfReal (AmplitudeTier me); void Sound_AmplitudeTier_multiply_inline (Sound me, AmplitudeTier intensity); autoSound Sound_AmplitudeTier_multiply (Sound me, AmplitudeTier intensity); autoAmplitudeTier PointProcess_Sound_to_AmplitudeTier_point (PointProcess me, Sound thee); autoAmplitudeTier PointProcess_Sound_to_AmplitudeTier_period (PointProcess me, Sound thee, double tmin, double tmax, double shortestPeriod, double longestPeriod, double maximumPeriodFactor); double AmplitudeTier_getShimmer_local (AmplitudeTier me, double shortestPeriod, double longestPeriod, double maximumAmplitudeFactor); double AmplitudeTier_getShimmer_local_dB (AmplitudeTier me, double shortestPeriod, double longestPeriod, double maximumAmplitudeFactor); double AmplitudeTier_getShimmer_apq3 (AmplitudeTier me, double shortestPeriod, double longestPeriod, double maximumAmplitudeFactor); double AmplitudeTier_getShimmer_apq5 (AmplitudeTier me, double shortestPeriod, double longestPeriod, double maximumAmplitudeFactor); double AmplitudeTier_getShimmer_apq11 (AmplitudeTier me, double shortestPeriod, double longestPeriod, double maximumAmplitudeFactor); double AmplitudeTier_getShimmer_dda (AmplitudeTier me, double shortestPeriod, double longestPeriod, double maximumAmplitudeFactor); autoSound AmplitudeTier_to_Sound (AmplitudeTier me, double samplingFrequency, long interpolationDepth); /* End of file AmplitudeTier.h */ #endif praat-6.0.04/fon/AmplitudeTierEditor.cpp000066400000000000000000000036251261542461700201330ustar00rootroot00000000000000/* AmplitudeTierEditor.cpp * * Copyright (C) 2003-2011,2012,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "AmplitudeTierEditor.h" #include "EditorM.h" Thing_implement (AmplitudeTierEditor, RealTierEditor, 0); static void menu_cb_AmplitudeTierHelp (EDITOR_ARGS) { EDITOR_IAM (AmplitudeTierEditor); Melder_help (U"AmplitudeTier"); } void structAmplitudeTierEditor :: v_createHelpMenuItems (EditorMenu menu) { AmplitudeTierEditor_Parent :: v_createHelpMenuItems (menu); EditorMenu_addCommand (menu, U"AmplitudeTier help", 0, menu_cb_AmplitudeTierHelp); } void structAmplitudeTierEditor :: v_play (double fromTime, double toTime) { if (our d_sound.data) { Sound_playPart (our d_sound.data, fromTime, toTime, theFunctionEditor_playCallback, this); } else { //AmplitudeTier_playPart (data, fromTime, toTime, false); } } autoAmplitudeTierEditor AmplitudeTierEditor_create (const char32 *title, AmplitudeTier amplitude, Sound sound, bool ownSound) { try { autoAmplitudeTierEditor me = Thing_new (AmplitudeTierEditor); RealTierEditor_init (me.peek(), title, (RealTier) amplitude, sound, ownSound); return me; } catch (MelderError) { Melder_throw (U"AmplitudeTier window not created."); } } /* End of file AmplitudeTierEditor.cpp */ praat-6.0.04/fon/AmplitudeTierEditor.h000066400000000000000000000041401261542461700175710ustar00rootroot00000000000000#ifndef _AmplitudeTierEditor_h_ #define _AmplitudeTierEditor_h_ /* AmplitudeTierEditor.h * * Copyright (C) 2003-2011,2012,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "RealTierEditor.h" #include "AmplitudeTier.h" #include "Sound.h" Thing_define (AmplitudeTierEditor, RealTierEditor) { void v_createHelpMenuItems (EditorMenu menu) override; void v_play (double fromTime, double toTime) override; const char32 * v_quantityText () override { return U"Sound pressure (Pa)"; } const char32 * v_quantityKey () override { return U"Sound pressure"; } const char32 * v_rightTickUnits () override { return U" Pa"; } double v_defaultYmin () override { return -1.0; } double v_defaultYmax () override { return +1.0; } const char32 * v_setRangeTitle () override { return U"Set amplitude range..."; } const char32 * v_defaultYminText () override { return U"-1.0"; } const char32 * v_defaultYmaxText () override { return U"+1.0"; } const char32 * v_yminText () override { return U"Minimum amplitude (Pa)"; } const char32 * v_ymaxText () override { return U"Maximum amplitude (Pa)"; } const char32 * v_yminKey () override { return U"Minimum amplitude"; } const char32 * v_ymaxKey () override { return U"Maximum amplitude"; } }; autoAmplitudeTierEditor AmplitudeTierEditor_create (const char32 *title, AmplitudeTier amplitude, Sound sound, // may be null bool ownSound); /* End of file AmplitudeTierEditor.h */ #endif praat-6.0.04/fon/AnyTier.cpp000066400000000000000000000163331261542461700155670ustar00rootroot00000000000000/* AnyTier.cpp * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "AnyTier.h" #include "oo_DESTROY.h" #include "AnyTier_def.h" #include "oo_COPY.h" #include "AnyTier_def.h" #include "oo_EQUAL.h" #include "AnyTier_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "AnyTier_def.h" #include "oo_WRITE_TEXT.h" #include "AnyTier_def.h" #include "oo_READ_TEXT.h" #include "AnyTier_def.h" #include "oo_WRITE_BINARY.h" #include "AnyTier_def.h" #include "oo_READ_BINARY.h" #include "AnyTier_def.h" #include "oo_DESCRIPTION.h" #include "AnyTier_def.h" Thing_implement (AnyPoint, SimpleDouble, 0); Thing_implement (AnyTier, Function, 0); void structAnyTier :: v_shiftX (double xfrom, double xto) { AnyTier_Parent :: v_shiftX (xfrom, xto); for (long i = 1; i <= points -> size; i ++) { AnyPoint point = (AnyPoint) points -> item [i]; NUMshift (& point -> number, xfrom, xto); } } void structAnyTier :: v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto) { AnyTier_Parent :: v_scaleX (xminfrom, xmaxfrom, xminto, xmaxto); for (long i = 1; i <= points -> size; i ++) { AnyPoint point = (AnyPoint) points -> item [i]; NUMscale (& point -> number, xminfrom, xmaxfrom, xminto, xmaxto); } } long AnyTier_timeToLowIndex (I, double time) { iam (AnyTier); if (my points -> size == 0) return 0; // undefined long ileft = 1, iright = my points -> size; AnyPoint *points = (AnyPoint *) my points -> item; double tleft = points [ileft] -> number; if (time < tleft) return 0; // offleft double tright = points [iright] -> number; if (time >= tright) return iright; Melder_assert (time >= tleft && time < tright); Melder_assert (iright > ileft); while (iright > ileft + 1) { long imid = (ileft + iright) / 2; double tmid = points [imid] -> number; if (time < tmid) { iright = imid; tright = tmid; } else { ileft = imid; tleft = tmid; } } Melder_assert (iright == ileft + 1); Melder_assert (ileft >= 1); Melder_assert (iright <= my points -> size); Melder_assert (time >= points [ileft] -> number); Melder_assert (time <= points [iright] -> number); return ileft; } long AnyTier_timeToHighIndex (I, double time) { iam (AnyTier); if (my points -> size == 0) return 0; // undefined; is this right? long ileft = 1, iright = my points -> size; AnyPoint *points = (AnyPoint *) my points -> item; double tleft = points [ileft] -> number; if (time <= tleft) return 1; double tright = points [iright] -> number; if (time > tright) return iright + 1; // offright Melder_assert (time > tleft && time <= tright); Melder_assert (iright > ileft); while (iright > ileft + 1) { long imid = (ileft + iright) / 2; double tmid = points [imid] -> number; if (time <= tmid) { iright = imid; tright = tmid; } else { ileft = imid; tleft = tmid; } } Melder_assert (iright == ileft + 1); Melder_assert (ileft >= 1); Melder_assert (iright <= my points -> size); Melder_assert (time >= points [ileft] -> number); Melder_assert (time <= points [iright] -> number); return iright; } long AnyTier_getWindowPoints (I, double tmin, double tmax, long *imin, long *imax) { iam (AnyTier); if (my points -> size == 0) return 0; *imin = AnyTier_timeToHighIndex (me, tmin); *imax = AnyTier_timeToLowIndex (me, tmax); if (*imax < *imin) return 0; return *imax - *imin + 1; } long AnyTier_timeToNearestIndex (I, double time) { iam (AnyTier); if (my points -> size == 0) return 0; // undefined long ileft = 1, iright = my points -> size; AnyPoint *points = (AnyPoint *) my points -> item; double tleft = points [ileft] -> number; if (time <= tleft) return 1; double tright = points [iright] -> number; if (time >= tright) return iright; Melder_assert (time > tleft && time < tright); Melder_assert (iright > ileft); while (iright > ileft + 1) { long imid = (ileft + iright) / 2; double tmid = points [imid] -> number; if (time < tmid) { iright = imid; tright = tmid; } else { ileft = imid; tleft = tmid; } } Melder_assert (iright == ileft + 1); Melder_assert (ileft >= 1); Melder_assert (iright <= my points -> size); Melder_assert (time >= points [ileft] -> number); Melder_assert (time <= points [iright] -> number); return time - tleft <= tright - time ? ileft : iright; } long AnyTier_hasPoint (I, double t) { iam (AnyTier); if (my points -> size == 0) return 0; // point not found long ileft = 1, iright = my points -> size; AnyPoint *points = (AnyPoint *) my points -> item; double tleft = points [ileft] -> number; if (t < tleft) return 0; // offleft double tright = points [iright] -> number; if (t > tright) return 0; // offright if (t == tleft) return 1; if (t == tright) return iright; Melder_assert (t > tleft && t < tright); Melder_assert (iright > ileft); while (iright > ileft + 1) { long imid = (ileft + iright) / 2; double tmid = points [imid] -> number; if (t < tmid) { iright = imid; tright = tmid; } else if (t == tmid) { return imid; // point found } else { ileft = imid; tleft = tmid; } } Melder_assert (iright == ileft + 1); Melder_assert (ileft >= 1); Melder_assert (iright <= my points -> size); Melder_assert (t > points [ileft] -> number); Melder_assert (t < points [iright] -> number); return 0; /* Point not found. */ } void AnyTier_addPoint (I, Daata point) { iam (AnyTier); try { Collection_addItem (my points, point); } catch (MelderError) { Melder_throw (me, U": point not added."); } } void AnyTier_removePoint (I, long i) { iam (AnyTier); if (i >= 1 && i <= my points -> size) Collection_removeItem (my points, i); } void AnyTier_removePointNear (I, double time) { iam (AnyTier); long ipoint = AnyTier_timeToNearestIndex (me, time); if (ipoint) Collection_removeItem (my points, ipoint); } void AnyTier_removePointsBetween (I, double tmin, double tmax) { iam (AnyTier); if (my points -> size == 0) return; long ileft = AnyTier_timeToHighIndex (me, tmin); long iright = AnyTier_timeToLowIndex (me, tmax); for (long i = iright; i >= ileft; i --) Collection_removeItem (my points, i); } PointProcess AnyTier_downto_PointProcess (I) { iam (AnyTier); try { long numberOfPoints = my points -> size; AnyPoint *points = (AnyPoint *) my points -> item; autoPointProcess thee = PointProcess_create (my xmin, my xmax, numberOfPoints); /* OPTIMIZATION, bypassing PointProcess_addTime: */ for (long i = 1; i <= numberOfPoints; i ++) thy t [i] = points [i] -> number; thy nt = numberOfPoints; return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not converted to PointProcess."); } } /* End of file AnyTier.cpp */ praat-6.0.04/fon/AnyTier.h000066400000000000000000000027301261542461700152300ustar00rootroot00000000000000#ifndef _AnyTier_h_ #define _AnyTier_h_ /* AnyTier.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Collection.h" #include "PointProcess.h" #include "AnyTier_def.h" oo_CLASS_CREATE (AnyPoint, SimpleDouble); oo_CLASS_CREATE (AnyTier, Function); long AnyTier_timeToLowIndex (I, double time); long AnyTier_timeToHighIndex (I, double time); long AnyTier_getWindowPoints (I, double tmin, double tmax, long *imin, long *imax); long AnyTier_timeToNearestIndex (I, double time); long AnyTier_hasPoint (I, double t); void AnyTier_addPoint (I, Daata point); void AnyTier_removePoint (I, long i); void AnyTier_removePointNear (I, double time); void AnyTier_removePointsBetween (I, double tmin, double tmax); PointProcess AnyTier_downto_PointProcess (I); #endif /* End of file AnyTier.h */ praat-6.0.04/fon/AnyTier_def.h000066400000000000000000000023411261542461700160440ustar00rootroot00000000000000/* AnyTier_def.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT AnyPoint oo_DEFINE_CLASS (AnyPoint, SimpleDouble) oo_END_CLASS (AnyPoint) #undef ooSTRUCT #define ooSTRUCT AnyTier oo_DEFINE_CLASS (AnyTier, Function) oo_COLLECTION (SortedSetOfDouble, points, AnyPoint, 0) #if oo_DECLARING void v_shiftX (double xfrom, double xto) override; void v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto) override; #endif oo_END_CLASS (AnyTier) #undef ooSTRUCT /* End of file AnyTier_def.h */ praat-6.0.04/fon/Cochleagram.cpp000066400000000000000000000077501261542461700164240ustar00rootroot00000000000000/* Cochleagram.cpp * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Graphics.h" #include "Cochleagram.h" Thing_implement (Cochleagram, Matrix, 2); autoCochleagram Cochleagram_create (double tmin, double tmax, long nt, double dt, double t1, double df, long nf) { try { autoCochleagram me = Thing_new (Cochleagram); Matrix_init (me.peek(), tmin, tmax, nt, dt, t1, 0.0, nf * df, nf, df, 0.5 * df); return me; } catch (MelderError) { Melder_throw (U"Cochleagram with ", nt, U" times and ", nf, U" frequencies not created."); } } void Cochleagram_paint (Cochleagram me, Graphics g, double tmin, double tmax, int garnish) { static double border [1 + 12] { 0.0, 25.0, 30.0, 35.0, 40.0, 45.0, 50.0, 55.0, 60.0, 65.0, 70.0, 75.0, 80.0 }; try { autoCochleagram copy = Data_copy (me); if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } long itmin, itmax; Matrix_getWindowSamplesX (me, tmin, tmax, & itmin, & itmax); for (long iy = 2; iy < my ny; iy ++) for (long ix = itmin; ix <= itmax; ix ++) if (my z [iy] [ix] > my z [iy - 1] [ix] && my z [iy] [ix] > my z [iy + 1] [ix]) { copy -> z [iy - 1] [ix] += 10.0; copy -> z [iy] [ix] += 10.0; copy -> z [iy + 1] [ix] += 10.0; } Graphics_setInner (g); Graphics_setWindow (g, tmin, tmax, 0.0, my ny * my dy); Graphics_grey (g, copy -> z, itmin, itmax, Matrix_columnToX (me, itmin), Matrix_columnToX (me, itmax), 1, my ny, 0.5 * my dy, (my ny - 0.5) * my dy, 12, border); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Time (s)"); Graphics_marksBottom (g, 2, true, true, false); Graphics_textLeft (g, true, U"Place (Bark)"); Graphics_marksLeftEvery (g, 1.0, 5.0, true, true, false); } } catch (MelderError) { Melder_clearError (); } } double Cochleagram_difference (Cochleagram me, Cochleagram thee, double tmin, double tmax) { try { if (my nx != thy nx || my dx != thy dx || my x1 != thy x1) Melder_throw (U"Unequal time samplings."); if (my ny != thy ny) Melder_throw (U"Unequal numbers of frequencies."); if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } long itmin, itmax; long nt = Matrix_getWindowSamplesX (me, tmin, tmax, & itmin, & itmax); if (nt == 0) Melder_throw (U"Window too short."); double diff = 0.0; for (long itime = itmin; itime <= itmax; itime ++) { for (long ifreq = 1; ifreq <= my ny; ifreq ++) { double d = my z [ifreq] [itime] - thy z [ifreq] [itime]; diff += d * d; } } diff /= nt * my ny; return sqrt (diff); } catch (MelderError) { Melder_throw (me, U" & ", thee, U": difference not computed."); } } autoCochleagram Matrix_to_Cochleagram (Matrix me) { try { autoCochleagram thee = Cochleagram_create (my xmin, my xmax, my nx, my dx, my x1, my dy, my ny); NUMmatrix_copyElements (my z, thy z, 1, my ny, 1, my nx); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Cochleagram."); } } autoMatrix Cochleagram_to_Matrix (Cochleagram me) { try { autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, my ymin, my ymax, my ny, my dy, my y1); NUMmatrix_copyElements (my z, thy z, 1, my ny, 1, my nx); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Matrix."); } } /* End of file Cochleagram.cpp */ praat-6.0.04/fon/Cochleagram.h000066400000000000000000000051771261542461700160720ustar00rootroot00000000000000#ifndef _Cochleagram_h_ #define _Cochleagram_h_ /* Cochleagram.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Matrix.h" Thing_define (Cochleagram, Matrix) { int v_domainQuantity () override { return MelderQuantity_TIME_SECONDS; } }; /* Normally, the attributes will meet the following: xmin; // Start time (seconds). xmax; // End time (seconds). nx; // Number of time slices. dx; // Time step (seconds). x1; // Centre of first time sample (seconds). ymin = 0; // Minimum frequency (Bark). ymax = 25.6; // Maximum frequency (Bark). ny; // Number of frequencies. dy = 25.6 / ny; // Frequency step (Bark). y1 = 0.5 * dy; // Centre of first frequency band (Bark). z; // Basilar filter output (milliVolt), or firing rate (Hz), or intensity (phon). */ autoCochleagram Cochleagram_create (double tmin, double tmax, long nt, double dt, double t1, double df, long nf); /* Function: return a new instance of Cochleagram. Preconditions: dt > 0.0; df > 0.0; nt >= 1; nf >= 1; Postconditions: result -> xmin == tmin; result -> ymin == 0.0; result -> xmax == tmax; result -> ymax == 25.6; result -> nx == nt; result -> ny == nf; result -> dx == dt; result -> dy == df; result -> x1 == t1; result -> y1 == 0.5 * df; result -> z [1..nf] [1..nt] == 0.0; */ void Cochleagram_paint (Cochleagram me, Graphics g, double tmin, double tmax, int garnish); double Cochleagram_difference (Cochleagram me, Cochleagram thee, double tmin, double tmax); autoCochleagram Matrix_to_Cochleagram (Matrix me); /* Function: create a Cochleagram from a Matrix, with deep copy of all its attributes, except class information and methods. Fail if out of memory. */ autoMatrix Cochleagram_to_Matrix (Cochleagram me); /* Function: create a Matrix from a Cochleagram, with deep copy of all its attributes, except class information and methods. Fail if out of memory. */ /* End of file Cochleagram.h */ #endif praat-6.0.04/fon/Cochleagram_and_Excitation.cpp000066400000000000000000000026451261542461700214330ustar00rootroot00000000000000/* Cochleagram_and_Excitation.cpp * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 1993/12/20 * pb 2002/07/16 GPL * pb 2011/05/05 type * pb 2011/05/09 C++ */ #include "Cochleagram_and_Excitation.h" autoExcitation Cochleagram_to_Excitation (Cochleagram me, double t) { try { long column = Matrix_xToNearestColumn (me, t); if (column < 1) column = 1; if (column > my nx) column = my nx; autoExcitation thee = Excitation_create (my dy, my ny); for (long ifreq = 1; ifreq <= my ny; ifreq ++) thy z [1] [ifreq] = my z [ifreq] [column]; return thee; } catch (MelderError) { Melder_throw (me, U": slice at time ", t, U" seconds not extracted to Excitation."); } } /* End of file Cochleagram_and_Excitation.cpp */ praat-6.0.04/fon/Cochleagram_and_Excitation.h000066400000000000000000000016671261542461700211030ustar00rootroot00000000000000/* Cochleagram_and_Excitation.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Cochleagram.h" #include "Excitation.h" autoExcitation Cochleagram_to_Excitation (Cochleagram me, double t); /* End of file Cochleagram_and_Excitation.h */ praat-6.0.04/fon/Corpus.cpp000066400000000000000000000024271261542461700154660ustar00rootroot00000000000000/* Corpus.cpp * * Copyright (C) 2011 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Corpus.h" #include "oo_DESTROY.h" #include "Corpus_def.h" #include "oo_COPY.h" #include "Corpus_def.h" #include "oo_EQUAL.h" #include "Corpus_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Corpus_def.h" #include "oo_WRITE_TEXT.h" #include "Corpus_def.h" #include "oo_READ_TEXT.h" #include "Corpus_def.h" #include "oo_WRITE_BINARY.h" #include "Corpus_def.h" #include "oo_READ_BINARY.h" #include "Corpus_def.h" #include "oo_DESCRIPTION.h" #include "Corpus_def.h" Thing_implement (Corpus, Table, 0); /* End of file Corpus.cpp */ praat-6.0.04/fon/Corpus.h000066400000000000000000000016111261542461700151250ustar00rootroot00000000000000#ifndef _Corpus_h_ #define _Corpus_h_ /* AnyTier.h * * Copyright (C) 2011 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Table.h" #include "Corpus_def.h" oo_CLASS_CREATE (Corpus, Table); #endif /* End of file Corpus.h */ praat-6.0.04/fon/Corpus_def.h000066400000000000000000000015671261542461700157550ustar00rootroot00000000000000/* Corpus_def.h * * Copyright (C) 2011 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT Corpus oo_DEFINE_CLASS (Corpus, Table) oo_END_CLASS (Corpus) #undef ooSTRUCT /* End of file Corpus_def.h */ praat-6.0.04/fon/Distributions_and_Transition.cpp000066400000000000000000000132571261542461700221140ustar00rootroot00000000000000/* Distributions_and_Transition.cpp * * Copyright (C) 1997-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 1997/03/02 created * pb 2002/07/16 GPL * pb 2007/08/12 wchar * pb 2011/05/09 C++ */ #include "Distributions_and_Transition.h" autoTransition Distributions_to_Transition (Distributions underlying, Distributions surface, long environment, Transition adjacency, int greedy) { try { if (! underlying) return nullptr; /* * Preconditions: range check and matrix matching. */ if (environment < 1 || environment > underlying -> numberOfColumns) Melder_throw (U"Environment (", environment, U") out of range (1-", underlying -> numberOfColumns, U")."); if (surface && (underlying -> numberOfColumns != surface -> numberOfColumns || underlying -> numberOfRows != surface -> numberOfRows)) Melder_throw (U"Sizes of underlying and surface distributions do not match."); if (adjacency && adjacency -> numberOfStates != underlying -> numberOfColumns) Melder_throw (U"Number of states (", adjacency -> numberOfStates, U") in adjacency matrix " U"does not match number of distributions (", underlying -> numberOfColumns, U")"); /* * Defaults. */ if (! surface) surface = underlying; /* * Create the output object. */ autoTransition thee = Transition_create (underlying -> numberOfColumns); /* * Copy labels and set name. */ for (long i = 1; i <= thy numberOfStates; i ++) { thy stateLabels [i] = Melder_dup (underlying -> columnLabels [i]); } Thing_setName (thee.peek(), underlying -> columnLabels [environment]); /* * Compute the off-diagonal elements of the transition matrix in environment 'environment'. */ for (long i = 1; i <= thy numberOfStates; i ++) { /* * How many states are available for the learner to step to (excluding current state)? */ long numberOfAdjacentStates; if (adjacency) { numberOfAdjacentStates = 0; for (long j = 1; j <= thy numberOfStates; j ++) if (i != j && adjacency -> data [i] [j] != 0.0) numberOfAdjacentStates ++; } else { numberOfAdjacentStates = thy numberOfStates - 1; } /* * Try all possible steps to adjacent states. */ for (long j = 1; j <= thy numberOfStates; j ++) if (i != j) { /* * Local: grammar step only possible to adjacent grammar. */ if (adjacency && adjacency -> data [i] [j] == 0) continue; /* * Compute element (i, j): sum over all possible data. */ for (long m = 1; m <= underlying -> numberOfRows; m ++) { /* * Error-driven: grammar step only triggered by positive evidence. * If the datum does not conflict with the current hypothesis (i), ignore it. */ if (underlying -> data [m] [i] != 0.0) continue; /* * Greedy: grammar step only taken if new grammar accepts datum. */ if (greedy && underlying -> data [m] [j] == 0) continue; /* * The step is taken if this datum occurs and this grammar (j) is chosen. */ thy data [i] [j] += surface -> data [m] [environment] / numberOfAdjacentStates; } } } /* * Compute the elements on the diagonal, so that the sum of each row is unity. */ for (long i = 1; i <= thy numberOfStates; i ++) { double sum = 0.0; for (long j = 1; j <= thy numberOfStates; j ++) if (j != i) sum += thy data [i] [j]; thy data [i] [i] = sum > 1.0 ? 0.0 : 1.0 - sum; // guard against rounding errors } return thee; } catch (MelderError) { Melder_throw (underlying, U": Transition not computed."); } } autoDistributions Distributions_Transition_map (Distributions me, Transition map) { try { /* * Preconditions: matrix matching. */ if (map -> numberOfStates != my numberOfRows) Melder_throw (U"Number of data (", map -> numberOfStates, U") in mapping matrix " U"does not match number of data (", my numberOfRows, U") in distribution."); /* * Create the output object. */ autoDistributions thee = Data_copy (me); /* * Compute the elements of the surface distributions. */ for (long row = 1; row <= my numberOfRows; row ++) for (long col = 1; col <= my numberOfColumns; col ++) { thy data [row] [col] = 0.0; for (long m = 1; m <= map -> numberOfStates; m ++) thy data [row] [col] += my data [m] [col] * map -> data [m] [row]; } return thee; } catch (MelderError) { Melder_throw (me, U": not mapped to Transition."); } } autoDistributions Transition_to_Distributions_conflate (Transition me) { try { autoDistributions thee = Distributions_create (my numberOfStates, 1); /* * Copy labels. */ for (long i = 1; i <= my numberOfStates; i ++) { thy rowLabels [i] = Melder_dup (my stateLabels [i]); } /* * Average rows. */ for (long i = 1; i <= my numberOfStates; i ++) { for (long j = 1; j <= my numberOfStates; j ++) thy data [i] [1] += my data [j] [i]; thy data [i] [1] /= my numberOfStates; } return thee; } catch (MelderError) { Melder_throw (me, U": not conflated to Distributions."); } } /* End of file Distributions_and_Transition.cpp */ praat-6.0.04/fon/Distributions_and_Transition.h000066400000000000000000000022501261542461700215500ustar00rootroot00000000000000/* Distributions_and_Transition.h * * Copyright (C) 1997-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Distributions.h" #include "Transition.h" autoTransition Distributions_to_Transition (Distributions underlying, Distributions surface, long environment, Transition adjacency, int greedy); autoDistributions Distributions_Transition_map (Distributions me, Transition map); autoDistributions Transition_to_Distributions_conflate (Transition me); /* End of file Distributions_and_Transition.h */ praat-6.0.04/fon/DurationTier.cpp000066400000000000000000000043451261542461700166250ustar00rootroot00000000000000/* DurationTier.cpp * * Copyright (C) 1992-2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "DurationTier.h" Thing_implement (DurationTier, RealTier, 0); void structDurationTier :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Time domain:"); MelderInfo_writeLine (U" Start time: ", xmin, U" seconds"); MelderInfo_writeLine (U" End time: ", xmax, U" seconds"); MelderInfo_writeLine (U" Total original duration: ", xmax - xmin, U" seconds"); MelderInfo_writeLine (U"Number of points: ", points -> size); MelderInfo_writeLine (U"Minimum relative duration value: ", RealTier_getMinimumValue (this)); MelderInfo_writeLine (U"Maximum relative duration value: ", RealTier_getMaximumValue (this)); } autoDurationTier DurationTier_create (double tmin, double tmax) { try { autoDurationTier me = Thing_new (DurationTier); RealTier_init (me.peek(), tmin, tmax); return me; } catch (MelderError) { Melder_throw (U"DurationTier not created."); } } void DurationTier_draw (DurationTier me, Graphics g, double tmin, double tmax, double ymin, double ymax, const char32 *method, int garnish) { RealTier_draw (me, g, tmin, tmax, ymin, ymax, garnish, method, U"Relative duration"); } autoDurationTier PointProcess_upto_DurationTier (PointProcess me) { try { autoDurationTier thee = DurationTier_create (my xmin, my xmax); for (long i = 1; i <= my nt; i ++) { RealTier_addPoint (thee.peek(), my t [i], 1.0); } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to DurationTier."); } } /* End of file DurationTier.cpp */ praat-6.0.04/fon/DurationTier.h000066400000000000000000000025361261542461700162720ustar00rootroot00000000000000#ifndef _DurationTier_h_ #define _DurationTier_h_ /* DurationTier.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "RealTier.h" #include "Graphics.h" /********** class DurationTier **********/ Thing_define (DurationTier, RealTier) { void v_info () override; int v_domainQuantity () override { return MelderQuantity_TIME_SECONDS; } }; autoDurationTier DurationTier_create (double tmin, double tmax); void DurationTier_draw (DurationTier me, Graphics g, double tmin, double tmax, double ymin, double ymax, const char32 *method, int garnish); autoDurationTier PointProcess_upto_DurationTier (PointProcess me); /* End of file DurationTier.h */ #endif praat-6.0.04/fon/DurationTierEditor.cpp000066400000000000000000000035541261542461700177750ustar00rootroot00000000000000/* DurationTierEditor.cpp * * Copyright (C) 1992-2011,2012,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "DurationTierEditor.h" #include "EditorM.h" Thing_implement (DurationTierEditor, RealTierEditor, 0); static void menu_cb_DurationTierHelp (EDITOR_ARGS) { EDITOR_IAM (DurationTierEditor); Melder_help (U"DurationTier"); } void structDurationTierEditor :: v_createHelpMenuItems (EditorMenu menu) { DurationTierEditor_Parent :: v_createHelpMenuItems (menu); EditorMenu_addCommand (menu, U"DurationTier help", 0, menu_cb_DurationTierHelp); } void structDurationTierEditor :: v_play (double fromTime, double toTime) { if (our d_sound.data) { Sound_playPart (our d_sound.data, fromTime, toTime, nullptr, nullptr); } else { //DurationTier_playPart (data, fromTime, toTime, false); } } autoDurationTierEditor DurationTierEditor_create (const char32 *title, DurationTier duration, Sound sound, bool ownSound) { try { autoDurationTierEditor me = Thing_new (DurationTierEditor); RealTierEditor_init (me.peek(), title, (RealTier) duration, sound, ownSound); return me; } catch (MelderError) { Melder_throw (U"DurationTier window not created."); } } /* End of file DurationTierEditor.cpp */ praat-6.0.04/fon/DurationTierEditor.h000066400000000000000000000042061261542461700174350ustar00rootroot00000000000000#ifndef _DurationTierEditor_h_ #define _DurationTierEditor_h_ /* DurationTierEditor.h * * Copyright (C) 1992-2011,2012,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "RealTierEditor.h" #include "DurationTier.h" #include "Sound.h" Thing_define (DurationTierEditor, RealTierEditor) { void v_createHelpMenuItems (EditorMenu menu) override; void v_play (double fromTime, double toTime) override; double v_minimumLegalValue () override { return 0.0; } const char32 * v_quantityText () override { return U"Relative duration"; } const char32 * v_quantityKey () override { return U"Relative duration"; } const char32 * v_rightTickUnits () override { return U""; } double v_defaultYmin () override { return 0.25; } double v_defaultYmax () override { return 3.0; } const char32 * v_setRangeTitle () override { return U"Set duration range..."; } const char32 * v_defaultYminText () override { return U"0.25"; } const char32 * v_defaultYmaxText () override { return U"3.0"; } const char32 * v_yminText () override { return U"Minimum duration"; } const char32 * v_ymaxText () override { return U"Maximum duration"; } const char32 * v_yminKey () override { return U"Minimum duration"; } const char32 * v_ymaxKey () override { return U"Maximum duration"; } }; autoDurationTierEditor DurationTierEditor_create (const char32 *title, DurationTier duration, Sound sound, bool ownSound); /* 'sound' may be null. */ /* End of file DurationTierEditor.h */ #endif praat-6.0.04/fon/Excitation.cpp000066400000000000000000000115061261542461700163200ustar00rootroot00000000000000/* Excitation.cpp * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Excitation.h" Thing_implement (Excitation, Vector, 2); double Excitation_hertzToBark (double hertz) { double h650 = hertz / 650; return 7.0 * log (h650 + sqrt (1.0 + h650 * h650)); } double Excitation_barkToHertz (double bark) { return 650.0 * sinh (bark / 7.0); } double Excitation_phonToDifferenceLimens (double phon) { return 30.0 * (pow (61.0 / 60.0, phon) - 1); } double Excitation_differenceLimensToPhon (double ndli) { return log (1 + ndli / 30.0) / log (61.0 / 60.0); } double Excitation_soundPressureToPhon (double soundPressure, double bark) { double result, dum; if (soundPressure <= 0.0) return 0.0; /* dB = 20 * log10 (soundPressure / threshold) */ result = 20.0 * log10 (soundPressure / 2.0e-5); /* First approximation: phon = dB */ /* Phones from dB */ if (result < 90.0 && bark < 8.0) { dum = (90.0 - result) * (8.0 - bark); result -= dum * dum / 2500; } dum = bark / 3.6 - 5.0; result += 5.0 * exp (- dum * dum); if (bark > 20.0) { dum = bark - 20.0; result -= 0.5 * dum * dum; } if (result < 0.0) result = 0.0; return result; } void structExcitation :: v_info () { double *y = z [1]; long numberOfMaxima = 0; structDaata :: v_info (); MelderInfo_writeLine (U"Loudness: ", Melder_half (Excitation_getLoudness (this)), U" sones"); for (long i = 2; i < nx; i ++) if (y [i] > y [i - 1] && y [i] >= y [i + 1]) { if (++ numberOfMaxima > 15) break; double i_real; double strength = NUMimproveMaximum (z [1], nx, i, NUM_PEAK_INTERPOLATE_SINC70, & i_real); double formant_bark = x1 + (i_real - 1.0) * dx; MelderInfo_write (U"Peak at ", Melder_single (formant_bark), U" Bark"); MelderInfo_write (U", ", (long) NUMbarkToHertz (formant_bark), U" Hz"); MelderInfo_writeLine (U", ", Melder_half (strength), U" phon."); } } autoExcitation Excitation_create (double df, long nf) { try { autoExcitation me = Thing_new (Excitation); Matrix_init (me.peek(), 0.0, nf * df, nf, df, 0.5 * df, 1.0, 1.0, 1, 1.0, 1.0); return me; } catch (MelderError) { Melder_throw (U"Excitation not created."); } } double Excitation_getDistance (Excitation me, Excitation thee) { double distance = 0.0, mean = 0.0; Melder_assert (my nx == thy nx); for (long i = 1; i <= my nx; i ++) { double dper = my z [1] [i] - thy z [1] [i]; mean += dper; distance += dper * dper; } mean /= my nx; distance /= my nx; /* distance -= mean * mean; */ return sqrt (distance); } double Excitation_getLoudness (Excitation me) { double loudness = 0.0; for (int i = 1; i <= my nx; i ++) /* Sones = 2 ** ((Phones - 40) / 10) */ loudness += pow (2.0, (my z [1] [i] - 40.0) / 10.0); return my dx * loudness; } void Excitation_draw (Excitation me, Graphics g, double fmin, double fmax, double minimum, double maximum, int garnish) { if (fmax <= fmin) { fmin = my xmin; fmax = my xmax; } long ifmin, ifmax; Matrix_getWindowSamplesX (me, fmin, fmax, & ifmin, & ifmax); if (maximum <= minimum) Matrix_getWindowExtrema (me, ifmin, ifmax, 1, 1, & minimum, & maximum); if (maximum <= minimum) { minimum -= 20.0; maximum += 20.0; } Graphics_setInner (g); Graphics_setWindow (g, fmin, fmax, minimum, maximum); Graphics_function (g, my z [1], ifmin, ifmax, Matrix_columnToX (me, ifmin), Matrix_columnToX (me, ifmax)); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Frequency (Bark)"); Graphics_textLeft (g, true, U"Excitation (phon)"); Graphics_marksBottomEvery (g, 1.0, 5.0, true, true, false); Graphics_marksLeftEvery (g, 1.0, 20.0, true, true, false); } } autoMatrix Excitation_to_Matrix (Excitation me) { try { autoMatrix thee = Thing_new (Matrix); my structMatrix :: v_copy (thee.peek()); // BUG: safe, but compiler should be able to check return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Matrix."); } } autoExcitation Matrix_to_Excitation (Matrix me) { try { autoExcitation thee = Thing_new (Excitation); my structMatrix :: v_copy (thee.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Excitation."); } } /* End of file Excitation.cpp */ praat-6.0.04/fon/Excitation.h000066400000000000000000000032521261542461700157640ustar00rootroot00000000000000#ifndef _Excitation_h_ #define _Excitation_h_ /* Excitation.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Vector.h" #include "Graphics.h" Thing_define (Excitation, Vector) { void v_info () override; int v_domainQuantity () override { return MelderQuantity_FREQUENCY_BARK; } }; double Excitation_hertzToBark (double hertz); double Excitation_barkToHertz (double bark); double Excitation_phonToDifferenceLimens (double phon); double Excitation_differenceLimensToPhon (double ndli); double Excitation_soundPressureToPhon (double soundPressure, double bark); autoExcitation Excitation_create (double df, long nf); double Excitation_getDistance (Excitation me, Excitation thee); double Excitation_getLoudness (Excitation me); void Excitation_draw (Excitation me, Graphics g, double fmin, double fmax, double minimum, double maximum, int garnish); autoMatrix Excitation_to_Matrix (Excitation me); autoExcitation Matrix_to_Excitation (Matrix me); /* End of file Excitation.h */ #endif praat-6.0.04/fon/Excitation_to_Formant.cpp000066400000000000000000000045671261542461700205210ustar00rootroot00000000000000/* Excitation_to_Formant.cpp * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 1995/08/23 * pb 2002/07/16 GPL * pb 2008/01/19 double * pb 2011/05/24 C++ */ #include "Excitation_to_Formant.h" autoFormant Excitation_to_Formant (Excitation me, int maxnFormants) { try { long nfreq = my nx, nform = 0; double *p = my z [1]; autoFormant thee = Formant_create (0, 1, 1, 1, 0.5, maxnFormants); thy d_frames [1]. formant = NUMvector (1, maxnFormants); for (long i = 2; i < nfreq; i ++) if (p [i] > p [i - 1] && p [i] >= p [i + 1]) { double min3phon, left, right; double firstDerivative = p [i+1] - p [i-1], secondDerivative = 2 * p [i] - p [i-1] - p [i+1]; long j; Formant_Formant formant = & thy d_frames [1]. formant [++ nform]; formant -> frequency = Excitation_barkToHertz ( my x1 + my dx * (i - 1 + 0.5 * firstDerivative / secondDerivative)); min3phon = p [i] + 0.125 * firstDerivative * firstDerivative / secondDerivative - 3.0; /* Search left. */ j = i - 1; while (p [j] > min3phon && j > 1) j --; left = Excitation_barkToHertz ( p [j] > min3phon ? my xmin : my x1 + my dx * (j - 1 + (min3phon - p [j]) / (p [j + 1] - p [j]))); /* Search right. */ j = i + 1; while (p [j] > min3phon && j < nfreq) j ++; right = Excitation_barkToHertz ( p [j] > min3phon ? my xmax : my x1 + my dx * (j - 1 - (min3phon - p [j]) / (p [j - 1] - p [j]))); formant -> bandwidth = right - left; if (nform == thy maxnFormants) break; } thy d_frames [1]. nFormants = nform; return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Formant."); } } /* End of file Excitation_to_Formant.cpp */ praat-6.0.04/fon/Excitation_to_Formant.h000066400000000000000000000016461261542461700201610ustar00rootroot00000000000000/* Excitation_to_Formant.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Excitation.h" #include "Formant.h" autoFormant Excitation_to_Formant (Excitation, int maxnFormants); /* End of file Excitation_to_Formant.h */ praat-6.0.04/fon/ExperimentMFC.cpp000066400000000000000000000474021261542461700166630ustar00rootroot00000000000000/* ExperimentMFC.cpp * * Copyright (C) 2001-2011,2013 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2002/10/31 NUMlog2 * pb 2003/03/08 inter-stimulus interval; version 2 * pb 2003/09/14 MelderDir_relativePathToFile * pb 2004/06/22 added response keys; version 3 * pb 2004/08/12 removed a bug (something said carrierBefore instead of carrierAfter) * that caused Praat to crash if the carrier before was longer than the carrier after * pb 2005/11/21 added replay button; version 4 * pb 2005/12/02 response sounds are read * pb 2006/10/28 erased MacOS 9 stuff * pb 2006/12/20 stereo * pb 2007/08/12 wchar * pb 2007/09/26 added font size; version 5 * pb 2007/10/01 can write as encoding * pb 2008/04/08 in ExtractResults, check that a resonse was given * pb 2008/10/20 except nonstandard sound files * pb 2009/03/18 removed a bug introduced by the previous change (an error check got hidden) * pb 2011/03/03 added reaction times; version 2 of ResultsMFC * pb 2011/03/15 allowed result extraction from incomplete experiments * pb 2011/03/23 C++ * pb 2011/07/06 C++ * pb 2013/01/01 added blank while playing; version 6 */ #include "ExperimentMFC.h" #include "oo_DESTROY.h" #include "ExperimentMFC_def.h" #include "oo_COPY.h" #include "ExperimentMFC_def.h" #include "oo_EQUAL.h" #include "ExperimentMFC_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "ExperimentMFC_def.h" #include "oo_READ_TEXT.h" #include "ExperimentMFC_def.h" #include "oo_WRITE_TEXT.h" #include "ExperimentMFC_def.h" #include "oo_READ_BINARY.h" #include "ExperimentMFC_def.h" #include "oo_WRITE_BINARY.h" #include "ExperimentMFC_def.h" #include "oo_DESCRIPTION.h" #include "ExperimentMFC_def.h" Thing_implement (ExperimentMFC, Daata, 6); #include "enums_getText.h" #include "Experiment_enums.h" #include "enums_getValue.h" #include "Experiment_enums.h" static void readSound (ExperimentMFC me, const char32 *fileNameHead, const char32 *fileNameTail, double medialSilenceDuration, char32 **name, Sound *sound) { char32 fileNameBuffer [256], *fileNames = & fileNameBuffer [0]; Melder_sprint (fileNameBuffer,256, *name); structMelderFile file = { 0 }; /* * The following conversion is needed when fileNameHead is an absolute path, * and the stimulus names contain slashes for relative paths. * An ugly case, but allowed. */ #if defined (_WIN32) for (;;) { char32 *slash = str32chr (fileNames, U'/'); if (! slash) break; *slash = U'\\'; } #endif forget (*sound); char32 pathName [kMelder_MAXPATH+1]; /* * 'fileNames' can contain commas, which separate partial file names. * The separate files should be concatenated. */ for (;;) { /* * Determine partial file name. */ char32 *comma = str32chr (fileNames, U','); if (comma) *comma = '\0'; /* * Determine complete (relative) file name. */ Melder_sprint (pathName,kMelder_MAXPATH+1, fileNameHead, fileNames, fileNameTail); /* * Make sure we are in the correct directory. */ if (MelderDir_isNull (& my rootDirectory)) { /* * Absolute file name. */ Melder_pathToFile (pathName, & file); } else { /* * Relative or absolute file name. */ MelderDir_relativePathToFile (& my rootDirectory, pathName, & file); if (Melder_debug == 32) { MelderInfo_open (); MelderInfo_writeLine (U"Path name <", pathName, U">"); MelderInfo_writeLine (U"Root directory <", my rootDirectory.path, U">"); MelderInfo_writeLine (U"Full path name <", file.path, U">"); MelderInfo_close (); } } /* * Read the substimulus. */ autoSound substimulus = (Sound) Data_readFromFile (& file); // Sound_readFromSoundFile (& file); if (substimulus -> classInfo != classSound) Melder_throw (U"File ", & file, U" contains a ", Thing_className (substimulus.peek()), U" instead of a sound."); /* * Check whether all sounds have the same number of channels. */ if (my numberOfChannels == 0) { my numberOfChannels = substimulus -> ny; } else if (substimulus -> ny != my numberOfChannels) { Melder_throw (U"The sound in file ", & file, U" has a different number of channels than some other sound."); } /* * Check whether all sounds have the same sampling frequency. */ if (my samplePeriod == 0.0) { my samplePeriod = substimulus -> dx; /* This must be the first sound read. */ } else if (substimulus -> dx != my samplePeriod) { Melder_throw (U"The sound in file ", & file, U" has a different sampling frequency than some other sound."); } /* * Append the substimuli, perhaps with silent intervals. */ if (! *sound) { *sound = substimulus.transfer(); } else { autoSound newStimulus = Sounds_append (*sound, medialSilenceDuration, substimulus.peek()); Melder_assert (sound == & (*sound)); forget (*sound); *sound = newStimulus.transfer(); } /* * Cycle. */ if (! comma) break; fileNames = & comma [1]; } } static void permuteRandomly (ExperimentMFC me, long first, long last) { for (long itrial = first; itrial < last; itrial ++) { long jtrial = NUMrandomInteger (itrial, last); long dummy = my stimuli [jtrial]; my stimuli [jtrial] = my stimuli [itrial]; my stimuli [itrial] = dummy; } } void ExperimentMFC_start (ExperimentMFC me) { try { long maximumStimulusPlaySamples, maximumResponsePlaySamples, maximumPlaySamples; long stimulusCarrierBeforeSamples = 0, stimulusCarrierAfterSamples = 0, maximumStimulusSamples = 0; long responseCarrierBeforeSamples = 0, responseCarrierAfterSamples = 0, maximumResponseSamples = 0; Melder_warningOff (); my trial = 0; NUMvector_free (my stimuli, 1); NUMvector_free (my responses, 1); NUMvector_free (my goodnesses, 1); NUMvector_free (my reactionTimes, 1); my playBuffer.reset(); my pausing = false; my numberOfTrials = my numberOfDifferentStimuli * my numberOfReplicationsPerStimulus; my stimuli = NUMvector (1, my numberOfTrials); my responses = NUMvector (1, my numberOfTrials); my goodnesses = NUMvector (1, my numberOfTrials); my reactionTimes = NUMvector (1, my numberOfTrials); /* * Read all the sounds. They must all have the same sampling frequency and number of channels. */ my samplePeriod = 0.0; my numberOfChannels = 0; if (my stimuliAreSounds) { if (my stimulusCarrierBefore. name && my stimulusCarrierBefore. name [0]) { readSound (me, my stimulusFileNameHead, my stimulusFileNameTail, my stimulusMedialSilenceDuration, & my stimulusCarrierBefore. name, & my stimulusCarrierBefore. sound); stimulusCarrierBeforeSamples = my stimulusCarrierBefore. sound -> nx; } if (my stimulusCarrierAfter. name && my stimulusCarrierAfter. name [0]) { readSound (me, my stimulusFileNameHead, my stimulusFileNameTail, my stimulusMedialSilenceDuration, & my stimulusCarrierAfter. name, & my stimulusCarrierAfter. sound); stimulusCarrierAfterSamples = my stimulusCarrierAfter. sound -> nx; } for (long istim = 1; istim <= my numberOfDifferentStimuli; istim ++) { readSound (me, my stimulusFileNameHead, my stimulusFileNameTail, my stimulusMedialSilenceDuration, & my stimulus [istim]. name, & my stimulus [istim]. sound); if (my stimulus [istim]. sound -> nx > maximumStimulusSamples) maximumStimulusSamples = my stimulus [istim]. sound -> nx; } } if (my responsesAreSounds) { if (my responseCarrierBefore. name && my responseCarrierBefore. name [0]) { readSound (me, my responseFileNameHead, my responseFileNameTail, my responseMedialSilenceDuration, & my responseCarrierBefore. name, & my responseCarrierBefore. sound); responseCarrierBeforeSamples = my responseCarrierBefore. sound -> nx; } if (my responseCarrierAfter. name && my responseCarrierAfter. name [0]) { readSound (me, my responseFileNameHead, my responseFileNameTail, my responseMedialSilenceDuration, & my responseCarrierAfter. name, & my responseCarrierAfter. sound); responseCarrierAfterSamples = my responseCarrierAfter. sound -> nx; } for (long iresp = 1; iresp <= my numberOfDifferentResponses; iresp ++) { readSound (me, my responseFileNameHead, my responseFileNameTail, my responseMedialSilenceDuration, & my response [iresp]. name, & my response [iresp]. sound); if (my response [iresp]. sound -> nx > maximumResponseSamples) maximumResponseSamples = my response [iresp]. sound -> nx; } } /* * Create the play buffer. */ maximumStimulusPlaySamples = lround (my stimulusInitialSilenceDuration / my samplePeriod) + lround (my stimulusFinalSilenceDuration / my samplePeriod) + stimulusCarrierBeforeSamples + maximumStimulusSamples + stimulusCarrierAfterSamples + 2; maximumResponsePlaySamples = lround (my responseInitialSilenceDuration / my samplePeriod) + lround (my responseFinalSilenceDuration / my samplePeriod) + responseCarrierBeforeSamples + maximumResponseSamples + responseCarrierAfterSamples + 2; maximumPlaySamples = maximumStimulusPlaySamples > maximumResponsePlaySamples ? maximumStimulusPlaySamples : maximumResponsePlaySamples; my playBuffer = Sound_create (my numberOfChannels, 0.0, maximumPlaySamples * my samplePeriod, maximumPlaySamples, my samplePeriod, 0.5 * my samplePeriod); /* * Determine the order in which the stimuli will be presented to the subject. */ if (my randomize == kExperiment_randomize_CYCLIC_NON_RANDOM) { for (long itrial = 1; itrial <= my numberOfTrials; itrial ++) my stimuli [itrial] = (itrial - 1) % my numberOfDifferentStimuli + 1; } else if (my randomize == kExperiment_randomize_PERMUTE_ALL) { for (long itrial = 1; itrial <= my numberOfTrials; itrial ++) my stimuli [itrial] = (itrial - 1) % my numberOfDifferentStimuli + 1; permuteRandomly (me, 1, my numberOfTrials); } else if (my randomize == kExperiment_randomize_PERMUTE_BALANCED) { for (long ireplica = 1; ireplica <= my numberOfReplicationsPerStimulus; ireplica ++) { long offset = (ireplica - 1) * my numberOfDifferentStimuli; for (long istim = 1; istim <= my numberOfDifferentStimuli; istim ++) my stimuli [offset + istim] = istim; permuteRandomly (me, offset + 1, offset + my numberOfDifferentStimuli); } } else if (my randomize == kExperiment_randomize_PERMUTE_BALANCED_NO_DOUBLETS) { for (long ireplica = 1; ireplica <= my numberOfReplicationsPerStimulus; ireplica ++) { long offset = (ireplica - 1) * my numberOfDifferentStimuli; for (long istim = 1; istim <= my numberOfDifferentStimuli; istim ++) my stimuli [offset + istim] = istim; do { permuteRandomly (me, offset + 1, offset + my numberOfDifferentStimuli); } while (ireplica != 1 && my stimuli [offset + 1] == my stimuli [offset] && my numberOfDifferentStimuli > 1); } } else if (my randomize == kExperiment_randomize_WITH_REPLACEMENT) { for (long itrial = 1; itrial <= my numberOfTrials; itrial ++) my stimuli [itrial] = NUMrandomInteger (1, my numberOfDifferentStimuli); } Melder_warningOn (); } catch (MelderError) { Melder_warningOn (); my numberOfTrials = 0; NUMvector_free (my stimuli, 1); my stimuli = nullptr; Melder_throw (me, U": not started."); } } static void playSound (ExperimentMFC me, Sound sound, Sound carrierBefore, Sound carrierAfter, double initialSilenceDuration, double finalSilenceDuration) { long numberOfSamplesWritten = 0; long initialSilenceSamples = lround (initialSilenceDuration / my samplePeriod); for (long channel = 1; channel <= my numberOfChannels; channel ++) { for (long i = 1; i <= initialSilenceSamples; i ++) { my playBuffer -> z [channel] [i] = 0.0; } } numberOfSamplesWritten += initialSilenceSamples; if (carrierBefore) { for (long channel = 1; channel <= my numberOfChannels; channel ++) { NUMvector_copyElements (carrierBefore -> z [channel], my playBuffer -> z [channel] + numberOfSamplesWritten, 1, carrierBefore -> nx); } numberOfSamplesWritten += carrierBefore -> nx; } if (sound) { for (long channel = 1; channel <= my numberOfChannels; channel ++) { NUMvector_copyElements (sound -> z [channel], my playBuffer -> z [channel] + numberOfSamplesWritten, 1, sound -> nx); } numberOfSamplesWritten += sound -> nx; } if (carrierAfter) { for (long channel = 1; channel <= my numberOfChannels; channel ++) { NUMvector_copyElements (carrierAfter -> z [channel], my playBuffer -> z [channel] + numberOfSamplesWritten, 1, carrierAfter -> nx); } numberOfSamplesWritten += carrierAfter -> nx; } long finalSilenceSamples = lround (finalSilenceDuration / my samplePeriod); for (long channel = 1; channel <= my numberOfChannels; channel ++) { for (long i = 1; i <= finalSilenceSamples; i ++) { my playBuffer -> z [channel] [i + numberOfSamplesWritten] = 0.0; } } numberOfSamplesWritten += finalSilenceSamples; if (! my blankWhilePlaying) my startingTime = Melder_clock (); Sound_playPart (my playBuffer.get(), 0.0, numberOfSamplesWritten * my samplePeriod, 0, nullptr); if (my blankWhilePlaying) my startingTime = Melder_clock (); } void ExperimentMFC_playStimulus (ExperimentMFC me, long istim) { playSound (me, my stimulus [istim]. sound, my stimulusCarrierBefore. sound, my stimulusCarrierAfter. sound, my stimulusInitialSilenceDuration, my stimulusFinalSilenceDuration); } void ExperimentMFC_playResponse (ExperimentMFC me, long iresp) { playSound (me, my response [iresp]. sound, my responseCarrierBefore. sound, my responseCarrierAfter. sound, my responseInitialSilenceDuration, my responseFinalSilenceDuration); } Thing_implement (ResultsMFC, Daata, 2); ResultsMFC ResultsMFC_create (long numberOfTrials) { try { autoResultsMFC me = Thing_new (ResultsMFC); my numberOfTrials = numberOfTrials; my result = NUMvector (1, my numberOfTrials); return me.transfer(); } catch (MelderError) { Melder_throw (U"ResultsMFC not created."); } } ResultsMFC ExperimentMFC_extractResults (ExperimentMFC me) { try { if (my trial == 0 || my trial <= my numberOfTrials) Melder_warning (U"The experiment was not finished. Only the first ", my trial - 1 + my pausing, U" responses are valid."); autoResultsMFC thee = ResultsMFC_create (my numberOfTrials); for (long trial = 1; trial <= my numberOfTrials; trial ++) { char32 *pipe = my stimulus [my stimuli [trial]]. visibleText ? str32chr (my stimulus [my stimuli [trial]]. visibleText, U'|') : nullptr; thy result [trial]. stimulus = Melder_dup (Melder_cat (my stimulus [my stimuli [trial]]. name, pipe)); //if (my responses [trial] < 1) Melder_throw (U"No response for trial ", trial, U".") thy result [trial]. response = Melder_dup (my responses [trial] ? my response [my responses [trial]]. name : U""); thy result [trial]. goodness = my goodnesses [trial]; thy result [trial]. reactionTime = my reactionTimes [trial]; } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": results not extracted."); } } ResultsMFC ResultsMFC_removeUnsharedStimuli (ResultsMFC me, ResultsMFC thee) { try { autoResultsMFC him = ResultsMFC_create (thy numberOfTrials); his numberOfTrials = 0; for (long i = 1; i <= thy numberOfTrials; i ++) { bool present = false; for (long j = 1; j <= my numberOfTrials; j ++) { if (str32equ (thy result [i]. stimulus, my result [j]. stimulus)) { present = true; break; } } if (present) { his numberOfTrials ++; his result [his numberOfTrials]. stimulus = Melder_dup (thy result [i]. stimulus); his result [his numberOfTrials]. response = Melder_dup (thy result [i]. response); } } if (his numberOfTrials == 0) Melder_throw (U"No shared stimuli."); return him.transfer(); } catch (MelderError) { Melder_throw (me, U" & ", thee, U": unshared stimuli not removed."); } } Table ResultsMFCs_to_Table (Collection me) { try { long irow = 0; bool hasGoodnesses = false, hasReactionTimes = false; for (long iresults = 1; iresults <= my size; iresults ++) { ResultsMFC results = (ResultsMFC) my item [iresults]; for (long itrial = 1; itrial <= results -> numberOfTrials; itrial ++) { irow ++; if (results -> result [itrial]. goodness != 0) hasGoodnesses = true; if (results -> result [itrial]. reactionTime != 0.0) hasReactionTimes = true; } } autoTable thee = Table_create (irow, 3 + hasGoodnesses + hasReactionTimes); Table_setColumnLabel (thee.peek(), 1, U"subject"); Table_setColumnLabel (thee.peek(), 2, U"stimulus"); Table_setColumnLabel (thee.peek(), 3, U"response"); if (hasGoodnesses) Table_setColumnLabel (thee.peek(), 4, U"goodness"); if (hasReactionTimes) Table_setColumnLabel (thee.peek(), 4 + hasGoodnesses, U"reactionTime"); irow = 0; for (long iresults = 1; iresults <= my size; iresults ++) { ResultsMFC results = (ResultsMFC) my item [iresults]; for (long itrial = 1; itrial <= results -> numberOfTrials; itrial ++) { irow ++; Table_setStringValue (thee.peek(), irow, 1, results -> name); Table_setStringValue (thee.peek(), irow, 2, results -> result [itrial]. stimulus); Table_setStringValue (thee.peek(), irow, 3, results -> result [itrial]. response); if (hasGoodnesses) { Table_setNumericValue (thee.peek(), irow, 4, results -> result [itrial]. goodness); } if (hasReactionTimes) { Table_setNumericValue (thee.peek(), irow, 4 + hasGoodnesses, results -> result [itrial]. reactionTime); } } } return thee.transfer(); } catch (MelderError) { Melder_throw (U"ResultsMFC objects not collected to Table."); } } Categories ResultsMFC_to_Categories_stimuli (ResultsMFC me) { try { autoCategories thee = Categories_create (); for (long trial = 1; trial <= my numberOfTrials; trial ++) { autoSimpleString category = SimpleString_create (my result [trial]. stimulus); Collection_addItem (thee.peek(), category.transfer()); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": stimuli not converted to Categories."); } } Categories ResultsMFC_to_Categories_responses (ResultsMFC me) { try { autoCategories thee = Categories_create (); for (long trial = 1; trial <= my numberOfTrials; trial ++) { autoSimpleString category = SimpleString_create (my result [trial]. response); Collection_addItem (thee.peek(), category.transfer()); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": responses not converted to Categories."); } } static int compare (SimpleString me, SimpleString thee) { return str32cmp (my string, thy string); } void Categories_sort (Categories me) { NUMsort_p (my size, my item, (int (*) (const void *, const void *)) compare); } double Categories_getEntropy (Categories me) { long numberOfTokens = 0; char32 *previousString = nullptr; double entropy = 0.0; autoCategories thee = Data_copy (me); Categories_sort (thee.peek()); for (long i = 1; i <= thy size; i ++) { SimpleString s = (SimpleString) thy item [i]; char32 *string = s -> string; if (previousString && ! str32equ (string, previousString)) { double p = (double) numberOfTokens / thy size; entropy -= p * NUMlog2 (p); numberOfTokens = 1; } else { numberOfTokens ++; } previousString = string; } if (numberOfTokens) { double p = (double) numberOfTokens / thy size; entropy -= p * NUMlog2 (p); } return entropy; } /* End of file ExperimentMFC.cpp */ praat-6.0.04/fon/ExperimentMFC.h000066400000000000000000000032221261542461700163200ustar00rootroot00000000000000#ifndef _ExperimentMFC_h_ #define _ExperimentMFC_h_ /* ExperimentMFC.h * * Copyright (C) 2001-2011 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Sound.h" #include "Categories.h" #include "Table.h" #include "Experiment_enums.h" #include "ExperimentMFC_def.h" oo_CLASS_CREATE (ExperimentMFC, Daata); oo_CLASS_CREATE (ResultsMFC, Daata); void ExperimentMFC_start (ExperimentMFC me); void ExperimentMFC_playStimulus (ExperimentMFC me, long istim); void ExperimentMFC_playResponse (ExperimentMFC me, long iresp); ResultsMFC ResultsMFC_create (long numberOfResults); ResultsMFC ExperimentMFC_extractResults (ExperimentMFC me); ResultsMFC ResultsMFC_removeUnsharedStimuli (ResultsMFC me, ResultsMFC thee); Table ResultsMFCs_to_Table (Collection me); Categories ResultsMFC_to_Categories_stimuli (ResultsMFC me); Categories ResultsMFC_to_Categories_responses (ResultsMFC me); void Categories_sort (Categories me); double Categories_getEntropy (Categories me); /* End of file ExperimentMFC.h */ #endif praat-6.0.04/fon/ExperimentMFC_def.h000066400000000000000000000125701261542461700171440ustar00rootroot00000000000000/* ExperimentMFC_def.h * * Copyright (C) 2001-2011,2013,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2003/02/07 added rootDirectory * pb 2003/03/08 added stimulusMedialSilenceDuration and stimulusInitialSilenceDuration (version 2) * pb 2004/06/22 added response key (version 3) * pb 2005/11/21 added replayButton (version 4) * pb 2005/12/04 added okButton and oopsButton (version 4) * pb 2005/12/06 fix stimuliAreSounds: defaults to TRUE * pb 2007/08/12 wchar * pb 2007/09/26 added font size (version 5) * pb 2011/03/03 added reaction time (version 2 of ResultsMFC) * pb 2013/01/01 added finalSilenceDuration and blankWhilePlaying (version 6) */ /********* class ExperimentMFC **********/ #define ooSTRUCT SoundMFC oo_DEFINE_STRUCT (SoundMFC) oo_STRING (name) #if !oo_READING && !oo_WRITING oo_OBJECT (Sound, 0, sound) #endif oo_END_STRUCT (SoundMFC) #undef ooSTRUCT #define ooSTRUCT StimulusMFC oo_DEFINE_STRUCT (StimulusMFC) oo_STRING (name) oo_FROM (4) oo_STRING (visibleText) oo_ENDFROM #if !oo_READING && !oo_WRITING oo_OBJECT (Sound, 0, sound) #endif oo_END_STRUCT (StimulusMFC) #undef ooSTRUCT #define ooSTRUCT ResponseMFC oo_DEFINE_STRUCT (ResponseMFC) oo_FLOAT (left) oo_FLOAT (right) oo_FLOAT (bottom) oo_FLOAT (top) oo_STRING (label) oo_FROM (5) oo_INT (fontSize) oo_ENDFROM oo_FROM (3) oo_STRING (key) oo_ENDFROM oo_STRING (name) #if !oo_READING && !oo_WRITING oo_OBJECT (Sound, 0, sound) #endif oo_END_STRUCT (ResponseMFC) #undef ooSTRUCT #define ooSTRUCT GoodnessMFC oo_DEFINE_STRUCT (GoodnessMFC) oo_FLOAT (left) oo_FLOAT (right) oo_FLOAT (bottom) oo_FLOAT (top) oo_STRING (label) oo_END_STRUCT (GoodnessMFC) #undef ooSTRUCT #define ooSTRUCT ExperimentMFC oo_DEFINE_CLASS (ExperimentMFC, Daata) oo_FROM (6) oo_QUESTION (blankWhilePlaying) oo_ENDFROM oo_FROM (4) oo_QUESTION (stimuliAreSounds) oo_ENDFROM oo_STRING (stimulusFileNameHead) oo_STRING (stimulusFileNameTail) oo_STRUCT (SoundMFC, stimulusCarrierBefore) oo_STRUCT (SoundMFC, stimulusCarrierAfter) oo_FROM (2) oo_DOUBLE (stimulusInitialSilenceDuration) oo_DOUBLE (stimulusMedialSilenceDuration) oo_ENDFROM oo_FROM (6) oo_DOUBLE (stimulusFinalSilenceDuration) oo_ENDFROM oo_LONG (numberOfDifferentStimuli) oo_STRUCT_VECTOR (StimulusMFC, stimulus, numberOfDifferentStimuli) oo_LONG (numberOfReplicationsPerStimulus) oo_LONG (breakAfterEvery) oo_ENUM (kExperiment_randomize, randomize) oo_STRING (startText) oo_STRING (runText) oo_STRING (pauseText) oo_STRING (endText) oo_FROM (4) oo_LONG (maximumNumberOfReplays) oo_FLOAT (replay_left) oo_FLOAT (replay_right) oo_FLOAT (replay_bottom) oo_FLOAT (replay_top) oo_STRING (replay_label) oo_STRING (replay_key) oo_FLOAT (ok_left) oo_FLOAT (ok_right) oo_FLOAT (ok_bottom) oo_FLOAT (ok_top) oo_STRING (ok_label) oo_STRING (ok_key) oo_FLOAT (oops_left) oo_FLOAT (oops_right) oo_FLOAT (oops_bottom) oo_FLOAT (oops_top) oo_STRING (oops_label) oo_STRING (oops_key) oo_ENDFROM oo_FROM (4) oo_QUESTION (responsesAreSounds) oo_STRING (responseFileNameHead) oo_STRING (responseFileNameTail) oo_STRUCT (SoundMFC, responseCarrierBefore) oo_STRUCT (SoundMFC, responseCarrierAfter) oo_DOUBLE (responseInitialSilenceDuration) oo_DOUBLE (responseMedialSilenceDuration) oo_ENDFROM oo_FROM (6) oo_DOUBLE (responseFinalSilenceDuration) oo_ENDFROM oo_LONG (numberOfDifferentResponses) oo_STRUCT_VECTOR (ResponseMFC, response, numberOfDifferentResponses) oo_FROM (1) oo_LONG (numberOfGoodnessCategories) oo_STRUCT_VECTOR (GoodnessMFC, goodness, numberOfGoodnessCategories) oo_ENDFROM #if !oo_READING && !oo_WRITING oo_DOUBLE (samplePeriod) oo_INT (numberOfChannels) oo_BOOLEAN (pausing) oo_LONG (trial) oo_LONG (numberOfTrials) oo_LONG_VECTOR (stimuli, numberOfTrials) oo_LONG_VECTOR (responses, numberOfTrials) oo_DOUBLE_VECTOR (goodnesses, numberOfTrials) oo_DOUBLE (startingTime) oo_DOUBLE_VECTOR (reactionTimes, numberOfTrials) oo_AUTO_OBJECT (Sound, 0, playBuffer) #endif oo_DIR (rootDirectory) #if oo_READING MelderDir_copy (& Data_directoryBeingRead, & rootDirectory); if (formatVersion < 4) stimuliAreSounds = true; #endif oo_END_CLASS (ExperimentMFC) #undef ooSTRUCT /********** class ResultsMFC **********/ #define ooSTRUCT TrialMFC oo_DEFINE_STRUCT (TrialMFC) oo_STRING (stimulus) oo_STRING (response) oo_FROM (1) oo_DOUBLE (goodness) oo_ENDFROM oo_FROM (2) oo_DOUBLE (reactionTime) oo_ENDFROM oo_END_STRUCT (TrialMFC) #undef ooSTRUCT #define ooSTRUCT ResultsMFC oo_DEFINE_CLASS (ResultsMFC, Daata) oo_LONG (numberOfTrials) oo_STRUCT_VECTOR (TrialMFC, result, numberOfTrials) oo_END_CLASS (ResultsMFC) #undef ooSTRUCT /* End of file ExperimentMFC_def.h */ praat-6.0.04/fon/Experiment_enums.h000066400000000000000000000024371261542461700172100ustar00rootroot00000000000000/* Experiment_enums.h * * Copyright (C) 2001-2009,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ enums_begin (kExperiment_randomize, 0) enums_add (kExperiment_randomize, 0, CYCLIC_NON_RANDOM, U"CyclicNonRandom") enums_add (kExperiment_randomize, 1, PERMUTE_ALL, U"PermuteAll") enums_add (kExperiment_randomize, 2, PERMUTE_BALANCED, U"PermuteBalanced") enums_add (kExperiment_randomize, 3, PERMUTE_BALANCED_NO_DOUBLETS, U"PermuteBalancedNoDoublets") enums_add (kExperiment_randomize, 4, WITH_REPLACEMENT, U"WithReplacement") enums_end (kExperiment_randomize, 4, PERMUTE_BALANCED_NO_DOUBLETS) /* End of file Experiment_enums.h */ praat-6.0.04/fon/Formant.cpp000066400000000000000000000515631261542461700156260ustar00rootroot00000000000000/* Formant.cpp * * Copyright (C) 1992-2012,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2004/10/05 allow reverse axes in scatter plot (and remove special routine for those) * pb 2005/12/08 Formant_getQuantileOfBandwidth * pb 2007/03/17 domain quantity * pb 2007/10/01 can write as encoding * pb 2008/01/19 version 2 * pb 2008/01/19 don't draw undefined lines * pb 2008/06/01 Formant_downto_Table, Formant_list * pb 2009/01/18 Interpreter argument to formula * pb 2011/05/24 C++ */ #include "Formant.h" #include "oo_DESTROY.h" #include "Formant_def.h" #include "oo_COPY.h" #include "Formant_def.h" #include "oo_EQUAL.h" #include "Formant_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Formant_def.h" #include "oo_READ_TEXT.h" #include "Formant_def.h" #include "oo_WRITE_TEXT.h" #include "Formant_def.h" #include "oo_READ_BINARY.h" #include "Formant_def.h" #include "oo_WRITE_BINARY.h" #include "Formant_def.h" #include "oo_DESCRIPTION.h" #include "Formant_def.h" Thing_implement (Formant, Sampled, 2); // version 1 = with intensity, 2 = double void structFormant :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Time domain:"); MelderInfo_writeLine (U" Start time: ", xmin, U" seconds"); MelderInfo_writeLine (U" End time: ", xmax, U" seconds"); MelderInfo_writeLine (U" Total duration: ", xmax - xmin, U" seconds"); MelderInfo_writeLine (U"Time sampling:"); MelderInfo_writeLine (U" Number of frames: ", nx); MelderInfo_writeLine (U" Time step: ", dx, U" seconds"); MelderInfo_writeLine (U" First frame centred at: ", x1, U" seconds"); } double structFormant :: v_getValueAtSample (long iframe, long which, int units) { Formant_Frame frame = & d_frames [iframe]; long iformant = which >> 1; if (iformant < 1 || iformant > frame -> nFormants) return NUMundefined; double frequency = frame -> formant [iformant]. frequency; if ((which & 1) == 0) { return units ? NUMhertzToBark (frequency) : frequency; } else { double bandwidth = frame -> formant [iformant]. bandwidth; if (units) { double fleft = frequency - 0.5 * bandwidth, fright = frequency + 0.5 * bandwidth; fleft = fleft <= 0 ? 0 : NUMhertzToBark (fleft); // prevent NUMundefined fright = NUMhertzToBark (fright); return fright - fleft; } return bandwidth; } return NUMundefined; } autoFormant Formant_create (double tmin, double tmax, long nt, double dt, double t1, int maxnFormants) { try { autoFormant me = Thing_new (Formant); Sampled_init (me.peek(), tmin, tmax, nt, dt, t1); my d_frames = NUMvector (1, nt); my maxnFormants = maxnFormants; return me; } catch (MelderError) { Melder_throw (U"Formant object not created."); } } long Formant_getMinNumFormants (Formant me) { long minNumFormants = 100000000; for (long iframe = 1; iframe <= my nx; iframe ++) if (my d_frames [iframe]. nFormants < minNumFormants) minNumFormants = my d_frames [iframe]. nFormants; return minNumFormants; } long Formant_getMaxNumFormants (Formant me) { long maxNumFormants = 0; for (long iframe = 1; iframe <= my nx; iframe ++) if (my d_frames [iframe]. nFormants > maxNumFormants) maxNumFormants = my d_frames [iframe]. nFormants; return maxNumFormants; } void Formant_drawTracks (Formant me, Graphics g, double tmin, double tmax, double fmax, int garnish) { long itmin, itmax, ntrack = Formant_getMinNumFormants (me); if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } if (! Sampled_getWindowSamples (me, tmin, tmax, & itmin, & itmax)) return; Graphics_setInner (g); Graphics_setWindow (g, tmin, tmax, 0.0, fmax); for (long itrack = 1; itrack <= ntrack; itrack ++) { for (long iframe = itmin; iframe < itmax; iframe ++) { Formant_Frame curFrame = & my d_frames [iframe], nextFrame = & my d_frames [iframe + 1]; double x1 = Sampled_indexToX (me, iframe), x2 = Sampled_indexToX (me, iframe + 1); double f1 = curFrame -> formant [itrack]. frequency; double f2 = nextFrame -> formant [itrack]. frequency; if (NUMdefined (x1) && NUMdefined (f1) && NUMdefined (x2) && NUMdefined (f2)) Graphics_line (g, x1, f1, x2, f2); } } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Time (s)"); Graphics_textLeft (g, true, U"Formant frequency (Hz)"); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeftEvery (g, 1.0, 1000.0, true, true, true); } } void Formant_drawSpeckles_inside (Formant me, Graphics g, double tmin, double tmax, double fmin, double fmax, double suppress_dB) { long itmin, itmax; double maximumIntensity = 0.0, minimumIntensity; if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } if (! Sampled_getWindowSamples (me, tmin, tmax, & itmin, & itmax)) return; Graphics_setWindow (g, tmin, tmax, fmin, fmax); for (long iframe = itmin; iframe <= itmax; iframe ++) { Formant_Frame frame = & my d_frames [iframe]; if (frame -> intensity > maximumIntensity) maximumIntensity = frame -> intensity; } if (maximumIntensity == 0.0 || suppress_dB <= 0.0) minimumIntensity = 0.0; // ignore else minimumIntensity = maximumIntensity / pow (10.0, suppress_dB / 10.0); for (long iframe = itmin; iframe <= itmax; iframe ++) { Formant_Frame frame = & my d_frames [iframe]; double x = Sampled_indexToX (me, iframe); if (frame -> intensity < minimumIntensity) continue; for (long iformant = 1; iformant <= frame -> nFormants; iformant ++) { double frequency = frame -> formant [iformant]. frequency; if (frequency >= fmin && frequency <= fmax) Graphics_speckle (g, x, frequency); } } } void Formant_drawSpeckles (Formant me, Graphics g, double tmin, double tmax, double fmax, double suppress_dB, int garnish) { Graphics_setInner (g); Formant_drawSpeckles_inside (me, g, tmin, tmax, 0.0, fmax, suppress_dB); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Time (s)"); Graphics_textLeft (g, true, U"Formant frequency (Hz)"); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeftEvery (g, 1.0, 1000.0, true, true, true); } } void Formant_formula_bandwidths (Formant me, const char32 *formula, Interpreter interpreter) { try { long nrow = Formant_getMaxNumFormants (me); if (nrow < 1) Melder_throw (U"No formants available."); autoMatrix mat = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, 0.5, nrow + 0.5, nrow, 1.0, 1.0); for (long iframe = 1; iframe <= my nx; iframe ++) { Formant_Frame frame = & my d_frames [iframe]; for (long iformant = 1; iformant <= frame -> nFormants; iformant ++) mat -> z [iformant] [iframe] = frame -> formant [iformant]. bandwidth; } Matrix_formula (mat.peek(), formula, interpreter, nullptr); for (long iframe = 1; iframe <= my nx; iframe ++) { Formant_Frame frame = & my d_frames [iframe]; for (long iformant = 1; iformant <= frame -> nFormants; iformant ++) frame -> formant [iformant]. bandwidth = mat -> z [iformant] [iframe]; } } catch (MelderError) { Melder_throw (me, U": bandwidth formula not executed."); } } void Formant_formula_frequencies (Formant me, const char32 *formula, Interpreter interpreter) { try { long nrow = Formant_getMaxNumFormants (me); if (nrow < 1) Melder_throw (U"No formants available."); autoMatrix mat = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, 0.5, nrow + 0.5, nrow, 1.0, 1.0); for (long iframe = 1; iframe <= my nx; iframe ++) { Formant_Frame frame = & my d_frames [iframe]; for (long iformant = 1; iformant <= frame -> nFormants; iformant ++) mat -> z [iformant] [iframe] = frame -> formant [iformant]. frequency; } Matrix_formula (mat.peek(), formula, interpreter, nullptr); for (long iframe = 1; iframe <= my nx; iframe ++) { Formant_Frame frame = & my d_frames [iframe]; for (long iformant = 1; iformant <= frame -> nFormants; iformant ++) frame -> formant [iformant]. frequency = mat -> z [iformant] [iframe]; } } catch (MelderError) { Melder_throw (me, U": frequency formula not executed."); } } void Formant_getExtrema (Formant me, int iformant, double tmin, double tmax, double *fmin, double *fmax) { long itmin, itmax, iframe; if (fmin) *fmin = 0.0; if (fmax) *fmax = 0.0; if (iformant < 1) return; if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } if (! Sampled_getWindowSamples (me, tmin, tmax, & itmin, & itmax)) return; for (iframe = itmin; iframe <= itmax; iframe ++) { Formant_Frame frame = & my d_frames [iframe]; double f; if (iformant > frame -> nFormants) continue; f = frame -> formant [iformant]. frequency; if (f == 0.0) continue; if (fmin) if (f < *fmin || *fmin == 0.0) *fmin = f; if (fmax) if (f > *fmax) *fmax = f; } } void Formant_getMinimumAndTime (Formant me, int iformant, double tmin, double tmax, int bark, int interpolate, double *return_minimum, double *return_timeOfMinimum) { Sampled_getMinimumAndX (me, tmin, tmax, iformant << 1, bark, interpolate, return_minimum, return_timeOfMinimum); if (return_minimum && *return_minimum <= 0.0) *return_minimum = NUMundefined; } double Formant_getMinimum (Formant me, int iformant, double tmin, double tmax, int bark, int interpolate) { double minimum; Formant_getMinimumAndTime (me, iformant, tmin, tmax, bark, interpolate, & minimum, nullptr); return minimum; } double Formant_getTimeOfMinimum (Formant me, int iformant, double tmin, double tmax, int bark, int interpolate) { double time; Formant_getMinimumAndTime (me, iformant, tmin, tmax, bark, interpolate, nullptr, & time); return time; } void Formant_getMaximumAndTime (Formant me, int iformant, double tmin, double tmax, int bark, int interpolate, double *return_maximum, double *return_timeOfMaximum) { Sampled_getMaximumAndX (me, tmin, tmax, iformant << 1, bark, interpolate, return_maximum, return_timeOfMaximum); if (return_maximum && *return_maximum <= 0.0) *return_maximum = NUMundefined; // unlikely } double Formant_getMaximum (Formant me, int iformant, double tmin, double tmax, int bark, int interpolate) { double maximum; Formant_getMaximumAndTime (me, iformant, tmin, tmax, bark, interpolate, & maximum, nullptr); return maximum; } double Formant_getTimeOfMaximum (Formant me, int iformant, double tmin, double tmax, int bark, int interpolate) { double time; Formant_getMaximumAndTime (me, iformant, tmin, tmax, bark, interpolate, nullptr, & time); return time; } double Formant_getQuantile (Formant me, int iformant, double quantile, double tmin, double tmax, int bark) { return Sampled_getQuantile (me, tmin, tmax, quantile, iformant << 1, bark); } double Formant_getMean (Formant me, int iformant, double tmin, double tmax, int bark) { return Sampled_getMean (me, tmin, tmax, iformant << 1, bark, true); } double Formant_getStandardDeviation (Formant me, int iformant, double tmin, double tmax, int bark) { if (iformant < 1 || tmin == NUMundefined || tmax == NUMundefined) return NUMundefined; if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } long itmin, itmax; if (! Sampled_getWindowSamples (me, tmin, tmax, & itmin, & itmax)) return NUMundefined; double mean = Formant_getMean (me, iformant, tmin, tmax, bark); double sum = 0.0; long n = 0; for (long iframe = itmin; iframe <= itmax; iframe ++) { Formant_Frame frame = & my d_frames [iframe]; if (iformant > frame -> nFormants) continue; double f = frame -> formant [iformant]. frequency; if (f == 0.0) continue; if (bark) f = NUMhertzToBark (f); n += 1; sum += (f - mean) * (f - mean); } if (n > 1) return sqrt (sum / (n - 1)); return NUMundefined; } double Formant_getValueAtTime (Formant me, int iformant, double time, int bark) { return Sampled_getValueAtX (me, time, iformant << 1, bark, true); } double Formant_getBandwidthAtTime (Formant me, int iformant, double time, int bark) { return Sampled_getValueAtX (me, time, (iformant << 1) + 1, bark, true); } double Formant_getQuantileOfBandwidth (Formant me, int iformant, double quantile, double tmin, double tmax, int bark) { return Sampled_getQuantile (me, tmin, tmax, quantile, (iformant << 1) + 1, bark); } void Formant_scatterPlot (Formant me, Graphics g, double tmin, double tmax, int iformant1, double fmin1, double fmax1, int iformant2, double fmin2, double fmax2, double size_mm, const char32 *mark, int garnish) { if (iformant1 < 1 || iformant2 < 1) return; if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } long itmin, itmax; if (! Sampled_getWindowSamples (me, tmin, tmax, & itmin, & itmax)) return; if (fmax1 == fmin1) Formant_getExtrema (me, iformant1, tmin, tmax, & fmin1, & fmax1); if (fmax1 == fmin1) return; if (fmax2 == fmin2) Formant_getExtrema (me, iformant2, tmin, tmax, & fmin2, & fmax2); if (fmax2 == fmin2) return; Graphics_setInner (g); Graphics_setWindow (g, fmin1, fmax1, fmin2, fmax2); for (long iframe = itmin; iframe <= itmax; iframe ++) { Formant_Frame frame = & my d_frames [iframe]; if (iformant1 > frame -> nFormants || iformant2 > frame -> nFormants) continue; double x = frame -> formant [iformant1]. frequency; double y = frame -> formant [iformant2]. frequency; if (x == 0.0 || y == 0.0) continue; Graphics_mark (g, x, y, size_mm, mark); } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, Melder_cat (U"%%F_", iformant1, U" (Hz)")); Graphics_textLeft (g, true, Melder_cat (U"%%F_", iformant2, U" (Hz)")); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); } } autoMatrix Formant_to_Matrix (Formant me, int iformant) { try { autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, 1.0, 1.0, 1, 1.0, 1.0); for (long iframe = 1; iframe <= my nx; iframe ++) { Formant_Frame frame = & my d_frames [iframe]; thy z [1] [iframe] = iformant <= frame -> nFormants ? frame -> formant [iformant]. frequency : 0.0; } return thee; } catch (MelderError) { Melder_throw (me, U": frequencies of formant ", iformant, U" not converted to Matrix."); } } autoMatrix Formant_to_Matrix_bandwidths (Formant me, int iformant) { try { autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, 1.0, 1.0, 1, 1.0, 1.0); for (long iframe = 1; iframe <= my nx; iframe ++) { Formant_Frame frame = & my d_frames [iframe]; thy z [1] [iframe] = iformant <= frame -> nFormants ? frame -> formant [iformant]. bandwidth : 0.0; } return thee; } catch (MelderError) { Melder_throw (me, U": bandwidths of formant ", iformant, U" not converted to Matrix."); } } /*** Viterbi methods. ***/ struct fparm { Formant me, thee; double dfCost, bfCost, octaveJumpCost, refF [1 + 5]; }; static double getLocalCost (long iframe, long icand, int itrack, void *closure) { struct fparm *me = (struct fparm *) closure; Formant_Frame frame = & my my d_frames [iframe]; Formant_Formant candidate; if (icand > frame -> nFormants) return 1e30; candidate = & frame -> formant [icand]; /*if (candidate -> frequency <= 0.0) candidate -> frequency = 0.001; Melder_fatal (U"Weird formant frequency ", candidate -> frequency, U" Hz.")*/; Melder_assert (candidate -> bandwidth > 0.0); Melder_assert (itrack > 0 && itrack <= 5); return my dfCost * fabs (candidate -> frequency - my refF [itrack]) + my bfCost * candidate -> bandwidth / candidate -> frequency; } static double getTransitionCost (long iframe, long icand1, long icand2, int itrack, void *closure) { struct fparm *me = (struct fparm *) closure; Formant_Frame prevFrame = & my my d_frames [iframe - 1], curFrame = & my my d_frames [iframe]; double f1, f2; (void) itrack; if (icand1 > prevFrame -> nFormants || icand2 > curFrame -> nFormants) return 1e30; f1 = prevFrame -> formant [icand1]. frequency; f2 = curFrame -> formant [icand2]. frequency; /*Melder_assert (f1 > 0.0);*/ /*Melder_assert (f2 > 0.0);*/ return my octaveJumpCost * fabs (NUMlog2 (f1 / f2)); } static void putResult (long iframe, long place, int itrack, void *closure) { struct fparm *me = (struct fparm *) closure; Melder_assert (iframe > 0 && iframe <= my my nx); Melder_assert (itrack > 0 && itrack <= 5); Melder_assert (place > 0); Melder_assert (place <= my my d_frames [iframe]. nFormants); my thy d_frames [iframe]. formant [itrack] = my my d_frames [iframe]. formant [place]; } autoFormant Formant_tracker (Formant me, int ntrack, double refF1, double refF2, double refF3, double refF4, double refF5, double dfCost, /* Per kHz. */ double bfCost, double octaveJumpCost) { try { long nformmin = Formant_getMinNumFormants (me); struct fparm parm; if (ntrack > nformmin) Melder_throw (U"Number of tracks (", ntrack, U") should not exceed minimum number of formants (", nformmin, U")."); autoFormant thee = Formant_create (my xmin, my xmax, my nx, my dx, my x1, ntrack); for (long iframe = 1; iframe <= thy nx; iframe ++) { thy d_frames [iframe]. formant = NUMvector (1, ntrack); thy d_frames [iframe]. nFormants = ntrack; thy d_frames [iframe]. intensity = my d_frames [iframe]. intensity; } /* BUG: limit costs to 1e10 or so */ parm.me = me; parm.thee = thee.peek(); parm.dfCost = dfCost / 1000.0; // per Hz parm.bfCost = bfCost; parm.octaveJumpCost = octaveJumpCost; parm.refF [1] = refF1; parm.refF [2] = refF2; parm.refF [3] = refF3; parm.refF [4] = refF4; parm.refF [5] = refF5; NUM_viterbi_multi (my nx, my maxnFormants, ntrack, getLocalCost, getTransitionCost, putResult, & parm); return thee; } catch (MelderError) { Melder_throw (me, U": not tracked."); } } autoTable Formant_downto_Table (Formant me, bool includeFrameNumbers, bool includeTimes, int timeDecimals, bool includeIntensity, int intensityDecimals, bool includeNumberOfFormants, int frequencyDecimals, bool includeBandwidths) { try { autoTable thee = Table_createWithoutColumnNames (my nx, includeFrameNumbers + includeTimes + includeIntensity + includeNumberOfFormants + my maxnFormants * (1 + includeBandwidths)); long icol = 0; if (includeFrameNumbers) Table_setColumnLabel (thee.peek(), ++ icol, U"frame"); if (includeTimes) Table_setColumnLabel (thee.peek(), ++ icol, U"time(s)"); if (includeIntensity) Table_setColumnLabel (thee.peek(), ++ icol, U"intensity"); if (includeNumberOfFormants) Table_setColumnLabel (thee.peek(), ++ icol, U"nformants"); for (long iformant = 1; iformant <= my maxnFormants; iformant ++) { Table_setColumnLabel (thee.peek(), ++ icol, Melder_cat (U"F", iformant, U"(Hz)")); if (includeBandwidths) { Table_setColumnLabel (thee.peek(), ++ icol, Melder_cat (U"B", iformant, U"(Hz)")); } } for (long iframe = 1; iframe <= my nx; iframe ++) { icol = 0; if (includeFrameNumbers) Table_setNumericValue (thee.peek(), iframe, ++ icol, iframe); if (includeTimes) Table_setStringValue (thee.peek(), iframe, ++ icol, Melder_fixed (my x1 + (iframe - 1) * my dx, timeDecimals)); Formant_Frame frame = & my d_frames [iframe]; if (includeIntensity) Table_setStringValue (thee.peek(), iframe, ++ icol, Melder_fixed (frame -> intensity, intensityDecimals)); if (includeNumberOfFormants) Table_setNumericValue (thee.peek(), iframe, ++ icol, frame -> nFormants); for (long iformant = 1; iformant <= frame -> nFormants; iformant ++) { Formant_Formant formant = & frame -> formant [iformant]; Table_setStringValue (thee.peek(), iframe, ++ icol, Melder_fixed (formant -> frequency, frequencyDecimals)); if (includeBandwidths) Table_setStringValue (thee.peek(), iframe, ++ icol, Melder_fixed (formant -> bandwidth, frequencyDecimals)); } for (long iformant = frame -> nFormants + 1; iformant <= my maxnFormants; iformant ++) { Table_setNumericValue (thee.peek(), iframe, ++ icol, NUMundefined); if (includeBandwidths) Table_setNumericValue (thee.peek(), iframe, ++ icol, NUMundefined); } } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Table."); } } void Formant_list (Formant me, bool includeFrameNumbers, bool includeTimes, int timeDecimals, bool includeIntensity, int intensityDecimals, bool includeNumberOfFormants, int frequencyDecimals, bool includeBandwidths) { try { autoTable table = Formant_downto_Table (me, includeFrameNumbers, includeTimes, timeDecimals, includeIntensity, intensityDecimals, includeNumberOfFormants, frequencyDecimals, includeBandwidths); Table_list (table.peek(), false); } catch (MelderError) { Melder_throw (me, U": not listed."); } } /* End of file Formant.cpp */ praat-6.0.04/fon/Formant.h000066400000000000000000000110571261542461700152650ustar00rootroot00000000000000#ifndef _Formant_h_ #define _Formant_h_ /* Formant.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Matrix.h" #include "Table.h" #include "Interpreter_decl.h" #include "Formant_def.h" oo_CLASS_CREATE (Formant, Sampled); autoFormant Formant_create (double tmin, double tmax, long nt, double dt, double t1, int maxnFormants); /* Function: return a new instance of Formant. Preconditions: nt >= 1; dt > 0.0; maxnFormants >= 1; Postconditions: my xmin = tmin; my xmax = tmax; my nx = nt; my dx = dt; my x1 = t1; my maximumNumberOfPairs == maxnFormants; my frames [1..nt]. intensity == 0.0; my frames [1..nt]. numberOfPairs == 0; my frames [1..nt]. formants [1..maxnFormants] = 0.0; my frames [1..nt]. bandwidths [1..maxnFormants] = 0.0; */ long Formant_getMinNumFormants (Formant me); long Formant_getMaxNumFormants (Formant me); double Formant_getValueAtTime (Formant me, int iformant, double time, int bark); double Formant_getBandwidthAtTime (Formant me, int iformant, double time, int bark); void Formant_getExtrema (Formant me, int iformant, double tmin, double tmax, double *fmin, double *fmax); void Formant_getMinimumAndTime (Formant me, int iformant, double tmin, double tmax, int bark, int interpolate, double *return_minimum, double *return_timeOfMinimum); void Formant_getMaximumAndTime (Formant me, int iformant, double tmin, double tmax, int bark, int interpolate, double *return_maximum, double *return_timeOfMaximum); double Formant_getMinimum (Formant me, int iformant, double tmin, double tmax, int bark, int interpolate); double Formant_getMaximum (Formant me, int iformant, double tmin, double tmax, int bark, int interpolate); double Formant_getTimeOfMaximum (Formant me, int iformant, double tmin, double tmax, int bark, int interpolate); double Formant_getTimeOfMinimum (Formant me, int iformant, double tmin, double tmax, int bark, int interpolate); double Formant_getQuantile (Formant me, int iformant, double quantile, double tmin, double tmax, int bark); double Formant_getQuantileOfBandwidth (Formant me, int iformant, double quantile, double tmin, double tmax, int bark); double Formant_getMean (Formant me, int iformant, double tmin, double tmax, int bark); double Formant_getStandardDeviation (Formant me, int iformant, double tmin, double tmax, int bark); void Formant_sort (Formant me); void Formant_drawTracks (Formant me, Graphics g, double tmin, double tmax, double fmax, int garnish); void Formant_drawSpeckles_inside (Formant me, Graphics g, double tmin, double tmax, double fmin, double fmax, double suppress_dB); void Formant_drawSpeckles (Formant me, Graphics g, double tmin, double tmax, double fmax, double suppress_dB, int garnish); void Formant_scatterPlot (Formant me, Graphics g, double tmin, double tmax, int iformant1, double fmin1, double fmax1, int iformant2, double fmin2, double fmax2, double size_mm, const char32 *mark, int garnish); autoMatrix Formant_to_Matrix (Formant me, int iformant); autoMatrix Formant_to_Matrix_bandwidths (Formant me, int iformant); void Formant_formula_frequencies (Formant me, const char32 *formula, Interpreter interpreter); void Formant_formula_bandwidths (Formant me, const char32 *formula, Interpreter interpreter); autoFormant Formant_tracker (Formant me, int numberOfTracks, double refF1, double refF2, double refF3, double refF4, double refF5, double dfCost, // per kHz double bfCost, double octaveJumpCost); autoTable Formant_downto_Table (Formant me, bool includeFrameNumbers, bool includeTimes, int timeDecimals, bool includeIntensity, int intensityDecimals, bool includeNumberOfFormants, int frequencyDecimals, bool includeBandwidths); void Formant_list (Formant me, bool includeFrameNumbers, bool includeTimes, int timeDecimals, bool includeIntensity, int intensityDecimals, bool includeNumberOfFormants, int frequencyDecimals, bool includeBandwidths); /* End of file Formant.h */ #endif praat-6.0.04/fon/FormantGrid.cpp000066400000000000000000000332741261542461700164330ustar00rootroot00000000000000/* FormantGrid.cpp * * Copyright (C) 2008-2011,2014,2015 Paul Boersma & David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "FormantGrid.h" #include "PitchTier_to_Sound.h" #include "Formula.h" #include "oo_DESTROY.h" #include "FormantGrid_def.h" #include "oo_COPY.h" #include "FormantGrid_def.h" #include "oo_EQUAL.h" #include "FormantGrid_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "FormantGrid_def.h" #include "oo_WRITE_TEXT.h" #include "FormantGrid_def.h" #include "oo_READ_TEXT.h" #include "FormantGrid_def.h" #include "oo_WRITE_BINARY.h" #include "FormantGrid_def.h" #include "oo_READ_BINARY.h" #include "FormantGrid_def.h" #include "oo_DESCRIPTION.h" #include "FormantGrid_def.h" Thing_implement (FormantGrid, Function, 0); double structFormantGrid :: v_getVector (long irow, long icol) { RealTier tier = (RealTier) formants -> item [irow]; return RealTier_getValueAtIndex (tier, icol); } double structFormantGrid :: v_getFunction1 (long irow, double x) { RealTier tier = (RealTier) formants -> item [irow]; return RealTier_getValueAtTime (tier, x); } void structFormantGrid :: v_shiftX (double xfrom, double xto) { FormantGrid_Parent :: v_shiftX (xfrom, xto); for (long i = 1; i <= formants -> size; i ++) { RealTier tier = (RealTier) formants -> item [i]; tier -> v_shiftX (xfrom, xto); } for (long i = 1; i <= bandwidths -> size; i ++) { RealTier tier = (RealTier) bandwidths -> item [i]; tier -> v_shiftX (xfrom, xto); } } void structFormantGrid :: v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto) { FormantGrid_Parent :: v_scaleX (xminfrom, xmaxfrom, xminto, xmaxto); for (long i = 1; i <= formants -> size; i ++) { RealTier tier = (RealTier) formants -> item [i]; tier -> v_scaleX (xminfrom, xmaxfrom, xminto, xmaxto); } for (long i = 1; i <= bandwidths -> size; i ++) { RealTier tier = (RealTier) bandwidths -> item [i]; tier -> v_scaleX (xminfrom, xmaxfrom, xminto, xmaxto); } } void FormantGrid_init (FormantGrid me, double tmin, double tmax, long numberOfFormants) { my formants = Ordered_create (); my bandwidths = Ordered_create (); for (long iformant = 1; iformant <= numberOfFormants; iformant ++) { autoRealTier formant = RealTier_create (tmin, tmax); Collection_addItem (my formants, formant.transfer()); autoRealTier bandwidth = RealTier_create (tmin, tmax); Collection_addItem (my bandwidths, bandwidth.transfer()); } my xmin = tmin; my xmax = tmax; } autoFormantGrid FormantGrid_createEmpty (double tmin, double tmax, long numberOfFormants) { try { autoFormantGrid me = Thing_new (FormantGrid); FormantGrid_init (me.peek(), tmin, tmax, numberOfFormants); return me; } catch (MelderError) { Melder_throw (U"Empty FormantGrid not created."); } } autoFormantGrid FormantGrid_create (double tmin, double tmax, long numberOfFormants, double initialFirstFormant, double initialFormantSpacing, double initialFirstBandwidth, double initialBandwidthSpacing) { try { autoFormantGrid me = FormantGrid_createEmpty (tmin, tmax, numberOfFormants); for (long iformant = 1; iformant <= numberOfFormants; iformant ++) { FormantGrid_addFormantPoint (me.peek(), iformant, 0.5 * (tmin + tmax), initialFirstFormant + (iformant - 1) * initialFormantSpacing); FormantGrid_addBandwidthPoint (me.peek(), iformant, 0.5 * (tmin + tmax), initialFirstBandwidth + (iformant - 1) * initialBandwidthSpacing); } return me; } catch (MelderError) { Melder_throw (U"FormantGrid not created."); } } void FormantGrid_addFormantPoint (FormantGrid me, long iformant, double t, double value) { try { if (iformant < 1 || iformant > my formants -> size) Melder_throw (U"No such formant number."); RealTier formantTier = (RealTier) my formants -> item [iformant]; RealTier_addPoint (formantTier, t, value); } catch (MelderError) { Melder_throw (me, U": formant point not added."); } } void FormantGrid_addBandwidthPoint (FormantGrid me, long iformant, double t, double value) { try { if (iformant < 1 || iformant > my formants -> size) Melder_throw (U"No such formant number."); RealTier bandwidthTier = (RealTier) my bandwidths -> item [iformant]; RealTier_addPoint (bandwidthTier, t, value); } catch (MelderError) { Melder_throw (me, U": bandwidth point not added."); } } double FormantGrid_getFormantAtTime (FormantGrid me, long iformant, double t) { if (iformant < 1 || iformant > my formants -> size) return NUMundefined; return RealTier_getValueAtTime ((RealTier) my formants -> item [iformant], t); } double FormantGrid_getBandwidthAtTime (FormantGrid me, long iformant, double t) { if (iformant < 1 || iformant > my bandwidths -> size) return NUMundefined; return RealTier_getValueAtTime ((RealTier) my bandwidths -> item [iformant], t); } void FormantGrid_removeFormantPointsBetween (FormantGrid me, long iformant, double tmin, double tmax) { if (iformant < 1 || iformant > my formants -> size) return; AnyTier_removePointsBetween (my formants -> item [iformant], tmin, tmax); } void FormantGrid_removeBandwidthPointsBetween (FormantGrid me, long iformant, double tmin, double tmax) { if (iformant < 1 || iformant > my bandwidths -> size) return; AnyTier_removePointsBetween (my bandwidths -> item [iformant], tmin, tmax); } void Sound_FormantGrid_filter_inline (Sound me, FormantGrid formantGrid) { double dt = my dx; if (formantGrid -> formants -> size && formantGrid -> bandwidths -> size) for (long iformant = 1; iformant <= formantGrid -> formants -> size; iformant ++) { RealTier formantTier = (RealTier) formantGrid -> formants -> item [iformant]; RealTier bandwidthTier = (RealTier) formantGrid -> bandwidths -> item [iformant]; for (long isamp = 1; isamp <= my nx; isamp ++) { double t = my x1 + (isamp - 1) * my dx; /* * Compute LP coefficients. */ double formant, bandwidth; formant = RealTier_getValueAtTime (formantTier, t); bandwidth = RealTier_getValueAtTime (bandwidthTier, t); if (NUMdefined (formant) && NUMdefined (bandwidth)) { double cosomdt = cos (2 * NUMpi * formant * dt); double r = exp (- NUMpi * bandwidth * dt); /* Formants at 0 Hz or the Nyquist are single poles, others are double poles. */ if (fabs (cosomdt) > 0.999999) { /* Allow for round-off errors. */ /* single pole: D(z) = 1 - r z^-1 */ for (long channel = 1; channel <= my ny; channel ++) { if (isamp > 1) my z [channel] [isamp] += r * my z [channel] [isamp - 1]; } } else { /* double pole: D(z) = 1 + p z^-1 + q z^-2 */ double p = - 2 * r * cosomdt; double q = r * r; for (long channel = 1; channel <= my ny; channel ++) { if (isamp > 1) my z [channel] [isamp] -= p * my z [channel] [isamp - 1]; if (isamp > 2) my z [channel] [isamp] -= q * my z [channel] [isamp - 2]; } } } } } } autoSound Sound_FormantGrid_filter (Sound me, FormantGrid formantGrid) { try { autoSound thee = Data_copy (me); Sound_FormantGrid_filter_inline (thee.peek(), formantGrid); Vector_scale (thee.peek(), 0.99); return thee; } catch (MelderError) { Melder_throw (me, U": not filtered with ", formantGrid, U"."); } } autoSound Sound_FormantGrid_filter_noscale (Sound me, FormantGrid formantGrid) { try { autoSound thee = Data_copy (me); Sound_FormantGrid_filter_inline (thee.peek(), formantGrid); return thee; } catch (MelderError) { Melder_throw (me, U": not filtered with ", formantGrid, U"."); } } autoSound FormantGrid_to_Sound (FormantGrid me, double samplingFrequency, double tStart, double f0Start, double tMid, double f0Mid, double tEnd, double f0End, double adaptFactor, double maximumPeriod, double openPhase, double collisionPhase, double power1, double power2) { try { autoPitchTier pitch = PitchTier_create (my xmin, my xmax); RealTier_addPoint (pitch.peek(), my xmin + tStart * (my xmax - my xmin), f0Start); RealTier_addPoint (pitch.peek(), my xmin + tMid * (my xmax - my xmin), f0Mid); RealTier_addPoint (pitch.peek(), my xmax - (1.0 - tEnd) * (my xmax - my xmin), f0End); autoSound thee = PitchTier_to_Sound_phonation (pitch.peek(), samplingFrequency, adaptFactor, maximumPeriod, openPhase, collisionPhase, power1, power2, false); Sound_FormantGrid_filter_inline (thee.peek(), me); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Sound."); } } void FormantGrid_playPart (FormantGrid me, double tmin, double tmax, double samplingFrequency, double tStart, double f0Start, double tMid, double f0Mid, double tEnd, double f0End, double adaptFactor, double maximumPeriod, double openPhase, double collisionPhase, double power1, double power2, int (*playCallback) (void *playClosure, int phase, double tmin, double tmax, double t), void *playClosure) { try { autoSound sound = FormantGrid_to_Sound (me, samplingFrequency, tStart, f0Start, tMid, f0Mid, tEnd, f0End, adaptFactor, maximumPeriod, openPhase, collisionPhase, power1, power2); Vector_scale (sound.peek(), 0.99); Sound_playPart (sound.peek(), tmin, tmax, playCallback, playClosure); } catch (MelderError) { Melder_throw (me, U": not played."); } } void FormantGrid_formula_bandwidths (FormantGrid me, const char32 *expression, Interpreter interpreter, FormantGrid thee) { try { Formula_compile (interpreter, me, expression, kFormula_EXPRESSION_TYPE_NUMERIC, true); if (! thee) thee = me; for (long irow = 1; irow <= my formants -> size; irow ++) { RealTier bandwidth = (RealTier) thy bandwidths -> item [irow]; for (long icol = 1; icol <= bandwidth -> points -> size; icol ++) { struct Formula_Result result; Formula_run (irow, icol, & result); if (result. result.numericResult == NUMundefined) Melder_throw (U"Cannot put an undefined value into the tier.\nFormula not finished."); ((RealPoint) bandwidth -> points -> item [icol]) -> value = result. result.numericResult; } } } catch (MelderError) { Melder_throw (me, U": bandwidth formula not completed."); } } void FormantGrid_formula_frequencies (FormantGrid me, const char32 *expression, Interpreter interpreter, FormantGrid thee) { try { Formula_compile (interpreter, me, expression, kFormula_EXPRESSION_TYPE_NUMERIC, true); if (! thee) thee = me; for (long irow = 1; irow <= my formants -> size; irow ++) { RealTier formant = (RealTier) thy formants -> item [irow]; for (long icol = 1; icol <= formant -> points -> size; icol ++) { struct Formula_Result result; Formula_run (irow, icol, & result); if (result. result.numericResult == NUMundefined) Melder_throw (U"Cannot put an undefined value into the tier.\nFormula not finished."); ((RealPoint) formant -> points -> item [icol]) -> value = result. result.numericResult; } } } catch (MelderError) { Melder_throw (me, U": frequency formula not completed."); } } autoFormantGrid Formant_downto_FormantGrid (Formant me) { try { autoFormantGrid thee = FormantGrid_createEmpty (my xmin, my xmax, my maxnFormants); for (long iframe = 1; iframe <= my nx; iframe ++) { Formant_Frame frame = & my d_frames [iframe]; double t = Sampled_indexToX (me, iframe); for (long iformant = 1; iformant <= frame -> nFormants; iformant ++) { Formant_Formant pair = & frame -> formant [iformant]; FormantGrid_addFormantPoint (thee.peek(), iformant, t, pair -> frequency); FormantGrid_addBandwidthPoint (thee.peek(), iformant, t, pair -> bandwidth); } } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to FormantGrid."); } } autoFormant FormantGrid_to_Formant (FormantGrid me, double dt, double intensity) { try { Melder_assert (dt > 0.0); Melder_assert (intensity >= 0.0); long nt = (long) floor ((my xmax - my xmin) / dt) + 1; double t1 = 0.5 * (my xmin + my xmax - (nt - 1) * dt); autoFormant thee = Formant_create (my xmin, my xmax, nt, dt, t1, my formants -> size); for (long iframe = 1; iframe <= nt; iframe ++) { Formant_Frame frame = & thy d_frames [iframe]; frame -> intensity = intensity; frame -> nFormants = my formants -> size; frame -> formant = NUMvector (1, my formants -> size); double t = t1 + (iframe - 1) * dt; for (long iformant = 1; iformant <= my formants -> size; iformant ++) { Formant_Formant formant = & frame -> formant [iformant]; formant -> frequency = RealTier_getValueAtTime ((RealTier) my formants -> item [iformant], t); formant -> bandwidth = RealTier_getValueAtTime ((RealTier) my bandwidths -> item [iformant], t); } } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Formant."); } } autoSound Sound_Formant_filter (Sound me, Formant formant) { try { autoFormantGrid grid = Formant_downto_FormantGrid (formant); autoSound thee = Sound_FormantGrid_filter (me, grid.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": not filtered with ", formant, U"."); } } autoSound Sound_Formant_filter_noscale (Sound me, Formant formant) { try { autoFormantGrid grid = Formant_downto_FormantGrid (formant); autoSound thee = Sound_FormantGrid_filter_noscale (me, grid.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": not filtered with ", formant, U"."); } } /* End of file FormantGrid.cpp */ praat-6.0.04/fon/FormantGrid.h000066400000000000000000000065171261542461700161000ustar00rootroot00000000000000#ifndef _FormantGrid_h_ #define _FormantGrid_h_ /* FormantGrid.h * * Copyright (C) 2008-2011,2014,2015 Paul Boersma & David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "RealTier.h" #include "Sound.h" #include "Formant.h" Thing_declare (Interpreter); #include "FormantGrid_def.h" oo_CLASS_CREATE (FormantGrid, Function); void FormantGrid_init (FormantGrid me, double tmin, double tmax, long numberOfFormants); autoFormantGrid FormantGrid_createEmpty (double tmin, double tmax, long numberOfFormants); autoFormantGrid FormantGrid_create (double tmin, double tmax, long numberOfFormants, double initialFirstFormant, double initialFormantSpacing, double initialFirstBandwidth, double initialBandwidthSpacing); double FormantGrid_getFormantAtTime (FormantGrid me, long iformant, double t); double FormantGrid_getBandwidthAtTime (FormantGrid me, long iformant, double t); void FormantGrid_addFormantPoint (FormantGrid me, long iformant, double t, double value); void FormantGrid_addBandwidthPoint (FormantGrid me, long iformant, double t, double value); void FormantGrid_removeFormantPointsBetween (FormantGrid me, long iformant, double tmin, double tmax); void FormantGrid_removeBandwidthPointsBetween (FormantGrid me, long iformant, double tmin, double tmax); void Sound_FormantGrid_filter_inline (Sound me, FormantGrid formantGrid); autoSound Sound_FormantGrid_filter (Sound me, FormantGrid formantGrid); autoSound Sound_FormantGrid_filter_noscale (Sound me, FormantGrid formantGrid); autoSound FormantGrid_to_Sound (FormantGrid me, double samplingFrequency, double tStart, double f0Start, double tMid, double f0Mid, double tEnd, double f0End, double adaptFactor, double maximumPeriod, double openPhase, double collisionPhase, double power1, double power2); void FormantGrid_playPart (FormantGrid me, double tmin, double tmax, double samplingFrequency, double tStart, double f0Start, double tMid, double f0Mid, double tEnd, double f0End, double adaptFactor, double maximumPeriod, double openPhase, double collisionPhase, double power1, double power2, int (*playCallback) (void *playClosure, int phase, double tmin, double tmax, double t), void *playClosure); void FormantGrid_formula_frequencies (FormantGrid me, const char32 *expression, Interpreter interpreter, FormantGrid thee); void FormantGrid_formula_bandwidths (FormantGrid me, const char32 *expression, Interpreter interpreter, FormantGrid thee); autoFormantGrid Formant_downto_FormantGrid (Formant me); autoFormant FormantGrid_to_Formant (FormantGrid me, double dt, double intensity); autoSound Sound_Formant_filter (Sound me, Formant formant); autoSound Sound_Formant_filter_noscale (Sound me, Formant formant); /* End of file FormantGrid.h */ #endif praat-6.0.04/fon/FormantGridEditor.cpp000066400000000000000000000514101261542461700175720ustar00rootroot00000000000000/* FormantGridEditor.cpp * * Copyright (C) 2008-2011,2012,2013,2014,2015 Paul Boersma & David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "FormantGridEditor.h" #include "EditorM.h" #include "PointProcess_and_Sound.h" Thing_implement (FormantGridEditor, FunctionEditor, 0); #include "prefs_define.h" #include "FormantGridEditor_prefs.h" #include "prefs_install.h" #include "FormantGridEditor_prefs.h" #include "prefs_copyToInstance.h" #include "FormantGridEditor_prefs.h" /********** MENU COMMANDS **********/ static void menu_cb_removePoints (EDITOR_ARGS) { EDITOR_IAM (FormantGridEditor); Editor_save (me, U"Remove point(s)"); FormantGrid grid = (FormantGrid) my data; Ordered tiers = my editingBandwidths ? grid -> bandwidths : grid -> formants; RealTier tier = (RealTier) tiers -> item [my selectedFormant]; if (my d_startSelection == my d_endSelection) AnyTier_removePointNear (tier, my d_startSelection); else AnyTier_removePointsBetween (tier, my d_startSelection, my d_endSelection); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_addPointAtCursor (EDITOR_ARGS) { EDITOR_IAM (FormantGridEditor); Editor_save (me, U"Add point"); FormantGrid grid = (FormantGrid) my data; Ordered tiers = my editingBandwidths ? grid -> bandwidths : grid -> formants; RealTier tier = (RealTier) tiers -> item [my selectedFormant]; RealTier_addPoint (tier, 0.5 * (my d_startSelection + my d_endSelection), my ycursor); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_addPointAt (EDITOR_ARGS) { EDITOR_IAM (FormantGridEditor); EDITOR_FORM (U"Add point", 0) REAL (U"Time (s)", U"0.0") POSITIVE (U"Frequency (Hz)", U"200.0") EDITOR_OK SET_REAL (U"Time", 0.5 * (my d_startSelection + my d_endSelection)) SET_REAL (U"Frequency", my ycursor) EDITOR_DO Editor_save (me, U"Add point"); FormantGrid grid = (FormantGrid) my data; Ordered tiers = my editingBandwidths ? grid -> bandwidths : grid -> formants; RealTier tier = (RealTier) tiers -> item [my selectedFormant]; RealTier_addPoint (tier, GET_REAL (U"Time"), GET_REAL (U"Frequency")); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); EDITOR_END } static void menu_cb_setFormantRange (EDITOR_ARGS) { EDITOR_IAM (FormantGridEditor); EDITOR_FORM (U"Set formant range", 0) REAL (U"Minimum formant (Hz)", my default_formantFloor ()) REAL (U"Maximum formant (Hz)", my default_formantCeiling ()) EDITOR_OK SET_REAL (U"Minimum formant", my p_formantFloor) SET_REAL (U"Maximum formant", my p_formantCeiling) EDITOR_DO my pref_formantFloor () = my p_formantFloor = GET_REAL (U"Minimum formant"); my pref_formantCeiling () = my p_formantCeiling = GET_REAL (U"Maximum formant"); FunctionEditor_redraw (me); EDITOR_END } static void menu_cb_setBandwidthRange (EDITOR_ARGS) { EDITOR_IAM (FormantGridEditor); EDITOR_FORM (U"Set bandwidth range", 0) REAL (U"Minimum bandwidth (Hz)", my default_bandwidthFloor ()) REAL (U"Maximum bandwidth (Hz)", my default_bandwidthCeiling ()) EDITOR_OK SET_REAL (U"Minimum bandwidth", my p_bandwidthFloor) SET_REAL (U"Maximum bandwidth", my p_bandwidthCeiling) EDITOR_DO my pref_bandwidthFloor () = my p_bandwidthFloor = GET_REAL (U"Minimum bandwidth"); my pref_bandwidthCeiling () = my p_bandwidthCeiling = GET_REAL (U"Maximum bandwidth"); FunctionEditor_redraw (me); EDITOR_END } static void menu_cb_showBandwidths (EDITOR_ARGS) { EDITOR_IAM (FormantGridEditor); my editingBandwidths = ! my editingBandwidths; GuiMenuItem_check (my d_bandwidthsToggle, my editingBandwidths); FunctionEditor_redraw (me); } static void selectFormantOrBandwidth (FormantGridEditor me, long iformant) { FormantGrid grid = (FormantGrid) my data; long numberOfFormants = grid -> formants -> size; if (iformant > numberOfFormants) Melder_throw (U"Cannot select formant ", iformant, U", because the FormantGrid has only ", numberOfFormants, U" formants."); my selectedFormant = iformant; FunctionEditor_redraw (me); } static void menu_cb_selectFirst (EDITOR_ARGS) { EDITOR_IAM (FormantGridEditor); selectFormantOrBandwidth (me, 1); } static void menu_cb_selectSecond (EDITOR_ARGS) { EDITOR_IAM (FormantGridEditor); selectFormantOrBandwidth (me, 2); } static void menu_cb_selectThird (EDITOR_ARGS) { EDITOR_IAM (FormantGridEditor); selectFormantOrBandwidth (me, 3); } static void menu_cb_selectFourth (EDITOR_ARGS) { EDITOR_IAM (FormantGridEditor); selectFormantOrBandwidth (me, 4); } static void menu_cb_selectFifth (EDITOR_ARGS) { EDITOR_IAM (FormantGridEditor); selectFormantOrBandwidth (me, 5); } static void menu_cb_selectSixth (EDITOR_ARGS) { EDITOR_IAM (FormantGridEditor); selectFormantOrBandwidth (me, 6); } static void menu_cb_selectSeventh (EDITOR_ARGS) { EDITOR_IAM (FormantGridEditor); selectFormantOrBandwidth (me, 7); } static void menu_cb_selectEighth (EDITOR_ARGS) { EDITOR_IAM (FormantGridEditor); selectFormantOrBandwidth (me, 8); } static void menu_cb_selectNinth (EDITOR_ARGS) { EDITOR_IAM (FormantGridEditor); selectFormantOrBandwidth (me, 9); } static void menu_cb_selectFormantOrBandwidth (EDITOR_ARGS) { EDITOR_IAM (FormantGridEditor); EDITOR_FORM (U"Select formant or bandwidth", 0) NATURAL (U"Formant number", U"1") EDITOR_OK SET_INTEGER (U"Formant number", my selectedFormant) EDITOR_DO selectFormantOrBandwidth (me, GET_INTEGER (U"Formant number")); FunctionEditor_redraw (me); EDITOR_END } static void menu_cb_pitchSettings (EDITOR_ARGS) { EDITOR_IAM (FormantGridEditor); EDITOR_FORM (U"Source pitch settings", 0) LABEL (U"", U"These settings apply to the pitch curve") LABEL (U"", U"that you hear when playing the FormantGrid.") REAL (U"Starting time", my default_source_pitch_tStart ()) POSITIVE (U"Starting pitch (Hz)", my default_source_pitch_f0Start ()) REAL (U"Mid time", my default_source_pitch_tMid ()) POSITIVE (U"Mid pitch (Hz)", my default_source_pitch_f0Mid ()) REAL (U"End time", my default_source_pitch_tEnd ()) POSITIVE (U"End pitch (Hz)", my default_source_pitch_f0End ()) EDITOR_OK SET_REAL (U"Starting time", my p_source_pitch_tStart) SET_REAL (U"Starting pitch", my p_source_pitch_f0Start) SET_REAL (U"Mid time", my p_source_pitch_tMid) SET_REAL (U"Mid pitch", my p_source_pitch_f0Mid) SET_REAL (U"End time", my p_source_pitch_tEnd) SET_REAL (U"End pitch", my p_source_pitch_f0End) EDITOR_DO my pref_source_pitch_tStart () = my p_source_pitch_tStart = GET_REAL (U"Starting time"); my pref_source_pitch_f0Start () = my p_source_pitch_f0Start = GET_REAL (U"Starting pitch"); my pref_source_pitch_tMid () = my p_source_pitch_tMid = GET_REAL (U"Mid time"); my pref_source_pitch_f0Mid () = my p_source_pitch_f0Mid = GET_REAL (U"Mid pitch"); my pref_source_pitch_tEnd () = my p_source_pitch_tEnd = GET_REAL (U"End time"); my pref_source_pitch_f0End () = my p_source_pitch_f0End = GET_REAL (U"End pitch"); EDITOR_END } void structFormantGridEditor :: v_createMenus () { FormantGridEditor_Parent :: v_createMenus (); EditorMenu menu = Editor_addMenu (this, U"Formant", 0); our d_bandwidthsToggle = EditorMenu_addCommand (menu, U"Show bandwidths", GuiMenu_CHECKBUTTON, menu_cb_showBandwidths); EditorMenu_addCommand (menu, U"Set formant range...", 0, menu_cb_setFormantRange); EditorMenu_addCommand (menu, U"Set bandwidth range...", 0, menu_cb_setBandwidthRange); EditorMenu_addCommand (menu, U"-- select formant --", 0, nullptr); EditorMenu_addCommand (menu, U"Select first", '1', menu_cb_selectFirst); EditorMenu_addCommand (menu, U"Select second", '2', menu_cb_selectSecond); EditorMenu_addCommand (menu, U"Select third", '3', menu_cb_selectThird); EditorMenu_addCommand (menu, U"Select fourth", '4', menu_cb_selectFourth); EditorMenu_addCommand (menu, U"Select fifth", '5', menu_cb_selectFifth); EditorMenu_addCommand (menu, U"Select sixth", '6', menu_cb_selectSixth); EditorMenu_addCommand (menu, U"Select seventh", '7', menu_cb_selectSeventh); EditorMenu_addCommand (menu, U"Select eighth", '8', menu_cb_selectEighth); EditorMenu_addCommand (menu, U"Select ninth", '9', menu_cb_selectNinth); EditorMenu_addCommand (menu, U"Select formant or bandwidth...", 0, menu_cb_selectFormantOrBandwidth); menu = Editor_addMenu (this, U"Point", 0); EditorMenu_addCommand (menu, U"Add point at cursor", 'T', menu_cb_addPointAtCursor); EditorMenu_addCommand (menu, U"Add point at...", 0, menu_cb_addPointAt); EditorMenu_addCommand (menu, U"-- remove point --", 0, nullptr); EditorMenu_addCommand (menu, U"Remove point(s)", GuiMenu_OPTION + 'T', menu_cb_removePoints); if (our v_hasSourceMenu ()) { menu = Editor_addMenu (this, U"Source", 0); EditorMenu_addCommand (menu, U"Pitch settings...", 0, menu_cb_pitchSettings); //EditorMenu_addCommand (menu, U"Phonation settings...", 0, menu_cb_phonationSettings); } } /********** DRAWING AREA **********/ void structFormantGridEditor :: v_draw () { FormantGrid grid = (FormantGrid) our data; Ordered tiers = our editingBandwidths ? grid -> bandwidths : grid -> formants; RealTier selectedTier = (RealTier) tiers -> item [selectedFormant]; double ymin = our editingBandwidths ? our p_bandwidthFloor : our p_formantFloor; double ymax = our editingBandwidths ? our p_bandwidthCeiling : our p_formantCeiling; Graphics_setColour (our d_graphics, Graphics_WHITE); Graphics_setWindow (our d_graphics, 0, 1, 0, 1); Graphics_fillRectangle (our d_graphics, 0, 1, 0, 1); Graphics_setWindow (our d_graphics, our d_startWindow, our d_endWindow, ymin, ymax); Graphics_setColour (our d_graphics, Graphics_RED); Graphics_line (our d_graphics, our d_startWindow, our ycursor, our d_endWindow, our ycursor); Graphics_setTextAlignment (our d_graphics, Graphics_RIGHT, Graphics_HALF); Graphics_text (our d_graphics, our d_startWindow, our ycursor, Melder_float (Melder_half (our ycursor))); Graphics_setColour (our d_graphics, Graphics_BLUE); Graphics_setTextAlignment (our d_graphics, Graphics_LEFT, Graphics_TOP); Graphics_text (our d_graphics, our d_endWindow, ymax, Melder_float (Melder_half (ymax)), U" Hz"); Graphics_setTextAlignment (our d_graphics, Graphics_LEFT, Graphics_HALF); Graphics_text (our d_graphics, our d_endWindow, ymin, Melder_float (Melder_half (ymin)), U" Hz"); Graphics_setLineWidth (our d_graphics, 1); Graphics_setColour (our d_graphics, Graphics_GREY); for (long iformant = 1; iformant <= grid -> formants -> size; iformant ++) if (iformant != our selectedFormant) { RealTier tier = (RealTier) tiers -> item [iformant]; long imin = AnyTier_timeToHighIndex (tier, our d_startWindow); long imax = AnyTier_timeToLowIndex (tier, our d_endWindow); long n = tier -> points -> size; if (n == 0) { } else if (imax < imin) { double yleft = RealTier_getValueAtTime (tier, our d_startWindow); double yright = RealTier_getValueAtTime (tier, our d_endWindow); Graphics_line (our d_graphics, our d_startWindow, yleft, our d_endWindow, yright); } else for (long i = imin; i <= imax; i ++) { RealPoint point = (RealPoint) tier -> points -> item [i]; double t = point -> number, y = point -> value; Graphics_fillCircle_mm (our d_graphics, t, y, 2); if (i == 1) Graphics_line (our d_graphics, our d_startWindow, y, t, y); else if (i == imin) Graphics_line (our d_graphics, t, y, our d_startWindow, RealTier_getValueAtTime (tier, our d_startWindow)); if (i == n) Graphics_line (our d_graphics, t, y, our d_endWindow, y); else if (i == imax) Graphics_line (our d_graphics, t, y, our d_endWindow, RealTier_getValueAtTime (tier, our d_endWindow)); else { RealPoint pointRight = (RealPoint) tier -> points -> item [i + 1]; Graphics_line (our d_graphics, t, y, pointRight -> number, pointRight -> value); } } } Graphics_setColour (our d_graphics, Graphics_BLUE); long ifirstSelected = AnyTier_timeToHighIndex (selectedTier, our d_startSelection); long ilastSelected = AnyTier_timeToLowIndex (selectedTier, our d_endSelection); long n = selectedTier -> points -> size; long imin = AnyTier_timeToHighIndex (selectedTier, our d_startWindow); long imax = AnyTier_timeToLowIndex (selectedTier, our d_endWindow); Graphics_setLineWidth (our d_graphics, 2); if (n == 0) { Graphics_setTextAlignment (our d_graphics, Graphics_CENTRE, Graphics_HALF); Graphics_text (our d_graphics, 0.5 * (our d_startWindow + our d_endWindow), 0.5 * (ymin + ymax), U"(no points in selected formant tier)"); } else if (imax < imin) { double yleft = RealTier_getValueAtTime (selectedTier, our d_startWindow); double yright = RealTier_getValueAtTime (selectedTier, our d_endWindow); Graphics_line (our d_graphics, our d_startWindow, yleft, our d_endWindow, yright); } else for (long i = imin; i <= imax; i ++) { RealPoint point = (RealPoint) selectedTier -> points -> item [i]; double t = point -> number, y = point -> value; if (i >= ifirstSelected && i <= ilastSelected) Graphics_setColour (our d_graphics, Graphics_RED); Graphics_fillCircle_mm (our d_graphics, t, y, 3); Graphics_setColour (our d_graphics, Graphics_BLUE); if (i == 1) Graphics_line (our d_graphics, our d_startWindow, y, t, y); else if (i == imin) Graphics_line (our d_graphics, t, y, our d_startWindow, RealTier_getValueAtTime (selectedTier, our d_startWindow)); if (i == n) Graphics_line (our d_graphics, t, y, our d_endWindow, y); else if (i == imax) Graphics_line (our d_graphics, t, y, our d_endWindow, RealTier_getValueAtTime (selectedTier, our d_endWindow)); else { RealPoint pointRight = (RealPoint) selectedTier -> points -> item [i + 1]; Graphics_line (our d_graphics, t, y, pointRight -> number, pointRight -> value); } } Graphics_setLineWidth (our d_graphics, 1); Graphics_setColour (our d_graphics, Graphics_BLACK); } static void drawWhileDragging (FormantGridEditor me, double xWC, double yWC, long first, long last, double dt, double dy) { FormantGrid grid = (FormantGrid) my data; Ordered tiers = my editingBandwidths ? grid -> bandwidths : grid -> formants; RealTier tier = (RealTier) tiers -> item [my selectedFormant]; double ymin = my editingBandwidths ? my p_bandwidthFloor : my p_formantFloor; double ymax = my editingBandwidths ? my p_bandwidthCeiling : my p_formantCeiling; (void) xWC; (void) yWC; /* * Draw all selected points as magenta empty circles, if inside the window. */ for (long i = first; i <= last; i ++) { RealPoint point = (RealPoint) tier -> points -> item [i]; double t = point -> number + dt, y = point -> value + dy; if (t >= my d_startWindow && t <= my d_endWindow) Graphics_circle_mm (my d_graphics, t, y, 3); } if (last == first) { /* * Draw a crosshair with time and y. */ RealPoint point = (RealPoint) tier -> points -> item [first]; double t = point -> number + dt, y = point -> value + dy; Graphics_line (my d_graphics, t, ymin, t, ymax - Graphics_dyMMtoWC (my d_graphics, 4.0)); Graphics_setTextAlignment (my d_graphics, kGraphics_horizontalAlignment_CENTRE, Graphics_TOP); Graphics_text (my d_graphics, t, ymax, Melder_fixed (t, 6)); Graphics_line (my d_graphics, my d_startWindow, y, my d_endWindow, y); Graphics_setTextAlignment (my d_graphics, Graphics_LEFT, Graphics_BOTTOM); Graphics_text (my d_graphics, my d_startWindow, y, Melder_fixed (y, 6)); } } int structFormantGridEditor :: v_click (double xWC, double yWC, bool shiftKeyPressed) { FormantGrid grid = (FormantGrid) our data; Ordered tiers = editingBandwidths ? grid -> bandwidths : grid -> formants; RealTier tier = (RealTier) tiers -> item [selectedFormant]; double ymin = our editingBandwidths ? our p_bandwidthFloor : our p_formantFloor; double ymax = our editingBandwidths ? our p_bandwidthCeiling : our p_formantCeiling; long inearestPoint, ifirstSelected, ilastSelected; RealPoint nearestPoint; double dt = 0, df = 0; bool draggingSelection; /* * Perform the default action: move cursor. */ //d_startSelection = d_endSelection = xWC; our ycursor = (1.0 - yWC) * ymin + yWC * ymax; Graphics_setWindow (our d_graphics, our d_startWindow, our d_endWindow, ymin, ymax); yWC = our ycursor; /* * Clicked on a point? */ inearestPoint = AnyTier_timeToNearestIndex (tier, xWC); if (inearestPoint == 0) { return FormantGridEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed); } nearestPoint = (RealPoint) tier -> points -> item [inearestPoint]; if (Graphics_distanceWCtoMM (our d_graphics, xWC, yWC, nearestPoint -> number, nearestPoint -> value) > 1.5) { return our FormantGridEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed); } /* * Clicked on a selected point? */ draggingSelection = shiftKeyPressed && nearestPoint -> number > our d_startSelection && nearestPoint -> number < our d_endSelection; if (draggingSelection) { ifirstSelected = AnyTier_timeToHighIndex (tier, our d_startSelection); ilastSelected = AnyTier_timeToLowIndex (tier, our d_endSelection); Editor_save (this, U"Drag points"); } else { ifirstSelected = ilastSelected = inearestPoint; Editor_save (this, U"Drag point"); } /* * Drag. */ Graphics_xorOn (our d_graphics, Graphics_MAROON); drawWhileDragging (this, xWC, yWC, ifirstSelected, ilastSelected, dt, df); while (Graphics_mouseStillDown (our d_graphics)) { double xWC_new, yWC_new; Graphics_getMouseLocation (our d_graphics, & xWC_new, & yWC_new); if (xWC_new != xWC || yWC_new != yWC) { drawWhileDragging (this, xWC, yWC, ifirstSelected, ilastSelected, dt, df); dt += xWC_new - xWC, df += yWC_new - yWC; xWC = xWC_new, yWC = yWC_new; drawWhileDragging (this, xWC, yWC, ifirstSelected, ilastSelected, dt, df); } } Graphics_xorOff (our d_graphics); /* * Dragged inside window? */ if (xWC < d_startWindow || xWC > d_endWindow) return 1; /* * Points not dragged past neighbours? */ RealPoint *points = (RealPoint *) tier -> points -> item; double newTime = points [ifirstSelected] -> number + dt; if (newTime < our tmin) return 1; // outside domain if (ifirstSelected > 1 && newTime <= points [ifirstSelected - 1] -> number) return 1; // past left neighbour newTime = points [ilastSelected] -> number + dt; if (newTime > our tmax) return 1; // outside domain if (ilastSelected < tier -> points -> size && newTime >= points [ilastSelected + 1] -> number) return 1; // past right neighbour /* * Drop. */ for (long i = ifirstSelected; i <= ilastSelected; i ++) { RealPoint point = (RealPoint) tier -> points -> item [i]; point -> number += dt; point -> value += df; } /* * Make sure that the same points are still selected (a problem with Undo...). */ if (draggingSelection) our d_startSelection += dt, our d_endSelection += dt; if (ifirstSelected == ilastSelected) { /* * Move crosshair to only selected formant point. */ RealPoint point = (RealPoint) tier -> points -> item [ifirstSelected]; our d_startSelection = our d_endSelection = point -> number; our ycursor = point -> value; } else { /* * Move crosshair to mouse location. */ /*our cursor += dt;*/ our ycursor += df; } Editor_broadcastDataChanged (this); return 1; // update needed } void structFormantGridEditor :: v_play (double tmin, double tmax) { FormantGrid_playPart ((FormantGrid) our data, tmin, tmax, our p_play_samplingFrequency, our p_source_pitch_tStart, our p_source_pitch_f0Start, our p_source_pitch_tMid, our p_source_pitch_f0Mid, our p_source_pitch_tEnd, our p_source_pitch_f0End, our p_source_phonation_adaptFactor, our p_source_phonation_maximumPeriod, our p_source_phonation_openPhase, our p_source_phonation_collisionPhase, our p_source_phonation_power1, our p_source_phonation_power2, theFunctionEditor_playCallback, this); } void FormantGridEditor_init (FormantGridEditor me, const char32 *title, FormantGrid data) { Melder_assert (data != nullptr); Melder_assert (Thing_isa (data, classFormantGrid)); FunctionEditor_init (me, title, data); my ycursor = 0.382 * my p_formantFloor + 0.618 * my p_formantCeiling; my selectedFormant = 1; } autoFormantGridEditor FormantGridEditor_create (const char32 *title, FormantGrid data) { try { autoFormantGridEditor me = Thing_new (FormantGridEditor); FormantGridEditor_init (me.peek(), title, data); return me; } catch (MelderError) { Melder_throw (U"FormantGrid window not created."); } } /* End of file FormantGridEditor.cpp */ praat-6.0.04/fon/FormantGridEditor.h000066400000000000000000000030441261542461700172370ustar00rootroot00000000000000#ifndef _FormantGridEditor_h_ #define _FormantGridEditor_h_ /* FormantGridEditor.h * * Copyright (C) 2008-2011,2012,2013,2015 Paul Boersma & David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "FunctionEditor.h" #include "FormantGrid.h" Thing_define (FormantGridEditor, FunctionEditor) { bool editingBandwidths; GuiMenuItem d_bandwidthsToggle; long selectedFormant; double ycursor; void v_createMenus () override; void v_draw () override; int v_click (double xWC, double yWC, bool shiftKeyPressed) override; void v_play (double tmin, double tmax) override; virtual bool v_hasSourceMenu () { return true; } #include "FormantGridEditor_prefs.h" }; void FormantGridEditor_init (FormantGridEditor me, const char32 *title, FormantGrid data); autoFormantGridEditor FormantGridEditor_create (const char32 *title, FormantGrid data); /* End of file FormantGridEditor.h */ #endif praat-6.0.04/fon/FormantGridEditor_prefs.h000066400000000000000000000050431261542461700204370ustar00rootroot00000000000000/* FormantGridEditor_prefs.h * * Copyright (C) 2013,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ prefs_begin (FormantGridEditor) prefs_add_double_with_data (FormantGridEditor, formantFloor, 1, U"0.0") // Hz prefs_add_double_with_data (FormantGridEditor, formantCeiling, 1, U"11000.0") // Hz prefs_add_double_with_data (FormantGridEditor, bandwidthFloor, 1, U"0.0") // Hz prefs_add_double_with_data (FormantGridEditor, bandwidthCeiling, 1, U"1000.0") // Hz prefs_add_double_with_data (FormantGridEditor, play_samplingFrequency, 1, U"44100.0") // Hz prefs_add_double_with_data (FormantGridEditor, source_pitch_tStart, 1, U"0.0%") // relative time prefs_add_double_with_data (FormantGridEditor, source_pitch_f0Start, 1, U"150.0") // Hz prefs_add_double_with_data (FormantGridEditor, source_pitch_tMid, 1, U"25.0%") // relative time prefs_add_double_with_data (FormantGridEditor, source_pitch_f0Mid, 1, U"180.0") // Hz prefs_add_double_with_data (FormantGridEditor, source_pitch_tEnd, 1, U"100.0%") // relative time prefs_add_double_with_data (FormantGridEditor, source_pitch_f0End, 1, U"120.0") // Hz prefs_add_double_with_data (FormantGridEditor, source_phonation_adaptFactor, 1, U"1.0") prefs_add_double_with_data (FormantGridEditor, source_phonation_maximumPeriod, 1, U"0.05") prefs_add_double_with_data (FormantGridEditor, source_phonation_openPhase, 1, U"0.7") prefs_add_double_with_data (FormantGridEditor, source_phonation_collisionPhase, 1, U"0.03") prefs_add_double_with_data (FormantGridEditor, source_phonation_power1, 1, U"3.0") prefs_add_double_with_data (FormantGridEditor, source_phonation_power2, 1, U"4.0") prefs_end (FormantGridEditor) /* End of file FormantGridEditor_prefs.h */ praat-6.0.04/fon/FormantGrid_def.h000066400000000000000000000031031261542461700167020ustar00rootroot00000000000000/* FormantGrid_def.h * * Copyright (C) 2008-2011,2015 Paul Boersma & David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT FormantGrid oo_DEFINE_CLASS (FormantGrid, Function) oo_COLLECTION (Ordered, formants, RealTier, 0) oo_COLLECTION (Ordered, bandwidths, RealTier, 0) #if oo_DECLARING bool v_hasGetVector () override { return true; } double v_getVector (long irow, long icol) override; bool v_hasGetFunction1 () override { return true; } double v_getFunction1 (long irow, double x) override; const char32 * v_getUnitText (long ilevel, int /* unit */, unsigned long /* flags */) override { return ilevel & 1 ? U"Formant (Hz)" : U"Bandwidth (Hz)"; } void v_shiftX (double xfrom, double xto) override; void v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto) override; #endif oo_END_CLASS (FormantGrid) #undef ooSTRUCT /* End of file FormantGrid_def.h */ praat-6.0.04/fon/FormantTier.cpp000066400000000000000000000273431261542461700164510ustar00rootroot00000000000000/* FormantTier.cpp * * Copyright (C) 1992-2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2006/07/21 made Sound_FormantTier_filter_inline () accurate for higher numbers of formants * pb 2007/01/27 made compatible with stereo sounds * pb 2007/03/17 domain quantity * pb 2007/10/01 can write as encoding * pb 2011/03/01 moved Formant filtering to FormantGrid (reimplemented) * pb 2011/05/26 C++ */ #include "FormantTier.h" #include "AnyTier.h" #include "oo_DESTROY.h" #include "FormantTier_def.h" #include "oo_COPY.h" #include "FormantTier_def.h" #include "oo_EQUAL.h" #include "FormantTier_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "FormantTier_def.h" #include "oo_WRITE_TEXT.h" #include "FormantTier_def.h" #include "oo_READ_TEXT.h" #include "FormantTier_def.h" #include "oo_WRITE_BINARY.h" #include "FormantTier_def.h" #include "oo_READ_BINARY.h" #include "FormantTier_def.h" #include "oo_DESCRIPTION.h" #include "FormantTier_def.h" Thing_implement (FormantPoint, Daata, 0); autoFormantPoint FormantPoint_create (double time) { try { autoFormantPoint me = Thing_new (FormantPoint); my time = time; return me; } catch (MelderError) { Melder_throw (U"Formant point not created."); } } Thing_implement (FormantTier, Function, 0); autoFormantTier FormantTier_create (double tmin, double tmax) { try { autoFormantTier me = Thing_new (FormantTier); my points = SortedSetOfDouble_create (); my xmin = tmin; my xmax = tmax; return me; } catch (MelderError) { Melder_throw (U"FormantTier not created."); } } double FormantTier_getValueAtTime (FormantTier me, int iformant, double t) { long n = my points -> size; if (n == 0 || iformant < 1) return NUMundefined; FormantPoint pointRight = (FormantPoint) my points -> item [1]; if (t <= pointRight -> time) { if (iformant > pointRight -> numberOfFormants) return NUMundefined; return pointRight -> formant [iformant-1]; /* Constant extrapolation. */ } FormantPoint pointLeft = (FormantPoint) my points -> item [n]; if (t >= pointLeft -> time) { if (iformant > pointLeft -> numberOfFormants) return NUMundefined; return pointLeft -> formant [iformant-1]; /* Constant extrapolation. */ } Melder_assert (n >= 2); long ileft = AnyTier_timeToLowIndex (me, t), iright = ileft + 1; Melder_assert (ileft >= 1 && iright <= n); pointLeft = (FormantPoint) my points -> item [ileft]; pointRight = (FormantPoint) my points -> item [iright]; double tleft = pointLeft -> time; double fleft = iformant > pointLeft -> numberOfFormants ? NUMundefined : pointLeft -> formant [iformant-1]; double tright = pointRight -> time; double fright = iformant > pointRight -> numberOfFormants ? NUMundefined : pointRight -> formant [iformant-1]; return fleft == NUMundefined ? fright == NUMundefined ? NUMundefined : fright : fright == NUMundefined ? fleft : t == tright ? fright /* Be very accurate. */ : tleft == tright ? 0.5 * (fleft + fright) /* Unusual, but possible; no preference. */ : fleft + (t - tleft) * (fright - fleft) / (tright - tleft); /* Linear interpolation. */ } double FormantTier_getBandwidthAtTime (FormantTier me, int iformant, double t) { long n = my points -> size; if (n == 0) return 0.0; FormantPoint pointRight = (FormantPoint) my points -> item [1]; if (t <= pointRight -> time) { if (iformant > pointRight -> numberOfFormants) return NUMundefined; return pointRight -> bandwidth [iformant-1]; /* Constant extrapolation. */ } FormantPoint pointLeft = (FormantPoint) my points -> item [n]; if (t >= pointLeft -> time) { if (iformant > pointLeft -> numberOfFormants) return NUMundefined; return pointLeft -> bandwidth [iformant-1]; /* Constant extrapolation. */ } Melder_assert (n >= 2); long ileft = AnyTier_timeToLowIndex (me, t), iright = ileft + 1; Melder_assert (ileft >= 1 && iright <= n); pointLeft = (FormantPoint) my points -> item [ileft]; pointRight = (FormantPoint) my points -> item [iright]; double tleft = pointLeft -> time; double fleft = iformant > pointLeft -> numberOfFormants ? NUMundefined : pointLeft -> bandwidth [iformant-1]; double tright = pointRight -> time; double fright = iformant > pointRight -> numberOfFormants ? NUMundefined : pointRight -> bandwidth [iformant-1]; return fleft == NUMundefined ? fright == NUMundefined ? NUMundefined : fright : fright == NUMundefined ? fleft : t == tright ? fright /* Be very accurate. */ : tleft == tright ? 0.5 * (fleft + fright) /* Unusual, but possible; no preference. */ : fleft + (t - tleft) * (fright - fleft) / (tright - tleft); /* Linear interpolation. */ } void FormantTier_speckle (FormantTier me, Graphics g, double tmin, double tmax, double fmax, int garnish) { if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } Graphics_setWindow (g, tmin, tmax, 0.0, fmax); Graphics_setInner (g); long imin = AnyTier_timeToHighIndex (me, tmin); long imax = AnyTier_timeToLowIndex (me, tmax); if (imin > 0) for (long i = imin; i <= imax; i ++) { FormantPoint point = (FormantPoint) my points -> item [i]; double t = point -> time; for (long j = 1; j <= point -> numberOfFormants; j ++) { double f = point -> formant [j-1]; if (f <= fmax) Graphics_speckle (g, t, f); } } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Time (s)"); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); Graphics_textLeft (g, true, U"Frequency (Hz)"); } } autoFormantTier Formant_downto_FormantTier (Formant me) { try { autoFormantTier thee = FormantTier_create (my xmin, my xmax); for (long i = 1; i <= my nx; i ++) { Formant_Frame frame = & my d_frames [i]; autoFormantPoint point = FormantPoint_create (Sampled_indexToX (me, i)); point -> numberOfFormants = frame -> nFormants > 10 ? 10 : frame -> nFormants; for (long j = 1; j <= point -> numberOfFormants; j ++) { Formant_Formant pair = & frame -> formant [j]; point -> formant [j-1] = pair -> frequency; point -> bandwidth [j-1] = pair -> bandwidth; } Collection_addItem (thy points, point.transfer()); } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to FormantTier."); } } autoFormantTier Formant_PointProcess_to_FormantTier (Formant me, PointProcess pp) { try { autoFormantTier temp = Formant_downto_FormantTier (me); autoFormantTier thee = FormantTier_create (pp -> xmin, pp -> xmax); for (long ipoint = 1; ipoint <= pp -> nt; ipoint ++) { double time = pp -> t [ipoint]; autoFormantPoint point = FormantPoint_create (time); long iformant = 1; for (; iformant <= 10; iformant ++) { double value = FormantTier_getValueAtTime (temp.peek(), iformant, time); if (value == NUMundefined) break; point -> formant [iformant-1] = value; value = FormantTier_getBandwidthAtTime (temp.peek(), iformant, time); Melder_assert (value != NUMundefined); point -> bandwidth [iformant-1] = value; } point -> numberOfFormants = iformant - 1; Collection_addItem (thy points, point.transfer()); } return thee; } catch (MelderError) { Melder_throw (me, U" & ", pp, U": not converted to FormantTier."); } } int FormantTier_getMinNumFormants (FormantTier me) { int minNumFormants = 10; for (long ipoint = 1; ipoint <= my points -> size; ipoint ++) { FormantPoint point = (FormantPoint) my points -> item [ipoint]; if (point -> numberOfFormants < minNumFormants) minNumFormants = point -> numberOfFormants; } return minNumFormants; } int FormantTier_getMaxNumFormants (FormantTier me) { int maxNumFormants = 0; for (long ipoint = 1; ipoint <= my points -> size; ipoint ++) { FormantPoint point = (FormantPoint) my points -> item [ipoint]; if (point -> numberOfFormants > maxNumFormants) maxNumFormants = point -> numberOfFormants; } return maxNumFormants; } autoTableOfReal FormantTier_downto_TableOfReal (FormantTier me, int includeFormants, int includeBandwidths) { try { int maximumNumberOfFormants = FormantTier_getMaxNumFormants (me); autoTableOfReal thee = TableOfReal_create (my points -> size, 1 + ( includeFormants ? maximumNumberOfFormants : 0 ) + ( includeBandwidths ? maximumNumberOfFormants : 0 )); TableOfReal_setColumnLabel (thee.peek(), 1, U"Time"); for (long icol = 1, iformant = 1; iformant <= maximumNumberOfFormants; iformant ++) { char32 label [4]; if (includeFormants) { Melder_sprint (label,4, U"F", iformant); TableOfReal_setColumnLabel (thee.peek(), ++ icol, label); } if (includeBandwidths) { Melder_sprint (label,4, U"B", iformant); TableOfReal_setColumnLabel (thee.peek(), ++ icol, label); } } for (long ipoint = 1; ipoint <= my points -> size; ipoint ++) { FormantPoint point = (FormantPoint) my points -> item [ipoint]; thy data [ipoint] [1] = point -> time; for (long icol = 1, iformant = 1; iformant <= maximumNumberOfFormants; iformant ++) { if (includeFormants) thy data [ipoint] [++ icol] = point -> formant [iformant-1]; if (includeBandwidths) thy data [ipoint] [++ icol] = point -> bandwidth [iformant-1]; } } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to TableOfReal."); } } void Sound_FormantTier_filter_inline (Sound me, FormantTier formantTier) { double dt = my dx; if (formantTier -> points -> size) for (long iformant = 1; iformant <= 10; iformant ++) { for (long isamp = 1; isamp <= my nx; isamp ++) { double t = my x1 + (isamp - 1) * my dx; /* * Compute LP coefficients. */ double formant, bandwidth; formant = FormantTier_getValueAtTime (formantTier, iformant, t); bandwidth = FormantTier_getBandwidthAtTime (formantTier, iformant, t); if (NUMdefined (formant) && NUMdefined (bandwidth)) { double cosomdt = cos (2 * NUMpi * formant * dt); double r = exp (- NUMpi * bandwidth * dt); /* Formants at 0 Hz or the Nyquist are single poles, others are double poles. */ if (fabs (cosomdt) > 0.999999) { /* Allow for round-off errors. */ /* single pole: D(z) = 1 - r z^-1 */ for (long channel = 1; channel <= my ny; channel ++) { if (isamp > 1) my z [channel] [isamp] += r * my z [channel] [isamp - 1]; } } else { /* double pole: D(z) = 1 + p z^-1 + q z^-2 */ double p = - 2 * r * cosomdt; double q = r * r; for (long channel = 1; channel <= my ny; channel ++) { if (isamp > 1) my z [channel] [isamp] -= p * my z [channel] [isamp - 1]; if (isamp > 2) my z [channel] [isamp] -= q * my z [channel] [isamp - 2]; } } } } } } autoSound Sound_FormantTier_filter (Sound me, FormantTier formantTier) { try { autoSound thee = Data_copy (me); Sound_FormantTier_filter_inline (thee.peek(), formantTier); Vector_scale (thee.peek(), 0.99); return thee; } catch (MelderError) { Melder_throw (me, U": not filtered with ", formantTier, U"."); } } autoSound Sound_FormantTier_filter_noscale (Sound me, FormantTier formantTier) { try { autoSound thee = Data_copy (me); Sound_FormantTier_filter_inline (thee.peek(), formantTier); return thee; } catch (MelderError) { Melder_throw (me, U": not filtered with ", formantTier, U"."); } } /* End of file FormantTier.cpp */ praat-6.0.04/fon/FormantTier.h000066400000000000000000000037411261542461700161120ustar00rootroot00000000000000#ifndef _FormantTier_h_ #define _FormantTier_h_ /* FormantTier.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "PointProcess.h" #include "Formant.h" #include "TableOfReal.h" #include "Sound.h" #include "FormantTier_def.h" oo_CLASS_CREATE (FormantPoint, Daata); oo_CLASS_CREATE (FormantTier, Function); autoFormantPoint FormantPoint_create (double time); autoFormantTier FormantTier_create (double tmin, double tmax); double FormantTier_getValueAtTime (FormantTier me, int iformant, double t); double FormantTier_getBandwidthAtTime (FormantTier me, int iformant, double t); int FormantTier_getMinNumFormants (FormantTier me); int FormantTier_getMaxNumFormants (FormantTier me); void FormantTier_speckle (FormantTier me, Graphics g, double tmin, double tmax, double fmax, int garnish); autoFormantTier Formant_downto_FormantTier (Formant me); autoFormantTier Formant_PointProcess_to_FormantTier (Formant me, PointProcess pp); autoTableOfReal FormantTier_downto_TableOfReal (FormantTier me, int includeFormants, int includeBandwidths); void Sound_FormantTier_filter_inline (Sound me, FormantTier formantTier); autoSound Sound_FormantTier_filter (Sound me, FormantTier formantTier); autoSound Sound_FormantTier_filter_noscale (Sound me, FormantTier formantTier); /* End of file FormantTier.h */ #endif praat-6.0.04/fon/FormantTier_def.h000066400000000000000000000023531261542461700167260ustar00rootroot00000000000000/* FormantTier_def.h * * Copyright (C) 1992-2002 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT FormantPoint oo_DEFINE_CLASS (FormantPoint, Daata) oo_DOUBLE (time) /* AnyPoint */ oo_INT (numberOfFormants) oo_DOUBLE_ARRAY (formant, 10, numberOfFormants) oo_DOUBLE_ARRAY (bandwidth, 10, numberOfFormants) oo_END_CLASS (FormantPoint) #undef ooSTRUCT #define ooSTRUCT FormantTier oo_DEFINE_CLASS (FormantTier, Function) oo_COLLECTION (SortedSetOfDouble, points, FormantPoint, 0) oo_END_CLASS (FormantTier) #undef ooSTRUCT /* End of file FormantTier_def.h */ praat-6.0.04/fon/Formant_def.h000066400000000000000000000033531261542461700161030ustar00rootroot00000000000000/* Formant_def.h * * Copyright (C) 1992-2002,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT Formant_Formant oo_DEFINE_STRUCT (Formant_Formant) #if oo_READING if (formatVersion <= 1) { oo_FLOAT (frequency) oo_FLOAT (bandwidth) } else { oo_DOUBLE (frequency) oo_DOUBLE (bandwidth) } #else oo_DOUBLE (frequency) oo_DOUBLE (bandwidth) #endif oo_END_STRUCT (Formant_Formant) #undef ooSTRUCT #define ooSTRUCT Formant_Frame oo_DEFINE_STRUCT (Formant_Frame) oo_FROM (1) oo_DOUBLE (intensity) oo_ENDFROM oo_INT (nFormants) oo_STRUCT_VECTOR (Formant_Formant, formant, nFormants) oo_END_STRUCT (Formant_Frame) #undef ooSTRUCT #define ooSTRUCT Formant oo_DEFINE_CLASS (Formant, Sampled) oo_INT (maxnFormants) oo_STRUCT_VECTOR (Formant_Frame, d_frames, nx) #if oo_DECLARING void v_info () override; int v_domainQuantity () override { return MelderQuantity_TIME_SECONDS; } double v_getValueAtSample (long iframe, long which, int units) override; #endif oo_END_CLASS (Formant) #undef ooSTRUCT /* End of file Formant_def.h */ praat-6.0.04/fon/FujisakiPitch.cpp000066400000000000000000000077571261542461700167630ustar00rootroot00000000000000/* FujisakiPitch.cpp * * Copyright (C) 2002-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2007/10/01 can write as encoding * pb 2011/05/27 C++ */ #include "FujisakiPitch.h" #include "oo_DESTROY.h" #include "FujisakiPitch_def.h" #include "oo_COPY.h" #include "FujisakiPitch_def.h" #include "oo_EQUAL.h" #include "FujisakiPitch_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "FujisakiPitch_def.h" #include "oo_WRITE_TEXT.h" #include "FujisakiPitch_def.h" #include "oo_READ_TEXT.h" #include "FujisakiPitch_def.h" #include "oo_WRITE_BINARY.h" #include "FujisakiPitch_def.h" #include "oo_READ_BINARY.h" #include "FujisakiPitch_def.h" #include "oo_DESCRIPTION.h" #include "FujisakiPitch_def.h" Thing_implement (FujisakiCommand, Function, 0); autoFujisakiCommand FujisakiCommand_create (double tmin, double tmax, double amplitude) { try { autoFujisakiCommand me = Thing_new (FujisakiCommand); Function_init (me.peek(), tmin, tmax); my amplitude = amplitude; return me; } catch (MelderError) { Melder_throw (U"Fujisaki command not created."); } } Thing_implement (FujisakiPitch, Function, 0); autoFujisakiPitch FujisakiPitch_create (double tmin, double tmax, double baseFrequency, double alpha, double beta, double gamma) { try { autoFujisakiPitch me = Thing_new (FujisakiPitch); Function_init (me.peek(), tmin, tmax); my baseFrequency = baseFrequency; my alpha = alpha; my beta = beta; my gamma = gamma; my phraseCommands = SortedSetOfDouble_create (); my accentCommands = SortedSetOfDouble_create (); return me; } catch (MelderError) { Melder_throw (U"FujisakiPitch not created."); } } autoFujisakiPitch Pitch_to_FujisakiPitch (Pitch me, double gamma, double timeResolution, autoFujisakiPitch *intermediate1, autoFujisakiPitch *intermediate2, autoFujisakiPitch *intermediate3) { (void) timeResolution; try { autoFujisakiPitch thee = FujisakiPitch_create (my xmin, my xmax, 0, 0, 0, gamma); /* * Get phrase commands. */ while (/* ... */ 0) { double onsetTime = /* ... */ 0.0; double offsetTime = /* ... */ 3.0; double amplitude = /* ... */ 1.0; autoFujisakiCommand phraseCommand = FujisakiCommand_create (onsetTime, offsetTime, amplitude); Collection_addItem (thy phraseCommands, phraseCommand.transfer()); } if (intermediate1) *intermediate1 = Data_copy (thee.peek()); /* * Get accent commands. */ while (/* ... */ 0) { double onsetTime = /* ... */ 0.0; double offsetTime = /* ... */ 3.0; double amplitude = /* ... */ 1.0; autoFujisakiCommand accentCommand = FujisakiCommand_create (onsetTime, offsetTime, amplitude); Collection_addItem (thy accentCommands, accentCommand.transfer()); } if (intermediate2) *intermediate2 = Data_copy (thee.peek()); /* * Do some extra processing. */ /* ... */ if (intermediate3) *intermediate3 = Data_copy (thee.peek()); /* * Tidy up. */ for (long i = 1; i <= thy phraseCommands -> size; i ++) { FujisakiCommand phraseCommand = (FujisakiCommand) thy phraseCommands -> item [i]; /* ... */ } for (long i = 1; i <= thy accentCommands -> size; i ++) { FujisakiCommand accentCommand = (FujisakiCommand) thy accentCommands -> item [i]; /* ... */ } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to FujisakiPitch."); } } /* End of file FujisakiPitch.cpp */ praat-6.0.04/fon/FujisakiPitch.h000066400000000000000000000026441261542461700164160ustar00rootroot00000000000000#ifndef _FujisakiPitch_h_ #define _FujisakiPitch_h_ /* FujisakiPitch.h * * Copyright (C) 2002-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Pitch.h" #include "Collection.h" #include "FujisakiPitch_def.h" oo_CLASS_CREATE (FujisakiCommand, Function); oo_CLASS_CREATE (FujisakiPitch, Function); autoFujisakiCommand FujisakiCommand_create (double tmin, double tmax, double amplitude); autoFujisakiPitch FujisakiPitch_create (double tmin, double tmax, double baseFrequency, double alpha, double beta, double gamma); autoFujisakiPitch Pitch_to_FujisakiPitch (Pitch me, double gamma, double timeResolution, autoFujisakiPitch *intermediate1, autoFujisakiPitch *intermediate2, autoFujisakiPitch *intermediate3); /* End of file FujisakiPitch.h */ #endif praat-6.0.04/fon/FujisakiPitch_def.h000066400000000000000000000025311261542461700172270ustar00rootroot00000000000000/* FujisakiPitch_def.h * * Copyright (C) 2002 Paul Boersma & Hansjoerg Mixdorff * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/05/18 * pb 2002/07/16 GPL */ #define ooSTRUCT FujisakiCommand oo_DEFINE_CLASS (FujisakiCommand, Function) oo_DOUBLE (amplitude) oo_END_CLASS (FujisakiCommand) #undef ooSTRUCT #define ooSTRUCT FujisakiPitch oo_DEFINE_CLASS (FujisakiPitch, Function) oo_DOUBLE (baseFrequency) oo_DOUBLE (alpha) oo_DOUBLE (beta) oo_DOUBLE (gamma) oo_COLLECTION (SortedSetOfDouble, phraseCommands, FujisakiCommand, 0) oo_COLLECTION (SortedSetOfDouble, accentCommands, FujisakiCommand, 0) oo_END_CLASS (FujisakiPitch) #undef ooSTRUCT /* End of file FujisakiPitch_def.h */ praat-6.0.04/fon/Function.cpp000066400000000000000000000134311261542461700157750ustar00rootroot00000000000000/* Function.cpp * * Copyright (C) 1992-2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Function.h" #include "oo_DESTROY.h" #include "Function_def.h" #include "oo_COPY.h" #include "Function_def.h" #include "oo_EQUAL.h" #include "Function_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Function_def.h" #include "oo_WRITE_TEXT.h" #include "Function_def.h" #include "oo_READ_TEXT.h" #include "Function_def.h" #include "oo_WRITE_BINARY.h" #include "Function_def.h" #include "oo_READ_BINARY.h" #include "Function_def.h" #include "oo_DESCRIPTION.h" #include "Function_def.h" Thing_implement (Function, Daata, 0); void structFunction :: v_info () { Function_Parent :: v_info (); MelderInfo_writeLine (U"Domain:"); MelderInfo_writeLine (U" xmin: ", xmin); MelderInfo_writeLine (U" xmax: ", xmax); } void structFunction :: v_shiftX (double xfrom, double xto) { NUMshift (& xmin, xfrom, xto); NUMshift (& xmax, xfrom, xto); } void structFunction :: v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto) { NUMscale (& xmin, xminfrom, xmaxfrom, xminto, xmaxto); NUMscale (& xmax, xminfrom, xmaxfrom, xminto, xmaxto); } void Function_init (Function me, double xmin_, double xmax_) { my xmin = xmin_; my xmax = xmax_; } int Function_getMinimumUnit (Function me, long ilevel) { return my v_getMinimumUnit (ilevel); } int Function_getMaximumUnit (Function me, long ilevel) { return my v_getMaximumUnit (ilevel); } int Function_getDomainQuantity (Function me) { return my v_domainQuantity (); } const char32 * Function_getUnitText (Function me, long ilevel, int unit, unsigned long flags) { Melder_assert (unit >= my v_getMinimumUnit (ilevel) && unit <= my v_getMaximumUnit (ilevel)); return my v_getUnitText (ilevel, unit, flags); } bool Function_isUnitLogarithmic (Function me, long ilevel, int unit) { Melder_assert (unit >= my v_getMinimumUnit (ilevel) && unit <= my v_getMaximumUnit (ilevel)); return my v_isUnitLogarithmic (ilevel, unit); } double Function_convertStandardToSpecialUnit (Function me, double value, long ilevel, int unit) { return NUMdefined (value) ? my v_convertStandardToSpecialUnit (value, ilevel, unit) : NUMundefined; } double Function_convertSpecialToStandardUnit (Function me, double value, long ilevel, int unit) { return NUMdefined (value) ? my v_convertSpecialToStandardUnit (value, ilevel, unit) : NUMundefined; } double Function_convertToNonlogarithmic (Function me, double value, long ilevel, int unit) { return NUMdefined (value) && my v_isUnitLogarithmic (ilevel, unit) ? pow (10.0, value) : value; } void Function_shiftXBy (Function me, double shift) { my v_shiftX (0.0, shift); } void Function_shiftXTo (Function me, double xfrom, double xto) { my v_shiftX (xfrom, xto); } void Function_scaleXBy (Function me, double factor) { my v_scaleX (0.0, 1.0, 0.0, factor); } void Function_scaleXTo (Function me, double xminto, double xmaxto) { my v_scaleX (my xmin, my xmax, xminto, xmaxto); } double Function_window (double tim, int windowType) { static double one_by_bessi_0_12, one_by_bessi_0_20; switch (windowType) { case Function_RECTANGULAR: if (tim < -0.5 || tim > 0.5) return 0.0; return 1; case Function_TRIANGULAR: if (tim < -0.5 || tim > 0.5) return 0.0; return 1 - tim - tim; case Function_PARABOLIC: if (tim < -0.5 || tim > 0.5) return 0.0; return 1 - 4 * tim * tim; case Function_HANNING: if (tim < -0.5 || tim > 0.5) return 0.0; return 0.5 + 0.5 * cos (2 * NUMpi * tim); case Function_HAMMING: if (tim < -0.5 || tim > 0.5) return 0.0; return 0.54 + 0.46 * cos (2 * NUMpi * tim); case Function_POTTER: if (tim < -0.77 || tim > 0.77) return 0.0; return 0.54 + 0.46 * cos (2 * NUMpi * tim); case Function_KAISER12: if (tim < -0.77 || tim > 0.77) return 0.0; if (one_by_bessi_0_12 == 0.0) one_by_bessi_0_12 = 1.0 / NUMbessel_i0_f (12); return NUMbessel_i0_f (12 * sqrt (1 - (1.0 / 0.77 / 0.77) * tim * tim)) * one_by_bessi_0_12; case Function_KAISER20: if (tim <= -1 || tim >= 1) return 0.0; if (one_by_bessi_0_20 == 0.0) one_by_bessi_0_20 = 1.0 / NUMbessel_i0_f (20.24); return NUMbessel_i0_f (20.24 * sqrt (1 - tim * tim)) * one_by_bessi_0_20; case Function_GAUSSIAN: return exp ((- NUMpi * NUMpi) * tim * tim); default: return 0.0; } } void Function_unidirectionalAutowindow (Function me, double *xmin, double *xmax) { if (*xmin >= *xmax) { *xmin = my xmin; *xmax = my xmax; } } void Function_bidirectionalAutowindow (Function me, double *x1, double *x2) { if (*x1 == *x2) { *x1 = my xmin; *x2 = my xmax; } } bool Function_intersectRangeWithDomain (Function me, double *x1, double *x2) { if (*x1 == *x2) return false; if (*x1 < *x2) { if (*x1 < my xmin) *x1 = my xmin; // intersect requested range with logical domain if (*x2 > my xmax) *x2 = my xmax; if (*x2 <= *x1) return false; // requested range and logical domain do not intersect } else { if (*x2 < my xmin) *x2 = my xmin; // intersect requested range with logical domain if (*x1 > my xmax) *x1 = my xmax; if (*x1 <= *x2) return false; // requested range and logical domain do not intersect } return true; } /* End of file Function.cpp */ praat-6.0.04/fon/Function.h000066400000000000000000000113541261542461700154440ustar00rootroot00000000000000#ifndef _Function_h_ #define _Function_h_ /* Function.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Data.h" #include "Function_def.h" oo_CLASS_CREATE (Function, Daata); /* An object of type Function represents a function f (x, ...) on the domain [xmin, xmax] * .... Class invariants: xmax >= xmin; xmin, xmax are constant; */ void Function_init (Function me, double xmin, double xmax); /* Preconditions: xmin <= xmax; Postconditions: result -> xmin == xmin; result -> xmax == xmax; */ int Function_getDomainQuantity (Function me); // as input for MelderQuantity_getXXX /* * A function value is often expressed in some unit, such as: * Pa, Hz, dB, sones. * In the following, 'ilevel' is for multidimensional functions; it could be the row number of a matrix, * or pitch height (Hz) vs. pitch strength (dimensionless), and so on. * 'unit' is enumerated type that has to be defined in the header files of the descendant class, * starting from 0, which should be the default unit; e.g. for pitch: 0 = Hz, 1 = logHz, 2 = semitones, 3 = mel. */ int Function_getMinimumUnit (Function me, long ilevel); int Function_getMaximumUnit (Function me, long ilevel); #define Function_UNIT_TEXT_SHORT 0x00000001 #define Function_UNIT_TEXT_GRAPHICAL 0x00000002 #define Function_UNIT_TEXT_MENU 0x00000004 const char32 * Function_getUnitText (Function me, long ilevel, int unit, unsigned long flags); bool Function_isUnitLogarithmic (Function me, long ilevel, int unit); double Function_convertStandardToSpecialUnit (Function me, double value, long ilevel, int unit); double Function_convertSpecialToStandardUnit (Function me, double value, long ilevel, int unit); double Function_convertToNonlogarithmic (Function me, double value, long ilevel, int unit); /* The domain of a function can be changed by windowing. */ /* Here follow some window functions. */ #define Function_RECTANGULAR 0 #define Function_TRIANGULAR 1 #define Function_PARABOLIC 2 #define Function_HANNING 3 #define Function_HAMMING 4 #define Function_POTTER 5 #define Function_KAISER12 6 #define Function_KAISER20 7 #define Function_GAUSSIAN 8 double Function_window (double tim, int windowType); /* Return value: a number between 0 and 1, zero outside the "domain": domain [-0.5, 0.5]: rectangular, triangular, parabolic, hanning, hamming; domain [-0.77, 0.77]: potter, kaiser12; domain [-1, 1]: kaiser20; domain [-inf, +inf]: gaussian. Rectangular: 1; Triangular ("Parzen"): 1 - tim / 0.5 Parabolic ("Welch"): 1 - (tim / 0.5) ^ 2 Hanning (raised cosine): 0.5 + 0.5 * cos (2 * pi * tim) Hamming (raised cosine): 0.54 + 0.46 * cos (2 * pi * tim) Gaussian: exp (- (pi * tim) ^ 2) Kaiser12: besselI0 (12 * sqrt (1 - (tim / 0.77) ^ 2)) / besselI0 (12) Kaiser20: besselI0 (20.24 * sqrt (1 - tim ^ 2)) / besselI0 (20.24) Usage: the preferred window for almost every application is Kaiser20; its only shortcoming is the usual double computation time. Properties: Highest sidelobe: Rectangular: -10 dB Hanning: -30 dB Hamming: -40 dB Potter, Kaiser12: -90 dB Kaiser20: -180 dB Gaussian: -inf dB Height at 'tim' is +0.5 or -0.5 (limit from below): Rectangular: 1 Triangular, Parabolic, Hanning: 0 Hamming: 0.08 Gaussian: 0.085 Kaiser20: 0.0715 Potter: ... Area: Rectangular: 1 Parabolic: 2/3 Gaussian: 1 / sqrt (pi) Kaiser20: 0.9813318115591122859 / sqrt (pi) Hamming: 0.54 Triangular, Hanning: 1/2 Bandwidth (-20 dB): ... */ /* * Procedures to adapt a range to the extent of the function domain. */ void Function_unidirectionalAutowindow (Function me, double *xmin, double *xmax); void Function_bidirectionalAutowindow (Function me, double *x1, double *x2); bool Function_intersectRangeWithDomain (Function me, double *x1, double *x2); void Function_shiftXBy (Function me, double shift); void Function_shiftXTo (Function me, double xfrom, double xto); void Function_scaleXBy (Function me, double factor); void Function_scaleXTo (Function me, double xminto, double xmaxto); /* End of file Function.h */ #endif praat-6.0.04/fon/FunctionEditor.cpp000066400000000000000000002006021261542461700171420ustar00rootroot00000000000000/* FunctionEditor.cpp * * Copyright (C) 1992-2011,2012,2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "FunctionEditor.h" #include "machine.h" #include "EditorM.h" #include "GuiP.h" Thing_implement (FunctionEditor, Editor, 0); #define maximumScrollBarValue 2000000000 #define RELATIVE_PAGE_INCREMENT 0.8 #define SCROLL_INCREMENT_FRACTION 20 #define space 30 #define MARGIN 107 #define BOTTOM_MARGIN 2 #define TOP_MARGIN 3 #define TEXT_HEIGHT 50 #define BUTTON_X 3 #define BUTTON_WIDTH 40 #define BUTTON_SPACING 8 #include "prefs_define.h" #include "FunctionEditor_prefs.h" #include "prefs_install.h" #include "FunctionEditor_prefs.h" #include "prefs_copyToInstance.h" #include "FunctionEditor_prefs.h" namespace { constexpr int maxGroup { 100 }; int nGroup = 0; FunctionEditor theGroup [1 + maxGroup]; } static void drawWhileDragging (FunctionEditor me, double x1, double x2); static int group_equalDomain (double tmin, double tmax) { if (nGroup == 0) return 1; for (int i = 1; i <= maxGroup; i ++) if (theGroup [i]) return tmin == theGroup [i] -> tmin && tmax == theGroup [i] -> tmax; return 0; // should not occur } static void updateScrollBar (FunctionEditor me) { /* We cannot call this immediately after creation. */ double slider_size = (my d_endWindow - my d_startWindow) / (my tmax - my tmin) * maximumScrollBarValue - 1; double increment, page_increment; double value = (my d_startWindow - my tmin) / (my tmax - my tmin) * maximumScrollBarValue + 1; if (slider_size < 1) slider_size = 1; if (value > maximumScrollBarValue - slider_size) value = maximumScrollBarValue - slider_size; if (value < 1) value = 1; increment = slider_size / SCROLL_INCREMENT_FRACTION + 1; page_increment = RELATIVE_PAGE_INCREMENT * slider_size + 1; GuiScrollBar_set (my scrollBar, NUMundefined, maximumScrollBarValue, value, slider_size, increment, page_increment); } static void updateGroup (FunctionEditor me) { if (! my group) return; for (int i = 1; i <= maxGroup; i ++) if (theGroup [i] && theGroup [i] != me) { FunctionEditor thee = theGroup [i]; if (my pref_synchronizedZoomAndScroll ()) { thy d_startWindow = my d_startWindow; thy d_endWindow = my d_endWindow; } thy d_startSelection = my d_startSelection; thy d_endSelection = my d_endSelection; FunctionEditor_updateText (thee); updateScrollBar (thee); Graphics_updateWs (thy d_graphics); } } static void drawNow (FunctionEditor me) { int leftFromWindow = my d_startWindow > my tmin; int rightFromWindow = my d_endWindow < my tmax; int cursorVisible = my d_startSelection == my d_endSelection && my d_startSelection >= my d_startWindow && my d_startSelection <= my d_endWindow; int selection = my d_endSelection > my d_startSelection; int beginVisible, endVisible; double verticalCorrection; /* Update selection. */ beginVisible = my d_startSelection > my d_startWindow && my d_startSelection < my d_endWindow; endVisible = my d_endSelection > my d_startWindow && my d_endSelection < my d_endWindow; /* Update markers. */ my numberOfMarkers = 0; if (beginVisible) my marker [++ my numberOfMarkers] = my d_startSelection; if (endVisible && my d_endSelection != my d_startSelection) my marker [++ my numberOfMarkers] = my d_endSelection; my marker [++ my numberOfMarkers] = my d_endWindow; NUMsort_d (my numberOfMarkers, my marker); /* Update rectangles. */ for (int i = 0; i < 8; i++) my rect [i]. left = my rect [i]. right = 0; /* 0: rectangle for total. */ my rect [0]. left = my functionViewerLeft + ( leftFromWindow ? 0 : MARGIN ); my rect [0]. right = my functionViewerRight - ( rightFromWindow ? 0 : MARGIN ); my rect [0]. bottom = BOTTOM_MARGIN; my rect [0]. top = BOTTOM_MARGIN + space; /* 1: rectangle for visible part. */ my rect [1]. left = my functionViewerLeft + MARGIN; my rect [1]. right = my functionViewerRight - MARGIN; my rect [1]. bottom = BOTTOM_MARGIN + space; my rect [1]. top = BOTTOM_MARGIN + space * (my numberOfMarkers > 1 ? 2 : 3); /* 2: rectangle for left from visible part. */ if (leftFromWindow) { my rect [2]. left = my functionViewerLeft; my rect [2]. right = my functionViewerLeft + MARGIN; my rect [2]. bottom = BOTTOM_MARGIN + space; my rect [2]. top = BOTTOM_MARGIN + space * 2; } /* 3: rectangle for right from visible part. */ if (rightFromWindow) { my rect [3]. left = my functionViewerRight - MARGIN; my rect [3]. right = my functionViewerRight; my rect [3]. bottom = BOTTOM_MARGIN + space; my rect [3]. top = BOTTOM_MARGIN + space * 2; } /* 4, 5, 6: rectangles between markers visible in visible part. */ if (my numberOfMarkers > 1) { double window = my d_endWindow - my d_startWindow; for (int i = 1; i <= my numberOfMarkers; i ++) { my rect [3 + i]. left = i == 1 ? my functionViewerLeft + MARGIN : my functionViewerLeft + MARGIN + (my functionViewerRight - my functionViewerLeft - MARGIN * 2) * (my marker [i - 1] - my d_startWindow) / window; my rect [3 + i]. right = my functionViewerLeft + MARGIN + (my functionViewerRight - my functionViewerLeft - MARGIN * 2) * (my marker [i] - my d_startWindow) / window; my rect [3 + i]. bottom = BOTTOM_MARGIN + space * 2; my rect [3 + i]. top = BOTTOM_MARGIN + space * 3; } } if (selection) { double window = my d_endWindow - my d_startWindow; double left = my d_startSelection == my d_startWindow ? my functionViewerLeft + MARGIN : my d_startSelection == my tmin ? my functionViewerLeft : my d_startSelection < my d_startWindow ? my functionViewerLeft + MARGIN * 0.3 : my d_startSelection < my d_endWindow ? my functionViewerLeft + MARGIN + (my functionViewerRight - my functionViewerLeft - MARGIN * 2) * (my d_startSelection - my d_startWindow) / window : my d_startSelection == my d_endWindow ? my functionViewerRight - MARGIN : my functionViewerRight - MARGIN * 0.7; double right = my d_endSelection < my d_startWindow ? my functionViewerLeft + MARGIN * 0.7 : my d_endSelection == my d_startWindow ? my functionViewerLeft + MARGIN : my d_endSelection < my d_endWindow ? my functionViewerLeft + MARGIN + (my functionViewerRight - my functionViewerLeft - MARGIN * 2) * (my d_endSelection - my d_startWindow) / window : my d_endSelection == my d_endWindow ? my functionViewerRight - MARGIN : my d_endSelection < my tmax ? my functionViewerRight - MARGIN * 0.3 : my functionViewerRight; my rect [7]. left = left; my rect [7]. right = right; my rect [7]. bottom = my height - space - TOP_MARGIN; my rect [7]. top = my height - TOP_MARGIN; } /* * Be responsive: update the markers now. */ Graphics_setViewport (my d_graphics, my functionViewerLeft, my functionViewerRight, 0, my height); Graphics_setWindow (my d_graphics, my functionViewerLeft, my functionViewerRight, 0, my height); Graphics_setColour (my d_graphics, Graphics_WINDOW_BACKGROUND_COLOUR); Graphics_fillRectangle (my d_graphics, my functionViewerLeft + MARGIN, my selectionViewerRight - MARGIN, my height - (TOP_MARGIN + space), my height); Graphics_fillRectangle (my d_graphics, my functionViewerLeft, my functionViewerLeft + MARGIN, BOTTOM_MARGIN + ( leftFromWindow ? space * 2 : 0 ), my height); Graphics_fillRectangle (my d_graphics, my functionViewerRight - MARGIN, my functionViewerRight, BOTTOM_MARGIN + ( rightFromWindow ? space * 2 : 0 ), my height); if (my p_showSelectionViewer) { Graphics_setViewport (my d_graphics, my selectionViewerLeft, my selectionViewerRight, 0, my height); Graphics_setWindow (my d_graphics, my selectionViewerLeft, my selectionViewerRight, 0, my height); Graphics_fillRectangle (my d_graphics, my selectionViewerLeft, my selectionViewerLeft + MARGIN, BOTTOM_MARGIN, my height); Graphics_fillRectangle (my d_graphics, my selectionViewerRight - MARGIN, my selectionViewerRight, BOTTOM_MARGIN, my height); Graphics_fillRectangle (my d_graphics, my selectionViewerLeft + MARGIN, my selectionViewerRight - MARGIN, 0, BOTTOM_MARGIN + space * 3); } Graphics_setGrey (my d_graphics, 0.0); #if defined (macintosh) Graphics_line (my d_graphics, my functionViewerLeft, 2, my selectionViewerRight, 2); Graphics_line (my d_graphics, my functionViewerLeft, my height - 2, my selectionViewerRight, my height - 2); #endif Graphics_setViewport (my d_graphics, my functionViewerLeft, my functionViewerRight, 0, my height); Graphics_setWindow (my d_graphics, my functionViewerLeft, my functionViewerRight, 0, my height); Graphics_setTextAlignment (my d_graphics, Graphics_CENTRE, Graphics_HALF); for (int i = 0; i < 8; i ++) { double left = my rect [i]. left, right = my rect [i]. right; if (left < right) Graphics_button (my d_graphics, left, right, my rect [i]. bottom, my rect [i]. top); } verticalCorrection = my height / (my height - 111 + 11.0); #ifdef _WIN32 verticalCorrection *= 1.5; #endif for (int i = 0; i < 8; i ++) { double left = my rect [i]. left, right = my rect [i]. right; double bottom = my rect [i]. bottom, top = my rect [i]. top; if (left < right) { const char *format = my v_format_long (); double value = NUMundefined, inverseValue = 0.0; switch (i) { case 0: format = my v_format_totalDuration (), value = my tmax - my tmin; break; case 1: format = my v_format_window (), value = my d_endWindow - my d_startWindow; /* * Window domain text. */ Graphics_setColour (my d_graphics, Graphics_BLUE); Graphics_setTextAlignment (my d_graphics, Graphics_LEFT, Graphics_HALF); Graphics_text (my d_graphics, left, 0.5 * (bottom + top) - verticalCorrection, Melder_fixed (my d_startWindow, my v_fixedPrecision_long ())); Graphics_setTextAlignment (my d_graphics, Graphics_RIGHT, Graphics_HALF); Graphics_text (my d_graphics, right, 0.5 * (bottom + top) - verticalCorrection, Melder_fixed (my d_endWindow, my v_fixedPrecision_long ())); Graphics_setColour (my d_graphics, Graphics_BLACK); Graphics_setTextAlignment (my d_graphics, Graphics_CENTRE, Graphics_HALF); break; case 2: value = my d_startWindow - my tmin; break; case 3: value = my tmax - my d_endWindow; break; case 4: value = my marker [1] - my d_startWindow; break; case 5: value = my marker [2] - my marker [1]; break; case 6: value = my marker [3] - my marker [2]; break; case 7: format = my v_format_selection (), value = my d_endSelection - my d_startSelection, inverseValue = 1 / value; break; } char text8 [100]; snprintf (text8, 100, format, value, inverseValue); autostring32 text = Melder_8to32 (text8); if (Graphics_textWidth (my d_graphics, text.peek()) < right - left) { Graphics_text (my d_graphics, 0.5 * (left + right), 0.5 * (bottom + top) - verticalCorrection, text.peek()); } else if (format == my v_format_long ()) { snprintf (text8, 100, my v_format_short (), value); text.reset (Melder_8to32 (text8)); if (Graphics_textWidth (my d_graphics, text.peek()) < right - left) Graphics_text (my d_graphics, 0.5 * (left + right), 0.5 * (bottom + top) - verticalCorrection, text.peek()); } else { snprintf (text8, 100, my v_format_long (), value); text.reset (Melder_8to32 (text8)); if (Graphics_textWidth (my d_graphics, text.peek()) < right - left) { Graphics_text (my d_graphics, 0.5 * (left + right), 0.5 * (bottom + top) - verticalCorrection, text.peek()); } else { snprintf (text8, 100, my v_format_short (), my d_endSelection - my d_startSelection); text.reset (Melder_8to32 (text8)); if (Graphics_textWidth (my d_graphics, text.peek()) < right - left) Graphics_text (my d_graphics, 0.5 * (left + right), 0.5 * (bottom + top) - verticalCorrection, text.peek()); } } } } Graphics_setViewport (my d_graphics, my functionViewerLeft + MARGIN, my functionViewerRight - MARGIN, 0, my height); Graphics_setWindow (my d_graphics, my d_startWindow, my d_endWindow, 0, my height); /*Graphics_setColour (my d_graphics, Graphics_WHITE); Graphics_fillRectangle (my d_graphics, my d_startWindow, my d_endWindow, BOTTOM_MARGIN + space * 3, my height - (TOP_MARGIN + space));*/ Graphics_setColour (my d_graphics, Graphics_BLACK); Graphics_rectangle (my d_graphics, my d_startWindow, my d_endWindow, BOTTOM_MARGIN + space * 3, my height - (TOP_MARGIN + space)); /* * Red marker text. */ Graphics_setColour (my d_graphics, Graphics_RED); if (cursorVisible) { Graphics_setTextAlignment (my d_graphics, Graphics_CENTRE, Graphics_BOTTOM); Graphics_text (my d_graphics, my d_startSelection, my height - (TOP_MARGIN + space) - verticalCorrection, Melder_fixed (my d_startSelection, my v_fixedPrecision_long ())); } if (beginVisible && selection) { Graphics_setTextAlignment (my d_graphics, Graphics_RIGHT, Graphics_HALF); Graphics_text (my d_graphics, my d_startSelection, my height - (TOP_MARGIN + space/2) - verticalCorrection, Melder_fixed (my d_startSelection, my v_fixedPrecision_long ())); } if (endVisible && selection) { Graphics_setTextAlignment (my d_graphics, Graphics_LEFT, Graphics_HALF); Graphics_text (my d_graphics, my d_endSelection, my height - (TOP_MARGIN + space/2) - verticalCorrection, Melder_fixed (my d_endSelection, my v_fixedPrecision_long ())); } Graphics_setColour (my d_graphics, Graphics_BLACK); /* * To reduce flashing, give our descendants the opportunity to prepare their data. */ my v_prepareDraw (); /* * Start of inner drawing. */ Graphics_setViewport (my d_graphics, my functionViewerLeft + MARGIN, my functionViewerRight - MARGIN, BOTTOM_MARGIN + space * 3, my height - (TOP_MARGIN + space)); my v_draw (); Graphics_setViewport (my d_graphics, my functionViewerLeft + MARGIN, my functionViewerRight - MARGIN, BOTTOM_MARGIN + space * 3, my height - (TOP_MARGIN + space)); /* * Red dotted marker lines. */ Graphics_setWindow (my d_graphics, my d_startWindow, my d_endWindow, 0.0, 1.0); Graphics_setColour (my d_graphics, Graphics_RED); Graphics_setLineType (my d_graphics, Graphics_DOTTED); double bottom = my v_getBottomOfSoundAndAnalysisArea (); if (cursorVisible) Graphics_line (my d_graphics, my d_startSelection, bottom, my d_startSelection, 1.0); if (beginVisible) Graphics_line (my d_graphics, my d_startSelection, bottom, my d_startSelection, 1.0); if (endVisible) Graphics_line (my d_graphics, my d_endSelection, bottom, my d_endSelection, 1.0); Graphics_setColour (my d_graphics, Graphics_BLACK); Graphics_setLineType (my d_graphics, Graphics_DRAWN); /* * Highlight selection. */ if (selection && my d_startSelection < my d_endWindow && my d_endSelection > my d_startWindow) { double left = my d_startSelection, right = my d_endSelection; if (left < my d_startWindow) left = my d_startWindow; if (right > my d_endWindow) right = my d_endWindow; my v_highlightSelection (left, right, 0.0, 1.0); } /* * Draw the selection part. */ if (my p_showSelectionViewer) { Graphics_setViewport (my d_graphics, my selectionViewerLeft + MARGIN, my selectionViewerRight - MARGIN, BOTTOM_MARGIN + space * 3, my height - (TOP_MARGIN + space)); my v_drawSelectionViewer (); } /* * End of inner drawing. */ Graphics_flushWs (my d_graphics); Graphics_setViewport (my d_graphics, my functionViewerLeft, my selectionViewerRight, 0, my height); } /********** METHODS **********/ void structFunctionEditor :: v_destroy () { MelderAudio_stopPlaying (MelderAudio_IMPLICIT); if (our group) { // undangle int i = 1; while (theGroup [i] != this) { Melder_assert (i < maxGroup); i ++; } theGroup [i] = nullptr; nGroup --; } forget (our d_graphics); FunctionEditor_Parent :: v_destroy (); } void structFunctionEditor :: v_info () { FunctionEditor_Parent :: v_info (); MelderInfo_writeLine (U"Editor start: ", our tmin, U" ", v_format_units ()); MelderInfo_writeLine (U"Editor end: ", our tmax, U" ", v_format_units ()); MelderInfo_writeLine (U"Window start: ", our d_startWindow, U" ", v_format_units ()); MelderInfo_writeLine (U"Window end: ", our d_endWindow, U" ", v_format_units ()); MelderInfo_writeLine (U"Selection start: ", our d_startSelection, U" ", v_format_units ()); MelderInfo_writeLine (U"Selection end: ", our d_endSelection, U" ", v_format_units ()); MelderInfo_writeLine (U"Arrow scroll step: ", our p_arrowScrollStep, U" ", v_format_units ()); MelderInfo_writeLine (U"Group: ", group ? U"yes" : U"no"); } /********** FILE MENU **********/ static void gui_drawingarea_cb_resize (I, GuiDrawingAreaResizeEvent event) { iam (FunctionEditor); if (! my d_graphics) return; // could be the case in the very beginning Graphics_setWsViewport (my d_graphics, 0, event -> width, 0, event -> height); int width = event -> width + 21; /* * Put the function viewer at the left and the selection viewer at the right. */ my functionViewerLeft = 0; my functionViewerRight = my p_showSelectionViewer ? (short) floor (width * (2.0/3)) : width; my selectionViewerLeft = my functionViewerRight; my selectionViewerRight = width; my height = event -> height + 111; Graphics_setWsWindow (my d_graphics, 0, width, 0, my height); Graphics_setViewport (my d_graphics, 0, width, 0, my height); Graphics_updateWs (my d_graphics); /* Save the current shell size as the user's preference for a new FunctionEditor. */ my pref_shellWidth () = GuiShell_getShellWidth (my d_windowForm); my pref_shellHeight () = GuiShell_getShellHeight (my d_windowForm); } static void menu_cb_preferences (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); EDITOR_FORM (U"Preferences", 0) BOOLEAN (U"Synchronize zoom and scroll", my default_synchronizedZoomAndScroll ()) BOOLEAN (U"Show selection viewer", my default_showSelectionViewer ()) POSITIVE (Melder_cat (U"Arrow scroll step (", my v_format_units (), U")"), my default_arrowScrollStep ()) my v_prefs_addFields (cmd); EDITOR_OK SET_INTEGER (U"Synchronize zoom and scroll", my pref_synchronizedZoomAndScroll ()) SET_INTEGER (U"Show selection viewer", my pref_showSelectionViewer()) SET_REAL (U"Arrow scroll step", my p_arrowScrollStep) my v_prefs_setValues (cmd); EDITOR_DO bool oldSynchronizedZoomAndScroll = my pref_synchronizedZoomAndScroll (); bool oldShowSelectionViewer = my p_showSelectionViewer; my pref_synchronizedZoomAndScroll () = GET_INTEGER (U"Synchronize zoom and scroll"); my pref_showSelectionViewer () = my p_showSelectionViewer = GET_INTEGER (U"Show selection viewer"); my pref_arrowScrollStep () = my p_arrowScrollStep = GET_REAL (U"Arrow scroll step"); if (my p_showSelectionViewer != oldShowSelectionViewer) { struct structGuiDrawingAreaResizeEvent event = { my drawingArea, 0 }; event. width = GuiControl_getWidth (my drawingArea); event. height = GuiControl_getHeight (my drawingArea); gui_drawingarea_cb_resize (me, & event); } if (! oldSynchronizedZoomAndScroll && my pref_synchronizedZoomAndScroll ()) { updateGroup (me); } my v_prefs_getValues (cmd); EDITOR_END } void structFunctionEditor :: v_form_pictureSelection (EditorCommand cmd) { BOOLEAN (U"Draw selection times", 1); BOOLEAN (U"Draw selection hairs", 1); } void structFunctionEditor :: v_ok_pictureSelection (EditorCommand cmd) { FunctionEditor me = (FunctionEditor) cmd -> d_editor; SET_INTEGER (U"Draw selection times", my pref_picture_drawSelectionTimes ()); SET_INTEGER (U"Draw selection hairs", my pref_picture_drawSelectionHairs ()); } void structFunctionEditor :: v_do_pictureSelection (EditorCommand cmd) { FunctionEditor me = (FunctionEditor) cmd -> d_editor; my pref_picture_drawSelectionTimes () = GET_INTEGER (U"Draw selection times"); my pref_picture_drawSelectionHairs () = GET_INTEGER (U"Draw selection hairs"); } /********** QUERY MENU **********/ static void menu_cb_getB (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); Melder_informationReal (my d_startSelection, my v_format_units ()); } static void menu_cb_getCursor (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); Melder_informationReal (0.5 * (my d_startSelection + my d_endSelection), my v_format_units ()); } static void menu_cb_getE (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); Melder_informationReal (my d_endSelection, my v_format_units ()); } static void menu_cb_getSelectionDuration (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); Melder_informationReal (my d_endSelection - my d_startSelection, my v_format_units ()); } /********** VIEW MENU **********/ static void menu_cb_zoom (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); EDITOR_FORM (U"Zoom", 0) REAL (U"From", U"0.0") REAL (U"To", U"1.0") EDITOR_OK SET_REAL (U"From", my d_startWindow) SET_REAL (U"To", my d_endWindow) EDITOR_DO my d_startWindow = GET_REAL (U"From"); if (my d_startWindow < my tmin + 1e-12) my d_startWindow = my tmin; my d_endWindow = GET_REAL (U"To"); if (my d_endWindow > my tmax - 1e-12) my d_endWindow = my tmax; my v_updateText (); updateScrollBar (me); /*Graphics_updateWs (my d_graphics);*/ drawNow (me); updateGroup (me); EDITOR_END } static void do_showAll (FunctionEditor me) { my d_startWindow = my tmin; my d_endWindow = my tmax; my v_updateText (); updateScrollBar (me); /*Graphics_updateWs (my d_graphics);*/ drawNow (me); if (my pref_synchronizedZoomAndScroll ()) { updateGroup (me); } } static void gui_button_cb_showAll (I, GuiButtonEvent /*event*/) { iam (FunctionEditor); do_showAll (me); } static void do_zoomIn (FunctionEditor me) { double shift = (my d_endWindow - my d_startWindow) / 4; my d_startWindow += shift; my d_endWindow -= shift; my v_updateText (); updateScrollBar (me); /*Graphics_updateWs (my d_graphics);*/ drawNow (me); if (my pref_synchronizedZoomAndScroll ()) { updateGroup (me); } } static void gui_button_cb_zoomIn (I, GuiButtonEvent /*event*/) { iam (FunctionEditor); do_zoomIn (me); } static void do_zoomOut (FunctionEditor me) { double shift = (my d_endWindow - my d_startWindow) / 2; MelderAudio_stopPlaying (MelderAudio_IMPLICIT); /* Quickly, before window changes. */ my d_startWindow -= shift; if (my d_startWindow < my tmin + 1e-12) my d_startWindow = my tmin; my d_endWindow += shift; if (my d_endWindow > my tmax - 1e-12) my d_endWindow = my tmax; my v_updateText (); updateScrollBar (me); /*Graphics_updateWs (my d_graphics);*/ drawNow (me); if (my pref_synchronizedZoomAndScroll ()) { updateGroup (me); } } static void gui_button_cb_zoomOut (I, GuiButtonEvent /*event*/) { iam (FunctionEditor); do_zoomOut (me); } static void do_zoomToSelection (FunctionEditor me) { if (my d_endSelection > my d_startSelection) { my startZoomHistory = my d_startWindow; // remember for Zoom Back my endZoomHistory = my d_endWindow; // remember for Zoom Back trace (U"Zooming in to ", my d_startSelection, U" ~ ", my d_endSelection, U" seconds."); my d_startWindow = my d_startSelection; my d_endWindow = my d_endSelection; trace (U"Zoomed in to ", my d_startWindow, U" ~ ", my d_endWindow, U" seconds (1)."); my v_updateText (); trace (U"Zoomed in to ", my d_startWindow, U" ~ ", my d_endWindow, U" seconds (2)."); updateScrollBar (me); trace (U"Zoomed in to ", my d_startWindow, U" ~ ", my d_endWindow, U" seconds (3)."); /*Graphics_updateWs (my d_graphics);*/ drawNow (me); if (my pref_synchronizedZoomAndScroll ()) { updateGroup (me); } trace (U"Zoomed in to ", my d_startWindow, U" ~ ", my d_endWindow, U" seconds (4)."); } } static void gui_button_cb_zoomToSelection (I, GuiButtonEvent /*event*/) { iam (FunctionEditor); do_zoomToSelection (me); } static void do_zoomBack (FunctionEditor me) { if (my endZoomHistory > my startZoomHistory) { my d_startWindow = my startZoomHistory; my d_endWindow = my endZoomHistory; my v_updateText (); updateScrollBar (me); /*Graphics_updateWs (my d_graphics);*/ drawNow (me); if (my pref_synchronizedZoomAndScroll ()) { updateGroup (me); } } } static void gui_button_cb_zoomBack (I, GuiButtonEvent /*event*/) { iam (FunctionEditor); do_zoomBack (me); } static void menu_cb_showAll (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); do_showAll (me); } static void menu_cb_zoomIn (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); do_zoomIn (me); } static void menu_cb_zoomOut (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); do_zoomOut (me); } static void menu_cb_zoomToSelection (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); do_zoomToSelection (me); } static void menu_cb_zoomBack (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); do_zoomBack (me); } static void menu_cb_play (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); EDITOR_FORM (U"Play", 0) REAL (U"From", U"0.0") REAL (U"To", U"1.0") EDITOR_OK SET_REAL (U"From", my d_startWindow) SET_REAL (U"To", my d_endWindow) EDITOR_DO MelderAudio_stopPlaying (MelderAudio_IMPLICIT); my v_play (GET_REAL (U"From"), GET_REAL (U"To")); EDITOR_END } static void menu_cb_playOrStop (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); if (MelderAudio_isPlaying) { MelderAudio_stopPlaying (MelderAudio_EXPLICIT); } else if (my d_startSelection < my d_endSelection) { my playingSelection = true; my v_play (my d_startSelection, my d_endSelection); } else { my playingCursor = true; if (my d_startSelection == my d_endSelection && my d_startSelection > my d_startWindow && my d_startSelection < my d_endWindow) my v_play (my d_startSelection, my d_endWindow); else my v_play (my d_startWindow, my d_endWindow); } } static void menu_cb_playWindow (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); MelderAudio_stopPlaying (MelderAudio_IMPLICIT); my playingCursor = true; my v_play (my d_startWindow, my d_endWindow); } static void menu_cb_interruptPlaying (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); MelderAudio_stopPlaying (MelderAudio_IMPLICIT); } /********** SELECT MENU **********/ static void menu_cb_select (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); EDITOR_FORM (U"Select", 0) REAL (U"Start of selection", U"0.0") REAL (U"End of selection", U"1.0") EDITOR_OK SET_REAL (U"Start of selection", my d_startSelection) SET_REAL (U"End of selection", my d_endSelection) EDITOR_DO my d_startSelection = GET_REAL (U"Start of selection"); if (my d_startSelection < my tmin + 1e-12) my d_startSelection = my tmin; my d_endSelection = GET_REAL (U"End of selection"); if (my d_endSelection > my tmax - 1e-12) my d_endSelection = my tmax; if (my d_startSelection > my d_endSelection) { double dummy = my d_startSelection; my d_startSelection = my d_endSelection; my d_endSelection = dummy; } my v_updateText (); /*Graphics_updateWs (my d_graphics);*/ drawNow (me); updateGroup (me); EDITOR_END } static void menu_cb_moveCursorToB (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); my d_endSelection = my d_startSelection; my v_updateText (); /*Graphics_updateWs (my d_graphics);*/ drawNow (me); updateGroup (me); } static void menu_cb_moveCursorToE (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); my d_startSelection = my d_endSelection; my v_updateText (); /*Graphics_updateWs (my d_graphics);*/ drawNow (me); updateGroup (me); } static void menu_cb_moveCursorTo (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); EDITOR_FORM (U"Move cursor to", 0) REAL (U"Position", U"0.0") EDITOR_OK SET_REAL (U"Position", 0.5 * (my d_startSelection + my d_endSelection)) EDITOR_DO double position = GET_REAL (U"Position"); if (position < my tmin + 1e-12) position = my tmin; if (position > my tmax - 1e-12) position = my tmax; my d_startSelection = my d_endSelection = position; my v_updateText (); /*Graphics_updateWs (my d_graphics);*/ drawNow (me); updateGroup (me); EDITOR_END } static void menu_cb_moveCursorBy (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); EDITOR_FORM (U"Move cursor by", 0) REAL (U"Distance", U"0.05") EDITOR_OK EDITOR_DO double position = 0.5 * (my d_startSelection + my d_endSelection) + GET_REAL (U"Distance"); if (position < my tmin) position = my tmin; if (position > my tmax) position = my tmax; my d_startSelection = my d_endSelection = position; my v_updateText (); /*Graphics_updateWs (my d_graphics);*/ drawNow (me); updateGroup (me); EDITOR_END } static void menu_cb_moveBby (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); EDITOR_FORM (U"Move start of selection by", 0) REAL (U"Distance", U"0.05") EDITOR_OK EDITOR_DO double position = my d_startSelection + GET_REAL (U"Distance"); if (position < my tmin) position = my tmin; if (position > my tmax) position = my tmax; my d_startSelection = position; if (my d_startSelection > my d_endSelection) { double dummy = my d_startSelection; my d_startSelection = my d_endSelection; my d_endSelection = dummy; } my v_updateText (); /*Graphics_updateWs (my d_graphics);*/ drawNow (me); updateGroup (me); EDITOR_END } static void menu_cb_moveEby (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); EDITOR_FORM (U"Move end of selection by", 0) REAL (U"Distance", U"0.05") EDITOR_OK EDITOR_DO double position = my d_endSelection + GET_REAL (U"Distance"); if (position < my tmin) position = my tmin; if (position > my tmax) position = my tmax; my d_endSelection = position; if (my d_startSelection > my d_endSelection) { double dummy = my d_startSelection; my d_startSelection = my d_endSelection; my d_endSelection = dummy; } my v_updateText (); /*Graphics_updateWs (my d_graphics);*/ drawNow (me); updateGroup (me); EDITOR_END } void FunctionEditor_shift (FunctionEditor me, double shift, bool needsUpdateGroup) { double windowLength = my d_endWindow - my d_startWindow; MelderAudio_stopPlaying (MelderAudio_IMPLICIT); /* Quickly, before window changes. */ trace (U"shifting by ", shift); if (shift < 0.0) { my d_startWindow += shift; if (my d_startWindow < my tmin + 1e-12) my d_startWindow = my tmin; my d_endWindow = my d_startWindow + windowLength; if (my d_endWindow > my tmax - 1e-12) my d_endWindow = my tmax; } else { my d_endWindow += shift; if (my d_endWindow > my tmax - 1e-12) my d_endWindow = my tmax; my d_startWindow = my d_endWindow - windowLength; if (my d_startWindow < my tmin + 1e-12) my d_startWindow = my tmin; } FunctionEditor_marksChanged (me, needsUpdateGroup); } static void menu_cb_pageUp (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); FunctionEditor_shift (me, -RELATIVE_PAGE_INCREMENT * (my d_endWindow - my d_startWindow), true); } static void menu_cb_pageDown (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); FunctionEditor_shift (me, +RELATIVE_PAGE_INCREMENT * (my d_endWindow - my d_startWindow), true); } static void scrollToView (FunctionEditor me, double t) { if (t <= my d_startWindow) { FunctionEditor_shift (me, t - my d_startWindow - 0.618 * (my d_endWindow - my d_startWindow), true); } else if (t >= my d_endWindow) { FunctionEditor_shift (me, t - my d_endWindow + 0.618 * (my d_endWindow - my d_startWindow), true); } else { FunctionEditor_marksChanged (me, true); } } static void menu_cb_selectEarlier (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); my d_startSelection -= my p_arrowScrollStep; if (my d_startSelection < my tmin + 1e-12) my d_startSelection = my tmin; my d_endSelection -= my p_arrowScrollStep; if (my d_endSelection < my tmin + 1e-12) my d_endSelection = my tmin; scrollToView (me, 0.5 * (my d_startSelection + my d_endSelection)); } static void menu_cb_selectLater (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); my d_startSelection += my p_arrowScrollStep; if (my d_startSelection > my tmax - 1e-12) my d_startSelection = my tmax; my d_endSelection += my p_arrowScrollStep; if (my d_endSelection > my tmax - 1e-12) my d_endSelection = my tmax; scrollToView (me, 0.5 * (my d_startSelection + my d_endSelection)); } static void menu_cb_moveBleft (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); my d_startSelection -= my p_arrowScrollStep; if (my d_startSelection < my tmin + 1e-12) my d_startSelection = my tmin; scrollToView (me, 0.5 * (my d_startSelection + my d_endSelection)); } static void menu_cb_moveBright (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); my d_startSelection += my p_arrowScrollStep; if (my d_startSelection > my tmax - 1e-12) my d_startSelection = my tmax; if (my d_startSelection > my d_endSelection) { double dummy = my d_startSelection; my d_startSelection = my d_endSelection; my d_endSelection = dummy; } scrollToView (me, 0.5 * (my d_startSelection + my d_endSelection)); } static void menu_cb_moveEleft (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); my d_endSelection -= my p_arrowScrollStep; if (my d_endSelection < my tmin + 1e-12) my d_endSelection = my tmin; if (my d_startSelection > my d_endSelection) { double dummy = my d_startSelection; my d_startSelection = my d_endSelection; my d_endSelection = dummy; } scrollToView (me, 0.5 * (my d_startSelection + my d_endSelection)); } static void menu_cb_moveEright (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); my d_endSelection += my p_arrowScrollStep; if (my d_endSelection > my tmax - 1e-12) my d_endSelection = my tmax; scrollToView (me, 0.5 * (my d_startSelection + my d_endSelection)); } /********** GUI CALLBACKS **********/ static void gui_cb_scroll (I, GuiScrollBarEvent event) { iam (FunctionEditor); if (! my d_graphics) return; // ignore events during creation double value = GuiScrollBar_getValue (event -> scrollBar); double shift = my tmin + (value - 1) * (my tmax - my tmin) / maximumScrollBarValue - my d_startWindow; bool shifted = shift != 0.0; double oldSliderSize = (my d_endWindow - my d_startWindow) / (my tmax - my tmin) * maximumScrollBarValue - 1; double newSliderSize = GuiScrollBar_getSliderSize (event -> scrollBar); bool zoomed = newSliderSize != oldSliderSize; #if ! cocoa zoomed = false; #endif if (shifted) { my d_startWindow += shift; if (my d_startWindow < my tmin + 1e-12) my d_startWindow = my tmin; my d_endWindow += shift; if (my d_endWindow > my tmax - 1e-12) my d_endWindow = my tmax; } if (zoomed) { double zoom = (newSliderSize + 1) * (my tmax - my tmin) / maximumScrollBarValue; my d_endWindow = my d_startWindow + zoom; if (my d_endWindow > my tmax - 1e-12) my d_endWindow = my tmax; } if (shifted || zoomed) { my v_updateText (); updateScrollBar (me); #if cocoa Graphics_updateWs (my d_graphics); #else /*Graphics_clearWs (my d_graphics);*/ drawNow (me); /* Do not wait for expose event. */ #endif if (! my group || ! my pref_synchronizedZoomAndScroll ()) return; for (int i = 1; i <= maxGroup; i ++) if (theGroup [i] && theGroup [i] != me) { theGroup [i] -> d_startWindow = my d_startWindow; theGroup [i] -> d_endWindow = my d_endWindow; FunctionEditor_updateText (theGroup [i]); updateScrollBar (theGroup [i]); #if cocoa Graphics_updateWs (theGroup [i] -> d_graphics); #else Graphics_clearWs (theGroup [i] -> d_graphics); drawNow (theGroup [i]); #endif } } } static void gui_checkbutton_cb_group (I, GuiCheckButtonEvent event) { iam (FunctionEditor); (void) event; int i; my group = ! my group; if (my group) { FunctionEditor thee; i = 1; while (theGroup [i]) i ++; theGroup [i] = me; if (++ nGroup == 1) { Graphics_updateWs (my d_graphics); return; } i = 1; while (theGroup [i] == nullptr || theGroup [i] == me) i ++; thee = theGroup [i]; if (my pref_synchronizedZoomAndScroll ()) { my d_startWindow = thy d_startWindow; my d_endWindow = thy d_endWindow; } my d_startSelection = thy d_startSelection; my d_endSelection = thy d_endSelection; if (my tmin > thy tmin || my tmax < thy tmax) { if (my tmin > thy tmin) my tmin = thy tmin; if (my tmax < thy tmax) my tmax = thy tmax; my v_updateText (); updateScrollBar (me); Graphics_updateWs (my d_graphics); } else { my v_updateText (); updateScrollBar (me); Graphics_updateWs (my d_graphics); if (my tmin < thy tmin || my tmax > thy tmax) for (i = 1; i <= maxGroup; i ++) if (theGroup [i] && theGroup [i] != me) { if (my tmin < thy tmin) theGroup [i] -> tmin = my tmin; if (my tmax > thy tmax) theGroup [i] -> tmax = my tmax; FunctionEditor_updateText (theGroup [i]); updateScrollBar (theGroup [i]); Graphics_updateWs (theGroup [i] -> d_graphics); } } } else { i = 1; while (theGroup [i] != me) i ++; theGroup [i] = nullptr; nGroup --; my v_updateText (); Graphics_updateWs (my d_graphics); // for setting buttons in draw method } if (my group) updateGroup (me); } static void menu_cb_intro (EDITOR_ARGS) { EDITOR_IAM (FunctionEditor); Melder_help (U"Intro"); } void structFunctionEditor :: v_createMenuItems_file (EditorMenu menu) { FunctionEditor_Parent :: v_createMenuItems_file (menu); EditorMenu_addCommand (menu, U"Preferences...", 0, menu_cb_preferences); EditorMenu_addCommand (menu, U"-- after preferences --", 0, 0); } void structFunctionEditor :: v_createMenuItems_view_timeDomain (EditorMenu menu) { EditorMenu_addCommand (menu, v_format_domain (), GuiMenu_INSENSITIVE, menu_cb_zoom /* dummy */); EditorMenu_addCommand (menu, U"Zoom...", 0, menu_cb_zoom); EditorMenu_addCommand (menu, U"Show all", 'A', menu_cb_showAll); EditorMenu_addCommand (menu, U"Zoom in", 'I', menu_cb_zoomIn); EditorMenu_addCommand (menu, U"Zoom out", 'O', menu_cb_zoomOut); EditorMenu_addCommand (menu, U"Zoom to selection", 'N', menu_cb_zoomToSelection); EditorMenu_addCommand (menu, U"Zoom back", 'B', menu_cb_zoomBack); EditorMenu_addCommand (menu, U"Scroll page back", GuiMenu_PAGE_UP, menu_cb_pageUp); EditorMenu_addCommand (menu, U"Scroll page forward", GuiMenu_PAGE_DOWN, menu_cb_pageDown); } void structFunctionEditor :: v_createMenuItems_view_audio (EditorMenu menu) { EditorMenu_addCommand (menu, U"-- play --", 0, 0); EditorMenu_addCommand (menu, U"Audio:", GuiMenu_INSENSITIVE, menu_cb_play /* dummy */); EditorMenu_addCommand (menu, U"Play...", 0, menu_cb_play); EditorMenu_addCommand (menu, U"Play or stop", GuiMenu_TAB, menu_cb_playOrStop); EditorMenu_addCommand (menu, U"Play window", GuiMenu_SHIFT + GuiMenu_TAB, menu_cb_playWindow); EditorMenu_addCommand (menu, U"Interrupt playing", GuiMenu_ESCAPE, menu_cb_interruptPlaying); } void structFunctionEditor :: v_createMenuItems_view (EditorMenu menu) { v_createMenuItems_view_timeDomain (menu); v_createMenuItems_view_audio (menu); } void structFunctionEditor :: v_createMenuItems_query (EditorMenu menu) { FunctionEditor_Parent :: v_createMenuItems_query (menu); EditorMenu_addCommand (menu, U"-- query selection --", 0, 0); EditorMenu_addCommand (menu, U"Get start of selection", 0, menu_cb_getB); EditorMenu_addCommand (menu, U"Get begin of selection", Editor_HIDDEN, menu_cb_getB); EditorMenu_addCommand (menu, U"Get cursor", GuiMenu_F6, menu_cb_getCursor); EditorMenu_addCommand (menu, U"Get end of selection", 0, menu_cb_getE); EditorMenu_addCommand (menu, U"Get selection length", 0, menu_cb_getSelectionDuration); } void structFunctionEditor :: v_createMenus () { FunctionEditor_Parent :: v_createMenus (); EditorMenu menu; menu = Editor_addMenu (this, U"View", 0); v_createMenuItems_view (menu); Editor_addMenu (this, U"Select", 0); Editor_addCommand (this, U"Select", U"Select...", 0, menu_cb_select); Editor_addCommand (this, U"Select", U"Move cursor to start of selection", 0, menu_cb_moveCursorToB); Editor_addCommand (this, U"Select", U"Move cursor to begin of selection", Editor_HIDDEN, menu_cb_moveCursorToB); Editor_addCommand (this, U"Select", U"Move cursor to end of selection", 0, menu_cb_moveCursorToE); Editor_addCommand (this, U"Select", U"Move cursor to...", 0, menu_cb_moveCursorTo); Editor_addCommand (this, U"Select", U"Move cursor by...", 0, menu_cb_moveCursorBy); Editor_addCommand (this, U"Select", U"Move start of selection by...", 0, menu_cb_moveBby); Editor_addCommand (this, U"Select", U"Move begin of selection by...", Editor_HIDDEN, menu_cb_moveBby); Editor_addCommand (this, U"Select", U"Move end of selection by...", 0, menu_cb_moveEby); /*Editor_addCommand (this, U"Select", U"Move cursor back by half a second", motif_, menu_cb_moveCursorBy);*/ Editor_addCommand (this, U"Select", U"Select earlier", GuiMenu_UP_ARROW, menu_cb_selectEarlier); Editor_addCommand (this, U"Select", U"Select later", GuiMenu_DOWN_ARROW, menu_cb_selectLater); Editor_addCommand (this, U"Select", U"Move start of selection left", GuiMenu_SHIFT + GuiMenu_UP_ARROW, menu_cb_moveBleft); Editor_addCommand (this, U"Select", U"Move begin of selection left", Editor_HIDDEN, menu_cb_moveBleft); Editor_addCommand (this, U"Select", U"Move start of selection right", GuiMenu_SHIFT + GuiMenu_DOWN_ARROW, menu_cb_moveBright); Editor_addCommand (this, U"Select", U"Move begin of selection right", Editor_HIDDEN, menu_cb_moveBright); Editor_addCommand (this, U"Select", U"Move end of selection left", GuiMenu_COMMAND + GuiMenu_UP_ARROW, menu_cb_moveEleft); Editor_addCommand (this, U"Select", U"Move end of selection right", GuiMenu_COMMAND + GuiMenu_DOWN_ARROW, menu_cb_moveEright); } void structFunctionEditor :: v_createHelpMenuItems (EditorMenu menu) { FunctionEditor_Parent :: v_createHelpMenuItems (menu); EditorMenu_addCommand (menu, U"Intro", 0, menu_cb_intro); } static void gui_drawingarea_cb_expose (I, GuiDrawingAreaExposeEvent /* event */) { iam (FunctionEditor); if (! my d_graphics) return; // could be the case in the very beginning if (my enableUpdates) drawNow (me); } static void gui_drawingarea_cb_click (I, GuiDrawingAreaClickEvent event) { iam (FunctionEditor); if (! my d_graphics) return; // could be the case in the very beginning my shiftKeyPressed = event -> shiftKeyPressed; Graphics_setWindow (my d_graphics, my functionViewerLeft, my functionViewerRight, 0, my height); double xWC, yWC; Graphics_DCtoWC (my d_graphics, event -> x, event -> y, & xWC, & yWC); if (yWC > BOTTOM_MARGIN + space * 3 && yWC < my height - (TOP_MARGIN + space)) { // in signal region? int needsUpdate; Graphics_setViewport (my d_graphics, my functionViewerLeft + MARGIN, my functionViewerRight - MARGIN, BOTTOM_MARGIN + space * 3, my height - (TOP_MARGIN + space)); Graphics_setWindow (my d_graphics, my d_startWindow, my d_endWindow, 0.0, 1.0); Graphics_DCtoWC (my d_graphics, event -> x, event -> y, & xWC, & yWC); if (xWC < my d_startWindow) xWC = my d_startWindow; if (xWC > my d_endWindow) xWC = my d_endWindow; if (Melder_debug == 24) { Melder_casual (U"FunctionEditor::gui_drawingarea_cb_click:" U" button ", event -> button, U" shift ", my shiftKeyPressed, U" option ", event -> optionKeyPressed, U" command ", event -> commandKeyPressed, U" control ", event -> extraControlKeyPressed); } #if defined (macintosh) needsUpdate = event -> optionKeyPressed || event -> extraControlKeyPressed ? my v_clickB (xWC, yWC) : event -> commandKeyPressed ? my v_clickE (xWC, yWC) : my v_click (xWC, yWC, my shiftKeyPressed); #elif defined (_WIN32) needsUpdate = event -> commandKeyPressed ? my v_clickB (xWC, yWC) : event -> optionKeyPressed ? my v_clickE (xWC, yWC) : my v_click (xWC, yWC, my shiftKeyPressed); #else needsUpdate = event -> commandKeyPressed ? my v_clickB (xWC, yWC) : event -> optionKeyPressed ? my v_clickE (xWC, yWC) : event -> button == 1 ? my v_click (xWC, yWC, my shiftKeyPressed) : event -> button == 2 ? my v_clickB (xWC, yWC) : my v_clickE (xWC, yWC); #endif if (needsUpdate) my v_updateText (); Graphics_setViewport (my d_graphics, my functionViewerLeft, my functionViewerRight, 0, my height); if (needsUpdate) { drawNow (me); } if (needsUpdate) updateGroup (me); } else /* Clicked outside signal region? Let us hear it. */ { try { for (int i = 0; i < 8; i ++) { if (xWC > my rect [i]. left && xWC < my rect [i]. right && yWC > my rect [i]. bottom && yWC < my rect [i]. top) switch (i) { case 0: my v_play (my tmin, my tmax); break; case 1: my v_play (my d_startWindow, my d_endWindow); break; case 2: my v_play (my tmin, my d_startWindow); break; case 3: my v_play (my d_endWindow, my tmax); break; case 4: my v_play (my d_startWindow, my marker [1]); break; case 5: my v_play (my marker [1], my marker [2]); break; case 6: my v_play (my marker [2], my marker [3]); break; case 7: my v_play (my d_startSelection, my d_endSelection); break; } } } catch (MelderError) { Melder_flushError (); } } } void structFunctionEditor :: v_createChildren () { int x = BUTTON_X; /***** Create zoom buttons. *****/ GuiButton_createShown (our d_windowForm, x, x + BUTTON_WIDTH, -4 - Gui_PUSHBUTTON_HEIGHT, -4, U"all", gui_button_cb_showAll, this, 0); x += BUTTON_WIDTH + BUTTON_SPACING; GuiButton_createShown (our d_windowForm, x, x + BUTTON_WIDTH, -4 - Gui_PUSHBUTTON_HEIGHT, -4, U"in", gui_button_cb_zoomIn, this, 0); x += BUTTON_WIDTH + BUTTON_SPACING; GuiButton_createShown (our d_windowForm, x, x + BUTTON_WIDTH, -4 - Gui_PUSHBUTTON_HEIGHT, -4, U"out", gui_button_cb_zoomOut, this, 0); x += BUTTON_WIDTH + BUTTON_SPACING; GuiButton_createShown (our d_windowForm, x, x + BUTTON_WIDTH, -4 - Gui_PUSHBUTTON_HEIGHT, -4, U"sel", gui_button_cb_zoomToSelection, this, 0); x += BUTTON_WIDTH + BUTTON_SPACING; GuiButton_createShown (our d_windowForm, x, x + BUTTON_WIDTH, -4 - Gui_PUSHBUTTON_HEIGHT, -4, U"bak", gui_button_cb_zoomBack, this, 0); /***** Create scroll bar. *****/ our scrollBar = GuiScrollBar_createShown (our d_windowForm, x += BUTTON_WIDTH + BUTTON_SPACING, -80 - BUTTON_SPACING, -4 - Gui_PUSHBUTTON_HEIGHT, 0, 1, maximumScrollBarValue, 1, maximumScrollBarValue - 1, 1, 1, gui_cb_scroll, this, GuiScrollBar_HORIZONTAL); /***** Create Group button. *****/ our groupButton = GuiCheckButton_createShown (d_windowForm, -80, 0, -4 - Gui_PUSHBUTTON_HEIGHT, -4, U"Group", gui_checkbutton_cb_group, this, group_equalDomain (our tmin, our tmax) ? GuiCheckButton_SET : 0); /***** Create optional text field. *****/ if (our v_hasText ()) { our text = GuiText_createShown (our d_windowForm, 0, 0, Machine_getMenuBarHeight (), Machine_getMenuBarHeight () + TEXT_HEIGHT, GuiText_WORDWRAP | GuiText_MULTILINE); #if gtk Melder_assert (our text -> d_widget); gtk_widget_grab_focus (GTK_WIDGET (our text -> d_widget)); // BUG: can hardly be correct (the text should grab the focus of the window, not the global focus) #elif cocoa Melder_assert ([(NSView *) our text -> d_widget window]); //[[(NSView *) our text -> d_widget window] setInitialFirstResponder: (NSView *) our text -> d_widget]; [[(NSView *) our text -> d_widget window] makeFirstResponder: (NSView *) our text -> d_widget]; #endif } /***** Create drawing area. *****/ #if cocoa int marginBetweenTextAndDrawingAreaToEnsureCorrectUnhighlighting = 3; #else int marginBetweenTextAndDrawingAreaToEnsureCorrectUnhighlighting = 0; #endif our drawingArea = GuiDrawingArea_createShown (our d_windowForm, 0, 0, Machine_getMenuBarHeight () + ( our v_hasText () ? TEXT_HEIGHT + marginBetweenTextAndDrawingAreaToEnsureCorrectUnhighlighting : 0), -8 - Gui_PUSHBUTTON_HEIGHT, gui_drawingarea_cb_expose, gui_drawingarea_cb_click, nullptr, gui_drawingarea_cb_resize, this, 0); GuiDrawingArea_setSwipable (our drawingArea, our scrollBar, nullptr); } void structFunctionEditor :: v_dataChanged () { Function function = (Function) our data; Melder_assert (Thing_isa (function, classFunction)); our tmin = function -> xmin; our tmax = function -> xmax; if (our d_startWindow < our tmin || our d_startWindow > our tmax) our d_startWindow = our tmin; if (our d_endWindow < our tmin || our d_endWindow > our tmax) our d_endWindow = our tmax; if (our d_startWindow >= our d_endWindow) { our d_startWindow = our tmin; our d_endWindow = our tmax; } if (our d_startSelection < our tmin) our d_startSelection = our tmin; if (our d_startSelection > our tmax) our d_startSelection = our tmax; if (our d_endSelection < our tmin) our d_endSelection = our tmin; if (our d_endSelection > our tmax) our d_endSelection = our tmax; FunctionEditor_marksChanged (this, false); } static void drawWhileDragging (FunctionEditor me, double x1, double x2) { /* * We must draw this within the window, because the window tends to have a white background. * We cannot draw this in the margins, because these tend to be grey, so that Graphics_xorOn does not work properly. * We draw the text twice, because we expect that not ALL of the window is white... */ double xleft, xright; if (x1 > x2) xleft = x2, xright = x1; else xleft = x1, xright = x2; Graphics_xorOn (my d_graphics, Graphics_MAROON); Graphics_setTextAlignment (my d_graphics, Graphics_RIGHT, Graphics_TOP); Graphics_text (my d_graphics, xleft, 1.0, Melder_fixed (xleft, 6)); Graphics_setTextAlignment (my d_graphics, Graphics_LEFT, Graphics_TOP); Graphics_text (my d_graphics, xright, 1.0, Melder_fixed (xright, 6)); Graphics_setTextAlignment (my d_graphics, Graphics_RIGHT, Graphics_BOTTOM); Graphics_text (my d_graphics, xleft, 0.0, Melder_fixed (xleft, 6)); Graphics_setTextAlignment (my d_graphics, Graphics_LEFT, Graphics_BOTTOM); Graphics_text (my d_graphics, xright, 0.0, Melder_fixed (xright, 6)); Graphics_setLineType (my d_graphics, Graphics_DOTTED); Graphics_line (my d_graphics, xleft, 0.0, xleft, 1.0); Graphics_line (my d_graphics, xright, 0.0, xright, 1.0); Graphics_setLineType (my d_graphics, Graphics_DRAWN); Graphics_xorOff (my d_graphics); } int structFunctionEditor :: v_click (double xbegin, double ybegin, bool a_shiftKeyPressed) { bool drag = false; double x = xbegin, y = ybegin; /* * The 'anchor' is the point that will stay fixed during dragging. * For instance, if she clicks and drags to the right, * the location at which she originally clicked will be the anchor, * even if she later chooses to drag the mouse to the left of it. * Another example: if she shift-clicks near E, B will become (and stay) the anchor. */ Graphics_setWindow (d_graphics, d_startWindow, d_endWindow, 0, 1); double anchorForDragging = xbegin; // the default (for if the shift key isn't pressed) if (a_shiftKeyPressed) { /* * Extend the selection. * We should always end up with a real selection (B < E), * even if we start with the reversed temporal order (E < B). */ bool reversed = d_startSelection > d_endSelection; double firstMark = reversed ? d_endSelection : d_startSelection; double secondMark = reversed ? d_startSelection : d_endSelection; /* * Undraw the old selection. */ if (d_endSelection > d_startSelection) { /* * Determine the visible part of the old selection. */ double startVisible = d_startSelection > d_startWindow ? d_startSelection : d_startWindow; double endVisible = d_endSelection < d_endWindow ? d_endSelection : d_endWindow; /* * Undraw the visible part of the old selection. */ if (endVisible > startVisible) { v_unhighlightSelection (startVisible, endVisible, 0, 1); //Graphics_flushWs (d_graphics); } } if (xbegin >= secondMark) { /* * She clicked right from the second mark (usually E). We move E. */ d_endSelection = xbegin; anchorForDragging = d_startSelection; } else if (xbegin <= firstMark) { /* * She clicked left from the first mark (usually B). We move B. */ d_startSelection = xbegin; anchorForDragging = d_endSelection; } else { /* * She clicked in between the two marks. We move the nearest mark. */ double distanceOfClickToFirstMark = fabs (xbegin - firstMark); double distanceOfClickToSecondMark = fabs (xbegin - secondMark); /* * We make sure that the marks are in the unmarked B - E order. */ if (reversed) { /* * Swap B and E. */ d_startSelection = firstMark; d_endSelection = secondMark; } /* * Move the nearest mark. */ if (distanceOfClickToFirstMark < distanceOfClickToSecondMark) { d_startSelection = xbegin; anchorForDragging = d_endSelection; } else { d_endSelection = xbegin; anchorForDragging = d_startSelection; } } /* * Draw the new selection. */ if (d_endSelection > d_startSelection) { /* * Determine the visible part of the new selection. */ double startVisible = d_startSelection > d_startWindow ? d_startSelection : d_startWindow; double endVisible = d_endSelection < d_endWindow ? d_endSelection : d_endWindow; /* * Draw the visible part of the new selection. */ if (endVisible > startVisible) v_highlightSelection (startVisible, endVisible, 0, 1); } } /* * Find out whether this is a click or a drag. */ while (Graphics_mouseStillDown (d_graphics)) { Graphics_getMouseLocation (d_graphics, & x, & y); if (x < d_startWindow) x = d_startWindow; if (x > d_endWindow) x = d_endWindow; if (fabs (Graphics_dxWCtoMM (d_graphics, x - xbegin)) > 1.5) { drag = true; break; } } if (drag) { /* * First undraw the old selection. */ if (d_endSelection > d_startSelection) { /* * Determine the visible part of the old selection. */ double startVisible = d_startSelection > d_startWindow ? d_startSelection : d_startWindow; double endVisible = d_endSelection < d_endWindow ? d_endSelection : d_endWindow; /* * Undraw the visible part of the old selection. */ if (endVisible > startVisible) v_unhighlightSelection (startVisible, endVisible, 0, 1); } /* * Draw the text at least once. */ /*if (x < d_startWindow) x = d_startWindow; else if (x > d_endWindow) x = d_endWindow;*/ drawWhileDragging (this, anchorForDragging, x); /* * Draw the dragged selection at least once. */ { double x1, x2; if (x > anchorForDragging) x1 = anchorForDragging, x2 = x; else x1 = x, x2 = anchorForDragging; v_highlightSelection (x1, x2, 0, 1); } /* * Drag for the new selection. */ while (Graphics_mouseStillDown (d_graphics)) { double xold = x, x1, x2; Graphics_getMouseLocation (d_graphics, & x, & y); /* * Clip to the visible window. Ideally, we should perform autoscrolling instead, though... */ if (x < d_startWindow) x = d_startWindow; else if (x > d_endWindow) x = d_endWindow; if (x == xold) continue; /* * Undraw previous dragged selection. */ if (xold > anchorForDragging) x1 = anchorForDragging, x2 = xold; else x1 = xold, x2 = anchorForDragging; if (x1 != x2) v_unhighlightSelection (x1, x2, 0, 1); /* * Undraw the text. */ drawWhileDragging (this, anchorForDragging, xold); /* * Redraw the text at the new location. */ drawWhileDragging (this, anchorForDragging, x); /* * Draw new dragged selection. */ if (x > anchorForDragging) x1 = anchorForDragging, x2 = x; else x1 = x, x2 = anchorForDragging; if (x1 != x2) v_highlightSelection (x1, x2, 0, 1); } ; /* * Set the new selection. */ if (x > anchorForDragging) d_startSelection = anchorForDragging, d_endSelection = x; else d_startSelection = x, d_endSelection = anchorForDragging; } else if (! a_shiftKeyPressed) { /* * Move the cursor to the clicked position. */ d_startSelection = d_endSelection = xbegin; } return FunctionEditor_UPDATE_NEEDED; } int structFunctionEditor :: v_clickB (double xWC, double yWC) { (void) yWC; d_startSelection = xWC; if (d_startSelection > d_endSelection) { double dummy = d_startSelection; d_startSelection = d_endSelection; d_endSelection = dummy; } return 1; } int structFunctionEditor :: v_clickE (double xWC, double yWC) { d_endSelection = xWC; (void) yWC; if (d_startSelection > d_endSelection) { double dummy = d_startSelection; d_startSelection = d_endSelection; d_endSelection = dummy; } return 1; } void FunctionEditor_insetViewport (FunctionEditor me) { Graphics_setViewport (my d_graphics, my functionViewerLeft + MARGIN, my functionViewerRight - MARGIN, BOTTOM_MARGIN + space * 3, my height - (TOP_MARGIN + space)); Graphics_setWindow (my d_graphics, my d_startWindow, my d_endWindow, 0, 1); } int structFunctionEditor :: v_playCallback (int phase, double a_tmin, double a_tmax, double t) { /* * This callback will often be called by the Melder workproc during playback. * However, it will sometimes be called by Melder_stopPlaying with phase=3. * This will occur at unpredictable times, perhaps when the LongSound is updated. * So we had better make no assumptions about the current viewport. */ double x1NDC, x2NDC, y1NDC, y2NDC; (void) a_tmin; Graphics_inqViewport (d_graphics, & x1NDC, & x2NDC, & y1NDC, & y2NDC); FunctionEditor_insetViewport (this); Graphics_xorOn (d_graphics, Graphics_MAROON); /* * Undraw the play cursor at its old location. * BUG: during scrolling, zooming, and exposure, an ugly line may remain. */ if (phase != 1 && playCursor >= d_startWindow && playCursor <= d_endWindow) { Graphics_setLineWidth (d_graphics, 3.0); Graphics_line (d_graphics, playCursor, 0, playCursor, 1); Graphics_setLineWidth (d_graphics, 1.0); } /* * Draw the play cursor at its new location. */ if (phase != 3 && t >= d_startWindow && t <= d_endWindow) { Graphics_setLineWidth (d_graphics, 3.0); Graphics_line (d_graphics, t, 0, t, 1); Graphics_setLineWidth (d_graphics, 1.0); } Graphics_xorOff (d_graphics); /* * Usually, there will be an event test after each invocation of this callback, * because the asynchronicity is kMelder_asynchronicityLevel_INTERRUPTABLE or kMelder_asynchronicityLevel_ASYNCHRONOUS. * However, if the asynchronicity is just kMelder_asynchronicityLevel_CALLING_BACK, * there is no event test. Which means: no server round trip. * Which means: no automatic flushing of graphics output. * So: we force the flushing ourselves, lest we see too few moving cursors. */ Graphics_flushWs (d_graphics); Graphics_setViewport (d_graphics, x1NDC, x2NDC, y1NDC, y2NDC); playCursor = t; if (phase == 3) { if (t < a_tmax && MelderAudio_stopWasExplicit ()) { if (t > d_startSelection && t < d_endSelection) d_startSelection = t; else d_startSelection = d_endSelection = t; v_updateText (); /*Graphics_updateWs (d_graphics);*/ drawNow (this); updateGroup (this); } playingCursor = false; playingSelection = false; } return 1; } int theFunctionEditor_playCallback (void *void_me, int phase, double a_tmin, double a_tmax, double t) { iam (FunctionEditor); return my v_playCallback (phase, a_tmin, a_tmax, t); } void structFunctionEditor :: v_highlightSelection (double left, double right, double bottom, double top) { Graphics_highlight (d_graphics, left, right, bottom, top); } void structFunctionEditor :: v_unhighlightSelection (double left, double right, double bottom, double top) { Graphics_unhighlight (d_graphics, left, right, bottom, top); } void FunctionEditor_init (FunctionEditor me, const char32 *title, Function data) { my tmin = data -> xmin; // set before adding children (see group button) my tmax = data -> xmax; Editor_init (me, 0, 0, my pref_shellWidth (), my pref_shellHeight (), title, data); my d_startWindow = my tmin; my d_endWindow = my tmax; my d_startSelection = my d_endSelection = 0.5 * (my tmin + my tmax); #if motif Melder_assert (XtWindow (my drawingArea -> d_widget)); #endif my d_graphics = Graphics_create_xmdrawingarea (my drawingArea); Graphics_setFontSize (my d_graphics, 12); // This exdents because it's a hack: struct structGuiDrawingAreaResizeEvent event = { my drawingArea, 0 }; event. width = GuiControl_getWidth (my drawingArea); event. height = GuiControl_getHeight (my drawingArea); gui_drawingarea_cb_resize (me, & event); my v_updateText (); if (group_equalDomain (my tmin, my tmax)) gui_checkbutton_cb_group (me, nullptr); // BUG: nullptr my enableUpdates = true; } void FunctionEditor_marksChanged (FunctionEditor me, bool needsUpdateGroup) { my v_updateText (); updateScrollBar (me); /*Graphics_updateWs (my d_graphics);*/ drawNow (me); if (needsUpdateGroup) updateGroup (me); } void FunctionEditor_updateText (FunctionEditor me) { my v_updateText (); } void FunctionEditor_redraw (FunctionEditor me) { //Graphics_updateWs (my d_graphics); drawNow (me); } void FunctionEditor_enableUpdates (FunctionEditor me, bool enable) { my enableUpdates = enable; } void FunctionEditor_ungroup (FunctionEditor me) { if (! my group) return; my group = false; GuiCheckButton_setValue (my groupButton, false); int i = 1; while (theGroup [i] != me) i ++; theGroup [i] = nullptr; nGroup --; my v_updateText (); Graphics_updateWs (my d_graphics); // for setting buttons in v_draw() method } void FunctionEditor_drawRangeMark (FunctionEditor me, double yWC, const char32 *yWC_string, const char32 *units, int verticalAlignment) { static MelderString text { 0 }; MelderString_copy (& text, yWC_string, units); double textWidth = Graphics_textWidth (my d_graphics, text.string) + Graphics_dxMMtoWC (my d_graphics, 0.5); Graphics_setColour (my d_graphics, Graphics_BLUE); Graphics_line (my d_graphics, my d_endWindow, yWC, my d_endWindow + textWidth, yWC); Graphics_setTextAlignment (my d_graphics, Graphics_LEFT, verticalAlignment); if (verticalAlignment == Graphics_BOTTOM) yWC -= Graphics_dyMMtoWC (my d_graphics, 0.5); Graphics_text (my d_graphics, my d_endWindow, yWC, text.string); } void FunctionEditor_drawCursorFunctionValue (FunctionEditor me, double yWC, const char32 *yWC_string, const char32 *units) { Graphics_setColour (my d_graphics, Graphics_CYAN); Graphics_line (my d_graphics, my d_startWindow, yWC, 0.99 * my d_startWindow + 0.01 * my d_endWindow, yWC); Graphics_fillCircle_mm (my d_graphics, 0.5 * (my d_startSelection + my d_endSelection), yWC, 1.5); Graphics_setColour (my d_graphics, Graphics_BLUE); Graphics_setTextAlignment (my d_graphics, Graphics_RIGHT, Graphics_HALF); Graphics_text (my d_graphics, my d_startWindow, yWC, yWC_string, units); } void FunctionEditor_insertCursorFunctionValue (FunctionEditor me, double yWC, const char32 *yWC_string, const char32 *units, double minimum, double maximum) { double textX = my d_endWindow, textY = yWC; int tooHigh = Graphics_dyWCtoMM (my d_graphics, maximum - textY) < 5.0; int tooLow = Graphics_dyWCtoMM (my d_graphics, textY - minimum) < 5.0; if (yWC < minimum || yWC > maximum) return; Graphics_setColour (my d_graphics, Graphics_CYAN); Graphics_line (my d_graphics, 0.99 * my d_endWindow + 0.01 * my d_startWindow, yWC, my d_endWindow, yWC); Graphics_fillCircle_mm (my d_graphics, 0.5 * (my d_startSelection + my d_endSelection), yWC, 1.5); if (tooHigh) { if (tooLow) textY = 0.5 * (minimum + maximum); else textY = maximum - Graphics_dyMMtoWC (my d_graphics, 5.0); } else if (tooLow) { textY = minimum + Graphics_dyMMtoWC (my d_graphics, 5.0); } static MelderString text { 0 }; MelderString_copy (& text, yWC_string, units); double textWidth = Graphics_textWidth (my d_graphics, text.string); Graphics_fillCircle_mm (my d_graphics, my d_endWindow + textWidth + Graphics_dxMMtoWC (my d_graphics, 1.5), textY, 1.5); Graphics_setColour (my d_graphics, Graphics_RED); Graphics_setTextAlignment (my d_graphics, Graphics_LEFT, Graphics_HALF); Graphics_text (my d_graphics, textX, textY, text.string); } void FunctionEditor_drawHorizontalHair (FunctionEditor me, double yWC, const char32 *yWC_string, const char32 *units) { Graphics_setColour (my d_graphics, Graphics_RED); Graphics_line (my d_graphics, my d_startWindow, yWC, my d_endWindow, yWC); Graphics_setTextAlignment (my d_graphics, Graphics_RIGHT, Graphics_HALF); Graphics_text (my d_graphics, my d_startWindow, yWC, yWC_string, units); } void FunctionEditor_drawGridLine (FunctionEditor me, double yWC) { Graphics_setColour (my d_graphics, Graphics_CYAN); Graphics_setLineType (my d_graphics, Graphics_DOTTED); Graphics_line (my d_graphics, my d_startWindow, yWC, my d_endWindow, yWC); Graphics_setLineType (my d_graphics, Graphics_DRAWN); } void FunctionEditor_garnish (FunctionEditor me) { if (my pref_picture_drawSelectionTimes ()) { if (my d_startSelection >= my d_startWindow && my d_startSelection <= my d_endWindow) Graphics_markTop (my pictureGraphics, my d_startSelection, true, true, false, nullptr); if (my d_endSelection != my d_startSelection && my d_endSelection >= my d_startWindow && my d_endSelection <= my d_endWindow) Graphics_markTop (my pictureGraphics, my d_endSelection, true, true, false, nullptr); } if (my pref_picture_drawSelectionHairs ()) { if (my d_startSelection >= my d_startWindow && my d_startSelection <= my d_endWindow) Graphics_markTop (my pictureGraphics, my d_startSelection, false, false, true, nullptr); if (my d_endSelection != my d_startSelection && my d_endSelection >= my d_startWindow && my d_endSelection <= my d_endWindow) Graphics_markTop (my pictureGraphics, my d_endSelection, false, false, true, nullptr); } } /* End of file FunctionEditor.cpp */ praat-6.0.04/fon/FunctionEditor.h000066400000000000000000000244241261542461700166150ustar00rootroot00000000000000#ifndef _FunctionEditor_h_ #define _FunctionEditor_h_ /* FunctionEditor.h * * Copyright (C) 1992-2011,2012,2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Editor.h" #include "Graphics.h" #include "Function.h" struct FunctionEditor_picture { /* KEEP IN SYNC WITH PREFS. */ bool garnish; }; Thing_define (FunctionEditor, Editor) { /* Subclass may change the following attributes, */ /* but has to respect the invariants, */ /* and has to call FunctionEditor_marksChanged () */ /* immediately after making the changes. */ double tmin, tmax, d_startWindow, d_endWindow; double d_startSelection, d_endSelection; // markers /* These attributes are all expressed in seconds. Invariants: */ /* tmin <= startWindow < endWindow <= tmax; */ /* tmin <= (startSelection, endSelection) <= tmax; */ Graphics d_graphics; // used in the 'draw' method short functionViewerLeft, functionViewerRight; // size of drawing areas in pixels short selectionViewerLeft, selectionViewerRight; // size of drawing areas in pixels short height; // size of drawing areas in pixels GuiText text; // optional text at top int shiftKeyPressed; // information for the 'play' method bool playingCursor, playingSelection; // information for end of play struct FunctionEditor_picture picture; /* Private: */ GuiDrawingArea drawingArea; GuiScrollBar scrollBar; GuiCheckButton groupButton; GuiObject bottomArea; bool group, enableUpdates; int nrect; struct { double left, right, bottom, top; } rect [8]; double marker [1 + 3], playCursor, startZoomHistory, endZoomHistory; int numberOfMarkers; void v_destroy () override; void v_info () override; void v_createMenus () override; void v_createMenuItems_file (EditorMenu) override; void v_createMenuItems_query (EditorMenu) override; void v_createChildren () override; void v_createHelpMenuItems (EditorMenu) override; void v_dataChanged () override; virtual void v_draw () { } /* * Message: "draw your part of the data between startWindow and endWindow." */ virtual void v_drawSelectionViewer () { } virtual void v_prepareDraw () { } // for less flashing virtual const char32 * v_format_domain () { return U"Time domain:"; } virtual const char * v_format_short () { return u8"%.3f"; } virtual const char * v_format_long () { return u8"%f"; } virtual const char32 * v_format_units () { return U"seconds"; } virtual const char * v_format_totalDuration () { return u8"Total duration %f seconds"; } virtual const char * v_format_window () { return u8"Visible part %f seconds"; } virtual const char * v_format_selection () { return u8"%f (%.3f / s)"; } virtual int v_fixedPrecision_long () { return 6; } virtual bool v_hasText () { return false; } virtual void v_play (double /* timeFrom */, double /* timeTo */) { } /* * Message: "the user clicked in one of the rectangles above or below the data window." */ virtual int v_click (double xWC, double yWC, bool shiftKeyPressed); /* * Message: "the user clicked in data window with the left mouse button." * 'xWC' is the time; * 'yWC' is a value between 0.0 (bottom) and 1.0 (top); * 'shiftKeyPressed' flags if the Shift key was held down during the click. * Constraints: * Return FunctionEditor_UPDATE_NEEDED if you want a window update, i.e., * if your 'click' moves the cursor or otherwise changes the appearance of the data. * Return FunctionEditor_NO_UPDATE_NEEDED if you do not want a window update, e.g., * if your 'click' method just 'plays' something or puts a dialog on the screen. * In the latter case, the 'ok' callback of the dialog should * call FunctionEditor_marksChanged if necessary. * Behaviour of FunctionEditor::click (): * moves the cursor to 'xWC', drags to create a selection, or extends the selection. */ virtual int v_clickB (double xWC, double yWC); virtual int v_clickE (double xWC, double yWC); virtual int v_playCallback (int phase, double tmin, double tmax, double t); virtual void v_updateText () { } virtual void v_prefs_addFields (EditorCommand) { } virtual void v_prefs_setValues (EditorCommand) { } virtual void v_prefs_getValues (EditorCommand) { } virtual void v_createMenuItems_file_draw (EditorMenu) { } virtual void v_createMenuItems_file_extract (EditorMenu) { } virtual void v_createMenuItems_file_write (EditorMenu) { } virtual void v_createMenuItems_view (EditorMenu); virtual void v_createMenuItems_view_timeDomain (EditorMenu); virtual void v_createMenuItems_view_audio (EditorMenu); virtual void v_highlightSelection (double left, double right, double bottom, double top); virtual void v_unhighlightSelection (double left, double right, double bottom, double top); virtual double v_getBottomOfSoundArea () { return 0.0; } virtual double v_getBottomOfSoundAndAnalysisArea () { return 0.0; } virtual void v_form_pictureSelection (EditorCommand); virtual void v_ok_pictureSelection (EditorCommand); virtual void v_do_pictureSelection (EditorCommand); #include "FunctionEditor_prefs.h" }; int theFunctionEditor_playCallback (void *void_me, int phase, double tmin, double tmax, double t); /* Attributes: data: must be a Function. int clickB (double xWC, double yWC); "user clicked in data window with the middle mouse button (Mac: control- or option-click)." 'xWC' is the time; 'yWC' is a value between 0.0 (bottom) and 1.0 (top). For the return value, see the 'click' method. FunctionEditor::clickB simply moves the start of the selection (B) to 'xWC', with the sole statement 'my startSelection = xWC'. int clickE (double xWC, double yWC); "user clicked in data window with the right mouse button (Mac: command-click)." 'xWC' is the time; 'yWC' is a value between 0.0 (bottom) and 1.0 (top). For the return value, see the 'click' method. FunctionEditor::clickB simply moves the end of the selection (E) to 'xWC', with the sole statement 'my endSelection = xWC'. void key (unsigned char key); "user typed a key to the data window." FunctionEditor::key ignores this message. */ #define FunctionEditor_UPDATE_NEEDED 1 #define FunctionEditor_NO_UPDATE_NEEDED 0 void FunctionEditor_init (FunctionEditor me, const char32 *title, Function data); /* Function: creates an Editor with a drawing area, a scroll bar and some buttons. Postconditions: my drawingArea is attached to the form at all sides, my scrollBar only to the bottom, left and right sides. */ void FunctionEditor_marksChanged (FunctionEditor me, bool needsUpdateGroup); /* Function: update optional text field, the scroll bar, the drawing area and the buttons, from the current total time, window, cursor, and selection, and redraw the contents. If needsUpdateGroup is true, this will be done for all the editors in the group. Usage: call this after a change in any of the markers or in the duration of the data. */ void FunctionEditor_shift (FunctionEditor me, double shift, bool needsUpdateGroup); /* Function: shift (scroll) the window through time, keeping the window length constant. Usage: call this after a search. */ void FunctionEditor_updateText (FunctionEditor me); /* Function: update the optional text widget. Usage: call this after moving the cursor, if that would have to change the text. The generic FunctionEditor also calls this if one of the other marks have changed. Behaviour: we just call the updateText method, which the inheritor will have to modify, since FunctionEditor::updateText does nothing. */ void FunctionEditor_redraw (FunctionEditor me); /* Function: update the drawing area of a single editor. Usage: calls this after she changes a view option (font, scaling, hide/show xx) or after any of the data have changed. In the latter case, also call Editor_broadcastChange. Behaviour: we just call Graphics_updateWs (my graphics). */ void FunctionEditor_enableUpdates (FunctionEditor me, bool enable); /* Function: temporarily disable update event to cause 'draw' messages. Usage: If you call from your 'draw' method routines that may trigger expose events, you should bracket those routines between FunctionEditor_enableUpdates (me, false); and FunctionEditor_enableUpdates (me, true); This may happen if you call an analysis routine which calls Melder_progress. */ void FunctionEditor_ungroup (FunctionEditor me); /* Function: force me out of the group. Usage: Start cut or paste methods by calling this routine, as the grouped editors will not be synchronized after either of those actions. Worse, the selection may get outside the common interval of the editors. */ /* Some routines to enforce common look to all function editors. */ /* The x axis of the window is supposed to have been set to [my startWindow, my endWindow]. */ /* Preconditions: default line type, default line width. */ /* Postconditions: default line type, default line width, undefined colour, undefined text alignment. */ void FunctionEditor_drawRangeMark (FunctionEditor me, double yWC, const char32 *yWC_string, const char32 *units, int verticalAlignment); void FunctionEditor_drawCursorFunctionValue (FunctionEditor me, double yWC, const char32 *yWC_string, const char32 *units); void FunctionEditor_insertCursorFunctionValue (FunctionEditor me, double yWC, const char32 *yWC_string, const char32 *units, double minimum, double maximum); void FunctionEditor_drawHorizontalHair (FunctionEditor me, double yWC, const char32 *yWC_string, const char32 *units); void FunctionEditor_drawGridLine (FunctionEditor me, double yWC); void FunctionEditor_insetViewport (FunctionEditor me); void FunctionEditor_garnish (FunctionEditor me); // Optionally selection times and selection hairs. /* End of file FunctionEditor.h */ #endif praat-6.0.04/fon/FunctionEditor_prefs.h000066400000000000000000000025451261542461700200140ustar00rootroot00000000000000/* FunctionEditor_prefs.h * * Copyright (C) 2013,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ prefs_begin (FunctionEditor) prefs_add_int (FunctionEditor, shellWidth, 1, U"700") prefs_add_int (FunctionEditor, shellHeight, 1, U"440") prefs_add_bool (FunctionEditor, synchronizedZoomAndScroll, 1, true) prefs_add_bool_with_data (FunctionEditor, showSelectionViewer, 1, false) prefs_add_double_with_data (FunctionEditor, arrowScrollStep, 1, U"0.05") prefs_add_bool (FunctionEditor, picture_drawSelectionTimes, 1, true) prefs_add_bool (FunctionEditor, picture_drawSelectionHairs, 1, true) prefs_end (FunctionEditor) /* End of file FunctionEditor_prefs.h */ praat-6.0.04/fon/Function_def.h000066400000000000000000000042041261542461700162560ustar00rootroot00000000000000/* Function_def.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT Function oo_DEFINE_CLASS (Function, Daata) oo_DOUBLE (xmin) oo_DOUBLE (xmax) #if oo_READING if (xmin > xmax) Melder_throw (U"Wrong xmin ", xmin, U" and xmax ", xmax, U"."); #endif #if oo_DECLARING void v_info () override; bool v_hasGetXmin () override { return true; } double v_getXmin () override { return xmin; } bool v_hasGetXmax () override { return true; } double v_getXmax () override { return xmax; } virtual int v_domainQuantity () { return 0; } virtual int v_getMinimumUnit (long ilevel) { (void) ilevel; return 0; } virtual int v_getMaximumUnit (long ilevel) { (void) ilevel; return 0; } virtual const char32 * v_getUnitText (long ilevel, int unit, unsigned long flags) { (void) ilevel; (void) unit; (void) flags; return U""; } virtual bool v_isUnitLogarithmic (long ilevel, int unit) { (void) ilevel; (void) unit; return false; } virtual double v_convertStandardToSpecialUnit (double value, long ilevel, int unit) { (void) ilevel; (void) unit; return value; } virtual double v_convertSpecialToStandardUnit (double value, long ilevel, int unit) { (void) ilevel; (void) unit; return value; } virtual void v_shiftX (double xfrom, double xto); virtual void v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto); #endif oo_END_CLASS (Function) #undef ooSTRUCT /* End of file Function_def.h */ praat-6.0.04/fon/Harmonicity.cpp000066400000000000000000000127761261542461700165110ustar00rootroot00000000000000/* Harmonicity.cpp * * Copyright (C) 1992-2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Graphics.h" #include "Harmonicity.h" Thing_implement (Harmonicity, Vector, 2); double Harmonicity_getMean (Harmonicity me, double tmin, double tmax) { if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } long imin, imax; long n = Sampled_getWindowSamples (me, tmin, tmax, & imin, & imax); if (n < 1) return NUMundefined; double sum = 0.0; long nSounding = 0; for (long i = imin; i <= imax; i ++) { if (my z [1] [i] != -200) { nSounding ++; sum += my z [1] [i]; } } if (nSounding < 1) return NUMundefined; return sum / nSounding; } double Harmonicity_getStandardDeviation (Harmonicity me, double tmin, double tmax) { if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } long imin, imax; long n = Sampled_getWindowSamples (me, tmin, tmax, & imin, & imax); if (n < 1) return NUMundefined; double sum = 0.0; long nSounding = 0; for (long i = imin; i <= imax; i ++) { if (my z [1] [i] != -200) { nSounding ++; sum += my z [1] [i]; } } if (nSounding < 2) return NUMundefined; double mean = sum / nSounding; double sumOfSquares = 0.0; for (long i = imin; i <= imax; i ++) { if (my z [1] [i] != -200) { double d = my z [1] [i] - mean; sumOfSquares += d * d; } } return sqrt (sumOfSquares / (nSounding - 1)); } double Harmonicity_getQuantile (Harmonicity me, double quantile) { autoNUMvector strengths (1, my nx); long nSounding = 0; for (long ix = 1; ix <= my nx; ix ++) if (my z [1] [ix] != -200) strengths [++ nSounding] = my z [1] [ix]; double result = -200.0; if (nSounding >= 1) { NUMsort_d (nSounding, strengths.peek()); result = NUMquantile (nSounding, strengths.peek(), quantile); } return result; } void structHarmonicity :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Time domain:"); MelderInfo_writeLine (U" Start time: ", xmin, U" seconds"); MelderInfo_writeLine (U" End time: ", xmax, U" seconds"); MelderInfo_writeLine (U" Total duration: ", xmax - xmin, U" seconds"); autoNUMvector strengths (1, nx); long nSounding = 0; for (long ix = 1; ix <= nx; ix ++) if (z [1] [ix] != -200) strengths [++ nSounding] = z [1] [ix]; MelderInfo_writeLine (U"Time sampling:"); MelderInfo_writeLine (U" Number of frames: ", nx, U" (", nSounding, U" sounding)"); MelderInfo_writeLine (U" Time step: ", dx, U" seconds"); MelderInfo_writeLine (U" First frame centred at: ", x1, U" seconds"); if (nSounding) { double sum = 0, sumOfSquares = 0; MelderInfo_writeLine (U"Periodicity-to-noise ratios of sounding frames:"); NUMsort_d (nSounding, strengths.peek()); MelderInfo_writeLine (U" Median ", Melder_single (NUMquantile (nSounding, strengths.peek(), 0.50)), U" dB"); MelderInfo_writeLine (U" 10 % = ", Melder_single (NUMquantile (nSounding, strengths.peek(), 0.10)), U" dB 90 %% = ", Melder_single (NUMquantile (nSounding, strengths.peek(), 0.90)), U" dB"); MelderInfo_writeLine (U" 16 % = ", Melder_single (NUMquantile (nSounding, strengths.peek(), 0.16)), U" dB 84 %% = ", Melder_single (NUMquantile (nSounding, strengths.peek(), 0.84)), U" dB"); MelderInfo_writeLine (U" 25 % = ", Melder_single (NUMquantile (nSounding, strengths.peek(), 0.25)), U" dB 75 %% = ", Melder_single (NUMquantile (nSounding, strengths.peek(), 0.75)), U" dB"); MelderInfo_writeLine (U"Minimum: ", Melder_single (strengths [1]), U" dB"); MelderInfo_writeLine (U"Maximum: ", Melder_single (strengths [nSounding]), U" dB"); for (long i = 1; i <= nSounding; i ++) { double f = strengths [i]; sum += f; sumOfSquares += f * f; } MelderInfo_writeLine (U"Average: ", Melder_single (sum / nSounding), U" dB"); if (nSounding > 1) { double var = (sumOfSquares - sum * sum / nSounding) / (nSounding - 1); MelderInfo_writeLine (U"Standard deviation: ", Melder_single (var < 0.0 ? 0.0 : sqrt (var)), U" dB"); } } } autoHarmonicity Harmonicity_create (double tmin, double tmax, long nt, double dt, double t1) { try { autoHarmonicity me = Thing_new (Harmonicity); Matrix_init (me.peek(), tmin, tmax, nt, dt, t1, 1, 1, 1, 1, 1); return me; } catch (MelderError) { Melder_throw (U"Harmonicity not created."); } } autoMatrix Harmonicity_to_Matrix (Harmonicity me) { try { autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, my ymin, my ymax, my ny, my dy, my y1); NUMvector_copyElements (my z [1], thy z [1], 1, my nx); return thee; } catch (MelderError) { Melder_throw (me, U"not converted to Matrix."); } } autoHarmonicity Matrix_to_Harmonicity (Matrix me) { try { autoHarmonicity thee = Harmonicity_create (my xmin, my xmax, my nx, my dx, my x1); NUMvector_copyElements (my z [1], thy z [1], 1, my nx); return thee; } catch (MelderError) { Melder_throw (me, U"not converted to Harmonicity."); } } /* End of file Harmonicity.cpp */ praat-6.0.04/fon/Harmonicity.h000066400000000000000000000042061261542461700161430ustar00rootroot00000000000000#ifndef _Harmonicity_h_ #define _Harmonicity_h_ /* Harmonicity.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Vector.h" Thing_define (Harmonicity, Vector) { void v_info () override; int v_domainQuantity () override { return MelderQuantity_TIME_SECONDS; } }; /* Attributes: xmin // Start time (seconds). xmax > xmin // End time (seconds). nx >= 1 // Number of time slices. dx > 0.0 // Time step (seconds). x1 // Centre of first time slice (seconds). ymin, ymax, ny, dy, y1 = 1 z [1] [1..nt] // The harmonic strength, a real number between -150 dB and +150 dB: // -150 dB means not periodic at all, +150 dB means perfectly periodic. // Normal values for speech are between -10 dB for [s] and +30 dB for [u]. // -200 means silence. */ autoHarmonicity Harmonicity_create (double tmin, double tmax, long nt, double dt, double t1); void Harmonicity_draw (Harmonicity me, double tmin, double tmax, double min, double max); /* draw a harmonicity contour into the current Graphics. If tmax <= tmin, draw whole time domain. If max <= min, scale to extrema. */ double Harmonicity_getMean (Harmonicity me, double tmin, double tmax); double Harmonicity_getStandardDeviation (Harmonicity me, double tmin, double tmax); double Harmonicity_getQuantile (Harmonicity me, double quantile); autoMatrix Harmonicity_to_Matrix (Harmonicity me); autoHarmonicity Matrix_to_Harmonicity (Matrix me); /* End of file Harmonicity.h */ #endif praat-6.0.04/fon/Harmonics.h000066400000000000000000000030011261542461700155700ustar00rootroot00000000000000#ifndef _Harmonics_h_ #define _Harmonics_h_ /* Harmonics.h * * Copyright (C) 2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "PointProcess.h" #include "Sound.h" #include "Harmonics_def.h" oo_CLASS_CREATE (Harmonics, Daata); autoHarmonics Harmonics_create (long numberOfHarmonics); void Harmonics_draw (Harmonics me, Graphics g, double fmin, double fmax, double minimum, double maximum, int garnish, const char32 *method); autoMatrix Harmonics_to_Matrix (Harmonics me); autoHarmonics Matrix_to_Harmonics (Matrix me); /* Direct computation. */ autoHarmonics PointProcess_Sound_to_Harmonics (PointProcess pulses, Sound sound, long maximumHarmonic, double shortestPeriod, double longestPeriod, double maximumPeriodFactor); /* Shortcut. */ autoHarmonics Sound_to_Harmonics (Sound me, double bandwidth); /* End of file Harmonics.h */ #endif praat-6.0.04/fon/Harmonics_def.h000066400000000000000000000020241261542461700164120ustar00rootroot00000000000000/* Harmonics_def.h * * Copyright (C) 2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT Harmonics oo_DEFINE_CLASS (Harmonics, Daata) oo_LONG (numberOfHarmonics) oo_DOUBLE_VECTOR (harmonics, numberOfHarmonics) #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (Harmonics) #undef ooSTRUCT /* End of file Harmonics_def.h */ praat-6.0.04/fon/Image.cpp000066400000000000000000000025411261542461700152320ustar00rootroot00000000000000/* Image.cpp * * Copyright (C) 1992-2011 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2003/02/17 removed all meaningful source code */ #include "Image.h" #include "Matrix.h" #include "oo_DESTROY.h" #include "Image_def.h" #include "oo_COPY.h" #include "Image_def.h" #include "oo_EQUAL.h" #include "Image_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Image_def.h" #include "oo_WRITE_TEXT.h" #include "Image_def.h" #include "oo_READ_TEXT.h" #include "Image_def.h" #include "oo_WRITE_BINARY.h" #include "Image_def.h" #include "oo_READ_BINARY.h" #include "Image_def.h" #include "oo_DESCRIPTION.h" #include "Image_def.h" Thing_implement (Image, Sampled, 0); /* End of file Image.cpp */ praat-6.0.04/fon/Image.h000066400000000000000000000046051261542461700147020ustar00rootroot00000000000000#ifndef _Image_h_ #define _Image_h_ /* Image.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Sampled.h" #include "Graphics.h" #include "Image_def.h" oo_CLASS_CREATE (Image, Sampled); /* An object of type Image represents a quantized function z (x, y) on the domain [xmin, xmax] * [ymin, ymax]. The domain has been sampled in the x and y directions with constant sampling intervals (dx and dy) along each direction. The samples are thus z [iy] [ix] with ix = 1..nx and iy = 1..ny. These represent the function values z (x1 + (ix - 1) * dx, y1 + (iy - 1) * dy). */ //int Image_init // (Image me, double xmin, double xmax, long nx, double dx, double x1, // double ymin, double ymax, long ny, double dy, double y1); //Image Image_create // (double xmin, double xmax, long nx, double dx, double x1, // double ymin, double ymax, long ny, double dy, double y1); /* Function: return a new empty Image. Preconditions: xmin <= xmax; ymin <= ymax; nx >= 1; ny >= 1; dx > 0.0; dy > 0.0; Postconditions: result -> xmin == xmin; result -> xmax == xmax; result -> ymin == ymin; result -> ymax == ymax; result -> nx == nx; result -> ny == ny; result -> dx == dx; result -> dy == dy; result -> x1 == x1; result -> y1 == y1; result -> z [1..ny] [1..nx] == 0; */ //long Image_getWindowExtrema (I, long ixmin, long ixmax, long iymin, long iymax, // unsigned char *minimum, unsigned char *maximum); //void Image_paint (I, Graphics g, double xmin, double xmax, double ymin, double ymax, // unsigned char minimum, unsigned char maximum); /* Every sample is drawn as a grey rectangle. The larger the value of the sample, the darker the rectangle. */ /* End of file Image.h */ #endif praat-6.0.04/fon/Image_def.h000066400000000000000000000017511261542461700155170ustar00rootroot00000000000000/* Image_def.h * * Copyright (C) 1992-2011 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT Image oo_DEFINE_CLASS (Image, Sampled) oo_DOUBLE (ymin) oo_DOUBLE (ymax) oo_LONG (ny) oo_DOUBLE (dy) oo_DOUBLE (y1) oo_UBYTE_MATRIX (z, ny, nx) oo_END_CLASS (Image) #undef ooSTRUCT /* End of file Image_def.h */ praat-6.0.04/fon/Intensity.cpp000066400000000000000000000106111261542461700161730ustar00rootroot00000000000000/* Intensity.cpp * * Copyright (C) 1992-2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Intensity.h" Thing_implement (Intensity, Vector, 2); void structIntensity :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Time domain:"); MelderInfo_writeLine (U" Start time: ", xmin, U" seconds"); MelderInfo_writeLine (U" End time: ", xmax, U" seconds"); MelderInfo_writeLine (U" Total duration: ", xmax - xmin, U" seconds"); MelderInfo_writeLine (U"Time sampling:"); MelderInfo_writeLine (U" Number of frames: ", nx); MelderInfo_writeLine (U" Time step: ", dx, U" seconds"); MelderInfo_writeLine (U" First frame centred at: ", x1, U" seconds"); } double structIntensity :: v_convertStandardToSpecialUnit (double value, long ilevel, int unit) { (void) ilevel; if (unit == 1) { return pow (10.0, 0.1 * value); // energy } else if (unit == 2) { return pow (2.0, 0.1 * value); // sones } return value; // default, especially if units == 0 (as in Vector_getMean) or units == 3 (averaging_DB) } double structIntensity :: v_convertSpecialToStandardUnit (double value, long ilevel, int unit) { (void) ilevel; return unit == 1 ? 10.0 * log10 (value) : // value = energy unit == 2 ? 10.0 * NUMlog2 (value) : // value = sones value; // value = dB } void Intensity_init (Intensity me, double tmin, double tmax, long nt, double dt, double t1) { Matrix_init (me, tmin, tmax, nt, dt, t1, 1.0, 1.0, 1, 1.0, 1.0); } autoIntensity Intensity_create (double tmin, double tmax, long nt, double dt, double t1) { try { autoIntensity me = Thing_new (Intensity); Intensity_init (me.peek(), tmin, tmax, nt, dt, t1); return me; } catch (MelderError) { Melder_throw (U"Intensity not created."); } } autoMatrix Intensity_to_Matrix (Intensity me) { try { autoMatrix thee = Thing_new (Matrix); my structMatrix :: v_copy (thee.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Intensity."); } } autoIntensity Matrix_to_Intensity (Matrix me) { try { autoIntensity thee = Thing_new (Intensity); my structMatrix :: v_copy (thee.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Matrix."); } } void Intensity_drawInside (Intensity me, Graphics g, double tmin, double tmax, double minimum, double maximum) { if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } // autowindow long itmin, itmax; Matrix_getWindowSamplesX (me, tmin, tmax, & itmin, & itmax); if (maximum <= minimum) Matrix_getWindowExtrema (me, itmin, itmax, 1, 1, & minimum, & maximum); // autoscale if (maximum <= minimum) { minimum -= 10; maximum += 10; } Graphics_setWindow (g, tmin, tmax, minimum, maximum); Graphics_function (g, my z [1], itmin, itmax, Matrix_columnToX (me, itmin), Matrix_columnToX (me, itmax)); } void Intensity_draw (Intensity me, Graphics g, double tmin, double tmax, double minimum, double maximum, int garnish) { Graphics_setInner (g); Intensity_drawInside (me, g, tmin, tmax, minimum, maximum); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Time (s)"); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); Graphics_textLeft (g, true, U"Intensity (dB)"); } } double Intensity_getQuantile (Intensity me, double tmin, double tmax, double quantile) { return Sampled_getQuantile (me, tmin, tmax, quantile, 0, Intensity_units_DB); } double Intensity_getAverage (Intensity me, double tmin, double tmax, int averagingMethod) { return averagingMethod == Intensity_averaging_MEDIAN ? Intensity_getQuantile (me, tmin, tmax, 0.50) : Sampled_getMean_standardUnit (me, tmin, tmax, 0, averagingMethod, true); } /* End of file Intensity.cpp */ praat-6.0.04/fon/Intensity.h000066400000000000000000000044501261542461700156440ustar00rootroot00000000000000#ifndef _Intensity_h_ #define _Intensity_h_ /* Intensity.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* class Intensity = Vector; x = time (seconds) nx = number of frames dx = distance between frames (seconds) x1 = centre of first frame (seconds) z = intensity (dB relative to 2e-5 N/m2 or 1e-12 W/m2) */ #include "Vector.h" Thing_define (Intensity, Vector) { void v_info () override; int v_domainQuantity () override { return MelderQuantity_TIME_SECONDS; } double v_convertStandardToSpecialUnit (double value, long ilevel, int unit) override; double v_convertSpecialToStandardUnit (double value, long ilevel, int unit) override; }; autoIntensity Intensity_create (double tmin, double tmax, long nt, double dt, double t1); void Intensity_init (Intensity me, double tmin, double tmax, long nt, double dt, double t1); autoMatrix Intensity_to_Matrix (Intensity me); autoIntensity Matrix_to_Intensity (Matrix me); void Intensity_drawInside (Intensity me, Graphics g, double tmin, double tmax, double minimum, double maximum); void Intensity_draw (Intensity me, Graphics g, double tmin, double tmax, double minimum, double maximum, int garnish); double Intensity_getQuantile (Intensity me, double tmin, double tmax, double quantile); #define Intensity_units_ENERGY 1 #define Intensity_units_SONES 2 #define Intensity_units_DB 3 #define Intensity_averaging_MEDIAN 0 #define Intensity_averaging_ENERGY 1 #define Intensity_averaging_SONES 2 #define Intensity_averaging_DB 3 double Intensity_getAverage (Intensity me, double tmin, double tmax, int averagingMethod); /* End of file Intensity.h */ #endif praat-6.0.04/fon/IntensityTier.cpp000066400000000000000000000105161261542461700170230ustar00rootroot00000000000000/* IntensityTier.cpp * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "IntensityTier.h" Thing_implement (IntensityTier, RealTier, 0); autoIntensityTier IntensityTier_create (double tmin, double tmax) { try { autoIntensityTier me = Thing_new (IntensityTier); RealTier_init (me.peek(), tmin, tmax); return me; } catch (MelderError) { Melder_throw (U"IntensityTier not created."); } } void IntensityTier_draw (IntensityTier me, Graphics g, double tmin, double tmax, double ymin, double ymax, const char32 *method, int garnish) { RealTier_draw (me, g, tmin, tmax, ymin, ymax, garnish, method, U"Intensity (dB)"); } autoIntensityTier PointProcess_upto_IntensityTier (PointProcess me, double intensity) { try { autoIntensityTier thee = PointProcess_upto_RealTier (me, intensity, classIntensityTier).static_cast_move(); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to IntensityTier."); } } autoIntensityTier Intensity_downto_IntensityTier (Intensity me) { try { autoIntensityTier thee = Vector_to_RealTier (me, 1, classIntensityTier).static_cast_move(); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to IntensityTier."); } } autoIntensityTier Intensity_to_IntensityTier_peaks (Intensity me) { try { autoIntensityTier thee = Vector_to_RealTier_peaks (me, 1, classIntensityTier).static_cast_move(); return thee; } catch (MelderError) { Melder_throw (me, U": peaks not converted to IntensityTier."); } } autoIntensityTier Intensity_to_IntensityTier_valleys (Intensity me) { try { autoIntensityTier thee = Vector_to_RealTier_valleys (me, 1, classIntensityTier).static_cast_move(); return thee; } catch (MelderError) { Melder_throw (me, U": valleys not converted to IntensityTier."); } } autoIntensityTier Intensity_PointProcess_to_IntensityTier (Intensity me, PointProcess pp) { try { autoIntensityTier temp = Intensity_downto_IntensityTier (me); autoIntensityTier thee = IntensityTier_PointProcess_to_IntensityTier (temp.peek(), pp); return thee; } catch (MelderError) { Melder_throw (me, U" & ", pp, U": not converted to IntensityTier."); } } autoIntensityTier IntensityTier_PointProcess_to_IntensityTier (IntensityTier me, PointProcess pp) { try { if (my points -> size == 0) Melder_throw (U"No intensity points."); autoIntensityTier thee = IntensityTier_create (pp -> xmin, pp -> xmax); for (long i = 1; i <= pp -> nt; i ++) { double time = pp -> t [i]; double value = RealTier_getValueAtTime (me, time); RealTier_addPoint (thee.peek(), time, value); } return thee; } catch (MelderError) { Melder_throw (me, U" & ", pp, U": not converted to IntensityTier."); } } autoTableOfReal IntensityTier_downto_TableOfReal (IntensityTier me) { return RealTier_downto_TableOfReal (me, U"Time (s)", U"Intensity (dB)"); } void Sound_IntensityTier_multiply_inline (Sound me, IntensityTier intensity) { if (intensity -> points -> size == 0) return; for (long isamp = 1; isamp <= my nx; isamp ++) { double t = my x1 + (isamp - 1) * my dx; double factor = pow (10, RealTier_getValueAtTime (intensity, t) / 20); for (long channel = 1; channel <= my ny; channel ++) { my z [channel] [isamp] *= factor; } } } autoSound Sound_IntensityTier_multiply (Sound me, IntensityTier intensity, int scale) { try { autoSound thee = Data_copy (me); Sound_IntensityTier_multiply_inline (thee.peek(), intensity); if (scale) Vector_scale (thee.peek(), 0.9); return thee; } catch (MelderError) { Melder_throw (me, U": not multiplied with ", intensity, U"."); } } /* End of file IntensityTier.cpp */ praat-6.0.04/fon/IntensityTier.h000066400000000000000000000037211261542461700164700ustar00rootroot00000000000000#ifndef _IntensityTier_h_ #define _IntensityTier_h_ /* IntensityTier.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "RealTier.h" #include "Intensity.h" #include "TableOfReal.h" #include "Sound.h" Thing_define (IntensityTier, RealTier) { int v_domainQuantity () override { return MelderQuantity_TIME_SECONDS; } }; autoIntensityTier IntensityTier_create (double tmin, double tmax); void IntensityTier_draw (IntensityTier me, Graphics g, double tmin, double tmax, double ymin, double ymax, const char32 *method, int garnish); autoIntensityTier PointProcess_upto_IntensityTier (PointProcess me, double intensity); autoIntensityTier Intensity_downto_IntensityTier (Intensity me); autoIntensityTier Intensity_to_IntensityTier_peaks (Intensity me); autoIntensityTier Intensity_to_IntensityTier_valleys (Intensity me); autoIntensityTier Intensity_PointProcess_to_IntensityTier (Intensity me, PointProcess pp); autoIntensityTier IntensityTier_PointProcess_to_IntensityTier (IntensityTier me, PointProcess pp); autoTableOfReal IntensityTier_downto_TableOfReal (IntensityTier me); void Sound_IntensityTier_multiply_inline (Sound me, IntensityTier intensity); autoSound Sound_IntensityTier_multiply (Sound me, IntensityTier intensity, int scale); /* End of file IntensityTier.h */ #endif praat-6.0.04/fon/IntensityTierEditor.cpp000066400000000000000000000036231261542461700201730ustar00rootroot00000000000000/* IntensityTierEditor.cpp * * Copyright (C) 1992-2011,2012,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "IntensityTierEditor.h" #include "EditorM.h" Thing_implement (IntensityTierEditor, RealTierEditor, 0); static void menu_cb_IntensityTierHelp (EDITOR_ARGS) { EDITOR_IAM (IntensityTierEditor); Melder_help (U"IntensityTier"); } void structIntensityTierEditor :: v_createHelpMenuItems (EditorMenu menu) { IntensityTierEditor_Parent :: v_createHelpMenuItems (menu); EditorMenu_addCommand (menu, U"IntensityTier help", 0, menu_cb_IntensityTierHelp); } void structIntensityTierEditor :: v_play (double a_tmin, double a_tmax) { if (our d_sound.data) { Sound_playPart (our d_sound.data, a_tmin, a_tmax, theFunctionEditor_playCallback, this); } else { //IntensityTier_playPart (our data, a_tmin, a_tmax, false); } } autoIntensityTierEditor IntensityTierEditor_create (const char32 *title, IntensityTier intensity, Sound sound, bool ownSound) { try { autoIntensityTierEditor me = Thing_new (IntensityTierEditor); RealTierEditor_init (me.peek(), title, (RealTier) intensity, sound, ownSound); return me; } catch (MelderError) { Melder_throw (U"IntensityTier window not created."); } } /* End of file IntensityTierEditor.cpp */ praat-6.0.04/fon/IntensityTierEditor.h000066400000000000000000000041261261542461700176370ustar00rootroot00000000000000#ifndef _IntensityTierEditor_h_ #define _IntensityTierEditor_h_ /* IntensityTierEditor.h * * Copyright (C) 1992-2011,2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "RealTierEditor.h" #include "IntensityTier.h" #include "Sound.h" Thing_define (IntensityTierEditor, RealTierEditor) { void v_createHelpMenuItems (EditorMenu menu) override; void v_play (double tmin, double tmax) override; const char32 * v_quantityText () override { return U"Intensity (dB)"; } const char32 * v_quantityKey () override { return U"Intensity"; } const char32 * v_rightTickUnits () override { return U" dB"; } double v_defaultYmin () override { return 50.0; } double v_defaultYmax () override { return 100.0; } const char32 * v_setRangeTitle () override { return U"Set intensity range..."; } const char32 * v_defaultYminText () override { return U"50.0"; } const char32 * v_defaultYmaxText () override { return U"100.0"; } const char32 * v_yminText () override { return U"Minimum intensity (dB)"; } const char32 * v_ymaxText () override { return U"Maximum intensity (dB)"; } const char32 * v_yminKey () override { return U"Minimum intensity"; } const char32 * v_ymaxKey () override { return U"Maximum intensity"; } }; autoIntensityTierEditor IntensityTierEditor_create (const char32 *title, IntensityTier intensity, Sound sound, bool ownSound); /* 'sound' may be null. */ /* End of file IntensityTierEditor.h */ #endif praat-6.0.04/fon/Label.cpp000066400000000000000000000076511261542461700152360ustar00rootroot00000000000000/* Label.cpp * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Label.h" Thing_implement (Autosegment, Function, 0); void structAutosegment :: v_copy (thou) { thouart (Autosegment); Autosegment_Parent :: v_copy (thee); if (name) Thing_setName (thee, name); } bool structAutosegment :: v_equal (thou) { thouart (Autosegment); if (! Autosegment_Parent :: v_equal (thee)) return false; if (! our name && ! thy name) return true; // shortcut: no names if (! our name || ! thy name) return false; return str32equ (name, thy name); } static struct structData_Description theAutosegment_description [] = { { U"Autosegment", inheritwa, 0, sizeof (struct structAutosegment), U"Autosegment", & theClassInfo_Function }, { U"name", stringwa, Melder_offsetof (Autosegment, name), sizeof (char32 *) }, { 0 } }; Data_Description structAutosegment :: s_description = & theAutosegment_description [0]; autoAutosegment Autosegment_create (double tmin, double tmax, const char32 *label) { try { autoAutosegment me = Thing_new (Autosegment); Function_init (me.peek(), tmin, tmax); if (label) { Thing_setName (me.peek(), label); } return me; } catch (MelderError) { Melder_throw (U"Autosegment not created."); } } int structTier :: compare (I, thou) { iam (Function); thouart (Function); if (my xmin < thy xmin) return -1; if (my xmin > thy xmin) return 1; if (my xmax < thy xmax) return -1; if (my xmax > thy xmax) return 1; return 0; } Thing_implement (Tier, Sorted, 0); void Tier_init (Tier me, long initialCapacity) { Sorted_init (me, classAutosegment, initialCapacity); Collection_addItem (me, Autosegment_create (-1e30, 1e30, nullptr).transfer()); } autoTier Tier_create (long initialCapacity) { try { autoTier me = Thing_new (Tier); Tier_init (me.peek(), initialCapacity); return me; } catch (MelderError) { Melder_throw (U"Tier not created."); } } long Tier_timeToIndex (Tier me, double time) { for (long i = 1; i <= my size; i ++) { Autosegment interval = (Autosegment) my item [i]; if (time >= interval -> xmin && time < interval -> xmax) return i; } return 0; // empty tier or very large time } Thing_implement (Label, Ordered, 0); void Label_init (Label me, long initialNumberOfTiers) { Ordered_init (me, classTier, initialNumberOfTiers); for (long i = 1; i <= initialNumberOfTiers; i ++) { Collection_addItem (me, Tier_create (10).transfer()); } } autoLabel Label_create (long initialNumberOfTiers) { try { autoLabel me = Thing_new (Label); Label_init (me.peek(), initialNumberOfTiers); return me; } catch (MelderError) { Melder_throw (U"Label not created."); } } void Label_addTier (Label me) { Collection_addItem (me, Tier_create (10).transfer()); } void Label_suggestDomain (Label me, double *tmin, double *tmax) { *tmin = 0.0; *tmax = 0.0; for (int itier = 1; itier <= my size; itier ++) { Tier tier = (Tier) my item [itier]; if (tier -> size) { Autosegment seg = (Autosegment) tier -> item [1]; if (seg -> xmin <= *tmin) { if (seg -> name && seg -> name [0]) *tmin = seg -> xmin - 1.0; else *tmin = seg -> xmin; } seg = (Autosegment) tier -> item [tier -> size]; if (seg -> xmax >= *tmax) *tmax = seg -> xmax; } } *tmax += 1.0; } /* End of file Label.cpp */ praat-6.0.04/fon/Label.h000066400000000000000000000047441261542461700147030ustar00rootroot00000000000000#ifndef _Label_h_ #define _Label_h_ /* Label.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Collection.h" #include "Function.h" Thing_define (Autosegment, Function) { void v_copy (Any data_to) override; bool v_equal (Any otherData) override; static Data_Description s_description; Data_Description v_description () override { return s_description; } }; autoAutosegment Autosegment_create (double tmin, double tmax, const char32 *label); /* Function: create a new instance of Autosegment. Return value: the new Autosegment. Preconditions: tmax > tmin; label may be null; Postconditions: result -> tmin == tmin; result -> tmax == tmax; if (label) result -> name == nullptr; else result -> name [] == label []; // 'label' copied into 'name' */ Thing_define (Tier, Sorted) { static int compare (Any data1, Any data2); int (*v_getCompareFunction ()) (Any data1, Any data2) override { return compare; } }; void Tier_init (Tier me, long initialCapacity); autoTier Tier_create (long initialCapacity); /* Function: create a new Tier containing one Autosegment from -1e30 to 1e30. Return value: the new Tier. Postconditions: my size == 1; my item [1] -> methods == classAutosegment; my item [1] -> xmin == -1e30; my item [1] -> xmax == 1e30; my item [1] -> name == nullptr; */ long Tier_timeToIndex (Tier me, double t); /* Return value: index, or 0 if the tier is empty or t is very large. Postconditions: result == 0 || my item [i] -> xmin <= result < my item [i] -> xmax; */ Thing_define (Label, Ordered) { }; autoLabel Label_create (long initialNumberOfTiers); void Label_init (Label me, long initialNumberOfTiers); void Label_addTier (Label me); void Label_suggestDomain (Label me, double *tmin, double *tmax); #endif /* End of file Label.h */ praat-6.0.04/fon/LongSound.cpp000066400000000000000000000675041261542461700161320ustar00rootroot00000000000000/* LongSound.cpp * * Copyright (C) 1992-2012,2014,2015 Paul Boersma, 2007 Erez Volk (for FLAC and MP3) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/05/28 * pb 2002/07/16 GPL * pb 2003/09/12 changed 5 to Melder_NUMBER_OF_AUDIO_FILE_TYPES * pb 2004/05/14 support for reading 24-bit and 32-bit audio files * pb 2004/11/24 made buffer length settable * pb 2006/12/10 MelderInfo * pb 2006/12/13 support for IEEE float 32-bit audio files * pb 2007/01/01 compatible with stereo sounds * pb 2007/01/27 more compatible with stereo sounds * pb 2007/03/17 domain quantity * Erez Volk 2007/03 FLAC reading * Erez Volk 2007/05/14 FLAC writing * Erez Volk 2007/06/04 MP3 reading * pb 2007/12/05 prefs * pb 2008/01/19 double * pb 2010/01/10 MP3 precision warning * fb 2010/02/25 corrected a bug that could cause LongSound_playPart to crash with an assertion on error * pb 2010/11/07 no longer do an assertion on thy resampledBuffer * pb 2010/12/20 support for more than 2 channels * pb 2011/06/02 C++ * pb 2011/07/05 C++ * pb 2014/06/16 more support for more than 2 channels */ #include "LongSound.h" #include "Preferences.h" #include "flac_FLAC_stream_decoder.h" #include "mp3.h" Thing_implement (LongSound, Sampled, 0); #define MARGIN 0.01 #define USE_MEMMOVE 1 static long prefs_bufferLength; void LongSound_preferences () { Preferences_addLong (U"LongSound.bufferLength", & prefs_bufferLength, 60); // seconds } long LongSound_getBufferSizePref_seconds () { return prefs_bufferLength; } void LongSound_setBufferSizePref_seconds (long size) { prefs_bufferLength = size < 10 ? 10 : size > 10000 ? 10000: size; } void structLongSound :: v_destroy () { /* * The play callback may contain a pointer to my buffer. * That pointer is about to dangle, so kill the playback. */ MelderAudio_stopPlaying (MelderAudio_IMPLICIT); if (mp3f) mp3f_delete (mp3f); if (flacDecoder) { FLAC__stream_decoder_finish (flacDecoder); // closes f FLAC__stream_decoder_delete (flacDecoder); } else if (f) fclose (f); NUMvector_free (buffer, 0); LongSound_Parent :: v_destroy (); } void structLongSound :: v_info () { static const char32 *encodingStrings [1+20] = { U"none", U"linear 8 bit signed", U"linear 8 bit unsigned", U"linear 16 bit big-endian", U"linear 16 bit little-endian", U"linear 24 bit big-endian", U"linear 24 bit little-endian", U"linear 32 bit big-endian", U"linear 32 bit little-endian", U"mu-law", U"A-law", U"shorten", U"polyphone", U"IEEE float 32 bit big-endian", U"IEEE float 32 bit little-endian", U"FLAC", U"FLAC", U"FLAC", U"MP3", U"MP3", U"MP3" }; structDaata :: v_info (); MelderInfo_writeLine (U"Duration: ", xmax - xmin, U" seconds"); MelderInfo_writeLine (U"File name: ", Melder_fileToPath (& file)); MelderInfo_writeLine (U"File type: ", audioFileType > Melder_NUMBER_OF_AUDIO_FILE_TYPES ? U"unknown" : Melder_audioFileTypeString (audioFileType)); MelderInfo_writeLine (U"Number of channels: ", numberOfChannels); MelderInfo_writeLine (U"Encoding: ", encoding > 20 ? U"unknown" : encodingStrings [encoding]); MelderInfo_writeLine (U"Sampling frequency: ", sampleRate, U" Hz"); MelderInfo_writeLine (U"Size: ", nx, U" samples"); MelderInfo_writeLine (U"Start of sample data: ", startOfData, U" bytes from the start of the file"); } static void _LongSound_FLAC_convertFloats (LongSound me, const FLAC__int32 * const samples[], long bitsPerSample, long numberOfSamples) { double multiplier; switch (bitsPerSample) { case 8: multiplier = (1.0f / 128); break; case 16: multiplier = (1.0f / 32768); break; case 24: multiplier = (1.0f / 8388608); break; case 32: multiplier = (1.0f / 32768 / 65536); break; default: multiplier = 0.0; } for (long i = 0; i < 2; ++i) { const FLAC__int32 *input = samples [i]; double *output = my compressedFloats [i]; if (! output ) continue; for (long j = 0; j < numberOfSamples; ++j) output [j] = (long)input [j] * multiplier; my compressedFloats [i] += numberOfSamples; } } static void _LongSound_FLAC_convertShorts (LongSound me, const FLAC__int32 * const samples[], long bitsPerSample, long numberOfSamples) { for (long channel = 0; channel < my numberOfChannels; ++ channel) { short *output = my compressedShorts + channel; const FLAC__int32 *input = samples [channel]; for (long j = 0; j < numberOfSamples; ++ j, output += my numberOfChannels) { FLAC__int32 sample = * (input ++); switch (bitsPerSample) { case 8: sample *= 256; break; case 16: break; case 24: sample /= 256; break; case 32: sample /= 65536; break; default: sample = 0; break; } *output = (short) sample; } } my compressedShorts += numberOfSamples * my numberOfChannels; } static FLAC__StreamDecoderWriteStatus _LongSound_FLAC_write (const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], I) { iam (LongSound); const FLAC__FrameHeader *header = & frame -> header; long numberOfSamples = header -> blocksize; long bitsPerSample = header -> bits_per_sample; (void) decoder; if (numberOfSamples > my compressedSamplesLeft) numberOfSamples = my compressedSamplesLeft; if (numberOfSamples == 0) return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; if (my compressedMode == COMPRESSED_MODE_READ_FLOAT) _LongSound_FLAC_convertFloats (me, buffer, bitsPerSample, numberOfSamples); else _LongSound_FLAC_convertShorts (me, buffer, bitsPerSample, numberOfSamples); my compressedSamplesLeft -= numberOfSamples; return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; } static void _LongSound_FLAC_error (const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, I) { iam (LongSound); (void) me; (void) decoder; (void) status; } static void _LongSound_MP3_convertFloats (LongSound me, const MP3F_SAMPLE *channels[MP3F_MAX_CHANNELS], long numberOfSamples) { for (long i = 0; i < 2; ++i) { const MP3F_SAMPLE *input = channels [i]; double *output = my compressedFloats [i]; if (! output ) continue; for (long j = 0; j < numberOfSamples; ++j) output [j] = mp3f_sample_to_float (input [j]); my compressedFloats [i] += numberOfSamples; } } static void _LongSound_MP3_convertShorts (LongSound me, const MP3F_SAMPLE *channels[MP3F_MAX_CHANNELS], long numberOfSamples) { for (long i = 0; i < my numberOfChannels; ++ i) { const MP3F_SAMPLE *input = channels [i]; short *output = my compressedShorts + i; for (long j = 0; j < numberOfSamples; ++j, output += my numberOfChannels) { int sample = *input++; *output = mp3f_sample_to_short (sample); } } my compressedShorts += numberOfSamples * my numberOfChannels; } static void _LongSound_MP3_convert (const MP3F_SAMPLE *channels[MP3F_MAX_CHANNELS], long numberOfSamples, I) { iam (LongSound); if (numberOfSamples > my compressedSamplesLeft) numberOfSamples = my compressedSamplesLeft; if (numberOfSamples == 0) return; if (my compressedMode == COMPRESSED_MODE_READ_FLOAT) _LongSound_MP3_convertFloats (me, channels, numberOfSamples); else _LongSound_MP3_convertShorts (me, channels, numberOfSamples); my compressedSamplesLeft -= numberOfSamples; } static void LongSound_init (LongSound me, MelderFile file) { MelderFile_copy (file, & my file); MelderFile_open (file); // BUG: should be auto, but that requires an implemented .transfer() my f = file -> filePointer; my audioFileType = MelderFile_checkSoundFile (file, & my numberOfChannels, & my encoding, & my sampleRate, & my startOfData, & my nx); if (my audioFileType == 0) Melder_throw (U"File not recognized (LongSound only supports AIFF, AIFC, WAV, NeXT/Sun, NIST and FLAC)."); if (my encoding == Melder_SHORTEN || my encoding == Melder_POLYPHONE) Melder_throw (U"LongSound does not support sound files compressed with \"shorten\"."); if (my nx < 1) Melder_throw (U"Audio file contains 0 samples."); my xmin = 0.0; my dx = 1 / my sampleRate; my xmax = my nx * my dx; my x1 = 0.5 * my dx; my numberOfBytesPerSamplePoint = Melder_bytesPerSamplePoint (my encoding); my bufferLength = prefs_bufferLength; for (;;) { my nmax = my bufferLength * my numberOfChannels * my sampleRate * (1 + 3 * MARGIN); try { my buffer = NUMvector (0, my nmax * my numberOfChannels); break; } catch (MelderError) { my bufferLength *= 0.5; // try 30, 15, or 7.5 seconds if (my bufferLength < 5.0) // too short to be good throw; Melder_clearError (); // delete out-of-memory message } } my imin = 1; my imax = 0; my flacDecoder = nullptr; if (my audioFileType == Melder_FLAC) { my flacDecoder = FLAC__stream_decoder_new (); FLAC__stream_decoder_init_FILE (my flacDecoder, my f, _LongSound_FLAC_write, nullptr, _LongSound_FLAC_error, me); } my mp3f = nullptr; if (my audioFileType == Melder_MP3) { my mp3f = mp3f_new (); mp3f_set_file (my mp3f, my f); mp3f_set_callback (my mp3f, _LongSound_MP3_convert, me); if (! mp3f_analyze (my mp3f)) Melder_throw (U"Unable to analyze MP3 file."); Melder_warning (U"Time measurements in MP3 files can be off by several tens of milliseconds. " U"Please convert to WAV file if you need time precision or annotation."); } } void structLongSound :: v_copy (thou) { thouart (LongSound); thy f = nullptr; thy buffer = nullptr; LongSound_init (thee, & file); } autoLongSound LongSound_open (MelderFile file) { try { autoLongSound me = Thing_new (LongSound); LongSound_init (me.peek(), file); return me; } catch (MelderError) { Melder_throw (U"LongSound not created."); } } static void _LongSound_FLAC_process (LongSound me, long firstSample, long numberOfSamples) { my compressedSamplesLeft = numberOfSamples - 1; if (! FLAC__stream_decoder_seek_absolute (my flacDecoder, firstSample)) Melder_throw (U"Cannot seek in FLAC file ", & my file, U"."); while (my compressedSamplesLeft > 0) { if (FLAC__stream_decoder_get_state (my flacDecoder) == FLAC__STREAM_DECODER_END_OF_STREAM) Melder_throw (U"FLAC file ", & my file, U" too short."); if (! FLAC__stream_decoder_process_single (my flacDecoder)) Melder_throw (U"Error decoding FLAC file ", & my file, U"."); } } static void _LongSound_FILE_seekSample (LongSound me, long firstSample) { if (fseek (my f, my startOfData + (firstSample - 1) * my numberOfChannels * my numberOfBytesPerSamplePoint, SEEK_SET)) Melder_throw (U"Cannot seek in file ", & my file, U"."); } static void _LongSound_FLAC_readAudioToShort (LongSound me, short *buffer, long firstSample, long numberOfSamples) { my compressedMode = COMPRESSED_MODE_READ_SHORT; my compressedShorts = buffer + 1; _LongSound_FLAC_process (me, firstSample, numberOfSamples); } static void _LongSound_MP3_process (LongSound me, long firstSample, long numberOfSamples) { if (! mp3f_seek (my mp3f, firstSample)) Melder_throw (U"Cannot seek in MP3 file ", & my file, U"."); my compressedSamplesLeft = numberOfSamples; if (! mp3f_read (my mp3f, numberOfSamples)) Melder_throw (U"Error decoding MP3 file ", & my file, U"."); } static void _LongSound_MP3_readAudioToShort (LongSound me, short *buffer, long firstSample, long numberOfSamples) { my compressedMode = COMPRESSED_MODE_READ_SHORT; my compressedShorts = buffer + 1; _LongSound_MP3_process (me, firstSample, numberOfSamples - 1); } void LongSound_readAudioToFloat (LongSound me, double **buffer, long firstSample, long numberOfSamples) { if (my encoding == Melder_FLAC_COMPRESSION_16) { my compressedMode = COMPRESSED_MODE_READ_FLOAT; for (int ichan = 1; ichan <= my numberOfChannels; ichan ++) { my compressedFloats [ichan - 1] = & buffer [ichan] [1]; } _LongSound_FLAC_process (me, firstSample, numberOfSamples); } else if (my encoding == Melder_MPEG_COMPRESSION_16) { my compressedMode = COMPRESSED_MODE_READ_FLOAT; for (int ichan = 1; ichan <= my numberOfChannels; ichan ++) { my compressedFloats [ichan - 1] = & buffer [ichan] [1]; } _LongSound_MP3_process (me, firstSample, numberOfSamples); } else { _LongSound_FILE_seekSample (me, firstSample); Melder_readAudioToFloat (my f, my numberOfChannels, my encoding, buffer, numberOfSamples); } } void LongSound_readAudioToShort (LongSound me, short *buffer, long firstSample, long numberOfSamples) { if (my encoding == Melder_FLAC_COMPRESSION_16) { _LongSound_FLAC_readAudioToShort (me, buffer, firstSample, numberOfSamples); } else if (my encoding == Melder_MPEG_COMPRESSION_16) { _LongSound_MP3_readAudioToShort (me, buffer, firstSample, numberOfSamples); } else { _LongSound_FILE_seekSample (me, firstSample); Melder_readAudioToShort (my f, my numberOfChannels, my encoding, buffer, numberOfSamples); } } autoSound LongSound_extractPart (LongSound me, double tmin, double tmax, int preserveTimes) { try { if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } if (tmin < my xmin) tmin = my xmin; if (tmax > my xmax) tmax = my xmax; long imin, imax; long n = Sampled_getWindowSamples (me, tmin, tmax, & imin, & imax); if (n < 1) Melder_throw (U"Less than 1 sample in window."); autoSound thee = Sound_create (my numberOfChannels, tmin, tmax, n, my dx, my x1 + (imin - 1) * my dx); if (! preserveTimes) thy xmin = 0.0, thy xmax -= tmin, thy x1 -= tmin; LongSound_readAudioToFloat (me, thy z, imin, n); return thee; } catch (MelderError) { Melder_throw (me, U": Sound not extracted."); } } static void _LongSound_readSamples (LongSound me, short *buffer, long imin, long imax) { LongSound_readAudioToShort (me, buffer, imin, imax - imin + 1); } static void writePartToOpenFile (LongSound me, int audioFileType, long imin, long n, MelderFile file, int numberOfChannels_override, int numberOfBitsPerSamplePoint) { long ibuffer, offset, numberOfBuffers, numberOfSamplesInLastBuffer; offset = imin; numberOfBuffers = (n - 1) / my nmax + 1; numberOfSamplesInLastBuffer = (n - 1) % my nmax + 1; if (file -> filePointer) for (ibuffer = 1; ibuffer <= numberOfBuffers; ibuffer ++) { long numberOfSamplesToCopy = ibuffer < numberOfBuffers ? my nmax : numberOfSamplesInLastBuffer; LongSound_readAudioToShort (me, my buffer, offset, numberOfSamplesToCopy); offset += numberOfSamplesToCopy; MelderFile_writeShortToAudio (file, numberOfChannels_override ? numberOfChannels_override : my numberOfChannels, Melder_defaultAudioFileEncoding (audioFileType, numberOfBitsPerSamplePoint), my buffer, numberOfSamplesToCopy); } /* * We "have" no samples any longer. */ my imin = 1; my imax = 0; } void LongSound_writePartToAudioFile (LongSound me, int audioFileType, double tmin, double tmax, MelderFile file, int numberOfBitsPerSamplePoint) { try { if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } if (tmin < my xmin) tmin = my xmin; if (tmax > my xmax) tmax = my xmax; long imin, imax; long n = Sampled_getWindowSamples (me, tmin, tmax, & imin, & imax); if (n < 1) Melder_throw (U"Less than 1 sample selected."); autoMelderFile mfile = MelderFile_create (file); MelderFile_writeAudioFileHeader (file, audioFileType, my sampleRate, n, my numberOfChannels, numberOfBitsPerSamplePoint); writePartToOpenFile (me, audioFileType, imin, n, file, 0, numberOfBitsPerSamplePoint); MelderFile_writeAudioFileTrailer (file, audioFileType, my sampleRate, n, my numberOfChannels, numberOfBitsPerSamplePoint); mfile.close (); } catch (MelderError) { Melder_throw (me, U": not written to sound file ", file, U"."); } } void LongSound_writeChannelToAudioFile (LongSound me, int audioFileType, int channel, MelderFile file) { try { if (my numberOfChannels != 2) Melder_throw (U"This audio file is not a stereo file. It does not have a ", channel == 0 ? U"left" : U"right", U" channel."); autoMelderFile mfile = MelderFile_create (file); if (file -> filePointer) { MelderFile_writeAudioFileHeader (file, audioFileType, my sampleRate, my nx, 1, 8 * my numberOfBytesPerSamplePoint); } writePartToOpenFile (me, audioFileType, 1, my nx, file, channel == 0 ? -1 : -2, 8 * my numberOfBytesPerSamplePoint); MelderFile_writeAudioFileTrailer (file, audioFileType, my sampleRate, my nx, 1, 8 * my numberOfBytesPerSamplePoint); mfile.close (); } catch (MelderError) { Melder_throw (U"Channel ", channel, U" of ", me, U": not written to sound file ", file, U"."); } } static void _LongSound_haveSamples (LongSound me, long imin, long imax) { long n = imax - imin + 1; Melder_assert (n <= my nmax); /* * Included? */ if (imin >= my imin && imax <= my imax) return; /* * Extendable? */ if (imin >= my imin && imax - my imin + 1 <= my nmax) { _LongSound_readSamples (me, my buffer + (my imax - my imin + 1) * my numberOfChannels, my imax + 1, imax); my imax = imax; return; } /* * Determine the loadable imin..imax. * Add margins on both sides. */ imin -= MARGIN * n; if (imin < 1) imin = 1; imax = imin + (1.0 + 2 * MARGIN) * n; if (imax > my nx) imax = my nx; imin = imax - (1.0 + 2 * MARGIN) * n; if (imin < 1) imin = 1; Melder_assert (imax - imin + 1 <= my nmax); /* * Overlap? */ if (imax < my imin || imin > my imax) { /* * No overlap. */ _LongSound_readSamples (me, my buffer, imin, imax); } else if (imin < my imin) { /* * Left overlap. */ if (imax <= my imax) { /* * Only left overlap (e.g. scrolling up). */ long nshift = (imax - my imin + 1) * my numberOfChannels, shift = (my imin - imin) * my numberOfChannels; #if USE_MEMMOVE memmove (my buffer + shift, my buffer, nshift * sizeof (short)); #else for (i = nshift - 1; i >= 0; i --) my buffer [i + shift] = my buffer [i]; #endif _LongSound_readSamples (me, my buffer, imin, my imin - 1); } else { /* * Left and right overlap (e.g. zooming out). */ long nshift = (my imax - my imin + 1) * my numberOfChannels, shift = (my imin - imin) * my numberOfChannels; #if USE_MEMMOVE memmove (my buffer + shift, my buffer, nshift * sizeof (short)); #else for (i = nshift - 1; i >= 0; i --) my buffer [i + shift] = my buffer [i]; #endif _LongSound_readSamples (me, my buffer, imin, my imin - 1); _LongSound_readSamples (me, my buffer + (my imax - imin + 1) * my numberOfChannels, my imax + 1, imax); } } else { /* * Only right overlap (e.g. scrolling down). */ long nshift = (my imax - imin + 1) * my numberOfChannels, shift = (imin - my imin) * my numberOfChannels; #if USE_MEMMOVE memmove (my buffer, my buffer + shift, nshift * sizeof (short)); #else for (i = 0; i < nshift; i ++) my buffer [i] = my buffer [i + shift]; #endif _LongSound_readSamples (me, my buffer + (my imax - imin + 1) * my numberOfChannels, my imax + 1, imax); } my imin = imin, my imax = imax; } bool LongSound_haveWindow (LongSound me, double tmin, double tmax) { long imin, imax; long n = Sampled_getWindowSamples (me, tmin, tmax, & imin, & imax); if ((1.0 + 2 * MARGIN) * n + 1 > my nmax) return false; _LongSound_haveSamples (me, imin, imax); return true; } void LongSound_getWindowExtrema (LongSound me, double tmin, double tmax, int channel, double *minimum, double *maximum) { long imin, imax; long i, minimum_int = 32767, maximum_int = -32768; (void) Sampled_getWindowSamples (me, tmin, tmax, & imin, & imax); *minimum = 1.0; *maximum = -1.0; try { LongSound_haveWindow (me, tmin, tmax); } catch (MelderError) { Melder_clearError (); return; } for (i = imin; i <= imax; i ++) { long value = my buffer [(i - my imin) * my numberOfChannels + channel - 1]; if (value < minimum_int) minimum_int = value; if (value > maximum_int) maximum_int = value; } *minimum = minimum_int / 32768.0; *maximum = maximum_int / 32768.0; } static struct LongSoundPlay { long numberOfSamples, i1, i2, silenceBefore, silenceAfter; double tmin, tmax, dt, t1; short *resampledBuffer; int (*callback) (void *closure, int phase, double tmin, double tmax, double t); void *closure; } thePlayingLongSound; static bool melderPlayCallback (void *closure, long samplesPlayed) { struct LongSoundPlay *me = (struct LongSoundPlay *) closure; int phase = 2; double t = samplesPlayed <= my silenceBefore ? my tmin : samplesPlayed >= my silenceBefore + my numberOfSamples ? my tmax : my t1 + (my i1 - 1.5 + samplesPlayed - my silenceBefore) * my dt; if (! MelderAudio_isPlaying) { phase = 3; Melder_free (my resampledBuffer); } if (my callback) return my callback (my closure, phase, my tmin, my tmax, t); return true; } void LongSound_playPart (LongSound me, double tmin, double tmax, int (*callback) (void *closure, int phase, double tmin, double tmax, double t), void *closure) { struct LongSoundPlay *thee = (struct LongSoundPlay *) & thePlayingLongSound; MelderAudio_stopPlaying (MelderAudio_IMPLICIT); Melder_free (thy resampledBuffer); // just in case, and after playing has stopped try { int fits = LongSound_haveWindow (me, tmin, tmax); long bestSampleRate = MelderAudio_getOutputBestSampleRate (my sampleRate), n, i1, i2; if (! fits) Melder_throw (U"Sound too long (", tmax - tmin, U" seconds)."); /* * Assign to *thee only after stopping the playing sound. */ thy tmin = tmin; thy tmax = tmax; thy callback = callback; thy closure = closure; if ((n = Sampled_getWindowSamples (me, tmin, tmax, & i1, & i2)) < 2) return; if (bestSampleRate == my sampleRate) { thy numberOfSamples = n; thy dt = 1 / my sampleRate; thy t1 = my x1; thy i1 = i1; thy i2 = i2; thy silenceBefore = (long) (my sampleRate * MelderAudio_getOutputSilenceBefore ()); thy silenceAfter = (long) (my sampleRate * MelderAudio_getOutputSilenceAfter ()); if (thy callback) thy callback (thy closure, 1, tmin, tmax, tmin); if (thy silenceBefore > 0 || thy silenceAfter > 0 || 1) { thy resampledBuffer = Melder_calloc (short, (thy silenceBefore + thy numberOfSamples + thy silenceAfter) * my numberOfChannels); memcpy (& thy resampledBuffer [thy silenceBefore * my numberOfChannels], & my buffer [(i1 - my imin) * my numberOfChannels], thy numberOfSamples * sizeof (short) * my numberOfChannels); MelderAudio_play16 (thy resampledBuffer, my sampleRate, thy silenceBefore + thy numberOfSamples + thy silenceAfter, my numberOfChannels, melderPlayCallback, thee); } else { MelderAudio_play16 (my buffer + (i1 - my imin) * my numberOfChannels, my sampleRate, thy numberOfSamples, my numberOfChannels, melderPlayCallback, thee); } } else { long newSampleRate = bestSampleRate; long newN = ((double) n * newSampleRate) / my sampleRate - 1, i; long silenceBefore = (long) (newSampleRate * MelderAudio_getOutputSilenceBefore ()); long silenceAfter = (long) (newSampleRate * MelderAudio_getOutputSilenceAfter ()); short *resampledBuffer = Melder_calloc (short, (silenceBefore + newN + silenceAfter) * my numberOfChannels); short *from = my buffer + (i1 - my imin) * my numberOfChannels; /* Guaranteed: from [0 .. (my imax - my imin + 1) * nchan] */ double t1 = my x1, dt = 1.0 / newSampleRate; thy numberOfSamples = newN; thy dt = dt; thy t1 = t1 + i1 / my sampleRate; thy i1 = 0; thy i2 = newN - 1; thy silenceBefore = silenceBefore; thy silenceAfter = silenceAfter; thy resampledBuffer = resampledBuffer; if (my numberOfChannels == 1) { for (i = 0; i < newN; i ++) { double t = t1 + i * dt; /* From t1 to t1 + (newN-1) * dt */ double index = (t - t1) * my sampleRate; /* From 0. */ long flore = index; /* DANGEROUS: Implicitly rounding down... */ double fraction = index - flore; resampledBuffer [i + silenceBefore] = (1.0 - fraction) * from [flore] + fraction * from [flore + 1]; } } else if (my numberOfChannels == 2) { for (i = 0; i < newN; i ++) { double t = t1 + i * dt; double index = (t - t1) * my sampleRate; long flore = index; double fraction = index - flore; long ii = i + silenceBefore; resampledBuffer [ii + ii] = (1.0 - fraction) * from [flore + flore] + fraction * from [flore + flore + 2]; resampledBuffer [ii + ii + 1] = (1.0 - fraction) * from [flore + flore + 1] + fraction * from [flore + flore + 3]; } } else { for (i = 0; i < newN; i ++) { double t = t1 + i * dt; double index = (t - t1) * my sampleRate; long flore = index; double fraction = index - flore; long ii = (i + silenceBefore) * my numberOfChannels; for (long chan = 0; chan < my numberOfChannels; chan ++) { resampledBuffer [ii + chan] = (1.0 - fraction) * from [flore * my numberOfChannels + chan] + fraction * from [(flore + 1) * my numberOfChannels + chan]; } } } if (thy callback) thy callback (thy closure, 1, tmin, tmax, tmin); MelderAudio_play16 (resampledBuffer, newSampleRate, silenceBefore + newN + silenceAfter, my numberOfChannels, melderPlayCallback, thee); } //Melder_free (thy resampledBuffer); // cannot do that, because MelderAudio_play16 isn't necessarily synchronous } catch (MelderError) { Melder_free (thy resampledBuffer); Melder_throw (me, U": not played."); } } void LongSound_concatenate (Collection me, MelderFile file, int audioFileType, int numberOfBitsPerSamplePoint) { try { long sampleRate, n; /* Integer sampling frequencies only, because of possible rounding errors. */ int numberOfChannels; if (my size < 1) Melder_throw (U"No Sound or LongSound objects to concatenate."); /* * The sampling frequencies and numbers of channels must be equal for all (long)sounds. */ Sampled data = (Sampled) my item [1]; if (data -> classInfo == classSound) { Sound sound = (Sound) data; sampleRate = floor (1.0 / sound -> dx + 0.5); numberOfChannels = sound -> ny; n = sound -> nx; } else { LongSound longSound = (LongSound) data; sampleRate = longSound -> sampleRate; numberOfChannels = longSound -> numberOfChannels; n = longSound -> nx; } /* * Check whether all the sampling frequencies and channels match. */ for (long i = 2; i <= my size; i ++) { int sampleRatesMatch, numbersOfChannelsMatch; data = (Sampled) my item [i]; if (data -> classInfo == classSound) { Sound sound = (Sound) data; sampleRatesMatch = round (1.0 / sound -> dx) == sampleRate; numbersOfChannelsMatch = sound -> ny == numberOfChannels; n += sound -> nx; } else { LongSound longSound = (LongSound) data; sampleRatesMatch = longSound -> sampleRate == sampleRate; numbersOfChannelsMatch = longSound -> numberOfChannels == numberOfChannels; n += longSound -> nx; } if (! sampleRatesMatch) Melder_throw (U"Sampling frequencies are not equal."); if (! numbersOfChannelsMatch) Melder_throw (U"Cannot mix stereo and mono."); } /* * Create output file and write header. */ autoMelderFile mfile = MelderFile_create (file); if (file -> filePointer) { MelderFile_writeAudioFileHeader (file, audioFileType, sampleRate, n, numberOfChannels, numberOfBitsPerSamplePoint); } for (long i = 1; i <= my size; i ++) { data = (Sampled) my item [i]; if (data -> classInfo == classSound) { Sound sound = (Sound) data; if (file -> filePointer) { MelderFile_writeFloatToAudio (file, sound -> ny, Melder_defaultAudioFileEncoding (audioFileType, numberOfBitsPerSamplePoint), sound -> z, sound -> nx, true); } } else { LongSound longSound = (LongSound) data; writePartToOpenFile (longSound, audioFileType, 1, longSound -> nx, file, 0, numberOfBitsPerSamplePoint); } } MelderFile_writeAudioFileTrailer (file, audioFileType, sampleRate, n, numberOfChannels, numberOfBitsPerSamplePoint); mfile.close (); } catch (MelderError) { Melder_throw (U"Sounds not concatenated and not saved to ", file, U"."); } } /* End of file LongSound.cpp */ praat-6.0.04/fon/LongSound.h000066400000000000000000000057731261542461700155770ustar00rootroot00000000000000#ifndef _LongSound_h_ #define _LongSound_h_ /* LongSound.h * * Copyright (C) 1992-2012,2015 Paul Boersma, 2007 Erez Volk (for FLAC, MP3) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Sound.h" #include "Collection.h" #define COMPRESSED_MODE_READ_FLOAT 0 #define COMPRESSED_MODE_READ_SHORT 1 struct FLAC__StreamDecoder; struct FLAC__StreamEncoder; struct _MP3_FILE; Thing_define (LongSound, Sampled) { structMelderFile file; FILE *f; int audioFileType, numberOfChannels, encoding, numberOfBytesPerSamplePoint; double sampleRate; long startOfData; double bufferLength; short *buffer; long imin, imax, nmax; struct FLAC__StreamDecoder *flacDecoder; struct _MP3_FILE *mp3f; int compressedMode; long compressedSamplesLeft; double *compressedFloats [2]; short *compressedShorts; void v_destroy () override; void v_info () override; void v_copy (Any data_to) override; bool v_writable () override { return false; } int v_domainQuantity () override { return MelderQuantity_TIME_SECONDS; } }; autoLongSound LongSound_open (MelderFile file); autoSound LongSound_extractPart (LongSound me, double tmin, double tmax, int preserveTimes); bool LongSound_haveWindow (LongSound me, double tmin, double tmax); /* * Returns 0 if error or if window exceeds buffer, otherwise 1; */ void LongSound_getWindowExtrema (LongSound me, double tmin, double tmax, int channel, double *minimum, double *maximum); void LongSound_playPart (LongSound me, double tmin, double tmax, int (*callback) (void *closure, int phase, double tmin, double tmax, double t), void *closure); void LongSound_writePartToAudioFile (LongSound me, int audioFileType, double tmin, double tmax, MelderFile file, int numberOfBitsPerSamplePoint); void LongSound_writeChannelToAudioFile (LongSound me, int audioFileType, int channel, MelderFile file); void LongSound_readAudioToFloat (LongSound me, double **buffer, long firstSample, long numberOfSamples); void LongSound_readAudioToShort (LongSound me, short *buffer, long firstSample, long numberOfSamples); void LongSound_concatenate (Collection collection, MelderFile file, int audioFileType, int numberOfBitsPerSamplePoint); /* Concatenate a collection of Sound and LongSound objects. */ void LongSound_preferences (); long LongSound_getBufferSizePref_seconds (); void LongSound_setBufferSizePref_seconds (long size); /* End of file LongSound.h */ #endif praat-6.0.04/fon/Ltas.cpp000066400000000000000000000436101261542461700151150ustar00rootroot00000000000000/* Ltas.cpp * * Copyright (C) 1992-2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * a selection of changes: * pb 2005/11/26 pitch-corrected Ltas */ #include "Ltas.h" #include "Sound_and_Spectrum.h" #include "Sound_to_PointProcess.h" Thing_implement (Ltas, Vector, 2); void structLtas :: v_info () { double meanPowerDensity; structDaata :: v_info (); MelderInfo_writeLine (U"Frequency domain:"); MelderInfo_writeLine (U" Lowest frequency: ", xmin, U" Hz"); MelderInfo_writeLine (U" Highest frequency: ", xmax, U" Hz"); MelderInfo_writeLine (U" Total frequency domain: ", xmax - xmin, U" Hz"); MelderInfo_writeLine (U"Frequency sampling:"); MelderInfo_writeLine (U" Number of frequency bands: ", nx); MelderInfo_writeLine (U" Width of each band: ", dx, U" Hz"); MelderInfo_writeLine (U" First band centred at: ", x1, U" Hz"); meanPowerDensity = Sampled_getMean (this, xmin, xmax, 0, 1, false); MelderInfo_writeLine (U"Total SPL: ", Melder_single (10.0 * log10 (meanPowerDensity * (xmax - xmin))), U" dB"); } double structLtas :: v_convertStandardToSpecialUnit (double value, long ilevel, int unit) { (void) ilevel; if (unit == 1) { return pow (10.0, 0.1 * value); // energy } else if (unit == 2) { return pow (2.0, 0.1 * value); // sones } return value; } double structLtas :: v_convertSpecialToStandardUnit (double value, long ilevel, int unit) { (void) ilevel; return unit == 1 ? 10.0 * log10 (value) : // value = energy unit == 2 ? 10.0 * NUMlog2 (value) : // value = sones value; // value = dB } autoLtas Ltas_create (long nx, double dx) { try { autoLtas me = Thing_new (Ltas); Matrix_init (me.peek(), 0.0, nx * dx, nx, dx, 0.5 * dx, 1.0, 1.0, 1, 1.0, 1.0); return me; } catch (MelderError) { Melder_throw (U"Ltas not created."); } } void Ltas_draw (Ltas me, Graphics g, double fmin, double fmax, double minimum, double maximum, int garnish, const char32 *method) { Vector_draw (me, g, & fmin, & fmax, & minimum, & maximum, 1.0, method); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Frequency (Hz)"); Graphics_marksBottom (g, 2, true, true, false); Graphics_textLeft (g, true, U"Sound pressure level (dB/Hz)"); Graphics_marksLeft (g, 2, true, true, false); } } double Ltas_getSlope (Ltas me, double f1min, double f1max, double f2min, double f2max, int averagingUnits) { double low = Sampled_getMean (me, f1min, f1max, 0, averagingUnits, false); double high = Sampled_getMean (me, f2min, f2max, 0, averagingUnits, false); if (low == NUMundefined || high == NUMundefined) return NUMundefined; return averagingUnits == 3 ? high - low : Function_convertSpecialToStandardUnit (me, high / low, 0, averagingUnits); } double Ltas_getLocalPeakHeight (Ltas me, double environmentMin, double environmentMax, double peakMin, double peakMax, int averagingUnits) { double environmentLow = Sampled_getMean (me, environmentMin, peakMin, 0, averagingUnits, false); double environmentHigh = Sampled_getMean (me, peakMax, environmentMax, 0, averagingUnits, false); double peak = Sampled_getMean (me, peakMin, peakMax, 0, averagingUnits, false); if (environmentLow == NUMundefined || environmentHigh == NUMundefined || peak == NUMundefined) return NUMundefined; return averagingUnits == 3 ? peak - 0.5 * (environmentLow + environmentHigh) : Function_convertSpecialToStandardUnit (me, peak / (0.5 * (environmentLow + environmentHigh)), 0, averagingUnits); } autoMatrix Ltas_to_Matrix (Ltas me) { try { autoMatrix thee = Thing_new (Matrix); my structMatrix :: v_copy (thee.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Matrix."); } } autoLtas Matrix_to_Ltas (Matrix me) { try { autoLtas thee = Thing_new (Ltas); my structMatrix :: v_copy (thee.peek()); // because copying a descendant of Matrix with additional members should not crash return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Ltas."); } } autoLtas Ltases_merge (Collection ltases) { try { if (ltases -> size < 1) Melder_throw (U"Cannot merge zero Ltas objects."); Ltas me = (Ltas) ltases -> item [1]; autoLtas thee = Data_copy (me); /* * Convert to energy. */ for (long iband = 1; iband <= thy nx; iband ++) { thy z [1] [iband] = pow (10.0, thy z [1] [iband] / 10.0); } for (long ispec = 2; ispec <= ltases -> size; ispec ++) { Ltas him = (Ltas) ltases -> item [ispec]; if (his xmin != thy xmin || his xmax != thy xmax) Melder_throw (U"Frequency domains do not match."); if (his dx != thy dx) Melder_throw (U"Bandwidths do not match."); if (his nx != thy nx || his x1 != thy x1) Melder_throw (U"Frequency bands do not match."); /* * Add band energies. */ for (long iband = 1; iband <= thy nx; iband ++) { thy z [1] [iband] += pow (10.0, his z [1] [iband] / 10.0); } } /* * Convert back to dB. */ for (long iband = 1; iband <= thy nx; iband ++) { thy z [1] [iband] = 10.0 * log10 (thy z [1] [iband]); } return thee; } catch (MelderError) { Melder_throw (U"Ltas objects not merged."); } } autoLtas Ltases_average (Collection ltases) { try { double factor = -10.0 * log10 (ltases -> size); autoLtas thee = Ltases_merge (ltases); for (long iband = 1; iband <= thy nx; iband ++) { thy z [1] [iband] += factor; } return thee; } catch (MelderError) { Melder_throw (U"Ltas objects not averaged."); } } autoLtas Ltas_computeTrendLine (Ltas me, double fmin, double fmax) { try { /* * Find the first and last bin. */ long imin, imax, n; if ((n = Sampled_getWindowSamples (me, fmin, fmax, & imin, & imax)) < 2) Melder_throw (U"Number of bins too low (", n, U"). Should be at least 2."); autoLtas thee = Data_copy (me); /* * Compute average amplitude and frequency. */ double sum = 0.0, amean, fmean, numerator = 0.0, denominator = 0.0, slope; for (long i = imin; i <= imax; i ++) { sum += thy z [1] [i]; } amean = sum / n; fmean = thy x1 + (0.5 * (imin + imax) - 1) * thy dx; /* * Compute slope. */ for (long i = imin; i <= imax; i ++) { double da = thy z [1] [i] - amean, df = thy x1 + (i - 1) * thy dx - fmean; numerator += da * df; denominator += df * df; } slope = numerator / denominator; /* * Modify bins. */ for (long i = 1; i <= thy nx; i ++) { double df = thy x1 + (i - 1) * thy dx - fmean; thy z [1] [i] = amean + slope * df; } return thee; } catch (MelderError) { Melder_throw (me, U": trend line not computed."); } } autoLtas Ltas_subtractTrendLine (Ltas me, double fmin, double fmax) { try { /* * Find the first and last bin. */ long imin, imax, n; if ((n = Sampled_getWindowSamples (me, fmin, fmax, & imin, & imax)) < 2) Melder_throw (U"Number of bins too low (", n, U"). Should be at least 2."); autoLtas thee = Data_copy (me); /* * Compute average amplitude and frequency. */ double sum = 0.0, amean, fmean, numerator = 0.0, denominator = 0.0, slope; for (long i = imin; i <= imax; i ++) { sum += thy z [1] [i]; } amean = sum / n; fmean = thy x1 + (0.5 * (imin + imax) - 1) * thy dx; /* * Compute slope. */ for (long i = imin; i <= imax; i ++) { double da = thy z [1] [i] - amean, df = thy x1 + (i - 1) * thy dx - fmean; numerator += da * df; denominator += df * df; } slope = numerator / denominator; /* * Modify bins. */ for (long i = 1; i < imin; i ++) { thy z [1] [i] = 0.0; } for (long i = imin; i <= imax; i ++) { double df = thy x1 + (i - 1) * thy dx - fmean; thy z [1] [i] -= amean + slope * df; } for (long i = imax + 1; i <= thy nx; i ++) { thy z [1] [i] = 0.0; } return thee; } catch (MelderError) { Melder_throw (me, U": trend line not subtracted."); } } autoLtas Spectrum_to_Ltas (Spectrum me, double bandWidth) { try { long numberOfBands = ceil ((my xmax - my xmin) / bandWidth); if (bandWidth <= my dx) Melder_throw (U"Bandwidth must be greater than ", my dx, U"."); autoLtas thee = Thing_new (Ltas); Matrix_init (thee.peek(), my xmin, my xmax, numberOfBands, bandWidth, my xmin + 0.5 * bandWidth, 1.0, 1.0, 1, 1.0, 1.0); for (long iband = 1; iband <= numberOfBands; iband ++) { double fmin = thy xmin + (iband - 1) * bandWidth; double meanEnergyDensity = Sampled_getMean (me, fmin, fmin + bandWidth, 0, 1, false); double meanPowerDensity = meanEnergyDensity * my dx; // as an approximation for a division by the original duration thy z [1] [iband] = meanPowerDensity == 0.0 ? -300.0 : 10.0 * log10 (meanPowerDensity / 4.0e-10); } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Ltas."); } } autoLtas Spectrum_to_Ltas_1to1 (Spectrum me) { try { autoLtas thee = Thing_new (Ltas); Matrix_init (thee.peek(), my xmin, my xmax, my nx, my dx, my x1, 1.0, 1.0, 1, 1.0, 1.0); for (long iband = 1; iband <= my nx; iband ++) { thy z [1] [iband] = Sampled_getValueAtSample (me, iband, 0, 2); } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Ltas."); } } autoLtas Sound_to_Ltas (Sound me, double bandwidth) { try { autoSpectrum thee = Sound_to_Spectrum (me, true); autoLtas him = Spectrum_to_Ltas (thee.peek(), bandwidth); double correction = -10.0 * log10 (thy dx * my nx * my dx); for (long iband = 1; iband <= his nx; iband ++) { his z [1] [iband] += correction; } return him; } catch (MelderError) { Melder_throw (me, U": LTAS analysis not performed."); } } autoLtas PointProcess_Sound_to_Ltas (PointProcess pulses, Sound sound, double maximumFrequency, double bandWidth, double shortestPeriod, double longestPeriod, double maximumPeriodFactor) { try { long numberOfPeriods = pulses -> nt - 2, totalNumberOfEnergies = 0; autoLtas ltas = Ltas_create (maximumFrequency / bandWidth, bandWidth); ltas -> xmax = maximumFrequency; autoLtas numbers = Data_copy (ltas.peek()); if (numberOfPeriods < 1) Melder_throw (U"Cannot compute an Ltas if there are no periods in the point process."); autoMelderProgress progress (U"Ltas analysis..."); for (long ipulse = 2; ipulse < pulses -> nt; ipulse ++) { double leftInterval = pulses -> t [ipulse] - pulses -> t [ipulse - 1]; double rightInterval = pulses -> t [ipulse + 1] - pulses -> t [ipulse]; double intervalFactor = leftInterval > rightInterval ? leftInterval / rightInterval : rightInterval / leftInterval; Melder_progress ((double) ipulse / pulses -> nt, U"Sound & PointProcess: To Ltas: pulse ", ipulse, U" out of ", pulses -> nt); if (leftInterval >= shortestPeriod && leftInterval <= longestPeriod && rightInterval >= shortestPeriod && rightInterval <= longestPeriod && intervalFactor <= maximumPeriodFactor) { /* * We have a period! Compute the spectrum. */ autoSound period = Sound_extractPart (sound, pulses -> t [ipulse] - 0.5 * leftInterval, pulses -> t [ipulse] + 0.5 * rightInterval, kSound_windowShape_RECTANGULAR, 1.0, false); autoSpectrum spectrum = Sound_to_Spectrum (period.peek(), false); for (long ifreq = 1; ifreq <= spectrum -> nx; ifreq ++) { double frequency = spectrum -> xmin + (ifreq - 1) * spectrum -> dx; double realPart = spectrum -> z [1] [ifreq]; double imaginaryPart = spectrum -> z [2] [ifreq]; double energy = (realPart * realPart + imaginaryPart * imaginaryPart) * 2.0 * spectrum -> dx /* OLD: * sound -> nx */; long iband = ceil (frequency / bandWidth); if (iband >= 1 && iband <= ltas -> nx) { ltas -> z [1] [iband] += energy; numbers -> z [1] [iband] += 1; totalNumberOfEnergies += 1; } } } else { numberOfPeriods -= 1; } } if (numberOfPeriods < 1) Melder_throw (U"There are no periods in the point process."); for (long iband = 1; iband <= ltas -> nx; iband ++) { if (numbers -> z [1] [iband] == 0.0) { ltas -> z [1] [iband] = NUMundefined; } else { /* * Each bin now contains a total energy in Pa2 sec. * To convert this to power density, we */ double totalEnergyInThisBand = ltas -> z [1] [iband]; if (0 /* i.e. if you just want to have a spectrum of the voiced parts... */) { double energyDensityInThisBand = totalEnergyInThisBand / ltas -> dx; double powerDensityInThisBand = energyDensityInThisBand / (sound -> xmax - sound -> xmin); ltas -> z [1] [iband] = 10.0 * log10 (powerDensityInThisBand / 4.0e-10); } else { /* * And this is what we really want. The total energy has to be redistributed. */ double meanEnergyInThisBand = totalEnergyInThisBand / numbers -> z [1] [iband]; double meanNumberOfEnergiesPerBand = (double) totalNumberOfEnergies / ltas -> nx; double redistributedEnergyInThisBand = meanEnergyInThisBand * meanNumberOfEnergiesPerBand; double redistributedEnergyDensityInThisBand = redistributedEnergyInThisBand / ltas -> dx; double redistributedPowerDensityInThisBand = redistributedEnergyDensityInThisBand / (sound -> xmax - sound -> xmin); ltas -> z [1] [iband] = 10.0 * log10 (redistributedPowerDensityInThisBand / 4.0e-10); /* OLD: ltas -> z [1] [iband] = 10.0 * log10 (ltas -> z [1] [iband] / numbers -> z [1] [iband] * sound -> nx);*/ } } } for (long iband = 1; iband <= ltas -> nx; iband ++) { if (ltas -> z [1] [iband] == NUMundefined) { long ibandleft = iband - 1, ibandright = iband + 1; while (ibandleft >= 1 && ltas -> z [1] [ibandleft] == NUMundefined) ibandleft --; while (ibandright <= ltas -> nx && ltas -> z [1] [ibandright] == NUMundefined) ibandright ++; if (ibandleft < 1 && ibandright > ltas -> nx) Melder_throw (U"Cannot create an Ltas without energy in any bins."); if (ibandleft < 1) { ltas -> z [1] [iband] = ltas -> z [1] [ibandright]; } else if (ibandright > ltas -> nx) { ltas -> z [1] [iband] = ltas -> z [1] [ibandleft]; } else { double frequency = ltas -> x1 + (iband - 1) * ltas -> dx; double fleft = ltas -> x1 + (ibandleft - 1) * ltas -> dx; double fright = ltas -> x1 + (ibandright - 1) * ltas -> dx; ltas -> z [1] [iband] = ((fright - frequency) * ltas -> z [1] [ibandleft] + (frequency - fleft) * ltas -> z [1] [ibandright]) / (fright - fleft); } } } return ltas; } catch (MelderError) { Melder_throw (sound, U" & ", pulses, U": LTAS analysis not performed."); } } autoLtas Sound_to_Ltas_pitchCorrected (Sound sound, double minimumPitch, double maximumPitch, double maximumFrequency, double bandWidth, double shortestPeriod, double longestPeriod, double maximumPeriodFactor) { try { autoPointProcess pulses = Sound_to_PointProcess_periodic_cc (sound, minimumPitch, maximumPitch); autoLtas ltas = PointProcess_Sound_to_Ltas (pulses.peek(), sound, maximumFrequency, bandWidth, shortestPeriod, longestPeriod, maximumPeriodFactor); return ltas; } catch (MelderError) { Melder_throw (sound, U": pitch-corrected LTAS analysis not performed."); } } autoLtas PointProcess_Sound_to_Ltas_harmonics (PointProcess pulses, Sound sound, long maximumHarmonic, double shortestPeriod, double longestPeriod, double maximumPeriodFactor) { try { long numberOfPeriods = pulses -> nt - 2; autoLtas ltas = Ltas_create (maximumHarmonic, 1.0); ltas -> xmax = maximumHarmonic; if (numberOfPeriods < 1) Melder_throw (U"There are no periods in the point process."); autoMelderProgress progress (U"LTAS (harmonics) analysis..."); for (long ipulse = 2; ipulse < pulses -> nt; ipulse ++) { double leftInterval = pulses -> t [ipulse] - pulses -> t [ipulse - 1]; double rightInterval = pulses -> t [ipulse + 1] - pulses -> t [ipulse]; double intervalFactor = leftInterval > rightInterval ? leftInterval / rightInterval : rightInterval / leftInterval; Melder_progress ((double) ipulse / pulses -> nt, U"Sound & PointProcess: To Ltas: pulse ", ipulse, U" out of ", pulses -> nt); if (leftInterval >= shortestPeriod && leftInterval <= longestPeriod && rightInterval >= shortestPeriod && rightInterval <= longestPeriod && intervalFactor <= maximumPeriodFactor) { /* * We have a period! Compute the spectrum. */ long localMaximumHarmonic; autoSound period = Sound_extractPart (sound, pulses -> t [ipulse] - 0.5 * leftInterval, pulses -> t [ipulse] + 0.5 * rightInterval, kSound_windowShape_RECTANGULAR, 1.0, false); autoSpectrum spectrum = Sound_to_Spectrum (period.peek(), false); localMaximumHarmonic = maximumHarmonic < spectrum -> nx ? maximumHarmonic : spectrum -> nx; for (long iharm = 1; iharm <= localMaximumHarmonic; iharm ++) { double realPart = spectrum -> z [1] [iharm]; double imaginaryPart = spectrum -> z [2] [iharm]; double energy = (realPart * realPart + imaginaryPart * imaginaryPart) * 2.0 * spectrum -> dx; ltas -> z [1] [iharm] += energy; } } else { numberOfPeriods -= 1; } } if (numberOfPeriods < 1) Melder_throw (U"There are no periods in the point process."); for (long iharm = 1; iharm <= ltas -> nx; iharm ++) { if (ltas -> z [1] [iharm] == 0.0) { ltas -> z [1] [iharm] = -300.0; } else { double energyInThisBand = ltas -> z [1] [iharm]; double powerInThisBand = energyInThisBand / (sound -> xmax - sound -> xmin); ltas -> z [1] [iharm] = 10.0 * log10 (powerInThisBand / 4.0e-10); } } return ltas; } catch (MelderError) { Melder_throw (sound, U" & ", pulses, U": LTAS analysis (harmonics) not performed."); } } /* End of file Ltas.cpp */ praat-6.0.04/fon/Ltas.h000066400000000000000000000065071261542461700145660ustar00rootroot00000000000000#ifndef _Ltas_h_ #define _Ltas_h_ /* Ltas.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Spectrum.h" #include "Sound.h" #include "PointProcess.h" #include "Collection.h" Thing_define (Ltas, Vector) { void v_info () override; int v_domainQuantity () override { return MelderQuantity_FREQUENCY_HERTZ; } double v_convertStandardToSpecialUnit (double value, long ilevel, int unit) override; double v_convertSpecialToStandardUnit (double value, long ilevel, int unit) override; }; /* Attributes: xmin // Minimum frequency (Hz). xmax > xmin // Maximum frequency (Hz). nx >= 1 // Number of bands. dx > 0.0 // Band width (Hz). x1 // Centre of first band (Hz). ymin, ymax, ny, dy, y1 = 1 z [1] [1..nx] // The intensity per band, in db/Hz. */ autoLtas Ltas_create (long nx, double dx); /* Function: create an Ltas. Preconditions: nx >= 1; dx > 0.0; Postconditions: my xmin == 0; my ymin == 1; my xmax == nx * dx; my ymax == 1; my nx == nx; my ny == 1; my dx == dx; my dy == 1; my x1 == 0.5 * dx; my y1 == 1; my z [1] [1..nx] == 1e-4; // straight tube, area 1 cm2. */ void Ltas_draw (Ltas me, Graphics g, double fmin, double fmax, double minimum, double maximum, int garnish, const char32 *method); autoMatrix Ltas_to_Matrix (Ltas me); autoLtas Matrix_to_Ltas (Matrix me); autoLtas Ltases_merge (Collection ltases); autoLtas Ltases_average (Collection ltases); autoLtas Ltas_computeTrendLine (Ltas me, double fmin, double fmax); autoLtas Ltas_subtractTrendLine (Ltas me, double fmin, double fmax); /* Direct computations. */ autoLtas Spectrum_to_Ltas (Spectrum me, double bandwidth); autoLtas Spectrum_to_Ltas_1to1 (Spectrum me); autoLtas PointProcess_Sound_to_Ltas (PointProcess pulses, Sound sound, double maximumFrequency, double bandWidth, double shortestPeriod, double longestPeriod, double maximumPeriodFactor); autoLtas PointProcess_Sound_to_Ltas_harmonics (PointProcess pulses, Sound sound, long maximumHarmonic, double shortestPeriod, double longestPeriod, double maximumPeriodFactor); /* Shortcuts. */ autoLtas Sound_to_Ltas (Sound me, double bandwidth); autoLtas Sound_to_Ltas_pitchCorrected (Sound sound, double minimumPitch, double maximumPitch, double maximumFrequency, double bandWidth, double shortestPeriod, double longestPeriod, double maximumPeriodFactor); double Ltas_getSlope (Ltas me, double f1min, double f1max, double f2min, double f2max, int averagingUnits); double Ltas_getLocalPeakHeight (Ltas me, double environmentMin, double environmentMax, double peakMin, double peakMax, int averagingUnits); /* End of file Ltas.h */ #endif praat-6.0.04/fon/Ltas_to_SpectrumTier.cpp000066400000000000000000000021741261542461700203250ustar00rootroot00000000000000/* Ltas_to_SpectrumTier.cpp * * Copyright (C) 2007-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Ltas_to_SpectrumTier.h" autoSpectrumTier Ltas_to_SpectrumTier_peaks (Ltas me) { try { autoSpectrumTier thee = Vector_to_RealTier_peaks (me, 1, classSpectrumTier).static_cast_move(); return thee; } catch (MelderError) { Melder_throw (me, U": peaks not analyzed as SpectrumTier."); } } /* End of file Ltas_to_SpectrumTier.cpp */ praat-6.0.04/fon/Ltas_to_SpectrumTier.h000066400000000000000000000016301261542461700177660ustar00rootroot00000000000000/* Ltas_to_SpectrumTier.h * * Copyright (C) 2007-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Ltas.h" #include "SpectrumTier.h" autoSpectrumTier Ltas_to_SpectrumTier_peaks (Ltas me); /* End of file Ltas_to_SpectrumTier.h */ praat-6.0.04/fon/Makefile000066400000000000000000000053621261542461700151500ustar00rootroot00000000000000# Makefile of the library "fon" # Paul Boersma, 27 October 2013 include ../makefile.defs CPPFLAGS = -I ../num -I ../kar -I ../sys -I ../dwsys -I ../stat -I ../dwtools -I ../LPC -I ../fon -I ../external/portaudio -I ../external/flac -I ../external/mp3 OBJECTS = Transition.o Distributions_and_Transition.o \ Function.o Sampled.o SampledXY.o Matrix.o Vector.o Polygon.o PointProcess.o \ Matrix_and_PointProcess.o Matrix_and_Polygon.o AnyTier.o RealTier.o \ Sound.o LongSound.o Sound_files.o Sound_audio.o PointProcess_and_Sound.o Sound_PointProcess.o ParamCurve.o \ Pitch.o Harmonicity.o Intensity.o Matrix_and_Pitch.o Sound_to_Pitch.o \ Sound_to_Intensity.o Sound_to_Harmonicity.o Sound_to_Harmonicity_GNE.o Sound_to_PointProcess.o \ Pitch_to_PointProcess.o Pitch_to_Sound.o Pitch_Intensity.o \ PitchTier.o Pitch_to_PitchTier.o PitchTier_to_PointProcess.o PitchTier_to_Sound.o Manipulation.o \ Pitch_AnyTier_to_PitchTier.o IntensityTier.o DurationTier.o AmplitudeTier.o \ Spectrum.o Ltas.o Spectrogram.o SpectrumTier.o Ltas_to_SpectrumTier.o \ Formant.o Image.o Sound_to_Formant.o Sound_and_Spectrogram.o \ Sound_and_Spectrum.o Spectrum_and_Spectrogram.o Spectrum_to_Formant.o \ FormantTier.o TextGrid.o TextGrid_Sound.o Label.o FormantGrid.o \ Excitation.o Cochleagram.o Cochleagram_and_Excitation.o Excitation_to_Formant.o \ Sound_to_Cochleagram.o Spectrum_to_Excitation.o \ VocalTract.o VocalTract_to_Spectrum.o \ SoundRecorder.o Sound_enhance.o VoiceAnalysis.o \ FunctionEditor.o TimeSoundEditor.o TimeSoundAnalysisEditor.o \ PitchEditor.o SoundEditor.o SpectrumEditor.o SpectrogramEditor.o PointEditor.o \ RealTierEditor.o PitchTierEditor.o IntensityTierEditor.o \ DurationTierEditor.o AmplitudeTierEditor.o \ ManipulationEditor.o TextGridEditor.o FormantGridEditor.o \ WordList.o SpellingChecker.o \ FujisakiPitch.o \ ExperimentMFC.o RunnerMFC.o manual_Exp.o praat_Exp.o \ Photo.o Movie.o MovieWindow.o \ Corpus.o \ manual_Picture.o manual_Manual.o manual_Script.o \ manual_soundFiles.o manual_tutorials.o manual_references.o \ manual_programming.o manual_Fon.o manual_voice.o Praat_tests.o \ manual_glossary.o manual_Sampling.o manual_exampleSound.o \ manual_sound.o manual_pitch.o manual_spectrum.o manual_formant.o manual_annotation.o \ praat_Sound_init.o praat_TextGrid_init.o praat_Fon.o .PHONY: all clean all: libfon.a clean: $(RM) $(OBJECTS) $(RM) libfon.a libfon.a: $(OBJECTS) touch libfon.a rm libfon.a $(AR) cq libfon.a $(OBJECTS) $(RANLIB) libfon.a $(OBJECTS): *.h ../num/NUM.h ../external/portaudio/*.h ../kar/*.h ../sys/*.h ../dwsys/*.h ../stat/*.h ../dwtools/*.h ../LPC/*.h ../external/flac/*.h ../external/mp3/mp3.h praat-6.0.04/fon/Manipulation.cpp000066400000000000000000000661651261542461700166640ustar00rootroot00000000000000/* Manipulation.cpp * * Copyright (C) 1992-2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Manipulation.h" #include "Sound_to_Pitch.h" #include "Pitch_to_PitchTier.h" #include "Pitch_AnyTier_to_PitchTier.h" #include "PitchTier_to_PointProcess.h" #include "Pitch_to_PointProcess.h" #include "PointProcess_and_Sound.h" #include "Sound_and_LPC.h" #define MAX_T 0.02000000001 /* Maximum interval between two voice pulses (otherwise voiceless). */ #include "oo_DESTROY.h" #include "Manipulation_def.h" #include "oo_COPY.h" #include "Manipulation_def.h" #include "oo_EQUAL.h" #include "Manipulation_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Manipulation_def.h" #include "oo_WRITE_TEXT.h" #include "Manipulation_def.h" #include "oo_READ_TEXT.h" #include "Manipulation_def.h" #include "oo_WRITE_BINARY.h" #include "Manipulation_def.h" #include "oo_READ_BINARY.h" #include "Manipulation_def.h" #include "oo_DESCRIPTION.h" #include "Manipulation_def.h" Thing_implement (Manipulation, Function, 5); void structManipulation :: v_shiftX (double xfrom, double xto) { Manipulation_Parent :: v_shiftX (xfrom, xto); if (our sound ) Function_shiftXTo (our sound.get(), xfrom, xto); if (our pulses ) Function_shiftXTo (our pulses.get(), xfrom, xto); if (our pitch ) Function_shiftXTo (our pitch.get(), xfrom, xto); if (our duration) Function_shiftXTo (our duration.get(), xfrom, xto); if (our lpc ) Function_shiftXTo (our lpc, xfrom, xto); } void structManipulation :: v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto) { Manipulation_Parent :: v_scaleX (xminfrom, xmaxfrom, xminto, xmaxto); if (our sound ) our sound -> v_scaleX (xminfrom, xmaxfrom, xminto, xmaxto); if (our pulses ) our pulses -> v_scaleX (xminfrom, xmaxfrom, xminto, xmaxto); if (our pitch ) our pitch -> v_scaleX (xminfrom, xmaxfrom, xminto, xmaxto); if (our duration) our duration -> v_scaleX (xminfrom, xmaxfrom, xminto, xmaxto); if (our lpc ) our lpc -> v_scaleX (xminfrom, xmaxfrom, xminto, xmaxto); } autoManipulation Manipulation_create (double tmin, double tmax) { try { autoManipulation me = Thing_new (Manipulation); my xmin = tmin, my xmax = tmax; my duration = DurationTier_create (tmin, tmax); return me; } catch (MelderError) { Melder_throw (U"Manipulation object not created."); } } void Manipulation_replaceOriginalSound (Manipulation me, Sound sound) { try { my sound = Sound_convertToMono (sound); Vector_subtractMean (my sound.peek()); my lpc = nullptr; } catch (MelderError) { Melder_throw (me, U": original Sound not replaced with ", sound, U"."); } } void Manipulation_replacePulses (Manipulation me, PointProcess pulses) { try { my pulses = Data_copy (pulses); } catch (MelderError) { Melder_throw (me, U": pulses not replaced with ", pulses, U"."); } } void Manipulation_replacePitchTier (Manipulation me, PitchTier pitch) { try { my pitch = Data_copy (pitch); } catch (MelderError) { Melder_throw (me, U": pitch tier not replaced with ", pitch, U"."); } } void Manipulation_replaceDurationTier (Manipulation me, DurationTier duration) { try { my duration = Data_copy (duration); } catch (MelderError) { Melder_throw (me, U": duration tier not replaced with ", duration, U"."); } } autoManipulation Sound_to_Manipulation (Sound me, double timeStep, double minimumPitch, double maximumPitch) { try { autoManipulation thee = Manipulation_create (my xmin, my xmax); thy sound = Sound_convertToMono (me); Vector_subtractMean (thy sound.get()); autoPitch pitch = Sound_to_Pitch (thy sound.get(), timeStep, minimumPitch, maximumPitch); thy pulses = Sound_Pitch_to_PointProcess_cc (thy sound.get(), pitch.peek()); thy pitch = Pitch_to_PitchTier (pitch.peek()); /* (DurationTier has been done at creation time) */ return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Manipulation."); } } autoManipulation Sound_Pitch_to_Manipulation (Sound sound, Pitch pitch) { try { autoManipulation me = Manipulation_create (sound -> xmin, sound -> xmax); my sound = Sound_convertToMono (sound); Vector_subtractMean (my sound.get()); my pulses = Sound_Pitch_to_PointProcess_cc (my sound.get(), pitch); my pitch = Pitch_to_PitchTier (pitch); return me; } catch (MelderError) { Melder_throw (sound, U" & ", pitch, U": not converted to Manipulation."); } } autoManipulation Sound_PointProcess_to_Manipulation (Sound sound, PointProcess point) { try { autoManipulation me = Manipulation_create (sound -> xmin, sound -> xmax); my sound = Sound_convertToMono (sound); Vector_subtractMean (my sound.get()); my pulses = Data_copy (point); my pitch = PointProcess_to_PitchTier (point, MAX_T); return me; } catch (MelderError) { Melder_throw (sound, U" & ", point, U": not converted to Manipulation."); } } int Manipulation_playPart (Manipulation me, double tmin, double tmax, int method) { try { if (method == Manipulation_OVERLAPADD) { if (! my sound) Melder_throw (U"Cannot synthesize overlap-add without a sound."); autoSound part = Data_copy (my sound.get()); long imin = Sampled_xToLowIndex (part.peek(), tmin), imax = Sampled_xToHighIndex (part.peek(), tmax); double *amp = part -> z [1]; for (long i = 1; i <= imin; i ++) amp [i] = 0.0; for (long i = imax; i <= part -> nx; i ++) amp [i] = 0.0; autoSound saved = my sound.move(); my sound = part.move(); try { autoSound played = Manipulation_to_Sound (me, Manipulation_OVERLAPADD); my sound = saved.move(); amp = played -> z [1]; for (imin = 1; imin <= played -> nx; imin ++) if (amp [imin] != 0.0) break; for (imax = played -> nx; imax >= 1; imax --) if (amp [imax] != 0.0) break; Sound_playPart (played.peek(), played -> x1 + (imin - 1.5) * played -> dx, played -> x1 + (imax - 0.5) * played -> dx, nullptr, nullptr); } catch (MelderError) { my sound = saved.move(); throw; } } else { autoSound sound = Manipulation_to_Sound (me, method); Sound_playPart (sound.peek(), tmin, tmax, nullptr, nullptr); } return 1; } catch (MelderError) { Melder_throw (me, U": not played."); } } int Manipulation_play (Manipulation me, int method) { try { autoSound sound = Manipulation_to_Sound (me, method); Sound_play (sound.peek(), nullptr, nullptr); return 1; } catch (MelderError) { Melder_throw (me, U": not played."); } } static long PointProcess_getFirstVoicedPoint (PointProcess me, double maxT) { for (long i = 1; i < my nt; i ++) if (my t [i + 1] - my t [i] <= maxT) return i; return 0; } static void copyRise (Sound me, double tmin, double tmax, Sound thee, double tmaxTarget) { long imin = Sampled_xToHighIndex (me, tmin); if (imin < 1) imin = 1; long imax = Sampled_xToHighIndex (me, tmax) - 1; // not xToLowIndex: ensure separation of subsequent calls if (imax > my nx) imax = my nx; if (imax < imin) return; long imaxTarget = Sampled_xToHighIndex (thee, tmaxTarget) - 1; long distance = imaxTarget - imax; double dphase = NUMpi / (imax - imin + 1); for (long i = imin; i <= imax; i ++) { long iTarget = i + distance; if (iTarget >= 1 && iTarget <= thy nx) thy z [1] [iTarget] += my z [1] [i] * 0.5 * (1.0 - cos (dphase * (i - imin + 0.5))); } } static void copyFall (Sound me, double tmin, double tmax, Sound thee, double tminTarget) { long imin = Sampled_xToHighIndex (me, tmin); if (imin < 1) imin = 1; long imax = Sampled_xToHighIndex (me, tmax) - 1; // not xToLowIndex: ensure separation of subsequent calls if (imax > my nx) imax = my nx; if (imax < imin) return; long iminTarget = Sampled_xToHighIndex (thee, tminTarget); long distance = iminTarget - imin; double dphase = NUMpi / (imax - imin + 1); for (long i = imin; i <= imax; i ++) { long iTarget = i + distance; if (iTarget >= 1 && iTarget <= thy nx) thy z [1] [iTarget] += my z [1] [i] * 0.5 * (1.0 + cos (dphase * (i - imin + 0.5))); } } static void copyBell (Sound me, double tmid, double leftWidth, double rightWidth, Sound thee, double tmidTarget) { copyRise (me, tmid - leftWidth, tmid, thee, tmidTarget); copyFall (me, tmid, tmid + rightWidth, thee, tmidTarget); } static void copyBell2 (Sound me, PointProcess source, long isource, double leftWidth, double rightWidth, Sound thee, double tmidTarget, double maxT) { /* * Replace 'leftWidth' and 'rightWidth' by the lengths of the intervals in the source (instead of target), * if these are shorter. */ double tmid = source -> t [isource]; if (isource > 1 && tmid - source -> t [isource - 1] <= maxT) { double sourceLeftWidth = tmid - source -> t [isource - 1]; if (sourceLeftWidth < leftWidth) leftWidth = sourceLeftWidth; } if (isource < source -> nt && source -> t [isource + 1] - tmid <= maxT) { double sourceRightWidth = source -> t [isource + 1] - tmid; if (sourceRightWidth < rightWidth) rightWidth = sourceRightWidth; } copyBell (me, tmid, leftWidth, rightWidth, thee, tmidTarget); } static void copyFlat (Sound me, double tmin, double tmax, Sound thee, double tminTarget) { long imin = Sampled_xToHighIndex (me, tmin); if (imin < 1) imin = 1; long imax = Sampled_xToHighIndex (me, tmax) - 1; /* Not xToLowIndex: ensure separation of subsequent calls. */ if (imax > my nx) imax = my nx; if (imax < imin) return; long iminTarget = Sampled_xToHighIndex (thee, tminTarget); if (iminTarget < 1) iminTarget = 1; trace (tmin, U" ", tmax, U" ", tminTarget, U" ", imin, U" ", imax, U" ", iminTarget); Melder_assert (iminTarget + imax - imin <= thy nx); NUMvector_copyElements (my z [1] + imin, thy z [1] + iminTarget, 0, imax - imin); } autoSound Sound_Point_Point_to_Sound (Sound me, PointProcess source, PointProcess target, double maxT) { try { autoSound thee = Sound_create (1, my xmin, my xmax, my nx, my dx, my x1); if (source -> nt < 2 || target -> nt < 2) { /* Almost completely voiceless? */ NUMvector_copyElements (my z [1], thy z [1], 1, my nx); return thee.transfer(); } for (long i = 1; i <= target -> nt; i ++) { double tmid = target -> t [i]; double tleft = i > 1 ? target -> t [i - 1] : my xmin; double tright = i < target -> nt ? target -> t [i + 1] : my xmax; double leftWidth = tmid - tleft, rightWidth = tright - tmid; int leftVoiced = i > 1 && leftWidth <= maxT; int rightVoiced = i < target -> nt && rightWidth <= maxT; long isource = PointProcess_getNearestIndex (source, tmid); if (! leftVoiced) leftWidth = rightWidth; /* Symmetric bell. */ if (! rightVoiced) rightWidth = leftWidth; /* Symmetric bell. */ if (leftVoiced || rightVoiced) { copyBell2 (me, source, isource, leftWidth, rightWidth, thee.peek(), tmid, maxT); if (! leftVoiced) { double startOfFlat = i == 1 ? tleft : (tleft + tmid) / 2; double endOfFlat = tmid - leftWidth; copyFlat (me, startOfFlat, endOfFlat, thee.peek(), startOfFlat); copyFall (me, endOfFlat, tmid, thee.peek(), endOfFlat); } else if (! rightVoiced) { double startOfFlat = tmid + rightWidth; double endOfFlat = i == target -> nt ? tright : (tmid + tright) / 2; copyRise (me, tmid, startOfFlat, thee.peek(), startOfFlat); copyFlat (me, startOfFlat, endOfFlat, thee.peek(), startOfFlat); } } else { double startOfFlat = i == 1 ? tleft : (tleft + tmid) / 2; double endOfFlat = i == target -> nt ? tright : (tmid + tright) / 2; copyFlat (me, startOfFlat, endOfFlat, thee.peek(), startOfFlat); } } return thee; } catch (MelderError) { Melder_throw (me, U": not manipulated."); } } autoSound Sound_Point_Pitch_Duration_to_Sound (Sound me, PointProcess pulses, PitchTier pitch, DurationTier duration, double maxT) { try { long ipointleft, ipointright; double deltat = 0, handledTime = my xmin; double startOfSourceNoise, endOfSourceNoise, startOfTargetNoise, endOfTargetNoise; double durationOfSourceNoise, durationOfTargetNoise; double startOfSourceVoice, endOfSourceVoice, startOfTargetVoice, endOfTargetVoice; double durationOfSourceVoice, durationOfTargetVoice; double startingPeriod, finishingPeriod, ttarget, voicelessPeriod; if (duration -> points -> size == 0) Melder_throw (U"No duration points."); /* * Create a Sound long enough to hold the longest possible duration-manipulated sound. */ autoSound thee = Sound_create (1, my xmin, my xmin + 3 * (my xmax - my xmin), 3 * my nx, my dx, my x1); /* * Below, I'll abbreviate the voiced interval as "voice" and the voiceless interval as "noise". */ if (pitch && pitch -> points -> size) for (ipointleft = 1; ipointleft <= pulses -> nt; ipointleft = ipointright + 1) { /* * Find the beginning of the voice. */ startOfSourceVoice = pulses -> t [ipointleft]; /* The first pulse of the voice. */ startingPeriod = 1.0 / RealTier_getValueAtTime (pitch, startOfSourceVoice); startOfSourceVoice -= 0.5 * startingPeriod; /* The first pulse is in the middle of a period. */ /* * Measure one noise. */ startOfSourceNoise = handledTime; endOfSourceNoise = startOfSourceVoice; durationOfSourceNoise = endOfSourceNoise - startOfSourceNoise; startOfTargetNoise = startOfSourceNoise + deltat; endOfTargetNoise = startOfTargetNoise + RealTier_getArea (duration, startOfSourceNoise, endOfSourceNoise); durationOfTargetNoise = endOfTargetNoise - startOfTargetNoise; /* * Copy the noise. */ voicelessPeriod = NUMrandomUniform (0.008, 0.012); ttarget = startOfTargetNoise + 0.5 * voicelessPeriod; while (ttarget < endOfTargetNoise) { double tsource; double tleft = startOfSourceNoise, tright = endOfSourceNoise; int i; for (i = 1; i <= 15; i ++) { double tsourcemid = 0.5 * (tleft + tright); double ttargetmid = startOfTargetNoise + RealTier_getArea (duration, startOfSourceNoise, tsourcemid); if (ttargetmid < ttarget) tleft = tsourcemid; else tright = tsourcemid; } tsource = 0.5 * (tleft + tright); copyBell (me, tsource, voicelessPeriod, voicelessPeriod, thee.peek(), ttarget); voicelessPeriod = NUMrandomUniform (0.008, 0.012); ttarget += voicelessPeriod; } deltat += durationOfTargetNoise - durationOfSourceNoise; /* * Find the end of the voice. */ for (ipointright = ipointleft + 1; ipointright <= pulses -> nt; ipointright ++) if (pulses -> t [ipointright] - pulses -> t [ipointright - 1] > maxT) break; ipointright --; endOfSourceVoice = pulses -> t [ipointright]; /* The last pulse of the voice. */ finishingPeriod = 1.0 / RealTier_getValueAtTime (pitch, endOfSourceVoice); endOfSourceVoice += 0.5 * finishingPeriod; /* The last pulse is in the middle of a period. */ /* * Measure one voice. */ durationOfSourceVoice = endOfSourceVoice - startOfSourceVoice; /* * This will be copied to an interval with a different location and duration. */ startOfTargetVoice = startOfSourceVoice + deltat; endOfTargetVoice = startOfTargetVoice + RealTier_getArea (duration, startOfSourceVoice, endOfSourceVoice); durationOfTargetVoice = endOfTargetVoice - startOfTargetVoice; /* * Copy the voiced part. */ ttarget = startOfTargetVoice + 0.5 * startingPeriod; while (ttarget < endOfTargetVoice) { double tsource, period; long isourcepulse; double tleft = startOfSourceVoice, tright = endOfSourceVoice; int i; for (i = 1; i <= 15; i ++) { double tsourcemid = 0.5 * (tleft + tright); double ttargetmid = startOfTargetVoice + RealTier_getArea (duration, startOfSourceVoice, tsourcemid); if (ttargetmid < ttarget) tleft = tsourcemid; else tright = tsourcemid; } tsource = 0.5 * (tleft + tright); period = 1.0 / RealTier_getValueAtTime (pitch, tsource); isourcepulse = PointProcess_getNearestIndex (pulses, tsource); copyBell2 (me, pulses, isourcepulse, period, period, thee.peek(), ttarget, maxT); ttarget += period; } deltat += durationOfTargetVoice - durationOfSourceVoice; handledTime = endOfSourceVoice; } /* * Copy the remaining unvoiced part, if we are at the end. */ startOfSourceNoise = handledTime; endOfSourceNoise = my xmax; durationOfSourceNoise = endOfSourceNoise - startOfSourceNoise; startOfTargetNoise = startOfSourceNoise + deltat; endOfTargetNoise = startOfTargetNoise + RealTier_getArea (duration, startOfSourceNoise, endOfSourceNoise); durationOfTargetNoise = endOfTargetNoise - startOfTargetNoise; voicelessPeriod = NUMrandomUniform (0.008, 0.012); ttarget = startOfTargetNoise + 0.5 * voicelessPeriod; while (ttarget < endOfTargetNoise) { double tsource; double tleft = startOfSourceNoise, tright = endOfSourceNoise; for (int i = 1; i <= 15; i ++) { double tsourcemid = 0.5 * (tleft + tright); double ttargetmid = startOfTargetNoise + RealTier_getArea (duration, startOfSourceNoise, tsourcemid); if (ttargetmid < ttarget) tleft = tsourcemid; else tright = tsourcemid; } tsource = 0.5 * (tleft + tright); copyBell (me, tsource, voicelessPeriod, voicelessPeriod, thee.peek(), ttarget); voicelessPeriod = NUMrandomUniform (0.008, 0.012); ttarget += voicelessPeriod; } /* * Find the number of trailing zeroes and hack the sound's time domain. */ thy xmax = thy xmin + RealTier_getArea (duration, my xmin, my xmax); if (fabs (thy xmax - my xmax) < 1e-12) thy xmax = my xmax; /* Common situation. */ thy nx = Sampled_xToLowIndex (thee.peek(), thy xmax); if (thy nx > 3 * my nx) thy nx = 3 * my nx; return thee; } catch (MelderError) { Melder_throw (me, U": not manipulated."); } } static autoSound synthesize_overlapAdd_nodur (Manipulation me) { try { if (! my sound) Melder_throw (U"Missing original sound."); if (! my pulses) Melder_throw (U"Missing pulses analysis."); if (! my pitch) Melder_throw (U"Missing pitch manipulation."); autoPointProcess targetPulses = PitchTier_Point_to_PointProcess (my pitch.get(), my pulses.get(), MAX_T); return Sound_Point_Point_to_Sound (my sound.get(), my pulses.get(), targetPulses.peek(), MAX_T); } catch (MelderError) { Melder_throw (me, U": overlap-add synthesis (without duration) not performed."); } } static autoSound synthesize_overlapAdd (Manipulation me) { if (! my duration || my duration -> points -> size == 0) return synthesize_overlapAdd_nodur (me); try { if (! my sound) Melder_throw (U"Missing original sound."); if (! my pulses) Melder_throw (U"Missing pulses analysis."); if (! my pitch) Melder_throw (U"Missing pitch manipulation."); return Sound_Point_Pitch_Duration_to_Sound (my sound.get(), my pulses.get(), my pitch.get(), my duration.get(), MAX_T); } catch (MelderError) { Melder_throw (me, U": overlap-add synthesis not performed."); } } static autoSound synthesize_pulses (Manipulation me) { try { if (! my pulses) Melder_throw (U"Missing pulses analysis."); return PointProcess_to_Sound_pulseTrain (my pulses.get(), 44100, 0.7, 0.05, 30); } catch (MelderError) { Melder_throw (me, U": pulses synthesis not performed."); } } static autoSound synthesize_pulses_hum (Manipulation me) { try { if (! my pulses) Melder_throw (U"Missing pulses analysis."); return PointProcess_to_Sound_hum (my pulses.get()); } catch (MelderError) { Melder_throw (me, U": pulses hum synthesis not performed."); } } static autoSound synthesize_pitch (Manipulation me) { try { if (! my pitch) Melder_throw (U"Missing pitch tier."); autoPointProcess pulses = PitchTier_to_PointProcess (my pitch.get()); return PointProcess_to_Sound_pulseTrain (pulses.peek(), 44100, 0.7, 0.05, 30); } catch (MelderError) { Melder_throw (me, U": pitch manipulation not synthesized."); } } static autoSound synthesize_pitch_hum (Manipulation me) { try { if (! my pitch) Melder_throw (U"Missing pitch tier."); autoPointProcess pulses = PitchTier_to_PointProcess (my pitch.get()); return PointProcess_to_Sound_hum (pulses.peek()); } catch (MelderError) { Melder_throw (me, U": pitch hum manipulation not synthesized."); } } static autoSound synthesize_pulses_pitch (Manipulation me) { try { if (! my pulses) Melder_throw (U"Missing pulses analysis."); if (! my pitch) Melder_throw (U"Missing pitch tier."); autoPointProcess pulses = PitchTier_Point_to_PointProcess (my pitch.get(), my pulses.get(), MAX_T); return PointProcess_to_Sound_pulseTrain (pulses.peek(), 44100, 0.7, 0.05, 30); } catch (MelderError) { Melder_throw (me, U": pitch pulses manipulation not synthesized."); } } static autoSound synthesize_pulses_pitch_hum (Manipulation me) { try { if (! my pulses) Melder_throw (U"Missing pulses analysis."); if (! my pitch) Melder_throw (U"Missing pitch tier."); autoPointProcess pulses = PitchTier_Point_to_PointProcess (my pitch.get(), my pulses.get(), MAX_T); return PointProcess_to_Sound_hum (pulses.peek()); } catch (MelderError) { Melder_throw (me, U": pitch pulses hum manipulation not synthesized."); } } /* void Sound_Formant_Intensity_filter (Sound me, FormantTier formantTier, IntensityTier intensity) { Sound_FormantTier_filter_inline (me, formantTier); if (intensity) Sound_IntensityTier_multiply_inline (me, intensity); NUMdeemphasize_f (my z [1], my nx, my dx, 50.0); Vector_scale (me, 0.99); } static Sound synthesize_pulses_formant (Manipulation me, int useIntensity) { try { if (! my pulses) Melder_throw (U"Missing pulses analysis."); if (! my formant) Melder_throw (U"Missing formant information."); autoSound thee = PointProcess_to_Sound (my pulses, 44100, 0.7, 0.05, 30); Sound_Formant_Intensity_filter (thee.peek(), my formant, useIntensity ? my intensity : nullptr); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": formant and pulses manipulation not synthesized."); } } */ static void Sound_PointProcess_fillVoiceless (Sound me, PointProcess pulses) { long ipointleft, ipointright; double beginVoiceless = my xmin, endVoiceless; for (ipointleft = 1; ipointleft <= pulses -> nt; ipointleft = ipointright + 1) { long i1, i2, i; endVoiceless = pulses -> t [ipointleft] - 0.005; i1 = Sampled_xToHighIndex (me, beginVoiceless); if (i1 < 1) i1 = 1; if (i1 > my nx) i1 = my nx; i2 = Sampled_xToLowIndex (me, endVoiceless); if (i2 < 1) i2 = 1; if (i2 > my nx) i2 = my nx; if (i2 - i1 > 10) for (i = i1; i <= i2; i ++) my z [1] [i] = NUMrandomGauss (0.0, 0.3); for (ipointright = ipointleft + 1; ipointright <= pulses -> nt; ipointright ++) if (pulses -> t [ipointright] - pulses -> t [ipointright - 1] > MAX_T) break; ipointright --; beginVoiceless = pulses -> t [ipointright] + 0.005; } endVoiceless = my xmax; { long i1, i2, i; i1 = Sampled_xToHighIndex (me, beginVoiceless); if (i1 < 1) i1 = 1; if (i1 > my nx) i1 = my nx; i2 = Sampled_xToLowIndex (me, endVoiceless); if (i2 < 1) i2 = 1; if (i2 > my nx) i2 = my nx; if (i2 - i1 > 10) for (i = i1; i <= i2; i ++) my z [1] [i] = NUMrandomGauss (0.0, 0.3); } } static autoSound synthesize_pulses_lpc (Manipulation me) { try { if (! my lpc) { if (! my sound) Melder_throw (U"Missing original sound."); autoSound sound10k = Sound_resample (my sound.get(), 10000.0, 50); my lpc = Sound_to_LPC_burg (sound10k.peek(), 20, 0.025, 0.01, 50.0).transfer(); } if (! my pulses) Melder_throw (U"Missing pulses analysis."); autoSound train = PointProcess_to_Sound_pulseTrain (my pulses.get(), 1.0 / my lpc -> samplingPeriod, 0.7, 0.05, 30); train -> dx = my lpc -> samplingPeriod; // to be exact Sound_PointProcess_fillVoiceless (train.peek(), my pulses.get()); autoSound result = LPC_and_Sound_filter (my lpc, train.peek(), true); NUMdeemphasize_f (result -> z [1], result -> nx, result -> dx, 50.0); Vector_scale (result.peek(), 0.99); return result; } catch (MelderError) { Melder_throw (me, U": LPC synthesis not performed."); } } static autoSound synthesize_pitch_lpc (Manipulation me) { try { if (! my lpc) { if (! my sound) Melder_throw (U"Missing original sound."); autoSound sound10k = Sound_resample (my sound.get(), 10000.0, 50); my lpc = Sound_to_LPC_burg (sound10k.peek(), 20, 0.025, 0.01, 50.0).transfer(); } if (! my pitch) Melder_throw (U"Missing pitch manipulation."); if (! my pulses) Melder_throw (U"Missing pulses analysis."); autoPointProcess pulses = PitchTier_Point_to_PointProcess (my pitch.get(), my pulses.get(), MAX_T); autoSound train = PointProcess_to_Sound_pulseTrain (pulses.peek(), 1 / my lpc -> samplingPeriod, 0.7, 0.05, 30); train -> dx = my lpc -> samplingPeriod; // to be exact Sound_PointProcess_fillVoiceless (train.peek(), my pulses.get()); autoSound result = LPC_and_Sound_filter (my lpc, train.peek(), true); NUMdeemphasize_f (result -> z [1], result -> nx, result -> dx, 50.0); Vector_scale (result.peek(), 0.99); return result; } catch (MelderError) { Melder_throw (me, U": pitch LPC synthesis not performed."); } } autoSound Manipulation_to_Sound (Manipulation me, int method) { switch (method) { case Manipulation_OVERLAPADD: return synthesize_overlapAdd (me); case Manipulation_PULSES: return synthesize_pulses (me); case Manipulation_PULSES_HUM: return synthesize_pulses_hum (me); case Manipulation_PITCH: return synthesize_pitch (me); case Manipulation_PITCH_HUM: return synthesize_pitch_hum (me); case Manipulation_PULSES_PITCH: return synthesize_pulses_pitch (me); case Manipulation_PULSES_PITCH_HUM: return synthesize_pulses_pitch_hum (me); case Manipulation_OVERLAPADD_NODUR: return synthesize_overlapAdd_nodur (me); case Manipulation_PULSES_FORMANT: return 0; case Manipulation_PULSES_FORMANT_INTENSITY: return 0; case Manipulation_PULSES_LPC: return synthesize_pulses_lpc (me); case Manipulation_PULSES_LPC_INTENSITY: return 0; case Manipulation_PITCH_LPC: return synthesize_pitch_lpc (me); case Manipulation_PITCH_LPC_INTENSITY: return 0; default: return synthesize_overlapAdd (me); } } autoManipulation Manipulation_AnyTier_to_Manipulation (Manipulation me, AnyTier tier) { try { if (! my pitch) Melder_throw (U"Missing pitch manipulation."); autoManipulation result = Data_copy (me); result -> pitch = PitchTier_AnyTier_to_PitchTier (my pitch.get(), tier); return result; } catch (MelderError) { Melder_throw (me, U": not converted."); } } void Manipulation_writeToTextFileWithoutSound (Manipulation me, MelderFile file) { autoSound saved = my sound.move(); try { Data_writeToTextFile (me, file); my sound = saved.move(); } catch (MelderError) { my sound = saved.move(); Melder_throw (me, U": not saved to text file."); } } void Manipulation_writeToBinaryFileWithoutSound (Manipulation me, MelderFile file) { autoSound saved = my sound.move(); try { Data_writeToBinaryFile (me, file); my sound = saved.move(); } catch (MelderError) { my sound = saved.move(); Melder_throw (me, U": not saved to binary file."); } } /* End of file Manipulation.cpp */ praat-6.0.04/fon/Manipulation.h000066400000000000000000000065371261542461700163260ustar00rootroot00000000000000#ifndef _Manipulation_h_ #define _Manipulation_h_ /* Manipulation.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Sound.h" #include "PointProcess.h" #include "PitchTier.h" #include "DurationTier.h" #include "LPC.h" /* The following have to be included for compatibility. */ #include "IntensityTier.h" #include "Intensity.h" #include "FormantTier.h" #include "Formant.h" #include "Pitch.h" #include "Image.h" #include "Manipulation_def.h" oo_CLASS_CREATE (Manipulation, Function); /* How to create an Manipulation. */ autoManipulation Manipulation_create (double tmin, double tmax); void Manipulation_replaceOriginalSound (Manipulation me, Sound sound); void Manipulation_replacePulses (Manipulation me, PointProcess pulses); void Manipulation_replaceIntensityTier (Manipulation me, IntensityTier intensity); void Manipulation_replacePitchTier (Manipulation me, PitchTier pitch); void Manipulation_replaceDurationTier (Manipulation me, DurationTier duration); autoManipulation Sound_to_Manipulation (Sound me, double timeStep, double minimumPitch, double maximumPitch); autoManipulation Sound_Pitch_to_Manipulation (Sound sound, Pitch pitch); autoManipulation Sound_PointProcess_to_Manipulation (Sound sound, PointProcess point); autoManipulation Manipulation_AnyTier_to_Manipulation (Manipulation manip, AnyTier tier); /* Resynthesis. */ #define Manipulation_OVERLAPADD 1 #define Manipulation_PULSES 2 #define Manipulation_PULSES_HUM 3 #define Manipulation_PITCH 4 #define Manipulation_PITCH_HUM 5 #define Manipulation_PULSES_PITCH 6 #define Manipulation_PULSES_PITCH_HUM 7 #define Manipulation_OVERLAPADD_NODUR 8 #define Manipulation_PULSES_FORMANT 9 #define Manipulation_PULSES_FORMANT_INTENSITY 10 #define Manipulation_PULSES_LPC 11 #define Manipulation_PULSES_LPC_INTENSITY 12 #define Manipulation_PITCH_LPC 13 #define Manipulation_PITCH_LPC_INTENSITY 14 #define Manipulation_PITCH_LPC_INT_DUR 15 autoSound Sound_Point_Point_to_Sound (Sound me, PointProcess source, PointProcess target, double maxT); /*void Sound_Formant_Intensity_filter (Sound me, FormantTier formant, IntensityTier intensity);*/ autoSound Manipulation_to_Sound (Manipulation me, int method); int Manipulation_playPart (Manipulation me, double tmin, double tmax, int method); int Manipulation_play (Manipulation me, int method); void Manipulation_writeToTextFileWithoutSound (Manipulation me, MelderFile file); void Manipulation_writeToBinaryFileWithoutSound (Manipulation me, MelderFile file); /* The low-level synthesis routines. */ autoSound Sound_Point_Pitch_Duration_to_Sound (Sound me, PointProcess pulses, PitchTier pitch, DurationTier duration, double maxT); /* End of file Manipulation.h */ #endif praat-6.0.04/fon/ManipulationEditor.cpp000066400000000000000000001567131261542461700200320ustar00rootroot00000000000000/* ManipulationEditor.cpp * * Copyright (C) 1992-2011,2012,2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ManipulationEditor.h" #include "PitchTier_to_PointProcess.h" #include "Sound_to_PointProcess.h" #include "Sound_to_Pitch.h" #include "Pitch_to_PitchTier.h" #include "Pitch_to_PointProcess.h" #include "EditorM.h" #include "enums_getText.h" #include "ManipulationEditor_enums.h" #include "enums_getValue.h" #include "ManipulationEditor_enums.h" Thing_implement (ManipulationEditor, FunctionEditor, 0); #include "prefs_define.h" #include "ManipulationEditor_prefs.h" #include "prefs_install.h" #include "ManipulationEditor_prefs.h" #include "prefs_copyToInstance.h" #include "ManipulationEditor_prefs.h" /* * How to add a synthesis method (in an interruptable order): * 1. add an Manipulation_ #define in Manipulation.h; * 2. add a synthesize_ routine in Manipulation.cpp, and a reference to it in Manipulation_to_Sound; * 3. add a button in ManipulationEditor.h; * 4. add a cb_Synth_ callback. * 5. create the button in createMenus and update updateMenus; */ static const char32 *units_strings [] = { 0, U"Hz", U"st" }; static int prefs_synthesisMethod = Manipulation_OVERLAPADD; /* Remembered across editor creations, not across Praat sessions. */ /* BUG: 25 should be fmin */ #define YLIN(freq) (my p_pitch_units == kManipulationEditor_pitchUnits_HERTZ ? ((freq) < 25 ? 25 : (freq)) : NUMhertzToSemitones ((freq) < 25 ? 25 : (freq))) #define YLININV(freq) (my p_pitch_units == kManipulationEditor_pitchUnits_HERTZ ? (freq) : NUMsemitonesToHertz (freq)) static void updateMenus (ManipulationEditor me) { Melder_assert (my synthPulsesButton); GuiMenuItem_check (my synthPulsesButton, my synthesisMethod == Manipulation_PULSES); Melder_assert (my synthPulsesHumButton); GuiMenuItem_check (my synthPulsesHumButton, my synthesisMethod == Manipulation_PULSES_HUM); Melder_assert (my synthPulsesLpcButton); GuiMenuItem_check (my synthPulsesLpcButton, my synthesisMethod == Manipulation_PULSES_LPC); Melder_assert (my synthPitchButton); GuiMenuItem_check (my synthPitchButton, my synthesisMethod == Manipulation_PITCH); Melder_assert (my synthPitchHumButton); GuiMenuItem_check (my synthPitchHumButton, my synthesisMethod == Manipulation_PITCH_HUM); Melder_assert (my synthPulsesPitchButton); GuiMenuItem_check (my synthPulsesPitchButton, my synthesisMethod == Manipulation_PULSES_PITCH); Melder_assert (my synthPulsesPitchHumButton); GuiMenuItem_check (my synthPulsesPitchHumButton, my synthesisMethod == Manipulation_PULSES_PITCH_HUM); Melder_assert (my synthOverlapAddButton); GuiMenuItem_check (my synthOverlapAddButton, my synthesisMethod == Manipulation_OVERLAPADD); Melder_assert (my synthPitchLpcButton); GuiMenuItem_check (my synthPitchLpcButton, my synthesisMethod == Manipulation_PITCH_LPC); } /* * The "sound area" contains the original sound and the pulses. */ static bool getSoundArea (ManipulationEditor me, double *ymin, double *ymax) { Manipulation ana = (Manipulation) my data; *ymin = 0.66; *ymax = 1.00; return ana -> sound || ana -> pulses; } /* * The "pitch area" contains the grey pitch analysis based on the pulses, and the blue pitch tier. */ static bool getPitchArea (ManipulationEditor me, double *ymin, double *ymax) { Manipulation ana = (Manipulation) my data; *ymin = ana -> duration ? 0.16 : 0.00; *ymax = 0.65; return ana -> pulses || ana -> pitch; } static bool getDurationArea (ManipulationEditor me, double *ymin, double *ymax) { Manipulation ana = (Manipulation) my data; if (! ana -> duration) return false; *ymin = 0.00; *ymax = 0.15; return true; } /********** MENU COMMANDS **********/ /***** FILE MENU *****/ static void menu_cb_extractOriginalSound (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); Manipulation ana = (Manipulation) my data; if (! ana -> sound) return; autoSound publish = Data_copy (ana -> sound.get()); Editor_broadcastPublication (me, publish.transfer()); } static void menu_cb_extractPulses (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); Manipulation ana = (Manipulation) my data; if (! ana -> pulses) return; autoPointProcess publish = Data_copy (ana -> pulses.get()); Editor_broadcastPublication (me, publish.transfer()); } static void menu_cb_extractPitchTier (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); Manipulation ana = (Manipulation) my data; if (! ana -> pitch) return; autoPitchTier publish = Data_copy (ana -> pitch.get()); Editor_broadcastPublication (me, publish.transfer()); } static void menu_cb_extractDurationTier (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); Manipulation ana = (Manipulation) my data; if (! ana -> duration) return; autoDurationTier publish = Data_copy (ana -> duration.get()); Editor_broadcastPublication (me, publish.transfer()); } static void menu_cb_extractManipulatedSound (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); Manipulation ana = (Manipulation) my data; autoSound publish = Manipulation_to_Sound (ana, my synthesisMethod); Editor_broadcastPublication (me, publish.transfer()); } /***** EDIT MENU *****/ void structManipulationEditor :: v_saveData () { Manipulation ana = (Manipulation) our data; if (ana -> pulses) our previousPulses = Data_copy (ana -> pulses.get()); if (ana -> pitch) our previousPitch = Data_copy (ana -> pitch.get()); if (ana -> duration) our previousDuration = Data_copy (ana -> duration.get()); } void structManipulationEditor :: v_restoreData () { Manipulation ana = (Manipulation) our data; autoPointProcess dummy1 = ana -> pulses.move(); ana -> pulses = our previousPulses.move(); our previousPulses = dummy1.move(); autoPitchTier dummy2 = ana -> pitch.move(); ana -> pitch = our previousPitch.move(); our previousPitch = dummy2.move(); autoDurationTier dummy3 = ana -> duration.move(); ana -> duration = our previousDuration.move(); our previousDuration = dummy3.move(); } /***** PULSES MENU *****/ static void menu_cb_removePulses (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); Manipulation ana = (Manipulation) my data; if (! ana -> pulses) return; Editor_save (me, U"Remove pulse(s)"); if (my d_startSelection == my d_endSelection) PointProcess_removePointNear (ana -> pulses.get(), my d_startSelection); else PointProcess_removePointsBetween (ana -> pulses.get(), my d_startSelection, my d_endSelection); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_addPulseAtCursor (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); Manipulation ana = (Manipulation) my data; if (! ana -> pulses) return; Editor_save (me, U"Add pulse"); PointProcess_addPoint (ana -> pulses.get(), 0.5 * (my d_startSelection + my d_endSelection)); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_addPulseAt (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); EDITOR_FORM (U"Add pulse", 0) REAL (U"Position (s)", U"0.0") EDITOR_OK SET_REAL (U"Position", 0.5 * (my d_startSelection + my d_endSelection)) EDITOR_DO Manipulation ana = (Manipulation) my data; if (! ana -> pulses) return; Editor_save (me, U"Add pulse"); PointProcess_addPoint (ana -> pulses.get(), GET_REAL (U"Position")); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); EDITOR_END } /***** PITCH MENU *****/ static void menu_cb_removePitchPoints (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); Manipulation ana = (Manipulation) my data; if (! ana -> pitch) return; Editor_save (me, U"Remove pitch point(s)"); if (my d_startSelection == my d_endSelection) AnyTier_removePointNear (ana -> pitch.get(), my d_startSelection); else AnyTier_removePointsBetween (ana -> pitch.get(), my d_startSelection, my d_endSelection); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_addPitchPointAtCursor (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); Manipulation ana = (Manipulation) my data; if (! ana -> pitch) return; Editor_save (me, U"Add pitch point"); RealTier_addPoint (ana -> pitch.get(), 0.5 * (my d_startSelection + my d_endSelection), YLININV (my pitchTier.cursor)); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_addPitchPointAtSlice (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); Manipulation ana = (Manipulation) my data; PointProcess pulses = ana -> pulses.get(); if (! pulses) Melder_throw (U"There are no pulses."); if (! ana -> pitch) return; long ileft = PointProcess_getLowIndex (pulses, 0.5 * (my d_startSelection + my d_endSelection)), iright = ileft + 1, nt = pulses -> nt; double *t = pulses -> t; double f = my pitchTier.cursor; // default Editor_save (me, U"Add pitch point"); if (nt <= 1) { /* Ignore. */ } else if (ileft <= 0) { double tright = t [2] - t [1]; if (tright > 0.0 && tright <= 0.02) f = YLIN (1.0 / tright); } else if (iright > nt) { double tleft = t [nt] - t [nt - 1]; if (tleft > 0.0 && tleft <= 0.02) f = YLIN (1.0 / tleft); } else { /* Three-period median. */ double tmid = t [iright] - t [ileft], tleft = 0.0, tright = 0.0; if (ileft > 1) tleft = t [ileft] - t [ileft - 1]; if (iright < nt) tright = t [iright + 1] - t [iright]; if (tleft > 0.02) tleft = 0; if (tmid > 0.02) tmid = 0; if (tright > 0.02) tright = 0; /* Bubble-sort. */ if (tmid < tleft) { double dum = tmid; tmid = tleft; tleft = dum; } if (tright < tleft) { double dum = tright; tright = tleft; tleft = dum; } if (tright < tmid) { double dum = tright; tright = tmid; tmid = dum; } if (tleft != 0.0) f = YLIN (1 / tmid); // median of 3 else if (tmid != 0.0) f = YLIN (2 / (tmid + tright)); // median of 2 else if (tright != 0.0) f = YLIN (1 / tright); // median of 1 } RealTier_addPoint (ana -> pitch.get(), 0.5 * (my d_startSelection + my d_endSelection), YLININV (f)); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_addPitchPointAt (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); EDITOR_FORM (U"Add pitch point", 0) REAL (U"Time (s)", U"0.0") REAL (U"Frequency (Hz or st)", U"100.0") EDITOR_OK SET_REAL (U"Time", 0.5 * (my d_startSelection + my d_endSelection)) SET_REAL (U"Frequency", my pitchTier.cursor) EDITOR_DO Manipulation ana = (Manipulation) my data; if (! ana -> pitch) return; Editor_save (me, U"Add pitch point"); RealTier_addPoint (ana -> pitch.get(), GET_REAL (U"Time"), YLININV (GET_REAL (U"Frequency"))); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); EDITOR_END } static void menu_cb_stylizePitch (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); EDITOR_FORM (U"Stylize pitch", U"PitchTier: Stylize...") REAL (U"Frequency resolution", my default_pitch_stylize_frequencyResolution ()) RADIO (U"Units", my default_pitch_stylize_useSemitones () + 1) RADIOBUTTON (U"Hertz") RADIOBUTTON (U"semitones") EDITOR_OK SET_REAL (U"Frequency resolution", my p_pitch_stylize_frequencyResolution) SET_INTEGER (U"Units", my p_pitch_stylize_useSemitones + 1) EDITOR_DO Manipulation ana = (Manipulation) my data; if (! ana -> pitch) return; Editor_save (me, U"Stylize pitch"); PitchTier_stylize (ana -> pitch.get(), my pref_pitch_stylize_frequencyResolution () = my p_pitch_stylize_frequencyResolution = GET_REAL (U"Frequency resolution"), my pref_pitch_stylize_useSemitones () = my p_pitch_stylize_useSemitones = GET_INTEGER (U"Units") - 1); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); EDITOR_END } static void menu_cb_stylizePitch_2st (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); Manipulation ana = (Manipulation) my data; if (! ana -> pitch) return; Editor_save (me, U"Stylize pitch"); PitchTier_stylize (ana -> pitch.get(), 2.0, true); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_interpolateQuadratically (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); EDITOR_FORM (U"Interpolate quadratically", 0) NATURAL (U"Number of points per parabola", my default_pitch_interpolateQuadratically_numberOfPointsPerParabola ()) EDITOR_OK SET_INTEGER (U"Number of points per parabola", my p_pitch_interpolateQuadratically_numberOfPointsPerParabola) EDITOR_DO Manipulation ana = (Manipulation) my data; if (! ana -> pitch) return; Editor_save (me, U"Interpolate quadratically"); RealTier_interpolateQuadratically (ana -> pitch.get(), my pref_pitch_interpolateQuadratically_numberOfPointsPerParabola () = my p_pitch_interpolateQuadratically_numberOfPointsPerParabola = GET_INTEGER (U"Number of points per parabola"), my p_pitch_units == kManipulationEditor_pitchUnits_SEMITONES); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); EDITOR_END } static void menu_cb_interpolateQuadratically_4pts (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); Manipulation ana = (Manipulation) my data; if (! ana -> pitch) return; Editor_save (me, U"Interpolate quadratically"); RealTier_interpolateQuadratically (ana -> pitch.get(), 4, my p_pitch_units == kManipulationEditor_pitchUnits_SEMITONES); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_shiftPitchFrequencies (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); EDITOR_FORM (U"Shift pitch frequencies", 0) REAL (U"Frequency shift", U"-20.0") OPTIONMENU (U"Unit", 1) OPTION (U"Hertz") OPTION (U"mel") OPTION (U"logHertz") OPTION (U"semitones") OPTION (U"ERB") EDITOR_OK EDITOR_DO Manipulation ana = (Manipulation) my data; int unit = GET_INTEGER (U"Unit"); unit = unit == 1 ? kPitch_unit_HERTZ : unit == 2 ? kPitch_unit_MEL : unit == 3 ? kPitch_unit_LOG_HERTZ : unit == 4 ? kPitch_unit_SEMITONES_1 : kPitch_unit_ERB; if (! ana -> pitch) return; Editor_save (me, U"Shift pitch frequencies"); try { PitchTier_shiftFrequencies (ana -> pitch.get(), my d_startSelection, my d_endSelection, GET_REAL (U"Frequency shift"), unit); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } catch (MelderError) { // the PitchTier may have partially changed FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); throw; } EDITOR_END } static void menu_cb_multiplyPitchFrequencies (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); EDITOR_FORM (U"Multiply pitch frequencies", 0) POSITIVE (U"Factor", U"1.2") LABEL (U"", U"The multiplication is always done in hertz.") EDITOR_OK EDITOR_DO Manipulation ana = (Manipulation) my data; if (! ana -> pitch) return; Editor_save (me, U"Multiply pitch frequencies"); PitchTier_multiplyFrequencies (ana -> pitch.get(), my d_startSelection, my d_endSelection, GET_REAL (U"Factor")); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); EDITOR_END } static void menu_cb_setPitchRange (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); EDITOR_FORM (U"Set pitch range", 0) /* BUG: should include Minimum */ REAL (U"Maximum (Hz or st)", my default_pitch_maximum ()) EDITOR_OK SET_REAL (U"Maximum", my p_pitch_maximum) EDITOR_DO double maximum = GET_REAL (U"Maximum"); if (maximum <= my pitchTier.minPeriodic) Melder_throw (U"Maximum pitch must be greater than ", Melder_half (my pitchTier.minPeriodic), U" ", units_strings [my p_pitch_units], U"."); my pref_pitch_maximum () = my p_pitch_maximum = maximum; FunctionEditor_redraw (me); EDITOR_END } static void menu_cb_setPitchUnits (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); EDITOR_FORM (U"Set pitch units", 0) RADIO_ENUM (U"Pitch units", kManipulationEditor_pitchUnits, my default_pitch_units ()) EDITOR_OK SET_ENUM (U"Pitch units", kManipulationEditor_pitchUnits, my p_pitch_units) EDITOR_DO enum kManipulationEditor_pitchUnits oldPitchUnits = my p_pitch_units; my pref_pitch_units () = my p_pitch_units = GET_ENUM (kManipulationEditor_pitchUnits, U"Pitch units"); if (my p_pitch_units == oldPitchUnits) return; if (my p_pitch_units == kManipulationEditor_pitchUnits_HERTZ) { my p_pitch_minimum = 25.0; my pitchTier.minPeriodic = 50.0; my pref_pitch_maximum () = my p_pitch_maximum = NUMsemitonesToHertz (my p_pitch_maximum); my pitchTier.cursor = NUMsemitonesToHertz (my pitchTier.cursor); } else { my p_pitch_minimum = -24.0; my pitchTier.minPeriodic = -12.0; my pref_pitch_maximum () = my p_pitch_maximum = NUMhertzToSemitones (my p_pitch_maximum); my pitchTier.cursor = NUMhertzToSemitones (my pitchTier.cursor); } FunctionEditor_redraw (me); EDITOR_END } /***** DURATION MENU *****/ static void menu_cb_setDurationRange (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); EDITOR_FORM (U"Set duration range", 0) REAL (U"Minimum", my default_duration_minimum ()) REAL (U"Maximum", my default_duration_maximum ()) EDITOR_OK SET_REAL (U"Minimum", my p_duration_minimum) SET_REAL (U"Maximum", my p_duration_maximum) EDITOR_DO Manipulation ana = (Manipulation) my data; double minimum = GET_REAL (U"Minimum"), maximum = GET_REAL (U"Maximum"); double minimumValue = ana -> duration ? RealTier_getMinimumValue (ana -> duration.get()) : NUMundefined; double maximumValue = ana -> duration ? RealTier_getMaximumValue (ana -> duration.get()) : NUMundefined; if (minimum > 1) Melder_throw (U"Minimum relative duration must not be greater than 1."); if (maximum < 1) Melder_throw (U"Maximum relative duration must not be less than 1."); if (minimum >= maximum) Melder_throw (U"Maximum relative duration must be greater than minimum."); if (NUMdefined (minimumValue) && minimum > minimumValue) Melder_throw (U"Minimum relative duration must not be greater than the minimum value present, " U"which is ", Melder_half (minimumValue), U"."); if (NUMdefined (maximumValue) && maximum < maximumValue) Melder_throw (U"Maximum relative duration must not be less than the maximum value present, " U"which is ", Melder_half (maximumValue), U"."); my pref_duration_minimum () = my p_duration_minimum = minimum; my pref_duration_maximum () = my p_duration_maximum = maximum; FunctionEditor_redraw (me); EDITOR_END } static void menu_cb_setDraggingStrategy (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); EDITOR_FORM (U"Set dragging strategy", U"ManipulationEditor") RADIO_ENUM (U"Dragging strategy", kManipulationEditor_draggingStrategy, my default_pitch_draggingStrategy ()) EDITOR_OK SET_INTEGER (U"Dragging strategy", my p_pitch_draggingStrategy) EDITOR_DO my pref_pitch_draggingStrategy () = my p_pitch_draggingStrategy = GET_ENUM (kManipulationEditor_draggingStrategy, U"Dragging strategy"); EDITOR_END } static void menu_cb_removeDurationPoints (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); Manipulation ana = (Manipulation) my data; if (! ana -> duration) return; Editor_save (me, U"Remove duration point(s)"); if (my d_startSelection == my d_endSelection) AnyTier_removePointNear (ana -> duration.get(), 0.5 * (my d_startSelection + my d_endSelection)); else AnyTier_removePointsBetween (ana -> duration.get(), my d_startSelection, my d_endSelection); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_addDurationPointAtCursor (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); Manipulation ana = (Manipulation) my data; if (! ana -> duration) return; Editor_save (me, U"Add duration point"); RealTier_addPoint (ana -> duration.get(), 0.5 * (my d_startSelection + my d_endSelection), my duration.cursor); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_addDurationPointAt (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); EDITOR_FORM (U"Add duration point", 0) REAL (U"Time (s)", U"0.0"); REAL (U"Relative duration", U"1.0"); EDITOR_OK SET_REAL (U"Time", 0.5 * (my d_startSelection + my d_endSelection)) EDITOR_DO Manipulation ana = (Manipulation) my data; if (! ana -> duration) return; Editor_save (me, U"Add duration point"); RealTier_addPoint (ana -> duration.get(), GET_REAL (U"Time"), GET_REAL (U"Relative duration")); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); EDITOR_END } static void menu_cb_newDuration (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); Manipulation ana = (Manipulation) my data; Editor_save (me, U"New duration"); ana -> duration = DurationTier_create (ana -> xmin, ana -> xmax); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_forgetDuration (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); Manipulation ana = (Manipulation) my data; ana -> duration = nullptr; FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_ManipulationEditorHelp (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); Melder_help (U"ManipulationEditor"); } static void menu_cb_ManipulationHelp (EDITOR_ARGS) { EDITOR_IAM (ManipulationEditor); Melder_help (U"Manipulation"); } #define menu_cb_Synth_common(menu_cb,meth) \ static void menu_cb (EDITOR_ARGS) { \ EDITOR_IAM (ManipulationEditor); \ prefs_synthesisMethod = my synthesisMethod = meth; \ updateMenus (me); \ } menu_cb_Synth_common (menu_cb_Synth_Pulses, Manipulation_PULSES) menu_cb_Synth_common (menu_cb_Synth_Pulses_hum, Manipulation_PULSES_HUM) menu_cb_Synth_common (menu_cb_Synth_Pulses_Lpc, Manipulation_PULSES_LPC) menu_cb_Synth_common (menu_cb_Synth_Pitch, Manipulation_PITCH) menu_cb_Synth_common (menu_cb_Synth_Pitch_hum, Manipulation_PITCH_HUM) menu_cb_Synth_common (menu_cb_Synth_Pulses_Pitch, Manipulation_PULSES_PITCH) menu_cb_Synth_common (menu_cb_Synth_Pulses_Pitch_hum, Manipulation_PULSES_PITCH_HUM) menu_cb_Synth_common (menu_cb_Synth_OverlapAdd_nodur, Manipulation_OVERLAPADD_NODUR) menu_cb_Synth_common (menu_cb_Synth_OverlapAdd, Manipulation_OVERLAPADD) menu_cb_Synth_common (menu_cb_Synth_Pitch_Lpc, Manipulation_PITCH_LPC) void structManipulationEditor :: v_createMenus () { ManipulationEditor_Parent :: v_createMenus (); Editor_addCommand (this, U"File", U"Extract original sound", 0, menu_cb_extractOriginalSound); Editor_addCommand (this, U"File", U"Extract pulses", 0, menu_cb_extractPulses); Editor_addCommand (this, U"File", U"Extract pitch tier", 0, menu_cb_extractPitchTier); Editor_addCommand (this, U"File", U"Extract duration tier", 0, menu_cb_extractDurationTier); Editor_addCommand (this, U"File", U"Publish resynthesis", 0, menu_cb_extractManipulatedSound); Editor_addCommand (this, U"File", U"-- close --", 0, nullptr); Editor_addMenu (this, U"Pulse", 0); Editor_addCommand (this, U"Pulse", U"Add pulse at cursor", 'P', menu_cb_addPulseAtCursor); Editor_addCommand (this, U"Pulse", U"Add pulse at...", 0, menu_cb_addPulseAt); Editor_addCommand (this, U"Pulse", U"-- remove pulses --", 0, nullptr); Editor_addCommand (this, U"Pulse", U"Remove pulse(s)", GuiMenu_OPTION + 'P', menu_cb_removePulses); Editor_addMenu (this, U"Pitch", 0); Editor_addCommand (this, U"Pitch", U"Add pitch point at cursor", 'T', menu_cb_addPitchPointAtCursor); Editor_addCommand (this, U"Pitch", U"Add pitch point at time slice", 0, menu_cb_addPitchPointAtSlice); Editor_addCommand (this, U"Pitch", U"Add pitch point at...", 0, menu_cb_addPitchPointAt); Editor_addCommand (this, U"Pitch", U"-- remove pitch --", 0, nullptr); Editor_addCommand (this, U"Pitch", U"Remove pitch point(s)", GuiMenu_OPTION + 'T', menu_cb_removePitchPoints); Editor_addCommand (this, U"Pitch", U"-- pitch prefs --", 0, nullptr); Editor_addCommand (this, U"Pitch", U"Set pitch range...", 0, menu_cb_setPitchRange); Editor_addCommand (this, U"Pitch", U"Set pitch units...", 0, menu_cb_setPitchUnits); Editor_addCommand (this, U"Pitch", U"Set pitch dragging strategy...", 0, menu_cb_setDraggingStrategy); Editor_addCommand (this, U"Pitch", U"-- modify pitch --", 0, nullptr); Editor_addCommand (this, U"Pitch", U"Shift pitch frequencies...", 0, menu_cb_shiftPitchFrequencies); Editor_addCommand (this, U"Pitch", U"Multiply pitch frequencies...", 0, menu_cb_multiplyPitchFrequencies); Editor_addCommand (this, U"Pitch", U"All:", GuiMenu_INSENSITIVE, menu_cb_stylizePitch); Editor_addCommand (this, U"Pitch", U"Stylize pitch...", 0, menu_cb_stylizePitch); Editor_addCommand (this, U"Pitch", U"Stylize pitch (2 st)", '2', menu_cb_stylizePitch_2st); Editor_addCommand (this, U"Pitch", U"Interpolate quadratically...", 0, menu_cb_interpolateQuadratically); Editor_addCommand (this, U"Pitch", U"Interpolate quadratically (4 pts)", '4', menu_cb_interpolateQuadratically_4pts); Editor_addMenu (this, U"Dur", 0); Editor_addCommand (this, U"Dur", U"Add duration point at cursor", 'D', menu_cb_addDurationPointAtCursor); Editor_addCommand (this, U"Dur", U"Add duration point at...", 0, menu_cb_addDurationPointAt); Editor_addCommand (this, U"Dur", U"-- remove duration --", 0, nullptr); Editor_addCommand (this, U"Dur", U"Remove duration point(s)", GuiMenu_OPTION + 'D', menu_cb_removeDurationPoints); Editor_addCommand (this, U"Dur", U"-- duration prefs --", 0, nullptr); Editor_addCommand (this, U"Dur", U"Set duration range...", 0, menu_cb_setDurationRange); Editor_addCommand (this, U"Dur", U"-- refresh duration --", 0, nullptr); Editor_addCommand (this, U"Dur", U"New duration", 0, menu_cb_newDuration); Editor_addCommand (this, U"Dur", U"Forget duration", 0, menu_cb_forgetDuration); Editor_addMenu (this, U"Synth", 0); our synthPulsesButton = Editor_addCommand (this, U"Synth", U"Pulses --", GuiMenu_RADIO_FIRST, menu_cb_Synth_Pulses); our synthPulsesHumButton = Editor_addCommand (this, U"Synth", U"Pulses (hum) --", GuiMenu_RADIO_NEXT, menu_cb_Synth_Pulses_hum); our synthPulsesLpcButton = Editor_addCommand (this, U"Synth", U"Pulses & LPC -- (\"LPC resynthesis\")", GuiMenu_RADIO_NEXT, menu_cb_Synth_Pulses_Lpc); Editor_addCommand (this, U"Synth", U"-- pitch resynth --", 0, nullptr); our synthPitchButton = Editor_addCommand (this, U"Synth", U" -- Pitch", GuiMenu_RADIO_NEXT, menu_cb_Synth_Pitch); our synthPitchHumButton = Editor_addCommand (this, U"Synth", U" -- Pitch (hum)", GuiMenu_RADIO_NEXT, menu_cb_Synth_Pitch_hum); our synthPulsesPitchButton = Editor_addCommand (this, U"Synth", U"Pulses -- Pitch", GuiMenu_RADIO_NEXT, menu_cb_Synth_Pulses_Pitch); our synthPulsesPitchHumButton = Editor_addCommand (this, U"Synth", U"Pulses -- Pitch (hum)", GuiMenu_RADIO_NEXT, menu_cb_Synth_Pulses_Pitch_hum); Editor_addCommand (this, U"Synth", U"-- full resynth --", 0, nullptr); our synthOverlapAddButton = Editor_addCommand (this, U"Synth", U"Sound & Pulses -- Pitch & Duration (\"Overlap-add manipulation\")", GuiMenu_RADIO_NEXT | GuiMenu_TOGGLE_ON, menu_cb_Synth_OverlapAdd); our synthPitchLpcButton = Editor_addCommand (this, U"Synth", U"LPC -- Pitch (\"LPC pitch manipulation\")", GuiMenu_RADIO_NEXT, menu_cb_Synth_Pitch_Lpc); } void structManipulationEditor :: v_createHelpMenuItems (EditorMenu menu) { ManipulationEditor_Parent :: v_createHelpMenuItems (menu); EditorMenu_addCommand (menu, U"ManipulationEditor help", '?', menu_cb_ManipulationEditorHelp); EditorMenu_addCommand (menu, U"Manipulation help", 0, menu_cb_ManipulationHelp); } /********** DRAWING AREA **********/ static void drawSoundArea (ManipulationEditor me, double ymin, double ymax) { Manipulation ana = (Manipulation) my data; Sound sound = ana -> sound.get(); PointProcess pulses = ana -> pulses.get(); long first, last, i; Graphics_Viewport viewport = Graphics_insetViewport (my d_graphics, 0, 1, ymin, ymax); Graphics_setWindow (my d_graphics, 0, 1, 0, 1); Graphics_setColour (my d_graphics, Graphics_WHITE); Graphics_fillRectangle (my d_graphics, 0, 1, 0, 1); Graphics_setColour (my d_graphics, Graphics_BLACK); Graphics_rectangle (my d_graphics, 0, 1, 0, 1); Graphics_setTextAlignment (my d_graphics, Graphics_RIGHT, Graphics_TOP); Graphics_setFont (my d_graphics, kGraphics_font_TIMES); Graphics_text (my d_graphics, 1, 1, U"%%Sound"); Graphics_setColour (my d_graphics, Graphics_BLUE); Graphics_text (my d_graphics, 1, 1 - Graphics_dyMMtoWC (my d_graphics, 3), U"%%Pulses"); Graphics_setFont (my d_graphics, kGraphics_font_HELVETICA); /* * Draw blue pulses. */ if (pulses) { Graphics_setWindow (my d_graphics, my d_startWindow, my d_endWindow, 0.0, 1.0); Graphics_setColour (my d_graphics, Graphics_BLUE); for (i = 1; i <= pulses -> nt; i ++) { double t = pulses -> t [i]; if (t >= my d_startWindow && t <= my d_endWindow) Graphics_line (my d_graphics, t, 0.05, t, 0.95); } } /* * Draw sound. */ if (sound && Sampled_getWindowSamples (sound, my d_startWindow, my d_endWindow, & first, & last) > 1) { double minimum, maximum, scaleMin, scaleMax; Matrix_getWindowExtrema (sound, first, last, 1, 1, & minimum, & maximum); if (minimum == maximum) minimum = -0.5, maximum = +0.5; /* * Scaling. */ scaleMin = 0.83 * minimum + 0.17 * my soundmin; scaleMax = 0.83 * maximum + 0.17 * my soundmax; Graphics_setWindow (my d_graphics, my d_startWindow, my d_endWindow, scaleMin, scaleMax); FunctionEditor_drawRangeMark (me, scaleMin, Melder_float (Melder_half (scaleMin)), U"", Graphics_BOTTOM); FunctionEditor_drawRangeMark (me, scaleMax, Melder_float (Melder_half (scaleMax)), U"", Graphics_TOP); /* * Draw dotted zero line. */ if (minimum < 0.0 && maximum > 0.0) { Graphics_setColour (my d_graphics, Graphics_CYAN); Graphics_setLineType (my d_graphics, Graphics_DOTTED); Graphics_line (my d_graphics, my d_startWindow, 0.0, my d_endWindow, 0.0); Graphics_setLineType (my d_graphics, Graphics_DRAWN); } /* * Draw samples. */ Graphics_setColour (my d_graphics, Graphics_BLACK); Graphics_function (my d_graphics, sound -> z [1], first, last, Sampled_indexToX (sound, first), Sampled_indexToX (sound, last)); } Graphics_resetViewport (my d_graphics, viewport); } static void drawPitchArea (ManipulationEditor me, double ymin, double ymax) { Manipulation ana = (Manipulation) my data; PointProcess pulses = ana -> pulses.get(); PitchTier pitch = ana -> pitch.get(); long ifirstSelected, ilastSelected, n = pitch ? pitch -> points -> size : 0, imin, imax, i; int cursorVisible = my d_startSelection == my d_endSelection && my d_startSelection >= my d_startWindow && my d_startSelection <= my d_endWindow; double minimumFrequency = YLIN (50); int rangePrecisions [] = { 0, 1, 2 }; const char32 *rangeUnits [] = { U"", U" Hz", U" st" }; /* * Pitch contours. */ Graphics_Viewport viewport = Graphics_insetViewport (my d_graphics, 0, 1, ymin, ymax); Graphics_setWindow (my d_graphics, 0, 1, 0, 1); Graphics_setColour (my d_graphics, Graphics_WHITE); Graphics_fillRectangle (my d_graphics, 0, 1, 0, 1); Graphics_setColour (my d_graphics, Graphics_BLACK); Graphics_rectangle (my d_graphics, 0, 1, 0, 1); Graphics_setColour (my d_graphics, Graphics_GREEN); Graphics_setFont (my d_graphics, kGraphics_font_TIMES); Graphics_setTextAlignment (my d_graphics, Graphics_RIGHT, Graphics_TOP); Graphics_text (my d_graphics, 1, 1, U"%%Pitch manip"); Graphics_setGrey (my d_graphics, 0.7); Graphics_text (my d_graphics, 1, 1 - Graphics_dyMMtoWC (my d_graphics, 3), U"%%Pitch from pulses"); Graphics_setFont (my d_graphics, kGraphics_font_HELVETICA); Graphics_setWindow (my d_graphics, my d_startWindow, my d_endWindow, my p_pitch_minimum, my p_pitch_maximum); /* * Draw pitch contour based on pulses. */ Graphics_setGrey (my d_graphics, 0.7); if (pulses) for (i = 1; i < pulses -> nt; i ++) { double tleft = pulses -> t [i], tright = pulses -> t [i + 1], t = 0.5 * (tleft + tright); if (t >= my d_startWindow && t <= my d_endWindow) { if (tleft != tright) { double f = YLIN (1 / (tright - tleft)); if (f >= my pitchTier.minPeriodic && f <= my p_pitch_maximum) { Graphics_fillCircle_mm (my d_graphics, t, f, 1); } } } } Graphics_setGrey (my d_graphics, 0.0); FunctionEditor_drawGridLine (me, minimumFrequency); FunctionEditor_drawRangeMark (me, my p_pitch_maximum, Melder_fixed (my p_pitch_maximum, rangePrecisions [my p_pitch_units]), rangeUnits [my p_pitch_units], Graphics_TOP); FunctionEditor_drawRangeMark (me, my p_pitch_minimum, Melder_fixed (my p_pitch_minimum, rangePrecisions [my p_pitch_units]), rangeUnits [my p_pitch_units], Graphics_BOTTOM); if (my d_startSelection == my d_endSelection && my pitchTier.cursor >= my p_pitch_minimum && my pitchTier.cursor <= my p_pitch_maximum) FunctionEditor_drawHorizontalHair (me, my pitchTier.cursor, Melder_fixed (my pitchTier.cursor, rangePrecisions [my p_pitch_units]), rangeUnits [my p_pitch_units]); if (cursorVisible && n > 0) { double y = YLIN (RealTier_getValueAtTime (pitch, my d_startSelection)); FunctionEditor_insertCursorFunctionValue (me, y, Melder_fixed (y, rangePrecisions [my p_pitch_units]), rangeUnits [my p_pitch_units], my p_pitch_minimum, my p_pitch_maximum); } if (pitch) { ifirstSelected = AnyTier_timeToHighIndex (pitch, my d_startSelection); ilastSelected = AnyTier_timeToLowIndex (pitch, my d_endSelection); imin = AnyTier_timeToHighIndex (pitch, my d_startWindow); imax = AnyTier_timeToLowIndex (pitch, my d_endWindow); } Graphics_setLineWidth (my d_graphics, 2); if (n == 0) { Graphics_setTextAlignment (my d_graphics, Graphics_CENTRE, Graphics_HALF); Graphics_setColour (my d_graphics, Graphics_BLACK); Graphics_text (my d_graphics, 0.5 * (my d_startWindow + my d_endWindow), 0.5 * (my p_pitch_minimum + my p_pitch_maximum), U"(no pitch points)"); } else if (imax < imin) { double fleft = YLIN (RealTier_getValueAtTime (pitch, my d_startWindow)); double fright = YLIN (RealTier_getValueAtTime (pitch, my d_endWindow)); Graphics_setColour (my d_graphics, Graphics_GREEN); Graphics_line (my d_graphics, my d_startWindow, fleft, my d_endWindow, fright); } else { for (i = imin; i <= imax; i ++) { RealPoint point = (RealPoint) pitch -> points -> item [i]; double t = point -> number, f = YLIN (point -> value); Graphics_setColour (my d_graphics, Graphics_GREEN); if (i == 1) Graphics_line (my d_graphics, my d_startWindow, f, t, f); else if (i == imin) Graphics_line (my d_graphics, t, f, my d_startWindow, YLIN (RealTier_getValueAtTime (pitch, my d_startWindow))); if (i == n) Graphics_line (my d_graphics, t, f, my d_endWindow, f); else if (i == imax) Graphics_line (my d_graphics, t, f, my d_endWindow, YLIN (RealTier_getValueAtTime (pitch, my d_endWindow))); else { RealPoint pointRight = (RealPoint) pitch -> points -> item [i + 1]; Graphics_line (my d_graphics, t, f, pointRight -> number, YLIN (pointRight -> value)); } } for (i = imin; i <= imax; i ++) { RealPoint point = (RealPoint) pitch -> points -> item [i]; double t = point -> number, f = YLIN (point -> value); if (i >= ifirstSelected && i <= ilastSelected) Graphics_setColour (my d_graphics, Graphics_RED); else Graphics_setColour (my d_graphics, Graphics_GREEN); Graphics_fillCircle_mm (my d_graphics, t, f, 3); } } Graphics_setLineWidth (my d_graphics, 1); Graphics_setColour (my d_graphics, Graphics_BLACK); Graphics_resetViewport (my d_graphics, viewport); } static void drawDurationArea (ManipulationEditor me, double ymin, double ymax) { Manipulation ana = (Manipulation) my data; DurationTier duration = ana -> duration.get(); long ifirstSelected, ilastSelected, n = duration ? duration -> points -> size : 0, imin, imax, i; int cursorVisible = my d_startSelection == my d_endSelection && my d_startSelection >= my d_startWindow && my d_startSelection <= my d_endWindow; /* * Duration contours. */ Graphics_Viewport viewport = Graphics_insetViewport (my d_graphics, 0, 1, ymin, ymax); Graphics_setWindow (my d_graphics, 0, 1, 0, 1); Graphics_setColour (my d_graphics, Graphics_WHITE); Graphics_fillRectangle (my d_graphics, 0, 1, 0, 1); Graphics_setColour (my d_graphics, Graphics_BLACK); Graphics_rectangle (my d_graphics, 0, 1, 0, 1); Graphics_setColour (my d_graphics, Graphics_GREEN); Graphics_setFont (my d_graphics, kGraphics_font_TIMES); Graphics_setTextAlignment (my d_graphics, Graphics_RIGHT, Graphics_TOP); Graphics_text (my d_graphics, 1, 1, U"%%Duration manip"); Graphics_setFont (my d_graphics, kGraphics_font_HELVETICA); Graphics_setWindow (my d_graphics, my d_startWindow, my d_endWindow, my p_duration_minimum, my p_duration_maximum); FunctionEditor_drawGridLine (me, 1.0); FunctionEditor_drawRangeMark (me, my p_duration_maximum, Melder_fixed (my p_duration_maximum, 3), U"", Graphics_TOP); FunctionEditor_drawRangeMark (me, my p_duration_minimum, Melder_fixed (my p_duration_minimum, 3), U"", Graphics_BOTTOM); if (my d_startSelection == my d_endSelection && my duration.cursor >= my p_duration_minimum && my duration.cursor <= my p_duration_maximum) FunctionEditor_drawHorizontalHair (me, my duration.cursor, Melder_fixed (my duration.cursor, 3), U""); if (cursorVisible && n > 0) { double y = RealTier_getValueAtTime (duration, my d_startSelection); FunctionEditor_insertCursorFunctionValue (me, y, Melder_fixed (y, 3), U"", my p_duration_minimum, my p_duration_maximum); } /* * Draw duration tier. */ if (duration) { ifirstSelected = AnyTier_timeToHighIndex (duration, my d_startSelection); ilastSelected = AnyTier_timeToLowIndex (duration, my d_endSelection); imin = AnyTier_timeToHighIndex (duration, my d_startWindow); imax = AnyTier_timeToLowIndex (duration, my d_endWindow); } Graphics_setLineWidth (my d_graphics, 2); if (n == 0) { Graphics_setColour (my d_graphics, Graphics_BLACK); Graphics_setTextAlignment (my d_graphics, Graphics_CENTRE, Graphics_HALF); Graphics_text (my d_graphics, 0.5 * (my d_startWindow + my d_endWindow), 0.5 * (my p_duration_minimum + my p_duration_maximum), U"(no duration points)"); } else if (imax < imin) { double fleft = RealTier_getValueAtTime (duration, my d_startWindow); double fright = RealTier_getValueAtTime (duration, my d_endWindow); Graphics_setColour (my d_graphics, Graphics_GREEN); Graphics_line (my d_graphics, my d_startWindow, fleft, my d_endWindow, fright); } else { for (i = imin; i <= imax; i ++) { RealPoint point = (RealPoint) duration -> points -> item [i]; double t = point -> number, dur = point -> value; Graphics_setColour (my d_graphics, Graphics_GREEN); if (i == 1) Graphics_line (my d_graphics, my d_startWindow, dur, t, dur); else if (i == imin) Graphics_line (my d_graphics, t, dur, my d_startWindow, RealTier_getValueAtTime (duration, my d_startWindow)); if (i == n) Graphics_line (my d_graphics, t, dur, my d_endWindow, dur); else if (i == imax) Graphics_line (my d_graphics, t, dur, my d_endWindow, RealTier_getValueAtTime (duration, my d_endWindow)); else { RealPoint pointRight = (RealPoint) duration -> points -> item [i + 1]; Graphics_line (my d_graphics, t, dur, pointRight -> number, pointRight -> value); } } for (i = imin; i <= imax; i ++) { RealPoint point = (RealPoint) duration -> points -> item [i]; double t = point -> number, dur = point -> value; if (i >= ifirstSelected && i <= ilastSelected) Graphics_setColour (my d_graphics, Graphics_RED); else Graphics_setColour (my d_graphics, Graphics_GREEN); Graphics_fillCircle_mm (my d_graphics, t, dur, 3); } } Graphics_setLineWidth (my d_graphics, 1); Graphics_setColour (my d_graphics, Graphics_BLACK); Graphics_resetViewport (my d_graphics, viewport); } void structManipulationEditor :: v_draw () { double ysoundmin, ysoundmax; double ypitchmin, ypitchmax, ydurationmin, ydurationmax; int hasSoundArea = getSoundArea (this, & ysoundmin, & ysoundmax); int hasPitchArea = getPitchArea (this, & ypitchmin, & ypitchmax); int hasDurationArea = getDurationArea (this, & ydurationmin, & ydurationmax); if (hasSoundArea) drawSoundArea (this, ysoundmin, ysoundmax); if (hasPitchArea) drawPitchArea (this, ypitchmin, ypitchmax); if (hasDurationArea) drawDurationArea (this, ydurationmin, ydurationmax); Graphics_setWindow (our d_graphics, 0.0, 1.0, 0.0, 1.0); Graphics_setGrey (our d_graphics, 0.85); Graphics_fillRectangle (our d_graphics, -0.001, 1.001, ypitchmax, ysoundmin); Graphics_setGrey (our d_graphics, 0.00); Graphics_line (our d_graphics, 0, ysoundmin, 1, ysoundmin); Graphics_line (our d_graphics, 0, ypitchmax, 1, ypitchmax); if (hasDurationArea) { Graphics_setGrey (our d_graphics, 0.85); Graphics_fillRectangle (our d_graphics, -0.001, 1.001, ydurationmax, ypitchmin); Graphics_setGrey (our d_graphics, 0.00); Graphics_line (our d_graphics, 0, ypitchmin, 1, ypitchmin); Graphics_line (our d_graphics, 0, ydurationmax, 1, ydurationmax); } updateMenus (this); } static void drawWhileDragging (ManipulationEditor me, double xWC, double yWC, long first, long last, double dt, double df) { Manipulation ana = (Manipulation) my data; PitchTier pitch = ana -> pitch.get(); (void) xWC; (void) yWC; /* * Draw all selected pitch points as magenta empty circles, if inside the window. */ for (long i = first; i <= last; i ++) { RealPoint point = pitch -> point (i); double t = point -> number + dt, f = YLIN (point -> value) + df; if (t >= my d_startWindow && t <= my d_endWindow) Graphics_circle_mm (my d_graphics, t, f < my pitchTier.minPeriodic ? my pitchTier.minPeriodic : f > my p_pitch_maximum ? my p_pitch_maximum : f, 3); } if (last == first) { /* * Draw a crosshair with time and frequency. */ RealPoint point = pitch -> point (first); double t = point -> number + dt, fWC = YLIN (point -> value) + df; Graphics_line (my d_graphics, t, my p_pitch_minimum, t, my p_pitch_maximum - Graphics_dyMMtoWC (my d_graphics, 4.0)); Graphics_setTextAlignment (my d_graphics, Graphics_CENTRE, Graphics_TOP); Graphics_text (my d_graphics, t, my p_pitch_maximum, Melder_fixed (t, 6)); Graphics_line (my d_graphics, my d_startWindow, fWC, my d_endWindow, fWC); Graphics_setTextAlignment (my d_graphics, Graphics_LEFT, Graphics_BOTTOM); Graphics_text (my d_graphics, my d_startWindow, fWC, Melder_fixed (fWC, 5)); } } static int clickPitch (ManipulationEditor me, double xWC, double yWC, bool shiftKeyPressed) { Manipulation ana = (Manipulation) my data; PitchTier pitch = ana -> pitch.get(); long inearestPoint, ifirstSelected, ilastSelected, i; RealPoint nearestPoint; double dt = 0, df = 0; int draggingSelection, dragHorizontal, dragVertical; my pitchTier.cursor = my p_pitch_minimum + yWC * (my p_pitch_maximum - my p_pitch_minimum); if (! pitch) { Graphics_resetViewport (my d_graphics, my inset); return my ManipulationEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed); } Graphics_setWindow (my d_graphics, my d_startWindow, my d_endWindow, my p_pitch_minimum, my p_pitch_maximum); yWC = my pitchTier.cursor; /* * Clicked on a pitch point? */ inearestPoint = AnyTier_timeToNearestIndex (pitch, xWC); if (inearestPoint == 0) { Graphics_resetViewport (my d_graphics, my inset); return my ManipulationEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed); } nearestPoint = (RealPoint) pitch -> points -> item [inearestPoint]; if (Graphics_distanceWCtoMM (my d_graphics, xWC, yWC, nearestPoint -> number, YLIN (nearestPoint -> value)) > 1.5) { Graphics_resetViewport (my d_graphics, my inset); return my ManipulationEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed); } /* * Clicked on a selected pitch point? */ draggingSelection = shiftKeyPressed && nearestPoint -> number > my d_startSelection && nearestPoint -> number < my d_endSelection; if (draggingSelection) { ifirstSelected = AnyTier_timeToHighIndex (pitch, my d_startSelection); ilastSelected = AnyTier_timeToLowIndex (pitch, my d_endSelection); Editor_save (me, U"Drag pitch points"); } else { ifirstSelected = ilastSelected = inearestPoint; Editor_save (me, U"Drag pitch point"); } /* * Drag. */ /* * Draw at the old location once. * Since some systems do double buffering, * the undrawing at the old position and redrawing at the new have to be bracketed by Graphics_mouseStillDown (). */ Graphics_xorOn (my d_graphics, Graphics_MAROON); drawWhileDragging (me, xWC, yWC, ifirstSelected, ilastSelected, dt, df); dragHorizontal = my p_pitch_draggingStrategy != kManipulationEditor_draggingStrategy_VERTICAL && (! shiftKeyPressed || my p_pitch_draggingStrategy != kManipulationEditor_draggingStrategy_HYBRID); dragVertical = my p_pitch_draggingStrategy != kManipulationEditor_draggingStrategy_HORIZONTAL; while (Graphics_mouseStillDown (my d_graphics)) { double xWC_new, yWC_new; Graphics_getMouseLocation (my d_graphics, & xWC_new, & yWC_new); if (xWC_new != xWC || yWC_new != yWC) { drawWhileDragging (me, xWC, yWC, ifirstSelected, ilastSelected, dt, df); if (dragHorizontal) dt += xWC_new - xWC; if (dragVertical) df += yWC_new - yWC; xWC = xWC_new, yWC = yWC_new; drawWhileDragging (me, xWC, yWC, ifirstSelected, ilastSelected, dt, df); } } Graphics_xorOff (my d_graphics); /* * Dragged inside window? */ if (xWC < my d_startWindow || xWC > my d_endWindow) return 1; /* * Points not dragged past neighbours? */ { RealPoint *points = (RealPoint *) pitch -> points -> item; double newTime = points [ifirstSelected] -> number + dt; if (newTime < my tmin) return 1; // outside domain if (ifirstSelected > 1 && newTime <= points [ifirstSelected - 1] -> number) return 1; /* Past left neighbour. */ newTime = points [ilastSelected] -> number + dt; if (newTime > my tmax) return 1; // outside domain if (ilastSelected < pitch -> points -> size && newTime >= points [ilastSelected + 1] -> number) return 1; // past right neighbour } /* * Drop. */ for (i = ifirstSelected; i <= ilastSelected; i ++) { RealPoint point = (RealPoint) pitch -> points -> item [i]; point -> number += dt; point -> value = YLININV (YLIN (point -> value) + df); if (point -> value < 50.0) point -> value = 50.0; if (point -> value > YLININV (my p_pitch_maximum)) point -> value = YLININV (my p_pitch_maximum); } /* * Make sure that the same pitch points are still selected (a problem with Undo...). */ if (draggingSelection) my d_startSelection += dt, my d_endSelection += dt; if (my d_startSelection == my d_endSelection) { RealPoint point = (RealPoint) pitch -> points -> item [ifirstSelected]; my d_startSelection = my d_endSelection = point -> number; my pitchTier.cursor = YLIN (point -> value); } Editor_broadcastDataChanged (me); return 1; /* Update needed. */ } static void drawDurationWhileDragging (ManipulationEditor me, double xWC, double yWC, long first, long last, double dt, double df) { Manipulation ana = (Manipulation) my data; DurationTier duration = ana -> duration.get(); long i; (void) xWC; (void) yWC; /* * Draw all selected duration points as magenta empty circles, if inside the window. */ for (i = first; i <= last; i ++) { RealPoint point = (RealPoint) duration -> points -> item [i]; double t = point -> number + dt, dur = point -> value + df; if (t >= my d_startWindow && t <= my d_endWindow) Graphics_circle_mm (my d_graphics, t, dur < my p_duration_minimum ? my p_duration_minimum : dur > my p_duration_maximum ? my p_duration_maximum : dur, 3); } if (last == first) { /* * Draw a crosshair with time and duration. */ RealPoint point = (RealPoint) duration -> points -> item [first]; double t = point -> number + dt, durWC = point -> value + df; Graphics_line (my d_graphics, t, my p_duration_minimum, t, my p_duration_maximum - Graphics_dyMMtoWC (my d_graphics, 4.0)); Graphics_setTextAlignment (my d_graphics, Graphics_CENTRE, Graphics_TOP); Graphics_text (my d_graphics, t, my p_duration_maximum, Melder_fixed (t, 6)); Graphics_line (my d_graphics, my d_startWindow, durWC, my d_endWindow, durWC); Graphics_setTextAlignment (my d_graphics, Graphics_LEFT, Graphics_BOTTOM); Graphics_text (my d_graphics, my d_startWindow, durWC, Melder_fixed (durWC, 2)); } } static int clickDuration (ManipulationEditor me, double xWC, double yWC, int shiftKeyPressed) { Manipulation ana = (Manipulation) my data; DurationTier duration = ana -> duration.get(); long inearestPoint, ifirstSelected, ilastSelected, i; RealPoint nearestPoint; double dt = 0, df = 0; int draggingSelection; /* * Convert from FunctionEditor's [0, 1] coordinates to world coordinates. */ yWC = my p_duration_minimum + yWC * (my p_duration_maximum - my p_duration_minimum); /* * Move horizontal hair to clicked position. */ my duration.cursor = yWC; if (! duration) { Graphics_resetViewport (my d_graphics, my inset); return my ManipulationEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed); } Graphics_setWindow (my d_graphics, my d_startWindow, my d_endWindow, my p_duration_minimum, my p_duration_maximum); /* * Clicked on a duration point? */ inearestPoint = AnyTier_timeToNearestIndex (duration, xWC); if (inearestPoint == 0) { Graphics_resetViewport (my d_graphics, my inset); return my ManipulationEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed); } nearestPoint = (RealPoint) duration -> points -> item [inearestPoint]; if (Graphics_distanceWCtoMM (my d_graphics, xWC, yWC, nearestPoint -> number, nearestPoint -> value) > 1.5) { Graphics_resetViewport (my d_graphics, my inset); return my ManipulationEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed); } /* * Clicked on a selected duration point? */ draggingSelection = shiftKeyPressed && nearestPoint -> number > my d_startSelection && nearestPoint -> number < my d_endSelection; if (draggingSelection) { ifirstSelected = AnyTier_timeToHighIndex (duration, my d_startSelection); ilastSelected = AnyTier_timeToLowIndex (duration, my d_endSelection); Editor_save (me, U"Drag duration points"); } else { ifirstSelected = ilastSelected = inearestPoint; Editor_save (me, U"Drag duration point"); } /* * Drag. */ Graphics_xorOn (my d_graphics, Graphics_MAROON); drawDurationWhileDragging (me, xWC, yWC, ifirstSelected, ilastSelected, dt, df); while (Graphics_mouseStillDown (my d_graphics)) { double xWC_new, yWC_new; Graphics_getMouseLocation (my d_graphics, & xWC_new, & yWC_new); if (xWC_new != xWC || yWC_new != yWC) { drawDurationWhileDragging (me, xWC, yWC, ifirstSelected, ilastSelected, dt, df); dt += xWC_new - xWC, xWC = xWC_new; df += yWC_new - yWC, yWC = yWC_new; drawDurationWhileDragging (me, xWC_new, yWC_new, ifirstSelected, ilastSelected, dt, df); } } Graphics_xorOff (my d_graphics); /* * Dragged inside window? */ if (xWC < my d_startWindow || xWC > my d_endWindow) return 1; /* * Points not dragged past neighbours? */ { RealPoint *points = (RealPoint *) duration -> points -> item; double newTime = points [ifirstSelected] -> number + dt; if (newTime < my tmin) return 1; // outside domain if (ifirstSelected > 1 && newTime <= points [ifirstSelected - 1] -> number) return 1; /* Past left neighbour. */ newTime = points [ilastSelected] -> number + dt; if (newTime > my tmax) return 1; // outside domain if (ilastSelected < duration -> points -> size && newTime >= points [ilastSelected + 1] -> number) return 1; // past right neighbour } /* * Drop. */ for (i = ifirstSelected; i <= ilastSelected; i ++) { RealPoint point = (RealPoint) duration -> points -> item [i]; point -> number += dt; point -> value += df; if (point -> value < my p_duration_minimum) point -> value = my p_duration_minimum; if (point -> value > my p_duration_maximum) point -> value = my p_duration_maximum; } /* * Make sure that the same duration points are still selected (a problem with Undo...). */ if (draggingSelection) my d_startSelection += dt, my d_endSelection += dt; if (my d_startSelection == my d_endSelection) { RealPoint point = (RealPoint) duration -> points -> item [ifirstSelected]; my d_startSelection = my d_endSelection = point -> number; my duration.cursor = point -> value; } Editor_broadcastDataChanged (me); return 1; /* Update needed. */ } int structManipulationEditor :: v_click (double xWC, double yWC, bool shiftKeyPressed) { double ypitchmin, ypitchmax, ydurationmin, ydurationmax; int hasPitchArea = getPitchArea (this, & ypitchmin, & ypitchmax); int hasDurationArea = getDurationArea (this, & ydurationmin, & ydurationmax); /* * Dispatch click to clicked area. */ if (hasPitchArea && yWC > ypitchmin && yWC < ypitchmax) { // clicked in pitch area? inset = Graphics_insetViewport (our d_graphics, 0, 1, ypitchmin, ypitchmax); return clickPitch (this, xWC, (yWC - ypitchmin) / (ypitchmax - ypitchmin), shiftKeyPressed); } else if (hasDurationArea && yWC > ydurationmin && yWC < ydurationmax) { // clicked in duration area? inset = Graphics_insetViewport (our d_graphics, 0, 1, ydurationmin, ydurationmax); return clickDuration (this, xWC, (yWC - ydurationmin) / (ydurationmax - ydurationmin), shiftKeyPressed); } /* * Perform the default action: move cursor or drag selection. */ return our ManipulationEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed); } void structManipulationEditor :: v_play (double a_tmin, double a_tmax) { Manipulation ana = (Manipulation) our data; if (our shiftKeyPressed) { if (ana -> sound) Sound_playPart (ana -> sound.get(), a_tmin, a_tmax, theFunctionEditor_playCallback, this); } else { Manipulation_playPart (ana, a_tmin, a_tmax, our synthesisMethod); } } autoManipulationEditor ManipulationEditor_create (const char32 *title, Manipulation ana) { try { autoManipulationEditor me = Thing_new (ManipulationEditor); FunctionEditor_init (me.peek(), title, ana); double maximumPitchValue = RealTier_getMaximumValue (ana -> pitch.get()); if (my p_pitch_units == kManipulationEditor_pitchUnits_HERTZ) { my p_pitch_minimum = 25.0; my pitchTier.minPeriodic = 50.0; my p_pitch_maximum = maximumPitchValue; my pitchTier.cursor = my p_pitch_maximum * 0.8; my p_pitch_maximum *= 1.2; } else { my p_pitch_minimum = -24.0; my pitchTier.minPeriodic = -12.0; my p_pitch_maximum = NUMdefined (maximumPitchValue) ? NUMhertzToSemitones (maximumPitchValue) : NUMundefined; my pitchTier.cursor = my p_pitch_maximum - 4.0; my p_pitch_maximum += 3.0; } if (my p_pitch_maximum == NUMundefined || my p_pitch_maximum < my pref_pitch_maximum ()) my p_pitch_maximum = my pref_pitch_maximum (); double minimumDurationValue = ana -> duration ? RealTier_getMinimumValue (ana -> duration.get()) : NUMundefined; my p_duration_minimum = NUMdefined (minimumDurationValue) ? minimumDurationValue : 1.0; if (my pref_duration_minimum () > 1) my pref_duration_minimum () = Melder_atof (my default_duration_minimum ()); if (my p_duration_minimum > my pref_duration_minimum ()) my p_duration_minimum = my pref_duration_minimum (); double maximumDurationValue = ana -> duration ? RealTier_getMaximumValue (ana -> duration.get()) : NUMundefined; my p_duration_maximum = NUMdefined (maximumDurationValue) ? maximumDurationValue : 1.0; if (my pref_duration_maximum () < 1) my pref_duration_maximum () = Melder_atof (my default_duration_maximum ()); if (my pref_duration_maximum () <= my pref_duration_minimum ()) { my pref_duration_minimum () = Melder_atof (my default_duration_minimum ()); my pref_duration_maximum () = Melder_atof (my default_duration_maximum ()); } if (my p_duration_maximum < my pref_duration_maximum ()) my p_duration_maximum = my pref_duration_maximum (); my duration.cursor = 1.0; my synthesisMethod = prefs_synthesisMethod; if (ana -> sound) Matrix_getWindowExtrema (ana -> sound.get(), 0, 0, 0, 0, & my soundmin, & my soundmax); if (my soundmin == my soundmax) my soundmin = -1.0, my soundmax = +1.0; updateMenus (me.peek()); return me; } catch (MelderError) { Melder_throw (U"Manipulation window not created."); } } /* End of file ManipulationEditor.cpp */ praat-6.0.04/fon/ManipulationEditor.h000066400000000000000000000040101261542461700174550ustar00rootroot00000000000000#ifndef _ManipulationEditor_h_ #define _ManipulationEditor_h_ /* ManipulationEditor.h * * Copyright (C) 1992-2011,2012,2013,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "FunctionEditor.h" #include "Manipulation.h" #include "ManipulationEditor_enums.h" Thing_define (ManipulationEditor, FunctionEditor) { autoPointProcess previousPulses; autoPitchTier previousPitch; autoDurationTier previousDuration; double soundmin, soundmax; int synthesisMethod; GuiMenuItem synthPulsesButton, synthPulsesHumButton; GuiMenuItem synthPulsesLpcButton; GuiMenuItem synthPitchButton, synthPitchHumButton; GuiMenuItem synthPulsesPitchButton, synthPulsesPitchHumButton; GuiMenuItem synthOverlapAddNodurButton, synthOverlapAddButton; GuiMenuItem synthPitchLpcButton; struct { double minPeriodic, cursor; } pitchTier; struct { double cursor; } duration; Graphics_Viewport inset; void v_createMenus () override; void v_createHelpMenuItems (EditorMenu menu) override; void v_saveData () override; void v_restoreData () override; void v_draw () override; int v_click (double xWC, double yWC, bool shiftKeyPressed) override; void v_play (double tmin, double tmax) override; #include "ManipulationEditor_prefs.h" }; autoManipulationEditor ManipulationEditor_create (const char32 *title, Manipulation ana); /* End of file ManipulationEditor.h */ #endif praat-6.0.04/fon/ManipulationEditor_enums.h000066400000000000000000000027561261542461700207030ustar00rootroot00000000000000/* ManipulationEditor_enums.h * * Copyright (C) 1992-2007,2013,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ enums_begin (kManipulationEditor_draggingStrategy, 1) enums_add (kManipulationEditor_draggingStrategy, 1, ALL, U"all") enums_add (kManipulationEditor_draggingStrategy, 2, HORIZONTAL, U"only horizontal") enums_add (kManipulationEditor_draggingStrategy, 3, VERTICAL, U"only vertical") enums_add (kManipulationEditor_draggingStrategy, 4, HYBRID, U"single all, multiple only vertical") enums_end (kManipulationEditor_draggingStrategy, 4, ALL) enums_begin (kManipulationEditor_pitchUnits, 1) enums_add (kManipulationEditor_pitchUnits, 1, HERTZ, U"Hertz") enums_add (kManipulationEditor_pitchUnits, 2, SEMITONES, U"semitones re 100 Hz") enums_end (kManipulationEditor_pitchUnits, 2, HERTZ) /* End of file ManipulationEditor.h */ praat-6.0.04/fon/ManipulationEditor_prefs.h000066400000000000000000000036711261542461700206700ustar00rootroot00000000000000/* ManipulationEditor_prefs.h * * Copyright (C) 2013,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ prefs_begin (ManipulationEditor) prefs_add_double_with_data (ManipulationEditor, pitch_minimum, 1, U"50.0") // Hz prefs_add_double_with_data (ManipulationEditor, pitch_maximum, 1, U"300.0") // Hz prefs_add_enum_with_data (ManipulationEditor, pitch_units, 1, kManipulationEditor_pitchUnits, DEFAULT) prefs_add_enum_with_data (ManipulationEditor, pitch_draggingStrategy, 1, kManipulationEditor_draggingStrategy, DEFAULT) prefs_add_double_with_data (ManipulationEditor, pitch_stylize_frequencyResolution, 1, U"2.0") prefs_add_bool_with_data (ManipulationEditor, pitch_stylize_useSemitones, 1, true) prefs_add_long_with_data (ManipulationEditor, pitch_interpolateQuadratically_numberOfPointsPerParabola, 1, U"4") prefs_add_double_with_data (ManipulationEditor, duration_minimum, 1, U"0.25") prefs_add_double_with_data (ManipulationEditor, duration_maximum, 1, U"3.0") prefs_end (ManipulationEditor) /* End of file ManipulationEditor_prefs.h */ praat-6.0.04/fon/Manipulation_def.h000066400000000000000000000050101261542461700171250ustar00rootroot00000000000000/* Manipulation_def.h * * Copyright (C) 1992-2008,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT Manipulation oo_DEFINE_CLASS (Manipulation, Function) #if oo_READING if (formatVersion >= 5 || (Melder_debug == 25 && formatVersion == 4)) { oo_AUTO_OBJECT (Sound, 2, sound) } else { oo_AUTO_OBJECT (Sound, 0, sound) } #else oo_AUTO_OBJECT (Sound, 0, sound) #endif oo_AUTO_OBJECT (PointProcess, 0, pulses) oo_AUTO_OBJECT (PitchTier, 0, pitch) oo_FROM (1) oo_AUTO_OBJECT (IntensityTier, 0, dummyIntensity) oo_ENDFROM oo_FROM (2) oo_AUTO_OBJECT (DurationTier, 0, duration) oo_ENDFROM oo_FROM (3) /* * Make sure that the spectrogram is not written, * but allow it to be read (a legacy of writing but not reading the version 3 stuff). */ #if oo_WRITING { Image save = dummySpectrogram; dummySpectrogram = nullptr; #endif oo_OBJECT (Image, 0, dummySpectrogram) #if oo_WRITING dummySpectrogram = save; } #endif oo_OBJECT (FormantTier, 0, dummyFormantTier) oo_OBJECT (Daata, 0, dummy1) oo_OBJECT (Daata, 0, dummy2) oo_OBJECT (Daata, 0, dummy3) oo_ENDFROM oo_FROM (4) oo_DOUBLE (dummy10) oo_OBJECT (Pitch, 0, dummyPitchAnalysis) oo_DOUBLE (dummy11) oo_DOUBLE (dummy12) oo_OBJECT (Intensity, 0, dummyIntensityAnalysis) oo_OBJECT (Formant, 1, dummyFormantAnalysis) oo_INT (dummy4) oo_DOUBLE (dummy5) oo_DOUBLE (dummy6) oo_DOUBLE (dummy7) oo_DOUBLE (dummy8) oo_DOUBLE (dummy9) oo_ENDFROM #if !oo_READING && !oo_WRITING oo_OBJECT (LPC, 0, lpc) #endif #if oo_DECLARING int v_domainQuantity () override { return MelderQuantity_TIME_SECONDS; } void v_shiftX (double xfrom, double xto) override; void v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto) override; #endif oo_END_CLASS (Manipulation) #undef ooSTRUCT /* End of file Manipulation_def.h */ praat-6.0.04/fon/Matrix.cpp000066400000000000000000000637121261542461700154630ustar00rootroot00000000000000/* Matrix.cpp * * Copyright (C) 1992-2012,2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Matrix.h" #include "NUM2.h" #include "Formula.h" #include "Eigen.h" #include "oo_DESTROY.h" #include "Matrix_def.h" #include "oo_COPY.h" #include "Matrix_def.h" #include "oo_EQUAL.h" #include "Matrix_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Matrix_def.h" #include "oo_WRITE_TEXT.h" #include "Matrix_def.h" #include "oo_WRITE_BINARY.h" #include "Matrix_def.h" #include "oo_READ_BINARY.h" #include "Matrix_def.h" #include "oo_DESCRIPTION.h" #include "Matrix_def.h" Thing_implement (Matrix, SampledXY, 2); void structMatrix :: v_info () { structDaata :: v_info (); double minimum = 0.0, maximum = 0.0; Matrix_getWindowExtrema (this, 1, our nx, 1, our ny, & minimum, & maximum); MelderInfo_writeLine (U"xmin: ", our xmin); MelderInfo_writeLine (U"xmax: ", our xmax); MelderInfo_writeLine (U"Number of columns: ", our nx); MelderInfo_writeLine (U"dx: ", our dx, U" (-> sampling rate ", 1.0 / our dx, U" )"); MelderInfo_writeLine (U"x1: ", our x1); MelderInfo_writeLine (U"ymin: ", our ymin); MelderInfo_writeLine (U"ymax: ", our ymax); MelderInfo_writeLine (U"Number of rows: ", our ny); MelderInfo_writeLine (U"dy: ", our dy, U" (-> sampling rate ", 1.0 / our dy, U" )"); MelderInfo_writeLine (U"y1: ", our y1); MelderInfo_writeLine (U"Minimum value: ", minimum); MelderInfo_writeLine (U"Maximum value: ", maximum); } void structMatrix :: v_readText (MelderReadText text, int formatVersion) { if (formatVersion < 0) { our xmin = texgetr8 (text); our xmax = texgetr8 (text); our ymin = texgetr8 (text); our ymax = texgetr8 (text); our nx = texgeti4 (text); our ny = texgeti4 (text); our dx = texgetr8 (text); our dy = texgetr8 (text); our x1 = texgetr8 (text); our y1 = texgetr8 (text); } else { Matrix_Parent :: v_readText (text, formatVersion); } if (our xmin > our xmax) Melder_throw (U"xmin should be less than or equal to xmax."); if (our ymin > our ymax) Melder_throw (U"ymin should be less than or equal to ymax."); if (our nx < 1) Melder_throw (U"nx should be at least 1."); if (our ny < 1) Melder_throw (U"ny should be at least 1."); if (our dx <= 0.0) Melder_throw (U"dx should be greater than 0.0."); if (our dy <= 0.0) Melder_throw (U"dy should be greater than 0.0."); our z = NUMmatrix_readText_r8 (1, our ny, 1, our nx, text, "z"); } double structMatrix :: v_getValueAtSample (long isamp, long ilevel, int unit) { double value = our z [ilevel] [isamp]; return NUMdefined (value) ? our v_convertStandardToSpecialUnit (value, ilevel, unit) : NUMundefined; } double structMatrix :: v_getMatrix (long irow, long icol) { if (irow < 1 || irow > our ny) return 0.0; if (icol < 1 || icol > our nx) return 0.0; return z [irow] [icol]; } double structMatrix :: v_getFunction2 (double x, double y) { double rrow = (y - our y1) / our dy + 1.0; double rcol = (x - our x1) / our dx + 1.0; long irow = (long) floor (rrow), icol = (long) floor (rcol); double drow = rrow - irow, dcol = rcol - icol; double z1 = irow < 1 || irow > our ny || icol < 1 || icol > our nx ? 0.0 : z [irow] [icol]; double z2 = irow < 0 || irow >= our ny || icol < 1 || icol > our nx ? 0.0 : z [irow + 1] [icol]; double z3 = irow < 1 || irow > our ny || icol < 0 || icol >= our nx ? 0.0 : z [irow] [icol + 1]; double z4 = irow < 0 || irow >= our ny || icol < 0 || icol >= our nx ? 0.0 : z [irow + 1] [icol + 1]; return (1.0 - drow) * (1.0 - dcol) * z1 + drow * (1.0 - dcol) * z2 + (1.0 - drow) * dcol * z3 + drow * dcol * z4; } void Matrix_init (Matrix me, double xmin, double xmax, long nx, double dx, double x1, double ymin, double ymax, long ny, double dy, double y1) { Sampled_init (me, xmin, xmax, nx, dx, x1); my ymin = ymin; my ymax = ymax; my ny = ny; my dy = dy; my y1 = y1; my z = NUMmatrix (1, my ny, 1, my nx); } autoMatrix Matrix_create (double xmin, double xmax, long nx, double dx, double x1, double ymin, double ymax, long ny, double dy, double y1) { try { autoMatrix me = Thing_new (Matrix); Matrix_init (me.peek(), xmin, xmax, nx, dx, x1, ymin, ymax, ny, dy, y1); return me; } catch (MelderError) { Melder_throw (U"Matrix object not created."); } } autoMatrix Matrix_createSimple (long numberOfRows, long numberOfColumns) { try { autoMatrix me = Thing_new (Matrix); Matrix_init (me.peek(), 0.5, numberOfColumns + 0.5, numberOfColumns, 1, 1, 0.5, numberOfRows + 0.5, numberOfRows, 1, 1); return me; } catch (MelderError) { Melder_throw (U"Matrix object not created."); } } double Matrix_columnToX (Matrix me, double column) { return my x1 + (column - 1) * my dx; } double Matrix_rowToY (Matrix me, double row) { return my y1 + (row - 1) * my dy; } double Matrix_xToColumn (Matrix me, double x) { return (x - my x1) / my dx + 1; } long Matrix_xToLowColumn (Matrix me, double x) { return (long) floor (Matrix_xToColumn (me, x)); } long Matrix_xToHighColumn (Matrix me, double x) { return (long) ceil (Matrix_xToColumn (me, x)); } long Matrix_xToNearestColumn (Matrix me, double x) { return (long) floor (Matrix_xToColumn (me, x) + 0.5); } double Matrix_yToRow (Matrix me, double y) { return (y - my y1) / my dy + 1; } long Matrix_yToLowRow (Matrix me, double y) { return (long) floor (Matrix_yToRow (me, y)); } long Matrix_yToHighRow (Matrix me, double y) { return (long) ceil (Matrix_yToRow (me, y)); } long Matrix_yToNearestRow (Matrix me, double y) { return (long) floor (Matrix_yToRow (me, y) + 0.5); } long Matrix_getWindowSamplesX (Matrix me, double xmin, double xmax, long *ixmin, long *ixmax) { *ixmin = 1 + (long) ceil ((xmin - my x1) / my dx); *ixmax = 1 + (long) floor ((xmax - my x1) / my dx); if (*ixmin < 1) *ixmin = 1; if (*ixmax > my nx) *ixmax = my nx; if (*ixmin > *ixmax) return 0; return *ixmax - *ixmin + 1; } long Matrix_getWindowSamplesY (Matrix me, double ymin, double ymax, long *iymin, long *iymax) { *iymin = 1 + (long) ceil ((ymin - my y1) / my dy); *iymax = 1 + (long) floor ((ymax - my y1) / my dy); if (*iymin < 1) *iymin = 1; if (*iymax > my ny) *iymax = my ny; if (*iymin > *iymax) return 0; return *iymax - *iymin + 1; } long Matrix_getWindowExtrema (Matrix me, long ixmin, long ixmax, long iymin, long iymax, double *minimum, double *maximum) { if (ixmin == 0) ixmin = 1; if (ixmax == 0) ixmax = my nx; if (iymin == 0) iymin = 1; if (iymax == 0) iymax = my ny; if (ixmin > ixmax || iymin > iymax) return 0; *minimum = *maximum = my z [iymin] [ixmin]; for (long iy = iymin; iy <= iymax; iy ++) { for (long ix = ixmin; ix <= ixmax; ix ++) { if (my z [iy] [ix] < *minimum) *minimum = my z [iy] [ix]; if (my z [iy] [ix] > *maximum) *maximum = my z [iy] [ix]; } } return (ixmax - ixmin + 1) * (iymax - iymin + 1); } double Matrix_getValueAtXY (Matrix me, double x, double y) { long bottomRow, leftCol, topRow, rightCol; double drow, dcol; double row_real = (y - my y1) / my dy + 1.0; double col_real = (x - my x1) / my dx + 1.0; /* * We imagine a unit square around every (xi, yi) point in the matrix. * For (x, y) values outside the union of these squares, the z value is undefined. */ if (row_real < 0.5 || row_real > my ny + 0.5) return NUMundefined; if (col_real < 0.5 || col_real > my nx + 0.5) return NUMundefined; /* * Determine the four nearest (xi, yi) points. */ bottomRow = (long) floor (row_real); // 0 <= bottomRow <= my ny topRow = bottomRow + 1; // 1 <= topRow <= my ny + 1 leftCol = (long) floor (col_real); // 0 <= leftCol <= my nx rightCol = leftCol + 1; // 1 <= rightCol <= my nx + 1 drow = row_real - bottomRow; // 0.0 <= drow < 1.0 dcol = col_real - leftCol; // 0.0 <= dcol < 1.0 /* * If adjacent points exist * (i.e., both row numbers are between 1 and my ny, * or both column numbers are between 1 and my nx), * we do linear interpolation. * If not, we do constant extrapolation, * which can be simulated by an interpolation between equal z values. */ if (bottomRow < 1) bottomRow = 1; // 1 <= bottomRow <= my ny if (topRow > my ny) topRow = my ny; // 1 <= topRow <= my ny if (leftCol < 1) leftCol = 1; // 1 <= leftCol <= my nx if (rightCol > my nx) rightCol = my nx; // 1 <= rightCol <= my nx return (1.0 - drow) * (1.0 - dcol) * my z [bottomRow] [leftCol] + drow * (1.0 - dcol) * my z [topRow] [leftCol] + (1.0 - drow) * dcol * my z [bottomRow] [rightCol] + drow * dcol * my z [topRow] [rightCol]; } double Matrix_getSum (Matrix me) { double sum = 0.0; for (long row = 1; row <= my ny; row ++) for (long col = 1; col <= my nx; col ++) sum += my z [row] [col]; return sum; } double Matrix_getNorm (Matrix me) { double sum = 0.0; for (long row = 1; row <= my ny; row ++) for (long col = 1; col <= my nx; col ++) sum += my z [row] [col] * my z [row] [col]; return sqrt (sum); } void Matrix_drawRows (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum) { if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } long ixmin, ixmax, iymin, iymax; (void) Matrix_getWindowSamplesX (me, xmin, xmax, & ixmin, & ixmax); (void) Matrix_getWindowSamplesY (me, ymin, ymax, & iymin, & iymax); if (maximum <= minimum) (void) Matrix_getWindowExtrema (me, ixmin, ixmax, iymin, iymax, & minimum, & maximum); if (maximum <= minimum) { minimum -= 1.0; maximum += 1.0; } if (xmin >= xmax) return; Graphics_setInner (g); for (long iy = iymin; iy <= iymax; iy ++) { Graphics_setWindow (g, xmin, xmax, minimum - (iy - iymin) * (maximum - minimum), maximum + (iymax - iy) * (maximum - minimum)); Graphics_function (g, my z [iy], ixmin, ixmax, Matrix_columnToX (me, ixmin), Matrix_columnToX (me, ixmax)); } Graphics_unsetInner (g); if (iymin < iymax) Graphics_setWindow (g, xmin, xmax, my y1 + (iymin - 1.5) * my dy, my y1 + (iymax - 0.5) * my dy); } void Matrix_drawOneContour (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, double height) { bool xreversed = xmin > xmax, yreversed = ymin > ymax; if (xmax == xmin) { xmin = my xmin; xmax = my xmax; } if (ymax == ymin) { ymin = my ymin; ymax = my ymax; } if (xreversed) { double temp = xmin; xmin = xmax; xmax = temp; } if (yreversed) { double temp = ymin; ymin = ymax; ymax = temp; } long ixmin, ixmax, iymin, iymax; (void) Matrix_getWindowSamplesX (me, xmin, xmax, & ixmin, & ixmax); (void) Matrix_getWindowSamplesY (me, ymin, ymax, & iymin, & iymax); if (xmin == xmax || ymin == ymax) return; Graphics_setInner (g); Graphics_setWindow (g, xreversed ? xmax : xmin, xreversed ? xmin : xmax, yreversed ? ymax : ymin, yreversed ? ymin : ymax); Graphics_contour (g, my z, ixmin, ixmax, Matrix_columnToX (me, ixmin), Matrix_columnToX (me, ixmax), iymin, iymax, Matrix_rowToY (me, iymin), Matrix_rowToY (me, iymax), height); Graphics_rectangle (g, xmin, xmax, ymin, ymax); Graphics_unsetInner (g); } void Matrix_drawContours (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum) { double border [1 + 8]; if (xmax == xmin) { xmin = my xmin; xmax = my xmax; } if (ymax == ymin) { ymin = my ymin; ymax = my ymax; } long ixmin, ixmax, iymin, iymax, iborder; (void) Matrix_getWindowSamplesX (me, xmin, xmax, & ixmin, & ixmax); (void) Matrix_getWindowSamplesY (me, ymin, ymax, & iymin, & iymax); if (maximum <= minimum) (void) Matrix_getWindowExtrema (me, ixmin, ixmax, iymin, iymax, & minimum, & maximum); if (maximum <= minimum) { minimum -= 1.0; maximum += 1.0; } for (iborder = 1; iborder <= 8; iborder ++) border [iborder] = minimum + iborder * (maximum - minimum) / (8 + 1); if (xmin == xmax || ymin == ymax) return; Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_altitude (g, my z, ixmin, ixmax, Matrix_columnToX (me, ixmin), Matrix_columnToX (me, ixmax), iymin, iymax, Matrix_rowToY (me, iymin), Matrix_rowToY (me, iymax), 8, border); Graphics_rectangle (g, xmin, xmax, ymin, ymax); Graphics_unsetInner (g); } void Matrix_paintContours (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum) { double border [1 + 30]; if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } long ixmin, ixmax, iymin, iymax, iborder; (void) Matrix_getWindowSamplesX (me, xmin, xmax, & ixmin, & ixmax); (void) Matrix_getWindowSamplesY (me, ymin, ymax, & iymin, & iymax); if (maximum <= minimum) (void) Matrix_getWindowExtrema (me, ixmin, ixmax, iymin, iymax, & minimum, & maximum); if (maximum <= minimum) { minimum -= 1.0; maximum += 1.0; } for (iborder = 1; iborder <= 30; iborder ++) border [iborder] = minimum + iborder * (maximum - minimum) / (30 + 1); if (xmin >= xmax || ymin >= ymax) return; Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_grey (g, my z, ixmin, ixmax, Matrix_columnToX (me, ixmin), Matrix_columnToX (me, ixmax), iymin, iymax, Matrix_rowToY (me, iymin), Matrix_rowToY (me, iymax), 30, border); Graphics_rectangle (g, xmin, xmax, ymin, ymax); Graphics_unsetInner (g); } static void cellArrayOrImage (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum, bool interpolate) { if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } long ixmin, ixmax, iymin, iymax; (void) Matrix_getWindowSamplesX (me, xmin - 0.49999 * my dx, xmax + 0.49999 * my dx, & ixmin, & ixmax); (void) Matrix_getWindowSamplesY (me, ymin - 0.49999 * my dy, ymax + 0.49999 * my dy, & iymin, & iymax); if (maximum <= minimum) (void) Matrix_getWindowExtrema (me, ixmin, ixmax, iymin, iymax, & minimum, & maximum); if (maximum <= minimum) { minimum -= 1.0; maximum += 1.0; } if (xmin >= xmax || ymin >= ymax) return; Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); if (interpolate) Graphics_image (g, my z, ixmin, ixmax, Sampled_indexToX (me, ixmin - 0.5), Sampled_indexToX (me, ixmax + 0.5), iymin, iymax, SampledXY_indexToY (me, iymin - 0.5), SampledXY_indexToY (me, iymax + 0.5), minimum, maximum); else Graphics_cellArray (g, my z, ixmin, ixmax, Sampled_indexToX (me, ixmin - 0.5), Sampled_indexToX (me, ixmax + 0.5), iymin, iymax, SampledXY_indexToY (me, iymin - 0.5), SampledXY_indexToY (me, iymax + 0.5), minimum, maximum); Graphics_rectangle (g, xmin, xmax, ymin, ymax); Graphics_unsetInner (g); } void Matrix_paintImage (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum) { cellArrayOrImage (me, g, xmin, xmax, ymin, ymax, minimum, maximum, true); } void Matrix_paintCells (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum) { cellArrayOrImage (me, g, xmin, xmax, ymin, ymax, minimum, maximum, false); } void Matrix_paintSurface (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum, double elevation, double azimuth) { if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } long ixmin, ixmax, iymin, iymax; (void) Matrix_getWindowSamplesX (me, xmin, xmax, & ixmin, & ixmax); (void) Matrix_getWindowSamplesY (me, ymin, ymax, & iymin, & iymax); if (maximum <= minimum) (void) Matrix_getWindowExtrema (me, ixmin, ixmax, iymin, iymax, & minimum, & maximum); if (maximum <= minimum) { minimum -= 1.0; maximum += 1.0; } Graphics_setInner (g); Graphics_setWindow (g, -1, 1, minimum, maximum); Graphics_surface (g, my z, ixmin, ixmax, Matrix_columnToX (me, ixmin), Matrix_columnToX (me, ixmax), iymin, iymax, Matrix_rowToY (me, iymin), Matrix_rowToY (me, iymax), minimum, maximum, elevation, azimuth); Graphics_unsetInner (g); } void Matrix_movie (Matrix me, Graphics g) { autoNUMvector column (1, my ny); double minimum = 0.0, maximum = 1.0; Matrix_getWindowExtrema (me, 1, my nx, 1, my ny, & minimum, & maximum); Graphics_setViewport (g, 0, 1, 0, 1); Graphics_setWindow (g, my ymin, my ymax, minimum, maximum); for (long icol = 1; icol <= my nx; icol ++) { for (long irow = 1; irow <= my ny; irow ++) column [irow] = my z [irow] [icol]; Graphics_clearWs (g); Graphics_function (g, column.peek(), 1, my ny, my ymin, my ymax); Graphics_flushWs (g); } } autoMatrix Matrix_readAP (MelderFile file) { try { autofile f = Melder_fopen (file, "rb"); int16_t header [256]; for (long i = 0; i < 256; i ++) header [i] = bingeti2LE (f); double samplingFrequency = header [100]; // converting up (from 16 to 54 bytes) Melder_casual (U"Sampling frequency ", samplingFrequency); autoMatrix me = Matrix_create (0, header [34], header [34] /* Number of frames. */, 1, 0.5, 0, header [35], header [35] /* Number of words per frame. */, 1, 0.5); /*Mat := MATRIX_create (Buffer.I2 [36], (* Number of words per frame. *) Buffer.I2 [35], (* Number of frames. *) 1.0, Buffer.I2 [111] / (* Samples per frame. *) Buffer.I2 [101]); (* Sampling frequency. *)*/ Melder_casual (U"... Loading ", header [34], U" frames", U" of ", header [35], U" words ..."); for (long i = 1; i <= my nx; i ++) for (long j = 1; j <= my ny; j ++) my z [j] [i] = bingeti2LE (f); // converting up (from 16 to 54 bytes) /* * Get pitch frequencies. */ for (long i = 1; i <= my nx; i ++) if (my z [1] [i] != 0.0) my z [1] [i] = - samplingFrequency / my z [1] [i]; f.close (file); return me; } catch (MelderError) { Melder_throw (U"Matrix object not read from AP file ", file); } } autoMatrix Matrix_appendRows (Matrix me, Matrix thee, ClassInfo klas) { try { autoMatrix him = static_cast (Thing_newFromClass (klas)); Matrix_init (him.peek(), my xmin < thy xmin ? my xmin : thy xmin, my xmax > thy xmax ? my xmax : thy xmax, my nx > thy nx ? my nx : thy nx, my dx, my x1 < thy x1 ? my x1 : thy x1, my ymin, my ymax + (thy ymax - thy ymin), my ny + thy ny, my dy, my y1); for (long irow = 1; irow <= my ny; irow ++) for (long icol = 1; icol <= my nx; icol ++) his z [irow] [icol] = my z [irow] [icol]; for (long irow = 1; irow <= thy ny; irow ++) for (long icol = 1; icol <= thy nx; icol ++) his z [irow + my ny] [icol] = thy z [irow] [icol]; return him; } catch (MelderError) { Melder_throw (me, U" & ", thee, U": rows not appended."); } } autoMatrix Matrix_readFromRawTextFile (MelderFile file) { // BUG: not Unicode-compatible try { autofile f = Melder_fopen (file, "rb"); /* * Count number of columns. */ long ncol = 0; for (;;) { int kar = fgetc (f); if (kar == '\n' || kar == '\r' || kar == EOF) break; if (kar == ' ' || kar == '\t') continue; ncol ++; do { kar = fgetc (f); } while (kar != ' ' && kar != '\t' && kar != '\n' && kar != '\r' && kar != EOF); if (kar == '\n' || kar == '\r' || kar == EOF) break; } if (ncol == 0) Melder_throw (U"File empty"); /* * Count number of elements. */ rewind (f); long nelements = 0; for (;;) { double element; if (fscanf (f, "%lf", & element) < 1) break; // zero or end-of-file nelements ++; } /* * Check if all columns are complete. */ if (nelements == 0 || nelements % ncol != 0) Melder_throw (U"The number of elements (", nelements, U") is not a multiple of the number of columns (", ncol, U")."); /* * Create simple matrix. */ long nrow = nelements / ncol; autoMatrix me = Matrix_createSimple (nrow, ncol); /* * Read elements. */ rewind (f); for (long irow = 1; irow <= nrow; irow ++) for (long icol = 1; icol <= ncol; icol ++) fscanf (f, "%lf", & my z [irow] [icol]); f.close (file); return me; } catch (MelderError) { Melder_throw (U"Matrix object not read from raw text file ", file, U"."); } } void Matrix_eigen (Matrix me, Matrix *out_eigenvectors, Matrix *out_eigenvalues) { *out_eigenvectors = nullptr; *out_eigenvalues = nullptr; try { if (my nx != my ny) Melder_throw (U"(Matrix not square."); autoEigen eigen = Thing_new (Eigen); Eigen_initFromSymmetricMatrix (eigen.peek(), my z, my nx); autoMatrix eigenvectors = Data_copy (me); autoMatrix eigenvalues = Matrix_create (1, 1, 1, 1, 1, my ymin, my ymax, my ny, my dy, my y1); for (long i = 1; i <= my nx; i ++) { eigenvalues -> z [i] [1] = eigen -> eigenvalues [i]; for (long j = 1; j <= my nx; j ++) eigenvectors -> z [i] [j] = eigen -> eigenvectors [j] [i]; } *out_eigenvectors = eigenvectors.transfer(); *out_eigenvalues = eigenvalues.transfer(); } catch (MelderError) { Melder_throw (me, U": eigenstructure not computed."); } } autoMatrix Matrix_power (Matrix me, long power) { try { if (my nx != my ny) Melder_throw (U"Matrix not square."); autoMatrix thee = Data_copy (me); autoMatrix him = Data_copy (me); for (long ipow = 2; ipow <= power; ipow ++) { double **tmp = his z; his z = thy z; thy z = tmp; for (long irow = 1; irow <= my ny; irow ++) { for (long icol = 1; icol <= my nx; icol ++) { thy z [irow] [icol] = 0.0; for (long i = 1; i <= my nx; i ++) { thy z [irow] [icol] += his z [irow] [i] * my z [i] [icol]; } } } } return thee; } catch (MelderError) { Melder_throw (me, U": power not computed."); } } void Matrix_writeToMatrixTextFile (Matrix me, MelderFile file) { try { autofile f = Melder_fopen (file, "w"); fprintf (f, "\"ooTextFile\"\n\"Matrix\"\n%.17g %.17g %ld %.17g %.17g\n%.17g %.17g %ld %.17g %.17g\n", my xmin, my xmax, (long) my nx, my dx, my x1, my ymin, my ymax, my ny, my dy, my y1); for (long i = 1; i <= my ny; i ++) { for (long j = 1; j <= my nx; j ++) { if (j > 1) fprintf (f, " "); fprintf (f, "%.17g", my z [i] [j]); } fprintf (f, "\n"); } f.close (file); } catch (MelderError) { Melder_throw (me, U": not written to Matrix text file."); } } void Matrix_writeToHeaderlessSpreadsheetFile (Matrix me, MelderFile file) { try { autofile f = Melder_fopen (file, "w"); for (long i = 1; i <= my ny; i ++) { for (long j = 1; j <= my nx; j ++) { if (j > 1) fprintf (f, "\t"); fprintf (f, "%s", Melder8_single (my z [i] [j])); } fprintf (f, "\n"); } f.close (file); } catch (MelderError) { Melder_throw (me, U": not saved as tab-separated file ", file); } } void Matrix_formula (Matrix me, const char32 *expression, Interpreter interpreter, Matrix target) { try { struct Formula_Result result; Formula_compile (interpreter, me, expression, kFormula_EXPRESSION_TYPE_NUMERIC, true); if (! target) target = me; for (long irow = 1; irow <= my ny; irow ++) { for (long icol = 1; icol <= my nx; icol ++) { Formula_run (irow, icol, & result); target -> z [irow] [icol] = result. result.numericResult; } } } catch (MelderError) { Melder_throw (me, U": formula not completed."); } } void Matrix_formula_part (Matrix me, double xmin, double xmax, double ymin, double ymax, const char32 *expression, Interpreter interpreter, Matrix target) { try { if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } long ixmin, ixmax, iymin, iymax; (void) Matrix_getWindowSamplesX (me, xmin, xmax, & ixmin, & ixmax); (void) Matrix_getWindowSamplesY (me, ymin, ymax, & iymin, & iymax); struct Formula_Result result; Formula_compile (interpreter, me, expression, kFormula_EXPRESSION_TYPE_NUMERIC, true); if (! target) target = me; for (long irow = iymin; irow <= iymax; irow ++) { for (long icol = ixmin; icol <= ixmax; icol ++) { Formula_run (irow, icol, & result); target -> z [irow] [icol] = result. result.numericResult; } } } catch (MelderError) { Melder_throw (me, U": formula not completed."); } } void Matrix_scaleAbsoluteExtremum (Matrix me, double scale) { double extremum = 0.0; for (long i = 1; i <= my ny; i ++) { for (long j = 1; j <= my nx; j ++) { if (fabs (my z [i] [j]) > extremum) { extremum = fabs (my z [i] [j]); } } } if (extremum != 0.0) { double factor = scale / extremum; for (long i = 1; i <= my ny; i ++) { for (long j = 1; j <= my nx; j ++) { my z [i] [j] *= factor; } } } } autoMatrix TableOfReal_to_Matrix (TableOfReal me) { try { autoMatrix thee = Matrix_createSimple (my numberOfRows, my numberOfColumns); for (long i = 1; i <= my numberOfRows; i ++) for (long j = 1; j <= my numberOfColumns; j ++) thy z [i] [j] = my data [i] [j]; return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Matrix."); } } autoTableOfReal Matrix_to_TableOfReal (Matrix me) { try { autoTableOfReal thee = TableOfReal_create (my ny, my nx); for (long i = 1; i <= my ny; i ++) for (long j = 1; j <= my nx; j ++) thy data [i] [j] = my z [i] [j]; return thee; } catch (MelderError) { Melder_throw (me, U": not converted to TableOfReal."); } } autoMatrix Table_to_Matrix (Table me) { try { autoMatrix thee = Matrix_createSimple (my rows -> size, my numberOfColumns); for (long icol = 1; icol <= my numberOfColumns; icol ++) { Table_numericize_Assert (me, icol); } for (long irow = 1; irow <= my rows -> size; irow ++) { TableRow row = static_cast (my rows -> item [irow]); for (long icol = 1; icol <= my numberOfColumns; icol ++) { thy z [irow] [icol] = row -> cells [icol]. number; } } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Matrix."); } } /* End of file Matrix.cpp */ praat-6.0.04/fon/Matrix.h000066400000000000000000000230151261542461700151200ustar00rootroot00000000000000#ifndef _Matrix_h_ #define _Matrix_h_ /* Matrix.h * * Copyright (C) 1992-2011,2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "SampledXY.h" #include "Graphics.h" #include "../stat/Table.h" #include "../stat/TableOfReal.h" #include "Interpreter_decl.h" #include "Matrix_def.h" oo_CLASS_CREATE (Matrix, SampledXY); void Matrix_init (Matrix me, double xmin, double xmax, long nx, double dx, double x1, double ymin, double ymax, long ny, double dy, double y1); autoMatrix Matrix_create (double xmin, double xmax, long nx, double dx, double x1, double ymin, double ymax, long ny, double dy, double y1); /* Function: return a new empty Matrix. Preconditions: xmin <= xmax; ymin <= ymax; nx >= 1; ny >= 1; dx > 0.0; dy > 0.0; Postconditions: result -> xmin == xmin; result -> xmax == xmax; result -> ymin == ymin; result -> ymax == ymax; result -> nx == nx; result -> ny == ny; result -> dx == dx; result -> dy == dy; result -> x1 == x1; result -> y1 == y1; result -> z [1..ny] [1..nx] == 0.0; */ autoMatrix Matrix_createSimple (long numberOfRows, long numberOfColumns); /* Function: return a new empty Matrix. Preconditions: numberOfRows >= 1; numberOfColumns >= 1; Postconditions: result -> xmin == 0.5; result -> xmax == numberOfColumns + 0.5; result -> ymin == 0.5; result -> ymax == numberOfRows + 0.5; result -> nx == numberOfColumns; result -> ny == numberOfRows; result -> dx == 1; result -> dy == 1; result -> x1 == 1; result -> y1 == 1; result -> z [1..ny] [1..nx] == 0.0; */ /* Implemented methods int Matrix::writeText (I, FILE *f); writes a Matrix as text to the stream f. A sample of the format follows (see example 3 above): 0 5000 1 2 ! xmin xmax ymin ymax 8193 2 ! nx ny 0.61035156 1 ! dx dy 0 1 ! x1 y1 5.1e-8 ! 0 1 5 ! 0.61035156 1 -3.556473 ! 1.2207031 1 ... 90000000 ! 4998.7793 2 3.1415927 ! 4999.3896 2 -5.735668e35 ! 5000 2 The data lines (all lines after the fourth) contain: my z [iy, ix], x, y. things written after the "!" are mere comments: you cannot use them to change the meaning or order of the data. int Matrix::readText (I, FILE *f) reads a Matrix as text from the stream f. The requested format is the same as the format produced by Matrix::writeText, though any comments may be left out. Failures: Wrong text input: this line should start with xmin, xmax, ymin, and ymax. Wrong text input: this line should start with nx >= 1 and ny >= 1. Wrong text input: this line should start with dx > 0.0 and dy > 0.0. Wrong text input: this line should start with x1 and y1. Out of text input: there should be 'nx * ny' lines with z values. int Matrix::writeBinary (I, FILE *f) writes a Matrix to the stream f, in IEEE floating-point format. int Matrix::readBinary (I, FILE *f) reads a Matrix from the stream f, in IEEE floating-point format. Failures: Wrong binary input. Not enough memory to read this Matrix. Out of input. */ long Matrix_getWindowSamplesX (Matrix me, double xmin, double xmax, long *ixmin, long *ixmax); /* Function: return the number of samples with x values in [xmin, xmax]. Put the first of these samples in ixmin. Put the last of these samples in ixmax. Postconditions: *ixmin >= 1; *ixmax <= my nx; if (result != 0) *ixmin <= *ixmax; else *ixmin > *ixmax; if (result != 0) result == *ixmax - *ixmin + 1; */ double Matrix_getValueAtXY (Matrix me, double x, double y); /* Linear interpolation between matrix points, constant extrapolation in cells on the edge, NUMundefined outside the union of the unit squares around the points. */ double Matrix_getSum (Matrix me); double Matrix_getNorm (Matrix me); double Matrix_columnToX (Matrix me, double column); /* Return my x1 + (column - 1) * my dx. */ double Matrix_rowToY (Matrix me, double row); /* Return my y1 + (row - 1) * my dy. */ double Matrix_xToColumn (Matrix me, double x); /* Return (x - xmin) / my dx + 1. */ long Matrix_xToLowColumn (Matrix me, double x); /* Return floor (Matrix_xToColumn (me, x)). */ long Matrix_xToHighColumn (Matrix me, double x); /* Return ceil (Matrix_xToColumn (me, x)). */ long Matrix_xToNearestColumn (Matrix me, double x); /* Return floor (Matrix_xToColumn (me, x) + 0.5). */ double Matrix_yToRow (Matrix me, double y); /* Return (y - ymin) / my dy + 1. */ long Matrix_yToLowRow (Matrix me, double y); /* Return floor (Matrix_yToRow (me, y)). */ long Matrix_yToHighRow (Matrix me, double x); /* Return ceil (Matrix_yToRow (me, y)). */ long Matrix_yToNearestRow (Matrix me, double y); /* Return floor (Matrix_yToRow (me, y) + 0.5). */ long Matrix_getWindowSamplesY (Matrix me, double ymin, double ymax, long *iymin, long *iymax); long Matrix_getWindowExtrema (Matrix me, long ixmin, long ixmax, long iymin, long iymax, double *minimum, double *maximum); /* Function: compute the minimum and maximum values of my z over all samples inside [ixmin, ixmax] * [iymin, iymax]. Arguments: if ixmin = 0, start at first column; if ixmax = 0, end at last column (same for iymin and iymax). Return value: the number of samples inside the window. Postconditions: if result == 0, *minimum and *maximum are not changed; */ void Matrix_formula (Matrix me, const char32 *expression, Interpreter interpreter, Matrix target); /* Arguments: "me" is the Matrix referred to as "self" or with "nx" etc. in the expression "target" is the Matrix whose elements will change according to: FOR row FROM 1 TO my ny FOR col FROM 1 TO my nx target -> z [row, col] = expression ENDFOR ENDFOR "expression" is the text to be compiled and interpreted. If "target" is null, the result will go to "me"; otherwise, to "target". Return value: 0 in case of failure, otherwise 1. */ void Matrix_formula_part (Matrix me, double xmin, double xmax, double ymin, double ymax, const char32 *expression, Interpreter interpreter, Matrix target); /***** Graphics routines. *****/ /* All of these routines show the samples of a Matrix whose x and y values are inside the window [xmin, xmax] * [ymin, ymax]. The scaling of the values of these samples is determined by "minimum" and "maximum". All of these routines can perform automatic windowing and scaling: if xmax <= xmin, the window in the x direction will be set to [my xmin, my xmax]; if ymax <= ymin, the window in the y direction will be set to [my ymin, my ymax]; if maximum <= minimum, the windowing (scaling) in the z direction will be determined by the minimum and maximum values of the samples inside the window. */ void Matrix_drawRows (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum); /* Every row is plotted as a function of x, with straight lines connecting the sample points. The rows are stacked from bottom to top. */ void Matrix_drawOneContour (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, double height); void Matrix_drawContours (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum); /* A contour altitude plot with curves at multiple heights. */ void Matrix_paintContours (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum); /* A contour plot with multiple shades of grey and white (low) and black (high) paint. */ void Matrix_paintImage (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum); /* Two-dimensional interpolation of greys. The larger the value of the sample, the darker the greys. */ void Matrix_paintCells (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum); /* Every sample is drawn as a grey rectangle. The larger the value of the sample, the darker the rectangle. */ void Matrix_paintSurface (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum, double elevation, double azimuth); /* 3D surface plot. Every space between adjacent four samples is drawn as a tetragon filled with a grey value. 'elevation' may be 30 degrees, 'azimuth' may be 45 degrees. */ void Matrix_movie (Matrix me, Graphics g); autoMatrix Matrix_readFromRawTextFile (MelderFile file); autoMatrix Matrix_readAP (MelderFile file); autoMatrix Matrix_appendRows (Matrix me, Matrix thee, ClassInfo klas); void Matrix_eigen (Matrix me, Matrix *eigenvectors, Matrix *eigenvalues); autoMatrix Matrix_power (Matrix me, long power); void Matrix_scaleAbsoluteExtremum (Matrix me, double scale); autoMatrix Table_to_Matrix (Table me); void Matrix_writeToMatrixTextFile (Matrix me, MelderFile file); void Matrix_writeToHeaderlessSpreadsheetFile (Matrix me, MelderFile file); autoMatrix TableOfReal_to_Matrix (TableOfReal me); autoTableOfReal Matrix_to_TableOfReal (Matrix me); /* End of file Matrix.h */ #endif praat-6.0.04/fon/Matrix_and_Pitch.cpp000066400000000000000000000057701261542461700174340ustar00rootroot00000000000000/* Matrix_and_Pitch.cpp * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2007/08/12 wchar * pb 2009/01/18 Interpreter argument to formula * pb 2009/04/04 corrected voiceless frames in Pitch_to_Matrix * pb 2011/06/04 C++ */ #include "Matrix_and_Pitch.h" autoMatrix Pitch_to_Matrix (Pitch me) { try { autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, 1, 1, 1, 1, 1); for (long i = 1; i <= my nx; i ++) { double value = my frame [i]. candidate [1]. frequency; thy z [1] [i] = value > 0.0 && value < my ceiling ? my frame [i]. candidate [1]. frequency : 0.0; } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Matrix."); } } autoPitch Matrix_to_Pitch (Matrix me) { try { autoPitch thee = Pitch_create (my xmin, my xmax, my nx, my dx, my x1, 5000, 2); for (long i = 1; i <= my nx; i ++) { Pitch_Frame frame = & thy frame [i]; if (my z [1] [i] == 0.0) { Pitch_Frame_init (frame, 1); frame->candidate[1].frequency = 0.0; // voiceless candidate always present frame->candidate[1].strength = 0.4; } else { Pitch_Frame_init (frame, 2); frame->intensity = 1; frame->candidate[1].frequency = my z [1] [i]; frame->candidate[1].strength = 0.9; frame->candidate[2].frequency = 0.0; // voiceless candidate always present frame->candidate[2].strength = 0.4; } } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Pitch."); } } void Pitch_formula (Pitch me, const char32 *formula, Interpreter interpreter) { try { autoMatrix m = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, 1, my maxnCandidates, my maxnCandidates, 1, 1); for (long iframe = 1; iframe <= my nx; iframe ++) { Pitch_Frame frame = & my frame [iframe]; for (long icand = 1; icand <= frame -> nCandidates; icand ++) m -> z [icand] [iframe] = frame -> candidate [icand]. frequency; } Matrix_formula (m.peek(), formula, interpreter, NULL); for (long iframe = 1; iframe <= my nx; iframe ++) { Pitch_Frame frame = & my frame [iframe]; for (long icand = 1; icand <= frame -> nCandidates; icand ++) frame -> candidate [icand]. frequency = m -> z [icand] [iframe]; } } catch (MelderError) { Melder_throw (me, U": formula not completed."); } } /* End of file Matrix_and_Pitch.cpp */ praat-6.0.04/fon/Matrix_and_Pitch.h000066400000000000000000000016431261542461700170740ustar00rootroot00000000000000/* Matrix_and_Pitch.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Matrix.h" #include "Pitch.h" autoMatrix Pitch_to_Matrix (Pitch me); autoPitch Matrix_to_Pitch (Matrix me); /* End of file Matrix_and_Pitch.h */ praat-6.0.04/fon/Matrix_and_PointProcess.cpp000066400000000000000000000031601261542461700210040ustar00rootroot00000000000000/* Matrix_and_PointProcess.cpp * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 1997/03/29 * pb 2002/07/16 GPL * pb 2011/06/04 C++ */ #include "Matrix_and_PointProcess.h" autoMatrix PointProcess_to_Matrix (PointProcess me) { try { if (my nt == 0) Melder_throw (U"No times in PointProcess."); autoMatrix thee = Matrix_create (1, my nt, my nt, 1, 1, 1, 1, 1, 1, 1); for (long i = 1; i <= my nt; i ++) thy z [1] [i] = my t [i]; return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Matrix."); } } autoPointProcess Matrix_to_PointProcess (Matrix me) { try { autoPointProcess thee = PointProcess_create (my z [1] [1], my z [1] [my nx], my nx); for (long i = 1; i <= my nx; i ++) { PointProcess_addPoint (thee.peek(), my z [1] [i]); } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to PointProcess."); } } /* End of file Matrix_and_PointProcess.cpp */ praat-6.0.04/fon/Matrix_and_PointProcess.h000066400000000000000000000027011261542461700204510ustar00rootroot00000000000000/* Matrix_and_PointProcess.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Matrix.h" #include "PointProcess.h" autoMatrix PointProcess_to_Matrix (PointProcess me); /* Function: create a Matrix from a PointProcess. Postconditions: thy xmin == 1; thy xmax == my numberOfEvents; thy nx == my numberOfEvents; thy dx == 1; thy x1 == 1; thy ymin ymax ny dy y1 == 1; for (ievent in 1..my numberOfEvents) thy z [1] [ievent] == my event [ievent]; */ autoPointProcess Matrix_to_PointProcess (Matrix me); /* Function: create a PointProcess from a Matrix. Postconditions: thy maximumNumberOfEvents == my nx; thy numberOfEvents == my nx; for (ix in 1..my nx) thy event [ix] == my z [1] [ix]; */ /* End of file Matrix_and_PointProcess.h */ praat-6.0.04/fon/Matrix_and_Polygon.cpp000066400000000000000000000035641261542461700200130ustar00rootroot00000000000000/* Matrix_and_Polygon.cpp * * Copyright (C) 1992-2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 1995/11/07 * pb 2002/07/16 GPL * pb 2008/01/19 double * pb 2011/06/04 C++ */ #include "Matrix_and_Polygon.h" autoPolygon Matrix_to_Polygon (Matrix me) { try { if (my nx != 2 && my ny != 2) Melder_throw (U"Matrix must have exactly 2 rows or columns."); autoPolygon thee; if (my ny == 2) { thee = Polygon_create (my nx); NUMvector_copyElements (my z [1], thy x, 1, my nx); NUMvector_copyElements (my z [2], thy y, 1, my nx); } else { thee = Polygon_create (my ny); for (long i = 1; i <= my ny; i ++) { thy x [i] = my z [i] [1]; thy y [i] = my z [i] [2]; } } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Polygon."); } } autoMatrix Polygon_to_Matrix (Polygon me) { try { autoMatrix thee = Matrix_create (1, my numberOfPoints, my numberOfPoints, 1, 1, 1, 2, 2, 1, 1); NUMvector_copyElements (my x, thy z [1], 1, my numberOfPoints); NUMvector_copyElements (my y, thy z [2], 1, my numberOfPoints); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Matrix."); } } /* End of file Matrix_and_Polygon.cpp */ praat-6.0.04/fon/Matrix_and_Polygon.h000066400000000000000000000030351261542461700174510ustar00rootroot00000000000000/* Matrix_and_Polygon.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Matrix.h" #include "Polygon.h" autoPolygon Matrix_to_Polygon (Matrix me); /* Function: create a Polygon from a Matrix. Failures: my ny != 2 && my nx != 2; // Matrix must have exactly 2 rows or columns. Out of memory. Postconditions: thy numberOfPoints == my nx; if (my ny == 2) { thy x [...] == my z [1] [...]; thy y [...] == my z [2] [...]; } else { thy x [...] == my z [...] [1]; thy y [...] == my z [...] [2]; } */ autoMatrix Polygon_to_Matrix (Polygon me); /* Function: create a Matrix from a Polygon. Postconditions: thy xmin xmax nx dx x1 == 1 my numberOfPoints my numberOfPoints 1 1; thy ymin ymax ny dy y1 == 1 2 2 1 1; thy z [1] [...] == my x [...]; thy z [2] [...] == my y [...]; */ /* End of file Matrix_and_Polygon.h */ praat-6.0.04/fon/Matrix_def.h000066400000000000000000000033571261542461700157450ustar00rootroot00000000000000/* Matrix_def.h * * Copyright (C) 1992-2011,2013,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT Matrix oo_DEFINE_CLASS (Matrix, SampledXY) #if oo_READING if (Melder_debug == 45) Melder_casual (U"structMatrix :: read:" U" Going to read ", ny, U" rows" U" of ", nx, U" columns."); if (formatVersion >= 2) { oo_DOUBLE_MATRIX (z, ny, nx) } else { oo_FLOAT_MATRIX (z, ny, nx) } #else oo_DOUBLE_MATRIX (z, ny, nx) #endif #if oo_DECLARING void v_info () override; bool v_hasGetNrow () override { return true; } double v_getNrow () override { return ny; } bool v_hasGetNcol () override { return true; } double v_getNcol () override { return nx; } bool v_hasGetMatrix () override { return true; } double v_getMatrix (long irow, long icol) override; bool v_hasGetFunction2 () override { return true; } double v_getFunction2 (double x, double y) override; double v_getValueAtSample (long isamp, long ilevel, int unit) override; #endif oo_END_CLASS (Matrix) #undef ooSTRUCT /* End of file Matrix_def.h */ praat-6.0.04/fon/Movie.cpp000066400000000000000000000107521261542461700152720ustar00rootroot00000000000000/* Movie.cpp * * Copyright (C) 2011-2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Movie.h" #include "oo_DESTROY.h" #include "Movie_def.h" #include "oo_COPY.h" #include "Movie_def.h" #include "oo_EQUAL.h" #include "Movie_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Movie_def.h" #include "oo_WRITE_TEXT.h" #include "Movie_def.h" #include "oo_READ_TEXT.h" #include "Movie_def.h" #include "oo_WRITE_BINARY.h" #include "Movie_def.h" #include "oo_READ_BINARY.h" #include "Movie_def.h" #include "oo_DESCRIPTION.h" #include "Movie_def.h" Thing_implement (Movie, Sampled, 0); void structMovie :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Start time: ", xmin, U" seconds"); MelderInfo_writeLine (U"End time: ", xmax, U" seconds"); MelderInfo_writeLine (U"Total duration: ", xmax - xmin, U" seconds"); MelderInfo_writeLine (U"Time sampling:"); MelderInfo_writeLine (U" Number of frames: ", nx); MelderInfo_writeLine (U" Frame duration: ", dx, U" seconds"); MelderInfo_writeLine (U" Frame rate: ", Melder_single (1.0 / dx), U" frames per second"); MelderInfo_writeLine (U" First frame centred at: ", x1, U" seconds"); } void Movie_init (Movie me, Sound sound, const char32 *folderName, Strings fileNames) { Sampled_init (me, sound -> xmin, sound -> xmax, fileNames ? fileNames -> numberOfStrings : 0, 0.04, 0.0); my d_sound = sound; my d_folderName = Melder_dup (folderName); my d_fileNames = fileNames; } autoMovie Movie_openFromSoundFile (MelderFile file) { try { autoMovie me = Thing_new (Movie); autoSound sound = Sound_readFromSoundFile (file); autoMelderString fileNameHead; MelderString_copy (& fileNameHead, Melder_fileToPath (file)); char32 *extensionLocation = str32rchr (fileNameHead.string, U'.'); if (! extensionLocation) extensionLocation = & fileNameHead.string [fileNameHead.length]; *extensionLocation = U'\0'; fileNameHead.length = extensionLocation - fileNameHead.string; autoStrings strings = Strings_createAsFileList (Melder_cat (fileNameHead.string, U"*.png")); struct structMelderDir folder; MelderFile_getParentDir (file, & folder); Movie_init (me.peek(), sound.transfer(), Melder_dirToPath (& folder), strings.transfer()); return me; } catch (MelderError) { Melder_throw (U"Movie object not read from file ", file, U"."); } } void Movie_paintOneImageInside (Movie me, Graphics graphics, long frameNumber, double xmin, double xmax, double ymin, double ymax) { try { if (frameNumber < 1) Melder_throw (U"Specified frame number is ", frameNumber, U" but should be at least 1."); if (frameNumber > my nx) Melder_throw (U"Specified frame number is ", frameNumber, U" but there are only ", my nx, U"frames."); Melder_assert (my d_fileNames != 0); Melder_assert (my d_fileNames -> numberOfStrings == my nx); struct structMelderDir folder; Melder_pathToDir (my d_folderName, & folder); struct structMelderFile file; MelderDir_getFile (& folder, my d_fileNames -> strings [frameNumber], & file); Graphics_imageFromFile (graphics, Melder_fileToPath (& file), xmin, xmax, ymin, ymax); } catch (MelderError) { Melder_throw (me, U": image ", frameNumber, U" not painted."); } } void Movie_paintOneImage (Movie me, Graphics graphics, long frameNumber, double xmin, double xmax, double ymin, double ymax) { try { Graphics_setInner (graphics); Graphics_setWindow (graphics, 0.0, 1.0, 0.0, 1.0); Movie_paintOneImageInside (me, graphics, frameNumber, xmin, xmax, ymin, ymax); Graphics_unsetInner (graphics); } catch (MelderError) { Graphics_unsetInner (graphics); // TODO: should be auto throw; } } void Movie_play (Movie me, Graphics g, double tmin, double tmax, int (*callback) (void *closure, int phase, double tmin, double tmax, double t), void *closure) { (void) g; Sound_playPart (my d_sound, tmin, tmax, callback, closure); } /* End of file Movie.cpp */ praat-6.0.04/fon/Movie.h000066400000000000000000000030111261542461700147250ustar00rootroot00000000000000#ifndef _Movie_h_ #define _Movie_h_ /* Movie.h * * Copyright (C) 2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Sampled.h" #include "Graphics.h" #include "Sound.h" #include "Strings_.h" #include "Movie_def.h" oo_CLASS_CREATE (Movie, Sampled); autoMovie Movie_openFromSoundFile (MelderFile file); void Movie_init (Movie me, Sound sound, const char32 *folderName, Strings fileNames); void Movie_paintOneImageInside (Movie me, Graphics graphics, long frameNumber, double xmin, double xmax, double ymin, double ymax); void Movie_paintOneImage (Movie me, Graphics graphics, long frameNumber, double xmin, double xmax, double ymin, double ymax); void Movie_play (Movie me, Graphics graphics, double tmin, double tmax, int (*callback) (void *closure, int phase, double tmin, double tmax, double t), void *closure); /* End of file Movie.h */ #endif praat-6.0.04/fon/MovieWindow.cpp000066400000000000000000000133401261542461700164560ustar00rootroot00000000000000/* MovieWindow.cpp * * Copyright (C) 2011-2012,2013,2014 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "MovieWindow.h" #include "EditorM.h" Thing_implement (MovieWindow, TimeSoundAnalysisEditor, 0); /********** MENU COMMANDS **********/ void structMovieWindow :: v_createMenuItems_view (EditorMenu menu) { our MovieWindow_Parent :: v_createMenuItems_view (menu); //EditorMenu_addCommand (menu, L"-- view/realtier --", 0, 0); //EditorMenu_addCommand (menu, v_setRangeTitle (), 0, menu_cb_setRange); } void structMovieWindow :: v_createMenus () { our MovieWindow_Parent :: v_createMenus (); //EditorMenu menu = Editor_addMenu (this, L"Movie", 0); //EditorMenu_addCommand (menu, L"Add point at cursor", 'T', menu_cb_addPointAtCursor); our v_createMenus_analysis (); // insert some of the ancestor's menus *after* the Movie menus } /********** DRAWING AREA **********/ /** * @returns a value between 0.0 and 1.0; depends on whether the Sound and/or analyses are visible */ static double _MovieWindow_getSoundBottomPosition (MovieWindow me) { Movie movie = (Movie) my data; bool showAnalysis = (my p_spectrogram_show || my p_pitch_show || my p_intensity_show || my p_formant_show) && movie -> d_sound; return movie -> d_sound ? (showAnalysis ? 0.7 : 0.3) : 1.0; } void structMovieWindow :: v_draw () { Movie movie = (Movie) our data; bool showAnalysis = (our p_spectrogram_show || our p_pitch_show || our p_intensity_show || our p_formant_show) && movie -> d_sound; double soundY = _MovieWindow_getSoundBottomPosition (this); if (movie -> d_sound) { Graphics_Viewport viewport = Graphics_insetViewport (our d_graphics, 0, 1, soundY, 1.0); Graphics_setColour (our d_graphics, Graphics_WHITE); Graphics_setWindow (our d_graphics, 0, 1, 0, 1); Graphics_fillRectangle (our d_graphics, 0, 1, 0, 1); TimeSoundEditor_drawSound (this, -1.0, 1.0); Graphics_flushWs (our d_graphics); Graphics_resetViewport (our d_graphics, viewport); } if (true) { Graphics_Viewport viewport = Graphics_insetViewport (d_graphics, 0.0, 1.0, 0.0, 0.3); Graphics_setColour (our d_graphics, Graphics_WHITE); Graphics_setWindow (our d_graphics, 0, 1, 0, 1); Graphics_fillRectangle (our d_graphics, 0, 1, 0, 1); Graphics_setColour (our d_graphics, Graphics_BLACK); Graphics_setWindow (our d_graphics, our d_startWindow, our d_endWindow, 0.0, 1.0); long firstFrame = Sampled_xToNearestIndex (movie, our d_startWindow); long lastFrame = Sampled_xToNearestIndex (movie, our d_endWindow); if (firstFrame < 1) firstFrame = 1; if (lastFrame > movie -> nx) lastFrame = movie -> nx; for (long iframe = firstFrame; iframe <= lastFrame; iframe ++) { double time = Sampled_indexToX (movie, iframe); double timeLeft = time - 0.5 * movie -> dx, timeRight = time + 0.5 * movie -> dx; if (timeLeft < our d_startWindow) timeLeft = our d_startWindow; if (timeRight > our d_endWindow) timeRight = our d_endWindow; Movie_paintOneImageInside (movie, our d_graphics, iframe, timeLeft, timeRight, 0.0, 1.0); } Graphics_flushWs (our d_graphics); Graphics_resetViewport (our d_graphics, viewport); } if (showAnalysis) { Graphics_Viewport viewport = Graphics_insetViewport (our d_graphics, 0.0, 1.0, 0.3, soundY); our v_draw_analysis (); Graphics_flushWs (our d_graphics); Graphics_resetViewport (our d_graphics, viewport); /* Draw pulses. */ if (our p_pulses_show) { viewport = Graphics_insetViewport (our d_graphics, 0.0, 1.0, soundY, 1.0); our v_draw_analysis_pulses (); TimeSoundEditor_drawSound (this, -1.0, 1.0); // second time, partially across the pulses Graphics_flushWs (our d_graphics); Graphics_resetViewport (our d_graphics, viewport); } } our v_updateMenuItems_file (); } void structMovieWindow :: v_highlightSelection (double left, double right, double bottom, double top) { if (our p_spectrogram_show) Graphics_highlight (our d_graphics, left, right, 0.3 * bottom + 0.7 * top, top); else Graphics_highlight (our d_graphics, left, right, 0.7 * bottom + 0.3 * top, top); } void structMovieWindow :: v_unhighlightSelection (double left, double right, double bottom, double top) { if (our p_spectrogram_show) Graphics_highlight (our d_graphics, left, right, 0.3 * bottom + 0.7 * top, top); else Graphics_highlight (our d_graphics, left, right, 0.7 * bottom + 0.3 * top, top); } int structMovieWindow :: v_click (double xWC, double yWC, bool shiftKeyPressed) { return our MovieWindow_Parent :: v_click (xWC, yWC, shiftKeyPressed); } void structMovieWindow :: v_play (double tmin, double tmax) { Movie movie = (Movie) data; Movie_play (movie, our d_graphics, tmin, tmax, theFunctionEditor_playCallback, this); } void MovieWindow_init (MovieWindow me, const char32 *title, Movie movie) { Melder_assert (movie); TimeSoundAnalysisEditor_init (me, title, movie, movie -> d_sound, false); } autoMovieWindow MovieWindow_create (const char32 *title, Movie movie) { try { autoMovieWindow me = Thing_new (MovieWindow); MovieWindow_init (me.peek(), title, movie); return me; } catch (MelderError) { Melder_throw (U"Movie window not created."); } } /* End of file MovieWindow.cpp */ praat-6.0.04/fon/MovieWindow.h000066400000000000000000000030271261542461700161240ustar00rootroot00000000000000#ifndef _MovieWindow_h_ #define _MovieWindow_h_ /* MovieWindow.h * * Copyright (C) 2011,2012,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "TimeSoundAnalysisEditor.h" #include "Movie.h" Thing_define (MovieWindow, TimeSoundAnalysisEditor) { void v_createMenus () override; void v_draw () override; int v_click (double xWC, double yWC, bool shiftKeyPressed) override; void v_play (double tmin, double tmax) override; void v_createMenuItems_view (EditorMenu menu) override; void v_highlightSelection (double left, double right, double bottom, double top) override; void v_unhighlightSelection (double left, double right, double bottom, double top) override; }; void MovieWindow_init (MovieWindow me, const char32 *title, Movie movie); autoMovieWindow MovieWindow_create (const char32 *title, Movie movie); /* End of file MovieWindow.h */ #endif praat-6.0.04/fon/Movie_def.h000066400000000000000000000020211261542461700155430ustar00rootroot00000000000000/* Movie_def.h * * Copyright (C) 2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT Movie oo_DEFINE_CLASS (Movie, Sampled) oo_OBJECT (Sound, 2, d_sound) oo_STRING (d_folderName) oo_OBJECT (Strings, 0, d_fileNames) #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (Movie) #undef ooSTRUCT /* End of file Movie_def.h */ praat-6.0.04/fon/ParamCurve.cpp000066400000000000000000000131621261542461700162560ustar00rootroot00000000000000/* ParamCurve.cpp * * Copyright (C) 1992-2012,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ParamCurve.h" #include "oo_DESTROY.h" #include "ParamCurve_def.h" #include "oo_COPY.h" #include "ParamCurve_def.h" #include "oo_EQUAL.h" #include "ParamCurve_def.h" #include "oo_DESCRIPTION.h" #include "ParamCurve_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "ParamCurve_def.h" Thing_implement (ParamCurve, Function, 2); void structParamCurve :: v_info () { double xmin = 1e308, xmax = -1e308, ymin = 1e308, ymax = -1e308; for (long i = 1; i <= our x -> nx; i ++) { double value = our x -> z [1] [i]; if (value < xmin) xmin = value; if (value > xmax) xmax = value; } for (long i = 1; i <= y -> nx; i ++) { double value = our y -> z [1] [i]; if (value < ymin) ymin = value; if (value > ymax) ymax = value; } structDaata :: v_info (); MelderInfo_writeLine (U"Domain:"); MelderInfo_writeLine (U" tmin: ", xmin); MelderInfo_writeLine (U" tmax: ", xmax); MelderInfo_writeLine (U"x sampling:"); MelderInfo_writeLine (U" Number of values of t in x: ", our x -> nx); MelderInfo_writeLine (U" t step in x: ", our x -> dx, U" (sampling rate ", 1.0 / our x -> dx, U")"); MelderInfo_writeLine (U" First t in x: ", our x -> x1); MelderInfo_writeLine (U"x values:"); MelderInfo_writeLine (U" Minimum x: ", xmin); MelderInfo_writeLine (U" Maximum x: ", xmax); MelderInfo_writeLine (U"y sampling:"); MelderInfo_writeLine (U" Number of values of t in y: ", our y -> nx); MelderInfo_writeLine (U" t step in y: ", our y -> dx, U" (sampling rate ", 1.0 / our y -> dx, U")"); MelderInfo_writeLine (U" First t in y: ", our y -> x1); MelderInfo_writeLine (U"y values:"); MelderInfo_writeLine (U" Minimum y: ", ymin); MelderInfo_writeLine (U" Maximum y: ", ymax); } void structParamCurve :: v_writeText (MelderFile file) { Data_writeText (our x.get(), file); Data_writeText (our y.get(), file); } void structParamCurve :: v_readText (MelderReadText text, int formatVersion) { our x = Thing_new (Sound); our y = Thing_new (Sound); Data_readText (our x.get(), text, formatVersion); Data_readText (our y.get(), text, formatVersion); our xmin = our x -> xmin > our y -> xmin ? our x -> xmin : our y -> xmin; our xmax = our x -> xmax < our y -> xmax ? our x -> xmax : our y -> xmax; } void structParamCurve :: v_writeBinary (FILE *f) { Data_writeBinary (x.get(), f); Data_writeBinary (y.get(), f); } void structParamCurve :: v_readBinary (FILE *f, int /*formatVersion*/) { our x = Thing_new (Sound); our y = Thing_new (Sound); Data_readBinary (our x.get(), f, 2); Data_readBinary (our y.get(), f, 2); our xmin = our x -> xmin > our y -> xmin ? our x -> xmin : our y -> xmin; our xmax = our x -> xmax < our y -> xmax ? our x -> xmax : our y -> xmax; } void ParamCurve_init (ParamCurve me, Sound x, Sound y) { if (x -> xmax <= y -> xmin || x -> xmin >= y -> xmax) Melder_throw (U"Domains do not overlap."); my x = Data_copy (x); my y = Data_copy (y); my xmin = x -> xmin > y -> xmin ? x -> xmin : y -> xmin; my xmax = x -> xmax < y -> xmax ? x -> xmax : y -> xmax; } autoParamCurve ParamCurve_create (Sound x, Sound y) { try { autoParamCurve me = Thing_new (ParamCurve); ParamCurve_init (me.peek(), x, y); return me; } catch (MelderError) { Melder_throw (U"ParamCurve not created."); } } void ParamCurve_draw (ParamCurve me, Graphics g, double t1, double t2, double dt, double x1, double x2, double y1, double y2, int garnish) { if (t2 <= t1) { double tx1 = my x -> x1; double ty1 = my y -> x1; double tx2 = my x -> x1 + (my x -> nx - 1) * my x -> dx; double ty2 = my y -> x1 + (my y -> nx - 1) * my y -> dx; t1 = tx1 > ty1 ? tx1 : ty1; t2 = tx2 < ty2 ? tx2 : ty2; } if (x2 <= x1) Matrix_getWindowExtrema (my x.get(), 0, 0, 1, 1, & x1, & x2); if (x1 == x2) { x1 -= 1.0; x2 += 1.0; } if (y2 <= y1) Matrix_getWindowExtrema (my y.get(), 0, 0, 1, 1, & y1, & y2); if (y1 == y2) { y1 -= 1.0; y2 += 1.0; } if (dt <= 0.0) dt = my x -> dx < my y -> dx ? my x -> dx : my y -> dx; long numberOfPoints = (long) ceil ((t2 - t1) / dt) + 1; if (numberOfPoints > 0) { autoNUMvector x (1, numberOfPoints); autoNUMvector y (1, numberOfPoints); for (long i = 1; i <= numberOfPoints; i ++) { double t = i == numberOfPoints ? t2 : t1 + (i - 1) * dt; double index = Sampled_xToIndex (my x.get(), t); x [i] = NUM_interpolate_sinc (my x -> z [1], my x -> nx, index, 50); index = Sampled_xToIndex (my y.get(), t); y [i] = NUM_interpolate_sinc (my y -> z [1], my y -> nx, index, 50); } Graphics_setWindow (g, x1, x2, y1, y2); Graphics_setInner (g); Graphics_polyline (g, numberOfPoints, & x [1], & y [1]); Graphics_unsetInner (g); } if (garnish) { Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); } } void ParamCurve_swapXY (ParamCurve me) { autoSound help = my x.move(); my x = my y.move(); my y = help.move(); } /* End of file ParamCurve.cpp */ praat-6.0.04/fon/ParamCurve.h000066400000000000000000000043721261542461700157260ustar00rootroot00000000000000#ifndef _ParamCurve_h_ #define _ParamCurve_h_ /* ParamCurve.h * * Copyright (C) 1992-2011,2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Parametrized curve (x (t), y (t)): two functions (x and y) of one variable (the parameter t). Sampled parametrized curve (x [i], y [j]): x [i] = x (tx [i]) = x (tx1 + (i - 1) * dtx); y [i] = y (ty [i]) = y (ty1 + (i - 1) * dty); */ #include "Sound.h" #include "Graphics.h" #include "ParamCurve_def.h" oo_CLASS_CREATE (ParamCurve, Function); void ParamCurve_init (ParamCurve me, Sound x, Sound y); autoParamCurve ParamCurve_create (Sound x, Sound y); /* Return value: a newly created ParamCurve object. Failures: Out of memory. Domains do not overlap: x -> xmax <= y -> xmin || x -> xmin >= y -> xmax. Postconditions: (Result's domain is intersection of both domains:) result -> xmin = max (x -> xmin, y -> xmin); result -> xmax = min (x -> xmax, y -> xmax); */ void ParamCurve_draw (ParamCurve me, Graphics g, double t1, double t2, double dt, double x1, double x2, double y1, double y2, int garnish); /* Function: draw the points of the curve between parameter values t1 and t2, in time steps dt starting at t1 and including t2, along the axes [x1, x2] x [y1, y2]. Defaults: t2 <= t1: draw all (overlapping) points. dt <= 0.0: time step is the smaller of my x -> dx and my y -> dx. x2 <= x1: autoscaling along horizontal axis. y2 <= y1: autoscaling along vertical axis. */ void ParamCurve_swapXY (ParamCurve me); /* Reflect around y = x. Postconditions: x == old y; y == old x; */ /* End of file ParamCurve.h */ #endif praat-6.0.04/fon/ParamCurve_def.h000066400000000000000000000020161261542461700165350ustar00rootroot00000000000000/* ParamCurve_def.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT ParamCurve oo_DEFINE_CLASS (ParamCurve, Function) oo_AUTO_OBJECT (Sound, 2, x) oo_AUTO_OBJECT (Sound, 2, y) #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (ParamCurve) #undef ooSTRUCT /* End of file ParamCurve_def.h */ praat-6.0.04/fon/Photo.cpp000066400000000000000000000435211261542461700153040ustar00rootroot00000000000000/* Photo.cpp * * Copyright (C) 2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Photo.h" #include "NUM2.h" #include "Formula.h" #if defined (_WIN32) #include #elif defined (macintosh) #include "macport_on.h" #include #include "macport_off.h" #elif defined (linux) #include #endif #include "oo_DESTROY.h" #include "Photo_def.h" #include "oo_COPY.h" #include "Photo_def.h" #include "oo_EQUAL.h" #include "Photo_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Photo_def.h" #include "oo_WRITE_TEXT.h" #include "Photo_def.h" #include "oo_READ_TEXT.h" #include "Photo_def.h" #include "oo_WRITE_BINARY.h" #include "Photo_def.h" #include "oo_READ_BINARY.h" #include "Photo_def.h" #include "oo_DESCRIPTION.h" #include "Photo_def.h" Thing_implement (Photo, SampledXY, 0); void structPhoto :: v_info () { our structDaata :: v_info (); MelderInfo_writeLine (U"xmin: ", our xmin); MelderInfo_writeLine (U"xmax: ", our xmax); MelderInfo_writeLine (U"Number of columns: ", our nx); MelderInfo_writeLine (U"dx: ", our dx, U" (-> sampling rate ", 1.0 / our dx, U" )"); MelderInfo_writeLine (U"x1: ", our x1); MelderInfo_writeLine (U"ymin: ", our ymin); MelderInfo_writeLine (U"ymax: ", our ymax); MelderInfo_writeLine (U"Number of rows: ", our ny); MelderInfo_writeLine (U"dy: ", our dy, U" (-> sampling rate ", 1.0 / our dy, U" )"); MelderInfo_writeLine (U"y1: ", our y1); } void Photo_init (Photo me, double xmin, double xmax, long nx, double dx, double x1, double ymin, double ymax, long ny, double dy, double y1) { SampledXY_init (me, xmin, xmax, nx, dx, x1, ymin, ymax, ny, dy, y1); my d_red = Matrix_create (xmin, xmax, nx, dx, x1, ymin, ymax, ny, dy, y1); my d_green = Matrix_create (xmin, xmax, nx, dx, x1, ymin, ymax, ny, dy, y1); my d_blue = Matrix_create (xmin, xmax, nx, dx, x1, ymin, ymax, ny, dy, y1); my d_transparency = Matrix_create (xmin, xmax, nx, dx, x1, ymin, ymax, ny, dy, y1); } Photo Photo_create (double xmin, double xmax, long nx, double dx, double x1, double ymin, double ymax, long ny, double dy, double y1) { try { autoPhoto me = Thing_new (Photo); Photo_init (me.peek(), xmin, xmax, nx, dx, x1, ymin, ymax, ny, dy, y1); return me.transfer(); } catch (MelderError) { Melder_throw (U"Photo object not created."); } } Photo Photo_createSimple (long numberOfRows, long numberOfColumns) { try { autoPhoto me = Thing_new (Photo); Photo_init (me.peek(), 0.5, numberOfColumns + 0.5, numberOfColumns, 1, 1, 0.5, numberOfRows + 0.5, numberOfRows, 1, 1); return me.transfer(); } catch (MelderError) { Melder_throw (U"Photo object not created."); } } Photo Photo_readFromImageFile (MelderFile file) { try { #if defined (linux) cairo_surface_t *surface = cairo_image_surface_create_from_png (Melder_peek32to8 (file -> path)); //if (cairo_surface_status) // Melder_throw (U"Error opening PNG file."); long width = cairo_image_surface_get_width (surface); long height = cairo_image_surface_get_height (surface); if (width == 0 || height == 0) { cairo_surface_destroy (surface); Melder_throw (U"Error reading PNG file."); } unsigned char *imageData = cairo_image_surface_get_data (surface); long bytesPerRow = cairo_image_surface_get_stride (surface); cairo_format_t format = cairo_image_surface_get_format (surface); autoPhoto me = Photo_createSimple (height, width); if (format == CAIRO_FORMAT_ARGB32) { for (long irow = 1; irow <= height; irow ++) { uint8_t *rowAddress = imageData + bytesPerRow * (height - irow); for (long icol = 1; icol <= width; icol ++) { my d_blue -> z [irow] [icol] = (* rowAddress ++) / 255.0; my d_green -> z [irow] [icol] = (* rowAddress ++) / 255.0; my d_red -> z [irow] [icol] = (* rowAddress ++) / 255.0; my d_transparency -> z [irow] [icol] = 1.0 - (* rowAddress ++) / 255.0; } } } else if (format == CAIRO_FORMAT_RGB24) { for (long irow = 1; irow <= height; irow ++) { uint8_t *rowAddress = imageData + bytesPerRow * (height - irow); for (long icol = 1; icol <= width; icol ++) { my d_blue -> z [irow] [icol] = (* rowAddress ++) / 255.0; my d_green -> z [irow] [icol] = (* rowAddress ++) / 255.0; my d_red -> z [irow] [icol] = (* rowAddress ++) / 255.0; my d_transparency -> z [irow] [icol] = 0.0; rowAddress ++; } } } else { cairo_surface_destroy (surface); Melder_throw (U"Unsupported PNG format ", format, U"."); } cairo_surface_destroy (surface); return me.transfer(); #elif defined (_WIN32) Gdiplus::Bitmap gdiplusBitmap (Melder_peek32toW (file -> path)); long width = gdiplusBitmap. GetWidth (); long height = gdiplusBitmap. GetHeight (); if (width == 0 || height == 0) Melder_throw (U"Error reading PNG file."); autoPhoto me = Photo_createSimple (height, width); for (long irow = 1; irow <= height; irow ++) { for (long icol = 1; icol <= width; icol ++) { Gdiplus::Color gdiplusColour; gdiplusBitmap. GetPixel (icol - 1, height - irow, & gdiplusColour); my d_red -> z [irow] [icol] = (gdiplusColour. GetRed ()) / 255.0; my d_green -> z [irow] [icol] = (gdiplusColour. GetGreen ()) / 255.0; my d_blue -> z [irow] [icol] = (gdiplusColour. GetBlue ()) / 255.0; my d_transparency -> z [irow] [icol] = 1.0 - (gdiplusColour. GetAlpha ()) / 255.0; } } return me.transfer(); #elif defined (macintosh) autoPhoto me; char utf8 [500]; Melder_str32To8bitFileRepresentation_inline (file -> path, utf8); CFStringRef path = CFStringCreateWithCString (nullptr, utf8, kCFStringEncodingUTF8); CFURLRef url = CFURLCreateWithFileSystemPath (nullptr, path, kCFURLPOSIXPathStyle, false); CFRelease (path); CGImageSourceRef imageSource = CGImageSourceCreateWithURL (url, nullptr); CFRelease (url); if (! imageSource) Melder_throw (U"Cannot open picture file ", file, U"."); CGImageRef image = CGImageSourceCreateImageAtIndex (imageSource, 0, nullptr); CFRelease (imageSource); if (image) { long width = CGImageGetWidth (image); long height = CGImageGetHeight (image); me.reset (Photo_createSimple (height, width)); long bitsPerPixel = CGImageGetBitsPerPixel (image); long bitsPerComponent = CGImageGetBitsPerComponent (image); long bytesPerRow = CGImageGetBytesPerRow (image); trace ( bitsPerPixel, U" bits per pixel, ", bitsPerComponent, U" bits per component, ", bytesPerRow, U" bytes per row" ); /* * Now we probably need to use: * CGColorSpaceRef CGImageGetColorSpace (CGImageRef image); * CGImageAlphaInfo CGImageGetAlphaInfo (CGImageRef image); */ CGDataProviderRef dataProvider = CGImageGetDataProvider (image); // not retained, so don't release CFDataRef data = CGDataProviderCopyData (dataProvider); uint8_t *pixelData = (uint8_t *) CFDataGetBytePtr (data); for (long irow = 1; irow <= height; irow ++) { uint8_t *rowAddress = pixelData + bytesPerRow * (height - irow); for (long icol = 1; icol <= width; icol ++) { my d_red -> z [irow] [icol] = (*rowAddress ++) / 255.0; my d_green -> z [irow] [icol] = (*rowAddress ++) / 255.0; my d_blue -> z [irow] [icol] = (*rowAddress ++) / 255.0; my d_transparency -> z [irow] [icol] = 1.0 - (*rowAddress ++) / 255.0; } } CFRelease (data); CGImageRelease (image); } return me.transfer(); #endif } catch (MelderError) { Melder_throw (U"Picture file ", file, U" not opened as Photo."); } } #if defined (macintosh) #include #include "macport_on.h" static void _mac_releaseDataCallback (void *info, const void *data, size_t size) { (void) info; (void) size; Melder_free (data); } #endif #ifdef linux static void _lin_saveAsImageFile (Photo me, MelderFile file, const char32 *which) { cairo_format_t format = CAIRO_FORMAT_ARGB32; long bytesPerRow = cairo_format_stride_for_width (format, my nx); // likely to be my nx * 4 long numberOfRows = my ny; uint8 *imageData = Melder_malloc_f (uint8, bytesPerRow * numberOfRows); for (long irow = 1; irow <= my ny; irow ++) { uint8 *rowAddress = imageData + bytesPerRow * (my ny - irow); for (long icol = 1; icol <= my nx; icol ++) { * rowAddress ++ = round (my d_blue -> z [irow] [icol] * 255.0); * rowAddress ++ = round (my d_green -> z [irow] [icol] * 255.0); * rowAddress ++ = round (my d_red -> z [irow] [icol] * 255.0); * rowAddress ++ = 255 - round (my d_transparency -> z [irow] [icol] * 255.0); } } cairo_surface_t *surface = cairo_image_surface_create_for_data (imageData, format, my nx, my ny, bytesPerRow); cairo_surface_write_to_png (surface, Melder_peek32to8 (file -> path)); cairo_surface_destroy (surface); } #endif #ifdef _WIN32 static void _win_saveAsImageFile (Photo me, MelderFile file, const char32 *mimeType) { Gdiplus::Bitmap gdiplusBitmap (my nx, my ny, PixelFormat32bppARGB); for (long irow = 1; irow <= my ny; irow ++) { for (long icol = 1; icol <= my nx; icol ++) { Gdiplus::Color gdiplusColour ( 255 - round (my d_transparency -> z [irow] [icol] * 255.0), round (my d_red -> z [irow] [icol] * 255.0), round (my d_green -> z [irow] [icol] * 255.0), round (my d_blue -> z [irow] [icol] * 255.0)); gdiplusBitmap. SetPixel (icol - 1, my ny - irow, gdiplusColour); } } /* * The 'mimeType' parameter specifies a "class encoder". Look it up. */ UINT numberOfImageEncoders, sizeOfImageEncoderArray; Gdiplus::GetImageEncodersSize (& numberOfImageEncoders, & sizeOfImageEncoderArray); if (sizeOfImageEncoderArray == 0) Melder_throw (U"Cannot find image encoders."); Gdiplus::ImageCodecInfo *imageEncoderInfos = Melder_malloc (Gdiplus::ImageCodecInfo, sizeOfImageEncoderArray); Gdiplus::GetImageEncoders (numberOfImageEncoders, sizeOfImageEncoderArray, imageEncoderInfos); for (int iencoder = 0; iencoder < numberOfImageEncoders; iencoder ++) { trace (U"Supported MIME type: ", Melder_peekWto32 (imageEncoderInfos [iencoder]. MimeType)); if (str32equ (Melder_peekWto32 (imageEncoderInfos [iencoder]. MimeType), mimeType)) { Gdiplus::EncoderParameters *p = nullptr; Gdiplus::EncoderParameters encoderParameters; if (str32equ (mimeType, U"image/jpeg")) { encoderParameters. Count = 1; GUID guid = { 0x1D5BE4B5, 0xFA4A, 0x452D, { 0x9C, 0xDD, 0x5D, 0xB3, 0x51, 0x05, 0xE7, 0xEB }}; // EncoderQuality encoderParameters. Parameter [0]. Guid = guid; encoderParameters. Parameter [0]. Type = Gdiplus::EncoderParameterValueTypeLong; encoderParameters. Parameter [0]. NumberOfValues = 1; ULONG quality = 100; encoderParameters. Parameter [0]. Value = & quality; p = & encoderParameters; } gdiplusBitmap. Save (Melder_peek32toW (file -> path), & imageEncoderInfos [iencoder]. Clsid, p); Melder_free (imageEncoderInfos); return; } } Melder_throw (U"Unknown MIME type ", mimeType, U"."); } #endif #ifdef macintosh static void _mac_saveAsImageFile (Photo me, MelderFile file, const void *which) { long bytesPerRow = my nx * 4; long numberOfRows = my ny; unsigned char *imageData = Melder_malloc_f (unsigned char, bytesPerRow * numberOfRows); for (long irow = 1; irow <= my ny; irow ++) { uint8_t *rowAddress = imageData + bytesPerRow * (my ny - irow); for (long icol = 1; icol <= my nx; icol ++) { * rowAddress ++ = (uint8) lround (my d_red -> z [irow] [icol] * 255.0); // BUG: should be tested for speed * rowAddress ++ = (uint8) lround (my d_green -> z [irow] [icol] * 255.0); * rowAddress ++ = (uint8) lround (my d_blue -> z [irow] [icol] * 255.0); * rowAddress ++ = 255 - (uint8) lround (my d_transparency -> z [irow] [icol] * 255.0); } } static CGColorSpaceRef colourSpace = nullptr; if (! colourSpace) { colourSpace = CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB); // used to be kCGColorSpaceUserRGB Melder_assert (colourSpace); } CGDataProviderRef dataProvider = CGDataProviderCreateWithData (nullptr, imageData, bytesPerRow * numberOfRows, _mac_releaseDataCallback // needed? ); Melder_assert (dataProvider); CGImageRef image = CGImageCreate (my nx, numberOfRows, 8, 32, bytesPerRow, colourSpace, kCGImageAlphaNone, dataProvider, nullptr, false, kCGRenderingIntentDefault); CGDataProviderRelease (dataProvider); Melder_assert (image); NSString *path = (NSString *) Melder_peek32toCfstring (Melder_fileToPath (file)); CFURLRef url = (CFURLRef) [NSURL fileURLWithPath: path isDirectory: NO]; CGImageDestinationRef destination = CGImageDestinationCreateWithURL (url, (CFStringRef) which, 1, nullptr); CGImageDestinationAddImage (destination, image, nil); if (! CGImageDestinationFinalize (destination)) { //Melder_throw; } CFRelease (destination); CGColorSpaceRelease (colourSpace); CGImageRelease (image); } #endif void Photo_saveAsPNG (Photo me, MelderFile file) { #if defined (_WIN32) _win_saveAsImageFile (me, file, U"image/png"); #elif defined (macintosh) _mac_saveAsImageFile (me, file, kUTTypePNG); #elif defined (linux) _lin_saveAsImageFile (me, file, U"image/png"); #endif } void Photo_saveAsTIFF (Photo me, MelderFile file) { #if defined (_WIN32) _win_saveAsImageFile (me, file, U"image/tiff"); #elif defined (macintosh) _mac_saveAsImageFile (me, file, kUTTypeTIFF); #else (void) me; (void) file; #endif } void Photo_saveAsGIF (Photo me, MelderFile file) { #if defined (_WIN32) _win_saveAsImageFile (me, file, U"image/gif"); #elif defined (macintosh) _mac_saveAsImageFile (me, file, kUTTypeGIF); #else (void) me; (void) file; #endif } void Photo_saveAsWindowsBitmapFile (Photo me, MelderFile file) { #if defined (_WIN32) _win_saveAsImageFile (me, file, U"image/bmp"); #elif defined (macintosh) _mac_saveAsImageFile (me, file, kUTTypeBMP); #else (void) me; (void) file; #endif } void Photo_saveAsJPEG (Photo me, MelderFile file) { #if defined (_WIN32) _win_saveAsImageFile (me, file, U"image/jpeg"); #elif defined (macintosh) _mac_saveAsImageFile (me, file, kUTTypeJPEG); #else (void) me; (void) file; #endif } void Photo_saveAsJPEG2000 (Photo me, MelderFile file) { #if defined (_WIN32) _win_saveAsImageFile (me, file, U"image/jpeg2000"); #elif defined (macintosh) _mac_saveAsImageFile (me, file, kUTTypeJPEG2000); #else (void) me; (void) file; #endif } void Photo_saveAsAppleIconFile (Photo me, MelderFile file) { #if defined (_WIN32) _win_saveAsImageFile (me, file, U"image/ICNS"); #elif defined (macintosh) _mac_saveAsImageFile (me, file, kUTTypeAppleICNS); #else (void) me; (void) file; #endif } void Photo_saveAsWindowsIconFile (Photo me, MelderFile file) { #if defined (_WIN32) _win_saveAsImageFile (me, file, U"image/icon"); #elif defined (macintosh) _mac_saveAsImageFile (me, file, kUTTypeICO); #else (void) me; (void) file; #endif } void Photo_replaceRed (Photo me, Matrix red) { my d_red = Data_copy (red); } void Photo_replaceGreen (Photo me, Matrix green) { my d_green = Data_copy (green); } void Photo_replaceBlue (Photo me, Matrix blue) { my d_blue = Data_copy (blue); } void Photo_replaceTransparency (Photo me, Matrix transparency) { my d_transparency = Data_copy (transparency); } static void _Photo_cellArrayOrImage (Photo me, Graphics g, double xmin, double xmax, double ymin, double ymax, bool interpolate) { if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } long ixmin, ixmax, iymin, iymax; Sampled_getWindowSamples (me, xmin - 0.49999 * my dx, xmax + 0.49999 * my dx, & ixmin, & ixmax); SampledXY_getWindowSamplesY (me, ymin - 0.49999 * my dy, ymax + 0.49999 * my dy, & iymin, & iymax); if (ixmin > ixmax || iymin > iymax) { Melder_fatal (U"ixmin ", ixmin, U" ixmax ", ixmax, U" iymin ", iymin, U" iymax ", iymax); return; } Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); autoNUMmatrix z (iymin, iymax, ixmin, ixmax); for (long iy = iymin; iy <= iymax; iy ++) { for (long ix = ixmin; ix <= ixmax; ix ++) { z [iy] [ix]. red = my d_red -> z [iy] [ix]; z [iy] [ix]. green = my d_green -> z [iy] [ix]; z [iy] [ix]. blue = my d_blue -> z [iy] [ix]; z [iy] [ix]. transparency = my d_transparency -> z [iy] [ix]; } } if (interpolate) Graphics_image_colour (g, z.peek(), ixmin, ixmax, Sampled_indexToX (me, ixmin - 0.5), Sampled_indexToX (me, ixmax + 0.5), iymin, iymax, SampledXY_indexToY (me, iymin - 0.5), SampledXY_indexToY (me, iymax + 0.5), 0.0, 1.0); else Graphics_cellArray_colour (g, z.peek(), ixmin, ixmax, Sampled_indexToX (me, ixmin - 0.5), Sampled_indexToX (me, ixmax + 0.5), iymin, iymax, SampledXY_indexToY (me, iymin - 0.5), SampledXY_indexToY (me, iymax + 0.5), 0.0, 1.0); //Graphics_rectangle (g, xmin, xmax, ymin, ymax); Graphics_unsetInner (g); } void Photo_paintImage (Photo me, Graphics g, double xmin, double xmax, double ymin, double ymax) { _Photo_cellArrayOrImage (me, g, xmin, xmax, ymin, ymax, true); } void Photo_paintCells (Photo me, Graphics g, double xmin, double xmax, double ymin, double ymax) { _Photo_cellArrayOrImage (me, g, xmin, xmax, ymin, ymax, false); } /* End of file Photo.cpp */ praat-6.0.04/fon/Photo.h000066400000000000000000000072601261542461700147510ustar00rootroot00000000000000#ifndef _Photo_h_ #define _Photo_h_ /* Photo.h * * Copyright (C) 2013,2014 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Matrix.h" #include "Photo_def.h" oo_CLASS_CREATE (Photo, SampledXY); void Photo_init (Photo me, double xmin, double xmax, long nx, double dx, double x1, double ymin, double ymax, long ny, double dy, double y1); Photo Photo_create (double xmin, double xmax, long nx, double dx, double x1, double ymin, double ymax, long ny, double dy, double y1); /* Function: return a new opaque black Photo. Preconditions: xmin <= xmax; ymin <= ymax; nx >= 1; ny >= 1; dx > 0.0; dy > 0.0; Postconditions: result -> xmin == xmin; result -> xmax == xmax; result -> ymin == ymin; result -> ymax == ymax; result -> nx == nx; result -> ny == ny; result -> dx == dx; result -> dy == dy; result -> x1 == x1; result -> y1 == y1; result -> d_red -> z [1..ny] [1..nx] == 0.0; result -> d_green -> z [1..ny] [1..nx] == 0.0; result -> d_blue -> z [1..ny] [1..nx] == 0.0; result -> d_transparency -> z [1..ny] [1..nx] == 0.0; */ Photo Photo_createSimple (long numberOfRows, long numberOfColumns); /* Function: return a new opaque black Photo. Preconditions: numberOfRows >= 1; numberOfColumns >= 1; Postconditions: result -> xmin == 0.5; result -> xmax == numberOfColumns + 0.5; result -> ymin == 0.5; result -> ymax == numberOfRows + 0.5; result -> nx == numberOfColumns; result -> ny == numberOfRows; result -> dx == 1; result -> dy == 1; result -> x1 == 1; result -> y1 == 1; result -> d_red -> z [1..ny] [1..nx] == 0.0; result -> d_green -> z [1..ny] [1..nx] == 0.0; result -> d_blue -> z [1..ny] [1..nx] == 0.0; result -> d_transparency -> z [1..ny] [1..nx] == 0.0; */ Photo Photo_readFromImageFile (MelderFile file); double_rgbt Photo_getValueAtXY (Photo me, double x, double y); /* Linear interpolation between matrix points, constant extrapolation in cells on the edge, NUMundefined outside the union of the unit squares around the points. */ void Photo_replaceRed (Photo me, Matrix red); void Photo_replaceGreen (Photo me, Matrix green); void Photo_replaceBlue (Photo me, Matrix blue); void Photo_replaceTransparency (Photo me, Matrix transparency); void Photo_paintImage (Photo me, Graphics g, double xmin, double xmax, double ymin, double ymax); void Photo_paintCells (Photo me, Graphics g, double xmin, double xmax, double ymin, double ymax); /* Every sample is drawn as a rectangle. */ void Photo_movie (Photo me, Graphics g); void Photo_saveAsPNG (Photo me, MelderFile file); void Photo_saveAsTIFF (Photo me, MelderFile file); void Photo_saveAsGIF (Photo me, MelderFile file); void Photo_saveAsWindowsBitmapFile (Photo me, MelderFile file); void Photo_saveAsJPEG (Photo me, MelderFile file); void Photo_saveAsJPEG2000 (Photo me, MelderFile file); void Photo_saveAsAppleIconFile (Photo me, MelderFile file); void Photo_saveAsWindowsIconFile (Photo me, MelderFile file); /* End of file Photo.h */ #endif praat-6.0.04/fon/Photo_def.h000066400000000000000000000034431261542461700155660ustar00rootroot00000000000000/* Photo_def.h * * Copyright (C) 2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT Photo oo_DEFINE_CLASS (Photo, SampledXY) oo_AUTO_OBJECT (Matrix, 2, d_red) oo_AUTO_OBJECT (Matrix, 2, d_green) oo_AUTO_OBJECT (Matrix, 2, d_blue) oo_AUTO_OBJECT (Matrix, 2, d_transparency) #if oo_DECLARING void v_info () override; bool v_hasGetNrow () override { return true; } double v_getNrow () override { return ny; } bool v_hasGetNcol () override { return true; } double v_getNcol () override { return nx; } bool v_hasGetYmin () override { return true; } double v_getYmin () override { return ymin; } bool v_hasGetYmax () override { return true; } double v_getYmax () override { return ymax; } bool v_hasGetNy () override { return true; } double v_getNy () override { return ny; } bool v_hasGetDy () override { return true; } double v_getDy () override { return dy; } bool v_hasGetY () override { return true; } double v_getY (long iy) override { return y1 + (iy - 1) * dy; } #endif oo_END_CLASS (Photo) #undef ooSTRUCT /* End of file Matrix_def.h */ praat-6.0.04/fon/Pitch.cpp000066400000000000000000001060461261542461700152640ustar00rootroot00000000000000/* Pitch.cpp * * Copyright (C) 1992-2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Pitch.h" #include #include "Sound_and_Spectrum.h" #include "Matrix_and_Pitch.h" #include "oo_DESTROY.h" #include "Pitch_def.h" #include "oo_COPY.h" #include "Pitch_def.h" #include "oo_EQUAL.h" #include "Pitch_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Pitch_def.h" #include "oo_WRITE_TEXT.h" #include "Pitch_def.h" #include "oo_READ_TEXT.h" #include "Pitch_def.h" #include "oo_WRITE_BINARY.h" #include "Pitch_def.h" #include "oo_READ_BINARY.h" #include "Pitch_def.h" #include "oo_DESCRIPTION.h" #include "Pitch_def.h" #include "enums_getText.h" #include "Pitch_enums.h" #include "enums_getValue.h" #include "Pitch_enums.h" Thing_implement (Pitch, Sampled, 1); #define FREQUENCY(frame) ((frame) -> candidate [1]. frequency) #define STRENGTH(frame) ((frame) -> candidate [1]. strength) #define NOT_VOICED(f) ((f) <= 0.0 || (f) >= my ceiling) /* This includes NUMundefined! */ int structPitch :: v_getMinimumUnit (long ilevel) { return ilevel == Pitch_LEVEL_FREQUENCY ? kPitch_unit_MIN : Pitch_STRENGTH_UNIT_min; } int structPitch :: v_getMaximumUnit (long ilevel) { return ilevel == Pitch_LEVEL_FREQUENCY ? kPitch_unit_MAX : Pitch_STRENGTH_UNIT_max; } const char32 * structPitch :: v_getUnitText (long ilevel, int unit, unsigned long flags) { if (ilevel == Pitch_LEVEL_FREQUENCY) { return unit == kPitch_unit_HERTZ ? flags & Function_UNIT_TEXT_MENU ? U"Hertz" : U"Hz" : unit == kPitch_unit_HERTZ_LOGARITHMIC ? flags & Function_UNIT_TEXT_MENU ? U"Hertz (logarithmic)" : (flags & Function_UNIT_TEXT_SHORT) && (flags & Function_UNIT_TEXT_GRAPHICAL) ? U"%%Hz%" : U"Hz" : unit == kPitch_unit_MEL ? U"mel" : unit == kPitch_unit_LOG_HERTZ ? flags & Function_UNIT_TEXT_MENU ? U"logHertz" : U"logHz" : unit == kPitch_unit_SEMITONES_1 ? flags & Function_UNIT_TEXT_SHORT ? U"st__1_" : flags & Function_UNIT_TEXT_GRAPHICAL ? U"semitones %%re% 1 Hz" : U"semitones re 1 Hz" : unit == kPitch_unit_SEMITONES_100 ? flags & Function_UNIT_TEXT_SHORT ? U"st__100_" : flags & Function_UNIT_TEXT_GRAPHICAL ? U"semitones %%re% 100 Hz" : U"semitones re 100 Hz" : unit == kPitch_unit_SEMITONES_200 ? flags & Function_UNIT_TEXT_SHORT ? U"st__200_" : flags & Function_UNIT_TEXT_GRAPHICAL ? U"semitones %%re% 200 Hz" : U"semitones re 200 Hz" : unit == kPitch_unit_SEMITONES_440 ? flags & Function_UNIT_TEXT_SHORT ? U"st__a_" : flags & Function_UNIT_TEXT_GRAPHICAL ? U"semitones %%re% 440 Hz" : U"semitones re 440 Hz" : unit == kPitch_unit_ERB ? flags & Function_UNIT_TEXT_SHORT ? U"erb" : U"ERB" : U""; } else if (ilevel == Pitch_LEVEL_STRENGTH) { return unit == Pitch_STRENGTH_UNIT_AUTOCORRELATION ? U"" : unit == Pitch_STRENGTH_UNIT_NOISE_HARMONICS_RATIO ? U"" : unit == Pitch_STRENGTH_UNIT_HARMONICS_NOISE_DB ? U"dB" : U""; } return U"unknown"; } bool structPitch :: v_isUnitLogarithmic (long ilevel, int unit) { return ilevel == Pitch_LEVEL_FREQUENCY && unit == kPitch_unit_HERTZ_LOGARITHMIC; } double structPitch :: v_convertStandardToSpecialUnit (double value, long ilevel, int unit) { if (ilevel == Pitch_LEVEL_FREQUENCY) { return unit == kPitch_unit_HERTZ ? value : unit == kPitch_unit_HERTZ_LOGARITHMIC ? value <= 0.0 ? NUMundefined : log10 (value) : unit == kPitch_unit_MEL ? NUMhertzToMel (value) : unit == kPitch_unit_LOG_HERTZ ? value <= 0.0 ? NUMundefined : log10 (value) : unit == kPitch_unit_SEMITONES_1 ? value <= 0.0 ? NUMundefined : 12.0 * log (value / 1.0) / NUMln2 : unit == kPitch_unit_SEMITONES_100 ? value <= 0.0 ? NUMundefined : 12.0 * log (value / 100.0) / NUMln2 : unit == kPitch_unit_SEMITONES_200 ? value <= 0.0 ? NUMundefined : 12.0 * log (value / 200.0) / NUMln2 : unit == kPitch_unit_SEMITONES_440 ? value <= 0.0 ? NUMundefined : 12.0 * log (value / 440.0) / NUMln2 : unit == kPitch_unit_ERB ? NUMhertzToErb (value) : NUMundefined; } else { return unit == Pitch_STRENGTH_UNIT_AUTOCORRELATION ? value : unit == Pitch_STRENGTH_UNIT_NOISE_HARMONICS_RATIO ? value <= 1e-15 ? 1e15 : value > 1.0 - 1e-15 ? 1e-15 : (1.0 - value) / value : /* Before losing precision. */ unit == Pitch_STRENGTH_UNIT_HARMONICS_NOISE_DB ? value <= 1e-15 ? -150.0 : value > 1.0 - 1e-15 ? 150.0 : 10 * log10 (value / (1.0 - value)) : /* Before losing precision. */ NUMundefined; } } double structPitch :: v_convertSpecialToStandardUnit (double value, long ilevel, int unit) { if (ilevel == Pitch_LEVEL_FREQUENCY) { return unit == kPitch_unit_HERTZ ? value : unit == kPitch_unit_HERTZ_LOGARITHMIC ? pow (10.0, value) : unit == kPitch_unit_MEL ? NUMmelToHertz (value) : unit == kPitch_unit_LOG_HERTZ ? pow (10.0, value) : unit == kPitch_unit_SEMITONES_1 ? 1.0 * exp (value * (NUMln2 / 12.0)): unit == kPitch_unit_SEMITONES_100 ? 100.0 * exp (value * (NUMln2 / 12.0)): unit == kPitch_unit_SEMITONES_200 ? 200.0 * exp (value * (NUMln2 / 12.0)): unit == kPitch_unit_SEMITONES_440 ? 440.0 * exp (value * (NUMln2 / 12.0)): unit == kPitch_unit_ERB ? NUMerbToHertz (value) : NUMundefined; } else { return NUMundefined; } } #define doesUnitAllowNegativeValues(unit) \ ( (unit) == kPitch_unit_HERTZ_LOGARITHMIC || (unit) == kPitch_unit_LOG_HERTZ || \ (unit) == kPitch_unit_SEMITONES_1 || (unit) == kPitch_unit_SEMITONES_100 || \ (unit) == kPitch_unit_SEMITONES_200 || (unit) == kPitch_unit_SEMITONES_440 ) double structPitch :: v_getValueAtSample (long iframe, long ilevel, int unit) { double f = frame [iframe]. candidate [1]. frequency; if (f <= 0.0 || f >= ceiling) return NUMundefined; // frequency out of range (or NUMundefined)? Voiceless return v_convertStandardToSpecialUnit (ilevel == Pitch_LEVEL_FREQUENCY ? f : frame [iframe]. candidate [1]. strength, ilevel, unit); } bool Pitch_isVoiced_i (Pitch me, long iframe) { return NUMdefined (Sampled_getValueAtSample (me, iframe, Pitch_LEVEL_FREQUENCY, kPitch_unit_HERTZ)); } bool Pitch_isVoiced_t (Pitch me, double time) { return NUMdefined (Sampled_getValueAtX (me, time, Pitch_LEVEL_FREQUENCY, kPitch_unit_HERTZ, false)); } double Pitch_getValueAtTime (Pitch me, double time, int unit, int interpolate) { return Sampled_getValueAtX (me, time, Pitch_LEVEL_FREQUENCY, unit, interpolate); } double Pitch_getStrengthAtTime (Pitch me, double time, int unit, int interpolate) { return Sampled_getValueAtX (me, time, Pitch_LEVEL_STRENGTH, unit, interpolate); } long Pitch_countVoicedFrames (Pitch me) { return Sampled_countDefinedSamples (me, Pitch_LEVEL_FREQUENCY, kPitch_unit_HERTZ); } double Pitch_getMean (Pitch me, double tmin, double tmax, int unit) { return Sampled_getMean (me, tmin, tmax, Pitch_LEVEL_FREQUENCY, unit, true); } double Pitch_getMeanStrength (Pitch me, double tmin, double tmax, int unit) { return Sampled_getMean (me, tmin, tmax, Pitch_LEVEL_STRENGTH, unit, true); } double Pitch_getQuantile (Pitch me, double tmin, double tmax, double quantile, int unit) { double value = Sampled_getQuantile (me, tmin, tmax, quantile, Pitch_LEVEL_FREQUENCY, unit); if (value <= 0.0 && ! doesUnitAllowNegativeValues (unit)) { value = NUMundefined; } return value; } double Pitch_getStandardDeviation (Pitch me, double tmin, double tmax, int unit) { return Sampled_getStandardDeviation (me, tmin, tmax, Pitch_LEVEL_FREQUENCY, unit, true); } #define MEL(f) NUMhertzToMel (f) #define SEMITONES(f) NUMhertzToSemitones (f) #define ERB(f) NUMhertzToErb (f) void Pitch_getMaximumAndTime (Pitch me, double tmin, double tmax, int unit, int interpolate, double *return_maximum, double *return_timeOfMaximum) { Sampled_getMaximumAndX (me, tmin, tmax, Pitch_LEVEL_FREQUENCY, unit, interpolate, return_maximum, return_timeOfMaximum); if (! doesUnitAllowNegativeValues (unit) && return_maximum && *return_maximum <= 0.0) { *return_maximum = NUMundefined; /* Unlikely. */ } } double Pitch_getMaximum (Pitch me, double tmin, double tmax, int unit, int interpolate) { double maximum; Pitch_getMaximumAndTime (me, tmin, tmax, unit, interpolate, & maximum, nullptr); return maximum; } double Pitch_getTimeOfMaximum (Pitch me, double tmin, double tmax, int unit, int interpolate) { double time; Pitch_getMaximumAndTime (me, tmin, tmax, unit, interpolate, nullptr, & time); return time; } void Pitch_getMinimumAndTime (Pitch me, double tmin, double tmax, int unit, int interpolate, double *return_minimum, double *return_timeOfMinimum) { Sampled_getMinimumAndX (me, tmin, tmax, Pitch_LEVEL_FREQUENCY, unit, interpolate, return_minimum, return_timeOfMinimum); if (! doesUnitAllowNegativeValues (unit) && return_minimum && *return_minimum <= 0.0) { *return_minimum = NUMundefined; /* Not so unlikely. */ } } double Pitch_getMinimum (Pitch me, double tmin, double tmax, int unit, int interpolate) { double minimum; Pitch_getMinimumAndTime (me, tmin, tmax, unit, interpolate, & minimum, nullptr); return minimum; } double Pitch_getTimeOfMinimum (Pitch me, double tmin, double tmax, int unit, int interpolate) { double time; Pitch_getMinimumAndTime (me, tmin, tmax, unit, interpolate, nullptr, & time); return time; } static long Pitch_getMeanAbsoluteSlope (Pitch me, double *out_hertz, double *out_mel, double *out_semitones, double *out_erb, double *out_withoutOctaveJumps) { long firstVoicedFrame = 0, lastVoicedFrame = 0, nVoiced = 0; autoNUMvector frequencies (1, my nx); for (long i = 1; i <= my nx; i ++) { double frequency = my frame [i]. candidate [1]. frequency; frequencies [i] = frequency > 0.0 && frequency < my ceiling ? frequency : 0.0; if (frequencies [i] != 0.0) nVoiced ++; } for (long i = 1; i <= my nx; i ++) // look for first voiced frame if (frequencies [i] != 0.0) { firstVoicedFrame = i; break; } for (long i = my nx; i >= 1; i --) // look for last voiced frame if (frequencies [i] != 0.0) { lastVoicedFrame = i; break; } if (nVoiced > 1) { int ilast = firstVoicedFrame; double span = (lastVoicedFrame - firstVoicedFrame) * my dx, flast = frequencies [ilast]; double slopeHz = 0.0, slopeMel = 0.0, slopeSemitones = 0.0, slopeErb = 0.0, slopeRobust = 0.0; for (long i = firstVoicedFrame + 1; i <= lastVoicedFrame; i ++) if (frequencies [i] != 0.0) { double localStepSemitones = fabs (SEMITONES (frequencies [i]) - SEMITONES (flast)); slopeHz += fabs (frequencies [i] - flast); slopeMel += fabs (MEL (frequencies [i]) - MEL (flast)); slopeSemitones += localStepSemitones; slopeErb += fabs (ERB (frequencies [i]) - ERB (flast)); while (localStepSemitones >= 12.0) localStepSemitones -= 12.0; // kill octave jumps if (localStepSemitones > 6.0) localStepSemitones = 12.0 - localStepSemitones; slopeRobust += localStepSemitones; ilast = i; flast = frequencies [ilast]; } if (out_hertz) *out_hertz = slopeHz / span; if (out_mel) *out_mel = slopeMel / span; if (out_semitones) *out_semitones = slopeSemitones / span; if (out_erb) *out_erb = slopeErb / span; if (out_withoutOctaveJumps) *out_withoutOctaveJumps = slopeRobust / span; } else { if (out_hertz) *out_hertz = NUMundefined; if (out_mel) *out_mel = NUMundefined; if (out_semitones) *out_semitones = NUMundefined; if (out_erb) *out_erb = NUMundefined; if (out_withoutOctaveJumps) *out_withoutOctaveJumps = NUMundefined; } return nVoiced; } long Pitch_getMeanAbsSlope_hertz (Pitch me, double *slope) { return Pitch_getMeanAbsoluteSlope (me, slope, nullptr, nullptr, nullptr, nullptr); } long Pitch_getMeanAbsSlope_mel (Pitch me, double *slope) { return Pitch_getMeanAbsoluteSlope (me, nullptr, slope, nullptr, nullptr, nullptr); } long Pitch_getMeanAbsSlope_semitones (Pitch me, double *slope) { return Pitch_getMeanAbsoluteSlope (me, nullptr, nullptr, slope, nullptr, nullptr); } long Pitch_getMeanAbsSlope_erb (Pitch me, double *slope) { return Pitch_getMeanAbsoluteSlope (me, nullptr, nullptr, nullptr, slope, nullptr); } long Pitch_getMeanAbsSlope_noOctave (Pitch me, double *slope) { return Pitch_getMeanAbsoluteSlope (me, nullptr, nullptr, nullptr, nullptr, slope); } void structPitch :: v_info () { long nVoiced; autoNUMvector frequencies (Sampled_getSortedValues (this, Pitch_LEVEL_FREQUENCY, kPitch_unit_HERTZ, & nVoiced), 1); structDaata :: v_info (); MelderInfo_writeLine (U"Time domain:"); MelderInfo_writeLine (U" Start time: ", xmin, U" seconds"); MelderInfo_writeLine (U" End time: ", xmax, U" seconds"); MelderInfo_writeLine (U" Total duration: ", xmax - xmin, U" seconds"); MelderInfo_writeLine (U"Time sampling:"); MelderInfo_writeLine (U" Number of frames: ", nx, U" (", nVoiced, U" voiced)"); MelderInfo_writeLine (U" Time step: ", dx, U" seconds"); MelderInfo_writeLine (U" First frame centred at: ", x1, U" seconds"); MelderInfo_writeLine (U"Ceiling at: ", ceiling, U" Hz"); if (nVoiced >= 1) { // quantiles double quantile10, quantile16, quantile50, quantile84, quantile90; quantile10 = NUMquantile (nVoiced, frequencies.peek(), 0.10); quantile16 = NUMquantile (nVoiced, frequencies.peek(), 0.16); quantile50 = NUMquantile (nVoiced, frequencies.peek(), 0.50); // median quantile84 = NUMquantile (nVoiced, frequencies.peek(), 0.84); quantile90 = NUMquantile (nVoiced, frequencies.peek(), 0.90); MelderInfo_writeLine (U"\nEstimated quantiles:"); MelderInfo_write (U" 10% = ", Melder_single (quantile10), U" Hz = ", Melder_single (MEL (quantile10)), U" Mel = "); MelderInfo_writeLine (Melder_single (SEMITONES (quantile10)), U" semitones above 100 Hz = ", Melder_single (ERB (quantile10)), U" ERB"); MelderInfo_write (U" 16% = ", Melder_single (quantile16), U" Hz = ", Melder_single (MEL (quantile16)), U" Mel = "); MelderInfo_writeLine (Melder_single (SEMITONES (quantile16)), U" semitones above 100 Hz = ", Melder_single (ERB (quantile16)), U" ERB"); MelderInfo_write (U" 50% = ", Melder_single (quantile50), U" Hz = ", Melder_single (MEL (quantile50)), U" Mel = "); MelderInfo_writeLine (Melder_single (SEMITONES (quantile50)), U" semitones above 100 Hz = ", Melder_single (ERB (quantile50)), U" ERB"); MelderInfo_write (U" 84% = ", Melder_single (quantile84), U" Hz = ", Melder_single (MEL (quantile84)), U" Mel = "); MelderInfo_writeLine (Melder_single (SEMITONES (quantile84)), U" semitones above 100 Hz = ", Melder_single (ERB (quantile84)), U" ERB"); MelderInfo_write (U" 90% = ", Melder_single (quantile90), U" Hz = ", Melder_single (MEL (quantile90)), U" Mel = "); MelderInfo_writeLine (Melder_single (SEMITONES (quantile90)), U" semitones above 100 Hz = ", Melder_single (ERB (quantile90)), U" ERB"); if (nVoiced > 1) { double corr = sqrt (nVoiced / (nVoiced - 1.0)); MelderInfo_writeLine (U"\nEstimated spreading:"); MelderInfo_write (U" 84%-median = ", Melder_half ((quantile84 - quantile50) * corr), U" Hz = ", Melder_half ((MEL (quantile84) - MEL (quantile50)) * corr), U" Mel = "); MelderInfo_writeLine (Melder_half ((SEMITONES (quantile84) - SEMITONES (quantile50)) * corr), U" semitones = ", Melder_half ((ERB (quantile84) - ERB (quantile50)) * corr), U" ERB"); MelderInfo_write (U" median-16% = ", Melder_half ((quantile50 - quantile16) * corr), U" Hz = ", Melder_half ((MEL (quantile50) - MEL (quantile16)) * corr), U" Mel = "); MelderInfo_writeLine (Melder_half ((SEMITONES (quantile50) - SEMITONES (quantile16)) * corr), U" semitones = ", Melder_half ((ERB (quantile50) - ERB (quantile16)) * corr), U" ERB"); MelderInfo_write (U" 90%-10% = ", Melder_half ((quantile90 - quantile10) * corr), U" Hz = ", Melder_half ((MEL (quantile90) - MEL (quantile10)) * corr), U" Mel = "); MelderInfo_writeLine (Melder_half ((SEMITONES (quantile90) - SEMITONES (quantile10)) * corr), U" semitones = ", Melder_half ((ERB (quantile90) - ERB (quantile10)) * corr), U" ERB"); } } if (nVoiced >= 1) { // extrema, range, mean and standard deviation double minimum = Pitch_getMinimum (this, xmin, xmax, kPitch_unit_HERTZ, false); double maximum = Pitch_getMaximum (this, xmin, xmax, kPitch_unit_HERTZ, false); double meanHertz, meanMel, meanSemitones, meanErb; MelderInfo_write (U"\nMinimum ", Melder_single (minimum), U" Hz = ", Melder_single (MEL (minimum)), U" Mel = "); MelderInfo_writeLine (Melder_single (SEMITONES (minimum)), U" semitones above 100 Hz = ", Melder_single (ERB (minimum)), U" ERB"); MelderInfo_write (U"Maximum ", Melder_single (maximum), U" Hz = ", Melder_single (MEL (maximum)), U" Mel = "); MelderInfo_writeLine (Melder_single (SEMITONES (maximum)), U" semitones above 100 Hz = ", Melder_single (ERB (maximum)), U" ERB"); MelderInfo_write (U"Range ", Melder_half (maximum - minimum), U" Hz = ", Melder_single (MEL (maximum) - MEL (minimum)), U" Mel = "); MelderInfo_writeLine (Melder_half (SEMITONES (maximum) - SEMITONES (minimum)), U" semitones = ", Melder_half (ERB (maximum) - ERB (minimum)), U" ERB"); meanHertz = Pitch_getMean (this, 0, 0, kPitch_unit_HERTZ); meanMel = Pitch_getMean (this, 0, 0, kPitch_unit_MEL); meanSemitones = Pitch_getMean (this, 0, 0, kPitch_unit_SEMITONES_100); meanErb = Pitch_getMean (this, 0, 0, kPitch_unit_ERB); MelderInfo_write (U"Average: ", Melder_single (meanHertz), U" Hz = ", Melder_single (meanMel), U" Mel = "); MelderInfo_writeLine (Melder_single (meanSemitones), U" semitones above 100 Hz = ", Melder_single (meanErb), U" ERB"); if (nVoiced >= 2) { double stdevHertz = Pitch_getStandardDeviation (this, 0, 0, kPitch_unit_HERTZ); double stdevMel = Pitch_getStandardDeviation (this, 0, 0, kPitch_unit_MEL); double stdevSemitones = Pitch_getStandardDeviation (this, 0, 0, kPitch_unit_SEMITONES_100); double stdevErb = Pitch_getStandardDeviation (this, 0, 0, kPitch_unit_ERB); MelderInfo_write (U"Standard deviation: ", Melder_half (stdevHertz), U" Hz = ", Melder_half (stdevMel), U" Mel = "); MelderInfo_writeLine (Melder_half (stdevSemitones), U" semitones = ", Melder_half (stdevErb), U" ERB"); } } if (nVoiced > 1) { // variability: mean absolute slope double slopeHertz, slopeMel, slopeSemitones, slopeErb, slopeWithoutOctaveJumps; Pitch_getMeanAbsoluteSlope (this, & slopeHertz, & slopeMel, & slopeSemitones, & slopeErb, & slopeWithoutOctaveJumps); MelderInfo_write (U"\nMean absolute slope: ", Melder_half (slopeHertz), U" Hz/s = ", Melder_half (slopeMel), U" Mel/s = "); MelderInfo_writeLine (Melder_half (slopeSemitones), U" semitones/s = ", Melder_half (slopeErb), U" ERB/s"); MelderInfo_writeLine (U"Mean absolute slope without octave jumps: ", Melder_half (slopeWithoutOctaveJumps), U" semitones/s"); } } void Pitch_Frame_init (Pitch_Frame me, int nCandidates) { /* * Create without change. */ autoNUMvector candidate (1, nCandidates); /* * Change without error. */ NUMvector_free (my candidate, 1); my candidate = candidate.transfer(); my nCandidates = nCandidates; } autoPitch Pitch_create (double tmin, double tmax, long nt, double dt, double t1, double ceiling, int maxnCandidates) { try { autoPitch me = Thing_new (Pitch); Sampled_init (me.peek(), tmin, tmax, nt, dt, t1); my ceiling = ceiling; my maxnCandidates = maxnCandidates; my frame = NUMvector (1, nt); /* Put one candidate in every frame (unvoiced, silent). */ for (long it = 1; it <= nt; it ++) { Pitch_Frame_init (& my frame [it], 1); } return me; } catch (MelderError) { Melder_throw (U"Pitch not created."); } } void Pitch_setCeiling (Pitch me, double ceiling) { my ceiling = ceiling; } int Pitch_getMaxnCandidates (Pitch me) { int result = 0; for (long i = 1; i <= my nx; i ++) { int nCandidates = my frame [i]. nCandidates; if (nCandidates > result) result = nCandidates; } return result; } void Pitch_pathFinder (Pitch me, double silenceThreshold, double voicingThreshold, double octaveCost, double octaveJumpCost, double voicedUnvoicedCost, double ceiling, int pullFormants) { if (Melder_debug == 33) Melder_casual (U"Pitch path finder:" U"\nSilence threshold = ", silenceThreshold, U"\nVoicing threshold = ", voicingThreshold, U"\nOctave cost = ", octaveCost, U"\nOctave jump cost = ", octaveJumpCost, U"\nVoiced/unvoiced cost = ", voicedUnvoicedCost, U"\nCeiling = ", ceiling, U"\nPull formants = ", pullFormants); try { long maxnCandidates = Pitch_getMaxnCandidates (me); long place; volatile double maximum, value; double ceiling2 = pullFormants ? 2 * ceiling : ceiling; /* Next three lines 20011015 */ double timeStepCorrection = 0.01 / my dx; octaveJumpCost *= timeStepCorrection; voicedUnvoicedCost *= timeStepCorrection; my ceiling = ceiling; autoNUMmatrix delta (1, my nx, 1, maxnCandidates); autoNUMmatrix psi (1, my nx, 1, maxnCandidates); for (long iframe = 1; iframe <= my nx; iframe ++) { Pitch_Frame frame = & my frame [iframe]; double unvoicedStrength = silenceThreshold <= 0 ? 0 : 2 - frame->intensity / (silenceThreshold / (1 + voicingThreshold)); unvoicedStrength = voicingThreshold + (unvoicedStrength > 0 ? unvoicedStrength : 0); for (long icand = 1; icand <= frame->nCandidates; icand ++) { Pitch_Candidate candidate = & frame->candidate [icand]; int voiceless = candidate->frequency == 0 || candidate->frequency > ceiling2; delta [iframe] [icand] = voiceless ? unvoicedStrength : candidate->strength - octaveCost * NUMlog2 (ceiling / candidate->frequency); } } /* Look for the most probable path through the maxima. */ /* There is a cost for the voiced/unvoiced transition, */ /* and a cost for a frequency jump. */ for (long iframe = 2; iframe <= my nx; iframe ++) { Pitch_Frame prevFrame = & my frame [iframe - 1], curFrame = & my frame [iframe]; double *prevDelta = delta [iframe - 1], *curDelta = delta [iframe]; long *curPsi = psi [iframe]; for (long icand2 = 1; icand2 <= curFrame -> nCandidates; icand2 ++) { double f2 = curFrame -> candidate [icand2]. frequency; maximum = -1e30; place = 0; for (long icand1 = 1; icand1 <= prevFrame -> nCandidates; icand1 ++) { double f1 = prevFrame -> candidate [icand1]. frequency; double transitionCost; bool previousVoiceless = f1 <= 0 || f1 >= ceiling2; bool currentVoiceless = f2 <= 0 || f2 >= ceiling2; if (currentVoiceless) { if (previousVoiceless) { transitionCost = 0; // both voiceless } else { transitionCost = voicedUnvoicedCost; // voiced-to-unvoiced transition } } else { if (previousVoiceless) { transitionCost = voicedUnvoicedCost; // unvoiced-to-voiced transition if (Melder_debug == 30) { /* * Try to take into account a frequency jump across a voiceless stretch. */ long place1 = icand1; for (long jframe = iframe - 2; jframe >= 1; jframe --) { place1 = psi [jframe + 1] [place1]; f1 = my frame [jframe]. candidate [place1]. frequency; if (f1 > 0 && f1 < ceiling) { transitionCost += octaveJumpCost * fabs (NUMlog2 (f1 / f2)) / (iframe - jframe); break; } } } } else { transitionCost = octaveJumpCost * fabs (NUMlog2 (f1 / f2)); // both voiced } } value = prevDelta [icand1] - transitionCost + curDelta [icand2]; //if (Melder_debug == 33) Melder_casual ("Frame %ld, current candidate %ld (delta %g), previous candidate %ld (delta %g), " // "transition cost %g, value %g, maximum %g", iframe, icand2, curDelta [icand2], icand1, prevDelta [icand1], transitionCost, value, maximum); if (value > maximum) { maximum = value; place = icand1; } else if (value == maximum) { if (Melder_debug == 33) Melder_casual ( U"A tie in frame ", iframe, U", current candidate ", icand2, U", previous candidate ", icand1 ); } } curDelta [icand2] = maximum; curPsi [icand2] = place; } } /* Find the end of the most probable path. */ place = 1; maximum = delta [my nx] [place]; for (long icand = 2; icand <= my frame [my nx]. nCandidates; icand ++) { if (delta [my nx] [icand] > maximum) { place = icand; maximum = delta [my nx] [place]; } } /* Backtracking: follow the path backwards. */ for (long iframe = my nx; iframe >= 1; iframe --) { if (Melder_debug == 33) Melder_casual ( U"Frame ", iframe, U":", U" swapping candidates 1 and ", place ); Pitch_Frame frame = & my frame [iframe]; structPitch_Candidate help = frame -> candidate [1]; frame -> candidate [1] = frame -> candidate [place]; frame -> candidate [place] = help; place = psi [iframe] [place]; // This assignment is challenging to CodeWarrior 11. } /* Pull formants: devoice frames with frequencies between ceiling and ceiling2. */ if (ceiling2 > ceiling) { if (Melder_debug == 33) Melder_casual (U"Pulling formants..."); for (long iframe = my nx; iframe >= 1; iframe --) { Pitch_Frame frame = & my frame [iframe]; Pitch_Candidate winner = & frame -> candidate [1]; double f = winner -> frequency; if (f > ceiling && f <= ceiling2) { for (long icand = 2; icand <= frame -> nCandidates; icand ++) { Pitch_Candidate loser = & frame -> candidate [icand]; if (loser -> frequency == 0.0) { structPitch_Candidate help = * winner; * winner = * loser; * loser = help; break; } } } } } } catch (MelderError) { Melder_throw (me, U": path not found."); } } void Pitch_drawInside (Pitch me, Graphics g, double xmin, double xmax, double fmin, double fmax, bool speckle, int unit) { Sampled_drawInside (me, g, xmin, xmax, fmin, fmax, speckle, Pitch_LEVEL_FREQUENCY, unit); } void Pitch_draw (Pitch me, Graphics g, double tmin, double tmax, double fmin, double fmax, bool garnish, bool speckle, int unit) { Graphics_setInner (g); Pitch_drawInside (me, g, tmin, tmax, fmin, fmax, speckle, unit); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Time (s)"); Graphics_marksBottom (g, 2, true, true, false); Graphics_textLeft (g, true, Melder_cat (U"Pitch (", Function_getUnitText (me, Pitch_LEVEL_FREQUENCY, unit, Function_UNIT_TEXT_GRAPHICAL), U")")); if (Function_isUnitLogarithmic (me, Pitch_LEVEL_FREQUENCY, unit)) { Graphics_marksLeftLogarithmic (g, 6, true, true, false); } else { Graphics_marksLeft (g, 2, true, true, false); } } } void Pitch_difference (Pitch me, Pitch thee) { long nuvtov = 0, nvtouv = 0, ndfdown = 0, ndfup = 0; if (my nx != thy nx || my dx != thy dx || my x1 != thy x1) { Melder_flushError (U"Pitch_difference: these Pitches are not aligned."); return; } for (long i = 1; i <= my nx; i ++) { double myf = my frame [i]. candidate [1]. frequency, thyf = thy frame [i]. candidate [1]. frequency; int myUnvoiced = myf == 0 || myf > my ceiling; int thyUnvoiced = thyf == 0 || thyf > thy ceiling; double t = Sampled_indexToX (me, i); if (myUnvoiced && ! thyUnvoiced) { Melder_casual ( U"Frame ", i, U" time ", t, U": unvoiced to voiced." ); nuvtov ++; } else if (! myUnvoiced && thyUnvoiced) { Melder_casual ( U"Frame ", i, U" time ", t, U": voiced to unvoiced." ); nvtouv ++; } else if (! myUnvoiced && ! thyUnvoiced) { if (myf > thyf) { //Melder_casual ("Frame %ld time %f: downward frequency jump from %.5g Hz to %.5g Hz.", i, t, myf, thyf); ndfdown ++; } else if (myf < thyf) { //Melder_casual ("Frame %ld time %f: upward frequency jump from %.5g Hz to %.5g Hz.", i, t, myf, thyf); ndfup ++; } } } MelderInfo_open (); MelderInfo_writeLine (U"Difference between two Pitches:"); MelderInfo_writeLine (U"Unvoiced to voiced: ", nuvtov, U" frames."); MelderInfo_writeLine (U"Voiced to unvoiced: ", nvtouv, U" frames."); MelderInfo_writeLine (U"Downward frequency jump: ", ndfdown, U" frames."); MelderInfo_writeLine (U"Upward frequency jump: ", ndfup, U" frames."); MelderInfo_close (); } autoPitch Pitch_killOctaveJumps (Pitch me) { try { autoPitch thee = Pitch_create (my xmin, my xmax, my nx, my dx, my x1, my ceiling, 2); long nVoiced = 0, nUp = 0; double lastFrequency = 0.0; for (long i = 1; i <= my nx; i ++) { double f = my frame [i]. candidate [1]. frequency; thy frame [i]. candidate [1]. strength = my frame [i]. candidate [1]. strength; if (f > 0.0 && f < my ceiling) { nVoiced ++; if (lastFrequency != 0.0) { double fmin = lastFrequency * 0.7071, fmax = 2.0 * fmin; while (f < fmin) { f *= 2.0; nUp ++; } while (f > fmax) { f *= 0.5; nUp --; } } lastFrequency = thy frame [i]. candidate [1]. frequency = f; } } thy ceiling *= 2.0; // make room for some octave jumps while (nUp > nVoiced / 2) { for (long i = 1; i <= thy nx; i ++) thy frame [i]. candidate [1]. frequency *= 0.5; nUp -= nVoiced; } while (nUp < - nVoiced / 2) { for (long i = 1; i <= thy nx; i ++) thy frame [i]. candidate [1]. frequency *= 2.0; nUp += nVoiced; } return thee; } catch (MelderError) { Melder_throw (me, U": octave jumps not killed."); } } autoPitch Pitch_interpolate (Pitch me) { try { autoPitch thee = Pitch_create (my xmin, my xmax, my nx, my dx, my x1, my ceiling, 2); for (long i = 1; i <= my nx; i ++) { double f = my frame [i]. candidate [1]. frequency; thy frame [i]. candidate [1]. strength = 0.9; if (f > 0.0 && f < my ceiling) { thy frame [i]. candidate [1]. frequency = f; } else { long left, right; double fleft = 0.0, fright = 0.0; for (left = i - 1; left >= 1 && fleft == 0.0; left --) { fleft = my frame [left]. candidate [1]. frequency; if (fleft >= my ceiling) fleft = 0.0; } for (right = i + 1; right <= my nx && fright == 0.0; right ++) { fright = my frame [right]. candidate [1]. frequency; if (fright >= my ceiling) fright = 0.0; } if (fleft != 0.0 && fright != 0.0) thy frame [i]. candidate [1]. frequency = ((i - left) * fright + (right - i) * fleft) / (right - left); } } return thee; } catch (MelderError) { Melder_throw (me, U": not interpolated."); } } autoPitch Pitch_subtractLinearFit (Pitch me, int unit) { try { autoPitch thee = Pitch_interpolate (me); /* * Find the first and last voiced frame. */ long imin = thy nx + 1, imax = 0; for (long i = 1; i <= my nx; i ++) if (Pitch_isVoiced_i (thee.peek(), i)) { imin = i; break; } for (long i = imin + 1; i <= my nx; i ++) if (! Pitch_isVoiced_i (thee.peek(), i)) { imax = i - 1; break; } long n = imax - imin + 1; if (n < 3) return thee.transfer(); /* * Compute average pitch and time. */ double sum = 0.0; for (long i = imin; i <= imax; i ++) { sum += Sampled_getValueAtSample (thee.peek(), i, Pitch_LEVEL_FREQUENCY, unit); } double fmean = sum / n; double tmean = thy x1 + (0.5 * (imin + imax) - 1) * thy dx; /* * Compute slope. */ double numerator = 0.0, denominator = 0.0; for (long i = imin; i <= imax; i ++) { double t = thy x1 + (i - 1) * thy dx - tmean; double f = Sampled_getValueAtSample (thee.peek(), i, Pitch_LEVEL_FREQUENCY, unit) - fmean; numerator += f * t; denominator += t * t; } double slope = numerator / denominator; /* * Modify frequencies. */ for (long i = imin; i <= imax; i ++) { Pitch_Frame myFrame = & my frame [i], thyFrame = & thy frame [i]; double t = thy x1 + (i - 1) * thy dx - tmean, myFreq = FREQUENCY (myFrame); double f = Sampled_getValueAtSample (thee.peek(), i, Pitch_LEVEL_FREQUENCY, unit); f -= slope * t; if (NOT_VOICED (myFreq)) FREQUENCY (thyFrame) = 0.0; else FREQUENCY (thyFrame) = Function_convertSpecialToStandardUnit (me, f, Pitch_LEVEL_FREQUENCY, unit); } return thee; } catch (MelderError) { Melder_throw (me, U": linear fit not subtracted."); } } autoPitch Pitch_smooth (Pitch me, double bandWidth) { try { autoPitch interp = Pitch_interpolate (me); autoMatrix matrix1 = Pitch_to_Matrix (interp.peek()); autoSound sound1 = Sound_create (1, 2 * matrix1->xmin - matrix1->xmax, 2 * matrix1->xmax - matrix1->xmin, 3 * matrix1->nx, matrix1->dx, matrix1->x1 - 2 * matrix1->nx * matrix1->dx); long firstVoiced = 0, lastVoiced = 0; for (long i = 1; i <= matrix1 -> nx; i ++) { double f = matrix1 -> z [1] [i]; if (f != 0.0) { if (! firstVoiced) firstVoiced = i; lastVoiced = i; sound1 -> z [1] [i + matrix1 -> nx] = f; } } /* Extrapolate. */ double fextrap = matrix1 -> z [1] [firstVoiced]; firstVoiced += matrix1 -> nx; for (long i = 1; i < firstVoiced; i ++) sound1 -> z [1] [i] = fextrap; fextrap = matrix1 -> z [1] [lastVoiced]; lastVoiced += matrix1 -> nx; for (long i = lastVoiced + 1; i <= sound1 -> nx; i ++) sound1 -> z [1] [i] = fextrap; /* Smooth. */ autoSpectrum spectrum = Sound_to_Spectrum (sound1.peek(), true); for (long i = 1; i <= spectrum -> nx; i ++) { double f = (i - 1) * spectrum -> dx, fT = f / bandWidth, factor = exp (- fT * fT); spectrum -> z [1] [i] *= factor; spectrum -> z [2] [i] *= factor; } autoSound sound2 = Spectrum_to_Sound (spectrum.peek()); autoMatrix matrix2 = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, 1, 1, 1, 1, 1); for (long i = 1; i <= my nx; i ++) { double originalF0 = my frame [i]. candidate [1]. frequency; matrix2 -> z [1] [i] = originalF0 > 0.0 && originalF0 < my ceiling ? sound2 -> z [1] [i + matrix2 -> nx] : 0.0; } autoPitch thee = Matrix_to_Pitch (matrix2.peek()); thy ceiling = my ceiling; return thee; } catch (MelderError) { Melder_throw (me, U": not smoothed."); } } void Pitch_step (Pitch me, double step, double precision, double tmin, double tmax) { Melder_assert (precision >= 0.0 && precision < 1.0); long imin, imax; if (! Sampled_getWindowSamples (me, tmin, tmax, & imin, & imax)) return; for (long i = imin; i <= imax; i ++) { Pitch_Frame frame = & my frame [i]; double currentFrequency = frame -> candidate [1]. frequency; if (currentFrequency > 0.0 && currentFrequency < my ceiling) { double targetFrequency = currentFrequency * step; double fmin = (1 - precision) * targetFrequency; double fmax = (1 + precision) * targetFrequency; int icand, nearestCandidate = 0; double nearestDistance = my ceiling; if (fmax > my ceiling) fmax = my ceiling; for (icand = 2; icand <= frame -> nCandidates; icand ++) { double f = frame -> candidate [icand]. frequency; if (f > fmin && f < fmax) { double localDistance = fabs (f - targetFrequency); if (localDistance < nearestDistance) { nearestCandidate = icand; nearestDistance = localDistance; } } } if (nearestCandidate) { /* Swap candidates. */ struct structPitch_Candidate candidate = frame -> candidate [nearestCandidate]; frame -> candidate [nearestCandidate] = frame -> candidate [1]; frame -> candidate [1] = candidate; } } } } /* End of file Pitch.cpp */ praat-6.0.04/fon/Pitch.h000066400000000000000000000160551261542461700147310ustar00rootroot00000000000000#ifndef _Pitch_h_ #define _Pitch_h_ /* Pitch.h * * Copyright (C) 1992-2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Sampled.h" #include "Graphics.h" #include "Interpreter_decl.h" #include "Pitch_enums.h" #include "Pitch_def.h" oo_CLASS_CREATE (Pitch, Sampled); autoPitch Pitch_create (double tmin, double tmax, long nt, double dt, double t1, double ceiling, int maxnCandidates); /* Function: create an empty pitch contour (voiceless). Preconditions: tmax > tmin; nt >= 1; dt > 0.0; maxnCandidates >= 2; Postconditions: my xmin == tmin; my xmax == tmax; my nx == nt; my dx == dt; my x1 == t1; my ceiling == ceiling; my maxnCandidates == maxnCandidates; my frame [1..nt]. nCandidates == 1; my frame [1..nt]. candidate [1]. frequency == 0.0; // unvoiced my frame [1..nt]. candidate [1]. strength == 0.0; // aperiodic my frame [1..nt]. intensity == 0.0; // silent */ void Pitch_Frame_init (Pitch_Frame me, int nCandidates); /* Function: create space for a number of candidates; space already there is disposed of. Preconditions: nCandidates >= 1; Postconditions: my nCandidates == nCandidates; my candidate [1..nCandidates]. frequency == 0.0; // unvoiced my candidate [1..nCandidates]. strength == 0.0; // aperiodic my intensity == 0.0; // silent */ bool Pitch_isVoiced_i (Pitch me, long index); /* Is the frame 'index' voiced? A frame is considered voiced if the frequency of its first candidate is greater than 0.0 but less than my ceiling. Precondition: index >= 1 && index <= my nx; */ bool Pitch_isVoiced_t (Pitch me, double t); /* Are you voiced at time `t`? The answer is `true` iff `t` lies within a voiced frame. */ #define Pitch_LEVEL_FREQUENCY 1 #define Pitch_LEVEL_STRENGTH 2 #define Pitch_STRENGTH_UNIT_min 0 #define Pitch_STRENGTH_UNIT_AUTOCORRELATION 0 #define Pitch_STRENGTH_UNIT_NOISE_HARMONICS_RATIO 1 #define Pitch_STRENGTH_UNIT_HARMONICS_NOISE_DB 2 #define Pitch_STRENGTH_UNIT_max 2 #define Pitch_NEAREST 0 #define Pitch_LINEAR 1 double Pitch_getValueAtTime (Pitch me, double time, int unit, int interpolate); double Pitch_getStrengthAtTime (Pitch me, double time, int unit, int interpolate); long Pitch_countVoicedFrames (Pitch me); double Pitch_getMean (Pitch me, double tmin, double tmax, int unit); double Pitch_getMeanStrength (Pitch me, double tmin, double tmax, int unit); double Pitch_getQuantile (Pitch me, double tmin, double tmax, double quantile, int unit); double Pitch_getStandardDeviation (Pitch me, double tmin, double tmax, int unit); void Pitch_getMaximumAndTime (Pitch me, double tmin, double tmax, int unit, int interpolate, double *return_maximum, double *return_timeOfMaximum); double Pitch_getMaximum (Pitch me, double tmin, double tmax, int unit, int interpolate); double Pitch_getTimeOfMaximum (Pitch me, double tmin, double tmax, int unit, int interpolate); void Pitch_getMinimumAndTime (Pitch me, double tmin, double tmax, int unit, int interpolate, double *return_minimum, double *return_timeOfMinimum); double Pitch_getMinimum (Pitch me, double tmin, double tmax, int unit, int interpolate); double Pitch_getTimeOfMinimum (Pitch me, double tmin, double tmax, int unit, int interpolate); int Pitch_getMaxnCandidates (Pitch me); /* Returns the largest number of candidates actually attested in a frame. */ void Pitch_setCeiling (Pitch me, double ceiling); /* Postcondition: my ceiling = ceiling; */ void Pitch_pathFinder (Pitch me, double silenceThreshold, double voicingThreshold, double octaveCost, double octaveJumpCost, double voicedUnvoicedCost, double ceiling, int pullFormants); /* Drawing methods. */ #define Pitch_speckle_NO false #define Pitch_speckle_YES true void Pitch_drawInside (Pitch me, Graphics g, double tmin, double tmax, double fmin, double fmax, bool speckle, int yscale); void Pitch_draw (Pitch me, Graphics g, double tmin, double tmax, double fmin, double fmax, bool garnish, bool speckle, int yscale); /* draw a pitch contour into a Graphics. If tmax <= tmin, draw whole time domain. */ void Pitch_difference (Pitch me, Pitch thee); /* give information about frames that are different in me and thee. */ long Pitch_getMeanAbsSlope_hertz (Pitch me, double *slope); long Pitch_getMeanAbsSlope_mel (Pitch me, double *slope); long Pitch_getMeanAbsSlope_semitones (Pitch me, double *slope); long Pitch_getMeanAbsSlope_erb (Pitch me, double *slope); long Pitch_getMeanAbsSlope_noOctave (Pitch me, double *slope); /* The value returned is the number of voiced frames (nVoiced); this signals if the values are valid: 'value', 'minimum', 'maximum', and 'mean' are valid if nVoiced >= 1; 'variance' and 'slope' are valid if nVoiced >= 2. Invalid variables are always set to 0.0. 'minimum', 'maximum', 'mean', and 'variance' may be NULL. */ autoPitch Pitch_killOctaveJumps (Pitch me); /* Add octave jumps so that every pitch step, including those across unvoiced frames, does not exceed 1/2 octave. Postcondition: result -> ceiling = my ceiling * 2; */ autoPitch Pitch_interpolate (Pitch me); /* Interpolate the pitch values of unvoiced frames. */ /* No extrapolation beyond first and last voiced frames. */ autoPitch Pitch_subtractLinearFit (Pitch me, int unit); autoPitch Pitch_smooth (Pitch me, double bandWidth); /* Smoothing by convolution with Gaussian curve. Time domain: exp (- (pi t bandWidth) ^ 2) down to 8.5 % for t = +- 0.5/bandWidth Frequency domain: exp (- (f / bandWidth) ^ 2) down to 1/e for f = +- bandWidth Example: if bandWidth = 10 Hz, then the Gaussian curve has a 8.5% duration of 0.1 s, and a 1/e low-pass point of 10 Hz. Algorithm: Interpolation of pitch at internal unvoiced parts. Zeroth-degree extrapolation at edges (duration triples). FFT; multiply by Gaussian; inverse FFT. Cut back to normal duration. Undo interpolation. */ void Pitch_step (Pitch me, double step, double precision, double tmin, double tmax); /* Instead of the currently chosen candidate, choose the candidate with another ("target") frequency, determined by 'step'. E.g., for an upward octave jump, 'step' is 2. Only consider frequencies between (1 - precision) * targetFrequency and (1 - precision) * targetFrequency. Take the candidate nearest to targetFrequency, as long as that candidate is in between 0 and my ceiling. */ void Pitch_formula (Pitch me, const char32 *formula, Interpreter interpreter); /* End of file Pitch.h */ #endif praat-6.0.04/fon/PitchEditor.cpp000066400000000000000000000331061261542461700164270ustar00rootroot00000000000000/* PitchEditor.cpp * * Copyright (C) 1992-2011,2012,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Pitch_to_Sound.h" #include "PitchEditor.h" #include "EditorM.h" Thing_implement (PitchEditor, FunctionEditor, 0); #define HEIGHT_UNV 3.0 #define HEIGHT_INTENS 6.0 #define RADIUS 2.5 /********** MENU COMMANDS **********/ static void menu_cb_setCeiling (EDITOR_ARGS) { EDITOR_IAM (PitchEditor); EDITOR_FORM (U"Change ceiling", 0) POSITIVE (U"Ceiling (Hz)", U"600") EDITOR_OK Pitch pitch = (Pitch) my data; SET_REAL (U"Ceiling", pitch -> ceiling) EDITOR_DO Pitch pitch = (Pitch) my data; Editor_save (me, U"Change ceiling"); Pitch_setCeiling (pitch, GET_REAL (U"Ceiling")); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); EDITOR_END } static void menu_cb_pathFinder (EDITOR_ARGS) { EDITOR_IAM (PitchEditor); EDITOR_FORM (U"Path finder", 0) REAL (U"Silence threshold", U"0.03") REAL (U"Voicing threshold", U"0.45") REAL (U"Octave cost", U"0.01") REAL (U"Octave-jump cost", U"0.35") REAL (U"Voiced/unvoiced cost", U"0.14") POSITIVE (U"Ceiling (Hz)", U"600") BOOLEAN (U"Pull formants", 0) EDITOR_OK Pitch pitch = (Pitch) my data; SET_REAL (U"Ceiling", pitch -> ceiling) EDITOR_DO Pitch pitch = (Pitch) my data; Editor_save (me, U"Path finder"); Pitch_pathFinder (pitch, GET_REAL (U"Silence threshold"), GET_REAL (U"Voicing threshold"), GET_REAL (U"Octave cost"), GET_REAL (U"Octave-jump cost"), GET_REAL (U"Voiced/unvoiced cost"), GET_REAL (U"Ceiling"), GET_INTEGER (U"Pull formants")); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); EDITOR_END } static void menu_cb_getPitch (EDITOR_ARGS) { EDITOR_IAM (PitchEditor); if (my d_startSelection == my d_endSelection) { Melder_informationReal (Pitch_getValueAtTime ((Pitch) my data, my d_startSelection, kPitch_unit_HERTZ, 1), U"Hz"); } else { Melder_informationReal (Pitch_getMean ((Pitch) my data, my d_startSelection, my d_endSelection, kPitch_unit_HERTZ), U"Hz"); } } static void menu_cb_octaveUp (EDITOR_ARGS) { EDITOR_IAM (PitchEditor); Pitch pitch = (Pitch) my data; Editor_save (me, U"Octave up"); Pitch_step (pitch, 2.0, 0.1, my d_startSelection, my d_endSelection); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_fifthUp (EDITOR_ARGS) { EDITOR_IAM (PitchEditor); Pitch pitch = (Pitch) my data; Editor_save (me, U"Fifth up"); Pitch_step (pitch, 1.5, 0.1, my d_startSelection, my d_endSelection); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_fifthDown (EDITOR_ARGS) { EDITOR_IAM (PitchEditor); Pitch pitch = (Pitch) my data; Editor_save (me, U"Fifth down"); Pitch_step (pitch, 1 / 1.5, 0.1, my d_startSelection, my d_endSelection); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_octaveDown (EDITOR_ARGS) { EDITOR_IAM (PitchEditor); Pitch pitch = (Pitch) my data; Editor_save (me, U"Octave down"); Pitch_step (pitch, 0.5, 0.1, my d_startSelection, my d_endSelection); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_voiceless (EDITOR_ARGS) { EDITOR_IAM (PitchEditor); Pitch pitch = (Pitch) my data; long ileft = Sampled_xToHighIndex (pitch, my d_startSelection); long iright = Sampled_xToLowIndex (pitch, my d_endSelection); if (ileft < 1) ileft = 1; if (iright > pitch -> nx) iright = pitch -> nx; Editor_save (me, U"Unvoice"); for (long i = ileft; i <= iright; i ++) { Pitch_Frame frame = & pitch -> frame [i]; for (long cand = 1; cand <= frame -> nCandidates; cand ++) { if (frame -> candidate [cand]. frequency == 0.0) { struct structPitch_Candidate help = frame -> candidate [1]; frame -> candidate [1] = frame -> candidate [cand]; frame -> candidate [cand] = help; } } } FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_PitchEditorHelp (EDITOR_ARGS) { EDITOR_IAM (PitchEditor); Melder_help (U"PitchEditor"); } static void menu_cb_PitchHelp (EDITOR_ARGS) { EDITOR_IAM (PitchEditor); Melder_help (U"Pitch"); } void structPitchEditor :: v_createMenus () { PitchEditor_Parent :: v_createMenus (); Editor_addCommand (this, U"Edit", U"Change ceiling...", 0, menu_cb_setCeiling); Editor_addCommand (this, U"Edit", U"Path finder...", 0, menu_cb_pathFinder); Editor_addCommand (this, U"Query", U"-- pitch --", 0, NULL); Editor_addCommand (this, U"Query", U"Get pitch", GuiMenu_F5, menu_cb_getPitch); Editor_addMenu (this, U"Selection", 0); Editor_addCommand (this, U"Selection", U"Unvoice", 0, menu_cb_voiceless); Editor_addCommand (this, U"Selection", U"-- up and down --", 0, NULL); Editor_addCommand (this, U"Selection", U"Octave up", 0, menu_cb_octaveUp); Editor_addCommand (this, U"Selection", U"Fifth up", 0, menu_cb_fifthUp); Editor_addCommand (this, U"Selection", U"Fifth down", 0, menu_cb_fifthDown); Editor_addCommand (this, U"Selection", U"Octave down", 0, menu_cb_octaveDown); } void structPitchEditor :: v_createHelpMenuItems (EditorMenu menu) { PitchEditor_Parent :: v_createHelpMenuItems (menu); EditorMenu_addCommand (menu, U"PitchEditor help", U'?', menu_cb_PitchEditorHelp); EditorMenu_addCommand (menu, U"Pitch help", 0, menu_cb_PitchHelp); } /********** DRAWING AREA **********/ void structPitchEditor :: v_draw () { Pitch pitch = (Pitch) our data; long it, it1, it2; double dyUnv, dyIntens; Graphics_setWindow (our d_graphics, 0, 1, 0, 1); Graphics_setColour (our d_graphics, Graphics_WHITE); Graphics_fillRectangle (our d_graphics, 0, 1, 0, 1); Graphics_setColour (our d_graphics, Graphics_BLACK); Graphics_rectangle (our d_graphics, 0, 1, 0, 1); dyUnv = Graphics_dyMMtoWC (our d_graphics, HEIGHT_UNV); dyIntens = Graphics_dyMMtoWC (our d_graphics, HEIGHT_INTENS); Sampled_getWindowSamples (pitch, our d_startWindow, our d_endWindow, & it1, & it2); /* * Show pitch. */ { long df = pitch -> ceiling > 10000 ? 2000 : pitch -> ceiling > 5000 ? 1000 : pitch -> ceiling > 2000 ? 500 : pitch -> ceiling > 800 ? 200 : pitch -> ceiling > 400 ? 100 : 50; double radius; Graphics_Viewport previous; previous = Graphics_insetViewport (our d_graphics, 0, 1, dyUnv, 1 - dyIntens); Graphics_setWindow (our d_graphics, our d_startWindow, our d_endWindow, 0, pitch -> ceiling); radius = Graphics_dxMMtoWC (our d_graphics, RADIUS); /* Horizontal hair at current pitch. */ if (our d_startSelection == our d_endSelection && our d_startSelection >= our d_startWindow && our d_startSelection <= our d_endWindow) { double f = Pitch_getValueAtTime (pitch, our d_startSelection, kPitch_unit_HERTZ, Pitch_LINEAR); if (NUMdefined (f)) { Graphics_setColour (our d_graphics, Graphics_RED); Graphics_line (our d_graphics, our d_startWindow - radius, f, our d_endWindow, f); Graphics_setTextAlignment (our d_graphics, Graphics_RIGHT, Graphics_HALF); Graphics_text (our d_graphics, our d_startWindow - radius, f, Melder_fixed (f, 2)); } } /* Horizontal scaling lines. */ Graphics_setColour (our d_graphics, Graphics_BLUE); Graphics_setLineType (our d_graphics, Graphics_DOTTED); Graphics_setTextAlignment (our d_graphics, Graphics_LEFT, Graphics_HALF); for (long f = df; f <= pitch -> ceiling; f += df) { Graphics_line (our d_graphics, our d_startWindow, f, our d_endWindow, f); Graphics_text (our d_graphics, our d_endWindow + radius/2, f, f, U" Hz"); } Graphics_setLineType (our d_graphics, Graphics_DRAWN); /* Show candidates. */ for (it = it1; it <= it2; it ++) { Pitch_Frame frame = & pitch -> frame [it]; double t = Sampled_indexToX (pitch, it); double f = frame -> candidate [1]. frequency; if (f > 0.0 && f < pitch -> ceiling) { Graphics_setColour (our d_graphics, Graphics_MAGENTA); Graphics_fillCircle_mm (our d_graphics, t, f, RADIUS * 2); } Graphics_setColour (our d_graphics, Graphics_BLACK); Graphics_setTextAlignment (our d_graphics, Graphics_CENTRE, Graphics_HALF); for (int icand = 1; icand <= frame -> nCandidates; icand ++) { int strength = (int) floor (10 * frame -> candidate [icand]. strength + 0.5); f = frame -> candidate [icand]. frequency; if (strength > 9) strength = 9; if (f > 0 && f <= pitch -> ceiling) Graphics_text (our d_graphics, t, f, strength); } } Graphics_resetViewport (our d_graphics, previous); } /* * Show intensity. */ { Graphics_Viewport previous = Graphics_insetViewport (our d_graphics, 0, 1, 1 - dyIntens, 1); Graphics_setWindow (our d_graphics, our d_startWindow, our d_endWindow, 0, 1); Graphics_setColour (our d_graphics, Graphics_BLACK); Graphics_setTextAlignment (our d_graphics, Graphics_RIGHT, Graphics_HALF); Graphics_text (our d_graphics, our d_startWindow, 0.5, U"intens"); Graphics_setTextAlignment (our d_graphics, Graphics_LEFT, Graphics_HALF); Graphics_text (our d_graphics, our d_endWindow, 0.5, U"intens"); Graphics_setTextAlignment (our d_graphics, Graphics_CENTRE, Graphics_HALF); for (it = it1; it <= it2; it ++) { Pitch_Frame frame = & pitch -> frame [it]; double t = Sampled_indexToX (pitch, it); int strength = (int) floor (10 * frame -> intensity + 0.5); // map 0.0-1.0 to 0-9 if (strength > 9) strength = 9; Graphics_text (our d_graphics, t, 0.5, strength); } Graphics_resetViewport (our d_graphics, previous); } if (it1 > 1) it1 -= 1; if (it2 < pitch -> nx) it2 += 1; /* * Show voicelessness. */ { Graphics_Viewport previous = Graphics_insetViewport (our d_graphics, 0, 1, 0, dyUnv); Graphics_setColour (our d_graphics, Graphics_BLUE); Graphics_line (our d_graphics, our d_startWindow, 1, our d_endWindow, 1); Graphics_setTextAlignment (our d_graphics, Graphics_RIGHT, Graphics_HALF); Graphics_text (our d_graphics, our d_startWindow, 0.5, U"Unv"); Graphics_setTextAlignment (our d_graphics, Graphics_LEFT, Graphics_HALF); Graphics_text (our d_graphics, our d_endWindow, 0.5, U"Unv"); for (it = it1; it <= it2; it ++) { Pitch_Frame frame = & pitch -> frame [it]; double t = Sampled_indexToX (pitch, it), tleft = t - 0.5 * pitch -> dx, tright = t + 0.5 * pitch -> dx; double f = frame -> candidate [1]. frequency; if ((f > 0.0 && f < pitch -> ceiling) || tright <= our d_startWindow || tleft >= our d_endWindow) continue; if (tleft < our d_startWindow) tleft = our d_startWindow; if (tright > our d_endWindow) tright = our d_endWindow; Graphics_fillRectangle (our d_graphics, tleft, tright, 0, 1); } Graphics_setColour (our d_graphics, Graphics_BLACK); Graphics_resetViewport (our d_graphics, previous); } } void structPitchEditor :: v_play (double a_tmin, double a_tmax) { Pitch_hum ((Pitch) our data, a_tmin, a_tmax); } int structPitchEditor :: v_click (double xWC, double yWC, bool dummy) { Pitch pitch = (Pitch) our data; double dyUnv = Graphics_dyMMtoWC (d_graphics, HEIGHT_UNV); double dyIntens = Graphics_dyMMtoWC (d_graphics, HEIGHT_INTENS); double frequency = (yWC - dyUnv) / (1 - dyIntens - dyUnv) * pitch -> ceiling, tmid; double minimumDf = 1e30; int cand, bestCandidate = -1; long ibestFrame; Pitch_Frame bestFrame; ibestFrame = Sampled_xToNearestIndex (pitch, xWC); if (ibestFrame < 1) ibestFrame = 1; if (ibestFrame > pitch -> nx) ibestFrame = pitch -> nx; bestFrame = & pitch -> frame [ibestFrame]; tmid = Sampled_indexToX (pitch, ibestFrame); for (cand = 1; cand <= bestFrame -> nCandidates; cand ++) { double df = frequency - bestFrame -> candidate [cand]. frequency; if (fabs (df) < minimumDf) { minimumDf = fabs (df); bestCandidate = cand; } } if (bestCandidate != -1) { double bestFrequency = bestFrame -> candidate [bestCandidate]. frequency; double distanceWC = (frequency - bestFrequency) / pitch -> ceiling * (1 - dyIntens - dyUnv); double dx_mm = Graphics_dxWCtoMM (our d_graphics, xWC - tmid), dy_mm = Graphics_dyWCtoMM (our d_graphics, distanceWC); if (bestFrequency < pitch -> ceiling && // above ceiling: ignore ((bestFrequency <= 0.0 && fabs (xWC - tmid) <= 0.5 * pitch -> dx && frequency <= 0.0) || // voiceless: click within frame (bestFrequency > 0.0 && dx_mm * dx_mm + dy_mm * dy_mm <= RADIUS * RADIUS))) // voiced: click within circle { struct structPitch_Candidate help = bestFrame -> candidate [1]; Editor_save (this, U"Change path"); bestFrame -> candidate [1] = bestFrame -> candidate [bestCandidate]; bestFrame -> candidate [bestCandidate] = help; FunctionEditor_redraw (this); Editor_broadcastDataChanged (this); our d_startSelection = our d_endSelection = tmid; // cursor will snap to candidate return 1; } else { return PitchEditor_Parent :: v_click (xWC, yWC, dummy); // move cursor or drag selection } } return PitchEditor_Parent :: v_click (xWC, yWC, dummy); // move cursor or drag selection } autoPitchEditor PitchEditor_create (const char32 *title, Pitch pitch) { try { autoPitchEditor me = Thing_new (PitchEditor); FunctionEditor_init (me.peek(), title, pitch); return me; } catch (MelderError) { Melder_throw (U"Pitch window not created."); } } /* End of file PitchEditor.cpp */ praat-6.0.04/fon/PitchEditor.h000066400000000000000000000023731261542461700160760ustar00rootroot00000000000000#ifndef _PitchEditor_h_ #define _PitchEditor_h_ /* PitchEditor.h * * Copyright (C) 1992-2011,2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "FunctionEditor.h" #include "Pitch.h" Thing_define (PitchEditor, FunctionEditor) { void v_createMenus () override; void v_createHelpMenuItems (EditorMenu menu) override; void v_draw () override; void v_play (double tmin, double tmax) override; int v_click (double xWC, double yWC, bool shiftKeyPressed) override; }; autoPitchEditor PitchEditor_create (const char32 *title, Pitch pitch); /* End of file PitchEditor.h */ #endif praat-6.0.04/fon/PitchTier.cpp000066400000000000000000000127631261542461700161120ustar00rootroot00000000000000/* PitchTier.cpp * * Copyright (C) 1992-2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "PitchTier.h" #include "Pitch.h" Thing_implement (PitchTier, RealTier, 0); void structPitchTier :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Time domain:"); MelderInfo_writeLine (U" Start time: ", xmin, U" seconds"); MelderInfo_writeLine (U" End time: ", xmax, U" seconds"); MelderInfo_writeLine (U" Total duration: ", xmax - xmin, U" seconds"); MelderInfo_writeLine (U"Number of points: ", points -> size); MelderInfo_writeLine (U"Minimum pitch value: ", RealTier_getMinimumValue (this), U" Hz"); MelderInfo_writeLine (U"Maximum pitch value: ", RealTier_getMaximumValue (this), U" Hz"); } autoPitchTier PitchTier_create (double tmin, double tmax) { try { autoPitchTier me = Thing_new (PitchTier); RealTier_init (me.peek(), tmin, tmax); return me; } catch (MelderError) { Melder_throw (U"PitchTier not created."); } } void PitchTier_draw (PitchTier me, Graphics g, double tmin, double tmax, double fmin, double fmax, int garnish, const char32 *method) { RealTier_draw (me, g, tmin, tmax, fmin, fmax, garnish, method, U"Frequency (Hz)"); } autoPitchTier PointProcess_upto_PitchTier (PointProcess me, double frequency) { try { autoPitchTier thee = PointProcess_upto_RealTier (me, frequency, classPitchTier).static_cast_move(); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to PitchTier."); } } void PitchTier_stylize (PitchTier me, double frequencyResolution, int useSemitones) { double dfmin; for (;;) { long i, imin = 0; dfmin = 1e308; for (i = 2; i <= my points -> size - 1; i ++) { RealPoint pm = (RealPoint) my points -> item [i]; RealPoint pl = (RealPoint) my points -> item [i - 1]; RealPoint pr = (RealPoint) my points -> item [i + 1]; double expectedFrequency = pl -> value + (pr -> value - pl -> value) / (pr -> number - pl -> number) * (pm -> number - pl -> number); double df = useSemitones ? 12 * fabs (log (pm -> value / expectedFrequency)) / NUMln2: fabs (pm -> value - expectedFrequency); if (df < dfmin) { imin = i; dfmin = df; } } if (imin == 0 || dfmin > frequencyResolution) break; Collection_removeItem (my points, imin); } } static void PitchTier_writeToSpreadsheetFile (PitchTier me, MelderFile file, bool hasHeader) { autofile f = Melder_fopen (file, "w"); if (hasHeader) fprintf (f, "\"ooTextFile\"\n\"PitchTier\"\n%.17g %.17g %ld\n", my xmin, my xmax, my points -> size); for (long i = 1; i <= my points -> size; i ++) { RealPoint point = (RealPoint) my points -> item [i]; fprintf (f, "%.17g\t%.17g\n", point -> number, point -> value); } f.close (file); } void PitchTier_writeToPitchTierSpreadsheetFile (PitchTier me, MelderFile file) { try { PitchTier_writeToSpreadsheetFile (me, file, true); } catch (MelderError) { Melder_throw (me, U" not written to tab-separated PitchTier file."); } } void PitchTier_writeToHeaderlessSpreadsheetFile (PitchTier me, MelderFile file) { try { PitchTier_writeToSpreadsheetFile (me, file, false); } catch (MelderError) { Melder_throw (me, U" not written to tab-separated table file."); } } void PitchTier_shiftFrequencies (PitchTier me, double tmin, double tmax, double shift, int unit) { try { for (long i = 1; i <= my points -> size; i ++) { RealPoint point = (RealPoint) my points -> item [i]; double frequency = point -> value; if (point -> number < tmin || point -> number > tmax) continue; switch (unit) { case kPitch_unit_HERTZ: { frequency += shift; if (frequency <= 0.0) Melder_throw (U"The resulting frequency has to be greater than 0 Hz."); } break; case kPitch_unit_MEL: { frequency = NUMhertzToMel (frequency) + shift; if (frequency <= 0.0) Melder_throw (U"The resulting frequency has to be greater than 0 mel."); frequency = NUMmelToHertz (frequency); } break; case kPitch_unit_LOG_HERTZ: { frequency = pow (10.0, log10 (frequency) + shift); } break; case kPitch_unit_SEMITONES_1: { frequency = NUMsemitonesToHertz (NUMhertzToSemitones (frequency) + shift); } break; case kPitch_unit_ERB: { frequency = NUMhertzToErb (frequency) + shift; if (frequency <= 0.0) Melder_throw (U"The resulting frequency has to be greater than 0 ERB."); frequency = NUMerbToHertz (frequency); } } point -> value = frequency; } } catch (MelderError) { Melder_throw (me, U": not all frequencies were shifted."); } } void PitchTier_multiplyFrequencies (PitchTier me, double tmin, double tmax, double factor) { Melder_assert (factor > 0.0); for (long i = 1; i <= my points -> size; i ++) { RealPoint point = (RealPoint) my points -> item [i]; if (point -> number < tmin || point -> number > tmax) continue; point -> value *= factor; } } /* End of file PitchTier.cpp */ praat-6.0.04/fon/PitchTier.h000066400000000000000000000036021261542461700155470ustar00rootroot00000000000000#ifndef _PitchTier_h_ #define _PitchTier_h_ /* PitchTier.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "RealTier.h" #include "Graphics.h" #include "Sound.h" /********** class PitchTier **********/ Thing_define (PitchTier, RealTier) { void v_info () override; int v_domainQuantity () override { return MelderQuantity_TIME_SECONDS; } }; autoPitchTier PitchTier_create (double tmin, double tmax); /* Postconditions: result -> xmin == tmin; result -> xmax == tmax; result -> points -> size == 0; */ void PitchTier_shiftFrequencies (PitchTier me, double tmin, double tmax, double shift, int units); void PitchTier_multiplyFrequencies (PitchTier me, double tmin, double tmax, double factor); void PitchTier_draw (PitchTier me, Graphics g, double tmin, double tmax, double fmin, double fmax, int garnish, const char32 *method); autoPitchTier PointProcess_upto_PitchTier (PointProcess me, double frequency); void PitchTier_stylize (PitchTier me, double frequencyResolution, int useSemitones); void PitchTier_writeToPitchTierSpreadsheetFile (PitchTier me, MelderFile file); void PitchTier_writeToHeaderlessSpreadsheetFile (PitchTier me, MelderFile file); /* End of file PitchTier.h */ #endif praat-6.0.04/fon/PitchTierEditor.cpp000066400000000000000000000040521261542461700172510ustar00rootroot00000000000000/* PitchTierEditor.cpp * * Copyright (C) 1992-2011,2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "PitchTierEditor.h" #include "PitchTier_to_Sound.h" #include "EditorM.h" Thing_implement (PitchTierEditor, RealTierEditor, 0); static void menu_cb_PitchTierEditorHelp (EDITOR_ARGS) { EDITOR_IAM (PitchTierEditor); Melder_help (U"PitchTierEditor"); } static void menu_cb_PitchTierHelp (EDITOR_ARGS) { EDITOR_IAM (PitchTierEditor); Melder_help (U"PitchTier"); } void structPitchTierEditor :: v_createHelpMenuItems (EditorMenu menu) { PitchTierEditor_Parent :: v_createHelpMenuItems (menu); EditorMenu_addCommand (menu, U"PitchTierEditor help", 0, menu_cb_PitchTierEditorHelp); EditorMenu_addCommand (menu, U"PitchTier help", 0, menu_cb_PitchTierHelp); } void structPitchTierEditor :: v_play (double a_tmin, double a_tmax) { if (d_sound.data) { Sound_playPart (d_sound.data, a_tmin, a_tmax, theFunctionEditor_playCallback, this); } else { PitchTier_playPart ((PitchTier) data, a_tmin, a_tmax, false); } } autoPitchTierEditor PitchTierEditor_create (const char32 *title, PitchTier pitch, Sound sound, bool ownSound) { try { autoPitchTierEditor me = Thing_new (PitchTierEditor); RealTierEditor_init (me.peek(), title, (RealTier) pitch, sound, ownSound); return me; } catch (MelderError) { Melder_throw (U"PitchTier window not created."); } } /* End of file PitchTierEditor.cpp */ praat-6.0.04/fon/PitchTierEditor.h000066400000000000000000000041371261542461700167220ustar00rootroot00000000000000#ifndef _PitchTierEditor_h_ #define _PitchTierEditor_h_ /* PitchTierEditor.h * * Copyright (C) 1992-2011,2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "RealTierEditor.h" #include "PitchTier.h" #include "Sound.h" Thing_define (PitchTierEditor, RealTierEditor) { void v_createHelpMenuItems (EditorMenu menu) override; void v_play (double tmin, double tmax) override; double v_minimumLegalValue () override { return 0.0; } const char32 * v_quantityText () override { return U"Frequency (Hz)"; } const char32 * v_quantityKey () override { return U"Frequency"; } const char32 * v_rightTickUnits () override { return U" Hz"; } double v_defaultYmin () override { return 50.0; } double v_defaultYmax () override { return 600.0; } const char32 * v_setRangeTitle () override { return U"Set frequency range..."; } const char32 * v_defaultYminText () override { return U"50.0"; } const char32 * v_defaultYmaxText () override { return U"600.0"; } const char32 * v_yminText () override { return U"Minimum frequency (Hz)"; } const char32 * v_ymaxText () override { return U"Maximum frequency (Hz)"; } const char32 * v_yminKey () override { return U"Minimum frequency"; } const char32 * v_ymaxKey () override { return U"Maximum frequency"; } }; autoPitchTierEditor PitchTierEditor_create (const char32 *title, PitchTier pitch, Sound sound, // may be NULL bool ownSound); /* End of file PitchTierEditor.h */ #endif praat-6.0.04/fon/PitchTier_to_PointProcess.cpp000066400000000000000000000131341261542461700213150ustar00rootroot00000000000000/* PitchTier_to_PointProcess.cpp * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2007/08/12 wchar * pb 2011/06/05 */ #include "PitchTier_to_PointProcess.h" #include "Pitch_to_PitchTier.h" autoPointProcess PitchTier_to_PointProcess (PitchTier me) { try { autoPointProcess thee = PointProcess_create (my xmin, my xmax, 1000); double area = 0.5; // imagine an event half a period before the beginning long size = my points -> size; if (size == 0) return thee.transfer(); for (long interval = 0; interval <= size; interval ++) { double t1 = interval == 0 ? my xmin : ((RealPoint) my points -> item [interval]) -> number; Melder_assert (NUMdefined (t1)); double t2 = interval == size ? my xmax : ((RealPoint) my points -> item [interval + 1]) -> number; Melder_assert (NUMdefined (t2)); double f1 = ((RealPoint) my points -> item [interval == 0 ? 1 : interval]) -> value; Melder_assert (NUMdefined (f1)); double f2 = ((RealPoint) my points -> item [interval == size ? size : interval + 1]) -> value; Melder_assert (NUMdefined (f2)); area += (t2 - t1) * 0.5 * (f1 + f2); while (area >= 1.0) { double slope = (f2 - f1) / (t2 - t1), discriminant; area -= 1.0; discriminant = f2 * f2 - 2.0 * area * slope; if (discriminant < 0.0) discriminant = 0.0; // catch rounding errors PointProcess_addPoint (thee.peek(), t2 - 2.0 * area / (f2 + sqrt (discriminant))); } } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to PointProcess."); } } autoPointProcess PitchTier_Pitch_to_PointProcess (PitchTier me, Pitch vuv) { try { autoPointProcess fullPoint = PitchTier_to_PointProcess (me); autoPointProcess thee = PointProcess_create (my xmin, my xmax, fullPoint -> maxnt); /* * Copy only voiced parts to result. */ for (long i = 1; i <= fullPoint -> nt; i ++) { double t = fullPoint -> t [i]; if (Pitch_isVoiced_t (vuv, t)) { PointProcess_addPoint (thee.peek(), t); } } return thee; } catch (MelderError) { Melder_throw (me, U" & ", vuv, U": not converted to PointProcess."); } } static int PointProcess_isVoiced_t (PointProcess me, double t, double maxT) { long imid = PointProcess_getNearestIndex (me, t); if (imid == 0) return 0; double tmid = my t [imid]; int leftVoiced = imid > 1 && tmid - my t [imid - 1] <= maxT; int rightVoiced = imid < my nt && my t [imid + 1] - tmid <= maxT; if ((leftVoiced && t <= tmid) || (rightVoiced && t >= tmid)) return 1; if (leftVoiced && t < 1.5 * tmid - 0.5 * my t [imid - 1]) return 1; if (rightVoiced && t > 1.5 * tmid - 0.5 * my t [imid + 1]) return 1; return 0; } autoPointProcess PitchTier_Point_to_PointProcess (PitchTier me, PointProcess vuv, double maxT) { try { autoPointProcess fullPoint = PitchTier_to_PointProcess (me); autoPointProcess thee = PointProcess_create (my xmin, my xmax, fullPoint -> maxnt); /* * Copy only voiced parts to result. */ for (long i = 1; i <= fullPoint -> nt; i ++) { double t = fullPoint -> t [i]; if (PointProcess_isVoiced_t (vuv, t, maxT)) { PointProcess_addPoint (thee.peek(), t); } } return thee; } catch (MelderError) { Melder_throw (me, U" & ", vuv, U": not converted to PointProcess."); } } autoPitchTier PointProcess_to_PitchTier (PointProcess me, double maximumInterval) { try { autoPitchTier thee = PitchTier_create (my xmin, my xmax); for (long i = 1; i < my nt; i ++) { double interval = my t [i + 1] - my t [i]; if (interval <= maximumInterval) { RealTier_addPoint (thee.peek(), my t [i] + 0.5 * interval, 1.0 / interval); } } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to PitchTier."); } } autoPitchTier Pitch_PointProcess_to_PitchTier (Pitch me, PointProcess pp) { try { autoPitchTier temp = Pitch_to_PitchTier (me); autoPitchTier thee = PitchTier_PointProcess_to_PitchTier (temp.peek(), pp); return thee; } catch (MelderError) { Melder_throw (me, U" & ", pp, U": not converted to PitchTier."); } } autoPitchTier PitchTier_PointProcess_to_PitchTier (PitchTier me, PointProcess pp) { try { if (my points -> size == 0) Melder_throw (U"No pitch points."); autoPitchTier thee = PitchTier_create (pp -> xmin, pp -> xmax); for (long i = 1; i <= pp -> nt; i ++) { double time = pp -> t [i]; double value = RealTier_getValueAtTime (me, time); RealTier_addPoint (thee.peek(), time, value); } return thee; } catch (MelderError) { Melder_throw (me, U" & ", pp, U": not converted to PitchTier."); } } autoTableOfReal PitchTier_downto_TableOfReal (PitchTier me, int useSemitones) { try { autoTableOfReal thee = RealTier_downto_TableOfReal (me, U"Time", U"F0"); if (useSemitones) for (long i = 1; i <= thy numberOfRows; i ++) thy data [i] [2] = NUMhertzToSemitones (thy data [i] [2]); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to TableOfReal."); } } /* End of file PitchTier_to_PointProcess.cpp */ praat-6.0.04/fon/PitchTier_to_PointProcess.h000066400000000000000000000033441261542461700207640ustar00rootroot00000000000000/* PitchTier_to_PointProcess.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "PitchTier.h" #include "PointProcess.h" #include "Pitch.h" autoPointProcess PitchTier_to_PointProcess (PitchTier me); autoPointProcess PitchTier_Pitch_to_PointProcess (PitchTier me, Pitch vuv); /* Keeps only the parts that are voiced according to 'vuv'. */ /* Voiced means: inside voiced frame of 'pitch'. */ autoPointProcess PitchTier_Point_to_PointProcess (PitchTier me, PointProcess vuv, double maxT); /* Keeps only the parts that are voiced according to 'vuv'. */ /* Voiced means: within an interval no longer than 'maxT', */ /* or within half an adjacent short-enough interval from any pulse. */ autoPitchTier PointProcess_to_PitchTier (PointProcess me, double maximumInterval); autoPitchTier Pitch_PointProcess_to_PitchTier (Pitch me, PointProcess pp); autoPitchTier PitchTier_PointProcess_to_PitchTier (PitchTier me, PointProcess pp); autoTableOfReal PitchTier_downto_TableOfReal (PitchTier me, int useSemitones); /* End of file PitchTier_to_PointProcess.h */ praat-6.0.04/fon/PitchTier_to_Sound.cpp000066400000000000000000000105201261542461700177510ustar00rootroot00000000000000/* PitchTier_to_Sound.cpp * * Copyright (C) 1992-2011 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2004/10/03 sine wave generation * pb 2005/07/08 PitchTier_to_Sound_phonation * pb 2006/12/30 new Sound_create API * pb 2007/02/25 changed default sampling frequency to 44100 Hz * pb 2008/01/19 double * pb 2011/06/05 C++ */ #include "PitchTier_to_Sound.h" #include "PitchTier_to_PointProcess.h" #include "PointProcess_and_Sound.h" autoSound PitchTier_to_Sound_pulseTrain (PitchTier me, double samplingFrequency, double adaptFactor, double adaptTime, long interpolationDepth, bool hum) { static double formant [1 + 6] = { 0.0, 600.0, 1400.0, 2400.0, 3400.0, 4500.0, 5500.0 }; static double bandwidth [1 + 6] = { 0.0, 50.0, 100.0, 200.0, 300.0, 400.0, 500.0 }; try { autoPointProcess point = PitchTier_to_PointProcess (me); autoSound sound = PointProcess_to_Sound_pulseTrain (point.peek(), samplingFrequency, adaptFactor, adaptTime, interpolationDepth); if (hum) { Sound_filterWithFormants (sound.peek(), 0.0, 0.0, 6, formant, bandwidth); } return sound; } catch (MelderError) { Melder_throw (me, U": not converted to Sound (pulse train)."); } } autoSound PitchTier_to_Sound_phonation (PitchTier me, double samplingFrequency, double adaptFactor, double maximumPeriod, double openPhase, double collisionPhase, double power1, double power2, bool hum) { static double formant [1 + 6] = { 0.0, 600.0, 1400.0, 2400.0, 3400.0, 4500.0, 5500.0 }; static double bandwidth [1 + 6] = { 0.0, 50.0, 100.0, 200.0, 300.0, 400.0, 500.0 }; try { autoPointProcess point = PitchTier_to_PointProcess (me); autoSound sound = PointProcess_to_Sound_phonation (point.peek(), samplingFrequency, adaptFactor, maximumPeriod, openPhase, collisionPhase, power1, power2); if (hum) { Sound_filterWithFormants (sound.peek(), 0.0, 0.0, 6, formant, bandwidth); } return sound; } catch (MelderError) { Melder_throw (me, U": not converted to Sound (phonation)."); } } void PitchTier_playPart (PitchTier me, double tmin, double tmax, bool hum) { try { autoSound sound = PitchTier_to_Sound_pulseTrain (me, 44100.0, 0.7, 0.05, 30, hum); Sound_playPart (sound.peek(), tmin, tmax, nullptr, nullptr); } catch (MelderError) { Melder_throw (me, U": not played."); } } void PitchTier_play (PitchTier me) { PitchTier_playPart (me, my xmin, my xmax, false); } void PitchTier_hum (PitchTier me) { PitchTier_playPart (me, my xmin, my xmax, true); } autoSound PitchTier_to_Sound_sine (PitchTier me, double tmin, double tmax, double samplingFrequency) { try { if (tmax <= tmin) tmin = my xmin, tmax = my xmax; long numberOfSamples = 1 + (long) floor ((my xmax - my xmin) * samplingFrequency); // >= 1 double samplingPeriod = 1.0 / samplingFrequency; double tmid = (tmin + tmax) / 2.0; double t1 = tmid - 0.5 * (numberOfSamples - 1) * samplingPeriod; autoSound thee = Sound_create (1, tmin, tmax, numberOfSamples, samplingPeriod, t1); double phase = 0.0; for (long isamp = 2; isamp <= numberOfSamples; isamp ++) { double tleft = t1 + (isamp - 1.5) * samplingPeriod; double fleft = RealTier_getValueAtTime (me, tleft); phase += fleft * thy dx; thy z [1] [isamp] = 0.5 * sin (2.0 * NUMpi * phase); } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Sound (sine)."); } } void PitchTier_playPart_sine (PitchTier me, double tmin, double tmax) { try { if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } // autowindowing autoSound sound = PitchTier_to_Sound_sine (me, tmin, tmax, 44100.0); Sound_playPart (sound.peek(), tmin, tmax, nullptr, nullptr); } catch (MelderError) { Melder_throw (me, U": not played."); } } /* End of file PitchTier_to_Sound.cpp */ praat-6.0.04/fon/PitchTier_to_Sound.h000066400000000000000000000030151261542461700174170ustar00rootroot00000000000000/* PitchTier_to_Sound.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "PitchTier.h" #include "Sound.h" autoSound PitchTier_to_Sound_pulseTrain (PitchTier me, double samplingFrequency, double adaptFactor, double adaptTime, long interpolationDepth, bool hum); autoSound PitchTier_to_Sound_phonation (PitchTier me, double samplingFrequency, double adaptFactor, double maximumPeriod, double openPhase, double collisionPhase, double power1, double power2, bool hum); void PitchTier_playPart (PitchTier me, double tmin, double tmax, bool hum); void PitchTier_play (PitchTier me); void PitchTier_hum (PitchTier me); autoSound PitchTier_to_Sound_sine (PitchTier me, double tmin, double tmax, double samplingFrequency); void PitchTier_playPart_sine (PitchTier me, double tmin, double tmax); /* End of file PitchTier_to_Sound.h */ praat-6.0.04/fon/Pitch_AnyTier_to_PitchTier.cpp000066400000000000000000000060011261542461700213620ustar00rootroot00000000000000/* Pitch_AnyTier_to_PitchTier.cpp * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2005/06/16 units * pb 2011/06/04 C++ */ #include "Pitch_AnyTier_to_PitchTier.h" #include "Pitch_to_PitchTier.h" autoPitchTier PitchTier_AnyTier_to_PitchTier (PitchTier pitch, AnyTier tier) { try { SortedSetOfDouble points = tier -> points; if (pitch -> points -> size == 0) Melder_throw (U"No pitch points."); /* * Result's domain is a union of both domains. */ autoPitchTier thee = PitchTier_create ( pitch -> xmin < tier -> xmin ? pitch -> xmin : tier -> xmin, pitch -> xmax > tier -> xmax ? pitch -> xmax : tier -> xmax); /* * Copy pitch's frequencies at tier's points to the resulting PitchTier. */ for (long ipoint = 1; ipoint <= points -> size; ipoint ++) { AnyPoint point = (AnyPoint) points -> item [ipoint]; double time = point -> number; double frequency = RealTier_getValueAtTime (pitch, time); RealTier_addPoint (thee.peek(), time, frequency); } return thee; } catch (MelderError) { Melder_throw (pitch, U" & ", tier, U": not converted to PitchTier."); } } autoPitchTier Pitch_AnyTier_to_PitchTier (Pitch pitch, AnyTier tier, int checkMethod) { try { SortedSetOfDouble points = tier -> points; if (checkMethod == 2) { autoPitchTier temp = Pitch_to_PitchTier (pitch); autoPitchTier thee = PitchTier_AnyTier_to_PitchTier (temp.peek(), tier); return thee.transfer(); } /* * Result's domain is a union of both domains. */ autoPitchTier thee = PitchTier_create ( pitch -> xmin < tier -> xmin ? pitch -> xmin : tier -> xmin, pitch -> xmax > tier -> xmax ? pitch -> xmax : tier -> xmax); /* * Copy pitch's frequencies at tier's points to the resulting PitchTier. */ for (long ipoint = 1; ipoint <= points -> size; ipoint ++) { AnyPoint point = (AnyPoint) points -> item [ipoint]; double time = point -> number; double frequency = Pitch_getValueAtTime (pitch, time, kPitch_unit_HERTZ, Pitch_LINEAR); if (frequency == NUMundefined && checkMethod) Melder_throw (U"No periodicity at time ", time, U" seconds."); RealTier_addPoint (thee.peek(), time, frequency); } return thee; } catch (MelderError) { Melder_throw (pitch, U" & ", tier, U": not converted to PitchTier."); } } /* End of file Pitch_AnyTier_to_PitchTier.cpp */ praat-6.0.04/fon/Pitch_AnyTier_to_PitchTier.h000066400000000000000000000020451261542461700210330ustar00rootroot00000000000000/* Pitch_AnyTier_to_PitchTier.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Pitch.h" #include "AnyTier.h" #include "PitchTier.h" autoPitchTier Pitch_AnyTier_to_PitchTier (Pitch pitch, AnyTier tier, int checkMethod); autoPitchTier PitchTier_AnyTier_to_PitchTier (PitchTier pitch, AnyTier tier); /* End of file Pitch_AnyTier_to_PitchTier.h */ praat-6.0.04/fon/Pitch_Intensity.cpp000066400000000000000000000054731261542461700173340ustar00rootroot00000000000000/* Pitch_Intensity.cpp * * Copyright (C) 1992-2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2005/03/08 connect * pb 2005/06/17 units * pb 2011/06/04 C++ */ #include "Pitch_Intensity.h" static void Pitch_getExtrema (Pitch me, double *minimum, double *maximum) { *minimum = 1e30, *maximum = -1e30; for (long i = 1; i <= my nx; i ++) { double frequency = my frame [i]. candidate [1]. frequency; if (frequency == 0.0) continue; /* Voiceless. */ if (frequency < *minimum) *minimum = frequency; if (frequency > *maximum) *maximum = frequency; } if (*maximum == -1e30) *maximum = 0.0; if (*minimum == 1e30) *minimum = 0.0; } void Pitch_Intensity_draw (Pitch pitch, Intensity intensity, Graphics g, double f1, double f2, double s1, double s2, int garnish, int connect) { if (f2 <= f1) Pitch_getExtrema (pitch, & f1, & f2); if (f1 == 0.0) return; /* All voiceless. */ if (f1 == f2) { f1 -= 1.0; f2 += 1.0; } if (s2 <= s1) Matrix_getWindowExtrema (intensity, 0, 0, 1, 1, & s1, & s2); if (s1 == s2) { s1 -= 1.0; s2 += 1.0; } Graphics_setWindow (g, f1, f2, s1, s2); Graphics_setInner (g); long previousI = 0; double previousX = NUMundefined, previousY = NUMundefined; for (long i = 1; i <= pitch -> nx; i ++) { double t = Sampled_indexToX (pitch, i); double x = pitch -> frame [i]. candidate [1]. frequency; double y = Sampled_getValueAtX (intensity, t, Pitch_LEVEL_FREQUENCY, kPitch_unit_HERTZ, true); if (x == 0) { continue; /* Voiceless. */ } if (connect & 1) Graphics_speckle (g, x, y); if ((connect & 2) && NUMdefined (previousX)) { if (previousI >= 1 && previousI < i - 1) { Graphics_setLineType (g, Graphics_DOTTED); } Graphics_line (g, previousX, previousY, x, y); Graphics_setLineType (g, Graphics_DRAWN); } previousX = x; previousY = y; previousI = i; } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Fundamental frequency (Hz)"); Graphics_marksBottom (g, 2, true, true, false); Graphics_textLeft (g, true, U"Intensity (dB)"); Graphics_marksLeft (g, 2, true, true, false); } } /* End of file Pitch_Intensity.cpp */ praat-6.0.04/fon/Pitch_Intensity.h000066400000000000000000000017671261542461700170030ustar00rootroot00000000000000/* Pitch_Intensity.h * * Copyright (C) 1992-2011 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Pitch.h" #include "Intensity.h" #include "Graphics.h" void Pitch_Intensity_draw (Pitch pitch, Intensity intensity, Graphics g, double f1, double f2, double s1, double s2, int garnish, int connect); /* End of file Pitch_Intensity.h */ praat-6.0.04/fon/Pitch_def.h000066400000000000000000000066011261542461700155430ustar00rootroot00000000000000/* Pitch_def.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Attributes: xmin // Start time (seconds). xmax > xmin // End time (seconds). nx >= 1 // Number of time slices. dx > 0.0 // Time step (seconds). x1 // Centre of first time slice (seconds). ceiling // Candidates with a higher frequency are unvoiced. maxnCandidates >= 1 // Maximum number of candidates per time slice. frame[1..nx].nCandidates // Number of candidates in each time slice, including the unvoiced candidate. frame[1..nx].candidate[1..nCandidates].frequency // The frequency of each candidate (Hz), 0 means aperiodic or silent. // candidate[1].frequency is the frequency of the currently best candidate. frame[1..nx].candidate[1..nCandidates].strength // The strength of each candidate, a real number between 0 and 1: // 0 means not periodic at all, 1 means perfectly periodic; // if the frequency of the candidate is 0, its strength is a real number // that represents the maximum periodicity that // can still be considered to be due to noise (e.g., 0.4). // candidate[1].strength is the strength of the currently best candidate. frame[1..nx].intensity // The relative intensity of each frame, a real number between 0 and 1. */ #define ooSTRUCT Pitch_Candidate oo_DEFINE_STRUCT (Pitch_Candidate) oo_DOUBLE (frequency) oo_DOUBLE (strength) oo_END_STRUCT (Pitch_Candidate) #undef ooSTRUCT #define ooSTRUCT Pitch_Frame oo_DEFINE_STRUCT (Pitch_Frame) #if oo_READING_BINARY if (formatVersion < 0) { oo_INT (nCandidates) oo_FLOAT (intensity) } else if (formatVersion == 0) { oo_FLOAT (intensity) oo_LONG (nCandidates) } else { oo_DOUBLE (intensity) oo_LONG (nCandidates) } #else oo_DOUBLE (intensity) oo_LONG (nCandidates) #endif oo_STRUCT_VECTOR (Pitch_Candidate, candidate, nCandidates) oo_END_STRUCT (Pitch_Frame) #undef ooSTRUCT #define ooSTRUCT Pitch oo_DEFINE_CLASS (Pitch, Sampled) oo_DOUBLE (ceiling) oo_INT (maxnCandidates) oo_STRUCT_VECTOR (Pitch_Frame, frame, nx) #if oo_DECLARING void v_info () override; int v_domainQuantity () override { return MelderQuantity_TIME_SECONDS; } int v_getMinimumUnit (long ilevel) override; int v_getMaximumUnit (long ilevel) override; const char32 * v_getUnitText (long ilevel, int unit, unsigned long flags) override; bool v_isUnitLogarithmic (long ilevel, int unit) override; double v_convertStandardToSpecialUnit (double value, long ilevel, int unit) override; double v_convertSpecialToStandardUnit (double value, long ilevel, int unit) override; double v_getValueAtSample (long isamp, long ilevel, int unit) override; #endif oo_END_CLASS (Pitch) #undef ooSTRUCT /* End of file Pitch_def.h */ praat-6.0.04/fon/Pitch_enums.h000066400000000000000000000025501261542461700161330ustar00rootroot00000000000000/* Pitch_enums.h * * Copyright (C) 1992-2007,2013,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ enums_begin (kPitch_unit, 0) enums_add (kPitch_unit, 0, HERTZ, U"Hertz") enums_add (kPitch_unit, 1, HERTZ_LOGARITHMIC, U"Hertz (logarithmic)") enums_add (kPitch_unit, 2, MEL, U"mel") enums_add (kPitch_unit, 3, LOG_HERTZ, U"logHertz") enums_add (kPitch_unit, 4, SEMITONES_1, U"semitones re 1 Hz") enums_add (kPitch_unit, 5, SEMITONES_100, U"semitones re 100 Hz") enums_add (kPitch_unit, 6, SEMITONES_200, U"semitones re 200 Hz") enums_add (kPitch_unit, 7, SEMITONES_440, U"semitones re 440 Hz") enums_add (kPitch_unit, 8, ERB, U"ERB") enums_end (kPitch_unit, 8, HERTZ) /* End of file Pitch_enums.h */ praat-6.0.04/fon/Pitch_to_PitchTier.cpp000066400000000000000000000117111261542461700177330ustar00rootroot00000000000000/* Pitch_to_PitchTier.cpp * * Copyright (C) 1992-2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 1998/03/19 * pb 2002/07/16 GPL * pb 2010/10/19 allow drawing without speckles * pb 2011/06/04 C++ */ #include "Pitch_to_PitchTier.h" autoPitchTier Pitch_to_PitchTier (Pitch me) { try { autoPitchTier thee = PitchTier_create (my xmin, my xmax); for (long i = 1; i <= my nx; i ++) { double frequency = my frame [i]. candidate [1]. frequency; /* * Count only voiced frames. */ if (frequency > 0.0 && frequency < my ceiling) { double time = Sampled_indexToX (me, i); RealTier_addPoint (thee.peek(), time, frequency); } } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to PitchTier."); } } static void Pitch_line (Pitch me, Graphics g, double tmin, double fleft, double tmax, double fright, int nonPeriodicLineType) { /* * f = fleft + (t - tmin) * (fright - fleft) / (tmax - tmin); */ int lineType = Graphics_inqLineType (g); double lineWidth = Graphics_inqLineWidth (g); double slope = (fright - fleft) / (tmax - tmin); long imin = Sampled_xToNearestIndex (me, tmin); if (imin < 1) imin = 1; long imax = Sampled_xToNearestIndex (me, tmax); if (imax > my nx) imax = my nx; for (long i = imin; i <= imax; i ++) { double tleft, tright; if (! Pitch_isVoiced_i (me, i)) { if (nonPeriodicLineType == 2) continue; Graphics_setLineType (g, Graphics_DOTTED); Graphics_setLineWidth (g, 0.67 * lineWidth); } else if (nonPeriodicLineType != 2) { Graphics_setLineWidth (g, 2 * lineWidth); } tleft = Sampled_indexToX (me, i) - 0.5 * my dx, tright = tleft + my dx; if (tleft < tmin) tleft = tmin; if (tright > tmax) tright = tmax; Graphics_line (g, tleft, fleft + (tleft - tmin) * slope, tright, fleft + (tright - tmin) * slope); Graphics_setLineType (g, lineType); Graphics_setLineWidth (g, lineWidth); } } void PitchTier_Pitch_draw (PitchTier me, Pitch uv, Graphics g, double tmin, double tmax, double fmin, double fmax, int nonPeriodicLineType, int garnish, const char32 *method) { long n = my points -> size, imin, imax, i; if (nonPeriodicLineType == 0) { PitchTier_draw (me, g, tmin, tmax, fmin, fmax, garnish, method); return; } if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } Graphics_setWindow (g, tmin, tmax, fmin, fmax); Graphics_setInner (g); imin = AnyTier_timeToHighIndex (me, tmin); imax = AnyTier_timeToLowIndex (me, tmax); if (n == 0) { } else if (imax < imin) { double fleft = RealTier_getValueAtTime (me, tmin); double fright = RealTier_getValueAtTime (me, tmax); Pitch_line (uv, g, tmin, fleft, tmax, fright, nonPeriodicLineType); } else for (i = imin; i <= imax; i ++) { RealPoint point = (RealPoint) my points -> item [i]; double t = point -> number, f = point -> value; Graphics_speckle (g, t, f); if (i == 1) Pitch_line (uv, g, tmin, f, t, f, nonPeriodicLineType); else if (i == imin) Pitch_line (uv, g, t, f, tmin, RealTier_getValueAtTime (me, tmin), nonPeriodicLineType); if (i == n) Pitch_line (uv, g, t, f, tmax, f, nonPeriodicLineType); else if (i == imax) Pitch_line (uv, g, t, f, tmax, RealTier_getValueAtTime (me, tmax), nonPeriodicLineType); else { RealPoint pointRight = (RealPoint) my points -> item [i + 1]; Pitch_line (uv, g, t, f, pointRight -> number, pointRight -> value, nonPeriodicLineType); } } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Time (s)"); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); Graphics_textLeft (g, true, U"Frequency (Hz)"); } } autoPitch Pitch_PitchTier_to_Pitch (Pitch me, PitchTier tier) { try { if (tier -> points -> size == 0) Melder_throw (U"No pitch points."); autoPitch thee = Data_copy (me); for (long iframe = 1; iframe <= my nx; iframe ++) { Pitch_Frame frame = & thy frame [iframe]; Pitch_Candidate cand = & frame -> candidate [1]; if (cand -> frequency > 0.0 && cand -> frequency <= my ceiling) cand -> frequency = RealTier_getValueAtTime (tier, Sampled_indexToX (me, iframe)); cand -> strength = 0.9; frame -> nCandidates = 1; } return thee; } catch (MelderError) { Melder_throw (me, U" & ", tier, U": not converted to Pitch."); } } /* End of file Pitch_to_PitchTier.cpp */ praat-6.0.04/fon/Pitch_to_PitchTier.h000066400000000000000000000024341261542461700174020ustar00rootroot00000000000000/* Pitch_to_PitchTier.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Pitch.h" #include "PitchTier.h" autoPitchTier Pitch_to_PitchTier (Pitch me); /* Creates a PitchTier from an existing Pitch contour. The best candidate in each frame becomes a target in the result. Unvoiced frames are not converted. */ void PitchTier_Pitch_draw (PitchTier me, Pitch uv, Graphics g, double tmin, double tmax, double fmin, double fmax, int nonPeriodicLineType, int garnish, const char32 *method); autoPitch Pitch_PitchTier_to_Pitch (Pitch me, PitchTier tier); /* End of file Pitch_to_PitchTier.h */ praat-6.0.04/fon/Pitch_to_PointProcess.cpp000066400000000000000000000307551261542461700205010ustar00rootroot00000000000000/* Pitch_to_PointProcess.cpp * * Copyright (C) 1992-2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2003/02/26 Sound_Pitch_to_PointProcess_peaks * pb 2003/05/17 introduced silence threshold * pb 2003/05/20 removed bug in global peak * pb 2003/05/22 changed 1.2 to 1.25 * pb 2004/05/11 undefined pitch is NUMundefined rather than 0.0 * pb 2004/11/01 Pitch_getVoicedIntervalAfter clips to my xmax * pb 2004/11/28 repaired memory leak in Pitch_to_PointProcess * pb 2004/11/28 truncated tleft in Pitch_getVoicedIntervalAfter to my xmin (otherwise, getValue can crash) * pb 2005/06/16 units * pb 2007/01/26 compatible with stereo sounds * pb 2008/01/19 double * pb 2011/06/04 C++ */ #include "Pitch_to_PointProcess.h" #include "PitchTier_to_PointProcess.h" #include "Pitch_to_PitchTier.h" #include autoPointProcess Pitch_to_PointProcess (Pitch pitch) { try { autoPitchTier pitchTier = Pitch_to_PitchTier (pitch); autoPointProcess point = PitchTier_Pitch_to_PointProcess (pitchTier.peek(), pitch); return point; } catch (MelderError) { Melder_throw (pitch, U": not converted to PointProcess."); } } static int Pitch_getVoicedIntervalAfter (Pitch me, double after, double *tleft, double *tright) { long ileft = Sampled_xToHighIndex (me, after), iright; if (ileft > my nx) return 0; // offright if (ileft < 1) ileft = 1; // offleft /* Search for first voiced frame. */ for (; ileft <= my nx; ileft ++) if (Pitch_isVoiced_i (me, ileft)) break; if (ileft > my nx) return 0; // offright /* Search for last voiced frame. */ for (iright = ileft; iright <= my nx; iright ++) if (! Pitch_isVoiced_i (me, iright)) break; iright --; *tleft = Sampled_indexToX (me, ileft) - 0.5 * my dx; // the whole frame is considered voiced *tright = Sampled_indexToX (me, iright) + 0.5 * my dx; if (*tleft >= my xmax - 0.5 * my dx) return 0; if (*tleft < my xmin) *tleft = my xmin; if (*tright > my xmax) *tright = my xmax; if (*tright <= after) return 0; return 1; } static double findExtremum_3 (double *channel1_base, double *channel2_base, long d, long n, int includeMaxima, int includeMinima) { double *channel1 = channel1_base + d, *channel2 = channel2_base ? channel2_base + d : NULL; int includeAll = includeMaxima == includeMinima; long imin = 1, imax = 1, i, iextr; double minimum, maximum; if (n < 3) { if (n <= 0) return 0.0; // outside else if (n == 1) return 1.0; else { // n == 2 double x1 = channel2 ? 0.5 * (channel1 [1] + channel2 [1]) : channel1 [1]; double x2 = channel2 ? 0.5 * (channel1 [2] + channel2 [2]) : channel1 [2]; double xleft = includeAll ? fabs (x1) : includeMaxima ? x1 : - x1; double xright = includeAll ? fabs (x2) : includeMaxima ? x2 : - x2; if (xleft > xright) return 1.0; else if (xleft < xright) return 2.0; else return 1.5; } } minimum = maximum = channel2 ? 0.5 * (channel1 [1] + channel2 [1]) : channel1 [1]; for (i = 2; i <= n; i ++) { double value = channel2 ? 0.5 * (channel1 [i] + channel2 [i]) : channel1 [i]; if (value < minimum) { minimum = value; imin = i; } if (value > maximum) { maximum = value; imax = i; } } if (minimum == maximum) { return 0.5 * (n + 1.0); // all equal } iextr = includeAll ? ( fabs (minimum) > fabs (maximum) ? imin : imax ) : includeMaxima ? imax : imin; if (iextr == 1) return 1.0; if (iextr == n) return (double) n; /* Parabolic interpolation. */ /* We do NOT need fabs here: we look for a genuine extremum. */ double valueMid = channel2 ? 0.5 * (channel1 [iextr] + channel2 [iextr]) : channel1 [iextr]; double valueLeft = channel2 ? 0.5 * (channel1 [iextr - 1] + channel2 [iextr - 1]) : channel1 [iextr - 1]; double valueRight = channel2 ? 0.5 * (channel1 [iextr + 1] + channel2 [iextr + 1]) : channel1 [iextr + 1]; return iextr + 0.5 * (valueRight - valueLeft) / (2 * valueMid - valueLeft - valueRight); } static double Sound_findExtremum (Sound me, double tmin, double tmax, int includeMaxima, int includeMinima) { long imin = Sampled_xToLowIndex (me, tmin), imax = Sampled_xToHighIndex (me, tmax); Melder_assert (NUMdefined (tmin)); Melder_assert (NUMdefined (tmax)); if (imin < 1) imin = 1; if (imax > my nx) imax = my nx; double iextremum = findExtremum_3 (my z [1], my ny > 1 ? my z [2] : NULL, imin - 1, imax - imin + 1, includeMaxima, includeMinima); if (iextremum != 0.0) return my x1 + (imin - 1 + iextremum - 1) * my dx; else return (tmin + tmax) / 2; } static double Sound_findMaximumCorrelation (Sound me, double t1, double windowLength, double tmin2, double tmax2, double *tout, double *peak) { double maximumCorrelation = -1.0; // smart 'impossible' starting value double r1_best = NUMundefined, r3_best = NUMundefined, ir = NUMundefined; // assignments not necessary, but extra safe double r1 = 0.0, r2 = 0.0, r3 = 0.0; double halfWindowLength = 0.5 * windowLength; long ileft1 = Sampled_xToNearestIndex ((Sampled) me, t1 - halfWindowLength); long iright1 = Sampled_xToNearestIndex ((Sampled) me, t1 + halfWindowLength); long ileft2min = Sampled_xToLowIndex ((Sampled) me, tmin2 - halfWindowLength); long ileft2max = Sampled_xToHighIndex ((Sampled) me, tmax2 - halfWindowLength); *peak = 0.0; // default Melder_assert (ileft2max >= ileft2min); // if the loop is never executed, the result will be garbage for (long ileft2 = ileft2min; ileft2 <= ileft2max; ileft2 ++) { double norm1 = 0.0, norm2 = 0.0, product = 0.0, localPeak = 0.0; for (long ichan = 1; ichan <= my ny; ichan ++) { for (long i1 = ileft1, i2 = ileft2; i1 <= iright1; i1 ++, i2 ++) { if (i1 < 1 || i1 > my nx || i2 < 1 || i2 > my nx) continue; double amp1 = my z [ichan] [i1], amp2 = my z [ichan] [i2]; norm1 += amp1 * amp1; norm2 += amp2 * amp2; product += amp1 * amp2; if (fabs (amp2) > localPeak) localPeak = fabs (amp2); } } r1 = r2; // >= 0 r2 = r3; // >= 0 r3 = product != 0.0 ? product / (sqrt (norm1 * norm2)) : 0.0; // >= 0 if (r2 > maximumCorrelation /* true on first test */ && r2 >= r1 && r2 >= r3) { r1_best = r1; maximumCorrelation = r2; r3_best = r3; ir = ileft2 - 1; *peak = localPeak; } } /* * Improve the result by means of parabolic interpolation. */ if (maximumCorrelation > -1.0) { // was maximumCorrelation ever assigned to?... // ...then r1_best and r3_best and ir must also have been assigned to: Melder_assert (NUMdefined (r1_best) && NUMdefined (r3_best) && NUMdefined (ir)); double d2r = 2 * maximumCorrelation - r1_best - r3_best; if (d2r != 0.0) { double dr = 0.5 * (r3_best - r1_best); maximumCorrelation += 0.5 * dr * dr / d2r; ir += dr / d2r; } *tout = t1 + (ir - ileft1) * my dx; } return maximumCorrelation; } autoPointProcess Sound_Pitch_to_PointProcess_cc (Sound sound, Pitch pitch) { try { autoPointProcess point = PointProcess_create (sound -> xmin, sound -> xmax, 10); double t = pitch -> xmin; double addedRight = -1e308; double globalPeak = Vector_getAbsoluteExtremum (sound, sound -> xmin, sound -> xmax, 0), peak; /* * Cycle over all voiced intervals. */ autoMelderProgress progress (U"Sound & Pitch: To PointProcess..."); for (;;) { double tleft, tright; if (! Pitch_getVoicedIntervalAfter (pitch, t, & tleft, & tright)) break; Melder_assert (tright > t); /* * Go to the middle of the voice stretch. */ double tmiddle = (tleft + tright) / 2; Melder_progress ((tmiddle - sound -> xmin) / (sound -> xmax - sound -> xmin), U"Sound & Pitch to PointProcess"); double f0middle = Pitch_getValueAtTime (pitch, tmiddle, kPitch_unit_HERTZ, Pitch_LINEAR); /* * Our first point is near this middle. */ if (f0middle == NUMundefined) { Melder_fatal (U"Sound_Pitch_to_PointProcess_cc:" U" tleft ", tleft, U", tright ", tright, U", f0middle ", f0middle ); } double tmax = Sound_findExtremum (sound, tmiddle - 0.5 / f0middle, tmiddle + 0.5 / f0middle, true, true); Melder_assert (NUMdefined (tmax)); PointProcess_addPoint (point.peek(), tmax); double tsave = tmax; for (;;) { double f0 = Pitch_getValueAtTime (pitch, tmax, kPitch_unit_HERTZ, Pitch_LINEAR), correlation; if (f0 == NUMundefined) break; correlation = Sound_findMaximumCorrelation (sound, tmax, 1.0 / f0, tmax - 1.25 / f0, tmax - 0.8 / f0, & tmax, & peak); if (correlation == -1) /*break*/ tmax -= 1.0 / f0; // this one period will drop out if (tmax < tleft) { if (correlation > 0.7 && peak > 0.023333 * globalPeak && tmax - addedRight > 0.8 / f0) { PointProcess_addPoint (point.peek(), tmax); } break; } if (correlation > 0.3 && (peak == 0.0 || peak > 0.01 * globalPeak)) { if (tmax - addedRight > 0.8 / f0) { // do not fill in a short originally unvoiced interval twice PointProcess_addPoint (point.peek(), tmax); } } } tmax = tsave; for (;;) { double f0 = Pitch_getValueAtTime (pitch, tmax, kPitch_unit_HERTZ, Pitch_LINEAR), correlation; if (f0 == NUMundefined) break; correlation = Sound_findMaximumCorrelation (sound, tmax, 1.0 / f0, tmax + 0.8 / f0, tmax + 1.25 / f0, & tmax, & peak); if (correlation == -1) /*break*/ tmax += 1.0 / f0; if (tmax > tright) { if (correlation > 0.7 && peak > 0.023333 * globalPeak) { PointProcess_addPoint (point.peek(), tmax); addedRight = tmax; } break; } if (correlation > 0.3 && (peak == 0.0 || peak > 0.01 * globalPeak)) { PointProcess_addPoint (point.peek(), tmax); addedRight = tmax; } } t = tright; } return point; } catch (MelderError) { Melder_throw (sound, U" & ", pitch, U": not converted to PointProcess (cc)."); } } autoPointProcess Sound_Pitch_to_PointProcess_peaks (Sound sound, Pitch pitch, int includeMaxima, int includeMinima) { try { autoPointProcess point = PointProcess_create (sound -> xmin, sound -> xmax, 10); double t = pitch -> xmin; double addedRight = -1e308; /* * Cycle over all voiced intervals. */ autoMelderProgress progress (U"Sound & Pitch: To PointProcess"); for (;;) { double tleft, tright; if (! Pitch_getVoicedIntervalAfter (pitch, t, & tleft, & tright)) break; /* * Go to the middle of the voiced interval. */ double tmiddle = (tleft + tright) / 2; Melder_progress ((tmiddle - sound -> xmin) / (sound -> xmax - sound -> xmin), U"Sound & Pitch: To PointProcess"); double f0middle = Pitch_getValueAtTime (pitch, tmiddle, kPitch_unit_HERTZ, Pitch_LINEAR); /* * Our first point is near this middle. */ Melder_assert (NUMdefined (f0middle)); double tmax = Sound_findExtremum (sound, tmiddle - 0.5 / f0middle, tmiddle + 0.5 / f0middle, includeMaxima, includeMinima); Melder_assert (NUMdefined (tmax)); PointProcess_addPoint (point.peek(), tmax); double tsave = tmax; for (;;) { double f0 = Pitch_getValueAtTime (pitch, tmax, kPitch_unit_HERTZ, Pitch_LINEAR); if (f0 == NUMundefined) break; tmax = Sound_findExtremum (sound, tmax - 1.25 / f0, tmax - 0.8 / f0, includeMaxima, includeMinima); if (tmax < tleft) { if (tmax - addedRight > 0.8 / f0) { PointProcess_addPoint (point.peek(), tmax); } break; } if (tmax - addedRight > 0.8 / f0) { // do not fill in a short originally unvoiced interval twice PointProcess_addPoint (point.peek(), tmax); } } tmax = tsave; for (;;) { double f0 = Pitch_getValueAtTime (pitch, tmax, kPitch_unit_HERTZ, Pitch_LINEAR); if (f0 == NUMundefined) break; tmax = Sound_findExtremum (sound, tmax + 0.8 / f0, tmax + 1.25 / f0, includeMaxima, includeMinima); if (tmax > tright) { PointProcess_addPoint (point.peek(), tmax); addedRight = tmax; break; } PointProcess_addPoint (point.peek(), tmax); addedRight = tmax; } t = tright; } return point; } catch (MelderError) { Melder_throw (sound, U" & ", pitch, U": not converted to PointProcess (peaks)."); } } /* End of file Pitch_to_PointProcess.cpp */ praat-6.0.04/fon/Pitch_to_PointProcess.h000066400000000000000000000021531261542461700201350ustar00rootroot00000000000000/* Pitch_to_PointProcess.h * * Copyright (C) 1992-2011 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Pitch.h" #include "PointProcess.h" #include "Sound.h" autoPointProcess Pitch_to_PointProcess (Pitch pitch); autoPointProcess Sound_Pitch_to_PointProcess_cc (Sound sound, Pitch pitch); autoPointProcess Sound_Pitch_to_PointProcess_peaks (Sound sound, Pitch pitch, int includeMaxima, int includeMinima); /* End of file Pitch_to_PointProcess.h */ praat-6.0.04/fon/Pitch_to_Sound.cpp000066400000000000000000000066331261542461700171370ustar00rootroot00000000000000/* Pitch_to_Sound.cpp * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2005/02/09 Pitch_to_Sound_sine * pb 2007/02/25 changed default sampling frequency to 44100 Hz * pb 2008/01/19 double * pb 2011/06/05 C++ */ #include "Pitch_to_PointProcess.h" #include "PointProcess_and_Sound.h" #include "Pitch_to_Sound.h" #include "PitchTier_to_Sound.h" #include "Pitch_to_PitchTier.h" autoSound Pitch_to_Sound (Pitch me, double tmin, double tmax, int hum) { static double formant [1 + 6] = { 0, 600, 1400, 2400, 3400, 4500, 5500 }; static double bandwidth [1 + 6] = { 0, 50, 100, 200, 300, 400, 500 }; try { autoPointProcess point = Pitch_to_PointProcess (me); autoSound sound = PointProcess_to_Sound_pulseTrain (point.peek(), 44100, 0.7, 0.05, 30); if (hum) { Sound_filterWithFormants (sound.peek(), tmin, tmax, 6, formant, bandwidth); } return sound; } catch (MelderError) { Melder_throw (me, U": not converted to Sound."); } } void Pitch_play (Pitch me, double tmin, double tmax) { try { autoSound sound = Pitch_to_Sound (me, tmin, tmax, false); if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } // autowindowing Sound_playPart (sound.peek(), tmin, tmax, nullptr, nullptr); } catch (MelderError) { Melder_throw (me, U": not played."); } } void Pitch_hum (Pitch me, double tmin, double tmax) { try { autoSound sound = Pitch_to_Sound (me, tmin, tmax, true); if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } // autowindowing Sound_playPart (sound.peek(), tmin, tmax, nullptr, nullptr); } catch (MelderError) { Melder_throw (me, U": not played."); } } autoSound Pitch_to_Sound_sine (Pitch me, double tmin, double tmax, double samplingFrequency, int roundToNearestZeroCrossings) { try { autoPitchTier tier = Pitch_to_PitchTier (me); autoSound sound = PitchTier_to_Sound_sine (tier.peek(), tmin, tmax, samplingFrequency); long iframe = 1; double unvoicedMin = my xmin; double unvoicedMax = my x1 + (iframe - 1.5) * my dx; for (;;) { while (! Pitch_isVoiced_i (me, iframe)) { unvoicedMax = my x1 + (iframe - 0.5) * my dx; if (++ iframe > my nx) break; } if (unvoicedMax > unvoicedMin) { Sound_setZero (sound.peek(), unvoicedMin, unvoicedMax, roundToNearestZeroCrossings); } if (iframe > my nx) break; while (Pitch_isVoiced_i (me, iframe)) { unvoicedMin = my x1 + (iframe - 0.5) * my dx; if (++ iframe > my nx) break; } if (iframe > my nx) break; } unvoicedMax = my xmax; if (unvoicedMax > unvoicedMin) { Sound_setZero (sound.peek(), unvoicedMin, unvoicedMax, roundToNearestZeroCrossings); } return sound; } catch (MelderError) { Melder_throw (me, U": not converted to Sound (sine)."); } } /* End of file Pitch_to_Sound.cpp */ praat-6.0.04/fon/Pitch_to_Sound.h000066400000000000000000000027061261542461700166010ustar00rootroot00000000000000/* Pitch_to_Sound.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Pitch.h" #include "Sound.h" /* These routines convert a Pitch into a PointProcess, */ /* then this PointProcess into a Sound (pulse train), */ /* and then optionally filter this with 6 formants. */ autoSound Pitch_to_Sound (Pitch me, double tmin, double tmax, int hum); void Pitch_play (Pitch me, double tmin, double tmax); void Pitch_hum (Pitch me, double tmin, double tmax); /* This one converts a Pitch into a PitchTier, */ /* then this PitchTier into a Sound (sine wave), */ /* and then cuts away the unvoiced stretches. */ autoSound Pitch_to_Sound_sine (Pitch me, double tmin, double tmax, double samplingFrequency, int roundToNearestZeroCrossings); /* End of file Pitch_to_Sound.h */ praat-6.0.04/fon/PointEditor.cpp000066400000000000000000000243751261542461700164610ustar00rootroot00000000000000/* PointEditor.cpp * * Copyright (C) 1992-2011,2012,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "PointEditor.h" #include "PointProcess_and_Sound.h" #include "EditorM.h" #include "VoiceAnalysis.h" Thing_implement (PointEditor, TimeSoundEditor, 0); /********** DESTRUCTION **********/ void structPointEditor :: v_destroy () { forget (monoSound); PointEditor_Parent :: v_destroy (); } /********** MENU COMMANDS **********/ static void menu_cb_getJitter_local (EDITOR_ARGS) { EDITOR_IAM (PointEditor); if (my d_startSelection == my d_endSelection) Melder_throw (U"To measure jitter, make a selection first."); Melder_informationReal (PointProcess_getJitter_local ((PointProcess) my data, my d_startSelection, my d_endSelection, 1e-4, 0.02, 1.3), NULL); } static void menu_cb_getJitter_local_absolute (EDITOR_ARGS) { EDITOR_IAM (PointEditor); if (my d_startSelection == my d_endSelection) Melder_throw (U"To measure jitter, make a selection first."); Melder_informationReal (PointProcess_getJitter_local_absolute ((PointProcess) my data, my d_startSelection, my d_endSelection, 1e-4, 0.02, 1.3), U"seconds"); } static void menu_cb_getJitter_rap (EDITOR_ARGS) { EDITOR_IAM (PointEditor); if (my d_startSelection == my d_endSelection) Melder_throw (U"To measure jitter, make a selection first."); Melder_informationReal (PointProcess_getJitter_rap ((PointProcess) my data, my d_startSelection, my d_endSelection, 1e-4, 0.02, 1.3), NULL); } static void menu_cb_getJitter_ppq5 (EDITOR_ARGS) { EDITOR_IAM (PointEditor); if (my d_startSelection == my d_endSelection) Melder_throw (U"To measure jitter, make a selection first."); Melder_informationReal (PointProcess_getJitter_ppq5 ((PointProcess) my data, my d_startSelection, my d_endSelection, 1e-4, 0.02, 1.3), NULL); } static void menu_cb_getJitter_ddp (EDITOR_ARGS) { EDITOR_IAM (PointEditor); if (my d_startSelection == my d_endSelection) Melder_throw (U"To measure jitter, make a selection first."); Melder_informationReal (PointProcess_getJitter_ddp ((PointProcess) my data, my d_startSelection, my d_endSelection, 1e-4, 0.02, 1.3), NULL); } static void menu_cb_getShimmer_local (EDITOR_ARGS) { EDITOR_IAM (PointEditor); if (my d_startSelection == my d_endSelection) Melder_throw (U"To measure shimmer, make a selection first."); Melder_informationReal (PointProcess_Sound_getShimmer_local ((PointProcess) my data, my d_sound.data, my d_startSelection, my d_endSelection, 1e-4, 0.02, 1.3, 1.6), NULL); } static void menu_cb_getShimmer_local_dB (EDITOR_ARGS) { EDITOR_IAM (PointEditor); if (my d_startSelection == my d_endSelection) Melder_throw (U"To measure shimmer, make a selection first."); Melder_informationReal (PointProcess_Sound_getShimmer_local_dB ((PointProcess) my data, my d_sound.data, my d_startSelection, my d_endSelection, 1e-4, 0.02, 1.3, 1.6), NULL); } static void menu_cb_getShimmer_apq3 (EDITOR_ARGS) { EDITOR_IAM (PointEditor); if (my d_startSelection == my d_endSelection) Melder_throw (U"To measure shimmer, make a selection first."); Melder_informationReal (PointProcess_Sound_getShimmer_apq3 ((PointProcess) my data, my d_sound.data, my d_startSelection, my d_endSelection, 1e-4, 0.02, 1.3, 1.6), NULL); } static void menu_cb_getShimmer_apq5 (EDITOR_ARGS) { EDITOR_IAM (PointEditor); if (my d_startSelection == my d_endSelection) Melder_throw (U"To measure shimmer, make a selection first."); Melder_informationReal (PointProcess_Sound_getShimmer_apq5 ((PointProcess) my data, my d_sound.data, my d_startSelection, my d_endSelection, 1e-4, 0.02, 1.3, 1.6), NULL); } static void menu_cb_getShimmer_apq11 (EDITOR_ARGS) { EDITOR_IAM (PointEditor); if (my d_startSelection == my d_endSelection) Melder_throw (U"To measure shimmer, make a selection first."); Melder_informationReal (PointProcess_Sound_getShimmer_apq11 ((PointProcess) my data, my d_sound.data, my d_startSelection, my d_endSelection, 1e-4, 0.02, 1.3, 1.6), NULL); } static void menu_cb_getShimmer_dda (EDITOR_ARGS) { EDITOR_IAM (PointEditor); if (my d_startSelection == my d_endSelection) Melder_throw (U"To measure shimmer, make a selection first."); Melder_informationReal (PointProcess_Sound_getShimmer_dda ((PointProcess) my data, my d_sound.data, my d_startSelection, my d_endSelection, 1e-4, 0.02, 1.3, 1.6), NULL); } static void menu_cb_removePoints (EDITOR_ARGS) { EDITOR_IAM (PointEditor); Editor_save (me, U"Remove point(s)"); if (my d_startSelection == my d_endSelection) PointProcess_removePointNear ((PointProcess) my data, my d_startSelection); else PointProcess_removePointsBetween ((PointProcess) my data, my d_startSelection, my d_endSelection); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_addPointAtCursor (EDITOR_ARGS) { EDITOR_IAM (PointEditor); Editor_save (me, U"Add point"); PointProcess_addPoint ((PointProcess) my data, 0.5 * (my d_startSelection + my d_endSelection)); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_addPointAt (EDITOR_ARGS) { EDITOR_IAM (PointEditor); EDITOR_FORM (U"Add point", 0) REAL (U"Position", U"0.0"); EDITOR_OK SET_REAL (U"Position", 0.5 * (my d_startSelection + my d_endSelection)); EDITOR_DO Editor_save (me, U"Add point"); PointProcess_addPoint ((PointProcess) my data, GET_REAL (U"Position")); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); EDITOR_END } static void menu_cb_PointEditorHelp (EDITOR_ARGS) { EDITOR_IAM (PointEditor); Melder_help (U"PointEditor"); } void structPointEditor :: v_createMenus () { PointEditor_Parent :: v_createMenus (); Editor_addCommand (this, U"Query", U"-- query jitter --", 0, NULL); Editor_addCommand (this, U"Query", U"Get jitter (local)", 0, menu_cb_getJitter_local); Editor_addCommand (this, U"Query", U"Get jitter (local, absolute)", 0, menu_cb_getJitter_local_absolute); Editor_addCommand (this, U"Query", U"Get jitter (rap)", 0, menu_cb_getJitter_rap); Editor_addCommand (this, U"Query", U"Get jitter (ppq5)", 0, menu_cb_getJitter_ppq5); Editor_addCommand (this, U"Query", U"Get jitter (ddp)", 0, menu_cb_getJitter_ddp); if (d_sound.data) { Editor_addCommand (this, U"Query", U"-- query shimmer --", 0, NULL); Editor_addCommand (this, U"Query", U"Get shimmer (local)", 0, menu_cb_getShimmer_local); Editor_addCommand (this, U"Query", U"Get shimmer (local, dB)", 0, menu_cb_getShimmer_local_dB); Editor_addCommand (this, U"Query", U"Get shimmer (apq3)", 0, menu_cb_getShimmer_apq3); Editor_addCommand (this, U"Query", U"Get shimmer (apq5)", 0, menu_cb_getShimmer_apq5); Editor_addCommand (this, U"Query", U"Get shimmer (apq11)", 0, menu_cb_getShimmer_apq11); Editor_addCommand (this, U"Query", U"Get shimmer (dda)", 0, menu_cb_getShimmer_dda); } Editor_addMenu (this, U"Point", 0); Editor_addCommand (this, U"Point", U"Add point at cursor", 'P', menu_cb_addPointAtCursor); Editor_addCommand (this, U"Point", U"Add point at...", 0, menu_cb_addPointAt); Editor_addCommand (this, U"Point", U"-- remove point --", 0, NULL); Editor_addCommand (this, U"Point", U"Remove point(s)", GuiMenu_OPTION + 'P', menu_cb_removePoints); } void structPointEditor :: v_createHelpMenuItems (EditorMenu menu) { PointEditor_Parent :: v_createHelpMenuItems (menu); EditorMenu_addCommand (menu, U"PointEditor help", '?', menu_cb_PointEditorHelp); } /********** DRAWING AREA **********/ void structPointEditor :: v_draw () { PointProcess point = static_cast (our data); Sound sound = d_sound.data; Graphics_setColour (d_graphics, Graphics_WHITE); Graphics_setWindow (d_graphics, 0, 1, 0, 1); Graphics_fillRectangle (d_graphics, 0, 1, 0, 1); double minimum = -1.0, maximum = +1.0; if (sound != NULL && (p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_BY_WINDOW || p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_BY_WINDOW_AND_CHANNEL)) { long first, last; if (Sampled_getWindowSamples (sound, d_startWindow, d_endWindow, & first, & last) >= 1) { Matrix_getWindowExtrema (sound, first, last, 1, 1, & minimum, & maximum); if (minimum == maximum) minimum -= 1.0, maximum += 1.0; } } Graphics_setWindow (d_graphics, d_startWindow, d_endWindow, minimum, maximum); Graphics_setColour (d_graphics, Graphics_BLACK); if (sound != NULL) { long first, last; if (Sampled_getWindowSamples (sound, d_startWindow, d_endWindow, & first, & last) > 1) { Graphics_setLineType (d_graphics, Graphics_DOTTED); Graphics_line (d_graphics, d_startWindow, 0.0, d_endWindow, 0.0); Graphics_setLineType (d_graphics, Graphics_DRAWN); Graphics_function (d_graphics, sound -> z [1], first, last, Sampled_indexToX (sound, first), Sampled_indexToX (sound, last)); } } Graphics_setColour (d_graphics, Graphics_BLUE); Graphics_setWindow (d_graphics, d_startWindow, d_endWindow, -1.0, +1.0); for (long i = 1; i <= point -> nt; i ++) { double t = point -> t [i]; if (t >= d_startWindow && t <= d_endWindow) Graphics_line (d_graphics, t, -0.9, t, +0.9); } Graphics_setColour (d_graphics, Graphics_BLACK); v_updateMenuItems_file (); } void structPointEditor :: v_play (double a_tmin, double a_tmax) { if (d_sound.data) { Sound_playPart (d_sound.data, a_tmin, a_tmax, theFunctionEditor_playCallback, this); } else { PointProcess_playPart ((PointProcess) data, a_tmin, a_tmax); } } autoPointEditor PointEditor_create (const char32 *title, PointProcess point, Sound sound) { try { autoPointEditor me = Thing_new (PointEditor); if (sound) { my monoSound = Sound_convertToMono (sound).transfer(); } TimeSoundEditor_init (me.peek(), title, point, my monoSound, false); return me; } catch (MelderError) { Melder_throw (U"PointProcess window not created."); } } /* End of file PointEditor.cpp */ praat-6.0.04/fon/PointEditor.h000066400000000000000000000024631261542461700161200ustar00rootroot00000000000000#ifndef _PointEditor_h_ #define _PointEditor_h_ /* PointEditor.h * * Copyright (C) 1992-2011,2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "TimeSoundEditor.h" #include "PointProcess.h" Thing_define (PointEditor, TimeSoundEditor) { Sound monoSound; GuiObject addPointAtDialog; void v_destroy () override; void v_createMenus () override; void v_createHelpMenuItems (EditorMenu menu) override; void v_draw () override; void v_play (double tmin, double tmax) override; }; autoPointEditor PointEditor_create (const char32 *title, PointProcess point, Sound sound // may be NULL ); /* End of file PointEditor.h */ #endif praat-6.0.04/fon/PointProcess.cpp000066400000000000000000000417661261542461700166540ustar00rootroot00000000000000/* PointProcess.cpp * * Copyright (C) 1992-2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "PointProcess.h" #include "VoiceAnalysis.h" #include "oo_DESTROY.h" #include "PointProcess_def.h" #include "oo_COPY.h" #include "PointProcess_def.h" #include "oo_EQUAL.h" #include "PointProcess_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "PointProcess_def.h" #include "oo_WRITE_TEXT.h" #include "PointProcess_def.h" #include "oo_READ_TEXT.h" #include "PointProcess_def.h" #include "oo_WRITE_BINARY.h" #include "PointProcess_def.h" #include "oo_READ_BINARY.h" #include "PointProcess_def.h" #include "oo_DESCRIPTION.h" #include "PointProcess_def.h" Thing_implement (PointProcess, Function, 0); static void infoPeriods (PointProcess me, double shortestPeriod, double longestPeriod, double maximumPeriodFactor, int precision) { long numberOfPeriods = PointProcess_getNumberOfPeriods (me, 0.0, 0.0, shortestPeriod, longestPeriod, maximumPeriodFactor); double meanPeriod = PointProcess_getMeanPeriod (me, 0.0, 0.0, shortestPeriod, longestPeriod, maximumPeriodFactor); double stdevPeriod = PointProcess_getStdevPeriod (me, 0.0, 0.0, shortestPeriod, longestPeriod, maximumPeriodFactor); double jitter_local = PointProcess_getJitter_local (me, 0.0, 0.0, shortestPeriod, longestPeriod, maximumPeriodFactor); double jitter_local_absolute = PointProcess_getJitter_local_absolute (me, 0.0, 0.0, shortestPeriod, longestPeriod, maximumPeriodFactor); double jitter_rap = PointProcess_getJitter_rap (me, 0.0, 0.0, shortestPeriod, longestPeriod, maximumPeriodFactor); double jitter_ppq5 = PointProcess_getJitter_ppq5 (me, 0.0, 0.0, shortestPeriod, longestPeriod, maximumPeriodFactor); double jitter_ddp = PointProcess_getJitter_ddp (me, 0.0, 0.0, shortestPeriod, longestPeriod, maximumPeriodFactor); MelderInfo_writeLine (U" Number of periods: ", numberOfPeriods); MelderInfo_writeLine (U" Mean period: ", meanPeriod, U" seconds"); MelderInfo_writeLine (U" Stdev period: ", stdevPeriod, U" seconds"); MelderInfo_writeLine (U" Jitter (local): ", Melder_percent (jitter_local, precision)); MelderInfo_writeLine (U" Jitter (local, absolute): ", Melder_fixedExponent (jitter_local_absolute, -6, precision), U" seconds"); MelderInfo_writeLine (U" Jitter (rap): ", Melder_percent (jitter_rap, precision)); MelderInfo_writeLine (U" Jitter (ppq5): ", Melder_percent (jitter_ppq5, precision)); MelderInfo_writeLine (U" Jitter (ddp): ", Melder_percent (jitter_ddp, precision)); } void structPointProcess :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Time domain:"); MelderInfo_writeLine (U" Start time: ", xmin, U" seconds"); MelderInfo_writeLine (U" End time: ", xmax, U" seconds"); MelderInfo_writeLine (U" Total duration: ", xmax - xmin, U" seconds"); MelderInfo_writeLine (U"Number of times: ", nt); if (nt) { MelderInfo_writeLine (U"First time: ", t [1], U" seconds"); MelderInfo_writeLine (U"Last time: ", t [nt], U" seconds"); } MelderInfo_writeLine (U"Periods between 0.1 ms and 20 ms (pitch between 50 and 10000 Hz),"); MelderInfo_writeLine (U"with a maximum \"period factor\" of 1.3:"); infoPeriods (this, 1e-4, 20e-3, 1.3, 3); MelderInfo_writeLine (U"All periods:"); infoPeriods (this, 0.0, 0.0, 1e308, 6); } void structPointProcess :: v_shiftX (double xfrom, double xto) { PointProcess_Parent :: v_shiftX (xfrom, xto); for (long i = 1; i <= nt; i ++) { NUMshift (& t [i], xfrom, xto); } } void structPointProcess :: v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto) { PointProcess_Parent :: v_scaleX (xminfrom, xmaxfrom, xminto, xmaxto); for (long i = 1; i <= nt; i ++) { NUMscale (& t [i], xminfrom, xmaxfrom, xminto, xmaxto); } } void PointProcess_init (PointProcess me, double tmin, double tmax, long initialMaxnt) { Function_init (me, tmin, tmax); if (initialMaxnt < 1) initialMaxnt = 1; my maxnt = initialMaxnt; my nt = 0; my t = NUMvector (1, my maxnt); } autoPointProcess PointProcess_create (double tmin, double tmax, long initialMaxnt) { try { autoPointProcess me = Thing_new (PointProcess); PointProcess_init (me.peek(), tmin, tmax, initialMaxnt); return me; } catch (MelderError) { Melder_throw (U"PointProcess not created."); } } autoPointProcess PointProcess_createPoissonProcess (double startingTime, double finishingTime, double density) { try { long nt = NUMrandomPoisson ((finishingTime - startingTime) * density); autoPointProcess me = PointProcess_create (startingTime, finishingTime, nt); my nt = nt; for (long i = 1; i <= nt; i ++) my t [i] = NUMrandomUniform (startingTime, finishingTime); NUMsort_d (my nt, my t); return me; } catch (MelderError) { Melder_throw (U"PointProcess (Poisson process) not created."); } } long PointProcess_getLowIndex (PointProcess me, double t) { if (my nt == 0 || t < my t [1]) return 0; if (t >= my t [my nt]) /* Special case that often occurs in practice. */ return my nt; Melder_assert (my nt != 1); /* May fail if t or my t [1] is NaN. */ /* Start binary search. */ long left = 1, right = my nt; while (left < right - 1) { long mid = (left + right) / 2; if (t >= my t [mid]) left = mid; else right = mid; } Melder_assert (right == left + 1); return left; } long PointProcess_getHighIndex (PointProcess me, double t) { if (my nt == 0) return 0; if (t <= my t [1]) return 1; if (t > my t [my nt]) return my nt + 1; /* Start binary search. */ long left = 1, right = my nt; while (left < right - 1) { long mid = (left + right) / 2; if (t > my t [mid]) left = mid; else right = mid; } Melder_assert (right == left + 1); return right; } long PointProcess_getNearestIndex (PointProcess me, double t) { if (my nt == 0) return 0; if (t <= my t [1]) return 1; if (t >= my t [my nt]) return my nt; /* Start binary search. */ long left = 1, right = my nt; while (left < right - 1) { long mid = (left + right) / 2; if (t >= my t [mid]) left = mid; else right = mid; } Melder_assert (right == left + 1); return t - my t [left] < my t [right] - t ? left : right; } void PointProcess_addPoint (PointProcess me, double t) { try { if (t == NUMundefined) Melder_throw (U"Cannot add a point at an undefined time."); if (my nt >= my maxnt) { /* * Create without change. */ autoNUMvector dum (1, 2 * my maxnt); NUMvector_copyElements (my t, dum.peek(), 1, my nt); /* * Change without error. */ NUMvector_free (my t, 1); my t = dum.transfer(); my maxnt *= 2; } if (my nt == 0 || t >= my t [my nt]) { // special case that often occurs in practice my t [++ my nt] = t; } else { long left = PointProcess_getLowIndex (me, t); if (left == 0 || my t [left] != t) { for (long i = my nt; i > left; i --) my t [i + 1] = my t [i]; my nt ++; my t [left + 1] = t; } } } catch (MelderError) { Melder_throw (me, U": point not added."); } } void PointProcess_removePoint (PointProcess me, long index) { if (index < 1 || index > my nt) return; for (long i = index; i < my nt; i ++) my t [i] = my t [i + 1]; my nt --; } void PointProcess_removePointNear (PointProcess me, double t) { PointProcess_removePoint (me, PointProcess_getNearestIndex (me, t)); } void PointProcess_removePoints (PointProcess me, long first, long last) { if (first < 1) first = 1; if (last > my nt) last = my nt; long distance = last - first + 1; if (distance <= 0) return; for (long i = first + distance; i <= my nt; i ++) my t [i - distance] = my t [i]; my nt -= distance; } void PointProcess_removePointsBetween (PointProcess me, double tmin, double tmax) { PointProcess_removePoints (me, PointProcess_getHighIndex (me, tmin), PointProcess_getLowIndex (me, tmax)); } void PointProcess_draw (PointProcess me, Graphics g, double tmin, double tmax, int garnish) { if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } Graphics_setWindow (g, tmin, tmax, -1.0, 1.0); if (my nt) { long imin = PointProcess_getHighIndex (me, tmin), imax = PointProcess_getLowIndex (me, tmax), i; int lineType = Graphics_inqLineType (g); Graphics_setLineType (g, Graphics_DOTTED); Graphics_setInner (g); for (i = imin; i <= imax; i ++) { Graphics_line (g, my t [i], -1.0, my t [i], 1.0); } Graphics_setLineType (g, lineType); Graphics_unsetInner (g); } if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Time (s)"); Graphics_marksBottom (g, 2, true, true, false); } } double PointProcess_getInterval (PointProcess me, double t) { long ileft = PointProcess_getLowIndex (me, t); if (ileft <= 0 || ileft >= my nt) return NUMundefined; return my t [ileft + 1] - my t [ileft]; } autoPointProcess PointProcesses_union (PointProcess me, PointProcess thee) { try { autoPointProcess him = Data_copy (me); if (thy xmin < my xmin) his xmin = thy xmin; if (thy xmax > my xmax) his xmax = thy xmax; for (long i = 1; i <= thy nt; i ++) { PointProcess_addPoint (him.peek(), thy t [i]); } return him; } catch (MelderError) { Melder_throw (me, U" & ", thee, U": union not computed."); } } long PointProcess_findPoint (PointProcess me, double t) { long left = 1, right = my nt; if (my nt == 0) return 0; if (t < my t [left] || t > my t [right]) return 0; while (left < right - 1) { long mid = (left + right) / 2; /* tleft <= t <= tright */ if (t == my t [mid]) return mid; if (t > my t [mid]) left = mid; else right = mid; } if (t == my t [left]) return left; if (t == my t [right]) return right; return 0; } autoPointProcess PointProcesses_intersection (PointProcess me, PointProcess thee) { try { autoPointProcess him = Data_copy (me); if (thy xmin > my xmin) his xmin = thy xmin; if (thy xmax < my xmax) his xmax = thy xmax; for (long i = my nt; i >= 1; i --) if (! PointProcess_findPoint (thee, my t [i])) PointProcess_removePoint (him.peek(), i); return him; } catch (MelderError) { Melder_throw (me, U" & ", thee, U": intersection not computed."); } } autoPointProcess PointProcesses_difference (PointProcess me, PointProcess thee) { try { autoPointProcess him = Data_copy (me); for (long i = my nt; i >= 1; i --) if (PointProcess_findPoint (thee, my t [i])) PointProcess_removePoint (him.peek(), i); return him; } catch (MelderError) { Melder_throw (me, U" & ", thee, U": difference not computed."); } } void PointProcess_fill (PointProcess me, double tmin, double tmax, double period) { try { if (tmax <= tmin) tmin = my xmin, tmax = my xmax; // autowindowing long n = (long) floor ((tmax - tmin) / period); double t = 0.5 * (tmin + tmax - n * period); for (long i = 1; i <= n; i ++, t += period) { PointProcess_addPoint (me, t); } } catch (MelderError) { Melder_throw (me, U": not filled."); } } void PointProcess_voice (PointProcess me, double period, double maxT) { try { long ipointright; double beginVoiceless = my xmin, endVoiceless; for (long ipointleft = 1; ipointleft <= my nt; ipointleft = ipointright + 1) { endVoiceless = my t [ipointleft]; PointProcess_fill (me, beginVoiceless, endVoiceless, period); for (ipointright = ipointleft + 1; ipointright <= my nt; ipointright ++) if (my t [ipointright] - my t [ipointright - 1] > maxT) break; ipointright --; beginVoiceless = my t [ipointright] + 0.005; } endVoiceless = my xmax; PointProcess_fill (me, beginVoiceless, endVoiceless, period); } catch (MelderError) { Melder_throw (me, U": not voiced."); } } long PointProcess_getWindowPoints (PointProcess me, double tmin, double tmax, long *pimin, long *pimax) { long imin = PointProcess_getHighIndex (me, tmin); long imax = PointProcess_getLowIndex (me, tmax); if (pimin) *pimin = imin; if (pimax) *pimax = imax; return imax - imin + 1; } static bool PointProcess_isPeriod (PointProcess me, long ileft, double minimumPeriod, double maximumPeriod, double maximumPeriodFactor) { /* * This function answers the question: is the interval from point 'ileft' to point 'ileft+1' a period? */ long iright = ileft + 1; /* * Period condition 1: both 'ileft' and 'iright' have to be within the point process. */ if (ileft < 1 || iright > my nt) { return false; } else { /* * Period condition 2: the interval has to be within the boundaries, if specified. */ if (minimumPeriod == maximumPeriod) { return true; /* All intervals count as periods, irrespective of absolute size and relative size. */ } else { double interval = my t [iright] - my t [ileft]; if (interval <= 0.0 || interval < minimumPeriod || interval > maximumPeriod) { return false; } else if (! NUMdefined (maximumPeriodFactor) || maximumPeriodFactor < 1.0) { return true; } else { /* * Period condition 3: the interval cannot be too different from both of its neigbours, if any. */ double previousInterval = ileft <= 1 ? NUMundefined : my t [ileft] - my t [ileft - 1]; double nextInterval = iright >= my nt ? NUMundefined : my t [iright + 1] - my t [iright]; double previousIntervalFactor = NUMdefined (previousInterval) && previousInterval > 0.0 ? interval / previousInterval : NUMundefined; double nextIntervalFactor = NUMdefined (nextInterval) && nextInterval > 0.0 ? interval / nextInterval : NUMundefined; if (! NUMdefined (previousIntervalFactor) && ! NUMdefined (nextIntervalFactor)) { return true; /* No neighbours: this is a period. */ } if (NUMdefined (previousIntervalFactor) && previousIntervalFactor > 0.0 && previousIntervalFactor < 1.0) { previousIntervalFactor = 1.0 / previousIntervalFactor; } if (NUMdefined (nextIntervalFactor) && nextIntervalFactor > 0.0 && nextIntervalFactor < 1.0) { nextIntervalFactor = 1.0 / nextIntervalFactor; } if (NUMdefined (previousIntervalFactor) && previousIntervalFactor > maximumPeriodFactor && NUMdefined (nextIntervalFactor) && nextIntervalFactor > maximumPeriodFactor) { return false; } } } } return true; } long PointProcess_getNumberOfPeriods (PointProcess me, double tmin, double tmax, double minimumPeriod, double maximumPeriod, double maximumPeriodFactor) { if (tmax <= tmin) tmin = my xmin, tmax = my xmax; // autowindowing long imin, imax; long numberOfPeriods = PointProcess_getWindowPoints (me, tmin, tmax, & imin, & imax) - 1; if (numberOfPeriods < 1) return 0; for (long i = imin; i < imax; i ++) { if (PointProcess_isPeriod (me, i, minimumPeriod, maximumPeriod, maximumPeriodFactor)) { (void) 0; // this interval counts as a period } else { numberOfPeriods --; // this interval does not count as a period } } return numberOfPeriods; } double PointProcess_getMeanPeriod (PointProcess me, double tmin, double tmax, double minimumPeriod, double maximumPeriod, double maximumPeriodFactor) { if (tmax <= tmin) tmin = my xmin, tmax = my xmax; // autowindowing long imin, imax; long numberOfPeriods = PointProcess_getWindowPoints (me, tmin, tmax, & imin, & imax) - 1; if (numberOfPeriods < 1) return NUMundefined; double sum = 0.0; for (long i = imin; i < imax; i ++) { if (PointProcess_isPeriod (me, i, minimumPeriod, maximumPeriod, maximumPeriodFactor)) { sum += my t [i + 1] - my t [i]; // this interval counts as a period } else { numberOfPeriods --; // this interval does not count as a period } } return numberOfPeriods > 0 ? sum / numberOfPeriods : NUMundefined; } double PointProcess_getStdevPeriod (PointProcess me, double tmin, double tmax, double minimumPeriod, double maximumPeriod, double maximumPeriodFactor) { if (tmax <= tmin) tmin = my xmin, tmax = my xmax; // autowindowing long imin, imax; long numberOfPeriods = PointProcess_getWindowPoints (me, tmin, tmax, & imin, & imax) - 1; if (numberOfPeriods < 2) return NUMundefined; /* * Compute mean. */ double sum = 0.0; for (long i = imin; i < imax; i ++) { if (PointProcess_isPeriod (me, i, minimumPeriod, maximumPeriod, maximumPeriodFactor)) { sum += my t [i + 1] - my t [i]; // this interval counts as a period } else { numberOfPeriods --; // this interval does not count as a period } } if (numberOfPeriods < 2) return NUMundefined; double mean = sum / numberOfPeriods; /* * Compute variance. */ double sum2 = 0.0; for (long i = imin; i < imax; i ++) { if (PointProcess_isPeriod (me, i, minimumPeriod, maximumPeriod, maximumPeriodFactor)) { double dperiod = my t [i + 1] - my t [i] - mean; sum2 += dperiod * dperiod; } } /* * Compute standard deviation. */ return sqrt (sum2 / (numberOfPeriods - 1)); } /* End of file PointProcess.cpp */ praat-6.0.04/fon/PointProcess.h000066400000000000000000000056631261542461700163150ustar00rootroot00000000000000#ifndef _PointProcess_h_ #define _PointProcess_h_ /* PointProcess.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Function.h" #include "Graphics.h" #include "PointProcess_def.h" oo_CLASS_CREATE (PointProcess, Function); autoPointProcess PointProcess_create (double startingTime, double finishingTime, long initialMaxnt); autoPointProcess PointProcess_createPoissonProcess (double startingTime, double finishingTime, double density); void PointProcess_init (PointProcess me, double startingTime, double finishingTime, long initialMaxnt); long PointProcess_getLowIndex (PointProcess me, double t); long PointProcess_getHighIndex (PointProcess me, double t); long PointProcess_getNearestIndex (PointProcess me, double t); long PointProcess_getWindowPoints (PointProcess me, double tmin, double tmax, long *imin, long *imax); void PointProcess_addPoint (PointProcess me, double t); long PointProcess_findPoint (PointProcess me, double t); void PointProcess_removePoint (PointProcess me, long index); void PointProcess_removePointNear (PointProcess me, double t); void PointProcess_removePoints (PointProcess me, long first, long last); void PointProcess_removePointsBetween (PointProcess me, double fromTime, double toTime); void PointProcess_draw (PointProcess me, Graphics g, double fromTime, double toTime, int garnish); double PointProcess_getInterval (PointProcess me, double t); autoPointProcess PointProcesses_union (PointProcess me, PointProcess thee); autoPointProcess PointProcesses_intersection (PointProcess me, PointProcess thee); autoPointProcess PointProcesses_difference (PointProcess me, PointProcess thee); void PointProcess_fill (PointProcess me, double tmin, double tmax, double period); void PointProcess_voice (PointProcess me, double period, double maxT); long PointProcess_getNumberOfPeriods (PointProcess me, double tmin, double tmax, double minimumPeriod, double maximumPeriod, double maximumPeriodFactor); double PointProcess_getMeanPeriod (PointProcess me, double tmin, double tmax, double minimumPeriod, double maximumPeriod, double maximumPeriodFactor); double PointProcess_getStdevPeriod (PointProcess me, double tmin, double tmax, double minimumPeriod, double maximumPeriod, double maximumPeriodFactor); /* End of file PointProcess.h */ #endif praat-6.0.04/fon/PointProcess_and_Sound.cpp000066400000000000000000000200241261542461700206260ustar00rootroot00000000000000/* PointProcess_and_Sound.cpp * * Copyright (C) 1992-2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2003/04/15 improved handling of edges in Sound_getRms * pb 2003/07/20 moved shimmer measurements to VoiceAnalysis.c * pb 2005/07/07 glottal source signals * pb 2006/12/30 new Sound_create API * pb 2007/02/25 changed default sampling frequency to 44100 Hz * pb 2008/01/19 double * pb 2011/06/06 C++ * pb 2011/06/19 removed a bug in PointProcess_to_Sound_phonation that caused a crash if a pulse came after the time domain */ #include "PointProcess_and_Sound.h" autoSound PointProcess_to_Sound_pulseTrain (PointProcess me, double samplingFrequency, double adaptFactor, double adaptTime, long interpolationDepth) { try { long sound_nt = 1 + (long) floor ((my xmax - my xmin) * samplingFrequency); // >= 1 double dt = 1.0 / samplingFrequency; double tmid = (my xmin + my xmax) / 2; double t1 = tmid - 0.5 * (sound_nt - 1) * dt; autoSound thee = Sound_create (1, my xmin, my xmax, sound_nt, dt, t1); double *sound = thy z [1]; for (long it = 1; it <= my nt; it ++) { double t = my t [it], amplitude = 0.9, angle, halfampsinangle; long mid = Sampled_xToNearestIndex (thee.peek(), t); if (it <= 2 || my t [it - 2] < my t [it] - adaptTime) { amplitude *= adaptFactor; if (it == 1 || my t [it - 1] < my t [it] - adaptTime) amplitude *= adaptFactor; } long begin = mid - interpolationDepth, end = mid + interpolationDepth; if (begin < 1) begin = 1; if (end > thy nx) end = thy nx; angle = NUMpi * (Sampled_indexToX (thee.peek(), begin) - t) / thy dx; halfampsinangle = 0.5 * amplitude * sin (angle); for (long j = begin; j <= end; j ++) { if (fabs (angle) < 1e-6) sound [j] += amplitude; else if (angle < 0.0) sound [j] += halfampsinangle * (1.0 + cos (angle / (mid - begin + 1))) / angle; else sound [j] += halfampsinangle * (1.0 + cos (angle / (end - mid + 1))) / angle; angle += NUMpi; halfampsinangle = - halfampsinangle; } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": pulse train not synthesized."); } } autoSound PointProcess_to_Sound_phonation (PointProcess me, double samplingFrequency, double adaptFactor, double maximumPeriod, double openPhase, double collisionPhase, double power1, double power2) { try { long sound_nt = 1 + (long) floor ((my xmax - my xmin) * samplingFrequency); // >= 1 double dt = 1.0 / samplingFrequency; double tmid = (my xmin + my xmax) / 2; double t1 = tmid - 0.5 * (sound_nt - 1) * dt; double a = (power1 + power2 + 1.0) / (power2 - power1); double re = openPhase - collisionPhase; autoSound thee = Sound_create (1, my xmin, my xmax, sound_nt, dt, t1); /* * Compute "re" by iteration. */ if (collisionPhase <= 0.0) { re = openPhase; } else { double xmaxFlow = pow (power1 / power2, 1.0 / (power2 - power1)); double xleft = xmaxFlow; double xright = 1.0; for (int i = 1; i <= 50; i ++) { double xmid = 0.5 * (xleft + xright); double gmid = pow (xmid, power1) - pow (xmid, power2); double gderivmid = power1 * pow (xmid, power1 - 1.0) - power2 * pow (xmid, power2 - 1.0); double fmid = - gmid / gderivmid; if (fmid > collisionPhase / openPhase) { xleft = xmid; } else { xright = xmid; } re = xmid * openPhase; } } /* * Cycle through the points. Each will become a period. */ double *sound = thy z [1]; for (long it = 1; it <= my nt; it ++) { double t = my t [it], amplitude = a; double period = NUMundefined, te, phase, flow; long midSample = Sampled_xToNearestIndex (thee.peek(), t); /* * Determine the period: first look left (because that's where the open phase is), * then right. */ if (it >= 2) { period = my t [it] - my t [it - 1]; if (period > maximumPeriod) { period = NUMundefined; } } if (! NUMdefined (period)) { if (it < my nt) { period = my t [it + 1] - my t [it]; if (period > maximumPeriod) { period = NUMundefined; } } if (! NUMdefined (period)) { period = 0.5 * maximumPeriod; // some default value } } te = re * period; /* * Determine the amplitude of this peak. */ amplitude /= period * openPhase; if (it == 1 || my t [it - 1] < my t [it] - maximumPeriod) { amplitude *= adaptFactor * adaptFactor; } else if (it == 2 || my t [it - 2] < my t [it - 1] - maximumPeriod) { amplitude *= adaptFactor; } /* * Fill in the samples to the left of the current point. */ {// scope long beginSample = midSample - (long) floor (te / thy dx); if (beginSample < 1) beginSample = 1; long endSample = midSample; if (endSample > thy nx) endSample = thy nx; for (long isamp = beginSample; isamp <= endSample; isamp ++) { double tsamp = thy x1 + (isamp - 1) * thy dx; phase = (tsamp - (t - te)) / (period * openPhase); if (phase > 0.0) sound [isamp] += amplitude * (power1 * pow (phase, power1 - 1.0) - power2 * pow (phase, power2 - 1.0)); } } /* * Determine the signal parameters at the current point. */ phase = te / (period * openPhase); flow = amplitude * (period * openPhase) * (pow (phase, power1) - pow (phase, power2)); /* * Fill in the samples to the right of the current point. */ if (flow > 0.0) { double flowDerivative = amplitude * (power1 * pow (phase, power1 - 1.0) - power2 * pow (phase, power2 - 1.0)); double ta = - flow / flowDerivative; double factorPerSample = exp (- thy dx / ta); double value = flowDerivative * factorPerSample; long beginSample = midSample + 1; if (beginSample < 1) beginSample = 1; long endSample = midSample + (long) floor (20.0 * ta / thy dx); if (endSample > thy nx) endSample = thy nx; for (long isamp = beginSample; isamp <= endSample; isamp ++) { sound [isamp] += value; value *= factorPerSample; } } } Vector_scale (thee.peek(), 0.9); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Sound (phonation)."); } } void PointProcess_playPart (PointProcess me, double tmin, double tmax) { try { autoSound sound = PointProcess_to_Sound_pulseTrain (me, 44100, 0.7, 0.05, 30); Sound_playPart (sound.peek(), tmin, tmax, NULL, NULL); } catch (MelderError) { Melder_throw (me, U": not played."); } } void PointProcess_play (PointProcess me) { PointProcess_playPart (me, my xmin, my xmax); } void PointProcess_hum (PointProcess me, double tmin, double tmax) { static double formant [1 + 6] = { 0, 600, 1400, 2400, 3400, 4500, 5500 }; static double bandwidth [1 + 6] = { 0, 50, 100, 200, 300, 400, 500 }; autoSound sound = PointProcess_to_Sound_pulseTrain (me, 44100, 0.7, 0.05, 30); Sound_filterWithFormants (sound.peek(), tmin, tmax, 6, formant, bandwidth); Sound_playPart (sound.peek(), tmin, tmax, NULL, NULL); } autoSound PointProcess_to_Sound_hum (PointProcess me) { static double formant [1 + 6] = { 0, 600, 1400, 2400, 3400, 4500, 5500 }; static double bandwidth [1 + 6] = { 0, 50, 100, 200, 300, 400, 500 }; try { autoSound sound = PointProcess_to_Sound_pulseTrain (me, 44100, 0.7, 0.05, 30); Sound_filterWithFormants (sound.peek(), my xmin, my xmax, 6, formant, bandwidth); return sound; } catch (MelderError) { Melder_throw (me, U": not converted to Sound (hum)."); } } /* End of file PointProcess_and_Sound.cpp */ praat-6.0.04/fon/PointProcess_and_Sound.h000066400000000000000000000041141261542461700202750ustar00rootroot00000000000000/* PointProcess_and_Sound.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "PointProcess.h" #include "Sound.h" autoSound PointProcess_to_Sound_pulseTrain (PointProcess me, double samplingFrequency, double adaptFactor, double adaptTime, long interpolationDepth); /* Function: create a time signal out of a point process. Preconditions: samplingFrequency > 0.0; Arguments: "adaptFactor" defaults to 1. "adaptTime" defaults to 0. "interpolationDepth" is the number of samples for sinxx interpolation in each direction. */ autoSound PointProcess_to_Sound_phonation (PointProcess me, double samplingFrequency, double adaptFactor, double maximumPeriod, double openPhase, double collisionPhase, double power1, double power2); #define PointProcess_to_Sound_phonation_DEFAULT_ADAPT_FACTOR 1.0 #define PointProcess_to_Sound_phonation_DEFAULT_MAXIMUM_PERIOD 0.05 #define PointProcess_to_Sound_phonation_DEFAULT_OPEN_PHASE 0.7 #define PointProcess_to_Sound_phonation_DEFAULT_COLLISION_PHASE 0.03 #define PointProcess_to_Sound_phonation_DEFAULT_POWER_1 3.0 #define PointProcess_to_Sound_phonation_DEFAULT_POWER_2 4.0 void PointProcess_playPart (PointProcess me, double tmin, double tmax); void PointProcess_play (PointProcess me); void PointProcess_hum (PointProcess me, double tmin, double tmax); autoSound PointProcess_to_Sound_hum (PointProcess me); /* End of file PointProcess_and_Sound.h */ praat-6.0.04/fon/PointProcess_def.h000066400000000000000000000027761261542461700171350ustar00rootroot00000000000000/* PointProcess_def.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT PointProcess oo_DEFINE_CLASS (PointProcess, Function) #if oo_DECLARING || oo_COPYING oo_LONG (maxnt) #endif oo_LONG (nt) #if oo_COPYING oo_DOUBLE_VECTOR (t, maxnt) #elif oo_READING if (our nt) { our maxnt = our nt; oo_DOUBLE_VECTOR (t, nt) } else { our maxnt = 1; our t = NUMvector (1, 1); } #else oo_DOUBLE_VECTOR (t, nt) #endif #if oo_DECLARING void v_info () override; int v_domainQuantity () override { return MelderQuantity_TIME_SECONDS; } void v_shiftX (double xfrom, double xto) override; void v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto) override; #endif oo_END_CLASS (PointProcess) #undef ooSTRUCT /* End of file PointProcess_def.h */ praat-6.0.04/fon/Polygon.cpp000066400000000000000000000265051261542461700156450ustar00rootroot00000000000000/* Polygon.cpp * * Copyright (C) 1992-2012,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Polygon.h" #include "oo_DESTROY.h" #include "Polygon_def.h" #include "oo_COPY.h" #include "Polygon_def.h" #include "oo_EQUAL.h" #include "Polygon_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Polygon_def.h" #include "oo_WRITE_BINARY.h" #include "Polygon_def.h" #include "oo_READ_BINARY.h" #include "Polygon_def.h" #include "oo_DESCRIPTION.h" #include "Polygon_def.h" Thing_implement (Polygon, Daata, 1); void structPolygon :: v_info () { our structDaata :: v_info (); MelderInfo_writeLine (U"Number of points: ", our numberOfPoints); MelderInfo_writeLine (U"Perimeter: ", Melder_single (Polygon_perimeter (this))); } void structPolygon :: v_writeText (MelderFile file) { texputi4 (file, our numberOfPoints, U"numberOfPoints", 0,0,0,0,0); for (long i = 1; i <= our numberOfPoints; i ++) { texputr4 (file, our x [i], U"x [", Melder_integer (i), U"]", 0,0,0); texputr4 (file, our y [i], U"y [", Melder_integer (i), U"]", 0,0,0); } } void structPolygon :: v_readText (MelderReadText text, int /*formatVersion*/) { our numberOfPoints = texgeti4 (text); if (our numberOfPoints < 1) Melder_throw (U"Cannot read a Polygon with only ", our numberOfPoints, U" points."); our x = NUMvector (1, our numberOfPoints); our y = NUMvector (1, our numberOfPoints); for (long i = 1; i <= our numberOfPoints; i ++) { our x [i] = texgetr4 (text); our y [i] = texgetr4 (text); } } autoPolygon Polygon_create (long numberOfPoints) { try { autoPolygon me = Thing_new (Polygon); my numberOfPoints = numberOfPoints; my x = NUMvector (1, numberOfPoints); my y = NUMvector (1, numberOfPoints); return me; } catch (MelderError) { Melder_throw (U"Polygon not created."); } } void Polygon_randomize (Polygon me) { for (long i = 1; i <= my numberOfPoints; i ++) { long j = NUMrandomInteger (i, my numberOfPoints); double xdum = my x [i]; double ydum = my y [i]; my x [i] = my x [j]; my y [i] = my y [j]; my x [j] = xdum; my y [j] = ydum; } } double Polygon_perimeter (Polygon me) { if (my numberOfPoints < 1) return 0.0; double dx = my x [1] - my x [my numberOfPoints], dy = my y [1] - my y [my numberOfPoints]; double result = sqrt (dx * dx + dy * dy); for (long i = 1; i <= my numberOfPoints - 1; i ++) { dx = my x [i] - my x [i + 1]; dy = my y [i] - my y [i + 1]; result += sqrt (dx * dx + dy * dy); } return result; } static void computeDistanceTable (Polygon me, int **table) { for (long i = 1; i <= my numberOfPoints - 1; i ++) for (long j = i + 1; j <= my numberOfPoints; j ++) { double dx = my x [i] - my x [j], dy = my y [i] - my y [j]; table [i] [j] = table [j] [i] = (int) floor (sqrt (dx * dx + dy * dy)); // round to zero } } static long computeTotalDistance (int **distance, int path [], int numberOfCities) { long result = 0; for (long i = 1; i <= numberOfCities; i ++) result += distance [path [i - 1]] [path [i]]; return result; } static void shuffle (int path [], int numberOfCities) { for (long i = 1; i <= numberOfCities; i ++) { int j = NUMrandomInteger (i, numberOfCities); int help = path [i]; path [i] = path [j]; path [j] = help; } path [0] = path [numberOfCities]; } static int tryExchange (int **distance, int *path, int numberOfCities, long *totalDistance) { int result = 0; int b1 = path [0]; int b2nr = 1; while (b2nr < numberOfCities - 1) { int b2 = path [b2nr]; int distance_b1_b2 = distance [b1] [b2]; int d2nr = b2nr + 2; int d1 = path [d2nr - 1]; int cont = 1; while (d2nr <= numberOfCities && cont) { int d2 = path [d2nr]; int gain = distance_b1_b2 + distance [d1] [d2] - distance [b1] [d1] - distance [b2] [d2]; if (gain > 0) { int below = b2nr, above = d2nr - 1; cont = 0; do { int help = path [below]; path [below ++] = path [above]; path [above --] = help; } while (below < above); *totalDistance -= gain; } d1 = d2; d2nr ++; } if (cont) { b1 = b2; b2nr ++; } else result = 1; } return result; } static int tryAdoption (int **distance, int *path, int numberOfCities, long *totalDistance) { int *help = NUMvector (0, numberOfCities); int i, maximumGainLeft, result = 0; /* Compute maximum distance between two successive cities. */ int city1 = path [0], city2 = path [1]; int maximumDistance = distance [city1] [city2]; for (i = 2; i <= numberOfCities; i ++) { city1 = city2; city2 = path [i]; if (distance [city1] [city2] > maximumDistance) maximumDistance = distance [city1] [city2]; } maximumGainLeft = maximumDistance; for (i = 1; i <= numberOfCities; i ++) { int cont = 1, b1, b2, distance_b1_b2, d1nr = 3, cc, e1nrMax = 6; int numberOfCitiesMinus1 = numberOfCities - 1, j; for (j = 0; j <= numberOfCitiesMinus1; j ++) path [j] = path [j + 1]; path [numberOfCities] = path [0]; b1 = path [0]; b2 = path [1]; distance_b1_b2 = distance [b1] [b2]; cc = path [2]; while (d1nr < numberOfCitiesMinus1 && cont) { int d1 = path [d1nr]; int gain1 = distance_b1_b2 + distance [d1] [cc] - distance [d1] [b2]; if (gain1 + maximumGainLeft > 0) { int e1nr = d1nr + 1; int dn = path [d1nr]; if (e1nrMax > numberOfCitiesMinus1) e1nrMax = numberOfCitiesMinus1; while (e1nr < e1nrMax && cont) { int e1 = path [e1nr]; int gain = gain1 + distance [dn] [e1] - distance [dn] [b1] - distance [cc] [e1]; if (gain > 0) { int nAdoption = e1nr - d1nr; int dnnr = e1nr - 1; cont = 0; *totalDistance -= gain; for (j = 0; j <= dnnr - 1; j ++) help [j] = path [j + 1]; for (j = 1; j <= nAdoption; j ++) path [j] = help [dnnr - j]; for (j = 0; j <= d1nr - 2; j ++) path [nAdoption + j + 1] = help [j]; } dn = e1; e1nr ++; } } e1nrMax ++; cc = d1; d1nr ++; } result |= ! cont; } NUMvector_free (help, 0); return result; } void Polygon_salesperson (Polygon me, long numberOfIterations) { try { long numberOfShortest = 1, totalDistance, shortestDistance = 0; int numberOfCities = my numberOfPoints; if (numberOfCities < 1) Melder_throw (U"No points."); autoNUMmatrix distance (1, numberOfCities, 1, numberOfCities); computeDistanceTable (me, distance.peek()); autoNUMvector path (0L, numberOfCities); for (int i = 1; i <= numberOfCities; i ++) path [i] = i; path [0] = numberOfCities; // close path autoNUMvector shortestPath (NUMvector_copy (path.peek(), 0, numberOfCities), 0); for (long iteration = 1; iteration <= numberOfIterations; iteration ++) { if (iteration > 1) shuffle (path.peek(), numberOfCities); totalDistance = computeTotalDistance (distance.peek(), path.peek(), numberOfCities); if (iteration == 1) shortestDistance = totalDistance; do { do { } while (tryExchange (distance.peek(), path.peek(), numberOfCities, & totalDistance)); } while (tryAdoption (distance.peek(), path.peek(), numberOfCities, & totalDistance)); if (totalDistance < shortestDistance) { // new shortest path numberOfShortest = 1; for (int i = 0; i <= numberOfCities; i ++) shortestPath [i] = path [i]; shortestDistance = totalDistance; } else if (totalDistance == shortestDistance) // shortest path confirmed numberOfShortest ++; } if (numberOfIterations > 1) Melder_casual (U"Polygon_salesperson:" U" found ", numberOfShortest, U" times the same shortest path."); /* Change me: I will follow the shortest path found. */ autoPolygon help = Data_copy (me); for (long i = 1; i <= numberOfCities; i ++) { my x [i] = help -> x [shortestPath [i]]; my y [i] = help -> y [shortestPath [i]]; } } catch (MelderError) { Melder_throw (me, U": shortest path not found."); } } static void setWindow (Polygon me, Graphics graphics, double xmin, double xmax, double ymin, double ymax) { Melder_assert (me); if (xmax == xmin) { // autoscaling along x axis xmax = xmin = my x [1]; for (long i = 2; i <= my numberOfPoints; i ++) { if (my x [i] < xmin) xmin = my x [i]; if (my x [i] > xmax) xmax = my x [i]; } if (xmin == xmax) { xmin -= 1.0; xmax += 1.0; } } if (ymax == ymin) { // autoscaling along y axis ymax = ymin = my y [1]; for (long i = 2; i <= my numberOfPoints; i ++) { if (my y [i] < ymin) ymin = my y [i]; if (my y [i] > ymax) ymax = my y [i]; } if (ymin == ymax) { ymin -= 1.0; ymax += 1.0; } } Graphics_setWindow (graphics, xmin, xmax, ymin, ymax); } void Polygon_draw (Polygon me, Graphics g, double xmin, double xmax, double ymin, double ymax) { Graphics_setInner (g); setWindow (me, g, xmin, xmax, ymin, ymax); Graphics_polyline (g, my numberOfPoints, & my x [1], & my y [1]); Graphics_unsetInner (g); } void Polygon_drawClosed (Polygon me, Graphics g, double xmin, double xmax, double ymin, double ymax) { Graphics_setInner (g); setWindow (me, g, xmin, xmax, ymin, ymax); Graphics_polyline_closed (g, my numberOfPoints, & my x [1], & my y [1]); Graphics_unsetInner (g); } void Polygon_paint (Polygon me, Graphics g, Graphics_Colour colour, double xmin, double xmax, double ymin, double ymax) { Graphics_setInner (g); setWindow (me, g, xmin, xmax, ymin, ymax); Graphics_setColour (g, colour); Graphics_fillArea (g, my numberOfPoints, & my x [1], & my y [1]); Graphics_unsetInner (g); } void Polygon_drawCircles (Polygon me, Graphics g, double xmin, double xmax, double ymin, double ymax, double diameter_mm) { Graphics_setInner (g); setWindow (me, g, xmin, xmax, ymin, ymax); for (long i = 1; i <= my numberOfPoints; i ++) Graphics_circle_mm (g, my x [i], my y [i], diameter_mm); Graphics_unsetInner (g); } void Polygon_paintCircles (Polygon me, Graphics g, double xmin, double xmax, double ymin, double ymax, double diameter) { Graphics_setInner (g); setWindow (me, g, xmin, xmax, ymin, ymax); for (long i = 1; i <= my numberOfPoints; i ++) Graphics_fillCircle_mm (g, my x [i], my y [i], diameter); Graphics_unsetInner (g); } void Polygons_drawConnection (Polygon me, Polygon thee, Graphics g, double xmin, double xmax, double ymin, double ymax, int hasArrow, double relativeLength) { double w2 = 0.5 * (1 - relativeLength), w1 = 1 - w2; long n = my numberOfPoints; if (thy numberOfPoints < n) n = thy numberOfPoints; Graphics_setInner (g); setWindow (me, g, xmin, xmax, ymin, ymax); for (long i = 1; i <= n; i ++) { double x1 = my x [i], x2 = thy x [i], y1 = my y [i], y2 = thy y [i]; double dummy = w1 * x1 + w2 * x2; x2 = w1 * x2 + w2 * x1; x1 = dummy; dummy = w1 * y1 + w2 * y2; y2 = w1 * y2 + w2 * y1; y1 = dummy; if (hasArrow) Graphics_arrow (g, x1, y1, x2, y2); else Graphics_line (g, x1, y1, x2, y2); } Graphics_unsetInner (g); } /* End of file Polygon.cpp */ praat-6.0.04/fon/Polygon.h000066400000000000000000000051131261542461700153020ustar00rootroot00000000000000#ifndef _Polygon_h_ #define _Polygon_h_ /* Polygon.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Data.h" #include "Graphics.h" #include "Polygon_def.h" oo_CLASS_CREATE (Polygon, Daata); autoPolygon Polygon_create (long numberOfPoints); /* Function: create a new instance of Polygon. Return value: a pointer to the newly created object, or NULL in case of failure. Precondition: numberOfPoints >= 1; Failure: Out of memory. Postconditions: result -> numberOfPoints == numberOfPoints; result -> x [1..numberOfPoints] == 0.0; result -> y [1..numberOfPoints] == 0.0; */ void Polygon_randomize (Polygon me); /* Randomize the order of the points. */ double Polygon_perimeter (Polygon me); /* Return the length of the closed path through all points. */ void Polygon_salesperson (Polygon me, long numberOfIterations); /* Function: change the order of the points in such a way that it defines the shortest closed path. Preconditions: me != NULL; numberOfIterations >= 1; Postconditions: my numberOfPoints == my old numberOfPoints; Polygon_perimeter (me) <= old Polygon_perimeter (me); */ /*** Drawing routines. ***/ void Polygon_draw (Polygon me, Graphics g, double xmin, double xmax, double ymin, double ymax); void Polygon_drawClosed (Polygon me, Graphics g, double xmin, double xmax, double ymin, double ymax); void Polygon_paint (Polygon me, Graphics g, Graphics_Colour colour, double xmin, double xmax, double ymin, double ymax); void Polygon_drawCircles (Polygon me, Graphics g, double xmin, double xmax, double ymin, double ymax, double diameter_mm); void Polygon_paintCircles (Polygon me, Graphics g, double xmin, double xmax, double ymin, double ymax, double diameter_mm); void Polygons_drawConnection (Polygon me, Polygon thee, Graphics g, double xmin, double xmax, double ymin, double ymax, int hasArrow, double relativeLength); /* End of file Polygon.h */ #endif praat-6.0.04/fon/Polygon_def.h000066400000000000000000000024211261542461700161170ustar00rootroot00000000000000/* Polygon_def.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT Polygon oo_DEFINE_CLASS (Polygon, Daata) oo_LONG (numberOfPoints) #if oo_READING if (formatVersion >= 1) { oo_DOUBLE_VECTOR (x, numberOfPoints) oo_DOUBLE_VECTOR (y, numberOfPoints) } else { oo_FLOAT_VECTOR (x, numberOfPoints) oo_FLOAT_VECTOR (y, numberOfPoints) } #else oo_DOUBLE_VECTOR (x, numberOfPoints) oo_DOUBLE_VECTOR (y, numberOfPoints) #endif #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (Polygon) #undef ooSTRUCT /* End of file Polygon_def.h */ praat-6.0.04/fon/Praat_tests.cpp000066400000000000000000000227001261542461700165000ustar00rootroot00000000000000/* Praat_tests.cpp */ /* Paul Boersma, August 2, 2001 */ /* December 10, 2006: MelderInfo */ /* November 5, 2007: wchar */ /* 21 March 2009: modern enums */ /* 24 May 2011: C++ */ /* 5 June 2015: char32 */ #include "Praat_tests.h" #include "Graphics.h" #include "praat.h" #include "enums_getText.h" #include "Praat_tests_enums.h" #include "enums_getValue.h" #include "Praat_tests_enums.h" #include static void testAutoData (autoDaata data) { fprintf (stderr, "testAutoData: %p %p\n", data.get(), data -> name); } static void testAutoDataRef (autoDaata& data) { fprintf (stderr, "testAutoDataRef: %p %p\n", data.get(), data -> name); } static void testData (Daata data) { fprintf (stderr, "testData: %p %s\n", data, Melder_peek32to8 (data -> name)); } static autoDaata newAutoData () { autoDaata data (Thing_new (Daata)); return data; } int Praat_tests (int itest, char32 *arg1, char32 *arg2, char32 *arg3, char32 *arg4) { int64 n = Melder_atoi (arg1); double t = 0.0; (void) arg1; (void) arg2; (void) arg3; (void) arg4; Melder_clearInfo (); Melder_stopwatch (); switch (itest) { case kPraatTests_TIME_RANDOM_FRACTION: { for (int64 i = 1; i <= n; i ++) (void) NUMrandomFraction (); t = Melder_stopwatch (); } break; case kPraatTests_TIME_RANDOM_GAUSS: { for (int64 i = 1; i <= n; i ++) (void) NUMrandomGauss (0.0, 1.0); t = Melder_stopwatch (); } break; case kPraatTests_TIME_SORT: { long m = Melder_atoi (arg2); long *array = NUMvector (1, m); for (int64 i = 1; i <= m; i ++) array [i] = NUMrandomInteger (1, 100); Melder_stopwatch (); for (int64 i = 1; i <= n; i ++) NUMsort_l (m, array); t = Melder_stopwatch (); NUMvector_free (array, 1); } break; case kPraatTests_TIME_INTEGER: { int64 sum = 0; #if ! useCarbon for (int64 i = 1; i <= n; i ++) sum += i * (i - 1) * (i - 2); #endif t = Melder_stopwatch (); MelderInfo_writeLine (sum); } break; case kPraatTests_TIME_FLOAT: { double sum = 0.0, fn = n; for (double fi = 1.0; fi <= fn; fi = fi + 1.0) sum += fi * (fi - 1.0) * (fi - 2.0); t = Melder_stopwatch (); MelderInfo_writeLine (sum); } break; case kPraatTests_TIME_FLOAT_TO_UNSIGNED_BUILTIN: { uint64_t sum = 0; double fn = n; for (double fi = 1.0; fi <= fn; fi = fi + 1.0) sum += (uint32) fi; t = Melder_stopwatch (); // 2.59 // 1.60 MelderInfo_writeLine (sum); } break; case kPraatTests_TIME_FLOAT_TO_UNSIGNED_EXTERN: { uint64_t sum = 0; double fn = n; for (double fi = 1.0; fi <= fn; fi = fi + 1.0) sum += (uint32) ((int32) (fi - 2147483648.0) + 2147483647L + 1); t = Melder_stopwatch (); // 1.60 MelderInfo_writeLine (sum); } break; case kPraatTests_TIME_UNSIGNED_TO_FLOAT_BUILTIN: { double sum = 0.0; uint32 nu = (uint32) n; for (uint32 iu = 1; iu <= nu; iu ++) sum += (double) iu; t = Melder_stopwatch (); // 1.35 MelderInfo_writeLine (sum); } break; case kPraatTests_TIME_UNSIGNED_TO_FLOAT_EXTERN: { double sum = 0.0; uint32 nu = (uint32) n; for (uint32 iu = 1; iu <= nu; iu ++) sum += (double) (int32) (iu - 2147483647L - 1) + 2147483648.0; t = Melder_stopwatch (); // 0.96 MelderInfo_writeLine (sum); } break; case kPraatTests_TIME_STRING_MELDER_32: { autoMelderString string; char32 word [] { U"abc" }; word [2] = NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { MelderString_copy (& string, word); for (int j = 1; j <= 30; j ++) MelderString_append (& string, word); } t = Melder_stopwatch (); } break; case kPraatTests_TIME_STRING_MELDER_32_ALLOC: { char32 word [] { U"abc" }; word [2] = NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { autoMelderString string; MelderString_copy (& string, word); for (int j = 1; j <= 30; j ++) MelderString_append (& string, word); } t = Melder_stopwatch (); } break; case kPraatTests_TIME_STRING_CPP_S: { std::string s = ""; char word [] { "abc" }; word [2] = (char) NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { s = word; for (int j = 1; j <= 30; j ++) s += word; } t = Melder_stopwatch (); } break; case kPraatTests_TIME_STRING_CPP_C: { std::basic_string s = ""; char word [] { "abc" }; word [2] = (char) NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { s = word; for (int j = 1; j <= 30; j ++) s += word; } t = Melder_stopwatch (); } break; case kPraatTests_TIME_STRING_CPP_WS: { std::wstring s = L""; wchar_t word [] { L"abc" }; word [2] = NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { s = word; for (int j = 1; j <= 30; j ++) s += word; } t = Melder_stopwatch (); } break; case kPraatTests_TIME_STRING_CPP_WC: { std::basic_string s = L""; wchar_t word [] { L"abc" }; word [2] = NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { s = word; for (int j = 1; j <= 30; j ++) s += word; } t = Melder_stopwatch (); } break; case kPraatTests_TIME_STRING_CPP_32: { std::basic_string s = U""; char32 word [] { U"abc" }; word [2] = NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { s = word; for (int j = 1; j <= 30; j ++) s += word; } t = Melder_stopwatch (); } break; case kPraatTests_TIME_STRING_CPP_U32STRING: { #if ! defined (macintosh) || ! useCarbon std::u32string s = U""; char32 word [] { U"abc" }; word [2] = NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { s = word; for (int j = 1; j <= 30; j ++) s += word; } #endif t = Melder_stopwatch (); } break; case kPraatTests_TIME_STRCPY: { char buffer [100]; char word [] { "abc" }; word [2] = (char) NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { strcpy (buffer, word); for (int j = 1; j <= 30; j ++) strcpy (buffer + strlen (buffer), word); } t = Melder_stopwatch (); MelderInfo_writeLine (Melder_peek8to32 (buffer)); } break; case kPraatTests_TIME_WCSCPY: { wchar_t buffer [100]; wchar_t word [] { L"abc" }; word [2] = NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { wcscpy (buffer, word); for (int j = 1; j <= 30; j ++) wcscpy (buffer + wcslen (buffer), word); } t = Melder_stopwatch (); } break; case kPraatTests_TIME_STR32CPY: { char32 buffer [100]; char32 word [] { U"abc" }; word [2] = NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { str32cpy (buffer, word); for (int j = 1; j <= 30; j ++) str32cpy (buffer + str32len (buffer), word); } t = Melder_stopwatch (); MelderInfo_writeLine (buffer); } break; case kPraatTests_TIME_GRAPHICS_TEXT_TOP: { autoPraatPicture picture; for (int64 i = 1; i <= n; i ++) { Graphics_textTop (GRAPHICS, false, U"hello world"); } t = Melder_stopwatch (); } break; case kPraatTests_THING_AUTO: { int numberOfThingsBefore = Thing_getTotalNumberOfThings (); { Melder_casual (U"1\n"); autoDaata data = Thing_new (Daata); Thing_setName (data.get(), U"hello"); Melder_casual (U"2\n"); testData (data.peek()); testAutoData (data.move()); autoDaata data18 = Thing_new (Daata); testAutoData (data18.move()); fprintf (stderr, "3\n"); autoDaata data2 = newAutoData (); fprintf (stderr, "4\n"); autoDaata data3 = newAutoData (); fprintf (stderr, "5\n"); //data2 = data; // disabled l-value copy assignment from same class fprintf (stderr, "6\n"); autoOrdered ordered = Thing_new (Ordered); fprintf (stderr, "7\n"); //data = ordered; // disabled l-value copy assignment from subclass data = ordered.move(); //ordered = data; // disabled l-value copy assignment from superclass //ordered = data.move(); // assignment from superclass to subclass is rightfully refused by compiler fprintf (stderr, "8\n"); data2 = newAutoData (); fprintf (stderr, "8a\n"); autoDaata data5 = newAutoData (); fprintf (stderr, "8b\n"); data2 = data5.move(); fprintf (stderr, "9\n"); //ordered = data; // rightfully refused by compiler fprintf (stderr, "10\n"); //autoOrdered ordered2 = Thing_new (Daata); // rightfully refused by compiler fprintf (stderr, "11\n"); autoDaata data4 = Thing_new (Ordered); // constructor fprintf (stderr, "12\n"); //autoDaata data6 = data4; // disabled l-value copy constructor from same class fprintf (stderr, "13\n"); autoDaata data7 = data4.move(); fprintf (stderr, "14\n"); autoOrdered ordered3 = Thing_new (Ordered); autoDaata data8 = ordered3.move(); fprintf (stderr, "15\n"); //autoDaata data9 = ordered; // disabled l-value copy constructor from subclass fprintf (stderr, "16\n"); autoDaata data10 = data7.move(); fprintf (stderr, "17\n"); autoDaata data11 = Thing_new (Daata); // constructor, move assignment, null destructor fprintf (stderr, "18\n"); data11 = Thing_new (Ordered); fprintf (stderr, "19\n"); testAutoDataRef (data11); fprintf (stderr, "20\n"); data11 = nullptr; fprintf (stderr, "21\n"); } int numberOfThingsAfter = Thing_getTotalNumberOfThings (); fprintf (stderr, "Number of things: before %d, after %d\n", numberOfThingsBefore, numberOfThingsAfter); } break; } MelderInfo_writeLine (Melder_single (t / n * 1e9), U" nanoseconds"); MelderInfo_close (); return 1; } /* End of file Praat_tests.cpp */ praat-6.0.04/fon/Praat_tests.h000066400000000000000000000004021261542461700161400ustar00rootroot00000000000000#ifndef _Praat_tests_h_ #define _Praat_tests_h_ /* Paul Boersma, 5 June 2015 */ #include "Thing.h" #include "Praat_tests_enums.h" int Praat_tests (int itest, char32 *arg1, char32 *arg2, char32 *arg3, char32 *arg4); #endif /* End of file Praat_tests.h */ praat-6.0.04/fon/Praat_tests_enums.h000066400000000000000000000035051261542461700173560ustar00rootroot00000000000000/* Praat_tests_enums.h */ /* Paul Boersma, 26 September 2015 */ enums_begin (kPraatTests, 0) enums_add (kPraatTests, 0, _, U"_") enums_add (kPraatTests, 1, CHECK_RANDOM_1009_2009, U"CheckRandom1009_2009") enums_add (kPraatTests, 2, TIME_RANDOM_FRACTION, U"TimeRandomFraction") enums_add (kPraatTests, 3, TIME_RANDOM_GAUSS, U"TimeRandomGauss") enums_add (kPraatTests, 4, TIME_SORT, U"TimeSort") enums_add (kPraatTests, 5, TIME_INTEGER, U"TimeInteger") enums_add (kPraatTests, 6, TIME_FLOAT, U"TimeFloat") enums_add (kPraatTests, 7, TIME_FLOAT_TO_UNSIGNED_BUILTIN, U"TimeFloatToUnsigned_builtin") enums_add (kPraatTests, 8, TIME_FLOAT_TO_UNSIGNED_EXTERN, U"TimeFloatToUnsigned_extern") enums_add (kPraatTests, 9, TIME_UNSIGNED_TO_FLOAT_BUILTIN, U"TimeUnsignedToFloat_builtin") enums_add (kPraatTests, 10, TIME_UNSIGNED_TO_FLOAT_EXTERN, U"TimeUnsignedToFloat_extern") enums_add (kPraatTests, 11, TIME_STRING_MELDER_32, U"TimeStringMelder32") enums_add (kPraatTests, 12, TIME_STRING_MELDER_32_ALLOC, U"TimeStringMelder32_alloc") enums_add (kPraatTests, 13, TIME_STRING_CPP_S, U"TimeStringC++S") enums_add (kPraatTests, 14, TIME_STRING_CPP_C, U"TimeStringC++C") enums_add (kPraatTests, 15, TIME_STRING_CPP_WS, U"TimeStringC++WS") enums_add (kPraatTests, 16, TIME_STRING_CPP_WC, U"TimeStringC++WC") enums_add (kPraatTests, 17, TIME_STRING_CPP_32, U"TimeStringC++32") enums_add (kPraatTests, 18, TIME_STRING_CPP_U32STRING, U"TimeStringC++U32STRING") enums_add (kPraatTests, 19, TIME_STRCPY, U"TimeStrcpy") enums_add (kPraatTests, 20, TIME_WCSCPY, U"TimeWcscpy") enums_add (kPraatTests, 21, TIME_STR32CPY, U"TimeStr32cpy") enums_add (kPraatTests, 22, TIME_GRAPHICS_TEXT_TOP, U"TimeGraphicsTextTop") enums_add (kPraatTests, 23, THING_AUTO, U"ThingAuto") enums_end (kPraatTests, 23, CHECK_RANDOM_1009_2009) /* End of file Praat_tests_enums.h */ praat-6.0.04/fon/RealTier.cpp000066400000000000000000000426771261542461700157350ustar00rootroot00000000000000/* RealTier.cpp * * Copyright (C) 1992-2012,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "RealTier.h" #include "Formula.h" #include "oo_DESTROY.h" #include "RealTier_def.h" #include "oo_COPY.h" #include "RealTier_def.h" #include "oo_EQUAL.h" #include "RealTier_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "RealTier_def.h" #include "oo_WRITE_TEXT.h" #include "RealTier_def.h" #include "oo_READ_TEXT.h" #include "RealTier_def.h" #include "oo_WRITE_BINARY.h" #include "RealTier_def.h" #include "oo_READ_BINARY.h" #include "RealTier_def.h" #include "oo_DESCRIPTION.h" #include "RealTier_def.h" /********** class RealPoint **********/ Thing_implement (RealPoint, AnyPoint, 0); autoRealPoint RealPoint_create (double time, double value) { autoRealPoint me = Thing_new (RealPoint); my number = time; my value = value; return me.transfer(); } /********** class RealTier **********/ void structRealTier :: v_info () { structFunction :: v_info (); MelderInfo_writeLine (U"Number of points: ", our numberOfPoints ()); MelderInfo_writeLine (U"Minimum value: ", RealTier_getMinimumValue (this)); MelderInfo_writeLine (U"Maximum value: ", RealTier_getMaximumValue (this)); } double structRealTier :: v_getVector (long irow, long icol) { (void) irow; return RealTier_getValueAtIndex (this, icol); } double structRealTier :: v_getFunction1 (long irow, double x) { (void) irow; return RealTier_getValueAtTime (this, x); } void structRealTier :: v_shiftX (double xfrom, double xto) { RealTier_Parent :: v_shiftX (xfrom, xto); for (long i = 1; i <= our numberOfPoints (); i ++) { RealPoint point = our point (i); NUMshift (& point -> number, xfrom, xto); } } void structRealTier :: v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto) { RealTier_Parent :: v_scaleX (xminfrom, xmaxfrom, xminto, xmaxto); for (long i = 1; i <= our numberOfPoints (); i ++) { RealPoint point = our point (i); NUMscale (& point -> number, xminfrom, xmaxfrom, xminto, xmaxto); } } Thing_implement (RealTier, Function, 0); void RealTier_init (RealTier me, double tmin, double tmax) { my xmin = tmin; my xmax = tmax; my points = SortedSetOfDouble_create (); } autoRealTier RealTier_create (double tmin, double tmax) { try { autoRealTier me = Thing_new (RealTier); RealTier_init (me.peek(), tmin, tmax); return me; } catch (MelderError) { Melder_throw (U"RealTier not created."); } } autoRealTier RealTier_createWithClass (double tmin, double tmax, ClassInfo klas) { try { autoRealTier me = static_cast (Thing_newFromClass (klas)); RealTier_init (me.peek(), tmin, tmax); return me; } catch (MelderError) { Melder_throw (klas -> className, U" not created."); } } void RealTier_addPoint (RealTier me, double t, double value) { try { autoRealPoint point = RealPoint_create (t, value); Collection_addItem (my points, point.transfer()); } catch (MelderError) { Melder_throw (me, U": point not added."); } } double RealTier_getValueAtIndex (RealTier me, long i) { if (i < 1 || i > my numberOfPoints ()) return NUMundefined; return my point (i) -> value; } double RealTier_getValueAtTime (RealTier me, double t) { long n = my numberOfPoints (); if (n == 0) return NUMundefined; RealPoint pointRight = my point (1); if (t <= pointRight -> number) return pointRight -> value; // constant extrapolation RealPoint pointLeft = my point (n); if (t >= pointLeft -> number) return pointLeft -> value; // constant extrapolation Melder_assert (n >= 2); long ileft = AnyTier_timeToLowIndex (me, t), iright = ileft + 1; Melder_assert (ileft >= 1 && iright <= n); pointLeft = my point (ileft); pointRight = my point (iright); double tleft = pointLeft -> number, fleft = pointLeft -> value; double tright = pointRight -> number, fright = pointRight -> value; return t == tright ? fright // be very accurate : tleft == tright ? 0.5 * (fleft + fright) // unusual, but possible; no preference : fleft + (t - tleft) * (fright - fleft) / (tright - tleft); // linear interpolation } double RealTier_getMaximumValue (RealTier me) { double result = NUMundefined; long n = my numberOfPoints (); for (long i = 1; i <= n; i ++) { RealPoint point = my point (i); if (result == NUMundefined || point -> value > result) result = point -> value; } return result; } double RealTier_getMinimumValue (RealTier me) { double result = NUMundefined; long n = my numberOfPoints (); for (long i = 1; i <= n; i ++) { RealPoint point = my point (i); if (result == NUMundefined || point -> value < result) result = point -> value; } return result; } double RealTier_getArea (RealTier me, double tmin, double tmax) { long n = my numberOfPoints (), imin, imax; RealPoint *points = my peekPoints (); if (n == 0) return NUMundefined; if (n == 1) return (tmax - tmin) * points [1] -> value; imin = AnyTier_timeToLowIndex (me, tmin); if (imin == n) return (tmax - tmin) * points [n] -> value; imax = AnyTier_timeToHighIndex (me, tmax); if (imax == 1) return (tmax - tmin) * points [1] -> value; Melder_assert (imin < n); Melder_assert (imax > 1); /* * Sum the areas between the points. * This works even if imin is 0 (offleft) and/or imax is n + 1 (offright). */ double area = 0.0; for (long i = imin; i < imax; i ++) { double tleft, fleft, tright, fright; if (i == imin) tleft = tmin, fleft = RealTier_getValueAtTime (me, tmin); else tleft = points [i] -> number, fleft = points [i] -> value; if (i + 1 == imax) tright = tmax, fright = RealTier_getValueAtTime (me, tmax); else tright = points [i + 1] -> number, fright = points [i + 1] -> value; area += 0.5 * (fleft + fright) * (tright - tleft); } return area; } double RealTier_getMean_curve (RealTier me, double tmin, double tmax) { if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } // autowindow double area = RealTier_getArea (me, tmin, tmax); if (area == NUMundefined) return NUMundefined; return area / (tmax - tmin); } double RealTier_getStandardDeviation_curve (RealTier me, double tmin, double tmax) { long n = my numberOfPoints (), imin, imax; RealPoint *points = my peekPoints (); double mean, integral = 0.0; if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } // autowindow if (n == 0) return NUMundefined; if (n == 1) return 0.0; imin = AnyTier_timeToLowIndex (me, tmin); if (imin == n) return 0.0; imax = AnyTier_timeToHighIndex (me, tmax); if (imax == 1) return 0.0; Melder_assert (imin < n); Melder_assert (imax > 1); /* * Add the areas between the points. * This works even if imin is 0 (offleft) and/or imax is n + 1 (offright). */ mean = RealTier_getMean_curve (me, tmin, tmax); for (long i = imin; i < imax; i ++) { double tleft, fleft, tright, fright, sum, diff; if (i == imin) tleft = tmin, fleft = RealTier_getValueAtTime (me, tmin); else tleft = points [i] -> number, fleft = points [i] -> value - mean; if (i + 1 == imax) tright = tmax, fright = RealTier_getValueAtTime (me, tmax); else tright = points [i + 1] -> number, fright = points [i + 1] -> value - mean; /* * The area is integral dt f^2 * = integral dt [f1 + (f2-f1)/(t2-t1) (t-t1)]^2 * = int dt f1^2 + int dt 2 f1 (f2-f1)/(t2-t1) (t-t1) + int dt [(f2-f1)/(t2-t1)]^2 (t-t1)^2 * = f1^2 (t2-t1) + f1 (f2-f1)/(t2-t1) (t2-t1)^2 + 1/3 [(f2-f1)/(t2-t1)]^2 (t2-t1)^3 * = (t2-t1) [f1 f2 + 1/3 (f2-f1)^2] * = (t2-t1) (f1^2 + f2^2 + 1/3 f1 f2) * = (t2-t1) [1/4 (f1+f2)^2 + 1/12 (f1-f2)^2] * In the last expression, we have a sum of squares, which is computationally best. */ sum = fleft + fright; diff = fleft - fright; integral += (sum * sum + (1.0/3.0) * diff * diff) * (tright - tleft); } return sqrt (0.25 * integral / (tmax - tmin)); } double RealTier_getMean_points (RealTier me, double tmin, double tmax) { long n = my numberOfPoints (), imin, imax; double sum = 0.0; RealPoint *points = my peekPoints (); if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } // autowindow n = AnyTier_getWindowPoints (me, tmin, tmax, & imin, & imax); if (n == 0) return NUMundefined; for (long i = imin; i <= imax; i ++) sum += points [i] -> value; return sum / n; } double RealTier_getStandardDeviation_points (RealTier me, double tmin, double tmax) { long n = my numberOfPoints (), imin, imax; double mean, sum = 0.0; RealPoint *points = my peekPoints (); if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } // autowindow n = AnyTier_getWindowPoints (me, tmin, tmax, & imin, & imax); if (n < 2) return NUMundefined; mean = RealTier_getMean_points (me, tmin, tmax); for (long i = imin; i <= imax; i ++) { double diff = points [i] -> value - mean; sum += diff * diff; } return sqrt (sum / (n - 1)); } void RealTier_multiplyPart (RealTier me, double tmin, double tmax, double factor) { for (long ipoint = 1; ipoint <= my numberOfPoints (); ipoint ++) { RealPoint point = my point (ipoint); double t = point -> number; if (t >= tmin && t <= tmax) { point -> value *= factor; } } } void RealTier_draw (RealTier me, Graphics g, double tmin, double tmax, double fmin, double fmax, int garnish, const char32 *method, const char32 *quantity) { bool drawLines = str32str (method, U"lines") || str32str (method, U"Lines"); bool drawSpeckles = str32str (method, U"speckles") || str32str (method, U"Speckles"); long n = my numberOfPoints (), imin, imax, i; if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } Graphics_setWindow (g, tmin, tmax, fmin, fmax); Graphics_setInner (g); imin = AnyTier_timeToHighIndex (me, tmin); imax = AnyTier_timeToLowIndex (me, tmax); if (n == 0) { } else if (imax < imin) { double fleft = RealTier_getValueAtTime (me, tmin); double fright = RealTier_getValueAtTime (me, tmax); if (drawLines) Graphics_line (g, tmin, fleft, tmax, fright); } else for (i = imin; i <= imax; i ++) { RealPoint point = my point (i); double t = point -> number, f = point -> value; if (drawSpeckles) Graphics_speckle (g, t, f); if (drawLines) { if (i == 1) Graphics_line (g, tmin, f, t, f); else if (i == imin) Graphics_line (g, t, f, tmin, RealTier_getValueAtTime (me, tmin)); if (i == n) Graphics_line (g, t, f, tmax, f); else if (i == imax) Graphics_line (g, t, f, tmax, RealTier_getValueAtTime (me, tmax)); else { RealPoint pointRight = my point (i + 1); Graphics_line (g, t, f, pointRight -> number, pointRight -> value); } } } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, my v_getUnitText (0, 0, 0)); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); if (quantity) Graphics_textLeft (g, true, quantity); } } autoTableOfReal RealTier_downto_TableOfReal (RealTier me, const char32 *timeLabel, const char32 *valueLabel) { try { autoTableOfReal thee = TableOfReal_create (my numberOfPoints (), 2); TableOfReal_setColumnLabel (thee.peek(), 1, timeLabel); TableOfReal_setColumnLabel (thee.peek(), 2, valueLabel); for (long i = 1; i <= my numberOfPoints (); i ++) { RealPoint point = my point (i); thy data [i] [1] = point -> number; thy data [i] [2] = point -> value; } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to TableOfReal."); } } void RealTier_interpolateQuadratically (RealTier me, long numberOfPointsPerParabola, int logarithmically) { try { autoRealTier thee = Data_copy (me); for (long ipoint = 1; ipoint < my numberOfPoints (); ipoint ++) { RealPoint point1 = my point (ipoint), point2 = my point (ipoint + 1); double time1 = point1 -> number, time2 = point2 -> number, tmid = 0.5 * (time1 + time2); double value1 = point1 -> value, value2 = point2 -> value, valuemid; double timeStep = (tmid - time1) / (numberOfPointsPerParabola + 1); if (logarithmically) value1 = log (value1), value2 = log (value2); valuemid = 0.5 * (value1 + value2); /* * Left from the midpoint. */ for (long inewpoint = 1; inewpoint <= numberOfPointsPerParabola; inewpoint ++) { double newTime = time1 + inewpoint * timeStep; double phase = (newTime - time1) / (tmid - time1); double newValue = value1 + (valuemid - value1) * phase * phase; if (logarithmically) newValue = exp (newValue); RealTier_addPoint (thee.peek(), newTime, newValue); } /* * The midpoint. */ RealTier_addPoint (thee.peek(), tmid, logarithmically ? exp (valuemid) : valuemid); /* * Right from the midpoint. */ for (long inewpoint = 1; inewpoint <= numberOfPointsPerParabola; inewpoint ++) { double newTime = tmid + inewpoint * timeStep; double phase = (time2 - newTime) / (time2 - tmid); double newValue = value2 + (valuemid - value2) * phase * phase; if (logarithmically) newValue = exp (newValue); RealTier_addPoint (thee.peek(), newTime, newValue); } } Thing_swap (me, thee.peek()); } catch (MelderError) { Melder_throw (me, U": not interpolated quadratically."); } } autoTable RealTier_downto_Table (RealTier me, const char32 *indexText, const char32 *timeText, const char32 *valueText) { try { autoTable thee = Table_createWithoutColumnNames (my numberOfPoints (), (indexText != NULL) + (timeText != NULL) + (valueText != NULL)); long icol = 0; if (indexText != NULL) Table_setColumnLabel (thee.peek(), ++ icol, indexText); if (timeText != NULL) Table_setColumnLabel (thee.peek(), ++ icol, timeText); if (valueText != NULL) Table_setColumnLabel (thee.peek(), ++ icol, valueText); for (long ipoint = 1; ipoint <= my numberOfPoints (); ipoint ++) { RealPoint point = my point (ipoint); icol = 0; if (indexText != NULL) Table_setNumericValue (thee.peek(), ipoint, ++ icol, ipoint); if (timeText != NULL) Table_setNumericValue (thee.peek(), ipoint, ++ icol, point -> number); if (valueText != NULL) Table_setNumericValue (thee.peek(), ipoint, ++ icol, point -> value); } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Table."); } } autoRealTier Vector_to_RealTier (Vector me, long channel, ClassInfo klas) { try { autoRealTier thee = RealTier_createWithClass (my xmin, my xmax, klas); for (long i = 1; i <= my nx; i ++) { RealTier_addPoint (thee.peek(), Sampled_indexToX (me, i), my z [channel] [i]); } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to ", klas -> className, U"."); } } autoRealTier Vector_to_RealTier_peaks (Vector me, long channel, ClassInfo klas) { try { autoRealTier thee = RealTier_createWithClass (my xmin, my xmax, klas); for (long i = 2; i < my nx; i ++) { double left = my z [channel] [i - 1], centre = my z [channel] [i], right = my z [channel] [i + 1]; if (left <= centre && right < centre) { double x, maximum; Vector_getMaximumAndX (me, my x1 + (i - 2.5) * my dx, my x1 + (i + 0.5) * my dx, channel, NUM_PEAK_INTERPOLATE_PARABOLIC, & maximum, & x); RealTier_addPoint (thee.peek(), x, maximum); } } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to ", klas -> className, U" (peaks)."); } } autoRealTier Vector_to_RealTier_valleys (Vector me, long channel, ClassInfo klas) { try { autoRealTier thee = RealTier_createWithClass (my xmin, my xmax, klas); for (long i = 2; i < my nx; i ++) { double left = my z [channel] [i - 1], centre = my z [channel] [i], right = my z [channel] [i + 1]; if (left >= centre && right > centre) { double x, minimum; Vector_getMinimumAndX (me, my x1 + (i - 2.5) * my dx, my x1 + (i + 0.5) * my dx, channel, NUM_PEAK_INTERPOLATE_PARABOLIC, & minimum, & x); RealTier_addPoint (thee.peek(), x, minimum); } } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to ", klas -> className, U" (valleys)."); } } autoRealTier PointProcess_upto_RealTier (PointProcess me, double value, ClassInfo klas) { try { autoRealTier thee = RealTier_createWithClass (my xmin, my xmax, klas); for (long i = 1; i <= my nt; i ++) { RealTier_addPoint (thee.peek(), my t [i], value); } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to RealTier."); } } void RealTier_formula (RealTier me, const char32 *expression, Interpreter interpreter, RealTier thee) { try { Formula_compile (interpreter, me, expression, kFormula_EXPRESSION_TYPE_NUMERIC, true); if (thee == NULL) thee = me; for (long icol = 1; icol <= my numberOfPoints (); icol ++) { struct Formula_Result result; Formula_run (0, icol, & result); if (result. result.numericResult == NUMundefined) Melder_throw (U"Cannot put an undefined value into the tier."); thy point (icol) -> value = result. result.numericResult; } } catch (MelderError) { Melder_throw (me, U": formula not completed."); } } void RealTier_removePointsBelow (RealTier me, double level) { for (long ipoint = my numberOfPoints (); ipoint > 0; ipoint --) { RealPoint point = my point (ipoint); if (point -> value < level) { AnyTier_removePoint (me, ipoint); } } } /* End of file RealTier.cpp */ praat-6.0.04/fon/RealTier.h000066400000000000000000000066501261542461700153710ustar00rootroot00000000000000#ifndef _RealTier_h_ #define _RealTier_h_ /* RealTier.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "AnyTier.h" #include "Graphics.h" #include "TableOfReal.h" #include "Vector.h" #include "Interpreter_decl.h" /********** class RealPoint **********/ #include "RealTier_def.h" oo_CLASS_CREATE (RealPoint, AnyPoint); autoRealPoint RealPoint_create (double time, double value); /* Postconditions: result -> time == time; result -> value == value; */ /********** class RealTier **********/ oo_CLASS_CREATE (RealTier, Function); void RealTier_init (RealTier me, double tmin, double tmax); autoRealTier RealTier_create (double tmin, double tmax); autoRealTier RealTier_createWithClass (double tmin, double tmax, ClassInfo klas); /* Postconditions: result -> xmin == tmin; result -> xmax == tmax; result -> points -> size == 0; */ double RealTier_getValueAtIndex (RealTier me, long point); /* No points or 'point' out of range: NUMundefined. */ double RealTier_getValueAtTime (RealTier me, double t); /* Inside points: linear intrapolation. */ /* Outside points: constant extrapolation. */ /* No points: NUMundefined. */ double RealTier_getMinimumValue (RealTier me); double RealTier_getMaximumValue (RealTier me); double RealTier_getArea (RealTier me, double tmin, double tmax); double RealTier_getMean_curve (RealTier me, double tmin, double tmax); double RealTier_getMean_points (RealTier me, double tmin, double tmax); double RealTier_getStandardDeviation_curve (RealTier me, double tmin, double tmax); double RealTier_getStandardDeviation_points (RealTier me, double tmin, double tmax); void RealTier_addPoint (RealTier me, double t, double value); void RealTier_draw (RealTier me, Graphics g, double tmin, double tmax, double ymin, double ymax, int garnish, const char32 *method, const char32 *quantity); autoTableOfReal RealTier_downto_TableOfReal (RealTier me, const char32 *timeLabel, const char32 *valueLabel); void RealTier_interpolateQuadratically (RealTier me, long numberOfPointsPerParabola, int logarithmically); autoTable RealTier_downto_Table (RealTier me, const char32 *indexText, const char32 *timeText, const char32 *valueText); autoRealTier Vector_to_RealTier (Vector me, long channel, ClassInfo klas); autoRealTier Vector_to_RealTier_peaks (Vector me, long channel, ClassInfo klas); autoRealTier Vector_to_RealTier_valleys (Vector me, long channel, ClassInfo klas); autoRealTier PointProcess_upto_RealTier (PointProcess me, double value, ClassInfo klas); void RealTier_formula (RealTier me, const char32 *expression, Interpreter interpreter, RealTier thee); void RealTier_multiplyPart (RealTier me, double tmin, double tmax, double factor); void RealTier_removePointsBelow (RealTier me, double level); /* End of file RealTier.h */ #endif praat-6.0.04/fon/RealTierEditor.cpp000066400000000000000000000367401261542461700170760ustar00rootroot00000000000000/* RealTierEditor.cpp * * Copyright (C) 1992-2011,2012,2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "RealTierEditor.h" #include "EditorM.h" Thing_implement (RealTierEditor, TimeSoundEditor, 0); #define SOUND_HEIGHT 0.382 /********** MENU COMMANDS **********/ static void menu_cb_removePoints (EDITOR_ARGS) { EDITOR_IAM (RealTierEditor); Editor_save (me, U"Remove point(s)"); if (my d_startSelection == my d_endSelection) AnyTier_removePointNear (my data, my d_startSelection); else AnyTier_removePointsBetween (my data, my d_startSelection, my d_endSelection); RealTierEditor_updateScaling (me); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_addPointAtCursor (EDITOR_ARGS) { EDITOR_IAM (RealTierEditor); if (NUMdefined (my v_minimumLegalValue ()) && my ycursor < my v_minimumLegalValue ()) Melder_throw (U"Cannot add a point below ", my v_minimumLegalValue (), my v_rightTickUnits (), U"."); if (NUMdefined (my v_maximumLegalValue ()) && my ycursor > my v_maximumLegalValue ()) Melder_throw (U"Cannot add a point above ", my v_maximumLegalValue (), my v_rightTickUnits (), U"."); Editor_save (me, U"Add point"); RealTier_addPoint ((RealTier) my data, 0.5 * (my d_startSelection + my d_endSelection), my ycursor); RealTierEditor_updateScaling (me); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_addPointAt (EDITOR_ARGS) { EDITOR_IAM (RealTierEditor); EDITOR_FORM (U"Add point", 0) REAL (U"Time (s)", U"0.0") REAL (my v_quantityText (), U"0.0") EDITOR_OK SET_REAL (U"Time", 0.5 * (my d_startSelection + my d_endSelection)) SET_REAL (my v_quantityKey (), my ycursor) EDITOR_DO double desiredValue = GET_REAL (my v_quantityKey ()); if (NUMdefined (my v_minimumLegalValue ()) && desiredValue < my v_minimumLegalValue ()) Melder_throw (U"Cannot add a point below ", my v_minimumLegalValue (), my v_rightTickUnits (), U"."); if (NUMdefined (my v_maximumLegalValue ()) && desiredValue > my v_maximumLegalValue ()) Melder_throw (U"Cannot add a point above ", my v_maximumLegalValue (), my v_rightTickUnits (), U"."); Editor_save (me, U"Add point"); RealTier_addPoint ((RealTier) my data, GET_REAL (U"Time"), desiredValue); RealTierEditor_updateScaling (me); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); EDITOR_END } static void menu_cb_setRange (EDITOR_ARGS) { EDITOR_IAM (RealTierEditor); EDITOR_FORM (my v_setRangeTitle (), 0) REAL (my v_yminText (), my v_defaultYminText ()) REAL (my v_ymaxText (), my v_defaultYmaxText ()) EDITOR_OK SET_REAL (my v_yminKey (), my ymin) SET_REAL (my v_ymaxKey (), my ymax) EDITOR_DO my ymin = GET_REAL (my v_yminKey ()); my ymax = GET_REAL (my v_ymaxKey ()); if (my ymax <= my ymin) RealTierEditor_updateScaling (me); FunctionEditor_redraw (me); EDITOR_END } void structRealTierEditor :: v_createMenuItems_view (EditorMenu menu) { RealTierEditor_Parent :: v_createMenuItems_view (menu); EditorMenu_addCommand (menu, U"-- view/realtier --", 0, 0); EditorMenu_addCommand (menu, v_setRangeTitle (), 0, menu_cb_setRange); } void structRealTierEditor :: v_createMenus () { RealTierEditor_Parent :: v_createMenus (); EditorMenu menu = Editor_addMenu (this, U"Point", 0); EditorMenu_addCommand (menu, U"Add point at cursor", 'T', menu_cb_addPointAtCursor); EditorMenu_addCommand (menu, U"Add point at...", 0, menu_cb_addPointAt); EditorMenu_addCommand (menu, U"-- remove point --", 0, NULL); EditorMenu_addCommand (menu, U"Remove point(s)", GuiMenu_OPTION + 'T', menu_cb_removePoints); } void RealTierEditor_updateScaling (RealTierEditor me) { RealTier data = (RealTier) my data; if (data -> points -> size == 0) { my ymin = my v_defaultYmin (); my ymax = my v_defaultYmax (); } else { double ymin = RealTier_getMinimumValue (data); double ymax = RealTier_getMaximumValue (data); double range = ymax - ymin; if (range == 0.0) ymin -= 1.0, ymax += 1.0; else ymin -= 0.2 * range, ymax += 0.2 * range; if (NUMdefined (my v_minimumLegalValue()) && ymin < my v_minimumLegalValue ()) ymin = my v_minimumLegalValue (); if (NUMdefined (my v_maximumLegalValue ()) && ymin > my v_maximumLegalValue ()) ymin = my v_maximumLegalValue (); if (NUMdefined (my v_minimumLegalValue ()) && ymax < my v_minimumLegalValue ()) ymax = my v_minimumLegalValue (); if (NUMdefined (my v_maximumLegalValue ()) && ymax > my v_maximumLegalValue ()) ymax = my v_maximumLegalValue (); if (ymin >= ymax) { if (NUMdefined (my v_minimumLegalValue ()) && NUMdefined (my v_maximumLegalValue ())) { ymin = my v_minimumLegalValue (); ymax = my v_maximumLegalValue (); } else if (NUMdefined (my v_minimumLegalValue ())) { ymin = my v_minimumLegalValue (); ymax = ymin + 1.0; } else { Melder_assert (NUMdefined (my v_maximumLegalValue ())); ymax = my v_maximumLegalValue (); ymin = ymax - 1.0; } } if (ymin < my ymin || my ymin < 0.0) my ymin = ymin; if (ymax > my ymax) my ymax = ymax; if (my ycursor <= my ymin || my ycursor >= my ymax) my ycursor = 0.382 * my ymin + 0.618 * my ymax; } } void structRealTierEditor :: v_dataChanged () { RealTierEditor_updateScaling (this); RealTierEditor_Parent :: v_dataChanged (); } /********** DRAWING AREA **********/ void structRealTierEditor :: v_draw () { RealTier data = (RealTier) our data; long ifirstSelected, ilastSelected, n = data -> points -> size, imin, imax, i; Graphics_Viewport viewport; if (our d_sound.data) { viewport = Graphics_insetViewport (our d_graphics, 0, 1, 1 - SOUND_HEIGHT, 1.0); Graphics_setColour (our d_graphics, Graphics_WHITE); Graphics_setWindow (our d_graphics, 0, 1, 0, 1); Graphics_fillRectangle (our d_graphics, 0, 1, 0, 1); TimeSoundEditor_drawSound (this, -1.0, 1.0); Graphics_resetViewport (our d_graphics, viewport); Graphics_insetViewport (our d_graphics, 0, 1, 0.0, 1 - SOUND_HEIGHT); } Graphics_setColour (our d_graphics, Graphics_WHITE); Graphics_setWindow (our d_graphics, 0, 1, 0, 1); Graphics_fillRectangle (our d_graphics, 0, 1, 0, 1); Graphics_setWindow (our d_graphics, our d_startWindow, our d_endWindow, our ymin, our ymax); Graphics_setColour (our d_graphics, Graphics_RED); Graphics_line (our d_graphics, our d_startWindow, ycursor, our d_endWindow, our ycursor); Graphics_setTextAlignment (our d_graphics, Graphics_RIGHT, Graphics_HALF); Graphics_text (our d_graphics, our d_startWindow, our ycursor, Melder_float (Melder_half (our ycursor))); Graphics_setColour (our d_graphics, Graphics_BLUE); Graphics_setTextAlignment (our d_graphics, Graphics_LEFT, Graphics_TOP); Graphics_text (our d_graphics, our d_endWindow, our ymax, Melder_float (Melder_half (ymax)), our v_rightTickUnits ()); Graphics_setTextAlignment (our d_graphics, Graphics_LEFT, Graphics_HALF); Graphics_text (our d_graphics, our d_endWindow, our ymin, Melder_float (Melder_half (our ymin)), our v_rightTickUnits ()); ifirstSelected = AnyTier_timeToHighIndex (data, our d_startSelection); ilastSelected = AnyTier_timeToLowIndex (data, our d_endSelection); imin = AnyTier_timeToHighIndex (data, our d_startWindow); imax = AnyTier_timeToLowIndex (data, our d_endWindow); Graphics_setLineWidth (our d_graphics, 2); if (n == 0) { Graphics_setTextAlignment (our d_graphics, Graphics_CENTRE, Graphics_HALF); Graphics_text (our d_graphics, 0.5 * (our d_startWindow + our d_endWindow), 0.5 * (our ymin + our ymax), U"(no points)"); } else if (imax < imin) { double yleft = RealTier_getValueAtTime (data, our d_startWindow); double yright = RealTier_getValueAtTime (data, our d_endWindow); Graphics_line (our d_graphics, our d_startWindow, yleft, our d_endWindow, yright); } else for (i = imin; i <= imax; i ++) { RealPoint point = data -> point (i); double t = point -> number, y = point -> value; if (i >= ifirstSelected && i <= ilastSelected) Graphics_setColour (our d_graphics, Graphics_RED); Graphics_fillCircle_mm (our d_graphics, t, y, 3); Graphics_setColour (our d_graphics, Graphics_BLUE); if (i == 1) Graphics_line (our d_graphics, our d_startWindow, y, t, y); else if (i == imin) Graphics_line (our d_graphics, t, y, our d_startWindow, RealTier_getValueAtTime (data, our d_startWindow)); if (i == n) Graphics_line (our d_graphics, t, y, our d_endWindow, y); else if (i == imax) Graphics_line (our d_graphics, t, y, our d_endWindow, RealTier_getValueAtTime (data, our d_endWindow)); else { RealPoint pointRight = data -> point (i + 1); Graphics_line (our d_graphics, t, y, pointRight -> number, pointRight -> value); } } Graphics_setLineWidth (our d_graphics, 1); Graphics_setColour (our d_graphics, Graphics_BLACK); our v_updateMenuItems_file (); } static void drawWhileDragging (RealTierEditor me, double xWC, double yWC, long first, long last, double dt, double dy) { RealTier data = (RealTier) my data; (void) xWC; (void) yWC; /* * Draw all selected points as magenta empty circles, if inside the window. */ for (long i = first; i <= last; i ++) { RealPoint point = data -> point (i); double t = point -> number + dt, y = point -> value + dy; if (t >= my d_startWindow && t <= my d_endWindow) Graphics_circle_mm (my d_graphics, t, y, 3); } if (last == first) { /* * Draw a crosshair with time and y. */ RealPoint point = data -> point (first); double t = point -> number + dt, y = point -> value + dy; Graphics_line (my d_graphics, t, my ymin, t, my ymax - Graphics_dyMMtoWC (my d_graphics, 4.0)); Graphics_setTextAlignment (my d_graphics, kGraphics_horizontalAlignment_CENTRE, Graphics_TOP); Graphics_text (my d_graphics, t, my ymax, Melder_fixed (t, 6)); Graphics_line (my d_graphics, my d_startWindow, y, my d_endWindow, y); Graphics_setTextAlignment (my d_graphics, Graphics_LEFT, Graphics_BOTTOM); Graphics_text (my d_graphics, my d_startWindow, y, Melder_fixed (y, 6)); } } int structRealTierEditor :: v_click (double xWC, double yWC, bool shiftKeyPressed) { RealTier pitch = (RealTier) our data; long inearestPoint, ifirstSelected, ilastSelected; RealPoint nearestPoint; double dt = 0, df = 0; bool draggingSelection; Graphics_Viewport viewport; /* * Perform the default action: move cursor. */ //our d_startSelection = our d_endSelection = xWC; if (our d_sound.data) { if (yWC < 1 - SOUND_HEIGHT) { /* Clicked in tier area? */ yWC /= 1 - SOUND_HEIGHT; our ycursor = (1.0 - yWC) * our ymin + yWC * our ymax; viewport = Graphics_insetViewport (our d_graphics, 0, 1, 0, 1 - SOUND_HEIGHT); } else { return our RealTierEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed); } } else { our ycursor = (1.0 - yWC) * our ymin + yWC * our ymax; } Graphics_setWindow (our d_graphics, our d_startWindow, our d_endWindow, our ymin, our ymax); yWC = our ycursor; /* * Clicked on a point? */ inearestPoint = AnyTier_timeToNearestIndex (pitch, xWC); if (inearestPoint == 0) return RealTierEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed); nearestPoint = (RealPoint) pitch -> points -> item [inearestPoint]; if (Graphics_distanceWCtoMM (d_graphics, xWC, yWC, nearestPoint -> number, nearestPoint -> value) > 1.5) { if (d_sound.data) Graphics_resetViewport (our d_graphics, viewport); return our RealTierEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed); } /* * Clicked on a selected point? */ draggingSelection = shiftKeyPressed && nearestPoint -> number > d_startSelection && nearestPoint -> number < d_endSelection; if (draggingSelection) { ifirstSelected = AnyTier_timeToHighIndex (pitch, d_startSelection); ilastSelected = AnyTier_timeToLowIndex (pitch, d_endSelection); Editor_save (this, U"Drag points"); } else { ifirstSelected = ilastSelected = inearestPoint; Editor_save (this, U"Drag point"); } /* * Drag. */ Graphics_xorOn (our d_graphics, Graphics_MAROON); drawWhileDragging (this, xWC, yWC, ifirstSelected, ilastSelected, dt, df); // draw at old position while (Graphics_mouseStillDown (our d_graphics)) { double xWC_new, yWC_new; Graphics_getMouseLocation (our d_graphics, & xWC_new, & yWC_new); if (xWC_new != xWC || yWC_new != yWC) { drawWhileDragging (this, xWC, yWC, ifirstSelected, ilastSelected, dt, df); // undraw at old position dt += xWC_new - xWC, df += yWC_new - yWC; xWC = xWC_new, yWC = yWC_new; drawWhileDragging (this, xWC, yWC, ifirstSelected, ilastSelected, dt, df); // draw at new position } } Graphics_xorOff (d_graphics); /* * Dragged inside window? */ if (xWC < d_startWindow || xWC > d_endWindow) return 1; /* * Points not dragged past neighbours? */ { RealPoint *points = pitch -> peekPoints (); double newTime = points [ifirstSelected] -> number + dt; if (newTime < our tmin) return 1; // outside domain if (ifirstSelected > 1 && newTime <= points [ifirstSelected - 1] -> number) return 1; // past left neighbour newTime = points [ilastSelected] -> number + dt; if (newTime > our tmax) return 1; // outside domain if (ilastSelected < pitch -> numberOfPoints() && newTime >= points [ilastSelected + 1] -> number) return 1; // past right neighbour } /* * Drop. */ for (int i = ifirstSelected; i <= ilastSelected; i ++) { RealPoint point = pitch -> point (i); point -> number += dt; point -> value += df; if (NUMdefined (v_minimumLegalValue ()) && point -> value < v_minimumLegalValue ()) point -> value = v_minimumLegalValue (); if (NUMdefined (v_maximumLegalValue ()) && point -> value > v_maximumLegalValue ()) point -> value = v_maximumLegalValue (); } /* * Make sure that the same points are still selected (a problem with Undo...). */ if (draggingSelection) our d_startSelection += dt, our d_endSelection += dt; if (ifirstSelected == ilastSelected) { /* * Move crosshair to only selected pitch point. */ RealPoint point = (RealPoint) pitch -> points -> item [ifirstSelected]; our d_startSelection = our d_endSelection = point -> number; our ycursor = point -> value; } else { /* * Move crosshair to mouse location. */ /*our cursor += dt;*/ our ycursor += df; if (NUMdefined (v_minimumLegalValue ()) && our ycursor < v_minimumLegalValue ()) our ycursor = v_minimumLegalValue (); if (NUMdefined (v_maximumLegalValue ()) && our ycursor > v_maximumLegalValue ()) our ycursor = v_maximumLegalValue (); } Editor_broadcastDataChanged (this); RealTierEditor_updateScaling (this); return 1; // update needed } void structRealTierEditor :: v_play (double a_tmin, double a_tmax) { if (our d_sound.data) Sound_playPart (our d_sound.data, a_tmin, a_tmax, theFunctionEditor_playCallback, this); } void RealTierEditor_init (RealTierEditor me, const char32 *title, RealTier data, Sound sound, bool ownSound) { Melder_assert (data != NULL); Melder_assert (Thing_isa (data, classRealTier)); TimeSoundEditor_init (me, title, data, sound, ownSound); my ymin = -1.0; RealTierEditor_updateScaling (me); my ycursor = 0.382 * my ymin + 0.618 * my ymax; } /* End of file RealTierEditor.cpp */ praat-6.0.04/fon/RealTierEditor.h000066400000000000000000000052331261542461700165340ustar00rootroot00000000000000#ifndef _RealTierEditor_h_ #define _RealTierEditor_h_ /* RealTierEditor.h * * Copyright (C) 1992-2011,2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "TimeSoundEditor.h" #include "RealTier.h" Thing_define (RealTierEditor, TimeSoundEditor) { double ymin, ymax, ycursor; void v_createMenus () override; void v_dataChanged () override; void v_draw () override; int v_click (double xWC, double yWC, bool shiftKeyPressed) override; void v_play (double tmin, double tmax) override; void v_createMenuItems_view (EditorMenu menu) override; virtual double v_minimumLegalValue () { return NUMundefined; } virtual double v_maximumLegalValue () { return NUMundefined; } virtual const char32 * v_quantityText () { return U"Y"; } // normally includes units virtual const char32 * v_quantityKey () { return U"Y"; } // without units virtual const char32 * v_rightTickUnits () { return U""; } virtual double v_defaultYmin () { return 0.0; } virtual double v_defaultYmax () { return 1.0; } virtual const char32 * v_setRangeTitle () { return U"Set range..."; } virtual const char32 * v_defaultYminText () { return U"0.0"; } virtual const char32 * v_defaultYmaxText () { return U"1.0"; } virtual const char32 * v_yminText () { return U"Minimum"; } // normally includes units virtual const char32 * v_ymaxText () { return U"Maximum"; } // normally includes units virtual const char32 * v_yminKey () { return U"Minimum"; } // without units virtual const char32 * v_ymaxKey () { return U"Maximum"; } // without units }; void RealTierEditor_updateScaling (RealTierEditor me); /* Computes the ymin and ymax values on the basis of the data. Call after every change in the data. */ void RealTierEditor_init (RealTierEditor me, const char32 *title, RealTier data, Sound sound, bool ownSound); /* `Sound` may be NULL; if `ownSound` is `true`, the editor will contain a deep copy of the Sound, which the editor will destroy when the editor is destroyed. */ /* End of file RealTierEditor.h */ #endif praat-6.0.04/fon/RealTier_def.h000066400000000000000000000043661261542461700162110ustar00rootroot00000000000000/* RealTier_def.h * * Copyright (C) 1992-2012,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT RealPoint oo_DEFINE_CLASS (RealPoint, AnyPoint) oo_DOUBLE (value) oo_END_CLASS (RealPoint) #undef ooSTRUCT #define ooSTRUCT RealTier oo_DEFINE_CLASS (RealTier, Function) oo_COLLECTION (SortedSetOfDouble, points, RealPoint, 0) #if oo_DECLARING long numberOfPoints () // accessor { return points -> size; } RealPoint * peekPoints () // accessor { return reinterpret_cast (points -> item); } RealPoint point (long ipoint) // accessor { return static_cast (points -> item [ipoint]); } void v_info () override; bool v_hasGetNx () override { return true; } double v_getNx () override { return numberOfPoints (); } bool v_hasGetX () override { return true; } double v_getX (long ix) override { return point (ix) -> number; } bool v_hasGetNcol () override { return true; } double v_getNcol () override { return numberOfPoints (); } bool v_hasGetVector () override { return true; } double v_getVector (long irow, long icol) override; bool v_hasGetFunction1 () override { return true; } double v_getFunction1 (long irow, double x) override; const char32 * v_getUnitText (long /* ilevel */, int /* unit */, unsigned long /* flags */) override { return U"Time (s)"; } void v_shiftX (double xfrom, double xto) override; void v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto) override; #endif oo_END_CLASS (RealTier) #undef ooSTRUCT /* End of file RealTier_def.h */ praat-6.0.04/fon/RunnerMFC.cpp000066400000000000000000000505361261542461700160160ustar00rootroot00000000000000/* RunnerMFC.cpp * * Copyright (C) 2001-2011,2013,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * a selection of changes: * pb 2002/07/08 goodness * pb 2005/11/21 play again * pb 2005/12/02 response sounds are played * pb 2005/12/04 oops button * pb 2005/12/08 multiple experiments * pb 2011/03/03 reaction times for mouse clicks * pb 2011/04/14 reaction times for key presses */ #include "RunnerMFC.h" #include "EditorM.h" #include "machine.h" Thing_implement (RunnerMFC, Editor, 0); void structRunnerMFC :: v_destroy () { if (our experiments) { our experiments -> size = 0; // give ownership back to whoever thinks they own the experiments. BUG: can be dontOwnItems forget (our experiments); } forget (our graphics); our RunnerMFC_Parent :: v_destroy (); } void structRunnerMFC :: v_dataChanged () { Graphics_updateWs (our graphics); } static int RunnerMFC_startExperiment (RunnerMFC me) { my data = (Daata) my experiments -> item [my iexperiment]; Melder_assert (my data -> classInfo == classExperimentMFC); ExperimentMFC_start ((ExperimentMFC) my data); Thing_setName (me, ((ExperimentMFC) my data) -> name); Editor_broadcastDataChanged (me); Graphics_updateWs (my graphics); return 1; } static void drawControlButton (RunnerMFC me, double left, double right, double bottom, double top, const char32 *visibleText) { Graphics_setColour (my graphics, Graphics_MAROON); Graphics_setLineWidth (my graphics, 3.0); Graphics_fillRectangle (my graphics, left, right, bottom, top); Graphics_setColour (my graphics, Graphics_YELLOW); Graphics_rectangle (my graphics, left, right, bottom, top); Graphics_text (my graphics, 0.5 * (left + right), 0.5 * (bottom + top), visibleText); } static void gui_drawingarea_cb_expose (I, GuiDrawingAreaExposeEvent event) { iam (RunnerMFC); Melder_assert (event -> widget == my d_drawingArea); if (my graphics == NULL) return; // Could be the case in the very beginning. ExperimentMFC experiment = (ExperimentMFC) my data; long iresponse; if (my data == NULL) return; Graphics_setGrey (my graphics, 0.8); Graphics_fillRectangle (my graphics, 0, 1, 0, 1); Graphics_setGrey (my graphics, 0.0); if (experiment -> trial == 0) { Graphics_setTextAlignment (my graphics, Graphics_CENTRE, Graphics_HALF); Graphics_setFontSize (my graphics, 24); Graphics_text (my graphics, 0.5, 0.5, experiment -> startText); } else if (experiment -> pausing) { Graphics_setTextAlignment (my graphics, Graphics_CENTRE, Graphics_HALF); Graphics_setFontSize (my graphics, 24); Graphics_text (my graphics, 0.5, 0.5, experiment -> pauseText); if (experiment -> oops_right > experiment -> oops_left && experiment -> trial > 1) { drawControlButton (me, experiment -> oops_left, experiment -> oops_right, experiment -> oops_bottom, experiment -> oops_top, experiment -> oops_label); } } else if (experiment -> trial <= experiment -> numberOfTrials) { const char32 *visibleText = experiment -> stimulus [experiment -> stimuli [experiment -> trial]]. visibleText; autostring32 visibleText_dup = Melder_dup_f (visibleText ? visibleText : U""); char32 *visibleText_p = visibleText_dup.peek(); Graphics_setFont (my graphics, kGraphics_font_TIMES); Graphics_setFontSize (my graphics, 10); Graphics_setColour (my graphics, Graphics_BLACK); Graphics_setTextAlignment (my graphics, Graphics_LEFT, Graphics_TOP); Graphics_text (my graphics, 0, 1, experiment -> trial, U" / ", experiment -> numberOfTrials); Graphics_setTextAlignment (my graphics, Graphics_CENTRE, Graphics_TOP); Graphics_setFontSize (my graphics, 24); /* * The run text. */ if (visibleText_p [0] != U'\0') { char32 *visibleText_q = str32chr (visibleText_p, U'|'); if (visibleText_q) *visibleText_q = '\0'; Graphics_text (my graphics, 0.5, 1.0, visibleText_p [0] != '\0' ? visibleText_p : experiment -> runText); if (visibleText_q) visibleText_p = visibleText_q + 1; else visibleText_p += str32len (visibleText_p); } else { Graphics_text (my graphics, 0.5, 1.0, experiment -> runText); } Graphics_setTextAlignment (my graphics, Graphics_CENTRE, Graphics_HALF); for (iresponse = 1; iresponse <= experiment -> numberOfDifferentResponses; iresponse ++) { ResponseMFC response = & experiment -> response [iresponse]; char32 *textToDraw = response -> label; // can be overridden if (visibleText_p [0] != U'\0') { char32 *visibleText_q = str32chr (visibleText_p, U'|'); if (visibleText_q) *visibleText_q = U'\0'; textToDraw = visibleText_p; // override if (visibleText_q) visibleText_p = visibleText_q + 1; else visibleText_p += str32len (visibleText_p); } if (str32nequ (textToDraw, U"\\FI", 3)) { structMelderFile file = { 0 }; MelderDir_relativePathToFile (& experiment -> rootDirectory, textToDraw + 3, & file); Graphics_imageFromFile (my graphics, Melder_fileToPath (& file), response -> left, response -> right, response -> bottom, response -> top); } else { Graphics_setColour (my graphics, response -> name [0] == U'\0' ? Graphics_SILVER : experiment -> responses [experiment -> trial] == iresponse ? Graphics_RED : experiment -> ok_right > experiment -> ok_left || experiment -> responses [experiment -> trial] == 0 ? Graphics_YELLOW : Graphics_SILVER); Graphics_setLineWidth (my graphics, 3.0); Graphics_fillRectangle (my graphics, response -> left, response -> right, response -> bottom, response -> top); Graphics_setColour (my graphics, Graphics_MAROON); Graphics_rectangle (my graphics, response -> left, response -> right, response -> bottom, response -> top); Graphics_setFontSize (my graphics, response -> fontSize ? response -> fontSize : 24); Graphics_text (my graphics, 0.5 * (response -> left + response -> right), 0.5 * (response -> bottom + response -> top), textToDraw); } Graphics_setFontSize (my graphics, 24); } for (iresponse = 1; iresponse <= experiment -> numberOfGoodnessCategories; iresponse ++) { GoodnessMFC goodness = & experiment -> goodness [iresponse]; Graphics_setColour (my graphics, experiment -> responses [experiment -> trial] == 0 ? Graphics_SILVER : experiment -> goodnesses [experiment -> trial] == iresponse ? Graphics_RED : Graphics_YELLOW); Graphics_setLineWidth (my graphics, 3.0); Graphics_fillRectangle (my graphics, goodness -> left, goodness -> right, goodness -> bottom, goodness -> top); Graphics_setColour (my graphics, Graphics_MAROON); Graphics_rectangle (my graphics, goodness -> left, goodness -> right, goodness -> bottom, goodness -> top); Graphics_text (my graphics, 0.5 * (goodness -> left + goodness -> right), 0.5 * (goodness -> bottom + goodness -> top), goodness -> label); } if (experiment -> replay_right > experiment -> replay_left && my numberOfReplays < experiment -> maximumNumberOfReplays) { drawControlButton (me, experiment -> replay_left, experiment -> replay_right, experiment -> replay_bottom, experiment -> replay_top, experiment -> replay_label); } if (experiment -> ok_right > experiment -> ok_left && experiment -> responses [experiment -> trial] != 0 && (experiment -> numberOfGoodnessCategories == 0 || experiment -> goodnesses [experiment -> trial] != 0)) { drawControlButton (me, experiment -> ok_left, experiment -> ok_right, experiment -> ok_bottom, experiment -> ok_top, experiment -> ok_label); } if (experiment -> oops_right > experiment -> oops_left && experiment -> trial > 1) { drawControlButton (me, experiment -> oops_left, experiment -> oops_right, experiment -> oops_bottom, experiment -> oops_top, experiment -> oops_label); } } else { Graphics_setTextAlignment (my graphics, Graphics_CENTRE, Graphics_HALF); Graphics_setFontSize (my graphics, 24); Graphics_text (my graphics, 0.5, 0.5, experiment -> endText); if (experiment -> oops_right > experiment -> oops_left && experiment -> trial > 1) { drawControlButton (me, experiment -> oops_left, experiment -> oops_right, experiment -> oops_bottom, experiment -> oops_top, experiment -> oops_label); } } } static void gui_drawingarea_cb_resize (I, GuiDrawingAreaResizeEvent event) { iam (RunnerMFC); if (my graphics == NULL) return; Graphics_setWsViewport (my graphics, 0, event -> width, 0, event -> height); Graphics_setWsWindow (my graphics, 0, event -> width, 0, event -> height); Graphics_setViewport (my graphics, 0, event -> width, 0, event -> height); Graphics_updateWs (my graphics); } static void do_ok (RunnerMFC me) { ExperimentMFC experiment = (ExperimentMFC) my data; Melder_assert (experiment -> trial >= 1 && experiment -> trial <= experiment -> numberOfTrials); my numberOfReplays = 0; if (experiment -> trial == experiment -> numberOfTrials) { experiment -> trial ++; Editor_broadcastDataChanged (me); Graphics_updateWs (my graphics); } else if (experiment -> breakAfterEvery != 0 && experiment -> trial % experiment -> breakAfterEvery == 0) { experiment -> pausing = true; Editor_broadcastDataChanged (me); Graphics_updateWs (my graphics); } else { experiment -> trial ++; Editor_broadcastDataChanged (me); if (experiment -> blankWhilePlaying) { Graphics_setGrey (my graphics, 0.8); Graphics_fillRectangle (my graphics, 0, 1, 0, 1); Graphics_setGrey (my graphics, 0.0); Graphics_flushWs (my graphics); } Graphics_updateWs (my graphics); if (experiment -> stimuliAreSounds) { autoMelderAudioSaveMaximumAsynchronicity saveMaximumAsynchronicity; if (experiment -> blankWhilePlaying) MelderAudio_setOutputMaximumAsynchronicity (kMelder_asynchronicityLevel_SYNCHRONOUS); ExperimentMFC_playStimulus (experiment, experiment -> stimuli [experiment -> trial]); } } } static void do_oops (RunnerMFC me) { ExperimentMFC experiment = (ExperimentMFC) my data; Melder_assert (experiment -> trial >= 2 && experiment -> trial <= experiment -> numberOfTrials + 1); if (experiment -> trial <= experiment -> numberOfTrials) { experiment -> responses [experiment -> trial] = 0; experiment -> goodnesses [experiment -> trial] = 0; } experiment -> trial --; experiment -> responses [experiment -> trial] = 0; experiment -> goodnesses [experiment -> trial] = 0; experiment -> pausing = false; my numberOfReplays = 0; Editor_broadcastDataChanged (me); if (experiment -> blankWhilePlaying) { Graphics_setGrey (my graphics, 0.8); Graphics_fillRectangle (my graphics, 0, 1, 0, 1); Graphics_setGrey (my graphics, 0.0); Graphics_flushWs (my graphics); } Graphics_updateWs (my graphics); if (experiment -> stimuliAreSounds) { autoMelderAudioSaveMaximumAsynchronicity saveMaximumAsynchronicity; if (experiment -> blankWhilePlaying) MelderAudio_setOutputMaximumAsynchronicity (kMelder_asynchronicityLevel_SYNCHRONOUS); ExperimentMFC_playStimulus (experiment, experiment -> stimuli [experiment -> trial]); } } static void do_replay (RunnerMFC me) { ExperimentMFC experiment = (ExperimentMFC) my data; Melder_assert (experiment -> trial >= 1 && experiment -> trial <= experiment -> numberOfTrials); my numberOfReplays ++; Editor_broadcastDataChanged (me); if (experiment -> blankWhilePlaying) { Graphics_setGrey (my graphics, 0.8); Graphics_fillRectangle (my graphics, 0, 1, 0, 1); Graphics_setGrey (my graphics, 0.0); Graphics_flushWs (my graphics); } Graphics_updateWs (my graphics); if (experiment -> stimuliAreSounds) { autoMelderAudioSaveMaximumAsynchronicity saveMaximumAsynchronicity; if (experiment -> blankWhilePlaying) MelderAudio_setOutputMaximumAsynchronicity (kMelder_asynchronicityLevel_SYNCHRONOUS); ExperimentMFC_playStimulus (experiment, experiment -> stimuli [experiment -> trial]); } } static void gui_drawingarea_cb_click (I, GuiDrawingAreaClickEvent event) { iam (RunnerMFC); if (my graphics == NULL) return; // could be the case in the very beginning ExperimentMFC experiment = (ExperimentMFC) my data; if (my data == NULL) return; double reactionTime = Melder_clock () - experiment -> startingTime; if (! experiment -> blankWhilePlaying) reactionTime -= experiment -> stimulusInitialSilenceDuration; double x, y; Graphics_DCtoWC (my graphics, event -> x, event -> y, & x, & y); if (experiment -> trial == 0) { // the first click of the experiment experiment -> trial ++; Editor_broadcastDataChanged (me); if (experiment -> blankWhilePlaying) { Graphics_setGrey (my graphics, 0.8); Graphics_fillRectangle (my graphics, 0, 1, 0, 1); Graphics_setGrey (my graphics, 0.0); Graphics_flushWs (my graphics); } Graphics_updateWs (my graphics); if (experiment -> stimuliAreSounds) { if (experiment -> numberOfTrials < 1) { Melder_flushError (U"There are zero trials in this experiment."); forget (me); return; } autoMelderAudioSaveMaximumAsynchronicity saveMaximumAsynchronicity; if (experiment -> blankWhilePlaying) MelderAudio_setOutputMaximumAsynchronicity (kMelder_asynchronicityLevel_SYNCHRONOUS); ExperimentMFC_playStimulus (experiment, experiment -> stimuli [1]); // works only if there is at least one trial } } else if (experiment -> pausing) { // a click to leave the break if (x > experiment -> oops_left && x < experiment -> oops_right && y > experiment -> oops_bottom && y < experiment -> oops_top && experiment -> trial > 1) { do_oops (me); } else { experiment -> pausing = false; experiment -> trial ++; Editor_broadcastDataChanged (me); if (experiment -> blankWhilePlaying) { Graphics_setGrey (my graphics, 0.8); Graphics_fillRectangle (my graphics, 0, 1, 0, 1); Graphics_setGrey (my graphics, 0.0); Graphics_flushWs (my graphics); } Graphics_updateWs (my graphics); if (experiment -> stimuliAreSounds) { autoMelderAudioSaveMaximumAsynchronicity saveMaximumAsynchronicity; if (experiment -> blankWhilePlaying) MelderAudio_setOutputMaximumAsynchronicity (kMelder_asynchronicityLevel_SYNCHRONOUS); ExperimentMFC_playStimulus (experiment, experiment -> stimuli [experiment -> trial]); } } } else if (experiment -> trial <= experiment -> numberOfTrials) { long iresponse; if (x > experiment -> ok_left && x < experiment -> ok_right && y > experiment -> ok_bottom && y < experiment -> ok_top && experiment -> responses [experiment -> trial] != 0 && (experiment -> numberOfGoodnessCategories == 0 || experiment -> goodnesses [experiment -> trial] != 0)) { do_ok (me); } else if (x > experiment -> replay_left && x < experiment -> replay_right && y > experiment -> replay_bottom && y < experiment -> replay_top && my numberOfReplays < experiment -> maximumNumberOfReplays) { do_replay (me); } else if (x > experiment -> oops_left && x < experiment -> oops_right && y > experiment -> oops_bottom && y < experiment -> oops_top && experiment -> trial > 1) { do_oops (me); } else if (experiment -> responses [experiment -> trial] == 0 || experiment -> ok_right > experiment -> ok_left) { for (iresponse = 1; iresponse <= experiment -> numberOfDifferentResponses; iresponse ++) { ResponseMFC response = & experiment -> response [iresponse]; if (x > response -> left && x < response -> right && y > response -> bottom && y < response -> top && response -> name [0] != '\0') { experiment -> responses [experiment -> trial] = iresponse; experiment -> reactionTimes [experiment -> trial] = reactionTime; if (experiment -> responsesAreSounds) { ExperimentMFC_playResponse (experiment, iresponse); } if (experiment -> ok_right <= experiment -> ok_left && experiment -> numberOfGoodnessCategories == 0) { do_ok (me); } else { Editor_broadcastDataChanged (me); Graphics_updateWs (my graphics); } } } if (experiment -> responses [experiment -> trial] != 0 && experiment -> ok_right > experiment -> ok_left) { for (iresponse = 1; iresponse <= experiment -> numberOfGoodnessCategories; iresponse ++) { GoodnessMFC cat = & experiment -> goodness [iresponse]; if (x > cat -> left && x < cat -> right && y > cat -> bottom && y < cat -> top) { experiment -> goodnesses [experiment -> trial] = iresponse; Editor_broadcastDataChanged (me); Graphics_updateWs (my graphics); } } } } else if (experiment -> responses [experiment -> trial] != 0) { Melder_assert (experiment -> ok_right <= experiment -> ok_left); for (iresponse = 1; iresponse <= experiment -> numberOfGoodnessCategories; iresponse ++) { GoodnessMFC cat = & experiment -> goodness [iresponse]; if (x > cat -> left && x < cat -> right && y > cat -> bottom && y < cat -> top) { experiment -> goodnesses [experiment -> trial] = iresponse; do_ok (me); } } } } else { if (x > experiment -> oops_left && x < experiment -> oops_right && y > experiment -> oops_bottom && y < experiment -> oops_top) { do_oops (me); return; } if (my iexperiment < my experiments -> size) { my iexperiment ++; if (! RunnerMFC_startExperiment (me)) { Melder_flushError (); forget (me); return; } } } } static void gui_drawingarea_cb_key (I, GuiDrawingAreaKeyEvent event) { iam (RunnerMFC); if (my graphics == NULL) return; // Could be the case in the very beginning. ExperimentMFC experiment = (ExperimentMFC) my data; if (my data == NULL) return; double reactionTime = Melder_clock () - experiment -> startingTime; if (! experiment -> blankWhilePlaying) reactionTime -= experiment -> stimulusInitialSilenceDuration; if (experiment -> trial == 0) { } else if (experiment -> pausing) { } else if (experiment -> trial <= experiment -> numberOfTrials) { long iresponse; if (experiment -> ok_key != NULL && experiment -> ok_key [0] == event -> key && experiment -> responses [experiment -> trial] != 0 && (experiment -> numberOfGoodnessCategories == 0 || experiment -> goodnesses [experiment -> trial] != 0)) { do_ok (me); } else if (experiment -> replay_key != NULL && experiment -> replay_key [0] == event -> key && my numberOfReplays < experiment -> maximumNumberOfReplays) { do_replay (me); } else if (experiment -> oops_key != NULL && experiment -> oops_key [0] == event -> key) { if (experiment -> trial > 1) { do_oops (me); } } else if (experiment -> responses [experiment -> trial] == 0) { for (iresponse = 1; iresponse <= experiment -> numberOfDifferentResponses; iresponse ++) { ResponseMFC response = & experiment -> response [iresponse]; if (response -> key != NULL && response -> key [0] == event -> key) { experiment -> responses [experiment -> trial] = iresponse; experiment -> reactionTimes [experiment -> trial] = reactionTime; if (experiment -> responsesAreSounds) { ExperimentMFC_playResponse (experiment, iresponse); } if (experiment -> ok_right <= experiment -> ok_left && experiment -> numberOfGoodnessCategories == 0) { do_ok (me); } else { Editor_broadcastDataChanged (me); Graphics_updateWs (my graphics); } } } } } } void structRunnerMFC :: v_createChildren () { our d_drawingArea = GuiDrawingArea_createShown (our d_windowForm, 0, 0, Machine_getMenuBarHeight (), 0, gui_drawingarea_cb_expose, gui_drawingarea_cb_click, gui_drawingarea_cb_key, gui_drawingarea_cb_resize, this, 0); } autoRunnerMFC RunnerMFC_create (const char32 *title, Ordered experiments) { try { autoRunnerMFC me = Thing_new (RunnerMFC); Editor_init (me.peek(), 0, 0, 2000, 2000, title, NULL); my experiments = experiments; my graphics = Graphics_create_xmdrawingarea (my d_drawingArea); struct structGuiDrawingAreaResizeEvent event = { my d_drawingArea, 0 }; event. width = GuiControl_getWidth (my d_drawingArea); event. height = GuiControl_getHeight (my d_drawingArea); gui_drawingarea_cb_resize (me.peek(), & event); my iexperiment = 1; RunnerMFC_startExperiment (me.peek()); return me; } catch (MelderError) { Melder_throw (U"Experiment window not created."); } } /* End of file RunnerMFC.cpp */ praat-6.0.04/fon/RunnerMFC.h000066400000000000000000000024701261542461700154550ustar00rootroot00000000000000#ifndef _RunnerMFC_h_ #define _RunnerMFC_h_ /* RunnerMFC.h * * Copyright (C) 2001-2011,2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Editor.h" #include "ExperimentMFC.h" Thing_define (RunnerMFC, Editor) { GuiDrawingArea d_drawingArea; Ordered experiments; long iexperiment; Graphics graphics; long numberOfReplays; void v_destroy () override; bool v_editable () override { return false; } bool v_scriptable () override { return false; } void v_createChildren () override; void v_dataChanged () override; }; autoRunnerMFC RunnerMFC_create (const char32 *title, Ordered experiments); /* End of file RunnerMFC.h */ #endif praat-6.0.04/fon/Sampled.cpp000066400000000000000000000742451261542461700156070ustar00rootroot00000000000000/* Sampled.cpp * * Copyright (C) 1992-2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include "Sampled.h" #include "oo_DESTROY.h" #include "Sampled_def.h" #include "oo_COPY.h" #include "Sampled_def.h" #include "oo_EQUAL.h" #include "Sampled_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Sampled_def.h" #include "oo_WRITE_TEXT.h" #include "Sampled_def.h" #include "oo_READ_TEXT.h" #include "Sampled_def.h" #include "oo_WRITE_BINARY.h" #include "Sampled_def.h" #include "oo_READ_BINARY.h" #include "Sampled_def.h" #include "oo_DESCRIPTION.h" #include "Sampled_def.h" Thing_implement (Sampled, Function, 0); void structSampled :: v_shiftX (double xfrom, double xto) { Sampled_Parent :: v_shiftX (xfrom, xto); NUMshift (& our x1, xfrom, xto); } void structSampled :: v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto) { Sampled_Parent :: v_scaleX (xminfrom, xmaxfrom, xminto, xmaxto); NUMscale (& our x1, xminfrom, xmaxfrom, xminto, xmaxto); our dx *= (xmaxto - xminto) / (xmaxfrom - xminfrom); } long Sampled_getWindowSamples (Sampled me, double xmin, double xmax, long *ixmin, long *ixmax) { double rixmin = 1.0 + ceil ((xmin - my x1) / my dx); double rixmax = 1.0 + floor ((xmax - my x1) / my dx); // could be above 32-bit LONG_MAX *ixmin = rixmin < 1.0 ? 1 : (long) rixmin; *ixmax = rixmax > (double) my nx ? my nx : (long) rixmax; if (*ixmin > *ixmax) return 0; return *ixmax - *ixmin + 1; } void Sampled_init (Sampled me, double xmin, double xmax, long nx, double dx, double x1) { my xmin = xmin; my xmax = xmax; my nx = nx; my dx = dx; my x1 = x1; } void Sampled_shortTermAnalysis (Sampled me, double windowDuration, double timeStep, long *numberOfFrames, double *firstTime) { Melder_assert (windowDuration > 0.0); Melder_assert (timeStep > 0.0); volatile double myDuration = my dx * my nx; if (windowDuration > myDuration) Melder_throw (me, U": shorter than window length."); *numberOfFrames = (long) floor ((myDuration - windowDuration) / timeStep) + 1; Melder_assert (*numberOfFrames >= 1); double ourMidTime = my x1 - 0.5 * my dx + 0.5 * myDuration; double thyDuration = *numberOfFrames * timeStep; *firstTime = ourMidTime - 0.5 * thyDuration + 0.5 * timeStep; } double Sampled_getValueAtSample (Sampled me, long isamp, long ilevel, int unit) { if (isamp < 1 || isamp > my nx) return NUMundefined; return my v_getValueAtSample (isamp, ilevel, unit); } double Sampled_getValueAtX (Sampled me, double x, long ilevel, int unit, bool interpolate) { if (x < my xmin || x > my xmax) return NUMundefined; if (interpolate) { double ireal = Sampled_xToIndex (me, x); long ileft = (long) floor (ireal), inear, ifar; double phase = ireal - ileft; if (phase < 0.5) { inear = ileft, ifar = ileft + 1; } else { ifar = ileft, inear = ileft + 1; phase = 1.0 - phase; } if (inear < 1 || inear > my nx) return NUMundefined; // x out of range? double fnear = my v_getValueAtSample (inear, ilevel, unit); if (fnear == NUMundefined) return NUMundefined; // function value not defined? if (ifar < 1 || ifar > my nx) return fnear; // at edge? Extrapolate double ffar = my v_getValueAtSample (ifar, ilevel, unit); if (ffar == NUMundefined) return fnear; // neighbour undefined? Extrapolate return fnear + phase * (ffar - fnear); // interpolate } return Sampled_getValueAtSample (me, Sampled_xToNearestIndex (me, x), ilevel, unit); } long Sampled_countDefinedSamples (Sampled me, long ilevel, int unit) { long numberOfDefinedSamples = 0; for (long isamp = 1; isamp <= my nx; isamp ++) { double value = my v_getValueAtSample (isamp, ilevel, unit); if (value == NUMundefined) continue; numberOfDefinedSamples += 1; } return numberOfDefinedSamples; } double * Sampled_getSortedValues (Sampled me, long ilevel, int unit, long *return_numberOfValues) { long isamp, numberOfDefinedSamples = 0; autoNUMvector values (1, my nx); for (isamp = 1; isamp <= my nx; isamp ++) { double value = my v_getValueAtSample (isamp, ilevel, unit); if (value == NUMundefined) continue; values [++ numberOfDefinedSamples] = value; } if (numberOfDefinedSamples) NUMsort_d (numberOfDefinedSamples, values.peek()); if (return_numberOfValues) *return_numberOfValues = numberOfDefinedSamples; return values.transfer(); } double Sampled_getQuantile (Sampled me, double xmin, double xmax, double quantile, long ilevel, int unit) { try { autoNUMvector values (1, my nx); Function_unidirectionalAutowindow (me, & xmin, & xmax); if (! Function_intersectRangeWithDomain (me, & xmin, & xmax)) return NUMundefined; long imin, imax, numberOfDefinedSamples = 0; Sampled_getWindowSamples (me, xmin, xmax, & imin, & imax); for (long i = imin; i <= imax; i ++) { double value = my v_getValueAtSample (i, ilevel, unit); if (NUMdefined (value)) { values [++ numberOfDefinedSamples] = value; } } double result = NUMundefined; if (numberOfDefinedSamples >= 1) { NUMsort_d (numberOfDefinedSamples, values.peek()); result = NUMquantile (numberOfDefinedSamples, values.peek(), quantile); } return result; } catch (MelderError) { Melder_throw (me, U": quantile not computed."); } } static void Sampled_getSumAndDefinitionRange (Sampled me, double xmin, double xmax, long ilevel, int unit, bool interpolate, double *return_sum, double *return_definitionRange) { /* This function computes the area under the linearly interpolated curve between xmin and xmax. Outside [x1-dx/2, xN+dx/2], the curve is undefined and neither times nor values are counted. In [x1-dx/2,x1] and [xN,xN+dx/2], the curve is linearly extrapolated. */ long imin, imax, isamp; double sum = 0.0, definitionRange = 0.0; Function_unidirectionalAutowindow (me, & xmin, & xmax); if (Function_intersectRangeWithDomain (me, & xmin, & xmax)) { if (interpolate) { if (Sampled_getWindowSamples (me, xmin, xmax, & imin, & imax)) { double leftEdge = my x1 - 0.5 * my dx, rightEdge = leftEdge + my nx * my dx; for (isamp = imin; isamp <= imax; isamp ++) { double value = my v_getValueAtSample (isamp, ilevel, unit); // a fast way to integrate a linearly interpolated curve; works everywhere except at the edges if (NUMdefined (value)) { definitionRange += 1.0; sum += value; } } /* * Corrections within the first and last sampling intervals. */ if (xmin > leftEdge) { // otherwise, constant extrapolation over 0.5 sample is OK double phase = (my x1 + (imin - 1) * my dx - xmin) / my dx; // this fraction of sampling interval is still to be determined double rightValue = Sampled_getValueAtSample (me, imin, ilevel, unit); double leftValue = Sampled_getValueAtSample (me, imin - 1, ilevel, unit); if (NUMdefined (rightValue)) { definitionRange -= 0.5; // delete constant extrapolation over 0.5 sample sum -= 0.5 * rightValue; if (NUMdefined (leftValue)) { definitionRange += phase; /* Add current fraction. */ sum += phase * (rightValue + 0.5 * phase * (leftValue - rightValue)); // interpolate to outside sample } else { if (phase > 0.5) phase = 0.5; definitionRange += phase; // add current fraction, but never more than 0.5 sum += phase * rightValue; } } else if (NUMdefined (leftValue) && phase > 0.5) { definitionRange += phase - 0.5; sum += (phase - 0.5) * leftValue; } } if (xmax < rightEdge) { // otherwise, constant extrapolation is OK double phase = (xmax - (my x1 + (imax - 1) * my dx)) / my dx; // this fraction of sampling interval is still to be determined double leftValue = Sampled_getValueAtSample (me, imax, ilevel, unit); double rightValue = Sampled_getValueAtSample (me, imax + 1, ilevel, unit); if (NUMdefined (leftValue)) { definitionRange -= 0.5; // delete constant extrapolation over 0.5 sample sum -= 0.5 * leftValue; if (NUMdefined (rightValue)) { definitionRange += phase; // add current fraction sum += phase * (leftValue + 0.5 * phase * (rightValue - leftValue)); // interpolate to outside sample } else { if (phase > 0.5) phase = 0.5; definitionRange += phase; // add current fraction, but never more than 0.5 sum += phase * leftValue; } } else if (NUMdefined (rightValue) && phase > 0.5) { definitionRange += phase - 0.5; sum += (phase - 0.5) * rightValue; } } } else { /* No sample centres between xmin and xmax. */ /* * Try to return the mean of the interpolated values at these two points. * Thus, a small (xmin, xmax) range gives the same value as the (xmin+xmax)/2 point. */ double leftValue = Sampled_getValueAtSample (me, imax, ilevel, unit); double rightValue = Sampled_getValueAtSample (me, imin, ilevel, unit); double phase1 = (xmin - (my x1 + (imax - 1) * my dx)) / my dx; double phase2 = (xmax - (my x1 + (imax - 1) * my dx)) / my dx; if (imin == imax + 1) { // not too far from sample definition region if (NUMdefined (leftValue)) { if (NUMdefined (rightValue)) { definitionRange += phase2 - phase1; sum += (phase2 - phase1) * (leftValue + 0.5 * (phase1 + phase2) * (rightValue - leftValue)); } else if (phase1 < 0.5) { if (phase2 > 0.5) phase2 = 0.5; definitionRange += phase2 - phase1; sum += (phase2 - phase1) * leftValue; } } else if (NUMdefined (rightValue) && phase2 > 0.5) { if (phase1 < 0.5) phase1 = 0.5; definitionRange += phase2 - phase1; sum += (phase2 - phase1) * rightValue; } } } } else { // no interpolation double rimin = Sampled_xToIndex (me, xmin), rimax = Sampled_xToIndex (me, xmax); if (rimax >= 0.5 && rimin < my nx + 0.5) { imin = rimin < 0.5 ? 0 : (long) floor (rimin + 0.5); imax = rimax >= my nx + 0.5 ? my nx + 1 : (long) floor (rimax + 0.5); for (isamp = imin + 1; isamp < imax; isamp ++) { double value = my v_getValueAtSample (isamp, ilevel, unit); if (NUMdefined (value)) { definitionRange += 1.0; sum += value; } } if (imin == imax) { double value = my v_getValueAtSample (imin, ilevel, unit); if (NUMdefined (value)) { double phase = rimax - rimin; definitionRange += phase; sum += phase * value; } } else { if (imin >= 1) { double value = my v_getValueAtSample (imin, ilevel, unit); if (NUMdefined (value)) { double phase = imin - rimin + 0.5; definitionRange += phase; sum += phase * value; } } if (imax <= my nx) { double value = my v_getValueAtSample (imax, ilevel, unit); if (NUMdefined (value)) { double phase = rimax - imax + 0.5; definitionRange += phase; sum += phase * value; } } } } } } if (return_sum) *return_sum = sum; if (return_definitionRange) *return_definitionRange = definitionRange; } double Sampled_getMean (Sampled me, double xmin, double xmax, long ilevel, int unit, bool interpolate) { double sum, definitionRange; Sampled_getSumAndDefinitionRange (me, xmin, xmax, ilevel, unit, interpolate, & sum, & definitionRange); return definitionRange <= 0.0 ? NUMundefined : sum / definitionRange; } double Sampled_getMean_standardUnit (Sampled me, double xmin, double xmax, long ilevel, int averagingUnit, bool interpolate) { return Function_convertSpecialToStandardUnit (me, Sampled_getMean (me, xmin, xmax, ilevel, averagingUnit, interpolate), ilevel, averagingUnit); } double Sampled_getIntegral (Sampled me, double xmin, double xmax, long ilevel, int unit, bool interpolate) { double sum, definitionRange; Sampled_getSumAndDefinitionRange (me, xmin, xmax, ilevel, unit, interpolate, & sum, & definitionRange); return sum * my dx; } double Sampled_getIntegral_standardUnit (Sampled me, double xmin, double xmax, long ilevel, int averagingUnit, bool interpolate) { return Function_convertSpecialToStandardUnit (me, Sampled_getIntegral (me, xmin, xmax, ilevel, averagingUnit, interpolate), ilevel, averagingUnit); } static void Sampled_getSum2AndDefinitionRange (Sampled me, double xmin, double xmax, long ilevel, int unit, double mean, bool interpolate, double *return_sum2, double *return_definitionRange) { /* This function computes the area under the linearly interpolated squared difference curve between xmin and xmax. Outside [x1-dx/2, xN+dx/2], the curve is undefined and neither times nor values are counted. In [x1-dx/2,x1] and [xN,xN+dx/2], the curve is linearly extrapolated. */ long imin, imax; double sum2 = 0.0, definitionRange = 0.0; Function_unidirectionalAutowindow (me, & xmin, & xmax); if (Function_intersectRangeWithDomain (me, & xmin, & xmax)) { if (interpolate) { if (Sampled_getWindowSamples (me, xmin, xmax, & imin, & imax)) { double leftEdge = my x1 - 0.5 * my dx, rightEdge = leftEdge + my nx * my dx; for (long isamp = imin; isamp <= imax; isamp ++) { double value = my v_getValueAtSample (isamp, ilevel, unit); // a fast way to integrate a linearly interpolated curve; works everywhere except at the edges if (NUMdefined (value)) { value -= mean; value *= value; definitionRange += 1.0; sum2 += value; } } /* * Corrections within the first and last sampling intervals. */ if (xmin > leftEdge) { // otherwise, constant extrapolation over 0.5 sample is OK double phase = (my x1 + (imin - 1) * my dx - xmin) / my dx; // this fraction of sampling interval is still to be determined double rightValue = Sampled_getValueAtSample (me, imin, ilevel, unit); double leftValue = Sampled_getValueAtSample (me, imin - 1, ilevel, unit); if (NUMdefined (rightValue)) { rightValue -= mean; rightValue *= rightValue; definitionRange -= 0.5; // delete constant extrapolation over 0.5 sample sum2 -= 0.5 * rightValue; if (NUMdefined (leftValue)) { leftValue -= mean; leftValue *= leftValue; definitionRange += phase; // add current fraction sum2 += phase * (rightValue + 0.5 * phase * (leftValue - rightValue)); // interpolate to outside sample } else { if (phase > 0.5) phase = 0.5; definitionRange += phase; // add current fraction, but never more than 0.5 sum2 += phase * rightValue; } } else if (NUMdefined (leftValue) && phase > 0.5) { leftValue -= mean; leftValue *= leftValue; definitionRange += phase - 0.5; sum2 += (phase - 0.5) * leftValue; } } if (xmax < rightEdge) { // otherwise, constant extrapolation is OK double phase = (xmax - (my x1 + (imax - 1) * my dx)) / my dx; // this fraction of sampling interval is still to be determined double leftValue = Sampled_getValueAtSample (me, imax, ilevel, unit); double rightValue = Sampled_getValueAtSample (me, imax + 1, ilevel, unit); if (NUMdefined (leftValue)) { leftValue -= mean; leftValue *= leftValue; definitionRange -= 0.5; // delete constant extrapolation over 0.5 sample sum2 -= 0.5 * leftValue; if (NUMdefined (rightValue)) { rightValue -= mean; rightValue *= rightValue; definitionRange += phase; // add current fraction sum2 += phase * (leftValue + 0.5 * phase * (rightValue - leftValue)); // interpolate to outside sample } else { if (phase > 0.5) phase = 0.5; definitionRange += phase; // add current fraction, but never more than 0.5 sum2 += phase * leftValue; } } else if (NUMdefined (rightValue) && phase > 0.5) { rightValue -= mean; rightValue *= rightValue; definitionRange += phase - 0.5; sum2 += (phase - 0.5) * rightValue; } } } else { // no sample centres between xmin and xmax /* * Try to return the mean of the interpolated values at these two points. * Thus, a small (xmin, xmax) range gives the same value as the (xmin+xmax)/2 point. */ double leftValue = Sampled_getValueAtSample (me, imax, ilevel, unit); double rightValue = Sampled_getValueAtSample (me, imin, ilevel, unit); double phase1 = (xmin - (my x1 + (imax - 1) * my dx)) / my dx; double phase2 = (xmax - (my x1 + (imax - 1) * my dx)) / my dx; if (imin == imax + 1) { // not too far from sample definition region if (NUMdefined (leftValue)) { leftValue -= mean; leftValue *= leftValue; if (NUMdefined (rightValue)) { rightValue -= mean; rightValue *= rightValue; definitionRange += phase2 - phase1; sum2 += (phase2 - phase1) * (leftValue + 0.5 * (phase1 + phase2) * (rightValue - leftValue)); } else if (phase1 < 0.5) { if (phase2 > 0.5) phase2 = 0.5; definitionRange += phase2 - phase1; sum2 += (phase2 - phase1) * leftValue; } } else if (NUMdefined (rightValue) && phase2 > 0.5) { rightValue -= mean; rightValue *= rightValue; if (phase1 < 0.5) phase1 = 0.5; definitionRange += phase2 - phase1; sum2 += (phase2 - phase1) * rightValue; } } } } else { // no interpolation double rimin = Sampled_xToIndex (me, xmin), rimax = Sampled_xToIndex (me, xmax); if (rimax >= 0.5 && rimin < my nx + 0.5) { imin = rimin < 0.5 ? 0 : lround (rimin); imax = rimax >= my nx + 0.5 ? my nx + 1 : lround (rimax); for (long isamp = imin + 1; isamp < imax; isamp ++) { double value = my v_getValueAtSample (isamp, ilevel, unit); if (NUMdefined (value)) { value -= mean; value *= value; definitionRange += 1.0; sum2 += value; } } if (imin == imax) { double value = my v_getValueAtSample (imin, ilevel, unit); if (NUMdefined (value)) { double phase = rimax - rimin; value -= mean; value *= value; definitionRange += phase; sum2 += phase * value; } } else { if (imin >= 1) { double value = my v_getValueAtSample (imin, ilevel, unit); if (NUMdefined (value)) { double phase = imin - rimin + 0.5; value -= mean; value *= value; definitionRange += phase; sum2 += phase * value; } } if (imax <= my nx) { double value = my v_getValueAtSample (imax, ilevel, unit); if (NUMdefined (value)) { double phase = rimax - imax + 0.5; value -= mean; value *= value; definitionRange += phase; sum2 += phase * value; } } } } } } if (return_sum2) *return_sum2 = sum2; if (return_definitionRange) *return_definitionRange = definitionRange; } double Sampled_getStandardDeviation (Sampled me, double xmin, double xmax, long ilevel, int unit, bool interpolate) { double sum, sum2, definitionRange; Sampled_getSumAndDefinitionRange (me, xmin, xmax, ilevel, unit, interpolate, & sum, & definitionRange); if (definitionRange < 2.0) return NUMundefined; Sampled_getSum2AndDefinitionRange (me, xmin, xmax, ilevel, unit, sum / definitionRange, interpolate, & sum2, & definitionRange); return sqrt (sum2 / (definitionRange - 1.0)); } double Sampled_getStandardDeviation_standardUnit (Sampled me, double xmin, double xmax, long ilevel, int averagingUnit, bool interpolate) { return Function_convertSpecialToStandardUnit (me, Sampled_getStandardDeviation (me, xmin, xmax, ilevel, averagingUnit, interpolate), ilevel, averagingUnit); } void Sampled_getMinimumAndX (Sampled me, double xmin, double xmax, long ilevel, int unit, bool interpolate, double *return_minimum, double *return_xOfMinimum) { double minimum = 1e301, xOfMinimum = 0.0; if (xmin == NUMundefined || xmax == NUMundefined) { minimum = xOfMinimum = NUMundefined; goto end; } Function_unidirectionalAutowindow (me, & xmin, & xmax); if (! Function_intersectRangeWithDomain (me, & xmin, & xmax)) { minimum = xOfMinimum = NUMundefined; // requested range and logical domain do not intersect goto end; } long imin, imax; if (! Sampled_getWindowSamples (me, xmin, xmax, & imin, & imax)) { /* * No sample centres between xmin and xmax. * Try to return the lesser of the values at these two points. */ double fleft = Sampled_getValueAtX (me, xmin, ilevel, unit, interpolate); double fright = Sampled_getValueAtX (me, xmax, ilevel, unit, interpolate); if (NUMdefined (fleft) && fleft < minimum) minimum = fleft, xOfMinimum = xmin; if (NUMdefined (fright) && fright < minimum) minimum = fright, xOfMinimum = xmax; } else { for (long i = imin; i <= imax; i ++) { double fmid = my v_getValueAtSample (i, ilevel, unit); if (fmid == NUMundefined) continue; if (! interpolate) { if (fmid < minimum) minimum = fmid, xOfMinimum = i; } else { /* * Try an interpolation, possibly even taking into account a sample just outside the selection. */ double fleft = i <= 1 ? NUMundefined : my v_getValueAtSample (i - 1, ilevel, unit); double fright = i >= my nx ? NUMundefined : my v_getValueAtSample (i + 1, ilevel, unit); if (fleft == NUMundefined || fright == NUMundefined) { if (fmid < minimum) minimum = fmid, xOfMinimum = i; } else if (fmid < fleft && fmid <= fright) { double y [4], i_real, localMinimum; y [1] = fleft, y [2] = fmid, y [3] = fright; localMinimum = NUMimproveMinimum (y, 3, 2, NUM_PEAK_INTERPOLATE_PARABOLIC, & i_real); if (localMinimum < minimum) minimum = localMinimum, xOfMinimum = i_real + i - 2; } } } xOfMinimum = my x1 + (xOfMinimum - 1) * my dx; // from index plus phase to time /* Check boundary values. */ if (interpolate) { double fleft = Sampled_getValueAtX (me, xmin, ilevel, unit, true); double fright = Sampled_getValueAtX (me, xmax, ilevel, unit, true); if (NUMdefined (fleft) && fleft < minimum) minimum = fleft, xOfMinimum = xmin; if (NUMdefined (fright) && fright < minimum) minimum = fright, xOfMinimum = xmax; } if (xOfMinimum < xmin) xOfMinimum = xmin; if (xOfMinimum > xmax) xOfMinimum = xmax; } if (minimum == 1e301) minimum = xOfMinimum = NUMundefined; end: if (return_minimum) *return_minimum = minimum; if (return_xOfMinimum) *return_xOfMinimum = xOfMinimum; } double Sampled_getMinimum (Sampled me, double xmin, double xmax, long ilevel, int unit, bool interpolate) { double minimum; Sampled_getMinimumAndX (me, xmin, xmax, ilevel, unit, interpolate, & minimum, nullptr); return minimum; } double Sampled_getXOfMinimum (Sampled me, double xmin, double xmax, long ilevel, int unit, bool interpolate) { double time; Sampled_getMinimumAndX (me, xmin, xmax, ilevel, unit, interpolate, nullptr, & time); return time; } void Sampled_getMaximumAndX (Sampled me, double xmin, double xmax, long ilevel, int unit, bool interpolate, double *return_maximum, double *return_xOfMaximum) { double maximum = -1e301, xOfMaximum = 0.0; if (xmin == NUMundefined || xmax == NUMundefined) { maximum = xOfMaximum = NUMundefined; goto end; } Function_unidirectionalAutowindow (me, & xmin, & xmax); if (! Function_intersectRangeWithDomain (me, & xmin, & xmax)) { maximum = xOfMaximum = NUMundefined; // requested range and logical domain do not intersect goto end; } long imin, imax; if (! Sampled_getWindowSamples (me, xmin, xmax, & imin, & imax)) { /* * No sample centres between tmin and tmax. * Try to return the greater of the values at these two points. */ double fleft = Sampled_getValueAtX (me, xmin, ilevel, unit, interpolate); double fright = Sampled_getValueAtX (me, xmax, ilevel, unit, interpolate); if (NUMdefined (fleft) && fleft > maximum) maximum = fleft, xOfMaximum = xmin; if (NUMdefined (fright) && fright > maximum) maximum = fright, xOfMaximum = xmax; } else { for (long i = imin; i <= imax; i ++) { double fmid = my v_getValueAtSample (i, ilevel, unit); if (fmid == NUMundefined) continue; if (! interpolate) { if (fmid > maximum) maximum = fmid, xOfMaximum = i; } else { /* * Try an interpolation, possibly even taking into account a sample just outside the selection. */ double fleft = i <= 1 ? NUMundefined : my v_getValueAtSample (i - 1, ilevel, unit); double fright = i >= my nx ? NUMundefined : my v_getValueAtSample (i + 1, ilevel, unit); if (fleft == NUMundefined || fright == NUMundefined) { if (fmid > maximum) maximum = fmid, xOfMaximum = i; } else if (fmid > fleft && fmid >= fright) { double y [4], i_real, localMaximum; y [1] = fleft, y [2] = fmid, y [3] = fright; localMaximum = NUMimproveMaximum (y, 3, 2, NUM_PEAK_INTERPOLATE_PARABOLIC, & i_real); if (localMaximum > maximum) maximum = localMaximum, xOfMaximum = i_real + i - 2; } } } xOfMaximum = my x1 + (xOfMaximum - 1) * my dx; // from index plus phase to time /* Check boundary values. */ if (interpolate) { double fleft = Sampled_getValueAtX (me, xmin, ilevel, unit, true); double fright = Sampled_getValueAtX (me, xmax, ilevel, unit, true); if (NUMdefined (fleft) && fleft > maximum) maximum = fleft, xOfMaximum = xmin; if (NUMdefined (fright) && fright > maximum) maximum = fright, xOfMaximum = xmax; } if (xOfMaximum < xmin) xOfMaximum = xmin; if (xOfMaximum > xmax) xOfMaximum = xmax; } if (maximum == -1e301) maximum = xOfMaximum = NUMundefined; end: if (return_maximum) *return_maximum = maximum; if (return_xOfMaximum) *return_xOfMaximum = xOfMaximum; } double Sampled_getMaximum (Sampled me, double xmin, double xmax, long ilevel, int unit, bool interpolate) { double maximum; Sampled_getMaximumAndX (me, xmin, xmax, ilevel, unit, interpolate, & maximum, NULL); return maximum; } double Sampled_getXOfMaximum (Sampled me, double xmin, double xmax, long ilevel, int unit, bool interpolate) { double time; Sampled_getMaximumAndX (me, xmin, xmax, ilevel, unit, interpolate, NULL, & time); return time; } static void Sampled_speckleInside (Sampled me, Graphics g, double xmin, double xmax, double ymin, double ymax, long ilevel, int unit) { Function_unidirectionalAutowindow (me, & xmin, & xmax); long ixmin, ixmax; Sampled_getWindowSamples (me, xmin, xmax, & ixmin, & ixmax); if (Function_isUnitLogarithmic (me, ilevel, unit)) { ymin = Function_convertStandardToSpecialUnit (me, ymin, ilevel, unit); ymax = Function_convertStandardToSpecialUnit (me, ymax, ilevel, unit); } if (ymax <= ymin) return; Graphics_setWindow (g, xmin, xmax, ymin, ymax); for (long ix = ixmin; ix <= ixmax; ix ++) { double value = Sampled_getValueAtSample (me, ix, ilevel, unit); if (NUMdefined (value)) { double x = Sampled_indexToX (me, ix); if (value >= ymin && value <= ymax) { Graphics_speckle (g, x, value); } } } } void Sampled_drawInside (Sampled me, Graphics g, double xmin, double xmax, double ymin, double ymax, bool speckle, long ilevel, int unit) { try { if (speckle) { Sampled_speckleInside (me, g, xmin, xmax, ymin, ymax, ilevel, unit); return; } Function_unidirectionalAutowindow (me, & xmin, & xmax); long ixmin, ixmax, startOfDefinedStretch = -1; Sampled_getWindowSamples (me, xmin, xmax, & ixmin, & ixmax); if (Function_isUnitLogarithmic (me, ilevel, unit)) { ymin = Function_convertStandardToSpecialUnit (me, ymin, ilevel, unit); ymax = Function_convertStandardToSpecialUnit (me, ymax, ilevel, unit); } if (ymax <= ymin) return; Graphics_setWindow (g, xmin, xmax, ymin, ymax); autoNUMvector xarray (ixmin - 1, ixmax + 1); autoNUMvector yarray (ixmin - 1, ixmax + 1); double previousValue = Sampled_getValueAtSample (me, ixmin - 1, ilevel, unit); if (NUMdefined (previousValue)) { startOfDefinedStretch = ixmin - 1; xarray [ixmin - 1] = Sampled_indexToX (me, ixmin - 1); yarray [ixmin - 1] = previousValue; } for (long ix = ixmin; ix <= ixmax; ix ++) { double x = Sampled_indexToX (me, ix), value = Sampled_getValueAtSample (me, ix, ilevel, unit); if (NUMdefined (value)) { if (NUMdefined (previousValue)) { xarray [ix] = x; yarray [ix] = value; } else { startOfDefinedStretch = ix - 1; xarray [ix - 1] = x - 0.5 * my dx; yarray [ix - 1] = value; xarray [ix] = x; yarray [ix] = value; } } else if (NUMdefined (previousValue)) { Melder_assert (startOfDefinedStretch >= ixmin - 1); if (ix > ixmin) { xarray [ix] = x - 0.5 * my dx; yarray [ix] = previousValue; if (xarray [startOfDefinedStretch] < xmin) { double phase = (xmin - xarray [startOfDefinedStretch]) / my dx; xarray [startOfDefinedStretch] = xmin; yarray [startOfDefinedStretch] = phase * yarray [startOfDefinedStretch + 1] + (1.0 - phase) * yarray [startOfDefinedStretch]; } Graphics_polyline (g, ix + 1 - startOfDefinedStretch, & xarray [startOfDefinedStretch], & yarray [startOfDefinedStretch]); } startOfDefinedStretch = -1; } previousValue = value; } if (startOfDefinedStretch > -1) { double x = Sampled_indexToX (me, ixmax + 1), value = Sampled_getValueAtSample (me, ixmax + 1, ilevel, unit); Melder_assert (NUMdefined (previousValue)); if (NUMdefined (value)) { xarray [ixmax + 1] = x; yarray [ixmax + 1] = value; } else { xarray [ixmax + 1] = x - 0.5 * my dx; yarray [ixmax + 1] = previousValue; } if (xarray [startOfDefinedStretch] < xmin) { double phase = (xmin - xarray [startOfDefinedStretch]) / my dx; xarray [startOfDefinedStretch] = xmin; yarray [startOfDefinedStretch] = phase * yarray [startOfDefinedStretch + 1] + (1.0 - phase) * yarray [startOfDefinedStretch]; } if (xarray [ixmax + 1] > xmax) { double phase = (xarray [ixmax + 1] - xmax) / my dx; xarray [ixmax + 1] = xmax; yarray [ixmax + 1] = phase * yarray [ixmax] + (1.0 - phase) * yarray [ixmax + 1]; } Graphics_polyline (g, ixmax + 2 - startOfDefinedStretch, & xarray [startOfDefinedStretch], & yarray [startOfDefinedStretch]); } } catch (MelderError) { Melder_clearError (); } } /* End of file Sampled.cpp */ praat-6.0.04/fon/Sampled.h000066400000000000000000000122651261542461700152460ustar00rootroot00000000000000#ifndef _Sampled_h_ #define _Sampled_h_ /* Sampled.h * * Copyright (C) 1992-2011,2014 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Sampled inherits from Function */ #include "Function.h" #include "Graphics.h" #include "Sampled_def.h" oo_CLASS_CREATE (Sampled, Function); /* A Sampled is a Function that is sampled at nx points [1..nx], */ /* which are spaced apart by a constant distance dx. */ /* The first sample point is at x1, the second at x1 + dx, */ /* and the last at x1 + (nx - 1) * dx. */ static inline double Sampled_indexToX (Sampled me, long index) { return my x1 + (index - 1 ) * my dx; } static inline double Sampled_indexToX (Sampled me, double index) { return my x1 + (index - 1.0) * my dx; } static inline double Sampled_xToIndex (Sampled me, double x) { return (x - my x1) / my dx + 1.0; } static inline long Sampled_xToLowIndex (Sampled me, double x) { return (long) floor ((x - my x1) / my dx + 1.0); } static inline long Sampled_xToHighIndex (Sampled me, double x) { return (long) ceil ((x - my x1) / my dx + 1.0); } static inline long Sampled_xToNearestIndex (Sampled me, double x) { return (long) round ((x - my x1) / my dx + 1.0); } long Sampled_getWindowSamples (Sampled me, double xmin, double xmax, long *ixmin, long *ixmax); void Sampled_init (Sampled me, double xmin, double xmax, long nx, double dx, double x1); void Sampled_shortTermAnalysis (Sampled me, double windowDuration, double timeStep, long *numberOfFrames, double *firstTime); /* Function: how to put as many analysis windows of length 'windowDuration' as possible into my duration, when they are equally spaced by 'timeStep'. Input arguments: windowDuration: the duration of the analysis window, in seconds. timeStep: the time step, in seconds. Output arguments: numberOfFrames: at least 1 (if no failure); equals floor ((nx * dx - windowDuration) / timeStep) + 1. firstTime: the centre of the first frame, in seconds. Failures: Window longer than signal. Postconditions: the frames are divided symmetrically over my defined domain, which is [x1 - dx/2, x[nx] + dx/2], where x[nx] == x1 + (nx - 1) * dx. All analysis windows will fit into this domain. Usage: the resulting Sampled (analysis sequence, e.g., Pitch, Formant, Spectrogram, etc.) will have the following attributes: result -> xmin == my xmin; // Copy logical domain. result -> xmax == my xmax; result -> nx == numberOfFrames; result -> dx == timeStep; result -> x1 == firstTime; */ double Sampled_getValueAtSample (Sampled me, long isamp, long ilevel, int unit); double Sampled_getValueAtX (Sampled me, double x, long ilevel, int unit, bool interpolate); long Sampled_countDefinedSamples (Sampled me, long ilevel, int unit); double * Sampled_getSortedValues (Sampled me, long ilevel, int unit, long *numberOfValues); double Sampled_getQuantile (Sampled me, double xmin, double xmax, double quantile, long ilevel, int unit); double Sampled_getMean (Sampled me, double xmin, double xmax, long ilevel, int unit, bool interpolate); double Sampled_getMean_standardUnit (Sampled me, double xmin, double xmax, long ilevel, int averagingUnit, bool interpolate); double Sampled_getIntegral (Sampled me, double xmin, double xmax, long ilevel, int unit, bool interpolate); double Sampled_getIntegral_standardUnit (Sampled me, double xmin, double xmax, long ilevel, int averagingUnit, bool interpolate); double Sampled_getStandardDeviation (Sampled me, double xmin, double xmax, long ilevel, int unit, bool interpolate); double Sampled_getStandardDeviation_standardUnit (Sampled me, double xmin, double xmax, long ilevel, int averagingUnit, bool interpolate); void Sampled_getMinimumAndX (Sampled me, double xmin, double xmax, long ilevel, int unit, bool interpolate, double *return_minimum, double *return_xOfMinimum); double Sampled_getMinimum (Sampled me, double xmin, double xmax, long ilevel, int unit, bool interpolate); double Sampled_getXOfMinimum (Sampled me, double xmin, double xmax, long ilevel, int unit, bool interpolate); void Sampled_getMaximumAndX (Sampled me, double xmin, double xmax, long ilevel, int unit, bool interpolate, double *return_maximum, double *return_xOfMaximum); double Sampled_getMaximum (Sampled me, double xmin, double xmax, long ilevel, int unit, bool interpolate); double Sampled_getXOfMaximum (Sampled me, double xmin, double xmax, long ilevel, int unit, bool interpolate); void Sampled_drawInside (Sampled me, Graphics g, double xmin, double xmax, double ymin, double ymax, bool speckle, long ilevel, int unit); /* End of file Sampled.h */ #endif praat-6.0.04/fon/SampledXY.cpp000066400000000000000000000037761261542461700160710ustar00rootroot00000000000000/* SampledXY.cpp * * Copyright (C) 1992-2012,2013,2014 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "SampledXY.h" #include "oo_DESTROY.h" #include "SampledXY_def.h" #include "oo_COPY.h" #include "SampledXY_def.h" #include "oo_EQUAL.h" #include "SampledXY_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "SampledXY_def.h" #include "oo_WRITE_TEXT.h" #include "SampledXY_def.h" #include "oo_READ_TEXT.h" #include "SampledXY_def.h" #include "oo_WRITE_BINARY.h" #include "SampledXY_def.h" #include "oo_READ_BINARY.h" #include "SampledXY_def.h" #include "oo_DESCRIPTION.h" #include "SampledXY_def.h" Thing_implement (SampledXY, Sampled, 0); void SampledXY_init (SampledXY me, double xmin, double xmax, long nx, double dx, double x1, double ymin, double ymax, long ny, double dy, double y1) { Sampled_init (me, xmin, xmax, nx, dx, x1); my ymin = ymin; my ymax = ymax; my ny = ny; my dy = dy; my y1 = y1; } long SampledXY_getWindowSamplesY (SampledXY me, double fromY, double toY, long *iymin, long *iymax) { double riymin = 1.0 + ceil ((fromY - my y1) / my dy); double riymax = 1.0 + floor ((toY - my y1) / my dy); // could be above 32-bit LONG_MAX *iymin = riymin < 1.0 ? 1 : (long) riymin; *iymax = riymax > (double) my ny ? my ny : (long) riymax; if (*iymin > *iymax) return 0; return *iymax - *iymin + 1; } /* End of file SampledXY.cpp */ praat-6.0.04/fon/SampledXY.h000066400000000000000000000036041261542461700155240ustar00rootroot00000000000000#ifndef _SampledXY_h_ #define _SampledXY_h_ /* SampledXY.h * * Copyright (C) 1992-2011,2013,2014 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Sampled.h" #include "SampledXY_def.h" oo_CLASS_CREATE (SampledXY, Sampled); void SampledXY_init (SampledXY me, double xmin, double xmax, long nx, double dx, double x1, double ymin, double ymax, long ny, double dy, double y1); static inline double SampledXY_indexToY (SampledXY me, long index) { return my y1 + (index - 1 ) * my dy; } static inline double SampledXY_indexToY (SampledXY me, double index) { return my y1 + (index - 1.0) * my dy; } static inline double SampledXY_yToIndex (SampledXY me, double y) { return (y - my y1) / my dy + 1.0; } static inline long SampledXY_yToLowIndex (SampledXY me, double y) { return (long) floor ((y - my y1) / my dy + 1.0); } static inline long SampledXY_yToHighIndex (SampledXY me, double y) { return (long) ceil ((y - my y1) / my dy + 1.0); } static inline long SampledXY_yToNearestIndex (SampledXY me, double y) { return (long) round ((y - my y1) / my dy + 1.0); } long SampledXY_getWindowSamplesY (SampledXY me, double ymin, double ymax, long *iymin, long *iymax); /* End of file SampledXY.h */ #endif praat-6.0.04/fon/SampledXY_def.h000066400000000000000000000030731261542461700163420ustar00rootroot00000000000000/* SampledXY_def.h * * Copyright (C) 1992-2011,2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 20131022 split off from Matrix */ #define ooSTRUCT SampledXY oo_DEFINE_CLASS (SampledXY, Sampled) oo_DOUBLE (ymin) oo_DOUBLE (ymax) oo_LONG (ny) oo_DOUBLE (dy) oo_DOUBLE (y1) #if oo_DECLARING bool v_hasGetYmin () override { return true; } double v_getYmin () override { return ymin; } bool v_hasGetYmax () override { return true; } double v_getYmax () override { return ymax; } bool v_hasGetNy () override { return true; } double v_getNy () override { return ny; } bool v_hasGetDy () override { return true; } double v_getDy () override { return dy; } bool v_hasGetY () override { return true; } double v_getY (long iy) override { return y1 + (iy - 1) * dy; } #endif oo_END_CLASS (SampledXY) #undef ooSTRUCT /* End of file SampledXY_def.h */ praat-6.0.04/fon/Sampled_def.h000066400000000000000000000030361261542461700160600ustar00rootroot00000000000000/* Sampled_def.h * * Copyright (C) 1992-2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT Sampled oo_DEFINE_CLASS (Sampled, Function) oo_INT32 (nx) oo_DOUBLE (dx) oo_DOUBLE (x1) #if oo_DECLARING bool v_hasGetNx () override { return true; } double v_getNx () override { return nx; } bool v_hasGetDx () override { return true; } double v_getDx () override { return dx; } bool v_hasGetX () override { return true; } double v_getX (long ix) override { return x1 + (ix - 1) * dx; } void v_shiftX (double xfrom, double xto) override; void v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto) override; virtual double v_getValueAtSample (long /* isamp */, long /* ilevel */, int /* unit */) { return NUMundefined; } #endif oo_END_CLASS (Sampled) #undef ooSTRUCT /* End of file Sampled_def.h */ praat-6.0.04/fon/Sound.cpp000066400000000000000000001365211261542461700153060ustar00rootroot00000000000000/* Sound.cpp * * Copyright (C) 1992-2012,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * a selection of changes: * pb 2006/12/31 stereo * pb 2010/03/26 Sounds_convolve, Sounds_crossCorrelate, Sound_autocorrelate */ #include "Sound.h" #include "Sound_extensions.h" #include "NUM2.h" #include "enums_getText.h" #include "Sound_enums.h" #include "enums_getValue.h" #include "Sound_enums.h" Thing_implement (Sound, Vector, 2); Sound Sound_clipboard; void structSound :: v_info () { structDaata :: v_info (); const double rho_c = 400; /* rho = 1.14 kg m-3; c = 353 m s-1; [rho c] = kg m-2 s-1 */ double minimum = z [1] [1], maximum = minimum; MelderInfo_writeLine (U"Number of channels: ", ny, ny == 1 ? U" (mono)" : ny == 2 ? U" (stereo)" : U""); MelderInfo_writeLine (U"Time domain:"); MelderInfo_writeLine (U" Start time: ", xmin, U" seconds"); MelderInfo_writeLine (U" End time: ", xmax, U" seconds"); MelderInfo_writeLine (U" Total duration: ", xmax - xmin, U" seconds"); MelderInfo_writeLine (U"Time sampling:"); MelderInfo_writeLine (U" Number of samples: ", nx); MelderInfo_writeLine (U" Sampling period: ", dx, U" seconds"); MelderInfo_writeLine (U" Sampling frequency: ", Melder_single (1.0 / dx), U" Hz"); MelderInfo_writeLine (U" First sample centred at: ", x1, U" seconds"); {// scope double sum = 0.0, sumOfSquares = 0.0; for (long channel = 1; channel <= ny; channel ++) { double *amplitude = z [channel]; for (long i = 1; i <= nx; i ++) { double value = amplitude [i]; sum += value; sumOfSquares += value * value; if (value < minimum) minimum = value; if (value > maximum) maximum = value; } } MelderInfo_writeLine (U"Amplitude:"); MelderInfo_writeLine (U" Minimum: ", Melder_single (minimum), U" Pascal"); MelderInfo_writeLine (U" Maximum: ", Melder_single (maximum), U" Pascal"); double mean = sum / (nx * ny); MelderInfo_writeLine (U" Mean: ", Melder_single (mean), U" Pascal"); MelderInfo_writeLine (U" Root-mean-square: ", Melder_single (sqrt (sumOfSquares / (nx * ny))), U" Pascal"); double penergy = sumOfSquares * dx / ny; /* Pa2 s = kg2 m-2 s-3 */ MelderInfo_write (U"Total energy: ", Melder_single (penergy), U" Pascal\u00B2 sec"); double energy = penergy / rho_c; /* kg s-2 = Joule m-2 */ MelderInfo_writeLine (U" (energy in air: ", Melder_single (energy), U" Joule/m\u00B2)"); double power = energy / (dx * nx); /* kg s-3 = Watt/m2 */ MelderInfo_write (U"Mean power (intensity) in air: ", Melder_single (power), U" Watt/m\u00B2"); if (power != 0.0) { MelderInfo_writeLine (U" = ", Melder_half (10 * log10 (power / 1e-12)), U" dB"); } else { MelderInfo_writeLine (U""); } } if (nx > 1) { for (long channel = 1; channel <= ny; channel ++) { double *amplitude = z [channel]; double sum = 0.0; for (long i = 1; i <= nx; i ++) { double value = amplitude [i]; sum += value; } double mean = sum / nx, stdev = 0.0; for (long i = 1; i <= nx; i ++) { double value = amplitude [i] - mean; stdev += value * value; } stdev = sqrt (stdev / (nx - 1)); MelderInfo_writeLine (U"Standard deviation in channel ", channel, U": ", Melder_single (stdev), U" Pascal"); } } } double structSound :: v_getMatrix (long irow, long icol) { if (irow < 1 || irow > ny) { if (irow == 0) { if (icol < 1 || icol > nx) return 0.0; if (ny == 1) return z [1] [icol]; // optimization if (ny == 2) return 0.5 * (z [1] [icol] + z [2] [icol]); // optimization double sum = 0.0; for (long channel = 1; channel <= ny; channel ++) { sum += z [channel] [icol]; } return sum / ny; } return 0.0; } if (icol < 1 || icol > nx) return 0.0; return z [irow] [icol]; } double structSound :: v_getFunction2 (double x, double y) { long channel = (long) floor (y); if (channel < 0 || channel > ny || y != (double) channel) return 0.0; return v_getFunction1 (channel, x); } autoSound Sound_create (long numberOfChannels, double xmin, double xmax, long nx, double dx, double x1) { try { autoSound me = Thing_new (Sound); Matrix_init (me.peek(), xmin, xmax, nx, dx, x1, 1, numberOfChannels, numberOfChannels, 1, 1); return me; } catch (MelderError) { Melder_throw (U"Sound not created."); } } autoSound Sound_createSimple (long numberOfChannels, double duration, double samplingFrequency) { Melder_assert (duration >= 0.0); Melder_assert (samplingFrequency > 0.0); double numberOfSamples_f = round (duration * samplingFrequency); if (numberOfSamples_f > (double) INT32_MAX) Melder_throw (U"Cannot create sounds with more than ", Melder_bigInteger (INT32_MAX), U" samples, because they cannot be saved to disk."); return Sound_create (numberOfChannels, 0.0, duration, (long) (int32_t) numberOfSamples_f, 1.0 / samplingFrequency, 0.5 / samplingFrequency); } autoSound Sound_convertToMono (Sound me) { if (my ny == 1) return Data_copy (me); // optimization try { autoSound thee = Sound_create (1, my xmin, my xmax, my nx, my dx, my x1); if (my ny == 2) { // Optimization. for (long i = 1; i <= my nx; i ++) { thy z [1] [i] = 0.5 * (my z [1] [i] + my z [2] [i]); } } else { for (long i = 1; i <= my nx; i ++) { double sum = my z [1] [i] + my z [2] [i] + my z [3] [i]; for (long channel = 4; channel <= my ny; channel ++) { sum += my z [channel] [i]; } thy z [1] [i] = sum / my ny; } } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to mono."); } } autoSound Sound_convertToStereo (Sound me) { if (my ny == 2) return Data_copy (me); try { if (my ny > 2) { Melder_throw (U"The Sound has ", my ny, U" channels; don't know which to choose."); } Melder_assert (my ny == 1); autoSound thee = Sound_create (2, my xmin, my xmax, my nx, my dx, my x1); for (long i = 1; i <= my nx; i ++) { thy z [1] [i] = thy z [2] [i] = my z [1] [i]; } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to stereo."); } } autoSound Sounds_combineToStereo (Collection me) { try { long totalNumberOfChannels = 0; double sharedSamplingPeriod = 0.0; for (long isound = 1; isound <= my size; isound ++) { Sound sound = (Sound) my item [isound]; totalNumberOfChannels += sound -> ny; if (sharedSamplingPeriod == 0.0) { sharedSamplingPeriod = sound -> dx; } else if (sound -> dx != sharedSamplingPeriod) { Melder_throw (U"To combine sounds, their sampling frequencies must be equal.\n" U"You could resample one or more of the sounds before combining."); } } double sharedMinimumTime = NUMundefined, sharedMaximumTime = NUMundefined; for (long isound = 1; isound <= my size; isound ++) { Sound sound = (Sound) my item [isound]; if (isound == 1) { sharedMinimumTime = sound -> xmin; sharedMaximumTime = sound -> xmax; } else { if (sound -> xmin < sharedMinimumTime) sharedMinimumTime = sound -> xmin; if (sound -> xmax > sharedMaximumTime) sharedMaximumTime = sound -> xmax; } } autoNUMvector numberOfInitialZeroes (1, my size); long sharedNumberOfSamples = 0; double sumOfFirstTimes = 0.0; for (long isound = 1; isound <= my size; isound ++) { Sound sound = (Sound) my item [isound]; numberOfInitialZeroes [isound] = floor ((sound -> xmin - sharedMinimumTime) / sharedSamplingPeriod); double newFirstTime = sound -> x1 - sound -> dx * numberOfInitialZeroes [isound]; sumOfFirstTimes += newFirstTime; long newNumberOfSamplesThroughLastNonzero = sound -> nx + (long) floor (numberOfInitialZeroes [isound]); if (newNumberOfSamplesThroughLastNonzero > sharedNumberOfSamples) sharedNumberOfSamples = newNumberOfSamplesThroughLastNonzero; } double sharedTimeOfFirstSample = sumOfFirstTimes / my size; // this is an approximation autoSound thee = Sound_create (totalNumberOfChannels, sharedMinimumTime, sharedMaximumTime, sharedNumberOfSamples, sharedSamplingPeriod, sharedTimeOfFirstSample); long channelNumber = 0; for (long isound = 1; isound <= my size; isound ++) { Sound sound = (Sound) my item [isound]; long offset = (long) floor (numberOfInitialZeroes [isound]); for (long ichan = 1; ichan <= sound -> ny; ichan ++) { channelNumber ++; for (long isamp = 1; isamp <= sound -> nx; isamp ++) { thy z [channelNumber] [isamp + offset] = sound -> z [ichan] [isamp]; } } } return thee; } catch (MelderError) { Melder_throw (U"Sounds not combined to stereo."); } } autoSound Sound_extractChannel (Sound me, long ichan) { try { if (ichan <= 0 || ichan > my ny) Melder_throw (U"There is no channel ", ichan, U"."); autoSound thee = Sound_create (1, my xmin, my xmax, my nx, my dx, my x1); for (long isamp = 1; isamp <= my nx; isamp ++) { thy z [1] [isamp] = my z [ichan] [isamp]; } return thee; } catch (MelderError) { Melder_throw (me, U": channel ", ichan, U" not extracted."); } } static double getSumOfSquares (Sound me, double xmin, double xmax, long *n) { if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } long imin, imax; *n = Sampled_getWindowSamples (me, xmin, xmax, & imin, & imax); if (*n < 1) return NUMundefined; double sum2 = 0.0; for (long channel = 1; channel <= my ny; channel ++) { double *amplitude = my z [channel]; for (long i = imin; i <= imax; i ++) { double value = amplitude [i]; sum2 += value * value; } } return sum2; } double Sound_getRootMeanSquare (Sound me, double xmin, double xmax) { long n; double sum2 = getSumOfSquares (me, xmin, xmax, & n); return NUMdefined (sum2) ? sqrt (sum2 / (n * my ny)) : NUMundefined; } double Sound_getEnergy (Sound me, double xmin, double xmax) { long n; double sum2 = getSumOfSquares (me, xmin, xmax, & n); return NUMdefined (sum2) ? sum2 * my dx / my ny : NUMundefined; } double Sound_getPower (Sound me, double xmin, double xmax) { long n; double sum2 = getSumOfSquares (me, xmin, xmax, & n); return NUMdefined (sum2) ? sum2 / (n * my ny) : NUMundefined; } double Sound_getEnergyInAir (Sound me) { long n; double sum2 = getSumOfSquares (me, 0, 0, & n); return NUMdefined (sum2) ? sum2 * my dx / (400 * my ny) : NUMundefined; } double Sound_getIntensity_dB (Sound me) { long n; double sum2 = getSumOfSquares (me, 0, 0, & n); return NUMdefined (sum2) && sum2 != 0.0 ? 10 * log10 (sum2 / (n * my ny) / 4.0e-10) : NUMundefined; } double Sound_getPowerInAir (Sound me) { long n; double sum2 = getSumOfSquares (me, 0, 0, & n); return NUMdefined (sum2) ? sum2 / (n * my ny) / 400 : NUMundefined; } autoSound Matrix_to_Sound_mono (Matrix me, long row) { try { autoSound thee = Sound_create (1, my xmin, my xmax, my nx, my dx, my x1); if (row < 0) row = my ny + 1 + row; if (row < 1) row = 1; if (row > my ny) row = my ny; NUMvector_copyElements (my z [row], thy z [1], 1, my nx); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Sound."); } } autoSound Matrix_to_Sound (Matrix me) { try { autoSound thee = Thing_new (Sound); my structMatrix :: v_copy (thee.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Sound."); } } autoMatrix Sound_to_Matrix (Sound me) { try { autoMatrix thee = Thing_new (Matrix); my structMatrix :: v_copy (thee.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Matrix."); } } autoSound Sound_upsample (Sound me) { try { long nfft = 1; while (nfft < my nx + 2000) nfft *= 2; autoSound thee = Sound_create (my ny, my xmin, my xmax, my nx * 2, my dx / 2, my x1 - my dx / 4); for (long channel = 1; channel <= my ny; channel ++) { autoNUMvector data (1, 2 * nfft); // zeroing is important... NUMvector_copyElements (my z [channel], & data [1000], 1, my nx); // ...because this fills only part of the sound NUMrealft (data.peek(), nfft, 1); long imin = (long) (nfft * 0.95); for (long i = imin + 1; i <= nfft; i ++) { data [i] *= ((double) (nfft - i)) / (nfft - imin); } data [2] = 0.0; NUMrealft (data.peek(), 2 * nfft, -1); double factor = 1.0 / nfft; for (long i = 1; i <= thy nx; i ++) { thy z [channel] [i] = data [i + 2000] * factor; } } return thee; } catch (MelderError) { Melder_throw (me, U": not upsampled."); } } autoSound Sound_resample (Sound me, double samplingFrequency, long precision) { double upfactor = samplingFrequency * my dx; if (fabs (upfactor - 2) < 1e-6) return Sound_upsample (me); if (fabs (upfactor - 1) < 1e-6) return Data_copy (me); try { long numberOfSamples = lround ((my xmax - my xmin) * samplingFrequency); if (numberOfSamples < 1) Melder_throw (U"The resampled Sound would have no samples."); autoSound filtered; if (upfactor < 1.0) { // need anti-aliasing filter? long nfft = 1, antiTurnAround = 1000; while (nfft < my nx + antiTurnAround * 2) nfft *= 2; autoNUMvector data (1, nfft); filtered = Sound_create (my ny, my xmin, my xmax, my nx, my dx, my x1); for (long channel = 1; channel <= my ny; channel ++) { for (long i = 1; i <= nfft; i ++) { data [i] = 0.0; } NUMvector_copyElements (my z [channel], & data [antiTurnAround], 1, my nx); NUMrealft (data.peek(), nfft, 1); // go to the frequency domain for (long i = (long) floor (upfactor * nfft); i <= nfft; i ++) { data [i] = 0.0; // filter away high frequencies } data [2] = 0.0; NUMrealft (data.peek(), nfft, -1); // return to the time domain double factor = 1.0 / nfft; double *to = filtered -> z [channel]; for (long i = 1; i <= my nx; i ++) { to [i] = data [i + antiTurnAround] * factor; } } me = filtered.peek(); // reference copy; remove at end } autoSound thee = Sound_create (my ny, my xmin, my xmax, numberOfSamples, 1.0 / samplingFrequency, 0.5 * (my xmin + my xmax - (numberOfSamples - 1) / samplingFrequency)); for (long channel = 1; channel <= my ny; channel ++) { double *from = my z [channel]; double *to = thy z [channel]; if (precision <= 1) { for (long i = 1; i <= numberOfSamples; i ++) { double x = Sampled_indexToX (thee.peek(), i); double index = Sampled_xToIndex (me, x); long leftSample = (long) floor (index); double fraction = index - leftSample; to [i] = leftSample < 1 || leftSample >= my nx ? 0.0 : (1 - fraction) * from [leftSample] + fraction * from [leftSample + 1]; } } else { for (long i = 1; i <= numberOfSamples; i ++) { double x = Sampled_indexToX (thee.peek(), i); double index = Sampled_xToIndex (me, x); to [i] = NUM_interpolate_sinc (my z [channel], my nx, index, precision); } } } return thee; } catch (MelderError) { Melder_throw (me, U": not resampled."); } } autoSound Sounds_append (Sound me, double silenceDuration, Sound thee) { try { long nx_silence = lround (silenceDuration / my dx), nx = my nx + nx_silence + thy nx; if (my ny != thy ny) Melder_throw (U"The numbers of channels are not equal (e.g. one is mono, the other stereo)."); if (my dx != thy dx) Melder_throw (U"The sampling frequencies are not equal."); autoSound him = Sound_create (my ny, 0.0, nx * my dx, nx, my dx, 0.5 * my dx); for (long channel = 1; channel <= my ny; channel ++) { NUMvector_copyElements (my z [channel], his z [channel], 1, my nx); NUMvector_copyElements (thy z [channel], his z [channel] + my nx + nx_silence, 1, thy nx); } return him; } catch (MelderError) { Melder_throw (me, U" & ", thee, U": not appended."); } } autoSound Sounds_concatenate_e (Collection me, double overlapTime) { try { long numberOfChannels = 0, nx = 0, numberOfSmoothingSamples; double dx = 0.0; for (long i = 1; i <= my size; i ++) { Sound sound = (Sound) my item [i]; if (numberOfChannels == 0) { numberOfChannels = sound -> ny; } else if (sound -> ny != numberOfChannels) { Melder_throw (U"To concatenate sounds, their numbers of channels (mono, stereo) must be equal."); } if (dx == 0.0) { dx = sound -> dx; } else if (sound -> dx != dx) { Melder_throw (U"To concatenate sounds, their sampling frequencies must be equal.\n" U"You could resample one or more of the sounds before concatenating."); } nx += sound -> nx; } numberOfSmoothingSamples = lround (overlapTime / dx); autoSound thee = Sound_create (numberOfChannels, 0.0, nx * dx, nx, dx, 0.5 * dx); autoNUMvector smoother; if (numberOfSmoothingSamples > 0) { smoother.reset (1, numberOfSmoothingSamples); double factor = NUMpi / numberOfSmoothingSamples; for (long i = 1; i <= numberOfSmoothingSamples; i ++) { smoother [i] = 0.5 - 0.5 * cos (factor * (i - 0.5)); } } nx = 0; for (long i = 1; i <= my size; i ++) { Sound sound = (Sound) my item [i]; if (numberOfSmoothingSamples > 2 * sound -> nx) Melder_throw (U"At least one of the sounds is shorter than twice the overlap time.\nChoose a shorter overlap time."); bool thisIsTheFirstSound = ( i == 1 ); bool thisIsTheLastSound = ( i == my size ); bool weNeedSmoothingAtTheStartOfThisSound = ! thisIsTheFirstSound; bool weNeedSmoothingAtTheEndOfThisSound = ! thisIsTheLastSound; long numberOfSmoothingSamplesAtTheStartOfThisSound = weNeedSmoothingAtTheStartOfThisSound ? numberOfSmoothingSamples : 0; long numberOfSmoothingSamplesAtTheEndOfThisSound = weNeedSmoothingAtTheEndOfThisSound ? numberOfSmoothingSamples : 0; for (long channel = 1; channel <= numberOfChannels; channel ++) { for (long j = 1, mySample = 1, thySample = mySample + nx; j <= numberOfSmoothingSamplesAtTheStartOfThisSound; j ++, mySample ++, thySample ++) { thy z [channel] [thySample] += sound -> z [channel] [mySample] * smoother [j]; // add } NUMvector_copyElements (sound -> z [channel], thy z [channel] + nx, 1 + numberOfSmoothingSamplesAtTheStartOfThisSound, sound -> nx - numberOfSmoothingSamplesAtTheEndOfThisSound); for (long j = 1, mySample = sound -> nx - numberOfSmoothingSamplesAtTheEndOfThisSound + 1, thySample = mySample + nx; j <= numberOfSmoothingSamplesAtTheEndOfThisSound; j ++, mySample ++, thySample ++) { thy z [channel] [thySample] = sound -> z [channel] [mySample] * smoother [numberOfSmoothingSamplesAtTheEndOfThisSound + 1 - j]; // replace (or add, which is the same since it's all zeroes to start with) } } nx += sound -> nx - numberOfSmoothingSamplesAtTheEndOfThisSound; } thy nx -= numberOfSmoothingSamples * (my size - 1); Melder_assert (thy nx == nx); thy xmax = thy nx * dx; return thee; } catch (MelderError) { Melder_throw (U"Sounds not concatenated."); } } autoSound Sounds_convolve (Sound me, Sound thee, enum kSounds_convolve_scaling scaling, enum kSounds_convolve_signalOutsideTimeDomain signalOutsideTimeDomain) { try { if (my ny > 1 && thy ny > 1 && my ny != thy ny) Melder_throw (U"The numbers of channels of the two sounds have to be equal or 1."); if (my dx != thy dx) Melder_throw (U"The sampling frequencies of the two sounds have to be equal."); long n1 = my nx, n2 = thy nx; long n3 = n1 + n2 - 1, nfft = 1; while (nfft < n3) nfft *= 2; autoNUMvector data1 (1, nfft); autoNUMvector data2 (1, nfft); long numberOfChannels = my ny > thy ny ? my ny : thy ny; autoSound him = Sound_create (numberOfChannels, my xmin + thy xmin, my xmax + thy xmax, n3, my dx, my x1 + thy x1); for (long channel = 1; channel <= numberOfChannels; channel ++) { double *a = my z [my ny == 1 ? 1 : channel]; for (long i = n1; i > 0; i --) data1 [i] = a [i]; for (long i = n1 + 1; i <= nfft; i ++) data1 [i] = 0.0; a = thy z [thy ny == 1 ? 1 : channel]; for (long i = n2; i > 0; i --) data2 [i] = a [i]; for (long i = n2 + 1; i <= nfft; i ++) data2 [i] = 0.0; NUMrealft (data1.peek(), nfft, 1); NUMrealft (data2.peek(), nfft, 1); data2 [1] *= data1 [1]; data2 [2] *= data1 [2]; for (long i = 3; i <= nfft; i += 2) { double temp = data1 [i] * data2 [i] - data1 [i + 1] * data2 [i + 1]; data2 [i + 1] = data1 [i] * data2 [i + 1] + data1 [i + 1] * data2 [i]; data2 [i] = temp; } NUMrealft (data2.peek(), nfft, -1); a = him -> z [channel]; for (long i = 1; i <= n3; i ++) { a [i] = data2 [i]; } } switch (signalOutsideTimeDomain) { case kSounds_convolve_signalOutsideTimeDomain_ZERO: { // do nothing } break; case kSounds_convolve_signalOutsideTimeDomain_SIMILAR: { for (long channel = 1; channel <= numberOfChannels; channel ++) { double *a = his z [channel]; double edge = n1 < n2 ? n1 : n2; for (long i = 1; i < edge; i ++) { double factor = edge / i; a [i] *= factor; a [n3 + 1 - i] *= factor; } } } break; //case kSounds_convolve_signalOutsideTimeDomain_PERIODIC: { // do nothing //} break; default: Melder_fatal (U"Sounds_convolve: unimplemented outside-time-domain strategy ", signalOutsideTimeDomain); } switch (scaling) { case kSounds_convolve_scaling_INTEGRAL: { Vector_multiplyByScalar (him.peek(), my dx / nfft); } break; case kSounds_convolve_scaling_SUM: { Vector_multiplyByScalar (him.peek(), 1.0 / nfft); } break; case kSounds_convolve_scaling_NORMALIZE: { double normalizationFactor = Matrix_getNorm (me) * Matrix_getNorm (thee); if (normalizationFactor != 0.0) { Vector_multiplyByScalar (him.peek(), 1.0 / nfft / normalizationFactor); } } break; case kSounds_convolve_scaling_PEAK_099: { Vector_scale (him.peek(), 0.99); } break; default: Melder_fatal (U"Sounds_convolve: unimplemented scaling ", scaling); } return him; } catch (MelderError) { Melder_throw (me, U" & ", thee, U": not convolved."); } } autoSound Sounds_crossCorrelate (Sound me, Sound thee, enum kSounds_convolve_scaling scaling, enum kSounds_convolve_signalOutsideTimeDomain signalOutsideTimeDomain) { try { if (my ny > 1 && thy ny > 1 && my ny != thy ny) Melder_throw (U"The numbers of channels of the two sounds have to be equal or 1."); if (my dx != thy dx) Melder_throw (U"The sampling frequencies of the two sounds have to be equal."); long numberOfChannels = my ny > thy ny ? my ny : thy ny; long n1 = my nx, n2 = thy nx; long n3 = n1 + n2 - 1, nfft = 1; while (nfft < n3) nfft *= 2; autoNUMvector data1 (1, nfft); autoNUMvector data2 (1, nfft); double my_xlast = my x1 + (n1 - 1) * my dx; autoSound him = Sound_create (numberOfChannels, thy xmin - my xmax, thy xmax - my xmin, n3, my dx, thy x1 - my_xlast); for (long channel = 1; channel <= numberOfChannels; channel ++) { double *a = my z [my ny == 1 ? 1 : channel]; for (long i = n1; i > 0; i --) data1 [i] = a [i]; for (long i = n1 + 1; i <= nfft; i ++) data1 [i] = 0.0; a = thy z [thy ny == 1 ? 1 : channel]; for (long i = n2; i > 0; i --) data2 [i] = a [i]; for (long i = n2 + 1; i <= nfft; i ++) data2 [i] = 0.0; NUMrealft (data1.peek(), nfft, 1); NUMrealft (data2.peek(), nfft, 1); data2 [1] *= data1 [1]; data2 [2] *= data1 [2]; for (long i = 3; i <= nfft; i += 2) { double temp = data1 [i] * data2 [i] + data1 [i + 1] * data2 [i + 1]; // reverse me by taking the conjugate of data1 data2 [i + 1] = data1 [i] * data2 [i + 1] - data1 [i + 1] * data2 [i]; // reverse me by taking the conjugate of data1 data2 [i] = temp; } NUMrealft (data2.peek(), nfft, -1); a = him -> z [channel]; for (long i = 1; i < n1; i ++) { a [i] = data2 [i + (nfft - (n1 - 1))]; // data for the first part ("negative lags") is at the end of data2 } for (long i = 1; i <= n2; i ++) { a [i + (n1 - 1)] = data2 [i]; // data for the second part ("positive lags") is at the beginning of data2 } } switch (signalOutsideTimeDomain) { case kSounds_convolve_signalOutsideTimeDomain_ZERO: { // do nothing } break; case kSounds_convolve_signalOutsideTimeDomain_SIMILAR: { for (long channel = 1; channel <= numberOfChannels; channel ++) { double *a = his z [channel]; double edge = n1 < n2 ? n1 : n2; for (long i = 1; i < edge; i ++) { double factor = edge / i; a [i] *= factor; a [n3 + 1 - i] *= factor; } } } break; //case kSounds_convolve_signalOutsideTimeDomain_PERIODIC: { // do nothing //} break; default: Melder_fatal (U"Sounds_crossCorrelate: unimplemented outside-time-domain strategy ", signalOutsideTimeDomain); } switch (scaling) { case kSounds_convolve_scaling_INTEGRAL: { Vector_multiplyByScalar (him.peek(), my dx / nfft); } break; case kSounds_convolve_scaling_SUM: { Vector_multiplyByScalar (him.peek(), 1.0 / nfft); } break; case kSounds_convolve_scaling_NORMALIZE: { double normalizationFactor = Matrix_getNorm (me) * Matrix_getNorm (thee); if (normalizationFactor != 0.0) { Vector_multiplyByScalar (him.peek(), 1.0 / nfft / normalizationFactor); } } break; case kSounds_convolve_scaling_PEAK_099: { Vector_scale (him.peek(), 0.99); } break; default: Melder_fatal (U"Sounds_crossCorrelate: unimplemented scaling ", scaling); } return him; } catch (MelderError) { Melder_throw (me, U" & ", thee, U": not cross-correlated."); } } autoSound Sound_autoCorrelate (Sound me, enum kSounds_convolve_scaling scaling, enum kSounds_convolve_signalOutsideTimeDomain signalOutsideTimeDomain) { try { long numberOfChannels = my ny, n1 = my nx, n2 = n1 + n1 - 1, nfft = 1; while (nfft < n2) nfft *= 2; autoNUMvector data (1, nfft); double my_xlast = my x1 + (n1 - 1) * my dx; autoSound thee = Sound_create (numberOfChannels, my xmin - my xmax, my xmax - my xmin, n2, my dx, my x1 - my_xlast); for (long channel = 1; channel <= numberOfChannels; channel ++) { double *a = my z [channel]; for (long i = n1; i > 0; i --) data [i] = a [i]; for (long i = n1 + 1; i <= nfft; i ++) data [i] = 0.0; NUMrealft (data.peek(), nfft, 1); data [1] *= data [1]; data [2] *= data [2]; for (long i = 3; i <= nfft; i += 2) { data [i] = data [i] * data [i] + data [i + 1] * data [i + 1]; data [i + 1] = 0.0; // reverse me by taking the conjugate of data1 } NUMrealft (data.peek(), nfft, -1); a = thy z [channel]; for (long i = 1; i < n1; i ++) { a [i] = data [i + (nfft - (n1 - 1))]; // data for the first part ("negative lags") is at the end of data } for (long i = 1; i <= n1; i ++) { a [i + (n1 - 1)] = data [i]; // data for the second part ("positive lags") is at the beginning of data } } switch (signalOutsideTimeDomain) { case kSounds_convolve_signalOutsideTimeDomain_ZERO: { // do nothing } break; case kSounds_convolve_signalOutsideTimeDomain_SIMILAR: { for (long channel = 1; channel <= numberOfChannels; channel ++) { double *a = thy z [channel]; double edge = n1; for (long i = 1; i < edge; i ++) { double factor = edge / i; a [i] *= factor; a [n2 + 1 - i] *= factor; } } } break; //case kSounds_convolve_signalOutsideTimeDomain_PERIODIC: { // do nothing //} break; default: Melder_fatal (U"Sounds_autoCorrelate: unimplemented outside-time-domain strategy ", signalOutsideTimeDomain); } switch (scaling) { case kSounds_convolve_scaling_INTEGRAL: { Vector_multiplyByScalar (thee.peek(), my dx / nfft); } break; case kSounds_convolve_scaling_SUM: { Vector_multiplyByScalar (thee.peek(), 1.0 / nfft); } break; case kSounds_convolve_scaling_NORMALIZE: { double normalizationFactor = Matrix_getNorm (me) * Matrix_getNorm (me); if (normalizationFactor != 0.0) { Vector_multiplyByScalar (thee.peek(), 1.0 / nfft / normalizationFactor); } } break; case kSounds_convolve_scaling_PEAK_099: { Vector_scale (thee.peek(), 0.99); } break; default: Melder_fatal (U"Sounds_autoCorrelate: unimplemented scaling ", scaling); } return thee; } catch (MelderError) { Melder_throw (me, U": autocorrelation not computed."); } } void Sound_draw (Sound me, Graphics g, double tmin, double tmax, double minimum, double maximum, bool garnish, const char32 *method) { long ixmin, ixmax; bool treversed = tmin > tmax; if (treversed) { double temp = tmin; tmin = tmax; tmax = temp; } /* * Automatic domain. */ if (tmin == tmax) { tmin = my xmin; tmax = my xmax; } /* * Domain expressed in sample numbers. */ Matrix_getWindowSamplesX (me, tmin, tmax, & ixmin, & ixmax); /* * Automatic vertical range. */ if (minimum == maximum) { Matrix_getWindowExtrema (me, ixmin, ixmax, 1, my ny, & minimum, & maximum); if (minimum == maximum) { minimum -= 1.0; maximum += 1.0; } } /* * Set coordinates for drawing. */ Graphics_setInner (g); for (long channel = 1; channel <= my ny; channel ++) { Graphics_setWindow (g, treversed ? tmax : tmin, treversed ? tmin : tmax, minimum - (my ny - channel) * (maximum - minimum), maximum + (channel - 1) * (maximum - minimum)); if (str32str (method, U"bars") || str32str (method, U"Bars")) { for (long ix = ixmin; ix <= ixmax; ix ++) { double x = Sampled_indexToX (me, ix); double y = my z [channel] [ix]; double left = x - 0.5 * my dx, right = x + 0.5 * my dx; if (y > maximum) y = maximum; if (left < tmin) left = tmin; if (right > tmax) right = tmax; Graphics_line (g, left, y, right, y); Graphics_line (g, left, y, left, minimum); Graphics_line (g, right, y, right, minimum); } } else if (str32str (method, U"poles") || str32str (method, U"Poles")) { for (long ix = ixmin; ix <= ixmax; ix ++) { double x = Sampled_indexToX (me, ix); Graphics_line (g, x, 0, x, my z [channel] [ix]); } } else if (str32str (method, U"speckles") || str32str (method, U"Speckles")) { for (long ix = ixmin; ix <= ixmax; ix ++) { double x = Sampled_indexToX (me, ix); Graphics_speckle (g, x, my z [channel] [ix]); } } else { /* * The default: draw as a curve. */ Graphics_function (g, my z [channel], ixmin, ixmax, Matrix_columnToX (me, ixmin), Matrix_columnToX (me, ixmax)); } } Graphics_setWindow (g, treversed ? tmax : tmin, treversed ? tmin : tmax, minimum, maximum); if (garnish && my ny == 2) Graphics_line (g, tmin, 0.5 * (minimum + maximum), tmax, 0.5 * (minimum + maximum)); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Time (s)"); Graphics_marksBottom (g, 2, true, true, false); Graphics_setWindow (g, tmin, tmax, minimum - (my ny - 1) * (maximum - minimum), maximum); Graphics_markLeft (g, minimum, true, true, false, nullptr); Graphics_markLeft (g, maximum, true, true, false, nullptr); if (minimum != 0.0 && maximum != 0.0 && (minimum > 0.0) != (maximum > 0.0)) { Graphics_markLeft (g, 0.0, true, true, true, nullptr); } if (my ny == 2) { Graphics_setWindow (g, treversed ? tmax : tmin, treversed ? tmin : tmax, minimum, maximum + (my ny - 1) * (maximum - minimum)); Graphics_markRight (g, minimum, true, true, false, nullptr); Graphics_markRight (g, maximum, true, true, false, nullptr); if (minimum != 0.0 && maximum != 0.0 && (minimum > 0.0) != (maximum > 0.0)) { Graphics_markRight (g, 0.0, true, true, true, nullptr); } } } } static double interpolate (Sound me, long i1, long channel) /* Precondition: my z [1] [i1] != my z [1] [i1 + 1]; */ { long i2 = i1 + 1; double x1 = Sampled_indexToX (me, i1), x2 = Sampled_indexToX (me, i2); double y1 = my z [channel] [i1], y2 = my z [channel] [i2]; return x1 + (x2 - x1) * y1 / (y1 - y2); // linear } double Sound_getNearestZeroCrossing (Sound me, double position, long channel) { double *amplitude = my z [channel]; long leftSample = Sampled_xToLowIndex (me, position); long rightSample = leftSample + 1, ileft, iright; double leftZero, rightZero; /* Are we already at a zero crossing? */ if (leftSample >= 1 && rightSample <= my nx && (amplitude [leftSample] >= 0.0) != (amplitude [rightSample] >= 0.0)) { return interpolate (me, leftSample, channel); } /* Search to the left. */ if (leftSample > my nx) return NUMundefined; for (ileft = leftSample - 1; ileft >= 1; ileft --) if ((amplitude [ileft] >= 0.0) != (amplitude [ileft + 1] >= 0.0)) { leftZero = interpolate (me, ileft, channel); break; } /* Search to the right. */ if (rightSample < 1) return NUMundefined; for (iright = rightSample + 1; iright <= my nx; iright ++) if ((amplitude [iright] >= 0.0) != (amplitude [iright - 1] >= 0.0)) { rightZero = interpolate (me, iright - 1, channel); break; } if (ileft < 1 && iright > my nx) return NUMundefined; return ileft < 1 ? rightZero : iright > my nx ? leftZero : position - leftZero < rightZero - position ? leftZero : rightZero; } void Sound_setZero (Sound me, double tmin_in, double tmax_in, int roundTimesToNearestZeroCrossing) { Function_unidirectionalAutowindow (me, & tmin_in, & tmax_in); Function_intersectRangeWithDomain (me, & tmin_in, & tmax_in); for (long channel = 1; channel <= my ny; channel ++) { double tmin = tmin_in, tmax = tmax_in; if (roundTimesToNearestZeroCrossing) { if (tmin > my xmin) tmin = Sound_getNearestZeroCrossing (me, tmin_in, channel); if (tmax < my xmax) tmax = Sound_getNearestZeroCrossing (me, tmax_in, channel); } if (tmin == NUMundefined) tmin = my xmin; if (tmax == NUMundefined) tmax = my xmax; long imin, imax; Sampled_getWindowSamples (me, tmin, tmax, & imin, & imax); for (long i = imin; i <= imax; i ++) { my z [channel] [i] = 0.0; } } } autoSound Sound_createAsPureTone (long numberOfChannels, double startingTime, double endTime, double sampleRate, double frequency, double amplitude, double fadeInDuration, double fadeOutDuration) { try { double numberOfSamples_f = round ((endTime - startingTime) * sampleRate); if (numberOfSamples_f > (double) INT32_MAX) Melder_throw (U"Cannot create sounds with more than ", Melder_bigInteger (INT32_MAX), U" samples, because they cannot be saved to disk."); autoSound me = Sound_create (numberOfChannels, startingTime, endTime, (long) numberOfSamples_f, 1.0 / sampleRate, startingTime + 0.5 / sampleRate); for (long isamp = 1; isamp <= my nx; isamp ++) { double time = my x1 + (isamp - 1) * my dx; double value = amplitude * sin (NUM2pi * frequency * time); double timeFromStart = time - startingTime; if (timeFromStart < fadeInDuration) value *= 0.5 - 0.5 * cos (NUMpi * timeFromStart / fadeInDuration); double timeFromEnd = endTime - time; if (timeFromEnd < fadeOutDuration) value *= 0.5 - 0.5 * cos (NUMpi * timeFromEnd / fadeOutDuration); for (long ichan = 1; ichan <= my ny; ichan ++) { my z [ichan] [isamp] = value; } } return me; } catch (MelderError) { Melder_throw (U"Sound not created from tone complex."); } } autoSound Sound_createFromToneComplex (double startingTime, double endTime, double sampleRate, int phase, double frequencyStep, double firstFrequency, double ceiling, long numberOfComponents) { try { if (frequencyStep == 0.0) Melder_throw (U"Frequency step must not be zero."); /* * Translate default firstFrequency. */ if (firstFrequency <= 0.0) firstFrequency = frequencyStep; double firstOmega = 2 * NUMpi * firstFrequency; /* * Translate default ceiling. */ double omegaStep = 2 * NUMpi * frequencyStep, nyquistFrequency = 0.5 * sampleRate; if (ceiling <= 0.0 || ceiling > nyquistFrequency) ceiling = nyquistFrequency; /* * Translate number of components. */ long maximumNumberOfComponents = (long) floor ((ceiling - firstFrequency) / frequencyStep) + 1; if (numberOfComponents <= 0 || numberOfComponents > maximumNumberOfComponents) numberOfComponents = maximumNumberOfComponents; if (numberOfComponents < 1) Melder_throw (U"Zero sine waves."); /* * Generate the Sound. */ double factor = 0.99 / numberOfComponents; autoSound me = Sound_create (1, startingTime, endTime, lround ((endTime - startingTime) * sampleRate), 1.0 / sampleRate, startingTime + 0.5 / sampleRate); double *amplitude = my z [1]; for (long isamp = 1; isamp <= my nx; isamp ++) { double value = 0.0, t = Sampled_indexToX (me.peek(), isamp); double omegaStepT = omegaStep * t, firstOmegaT = firstOmega * t; if (phase == Sound_TONE_COMPLEX_SINE) for (long icomp = 1; icomp <= numberOfComponents; icomp ++) value += sin (firstOmegaT + (icomp - 1) * omegaStepT); else for (long icomp = 1; icomp <= numberOfComponents; icomp ++) value += cos (firstOmegaT + (icomp - 1) * omegaStepT); amplitude [isamp] = value * factor; } return me; } catch (MelderError) { Melder_throw (U"Sound not created from tone complex."); } } void Sound_multiplyByWindow (Sound me, enum kSound_windowShape windowShape) { for (long channel = 1; channel <= my ny; channel ++) { long i, n = my nx; double *amp = my z [channel]; double imid, edge, onebyedge1, factor; switch (windowShape) { case kSound_windowShape_RECTANGULAR: ; break; case kSound_windowShape_TRIANGULAR: /* "Bartlett" */ for (i = 1; i <= n; i ++) { double phase = (double) i / n; /* 0..1 */ amp [i] *= 1.0 - fabs ((2.0 * phase - 1.0)); } break; case kSound_windowShape_PARABOLIC: /* "Welch" */ for (i = 1; i <= n; i ++) { double phase = (double) i / n; amp [i] *= 1.0 - (2.0 * phase - 1.0) * (2.0 * phase - 1.0); } break; case kSound_windowShape_HANNING: for (i = 1; i <= n; i ++) { double phase = (double) i / n; amp [i] *= 0.5 * (1.0 - cos (2.0 * NUMpi * phase)); } break; case kSound_windowShape_HAMMING: for (i = 1; i <= n; i ++) { double phase = (double) i / n; amp [i] *= 0.54 - 0.46 * cos (2.0 * NUMpi * phase); } break; case kSound_windowShape_GAUSSIAN_1: imid = 0.5 * (n + 1), edge = exp (-3.0), onebyedge1 = 1 / (1.0 - edge); /* -0.5..+0.5 */ for (i = 1; i <= n; i ++) { double phase = ((double) i - imid) / n; amp [i] *= (exp (-12.0 * phase * phase) - edge) * onebyedge1; } break; case kSound_windowShape_GAUSSIAN_2: imid = 0.5 * (double) (n + 1), edge = exp (-12.0), onebyedge1 = 1 / (1.0 - edge); for (i = 1; i <= n; i ++) { double phase = ((double) i - imid) / n; amp [i] *= (exp (-48.0 * phase * phase) - edge) * onebyedge1; } break; case kSound_windowShape_GAUSSIAN_3: imid = 0.5 * (double) (n + 1), edge = exp (-27.0), onebyedge1 = 1 / (1.0 - edge); for (i = 1; i <= n; i ++) { double phase = ((double) i - imid) / n; amp [i] *= (exp (-108.0 * phase * phase) - edge) * onebyedge1; } break; case kSound_windowShape_GAUSSIAN_4: imid = 0.5 * (double) (n + 1), edge = exp (-48.0), onebyedge1 = 1 / (1.0 - edge); for (i = 1; i <= n; i ++) { double phase = ((double) i - imid) / n; amp [i] *= (exp (-192.0 * phase * phase) - edge) * onebyedge1; } break; case kSound_windowShape_GAUSSIAN_5: imid = 0.5 * (double) (n + 1), edge = exp (-75.0), onebyedge1 = 1 / (1.0 - edge); for (i = 1; i <= n; i ++) { double phase = ((double) i - imid) / n; amp [i] *= (exp (-300.0 * phase * phase) - edge) * onebyedge1; } break; case kSound_windowShape_KAISER_1: imid = 0.5 * (double) (n + 1); factor = 1 / NUMbessel_i0_f (2 * NUMpi); for (i = 1; i <= n; i ++) { double phase = 2 * ((double) i - imid) / n; /* -1..+1 */ double root = 1 - phase * phase; amp [i] *= root <= 0.0 ? 0.0 : factor * NUMbessel_i0_f (2 * NUMpi * sqrt (root)); } break; case kSound_windowShape_KAISER_2: imid = 0.5 * (double) (n + 1); factor = 1 / NUMbessel_i0_f (2 * NUMpi * NUMpi + 0.5); for (i = 1; i <= n; i ++) { double phase = 2 * ((double) i - imid) / n; /* -1..+1 */ double root = 1 - phase * phase; amp [i] *= root <= 0.0 ? 0.0 : factor * NUMbessel_i0_f ((2 * NUMpi * NUMpi + 0.5) * sqrt (root)); } break; default: break; } } } void Sound_scaleIntensity (Sound me, double newAverageIntensity) { double currentIntensity = Sound_getIntensity_dB (me), factor; if (currentIntensity == NUMundefined) return; factor = pow (10, (newAverageIntensity - currentIntensity) / 20.0); for (long channel = 1; channel <= my ny; channel ++) { for (long i = 1; i <= my nx; i ++) { my z [channel] [i] *= factor; } } } void Sound_overrideSamplingFrequency (Sound me, double rate) { my dx = 1 / rate; my x1 = my xmin + 0.5 * my dx; my xmax = my xmin + my nx * my dx; } autoSound Sound_extractPart (Sound me, double t1, double t2, enum kSound_windowShape windowShape, double relativeWidth, bool preserveTimes) { try { /* * We do not clip to the Sound's time domain. * Any samples outside it are taken to be zero. */ /* * Autowindow. */ if (t1 == t2) { t1 = my xmin; t2 = my xmax; }; /* * Allow window tails outside specified domain. */ if (relativeWidth != 1.0) { double margin = 0.5 * (relativeWidth - 1) * (t2 - t1); t1 -= margin; t2 += margin; } /* * Determine index range. We use all the real or virtual samples that fit within [t1..t2]. */ long ix1 = 1 + (long) ceil ((t1 - my x1) / my dx); long ix2 = 1 + (long) floor ((t2 - my x1) / my dx); if (ix2 < ix1) Melder_throw (U"Extracted Sound would contain no samples."); /* * Create sound, optionally shifted to [0..t2-t1]. */ autoSound thee = Sound_create (my ny, t1, t2, ix2 - ix1 + 1, my dx, my x1 + (ix1 - 1) * my dx); if (! preserveTimes) { thy xmin = 0.0; thy xmax -= t1; thy x1 -= t1; } /* * Copy only *real* samples into the new sound. * The *virtual* samples will remain at zero. */ for (long channel = 1; channel <= my ny; channel ++) { NUMvector_copyElements (my z [channel], thy z [channel] + 1 - ix1, ( ix1 < 1 ? 1 : ix1 ), ( ix2 > my nx ? my nx : ix2 )); } /* * Multiply by a window that extends throughout the target domain. */ Sound_multiplyByWindow (thee.peek(), windowShape); return thee; } catch (MelderError) { Melder_throw (me, U": part not extracted."); } } autoSound Sound_extractPartForOverlap (Sound me, double t1, double t2, double overlap) { try { if (t1 == t2) { t1 = my xmin; t2 = my xmax; }; // autowindow if (overlap > 0.0) { double margin = 0.5 * overlap; t1 -= margin; t2 += margin; } if (t1 < my xmin) t1 = my xmin; // clip to my time domain if (t2 > my xmax) t2 = my xmax; /* * Determine index range. We use all the real or virtual samples that fit within [t1..t2]. */ long ix1 = 1 + (long) ceil ((t1 - my x1) / my dx); long ix2 = 1 + (long) floor ((t2 - my x1) / my dx); if (ix2 < ix1) Melder_throw (U"Extracted Sound would contain no samples."); /* * Create sound. */ autoSound thee = Sound_create (my ny, t1, t2, ix2 - ix1 + 1, my dx, my x1 + (ix1 - 1) * my dx); thy xmin = 0.0; thy xmax -= t1; thy x1 -= t1; /* * Copy only *real* samples into the new sound. * The *virtual* samples will remain at zero. */ for (long channel = 1; channel <= my ny; channel ++) { NUMvector_copyElements (my z [channel], thy z [channel] + 1 - ix1, ( ix1 < 1 ? 1 : ix1 ), ( ix2 > my nx ? my nx : ix2 )); } return thee; } catch (MelderError) { Melder_throw (me, U": part not extracted."); } } void Sound_filterWithFormants (Sound me, double tmin, double tmax, int numberOfFormants, double formant [], double bandwidth []) { try { for (long channel = 1; channel <= my ny; channel ++) { if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } // autowindowing long itmin, itmax; long n = Sampled_getWindowSamples (me, tmin, tmax, & itmin, & itmax); if (n <= 2) Melder_throw (U"Sound too short."); double *amplitude = my z [channel] + itmin - 1; // base 1 NUMdeemphasize_f (amplitude, n, my dx, 50.0); for (int iformant = 1; iformant <= numberOfFormants; iformant ++) { NUMfilterSecondOrderSection_fb (amplitude, n, my dx, formant [iformant], bandwidth [iformant]); } } Matrix_scaleAbsoluteExtremum (me, 0.99); } catch (MelderError) { Melder_throw (me, U": not filtered."); } } autoSound Sound_filter_oneFormant (Sound me, double frequency, double bandwidth) { try { autoSound thee = Data_copy (me); Sound_filterWithOneFormantInline (thee.peek(), frequency, bandwidth); return thee; } catch (MelderError) { Melder_throw (me, U": not filtered (one formant)."); } } void Sound_filterWithOneFormantInline (Sound me, double frequency, double bandwidth) { for (long channel = 1; channel <= my ny; channel ++) { NUMfilterSecondOrderSection_fb (my z [channel], my nx, my dx, frequency, bandwidth); } Matrix_scaleAbsoluteExtremum (me, 0.99); } autoSound Sound_filter_preemphasis (Sound me, double frequency) { try { autoSound thee = Data_copy (me); Sound_preEmphasis (thee.peek(), frequency); Matrix_scaleAbsoluteExtremum (thee.peek(), 0.99); return thee; } catch (MelderError) { Melder_throw (me, U": not filtered (pre-emphasis)."); } } autoSound Sound_filter_deemphasis (Sound me, double frequency) { try { autoSound thee = Data_copy (me); Sound_deEmphasis (thee.peek(), frequency); Matrix_scaleAbsoluteExtremum (thee.peek(), 0.99); return thee; } catch (MelderError) { Melder_throw (me, U": not filtered (de-emphasis)."); } } void Sound_reverse (Sound me, double tmin, double tmax) { if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } // autowindowing long itmin, itmax; long n = Sampled_getWindowSamples (me, tmin, tmax, & itmin, & itmax) / 2; for (long channel = 1; channel <= my ny; channel ++) { double *amp = my z [channel]; for (long i = 0; i < n; i ++) { double dummy = amp [itmin + i]; amp [itmin + i] = amp [itmax - i]; amp [itmax - i] = dummy; } } } autoSound Sounds_crossCorrelate_short (Sound me, Sound thee, double tmin, double tmax, int normalize) { try { if (my dx != thy dx) Melder_throw (U"Sampling frequencies are not equal."); if (my ny != thy ny) Melder_throw (U"Numbers of channels are not equal."); double dt = my dx; double dphase = (thy x1 - my x1) / dt; dphase -= floor (dphase); // a number between 0 and 1 long i1 = (long) ceil (tmin / dt - dphase); // index of first sample if sample at dphase has index 0 long i2 = (long) floor (tmax / dt - dphase); // index of last sample if sample at dphase has index 0 long nt = i2 - i1 + 1; if (nt < 1) Melder_throw (U"Window too small."); double t1 = (dphase + i1) * dt; autoSound him = Sound_create (1, tmin, tmax, nt, dt, t1); for (long i = 1; i <= nt; i ++) { long di = i - 1 + i1; for (long ime = 1; ime <= my nx; ime ++) { if (ime + di < 1) continue; if (ime + di > thy nx) break; for (long channel = 1; channel <= my ny; channel ++) { his z [1] [i] += my z [channel] [ime] * thy z [channel] [ime + di]; } } } if (normalize) { double mypower = 0.0, thypower = 0.0; for (long channel = 1; channel <= my ny; channel ++) { for (long i = 1; i <= my nx; i ++) { double value = my z [channel] [i]; mypower += value * value; } for (long i = 1; i <= thy nx; i ++) { double value = thy z [channel] [i]; thypower += value * value; } } if (mypower != 0.0 && thypower != 0.0) { double factor = 1.0 / (sqrt (mypower) * sqrt (thypower)); for (long i = 1; i <= nt; i ++) { his z [1] [i] *= factor; } } } else { double factor = dt / my ny; for (long i = 1; i <= nt; i ++) { his z [1] [i] *= factor; } } return him; } catch (MelderError) { Melder_throw (me, U": not cross-correlated."); } } /* End of file Sound.cpp */ praat-6.0.04/fon/Sound.h000066400000000000000000000314141261542461700147460ustar00rootroot00000000000000#ifndef _Sound_h_ #define _Sound_h_ /* Sound.h * * Copyright (C) 1992-2011,2012,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Sound inherits from Vector */ /* A Sound is a sampled signal, not quantized. */ #include "Vector.h" #include "Collection.h" #include "Sound_enums.h" Thing_define (Sound, Vector) { void v_info () override; bool v_hasGetMatrix () override { return true; } double v_getMatrix (long irow, long icol) override; bool v_hasGetFunction2 () override { return true; } double v_getFunction2 (double x, double y) override; int v_domainQuantity () override { return MelderQuantity_TIME_SECONDS; } }; /* Attributes: xmin // Start time (seconds). xmax // End time (seconds). nx // Number of samples. dx // Sampling period (seconds). x1 // Time of first sample (seconds). ymin == 1 // Left or only channel. ymax // Right or only channels. ny // Number of channels. dy == 1; y1 == 1 // y is channel number (1 = left or mono; 2 = right). z [i] [...] // Amplitude. z may be replaced (e.g., in pasting). */ autoSound Sound_create (long numberOfChannels, double xmin, double xmax, long nx, double dx, double x1); /* Function: return a new silent Sound. Preconditions: xmax > xmin; nx >= 1; dx > 0.0; Postconditions: thy xmin == xmin; thy xmax == xmax; thy nx == nx; thy dx == dx; thy x1 == x1; thy ymin = 1.0; thy ymax = numberOfChannels; thy ny = numberOfChannels; thy dx = 1.0; thy x1 = 1.0; thy z [i] [1..nx] == 0.0; */ autoSound Sound_createSimple (long numberOfChannels, double duration, double samplingFrequency); /* Function: return a new silent Sound. Preconditions: duration > 0.0; samplingFrequency > 0.0; Postconditions: thy xmin == 0.0; thy xmax == duration; thy nx == round (duration * samplingFrequency); thy dx == 1 / samplingFrequency; thy x1 == 0.5 * thy dx; // Centre of first sampling period. thy ymin = 1.0; thy ymax = numberOfChannels; thy ny = numberOfChannels; thy dx = 1.0; thy x1 = 1.0; thy z [i] [1..nx] == 0.0; */ autoSound Sound_convertToMono (Sound me); autoSound Sound_convertToStereo (Sound me); autoSound Sound_extractChannel (Sound me, long ichannel); autoSound Sounds_combineToStereo (Collection me); /* Levels for Sampled_getValueAtSample (me, index, level, unit) */ #define Sound_LEVEL_MONO 0 #define Sound_LEVEL_LEFT 1 #define Sound_LEVEL_RIGHT 2 autoSound Sound_upsample (Sound me); /* By a factor 2. */ autoSound Sound_resample (Sound me, double samplingFrequency, long precision); /* Method: precision <= 1: linear interpolation. precision >= 2: sinx/x interpolation with maximum depth equal to 'precision'. */ autoSound Sounds_append (Sound me, double silenceDuration, Sound thee); /* Function: append two Sounds. Failure: my dx != thy dx: "Sampling frequencies do not match." Postconditions: result -> xmin == 0; result -> xmax == result -> nx * my dx; result -> nx == my nx + thy nx + round (silenceDuration / my dx); result -> dx == my dx; result -> x1 == 0.5 * my dx; for (i = 1..my nx) result -> z [1] [i] == my z [1] [i] for (i = 1..thy nx) result -> z [1] [i + my nx + round (silenceDuration / my dx)] == thy z [1] [i] */ autoSound Sounds_convolve (Sound me, Sound thee, enum kSounds_convolve_scaling scaling, enum kSounds_convolve_signalOutsideTimeDomain signalOutsideTimeDomain); /* Function: convolve two Sounds. Failure: my dx != thy dx: "Sampling frequencies do not match." Postconditions: result -> xmin == my xmin + thy xmin; result -> xmax == my xmax + thy xmax; result -> nx == my nx + thy nx - 1; result -> dx == my dx; result -> x1 == my x1 + thy x1; for (i = 1..result -> nx) result -> z [1] [i] == result -> dx * sum (j = 1..i, my z [1] [j] * thy z [1] [i - j + 1]) */ autoSound Sounds_crossCorrelate (Sound me, Sound thee, enum kSounds_convolve_scaling scaling, enum kSounds_convolve_signalOutsideTimeDomain signalOutsideTimeDomain); autoSound Sounds_crossCorrelate_short (Sound me, Sound thee, double tmin, double tmax, int normalize); autoSound Sound_autoCorrelate (Sound me, enum kSounds_convolve_scaling scaling, enum kSounds_convolve_signalOutsideTimeDomain signalOutsideTimeDomain); double Sound_getRootMeanSquare (Sound me, double xmin, double xmax); double Sound_getEnergy (Sound me, double xmin, double xmax); double Sound_getPower (Sound me, double xmin, double xmax); double Sound_getEnergyInAir (Sound me); double Sound_getPowerInAir (Sound me); double Sound_getIntensity_dB (Sound me); double Sound_getNearestZeroCrossing (Sound me, double position, long ichannel); void Sound_setZero (Sound me, double tmin, double tmax, int roundTimesToNearestZeroCrossing); autoSound Sound_createAsPureTone (long numberOfChannels, double startingTime, double endTime, double sampleRate, double frequency, double amplitude, double fadeInDuration, double fadeOutDuration); autoSound Sound_createFromToneComplex (double startingTime, double endTime, double sampleRate, int phase, double frequencyStep, double firstFrequency, double ceiling, long numberOfComponents); /* Values for `phase' parameter: */ #define Sound_TONE_COMPLEX_SINE 0 #define Sound_TONE_COMPLEX_COSINE 1 autoSound Sounds_concatenate_e (Collection me, double overlapTime); void Sound_multiplyByWindow (Sound me, enum kSound_windowShape windowShape); void Sound_scaleIntensity (Sound me, double newAverageIntensity); void Sound_overrideSamplingFrequency (Sound me, double newSamplingFrequency); autoSound Sound_extractPart (Sound me, double t1, double t2, enum kSound_windowShape windowShape, double relativeWidth, bool preserveTimes); autoSound Sound_extractPartForOverlap (Sound me, double t1, double t2, double overlap); void Sound_filterWithFormants (Sound me, double tmin, double tmax, int numberOfFormants, double formant [], double bandwidth []); autoSound Sound_filter_oneFormant (Sound me, double frequency, double bandwidth); void Sound_filterWithOneFormantInline (Sound me, double frequency, double bandwidth); autoSound Sound_filter_preemphasis (Sound me, double frequency); autoSound Sound_filter_deemphasis (Sound me, double frequency); void Sound_reverse (Sound me, double tmin, double tmax); void Sound_draw (Sound me, Graphics g, double tmin, double tmax, double minimum, double maximum, bool garnish, const char32 *method); /* For method, see Vector_draw. */ autoMatrix Sound_to_Matrix (Sound me); /* Create a Matrix from a Sound, with deep copy of all its Matrix attributes, except class information and methods. */ autoSound Matrix_to_Sound (Matrix me); autoSound Matrix_to_Sound_mono (Matrix me, long row); /* Function: create a Sound from one row of a Matrix. "row" is forced inside the segment [1, my ny]; negative values count from the last row; e.g., if "row" is -1, the last row is taken. Postconditions: thy xmin == my xmin; thy xmax == my xmax; thy nx == my nx; thy dx == my dx; thy x1 == my x1; thy ymin ymax ny dy y1 == 1; thy z [1] [...] == my z [row] [...]; */ extern Sound Sound_clipboard; /********** Sound_audio.cpp **********/ autoSound Sound_recordFixedTime (int inputSource, double gain, double balance, double samplingFrequency, double duration); /* Function: record a sound without user interaction, synchronously (i.e., return when recording finsishes). Arguments: inputSource: <=0 = do not change (may be set by Audio Control Panel). 1 = microphone. 2 = line. 3 = digital. If the input source selection fails, the microphone is used. gain: <0.0 = do not change. 0.0 = minimum. 1.0 = maximum. balance: <0.0 = do not change. 0.0 = left channel only. 0.5 = mid balance. 1.0 = right channel only. samplingFrequency: <=0.0 = do not change. must be one of the sample rates supported by the hardware. duration: positive time in seconds. Return value: the resulting Sound; NULL in case of failure. Failures: Hardware does not support sampling frequency. Duration must be positive. Duration too long (out of memory). Usage: batch; in an interactive environment, it is better to use SoundRecorder_create, and wait for broadcastPublication(). */ void Sound_playPart (Sound me, double tmin, double tmax, int (*playCallback) (void *playClosure, int phase, double tmin, double tmax, double t), void *playClosure); /* * Play a sound. The playing can be interrupted with the Escape key (also Command-period on the Mac). * If playCallback is not NULL, Sound_play will call it repeatedly, with five parameters: * 1. playClosure: the same value as was supplied as the last argument to Sound_playPart. * 2. phase: 1 at the start, 2 while playing, 3 at the end. * 3. tmin: the same tmin that was supplied as the second argument to Sound_playPart. * 4. tmax: the same tmax that was supplied as the second argument to Sound_playPart. * 5. t: the time (probably between tmin and tmax) at which the sound is playing. * The usage of playCallback is as follows. Suppose we are an editor that wants to show a moving * cursor while we play a sound: * Sound_playPart (my sound, my startSelection, my endSelection, thePlayCallback, me); * We gave ourselves as the playClosure, so that the message will arrive with us: * int thePlayCallback (void *playClosure, int phase, double tmin, double tmax, double t) { * SoundEditor me = (SoundEditor) playClosure; * if (phase == 1) { * Melder_assert (t == tmin); * drawPlayCursor (me, my playCursor = t); * } else if (phase == 2) { * undrawPlayCursor (me, my playCursor); * drawPlayCursor (me, my playCursor = t); * } else { * undrawPlayCursor (me, t); * moveCursor (me, t); * if (t < tmax) { Melder_casual (U"Sound play interrupted."); } * } * return 1; * } * The playCallback procedure usually returns 1, because the sound should continue playing. * If playCallback returns 0 instead, Sound_play will interrupt the play and return. * Sound_playPart returns the time at which playing stopped. If playing was not interrupted, it returns tmax. * * Sound_playPart () usually runs asynchronously, and kills an already playing sound. */ void Sound_play (Sound me, int (*playCallback) (void *playClosure, int phase, double tmin, double tmax, double t), void *playClosure); /* The same as Sound_playPart (me, my xmin, my xmax, playCallback, playClosure); */ /********** Sound_files.cpp **********/ /* To avoid clipping, keep the absolute amplitude below 1.000. */ /* All are mono or stereo PCM. */ void Sound_writeToAudioFile (Sound me, MelderFile file, int audioFileType, int numberOfBitsPerSamplePoint); void Sound_writeToKayFile (Sound me, MelderFile file); // 16-bit void Sound_writeToSesamFile (Sound me, MelderFile file); // 12-bit SESAM/LVS autoSound Sound_readFromSoundFile (MelderFile file); // AIFF, WAV, NeXT/Sun, or NIST autoSound Sound_readFromKayFile (MelderFile file); // 16-bit autoSound Sound_readFromSesamFile (MelderFile file); // 12-bit SESAM/LVS autoSound Sound_readFromBellLabsFile (MelderFile file); // 16-bit autoSound Sound_readFromRawAlawFile (MelderFile file); autoSound Sound_readFromMovieFile (MelderFile file); autoSound Sound_readFromRawSoundFile (MelderFile file, int encoding, int numberOfChannels, double sampleRate); /* 'encoding' is any of the following: Melder_LINEAR_8_SIGNED Melder_LINEAR_8_UNSIGNED Melder_LINEAR_16_BIG_ENDIAN Melder_LINEAR_16_LITTLE_ENDIAN Melder_MULAW Melder_ALAW 'numberOfChannels' is 1 (mono) or 2 (stereo) 'sampleRate' is in hertz */ void Sound_writeToRawSoundFile (Sound me, MelderFile file, int encoding); /* 'encoding' is any of the following: Melder_LINEAR_8_SIGNED Melder_LINEAR_8_UNSIGNED Melder_LINEAR_16_BIG_ENDIAN Melder_LINEAR_16_LITTLE_ENDIAN 'me' must exist */ /********** Sound_enhance.cpp **********/ autoSound Sound_lengthen_overlapAdd (Sound me, double fmin, double fmax, double factor); autoSound Sound_deepenBandModulation (Sound me, double enhancement_dB, double flow, double fhigh, double slowModulation, double fastModulation, double bandSmoothing); /* End of file Sound.h */ #endif praat-6.0.04/fon/SoundEditor.cpp000066400000000000000000000412061261542461700164500ustar00rootroot00000000000000/* SoundEditor.cpp * * Copyright (C) 1992-2012,2013,2014,2015 Paul Boersma, 2007 Erez Volk (FLAC support) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "SoundEditor.h" #include "Sound_and_Spectrogram.h" #include "Pitch.h" #include "Preferences.h" #include "EditorM.h" Thing_implement (SoundEditor, TimeSoundAnalysisEditor, 0); /********** METHODS **********/ void structSoundEditor :: v_dataChanged () { Sound sound = (Sound) data; Melder_assert (sound != NULL); // LongSound objects should not get v_dataChanged messages Matrix_getWindowExtrema (sound, 1, sound -> nx, 1, sound -> ny, & d_sound.minimum, & d_sound.maximum); // BUG unreadable v_reset_analysis (); SoundEditor_Parent :: v_dataChanged (); } /***** EDIT MENU *****/ static void menu_cb_Copy (EDITOR_ARGS) { EDITOR_IAM (SoundEditor); try { /* * Create without change. */ autoSound publish = my d_longSound.data ? LongSound_extractPart ((LongSound) my data, my d_startSelection, my d_endSelection, false) : Sound_extractPart ((Sound) my data, my d_startSelection, my d_endSelection, kSound_windowShape_RECTANGULAR, 1.0, false); /* * Change without error. */ forget (Sound_clipboard); Sound_clipboard = publish.transfer(); } catch (MelderError) { Melder_throw (U"Sound selection not copied to clipboard."); } } static void menu_cb_Cut (EDITOR_ARGS) { EDITOR_IAM (SoundEditor); try { Sound sound = (Sound) my data; long first, last, selectionNumberOfSamples = Sampled_getWindowSamples (sound, my d_startSelection, my d_endSelection, & first, & last); long oldNumberOfSamples = sound -> nx; long newNumberOfSamples = oldNumberOfSamples - selectionNumberOfSamples; if (newNumberOfSamples < 1) Melder_throw (U"You cannot cut all of the signal away,\n" U"because you cannot create a Sound with 0 samples.\n" U"You could consider using Copy instead."); if (selectionNumberOfSamples) { double **oldData = sound -> z; /* * Create without change. */ autoSound publish = Sound_create (sound -> ny, 0.0, selectionNumberOfSamples * sound -> dx, selectionNumberOfSamples, sound -> dx, 0.5 * sound -> dx); for (long channel = 1; channel <= sound -> ny; channel ++) { long j = 0; for (long i = first; i <= last; i ++) { publish -> z [channel] [++ j] = oldData [channel] [i]; } } autoNUMmatrix newData (1, sound -> ny, 1, newNumberOfSamples); for (long channel = 1; channel <= sound -> ny; channel ++) { long j = 0; for (long i = 1; i < first; i ++) { newData [channel] [++ j] = oldData [channel] [i]; } for (long i = last + 1; i <= oldNumberOfSamples; i ++) { newData [channel] [++ j] = oldData [channel] [i]; } } Editor_save (me, U"Cut"); /* * Change without error. */ NUMmatrix_free (oldData, 1, 1); sound -> xmin = 0.0; sound -> xmax = newNumberOfSamples * sound -> dx; sound -> nx = newNumberOfSamples; sound -> x1 = 0.5 * sound -> dx; sound -> z = newData.transfer(); forget (Sound_clipboard); Sound_clipboard = publish.transfer(); /* Start updating the markers of the FunctionEditor, respecting the invariants. */ my tmin = sound -> xmin; my tmax = sound -> xmax; /* Collapse the selection, */ /* so that the Cut operation can immediately be undone by a Paste. */ /* The exact position will be half-way in between two samples. */ my d_startSelection = my d_endSelection = sound -> xmin + (first - 1) * sound -> dx; /* Update the window. */ { double t1 = (first - 1) * sound -> dx; double t2 = last * sound -> dx; double windowLength = my d_endWindow - my d_startWindow; // > 0 if (t1 > my d_startWindow) if (t2 < my d_endWindow) my d_startWindow -= 0.5 * (t2 - t1); else (void) 0; else if (t2 < my d_endWindow) my d_startWindow -= t2 - t1; else /* Cut overlaps entire window: centre. */ my d_startWindow = my d_startSelection - 0.5 * windowLength; my d_endWindow = my d_startWindow + windowLength; // first try if (my d_endWindow > my tmax) { my d_startWindow -= my d_endWindow - my tmax; // second try if (my d_startWindow < my tmin) my d_startWindow = my tmin; // third try my d_endWindow = my tmax; // second try } else if (my d_startWindow < my tmin) { my d_endWindow -= my d_startWindow - my tmin; // second try if (my d_endWindow > my tmax) my d_endWindow = my tmax; // third try my d_startWindow = my tmin; // second try } } /* Force FunctionEditor to show changes. */ Matrix_getWindowExtrema (sound, 1, sound -> nx, 1, sound -> ny, & my d_sound.minimum, & my d_sound.maximum); my v_reset_analysis (); FunctionEditor_ungroup (me); FunctionEditor_marksChanged (me, false); Editor_broadcastDataChanged (me); } else { Melder_warning (U"No samples selected."); } } catch (MelderError) { Melder_throw (U"Sound selection not cut to clipboard."); } } static void menu_cb_Paste (EDITOR_ARGS) { EDITOR_IAM (SoundEditor); Sound sound = (Sound) my data; long leftSample = Sampled_xToLowIndex (sound, my d_endSelection); long oldNumberOfSamples = sound -> nx, newNumberOfSamples; double **oldData = sound -> z; if (! Sound_clipboard) { Melder_warning (U"Clipboard is empty; nothing pasted."); return; } if (Sound_clipboard -> ny != sound -> ny) Melder_throw (U"Cannot paste, because\n" U"the number of channels of the clipboard is not equal to\n" U"the number of channels of the edited sound."); if (Sound_clipboard -> dx != sound -> dx) Melder_throw (U"Cannot paste, because\n" U"the sampling frequency of the clipboard is not equal to\n" U"the sampling frequency of the edited sound."); if (leftSample < 0) leftSample = 0; if (leftSample > oldNumberOfSamples) leftSample = oldNumberOfSamples; newNumberOfSamples = oldNumberOfSamples + Sound_clipboard -> nx; /* * Check without change. */ autoNUMmatrix newData (1, sound -> ny, 1, newNumberOfSamples); for (long channel = 1; channel <= sound -> ny; channel ++) { long j = 0; for (long i = 1; i <= leftSample; i ++) { newData [channel] [++ j] = oldData [channel] [i]; } for (long i = 1; i <= Sound_clipboard -> nx; i ++) { newData [channel] [++ j] = Sound_clipboard -> z [channel] [i]; } for (long i = leftSample + 1; i <= oldNumberOfSamples; i ++) { newData [channel] [++ j] = oldData [channel] [i]; } } Editor_save (me, U"Paste"); /* * Change without error. */ NUMmatrix_free (oldData, 1, 1); sound -> xmin = 0.0; sound -> xmax = newNumberOfSamples * sound -> dx; sound -> nx = newNumberOfSamples; sound -> x1 = 0.5 * sound -> dx; sound -> z = newData.transfer(); /* Start updating the markers of the FunctionEditor, respecting the invariants. */ my tmin = sound -> xmin; my tmax = sound -> xmax; my d_startSelection = leftSample * sound -> dx; my d_endSelection = (leftSample + Sound_clipboard -> nx) * sound -> dx; /* Force FunctionEditor to show changes. */ Matrix_getWindowExtrema (sound, 1, sound -> nx, 1, sound -> ny, & my d_sound.minimum, & my d_sound.maximum); my v_reset_analysis (); FunctionEditor_ungroup (me); FunctionEditor_marksChanged (me, false); Editor_broadcastDataChanged (me); } static void menu_cb_SetSelectionToZero (EDITOR_ARGS) { EDITOR_IAM (SoundEditor); Sound sound = (Sound) my data; long first, last; Sampled_getWindowSamples (sound, my d_startSelection, my d_endSelection, & first, & last); Editor_save (me, U"Set to zero"); for (long channel = 1; channel <= sound -> ny; channel ++) { for (long i = first; i <= last; i ++) { sound -> z [channel] [i] = 0.0; } } my v_reset_analysis (); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_ReverseSelection (EDITOR_ARGS) { EDITOR_IAM (SoundEditor); Editor_save (me, U"Reverse selection"); Sound_reverse ((Sound) my data, my d_startSelection, my d_endSelection); my v_reset_analysis (); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } /***** SELECT MENU *****/ static void menu_cb_MoveCursorToZero (EDITOR_ARGS) { EDITOR_IAM (SoundEditor); double zero = Sound_getNearestZeroCrossing ((Sound) my data, 0.5 * (my d_startSelection + my d_endSelection), 1); // STEREO BUG if (NUMdefined (zero)) { my d_startSelection = my d_endSelection = zero; FunctionEditor_marksChanged (me, true); } } static void menu_cb_MoveBtoZero (EDITOR_ARGS) { EDITOR_IAM (SoundEditor); double zero = Sound_getNearestZeroCrossing ((Sound) my data, my d_startSelection, 1); // STEREO BUG if (NUMdefined (zero)) { my d_startSelection = zero; if (my d_startSelection > my d_endSelection) { double dummy = my d_startSelection; my d_startSelection = my d_endSelection; my d_endSelection = dummy; } FunctionEditor_marksChanged (me, true); } } static void menu_cb_MoveEtoZero (EDITOR_ARGS) { EDITOR_IAM (SoundEditor); double zero = Sound_getNearestZeroCrossing ((Sound) my data, my d_endSelection, 1); // STEREO BUG if (NUMdefined (zero)) { my d_endSelection = zero; if (my d_startSelection > my d_endSelection) { double dummy = my d_startSelection; my d_startSelection = my d_endSelection; my d_endSelection = dummy; } FunctionEditor_marksChanged (me, true); } } /***** HELP MENU *****/ static void menu_cb_SoundEditorHelp (EDITOR_ARGS) { EDITOR_IAM (SoundEditor); Melder_help (U"SoundEditor"); } static void menu_cb_LongSoundEditorHelp (EDITOR_ARGS) { EDITOR_IAM (SoundEditor); Melder_help (U"LongSoundEditor"); } void structSoundEditor :: v_createMenus () { SoundEditor_Parent :: v_createMenus (); Melder_assert (data != NULL); Melder_assert (d_sound.data != NULL || d_longSound.data != NULL); Editor_addCommand (this, U"Edit", U"-- cut copy paste --", 0, NULL); if (d_sound.data) cutButton = Editor_addCommand (this, U"Edit", U"Cut", 'X', menu_cb_Cut); copyButton = Editor_addCommand (this, U"Edit", U"Copy selection to Sound clipboard", 'C', menu_cb_Copy); if (d_sound.data) pasteButton = Editor_addCommand (this, U"Edit", U"Paste after selection", 'V', menu_cb_Paste); if (d_sound.data) { Editor_addCommand (this, U"Edit", U"-- zero --", 0, NULL); zeroButton = Editor_addCommand (this, U"Edit", U"Set selection to zero", 0, menu_cb_SetSelectionToZero); reverseButton = Editor_addCommand (this, U"Edit", U"Reverse selection", 'R', menu_cb_ReverseSelection); } if (d_sound.data) { Editor_addCommand (this, U"Select", U"-- move to zero --", 0, 0); Editor_addCommand (this, U"Select", U"Move start of selection to nearest zero crossing", ',', menu_cb_MoveBtoZero); Editor_addCommand (this, U"Select", U"Move begin of selection to nearest zero crossing", Editor_HIDDEN, menu_cb_MoveBtoZero); Editor_addCommand (this, U"Select", U"Move cursor to nearest zero crossing", '0', menu_cb_MoveCursorToZero); Editor_addCommand (this, U"Select", U"Move end of selection to nearest zero crossing", '.', menu_cb_MoveEtoZero); } v_createMenus_analysis (); } void structSoundEditor :: v_createHelpMenuItems (EditorMenu menu) { SoundEditor_Parent :: v_createHelpMenuItems (menu); EditorMenu_addCommand (menu, U"SoundEditor help", '?', menu_cb_SoundEditorHelp); EditorMenu_addCommand (menu, U"LongSoundEditor help", 0, menu_cb_LongSoundEditorHelp); } /********** UPDATE **********/ void structSoundEditor :: v_prepareDraw () { if (d_longSound.data) { try { LongSound_haveWindow (d_longSound.data, d_startWindow, d_endWindow); } catch (MelderError) { Melder_clearError (); } } } void structSoundEditor :: v_draw () { Sampled data = (Sampled) this -> data; Graphics_Viewport viewport; bool showAnalysis = p_spectrogram_show || p_pitch_show || p_intensity_show || p_formant_show; Melder_assert (data != NULL); Melder_assert (d_sound.data != NULL || d_longSound.data != NULL); /* * We check beforehand whether the window fits the LongSound buffer. */ if (d_longSound.data && d_endWindow - d_startWindow > d_longSound.data -> bufferLength) { Graphics_setColour (d_graphics, Graphics_WHITE); Graphics_setWindow (d_graphics, 0, 1, 0, 1); Graphics_fillRectangle (d_graphics, 0, 1, 0, 1); Graphics_setColour (d_graphics, Graphics_BLACK); Graphics_setTextAlignment (d_graphics, Graphics_CENTRE, Graphics_BOTTOM); Graphics_text (d_graphics, 0.5, 0.5, U"(window longer than ", Melder_float (Melder_single (d_longSound.data -> bufferLength)), U" seconds)"); Graphics_setTextAlignment (d_graphics, Graphics_CENTRE, Graphics_TOP); Graphics_text (d_graphics, 0.5, 0.5, U"(zoom in to see the samples)"); return; } /* Draw sound. */ if (showAnalysis) viewport = Graphics_insetViewport (d_graphics, 0, 1, 0.5, 1); Graphics_setColour (d_graphics, Graphics_WHITE); Graphics_setWindow (d_graphics, 0, 1, 0, 1); Graphics_fillRectangle (d_graphics, 0, 1, 0, 1); TimeSoundEditor_drawSound (this, d_sound.minimum, d_sound.maximum); Graphics_flushWs (d_graphics); if (showAnalysis) Graphics_resetViewport (d_graphics, viewport); /* Draw analyses. */ if (showAnalysis) { /* Draw spectrogram, pitch, formants. */ viewport = Graphics_insetViewport (d_graphics, 0, 1, 0, 0.5); v_draw_analysis (); Graphics_flushWs (d_graphics); Graphics_resetViewport (d_graphics, viewport); } /* Draw pulses. */ if (p_pulses_show) { if (showAnalysis) viewport = Graphics_insetViewport (d_graphics, 0, 1, 0.5, 1); v_draw_analysis_pulses (); TimeSoundEditor_drawSound (this, d_sound.minimum, d_sound.maximum); // second time, partially across the pulses Graphics_flushWs (d_graphics); if (showAnalysis) Graphics_resetViewport (d_graphics, viewport); } /* Update buttons. */ long first, last; long selectedSamples = Sampled_getWindowSamples (data, d_startSelection, d_endSelection, & first, & last); v_updateMenuItems_file (); if (d_sound.data) { GuiThing_setSensitive (cutButton , selectedSamples != 0 && selectedSamples < d_sound.data -> nx); GuiThing_setSensitive (copyButton , selectedSamples != 0); GuiThing_setSensitive (zeroButton , selectedSamples != 0); GuiThing_setSensitive (reverseButton , selectedSamples != 0); } } void structSoundEditor :: v_play (double a_tmin, double a_tmax) { if (d_longSound.data) LongSound_playPart ((LongSound) data, a_tmin, a_tmax, theFunctionEditor_playCallback, this); else Sound_playPart ((Sound) data, a_tmin, a_tmax, theFunctionEditor_playCallback, this); } int structSoundEditor :: v_click (double xWC, double yWC, bool shiftKeyPressed) { if ((p_spectrogram_show || p_formant_show) && yWC < 0.5 && xWC > d_startWindow && xWC < d_endWindow) { d_spectrogram_cursor = p_spectrogram_viewFrom + 2 * yWC * (p_spectrogram_viewTo - p_spectrogram_viewFrom); } return SoundEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed); // drag & update } void structSoundEditor :: v_highlightSelection (double left, double right, double bottom, double top) { if (p_spectrogram_show) Graphics_highlight (d_graphics, left, right, 0.5 * (bottom + top), top); else Graphics_highlight (d_graphics, left, right, bottom, top); } void structSoundEditor :: v_unhighlightSelection (double left, double right, double bottom, double top) { if (p_spectrogram_show) Graphics_unhighlight (d_graphics, left, right, 0.5 * (bottom + top), top); else Graphics_unhighlight (d_graphics, left, right, bottom, top); } void SoundEditor_init (SoundEditor me, const char32 *title, Sampled data) { /* * my longSound.data or my sound.data have to be set before we call FunctionEditor_init, * because createMenus expects that one of them is not NULL. */ TimeSoundAnalysisEditor_init (me, title, data, data, false); if (my d_longSound.data && my d_endWindow - my d_startWindow > 30.0) { my d_endWindow = my d_startWindow + 30.0; if (my d_startWindow == my tmin) my d_startSelection = my d_endSelection = 0.5 * (my d_startWindow + my d_endWindow); FunctionEditor_marksChanged (me, false); } } autoSoundEditor SoundEditor_create (const char32 *title, Sampled data) { Melder_assert (data); try { autoSoundEditor me = Thing_new (SoundEditor); SoundEditor_init (me.peek(), title, data); return me; } catch (MelderError) { Melder_throw (U"Sound window not created."); } } /* End of file SoundEditor.cpp */ praat-6.0.04/fon/SoundEditor.h000066400000000000000000000033251261542461700161150ustar00rootroot00000000000000#ifndef _SoundEditor_h_ #define _SoundEditor_h_ /* SoundEditor.h * * Copyright (C) 1992-2011,2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "TimeSoundAnalysisEditor.h" Thing_define (SoundEditor, TimeSoundAnalysisEditor) { GuiMenuItem cutButton, copyButton, pasteButton, zeroButton, reverseButton; double maxBuffer; void v_createMenus () override; void v_createHelpMenuItems (EditorMenu menu) override; void v_dataChanged () override; void v_prepareDraw () override; void v_draw () override; void v_play (double tmin, double tmax) override; int v_click (double xWC, double yWC, bool shiftKeyPressed) override; void v_highlightSelection (double left, double right, double bottom, double top) override; void v_unhighlightSelection (double left, double right, double bottom, double top) override; }; void SoundEditor_init (SoundEditor me, const char32 *title, Sampled data ); autoSoundEditor SoundEditor_create ( const char32 *title, Sampled data // either a Sound or a LongSound ); /* End of file SoundEditor.h */ #endif praat-6.0.04/fon/SoundRecorder.cpp000066400000000000000000001303261261542461700167710ustar00rootroot00000000000000/* SoundRecorder.cpp * * Copyright (C) 1992-2011,2012,2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Linux code originally by Darryl Purnell, Pretoria */ /* GTK conversion includes work by Franz Brauße */ /* This source file describes interactive sound recorders for the following systems: * MacOS * Linux * Windows * Because the behaviour of these sound recorders is partly similar, partly different, * this would seem a good candidate for object-oriented programming * (one audio manager and several audio drivers). * However, the places where sound recorders are similar and where they are different, * are hard to predict. For this reason, everything is done with system #ifdefs. */ #include #include "SoundRecorder.h" #include "Sound_and_Spectrum.h" #include "machine.h" #include "EditorM.h" #if defined (macintosh) #include "pa_mac_core.h" #endif #include "enums_getText.h" #include "SoundRecorder_enums.h" #include "enums_getValue.h" #include "SoundRecorder_enums.h" Thing_implement (SoundRecorder, Editor, 0); #include "prefs_define.h" #include "SoundRecorder_prefs.h" #include "prefs_install.h" #include "SoundRecorder_prefs.h" #include "prefs_copyToInstance.h" #include "SoundRecorder_prefs.h" static struct { int bufferSizeInMegabytes; } preferences; void SoundRecorder_preferences () { Preferences_addInt (U"SoundRecorder.bufferSizeInMegabytes", & preferences.bufferSizeInMegabytes, 60); } int SoundRecorder_getBufferSizePref_MB () { return preferences.bufferSizeInMegabytes; } void SoundRecorder_setBufferSizePref_MB (int size) { preferences.bufferSizeInMegabytes = size < 1 ? 1 : size > 1000 ? 1000: size; } #define step 1000 /* For those systems that do not have a pollable audio control panel, */ /* the settings are saved only here, so that they are remembered across */ /* subsequent creations of a SoundRecorder. Also, this is then the way */ /* in which two simultaneously open SoundRecorders would communicate. */ static struct { int inputSource; // 1 = microphone, 2 = line, 3 = digital int leftGain, rightGain; // 0..255 double sampleRate; } theControlPanel = #if defined (linux) { 1, 200, 200, 44100 }; #elif defined (macintosh) { 1, 26, 26, 44100 }; #else { 1, 26, 26, 44100 }; #endif /********** ERROR HANDLING **********/ #if defined (_WIN32) static void win_fillFormat (SoundRecorder me) { my waveFormat. nSamplesPerSec = (int) theControlPanel. sampleRate; my waveFormat. nChannels = my numberOfChannels; my waveFormat. wFormatTag = WAVE_FORMAT_PCM; my waveFormat. wBitsPerSample = 16; my waveFormat. nBlockAlign = my waveFormat. nChannels * my waveFormat. wBitsPerSample / 8; my waveFormat. nAvgBytesPerSec = my waveFormat. nBlockAlign * my waveFormat. nSamplesPerSec; my waveFormat. cbSize = 0; } static void win_fillHeader (SoundRecorder me, int which) { my waveHeader [which]. dwFlags = 0; my waveHeader [which]. lpData = which == 0 ? (char *) my buffer : which == 1 ? (char *) my buffertje1: (char *) my buffertje2; my waveHeader [which]. dwBufferLength = which == 0 ? my nmax * my waveFormat. nChannels * 2 : 1000 * my waveFormat. nChannels * 2; my waveHeader [which]. dwLoops = 0; my waveHeader [which]. lpNext = NULL; my waveHeader [which]. reserved = 0; } static void win_waveInCheck (SoundRecorder me) { char32 messageText [MAXERRORLENGTH]; MMRESULT err; if (my err == MMSYSERR_NOERROR) return; err = waveInGetErrorText (my err, Melder_32toW (messageText), MAXERRORLENGTH); if (err == MMSYSERR_NOERROR) Melder_throw (messageText); else if (err == MMSYSERR_BADERRNUM) Melder_throw (U"Error number ", my err, U" out of range."); else if (err == MMSYSERR_NODRIVER) Melder_throw (U"No sound driver present."); else if (err == MMSYSERR_NOMEM) Melder_throw (U"Out of memory."); else Melder_throw (U"Unknown sound error."); } static void win_waveInOpen (SoundRecorder me) { try { my err = waveInOpen (& my hWaveIn, WAVE_MAPPER, & my waveFormat, 0, 0, CALLBACK_NULL); win_waveInCheck (me); if (Melder_debug != 8) waveInReset (my hWaveIn); } catch (MelderError) { Melder_throw (U"Audio input not opened."); } } static void win_waveInPrepareHeader (SoundRecorder me, int which) { try { my err = waveInPrepareHeader (my hWaveIn, & my waveHeader [which], sizeof (WAVEHDR)); win_waveInCheck (me); } catch (MelderError) { Melder_throw (U"Audio input: cannot prepare header.\nQuit some other programs or go to \"Sound input prefs\" in the Preferences menu."); } } static void win_waveInAddBuffer (SoundRecorder me, int which) { try { my err = waveInAddBuffer (my hWaveIn, & my waveHeader [which], sizeof (WAVEHDR)); win_waveInCheck (me); } catch (MelderError) { Melder_throw (U"Audio input: cannot add buffer."); } } static void win_waveInStart (SoundRecorder me) { try { my err = waveInStart (my hWaveIn); // asynchronous win_waveInCheck (me); } catch (MelderError) { Melder_throw (U"Audio input not started."); } } static void win_waveInStop (SoundRecorder me) { try { my err = waveInStop (my hWaveIn); win_waveInCheck (me); } catch (MelderError) { Melder_throw (U"Audio input not stopped."); } } static void win_waveInReset (SoundRecorder me) { try { my err = waveInReset (my hWaveIn); win_waveInCheck (me); } catch (MelderError) { Melder_throw (U"Audio input not reset."); } } static void win_waveInUnprepareHeader (SoundRecorder me, int which) { try { my err = waveInUnprepareHeader (my hWaveIn, & my waveHeader [which], sizeof (WAVEHDR)); win_waveInCheck (me); } catch (MelderError) { Melder_throw (U"Audio input: cannot unprepare header."); } } static void win_waveInClose (SoundRecorder me) { try { my err = waveInClose (my hWaveIn); my hWaveIn = 0; win_waveInCheck (me); } catch (MelderError) { Melder_throw (U"Audio input not closed."); } } #endif static void stopRecording (SoundRecorder me) { if (! my recording) return; try { my recording = false; if (! my synchronous) { if (my inputUsesPortAudio) { Pa_StopStream (my portaudioStream); Pa_CloseStream (my portaudioStream); my portaudioStream = NULL; } else { #if defined (_WIN32) /* * On newer systems, waveInStop waits until the buffer is full. * Wrong behaviour! * Therefore, we call waveInReset instead. * But on these same newer systems, waveInReset causes the dwBytesRecorded * attribute to go to zero, so we cannot do * my nsamp = my waveHeader [0]. dwBytesRecorded / (sizeof (short) * my numberOfChannels); */ MMTIME mmtime; mmtime. wType = TIME_BYTES; my nsamp = 0; if (waveInGetPosition (my hWaveIn, & mmtime, sizeof (MMTIME)) == MMSYSERR_NOERROR) my nsamp = mmtime. u.cb / (sizeof (short) * my numberOfChannels); win_waveInReset (me); if (my nsamp == 0) my nsamp = my waveHeader [0]. dwBytesRecorded / (sizeof (short) * my numberOfChannels); if (my nsamp > my nmax) my nsamp = my nmax; win_waveInUnprepareHeader (me, 0); win_waveInClose (me); #endif } } } catch (MelderError) { Melder_flushError (U"Cannot stop recording."); } Graphics_setWindow (my graphics, 0.0, 1.0, 0.0, 1.0); Graphics_setColour (my graphics, Graphics_WHITE); Graphics_fillRectangle (my graphics, 0.0, 1.0, 0.0, 1.0); } void structSoundRecorder :: v_destroy () { stopRecording (this); // must occur before freeing my buffer MelderAudio_stopPlaying (MelderAudio_IMPLICIT); // must also occur before freeing my buffer #if cocoa if (our d_cocoaTimer) CFRunLoopTimerInvalidate (our d_cocoaTimer); #elif gtk g_idle_remove_by_data (this); #elif motif if (our workProcId) XtRemoveWorkProc (our workProcId); #endif NUMvector_free (buffer, 0); if (our inputUsesPortAudio) { if (our portaudioStream) Pa_StopStream (our portaudioStream); if (our portaudioStream) Pa_CloseStream (our portaudioStream); } else { #if defined (_WIN32) if (our hWaveIn != 0) { waveInReset (our hWaveIn); waveInUnprepareHeader (our hWaveIn, & our waveHeader [0], sizeof (WAVEHDR)); waveInClose (our hWaveIn); } #elif defined (macintosh) #elif defined (UNIX) if (our fd != -1) close (our fd); #endif } forget (our graphics); SoundRecorder_Parent :: v_destroy (); } static void showMaximum (SoundRecorder me, int channel, double maximum) { maximum /= 32768.0; Graphics_setWindow (my graphics, my numberOfChannels == 1 || channel == 1 ? 0.0 : -1.0, my numberOfChannels == 1 || channel == 2 ? 1.0 : 2.0, -0.1, 1.1); Graphics_setGrey (my graphics, 0.9); Graphics_fillRectangle (my graphics, 0.0, 1.0, maximum, 1.0); Graphics_setColour (my graphics, Graphics_GREEN); if (maximum < 0.75) { Graphics_fillRectangle (my graphics, 0.0, 1.0, 0.0, maximum); } else { Graphics_fillRectangle (my graphics, 0.0, 1.0, 0.0, 0.75); Graphics_setColour (my graphics, Graphics_YELLOW); if (maximum < 0.92) { Graphics_fillRectangle (my graphics, 0.0, 1.0, 0.75, maximum); } else { Graphics_fillRectangle (my graphics, 0.0, 1.0, 0.75, 0.92); Graphics_setColour (my graphics, Graphics_RED); Graphics_fillRectangle (my graphics, 0.0, 1.0, 0.92, maximum); } } } static void showMeter (SoundRecorder me, short *buffer, long nsamp) { Melder_assert (my graphics != NULL); if (nsamp < 1) { Graphics_setWindow (my graphics, 0.0, 1.0, 0.0, 1.0); #if defined (macintosh) Graphics_setColour (my graphics, Graphics_WHITE); Graphics_fillRectangle (my graphics, 0.2, 0.8, 0.3, 0.7); #endif Graphics_setTextAlignment (my graphics, Graphics_CENTRE, Graphics_HALF); Graphics_setColour (my graphics, Graphics_BLACK); Graphics_text (my graphics, 0.5, 0.5, U"Not recording."); return; } if (my p_meter_which == kSoundRecorder_meter_INTENSITY) { short leftMaximum = 0, rightMaximum = 0; if (my numberOfChannels == 1) { for (long i = 0; i < nsamp; i ++) { short value = buffer [i]; if (abs (value) > leftMaximum) leftMaximum = abs (value); } } else { for (long i = 0; i < nsamp; i ++) { long left = buffer [i+i], right = buffer [i+i+1]; if (abs (left) > leftMaximum) leftMaximum = abs (left); if (abs (right) > rightMaximum) rightMaximum = abs (right); } } if (my lastLeftMaximum > 30000) { int leak = my lastLeftMaximum - (int) floor (2000000 / theControlPanel. sampleRate); if (leftMaximum < leak) leftMaximum = leak; } showMaximum (me, 1, leftMaximum); my lastLeftMaximum = leftMaximum; if (my numberOfChannels == 2) { if (my lastRightMaximum > 30000) { int leak = my lastRightMaximum - (int) floor (2000000 / theControlPanel. sampleRate); if (rightMaximum < leak) rightMaximum = leak; } showMaximum (me, 2, rightMaximum); my lastRightMaximum = rightMaximum; } } else if (my p_meter_which == kSoundRecorder_meter_CENTRE_OF_GRAVITY_VERSUS_INTENSITY) { autoSound sound = Sound_create (my numberOfChannels, 0.0, nsamp / theControlPanel. sampleRate, nsamp, 1.0 / theControlPanel. sampleRate, 0.5 / theControlPanel. sampleRate); short *p = & buffer [0]; for (long isamp = 1; isamp <= nsamp; isamp ++) { for (long ichan = 1; ichan <= my numberOfChannels; ichan ++) { sound -> z [ichan] [isamp] = * (p ++) / 32768.0; } } Sound_multiplyByWindow (sound.peek(), kSound_windowShape_KAISER_2); double intensity = Sound_getIntensity_dB (sound.peek()); autoSpectrum spectrum = Sound_to_Spectrum (sound.peek(), true); double centreOfGravity = Spectrum_getCentreOfGravity (spectrum.peek(), 1.0); trace (nsamp, U" samples, intensity ", intensity, U" dB, centre of gravity ", centreOfGravity, U" Hz"); Graphics_setWindow (my graphics, my p_meter_centreOfGravity_minimum, my p_meter_centreOfGravity_maximum, my p_meter_intensity_minimum, my p_meter_intensity_maximum); Graphics_setColour (my graphics, Graphics_WHITE); Graphics_fillRectangle (my graphics, my p_meter_centreOfGravity_minimum, my p_meter_centreOfGravity_maximum, my p_meter_intensity_minimum, my p_meter_intensity_maximum); Graphics_setColour (my graphics, Graphics_BLACK); Graphics_fillCircle_mm (my graphics, centreOfGravity, intensity, 3.0); } Graphics_flushWs (my graphics); } static bool tooManySamplesInBufferToReturnToGui (SoundRecorder me) { (void) me; return false; } static long getMyNsamp (SoundRecorder me) { volatile long nsamp = my nsamp; // Prevent inlining. return nsamp; } #if cocoa #define WORKPROC_RETURN void #define WORKPROC_ARGS CFRunLoopTimerRef /*timer*/, void *void_me #elif gtk #define WORKPROC_RETURN gboolean #define WORKPROC_ARGS void *void_me #else #define WORKPROC_RETURN bool #define WORKPROC_ARGS void *void_me #endif static WORKPROC_RETURN workProc (WORKPROC_ARGS) { iam (SoundRecorder); try { short buffertje [step*2]; int stepje = 0; #if defined (linux) #define min(a,b) a > b ? b : a #endif /* Determine global audio parameters (may have been changed by an external control panel): * 1. input source; * 2. left and right gain; * 3. sampling frequency. */ if (my inputUsesPortAudio) { } else { } /* Set the buttons according to the audio parameters. */ if (my recordButton) GuiThing_setSensitive (my recordButton, ! my recording); if (my stopButton) GuiThing_setSensitive (my stopButton, my recording); if (my playButton) GuiThing_setSensitive (my playButton, ! my recording && my nsamp > 0); if (my applyButton) GuiThing_setSensitive (my applyButton, ! my recording && my nsamp > 0); if (my okButton) GuiThing_setSensitive (my okButton, ! my recording && my nsamp > 0); if (my monoButton && my numberOfChannels == 1) GuiRadioButton_set (my monoButton); if (my stereoButton && my numberOfChannels == 2) GuiRadioButton_set (my stereoButton); for (long i = 1; i <= SoundRecorder_IFSAMP_MAX; i ++) if (my fsamp_ [i]. button && theControlPanel. sampleRate == my fsamp_ [i]. fsamp) GuiRadioButton_set (my fsamp_ [i]. button); if (my device_ [theControlPanel. inputSource]. button) GuiRadioButton_set (my device_ [theControlPanel. inputSource]. button); if (my monoButton) GuiThing_setSensitive (my monoButton, ! my recording); if (my stereoButton) GuiThing_setSensitive (my stereoButton, ! my recording); for (long i = 1; i <= SoundRecorder_IFSAMP_MAX; i ++) if (my fsamp_ [i]. button) { GuiThing_setSensitive (my fsamp_ [i]. button, ! my recording); } for (long i = 1; i <= SoundRecorder_IDEVICE_MAX; i ++) if (my device_ [i]. button) GuiThing_setSensitive (my device_ [i]. button, ! my recording); /*Graphics_setGrey (my graphics, 0.9); Graphics_fillRectangle (my graphics, 0.0, 1.0, 0.0, 32768.0); Graphics_setGrey (my graphics, 0.9); Graphics_fillRectangle (my graphics, 0.0, 1.0, 0.0, 32768.0);*/ if (my synchronous) { /* * Read some samples into 'buffertje'. */ do { if (my inputUsesPortAudio) { /* * Asynchronous recording: do nothing. */ } else { #if defined (macintosh) || defined (_WIN32) /* * Asynchronous recording on these systems: do nothing. */ #else // linux if (my fd != -1) stepje = read (my fd, (void *) buffertje, step * (sizeof (short) * my numberOfChannels)) / (sizeof (short) * my numberOfChannels); #endif } if (my recording) { memcpy (my buffer + my nsamp * my numberOfChannels, buffertje, stepje * (sizeof (short) * my numberOfChannels)); } showMeter (me, buffertje, stepje); if (my recording) { my nsamp += stepje; if (my nsamp > my nmax - step) my recording = false; GuiScale_setValue (my progressScale, 1000.0 * ((double) my nsamp / (double) my nmax)); } } while (my recording && tooManySamplesInBufferToReturnToGui (me)); } else { if (my recording) { /* * We have to know how far the buffer has been filled. * However, the buffer may be filled at interrupt time, * so that the buffer may be being filled during this workproc. * So we ask for the buffer filling just once, namely here at the beginning. */ long lastSample = 0; if (my inputUsesPortAudio) { /* * The buffer filling is contained in my nsamp, * which has been set during interrupt time and may again be updated behind our backs during this workproc. * So we do it in such a way that the compiler cannot ask for my nsamp twice. */ lastSample = getMyNsamp (me); Pa_Sleep (10); } else { #if defined (_WIN32) MMTIME mmtime; mmtime. wType = TIME_BYTES; if (waveInGetPosition (my hWaveIn, & mmtime, sizeof (MMTIME)) == MMSYSERR_NOERROR) lastSample = mmtime. u.cb / (sizeof (short) * my numberOfChannels); #elif defined (macintosh) #endif } long firstSample = lastSample - 3000; if (firstSample < 0) firstSample = 0; showMeter (me, my buffer + firstSample * my numberOfChannels, lastSample - firstSample); GuiScale_setValue (my progressScale, 1000.0 * ((double) lastSample / (double) my nmax)); } else { showMeter (me, NULL, 0); } } } catch (MelderError) { Melder_flushError (); } #if cocoa return; #elif gtk return true; #else return false; #endif } static int portaudioStreamCallback ( const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *void_me) { /* * This procedure may be called at interrupt time. * It therefore accesses only data that is constant during recording, * namely me, my buffer, my numberOfChannels, and my nmax. * The only thing it changes is my nsamp; * the workProc will therefore have to take some care in accessing my nsamp (see there). */ iam (SoundRecorder); (void) output; (void) timeInfo; (void) statusFlags; if (Melder_debug == 20) Melder_casual (U"The PortAudio stream callback receives ", frameCount, U" frames."); Melder_assert (my nsamp <= my nmax); unsigned long samplesLeft = my nmax - my nsamp; if (samplesLeft > 0) { unsigned long dsamples = samplesLeft > frameCount ? frameCount : samplesLeft; if (Melder_debug == 20) Melder_casual (U"play ", dsamples, U" ", Pa_GetStreamCpuLoad (my portaudioStream)); memcpy (my buffer + my nsamp * my numberOfChannels, input, 2 * dsamples * my numberOfChannels); my nsamp += dsamples; if (my nsamp >= my nmax) return paComplete; } else /*if (my nsamp >= my nmax)*/ { my nsamp = my nmax; return paComplete; } return paContinue; } static void gui_button_cb_record (I, GuiButtonEvent /* event */) { iam (SoundRecorder); try { if (my recording) return; my nsamp = 0; my recording = true; my lastLeftMaximum = 0; my lastRightMaximum = 0; if (! my synchronous) { if (my inputUsesPortAudio) { PaStreamParameters streamParameters = { 0 }; streamParameters. device = my deviceIndices [theControlPanel. inputSource]; streamParameters. channelCount = my numberOfChannels; streamParameters. sampleFormat = paInt16; streamParameters. suggestedLatency = my deviceInfos [theControlPanel. inputSource] -> defaultLowInputLatency; #if defined (macintosh) PaMacCoreStreamInfo macCoreStreamInfo = { 0 }; macCoreStreamInfo. size = sizeof (PaMacCoreStreamInfo); macCoreStreamInfo. hostApiType = paCoreAudio; macCoreStreamInfo. version = 0x01; macCoreStreamInfo. flags = paMacCoreChangeDeviceParameters | paMacCoreFailIfConversionRequired; streamParameters. hostApiSpecificStreamInfo = & macCoreStreamInfo; #endif if (Melder_debug == 20) Melder_casual (U"Before Pa_OpenStream"); PaError err = Pa_OpenStream (& my portaudioStream, & streamParameters, NULL, theControlPanel. sampleRate, 0, paNoFlag, portaudioStreamCallback, (void *) me); if (Melder_debug == 20) Melder_casual (U"Pa_OpenStream returns ", (int) err); if (err) Melder_throw (U"open ", Melder_peek8to32 (Pa_GetErrorText (err))); Pa_StartStream (my portaudioStream); if (Melder_debug == 20) Melder_casual (U"Pa_StartStream returns ", (int) err); if (err) Melder_throw (U"start ", Melder_peek8to32 (Pa_GetErrorText (err))); } else { #if defined (_WIN32) win_fillFormat (me); win_fillHeader (me, 0); win_waveInOpen (me); win_waveInPrepareHeader (me, 0); win_waveInAddBuffer (me, 0); win_waveInStart (me); #elif defined (macintosh) #endif } } Graphics_setWindow (my graphics, 0.0, 1.0, 0.0, 1.0); Graphics_setColour (my graphics, Graphics_WHITE); Graphics_fillRectangle (my graphics, 0.0, 1.0, 0.0, 1.0); } catch (MelderError) { Graphics_setWindow (my graphics, 0.0, 1.0, 0.0, 1.0); Graphics_setColour (my graphics, Graphics_WHITE); Graphics_fillRectangle (my graphics, 0.0, 1.0, 0.0, 1.0); my recording = false; Melder_flushError (U"Cannot record."); } } static void gui_button_cb_stop (I, GuiButtonEvent /* event */) { iam (SoundRecorder); stopRecording (me); } static void gui_button_cb_play (I, GuiButtonEvent /* event */) { iam (SoundRecorder); if (my recording || my nsamp == 0) return; MelderAudio_play16 (my buffer, theControlPanel. sampleRate, my fakeMono ? my nsamp / 2 : my nsamp, my fakeMono ? 2 : my numberOfChannels, NULL, NULL); } static void publish (SoundRecorder me) { autoSound sound; long nsamp = my fakeMono ? my nsamp / 2 : my nsamp; if (my nsamp == 0) return; double fsamp = theControlPanel. sampleRate; if (fsamp <= 0.0) fsamp = 44100.0; // safe try { sound = Sound_createSimple (my numberOfChannels, (double) nsamp / fsamp, fsamp); } catch (MelderError) { Melder_flushError (U"You can still save to file."); return; } if (my fakeMono) { for (long i = 1; i <= nsamp; i ++) sound -> z [1] [i] = (my buffer [i + i - 2] + my buffer [i + i - 1]) * (1.0 / 65536); } else if (my numberOfChannels == 1) { for (long i = 1; i <= nsamp; i ++) sound -> z [1] [i] = my buffer [i - 1] * (1.0 / 32768); } else { for (long i = 1; i <= nsamp; i ++) { sound -> z [1] [i] = my buffer [i + i - 2] * (1.0 / 32768); sound -> z [2] [i] = my buffer [i + i - 1] * (1.0 / 32768); } } if (my soundName) { autostring32 name = GuiText_getString (my soundName); Thing_setName (sound.peek(), name.peek()); } Editor_broadcastPublication (me, sound.transfer()); } static void gui_button_cb_cancel (I, GuiButtonEvent /* event */) { iam (SoundRecorder); stopRecording (me); forget (me); } static void gui_button_cb_apply (I, GuiButtonEvent /* event */) { iam (SoundRecorder); stopRecording (me); publish (me); } static void gui_button_cb_ok (I, GuiButtonEvent /* event */) { iam (SoundRecorder); stopRecording (me); publish (me); forget (me); } static void initialize (SoundRecorder me) { try { if (my inputUsesPortAudio) { #if defined (macintosh) my fsamp_ [SoundRecorder_IFSAMP_8000]. canDo = false; my fsamp_ [SoundRecorder_IFSAMP_11025]. canDo = false; my fsamp_ [SoundRecorder_IFSAMP_12000]. canDo = false; my fsamp_ [SoundRecorder_IFSAMP_16000]. canDo = false; my fsamp_ [SoundRecorder_IFSAMP_22050]. canDo = false; my fsamp_ [SoundRecorder_IFSAMP_24000]. canDo = false; my fsamp_ [SoundRecorder_IFSAMP_32000]. canDo = false; my fsamp_ [SoundRecorder_IFSAMP_64000]. canDo = false; #else // Accept all standard sample rates. (void) me; #endif } else { #if defined (macintosh) #elif defined (_WIN32) (void) me; #elif defined (linux) int sampleRate = (int) theControlPanel. sampleRate, sampleSize = 16; int channels = my numberOfChannels, stereo = ( my numberOfChannels == 2 ), val; #if __BYTE_ORDER == __BIG_ENDIAN int format = AFMT_S16_BE; #else int format = AFMT_S16_LE; #endif int fd_mixer; my fd = open ("/dev/dsp", O_RDONLY); if (my fd == -1) { if (errno == EBUSY) Melder_throw (U"Audio device already in use."); else Melder_throw (U"Cannot open audio device.\n" U"Please switch on PortAudio in the Sound Recording Preferences."); } ioctl (my fd, SNDCTL_DSP_RESET, NULL); ioctl (my fd, SNDCTL_DSP_SPEED, & sampleRate); ioctl (my fd, SNDCTL_DSP_SAMPLESIZE, & sampleSize); ioctl (my fd, SNDCTL_DSP_CHANNELS, (val = channels, & val)); if (channels == 1 && val == 2) { close (my fd); Melder_throw (U"This sound card does not support mono."); } ioctl (my fd, SNDCTL_DSP_STEREO, & stereo); ioctl (my fd, SNDCTL_DSP_SETFMT, & format); fd_mixer = open ("/dev/mixer", O_WRONLY); if (fd_mixer == -1) { Melder_throw (U"Cannot open /dev/mixer."); } else { int dev_mask = theControlPanel. inputSource == 2 ? SOUND_MASK_LINE : SOUND_MASK_MIC; if (ioctl (fd_mixer, SOUND_MIXER_WRITE_RECSRC, & dev_mask) == -1) { close (fd_mixer); Melder_throw (U"Can't set recording device in mixer."); } close (fd_mixer); } #endif } } catch (MelderError) { Melder_throw (U"16-bit audio recording not initialized."); } } static void gui_radiobutton_cb_input (I, GuiRadioButtonEvent event) { iam (SoundRecorder); Melder_casual (U"SoundRecorder:" U" setting the input source from ", theControlPanel. inputSource, U" to ", event -> position, U"."); theControlPanel. inputSource = event -> position; /* Set system's input source. */ if (my inputUsesPortAudio) { // deferred to the start of recording } else { #if defined (_WIN32) // deferred to the start of recording #elif defined (macintosh) //SPBCloseDevice (my refNum); try { initialize (me); } catch (MelderError) { Melder_flushError (); } #elif defined (linux) int fd_mixer = open ("/dev/mixer", O_WRONLY); if (fd_mixer == -1) { Melder_flushError (U"(Sound_record:) Cannot open /dev/mixer."); } int dev_mask = theControlPanel.inputSource == 2 ? SOUND_MASK_LINE : SOUND_MASK_MIC; if (ioctl (fd_mixer, SOUND_MIXER_WRITE_RECSRC, & dev_mask) == -1) Melder_flushError (U"(Sound_record:) Can't set recording device in mixer"); close (fd_mixer); #endif } } static void gui_radiobutton_cb_fsamp (I, GuiRadioButtonEvent event) { iam (SoundRecorder); if (my recording) return; try { double fsamp = NUMundefined; for (long i = 1; i <= SoundRecorder_IFSAMP_MAX; i ++) if (event -> toggle == my fsamp_ [i]. button) fsamp = my fsamp_ [i]. fsamp; Melder_assert (NUMdefined (fsamp)); /* * If we push the 48000 button while the sampling frequency is 22050, * we first get a message that the 22050 button has changed, * and then we get a message that the 48000 button has changed. * So the following will work (it used to be different with old Motif versions on Linux): */ Melder_casual (U"SoundRecorder:" U" setting the sample rate from ", (long) theControlPanel. sampleRate, U" to ", (long) fsamp, U" Hz."); if (fsamp == theControlPanel. sampleRate) return; /* * Now we know, hopefully, that the message is from the button that was clicked, * not the one that was unset by the radio box, so we can take action. */ theControlPanel. sampleRate = fsamp; /* * Set the system's sampling frequency. * On some systems, we cannot do this without closing the audio device, * and reopening it with a new sampling frequency. */ if (my inputUsesPortAudio) { // deferred to the start of recording } else { #if defined (_WIN32) // deferred to the start of recording #elif defined (macintosh) //SPBCloseDevice (my refNum); initialize (me); #elif defined (linux) close (my fd); initialize (me); #endif } } catch (MelderError) { Melder_throw (U"Sampling frequency not changed."); } } static void gui_drawingarea_cb_resize (I, GuiDrawingAreaResizeEvent event) { iam (SoundRecorder); if (my graphics == NULL) return; // Could be the case in the very beginning. Graphics_setWsViewport (my graphics, 0, event -> width, 0, event -> height); Graphics_setWsWindow (my graphics, 0, event -> width, 0, event -> height); Graphics_setViewport (my graphics, 0, event -> width, 0, event -> height); Graphics_updateWs (my graphics); } void structSoundRecorder :: v_createChildren () { /* Channels */ long y = 20 + Machine_getMenuBarHeight (); GuiLabel_createShown (d_windowForm, 10, 160, y, y + Gui_LABEL_HEIGHT, U"Channels:", 0); GuiRadioGroup_begin (); y += Gui_RADIOBUTTON_HEIGHT + Gui_RADIOBUTTON_SPACING; monoButton = GuiRadioButton_createShown (d_windowForm, 20, 170, y, y + Gui_RADIOBUTTON_HEIGHT, U"Mono", NULL, NULL, 0); y += Gui_RADIOBUTTON_HEIGHT + Gui_RADIOBUTTON_SPACING; stereoButton = GuiRadioButton_createShown (d_windowForm, 20, 170, y, y + Gui_RADIOBUTTON_HEIGHT, U"Stereo", NULL, NULL, 0); GuiRadioGroup_end (); /* Input source */ y = 140 + Machine_getMenuBarHeight (); #if defined (_WIN32) GuiLabel_createShown (d_windowForm, 10, 170, y, y + Gui_LABEL_HEIGHT, U"(use Windows mixer", 0); y += Gui_LABEL_HEIGHT + 10; GuiLabel_createShown (d_windowForm, 10, 170, y, y + Gui_LABEL_HEIGHT, U" without meters)", 0); #else GuiLabel_createShown (d_windowForm, 10, 170, y, y + Gui_LABEL_HEIGHT, U"Input source:", 0); GuiRadioGroup_begin (); for (long i = 1; i <= SoundRecorder_IDEVICE_MAX; i ++) { if (device_ [i]. canDo) { y += Gui_RADIOBUTTON_HEIGHT + Gui_RADIOBUTTON_SPACING; device_ [i]. button = GuiRadioButton_createShown (d_windowForm, 20, 170, y, y + Gui_RADIOBUTTON_HEIGHT, device_ [i]. name, gui_radiobutton_cb_input, this, 0); } } GuiRadioGroup_end (); #endif /* Meter box */ y = 20 + Machine_getMenuBarHeight (); GuiLabel_createShown (d_windowForm, 170, -170, y, y + Gui_LABEL_HEIGHT, U"Meter", GuiLabel_CENTRE); y += Gui_LABEL_HEIGHT; meter = GuiDrawingArea_createShown (d_windowForm, 170, -170, y, -150, NULL, NULL, NULL, gui_drawingarea_cb_resize, this, GuiDrawingArea_BORDER); /* Sampling frequency */ y = 20 + Machine_getMenuBarHeight (); GuiLabel_createShown (d_windowForm, -160, -10, y, y + Gui_LABEL_HEIGHT, U"Sampling frequency:", 0); GuiRadioGroup_begin (); for (long i = 1; i <= SoundRecorder_IFSAMP_MAX; i ++) { if (fsamp_ [i]. canDo) { double fsamp = fsamp_ [i]. fsamp; y += Gui_RADIOBUTTON_HEIGHT + Gui_RADIOBUTTON_SPACING; fsamp_ [i]. button = GuiRadioButton_createShown (d_windowForm, -150, -10, y, y + Gui_RADIOBUTTON_HEIGHT, Melder_cat (fsamp == floor (fsamp) ? Melder_integer ((long) fsamp) : Melder_fixed (fsamp, 5), U" Hz"), gui_radiobutton_cb_fsamp, this, fsamp == theControlPanel. sampleRate ? GuiRadioButton_SET : 0); } } GuiRadioGroup_end (); progressScale = GuiScale_createShown (d_windowForm, 10, 350, -130, -90, 0, 1000, 0, 0); y = 60; recordButton = GuiButton_createShown (d_windowForm, 20, 90, -y - Gui_PUSHBUTTON_HEIGHT, -y, U"Record", gui_button_cb_record, this, 0); stopButton = GuiButton_createShown (d_windowForm, 100, 170, -y - Gui_PUSHBUTTON_HEIGHT, -y, U"Stop", gui_button_cb_stop, this, 0); if (inputUsesPortAudio) { playButton = GuiButton_createShown (d_windowForm, 180, 250, -y - Gui_PUSHBUTTON_HEIGHT, -y, U"Play", gui_button_cb_play, this, 0); } else { #if defined (_WIN32) || defined (macintosh) playButton = GuiButton_createShown (d_windowForm, 180, 250, -y - Gui_PUSHBUTTON_HEIGHT, -y, U"Play", gui_button_cb_play, this, 0); #endif } GuiLabel_createShown (d_windowForm, -200, -130, -y - 2 - Gui_TEXTFIELD_HEIGHT, -y - 2, U"Name:", GuiLabel_RIGHT); soundName = GuiText_createShown (d_windowForm, -120, -20, -y - 2 - Gui_TEXTFIELD_HEIGHT, -y - 2, 0); GuiText_setString (soundName, U"untitled"); y = 20; cancelButton = GuiButton_createShown (d_windowForm, -350, -280, -y - Gui_PUSHBUTTON_HEIGHT, -y, U"Close", gui_button_cb_cancel, this, 0); applyButton = GuiButton_createShown (d_windowForm, -270, -170, -y - Gui_PUSHBUTTON_HEIGHT, -y, U"Save to list", gui_button_cb_apply, this, GuiButton_DEFAULT); okButton = GuiButton_createShown (d_windowForm, -160, -20, -y - Gui_PUSHBUTTON_HEIGHT, -y, U"Save to list & Close", gui_button_cb_ok, this, 0); } static void writeFakeMonoFile (SoundRecorder me, MelderFile file, int audioFileType) { long nsamp = my nsamp / 2; autoMelderFile mfile = MelderFile_create (file); MelderFile_writeAudioFileHeader (file, audioFileType, theControlPanel. sampleRate, nsamp, 1, 16); if (Melder_defaultAudioFileEncoding (audioFileType, 16) == Melder_LINEAR_16_BIG_ENDIAN) { for (long i = 0; i < nsamp; i ++) binputi2 ((my buffer [i + i - 2] + my buffer [i + i - 1]) / 2, file -> filePointer); } else { for (long i = 0; i < nsamp; i ++) binputi2LE ((my buffer [i + i - 2] + my buffer [i + i - 1]) / 2, file -> filePointer); } MelderFile_writeAudioFileTrailer (file, audioFileType, lround (theControlPanel. sampleRate), nsamp, 1, 16); mfile.close (); } static void writeAudioFile (SoundRecorder me, MelderFile file, int audioFileType) { try { if (my fakeMono) { writeFakeMonoFile (me, file, audioFileType); } else { MelderFile_writeAudioFile (file, audioFileType, my buffer, lround (theControlPanel. sampleRate), my nsamp, my numberOfChannels, 16); } } catch (MelderError) { Melder_throw (U"Audio file not written."); } } static void menu_cb_writeWav (EDITOR_ARGS) { EDITOR_IAM (SoundRecorder); EDITOR_FORM_WRITE (U"Save as WAV file", 0) char32 *name = GuiText_getString (my soundName); Melder_sprint (defaultName,300, name, U".wav"); Melder_free (name); EDITOR_DO_WRITE writeAudioFile (me, file, Melder_WAV); EDITOR_END } static void menu_cb_writeAifc (EDITOR_ARGS) { EDITOR_IAM (SoundRecorder); EDITOR_FORM_WRITE (U"Save as AIFC file", 0) char32 *name = GuiText_getString (my soundName); Melder_sprint (defaultName,300, name, U".aifc"); Melder_free (name); EDITOR_DO_WRITE writeAudioFile (me, file, Melder_AIFC); EDITOR_END } static void menu_cb_writeNextSun (EDITOR_ARGS) { EDITOR_IAM (SoundRecorder); EDITOR_FORM_WRITE (U"Save as NeXT/Sun file", 0) char32 *name = GuiText_getString (my soundName); Melder_sprint (defaultName,300, name, U".au"); Melder_free (name); EDITOR_DO_WRITE writeAudioFile (me, file, Melder_NEXT_SUN); EDITOR_END } static void menu_cb_writeNist (EDITOR_ARGS) { EDITOR_IAM (SoundRecorder); EDITOR_FORM_WRITE (U"Save as NIST file", 0) char32 *name = GuiText_getString (my soundName); Melder_sprint (defaultName,300, name, U".nist"); Melder_free (name); EDITOR_DO_WRITE writeAudioFile (me, file, Melder_NIST); EDITOR_END } static void updateMenus (SoundRecorder me) { GuiMenuItem_check (my d_meterIntensityButton, my p_meter_which == kSoundRecorder_meter_INTENSITY); GuiMenuItem_check (my d_meterCentreOfGravityVersusIntensityButton, my p_meter_which == kSoundRecorder_meter_CENTRE_OF_GRAVITY_VERSUS_INTENSITY); } static void menu_cb_intensity (EDITOR_ARGS) { EDITOR_IAM (SoundRecorder); my pref_meter_which () = my p_meter_which = kSoundRecorder_meter_INTENSITY; updateMenus (me); } static void menu_cb_centreOfGravityVersusIntensity (EDITOR_ARGS) { EDITOR_IAM (SoundRecorder); my pref_meter_which () = my p_meter_which = kSoundRecorder_meter_CENTRE_OF_GRAVITY_VERSUS_INTENSITY; updateMenus (me); } static void menu_cb_SoundRecorder_help (EDITOR_ARGS) { EDITOR_IAM (SoundRecorder); Melder_help (U"SoundRecorder"); } void structSoundRecorder :: v_createMenus () { SoundRecorder_Parent :: v_createMenus (); Editor_addCommand (this, U"File", U"Save as WAV file...", 0, menu_cb_writeWav); Editor_addCommand (this, U"File", U"Save as AIFC file...", 0, menu_cb_writeAifc); Editor_addCommand (this, U"File", U"Save as NeXT/Sun file...", 0, menu_cb_writeNextSun); Editor_addCommand (this, U"File", U"Save as NIST file...", 0, menu_cb_writeNist); Editor_addCommand (this, U"File", U"-- write --", 0, 0); Editor_addMenu (this, U"Meter", 0); d_meterIntensityButton = Editor_addCommand (this, U"Meter", U"Intensity", GuiMenu_RADIO_FIRST, menu_cb_intensity); d_meterCentreOfGravityVersusIntensityButton = Editor_addCommand (this, U"Meter", U"Centre of gravity ~ intensity", GuiMenu_RADIO_NEXT, menu_cb_centreOfGravityVersusIntensity); } void structSoundRecorder :: v_createHelpMenuItems (EditorMenu menu) { SoundRecorder_Parent :: v_createHelpMenuItems (menu); EditorMenu_addCommand (menu, U"SoundRecorder help", '?', menu_cb_SoundRecorder_help); } autoSoundRecorder SoundRecorder_create (int numberOfChannels) { try { autoSoundRecorder me = Thing_new (SoundRecorder); my inputUsesPortAudio = #if defined (_WIN32) MelderAudio_getInputSoundSystem () == kMelder_inputSoundSystem_MME_VIA_PORTAUDIO; #elif defined (macintosh) MelderAudio_getInputSoundSystem () == kMelder_inputSoundSystem_COREAUDIO_VIA_PORTAUDIO; #else MelderAudio_getInputSoundSystem () == kMelder_inputSoundSystem_ALSA_VIA_PORTAUDIO; #endif if (my inputUsesPortAudio) { } else { #if defined (_WIN32) UINT numberOfDevices = waveInGetNumDevs (), i; WAVEINCAPS caps; MMRESULT err; if (numberOfDevices == 0) Melder_throw (U"No sound input devices available."); err = waveInGetDevCaps (WAVE_MAPPER, & caps, sizeof (WAVEINCAPS)); if (numberOfChannels == 2 && caps. wChannels < 2) Melder_throw (U"Your computer does not support stereo sound input."); /* BUG: should we ask whether 16 bit is supported? */ for (i = 0; i < numberOfDevices; i ++) { waveInGetDevCaps (i, & caps, sizeof (WAVEINCAPS)); /*Melder_casual (U"Name of device ", i, U": ", Melder_peek16to32 (aps. szPname));*/ } #elif defined (macintosh) SInt32 soundFeatures; if (Gestalt (gestaltSoundAttr, & soundFeatures) || ! (soundFeatures & (1 << gestaltSoundIOMgrPresent)) || ! (soundFeatures & (1 << gestaltBuiltInSoundInput)) || ! (soundFeatures & (1 << gestaltHasSoundInputDevice))) Melder_throw (U"Your computer does not support sound input."); if (! (soundFeatures & (1 << gestalt16BitSoundIO)) || // hardware ! (soundFeatures & (1 << gestaltStereoInput)) || // hardware ! (soundFeatures & (1 << gestalt16BitAudioSupport))) // software Melder_throw (U"Your computer does not support stereo sound input."); #endif } my numberOfChannels = numberOfChannels; if (sizeof (short) != 2) Melder_throw (U"Long shorts!!!!!"); if (my inputUsesPortAudio) { my synchronous = false; } else { #if defined (macintosh) || defined (_WIN32) my synchronous = false; #else my synchronous = true; #endif } /* * Allocate the maximum buffer. */ if (preferences.bufferSizeInMegabytes < 1) preferences.bufferSizeInMegabytes = 1; // validate preferences if (preferences.bufferSizeInMegabytes > 1000) preferences.bufferSizeInMegabytes = 1000; if (my buffer == NULL) { long nmax_bytes_pref = preferences.bufferSizeInMegabytes * 1000000; long nmax_bytes = my inputUsesPortAudio ? nmax_bytes_pref : #if defined (_WIN32) 66150000; // the maximum physical buffer on Windows XP; shorter than in Windows 98, alas. #else nmax_bytes_pref; #endif my nmax = nmax_bytes / (sizeof (short) * numberOfChannels); for (;;) { try { my buffer = NUMvector (0, my nmax * numberOfChannels - 1); break; // success } catch (MelderError) { if (my nmax < 100000) { throw MelderError (); // failure, with error message } else { Melder_clearError (); my nmax /= 2; // retry with less application memory } } } } Melder_assert (my buffer != NULL); /* * Count the number of input devices and sources. */ if (my inputUsesPortAudio) { static bool paInitialized = false; if (! paInitialized) { PaError err = Pa_Initialize (); if (Melder_debug == 20) Melder_casual (U"init ", Melder_peek8to32 (Pa_GetErrorText (err))); paInitialized = true; if (Melder_debug == 20) { PaHostApiIndex hostApiCount = Pa_GetHostApiCount (); Melder_casual (U"host API count ", hostApiCount); for (PaHostApiIndex iHostApi = 0; iHostApi < hostApiCount; iHostApi ++) { const PaHostApiInfo *hostApiInfo = Pa_GetHostApiInfo (iHostApi); PaHostApiTypeId type = hostApiInfo -> type; Melder_casual (U"host API ", iHostApi, U": ", type, U", \"", Melder_peek8to32 (hostApiInfo -> name), U"\" ", hostApiInfo -> deviceCount); } PaHostApiIndex defaultHostApi = Pa_GetDefaultHostApi (); Melder_casual (U"default host API ", defaultHostApi); PaDeviceIndex deviceCount = Pa_GetDeviceCount (); Melder_casual (U"device count ", deviceCount); } } PaDeviceIndex deviceCount = Pa_GetDeviceCount (); for (PaDeviceIndex idevice = 0; idevice < deviceCount; idevice ++) { const PaDeviceInfo *deviceInfo = Pa_GetDeviceInfo (idevice); if (Melder_debug == 20) Melder_casual ( U"Device \"", Melder_peek8to32 (deviceInfo -> name), U"\", input ", deviceInfo -> maxInputChannels, U", output ", deviceInfo -> maxOutputChannels, U", sample rate ", deviceInfo -> defaultSampleRate ); if (deviceInfo -> maxInputChannels > 0 && my numberOfInputDevices < SoundRecorder_IDEVICE_MAX) { my device_ [++ my numberOfInputDevices]. canDo = true; str32ncpy (my device_ [my numberOfInputDevices]. name, Melder_peek8to32 (deviceInfo -> name), 40); my device_ [my numberOfInputDevices]. name [40] = U'\0'; my deviceInfos [my numberOfInputDevices] = deviceInfo; my deviceIndices [my numberOfInputDevices] = idevice; } } if (my numberOfInputDevices == 0) Melder_throw (U"No input devices available."); } else { #if defined (macintosh) #elif defined (_WIN32) // No device info: use Windows mixer. #else my device_ [1]. canDo = true; str32cpy (my device_ [1]. name, U"Microphone"); my device_ [2]. canDo = true; str32cpy (my device_ [2]. name, U"Line"); #endif } /* * Sampling frequency constants. */ my fsamp_ [SoundRecorder_IFSAMP_8000]. fsamp = 8000.0; my fsamp_ [SoundRecorder_IFSAMP_9800]. fsamp = 9800.0; my fsamp_ [SoundRecorder_IFSAMP_11025]. fsamp = 11025.0; my fsamp_ [SoundRecorder_IFSAMP_12000]. fsamp = 12000.0; my fsamp_ [SoundRecorder_IFSAMP_16000]. fsamp = 16000.0; my fsamp_ [SoundRecorder_IFSAMP_22050]. fsamp = 22050.0; my fsamp_ [SoundRecorder_IFSAMP_22254]. fsamp = 22254.54545; my fsamp_ [SoundRecorder_IFSAMP_24000]. fsamp = 24000.0; my fsamp_ [SoundRecorder_IFSAMP_32000]. fsamp = 32000.0; my fsamp_ [SoundRecorder_IFSAMP_44100]. fsamp = 44100.0; my fsamp_ [SoundRecorder_IFSAMP_48000]. fsamp = 48000.0; my fsamp_ [SoundRecorder_IFSAMP_64000]. fsamp = 64000.0; my fsamp_ [SoundRecorder_IFSAMP_96000]. fsamp = 96000.0; my fsamp_ [SoundRecorder_IFSAMP_192000]. fsamp = 192000.0; /* * The default set of possible sampling frequencies, to be modified in the initialize () procedure. */ for (long i = 1; i <= SoundRecorder_IFSAMP_MAX; i ++) my fsamp_ [i]. canDo = true; // optimistic: can do all, except two: my fsamp_ [SoundRecorder_IFSAMP_9800]. canDo = false; // sgi only my fsamp_ [SoundRecorder_IFSAMP_22254]. canDo = false; // old Mac only /* * Initialize system-dependent structures. * On all systems: stereo 16-bit linear encoding. * Some systems take initial values from the system control panel * (automatically in the workProc), other systems from theControlPanel. */ initialize (me.peek()); Editor_init (me.peek(), 100, 100, 600, 500, U"SoundRecorder", NULL); my graphics = Graphics_create_xmdrawingarea (my meter); Melder_assert (my graphics); Graphics_setWindow (my graphics, 0.0, 1.0, 0.0, 1.0); Graphics_setColour (my graphics, Graphics_WHITE); Graphics_fillRectangle (my graphics, 0.0, 1.0, 0.0, 1.0); struct structGuiDrawingAreaResizeEvent event = { my meter, 0 }; event. width = GuiControl_getWidth (my meter); event. height = GuiControl_getHeight (my meter); gui_drawingarea_cb_resize (me.peek(), & event); #if cocoa CFRunLoopTimerContext context = { 0, me.peek(), NULL, NULL, NULL }; my d_cocoaTimer = CFRunLoopTimerCreate (NULL, CFAbsoluteTimeGetCurrent () + 0.02, 0.02, 0, 0, workProc, & context); CFRunLoopAddTimer (CFRunLoopGetCurrent (), my d_cocoaTimer, kCFRunLoopCommonModes); #elif gtk g_idle_add (workProc, me.peek()); #elif motif my workProcId = GuiAddWorkProc (workProc, me.peek()); #endif updateMenus (me.peek()); return me; } catch (MelderError) { Melder_throw (U"SoundRecorder not created."); } } /* End of file SoundRecorder.cpp */ praat-6.0.04/fon/SoundRecorder.h000066400000000000000000000076511261542461700164420ustar00rootroot00000000000000#ifndef _SoundRecorder_h_ #define _SoundRecorder_h_ /* SoundRecorder.h * * Copyright (C) 1992-2011,2012,2013,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* An editor-like object that allows the user to record sounds. */ #include "Editor.h" #include "Sound.h" #include "SoundRecorder_enums.h" #include "../external/portaudio/portaudio.h" #if defined (_WIN32) #elif defined (macintosh) #elif defined (linux) #include #include #include #include #include #if defined (__OpenBSD__) || defined (__NetBSD__) #include #else #include #endif #endif struct SoundRecorder_Device { char32 name [1+40]; bool canDo; GuiRadioButton button; }; struct SoundRecorder_Fsamp { double fsamp; bool canDo; GuiRadioButton button; }; #define SoundRecorder_IDEVICE_MAX 8 #define SoundRecorder_IFSAMP_8000 1 #define SoundRecorder_IFSAMP_9800 2 #define SoundRecorder_IFSAMP_11025 3 #define SoundRecorder_IFSAMP_12000 4 #define SoundRecorder_IFSAMP_16000 5 #define SoundRecorder_IFSAMP_22050 6 #define SoundRecorder_IFSAMP_22254 7 #define SoundRecorder_IFSAMP_24000 8 #define SoundRecorder_IFSAMP_32000 9 #define SoundRecorder_IFSAMP_44100 10 #define SoundRecorder_IFSAMP_48000 11 #define SoundRecorder_IFSAMP_64000 12 #define SoundRecorder_IFSAMP_96000 13 #define SoundRecorder_IFSAMP_192000 14 #define SoundRecorder_IFSAMP_MAX 14 Thing_define (SoundRecorder, Editor) { int numberOfChannels; long nsamp, nmax; bool fakeMono, synchronous, recording; int lastLeftMaximum, lastRightMaximum; long numberOfInputDevices; struct SoundRecorder_Device device_ [1+SoundRecorder_IDEVICE_MAX]; struct SoundRecorder_Fsamp fsamp_ [1+SoundRecorder_IFSAMP_MAX]; short *buffer; GuiRadioButton monoButton, stereoButton; GuiDrawingArea meter; GuiScale progressScale; GuiButton recordButton, stopButton, playButton; GuiText soundName; GuiButton cancelButton, applyButton, okButton; GuiMenuItem d_meterIntensityButton, d_meterCentreOfGravityVersusIntensityButton; Graphics graphics; bool inputUsesPortAudio; const PaDeviceInfo *deviceInfos [1+SoundRecorder_IDEVICE_MAX]; PaDeviceIndex deviceIndices [1+SoundRecorder_IDEVICE_MAX]; PaStream *portaudioStream; #if cocoa CFRunLoopTimerRef d_cocoaTimer; #elif motif XtWorkProcId workProcId; #endif #if defined (_WIN32) HWAVEIN hWaveIn; WAVEFORMATEX waveFormat; WAVEHDR waveHeader [3]; MMRESULT err; short buffertje1 [1000*2], buffertje2 [1000*2]; #elif defined (macintosh) short macSource [1+8]; Str255 hybridDeviceNames [1+8]; long refNum; #elif defined (linux) int fd; #else int fd; #endif void v_destroy () override; bool v_editable () override { return false; } bool v_scriptable () override { return false; } void v_createChildren () override; void v_createMenus () override; void v_createHelpMenuItems (EditorMenu menu) override; #include "SoundRecorder_prefs.h" }; autoSoundRecorder SoundRecorder_create (int numberOfChannels); /* Function: create a SoundRecorder, which is an interactive window for recording in 16-bit mono or stereo. */ void SoundRecorder_preferences (); int SoundRecorder_getBufferSizePref_MB (); void SoundRecorder_setBufferSizePref_MB (int size); /* End of file SoundRecorder.h */ #endif praat-6.0.04/fon/SoundRecorder_enums.h000066400000000000000000000020531261542461700176400ustar00rootroot00000000000000/* SoundRecorder_enums.h * * Copyright (C) 2013,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ enums_begin (kSoundRecorder_meter, 1) enums_add (kSoundRecorder_meter, 1, INTENSITY, U"intensity") enums_add (kSoundRecorder_meter, 2, CENTRE_OF_GRAVITY_VERSUS_INTENSITY, U"centre of gravity ~ intensity") enums_end (kSoundRecorder_meter, 2, INTENSITY) /* End of file SoundRecorder_enums.h */ praat-6.0.04/fon/SoundRecorder_prefs.h000066400000000000000000000024721261542461700176350ustar00rootroot00000000000000/* SoundRecorder_prefs.h * * Copyright (C) 2013,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ prefs_begin (SoundRecorder) prefs_add_enum_with_data (SoundRecorder, meter_which, 1, kSoundRecorder_meter, INTENSITY) prefs_add_double_with_data (SoundRecorder, meter_intensity_minimum, 1, U"50.0") // dB prefs_add_double_with_data (SoundRecorder, meter_intensity_maximum, 1, U"94.0") // dB prefs_add_double_with_data (SoundRecorder, meter_centreOfGravity_minimum, 1, U"500.0") // Hz prefs_add_double_with_data (SoundRecorder, meter_centreOfGravity_maximum, 1, U"8000.0") // Hz prefs_end (SoundRecorder) /* End of file SoundRecorder_prefs.h */ praat-6.0.04/fon/Sound_PointProcess.cpp000066400000000000000000000043371261542461700200150ustar00rootroot00000000000000/* Sound_PointProcess.cpp * * Copyright (C) 2010-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2010/12/09 created * pb 2011/06/08 C++ */ #include "Sound_PointProcess.h" autoSound Sound_PointProcess_to_SoundEnsemble_correlate (Sound me, PointProcess thee, double fromLag, double toLag) { try { if (my ny > 1) Melder_throw (U"Sound has to be mono."); long numberOfPoints = thy nt; double hisDuration = toLag - fromLag; long numberOfSamples = (long) floor (hisDuration / my dx) + 1; if (numberOfSamples < 1) Melder_throw (U"Time window too short."); double midTime = 0.5 * (fromLag + toLag); double hisPhysicalDuration = numberOfSamples * my dx; double firstTime = midTime - 0.5 * hisPhysicalDuration + 0.5 * my dx; // distribute the samples evenly over the time domain autoSound him = Sound_create (numberOfPoints, fromLag, toLag, numberOfSamples, my dx, firstTime); for (long ipoint = 1; ipoint <= numberOfPoints; ipoint ++) { double myTimeOfPoint = thy t [ipoint]; double hisTimeOfPoint = 0.0; double mySample = 1 + (myTimeOfPoint - my x1) / my dx; double hisSample = 1 + (hisTimeOfPoint - his x1) / my dx; long sampleDifference = lround (mySample - hisSample); for (long isample = 1; isample <= numberOfSamples; isample ++) { long jsample = isample + sampleDifference; his z [ipoint] [isample] = jsample < 1 || jsample > my nx ? 0.0 : my z [1] [jsample]; } } return him; } catch (MelderError) { Melder_throw (me, U" & ", thee, U": Sound ensemble not created."); } } /* End of file Sound_PointProcess.cpp */ praat-6.0.04/fon/Sound_PointProcess.h000066400000000000000000000017171261542461700174610ustar00rootroot00000000000000/* Sound_PointProcess.h * * Copyright (C) 2010-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Sound.h" #include "PointProcess.h" autoSound Sound_PointProcess_to_SoundEnsemble_correlate (Sound me, PointProcess thee, double tmin, double tmax); /* End of file Sound_PointProcess.h */ praat-6.0.04/fon/Sound_and_Spectrogram.cpp000066400000000000000000000206041261542461700204700ustar00rootroot00000000000000/* Sound_and_Spectrogram.cpp * * Copyright (C) 1992-2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2003/07/02 checks on NUMrealft * pb 2003/11/30 Sound_to_Spectrogram_windowShapeText * pb 2004/03/13 bins are a fixed number of frequency samples wide; * this improves the positioning of peaks; thanks to Gabriel Beckers for his persistence * pb 2004/10/18 use of FFT tables speeds everything up by a factor of 2.5 * pb 2004/10/20 progress bar * pb 2006/12/30 new Sound_create API * pb 2007/01/01 compatible with stereo sounds * pb 2007/12/06 enums * pb 2008/01/19 double * pb 2010/02/26 fixed a message * pb 2011/06/06 C++ */ #include "Sound_and_Spectrogram.h" #include "NUM2.h" #include "enums_getText.h" #include "Sound_and_Spectrogram_enums.h" #include "enums_getValue.h" #include "Sound_and_Spectrogram_enums.h" autoSpectrogram Sound_to_Spectrogram (Sound me, double effectiveAnalysisWidth, double fmax, double minimumTimeStep1, double minimumFreqStep1, enum kSound_to_Spectrogram_windowShape windowType, double maximumTimeOversampling, double maximumFreqOversampling) { try { double nyquist = 0.5 / my dx; double physicalAnalysisWidth = windowType == kSound_to_Spectrogram_windowShape_GAUSSIAN ? 2 * effectiveAnalysisWidth : effectiveAnalysisWidth; double effectiveTimeWidth = effectiveAnalysisWidth / sqrt (NUMpi); double effectiveFreqWidth = 1 / effectiveTimeWidth; double minimumTimeStep2 = effectiveTimeWidth / maximumTimeOversampling; double minimumFreqStep2 = effectiveFreqWidth / maximumFreqOversampling; double timeStep = minimumTimeStep1 > minimumTimeStep2 ? minimumTimeStep1 : minimumTimeStep2; double freqStep = minimumFreqStep1 > minimumFreqStep2 ? minimumFreqStep1 : minimumFreqStep2; double duration = my dx * (double) my nx, windowssq = 0.0; /* * Compute the time sampling. */ long nsamp_window = (long) floor (physicalAnalysisWidth / my dx); long halfnsamp_window = nsamp_window / 2 - 1; nsamp_window = halfnsamp_window * 2; if (nsamp_window < 1) Melder_throw (U"Your analysis window is too short: less than two samples."); if (physicalAnalysisWidth > duration) Melder_throw (U"Your sound is too short:\n" U"it should be at least as long as ", windowType == kSound_to_Spectrogram_windowShape_GAUSSIAN ? U"two window lengths." : U"one window length."); long numberOfTimes = 1 + (long) floor ((duration - physicalAnalysisWidth) / timeStep); // >= 1 double t1 = my x1 + 0.5 * ((double) (my nx - 1) * my dx - (double) (numberOfTimes - 1) * timeStep); /* Centre of first frame. */ /* * Compute the frequency sampling of the FFT spectrum. */ if (fmax <= 0.0 || fmax > nyquist) fmax = nyquist; long numberOfFreqs = (long) floor (fmax / freqStep); if (numberOfFreqs < 1) return NULL; long nsampFFT = 1; while (nsampFFT < nsamp_window || nsampFFT < 2 * numberOfFreqs * (nyquist / fmax)) nsampFFT *= 2; long half_nsampFFT = nsampFFT / 2; /* * Compute the frequency sampling of the spectrogram. */ long binWidth_samples = (long) floor (freqStep * my dx * nsampFFT); if (binWidth_samples < 1) binWidth_samples = 1; double binWidth_hertz = 1.0 / (my dx * nsampFFT); freqStep = binWidth_samples * binWidth_hertz; numberOfFreqs = (long) floor (fmax / freqStep); if (numberOfFreqs < 1) return NULL; autoSpectrogram thee = Spectrogram_create (my xmin, my xmax, numberOfTimes, timeStep, t1, 0.0, fmax, numberOfFreqs, freqStep, 0.5 * (freqStep - binWidth_hertz)); autoNUMvector frame (1, nsampFFT); autoNUMvector spec (1, nsampFFT); autoNUMvector window (1, nsamp_window); autoNUMfft_Table fftTable; NUMfft_Table_init (& fftTable, nsampFFT); autoMelderProgress progress (U"Sound to Spectrogram..."); for (long i = 1; i <= nsamp_window; i ++) { double nSamplesPerWindow_f = physicalAnalysisWidth / my dx; double phase = (double) i / nSamplesPerWindow_f; // 0 .. 1 double value; switch (windowType) { case kSound_to_Spectrogram_windowShape_SQUARE: value = 1.0; break; case kSound_to_Spectrogram_windowShape_HAMMING: value = 0.54 - 0.46 * cos (2.0 * NUMpi * phase); break; case kSound_to_Spectrogram_windowShape_BARTLETT: value = 1.0 - fabs ((2.0 * phase - 1.0)); break; case kSound_to_Spectrogram_windowShape_WELCH: value = 1.0 - (2.0 * phase - 1.0) * (2.0 * phase - 1.0); break; case kSound_to_Spectrogram_windowShape_HANNING: value = 0.5 * (1.0 - cos (2.0 * NUMpi * phase)); break; case kSound_to_Spectrogram_windowShape_GAUSSIAN: { double imid = 0.5 * (double) (nsamp_window + 1), edge = exp (-12.0); phase = ((double) i - imid) / nSamplesPerWindow_f; /* -0.5 .. +0.5 */ value = (exp (-48.0 * phase * phase) - edge) / (1.0 - edge); break; } break; default: value = 1.0; } window [i] = (float) value; windowssq += value * value; } double oneByBinWidth = 1.0 / windowssq / binWidth_samples; for (long iframe = 1; iframe <= numberOfTimes; iframe ++) { double t = Sampled_indexToX (thee.peek(), iframe); long leftSample = Sampled_xToLowIndex (me, t), rightSample = leftSample + 1; long startSample = rightSample - halfnsamp_window; long endSample = leftSample + halfnsamp_window; Melder_assert (startSample >= 1); Melder_assert (endSample <= my nx); for (long i = 1; i <= half_nsampFFT; i ++) { spec [i] = 0.0; } for (long channel = 1; channel <= my ny; channel ++) { for (long j = 1, i = startSample; j <= nsamp_window; j ++) { frame [j] = my z [channel] [i ++] * window [j]; } for (long j = nsamp_window + 1; j <= nsampFFT; j ++) frame [j] = 0.0f; Melder_progress (iframe / (numberOfTimes + 1.0), U"Sound to Spectrogram: analysis of frame ", iframe, U" out of ", numberOfTimes); /* Compute Fast Fourier Transform of the frame. */ NUMfft_forward (& fftTable, frame.peek()); // complex spectrum /* Put power spectrum in frame [1..half_nsampFFT + 1]. */ spec [1] += frame [1] * frame [1]; // DC component for (long i = 2; i <= half_nsampFFT; i ++) spec [i] += frame [i + i - 2] * frame [i + i - 2] + frame [i + i - 1] * frame [i + i - 1]; spec [half_nsampFFT + 1] += frame [nsampFFT] * frame [nsampFFT]; // Nyquist frequency. Correct?? } if (my ny > 1 ) for (long i = 1; i <= half_nsampFFT; i ++) { spec [i] /= my ny; } /* Bin into frame [1..nBands]. */ for (long iband = 1; iband <= numberOfFreqs; iband ++) { long leftsample = (iband - 1) * binWidth_samples + 1, rightsample = leftsample + binWidth_samples; float power = 0.0f; for (long i = leftsample; i < rightsample; i ++) power += spec [i]; thy z [iband] [iframe] = power * oneByBinWidth; } } return thee; } catch (MelderError) { Melder_throw (me, U": spectrogram analysis not performed."); } } autoSound Spectrogram_to_Sound (Spectrogram me, double fsamp) { try { double dt = 1 / fsamp; long n = (long) floor ((my xmax - my xmin) / dt); if (n < 0) return NULL; autoSound thee = Sound_create (1, my xmin, my xmax, n, dt, 0.5 * dt); for (long i = 1; i <= n; i ++) { double t = Sampled_indexToX (thee.peek(), i); double rframe = Sampled_xToIndex (me, t), phase, value = 0.0; long leftFrame, rightFrame; if (rframe < 1 || rframe >= my nx) continue; leftFrame = (long) floor (rframe), rightFrame = leftFrame + 1, phase = rframe - leftFrame; for (long j = 1; j <= my ny; j ++) { double f = Matrix_rowToY (me, j); double power = my z [j] [leftFrame] * (1 - phase) + my z [j] [rightFrame] * phase; value += sqrt (power) * sin (2 * NUMpi * f * t); } thy z [1] [i] = value; } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Sound."); } } /* End of file Sound_and_Spectrogram.cpp */ praat-6.0.04/fon/Sound_and_Spectrogram.h000066400000000000000000000024301261542461700201320ustar00rootroot00000000000000#ifndef _Sound_and_Spectrogram_h_ #define _Sound_and_Spectrogram_h_ /* Sound_and_Spectrogram.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Sound.h" #include "Spectrogram.h" #include "Sound_and_Spectrogram_enums.h" autoSpectrogram Sound_to_Spectrogram (Sound me, double effectiveAnalysisWidth, double fmax, double minimumTimeStep1, double minimumFreqStep1, enum kSound_to_Spectrogram_windowShape windowShape, double maximumTimeOversampling, double maximumFreqOversampling); autoSound Spectrogram_to_Sound (Spectrogram me, double fsamp); /* End of Sound_and_Spectrogram.h */ #endif praat-6.0.04/fon/Sound_and_Spectrogram_enums.h000066400000000000000000000031121261542461700213370ustar00rootroot00000000000000/* Sound_and_Spectrogram_enums.h * * Copyright (C) 1992-2007,2013,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ enums_begin (kSound_to_Spectrogram_method, 1) enums_add (kSound_to_Spectrogram_method, 1, FOURIER, U"Fourier") enums_end (kSound_to_Spectrogram_method, 1, FOURIER) enums_begin (kSound_to_Spectrogram_windowShape, 0) enums_add (kSound_to_Spectrogram_windowShape, 0, SQUARE, U"square (rectangular)") enums_add (kSound_to_Spectrogram_windowShape, 1, HAMMING, U"Hamming (raised sine-squared)") enums_add (kSound_to_Spectrogram_windowShape, 2, BARTLETT, U"Bartlett (triangular)") enums_add (kSound_to_Spectrogram_windowShape, 3, WELCH, U"Welch (parabolic)") enums_add (kSound_to_Spectrogram_windowShape, 4, HANNING, U"Hanning (sine-squared)") enums_add (kSound_to_Spectrogram_windowShape, 5, GAUSSIAN, U"Gaussian") enums_end (kSound_to_Spectrogram_windowShape, 5, GAUSSIAN) /* End of Sound_and_Spectrogram_enums.h */ praat-6.0.04/fon/Sound_and_Spectrum.cpp000066400000000000000000000172351261542461700200120ustar00rootroot00000000000000/* Sound_and_Spectrum.cpp * * Copyright (C) 1992-2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2003/03/09 shorter sounds from Hann band filtering * pb 2003/05/15 replaced memcof with NUMburg * pb 2003/07/02 checks on NUMrealft * pb 2004/04/21 Sound_to_Spectrum_dft * pb 2004/10/18 explicit Fourier tables * pb 2004/11/22 single Sound_to_Spectrum procedure * pb 2006/12/30 new Sound_create API * pb 2006/12/31 compatible with stereo sounds * pb 2009/01/18 Interpreter argument to formula * pb 2011/06/06 C++ */ #include "Sound_and_Spectrum.h" #include "NUM2.h" autoSpectrum Sound_to_Spectrum (Sound me, int fast) { try { long numberOfSamples = my nx; if (fast) { numberOfSamples = 2; while (numberOfSamples < my nx) numberOfSamples *= 2; } long numberOfFrequencies = numberOfSamples / 2 + 1; // 4 samples -> cos0 cos1 sin1 cos2; 5 samples -> cos0 cos1 sin1 cos2 sin2 autoNUMvector data (1, numberOfSamples); autoNUMfft_Table fourierTable; NUMfft_Table_init (& fourierTable, numberOfSamples); for (long i = 1; i <= my nx; i ++) data [i] = my ny == 1 ? my z [1] [i] : 0.5 * (my z [1] [i] + my z [2] [i]); NUMfft_forward (& fourierTable, data.peek()); autoSpectrum thee = Spectrum_create (0.5 / my dx, numberOfFrequencies); thy dx = 1.0 / (my dx * numberOfSamples); // override double *re = thy z [1]; double *im = thy z [2]; double scaling = my dx; re [1] = data [1] * scaling; im [1] = 0.0; for (long i = 2; i < numberOfFrequencies; i ++) { re [i] = data [i + i - 2] * scaling; im [i] = data [i + i - 1] * scaling; } if ((numberOfSamples & 1) != 0) { if (numberOfSamples > 1) { re [numberOfFrequencies] = data [numberOfSamples - 1] * scaling; im [numberOfFrequencies] = data [numberOfSamples] * scaling; } } else { re [numberOfFrequencies] = data [numberOfSamples] * scaling; im [numberOfFrequencies] = 0.0; } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Spectrum."); } } autoSound Spectrum_to_Sound (Spectrum me) { try { double *re = my z [1], *im = my z [2]; double lastFrequency = my x1 + (my nx - 1) * my dx; int originalNumberOfSamplesProbablyOdd = im [my nx] != 0.0 || my xmax - lastFrequency > 0.25 * my dx; if (my x1 != 0.0) Melder_throw (U"A Fourier-transformable Spectrum must have a first frequency of 0 Hz, not ", my x1, U" Hz."); long numberOfSamples = 2 * my nx - ( originalNumberOfSamplesProbablyOdd ? 1 : 2 ); autoSound thee = Sound_createSimple (1, 1 / my dx, numberOfSamples * my dx); double *amp = thy z [1]; double scaling = my dx; amp [1] = re [1] * scaling; for (long i = 2; i < my nx; i ++) { amp [i + i - 1] = re [i] * scaling; amp [i + i] = im [i] * scaling; } if (originalNumberOfSamplesProbablyOdd) { amp [numberOfSamples] = re [my nx] * scaling; if (numberOfSamples > 1) amp [2] = im [my nx] * scaling; } else { amp [2] = re [my nx] * scaling; } NUMrealft (amp, numberOfSamples, -1); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Sound."); } } autoSpectrum Spectrum_lpcSmoothing (Spectrum me, int numberOfPeaks, double preemphasisFrequency) { try { double gain, a [100]; long numberOfCoefficients = 2 * numberOfPeaks; autoSound sound = Spectrum_to_Sound (me); NUMpreemphasize_f (sound -> z [1], sound -> nx, sound -> dx, preemphasisFrequency); NUMburg (sound -> z [1], sound -> nx, a, numberOfCoefficients, & gain); for (long i = 1; i <= numberOfCoefficients; i ++) a [i] = - a [i]; autoSpectrum thee = Data_copy (me); long nfft = 2 * (thy nx - 1); long ndata = numberOfCoefficients < nfft ? numberOfCoefficients : nfft - 1; double scale = 10 * (gain > 0 ? sqrt (gain) : 1) / numberOfCoefficients; autoNUMvector data (1, nfft); data [1] = 1; for (long i = 1; i <= ndata; i ++) data [i + 1] = a [i]; NUMrealft (data.peek(), nfft, 1); double *re = thy z [1]; double *im = thy z [2]; re [1] = scale / data [1]; im [1] = 0.0; long halfnfft = nfft / 2; for (long i = 2; i <= halfnfft; i ++) { double real = data [i + i - 1], imag = data [i + i]; re [i] = scale / sqrt (real * real + imag * imag) / (1 + thy dx * (i - 1) / preemphasisFrequency); im [i] = 0; } re [halfnfft + 1] = scale / data [2] / (1 + thy dx * halfnfft / preemphasisFrequency); im [halfnfft + 1] = 0.0; return thee; } catch (MelderError) { Melder_throw (me, U": not smoothed."); } } autoSound Sound_filter_formula (Sound me, const char32 *formula, Interpreter interpreter) { try { autoSound thee = Data_copy (me); if (my ny == 1) { autoSpectrum spec = Sound_to_Spectrum (me, true); Matrix_formula ((Matrix) spec.peek(), formula, interpreter, nullptr); autoSound him = Spectrum_to_Sound (spec.peek()); NUMvector_copyElements (his z [1], thy z [1], 1, thy nx); } else { for (long ichan = 1; ichan <= my ny; ichan ++) { autoSound channel = Sound_extractChannel (me, ichan); autoSpectrum spec = Sound_to_Spectrum (channel.peek(), true); Matrix_formula ((Matrix) spec.peek(), formula, interpreter, nullptr); autoSound him = Spectrum_to_Sound (spec.peek()); NUMvector_copyElements (his z [1], thy z [ichan], 1, thy nx); } } return thee; } catch (MelderError) { Melder_throw (me, U": not filtered (with formula)."); } } autoSound Sound_filter_passHannBand (Sound me, double fmin, double fmax, double smooth) { try { autoSound thee = Data_copy (me); if (my ny == 1) { autoSpectrum spec = Sound_to_Spectrum (me, true); Spectrum_passHannBand (spec.peek(), fmin, fmax, smooth); autoSound him = Spectrum_to_Sound (spec.peek()); NUMvector_copyElements (his z [1], thy z [1], 1, thy nx); } else { for (long ichan = 1; ichan <= my ny; ichan ++) { autoSound channel = Sound_extractChannel (me, ichan); autoSpectrum spec = Sound_to_Spectrum (channel.peek(), true); Spectrum_passHannBand (spec.peek(), fmin, fmax, smooth); autoSound him = Spectrum_to_Sound (spec.peek()); NUMvector_copyElements (his z [1], thy z [ichan], 1, thy nx); } } return thee; } catch (MelderError) { Melder_throw (me, U": not filtered (pass Hann band)."); } } autoSound Sound_filter_stopHannBand (Sound me, double fmin, double fmax, double smooth) { try { autoSound thee = Data_copy (me); if (my ny == 1) { autoSpectrum spec = Sound_to_Spectrum (me, true); Spectrum_stopHannBand (spec.peek(), fmin, fmax, smooth); autoSound him = Spectrum_to_Sound (spec.peek()); NUMvector_copyElements (his z [1], thy z [1], 1, thy nx); } else { for (long ichan = 1; ichan <= my ny; ichan ++) { autoSound channel = Sound_extractChannel (me, ichan); autoSpectrum spec = Sound_to_Spectrum (channel.peek(), true); Spectrum_stopHannBand (spec.peek(), fmin, fmax, smooth); autoSound him = Spectrum_to_Sound (spec.peek()); NUMvector_copyElements (his z [1], thy z [ichan], 1, thy nx); } } return thee; } catch (MelderError) { Melder_throw (me, U": not filtered (stop Hann band)."); } } /* End of file Sound_and_Spectrum.cpp */ praat-6.0.04/fon/Sound_and_Spectrum.h000066400000000000000000000026531261542461700174550ustar00rootroot00000000000000/* Sound_and_Spectrum.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Sound.h" #include "Spectrum.h" #include "Interpreter_decl.h" autoSpectrum Sound_to_Spectrum_at (Sound me, double tim, double windowDuration, int windowType); autoSpectrum Sound_to_Spectrum (Sound me, int fast); autoSound Spectrum_to_Sound (Spectrum me); autoSpectrum Spectrum_lpcSmoothing (Spectrum me, int numberOfPeaks, double preemphasisFrequency); autoSound Sound_filter_passHannBand (Sound me, double fmin, double fmax, double smooth); autoSound Sound_filter_stopHannBand (Sound me, double fmin, double fmax, double smooth); autoSound Sound_filter_formula (Sound me, const char32 *formula, Interpreter interpreter); /* End of file Sound_and_Spectrum.h */ praat-6.0.04/fon/Sound_audio.cpp000066400000000000000000000525571261542461700164750ustar00rootroot00000000000000/* Sound_audio.cpp * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2003/09/14 Sound_recordFixedTime records in stereo if mono is not available * pb 2003/12/06 use sys/soundcard.h instead of linux/soundcard.h for FreeBSD compatibility * pb 2005/04/24 Sound_recordFixedTime: Firewire Solo 1264 * pb 2005/06/16 removed previous change (System Preferences handles this) * pb 2005/10/13 edition for OpenBSD * pb 2006/10/28 erased MacOS 9 stuff * pb 2006/12/20 Sound_playPart and Sound_play allow stereo * pb 2006/12/30 Sound_playPart and Sound_play allow better stereo * pb 2007/01/07 PortAudio * Stefan de Konink 2007/12/02 big-endian Linux * pb 2008/01/19 double * pb 2008/07/07 split zero padding between silenceBefore and silenceAfter * fb 2010/02/26 fix resource leak fd_mixer in case of error during init * pb 2010/04/20 Sound_recordFixedTime for Linux: repair * pb 2010/11/02 Sound_recordFixedTime for Linux: repair bug from 1998 * pb 2011/06/07 C++ */ #include #ifdef linux #define DEV_AUDIO "/dev/dsp" #else #define DEV_AUDIO "/dev/audio" #endif #include "Sound.h" #include "Preferences.h" #include "../external/portaudio/portaudio.h" #if defined (macintosh) #include "macport_on.h" #if useCarbon #include #endif #include "pa_mac_core.h" #include "macport_off.h" #elif defined (_WIN32) #include "winport_on.h" #include #include #include "winport_off.h" #elif defined (linux) #include #if defined (__OpenBSD__) || defined (__NetBSD__) #include #else #include #endif #include /* ioctl */ #include /* open write close read */ #else #include #endif static int ulaw2linear [] = { -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956, -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764, -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412, -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316, -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140, -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092, -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004, -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980, -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436, -1372, -1308, -1244, -1180, -1116, -1052, -988, -924, -876, -844, -812, -780, -748, -716, -684, -652, -620, -588, -556, -524, -492, -460, -428, -396, -372, -356, -340, -324, -308, -292, -276, -260, -244, -228, -212, -196, -180, -164, -148, -132, -120, -112, -104, -96, -88, -80, -72, -64, -56, -48, -40, -32, -24, -16, -8, 0, 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956, 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764, 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412, 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316, 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140, 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092, 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004, 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980, 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436, 1372, 1308, 1244, 1180, 1116, 1052, 988, 924, 876, 844, 812, 780, 748, 716, 684, 652, 620, 588, 556, 524, 492, 460, 428, 396, 372, 356, 340, 324, 308, 292, 276, 260, 244, 228, 212, 196, 180, 164, 148, 132, 120, 112, 104, 96, 88, 80, 72, 64, 56, 48, 40, 32, 24, 16, 8, 0 }; struct Sound_recordFixedTime_Info { long numberOfSamples, numberOfSamplesRead; short *buffer; }; static long getNumberOfSamplesRead (volatile struct Sound_recordFixedTime_Info *info) { volatile long numberOfSamplesRead = info -> numberOfSamplesRead; return numberOfSamplesRead; } static int portaudioStreamCallback ( const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *void_info) { (void) output; (void) timeInfo; (void) statusFlags; struct Sound_recordFixedTime_Info *info = (struct Sound_recordFixedTime_Info *) void_info; unsigned long samplesLeft = info -> numberOfSamples - info -> numberOfSamplesRead; if (samplesLeft > 0) { unsigned long dsamples = samplesLeft > frameCount ? frameCount : samplesLeft; memcpy (info -> buffer + 1 + info -> numberOfSamplesRead, input, 2 * dsamples); info -> numberOfSamplesRead += dsamples; short *input2 = (short*) input; trace (U"read ", dsamples, U" samples: ", input2 [0], U", ", input2 [1], U", ", input2 [3], U"..."); if (info -> numberOfSamplesRead >= info -> numberOfSamples) return paComplete; } else /*if (info -> numberOfSamplesRead >= info -> numberOfSamples)*/ { info -> numberOfSamplesRead = info -> numberOfSamples; return paComplete; } return paContinue; } autoSound Sound_recordFixedTime (int inputSource, double gain, double balance, double sampleRate, double duration) { bool inputUsesPortAudio = #if defined (_WIN32) MelderAudio_getInputSoundSystem () == kMelder_inputSoundSystem_MME_VIA_PORTAUDIO; #elif defined (macintosh) MelderAudio_getInputSoundSystem () == kMelder_inputSoundSystem_COREAUDIO_VIA_PORTAUDIO; #else MelderAudio_getInputSoundSystem () == kMelder_inputSoundSystem_ALSA_VIA_PORTAUDIO; #endif PaStream *portaudioStream = NULL; #if defined (macintosh) #elif defined (_WIN32) HWAVEIN hWaveIn = 0; #else int fd = -1; // other systems use stream I/O with a file descriptor int fd_mixer = -1; #endif try { long numberOfSamples, i; bool mulaw = false; bool can16bit = true; bool fakeMonoByStereo = false; // will be set to `true` for systems (like MacOS X) that do not allow direct mono recording /* Declare system-dependent data structures. */ static bool paInitialized = false; volatile struct Sound_recordFixedTime_Info info = { 0 }; PaStreamParameters streamParameters = { 0 }; #if defined (macintosh) (void) gain; (void) balance; #elif defined (_WIN32) WAVEFORMATEX waveFormat; WAVEHDR waveHeader; MMRESULT err; (void) inputSource; (void) gain; (void) balance; #elif defined (linux) #define min(a,b) a > b ? b : a int dev_mask; int fd_mixer = -1; int val; #endif /* Check representation of shorts. */ if (sizeof (short) != 2) Melder_throw (U"Cannot record a sound on this computer."); /* Check sampling frequency. */ bool supportsSamplingFrequency = true; if (inputUsesPortAudio) { #if defined (macintosh) if (sampleRate != 44100 && sampleRate != 48000 && sampleRate != 96000) supportsSamplingFrequency = false; #endif } else { #if defined (macintosh) if (sampleRate != 44100) supportsSamplingFrequency = false; #elif defined (linux) if (sampleRate != 8000 && sampleRate != 11025 && sampleRate != 16000 && sampleRate != 22050 && sampleRate != 32000 && sampleRate != 44100 && sampleRate != 48000) supportsSamplingFrequency = false; #elif defined (_WIN32) if (sampleRate != 8000 && sampleRate != 11025 && sampleRate != 16000 && sampleRate != 22050 && sampleRate != 32000 && sampleRate != 44100 && sampleRate != 48000 && sampleRate != 96000) supportsSamplingFrequency = false; #endif } if (! supportsSamplingFrequency) Melder_throw (U"Your audio hardware does not support a sampling frequency of ", sampleRate, U" Hz."); /* * Open phase 1. * On some systems, the info is filled in before the audio port is opened. * On other systems, the info is filled in after the port is opened. */ if (inputUsesPortAudio) { if (! paInitialized) { PaError err = Pa_Initialize (); if (err) Melder_throw (U"Pa_Initialize: ", Melder_peek8to32 (Pa_GetErrorText (err))); paInitialized = true; } } else { #if defined (macintosh) #elif defined (_WIN32) #else /* We must open the port now, because we use an ioctl to set the info to an open port. */ fd = open (DEV_AUDIO, O_RDONLY); if (fd == -1) { if (errno == EBUSY) Melder_throw (U"Audio device in use by another program."); else #ifdef linux Melder_throw (U"Cannot open audio device.\nPlease switch on PortAudio in the Sound Recording Preferences."); #else Melder_throw (U"Cannot open audio device."); #endif } /* The device immediately started recording into its buffer, but probably at the wrong rate etc. */ /* Pause and flush this rubbish. */ #if defined (linux) ioctl (fd, SNDCTL_DSP_RESET, NULL); #endif #endif } /* Set the input source; the default is the microphone. */ if (inputUsesPortAudio) { if (inputSource < 1 || inputSource > Pa_GetDeviceCount ()) Melder_throw (U"Unknown device #", inputSource, U"."); streamParameters. device = inputSource - 1; } else { #if defined (macintosh) #elif defined (linux) fd_mixer = open ("/dev/mixer", O_WRONLY); if (fd_mixer == -1) Melder_throw (U"Cannot open /dev/mixer."); dev_mask = inputSource == 1 ? SOUND_MASK_MIC : SOUND_MASK_LINE; if (ioctl (fd_mixer, SOUND_MIXER_WRITE_RECSRC, & dev_mask) == -1) Melder_throw (U"Cannot set recording device in mixer"); #endif } /* Set gain and balance. */ if (inputUsesPortAudio) { /* Taken from Audio Control Panel. */ } else { #if defined (macintosh) || defined (_WIN32) /* Taken from Audio Control Panel. */ #elif defined (linux) val = (gain <= 0.0 ? 0 : gain >= 1.0 ? 100 : floor (gain * 100 + 0.5)); balance = balance <= 0 ? 0 : balance >= 1 ? 1 : balance; if (balance >= 0.5) { val = (int)(((int)(val*balance/(1-balance)) << 8) | val); } else { val = (int)(val | ((int)(val*(1-balance)/balance) << 8)); } val = (int)((min(2-2*balance,1))*val) | ((int)((min(2*balance,1))*val) << 8); if (inputSource == 1) { /* MIC */ if (ioctl (fd_mixer, MIXER_WRITE (SOUND_MIXER_MIC), & val) == -1) Melder_throw (U"Cannot set gain and balance."); } else { /* LINE */ if (ioctl (fd_mixer, MIXER_WRITE (SOUND_MIXER_LINE), & val) == -1) Melder_throw (U"Cannot set gain and balance."); } close (fd_mixer); fd_mixer = -1; #endif } /* Set the sampling frequency. */ if (inputUsesPortAudio) { // Set while opening. } else { #if defined (macintosh) #elif defined (linux) int sampleRate_int = (int) sampleRate; if (ioctl (fd, SNDCTL_DSP_SPEED, & sampleRate_int) == -1) Melder_throw (U"Cannot set sampling frequency to ", sampleRate, U" Hz."); #elif defined (_WIN32) waveFormat. nSamplesPerSec = sampleRate; #endif } /* Set the number of channels to 1 (mono), if possible. */ if (inputUsesPortAudio) { streamParameters. channelCount = 1; } else { #if defined (macintosh) #elif defined (linux) val = 1; if (ioctl (fd, SNDCTL_DSP_CHANNELS, & val) == -1) Melder_throw (U"Cannot set to mono."); #elif defined (_WIN32) waveFormat. nChannels = 1; #endif } /* Set the encoding to 16-bit linear (or to 8-bit linear, if 16-bit is not available). */ if (inputUsesPortAudio) { streamParameters. sampleFormat = paInt16; } else { #if defined (macintosh) #elif defined (linux) #if __BYTE_ORDER == __BIG_ENDIAN val = AFMT_S16_BE; #else val = AFMT_S16_LE; #endif if (ioctl (fd, SNDCTL_DSP_SETFMT, & val) == -1) Melder_throw (U"Cannot set 16-bit linear."); #elif defined (_WIN32) waveFormat. wFormatTag = WAVE_FORMAT_PCM; waveFormat. wBitsPerSample = 16; waveFormat. nBlockAlign = waveFormat. nChannels * waveFormat. wBitsPerSample / 8; waveFormat. nAvgBytesPerSec = waveFormat. nBlockAlign * waveFormat. nSamplesPerSec; #endif } /* Create a buffer for recording, and the resulting sound. */ numberOfSamples = lround (sampleRate * duration); if (numberOfSamples < 1) Melder_throw (U"Duration too short."); autoNUMvector buffer (1, numberOfSamples * (fakeMonoByStereo ? 2 : 1)); autoSound me = Sound_createSimple (1, numberOfSamples / sampleRate, sampleRate); // STEREO BUG Melder_assert (my nx == numberOfSamples); /* * Open phase 2. * This starts recording now. */ if (inputUsesPortAudio) { streamParameters. suggestedLatency = Pa_GetDeviceInfo (inputSource - 1) -> defaultLowInputLatency; #if defined (macintosh) PaMacCoreStreamInfo macCoreStreamInfo = { 0 }; macCoreStreamInfo. size = sizeof (PaMacCoreStreamInfo); macCoreStreamInfo. hostApiType = paCoreAudio; macCoreStreamInfo. version = 0x01; macCoreStreamInfo. flags = paMacCoreChangeDeviceParameters | paMacCoreFailIfConversionRequired; streamParameters. hostApiSpecificStreamInfo = & macCoreStreamInfo; #endif info. numberOfSamples = numberOfSamples; info. numberOfSamplesRead = 0; info. buffer = buffer.peek(); PaError err = Pa_OpenStream (& portaudioStream, & streamParameters, NULL, sampleRate, 0, paNoFlag, portaudioStreamCallback, (void *) & info); if (err) Melder_throw (U"open ", Melder_peek8to32 (Pa_GetErrorText (err))); Pa_StartStream (portaudioStream); if (err) Melder_throw (U"start ", Melder_peek8to32 (Pa_GetErrorText (err))); } else { #if defined (macintosh) #elif defined (_WIN32) waveFormat. cbSize = 0; err = waveInOpen (& hWaveIn, WAVE_MAPPER, & waveFormat, 0, 0, CALLBACK_NULL); if (err != MMSYSERR_NOERROR) Melder_throw (U"Error ", err, U" while opening."); #endif } for (i = 1; i <= numberOfSamples; i ++) trace (U"Started ", buffer [i]); /* Read the sound into the buffer. */ if (inputUsesPortAudio) { // The callback will do this. Just wait. while (/*getNumberOfSamplesRead (& info)*/ info. numberOfSamplesRead < numberOfSamples) { //Pa_Sleep (1); //Melder_casual ("filled %ld/%ld", getNumberOfSamplesRead (& info), numberOfSamples); } for (i = 1; i <= numberOfSamples; i ++) trace (U"Recorded ", buffer [i]); } else { #if defined (macintosh) #elif defined (_WIN32) waveHeader. dwFlags = 0; waveHeader. lpData = (char *) & buffer [1]; waveHeader. dwBufferLength = numberOfSamples * 2; waveHeader. dwLoops = 0; waveHeader. lpNext = NULL; waveHeader. reserved = 0; err = waveInPrepareHeader (hWaveIn, & waveHeader, sizeof (WAVEHDR)); if (err != MMSYSERR_NOERROR) Melder_throw (U"Error ", err, U" while preparing header."); err = waveInAddBuffer (hWaveIn, & waveHeader, sizeof (WAVEHDR)); if (err != MMSYSERR_NOERROR) Melder_throw (U"Error ", err, U" while listening."); err = waveInStart (hWaveIn); if (err != MMSYSERR_NOERROR) Melder_throw (U"Error ", err, U" while starting."); while (! (waveHeader. dwFlags & WHDR_DONE)) { Pa_Sleep (1); } err = waveInUnprepareHeader (hWaveIn, & waveHeader, sizeof (WAVEHDR)); if (err != MMSYSERR_NOERROR) Melder_throw (U"Error ", err, U" while unpreparing header."); #else if (mulaw) read (fd, (char *) & buffer [1], numberOfSamples); else { long bytesLeft = 2 * numberOfSamples, dbytes, bytesRead = 0; while (bytesLeft) { //Melder_casual ("Reading %ld bytes", bytesLeft > 4000 ? 4000 : bytesLeft); dbytes = read (fd, & ((char *) buffer.peek()) [2 + bytesRead], bytesLeft > 4000 ? 4000 : bytesLeft); //Melder_casual("Read %ld bytes", dbytes); if (dbytes <= 0) break; bytesLeft -= dbytes; bytesRead += dbytes; }; } #endif } /* Copy the buffered data to the sound object, and discard the buffer. */ if (fakeMonoByStereo) for (i = 1; i <= numberOfSamples; i ++) my z [1] [i] = ((long) buffer [i + i - 1] + buffer [i + i]) * (1.0 / 65536); else if (mulaw) for (i = 1; i <= numberOfSamples; i ++) my z [1] [i] = ulaw2linear [((unsigned char *) buffer.peek()) [i]] * (1.0 / 32768); else if (can16bit) for (i = 1; i <= numberOfSamples; i ++) my z [1] [i] = buffer [i] * (1.0 / 32768); else for (i = 1; i <= numberOfSamples; i ++) my z [1] [i] = ((int) ((unsigned char *) buffer.peek()) [i + 1] - 128) * (1.0 / 128); /* Close the audio device. */ if (inputUsesPortAudio) { Pa_StopStream (portaudioStream); Pa_CloseStream (portaudioStream); } else { #if defined (macintosh) #elif defined (_WIN32) err = waveInClose (hWaveIn); if (err != MMSYSERR_NOERROR) Melder_throw (U"Error ", err, U" while closing."); #else close (fd); #endif } /* Hand the resulting sound to the caller. */ return me; } catch (MelderError) { if (inputUsesPortAudio) { if (portaudioStream) Pa_StopStream (portaudioStream); if (portaudioStream) Pa_CloseStream (portaudioStream); } else { #if defined (macintosh) #elif defined (_WIN32) if (hWaveIn != 0) waveInClose (hWaveIn); #else if (fd_mixer != -1) close (fd_mixer); if (fd != -1) close (fd); #endif } Melder_throw (U"Sound not recorded."); } } /********** PLAYING A SOUND **********/ static struct SoundPlay { long numberOfSamples, i1, i2, silenceBefore, silenceAfter; double tmin, tmax, dt, t1; int (*callback) (void *closure, int phase, double tmin, double tmax, double t); void *closure; short *buffer; } thePlayingSound; static bool melderPlayCallback (void *closure, long samplesPlayed) { struct SoundPlay *me = (struct SoundPlay *) closure; int phase = 2; double t = samplesPlayed <= my silenceBefore ? my tmin : samplesPlayed >= my silenceBefore + my numberOfSamples ? my tmax : my t1 + (my i1 - 1.5 + samplesPlayed - my silenceBefore) * my dt; if (! MelderAudio_isPlaying) { NUMvector_free (my buffer, 1), my buffer = NULL; phase = 3; } if (my callback) return my callback (my closure, phase, my tmin, my tmax, t); return true; } void Sound_playPart (Sound me, double tmin, double tmax, int (*callback) (void *closure, int phase, double tmin, double tmax, double t), void *closure) { try { long ifsamp = lround (1.0 / my dx), bestSampleRate = MelderAudio_getOutputBestSampleRate (ifsamp); if (ifsamp == bestSampleRate) { struct SoundPlay *thee = (struct SoundPlay *) & thePlayingSound; double *fromLeft = my z [1], *fromRight = my ny > 1 ? my z [2] : NULL; MelderAudio_stopPlaying (MelderAudio_IMPLICIT); long i1, i2; if ((thy numberOfSamples = Matrix_getWindowSamplesX (me, tmin, tmax, & i1, & i2)) < 1) return; thy tmin = tmin; thy tmax = tmax; thy dt = my dx; thy t1 = my x1; thy callback = callback; thy closure = closure; thy silenceBefore = (long) (ifsamp * MelderAudio_getOutputSilenceBefore ()); thy silenceAfter = (long) (ifsamp * MelderAudio_getOutputSilenceAfter ()); int numberOfChannels = my ny; NUMvector_free (thy buffer, 1); // just in case thy buffer = NUMvector (1, (i2 - i1 + 1 + thy silenceBefore + thy silenceAfter) * numberOfChannels); thy i1 = i1; thy i2 = i2; short *to = thy buffer + thy silenceBefore * numberOfChannels; if (numberOfChannels > 2) { for (long i = i1; i <= i2; i ++) { for (long chan = 1; chan <= my ny; chan ++) { long value = (long) round (my z [chan] [i] * 32768.0); * ++ to = value < -32768 ? -32768 : value > 32767 ? 32767 : value; } } } else if (numberOfChannels == 2) { for (long i = i1; i <= i2; i ++) { long valueLeft = (long) round (fromLeft [i] * 32768.0); * ++ to = valueLeft < -32768 ? -32768 : valueLeft > 32767 ? 32767 : valueLeft; long valueRight = (long) round (fromRight [i] * 32768.0); * ++ to = valueRight < -32768 ? -32768 : valueRight > 32767 ? 32767 : valueRight; } } else { for (long i = i1; i <= i2; i ++) { long value = (long) round (fromLeft [i] * 32768.0); * ++ to = value < -32768 ? -32768 : value > 32767 ? 32767 : value; } } if (thy callback) thy callback (thy closure, 1, tmin, tmax, tmin); MelderAudio_play16 (thy buffer + 1, ifsamp, thy silenceBefore + thy numberOfSamples + thy silenceAfter, numberOfChannels, melderPlayCallback, thee); } else { autoSound resampled = Sound_resample (me, bestSampleRate, 1); Sound_playPart (resampled.peek(), tmin, tmax, callback, closure); // recursively } } catch (MelderError) { Melder_throw (me, U": not played."); } } void Sound_play (Sound me, int (*playCallback) (void *playClosure, int phase, double tmin, double tmax, double t), void *playClosure) { Sound_playPart (me, my xmin, my xmax, playCallback, playClosure); } /* End of file Sound_audio.cpp */ praat-6.0.04/fon/Sound_enhance.cpp000066400000000000000000000121421261542461700167570ustar00rootroot00000000000000/* Sound_enhance.cpp * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2004/11/22 simplified Sound_to_Spectrum () * pb 2007/01/28 made compatible with stereo sounds (by rejecting them) * pb 2007/07/22 renamed the overlap-add method in such a way that it does not sound like a trademark for diphone concatenation * pb 2008/01/19 double * pb 2011/06/07 C++ */ #include "Manipulation.h" #include "Sound_to_Pitch.h" #include "Pitch_to_PitchTier.h" #include "Pitch_to_PointProcess.h" #include "Sound_and_Spectrum.h" autoSound Sound_lengthen_overlapAdd (Sound me, double fmin, double fmax, double factor) { try { if (my ny > 1) Melder_throw (U"Overlap-add works only on mono sounds."); autoSound sound = Data_copy (me); Vector_subtractMean (sound.peek()); autoPitch pitch = Sound_to_Pitch (sound.peek(), 0.8 / fmin, fmin, fmax); autoPointProcess pulses = Sound_Pitch_to_PointProcess_cc (sound.peek(), pitch.peek()); autoPitchTier pitchTier = Pitch_to_PitchTier (pitch.peek()); autoDurationTier duration = DurationTier_create (my xmin, my xmax); RealTier_addPoint (duration.peek(), 0.5 * (my xmin + my xmax), factor); autoSound thee = Sound_Point_Pitch_Duration_to_Sound (sound.peek(), pulses.peek(), pitchTier.peek(), duration.peek(), 1.5 / fmin); return thee; } catch (MelderError) { Melder_throw (me, U": not lengthened."); } } autoSound Sound_deepenBandModulation (Sound me, double enhancement_dB, double flow, double fhigh, double slowModulation, double fastModulation, double bandSmoothing) { try { autoSound thee = Data_copy (me); double maximumFactor = pow (10, enhancement_dB / 20), alpha = sqrt (log (2.0)); double alphaslow = alpha / slowModulation, alphafast = alpha / fastModulation; for (long channel = 1; channel <= my ny; channel ++) { autoSound channelSound = Sound_extractChannel (me, channel); autoSpectrum orgspec = Sound_to_Spectrum (channelSound.peek(), true); /* * Keep the part of the sound that is outside the filter bank. */ autoSpectrum spec = Data_copy (orgspec.peek()); Spectrum_stopHannBand (spec.peek(), flow, fhigh, bandSmoothing); autoSound filtered = Spectrum_to_Sound (spec.peek()); long n = thy nx; double *amp = thy z [channel]; for (long i = 1; i <= n; i ++) amp [i] = filtered -> z [1] [i]; autoMelderProgress progress (U"Deepen band modulation..."); double fmin = flow; while (fmin < fhigh) { /* * Take a one-bark frequency band. */ double fmid_bark = NUMhertzToBark (fmin) + 0.5, ceiling; double fmax = NUMbarkToHertz (NUMhertzToBark (fmin) + 1); if (fmax > fhigh) fmax = fhigh; Melder_progress (fmin / fhigh, U"Band: ", Melder_fixed (fmin, 0), U" ... ", Melder_fixed (fmax, 0), U" Hz"); NUMmatrix_copyElements (orgspec -> z, spec -> z, 1, 2, 1, spec -> nx); Spectrum_passHannBand (spec.peek(), fmin, fmax, bandSmoothing); autoSound band = Spectrum_to_Sound (spec.peek()); /* * Compute a relative intensity contour. */ autoSound intensity = Data_copy (band.peek()); n = intensity -> nx; amp = intensity -> z [1]; for (long i = 1; i <= n; i ++) amp [i] = 10 * log10 (amp [i] * amp [i] + 1e-6); autoSpectrum intensityFilter = Sound_to_Spectrum (intensity.peek(), true); n = intensityFilter -> nx; for (long i = 1; i <= n; i ++) { double frequency = intensityFilter -> x1 + (i - 1) * intensityFilter -> dx; double slow = alphaslow * frequency, fast = alphafast * frequency; double factor = exp (- fast * fast) - exp (- slow * slow); intensityFilter -> z [1] [i] *= factor; intensityFilter -> z [2] [i] *= factor; } intensity = Spectrum_to_Sound (intensityFilter.peek()); n = intensity -> nx; amp = intensity -> z [1]; for (long i = 1; i <= n; i ++) amp [i] = pow (10, amp [i] / 2); /* * Clip to maximum enhancement. */ ceiling = 1 + (maximumFactor - 1.0) * (0.5 - 0.5 * cos (NUMpi * fmid_bark / 13)); for (long i = 1; i <= n; i ++) amp [i] = 1 / (1 / amp [i] + 1 / ceiling); n = thy nx; amp = thy z [channel]; for (long i = 1; i <= n; i ++) amp [i] += band -> z [1] [i] * intensity -> z [1] [i]; fmin = fmax; } } Vector_scale (thee.peek(), 0.99); /* Truncate. */ thy xmin = my xmin; thy xmax = my xmax; thy nx = my nx; thy x1 = my x1; return thee; } catch (MelderError) { Melder_throw (me, U": band modulation not deepened."); } } /* End of file Sound_enhance.cpp */ praat-6.0.04/fon/Sound_enums.h000066400000000000000000000043741261542461700161620ustar00rootroot00000000000000/* Sound_enums.h * * Copyright (C) 1992-2010,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ enums_begin (kSound_windowShape, 0) enums_add (kSound_windowShape, 0, RECTANGULAR, U"rectangular") enums_add (kSound_windowShape, 1, TRIANGULAR, U"triangular") enums_add (kSound_windowShape, 2, PARABOLIC, U"parabolic") enums_add (kSound_windowShape, 3, HANNING, U"Hanning") enums_add (kSound_windowShape, 4, HAMMING, U"Hamming") enums_add (kSound_windowShape, 5, GAUSSIAN_1, U"Gaussian1") enums_add (kSound_windowShape, 6, GAUSSIAN_2, U"Gaussian2") enums_add (kSound_windowShape, 7, GAUSSIAN_3, U"Gaussian3") enums_add (kSound_windowShape, 8, GAUSSIAN_4, U"Gaussian4") enums_add (kSound_windowShape, 9, GAUSSIAN_5, U"Gaussian5") enums_add (kSound_windowShape, 10, KAISER_1, U"Kaiser1") enums_add (kSound_windowShape, 11, KAISER_2, U"Kaiser2") enums_end (kSound_windowShape, 11, RECTANGULAR) enums_begin (kSounds_convolve_scaling, 1) enums_add (kSounds_convolve_scaling, 1, INTEGRAL, U"integral") enums_add (kSounds_convolve_scaling, 2, SUM, U"sum") enums_add (kSounds_convolve_scaling, 3, NORMALIZE, U"normalize") enums_add (kSounds_convolve_scaling, 4, PEAK_099, U"peak 0.99") enums_end (kSounds_convolve_scaling, 4, PEAK_099) enums_begin (kSounds_convolve_signalOutsideTimeDomain, 1) enums_add (kSounds_convolve_signalOutsideTimeDomain, 1, ZERO, U"zero") enums_add (kSounds_convolve_signalOutsideTimeDomain, 2, SIMILAR, U"similar") //enums_add (kSounds_convolve_signalOutsideTimeDomain, 3, PERIODIC, U"periodic") enums_end (kSounds_convolve_signalOutsideTimeDomain, 2, ZERO) /* End of file Sound_enums.h */ praat-6.0.04/fon/Sound_files.cpp000066400000000000000000000323601261542461700164640ustar00rootroot00000000000000/* Sound_files.cpp * * Copyright (C) 1992-2011,2012,2014,2015 Paul Boersma & David Weenink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2003/09/12 MelderFile_checkSoundFile * pb 2004/10/17 test for NULL file pointer when closing in Sound_read(2)FromSoundFile * pb 2005/06/17 Mac headers * pb 2006/01/05 movies for Mac * pb 2006/05/29 QuickTime inclusion made optional * pb 2006/10/28 erased MacOS 9 stuff * pb 2006/12/30 stereo * pb 2006/01/01 more stereo * pb 2007/01/28 removed a warning * pb 2007/01/28 made readFromMovieFile compatible with stereo * pb 2007/03/17 resistant against conflicting declarations of Collection * pb 2007/05/08 removed warning about stereo sounds * pb 2007/10/05 removed FSSpec * pb 2007/10/05 made Sound_readFromMacSoundFile compatible with sample rates between 32768 and 65535 Hz * pb 2008/01/19 double * pb 2009/09/21 made stereo movies readable * pb 2010/12/27 support for multiple channels (i.e. more than two) * pb 2011/06/07 C++ * pb 2012/04/29 removed Sound Manager stuff * pb 2012/04/29 removed QuickTime */ /* static void Sound_ulawDecode (Sound me) { double mu = 100, lnu1 = log (1 + mu); for (long i = 1; i <= my nx; i ++) { double zabs = (exp (fabs (my z [1] [i]) * lnu1) - 1.0) / mu; my z [1] [i] = my z [1] [i] < 0 ? -zabs : zabs; } } static void Sound_alawDecode (Sound me) { double a = 87.6, lna1 = 1.0 + log (a); for (long i = 1; i <= my nx; i ++) { double zabs = fabs (my z [1] [i]); if (zabs <= 1.0 / lna1) { my z [1] [i] *= lna1 / a; } else { double t = exp (lna1 * zabs - 1.0) / a; my z [1] [i] = my z [1] [i] > 0 ? t : - t; } } } */ #include #include "Sound.h" autoSound Sound_readFromSoundFile (MelderFile file) { try { autoMelderFile mfile = MelderFile_open (file); int numberOfChannels, encoding; double sampleRate; long startOfData; int32 numberOfSamples; int fileType = MelderFile_checkSoundFile (file, & numberOfChannels, & encoding, & sampleRate, & startOfData, & numberOfSamples); if (fileType == 0) Melder_throw (U"Not an audio file."); if (fseek (file -> filePointer, startOfData, SEEK_SET) == EOF) // start from beginning of Data Chunk Melder_throw (U"No data in audio file."); if (numberOfSamples < 1) Melder_throw (U"Audio file contains 0 samples."); autoSound me = Sound_createSimple (numberOfChannels, numberOfSamples / sampleRate, sampleRate); if (encoding == Melder_SHORTEN || encoding == Melder_POLYPHONE) Melder_throw (U"Cannot unshorten. Write to paul.boersma@uva.nl for more information."); Melder_readAudioToFloat (file -> filePointer, numberOfChannels, encoding, my z, numberOfSamples); mfile.close (); return me; } catch (MelderError) { Melder_throw (U"Sound not read from sound file ", file, U"."); } } autoSound Sound_readFromSesamFile (MelderFile file) { try { autofile f = Melder_fopen (file, "rb"); int32_t header [1 + 128]; for (long i = 1; i <= 128; i ++) header [i] = bingeti4LE (f); /* * Try SESAM header. */ double samplingFrequency = header [126]; // converting up (from 32 to 54 bits) int32_t numberOfSamples = header [127]; if (samplingFrequency == 0.0 || numberOfSamples == 0) { /* * Try LVS header. */ samplingFrequency = header [62]; numberOfSamples = (header [6] << 8) - header [68]; } if (numberOfSamples < 1 || numberOfSamples > 1000000000 || samplingFrequency < 10.0 || samplingFrequency > 100000000.0) Melder_throw (U"Not a correct SESAM or LVS file."); autoSound me = Sound_createSimple (1, numberOfSamples / samplingFrequency, samplingFrequency); for (int32_t i = 1; i <= numberOfSamples; i ++) { my z [1] [i] = (double) bingeti2LE (f) * (1.0 / 2048); // 12 bits } f.close (file); return me; } catch (MelderError) { Melder_throw (U"Sound not read from Sesam file ", file, U"."); } } autoSound Sound_readFromBellLabsFile (MelderFile file) { try { /* * Check existence and permissions of file. */ autofile f = Melder_fopen (file, "rb"); /* * Check identity of file: first line is "SIG", second line contains a number. */ char tag [200]; if (fread (tag, 1, 16, f) < 16 || ! strnequ (tag, "SIG\n", 4)) Melder_throw (U"Not a Bell-Labs sound file."); char *endOfTag = strchr (tag + 4, '\n'); if (endOfTag == NULL) Melder_throw (U"Second line missing or too long."); unsigned long tagLength = (endOfTag - tag) + 1; // probably 12 unsigned long headerLength = atol (tag + 4); if (headerLength <= 0) Melder_throw (U"Wrong header-length info."); /* * Read data from header. * Use defaults if necessary. */ autostring8 lines = Melder_calloc (char, headerLength + 1); if (fread (lines.peek(), 1, headerLength, f) < headerLength) Melder_throw (U"Header too short."); unsigned long numberOfSamples = 0; char *psamples = & lines [-1]; while ((psamples = strstr (psamples + 1, "samples ")) != NULL) // take last occurrence numberOfSamples = atol (psamples + 8); if (numberOfSamples < 1) { /* Use file length. */ fseek (f, 0, SEEK_END); /* Position file pointer at end of file. */ numberOfSamples = (ftell (f) - tagLength - headerLength) / 2; } if (numberOfSamples < 1) Melder_throw (U"No samples found."); double samplingFrequency = 0.0; char *pfrequency = & lines [-1]; while ((pfrequency = strstr (pfrequency + 1, "frequency ")) != NULL) // take last occurrence samplingFrequency = atof (pfrequency + 10); if (samplingFrequency <= 0.0) samplingFrequency = 16000.0; /* * Create sound. */ autoSound me = Sound_createSimple (1, numberOfSamples / samplingFrequency, samplingFrequency); /* * Read samples. */ fseek (f, tagLength + headerLength, SEEK_SET); for (unsigned long i = 1; i <= numberOfSamples; i ++) my z [1] [i] = (double) bingeti2 (f) * (1.0 / 32768); // 16-bits big-endian f.close (file); return me; } catch (MelderError) { Melder_throw (U"Sound not read from Bell Labs sound file ", file, U"."); } } static void readError () { Melder_throw (U"Error reading bytes from file."); } autoSound Sound_readFromKayFile (MelderFile file) { try { autofile f = Melder_fopen (file, "rb"); /* Read header of KAY file: 12 bytes. */ char data [100]; if (fread (data, 1, 12, f) < 12) readError (); if (! strnequ (data, "FORMDS16", 8)) Melder_throw (U"Not a KAY DS-16 file."); /* HEDR or HDR8 chunk */ if (fread (data, 1, 4, f) < 4) readError (); if (! strnequ (data, "HEDR", 4) && ! strnequ (data, "HDR8", 4)) Melder_throw (U"Missing HEDR or HDR8 chunk. Please report to paul.boersma@uva.nl."); uint32_t chunkSize = bingetu4LE (f); if (chunkSize & 1) ++ chunkSize; if (chunkSize != 32 && chunkSize != 44) Melder_throw (U"Unknown chunk size %ld. Please report to paul.boersma@uva.nl.", chunkSize); if (fread (data, 1, 20, f) < 20) readError (); double samplingFrequency = bingetu4LE (f); // converting up (from 32 to 53 bits) uint32_t numberOfSamples = bingetu4LE (f); if (samplingFrequency <= 0 || samplingFrequency > 1e7 || numberOfSamples >= 1000000000) Melder_throw (U"Not a correct Kay file."); int16_t tmp1 = bingeti2LE (f); int16_t tmp2 = bingeti2LE (f); long numberOfChannels = tmp1 == -1 || tmp2 == -1 ? 1 : 2; if (chunkSize == 44) if (fread (data, 1, 12, f) < 12) readError (); /* SD chunk */ if (fread (data, 1, 4, f) < 4) readError (); while (! strnequ (data, "SDA_", 4) && ! strnequ (data, "SD_B", 4)) { if (feof ((FILE *) f)) Melder_throw (U"Missing or unreadable SD chunk. Please report to paul.boersma@uva.nl."); chunkSize = bingetu4LE (f); if (chunkSize & 1) ++ chunkSize; if (fread (data, 1, chunkSize, f) < chunkSize) readError (); if (fread (data, 1, 4, f) < 4) readError (); } chunkSize = bingetu4LE (f); if (chunkSize != numberOfSamples * 2) Melder_throw (U"Incomplete SD chunk. Please report to paul.boersma@uva.nl."); autoSound me = Sound_createSimple (numberOfChannels, numberOfSamples / samplingFrequency, samplingFrequency); for (long ichan = 1; ichan <= numberOfChannels; ichan ++) { for (unsigned long i = 1; i <= numberOfSamples; i ++) { my z [ichan] [i] = (double) bingeti2LE (f) / 32768.0; } } f.close (file); return me; } catch (MelderError) { Melder_throw (U"Sound not read from Kay file ", file, U"."); } } autoSound Sound_readFromRawAlawFile (MelderFile file) { try { double sampleRate = 8000.0; autofile f = Melder_fopen (file, "rb"); fseek (f, 0, SEEK_END); long numberOfSamples = ftell (f); rewind (f); autoSound me = Sound_createSimple (1, numberOfSamples / sampleRate, sampleRate); Melder_readAudioToFloat (f, 1, Melder_ALAW, my z, numberOfSamples); f.close (file); return me; } catch (MelderError) { Melder_throw (U"Sound not read from raw A-law file ", file, U"."); } } void Sound_writeToAudioFile (Sound me, MelderFile file, int audioFileType, int numberOfBitsPerSamplePoint) { try { autoMelderFile mfile = MelderFile_create (file); MelderFile_writeAudioFileHeader (file, audioFileType, lround (1.0 / my dx), my nx, my ny, numberOfBitsPerSamplePoint); MelderFile_writeFloatToAudio (file, my ny, Melder_defaultAudioFileEncoding (audioFileType, numberOfBitsPerSamplePoint), my z, my nx, true); MelderFile_writeAudioFileTrailer (file, audioFileType, lround (1.0 / my dx), my nx, my ny, numberOfBitsPerSamplePoint); mfile.close (); } catch (MelderError) { Melder_throw (me, U": not written to 16-bit sound file ", file, U"."); } } void Sound_writeToSesamFile (Sound me, MelderFile file) { try { autofile f = Melder_fopen (file, "wb"); long header [1 + 128], tail; for (long i = 1; i <= 128; i ++) header [i] = 0; /* ILS header. */ header [6] = ((my nx - 1) >> 8) + 1; // number of disk blocks header [64] = 32149; // ILS magic /* LVS header. */ header [62] = lround (1 / my dx); // sampling frequency, rounded to n Hz header [63] = -32000; // magic: "sampled signal" header [66] = 2047; // maximum absolute value: 12 bits header [67] = 2047; // LVS magic header [68] = my nx % 256; // number of samples in last block header [69] = 1; // ? /* Sesam header. */ header [126] = lround (1 / my dx); // sampling frequency, rounded to n Hz header [127] = my nx; // number of samples for (long i = 1; i <= 128; i ++) binputi4LE (header [i], f); for (long i = 1; i <= my nx; i ++) binputi2LE (lround (my z [1] [i] * 2048), f); tail = 256 - my nx % 256; if (tail == 256) tail = 0; for (long i = 1; i <= tail; i ++) binputi2LE (0, f); // pad last block with zeroes f.close (file); } catch (MelderError) { Melder_throw (me, U": not written to Sesam file ", file, U"."); } } void Sound_writeToKayFile (Sound me, MelderFile file) { try { autoMelderFile mfile = MelderFile_create (file); /* Form Chunk: contains all other chunks. */ fwrite ("FORMDS16", 1, 8, file -> filePointer); binputi4LE (48 + my nx * 2, file -> filePointer); // size of Form Chunk fwrite ("HEDR", 1, 4, file -> filePointer); binputi4LE (32, file -> filePointer); char date [100]; time_t today = time (NULL); strcpy (date, ctime (& today)); fwrite (date+4, 1, 20, file -> filePointer); // skip weekday binputi4LE (lround (1 / my dx), file -> filePointer); // sampling frequency binputi4LE (my nx, file -> filePointer); // number of samples int maximumA = 0; for (long i = 1; i <= my nx; i ++) { long value = lround (my z [1] [i] * 32768); if (value < - maximumA) maximumA = - value; if (value > maximumA) maximumA = value; } binputi2LE (maximumA, file -> filePointer); // absolute maximum window A if (my ny == 1) { binputi2LE (-1, file -> filePointer); } else { int maximumB = 0; for (long i = 1; i <= my nx; i ++) { long value = lround (my z [2] [i] * 32768); if (value < - maximumB) maximumB = - value; if (value > maximumB) maximumB = value; } binputi2LE (maximumB, file -> filePointer); // absolute maximum window B } fwrite ("SDA_", 1, 4, file -> filePointer); binputi4LE (my nx * 2, file -> filePointer); // chunk size MelderFile_writeFloatToAudio (file, 1, Melder_LINEAR_16_LITTLE_ENDIAN, my z, my nx, true); if (my ny > 1) MelderFile_writeFloatToAudio (file, 1, Melder_LINEAR_16_LITTLE_ENDIAN, my z + 1, my nx, true); mfile.close (); } catch (MelderError) { Melder_throw (me, U": not written to Kay sound file ", file, U"."); } } void Sound_writeToRawSoundFile (Sound me, MelderFile file, int encoding) { try { autoMelderFile mfile = MelderFile_create (file); MelderFile_writeFloatToAudio (file, my ny, encoding, my z, my nx, true); mfile.close (); } catch (MelderError) { Melder_throw (me, U": not written to raw sound file ", file, U"."); } } /* End of file Sound_files.cpp */ praat-6.0.04/fon/Sound_to_Cochleagram.cpp000066400000000000000000000207171261542461700202740ustar00rootroot00000000000000/* Sound_to_Cochleagram.cpp * * Copyright (C) 1992-2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 1997/09/03 BUG: exponential decay only for iframe > 1 * pb 1998/01/05 forward masking time * pb 2002/07/16 GPL * pb 2002/08/26 correct handling of zero forwardMaskingTime (bug found by djmw) * pb 2004/11/22 simplified Sound_to_Spectrum () * pb 2006/12/30 new Sound_create API * pb 2007/01/28 made compatible with stereo sounds * pb 2008/01/19 double * pb 2011/06/08 C++ */ #include "Sound_to_Cochleagram.h" #include "Sound_and_Spectrum.h" #include "Spectrum_to_Excitation.h" autoCochleagram Sound_to_Cochleagram (Sound me, double dt, double df, double dt_window, double forwardMaskingTime) { try { double duration = my nx * my dx; long nFrames = 1 + (long) floor ((duration - dt_window) / dt); long nsamp_window = (long) floor (dt_window / my dx), halfnsamp_window = nsamp_window / 2 - 1; long nf = lround (25.6 / df); double dampingFactor = forwardMaskingTime > 0.0 ? exp (- dt / forwardMaskingTime) : 0.0; // default 30 ms double integrationCorrection = 1.0 - dampingFactor; nsamp_window = halfnsamp_window * 2; if (nFrames < 2) return NULL; double t1 = my x1 + 0.5 * (duration - my dx - (nFrames - 1) * dt); // centre of first frame autoCochleagram thee = Cochleagram_create (my xmin, my xmax, nFrames, dt, t1, df, nf); autoSound window = Sound_createSimple (1, nsamp_window * my dx, 1.0 / my dx); for (long iframe = 1; iframe <= nFrames; iframe ++) { double t = Sampled_indexToX (thee.peek(), iframe); long leftSample = Sampled_xToLowIndex (me, t); long rightSample = leftSample + 1; long startSample = rightSample - halfnsamp_window; long endSample = rightSample + halfnsamp_window; if (startSample < 1) { Melder_casual (U"Start sample too small: ", startSample, U" instead of 1."); startSample = 1; } if (endSample > my nx) { Melder_casual (U"End sample too small: ", endSample, U" instead of ", my nx, U"."); endSample = my nx; } /* Copy a window to a frame. */ for (long i = 1; i <= nsamp_window; i ++) window -> z [1] [i] = ( my ny == 1 ? my z[1][i+startSample-1] : 0.5 * (my z[1][i+startSample-1] + my z[2][i+startSample-1]) ) * (0.5 - 0.5 * cos (2 * NUMpi * i / (nsamp_window + 1))); autoSpectrum spec = Sound_to_Spectrum (window.peek(), true); autoExcitation excitation = Spectrum_to_Excitation (spec.peek(), df); for (long ifreq = 1; ifreq <= nf; ifreq ++) thy z [ifreq] [iframe] = excitation -> z [1] [ifreq] + ( iframe > 1 ? dampingFactor * thy z [ifreq] [iframe - 1] : 0 ); } for (long iframe = 1; iframe <= nFrames; iframe ++) for (long ifreq = 1; ifreq <= nf; ifreq ++) thy z [ifreq] [iframe] *= integrationCorrection; return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Cochleagram."); } } static autoSound createGammatone (double midFrequency_Hertz, double samplingFrequency) { double lengthOfGammatone_seconds = 50.0 / midFrequency_Hertz; // 50 periods long lengthOfGammatone_samples; /* EdB's alfa1: */ double latency = 1.95e-3 * pow (midFrequency_Hertz / 1000, -0.725) + 0.6e-3; /* EdB's beta: */ double decayTime = 1e-3 * pow (midFrequency_Hertz / 1000, -0.663); /* EdB's omega: */ double midFrequency_radPerSecond = 2 * NUMpi * midFrequency_Hertz; autoSound gammatone = Sound_createSimple (1, lengthOfGammatone_seconds, samplingFrequency); lengthOfGammatone_samples = gammatone -> nx; for (long itime = 1; itime <= lengthOfGammatone_samples; itime ++) { double time_seconds = (itime - 0.5) / samplingFrequency; double timeAfterLatency = time_seconds - latency; double x = timeAfterLatency / decayTime; if (time_seconds > latency) gammatone -> z [1] [itime] = x * x * x * exp (- x) * cos (midFrequency_radPerSecond * timeAfterLatency); } return gammatone; } autoCochleagram Sound_to_Cochleagram_edb (Sound me, double dtime, double dfreq, int hasSynapse, double replenishmentRate, double lossRate, double returnRate, double reprocessingRate) { try { double duration_seconds = my xmax; if (dtime < my dx) dtime = my dx; long ntime = lround (duration_seconds / dtime); if (ntime < 2) return NULL; long nfreq = lround (25.6 / dfreq); // 25.6 Bark = highest frequency autoCochleagram thee = Cochleagram_create (my xmin, my xmax, ntime, dtime, 0.5 * dtime, dfreq, nfreq); /* Stages 1 and 2: outer- and middle-ear filtering. */ /* From acoustic sound to oval window. */ for (long ifreq = 1; ifreq <= nfreq; ifreq ++) { double *response = thy z [ifreq]; /* Stage 3: basilar membrane filtering by gammatones. */ /* From oval window to basilar membrane response. */ double midFrequency_Bark = (ifreq - 0.5) * dfreq; double midFrequency_Hertz = Excitation_barkToHertz (midFrequency_Bark); autoSound gammatone = createGammatone (midFrequency_Hertz, 1 / my dx); autoSound basil = Sounds_convolve (me, gammatone.peek(), kSounds_convolve_scaling_SUM, kSounds_convolve_signalOutsideTimeDomain_ZERO); /* Stage 4: detection = rectify + integrate + low-pass 500 Hz. */ /* From basilar membrane response to firing rate. */ if (hasSynapse) { double dt = my dx; double M = 1; /* Maximum free transmitter. */ double A = 5, B = 300, g = 2000; /* Determine permeability. */ double y = replenishmentRate; /* Meddis: 5.05 */ double l = lossRate, r = returnRate; /* Meddis: 2500, 6580 */ double x = reprocessingRate; /* Meddis: 66.31 */ double h = 50000; /* Convert cleft contents to firing rate. */ double gdt = 1 - exp (- g * dt), ydt = 1 - exp (- y * dt), ldt = (1 - exp (- (l + r) * dt)) * l / (l + r), rdt = (1 - exp (- (l + r) * dt)) * r / (l + r), xdt = 1 - exp (- x * dt); double kt = g * A / (A + B); /* Membrane permeability. */ double c = M * y * kt / (l * kt + y * (l + r)); /* Cleft contents. */ double q = c * (l + r) / kt; /* Free transmitter. */ double w = c * r / x; /* Reprocessing store. */ for (long itime = 1; itime <= basil -> nx; itime ++) { double splusA = basil -> z [1] [itime] * 10 + A; double replenish = M > q ? ydt * (M - q) : 0; double eject, loss, reuptake, reprocess; kt = splusA > 0 ? gdt * splusA / (splusA + B) : 0; eject = kt * q; loss = ldt * c; reuptake = rdt * c; reprocess = xdt * w; q = q + replenish - eject + reprocess; c = c + eject - loss - reuptake; w = w + reuptake - reprocess; basil -> z [1] [itime] = h * c; } } if (dtime == my dx) { for (long itime = 1; itime <= ntime; itime ++) response [itime] = basil -> z [1] [itime]; } else { double d = dtime / basil -> dx / 2; double factor = -6 / d / d; double area = d * sqrt (NUMpi / 6); double expmin6 = exp (-6), onebyoneminexpmin6 = 1 / (1 - expmin6); for (long itime = 1; itime <= ntime; itime ++) { double t1 = (itime - 1) * dtime, t2 = t1 + dtime, mean = 0; long i1, i2; long n = Matrix_getWindowSamplesX (basil.peek(), t1, t2, & i1, & i2); Melder_assert (n >= 1); if (n <= 2) { for (long isamp = i1; isamp <= i2; isamp ++) mean += basil -> z [1] [isamp]; mean /= n; } else { double mu = floor ((i1 + i2) / 2.0); long muint = (long) mu, dint = (long) d; for (long isamp = muint - dint; isamp <= muint + dint; isamp ++) { double y = 0; if (isamp < 1 || isamp > basil -> nx) Melder_casual (U"isamp ", isamp); else y = basil -> z [1] [isamp]; mean += y * onebyoneminexpmin6 * (exp (factor * (isamp - muint) * (isamp - muint)) - expmin6); } mean /= area; } response [itime] = mean; } } } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Cochleagram (edb)."); } } /* End of file Sound_to_Cochleagram.cpp */ praat-6.0.04/fon/Sound_to_Cochleagram.h000066400000000000000000000022241261542461700177320ustar00rootroot00000000000000/* Sound_to_Cochleagram.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Sound.h" #include "Cochleagram.h" autoCochleagram Sound_to_Cochleagram (Sound me, double dt, double df, double windowLength, double forwardMaskingTime); autoCochleagram Sound_to_Cochleagram_edb (Sound me, double dtime, double dfreq, int hasSynapse, double replenishmentRate, double lossRate, double returnRate, double reprocessingRate); /* End of file Sound_to_Cochleagram.h */ praat-6.0.04/fon/Sound_to_Formant.cpp000066400000000000000000000326071261542461700174760ustar00rootroot00000000000000/* Sound_to_Formant.cpp * * Copyright (C) 1992-2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2003/05/15 replaced memcof with NUMburg * pb 2003/09/18 default time step is 4 times oversampling * pb 2006/05/10 better handling of interruption in Sound_to_Formant * pb 2006/05/10 better handling of NULL from Polynomial_to_Roots * pb 2007/01/26 made compatible with stereo Sounds * pb 2007/03/30 changed float to double (against compiler warnings) * pb 2010/12/13 removed some style bugs * pb 2011/06/08 C++ */ #include "Sound_to_Formant.h" #include "NUM2.h" #include "Polynomial.h" static void burg (double sample [], long nsamp_window, double cof [], int nPoles, Formant_Frame frame, double nyquistFrequency, double safetyMargin) { double a0; NUMburg (sample, nsamp_window, cof, nPoles, & a0); /* * Convert LP coefficients to polynomial. */ autoPolynomial polynomial = Polynomial_create (-1, 1, nPoles); for (int i = 1; i <= nPoles; i ++) polynomial -> coefficients [i] = - cof [nPoles - i + 1]; polynomial -> coefficients [nPoles + 1] = 1.0; /* * Find the roots of the polynomial. */ autoRoots roots = Polynomial_to_Roots (polynomial.peek()); Roots_fixIntoUnitCircle (roots.peek()); Melder_assert (frame -> nFormants == 0 && frame -> formant == NULL); /* * First pass: count the formants. * The roots come in conjugate pairs, so we need only count those above the real axis. */ for (int i = roots -> min; i <= roots -> max; i ++) if (roots -> v [i]. im >= 0) { double f = fabs (atan2 (roots -> v [i].im, roots -> v [i].re)) * nyquistFrequency / NUMpi; if (f >= safetyMargin && f <= nyquistFrequency - safetyMargin) frame -> nFormants ++; } /* * Create space for formant data. */ if (frame -> nFormants > 0) frame -> formant = NUMvector (1, frame -> nFormants); /* * Second pass: fill in the formants. */ int iformant = 0; for (int i = roots -> min; i <= roots -> max; i ++) if (roots -> v [i]. im >= 0.0) { double f = fabs (atan2 (roots -> v [i].im, roots -> v [i].re)) * nyquistFrequency / NUMpi; if (f >= safetyMargin && f <= nyquistFrequency - safetyMargin) { Formant_Formant formant = & frame -> formant [++ iformant]; formant -> frequency = f; formant -> bandwidth = - log (roots -> v [i].re * roots -> v [i].re + roots -> v [i].im * roots -> v [i].im) * nyquistFrequency / NUMpi; } } Melder_assert (iformant == frame -> nFormants); // may fail if some frequency is NaN } static int findOneZero (int ijt, double vcx [], double a, double b, double *zero) { double x = 0.5 * (a + b), fa = 0.0, fb = 0.0, fx = 0.0; long k; for (k = ijt; k >= 0; k --) { fa = vcx [k] + a * fa; fb = vcx [k] + b * fb; } if (fa * fb >= 0.0) { // there should be a zero between a and b Melder_casual ( U"There is no zero between ,", Melder_single (a), U" and ", Melder_single (b), U".\n The function values are ", Melder_single (fa), U" and ", Melder_single (fb), U", respectively." ); return 0; } do { fx = 0.0; /*x = fa == fb ? 0.5 * (a + b) : a + fa * (a - b) / (fb - fa);*/ x = 0.5 * (a + b); // simple bisection for (k = ijt; k >= 0; k --) fx = vcx [k] + x * fx; if (fa * fx > 0.0) { a = x; fa = fx; } else { b = x; fb = fx; } } while (fabs (fx) > 1e-5); *zero = x; return 1; // OK } static int findNewZeroes (int ijt, double ppORIG [], int degree, double zeroes []) // In / out { static double cosa [7] [7] = { { 1, 0, 0, 0, 0, 0, 0 }, { 0, 2, 0, 0, 0, 0, 0 }, { -2, 0, 4, 0, 0, 0, 0 }, { 0, -6, 0, 8, 0, 0, 0 }, { 2, 0, -16, 0, 16, 0, 0 }, { 0, 10, 0, -40, 0, 32, 0 }, { -2, 0, 36, 0, -96, 0, 64 } }; double pp [33], newZeroes [33], px [33]; int pt, vt, i, half_degree = (degree + 1) / 2; for (vt = 0; vt <= half_degree; vt ++) pp [vt] = ppORIG [vt]; if (! (degree & 1)) for (vt = 1; vt <= half_degree; vt ++) pp [vt] -= pp [vt - 1]; for (i = 0; i <= half_degree; i ++) px [i] = cosa [half_degree] [i]; for (pt = half_degree - 1; pt >= 0; pt --) for (vt = 0; vt <= half_degree; vt ++) px [vt] += pp [half_degree - pt] * cosa [pt] [vt]; /* Fill an array with the new zeroes, which lie between the old zeroes. */ newZeroes [0] = 1.0; for (i = 1; i <= half_degree; i ++) { if (! findOneZero (ijt, px, zeroes [i - 1], zeroes [i], & newZeroes [i])) { Melder_casual ( U"Degree ", degree, U" not completed." ); return 0; } } newZeroes [half_degree + 1] = -1.0; /* Grow older. */ for (i = 0; i <= half_degree + 1; i ++) zeroes [i] = newZeroes [i]; return 1; } static int splitLevinson ( double xw [], long nx, // the windowed signal xw [1..nx] int ncof, // the coefficients cof [1..ncof] Formant_Frame frame, double nyquistFrequency) // put the results here { int result = 1; double rx [100], zeroes [33]; for (int i = 0; i <= 32; i ++) zeroes [i] = 0.0; /* Compute the autocorrelation of the windowed signal. */ for (int i = 0; i < ncof; i ++) { rx [i] = 0.0; for (int j = 1; j <= nx - i; j ++) rx [i] += xw [j] * xw [j + i]; } /* Normalize autocorrelation; (should we also divide by the autocorrelation of the window?). */ for (int i = 1; i < ncof; i ++) rx [i] /= rx [0]; rx [0] = 1.0; /* Compute zeroes. */ { double tau = 0.5 * rx [0]; double pnu [33], pk [33], pkz [33]; for (int i = 0; i <= 32; i ++) pkz [i] = pk [i] = 0.0; pkz [0] = 1.0; pk [0] = 1.0; pk [1] = 1.0; for (int degree = 1; degree < ncof; degree ++) { int t = degree / 2; double tauk = rx [0] + rx [degree], alfak; for (int it = 1; it <= t; it ++) tauk += pk [it] * ( 2 * it == degree ? rx [it] : rx [it] + rx [degree - it] ); alfak = tauk / tau; tau = tauk; pnu [0] = 1.0; int ijt = (degree + 1) / 2; for (int it = ijt; it > 0; it --) pnu [it] = pk [it] + pk [it - 1] - alfak * pkz [it - 1]; if (2 * ijt == degree) pnu [ijt + 1] = pnu [ijt]; if (degree == 1) { (void) 0; } else if (degree == 2) { zeroes [0] = 1.0; // starting values zeroes [1] = 0.5 - 0.5 * pnu [1]; zeroes [2] = -1.0; } else if (! findNewZeroes (ijt, pnu, degree, zeroes)) { result = 0; goto loopEnd; } /* Grow older. */ for (int i = 0; i <= 32; i ++) { pkz [i] = pk [i]; pk [i] = pnu [i]; } } } loopEnd: /* First pass: count the poles. */ for (int i = 1; i <= ncof / 2; i ++) { if (zeroes [i] == 0.0 || zeroes [i] == -1.0) break; frame -> nFormants ++; } /* Create space for formant data. */ if (frame -> nFormants > 0) frame -> formant = NUMvector (1, frame -> nFormants); /* Second pass: fill in the poles. */ int iformant = 0; for (int i = 1; i <= ncof / 2; i ++) { Formant_Formant formant = & frame -> formant [++ iformant]; if (zeroes [i] == 0.0 || zeroes [i] == -1.0) break; formant -> frequency = acos (zeroes [i]) * nyquistFrequency / NUMpi; formant -> bandwidth = 50.0; } return result; } static void Sound_preEmphasis (Sound me, double preEmphasisFrequency) { double preEmphasis = exp (-2.0 * NUMpi * preEmphasisFrequency * my dx); for (long channel = 1; channel <= my ny; channel ++) { double *s = my z [channel]; for (long i = my nx; i >= 2; i --) s [i] -= preEmphasis * s [i - 1]; } } void Formant_sort (Formant me) { for (long iframe = 1; iframe <= my nx; iframe ++) { Formant_Frame frame = & my d_frames [iframe]; long n = frame -> nFormants; for (long i = 1; i < n; i ++) { double min = frame -> formant [i]. frequency; long imin = i; for (long j = i + 1; j <= n; j ++) if (frame -> formant [j]. frequency < min) { min = frame -> formant [j]. frequency; imin = j; } if (imin != i) { double min_bandwidth = frame -> formant [imin]. bandwidth; frame -> formant [imin]. frequency = frame -> formant [i]. frequency; frame -> formant [imin]. bandwidth = frame -> formant [i]. bandwidth; frame -> formant [i]. frequency = min; frame -> formant [i]. bandwidth = min_bandwidth; } } } } static autoFormant Sound_to_Formant_any_inline (Sound me, double dt_in, int numberOfPoles, double halfdt_window, int which, double preemphasisFrequency, double safetyMargin) { double dt = dt_in > 0.0 ? dt_in : halfdt_window / 4.0; double duration = my nx * my dx, t1; double dt_window = 2.0 * halfdt_window; long nFrames = 1 + (long) floor ((duration - dt_window) / dt); long nsamp_window = (long) floor (dt_window / my dx), halfnsamp_window = nsamp_window / 2; if (nsamp_window < numberOfPoles + 1) Melder_throw (U"Window too short."); t1 = my x1 + 0.5 * (duration - my dx - (nFrames - 1) * dt); // centre of first frame if (nFrames < 1) { nFrames = 1; t1 = my x1 + 0.5 * duration; dt_window = duration; nsamp_window = my nx; } autoFormant thee = Formant_create (my xmin, my xmax, nFrames, dt, t1, (numberOfPoles + 1) / 2); // e.g. 11 poles -> maximally 6 formants autoNUMvector window (1, nsamp_window); autoNUMvector frame (1, nsamp_window); autoNUMvector cof (1, numberOfPoles); // superfluous if which==2, but nobody uses that anyway autoMelderProgress progress (U"Formant analysis..."); /* Pre-emphasis. */ Sound_preEmphasis (me, preemphasisFrequency); /* Gaussian window. */ for (long i = 1; i <= nsamp_window; i ++) { double imid = 0.5 * (nsamp_window + 1), edge = exp (-12.0); window [i] = (exp (-48.0 * (i - imid) * (i - imid) / (nsamp_window + 1) / (nsamp_window + 1)) - edge) / (1.0 - edge); } for (long iframe = 1; iframe <= nFrames; iframe ++) { double t = Sampled_indexToX (thee.peek(), iframe); long leftSample = Sampled_xToLowIndex (me, t); long rightSample = leftSample + 1; long startSample = rightSample - halfnsamp_window; long endSample = leftSample + halfnsamp_window; double maximumIntensity = 0.0; if (startSample < 1) startSample = 1; if (endSample > my nx) endSample = my nx; for (long i = startSample; i <= endSample; i ++) { double value = Sampled_getValueAtSample (me, i, Sound_LEVEL_MONO, 0); if (value * value > maximumIntensity) { maximumIntensity = value * value; } } if (maximumIntensity == HUGE_VAL) Melder_throw (U"Sound contains infinities."); thy d_frames [iframe]. intensity = maximumIntensity; if (maximumIntensity == 0.0) continue; // Burg cannot stand all zeroes /* Copy a pre-emphasized window to a frame. */ for (long j = 1, i = startSample; j <= nsamp_window; j ++) frame [j] = Sampled_getValueAtSample (me, i ++, Sound_LEVEL_MONO, 0) * window [j]; if (which == 1) { burg (frame.peek(), endSample - startSample + 1, cof.peek(), numberOfPoles, & thy d_frames [iframe], 0.5 / my dx, safetyMargin); } else if (which == 2) { if (! splitLevinson (frame.peek(), endSample - startSample + 1, numberOfPoles, & thy d_frames [iframe], 0.5 / my dx)) { Melder_clearError (); Melder_casual (U"(Sound_to_Formant:)" U" Analysis results of frame ", iframe, U" will be wrong." ); } } Melder_progress ((double) iframe / (double) nFrames, U"Formant analysis: frame ", iframe); } Formant_sort (thee.peek()); return thee; } autoFormant Sound_to_Formant_any (Sound me, double dt, int numberOfPoles, double maximumFrequency, double halfdt_window, int which, double preemphasisFrequency, double safetyMargin) { double nyquist = 0.5 / my dx; autoSound sound; if (maximumFrequency <= 0.0 || fabs (maximumFrequency / nyquist - 1) < 1.0e-12) { sound = Data_copy (me); // will be modified } else { sound = Sound_resample (me, maximumFrequency * 2, 50); } return Sound_to_Formant_any_inline (sound.peek(), dt, numberOfPoles, halfdt_window, which, preemphasisFrequency, safetyMargin); } autoFormant Sound_to_Formant_burg (Sound me, double dt, double nFormants, double maximumFrequency, double halfdt_window, double preemphasisFrequency) { try { return Sound_to_Formant_any (me, dt, (int) (2 * nFormants), maximumFrequency, halfdt_window, 1, preemphasisFrequency, 50.0); } catch (MelderError) { Melder_throw (me, U": formant analysis (Burg) not performed."); } } autoFormant Sound_to_Formant_keepAll (Sound me, double dt, double nFormants, double maximumFrequency, double halfdt_window, double preemphasisFrequency) { try { return Sound_to_Formant_any (me, dt, (int) (2 * nFormants), maximumFrequency, halfdt_window, 1, preemphasisFrequency, 0.0); } catch (MelderError) { Melder_throw (me, U": formant analysis (keep all) not performed."); } } autoFormant Sound_to_Formant_willems (Sound me, double dt, double nFormants, double maximumFrequency, double halfdt_window, double preemphasisFrequency) { try { return Sound_to_Formant_any (me, dt, (int) (2 * nFormants), maximumFrequency, halfdt_window, 2, preemphasisFrequency, 50.0); } catch (MelderError) { Melder_throw (me, U": formant analysis (Burg) not performed."); } } /* End of file Sound_to_Formant.cpp */ praat-6.0.04/fon/Sound_to_Formant.h000066400000000000000000000033561261542461700171420ustar00rootroot00000000000000/* Sound_to_Formant.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Sound.h" #include "Formant.h" autoFormant Sound_to_Formant_any (Sound me, double timeStep, int numberOfPoles, double maximumFrequency, double halfdt_window, int which, double preemphasisFrequency, double safetyMargin); /* Which = 1: Burg. Which = 2: Split-Levinson */ autoFormant Sound_to_Formant_burg (Sound me, double timeStep, double maximumNumberOfFormants, double maximumFormantFrequency, double windowLength, double preemphasisFrequency); /* Throws away all formants below 50 Hz and above Nyquist minus 50 Hz. */ autoFormant Sound_to_Formant_keepAll (Sound me, double timeStep, double maximumNumberOfFormants, double maximumFormantFrequency, double windowLength, double preemphasisFrequency); /* Same as previous, but keeps all formants. Good for resynthesis. */ autoFormant Sound_to_Formant_willems (Sound me, double timeStep, double numberOfFormants, double maximumFormantFrequency, double windowLength, double preemphasisFrequency); /* End of file Sound_to_Formant.h */ praat-6.0.04/fon/Sound_to_Harmonicity.cpp000066400000000000000000000047631261542461700203600ustar00rootroot00000000000000/* Sound_to_Harmonicity.cpp * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2004/10/29 corrected * pb 2011/03/09 C++ */ #include "Sound_to_Pitch.h" #include "Sound_to_Harmonicity.h" autoHarmonicity Sound_to_Harmonicity_ac (Sound me, double dt, double minimumPitch, double silenceThreshold, double periodsPerWindow) { try { autoPitch pitch = Sound_to_Pitch_any (me, dt, minimumPitch, periodsPerWindow, 15, 1, silenceThreshold, 0, 0, 0, 0, 0.5 / my dx); autoHarmonicity thee = Harmonicity_create (my xmin, my xmax, pitch -> nx, pitch -> dx, pitch -> x1); for (long i = 1; i <= thy nx; i ++) { if (pitch -> frame [i]. candidate [1]. frequency == 0) { thy z [1] [i] = -200; } else { double r = pitch -> frame [i]. candidate [1]. strength; thy z [1] [i] = r <= 1e-15 ? -150 : r > 1 - 1e-15 ? 150 : 10 * log10 (r / (1 - r)); } } return thee; } catch (MelderError) { Melder_throw (me, U": harmonicity analysis (ac) not performed."); } } autoHarmonicity Sound_to_Harmonicity_cc (Sound me, double dt, double minimumPitch, double silenceThreshold, double periodsPerWindow) { try { autoPitch pitch = Sound_to_Pitch_any (me, dt, minimumPitch, periodsPerWindow, 15, 3, silenceThreshold, 0, 0, 0, 0, 0.5 / my dx); autoHarmonicity thee = Harmonicity_create (my xmin, my xmax, pitch -> nx, pitch -> dx, pitch -> x1); for (long i = 1; i <= thy nx; i ++) { if (pitch -> frame [i]. candidate [1]. frequency == 0) { thy z [1] [i] = -200; } else { double r = pitch -> frame [i]. candidate [1]. strength; thy z [1] [i] = r <= 1e-15 ? -150 : r > 1 - 1e-15 ? 150 : 10 * log10 (r / (1 - r)); } } return thee; } catch (MelderError) { Melder_throw (me, U": harmonicity analysis (cc) not performed."); } } /* End of file Sound_to_Harmonicity.cpp */ praat-6.0.04/fon/Sound_to_Harmonicity.h000066400000000000000000000024321261542461700200140ustar00rootroot00000000000000/* Sound_to_Harmonicity.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Sound.h" #include "Harmonicity.h" autoHarmonicity Sound_to_Harmonicity_ac (Sound me, double dt, double minimumPitch, double silenceThreshold, double periodsPerWindow); autoHarmonicity Sound_to_Harmonicity_cc (Sound me, double dt, double minimumPitch, double silenceThreshold, double periodsPerWindow); autoMatrix Sound_to_Harmonicity_GNE (Sound me, double fmin, /* 500 Hz */ double fmax, /* 4500 Hz */ double bandwidth, /* 1000 Hz */ double step); /* 80 Hz */ /* End of file Sound_to_Harmonicity.h */ praat-6.0.04/fon/Sound_to_Harmonicity_GNE.cpp000066400000000000000000000137311261542461700210440ustar00rootroot00000000000000/* Sound_to_Harmonicity_GNE.cpp * * Copyright (C) 1999-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2004/11/22 simplified Sound_to_Spectrum () * pb 2008/01/19 double * pb 2011/06/13 C++ */ /* a replication of: D. Michaelis, T. Gramss & H.W. Strube (1997): "Glottal-to-noise excitation ratio -- a new measure for describing pathological voices." ACUSTICA - acta acustica 83: 700-706. henceforth abbreviated as "MGS". */ #include "Sound_to_Harmonicity.h" #include "Sound_and_LPC.h" #include "Sound_and_Spectrum.h" static void bandFilter (Spectrum me, double fmid, double bandwidth) { double *re = my z [1], *im = my z [2]; double fmin = fmid - bandwidth / 2, fmax = fmid + bandwidth / 2; double twopibybandwidth = 2 * NUMpi / bandwidth; for (long col = 1; col <= my nx; col ++) { double x = my x1 + (col - 1) * my dx; if (x < fmin || x > fmax) { re [col] = 0.0; im [col] = 0.0; } else { double factor = 0.5 + 0.5 * cos (twopibybandwidth * (x - fmid)); re [col] *= factor; im [col] *= factor; } } } autoMatrix Sound_to_Harmonicity_GNE (Sound me, double fmin, /* 500 Hz */ double fmax, /* 4500 Hz */ double bandwidth, /* 1000 Hz */ double step) /* 80 Hz */ { try { autoSound envelope [1+100]; long nenvelopes = (long) floor ((fmax - fmin) / step); for (long ienvelope = 1; ienvelope <= 100; ienvelope ++) Melder_assert (envelope [ienvelope].peek() == NULL); /* * Step 1: down-sampling to 10 kHz, * in order to be able to flatten the spectrum * (since the human voice does not contain much above 5 kHz). */ autoSound original10k = Sound_resample (me, 10000, 500); Vector_subtractMean (original10k.peek()); double duration = my xmax - my xmin; /* * Step 2: inverse filtering of the speech signal * by 13th-order "autocorrelation method" * with a Gaussian (not Hann, like MGS!) window of 30 ms length * and 10 ms shift between successive frames. * Since we need a spectrally flat signal (not an approximation * of the source signal), we must turn the pre-emphasis off * (by setting its turnover point at 1,000,000,000 Hz); * otherwise, the pre-emphasis would cause an overestimation * in the LPC object of the high frequencies, so that inverse * filtering would yield weakened high frequencies. */ autoLPC lpc = Sound_to_LPC_auto (original10k.peek(), 13, 30e-3, 10e-3, 1e9); autoSound flat = LPC_and_Sound_filterInverse (lpc.peek(), original10k.peek()); autoSpectrum flatSpectrum = Sound_to_Spectrum (flat.peek(), true); autoSpectrum hilbertSpectrum = Data_copy (flatSpectrum.peek()); for (long col = 1; col <= hilbertSpectrum -> nx; col ++) { hilbertSpectrum -> z [1] [col] = flatSpectrum -> z [2] [col]; hilbertSpectrum -> z [2] [col] = - flatSpectrum -> z [1] [col]; } double fmid = fmin; long ienvelope = 1; autoMelderMonitor monitor (U"Computing Hilbert envelopes..."); while (fmid <= fmax) { /* * Step 3: calculate Hilbert envelopes of bands. */ autoSpectrum bandSpectrum = Data_copy (flatSpectrum.peek()); autoSpectrum hilbertBandSpectrum = Data_copy (hilbertSpectrum.peek()); /* * 3a: Filter both the spectrum of the original flat sound and its Hilbert transform. */ bandFilter (bandSpectrum.peek(), fmid, bandwidth); bandFilter (hilbertBandSpectrum.peek(), fmid, bandwidth); /* * 3b: Create both the band-filtered flat sound and its Hilbert transform. */ autoSound band = Spectrum_to_Sound (bandSpectrum.peek()); /*if (graphics) { Graphics_clearWs (graphics); Spectrum_draw (bandSpectrum, graphics, 0, 5000, 0, 0, true); }*/ Melder_monitor (ienvelope / (nenvelopes + 1.0), U"Computing Hilbert envelope ", ienvelope, U"..."); autoSound hilbertBand = Spectrum_to_Sound (hilbertBandSpectrum.peek()); envelope [ienvelope] = Sound_extractPart (band.peek(), 0, duration, kSound_windowShape_RECTANGULAR, 1.0, true); /* * 3c: Compute the Hilbert envelope of the band-passed flat signal. */ for (long col = 1; col <= envelope [ienvelope] -> nx; col ++) { double self = envelope [ienvelope] -> z [1] [col], other = hilbertBand -> z [1] [col]; envelope [ienvelope] -> z [1] [col] = sqrt (self * self + other * other); } Vector_subtractMean (envelope [ienvelope].peek()); /* * Next band. */ fmid += step; ienvelope += 1; } /* * Step 4: crosscorrelation */ nenvelopes = ienvelope - 1; autoMatrix cc = Matrix_createSimple (nenvelopes, nenvelopes); for (long row = 2; row <= nenvelopes; row ++) { for (long col = 1; col <= row - 1; col ++) { autoSound crossCorrelation = Sounds_crossCorrelate_short (envelope [row].peek(), envelope [col].peek(), -3.1e-4, 3.1e-4, true); /* * Step 5: the maximum of each correlation function */ double ccmax = Vector_getMaximum (crossCorrelation.peek(), 0, 0, 0); cc -> z [row] [col] = ccmax; } } /* * Step 6: maximum of the maxima, ignoring those too close to the diagonal. */ for (long row = 2; row <= nenvelopes; row ++) { for (long col = 1; col <= row - 1; col ++) { if (labs (row - col) < bandwidth / 2 / step) { cc -> z [row] [col] = 0.0; } } } return cc; } catch (MelderError) { Melder_throw (me, U": not converted to Harmonicity (GNE)."); } } /* End of file Sound_to_Harmonicity_GNE.cpp */ praat-6.0.04/fon/Sound_to_Intensity.cpp000066400000000000000000000126001261542461700200450ustar00rootroot00000000000000/* Sound_to_Intensity.cpp * * Copyright (C) 1992-2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2003/05/20 default time step is four times oversampling * pb 2003/07/10 NUMbessel_i0_f * pb 2003/11/19 Sound_to_Intensity veryAccurate * pb 2003/12/15 removed bug introduced by previous change * pb 2004/10/27 subtractMean * pb 2006/12/31 compatible with stereo sounds * pb 2007/01/27 for stereo sounds, add channel energies * pb 2007/02/14 honoured precondition of Sampled_shortTermAnalysis (by checking whether minimumPitch is defined) * pb 2008/01/19 double * pb 2011/03/04 C++ * pb 2011/03/28 C++ */ #include "Sound_to_Intensity.h" static autoIntensity Sound_to_Intensity_ (Sound me, double minimumPitch, double timeStep, int subtractMeanPressure) { try { /* * Preconditions. */ if (! NUMdefined (minimumPitch)) Melder_throw (U"(Sound-to-Intensity:) Minimum pitch undefined."); if (! NUMdefined (timeStep)) Melder_throw (U"(Sound-to-Intensity:) Time step undefined."); if (timeStep < 0.0) Melder_throw (U"(Sound-to-Intensity:) Time step should be zero or positive instead of ", timeStep, U"."); if (my dx <= 0.0) Melder_throw (U"(Sound-to-Intensity:) The Sound's time step should be positive."); if (minimumPitch <= 0.0) Melder_throw (U"(Sound-to-Intensity:) Minimum pitch should be positive."); /* * Defaults. */ if (timeStep == 0.0) timeStep = 0.8 / minimumPitch; // default: four times oversampling Hanning-wise double windowDuration = 6.4 / minimumPitch; Melder_assert (windowDuration > 0.0); double halfWindowDuration = 0.5 * windowDuration; long halfWindowSamples = (long) floor (halfWindowDuration / my dx); autoNUMvector amplitude (- halfWindowSamples, halfWindowSamples); autoNUMvector window (- halfWindowSamples, halfWindowSamples); for (long i = - halfWindowSamples; i <= halfWindowSamples; i ++) { double x = i * my dx / halfWindowDuration, root = 1 - x * x; window [i] = root <= 0.0 ? 0.0 : NUMbessel_i0_f ((2 * NUMpi * NUMpi + 0.5) * sqrt (root)); } long numberOfFrames; double thyFirstTime; try { Sampled_shortTermAnalysis (me, windowDuration, timeStep, & numberOfFrames, & thyFirstTime); } catch (MelderError) { Melder_throw (U"The duration of the sound in an intensity analysis should be at least 6.4 divided by the minimum pitch (", minimumPitch, U" Hz), " U"i.e. at least ", 6.4 / minimumPitch, U" s, instead of ", my xmax - my xmin, U" s."); } autoIntensity thee = Intensity_create (my xmin, my xmax, numberOfFrames, timeStep, thyFirstTime); for (long iframe = 1; iframe <= numberOfFrames; iframe ++) { double midTime = Sampled_indexToX (thee.peek(), iframe); long midSample = Sampled_xToNearestIndex (me, midTime); long leftSample = midSample - halfWindowSamples, rightSample = midSample + halfWindowSamples; double sumxw = 0.0, sumw = 0.0, intensity; if (leftSample < 1) leftSample = 1; if (rightSample > my nx) rightSample = my nx; for (long channel = 1; channel <= my ny; channel ++) { for (long i = leftSample; i <= rightSample; i ++) { amplitude [i - midSample] = my z [channel] [i]; } if (subtractMeanPressure) { double sum = 0.0; for (long i = leftSample; i <= rightSample; i ++) { sum += amplitude [i - midSample]; } double mean = sum / (rightSample - leftSample + 1); for (long i = leftSample; i <= rightSample; i ++) { amplitude [i - midSample] -= mean; } } for (long i = leftSample; i <= rightSample; i ++) { sumxw += amplitude [i - midSample] * amplitude [i - midSample] * window [i - midSample]; sumw += window [i - midSample]; } } intensity = sumxw / sumw; intensity /= 4e-10; thy z [1] [iframe] = intensity < 1e-30 ? -300 : 10 * log10 (intensity); } return thee; } catch (MelderError) { Melder_throw (me, U": intensity analysis not performed."); } } autoIntensity Sound_to_Intensity (Sound me, double minimumPitch, double timeStep, int subtractMeanPressure) { bool veryAccurate = false; if (veryAccurate) { autoSound up = Sound_upsample (me); // because squaring doubles the frequency content, i.e. you get super-Nyquist components return Sound_to_Intensity_ (up.peek(), minimumPitch, timeStep, subtractMeanPressure); } else { return Sound_to_Intensity_ (me, minimumPitch, timeStep, subtractMeanPressure); } } autoIntensityTier Sound_to_IntensityTier (Sound me, double minimumPitch, double timeStep, int subtractMean) { try { autoIntensity intensity = Sound_to_Intensity (me, minimumPitch, timeStep, subtractMean); return Intensity_downto_IntensityTier (intensity.peek()); } catch (MelderError) { Melder_throw (me, U": no IntensityTier created."); } } /* End of file Sound_to_Intensity.cpp */ praat-6.0.04/fon/Sound_to_Intensity.h000066400000000000000000000035761261542461700175260ustar00rootroot00000000000000/* Sound_to_Intensity.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Sound.h" #include "Intensity.h" #include "IntensityTier.h" autoIntensity Sound_to_Intensity (Sound me, double minimumPitch, double timeStep, int subtractMean); /* Function: smooth away the periodic part of a signal, by convolving the square of the signal with a Kaiser(20.24) window; and resample on original sample points. Arguments: 'minimumPitch': the minimum periodicity frequency that will be smoothed away to at most 0.00001 %. The Hanning/Hamming-equivalent window length will be 3.2 / 'minimumPitch'. The actual window length will be twice that. 'timeStep': if <= 0.0, then 0.8 / minimumPitch. Performance: every periodicity frequency greater than 'minimumPitch' will be smoothed away to at most 0.00001 %; if 'timeStep' is 0 or less than 3.2 / 'minimumPitch', aliased frequencies will be at least 140 dB down. Example: minimumPitch = 100 Hz; Hanning/Hanning-equivalent window duration = 32 ms; actual window duration = 64 ms; */ autoIntensityTier Sound_to_IntensityTier (Sound me, double minimumPitch, double timeStep, int subtractMean); /* End of file Sound_to_Intensity.h */ praat-6.0.04/fon/Sound_to_Pitch kopie.cpp000066400000000000000000000535311261542461700202260ustar00rootroot00000000000000/* Sound_to_Pitch.cpp * * Copyright (C) 1992-2011,2014 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2002/10/11 removed some assertions * pb 2003/05/20 default time step is four times oversampling * pb 2003/07/02 checks on NUMrealft * pb 2004/05/10 better error messages * pb 2004/10/18 auto maxnCandidates * pb 2004/10/18 use of constant FFT tables speeds up AC method by a factor of 1.9 * pb 2006/12/31 compatible with stereo sounds * pb 2007/01/30 loop split for stereo speeds up CC method by a factor of 6 * pb 2008/01/19 double * pb 2010/12/07 compatible with sounds with any number of channels * pb 2011/03/08 C++ * pb 2014/05/23 threads */ #include "Sound_to_Pitch.h" #include "NUM2.h" #include #define AC_HANNING 0 #define AC_GAUSS 1 #define FCC_NORMAL 2 #define FCC_ACCURATE 3 static void Sound_into_PitchFrame (Sound me, Pitch_Frame pitchFrame, double t, double minimumPitch, int maxnCandidates, int method, double voicingThreshold, double octaveCost, NUMfft_Table fftTable, double dt_window, long nsamp_window, long halfnsamp_window, long maximumLag, long nsampFFT, long nsamp_period, long halfnsamp_period, long brent_ixmax, long brent_depth, double globalPeak, double **frame, double *ac, double *window, double *windowR, double *r, long *imax, double *localMean) { double localPeak; long leftSample = Sampled_xToLowIndex (me, t), rightSample = leftSample + 1; long startSample, endSample; for (long channel = 1; channel <= my ny; channel ++) { /* * Compute the local mean; look one longest period to both sides. */ startSample = rightSample - nsamp_period; endSample = leftSample + nsamp_period; Melder_assert (startSample >= 1); Melder_assert (endSample <= my nx); localMean [channel] = 0.0; for (long i = startSample; i <= endSample; i ++) { localMean [channel] += my z [channel] [i]; } localMean [channel] /= 2 * nsamp_period; /* * Copy a window to a frame and subtract the local mean. * We are going to kill the DC component before windowing. */ startSample = rightSample - halfnsamp_window; endSample = leftSample + halfnsamp_window; Melder_assert (startSample >= 1); Melder_assert (endSample <= my nx); if (method < FCC_NORMAL) { for (long j = 1, i = startSample; j <= nsamp_window; j ++) frame [channel] [j] = (my z [channel] [i ++] - localMean [channel]) * window [j]; for (long j = nsamp_window + 1; j <= nsampFFT; j ++) frame [channel] [j] = 0.0; } else { for (long j = 1, i = startSample; j <= nsamp_window; j ++) frame [channel] [j] = my z [channel] [i ++] - localMean [channel]; } } /* * Compute the local peak; look half a longest period to both sides. */ localPeak = 0.0; if ((startSample = halfnsamp_window + 1 - halfnsamp_period) < 1) startSample = 1; if ((endSample = halfnsamp_window + halfnsamp_period) > nsamp_window) endSample = nsamp_window; for (long channel = 1; channel <= my ny; channel ++) { for (long j = startSample; j <= endSample; j ++) { double value = fabs (frame [channel] [j]); if (value > localPeak) localPeak = value; } } pitchFrame->intensity = localPeak > globalPeak ? 1.0 : localPeak / globalPeak; /* * Compute the correlation into the array 'r'. */ if (method >= FCC_NORMAL) { double startTime = t - 0.5 * (1.0 / minimumPitch + dt_window); long localSpan = maximumLag + nsamp_window, localMaximumLag, offset; if ((startSample = Sampled_xToLowIndex (me, startTime)) < 1) startSample = 1; if (localSpan > my nx + 1 - startSample) localSpan = my nx + 1 - startSample; localMaximumLag = localSpan - nsamp_window; offset = startSample - 1; double sumx2 = 0; /* Sum of squares. */ for (long channel = 1; channel <= my ny; channel ++) { double *amp = my z [channel] + offset; for (long i = 1; i <= nsamp_window; i ++) { double x = amp [i] - localMean [channel]; sumx2 += x * x; } } double sumy2 = sumx2; /* At zero lag, these are still equal. */ r [0] = 1.0; for (long i = 1; i <= localMaximumLag; i ++) { double product = 0.0; for (long channel = 1; channel <= my ny; channel ++) { double *amp = my z [channel] + offset; double y0 = amp [i] - localMean [channel]; double yZ = amp [i + nsamp_window] - localMean [channel]; sumy2 += yZ * yZ - y0 * y0; for (long j = 1; j <= nsamp_window; j ++) { double x = amp [j] - localMean [channel]; double y = amp [i + j] - localMean [channel]; product += x * y; } } r [- i] = r [i] = product / sqrt (sumx2 * sumy2); } } else { /* * The FFT of the autocorrelation is the power spectrum. */ for (long i = 1; i <= nsampFFT; i ++) { ac [i] = 0.0; } for (long channel = 1; channel <= my ny; channel ++) { NUMfft_forward (fftTable, frame [channel]); /* Complex spectrum. */ ac [1] += frame [channel] [1] * frame [channel] [1]; /* DC component. */ for (long i = 2; i < nsampFFT; i += 2) { ac [i] += frame [channel] [i] * frame [channel] [i] + frame [channel] [i+1] * frame [channel] [i+1]; /* Power spectrum. */ } ac [nsampFFT] += frame [channel] [nsampFFT] * frame [channel] [nsampFFT]; /* Nyquist frequency. */ } NUMfft_backward (fftTable, ac); /* Autocorrelation. */ /* * Normalize the autocorrelation to the value with zero lag, * and divide it by the normalized autocorrelation of the window. */ r [0] = 1.0; for (long i = 1; i <= brent_ixmax; i ++) r [- i] = r [i] = ac [i + 1] / (ac [1] * windowR [i + 1]); } /* * Register the first candidate, which is always present: voicelessness. */ pitchFrame->nCandidates = 1; pitchFrame->candidate[1].frequency = 0.0; /* Voiceless: always present. */ pitchFrame->candidate[1].strength = 0.0; /* * Shortcut: absolute silence is always voiceless. * We are done for this frame. */ if (localPeak == 0) return; /* * Find the strongest maxima of the correlation of this frame, * and register them as candidates. */ imax [1] = 0; for (long i = 2; i < maximumLag && i < brent_ixmax; i ++) if (r [i] > 0.5 * voicingThreshold && /* Not too unvoiced? */ r [i] > r [i-1] && r [i] >= r [i+1]) /* Maximum? */ { int place = 0; /* * Use parabolic interpolation for first estimate of frequency, * and sin(x)/x interpolation to compute the strength of this frequency. */ double dr = 0.5 * (r [i+1] - r [i-1]), d2r = 2 * r [i] - r [i-1] - r [i+1]; double frequencyOfMaximum = 1 / my dx / (i + dr / d2r); long offset = - brent_ixmax - 1; double strengthOfMaximum = /* method & 1 ? */ NUM_interpolate_sinc (& r [offset], brent_ixmax - offset, 1 / my dx / frequencyOfMaximum - offset, 30) /* : r [i] + 0.5 * dr * dr / d2r */; /* High values due to short windows are to be reflected around 1. */ if (strengthOfMaximum > 1.0) strengthOfMaximum = 1.0 / strengthOfMaximum; /* * Find a place for this maximum. */ if (pitchFrame->nCandidates < maxnCandidates) { /* Is there still a free place? */ place = ++ pitchFrame->nCandidates; } else { /* Try the place of the weakest candidate so far. */ double weakest = 2; for (int iweak = 2; iweak <= maxnCandidates; iweak ++) { /* High frequencies are to be favoured */ /* if we want to analyze a perfectly periodic signal correctly. */ double localStrength = pitchFrame->candidate[iweak].strength - octaveCost * NUMlog2 (minimumPitch / pitchFrame->candidate[iweak].frequency); if (localStrength < weakest) { weakest = localStrength; place = iweak; } } /* If this maximum is weaker than the weakest candidate so far, give it no place. */ if (strengthOfMaximum - octaveCost * NUMlog2 (minimumPitch / frequencyOfMaximum) <= weakest) place = 0; } if (place) { /* Have we found a place for this candidate? */ pitchFrame->candidate[place].frequency = frequencyOfMaximum; pitchFrame->candidate[place].strength = strengthOfMaximum; imax [place] = i; } } /* * Second pass: for extra precision, maximize sin(x)/x interpolation ('sinc'). */ for (long i = 2; i <= pitchFrame->nCandidates; i ++) { if (method != AC_HANNING || pitchFrame->candidate[i].frequency > 0.0 / my dx) { double xmid, ymid; long offset = - brent_ixmax - 1; ymid = NUMimproveMaximum (& r [offset], brent_ixmax - offset, imax [i] - offset, pitchFrame->candidate[i].frequency > 0.3 / my dx ? NUM_PEAK_INTERPOLATE_SINC700 : brent_depth, & xmid); xmid += offset; pitchFrame->candidate[i].frequency = 1.0 / my dx / xmid; if (ymid > 1.0) ymid = 1.0 / ymid; pitchFrame->candidate[i].strength = ymid; } } } static void Sound_into_Pitch (Sound me, Pitch thee, long firstFrame, long lastFrame, double minimumPitch, int maxnCandidates, int method, double voicingThreshold, double octaveCost, NUMfft_Table fftTable, double dt_window, long nsamp_window, long halfnsamp_window, long maximumLag, long nsampFFT, long nsamp_period, long halfnsamp_period, long brent_ixmax, long brent_depth, double globalPeak, double **frame, double *ac, double *window, double *windowR, double *r, long *imax, double *localMean, bool isMainThread) { for (long iframe = firstFrame; iframe <= lastFrame; iframe ++) { Pitch_Frame pitchFrame = & thy frame [iframe]; double t = Sampled_indexToX (thee, iframe); if (isMainThread) Melder_progress (0.1 + 0.8 * (iframe - firstFrame) / (lastFrame - firstFrame), L"Sound to Pitch: analysing ", Melder_integer (lastFrame), L" frames"); Sound_into_PitchFrame (me, pitchFrame, t, minimumPitch, maxnCandidates, method, voicingThreshold, octaveCost, fftTable, dt_window, nsamp_window, halfnsamp_window, maximumLag, nsampFFT, nsamp_period, halfnsamp_period, brent_ixmax, brent_depth, globalPeak, frame, ac, window, windowR, r, imax, localMean); } } Pitch Sound_to_Pitch_any (Sound me, double dt, double minimumPitch, double periodsPerWindow, int maxnCandidates, int method, double silenceThreshold, double voicingThreshold, double octaveCost, double octaveJumpCost, double voicedUnvoicedCost, double ceiling) { try { autoNUMfft_Table fftTable, fftTable1, fftTable2, fftTable3; double duration, t1; double dt_window; /* Window length in seconds. */ long nsamp_window, halfnsamp_window; /* Number of samples per window. */ long nFrames, minimumLag, maximumLag; long nsampFFT; double interpolation_depth; long nsamp_period, halfnsamp_period; /* Number of samples in longest period. */ long brent_ixmax, brent_depth; double globalPeak; Melder_assert (maxnCandidates >= 2); Melder_assert (method >= AC_HANNING && method <= FCC_ACCURATE); if (maxnCandidates < ceiling / minimumPitch) maxnCandidates = ceiling / minimumPitch; if (dt <= 0.0) dt = periodsPerWindow / minimumPitch / 4.0; /* e.g. 3 periods, 75 Hz: 10 milliseconds. */ switch (method) { case AC_HANNING: brent_depth = NUM_PEAK_INTERPOLATE_SINC70; interpolation_depth = 0.5; break; case AC_GAUSS: periodsPerWindow *= 2; /* Because Gaussian window is twice as long. */ brent_depth = NUM_PEAK_INTERPOLATE_SINC700; interpolation_depth = 0.25; /* Because Gaussian window is twice as long. */ break; case FCC_NORMAL: brent_depth = NUM_PEAK_INTERPOLATE_SINC70; interpolation_depth = 1.0; break; case FCC_ACCURATE: brent_depth = NUM_PEAK_INTERPOLATE_SINC700; interpolation_depth = 1.0; break; } duration = my dx * my nx; if (minimumPitch < periodsPerWindow / duration) Melder_throw ("To analyse this Sound, ", L_LEFT_DOUBLE_QUOTE, "minimum pitch", L_RIGHT_DOUBLE_QUOTE, " must not be less than ", periodsPerWindow / duration, " Hz."); /* * Determine the number of samples in the longest period. * We need this to compute the local mean of the sound (looking one period in both directions), * and to compute the local peak of the sound (looking half a period in both directions). */ nsamp_period = floor (1 / my dx / minimumPitch); halfnsamp_period = nsamp_period / 2 + 1; if (ceiling > 0.5 / my dx) ceiling = 0.5 / my dx; /* * Determine window length in seconds and in samples. */ dt_window = periodsPerWindow / minimumPitch; nsamp_window = floor (dt_window / my dx); halfnsamp_window = nsamp_window / 2 - 1; if (halfnsamp_window < 2) Melder_throw ("Analysis window too short."); nsamp_window = halfnsamp_window * 2; /* * Determine the minimum and maximum lags. */ minimumLag = floor (1 / my dx / ceiling); if (minimumLag < 2) minimumLag = 2; maximumLag = floor (nsamp_window / periodsPerWindow) + 2; if (maximumLag > nsamp_window) maximumLag = nsamp_window; /* * Determine the number of frames. * Fit as many frames as possible symmetrically in the total duration. * We do this even for the forward cross-correlation method, * because that allows us to compare the two methods. */ try { Sampled_shortTermAnalysis (me, method >= FCC_NORMAL ? 1 / minimumPitch + dt_window : dt_window, dt, & nFrames, & t1); } catch (MelderError) { Melder_throw ("The pitch analysis would give zero pitch frames."); } /* * Create the resulting pitch contour. */ autoPitch thee = Pitch_create (my xmin, my xmax, nFrames, dt, t1, ceiling, maxnCandidates); /* * Create (too much) space for candidates. */ for (long iframe = 1; iframe <= nFrames; iframe ++) { Pitch_Frame pitchFrame = & thy frame [iframe]; Pitch_Frame_init (pitchFrame, maxnCandidates); } /* * Compute the global absolute peak for determination of silence threshold. */ globalPeak = 0.0; for (long channel = 1; channel <= my ny; channel ++) { double mean = 0.0; for (long i = 1; i <= my nx; i ++) { mean += my z [channel] [i]; } mean /= my nx; for (long i = 1; i <= my nx; i ++) { double value = fabs (my z [channel] [i] - mean); if (value > globalPeak) globalPeak = value; } } if (globalPeak == 0.0) { return thee.transfer(); } autoNUMvector window; autoNUMvector windowR; if (method >= FCC_NORMAL) { /* For cross-correlation analysis. */ brent_ixmax = nsamp_window * interpolation_depth; } else { /* For autocorrelation analysis. */ /* * Compute the number of samples needed for doing FFT. * To avoid edge effects, we have to append zeroes to the window. * The maximum lag considered for maxima is maximumLag. * The maximum lag used in interpolation is nsamp_window * interpolation_depth. */ nsampFFT = 1; while (nsampFFT < nsamp_window * (1 + interpolation_depth)) nsampFFT *= 2; /* * Create buffers for autocorrelation analysis. */ windowR.reset (1, nsampFFT); window.reset (1, nsamp_window); NUMfft_Table_init (& fftTable, nsampFFT); /* * A Gaussian or Hanning window is applied against phase effects. * The Hanning window is 2 to 5 dB better for 3 periods/window. * The Gaussian window is 25 to 29 dB better for 6 periods/window. */ if (method == AC_GAUSS) { /* Gaussian window. */ double imid = 0.5 * (nsamp_window + 1), edge = exp (-12.0); for (long i = 1; i <= nsamp_window; i ++) window [i] = (exp (-48.0 * (i - imid) * (i - imid) / (nsamp_window + 1) / (nsamp_window + 1)) - edge) / (1 - edge); } else { // Hanning window for (long i = 1; i <= nsamp_window; i ++) window [i] = 0.5 - 0.5 * cos (i * 2 * NUMpi / (nsamp_window + 1)); } /* * Compute the normalized autocorrelation of the window. */ for (long i = 1; i <= nsamp_window; i ++) windowR [i] = window [i]; NUMfft_forward (& fftTable, windowR.peek()); windowR [1] *= windowR [1]; // DC component for (long i = 2; i < nsampFFT; i += 2) { windowR [i] = windowR [i] * windowR [i] + windowR [i+1] * windowR [i+1]; windowR [i + 1] = 0.0; // power spectrum: square and zero } windowR [nsampFFT] *= windowR [nsampFFT]; // Nyquist frequency NUMfft_backward (& fftTable, windowR.peek()); // autocorrelation for (long i = 2; i <= nsamp_window; i ++) windowR [i] /= windowR [1]; // normalize windowR [1] = 1.0; // normalize brent_ixmax = nsamp_window * interpolation_depth; } NUMfft_Table_init (& fftTable1, nsampFFT); NUMfft_Table_init (& fftTable2, nsampFFT); NUMfft_Table_init (& fftTable3, nsampFFT); autoNUMmatrix frame, frame1, frame2, frame3; autoNUMvector ac, ac1, ac2, ac3; if (method >= FCC_NORMAL) { // cross-correlation frame.reset (1, my ny, 1, nsamp_window); frame1.reset (1, my ny, 1, nsamp_window); frame2.reset (1, my ny, 1, nsamp_window); frame3.reset (1, my ny, 1, nsamp_window); } else { // autocorrelation frame.reset (1, my ny, 1, nsampFFT); frame1.reset (1, my ny, 1, nsampFFT); frame2.reset (1, my ny, 1, nsampFFT); frame3.reset (1, my ny, 1, nsampFFT); ac.reset (1, nsampFFT); ac1.reset (1, nsampFFT); ac2.reset (1, nsampFFT); ac3.reset (1, nsampFFT); } autoNUMvector r (- nsamp_window, nsamp_window), r1 (- nsamp_window, nsamp_window), r2 (- nsamp_window, nsamp_window), r3 (- nsamp_window, nsamp_window); autoNUMvector imax (1, maxnCandidates), imax1 (1, maxnCandidates), imax2 (1, maxnCandidates), imax3 (1, maxnCandidates); autoNUMvector localMean (1, my ny), localMean1 (1, my ny), localMean2 (1, my ny), localMean3 (1, my ny); autoMelderProgress progress (L"Sound to Pitch..."); long numberOfFramesPerThread = 20; int numberOfThreads = (nFrames - 1) / numberOfFramesPerThread + 1; const int numberOfProcessors = 4; if (numberOfThreads > numberOfProcessors) numberOfThreads = numberOfProcessors; if (numberOfThreads > 16) numberOfThreads = 16; numberOfThreads = 4; numberOfFramesPerThread = (nFrames - 1) / numberOfThreads + 1; std::thread thread [3]; long firstFrame = 1, lastFrame = numberOfFramesPerThread; try { thread [0] = std::thread (Sound_into_Pitch, me, thee.peek(), firstFrame, lastFrame, minimumPitch, maxnCandidates, method, voicingThreshold, octaveCost, & fftTable1, dt_window, nsamp_window, halfnsamp_window, maximumLag, nsampFFT, nsamp_period, halfnsamp_period, brent_ixmax, brent_depth, globalPeak, frame1.peek(), ac1.peek(), window.peek(), windowR.peek(), r1.peek(), imax1.peek(), localMean1.peek(), false); firstFrame = lastFrame + 1; lastFrame += numberOfFramesPerThread; thread [1] = std::thread (Sound_into_Pitch, me, thee.peek(), firstFrame, lastFrame, minimumPitch, maxnCandidates, method, voicingThreshold, octaveCost, & fftTable2, dt_window, nsamp_window, halfnsamp_window, maximumLag, nsampFFT, nsamp_period, halfnsamp_period, brent_ixmax, brent_depth, globalPeak, frame2.peek(), ac2.peek(), window.peek(), windowR.peek(), r2.peek(), imax2.peek(), localMean2.peek(), false); firstFrame = lastFrame + 1; lastFrame += numberOfFramesPerThread; thread [2] = std::thread (Sound_into_Pitch, me, thee.peek(), firstFrame, lastFrame, minimumPitch, maxnCandidates, method, voicingThreshold, octaveCost, & fftTable3, dt_window, nsamp_window, halfnsamp_window, maximumLag, nsampFFT, nsamp_period, halfnsamp_period, brent_ixmax, brent_depth, globalPeak, frame3.peek(), ac3.peek(), window.peek(), windowR.peek(), r3.peek(), imax3.peek(), localMean3.peek(), false); firstFrame = lastFrame + 1; lastFrame += numberOfFramesPerThread; } catch (MelderError) { for (int ithread = 1; ithread < numberOfThreads; ithread ++) { if (thread [ithread - 1]. joinable ()) thread [ithread - 1]. join (); } throw; } Sound_into_Pitch (me, thee.peek(), firstFrame, nFrames, minimumPitch, maxnCandidates, method, voicingThreshold, octaveCost, & fftTable, dt_window, nsamp_window, halfnsamp_window, maximumLag, nsampFFT, nsamp_period, halfnsamp_period, brent_ixmax, brent_depth, globalPeak, frame.peek(), ac.peek(), window.peek(), windowR.peek(), r.peek(), imax.peek(), localMean.peek(), true); for (int ithread = 1; ithread < numberOfThreads; ithread ++) { thread [ithread - 1]. join (); } Melder_progress (0.95, L"Sound to Pitch: path finder"); // progress (0.95, L"Sound to Pitch: path finder"); Pitch_pathFinder (thee.peek(), silenceThreshold, voicingThreshold, octaveCost, octaveJumpCost, voicedUnvoicedCost, ceiling, Melder_debug == 31 ? true : false); return thee.transfer(); } catch (MelderError) { Melder_throw (me, ": pitch analysis not performed."); } } Pitch Sound_to_Pitch (Sound me, double timeStep, double minimumPitch, double maximumPitch) { return Sound_to_Pitch_ac (me, timeStep, minimumPitch, 3.0, 15, FALSE, 0.03, 0.45, 0.01, 0.35, 0.14, maximumPitch); } Pitch Sound_to_Pitch_ac (Sound me, double dt, double minimumPitch, double periodsPerWindow, int maxnCandidates, int accurate, double silenceThreshold, double voicingThreshold, double octaveCost, double octaveJumpCost, double voicedUnvoicedCost, double ceiling) { return Sound_to_Pitch_any (me, dt, minimumPitch, periodsPerWindow, maxnCandidates, accurate, silenceThreshold, voicingThreshold, octaveCost, octaveJumpCost, voicedUnvoicedCost, ceiling); } Pitch Sound_to_Pitch_cc (Sound me, double dt, double minimumPitch, double periodsPerWindow, int maxnCandidates, int accurate, double silenceThreshold, double voicingThreshold, double octaveCost, double octaveJumpCost, double voicedUnvoicedCost, double ceiling) { return Sound_to_Pitch_any (me, dt, minimumPitch, periodsPerWindow, maxnCandidates, 2 + accurate, silenceThreshold, voicingThreshold, octaveCost, octaveJumpCost, voicedUnvoicedCost, ceiling); } /* End of file Sound_to_Pitch.cpp */ praat-6.0.04/fon/Sound_to_Pitch.cpp000066400000000000000000000527461261542461700171450ustar00rootroot00000000000000/* Sound_to_Pitch.cpp * * Copyright (C) 1992-2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2002/10/11 removed some assertions * pb 2003/05/20 default time step is four times oversampling * pb 2003/07/02 checks on NUMrealft * pb 2004/05/10 better error messages * pb 2004/10/18 auto maxnCandidates * pb 2004/10/18 use of constant FFT tables speeds up AC method by a factor of 1.9 * pb 2006/12/31 compatible with stereo sounds * pb 2007/01/30 loop split for stereo speeds up CC method by a factor of 6 * pb 2008/01/19 double * pb 2010/12/07 compatible with sounds with any number of channels * pb 2011/03/08 C++ * pb 2014/05/23 threads */ #include "Sound_to_Pitch.h" #include "NUM2.h" #include "MelderThread.h" #define AC_HANNING 0 #define AC_GAUSS 1 #define FCC_NORMAL 2 #define FCC_ACCURATE 3 static void Sound_into_PitchFrame (Sound me, Pitch_Frame pitchFrame, double t, double minimumPitch, int maxnCandidates, int method, double voicingThreshold, double octaveCost, NUMfft_Table fftTable, double dt_window, long nsamp_window, long halfnsamp_window, long maximumLag, long nsampFFT, long nsamp_period, long halfnsamp_period, long brent_ixmax, long brent_depth, double globalPeak, double **frame, double *ac, double *window, double *windowR, double *r, long *imax, double *localMean) { double localPeak; long leftSample = Sampled_xToLowIndex (me, t), rightSample = leftSample + 1; long startSample, endSample; for (long channel = 1; channel <= my ny; channel ++) { /* * Compute the local mean; look one longest period to both sides. */ startSample = rightSample - nsamp_period; endSample = leftSample + nsamp_period; Melder_assert (startSample >= 1); Melder_assert (endSample <= my nx); localMean [channel] = 0.0; for (long i = startSample; i <= endSample; i ++) { localMean [channel] += my z [channel] [i]; } localMean [channel] /= 2 * nsamp_period; /* * Copy a window to a frame and subtract the local mean. * We are going to kill the DC component before windowing. */ startSample = rightSample - halfnsamp_window; endSample = leftSample + halfnsamp_window; Melder_assert (startSample >= 1); Melder_assert (endSample <= my nx); if (method < FCC_NORMAL) { for (long j = 1, i = startSample; j <= nsamp_window; j ++) frame [channel] [j] = (my z [channel] [i ++] - localMean [channel]) * window [j]; for (long j = nsamp_window + 1; j <= nsampFFT; j ++) frame [channel] [j] = 0.0; } else { for (long j = 1, i = startSample; j <= nsamp_window; j ++) frame [channel] [j] = my z [channel] [i ++] - localMean [channel]; } } /* * Compute the local peak; look half a longest period to both sides. */ localPeak = 0.0; if ((startSample = halfnsamp_window + 1 - halfnsamp_period) < 1) startSample = 1; if ((endSample = halfnsamp_window + halfnsamp_period) > nsamp_window) endSample = nsamp_window; for (long channel = 1; channel <= my ny; channel ++) { for (long j = startSample; j <= endSample; j ++) { double value = fabs (frame [channel] [j]); if (value > localPeak) localPeak = value; } } pitchFrame->intensity = localPeak > globalPeak ? 1.0 : localPeak / globalPeak; /* * Compute the correlation into the array 'r'. */ if (method >= FCC_NORMAL) { double startTime = t - 0.5 * (1.0 / minimumPitch + dt_window); long localSpan = maximumLag + nsamp_window, localMaximumLag, offset; if ((startSample = Sampled_xToLowIndex (me, startTime)) < 1) startSample = 1; if (localSpan > my nx + 1 - startSample) localSpan = my nx + 1 - startSample; localMaximumLag = localSpan - nsamp_window; offset = startSample - 1; double sumx2 = 0; // sum of squares for (long channel = 1; channel <= my ny; channel ++) { double *amp = my z [channel] + offset; for (long i = 1; i <= nsamp_window; i ++) { double x = amp [i] - localMean [channel]; sumx2 += x * x; } } double sumy2 = sumx2; // at zero lag, these are still equal r [0] = 1.0; for (long i = 1; i <= localMaximumLag; i ++) { double product = 0.0; for (long channel = 1; channel <= my ny; channel ++) { double *amp = my z [channel] + offset; double y0 = amp [i] - localMean [channel]; double yZ = amp [i + nsamp_window] - localMean [channel]; sumy2 += yZ * yZ - y0 * y0; for (long j = 1; j <= nsamp_window; j ++) { double x = amp [j] - localMean [channel]; double y = amp [i + j] - localMean [channel]; product += x * y; } } r [- i] = r [i] = product / sqrt (sumx2 * sumy2); } } else { /* * The FFT of the autocorrelation is the power spectrum. */ for (long i = 1; i <= nsampFFT; i ++) { ac [i] = 0.0; } for (long channel = 1; channel <= my ny; channel ++) { NUMfft_forward (fftTable, frame [channel]); // complex spectrum ac [1] += frame [channel] [1] * frame [channel] [1]; // DC component for (long i = 2; i < nsampFFT; i += 2) { ac [i] += frame [channel] [i] * frame [channel] [i] + frame [channel] [i+1] * frame [channel] [i+1]; // power spectrum } ac [nsampFFT] += frame [channel] [nsampFFT] * frame [channel] [nsampFFT]; // Nyquist frequency } NUMfft_backward (fftTable, ac); /* Autocorrelation. */ /* * Normalize the autocorrelation to the value with zero lag, * and divide it by the normalized autocorrelation of the window. */ r [0] = 1.0; for (long i = 1; i <= brent_ixmax; i ++) r [- i] = r [i] = ac [i + 1] / (ac [1] * windowR [i + 1]); } /* * Register the first candidate, which is always present: voicelessness. */ pitchFrame->nCandidates = 1; pitchFrame->candidate[1].frequency = 0.0; // voiceless: always present pitchFrame->candidate[1].strength = 0.0; /* * Shortcut: absolute silence is always voiceless. * We are done for this frame. */ if (localPeak == 0) return; /* * Find the strongest maxima of the correlation of this frame, * and register them as candidates. */ imax [1] = 0; for (long i = 2; i < maximumLag && i < brent_ixmax; i ++) if (r [i] > 0.5 * voicingThreshold && // not too unvoiced? r [i] > r [i-1] && r [i] >= r [i+1]) // maximum? { int place = 0; /* * Use parabolic interpolation for first estimate of frequency, * and sin(x)/x interpolation to compute the strength of this frequency. */ double dr = 0.5 * (r [i+1] - r [i-1]), d2r = 2 * r [i] - r [i-1] - r [i+1]; double frequencyOfMaximum = 1 / my dx / (i + dr / d2r); long offset = - brent_ixmax - 1; double strengthOfMaximum = /* method & 1 ? */ NUM_interpolate_sinc (& r [offset], brent_ixmax - offset, 1 / my dx / frequencyOfMaximum - offset, 30) /* : r [i] + 0.5 * dr * dr / d2r */; /* High values due to short windows are to be reflected around 1. */ if (strengthOfMaximum > 1.0) strengthOfMaximum = 1.0 / strengthOfMaximum; /* * Find a place for this maximum. */ if (pitchFrame->nCandidates < maxnCandidates) { // is there still a free place? place = ++ pitchFrame->nCandidates; } else { /* Try the place of the weakest candidate so far. */ double weakest = 2; for (int iweak = 2; iweak <= maxnCandidates; iweak ++) { /* High frequencies are to be favoured */ /* if we want to analyze a perfectly periodic signal correctly. */ double localStrength = pitchFrame->candidate[iweak].strength - octaveCost * NUMlog2 (minimumPitch / pitchFrame->candidate[iweak].frequency); if (localStrength < weakest) { weakest = localStrength; place = iweak; } } /* If this maximum is weaker than the weakest candidate so far, give it no place. */ if (strengthOfMaximum - octaveCost * NUMlog2 (minimumPitch / frequencyOfMaximum) <= weakest) place = 0; } if (place) { // have we found a place for this candidate? pitchFrame->candidate[place].frequency = frequencyOfMaximum; pitchFrame->candidate[place].strength = strengthOfMaximum; imax [place] = i; } } /* * Second pass: for extra precision, maximize sin(x)/x interpolation ('sinc'). */ for (long i = 2; i <= pitchFrame->nCandidates; i ++) { if (method != AC_HANNING || pitchFrame->candidate[i].frequency > 0.0 / my dx) { double xmid, ymid; long offset = - brent_ixmax - 1; ymid = NUMimproveMaximum (& r [offset], brent_ixmax - offset, imax [i] - offset, pitchFrame->candidate[i].frequency > 0.3 / my dx ? NUM_PEAK_INTERPOLATE_SINC700 : brent_depth, & xmid); xmid += offset; pitchFrame->candidate[i].frequency = 1.0 / my dx / xmid; if (ymid > 1.0) ymid = 1.0 / ymid; pitchFrame->candidate[i].strength = ymid; } } } Thing_define (Sound_into_Pitch_Args, Thing) { public: Sound sound; Pitch pitch; long firstFrame, lastFrame; double minimumPitch; int maxnCandidates, method; double voicingThreshold, octaveCost, dt_window; long nsamp_window, halfnsamp_window, maximumLag, nsampFFT, nsamp_period, halfnsamp_period, brent_ixmax, brent_depth; double globalPeak, *window, *windowR; bool isMainThread; volatile int *cancelled; }; Thing_implement (Sound_into_Pitch_Args, Thing, 0); static Sound_into_Pitch_Args Sound_into_Pitch_Args_create (Sound sound, Pitch pitch, long firstFrame, long lastFrame, double minimumPitch, int maxnCandidates, int method, double voicingThreshold, double octaveCost, double dt_window, long nsamp_window, long halfnsamp_window, long maximumLag, long nsampFFT, long nsamp_period, long halfnsamp_period, long brent_ixmax, long brent_depth, double globalPeak, double *window, double *windowR, bool isMainThread, volatile int *cancelled) { autoSound_into_Pitch_Args me = Thing_new (Sound_into_Pitch_Args); my sound = sound; my pitch = pitch; my firstFrame = firstFrame; my lastFrame = lastFrame; my minimumPitch = minimumPitch; my maxnCandidates = maxnCandidates; my method = method; my voicingThreshold = voicingThreshold; my octaveCost = octaveCost; my dt_window = dt_window; my nsamp_window = nsamp_window; my halfnsamp_window = halfnsamp_window; my maximumLag = maximumLag; my nsampFFT = nsampFFT; my nsamp_period = nsamp_period; my halfnsamp_period = halfnsamp_period; my brent_ixmax = brent_ixmax; my brent_depth = brent_depth; my globalPeak = globalPeak; my window = window; my windowR = windowR; my isMainThread = isMainThread; my cancelled = cancelled; return me.transfer(); } MelderThread_MUTEX (mutex); bool mutex_inited; static MelderThread_RETURN_TYPE Sound_into_Pitch (Sound_into_Pitch_Args me) { autoNUMfft_Table fftTable; autoNUMmatrix frame; autoNUMvector ac, r, localMean; autoNUMvector imax; {// scope MelderThread_LOCK (mutex); if (my method >= FCC_NORMAL) { // cross-correlation frame.reset (1, my sound -> ny, 1, my nsamp_window); } else { // autocorrelation NUMfft_Table_init (& fftTable, my nsampFFT); frame.reset (1, my sound -> ny, 1, my nsampFFT); ac.reset (1, my nsampFFT); } r.reset (- my nsamp_window, my nsamp_window); imax.reset (1, my maxnCandidates); localMean.reset (1, my sound -> ny); MelderThread_UNLOCK (mutex); } for (long iframe = my firstFrame; iframe <= my lastFrame; iframe ++) { Pitch_Frame pitchFrame = & my pitch -> frame [iframe]; double t = Sampled_indexToX (my pitch, iframe); if (my isMainThread) { try { Melder_progress (0.1 + 0.8 * (iframe - my firstFrame) / (my lastFrame - my firstFrame), U"Sound to Pitch: analysing ", my lastFrame, U" frames"); } catch (MelderError) { *my cancelled = 1; throw; } } else if (*my cancelled) { MelderThread_RETURN; } Sound_into_PitchFrame (my sound, pitchFrame, t, my minimumPitch, my maxnCandidates, my method, my voicingThreshold, my octaveCost, & fftTable, my dt_window, my nsamp_window, my halfnsamp_window, my maximumLag, my nsampFFT, my nsamp_period, my halfnsamp_period, my brent_ixmax, my brent_depth, my globalPeak, frame.peek(), ac.peek(), my window, my windowR, r.peek(), imax.peek(), localMean.peek()); } MelderThread_RETURN; } autoPitch Sound_to_Pitch_any (Sound me, double dt, double minimumPitch, double periodsPerWindow, int maxnCandidates, int method, double silenceThreshold, double voicingThreshold, double octaveCost, double octaveJumpCost, double voicedUnvoicedCost, double ceiling) { try { autoNUMfft_Table fftTable; double duration, t1; double dt_window; // window length in seconds long nsamp_window, halfnsamp_window; // number of samples per window long nFrames, minimumLag, maximumLag; long nsampFFT; double interpolation_depth; long nsamp_period, halfnsamp_period; // number of samples in longest period long brent_ixmax, brent_depth; double globalPeak; Melder_assert (maxnCandidates >= 2); Melder_assert (method >= AC_HANNING && method <= FCC_ACCURATE); if (maxnCandidates < ceiling / minimumPitch) maxnCandidates = (long) floor (ceiling / minimumPitch); if (dt <= 0.0) dt = periodsPerWindow / minimumPitch / 4.0; // e.g. 3 periods, 75 Hz: 10 milliseconds switch (method) { case AC_HANNING: brent_depth = NUM_PEAK_INTERPOLATE_SINC70; interpolation_depth = 0.5; break; case AC_GAUSS: periodsPerWindow *= 2; // because Gaussian window is twice as long brent_depth = NUM_PEAK_INTERPOLATE_SINC700; interpolation_depth = 0.25; // because Gaussian window is twice as long break; case FCC_NORMAL: brent_depth = NUM_PEAK_INTERPOLATE_SINC70; interpolation_depth = 1.0; break; case FCC_ACCURATE: brent_depth = NUM_PEAK_INTERPOLATE_SINC700; interpolation_depth = 1.0; break; } duration = my dx * my nx; if (minimumPitch < periodsPerWindow / duration) Melder_throw (U"To analyse this Sound, ", U_LEFT_DOUBLE_QUOTE, U"minimum pitch", U_RIGHT_DOUBLE_QUOTE, U" must not be less than ", periodsPerWindow / duration, U" Hz."); /* * Determine the number of samples in the longest period. * We need this to compute the local mean of the sound (looking one period in both directions), * and to compute the local peak of the sound (looking half a period in both directions). */ nsamp_period = (long) floor (1 / my dx / minimumPitch); halfnsamp_period = nsamp_period / 2 + 1; if (ceiling > 0.5 / my dx) ceiling = 0.5 / my dx; /* * Determine window length in seconds and in samples. */ dt_window = periodsPerWindow / minimumPitch; nsamp_window = (long) floor (dt_window / my dx); halfnsamp_window = nsamp_window / 2 - 1; if (halfnsamp_window < 2) Melder_throw (U"Analysis window too short."); nsamp_window = halfnsamp_window * 2; /* * Determine the minimum and maximum lags. */ minimumLag = (long) floor (1 / my dx / ceiling); if (minimumLag < 2) minimumLag = 2; maximumLag = (long) floor (nsamp_window / periodsPerWindow) + 2; if (maximumLag > nsamp_window) maximumLag = nsamp_window; /* * Determine the number of frames. * Fit as many frames as possible symmetrically in the total duration. * We do this even for the forward cross-correlation method, * because that allows us to compare the two methods. */ try { Sampled_shortTermAnalysis (me, method >= FCC_NORMAL ? 1 / minimumPitch + dt_window : dt_window, dt, & nFrames, & t1); } catch (MelderError) { Melder_throw (U"The pitch analysis would give zero pitch frames."); } /* * Create the resulting pitch contour. */ autoPitch thee = Pitch_create (my xmin, my xmax, nFrames, dt, t1, ceiling, maxnCandidates); /* * Create (too much) space for candidates. */ for (long iframe = 1; iframe <= nFrames; iframe ++) { Pitch_Frame pitchFrame = & thy frame [iframe]; Pitch_Frame_init (pitchFrame, maxnCandidates); } /* * Compute the global absolute peak for determination of silence threshold. */ globalPeak = 0.0; for (long channel = 1; channel <= my ny; channel ++) { double mean = 0.0; for (long i = 1; i <= my nx; i ++) { mean += my z [channel] [i]; } mean /= my nx; for (long i = 1; i <= my nx; i ++) { double value = fabs (my z [channel] [i] - mean); if (value > globalPeak) globalPeak = value; } } if (globalPeak == 0.0) { return thee; } autoNUMvector window; autoNUMvector windowR; if (method >= FCC_NORMAL) { /* For cross-correlation analysis. */ nsampFFT = 0; brent_ixmax = (long) floor (nsamp_window * interpolation_depth); } else { /* For autocorrelation analysis. */ /* * Compute the number of samples needed for doing FFT. * To avoid edge effects, we have to append zeroes to the window. * The maximum lag considered for maxima is maximumLag. * The maximum lag used in interpolation is nsamp_window * interpolation_depth. */ nsampFFT = 1; while (nsampFFT < nsamp_window * (1 + interpolation_depth)) nsampFFT *= 2; /* * Create buffers for autocorrelation analysis. */ windowR.reset (1, nsampFFT); window.reset (1, nsamp_window); NUMfft_Table_init (& fftTable, nsampFFT); /* * A Gaussian or Hanning window is applied against phase effects. * The Hanning window is 2 to 5 dB better for 3 periods/window. * The Gaussian window is 25 to 29 dB better for 6 periods/window. */ if (method == AC_GAUSS) { /* Gaussian window. */ double imid = 0.5 * (nsamp_window + 1), edge = exp (-12.0); for (long i = 1; i <= nsamp_window; i ++) window [i] = (exp (-48.0 * (i - imid) * (i - imid) / (nsamp_window + 1) / (nsamp_window + 1)) - edge) / (1 - edge); } else { // Hanning window for (long i = 1; i <= nsamp_window; i ++) window [i] = 0.5 - 0.5 * cos (i * 2 * NUMpi / (nsamp_window + 1)); } /* * Compute the normalized autocorrelation of the window. */ for (long i = 1; i <= nsamp_window; i ++) windowR [i] = window [i]; NUMfft_forward (& fftTable, windowR.peek()); windowR [1] *= windowR [1]; // DC component for (long i = 2; i < nsampFFT; i += 2) { windowR [i] = windowR [i] * windowR [i] + windowR [i+1] * windowR [i+1]; windowR [i + 1] = 0.0; // power spectrum: square and zero } windowR [nsampFFT] *= windowR [nsampFFT]; // Nyquist frequency NUMfft_backward (& fftTable, windowR.peek()); // autocorrelation for (long i = 2; i <= nsamp_window; i ++) windowR [i] /= windowR [1]; // normalize windowR [1] = 1.0; // normalize brent_ixmax = (long) floor (nsamp_window * interpolation_depth); } autoMelderProgress progress (U"Sound to Pitch..."); long numberOfFramesPerThread = 20; int numberOfThreads = (nFrames - 1) / numberOfFramesPerThread + 1; const int numberOfProcessors = MelderThread_getNumberOfProcessors (); trace (numberOfProcessors, U" processors"); if (numberOfThreads > numberOfProcessors) numberOfThreads = numberOfProcessors; if (numberOfThreads > 16) numberOfThreads = 16; if (numberOfThreads < 1) numberOfThreads = 1; numberOfFramesPerThread = (nFrames - 1) / numberOfThreads + 1; if (! mutex_inited) { MelderThread_MUTEX_INIT (mutex); mutex_inited = true; } autoSound_into_Pitch_Args args [16]; long firstFrame = 1, lastFrame = numberOfFramesPerThread; volatile int cancelled = 0; for (int ithread = 1; ithread <= numberOfThreads; ithread ++) { if (ithread == numberOfThreads) lastFrame = nFrames; args [ithread - 1].reset (Sound_into_Pitch_Args_create (me, thee.peek(), firstFrame, lastFrame, minimumPitch, maxnCandidates, method, voicingThreshold, octaveCost, dt_window, nsamp_window, halfnsamp_window, maximumLag, nsampFFT, nsamp_period, halfnsamp_period, brent_ixmax, brent_depth, globalPeak, window.peek(), windowR.peek(), ithread == numberOfThreads, & cancelled)); firstFrame = lastFrame + 1; lastFrame += numberOfFramesPerThread; } MelderThread_run (Sound_into_Pitch, args, numberOfThreads); Melder_progress (0.95, U"Sound to Pitch: path finder"); Pitch_pathFinder (thee.peek(), silenceThreshold, voicingThreshold, octaveCost, octaveJumpCost, voicedUnvoicedCost, ceiling, Melder_debug == 31 ? true : false); return thee; } catch (MelderError) { Melder_throw (me, U": pitch analysis not performed."); } } autoPitch Sound_to_Pitch (Sound me, double timeStep, double minimumPitch, double maximumPitch) { return Sound_to_Pitch_ac (me, timeStep, minimumPitch, 3.0, 15, false, 0.03, 0.45, 0.01, 0.35, 0.14, maximumPitch); } autoPitch Sound_to_Pitch_ac (Sound me, double dt, double minimumPitch, double periodsPerWindow, int maxnCandidates, int accurate, double silenceThreshold, double voicingThreshold, double octaveCost, double octaveJumpCost, double voicedUnvoicedCost, double ceiling) { return Sound_to_Pitch_any (me, dt, minimumPitch, periodsPerWindow, maxnCandidates, accurate, silenceThreshold, voicingThreshold, octaveCost, octaveJumpCost, voicedUnvoicedCost, ceiling); } autoPitch Sound_to_Pitch_cc (Sound me, double dt, double minimumPitch, double periodsPerWindow, int maxnCandidates, int accurate, double silenceThreshold, double voicingThreshold, double octaveCost, double octaveJumpCost, double voicedUnvoicedCost, double ceiling) { return Sound_to_Pitch_any (me, dt, minimumPitch, periodsPerWindow, maxnCandidates, 2 + accurate, silenceThreshold, voicingThreshold, octaveCost, octaveJumpCost, voicedUnvoicedCost, ceiling); } /* End of file Sound_to_Pitch.cpp */ praat-6.0.04/fon/Sound_to_Pitch.h000066400000000000000000000077321261542461700166050ustar00rootroot00000000000000/* Sound_to_Pitch.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Sound.h" #include "Pitch.h" autoPitch Sound_to_Pitch (Sound me, double timeStep, double minimumPitch, double maximumPitch); /* Calls Sound_to_Pitch_ac with default arguments. */ autoPitch Sound_to_Pitch_ac (Sound me, double timeStep, double minimumPitch, double periodsPerWindow, int maxnCandidates, int accurate, double silenceThreshold, double voicingThreshold, double octaveCost, double octaveJumpCost, double voicedUnvoicedCost, double maximumPitch); /* Calls Sound_to_Pitch_any with AC method. */ autoPitch Sound_to_Pitch_cc (Sound me, double timeStep, double minimumPitch, double periodsPerWindow, int maxnCandidates, int accurate, double silenceThreshold, double voicingThreshold, double octaveCost, double octaveJumpCost, double voicedUnvoicedCost, double maximumPitch); /* Calls Sound_to_Pitch_any with FCC method. */ autoPitch Sound_to_Pitch_any (Sound me, double dt, /* time step (seconds); 0.0 = automatic = periodsPerWindow / minimumPitch / 4 */ double minimumPitch, /* (Hz) */ double periodsPerWindow, /* ac3 for pitch analysis, 6 or 4.5 for HNR, 1 for FCC */ int maxnCandidates, /* maximum number of candidates per frame */ int method, /* 0 or 1 = AC, 2 or 3 = FCC, 0 or 2 = fast, 1 or 3 = accurate */ double silenceThreshold, /* relative to purely periodic; default 0.03 */ double voicingThreshold, /* relative to purely periodic; default 0.45 */ double octaveCost, /* favours higher pitches; default 0.01 */ double octaveJumpCost, /* default 0.35 */ double voicedUnvoicedCost, /* default 0.14 */ double maximumPitch); /* (Hz) */ /* Function: acoustic periodicity analysis. Preconditions: minimumPitch > 0.0; maxnCandidates >= 2; Return value: the resulting pitch contour, or NULL in case of failure. Failures: Out of memory. Minimum frequency too low. Maximum frequency should not be greater than the Sound's Nyquist frequency. Description for method 0 or 1: There is a Hanning window (method == 0) or Gaussian window (method == 1) over the analysis window, in order to avoid phase effects. Zeroes are appended to the analysis window to avoid edge effects in the FFT. An FFT is done on the window, giving a complex spectrum. This complex spectrum is squared, thus giving the power spectrum. The power spectrum is FFTed back, thus giving the autocorrelation of the windowed frame. This autocorrelation is expressed relative to the power, which is the autocorrelation for lag 0. The autocorrelation is divided by the normalized autocorrelation of the window, in order to bring all maxima of the autocorrelation of a periodic signal to the same height. General description: The maxima are found by sinc interpolation. The pitch values (frequencies) of the highest 'maxnCandidates' maxima are saved in 'result', together with their strengths (relative correlations). A Viterbi algorithm is used to find a smooth path through the candidates, using the last six arguments of this function. The 'maximumPitch' argument has no influence on the search for candidates. It is directly copied into the Pitch object as a hint for considering pitches above a certain value "voiceless". */ /* End of file Sound_to_Pitch.h */ praat-6.0.04/fon/Sound_to_PointProcess.cpp000066400000000000000000000114071261542461700205130ustar00rootroot00000000000000/* Sound_to_PointProcess.cpp * * Copyright (C) 1992-2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2003/02/26 Sound_to_PointProcess_peaks * pb 2004/07/11 default time steps in Sound_to_Pitch * pb 2007/01/28 made compatible with stereo sounds * pb 2008/01/19 double * pb 2011/03/09 C++ */ #include "Sound_to_PointProcess.h" #include "Sound_to_Pitch.h" #include "Pitch_to_PointProcess.h" autoPointProcess Sound_to_PointProcess_extrema (Sound me, long channel, int interpolation, bool includeMaxima, bool includeMinima) { try { /* * Pass 1: count the extrema. There may be a maximum and minimum in the same interval! */ long numberOfMaxima = 0; long numberOfMinima = 0; double *y = my z [channel]; for (long i = 2; i <= my nx - 1; i ++) { if (includeMaxima && y [i] > y [i - 1] && y [i] >= y [i + 1]) numberOfMaxima ++; if (includeMinima && y [i] <= y [i - 1] && y [i] < y [i + 1]) numberOfMinima ++; } /* * Create the empty result. */ autoPointProcess thee = PointProcess_create (my xmin, my xmax, numberOfMaxima + numberOfMinima); /* * Pass 2: compute and register the extrema. */ for (long i = 2; i <= my nx - 1; i ++) { double time, i_real; if (includeMaxima && y [i] > y [i - 1] && y [i] >= y [i + 1]) { (void) NUMimproveMaximum (y, my nx, i, interpolation, & i_real); time = my x1 + (i_real - 1.0) * my dx; PointProcess_addPoint (thee.peek(), time); } if (includeMinima && y [i] <= y [i - 1] && y [i] < y [i + 1]) { (void) NUMimproveMinimum (y, my nx, i, interpolation, & i_real); time = my x1 + (i_real - 1.0) * my dx; PointProcess_addPoint (thee.peek(), time); } } return thee; } catch (MelderError) { Melder_throw (me, U": extrema not computed."); } } autoPointProcess Sound_to_PointProcess_maxima (Sound me, long channel, int interpolation) { return Sound_to_PointProcess_extrema (me, channel, interpolation, true, false); } autoPointProcess Sound_to_PointProcess_minima (Sound me, long channel, int interpolation) { return Sound_to_PointProcess_extrema (me, channel, interpolation, false, true); } autoPointProcess Sound_to_PointProcess_allExtrema (Sound me, long channel, int interpolation) { return Sound_to_PointProcess_extrema (me, channel, interpolation, true, true); } autoPointProcess Sound_to_PointProcess_zeroes (Sound me, long channel, bool includeRaisers, bool includeFallers) { try { /* * Pass 1: count the zeroes. */ long numberOfRaisers = 0; long numberOfFallers = 0; double *y = my z [channel]; for (long i = 2; i <= my nx; i ++) { if (includeRaisers && y [i - 1] < 0.0 && y [i] >= 0.0) numberOfRaisers ++; if (includeFallers && y [i - 1] >= 0.0 && y [i] < 0.0) numberOfFallers ++; } /* * Create the empty result. */ autoPointProcess thee = PointProcess_create (my xmin, my xmax, numberOfRaisers + numberOfFallers); /* * Pass 2: compute and register the zeroes. */ for (long i = 2; i <= my nx; i ++) { if ((includeRaisers && y [i - 1] < 0.0 && y [i] >= 0.0) || (includeFallers && y [i - 1] >= 0.0 && y [i] < 0.0)) { double time = Sampled_indexToX (me, i - 1) + my dx * y [i - 1] / (y [i - 1] - y [i]); // linear PointProcess_addPoint (thee.peek(), time); } } return thee; } catch (MelderError) { Melder_throw (me, U": zeroes not computed."); } } autoPointProcess Sound_to_PointProcess_periodic_cc (Sound me, double fmin, double fmax) { try { autoPitch pitch = Sound_to_Pitch (me, 0.0, fmin, fmax); autoPointProcess thee = Sound_Pitch_to_PointProcess_cc (me, pitch.get()); return thee; } catch (MelderError) { Melder_throw (me, U": periodic pulses (cc) not computed."); } } autoPointProcess Sound_to_PointProcess_periodic_peaks (Sound me, double fmin, double fmax, bool includeMaxima, bool includeMinima) { try { autoPitch pitch = Sound_to_Pitch (me, 0.0, fmin, fmax); autoPointProcess thee = Sound_Pitch_to_PointProcess_peaks (me, pitch.peek(), includeMaxima, includeMinima); return thee; } catch (MelderError) { Melder_throw (me, U": periodic pulses (peaks) not computed."); } } /* End of file Sound_to_PointProcess.cpp */ praat-6.0.04/fon/Sound_to_PointProcess.h000066400000000000000000000031171261542461700201570ustar00rootroot00000000000000/* Sound_to_PointProcess.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Sound.h" #include "PointProcess.h" autoPointProcess Sound_to_PointProcess_extrema (Sound me, long channel, int interpolation, bool includeMaxima, bool includeMinima); autoPointProcess Sound_to_PointProcess_maxima (Sound me, long channel, int interpolation); autoPointProcess Sound_to_PointProcess_minima (Sound me, long channel, int interpolation); autoPointProcess Sound_to_PointProcess_allExtrema (Sound me, long channel, int interpolation); autoPointProcess Sound_to_PointProcess_zeroes (Sound me, long channel, bool includeRaisers, bool includeFallers); autoPointProcess Sound_to_PointProcess_periodic_cc (Sound me, double fmin, double fmax); autoPointProcess Sound_to_PointProcess_periodic_peaks (Sound me, double fmin, double fmax, bool includeMaxima, bool includeMinima); /* End of file Sound_to_PointProcess.h */ praat-6.0.04/fon/Spectrogram.cpp000066400000000000000000000135121261542461700164760ustar00rootroot00000000000000/* Spectrogram.cpp * * Copyright (C) 1992-2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Spectrogram.h" Thing_implement (Spectrogram, Matrix, 2); void structSpectrogram :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Time domain:"); MelderInfo_writeLine (U" Start time: ", xmin, U" seconds"); MelderInfo_writeLine (U" End time: ", xmax, U" seconds"); MelderInfo_writeLine (U" Total duration: ", xmax - xmin, U" seconds"); MelderInfo_writeLine (U"Time sampling:"); MelderInfo_writeLine (U" Number of time slices (frames): ", nx); MelderInfo_writeLine (U" Time step (frame distance): ", dx, U" seconds"); MelderInfo_writeLine (U" First time slice (frame centre) at: ", x1, U" seconds"); MelderInfo_writeLine (U"Frequency domain:"); MelderInfo_writeLine (U" Lowest frequency: ", ymin, U" Hz"); MelderInfo_writeLine (U" Highest frequency: ", ymax, U" Hz"); MelderInfo_writeLine (U" Total bandwidth: ", ymax - ymin, U" Hz"); MelderInfo_writeLine (U"Frequency sampling:"); MelderInfo_writeLine (U" Number of frequency bands (bins): ", ny); MelderInfo_writeLine (U" Frequency step (bin width): ", dy, U" Hz"); MelderInfo_writeLine (U" First frequency band around (bin centre at): ", y1, U" Hz"); } autoSpectrogram Spectrogram_create (double tmin, double tmax, long nt, double dt, double t1, double fmin, double fmax, long nf, double df, double f1) { try { autoSpectrogram me = Thing_new (Spectrogram); Matrix_init (me.peek(), tmin, tmax, nt, dt, t1, fmin, fmax, nf, df, f1); return me; } catch (MelderError) { Melder_throw (U"Spectrogram not created."); } } void Spectrogram_paintInside (Spectrogram me, Graphics g, double tmin, double tmax, double fmin, double fmax, double maximum, int autoscaling, double dynamic, double preemphasis, double dynamicCompression) { if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } if (fmax <= fmin) { fmin = my ymin; fmax = my ymax; } long itmin, itmax, ifmin, ifmax; if (! Matrix_getWindowSamplesX (me, tmin - 0.49999 * my dx, tmax + 0.49999 * my dx, & itmin, & itmax) || ! Matrix_getWindowSamplesY (me, fmin - 0.49999 * my dy, fmax + 0.49999 * my dy, & ifmin, & ifmax)) return; Graphics_setWindow (g, tmin, tmax, fmin, fmax); autoNUMvector preemphasisFactor (ifmin, ifmax); autoNUMvector dynamicFactor (itmin, itmax); /* Pre-emphasis in place; also compute maximum after pre-emphasis. */ for (long ifreq = ifmin; ifreq <= ifmax; ifreq ++) { preemphasisFactor [ifreq] = (preemphasis / NUMln2) * log (ifreq * my dy / 1000.0); for (long itime = itmin; itime <= itmax; itime ++) { double value = my z [ifreq] [itime]; /* Power. */ value = (10.0/NUMln10) * log ((value + 1e-30) / 4.0e-10) + preemphasisFactor [ifreq]; /* dB */ if (value > dynamicFactor [itime]) dynamicFactor [itime] = value; /* Local maximum. */ my z [ifreq] [itime] = value; } } /* Compute global maximum. */ if (autoscaling) { maximum = 0.0; for (long itime = itmin; itime <= itmax; itime ++) if (dynamicFactor [itime] > maximum) maximum = dynamicFactor [itime]; } /* Dynamic compression in place. */ for (long itime = itmin; itime <= itmax; itime ++) { dynamicFactor [itime] = dynamicCompression * (maximum - dynamicFactor [itime]); for (long ifreq = ifmin; ifreq <= ifmax; ifreq ++) my z [ifreq] [itime] += dynamicFactor [itime]; } Graphics_image (g, my z, itmin, itmax, Matrix_columnToX (me, itmin - 0.5), Matrix_columnToX (me, itmax + 0.5), ifmin, ifmax, Matrix_rowToY (me, ifmin - 0.5), Matrix_rowToY (me, ifmax + 0.5), maximum - dynamic, maximum); for (long ifreq = ifmin; ifreq <= ifmax; ifreq ++) for (long itime = itmin; itime <= itmax; itime ++) { double value = 4.0e-10 * exp ((my z [ifreq] [itime] - dynamicFactor [itime] - preemphasisFactor [ifreq]) * (NUMln10 / 10.0)) - 1e-30; my z [ifreq] [itime] = value > 0.0 ? value : 0.0; } } void Spectrogram_paint (Spectrogram me, Graphics g, double tmin, double tmax, double fmin, double fmax, double maximum, int autoscaling, double dynamic, double preemphasis, double dynamicCompression, int garnish) { Graphics_setInner (g); Spectrogram_paintInside (me, g, tmin, tmax, fmin, fmax, maximum, autoscaling, dynamic, preemphasis, dynamicCompression); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Time (s)"); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); Graphics_textLeft (g, true, U"Frequency (Hz)"); } } autoSpectrogram Matrix_to_Spectrogram (Matrix me) { try { autoSpectrogram thee = Spectrogram_create (my xmin, my xmax, my nx, my dx, my x1, my ymin, my ymax, my ny, my dy, my y1); NUMmatrix_copyElements (my z, thy z, 1, my ny, 1, my nx); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Spectrogram."); } } autoMatrix Spectrogram_to_Matrix (Spectrogram me) { try { autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, my ymin, my ymax, my ny, my dy, my y1); NUMmatrix_copyElements (my z, thy z, 1, my ny, 1, my nx); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Matrix."); } } /* End of Spectrogram.cpp */ praat-6.0.04/fon/Spectrogram.h000066400000000000000000000064731261542461700161530ustar00rootroot00000000000000#ifndef _Spectrogram_h_ #define _Spectrogram_h_ /* Spectrogram.h * * Copyright (C) 1992-2011,2015 David Weenink & Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Matrix.h" #include "Graphics.h" Thing_define (Spectrogram, Matrix) { void v_info () override; int v_domainQuantity () override { return MelderQuantity_TIME_SECONDS; } }; /* Attributes: xmin // Start time (seconds). xmax // End time (seconds). nx // Number of time slices. dx // The time between two subsequent time slices. x1 // The centre of the first time slice. ymin // Minimum frequency (Hz). ymax // Maximum frequency (Hz). dy // Frequency step (Hz). y1 // Centre of first frequency band (Hz). z [iy] [ix] // Power spectrum density. */ autoSpectrogram Spectrogram_create (double tmin, double tmax, long nt, double dt, double t1, double fmin, double fmax, long nf, double df, double f1); /* Function: Create the spectrogram data structure. Preconditions: nt > 0; nf > 0; dt > 0.0; df > 0.0; Postconditions: result -> xmin = tmin; result -> ymin = fmin; result -> xmax = tmax; result -> ymax = fmax; result -> nx = nt; result -> ny = nf; result -> dx = dt; result -> dy = df; result -> x1 = t1; result -> y1 = f1; result -> z [1..nf] [1..nt] = 0.0; */ void Spectrogram_paintInside (Spectrogram me, Graphics g, double tmin, double tmax, double fmin, double fmax, double maximum, int autoscaling, double dynamicRange, double preemphasis, double dynamicCompression); void Spectrogram_paint (Spectrogram me, Graphics g, double tmin, double tmax, double fmin, double fmax, double maximum, int autoscaling, double dynamicRange, double preemphasis, double dynamicCompression, int garnish); /* Function: Draw me to a Graphics. If tmax <= tmin, draw all time samples. If fmax <= fmin, draw all frequency bands. Arguments: dynamicRange (dB): the difference between the maximum intensity and the lowest visible intensity. preemphasis (dB/octave): high-pass filtering. dynamicCompression (0-1): the amount by which weaker frames are enhanced in the direction of the strongest frame; 0 = no compression, 1 = complete compression (all frames shown equally strong). garnish: a boolean that determines if a box, ticks, numbers, and text are written in the margins. */ autoSpectrogram Matrix_to_Spectrogram (Matrix me); /* Create a Spectrogram from a Matrix, with deep copy of all its attributes, except class information and methods. */ autoMatrix Spectrogram_to_Matrix (Spectrogram me); /* Create a Matrix from a Spectrogram, with deep copy of all its attributes, except class information and methods. */ /* End of file Spectrogram.h */ #endif praat-6.0.04/fon/SpectrogramEditor.cpp000066400000000000000000000065101261542461700176450ustar00rootroot00000000000000/* SpectrogramEditor.cpp * * Copyright (C) 1992-2011,2012,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "SpectrogramEditor.h" Thing_implement (SpectrogramEditor, FunctionEditor, 0); void structSpectrogramEditor :: v_draw () { Spectrogram spectrogram = (Spectrogram) our data; Graphics_setWindow (our d_graphics, 0, 1, 0, 1); Graphics_setColour (our d_graphics, Graphics_WHITE); Graphics_fillRectangle (our d_graphics, 0, 1, 0, 1); Graphics_setColour (our d_graphics, Graphics_BLACK); Graphics_rectangle (our d_graphics, 0, 1, 0, 1); long itmin, itmax; Sampled_getWindowSamples (spectrogram, our d_startWindow, our d_endWindow, & itmin, & itmax); /* * Autoscale frequency axis. */ our maximum = spectrogram -> ymax; Graphics_setWindow (our d_graphics, our d_startWindow, our d_endWindow, 0.0, our maximum); Spectrogram_paintInside (spectrogram, our d_graphics, our d_startWindow, our d_endWindow, 0, 0, 0.0, true, 60, 6.0, 0); /* * Horizontal scaling lines. */ Graphics_setWindow (our d_graphics, 0.0, 1.0, 0.0, our maximum); Graphics_setTextAlignment (our d_graphics, Graphics_RIGHT, Graphics_HALF); Graphics_setColour (our d_graphics, Graphics_RED); long df = 1000; for (long f = df; f <= our maximum; f += df) { Graphics_line (our d_graphics, 0.0, f, 1.0, f); Graphics_text (our d_graphics, -0.01, f, f, U" Hz"); } /* * Vertical cursor lines. */ Graphics_setWindow (our d_graphics, our d_startWindow, our d_endWindow, 0.0, our maximum); if (our d_startSelection > our d_startWindow && our d_startSelection < our d_endWindow) Graphics_line (our d_graphics, our d_startSelection, 0, our d_startSelection, our maximum); if (our d_endSelection > our d_startWindow && d_endSelection < d_endWindow) Graphics_line (our d_graphics, our d_endSelection, 0, our d_endSelection, our maximum); Graphics_setColour (our d_graphics, Graphics_BLACK); } int structSpectrogramEditor :: v_click (double xWC, double yWC, bool shiftKeyPressed) { Spectrogram spectrogram = (Spectrogram) our data; /*double frequency = yWC * our maximum;*/ long bestFrame; bestFrame = Sampled_xToNearestIndex (spectrogram, xWC); if (bestFrame < 1) bestFrame = 1; else if (bestFrame > spectrogram -> nx) bestFrame = spectrogram -> nx; return our SpectrogramEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed); } autoSpectrogramEditor SpectrogramEditor_create (const char32 *title, Spectrogram data) { try { autoSpectrogramEditor me = Thing_new (SpectrogramEditor); FunctionEditor_init (me.peek(), title, data); my maximum = 10000.0; return me; } catch (MelderError) { Melder_throw (U"Spectrogram window not created."); } } /* End of file SpectrogramEditor.cpp */ praat-6.0.04/fon/SpectrogramEditor.h000066400000000000000000000022611261542461700173110ustar00rootroot00000000000000#ifndef _SpectrogramEditor_h_ #define _SpectrogramEditor_h_ /* SpectrogramEditor.h * * Copyright (C) 1992-2011,2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "FunctionEditor.h" #include "Spectrogram.h" Thing_define (SpectrogramEditor, FunctionEditor) { double maximum; void v_draw () override; int v_click (double xWC, double yWC, bool shiftKeyPressed) override; }; autoSpectrogramEditor SpectrogramEditor_create (const char32 *title, Spectrogram data); /* End of file SpectrogramEditor.h */ #endif praat-6.0.04/fon/Spectrum.cpp000066400000000000000000000423601261542461700160150ustar00rootroot00000000000000/* Spectrum.cpp * * Copyright (C) 1992-2012,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * a selection of changes: * pb 2001/11/30 Spectral moments * pb 2002/05/22 changed sign of imaginary part * pb 2006/02/06 better cepstral smoothing */ #include "Sound_and_Spectrum.h" #include "SpectrumTier.h" #include "oo_DESTROY.h" #include "Spectrum_def.h" #include "oo_COPY.h" #include "Spectrum_def.h" #include "oo_EQUAL.h" #include "Spectrum_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Spectrum_def.h" #include "oo_WRITE_TEXT.h" #include "Spectrum_def.h" #include "oo_READ_TEXT.h" #include "Spectrum_def.h" #include "oo_WRITE_BINARY.h" #include "Spectrum_def.h" #include "oo_READ_BINARY.h" #include "Spectrum_def.h" #include "oo_DESCRIPTION.h" #include "Spectrum_def.h" Thing_implement (Spectrum, Matrix, 2); void structSpectrum :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Frequency domain:"); MelderInfo_writeLine (U" Lowest frequency: ", xmin, U" Hz"); MelderInfo_writeLine (U" Highest frequency: ", xmax, U" Hz"); MelderInfo_writeLine (U" Total bandwidth: ", xmax - xmin, U" Hz"); MelderInfo_writeLine (U"Frequency sampling:"); MelderInfo_writeLine (U" Number of frequency bands (bins): ", nx); MelderInfo_writeLine (U" Frequency step (bin width): ", dx, U" Hz"); MelderInfo_writeLine (U" First frequency band around (bin centre at): ", x1, U" Hz"); MelderInfo_writeLine (U"Total energy: ", Melder_single (Spectrum_getBandEnergy (this, 0.0, 0.0)), U" Pa2 sec"); } double structSpectrum :: v_getValueAtSample (long isamp, long which, int units) { if (units == 0) { return which == 1 ? z [1] [isamp] : which == 2 ? z [2] [isamp] : NUMundefined; } else { /* * The energy in a bin is 2 * (re^2 + im^2) times the bin width. * The factor of 2 derives from the assumption that the spectrum contains positive-frequency values only, * and that the negative-frequency values have the same norm, since they are the complex conjugates * of the positive-frequency values. */ double energyDensity = 2.0 * (z [1] [isamp] * z [1] [isamp] + z [2] [isamp] * z [2] [isamp]); /* Pa2/Hz2; sum of positive and negative frequencies */ if (units == 1) { return energyDensity; } else { double powerDensity = energyDensity * dx; /* Pa^2 Hz-2 s-1, after division by approximate duration */ if (units == 2) { /* "dB/Hz" */ return powerDensity == 0.0 ? -300.0 : 10.0 * log10 (powerDensity / 4.0e-10); } } } return NUMundefined; } autoSpectrum Spectrum_create (double fmax, long nf) { try { autoSpectrum me = Thing_new (Spectrum); Matrix_init (me.peek(), 0.0, fmax, nf, fmax / (nf - 1), 0.0, 1.0, 2.0, 2, 1.0, 1.0); return me; } catch (MelderError) { Melder_throw (U"Spectrum not created."); } } int Spectrum_getPowerDensityRange (Spectrum me, double *minimum, double *maximum) { *minimum = 1e308, *maximum = 0.0; for (long ifreq = 1; ifreq <= my nx; ifreq ++) { double oneSidedPowerSpectralDensity = /* Pa2 Hz-2 s-1 */ 2.0 * (my z [1] [ifreq] * my z [1] [ifreq] + my z [2] [ifreq] * my z [2] [ifreq]) * my dx; if (oneSidedPowerSpectralDensity < *minimum) *minimum = oneSidedPowerSpectralDensity; if (oneSidedPowerSpectralDensity > *maximum) *maximum = oneSidedPowerSpectralDensity; } if (*maximum == 0.0) return 0; *minimum = 10 * log10 (*minimum / 4.0e-10); *maximum = 10 * log10 (*maximum / 4.0e-10); return 1; } void Spectrum_drawInside (Spectrum me, Graphics g, double fmin, double fmax, double minimum, double maximum) { bool autoscaling = ( minimum >= maximum ); if (fmax <= fmin) { fmin = my xmin; fmax = my xmax; } long ifmin, ifmax; if (! Matrix_getWindowSamplesX (me, fmin, fmax, & ifmin, & ifmax)) return; autoNUMvector yWC (ifmin, ifmax); /* * First pass: compute power density. */ if (autoscaling) maximum = -1e30; for (long ifreq = ifmin; ifreq <= ifmax; ifreq ++) { double y = my v_getValueAtSample (ifreq, 0, 2); if (autoscaling && y > maximum) maximum = y; yWC [ifreq] = y; } if (autoscaling) minimum = maximum - 60; /* Default dynamic range is 60 dB. */ /* * Second pass: clip. */ for (long ifreq = ifmin; ifreq <= ifmax; ifreq ++) { if (yWC [ifreq] < minimum) yWC [ifreq] = minimum; else if (yWC [ifreq] > maximum) yWC [ifreq] = maximum; } Graphics_setWindow (g, fmin, fmax, minimum, maximum); Graphics_function (g, yWC.peek(), ifmin, ifmax, Matrix_columnToX (me, ifmin), Matrix_columnToX (me, ifmax)); } void Spectrum_draw (Spectrum me, Graphics g, double fmin, double fmax, double minimum, double maximum, int garnish) { Graphics_setInner (g); Spectrum_drawInside (me, g, fmin, fmax, minimum, maximum); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Frequency (Hz)"); Graphics_marksBottom (g, 2, true, true, false); Graphics_textLeft (g, true, U"Sound pressure level (dB/Hz)"); Graphics_marksLeftEvery (g, 1.0, 20.0, true, true, false); } } void Spectrum_drawLogFreq (Spectrum me, Graphics g, double fmin, double fmax, double minimum, double maximum, int garnish) { bool autoscaling = ( minimum >= maximum ); if (fmax <= fmin) { fmin = my xmin; fmax = my xmax; } long ifmin, ifmax; if (! Matrix_getWindowSamplesX (me, fmin, fmax, & ifmin, & ifmax)) return; if(ifmin==1)ifmin=2; /* BUG */ autoNUMvector xWC (ifmin, ifmax); autoNUMvector yWC (ifmin, ifmax); /* * First pass: compute power density. */ if (autoscaling) maximum = -1e6; for (long ifreq = ifmin; ifreq <= ifmax; ifreq ++) { xWC [ifreq] = log10 (my x1 + (ifreq - 1) * my dx); yWC [ifreq] = my v_getValueAtSample (ifreq, 0, 2); if (autoscaling && yWC [ifreq] > maximum) maximum = yWC [ifreq]; } if (autoscaling) minimum = maximum - 60; // default dynamic range is 60 dB /* * Second pass: clip. */ for (long ifreq = ifmin; ifreq <= ifmax; ifreq ++) { if (yWC [ifreq] < minimum) yWC [ifreq] = minimum; else if (yWC [ifreq] > maximum) yWC [ifreq] = maximum; } Graphics_setInner (g); Graphics_setWindow (g, log10 (fmin), log10 (fmax), minimum, maximum); Graphics_polyline (g, ifmax - ifmin + 1, & xWC [ifmin], & yWC [ifmin]); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Frequency (Hz)"); Graphics_marksBottomLogarithmic (g, 3, true, true, false); Graphics_textLeft (g, true, U"Sound pressure level (dB/Hz)"); Graphics_marksLeftEvery (g, 1.0, 20.0, true, true, false); } } autoTable Spectrum_downto_Table (Spectrum me, bool includeBinNumbers, bool includeFrequency, bool includeRealPart, bool includeImaginaryPart, bool includeEnergyDensity, bool includePowerDensity) { try { autoTable thee = Table_createWithoutColumnNames (my nx, includeBinNumbers + includeFrequency + includeRealPart + includeImaginaryPart + includeEnergyDensity + includePowerDensity); long icol = 0; if (includeBinNumbers) Table_setColumnLabel (thee.peek(), ++ icol, U"bin"); if (includeFrequency) Table_setColumnLabel (thee.peek(), ++ icol, U"freq(Hz)"); if (includeRealPart) Table_setColumnLabel (thee.peek(), ++ icol, U"re(Pa/Hz)"); if (includeImaginaryPart) Table_setColumnLabel (thee.peek(), ++ icol, U"im(Pa/Hz)"); if (includeEnergyDensity) Table_setColumnLabel (thee.peek(), ++ icol, U"energy(Pa^2/Hz^2)"); if (includePowerDensity) Table_setColumnLabel (thee.peek(), ++ icol, U"pow(dB/Hz)"); for (long ibin = 1; ibin <= my nx; ibin ++) { icol = 0; if (includeBinNumbers) Table_setNumericValue (thee.peek(), ibin, ++ icol, ibin); if (includeFrequency) Table_setNumericValue (thee.peek(), ibin, ++ icol, my x1 + (ibin - 1) * my dx); if (includeRealPart) Table_setNumericValue (thee.peek(), ibin, ++ icol, my z [1] [ibin]); if (includeImaginaryPart) Table_setNumericValue (thee.peek(), ibin, ++ icol, my z [2] [ibin]); if (includeEnergyDensity) Table_setNumericValue (thee.peek(), ibin, ++ icol, Sampled_getValueAtSample (me, ibin, 0, 1)); if (includePowerDensity) Table_setNumericValue (thee.peek(), ibin, ++ icol, Sampled_getValueAtSample (me, ibin, 0, 2)); } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Table."); } } void Spectrum_list (Spectrum me, bool includeBinNumbers, bool includeFrequency, bool includeRealPart, bool includeImaginaryPart, bool includeEnergyDensity, bool includePowerDensity) { try { autoTable table = Spectrum_downto_Table (me, includeBinNumbers, includeFrequency, includeRealPart, includeImaginaryPart, includeEnergyDensity, includePowerDensity); Table_list (table.peek(), false); } catch (MelderError) { Melder_throw (me, U": not listed."); } } autoSpectrum Matrix_to_Spectrum (Matrix me) { try { if (my ny != 2) Melder_throw (U"Matrix must have exactly 2 rows."); autoSpectrum thee = Thing_new (Spectrum); my structMatrix :: v_copy (thee.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Spectrum."); } } autoMatrix Spectrum_to_Matrix (Spectrum me) { try { autoMatrix thee = Thing_new (Matrix); my structMatrix :: v_copy (thee.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Matrix."); } } autoSpectrum Spectrum_cepstralSmoothing (Spectrum me, double bandWidth) { try { /* * dB-spectrum is log (power). */ autoSpectrum dBspectrum = Data_copy (me); double *re = dBspectrum -> z [1], *im = dBspectrum -> z [2]; for (long i = 1; i <= dBspectrum -> nx; i ++) { re [i] = log (re [i] * re [i] + im [i] * im [i] + 1e-308); im [i] = 0.0; } /* * Cepstrum is Fourier transform of dB-spectrum. */ autoSound cepstrum = Spectrum_to_Sound (dBspectrum.peek()); /* * Multiply cepstrum by a Gaussian. */ double factor = - bandWidth * bandWidth; for (long i = 1; i <= cepstrum -> nx; i ++) { double t = (i - 1) * cepstrum -> dx; cepstrum -> z [1] [i] *= exp (factor * t * t) * ( i == 1 ? 1.0 : 2.0 ); } /* * Smoothed power spectrum is original power spectrum convolved with a Gaussian. */ autoSpectrum thee = Sound_to_Spectrum (cepstrum.peek(), true); /* * Convert power spectrum back into a "complex" spectrum without phase information. */ re = thy z [1], im = thy z [2]; for (long i = 1; i <= thy nx; i ++) { re [i] = exp (0.5 * re [i]); // i.e., sqrt (exp (re [i])) im [i] = 0.0; } return thee; } catch (MelderError) { Melder_throw (me, U": cepstral smoothing not computed."); } } void Spectrum_passHannBand (Spectrum me, double fmin, double fmax0, double smooth) { double fmax = fmax0 == 0.0 ? my xmax : fmax0; double f1 = fmin - smooth, f2 = fmin + smooth, f3 = fmax - smooth, f4 = fmax + smooth; double halfpibysmooth = smooth != 0.0 ? NUMpi / (2.0 * smooth) : 0.0; double *re = my z [1], *im = my z [2]; for (long i = 1; i <= my nx; i ++) { double frequency = my x1 + (i - 1) * my dx; if (frequency < f1 || frequency > f4) re [i] = im [i] = 0.0; if (frequency < f2 && fmin > 0.0) { double factor = 0.5 - 0.5 * cos (halfpibysmooth * (frequency - f1)); re [i] *= factor; im [i] *= factor; } else if (frequency > f3 && fmax < my xmax) { double factor = 0.5 + 0.5 * cos (halfpibysmooth * (frequency - f3)); re [i] *= factor; im [i] *= factor; } } } void Spectrum_stopHannBand (Spectrum me, double fmin, double fmax0, double smooth) { double fmax = fmax0 == 0.0 ? my xmax : fmax0; double f1 = fmin - smooth, f2 = fmin + smooth, f3 = fmax - smooth, f4 = fmax + smooth; double halfpibysmooth = smooth != 0.0 ? NUMpi / (2.0 * smooth) : 0.0; double *re = my z [1], *im = my z [2]; for (long i = 1; i <= my nx; i ++) { double frequency = my x1 + (i - 1) * my dx; if (frequency < f1 || frequency > f4) continue; if (frequency < f2 && fmin > 0.0) { double factor = 0.5 + 0.5 * cos (halfpibysmooth * (frequency - f1)); re [i] *= factor; im [i] *= factor; } else if (frequency > f3 && fmax < my xmax) { double factor = 0.5 - 0.5 * cos (halfpibysmooth * (frequency - f3)); re [i] *= factor; im [i] *= factor; } else re [i] = im [i] = 0.0; } } double Spectrum_getBandEnergy (Spectrum me, double fmin, double fmax) { /* * The computation requires that the negative-frequency values are the complex conjugates * of the positive-frequency values, and that only the positive-frequency values are included * in the spectrum. */ if (my xmin < 0.0) return NUMundefined; /* * Any energy outside [my xmin, my xmax] is ignored. * This is very important, since my xmin and my xmax determine the meaning of the first and last bins; see below. * * The width of most bins is my dx, but the first and last bins can be truncated by fmin and fmax. * * This truncation even applies in the case of autowindowing, * i.e. if the total energy in the spectrum is computed. * In that case, the first and last bins can be truncated by my xmin and my xmax. * This happens almost always for the first bin, * which is usually centred at f=0, hence has a width of 0.5 * my dx, * and quite often for the last bin as well (namely if the original sound had an even number of samples), * which is then centred at f=nyquist, hence has a width of 0.5 * my dx. * * All this truncation is automatically performed by Sampled_getMean (). */ return Sampled_getIntegral (me, fmin, fmax, 0, 1, false); } double Spectrum_getBandDensity (Spectrum me, double fmin, double fmax) { if (my xmin < 0.0) return NUMundefined; // no negative frequencies allowed in one-sided spectral density return Sampled_getMean (me, fmin, fmax, 0, 1, false); } double Spectrum_getBandDensityDifference (Spectrum me, double lowBandMin, double lowBandMax, double highBandMin, double highBandMax) { double lowBandDensity = Spectrum_getBandDensity (me, lowBandMin, lowBandMax); double highBandDensity = Spectrum_getBandDensity (me, highBandMin, highBandMax); if (lowBandDensity == NUMundefined || highBandDensity == NUMundefined) return NUMundefined; if (lowBandDensity == 0.0 || highBandDensity == 0.0) return NUMundefined; return 10 * log10 (highBandDensity / lowBandDensity); } double Spectrum_getBandEnergyDifference (Spectrum me, double lowBandMin, double lowBandMax, double highBandMin, double highBandMax) { double lowBandEnergy = Spectrum_getBandEnergy (me, lowBandMin, lowBandMax); double highBandEnergy = Spectrum_getBandEnergy (me, highBandMin, highBandMax); if (lowBandEnergy == NUMundefined || highBandEnergy == NUMundefined) return NUMundefined; if (lowBandEnergy == 0.0 || highBandEnergy == 0.0) return NUMundefined; return 10.0 * log10 (highBandEnergy / lowBandEnergy); } double Spectrum_getCentreOfGravity (Spectrum me, double power) { double halfpower = 0.5 * power, sumenergy = 0.0, sumfenergy = 0.0; for (long i = 1; i <= my nx; i ++) { double re = my z [1] [i], im = my z [2] [i], energy = re * re + im * im; double f = my x1 + (i - 1) * my dx; if (halfpower != 1.0) energy = pow (energy, halfpower); sumenergy += energy; sumfenergy += f * energy; } return sumenergy == 0.0 ? NUMundefined : sumfenergy / sumenergy; } double Spectrum_getCentralMoment (Spectrum me, double moment, double power) { double halfpower = 0.5 * power, sumenergy = 0.0, sumfenergy = 0.0; double fmean = Spectrum_getCentreOfGravity (me, power); if (fmean == NUMundefined) return NUMundefined; for (long i = 1; i <= my nx; i ++) { double re = my z [1] [i], im = my z [2] [i], energy = re * re + im * im; double f = my x1 + (i - 1) * my dx; if (halfpower != 1.0) energy = pow (energy, halfpower); sumenergy += energy; sumfenergy += pow (f - fmean, moment) * energy; } return sumfenergy / sumenergy; } double Spectrum_getStandardDeviation (Spectrum me, double power) { return sqrt (Spectrum_getCentralMoment (me, 2.0, power)); } double Spectrum_getSkewness (Spectrum me, double power) { double m2 = Spectrum_getCentralMoment (me, 2.0, power); double m3 = Spectrum_getCentralMoment (me, 3.0, power); if (m2 == NUMundefined || m3 == NUMundefined || m2 == 0.0) return NUMundefined; return m3 / (m2 * sqrt (m2)); } double Spectrum_getKurtosis (Spectrum me, double power) { double m2 = Spectrum_getCentralMoment (me, 2.0, power); double m4 = Spectrum_getCentralMoment (me, 4.0, power); if (m2 == NUMundefined || m4 == NUMundefined || m2 == 0.0) return NUMundefined; return m4 / (m2 * m2) - 3; } void Spectrum_getNearestMaximum (Spectrum me, double frequency, double *frequencyOfMaximum, double *heightOfMaximum) { try { autoSpectrumTier thee = Spectrum_to_SpectrumTier_peaks (me); long index = AnyTier_timeToNearestIndex (thee.peek(), frequency); if (index == 0) Melder_throw (U"No peak."); RealPoint point = (RealPoint) thy points -> item [index]; *frequencyOfMaximum = point -> number; *heightOfMaximum = point -> value; } catch (MelderError) { Melder_throw (me, U": no nearest maximum found."); } } /* End of file Spectrum.cpp */ praat-6.0.04/fon/Spectrum.h000066400000000000000000000100471261542461700154570ustar00rootroot00000000000000#ifndef _Spectrum_h_ #define _Spectrum_h_ /* Spectrum.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Complex spectrum. */ /* If it comes from a sound (expressed in Pa), the values are expressed in Pa/Hz. */ #include "Matrix.h" #include "Graphics.h" #include "Spectrum_def.h" oo_CLASS_CREATE (Spectrum, Matrix); /* xmin // lowest frequency (Hz) xmax // highest frequency (Hz) nx // number of frequencies dx // frequency step (Hz) x1 // first frequency (Hz) ymin = 1 // first row: real part ymax = 2 // second row: imaginary part ny = 2 // two rows dy = 1; y1 = 1 // y is row number */ autoSpectrum Spectrum_create (double fmax, long nf); /* Preconditions: fmax > 0.0; nf >= 2; Postconditions: my xmin == 0.0; my xmax == fmax; my nx == nf; my dx == fmax / (nx - 1); my x1 == 0.0; my ymin == 1; my ymax == 2; my ny == 2; my dy == 1; my y1 == 1; my z [1..ny] [1..nx] == 0.0; */ int Spectrum_getPowerDensityRange (Spectrum me, double *minimum, double *maximum); /* Return 0 if all zeroes. */ double Spectrum_getBandDensity (Spectrum me, double fmin, double fmax); /* Pa2 / Hz2 */ double Spectrum_getBandEnergy (Spectrum me, double fmin, double fmax); /* Pa2 sec */ double Spectrum_getBandDensityDifference (Spectrum me, double lowBandMin, double lowBandMax, double highBandMin, double HighBandMax); double Spectrum_getBandEnergyDifference (Spectrum me, double lowBandMin, double lowBandMax, double highBandMin, double highBandMax); /* Spectral moments. */ double Spectrum_getCentreOfGravity (Spectrum me, double power); double Spectrum_getCentralMoment (Spectrum me, double moment, double power); double Spectrum_getStandardDeviation (Spectrum me, double power); double Spectrum_getSkewness (Spectrum me, double power); double Spectrum_getKurtosis (Spectrum me, double power); void Spectrum_drawInside (Spectrum me, Graphics g, double fmin, double fmax, double minimum, double maximum); void Spectrum_draw (Spectrum me, Graphics g, double fmin, double fmax, double minimum, double maximum, int garnish); /* Function: draw a Spectrum into a Graphics. Preconditions: maximum > minimum; Arguments: [fmin, fmax]: frequencies in Hz; x domain of drawing; Autowindowing: if fmax <= fmin, x domain of drawing is [my xmin, my xmax]. [minimum, maximum]: power in dB/Hz; y range of drawing. */ void Spectrum_drawLogFreq (Spectrum me, Graphics g, double fmin, double fmax, double minimum, double maximum, int garnish); autoTable Spectrum_downto_Table (Spectrum me, bool includeBinNumbers, bool includeFrequency, bool includeRealPart, bool includeImaginaryPart, bool includeEnergyDensity, bool includePowerDensity); void Spectrum_list (Spectrum me, bool includeBinNumbers, bool includeFrequency, bool includeRealPart, bool includeImaginaryPart, bool includeEnergyDensity, bool includePowerDensity); autoSpectrum Matrix_to_Spectrum (Matrix me); autoMatrix Spectrum_to_Matrix (Spectrum me); autoSpectrum Spectrum_cepstralSmoothing (Spectrum me, double bandWidth); void Spectrum_passHannBand (Spectrum me, double fmin, double fmax, double smooth); void Spectrum_stopHannBand (Spectrum me, double fmin, double fmax, double smooth); void Spectrum_getNearestMaximum (Spectrum me, double frequency, double *frequencyOfMaximum, double *heightOfMaximum); /* End of file Spectrum.h */ #endif praat-6.0.04/fon/SpectrumEditor.cpp000066400000000000000000000202511261542461700171570ustar00rootroot00000000000000/* SpectrumEditor.cpp * * Copyright (C) 1992-2011,2012,2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "SpectrumEditor.h" #include "Sound_and_Spectrum.h" #include "EditorM.h" Thing_implement (SpectrumEditor, FunctionEditor, 0); #include "prefs_define.h" #include "SpectrumEditor_prefs.h" #include "prefs_install.h" #include "SpectrumEditor_prefs.h" #include "prefs_copyToInstance.h" #include "SpectrumEditor_prefs.h" static void updateRange (SpectrumEditor me) { if (Spectrum_getPowerDensityRange ((Spectrum) my data, & my minimum, & my maximum)) { my minimum = my maximum - my p_dynamicRange; } else { my minimum = -1000, my maximum = 1000; } } void structSpectrumEditor :: v_dataChanged () { updateRange (this); SpectrumEditor_Parent :: v_dataChanged (); } void structSpectrumEditor :: v_draw () { Spectrum spectrum = (Spectrum) our data; Graphics_setWindow (our d_graphics, 0, 1, 0, 1); Graphics_setColour (our d_graphics, Graphics_WHITE); Graphics_fillRectangle (our d_graphics, 0, 1, 0, 1); Graphics_setColour (our d_graphics, Graphics_BLACK); Graphics_rectangle (our d_graphics, 0, 1, 0, 1); Spectrum_drawInside (spectrum, our d_graphics, our d_startWindow, our d_endWindow, our minimum, our maximum); FunctionEditor_drawRangeMark (this, our maximum, Melder_fixed (maximum, 1), U" dB", Graphics_TOP); FunctionEditor_drawRangeMark (this, our minimum, Melder_fixed (minimum, 1), U" dB", Graphics_BOTTOM); if (our cursorHeight > our minimum && our cursorHeight < our maximum) FunctionEditor_drawHorizontalHair (this, our cursorHeight, Melder_fixed (our cursorHeight, 1), U" dB"); Graphics_setColour (our d_graphics, Graphics_BLACK); /* Update buttons. */ long first, last; long selectedSamples = Sampled_getWindowSamples (spectrum, our d_startSelection, our d_endSelection, & first, & last); GuiThing_setSensitive (our publishBandButton, selectedSamples != 0); GuiThing_setSensitive (our publishSoundButton, selectedSamples != 0); } int structSpectrumEditor :: v_click (double xWC, double yWC, bool shiftKeyPressed) { our cursorHeight = our minimum + yWC * (our maximum - our minimum); return our SpectrumEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed); // move cursor or drag selection } static Spectrum Spectrum_band (Spectrum me, double fmin, double fmax) { autoSpectrum band = Data_copy (me); double *re = band -> z [1], *im = band -> z [2]; long imin = Sampled_xToLowIndex (band.peek(), fmin), imax = Sampled_xToHighIndex (band.peek(), fmax); for (long i = 1; i <= imin; i ++) re [i] = 0.0, im [i] = 0.0; for (long i = imax; i <= band -> nx; i ++) re [i] = 0.0, im [i] = 0.0; return band.transfer(); } static Sound Spectrum_to_Sound_part (Spectrum me, double fmin, double fmax) { autoSpectrum band = Spectrum_band (me, fmin, fmax); autoSound sound = Spectrum_to_Sound (band.peek()); return sound.transfer(); } void structSpectrumEditor :: v_play (double fmin, double fmax) { autoSound sound = Spectrum_to_Sound_part ((Spectrum) our data, fmin, fmax); Sound_play (sound.peek(), NULL, NULL); } static void menu_cb_publishBand (EDITOR_ARGS) { EDITOR_IAM (SpectrumEditor); autoSpectrum publish = Spectrum_band ((Spectrum) my data, my d_startSelection, my d_endSelection); Editor_broadcastPublication (me, publish.transfer()); } static void menu_cb_publishSound (EDITOR_ARGS) { EDITOR_IAM (SpectrumEditor); autoSound publish = Spectrum_to_Sound_part ((Spectrum) my data, my d_startSelection, my d_endSelection); Editor_broadcastPublication (me, publish.transfer()); } static void menu_cb_passBand (EDITOR_ARGS) { EDITOR_IAM (SpectrumEditor); EDITOR_FORM (U"Filter (pass Hann band)", U"Spectrum: Filter (pass Hann band)..."); REAL (U"Band smoothing (Hz)", my default_bandSmoothing ()) EDITOR_OK SET_REAL (U"Band smoothing", my p_bandSmoothing) EDITOR_DO my pref_bandSmoothing() = my p_bandSmoothing = GET_REAL (U"Band smoothing"); if (my d_endSelection <= my d_startSelection) Melder_throw (U"To apply a band-pass filter, first make a selection."); Editor_save (me, U"Pass band"); Spectrum_passHannBand ((Spectrum) my data, my d_startSelection, my d_endSelection, my p_bandSmoothing); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); EDITOR_END } static void menu_cb_stopBand (EDITOR_ARGS) { EDITOR_IAM (SpectrumEditor); EDITOR_FORM (U"Filter (stop Hann band)", 0) REAL (U"Band smoothing (Hz)", my default_bandSmoothing ()) EDITOR_OK SET_REAL (U"Band smoothing", my p_bandSmoothing) EDITOR_DO my pref_bandSmoothing () = my p_bandSmoothing = GET_REAL (U"Band smoothing"); if (my d_endSelection <= my d_startSelection) Melder_throw (U"To apply a band-stop filter, first make a selection."); Editor_save (me, U"Stop band"); Spectrum_stopHannBand ((Spectrum) my data, my d_startSelection, my d_endSelection, my p_bandSmoothing); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); EDITOR_END } static void menu_cb_moveCursorToPeak (EDITOR_ARGS) { EDITOR_IAM (SpectrumEditor); double frequencyOfMaximum, heightOfMaximum; Spectrum_getNearestMaximum ((Spectrum) my data, 0.5 * (my d_startSelection + my d_endSelection), & frequencyOfMaximum, & heightOfMaximum); my d_startSelection = my d_endSelection = frequencyOfMaximum; my cursorHeight = heightOfMaximum; FunctionEditor_marksChanged (me, true); } static void menu_cb_setDynamicRange (EDITOR_ARGS) { EDITOR_IAM (SpectrumEditor); EDITOR_FORM (U"Set dynamic range", 0) POSITIVE (U"Dynamic range (dB)", my default_dynamicRange ()) EDITOR_OK SET_REAL (U"Dynamic range", my p_dynamicRange) EDITOR_DO my pref_dynamicRange () = my p_dynamicRange = GET_REAL (U"Dynamic range"); updateRange (me); FunctionEditor_redraw (me); EDITOR_END } static void menu_cb_help_SpectrumEditor (EDITOR_ARGS) { EDITOR_IAM (SpectrumEditor); Melder_help (U"SpectrumEditor"); } static void menu_cb_help_Spectrum (EDITOR_ARGS) { EDITOR_IAM (SpectrumEditor); Melder_help (U"Spectrum"); } void structSpectrumEditor :: v_createMenus () { SpectrumEditor_Parent :: v_createMenus (); our publishBandButton = Editor_addCommand (this, U"File", U"Publish band", 0, menu_cb_publishBand); our publishSoundButton = Editor_addCommand (this, U"File", U"Publish band-filtered sound", 0, menu_cb_publishSound); Editor_addCommand (this, U"File", U"-- close --", 0, NULL); Editor_addCommand (this, U"Edit", U"-- edit band --", 0, NULL); Editor_addCommand (this, U"Edit", U"Pass band...", 0, menu_cb_passBand); Editor_addCommand (this, U"Edit", U"Stop band...", 0, menu_cb_stopBand); Editor_addCommand (this, U"Select", U"-- move to peak --", 0, 0); Editor_addCommand (this, U"Select", U"Move cursor to nearest peak", 'K', menu_cb_moveCursorToPeak); } void structSpectrumEditor :: v_createMenuItems_view (EditorMenu menu) { EditorMenu_addCommand (menu, U"Set dynamic range...", 0, menu_cb_setDynamicRange); EditorMenu_addCommand (menu, U"-- view settings --", 0, 0); SpectrumEditor_Parent :: v_createMenuItems_view (menu); } void structSpectrumEditor :: v_createHelpMenuItems (EditorMenu menu) { SpectrumEditor_Parent :: v_createHelpMenuItems (menu); EditorMenu_addCommand (menu, U"SpectrumEditor help", '?', menu_cb_help_SpectrumEditor); EditorMenu_addCommand (menu, U"Spectrum help", 0, menu_cb_help_Spectrum); } autoSpectrumEditor SpectrumEditor_create (const char32 *title, Spectrum data) { try { autoSpectrumEditor me = Thing_new (SpectrumEditor); FunctionEditor_init (me.peek(), title, data); my cursorHeight = -1000; updateRange (me.peek()); return me; } catch (MelderError) { Melder_throw (U"Spectrum window not created."); } } /* End of file SpectrumEditor.cpp */ praat-6.0.04/fon/SpectrumEditor.h000066400000000000000000000040651261542461700166310ustar00rootroot00000000000000#ifndef _SpectrumEditor_h_ #define _SpectrumEditor_h_ /* SpectrumEditor.h * * Copyright (C) 1992-2011,2012,2013,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "FunctionEditor.h" #include "Spectrum.h" Thing_define (SpectrumEditor, FunctionEditor) { double minimum, maximum, cursorHeight; GuiMenuItem publishBandButton, publishSoundButton; void v_createMenus () override; void v_createHelpMenuItems (EditorMenu menu) override; void v_dataChanged () override; void v_draw () override; int v_click (double xWC, double yWC, bool shiftKeyPressed) override; void v_play (double tmin, double tmax) override; void v_createMenuItems_view (EditorMenu menu) override; const char32 * v_format_domain () override { return U"Frequency domain:"; } const char * v_format_short () override { return "%.0f"; } const char * v_format_long () override { return "%.2f"; } int v_fixedPrecision_long () override { return 2; } const char32 * v_format_units () override { return U"hertz"; } const char * v_format_totalDuration () override { return u8"Total bandwidth %.2f hertz"; } const char * v_format_window () override { return u8"Visible part %.2f hertz"; } const char * v_format_selection () override { return u8"%.2f Hz"; } #include "SpectrumEditor_prefs.h" }; autoSpectrumEditor SpectrumEditor_create (const char32 *title, Spectrum data); /* End of file SpectrumEditor.h */ #endif praat-6.0.04/fon/SpectrumEditor_prefs.h000066400000000000000000000023341261542461700200250ustar00rootroot00000000000000/* SpectrumEditor_prefs.h * * Copyright (C) 2013,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ prefs_begin (SpectrumEditor) prefs_override_int (SpectrumEditor, shellWidth, 1, U"700") prefs_override_int (SpectrumEditor, shellHeight, 1, U"440") prefs_override_double (SpectrumEditor, arrowScrollStep, 1, U"100.0") prefs_add_double_with_data (SpectrumEditor, bandSmoothing, 1, U"100.0") prefs_add_double_with_data (SpectrumEditor, dynamicRange, 1, U"60.0") prefs_end (SpectrumEditor) /* End of file SpectrumEditor_prefs.h */ praat-6.0.04/fon/SpectrumTier.cpp000066400000000000000000000054631261542461700166440ustar00rootroot00000000000000/* SpectrumTier.cpp * * Copyright (C) 2007-2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Ltas_to_SpectrumTier.h" Thing_implement (SpectrumTier, RealTier, 0); void structSpectrumTier :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Frequency domain:"); MelderInfo_writeLine (U" Lowest frequency: ", xmin, U" Hz"); MelderInfo_writeLine (U" Highest frequency: ", xmax, U" Hz"); MelderInfo_writeLine (U" Total bandwidth: ", xmax - xmin, U" Hz"); MelderInfo_writeLine (U"Number of points: ", points -> size); MelderInfo_writeLine (U"Minimum power value: ", RealTier_getMinimumValue (this), U" dB/Hz"); MelderInfo_writeLine (U"Maximum power value: ", RealTier_getMaximumValue (this), U" dB/Hz"); } autoSpectrumTier SpectrumTier_create (double fmin, double fmax) { try { autoSpectrumTier me = Thing_new (SpectrumTier); RealTier_init (me.peek(), fmin, fmax); return me; } catch (MelderError) { Melder_throw (U"SpectrumTier not created."); } } void SpectrumTier_draw (SpectrumTier me, Graphics g, double fmin, double fmax, double pmin, double pmax, int garnish, const char32 *method) { RealTier_draw (me, g, fmin, fmax, pmin, pmax, garnish, method, U"Power spectral density (dB)"); } void SpectrumTier_list (SpectrumTier me, bool includeIndexes, bool includeFrequency, bool includePowerDensity) { try { autoTable table = SpectrumTier_downto_Table (me, includeIndexes, includeFrequency, includePowerDensity); Table_list (table.peek(), false); } catch (MelderError) { Melder_throw (me, U": not listed."); } } autoTable SpectrumTier_downto_Table (SpectrumTier me, bool includeIndexes, bool includeFrequency, bool includePowerDensity) { return RealTier_downto_Table (me, includeIndexes ? U"index" : NULL, includeFrequency ? U"freq(Hz)" : NULL, includePowerDensity ? U"pow(dB/Hz)" : NULL); } autoSpectrumTier Spectrum_to_SpectrumTier_peaks (Spectrum me) { try { autoLtas ltas = Spectrum_to_Ltas_1to1 (me); autoSpectrumTier thee = Ltas_to_SpectrumTier_peaks (ltas.peek()); return thee; } catch (MelderError) { Melder_throw (me, U": peaks not converted to SpectrumTier."); } } /* End of file SpectrumTier.cpp */ praat-6.0.04/fon/SpectrumTier.h000066400000000000000000000035311261542461700163030ustar00rootroot00000000000000#ifndef _SpectrumTier_h_ #define _SpectrumTier_h_ /* SpectrumTier.h * * Copyright (C) 2007-2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "RealTier.h" #include "Graphics.h" #include "Spectrum.h" /********** class SpectrumTier **********/ Thing_define (SpectrumTier, RealTier) { void v_info () override; int v_domainQuantity () override { return MelderQuantity_FREQUENCY_HERTZ; } const char32 * v_getUnitText (long /* ilevel */, int /* unit */, unsigned long /* flags */) override { return U"Frequency (Hz)"; } }; autoSpectrumTier SpectrumTier_create (double fmin, double fmax); /* Postconditions: result -> xmin == fmin; result -> xmax == fmax; result -> points -> size == 0; */ void SpectrumTier_draw (SpectrumTier me, Graphics g, double fmin, double fmax, double pmin, double pmax, int garnish, const char32 *method); void SpectrumTier_list (SpectrumTier me, bool includeIndexes, bool includeFrequency, bool includePowerDensity); autoTable SpectrumTier_downto_Table (SpectrumTier me, bool includeIndexes, bool includeFrequency, bool includePowerDensity); autoSpectrumTier Spectrum_to_SpectrumTier_peaks (Spectrum me); /* End of file SpectrumTier.h */ #endif praat-6.0.04/fon/Spectrum_and_Spectrogram.cpp000066400000000000000000000041171261542461700212030ustar00rootroot00000000000000/* Spectrum_and_Spectrogram.cpp * * Copyright (C) 1992-2011,2014,2015 David Weenink & Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 1998/04/18 * pb 2002/07/16 GPL * pb 2011/06/10 C++ */ #include "Spectrum_and_Spectrogram.h" autoSpectrum Spectrogram_to_Spectrum (Spectrogram me, double tim) { try { autoSpectrum thee = Spectrum_create (my ymax, my ny); /* Override stupid Spectrum values. */ thy xmin = my ymin; thy xmax = my ymax; thy x1 = my y1; // centre of first band, instead of 0 (makes it unFFTable) thy dx = my dy; // frequency step long itime = Sampled_xToNearestIndex (me, tim); if (itime < 1 ) itime = 1; if (itime > my nx) itime = my nx; for (long ifreq = 1; ifreq <= my ny; ifreq ++) { double value = my z [ifreq] [itime]; if (value < 0.0) Melder_throw (U"Negative values in spectrogram."); thy z [1] [ifreq] = sqrt (value); thy z [2] [ifreq] = 0.0; } return thee; } catch (MelderError) { Melder_throw (me, U": spectral slice not extracted."); } } autoSpectrogram Spectrum_to_Spectrogram (Spectrum me) { try { autoSpectrogram thee = Spectrogram_create (0, 1, 1, 1, 0.5, my xmin, my xmax, my nx, my dx, my x1); for (long i = 1; i <= my nx; i ++) thy z [i] [1] = my z [1] [i] * my z [1] [i] + my z [2] [i] * my z [2] [i]; return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Spectrogram."); } } /* End of file Spectrum_and_Spectrogram.cpp */ praat-6.0.04/fon/Spectrum_and_Spectrogram.h000066400000000000000000000037171261542461700206550ustar00rootroot00000000000000/* Spectrum_and_Spectrogram.h * * Copyright (C) 1992-2011,2015 David Weenink & Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Spectrum.h" #include "Spectrogram.h" autoSpectrum Spectrogram_to_Spectrum (Spectrogram me, double time); /* Function: Create a time slice from the Spectrogram at the time nearest to 'time'. Return NULL in case of failure (no memory). Postconditions: result -> xmin == my ymin; // Lowest frequency; often 0. result -> xmax == my ymax; // Highest frequency. result -> nx == my ny; // Number of frequency bands. result -> dx == my dy; // Frequency step. result -> x1 == my y1; // Centre of first frequency band. for (iy = 1; iy <= my ny; iy ++) { result -> z [1] [i] == sqrt (my z [i] ['time']); result -> z [2] [i] == 0.0; } */ autoSpectrogram Spectrum_to_Spectrogram (Spectrum me); /* Function: Create a Spectrogram with one time slice from the Spectrum. Return NULL in case of failure (no memory). Postconditions: thy xmin = 0.0; thy ymin == my xmin; thy xmax = 1.0; thy ymax == my xmax; thy nx == 1; thy ny == my nx; thy dx == 1.0; thy dy == my dx; thy x1 == 0.5; thy y1 == my x1; for (i = 1; i <= my nx; i ++) thy z [i] [1] == (my z [1] [i]) ^ 2 + (my z [2] [i]) ^ 2; */ /* End of file Spectrum_and_Spectrogram.h */ praat-6.0.04/fon/Spectrum_def.h000066400000000000000000000023331261542461700162740ustar00rootroot00000000000000/* Spectrum_def.h * * Copyright (C) 2002-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT Spectrum oo_DEFINE_CLASS (Spectrum, Matrix) #if oo_READING if (formatVersion < 1) { for (long i = 1; i <= nx; i ++) z [2] [i] = - z [2] [i]; } #endif #if oo_DECLARING void v_info () override; int v_domainQuantity () override { return MelderQuantity_FREQUENCY_HERTZ; } double v_getValueAtSample (long isamp, long which, int units) override; #endif oo_END_CLASS (Spectrum) #undef ooSTRUCT /* End of file Spectrum_def.h */ praat-6.0.04/fon/Spectrum_to_Excitation.cpp000066400000000000000000000052611261542461700207050ustar00rootroot00000000000000/* Spectrum_to_Excitation.cpp * * Copyright (C) 1992-2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 1995/05/20 * pb 2002/07/16 GPL * pb 2011/06/10 C++ */ #include "Spectrum_to_Excitation.h" autoExcitation Spectrum_to_Excitation (Spectrum me, double dbark) { try { long nbark = (int) floor (25.6 / dbark + 0.5); double *re = my z [1], *im = my z [2]; autoNUMvector auditoryFilter (1, nbark); double filterArea = 0; for (long i = 1; i <= nbark; i ++) { double bark = dbark * (i - nbark/2) + 0.474; filterArea += auditoryFilter [i] = pow (10, (1.581 + 0.75 * bark - 1.75 * sqrt (1 + bark * bark))); } /*for (long i = 1; i <= nbark; i ++) auditoryFilter [i] /= filterArea;*/ autoNUMvector rFreqs (1, nbark + 1); autoNUMvector iFreqs (1, nbark + 1); for (long i = 1; i <= nbark + 1; i ++) { rFreqs [i] = Excitation_barkToHertz (dbark * (i - 1)); iFreqs [i] = Sampled_xToNearestIndex (me, rFreqs [i]); } autoNUMvector inSig (1, nbark); for (long i = 1; i <= nbark; i ++) { long low = iFreqs [i], high = iFreqs [i + 1] - 1; if (low < 1) low = 1; if (high > my nx) high = my nx; for (long j = low; j <= high; j ++) inSig [i] += re [j] * re [j] + im [j] * im [j]; // Pa2 s2 /* An anti-undersampling correction. */ if (high >= low) inSig [i] *= 2 * (rFreqs [i + 1] - rFreqs [i]) / (high - low + 1) * my dx; // Pa2: power density in this band } /* Convolution with auditory (masking) filter. */ autoNUMvector outSig (1, 2 * nbark); for (long i = 1; i <= nbark; i ++) for (long j = 1; j <= nbark; j ++) outSig [i + j] += inSig [i] * auditoryFilter [j]; autoExcitation thee = Excitation_create (dbark, nbark); for (long i = 1; i <= nbark; i ++) thy z [1] [i] = Excitation_soundPressureToPhon (sqrt (outSig [i + nbark/2]), Sampled_indexToX (thee.peek(), i)); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Excitation."); } } /* End of file Spectrum_to_Excitation.cpp */ praat-6.0.04/fon/Spectrum_to_Excitation.h000066400000000000000000000020161261542461700203450ustar00rootroot00000000000000/* Spectrum_to_Excitation.h * * Copyright (C) 1992-2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Spectrum.h" #include "Excitation.h" autoExcitation Spectrum_to_Excitation (Spectrum me, double df); /* Postcondition: filtered with 10 ^ (1.581 + 0.75 * bark - 1.75 * sqrt (1 + bark * bark))) */ /* End of file Spectrum_to_Excitation.h */ praat-6.0.04/fon/Spectrum_to_Formant.cpp000066400000000000000000000047241261542461700202070ustar00rootroot00000000000000/* Spectrum_to_Formant.cpp * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 1999/09/09 * pb 2002/07/16 GPL * pb 2011/06/10 C++ */ #include "Spectrum_to_Formant.h" autoFormant Spectrum_to_Formant (Spectrum me, int maxnFormants) { try { long nfreq = my nx, nform = 0; autoNUMvector p (1, nfreq); // power autoFormant thee = Formant_create (0, 1, 1, 1, 0.5, maxnFormants); thy d_frames [1]. formant = NUMvector (1, maxnFormants); for (long i = 1; i <= nfreq; i ++) p [i] = my z [1] [i] * my z [1] [i] + my z [2] [i] * my z [2] [i]; for (long i = 2; i < nfreq; i ++) if (p [i] > p [i - 1] && p [i] >= p [i + 1]) { double firstDerivative = p [i+1] - p [i-1], secondDerivative = 2 * p [i] - p [i-1] - p [i+1]; Formant_Formant formant = & thy d_frames [1]. formant [++ nform]; formant -> frequency = my dx * (i - 1 + 0.5 * firstDerivative / secondDerivative); double min3dB = 0.5 * (p [i] + 0.125 * firstDerivative * firstDerivative / secondDerivative); /* Search left. */ long j = i - 1; while (p [j] > min3dB && j > 1) j --; if (p [j] > min3dB) formant -> bandwidth = formant -> frequency; else formant -> bandwidth = formant -> frequency - my dx * (j - 1 + (min3dB - p [j]) / (p [j + 1] - p [j])); /* Search right. */ j = i + 1; while (p [j] > min3dB && j < nfreq) j ++; if (p [j] > min3dB) formant -> bandwidth += my xmax - formant -> frequency; else formant -> bandwidth += my dx * (j - 1 - (min3dB - p [j]) / (p [j - 1] - p [j])) - formant -> frequency; if (nform == maxnFormants) break; } thy d_frames [1]. nFormants = nform; return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Formant."); } } /* End of file Spectrum_to_Formant.cpp */ praat-6.0.04/fon/Spectrum_to_Formant.h000066400000000000000000000016371261542461700176540ustar00rootroot00000000000000/* Spectrum_to_Formant.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Spectrum.h" #include "Formant.h" autoFormant Spectrum_to_Formant (Spectrum me, int maxnFormants); /* End of file Spectrum_to_Formant.h */ praat-6.0.04/fon/SpellingChecker.cpp000066400000000000000000000167411261542461700172610ustar00rootroot00000000000000/* SpellingChecker.cpp * * Copyright (C) 1999-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2007/06/21 tex * pb 2007/08/12 wchar * pb 2007/10/01 can write as encoding * pb 2011/03/03 wide-character WordList * pb 2011/06/10 C++ */ #include "SpellingChecker.h" #include #include "oo_DESTROY.h" #include "SpellingChecker_def.h" #include "oo_COPY.h" #include "SpellingChecker_def.h" #include "oo_EQUAL.h" #include "SpellingChecker_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "SpellingChecker_def.h" #include "oo_WRITE_TEXT.h" #include "SpellingChecker_def.h" #include "oo_WRITE_BINARY.h" #include "SpellingChecker_def.h" #include "oo_READ_TEXT.h" #include "SpellingChecker_def.h" #include "oo_READ_BINARY.h" #include "SpellingChecker_def.h" #include "oo_DESCRIPTION.h" #include "SpellingChecker_def.h" #include "longchar.h" Thing_implement (SpellingChecker, Daata, 0); autoSpellingChecker WordList_upto_SpellingChecker (WordList me) { try { autoSpellingChecker thee = Thing_new (SpellingChecker); thy wordList = Data_copy (me); thy separatingCharacters = Melder_dup (U".,;:()\""); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to SpellingChecker."); } } autoWordList SpellingChecker_extractWordList (SpellingChecker me) { return Data_copy (my wordList); } void SpellingChecker_replaceWordList (SpellingChecker me, WordList list) { try { /* * Create without change. */ autoWordList newList = Data_copy (list); /* * Change without error. */ forget (my wordList); my wordList = newList.transfer(); } catch (MelderError) { Melder_throw (me, U": word list not replaced."); } } autoSortedSetOfString SpellingChecker_extractUserDictionary (SpellingChecker me) { try { if (! my userDictionary) Melder_throw (U"This spelling checker does not contain a user dictionary."); return Data_copy (my userDictionary); } catch (MelderError) { Melder_throw (me, U": user dictionary not extracted."); } } void SpellingChecker_replaceUserDictionary (SpellingChecker me, SortedSetOfString userDictionary) { try { /* * Create without change. */ autoSortedSetOfString newDict = Data_copy (userDictionary); /* * Change without error. */ forget (my userDictionary); my userDictionary = newDict.transfer(); } catch (MelderError) { Melder_throw (me, U": user dictionary not replaced."); } } static int startsWithCapital (const char32 *word) { return iswupper ((int) word [0]) || (word [0] == '\\' && iswupper ((int) word [1])); } bool SpellingChecker_isWordAllowed (SpellingChecker me, const char32 *word) { int wordLength = str32len (word); if (my allowAllWordsContaining && my allowAllWordsContaining [0]) { char32 *p = & my allowAllWordsContaining [0]; while (*p) { /* * Find next token in list of allowed string parts. */ char32 token [100], *q = & token [0]; /* * Skip spaces in list. */ while (*p == U' ') p ++; /* * Collect one token string from list. */ while (*p != U'\0' && *p != U' ') { *q ++ = *p ++; } *q = U'\0'; // trailing null character /* * Allow word if it contains this token. */ if (str32str (word, token)) return true; } } if (my allowAllNames) { /* * Allow word if it starts with a capital. */ if (startsWithCapital (word)) { return true; } if (my namePrefixes && my namePrefixes [0]) { char32 *p = & my namePrefixes [0]; while (*p) { char32 token [100], *q = & token [0]; while (*p == U' ') p ++; while (*p != U'\0' && *p != U' ') *q ++ = *p ++; *q = U'\0'; // trailing null character /* * Allow word if starts with this prefix * and this prefix is followed by a capital. */ if (str32str (word, token) == word && startsWithCapital (word + str32len (token))) { return true; } } } } else if (my allowAllAbbreviations && startsWithCapital (word)) { const char32 *p = & word [0]; for (;;) { if (*p == '\0') return true; if (iswlower ((int) *p)) break; p ++; } } if (my allowAllWordsStartingWith && my allowAllWordsStartingWith [0]) { char32 *p = & my allowAllWordsStartingWith [0]; while (*p) { char32 token [100], *q = & token [0]; int tokenLength; while (*p == U' ') p ++; while (*p != U'\0' && *p != U' ') *q ++ = *p ++; *q = U'\0'; // trailing null character tokenLength = str32len (token); if (wordLength >= tokenLength && str32nequ (token, word, tokenLength)) { return true; } } } if (my allowAllWordsEndingIn && my allowAllWordsEndingIn [0]) { char32 *p = & my allowAllWordsEndingIn [0]; while (*p) { char32 token [100], *q = & token [0]; int tokenLength; while (*p == U' ') p ++; while (*p != U'\0' && *p != U' ') *q ++ = *p ++; *q = U'\0'; // trailing null character tokenLength = str32len (token); if (wordLength >= tokenLength && str32nequ (token, word + wordLength - tokenLength, tokenLength)) { return true; } } } if (WordList_hasWord (my wordList, word)) return true; if (my userDictionary != NULL) { if (str32len (word) > 3333) return false; // superfluous, because WordList_hasWord already checked; but safe static char32 buffer [3*3333+1]; Longchar_genericize32 (word, buffer); if (SortedSetOfString_lookUp (my userDictionary, buffer) != 0) return true; } return false; } void SpellingChecker_addNewWord (SpellingChecker me, const char32 *word) { try { if (! my userDictionary) my userDictionary = SortedSetOfString_create (); autostring32 generic = Melder_calloc (char32, 3 * str32len (word) + 1); Longchar_genericize32 (word, generic.peek()); SortedSetOfString_addString (my userDictionary, generic.transfer()); } catch (MelderError) { Melder_throw (me, U": word \"", word, U"\" not added."); } } char32 * SpellingChecker_nextNotAllowedWord (SpellingChecker me, const char32 *sentence, long *start) { const char32 *p = sentence + *start; for (;;) { if (*p == U'\0') { return NULL; // all words allowed } else if (*p == U'(' && my allowAllParenthesized) { p ++; for (;;) { if (*p == U'\0') { return NULL; // everything is parenthesized... } else if (*p == U')') { p ++; break; } else { p ++; } } } else if (*p == U' ' || (my separatingCharacters && str32chr (my separatingCharacters, *p))) { p ++; } else { static char32 word [100]; char32 *q = & word [0]; *start = p - sentence; for (;;) { if (*p == U'\0' || *p == U' ' || (my separatingCharacters && str32chr (my separatingCharacters, *p))) { *q ++ = U'\0'; if (SpellingChecker_isWordAllowed (me, word)) { /* Don't increment p (may contain a zero or a parenthesis). */ break; } else { return word; } } else { *q ++ = *p ++; } } } } return NULL; // all words allowed } /* End of file SpellingChecker.cpp */ praat-6.0.04/fon/SpellingChecker.h000066400000000000000000000031471261542461700167220ustar00rootroot00000000000000#ifndef _SpellingChecker_h_ #define _SpellingChecker_h_ /* SpellingChecker.h * * Copyright (C) 1999-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "WordList.h" #include "Collection.h" #include "SpellingChecker_def.h" oo_CLASS_CREATE (SpellingChecker, Daata); autoSpellingChecker WordList_upto_SpellingChecker (WordList me); autoWordList SpellingChecker_extractWordList (SpellingChecker me); void SpellingChecker_replaceWordList (SpellingChecker me, WordList list); autoSortedSetOfString SpellingChecker_extractUserDictionary (SpellingChecker me); void SpellingChecker_replaceUserDictionary (SpellingChecker me, SortedSetOfString userDictionary); bool SpellingChecker_isWordAllowed (SpellingChecker me, const char32 *word); char32 * SpellingChecker_nextNotAllowedWord (SpellingChecker me, const char32 *sentence, long *start); void SpellingChecker_addNewWord (SpellingChecker me, const char32 *word); /* End of file SpellingChecker.h */ #endif praat-6.0.04/fon/SpellingChecker_def.h000066400000000000000000000032371261542461700175400ustar00rootroot00000000000000/* SpellingChecker_def.h * * Copyright (C) 1999-2007,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2007/08/12 */ #define ooSTRUCT SpellingChecker oo_DEFINE_CLASS (SpellingChecker, Daata) // CGN: oo_STRING (forbiddenStrings) // : ; " oo_BOOLEAN (checkMatchingParentheses) // true oo_STRING (separatingCharacters) // .,:;()!? oo_BOOLEAN (allowAllParenthesized) // true oo_BOOLEAN (allowAllNames) // true oo_STRING (namePrefixes) // 's- d' l' oo_BOOLEAN (allowAllAbbreviations) // true oo_BOOLEAN (allowCapsSentenceInitially) // false oo_BOOLEAN (allowCapsAfterColon) // false oo_STRING (allowAllWordsContaining) // * xxx oo_STRING (allowAllWordsStartingWith) oo_STRING (allowAllWordsEndingIn) // - oo_OBJECT (WordList, 0, wordList) oo_COLLECTION (SortedSetOfString, userDictionary, SimpleString, 0) oo_END_CLASS (SpellingChecker) #undef ooSTRUCT /* End of file SpellingChecker_def.h */ praat-6.0.04/fon/TextGrid.cpp000066400000000000000000001767431261542461700157620ustar00rootroot00000000000000/* TextGrid.cpp * * Copyright (C) 1992-2012,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "TextGrid.h" #include "longchar.h" #include "oo_DESTROY.h" #include "TextGrid_def.h" #include "oo_COPY.h" #include "TextGrid_def.h" #include "oo_EQUAL.h" #include "TextGrid_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "TextGrid_def.h" #include "oo_WRITE_TEXT.h" #include "TextGrid_def.h" #include "oo_READ_TEXT.h" #include "TextGrid_def.h" #include "oo_WRITE_BINARY.h" #include "TextGrid_def.h" #include "oo_READ_BINARY.h" #include "TextGrid_def.h" #include "oo_DESCRIPTION.h" #include "TextGrid_def.h" #include "TextGrid_extensions.h" Thing_implement (TextPoint, AnyPoint, 0); autoTextPoint TextPoint_create (double time, const char32 *mark) { try { autoTextPoint me = Thing_new (TextPoint); my number = time; my mark = Melder_dup (mark); return me; } catch (MelderError) { Melder_throw (U"Text point not created."); } } void TextPoint_setText (TextPoint me, const char32 *text) { try { /* * Be fast if the string pointers are equal. */ if (text == my mark) return; /* * Create a temporary variable (i.e. a temporary pointer to the final string), * in order that 'my text' does not change in case of error. */ autostring32 newText = Melder_dup (text); Melder_free (my mark); my mark = newText.transfer(); } catch (MelderError) { Melder_throw (me, U": text not set."); } } Thing_implement (TextInterval, Function, 0); autoTextInterval TextInterval_create (double tmin, double tmax, const char32 *text) { try { autoTextInterval me = Thing_new (TextInterval); my xmin = tmin; my xmax = tmax; my text = Melder_dup (text); return me; } catch (MelderError) { Melder_throw (U"Text interval not created."); } } void TextInterval_setText (TextInterval me, const char32 *text) { try { /* * Be fast if the string pointers are equal. */ if (text == my text) return; /* * Create without change. */ autostring32 newText = Melder_dup (text); /* * Change without error. */ Melder_free (my text); my text = newText.transfer(); } catch (MelderError) { Melder_throw (U"Text interval: text not set."); } } Thing_implement (TextTier, Function, 0); void structTextTier :: v_shiftX (double xfrom, double xto) { TextTier_Parent :: v_shiftX (xfrom, xto); for (long i = 1; i <= our numberOfPoints(); i ++) { TextPoint point = our point (i); NUMshift (& point -> number, xfrom, xto); } } void structTextTier :: v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto) { TextTier_Parent :: v_scaleX (xminfrom, xmaxfrom, xminto, xmaxto); for (long i = 1; i <= our numberOfPoints(); i ++) { TextPoint point = our point (i); NUMscale (& point -> number, xminfrom, xmaxfrom, xminto, xmaxto); } } autoTextTier TextTier_create (double tmin, double tmax) { try { autoTextTier me = Thing_new (TextTier); my points = SortedSetOfDouble_create (); my xmin = tmin; my xmax = tmax; return me; } catch (MelderError) { Melder_throw (U"Point tier not created."); } } void TextTier_addPoint (TextTier me, double time, const char32 *mark) { try { autoTextPoint point = TextPoint_create (time, mark); Collection_addItem (my points, point.transfer()); } catch (MelderError) { Melder_throw (U"Point tier: point not added."); } } Thing_implement (IntervalTier, Function, 0); void structIntervalTier :: v_shiftX (double xfrom, double xto) { IntervalTier_Parent :: v_shiftX (xfrom, xto); for (long i = 1; i <= our numberOfIntervals(); i ++) { TextInterval interval = our interval (i); interval -> v_shiftX (xfrom, xto); } } void structIntervalTier :: v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto) { IntervalTier_Parent :: v_scaleX (xminfrom, xmaxfrom, xminto, xmaxto); for (long i = 1; i <= our numberOfIntervals(); i ++) { TextInterval interval = our interval (i); interval -> v_scaleX (xminfrom, xmaxfrom, xminto, xmaxto); } } autoIntervalTier IntervalTier_create (double tmin, double tmax) { try { autoIntervalTier me = Thing_new (IntervalTier); my intervals = SortedSetOfDouble_create (); my xmin = tmin; my xmax = tmax; autoTextInterval interval = TextInterval_create (tmin, tmax, nullptr); Collection_addItem (my intervals, interval.transfer()); return me.transfer(); } catch (MelderError) { Melder_throw (U"Interval tier not created."); } } long IntervalTier_timeToLowIndex (IntervalTier me, double t) { long ileft = 1, iright = my numberOfIntervals(); if (iright < 1) return 0; // empty tier TextInterval leftInterval = my interval (ileft); if (t < leftInterval -> xmin) return 0; // very small t TextInterval rightInterval = my interval (iright); if (t >= rightInterval -> xmax) return 0; // very large t while (ileft < iright) { long imid = (ileft + iright) / 2; TextInterval midInterval = my interval (imid); if (t >= midInterval -> xmax) { ileft = imid + 1; } else { iright = imid; } } return ileft; } long IntervalTier_timeToIndex (IntervalTier me, double t) { long ileft = 1, iright = my numberOfIntervals(); if (iright < 1) return 0; // empty tier TextInterval leftInterval = my interval (ileft); if (t < leftInterval -> xmin) return 0; // very small t TextInterval rightInterval = my interval (iright); if (t > rightInterval -> xmax) return 0; // very large t while (ileft < iright) { long imid = (ileft + iright) / 2; TextInterval midInterval = my interval (imid); if (t >= midInterval -> xmax) { ileft = imid + 1; } else { iright = imid; } } return ileft; } long IntervalTier_timeToHighIndex (IntervalTier me, double t) { long ileft = 1, iright = my numberOfIntervals(); if (iright < 1) return 0; // empty tier TextInterval leftInterval = my interval (ileft); if (t <= leftInterval -> xmin) return 0; // very small t TextInterval rightInterval = my interval (iright); if (t > rightInterval -> xmax) return 0; // very large t while (ileft < iright) { long imid = (ileft + iright) / 2; TextInterval midInterval = my interval (imid); if (t > midInterval -> xmax) { ileft = imid + 1; } else { iright = imid; } } return ileft; } long IntervalTier_hasTime (IntervalTier me, double t) { long ileft = 1, iright = my numberOfIntervals(); if (iright < 1) return 0; // empty tier TextInterval leftInterval = my interval (ileft); if (t < leftInterval -> xmin) return 0; // very small t TextInterval rightInterval = my interval (iright); if (t > rightInterval -> xmax) return 0; // very large t while (ileft < iright) { long imid = (ileft + iright) / 2; TextInterval midInterval = my interval (imid); if (t >= midInterval -> xmax) { ileft = imid + 1; } else { iright = imid; } } /* * We now know that t is within interval ileft. */ leftInterval = my interval (ileft); if (t == leftInterval -> xmin || t == leftInterval -> xmax) return ileft; return 0; // not found } long IntervalTier_hasBoundary (IntervalTier me, double t) { long ileft = 2, iright = my numberOfIntervals(); if (iright < 2) return 0; // tier without inner boundaries TextInterval leftInterval = my interval (ileft); if (t < leftInterval -> xmin) return 0; // very small t TextInterval rightInterval = my interval (iright); if (t >= rightInterval -> xmax) return 0; // very large t while (ileft < iright) { long imid = (ileft + iright) / 2; TextInterval midInterval = my interval (imid); if (t >= midInterval -> xmax) { ileft = imid + 1; } else { iright = imid; } } leftInterval = my interval (ileft); if (t == leftInterval -> xmin) return ileft; return 0; // not found } void structTextGrid :: v_info () { structDaata :: v_info (); long intervalTierCount = 0, pointTierCount = 0, intervalCount = 0, pointCount = 0; for (long itier = 1; itier <= our numberOfTiers(); itier ++) { Function anyTier = our tier (itier); if (anyTier -> classInfo == classIntervalTier) { IntervalTier intervalTier = static_cast (anyTier); intervalTierCount += 1; intervalCount += intervalTier -> numberOfIntervals(); } else { TextTier textTier = static_cast (anyTier); pointTierCount += 1; pointCount += textTier -> numberOfPoints(); } } MelderInfo_writeLine (U"Number of interval tiers: ", intervalTierCount); MelderInfo_writeLine (U"Number of point tiers: ", pointTierCount); MelderInfo_writeLine (U"Number of intervals: ", intervalCount); MelderInfo_writeLine (U"Number of points: ", pointCount); } static void IntervalTier_addInterval_unsafe (IntervalTier me, double tmin, double tmax, const char32 *label) { autoTextInterval interval = TextInterval_create (tmin, tmax, label); Collection_addItem (my intervals, interval.transfer()); } void structTextGrid :: v_repair () { for (long itier = 1; itier <= our numberOfTiers(); itier ++) { Function anyTier = our tier (itier); if (anyTier -> classInfo == classIntervalTier) { IntervalTier tier = static_cast (anyTier); if (tier -> numberOfIntervals() == 0) { IntervalTier_addInterval_unsafe (tier, tier -> xmin, tier -> xmax, U""); } } } } void structTextGrid :: v_shiftX (double xfrom, double xto) { TextGrid_Parent :: v_shiftX (xfrom, xto); for (long i = 1; i <= our numberOfTiers(); i ++) { Function tier = our tier (i); tier -> v_shiftX (xfrom, xto); } } void structTextGrid :: v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto) { TextGrid_Parent :: v_scaleX (xminfrom, xmaxfrom, xminto, xmaxto); for (long i = 1; i <= our numberOfTiers(); i ++) { Function tier = our tier (i); tier -> v_scaleX (xminfrom, xmaxfrom, xminto, xmaxto); } } Thing_implement (TextGrid, Function, 0); autoTextGrid TextGrid_createWithoutTiers (double tmin, double tmax) { try { autoTextGrid me = Thing_new (TextGrid); my tiers = Ordered_create (); my xmin = tmin; my xmax = tmax; return me; } catch (MelderError) { Melder_throw (U"TextGrid not created."); } } autoTextGrid TextGrid_create (double tmin, double tmax, const char32 *tierNames, const char32 *pointTiers) { try { autoTextGrid me = TextGrid_createWithoutTiers (tmin, tmax); char32 nameBuffer [400]; /* * Create a number of IntervalTier objects. */ if (tierNames && tierNames [0]) { str32cpy (nameBuffer, tierNames); for (char32 *tierName = Melder_tok (nameBuffer, U" "); tierName != NULL; tierName = Melder_tok (NULL, U" ")) { autoIntervalTier tier = IntervalTier_create (tmin, tmax); Thing_setName (tier.peek(), tierName); Collection_addItem (my tiers, tier.transfer()); } } /* * Replace some IntervalTier objects with TextTier objects. */ if (pointTiers && pointTiers [0]) { str32cpy (nameBuffer, pointTiers); for (char32 *tierName = Melder_tok (nameBuffer, U" "); tierName != NULL; tierName = Melder_tok (NULL, U" ")) { for (long itier = 1; itier <= my numberOfTiers(); itier ++) { if (str32equ (tierName, Thing_getName (my tier (itier)))) { autoTextTier tier = TextTier_create (tmin, tmax); Thing_setName (tier.peek(), tierName); forget (my tier (itier)); my tier (itier) = tier.transfer(); } } } } if (my numberOfTiers() == 0) Melder_throw (U"Cannot create a TextGrid without tiers. Supply at least one tier name."); return me; } catch (MelderError) { Melder_throw (U"TextGrid not created."); } } autoTextTier TextTier_readFromXwaves (MelderFile file) { try { char *line; autoTextTier me = TextTier_create (0, 100); autoMelderFile mfile = MelderFile_open (file); /* * Search for a line that starts with '#'. */ for (;;) { line = MelderFile_readLine (file); if (line == NULL) Melder_throw (U"Missing '#' line."); if (line [0] == '#') break; } /* * Read a mark from every line. */ for (;;) { line = MelderFile_readLine (file); if (line == NULL) break; // normal end-of-file double time; long colour; char mark [300]; if (sscanf (line, "%lf%ld%s", & time, & colour, mark) < 3) // BUG: buffer overflow Melder_throw (U"Line too short: \"", Melder_peek8to32 (line), U"\"."); TextTier_addPoint (me.peek(), time, Melder_peek8to32 (mark)); } /* * Fix domain. */ if (my numberOfPoints() > 0) { TextPoint point = my point (1); if (point -> number < 0.0) my xmin = point -> number - 1.0; point = my point (my numberOfPoints()); my xmax = point -> number + 1.0; } mfile.close (); return me; } catch (MelderError) { Melder_throw (U"TextTier not read from Xwaves file."); } } Function TextGrid_checkSpecifiedTierNumberWithinRange (TextGrid me, long tierNumber) { if (tierNumber < 1) Melder_throw (me, U": the specified tier number is ", tierNumber, U", but should be at least 1."); if (tierNumber > my numberOfTiers()) Melder_throw (me, U": the specified tier number (", tierNumber, U") exceeds my number of tiers (", my numberOfTiers(), U")."); return my tier (tierNumber); } IntervalTier TextGrid_checkSpecifiedTierIsIntervalTier (TextGrid me, long tierNumber) { Function tier = TextGrid_checkSpecifiedTierNumberWithinRange (me, tierNumber); if (tier -> classInfo != classIntervalTier) Melder_throw (U"Tier ", tierNumber, U" is not an interval tier."); return static_cast (tier); } TextTier TextGrid_checkSpecifiedTierIsPointTier (TextGrid me, long tierNumber) { Function tier = TextGrid_checkSpecifiedTierNumberWithinRange (me, tierNumber); if (tier -> classInfo != classTextTier) Melder_throw (U"Tier ", tierNumber, U" is not a point tier."); return static_cast (tier); } long TextGrid_countLabels (TextGrid me, long tierNumber, const char32 *text) { try { Function anyTier = TextGrid_checkSpecifiedTierNumberWithinRange (me, tierNumber); long count = 0; if (anyTier -> classInfo == classIntervalTier) { IntervalTier tier = static_cast (anyTier); for (long i = 1; i <= tier -> numberOfIntervals(); i ++) { TextInterval segment = tier -> interval (i); if (segment -> text && str32equ (segment -> text, text)) count ++; } } else { TextTier tier = static_cast (anyTier); for (long i = 1; i <= tier -> numberOfPoints(); i ++) { TextPoint point = tier -> point (i); if (point -> mark && str32equ (point -> mark, text)) count ++; } } return count; } catch (MelderError) { Melder_throw (me, U": labels not counted."); } } long TextGrid_countIntervalsWhere (TextGrid me, long tierNumber, int which_Melder_STRING, const char32 *criterion) { try { long count = 0; IntervalTier tier = TextGrid_checkSpecifiedTierIsIntervalTier (me, tierNumber); for (long iinterval = 1; iinterval <= tier -> numberOfIntervals(); iinterval ++) { TextInterval interval = tier -> interval (iinterval); if (Melder_stringMatchesCriterion (interval -> text, which_Melder_STRING, criterion)) { count ++; } } return count; } catch (MelderError) { Melder_throw (me, U": intervals not counted."); } } long TextGrid_countPointsWhere (TextGrid me, long tierNumber, int which_Melder_STRING, const char32 *criterion) { try { long count = 0; TextTier tier = TextGrid_checkSpecifiedTierIsPointTier (me, tierNumber); for (long ipoint = 1; ipoint <= tier -> numberOfPoints(); ipoint ++) { TextPoint point = tier -> point (ipoint); if (Melder_stringMatchesCriterion (point -> mark, which_Melder_STRING, criterion)) { count ++; } } return count; } catch (MelderError) { Melder_throw (me, U": points not counted."); } } void TextGrid_addTier_copy (TextGrid me, Function anyTier) { try { autoFunction tier = Data_copy (anyTier); if (tier -> xmin < my xmin) my xmin = tier -> xmin; if (tier -> xmax > my xmax) my xmax = tier -> xmax; Collection_addItem (my tiers, tier.transfer()); } catch (MelderError) { Melder_throw (me, U": tier not added."); } } autoTextGrid TextGrid_merge (Collection textGrids) { try { if (textGrids -> size < 1) Melder_throw (U"Cannot merge zero TextGrid objects."); autoTextGrid thee = Data_copy ((TextGrid) textGrids -> item [1]); for (long igrid = 2; igrid <= textGrids -> size; igrid ++) { TextGrid textGrid = (TextGrid) textGrids -> item [igrid]; for (long itier = 1; itier <= textGrid -> numberOfTiers(); itier ++) { TextGrid_addTier_copy (thee.peek(), textGrid -> tier (itier)); } } return thee; } catch (MelderError) { Melder_throw (U"TextGrids not merged."); } } autoTextGrid TextGrid_extractPart (TextGrid me, double tmin, double tmax, int preserveTimes) { try { autoTextGrid thee = Data_copy (me); if (tmax <= tmin) return thee.transfer(); for (long itier = 1; itier <= my numberOfTiers(); itier ++) { Function anyTier = thy tier (itier); if (anyTier -> classInfo == classIntervalTier) { IntervalTier tier = static_cast (anyTier); for (long iinterval = tier -> numberOfIntervals(); iinterval >= 1; iinterval --) { TextInterval interval = tier -> interval (iinterval); if (interval -> xmin >= tmax || interval -> xmax <= tmin) { Collection_removeItem (tier -> intervals, iinterval); } else { if (interval -> xmin < tmin) interval -> xmin = tmin; if (interval -> xmax > tmax) interval -> xmax = tmax; } } } else { TextTier textTier = static_cast (anyTier); for (long ipoint = textTier -> numberOfPoints(); ipoint >= 1; ipoint --) { TextPoint point = textTier -> point (ipoint); if (point -> number < tmin || point -> number > tmax) { Collection_removeItem (textTier -> points, ipoint); } } } anyTier -> xmin = tmin; anyTier -> xmax = tmax; } thy xmin = tmin; thy xmax = tmax; if (! preserveTimes) Function_shiftXTo (thee.peek(), thy xmin, 0.0); return thee; } catch (MelderError) { Melder_throw (me, U": part not extracted."); } } static autoTextGrid _Label_to_TextGrid (Label me, double tmin, double tmax) { autoTextGrid thee = TextGrid_createWithoutTiers (tmin, tmax); for (long itier = 1; itier <= my size; itier ++) { Tier tier = (Tier) my item [itier]; autoIntervalTier intervalTier = IntervalTier_create (tmin, tmax); Collection_addItem (thy tiers, intervalTier.transfer()); Collection_removeItem (intervalTier -> intervals, 1); for (long iinterval = 1; iinterval <= tier -> size; iinterval ++) { Autosegment autosegment = (Autosegment) tier -> item [iinterval]; autoTextInterval textInterval = TextInterval_create ( iinterval == 1 ? tmin : autosegment -> xmin, iinterval == tier -> size ? tmax : autosegment -> xmax, autosegment -> name); Collection_addItem (intervalTier -> intervals, textInterval.transfer()); } } return thee; } autoTextGrid Label_to_TextGrid (Label me, double duration) { try { double tmin = 0.0, tmax = duration; if (duration == 0.0) Label_suggestDomain (me, & tmin, & tmax); trace (duration, U" ", tmin, U" ", tmax); return _Label_to_TextGrid (me, tmin, tmax); } catch (MelderError) { Melder_throw (me, U": not converted to TextGrid."); } } autoTextGrid Label_Function_to_TextGrid (Label me, Any function) { try { return _Label_to_TextGrid (me, ((Function) function) -> xmin, ((Function) function) -> xmax); } catch (MelderError) { Melder_throw (me, U": not converted to TextGrid."); } } autoTextTier PointProcess_upto_TextTier (PointProcess me, const char32 *text) { try { autoTextTier thee = TextTier_create (my xmin, my xmax); for (long i = 1; i <= my nt; i ++) { TextTier_addPoint (thee.peek(), my t [i], text); } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to TextTier."); } } autoPointProcess TextTier_getPoints (TextTier me, const char32 *text) { try { autoPointProcess thee = PointProcess_create (my xmin, my xmax, 10); for (long i = 1; i <= my numberOfPoints(); i ++) { TextPoint point = my point (i); if (text && text [0]) { if (point -> mark && str32equ (text, point -> mark)) PointProcess_addPoint (thee.peek(), point -> number); } else { if (! point -> mark || ! point -> mark [0]) PointProcess_addPoint (thee.peek(), point -> number); } } return thee; } catch (MelderError) { Melder_throw (me, U": points not converted to PointProcess."); } } autoPointProcess IntervalTier_getStartingPoints (IntervalTier me, const char32 *text) { try { autoPointProcess thee = PointProcess_create (my xmin, my xmax, 10); for (long i = 1; i <= my numberOfIntervals(); i ++) { TextInterval interval = my interval (i); if (text && text [0]) { if (interval -> text && str32equ (text, interval -> text)) PointProcess_addPoint (thee.peek(), interval -> xmin); } else { if (! interval -> text || ! interval -> text [0]) PointProcess_addPoint (thee.peek(), interval -> xmin); } } return thee; } catch (MelderError) { Melder_throw (me, U": starting points not gotten."); } } autoPointProcess IntervalTier_getEndPoints (IntervalTier me, const char32 *text) { try { autoPointProcess thee = PointProcess_create (my xmin, my xmax, 10); for (long i = 1; i <= my numberOfIntervals(); i ++) { TextInterval interval = my interval (i); if (text && text [0]) { if (interval -> text && str32equ (text, interval -> text)) PointProcess_addPoint (thee.peek(), interval -> xmax); } else { if (! interval -> text || ! interval -> text [0]) PointProcess_addPoint (thee.peek(), interval -> xmax); } } return thee; } catch (MelderError) { Melder_throw (me, U": end points not gotten."); } } autoPointProcess IntervalTier_getCentrePoints (IntervalTier me, const char32 *text) { try { autoPointProcess thee = PointProcess_create (my xmin, my xmax, 10); for (long i = 1; i <= my numberOfIntervals(); i ++) { TextInterval interval = my interval (i); if (text && text [0]) { if (interval -> text && str32equ (text, interval -> text)) PointProcess_addPoint (thee.peek(), 0.5 * (interval -> xmin + interval -> xmax)); } else { if (! interval -> text || ! interval -> text [0]) PointProcess_addPoint (thee.peek(), 0.5 * (interval -> xmin + interval -> xmax)); } } return thee; } catch (MelderError) { Melder_throw (me, U": centre points not gotten."); } } autoPointProcess TextGrid_getStartingPoints (TextGrid me, long tierNumber, int which_Melder_STRING, const char32 *criterion) { try { IntervalTier tier = TextGrid_checkSpecifiedTierIsIntervalTier (me, tierNumber); autoPointProcess thee = PointProcess_create (my xmin, my xmax, 10); for (long iinterval = 1; iinterval <= tier -> numberOfIntervals(); iinterval ++) { TextInterval interval = tier -> interval (iinterval); if (Melder_stringMatchesCriterion (interval -> text, which_Melder_STRING, criterion)) { PointProcess_addPoint (thee.peek(), interval -> xmin); } } return thee; } catch (MelderError) { Melder_throw (me, U": starting points not converted to PointProcess."); } } autoPointProcess TextGrid_getEndPoints (TextGrid me, long tierNumber, int which_Melder_STRING, const char32 *criterion) { try { IntervalTier tier = TextGrid_checkSpecifiedTierIsIntervalTier (me, tierNumber); autoPointProcess thee = PointProcess_create (my xmin, my xmax, 10); for (long iinterval = 1; iinterval <= tier -> numberOfIntervals(); iinterval ++) { TextInterval interval = tier -> interval (iinterval); if (Melder_stringMatchesCriterion (interval -> text, which_Melder_STRING, criterion)) { PointProcess_addPoint (thee.peek(), interval -> xmax); } } return thee; } catch (MelderError) { Melder_throw (me, U": end points not converted to PointProcess."); } } autoPointProcess TextGrid_getCentrePoints (TextGrid me, long tierNumber, int which_Melder_STRING, const char32 *criterion) { try { IntervalTier tier = TextGrid_checkSpecifiedTierIsIntervalTier (me, tierNumber); autoPointProcess thee = PointProcess_create (my xmin, my xmax, 10); for (long iinterval = 1; iinterval <= tier -> numberOfIntervals(); iinterval ++) { TextInterval interval = tier -> interval (iinterval); if (Melder_stringMatchesCriterion (interval -> text, which_Melder_STRING, criterion)) { PointProcess_addPoint (thee.peek(), 0.5 * (interval -> xmin + interval -> xmax)); } } return thee; } catch (MelderError) { Melder_throw (me, U": centre points not converted to PointProcess."); } } autoPointProcess TextGrid_getPoints (TextGrid me, long tierNumber, int which_Melder_STRING, const char32 *criterion) { try { TextTier tier = TextGrid_checkSpecifiedTierIsPointTier (me, tierNumber); autoPointProcess thee = PointProcess_create (my xmin, my xmax, 10); for (long ipoint = 1; ipoint <= tier -> numberOfPoints(); ipoint ++) { TextPoint point = tier -> point (ipoint); if (Melder_stringMatchesCriterion (point -> mark, which_Melder_STRING, criterion)) { PointProcess_addPoint (thee.peek(), point -> number); } } return thee; } catch (MelderError) { Melder_throw (me, U": points not converted to PointProcess."); } } autoPointProcess TextGrid_getPoints_preceded (TextGrid me, long tierNumber, int which_Melder_STRING, const char32 *criterion, int which_Melder_STRING_precededBy, const char32 *criterion_precededBy) { try { TextTier tier = TextGrid_checkSpecifiedTierIsPointTier (me, tierNumber); autoPointProcess thee = PointProcess_create (my xmin, my xmax, 10); for (long ipoint = 1; ipoint <= tier -> numberOfPoints(); ipoint ++) { TextPoint point = tier -> point (ipoint); if (Melder_stringMatchesCriterion (point -> mark, which_Melder_STRING, criterion)) { TextPoint preceding = ipoint <= 1 ? NULL : tier -> point (ipoint - 1); if (Melder_stringMatchesCriterion (preceding -> mark, which_Melder_STRING_precededBy, criterion_precededBy)) { PointProcess_addPoint (thee.peek(), point -> number); } } } return thee; } catch (MelderError) { Melder_throw (me, U": points not converted to PointProcess."); } } autoPointProcess TextGrid_getPoints_followed (TextGrid me, long tierNumber, int which_Melder_STRING, const char32 *criterion, int which_Melder_STRING_followedBy, const char32 *criterion_followedBy) { try { TextTier tier = TextGrid_checkSpecifiedTierIsPointTier (me, tierNumber); autoPointProcess thee = PointProcess_create (my xmin, my xmax, 10); for (long ipoint = 1; ipoint <= tier -> numberOfPoints(); ipoint ++) { TextPoint point = tier -> point (ipoint); if (Melder_stringMatchesCriterion (point -> mark, which_Melder_STRING, criterion)) { TextPoint following = ipoint >= tier -> numberOfPoints() ? NULL : tier -> point (ipoint + 1); if (Melder_stringMatchesCriterion (following -> mark, which_Melder_STRING_followedBy, criterion_followedBy)) { PointProcess_addPoint (thee.peek(), point -> number); } } } return thee; } catch (MelderError) { Melder_throw (me, U": points not converted to PointProcess."); } } autoPointProcess IntervalTier_PointProcess_startToCentre (IntervalTier tier, PointProcess point, double phase) { try { autoPointProcess thee = PointProcess_create (tier -> xmin, tier -> xmax, 10); for (long i = 1; i <= point -> nt; i ++) { double t = point -> t [i]; long index = IntervalTier_timeToLowIndex (tier, t); if (index) { TextInterval interval = tier -> interval (index); if (interval -> xmin == t) PointProcess_addPoint (thee.peek(), (1 - phase) * interval -> xmin + phase * interval -> xmax); } } return thee; } catch (MelderError) { Melder_throw (tier, U" & ", point, U": starts of intervals not converted to PointProcess."); } } autoPointProcess IntervalTier_PointProcess_endToCentre (IntervalTier tier, PointProcess point, double phase) { try { autoPointProcess thee = PointProcess_create (tier -> xmin, tier -> xmax, 10); for (long i = 1; i <= point -> nt; i ++) { double t = point -> t [i]; long index = IntervalTier_timeToHighIndex (tier, t); if (index) { TextInterval interval = tier -> interval (index); if (interval -> xmax == t) PointProcess_addPoint (thee.peek(), (1 - phase) * interval -> xmin + phase * interval -> xmax); } } return thee; } catch (MelderError) { Melder_throw (tier, U" & ", point, U": ends of intervals not converted to PointProcess."); } } autoTableOfReal IntervalTier_downto_TableOfReal (IntervalTier me, const char32 *label) { try { long n = 0; for (long i = 1; i <= my numberOfIntervals(); i ++) { TextInterval interval = my interval (i); if (! label || (label [0] == U'\0' && ! interval -> text) || (interval -> text && str32equ (interval -> text, label))) n ++; } autoTableOfReal thee = TableOfReal_create (n, 3); TableOfReal_setColumnLabel (thee.peek(), 1, U"Start"); TableOfReal_setColumnLabel (thee.peek(), 2, U"End"); TableOfReal_setColumnLabel (thee.peek(), 3, U"Duration"); n = 0; for (long i = 1; i <= my numberOfIntervals(); i ++) { TextInterval interval = my interval (i); if (label == NULL || (label [0] == U'\0' && ! interval -> text) || (interval -> text && str32equ (interval -> text, label))) { n ++; TableOfReal_setRowLabel (thee.peek(), n, interval -> text ? interval -> text : U""); thy data [n] [1] = interval -> xmin; thy data [n] [2] = interval -> xmax; thy data [n] [3] = interval -> xmax - interval -> xmin; } } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to TableOfReal."); } } autoTableOfReal IntervalTier_downto_TableOfReal_any (IntervalTier me) { return IntervalTier_downto_TableOfReal (me, nullptr); } autoTableOfReal TextTier_downto_TableOfReal (TextTier me, const char32 *label) { try { long n = 0; for (long i = 1; i <= my numberOfPoints(); i ++) { TextPoint point = my point (i); if (label == NULL || (label [0] == U'\0' && ! point -> mark) || (point -> mark && str32equ (point -> mark, label))) n ++; } autoTableOfReal thee = TableOfReal_create (n, 1); TableOfReal_setColumnLabel (thee.peek(), 1, U"Time"); n = 0; for (long i = 1; i <= my numberOfPoints(); i ++) { TextPoint point = my point (i); if (label == NULL || (label [0] == U'\0' && ! point -> mark) || (point -> mark && str32equ (point -> mark, label))) { n ++; TableOfReal_setRowLabel (thee.peek(), n, point -> mark ? point -> mark : U""); thy data [n] [1] = point -> number; } } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to TableOfReal."); } } autoTableOfReal TextTier_downto_TableOfReal_any (TextTier me) { return TextTier_downto_TableOfReal (me, nullptr); } autoIntervalTier IntervalTier_readFromXwaves (MelderFile file) { try { char *line; double lastTime = 0.0; autoIntervalTier me = IntervalTier_create (0, 100); autoMelderFile mfile = MelderFile_open (file); /* * Search for a line that starts with '#'. */ for (;;) { line = MelderFile_readLine (file); if (line == NULL) Melder_throw (U"Missing '#' line."); if (line [0] == '#') break; } /* * Read a mark from every line. */ for (;;) { double time; long colour, numberOfElements; char mark [300]; line = MelderFile_readLine (file); if (line == NULL) break; // normal end-of-file numberOfElements = sscanf (line, "%lf%ld%s", & time, & colour, mark); if (numberOfElements == 0) { break; // an empty line, hopefully at the end } if (numberOfElements == 1) Melder_throw (U"Line too short: \"", Melder_peek8to32 (line), U"\"."); if (numberOfElements == 2) mark [0] = '\0'; if (lastTime == 0.0) { TextInterval interval = my interval (1); interval -> xmax = time; TextInterval_setText (interval, Melder_peek8to32 (mark)); } else { IntervalTier_addInterval_unsafe (me.peek(), lastTime, time, Melder_peek8to32 (mark)); } lastTime = time; } /* * Fix domain. */ if (lastTime > 0.0) { TextInterval lastInterval = my interval (my numberOfIntervals()); my xmax = lastInterval -> xmax = lastTime; } mfile.close (); return me; } catch (MelderError) { Melder_throw (U"IntervalTier not read from file ", file, U"."); } } void IntervalTier_writeToXwaves (IntervalTier me, MelderFile file) { try { autofile f = Melder_fopen (file, "w"); fprintf (f, "separator ;\nnfields 1\n#\n"); for (long iinterval = 1; iinterval <= my numberOfIntervals(); iinterval ++) { TextInterval interval = my interval (iinterval); fprintf (f, "\t%.6f 26\t%s\n", interval -> xmax, Melder_peek32to8 (interval -> text)); } f.close (file); } catch (MelderError) { Melder_throw (me, U": not written to Xwaves file ", file, U"."); } } autoTextGrid PointProcess_to_TextGrid_vuv (PointProcess me, double maxT, double meanT) { try { autoTextGrid thee = TextGrid_create (my xmin, my xmax, U"vuv", NULL); IntervalTier tier = static_cast (thy tier (1)); Collection_removeItem (tier -> intervals, 1); long ipointright; double beginVoiceless = my xmin, endVoiceless, halfMeanT = 0.5 * meanT; for (long ipointleft = 1; ipointleft <= my nt; ipointleft = ipointright + 1) { endVoiceless = my t [ipointleft] - halfMeanT; if (endVoiceless <= beginVoiceless) { endVoiceless = beginVoiceless; // we will use for voiced interval } else { IntervalTier_addInterval_unsafe (tier, beginVoiceless, endVoiceless, U"U"); } for (ipointright = ipointleft + 1; ipointright <= my nt; ipointright ++) if (my t [ipointright] - my t [ipointright - 1] > maxT) break; ipointright --; beginVoiceless = my t [ipointright] + halfMeanT; if (beginVoiceless > my xmax) beginVoiceless = my xmax; IntervalTier_addInterval_unsafe (tier, endVoiceless, beginVoiceless, U"V"); } endVoiceless = my xmax; if (endVoiceless > beginVoiceless) { IntervalTier_addInterval_unsafe (tier, beginVoiceless, endVoiceless, U"U"); } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to TextGrid (vuv)."); } } long TextInterval_labelLength (TextInterval me) { return my text ? str32len (my text) : 0; } long TextPoint_labelLength (TextPoint me) { return my mark ? str32len (my mark) : 0; } long IntervalTier_maximumLabelLength (IntervalTier me) { long maximum = 0; for (long iinterval = 1; iinterval <= my numberOfIntervals(); iinterval ++) { long length = TextInterval_labelLength (my interval (iinterval)); if (length > maximum) { maximum = length; } } return maximum; } long TextTier_maximumLabelLength (TextTier me) { long maximum = 0; for (long ipoint = 1; ipoint <= my numberOfPoints(); ipoint ++) { long length = TextPoint_labelLength (my point (ipoint)); if (length > maximum) { maximum = length; } } return maximum; } long TextGrid_maximumLabelLength (TextGrid me) { long maximum = 0; for (long itier = 1; itier <= my numberOfTiers(); itier ++) { Function anyTier = my tier (itier); long length = anyTier -> classInfo == classIntervalTier ? IntervalTier_maximumLabelLength ((IntervalTier) anyTier) : TextTier_maximumLabelLength ((TextTier) anyTier); if (length > maximum) { maximum = length; } } return maximum; } static void genericize (char32 **pstring, char32 *buffer) { if (*pstring) { const char32 *p = (const char32 *) *pstring; while (*p) { if (*p > 126) { // only if necessary char32 *newString; Longchar_genericize32 (*pstring, buffer); newString = Melder_dup (buffer); /* * Replace string only if copying was OK. */ Melder_free (*pstring); *pstring = newString; break; } p ++; } } } void TextGrid_genericize (TextGrid me) { try { autostring32 buffer = Melder_calloc (char32, TextGrid_maximumLabelLength (me) * 3 + 1); for (long itier = 1; itier <= my numberOfTiers(); itier ++) { Function anyTier = my tier (itier); if (anyTier -> classInfo == classIntervalTier) { IntervalTier tier = static_cast (anyTier); for (long i = 1; i <= tier -> numberOfIntervals(); i ++) { TextInterval interval = tier -> interval (i); genericize (& interval -> text, buffer.peek()); } } else { TextTier tier = static_cast (anyTier); for (long i = 1; i <= tier -> numberOfPoints(); i ++) { TextPoint point = tier -> point (i); genericize (& point -> mark, buffer.peek()); } } } } catch (MelderError) { Melder_throw (me, U": not converted to backslash trigraphs."); } } void TextGrid_nativize (TextGrid me) { try { autostring32 buffer = Melder_calloc (char32, TextGrid_maximumLabelLength (me) + 1); for (long itier = 1; itier <= my numberOfTiers(); itier ++) { Function anyTier = my tier (itier); if (anyTier -> classInfo == classIntervalTier) { IntervalTier tier = static_cast (anyTier); for (long i = 1; i <= tier -> numberOfIntervals(); i ++) { TextInterval interval = tier -> interval (i); if (interval -> text) { Longchar_nativize32 (interval -> text, buffer.peek(), false); str32cpy (interval -> text, buffer.peek()); } } } else { TextTier tier = static_cast (anyTier); for (long i = 1; i <= tier -> numberOfPoints(); i ++) { TextPoint point = tier -> point (i); if (point -> mark) { Longchar_nativize32 (point -> mark, buffer.peek(), false); str32cpy (point -> mark, buffer.peek()); } } } } } catch (MelderError) { Melder_throw (me, U": backslash trigraphs not converted to Unicode."); } } void TextInterval_removeText (TextInterval me) { Melder_free (my text); } void TextPoint_removeText (TextPoint me) { Melder_free (my mark); } void IntervalTier_removeText (IntervalTier me) { long ninterval = my numberOfIntervals (); for (long iinterval = 1; iinterval <= ninterval; iinterval ++) TextInterval_removeText (my interval (iinterval)); } void TextTier_removeText (TextTier me) { long npoint = my numberOfPoints (); for (long ipoint = 1; ipoint <= npoint; ipoint ++) TextPoint_removeText (my point (ipoint)); } void TextGrid_insertBoundary (TextGrid me, int tierNumber, double t) { try { Function anyTier = TextGrid_checkSpecifiedTierNumberWithinRange (me, tierNumber); if (anyTier -> classInfo != classIntervalTier) Melder_throw (U"Cannot add a boundary on tier ", tierNumber, U", because that tier is not an interval tier."); IntervalTier intervalTier = static_cast (anyTier); if (IntervalTier_hasTime (intervalTier, t)) Melder_throw (U"Cannot add a boundary at ", Melder_fixed (t, 6), U" seconds, because there is already a boundary there."); long intervalNumber = IntervalTier_timeToIndex (intervalTier, t); if (intervalNumber == 0) Melder_throw (U"Cannot add a boundary at ", Melder_fixed (t, 6), U" seconds, because this is outside the time domain of the intervals."); TextInterval interval = intervalTier -> interval (intervalNumber); /* * Move the text to the left of the boundary. */ autoTextInterval newInterval = TextInterval_create (t, interval -> xmax, U""); interval -> xmax = t; Collection_addItem (intervalTier -> intervals, newInterval.transfer()); } catch (MelderError) { Melder_throw (me, U": boundary not inserted."); } } void IntervalTier_removeLeftBoundary (IntervalTier me, long intervalNumber) { try { Melder_assert (intervalNumber > 1); Melder_assert (intervalNumber <= my numberOfIntervals ()); TextInterval left = my interval (intervalNumber - 1); TextInterval right = my interval (intervalNumber); /* * Move the text to the left of the boundary. */ left -> xmax = right -> xmax; // collapse left and right intervals into left interval if (right -> text == NULL) { ; } else if (left -> text == NULL) { TextInterval_setText (left, right -> text); } else { TextInterval_setText (left, Melder_cat (left -> text, right -> text)); } Collection_removeItem (my intervals, intervalNumber); // remove right interval } catch (MelderError) { Melder_throw (me, U": left boundary not removed."); } } void TextGrid_removeBoundaryAtTime (TextGrid me, int tierNumber, double t) { try { IntervalTier intervalTier = TextGrid_checkSpecifiedTierIsIntervalTier (me, tierNumber); if (! IntervalTier_hasTime (intervalTier, t)) Melder_throw (U"There is no boundary at ", t, U" seconds."); long intervalNumber = IntervalTier_timeToIndex (intervalTier, t); if (intervalNumber == 0) Melder_throw (U"The time of ", t, U" seconds is outside the time domain of the intervals."); if (intervalNumber == 1) Melder_throw (U"The time of ", t, U" seconds is at the left edge of the tier."); IntervalTier_removeLeftBoundary (intervalTier, intervalNumber); } catch (MelderError) { Melder_throw (me, U": boundary not removed."); } } void TextGrid_setIntervalText (TextGrid me, int tierNumber, long intervalNumber, const char32 *text) { try { IntervalTier intervalTier = TextGrid_checkSpecifiedTierIsIntervalTier (me, tierNumber); if (intervalNumber < 1 || intervalNumber > intervalTier -> numberOfIntervals ()) Melder_throw (U"Interval ", intervalNumber, U" does not exist on tier ", tierNumber, U"."); TextInterval interval = intervalTier -> interval (intervalNumber); TextInterval_setText (interval, text); } catch (MelderError) { Melder_throw (me, U": interval text not set."); } } void TextGrid_insertPoint (TextGrid me, int tierNumber, double t, const char32 *mark) { try { TextTier textTier = TextGrid_checkSpecifiedTierIsPointTier (me, tierNumber); if (AnyTier_hasPoint (textTier, t)) Melder_throw (U"There is already a point at ", t, U" seconds."); autoTextPoint newPoint = TextPoint_create (t, mark); Collection_addItem (textTier -> points, newPoint.transfer()); } catch (MelderError) { Melder_throw (me, U": point not inserted."); } } void TextTier_removePoint (TextTier me, long ipoint) { Melder_assert (ipoint <= my numberOfPoints()); Collection_removeItem (my points, ipoint); } void TextTier_removePoints (TextTier me, int which_Melder_STRING, const char32 *criterion) { for (long i = my numberOfPoints (); i > 0; i --) if (Melder_stringMatchesCriterion (my point (i) -> mark, which_Melder_STRING, criterion)) Collection_removeItem (my points, i); } void TextGrid_removePoints (TextGrid me, long tierNumber, int which_Melder_STRING, const char32 *criterion) { try { TextTier tier = TextGrid_checkSpecifiedTierIsPointTier (me, tierNumber); TextTier_removePoints (tier, which_Melder_STRING, criterion); } catch (MelderError) { Melder_throw (me, U": points not removed."); } } void TextGrid_setPointText (TextGrid me, int tierNumber, long pointNumber, const char32 *text) { try { TextTier textTier = TextGrid_checkSpecifiedTierIsPointTier (me, tierNumber); if (pointNumber < 1 || pointNumber > textTier -> numberOfPoints ()) Melder_throw (U"Point ", pointNumber, U" does not exist on tier ", tierNumber, U"."); TextPoint point = textTier -> point (pointNumber); TextPoint_setText (point, text); } catch (MelderError) { Melder_throw (me, U": point text not set."); } } static void sgmlToPraat (char *text) { char *sgml = text, *praat = text; for (;;) { if (*sgml == '\0') break; if (*sgml == '&') { static struct { const char *sgml, *praat; } translations [] = { { "auml", "\\a\"" }, { "euml", "\\e\"" }, { "iuml", "\\i\"" }, { "ouml", "\\o\"" }, { "ouml", "\\o\"" }, { "Auml", "\\A\"" }, { "Euml", "\\E\"" }, { "Iuml", "\\I\"" }, { "Ouml", "\\O\"" }, { "Uuml", "\\U\"" }, { "aacute", "\\a'" }, { "eacute", "\\e'" }, { "iacute", "\\i'" }, { "oacute", "\\o'" }, { "oacute", "\\o'" }, { "Aacute", "\\A'" }, { "Eacute", "\\E'" }, { "Iacute", "\\I'" }, { "Oacute", "\\O'" }, { "Uacute", "\\U'" }, { "agrave", "\\a`" }, { "egrave", "\\e`" }, { "igrave", "\\i`" }, { "ograve", "\\o`" }, { "ograve", "\\o`" }, { "Agrave", "\\A`" }, { "Egrave", "\\E`" }, { "Igrave", "\\I`" }, { "Ograve", "\\O`" }, { "Ugrave", "\\U`" }, { "acirc", "\\a^" }, { "ecirc", "\\e^" }, { "icirc", "\\i^" }, { "ocirc", "\\o^" }, { "ocirc", "\\o^" }, { "Acirc", "\\A^" }, { "Ecirc", "\\E^" }, { "Icirc", "\\I^" }, { "Ocirc", "\\O^" }, { "Ucirc", "\\U^" }, { NULL, NULL } }; char sgmlCode [201]; int i = 0; ++ sgml; for (i = 0; i < 200; i ++) { char sgmlChar = sgml [i]; if (sgmlChar == ';') { if (i == 0) Melder_throw (U"Empty SGML code."); sgml += i + 1; break; } sgmlCode [i] = sgmlChar; } if (i >= 200) Melder_throw (U"Unfinished SGML code."); sgmlCode [i] = '\0'; for (i = 0; translations [i]. sgml != NULL; i ++) { if (strequ (sgmlCode, translations [i]. sgml)) { memcpy (praat, translations [i]. praat, strlen (translations [i]. praat)); praat += strlen (translations [i]. praat); break; } } if (translations [i]. sgml == NULL) Melder_throw (U"Unknown SGML code &", Melder_peek8to32 (sgmlCode), U";."); } else { * praat ++ = * sgml ++; } } *praat = '\0'; } autoTextGrid TextGrid_readFromChronologicalTextFile (MelderFile file) { try { int formatVersion = 0; autoMelderReadText text = MelderReadText_createFromFile (file); autostring32 tag = texgetw2 (text.peek()); if (! str32equ (tag.peek(), U"Praat chronological TextGrid text file")) Melder_throw (U"This is not a chronological TextGrid text file."); autoTextGrid me = Thing_new (TextGrid); my structFunction :: v_readText (text.peek(), formatVersion); my tiers = Ordered_create (); long numberOfTiers = texgeti4 (text.peek()); for (long itier = 1; itier <= numberOfTiers; itier ++) { autostring32 klas = texgetw2 (text.peek()); if (str32equ (klas.peek(), U"IntervalTier")) { autoIntervalTier tier = Thing_new (IntervalTier); tier -> name = texgetw2 (text.peek()); tier -> structFunction :: v_readText (text.peek(), formatVersion); tier -> intervals = SortedSetOfDouble_create (); Collection_addItem (my tiers, tier.transfer()); } else if (str32equ (klas.peek(), U"TextTier")) { autoTextTier tier = Thing_new (TextTier); tier -> name = texgetw2 (text.peek()); tier -> structFunction :: v_readText (text.peek(), formatVersion); tier -> points = SortedSetOfDouble_create (); Collection_addItem (my tiers, tier.transfer()); } else { Melder_throw (U"Unknown tier class \"", klas.peek(), U"\"."); } } for (;;) { long tierNumber; try { tierNumber = texgeti4 (text.peek()); } catch (MelderError) { if (str32str (Melder_getError (), U"Early end of text")) { Melder_clearError (); break; } else { throw; } } Function anyTier = TextGrid_checkSpecifiedTierNumberWithinRange (me.peek(), tierNumber); if (anyTier -> classInfo == classIntervalTier) { IntervalTier tier = static_cast (anyTier); autoTextInterval interval = Thing_new (TextInterval); interval -> v_readText (text.peek(), formatVersion); Collection_addItem (tier -> intervals, interval.transfer()); // not earlier: sorting depends on contents of interval } else { TextTier tier = static_cast (anyTier); autoTextPoint point = Thing_new (TextPoint); point -> v_readText (text.peek(), formatVersion); Collection_addItem (tier -> points, point.transfer()); // not earlier: sorting depends on contents of point } } return me; } catch (MelderError) { Melder_throw (U"TextGrid not read from chronological text file ", file, U"."); } } static void writeQuotedString (MelderFile file, const char32 *string) { MelderFile_writeCharacter (file, U'\"'); if (string) { char32 kar; while ((kar = *string ++) != U'\0') { MelderFile_writeCharacter (file, kar); if (kar == '\"') MelderFile_writeCharacter (file, kar); } } // BUG MelderFile_writeCharacter (file, U'\"'); } void TextGrid_writeToChronologicalTextFile (TextGrid me, MelderFile file) { try { Data_createTextFile (me, file, false); autoMelderFile mfile = file; /* * The "elements" (intervals and points) are sorted primarily by time and secondarily by tier. */ double sortingTime = -1e308; long sortingTier = 0; file -> verbose = false; texindent (file); MelderFile_write (file, U"\"Praat chronological TextGrid text file\"\n", my xmin, U" ", my xmax, U" ! Time domain.\n", my numberOfTiers(), U" ! Number of tiers."); for (long itier = 1; itier <= my numberOfTiers(); itier ++) { Function anyTier = my tier (itier); MelderFile_write (file, U"\n"); writeQuotedString (file, Thing_className (anyTier)); MelderFile_write (file, U" "); writeQuotedString (file, anyTier -> name); MelderFile_write (file, U" ", anyTier -> xmin, U" ", anyTier -> xmax); } for (;;) { double firstRemainingTime = +1e308; long firstRemainingTier = 2000000000, firstRemainingElement = 0; for (long itier = 1; itier <= my numberOfTiers(); itier ++) { Function anyTier = my tier (itier); if (anyTier -> classInfo == classIntervalTier) { IntervalTier tier = static_cast (anyTier); for (long ielement = 1; ielement <= tier -> numberOfIntervals(); ielement ++) { TextInterval interval = tier -> interval (ielement); if ((interval -> xmin > sortingTime || // sort primarily by time (interval -> xmin == sortingTime && itier > sortingTier)) && // sort secondarily by tier number (interval -> xmin < firstRemainingTime || // sort primarily by time (interval -> xmin == firstRemainingTime && itier < firstRemainingTier))) // sort secondarily by tier number { firstRemainingTime = interval -> xmin; firstRemainingTier = itier; firstRemainingElement = ielement; } } } else { TextTier tier = static_cast (anyTier); for (long ielement = 1; ielement <= tier -> numberOfPoints(); ielement ++) { TextPoint point = tier -> point (ielement); if ((point -> number > sortingTime || // sort primarily by time (point -> number == sortingTime && itier > sortingTier)) && // sort secondarily by tier number (point -> number < firstRemainingTime || // sort primarily by time (point -> number == firstRemainingTime && itier < firstRemainingTier))) // sort secondarily by tier number { firstRemainingTime = point -> number; firstRemainingTier = itier; firstRemainingElement = ielement; } } } } if (firstRemainingElement == 0) { break; } else { Function anyTier = my tier (firstRemainingTier); if (anyTier -> classInfo == classIntervalTier) { IntervalTier tier = static_cast (anyTier); TextInterval interval = tier -> interval (firstRemainingElement); if (tier -> name) MelderFile_write (file, U"\n\n! ", tier -> name, U":"); MelderFile_write (file, U"\n", firstRemainingTier, U" ", interval -> xmin, U" ", interval -> xmax); texputw4 (file, interval -> text, U"", 0,0,0,0,0); } else { TextTier tier = static_cast (anyTier); TextPoint point = tier -> point (firstRemainingElement); if (tier -> name) MelderFile_write (file, U"\n\n! ", tier -> name, U":"); MelderFile_write (file, U"\n", firstRemainingTier, U" ", point -> number, U" "); texputw4 (file, point -> mark, U"", 0,0,0,0,0); } sortingTime = firstRemainingTime; sortingTier = firstRemainingTier; } } texexdent (file); mfile.close (); } catch (MelderError) { Melder_throw (me, U": not written to chronological text file ", file, U"."); } } autoTextGrid TextGrid_readFromCgnSyntaxFile (MelderFile file) { try { autoTextGrid me = Thing_new (TextGrid); long sentenceNumber = 0; double phraseBegin = 0.0, phraseEnd = 0.0; IntervalTier sentenceTier = NULL, phraseTier = NULL; TextInterval lastInterval = NULL; static char phrase [1000]; my tiers = Ordered_create (); autoMelderFile mfile = MelderFile_open (file); char *line = MelderFile_readLine (file); if (! strequ (line, "")) Melder_throw (U"This is not a CGN syntax file."); line = MelderFile_readLine (file); if (! strequ (line, "")) Melder_throw (U"This is not a CGN syntax file."); line = MelderFile_readLine (file); long startOfData = MelderFile_tell (file); /* * Get duration. */ my xmin = 0.0; char arg1 [41], arg2 [41], arg3 [41], arg4 [41], arg5 [41], arg6 [41], arg7 [201]; for (;;) { line = MelderFile_readLine (file); if (! line) break; if (strnequ (line, " numberOfIntervals() > 0) { TextInterval latestInterval = sentenceTier -> interval (sentenceTier -> numberOfIntervals()); if (tb > latestInterval -> xmax) { autoTextInterval interval = TextInterval_create (latestInterval -> xmax, tb, U""); Collection_addItem (sentenceTier -> intervals, interval.transfer()); } else if (tb < latestInterval -> xmax) { Melder_throw (U"Overlap on tier not allowed."); } } else { if (tb > 0.0) { autoTextInterval interval = TextInterval_create (0.0, tb, U""); Collection_addItem (sentenceTier -> intervals, interval.transfer()); } else if (tb < 0.0) { Melder_throw (U"Negative times not allowed."); } } autoTextInterval interval = TextInterval_create (tb, te, Melder_integer (++ sentenceNumber)); Collection_addItem (sentenceTier -> intervals, interval.transfer()); } else if (strnequ (line, " strcat (phrase, arg7 + 3); } else { /* Begin a phrase. */ if (lastInterval) { sgmlToPraat (phrase); TextInterval_setText (lastInterval, Melder_peek8to32 (phrase)); } phrase [0] = '\0'; length = strlen (arg7); if (length < 6 || ! strnequ (arg7, "w=\"", 3)) Melder_throw (U"Missing word."); arg7 [length - 3] = '\0'; // truncate "/> strcat (phrase, arg7 + 3); if (phraseTier -> numberOfIntervals() > 0) { TextInterval latestInterval = phraseTier -> interval (phraseTier -> numberOfIntervals()); if (tb > latestInterval -> xmax) { autoTextInterval interval = TextInterval_create (latestInterval -> xmax, tb, U""); Collection_addItem (phraseTier -> intervals, interval.transfer()); } else if (tb < latestInterval -> xmax) { Melder_throw (U"Overlap on tier not allowed."); } } else { if (tb > 0.0) { autoTextInterval interval = TextInterval_create (0.0, tb, U""); Collection_addItem (phraseTier -> intervals, interval.transfer()); } else if (tb < 0.0) { Melder_throw (U"Negative times not allowed."); } } if (! phraseTier) Melder_throw (U"Phrase outside sentence."); autoTextInterval newLastInterval = TextInterval_create (tb, te, U""); lastInterval = newLastInterval.peek(); Collection_addItem (phraseTier -> intervals, newLastInterval.transfer()); phraseBegin = tb; phraseEnd = te; } } } if (lastInterval) { sgmlToPraat (phrase); TextInterval_setText (lastInterval, Melder_peek8to32 (phrase)); } for (long itier = 1; itier <= my numberOfTiers(); itier ++) { IntervalTier tier = static_cast (my tier (itier)); if (tier -> numberOfIntervals() > 0) { TextInterval latestInterval = tier -> interval (tier -> numberOfIntervals()); if (my xmax > latestInterval -> xmax) { autoTextInterval interval = TextInterval_create (latestInterval -> xmax, my xmax, U""); Collection_addItem (tier -> intervals, interval.transfer()); } } else { autoTextInterval interval = TextInterval_create (my xmin, my xmax, U""); Collection_addItem (tier -> intervals, interval.transfer()); } } mfile.close (); return me; } catch (MelderError) { Melder_throw (U"TextGrid not read from CGN syntax file ", file, U"."); } } autoTable TextGrid_downto_Table (TextGrid me, bool includeLineNumbers, int timeDecimals, bool includeTierNames, bool includeEmptyIntervals) { long numberOfRows = 0; for (long itier = 1; itier <= my numberOfTiers(); itier ++) { Function anyTier = my tier (itier); if (anyTier -> classInfo == classIntervalTier) { IntervalTier tier = static_cast (anyTier); if (includeEmptyIntervals) { numberOfRows += tier -> numberOfIntervals(); } else { for (long iinterval = 1; iinterval <= tier -> numberOfIntervals(); iinterval ++) { TextInterval interval = tier -> interval (iinterval); if (interval -> text != NULL && interval -> text [0] != U'\0') { numberOfRows ++; } } } } else { TextTier tier = static_cast (anyTier); numberOfRows += tier -> numberOfPoints(); } } autoTable thee = Table_createWithoutColumnNames (numberOfRows, 3 + includeLineNumbers + includeTierNames); long icol = 0; if (includeLineNumbers) Table_setColumnLabel (thee.peek(), ++ icol, U"line"); Table_setColumnLabel (thee.peek(), ++ icol, U"tmin"); if (includeTierNames) Table_setColumnLabel (thee.peek(), ++ icol, U"tier"); Table_setColumnLabel (thee.peek(), ++ icol, U"text"); Table_setColumnLabel (thee.peek(), ++ icol, U"tmax"); long irow = 0; for (long itier = 1; itier <= my numberOfTiers(); itier ++) { Function anyTier = my tier (itier); if (anyTier -> classInfo == classIntervalTier) { IntervalTier tier = static_cast (anyTier); for (long iinterval = 1; iinterval <= tier -> numberOfIntervals(); iinterval ++) { TextInterval interval = tier -> interval (iinterval); if (includeEmptyIntervals || (interval -> text != NULL && interval -> text [0] != U'\0')) { ++ irow; icol = 0; if (includeLineNumbers) Table_setNumericValue (thee.peek(), irow, ++ icol, irow); Table_setStringValue (thee.peek(), irow, ++ icol, Melder_fixed (interval -> xmin, timeDecimals)); if (includeTierNames) Table_setStringValue (thee.peek(), irow, ++ icol, tier -> name); Table_setStringValue (thee.peek(), irow, ++ icol, interval -> text); Table_setStringValue (thee.peek(), irow, ++ icol, Melder_fixed (interval -> xmax, timeDecimals)); } } } else { TextTier tier = static_cast (anyTier); for (long ipoint = 1; ipoint <= tier -> numberOfPoints(); ipoint ++) { TextPoint point = tier -> point (ipoint); ++ irow; icol = 0; if (includeLineNumbers) Table_setNumericValue (thee.peek(), irow, ++ icol, irow); Table_setStringValue (thee.peek(), irow, ++ icol, Melder_fixed (point -> number, timeDecimals)); if (includeTierNames) Table_setStringValue (thee.peek(), irow, ++ icol, tier -> name); Table_setStringValue (thee.peek(), irow, ++ icol, point -> mark); Table_setStringValue (thee.peek(), irow, ++ icol, Melder_fixed (point -> number, timeDecimals)); } } } long columns [1+2] = { 0, 1 + includeLineNumbers, 3 + includeLineNumbers + includeTierNames }; // sort by tmin and tmax Table_sortRows_Assert (thee.peek(), columns, 2); return thee; } void TextGrid_list (TextGrid me, bool includeLineNumbers, int timeDecimals, bool includeTierNames, bool includeEmptyIntervals) { try { autoTable table = TextGrid_downto_Table (me, includeLineNumbers, timeDecimals, includeTierNames, includeEmptyIntervals); Table_list (table.peek(), false); } catch (MelderError) { Melder_throw (me, U": not listed."); } } void TextGrid_correctRoundingErrors (TextGrid me) { for (long itier = 1; itier <= my numberOfTiers(); itier ++) { Function anyTier = my tier (itier); if (anyTier -> classInfo == classIntervalTier) { IntervalTier tier = static_cast (anyTier); TextInterval first = tier -> interval (1); first -> xmin = my xmin; Melder_assert (first -> xmin < first -> xmax); for (long iinterval = 1; iinterval < tier -> numberOfIntervals(); iinterval ++) { TextInterval left = tier -> interval (iinterval); TextInterval right = tier -> interval (iinterval + 1); right -> xmin = left -> xmax; trace (U"tier ", itier, U", interval ", iinterval, U", ", right -> xmin, U" ", right -> xmax); Melder_assert (right -> xmin < right -> xmax); } TextInterval last = tier -> interval (tier -> numberOfIntervals()); trace (tier -> numberOfIntervals(), U" ", last -> xmax, U" ", my xmax); last -> xmax = my xmax; Melder_assert (last -> xmax > last -> xmin); } anyTier -> xmin = my xmin; anyTier -> xmax = my xmax; } } autoTextGrid TextGrids_concatenate (Collection me) { try { autoTextGrid thee = TextGrids_to_TextGrid_appendContinuous (me, false); TextGrid_correctRoundingErrors (thee.peek()); return thee; } catch (MelderError) { Melder_throw (U"TextGrids not concatenated."); } } /* End of file TextGrid.cpp */ praat-6.0.04/fon/TextGrid.h000066400000000000000000000154151261542461700154130ustar00rootroot00000000000000#ifndef _TextGrid_h_ #define _TextGrid_h_ /* TextGrid.h * * Copyright (C) 1992-2012,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "AnyTier.h" #include "Label.h" #include "Graphics.h" #include "TableOfReal.h" #include "Table.h" #include "TextGrid_def.h" oo_CLASS_CREATE (TextPoint, AnyPoint); autoTextPoint TextPoint_create (double time, const char32 *mark); void TextPoint_setText (TextPoint me, const char32 *text); oo_CLASS_CREATE (TextInterval, Function); autoTextInterval TextInterval_create (double tmin, double tmax, const char32 *text); void TextInterval_setText (TextInterval me, const char32 *text); oo_CLASS_CREATE (TextTier, Function); autoTextTier TextTier_create (double tmin, double tmax); void TextTier_addPoint (TextTier me, double time, const char32 *mark); autoTextTier TextTier_readFromXwaves (MelderFile file); autoPointProcess TextTier_getPoints (TextTier me, const char32 *text); oo_CLASS_CREATE (IntervalTier, Function); autoIntervalTier IntervalTier_create (double tmin, double tmax); autoIntervalTier IntervalTier_readFromXwaves (MelderFile file); void IntervalTier_writeToXwaves (IntervalTier me, MelderFile file); long IntervalTier_timeToLowIndex (IntervalTier me, double t); long IntervalTier_timeToIndex (IntervalTier me, double t); // obsolete long IntervalTier_timeToHighIndex (IntervalTier me, double t); long IntervalTier_hasTime (IntervalTier me, double t); long IntervalTier_hasBoundary (IntervalTier me, double t); autoPointProcess IntervalTier_getStartingPoints (IntervalTier me, const char32 *text); autoPointProcess IntervalTier_getEndPoints (IntervalTier me, const char32 *text); autoPointProcess IntervalTier_getCentrePoints (IntervalTier me, const char32 *text); autoPointProcess IntervalTier_PointProcess_startToCentre (IntervalTier tier, PointProcess point, double phase); autoPointProcess IntervalTier_PointProcess_endToCentre (IntervalTier tier, PointProcess point, double phase); void IntervalTier_removeLeftBoundary (IntervalTier me, long iinterval); void TextTier_removePoint (TextTier me, long ipoint); oo_CLASS_CREATE (TextGrid, Function); autoTextGrid TextGrid_createWithoutTiers (double tmin, double tmax); autoTextGrid TextGrid_create (double tmin, double tmax, const char32 *tierNames, const char32 *pointTiers); long TextGrid_countLabels (TextGrid me, long itier, const char32 *text); long TextGrid_countIntervalsWhere (TextGrid me, long tierNumber, int which_Melder_STRING, const char32 *criterion); long TextGrid_countPointsWhere (TextGrid me, long tierNumber, int which_Melder_STRING, const char32 *criterion); autoPointProcess TextGrid_getStartingPoints (TextGrid me, long itier, int which_Melder_STRING, const char32 *criterion); autoPointProcess TextGrid_getEndPoints (TextGrid me, long itier, int which_Melder_STRING, const char32 *criterion); autoPointProcess TextGrid_getCentrePoints (TextGrid me, long itier, int which_Melder_STRING, const char32 *criterion); autoPointProcess TextGrid_getPoints (TextGrid me, long itier, int which_Melder_STRING, const char32 *criterion); autoPointProcess TextGrid_getPoints_preceded (TextGrid me, long tierNumber, int which_Melder_STRING, const char32 *criterion, int which_Melder_STRING_precededBy, const char32 *criterion_precededBy); autoPointProcess TextGrid_getPoints_followed (TextGrid me, long tierNumber, int which_Melder_STRING, const char32 *criterion, int which_Melder_STRING_followedBy, const char32 *criterion_followedBy); Function TextGrid_checkSpecifiedTierNumberWithinRange (TextGrid me, long tierNumber); IntervalTier TextGrid_checkSpecifiedTierIsIntervalTier (TextGrid me, long tierNumber); TextTier TextGrid_checkSpecifiedTierIsPointTier (TextGrid me, long tierNumber); void TextGrid_addTier_copy (TextGrid me, Function tier); autoTextGrid TextGrid_merge (Collection textGrids); autoTextGrid TextGrid_extractPart (TextGrid me, double tmin, double tmax, int preserveTimes); autoTextGrid Label_to_TextGrid (Label me, double duration); autoTextGrid Label_Function_to_TextGrid (Label me, Any function); autoTextTier PointProcess_upto_TextTier (PointProcess me, const char32 *text); autoTableOfReal IntervalTier_downto_TableOfReal (IntervalTier me, const char32 *label); autoTableOfReal IntervalTier_downto_TableOfReal_any (IntervalTier me); autoTableOfReal TextTier_downto_TableOfReal (TextTier me, const char32 *label); autoTableOfReal TextTier_downto_TableOfReal_any (TextTier me); autoTextGrid PointProcess_to_TextGrid_vuv (PointProcess me, double maxT, double meanT); long TextInterval_labelLength (TextInterval me); long TextPoint_labelLength (TextPoint me); long IntervalTier_maximumLabelLength (IntervalTier me); long TextTier_maximumLabelLength (TextTier me); long TextGrid_maximumLabelLength (TextGrid me); void TextGrid_genericize (TextGrid me); void TextGrid_nativize (TextGrid me); void TextInterval_removeText (TextInterval me); void TextPoint_removeText (TextPoint me); void IntervalTier_removeText (IntervalTier me); void TextTier_removeText (TextTier me); void TextTier_removePoints (TextTier me, int which_Melder_STRING, const char32 *criterion); void TextGrid_removePoints (TextGrid me, long tierNumber, int which_Melder_STRING, const char32 *criterion); void TextGrid_insertBoundary (TextGrid me, int itier, double t); void TextGrid_removeBoundaryAtTime (TextGrid me, int itier, double t); void TextGrid_setIntervalText (TextGrid me, int itier, long iinterval, const char32 *text); void TextGrid_insertPoint (TextGrid me, int itier, double t, const char32 *mark); void TextGrid_setPointText (TextGrid me, int itier, long ipoint, const char32 *text); void TextGrid_writeToChronologicalTextFile (TextGrid me, MelderFile file); autoTextGrid TextGrid_readFromChronologicalTextFile (MelderFile file); autoTextGrid TextGrid_readFromCgnSyntaxFile (MelderFile file); autoTable TextGrid_downto_Table (TextGrid me, bool includeLineNumbers, int timeDecimals, bool includeTierNames, bool includeEmptyIntervals); void TextGrid_list (TextGrid me, bool includeLineNumbers, int timeDecimals, bool includeTierNames, bool includeEmptyIntervals); void TextGrid_correctRoundingErrors (TextGrid me); autoTextGrid TextGrids_concatenate (Collection me); /* End of file TextGrid.h */ #endif praat-6.0.04/fon/TextGridEditor.cpp000066400000000000000000002650121261542461700171150ustar00rootroot00000000000000/* TextGridEditor.cpp * * Copyright (C) 1992-2012,2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Erez Volk added FLAC support in 2007 */ #include "TextGridEditor.h" #include "EditorM.h" #include "SoundEditor.h" #include "Sound_and_Spectrogram.h" #include "TextGrid_Sound.h" #include "SpeechSynthesizer_and_TextGrid.h" #include "enums_getText.h" #include "TextGridEditor_enums.h" #include "enums_getValue.h" #include "TextGridEditor_enums.h" Thing_implement (TextGridEditor, TimeSoundAnalysisEditor, 0); #include "prefs_define.h" #include "TextGridEditor_prefs.h" #include "prefs_install.h" #include "TextGridEditor_prefs.h" #include "prefs_copyToInstance.h" #include "TextGridEditor_prefs.h" void structTextGridEditor :: v_info () { TextGridEditor_Parent :: v_info (); MelderInfo_writeLine (U"Selected tier: ", selectedTier); MelderInfo_writeLine (U"TextGrid uses text styles: ", p_useTextStyles); MelderInfo_writeLine (U"TextGrid font size: ", p_fontSize); MelderInfo_writeLine (U"TextGrid alignment: ", kGraphics_horizontalAlignment_getText (p_alignment)); } /********** UTILITIES **********/ static double _TextGridEditor_computeSoundY (TextGridEditor me) { TextGrid grid = (TextGrid) my data; int numberOfTiers = grid -> tiers -> size; bool showAnalysis = my v_hasAnalysis () && (my p_spectrogram_show || my p_pitch_show || my p_intensity_show || my p_formant_show) && (my d_longSound.data || my d_sound.data); int numberOfVisibleChannels = my d_sound.data ? (my d_sound.data -> ny > 8 ? 8 : my d_sound.data -> ny) : my d_longSound.data ? (my d_longSound.data -> numberOfChannels > 8 ? 8 : my d_longSound.data -> numberOfChannels) : 1; return my d_sound.data || my d_longSound.data ? numberOfTiers / (2.0 * numberOfVisibleChannels + numberOfTiers * (showAnalysis ? 1.8 : 1.3)) : 1.0; } static void _AnyTier_identifyClass (Function anyTier, IntervalTier *intervalTier, TextTier *textTier) { if (anyTier -> classInfo == classIntervalTier) { *intervalTier = (IntervalTier) anyTier; *textTier = NULL; } else { *intervalTier = NULL; *textTier = (TextTier) anyTier; } } static int _TextGridEditor_yWCtoTier (TextGridEditor me, double yWC) { TextGrid grid = (TextGrid) my data; int ntier = grid -> tiers -> size; double soundY = _TextGridEditor_computeSoundY (me); int itier = ntier - (int) floor (yWC / soundY * (double) ntier); if (itier < 1) itier = 1; if (itier > ntier) itier = ntier; return itier; } static void _TextGridEditor_timeToInterval (TextGridEditor me, double t, int itier, double *tmin, double *tmax) { TextGrid grid = (TextGrid) my data; IntervalTier intervalTier; TextTier textTier; _AnyTier_identifyClass ((Function) grid -> tiers -> item [itier], & intervalTier, & textTier); if (intervalTier) { long iinterval = IntervalTier_timeToIndex (intervalTier, t); TextInterval interval; if (iinterval == 0) { if (t < my tmin) { iinterval = 1; } else { iinterval = intervalTier -> intervals -> size; } } Melder_assert (iinterval >= 1); Melder_assert (iinterval <= intervalTier -> intervals -> size); interval = (TextInterval) intervalTier -> intervals -> item [iinterval]; *tmin = interval -> xmin; *tmax = interval -> xmax; } else { long n = textTier -> points -> size; if (n == 0) { *tmin = my tmin; *tmax = my tmax; } else { long ipointleft = AnyTier_timeToLowIndex (textTier, t); *tmin = ipointleft == 0 ? my tmin : ((TextPoint) textTier -> points -> item [ipointleft]) -> number; *tmax = ipointleft == n ? my tmax : ((TextPoint) textTier -> points -> item [ipointleft + 1]) -> number; } } if (*tmin < my tmin) *tmin = my tmin; // clip by FunctionEditor's time domain if (*tmax > my tmax) *tmax = my tmax; } static void checkTierSelection (TextGridEditor me, const char32 *verbPhrase) { TextGrid grid = (TextGrid) my data; if (my selectedTier < 1 || my selectedTier > grid -> tiers -> size) Melder_throw (U"To ", verbPhrase, U", first select a tier by clicking anywhere inside it."); } static long getSelectedInterval (TextGridEditor me) { TextGrid grid = (TextGrid) my data; Melder_assert (my selectedTier >= 1 || my selectedTier <= grid -> tiers -> size); IntervalTier tier = (IntervalTier) grid -> tiers -> item [my selectedTier]; Melder_assert (tier -> classInfo == classIntervalTier); return IntervalTier_timeToIndex (tier, my d_startSelection); } static long getSelectedLeftBoundary (TextGridEditor me) { TextGrid grid = (TextGrid) my data; Melder_assert (my selectedTier >= 1 || my selectedTier <= grid -> tiers -> size); IntervalTier tier = (IntervalTier) grid -> tiers -> item [my selectedTier]; Melder_assert (tier -> classInfo == classIntervalTier); return IntervalTier_hasBoundary (tier, my d_startSelection); } static long getSelectedPoint (TextGridEditor me) { TextGrid grid = (TextGrid) my data; Melder_assert (my selectedTier >= 1 || my selectedTier <= grid -> tiers -> size); TextTier tier = (TextTier) grid -> tiers -> item [my selectedTier]; Melder_assert (tier -> classInfo == classTextTier); return AnyTier_hasPoint (tier, my d_startSelection); } static void scrollToView (TextGridEditor me, double t) { if (t <= my d_startWindow) { FunctionEditor_shift (me, t - my d_startWindow - 0.618 * (my d_endWindow - my d_startWindow), true); } else if (t >= my d_endWindow) { FunctionEditor_shift (me, t - my d_endWindow + 0.618 * (my d_endWindow - my d_startWindow), true); } else { FunctionEditor_marksChanged (me, true); } } /********** METHODS **********/ /* * The main invariant of the TextGridEditor is that the selected interval * always has the cursor in it, and that the cursor always selects an interval * if the selected tier is an interval tier. */ /***** FILE MENU *****/ static void menu_cb_ExtractSelectedTextGrid_preserveTimes (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); if (my d_endSelection <= my d_startSelection) Melder_throw (U"No selection."); autoTextGrid extract = TextGrid_extractPart ((TextGrid) my data, my d_startSelection, my d_endSelection, true); Editor_broadcastPublication (me, extract.transfer()); } static void menu_cb_ExtractSelectedTextGrid_timeFromZero (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); if (my d_endSelection <= my d_startSelection) Melder_throw (U"No selection."); autoTextGrid extract = TextGrid_extractPart ((TextGrid) my data, my d_startSelection, my d_endSelection, false); Editor_broadcastPublication (me, extract.transfer()); } void structTextGridEditor :: v_createMenuItems_file_extract (EditorMenu menu) { TextGridEditor_Parent :: v_createMenuItems_file_extract (menu); extractSelectedTextGridPreserveTimesButton = EditorMenu_addCommand (menu, U"Extract selected TextGrid (preserve times)", 0, menu_cb_ExtractSelectedTextGrid_preserveTimes); extractSelectedTextGridTimeFromZeroButton = EditorMenu_addCommand (menu, U"Extract selected TextGrid (time from 0)", 0, menu_cb_ExtractSelectedTextGrid_timeFromZero); } static void menu_cb_WriteToTextFile (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); EDITOR_FORM_WRITE (U"Save as TextGrid text file", 0) Melder_sprint (defaultName,300, my data -> name, U".TextGrid"); EDITOR_DO_WRITE Data_writeToTextFile (my data, file); EDITOR_END } void structTextGridEditor :: v_createMenuItems_file_write (EditorMenu menu) { TextGridEditor_Parent :: v_createMenuItems_file_write (menu); EditorMenu_addCommand (menu, U"Save TextGrid as text file...", 'S', menu_cb_WriteToTextFile); } static void menu_cb_DrawVisibleTextGrid (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); EDITOR_FORM (U"Draw visible TextGrid", 0) my v_form_pictureWindow (cmd); my v_form_pictureMargins (cmd); my v_form_pictureSelection (cmd); BOOLEAN (U"Garnish", my default_picture_garnish ()); EDITOR_OK my v_ok_pictureWindow (cmd); my v_ok_pictureMargins (cmd); my v_ok_pictureSelection (cmd); SET_INTEGER (U"Garnish", my pref_picture_garnish ()); EDITOR_DO my v_do_pictureWindow (cmd); my v_do_pictureMargins (cmd); my v_do_pictureSelection (cmd); my pref_picture_garnish () = GET_INTEGER (U"Garnish"); Editor_openPraatPicture (me); TextGrid_Sound_draw ((TextGrid) my data, NULL, my pictureGraphics, my d_startWindow, my d_endWindow, true, my p_useTextStyles, my pref_picture_garnish ()); FunctionEditor_garnish (me); Editor_closePraatPicture (me); EDITOR_END } static void menu_cb_DrawVisibleSoundAndTextGrid (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); EDITOR_FORM (U"Draw visible sound and TextGrid", 0) my v_form_pictureWindow (cmd); my v_form_pictureMargins (cmd); my v_form_pictureSelection (cmd); BOOLEAN (U"Garnish", my default_picture_garnish ()); EDITOR_OK my v_ok_pictureWindow (cmd); my v_ok_pictureMargins (cmd); my v_ok_pictureSelection (cmd); SET_INTEGER (U"Garnish", my pref_picture_garnish ()); EDITOR_DO my v_do_pictureWindow (cmd); my v_do_pictureMargins (cmd); my v_do_pictureSelection (cmd); my pref_picture_garnish () = GET_INTEGER (U"Garnish"); Editor_openPraatPicture (me); {// scope autoSound sound = my d_longSound.data ? LongSound_extractPart (my d_longSound.data, my d_startWindow, my d_endWindow, true) : Sound_extractPart (my d_sound.data, my d_startWindow, my d_endWindow, kSound_windowShape_RECTANGULAR, 1.0, true); TextGrid_Sound_draw ((TextGrid) my data, sound.get(), my pictureGraphics, my d_startWindow, my d_endWindow, true, my p_useTextStyles, my pref_picture_garnish ()); } FunctionEditor_garnish (me); Editor_closePraatPicture (me); EDITOR_END } void structTextGridEditor :: v_createMenuItems_file_draw (EditorMenu menu) { TextGridEditor_Parent :: v_createMenuItems_file_draw (menu); EditorMenu_addCommand (menu, U"Draw visible TextGrid...", 0, menu_cb_DrawVisibleTextGrid); if (d_sound.data || d_longSound.data) EditorMenu_addCommand (menu, U"Draw visible sound and TextGrid...", 0, menu_cb_DrawVisibleSoundAndTextGrid); } /***** EDIT MENU *****/ #ifndef macintosh static void menu_cb_Cut (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); GuiText_cut (my text); } static void menu_cb_Copy (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); GuiText_copy (my text); } static void menu_cb_Paste (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); GuiText_paste (my text); } static void menu_cb_Erase (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); GuiText_remove (my text); } #endif static void menu_cb_Genericize (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); Editor_save (me, U"Convert to Backslash Trigraphs"); TextGrid_genericize ((TextGrid) my data); FunctionEditor_updateText (me); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_Nativize (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); Editor_save (me, U"Convert to Unicode"); TextGrid_nativize ((TextGrid) my data); FunctionEditor_updateText (me); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } /***** QUERY MENU *****/ static void menu_cb_GetStartingPointOfInterval (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); TextGrid grid = (TextGrid) my data; checkTierSelection (me, U"query the starting point of an interval"); Function anyTier = (Function) grid -> tiers -> item [my selectedTier]; if (anyTier -> classInfo == classIntervalTier) { IntervalTier tier = (IntervalTier) anyTier; long iinterval = IntervalTier_timeToIndex (tier, my d_startSelection); double time = iinterval < 1 || iinterval > tier -> intervals -> size ? NUMundefined : ((TextInterval) tier -> intervals -> item [iinterval]) -> xmin; Melder_informationReal (time, U"seconds"); } else { Melder_throw (U"The selected tier is not an interval tier."); } } static void menu_cb_GetEndPointOfInterval (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); TextGrid grid = (TextGrid) my data; checkTierSelection (me, U"query the end point of an interval"); Function anyTier = (Function) grid -> tiers -> item [my selectedTier]; if (anyTier -> classInfo == classIntervalTier) { IntervalTier tier = (IntervalTier) anyTier; long iinterval = IntervalTier_timeToIndex (tier, my d_startSelection); double time = iinterval < 1 || iinterval > tier -> intervals -> size ? NUMundefined : ((TextInterval) tier -> intervals -> item [iinterval]) -> xmax; Melder_informationReal (time, U"seconds"); } else { Melder_throw (U"The selected tier is not an interval tier."); } } static void menu_cb_GetLabelOfInterval (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); TextGrid grid = (TextGrid) my data; checkTierSelection (me, U"query the label of an interval"); Function anyTier = (Function) grid -> tiers -> item [my selectedTier]; if (anyTier -> classInfo == classIntervalTier) { IntervalTier tier = (IntervalTier) anyTier; long iinterval = IntervalTier_timeToIndex (tier, my d_startSelection); const char32 *label = iinterval < 1 || iinterval > tier -> intervals -> size ? U"" : ((TextInterval) tier -> intervals -> item [iinterval]) -> text; Melder_information (label); } else { Melder_throw (U"The selected tier is not an interval tier."); } } /***** VIEW MENU *****/ static void do_selectAdjacentTier (TextGridEditor me, bool previous) { TextGrid grid = (TextGrid) my data; long n = grid -> tiers -> size; if (n >= 2) { my selectedTier = previous ? my selectedTier > 1 ? my selectedTier - 1 : n : my selectedTier < n ? my selectedTier + 1 : 1; _TextGridEditor_timeToInterval (me, my d_startSelection, my selectedTier, & my d_startSelection, & my d_endSelection); FunctionEditor_marksChanged (me, true); } } static void menu_cb_SelectPreviousTier (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_selectAdjacentTier (me, true); } static void menu_cb_SelectNextTier (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_selectAdjacentTier (me, false); } static void do_selectAdjacentInterval (TextGridEditor me, bool previous, bool shift) { TextGrid grid = (TextGrid) my data; IntervalTier intervalTier; TextTier textTier; if (my selectedTier < 1 || my selectedTier > grid -> tiers -> size) return; _AnyTier_identifyClass ((Function) grid -> tiers -> item [my selectedTier], & intervalTier, & textTier); if (intervalTier) { long n = intervalTier -> intervals -> size; if (n >= 2) { TextInterval interval; long iinterval = IntervalTier_timeToIndex (intervalTier, my d_startSelection); if (shift) { long binterval = IntervalTier_timeToIndex (intervalTier, my d_startSelection); long einterval = IntervalTier_timeToIndex (intervalTier, my d_endSelection); if (my d_endSelection == intervalTier -> xmax) einterval ++; if (binterval < iinterval && einterval > iinterval + 1) { interval = (TextInterval) intervalTier -> intervals -> item [iinterval]; my d_startSelection = interval -> xmin; my d_endSelection = interval -> xmax; } else if (previous) { if (einterval > iinterval + 1) { if (einterval <= n + 1) { interval = (TextInterval) intervalTier -> intervals -> item [einterval - 1]; my d_endSelection = interval -> xmin; } } else if (binterval > 1) { interval = (TextInterval) intervalTier -> intervals -> item [binterval - 1]; my d_startSelection = interval -> xmin; } } else { if (binterval < iinterval) { if (binterval > 0) { interval = (TextInterval) intervalTier -> intervals -> item [binterval]; my d_startSelection = interval -> xmax; } } else if (einterval <= n) { interval = (TextInterval) intervalTier -> intervals -> item [einterval]; my d_endSelection = interval -> xmax; } } } else { iinterval = previous ? iinterval > 1 ? iinterval - 1 : n : iinterval < n ? iinterval + 1 : 1; interval = (TextInterval) intervalTier -> intervals -> item [iinterval]; my d_startSelection = interval -> xmin; my d_endSelection = interval -> xmax; } scrollToView (me, iinterval == n ? my d_startSelection : iinterval == 1 ? my d_endSelection : (my d_startSelection + my d_endSelection) / 2); } } else { long n = textTier -> points -> size; if (n >= 2) { TextPoint point; long ipoint = AnyTier_timeToHighIndex (textTier, my d_startSelection); ipoint = previous ? ipoint > 1 ? ipoint - 1 : n : ipoint < n ? ipoint + 1 : 1; point = (TextPoint) textTier -> points -> item [ipoint]; my d_startSelection = my d_endSelection = point -> number; scrollToView (me, my d_startSelection); } } } static void menu_cb_SelectPreviousInterval (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_selectAdjacentInterval (me, true, false); } static void menu_cb_SelectNextInterval (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_selectAdjacentInterval (me, false, false); } static void menu_cb_ExtendSelectPreviousInterval (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_selectAdjacentInterval (me, true, true); } static void menu_cb_ExtendSelectNextInterval (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_selectAdjacentInterval (me, false, true); } static void menu_cb_MoveBtoZero (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); double zero = Sound_getNearestZeroCrossing (my d_sound.data, my d_startSelection, 1); // STEREO BUG if (NUMdefined (zero)) { my d_startSelection = zero; if (my d_startSelection > my d_endSelection) { double dummy = my d_startSelection; my d_startSelection = my d_endSelection; my d_endSelection = dummy; } FunctionEditor_marksChanged (me, true); } } static void menu_cb_MoveCursorToZero (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); double zero = Sound_getNearestZeroCrossing (my d_sound.data, 0.5 * (my d_startSelection + my d_endSelection), 1); // STEREO BUG if (NUMdefined (zero)) { my d_startSelection = my d_endSelection = zero; FunctionEditor_marksChanged (me, true); } } static void menu_cb_MoveEtoZero (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); double zero = Sound_getNearestZeroCrossing (my d_sound.data, my d_endSelection, 1); // STEREO BUG if (NUMdefined (zero)) { my d_endSelection = zero; if (my d_startSelection > my d_endSelection) { double dummy = my d_startSelection; my d_startSelection = my d_endSelection; my d_endSelection = dummy; } FunctionEditor_marksChanged (me, true); } } /***** PITCH MENU *****/ static void menu_cb_DrawTextGridAndPitch (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); EDITOR_FORM (U"Draw TextGrid and Pitch separately", 0) my v_form_pictureWindow (cmd); LABEL (U"", U"TextGrid:") BOOLEAN (U"Show boundaries and points", my default_picture_showBoundaries ()); LABEL (U"", U"Pitch:") BOOLEAN (U"Speckle", my default_picture_pitch_speckle ()); my v_form_pictureMargins (cmd); my v_form_pictureSelection (cmd); BOOLEAN (U"Garnish", my default_picture_garnish ()); EDITOR_OK my v_ok_pictureWindow (cmd); SET_INTEGER (U"Show boundaries and points", my pref_picture_showBoundaries ()); SET_INTEGER (U"Speckle", my pref_picture_pitch_speckle ()); my v_ok_pictureMargins (cmd); my v_ok_pictureSelection (cmd); SET_INTEGER (U"Garnish", my pref_picture_garnish ()); EDITOR_DO my v_do_pictureWindow (cmd); my pref_picture_showBoundaries () = GET_INTEGER (U"Show boundaries and points"); my pref_picture_pitch_speckle () = GET_INTEGER (U"Speckle"); my v_do_pictureMargins (cmd); my v_do_pictureSelection (cmd); my pref_picture_garnish () = GET_INTEGER (U"Garnish"); if (! my p_pitch_show) Melder_throw (U"No pitch contour is visible.\nFirst choose \"Show pitch\" from the Pitch menu."); if (! my d_pitch) { TimeSoundAnalysisEditor_computePitch (me); if (! my d_pitch) Melder_throw (U"Cannot compute pitch."); } Editor_openPraatPicture (me); double pitchFloor_hidden = Function_convertStandardToSpecialUnit (my d_pitch.peek(), my p_pitch_floor, Pitch_LEVEL_FREQUENCY, my p_pitch_unit); double pitchCeiling_hidden = Function_convertStandardToSpecialUnit (my d_pitch.peek(), my p_pitch_ceiling, Pitch_LEVEL_FREQUENCY, my p_pitch_unit); double pitchFloor_overt = Function_convertToNonlogarithmic (my d_pitch.peek(), pitchFloor_hidden, Pitch_LEVEL_FREQUENCY, my p_pitch_unit); double pitchCeiling_overt = Function_convertToNonlogarithmic (my d_pitch.peek(), pitchCeiling_hidden, Pitch_LEVEL_FREQUENCY, my p_pitch_unit); double pitchViewFrom_overt = my p_pitch_viewFrom < my p_pitch_viewTo ? my p_pitch_viewFrom : pitchFloor_overt; double pitchViewTo_overt = my p_pitch_viewFrom < my p_pitch_viewTo ? my p_pitch_viewTo : pitchCeiling_overt; TextGrid_Pitch_drawSeparately ((TextGrid) my data, my d_pitch.peek(), my pictureGraphics, my d_startWindow, my d_endWindow, pitchViewFrom_overt, pitchViewTo_overt, GET_INTEGER (U"Show boundaries and points"), my p_useTextStyles, GET_INTEGER (U"Garnish"), GET_INTEGER (U"Speckle"), my p_pitch_unit); FunctionEditor_garnish (me); Editor_closePraatPicture (me); EDITOR_END } /***** INTERVAL MENU *****/ static void insertBoundaryOrPoint (TextGridEditor me, int itier, double t1, double t2, bool insertSecond) { TextGrid grid = (TextGrid) my data; IntervalTier intervalTier; TextTier textTier; int ntiers = grid -> tiers -> size; if (itier < 1 || itier > ntiers) Melder_throw (U"No tier ", itier, U"."); _AnyTier_identifyClass ((Function) grid -> tiers -> item [itier], & intervalTier, & textTier); Melder_assert (t1 <= t2); if (intervalTier) { autoTextInterval rightNewInterval, midNewInterval; bool t1IsABoundary = IntervalTier_hasTime (intervalTier, t1); bool t2IsABoundary = IntervalTier_hasTime (intervalTier, t2); if (t1 == t2 && t1IsABoundary) Melder_throw (U"Cannot add a boundary at ", Melder_fixed (t1, 6), U" seconds, because there is already a boundary there."); if (t1IsABoundary && t2IsABoundary) Melder_throw (U"Cannot add boundaries at ", Melder_fixed (t1, 6), U" and ", Melder_fixed (t2, 6), U" seconds, because there are already boundaries there."); long iinterval = IntervalTier_timeToIndex (intervalTier, t1); //Melder_casual ("iinterval %ld, t = %f", iinterval, t1); long iinterval2 = t1 == t2 ? iinterval : IntervalTier_timeToIndex (intervalTier, t2); //Melder_casual ("iinterval2 %ld, t = %f", iinterval2, t2); if (iinterval == 0 || iinterval2 == 0) Melder_throw (U"The selection is outside the time domain of the intervals."); long correctedIinterval2 = t2IsABoundary && iinterval2 == intervalTier -> intervals -> size ? iinterval2 + 1 : iinterval2; if (correctedIinterval2 > iinterval + 1 || (correctedIinterval2 > iinterval && ! t2IsABoundary)) Melder_throw (U"The selection straddles a boundary."); TextInterval interval = (TextInterval) intervalTier -> intervals -> item [iinterval]; if (t1 == t2) { Editor_save (me, U"Add boundary"); } else { Editor_save (me, U"Add interval"); } if (itier == my selectedTier) { /* * Divide up the label text into left, mid and right, depending on where the text selection is. */ long left, right; char32 *text = GuiText_getStringAndSelectionPosition (my text, & left, & right); bool wholeTextIsSelected = right - left == str32len (text); rightNewInterval = TextInterval_create (t2, interval -> xmax, text + right); text [right] = '\0'; midNewInterval = TextInterval_create (t1, t2, text + left); if (! wholeTextIsSelected || t1 != t2) text [left] = U'\0'; TextInterval_setText (interval, text); Melder_free (text); } else { /* * Move the text to the left of the boundary. */ rightNewInterval = TextInterval_create (t2, interval -> xmax, U""); midNewInterval = TextInterval_create (t1, t2, U""); } if (t1IsABoundary) { /* * Merge mid with left interval. */ if (interval -> xmin != t1) Melder_fatal (U"Boundary unequal: ", interval -> xmin, U" versus ", t1, U"."); interval -> xmax = t2; TextInterval_setText (interval, Melder_cat (interval -> text, midNewInterval -> text)); } else if (t2IsABoundary) { /* * Merge mid and right interval. */ if (interval -> xmax != t2) Melder_fatal (U"Boundary unequal: ", interval -> xmax, U" versus ", t2, U"."); interval -> xmax = t1; Melder_assert (rightNewInterval -> xmin == t2); Melder_assert (rightNewInterval -> xmax == t2); rightNewInterval -> xmin = t1; TextInterval_setText (rightNewInterval.get(), Melder_cat (midNewInterval -> text, rightNewInterval -> text)); } else { interval -> xmax = t1; if (t1 != t2) Collection_addItem (intervalTier -> intervals, midNewInterval.transfer()); } Collection_addItem (intervalTier -> intervals, rightNewInterval.transfer()); if (insertSecond && ntiers >= 2 && t1 == t2) { /* * Find the last time before t on another tier. */ double tlast = interval -> xmin, tmin, tmax; for (int jtier = 1; jtier <= ntiers; jtier ++) if (jtier != itier) { _TextGridEditor_timeToInterval (me, t1, jtier, & tmin, & tmax); if (tmin > tlast) { tlast = tmin; } } if (tlast > interval -> xmin && tlast < t1) { autoTextInterval newInterval = TextInterval_create (tlast, t1, U""); interval -> xmax = tlast; Collection_addItem (intervalTier -> intervals, newInterval.transfer()); } } } else { if (AnyTier_hasPoint (textTier, t1)) Melder_throw (U"Cannot add a point at ", Melder_fixed (t1, 6), U" seconds, because there is already a point there."); Editor_save (me, U"Add point"); autoTextPoint newPoint = TextPoint_create (t1, U""); Collection_addItem (textTier -> points, newPoint.transfer()); } my d_startSelection = my d_endSelection = t1; } static void do_insertIntervalOnTier (TextGridEditor me, int itier) { try { insertBoundaryOrPoint (me, itier, my playingCursor || my playingSelection ? my playCursor : my d_startSelection, my playingCursor || my playingSelection ? my playCursor : my d_endSelection, true); my selectedTier = itier; FunctionEditor_marksChanged (me, true); Editor_broadcastDataChanged (me); } catch (MelderError) { Melder_throw (U"Interval not inserted."); } } static void menu_cb_InsertIntervalOnTier1 (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_insertIntervalOnTier (me, 1); } static void menu_cb_InsertIntervalOnTier2 (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_insertIntervalOnTier (me, 2); } static void menu_cb_InsertIntervalOnTier3 (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_insertIntervalOnTier (me, 3); } static void menu_cb_InsertIntervalOnTier4 (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_insertIntervalOnTier (me, 4); } static void menu_cb_InsertIntervalOnTier5 (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_insertIntervalOnTier (me, 5); } static void menu_cb_InsertIntervalOnTier6 (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_insertIntervalOnTier (me, 6); } static void menu_cb_InsertIntervalOnTier7 (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_insertIntervalOnTier (me, 7); } static void menu_cb_InsertIntervalOnTier8 (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_insertIntervalOnTier (me, 8); } static void menu_cb_AlignInterval (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); TextGrid grid = (TextGrid) my data; checkTierSelection (me, U"align words"); AnyTier tier = static_cast (grid -> tiers -> item [my selectedTier]); if (tier -> classInfo != classIntervalTier) Melder_throw (U"Alignment works only for interval tiers, whereas tier ", my selectedTier, U" is a point tier.\nSelect an interval tier instead."); long intervalNumber = getSelectedInterval (me); if (! intervalNumber) Melder_throw (U"Select an interval first"); if (! my p_align_includeWords && ! my p_align_includePhonemes) Melder_throw (U"Nothing to be done.\nPlease switch on \"Include words\" and/or \"Include phonemes\" in the \"Alignment settings\"."); {// scope autoMelderProgressOff noprogress; Function anySound = my d_sound.data; if (my d_longSound.data) anySound = my d_longSound.data; Editor_save (me, U"Align interval"); TextGrid_anySound_alignInterval (grid, anySound, my selectedTier, intervalNumber, my p_align_language, my p_align_includeWords, my p_align_includePhonemes); } FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_AlignmentSettings (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); EDITOR_FORM (U"Alignment settings", 0) OPTIONMENU (U"Language", Strings_findString (espeakdata_voices_names, U"English")) for (long i = 1; i <= espeakdata_voices_names -> numberOfStrings; i ++) { OPTION ((const char32 *) espeakdata_voices_names -> strings [i]); } BOOLEAN (U"Include words", my default_align_includeWords ()) BOOLEAN (U"Include phonemes", my default_align_includePhonemes ()) BOOLEAN (U"Allow silences", my default_align_allowSilences ()) EDITOR_OK long prefVoice = Strings_findString (espeakdata_voices_names, my p_align_language); if (prefVoice == 0) prefVoice = Strings_findString (espeakdata_voices_names, U"English"); SET_INTEGER (U"Language", prefVoice); SET_INTEGER (U"Include words", my p_align_includeWords) SET_INTEGER (U"Include phonemes", my p_align_includePhonemes) SET_INTEGER (U"Allow silences", my p_align_allowSilences) EDITOR_DO //my pref_align_language () = my p_align_language = GET_ENUM (kTextGrid_language, U"Language"); pref_str32cpy2 (my pref_align_language (), my p_align_language, GET_STRING (U"Language")); my pref_align_includeWords () = my p_align_includeWords = GET_INTEGER (U"Include words"); my pref_align_includePhonemes () = my p_align_includePhonemes = GET_INTEGER (U"Include phonemes"); my pref_align_allowSilences () = my p_align_allowSilences = GET_INTEGER (U"Allow silences"); EDITOR_END } /***** BOUNDARY/POINT MENU *****/ static void menu_cb_RemovePointOrBoundary (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); TextGrid grid = (TextGrid) my data; checkTierSelection (me, U"remove a point or boundary"); Function anyTier = (Function) grid -> tiers -> item [my selectedTier]; if (anyTier -> classInfo == classIntervalTier) { IntervalTier tier = (IntervalTier) anyTier; long selectedLeftBoundary = getSelectedLeftBoundary (me); if (! selectedLeftBoundary) Melder_throw (U"To remove a boundary, first click on it."); Editor_save (me, U"Remove boundary"); IntervalTier_removeLeftBoundary (tier, selectedLeftBoundary); } else { TextTier tier = (TextTier) anyTier; long selectedPoint = getSelectedPoint (me); if (! selectedPoint) Melder_throw (U"To remove a point, first click on it."); Editor_save (me, U"Remove point"); Collection_removeItem (tier -> points, selectedPoint); } FunctionEditor_updateText (me); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void do_movePointOrBoundary (TextGridEditor me, int where) { double position; TextGrid grid = (TextGrid) my data; if (where == 0 && my d_sound.data == NULL) return; checkTierSelection (me, U"move a point or boundary"); Function anyTier = (Function) grid -> tiers -> item [my selectedTier]; if (anyTier -> classInfo == classIntervalTier) { IntervalTier tier = (IntervalTier) anyTier; static const char32 *boundarySaveText [3] { U"Move boundary to zero crossing", U"Move boundary to B", U"Move boundary to E" }; TextInterval left, right; long selectedLeftBoundary = getSelectedLeftBoundary (me); if (! selectedLeftBoundary) Melder_throw (U"To move a boundary, first click on it."); left = (TextInterval) tier -> intervals -> item [selectedLeftBoundary - 1]; right = (TextInterval) tier -> intervals -> item [selectedLeftBoundary]; position = where == 1 ? my d_startSelection : where == 2 ? my d_endSelection : Sound_getNearestZeroCrossing (my d_sound.data, left -> xmax, 1); // STEREO BUG if (position == NUMundefined) Melder_throw (U"There is no zero crossing to move to."); if (position <= left -> xmin || position >= right -> xmax) Melder_throw (U"Cannot move a boundary past its neighbour."); Editor_save (me, boundarySaveText [where]); left -> xmax = right -> xmin = my d_startSelection = my d_endSelection = position; } else { TextTier tier = (TextTier) anyTier; static const char32 *pointSaveText [3] { U"Move point to zero crossing", U"Move point to B", U"Move point to E" }; TextPoint point; long selectedPoint = getSelectedPoint (me); if (! selectedPoint) Melder_throw (U"To move a point, first click on it."); point = (TextPoint) tier -> points -> item [selectedPoint]; position = where == 1 ? my d_startSelection : where == 2 ? my d_endSelection : Sound_getNearestZeroCrossing (my d_sound.data, point -> number, 1); // STEREO BUG if (position == NUMundefined) Melder_throw (U"There is no zero crossing to move to."); Editor_save (me, pointSaveText [where]); point -> number = my d_startSelection = my d_endSelection = position; } FunctionEditor_marksChanged (me, true); // because cursor has moved Editor_broadcastDataChanged (me); } static void menu_cb_MoveToB (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_movePointOrBoundary (me, 1); } static void menu_cb_MoveToE (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_movePointOrBoundary (me, 2); } static void menu_cb_MoveToZero (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_movePointOrBoundary (me, 0); } static void do_insertOnTier (TextGridEditor me, int itier) { try { insertBoundaryOrPoint (me, itier, my playingCursor || my playingSelection ? my playCursor : my d_startSelection, my playingCursor || my playingSelection ? my playCursor : my d_endSelection, false); my selectedTier = itier; FunctionEditor_marksChanged (me, true); Editor_broadcastDataChanged (me); } catch (MelderError) { Melder_throw (U"Boundary or point not inserted."); } } static void menu_cb_InsertOnSelectedTier (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_insertOnTier (me, my selectedTier); } static void menu_cb_InsertOnTier1 (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_insertOnTier (me, 1); } static void menu_cb_InsertOnTier2 (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_insertOnTier (me, 2); } static void menu_cb_InsertOnTier3 (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_insertOnTier (me, 3); } static void menu_cb_InsertOnTier4 (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_insertOnTier (me, 4); } static void menu_cb_InsertOnTier5 (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_insertOnTier (me, 5); } static void menu_cb_InsertOnTier6 (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_insertOnTier (me, 6); } static void menu_cb_InsertOnTier7 (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_insertOnTier (me, 7); } static void menu_cb_InsertOnTier8 (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_insertOnTier (me, 8); } static void menu_cb_InsertOnAllTiers (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); TextGrid grid = (TextGrid) my data; int saveTier = my selectedTier; for (int itier = 1; itier <= grid -> tiers -> size; itier ++) { do_insertOnTier (me, itier); } my selectedTier = saveTier; // only if everything went right; otherwise, the tier where something went wrong will stand selected } /***** SEARCH MENU *****/ static void findInTier (TextGridEditor me) { TextGrid grid = (TextGrid) my data; checkTierSelection (me, U"find a text"); Function anyTier = (Function) grid -> tiers -> item [my selectedTier]; if (anyTier -> classInfo == classIntervalTier) { IntervalTier tier = (IntervalTier) anyTier; long iinterval = IntervalTier_timeToIndex (tier, my d_startSelection) + 1; while (iinterval <= tier -> intervals -> size) { TextInterval interval = (TextInterval) tier -> intervals -> item [iinterval]; char32 *text = interval -> text; if (text) { char32 *position = str32str (text, my findString); if (position) { my d_startSelection = interval -> xmin; my d_endSelection = interval -> xmax; scrollToView (me, my d_startSelection); GuiText_setSelection (my text, position - text, position - text + str32len (my findString)); return; } } iinterval ++; } if (iinterval > tier -> intervals -> size) Melder_beep (); } else { TextTier tier = (TextTier) anyTier; long ipoint = AnyTier_timeToLowIndex (tier, my d_startSelection) + 1; while (ipoint <= tier -> points -> size) { TextPoint point = (TextPoint) tier -> points -> item [ipoint]; char32 *text = point -> mark; if (text) { char32 *position = str32str (text, my findString); if (position) { my d_startSelection = my d_endSelection = point -> number; scrollToView (me, point -> number); GuiText_setSelection (my text, position - text, position - text + str32len (my findString)); return; } } ipoint ++; } if (ipoint > tier -> points -> size) Melder_beep (); } } static void do_find (TextGridEditor me) { if (my findString) { long left, right; autostring32 label = GuiText_getStringAndSelectionPosition (my text, & left, & right); char32 *position = str32str (label.peek() + right, my findString); // CRLF BUG? if (position) { GuiText_setSelection (my text, position - label.peek(), position - label.peek() + str32len (my findString)); } else { findInTier (me); } } } static void menu_cb_Find (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); EDITOR_FORM (U"Find text", 0) LABEL (U"", U"Text:") TEXTFIELD (U"string", U"") EDITOR_OK EDITOR_DO Melder_free (my findString); my findString = Melder_dup_f (GET_STRING (U"string")); do_find (me); EDITOR_END } static void menu_cb_FindAgain (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); do_find (me); } static void checkSpellingInTier (TextGridEditor me) { TextGrid grid = (TextGrid) my data; checkTierSelection (me, U"check spelling"); Function anyTier = (Function) grid -> tiers -> item [my selectedTier]; if (anyTier -> classInfo == classIntervalTier) { IntervalTier tier = (IntervalTier) anyTier; long iinterval = IntervalTier_timeToIndex (tier, my d_startSelection) + 1; while (iinterval <= tier -> intervals -> size) { TextInterval interval = (TextInterval) tier -> intervals -> item [iinterval]; char32 *text = interval -> text; if (text) { long position = 0; char32 *notAllowed = SpellingChecker_nextNotAllowedWord (my spellingChecker, text, & position); if (notAllowed) { my d_startSelection = interval -> xmin; my d_endSelection = interval -> xmax; scrollToView (me, my d_startSelection); GuiText_setSelection (my text, position, position + str32len (notAllowed)); return; } } iinterval ++; } if (iinterval > tier -> intervals -> size) Melder_beep (); } else { TextTier tier = (TextTier) anyTier; long ipoint = AnyTier_timeToLowIndex (tier, my d_startSelection) + 1; while (ipoint <= tier -> points -> size) { TextPoint point = (TextPoint) tier -> points -> item [ipoint]; char32 *text = point -> mark; if (text) { long position = 0; char32 *notAllowed = SpellingChecker_nextNotAllowedWord (my spellingChecker, text, & position); if (notAllowed) { my d_startSelection = my d_endSelection = point -> number; scrollToView (me, point -> number); GuiText_setSelection (my text, position, position + str32len (notAllowed)); return; } } ipoint ++; } if (ipoint > tier -> points -> size) Melder_beep (); } } static void menu_cb_CheckSpelling (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); if (my spellingChecker) { long left, right; autostring32 label = GuiText_getStringAndSelectionPosition (my text, & left, & right); long position = right; char32 *notAllowed = SpellingChecker_nextNotAllowedWord (my spellingChecker, label.peek(), & position); if (notAllowed) { GuiText_setSelection (my text, position, position + str32len (notAllowed)); } else { checkSpellingInTier (me); } } } static void menu_cb_CheckSpellingInInterval (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); if (my spellingChecker) { long left, right; autostring32 label = GuiText_getStringAndSelectionPosition (my text, & left, & right); long position = right; char32 *notAllowed = SpellingChecker_nextNotAllowedWord (my spellingChecker, label.peek(), & position); if (notAllowed) { GuiText_setSelection (my text, position, position + str32len (notAllowed)); } } } static void menu_cb_AddToUserDictionary (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); if (my spellingChecker) { autostring32 word = GuiText_getSelection (my text); SpellingChecker_addNewWord (my spellingChecker, word.peek()); Editor_broadcastDataChanged (me); } } /***** TIER MENU *****/ static void menu_cb_RenameTier (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); EDITOR_FORM (U"Rename tier", 0) SENTENCE (U"Name", U""); EDITOR_OK TextGrid grid = (TextGrid) my data; checkTierSelection (me, U"rename a tier"); Daata tier = (Daata) grid -> tiers -> item [my selectedTier]; SET_STRING (U"Name", tier -> name ? tier -> name : U"") EDITOR_DO TextGrid grid = (TextGrid) my data; checkTierSelection (me, U"rename a tier"); Function tier = (Function) grid -> tiers -> item [my selectedTier]; Editor_save (me, U"Rename tier"); char32 *newName = GET_STRING (U"Name"); Thing_setName (tier, newName); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); EDITOR_END } static void menu_cb_PublishTier (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); TextGrid grid = (TextGrid) my data; checkTierSelection (me, U"publish a tier"); Function tier = (Function) grid -> tiers -> item [my selectedTier]; autoTextGrid publish = TextGrid_createWithoutTiers (1e30, -1e30); TextGrid_addTier_copy (publish.peek(), tier); Thing_setName (publish.peek(), tier -> name); Editor_broadcastPublication (me, publish.transfer()); } static void menu_cb_RemoveAllTextFromTier (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); TextGrid grid = (TextGrid) my data; checkTierSelection (me, U"remove all text from a tier"); IntervalTier intervalTier; TextTier textTier; _AnyTier_identifyClass ((Function) grid -> tiers -> item [my selectedTier], & intervalTier, & textTier); Editor_save (me, U"Remove text from tier"); if (intervalTier) { IntervalTier_removeText (intervalTier); } else { TextTier_removeText (textTier); } FunctionEditor_updateText (me); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_RemoveTier (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); TextGrid grid = (TextGrid) my data; if (grid -> tiers -> size <= 1) { Melder_throw (U"Sorry, I refuse to remove the last tier."); } checkTierSelection (me, U"remove a tier"); Editor_save (me, U"Remove tier"); Collection_removeItem (grid -> tiers, my selectedTier); my selectedTier = 1; FunctionEditor_updateText (me); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } static void menu_cb_AddIntervalTier (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); EDITOR_FORM (U"Add interval tier", 0) NATURAL (U"Position", U"1 (= at top)") SENTENCE (U"Name", U"") EDITOR_OK TextGrid grid = (TextGrid) my data; SET_STRING (U"Position", Melder_cat (grid -> tiers -> size + 1, U" (= at bottom)")) SET_STRING (U"Name", U"") EDITOR_DO TextGrid grid = (TextGrid) my data; int position = GET_INTEGER (U"Position"); char32 *name = GET_STRING (U"Name"); autoIntervalTier tier = IntervalTier_create (grid -> xmin, grid -> xmax); if (position > grid -> tiers -> size) position = grid -> tiers -> size + 1; Thing_setName (tier.peek(), name); Editor_save (me, U"Add interval tier"); Ordered_addItemPos (grid -> tiers, tier.transfer(), position); my selectedTier = position; FunctionEditor_updateText (me); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); EDITOR_END } static void menu_cb_AddPointTier (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); EDITOR_FORM (U"Add point tier", 0) NATURAL (U"Position", U"1 (= at top)") SENTENCE (U"Name", U""); EDITOR_OK TextGrid grid = (TextGrid) my data; SET_STRING (U"Position", Melder_cat (grid -> tiers -> size + 1, U" (= at bottom)")) SET_STRING (U"Name", U"") EDITOR_DO TextGrid grid = (TextGrid) my data; int position = GET_INTEGER (U"Position"); char32 *name = GET_STRING (U"Name"); autoTextTier tier = TextTier_create (grid -> xmin, grid -> xmax); if (position > grid -> tiers -> size) position = grid -> tiers -> size + 1; Thing_setName (tier.peek(), name); Editor_save (me, U"Add point tier"); Ordered_addItemPos (grid -> tiers, tier.transfer(), position); my selectedTier = position; FunctionEditor_updateText (me); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); EDITOR_END } static void menu_cb_DuplicateTier (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); EDITOR_FORM (U"Duplicate tier", 0) NATURAL (U"Position", U"1 (= at top)") SENTENCE (U"Name", U"") EDITOR_OK TextGrid grid = (TextGrid) my data; if (my selectedTier) { SET_STRING (U"Position", Melder_integer (my selectedTier + 1)) SET_STRING (U"Name", ((AnyTier) grid -> tiers -> item [my selectedTier]) -> name) } EDITOR_DO TextGrid grid = (TextGrid) my data; int position = GET_INTEGER (U"Position"); char32 *name = GET_STRING (U"Name"); checkTierSelection (me, U"duplicate a tier"); AnyTier tier = (AnyTier) grid -> tiers -> item [my selectedTier]; autoAnyTier newTier = Data_copy (tier); if (position > grid -> tiers -> size) position = grid -> tiers -> size + 1; Thing_setName (newTier.peek(), name); Editor_save (me, U"Duplicate tier"); Ordered_addItemPos (grid -> tiers, newTier.transfer(), position); my selectedTier = position; FunctionEditor_updateText (me); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); EDITOR_END } /***** HELP MENU *****/ static void menu_cb_TextGridEditorHelp (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); Melder_help (U"TextGridEditor"); } static void menu_cb_AboutSpecialSymbols (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); Melder_help (U"Special symbols"); } static void menu_cb_PhoneticSymbols (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); Melder_help (U"Phonetic symbols"); } static void menu_cb_AboutTextStyles (EDITOR_ARGS) { EDITOR_IAM (TextGridEditor); Melder_help (U"Text styles"); } void structTextGridEditor :: v_createMenus () { TextGridEditor_Parent :: v_createMenus (); EditorMenu menu; #ifndef macintosh Editor_addCommand (this, U"Edit", U"-- cut copy paste --", 0, NULL); Editor_addCommand (this, U"Edit", U"Cut text", 'X', menu_cb_Cut); Editor_addCommand (this, U"Edit", U"Cut", Editor_HIDDEN, menu_cb_Cut); Editor_addCommand (this, U"Edit", U"Copy text", 'C', menu_cb_Copy); Editor_addCommand (this, U"Edit", U"Copy", Editor_HIDDEN, menu_cb_Copy); Editor_addCommand (this, U"Edit", U"Paste text", 'V', menu_cb_Paste); Editor_addCommand (this, U"Edit", U"Paste", Editor_HIDDEN, menu_cb_Paste); Editor_addCommand (this, U"Edit", U"Erase text", 0, menu_cb_Erase); Editor_addCommand (this, U"Edit", U"Erase", Editor_HIDDEN, menu_cb_Erase); #endif Editor_addCommand (this, U"Edit", U"-- encoding --", 0, NULL); Editor_addCommand (this, U"Edit", U"Convert entire TextGrid to backslash trigraphs", 0, menu_cb_Genericize); Editor_addCommand (this, U"Edit", U"Genericize entire TextGrid", Editor_HIDDEN, menu_cb_Genericize); Editor_addCommand (this, U"Edit", U"Genericize", Editor_HIDDEN, menu_cb_Genericize); Editor_addCommand (this, U"Edit", U"Convert entire TextGrid to Unicode", 0, menu_cb_Nativize); Editor_addCommand (this, U"Edit", U"Nativize entire TextGrid", Editor_HIDDEN, menu_cb_Nativize); Editor_addCommand (this, U"Edit", U"Nativize", Editor_HIDDEN, menu_cb_Nativize); Editor_addCommand (this, U"Edit", U"-- search --", 0, NULL); Editor_addCommand (this, U"Edit", U"Find...", 'F', menu_cb_Find); Editor_addCommand (this, U"Edit", U"Find again", 'G', menu_cb_FindAgain); if (d_sound.data) { Editor_addCommand (this, U"Select", U"-- move to zero --", 0, 0); Editor_addCommand (this, U"Select", U"Move start of selection to nearest zero crossing", ',', menu_cb_MoveBtoZero); Editor_addCommand (this, U"Select", U"Move begin of selection to nearest zero crossing", Editor_HIDDEN, menu_cb_MoveBtoZero); Editor_addCommand (this, U"Select", U"Move cursor to nearest zero crossing", '0', menu_cb_MoveCursorToZero); Editor_addCommand (this, U"Select", U"Move end of selection to nearest zero crossing", '.', menu_cb_MoveEtoZero); } Editor_addCommand (this, U"Query", U"-- query interval --", 0, NULL); Editor_addCommand (this, U"Query", U"Get starting point of interval", 0, menu_cb_GetStartingPointOfInterval); Editor_addCommand (this, U"Query", U"Get end point of interval", 0, menu_cb_GetEndPointOfInterval); Editor_addCommand (this, U"Query", U"Get label of interval", 0, menu_cb_GetLabelOfInterval); menu = Editor_addMenu (this, U"Interval", 0); if (d_sound.data || d_longSound.data) { EditorMenu_addCommand (menu, U"Align interval", 'D', menu_cb_AlignInterval); EditorMenu_addCommand (menu, U"Alignment settings...", 0, menu_cb_AlignmentSettings); EditorMenu_addCommand (menu, U"-- add interval --", 0, NULL); } EditorMenu_addCommand (menu, U"Add interval on tier 1", GuiMenu_COMMAND | '1', menu_cb_InsertIntervalOnTier1); EditorMenu_addCommand (menu, U"Add interval on tier 2", GuiMenu_COMMAND | '2', menu_cb_InsertIntervalOnTier2); EditorMenu_addCommand (menu, U"Add interval on tier 3", GuiMenu_COMMAND | '3', menu_cb_InsertIntervalOnTier3); EditorMenu_addCommand (menu, U"Add interval on tier 4", GuiMenu_COMMAND | '4', menu_cb_InsertIntervalOnTier4); EditorMenu_addCommand (menu, U"Add interval on tier 5", GuiMenu_COMMAND | '5', menu_cb_InsertIntervalOnTier5); EditorMenu_addCommand (menu, U"Add interval on tier 6", GuiMenu_COMMAND | '6', menu_cb_InsertIntervalOnTier6); EditorMenu_addCommand (menu, U"Add interval on tier 7", GuiMenu_COMMAND | '7', menu_cb_InsertIntervalOnTier7); EditorMenu_addCommand (menu, U"Add interval on tier 8", GuiMenu_COMMAND | '8', menu_cb_InsertIntervalOnTier8); menu = Editor_addMenu (this, U"Boundary", 0); /*EditorMenu_addCommand (menu, U"Move to B", 0, menu_cb_MoveToB); EditorMenu_addCommand (menu, U"Move to E", 0, menu_cb_MoveToE);*/ if (d_sound.data) { EditorMenu_addCommand (menu, U"Move to nearest zero crossing", 0, menu_cb_MoveToZero); EditorMenu_addCommand (menu, U"-- insert boundary --", 0, NULL); } EditorMenu_addCommand (menu, U"Add on selected tier", GuiMenu_ENTER, menu_cb_InsertOnSelectedTier); EditorMenu_addCommand (menu, U"Add on tier 1", GuiMenu_COMMAND | GuiMenu_F1, menu_cb_InsertOnTier1); EditorMenu_addCommand (menu, U"Add on tier 2", GuiMenu_COMMAND | GuiMenu_F2, menu_cb_InsertOnTier2); EditorMenu_addCommand (menu, U"Add on tier 3", GuiMenu_COMMAND | GuiMenu_F3, menu_cb_InsertOnTier3); EditorMenu_addCommand (menu, U"Add on tier 4", GuiMenu_COMMAND | GuiMenu_F4, menu_cb_InsertOnTier4); EditorMenu_addCommand (menu, U"Add on tier 5", GuiMenu_COMMAND | GuiMenu_F5, menu_cb_InsertOnTier5); EditorMenu_addCommand (menu, U"Add on tier 6", GuiMenu_COMMAND | GuiMenu_F6, menu_cb_InsertOnTier6); EditorMenu_addCommand (menu, U"Add on tier 7", GuiMenu_COMMAND | GuiMenu_F7, menu_cb_InsertOnTier7); EditorMenu_addCommand (menu, U"Add on tier 8", GuiMenu_COMMAND | GuiMenu_F8, menu_cb_InsertOnTier8); EditorMenu_addCommand (menu, U"Add on all tiers", GuiMenu_COMMAND | GuiMenu_F9, menu_cb_InsertOnAllTiers); EditorMenu_addCommand (menu, U"-- remove mark --", 0, NULL); EditorMenu_addCommand (menu, U"Remove", GuiMenu_OPTION | GuiMenu_BACKSPACE, menu_cb_RemovePointOrBoundary); menu = Editor_addMenu (this, U"Tier", 0); EditorMenu_addCommand (menu, U"Add interval tier...", 0, menu_cb_AddIntervalTier); EditorMenu_addCommand (menu, U"Add point tier...", 0, menu_cb_AddPointTier); EditorMenu_addCommand (menu, U"Duplicate tier...", 0, menu_cb_DuplicateTier); EditorMenu_addCommand (menu, U"Rename tier...", 0, menu_cb_RenameTier); EditorMenu_addCommand (menu, U"-- remove tier --", 0, NULL); EditorMenu_addCommand (menu, U"Remove all text from tier", 0, menu_cb_RemoveAllTextFromTier); EditorMenu_addCommand (menu, U"Remove entire tier", 0, menu_cb_RemoveTier); EditorMenu_addCommand (menu, U"-- extract tier --", 0, NULL); EditorMenu_addCommand (menu, U"Extract to list of objects:", GuiMenu_INSENSITIVE, menu_cb_PublishTier /* dummy */); EditorMenu_addCommand (menu, U"Extract entire selected tier", 0, menu_cb_PublishTier); if (spellingChecker) { menu = Editor_addMenu (this, U"Spell", 0); EditorMenu_addCommand (menu, U"Check spelling in tier", GuiMenu_COMMAND | GuiMenu_OPTION | 'L', menu_cb_CheckSpelling); EditorMenu_addCommand (menu, U"Check spelling in interval", 0, menu_cb_CheckSpellingInInterval); EditorMenu_addCommand (menu, U"-- edit lexicon --", 0, NULL); EditorMenu_addCommand (menu, U"Add selected word to user dictionary", 0, menu_cb_AddToUserDictionary); } if (d_sound.data || d_longSound.data) { if (v_hasAnalysis ()) { v_createMenus_analysis (); // insert some of the ancestor's menus *after* the TextGrid menus } } } void structTextGridEditor :: v_createHelpMenuItems (EditorMenu menu) { TextGridEditor_Parent :: v_createHelpMenuItems (menu); EditorMenu_addCommand (menu, U"TextGridEditor help", '?', menu_cb_TextGridEditorHelp); EditorMenu_addCommand (menu, U"About special symbols", 0, menu_cb_AboutSpecialSymbols); EditorMenu_addCommand (menu, U"Phonetic symbols", 0, menu_cb_PhoneticSymbols); EditorMenu_addCommand (menu, U"About text styles", 0, menu_cb_AboutTextStyles); } /***** CHILDREN *****/ static void gui_text_cb_change (I, GuiTextEvent event) { iam (TextGridEditor); (void) event; TextGrid grid = (TextGrid) my data; //Melder_casual (U"gui_text_cb_change 1 in editor ", Melder_pointer (me)); if (my suppressRedraw) return; /* Prevent infinite loop if 'draw' method or Editor_broadcastChange calls GuiText_setString. */ //Melder_casual (U"gui_text_cb_change 2 in editor ", me); if (my selectedTier) { char32 *text = GuiText_getString (my text); IntervalTier intervalTier; TextTier textTier; _AnyTier_identifyClass ((Function) grid -> tiers -> item [my selectedTier], & intervalTier, & textTier); if (intervalTier) { long selectedInterval = getSelectedInterval (me); if (selectedInterval) { TextInterval interval = (TextInterval) intervalTier -> intervals -> item [selectedInterval]; //Melder_casual (U"gui_text_cb_change 3 in editor ", Melder_pointer (me)); TextInterval_setText (interval, text); //Melder_casual (U"gui_text_cb_change 4 in editor ", Melder_pointer (me)); FunctionEditor_redraw (me); //Melder_casual (U"gui_text_cb_change 5 in editor ", Melder_pointer (me)); Editor_broadcastDataChanged (me); //Melder_casual (U"gui_text_cb_change 6 in editor ", Melder_pointer (me)); } } else { long selectedPoint = getSelectedPoint (me); if (selectedPoint) { TextPoint point = (TextPoint) textTier -> points -> item [selectedPoint]; Melder_free (point -> mark); if (str32spn (text, U" \n\t") != str32len (text)) // any visible characters? point -> mark = Melder_dup_f (text); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); } } Melder_free (text); } } void structTextGridEditor :: v_createChildren () { TextGridEditor_Parent :: v_createChildren (); if (text) GuiText_setChangeCallback (text, gui_text_cb_change, this); } void structTextGridEditor :: v_dataChanged () { TextGrid grid = (TextGrid) data; /* * Perform a minimal selection change. * Most changes will involve intervals and boundaries; however, there may also be tier removals. * Do a simple guess. */ if (selectedTier > grid -> tiers -> size) { selectedTier = grid -> tiers -> size; } TextGridEditor_Parent :: v_dataChanged (); // does all the updating } /********** DRAWING AREA **********/ void structTextGridEditor :: v_prepareDraw () { if (d_longSound.data) { try { LongSound_haveWindow (d_longSound.data, d_startWindow, d_endWindow); } catch (MelderError) { Melder_clearError (); } } } static void do_drawIntervalTier (TextGridEditor me, IntervalTier tier, int itier) { #if gtk || defined (macintosh) bool platformUsesAntiAliasing = true; #else bool platformUsesAntiAliasing = false; #endif long x1DC, x2DC, yDC; int selectedInterval = itier == my selectedTier ? getSelectedInterval (me) : 0, iinterval, ninterval = tier -> intervals -> size; Graphics_WCtoDC (my d_graphics, my d_startWindow, 0.0, & x1DC, & yDC); Graphics_WCtoDC (my d_graphics, my d_endWindow, 0.0, & x2DC, & yDC); Graphics_setPercentSignIsItalic (my d_graphics, my p_useTextStyles); Graphics_setNumberSignIsBold (my d_graphics, my p_useTextStyles); Graphics_setCircumflexIsSuperscript (my d_graphics, my p_useTextStyles); Graphics_setUnderscoreIsSubscript (my d_graphics, my p_useTextStyles); /* * Highlight interval: yellow (selected) or green (matching label). */ for (iinterval = 1; iinterval <= ninterval; iinterval ++) { TextInterval interval = (TextInterval) tier -> intervals -> item [iinterval]; double tmin = interval -> xmin, tmax = interval -> xmax; if (tmax > my d_startWindow && tmin < my d_endWindow) { // interval visible? int intervalIsSelected = iinterval == selectedInterval; int labelMatches = Melder_stringMatchesCriterion (interval -> text, my p_greenMethod, my p_greenString); if (tmin < my d_startWindow) tmin = my d_startWindow; if (tmax > my d_endWindow) tmax = my d_endWindow; if (labelMatches) { Graphics_setColour (my d_graphics, Graphics_LIME); Graphics_fillRectangle (my d_graphics, tmin, tmax, 0.0, 1.0); } if (intervalIsSelected) { if (labelMatches) { tmin = 0.85 * tmin + 0.15 * tmax; tmax = 0.15 * tmin + 0.85 * tmax; } Graphics_setColour (my d_graphics, Graphics_YELLOW); Graphics_fillRectangle (my d_graphics, tmin, tmax, labelMatches ? 0.15 : 0.0, labelMatches? 0.85: 1.0); } } } Graphics_setColour (my d_graphics, Graphics_BLACK); Graphics_line (my d_graphics, my d_endWindow, 0.0, my d_endWindow, 1.0); /* * Draw a grey bar and a selection button at the cursor position. */ if (my d_startSelection == my d_endSelection && my d_startSelection >= my d_startWindow && my d_startSelection <= my d_endWindow) { bool cursorAtBoundary = false; for (iinterval = 2; iinterval <= ninterval; iinterval ++) { TextInterval interval = (TextInterval) tier -> intervals -> item [iinterval]; if (interval -> xmin == my d_startSelection) cursorAtBoundary = true; } if (! cursorAtBoundary) { double dy = Graphics_dyMMtoWC (my d_graphics, 1.5); Graphics_setGrey (my d_graphics, 0.8); Graphics_setLineWidth (my d_graphics, platformUsesAntiAliasing ? 6.0 : 5.0); Graphics_line (my d_graphics, my d_startSelection, 0.0, my d_startSelection, 1.0); Graphics_setLineWidth (my d_graphics, 1.0); Graphics_setColour (my d_graphics, Graphics_BLUE); Graphics_circle_mm (my d_graphics, my d_startSelection, 1.0 - dy, 3.0); } } Graphics_setTextAlignment (my d_graphics, my p_alignment, Graphics_HALF); for (iinterval = 1; iinterval <= ninterval; iinterval ++) { TextInterval interval = (TextInterval) tier -> intervals -> item [iinterval]; double tmin = interval -> xmin, tmax = interval -> xmax; if (tmin < my tmin) tmin = my tmin; if (tmax > my tmax) tmax = my tmax; if (tmin >= tmax) continue; bool intervalIsSelected = selectedInterval == iinterval; /* * Draw left boundary. */ if (tmin >= my d_startWindow && tmin <= my d_endWindow && iinterval > 1) { bool boundaryIsSelected = ( my selectedTier == itier && tmin == my d_startSelection ); Graphics_setColour (my d_graphics, boundaryIsSelected ? Graphics_RED : Graphics_BLUE); Graphics_setLineWidth (my d_graphics, platformUsesAntiAliasing ? 6.0 : 5.0); Graphics_line (my d_graphics, tmin, 0.0, tmin, 1.0); /* * Show alignment with cursor. */ if (tmin == my d_startSelection) { Graphics_setColour (my d_graphics, Graphics_YELLOW); Graphics_setLineWidth (my d_graphics, platformUsesAntiAliasing ? 2.0 : 1.0); Graphics_line (my d_graphics, tmin, 0.0, tmin, 1.0); } } Graphics_setLineWidth (my d_graphics, 1.0); /* * Draw label text. */ if (interval -> text && tmax >= my d_startWindow && tmin <= my d_endWindow) { double t1 = my d_startWindow > tmin ? my d_startWindow : tmin; double t2 = my d_endWindow < tmax ? my d_endWindow : tmax; Graphics_setColour (my d_graphics, intervalIsSelected ? Graphics_RED : Graphics_BLACK); Graphics_textRect (my d_graphics, t1, t2, 0.0, 1.0, interval -> text); Graphics_setColour (my d_graphics, Graphics_BLACK); } } Graphics_setPercentSignIsItalic (my d_graphics, true); Graphics_setNumberSignIsBold (my d_graphics, true); Graphics_setCircumflexIsSuperscript (my d_graphics, true); Graphics_setUnderscoreIsSubscript (my d_graphics, true); } static void do_drawTextTier (TextGridEditor me, TextTier tier, int itier) { #if gtk || defined (macintosh) bool platformUsesAntiAliasing = true; #else bool platformUsesAntiAliasing = false; #endif int ipoint, npoint = tier -> points -> size; Graphics_setPercentSignIsItalic (my d_graphics, my p_useTextStyles); Graphics_setNumberSignIsBold (my d_graphics, my p_useTextStyles); Graphics_setCircumflexIsSuperscript (my d_graphics, my p_useTextStyles); Graphics_setUnderscoreIsSubscript (my d_graphics, my p_useTextStyles); /* * Draw a grey bar and a selection button at the cursor position. */ if (my d_startSelection == my d_endSelection && my d_startSelection >= my d_startWindow && my d_startSelection <= my d_endWindow) { bool cursorAtPoint = false; for (ipoint = 1; ipoint <= npoint; ipoint ++) { TextPoint point = (TextPoint) tier -> points -> item [ipoint]; if (point -> number == my d_startSelection) cursorAtPoint = true; } if (! cursorAtPoint) { double dy = Graphics_dyMMtoWC (my d_graphics, 1.5); Graphics_setGrey (my d_graphics, 0.8); Graphics_setLineWidth (my d_graphics, platformUsesAntiAliasing ? 6.0 : 5.0); Graphics_line (my d_graphics, my d_startSelection, 0.0, my d_startSelection, 1.0); Graphics_setLineWidth (my d_graphics, 1.0); Graphics_setColour (my d_graphics, Graphics_BLUE); Graphics_circle_mm (my d_graphics, my d_startSelection, 1.0 - dy, 3.0); } } Graphics_setTextAlignment (my d_graphics, Graphics_CENTRE, Graphics_HALF); for (ipoint = 1; ipoint <= npoint; ipoint ++) { TextPoint point = (TextPoint) tier -> points -> item [ipoint]; double t = point -> number; if (t >= my d_startWindow && t <= my d_endWindow) { bool pointIsSelected = ( itier == my selectedTier && t == my d_startSelection ); Graphics_setColour (my d_graphics, pointIsSelected ? Graphics_RED : Graphics_BLUE); Graphics_setLineWidth (my d_graphics, platformUsesAntiAliasing ? 6.0 : 5.0); Graphics_line (my d_graphics, t, 0.0, t, 0.2); Graphics_line (my d_graphics, t, 0.8, t, 1); Graphics_setLineWidth (my d_graphics, 1.0); /* * Wipe out the cursor where the text is going to be. */ Graphics_setColour (my d_graphics, Graphics_WHITE); Graphics_line (my d_graphics, t, 0.2, t, 0.8); /* * Show alignment with cursor. */ if (my d_startSelection == my d_endSelection && t == my d_startSelection) { Graphics_setColour (my d_graphics, Graphics_YELLOW); Graphics_setLineWidth (my d_graphics, platformUsesAntiAliasing ? 2.0 : 1.0); Graphics_line (my d_graphics, t, 0.0, t, 0.2); Graphics_line (my d_graphics, t, 0.8, t, 1.0); } Graphics_setColour (my d_graphics, pointIsSelected ? Graphics_RED : Graphics_BLUE); if (point -> mark) Graphics_text (my d_graphics, t, 0.5, point -> mark); } } Graphics_setPercentSignIsItalic (my d_graphics, true); Graphics_setNumberSignIsBold (my d_graphics, true); Graphics_setCircumflexIsSuperscript (my d_graphics, true); Graphics_setUnderscoreIsSubscript (my d_graphics, true); } void structTextGridEditor :: v_draw () { TextGrid grid = (TextGrid) data; Graphics_Viewport vp1, vp2; long itier, ntier = grid -> tiers -> size; enum kGraphics_font oldFont = Graphics_inqFont (d_graphics); int oldFontSize = Graphics_inqFontSize (d_graphics); bool showAnalysis = v_hasAnalysis () && (p_spectrogram_show || p_pitch_show || p_intensity_show || p_formant_show) && (d_longSound.data || d_sound.data); double soundY = _TextGridEditor_computeSoundY (this), soundY2 = showAnalysis ? 0.5 * (1.0 + soundY) : soundY; /* * Draw optional sound. */ if (d_longSound.data || d_sound.data) { vp1 = Graphics_insetViewport (d_graphics, 0.0, 1.0, soundY2, 1.0); Graphics_setColour (d_graphics, Graphics_WHITE); Graphics_setWindow (d_graphics, 0, 1, 0, 1); Graphics_fillRectangle (d_graphics, 0, 1, 0, 1); TimeSoundEditor_drawSound (this, -1.0, 1.0); Graphics_flushWs (d_graphics); Graphics_resetViewport (d_graphics, vp1); } /* * Draw tiers. */ if (d_longSound.data || d_sound.data) vp1 = Graphics_insetViewport (d_graphics, 0.0, 1.0, 0.0, soundY); Graphics_setColour (d_graphics, Graphics_WHITE); Graphics_setWindow (d_graphics, 0, 1, 0, 1); Graphics_fillRectangle (d_graphics, 0, 1, 0, 1); Graphics_setColour (d_graphics, Graphics_BLACK); Graphics_rectangle (d_graphics, 0, 1, 0, 1); Graphics_setWindow (d_graphics, d_startWindow, d_endWindow, 0.0, 1.0); for (itier = 1; itier <= ntier; itier ++) { Function anyTier = (Function) grid -> tiers -> item [itier]; bool tierIsSelected = itier == selectedTier; bool isIntervalTier = anyTier -> classInfo == classIntervalTier; vp2 = Graphics_insetViewport (d_graphics, 0.0, 1.0, 1.0 - (double) itier / (double) ntier, 1.0 - (double) (itier - 1) / (double) ntier); Graphics_setColour (d_graphics, Graphics_BLACK); if (itier != 1) Graphics_line (d_graphics, d_startWindow, 1.0, d_endWindow, 1.0); /* * Show the number and the name of the tier. */ Graphics_setColour (d_graphics, tierIsSelected ? Graphics_RED : Graphics_BLACK); Graphics_setFont (d_graphics, oldFont); Graphics_setFontSize (d_graphics, 14); Graphics_setTextAlignment (d_graphics, Graphics_RIGHT, Graphics_HALF); Graphics_text (d_graphics, d_startWindow, 0.5, tierIsSelected ? U"☞ " : U"", itier); Graphics_setFontSize (d_graphics, oldFontSize); if (anyTier -> name && anyTier -> name [0]) { Graphics_setTextAlignment (d_graphics, Graphics_LEFT, p_showNumberOf == kTextGridEditor_showNumberOf_NOTHING ? Graphics_HALF : Graphics_BOTTOM); Graphics_text (d_graphics, d_endWindow, 0.5, anyTier -> name); } if (p_showNumberOf != kTextGridEditor_showNumberOf_NOTHING) { Graphics_setTextAlignment (d_graphics, Graphics_LEFT, Graphics_TOP); if (p_showNumberOf == kTextGridEditor_showNumberOf_INTERVALS_OR_POINTS) { long count = isIntervalTier ? ((IntervalTier) anyTier) -> intervals -> size : ((TextTier) anyTier) -> points -> size; long position = itier == selectedTier ? ( isIntervalTier ? getSelectedInterval (this) : getSelectedPoint (this) ) : 0; if (position) { Graphics_text (d_graphics, d_endWindow, 0.5, U"(", position, U"/", count, U")"); } else { Graphics_text (d_graphics, d_endWindow, 0.5, U"(", count, U")"); } } else { Melder_assert (kTextGridEditor_showNumberOf_NONEMPTY_INTERVALS_OR_POINTS); long count = 0; if (isIntervalTier) { IntervalTier tier = (IntervalTier) anyTier; long ninterval = tier -> intervals -> size, iinterval; for (iinterval = 1; iinterval <= ninterval; iinterval ++) { TextInterval interval = (TextInterval) tier -> intervals -> item [iinterval]; if (interval -> text != NULL && interval -> text [0] != '\0') { count ++; } } } else { TextTier tier = (TextTier) anyTier; long npoint = tier -> points -> size, ipoint; for (ipoint = 1; ipoint <= npoint; ipoint ++) { TextPoint point = (TextPoint) tier -> points -> item [ipoint]; if (point -> mark != NULL && point -> mark [0] != '\0') { count ++; } } } Graphics_text (d_graphics, d_endWindow, 0.5, U"(##", count, U"#)"); } } Graphics_setColour (d_graphics, Graphics_BLACK); Graphics_setFont (d_graphics, kGraphics_font_TIMES); Graphics_setFontSize (d_graphics, p_fontSize); if (isIntervalTier) do_drawIntervalTier (this, (IntervalTier) anyTier, itier); else do_drawTextTier (this, (TextTier) anyTier, itier); Graphics_resetViewport (d_graphics, vp2); } Graphics_setColour (d_graphics, Graphics_BLACK); Graphics_setFont (d_graphics, oldFont); Graphics_setFontSize (d_graphics, oldFontSize); if (d_longSound.data || d_sound.data) Graphics_resetViewport (d_graphics, vp1); Graphics_flushWs (d_graphics); if (showAnalysis) { vp1 = Graphics_insetViewport (d_graphics, 0.0, 1.0, soundY, soundY2); v_draw_analysis (); Graphics_flushWs (d_graphics); Graphics_resetViewport (d_graphics, vp1); /* Draw pulses. */ if (p_pulses_show) { vp1 = Graphics_insetViewport (d_graphics, 0.0, 1.0, soundY2, 1.0); v_draw_analysis_pulses (); TimeSoundEditor_drawSound (this, -1.0, 1.0); // second time, partially across the pulses Graphics_flushWs (d_graphics); Graphics_resetViewport (d_graphics, vp1); } } Graphics_setWindow (d_graphics, d_startWindow, d_endWindow, 0.0, 1.0); if (d_longSound.data || d_sound.data) { Graphics_line (d_graphics, d_startWindow, soundY, d_endWindow, soundY); if (showAnalysis) { Graphics_line (d_graphics, d_startWindow, soundY2, d_endWindow, soundY2); Graphics_line (d_graphics, d_startWindow, soundY, d_startWindow, soundY2); Graphics_line (d_graphics, d_endWindow, soundY, d_endWindow, soundY2); } } /* * Finally, us usual, update the menus. */ v_updateMenuItems_file (); } static void do_drawWhileDragging (TextGridEditor me, double numberOfTiers, bool selectedTier [], double x, double soundY) { long itier; for (itier = 1; itier <= numberOfTiers; itier ++) if (selectedTier [itier]) { double ymin = soundY * (1.0 - (double) itier / numberOfTiers); double ymax = soundY * (1.0 - (double) (itier - 1) / numberOfTiers); Graphics_setLineWidth (my d_graphics, 7.0); Graphics_line (my d_graphics, x, ymin, x, ymax); } Graphics_setLineWidth (my d_graphics, 1); Graphics_line (my d_graphics, x, 0.0, x, 1.01); Graphics_text (my d_graphics, x, 1.01, Melder_fixed (x, 6)); } static void do_dragBoundary (TextGridEditor me, double xbegin, int iClickedTier, int shiftKeyPressed) { TextGrid grid = (TextGrid) my data; int numberOfTiers = grid -> tiers -> size, itierDrop; double xWC = xbegin, yWC; double leftDraggingBoundary = my tmin, rightDraggingBoundary = my tmax; // initial dragging range bool selectedTier [1000]; double soundY = _TextGridEditor_computeSoundY (me); /* * Determine the set of selected boundaries and points, and the dragging range. */ for (int itier = 1; itier <= numberOfTiers; itier ++) { selectedTier [itier] = false; // the default /* * If she has pressed the shift key, let her drag all the boundaries and points at this time. * Otherwise, let her only drag the boundary or point on the clicked tier. */ if (itier == iClickedTier || shiftKeyPressed == my p_shiftDragMultiple) { IntervalTier intervalTier; TextTier textTier; _AnyTier_identifyClass ((Function) grid -> tiers -> item [itier], & intervalTier, & textTier); if (intervalTier) { long ibound = IntervalTier_hasBoundary (intervalTier, xbegin); if (ibound) { TextInterval leftInterval = (TextInterval) intervalTier -> intervals -> item [ibound - 1]; TextInterval rightInterval = (TextInterval) intervalTier -> intervals -> item [ibound]; selectedTier [itier] = true; /* * Prevent her to drag the boundary past its left or right neighbours on the same tier. */ if (leftInterval -> xmin > leftDraggingBoundary) { leftDraggingBoundary = leftInterval -> xmin; } if (rightInterval -> xmax < rightDraggingBoundary) { rightDraggingBoundary = rightInterval -> xmax; } } } else { if (AnyTier_hasPoint (textTier, xbegin)) { /* * Other than with boundaries on interval tiers, * points on text tiers can be dragged past their neighbours. */ selectedTier [itier] = true; } } } } Graphics_xorOn (my d_graphics, Graphics_MAROON); Graphics_setTextAlignment (my d_graphics, Graphics_CENTRE, Graphics_BOTTOM); do_drawWhileDragging (me, numberOfTiers, selectedTier, xWC, soundY); // draw at old position while (Graphics_mouseStillDown (my d_graphics)) { double xWC_new; Graphics_getMouseLocation (my d_graphics, & xWC_new, & yWC); if (xWC_new != xWC) { do_drawWhileDragging (me, numberOfTiers, selectedTier, xWC, soundY); // undraw at old position xWC = xWC_new; do_drawWhileDragging (me, numberOfTiers, selectedTier, xWC, soundY); // draw at new position } } do_drawWhileDragging (me, numberOfTiers, selectedTier, xWC, soundY); // undraw at new position Graphics_xorOff (my d_graphics); /* * The simplest way to cancel the dragging operation, is to drag outside the window. */ if (xWC <= my d_startWindow || xWC >= my d_endWindow) { return; } /* * If she dropped near an existing boundary in an unselected tier or near the cursor, we snap to that mark. */ itierDrop = _TextGridEditor_yWCtoTier (me, yWC); if (yWC > 0.0 && yWC < soundY && ! selectedTier [itierDrop]) { // dropped inside an unselected tier? Function anyTierDrop = (Function) grid -> tiers -> item [itierDrop]; if (anyTierDrop -> classInfo == classIntervalTier) { IntervalTier tierDrop = (IntervalTier) anyTierDrop; long ibound; for (ibound = 1; ibound < tierDrop -> intervals -> size; ibound ++) { TextInterval left = (TextInterval) tierDrop -> intervals -> item [ibound]; if (fabs (Graphics_dxWCtoMM (my d_graphics, xWC - left -> xmax)) < 1.5) { // near a boundary? /* * Snap to boundary. */ xWC = left -> xmax; } } } else { TextTier tierDrop = (TextTier) anyTierDrop; long ipoint; for (ipoint = 1; ipoint <= tierDrop -> points -> size; ipoint ++) { TextPoint point = (TextPoint) tierDrop -> points -> item [ipoint]; if (fabs (Graphics_dxWCtoMM (my d_graphics, xWC - point -> number)) < 1.5) { // near a point? /* * Snap to point. */ xWC = point -> number; } } } } else if (xbegin != my d_startSelection && fabs (Graphics_dxWCtoMM (my d_graphics, xWC - my d_startSelection)) < 1.5) { // near the cursor? /* * Snap to cursor. */ xWC = my d_startSelection; } else if (xbegin != my d_endSelection && fabs (Graphics_dxWCtoMM (my d_graphics, xWC - my d_endSelection)) < 1.5) { // near the cursor? /* * Snap to cursor. */ xWC = my d_endSelection; } /* * We cannot move a boundary out of the dragging range. */ if (xWC <= leftDraggingBoundary || xWC >= rightDraggingBoundary) { Melder_beep (); return; } Editor_save (me, U"Drag"); for (int itier = 1; itier <= numberOfTiers; itier ++) if (selectedTier [itier]) { IntervalTier intervalTier; TextTier textTier; _AnyTier_identifyClass ((Function) grid -> tiers -> item [itier], & intervalTier, & textTier); if (intervalTier) { long ibound, numberOfIntervals = intervalTier -> intervals -> size; Any *intervals = intervalTier -> intervals -> item; for (ibound = 2; ibound <= numberOfIntervals; ibound ++) { TextInterval left = (TextInterval) intervals [ibound - 1], right = (TextInterval) intervals [ibound]; if (left -> xmax == xbegin) { // boundary dragged? left -> xmax = right -> xmin = xWC; // move boundary to drop site break; } } } else { long iDraggedPoint = AnyTier_hasPoint (textTier, xbegin); if (iDraggedPoint) { long dropSiteHasPoint = AnyTier_hasPoint (textTier, xWC); if (dropSiteHasPoint) { Melder_warning (U"Cannot drop point on an existing point."); } else { TextPoint point = (TextPoint) textTier -> points -> item [iDraggedPoint]; /* * Move point to drop site. May have passed another point. */ TextPoint newPoint = Data_copy (point); newPoint -> number = xWC; // move point to drop site Collection_removeItem (textTier -> points, iDraggedPoint); Collection_addItem (textTier -> points, newPoint); } } } } /* * Select the drop site. */ if (my d_startSelection == xbegin) my d_startSelection = xWC; if (my d_endSelection == xbegin) my d_endSelection = xWC; if (my d_startSelection > my d_endSelection) { double dummy = my d_startSelection; my d_startSelection = my d_endSelection; my d_endSelection = dummy; } FunctionEditor_marksChanged (me, true); Editor_broadcastDataChanged (me); } int structTextGridEditor :: v_click (double xclick, double yWC, bool shiftKeyPressed) { TextGrid grid = (TextGrid) our data; double tmin, tmax, x, y; long ntiers = grid -> tiers -> size, iClickedTier, iClickedInterval, iClickedPoint; int clickedLeftBoundary = 0; bool nearBoundaryOrPoint, nearCursorCircle, drag = false; IntervalTier intervalTier; TextTier textTier; TextInterval interval = NULL; TextPoint point = NULL; double soundY = _TextGridEditor_computeSoundY (this); double tnear; /* * In answer to a click in the sound part, * we keep the same tier selected and move the cursor or drag the "yellow" selection. */ if (yWC > soundY) { /* Clicked in sound part? */ if ((our p_spectrogram_show || our p_formant_show) && yWC < 0.5 * (soundY + 1.0)) { our d_spectrogram_cursor = our p_spectrogram_viewFrom + 2.0 * (yWC - soundY) / (1.0 - soundY) * (our p_spectrogram_viewTo - our p_spectrogram_viewFrom); } our TextGridEditor_Parent :: v_click (xclick, yWC, shiftKeyPressed); return FunctionEditor_UPDATE_NEEDED; } /* * She clicked in the grid part. * We select the tier in which she clicked. */ iClickedTier = _TextGridEditor_yWCtoTier (this, yWC); if (xclick <= our d_startWindow || xclick >= our d_endWindow) { our selectedTier = iClickedTier; return FunctionEditor_UPDATE_NEEDED; } _TextGridEditor_timeToInterval (this, xclick, iClickedTier, & tmin, & tmax); _AnyTier_identifyClass ((Function) grid -> tiers -> item [iClickedTier], & intervalTier, & textTier); /* * Get the time of the nearest boundary or point. */ tnear = NUMundefined; if (intervalTier) { iClickedInterval = IntervalTier_timeToIndex (intervalTier, xclick); if (iClickedInterval) { interval = (TextInterval) intervalTier -> intervals -> item [iClickedInterval]; if (xclick > 0.5 * (interval -> xmin + interval -> xmax)) { tnear = interval -> xmax; clickedLeftBoundary = iClickedInterval + 1; } else { tnear = interval -> xmin; clickedLeftBoundary = iClickedInterval; } } else { /* * She clicked outside time domain of intervals. * This can occur when we are grouped with a longer time function. */ our selectedTier = iClickedTier; return FunctionEditor_UPDATE_NEEDED; } } else { iClickedPoint = AnyTier_timeToNearestIndex (textTier, xclick); if (iClickedPoint) { point = (TextPoint) textTier -> points -> item [iClickedPoint]; tnear = point -> number; } } Melder_assert (! (intervalTier && ! clickedLeftBoundary)); /* * Where did she click? */ nearBoundaryOrPoint = ( tnear != NUMundefined && fabs (Graphics_dxWCtoMM (our d_graphics, xclick - tnear)) < 1.5 ); nearCursorCircle = ( our d_startSelection == our d_endSelection && Graphics_distanceWCtoMM (our d_graphics, xclick, yWC, our d_startSelection, (ntiers + 1 - iClickedTier) * soundY / ntiers - Graphics_dyMMtoWC (our d_graphics, 1.5)) < 1.5 ); /* * Find out whether this is a click or a drag. */ while (Graphics_mouseStillDown (our d_graphics)) { Graphics_getMouseLocation (our d_graphics, & x, & y); if (x < our d_startWindow) x = our d_startWindow; if (x > our d_endWindow) x = our d_endWindow; if (fabs (Graphics_dxWCtoMM (our d_graphics, x - xclick)) > 1.5) { drag = true; break; } } if (nearBoundaryOrPoint) { /* * Possibility 1: she clicked near a boundary or point. * Select or drag it. */ if (intervalTier && (clickedLeftBoundary < 2 || clickedLeftBoundary > intervalTier -> intervals -> size)) { /* * Ignore click on left edge of first interval or right edge of last interval. */ our selectedTier = iClickedTier; } else if (drag) { /* * The tier that has been clicked becomes the new selected tier. * This has to be done before the next Update, i.e. also before do_dragBoundary! */ our selectedTier = iClickedTier; do_dragBoundary (this, tnear, iClickedTier, shiftKeyPressed); return FunctionEditor_NO_UPDATE_NEEDED; } else { /* * If she clicked on an unselected boundary or point, we select it. */ if (shiftKeyPressed) { if (tnear > 0.5 * (our d_startSelection + our d_endSelection)) our d_endSelection = tnear; else our d_startSelection = tnear; } else { our d_startSelection = our d_endSelection = tnear; /* Move cursor so that the boundary or point is selected. */ } our selectedTier = iClickedTier; } } else if (nearCursorCircle) { /* * Possibility 2: she clicked near the cursor circle. * Insert boundary or point. There is no danger that we insert on top of an existing boundary or point, * because we are not 'nearBoundaryOrPoint'. */ insertBoundaryOrPoint (this, iClickedTier, our d_startSelection, our d_startSelection, false); our selectedTier = iClickedTier; FunctionEditor_marksChanged (this, true); Editor_broadcastDataChanged (this); if (drag) Graphics_waitMouseUp (our d_graphics); return FunctionEditor_NO_UPDATE_NEEDED; } else { /* * Possibility 3: she clicked in empty space. */ if (intervalTier) { our d_startSelection = tmin; our d_endSelection = tmax; } selectedTier = iClickedTier; } if (drag) Graphics_waitMouseUp (our d_graphics); return FunctionEditor_UPDATE_NEEDED; } int structTextGridEditor :: v_clickB (double t, double yWC) { double soundY = _TextGridEditor_computeSoundY (this); if (yWC > soundY) { // clicked in sound part? our d_startSelection = t; if (our d_startSelection > our d_endSelection) { double dummy = our d_startSelection; our d_startSelection = our d_endSelection; our d_endSelection = dummy; } return FunctionEditor_UPDATE_NEEDED; } int itier = _TextGridEditor_yWCtoTier (this, yWC); double tmin, tmax; _TextGridEditor_timeToInterval (this, t, itier, & tmin, & tmax); our d_startSelection = t - tmin < tmax - t ? tmin : tmax; // to nearest boundary if (our d_startSelection > our d_endSelection) { double dummy = our d_startSelection; our d_startSelection = our d_endSelection; our d_endSelection = dummy; } return FunctionEditor_UPDATE_NEEDED; } int structTextGridEditor :: v_clickE (double t, double yWC) { double soundY = _TextGridEditor_computeSoundY (this); if (yWC > soundY) { // clicked in sound part? our d_endSelection = t; if (our d_startSelection > our d_endSelection) { double dummy = our d_startSelection; our d_startSelection = our d_endSelection; our d_endSelection = dummy; } return FunctionEditor_UPDATE_NEEDED; } int itier = _TextGridEditor_yWCtoTier (this, yWC); double tmin, tmax; _TextGridEditor_timeToInterval (this, t, itier, & tmin, & tmax); our d_endSelection = t - tmin < tmax - t ? tmin : tmax; if (our d_startSelection > our d_endSelection) { double dummy = our d_startSelection; our d_startSelection = our d_endSelection; our d_endSelection = dummy; } return FunctionEditor_UPDATE_NEEDED; } void structTextGridEditor :: v_play (double tmin, double tmax) { if (our d_longSound.data) { LongSound_playPart (our d_longSound.data, tmin, tmax, theFunctionEditor_playCallback, this); } else if (our d_sound.data) { Sound_playPart (our d_sound.data, tmin, tmax, theFunctionEditor_playCallback, this); } } void structTextGridEditor :: v_updateText () { TextGrid grid = (TextGrid) our data; const char32 *newText = U""; trace (U"selected tier ", our selectedTier); if (our selectedTier) { IntervalTier intervalTier; TextTier textTier; _AnyTier_identifyClass ((Function) grid -> tiers -> item [selectedTier], & intervalTier, & textTier); if (intervalTier) { long iinterval = IntervalTier_timeToIndex (intervalTier, d_startSelection); if (iinterval) { TextInterval interval = (TextInterval) intervalTier -> intervals -> item [iinterval]; if (interval -> text) { newText = interval -> text; } } } else { long ipoint = AnyTier_hasPoint (textTier, d_startSelection); if (ipoint) { TextPoint point = (TextPoint) textTier -> points -> item [ipoint]; if (point -> mark) { newText = point -> mark; } } } } //Melder_casual ("v_updateText in editor %ld %ls %d", this, name, (int) suppressRedraw); if (our text) { our suppressRedraw = true; // prevent valueChangedCallback from redrawing trace (U"setting new text ", newText); GuiText_setString (text, newText); long cursor = str32len (newText); // at end GuiText_setSelection (text, cursor, cursor); our suppressRedraw = false; } } void structTextGridEditor :: v_prefs_addFields (EditorCommand cmd) { Any radio; NATURAL (U"Font size (points)", default_fontSize ()) OPTIONMENU_ENUM (U"Text alignment in intervals", kGraphics_horizontalAlignment, kGraphics_horizontalAlignment_DEFAULT) OPTIONMENU (U"The symbols %#_^ in labels", default_useTextStyles () + 1) OPTION (U"are shown as typed") OPTION (U"mean italic/bold/sub/super") OPTIONMENU (U"With the shift key, you drag", default_shiftDragMultiple () + 1) OPTION (U"a single boundary") OPTION (U"multiple boundaries") OPTIONMENU_ENUM (U"Show number of", kTextGridEditor_showNumberOf, kTextGridEditor_showNumberOf_DEFAULT) OPTIONMENU_ENUM (U"Paint intervals green whose label...", kMelder_string, kMelder_string_DEFAULT) SENTENCE (U"...the text", default_greenString ()) } void structTextGridEditor :: v_prefs_setValues (EditorCommand cmd) { SET_INTEGER (U"The symbols %#_^ in labels", p_useTextStyles + 1) SET_INTEGER (U"Font size", p_fontSize) SET_ENUM (U"Text alignment in intervals", kGraphics_horizontalAlignment, p_alignment) SET_INTEGER (U"With the shift key, you drag", p_shiftDragMultiple + 1) SET_ENUM (U"Show number of", kTextGridEditor_showNumberOf, p_showNumberOf) SET_ENUM (U"Paint intervals green whose label...", kMelder_string, p_greenMethod) SET_STRING (U"...the text", p_greenString) } void structTextGridEditor :: v_prefs_getValues (EditorCommand cmd) { pref_useTextStyles () = p_useTextStyles = GET_INTEGER (U"The symbols %#_^ in labels") - 1; pref_fontSize () = p_fontSize = GET_INTEGER (U"Font size"); pref_alignment () = p_alignment = GET_ENUM (kGraphics_horizontalAlignment, U"Text alignment in intervals"); pref_shiftDragMultiple () = p_shiftDragMultiple = GET_INTEGER (U"With the shift key, you drag") - 1; pref_showNumberOf () = p_showNumberOf = GET_ENUM (kTextGridEditor_showNumberOf, U"Show number of"); pref_greenMethod () = p_greenMethod = GET_ENUM (kMelder_string, U"Paint intervals green whose label..."); pref_str32cpy2 (pref_greenString (), p_greenString, GET_STRING (U"...the text")); FunctionEditor_redraw (this); } void structTextGridEditor :: v_createMenuItems_view_timeDomain (EditorMenu menu) { TextGridEditor_Parent :: v_createMenuItems_view_timeDomain (menu); EditorMenu_addCommand (menu, U"Select previous tier", GuiMenu_OPTION | GuiMenu_UP_ARROW, menu_cb_SelectPreviousTier); EditorMenu_addCommand (menu, U"Select next tier", GuiMenu_OPTION | GuiMenu_DOWN_ARROW, menu_cb_SelectNextTier); EditorMenu_addCommand (menu, U"Select previous interval", GuiMenu_OPTION | GuiMenu_LEFT_ARROW, menu_cb_SelectPreviousInterval); EditorMenu_addCommand (menu, U"Select next interval", GuiMenu_OPTION | GuiMenu_RIGHT_ARROW, menu_cb_SelectNextInterval); EditorMenu_addCommand (menu, U"Extend-select left", GuiMenu_SHIFT | GuiMenu_OPTION | GuiMenu_LEFT_ARROW, menu_cb_ExtendSelectPreviousInterval); EditorMenu_addCommand (menu, U"Extend-select right", GuiMenu_SHIFT | GuiMenu_OPTION | GuiMenu_RIGHT_ARROW, menu_cb_ExtendSelectNextInterval); } void structTextGridEditor :: v_highlightSelection (double left, double right, double bottom, double top) { if (our v_hasAnalysis () && our p_spectrogram_show && (our d_longSound.data || our d_sound.data)) { double soundY = _TextGridEditor_computeSoundY (this), soundY2 = 0.5 * (1.0 + soundY); //Graphics_highlight (our d_graphics, left, right, bottom, soundY * top + (1 - soundY) * bottom); Graphics_highlight (our d_graphics, left, right, soundY2 * top + (1 - soundY2) * bottom, top); } else { Graphics_highlight (our d_graphics, left, right, bottom, top); } } void structTextGridEditor :: v_unhighlightSelection (double left, double right, double bottom, double top) { if (our v_hasAnalysis () && our p_spectrogram_show && (our d_longSound.data || our d_sound.data)) { double soundY = _TextGridEditor_computeSoundY (this), soundY2 = 0.5 * (1.0 + soundY); //Graphics_unhighlight (our d_graphics, left, right, bottom, soundY * top + (1 - soundY) * bottom); Graphics_unhighlight (our d_graphics, left, right, soundY2 * top + (1 - soundY2) * bottom, top); } else { Graphics_unhighlight (our d_graphics, left, right, bottom, top); } } double structTextGridEditor :: v_getBottomOfSoundArea () { return _TextGridEditor_computeSoundY (this); } double structTextGridEditor :: v_getBottomOfSoundAndAnalysisArea () { return _TextGridEditor_computeSoundY (this); } void structTextGridEditor :: v_createMenuItems_pitch_picture (EditorMenu menu) { TextGridEditor_Parent :: v_createMenuItems_pitch_picture (menu); EditorMenu_addCommand (menu, U"Draw visible pitch contour and TextGrid...", 0, menu_cb_DrawTextGridAndPitch); } void structTextGridEditor :: v_updateMenuItems_file () { TextGridEditor_Parent :: v_updateMenuItems_file (); GuiThing_setSensitive (extractSelectedTextGridPreserveTimesButton, our d_endSelection > our d_startSelection); GuiThing_setSensitive (extractSelectedTextGridTimeFromZeroButton, our d_endSelection > our d_startSelection); } /********** EXPORTED **********/ void TextGridEditor_init (TextGridEditor me, const char32 *title, TextGrid grid, Sampled sound, bool ownSound, SpellingChecker spellingChecker, const char *callbackSocket) { my spellingChecker = spellingChecker; // set in time my callbackSocket = Melder_strdup (callbackSocket); TimeSoundAnalysisEditor_init (me, title, grid, sound, ownSound); my selectedTier = 1; my v_updateText (); // to reflect changed tier selection if (my d_endWindow - my d_startWindow > 30.0) { my d_endWindow = my d_startWindow + 30.0; if (my d_startWindow == my tmin) my d_startSelection = my d_endSelection = 0.5 * (my d_startWindow + my d_endWindow); FunctionEditor_marksChanged (me, false); } if (spellingChecker != NULL) GuiText_setSelection (my text, 0, 0); if (sound && sound -> xmin == 0.0 && grid -> xmin != 0.0 && grid -> xmax > sound -> xmax) Melder_warning (U"The time domain of the TextGrid (starting at ", Melder_fixed (grid -> xmin, 6), U" seconds) does not overlap with that of the sound " U"(which starts at 0 seconds).\nIf you want to repair this, you can select the TextGrid " U"and choose “Shift times to...” from the Modify menu " U"to shift the starting time of the TextGrid to zero."); } autoTextGridEditor TextGridEditor_create (const char32 *title, TextGrid grid, Sampled sound, bool ownSound, SpellingChecker spellingChecker, const char *callbackSocket) { try { autoTextGridEditor me = Thing_new (TextGridEditor); TextGridEditor_init (me.peek(), title, grid, sound, ownSound, spellingChecker, callbackSocket); return me; } catch (MelderError) { Melder_throw (U"TextGrid window not created."); } } /* End of file TextGridEditor.cpp */ praat-6.0.04/fon/TextGridEditor.h000066400000000000000000000060561261542461700165630ustar00rootroot00000000000000#ifndef _TextGridEditor_h_ #define _TextGridEditor_h_ /* TextGridEditor.h * * Copyright (C) 1992-2011,2012,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "TimeSoundAnalysisEditor.h" #include "TextGrid.h" #include "SpellingChecker.h" #include "Preferences.h" #include "TextGridEditor_enums.h" Thing_define (TextGridEditor, TimeSoundAnalysisEditor) { SpellingChecker spellingChecker; long selectedTier; bool suppressRedraw; char32 *findString; GuiMenuItem extractSelectedTextGridPreserveTimesButton, extractSelectedTextGridTimeFromZeroButton; void v_info () override; void v_createChildren () override; void v_createMenus () override; void v_createHelpMenuItems (EditorMenu menu) override; void v_dataChanged () override; void v_createMenuItems_file_extract (EditorMenu menu) override; void v_createMenuItems_file_write (EditorMenu menu) override; void v_createMenuItems_file_draw (EditorMenu menu) override; void v_prepareDraw () override; void v_draw () override; bool v_hasText () override { return true; } int v_click (double xWC, double yWC, bool shiftKeyPressed) override; int v_clickB (double xWC, double yWC) override; int v_clickE (double xWC, double yWC) override; void v_play (double tmin, double tmax) override; void v_updateText () override; void v_prefs_addFields (EditorCommand cmd) override; void v_prefs_setValues (EditorCommand cmd) override; void v_prefs_getValues (EditorCommand cmd) override; void v_createMenuItems_view_timeDomain (EditorMenu menu) override; void v_highlightSelection (double left, double right, double bottom, double top) override; void v_unhighlightSelection (double left, double right, double bottom, double top) override; double v_getBottomOfSoundArea () override; double v_getBottomOfSoundAndAnalysisArea () override; void v_updateMenuItems_file () override; void v_createMenuItems_pitch_picture (EditorMenu menu) override; #include "TextGridEditor_prefs.h" }; void TextGridEditor_init (TextGridEditor me, const char32 *title, TextGrid grid, Sampled sound, bool ownSound, SpellingChecker spellingChecker, const char *callbackSocket); autoTextGridEditor TextGridEditor_create (const char32 *title, TextGrid grid, Sampled sound, // either a Sound or a LongSound, or null bool ownSound, SpellingChecker spellingChecker, const char *callbackSocket); /* End of file TextGridEditor.h */ #endif praat-6.0.04/fon/TextGridEditor_enums.h000066400000000000000000000060411261542461700177640ustar00rootroot00000000000000/* TextGridEditor_enums.h * * Copyright (C) 1992-2007,2013,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ enums_begin (kTextGridEditor_showNumberOf, 1) enums_add (kTextGridEditor_showNumberOf, 1, NOTHING, U"nothing") enums_add (kTextGridEditor_showNumberOf, 2, INTERVALS_OR_POINTS, U"intervals or points") enums_add (kTextGridEditor_showNumberOf, 3, NONEMPTY_INTERVALS_OR_POINTS, U"non-empty intervals or points") enums_end (kTextGridEditor_showNumberOf, 3, INTERVALS_OR_POINTS) enums_begin (kTextGridEditor_language, 1) enums_add (kTextGridEditor_language, 1, AFRIKAANS, U"Afrikaans") enums_add (kTextGridEditor_language, 2, AKAN, U"Akan") enums_add (kTextGridEditor_language, 3, ALBANIAN, U"Albanian") enums_add (kTextGridEditor_language, 4, AMHARIC, U"Amharic") enums_add (kTextGridEditor_language, 5, ARMENIAN, U"Armenian") enums_add (kTextGridEditor_language, 6, ARMENIAN_WEST, U"Armenian (West)") enums_add (kTextGridEditor_language, 7, AZERBAIJANI, U"Azerbaijani") enums_add (kTextGridEditor_language, 8, BOSNIAN, U"Bosnian") enums_add (kTextGridEditor_language, 9, BULGARIAN, U"Bulgarian") enums_add (kTextGridEditor_language, 10, CANTONESE, U"Cantonese") enums_add (kTextGridEditor_language, 11, CATALAN, U"Catalan") enums_add (kTextGridEditor_language, 12, CROATIAN, U"Croatian") enums_add (kTextGridEditor_language, 13, CZECH, U"Czech") enums_add (kTextGridEditor_language, 14, DARI, U"Danish") enums_add (kTextGridEditor_language, 15, DEFAULT_LANGUAGE, U"Default language") enums_add (kTextGridEditor_language, 16, DIVEHI, U"Divehi") enums_add (kTextGridEditor_language, 17, DUTCH, U"Dutch-test") enums_add (kTextGridEditor_language, 18, ENGLISH_AMERICAN, U"English (American)") enums_add (kTextGridEditor_language, 19, ENGLISH_RP, U"English (RP)") enums_add (kTextGridEditor_language, 20, ENGLISH_SCOTLAND, U"English (Scotland)") enums_add (kTextGridEditor_language, 21, ENGLISH_SOUTHERN_ENGLAND, U"English (Southern England)") enums_add (kTextGridEditor_language, 22, ENGLISH_WEST_INDIES, U"English (West Indies)") enums_add (kTextGridEditor_language, 22, ENGLISH_WEST_MIDLANDS, U"English (West Midlands)") enums_add (kTextGridEditor_language, 23, PORTUGUESE_BRAZILIAN, U"Portuguese (Brazilian)") enums_add (kTextGridEditor_language, 24, PORTUGUESE_EUROPEAN, U"Portuguese (European)") enums_end (kTextGridEditor_language, 2, ENGLISH_AMERICAN) /* End of file TextGridEditor_enums.h */ praat-6.0.04/fon/TextGridEditor_prefs.h000066400000000000000000000043141261542461700177550ustar00rootroot00000000000000/* TextGridEditor_prefs.h * * Copyright (C) 2013,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ prefs_begin (TextGridEditor) prefs_override_int (TextGridEditor, shellWidth, 1, U"800") prefs_override_int (TextGridEditor, shellHeight, 1, U"600") prefs_override_bool (TextGridEditor, picture_garnish, 1, true) prefs_add_bool_with_data (TextGridEditor, useTextStyles, 1, false) prefs_add_int_with_data (TextGridEditor, fontSize, 1, U"18") prefs_add_enum_with_data (TextGridEditor, alignment, 1, kGraphics_horizontalAlignment, DEFAULT) prefs_add_bool_with_data (TextGridEditor, shiftDragMultiple, 1, true) prefs_add_enum_with_data (TextGridEditor, showNumberOf, 1, kTextGridEditor_showNumberOf, DEFAULT) prefs_add_enum_with_data (TextGridEditor, greenMethod, 1, kMelder_string, DEFAULT) prefs_add_string_with_data (TextGridEditor, greenString, 1, U"some text here for green paint") prefs_add_bool (TextGridEditor, picture_showBoundaries, 1, true) prefs_add_bool (TextGridEditor, picture_pitch_speckle, 1, false) prefs_add_string_with_data (TextGridEditor, align_language, 1, U"English") prefs_add_bool_with_data (TextGridEditor, align_includeWords, 1, true) prefs_add_bool_with_data (TextGridEditor, align_includePhonemes, 1, false) prefs_add_bool_with_data (TextGridEditor, align_allowSilences, 1, false) prefs_end (TextGridEditor) /* End of file TextGridEditor_prefs.h */ praat-6.0.04/fon/TextGrid_Sound.cpp000066400000000000000000000731701261542461700171200ustar00rootroot00000000000000/* TextGrid_Sound.cpp * * Copyright (C) 1992-2011,2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2010/12/06 BDF/EDF files (for EEG) * pb 2010/12/08 split off from TextGrid.c and Sound.c * pb 2011/06/11 C++ */ #include "TextGrid_Sound.h" #include "Pitch_to_PitchTier.h" #include "SpeechSynthesizer_and_TextGrid.h" #include "LongSound.h" static bool IntervalTier_check (IntervalTier me) { for (long iinterval = 1; iinterval <= my numberOfIntervals (); iinterval ++) { TextInterval interval = my interval (iinterval); if (interval -> xmin >= interval -> xmax) return false; } if (my numberOfIntervals () < 2) return true; for (long iinterval = 1; iinterval < my numberOfIntervals (); iinterval ++) { TextInterval interval = my interval (iinterval), nextInterval = my interval (iinterval + 1); if (interval -> xmax != nextInterval -> xmin) return false; } return true; } static void IntervalTier_insertIntervalDestructively (IntervalTier me, double tmin, double tmax) { Melder_assert (tmin < tmax); Melder_assert (tmin >= my xmin); Melder_assert (tmax <= my xmax); /* * Make sure that the tier has boundaries at the edges of the interval. */ long firstIntervalNumber = IntervalTier_hasTime (me, tmin); if (! firstIntervalNumber) { long intervalNumber = IntervalTier_timeToIndex (me, tmin); if (intervalNumber == 0) Melder_throw (U"Cannot add a boundary at ", Melder_fixed (tmin, 6), U" seconds, because this is outside the time domain of the intervals."); TextInterval interval = my interval (intervalNumber); /* * Move the text to the left of the boundary. */ autoTextInterval newInterval = TextInterval_create (tmin, interval -> xmax, U""); interval -> xmax = tmin; Collection_addItem (my intervals, newInterval.transfer()); firstIntervalNumber = IntervalTier_hasTime (me, interval -> xmin); } Melder_assert (firstIntervalNumber >= 1 && firstIntervalNumber <= my intervals -> size); long lastIntervalNumber = IntervalTier_hasTime (me, tmax); if (! lastIntervalNumber) { long intervalNumber = IntervalTier_timeToIndex (me, tmax); if (intervalNumber == 0) Melder_throw (U"Cannot add a boundary at ", Melder_fixed (tmin, 6), U" seconds, because this is outside the time domain of the intervals."); TextInterval interval = my interval (intervalNumber); /* * Move the text to the right of the boundary. */ autoTextInterval newInterval = TextInterval_create (interval -> xmin, tmax, U""); interval -> xmin = tmax; Collection_addItem (my intervals, newInterval.transfer()); lastIntervalNumber = IntervalTier_hasTime (me, interval -> xmax); } Melder_assert (lastIntervalNumber >= 1 && lastIntervalNumber <= my intervals -> size); /* * Empty the interval in the word tier. */ trace (U"Empty interval %ld down to ", lastIntervalNumber, U".", firstIntervalNumber); for (long iinterval = lastIntervalNumber; iinterval >= firstIntervalNumber; iinterval --) { TextInterval interval = my interval (iinterval); if (interval -> xmin > tmin && interval -> xmin < tmax) { Melder_assert (iinterval > 1); TextInterval previous = (TextInterval) my intervals -> item [iinterval - 1]; previous -> xmax = tmax; // collapse left and right intervals into left interval TextInterval_setText (previous, U""); Collection_removeItem (my intervals, iinterval); // remove right interval } if (interval -> xmax == tmax) { TextInterval_setText (interval, U""); } } } static double IntervalTier_boundaryTimeClosestTo (IntervalTier me, double tmin, double tmax) { long intervalNumber = IntervalTier_timeToLowIndex (me, tmax); if (intervalNumber != 0) { TextInterval interval = my interval (intervalNumber); if (interval -> xmin > tmin && interval -> xmin < tmax) { return interval -> xmin; } } return 0.5 * (tmin + tmax); } static void IntervalTier_removeEmptyIntervals (IntervalTier me, IntervalTier boss) { IntervalTier_removeBoundariesBetweenIdenticallyLabeledIntervals (me, U""); if (my intervals -> size < 2) return; TextInterval firstInterval = my interval (1); if (Melder_equ (firstInterval -> text, U"")) { IntervalTier_removeLeftBoundary (me, 2); } if (my numberOfIntervals () < 2) return; TextInterval lastInterval = my interval (my numberOfIntervals ()); if (Melder_equ (lastInterval -> text, U"")) { IntervalTier_removeLeftBoundary (me, my numberOfIntervals ()); } if (my numberOfIntervals () < 3) return; for (long iinterval = my numberOfIntervals () - 1; iinterval >= 2; iinterval --) { TextInterval interval = my interval (iinterval); if (Melder_equ (interval -> text, U"")) { /* * Distribute the empty interval between its neigbours. */ double newBoundaryTime = boss ? IntervalTier_boundaryTimeClosestTo (boss, interval -> xmin, interval -> xmax) : 0.5 * (interval -> xmin + interval -> xmax); TextInterval previous = my interval (iinterval - 1); TextInterval next = my interval (iinterval + 1); previous -> xmax = newBoundaryTime; next -> xmin = newBoundaryTime; Collection_removeItem (my intervals, iinterval); } } } void TextGrid_anySound_alignInterval (TextGrid me, Function anySound, long tierNumber, long intervalNumber, const char32 *languageName, bool includeWords, bool includePhonemes) { try { IntervalTier headTier = TextGrid_checkSpecifiedTierIsIntervalTier (me, tierNumber); if (intervalNumber < 1 || intervalNumber > headTier -> numberOfIntervals ()) Melder_throw (U"Interval ", intervalNumber, U" does not exist."); TextInterval interval = headTier -> interval (intervalNumber); if (! includeWords && ! includePhonemes) Melder_throw (U"Nothing to be done, because you asked neither for word alignment nor for phoneme alignment."); if (str32str (headTier -> name, U"/") ) Melder_throw (U"The current tier already has a slash (\"/\") in its name. Cannot create a word or phoneme tier from it."); autoSound part = anySound -> classInfo == classLongSound ? LongSound_extractPart (static_cast (anySound), interval -> xmin, interval -> xmax, true) : Sound_extractPart (static_cast (anySound), interval -> xmin, interval -> xmax, kSound_windowShape_RECTANGULAR, 1.0, true); autoSpeechSynthesizer synthesizer = SpeechSynthesizer_create (languageName, U"default"); double silenceThreshold = -35, minSilenceDuration = 0.1, minSoundingDuration = 0.1; autoTextGrid analysis = NULL; if (! Melder_equ (interval -> text, U"")) { try { analysis = SpeechSynthesizer_and_Sound_and_TextInterval_align (synthesizer.peek(), part.peek(), interval, silenceThreshold, minSilenceDuration, minSoundingDuration); } catch (MelderError) { Melder_clearError (); // ignore all error messages from DTW and the like } } if (analysis.peek()) { /* * Clean up the analysis. */ Melder_assert (analysis -> xmin == interval -> xmin); Melder_assert (analysis -> xmax == interval -> xmax); Melder_assert (analysis -> numberOfTiers () == 4); Thing_cast (IntervalTier, analysisWordTier, analysis -> tier (3)); if (! IntervalTier_check (analysisWordTier)) Melder_throw (U"Analysis word tier out of order."); IntervalTier_removeEmptyIntervals (analysisWordTier, NULL); Melder_assert (analysisWordTier -> xmax == analysis -> xmax); Melder_assert (analysisWordTier -> numberOfIntervals () >= 1); TextInterval firstInterval = analysisWordTier -> interval (1); TextInterval lastInterval = analysisWordTier -> interval (analysisWordTier -> numberOfIntervals ()); firstInterval -> xmin = analysis -> xmin; lastInterval -> xmax = analysis -> xmax; if (lastInterval -> xmax != analysis -> xmax) Melder_fatal (U"analysis ends at ", analysis -> xmax, U", but last interval at ", lastInterval -> xmax, U" seconds"); if (! IntervalTier_check (analysisWordTier)) Melder_throw (U"Analysis word tier out of order (2)."); Thing_cast (IntervalTier, analysisPhonemeTier, analysis -> tier (4)); if (! IntervalTier_check (analysisPhonemeTier)) Melder_throw (U"Analysis phoneme tier out of order."); IntervalTier_removeEmptyIntervals (analysisPhonemeTier, analysisWordTier); Melder_assert (analysisPhonemeTier -> xmax == analysis -> xmax); Melder_assert (analysisPhonemeTier -> numberOfIntervals () >= 1); firstInterval = analysisPhonemeTier -> interval (1); lastInterval = analysisPhonemeTier -> interval (analysisPhonemeTier -> numberOfIntervals ()); firstInterval -> xmin = analysis -> xmin; lastInterval -> xmax = analysis -> xmax; Melder_assert (lastInterval -> xmax == analysis -> xmax); if (! IntervalTier_check (analysisPhonemeTier)) Melder_throw (U"Analysis phoneme tier out of order (2)."); } long wordTierNumber = 0, phonemeTierNumber = 0; IntervalTier wordTier = NULL, phonemeTier = NULL; /* * Include a word tier. */ if (includeWords) { /* * Make sure that the word tier exists. */ autoMelderString newWordTierName; MelderString_copy (& newWordTierName, headTier -> name, U"/word"); for (long itier = 1; itier <= my numberOfTiers (); itier ++) { IntervalTier tier = static_cast (my tier (itier)); if (Melder_equ (newWordTierName.string, tier -> name)) { if (tier -> classInfo != classIntervalTier) Melder_throw (U"A tier with the prospective word tier name (", tier -> name, U") already exists, but it is not an interval tier." U"\nPlease change its name or remove it."); wordTierNumber = itier; break; } } if (! wordTierNumber) { autoIntervalTier newWordTier = IntervalTier_create (my xmin, my xmax); Thing_setName (newWordTier.peek(), newWordTierName.string); Ordered_addItemPos (my tiers, newWordTier.transfer(), wordTierNumber = tierNumber + 1); } Melder_assert (wordTierNumber >= 1 && wordTierNumber <= my tiers -> size); wordTier = static_cast (my tier (wordTierNumber)); /* * Make sure that the word tier has boundaries at the edges of the interval. */ IntervalTier_insertIntervalDestructively (wordTier, interval -> xmin, interval -> xmax); /* * Copy the contents of the word analysis into the interval in the word tier. */ long wordIntervalNumber = IntervalTier_hasTime (wordTier, interval -> xmin); Melder_assert (wordIntervalNumber != 0); if (analysis.peek()) { Thing_cast (IntervalTier, analysisWordTier, analysis -> tier (3)); if (! IntervalTier_check (analysisWordTier)) Melder_throw (U"Analysis word tier out of order (3)."); if (! IntervalTier_check (wordTier)) Melder_throw (U"Word tier out of order (3)."); for (long ianalysisInterval = 1; ianalysisInterval <= analysisWordTier -> numberOfIntervals (); ianalysisInterval ++) { TextInterval analysisInterval = analysisWordTier -> interval (ianalysisInterval); TextInterval wordInterval = NULL; double tmin = analysisInterval -> xmin, tmax = analysisInterval -> xmax; if (tmax == analysis -> xmax) { wordInterval = wordTier -> interval (wordIntervalNumber); TextInterval_setText (wordInterval, analysisInterval -> text); } else { wordInterval = wordTier -> interval (wordIntervalNumber); autoTextInterval newInterval = TextInterval_create (tmin, tmax, analysisInterval -> text); wordInterval -> xmin = tmax; Collection_addItem (wordTier -> intervals, newInterval.transfer()); wordIntervalNumber ++; } } if (! IntervalTier_check (analysisWordTier)) Melder_throw (U"Analysis word tier out of order (4)."); if (! IntervalTier_check (wordTier)) Melder_throw (U"Word tier out of order (4)."); } } /* * Include a phoneme tier. */ if (includePhonemes) { /* * Make sure that the phoneme tier exists. */ autoMelderString newPhonemeTierName; MelderString_copy (& newPhonemeTierName, headTier -> name, U"/phon"); for (long itier = 1; itier <= my numberOfTiers (); itier ++) { IntervalTier tier = static_cast (my tier (itier)); if (Melder_equ (newPhonemeTierName.string, tier -> name)) { if (tier -> classInfo != classIntervalTier) Melder_throw (U"A tier with the prospective phoneme tier name (", tier -> name, U") already exists, but it is not an interval tier." U"\nPlease change its name or remove it."); phonemeTierNumber = itier; break; } } if (! phonemeTierNumber) { autoIntervalTier newPhonemeTier = IntervalTier_create (my xmin, my xmax); Thing_setName (newPhonemeTier.peek(), newPhonemeTierName.string); Ordered_addItemPos (my tiers, newPhonemeTier.transfer(), phonemeTierNumber = wordTierNumber ? wordTierNumber + 1 : tierNumber + 1); } Melder_assert (phonemeTierNumber >= 1 && phonemeTierNumber <= my tiers -> size); phonemeTier = static_cast (my tiers -> item [phonemeTierNumber]); /* * Make sure that the phoneme tier has boundaries at the edges of the interval. */ IntervalTier_insertIntervalDestructively (phonemeTier, interval -> xmin, interval -> xmax); /* * Copy the contents of the phoneme analysis into the interval in the phoneme tier. */ long phonemeIntervalNumber = IntervalTier_hasTime (phonemeTier, interval -> xmin); Melder_assert (phonemeIntervalNumber != 0); if (analysis.peek()) { Thing_cast (IntervalTier, analysisPhonemeTier, analysis -> tiers -> item [4]); for (long ianalysisInterval = 1; ianalysisInterval <= analysisPhonemeTier -> numberOfIntervals (); ianalysisInterval ++) { TextInterval analysisInterval = analysisPhonemeTier -> interval (ianalysisInterval); TextInterval phonemeInterval = NULL; double tmin = analysisInterval -> xmin, tmax = analysisInterval -> xmax; if (tmax == analysis -> xmax) { phonemeInterval = phonemeTier -> interval (phonemeIntervalNumber); TextInterval_setText (phonemeInterval, analysisInterval -> text); } else { phonemeInterval = phonemeTier -> interval (phonemeIntervalNumber); autoTextInterval newInterval = TextInterval_create (tmin, tmax, analysisInterval -> text); phonemeInterval -> xmin = tmax; Collection_addItem (phonemeTier -> intervals, newInterval.transfer()); phonemeIntervalNumber ++; } } } if (includeWords) { /* * Synchronize the boundaries between the word tier and the phoneme tier. */ //for (long iinterval = 1; iinterval <= } } } catch (MelderError) { Melder_throw (me, U" & ", anySound, U": interval not aligned."); } } void TextGrid_Sound_draw (TextGrid me, Sound sound, Graphics g, double tmin, double tmax, bool showBoundaries, bool useTextStyles, bool garnish) // STEREO BUG { long numberOfTiers = my numberOfTiers (); /* * Automatic windowing: */ if (tmax <= tmin) tmin = my xmin, tmax = my xmax; Graphics_setInner (g); Graphics_setWindow (g, tmin, tmax, -1.0 - 0.5 * numberOfTiers, 1.0); /* * Draw sound in upper part. */ long first, last; if (sound && Sampled_getWindowSamples (sound, tmin, tmax, & first, & last) > 1) { Graphics_setLineType (g, Graphics_DOTTED); Graphics_line (g, tmin, 0.0, tmax, 0.0); Graphics_setLineType (g, Graphics_DRAWN); Graphics_function (g, sound -> z [1], first, last, Sampled_indexToX (sound, first), Sampled_indexToX (sound, last)); } /* * Draw labels in lower part. */ Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); Graphics_setPercentSignIsItalic (g, useTextStyles); Graphics_setNumberSignIsBold (g, useTextStyles); Graphics_setCircumflexIsSuperscript (g, useTextStyles); Graphics_setUnderscoreIsSubscript (g, useTextStyles); for (long itier = 1; itier <= numberOfTiers; itier ++) { Function anyTier = my tier (itier); double ymin = -1.0 - 0.5 * itier, ymax = ymin + 0.5; Graphics_rectangle (g, tmin, tmax, ymin, ymax); if (anyTier -> classInfo == classIntervalTier) { IntervalTier tier = static_cast (anyTier); long ninterval = tier -> numberOfIntervals (); for (long iinterval = 1; iinterval <= ninterval; iinterval ++) { TextInterval interval = tier -> interval (iinterval); double intmin = interval -> xmin, intmax = interval -> xmax; if (intmin < tmin) intmin = tmin; if (intmax > tmax) intmax = tmax; if (intmin >= intmax) continue; if (showBoundaries && intmin > tmin && intmin < tmax) { Graphics_setLineType (g, Graphics_DOTTED); Graphics_line (g, intmin, -1.0, intmin, 1.0); /* In sound part. */ Graphics_setLineType (g, Graphics_DRAWN); } /* Draw left boundary. */ if (intmin > tmin && intmin < tmax) Graphics_line (g, intmin, ymin, intmin, ymax); /* Draw label text. */ if (interval -> text && intmax >= tmin && intmin <= tmax) { double t1 = tmin > intmin ? tmin : intmin; double t2 = tmax < intmax ? tmax : intmax; Graphics_text (g, 0.5 * (t1 + t2), 0.5 * (ymin + ymax), interval -> text); } } } else { TextTier tier = static_cast (anyTier); long numberOfPoints = tier -> numberOfPoints (); for (long ipoint = 1; ipoint <= numberOfPoints; ipoint ++) { TextPoint point = tier -> point (ipoint); double t = point -> number; if (t > tmin && t < tmax) { if (showBoundaries) { Graphics_setLineType (g, Graphics_DOTTED); Graphics_line (g, t, -1.0, t, 1.0); /* In sound part. */ Graphics_setLineType (g, Graphics_DRAWN); } Graphics_line (g, t, ymin, t, 0.8 * ymin + 0.2 * ymax); Graphics_line (g, t, 0.2 * ymin + 0.8 * ymax, t, ymax); if (point -> mark) Graphics_text (g, t, 0.5 * (ymin + ymax), point -> mark); } } } } Graphics_setPercentSignIsItalic (g, true); Graphics_setNumberSignIsBold (g, true); Graphics_setCircumflexIsSuperscript (g, true); Graphics_setUnderscoreIsSubscript (g, true); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Time (s)"); Graphics_marksBottom (g, 2, true, true, false); } } autoCollection TextGrid_Sound_extractAllIntervals (TextGrid me, Sound sound, long tierNumber, int preserveTimes) { try { IntervalTier tier = TextGrid_checkSpecifiedTierIsIntervalTier (me, tierNumber); autoCollection collection = Collection_create (NULL, tier -> numberOfIntervals ()); for (long iseg = 1; iseg <= tier -> numberOfIntervals (); iseg ++) { TextInterval segment = tier -> interval (iseg); autoSound interval = Sound_extractPart (sound, segment -> xmin, segment -> xmax, kSound_windowShape_RECTANGULAR, 1.0, preserveTimes); Thing_setName (interval.peek(), segment -> text ? segment -> text : U"untitled"); Collection_addItem (collection.peek(), interval.transfer()); } return collection; } catch (MelderError) { Melder_throw (me, U" & ", sound, U": intervals not extracted."); } } autoCollection TextGrid_Sound_extractNonemptyIntervals (TextGrid me, Sound sound, long tierNumber, int preserveTimes) { try { IntervalTier tier = TextGrid_checkSpecifiedTierIsIntervalTier (me, tierNumber); autoCollection collection = Collection_create (NULL, tier -> numberOfIntervals ()); for (long iseg = 1; iseg <= tier -> numberOfIntervals (); iseg ++) { TextInterval segment = tier -> interval (iseg); if (segment -> text != NULL && segment -> text [0] != '\0') { autoSound interval = Sound_extractPart (sound, segment -> xmin, segment -> xmax, kSound_windowShape_RECTANGULAR, 1.0, preserveTimes); Thing_setName (interval.peek(), segment -> text ? segment -> text : U"untitled"); Collection_addItem (collection.peek(), interval.transfer()); } } if (collection -> size == 0) Melder_warning (U"No non-empty intervals were found."); return collection; } catch (MelderError) { Melder_throw (me, U" & ", sound, U": non-empty intervals not extracted."); } } autoCollection TextGrid_Sound_extractIntervalsWhere (TextGrid me, Sound sound, long tierNumber, int comparison_Melder_STRING, const char32 *text, int preserveTimes) { try { IntervalTier tier = TextGrid_checkSpecifiedTierIsIntervalTier (me, tierNumber); autoCollection collection = Collection_create (NULL, tier -> numberOfIntervals ()); long count = 0; for (long iseg = 1; iseg <= tier -> numberOfIntervals (); iseg ++) { TextInterval segment = tier -> interval (iseg); if (Melder_stringMatchesCriterion (segment -> text, comparison_Melder_STRING, text)) { autoSound interval = Sound_extractPart (sound, segment -> xmin, segment -> xmax, kSound_windowShape_RECTANGULAR, 1.0, preserveTimes); Thing_setName (interval.peek(), Melder_cat (sound -> name ? sound -> name : U"", U"_", text, U"_", ++ count)); Collection_addItem (collection.peek(), interval.transfer()); } } if (collection -> size == 0) Melder_warning (U"No label that ", kMelder_string_getText (comparison_Melder_STRING), U" the text \"", text, U"\" was found."); return collection; } catch (MelderError) { Melder_throw (me, U" & ", sound, U": intervals not extracted."); } } static void autoMarks (Graphics g, double ymin, double ymax, bool haveDottedLines) { double dy = ymax - ymin; if (dy < 26.0) { long imin = (long) ceil ((ymin + 2.0) / 5.0), imax = (long) floor ((ymax - 2.0) / 5.0); for (long i = imin; i <= imax; i ++) Graphics_markLeft (g, i * 5.0, true, true, haveDottedLines, nullptr); } else if (dy < 110.0) { long imin = (long) ceil ((ymin + 8.0) / 20.0), imax = (long) floor ((ymax - 8.0) / 20.0); for (long i = imin; i <= imax; i ++) Graphics_markLeft (g, i * 20.0, true, true, haveDottedLines, nullptr); } else if (dy < 260.0) { long imin = (long) ceil ((ymin + 20.0) / 50.0), imax = (long) floor ((ymax - 20.0) / 50.0); for (long i = imin; i <= imax; i ++) Graphics_markLeft (g, i * 50.0, true, true, haveDottedLines, nullptr); } else if (dy < 510.0) { long imin = (long) ceil ((ymin + 40.0) / 100.0), imax = (long) floor ((ymax - 40.0) / 100.0); for (long i = imin; i <= imax; i ++) Graphics_markLeft (g, i * 100.0, true, true, haveDottedLines, nullptr); } } static void autoMarks_logarithmic (Graphics g, double ymin, double ymax, bool haveDottedLines) { double fy = ymax / ymin; for (int i = -12; i <= 12; i ++) { double power = pow (10, i), y = power; if (y > ymin * 1.2 && y < ymax / 1.2) Graphics_markLeftLogarithmic (g, y, true, true, haveDottedLines, nullptr); if (fy > 2100) { ; /* Enough. */ } else if (fy > 210) { y = 3.0 * power; if (y > ymin * 1.2 && y < ymax / 1.2) Graphics_markLeftLogarithmic (g, y, true, true, haveDottedLines, nullptr); } else { y = 2.0 * power; if (y > ymin * 1.2 && y < ymax / 1.2) Graphics_markLeftLogarithmic (g, y, true, true, haveDottedLines, nullptr); y = 5.0 * power; if (y > ymin * 1.2 && y < ymax / 1.2) Graphics_markLeftLogarithmic (g, y, true, true, haveDottedLines, nullptr); if (fy < 21) { y = 3.0 * power; if (y > ymin * 1.2 && y < ymax / 1.2) Graphics_markLeftLogarithmic (g, y, true, true, haveDottedLines, nullptr); y = 7.0 * power; if (y > ymin * 1.2 && y < ymax / 1.2) Graphics_markLeftLogarithmic (g, y, true, true, haveDottedLines, nullptr); } if (fy < 4.1) { y = 1.5 * power; if (y > ymin * 1.2 && y < ymax / 1.2) Graphics_markLeftLogarithmic (g, y, true, true, haveDottedLines, nullptr); y = 4.0 * power; if (y > ymin * 1.2 && y < ymax / 1.2) Graphics_markLeftLogarithmic (g, y, true, true, haveDottedLines, nullptr); } } } } static void autoMarks_semitones (Graphics g, double ymin, double ymax, bool haveDottedLines) { double dy = ymax - ymin; if (dy < 16) { long imin = (long) ceil ((ymin + 1.2) / 3.0), imax = (long) floor ((ymax - 1.2) / 3.0); for (long i = imin; i <= imax; i ++) Graphics_markLeft (g, i * 3.0, true, true, haveDottedLines, nullptr); } else if (dy < 32) { long imin = (long) ceil ((ymin + 2.4) / 6.0), imax = (long) floor ((ymax - 2.4) / 6.0); for (long i = imin; i <= imax; i ++) Graphics_markLeft (g, i * 6.0, true, true, haveDottedLines, nullptr); } else if (dy < 64) { long imin = (long) ceil ((ymin + 4.8) / 12.0), imax = (long) floor ((ymax - 4.8) / 12.0); for (long i = imin; i <= imax; i ++) Graphics_markLeft (g, i * 12.0, true, true, haveDottedLines, nullptr); } else if (dy < 128) { long imin = (long) ceil ((ymin + 9.6) / 24.0), imax = (long) floor ((ymax - 9.6) / 24.0); for (long i = imin; i <= imax; i ++) Graphics_markLeft (g, i * 24.0, true, true, haveDottedLines, nullptr); } } void TextGrid_Pitch_drawSeparately (TextGrid grid, Pitch pitch, Graphics g, double tmin, double tmax, double fmin, double fmax, int showBoundaries, int useTextStyles, int garnish, int speckle, int unit) { int ntier = grid -> tiers -> size; if (tmax <= tmin) tmin = grid -> xmin, tmax = grid -> xmax; if (Function_isUnitLogarithmic (pitch, Pitch_LEVEL_FREQUENCY, unit)) { fmin = Function_convertStandardToSpecialUnit (pitch, fmin, Pitch_LEVEL_FREQUENCY, unit); fmax = Function_convertStandardToSpecialUnit (pitch, fmax, Pitch_LEVEL_FREQUENCY, unit); } if (unit == kPitch_unit_HERTZ_LOGARITHMIC) Pitch_draw (pitch, g, tmin, tmax, pow (10.0, fmin - 0.25 * (fmax - fmin) * ntier), pow (10.0, fmax), false, speckle, unit); else Pitch_draw (pitch, g, tmin, tmax, fmin - 0.25 * (fmax - fmin) * ntier, fmax, false, speckle, unit); TextGrid_Sound_draw (grid, NULL, g, tmin, tmax, showBoundaries, useTextStyles, false); /* * Restore window for the sake of margin drawing. */ Graphics_setWindow (g, tmin, tmax, fmin - 0.25 * (fmax - fmin) * ntier, fmax); if (unit == kPitch_unit_HERTZ_LOGARITHMIC) fmin = pow (10, fmin), fmax = pow (10.0, fmax); if (garnish) { Graphics_drawInnerBox (g); if (unit == kPitch_unit_HERTZ_LOGARITHMIC) { Graphics_markLeftLogarithmic (g, fmin, true, true, false, nullptr); Graphics_markLeftLogarithmic (g, fmax, true, true, false, nullptr); autoMarks_logarithmic (g, fmin, fmax, false); } else if (unit == kPitch_unit_SEMITONES_100) { Graphics_markLeft (g, fmin, true, true, false, nullptr); Graphics_markLeft (g, fmax, true, true, false, nullptr); autoMarks_semitones (g, fmin, fmax, false); } else { Graphics_markLeft (g, fmin, true, true, false, nullptr); Graphics_markLeft (g, fmax, true, true, false, nullptr); autoMarks (g, fmin, fmax, false); } Graphics_textLeft (g, true, Melder_cat (U"Pitch (", Function_getUnitText (pitch, Pitch_LEVEL_FREQUENCY, unit, Function_UNIT_TEXT_GRAPHICAL), U")")); Graphics_textBottom (g, true, U"Time (s)"); Graphics_marksBottom (g, 2, true, true, false); } } void TextGrid_Pitch_draw (TextGrid grid, Pitch pitch, Graphics g, long tierNumber, double tmin, double tmax, double fmin, double fmax, double fontSize, int useTextStyles, int horizontalAlignment, int garnish, int speckle, int unit) { try { Function anyTier = TextGrid_checkSpecifiedTierNumberWithinRange (grid, tierNumber); double oldFontSize = Graphics_inqFontSize (g); Pitch_draw (pitch, g, tmin, tmax, fmin, fmax, garnish, speckle, unit); if (tmax <= tmin) tmin = grid -> xmin, tmax = grid -> xmax; autoPitchTier pitchTier = Pitch_to_PitchTier (pitch); if (Function_isUnitLogarithmic (pitch, Pitch_LEVEL_FREQUENCY, unit)) { fmin = Function_convertStandardToSpecialUnit (pitch, fmin, Pitch_LEVEL_FREQUENCY, unit); fmax = Function_convertStandardToSpecialUnit (pitch, fmax, Pitch_LEVEL_FREQUENCY, unit); } Graphics_setTextAlignment (g, horizontalAlignment, Graphics_BOTTOM); Graphics_setInner (g); Graphics_setFontSize (g, fontSize); Graphics_setPercentSignIsItalic (g, useTextStyles); Graphics_setNumberSignIsBold (g, useTextStyles); Graphics_setCircumflexIsSuperscript (g, useTextStyles); Graphics_setUnderscoreIsSubscript (g, useTextStyles); if (anyTier -> classInfo == classIntervalTier) { IntervalTier tier = static_cast (anyTier); for (long i = 1; i <= tier -> numberOfIntervals (); i ++) { TextInterval interval = tier -> interval (i); double tleft = interval -> xmin, tright = interval -> xmax, tmid, f0; if (! interval -> text || ! interval -> text [0]) continue; if (tleft < pitch -> xmin) tleft = pitch -> xmin; if (tright > pitch -> xmax) tright = pitch -> xmax; tmid = (tleft + tright) / 2; if (tmid < tmin || tmid > tmax) continue; f0 = Function_convertStandardToSpecialUnit (pitch, RealTier_getValueAtTime (pitchTier.peek(), tmid), Pitch_LEVEL_FREQUENCY, unit); if (f0 < fmin || f0 > fmax) continue; Graphics_text (g, horizontalAlignment == Graphics_LEFT ? tleft : horizontalAlignment == Graphics_RIGHT ? tright : tmid, f0, interval -> text); } } else { TextTier tier = static_cast (anyTier); for (long i = 1; i <= tier -> numberOfPoints (); i ++) { TextPoint point = tier -> point (i); double t = point -> number, f0; if (! point -> mark || ! point -> mark [0]) continue; if (t < tmin || t > tmax) continue; f0 = Function_convertStandardToSpecialUnit (pitch, RealTier_getValueAtTime (pitchTier.peek(), t), Pitch_LEVEL_FREQUENCY, unit); if (f0 < fmin || f0 > fmax) continue; Graphics_text (g, t, f0, point -> mark); } } Graphics_setPercentSignIsItalic (g, true); Graphics_setNumberSignIsBold (g, true); Graphics_setCircumflexIsSuperscript (g, true); Graphics_setUnderscoreIsSubscript (g, true); Graphics_setFontSize (g, oldFontSize); Graphics_unsetInner (g); } catch (MelderError) { Melder_throw (grid, U" & ", pitch, U": not drawn."); } } /* End of file TextGrid_Sound.cpp */ praat-6.0.04/fon/TextGrid_Sound.h000066400000000000000000000037521261542461700165640ustar00rootroot00000000000000/* TextGrid_Sound.h * * Copyright (C) 1992-2011,2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "TextGrid.h" #include "Sound.h" #include "Pitch.h" void TextGrid_Sound_draw (TextGrid me, Sound sound, Graphics g, double tmin, double tmax, bool showBoundaries, bool useTextStyles, bool garnish); autoCollection TextGrid_Sound_extractAllIntervals (TextGrid me, Sound sound, long itier, int preserveTimes); autoCollection TextGrid_Sound_extractNonemptyIntervals (TextGrid me, Sound sound, long itier, int preserveTimes); autoCollection TextGrid_Sound_extractIntervalsWhere (TextGrid me, Sound sound, long itier, int which_Melder_STRING, const char32 *text, int preserveTimes); void TextGrid_Pitch_draw (TextGrid grid, Pitch pitch, Graphics g, long itier, double tmin, double tmax, double fmin, double fmax, double fontSize, int useTextStyles, int horizontalAlignment, int garnish, int speckle, int yscale); void TextGrid_Pitch_drawSeparately (TextGrid grid, Pitch pitch, Graphics g, double tmin, double tmax, double fmin, double fmax, int showBoundaries, int useTextStyles, int garnish, int speckle, int yscale); void TextGrid_anySound_alignInterval (TextGrid me, Function anySound, long tierNumber, long intervalNumber, const char32 *languageName, bool includeWords, bool includePhonemes); /* End of file TextGrid_Sound.h */ praat-6.0.04/fon/TextGrid_def.h000066400000000000000000000063311261542461700162260ustar00rootroot00000000000000/* TextGrid_def.h * * Copyright (C) 1992-2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT TextPoint oo_DEFINE_CLASS (TextPoint, AnyPoint) oo_STRING (mark) /* 'after' was a temporary attribute (19970211-19970307). */ #if oo_READING_TEXT if (formatVersion == 1) texgetw2 (a_text); #elif oo_READING_BINARY if (formatVersion == 1) bingetw2 (f); #endif oo_END_CLASS (TextPoint) #undef ooSTRUCT #define ooSTRUCT TextInterval oo_DEFINE_CLASS (TextInterval, Function) oo_STRING (text) #if oo_DECLARING int v_domainQuantity () override { return MelderQuantity_TIME_SECONDS; } #endif oo_END_CLASS (TextInterval) #undef ooSTRUCT #define ooSTRUCT TextTier oo_DEFINE_CLASS (TextTier, Function) oo_COLLECTION (SortedSetOfDouble, points, TextPoint, 0) #if oo_DECLARING long numberOfPoints () // accessor { return our points -> size; } TextPoint& point (long i) // accessor { return reinterpret_cast (our points -> item [i]); } int v_domainQuantity () override { return MelderQuantity_TIME_SECONDS; } void v_shiftX (double xfrom, double xto) override; void v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto) override; #endif oo_END_CLASS (TextTier) #undef ooSTRUCT #define ooSTRUCT IntervalTier oo_DEFINE_CLASS (IntervalTier, Function) oo_COLLECTION (SortedSetOfDouble, intervals, TextInterval, 0) #if oo_DECLARING long numberOfIntervals () // accessor { return our intervals -> size; } TextInterval& interval (long i) // accessor { return reinterpret_cast (our intervals -> item [i]); } int v_domainQuantity () override { return MelderQuantity_TIME_SECONDS; } void v_shiftX (double xfrom, double xto) override; void v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto) override; #endif oo_END_CLASS (IntervalTier) #undef ooSTRUCT #define ooSTRUCT TextGrid oo_DEFINE_CLASS (TextGrid, Function) oo_OBJECT (Ordered, 0, tiers) // TextTier and IntervalTier objects #if oo_DECLARING long numberOfTiers () // accessor { return our tiers -> size; } Function& tier (long i) // accessor { return reinterpret_cast (our tiers -> item [i]); } void v_info () override; void v_repair () override; int v_domainQuantity () override { return MelderQuantity_TIME_SECONDS; } void v_shiftX (double xfrom, double xto) override; void v_scaleX (double xminfrom, double xmaxfrom, double xminto, double xmaxto) override; #endif oo_END_CLASS (TextGrid) #undef ooSTRUCT /* End of file TextGrid_def.h */ praat-6.0.04/fon/TimeSoundAnalysisEditor.cpp000066400000000000000000003165731261542461700210070ustar00rootroot00000000000000/* TimeSoundAnalysisEditor.cpp * * Copyright (C) 1992-2012,2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include "TimeSoundAnalysisEditor.h" #include "Preferences.h" #include "EditorM.h" #include "Sound_and_Spectrogram.h" #include "Sound_and_Spectrum.h" #include "Sound_to_Pitch.h" #include "Sound_to_Intensity.h" #include "Sound_to_Formant.h" #include "Pitch_to_PointProcess.h" #include "VoiceAnalysis.h" #include "praat_script.h" #include "enums_getText.h" #include "TimeSoundAnalysisEditor_enums.h" #include "enums_getValue.h" #include "TimeSoundAnalysisEditor_enums.h" Thing_implement (TimeSoundAnalysisEditor, TimeSoundEditor, 0); #include "prefs_define.h" #include "TimeSoundAnalysisEditor_prefs.h" #include "prefs_install.h" #include "TimeSoundAnalysisEditor_prefs.h" #include "prefs_copyToInstance.h" #include "TimeSoundAnalysisEditor_prefs.h" static const char32 * theMessage_Cannot_compute_spectrogram = U"The spectrogram is not defined at the edge of the sound."; static const char32 * theMessage_Cannot_compute_pitch = U"The pitch contour is not defined at the edge of the sound."; static const char32 * theMessage_Cannot_compute_formant = U"The formants are not defined at the edge of the sound."; static const char32 * theMessage_Cannot_compute_intensity = U"The intensity curve is not defined at the edge of the sound."; static const char32 * theMessage_Cannot_compute_pulses = U"The pulses are not defined at the edge of the sound."; void structTimeSoundAnalysisEditor :: v_destroy () { TimeSoundAnalysisEditor_Parent :: v_destroy (); } void structTimeSoundAnalysisEditor :: v_info () { TimeSoundAnalysisEditor_Parent :: v_info (); if (v_hasSpectrogram ()) { /* Spectrogram flag: */ MelderInfo_writeLine (U"Spectrogram show: ", p_spectrogram_show); /* Spectrogram settings: */ MelderInfo_writeLine (U"Spectrogram view from: ", p_spectrogram_viewFrom, U" Hz"); MelderInfo_writeLine (U"Spectrogram view to: ", p_spectrogram_viewTo, U" Hz"); MelderInfo_writeLine (U"Spectrogram window length: ", p_spectrogram_windowLength, U" seconds"); MelderInfo_writeLine (U"Spectrogram dynamic range: ", p_spectrogram_dynamicRange, U" dB"); /* Advanced spectrogram settings: */ MelderInfo_writeLine (U"Spectrogram number of time steps: ", p_spectrogram_timeSteps); MelderInfo_writeLine (U"Spectrogram number of frequency steps: ", p_spectrogram_frequencySteps); MelderInfo_writeLine (U"Spectrogram method: ", U"Fourier"); MelderInfo_writeLine (U"Spectrogram window shape: ", kSound_to_Spectrogram_windowShape_getText (p_spectrogram_windowShape)); MelderInfo_writeLine (U"Spectrogram autoscaling: ", p_spectrogram_autoscaling); MelderInfo_writeLine (U"Spectrogram maximum: ", p_spectrogram_maximum, U" dB/Hz"); MelderInfo_writeLine (U"Spectrogram pre-emphasis: ", p_spectrogram_preemphasis, U" dB/octave"); MelderInfo_writeLine (U"Spectrogram dynamicCompression: ", p_spectrogram_dynamicCompression); /* Dynamic information: */ MelderInfo_writeLine (U"Spectrogram cursor frequency: ", d_spectrogram_cursor, U" Hz"); } if (v_hasPitch ()) { /* Pitch flag: */ MelderInfo_writeLine (U"Pitch show: ", p_pitch_show); /* Pitch settings: */ MelderInfo_writeLine (U"Pitch floor: ", p_pitch_floor, U" Hz"); MelderInfo_writeLine (U"Pitch ceiling: ", p_pitch_ceiling, U" Hz"); MelderInfo_writeLine (U"Pitch unit: ", Function_getUnitText (Thing_dummyObject (Pitch), Pitch_LEVEL_FREQUENCY, p_pitch_unit, Function_UNIT_TEXT_MENU)); MelderInfo_writeLine (U"Pitch drawing method: ", kTimeSoundAnalysisEditor_pitch_drawingMethod_getText (p_pitch_drawingMethod)); /* Advanced pitch settings: */ MelderInfo_writeLine (U"Pitch view from: ", p_pitch_viewFrom, U" ", Function_getUnitText (Thing_dummyObject (Pitch), Pitch_LEVEL_FREQUENCY, p_pitch_unit, Function_UNIT_TEXT_MENU)); MelderInfo_writeLine (U"Pitch view to: ", p_pitch_viewTo, U" ", Function_getUnitText (Thing_dummyObject (Pitch), Pitch_LEVEL_FREQUENCY, p_pitch_unit, Function_UNIT_TEXT_MENU)); MelderInfo_writeLine (U"Pitch method: ", kTimeSoundAnalysisEditor_pitch_analysisMethod_getText (p_pitch_method)); MelderInfo_writeLine (U"Pitch very accurate: ", p_pitch_veryAccurate); MelderInfo_writeLine (U"Pitch max. number of candidates: ", p_pitch_maximumNumberOfCandidates); MelderInfo_writeLine (U"Pitch silence threshold: ", p_pitch_silenceThreshold, U" of global peak"); MelderInfo_writeLine (U"Pitch voicing threshold: ", p_pitch_voicingThreshold, U" (periodic power / total power)"); MelderInfo_writeLine (U"Pitch octave cost: ", p_pitch_octaveCost, U" per octave"); MelderInfo_writeLine (U"Pitch octave jump cost: ", p_pitch_octaveJumpCost, U" per octave"); MelderInfo_writeLine (U"Pitch voiced/unvoiced cost: ", p_pitch_voicedUnvoicedCost); } if (v_hasIntensity ()) { /* Intensity flag: */ MelderInfo_writeLine (U"Intensity show: ", p_intensity_show); /* Intensity settings: */ MelderInfo_writeLine (U"Intensity view from: ", p_intensity_viewFrom, U" dB"); MelderInfo_writeLine (U"Intensity view to: ", p_intensity_viewTo, U" dB"); MelderInfo_writeLine (U"Intensity averaging method: ", kTimeSoundAnalysisEditor_intensity_averagingMethod_getText (p_intensity_averagingMethod)); MelderInfo_writeLine (U"Intensity subtract mean pressure: ", p_intensity_subtractMeanPressure); } if (v_hasFormants ()) { /* Formant flag: */ MelderInfo_writeLine (U"Formant show: ", p_formant_show); /* Formant settings: */ MelderInfo_writeLine (U"Formant maximum formant: ", p_formant_maximumFormant, U" Hz"); MelderInfo_writeLine (U"Formant number of poles: ", Melder_integer (2 * p_formant_numberOfFormants)); // should be a whole number MelderInfo_writeLine (U"Formant window length: ", p_formant_windowLength, U" seconds"); MelderInfo_writeLine (U"Formant dynamic range: ", p_formant_dynamicRange, U" dB"); MelderInfo_writeLine (U"Formant dot size: ", p_formant_dotSize, U" mm"); /* Advanced formant settings: */ MelderInfo_writeLine (U"Formant method: ", kTimeSoundAnalysisEditor_formant_analysisMethod_getText (p_formant_method)); MelderInfo_writeLine (U"Formant pre-emphasis from: ", p_formant_preemphasisFrom, U" Hz"); } if (v_hasPulses ()) { /* Pulses flag: */ MelderInfo_writeLine (U"Pulses show: ", p_pulses_show); MelderInfo_writeLine (U"Pulses maximum period factor: ", p_pulses_maximumPeriodFactor); MelderInfo_writeLine (U"Pulses maximum amplitude factor: ", p_pulses_maximumAmplitudeFactor); } } void structTimeSoundAnalysisEditor :: v_reset_analysis () { d_spectrogram. reset(); d_pitch. reset(); d_intensity. reset(); d_formant. reset(); d_pulses. reset(); } enum { TimeSoundAnalysisEditor_PART_CURSOR = 1, TimeSoundAnalysisEditor_PART_SELECTION = 2 }; static const char32 *TimeSoundAnalysisEditor_partString (int part) { static const char32 *strings [] = { U"", U"CURSOR", U"SELECTION" }; return strings [part]; } static const char32 *TimeSoundAnalysisEditor_partString_locative (int part) { static const char32 *strings [] = { U"", U"at CURSOR", U"in SELECTION" }; return strings [part]; } static int makeQueriable (TimeSoundAnalysisEditor me, int allowCursor, double *tmin, double *tmax) { if (my d_endWindow - my d_startWindow > my p_longestAnalysis) { Melder_throw (U"Window too long to show analyses. Zoom in to at most ", Melder_half (my p_longestAnalysis), U" seconds " U"or set the \"longest analysis\" to at least ", Melder_half (my d_endWindow - my d_startWindow), U" seconds."); } if (my d_startSelection == my d_endSelection) { if (allowCursor) { *tmin = *tmax = my d_startSelection; return TimeSoundAnalysisEditor_PART_CURSOR; } else { Melder_throw (U"Make a selection first."); } } else if (my d_startSelection < my d_startWindow || my d_endSelection > my d_endWindow) { Melder_throw (U"Command ambiguous: a part of the selection (", my d_startSelection, U", ", my d_endSelection, U") " U"is outside of the window (", my d_startWindow, U", ", my d_endWindow, U"). " U"Either zoom or re-select."); } *tmin = my d_startSelection; *tmax = my d_endSelection; return TimeSoundAnalysisEditor_PART_SELECTION; } static void menu_cb_logSettings (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); EDITOR_FORM (U"Log settings", U"Log files") OPTIONMENU (U"Write log 1 to", 3) OPTION (U"Log file only") OPTION (U"Info window only") OPTION (U"Log file and Info window") LABEL (U"", U"Log file 1:") TEXTFIELD (U"Log file 1", my default_log1_fileName ()) LABEL (U"", U"Log 1 format:") TEXTFIELD (U"Log 1 format", my default_log1_format ()) OPTIONMENU (U"Write log 2 to", 3) OPTION (U"Log file only") OPTION (U"Info window only") OPTION (U"Log file and Info window") LABEL (U"", U"Log file 2:") TEXTFIELD (U"Log file 2", my default_log2_fileName ()) LABEL (U"", U"Log 2 format:") TEXTFIELD (U"Log 2 format", my default_log2_format ()) LABEL (U"", U"Log script 3:") TEXTFIELD (U"Log script 3", my default_logScript3 ()) LABEL (U"", U"Log script 4:") TEXTFIELD (U"Log script 4", my default_logScript4 ()) EDITOR_OK SET_INTEGER (U"Write log 1 to", my p_log1_toLogFile + 2 * my p_log1_toInfoWindow) SET_STRING (U"Log file 1", my p_log1_fileName) SET_STRING (U"Log 1 format", my p_log1_format) SET_INTEGER (U"Write log 2 to", my p_log2_toLogFile + 2 * my p_log2_toInfoWindow) SET_STRING (U"Log file 2", my p_log2_fileName) SET_STRING (U"Log 2 format", my p_log2_format) SET_STRING (U"Log script 3", my p_logScript3) SET_STRING (U"Log script 4", my p_logScript4) EDITOR_DO my pref_log1_toLogFile () = my p_log1_toLogFile = (GET_INTEGER (U"Write log 1 to") & 1) != 0; my pref_log1_toInfoWindow () = my p_log1_toInfoWindow = (GET_INTEGER (U"Write log 1 to") & 2) != 0; pref_str32cpy2 (my pref_log1_fileName (), my p_log1_fileName, GET_STRING (U"Log file 1")); pref_str32cpy2 (my pref_log1_format (), my p_log1_format, GET_STRING (U"Log 1 format")); my pref_log2_toLogFile () = my p_log2_toLogFile = (GET_INTEGER (U"Write log 2 to") & 1) != 0; my pref_log2_toInfoWindow () = my p_log2_toInfoWindow = (GET_INTEGER (U"Write log 2 to") & 2) != 0; pref_str32cpy2 (my pref_log2_fileName (), my p_log2_fileName, GET_STRING (U"Log file 2")); pref_str32cpy2 (my pref_log2_format (), my p_log2_format, GET_STRING (U"Log 2 format")); pref_str32cpy2 (my pref_logScript3 (), my p_logScript3, GET_STRING (U"Log script 3")); pref_str32cpy2 (my pref_logScript4 (), my p_logScript4, GET_STRING (U"Log script 4")); EDITOR_END } static void menu_cb_deleteLogFile1 (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); structMelderFile file = { 0 }; Melder_pathToFile (my p_log1_fileName, & file); MelderFile_delete (& file); } static void menu_cb_deleteLogFile2 (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); structMelderFile file = { 0 }; Melder_pathToFile (my p_log2_fileName, & file); MelderFile_delete (& file); } static void do_log (TimeSoundAnalysisEditor me, int which) { char32 format [Preferences_STRING_BUFFER_SIZE], *p; double tmin, tmax; int part = makeQueriable (me, true, & tmin, & tmax); str32cpy (format, which == 1 ? my p_log1_format : my p_log2_format); for (p = format; *p != U'\0'; p ++) if (*p == U'\'') { /* * Found a left quote. Search for a matching right quote. */ char32 *q = p + 1, varName [300], *r, *s, *colon; int precision = -1; double value = NUMundefined; const char32 *stringValue = NULL; while (*q != U'\0' && *q != U'\'') q ++; if (*q == U'\0') break; /* No matching right quote: done with this line. */ if (q - p == 1) continue; /* Ignore empty variable names. */ /* * Found a right quote. Get potential variable name. */ for (r = p + 1, s = varName; q - r > 0; r ++, s ++) *s = *r; *s = U'\0'; /* Trailing null byte. */ colon = str32chr (varName, U':'); if (colon) { precision = Melder_atoi (colon + 1); *colon = U'\0'; } if (str32equ (varName, U"time")) { value = 0.5 * (tmin + tmax); } else if (str32equ (varName, U"t1")) { value = tmin; } else if (str32equ (varName, U"t2")) { value = tmax; } else if (str32equ (varName, U"dur")) { value = tmax - tmin; } else if (str32equ (varName, U"freq")) { value = my d_spectrogram_cursor; } else if (str32equ (varName, U"tab$")) { stringValue = U"\t"; } else if (str32equ (varName, U"editor$")) { stringValue = my name; } else if (str32equ (varName, U"f0")) { if (! my p_pitch_show) Melder_throw (U"No pitch contour is visible.\nFirst choose \"Show pitch\" from the Pitch menu."); if (! my d_pitch) { Melder_throw (theMessage_Cannot_compute_pitch); } if (part == TimeSoundAnalysisEditor_PART_CURSOR) { value = Pitch_getValueAtTime (my d_pitch.get(), tmin, my p_pitch_unit, 1); } else { value = Pitch_getMean (my d_pitch.get(), tmin, tmax, my p_pitch_unit); } } else if (varName [0] == 'f' && varName [1] >= '1' && varName [1] <= '5' && varName [2] == '\0') { if (! my p_formant_show) Melder_throw (U"No formant contour is visible.\nFirst choose \"Show formants\" from the Formant menu."); if (! my d_formant) { Melder_throw (theMessage_Cannot_compute_formant); } if (part == TimeSoundAnalysisEditor_PART_CURSOR) { value = Formant_getValueAtTime (my d_formant.get(), (int) (varName [1] - U'0'), tmin, 0); } else { value = Formant_getMean (my d_formant.get(), (int) (varName [1] - U'0'), tmin, tmax, 0); } } else if (varName [0] == U'b' && varName [1] >= U'1' && varName [1] <= U'5' && varName [2] == U'\0') { if (! my p_formant_show) Melder_throw (U"No formant contour is visible.\nFirst choose \"Show formants\" from the Formant menu."); if (! my d_formant) { Melder_throw (theMessage_Cannot_compute_formant); } value = Formant_getBandwidthAtTime (my d_formant.get(), (int) (varName [1] - U'0'), 0.5 * (tmin + tmax), 0); } else if (str32equ (varName, U"intensity")) { if (! my p_intensity_show) Melder_throw (U"No intensity contour is visible.\nFirst choose \"Show intensity\" from the Intensity menu."); if (! my d_intensity) { Melder_throw (theMessage_Cannot_compute_intensity); } if (part == TimeSoundAnalysisEditor_PART_CURSOR) { value = Vector_getValueAtX (my d_intensity.get(), tmin, Vector_CHANNEL_1, Vector_VALUE_INTERPOLATION_LINEAR); } else { value = Intensity_getAverage (my d_intensity.get(), tmin, tmax, my p_intensity_averagingMethod); } } else if (str32equ (varName, U"power")) { if (! my p_spectrogram_show) Melder_throw (U"No spectrogram is visible.\nFirst choose \"Show spectrogram\" from the Spectrum menu."); if (! my d_spectrogram) { Melder_throw (theMessage_Cannot_compute_spectrogram); } if (part != TimeSoundAnalysisEditor_PART_CURSOR) Melder_throw (U"Click inside the spectrogram first."); value = Matrix_getValueAtXY (my d_spectrogram.get(), tmin, my d_spectrogram_cursor); } if (NUMdefined (value)) { int varlen = (q - p) - 1, headlen = p - format; char32 formattedNumber [400]; if (precision >= 0) { Melder_sprint (formattedNumber,400, Melder_fixed (value, precision)); } else { Melder_sprint (formattedNumber,400, value); } int arglen = str32len (formattedNumber); static MelderString buffer { 0 }; MelderString_ncopy (& buffer, format, headlen); MelderString_append (& buffer, formattedNumber, p + varlen + 2); str32cpy (format, buffer.string); p += arglen - 1; } else if (stringValue != NULL) { int varlen = (q - p) - 1, headlen = p - format, arglen = str32len (stringValue); static MelderString buffer { 0 }; MelderString_ncopy (& buffer, format, headlen); MelderString_append (& buffer, stringValue, p + varlen + 2); str32cpy (format, buffer.string); p += arglen - 1; } else { p = q - 1; // go to before next quote } } if ((which == 1 && my p_log1_toInfoWindow) || (which == 2 && my p_log2_toInfoWindow)) { MelderInfo_write (format); MelderInfo_close (); } if ((which == 1 && my p_log1_toLogFile) || (which == 2 && my p_log2_toLogFile)) { structMelderFile file = { 0 }; str32cpy (format + str32len (format), U"\n"); Melder_relativePathToFile (which == 1 ? my p_log1_fileName : my p_log2_fileName, & file); MelderFile_appendText (& file, format); } } static void menu_cb_log1 (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); do_log (me, 1); } static void menu_cb_log2 (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); do_log (me, 2); } static void menu_cb_logScript3 (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); DO_RunTheScriptFromAnyAddedEditorCommand (me, my p_logScript3); } static void menu_cb_logScript4 (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); DO_RunTheScriptFromAnyAddedEditorCommand (me, my p_logScript4); } static void menu_cb_showAnalyses (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); EDITOR_FORM (U"Show analyses", 0) BOOLEAN (U"Show spectrogram", my default_spectrogram_show ()) BOOLEAN (U"Show pitch", my default_pitch_show ()) BOOLEAN (U"Show intensity", my default_intensity_show ()) BOOLEAN (U"Show formants", my default_formant_show ()) BOOLEAN (U"Show pulses", my default_pulses_show ()) POSITIVE (U"Longest analysis (s)", my default_longestAnalysis ()) EDITOR_OK SET_INTEGER (U"Show spectrogram", my p_spectrogram_show) SET_INTEGER (U"Show pitch", my p_pitch_show) SET_INTEGER (U"Show intensity", my p_intensity_show) SET_INTEGER (U"Show formants", my p_formant_show) SET_INTEGER (U"Show pulses", my p_pulses_show) SET_REAL (U"Longest analysis", my p_longestAnalysis) EDITOR_DO GuiMenuItem_check (my spectrogramToggle , my pref_spectrogram_show () = my p_spectrogram_show = GET_INTEGER (U"Show spectrogram")); GuiMenuItem_check (my pitchToggle , my pref_pitch_show () = my p_pitch_show = GET_INTEGER (U"Show pitch")); GuiMenuItem_check (my intensityToggle , my pref_intensity_show () = my p_intensity_show = GET_INTEGER (U"Show intensity")); GuiMenuItem_check (my formantToggle , my pref_formant_show () = my p_formant_show = GET_INTEGER (U"Show formants")); GuiMenuItem_check (my pulsesToggle , my pref_pulses_show () = my p_pulses_show = GET_INTEGER (U"Show pulses")); my pref_longestAnalysis () = my p_longestAnalysis = GET_REAL (U"Longest analysis"); FunctionEditor_redraw (me); EDITOR_END } static void menu_cb_timeStepSettings (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); EDITOR_FORM (U"Time step settings", U"Time step settings...") OPTIONMENU_ENUM (U"Time step strategy", kTimeSoundAnalysisEditor_timeStepStrategy, my default_timeStepStrategy ()) LABEL (U"", U"") LABEL (U"", U"If the time step strategy is \"fixed\":") POSITIVE (U"Fixed time step (s)", my default_fixedTimeStep ()) LABEL (U"", U"") LABEL (U"", U"If the time step strategy is \"view-dependent\":") NATURAL (U"Number of time steps per view", my default_numberOfTimeStepsPerView ()) EDITOR_OK SET_ENUM (U"Time step strategy", kTimeSoundAnalysisEditor_timeStepStrategy, my p_timeStepStrategy) SET_REAL (U"Fixed time step", my p_fixedTimeStep) SET_INTEGER (U"Number of time steps per view", my p_numberOfTimeStepsPerView) EDITOR_DO my pref_timeStepStrategy () = my p_timeStepStrategy = GET_ENUM (kTimeSoundAnalysisEditor_timeStepStrategy, U"Time step strategy"); my pref_fixedTimeStep () = my p_fixedTimeStep = GET_REAL (U"Fixed time step"); my pref_numberOfTimeStepsPerView () = my p_numberOfTimeStepsPerView = GET_INTEGER (U"Number of time steps per view"); my d_pitch. reset(); my d_formant. reset(); my d_intensity. reset(); my d_pulses. reset(); FunctionEditor_redraw (me); EDITOR_END } /***** SPECTROGRAM MENU *****/ static void menu_cb_showSpectrogram (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); my pref_spectrogram_show () = my p_spectrogram_show = ! my p_spectrogram_show; GuiMenuItem_check (my spectrogramToggle, my p_spectrogram_show); // in case we're called from a script FunctionEditor_redraw (me); } static void menu_cb_spectrogramSettings (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); EDITOR_FORM (U"Spectrogram settings", U"Intro 3.2. Configuring the spectrogram") REAL (U"left View range (Hz)", my default_spectrogram_viewFrom ()) POSITIVE (U"right View range (Hz)", my default_spectrogram_viewTo ()) POSITIVE (U"Window length (s)", my default_spectrogram_windowLength ()) POSITIVE (U"Dynamic range (dB)", my default_spectrogram_dynamicRange ()) LABEL (U"note1", U"") LABEL (U"note2", U"") EDITOR_OK SET_REAL (U"left View range", my p_spectrogram_viewFrom) SET_REAL (U"right View range", my p_spectrogram_viewTo) SET_REAL (U"Window length", my p_spectrogram_windowLength) SET_REAL (U"Dynamic range", my p_spectrogram_dynamicRange) if (my p_spectrogram_timeSteps != Melder_atof (my default_spectrogram_timeSteps ()) || my p_spectrogram_frequencySteps != Melder_atof (my default_spectrogram_frequencySteps ()) || my p_spectrogram_method != my default_spectrogram_method () || my p_spectrogram_windowShape != my default_spectrogram_windowShape () || my p_spectrogram_maximum != Melder_atof (my default_spectrogram_maximum ()) || my p_spectrogram_autoscaling != my default_spectrogram_autoscaling ()|| my p_spectrogram_preemphasis != Melder_atof (my default_spectrogram_preemphasis ()) || my p_spectrogram_dynamicCompression != Melder_atof (my default_spectrogram_dynamicCompression ())) { SET_STRING (U"note1", U"Warning: you have non-standard \"advanced settings\".") } else { SET_STRING (U"note1", U"(all of your \"advanced settings\" have their standard values)") } if (my p_timeStepStrategy != my default_timeStepStrategy ()) { SET_STRING (U"note2", U"Warning: you have a non-standard \"time step strategy\".") } else { SET_STRING (U"note2", U"(your \"time step strategy\" has its standard value: automatic)") } EDITOR_DO my pref_spectrogram_viewFrom () = my p_spectrogram_viewFrom = GET_REAL (U"left View range"); my pref_spectrogram_viewTo () = my p_spectrogram_viewTo = GET_REAL (U"right View range"); my pref_spectrogram_windowLength () = my p_spectrogram_windowLength = GET_REAL (U"Window length"); my pref_spectrogram_dynamicRange () = my p_spectrogram_dynamicRange = GET_REAL (U"Dynamic range"); my d_spectrogram. reset(); FunctionEditor_redraw (me); EDITOR_END } static void menu_cb_advancedSpectrogramSettings (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); EDITOR_FORM (U"Advanced spectrogram settings", U"Advanced spectrogram settings...") LABEL (U"", U"Time and frequency resolutions:") NATURAL (U"Number of time steps", my default_spectrogram_timeSteps ()) NATURAL (U"Number of frequency steps", my default_spectrogram_frequencySteps ()) LABEL (U"", U"Spectrogram analysis settings:") OPTIONMENU_ENUM (U"Method", kSound_to_Spectrogram_method, my default_spectrogram_method ()) OPTIONMENU_ENUM (U"Window shape", kSound_to_Spectrogram_windowShape, my default_spectrogram_windowShape ()) LABEL (U"", U"Spectrogram view settings:") BOOLEAN (U"Autoscaling", my default_spectrogram_autoscaling ()) REAL (U"Maximum (dB/Hz)", my default_spectrogram_maximum ()) REAL (U"Pre-emphasis (dB/oct)", my default_spectrogram_preemphasis ()) REAL (U"Dynamic compression (0-1)", my default_spectrogram_dynamicCompression ()) EDITOR_OK SET_INTEGER (U"Number of time steps", my p_spectrogram_timeSteps) SET_INTEGER (U"Number of frequency steps", my p_spectrogram_frequencySteps) SET_ENUM (U"Method", kSound_to_Spectrogram_method, my p_spectrogram_method) SET_ENUM (U"Window shape", kSound_to_Spectrogram_windowShape, my p_spectrogram_windowShape) SET_INTEGER (U"Autoscaling", my p_spectrogram_autoscaling) SET_REAL (U"Maximum", my p_spectrogram_maximum) SET_REAL (U"Pre-emphasis", my p_spectrogram_preemphasis) SET_REAL (U"Dynamic compression", my p_spectrogram_dynamicCompression) EDITOR_DO my pref_spectrogram_timeSteps () = my p_spectrogram_timeSteps = GET_INTEGER (U"Number of time steps"); my pref_spectrogram_frequencySteps () = my p_spectrogram_frequencySteps = GET_INTEGER (U"Number of frequency steps"); my pref_spectrogram_method () = my p_spectrogram_method = GET_ENUM (kSound_to_Spectrogram_method, U"Method"); my pref_spectrogram_windowShape () = my p_spectrogram_windowShape = GET_ENUM (kSound_to_Spectrogram_windowShape, U"Window shape"); my pref_spectrogram_autoscaling () = my p_spectrogram_autoscaling = GET_INTEGER (U"Autoscaling"); my pref_spectrogram_maximum () = my p_spectrogram_maximum = GET_REAL (U"Maximum"); my pref_spectrogram_preemphasis () = my p_spectrogram_preemphasis = GET_REAL (U"Pre-emphasis"); my pref_spectrogram_dynamicCompression () = my p_spectrogram_dynamicCompression = GET_REAL (U"Dynamic compression"); my d_spectrogram. reset(); FunctionEditor_redraw (me); EDITOR_END } static void menu_cb_getFrequency (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); Melder_informationReal (my d_spectrogram_cursor, U"Hz"); } static void menu_cb_getSpectralPowerAtCursorCross (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); double tmin, tmax; int part = makeQueriable (me, true, & tmin, & tmax); if (! my p_spectrogram_show) Melder_throw (U"No spectrogram is visible.\nFirst choose \"Show spectrogram\" from the Spectrum menu."); if (! my d_spectrogram) { TimeSoundAnalysisEditor_computeSpectrogram (me); if (! my d_spectrogram) Melder_throw (theMessage_Cannot_compute_spectrogram); } if (part != TimeSoundAnalysisEditor_PART_CURSOR) Melder_throw (U"Click inside the spectrogram first."); MelderInfo_open (); MelderInfo_write (Matrix_getValueAtXY (my d_spectrogram.get(), tmin, my d_spectrogram_cursor), U" Pa2/Hz (at time = ", tmin, U" seconds and frequency = ", my d_spectrogram_cursor, U" Hz)"); MelderInfo_close (); } static void menu_cb_moveFrequencyCursorTo (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); if (! my p_spectrogram_show) Melder_throw (U"No spectrogram is visible.\nFirst choose \"Show spectrogram\" from the Spectrum menu."); EDITOR_FORM (U"Move frequency cursor to", 0) REAL (U"Frequency (Hz)", U"0.0") EDITOR_OK SET_REAL (U"Frequency", my d_spectrogram_cursor) EDITOR_DO double frequency = GET_REAL (U"Frequency"); my d_spectrogram_cursor = frequency; FunctionEditor_redraw (me); EDITOR_END } static autoSound extractSound (TimeSoundAnalysisEditor me, double tmin, double tmax) { autoSound sound; if (my d_longSound.data) { if (tmin < my d_longSound.data -> xmin) tmin = my d_longSound.data -> xmin; if (tmax > my d_longSound.data -> xmax) tmax = my d_longSound.data -> xmax; sound = LongSound_extractPart (my d_longSound.data, tmin, tmax, true); } else if (my d_sound.data) { if (tmin < my d_sound.data -> xmin) tmin = my d_sound.data -> xmin; if (tmax > my d_sound.data -> xmax) tmax = my d_sound.data -> xmax; sound = Sound_extractPart (my d_sound.data, tmin, tmax, kSound_windowShape_RECTANGULAR, 1.0, true); } return sound; } static void menu_cb_extractVisibleSpectrogram (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); if (! my p_spectrogram_show) Melder_throw (U"No spectrogram is visible.\nFirst choose \"Show spectrogram\" from the Spectrum menu."); if (! my d_spectrogram) { TimeSoundAnalysisEditor_computeSpectrogram (me); if (! my d_spectrogram) Melder_throw (theMessage_Cannot_compute_spectrogram); } autoSpectrogram publish = Data_copy (my d_spectrogram.get()); Editor_broadcastPublication (me, publish.transfer()); } static void menu_cb_viewSpectralSlice (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); double start = my d_startSelection == my d_endSelection ? my p_spectrogram_windowShape == kSound_to_Spectrogram_windowShape_GAUSSIAN ? my d_startSelection - my p_spectrogram_windowLength : my d_startSelection - my p_spectrogram_windowLength / 2 : my d_startSelection; double finish = my d_startSelection == my d_endSelection ? my p_spectrogram_windowShape == kSound_to_Spectrogram_windowShape_GAUSSIAN ? my d_endSelection + my p_spectrogram_windowLength : my d_endSelection + my p_spectrogram_windowLength / 2 : my d_endSelection; autoSound sound = extractSound (me, start, finish); Sound_multiplyByWindow (sound.peek(), my p_spectrogram_windowShape == kSound_to_Spectrogram_windowShape_SQUARE ? kSound_windowShape_RECTANGULAR : my p_spectrogram_windowShape == kSound_to_Spectrogram_windowShape_HAMMING ? kSound_windowShape_HAMMING : my p_spectrogram_windowShape == kSound_to_Spectrogram_windowShape_BARTLETT ? kSound_windowShape_TRIANGULAR : my p_spectrogram_windowShape == kSound_to_Spectrogram_windowShape_WELCH ? kSound_windowShape_PARABOLIC : my p_spectrogram_windowShape == kSound_to_Spectrogram_windowShape_HANNING ? kSound_windowShape_HANNING : my p_spectrogram_windowShape == kSound_to_Spectrogram_windowShape_GAUSSIAN ? kSound_windowShape_GAUSSIAN_2 : kSound_windowShape_RECTANGULAR); autoSpectrum publish = Sound_to_Spectrum (sound.peek(), true); Thing_setName (publish.peek(), Melder_cat (( my data == nullptr ? U"untitled" : ((Daata) my data) -> name ), U"_", Melder_fixed (0.5 * (my d_startSelection + my d_endSelection), 3))); Editor_broadcastPublication (me, publish.transfer()); } static void menu_cb_paintVisibleSpectrogram (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); EDITOR_FORM (U"Paint visible spectrogram", 0) my v_form_pictureWindow (cmd); my v_form_pictureMargins (cmd); my v_form_pictureSelection (cmd); BOOLEAN (U"Garnish", 1); EDITOR_OK my v_ok_pictureWindow (cmd); my v_ok_pictureMargins (cmd); my v_ok_pictureSelection (cmd); SET_INTEGER (U"Garnish", my p_spectrogram_picture_garnish); EDITOR_DO my v_do_pictureWindow (cmd); my v_do_pictureMargins (cmd); my v_do_pictureSelection (cmd); my pref_spectrogram_picture_garnish () = my p_spectrogram_picture_garnish = GET_INTEGER (U"Garnish"); if (! my p_spectrogram_show) Melder_throw (U"No spectrogram is visible.\nFirst choose \"Show spectrogram\" from the Spectrum menu."); if (! my d_spectrogram) { TimeSoundAnalysisEditor_computeSpectrogram (me); if (! my d_spectrogram) Melder_throw (theMessage_Cannot_compute_spectrogram); } Editor_openPraatPicture (me); Spectrogram_paint (my d_spectrogram.get(), my pictureGraphics, my d_startWindow, my d_endWindow, my p_spectrogram_viewFrom, my p_spectrogram_viewTo, my p_spectrogram_maximum, my p_spectrogram_autoscaling, my p_spectrogram_dynamicRange, my p_spectrogram_preemphasis, my p_spectrogram_dynamicCompression, my p_spectrogram_picture_garnish); FunctionEditor_garnish (me); Editor_closePraatPicture (me); EDITOR_END } /***** PITCH MENU *****/ static void menu_cb_showPitch (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); my pref_pitch_show () = my p_pitch_show = ! my p_pitch_show; GuiMenuItem_check (my pitchToggle, my p_pitch_show); // in case we're called from a script FunctionEditor_redraw (me); } static void menu_cb_pitchSettings (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); EDITOR_FORM (U"Pitch settings", U"Intro 4.2. Configuring the pitch contour") POSITIVE (U"left Pitch range (Hz)", my default_pitch_floor ()) POSITIVE (U"right Pitch range (Hz)", my default_pitch_ceiling ()) OPTIONMENU_ENUM (U"Unit", kPitch_unit, my default_pitch_unit ()) LABEL (U"opt1", U"The autocorrelation method optimizes for intonation research;") LABEL (U"opt2", U"and the cross-correlation method optimizes for voice research:") RADIO_ENUM (U"Analysis method", kTimeSoundAnalysisEditor_pitch_analysisMethod, my default_pitch_method ()) OPTIONMENU_ENUM (U"Drawing method", kTimeSoundAnalysisEditor_pitch_drawingMethod, my default_pitch_drawingMethod ()) LABEL (U"note1", U"") LABEL (U"note2", U"") EDITOR_OK SET_REAL (U"left Pitch range", my p_pitch_floor) SET_REAL (U"right Pitch range", my p_pitch_ceiling) SET_ENUM (U"Unit", kPitch_unit, my p_pitch_unit) SET_ENUM (U"Analysis method", kTimeSoundAnalysisEditor_pitch_analysisMethod, my p_pitch_method) SET_ENUM (U"Drawing method", kTimeSoundAnalysisEditor_pitch_drawingMethod, my p_pitch_drawingMethod) if (my p_pitch_viewFrom != Melder_atof (my default_pitch_viewFrom ()) || my p_pitch_viewTo != Melder_atof (my default_pitch_viewTo ()) || my p_pitch_veryAccurate != my default_pitch_veryAccurate () || my p_pitch_maximumNumberOfCandidates != Melder_atof (my default_pitch_maximumNumberOfCandidates ()) || my p_pitch_silenceThreshold != Melder_atof (my default_pitch_silenceThreshold ()) || my p_pitch_voicingThreshold != Melder_atof (my default_pitch_voicingThreshold ()) || my p_pitch_octaveCost != Melder_atof (my default_pitch_octaveCost ()) || my p_pitch_octaveJumpCost != Melder_atof (my default_pitch_octaveJumpCost ()) || my p_pitch_voicedUnvoicedCost != Melder_atof (my default_pitch_voicedUnvoicedCost ())) { SET_STRING (U"note1", U"Warning: you have some non-standard \"advanced settings\".") } else { SET_STRING (U"note1", U"(all of your \"advanced settings\" have their standard values)") } if (my p_timeStepStrategy != my default_timeStepStrategy ()) { SET_STRING (U"note2", U"Warning: you have a non-standard \"time step strategy\".") } else { SET_STRING (U"note2", U"(your \"time step strategy\" has its standard value: automatic)") } EDITOR_DO my pref_pitch_floor () = my p_pitch_floor = GET_REAL (U"left Pitch range"); my pref_pitch_ceiling () = my p_pitch_ceiling = GET_REAL (U"right Pitch range"); my pref_pitch_unit () = my p_pitch_unit = GET_ENUM (kPitch_unit, U"Unit"); my pref_pitch_method () = my p_pitch_method = GET_ENUM (kTimeSoundAnalysisEditor_pitch_analysisMethod, U"Analysis method"); my pref_pitch_drawingMethod () = my p_pitch_drawingMethod = GET_ENUM (kTimeSoundAnalysisEditor_pitch_drawingMethod, U"Drawing method"); my d_pitch. reset(); my d_intensity. reset(); my d_pulses. reset(); FunctionEditor_redraw (me); EDITOR_END } static void menu_cb_advancedPitchSettings (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); EDITOR_FORM (U"Advanced pitch settings", U"Advanced pitch settings...") LABEL (U"", U"Make view range different from analysis range:") REAL (U"left View range (units)", my default_pitch_viewFrom ()) REAL (U"right View range (units)", my default_pitch_viewTo ()) LABEL (U"", U"Analysis settings:") BOOLEAN (U"Very accurate", 0) NATURAL (U"Max. number of candidates", my default_pitch_maximumNumberOfCandidates ()) REAL (U"Silence threshold", my default_pitch_silenceThreshold ()) REAL (U"Voicing threshold", my default_pitch_voicingThreshold ()) REAL (U"Octave cost", my default_pitch_octaveCost ()) REAL (U"Octave-jump cost", my default_pitch_octaveJumpCost ()) REAL (U"Voiced / unvoiced cost", my default_pitch_voicedUnvoicedCost ()) EDITOR_OK SET_REAL (U"left View range", my p_pitch_viewFrom) SET_REAL (U"right View range", my p_pitch_viewTo) SET_INTEGER (U"Very accurate", my p_pitch_veryAccurate) SET_INTEGER (U"Max. number of candidates", my p_pitch_maximumNumberOfCandidates) SET_REAL (U"Silence threshold", my p_pitch_silenceThreshold) SET_REAL (U"Voicing threshold", my p_pitch_voicingThreshold) SET_REAL (U"Octave cost", my p_pitch_octaveCost) SET_REAL (U"Octave-jump cost", my p_pitch_octaveJumpCost) SET_REAL (U"Voiced / unvoiced cost", my p_pitch_voicedUnvoicedCost) EDITOR_DO long maxnCandidates = GET_INTEGER (U"Max. number of candidates"); if (maxnCandidates < 2) Melder_throw (U"Maximum number of candidates must be greater than 1."); my pref_pitch_viewFrom () = my p_pitch_viewFrom = GET_REAL (U"left View range"); my pref_pitch_viewTo () = my p_pitch_viewTo = GET_REAL (U"right View range"); my pref_pitch_veryAccurate () = my p_pitch_veryAccurate = GET_INTEGER (U"Very accurate"); my pref_pitch_maximumNumberOfCandidates () = my p_pitch_maximumNumberOfCandidates = GET_INTEGER (U"Max. number of candidates"); my pref_pitch_silenceThreshold () = my p_pitch_silenceThreshold = GET_REAL (U"Silence threshold"); my pref_pitch_voicingThreshold () = my p_pitch_voicingThreshold = GET_REAL (U"Voicing threshold"); my pref_pitch_octaveCost () = my p_pitch_octaveCost = GET_REAL (U"Octave cost"); my pref_pitch_octaveJumpCost () = my p_pitch_octaveJumpCost = GET_REAL (U"Octave-jump cost"); my pref_pitch_voicedUnvoicedCost () = my p_pitch_voicedUnvoicedCost = GET_REAL (U"Voiced / unvoiced cost"); my d_pitch. reset(); my d_intensity. reset(); my d_pulses. reset(); FunctionEditor_redraw (me); EDITOR_END } static void menu_cb_pitchListing (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); double tmin, tmax; int part = makeQueriable (me, true, & tmin, & tmax); if (! my p_pitch_show) Melder_throw (U"No pitch contour is visible.\nFirst choose \"Show pitch\" from the Pitch menu."); if (! my d_pitch) { TimeSoundAnalysisEditor_computePitch (me); if (! my d_pitch) Melder_throw (theMessage_Cannot_compute_pitch); } MelderInfo_open (); MelderInfo_writeLine (U"Time_s F0_", Function_getUnitText (my d_pitch.peek(), Pitch_LEVEL_FREQUENCY, my p_pitch_unit, Function_UNIT_TEXT_SHORT)); if (part == TimeSoundAnalysisEditor_PART_CURSOR) { double f0 = Pitch_getValueAtTime (my d_pitch.get(), tmin, my p_pitch_unit, true); f0 = Function_convertToNonlogarithmic (my d_pitch.get(), f0, Pitch_LEVEL_FREQUENCY, my p_pitch_unit); MelderInfo_writeLine (Melder_fixed (tmin, 6), U" ", Melder_fixed (f0, 6)); } else { long i, i1, i2; Sampled_getWindowSamples (my d_pitch.get(), tmin, tmax, & i1, & i2); for (i = i1; i <= i2; i ++) { double t = Sampled_indexToX (my d_pitch.get(), i); double f0 = Sampled_getValueAtSample (my d_pitch.get(), i, Pitch_LEVEL_FREQUENCY, my p_pitch_unit); f0 = Function_convertToNonlogarithmic (my d_pitch.get(), f0, Pitch_LEVEL_FREQUENCY, my p_pitch_unit); MelderInfo_writeLine (Melder_fixed (t, 6), U" ", Melder_fixed (f0, 6)); } } MelderInfo_close (); } static void menu_cb_getPitch (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); double tmin, tmax; int part = makeQueriable (me, true, & tmin, & tmax); if (! my p_pitch_show) Melder_throw (U"No pitch contour is visible.\nFirst choose \"Show pitch\" from the Pitch menu."); if (! my d_pitch) { TimeSoundAnalysisEditor_computePitch (me); if (! my d_pitch) Melder_throw (theMessage_Cannot_compute_pitch); } if (part == TimeSoundAnalysisEditor_PART_CURSOR) { double f0 = Pitch_getValueAtTime (my d_pitch.get(), tmin, my p_pitch_unit, true); f0 = Function_convertToNonlogarithmic (my d_pitch.get(), f0, Pitch_LEVEL_FREQUENCY, my p_pitch_unit); Melder_information (f0, U" ", Function_getUnitText (my d_pitch.get(), Pitch_LEVEL_FREQUENCY, my p_pitch_unit, 0), U" (interpolated pitch at CURSOR)"); } else { double f0 = Pitch_getMean (my d_pitch.get(), tmin, tmax, my p_pitch_unit); f0 = Function_convertToNonlogarithmic (my d_pitch.get(), f0, Pitch_LEVEL_FREQUENCY, my p_pitch_unit); Melder_information (f0, U" ", Function_getUnitText (my d_pitch.get(), Pitch_LEVEL_FREQUENCY, my p_pitch_unit, 0), U" (mean pitch ", TimeSoundAnalysisEditor_partString_locative (part), U")"); } } static void menu_cb_getMinimumPitch (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); double tmin, tmax, f0; int part = makeQueriable (me, false, & tmin, & tmax); if (! my p_pitch_show) Melder_throw (U"No pitch contour is visible.\nFirst choose \"Show pitch\" from the Pitch menu."); if (! my d_pitch) { TimeSoundAnalysisEditor_computePitch (me); if (! my d_pitch) Melder_throw (theMessage_Cannot_compute_pitch); } f0 = Pitch_getMinimum (my d_pitch.get(), tmin, tmax, my p_pitch_unit, true); f0 = Function_convertToNonlogarithmic (my d_pitch.get(), f0, Pitch_LEVEL_FREQUENCY, my p_pitch_unit); Melder_information (f0, U" ", Function_getUnitText (my d_pitch.get(), Pitch_LEVEL_FREQUENCY, my p_pitch_unit, 0), U" (minimum pitch ", TimeSoundAnalysisEditor_partString_locative (part), U")"); } static void menu_cb_getMaximumPitch (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); double tmin, tmax, f0; int part = makeQueriable (me, false, & tmin, & tmax); if (! my p_pitch_show) Melder_throw (U"No pitch contour is visible.\nFirst choose \"Show pitch\" from the Pitch menu."); if (! my d_pitch) { TimeSoundAnalysisEditor_computePitch (me); if (! my d_pitch) Melder_throw (theMessage_Cannot_compute_pitch); // BUG } f0 = Pitch_getMaximum (my d_pitch.get(), tmin, tmax, my p_pitch_unit, true); f0 = Function_convertToNonlogarithmic (my d_pitch.get(), f0, Pitch_LEVEL_FREQUENCY, my p_pitch_unit); Melder_information (f0, U" ", Function_getUnitText (my d_pitch.get(), Pitch_LEVEL_FREQUENCY, my p_pitch_unit, 0), U" (maximum pitch ", TimeSoundAnalysisEditor_partString_locative (part), U")"); } static void menu_cb_moveCursorToMinimumPitch (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); if (! my p_pitch_show) Melder_throw (U"No pitch contour is visible.\nFirst choose \"Show pitch\" from the View menu."); if (! my d_pitch) { TimeSoundAnalysisEditor_computePitch (me); if (! my d_pitch) Melder_throw (theMessage_Cannot_compute_pitch); } if (my d_startSelection == my d_endSelection) { Melder_throw (U"Empty selection."); } else { double time; Pitch_getMinimumAndTime (my d_pitch.get(), my d_startSelection, my d_endSelection, my p_pitch_unit, 1, NULL, & time); if (! NUMdefined (time)) Melder_throw (U"Selection is voiceless."); my d_startSelection = my d_endSelection = time; FunctionEditor_marksChanged (me, true); } } static void menu_cb_moveCursorToMaximumPitch (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); if (! my p_pitch_show) Melder_throw (U"No pitch contour is visible.\nFirst choose \"Show pitch\" from the View menu."); if (! my d_pitch) { TimeSoundAnalysisEditor_computePitch (me); if (! my d_pitch) Melder_throw (theMessage_Cannot_compute_pitch); } if (my d_startSelection == my d_endSelection) { Melder_throw (U"Empty selection."); } else { double time; Pitch_getMaximumAndTime (my d_pitch.get(), my d_startSelection, my d_endSelection, my p_pitch_unit, 1, NULL, & time); if (! NUMdefined (time)) Melder_throw (U"Selection is voiceless."); my d_startSelection = my d_endSelection = time; FunctionEditor_marksChanged (me, true); } } static void menu_cb_extractVisiblePitchContour (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); if (! my p_pitch_show) Melder_throw (U"No pitch contour is visible.\nFirst choose \"Show pitch\" from the Pitch menu."); if (! my d_pitch) { TimeSoundAnalysisEditor_computePitch (me); if (! my d_pitch) Melder_throw (theMessage_Cannot_compute_pitch); } autoPitch publish = Data_copy (my d_pitch.get()); Editor_broadcastPublication (me, publish.transfer()); } static void menu_cb_drawVisiblePitchContour (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); EDITOR_FORM (U"Draw visible pitch contour", 0) my v_form_pictureWindow (cmd); LABEL (U"", U"Pitch:") BOOLEAN (U"Speckle", 0); my v_form_pictureMargins (cmd); my v_form_pictureSelection (cmd); BOOLEAN (U"Garnish", 1); EDITOR_OK my v_ok_pictureWindow (cmd); SET_INTEGER (U"Speckle", my p_pitch_picture_speckle); my v_ok_pictureMargins (cmd); my v_ok_pictureSelection (cmd); SET_INTEGER (U"Garnish", my p_pitch_picture_garnish); EDITOR_DO my v_do_pictureWindow (cmd); my pref_pitch_picture_speckle () = my p_pitch_picture_speckle = GET_INTEGER (U"Speckle"); my v_do_pictureMargins (cmd); my v_do_pictureSelection (cmd); my pref_pitch_picture_garnish () = my p_pitch_picture_garnish = GET_INTEGER (U"Garnish"); if (! my p_pitch_show) Melder_throw (U"No pitch contour is visible.\nFirst choose \"Show pitch\" from the Pitch menu."); if (! my d_pitch) { TimeSoundAnalysisEditor_computePitch (me); if (! my d_pitch) Melder_throw (theMessage_Cannot_compute_pitch); } Editor_openPraatPicture (me); double pitchFloor_hidden = Function_convertStandardToSpecialUnit (my d_pitch.get(), my p_pitch_floor, Pitch_LEVEL_FREQUENCY, my p_pitch_unit); double pitchCeiling_hidden = Function_convertStandardToSpecialUnit (my d_pitch.get(), my p_pitch_ceiling, Pitch_LEVEL_FREQUENCY, my p_pitch_unit); double pitchFloor_overt = Function_convertToNonlogarithmic (my d_pitch.get(), pitchFloor_hidden, Pitch_LEVEL_FREQUENCY, my p_pitch_unit); double pitchCeiling_overt = Function_convertToNonlogarithmic (my d_pitch.get(), pitchCeiling_hidden, Pitch_LEVEL_FREQUENCY, my p_pitch_unit); double pitchViewFrom_overt = my p_pitch_viewFrom < my p_pitch_viewTo ? my p_pitch_viewFrom : pitchFloor_overt; double pitchViewTo_overt = my p_pitch_viewFrom < my p_pitch_viewTo ? my p_pitch_viewTo : pitchCeiling_overt; Pitch_draw (my d_pitch.get(), my pictureGraphics, my d_startWindow, my d_endWindow, pitchViewFrom_overt, pitchViewTo_overt, my p_pitch_picture_garnish, my p_pitch_picture_speckle, my p_pitch_unit); FunctionEditor_garnish (me); Editor_closePraatPicture (me); EDITOR_END } /***** INTENSITY MENU *****/ static void menu_cb_showIntensity (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); my pref_intensity_show () = my p_intensity_show = ! my p_intensity_show; GuiMenuItem_check (my intensityToggle, my p_intensity_show); // in case we're called from a script FunctionEditor_redraw (me); } static void menu_cb_intensitySettings (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); EDITOR_FORM (U"Intensity settings", U"Intro 6.2. Configuring the intensity contour") REAL (U"left View range (dB)", my default_intensity_viewFrom ()) REAL (U"right View range (dB)", my default_intensity_viewTo ()) RADIO_ENUM (U"Averaging method", kTimeSoundAnalysisEditor_intensity_averagingMethod, my default_intensity_averagingMethod ()) BOOLEAN (U"Subtract mean pressure", my default_intensity_subtractMeanPressure ()) LABEL (U"", U"Note: the pitch floor is taken from the pitch settings.") LABEL (U"note2", U"") EDITOR_OK SET_REAL (U"left View range", my p_intensity_viewFrom) SET_REAL (U"right View range", my p_intensity_viewTo) SET_ENUM (U"Averaging method", kTimeSoundAnalysisEditor_intensity_averagingMethod, my p_intensity_averagingMethod) SET_INTEGER (U"Subtract mean pressure", my p_intensity_subtractMeanPressure) if (my p_timeStepStrategy != my default_timeStepStrategy ()) { SET_STRING (U"note2", U"Warning: you have a non-standard \"time step strategy\".") } else { SET_STRING (U"note2", U"(your \"time step strategy\" has its standard value: automatic)") } EDITOR_DO my pref_intensity_viewFrom () = my p_intensity_viewFrom = GET_REAL (U"left View range"); my pref_intensity_viewTo () = my p_intensity_viewTo = GET_REAL (U"right View range"); my pref_intensity_averagingMethod () = my p_intensity_averagingMethod = GET_ENUM (kTimeSoundAnalysisEditor_intensity_averagingMethod, U"Averaging method"); my pref_intensity_subtractMeanPressure () = my p_intensity_subtractMeanPressure = GET_INTEGER (U"Subtract mean pressure"); my d_intensity. reset(); FunctionEditor_redraw (me); EDITOR_END } static void menu_cb_extractVisibleIntensityContour (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); if (! my p_intensity_show) Melder_throw (U"No intensity contour is visible.\nFirst choose \"Show intensity\" from the Intensity menu."); if (! my d_intensity) { TimeSoundAnalysisEditor_computeIntensity (me); if (! my d_intensity) Melder_throw (theMessage_Cannot_compute_intensity); } autoIntensity publish = Data_copy (my d_intensity.get()); Editor_broadcastPublication (me, publish.transfer()); } static void menu_cb_drawVisibleIntensityContour (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); EDITOR_FORM (U"Draw visible intensity contour", 0) my v_form_pictureWindow (cmd); my v_form_pictureMargins (cmd); my v_form_pictureSelection (cmd); BOOLEAN (U"Garnish", 1); EDITOR_OK my v_ok_pictureWindow (cmd); my v_ok_pictureMargins (cmd); my v_ok_pictureSelection (cmd); SET_INTEGER (U"Garnish", my p_intensity_picture_garnish); EDITOR_DO my v_do_pictureWindow (cmd); my v_do_pictureMargins (cmd); my v_do_pictureSelection (cmd); my pref_intensity_picture_garnish () = my p_intensity_picture_garnish = GET_INTEGER (U"Garnish"); if (! my p_intensity_show) Melder_throw (U"No intensity contour is visible.\nFirst choose \"Show intensity\" from the Intensity menu."); if (! my d_intensity) { TimeSoundAnalysisEditor_computeIntensity (me); if (! my d_intensity) Melder_throw (theMessage_Cannot_compute_intensity); } Editor_openPraatPicture (me); Intensity_draw (my d_intensity.get(), my pictureGraphics, my d_startWindow, my d_endWindow, my p_intensity_viewFrom, my p_intensity_viewTo, my p_intensity_picture_garnish); FunctionEditor_garnish (me); Editor_closePraatPicture (me); EDITOR_END } static void menu_cb_intensityListing (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); double tmin, tmax; int part = makeQueriable (me, true, & tmin, & tmax); if (! my p_intensity_show) Melder_throw (U"No intensity contour is visible.\nFirst choose \"Show intensity\" from the Intensity menu."); if (! my d_intensity) { TimeSoundAnalysisEditor_computeIntensity (me); if (! my d_intensity) Melder_throw (theMessage_Cannot_compute_intensity); } MelderInfo_open (); MelderInfo_writeLine (U"Time_s Intensity_dB"); if (part == TimeSoundAnalysisEditor_PART_CURSOR) { double intensity = Vector_getValueAtX (my d_intensity.get(), tmin, Vector_CHANNEL_1, Vector_VALUE_INTERPOLATION_LINEAR); MelderInfo_writeLine (Melder_fixed (tmin, 6), U" ", Melder_fixed (intensity, 6)); } else { long i, i1, i2; Sampled_getWindowSamples (my d_intensity.get(), tmin, tmax, & i1, & i2); for (i = i1; i <= i2; i ++) { double t = Sampled_indexToX (my d_intensity.get(), i); double intensity = Vector_getValueAtX (my d_intensity.get(), t, Vector_CHANNEL_1, Vector_VALUE_INTERPOLATION_NEAREST); MelderInfo_writeLine (Melder_fixed (t, 6), U" ", Melder_fixed (intensity, 6)); } } MelderInfo_close (); } static void menu_cb_getIntensity (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); double tmin, tmax; int part = makeQueriable (me, true, & tmin, & tmax); if (! my p_intensity_show) Melder_throw (U"No intensity contour is visible.\nFirst choose \"Show intensity\" from the Intensity menu."); if (! my d_intensity) { TimeSoundAnalysisEditor_computeIntensity (me); if (! my d_intensity) Melder_throw (theMessage_Cannot_compute_intensity); } if (part == TimeSoundAnalysisEditor_PART_CURSOR) { Melder_information (Vector_getValueAtX (my d_intensity.get(), tmin, Vector_CHANNEL_1, Vector_VALUE_INTERPOLATION_LINEAR), U" dB (intensity at CURSOR)"); } else { static const char32 *methodString [] = { U"median", U"mean-energy", U"mean-sones", U"mean-dB" }; Melder_information (Intensity_getAverage (my d_intensity.get(), tmin, tmax, my p_intensity_averagingMethod), U" dB (", methodString [my p_intensity_averagingMethod], U" intensity ", TimeSoundAnalysisEditor_partString_locative (part), U")"); } } static void menu_cb_getMinimumIntensity (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); double tmin, tmax; int part = makeQueriable (me, false, & tmin, & tmax); if (! my p_intensity_show) Melder_throw (U"No intensity contour is visible.\nFirst choose \"Show intensity\" from the Intensity menu."); if (! my d_intensity) { TimeSoundAnalysisEditor_computeIntensity (me); if (! my d_intensity) Melder_throw (theMessage_Cannot_compute_intensity); } double intensity = Vector_getMinimum (my d_intensity.get(), tmin, tmax, NUM_PEAK_INTERPOLATE_PARABOLIC); Melder_information (intensity, U" dB (minimum intensity ", TimeSoundAnalysisEditor_partString_locative (part), U")"); } static void menu_cb_getMaximumIntensity (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); double tmin, tmax; int part = makeQueriable (me, false, & tmin, & tmax); if (! my p_intensity_show) Melder_throw (U"No intensity contour is visible.\nFirst choose \"Show intensity\" from the Intensity menu."); if (! my d_intensity) { TimeSoundAnalysisEditor_computeIntensity (me); if (! my d_intensity) Melder_throw (theMessage_Cannot_compute_intensity); } double intensity = Vector_getMaximum (my d_intensity.get(), tmin, tmax, NUM_PEAK_INTERPOLATE_PARABOLIC); Melder_information (intensity, U" dB (maximum intensity ", TimeSoundAnalysisEditor_partString_locative (part), U")"); } /***** FORMANT MENU *****/ static void menu_cb_showFormants (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); my pref_formant_show () = my p_formant_show = ! my p_formant_show; GuiMenuItem_check (my formantToggle, my p_formant_show); // in case we're called from a script FunctionEditor_redraw (me); } static void menu_cb_formantSettings (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); EDITOR_FORM (U"Formant settings", U"Intro 5.2. Configuring the formant contours") POSITIVE (U"Maximum formant (Hz)", my default_formant_maximumFormant ()) POSITIVE (U"Number of formants", my default_formant_numberOfFormants ()) POSITIVE (U"Window length (s)", my default_formant_windowLength ()) REAL (U"Dynamic range (dB)", my default_formant_dynamicRange ()) POSITIVE (U"Dot size (mm)", my default_formant_dotSize ()) LABEL (U"note1", U"") LABEL (U"note2", U"") EDITOR_OK SET_REAL (U"Maximum formant", my p_formant_maximumFormant) SET_REAL (U"Number of formants", my p_formant_numberOfFormants) SET_REAL (U"Window length", my p_formant_windowLength) SET_REAL (U"Dynamic range", my p_formant_dynamicRange) SET_REAL (U"Dot size", my p_formant_dotSize) if (my p_formant_method != my default_formant_method () || my p_formant_preemphasisFrom != Melder_atof (my default_formant_preemphasisFrom ())) { SET_STRING (U"note1", U"Warning: you have non-standard \"advanced settings\".") } else { SET_STRING (U"note1", U"(all of your \"advanced settings\" have their standard values)") } if (my p_timeStepStrategy != my default_timeStepStrategy ()) { SET_STRING (U"note2", U"Warning: you have a non-standard \"time step strategy\".") } else { SET_STRING (U"note2", U"(your \"time step strategy\" has its standard value: automatic)") } EDITOR_DO my pref_formant_maximumFormant () = my p_formant_maximumFormant = GET_REAL (U"Maximum formant"); my pref_formant_numberOfFormants () = my p_formant_numberOfFormants = GET_REAL (U"Number of formants"); my pref_formant_windowLength () = my p_formant_windowLength = GET_REAL (U"Window length"); my pref_formant_dynamicRange () = my p_formant_dynamicRange = GET_REAL (U"Dynamic range"); my pref_formant_dotSize () = my p_formant_dotSize = GET_REAL (U"Dot size"); my d_formant. reset(); FunctionEditor_redraw (me); EDITOR_END } static void menu_cb_advancedFormantSettings (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); EDITOR_FORM (U"Advanced formant settings", U"Advanced formant settings...") RADIO_ENUM (U"Method", kTimeSoundAnalysisEditor_formant_analysisMethod, my default_formant_method ()) POSITIVE (U"Pre-emphasis from (Hz)", my default_formant_preemphasisFrom ()) EDITOR_OK SET_ENUM (U"Method", kTimeSoundAnalysisEditor_formant_analysisMethod, my p_formant_method) SET_REAL (U"Pre-emphasis from", my p_formant_preemphasisFrom) EDITOR_DO my pref_formant_method () = my p_formant_method = GET_ENUM (kTimeSoundAnalysisEditor_formant_analysisMethod, U"Method"); my pref_formant_preemphasisFrom () = my p_formant_preemphasisFrom = GET_REAL (U"Pre-emphasis from"); my d_formant. reset(); FunctionEditor_redraw (me); EDITOR_END } static void menu_cb_extractVisibleFormantContour (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); if (! my p_formant_show) Melder_throw (U"No formant contour is visible.\nFirst choose \"Show formants\" from the Formant menu."); if (! my d_formant) { TimeSoundAnalysisEditor_computeFormants (me); if (! my d_formant) Melder_throw (theMessage_Cannot_compute_formant); } autoFormant publish = Data_copy (my d_formant.peek()); Editor_broadcastPublication (me, publish.transfer()); } static void menu_cb_drawVisibleFormantContour (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); EDITOR_FORM (U"Draw visible formant contour", 0) my v_form_pictureWindow (cmd); my v_form_pictureMargins (cmd); my v_form_pictureSelection (cmd); BOOLEAN (U"Garnish", 1); EDITOR_OK my v_ok_pictureWindow (cmd); my v_ok_pictureMargins (cmd); my v_ok_pictureSelection (cmd); SET_INTEGER (U"Garnish", my p_formant_picture_garnish); EDITOR_DO my v_do_pictureWindow (cmd); my v_do_pictureMargins (cmd); my v_do_pictureSelection (cmd); my pref_formant_picture_garnish () = my p_formant_picture_garnish = GET_INTEGER (U"Garnish"); if (! my p_formant_show) Melder_throw (U"No formant contour is visible.\nFirst choose \"Show formant\" from the Formant menu."); if (! my d_formant) { TimeSoundAnalysisEditor_computeFormants (me); if (! my d_formant) Melder_throw (theMessage_Cannot_compute_formant); } Editor_openPraatPicture (me); Formant_drawSpeckles (my d_formant.get(), my pictureGraphics, my d_startWindow, my d_endWindow, my p_spectrogram_viewTo, my p_formant_dynamicRange, my p_formant_picture_garnish); FunctionEditor_garnish (me); Editor_closePraatPicture (me); EDITOR_END } static void menu_cb_formantListing (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); double tmin, tmax; int part = makeQueriable (me, true, & tmin, & tmax); if (! my p_formant_show) Melder_throw (U"No formant contour is visible.\nFirst choose \"Show formants\" from the Formant menu."); if (! my d_formant) { TimeSoundAnalysisEditor_computeFormants (me); if (! my d_formant) Melder_throw (theMessage_Cannot_compute_formant); } MelderInfo_open (); MelderInfo_writeLine (U"Time_s F1_Hz F2_Hz F3_Hz F4_Hz"); if (part == TimeSoundAnalysisEditor_PART_CURSOR) { double f1 = Formant_getValueAtTime (my d_formant.get(), 1, tmin, 0); double f2 = Formant_getValueAtTime (my d_formant.get(), 2, tmin, 0); double f3 = Formant_getValueAtTime (my d_formant.get(), 3, tmin, 0); double f4 = Formant_getValueAtTime (my d_formant.get(), 4, tmin, 0); MelderInfo_writeLine (Melder_fixed (tmin, 6), U" ", Melder_fixed (f1, 6), U" ", Melder_fixed (f2, 6), U" ", Melder_fixed (f3, 6), U" ", Melder_fixed (f4, 6)); } else { long i, i1, i2; Sampled_getWindowSamples (my d_formant.get(), tmin, tmax, & i1, & i2); for (i = i1; i <= i2; i ++) { double t = Sampled_indexToX (my d_formant.get(), i); double f1 = Formant_getValueAtTime (my d_formant.get(), 1, t, 0); double f2 = Formant_getValueAtTime (my d_formant.get(), 2, t, 0); double f3 = Formant_getValueAtTime (my d_formant.get(), 3, t, 0); double f4 = Formant_getValueAtTime (my d_formant.get(), 4, t, 0); MelderInfo_writeLine (Melder_fixed (t, 6), U" ", Melder_fixed (f1, 6), U" ", Melder_fixed (f2, 6), U" ", Melder_fixed (f3, 6), U" ", Melder_fixed (f4, 6)); } } MelderInfo_close (); } static void do_getFormant (TimeSoundAnalysisEditor me, int iformant) { double tmin, tmax; int part = makeQueriable (me, true, & tmin, & tmax); if (! my p_formant_show) Melder_throw (U"No formant contour is visible.\nFirst choose \"Show formants\" from the Formant menu."); if (! my d_formant) { TimeSoundAnalysisEditor_computeFormants (me); if (! my d_formant) Melder_throw (theMessage_Cannot_compute_formant); } if (part == TimeSoundAnalysisEditor_PART_CURSOR) { Melder_information (Formant_getValueAtTime (my d_formant.get(), iformant, tmin, 0), U" Hz (nearest F", iformant, U" to CURSOR)"); } else { Melder_information (Formant_getMean (my d_formant.get(), iformant, tmin, tmax, 0), U" Hz (mean F", iformant, U" ", TimeSoundAnalysisEditor_partString_locative (part), U")"); } } static void do_getBandwidth (TimeSoundAnalysisEditor me, int iformant) { double tmin, tmax; int part = makeQueriable (me, true, & tmin, & tmax); if (! my p_formant_show) Melder_throw (U"No formant contour is visible.\nFirst choose \"Show formants\" from the Formant menu."); if (! my d_formant) { TimeSoundAnalysisEditor_computeFormants (me); if (! my d_formant) Melder_throw (theMessage_Cannot_compute_formant); } if (part == TimeSoundAnalysisEditor_PART_CURSOR) { Melder_information (Formant_getBandwidthAtTime (my d_formant.get(), iformant, tmin, 0), U" Hz (nearest B", iformant, U" to CURSOR)"); } else { Melder_information (Formant_getBandwidthAtTime (my d_formant.get(), iformant, 0.5 * (tmin + tmax), 0), U" Hz (B", iformant, U" in centre of ", TimeSoundAnalysisEditor_partString (part), U")"); } } static void menu_cb_getFirstFormant (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); do_getFormant (me, 1); } static void menu_cb_getFirstBandwidth (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); do_getBandwidth (me, 1); } static void menu_cb_getSecondFormant (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); do_getFormant (me, 2); } static void menu_cb_getSecondBandwidth (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); do_getBandwidth (me, 2); } static void menu_cb_getThirdFormant (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); do_getFormant (me, 3); } static void menu_cb_getThirdBandwidth (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); do_getBandwidth (me, 3); } static void menu_cb_getFourthFormant (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); do_getFormant (me, 4); } static void menu_cb_getFourthBandwidth (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); do_getBandwidth (me, 4); } static void menu_cb_getFormant (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); EDITOR_FORM (U"Get formant", 0) NATURAL (U"Formant number", U"5") EDITOR_OK EDITOR_DO do_getFormant (me, GET_INTEGER (U"Formant number")); EDITOR_END } static void menu_cb_getBandwidth (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); EDITOR_FORM (U"Get bandwidth", 0) NATURAL (U"Formant number", U"5") EDITOR_OK EDITOR_DO do_getBandwidth (me, GET_INTEGER (U"Formant number")); EDITOR_END } /***** PULSE MENU *****/ static void menu_cb_showPulses (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); my pref_pulses_show () = my p_pulses_show = ! my p_pulses_show; GuiMenuItem_check (my pulsesToggle, my p_pulses_show); // in case we're called from a script FunctionEditor_redraw (me); } static void menu_cb_advancedPulsesSettings (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); EDITOR_FORM (U"Advanced pulses settings", U"Advanced pulses settings...") POSITIVE (U"Maximum period factor", my default_pulses_maximumPeriodFactor ()) POSITIVE (U"Maximum amplitude factor", my default_pulses_maximumAmplitudeFactor ()) EDITOR_OK SET_REAL (U"Maximum period factor", my p_pulses_maximumPeriodFactor) SET_REAL (U"Maximum amplitude factor", my p_pulses_maximumAmplitudeFactor) EDITOR_DO my pref_pulses_maximumPeriodFactor () = my p_pulses_maximumPeriodFactor = GET_REAL (U"Maximum period factor"); my pref_pulses_maximumAmplitudeFactor () = my p_pulses_maximumAmplitudeFactor = GET_REAL (U"Maximum amplitude factor"); my d_pulses. reset(); FunctionEditor_redraw (me); EDITOR_END } static void menu_cb_extractVisiblePulses (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); if (! my p_pulses_show) Melder_throw (U"No pulses are visible.\nFirst choose \"Show pulses\" from the Pulses menu."); if (! my d_pulses) { TimeSoundAnalysisEditor_computePulses (me); if (! my d_pulses) Melder_throw (theMessage_Cannot_compute_pulses); } autoPointProcess publish = Data_copy (my d_pulses.get()); Editor_broadcastPublication (me, publish.transfer()); } static void menu_cb_drawVisiblePulses (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); EDITOR_FORM (U"Draw visible pulses", 0) my v_form_pictureWindow (cmd); my v_form_pictureMargins (cmd); my v_form_pictureSelection (cmd); BOOLEAN (U"Garnish", 1); EDITOR_OK my v_ok_pictureWindow (cmd); my v_ok_pictureMargins (cmd); my v_ok_pictureSelection (cmd); SET_INTEGER (U"Garnish", my p_pulses_picture_garnish); EDITOR_DO my v_do_pictureWindow (cmd); my v_do_pictureMargins (cmd); my v_do_pictureSelection (cmd); my pref_pulses_picture_garnish () = my p_pulses_picture_garnish = GET_INTEGER (U"Garnish"); if (! my p_pulses_show) Melder_throw (U"No pulses are visible.\nFirst choose \"Show pulses\" from the Pulses menu."); if (! my d_pulses) { TimeSoundAnalysisEditor_computePulses (me); if (! my d_pulses) Melder_throw (theMessage_Cannot_compute_pulses); } Editor_openPraatPicture (me); PointProcess_draw (my d_pulses.get(), my pictureGraphics, my d_startWindow, my d_endWindow, my p_pulses_picture_garnish); FunctionEditor_garnish (me); Editor_closePraatPicture (me); EDITOR_END } static void menu_cb_voiceReport (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); time_t today = time (NULL); double tmin, tmax; int part = makeQueriable (me, false, & tmin, & tmax); if (! my p_pulses_show) Melder_throw (U"No pulses are visible.\nFirst choose \"Show pulses\" from the Pulses menu."); if (! my d_pulses) { TimeSoundAnalysisEditor_computePulses (me); if (! my d_pulses) Melder_throw (theMessage_Cannot_compute_pulses); } autoSound sound = extractSound (me, tmin, tmax); MelderInfo_open (); MelderInfo_writeLine (U"-- Voice report for ", my name, U" --\nDate: ", Melder_peek8to32 (ctime (& today))); if (my p_pitch_method != kTimeSoundAnalysisEditor_pitch_analysisMethod_CROSS_CORRELATION) MelderInfo_writeLine (U"WARNING: some of the following measurements may be imprecise.\n" "For more precision, go to \"Pitch settings\" and choose \"Optimize for voice analysis\".\n"); MelderInfo_writeLine (U"Time range of ", TimeSoundAnalysisEditor_partString (part)); Sound_Pitch_PointProcess_voiceReport (sound.peek(), my d_pitch.get(), my d_pulses.get(), tmin, tmax, my p_pitch_floor, my p_pitch_ceiling, my p_pulses_maximumPeriodFactor, my p_pulses_maximumAmplitudeFactor, my p_pitch_silenceThreshold, my p_pitch_voicingThreshold); MelderInfo_close (); } static void menu_cb_pulseListing (EDITOR_ARGS) { EDITOR_IAM (TimeSoundAnalysisEditor); long i, i1, i2; double tmin, tmax; makeQueriable (me, false, & tmin, & tmax); if (! my p_pulses_show) Melder_throw (U"No pulses are visible.\nFirst choose \"Show pulses\" from the Pulses menu."); if (! my d_pulses) { TimeSoundAnalysisEditor_computePulses (me); if (! my d_pulses) Melder_throw (theMessage_Cannot_compute_pulses); } MelderInfo_open (); MelderInfo_writeLine (U"Time_s"); i1 = PointProcess_getHighIndex (my d_pulses.get(), tmin); i2 = PointProcess_getLowIndex (my d_pulses.get(), tmax); for (i = i1; i <= i2; i ++) { double t = my d_pulses -> t [i]; MelderInfo_writeLine (Melder_fixed (t, 12)); } MelderInfo_close (); } /* static void cb_getJitter_xx (TimeSoundAnalysisEditor me, double (*PointProcess_getJitter_xx) (PointProcess, double, double, double, double, double)) { double minimumPeriod = 0.8 / my p_pitch_ceiling, maximumPeriod = 1.25 / my p_pitch_floor; if (! my p_pulses_show) Melder_throw (U"No pulses are visible.\nFirst choose \"Show pulses\" from the Pulses menu."); if (! my d_pulses) { computePulses (me); if (! my d_pulses) Melder_throw (theMessage_Cannot_compute_pulses); } if (my startSelection == my endSelection) Melder_throw (U"Make a selection first."); makeQueriable Melder_informationReal (PointProcess_getJitter_xx (my d_pulses, my startSelection, my endSelection, minimumPeriod, maximumPeriod, my p_pulses_maximumPeriodFactor), NULL); } DIRECT (TimeSoundAnalysisEditor, cb_getJitter_local) cb_getJitter_xx (me, PointProcess_getJitter_local); END DIRECT (TimeSoundAnalysisEditor, cb_getJitter_local_absolute) cb_getJitter_xx (me, PointProcess_getJitter_local_absolute); END DIRECT (TimeSoundAnalysisEditor, cb_getJitter_rap) cb_getJitter_xx (me, PointProcess_getJitter_rap); END DIRECT (TimeSoundAnalysisEditor, cb_getJitter_ppq5) cb_getJitter_xx (me, PointProcess_getJitter_ppq5); END DIRECT (TimeSoundAnalysisEditor, cb_getJitter_ddp) cb_getJitter_xx (me, PointProcess_getJitter_ddp); END static void cb_getShimmer_xx (TimeSoundAnalysisEditor me, double (*PointProcess_Sound_getShimmer_xx) (PointProcess, Sound, double, double, double, double, double)) { double minimumPeriod = 0.8 / my p_pitch_ceiling, maximumPeriod = 1.25 / my p_pitch_floor; if (! my p_pulses_show) Melder_throw (U"No pulses are visible.\nFirst choose \"Show pulses\" from the Pulses menu."); if (! my d_pulses) { computePulses (me); if (! my d_pulses) Melder_throw (theMessage_Cannot_compute_pulses); } if (my startSelection == my endSelection) Melder_throw (U"Make a selection first."); makeQueriable autoSound sound = extractSound (me, my startSelection, my endSelection); Melder_informationReal (PointProcess_Sound_getShimmer_xx (my d_pulses, sound, my startSelection, my endSelection, minimumPeriod, maximumPeriod, my p_pulses_maximumAmplitudeFactor), NULL); } DIRECT (TimeSoundAnalysisEditor, cb_getShimmer_local) cb_getShimmer_xx (me, PointProcess_Sound_getShimmer_local); END DIRECT (TimeSoundAnalysisEditor, cb_getShimmer_local_dB) cb_getShimmer_xx (me, PointProcess_Sound_getShimmer_local_dB); END DIRECT (TimeSoundAnalysisEditor, cb_getShimmer_apq3) cb_getShimmer_xx (me, PointProcess_Sound_getShimmer_apq3); END DIRECT (TimeSoundAnalysisEditor, cb_getShimmer_apq5) cb_getShimmer_xx (me, PointProcess_Sound_getShimmer_apq5); END DIRECT (TimeSoundAnalysisEditor, cb_getShimmer_apq11) cb_getShimmer_xx (me, PointProcess_Sound_getShimmer_apq11); END DIRECT (TimeSoundAnalysisEditor, cb_getShimmer_dda) cb_getShimmer_xx (me, PointProcess_Sound_getShimmer_dda); END */ void structTimeSoundAnalysisEditor :: v_createMenuItems_view_sound (EditorMenu menu) { TimeSoundAnalysisEditor_Parent :: v_createMenuItems_view_sound (menu); v_createMenuItems_view_sound_analysis (menu); } void structTimeSoundAnalysisEditor :: v_createMenuItems_view_sound_analysis (EditorMenu menu) { EditorMenu_addCommand (menu, U"Analysis window:", GuiMenu_INSENSITIVE, menu_cb_showAnalyses); EditorMenu_addCommand (menu, U"Show analyses...", 0, menu_cb_showAnalyses); EditorMenu_addCommand (menu, U"Time step settings...", 0, menu_cb_timeStepSettings); EditorMenu_addCommand (menu, U"-- sound analysis --", 0, 0); } void structTimeSoundAnalysisEditor :: v_createMenuItems_query (EditorMenu menu) { TimeSoundAnalysisEditor_Parent :: v_createMenuItems_query (menu); if (d_sound.data || d_longSound.data) { v_createMenuItems_query_log (menu); } } void structTimeSoundAnalysisEditor :: v_createMenuItems_query_log (EditorMenu menu) { EditorMenu_addCommand (menu, U"-- query log --", 0, NULL); EditorMenu_addCommand (menu, U"Log settings...", 0, menu_cb_logSettings); EditorMenu_addCommand (menu, U"Delete log file 1", 0, menu_cb_deleteLogFile1); EditorMenu_addCommand (menu, U"Delete log file 2", 0, menu_cb_deleteLogFile2); EditorMenu_addCommand (menu, U"Log 1", GuiMenu_F12, menu_cb_log1); EditorMenu_addCommand (menu, U"Log 2", GuiMenu_F12 + GuiMenu_SHIFT, menu_cb_log2); EditorMenu_addCommand (menu, U"Log script 3 (...)", GuiMenu_F12 + GuiMenu_OPTION, menu_cb_logScript3); EditorMenu_addCommand (menu, U"Log script 4 (...)", GuiMenu_F12 + GuiMenu_COMMAND, menu_cb_logScript4); } void structTimeSoundAnalysisEditor :: v_createMenus_analysis () { EditorMenu menu; if (v_hasSpectrogram ()) { menu = Editor_addMenu (this, U"Spectrum", 0); spectrogramToggle = EditorMenu_addCommand (menu, U"Show spectrogram", GuiMenu_CHECKBUTTON | (pref_spectrogram_show () ? GuiMenu_TOGGLE_ON : 0), menu_cb_showSpectrogram); EditorMenu_addCommand (menu, U"Spectrogram settings...", 0, menu_cb_spectrogramSettings); EditorMenu_addCommand (menu, U"Advanced spectrogram settings...", 0, menu_cb_advancedSpectrogramSettings); EditorMenu_addCommand (menu, U"-- spectrum query --", 0, NULL); EditorMenu_addCommand (menu, U"Query:", GuiMenu_INSENSITIVE, menu_cb_getFrequency /* dummy */); EditorMenu_addCommand (menu, U"Get frequency at frequency cursor", 0, menu_cb_getFrequency); EditorMenu_addCommand (menu, U"Get spectral power at cursor cross", GuiMenu_F7, menu_cb_getSpectralPowerAtCursorCross); EditorMenu_addCommand (menu, U"-- spectrum select --", 0, NULL); EditorMenu_addCommand (menu, U"Select:", GuiMenu_INSENSITIVE, menu_cb_moveFrequencyCursorTo/* dummy */); EditorMenu_addCommand (menu, U"Move frequency cursor to...", 0, menu_cb_moveFrequencyCursorTo); v_createMenuItems_spectrum_picture (menu); EditorMenu_addCommand (menu, U"-- spectrum extract --", 0, NULL); EditorMenu_addCommand (menu, U"Extract to objects window:", GuiMenu_INSENSITIVE, menu_cb_extractVisibleSpectrogram /* dummy */); EditorMenu_addCommand (menu, U"Extract visible spectrogram", 0, menu_cb_extractVisibleSpectrogram); EditorMenu_addCommand (menu, U"View spectral slice", 'L', menu_cb_viewSpectralSlice); } if (v_hasPitch ()) { menu = Editor_addMenu (this, U"Pitch", 0); pitchToggle = EditorMenu_addCommand (menu, U"Show pitch", GuiMenu_CHECKBUTTON | (pref_pitch_show () ? GuiMenu_TOGGLE_ON : 0), menu_cb_showPitch); EditorMenu_addCommand (menu, U"Pitch settings...", 0, menu_cb_pitchSettings); EditorMenu_addCommand (menu, U"Advanced pitch settings...", 0, menu_cb_advancedPitchSettings); EditorMenu_addCommand (menu, U"-- pitch query --", 0, NULL); EditorMenu_addCommand (menu, U"Query:", GuiMenu_INSENSITIVE, menu_cb_getFrequency /* dummy */); EditorMenu_addCommand (menu, U"Pitch listing", 0, menu_cb_pitchListing); EditorMenu_addCommand (menu, U"Get pitch", GuiMenu_F5, menu_cb_getPitch); EditorMenu_addCommand (menu, U"Get minimum pitch", GuiMenu_F5 + GuiMenu_COMMAND, menu_cb_getMinimumPitch); EditorMenu_addCommand (menu, U"Get maximum pitch", GuiMenu_F5 + GuiMenu_SHIFT, menu_cb_getMaximumPitch); EditorMenu_addCommand (menu, U"-- pitch select --", 0, NULL); EditorMenu_addCommand (menu, U"Select:", GuiMenu_INSENSITIVE, menu_cb_moveCursorToMinimumPitch /* dummy */); EditorMenu_addCommand (menu, U"Move cursor to minimum pitch", GuiMenu_COMMAND + GuiMenu_SHIFT + 'L', menu_cb_moveCursorToMinimumPitch); EditorMenu_addCommand (menu, U"Move cursor to maximum pitch", GuiMenu_COMMAND + GuiMenu_SHIFT + 'H', menu_cb_moveCursorToMaximumPitch); v_createMenuItems_pitch_picture (menu); EditorMenu_addCommand (menu, U"-- pitch extract --", 0, NULL); EditorMenu_addCommand (menu, U"Extract to objects window:", GuiMenu_INSENSITIVE, menu_cb_extractVisiblePitchContour /* dummy */); EditorMenu_addCommand (menu, U"Extract visible pitch contour", 0, menu_cb_extractVisiblePitchContour); } if (v_hasIntensity ()) { menu = Editor_addMenu (this, U"Intensity", 0); intensityToggle = EditorMenu_addCommand (menu, U"Show intensity", GuiMenu_CHECKBUTTON | (pref_intensity_show () ? GuiMenu_TOGGLE_ON : 0), menu_cb_showIntensity); EditorMenu_addCommand (menu, U"Intensity settings...", 0, menu_cb_intensitySettings); EditorMenu_addCommand (menu, U"-- intensity query --", 0, NULL); EditorMenu_addCommand (menu, U"Query:", GuiMenu_INSENSITIVE, menu_cb_getFrequency /* dummy */); EditorMenu_addCommand (menu, U"Intensity listing", 0, menu_cb_intensityListing); EditorMenu_addCommand (menu, U"Get intensity", GuiMenu_F8, menu_cb_getIntensity); EditorMenu_addCommand (menu, U"Get minimum intensity", GuiMenu_F8 + GuiMenu_COMMAND, menu_cb_getMinimumIntensity); EditorMenu_addCommand (menu, U"Get maximum intensity", GuiMenu_F8 + GuiMenu_SHIFT, menu_cb_getMaximumIntensity); v_createMenuItems_intensity_picture (menu); EditorMenu_addCommand (menu, U"-- intensity extract --", 0, NULL); EditorMenu_addCommand (menu, U"Extract to objects window:", GuiMenu_INSENSITIVE, menu_cb_extractVisibleIntensityContour /* dummy */); EditorMenu_addCommand (menu, U"Extract visible intensity contour", 0, menu_cb_extractVisibleIntensityContour); } if (v_hasFormants ()) { menu = Editor_addMenu (this, U"Formant", 0); formantToggle = EditorMenu_addCommand (menu, U"Show formants", GuiMenu_CHECKBUTTON | (pref_formant_show () ? GuiMenu_TOGGLE_ON : 0), menu_cb_showFormants); EditorMenu_addCommand (menu, U"Formant settings...", 0, menu_cb_formantSettings); EditorMenu_addCommand (menu, U"Advanced formant settings...", 0, menu_cb_advancedFormantSettings); EditorMenu_addCommand (menu, U"-- formant query --", 0, NULL); EditorMenu_addCommand (menu, U"Query:", GuiMenu_INSENSITIVE, menu_cb_getFrequency /* dummy */); EditorMenu_addCommand (menu, U"Formant listing", 0, menu_cb_formantListing); EditorMenu_addCommand (menu, U"Get first formant", GuiMenu_F1, menu_cb_getFirstFormant); EditorMenu_addCommand (menu, U"Get first bandwidth", 0, menu_cb_getFirstBandwidth); EditorMenu_addCommand (menu, U"Get second formant", GuiMenu_F2, menu_cb_getSecondFormant); EditorMenu_addCommand (menu, U"Get second bandwidth", 0, menu_cb_getSecondBandwidth); EditorMenu_addCommand (menu, U"Get third formant", GuiMenu_F3, menu_cb_getThirdFormant); EditorMenu_addCommand (menu, U"Get third bandwidth", 0, menu_cb_getThirdBandwidth); EditorMenu_addCommand (menu, U"Get fourth formant", GuiMenu_F4, menu_cb_getFourthFormant); EditorMenu_addCommand (menu, U"Get fourth bandwidth", 0, menu_cb_getFourthBandwidth); EditorMenu_addCommand (menu, U"Get formant...", 0, menu_cb_getFormant); EditorMenu_addCommand (menu, U"Get bandwidth...", 0, menu_cb_getBandwidth); v_createMenuItems_formant_picture (menu); EditorMenu_addCommand (menu, U"-- formant extract --", 0, NULL); EditorMenu_addCommand (menu, U"Extract to objects window:", GuiMenu_INSENSITIVE, menu_cb_extractVisibleFormantContour /* dummy */); EditorMenu_addCommand (menu, U"Extract visible formant contour", 0, menu_cb_extractVisibleFormantContour); } if (v_hasPulses ()) { menu = Editor_addMenu (this, U"Pulses", 0); pulsesToggle = EditorMenu_addCommand (menu, U"Show pulses", GuiMenu_CHECKBUTTON | (pref_pulses_show () ? GuiMenu_TOGGLE_ON : 0), menu_cb_showPulses); EditorMenu_addCommand (menu, U"Advanced pulses settings...", 0, menu_cb_advancedPulsesSettings); EditorMenu_addCommand (menu, U"-- pulses query --", 0, NULL); EditorMenu_addCommand (menu, U"Query:", GuiMenu_INSENSITIVE, menu_cb_getFrequency /* dummy */); EditorMenu_addCommand (menu, U"Voice report", 0, menu_cb_voiceReport); EditorMenu_addCommand (menu, U"Pulse listing", 0, menu_cb_pulseListing); /* EditorMenu_addCommand (menu, U"Get jitter (local)", 0, cb_getJitter_local); EditorMenu_addCommand (menu, U"Get jitter (local, absolute)", 0, cb_getJitter_local_absolute); EditorMenu_addCommand (menu, U"Get jitter (rap)", 0, cb_getJitter_rap); EditorMenu_addCommand (menu, U"Get jitter (ppq5)", 0, cb_getJitter_ppq5); EditorMenu_addCommand (menu, U"Get jitter (ddp)", 0, cb_getJitter_ddp); EditorMenu_addCommand (menu, U"Get shimmer (local)", 0, cb_getShimmer_local); EditorMenu_addCommand (menu, U"Get shimmer (local_dB)", 0, cb_getShimmer_local_dB); EditorMenu_addCommand (menu, U"Get shimmer (apq3)", 0, cb_getShimmer_apq3); EditorMenu_addCommand (menu, U"Get shimmer (apq5)", 0, cb_getShimmer_apq5); EditorMenu_addCommand (menu, U"Get shimmer (apq11)", 0, cb_getShimmer_apq11); EditorMenu_addCommand (menu, U"Get shimmer (dda)", 0, cb_getShimmer_dda); */ v_createMenuItems_pulses_picture (menu); EditorMenu_addCommand (menu, U"-- pulses extract --", 0, NULL); EditorMenu_addCommand (menu, U"Extract to objects window:", GuiMenu_INSENSITIVE, menu_cb_extractVisiblePulses /* dummy */); EditorMenu_addCommand (menu, U"Extract visible pulses", 0, menu_cb_extractVisiblePulses); } } void structTimeSoundAnalysisEditor :: v_createMenuItems_spectrum_picture (EditorMenu menu) { EditorMenu_addCommand (menu, U"-- spectrum draw --", 0, NULL); EditorMenu_addCommand (menu, U"Draw to picture window:", GuiMenu_INSENSITIVE, menu_cb_paintVisibleSpectrogram /* dummy */); EditorMenu_addCommand (menu, U"Paint visible spectrogram...", 0, menu_cb_paintVisibleSpectrogram); } void structTimeSoundAnalysisEditor :: v_createMenuItems_pitch_picture (EditorMenu menu) { EditorMenu_addCommand (menu, U"-- pitch draw --", 0, NULL); EditorMenu_addCommand (menu, U"Draw to picture window:", GuiMenu_INSENSITIVE, menu_cb_drawVisiblePitchContour /* dummy */); EditorMenu_addCommand (menu, U"Draw visible pitch contour...", 0, menu_cb_drawVisiblePitchContour); } void structTimeSoundAnalysisEditor :: v_createMenuItems_intensity_picture (EditorMenu menu) { EditorMenu_addCommand (menu, U"-- intensity draw --", 0, NULL); EditorMenu_addCommand (menu, U"Draw to picture window:", GuiMenu_INSENSITIVE, menu_cb_drawVisibleIntensityContour /* dummy */); EditorMenu_addCommand (menu, U"Draw visible intensity contour...", 0, menu_cb_drawVisibleIntensityContour); } void structTimeSoundAnalysisEditor :: v_createMenuItems_formant_picture (EditorMenu menu) { EditorMenu_addCommand (menu, U"-- formant draw --", 0, NULL); EditorMenu_addCommand (menu, U"Draw to picture window:", GuiMenu_INSENSITIVE, menu_cb_drawVisibleFormantContour /* dummy */); EditorMenu_addCommand (menu, U"Draw visible formant contour...", 0, menu_cb_drawVisibleFormantContour); } void structTimeSoundAnalysisEditor :: v_createMenuItems_pulses_picture (EditorMenu menu) { EditorMenu_addCommand (menu, U"-- pulses draw --", 0, NULL); EditorMenu_addCommand (menu, U"Draw to picture window:", GuiMenu_INSENSITIVE, menu_cb_drawVisiblePulses /* dummy */); EditorMenu_addCommand (menu, U"Draw visible pulses...", 0, menu_cb_drawVisiblePulses); } void TimeSoundAnalysisEditor_computeSpectrogram (TimeSoundAnalysisEditor me) { autoMelderProgressOff progress; if (my p_spectrogram_show && my d_endWindow - my d_startWindow <= my p_longestAnalysis && (! my d_spectrogram || my d_spectrogram -> xmin != my d_startWindow || my d_spectrogram -> xmax != my d_endWindow)) { double margin = my p_spectrogram_windowShape == kSound_to_Spectrogram_windowShape_GAUSSIAN ? my p_spectrogram_windowLength : 0.5 * my p_spectrogram_windowLength; my d_spectrogram.reset(); try { autoSound sound = extractSound (me, my d_startWindow - margin, my d_endWindow + margin); my d_spectrogram = Sound_to_Spectrogram (sound.peek(), my p_spectrogram_windowLength, my p_spectrogram_viewTo, (my d_endWindow - my d_startWindow) / my p_spectrogram_timeSteps, my p_spectrogram_viewTo / my p_spectrogram_frequencySteps, my p_spectrogram_windowShape, 8.0, 8.0); my d_spectrogram -> xmin = my d_startWindow; my d_spectrogram -> xmax = my d_endWindow; } catch (MelderError) { Melder_clearError (); } } } static void computePitch_inside (TimeSoundAnalysisEditor me) { double margin = my p_pitch_veryAccurate ? 3.0 / my p_pitch_floor : 1.5 / my p_pitch_floor; my d_pitch. reset(); try { autoSound sound = extractSound (me, my d_startWindow - margin, my d_endWindow + margin); double pitchTimeStep = my p_timeStepStrategy == kTimeSoundAnalysisEditor_timeStepStrategy_FIXED ? my p_fixedTimeStep : my p_timeStepStrategy == kTimeSoundAnalysisEditor_timeStepStrategy_VIEW_DEPENDENT ? (my d_endWindow - my d_startWindow) / my p_numberOfTimeStepsPerView : 0.0; // the default: determined by pitch floor my d_pitch = Sound_to_Pitch_any (sound.peek(), pitchTimeStep, my p_pitch_floor, my p_pitch_method == kTimeSoundAnalysisEditor_pitch_analysisMethod_AUTOCORRELATION ? 3.0 : 1.0, my p_pitch_maximumNumberOfCandidates, (my p_pitch_method - 1) * 2 + my p_pitch_veryAccurate, my p_pitch_silenceThreshold, my p_pitch_voicingThreshold, my p_pitch_octaveCost, my p_pitch_octaveJumpCost, my p_pitch_voicedUnvoicedCost, my p_pitch_ceiling); my d_pitch -> xmin = my d_startWindow; my d_pitch -> xmax = my d_endWindow; } catch (MelderError) { Melder_clearError (); } } void TimeSoundAnalysisEditor_computePitch (TimeSoundAnalysisEditor me) { autoMelderProgressOff progress; if (my p_pitch_show && my d_endWindow - my d_startWindow <= my p_longestAnalysis && (! my d_pitch || my d_pitch -> xmin != my d_startWindow || my d_pitch -> xmax != my d_endWindow)) { computePitch_inside (me); } } void TimeSoundAnalysisEditor_computeIntensity (TimeSoundAnalysisEditor me) { autoMelderProgressOff progress; if (my p_intensity_show && my d_endWindow - my d_startWindow <= my p_longestAnalysis && (! my d_intensity || my d_intensity -> xmin != my d_startWindow || my d_intensity -> xmax != my d_endWindow)) { double margin = 3.2 / my p_pitch_floor; my d_intensity. reset(); try { autoSound sound = extractSound (me, my d_startWindow - margin, my d_endWindow + margin); my d_intensity = Sound_to_Intensity (sound.peek(), my p_pitch_floor, my d_endWindow - my d_startWindow > my p_longestAnalysis ? (my d_endWindow - my d_startWindow) / 100 : 0.0, my p_intensity_subtractMeanPressure); my d_intensity -> xmin = my d_startWindow; my d_intensity -> xmax = my d_endWindow; } catch (MelderError) { Melder_clearError (); } } } void TimeSoundAnalysisEditor_computeFormants (TimeSoundAnalysisEditor me) { autoMelderProgressOff progress; if (my p_formant_show && my d_endWindow - my d_startWindow <= my p_longestAnalysis && (! my d_formant || my d_formant -> xmin != my d_startWindow || my d_formant -> xmax != my d_endWindow)) { double margin = my p_formant_windowLength; my d_formant. reset(); try { autoSound sound = my d_endWindow - my d_startWindow > my p_longestAnalysis ? extractSound (me, 0.5 * (my d_startWindow + my d_endWindow - my p_longestAnalysis) - margin, 0.5 * (my d_startWindow + my d_endWindow + my p_longestAnalysis) + margin) : extractSound (me, my d_startWindow - margin, my d_endWindow + margin); double formantTimeStep = my p_timeStepStrategy == kTimeSoundAnalysisEditor_timeStepStrategy_FIXED ? my p_fixedTimeStep : my p_timeStepStrategy == kTimeSoundAnalysisEditor_timeStepStrategy_VIEW_DEPENDENT ? (my d_endWindow - my d_startWindow) / my p_numberOfTimeStepsPerView : 0.0; // the default: determined by analysis window length my d_formant = Sound_to_Formant_any (sound.peek(), formantTimeStep, lround (my p_formant_numberOfFormants * 2), my p_formant_maximumFormant, my p_formant_windowLength, my p_formant_method, my p_formant_preemphasisFrom, 50.0); my d_formant -> xmin = my d_startWindow; my d_formant -> xmax = my d_endWindow; } catch (MelderError) { Melder_clearError (); } } } void TimeSoundAnalysisEditor_computePulses (TimeSoundAnalysisEditor me) { autoMelderProgressOff progress; if (my p_pulses_show && my d_endWindow - my d_startWindow <= my p_longestAnalysis && (! my d_pulses || my d_pulses -> xmin != my d_startWindow || my d_pulses -> xmax != my d_endWindow)) { my d_pulses. reset(); if (! my d_pitch || my d_pitch -> xmin != my d_startWindow || my d_pitch -> xmax != my d_endWindow) { computePitch_inside (me); } if (my d_pitch) { try { autoSound sound = extractSound (me, my d_startWindow, my d_endWindow); my d_pulses = Sound_Pitch_to_PointProcess_cc (sound.peek(), my d_pitch.get()); } catch (MelderError) { Melder_clearError (); } } } } static void TimeSoundAnalysisEditor_v_draw_analysis (TimeSoundAnalysisEditor me) { /* * d_pitch may not exist yet (if shown at all, it may be going to be created in TimeSoundAnalysisEditor_computePitch (), * and even if that fails the user should see what the pitch settings are). So we use a dummy object. */ double pitchFloor_hidden = Function_convertStandardToSpecialUnit (Thing_dummyObject (Pitch), my p_pitch_floor, Pitch_LEVEL_FREQUENCY, my p_pitch_unit); double pitchCeiling_hidden = Function_convertStandardToSpecialUnit (Thing_dummyObject (Pitch), my p_pitch_ceiling, Pitch_LEVEL_FREQUENCY, my p_pitch_unit); double pitchFloor_overt = Function_convertToNonlogarithmic (Thing_dummyObject (Pitch), pitchFloor_hidden, Pitch_LEVEL_FREQUENCY, my p_pitch_unit); double pitchCeiling_overt = Function_convertToNonlogarithmic (Thing_dummyObject (Pitch), pitchCeiling_hidden, Pitch_LEVEL_FREQUENCY, my p_pitch_unit); double pitchViewFrom_overt = my p_pitch_viewFrom < my p_pitch_viewTo ? my p_pitch_viewFrom : pitchFloor_overt; double pitchViewTo_overt = my p_pitch_viewFrom < my p_pitch_viewTo ? my p_pitch_viewTo : pitchCeiling_overt; double pitchViewFrom_hidden = Function_isUnitLogarithmic (Thing_dummyObject (Pitch), Pitch_LEVEL_FREQUENCY, my p_pitch_unit) ? log10 (pitchViewFrom_overt) : pitchViewFrom_overt; double pitchViewTo_hidden = Function_isUnitLogarithmic (Thing_dummyObject (Pitch), Pitch_LEVEL_FREQUENCY, my p_pitch_unit) ? log10 (pitchViewTo_overt) : pitchViewTo_overt; Graphics_setWindow (my d_graphics, 0.0, 1.0, 0.0, 1.0); Graphics_setColour (my d_graphics, Graphics_WHITE); Graphics_fillRectangle (my d_graphics, 0.0, 1.0, 0.0, 1.0); Graphics_setColour (my d_graphics, Graphics_BLACK); Graphics_rectangle (my d_graphics, 0.0, 1.0, 0.0, 1.0); if (my d_endWindow - my d_startWindow > my p_longestAnalysis) { Graphics_setFont (my d_graphics, kGraphics_font_HELVETICA); Graphics_setFontSize (my d_graphics, 10); Graphics_setTextAlignment (my d_graphics, Graphics_CENTRE, Graphics_HALF); Graphics_text (my d_graphics, 0.5, 0.67, U"(To see the analyses, zoom in to at most ", Melder_half (my p_longestAnalysis), U" seconds,"); Graphics_text (my d_graphics, 0.5, 0.33, U"or raise the \"longest analysis\" setting with \"Show analyses\" in the View menu.)"); Graphics_setFontSize (my d_graphics, 12); return; } TimeSoundAnalysisEditor_computeSpectrogram (me); if (my p_spectrogram_show && my d_spectrogram) { Spectrogram_paintInside (my d_spectrogram.get(), my d_graphics, my d_startWindow, my d_endWindow, my p_spectrogram_viewFrom, my p_spectrogram_viewTo, my p_spectrogram_maximum, my p_spectrogram_autoscaling, my p_spectrogram_dynamicRange, my p_spectrogram_preemphasis, my p_spectrogram_dynamicCompression); } TimeSoundAnalysisEditor_computePitch (me); if (my p_pitch_show && my d_pitch) { double periodsPerAnalysisWindow = my p_pitch_method == kTimeSoundAnalysisEditor_pitch_analysisMethod_AUTOCORRELATION ? 3.0 : 1.0; double greatestNonUndersamplingTimeStep = 0.5 * periodsPerAnalysisWindow / my p_pitch_floor; double defaultTimeStep = 0.5 * greatestNonUndersamplingTimeStep; double timeStep = my p_timeStepStrategy == kTimeSoundAnalysisEditor_timeStepStrategy_FIXED ? my p_fixedTimeStep : my p_timeStepStrategy == kTimeSoundAnalysisEditor_timeStepStrategy_VIEW_DEPENDENT ? (my d_endWindow - my d_startWindow) / my p_numberOfTimeStepsPerView : defaultTimeStep; int undersampled = timeStep > greatestNonUndersamplingTimeStep; long numberOfVisiblePitchPoints = (long) ((my d_endWindow - my d_startWindow) / timeStep); Graphics_setColour (my d_graphics, Graphics_CYAN); Graphics_setLineWidth (my d_graphics, 3.0); if ((my p_pitch_drawingMethod == kTimeSoundAnalysisEditor_pitch_drawingMethod_AUTOMATIC && (undersampled || numberOfVisiblePitchPoints < 101)) || my p_pitch_drawingMethod == kTimeSoundAnalysisEditor_pitch_drawingMethod_SPECKLE) { Pitch_drawInside (my d_pitch.get(), my d_graphics, my d_startWindow, my d_endWindow, pitchViewFrom_overt, pitchViewTo_overt, 2, my p_pitch_unit); } if ((my p_pitch_drawingMethod == kTimeSoundAnalysisEditor_pitch_drawingMethod_AUTOMATIC && ! undersampled) || my p_pitch_drawingMethod == kTimeSoundAnalysisEditor_pitch_drawingMethod_CURVE) { Pitch_drawInside (my d_pitch.get(), my d_graphics, my d_startWindow, my d_endWindow, pitchViewFrom_overt, pitchViewTo_overt, false, my p_pitch_unit); } Graphics_setColour (my d_graphics, Graphics_BLUE); Graphics_setLineWidth (my d_graphics, 1.0); if ((my p_pitch_drawingMethod == kTimeSoundAnalysisEditor_pitch_drawingMethod_AUTOMATIC && (undersampled || numberOfVisiblePitchPoints < 101)) || my p_pitch_drawingMethod == kTimeSoundAnalysisEditor_pitch_drawingMethod_SPECKLE) { Pitch_drawInside (my d_pitch.get(), my d_graphics, my d_startWindow, my d_endWindow, pitchViewFrom_overt, pitchViewTo_overt, 1, my p_pitch_unit); } if ((my p_pitch_drawingMethod == kTimeSoundAnalysisEditor_pitch_drawingMethod_AUTOMATIC && ! undersampled) || my p_pitch_drawingMethod == kTimeSoundAnalysisEditor_pitch_drawingMethod_CURVE) { Pitch_drawInside (my d_pitch.get(), my d_graphics, my d_startWindow, my d_endWindow, pitchViewFrom_overt, pitchViewTo_overt, false, my p_pitch_unit); } Graphics_setColour (my d_graphics, Graphics_BLACK); } TimeSoundAnalysisEditor_computeIntensity (me); if (my p_intensity_show && my d_intensity) { Graphics_setColour (my d_graphics, my p_spectrogram_show ? Graphics_YELLOW : Graphics_LIME); Graphics_setLineWidth (my d_graphics, my p_spectrogram_show ? 1.0 : 3.0); Intensity_drawInside (my d_intensity.get(), my d_graphics, my d_startWindow, my d_endWindow, my p_intensity_viewFrom, my p_intensity_viewTo); Graphics_setLineWidth (my d_graphics, 1.0); Graphics_setColour (my d_graphics, Graphics_BLACK); } TimeSoundAnalysisEditor_computeFormants (me); if (my p_formant_show && my d_formant) { Graphics_setColour (my d_graphics, Graphics_RED); Graphics_setSpeckleSize (my d_graphics, my p_formant_dotSize); Formant_drawSpeckles_inside (my d_formant.get(), my d_graphics, my d_startWindow, my d_endWindow, my p_spectrogram_viewFrom, my p_spectrogram_viewTo, my p_formant_dynamicRange); Graphics_setColour (my d_graphics, Graphics_BLACK); } /* * Draw vertical scales. */ if (my p_pitch_show) { double pitchCursor_overt = NUMundefined, pitchCursor_hidden = NUMundefined; Graphics_setWindow (my d_graphics, my d_startWindow, my d_endWindow, pitchViewFrom_hidden, pitchViewTo_hidden); Graphics_setColour (my d_graphics, Graphics_BLUE); if (my d_pitch) { if (my d_startSelection == my d_endSelection) pitchCursor_hidden = Pitch_getValueAtTime (my d_pitch.get(), my d_startSelection, my p_pitch_unit, 1); else pitchCursor_hidden = Pitch_getMean (my d_pitch.get(), my d_startSelection, my d_endSelection, my p_pitch_unit); pitchCursor_overt = Function_convertToNonlogarithmic (my d_pitch.get(), pitchCursor_hidden, Pitch_LEVEL_FREQUENCY, my p_pitch_unit); if (NUMdefined (pitchCursor_hidden)) { Graphics_setTextAlignment (my d_graphics, Graphics_LEFT, Graphics_HALF); Graphics_text (my d_graphics, my d_endWindow, pitchCursor_hidden, Melder_float (Melder_half (pitchCursor_overt)), U" ", Function_getUnitText (my d_pitch.get(), Pitch_LEVEL_FREQUENCY, my p_pitch_unit, Function_UNIT_TEXT_SHORT | Function_UNIT_TEXT_GRAPHICAL)); } if (! NUMdefined (pitchCursor_hidden) || Graphics_dyWCtoMM (my d_graphics, pitchCursor_hidden - pitchViewFrom_hidden) > 5.0) { Graphics_setTextAlignment (my d_graphics, Graphics_LEFT, Graphics_BOTTOM); Graphics_text (my d_graphics, my d_endWindow, pitchViewFrom_hidden - Graphics_dyMMtoWC (my d_graphics, 0.5), Melder_float (Melder_half (pitchViewFrom_overt)), U" ", Function_getUnitText (my d_pitch.get(), Pitch_LEVEL_FREQUENCY, my p_pitch_unit, Function_UNIT_TEXT_SHORT | Function_UNIT_TEXT_GRAPHICAL)); } if (! NUMdefined (pitchCursor_hidden) || Graphics_dyWCtoMM (my d_graphics, pitchViewTo_hidden - pitchCursor_hidden) > 5.0) { Graphics_setTextAlignment (my d_graphics, Graphics_LEFT, Graphics_TOP); Graphics_text (my d_graphics, my d_endWindow, pitchViewTo_hidden, Melder_float (Melder_half (pitchViewTo_overt)), U" ", Function_getUnitText (my d_pitch.get(), Pitch_LEVEL_FREQUENCY, my p_pitch_unit, Function_UNIT_TEXT_SHORT | Function_UNIT_TEXT_GRAPHICAL)); } } else { Graphics_setTextAlignment (my d_graphics, Graphics_CENTRE, Graphics_HALF); Graphics_setFontSize (my d_graphics, 10); Graphics_text (my d_graphics, 0.5 * (my d_startWindow + my d_endWindow), 0.5 * (pitchViewFrom_hidden + pitchViewTo_hidden), U"(Cannot show pitch contour. Zoom out or change bottom of pitch range in pitch settings.)"); Graphics_setFontSize (my d_graphics, 12); } Graphics_setColour (my d_graphics, Graphics_BLACK); } if (my p_intensity_show) { double intensityCursor = NUMundefined; Graphics_Colour textColour; int alignment; double y; if (! my p_pitch_show) textColour = Graphics_GREEN, alignment = Graphics_LEFT, y = my d_endWindow; else if (! my p_spectrogram_show && ! my p_formant_show) textColour = Graphics_GREEN, alignment = Graphics_RIGHT, y = my d_startWindow; else textColour = my p_spectrogram_show ? Graphics_LIME : Graphics_GREEN, alignment = Graphics_RIGHT, y = my d_endWindow; if (my p_intensity_viewTo > my p_intensity_viewFrom) { Graphics_setWindow (my d_graphics, my d_startWindow, my d_endWindow, my p_intensity_viewFrom, my p_intensity_viewTo); if (my d_intensity) { if (my d_startSelection == my d_endSelection) { intensityCursor = Vector_getValueAtX (my d_intensity.get(), my d_startSelection, Vector_CHANNEL_1, Vector_VALUE_INTERPOLATION_LINEAR); } else { intensityCursor = Intensity_getAverage (my d_intensity.get(), my d_startSelection, my d_endSelection, my p_intensity_averagingMethod); } } Graphics_setColour (my d_graphics, textColour); bool intensityCursorVisible = NUMdefined (intensityCursor) && intensityCursor > my p_intensity_viewFrom && intensityCursor < my p_intensity_viewTo; if (intensityCursorVisible) { static const char32 *methodString [] = { U" (.5)", U" (μE)", U" (μS)", U" (μ)" }; Graphics_setTextAlignment (my d_graphics, alignment, Graphics_HALF); Graphics_text (my d_graphics, y, intensityCursor, Melder_float (Melder_half (intensityCursor)), U" dB", my d_startSelection == my d_endSelection ? U"" : methodString [my p_intensity_averagingMethod]); } if (! intensityCursorVisible || Graphics_dyWCtoMM (my d_graphics, intensityCursor - my p_intensity_viewFrom) > 5.0) { Graphics_setTextAlignment (my d_graphics, alignment, Graphics_BOTTOM); Graphics_text (my d_graphics, y, my p_intensity_viewFrom - Graphics_dyMMtoWC (my d_graphics, 0.5), Melder_float (Melder_half (my p_intensity_viewFrom)), U" dB"); } if (! intensityCursorVisible || Graphics_dyWCtoMM (my d_graphics, my p_intensity_viewTo - intensityCursor) > 5.0) { Graphics_setTextAlignment (my d_graphics, alignment, Graphics_TOP); Graphics_text (my d_graphics, y, my p_intensity_viewTo, Melder_float (Melder_half (my p_intensity_viewTo)), U" dB"); } Graphics_setColour (my d_graphics, Graphics_BLACK); } } if (my p_spectrogram_show || my p_formant_show) { bool frequencyCursorVisible = my d_spectrogram_cursor > my p_spectrogram_viewFrom && my d_spectrogram_cursor < my p_spectrogram_viewTo; Graphics_setWindow (my d_graphics, my d_startWindow, my d_endWindow, my p_spectrogram_viewFrom, my p_spectrogram_viewTo); /* * Range marks. */ Graphics_setLineType (my d_graphics, Graphics_DRAWN); Graphics_setColour (my d_graphics, Graphics_BLACK); if (! frequencyCursorVisible || Graphics_dyWCtoMM (my d_graphics, my d_spectrogram_cursor - my p_spectrogram_viewFrom) > 5.0) { Graphics_setTextAlignment (my d_graphics, Graphics_RIGHT, Graphics_BOTTOM); Graphics_text (my d_graphics, my d_startWindow, my p_spectrogram_viewFrom - Graphics_dyMMtoWC (my d_graphics, 0.5), Melder_float (Melder_half (my p_spectrogram_viewFrom)), U" Hz"); } if (! frequencyCursorVisible || Graphics_dyWCtoMM (my d_graphics, my p_spectrogram_viewTo - my d_spectrogram_cursor) > 5.0) { Graphics_setTextAlignment (my d_graphics, Graphics_RIGHT, Graphics_TOP); Graphics_text (my d_graphics, my d_startWindow, my p_spectrogram_viewTo, Melder_float (Melder_half (my p_spectrogram_viewTo)), U" Hz"); } /* * Cursor lines. */ Graphics_setLineType (my d_graphics, Graphics_DOTTED); Graphics_setColour (my d_graphics, Graphics_RED); if (frequencyCursorVisible) { double x = my d_startWindow, y = my d_spectrogram_cursor; Graphics_setTextAlignment (my d_graphics, Graphics_RIGHT, Graphics_HALF); Graphics_text (my d_graphics, x, y, Melder_float (Melder_half (y)), U" Hz"); Graphics_line (my d_graphics, x, y, my d_endWindow, y); } /* if (our startSelection >= our startWindow && our startSelection <= our endWindow) Graphics_line (our graphics, our startSelection, our p_spectrogram_viewFrom, our startSelection, our p_spectrogram_viewTo); if (our endSelection > our startWindow && our endSelection < our endWindow && our endSelection != our startSelection) Graphics_line (our graphics, our endSelection, our p_spectrogram_viewFrom, our endSelection, our p_spectrogram_viewTo);*/ /* * Cadre. */ Graphics_setLineType (my d_graphics, Graphics_DRAWN); Graphics_setColour (my d_graphics, Graphics_BLACK); Graphics_rectangle (my d_graphics, my d_startWindow, my d_endWindow, my p_spectrogram_viewFrom, my p_spectrogram_viewTo); } } void structTimeSoundAnalysisEditor :: v_draw_analysis () { TimeSoundAnalysisEditor_v_draw_analysis (this); } void structTimeSoundAnalysisEditor :: v_draw_analysis_pulses () { TimeSoundAnalysisEditor_computePulses (this); if (our p_pulses_show && our d_endWindow - our d_startWindow <= our p_longestAnalysis && our d_pulses) { PointProcess point = our d_pulses.get(); Graphics_setWindow (our d_graphics, our d_startWindow, our d_endWindow, -1.0, 1.0); Graphics_setColour (our d_graphics, Graphics_BLUE); if (point -> nt < 2000) for (long i = 1; i <= point -> nt; i ++) { double t = point -> t [i]; if (t >= our d_startWindow && t <= our d_endWindow) Graphics_line (our d_graphics, t, -0.9, t, 0.9); } Graphics_setColour (our d_graphics, Graphics_BLACK); } } int structTimeSoundAnalysisEditor :: v_click (double xbegin, double ybegin, bool shiftKeyPressed) { if (our p_pitch_show) { //Melder_warning (xbegin, U" ", ybegin); if (xbegin >= our d_endWindow && ybegin > 0.48 && ybegin <= 0.50) { our pref_pitch_ceiling () = our p_pitch_ceiling = our p_pitch_ceiling * 1.26; our d_pitch. reset(); our d_intensity.reset(); our d_pulses. reset(); return 1; } if (xbegin >= our d_endWindow && ybegin > 0.46 && ybegin <= 0.48) { our pref_pitch_ceiling () = our p_pitch_ceiling = our p_pitch_ceiling / 1.26; our d_pitch. reset(); our d_intensity. reset(); our d_pulses. reset(); return 1; } } return TimeSoundAnalysisEditor_Parent :: v_click (xbegin, ybegin, shiftKeyPressed); } void TimeSoundAnalysisEditor_init (TimeSoundAnalysisEditor me, const char32 *title, Function data, Sampled sound, bool ownSound) { TimeSoundEditor_init (me, title, data, sound, ownSound); if (my v_hasAnalysis ()) { if (my p_log1_toLogFile == false && my p_log1_toInfoWindow == false) { my pref_log1_toLogFile () = my p_log1_toLogFile = true; my pref_log1_toInfoWindow () = my p_log1_toInfoWindow = true; } if (my p_log2_toLogFile == false && my p_log2_toInfoWindow == false) { my pref_log2_toLogFile () = my p_log2_toLogFile = true; my pref_log2_toInfoWindow () = my p_log2_toInfoWindow = true; } if (! my v_hasSpectrogram ()) my p_spectrogram_show = false; if (! my v_hasPitch ()) my p_pitch_show = false; if (! my v_hasIntensity ()) my p_intensity_show = false; if (! my v_hasFormants ()) my p_formant_show = false; if (! my v_hasPulses ()) my p_pulses_show = false; } } /* End of file TimeSoundAnalysisEditor.cpp */ praat-6.0.04/fon/TimeSoundAnalysisEditor.h000066400000000000000000000106611261542461700204410ustar00rootroot00000000000000#ifndef _TimeSoundAnalysisEditor_h_ #define _TimeSoundAnalysisEditor_h_ /* TimeSoundAnalysisEditor.h * * Copyright (C) 1992-2011,2012,2013,2014 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 2002/07/16 GPL * pb 2002/11/19 added show-widgets * pb 2002/11/19 added pulses * pb 2003/05/20 longestAnalysis replaces pitch.timeSteps, pitch.speckle, formant.maximumDuration * pb 2003/05/21 pitch floor and ceiling replace the view and analysis ranges * pb 2003/05/27 spectrogram maximum and autoscaling * pb 2003/08/23 formant.numberOfTimeSteps * pb 2003/09/16 advanced pitch settings: pitch.timeStep, pitch.timeStepsPerView, pitch.viewFrom, pitch.viewTo * pb 2003/09/18 advanced formant settings: formant.timeStep, formant.timeStepsPerView * pb 2003/10/01 time step settings: timeStepStrategy, fixedTimeStep, numberOfTimeStepsPerView * pb 2004/02/15 highlight methods * pb 2004/07/14 pulses.maximumAmplitudeFactor * pb 2004/10/24 intensity.averagingMethod * pb 2004/10/27 intensity.subtractMeanPressure * pb 2005/01/11 getBottomOfSoundAndAnalysisArea * pb 2005/06/16 units * pb 2005/12/07 arrowScrollStep * pb 2007/06/10 wchar * pb 2007/09/02 direct drawing to picture window * pb 2007/09/08 inherit from TimeSoundEditor * pb 2007/11/01 direct intensity, formants, and pulses drawing * pb 2007/12/02 split off TimeSoundAnalysisEditor_enums.h * pb 2011/03/23 C++ * pb 2011/07/15 C++ */ #include "TimeSoundEditor.h" #include "Sound_and_Spectrogram.h" #include "Pitch.h" #include "Intensity.h" #include "Formant.h" #include "PointProcess.h" #include "TimeSoundAnalysisEditor_enums.h" Thing_define (TimeSoundAnalysisEditor, TimeSoundEditor) { autoSpectrogram d_spectrogram; double d_spectrogram_cursor; autoPitch d_pitch; autoIntensity d_intensity; autoFormant d_formant; autoPointProcess d_pulses; GuiMenuItem spectrogramToggle, pitchToggle, intensityToggle, formantToggle, pulsesToggle; void v_destroy () override; void v_info () override; void v_createMenuItems_query (EditorMenu menu) override; int v_click (double xWC, double yWC, bool shiftKeyPressed) override; void v_createMenuItems_view_sound (EditorMenu menu) override; double v_getBottomOfSoundArea () override { return p_spectrogram_show || p_pitch_show || p_intensity_show || p_formant_show ? 0.5 : 0.0; } virtual bool v_hasAnalysis () { return true; } virtual bool v_hasSpectrogram () { return true; } virtual bool v_hasPitch () { return true; } virtual bool v_hasIntensity () { return true; } virtual bool v_hasFormants () { return true; } virtual bool v_hasPulses () { return true; } virtual void v_reset_analysis (); virtual void v_createMenuItems_spectrum_picture (EditorMenu menu); virtual void v_createMenuItems_pitch_picture (EditorMenu menu); virtual void v_createMenuItems_intensity_picture (EditorMenu menu); virtual void v_createMenuItems_formant_picture (EditorMenu menu); virtual void v_createMenuItems_pulses_picture (EditorMenu menu); virtual void v_draw_analysis (); virtual void v_draw_analysis_pulses (); virtual void v_createMenuItems_query_log (EditorMenu menu); virtual void v_createMenus_analysis (); virtual void v_createMenuItems_view_sound_analysis (EditorMenu menu); #include "TimeSoundAnalysisEditor_prefs.h" }; void TimeSoundAnalysisEditor_init (TimeSoundAnalysisEditor me, const char32 *title, Function data, Sampled sound, bool ownSound); void TimeSoundAnalysisEditor_computeSpectrogram (TimeSoundAnalysisEditor me); void TimeSoundAnalysisEditor_computePitch (TimeSoundAnalysisEditor me); void TimeSoundAnalysisEditor_computeIntensity (TimeSoundAnalysisEditor me); void TimeSoundAnalysisEditor_computeFormants (TimeSoundAnalysisEditor me); void TimeSoundAnalysisEditor_computePulses (TimeSoundAnalysisEditor me); /* End of file TimeSoundAnalysisEditor.h */ #endif praat-6.0.04/fon/TimeSoundAnalysisEditor_enums.h000066400000000000000000000053341261542461700216510ustar00rootroot00000000000000/* TimeSoundAnalysisEditor_enums.h * * Copyright (C) 2007,2013,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ enums_begin (kTimeSoundAnalysisEditor_timeStepStrategy, 1) enums_add (kTimeSoundAnalysisEditor_timeStepStrategy, 1, AUTOMATIC, U"automatic") enums_add (kTimeSoundAnalysisEditor_timeStepStrategy, 2, FIXED, U"fixed") enums_add (kTimeSoundAnalysisEditor_timeStepStrategy, 3, VIEW_DEPENDENT, U"view-dependent") enums_end (kTimeSoundAnalysisEditor_timeStepStrategy, 3, AUTOMATIC) enums_begin (kTimeSoundAnalysisEditor_pitch_drawingMethod, 1) enums_add (kTimeSoundAnalysisEditor_pitch_drawingMethod, 1, CURVE, U"curve") enums_add (kTimeSoundAnalysisEditor_pitch_drawingMethod, 2, SPECKLE, U"speckles") enums_alt (kTimeSoundAnalysisEditor_pitch_drawingMethod, SPECKLE, U"speckle") enums_add (kTimeSoundAnalysisEditor_pitch_drawingMethod, 3, AUTOMATIC, U"automatic") enums_end (kTimeSoundAnalysisEditor_pitch_drawingMethod, 3, AUTOMATIC) enums_begin (kTimeSoundAnalysisEditor_pitch_analysisMethod, 1) enums_add (kTimeSoundAnalysisEditor_pitch_analysisMethod, 1, AUTOCORRELATION, U"autocorrelation") enums_add (kTimeSoundAnalysisEditor_pitch_analysisMethod, 2, CROSS_CORRELATION, U"cross-correlation") enums_end (kTimeSoundAnalysisEditor_pitch_analysisMethod, 2, AUTOCORRELATION) enums_begin (kTimeSoundAnalysisEditor_intensity_averagingMethod, 0) enums_add (kTimeSoundAnalysisEditor_intensity_averagingMethod, 0, MEDIAN, U"median") // BUG: this HAS to be zero! enums_add (kTimeSoundAnalysisEditor_intensity_averagingMethod, 1, MEAN_ENERGY, U"mean energy") enums_add (kTimeSoundAnalysisEditor_intensity_averagingMethod, 2, MEAN_SONES, U"mean sones") enums_add (kTimeSoundAnalysisEditor_intensity_averagingMethod, 3, MEAN_DB, U"mean dB") enums_end (kTimeSoundAnalysisEditor_intensity_averagingMethod, 3, MEAN_ENERGY) enums_begin (kTimeSoundAnalysisEditor_formant_analysisMethod, 1) enums_add (kTimeSoundAnalysisEditor_formant_analysisMethod, 1, BURG, U"Burg") enums_end (kTimeSoundAnalysisEditor_formant_analysisMethod, 1, BURG) /* End of file TimeSoundAnalysisEditor_enums.h */ praat-6.0.04/fon/TimeSoundAnalysisEditor_prefs.h000066400000000000000000000211671261542461700216430ustar00rootroot00000000000000/* TimeSoundAnalysisEditor_prefs.h * * Copyright (C) 2013,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ prefs_begin (TimeSoundAnalysisEditor) prefs_add_double_with_data (TimeSoundAnalysisEditor, longestAnalysis, 1, U"10.0") // seconds prefs_add_enum_with_data (TimeSoundAnalysisEditor, timeStepStrategy, 1, kTimeSoundAnalysisEditor_timeStepStrategy, DEFAULT) prefs_add_double_with_data (TimeSoundAnalysisEditor, fixedTimeStep, 1, U"0.01") // seconds prefs_add_long_with_data (TimeSoundAnalysisEditor, numberOfTimeStepsPerView, 1, U"100") prefs_add_bool_with_data (TimeSoundAnalysisEditor, spectrogram_show, 1, true) prefs_add_double_with_data (TimeSoundAnalysisEditor, spectrogram_viewFrom, 2, U"0.0") // Hz prefs_add_double_with_data (TimeSoundAnalysisEditor, spectrogram_viewTo, 2, U"5000.0") // Hz prefs_add_double_with_data (TimeSoundAnalysisEditor, spectrogram_windowLength, 2, U"0.005") // seconds prefs_add_double_with_data (TimeSoundAnalysisEditor, spectrogram_dynamicRange, 2, U"70.0") // dB prefs_add_long_with_data (TimeSoundAnalysisEditor, spectrogram_timeSteps, 2, U"1000") prefs_add_long_with_data (TimeSoundAnalysisEditor, spectrogram_frequencySteps, 2, U"250") prefs_add_enum_with_data (TimeSoundAnalysisEditor, spectrogram_method, 2, kSound_to_Spectrogram_method, DEFAULT) prefs_add_enum_with_data (TimeSoundAnalysisEditor, spectrogram_windowShape, 2, kSound_to_Spectrogram_windowShape, DEFAULT) prefs_add_bool_with_data (TimeSoundAnalysisEditor, spectrogram_autoscaling, 2, true) prefs_add_double_with_data (TimeSoundAnalysisEditor, spectrogram_maximum, 2, U"100.0") // dB/Hz prefs_add_double_with_data (TimeSoundAnalysisEditor, spectrogram_preemphasis, 2, U"6.0") // dB/octave prefs_add_double_with_data (TimeSoundAnalysisEditor, spectrogram_dynamicCompression, 2, U"0.0") // 0..1 prefs_add_bool_with_data (TimeSoundAnalysisEditor, spectrogram_picture_garnish, 1, true) prefs_add_bool_with_data (TimeSoundAnalysisEditor, pitch_show, 1, true) prefs_add_double_with_data (TimeSoundAnalysisEditor, pitch_floor, 1, U"75.0") prefs_add_double_with_data (TimeSoundAnalysisEditor, pitch_ceiling, 1, U"500.0") prefs_add_enum_with_data (TimeSoundAnalysisEditor, pitch_unit, 1, kPitch_unit, DEFAULT) prefs_add_enum_with_data (TimeSoundAnalysisEditor, pitch_drawingMethod, 1, kTimeSoundAnalysisEditor_pitch_drawingMethod, DEFAULT) prefs_add_double_with_data (TimeSoundAnalysisEditor, pitch_viewFrom, 1, U"0.0 (= auto)") prefs_add_double_with_data (TimeSoundAnalysisEditor, pitch_viewTo, 1, U"0.0 (= auto)") prefs_add_enum_with_data (TimeSoundAnalysisEditor, pitch_method, 1, kTimeSoundAnalysisEditor_pitch_analysisMethod, DEFAULT) prefs_add_bool_with_data (TimeSoundAnalysisEditor, pitch_veryAccurate, 1, false) prefs_add_long_with_data (TimeSoundAnalysisEditor, pitch_maximumNumberOfCandidates, 1, U"15") prefs_add_double_with_data (TimeSoundAnalysisEditor, pitch_silenceThreshold, 1, U"0.03") prefs_add_double_with_data (TimeSoundAnalysisEditor, pitch_voicingThreshold, 1, U"0.45") prefs_add_double_with_data (TimeSoundAnalysisEditor, pitch_octaveCost, 1, U"0.01") prefs_add_double_with_data (TimeSoundAnalysisEditor, pitch_octaveJumpCost, 1, U"0.35") prefs_add_double_with_data (TimeSoundAnalysisEditor, pitch_voicedUnvoicedCost, 1, U"0.14") prefs_add_bool_with_data (TimeSoundAnalysisEditor, pitch_picture_speckle, 1, false) prefs_add_bool_with_data (TimeSoundAnalysisEditor, pitch_picture_garnish, 1, true) prefs_add_bool_with_data (TimeSoundAnalysisEditor, intensity_show, 1, false) prefs_add_double_with_data (TimeSoundAnalysisEditor, intensity_viewFrom, 1, U"50.0") // dB prefs_add_double_with_data (TimeSoundAnalysisEditor, intensity_viewTo, 1, U"100.0") // dB prefs_add_enum_with_data (TimeSoundAnalysisEditor, intensity_averagingMethod, 1, kTimeSoundAnalysisEditor_intensity_averagingMethod, DEFAULT) prefs_add_bool_with_data (TimeSoundAnalysisEditor, intensity_subtractMeanPressure, 1, true) prefs_add_bool_with_data (TimeSoundAnalysisEditor, intensity_picture_garnish, 1, true) prefs_add_bool_with_data (TimeSoundAnalysisEditor, formant_show, 1, false) prefs_add_double_with_data (TimeSoundAnalysisEditor, formant_maximumFormant, 1, U"5500.0") // Hz prefs_add_double_with_data (TimeSoundAnalysisEditor, formant_numberOfFormants, 1, U"5.0") prefs_add_double_with_data (TimeSoundAnalysisEditor, formant_windowLength, 1, U"0.025") // seconds prefs_add_double_with_data (TimeSoundAnalysisEditor, formant_dynamicRange, 1, U"30.0") // dB prefs_add_double_with_data (TimeSoundAnalysisEditor, formant_dotSize, 1, U"1.0") // mm prefs_add_enum_with_data (TimeSoundAnalysisEditor, formant_method, 1, kTimeSoundAnalysisEditor_formant_analysisMethod, BURG) prefs_add_double_with_data (TimeSoundAnalysisEditor, formant_preemphasisFrom, 1, U"50.0") // Hz prefs_add_bool_with_data (TimeSoundAnalysisEditor, formant_picture_garnish, 1, true) prefs_add_bool_with_data (TimeSoundAnalysisEditor, pulses_show, 1, false) prefs_add_double_with_data (TimeSoundAnalysisEditor, pulses_maximumPeriodFactor, 1, U"1.3") prefs_add_double_with_data (TimeSoundAnalysisEditor, pulses_maximumAmplitudeFactor, 1, U"1.6") prefs_add_bool_with_data (TimeSoundAnalysisEditor, pulses_picture_garnish, 1, true) prefs_add_bool_with_data (TimeSoundAnalysisEditor, log1_toInfoWindow, 1, true) prefs_add_bool_with_data (TimeSoundAnalysisEditor, log1_toLogFile, 1, true) prefs_add_bool_with_data (TimeSoundAnalysisEditor, log2_toInfoWindow, 1, true) prefs_add_bool_with_data (TimeSoundAnalysisEditor, log2_toLogFile, 1, true) #if defined (macintosh) prefs_add_string_with_data (TimeSoundAnalysisEditor, log1_fileName, 1, U"~/Desktop/Pitch Log") prefs_add_string_with_data (TimeSoundAnalysisEditor, log2_fileName, 1, U"~/Desktop/Formant Log") prefs_add_string_with_data (TimeSoundAnalysisEditor, logScript3, 1, U"~/Desktop/Log script 3") prefs_add_string_with_data (TimeSoundAnalysisEditor, logScript4, 1, U"~/Desktop/Log script 4") #elif defined (WIN32) prefs_add_string_with_data (TimeSoundAnalysisEditor, log1_fileName, 1, U"C:\\WINDOWS\\DESKTOP\\Pitch Log.txt") prefs_add_string_with_data (TimeSoundAnalysisEditor, log2_fileName, 1, U"C:\\WINDOWS\\DESKTOP\\Formant Log.txt") prefs_add_string_with_data (TimeSoundAnalysisEditor, logScript3, 1, U"C:\\WINDOWS\\DESKTOP\\Log script 3.praat") prefs_add_string_with_data (TimeSoundAnalysisEditor, logScript4, 1, U"C:\\WINDOWS\\DESKTOP\\Log script 4.praat") #else prefs_add_string_with_data (TimeSoundAnalysisEditor, log1_fileName, 1, U"~/pitch_log") prefs_add_string_with_data (TimeSoundAnalysisEditor, log2_fileName, 1, U"~/formant_log") prefs_add_string_with_data (TimeSoundAnalysisEditor, logScript3, 1, U"~/log_script3") prefs_add_string_with_data (TimeSoundAnalysisEditor, logScript4, 1, U"~/log_script4") #endif prefs_add_string_with_data (TimeSoundAnalysisEditor, log1_format, 1, U"Time 'time:6' seconds, pitch 'f0:2' Hz") prefs_add_string_with_data (TimeSoundAnalysisEditor, log2_format, 1, U"'t1:4''tab$''t2:4''tab$''f1:0''tab$''f2:0''tab$''f3:0'") prefs_end (TimeSoundAnalysisEditor) /* End of file TimeSoundAnalysisEditor_prefs.h */ praat-6.0.04/fon/TimeSoundEditor.cpp000066400000000000000000000773631261542461700173040ustar00rootroot00000000000000/* TimeSoundEditor.cpp * * Copyright (C) 1992-2012,2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "TimeSoundEditor.h" #include "EditorM.h" #include "UnicodeData.h" #include "enums_getText.h" #include "TimeSoundEditor_enums.h" #include "enums_getValue.h" #include "TimeSoundEditor_enums.h" Thing_implement (TimeSoundEditor, FunctionEditor, 0); #include "prefs_define.h" #include "TimeSoundEditor_prefs.h" #include "prefs_install.h" #include "TimeSoundEditor_prefs.h" #include "prefs_copyToInstance.h" #include "TimeSoundEditor_prefs.h" /********** Thing methods **********/ void structTimeSoundEditor :: v_destroy () { if (d_ownSound) forget (d_sound.data); TimeSoundEditor_Parent :: v_destroy (); } void structTimeSoundEditor :: v_info () { TimeSoundEditor_Parent :: v_info (); /* Sound flags: */ MelderInfo_writeLine (U"Sound scaling strategy: ", kTimeSoundEditor_scalingStrategy_getText (p_sound_scalingStrategy)); } /***** FILE MENU *****/ static void menu_cb_DrawVisibleSound (EDITOR_ARGS) { EDITOR_IAM (TimeSoundEditor); EDITOR_FORM (U"Draw visible sound", 0) my v_form_pictureWindow (cmd); LABEL (U"", U"Sound:") BOOLEAN (U"Preserve times", my default_picture_preserveTimes ()); REAL (U"left Vertical range", my default_picture_bottom ()) REAL (U"right Vertical range", my default_picture_top ()) my v_form_pictureMargins (cmd); my v_form_pictureSelection (cmd); BOOLEAN (U"Garnish", my default_picture_garnish ()); EDITOR_OK my v_ok_pictureWindow (cmd); SET_INTEGER (U"Preserve times", my pref_picture_preserveTimes ()); SET_REAL (U"left Vertical range", my pref_picture_bottom ()); SET_REAL (U"right Vertical range", my pref_picture_top ()); my v_ok_pictureMargins (cmd); my v_ok_pictureSelection (cmd); SET_INTEGER (U"Garnish", my pref_picture_garnish ()); EDITOR_DO my v_do_pictureWindow (cmd); my pref_picture_preserveTimes () = GET_INTEGER (U"Preserve times"); my pref_picture_bottom () = GET_REAL (U"left Vertical range"); my pref_picture_top () = GET_REAL (U"right Vertical range"); my v_do_pictureMargins (cmd); my v_do_pictureSelection (cmd); my pref_picture_garnish () = GET_INTEGER (U"Garnish"); if (my d_longSound.data == NULL && my d_sound.data == NULL) Melder_throw (U"There is no sound to draw."); autoSound publish = my d_longSound.data ? LongSound_extractPart (my d_longSound.data, my d_startWindow, my d_endWindow, my pref_picture_preserveTimes ()) : Sound_extractPart (my d_sound.data, my d_startWindow, my d_endWindow, kSound_windowShape_RECTANGULAR, 1.0, my pref_picture_preserveTimes ()); Editor_openPraatPicture (me); Sound_draw (publish.peek(), my pictureGraphics, 0.0, 0.0, my pref_picture_bottom (), my pref_picture_top (), my pref_picture_garnish (), U"Curve"); FunctionEditor_garnish (me); Editor_closePraatPicture (me); EDITOR_END } static void menu_cb_DrawSelectedSound (EDITOR_ARGS) { EDITOR_IAM (TimeSoundEditor); EDITOR_FORM (U"Draw selected sound", 0) my v_form_pictureWindow (cmd); LABEL (U"", U"Sound:") BOOLEAN (U"Preserve times", my default_picture_preserveTimes ()); REAL (U"left Vertical range", my default_picture_bottom ()); REAL (U"right Vertical range", my default_picture_top ()); my v_form_pictureMargins (cmd); BOOLEAN (U"Garnish", my default_picture_garnish ()); EDITOR_OK my v_ok_pictureWindow (cmd); SET_INTEGER (U"Preserve times", my pref_picture_preserveTimes ()); SET_REAL (U"left Vertical range", my pref_picture_bottom ()); SET_REAL (U"right Vertical range", my pref_picture_top ()); my v_ok_pictureMargins (cmd); SET_INTEGER (U"Garnish", my pref_picture_garnish ()); EDITOR_DO my v_do_pictureWindow (cmd); my pref_picture_preserveTimes () = GET_INTEGER (U"Preserve times"); my pref_picture_bottom () = GET_REAL (U"left Vertical range"); my pref_picture_top () = GET_REAL (U"right Vertical range"); my v_do_pictureMargins (cmd); my pref_picture_garnish () = GET_INTEGER (U"Garnish"); if (my d_longSound.data == NULL && my d_sound.data == NULL) Melder_throw (U"There is no sound to draw."); autoSound publish = my d_longSound.data ? LongSound_extractPart (my d_longSound.data, my d_startSelection, my d_endSelection, my pref_picture_preserveTimes ()) : Sound_extractPart (my d_sound.data, my d_startSelection, my d_endSelection, kSound_windowShape_RECTANGULAR, 1.0, my pref_picture_preserveTimes ()); Editor_openPraatPicture (me); Sound_draw (publish.peek(), my pictureGraphics, 0.0, 0.0, my pref_picture_bottom (), my pref_picture_top (), my pref_picture_garnish (), U"Curve"); Editor_closePraatPicture (me); EDITOR_END } static void do_ExtractSelectedSound (TimeSoundEditor me, bool preserveTimes) { autoSound extract; if (my d_endSelection <= my d_startSelection) Melder_throw (U"No selection."); if (my d_longSound.data) { extract = LongSound_extractPart (my d_longSound.data, my d_startSelection, my d_endSelection, preserveTimes); } else if (my d_sound.data) { extract = Sound_extractPart (my d_sound.data, my d_startSelection, my d_endSelection, kSound_windowShape_RECTANGULAR, 1.0, preserveTimes); } Editor_broadcastPublication (me, extract.transfer()); } static void menu_cb_ExtractSelectedSound_timeFromZero (EDITOR_ARGS) { EDITOR_IAM (TimeSoundEditor); do_ExtractSelectedSound (me, false); } static void menu_cb_ExtractSelectedSound_preserveTimes (EDITOR_ARGS) { EDITOR_IAM (TimeSoundEditor); do_ExtractSelectedSound (me, true); } static void menu_cb_ExtractSelectedSound_windowed (EDITOR_ARGS) { EDITOR_IAM (TimeSoundEditor); EDITOR_FORM (U"Extract selected sound (windowed)", 0) WORD (U"Name", U"slice") OPTIONMENU_ENUM (U"Window shape", kSound_windowShape, my default_extract_windowShape ()) POSITIVE (U"Relative width", my default_extract_relativeWidth ()) BOOLEAN (U"Preserve times", my default_extract_preserveTimes ()) EDITOR_OK SET_ENUM (U"Window shape", kSound_windowShape, my pref_extract_windowShape ()) SET_REAL (U"Relative width", my pref_extract_relativeWidth ()) SET_INTEGER (U"Preserve times", my pref_extract_preserveTimes ()) EDITOR_DO Sound sound = my d_sound.data; Melder_assert (sound != NULL); my pref_extract_windowShape () = GET_ENUM (kSound_windowShape, U"Window shape"); my pref_extract_relativeWidth () = GET_REAL (U"Relative width"); my pref_extract_preserveTimes () = GET_INTEGER (U"Preserve times"); autoSound extract = Sound_extractPart (sound, my d_startSelection, my d_endSelection, my pref_extract_windowShape (), my pref_extract_relativeWidth (), my pref_extract_preserveTimes ()); Thing_setName (extract.peek(), GET_STRING (U"Name")); Editor_broadcastPublication (me, extract.transfer()); EDITOR_END } static void menu_cb_ExtractSelectedSoundForOverlap (EDITOR_ARGS) { EDITOR_IAM (TimeSoundEditor); EDITOR_FORM (U"Extract selected sound for overlap)", 0) WORD (U"Name", U"slice") POSITIVE (U"Overlap (s)", my default_extract_overlap ()) EDITOR_OK SET_REAL (U"Overlap", my pref_extract_overlap ()) EDITOR_DO Sound sound = my d_sound.data; Melder_assert (sound != NULL); my pref_extract_overlap () = GET_REAL (U"Overlap"); autoSound extract = Sound_extractPartForOverlap (sound, my d_startSelection, my d_endSelection, my pref_extract_overlap ()); Thing_setName (extract.peek(), GET_STRING (U"Name")); Editor_broadcastPublication (me, extract.transfer()); EDITOR_END } static void do_write (TimeSoundEditor me, MelderFile file, int format, int numberOfBitsPerSamplePoint) { if (my d_startSelection >= my d_endSelection) Melder_throw (U"No samples selected."); if (my d_longSound.data) { LongSound_writePartToAudioFile (my d_longSound.data, format, my d_startSelection, my d_endSelection, file, numberOfBitsPerSamplePoint); } else if (my d_sound.data) { Sound sound = my d_sound.data; double margin = 0.0; long nmargin = (long) floor (margin / sound -> dx); long first, last, numberOfSamples = Sampled_getWindowSamples (sound, my d_startSelection, my d_endSelection, & first, & last) + nmargin * 2; first -= nmargin; last += nmargin; if (numberOfSamples) { autoSound save = Sound_create (sound -> ny, 0.0, numberOfSamples * sound -> dx, numberOfSamples, sound -> dx, 0.5 * sound -> dx); long offset = first - 1; if (first < 1) first = 1; if (last > sound -> nx) last = sound -> nx; for (long channel = 1; channel <= sound -> ny; channel ++) { for (long i = first; i <= last; i ++) { save -> z [channel] [i - offset] = sound -> z [channel] [i]; } } Sound_writeToAudioFile (save.peek(), file, format, numberOfBitsPerSamplePoint); } } } static void menu_cb_WriteWav (EDITOR_ARGS) { EDITOR_IAM (TimeSoundEditor); EDITOR_FORM_WRITE (U"Save selected sound as WAV file", 0) Melder_sprint (defaultName,300, my d_longSound.data ? my d_longSound.data -> name : my d_sound.data -> name, U".wav"); EDITOR_DO_WRITE do_write (me, file, Melder_WAV, 16); EDITOR_END } static void menu_cb_SaveAs24BitWav (EDITOR_ARGS) { EDITOR_IAM (TimeSoundEditor); EDITOR_FORM_WRITE (U"Save selected sound as 24-bit WAV file", 0) Melder_assert (my d_longSound.data == NULL && my d_sound.data != NULL); Melder_sprint (defaultName,300, my d_sound.data -> name, U".wav"); EDITOR_DO_WRITE do_write (me, file, Melder_WAV, 24); EDITOR_END } static void menu_cb_SaveAs32BitWav (EDITOR_ARGS) { EDITOR_IAM (TimeSoundEditor); EDITOR_FORM_WRITE (U"Save selected sound as 32-bit WAV file", 0) Melder_assert (my d_longSound.data == NULL && my d_sound.data != NULL); Melder_sprint (defaultName,300, my d_sound.data -> name, U".wav"); EDITOR_DO_WRITE do_write (me, file, Melder_WAV, 32); EDITOR_END } static void menu_cb_WriteAiff (EDITOR_ARGS) { EDITOR_IAM (TimeSoundEditor); EDITOR_FORM_WRITE (U"Save selected sound as AIFF file", 0) Melder_sprint (defaultName,300, my d_longSound.data ? my d_longSound.data -> name : my d_sound.data -> name, U".aiff"); EDITOR_DO_WRITE do_write (me, file, Melder_AIFF, 16); EDITOR_END } static void menu_cb_WriteAifc (EDITOR_ARGS) { EDITOR_IAM (TimeSoundEditor); EDITOR_FORM_WRITE (U"Save selected sound as AIFC file", 0) Melder_sprint (defaultName,300, my d_longSound.data ? my d_longSound.data -> name : my d_sound.data -> name, U".aifc"); EDITOR_DO_WRITE do_write (me, file, Melder_AIFC, 16); EDITOR_END } static void menu_cb_WriteNextSun (EDITOR_ARGS) { EDITOR_IAM (TimeSoundEditor); EDITOR_FORM_WRITE (U"Save selected sound as NeXT/Sun file", 0) Melder_sprint (defaultName,300, my d_longSound.data ? my d_longSound.data -> name : my d_sound.data -> name, U".au"); EDITOR_DO_WRITE do_write (me, file, Melder_NEXT_SUN, 16); EDITOR_END } static void menu_cb_WriteNist (EDITOR_ARGS) { EDITOR_IAM (TimeSoundEditor); EDITOR_FORM_WRITE (U"Save selected sound as NIST file", 0) Melder_sprint (defaultName,300, my d_longSound.data ? my d_longSound.data -> name : my d_sound.data -> name, U".nist"); EDITOR_DO_WRITE do_write (me, file, Melder_NIST, 16); EDITOR_END } static void menu_cb_WriteFlac (EDITOR_ARGS) { EDITOR_IAM (TimeSoundEditor); EDITOR_FORM_WRITE (U"Save selected sound as FLAC file", 0) Melder_sprint (defaultName,300, my d_longSound.data ? my d_longSound.data -> name : my d_sound.data -> name, U".flac"); EDITOR_DO_WRITE do_write (me, file, Melder_FLAC, 16); EDITOR_END } void structTimeSoundEditor :: v_createMenuItems_file_draw (EditorMenu menu) { EditorMenu_addCommand (menu, U"Draw to picture window:", GuiMenu_INSENSITIVE, menu_cb_DrawVisibleSound /* dummy */); if (d_sound.data || d_longSound.data) { EditorMenu_addCommand (menu, U"Draw visible sound...", 0, menu_cb_DrawVisibleSound); drawButton = EditorMenu_addCommand (menu, U"Draw selected sound...", 0, menu_cb_DrawSelectedSound); } } void structTimeSoundEditor :: v_createMenuItems_file_extract (EditorMenu menu) { EditorMenu_addCommand (menu, U"Extract to objects window:", GuiMenu_INSENSITIVE, menu_cb_ExtractSelectedSound_preserveTimes /* dummy */); if (d_sound.data || d_longSound.data) { publishPreserveButton = EditorMenu_addCommand (menu, U"Extract selected sound (preserve times)", 0, menu_cb_ExtractSelectedSound_preserveTimes); EditorMenu_addCommand (menu, U"Extract sound selection (preserve times)", Editor_HIDDEN, menu_cb_ExtractSelectedSound_preserveTimes); EditorMenu_addCommand (menu, U"Extract selection (preserve times)", Editor_HIDDEN, menu_cb_ExtractSelectedSound_preserveTimes); publishButton = EditorMenu_addCommand (menu, U"Extract selected sound (time from 0)", 0, menu_cb_ExtractSelectedSound_timeFromZero); EditorMenu_addCommand (menu, U"Extract sound selection (time from 0)", Editor_HIDDEN, menu_cb_ExtractSelectedSound_timeFromZero); EditorMenu_addCommand (menu, U"Extract selection (time from 0)", Editor_HIDDEN, menu_cb_ExtractSelectedSound_timeFromZero); EditorMenu_addCommand (menu, U"Extract selection", Editor_HIDDEN, menu_cb_ExtractSelectedSound_timeFromZero); if (d_sound.data) { publishWindowButton = EditorMenu_addCommand (menu, U"Extract selected sound (windowed)...", 0, menu_cb_ExtractSelectedSound_windowed); EditorMenu_addCommand (menu, U"Extract windowed sound selection...", Editor_HIDDEN, menu_cb_ExtractSelectedSound_windowed); EditorMenu_addCommand (menu, U"Extract windowed selection...", Editor_HIDDEN, menu_cb_ExtractSelectedSound_windowed); publishOverlapButton = EditorMenu_addCommand (menu, U"Extract selected sound for overlap...", 0, menu_cb_ExtractSelectedSoundForOverlap); } } } void structTimeSoundEditor :: v_createMenuItems_file_write (EditorMenu menu) { EditorMenu_addCommand (menu, U"Save to disk:", GuiMenu_INSENSITIVE, menu_cb_WriteWav /* dummy */); if (d_sound.data || d_longSound.data) { writeWavButton = EditorMenu_addCommand (menu, U"Save selected sound as WAV file...", 0, menu_cb_WriteWav); EditorMenu_addCommand (menu, U"Write selected sound to WAV file...", Editor_HIDDEN, menu_cb_WriteWav); EditorMenu_addCommand (menu, U"Write sound selection to WAV file...", Editor_HIDDEN, menu_cb_WriteWav); EditorMenu_addCommand (menu, U"Write selection to WAV file...", Editor_HIDDEN, menu_cb_WriteWav); if (d_sound.data) { d_saveAs24BitWavButton = EditorMenu_addCommand (menu, U"Save selected sound as 24-bit WAV file...", 0, menu_cb_SaveAs24BitWav); d_saveAs32BitWavButton = EditorMenu_addCommand (menu, U"Save selected sound as 32-bit WAV file...", 0, menu_cb_SaveAs32BitWav); } writeAiffButton = EditorMenu_addCommand (menu, U"Save selected sound as AIFF file...", 0, menu_cb_WriteAiff); EditorMenu_addCommand (menu, U"Write selected sound to AIFF file...", Editor_HIDDEN, menu_cb_WriteAiff); EditorMenu_addCommand (menu, U"Write sound selection to AIFF file...", Editor_HIDDEN, menu_cb_WriteAiff); EditorMenu_addCommand (menu, U"Write selection to AIFF file...", Editor_HIDDEN, menu_cb_WriteAiff); writeAifcButton = EditorMenu_addCommand (menu, U"Save selected sound as AIFC file...", 0, menu_cb_WriteAifc); EditorMenu_addCommand (menu, U"Write selected sound to AIFC file...", Editor_HIDDEN, menu_cb_WriteAifc); EditorMenu_addCommand (menu, U"Write sound selection to AIFC file...", Editor_HIDDEN, menu_cb_WriteAifc); EditorMenu_addCommand (menu, U"Write selection to AIFC file...", Editor_HIDDEN, menu_cb_WriteAifc); writeNextSunButton = EditorMenu_addCommand (menu, U"Save selected sound as Next/Sun file...", 0, menu_cb_WriteNextSun); EditorMenu_addCommand (menu, U"Write selected sound to Next/Sun file...", Editor_HIDDEN, menu_cb_WriteNextSun); EditorMenu_addCommand (menu, U"Write sound selection to Next/Sun file...", Editor_HIDDEN, menu_cb_WriteNextSun); EditorMenu_addCommand (menu, U"Write selection to Next/Sun file...", Editor_HIDDEN, menu_cb_WriteNextSun); writeNistButton = EditorMenu_addCommand (menu, U"Save selected sound as NIST file...", 0, menu_cb_WriteNist); EditorMenu_addCommand (menu, U"Write selected sound to NIST file...", Editor_HIDDEN, menu_cb_WriteNist); EditorMenu_addCommand (menu, U"Write sound selection to NIST file...", Editor_HIDDEN, menu_cb_WriteNist); EditorMenu_addCommand (menu, U"Write selection to NIST file...", Editor_HIDDEN, menu_cb_WriteNist); writeFlacButton = EditorMenu_addCommand (menu, U"Save selected sound as FLAC file...", 0, menu_cb_WriteFlac); EditorMenu_addCommand (menu, U"Write selected sound to FLAC file...", Editor_HIDDEN, menu_cb_WriteFlac); EditorMenu_addCommand (menu, U"Write sound selection to FLAC file...", Editor_HIDDEN, menu_cb_WriteFlac); } } void structTimeSoundEditor :: v_createMenuItems_file (EditorMenu menu) { TimeSoundEditor_Parent :: v_createMenuItems_file (menu); v_createMenuItems_file_draw (menu); EditorMenu_addCommand (menu, U"-- after file draw --", 0, NULL); v_createMenuItems_file_extract (menu); EditorMenu_addCommand (menu, U"-- after file extract --", 0, NULL); v_createMenuItems_file_write (menu); EditorMenu_addCommand (menu, U"-- after file write --", 0, NULL); } /********** QUERY MENU **********/ static void menu_cb_SoundInfo (EDITOR_ARGS) { EDITOR_IAM (TimeSoundEditor); Thing_info (my d_sound.data); } static void menu_cb_LongSoundInfo (EDITOR_ARGS) { EDITOR_IAM (TimeSoundEditor); Thing_info (my d_longSound.data); } void structTimeSoundEditor :: v_createMenuItems_query_info (EditorMenu menu) { TimeSoundEditor_Parent :: v_createMenuItems_query_info (menu); if (d_sound.data != NULL && d_sound.data != data) { EditorMenu_addCommand (menu, U"Sound info", 0, menu_cb_SoundInfo); } else if (d_longSound.data != NULL && d_longSound.data != data) { EditorMenu_addCommand (menu, U"LongSound info", 0, menu_cb_LongSoundInfo); } } /********** VIEW MENU **********/ static void menu_cb_soundScaling (EDITOR_ARGS) { EDITOR_IAM (TimeSoundEditor); EDITOR_FORM (U"Sound scaling", 0) OPTIONMENU_ENUM (U"Scaling strategy", kTimeSoundEditor_scalingStrategy, my default_sound_scalingStrategy ()) LABEL (U"", U"For \"fixed height\":"); POSITIVE (U"Height", my default_sound_scaling_height ()) LABEL (U"", U"For \"fixed range\":"); REAL (U"Minimum", my default_sound_scaling_minimum ()) REAL (U"Maximum", my default_sound_scaling_maximum ()) EDITOR_OK SET_ENUM (U"Scaling strategy", kTimeSoundEditor_scalingStrategy, my p_sound_scalingStrategy) SET_REAL (U"Height", my p_sound_scaling_height) SET_REAL (U"Minimum", my p_sound_scaling_minimum) SET_REAL (U"Maximum", my p_sound_scaling_maximum) EDITOR_DO my pref_sound_scalingStrategy () = my p_sound_scalingStrategy = GET_ENUM (kTimeSoundEditor_scalingStrategy, U"Scaling strategy"); my pref_sound_scaling_height () = my p_sound_scaling_height = GET_REAL (U"Height"); my pref_sound_scaling_minimum () = my p_sound_scaling_minimum = GET_REAL (U"Minimum"); my pref_sound_scaling_maximum () = my p_sound_scaling_maximum = GET_REAL (U"Maximum"); FunctionEditor_redraw (me); EDITOR_END } void structTimeSoundEditor :: v_createMenuItems_view (EditorMenu menu) { if (d_sound.data || d_longSound.data) v_createMenuItems_view_sound (menu); TimeSoundEditor_Parent :: v_createMenuItems_view (menu); } void structTimeSoundEditor :: v_createMenuItems_view_sound (EditorMenu menu) { EditorMenu_addCommand (menu, U"Sound scaling...", 0, menu_cb_soundScaling); EditorMenu_addCommand (menu, U"-- sound view --", 0, 0); } void structTimeSoundEditor :: v_updateMenuItems_file () { Sampled sound = d_sound.data != NULL ? (Sampled) d_sound.data : (Sampled) d_longSound.data; if (sound == NULL) return; long first, last, selectedSamples = Sampled_getWindowSamples (sound, d_startSelection, d_endSelection, & first, & last); if (drawButton) { GuiThing_setSensitive (drawButton, selectedSamples != 0); GuiThing_setSensitive (publishButton, selectedSamples != 0); GuiThing_setSensitive (publishPreserveButton, selectedSamples != 0); if (publishWindowButton) GuiThing_setSensitive (publishWindowButton, selectedSamples != 0); if (publishOverlapButton) GuiThing_setSensitive (publishOverlapButton, selectedSamples != 0); } GuiThing_setSensitive (writeWavButton, selectedSamples != 0); if (d_saveAs24BitWavButton) GuiThing_setSensitive (d_saveAs24BitWavButton, selectedSamples != 0); if (d_saveAs32BitWavButton) GuiThing_setSensitive (d_saveAs32BitWavButton, selectedSamples != 0); GuiThing_setSensitive (writeAiffButton, selectedSamples != 0); GuiThing_setSensitive (writeAifcButton, selectedSamples != 0); GuiThing_setSensitive (writeNextSunButton, selectedSamples != 0); GuiThing_setSensitive (writeNistButton, selectedSamples != 0); GuiThing_setSensitive (writeFlacButton, selectedSamples != 0); } void TimeSoundEditor_drawSound (TimeSoundEditor me, double globalMinimum, double globalMaximum) { Sound sound = my d_sound.data; LongSound longSound = my d_longSound.data; Melder_assert ((sound == NULL) != (longSound == NULL)); int nchan = sound ? sound -> ny : longSound -> numberOfChannels; bool cursorVisible = my d_startSelection == my d_endSelection && my d_startSelection >= my d_startWindow && my d_startSelection <= my d_endWindow; Graphics_setColour (my d_graphics, Graphics_BLACK); bool fits; try { fits = sound ? true : LongSound_haveWindow (longSound, my d_startWindow, my d_endWindow); } catch (MelderError) { int outOfMemory = str32str (Melder_getError (), U"memory") != NULL; if (Melder_debug == 9) Melder_flushError (); else Melder_clearError (); Graphics_setWindow (my d_graphics, 0, 1, 0, 1); Graphics_setTextAlignment (my d_graphics, Graphics_CENTRE, Graphics_HALF); Graphics_text (my d_graphics, 0.5, 0.5, outOfMemory ? U"(out of memory)" : U"(cannot read sound file)"); return; } if (! fits) { Graphics_setWindow (my d_graphics, 0, 1, 0, 1); Graphics_setTextAlignment (my d_graphics, Graphics_CENTRE, Graphics_HALF); Graphics_text (my d_graphics, 0.5, 0.5, U"(window too large; zoom in to see the data)"); return; } long first, last; if (Sampled_getWindowSamples (sound ? (Sampled) sound : (Sampled) longSound, my d_startWindow, my d_endWindow, & first, & last) <= 1) { Graphics_setWindow (my d_graphics, 0, 1, 0, 1); Graphics_setTextAlignment (my d_graphics, Graphics_CENTRE, Graphics_HALF); Graphics_text (my d_graphics, 0.5, 0.5, U"(zoom out to see the data)"); return; } const int numberOfVisibleChannels = nchan > 8 ? 8 : nchan; const int firstVisibleChannel = my d_sound.channelOffset + 1; int lastVisibleChannel = my d_sound.channelOffset + numberOfVisibleChannels; if (lastVisibleChannel > nchan) lastVisibleChannel = nchan; double maximumExtent = 0.0, visibleMinimum = 0.0, visibleMaximum = 0.0; if (my p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_BY_WINDOW) { if (longSound) LongSound_getWindowExtrema (longSound, my d_startWindow, my d_endWindow, firstVisibleChannel, & visibleMinimum, & visibleMaximum); else Matrix_getWindowExtrema (sound, first, last, firstVisibleChannel, firstVisibleChannel, & visibleMinimum, & visibleMaximum); for (int ichan = firstVisibleChannel + 1; ichan <= lastVisibleChannel; ichan ++) { double visibleChannelMinimum, visibleChannelMaximum; if (longSound) LongSound_getWindowExtrema (longSound, my d_startWindow, my d_endWindow, ichan, & visibleChannelMinimum, & visibleChannelMaximum); else Matrix_getWindowExtrema (sound, first, last, ichan, ichan, & visibleChannelMinimum, & visibleChannelMaximum); if (visibleChannelMinimum < visibleMinimum) visibleMinimum = visibleChannelMinimum; if (visibleChannelMaximum > visibleMaximum) visibleMaximum = visibleChannelMaximum; } maximumExtent = visibleMaximum - visibleMinimum; } for (int ichan = firstVisibleChannel; ichan <= lastVisibleChannel; ichan ++) { double cursorFunctionValue = longSound ? 0.0 : Vector_getValueAtX (sound, 0.5 * (my d_startSelection + my d_endSelection), ichan, 70); /* * BUG: this will only work for mono or stereo, until Graphics_function16 handles quadro. */ double ymin = (double) (numberOfVisibleChannels - ichan + my d_sound.channelOffset) / numberOfVisibleChannels; double ymax = (double) (numberOfVisibleChannels + 1 - ichan + my d_sound.channelOffset) / numberOfVisibleChannels; Graphics_Viewport vp = Graphics_insetViewport (my d_graphics, 0, 1, ymin, ymax); bool horizontal = false; double minimum = sound ? globalMinimum : -1.0, maximum = sound ? globalMaximum : 1.0; if (my p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_BY_WINDOW) { if (nchan > 2) { if (longSound) { LongSound_getWindowExtrema (longSound, my d_startWindow, my d_endWindow, ichan, & minimum, & maximum); } else { Matrix_getWindowExtrema (sound, first, last, ichan, ichan, & minimum, & maximum); } if (maximumExtent > 0.0) { double middle = 0.5 * (minimum + maximum); minimum = middle - 0.5 * maximumExtent; maximum = middle + 0.5 * maximumExtent; } } else { minimum = visibleMinimum; maximum = visibleMaximum; } } else if (my p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_BY_WINDOW_AND_CHANNEL) { if (longSound) { LongSound_getWindowExtrema (longSound, my d_startWindow, my d_endWindow, ichan, & minimum, & maximum); } else { Matrix_getWindowExtrema (sound, first, last, ichan, ichan, & minimum, & maximum); } } else if (my p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_FIXED_HEIGHT) { if (longSound) { LongSound_getWindowExtrema (longSound, my d_startWindow, my d_endWindow, ichan, & minimum, & maximum); } else { Matrix_getWindowExtrema (sound, first, last, ichan, ichan, & minimum, & maximum); } double channelExtent = my p_sound_scaling_height; double middle = 0.5 * (minimum + maximum); minimum = middle - 0.5 * channelExtent; maximum = middle + 0.5 * channelExtent; } else if (my p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_FIXED_RANGE) { minimum = my p_sound_scaling_minimum; maximum = my p_sound_scaling_maximum; } if (minimum == maximum) { horizontal = true; minimum -= 1; maximum += 1;} Graphics_setWindow (my d_graphics, my d_startWindow, my d_endWindow, minimum, maximum); if (horizontal) { Graphics_setTextAlignment (my d_graphics, Graphics_RIGHT, Graphics_HALF); double mid = 0.5 * (minimum + maximum); Graphics_text (my d_graphics, my d_startWindow, mid, Melder_float (Melder_half (mid))); } else { if (! cursorVisible || ! NUMdefined (cursorFunctionValue) || Graphics_dyWCtoMM (my d_graphics, cursorFunctionValue - minimum) > 5.0) { Graphics_setTextAlignment (my d_graphics, Graphics_RIGHT, Graphics_BOTTOM); Graphics_text (my d_graphics, my d_startWindow, minimum, Melder_float (Melder_half (minimum))); } if (! cursorVisible || ! NUMdefined (cursorFunctionValue) || Graphics_dyWCtoMM (my d_graphics, maximum - cursorFunctionValue) > 5.0) { Graphics_setTextAlignment (my d_graphics, Graphics_RIGHT, Graphics_TOP); Graphics_text (my d_graphics, my d_startWindow, maximum, Melder_float (Melder_half (maximum))); } } if (minimum < 0 && maximum > 0 && ! horizontal) { Graphics_setWindow (my d_graphics, 0, 1, minimum, maximum); if (! cursorVisible || ! NUMdefined (cursorFunctionValue) || fabs (Graphics_dyWCtoMM (my d_graphics, cursorFunctionValue - 0.0)) > 3.0) { Graphics_setTextAlignment (my d_graphics, Graphics_RIGHT, Graphics_HALF); Graphics_text (my d_graphics, 0, 0, U"0"); } Graphics_setColour (my d_graphics, Graphics_CYAN); Graphics_setLineType (my d_graphics, Graphics_DOTTED); Graphics_line (my d_graphics, 0, 0, 1, 0); Graphics_setLineType (my d_graphics, Graphics_DRAWN); } /* * Garnish the drawing area of each channel. */ Graphics_setWindow (my d_graphics, 0, 1, 0, 1); Graphics_setColour (my d_graphics, Graphics_CYAN); Graphics_innerRectangle (my d_graphics, 0, 1, 0, 1); Graphics_setColour (my d_graphics, Graphics_BLACK); if (nchan > 1) { Graphics_setTextAlignment (my d_graphics, Graphics_LEFT, Graphics_HALF); const char32 *channelName = my v_getChannelName (ichan); static MelderString channelLabel; MelderString_copy (& channelLabel, ( channelName ? U"ch" : U"Channel " ), ichan); if (channelName) MelderString_append (& channelLabel, U": ", channelName); if (ichan > 8 && ichan - my d_sound.channelOffset == 1) { MelderString_append (& channelLabel, U" " UNITEXT_UPWARDS_ARROW); } else if (ichan >= 8 && ichan - my d_sound.channelOffset == 8 && ichan < nchan) { MelderString_append (& channelLabel, U" " UNITEXT_DOWNWARDS_ARROW); } Graphics_text (my d_graphics, 1, 0.5, channelLabel.string); } /* * Draw a very thin separator line underneath. */ if (ichan < nchan) { /*Graphics_setColour (d_graphics, Graphics_BLACK);*/ Graphics_line (my d_graphics, 0, 0, 1, 0); } /* * Draw the samples. */ /*if (ichan == 1) FunctionEditor_SoundAnalysis_drawPulses (this);*/ if (sound) { Graphics_setWindow (my d_graphics, my d_startWindow, my d_endWindow, minimum, maximum); if (cursorVisible && NUMdefined (cursorFunctionValue)) FunctionEditor_drawCursorFunctionValue (me, cursorFunctionValue, Melder_float (Melder_half (cursorFunctionValue)), U""); Graphics_setColour (my d_graphics, Graphics_BLACK); Graphics_function (my d_graphics, sound -> z [ichan], first, last, Sampled_indexToX (sound, first), Sampled_indexToX (sound, last)); } else { Graphics_setWindow (my d_graphics, my d_startWindow, my d_endWindow, minimum * 32768, maximum * 32768); Graphics_function16 (my d_graphics, longSound -> buffer - longSound -> imin * nchan + (ichan - 1), nchan - 1, first, last, Sampled_indexToX (longSound, first), Sampled_indexToX (longSound, last)); } Graphics_resetViewport (my d_graphics, vp); } Graphics_setWindow (my d_graphics, 0, 1, 0, 1); Graphics_rectangle (my d_graphics, 0, 1, 0, 1); } int structTimeSoundEditor :: v_click (double xbegin, double ybegin, bool shiftKeyPressed) { Sound sound = d_sound.data; LongSound longSound = d_longSound.data; if ((sound == NULL) != (longSound == NULL)) { ybegin = (ybegin - v_getBottomOfSoundArea ()) / (1.0 - v_getBottomOfSoundArea ()); int nchan = sound ? sound -> ny : longSound -> numberOfChannels; if (nchan > 8) { trace (xbegin, U" ", ybegin, U" ", nchan, U" ", d_sound.channelOffset); if (xbegin >= d_endWindow && ybegin > 0.875 && ybegin <= 1.000 && d_sound.channelOffset > 0) { d_sound.channelOffset -= 8; return 1; } if (xbegin >= d_endWindow && ybegin > 0.000 && ybegin <= 0.125 && d_sound.channelOffset < nchan - 8) { d_sound.channelOffset += 8; return 1; } } } return TimeSoundEditor_Parent :: v_click (xbegin, ybegin, shiftKeyPressed); } void TimeSoundEditor_init (TimeSoundEditor me, const char32 *title, Function data, Sampled sound, bool ownSound) { my d_ownSound = ownSound; if (sound != NULL) { if (ownSound) { Melder_assert (Thing_isa (sound, classSound)); my d_sound.data = Data_copy ((Sound) sound); // deep copy; ownership transferred Matrix_getWindowExtrema (my d_sound.data, 1, my d_sound.data -> nx, 1, my d_sound.data -> ny, & my d_sound.minimum, & my d_sound.maximum); } else if (Thing_isa (sound, classSound)) { my d_sound.data = (Sound) sound; // reference copy; ownership not transferred Matrix_getWindowExtrema (my d_sound.data, 1, my d_sound.data -> nx, 1, my d_sound.data -> ny, & my d_sound.minimum, & my d_sound.maximum); } else if (Thing_isa (sound, classLongSound)) { my d_longSound.data = (LongSound) sound; my d_sound.minimum = -1.0, my d_sound.maximum = 1.0; } else { Melder_fatal (U"Invalid sound class in TimeSoundEditor::init."); } } FunctionEditor_init (me, title, data); } /* End of file TimeSoundEditor.cpp */ praat-6.0.04/fon/TimeSoundEditor.h000066400000000000000000000047131261542461700167360ustar00rootroot00000000000000#ifndef _TimeSoundEditor_h_ #define _TimeSoundEditor_h_ /* TimeSoundEditor.h * * Copyright (C) 1992-2012,2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "FunctionEditor.h" #include "Sound.h" #include "LongSound.h" #include "TimeSoundEditor_enums.h" struct TimeSoundEditor_sound { Sound data; double minimum, maximum; long channelOffset; }; Thing_define (TimeSoundEditor, FunctionEditor) { bool d_ownSound; struct TimeSoundEditor_sound d_sound; struct { LongSound data; } d_longSound; GuiMenuItem drawButton, publishButton, publishPreserveButton, publishWindowButton, publishOverlapButton; GuiMenuItem writeAiffButton, d_saveAs24BitWavButton, d_saveAs32BitWavButton, writeAifcButton, writeWavButton, writeNextSunButton, writeNistButton, writeFlacButton; void v_destroy () override; void v_info () override; void v_createMenuItems_file (EditorMenu menu) override; void v_createMenuItems_query_info (EditorMenu menu) override; void v_createMenuItems_file_draw (EditorMenu menu) override; void v_createMenuItems_file_extract (EditorMenu menu) override; void v_createMenuItems_file_write (EditorMenu menu) override; void v_createMenuItems_view (EditorMenu menu) override; int v_click (double xbegin, double ybegin, bool shiftKeyPressed) override; // catch channel scrolling virtual void v_createMenuItems_view_sound (EditorMenu menu); virtual void v_updateMenuItems_file (); virtual const char32 * v_getChannelName (long channelNumber) { (void) channelNumber; return NULL; } #include "TimeSoundEditor_prefs.h" }; void TimeSoundEditor_init (TimeSoundEditor me, const char32 *title, Function data, Sampled sound, bool ownSound); void TimeSoundEditor_drawSound (TimeSoundEditor me, double globalMinimum, double globalMaximum); /* End of file TimeSoundEditor.h */ #endif praat-6.0.04/fon/TimeSoundEditor_enums.h000066400000000000000000000024601261542461700201420ustar00rootroot00000000000000/* TimeSoundEditor_enums.h * * Copyright (C) 2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ enums_begin (kTimeSoundEditor_scalingStrategy, 1) enums_add (kTimeSoundEditor_scalingStrategy, 1, BY_WHOLE, U"by whole") enums_add (kTimeSoundEditor_scalingStrategy, 2, BY_WINDOW, U"by window") enums_add (kTimeSoundEditor_scalingStrategy, 3, BY_WINDOW_AND_CHANNEL, U"by window and channel") enums_add (kTimeSoundEditor_scalingStrategy, 4, FIXED_HEIGHT, U"fixed height") enums_add (kTimeSoundEditor_scalingStrategy, 5, FIXED_RANGE, U"fixed range") enums_end (kTimeSoundEditor_scalingStrategy, 5, BY_WINDOW) /* End of file TimeSoundEditor_enums.h */ praat-6.0.04/fon/TimeSoundEditor_prefs.h000066400000000000000000000035661261542461700201420ustar00rootroot00000000000000/* TimeSoundEditor_prefs.h * * Copyright (C) 2013,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ prefs_begin (TimeSoundEditor) prefs_add_enum_with_data (TimeSoundEditor, sound_scalingStrategy, 1, kTimeSoundEditor_scalingStrategy, DEFAULT) prefs_add_double_with_data (TimeSoundEditor, sound_scaling_height, 1, U"2.0") prefs_add_double_with_data (TimeSoundEditor, sound_scaling_minimum, 1, U"-1.0") prefs_add_double_with_data (TimeSoundEditor, sound_scaling_maximum, 1, U"1.0") prefs_add_bool (TimeSoundEditor, picture_preserveTimes, 1, true) prefs_add_double (TimeSoundEditor, picture_bottom, 1, U"0.0") prefs_add_double (TimeSoundEditor, picture_top, 1, U"0.0 (= auto)") prefs_add_bool (TimeSoundEditor, picture_garnish, 1, true) prefs_add_enum (TimeSoundEditor, extract_windowShape, 1, kSound_windowShape, DEFAULT) prefs_add_double (TimeSoundEditor, extract_relativeWidth, 1, U"1.0") prefs_add_bool (TimeSoundEditor, extract_preserveTimes, 1, true) prefs_add_double (TimeSoundEditor, extract_overlap, 1, U"0.01") prefs_end (TimeSoundEditor) /* End of file TimeSoundEditor_prefs.h */ praat-6.0.04/fon/Transition.cpp000066400000000000000000000174251261542461700163510ustar00rootroot00000000000000/* Transition.cpp * * Copyright (C) 1997-2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Transition.h" #include "NUM2.h" #include "Eigen.h" #include "oo_DESTROY.h" #include "Transition_def.h" #include "oo_COPY.h" #include "Transition_def.h" #include "oo_EQUAL.h" #include "Transition_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "Transition_def.h" #include "oo_WRITE_BINARY.h" #include "Transition_def.h" #include "oo_READ_TEXT.h" #include "Transition_def.h" #include "oo_READ_BINARY.h" #include "Transition_def.h" #include "oo_DESCRIPTION.h" #include "Transition_def.h" Thing_implement (Transition, Daata, 0); void structTransition :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Number of states: ", numberOfStates); } void structTransition :: v_writeText (MelderFile file) { texputi4 (file, numberOfStates, U"numberOfStates", 0,0,0,0,0); MelderFile_write (file, U"\nstateLabels []: "); if (numberOfStates < 1) MelderFile_write (file, U"(empty)"); MelderFile_write (file, U"\n"); for (long i = 1; i <= numberOfStates; i ++) { MelderFile_write (file, U"\""); if (stateLabels [i] != NULL) MelderFile_write (file, stateLabels [i]); MelderFile_write (file, U"\"\t"); } for (long i = 1; i <= numberOfStates; i ++) { MelderFile_write (file, U"\nstate [", i, U"]:"); for (long j = 1; j <= numberOfStates; j ++) { MelderFile_write (file, U"\t", data [i] [j]); } } } void Transition_init (Transition me, long numberOfStates) { if (numberOfStates < 1) Melder_throw (U"Cannot create empty matrix."); my numberOfStates = numberOfStates; my stateLabels = NUMvector (1, numberOfStates); my data = NUMmatrix (1, my numberOfStates, 1, my numberOfStates); } autoTransition Transition_create (long numberOfStates) { try { autoTransition me = Thing_new (Transition); Transition_init (me.peek(), numberOfStates); return me; } catch (MelderError) { Melder_throw (U"Transition not created."); } } static void NUMrationalize (double x, long *numerator, long *denominator) { double epsilon = 1e-6; *numerator = 1; for (*denominator = 1; *denominator <= 100000; (*denominator) ++) { double numerator_d = x * *denominator, rounded = round (numerator_d); if (fabs (rounded - numerator_d) < epsilon) { *numerator = (long) rounded; return; } } *denominator = 0; // failure } static void print4 (char *buffer, double value, int iformat, int width, int precision) { char formatString [40]; if (iformat == 4) { long numerator, denominator; NUMrationalize (value, & numerator, & denominator); if (numerator == 0) snprintf (buffer, 40, "0"); else if (denominator > 1) snprintf (buffer, 40, "%ld/%ld", numerator, denominator); else snprintf (buffer, 40, "%.7g", value); } else { snprintf (formatString, 40, "%%%d.%d%c", width, precision, iformat == 1 ? 'f' : iformat == 2 ? 'e' : 'g'); snprintf (buffer, 40, formatString, value); } } void Transition_drawAsNumbers (Transition me, Graphics g, int iformat, int precision) { double maxTextWidth = 0, maxTextHeight = 0; Graphics_setInner (g); Graphics_setWindow (g, 0.5, my numberOfStates + 0.5, 0, 1); double leftMargin = Graphics_dxMMtoWC (g, 1); double lineSpacing = Graphics_dyMMtoWC (g, 1.5 * Graphics_inqFontSize (g) * 25.4 / 72); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_BOTTOM); for (long col = 1; col <= my numberOfStates; col ++) { if (my stateLabels && my stateLabels [col] && my stateLabels [col] [0]) { Graphics_text (g, col, 1, my stateLabels [col]); if (maxTextHeight == 0.0) maxTextHeight = lineSpacing; } } for (long row = 1; row <= my numberOfStates; row ++) { double y = 1 - lineSpacing * (row - 1 + 0.7); Graphics_setTextAlignment (g, Graphics_RIGHT, Graphics_HALF); if (my stateLabels && my stateLabels [row]) { double textWidth = Graphics_textWidth (g, my stateLabels [row]); if (textWidth > maxTextWidth) maxTextWidth = textWidth; Graphics_text (g, 0.5 - leftMargin, y, my stateLabels [row]); } Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); for (long col = 1; col <= my numberOfStates; col ++) { char text [40]; print4 (text, my data [row] [col], iformat, 0, precision); Graphics_text (g, col, y, Melder_peek8to32 (text)); } } if (maxTextWidth != 0.0) Graphics_line (g, 0.5 - maxTextWidth - leftMargin, 1, my numberOfStates + 0.5, 1); if (maxTextHeight != 0.0) Graphics_line (g, 0.5, 1 + maxTextHeight, 0.5, 1 - lineSpacing * (my numberOfStates + 0.2)); Graphics_unsetInner (g); } static void Transition_transpose (Transition me) { for (long i = 1; i < my numberOfStates; i ++) { for (long j = i + 1; j <= my numberOfStates; j ++) { double temp = my data [i] [j]; my data [i] [j] = my data [j] [i]; my data [j] [i] = temp; } } } void Transition_eigen (Transition me, Matrix *out_eigenvectors, Matrix *out_eigenvalues) { *out_eigenvectors = NULL; *out_eigenvalues = NULL; bool transposed = false; try { autoEigen eigen = Thing_new (Eigen); Transition_transpose (me); Eigen_initFromSymmetricMatrix (eigen.peek(), my data, my numberOfStates); Transition_transpose (me); transposed = true; autoMatrix eigenvectors = Matrix_createSimple (my numberOfStates, my numberOfStates); autoMatrix eigenvalues = Matrix_createSimple (my numberOfStates, 1); for (long i = 1; i <= my numberOfStates; i ++) { eigenvalues -> z [i] [1] = eigen -> eigenvalues [i]; for (long j = 1; j <= my numberOfStates; j ++) eigenvectors -> z [i] [j] = eigen -> eigenvectors [j] [i]; } *out_eigenvectors = eigenvectors.transfer(); *out_eigenvalues = eigenvalues.transfer(); } catch (MelderError) { if (transposed) Transition_transpose (me); Melder_throw (me, U": eigenvectors not computed."); } } autoTransition Transition_power (Transition me, long power) { try { autoTransition thee = Data_copy (me); autoTransition him = Data_copy (me); for (long ipow = 2; ipow <= power; ipow ++) { double **tmp = his data; his data = thy data; thy data = tmp; // OPTIMIZE for (long irow = 1; irow <= my numberOfStates; irow ++) { for (long icol = 1; icol <= my numberOfStates; icol ++) { thy data [irow] [icol] = 0.0; for (long i = 1; i <= my numberOfStates; i ++) { thy data [irow] [icol] += his data [irow] [i] * my data [i] [icol]; } } } } return thee; } catch (MelderError) { Melder_throw (me, U": power not computed."); } } autoMatrix Transition_to_Matrix (Transition me) { try { autoMatrix thee = Matrix_createSimple (my numberOfStates, my numberOfStates); for (long i = 1; i <= my numberOfStates; i ++) for (long j = 1; j <= my numberOfStates; j ++) thy z [i] [j] = my data [i] [j]; return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Matrix."); } } autoTransition Matrix_to_Transition (Matrix me) { try { if (my nx != my ny) Melder_throw (U"Matrix should be square."); autoTransition thee = Transition_create (my nx); for (long i = 1; i <= my nx; i ++) for (long j = 1; j <= my nx; j ++) thy data [i] [j] = my z [i] [j]; return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Transition."); } } /* End of file Transition.cpp */ praat-6.0.04/fon/Transition.h000066400000000000000000000027051261542461700160110ustar00rootroot00000000000000#ifndef _Transition_h_ #define _Transition_h_ /* Transition.h * * Copyright (C) 1992-2011,2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Matrix.h" #include "Graphics.h" #include "Transition_def.h" oo_CLASS_CREATE (Transition, Daata); void Transition_init (Transition me, long numberOfStates); autoTransition Transition_create (long numberOfStates); void Transition_formula (Transition me, const char32 *formula); void Transition_drawAsNumbers (Transition me, Graphics g, int iformat, int precision); void Transition_eigen (Transition me, Matrix *eigenvectors, Matrix *eigenvalues); autoTransition Transition_power (Transition me, long power); autoMatrix Transition_to_Matrix (Transition me); autoTransition Matrix_to_Transition (Matrix me); /* End of file Transition.h */ #endif praat-6.0.04/fon/Transition_def.h000066400000000000000000000021221261542461700166200ustar00rootroot00000000000000/* Transition_def.h * * Copyright (C) 1997-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT Transition oo_DEFINE_CLASS (Transition, Daata) oo_LONG (numberOfStates) oo_STRING_VECTOR (stateLabels, numberOfStates) oo_DOUBLE_MATRIX (data, numberOfStates, numberOfStates) #if oo_DECLARING void v_info () override; #endif oo_END_CLASS (Transition) #undef ooSTRUCT /* End of file Transition_def.h */ praat-6.0.04/fon/Vector.cpp000066400000000000000000000362151261542461700154570ustar00rootroot00000000000000/* Vector.cpp * * Copyright (C) 1992-2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Vector.h" // // Vector::getVector () returns a channel or the average of all the channels. // double structVector :: v_getVector (long irow, long icol) { if (icol < 1 || icol > nx) return 0.0; if (ny == 1) return z [1] [icol]; // optimization if (irow == 0) { if (ny == 2) return 0.5 * (z [1] [icol] + z [2] [icol]); // optimization double sum = 0.0; for (long channel = 1; channel <= ny; channel ++) { sum += z [channel] [icol]; } return sum / ny; } Melder_assert (irow > 0 && irow <= ny); return z [irow] [icol]; } // // Vector::getFunction1 () returns a channel or the average of all the channels. // double structVector :: v_getFunction1 (long irow, double x) { double rcol = (x - x1) / dx + 1.0; long icol = floor (rcol); double dcol = rcol - icol; double z1; if (icol < 1 || icol > nx) { z1 = 0.0; // outside the definition region, Formula is expected to return zero } else if (ny == 1) { z1 = z [1] [icol]; // optimization } else if (irow == 0) { if (ny == 2) { z1 = 0.5 * (z [1] [icol] + z [2] [icol]); // optimization } else { double sum = 0.0; for (long channel = 1; channel <= ny; channel ++) { sum += z [channel] [icol]; } z1 = sum / ny; } } else { Melder_assert (irow > 0 && irow <= ny); z1 = z [irow] [icol]; } double z2; if (icol < 0 || icol >= nx) { z2 = 0.0; // outside the definition region, Formula is expected to return zero } else if (ny == 1) { z2 = z [1] [icol + 1]; // optimization } else if (irow == 0) { if (ny == 2) { z2 = 0.5 * (z [1] [icol + 1] + z [2] [icol + 1]); // optimization } else { double sum = 0.0; for (long channel = 1; channel <= ny; channel ++) { sum += z [channel] [icol + 1]; } z2 = sum / ny; } } else { Melder_assert (irow > 0 && irow <= ny); z2 = z [irow] [icol + 1]; } return (1.0 - dcol) * z1 + dcol * z2; } double structVector :: v_getValueAtSample (long isamp, long ilevel, int unit) { // Preconditions: // 1 <= isamp <= my nx // 0 <= ilevel <= my ny double value; if (ilevel > Vector_CHANNEL_AVERAGE) { value = z [ilevel] [isamp]; } else if (ny == 1) { value = z [1] [isamp]; // optimization } else if (ny == 2) { value = 0.5 * (z [1] [isamp] + z [2] [isamp]); // optimization } else { double sum = 0.0; for (long channel = 1; channel <= ny; channel ++) { sum += z [channel] [isamp]; } value = sum / ny; } return NUMdefined (value) ? v_convertStandardToSpecialUnit (value, ilevel, unit) : NUMundefined; } Thing_implement (Vector, Matrix, 2); /***** Get content. *****/ // // Vector_getValueAtX () returns the average of all the interpolated channels. // double Vector_getValueAtX (Vector me, double x, long ilevel, int interpolation) { double leftEdge = my x1 - 0.5 * my dx, rightEdge = leftEdge + my nx * my dx; if (x < leftEdge || x > rightEdge) return NUMundefined; if (ilevel > Vector_CHANNEL_AVERAGE) { Melder_assert (ilevel <= my ny); return NUM_interpolate_sinc (my z [ilevel], my nx, Sampled_xToIndex (me, x), interpolation == Vector_VALUE_INTERPOLATION_SINC70 ? NUM_VALUE_INTERPOLATE_SINC70 : interpolation == Vector_VALUE_INTERPOLATION_SINC700 ? NUM_VALUE_INTERPOLATE_SINC700 : interpolation); } double sum = 0.0; for (long channel = 1; channel <= my ny; channel ++) { sum += NUM_interpolate_sinc (my z [channel], my nx, Sampled_xToIndex (me, x), interpolation == Vector_VALUE_INTERPOLATION_SINC70 ? NUM_VALUE_INTERPOLATE_SINC70 : interpolation == Vector_VALUE_INTERPOLATION_SINC700 ? NUM_VALUE_INTERPOLATE_SINC700 : interpolation); } return sum / my ny; } /***** Get shape. *****/ void Vector_getMinimumAndX (Vector me, double xmin, double xmax, long channel, int interpolation, double *return_minimum, double *return_xOfMinimum) { long imin, imax, n = my nx; Melder_assert (channel >= 1 && channel <= my ny); double *y = my z [channel]; double minimum, x; if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (! Sampled_getWindowSamples (me, xmin, xmax, & imin, & imax)) { /* * No samples between xmin and xmax. * Try to return the lesser of the values at these two points. */ double yleft = Vector_getValueAtX (me, xmin, channel, interpolation > Vector_VALUE_INTERPOLATION_NEAREST ? Vector_VALUE_INTERPOLATION_LINEAR : Vector_VALUE_INTERPOLATION_NEAREST); double yright = Vector_getValueAtX (me, xmax, channel, interpolation > Vector_VALUE_INTERPOLATION_NEAREST ? Vector_VALUE_INTERPOLATION_LINEAR : Vector_VALUE_INTERPOLATION_NEAREST); minimum = yleft < yright ? yleft : yright; x = yleft == yright ? (xmin + xmax) / 2 : yleft < yright ? xmin : xmax; } else { minimum = y [imin], x = imin; if (y [imax] < minimum) minimum = y [imax], x = imax; if (imin == 1) imin ++; if (imax == my nx) imax --; for (long i = imin; i <= imax; i ++) { if (y [i] < y [i - 1] && y [i] <= y [i + 1]) { double i_real, localMinimum = NUMimproveMinimum (y, n, i, interpolation, & i_real); if (localMinimum < minimum) minimum = localMinimum, x = i_real; } } x = my x1 + (x - 1) * my dx; /* Convert sample to x. */ if (x < xmin) x = xmin; else if (x > xmax) x = xmax; } if (return_minimum) *return_minimum = minimum; if (return_xOfMinimum) *return_xOfMinimum = x; } void Vector_getMinimumAndXAndChannel (Vector me, double xmin, double xmax, int interpolation, double *return_minimum, double *return_xOfMinimum, long *return_channelOfMinimum) { double minimum, xOfMinimum; long channelOfMinimum = 1; Vector_getMinimumAndX (me, xmin, xmax, 1, interpolation, & minimum, & xOfMinimum); for (long channel = 2; channel <= my ny; channel ++) { double minimumOfChannel, xOfMinimumOfChannel; Vector_getMinimumAndX (me, xmin, xmax, channel, interpolation, & minimumOfChannel, & xOfMinimumOfChannel); if (minimumOfChannel < minimum) { minimum = minimumOfChannel; xOfMinimum = xOfMinimumOfChannel; channelOfMinimum = channel; } } if (return_minimum) *return_minimum = minimum; if (return_xOfMinimum) *return_xOfMinimum = xOfMinimum; if (return_channelOfMinimum) *return_channelOfMinimum = channelOfMinimum; } double Vector_getMinimum (Vector me, double xmin, double xmax, int interpolation) { double minimum; Vector_getMinimumAndXAndChannel (me, xmin, xmax, interpolation, & minimum, NULL, NULL); return minimum; } double Vector_getXOfMinimum (Vector me, double xmin, double xmax, int interpolation) { double xOfMinimum; Vector_getMinimumAndXAndChannel (me, xmin, xmax, interpolation, NULL, & xOfMinimum, NULL); return xOfMinimum; } long Vector_getChannelOfMinimum (Vector me, double xmin, double xmax, int interpolation) { long channelOfMinimum; Vector_getMinimumAndXAndChannel (me, xmin, xmax, interpolation, NULL, NULL, & channelOfMinimum); return channelOfMinimum; } void Vector_getMaximumAndX (Vector me, double xmin, double xmax, long channel, int interpolation, double *return_maximum, double *return_xOfMaximum) { long imin, imax, i, n = my nx; Melder_assert (channel >= 1 && channel <= my ny); double *y = my z [channel]; double maximum, x; if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (! Sampled_getWindowSamples (me, xmin, xmax, & imin, & imax)) { /* * No samples between xmin and xmax. * Try to return the greater of the values at these two points. */ double yleft = Vector_getValueAtX (me, xmin, channel, interpolation > Vector_VALUE_INTERPOLATION_NEAREST ? Vector_VALUE_INTERPOLATION_LINEAR : Vector_VALUE_INTERPOLATION_NEAREST); double yright = Vector_getValueAtX (me, xmax, channel, interpolation > Vector_VALUE_INTERPOLATION_NEAREST ? Vector_VALUE_INTERPOLATION_LINEAR : Vector_VALUE_INTERPOLATION_NEAREST); maximum = yleft > yright ? yleft : yright; x = yleft == yright ? (xmin + xmax) / 2 : yleft > yright ? xmin : xmax; } else { maximum = y [imin], x = imin; if (y [imax] > maximum) maximum = y [imax], x = imax; if (imin == 1) imin ++; if (imax == my nx) imax --; for (i = imin; i <= imax; i ++) { if (y [i] > y [i - 1] && y [i] >= y [i + 1]) { double i_real, localMaximum = NUMimproveMaximum (y, n, i, interpolation, & i_real); if (localMaximum > maximum) maximum = localMaximum, x = i_real; } } x = my x1 + (x - 1) * my dx; /* Convert sample to x. */ if (x < xmin) x = xmin; else if (x > xmax) x = xmax; } if (return_maximum) *return_maximum = maximum; if (return_xOfMaximum) *return_xOfMaximum = x; } void Vector_getMaximumAndXAndChannel (Vector me, double xmin, double xmax, int interpolation, double *return_maximum, double *return_xOfMaximum, long *return_channelOfMaximum) { double maximum, xOfMaximum; long channelOfMaximum = 1; Vector_getMaximumAndX (me, xmin, xmax, 1, interpolation, & maximum, & xOfMaximum); for (long channel = 2; channel <= my ny; channel ++) { double maximumOfChannel, xOfMaximumOfChannel; Vector_getMaximumAndX (me, xmin, xmax, channel, interpolation, & maximumOfChannel, & xOfMaximumOfChannel); if (maximumOfChannel > maximum) { maximum = maximumOfChannel; xOfMaximum = xOfMaximumOfChannel; channelOfMaximum = channel; } } if (return_maximum) *return_maximum = maximum; if (return_xOfMaximum) *return_xOfMaximum = xOfMaximum; if (return_channelOfMaximum) *return_channelOfMaximum = channelOfMaximum; } double Vector_getMaximum (Vector me, double xmin, double xmax, int interpolation) { double maximum; Vector_getMaximumAndXAndChannel (me, xmin, xmax, interpolation, & maximum, NULL, NULL); return maximum; } double Vector_getXOfMaximum (Vector me, double xmin, double xmax, int interpolation) { double xOfMaximum; Vector_getMaximumAndXAndChannel (me, xmin, xmax, interpolation, NULL, & xOfMaximum, NULL); return xOfMaximum; } long Vector_getChannelOfMaximum (Vector me, double xmin, double xmax, int interpolation) { long channelOfMaximum; Vector_getMaximumAndXAndChannel (me, xmin, xmax, interpolation, NULL, NULL, & channelOfMaximum); return channelOfMaximum; } double Vector_getAbsoluteExtremum (Vector me, double xmin, double xmax, int interpolation) { double minimum = fabs (Vector_getMinimum (me, xmin, xmax, interpolation)); double maximum = fabs (Vector_getMaximum (me, xmin, xmax, interpolation)); return minimum > maximum ? minimum : maximum; } /***** Get statistics. *****/ double Vector_getMean (Vector me, double xmin, double xmax, long channel) { return Sampled_getMean (me, xmin, xmax, channel, 0, true); } double Vector_getStandardDeviation (Vector me, double xmin, double xmax, long ilevel) { if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } long imin, imax, n = Sampled_getWindowSamples (me, xmin, xmax, & imin, & imax); if (n < 2) return NUMundefined; if (ilevel == Vector_CHANNEL_AVERAGE) { double sum2 = 0.0; for (long channel = 1; channel <= my ny; channel ++) { double mean = Vector_getMean (me, xmin, xmax, channel); for (long i = imin; i <= imax; i ++) { double diff = my z [channel] [i] - mean; sum2 += diff * diff; } } return sqrt (sum2 / (n * my ny - my ny)); // The number of constraints equals the number of channels, // because from every channel its own mean was subtracted. // Corollary: a two-channel mono sound will have the same stdev as the corresponding one-channel sound. } double mean = Vector_getMean (me, xmin, xmax, ilevel); double sum2 = 0.0; for (long i = imin; i <= imax; i ++) { double diff = my z [ilevel] [i] - mean; sum2 += diff * diff; } return sqrt (sum2 / (n - 1)); } /***** Modify. *****/ void Vector_addScalar (Vector me, double scalar) { for (long channel = 1; channel <= my ny; channel ++) { for (long i = 1; i <= my nx; i ++) { my z [channel] [i] += scalar; } } } void Vector_subtractMean (Vector me) { for (long channel = 1; channel <= my ny; channel ++) { double sum = 0.0; for (long i = 1; i <= my nx; i ++) { sum += my z [channel] [i]; } double mean = sum / my nx; for (long i = 1; i <= my nx; i ++) { my z [channel] [i] -= mean; } } } void Vector_multiplyByScalar (Vector me, double scalar) { for (long channel = 1; channel <= my ny; channel ++) { for (long i = 1; i <= my nx; i ++) { my z [channel] [i] *= scalar; } } } void Vector_scale (Vector me, double scale) { double extremum = 0.0; for (long channel = 1; channel <= my ny; channel ++) { for (long i = 1; i <= my nx; i ++) { if (fabs (my z [channel] [i]) > extremum) extremum = fabs (my z [channel] [i]); } } if (extremum != 0.0) { Vector_multiplyByScalar (me, scale / extremum); } } /***** Graphics. *****/ void Vector_draw (Vector me, Graphics g, double *pxmin, double *pxmax, double *pymin, double *pymax, double defaultDy, const char32 *method) { bool xreversed = *pxmin > *pxmax, yreversed = *pymin > *pymax; if (xreversed) { double temp = *pxmin; *pxmin = *pxmax; *pxmax = temp; } if (yreversed) { double temp = *pymin; *pymin = *pymax; *pymax = temp; } long ixmin, ixmax, ix; /* * Automatic domain. */ if (*pxmin == *pxmax) { *pxmin = my xmin; *pxmax = my xmax; } /* * Domain expressed in sample numbers. */ Matrix_getWindowSamplesX (me, *pxmin, *pxmax, & ixmin, & ixmax); /* * Automatic vertical range. */ if (*pymin == *pymax) { Matrix_getWindowExtrema (me, ixmin, ixmax, 1, 1, pymin, pymax); if (*pymin == *pymax) { *pymin -= defaultDy; *pymax += defaultDy; } } /* * Set coordinates for drawing. */ Graphics_setInner (g); Graphics_setWindow (g, xreversed ? *pxmax : *pxmin, xreversed ? *pxmin : *pxmax, yreversed ? *pymax : *pymin, yreversed ? *pymin : *pymax); if (str32str (method, U"bars") || str32str (method, U"Bars")) { for (ix = ixmin; ix <= ixmax; ix ++) { double x = Sampled_indexToX (me, ix); double y = my z [1] [ix]; double left = x - 0.5 * my dx, right = x + 0.5 * my dx; if (y > *pymax) y = *pymax; if (left < *pxmin) left = *pxmin; if (right > *pxmax) right = *pxmax; if (y > *pymin) { Graphics_line (g, left, y, right, y); Graphics_line (g, left, y, left, *pymin); Graphics_line (g, right, y, right, *pymin); } } } else if (str32str (method, U"poles") || str32str (method, U"Poles")) { for (ix = ixmin; ix <= ixmax; ix ++) { double x = Sampled_indexToX (me, ix); Graphics_line (g, x, 0, x, my z [1] [ix]); } } else if (str32str (method, U"speckles") || str32str (method, U"Speckles")) { for (ix = ixmin; ix <= ixmax; ix ++) { double x = Sampled_indexToX (me, ix); Graphics_speckle (g, x, my z [1] [ix]); } } else { /* * The default: draw as a curve. */ Graphics_function (g, my z [1], ixmin, ixmax, Matrix_columnToX (me, ixmin), Matrix_columnToX (me, ixmax)); } Graphics_unsetInner (g); } /* End of file Vector.cpp */ praat-6.0.04/fon/Vector.h000066400000000000000000000077611261542461700151300ustar00rootroot00000000000000#ifndef _Vector_h_ #define _Vector_h_ /* Vector.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Vector inherits from Matrix */ /* A Vector is a horizontal Matrix. */ /* The rows are 'channels'. There will often be only one channel, but e.g. a stereo sound has two. */ #include "Matrix.h" Thing_define (Vector, Matrix) { bool v_hasGetVector () override { return true; } double v_getVector (long irow, long icol) override; bool v_hasGetFunction1 () override { return true; } double v_getFunction1 (long irow, double x) override; bool v_hasGetMatrix () override { return false; } bool v_hasGetFunction2 () override { return false; } double v_getValueAtSample (long isamp, long ilevel, int unit) override; }; #define Vector_CHANNEL_AVERAGE 0 #define Vector_CHANNEL_1 1 #define Vector_CHANNEL_2 2 #define Vector_VALUE_INTERPOLATION_NEAREST 0 #define Vector_VALUE_INTERPOLATION_LINEAR 1 #define Vector_VALUE_INTERPOLATION_CUBIC 2 #define Vector_VALUE_INTERPOLATION_SINC70 3 #define Vector_VALUE_INTERPOLATION_SINC700 4 double Vector_getValueAtX (Vector me, double x, long channel, int interpolation); void Vector_getMinimumAndX (Vector me, double xmin, double xmax, long channel, int interpolation, double *return_minimum, double *return_xOfMinimum); void Vector_getMinimumAndXAndChannel (Vector me, double xmin, double xmax, int interpolation, double *return_minimum, double *return_xOfMinimum, long *return_channelOfMinimum); void Vector_getMaximumAndX (Vector me, double xmin, double xmax, long channel, int interpolation, double *return_maximum, double *return_xOfMaximum); void Vector_getMaximumAndXAndChannel (Vector me, double xmin, double xmax, int interpolation, double *return_maximum, double *return_xOfMaximum, long *return_channelOfMaximum); double Vector_getMinimum (Vector me, double xmin, double xmax, int interpolation); double Vector_getMaximum (Vector me, double xmin, double xmax, int interpolation); double Vector_getAbsoluteExtremum (Vector me, double xmin, double xmax, int interpolation); double Vector_getXOfMinimum (Vector me, double xmin, double xmax, int interpolation); double Vector_getXOfMaximum (Vector me, double xmin, double xmax, int interpolation); long Vector_getChannelOfMinimum (Vector me, double xmin, double xmax, int interpolation); long Vector_getChannelOfMaximum (Vector me, double xmin, double xmax, int interpolation); double Vector_getMean (Vector me, double xmin, double xmax, long channel); double Vector_getStandardDeviation (Vector me, double xmin, double xmax, long channel); void Vector_addScalar (Vector me, double scalar); void Vector_subtractMean (Vector me); void Vector_multiplyByScalar (Vector me, double scalar); void Vector_scale (Vector me, double scale); void Vector_draw (Vector me, Graphics g, double *pxmin, double *pxmax, double *pymin, double *pymax, double defaultDy, const char32 *method); /* If *pxmin equals *pxmax, then autowindowing from my xmin to my xmax. If *pymin equals *pymax, then autoscaling from minimum to maximum; if minimum then equals maximum, defaultDy will be subtracted from *pymin and added to *pymax; it must be a positive real number (e.g. 0.5 Pa for Sound, 1.0 dB for Ltas). method can be "curve", "bars", "poles", or "speckles"; it must not be NULL; if anything else is specified, a curve is drawn. */ /* End of file Vector.h */ #endif praat-6.0.04/fon/VocalTract.cpp000066400000000000000000000163241261542461700162560ustar00rootroot00000000000000/* VocalTract.cpp * * Copyright (C) 1992-2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "VocalTract.h" Thing_implement (VocalTract, Vector, 2); void structVocalTract :: v_info () { structDaata :: v_info (); MelderInfo_writeLine (U"Vocal tract length: ", Melder_single (xmax), U" metres"); MelderInfo_writeLine (U"Number of sections: ", nx); MelderInfo_writeLine (U"Section length: ", Melder_single (dx), U" metres"); } autoVocalTract VocalTract_create (long nx, double dx) { try { autoVocalTract me = Thing_new (VocalTract); Matrix_init (me.peek(), 0, nx * dx, nx, dx, 0.5 * dx, 1, 1, 1, 1, 1); return me; } catch (MelderError) { Melder_throw (U"VocalTract not created."); } } #define MinimumWidth 0.0001 static struct { const char32 *phone; int numberOfSections; double area [40]; } data [] = { { U"a", 34, { 1.7, 1.2, 1.6, 3.39, 2.1, 1.4, 1, 0.8, 0.8, 0.8, 1, 1.4, 2.1, 2.9, 3.09, 2.1, 2.5, 4, 5.3, 6.16, 7, 7.6, 8.15, 8.5, 8.6, 8.4, 8, 7.5, 6.9, 6, 5.1, 5, 5.5, 7.9 } }, { U"e", 33, { 2.3, 1.95, 1.73, 1.7, 5.3, 6.3, 6.8, 7.55, 8.2, 9.1, 9.7, 10.1, 10.2, 10, 8, 7.2, 7.5, 6.4, 5.4, 4.9, 4.35, 3.9, 3.5, 3.1, 2.7, 2.4, 2.2, 2.5, 3.4, 5, 6.7, 8.5, 10 } }, { U"i", 35, { 3, 2.9, 2.75, 2.58, 2.7, 6.35, 7.8, 8.9, 9.6, 10.15, 10.55, 10.9, 11.15, 11.3, 11.2, 10.8, 8, 7.8, 7, 4.5, 2.8, 1.9, 1.3, 0.9, 0.65, 0.55, 0.5, 0.55, 0.7, 0.95, 1.3, 2, 3, 5, 8 } }, { U"o", 37, { 2.6, 2.05, 1.56, 1.3, 5.2, 4.54, 3.49, 2.6, 2.1, 1.8, 1.6, 1.4, 1.29, 1.19, 1.22, 2.6, 2.9, 2.2, 2.6, 3.6, 4.55, 5.55, 6.4, 7.15, 8, 8.9, 9.6, 10.5, 11.8, 14.6, 14.5, 12.9, 10.4, 5, 3.4, 3.4, 4 } }, { U"u", 40, { 2.5, 2.5, 2.5, 2.4, 5, 8.1, 8.9, 8.9, 8.4, 7.5, 5.8, 3.9, 2.3, 1.6, 1.2, 1.05, 1.1, 1.4, 2.2, 2, 1.3, 2, 2.2, 2.3, 2.8, 3.7, 5, 6.2, 7.9, 10.9, 12.9, 13.15, 13, 12.5, 9.9, 3.9, 1.8, 0.32, 0.4, 0.6 } }, { U"y1", 37, { 3, 2.9, 2.75, 2.58, 2.7, 6.35, 7.8, 8.9, 9.6, 10.15, 10.55, 10.9, 11.15, 11.3, 11.2, 10.8, 8, 7.8, 7, 4.5, 2.8, 1.9, 1.3, 0.9, 0.65, 0.55, 0.5, 0.55, 0.7, 0.95, 1.3, 2, 3, 1.8, 0.32, 0.4, 0.6 } }, { U"y2", 38, { 3, 2.9, 2.75, 2.58, 2.7, 6.35, 7.8, 8.9, 9.6, 10.15, 10.55, 10.9, 11.15, 11.3, 11.2, 10.8, 8, 7.8, 7, 4.5, 2.8, 1.9, 1.3, 0.9, 0.65, 0.55, 0.5, 0.55, 0.7, 0.95, 1.3, 2, 3, 4, 1.8, 0.32, 0.4, 0.6 } }, { U"y3", 39, { 3, 2.9, 2.75, 2.58, 2.7, 6.35, 7.8, 8.9, 9.6, 10.15, 10.55, 10.9, 11.15, 11.3, 11.2, 10.8, 8, 7.8, 7, 4.5, 2.8, 1.9, 1.3, 0.9, 0.65, 0.55, 0.5, 0.55, 0.7, 0.95, 1.3, 2, 3, 4, 4, 1.8, 0.32, 0.4, 0.6 } }, { U"jery", 38, { 3.2, 3.2, 3.2, 3.2, 10.5, 10.5, 13, 13, 10.5, 10.5, 10.5, 10.5, 10.5, 8, 6.5, 6.5, 5, 4, 2, 2.6, 1.6, 1.3, 1, 1, 1.3, 1.6, 2, 2, 2.6, 3.2, 5, 8, 8, 8, 6.5, 2, 6.5, 6.5 } }, { U"p", 39, { 3.5, 3.2, 2.9, 2.6, 6.9, 6.65, 5.8, 4.9, 4, 3.14, 2.5, 1.84, 1.25, 0.83, 0.6, 0.53, 0.5, 0.6, 0.85, 1, 1.6, 2.05, 2.55, 3.08, 3.67, 4.15, 4.8, 5.5, 6.3, 7.4, 12, 12.98, 12.9, 11.4, 6.6, 2, 0.45, 0.1, MinimumWidth } }, { U"t", 36, { 2.8, 2.7, 2.4, 2.6, 6.45, 6.01, 5.31, 4.85, 4.55, 4.32, 4.18, 4.1, 4.04, 3.97, 3.85, 3.7, 3.4, 3.05, 2.91, 3.1, 3.55, 3.9, 4.1, 4, 3.8, 3.3, 2.55, 1.8, 1, 0.45, 0.1, MinimumWidth, 0.8, 2.5, 6, 9 } }, { U"k", 38, { 2.4, 2.7, 3, 3.3, 7, 9.38, 9.25, 8.62, 7.8, 6.7, 5.4, 4, 2.8, 1.9, 1.35, 0.9, 0.55, 0.3, 0.19, 0.07, MinimumWidth, 0.12, 0.17, 0.3, 0.5, 0.9, 1.4, 2.2, 3.3, 5, 9, 11.25, 10.9, 7.3, 4.3, 3.5, 3.7, 6 } }, { U"x", 40, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 } }, { U"pa", 39, { 1.7, 1.2, 1.6, 3.39, 2.1, 1.4, 1, 0.8, 0.8, 0.8, 1, 1.4, 2.1, 2.9, 3.09, 2.1, 2.5, 4, 5.3, 6.16, 7, 7.6, 8.15, 8.5, 8.6, 8.4, 8, 7.5, 6.9, 6, 5.1, 5, 5.5, 7.9, 6.6, 2, 0.45, 0.1, MinimumWidth } }, { U"ta", 34, { 1.7, 1.2, 1.6, 3.39, 2.1, 1.4, 1, 0.8, 0.8, 0.8, 1, 1.4, 2.1, 2.9, 3.09, 2.1, 2.5, 4, 5.3, 6.16, 7, 7.6, 8.15, 8.5, 8.6, 8.5, 6, 2, 0.45, MinimumWidth, 0.8, 2.5, 5.5, 7.9 } }, { U"ka", 34, { 1.7, 1.2, 1.6, 3.39, 2.1, 1.4, 1, 0.8, 0.8, 0.8, 1, 1.4, 2.1, 2.9, 3.09, 2.1, 0.3, MinimumWidth, 0.3, 2, 5, 7.6, 8.15, 8.5, 8.6, 8.4, 8, 7.5, 6.9, 6, 5.1, 5, 5.5, 7.9 } }, { U"pi", 39, { 3, 2.9, 2.75, 2.58, 2.7, 6.35, 7.8, 8.9, 9.6, 10.15, 10.55, 10.9, 11.15, 11.3, 11.2, 10.8, 8, 7.8, 7, 4.5, 2.8, 1.9, 1.3, 0.9, 0.65, 0.55, 0.5, 0.55, 0.7, 0.95, 1.3, 2, 3, 5, 6.6, 2, 0.45, 0.1, MinimumWidth } }, { U"ti", 35, { 3, 2.9, 2.75, 2.58, 2.7, 6.35, 7.8, 8.9, 9.6, 10.15, 10.55, 10.9, 11.15, 11.3, 11.2, 10.8, 8, 7.8, 7, 4.5, 2.8, 1.9, 1.3, 0.9, 0.65, 0.55, 0.5, 0.5, 0.5, 0.3, 0.1, MinimumWidth, 0.8, 2.5, 8 } }, { U"ki", 35, { 3, 2.9, 2.75, 2.58, 2.7, 6.35, 7.8, 8.9, 9.6, 10.15, 10.55, 10.9, 11.15, 11.3, 11.2, 10.8, 8, 6, 2, 0.3, MinimumWidth, 0.3, 1.3, 0.9, 0.65, 0.55, 0.5, 0.55, 0.7, 0.95, 1.3, 2, 3, 5, 8 } }, { U"pu", 40, { 2.5, 2.5, 2.5, 2.4, 5, 8.1, 8.9, 8.9, 8.4, 7.5, 5.8, 3.9, 2.3, 1.6, 1.2, 1.05, 1.1, 1.4, 2.2, 2, 1.3, 2, 2.2, 2.3, 2.8, 3.7, 5, 6.2, 7.9, 10.9, 12.9, 13.15, 13, 12.5, 9.9, 6.6, 2, 0.45, 0.1, MinimumWidth } }, { U"tu", 40, { 2.5, 2.5, 2.5, 2.4, 5, 8.1, 8.9, 8.9, 8.4, 7.5, 5.8, 3.9, 2.3, 1.6, 1.2, 1.05, 1.1, 1.4, 2.2, 2, 1.3, 2, 2.2, 2.3, 2.8, 3.7, 5, 6.2, 7.9, 10.9, 9, 3, 0.4, MinimumWidth, 0.8, 2.5, 1.8, 0.32, 0.4, 0.6 } }, { U"ku", 40, { 2.5, 2.5, 2.5, 2.4, 5, 8.1, 8.9, 8.9, 8.4, 7.5, 5.8, 3.9, 2.3, 1.6, 1.2, 1.05, 1.1, 1.4, 1.2, 0.3, MinimumWidth, 0.3, 2.2, 2.3, 2.8, 3.7, 5, 6.2, 7.9, 10.9, 12.9, 13.15, 13, 12.5, 9.9, 3.9, 1.8, 0.32, 0.4, 0.6 } }, { NULL, 0, { 0 } } }; autoVocalTract VocalTract_createFromPhone (const char32 *phone) { try { int i = 0; for (;; i ++) { if (data [i]. phone == NULL) Melder_throw (U"Unknown phone ", phone); if (Melder_equ (data [i]. phone, phone)) break; } autoVocalTract me = VocalTract_create (data [i]. numberOfSections, 0.005); for (int isection = 1; isection <= my nx; isection ++) my z [1] [isection] = data [i]. area [isection - 1] * 0.0001; return me; } catch (MelderError) { Melder_throw (U"VocalTract not created from phone."); } } void VocalTract_draw (VocalTract me, Graphics g) { Matrix_drawRows (me, g, 0, 0, 0, 0, 0, 0); } autoMatrix VocalTract_to_Matrix (VocalTract me) { try { autoMatrix thee = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, my ymin, my ymax, my ny, my dy, my y1); NUMvector_copyElements (my z [1], thy z [1], 1, my nx); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Matrix."); } } autoVocalTract Matrix_to_VocalTract (Matrix me) { try { autoVocalTract thee = VocalTract_create (my nx, my dx); NUMvector_copyElements (my z [1], thy z [1], 1, my nx); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to VocalTract."); } } /* End of file VocalTract.cpp */ praat-6.0.04/fon/VocalTract.h000066400000000000000000000046031261542461700157200ustar00rootroot00000000000000#ifndef _VocalTract_h_ #define _VocalTract_h_ /* VocalTract.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Vector.h" #include "Graphics.h" Thing_define (VocalTract, Vector) { void v_info () override; int v_domainQuantity () override { return MelderQuantity_DISTANCE_FROM_GLOTTIS_METRES; } }; /* Attributes: xmin // 0. xmax > xmin // Total length (metres). nx >= 1 // Number of sections. dx > 0.0 // Section length (metres). x1 // Centre of first section (metres). ymin, ymax, ny, dy, y1 = 1 z [1] [1..nx] // The area, in square metres. */ autoVocalTract VocalTract_create (long nx, double dx); /* Function: create a VocalTract. Preconditions: nx >= 1; dx > 0.0; Postconditions: my xmin == 0; my ymin == 1; my xmax == nx * dx; my ymax == 1; my nx == nx; my ny == 1; my dx == dx; my dy == 1; my x1 == 0.5 * dx; my y1 == 1; my z [1] [1..nx] == 1e-4; // straight tube, area 1 cm2. */ autoVocalTract VocalTract_createFromPhone (const char32 *phone); /* 'phone' is one of the following: a e i o u y1 y2 y3 jery p t k x pa ta ka pi ti ki pu tu ku */ void VocalTract_draw (VocalTract me, Graphics g); /* Draw a VocalTract into a Graphics. */ autoMatrix VocalTract_to_Matrix (VocalTract me); /* Create a Matrix from a VocalTract, with deep copy of all of its Matrix attributes, except class information and methods. */ autoVocalTract Matrix_to_VocalTract (Matrix me); /* Function: create a VocalTract from a Matrix. Postconditions: thy xmin == my xmin; thy xmax == my xmax; thy nx == my nx; thy dx == my dx; thy x1 == my x1; thy ymin ymax ny dy y1 == 1; thy z [1] [...] == my z [1] [...]; */ /* End of file VocalTract.h */ #endif praat-6.0.04/fon/VocalTract_to_Spectrum.cpp000066400000000000000000000124411261542461700206360ustar00rootroot00000000000000/* VocalTract_to_Spectrum.cpp * * Copyright (C) 1991-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * pb 1991/02/28 Pascal and Fortran versions * pb 1994/03/23 C version * pb 2002/06/04 * pb 2002/07/16 GPL * pb 2008/01/19 double * pb 2011/06/12 C++ */ #include "VocalTract_to_Spectrum.h" #define cc 353.0 #define rho 1.14 #define mu 1.86e-5 #define lambda 0.0055 #define cp 240.0 #define eta 1.4 #define shapeFactor 2.0 static void TUBE_transfer (double area [], int numberOfSections, double sectionLength, double frequency, double *re, double *im, /* Output. */ double glottalDamping, /* 0 or 0.1 */ int hasRadiationDamping, int hasInternalDamping) /* (Re,Im) := (air current at lips) / (air current at glottis) */ { int section; double omega = 2 * NUMpi * frequency; if (hasInternalDamping) { double bareResistance = sqrt (mu * rho / 2) * sqrt (omega); double bareConductance = (eta - 1) / (rho * cc * cc) * sqrt (lambda / (2 * cp * rho)) * sqrt (omega); dcomplex c = dcomplex_create (glottalDamping * area [1] / (rho * cc), 0.0); dcomplex d = dcomplex_create (1.0, 0.0); for (section = 1; section <= numberOfSections; section ++) { dcomplex help, help1, sinhg, coshg; double a = area [section]; double perimeter = shapeFactor * 2 * sqrt (NUMpi * a); double perimeter_by_a2 = perimeter / (a * a); double inertance = rho / a; double compliance = a / (rho * cc * cc); dcomplex cascade = dcomplex_create (perimeter_by_a2 * bareResistance, omega * inertance + perimeter_by_a2 * bareResistance); dcomplex parallel = dcomplex_create (perimeter * bareConductance, omega * compliance); dcomplex gamma = dcomplex_sqrt (dcomplex_mul (cascade, parallel)); dcomplex impedance = dcomplex_div (gamma, parallel); gamma = dcomplex_rmul (sectionLength, gamma); help = dcomplex_rmul (0.5, dcomplex_exp (gamma)); help1 = dcomplex_div (dcomplex_create (0.25, 0), help); sinhg = dcomplex_sub (help, help1); coshg = dcomplex_add (help, help1); help = dcomplex_add (dcomplex_mul (c, coshg), dcomplex_div (dcomplex_mul (d, sinhg), impedance)); d = dcomplex_add (dcomplex_mul (d, coshg), dcomplex_mul (dcomplex_mul (impedance, c), sinhg)); c = help; } if (hasRadiationDamping) { double ka = omega * sqrt (area [numberOfSections] / NUMpi) / cc; double z = rho * cc / area [numberOfSections]; double radiationResistance = z * ka * ka / 2; double radiationReactance = z * 8 * ka / 3 / NUMpi; *re = d.re + c.re * radiationResistance - c.im * radiationReactance; *im = d.im + c.im * radiationResistance + c.re * radiationReactance; } else { *re = d.re; *im = d.im; }; } else { double c_re, c_im; double angle = omega * sectionLength / cc, cosAngle = cos (angle), sinAngle = sin (angle); /* The parallel conductance of the glottis is due to air escaping */ /* through it. It is approximated as 0.1 A / rho C */ c_re = glottalDamping * cosAngle; c_im = sinAngle; *re = cosAngle; *im = glottalDamping * sinAngle; for (section = 1; section < numberOfSections; section ++) { double k = area [section] / area [section + 1]; double reDummy = c_re * k * cosAngle - *im * sinAngle; double imDummy = c_im * k * cosAngle + *re * sinAngle; *re = *re * cosAngle - c_im * k * sinAngle; *im = *im * cosAngle + c_re * k * sinAngle; c_re = reDummy; c_im = imDummy; } /* Radiation impedance at the lips. */ /* Energy radiates from the mouth. This loses energy to the formants. */ if (hasRadiationDamping) { double ka = omega * sqrt (area [numberOfSections] / NUMpi) / cc; double radiationResistance = ka * ka / 2; double radiationReactance = 8 * ka / 3 / NUMpi; *re += c_re * radiationResistance - c_im * radiationReactance; *im += c_re * radiationReactance + c_im * radiationResistance; } } /* Divide into 1. */ { double power = *re * *re + *im * *im; if (power != 0) { *re = *re / power; *im = *im / power; } } } autoSpectrum VocalTract_to_Spectrum (VocalTract me, long numberOfFrequencies, double maximumFrequency, double glottalDamping, int hasRadiationDamping, int hasInternalDamping) { try { autoSpectrum thee = Spectrum_create (maximumFrequency, numberOfFrequencies); for (long ifreq = 1; ifreq <= numberOfFrequencies; ifreq ++) { TUBE_transfer (my z [1], my nx, my dx, (ifreq - 0.9999) * maximumFrequency / (numberOfFrequencies - 1), & thy z [1] [ifreq], & thy z [2] [ifreq], glottalDamping, hasRadiationDamping, hasInternalDamping); thy z [1] [ifreq] *= 0.02; thy z [2] [ifreq] *= 0.02; } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Spectrum."); } } /* End of file VocalTract_to_Spectrum.cpp */ praat-6.0.04/fon/VocalTract_to_Spectrum.h000066400000000000000000000020421261542461700202770ustar00rootroot00000000000000/* VocalTract_to_Spectrum.h * * Copyright (C) 1992-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "VocalTract.h" #include "Spectrum.h" autoSpectrum VocalTract_to_Spectrum (VocalTract tube, long numberOfFrequencies, double maximumFrequency, double glottalDamping, int hasRadiationDamping, int hasInternalDamping); /* End of file VocalTract_to_Spectrum.h */ praat-6.0.04/fon/VoiceAnalysis.cpp000066400000000000000000000417511261542461700167670ustar00rootroot00000000000000/* VoiceAnalysis.cpp * * Copyright (C) 1992-2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "VoiceAnalysis.h" #include "AmplitudeTier.h" double PointProcess_getJitter_local (PointProcess me, double tmin, double tmax, double pmin, double pmax, double maximumPeriodFactor) { double sum = 0.0; if (tmax <= tmin) tmin = my xmin, tmax = my xmax; /* Autowindowing. */ long imin, imax; long numberOfPeriods = PointProcess_getWindowPoints (me, tmin, tmax, & imin, & imax) - 1; if (numberOfPeriods < 2) return NUMundefined; for (long i = imin + 1; i < imax; i ++) { double p1 = my t [i] - my t [i - 1], p2 = my t [i + 1] - my t [i]; double intervalFactor = p1 > p2 ? p1 / p2 : p2 / p1; if (pmin == pmax || (p1 >= pmin && p1 <= pmax && p2 >= pmin && p2 <= pmax && intervalFactor <= maximumPeriodFactor)) { sum += fabs (p1 - p2); } else { numberOfPeriods --; } } if (numberOfPeriods < 2) return NUMundefined; return sum / (numberOfPeriods - 1) / PointProcess_getMeanPeriod (me, tmin, tmax, pmin, pmax, maximumPeriodFactor); } double PointProcess_getJitter_local_absolute (PointProcess me, double tmin, double tmax, double pmin, double pmax, double maximumPeriodFactor) { if (tmax <= tmin) tmin = my xmin, tmax = my xmax; /* Autowindowing. */ long imin, imax; long numberOfPeriods = PointProcess_getWindowPoints (me, tmin, tmax, & imin, & imax) - 1; if (numberOfPeriods < 2) return NUMundefined; double sum = 0.0; for (long i = imin + 1; i < imax; i ++) { double p1 = my t [i] - my t [i - 1], p2 = my t [i + 1] - my t [i]; double intervalFactor = p1 > p2 ? p1 / p2 : p2 / p1; if (pmin == pmax || (p1 >= pmin && p1 <= pmax && p2 >= pmin && p2 <= pmax && intervalFactor <= maximumPeriodFactor)) { sum += fabs (p1 - p2); } else { numberOfPeriods --; } } if (numberOfPeriods < 2) return NUMundefined; return sum / (numberOfPeriods - 1); } double PointProcess_getJitter_rap (PointProcess me, double tmin, double tmax, double pmin, double pmax, double maximumPeriodFactor) { if (tmax <= tmin) tmin = my xmin, tmax = my xmax; /* Autowindowing. */ long imin, imax; long numberOfPeriods = PointProcess_getWindowPoints (me, tmin, tmax, & imin, & imax) - 1; if (numberOfPeriods < 3) return NUMundefined; double sum = 0.0; for (long i = imin + 2; i < imax; i ++) { double p1 = my t [i - 1] - my t [i - 2], p2 = my t [i] - my t [i - 1], p3 = my t [i + 1] - my t [i]; double intervalFactor1 = p1 > p2 ? p1 / p2 : p2 / p1, intervalFactor2 = p2 > p3 ? p2 / p3 : p3 / p2; if (pmin == pmax || (p1 >= pmin && p1 <= pmax && p2 >= pmin && p2 <= pmax && p3 >= pmin && p3 <= pmax && intervalFactor1 <= maximumPeriodFactor && intervalFactor2 <= maximumPeriodFactor)) { sum += fabs (p2 - (p1 + p2 + p3) / 3.0); } else { numberOfPeriods --; } } if (numberOfPeriods < 3) return NUMundefined; return sum / (numberOfPeriods - 2) / PointProcess_getMeanPeriod (me, tmin, tmax, pmin, pmax, maximumPeriodFactor); } double PointProcess_getJitter_ppq5 (PointProcess me, double tmin, double tmax, double pmin, double pmax, double maximumPeriodFactor) { if (tmax <= tmin) tmin = my xmin, tmax = my xmax; /* Autowindowing. */ long imin, imax; long numberOfPeriods = PointProcess_getWindowPoints (me, tmin, tmax, & imin, & imax) - 1; if (numberOfPeriods < 5) return NUMundefined; double sum = 0.0; for (long i = imin + 5; i <= imax; i ++) { double p1 = my t [i - 4] - my t [i - 5], p2 = my t [i - 3] - my t [i - 4], p3 = my t [i - 2] - my t [i - 3], p4 = my t [i - 1] - my t [i - 2], p5 = my t [i] - my t [i - 1]; double f1 = p1 > p2 ? p1 / p2 : p2 / p1, f2 = p2 > p3 ? p2 / p3 : p3 / p2, f3 = p3 > p4 ? p3 / p4 : p4 / p3, f4 = p4 > p5 ? p4 / p5 : p5 / p4; if (pmin == pmax || (p1 >= pmin && p1 <= pmax && p2 >= pmin && p2 <= pmax && p3 >= pmin && p3 <= pmax && p4 >= pmin && p4 <= pmax && p5 >= pmin && p5 <= pmax && f1 <= maximumPeriodFactor && f2 <= maximumPeriodFactor && f3 <= maximumPeriodFactor && f4 <= maximumPeriodFactor)) { sum += fabs (p3 - (p1 + p2 + p3 + p4 + p5) / 5.0); } else { numberOfPeriods --; } } if (numberOfPeriods < 5) return NUMundefined; return sum / (numberOfPeriods - 4) / PointProcess_getMeanPeriod (me, tmin, tmax, pmin, pmax, maximumPeriodFactor); } double PointProcess_getJitter_ddp (PointProcess me, double tmin, double tmax, double pmin, double pmax, double maximumPeriodFactor) { double rap = PointProcess_getJitter_rap (me, tmin, tmax, pmin, pmax, maximumPeriodFactor); return NUMdefined (rap) ? 3.0 * rap : NUMundefined; } double PointProcess_Sound_getShimmer_local (PointProcess me, Sound thee, double tmin, double tmax, double pmin, double pmax, double maximumPeriodFactor, double maximumAmplitudeFactor) { try { if (tmax <= tmin) tmin = my xmin, tmax = my xmax; // autowindowing autoAmplitudeTier peaks = PointProcess_Sound_to_AmplitudeTier_period (me, thee, tmin, tmax, pmin, pmax, maximumPeriodFactor); return AmplitudeTier_getShimmer_local (peaks.peek(), pmin, pmax, maximumAmplitudeFactor); } catch (MelderError) { if (Melder_hasError (U"Too few pulses between ")) { Melder_clearError (); return NUMundefined; } else { Melder_throw (me, U" & ", thee, U": shimmer (local) not computed."); } } } double PointProcess_Sound_getShimmer_local_dB (PointProcess me, Sound thee, double tmin, double tmax, double pmin, double pmax, double maximumPeriodFactor, double maximumAmplitudeFactor) { try { if (tmax <= tmin) tmin = my xmin, tmax = my xmax; // autowindowing autoAmplitudeTier peaks = PointProcess_Sound_to_AmplitudeTier_period (me, thee, tmin, tmax, pmin, pmax, maximumPeriodFactor); return AmplitudeTier_getShimmer_local_dB (peaks.peek(), pmin, pmax, maximumAmplitudeFactor); } catch (MelderError) { if (Melder_hasError (U"Too few pulses between ")) { Melder_clearError (); return NUMundefined; } else { Melder_throw (me, U" & ", thee, U": shimmer (local, dB) not computed."); } } } double PointProcess_Sound_getShimmer_apq3 (PointProcess me, Sound thee, double tmin, double tmax, double pmin, double pmax, double maximumPeriodFactor, double maximumAmplitudeFactor) { try { if (tmax <= tmin) tmin = my xmin, tmax = my xmax; // autowindowing autoAmplitudeTier peaks = PointProcess_Sound_to_AmplitudeTier_period (me, thee, tmin, tmax, pmin, pmax, maximumPeriodFactor); return AmplitudeTier_getShimmer_apq3 (peaks.peek(), pmin, pmax, maximumAmplitudeFactor); } catch (MelderError) { if (Melder_hasError (U"Too few pulses between ")) { Melder_clearError (); return NUMundefined; } else { Melder_throw (me, U" & ", thee, U": shimmer (apq3) not computed."); } } } double PointProcess_Sound_getShimmer_apq5 (PointProcess me, Sound thee, double tmin, double tmax, double pmin, double pmax, double maximumPeriodFactor, double maximumAmplitudeFactor) { try { if (tmax <= tmin) tmin = my xmin, tmax = my xmax; // autowindowing autoAmplitudeTier peaks = PointProcess_Sound_to_AmplitudeTier_period (me, thee, tmin, tmax, pmin, pmax, maximumPeriodFactor); return AmplitudeTier_getShimmer_apq5 (peaks.peek(), pmin, pmax, maximumAmplitudeFactor); } catch (MelderError) { if (Melder_hasError (U"Too few pulses between ")) { Melder_clearError (); return NUMundefined; } else { Melder_throw (me, U" & ", thee, U": shimmer (apq5) not computed."); } } } double PointProcess_Sound_getShimmer_apq11 (PointProcess me, Sound thee, double tmin, double tmax, double pmin, double pmax, double maximumPeriodFactor, double maximumAmplitudeFactor) { try { if (tmax <= tmin) tmin = my xmin, tmax = my xmax; // autowindowing autoAmplitudeTier peaks = PointProcess_Sound_to_AmplitudeTier_period (me, thee, tmin, tmax, pmin, pmax, maximumPeriodFactor); return AmplitudeTier_getShimmer_apq11 (peaks.peek(), pmin, pmax, maximumAmplitudeFactor); } catch (MelderError) { if (Melder_hasError (U"Too few pulses between ")) { Melder_clearError (); return NUMundefined; } else { Melder_throw (me, U" & ", thee, U": shimmer (apq11) not computed."); } } } double PointProcess_Sound_getShimmer_dda (PointProcess me, Sound thee, double tmin, double tmax, double pmin, double pmax, double maximumPeriodFactor, double maximumAmplitudeFactor) { try { if (tmax <= tmin) tmin = my xmin, tmax = my xmax; /* Autowindowing. */ autoAmplitudeTier peaks = PointProcess_Sound_to_AmplitudeTier_period (me, thee, tmin, tmax, pmin, pmax, maximumPeriodFactor); double apq3 = AmplitudeTier_getShimmer_apq3 (peaks.peek(), pmin, pmax, maximumAmplitudeFactor); return NUMdefined (apq3) ? 3.0 * apq3 : NUMundefined; } catch (MelderError) { if (Melder_hasError (U"Too few pulses between ")) { Melder_clearError (); return NUMundefined; } else { Melder_throw (me, U" & ", thee, U": shimmer (dda) not computed."); } } } void PointProcess_Sound_getShimmer_multi (PointProcess me, Sound thee, double tmin, double tmax, double pmin, double pmax, double maximumPeriodFactor, double maximumAmplitudeFactor, double *local, double *local_dB, double *apq3, double *apq5, double *apq11, double *dda) { try { if (tmax <= tmin) tmin = my xmin, tmax = my xmax; // autowindowing autoAmplitudeTier peaks = PointProcess_Sound_to_AmplitudeTier_period (me, thee, tmin, tmax, pmin, pmax, maximumPeriodFactor); if (local) *local = AmplitudeTier_getShimmer_local (peaks.peek(), pmin, pmax, maximumAmplitudeFactor); if (local_dB) *local_dB = AmplitudeTier_getShimmer_local_dB (peaks.peek(), pmin, pmax, maximumAmplitudeFactor); if (apq3) *apq3 = AmplitudeTier_getShimmer_apq3 (peaks.peek(), pmin, pmax, maximumAmplitudeFactor); if (apq5) *apq5 = AmplitudeTier_getShimmer_apq5 (peaks.peek(), pmin, pmax, maximumAmplitudeFactor); if (apq11) *apq11 = AmplitudeTier_getShimmer_apq11 (peaks.peek(), pmin, pmax, maximumAmplitudeFactor); if (dda) *dda = 3.0 * AmplitudeTier_getShimmer_apq3 (peaks.peek(), pmin, pmax, maximumAmplitudeFactor); } catch (MelderError) { if (Melder_hasError (U"Too few pulses between ")) { Melder_clearError (); if (local) *local = NUMundefined; if (local_dB) *local_dB = NUMundefined; if (apq3) *apq3 = NUMundefined; if (apq5) *apq5 = NUMundefined; if (apq11) *apq11 = NUMundefined; if (dda) *dda = NUMundefined; } else { Melder_throw (me, U" & ", thee, U": shimmer measures not computed."); } } } void Sound_Pitch_PointProcess_voiceReport (Sound sound, Pitch pitch, PointProcess pulses, double tmin, double tmax, double floor, double ceiling, double maximumPeriodFactor, double maximumAmplitudeFactor, double silenceThreshold, double voicingThreshold) { try { if (tmin >= tmax) tmin = sound -> xmin, tmax = sound -> xmax; /* * Time domain. Should be preceded by something like "Time range of SELECTION:" or so. */ MelderInfo_write (U" From ", Melder_fixed (tmin, 6), U" to ", Melder_fixed (tmax, 6), U" seconds"); MelderInfo_writeLine (U" (duration: ", Melder_fixed (tmax - tmin, 6), U" seconds)"); /* * Pitch statistics. */ MelderInfo_writeLine (U"Pitch:"); MelderInfo_writeLine (U" Median pitch: ", Melder_fixed (Pitch_getQuantile (pitch, tmin, tmax, 0.50, kPitch_unit_HERTZ), 3), U" Hz"); MelderInfo_writeLine (U" Mean pitch: ", Melder_fixed (Pitch_getMean (pitch, tmin, tmax, kPitch_unit_HERTZ), 3), U" Hz"); MelderInfo_writeLine (U" Standard deviation: ", Melder_fixed (Pitch_getStandardDeviation (pitch, tmin, tmax, kPitch_unit_HERTZ), 3), U" Hz"); MelderInfo_writeLine (U" Minimum pitch: ", Melder_fixed (Pitch_getMinimum (pitch, tmin, tmax, kPitch_unit_HERTZ, 1), 3), U" Hz"); MelderInfo_writeLine (U" Maximum pitch: ", Melder_fixed (Pitch_getMaximum (pitch, tmin, tmax, kPitch_unit_HERTZ, 1), 3), U" Hz"); /* * Pulses statistics. */ double pmin = 0.8 / ceiling, pmax = 1.25 / floor; MelderInfo_writeLine (U"Pulses:"); MelderInfo_writeLine (U" Number of pulses: ", PointProcess_getWindowPoints (pulses, tmin, tmax, NULL, NULL)); MelderInfo_writeLine (U" Number of periods: ", PointProcess_getNumberOfPeriods (pulses, tmin, tmax, pmin, pmax, maximumPeriodFactor)); MelderInfo_writeLine (U" Mean period: ", Melder_fixedExponent (PointProcess_getMeanPeriod (pulses, tmin, tmax, pmin, pmax, maximumPeriodFactor), -3, 6), U" seconds"); MelderInfo_writeLine (U" Standard deviation of period: ", Melder_fixedExponent (PointProcess_getStdevPeriod (pulses, tmin, tmax, pmin, pmax, maximumPeriodFactor), -3, 6), U" seconds"); /* * Voicing. */ long imin, imax, n = Sampled_getWindowSamples (pitch, tmin, tmax, & imin, & imax), nunvoiced = n; for (long i = imin; i <= imax; i ++) { Pitch_Frame frame = & pitch -> frame [i]; if (frame -> intensity >= silenceThreshold) { for (long icand = 1; icand <= frame -> nCandidates; icand ++) { Pitch_Candidate cand = & frame -> candidate [icand]; if (cand -> frequency > 0.0 && cand -> frequency < ceiling && cand -> strength >= voicingThreshold) { nunvoiced --; break; // next frame } } } } MelderInfo_writeLine (U"Voicing:"); MelderInfo_write (U" Fraction of locally unvoiced frames: ", Melder_percent (n <= 0 ? NUMundefined : (double) nunvoiced / n, 3)); MelderInfo_writeLine (U" (", nunvoiced, U" / ", n, U")"); n = PointProcess_getWindowPoints (pulses, tmin, tmax, & imin, & imax); long numberOfVoiceBreaks = 0; double durationOfVoiceBreaks = 0.0; if (n > 1) { bool previousPeriodVoiced = true; for (long i = imin + 1; i < imax; i ++) { double period = pulses -> t [i] - pulses -> t [i - 1]; if (period > pmax) { durationOfVoiceBreaks += period; if (previousPeriodVoiced) { numberOfVoiceBreaks ++; previousPeriodVoiced = false; } } else { previousPeriodVoiced = true; } } } MelderInfo_writeLine (U" Number of voice breaks: ", numberOfVoiceBreaks); MelderInfo_write (U" Degree of voice breaks: ", Melder_percent (durationOfVoiceBreaks / (tmax - tmin), 3)); MelderInfo_writeLine (U" (", Melder_fixed (durationOfVoiceBreaks, 6), U" seconds / ", Melder_fixed (tmax - tmin, 6), U" seconds)"); /* * Jitter. */ double shimmerLocal, shimmerLocal_dB, apq3, apq5, apq11, dda; MelderInfo_writeLine (U"Jitter:"); MelderInfo_writeLine (U" Jitter (local): ", Melder_percent (PointProcess_getJitter_local (pulses, tmin, tmax, pmin, pmax, maximumPeriodFactor), 3)); MelderInfo_writeLine (U" Jitter (local, absolute): ", Melder_fixedExponent (PointProcess_getJitter_local_absolute (pulses, tmin, tmax, pmin, pmax, maximumPeriodFactor), -6, 3), U" seconds"); MelderInfo_writeLine (U" Jitter (rap): ", Melder_percent (PointProcess_getJitter_rap (pulses, tmin, tmax, pmin, pmax, maximumPeriodFactor), 3)); MelderInfo_writeLine (U" Jitter (ppq5): ", Melder_percent (PointProcess_getJitter_ppq5 (pulses, tmin, tmax, pmin, pmax, maximumPeriodFactor), 3)); MelderInfo_writeLine (U" Jitter (ddp): ", Melder_percent (PointProcess_getJitter_ddp (pulses, tmin, tmax, pmin, pmax, maximumPeriodFactor), 3)); /* * Shimmer. */ PointProcess_Sound_getShimmer_multi (pulses, sound, tmin, tmax, pmin, pmax, maximumPeriodFactor, maximumAmplitudeFactor, & shimmerLocal, & shimmerLocal_dB, & apq3, & apq5, & apq11, & dda); MelderInfo_writeLine (U"Shimmer:"); MelderInfo_writeLine (U" Shimmer (local): ", Melder_percent (shimmerLocal, 3)); MelderInfo_writeLine (U" Shimmer (local, dB): ", Melder_fixed (shimmerLocal_dB, 3), U" dB"); MelderInfo_writeLine (U" Shimmer (apq3): ", Melder_percent (apq3, 3)); MelderInfo_writeLine (U" Shimmer (apq5): ", Melder_percent (apq5, 3)); MelderInfo_writeLine (U" Shimmer (apq11): ", Melder_percent (apq11, 3)); MelderInfo_writeLine (U" Shimmer (dda): ", Melder_percent (dda, 3)); /* * Harmonicity. */ MelderInfo_writeLine (U"Harmonicity of the voiced parts only:"); MelderInfo_writeLine (U" Mean autocorrelation: ", Melder_fixed (Pitch_getMeanStrength (pitch, tmin, tmax, Pitch_STRENGTH_UNIT_AUTOCORRELATION), 6)); MelderInfo_writeLine (U" Mean noise-to-harmonics ratio: ", Melder_fixed (Pitch_getMeanStrength (pitch, tmin, tmax, Pitch_STRENGTH_UNIT_NOISE_HARMONICS_RATIO), 6)); MelderInfo_writeLine (U" Mean harmonics-to-noise ratio: ", Melder_fixed (Pitch_getMeanStrength (pitch, tmin, tmax, Pitch_STRENGTH_UNIT_HARMONICS_NOISE_DB), 3), U" dB"); } catch (MelderError) { Melder_throw (sound, U" & ", pitch, U" & ", pulses, U": voice report not computed."); } } /* End of file VoiceAnalysis.cpp */ praat-6.0.04/fon/VoiceAnalysis.h000066400000000000000000000065301261542461700164300ustar00rootroot00000000000000/* VoiceAnalysis.h * * Copyright (C) 1992-2011 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Sound.h" #include "PointProcess.h" #include "Pitch.h" double PointProcess_getJitter_local (PointProcess me, double tmin, double tmax, double minimumPeriod, double maximumPeriod, double maximumPeriodFactor); double PointProcess_getJitter_local_absolute (PointProcess me, double tmin, double tmax, double minimumPeriod, double maximumPeriod, double maximumPeriodFactor); double PointProcess_getJitter_rap (PointProcess me, double tmin, double tmax, double minimumPeriod, double maximumPeriod, double maximumPeriodFactor); double PointProcess_getJitter_ppq5 (PointProcess me, double tmin, double tmax, double minimumPeriod, double maximumPeriod, double maximumPeriodFactor); double PointProcess_getJitter_ddp (PointProcess me, double tmin, double tmax, double minimumPeriod, double maximumPeriod, double maximumPeriodFactor); double PointProcess_Sound_getShimmer_local (PointProcess me, Sound thee, double tmin, double tmax, double minimumPeriod, double maximumPeriod, double maximumPeriodFactor, double maximumAmplitudeFactor); double PointProcess_Sound_getShimmer_local_dB (PointProcess me, Sound thee, double tmin, double tmax, double minimumPeriod, double maximumPeriod, double maximumPeriodFactor, double maximumAmplitudeFactor); double PointProcess_Sound_getShimmer_apq3 (PointProcess me, Sound thee, double tmin, double tmax, double minimumPeriod, double maximumPeriod, double maximumPeriodFactor, double maximumAmplitudeFactor); double PointProcess_Sound_getShimmer_apq5 (PointProcess me, Sound thee, double tmin, double tmax, double minimumPeriod, double maximumPeriod, double maximumPeriodFactor, double maximumAmplitudeFactor); double PointProcess_Sound_getShimmer_apq11 (PointProcess me, Sound thee, double tmin, double tmax, double minimumPeriod, double maximumPeriod, double maximumPeriodFactor, double maximumAmplitudeFactor); double PointProcess_Sound_getShimmer_dda (PointProcess me, Sound thee, double tmin, double tmax, double minimumPeriod, double maximumPeriod, double maximumPeriodFactor, double maximumAmplitudeFactor); void PointProcess_Sound_getShimmer_multi (PointProcess me, Sound thee, double tmin, double tmax, double minimumPeriod, double maximumPeriod, double maximumPeriodFactor, double maximumAmplitudeFactor, double *local, double *local_dB, double *apq3, double *apq5, double *apq11, double *dda); void Sound_Pitch_PointProcess_voiceReport (Sound sound, Pitch pitch, PointProcess pulses, double tmin, double tmax, double floor, double ceiling, double maximumPeriodFactor, double maximumAmplitudeFactor, double silenceThreshold, double voicingThreshold); /* End of file VoiceAnalysis.h */ praat-6.0.04/fon/WordList.cpp000066400000000000000000000167121261542461700157640ustar00rootroot00000000000000/* WordList.cpp * * Copyright (C) 1999-2012,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "WordList.h" #include "longchar.h" #include "oo_DESTROY.h" #include "WordList_def.h" #include "oo_COPY.h" #include "WordList_def.h" #include "oo_EQUAL.h" #include "WordList_def.h" #include "oo_CAN_WRITE_AS_ENCODING.h" #include "WordList_def.h" #include "oo_WRITE_TEXT.h" #include "WordList_def.h" #include "oo_READ_TEXT.h" #include "WordList_def.h" #include "oo_DESCRIPTION.h" #include "WordList_def.h" /* BUG: not Unicode-savvy */ Thing_implement (WordList, Daata, 0); static long WordList_count (WordList me) { long n = 0; for (char32 *p = my string; *p; p ++) { if (*p == '\n') n += 1; } return n; } void structWordList :: v_info () { structDaata :: v_info (); long n = WordList_count (this); if (! our length) our length = str32len (our string); MelderInfo_writeLine (U"Number of words: ", n); MelderInfo_writeLine (U"Number of characters: ", length - n); } void structWordList :: v_readBinary (FILE *f, int /*formatVersion*/) { char32 *current, *p; int kar = 0; our length = bingeti4 (f); if (our length < 0) Melder_throw (U"Wrong length ", our length, U"."); string = Melder_calloc (char32, our length + 1); p = current = string; if (our length > 0) { /* * Read first word. */ for (;;) { if (p - string >= length - 1) break; kar = fgetc (f); if (kar == EOF) Melder_throw (U"Early end of file."); if (kar >= 128) break; *p ++ = kar; } *p ++ = '\n'; /* * Read following words. */ for (;;) { char32 *previous = current; int numberOfSame = kar - 128; current = p; str32ncpy (current, previous, numberOfSame); p += numberOfSame; for (;;) { if (p - string >= length - 1) break; kar = fgetc (f); if (kar == EOF) Melder_throw (U"Early end of file."); if (kar >= 128) break; *p ++ = kar; } *p ++ = '\n'; if (p - string >= length) break; } } *p = '\0'; if (p - string != length) Melder_throw (U"Length in header (", length, U") does not match lenth of string (", (long) (p - string), U")."); } void structWordList :: v_writeBinary (FILE *f) { long currentLength, previousLength; if (! length) length = str32len (string); binputi4 (length, f); if (length > 0) { char32 *current = string, *kar = current; for (kar = current; *kar != U'\n'; kar ++) { } currentLength = kar - current; for (long i = 0; i < currentLength; i ++) fputc ((int) current [i], f); // TODO: check for (;;) { char32 *previous = current, *kar1, *kar2; int numberOfSame; previousLength = currentLength; current = previous + previousLength + 1; if (*current == U'\0') break; kar1 = previous, kar2 = current; while (*kar2 != U'\n' && *kar2 == *kar1) { kar1 ++, kar2 ++; } numberOfSame = kar2 - current; if (numberOfSame > 127) numberOfSame = 127; // clip fputc (128 + numberOfSame, f); while (*kar2 != U'\n') kar2 ++; currentLength = kar2 - current; for (long i = 0; i < currentLength - numberOfSame; i ++) fputc ((int) current [numberOfSame + i], f); // TODO: check } } } autoWordList Strings_to_WordList (Strings me) { try { long totalLength = 0; /* * Check whether the strings are generic and sorted. */ for (long i = 1; i <= my numberOfStrings; i ++) { char32 *string = my strings [i], *p; for (p = & string [0]; *p; p ++) { if (*p > 126) Melder_throw (U"String \"", string, U"\" not generic.\nPlease convert to backslash trigraphs first."); } if (i > 1 && str32cmp (my strings [i - 1], string) > 0) { Melder_throw (U"String \"", string, U"\" not sorted.\nPlease sort first."); } totalLength += str32len (string); } autoWordList thee = Thing_new (WordList); thy length = totalLength + my numberOfStrings; thy string = Melder_calloc (char32, thy length + 1); /* * Concatenate the strings into the word list. */ char32 *q = thy string; for (long i = 1; i <= my numberOfStrings; i ++) { long length = str32len (my strings [i]); str32cpy (q, my strings [i]); q += length; *q ++ = '\n'; } *q = U'\0'; Melder_assert (q - thy string == thy length); return thee; } catch (MelderError) { Melder_throw (me, U": not converted to WordList."); } } autoStrings WordList_to_Strings (WordList me) { try { unsigned char *word = (unsigned char *) my string; // BUG: explain this autoStrings thee = Thing_new (Strings); thy numberOfStrings = WordList_count (me); if (thy numberOfStrings > 0) { thy strings = NUMvector (1, thy numberOfStrings); } for (long i = 1; i <= thy numberOfStrings; i ++) { unsigned char *kar = word; for (; *kar != '\n'; kar ++) { } long length = kar - word; thy strings [i] = Melder_calloc (char32, length + 1); str32ncpy (thy strings [i], Melder_peek8to32 ((const char *) word), length); thy strings [i] [length] = U'\0'; word += length + 1; } return thee; } catch (MelderError) { Melder_throw (me, U": not converted to Strings."); } } static long gotoStart (WordList me, long p) { if (p <= 0) return 0; -- p; while (p >= 0 && my string [p] != U'\n') p --; return p + 1; } static long gotoNext (WordList me, long p) { if (p >= my length - 1) return my length; while (my string [p] != U'\n') p ++; return p + 1; } static long gotoPrevious (WordList me, long p) { if (p <= 0) return -1; if (my string [-- p] != U'\n') return -1; // should not occur if (p <= 0) return 0; // if first word is empty -- p; // step from newline while (p >= 0 && my string [p] != U'\n') p --; return p + 1; } static int compare (const char32 *word, const char32 *p) { for (;;) { if (*word == U'\0') { if (*p == U'\n') return 0; else return -1; // word is substring of p } if (*p == U'\n') return +1; // p is substring of word if (*word < *p) return -1; if (*word > *p) return +1; word ++, p ++; } return 0; // should not occur } static char32 buffer [3333+1]; bool WordList_hasWord (WordList me, const char32 *word) { if (str32len (word) > 3333) return false; Longchar_genericize32 (word, buffer); if (! my length) my length = str32len (my string); long p = my length / 2, d = p / 2; while (d > 20) { p = gotoStart (me, p); int cf = compare (buffer, my string + p); if (cf == 0) return true; if (cf < 0) p -= d; else p += d; d /= 2; } p = gotoStart (me, p); int cf = compare (buffer, my string + p); if (cf == 0) return true; if (cf > 0) { for (;;) { p = gotoNext (me, p); if (p >= my length) return false; cf = compare (buffer, my string + p); if (cf == 0) return true; if (cf < 0) return false; } } else { for (;;) { p = gotoPrevious (me, p); if (p < 0) return false; cf = compare (buffer, my string + p); if (cf == 0) return true; if (cf > 0) return false; } } return false; // should not occur } /* End of file WordList.cpp */ praat-6.0.04/fon/WordList.h000066400000000000000000000020721261542461700154230ustar00rootroot00000000000000#ifndef _WordList_h_ #define _WordList_h_ /* WordList.h * * Copyright (C) 1999-2011,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Strings_.h" #include "WordList_def.h" oo_CLASS_CREATE (WordList, Daata); autoWordList Strings_to_WordList (Strings me); autoStrings WordList_to_Strings (WordList me); bool WordList_hasWord (WordList me, const char32 *word); /* End of file WordList.h */ #endif praat-6.0.04/fon/WordList_def.h000066400000000000000000000020131261542461700162340ustar00rootroot00000000000000/* File WordList_def.h * * Copyright (C) 1999-2011 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define ooSTRUCT WordList oo_DEFINE_CLASS (WordList, Daata) #if !oo_DESCRIBING oo_LSTRING (string) #endif #if oo_DECLARING oo_LONG (length) void v_info () override; #endif oo_END_CLASS (WordList) #undef ooSTRUCT /* End of file WordList_def.h */ praat-6.0.04/fon/manual_Exp.cpp000066400000000000000000001350521261542461700163050ustar00rootroot00000000000000/* manual_Exp.c * * Copyright (C) 2001-2011,2013,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ManPagesM.h" void manual_Exp_init (ManPages me); void manual_Exp_init (ManPages me) { MAN_BEGIN (U"ExperimentMFC", U"ppgb", 20130101) INTRO (U"One of the @@types of objects@ in Praat, " "for running a Multiple Forced Choice listening experiment.") LIST_ITEM (U"@@ExperimentMFC 1. When to use Praat") LIST_ITEM (U"@@ExperimentMFC 2. The first example") LIST_ITEM (U"@@ExperimentMFC 2.1. The experiment file") LIST_ITEM (U"@@ExperimentMFC 2.2. The stimuli") LIST_ITEM (U"@@ExperimentMFC 2.3. The carrier phrase") LIST_ITEM (U"@@ExperimentMFC 2.4. Breaks") LIST_ITEM (U"@@ExperimentMFC 2.5. Randomization strategies") LIST_ITEM (U"@@ExperimentMFC 2.6. Instructions") LIST_ITEM (U"@@ExperimentMFC 2.7. Response categories") LIST_ITEM (U"@@ExperimentMFC 2.8. Goodness judgments") LIST_ITEM (U"@@ExperimentMFC 2.9. How an experiment proceeds") LIST_ITEM (U"@@ExperimentMFC 3. More examples") LIST_ITEM (U"@@ExperimentMFC 3.1. A simple discrimination experiment") LIST_ITEM (U"@@ExperimentMFC 3.2. An AXB discrimination experiment") LIST_ITEM (U"@@ExperimentMFC 3.3. A 4I-oddity experiment") LIST_ITEM (U"@@ExperimentMFC 3.4. Variable inter-stimulus intervals") LIST_ITEM (U"@@ExperimentMFC 4. Special buttons") LIST_ITEM (U"@@ExperimentMFC 4.1. The replay button") LIST_ITEM (U"@@ExperimentMFC 4.2. The OK button") LIST_ITEM (U"@@ExperimentMFC 4.3. The oops button") LIST_ITEM (U"@@ExperimentMFC 5. Stimulus-dependent texts") LIST_ITEM (U"@@ExperimentMFC 5.1. The stimulus-dependent run text") LIST_ITEM (U"@@ExperimentMFC 5.2. Stimulus-dependent response buttons") LIST_ITEM (U"@@ExperimentMFC 6. Responses are sounds") LIST_ITEM (U"@@ExperimentMFC 7. Blanking the screen") LIST_ITEM (U"@@ExperimentMFC 8. Running multiple experiments") MAN_END MAN_BEGIN (U"ExperimentMFC 1. When to use Praat", U"ppgb", 20130101) NORMAL (U"With Praat's ExperimentMFC, you can do simple experiments on identification and discrimination. " "`Simple' means that for identification, the subject hears a sound and has to click on one of a set of " "labelled rectangles (optionally, you can have the subject give a goodness-of-fit judgment). " "For discrimination, you can have simple same-different choices, or more intricate things like AXB, 4I-oddity, and so on.") NORMAL (U"The advantage of using Praat's ExperimentMFC for this is that it is free, it works on Windows, Unix, and Macintosh, " "and the whole experiment (experiment file plus sound files) is portable across computers " "(you can run it from a USB stick, for instance). Because of the limited possibilities, " "it is also quite easy to set up the experiment. Just read the description below.") NORMAL (U"If you require more from your experiment design, you can use Praat's @@Demo window@; " "with that less simple method you could for instance let the stimulus depend on the subject's previous responses. " "Alternatively, you could use a dedicated program like Presentation or E-prime instead of Praat; " "with these programs, you can also measure reaction times more accurately.") MAN_END MAN_BEGIN (U"ExperimentMFC 2. The first example", U"ppgb", 20051205) INTRO (U"The following pages give an example of an experiment definition, " "and explain the main features of an identification task.") LIST_ITEM (U"@@ExperimentMFC 2.1. The experiment file") LIST_ITEM (U"@@ExperimentMFC 2.2. The stimuli") LIST_ITEM (U"@@ExperimentMFC 2.3. The carrier phrase") LIST_ITEM (U"@@ExperimentMFC 2.4. Breaks") LIST_ITEM (U"@@ExperimentMFC 2.5. Randomization strategies") LIST_ITEM (U"@@ExperimentMFC 2.6. Instructions") LIST_ITEM (U"@@ExperimentMFC 2.7. Response categories") LIST_ITEM (U"@@ExperimentMFC 2.8. Goodness judgments") LIST_ITEM (U"@@ExperimentMFC 2.9. How an experiment proceeds") MAN_END MAN_BEGIN (U"ExperimentMFC 2.1. The experiment file", U"ppgb", 20130101) INTRO (U"An experiment is defined in a simple text file, which we call an %%experiment file%. " "The following is an example of such an experiment file. The first two lines have to be typed " "exactly as in this example, the rest depends on your stimuli, on your response categories, " "and on the way the experiment is to be presented to the listener. " "The order of the elements in this file cannot be changed, and nothing can be skipped.") CODE (U"\"ooTextFile\"") CODE (U"\"ExperimentMFC 6\"") CODE (U"blankWhilePlaying? ") CODE (U"stimuliAreSounds? ") CODE (U"stimulusFileNameHead = \"Sounds/\"") CODE (U"stimulusFileNameTail = \".wav\"") CODE (U"stimulusCarrierBefore = \"weSayTheWord\"") CODE (U"stimulusCarrierAfter = \"again\"") CODE (U"stimulusInitialSilenceDuration = 0.5 seconds") CODE (U"stimulusMedialSilenceDuration = 0") CODE (U"stimulusFinalSilenceDuration = 0.5 seconds") CODE (U"numberOfDifferentStimuli = 4") CODE1 (U"\"heed\" \"\"") CODE1 (U"\"hid\" \"\"") CODE1 (U"\"hood\" \"\"") CODE1 (U"\"hud\" \"\"") CODE (U"numberOfReplicationsPerStimulus = 3") CODE (U"breakAfterEvery = 0") CODE (U"randomize = ") CODE (U"startText = \"This is a listening experiment.") CODE (U"After hearing a sound, choose the vowel that is most similar to what you heard.") CODE (U"") CODE (U"Click to start.\"") CODE (U"runText = \"Choose the vowel that you heard.\"") CODE (U"pauseText = \"You can have a short break if you like. Click to proceed.\"") CODE (U"endText = \"The experiment has finished.\"") CODE (U"maximumNumberOfReplays = 0") CODE (U"replayButton = 0 0 0 0 \"\" \"\"") CODE (U"okButton = 0 0 0 0 \"\" \"\"") CODE (U"oopsButton = 0 0 0 0 \"\" \"\"") CODE (U"responsesAreSounds? \"\" \"\" \"\" \"\" 0 0 0") CODE (U"numberOfDifferentResponses = 5") CODE1 (U"0.2 0.3 0.7 0.8 \"h I d\" 40 \"\" \"i\"") CODE1 (U"0.3 0.4 0.5 0.6 \"h E d\" 40 \"\" \"e\"") CODE1 (U"0.4 0.5 0.3 0.4 \"h A d\" 40 \"\" \"a\"") CODE1 (U"0.5 0.6 0.5 0.6 \"h O d\" 40 \"\" \"o\"") CODE1 (U"0.6 0.7 0.7 0.8 \"h U d\" 40 \"\" \"u\"") CODE (U"numberOfGoodnessCategories = 5") CODE1 (U"0.25 0.35 0.10 0.20 \"1 (poor)\"") CODE1 (U"0.35 0.45 0.10 0.20 \"2\"") CODE1 (U"0.45 0.55 0.10 0.20 \"3\"") CODE1 (U"0.55 0.65 0.10 0.20 \"4\"") CODE1 (U"0.65 0.75 0.10 0.20 \"5 (good)\"") NORMAL (U"This experiment will play 4 different stimuli to the listener, each 3 times. " "Thus, the listener is confronted with 12 trials.") MAN_END MAN_BEGIN (U"ExperimentMFC 2.2. The stimuli", U"ppgb", 20130101) INTRO (U"You can see that the @@ExperimentMFC 2.1. The experiment file|example experiment@ " "contains four different stimuli: %heed, %hid, %hood, and %hud. " "These are the %names of the four stimuli.") NORMAL (U"Because in the example experiment stimuli are sounds, " "each of the four stimuli should be in a sound file. " "The names of these sound files must be identical to the names " "of the stimuli, bracketed with %stimulusFileNamehead and %stimulusFileNameTail. " "Hence, the stimuli are expected in the following four files:") LIST_ITEM (U"Sounds/heed.wav") LIST_ITEM (U"Sounds/hid.wav") LIST_ITEM (U"Sounds/hood.wav") LIST_ITEM (U"Sounds/hud.wav") NORMAL (U"You need not use WAV files. You can also use AIFF files, " "in which case %stimulusFileNameTail would probably be \".aiff\", or any other " "type of sound file that Praat supports. But all sound files must have the same number of channels " "(i.e. all mono or all stereo) and the same sampling frequency.") NORMAL (U"In this example, the experiment will look for the sound files in the directory #Sounds, " "which has to be in the same directory as your experiment file. " "In other words, \"Sounds/heed.wav\" is a %%relative file path%.") NORMAL (U"Instead of a relative path, you can also supply a %%full file path%. " "Such a path depends on your computer and on your operating system. " "For instance, if you have a Windows computer and the stimuli are in the directory ##D:\\bsCorpus\\bsAutumn\\bsSpeaker23#, " "you can write") CODE (U"fileNameHead = \"D:\\bsCorpus\\bsAutumn\\bsSpeaker23\\bs\"") NORMAL (U"If you have a Macintosh (OS X) or Unix computer and the stimuli are in ##/Users/mietta/Sounds/Dutch#, you write") CODE (U"fileNameHead = \"/Users/mietta/Sounds/Dutch/\"") NORMAL (U"But relative file paths will usually be preferred: they are more %portable. " "The advantage of using relative file paths is that you can move your whole experiment (experiment file plus sounds) " "from one computer to another without changing the experiment file, " "as long as you put the experiment file in the same directory as where you put the directory #Sounds. " "Or you can put the whole experiment on a USB stick and run the experiment directly from the stick. " "Since Praat supports the forward slash \"/\" as a directory separator on all computers, " "you can run the exact same experiment on Macintosh, Windows and Unix computers, " "independent of the type of computer where you have created your experiment.") MAN_END MAN_BEGIN (U"ExperimentMFC 2.3. The carrier phrase", U"ppgb", 20051205) NORMAL (U"The stimuli can be embedded in a %%carrier phrase%. " "In the @@ExperimentMFC 2.1. The experiment file|example experiment@, we see that the stimulus " "will be inserted between the sounds in the files ##weSayTheWord.wav# " "and ##again.wav#, both of which are expected to be in the directory #Sounds. " "If you do not want a carrier phrase, you do") CODE (U"stimulusCarrierBefore = \"\"") CODE (U"stimulusCarrierAfter = \"\"") NORMAL (U"If you want only an introductory phrase before the stimulus, and nothing after the stimulus, " "you do something like") CODE (U"stimulusCarrierBefore = \"listenTo\"") CODE (U"stimulusCarrierAfter = \"\"") NORMAL (U"and of course you supply the file ##listenTo.wav# in the directory #Sounds.") NORMAL (U"If you want to have a short silence before every stimulus (and before the carrier phrase), " "you supply a non-zero %stimulusInitialSilenceDuration, as in the example.") NORMAL (U"Since the carrier phrase is concatenated with the stimulus before it is played, it should have the same " "sampling frequency as the stimulus files.") MAN_END MAN_BEGIN (U"ExperimentMFC 2.4. Breaks", U"ppgb", 20051205) NORMAL (U"A new stimulus will arrive as soon as the listener makes her choice. To allow her some breathing " "time, you can insert a break after every so many trials. In the example, %breakAfterEvery is 0, " "because there are only 12 trials. A typical experiment has perhaps 180 trials, and you may want to " "insert a break after every 40 trials. In that case, you do") CODE (U"breakAfterEvery = 40") MAN_END MAN_BEGIN (U"ExperimentMFC 2.5. Randomization strategies", U"ppgb", 20051205) NORMAL (U"The 3 times 4 stimuli will have to be played in a certain order. For the least random order, you say") CODE (U"randomize = ") NORMAL (U"In this case, the stimuli will be played in the order in which they were specified in the file, 3 times:") FORMULA (U"heed hid hood hud heed hid hood hud heed hid hood hud") NORMAL (U"The most likely case in which you would want to use this randomization strategy, is if you have, say, 120 " "different stimuli and you want to play them only once (%numberOfReplicationsPerStimulus = 1) in a fixed order.") NORMAL (U"The other extreme, the most random order, is") CODE (U"randomize = ") NORMAL (U"In this case, a stimulus will be chosen at random 12 times without memory, for instance") FORMULA (U"hid hood hood heed hid hood hud hud hid hood heed hid") NORMAL (U"The order will probably be different for each listener. " "In this example, %hood and %hid occur four times each, %heed and %hud only twice each. " "This strategy is too random for most experiments. Usually, you will want to have the same number " "of replications of each stimulus. The most random way to do this is") CODE (U"randomize = ") NORMAL (U"In this case, all stimuli will be played exactly 3 times, for instance") FORMULA (U"heed hood hud hud hid heed heed hud hood hid hid hood") NORMAL (U"Quite often, you will want a less random order, namely one in which the 12 trials are divided into " "3 blocks of 4 stimuli. Within each block, all 4 different stimuli occur in a random order:") CODE (U"randomize = ") NORMAL (U"In this case, each stimulus occurs exactly once within each block:") FORMULA (U"heed hood hud hid hood hud hid heed heed hud hood hid") NORMAL (U"This strategy ensures a certain spreading of the stimuli over the sequence of 12 trials. " "As we see here, it is still possible that the same stimulus (%heed) occurs twice in a row, " "namely as the last stimulus of the second block and the first stimulus of the third. " "If you want to prevent that situation, you use") CODE (U"randomize = ") NORMAL (U"This will ensure that the same stimulus is never applied twice in a row:") FORMULA (U"heed hood hud hid hood hud hid heed hud heed hood hid") NORMAL (U"This randomization strategy is used in our example, and advised for most listening experiments " "in which you want to minimize effects of stimulus order.") NORMAL (U"The randomization procedure does not interfere in any way with the breaks. The order is determined " "before any breaks are inserted.") MAN_END MAN_BEGIN (U"ExperimentMFC 2.6. Instructions", U"ppgb", 20081123) NORMAL (U"Before the experiment begins, the listener will see the %startText in the centre of the screen. " "During each trial, she will see the %runText at the top of the screen. " "During breaks, she will see the %pauseText in the centre of the screen. " "After all the trials have been performed, she will see the %endText. " "As you can see in the example, all these texts can consist of multiple lines.") MAN_END MAN_BEGIN (U"ExperimentMFC 2.7. Response categories", U"ppgb", 20110911) NORMAL (U"Every trial comes with the same set of response categories. " "The @@ExperimentMFC 2.1. The experiment file|example experiment@ has five of them. " "For each response category, you supply the area of the screen where a rectangle will be drawn. " "The whole screen measures from 0.0 (left) to 1.0 (right) and from 0.0 (bottom) to 1.0 (top). " "Thus, \"0.2 0.3 0.7 0.8\" means that a rectangle will be drawn somewhere in the top left quadrant " "of the screen. You also supply the text that will be drawn in this rectangle, for instance the text \"h I d\". " "After this you supply the font size for this text, for instance 40.") NORMAL (U"The second text that you supply for every response is a response key on the keyboard. " "In the above example this is \"\", i.e. the subject cannot press a key as a response. " "If you want the user to be able to press the \"m\" key instead of clicking in the \"h I d\" rectangle, " "the line in the experiment file would be:") CODE1 (U"0.2 0.3 0.7 0.8 \"h I d\" 40 \"m\" \"i\"") NORMAL (U"The third text that you supply for each rectangle is the response category as it will be reported by Praat to you when the user clicks it, " "e.g. the text \"i\". If you want Praat to ignore mouse clicks on this rectangle, specify an empty response " "category, i.e. \"\".") NORMAL (U"The border of the rectangles will be maroon, the background of the screen will be light grey. " "The colour of clickable rectangles will be yellow, that of non-clickable rectangles (those with " "empty category specifications) light grey.") NORMAL (U"You can have a picture instead of a text on a response button, by using \\bsFI:") CODE1 (U"0.2 0.3 0.7 0.8 \"\\bsFIpictures/hello.jpg\" 40 \"m\" \"i\"") NORMAL (U"In this example, the picture ##hello.jpg# from the subdirectory #pictures " "(i.e. a subdirectory of the directory where your experiment file is) " "will be drawn into the rectangle [0.2, 0.3] \\xx [0.7, 0.8]. " "This currently (September 2011) works only on the Mac and Windows.") MAN_END MAN_BEGIN (U"ExperimentMFC 2.8. Goodness judgments", U"ppgb", 20051205) NORMAL (U"If %numberOfGoodnessCategories is not 0, some more rectangles will be drawn, " "as in the @@ExperimentMFC 2.1. The experiment file|example experiment@. " "You specify again the locations of these rectangles (in the example, they touch each other), " "and the texts on them. Praat will record the number of the button when the listener clicks on it. " "Thus, if she clicks on the button labelled \"1 (poor)\", Praat will record a goodness judgment of 1, " "because this is the first button in the list. If she clicks on \"5 (good)\", Praat will record a " "goodness judgment of 5.") MAN_END MAN_BEGIN (U"ExperimentMFC 2.9. How an experiment proceeds", U"ppgb", 20110317) NORMAL (U"A text file with an ExperimentMFC object can be read into Praat with @@Read from file...@ " "(it is not a script but a data file, so do not try to read it with ##Open Praat script...#). " "You can then choose #Run. After the experiment finishes, you can close the experiment window " "and choose ##Extract results#. The resulting ResultsMFC object contains for each trial the stimulus " "name (e.g. \"hood\"), the response category (e.g. \"u\"), and the goodness judgment (e.g. 4). " "You will want to save this ResultsMFC object to a text file with @@Save as text file...@. " "You may want to call these text files by the names of the subjects, e.g. ##ts.ResultsMFC# " "and ##mj.ResultsMFC#. Once you have collected the results of all your subjects, you can read " "all the results files into Praat with @@Read from file...@, then select all the resulting " "ResultsMFC objects (which will have automatically been named #ts, #mj, and so on), then choose " "##Collect to table#. This will result in a table whose first column contains the names of the subjects, " "the second column contains the stimulus names, the third column contains the responses, " "and the last column contains the approximate reaction times (measured from the start of the stimulus sound, i.e. after the initial silence duration). " "If there are goodness judgments, these will go into the fourth column. The table can be saved " "as a table file (with ##Save as tab-separated file...#), which can be read by programs like Excel and SPSS.") MAN_END MAN_BEGIN (U"ExperimentMFC 3. More examples", U"ppgb", 20051205) INTRO (U"You can do many more kinds of experiments than simple identification experiments.") LIST_ITEM (U"@@ExperimentMFC 3.1. A simple discrimination experiment") LIST_ITEM (U"@@ExperimentMFC 3.2. An AXB discrimination experiment") LIST_ITEM (U"@@ExperimentMFC 3.3. A 4I-oddity experiment") LIST_ITEM (U"@@ExperimentMFC 3.4. Variable inter-stimulus intervals") MAN_END MAN_BEGIN (U"ExperimentMFC 3.1. A simple discrimination experiment", U"ppgb", 20130416) NORMAL (U"The @@ExperimentMFC 2.1. The experiment file|example experiment@ was an %identification experiment: " "the subject had identify a single sound as one element of a set of categories. " "Phoneticians will often do %discrimination experiments, which are experiments in which " "a stimulus consists of multiple sub-stimuli played in sequence, and the subject has to judge the similarity " "between these sub-stimuli.") NORMAL (U"The simplest discrimination task has only two sub-stimuli, and the subject has to say whether these are " "the %same or %different. Suppose you have vowel-like sounds along an F1 continuum with seven steps, " "say 300, 320, 340, 360, 380, 400, and 420 hertz, and you are interested in knowing how well the listeners " "can distinguish these. As your stimuli, you create pairs of these sounds, separated by 0.8 seconds of silence. " "It is important to include stimuli in which the sounds are identical, e.g. stimuli in which both sounds have an F1 " "of 340 Hz (see the literature on signal detection theory). Since sounds that are very different acoustically " "will always be heard as different, you do not include pairs in which the distance is larger than 60 Hz. " "The experiment file will look like this:") CODE (U"\"ooTextFile\"") CODE (U"\"ExperimentMFC 6\"") CODE (U"blank while playing? ") CODE (U"stimuli are sounds? ") CODE (U"\"stimuli/\" \".wav\"") CODE (U"carrier phrase \"\" \"\"") CODE (U"initial silence duration 0.5 seconds") CODE (U"medial silence duration 0.8 seconds ! inter-stimulus interval") CODE (U"final silence duration 0 seconds") CODE (U"37 different stimuli") CODE1 (U"\"300,300\" \"\" \"300,320\" \"\" \"300,340\" \"\" \"300,360\" \"\"") CODE1 (U"\"320,300\" \"\" \"320,320\" \"\" \"320,340\" \"\" \"320,360\" \"\" \"320,380\" \"\"") CODE1 (U"\"340,300\" \"\" \"340,320\" \"\" \"340,340\" \"\" \"340,360\" \"\" \"340,380\" \"\" \"340,400\" \"\"") CODE1 (U"\"360,300\" \"\" \"360,320\" \"\" \"360,340\" \"\" \"360,360\" \"\" \"360,380\" \"\" \"360,400\" \"\" \"360,420\" \"\"") CODE1 (U"\"380,320\" \"\" \"380,340\" \"\" \"380,360\" \"\" \"380,380\" \"\" \"380,400\" \"\" \"380,420\" \"\"") CODE1 (U"\"400,340\" \"\" \"400,360\" \"\" \"400,380\" \"\" \"400,400\" \"\" \"400,420\" \"\"") CODE1 (U"\"420,360\" \"\" \"420,380\" \"\" \"420,400\" \"\" \"420,420\" \"\"") CODE (U"10 replications per stimulus") CODE (U"break after every 50 stimuli") CODE (U"") CODE (U"\"Click to start.\"") CODE (U"\"Say whether these sounds were the same or different.\"") CODE (U"\"You can have a short break if you like. Click to proceed.\"") CODE (U"\"The experiment has finished. Call the experimenter.\"") CODE (U"0 replays") CODE (U"replay button 0 0 0 0 \"\" \"\"") CODE (U"ok button 0 0 0 0 \"\" \"\"") CODE (U"oops button 0 0 0 0 \"\" \"\"") CODE (U"responses are sounds? \"\" \"\" \"\" \"\" 0 0 0") CODE (U"2 response categories") CODE1 (U"0.1 0.4 0.35 0.65 \"same\" 24 \"\" \"same\"") CODE1 (U"0.6 0.9 0.35 0.65 \"different\" 24 \"\" \"different\"") CODE (U"0 goodness categories") NORMAL (U"In this example, the subject will have to click 370 times. After every 50 times, she will have the " "opportunity to sip her tea. A 0.5-seconds silence is played before every stimulus, so that the listener " "will not hear the stimulus immediately after her mouse click.") NORMAL (U"The experimenter does not have to create the stimulus pairs as sound files. " "You can specify multiple sound files by separating them with commas. Thus, \"320,300\" means that " "Praat will play the files ##320.wav# and ##300.wav#. These two substimuli will be separated here by a silence " "of 0.8 seconds, called the %%inter-stimulus interval% (or %stimulusMedialSilenceDuration).") NORMAL (U"Note that the text in this file is rather different from the previous example. " "It does not matter whether you write \"numberOfDifferentStimuli\", or \"different stimuli\", or anything else; " "Praat ignores these texts as long as they do not contain numbers, quoted strings, or things between <>.") MAN_END MAN_BEGIN (U"ExperimentMFC 3.2. An AXB discrimination experiment", U"ppgb", 20130101) INTRO (U"In the AXB task, the subject will hear three stimuli in sequence, and has to say " "whether the second (X) is more similar to the first (A) or to the second (B). " "An experiment file could look like follows:") CODE (U"\"ooTextFile\"") CODE (U"\"ExperimentMFC 6\"") CODE (U"blankWhilePlaying? ") CODE (U"stimuliAreSounds? ") CODE (U"\"stimuli/\" \".wav\"") CODE (U"carrier \"\" \"\"") CODE (U"initial silence 0.5") CODE (U"inter-stimulus interval 0.3") CODE (U"final silence 0") CODE (U"100 stimuli") CODE1 (U"\"300,300,320\" \"\" \"300,320,340\" \"\" \"300,340,340\" \"\" \"300,340,360\" \"\"") CODE1 (U"...") CODE1 (U"(and 96 more triplets of substimuli)") CODE1 (U"...") CODE (U"4 replications") CODE (U"break every 50") CODE (U"") CODE (U"\"Click to start.\"") CODE (U"\"Say whether the second sound is more similar to the first or to the third.\"") CODE (U"\"You can have a short break if you like. Click to proceed.\"") CODE (U"\"The experiment has finished.\"") CODE (U"0 replays") CODE (U"replay button 0 0 0 0 \"\" \"\"") CODE (U"ok button 0 0 0 0 \"\" \"\"") CODE (U"oops button 0 0 0 0 \"\" \"\"") CODE (U"responses are sounds? \"\" \"\" \"\" \"\" 0 0 0") CODE (U"3 response categories") CODE1 (U"0.1 0.3 0.4 0.6 \"first\" 30 \"\" \"A\"") CODE1 (U"0.4 0.6 0.4 0.6 \"second\" 30 \"\" \"\"") CODE1 (U"0.7 0.9 0.4 0.6 \"third\" 30 \"\" \"B\"") CODE (U"0 goodness categories") NORMAL (U"In this example, the subject has to click 400 times. She sees three buttons, " "labelled %first, %second, and %third, but the second button (the one with the empty response category) " "is not clickable: it has a light grey rather than a yellow interior and cannot be chosen by the subject. " "In your ResultsMFC object, you will only see %A and %B responses.") MAN_END MAN_BEGIN (U"ExperimentMFC 3.3. A 4I-oddity experiment", U"ppgb", 20130101) NORMAL (U"In the four-items-oddity task, the subject will hear four stimuli in sequence, and has to say " "whether the second or the third is the odd one out. The other three substimuli are identical. " "An experiment file could look as follows:") CODE (U"\"ooTextFile\"") CODE (U"\"ExperimentMFC 6\"") CODE (U"blankWhilePlaying? ") CODE (U"stimuliAreSounds? ") CODE (U"stimulusFileNameHead = \"stimuli/\"") CODE (U"stimulusFileNameTail = \".wav\"") CODE (U"stimulusCarrierBefore = \"\"") CODE (U"stimulusCarrierAfter = \"\"") CODE (U"stimulusInitialSilenceDuration = 0.5 seconds") CODE (U"stimulusMedialSilenceDuration = 0.3 seconds") CODE (U"numberOfDifferentStimuli = 60") CODE1 (U"\"300,300,320,300\" \"\" \"300,320,300,300\" \"\"") CODE1 (U"\"300,300,340,300\" \"\" \"300,340,300,300\" \"\"") CODE1 (U"\"300,300,360,300\" \"\" \"300,360,300,300\" \"\"") CODE1 (U"\"320,320,300,320\" \"\" \"320,300,320,320\" \"\"") CODE1 (U"\"320,320,340,320\" \"\" \"320,340,320,320\" \"\"") CODE1 (U"\"320,320,360,320\" \"\" \"320,360,320,320\" \"\"") CODE1 (U"\"320,320,380,320\" \"\" \"320,380,320,320\" \"\"") CODE1 (U"\"340,340,300,340\" \"\" \"340,300,340,340\" \"\"") CODE1 (U"\"340,340,320,340\" \"\" \"340,320,340,340\" \"\"") CODE1 (U"\"340,340,360,340\" \"\" \"340,360,340,340\" \"\"") CODE1 (U"\"340,340,380,340\" \"\" \"340,380,340,340\" \"\"") CODE1 (U"\"340,340,400,340\" \"\" \"340,400,340,340\" \"\"") CODE1 (U"\"360,360,300,360\" \"\" \"360,300,360,360\" \"\"") CODE1 (U"\"360,360,320,360\" \"\" \"360,320,360,360\" \"\"") CODE1 (U"\"360,360,340,360\" \"\" \"360,340,360,360\" \"\"") CODE1 (U"\"360,360,380,360\" \"\" \"360,380,360,360\" \"\"") CODE1 (U"\"360,360,400,360\" \"\" \"360,400,360,360\" \"\"") CODE1 (U"\"360,360,420,360\" \"\" \"360,420,360,360\" \"\"") CODE1 (U"\"380,380,320,380\" \"\" \"380,320,380,380\" \"\"") CODE1 (U"\"380,380,340,380\" \"\" \"380,340,380,380\" \"\"") CODE1 (U"\"380,380,360,380\" \"\" \"380,360,380,380\" \"\"") CODE1 (U"\"380,380,400,380\" \"\" \"380,400,380,380\" \"\"") CODE1 (U"\"380,380,420,380\" \"\" \"380,420,380,380\" \"\"") CODE1 (U"\"400,400,340,400\" \"\" \"400,340,400,400\" \"\"") CODE1 (U"\"400,400,360,400\" \"\" \"400,360,400,400\" \"\"") CODE1 (U"\"400,400,380,400\" \"\" \"400,380,400,400\" \"\"") CODE1 (U"\"400,400,420,400\" \"\" \"400,420,400,400\" \"\"") CODE1 (U"\"420,420,360,420\" \"\" \"420,360,420,420\" \"\"") CODE1 (U"\"420,420,380,420\" \"\" \"420,380,420,420\" \"\"") CODE1 (U"\"420,420,400,420\" \"\" \"420,400,420,420\" \"\"") CODE (U"numberOfReplicationsPerStimulus = 5") CODE (U"breakAfterEvery = 40") CODE (U"randomize = ") CODE (U"startText = \"Click to start.\"") CODE (U"runText = \"Say whether the second or the third sound is different from the rest.\"") CODE (U"pauseText = \"You can have a short break if you like. Click to proceed.\"") CODE (U"endText = \"The experiment has finished.\"") CODE (U"maximumNumberOfReplays = 0") CODE (U"replayButton = 0 0 0 0 \"\" \"\"") CODE (U"okButton = 0 0 0 0 \"\" \"\"") CODE (U"oopsButton = 0 0 0 0 \"\" \"\"") CODE (U"responsesAreSounds? ") CODE (U"responseFileNameHead = \"\"") CODE (U"responseFileNameTail = \"\"") CODE (U"responseCarrierBefore = \"\"") CODE (U"responseCarrierAfter = \"\"") CODE (U"responseInitialSilenceDuration = 0") CODE (U"responseMedialSilenceDuration = 0") CODE (U"responseFinalSilenceDuration = 0") CODE (U"numberOfResponseCategories = 4") CODE1 (U"0.04 0.24 0.4 0.6 \"first\" 30 \"\" \"\"") CODE1 (U"0.28 0.48 0.4 0.6 \"second\" 30 \"\" \"2\"") CODE1 (U"0.52 0.72 0.4 0.6 \"third\" 30 \"\" \"3\"") CODE1 (U"0.76 0.96 0.4 0.6 \"fourth\" 30 \"\" \"\"") CODE (U"numberOfGoodnessCategories = 0") NORMAL (U"In this example, the subject has to click 300 times. She sees four buttons, " "but the first and fourth buttons cannot be chosen. " "In your ResultsMFC object, you will only see the responses %2 and %3.") MAN_END MAN_BEGIN (U"ExperimentMFC 3.4. Variable inter-stimulus intervals", U"ppgb", 20130101) NORMAL (U"Praat only supports a fixed inter-stimulus interval, but sometimes you may want to test " "discrimination as a function of the inter-stimulus interval itself. You can achieve this by " "supplying an %stimulusMedialSilenceDuration of 0 and using sound files with various silences:") CODE1 (U"\"300,silence0.5,320\" \"300,silence1.5,320\" \"300,silence4.5,320\"") NORMAL (U"In this example, you have to supply the sound files ##silence0.5.wav# and so on. You can " "create them with the help of @@Create Sound from formula...@ (supply a %formula of 0).") MAN_END MAN_BEGIN (U"ExperimentMFC 4. Special buttons", U"ppgb", 20051205) INTRO (U"You can include up to three special buttons on the screen that the participant sees. " "It is probably inadvisable to use all three at the same time.") LIST_ITEM (U"@@ExperimentMFC 4.1. The replay button") LIST_ITEM (U"@@ExperimentMFC 4.2. The OK button") LIST_ITEM (U"@@ExperimentMFC 4.3. The oops button") MAN_END MAN_BEGIN (U"ExperimentMFC 4.1. The replay button", U"ppgb", 20051205) INTRO (U"The @@ExperimentMFC 2.1. The experiment file|example experiment@ contained the following lines:") CODE (U"maximumNumberOfReplays = 0") CODE (U"replayButton = 0 0 0 0 \"\" \"\"") NORMAL (U"This means that that experiment did not have a replay button. " "To add a replay button along the lower edge of the screen, you do something like") CODE (U"maximumNumberOfReplays = 1000") CODE (U"replayButton = 0.3 0.7 0.01 0.07 \"Click here to play the last sound again\" \"\"") NORMAL (U"If you supply a right edge (here 0.7) that is greater than the left edge (here 0.3), " "Praat will know that you want to show a replay button.") NORMAL (U"When the participant clicks this button, Praat will play the current stimulus again. " "In this example, the button will be visible until the partipant has clicked it 1000 times.") NORMAL (U"To assign a keyboard shortcut to the replay button, do something like") CODE (U"maximumNumberOfReplays = 1000") CODE (U"replayButton = 0.1 0.9 0.01 0.07 \"Click here or press the space bar to play the last sound again\" \" \"") MAN_END MAN_BEGIN (U"ExperimentMFC 4.2. The OK button", U"ppgb", 20051205) INTRO (U"The @@ExperimentMFC 2.1. The experiment file|example experiment@ contained the following lines:") CODE (U"okButton = 0 0 0 0 \"\" \"\"") NORMAL (U"This means that that experiment did not have an OK button. " "To add an OK button in the lower right corner of the screen, you do something likw") CODE (U"okButton = 0.8 0.95 0.05 0.15 \"OK\" \"\"") NORMAL (U"If you supply a right edge (here 0.95) that is greater than the left edge (here 0.8), " "Praat will know that you want to show an OK button.") NORMAL (U"The behaviour of the experiment changes appreciably if you include an OK button. " "If you do not include an OK button, Praat will present the next stimulus as soon as the participant " "has clicked a response category (and a goodness category, if there are such). " "If you do include an OK button, it will become visible to the participant as soon as she has chosen " "a response category (and a goodness category, if there are such). " "The participant can then click the OK button, but she can also choose to click the response " "(and goodness buttons) a bit more first.") NORMAL (U"The OK button seems to be useful only if there is also a replay button, " "or if the response categories are sounds (see @@ExperimentMFC 6. Responses are sounds@).") NORMAL (U"To assign a keyboard shortcut (here, the space bar) to the OK button, do something like") CODE (U"okButton = 0.8 0.95 0.05 0.15 \"OK\" \" \"") MAN_END MAN_BEGIN (U"ExperimentMFC 4.3. The oops button", U"ppgb", 20051205) INTRO (U"The @@ExperimentMFC 2.1. The experiment file|example experiment@ contained the following lines:") CODE (U"oopsButton = 0 0 0 0 \"\" \"\"") NORMAL (U"This means that that experiment did not have an oops button. " "To add an oops button in the lower left corner of the screen, you do something likw") CODE (U"oopsButton = 0.05 0.2 0.05 0.15 \"oops\" \"\"") NORMAL (U"If you supply a right edge (here 0.2) that is greater than the left edge (here 0.05), " "Praat will know that you want to show an oops button.") NORMAL (U"If you include an oops button, it will become visible to the participant for every stimulus except the first, " "and it will also be visible on the pause (break) screens and on the final screen.") NORMAL (U"If the participant clicks the oops button, Praat will forget everything the participant did " "with the current stimulus and the previous stimulus. The experiment will continue with playing " "the previous stimulus again and waiting for the participant's choice.") MAN_END MAN_BEGIN (U"ExperimentMFC 5. Stimulus-dependent texts", U"ppgb", 20051205) INTRO (U"In the @@ExperimentMFC 2.1. The experiment file|example experiment@, the text at the top of the screen " "stayed the same throughout the experiment, and so did the texts on the response buttons. " "There are ways to have these texts depend on the stimulus at hand.") LIST_ITEM (U"@@ExperimentMFC 5.1. The stimulus-dependent run text") LIST_ITEM (U"@@ExperimentMFC 5.2. Stimulus-dependent response buttons") MAN_END MAN_BEGIN (U"ExperimentMFC 5.1. The stimulus-dependent run text", U"ppgb", 20051205) INTRO (U"The @@ExperimentMFC 2.1. The experiment file|example experiment@ contained the following lines:") CODE (U"numberOfDifferentStimuli = 4") CODE1 (U"\"heed\" \"\"") CODE1 (U"\"hid\" \"\"") CODE1 (U"\"hood\" \"\"") CODE1 (U"\"hud\" \"\"") CODE (U"...") CODE (U"...") CODE (U"runText = \"Choose the vowel that you heard.\"") NORMAL (U"For every stimulus, the same `run text' was written at the top of the screen. " "But suppose you want to make that text dependent on the stimulus. You would do:") CODE1 (U"\"heed\" \"Choose the vowel you heard.\"") CODE1 (U"\"hid\" \"Click the vowel you heard.\"") CODE1 (U"\"hood\" \"Select the vowel you heard.\"") CODE1 (U"\"hud\" \"What's the vowel you heard?\"") CODE (U"...") CODE (U"...") CODE (U"runText = \"\"") NORMAL (U"In this case, each stimulus comes with its own text. The %runText will only show up for stimuli " "for which you do not supply a separate text.") NORMAL (U"This feature is useful mainly in cases where the responses are sounds but the stimulus is not " "(see @@ExperimentMFC 6. Responses are sounds@) or if you want to cause some lexical priming.") MAN_END MAN_BEGIN (U"ExperimentMFC 5.2. Stimulus-dependent response buttons", U"ppgb", 20070926) INTRO (U"The @@ExperimentMFC 2.1. The experiment file|example experiment@ contained the following lines:") CODE (U"numberOfDifferentStimuli = 4") CODE1 (U"\"heed\" \"\"") CODE1 (U"\"hid\" \"\"") CODE1 (U"\"hood\" \"\"") CODE1 (U"\"hud\" \"\"") CODE (U"...") CODE (U"...") CODE (U"numberOfDifferentResponses = 5") CODE1 (U"0.2 0.3 0.7 0.8 \"h I d\" 40 \"\" \"i\"") CODE1 (U"0.3 0.4 0.5 0.6 \"h E d\" 40 \"\" \"e\"") CODE1 (U"0.4 0.5 0.3 0.4 \"h A d\" 40 \"\" \"a\"") CODE1 (U"0.5 0.6 0.5 0.6 \"h O d\" 40 \"\" \"o\"") CODE1 (U"0.6 0.7 0.7 0.8 \"h U d\" 40 \"\" \"u\"") NORMAL (U"For every stimulus, the buttons contained the same visible texts, such as \"h I d\" and \"h A d\".") NORMAL (U"But suppose you have an experiment about the perception of voicing in plosives. " "The first stimulus starts with an ambiguous /b/ or /p/, and you want the participant " "to choose between \"bath\" and \"path\". The next stimulus starts with an ambiguous /d/ or /t/, " "and you want the participant to choose between \"dart\" and \"tart\". " "You would go about like this:") CODE (U"numberOfDifferentStimuli = 6") CODE1 (U"\"bpath1\" \"|bath|path\"") CODE1 (U"\"bpath2\" \"|bath|path\"") CODE1 (U"\"bpath3\" \"|bath|path\"") CODE1 (U"\"dtart1\" \"|dart|tart\"") CODE1 (U"\"dtart2\" \"|dart|tart\"") CODE1 (U"\"dtart3\" \"|dart|tart\"") CODE (U"...") CODE (U"...") CODE (U"numberOfDifferentResponses = 2") CODE1 (U"0.2 0.4 0.7 0.8 \"\" 40 \"\" \"left\"") CODE1 (U"0.6 0.8 0.7 0.8 \"\" 40 \"\" \"right\"") NORMAL (U"In this case, the two response buttons show either \"path\" and \"path\", or \"dart\" and \"tart\".") NORMAL (U"In the ResultsMFC (see @@ExperimentMFC 2.9. How an experiment proceeds@), " "the stimuli will be recorded as \"bpath1|bath|path\" and the like, not just as \"bpath1\". " "Praat does this in order to be able to cope with balanced designs such as") CODE1 (U"\"bpath1\" \"|bath|path\"") CODE1 (U"\"bpath1\" \"|path|bath\"") NORMAL (U"In other words, the button ordering is considered part of the stimulus.") NORMAL (U"This trick can be combined with a stimulus-dependent run text:") CODE (U"numberOfDifferentStimuli = 32") CODE1 (U"\"bpath1\" \"Throw a...|bath|path\"") CODE1 (U"\"bpath1\" \"Walk a...|bath|path\"") CODE1 (U"\"bpath2\" \"Walk a...|bath|path\"") CODE1 (U"\"dtart1\" \"Throw a...|dart|tart\"") CODE1 (U"\"dtart1\" \"Carry a...|dart|tart\"") CODE (U"...") CODE (U"runText = \"\"") CODE (U"...") CODE (U"numberOfDifferentResponses = 2") CODE1 (U"0.2 0.4 0.7 0.8 \"\" 40 \"\" \"left\"") CODE1 (U"0.6 0.8 0.7 0.8 \"\" 40 \"\" \"right\"") MAN_END MAN_BEGIN (U"ExperimentMFC 6. Responses are sounds", U"ppgb", 20130101) INTRO (U"In the @@ExperimentMFC 2.1. The experiment file|example experiment@, " "the stimuli were sounds, and the responses were categories whose labels appeared on buttons. " "Sometimes you want it the other way around.") NORMAL (U"An example is the %%/i/ prototype% task: the top of the screen just says \"Please choose the best %ee\", " "and no stimulus sound is played. Instead, the participant can click repeatedly on an array of 40 buttons, " "each of which contains a different [i]-like sound. That is, if the participant clicks on a response button, " "an [i]-like sound is played, and every response button has its own sound.") NORMAL (U"Such a task can be regarded as reversing the task of the example experiment, " "in which the stimulus was a sound and the reponse was a phonological category. " "In the /i/ prototype task, the stimulus is a phonological category, and the response is a sound.") NORMAL (U"This is what the experiment file could look like:") CODE (U"\"ooTextFile\"") CODE (U"\"ExperimentMFC 6\"") CODE (U"blankWhilePlaying? ") CODE (U"stimuliAreSounds? \"\" \"\" \"\" \"\" 0 0 0") CODE (U"numberOfDifferentStimuli = 2") CODE1 (U"\"i\" \"Choose the best \\% \\% ee\\% .\"") CODE1 (U"\"I\" \"Choose the best \\% \\% i\\% .\"") CODE (U"numberOfReplicationsPerStimulus = 1") CODE (U"breakAfterEvery = 1") CODE (U"randomize = ") CODE (U"startText = \"Click to start.\"") CODE (U"runText = \"\"") CODE (U"pauseText = \"You can have a short break if you like. Click to proceed.\"") CODE (U"endText = \"The experiment has finished.\"") CODE (U"maximumNumberOfReplays = 0") CODE (U"replayButton = 0 0 0 0 \"\" \"\"") CODE (U"okButton = 0.8 0.95 0.45 0.55 \"OK\" \"\"") CODE (U"oopsButton = 0 0 0 0 \"\" \"\"") CODE (U"responsesAreSounds? ") CODE (U"responseFileNameHead = \"Sounds/\"") CODE (U"responseFileNameTail = \".wav\"") CODE (U"responseCarrierBefore = \"\"") CODE (U"responseCarrierAfter = \"\"") CODE (U"responseInitialSilenceDuration = 0.3") CODE (U"responseMedialSilenceDuration = 0") CODE (U"responseFinalSilenceDuration = 0") CODE (U"numberOfDifferentResponses = 16") CODE1 (U"0.2 0.3 0.7 0.8 \"\" 10 \"\" \"i11\"") CODE1 (U"0.3 0.4 0.7 0.8 \"\" 10 \"\" \"i12\"") CODE1 (U"0.4 0.5 0.7 0.8 \"\" 10 \"\" \"i13\"") CODE1 (U"0.5 0.6 0.7 0.8 \"\" 10 \"\" \"i14\"") CODE1 (U"0.2 0.3 0.6 0.7 \"\" 10 \"\" \"i21\"") CODE1 (U"0.3 0.4 0.6 0.7 \"\" 10 \"\" \"i22\"") CODE1 (U"0.4 0.5 0.6 0.7 \"\" 10 \"\" \"i23\"") CODE1 (U"0.5 0.6 0.6 0.7 \"\" 10 \"\" \"i24\"") CODE1 (U"0.2 0.3 0.5 0.6 \"\" 10 \"\" \"i31\"") CODE1 (U"0.3 0.4 0.5 0.6 \"\" 10 \"\" \"i32\"") CODE1 (U"0.4 0.5 0.5 0.6 \"\" 10 \"\" \"i33\"") CODE1 (U"0.5 0.6 0.5 0.6 \"\" 10 \"\" \"i34\"") CODE1 (U"0.2 0.3 0.4 0.5 \"\" 10 \"\" \"i41\"") CODE1 (U"0.3 0.4 0.4 0.5 \"\" 10 \"\" \"i42\"") CODE1 (U"0.4 0.5 0.4 0.5 \"\" 10 \"\" \"i43\"") CODE1 (U"0.5 0.6 0.4 0.5 \"\" 10 \"\" \"i44\"") CODE (U"numberOfGoodnessCategories = 5") CODE1 (U"0.25 0.35 0.10 0.20 \"1 (poor)\"") CODE1 (U"0.35 0.45 0.10 0.20 \"2\"") CODE1 (U"0.45 0.55 0.10 0.20 \"3\"") CODE1 (U"0.55 0.65 0.10 0.20 \"4\"") CODE1 (U"0.65 0.75 0.10 0.20 \"5 (good)\"") NORMAL (U"The participant will see 16 squares on the screen. First she will have to find the best /i/, " "then the best /\\ic/. The sound files ##Sounds/i11.wav# and so on must exist and have the same sampling frequency. " "A silence of 0.3 seconds is played just before each response sound.") MAN_END MAN_BEGIN (U"ExperimentMFC 7. Blanking the screen", U"ppgb", 20130102) INTRO (U"In all the earlier examples, the flag %blankWhilePlaying was set to . This means that in all those cases " "the participant will immediately see the response categories when the sound starts playing " "(or even earlier, if there is an initial silence).") NORMAL (U"This can be changed by setting %blankWhilePlaying to . When you do that, the participant will see a blank screen " "while the stimulus is playing, and the response buttons will come up only after the sound has finished. " "This is useful if you want to prevent the participant from clicking before the sound has finished, " "or for priming experiments. Reaction times are measured from when the response buttons appear.") NORMAL (U"If you want the response buttons to come up 0.5 seconds after the sound finishes playing, " "you set the %stimulusFinalSilenceDuration to 0.5.") MAN_END MAN_BEGIN (U"ExperimentMFC 8. Running multiple experiments", U"ppgb", 20130101) INTRO (U"In all the earlier examples, either the set of stimulus sounds or the set of response sounds stayed " "the same throughout the experiment. If you want more than one set of stimuli, or more than one set of responses, " "you can run several experiments after each other, simply by selecting more than one experiment, then clicking #Run.") NORMAL (U"You can put all these ExperimentMFC objects in one text file. The following example contains two experiments. " "The second line has to contain the text \"Collection\", followed by the number of experiments:") CODE (U"\"ooTextFile\"") CODE (U"\"Collection\" 2") CODE (U"") CODE (U"\"ExperimentMFC 6\" \"i\"") CODE (U"blankWhilePlaying? ") CODE (U"stimuliAreSounds? \"\" \"\" \"\" \"\" 0 0 0") CODE (U"numberOfDifferentStimuli = 1") CODE1 (U"\"i\" \"Choose the best \\% \\% ee\\% .\"") CODE (U"numberOfReplicationsPerStimulus = 1") CODE (U"breakAfterEvery = 0") CODE (U"randomize = ") CODE (U"startText = \"You are going to choose the best \\% \\% ee\\% . Click to start.\"") CODE (U"runText = \"\"") CODE (U"pauseText = \"\"") CODE (U"endText = \"Thank you for choosing the best \\% \\% ee\\% . Click to proceed.\"") CODE (U"maximumNumberOfReplays = 0") CODE (U"replayButton = 0 0 0 0 \"\" \"\"") CODE (U"okButton = 0.8 0.95 0.45 0.55 \"OK\" \"\"") CODE (U"oopsButton = 0 0 0 0 \"\" \"\"") CODE (U"responsesAreSounds? ") CODE (U"responseFileNameHead = \"Sounds/\"") CODE (U"responseFileNameTail = \".wav\"") CODE (U"responseCarrierBefore = \"\"") CODE (U"responseCarrierAfter = \"\"") CODE (U"responseInitialSilenceDuration = 0.3") CODE (U"responseMedialSilenceDuration = 0") CODE (U"responseFinalSilenceDuration = 0") CODE (U"numberOfDifferentResponses = 6") CODE1 (U"0.2 0.3 0.7 0.8 \"\" 10 \"\" \"i1\"") CODE1 (U"0.3 0.4 0.7 0.8 \"\" 10 \"\" \"i2\"") CODE1 (U"0.4 0.5 0.7 0.8 \"\" 10 \"\" \"i3\"") CODE1 (U"0.5 0.6 0.7 0.8 \"\" 10 \"\" \"i4\"") CODE1 (U"0.6 0.7 0.7 0.8 \"\" 10 \"\" \"i5\"") CODE1 (U"0.7 0.8 0.7 0.8 \"\" 10 \"\" \"i6\"") CODE (U"numberOfGoodnessCategories = 0") CODE (U"") CODE (U"\"ExperimentMFC 6\" \"u\"") CODE (U"blankWhilePlaying? ") CODE (U"stimuliAreSounds? \"\" \"\" \"\" \"\" 0 0 0") CODE (U"numberOfDifferentStimuli = 1") CODE1 (U"\"u\" \"Choose the best \\% \\% oo\\% .\"") CODE (U"numberOfReplicationsPerStimulus = 1") CODE (U"breakAfterEvery = 0") CODE (U"randomize = ") CODE (U"startText = \"You are going to choose the best \\% \\% oo\\% . Click to start.\"") CODE (U"runText = \"\"") CODE (U"pauseText = \"\"") CODE (U"endText = \"All the experiments have finished. You can call the experimenter.\"") CODE (U"maximumNumberOfReplays = 0") CODE (U"replayButton = 0 0 0 0 \"\" \"\"") CODE (U"okButton = 0.8 0.95 0.45 0.55 \"OK\" \"\"") CODE (U"oopsButton = 0 0 0 0 \"\" \"\"") CODE (U"responsesAreSounds? ") CODE (U"responseFileNameHead = \"Sounds/\"") CODE (U"responseFileNameTail = \".wav\"") CODE (U"responseCarrierBefore = \"\"") CODE (U"responseCarrierAfter = \"\"") CODE (U"responseInitialSilenceDuration = 0.3") CODE (U"responseMedialSilenceDuration = 0") CODE (U"responseFinalSilenceDuration = 0") CODE (U"numberOfDifferentResponses = 6") CODE1 (U"0.2 0.3 0.7 0.8 \"\" 10 \"\" \"u1\"") CODE1 (U"0.3 0.4 0.7 0.8 \"\" 10 \"\" \"u2\"") CODE1 (U"0.4 0.5 0.7 0.8 \"\" 10 \"\" \"u3\"") CODE1 (U"0.5 0.6 0.7 0.8 \"\" 10 \"\" \"u4\"") CODE1 (U"0.6 0.7 0.7 0.8 \"\" 10 \"\" \"u5\"") CODE1 (U"0.7 0.8 0.7 0.8 \"\" 10 \"\" \"u6\"") CODE (U"numberOfGoodnessCategories = 0") NORMAL (U"In this example, the participant first has to choose the best /i/ from among six [i]-like sounds, " "which are in the sound files ##i1.wav# through ##i6.wav#. After that, she has to choose the best /u/ " "from among six [u]-like sounds, which are in the sound files ##u1.wav# through ##u6.wav#. " "The percent signs in \\% \\% ee\\% mean that %ee will be italicized.") NORMAL (U"If you read this file with ##Read from file...#, you will see two ExperimentMFC objects, " "named #i and #u. They both stand selected. You then click #Run, and after the participant finishes, " "you select both ExperimentMFC objects again (probably they still stand selected), and click ##Extract results#. " "You will then get two #ResultMFC objects.") MAN_END } /* End of file manual_Exp.cpp */ praat-6.0.04/fon/manual_Fon.cpp000066400000000000000000003576271261542461700163110ustar00rootroot00000000000000/* manual_Fon.cpp * * Copyright (C) 1992-2011,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ManPagesM.h" static void draw_CreateDurationTier (Graphics g) { static double x [] = { 0.0, 0.3, 0.6, 0.7, 0.9 }, y [] = { 1.0, 1.0, 2.3, 1.0, 1.0 }; Graphics_setWindow (g, 0.0, 0.9, 0.0, 2.5); Graphics_drawInnerBox (g); Graphics_marksLeftEvery (g, 1.0, 1.0, true, true, false); Graphics_marksBottomEvery (g, 1.0, 0.1, true, true, false); Graphics_setInner (g); Graphics_setColour (g, Graphics_RED); Graphics_polyline (g, 5, x, y); Graphics_setColour (g, Graphics_BLACK); Graphics_unsetInner (g); Graphics_textBottom (g, true, U"Time (s)"); Graphics_textLeft (g, true, U"Relative duration"); } void manual_Sampling_init (ManPages me); void manual_sound_init (ManPages me); void manual_pitch_init (ManPages me); void manual_spectrum_init (ManPages me); void manual_formant_init (ManPages me); void manual_annotation_init (ManPages me); void manual_Fon_init (ManPages me); void manual_Fon_init (ManPages me) { manual_Sampling_init (me); manual_sound_init (me); manual_pitch_init (me); manual_spectrum_init (me); manual_formant_init (me); manual_annotation_init (me); MAN_BEGIN (U"Get high index from time...", U"ppgb", 20101230) INTRO (U"A @query to ask the selected tier object " "(@DurationTier, @IntensityTier, @PitchTier) " "which point is nearest to, but no earlier than, the specified time.") ENTRY (U"Setting") TAG (U"##Time (s)") DEFINITION (U"the time from which you want to get the point index.") ENTRY (U"Return value") NORMAL (U"This query returns the index of the point with the lowest time greater than or equal to #Time. " "It is @undefined if there are no points. " "It is the number of points plus 1 (offright) if the specified time is greater than the time of the last point.") MAN_END MAN_BEGIN (U"Get low index from time...", U"ppgb", 20101230) INTRO (U"A @query to ask the selected tier object " "(@DurationTier, @IntensityTier, @PitchTier) " "which point is nearest to, but no later than, the specified time.") ENTRY (U"Setting") TAG (U"##Time (s)") DEFINITION (U"the time from which you want to get the point index.") ENTRY (U"Return value") NORMAL (U"This query returns the index of the point with the highest time less than or equal to #Time. " "It is @undefined if there are no points. " "It is 0 (offleft) if the specified time is less than the time of the first point.") MAN_END MAN_BEGIN (U"Get nearest index from time...", U"ppgb", 20101230) INTRO (U"A @query to ask the selected tier object " "(@DurationTier, @IntensityTier, @PitchTier) " "which point is nearest to the specified time.") ENTRY (U"Setting") TAG (U"##Time (s)") DEFINITION (U"the time near which you want to get the point index.") ENTRY (U"Return value") NORMAL (U"This query returns the index of the point with the highest time less than or equal to #Time. " "It is @undefined if there are no points.") MAN_END MAN_BEGIN (U"Remove point...", U"ppgb", 20101230) INTRO (U"A command to remove one point from every selected time-based tier object " "(@DurationTier, @IntensityTier, @PitchTier).") ENTRY (U"Setting") TAG (U"##Point number") DEFINITION (U"the index of the point you want to remove.") ENTRY (U"Behaviour") NORMAL (U"If ##Point number# is 3, the third point counted from the start of the tier (if it exists) " "is removed from the tier.") MAN_END MAN_BEGIN (U"Remove point near...", U"ppgb", 20101230) INTRO (U"A command to remove one point from every selected time-based tier object " "(@DurationTier, @IntensityTier, @PitchTier).") ENTRY (U"Setting") TAG (U"##Time (s)") DEFINITION (U"the time near which you want to remove a point.") ENTRY (U"Behaviour") NORMAL (U"The point nearest to #Time (if there is any point) is removed from the tier.") MAN_END MAN_BEGIN (U"Remove points between...", U"ppgb", 20101230) INTRO (U"A command to remove some points from every selected time-based tier object " "(@DurationTier, @IntensityTier, @PitchTier).") ENTRY (U"Settings") TAG (U"##From time (s)") TAG (U"##To time (s)") DEFINITION (U"the times between which you want to remove all points.") ENTRY (U"Behaviour") NORMAL (U"Any points between ##Frome time# and ##To Time# (inclusive) are removed from the tier.") MAN_END MAN_BEGIN (U"AmplitudeTier", U"ppgb", 20070825) INTRO (U"One of the @@types of objects@ in Praat. " "An AmplitudeTier object represents a time-stamped amplitude contour, i.e., it contains a series of (%time, %amplitude) points. " "The amplitude values are in Pascal. To see some applications, consult the @IntensityTier information; " "the difference between an AmplitudeTier and an IntensityTier is that the former has values in Pascal " "which multiply linearly with a Sound (for instance), and the latter has values in dB, " "which multiply logarithmically with a Sound.") MAN_END MAN_BEGIN (U"Cochleagram", U"ppgb", 20030316) INTRO (U"One of the @@types of objects@ in Praat. It represents the excitation pattern " "of the basilar membrane in the inner ear (see @Excitation) as a function of time.") MAN_END MAN_BEGIN (U"Cochleagram: Formula...", U"ppgb", 20021206) INTRO (U"A command for changing the data in all selected @Cochleagram objects.") NORMAL (U"See the @Formulas tutorial for examples and explanations.") MAN_END MAN_BEGIN (U"Create DurationTier...", U"ppgb", 20140421) INTRO (U"A command in the @@New menu@ to create an empty @DurationTier object.") NORMAL (U"The resulting object will have the specified name and time domain, but contain no duration points. " "To add some points to it, use @@DurationTier: Add point...@.") ENTRY (U"Scripting example") NORMAL (U"To create a tier 0.9 seconds long, with an deceleration around 0.6 seconds, you do:") CODE (U"Create DurationTier: \"dur\", 0, 0.9") CODE (U"Add point: 0.3, 1") CODE (U"Add point: 0.6, 2.3") CODE (U"Add point: 0.7, 1") NORMAL (U"The result will look like") PICTURE (5, 2.5, draw_CreateDurationTier) NORMAL (U"The target duration will be the area under this curve, which is 0.9 + 1/2 · 1.3 · 0.4 = 1.16 seconds.") MAN_END MAN_BEGIN (U"Create empty PointProcess...", U"ppgb", 20021204) INTRO (U"A command in the @@New menu@ to create an empty @PointProcess. The newly created object is put in the list of objects.") MAN_END MAN_BEGIN (U"Create IntensityTier...", U"ppgb", 20021204) INTRO (U"A command in the @@New menu@ to create an empty @IntensityTier object.") NORMAL (U"The resulting object will have the specified name and time domain, but contain no formant points. " "To add some points to it, use @@IntensityTier: Add point...@.") NORMAL (U"For an example, see @@Source-filter synthesis@.") MAN_END MAN_BEGIN (U"Create Matrix...", U"ppgb", 20021212) INTRO (U"A command in the @@New menu@ to create a @Matrix with the specified sampling attributes, " "filled with values from a formula (see @@Matrix: Formula...@).") MAN_END MAN_BEGIN (U"Create Poisson process...", U"ppgb", 20041005) INTRO (U"A command to create a @PointProcess object that represents a Poisson process.") NORMAL (U"A Poisson process is a stationary point process with a fixed density %λ, " "which means that there are, on the average, %λ events per second.") ENTRY (U"Settings") TAG (U"##Start time (s)") DEFINITION (U"%t__%min_, the beginning of the time domain, in seconds.") TAG (U"##End time (s)") DEFINITION (U"%t__%max_, the end of the time domain, in seconds.") TAG (U"##Density (Hz)") DEFINITION (U"the average number of points per second.") ENTRY (U"Algorithm") NORMAL (U"First, the number of points %N in the time domain is determined. Its expectation value is") FORMULA (U"%λ = (%t__%max_ – %t__%min_) · %density") NORMAL (U"but its actual value is taken from the Poisson distribution:") FORMULA (U"%p(%n) = (%%λ^n% / %n!) %e^^–%λ") NORMAL (U"Then, %N points are computed throughout the time domain, according to a uniform distribution:") FORMULA (U"%p(%t) = 1 / (%t__%max_ – %t__%min_) for %t ∈ [%t__%min_, %t__%max_]") FORMULA (U"%p(%t) = 0 outside [%t__%min_, %t__%max_]") MAN_END MAN_BEGIN (U"Create simple Matrix...", U"ppgb", 20021204) INTRO (U"A command in the @@New menu@ to create a @Matrix with the specified number of rows and columns, " "filled with values from a formula (see @@Matrix: Formula...@).") MAN_END MAN_BEGIN (U"Create Strings as directory list...", U"ppgb", 20060919) INTRO (U"A command in the @@New menu@ to create a @Strings object containing a list of directories in a given parent directory. " "It works completely analogously to @@Create Strings as file list...@.") MAN_END MAN_BEGIN (U"Create Strings as file list...", U"ppgb", 20150713) INTRO (U"A command in the @@New menu@ to create a @Strings object containing a list of files in a given directory.") ENTRY (U"Settings") SCRIPT (5.4, Manual_SETTINGS_WINDOW_HEIGHT (2.6), U"" Manual_DRAW_SETTINGS_WINDOW ("Create Strings as file list", 2.6) Manual_DRAW_SETTINGS_WINDOW_FIELD ("Name", "fileList") Manual_DRAW_SETTINGS_WINDOW_TEXT ("File path", "/Users/miep/Sounds/*.wav") ) TAG (U"##Name") DEFINITION (U"the name of the resulting Strings object.") TAG (U"##File path") DEFINITION (U"the directory name, with an optional %wildcard (see below) for selecting files.") ENTRY (U"Behaviour") NORMAL (U"The resulting Strings object will contain an alphabetical list of file names, " "without the preceding path through the directory structures. If there are no files that match the file path, " "the Strings object will contain no strings.") ENTRY (U"Usage") NORMAL (U"There are two ways to specify the file path.") NORMAL (U"One way is to specify a directory name only. On Unix, the file path could be " "##/usr/people/miep/sounds# or ##/usr/people/miep/sounds/#, for instance. On Windows, " "##C:\\bsUsers\\bsMiep\\bsSounds# or ##C:\\bsUsers\\bsMiep\\bsSounds\\bs#. " "On Macintosh, ##/Users/miep/Sounds# or ##/Users/miep/Sounds/#. Any of these produce " "a list of all the files in the specified directory.") NORMAL (U"The other way is to specify a wildcard (a single asterisk) for the file names. " "To get a list of all the files whose names start with \"hal\" and end in \".wav\", " "type ##/usr/people/miep/sounds/hal*.wav#, ##C:\\bsUsers\\bsMiep\\bsSounds\\bshal*.wav#, " "or ##/Users/miep/Sounds/hal*.wav#.") ENTRY (U"Script usage") NORMAL (U"In a script, you can use this command to cycle through the files in a directory. " "For instance, to read in all the sound files in a specified directory, " "you could use the following script:") CODE (U"directory\\$ = \"/usr/people/miep/sounds\"") CODE (U"strings = Create Strings as file list: \"list\", directory\\$ + \"/*.wav\"") CODE (U"numberOfFiles = Get number of strings") CODE (U"for ifile to numberOfFiles") CODE1 (U"selectObject: strings") CODE1 (U"fileName\\$ = Get string: ifile") CODE1 (U"Read from file: directory\\$ + \"/\" + fileName\\$ ") CODE (U"endfor") NORMAL (U"If the script has been saved to a script file, you can use file paths that are relative to the directory " "where you saved the script. Thus, with") CODE (U"Create Strings as file list: \"list\", \"*.wav\"") NORMAL (U"you get a list of all the .wav files that are in the same directory as the script that contains this line. " "And to get a list of all the .wav files in the directory Sounds that resides in the same directory as your script, " "you can do") CODE (U"Create Strings as file list: \"list\", \"Sounds/*.wav\"") NORMAL (U"As is usual in Praat scripting, the forward slash (\"/\") in this example can be used on all platforms, including Windows. " "This makes your script portable across platforms.") ENTRY (U"See also") NORMAL (U"To get a list of directories instead of files, use @@Create Strings as directory list...@.") MAN_END MAN_BEGIN (U"Distributions", U"ppgb", 20030316) INTRO (U"One of the @@types of objects@ in Praat. Inherits most actions from @TableOfReal.") ENTRY (U"Actions") LIST_ITEM (U"@@Distributions: To Strings...@") MAN_END MAN_BEGIN (U"Distributions: To Strings...", U"ppgb", 19971022) INTRO (U"A command to create a @Strings object from every selected @Distributions object.") ENTRY (U"Settings") TAG (U"##Column number") DEFINITION (U"the column (in the #Distributions object) that contains the distribution that you are " "interested in. Often the #Distributions object will only contain a single distribution, " "so this argument will often be 1. If the #Distributions object contains nine distributions, " "specify any number between 1 and 9.") TAG (U"##Number of strings") DEFINITION (U"the number of times a string will be drawn from the chosen distribution. " "This is the number of strings that the resulting @Strings object is going to contain.") ENTRY (U"Behaviour") NORMAL (U"Every string in the resulting #Strings object will be a row label of the #Distributions object. " "The number in each row at the specified column will be considered the relative frequency of " "occurrence of that row.") NORMAL (U"%#Example. Suppose we have the following #Distributions:") CODE (U"File type = \"ooTextFile\"") CODE (U"Object class = \"Distributions\"") CODE (U"2 (number of columns)") CODE (U" \"English\" \"French\" (column labels)") CODE (U"3 (number of rows)") CODE (U"\"the\" 108 1.5") CODE (U"\"a\" 58.1 33") CODE (U"\"pour\" 0.7 15.5") NORMAL (U"If you set %Column to 1 and %%Number of strings% to 1000, " "you will get a @Strings object with approximately 647 occurrences of \"the\", " "348 occurrences of \"a\", and 4 occurrences of \"pour\". " "If you had set %Column to 2 (\"French\"), you would have gotten about " "30 times \"the\", 660 times \"a\", and 310 times \"pour\". " "The actual numbers will vary because the choice of a string will not depend on previous choices.") MAN_END MAN_BEGIN (U"DurationTier", U"ppgb", 20030316) INTRO (U"One of the @@types of objects@ in Praat. " "A DurationTier object contains a number of (%time, %duration) points, " "where %duration is to be interpreted as a relative duration (e.g. the duration of a manipulated sound " "as compared to the duration of the original). For instance, " "if your DurationTier contains two points, one with a duration value of 1.5 at a time of 0.5 seconds " "and one with a duration value of 0.6 at a time of 1.1 seconds, this is to be interpreted as " "a relative duration of 1.5 (i.e. a slowing down) for all original times before 0.5 seconds, " "a relative duration of 0.6 (i.e. a speeding up) for all original times after 1.1 seconds, " "and a linear interpolation between 0.5 and 1.1 seconds (e.g. a relative duration of " "1.2 at 0.7 seconds, and of 0.9 at 0.9 seconds).") NORMAL (U"See @@Intro 8.2. Manipulation of duration@ and @@Create DurationTier...@.") MAN_END MAN_BEGIN (U"DurationTier: Add point...", U"ppgb", 20030216) INTRO (U"A command to add a point to each selected @DurationTier. " "For an example, see @@Create DurationTier...@.") ENTRY (U"Settings") TAG (U"##Time (s)") DEFINITION (U"the time at which a point is to be added.") TAG (U"##Relative duration") DEFINITION (U"the relative duration value of the requested new point.") ENTRY (U"Behaviour") NORMAL (U"The tier is modified so that it contains the new point. " "If a point at the specified time was already present in the tier, nothing happens.") MAN_END MAN_BEGIN (U"DurationTier: Get target duration...", U"ppgb", 20101228) INTRO (U"A @query to the selected @DurationTier for the target duration of a specified time range.") ENTRY (U"Settings") TAG (U"##From time (s)") TAG (U"##To time (s)") DEFINITION (U"the start and end of the (original) time range.") ENTRY (U"Return value") NORMAL (U"the target duration in seconds.") MAN_END MAN_BEGIN (U"DurationTierEditor", U"ppgb", 20110128) INTRO (U"One of the @editors in the Praat program, for viewing and editing a @DurationTier object. " "To create a DurationTierEditor window, select a DurationTier and click ##View & Edit#.") MAN_END MAN_BEGIN (U"Editors", U"ppgb", 20110128) INTRO (U"Many @@types of objects@ in Praat can be viewed and edited in their own windows.") ENTRY (U"Editor windows") LIST_ITEM (U"• @SoundEditor") LIST_ITEM (U"• @LongSoundEditor") LIST_ITEM (U"• @TextGridEditor") LIST_ITEM (U"• @ManipulationEditor") LIST_ITEM (U"• @SpectrumEditor") LIST_ITEM (U"• @PitchEditor") LIST_ITEM (U"• @PointEditor") LIST_ITEM (U"• @PitchTierEditor") LIST_ITEM (U"• @IntensityTierEditor") LIST_ITEM (U"• @DurationTierEditor") LIST_ITEM (U"• #SpectrogramEditor") LIST_ITEM (U"• #ArtwordEditor") LIST_ITEM (U"• @OTGrammarEditor") LIST_ITEM (U"• (any type: @Inspect)") ENTRY (U"How to open an editor for an object") NORMAL (U"To open an editor window for an object in the list, select the object and choose ##View & Edit# " "(if the ##View & Edit# button exists, it is usually at the top of the @@Dynamic menu@). " "The name of the object will appear as the title of the editor window.") NORMAL (U"Objects that cannot be modified (e.g. LongSound) just have the command #View instead of ##View & Edit#.") ENTRY (U"General behaviour") NORMAL (U"Changes that you make to an object in its editor window will take effect immediately. " "For instance, you do not have close the editor window before saving the changed object to disk.") NORMAL (U"If you @Remove an object that you are viewing or editing from the @@List of Objects@, " "the editor window will automatically disappear from the screen.") NORMAL (U"All editors are independent windows: you can minimize and maximize them; " "if an editor window goes hiding behind another window, " "you can raise it by choosing the ##View & Edit# command again.") NORMAL (U"If you rename an object that you are viewing or editing (with @@Rename...@), " "the title of the editor window immediately changes to the new name.") ENTRY (U"Ways to control an editor window") LIST_ITEM (U"• @@Click") LIST_ITEM (U"• @@Shift-click") LIST_ITEM (U"• @@Drag") LIST_ITEM (U"• @@Shift-drag") LIST_ITEM (U"• @@Time selection") LIST_ITEM (U"• @@Keyboard shortcuts") MAN_END MAN_BEGIN (U"Excitation", U"ppgb", 20030316) INTRO (U"One of the @@types of objects@ in Praat. It represents the excitation pattern " "of the basilar membrane in the inner ear.") ENTRY (U"Inside an Excitation object") NORMAL (U"With @Inspect, you will see the following attributes.") TAG (U"%xmin = 0") DEFINITION (U"minimum place or frequency (Bark).") TAG (U"%xmax = 25.6 Bark") DEFINITION (U"maximum place or frequency (Bark).") TAG (U"%nx") DEFINITION (U"number of places or frequencies.") TAG (U"%dx = 25.6 / %nx") DEFINITION (U"Place or frequency step (Bark).") TAG (U"%x1 = %dx / 2") DEFINITION (U"centre of first place or frequency band (Bark).") TAG (U"%ymin = %ymax = %dy = %y__1_ = 1; %ny = 1") DEFINITION (U"dummies.") TAG (U"%z [1]") DEFINITION (U"intensity (sensation level) in phon.") MAN_END MAN_BEGIN (U"Excitation: Formula...", U"ppgb", 20021206) INTRO (U"A command for changing the data in all selected @Excitation objects.") NORMAL (U"See the @Formulas tutorial for examples and explanations.") MAN_END MAN_BEGIN (U"Excitation: Get loudness", U"ppgb", 19991016) INTRO (U"A @query to ask the selected @Excitation object for its loudness.") ENTRY (U"Return value") NORMAL (U"the loudness in sone units.") ENTRY (U"Algorithm") NORMAL (U"The loudness is defined as") FORMULA (U"∫%df 2^^(%e(%f) - 40 phon) / 10^") NORMAL (U"where %f is the frequency in Bark, and %e(%f) the excitation in phon. " "For our discrete Excitation object, the loudness is computed as") FORMULA (U"Δ%f ∑ 2^^(%e__%i_ - 40) / 10") NORMAL (U"where Δ%f is the distance between the excitation channels (in Bark).") MAN_END MAN_BEGIN (U"Excitation_hertzToBark", U"ppgb", 19970401) INTRO (U"A routine for converting frequency into basilar place, " "the inverse of @Excitation_barkToHertz.") ENTRY (U"Syntax") PROTOTYPE (U"##double Excitation_hertzToBark (double #%hertz##);") ENTRY (U"Algorithm") NORMAL (U"Returns 7 · ln (%hertz / 650 + √ (1 + (%hertz / 650)^2)).") MAN_END MAN_BEGIN (U"Excitation_barkToHertz", U"ppgb", 19970401) INTRO (U"A routine for converting basilar place into frequency, " "the inverse of @Excitation_hertzToBark.") ENTRY (U"Syntax") PROTOTYPE (U"##double Excitation_barkToHertz (double #%bark##);") ENTRY (U"Algorithm") NORMAL (U"Returns 650 · sinh (%bark / 7).") MAN_END /* double Excitation_soundPressureToPhon (double soundPressure, double bark); Uses auditory filter (width apx. 1 Bark) for masking. Excitation Excitation_create (double df, long nf); Function: return a new instance of Excitation. Preconditions: df > 0.0; nf >= 1; Postconditions: result -> xmin == 0.0; result -> ymin == 1; result -> xmax == 25.6; result -> ymax == 1; result -> nx == nf; result -> ny == 1; result -> dx == df; result -> dy == 1; result -> x1 == 0.5 * df; result -> y1 == 1; result -> z [1] [1..nt] == 0.0; double Excitation_getDistance (Excitation me, Excitation thee); void Excitation_draw (Excitation me, Graphics g, double fmin, double fmax, double minimum, double maximum, int garnish); Matrix Excitation_to_Matrix (Excitation me); Function: Create a Matrix from an Excitation, with deep copy of all of its Matrix attributes, except class information and methods. Excitation Matrix_to_Excitation (Matrix me); Function: create an Excitation from a Matrix. Postconditions: thy xmin == 0.0; thy xmax == my nx / (1 / my dx); thy nx == my nx; thy dx == 1 / (1 / my dx); thy x1 == 0.5 * thy dx; thy ymin ymax ny dy y1 == 1; thy z [1] [...] == my z [1] [...]; */ /*"Any object of one of the types Polygon, PointProcess, Sound, Pitch, Spectrum,\n" "Spectrogram, Excitation, Cochleagram, VocalTract\n" "is convertible to and from a Matrix.\n" "This allows extra hacking and drawing possibilities.\n" "For example, to square the y values of a Polygon, do the following:\n" " select a Polygon, click on `To Matrix', click on `Formula...',\n" " type \"self * if row=1 then 1 else self fi\", click on `To Polygon'."*/ MAN_BEGIN (U"Formula...", U"ppgb", 19980319) NORMAL (U"See @@Matrix: Formula...@") MAN_END MAN_BEGIN (U"Frequency selection", U"ppgb", 20010402) INTRO (U"The way to select a frequency domain in the @SpectrumEditor. " "This works completely analogously to the @@time selection@ in other editors.") MAN_END MAN_BEGIN (U"Get area...", U"ppgb", 20030216) INTRO (U"A @query to the selected tier object (@PitchTier, @IntensityTier, @DurationTier).") ENTRY (U"Return value") NORMAL (U"the area under the curve.") ENTRY (U"Settings") TAG (U"##From time (s)") TAG (U"##To time (s)") DEFINITION (U"the selected time domain. Values outside this domain are ignored. " "If ##To time# is not greater than ##From time#, the entire time domain of the tier is considered.") ENTRY (U"Algorithm") NORMAL (U"The curve consists of a sequence of line segments. The contribution of the line segment from " "(%t__1_, %f__1_) to (%t__2_, %f__2_) to the area is") FORMULA (U"1/2 (%f__1_ + %f__2_) (%t__2_ – %t__1_)") MAN_END MAN_BEGIN (U"Intensity", U"ppgb", 20030316) INTRO (U"One of the @@types of objects@ in Praat.") NORMAL (U"An Intensity object represents an intensity contour at linearly spaced time points " "%t__%i_ = %t__1_ + (%i – 1) %dt, with values in dB SPL, i.e. dB relative to 2·10^^-5^ Pascal, " "which is the normative auditory threshold for a 1000-Hz sine wave.") MAN_END MAN_BEGIN (U"Intensity: Get maximum...", U"ppgb", 20041107) INTRO (U"A @query to the selected @Intensity object.") ENTRY (U"Return value") NORMAL (U"the maximum value within the specified time domain, expressed in dB.") ENTRY (U"Settings") TAG (U"##Time range (s)") DEFINITION (U"the time range (%t__1_, %t__2_). Values outside this range are ignored. " "If %t__1_ is not less than %t__2_, the entire time domain of the Intensity is considered.") TAG (U"%%Interpolation") DEFINITION (U"the interpolation method (#None, #Parabolic, #Cubic, #Sinc) of the @@vector peak interpolation@. " "The standard is Parabolic because of the usual nonlinearity (logarithm) in the computation of intensity; " "sinc interpolation would be too stiff and may give unexpected results.") MAN_END MAN_BEGIN (U"Intensity: Get mean...", U"ppgb", 20041107) INTRO (U"A @query to the selected @Intensity object.") ENTRY (U"Return value") NORMAL (U"the mean (in dB) of the intensity values of the frames within a specified time domain.") ENTRY (U"Settings") TAG (U"##Time range (s)") DEFINITION (U"the time range (%t__1_, %t__2_). Values outside this range are ignored. " "If %t__1_ is not less than %t__2_, the entire time domain of the Intensity is considered.") TAG (U"##Averaging method") DEFINITION (U"the units in which the averaging is performed. If the method is #energy, " "the returned dB value is based on the mean power (in Pa^2/s) between %t__1_ and %t__2_. " "If the method is #dB, the returned value is the mean of the intensity curve in dB. " "If the method is #sones, the returned value is in between these two, " "and based on averaging properties of the human ear.") ENTRY (U"Algorithm") NORMAL (U"If the averaging method is #dB, the mean intensity between the times %t__1_ and %t__2_ is defined as") FORMULA (U"1/(%t__2_ - %t__1_) ∫__%%t%1_^^%%t%2^ %x(%t) %dt") NORMAL (U"where %x(%t) is the intensity as a function of time, in dB. If the method is #energy, the result is") FORMULA (U"10 log__10_ { 1/(%t__2_ - %t__1_) ∫__%%t%1_^^%%t%2^ 10^^%x(%t)/10^ %dt }") NORMAL (U"If the method is #sones, the result is") FORMULA (U"10 log__2_ { 1/(%t__2_ - %t__1_) ∫__%%t%1_^^%%t%2^ 2^^%x(%t)/10^ %dt }") ENTRY (U"Behaviour") NORMAL (U"After you do @@Sound: To Intensity...@, the mean intensity of the resulting #Intensity, " "if the averaging method is #energy, should be close to the mean SPL of the original #Sound, " "which can be found with #Info.") MAN_END MAN_BEGIN (U"Intensity: Get minimum...", U"ppgb", 20041107) INTRO (U"A @query to the selected @Intensity object.") ENTRY (U"Return value") NORMAL (U"the minimum value within a specified time domain, expressed in dB.") ENTRY (U"Settings") TAG (U"##Time range (s)") DEFINITION (U"the time range (%t__1_, %t__2_). Values outside this range are ignored. " "If %t__1_ is not less than %t__2_, the entire time domain of the Intensity is considered.") TAG (U"##Interpolation") DEFINITION (U"the interpolation method (#None, #Parabolic, #Cubic, #Sinc) of the @@vector peak interpolation@. " "The standard is Parabolic because of the usual nonlinearity (logarithm) in the computation of intensity; " "sinc interpolation would be too stiff and may give unexpected results.") MAN_END MAN_BEGIN (U"Intensity: Get standard deviation...", U"ppgb", 20041107) INTRO (U"A @query to the selected @Intensity object.") ENTRY (U"Return value") NORMAL (U"the standard deviation (in dB) of the intensity values of the frames within a specified time domain.") ENTRY (U"Settings") TAG (U"%%Time range (s)") DEFINITION (U"the time range (%t__1_, %t__2_). Values outside this range are ignored. " "If %t__1_ is not less than %t__2_, the entire time domain of the Intensity is considered.") ENTRY (U"Algorithm") NORMAL (U"The standard deviation between the times %t__1_ and %t__2_ is defined as") FORMULA (U"√ {1/(%t__2_ - %t__1_) ∫__%%t%1_^^%%t%2^ %dt (%x(%t) - %μ)^2}") NORMAL (U"where %x(%t) is the intensity (in dB) as a function of time, and %μ its mean. " "For our discrete Intensity object, the standard deviation is approximated by") FORMULA (U"√ {1/(%n-1) ∑__%i=%m..%m+%n-1_ (%x__%i_ - %μ)^2}") NORMAL (U"where %n is the number of frames between %t__1_ and %t__2_. Note the \"minus 1\".") MAN_END MAN_BEGIN (U"Intensity: Get time of maximum...", U"ppgb", 20041107) INTRO (U"A @query to the selected @Intensity object.") ENTRY (U"Return value") NORMAL (U"the time (in seconds) associated with the maximum intensity within a specified time domain.") ENTRY (U"Settings") TAG (U"%%Time range (s)") DEFINITION (U"the time range (%t__1_, %t__2_). Values outside this range are ignored, except for purposes of interpolation. " "If %t__1_ is not less than %t__2_, the entire time domain of the Intensity is considered.") TAG (U"%%Interpolation") DEFINITION (U"the interpolation method (None, Parabolic, Cubic, Sinc) of the @@vector peak interpolation@. " "The standard is Parabolic because of the usual nonlinearity (logarithm) in the computation of intensity; " "sinc interpolation would be too stiff and may give unexpected results.") MAN_END MAN_BEGIN (U"Intensity: Get time of minimum...", U"ppgb", 20041107) INTRO (U"A @query to the selected @Intensity object.") ENTRY (U"Return value") NORMAL (U"the time (in seconds) associated with the minimum intensity within a specified time domain.") ENTRY (U"Settings") TAG (U"##Time range (s)") DEFINITION (U"the time range (%t__1_, %t__2_). Values outside this range are ignored, except for purposes of interpolation. " "If %t__1_ is not less than %t__2_, the entire time domain of the Intensity is considered.") TAG (U"##Interpolation") DEFINITION (U"the interpolation method (None, Parabolic, Cubic, Sinc) of the @@vector peak interpolation@. " "The standard is Parabolic because of the usual nonlinearity (logarithm) in the computation of intensity; " "sinc interpolation would be too stiff and may give unexpected results.") MAN_END MAN_BEGIN (U"Intensity: Get value at time...", U"ppgb", 20030916) INTRO (U"A @query to the selected @Intensity object.") ENTRY (U"Return value") NORMAL (U"the intensity (in dB) at a specified time. If %time is outside the frames of the Intensity, the result is 0.") ENTRY (U"Settings") TAG (U"##Time (s)") DEFINITION (U"the time at which the value is to be evaluated.") TAG (U"##Interpolation") DEFINITION (U"the interpolation method, see @@vector value interpolation@. " "The standard is Cubic because of the usual nonlinearity (logarithm) in the computation of intensity; " "sinc interpolation would be too stiff and may give unexpected results.") MAN_END MAN_BEGIN (U"Intensity: Get value in frame...", U"ppgb", 19991016) INTRO (U"A @query to the selected @Intensity object.") ENTRY (U"Setting") TAG (U"##Frame number") DEFINITION (U"the frame whose value is to be looked up.") ENTRY (U"Return value") NORMAL (U"the intensity value (in dB) in the specified frame. " "If the index is less than 1 or greater than the number of frames, the result is 0; " "otherwise, it is %z [1] [%%frame number%].") MAN_END MAN_BEGIN (U"Intensity: To IntensityTier", U"ppgb", 19970321) INTRO (U"A command to convert each selected @Intensity object to an @IntensityTier.") ENTRY (U"Behaviour") NORMAL (U"Every sample in the @Intensity object is copied to a point on the @IntensityTier.") ENTRY (U"Postconditions") DEFINITION (U"Equal time domains:") LIST_ITEM (U"• %result. %xmin == %intensity. %xmin") LIST_ITEM (U"• %result. %xmax == %intensity. %xmax") DEFINITION (U"Equal number of points:") LIST_ITEM (U"• %result. %points. %size == %intensity. %nx") NORMAL (U"For all points %i = 1 ... %intensity. %nx:") DEFINITION (U" Explicit times:") LIST_ITEM (U" • %result. %points. %item [%i]. %time == %intensity. %x1 + (%i – 1) * %intensity. %dx") DEFINITION (U" Equal number of points:") LIST_ITEM (U" • %result. %points. %item [%i]. %value == %intensity. %z [1] [%i]") MAN_END MAN_BEGIN (U"Intensity & PointProcess: To IntensityTier...", U"ppgb", 20101230) INTRO (U"A command to copy information from an @Intensity, at times specified by a @PointProcess, " "to points on an @IntensityTier.") ENTRY (U"Behaviour") NORMAL (U"For all the times of the points in the PointProcess, an intensity is computed from the " "information in the Intensity object, by linear interpolation.") MAN_END MAN_BEGIN (U"IntensityTier", U"ppgb", 20101230) INTRO (U"One of the @@types of objects@ in Praat. " "An IntensityTier object represents a time-stamped intensity contour, i.e., it contains a series of (%time, %intensity) points. " "The intensity values are in dB.") NORMAL (U"For examples, see @@Source-filter synthesis@.") ENTRY (U"IntensityTier commands") NORMAL (U"Creation:") LIST_ITEM (U"From scratch:") LIST_ITEM (U"• @@Create IntensityTier...") LIST_ITEM (U"• @@IntensityTier: Add point...") LIST_ITEM (U"Copy from another object:") LIST_ITEM (U"• @@Intensity: To IntensityTier@: trivial copying of linearly spaced points.") LIST_ITEM (U"• @@Intensity & PointProcess: To IntensityTier...@: copying interpolated values at specified points.") LIST_ITEM (U"• @@PointProcess: Up to IntensityTier...@: equal values at specified points.") NORMAL (U"Viewing and editing:") LIST_ITEM (U"• @IntensityTierEditor") NORMAL (U"Conversion:") LIST_ITEM (U"• @@IntensityTier: Down to PointProcess@: copy times.") NORMAL (U"Synthesis (see @@Source-filter synthesis@):") LIST_ITEM (U"• @@Sound & IntensityTier: Multiply@") NORMAL (U"Queries:") LIST_ITEM (U"• @@Get low index from time...") LIST_ITEM (U"• @@Get high index from time...") LIST_ITEM (U"• @@Get nearest index from time...") NORMAL (U"Modification:") LIST_ITEM (U"• @@Remove point...") LIST_ITEM (U"• @@Remove point near...") LIST_ITEM (U"• @@Remove points between...") LIST_ITEM (U"• @@IntensityTier: Add point...@") MAN_END MAN_BEGIN (U"IntensityTier: Add point...", U"ppgb", 20010410) INTRO (U"A command to add a point to each selected @IntensityTier.") ENTRY (U"Settings") TAG (U"##Time (s)") DEFINITION (U"the time at which a point is to be added.") TAG (U"##Intensity (dB)") DEFINITION (U"the intensity value of the requested new point.") ENTRY (U"Behaviour") NORMAL (U"The tier is modified so that it contains the new point. " "If a point at the specified time was already present in the tier, nothing happens.") MAN_END MAN_BEGIN (U"IntensityTier: Down to PointProcess", U"ppgb", 20010410) INTRO (U"A command to degrade every selected @IntensityTier to a @PointProcess.") ENTRY (U"Behaviour") NORMAL (U"The times of all the points are trivially copied, and so is the time domain. The intensity information is lost.") MAN_END MAN_BEGIN (U"IntensityTierEditor", U"ppgb", 20110128) INTRO (U"One of the @editors in the Praat program, for viewing and editing an @IntensityTier object. " "To create a IntensityTierEditor window, select an IntensityTier and click ##View & Edit#.") MAN_END MAN_BEGIN (U"Keyboard shortcuts", U"ppgb", 20071016) INTRO (U"A way to accelerate the control of @Editors in Praat.") ENTRY (U"Purpose") NORMAL (U"to choose a menu command with the keyboard. All of these commands can also be chosen " "from a menu.") ENTRY (U"Command key") NORMAL (U"When mentioning the %%Command key%, this manual refers to the key that is marked with an apple on Apple keyboards " "or to the key that is marked \"Ctrl\" if you are on a Windows or Linux computer.") ENTRY (U"Option key") NORMAL (U"When mentioning the %%Option key%, this manual refers to the key marked \"alt\" or \"option\". " "In Praat, this key is sometimes used together with the Command key " "for destructive actions that are the reverse of the actions invoked by using the Command key only. " "For instance, if Command-T means \"add a target at the cursor position\", " "Option-Command-T may mean \"remove the selected targets\".") ENTRY (U"Shortcuts") LIST_ITEM (U"Command-A: Zoom all") LIST_ITEM (U"Command-C: Copy (the selected text, or the selected sound, or the selected part of the Picture window)") LIST_ITEM (U"Command-D (in Manipulation window): Insert duration point at cursor") LIST_ITEM (U"Option-Command-D (in Manipulation window): Remove selected duration points") LIST_ITEM (U"Command-E (in Picture window): Erase all") LIST_ITEM (U"Shift-Command-H: Move cursor to maximum pitch") LIST_ITEM (U"Command-I: Zoom in") LIST_ITEM (U"Command-L (in Objects window): @@Open long sound file...@") LIST_ITEM (U"Command-L (in sound windows): @@Intro 3.6. Viewing a spectral slice|View spectral slice@") LIST_ITEM (U"Shift-Command-L: Move cursor to minimum pitch") LIST_ITEM (U"Command-M: Search Praat manual...") LIST_ITEM (U"Command-N: Zoom to selection") LIST_ITEM (U"Command-O (in Objects window): @@Read from file...@") LIST_ITEM (U"Command-O (in sound windows): Zoom out") LIST_ITEM (U"Command-P (in Picture window): Print") LIST_ITEM (U"Command-P (in Manipulation window): Add pulse at cursor") LIST_ITEM (U"Option-Command-P (in Manipulation window): Remove selected pulses") LIST_ITEM (U"Command-Q: Quit") LIST_ITEM (U"Command-R: Reverse selection") LIST_ITEM (U"Command-S: Save") LIST_ITEM (U"Command-T (in Manipulation window): Add pitch point at cursor") LIST_ITEM (U"Option-Command-T (in Manipulation window): Remove selected pitch points") LIST_ITEM (U"Command-U: @@Calculator...@") LIST_ITEM (U"Command-V: Paste (insert the text or sound clipboard over the selected text or the selected sound)") LIST_ITEM (U"Command-W: Close window") LIST_ITEM (U"Command-X: Cut (the selected text or the selected sound)") LIST_ITEM (U"Command-Y: Redo") LIST_ITEM (U"Command-Z: Undo") LIST_ITEM (U"Command-0: Move cursor to nearest zero crossing") LIST_ITEM (U"Command-2 (in Manipulation window): Stylize pitch (2 semitones)") LIST_ITEM (U"Command-4 (in Manipulation window): Interpolate quadratically (4 points)") LIST_ITEM (U"Shift-Command-?: Local help") LIST_ITEM (U"Command-,: Move start of selection to nearest zero crossing") LIST_ITEM (U"Command-.: Move end of selection to nearest zero crossing") LIST_ITEM (U"F5: Get pitch") LIST_ITEM (U"Command-F5: Get minimum pitch") LIST_ITEM (U"Shift-F5: Get maximum pitch") LIST_ITEM (U"F1: Get first formant") LIST_ITEM (U"F2: Get second formant") LIST_ITEM (U"F3: Get third formant") LIST_ITEM (U"F4: Get fourth formant") LIST_ITEM (U"F5: Get pitch") LIST_ITEM (U"F6: Get cursor") LIST_ITEM (U"F7: Get spectral power at cursor cross") LIST_ITEM (U"F8: Get intensity") LIST_ITEM (U"F12: Log 1") LIST_ITEM (U"Shift-F12: Log 2") LIST_ITEM (U"Option-F12: Log script 3") LIST_ITEM (U"Command-F12: Log script 4") LIST_ITEM (U"Tab (in sound windows): Play selection") LIST_ITEM (U"Shift-Tab (in sound windows): Play window") LIST_ITEM (U"Arrow-up (in sound windows): Select earlier") LIST_ITEM (U"Arrow-down (in sound windows): Select later") LIST_ITEM (U"Shift-Arrow-up (in sound windows): Move start of selection left") LIST_ITEM (U"Shift-Arrow-down (in sound windows): Move start of selection right") LIST_ITEM (U"Command-Arrow-up (in sound windows): Move end of selection left") LIST_ITEM (U"Command-Arrow-down (in sound windows): Move end of selection right") LIST_ITEM (U"Page-up (in sound windows): Scroll page back") LIST_ITEM (U"Page-down (in sound windows): Scroll page forward") LIST_ITEM (U"Escape: Interrupt playing") MAN_END MAN_BEGIN (U"Log files", U"ppgb", 20140421) INTRO (U"With some commands in the @Query menu of the @SoundEditor and @TextGridEditor, " "you can write combined information about times, pitch values, formants, and intensities " "to the @@Info window@ and to a log file.") NORMAL (U"A log file is a text file on disk. It consists of a number of similar lines, " "whose format you determine with the log settings in the Query menu.") NORMAL (U"Every time you press F12 (or choose ##Log 1# from the Query menu, " "Praat writes a line to log file 1. If you press Shift-F12, Praat writes a line to log file 2.") NORMAL (U"With the ##log settings# command window, you determine the following:") TAG (U"##Log 1 to Info window") DEFINITION (U"this determines whether your log line will be written to the Info window or not.") TAG (U"##Log 1 to log file") DEFINITION (U"this determines whether your log line will be written to the log file or not.") TAG (U"##Log file 1") DEFINITION (U"the name of the log file. On Windows, this has to be a complete path name, such as " "$$C:\\bsWINDOWS\\bsDESKTOP\\bsPitch Log.txt$. " "On Unix and MacOS X, it can either be a complete path name, e.g. $$/home/mary/pitch_log$, " "or a home-relative name such as $$~/Desktop/Pitch log$.") TAG (U"##Log 1 format") DEFINITION (U"the format of the line that Praat will write. See below.") NORMAL (U"The same goes for log file 2.") ENTRY (U"Usage") NORMAL (U"The logging facility has been implemented in Praat especially for former users of Kay CSL, " "who have been used to doing it for years and like to continue doing it in Praat. " "Otherwise, you may prefer to use the @TextGridEditor to mark time points and run " "an automatic analysis afterwards.") NORMAL (U"If you do want to use the logging facility, you typically start by deleting any old " "log file (by choosing ##Delete log file 1# or ##Delete log file 2#), if you want to re-use " "the file name. Otherwise, you can change the log file name (with ##Log settings...#). " "After this, you will move the cursor to various time locations and press F12 (or Shift-F12) " "each time, so that information about the current time will be written to the log file.") ENTRY (U"Example 1: pitch logging") NORMAL (U"Suppose you want to log the time of the cursor and the pitch value at the cursor. " "You could use the following log format:") CODE (U"Time \'time:6\' seconds, pitch \'f0:2\' hertz") NORMAL (U"If you now click at 3.456789876 seconds, and the pitch happens to be 355.266 hertz " "at that time, the following line will be appended to the log file and/or to the Info window:") CODE (U"Time 3.456790 seconds, pitch 355.27 hertz.") NORMAL (U"The parts \":6\" and \":2\" denote the number of digits after the decimal point. " "If you leave them out, the values will be written with a precision of 17 digits.") NORMAL (U"The words \'time\' and \'f0\' mean exactly the same as the result of the commands " "##Get cursor# and ##Get pitch#. Therefore, if instead of setting a cursor line you selected a larger " "piece of the sound, \'time\' will give the centre of the selection and \'f0\' will give the mean pitch " "in the selection.") NORMAL (U"Beware of the following pitfall: if your pitch units are not hertz, but semitones, " "then \'f0\' will give the result in semitones. A format as in this example will then be misleading.") ENTRY (U"Example 2: formant logging") NORMAL (U"Suppose you want to log the start and finish of the selection, its duration, and the mean values " "of the first three formants, all separated by tab stops for easy importation into Microsoft® Excel™. " "You could use the following log format:") CODE (U"\'t1:4\'\'tab\\$ \'\'t2:4\'\'tab\\$ \'\'f1:0\'\'tab\\$ \'\'f2:0\'\'tab\\$ \'\'f3:0\'") NORMAL (U"You see that \'t1\' and \'t2\' are the start and finish of the selection, respectively, " "and that they are written with 4 digits after the decimal point. By using \":0\", the three formant values " "are rounded to whole numbers in hertz. The word \'tab\\$ \' is the tab stop.") ENTRY (U"Loggable values") NORMAL (U"The following values can be logged:") LIST_ITEM (U"\'time\': the time of the cursor, or the centre of the selection.") LIST_ITEM (U"\'t1\': the start of the selection (\"B\").") LIST_ITEM (U"\'t2\': the end of the selection (\"E\").") LIST_ITEM (U"\'dur\': the duration of the selection.") LIST_ITEM (U"\'freq\': the frequency at the frequency cursor.") LIST_ITEM (U"\'f0\': the pitch at the cursor time, or the mean pitch in the selection.") LIST_ITEM (U"\'f1\', \'f2\', \'f3\', \'f4\', \'f5\': the first/second/third/fourth/fifth formant at the cursor time, " "or the mean first/second/third/fourth/fifth formant in the selection.") LIST_ITEM (U"\'b1\', \'b2\', \'b3\', \'b4\', \'b5\': the bandwidth of the first/second/third/fourth/fifth formant " "at the cursor time or at the centre of the selection.") LIST_ITEM (U"\'intensity\': the intensity at the cursor time, or the mean intensity in the selection, in dB.") LIST_ITEM (U"\'power\': the spectral power at the cursor cross, in Pa^2/Hz.") LIST_ITEM (U"\'tab\\$ \': the tab stop.") LIST_ITEM (U"\'editor\\$ \': the title of the editor window (i.e. the name of the visible Sound or TextGrid).") ENTRY (U"More flexibility in logging") NORMAL (U"You may sometimes require information in your log file that cannot be generated directly " "by the loggable values above. Suppose, for instance, that you want to log the values for F1 and F2-F1 " "at the points where you click. You could write the following script:") CODE (U"f1 = Get first formant") CODE (U"f2 = Get second formant") CODE (U"f21 = f2 - f1") CODE (U"appendInfoLine: fixed\\$ (f1, 0), \" \", fixed\\$ (f21, 0)") CODE (U"appendFileLine: \"D:\\bsPraat logs\\bsFormant log.txt\", fixed\\$ (f1, 0), tab\\$ , fixed\\$ (f21, 0)") NORMAL (U"With this script, the information would be appended both to the Info window and to the " "file \"Formant log.txt\" on your desktop.") NORMAL (U"You can make this script accessible with Option-F12 (or Command-F12) " "by saving the script and specifying the name of the script file in the ##Log script 3# (or #4) field " "in the ##Log settings...# window.") NORMAL (U"These scripts may take arguments. Suppose, for instance, that you want to specify a vowel symbol " "as you press Option-F12. The following script will take care of that:") CODE (U"form Save vowel and formants") CODE1 (U"word Vowel a") CODE (U"endform") CODE (U"f1 = Get first formant") CODE (U"f2 = Get second formant") CODE (U"f21 = f2 - f1") CODE (U"appendInfoLine: vowel\\$ , \" \", fixed\\$ (f1, 0), \" \", fixed\\$ (f21, 0)") CODE (U"appendFileLine: \"~/Praat logs/Vowels and formants log\", vowel\\$ , tab\\$ , fixed\\$ (f1, 0), tab\\$ , fixed\\$ (f21, 0)") NORMAL (U"Beware of the following pitfall: because of the nature of scripts, you should not try to do this " "when you have two editor windows with the same name. I cannot predict which of the two windows " "will answer the #Get queries...") MAN_END MAN_BEGIN (U"Manipulation", U"ppgb", 20030316) INTRO (U"One of the @@types of objects@ in Praat, for changing the pitch and duration contours of a sound.") ENTRY (U"Inside a manipulation object") NORMAL (U"With @Inspect, you will see the following attributes:") TAG (U"##timeStep") DEFINITION (U"the time step (or %%frame length%) used in the pitch analysis. A common value is 0.010 seconds.") TAG (U"##minimumPitch") DEFINITION (U"the minimum pitch frequency considered in the pitch analysis. A common value is 75 hertz.") TAG (U"##maximumPitch") DEFINITION (U"the maximum pitch frequency considered in the pitch analysis. A common value is 600 hertz.") NORMAL (U"A Manipulation object also contains the following smaller objects:") LIST_ITEM (U"1. The original @Sound.") LIST_ITEM (U"2. A @PointProcess representing glottal pulses.") LIST_ITEM (U"3. A @PitchTier.") LIST_ITEM (U"4. A @DurationTier.") ENTRY (U"Analysis") NORMAL (U"When a Manipulation object is created from a sound, the following steps are performed:") LIST_ITEM (U"1. A pitch analysis is performed on the original sound, with the method of @@Sound: To Pitch...@. " "This uses the time step, minimum pitch, and maximum pitch parameters.") LIST_ITEM (U"2. The information of the resulting pitch contour (frequency and voiced/unvoiced decisions) " "is used to posit glottal pulses where the original sound contains much energy. " "The method is the same as in @@Sound & Pitch: To PointProcess (cc)@.") LIST_ITEM (U"3. The pitch contour is converted to a pitch tier with many points (targets), " "with the method of @@Pitch: To PitchTier@.") LIST_ITEM (U"4. An empty @DurationTier is created.") ENTRY (U"Resynthesis") TAG (U"A Manipulation object can produce Sound input. This Sound can be computed in several ways:") LIST_ITEM (U"• @@overlap-add@: from original sound + pulses + pitch tier + duration tier;") LIST_ITEM (U"• #LPC: from LPC (from original sound) + pulses + pitch tier;") LIST_ITEM (U"• from the pulses only, as a pulse train or hummed;") LIST_ITEM (U"• from the pitch tier only, as a pulse train or hummed.") MAN_END MAN_BEGIN (U"Manipulation: Extract duration tier", U"ppgb", 20010330) INTRO (U"A command to extract a copy of the duration information in each selected @Manipulation object into a new @DurationTier object.") MAN_END MAN_BEGIN (U"Manipulation: Extract original sound", U"ppgb", 20010330) INTRO (U"A command to copy the original sound in each selected @Manipulation object to a new @Sound object.") MAN_END MAN_BEGIN (U"Manipulation: Extract pitch tier", U"ppgb", 20010330) INTRO (U"A command to extract a copy of the pitch information in each selected @Manipulation object into a new @PitchTier object.") MAN_END MAN_BEGIN (U"Manipulation: Extract pulses", U"ppgb", 20010330) INTRO (U"A command to extract a copy of the vocal-pulse information in each selected @Manipulation object into a new @PointProcess object.") MAN_END MAN_BEGIN (U"Manipulation: Play (overlap-add)", U"ppgb", 20070722) INTRO (U"A command to play each selected @Manipulation object, resynthesized with the @@overlap-add@ method.") MAN_END MAN_BEGIN (U"Manipulation: Get resynthesis (overlap-add)", U"ppgb", 20070722) INTRO (U"A command to extract the sound from each selected @Manipulation object, resynthesized with the @@overlap-add@ method.") MAN_END MAN_BEGIN (U"Manipulation: Replace duration tier", U"ppgb", 20030216) INTRO (U"You can replace the duration tier that you see in your @Manipulation object " "with a separate @DurationTier object, for instance one that you extracted from another Manipulation " "or one that you created with @@Create DurationTier...@.") NORMAL (U"To do this, select your Manipulation object together with the @DurationTier object and click ##Replace duration tier#.") MAN_END MAN_BEGIN (U"Manipulation: Replace pitch tier", U"ppgb", 20030216) INTRO (U"You can replace the pitch tier that you see in your @Manipulation object " "with a separate @PitchTier object, for instance one that you extracted from another Manipulation " "or one that you created with @@Create PitchTier...@.") NORMAL (U"To do this, select your Manipulation object together with the @PitchTier object and click ##Replace pitch tier#.") MAN_END MAN_BEGIN (U"Manipulation: Replace pulses", U"ppgb", 20010330) INTRO (U"A command to replace the vocal-pulse information in the selected @Manipulation object with the selected @PointProcess object.") MAN_END MAN_BEGIN (U"Manipulation: Replace original sound", U"ppgb", 20010330) INTRO (U"A command to replace the original sound in the selected @Manipulation object with the selected @Sound object.") MAN_END MAN_BEGIN (U"ManipulationEditor", U"ppgb", 20030316) INTRO (U"One of the @Editors in Praat, for viewing and manipulating a @Manipulation object.") ENTRY (U"Objects") NORMAL (U"The editor shows:") LIST_ITEM (U"• The original @Sound.") LIST_ITEM (U"• The @PointProcess that represents the glottal %pulses. " "You can edit it for improving the pitch analysis.") LIST_ITEM (U"• A pitch contour based on the locations of the pulses, for comparison (drawn as grey dots). " "Changes shape if you edit the pulses.") LIST_ITEM (U"• The @PitchTier that determines the pitch contour of the resynthesized @Sound (drawn as blue circles). " "At the creation of the @Manipulation object, it is computed from the original pitch contour. " "You can manipulate it by simplifying it (i.e., removing targets), " "or by moving parts of it up and down, and back and forth.") LIST_ITEM (U"• A @DurationTier for manipulating the relative durations of the voiced parts of the sound.") ENTRY (U"Playing") NORMAL (U"To play (a part of) the %resynthesized sound (by any of the methods shown in the #Synth menu, " "like @@overlap-add@ and #LPC), @click on any of the 1 to 8 buttons below and above the drawing area " "or use the Play commands from the View menu.") NORMAL (U"To play the %original sound instead, use ##Shift-click#.") ENTRY (U"Pulses") TAG (U"To add:") DEFINITION (U"#click at the desired time location, and choose ##Add pulse at cursor# or type ##Command-p#.") TAG (U"To remove:") DEFINITION (U"make a @@time selection@, and choose ##Remove pulse(s)# or type ##Option-Command-p#. " "If there is no selection, the pulse nearest to the cursor is removed.") ENTRY (U"Pitch points") TAG (U"To add one at a specified %%time and frequency%:") DEFINITION (U"#click at the desired time-frequency location, and choose ##Add pitch point at cursor# or type ##Command-t#.") TAG (U"To add one at a specified %time only:") DEFINITION (U"#click at the desired time, and choose ##Add pitch point at time slice#. ManipulationEditor tries to compute the frequency from the " "intervals between the pulses, basically by a median-of-three method.") TAG (U"To remove:") DEFINITION (U"make a @@time selection@, and choose ##Remove pitch point(s)# or type ##Option-Command-t#. " "If there is no selection, the pitch point nearest to the cursor is removed.") TAG (U"To move %some:") DEFINITION (U"make a @@time selection@ (the points become red) and ##Shift-drag# the points across the window. " "You cannot drag them across adjacent points, or below 50 Hz, or above the maximum frequency. " "You can only drag them horizontally if the %%dragging strategy% is ##All# or ##Only horizontal#, " "and you can drag them vertically if the dragging strategy is not ##Only horizontal#. " "You can change the dragging strategy with ##Set pitch dragging strategy...# from the #Pitch menu.") TAG (U"To move %one:") DEFINITION (U"@drag that point across the window. " "You can only drag it horizontally if the dragging strategy is not ##Only vertical#, " "and you can drag it vertically if the dragging strategy is not ##Only horizontal#.") ENTRY (U"Duration points") NORMAL (U"Work pretty much the same as pitch points.") ENTRY (U"Stylization") NORMAL (U"Before editing the Pitch points, you may want to reduce their number by choosing any of the #Stylize " "commands from the #Pitch menu.") MAN_END MAN_BEGIN (U"Matrix", U"ppgb", 20030216) INTRO (U"One of the @@types of objects@ in Praat. " "A Matrix object represents a function %z (%x, %y) " "on the domain [%x__%min_, %x__%max_] × [%y__%min_, %y__%max_]. " "The domain has been sampled in the %x and %y directions " "with constant sampling intervals (%dx and %dy) along each direction. " "The samples are thus %z [%i__%y_] [%i__%x_], %i__%x_ = 1 ... %n__%x_, %i__%y_ = 1 ... %n__%y_. " "The samples represent the function values %z (%x__1_ + (%ix - 1) %dx, %y__1_ + (%iy - 1) %dy).") ENTRY (U"Matrix commands") NORMAL (U"Creation:") LIST_ITEM (U"• @@Create Matrix...") LIST_ITEM (U"• @@Create simple Matrix...") LIST_ITEM (U"• @@Read from file...") LIST_ITEM (U"• @@Read Matrix from raw text file...") LIST_ITEM (U"• ##Read Matrix from LVS AP file...") NORMAL (U"Drawing:") LIST_ITEM (U"• ##Matrix: Draw rows...") LIST_ITEM (U"• ##Matrix: Draw contours...") LIST_ITEM (U"• ##Matrix: Paint contours...") LIST_ITEM (U"• ##Matrix: Paint cells...") LIST_ITEM (U"• ##Matrix: Scatter plot...") LIST_ITEM (U"• @@Matrix: Draw as squares...") LIST_ITEM (U"• ##Matrix: Draw value distribution...") LIST_ITEM (U"• ##Matrix: Paint surface...") NORMAL (U"Modification:") LIST_ITEM (U"• @@Matrix: Formula...") LIST_ITEM (U"• ##Matrix: Scale...") ENTRY (U"Inside a Matrix object") NORMAL (U"With @Inspect, you will see the following attributes.") TAG (U"%xmin, %xmax ≥ %xmin") DEFINITION (U"%x domain.") TAG (U"%nx ≥ 1") DEFINITION (U"number of columns.") TAG (U"%dx > 0.0") DEFINITION (U"distance between columns.") TAG (U"%x1") DEFINITION (U"%x value associated with first column.") TAG (U"%ymin, %ymax ≥ %ymin") DEFINITION (U"%y domain.") TAG (U"%ny ≥ 1") DEFINITION (U"number of rows.") TAG (U"%dy > 0.0") DEFINITION (U"distance between rows.") TAG (U"%y1") DEFINITION (U"%y value associated with first row.") TAG (U"%z [1..%ny] [1..%nx]") DEFINITION (U"The sample values.") NORMAL (U"After creation of the #Matrix, %xmin, %xmax, %ymin, %ymax, " "%nx, %ny, %dx, %dy, %x1, and %y1 " "do not usually change. The contents of %z do.") NORMAL (U"Normally, you will want %xmin ≤ %x1 and %xmax ≥ %x1 + (%nx - 1) %dx.") ENTRY (U"Example: simple matrix") NORMAL (U"If a simple matrix has %x equal to column number " "and %y equal to row number, it has the following attributes:") LIST_ITEM (U"%xmin = 1; %xmax = %nx; %dx = 1; %x1 = 1;") LIST_ITEM (U"%ymin = 1; %ymax = %ny; %dy = 1; %y1 = 1;") ENTRY (U"Example: sampled signal") NORMAL (U"If the matrix represents a sampled signal of 1 second duration " "with a sampling frequency of 10 kHz, it has the following attributes:") LIST_ITEM (U"%xmin = 0.0; %xmax = 1.0; %nx = 10000 ; %dx = 1.0·10^^-4^; %x1 = 0.5·10^^-4^;") LIST_ITEM (U"%ymin = 1; %ymax = 1; %ny = 1; %dy = 1; %y1 = 1;") ENTRY (U"Example: complex signal") NORMAL (U"If the matrix represents a complex spectrum " "derived with an @FFT from the sound of example 2, it has the following attributes:") LIST_ITEM (U"%xmin = 0.0; %xmax = 5000.0; %nx = 8193 ; %dx = 5000.0 / 8192; %x1 = 0.0;") LIST_ITEM (U"%ny = 2 (real and imaginary part);") LIST_ITEM (U"%ymin = 1 (first row, real part);") LIST_ITEM (U"%ymax = 2 (second row, imaginary part);") LIST_ITEM (U"%dy = 1; %y1 = 1; (so that %y is equal to row number)") MAN_END MAN_BEGIN (U"Matrix: Draw as squares...", U"ppgb", 19980319) INTRO (U"A command to draw a @Matrix object into the @@Picture window@.") ENTRY (U"Settings") TAG (U"##Xmin") TAG (U"##Xmax") DEFINITION (U"the windowing domain in the %x direction. Elements outside will not be drawn. " "%Autowindowing: if (%Xmin ≥ %Xmax), the entire %x domain [%x__%min_, %x__%max_] of the Matrix is used.") TAG (U"##Ymin") TAG (U"##Ymax") DEFINITION (U"the windowing domain in the %y direction. Elements outside will not be drawn. " "%Autowindowing: if (%Ymin ≥ %Ymax), the entire %y domain [%y__%min_, %y__%max_] of the Matrix is used.") TAG (U"##Garnish") DEFINITION (U"determines whether axes are drawn around the picture. " "Turn this button off if you prefer to garnish your picture by yourself with the @Margins menu.") ENTRY (U"Behaviour") NORMAL (U"For every element of the Matrix inside the specified windowing domain, " "an opaque white or black rectangle is painted (white if the value of the element is positive, " "black if it is negative), surrounded by a thin black box. " "The %area of the rectangle is proportional to the value of the element.") ENTRY (U"Trick") NORMAL (U"If you prefer the %sides of the rectangle (instead of the area) to be proportional " "to the value of the element, you can use the formula \"$$self\\^ 2$\" before drawing (see @@Matrix: Formula...@).") MAN_END MAN_BEGIN (U"Matrix: Formula...", U"ppgb", 20021206) INTRO (U"A command for changing the data in all selected @Matrix objects.") NORMAL (U"See the @Formulas tutorial for examples and explanations.") MAN_END MAN_BEGIN (U"Matrix: Paint cells...", U"ppgb", 20021204) INTRO (U"A command to draw the contents of a @Matrix to the @@Picture window@.") NORMAL (U"Every cell of the matrix is drawn as a rectangle filled with a grey value between white (if the content " "of the cell is small) and black (if the content is large).") MAN_END /* if x > 1 and x < 1.5 then self * 1.3 else self fi je had gewoon de manual kunnen lezen (Help klikken bij Formula...). >poging 1: > for col:=16000 to 24000 do {self[col] := self[col] * 1.3 } geen lussen in formules. Er is een automatische lus: for row := 1 to nrow do for col := 1 to ncol do self := ... >poging 2: > col:=16000; for col:=16000 to 24000 do {self[col] := self[col] * 1.3 } geen toekenningen. Als je het 1000ste element op 8 wilt zetten, kun je doen Formula... if col=1000 then 8 else self fi of sneller: Set value... 1 1000 8 Wat dus wel werkt, maar ERG traag is: for col = 16000 to 24000 value = Get value... 1 col Set value... 1 col value*1.3 endfor >toen ben ik het wilde weg gaan proberen: > col=16000; for col:=16000 to 24000 do {self[col] := self[col] * 1.3 } de puntkomma betekent einde formule. Deze formule zet alles op 0, behalve element 16000, dat op 1 gezet wordt. De expressie is namelijk booleaans: "is col gelijk aan 16000"? Dit staat allemaal in de on-line handleiding, dus je hoeft niet te gokken! */ MAN_BEGIN (U"Matrix: Set value...", U"ppgb", 19980319) INTRO (U"A command to change the value of one cell in each selected @Matrix object.") ENTRY (U"Settings") TAG (U"##Row number") DEFINITION (U"the number of the row of the cell whose value you want to change.") TAG (U"##Column number") DEFINITION (U"the number of the column of the cell whose value you want to change.") TAG (U"##New value") DEFINITION (U"the value that you want the specified cell to have.") MAN_END /* 1. The Hilbert transform. I wondered whether my use of taking the square was worse than taking the Hilbert envelope. My formula is my_envelope1(t) = x(t) ^ 2 For a sampled signal, this introduces higher frequencies, so I should have filtered the signal at half the Nyquist frequency to prevent aliasing. I wonder how the Hilbert envelope behaves in this respect: your_envelope1(t) = x(t) ^ 2 + Px(t) ^ 2 I think it has the same problem, since it involves squaring the real and imaginary parts. Of course, the Hilbert transform is much smoother, but that cannot matter for frequencies above 100 Hz or so, since we are going to filter at 30 Hz anyway. Thus, I think these methods are comparable. Do you agree? 2. The non-linearity. In the second step, I take the logarithm: my_envelope2(t) = 10 log10 (my_envelope1(t) + 1e-6) Of course, the 1e-6 is there to guard against zero values in my_envelope1. I took the logarithm because it can handle negative values, which will arise in the filtering process. You take the square root instead: your_envelope2(t) = sqrt (your_envelope1(t)) 3. Filtering between 3 and 30 Hz. You use a second-order Butterworth filter in the time domain: your_envelope3(t) = your_envelope2(t) * Butterworth(t) What do you mean by "forward and backward filtering"? Did you use the second-order filter twice, thus making it fourth-order effectively? My alternative was to use the two Gaussians: my_spectrum2(f) = fft (my_envelope2(t)) my_spectrum3(f) = my_spectrum2(f) (exp(-(f/35)^2)-exp(-(f/3.5)^2) my_envelope3(t) = ifft (my_spectrum3 (f)) This is a filter with several desirable properties: no ringing, phase-preserving, an area of zero. On the other hand, it is not causal, but I think that that is not an issue here. Is it? 4. The new band. In my algorithm, I have to undo the non-linearity: my_envelope4(t) = 10 ^ (my_envelope3(t) / 2) You see that I divide by 2, not 10, thus effectively multiplying the dynamics, expressed in dB, by a factor of 5. Since I am going to use the new envelope as a multiplication factor, I will have to limit it to a factor of 10, because the maximum enhancement is 20 dB. But this limiting factor is band-dependent: ceiling(Fmid) = 1 + 9 (1/2 - 1/2 cos (pi Fmid / 13)) where Fmid is expressed in Bark. The limiting is done smoothly: my_envelope5(t) = 1 / (1 / my_envelope4(t) + 1 / ceiling) So this is the final multiplication factor for the band-filtered signal: new_band(t) = x(t) my_envelope5(t) Your multiplication factor is very different. Please tell me whether I am correct. your_envelope4(t) = rectify (your_envelope3(t)) This step is needed because you cannot handle negative values. It introduces higher-frequency components, which will have to be filtered out later. The new signal will have to carry the new envelope, so the multiplication factor is taken relative to the envelope of the original signal: your_envelope5(t) = your_envelope4(t) / your_envelope2(t) The components that were introduced by the rectification must be thrown out: your_envelope6(t) = your_envelope5(t) * Butterworth?(t) What were the characteristics of that filter? You did not specify them in your paper. Well, the next step is normalization to the power of the original band: new_band(t) = your_envelope6(t) ||x(t)|| / ||your_envelope5(t)|| At least, that's your formula (12). I suppose that it contains a mistake, and that the norm in the denominator should refer to the filtered your_envelope6(t) instead? By the normalization, the fast movements within each band have been strengtened, and the slow parts have been weakened. Thus, there is dynamic expansion within each band, whereas my algorithm has this only in the mid frequency range, am I correct? Could you also explain figure 5 to me? Some of the thick curves show enhanced peaks, but how about the valleys, are some of them deepened as well? 5. The new signal. My algorithm simply adds all the bands: new_signal(t) = SUM new_band(Fmid,t) The mid-frequency bands are favoured because they have stronger modulation deepening than the other bands. In your algorithm, the favouring of the mid frequencies is implemented in the last step: new_signal(t) = SUM new_band(Fmid,t) gain(Fmid) This would mean, for instance, that if the modulation is not deepened (for instance if there are no fast movements), the mid-frequency range is still multiplied by a factor of 10, whereas my algorithm would not change the signal at all in such a case. Is that so? If so, could any of the learning results have been produced by the general emphasis in the 1-4 kHz range? Have you any proof that the modulation deepening itself is the cause of the learning results? So the differences between the two algorithms are clear now: mine does modulation deepening selectively in the F2 range, yours does modulation deepening everywhere plus an independent emphasis in the F2 range. Since both algorithms will lead to emphasis in the F2 range, that leaves the question of whether a modulation change is necessary for the other frequency bands. Have you any idea, or was your choice for this just one of the minor decisions while constructing your algorithm? To sum up, I think that both algorithms perform what they were intended to do, namely selectively enhancing fast F2 transitions. If you agree with this, I may advise XXX to use my algorithm without change. I would, however, welcome any suggestions as to oversights in my implementation, or other possible problems or incorrect choices. */ MAN_BEGIN (U"Matrix: To TableOfReal", U"ppgb", 19991030) INTRO (U"A command to convert every selected @Matrix to a @TableOfReal.") NORMAL (U"This command is available from the #Cast menu. The resulting TableOfReal " "has the same number of rows and columns as the original Matrix, " "and the same data in the cells. However, it does not yet have any row or column " "labels; you can add those with some commands from the TableOfReal #Modify menu.") MAN_END MAN_BEGIN (U"Modify", U"ppgb", 20021204) INTRO (U"The title of a submenu of the @@dynamic menu@ for many object types. " "This submenu usually collects all the commands that can change the selected object.") MAN_END MAN_BEGIN (U"PairDistribution", U"ppgb", 20030316) INTRO (U"One of the @@types of objects@ in Praat. A " "PairDistribution object represents the relative probabilities with which " "the specified pairs of strings occur.") ENTRY (U"Class description") TAG (U"##struct-list# pairs") DEFINITION (U"a list of relative string-pair probabilities. Each element consists of:") TAG1 (U"#string %string1") DEFINITION1 (U"the first string.") TAG1 (U"#string %string2") DEFINITION1 (U"the second string.") TAG1 (U"#real %weight") DEFINITION1 (U"the relative probability associated with the string pair. This value cannot be negative.") MAN_END MAN_BEGIN (U"PairDistribution: To Stringses...", U"ppgb", 20030916) INTRO (U"A command to generate a number of string pairs from the selected @PairDistribution object. " "This command will create two aligned @Strings objects of equal size.") ENTRY (U"Settings") TAG (U"##Number# (standard: 1000)") DEFINITION (U"the number of the strings in either resulting Strings object.") TAG (U"##Name of first Strings# (standard: \"input\")") DEFINITION (U"the name of the resulting Strings object associated with the first string of each pair.") TAG (U"##Name of second Strings# (standard: \"output\")") DEFINITION (U"the name of the resulting Strings object associated with the second string of each pair.") ENTRY (U"Example") NORMAL (U"Suppose the PairDistribution contains the following:") CODE (U"4 pairs") CODE (U"\"at+ma\" \"atma\" 100") CODE (U"\"at+ma\" \"apma\" 0") CODE (U"\"an+pa\" \"anpa\" 20") CODE (U"\"an+pa\" \"ampa\" 80") NORMAL (U"The resulting Strings object \"input\" may then contain:") FORMULA (U"at+ma, an+pa, an+pa, at+ma, at+ma, an+pa, an+pa, an+pa, an+pa, at+ma, ...") NORMAL (U"The Strings object \"output\" may then contain:") FORMULA (U"atma, ampa, ampa, atma, atma, ampa, anpa, ampa, ampa, atma, ...") MAN_END MAN_BEGIN (U"ParamCurve", U"ppgb", 20030316) INTRO (U"One of the @@types of objects@ in Praat.") NORMAL (U"An object of class #ParamCurve represents a sequence of time-stamped points (%x (%%t__i_), %y (%%t__i_)) " "in a two-dimensional space.") MAN_END MAN_BEGIN (U"PointEditor", U"ppgb", 20110128) INTRO (U"One of the @Editors in Praat, for viewing and manipulating a @PointProcess object, " "which is optionally shown together with a @Sound object.") ENTRY (U"Objects") NORMAL (U"The editor shows:") LIST_ITEM (U"• The @Sound, if you selected a Sound object together with the PointProcess object " "before you clicked ##View & Edit#.") LIST_ITEM (U"• The @PointProcess; vertical blue lines represent the points.") ENTRY (U"Playing") NORMAL (U"To play (a part of) the %resynthesized sound (pulse train): " "@click on any of the 8 buttons below and above the drawing area, or choose a Play command from the View menu.") NORMAL (U"To play the %original sound instead, use @@Shift-click@.") ENTRY (U"Adding a point") NORMAL (U"@Click at the desired time location, and choose \"Add point at cursor\" or type ##Command-P#.") ENTRY (U"Removing points") NORMAL (U"To remove one or more points, " "make a @@time selection@ and choose ##Remove point(s)# from the ##Point# menu. " "If there is no selection, the point nearest to the cursor is removed.") MAN_END MAN_BEGIN (U"PointProcess", U"ppgb", 20110128) INTRO (U"One of the @@types of objects@ in Praat.") NORMAL (U"A PointProcess object represents a %%point process%, " "which is a sequence of %points %t__%i_ in time, defined on a domain [%t__%min_, %t__%max_]. " "The index %i runs from 1 to the number of points. The points are sorted by time, i.e. %t__%i+1_ > %t__%i_.") ENTRY (U"PointProcess commands") NORMAL (U"Creation from scratch:") LIST_ITEM (U"• @@Create empty PointProcess...@") LIST_ITEM (U"• @@Create Poisson process...@") NORMAL (U"Creation of a pulse train from a pitch contour:") LIST_ITEM (U"• @@PitchTier: To PointProcess@: area-1 along entire time domain.") LIST_ITEM (U"• @@Pitch: To PointProcess@: same, but excludes voiceless intervals.") LIST_ITEM (U"• @@Sound & Pitch: To PointProcess (cc)@: \"pitch-synchronous\": near locations of high amplitude.") LIST_ITEM (U"• @@Sound & Pitch: To PointProcess (peaks)...@: \"pitch-synchronous\": near locations of high amplitude.") LIST_ITEM (U"• @@Sound: To PointProcess (periodic, cc)...@: near locations of high amplitude.") LIST_ITEM (U"• @@Sound: To PointProcess (periodic, peaks)...@: near locations of high amplitude.") NORMAL (U"Creation from converting another object:") LIST_ITEM (U"• ##Matrix: To PointProcess") LIST_ITEM (U"• @@PitchTier: Down to PointProcess@") LIST_ITEM (U"• @@IntensityTier: Down to PointProcess@") NORMAL (U"Hearing:") LIST_ITEM (U"• @@PointProcess: Play@: pulse train.") LIST_ITEM (U"• @@PointProcess: Hum@: pulse train with formants.") NORMAL (U"Drawing:") LIST_ITEM (U"• @@PointProcess: Draw...@") NORMAL (U"Editing:") LIST_ITEM (U"• ##PointProcess: View & Edit#: invokes a @PointEditor.") LIST_ITEM (U"• ##PointProcess & Sound: View & Edit#: invokes a @PointEditor.") LIST_ITEM (U"• Inside a @ManipulationEditor.") NORMAL (U"Queries:") LIST_ITEM (U"• @@PointProcess: Get jitter (local)...@: periodic jitter.") LIST_ITEM (U"• @@PointProcess: Get jitter (local, absolute)...@: periodic jitter.") LIST_ITEM (U"• @@PointProcess: Get jitter (rap)...@: periodic jitter.") LIST_ITEM (U"• @@PointProcess: Get jitter (ppq5)...@: periodic jitter.") LIST_ITEM (U"• @@PointProcess: Get jitter (ddp)...@: periodic jitter.") LIST_ITEM (U"• @@PointProcess: Get low index...@: index of nearest point not after specified time.") LIST_ITEM (U"• @@PointProcess: Get high index...@: index of nearest point not before specified time.") LIST_ITEM (U"• @@PointProcess: Get nearest index...@: index of point nearest to specified time.") LIST_ITEM (U"• @@PointProcess: Get interval...@: duration of interval around specified time.") NORMAL (U"Set calculations:") LIST_ITEM (U"• @@PointProcesses: Union@: the union of two point processes.") LIST_ITEM (U"• @@PointProcesses: Intersection@: the intersection of two point processes.") LIST_ITEM (U"• @@PointProcesses: Difference@: the difference of two point processes.") NORMAL (U"Modification:") LIST_ITEM (U"• @@PointProcess: Add point...@: at a specified time.") LIST_ITEM (U"• @@PointProcess: Remove point...@: at specified index.") LIST_ITEM (U"• @@PointProcess: Remove point near...@: near specified time.") LIST_ITEM (U"• @@PointProcess: Remove points...@: between specified indices.") LIST_ITEM (U"• @@PointProcess: Remove points between...@: between specified times.") NORMAL (U"Analysis:") LIST_ITEM (U"• @@PointProcess: To PitchTier...@: pitch values in interval centres.") LIST_ITEM (U"• ##PointProcess & Sound: To Manipulation") NORMAL (U"Synthesis:") LIST_ITEM (U"• @@PointProcess: To Sound (pulse train)...@") LIST_ITEM (U"• @@PointProcess: To Sound (hum)...@") NORMAL (U"Conversion:") LIST_ITEM (U"• ##PointProcess: To Matrix") LIST_ITEM (U"• @@PointProcess: Up to TextGrid...") LIST_ITEM (U"• @@PointProcess: Up to PitchTier...") LIST_ITEM (U"• @@PointProcess: Up to IntensityTier...") MAN_END MAN_BEGIN (U"PointProcess: Add point...", U"ppgb", 20010410) INTRO (U"A command to add a point to each selected @PointProcess.") ENTRY (U"Setting") TAG (U"##Time (s)") DEFINITION (U"the time at which a point is to be added.") ENTRY (U"Behaviour") NORMAL (U"The point process is modified so that it contains the new point. " "If a point at the specified time was already present in the point process, nothing happens.") MAN_END MAN_BEGIN (U"PointProcesses: Difference", U"ppgb", 20021212) INTRO (U"A command to compute the difference of two selected @PointProcess objects.") ENTRY (U"Behaviour") NORMAL (U"The resulting #PointProcess will contain only those points of the first selected original point process " "that do not occur in the second.") NORMAL (U"The time domain of the resulting point process is equal to the time domain of the first original point process.") MAN_END MAN_BEGIN (U"PointProcess: Draw...", U"ppgb", 20021212) INTRO (U"A command to draw every selected @PointProcess into the @@Picture window@.") MAN_END MAN_BEGIN (U"PointProcess: Get high index...", U"ppgb", 20021212) INTRO (U"A @query to the selected @PointProcess object.") ENTRY (U"Return value") NORMAL (U"the index of the nearest point at or after the specified time, " "0 if the point process contains no points, " "or a number higher than the number of points if the specified time is after the last point.") ENTRY (U"Setting") TAG (U"##Time (s)") DEFINITION (U"the time from which a point is looked for, in seconds.") MAN_END MAN_BEGIN (U"PointProcess: Get interval...", U"ppgb", 20021212) INTRO (U"A @query to the selected @PointProcess object.") ENTRY (U"Return value") NORMAL (U"the duration of the interval around a specified time. " "if the point process contains no points or if the specified time falls before the first point " "or not before the last point, the value is @undefined. Otherwise, the result is the distance between " "the nearest points to the left and to the right of the specified time. " "If the point process happens to contain a point at exactly the specified time, " "the duration of the interval following this point is returned.") ENTRY (U"Setting") TAG (U"##Time (s)") DEFINITION (U"the time around which a point is looked for, in seconds.") MAN_END MAN_BEGIN (U"PointProcess: Get jitter (local)...", U"ppgb", 20110302) INTRO (U"A command that becomes available in the #Query submenu when you select a @PointProcess object.") NORMAL (U"This command will write into the Info window " "the %%local jitter%, which is the average absolute difference between consecutive intervals, " "divided by the average interval (an interval is the time between two consecutive points).") NORMAL (U"As %jitter is often used as a measure of voice quality (see @@Voice 2. Jitter@), " "the intervals are often considered to be %%glottal periods%. " "For this reason, the command has settings that can limit the possible duration of the interval (or period) " "or the possible difference in the durations of consecutive intervals (periods).") ENTRY (U"1. The command window") SCRIPT (5.4, Manual_SETTINGS_WINDOW_HEIGHT (4), U"" Manual_DRAW_SETTINGS_WINDOW ("PointProcess: Get jitter (local)", 4) Manual_DRAW_SETTINGS_WINDOW_RANGE ("Time range (s)", "0.0", "0.0 (= all)") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Period floor (s)", "0.0001") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Period ceiling (s)", "0.02") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Maximum period factor", "1.3") ) TAG (U"##Time range (s)") DEFINITION (U"the start time and end time of the part of the PointProcess that will be measured. " "Points outside this range will be ignored.") TAG (U"##Period floor (s)") DEFINITION (U"the shortest possible interval that will be used in the computation of jitter, in seconds. " "If an interval is shorter than this, it will be ignored in the computation of jitter " "(and the previous and next intervals will not be regarded as consecutive). " "This setting will normally be very small, say 0.1 ms.") TAG (U"##Period ceiling (s)") DEFINITION (U"the longest possible interval that will be used in the computation of jitter, in seconds. " "If an interval is longer than this, it will be ignored in the computation of jitter " "(and the previous and next intervals will not be regarded as consecutive). " "For example, if the minimum frequency of periodicity is 50 Hz, set this setting to 0.02 seconds; " "intervals longer than that could be regarded as voiceless stretches and will be ignored in the computation.") TAG (U"##Maximum period factor") DEFINITION (U"the largest possible difference between consecutive intervals that will be used in the computation of jitter. " "If the ratio of the durations of two consecutive intervals is greater than this, " "this pair of intervals will be ignored in the computation of jitter " "(each of the intervals could still take part in the computation of jitter in a comparison with its neighbour on the other side).") ENTRY (U"2. Usage") NORMAL (U"The local jitter can be used as a measure of voice quality; " "it is the most common jitter measurement and is usually expressed as a percentage. See @@Voice 2. Jitter@.") ENTRY (U"3. Algorithm") NORMAL (U"(In the following the term %absolute means two different things: (1) the absolute (i.e. non-negative) value of a real number, " "and (2) the opposite of %relative.)") NORMAL (U"The local jitter is defined as the relative mean absolute " "second-order difference of the point process (= the first-order difference of the interval process), as follows.") NORMAL (U"First, we define the absolute (non-relative) local jitter (in seconds) as the mean absolute (non-negative) " "difference of consecutive intervals:") FORMULA (U"%jitter(seconds) = ∑__%i=2_^^%N^ |%T__%i_ - %T__%i-1_| / (%N - 1)") NORMAL (U"where %T__%i_ is the duration of the %%i%th interval and %N is the number of intervals. " "If an interval %T__%i-1_ or %T__%i_ is not between ##Period floor# and ##Period ceiling#, " "or if %T__%i-1_/%T__%i_ or %T__%i_/%T__%i-1_ is greater than ##Maximum period factor#, " "the term |%T__%i_ - %T__%i-1_| is not counted in the sum, and %N is lowered by 1 " "(if %N ends up being less than 2, the result of the command is @undefined).") NORMAL (U"Second, we define the mean period as") FORMULA (U"%meanPeriod(seconds) = ∑__%i=1_^^%N^ %T__%i_ / %N") NORMAL (U"where %T__%i_ is the duration of the %%i%th interval and %N is the number of intervals. " "If an interval %T__%i_ is not between ##Period floor# and ##Period ceiling#, " "or if %T__%i-1_/%T__%i_ or %T__%i_/%T__%i-1_ is greater than ##Maximum period factor# " "%and %T__%i+1_/%T__%i_ or %T__%i_/%T__%i+1_ is greater than ##Maximum period factor#, " "the term %T__%i_ is not counted in the sum, and %N is lowered by 1; " "this procedure ensures that in the computation of the mean period we use at least all the intervals " "that had taken part in the computation of the absolute local jitter.") NORMAL (U"Finally, we compute the (relative) local jitter as") FORMULA (U"%jitter = %jitter(seconds) / %meanPeriod(seconds)") NORMAL (U"The result is a value between 0 and 2, or between 0 and 200 percent.") MAN_END MAN_BEGIN (U"PointProcess: Get jitter (local, absolute)...", U"ppgb", 20110220) INTRO (U"A command that becomes available in the #Query submenu when you select a @PointProcess object.") NORMAL (U"This command will write into the Info window " "the %%absolute local jitter%, which is the average absolute difference between consecutive intervals, " "in seconds (an interval is the time between two consecutive points).") NORMAL (U"As %jitter is often used as a measure of voice quality (see @@Voice 2. Jitter@), " "the intervals are often considered to be %%glottal periods%. " "For this reason, the command has settings that can limit the possible duration of the interval (or period) " "or the possible difference in the durations of consecutive intervals (periods).") ENTRY (U"1. The command window") SCRIPT (5.4, Manual_SETTINGS_WINDOW_HEIGHT (4), U"" Manual_DRAW_SETTINGS_WINDOW ("PointProcess: Get jitter (local, absolute)", 4) Manual_DRAW_SETTINGS_WINDOW_RANGE ("Time range (s)", "0.0", "0.0 (= all)") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Period floor (s)", "0.0001") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Period ceiling (s)", "0.02") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Maximum period factor", "1.3") ) TAG (U"##Time range (s)") DEFINITION (U"the start time and end time of the part of the PointProcess that will be measured. " "Points outside this range will be ignored.") TAG (U"##Period floor (s)") DEFINITION (U"the shortest possible interval that will be used in the computation of jitter, in seconds. " "If an interval is shorter than this, it will be ignored in the computation of jitter " "(and the previous and next intervals will not be regarded as consecutive). " "This setting will normally be very small, say 0.1 ms.") TAG (U"##Period ceiling (s)") DEFINITION (U"the longest possible interval that will be used in the computation of jitter, in seconds. " "If an interval is longer than this, it will be ignored in the computation of jitter " "(and the previous and next intervals will not be regarded as consecutive). " "For example, if the minimum frequency of periodicity is 50 Hz, set this argument to 0.02 seconds; " "intervals longer than that could be regarded as voiceless stretches and will be ignored in the computation.") TAG (U"##Maximum period factor") DEFINITION (U"the largest possible difference between consecutive intervals that will be used in the computation of jitter. " "If the ratio of the durations of two consecutive intervals is greater than this, " "this pair of intervals will be ignored in the computation of jitter " "(each of the intervals could still take part in the computation of jitter in a comparison with its neighbour on the other side).") ENTRY (U"2. Usage") NORMAL (U"The local jitter can be used as a measure of voice quality. See @@Voice 2. Jitter@.") ENTRY (U"3. Algorithm") NORMAL (U"The absolute local jitter is defined as the absolute (i.e. non-relative) mean absolute (i.e. non-negative) " "second-order difference of the point process (= the first-order difference of the interval process), as follows.") NORMAL (U"The absolute local jitter (in seconds) is the mean absolute (non-negative) " "difference of consecutive intervals:") FORMULA (U"%jitter(seconds) = ∑__%i=2_^^%N^ |%T__%i_ - %T__%i-1_| / (%N - 1)") NORMAL (U"where %T__%i_ is the duration of the %%i%th interval and %N is the number of intervals. " "If an interval %T__%i-1_ or %T__%i_ is not between ##Period floor# and ##Period ceiling#, " "or if %T__%i-1_/%T__%i_ or %T__%i_/%T__%i-1_ is greater than ##Maximum period factor#, " "the term |%T__%i_ - %T__%i-1_| is not counted in the sum, and %N is lowered by 1 " "(if %N ends up being less than 2, the result of the command is @undefined).") MAN_END MAN_BEGIN (U"PointProcess: Get jitter (rap)...", U"ppgb", 20110302) INTRO (U"A command that becomes available in the #Query submenu when you select a @PointProcess object.") NORMAL (U"This command will write into the Info window the %%Relative Average Perturbation% (RAP), " "a jitter measure defined as the average absolute difference between an interval and the average of it and its two neighbours, " "divided by the average interval (an interval is the time between two consecutive points).") NORMAL (U"As jitter is often used as a measure of voice quality (see @@Voice 2. Jitter@), " "the intervals are often considered to be %%glottal periods%. " "For this reason, the command has settings that can limit the possible duration of the interval (or period) " "or the possible difference in the durations of consecutive intervals (periods).") ENTRY (U"1. The command window") SCRIPT (5.4, Manual_SETTINGS_WINDOW_HEIGHT (4), U"" Manual_DRAW_SETTINGS_WINDOW ("PointProcess: Get jitter (rap)", 4) Manual_DRAW_SETTINGS_WINDOW_RANGE ("Time range (s)", "0.0", "0.0 (= all)") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Period floor (s)", "0.0001") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Period ceiling (s)", "0.02") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Maximum period factor", "1.3") ) TAG (U"##Time range (s)") DEFINITION (U"the start time and end time of the part of the PointProcess that will be measured. " "Points outside this range will be ignored.") TAG (U"##Period floor (s)") DEFINITION (U"the shortest possible interval that will be used in the computation of jitter, in seconds. " "If an interval is shorter than this, it will be ignored in the computation of jitter " "(and the previous and next intervals will not be regarded as consecutive). " "This setting will normally be very small, say 0.1 ms.") TAG (U"##Period ceiling (s)") DEFINITION (U"the longest possible interval that will be used in the computation of jitter, in seconds. " "If an interval is longer than this, it will be ignored in the computation of jitter " "(and the previous and next intervals will not be regarded as consecutive). " "For example, if the minimum frequency of periodicity is 50 Hz, set this argument to 0.02 seconds; " "intervals longer than that could be regarded as voiceless stretches and will be ignored in the computation.") TAG (U"##Maximum period factor") DEFINITION (U"the largest possible difference between consecutive intervals that will be used in the computation of jitter. " "If the ratio of the durations of two consecutive intervals is greater than this, " "this pair of intervals will be ignored in the computation of jitter " "(each of the intervals could still take part in the computation of jitter in a comparison with its neighbour on the other side).") ENTRY (U"2. Usage") NORMAL (U"The RAP can be used as a measure of voice quality; " "it is the second most common jitter measurement (after @@PointProcess: Get jitter (local)...|local jitter@). See @@Voice 2. Jitter@.") ENTRY (U"3. Algorithm") NORMAL (U"Relative Average Perturbation is defined in terms of three consecutive intervals, as follows.") NORMAL (U"First, we define the absolute (i.e. non-relative) Average Perturbation (in seconds):") FORMULA (U"%absAP(seconds) = ∑__%i=2_^^%N-1^ |%T__%i_ - (%T__%i-1_ + %T__%i_ + %T__%i+1_) / 3| / (%N - 2)") NORMAL (U"where %T__%i_ is the duration of the %%i%th interval and %N is the number of intervals. " "If an interval %T__%i-1_ or %T__%i_ or %T__%i+1_ is not between ##Period floor# and ##Period ceiling#, " "or if %T__%i-1_/%T__%i_ or %T__%i_/%T__%i-1_ or %T__%i+1_/%T__%i_ or %T__%i_/%T__%i+1_ is greater than ##Maximum period factor#, " "the term |%T__%i_ - (%T__%i-1_ + %T__%i_ + %T__%i+1_) / 3| is not counted in the sum, and %N is lowered by 1 " "(if %N ends up being less than 3, the result of the command is @undefined).") NORMAL (U"Second, we define the mean period as") FORMULA (U"%meanPeriod(seconds) = ∑__%i=1_^^%N^ %T__%i_ / %N") NORMAL (U"where %T__%i_ is the duration of the %%i%th interval and %N is the number of intervals. " "If an interval %T__%i_ is not between ##Period floor# and ##Period ceiling#, " "or if %T__%i-1_/%T__%i_ or %T__%i_/%T__%i-1_ is greater than ##Maximum period factor# " "%and %T__%i+1_/%T__%i_ or %T__%i_/%T__%i+1_ is greater than ##Maximum period factor#, " "the term %T__%i_ is not counted in the sum, and %N is lowered by 1; " "this procedure ensures that in the computation of the mean period we use at least all the intervals " "that had taken part in the computation of the absolute average perturbation.") NORMAL (U"Finally, we compute the Relative Average Perturbation as") FORMULA (U"%RAP = %absAP(seconds) / %meanPeriod(seconds)") NORMAL (U"The result is a value between 0 and 2, or between 0 and 200 percent.") MAN_END MAN_BEGIN (U"PointProcess: Get jitter (ppq5)...", U"ppgb", 20110302) INTRO (U"A command that becomes available in the #Query submenu when you select a @PointProcess object.") NORMAL (U"This command will write into the Info window the %%five-point Period Perturbation Quotient%, " "a jitter measure defined as the average absolute difference between an interval and the average of it and its four closest neighbours, " "divided by the average interval (an interval is the time between two consecutive points).") NORMAL (U"As jitter is often used as a measure of voice quality (see @@Voice 2. Jitter@), " "the intervals are often considered to be %%glottal periods%. " "For this reason, the command has settings that can limit the possible duration of the interval (or period) " "or the possible difference in the durations of consecutive intervals (periods).") ENTRY (U"1. The command window") SCRIPT (5.4, Manual_SETTINGS_WINDOW_HEIGHT (4), U"" Manual_DRAW_SETTINGS_WINDOW ("PointProcess: Get jitter (rap)", 4) Manual_DRAW_SETTINGS_WINDOW_RANGE ("Time range (s)", "0.0", "0.0 (= all)") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Period floor (s)", "0.0001") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Period ceiling (s)", "0.02") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Maximum period factor", "1.3") ) TAG (U"##Time range (s)") DEFINITION (U"the start time and end time of the part of the PointProcess that will be measured. " "Points outside this range will be ignored.") TAG (U"##Period floor (s)") DEFINITION (U"the shortest possible interval that will be used in the computation of jitter, in seconds. " "If an interval is shorter than this, it will be ignored in the computation of jitter " "(and the previous and next intervals will not be regarded as consecutive). " "This setting will normally be very small, say 0.1 ms.") TAG (U"##Period ceiling (s)") DEFINITION (U"the longest possible interval that will be used in the computation of jitter, in seconds. " "If an interval is longer than this, it will be ignored in the computation of jitter " "(and the previous and next intervals will not be regarded as consecutive). " "For example, if the minimum frequency of periodicity is 50 Hz, set this argument to 0.02 seconds; " "intervals longer than that could be regarded as voiceless stretches and will be ignored in the computation.") TAG (U"##Maximum period factor") DEFINITION (U"the largest possible difference between consecutive intervals that will be used in the computation of jitter. " "If the ratio of the durations of two consecutive intervals is greater than this, " "this pair of intervals will be ignored in the computation of jitter " "(each of the intervals could still take part in the computation of jitter in a comparison with its neighbour on the other side).") ENTRY (U"2. Usage") NORMAL (U"The jitter can be used as a measure of voice quality. See @@Voice 2. Jitter@.") ENTRY (U"3. Algorithm") NORMAL (U"The five-point Period Perturbation Quotient (PPQ5) is defined in terms of five consecutive intervals, as follows.") NORMAL (U"First, we define the absolute (i.e. non-relative) PPQ5 (in seconds):") FORMULA (U"%absPPQ5(seconds) = ∑__%i=3_^^%N-2^ |%T__%i_ - (%T__%i-2_ + %T__%i-1_ + %T__%i_ + %T__%i+1_ + %T__%i+2_) / 5| / (%N - 4)") NORMAL (U"where %T__%i_ is the duration of the %%i%th interval and %N is the number of intervals. " "If an interval %T__%i-2_ or %T__%i-1_ or %T__%i_ or %T__%i+1_ or %T__%i+2_ is not between ##Period floor# and ##Period ceiling#, " "or if %T__%i-2_/%T__%i-1_ or %T__%i-1_/%T__%i-2_ or %T__%i-1_/%T__%i_ or %T__%i_/%T__%i-1_ or %T__%i+1_/%T__%i_ or %T__%i_/%T__%i+1_ or %T__%i+2_/%T__%i+1_ or %T__%i+1_/%T__%i+2_ is greater than ##Maximum period factor#, " "the term |%T__%i_ - (%T__%i-2_ + %T__%i-1_ + %T__%i_ + %T__%i+1_ + %T__%i+2_) / 5| is not counted in the sum, and %N is lowered by 1 " "(if %N ends up being less than 5, the result of the command is @undefined).") NORMAL (U"Second, we define the mean period as") FORMULA (U"%meanPeriod(seconds) = ∑__%i=1_^^%N^ %T__%i_ / %N") NORMAL (U"where %T__%i_ is the duration of the %%i%th interval and %N is the number of intervals. " "If an interval %T__%i_ is not between ##Period floor# and ##Period ceiling#, " "or if %T__%i-1_/%T__%i_ or %T__%i_/%T__%i-1_ is greater than ##Maximum period factor# " "%and %T__%i+1_/%T__%i_ or %T__%i_/%T__%i+1_ is greater than ##Maximum period factor#, " "the term %T__%i_ is not counted in the sum, and %N is lowered by 1; " "this procedure ensures that in the computation of the mean period we use at least all the intervals " "that had taken part in the computation of the absolute PPQ5.") NORMAL (U"Finally, we compute the five-point Period Perturbation Quotient as") FORMULA (U"%PPQ5 = %PPQ5(seconds) / %meanPeriod(seconds)") NORMAL (U"The result is a value between 0 and 4, or between 0 and 400 percent.") MAN_END MAN_BEGIN (U"PointProcess: Get jitter (ddp)...", U"ppgb", 20110302) INTRO (U"A command that becomes available in the #Query submenu when you select a @PointProcess object.") NORMAL (U"This command will write into the Info window the %%Difference of Differences of Periods%, " "a jitter measure defined as the average absolute difference between the consecutives differences between consecutive intervals, " "divided by the average interval (an interval is the time between two consecutive points).") NORMAL (U"As jitter is often used as a measure of voice quality (see @@Voice 2. Jitter@), " "the intervals are often considered to be %%glottal periods%. " "For this reason, the command has settings that can limit the possible duration of the interval (or period) " "or the possible difference in the durations of consecutive intervals (periods).") ENTRY (U"1. The command window") SCRIPT (5.4, Manual_SETTINGS_WINDOW_HEIGHT (4), U"" Manual_DRAW_SETTINGS_WINDOW ("PointProcess: Get jitter (rap)", 4) Manual_DRAW_SETTINGS_WINDOW_RANGE ("Time range (s)", "0.0", "0.0 (= all)") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Period floor (s)", "0.0001") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Period ceiling (s)", "0.02") Manual_DRAW_SETTINGS_WINDOW_FIELD ("Maximum period factor", "1.3") ) TAG (U"##Time range (s)") DEFINITION (U"the start time and end time of the part of the PointProcess that will be measured. " "Points outside this range will be ignored.") TAG (U"##Period floor (s)") DEFINITION (U"the shortest possible interval that will be used in the computation of jitter, in seconds. " "If an interval is shorter than this, it will be ignored in the computation of jitter " "(and the previous and next intervals will not be regarded as consecutive). " "This setting will normally be very small, say 0.1 ms.") TAG (U"##Period ceiling (s)") DEFINITION (U"the longest possible interval that will be used in the computation of jitter, in seconds. " "If an interval is longer than this, it will be ignored in the computation of jitter " "(and the previous and next intervals will not be regarded as consecutive). " "For example, if the minimum frequency of periodicity is 50 Hz, set this argument to 0.02 seconds; " "intervals longer than that could be regarded as voiceless stretches and will be ignored in the computation.") TAG (U"##Maximum period factor") DEFINITION (U"the largest possible difference between consecutive intervals that will be used in the computation of jitter. " "If the ratio of the durations of two consecutive intervals is greater than this, " "this pair of intervals will be ignored in the computation of jitter " "(each of the intervals could still take part in the computation of jitter in a comparison with its neighbour on the other side).") ENTRY (U"2. Usage") NORMAL (U"The jitter can be used as a measure of voice quality. See @@Voice 2. Jitter@.") ENTRY (U"3. Algorithm") NORMAL (U"(In the following the term %absolute means two different things: (1) the absolute (i.e. non-negative) value of a real number, " "and (2) the opposite of %relative.)") NORMAL (U"DDP is defined as the relative mean absolute (i.e. non-negative) " "third-order difference of the point process (= the second-order difference of the interval process), as follows.") NORMAL (U"First, we define the absolute (i.e. non-relative) Average Perturbation (in seconds) as one third of the mean absolute (non-negative) " "difference of difference of consecutive intervals:") FORMULA (U"%absDDP(seconds) = ∑__%i=2_^^%N-1^ |(%T__%i+1_ - %T__%i_) - (%T__%i_ - %T__%i-1_)| / (%N - 2)") NORMAL (U"where %T__%i_ is the duration of the %%i%th interval and %N is the number of intervals. " "If an interval %T__%i-1_ or %T__%i_ or %T__%i+1_ is not between ###Period floor# and ##Period ceiling#, " "or if %T__%i-1_/%T__%i_ or %T__%i_/%T__%i-1_ or %T__%i+1_/%T__%i_ or %T__%i_/%T__%i+1_ is greater than ##Maximum period factor#, " "the term |2%T__%i_ - %T__%i-1_ - %T__%i+1_| is not counted in the sum, and %N is lowered by 1 " "(if %N ends up being less than 3, the result of the command is @undefined).") NORMAL (U"Second, we define the mean period as") FORMULA (U"%meanPeriod(seconds) = ∑__%i=1_^^%N^ %T__%i_ / %N") NORMAL (U"where %T__%i_ is the duration of the %%i%th interval and %N is the number of intervals. " "If an interval %T__%i_ is not between ##Period floor# and ##Period ceiling#, " "or if %T__%i-1_/%T__%i_ or %T__%i_/%T__%i-1_ is greater than ##Maximum period factor# " "%and %T__%i+1_/%T__%i_ or %T__%i_/%T__%i+1_ is greater than ##Maximum period factor#, " "the term %T__%i_ is not counted in the sum, and %N is lowered by 1; " "this procedure ensures that in the computation of the mean period we use at least all the intervals " "that had taken part in the computation of DDP.") NORMAL (U"Finally, we compute DDP as") FORMULA (U"%DDP = %absDDP(seconds) / %meanPeriod(seconds)") NORMAL (U"The result is exactly 3 times the @@PointProcess: Get jitter (rap)...|RAP@ jitter measurement: " "a value between 0 and 6, or between 0 and 600 percent.") MAN_END MAN_BEGIN (U"PointProcess: Get low index...", U"ppgb", 20021212) INTRO (U"A @query to the selected @PointProcess object.") ENTRY (U"Return value") NORMAL (U"the index of the nearest point before or at the specified time, " "or 0 if the point process contains no points or the specified time is before the first point.") ENTRY (U"Setting") TAG (U"##Time (s)") DEFINITION (U"the time from which a point is looked for, in seconds.") MAN_END MAN_BEGIN (U"PointProcess: Get nearest index...", U"ppgb", 20021212) INTRO (U"A @query to the selected @PointProcess object.") ENTRY (U"Return value") NORMAL (U"the index of the point nearest to the specified time, " "or 0 if the point process contains no points.") ENTRY (U"Setting") TAG (U"##Time (s)") DEFINITION (U"the time around which a point is looked for, in seconds.") /* form Get nearest raising zero real Time_(s) 0.5 endform To PointProcess (zeroes)... yes no index = Get nearest index... Time if index = 0 # Geen punten gevonden: default-actie. time = 'Time' else time = Get time from index... index endif echo 'time' */ MAN_END MAN_BEGIN (U"PointProcess: Hum", U"ppgb", 19970330) INTRO (U"A command to hear a @PointProcess.") ENTRY (U"Algorithm") NORMAL (U"A @Sound is created with the algorithm described at @@PointProcess: To Sound (hum)...@.") NORMAL (U"This sound is then played.") MAN_END MAN_BEGIN (U"PointProcesses: Intersection", U"ppgb", 20021212) INTRO (U"A command to merge two selected @PointProcess objects into one.") ENTRY (U"Behaviour") NORMAL (U"The resulting #PointProcess will contain only those points that occur in both original point processes.") NORMAL (U"The time domain of the resulting point process is the intersection of the time domains of the original point processes.") MAN_END MAN_BEGIN (U"PointProcess: Play", U"ppgb", 19970330) INTRO (U"A command to hear a @PointProcess.") ENTRY (U"Algorithm") NORMAL (U"A @Sound is created with the algorithm described at @@PointProcess: To Sound (pulse train)...@.") NORMAL (U"This sound is then played.") MAN_END MAN_BEGIN (U"PointProcess: Remove point...", U"ppgb", 20021212) INTRO (U"A command to remove a point from every selected @PointProcess.") ENTRY (U"Setting") TAG (U"##Index") DEFINITION (U"the index of the point that is to be removed.") ENTRY (U"Behaviour") NORMAL (U"Does nothing if %index is less than 1 or greater than the number of points %nt in the point process. " "Otherwise, one point is removed (e.g., if %index is 3, the third point is removed), and the other points stay the same.") MAN_END MAN_BEGIN (U"PointProcess: Remove point near...", U"ppgb", 20021212) INTRO (U"A command to remove a point from every selected @PointProcess.") ENTRY (U"Setting") TAG (U"##Time (s)") DEFINITION (U"the time (in seconds) around which a point is to be removed.") ENTRY (U"Behaviour") NORMAL (U"Does nothing if there are no points in the point process. " "Otherwise, the point nearest to %time is removed, and the other points stay the same.") MAN_END MAN_BEGIN (U"PointProcess: Remove points...", U"ppgb", 20021212) INTRO (U"A command to remove a range of points from every selected @PointProcess.") ENTRY (U"Settings") TAG (U"##From index (≥ 1)") DEFINITION (U"the first index of the range of points that are to be removed.") TAG (U"##To index") DEFINITION (U"the last index of the range of points that are to be removed.") ENTRY (U"Behaviour") NORMAL (U"All points that originally fell in the range [%fromIndex, %toIndex] are removed, and the other points stay the same.") MAN_END MAN_BEGIN (U"PointProcess: Remove points between...", U"ppgb", 20021212) INTRO (U"A command to remove a range of points from every selected @PointProcess.") ENTRY (U"Settings") TAG (U"##From time (s)") DEFINITION (U"the start of the domain from which all points are to be removed.") TAG (U"##To time (s)") DEFINITION (U"the end of the domain from which all points are to be removed.") ENTRY (U"Behaviour") NORMAL (U"All points that originally fell in the domain [%fromTime, %toTime], including the edges, are removed, " "and the other points stay the same.") MAN_END MAN_BEGIN (U"PointProcess: To Sound (hum)...", U"ppgb", 19970330) INTRO (U"A command to convert every selected @PointProcess into a @Sound.") ENTRY (U"Algorithm") NORMAL (U"A @Sound is created with the algorithm described at @@PointProcess: To Sound (pulse train)...@. " "This sound is then run through a sequence of second-order filters that represent five formants.") MAN_END MAN_BEGIN (U"PointProcess: To Sound (phonation)...", U"ppgb", 20070225) INTRO (U"A command to convert every selected @PointProcess into a @Sound.") ENTRY (U"Algorithm") NORMAL (U"A glottal waveform is generated at every point in the point process. " "Its shape depends on the settings %power1 and %power2 according to the formula") FORMULA (U"%U(%x) = %x^^%power1^ - %x^^%power2^") NORMAL (U"where %x is a normalized time that runs from 0 to 1 and %U(%x) is the normalized glottal flow in arbitrary units (the real unit is m^3/s). " "If %power1 = 2.0 and %power2 = 3.0, the glottal flow shape is that proposed by @@Rosenberg (1971)@, " "upon which for instance the Klatt synthesizer is based (@@Klatt & Klatt (1990)@):") SCRIPT (4.5, 3, U"Select outer viewport... 0 4.5 -0.4 3\n" "Axes... 0 1 -0.1 1\n" "One mark left... 0 yes yes yes\n" "One mark bottom... 0 yes yes no\n" "One mark bottom... 1 yes yes no\n" "Draw inner box\n" "Draw function... 0 1 1000 (x^2-x^3)*6\n" "Text bottom... yes Time (normalized)\n" "Text left... yes Glottal flow\n" ) NORMAL (U"If %power1 = 3.0 and %power2 = 4.0, the glottal flow shape starts somewhat smoother, " "reflecting the idea that the glottis opens like a zipper:") SCRIPT (4.5, 3, U"Axes... 0 1 -0.1 1\n" "One mark left... 0 yes yes yes\n" "One mark bottom... 0 yes yes no\n" "One mark bottom... 1 yes yes no\n" "Draw inner box\n" "Draw function... 0 1 1000 (x^3-x^4)*8\n" "Text bottom... yes Time (normalized)\n" "Text left... yes Glottal flow\n" ) NORMAL (U"For the generation of speech sounds, we do not take the glottal flow itself, " "but rather its derivative (this takes into account the influence of radiation at the lips). " "The glottal flow derivative is given by") FORMULA (U"%dU(%x)/%dx = %power1 %x^^(%power1-1)^ - %power2 %x^^(%power2-1)^") NORMAL (U"The flow derivative clearly shows the influence of the smoothing mentioned above. " "The unsmoothed curve, with %power1 = 2.0 and %power2 = 3.0, looks like:") SCRIPT (4.5, 4, U"Axes... 0 1 -9 3\n" "One mark left... 0 yes yes yes\n" "One mark bottom... 0 yes yes no\n" "One mark bottom... 1 yes yes no\n" "Draw inner box\n" "Draw function... 0 1 1000 (2*x-3*x^2)*6\n" "Text bottom... yes Time (normalized)\n" "Text left... yes Glottal flow derivative\n" ) NORMAL (U"Unlike the unsmoothed curve, the smoothed curve, with %power1 = 3.0 and %power2 = 4.0, starts out horizontally:") SCRIPT (4.5, 4, U"Axes... 0 1 -9 3\n" "One mark left... 0 yes yes yes\n" "One mark bottom... 0 yes yes no\n" "One mark bottom... 1 yes yes no\n" "Draw inner box\n" "Draw function... 0 1 1000 (3*x^2-4*x^3)*8\n" "Text bottom... yes Time (normalized)\n" "Text left... yes Glottal flow derivative\n" ) NORMAL (U"Another setting is the %%open phase%. If it is 0.70, the glottis will be open during 70 percent of a period. " "Suppose that the PointProcess has a pulse at time 0, at time 1, at time 2, and so on. The pulses at times 1 and 2 will then be turned " "into glottal flows starting at times 0.30 and 1.30:") SCRIPT (4.5, 2.5, U"Axes... 0 2 -0.1 1\n" "One mark left... 0 yes yes yes\n" "One mark bottom... 0 yes yes no\n" "One mark bottom... 1 yes yes yes\n" "One mark bottom... 2 yes yes no\n" "Draw inner box\n" "Draw function... 0 0.3 2 0\n" "Draw function... 0.3 1.3 300 if x<1 then (((x-0.3)/0.7)^3-((x-0.3)/0.7)^4)*8 else 0 fi\n" "Draw function... 1.3 2 300 (((x-1.3)/0.7)^3-((x-1.3)/0.7)^4)*8\n" "Text bottom... yes Time (normalized)\n" "Text left... yes Glottal flow\n" ) SCRIPT (4.5, 2.5, U"Axes... 0 2 -9 3\n" "One mark left... 0 yes yes yes\n" "One mark bottom... 0 yes yes no\n" "One mark bottom... 1 yes yes yes\n" "One mark bottom... 2 yes yes no\n" "Draw inner box\n" "Draw function... 0 0.3 2 0\n" "Draw function... 0.3 1.3 300 if x<1 then (3*((x-0.3)/0.7)^2-4*((x-0.3)/0.7)^3)*8 else 0 fi\n" "Draw function... 1.3 2 300 (3*((x-1.3)/0.7)^2-4*((x-1.3)/0.7)^3)*8\n" "Text bottom... yes Time (normalized)\n" "Text left... yes Glottal flow derivative\n" ) NORMAL (U"The final setting that influences the shape of the glottal flow is the %%collision phase%. " "If it is 0.03, for instance, the glottal flow derivative will not go abruptly to 0 at a pulse, " "but will instead decay by a factor of %e (≈ 2.7183) every 3 percent of a period. " "In order to keep the glottal flow curve smooth (and the derivative continuous), " "the basic shape discussed above has to be shifted slightly to the right and truncated " "at the time of the pulse, to be replaced there with the exponential decay curve; " "this also makes sure that the average of the derivative stays zero, as it was above " "(i.e. the area under the positive part of the curve equals the area above the negative part). " "This is what the curves look like if %power1 = 3.0, %power2 = 4.0, %openPhase = 0.70 and %collisionPhase = 0.03:") SCRIPT (4.5, 2.5, U"Axes... 0 2 -0.1 1\n" "One mark left... 0 yes yes yes\n" "One mark bottom... 0 yes yes no\n" "One mark bottom... 1 yes yes yes\n" "One mark bottom... 2 yes yes no\n" "Draw inner box\n" "xo = 0.32646\n" "g1 = 0.269422\n" "Draw function... 0 xo 300 g1 * exp(-x/0.03)\n" "Draw function... xo 1 300 (((x-xo)/0.7)^3-((x-xo)/0.7)^4)*8 + g1 * exp(-x/0.03)\n" "Draw function... 1 1+xo 300 g1 * exp(-(x-1)/0.03)\n" "Draw function... 1+xo 2 300 (((x-1-xo)/0.7)^3-((x-1-xo)/0.7)^4)*8 + g1 * exp(-(x-1)/0.03)\n" "Text bottom... yes Time (normalized)\n" "Text left... yes Glottal flow\n" ) SCRIPT (4.5, 2.5, U"Axes... 0 2 -9 3\n" "One mark left... 0 yes yes yes\n" "One mark bottom... 0 yes yes no\n" "One mark bottom... 1 yes yes yes\n" "One mark bottom... 2 yes yes no\n" "Draw inner box\n" "xo = 0.32646\n" "g1 = -8.980736 * 0.7\n" "Draw function... 0 xo 300 g1 * exp(-x/0.03)\n" "Draw function... xo 1 300 (3*((x-xo)/0.7)^2-4*((x-xo)/0.7)^3)*8 + g1 * exp(-x/0.03)\n" "Draw function... 1 1+xo 300 g1 * exp(-(x-1)/0.03)\n" "Draw function... 1+xo 2 300 (3*((x-1-xo)/0.7)^2-4*((x-1-xo)/0.7)^3)*8 + g1 * exp(-(x-1)/0.03)\n" "Text bottom... yes Time (normalized)\n" "Text left... yes Glottal flow derivative\n" ) NORMAL (U"These curves have moved 2.646 percent of a period to the right. At time 1, " "the glottal flow curve turns from a convex polynomial into a concave exponential, " "and the derivative still has its minimum there.") ENTRY (U"Settings") TAG (U"##Sampling frequency (Hz)") DEFINITION (U"the sampling frequency of the resulting Sound object, e.g. 44100 hertz.") TAG (U"##Adaptation factor") DEFINITION (U"the factor by which a pulse height will be multiplied if the pulse time is not within " "##Maximum period# from the previous pulse, and by which a pulse height will again be multiplied " "if the previous pulse time is not within ##Maximum period# from the pre-previous pulse. This factor is against " "abrupt starts of the pulse train after silences, and is 1.0 if you do want abrupt starts after silences.") TAG (U"##Maximum period (s)") DEFINITION (U"the minimal period that will be considered a silence, e.g. 0.05 seconds. " "Example: if ##Adaptation factor# is 0.6, and ##Adaptation time# is 0.02 s, " "then the heights of the first two pulses after silences of at least 20 ms " "will be multiplied by 0.36 and 0.6, respectively.") MAN_END MAN_BEGIN (U"PointProcess: To Sound (pulse train)...", U"ppgb", 20070225) INTRO (U"A command to convert every selected @PointProcess into a @Sound.") ENTRY (U"Algorithm") NORMAL (U"A pulse is generated at every point in the point process. This pulse is filtered at the Nyquist frequency " "of the resulting #Sound by converting it into a sampled #sinc function.") ENTRY (U"Settings") TAG (U"##Sampling frequency (Hz)") DEFINITION (U"the sampling frequency of the resulting Sound object, e.g. 44100 hertz.") TAG (U"##Adaptation factor") DEFINITION (U"the factor by which a pulse height will be multiplied if the pulse time is not within " "##Adaptation time# from the pre-previous pulse, and by which a pulse height will again be multiplied " "if the pulse time is not within ##Adaptation time# from the previous pulse. This factor is against " "abrupt starts of the pulse train after silences, and is 1.0 if you do want abrupt starts after silences.") TAG (U"##Adaptation time (s)") DEFINITION (U"the minimal period that will be considered a silence, e.g. 0.05 seconds.") TAG (U"##Interpolation depth") DEFINITION (U"the extent of the sinc function to the left and to the right of the peak, e.g. 2000 samples.") NORMAL (U"Example: if ##Adaptation factor# is 0.6, and ##Adaptation time# is 0.02 s, " "then the heights of the first two pulses after silences of at least 20 ms " "will be multiplied by 0.36 and 0.6, respectively.") MAN_END MAN_BEGIN (U"PointProcesses: Union", U"ppgb", 20021212) INTRO (U"A command to merge two selected @PointProcess objects into one.") ENTRY (U"Behaviour") NORMAL (U"The resulting #PointProcess will contain all the points of the two original point processes, sorted by time. " "Points that occur in both original point processes, will occur only once in the resulting point process.") NORMAL (U"The time domain of the resulting point process is the union of the time domains of the original point processes.") MAN_END MAN_BEGIN (U"PointProcess: Up to IntensityTier...", U"ppgb", 19970329) INTRO (U"A command to promote every selected @PointProcess to an @IntensityTier.") ENTRY (U"Setting") TAG (U"##Intensity (dB)") DEFINITION (U"the intensity that will be associated with every point.") ENTRY (U"Behaviour") NORMAL (U"The times of all the points are trivially copied, and so is the time domain. " "The intensity information will be the same for every point.") MAN_END MAN_BEGIN (U"PointProcess: Up to PitchTier...", U"ppgb", 19970329) INTRO (U"A command to promote every selected @PointProcess to a @PitchTier.") ENTRY (U"Setting") TAG (U"##Frequency (Hz)") DEFINITION (U"the pitch frequency that will be associated with every point.") ENTRY (U"Behaviour") NORMAL (U"The times of all the points are trivially copied, and so is the time domain. " "The pitch information will be the same for every point.") MAN_END MAN_BEGIN (U"Polygon", U"ppgb", 20030316) INTRO (U"One of the @@types of objects@ in Praat.") NORMAL (U"A Polygon object represents a sequence of points (%%x__i_, %%y__i_) in a two-dimensional space.") MAN_END MAN_BEGIN (U"Read Matrix from raw text file...", U"ppgb", 19980322) INTRO (U"A command to read a @Matrix object from a file on disk.") ENTRY (U"File format") NORMAL (U"The file should contain each row of the matrix on a separate line. Within each row, " "the elements must be separated by spaces or tabs.") NORMAL (U"For instance, the following text file will be read as a Matrix with three rows and four columns:") CODE (U"0.19 3 245 123") CODE (U"18e-6 -3e18 0 0.0") CODE (U"1.5 2.5 3.5 4.5") NORMAL (U"The resulting Matrix will have the same domain and sampling as Matrices created with " "##Create simple Matrix...#. In the above example, this means that the Matrix will have " "%x__%min_ = 0.5, %x__%max_ = 4.5, %n__%x_ = 4, %dx = 1.0, %x__1_ = 1.0, " "%y__%min_ = 0.5, %y__%max_ = 3.5, %n__%y_ = 3, %dy = 1.0, %y__1_ = 1.0.") MAN_END MAN_BEGIN (U"Read Strings from raw text file...", U"ppgb", 19990502) INTRO (U"A command to read a @Strings object from a simple text file. " "Each line is read as a separate string. See @Strings for an example.") MAN_END MAN_BEGIN (U"Sound: To Intensity...", U"ppgb", 20100605) INTRO (U"A command to create an @Intensity object from every selected @Sound.") ENTRY (U"Settings") TAG (U"##Minimum pitch (Hz)") DEFINITION (U"the minimum periodicity frequency in your signal. If you set it too high, " "you will end up with a pitch-synchronous intensity modulation. If you set it too low, " "your intensity contour may appear smeared, so you should set it as high as allowed by the signal " "if you want a sharp contour.") TAG (U"##Time step (s)") DEFINITION (U"the time step of the resulting intensity contour. If you set it to zero, the time step is computed as " "one quarter of the effective window length, i.e. as 0.8 / (%minimum_pitch).") TAG (U"##Subtract mean") DEFINITION (U"See @@Intro 6.2. Configuring the intensity contour@.") ENTRY (U"Algorithm") NORMAL (U"The values in the sound are first squared, then convolved with a Gaussian analysis window (Kaiser-20; sidelobes below -190 dB). " "The effective duration of this analysis window is 3.2 / (%minimum_pitch), which will guarantee that a periodic signal is analysed as having a " "pitch-synchronous intensity ripple not greater than 0.00001 dB.") MAN_END MAN_BEGIN (U"Sound & IntensityTier: Multiply", U"ppgb", 20000724) INTRO (U"A command to create a new Sound from the selected @Sound and @Intensity objects.") NORMAL (U"The resulting Sound equals the original sound, multiplied by a linear interpolation of the intensity. " "Afterwards, the resulting Sound is scaled so that its maximum absolute amplitude is 0.9.") MAN_END MAN_BEGIN (U"Strings", U"ppgb", 20141001) INTRO (U"One of the @@types of objects@ in Praat. Represents an ordered list of strings.") ENTRY (U"Creation") NORMAL (U"The difficult way is to create a #Strings object from a generic Praat text file " "(if there are non-ASCII symbols, use UTF-8 or UTF-16 format):") CODE (U"\"ooTextFile\"") CODE (U"\"Strings\"") CODE (U"5 ! number of strings") CODE (U"\"Hello\"") CODE (U"\"Goodbye\"") CODE (U"\"Auf wiedersehen\"") CODE (U"\"Tschüss\"") CODE (U"\"Arrivederci\"") NORMAL (U"In this example, we see that a double quote within a string should be written twice; " "the fourth string will therefore be read as ##Tschüss#. " "This file can be read simply with the generic @@Read from file...@ command from the #Open menu.") NORMAL (U"An easier way is to use the special command @@Read Strings from raw text file...@. " "The file can then simply look like this:") CODE (U"Hello") CODE (U"Goodbye") CODE (U"Auf wiedersehen") CODE (U"Tschüss") CODE (U"Arrivederci") NORMAL (U"You can also create a #Strings object from a directory listing or from some other objects:") LIST_ITEM (U"• @@Create Strings as file list...") LIST_ITEM (U"• @@Distributions: To Strings...@") LIST_ITEM (U"• @@OTGrammar: Generate inputs...@") LIST_ITEM (U"• @@OTGrammar & Strings: Inputs to outputs...@") MAN_END MAN_BEGIN (U"Strings: To Distributions", U"ppgb", 19971025) INTRO (U"A command to analyse each selected @Strings object into a @Distributions object.") NORMAL (U"The resulting #Distributions will collect the occurrences of every string in the #Strings object, " "and put the number of occurrences in its first and only column.") ENTRY (U"Example") NORMAL (U"We start from the following #Strings:") CODE (U"6 (number of strings)") CODE (U"\"hallo\"") CODE (U"\"dag allemaal\"") CODE (U"\"hallo\"") CODE (U"\"tot morgen\"") CODE (U"\"hallo\"") CODE (U"\"tot morgen\"") NORMAL (U"This will give us the following #Distributions:") CODE (U"1 (number of columns) \"\" (no column name)") CODE (U"\"hallo\" 3") CODE (U"\"dag allemaal\" 1") CODE (U"\"tot morgen\" 2") MAN_END MAN_BEGIN (U"Table", U"ppgb", 20030316) INTRO (U"One of the @@types of objects@ in Praat. See the @Statistics tutorial.") MAN_END MAN_BEGIN (U"TableOfReal", U"ppgb", 20030316) INTRO (U"One of the @@types of objects@ in Praat.") NORMAL (U"A TableOfReal object contains a number of %cells. Each cell belongs to a %row and a %column. " "For instance, a TableOfReal with 10 rows and 3 columns has 30 cells.") NORMAL (U"Each row and each column may be labeled with a %title.") ENTRY (U"Creating a TableOfReal from data in a text file") NORMAL (U"Suppose you have F1 and F2 data for vowels. " "You can create a simple text file like the following:") CODE (U"\"ooTextFile\" ! The line by which Praat can recognize your file") CODE (U"\"TableOfReal\" ! The line that tells Praat about the contents") CODE (U"2 \"F1\" \"F2\" ! Number of columns, and column labels") CODE (U"3 ! Number of rows") CODE (U"\"a\" 800 1100 ! Row label (vowel), F1 value, F2 value") CODE (U"\"i\" 280 2800 ! Row label (vowel), F1 value, F2 value") CODE (U"\"u\" 260 560 ! Row label (vowel), F1 value, F2 value") NORMAL (U"Praat is rather forgiving about the use of spaces, tabs, and newlines. " "See @@Save as text file...@ for general information.") NORMAL (U"You will often have your data in a file with a self-describing format, " "i.e. in which the number of values on a line equals the number of columns " "of the table:") CODE (U"800 1100") CODE (U"280 2800") CODE (U"260 560") NORMAL (U"Such a file can be read with @@Read Matrix from raw text file...@. " "This creates a Matrix object, which can be cast to a TableOfReal object " "by @@Matrix: To TableOfReal@. The resulting TableOfReal does not have " "any row or column labels yet. You could add column labels with:") CODE (U"Set column label (index)... 1 F1") CODE (U"Set column label (index)... 2 F2") NORMAL (U"Of course, if the row labels contain crucial information, " "and the number of rows is large, this is not a feasible method.") MAN_END MAN_BEGIN (U"TableOfReal: Set value...", U"ppgb", 19980105) INTRO (U"A command to change the value of one table cell in each selected @TableOfReal object.") ENTRY (U"Settings") TAG (U"##Row number") DEFINITION (U"the number of the row of the cell whose value you want to change.") TAG (U"##Column number") DEFINITION (U"the number of the column of the cell whose value you want to change.") TAG (U"##New value") DEFINITION (U"the value that you want the specified cell to have.") MAN_END } /* End of file manual_Fon.cpp */ praat-6.0.04/fon/manual_Manual.cpp000066400000000000000000000401441261542461700167630ustar00rootroot00000000000000/* manual_Manual.cpp * * Copyright (C) 1992-2011,2013,2014,2015 Paul Boersma * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ManPagesM.h" void manual_Manual_init (ManPages me); void manual_Manual_init (ManPages me) { MAN_BEGIN (U"Manual", U"ppgb", 20110101) INTRO (U"The documentation system for the Praat program.") NORMAL (U"You will get a manual window every time you choose anything from a #Help menu or press a #Help button.") ENTRY (U"How to find what you are looking for") NORMAL (U"You can navigate the manual in several ways:") LIST_ITEM (U"\\bu To go to the Intro, use the #Home button.") LIST_ITEM (U"\\bu To go to the information behind a %link (a piece of blue text), just click on it.") LIST_ITEM (U"\\bu To go forward and backward through a tutorial with numbered pages, use ##1 ># and ##< 1#.") LIST_ITEM (U"\\bu To %revisit previous pages, use the #< and #> buttons.") LIST_ITEM (U"\\bu To browse %alphabetically, use the horizontal scroll bar and the buttons " "named ##< 1# and ##1 >#, or the ##Search for page (list)...# command in the ##Go to# menu.") LIST_ITEM (U"\\bu To find a page with a %%known title%, use the ##Search for page...# command.") NORMAL (U"The fastest way to find what you want is usually the #Search button.") ENTRY (U"Search") NORMAL (U"In the text field after the Search button, you can type strings, separated by spaces. " "When you press the #Return (or #Enter) key, or click the #Search button, " "all manual pages are searched for the combination of strings that you typed. " "The titles of the 20 best matching pages are displayed as links.") NORMAL (U"##Example:# to know how to create a pitch contour from a sound, type") CODE (U"sou pit") NORMAL (U"and press #Return. The best matches should appear on top. These should include " "##Sound: To Pitch (ac)...# and ##Sound: To Pitch (cc)...#.") NORMAL (U"The search is case-insensitive. For instance, the search string \"$script\" will give you all " "the pages that contain the words %script, %Script, %description, %PostScript, or %SCRIPT, and so on.") NORMAL (U"#Background. The search algorithm uses the following heuristics:") LIST_ITEM (U"\\bu A match in the page title is better than one in the rest of the text.") LIST_ITEM (U"\\bu Pages with many matches are better than those with few.") ENTRY (U"Your own manual pages") NORMAL (U"To create your own manual pages, create @ManPages text files.") MAN_END MAN_BEGIN (U"ManPages", U"ppgb", 20140421) INTRO (U"You can create a documentation or education system with files that you and others " "can read into Praat (with the @@Read from file...@ command). " "Your files will become a hypertext system very similar to the usual @Manual.") ENTRY (U"Example 1: a single document") NORMAL (U"If you create a single ManPages text file, it will look like a manual with a single page. " "Here is an example:") CODE (U"ManPagesTextFile") CODE (U"\"Welkom\" \"miep\" 19970820 0") CODE (U" \"Hallo allemaal!\"") CODE (U" \"Belangrijk...\"") CODE (U" \"Hoogge\\bse\\\" \\\" erd publiek!\"") CODE (U" \"Einde.\"") NORMAL (U"A ManPages text file should start with the following information:") LIST_ITEM (U"1. The word \"ManPagesTextFile\" on the first line.") LIST_ITEM (U"2. The title of the manual page, between double quotes. " "This will be drawn at the top of the page. " "The name of the ManPages text file should be derived from this title (see below).") LIST_ITEM (U"3. The author of the manual page, between double quotes. " "This will be drawn at the bottom of the page.") LIST_ITEM (U"4. The date you created or modified the page, " "in the format year \\-- month (two digits) \\-- day (two digits), without spaces.") LIST_ITEM (U"5. The recording time. If this is not zero, " "three sound buttons (see below) will appear at the top of the page.") LIST_ITEM (U"6. A sequence of paragraph types and texts. " "You put the types between < and >, and the texts between double quotes " "(if your text contains a double quote, you should write two double quotes).") NORMAL (U"The format of a ManPages text file is rather free, as long as the first line is correct, " "the four required pieces of information are there in the correct order, " "and there is a correct alternation between paragraph texts and types. " "If you put multiple elements on a line, there should be at least one space between them. " "You may distribute texts across multiple lines, as long as you do not add any spaces:") CODE (U" \"Hoogge\\bse\\\" \\\" erd") CODE (U"publiek!\"") NORMAL (U"This will have exactly the same effect as above.") ENTRY (U"Example 2: multiple documents") NORMAL (U"The above example with a single document is not very useful. " "You will usually want to refer to other documents:") CODE (U"ManPagesTextFile") CODE (U"\"Welcome\" \"Paul Boersma\" 19970820 1.0") CODE (U" \"Welcome to Paul's transcription course.\"") CODE (U" \"Groups of speech sounds\"") CODE (U" \"You can listen to the following sounds") CODE (U"from the languages of the world,") CODE (U"pronounced by a single speaker (me):\\\"r") CODE (U" \"\\@ Vowels, quite problematic for Dutch students!\"") CODE (U" \"\\@ \\@ Dorsal fricatives\\@ , equally problematic!\"") NORMAL (U"With the symbol `\\@ ', you create a %link to another ManPages text file. " "A link will be drawn in blue on your screen. " "In this example, you have created links to the files ##Vowels.man# " "and ##Dorsal_fricatives.man# in the same directory as the current file " "(all ##.man# files have to be in the same directory; this makes it likely " "that their names are unique). " "If the link contains spaces or other non-alphanumeric symbols, " "you have to use three `\\@ ' symbols, as shown; " "with a single word, you may use a single `\\@ '.") NORMAL (U"In resolving the file name, the ManPages system replaces spaces " "and other special symbols with underscores, " "and converts any initial lower-case character by its upper-case variant. " "For instance, if your link is \"\\@ \\@ back vowels\\@ \", " "the file name will be ##Back_vowels.man#.") NORMAL (U"The title in the second line of ##Back_vowels.man# must be equal to the link name, " "though capitalization of the first letter is allowed. " "Thus, the title of ##Back_vowels.man# will probably be \"Back vowels\". " "Likewise, the starting file with the title \"Welcome\" should have the name ##Welcome.man# " "if any other files refer to it.") ENTRY (U"Paragraph types") NORMAL (U"A normal paragraph will have type . The hypertext system will " "leave a blank space between paragraphs with this type. " "The first paragraph of a manual page will normally have the type . " "Though this may look the same as , the search system of the @Manual " "may take account of the distinction.") NORMAL (U"Headings (like the title \"Paragraph types\" of this subsection) " "have type . This will be drawn in a larger character size.") NORMAL (U"For lists, you use the type . You will often combine this with %button symbols, " "like in the following:") CODE (U" \"Choose a colour:\"") CODE (U" \"\\bsbu \\@ Red.\"") CODE (U" \"\\bsbu \\@ Green.\"") CODE (U" \"\\bsbu \\@ Blue.\"") NORMAL (U"For text that should appear with a fixed character width, you use the type .") NORMAL (U"For a paragraph that should be connected with the following paragraph " "without leaving a blank space " "(probably a list item or a definition), you use the type .") NORMAL (U"For a paragraph with a blank left margin, you use the type .") NORMAL (U"For a paragraph with an embedded script (a picture), you use the type